Merge branch 'hwmon-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jdelv...
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 16 Jun 2009 18:28:50 +0000 (11:28 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 16 Jun 2009 18:28:50 +0000 (11:28 -0700)
* 'hwmon-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jdelvare/staging:
  hwmon: (max6650) Add support for alarms
  hwmon: (f71882fg) Add support for the F71858F
  hwmon: (f71882fg) Add temp#_fault sysfs attr for f8000
  hwmon: (f71882fg) Sanity check f8000 pwm settings
  hwmon: (f71882fg) Cleanup f8000 pwm handling
  hwmon: PCI quirk for hwmon access on MSI MS-7031 board
  hwmon: (w83627ehf) Add W83627DHG-P support
  hwmon: (tmp401) Add documentation
  hwmon: (tmp401) Add support for TI's TMP411 sensors chip
  hwmon: (tmp401) Add support for TI's TMP401 sensor chip
  hwmon: (ibmaem) Automatically load on HC10 blade
  hwmon: Fix more __devexit_p glitches

1495 files changed:
CREDITS
Documentation/DocBook/mac80211.tmpl
Documentation/feature-removal-schedule.txt
Documentation/filesystems/nilfs2.txt
Documentation/isdn/00-INDEX
Documentation/isdn/INTERFACE.CAPI
Documentation/isdn/README.gigaset
Documentation/kernel-parameters.txt
Documentation/networking/can.txt
Documentation/networking/ieee802154.txt [new file with mode: 0644]
Documentation/networking/ip-sysctl.txt
Documentation/networking/ipv6.txt
Documentation/networking/mac80211-injection.txt
Documentation/networking/operstates.txt
Documentation/networking/packet_mmap.txt
Documentation/powerpc/dts-bindings/can/sja1000.txt [new file with mode: 0644]
Documentation/powerpc/dts-bindings/ecm.txt [new file with mode: 0644]
Documentation/powerpc/dts-bindings/fsl/cpm_qe/qe.txt
Documentation/powerpc/dts-bindings/fsl/esdhc.txt
Documentation/powerpc/dts-bindings/fsl/mcm.txt [new file with mode: 0644]
Documentation/rfkill.txt
MAINTAINERS
arch/alpha/include/asm/errno.h
arch/arm/kernel/signal.c
arch/arm/mach-pxa/tosa-bt.c
arch/arm/mach-pxa/tosa.c
arch/avr32/kernel/signal.c
arch/ia64/mm/extable.c
arch/mips/include/asm/errno.h
arch/parisc/include/asm/errno.h
arch/powerpc/Kconfig
arch/powerpc/Kconfig.debug
arch/powerpc/Makefile
arch/powerpc/boot/dts/gef_ppc9a.dts
arch/powerpc/boot/dts/gef_sbc310.dts
arch/powerpc/boot/dts/gef_sbc610.dts
arch/powerpc/boot/dts/ksi8560.dts
arch/powerpc/boot/dts/mpc832x_mds.dts
arch/powerpc/boot/dts/mpc832x_rdb.dts
arch/powerpc/boot/dts/mpc8349emitx.dts
arch/powerpc/boot/dts/mpc8349emitxgp.dts
arch/powerpc/boot/dts/mpc834x_mds.dts
arch/powerpc/boot/dts/mpc836x_mds.dts
arch/powerpc/boot/dts/mpc836x_rdk.dts
arch/powerpc/boot/dts/mpc8377_mds.dts
arch/powerpc/boot/dts/mpc8378_mds.dts
arch/powerpc/boot/dts/mpc8379_mds.dts
arch/powerpc/boot/dts/mpc8536ds.dts
arch/powerpc/boot/dts/mpc8540ads.dts
arch/powerpc/boot/dts/mpc8541cds.dts
arch/powerpc/boot/dts/mpc8544ds.dts
arch/powerpc/boot/dts/mpc8548cds.dts
arch/powerpc/boot/dts/mpc8555cds.dts
arch/powerpc/boot/dts/mpc8560ads.dts
arch/powerpc/boot/dts/mpc8568mds.dts
arch/powerpc/boot/dts/mpc8569mds.dts [new file with mode: 0644]
arch/powerpc/boot/dts/mpc8572ds.dts
arch/powerpc/boot/dts/mpc8572ds_36b.dts
arch/powerpc/boot/dts/mpc8572ds_camp_core0.dts
arch/powerpc/boot/dts/mpc8572ds_camp_core1.dts
arch/powerpc/boot/dts/mpc8610_hpcd.dts
arch/powerpc/boot/dts/mpc8641_hpcn.dts
arch/powerpc/boot/dts/mpc8641_hpcn_36b.dts [new file with mode: 0644]
arch/powerpc/boot/dts/p2020ds.dts [new file with mode: 0644]
arch/powerpc/boot/dts/sbc8349.dts
arch/powerpc/boot/dts/sbc8548.dts
arch/powerpc/boot/dts/sbc8560.dts
arch/powerpc/boot/dts/sbc8641d.dts
arch/powerpc/boot/dts/sequoia.dts
arch/powerpc/boot/dts/socrates.dts
arch/powerpc/boot/dts/stx_gp3_8560.dts
arch/powerpc/boot/dts/tqm8540.dts
arch/powerpc/boot/dts/tqm8541.dts
arch/powerpc/boot/dts/tqm8548-bigflash.dts
arch/powerpc/boot/dts/tqm8548.dts
arch/powerpc/boot/dts/tqm8555.dts
arch/powerpc/boot/dts/tqm8560.dts
arch/powerpc/boot/dts/virtex440-ml510.dts [new file with mode: 0644]
arch/powerpc/boot/dts/warp.dts
arch/powerpc/configs/40x/acadia_defconfig
arch/powerpc/configs/40x/ep405_defconfig
arch/powerpc/configs/40x/kilauea_defconfig
arch/powerpc/configs/40x/makalu_defconfig
arch/powerpc/configs/40x/virtex_defconfig
arch/powerpc/configs/44x/arches_defconfig
arch/powerpc/configs/44x/bamboo_defconfig
arch/powerpc/configs/44x/canyonlands_defconfig
arch/powerpc/configs/44x/ebony_defconfig
arch/powerpc/configs/44x/katmai_defconfig
arch/powerpc/configs/44x/rainier_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/virtex5_defconfig
arch/powerpc/include/asm/cpm2.h
arch/powerpc/include/asm/dma-mapping.h
arch/powerpc/include/asm/elf.h
arch/powerpc/include/asm/emulated_ops.h [new file with mode: 0644]
arch/powerpc/include/asm/feature-fixups.h
arch/powerpc/include/asm/lppaca.h
arch/powerpc/include/asm/machdep.h
arch/powerpc/include/asm/mmu.h
arch/powerpc/include/asm/mpc86xx.h [deleted file]
arch/powerpc/include/asm/paca.h
arch/powerpc/include/asm/page.h
arch/powerpc/include/asm/pci-bridge.h
arch/powerpc/include/asm/pgtable-ppc64.h
arch/powerpc/include/asm/ppc-opcode.h
arch/powerpc/include/asm/ppc_asm.h
arch/powerpc/include/asm/ptrace.h
arch/powerpc/include/asm/qe.h
arch/powerpc/include/asm/scatterlist.h
arch/powerpc/include/asm/swiotlb.h [new file with mode: 0644]
arch/powerpc/include/asm/system.h
arch/powerpc/include/asm/xilinx_pci.h [new file with mode: 0644]
arch/powerpc/kernel/Makefile
arch/powerpc/kernel/align.c
arch/powerpc/kernel/asm-offsets.c
arch/powerpc/kernel/cputable.c
arch/powerpc/kernel/dma-swiotlb.c [new file with mode: 0644]
arch/powerpc/kernel/dma.c
arch/powerpc/kernel/exceptions-64s.S [new file with mode: 0644]
arch/powerpc/kernel/ftrace.c
arch/powerpc/kernel/head_32.S
arch/powerpc/kernel/head_64.S
arch/powerpc/kernel/head_booke.h
arch/powerpc/kernel/irq.c
arch/powerpc/kernel/lparcfg.c
arch/powerpc/kernel/misc_64.S
arch/powerpc/kernel/paca.c
arch/powerpc/kernel/pci-common.c
arch/powerpc/kernel/pci_32.c
arch/powerpc/kernel/pci_64.c
arch/powerpc/kernel/pci_dn.c
arch/powerpc/kernel/process.c
arch/powerpc/kernel/prom.c
arch/powerpc/kernel/ptrace.c
arch/powerpc/kernel/rtas_pci.c
arch/powerpc/kernel/setup_32.c
arch/powerpc/kernel/setup_64.c
arch/powerpc/kernel/time.c
arch/powerpc/kernel/traps.c
arch/powerpc/kernel/vector.S
arch/powerpc/mm/Makefile
arch/powerpc/mm/hash_native_64.c
arch/powerpc/mm/init_64.c
arch/powerpc/mm/mmu_context_nohash.c
arch/powerpc/mm/numa.c
arch/powerpc/oprofile/op_model_fsl_emb.c
arch/powerpc/platforms/40x/Kconfig
arch/powerpc/platforms/40x/Makefile
arch/powerpc/platforms/40x/kilauea.c [deleted file]
arch/powerpc/platforms/40x/makalu.c [deleted file]
arch/powerpc/platforms/40x/ppc40x_simple.c
arch/powerpc/platforms/40x/virtex.c
arch/powerpc/platforms/44x/Kconfig
arch/powerpc/platforms/44x/Makefile
arch/powerpc/platforms/44x/virtex.c
arch/powerpc/platforms/44x/virtex_ml510.c [new file with mode: 0644]
arch/powerpc/platforms/44x/warp.c
arch/powerpc/platforms/52xx/efika.c
arch/powerpc/platforms/52xx/mpc52xx_pci.c
arch/powerpc/platforms/82xx/ep8248e.c
arch/powerpc/platforms/82xx/pq2ads.h
arch/powerpc/platforms/85xx/Kconfig
arch/powerpc/platforms/85xx/mpc85xx_ds.c
arch/powerpc/platforms/85xx/mpc85xx_mds.c
arch/powerpc/platforms/86xx/gef_ppc9a.c
arch/powerpc/platforms/86xx/gef_sbc310.c
arch/powerpc/platforms/86xx/gef_sbc610.c
arch/powerpc/platforms/86xx/mpc8610_hpcd.c
arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
arch/powerpc/platforms/86xx/mpc86xx_smp.c
arch/powerpc/platforms/86xx/sbc8641d.c
arch/powerpc/platforms/8xx/mpc885ads.h
arch/powerpc/platforms/Kconfig
arch/powerpc/platforms/Kconfig.cputype
arch/powerpc/platforms/cell/celleb_pci.c
arch/powerpc/platforms/cell/celleb_scc_epci.c
arch/powerpc/platforms/cell/celleb_scc_pciex.c
arch/powerpc/platforms/cell/spufs/inode.c
arch/powerpc/platforms/chrp/pci.c
arch/powerpc/platforms/fsl_uli1575.c
arch/powerpc/platforms/iseries/iommu.c
arch/powerpc/platforms/iseries/pci.c
arch/powerpc/platforms/pasemi/gpio_mdio.c
arch/powerpc/platforms/powermac/pic.c
arch/powerpc/platforms/powermac/setup.c
arch/powerpc/platforms/ps3/smp.c
arch/powerpc/platforms/pseries/iommu.c
arch/powerpc/platforms/pseries/lpar.c
arch/powerpc/platforms/pseries/rtasd.c
arch/powerpc/platforms/pseries/setup.c
arch/powerpc/sysdev/Makefile
arch/powerpc/sysdev/cpm2.c
arch/powerpc/sysdev/fsl_msi.c
arch/powerpc/sysdev/fsl_pci.c
arch/powerpc/sysdev/fsl_pci.h
arch/powerpc/sysdev/fsl_rio.c
arch/powerpc/sysdev/fsl_soc.c
arch/powerpc/sysdev/indirect_pci.c
arch/powerpc/sysdev/mpic.c
arch/powerpc/sysdev/ppc4xx_pci.c
arch/powerpc/sysdev/qe_lib/qe.c
arch/powerpc/sysdev/tsi108_pci.c
arch/powerpc/sysdev/xilinx_intc.c
arch/powerpc/sysdev/xilinx_pci.c [new file with mode: 0644]
arch/powerpc/xmon/xmon.c
arch/sparc/include/asm/errno.h
arch/x86/kernel/apic/x2apic_uv_x.c
drivers/Makefile
drivers/acpi/acpica/acevents.h
drivers/acpi/acpica/acglobal.h
drivers/acpi/acpica/aclocal.h
drivers/acpi/acpica/acnamesp.h
drivers/acpi/acpica/amlcode.h
drivers/acpi/acpica/dsobject.c
drivers/acpi/acpica/dsopcode.c
drivers/acpi/acpica/dswstate.c
drivers/acpi/acpica/evregion.c
drivers/acpi/acpica/evxfevnt.c
drivers/acpi/acpica/exconfig.c
drivers/acpi/acpica/excreate.c
drivers/acpi/acpica/exdump.c
drivers/acpi/acpica/exfldio.c
drivers/acpi/acpica/exmutex.c
drivers/acpi/acpica/exstore.c
drivers/acpi/acpica/hwregs.c
drivers/acpi/acpica/nsalloc.c
drivers/acpi/acpica/nsnames.c
drivers/acpi/acpica/nsobject.c
drivers/acpi/acpica/nspredef.c
drivers/acpi/acpica/nssearch.c
drivers/acpi/acpica/nswalk.c
drivers/acpi/acpica/nsxfname.c
drivers/acpi/acpica/nsxfobj.c
drivers/acpi/acpica/rscalc.c
drivers/acpi/acpica/rsxface.c
drivers/acpi/acpica/tbfadt.c
drivers/acpi/acpica/tbinstal.c
drivers/acpi/acpica/utcopy.c
drivers/acpi/acpica/utdebug.c
drivers/acpi/acpica/utdelete.c
drivers/acpi/acpica/utmisc.c
drivers/acpi/acpica/utmutex.c
drivers/block/aoe/aoecmd.c
drivers/bluetooth/dtl1_cs.c
drivers/bluetooth/hci_vhci.c
drivers/char/pty.c
drivers/char/tty_ldisc.c
drivers/char/viotape.c
drivers/i2c/busses/i2c-ibm_iic.c
drivers/ieee802154/Kconfig [new file with mode: 0644]
drivers/ieee802154/Makefile [new file with mode: 0644]
drivers/ieee802154/fakehard.c [new file with mode: 0644]
drivers/infiniband/ulp/ipoib/ipoib_cm.c
drivers/infiniband/ulp/ipoib/ipoib_main.c
drivers/infiniband/ulp/ipoib/ipoib_multicast.c
drivers/infiniband/ulp/ipoib/ipoib_vlan.c
drivers/isdn/Kconfig
drivers/isdn/capi/capiutil.c
drivers/isdn/capi/kcapi.c
drivers/isdn/gigaset/Kconfig
drivers/isdn/gigaset/asyncdata.c
drivers/isdn/gigaset/common.c
drivers/isdn/gigaset/ev-layer.c
drivers/isdn/gigaset/gigaset.h
drivers/isdn/gigaset/i4l.c
drivers/isdn/gigaset/interface.c
drivers/isdn/gigaset/isocdata.c
drivers/isdn/gigaset/proc.c
drivers/isdn/gigaset/usb-gigaset.c
drivers/isdn/hardware/avm/b1.c
drivers/isdn/hardware/avm/b1dma.c
drivers/isdn/hardware/avm/c4.c
drivers/isdn/hardware/avm/t1isa.c
drivers/isdn/hardware/mISDN/Kconfig
drivers/isdn/hardware/mISDN/hfc_multi.h
drivers/isdn/hardware/mISDN/hfc_multi_8xx.h [new file with mode: 0644]
drivers/isdn/hardware/mISDN/hfcmulti.c
drivers/isdn/hardware/mISDN/hfcpci.c
drivers/isdn/hardware/mISDN/hfcsusb.c
drivers/isdn/hisax/hfc_pci.c
drivers/isdn/hisax/hisax.h
drivers/isdn/hysdn/hycapi.c
drivers/isdn/i4l/Kconfig
drivers/isdn/i4l/isdn_net.c
drivers/isdn/i4l/isdn_tty.c
drivers/isdn/mISDN/core.c
drivers/isdn/mISDN/dsp.h
drivers/isdn/mISDN/dsp_audio.c
drivers/isdn/mISDN/dsp_cmx.c
drivers/isdn/mISDN/dsp_core.c
drivers/isdn/mISDN/dsp_dtmf.c
drivers/isdn/mISDN/dsp_ecdis.h
drivers/isdn/mISDN/dsp_pipeline.c
drivers/isdn/mISDN/dsp_tones.c
drivers/isdn/mISDN/hwchannel.c
drivers/isdn/mISDN/l1oip.h
drivers/isdn/mISDN/l1oip_codec.c
drivers/isdn/mISDN/l1oip_core.c
drivers/isdn/mISDN/layer2.c
drivers/isdn/mISDN/layer2.h
drivers/isdn/mISDN/socket.c
drivers/isdn/mISDN/tei.c
drivers/isdn/mISDN/timerdev.c
drivers/macintosh/therm_adt746x.c
drivers/message/fusion/mptlan.c
drivers/misc/sgi-xp/xpnet.c
drivers/net/3c501.c
drivers/net/3c503.c
drivers/net/3c505.c
drivers/net/3c507.c
drivers/net/3c509.c
drivers/net/3c515.c
drivers/net/3c523.c
drivers/net/3c527.c
drivers/net/3c59x.c
drivers/net/7990.c
drivers/net/8139cp.c
drivers/net/8139too.c
drivers/net/82596.c
drivers/net/8390.c
drivers/net/8390p.c
drivers/net/Kconfig
drivers/net/Makefile
drivers/net/a2065.c
drivers/net/acenic.c
drivers/net/appletalk/ipddp.c
drivers/net/arm/at91_ether.c
drivers/net/arm/ep93xx_eth.c
drivers/net/arm/ether3.c
drivers/net/arm/ixp4xx_eth.c
drivers/net/atl1c/atl1c_ethtool.c
drivers/net/atl1c/atl1c_main.c
drivers/net/atl1e/atl1e.h
drivers/net/atl1e/atl1e_main.c
drivers/net/atlx/atl1.c
drivers/net/au1000_eth.c
drivers/net/b44.c
drivers/net/b44.h
drivers/net/benet/be_main.c
drivers/net/bfin_mac.c
drivers/net/bmac.c
drivers/net/bnx2.c
drivers/net/bnx2.h
drivers/net/bnx2x.h
drivers/net/bnx2x_fw_file_hdr.h [new file with mode: 0644]
drivers/net/bnx2x_init.h
drivers/net/bnx2x_init_ops.h [new file with mode: 0644]
drivers/net/bnx2x_init_values.h [deleted file]
drivers/net/bnx2x_main.c
drivers/net/bonding/bond_3ad.c
drivers/net/bonding/bond_3ad.h
drivers/net/bonding/bond_main.c
drivers/net/bonding/bond_sysfs.c
drivers/net/bonding/bonding.h
drivers/net/can/Kconfig
drivers/net/can/Makefile
drivers/net/can/dev.c [new file with mode: 0644]
drivers/net/can/sja1000/Makefile [new file with mode: 0644]
drivers/net/can/sja1000/ems_pci.c [new file with mode: 0644]
drivers/net/can/sja1000/kvaser_pci.c [new file with mode: 0644]
drivers/net/can/sja1000/sja1000.c [new file with mode: 0644]
drivers/net/can/sja1000/sja1000.h [new file with mode: 0644]
drivers/net/can/sja1000/sja1000_of_platform.c [new file with mode: 0644]
drivers/net/can/sja1000/sja1000_platform.c [new file with mode: 0644]
drivers/net/cassini.c
drivers/net/chelsio/common.h
drivers/net/chelsio/cphy.h
drivers/net/chelsio/cxgb2.c
drivers/net/chelsio/mv88e1xxx.c
drivers/net/chelsio/mv88x201x.c
drivers/net/chelsio/my3126.c
drivers/net/chelsio/sge.c
drivers/net/chelsio/subr.c
drivers/net/cpmac.c
drivers/net/cs89x0.c
drivers/net/cxgb3/Makefile
drivers/net/cxgb3/adapter.h
drivers/net/cxgb3/ael1002.c
drivers/net/cxgb3/aq100x.c [new file with mode: 0644]
drivers/net/cxgb3/common.h
drivers/net/cxgb3/cxgb3_main.c
drivers/net/cxgb3/cxgb3_offload.c
drivers/net/cxgb3/cxgb3_offload.h
drivers/net/cxgb3/sge.c
drivers/net/cxgb3/t3_hw.c
drivers/net/cxgb3/version.h
drivers/net/cxgb3/vsc8211.c
drivers/net/davinci_emac.c [new file with mode: 0644]
drivers/net/de600.c
drivers/net/de620.c
drivers/net/declance.c
drivers/net/defxx.c
drivers/net/depca.c
drivers/net/dl2k.c
drivers/net/dm9000.c
drivers/net/e100.c
drivers/net/e1000/e1000_main.c
drivers/net/e1000e/82571.c
drivers/net/e1000e/defines.h
drivers/net/e1000e/e1000.h
drivers/net/e1000e/es2lan.c
drivers/net/e1000e/ethtool.c
drivers/net/e1000e/hw.h
drivers/net/e1000e/ich8lan.c
drivers/net/e1000e/lib.c
drivers/net/e1000e/netdev.c
drivers/net/e1000e/param.c
drivers/net/e1000e/phy.c
drivers/net/ehea/ehea_main.c
drivers/net/enic/enic_main.c
drivers/net/eql.c
drivers/net/ethoc.c
drivers/net/ewrk3.c
drivers/net/fec.c
drivers/net/fec.h
drivers/net/fec_mpc52xx.c
drivers/net/fec_mpc52xx_phy.c
drivers/net/forcedeth.c
drivers/net/fs_enet/fs_enet-main.c
drivers/net/fs_enet/fs_enet.h
drivers/net/fs_enet/mac-fec.c
drivers/net/fs_enet/mii-bitbang.c
drivers/net/fs_enet/mii-fec.c
drivers/net/fsl_pq_mdio.c
drivers/net/gianfar.c
drivers/net/gianfar.h
drivers/net/hamachi.c
drivers/net/hamradio/baycom_epp.c
drivers/net/hamradio/bpqether.c
drivers/net/hamradio/hdlcdrv.c
drivers/net/hamradio/mkiss.c
drivers/net/hp100.c
drivers/net/hplance.c
drivers/net/ibm_newemac/core.c
drivers/net/ibmlana.c
drivers/net/ibmveth.c
drivers/net/ifb.c
drivers/net/igb/e1000_82575.h
drivers/net/igb/e1000_defines.h
drivers/net/igb/e1000_mbx.c
drivers/net/igb/e1000_phy.h
drivers/net/igb/e1000_regs.h
drivers/net/igb/igb.h
drivers/net/igb/igb_ethtool.c
drivers/net/igb/igb_main.c
drivers/net/igbvf/ethtool.c
drivers/net/igbvf/igbvf.h
drivers/net/igbvf/netdev.c
drivers/net/ioc3-eth.c
drivers/net/irda/Kconfig
drivers/net/irda/Makefile
drivers/net/irda/au1k_ir.c
drivers/net/irda/bfin_sir.c [new file with mode: 0644]
drivers/net/irda/bfin_sir.h [new file with mode: 0644]
drivers/net/irda/donauboe.c
drivers/net/irda/irda-usb.c
drivers/net/irda/kingsun-sir.c
drivers/net/irda/ks959-sir.c
drivers/net/irda/ksdazzle-sir.c
drivers/net/irda/mcs7780.c
drivers/net/irda/pxaficp_ir.c
drivers/net/irda/sa1100_ir.c
drivers/net/irda/sir_dev.c
drivers/net/irda/smsc-ircc2.c
drivers/net/iseries_veth.c
drivers/net/ixgb/ixgb_hw.c
drivers/net/ixgb/ixgb_hw.h
drivers/net/ixgb/ixgb_main.c
drivers/net/ixgb/ixgb_osdep.h
drivers/net/ixgbe/Makefile
drivers/net/ixgbe/ixgbe.h
drivers/net/ixgbe/ixgbe_82598.c
drivers/net/ixgbe/ixgbe_82599.c
drivers/net/ixgbe/ixgbe_common.c
drivers/net/ixgbe/ixgbe_common.h
drivers/net/ixgbe/ixgbe_dcb_82598.c
drivers/net/ixgbe/ixgbe_dcb_82599.c
drivers/net/ixgbe/ixgbe_dcb_nl.c
drivers/net/ixgbe/ixgbe_ethtool.c
drivers/net/ixgbe/ixgbe_fcoe.c [new file with mode: 0644]
drivers/net/ixgbe/ixgbe_fcoe.h [new file with mode: 0644]
drivers/net/ixgbe/ixgbe_main.c
drivers/net/ixgbe/ixgbe_phy.c
drivers/net/ixgbe/ixgbe_phy.h
drivers/net/ixgbe/ixgbe_type.h
drivers/net/ixp2000/ixpdev.c
drivers/net/jazzsonic.c
drivers/net/jme.c
drivers/net/korina.c
drivers/net/ks8842.c [new file with mode: 0644]
drivers/net/lasi_82596.c
drivers/net/lib82596.c
drivers/net/lib8390.c
drivers/net/ll_temac.h [new file with mode: 0644]
drivers/net/ll_temac_main.c [new file with mode: 0644]
drivers/net/ll_temac_mdio.c [new file with mode: 0644]
drivers/net/loopback.c
drivers/net/mac8390.c
drivers/net/mac89x0.c
drivers/net/macb.c
drivers/net/mace.c
drivers/net/macmace.c
drivers/net/macvlan.c
drivers/net/mdio.c [new file with mode: 0644]
drivers/net/meth.c
drivers/net/mii.c
drivers/net/mipsnet.c
drivers/net/mlx4/Makefile
drivers/net/mlx4/en_cq.c
drivers/net/mlx4/en_ethtool.c [new file with mode: 0644]
drivers/net/mlx4/en_main.c
drivers/net/mlx4/en_netdev.c
drivers/net/mlx4/en_params.c [deleted file]
drivers/net/mlx4/en_rx.c
drivers/net/mlx4/en_tx.c
drivers/net/mlx4/eq.c
drivers/net/mlx4/mlx4_en.h
drivers/net/mlx4/mr.c
drivers/net/mv643xx_eth.c
drivers/net/mvme147.c
drivers/net/myri10ge/myri10ge.c
drivers/net/myri_sbus.c
drivers/net/ne2k-pci.c
drivers/net/ne3210.c
drivers/net/netx-eth.c
drivers/net/netxen/netxen_nic.h
drivers/net/netxen/netxen_nic_ctx.c
drivers/net/netxen/netxen_nic_ethtool.c
drivers/net/netxen/netxen_nic_hdr.h
drivers/net/netxen/netxen_nic_hw.c
drivers/net/netxen/netxen_nic_hw.h
drivers/net/netxen/netxen_nic_init.c
drivers/net/netxen/netxen_nic_main.c
drivers/net/netxen/netxen_nic_niu.c
drivers/net/netxen/netxen_nic_phan_reg.h
drivers/net/ni65.c
drivers/net/niu.c
drivers/net/ns83820.c
drivers/net/pasemi_mac.c
drivers/net/pasemi_mac.h
drivers/net/pci-skeleton.c
drivers/net/pcmcia/3c574_cs.c
drivers/net/pcmcia/3c589_cs.c
drivers/net/pcmcia/axnet_cs.c
drivers/net/pcmcia/fmvj18x_cs.c
drivers/net/pcmcia/smc91c92_cs.c
drivers/net/pcmcia/xirc2ps_cs.c
drivers/net/pcnet32.c
drivers/net/phy/marvell.c
drivers/net/phy/mdio_bus.c
drivers/net/phy/phy_device.c
drivers/net/plip.c
drivers/net/ppp_generic.c
drivers/net/pppol2tp.c
drivers/net/qla3xxx.c
drivers/net/qlge/qlge.h
drivers/net/qlge/qlge_ethtool.c
drivers/net/qlge/qlge_main.c
drivers/net/qlge/qlge_mpi.c
drivers/net/r6040.c
drivers/net/r8169.c
drivers/net/rionet.c
drivers/net/rrunner.c
drivers/net/s2io-regs.h
drivers/net/s2io.c
drivers/net/s2io.h
drivers/net/sb1250-mac.c
drivers/net/sfc/Kconfig
drivers/net/sfc/boards.c
drivers/net/sfc/efx.c
drivers/net/sfc/ethtool.c
drivers/net/sfc/falcon.c
drivers/net/sfc/falcon_hwdefs.h
drivers/net/sfc/falcon_xmac.c
drivers/net/sfc/mdio_10g.c
drivers/net/sfc/mdio_10g.h
drivers/net/sfc/net_driver.h
drivers/net/sfc/rx.c
drivers/net/sfc/selftest.c
drivers/net/sfc/selftest.h
drivers/net/sfc/sfe4001.c
drivers/net/sfc/tenxpress.c
drivers/net/sfc/tx.c
drivers/net/sfc/xenpack.h [deleted file]
drivers/net/sfc/xfp_phy.c
drivers/net/sgiseeq.c
drivers/net/sh_eth.c
drivers/net/sh_eth.h
drivers/net/sis190.c
drivers/net/sis900.c
drivers/net/skfp/skfddi.c
drivers/net/skge.c
drivers/net/sky2.c
drivers/net/smc-mca.c
drivers/net/smc911x.c
drivers/net/smc9194.c
drivers/net/smsc911x.c
drivers/net/sonic.c
drivers/net/starfire.c
drivers/net/sun3_82586.c
drivers/net/sun3lance.c
drivers/net/sundance.c
drivers/net/sunhme.c
drivers/net/tc35815.c
drivers/net/tehuti.c
drivers/net/tg3.c
drivers/net/tg3.h
drivers/net/tlan.c
drivers/net/tokenring/3c359.c
drivers/net/tokenring/lanstreamer.c
drivers/net/tokenring/olympic.c
drivers/net/tokenring/smctr.c
drivers/net/tokenring/tms380tr.c
drivers/net/tulip/Kconfig
drivers/net/tulip/de2104x.c
drivers/net/tulip/de4x5.c
drivers/net/tulip/dmfe.c
drivers/net/tulip/uli526x.c
drivers/net/tulip/winbond-840.c
drivers/net/tun.c
drivers/net/ucc_geth.c
drivers/net/ucc_geth.h
drivers/net/usb/Kconfig
drivers/net/usb/Makefile
drivers/net/usb/cdc_ether.c
drivers/net/usb/dm9601.c
drivers/net/usb/hso.c
drivers/net/usb/int51x1.c [new file with mode: 0644]
drivers/net/usb/kaweth.c
drivers/net/usb/rtl8150.c
drivers/net/usb/smsc95xx.c
drivers/net/usb/usbnet.c
drivers/net/veth.c
drivers/net/via-rhine.c
drivers/net/via-velocity.c
drivers/net/via-velocity.h
drivers/net/virtio_net.c
drivers/net/vxge/vxge-config.c
drivers/net/vxge/vxge-main.c
drivers/net/vxge/vxge-traffic.c
drivers/net/wan/cycx_x25.c
drivers/net/wan/dlci.c
drivers/net/wan/hdlc_fr.c
drivers/net/wan/ixp4xx_hss.c
drivers/net/wan/pc300_drv.c
drivers/net/wan/sbni.c
drivers/net/wan/wanxl.c
drivers/net/wimax/i2400m/control.c
drivers/net/wimax/i2400m/driver.c
drivers/net/wimax/i2400m/fw.c
drivers/net/wimax/i2400m/i2400m-sdio.h
drivers/net/wimax/i2400m/i2400m.h
drivers/net/wimax/i2400m/netdev.c
drivers/net/wimax/i2400m/op-rfkill.c
drivers/net/wimax/i2400m/rx.c
drivers/net/wimax/i2400m/sdio-fw.c
drivers/net/wimax/i2400m/sdio-rx.c
drivers/net/wimax/i2400m/sdio.c
drivers/net/wimax/i2400m/tx.c
drivers/net/wimax/i2400m/usb.c
drivers/net/wireless/Kconfig
drivers/net/wireless/Makefile
drivers/net/wireless/adm8211.c
drivers/net/wireless/airo.c
drivers/net/wireless/ar9170/Kconfig [deleted file]
drivers/net/wireless/ar9170/Makefile [deleted file]
drivers/net/wireless/ar9170/ar9170.h [deleted file]
drivers/net/wireless/ar9170/cmd.c [deleted file]
drivers/net/wireless/ar9170/cmd.h [deleted file]
drivers/net/wireless/ar9170/eeprom.h [deleted file]
drivers/net/wireless/ar9170/hw.h [deleted file]
drivers/net/wireless/ar9170/led.c [deleted file]
drivers/net/wireless/ar9170/mac.c [deleted file]
drivers/net/wireless/ar9170/main.c [deleted file]
drivers/net/wireless/ar9170/phy.c [deleted file]
drivers/net/wireless/ar9170/usb.c [deleted file]
drivers/net/wireless/ar9170/usb.h [deleted file]
drivers/net/wireless/arlan-main.c
drivers/net/wireless/at76c50x-usb.c
drivers/net/wireless/ath/Kconfig [new file with mode: 0644]
drivers/net/wireless/ath/Makefile [new file with mode: 0644]
drivers/net/wireless/ath/ar9170/Kconfig [new file with mode: 0644]
drivers/net/wireless/ath/ar9170/Makefile [new file with mode: 0644]
drivers/net/wireless/ath/ar9170/ar9170.h [new file with mode: 0644]
drivers/net/wireless/ath/ar9170/cmd.c [new file with mode: 0644]
drivers/net/wireless/ath/ar9170/cmd.h [new file with mode: 0644]
drivers/net/wireless/ath/ar9170/eeprom.h [new file with mode: 0644]
drivers/net/wireless/ath/ar9170/hw.h [new file with mode: 0644]
drivers/net/wireless/ath/ar9170/led.c [new file with mode: 0644]
drivers/net/wireless/ath/ar9170/mac.c [new file with mode: 0644]
drivers/net/wireless/ath/ar9170/main.c [new file with mode: 0644]
drivers/net/wireless/ath/ar9170/phy.c [new file with mode: 0644]
drivers/net/wireless/ath/ar9170/usb.c [new file with mode: 0644]
drivers/net/wireless/ath/ar9170/usb.h [new file with mode: 0644]
drivers/net/wireless/ath/ath5k/Kconfig [new file with mode: 0644]
drivers/net/wireless/ath/ath5k/Makefile [new file with mode: 0644]
drivers/net/wireless/ath/ath5k/ath5k.h [new file with mode: 0644]
drivers/net/wireless/ath/ath5k/attach.c [new file with mode: 0644]
drivers/net/wireless/ath/ath5k/base.c [new file with mode: 0644]
drivers/net/wireless/ath/ath5k/base.h [new file with mode: 0644]
drivers/net/wireless/ath/ath5k/caps.c [new file with mode: 0644]
drivers/net/wireless/ath/ath5k/debug.c [new file with mode: 0644]
drivers/net/wireless/ath/ath5k/debug.h [new file with mode: 0644]
drivers/net/wireless/ath/ath5k/desc.c [new file with mode: 0644]
drivers/net/wireless/ath/ath5k/desc.h [new file with mode: 0644]
drivers/net/wireless/ath/ath5k/dma.c [new file with mode: 0644]
drivers/net/wireless/ath/ath5k/eeprom.c [new file with mode: 0644]
drivers/net/wireless/ath/ath5k/eeprom.h [new file with mode: 0644]
drivers/net/wireless/ath/ath5k/gpio.c [new file with mode: 0644]
drivers/net/wireless/ath/ath5k/initvals.c [new file with mode: 0644]
drivers/net/wireless/ath/ath5k/led.c [new file with mode: 0644]
drivers/net/wireless/ath/ath5k/pcu.c [new file with mode: 0644]
drivers/net/wireless/ath/ath5k/phy.c [new file with mode: 0644]
drivers/net/wireless/ath/ath5k/qcu.c [new file with mode: 0644]
drivers/net/wireless/ath/ath5k/reg.h [new file with mode: 0644]
drivers/net/wireless/ath/ath5k/reset.c [new file with mode: 0644]
drivers/net/wireless/ath/ath5k/rfbuffer.h [new file with mode: 0644]
drivers/net/wireless/ath/ath5k/rfgain.h [new file with mode: 0644]
drivers/net/wireless/ath/ath5k/rfkill.c [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/Kconfig [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/Makefile [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/ahb.c [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/ani.c [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/ani.h [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/ath9k.h [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/beacon.c [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/calib.c [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/calib.h [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/debug.c [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/debug.h [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/eeprom.c [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/eeprom.h [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/hw.c [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/hw.h [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/initvals.h [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/mac.c [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/mac.h [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/main.c [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/pci.c [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/phy.c [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/phy.h [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/rc.c [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/rc.h [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/recv.c [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/reg.h [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/virtual.c [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/xmit.c [new file with mode: 0644]
drivers/net/wireless/ath/main.c [new file with mode: 0644]
drivers/net/wireless/ath/regd.c [new file with mode: 0644]
drivers/net/wireless/ath/regd.h [new file with mode: 0644]
drivers/net/wireless/ath/regd_common.h [new file with mode: 0644]
drivers/net/wireless/ath5k/Kconfig [deleted file]
drivers/net/wireless/ath5k/Makefile [deleted file]
drivers/net/wireless/ath5k/ath5k.h [deleted file]
drivers/net/wireless/ath5k/attach.c [deleted file]
drivers/net/wireless/ath5k/base.c [deleted file]
drivers/net/wireless/ath5k/base.h [deleted file]
drivers/net/wireless/ath5k/caps.c [deleted file]
drivers/net/wireless/ath5k/debug.c [deleted file]
drivers/net/wireless/ath5k/debug.h [deleted file]
drivers/net/wireless/ath5k/desc.c [deleted file]
drivers/net/wireless/ath5k/desc.h [deleted file]
drivers/net/wireless/ath5k/dma.c [deleted file]
drivers/net/wireless/ath5k/eeprom.c [deleted file]
drivers/net/wireless/ath5k/eeprom.h [deleted file]
drivers/net/wireless/ath5k/gpio.c [deleted file]
drivers/net/wireless/ath5k/initvals.c [deleted file]
drivers/net/wireless/ath5k/led.c [deleted file]
drivers/net/wireless/ath5k/pcu.c [deleted file]
drivers/net/wireless/ath5k/phy.c [deleted file]
drivers/net/wireless/ath5k/qcu.c [deleted file]
drivers/net/wireless/ath5k/reg.h [deleted file]
drivers/net/wireless/ath5k/reset.c [deleted file]
drivers/net/wireless/ath5k/rfbuffer.h [deleted file]
drivers/net/wireless/ath5k/rfgain.h [deleted file]
drivers/net/wireless/ath9k/Kconfig [deleted file]
drivers/net/wireless/ath9k/Makefile [deleted file]
drivers/net/wireless/ath9k/ahb.c [deleted file]
drivers/net/wireless/ath9k/ani.c [deleted file]
drivers/net/wireless/ath9k/ani.h [deleted file]
drivers/net/wireless/ath9k/ath9k.h [deleted file]
drivers/net/wireless/ath9k/beacon.c [deleted file]
drivers/net/wireless/ath9k/calib.c [deleted file]
drivers/net/wireless/ath9k/calib.h [deleted file]
drivers/net/wireless/ath9k/debug.c [deleted file]
drivers/net/wireless/ath9k/debug.h [deleted file]
drivers/net/wireless/ath9k/eeprom.c [deleted file]
drivers/net/wireless/ath9k/eeprom.h [deleted file]
drivers/net/wireless/ath9k/hw.c [deleted file]
drivers/net/wireless/ath9k/hw.h [deleted file]
drivers/net/wireless/ath9k/initvals.h [deleted file]
drivers/net/wireless/ath9k/mac.c [deleted file]
drivers/net/wireless/ath9k/mac.h [deleted file]
drivers/net/wireless/ath9k/main.c [deleted file]
drivers/net/wireless/ath9k/pci.c [deleted file]
drivers/net/wireless/ath9k/phy.c [deleted file]
drivers/net/wireless/ath9k/phy.h [deleted file]
drivers/net/wireless/ath9k/rc.c [deleted file]
drivers/net/wireless/ath9k/rc.h [deleted file]
drivers/net/wireless/ath9k/recv.c [deleted file]
drivers/net/wireless/ath9k/reg.h [deleted file]
drivers/net/wireless/ath9k/regd.c [deleted file]
drivers/net/wireless/ath9k/regd.h [deleted file]
drivers/net/wireless/ath9k/regd_common.h [deleted file]
drivers/net/wireless/ath9k/virtual.c [deleted file]
drivers/net/wireless/ath9k/xmit.c [deleted file]
drivers/net/wireless/atmel.c
drivers/net/wireless/atmel_cs.c
drivers/net/wireless/b43/Kconfig
drivers/net/wireless/b43/Makefile
drivers/net/wireless/b43/b43.h
drivers/net/wireless/b43/dma.c
drivers/net/wireless/b43/leds.c
drivers/net/wireless/b43/main.c
drivers/net/wireless/b43/main.h
drivers/net/wireless/b43/phy_a.c
drivers/net/wireless/b43/phy_common.c
drivers/net/wireless/b43/phy_common.h
drivers/net/wireless/b43/phy_g.c
drivers/net/wireless/b43/phy_lp.c
drivers/net/wireless/b43/phy_n.c
drivers/net/wireless/b43/pio.c
drivers/net/wireless/b43/rfkill.c
drivers/net/wireless/b43/rfkill.h
drivers/net/wireless/b43/xmit.c
drivers/net/wireless/b43legacy/Kconfig
drivers/net/wireless/b43legacy/Makefile
drivers/net/wireless/b43legacy/b43legacy.h
drivers/net/wireless/b43legacy/leds.c
drivers/net/wireless/b43legacy/main.c
drivers/net/wireless/b43legacy/pio.c
drivers/net/wireless/b43legacy/rfkill.c
drivers/net/wireless/b43legacy/rfkill.h
drivers/net/wireless/b43legacy/xmit.c
drivers/net/wireless/b43legacy/xmit.h
drivers/net/wireless/hostap/hostap_80211_tx.c
drivers/net/wireless/hostap/hostap_hw.c
drivers/net/wireless/hostap/hostap_plx.c
drivers/net/wireless/ipw2x00/ipw2100.c
drivers/net/wireless/ipw2x00/ipw2200.c
drivers/net/wireless/ipw2x00/libipw_module.c
drivers/net/wireless/ipw2x00/libipw_tx.c
drivers/net/wireless/iwlwifi/Kconfig
drivers/net/wireless/iwlwifi/Makefile
drivers/net/wireless/iwlwifi/iwl-3945-led.c
drivers/net/wireless/iwlwifi/iwl-3945-rs.c
drivers/net/wireless/iwlwifi/iwl-3945.c
drivers/net/wireless/iwlwifi/iwl-3945.h
drivers/net/wireless/iwlwifi/iwl-4965.c
drivers/net/wireless/iwlwifi/iwl-5000-hw.h
drivers/net/wireless/iwlwifi/iwl-5000.c
drivers/net/wireless/iwlwifi/iwl-agn-rs.c
drivers/net/wireless/iwlwifi/iwl-agn-rs.h
drivers/net/wireless/iwlwifi/iwl-agn.c
drivers/net/wireless/iwlwifi/iwl-calib.c
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-csr.h
drivers/net/wireless/iwlwifi/iwl-debug.h
drivers/net/wireless/iwlwifi/iwl-debugfs.c
drivers/net/wireless/iwlwifi/iwl-dev.h
drivers/net/wireless/iwlwifi/iwl-eeprom.c
drivers/net/wireless/iwlwifi/iwl-eeprom.h
drivers/net/wireless/iwlwifi/iwl-io.h
drivers/net/wireless/iwlwifi/iwl-led.c
drivers/net/wireless/iwlwifi/iwl-power.c
drivers/net/wireless/iwlwifi/iwl-power.h
drivers/net/wireless/iwlwifi/iwl-rfkill.c [deleted file]
drivers/net/wireless/iwlwifi/iwl-rfkill.h [deleted file]
drivers/net/wireless/iwlwifi/iwl-rx.c
drivers/net/wireless/iwlwifi/iwl-scan.c
drivers/net/wireless/iwlwifi/iwl-sta.c
drivers/net/wireless/iwlwifi/iwl-sta.h
drivers/net/wireless/iwlwifi/iwl-tx.c
drivers/net/wireless/iwlwifi/iwl3945-base.c
drivers/net/wireless/iwmc3200wifi/Kconfig [new file with mode: 0644]
drivers/net/wireless/iwmc3200wifi/Makefile [new file with mode: 0644]
drivers/net/wireless/iwmc3200wifi/bus.h [new file with mode: 0644]
drivers/net/wireless/iwmc3200wifi/cfg80211.c [new file with mode: 0644]
drivers/net/wireless/iwmc3200wifi/cfg80211.h [new file with mode: 0644]
drivers/net/wireless/iwmc3200wifi/commands.c [new file with mode: 0644]
drivers/net/wireless/iwmc3200wifi/commands.h [new file with mode: 0644]
drivers/net/wireless/iwmc3200wifi/debug.h [new file with mode: 0644]
drivers/net/wireless/iwmc3200wifi/debugfs.c [new file with mode: 0644]
drivers/net/wireless/iwmc3200wifi/eeprom.c [new file with mode: 0644]
drivers/net/wireless/iwmc3200wifi/eeprom.h [new file with mode: 0644]
drivers/net/wireless/iwmc3200wifi/fw.c [new file with mode: 0644]
drivers/net/wireless/iwmc3200wifi/fw.h [new file with mode: 0644]
drivers/net/wireless/iwmc3200wifi/hal.c [new file with mode: 0644]
drivers/net/wireless/iwmc3200wifi/hal.h [new file with mode: 0644]
drivers/net/wireless/iwmc3200wifi/iwm.h [new file with mode: 0644]
drivers/net/wireless/iwmc3200wifi/lmac.h [new file with mode: 0644]
drivers/net/wireless/iwmc3200wifi/main.c [new file with mode: 0644]
drivers/net/wireless/iwmc3200wifi/netdev.c [new file with mode: 0644]
drivers/net/wireless/iwmc3200wifi/rx.c [new file with mode: 0644]
drivers/net/wireless/iwmc3200wifi/rx.h [new file with mode: 0644]
drivers/net/wireless/iwmc3200wifi/sdio.c [new file with mode: 0644]
drivers/net/wireless/iwmc3200wifi/sdio.h [new file with mode: 0644]
drivers/net/wireless/iwmc3200wifi/tx.c [new file with mode: 0644]
drivers/net/wireless/iwmc3200wifi/umac.h [new file with mode: 0644]
drivers/net/wireless/iwmc3200wifi/wext.c [new file with mode: 0644]
drivers/net/wireless/libertas/11d.c
drivers/net/wireless/libertas/11d.h
drivers/net/wireless/libertas/assoc.c
drivers/net/wireless/libertas/assoc.h
drivers/net/wireless/libertas/cmd.c
drivers/net/wireless/libertas/cmdresp.c
drivers/net/wireless/libertas/debugfs.c
drivers/net/wireless/libertas/defs.h
drivers/net/wireless/libertas/dev.h
drivers/net/wireless/libertas/host.h
drivers/net/wireless/libertas/hostcmd.h
drivers/net/wireless/libertas/if_cs.c
drivers/net/wireless/libertas/if_sdio.c
drivers/net/wireless/libertas/if_sdio.h
drivers/net/wireless/libertas/if_spi.c
drivers/net/wireless/libertas/if_usb.c
drivers/net/wireless/libertas/main.c
drivers/net/wireless/libertas/rx.c
drivers/net/wireless/libertas/scan.c
drivers/net/wireless/libertas/tx.c
drivers/net/wireless/libertas/types.h
drivers/net/wireless/libertas_tf/if_usb.c
drivers/net/wireless/libertas_tf/main.c
drivers/net/wireless/mac80211_hwsim.c
drivers/net/wireless/mwl8k.c
drivers/net/wireless/p54/p54.h
drivers/net/wireless/p54/p54common.c
drivers/net/wireless/p54/p54spi.c
drivers/net/wireless/p54/p54usb.c
drivers/net/wireless/p54/p54usb.h
drivers/net/wireless/prism54/islpci_eth.c
drivers/net/wireless/ray_cs.c
drivers/net/wireless/rndis_wlan.c
drivers/net/wireless/rt2x00/Kconfig
drivers/net/wireless/rt2x00/Makefile
drivers/net/wireless/rt2x00/rt2400pci.c
drivers/net/wireless/rt2x00/rt2500pci.c
drivers/net/wireless/rt2x00/rt2500usb.c
drivers/net/wireless/rt2x00/rt2800usb.c [new file with mode: 0644]
drivers/net/wireless/rt2x00/rt2800usb.h [new file with mode: 0644]
drivers/net/wireless/rt2x00/rt2x00.h
drivers/net/wireless/rt2x00/rt2x00config.c
drivers/net/wireless/rt2x00/rt2x00crypto.c
drivers/net/wireless/rt2x00/rt2x00dev.c
drivers/net/wireless/rt2x00/rt2x00ht.c [new file with mode: 0644]
drivers/net/wireless/rt2x00/rt2x00lib.h
drivers/net/wireless/rt2x00/rt2x00link.c
drivers/net/wireless/rt2x00/rt2x00mac.c
drivers/net/wireless/rt2x00/rt2x00pci.c
drivers/net/wireless/rt2x00/rt2x00queue.c
drivers/net/wireless/rt2x00/rt2x00queue.h
drivers/net/wireless/rt2x00/rt61pci.c
drivers/net/wireless/rt2x00/rt61pci.h
drivers/net/wireless/rt2x00/rt73usb.c
drivers/net/wireless/rtl818x/Makefile
drivers/net/wireless/rtl818x/rtl8180_dev.c
drivers/net/wireless/rtl818x/rtl8187.h
drivers/net/wireless/rtl818x/rtl8187_dev.c
drivers/net/wireless/rtl818x/rtl8187_leds.c [new file with mode: 0644]
drivers/net/wireless/rtl818x/rtl8187_leds.h [new file with mode: 0644]
drivers/net/wireless/strip.c
drivers/net/wireless/wavelan.c
drivers/net/wireless/wavelan_cs.c
drivers/net/wireless/wl12xx/Kconfig [new file with mode: 0644]
drivers/net/wireless/wl12xx/Makefile [new file with mode: 0644]
drivers/net/wireless/wl12xx/acx.c [new file with mode: 0644]
drivers/net/wireless/wl12xx/acx.h [new file with mode: 0644]
drivers/net/wireless/wl12xx/boot.c [new file with mode: 0644]
drivers/net/wireless/wl12xx/boot.h [new file with mode: 0644]
drivers/net/wireless/wl12xx/cmd.c [new file with mode: 0644]
drivers/net/wireless/wl12xx/cmd.h [new file with mode: 0644]
drivers/net/wireless/wl12xx/debugfs.c [new file with mode: 0644]
drivers/net/wireless/wl12xx/debugfs.h [new file with mode: 0644]
drivers/net/wireless/wl12xx/event.c [new file with mode: 0644]
drivers/net/wireless/wl12xx/event.h [new file with mode: 0644]
drivers/net/wireless/wl12xx/init.c [new file with mode: 0644]
drivers/net/wireless/wl12xx/init.h [new file with mode: 0644]
drivers/net/wireless/wl12xx/main.c [new file with mode: 0644]
drivers/net/wireless/wl12xx/ps.c [new file with mode: 0644]
drivers/net/wireless/wl12xx/ps.h [new file with mode: 0644]
drivers/net/wireless/wl12xx/reg.h [new file with mode: 0644]
drivers/net/wireless/wl12xx/rx.c [new file with mode: 0644]
drivers/net/wireless/wl12xx/rx.h [new file with mode: 0644]
drivers/net/wireless/wl12xx/spi.c [new file with mode: 0644]
drivers/net/wireless/wl12xx/spi.h [new file with mode: 0644]
drivers/net/wireless/wl12xx/tx.c [new file with mode: 0644]
drivers/net/wireless/wl12xx/tx.h [new file with mode: 0644]
drivers/net/wireless/wl12xx/wl1251.c [new file with mode: 0644]
drivers/net/wireless/wl12xx/wl1251.h [new file with mode: 0644]
drivers/net/wireless/wl12xx/wl12xx.h [new file with mode: 0644]
drivers/net/wireless/wl12xx/wl12xx_80211.h [new file with mode: 0644]
drivers/net/wireless/wl3501_cs.c
drivers/net/wireless/zd1201.c
drivers/net/wireless/zd1211rw/zd_mac.c
drivers/net/wireless/zd1211rw/zd_mac.h
drivers/net/yellowfin.c
drivers/of/Kconfig
drivers/of/Makefile
drivers/of/base.c
drivers/of/of_mdio.c [new file with mode: 0644]
drivers/pci/Makefile
drivers/pci/quirks.c
drivers/platform/x86/Kconfig
drivers/platform/x86/acer-wmi.c
drivers/platform/x86/dell-laptop.c
drivers/platform/x86/eeepc-laptop.c
drivers/platform/x86/hp-wmi.c
drivers/platform/x86/sony-laptop.c
drivers/platform/x86/thinkpad_acpi.c
drivers/platform/x86/toshiba_acpi.c
drivers/rapidio/rio-scan.c
drivers/regulator/Kconfig
drivers/regulator/Makefile
drivers/regulator/da903x.c
drivers/regulator/fixed.c
drivers/regulator/lp3971.c [new file with mode: 0644]
drivers/regulator/max1586.c [new file with mode: 0644]
drivers/regulator/pcf50633-regulator.c
drivers/regulator/userspace-consumer.c [new file with mode: 0644]
drivers/regulator/virtual.c
drivers/regulator/wm8350-regulator.c
drivers/regulator/wm8400-regulator.c
drivers/s390/net/claw.c
drivers/s390/net/ctcm_main.c
drivers/s390/net/netiucv.c
drivers/s390/net/qeth_core_main.c
drivers/s390/net/qeth_core_mpc.c
drivers/s390/net/qeth_core_mpc.h
drivers/s390/net/qeth_l2_main.c
drivers/s390/net/qeth_l3_main.c
drivers/scsi/fcoe/fcoe.c
drivers/scsi/fcoe/libfcoe.c
drivers/serial/serial_cs.c
drivers/staging/agnx/pci.c
drivers/staging/at76_usb/at76_usb.c
drivers/staging/et131x/et131x_netdev.c
drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c
drivers/staging/wlan-ng/p80211netdev.c
drivers/usb/gadget/f_phonet.c
drivers/usb/gadget/u_ether.c
drivers/video/xilinxfb.c
firmware/Makefile
firmware/WHENCE
firmware/bnx2x-e1-4.8.53.0.fw.ihex [new file with mode: 0644]
firmware/bnx2x-e1h-4.8.53.0.fw.ihex [new file with mode: 0644]
firmware/cis/3CCFEM556.cis.ihex [new file with mode: 0644]
firmware/cis/3CXEM556.cis.ihex [new file with mode: 0644]
firmware/cxgb3/t3fw-7.1.0.bin.ihex [deleted file]
firmware/cxgb3/t3fw-7.4.0.bin.ihex [new file with mode: 0644]
fs/nilfs2/bmap.c
fs/nilfs2/bmap.h
fs/nilfs2/btnode.c
fs/nilfs2/btnode.h
fs/nilfs2/btree.c
fs/nilfs2/btree.h
fs/nilfs2/cpfile.c
fs/nilfs2/cpfile.h
fs/nilfs2/dat.c
fs/nilfs2/dat.h
fs/nilfs2/direct.c
fs/nilfs2/direct.h
fs/nilfs2/gcinode.c
fs/nilfs2/inode.c
fs/nilfs2/ioctl.c
fs/nilfs2/mdt.c
fs/nilfs2/nilfs.h
fs/nilfs2/recovery.c
fs/nilfs2/segbuf.c
fs/nilfs2/seglist.h [deleted file]
fs/nilfs2/segment.c
fs/nilfs2/segment.h
fs/nilfs2/sufile.c
fs/nilfs2/sufile.h
fs/nilfs2/super.c
fs/nilfs2/the_nilfs.c
fs/ramfs/inode.c
include/acpi/acpixf.h
include/acpi/actypes.h
include/acpi/platform/acgcc.h
include/acpi/platform/aclinux.h
include/asm-generic/errno.h
include/linux/Kbuild
include/linux/can/Kbuild
include/linux/can/dev.h [new file with mode: 0644]
include/linux/can/netlink.h [new file with mode: 0644]
include/linux/can/platform/sja1000.h [new file with mode: 0644]
include/linux/clockchips.h
include/linux/etherdevice.h
include/linux/ethtool.h
include/linux/fs_enet_pd.h
include/linux/hrtimer.h
include/linux/ieee80211.h
include/linux/if.h
include/linux/if_arp.h
include/linux/if_ether.h
include/linux/if_packet.h
include/linux/if_tun.h
include/linux/if_tunnel.h
include/linux/if_vlan.h
include/linux/in.h
include/linux/ipv6.h
include/linux/isdn/capilli.h
include/linux/kernel.h
include/linux/list_nulls.h
include/linux/mISDNdsp.h
include/linux/mISDNhw.h
include/linux/mISDNif.h
include/linux/mdio.h [new file with mode: 0644]
include/linux/mii.h
include/linux/mmc/sdio_ids.h
include/linux/net_dropmon.h
include/linux/netdevice.h
include/linux/netfilter/Kbuild
include/linux/netfilter/nf_conntrack_common.h
include/linux/netfilter/nf_conntrack_tcp.h
include/linux/netfilter/nfnetlink.h
include/linux/netfilter/nfnetlink_conntrack.h
include/linux/netfilter/x_tables.h
include/linux/netfilter/xt_NFQUEUE.h
include/linux/netfilter/xt_osf.h [new file with mode: 0644]
include/linux/netfilter/xt_socket.h [new file with mode: 0644]
include/linux/nl80211.h
include/linux/nl802154.h [new file with mode: 0644]
include/linux/notifier.h
include/linux/of.h
include/linux/of_mdio.h [new file with mode: 0644]
include/linux/pci_ids.h
include/linux/phy.h
include/linux/regulator/lp3971.h [new file with mode: 0644]
include/linux/regulator/max1586.h [new file with mode: 0644]
include/linux/regulator/userspace-consumer.h [new file with mode: 0644]
include/linux/rfkill.h
include/linux/sched.h
include/linux/sctp.h
include/linux/skbuff.h
include/linux/smsc911x.h
include/linux/snmp.h
include/linux/socket.h
include/linux/spi/libertas_spi.h
include/linux/spi/wl12xx.h [new file with mode: 0644]
include/linux/tcp.h
include/linux/tick.h
include/linux/timer.h
include/linux/timex.h
include/linux/usb/usbnet.h
include/linux/wimax.h
include/linux/wimax/i2400m.h
include/net/bluetooth/bluetooth.h
include/net/bluetooth/hci_core.h
include/net/bluetooth/l2cap.h
include/net/cfg80211.h
include/net/dst.h
include/net/fib_rules.h
include/net/genetlink.h
include/net/ieee802154/af_ieee802154.h [new file with mode: 0644]
include/net/ieee802154/mac_def.h [new file with mode: 0644]
include/net/ieee802154/netdevice.h [new file with mode: 0644]
include/net/ieee802154/nl802154.h [new file with mode: 0644]
include/net/inet6_hashtables.h
include/net/inet_hashtables.h
include/net/inet_sock.h
include/net/ip.h
include/net/ip6_route.h
include/net/ip_fib.h
include/net/ipip.h
include/net/ipv6.h
include/net/iucv/af_iucv.h
include/net/mac80211.h
include/net/netfilter/ipv4/nf_conntrack_icmp.h [deleted file]
include/net/netfilter/ipv6/nf_conntrack_icmpv6.h
include/net/netfilter/nf_conntrack.h
include/net/netfilter/nf_conntrack_ecache.h
include/net/netfilter/nf_conntrack_extend.h
include/net/netfilter/nf_conntrack_helper.h
include/net/netfilter/nf_conntrack_l4proto.h
include/net/netlink.h
include/net/netns/conntrack.h
include/net/pkt_sched.h
include/net/regulatory.h [new file with mode: 0644]
include/net/route.h
include/net/sctp/structs.h
include/net/sctp/user.h
include/net/snmp.h
include/net/sock.h
include/net/tcp.h
include/net/wimax.h
include/net/wireless.h [deleted file]
include/net/xfrm.h
include/scsi/libfcoe.h
include/trace/events/napi.h [new file with mode: 0644]
kernel/hrtimer.c
kernel/module.c
kernel/printk.c
kernel/sched.c
kernel/sysctl.c
kernel/time/clockevents.c
kernel/time/clocksource.c
kernel/time/tick-broadcast.c
kernel/time/tick-oneshot.c
kernel/time/tick-sched.c
kernel/timer.c
kernel/trace/trace_sysprof.c
net/802/fddi.c
net/802/hippi.c
net/8021q/vlan.c
net/8021q/vlan_core.c
net/8021q/vlan_dev.c
net/8021q/vlanproc.c
net/Kconfig
net/Makefile
net/appletalk/ddp.c
net/appletalk/dev.c
net/atm/br2684.c
net/atm/clip.c
net/atm/lec.c
net/bluetooth/Kconfig
net/bluetooth/cmtp/capi.c
net/bluetooth/hci_core.c
net/bluetooth/l2cap.c
net/bluetooth/rfcomm/core.c
net/bridge/br.c
net/bridge/br_fdb.c
net/bridge/br_netfilter.c
net/bridge/br_private.h
net/bridge/br_sysfs_br.c
net/bridge/br_sysfs_if.c
net/bridge/netfilter/ebtables.c
net/can/af_can.c
net/core/datagram.c
net/core/dev.c
net/core/drop_monitor.c
net/core/fib_rules.c
net/core/gen_estimator.c
net/core/iovec.c
net/core/neighbour.c
net/core/net-sysfs.c
net/core/net-traces.c
net/core/net_namespace.c
net/core/netpoll.c
net/core/pktgen.c
net/core/skb_dma_map.c
net/core/skbuff.c
net/core/sock.c
net/core/stream.c
net/core/user_dma.c
net/dccp/ipv4.c
net/dccp/ipv6.c
net/dccp/output.c
net/decnet/af_decnet.c
net/decnet/dn_neigh.c
net/decnet/dn_nsp_in.c
net/decnet/dn_nsp_out.c
net/decnet/dn_route.c
net/decnet/dn_rules.c
net/dsa/slave.c
net/econet/af_econet.c
net/ethernet/eth.c
net/ieee802154/Kconfig [new file with mode: 0644]
net/ieee802154/Makefile [new file with mode: 0644]
net/ieee802154/af802154.h [new file with mode: 0644]
net/ieee802154/af_ieee802154.c [new file with mode: 0644]
net/ieee802154/dgram.c [new file with mode: 0644]
net/ieee802154/netlink.c [new file with mode: 0644]
net/ieee802154/nl_policy.c [new file with mode: 0644]
net/ieee802154/raw.c [new file with mode: 0644]
net/ipv4/Kconfig
net/ipv4/af_inet.c
net/ipv4/arp.c
net/ipv4/devinet.c
net/ipv4/fib_frontend.c
net/ipv4/fib_hash.c
net/ipv4/fib_lookup.h
net/ipv4/fib_rules.c
net/ipv4/fib_semantics.c
net/ipv4/fib_trie.c
net/ipv4/icmp.c
net/ipv4/igmp.c
net/ipv4/inet_diag.c
net/ipv4/inet_timewait_sock.c
net/ipv4/ip_forward.c
net/ipv4/ip_fragment.c
net/ipv4/ip_gre.c
net/ipv4/ip_input.c
net/ipv4/ip_options.c
net/ipv4/ip_output.c
net/ipv4/ip_sockglue.c
net/ipv4/ipconfig.c
net/ipv4/ipip.c
net/ipv4/ipmr.c
net/ipv4/netfilter.c
net/ipv4/netfilter/arp_tables.c
net/ipv4/netfilter/ip_queue.c
net/ipv4/netfilter/ip_tables.c
net/ipv4/netfilter/ipt_MASQUERADE.c
net/ipv4/netfilter/ipt_REJECT.c
net/ipv4/netfilter/nf_conntrack_proto_icmp.c
net/ipv4/netfilter/nf_nat_helper.c
net/ipv4/netfilter/nf_nat_proto_sctp.c
net/ipv4/netfilter/nf_nat_standalone.c
net/ipv4/proc.c
net/ipv4/raw.c
net/ipv4/route.c
net/ipv4/syncookies.c
net/ipv4/tcp.c
net/ipv4/tcp_input.c
net/ipv4/tcp_ipv4.c
net/ipv4/tcp_output.c
net/ipv4/udp.c
net/ipv4/xfrm4_input.c
net/ipv4/xfrm4_mode_tunnel.c
net/ipv4/xfrm4_output.c
net/ipv6/addrconf.c
net/ipv6/af_inet6.c
net/ipv6/exthdrs.c
net/ipv6/fib6_rules.c
net/ipv6/inet6_connection_sock.c
net/ipv6/ip6_input.c
net/ipv6/ip6_output.c
net/ipv6/ip6_tunnel.c
net/ipv6/ip6mr.c
net/ipv6/mcast.c
net/ipv6/ndisc.c
net/ipv6/netfilter.c
net/ipv6/netfilter/ip6_queue.c
net/ipv6/netfilter/ip6_tables.c
net/ipv6/netfilter/ip6t_REJECT.c
net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
net/ipv6/netfilter/nf_conntrack_reasm.c
net/ipv6/proc.c
net/ipv6/raw.c
net/ipv6/reassembly.c
net/ipv6/route.c
net/ipv6/sit.c
net/ipv6/syncookies.c
net/ipv6/tcp_ipv6.c
net/ipv6/udp.c
net/ipv6/xfrm6_mode_tunnel.c
net/ipv6/xfrm6_output.c
net/irda/irlap_frame.c
net/irda/irnetlink.c
net/iucv/af_iucv.c
net/iucv/iucv.c
net/llc/af_llc.c
net/llc/llc_conn.c
net/mac80211/Kconfig
net/mac80211/agg-rx.c
net/mac80211/agg-tx.c
net/mac80211/cfg.c
net/mac80211/debugfs.c
net/mac80211/driver-ops.h [new file with mode: 0644]
net/mac80211/event.c
net/mac80211/ht.c
net/mac80211/ibss.c
net/mac80211/ieee80211_i.h
net/mac80211/iface.c
net/mac80211/key.c
net/mac80211/key.h
net/mac80211/main.c
net/mac80211/mesh.c
net/mac80211/mesh.h
net/mac80211/mesh_hwmp.c
net/mac80211/mesh_plink.c
net/mac80211/mlme.c
net/mac80211/pm.c
net/mac80211/rc80211_minstrel.c
net/mac80211/rc80211_pid_algo.c
net/mac80211/rx.c
net/mac80211/scan.c
net/mac80211/spectmgmt.c
net/mac80211/sta_info.c
net/mac80211/sta_info.h
net/mac80211/tkip.c
net/mac80211/tx.c
net/mac80211/util.c
net/mac80211/wext.c
net/mac80211/wme.c
net/mac80211/wpa.c
net/netfilter/Kconfig
net/netfilter/Makefile
net/netfilter/ipvs/ip_vs_ctl.c
net/netfilter/ipvs/ip_vs_xmit.c
net/netfilter/nf_conntrack_core.c
net/netfilter/nf_conntrack_ecache.c
net/netfilter/nf_conntrack_ftp.c
net/netfilter/nf_conntrack_helper.c
net/netfilter/nf_conntrack_netbios_ns.c
net/netfilter/nf_conntrack_netlink.c
net/netfilter/nf_conntrack_proto_dccp.c
net/netfilter/nf_conntrack_proto_gre.c
net/netfilter/nf_conntrack_proto_sctp.c
net/netfilter/nf_conntrack_proto_tcp.c
net/netfilter/nf_log.c
net/netfilter/nf_queue.c
net/netfilter/nfnetlink.c
net/netfilter/nfnetlink_queue.c
net/netfilter/x_tables.c
net/netfilter/xt_NFQUEUE.c
net/netfilter/xt_TCPMSS.c
net/netfilter/xt_osf.c [new file with mode: 0644]
net/netfilter/xt_policy.c
net/netfilter/xt_realm.c
net/netfilter/xt_socket.c
net/netlabel/netlabel_cipso_v4.c
net/netlabel/netlabel_mgmt.c
net/netlabel/netlabel_unlabeled.c
net/netlink/genetlink.c
net/packet/af_packet.c
net/phonet/pep-gprs.c
net/phonet/pep.c
net/rds/af_rds.c
net/rds/connection.c
net/rds/ib.c
net/rds/ib.h
net/rds/ib_recv.c
net/rds/ib_ring.c
net/rds/ib_send.c
net/rds/info.c
net/rds/iw.c
net/rds/iw.h
net/rds/iw_recv.c
net/rds/iw_ring.c
net/rds/iw_send.c
net/rds/rdma.c
net/rds/rdma_transport.c
net/rds/rds.h
net/rds/send.c
net/rfkill/Kconfig
net/rfkill/Makefile
net/rfkill/core.c [new file with mode: 0644]
net/rfkill/input.c [new file with mode: 0644]
net/rfkill/rfkill-input.c [deleted file]
net/rfkill/rfkill-input.h [deleted file]
net/rfkill/rfkill.c [deleted file]
net/rfkill/rfkill.h [new file with mode: 0644]
net/rose/rose_dev.c
net/sched/cls_cgroup.c
net/sched/cls_flow.c
net/sched/cls_route.c
net/sched/em_meta.c
net/sched/sch_api.c
net/sched/sch_cbq.c
net/sched/sch_generic.c
net/sched/sch_hfsc.c
net/sched/sch_sfq.c
net/sched/sch_teql.c
net/sctp/associola.c
net/sctp/input.c
net/sctp/output.c
net/sctp/protocol.c
net/sctp/sm_make_chunk.c
net/sctp/sm_sideeffect.c
net/sctp/sm_statefuns.c
net/sctp/sm_statetable.c
net/sctp/socket.c
net/sctp/sysctl.c
net/sctp/ulpevent.c
net/sunrpc/auth_gss/auth_gss.c
net/sunrpc/xprtsock.c
net/tipc/eth_media.c
net/tipc/netlink.c
net/wimax/Kconfig
net/wimax/Makefile
net/wimax/debug-levels.h
net/wimax/debugfs.c
net/wimax/op-msg.c
net/wimax/op-rfkill.c
net/wimax/op-state-get.c [new file with mode: 0644]
net/wimax/stack.c
net/wireless/Kconfig
net/wireless/Makefile
net/wireless/core.c
net/wireless/core.h
net/wireless/debugfs.c [new file with mode: 0644]
net/wireless/debugfs.h [new file with mode: 0644]
net/wireless/ibss.c [new file with mode: 0644]
net/wireless/mlme.c
net/wireless/nl80211.c
net/wireless/nl80211.h
net/wireless/reg.c
net/wireless/scan.c
net/wireless/util.c
net/wireless/wext-compat.c
net/wireless/wext.c
net/xfrm/xfrm_algo.c
net/xfrm/xfrm_input.c
net/xfrm/xfrm_output.c
net/xfrm/xfrm_policy.c
security/selinux/hooks.c
security/selinux/xfrm.c

diff --git a/CREDITS b/CREDITS
index 2520ba620ff12a482e385b0c34403fe044ba0027..2b88fb37ad503e12ed271aa26b1068b7c5d93aea 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -1253,6 +1253,10 @@ S: 8124 Constitution Apt. 7
 S: Sterling Heights, Michigan 48313
 S: USA
 
+N: Wolfgang Grandegger
+E: wg@grandegger.com
+D: Controller Area Network (device drivers)
+
 N: William Greathouse
 E: wgreathouse@smva.com
 E: wgreathouse@myfavoritei.com
index fbeaffc1dcc39c7b25e3f36cc7923828be9cbec9..e36986663570d6be1577365645c25b11e866c138 100644 (file)
@@ -145,7 +145,6 @@ usage should require reading the full document.
         interface in STA mode at first!
       </para>
 !Finclude/net/mac80211.h ieee80211_if_init_conf
-!Finclude/net/mac80211.h ieee80211_if_conf
     </chapter>
 
     <chapter id="rx-tx">
index ec9ef5d0d7b3b3af5d12c595edd7ddb048be6f2b..7129846a27851a9e61d817e396802edc7e2eac3e 100644 (file)
@@ -438,6 +438,13 @@ Why:       Superseded by tdfxfb. I2C/DDC support used to live in a separate
 Who:   Jean Delvare <khali@linux-fr.org>
        Krzysztof Helt <krzysztof.h1@wp.pl>
 
+---------------------------
+
+What:  CONFIG_RFKILL_INPUT
+When:  2.6.33
+Why:   Should be implemented in userspace, policy daemon.
+Who:   Johannes Berg <johannes@sipsolutions.net>
+
 ----------------------------
 
 What:  CONFIG_X86_OLD_MCE
index 55c4300abfcbf88b852b4360690209d7004e8091..01539f4106763f8b9ad283d7e315a4b9c3639a73 100644 (file)
@@ -39,9 +39,8 @@ Features which NILFS2 does not support yet:
        - extended attributes
        - POSIX ACLs
        - quotas
-       - writable snapshots
-       - remote backup (CDP)
-       - data integrity
+       - fsck
+       - resize
        - defragmentation
 
 Mount options
index 5a2d69989a8c08099dadbcf99d3730d1b4a39303..f6010a536590bb0384ab87a549c1af4bdacca6f9 100644 (file)
@@ -22,16 +22,11 @@ README.gigaset
        - info on the drivers for Siemens Gigaset ISDN adapters.
 README.icn
        - info on the ICN-ISDN-card and its driver.
+>>>>>>> 93af7aca44f0e82e67bda10a0fb73d383edcc8bd:Documentation/isdn/00-INDEX
 README.HiSax
        - info on the HiSax driver which replaces the old teles.
-README.hfc-pci
-       - info on hfc-pci based cards.
-README.pcbit
-       - info on the PCBIT-D ISDN adapter and driver.
-README.syncppp
-       - info on running Sync PPP over ISDN.
-syncPPP.FAQ
-       - frequently asked questions about running PPP over ISDN.
+README.audio
+       - info for running audio over ISDN.
 README.avmb1
        - info on driver for AVM-B1 ISDN card.
 README.act2000
@@ -42,10 +37,28 @@ README.concap
        - info on "CONCAP" encapsulation protocol interface used for X.25.
 README.diversion
        - info on module for isdn diversion services.
+README.fax
+       - info for using Fax over ISDN.
+README.gigaset
+       - info on the drivers for Siemens Gigaset ISDN adapters
+README.hfc-pci
+       - info on hfc-pci based cards.
+README.hysdn
+        - info on driver for Hypercope active HYSDN cards
+README.icn
+       - info on the ICN-ISDN-card and its driver.
+README.mISDN
+       - info on the Modular ISDN subsystem (mISDN)
+README.pcbit
+       - info on the PCBIT-D ISDN adapter and driver.
 README.sc
        - info on driver for Spellcaster cards.
+README.syncppp
+       - info on running Sync PPP over ISDN.
 README.x25
        - info for running X.25 over ISDN.
+syncPPP.FAQ
+       - frequently asked questions about running PPP over ISDN.
 README.hysdn
        - info on driver for Hypercope active HYSDN cards
 README.mISDN
index 786d619b36e5164f1ded06f149360772c7a8e34b..686e107923ec16f36a4f6a32fd49b791e36b30b9 100644 (file)
@@ -45,7 +45,7 @@ From then on, Kernel CAPI may call the registered callback functions for the
 device.
 
 If the device becomes unusable for any reason (shutdown, disconnect ...), the
-driver has to call capi_ctr_reseted(). This will prevent further calls to the
+driver has to call capi_ctr_down(). This will prevent further calls to the
 callback functions by Kernel CAPI.
 
 
@@ -114,20 +114,36 @@ char *driver_name
 int (*load_firmware)(struct capi_ctr *ctrlr, capiloaddata *ldata)
        (optional) pointer to a callback function for sending firmware and
        configuration data to the device
+       Return value: 0 on success, error code on error
+       Called in process context.
 
 void (*reset_ctr)(struct capi_ctr *ctrlr)
-       pointer to a callback function for performing a reset on the device,
-       releasing all registered applications
+       (optional) pointer to a callback function for performing a reset on
+       the device, releasing all registered applications
+       Called in process context.
 
 void (*register_appl)(struct capi_ctr *ctrlr, u16 applid,
                        capi_register_params *rparam)
 void (*release_appl)(struct capi_ctr *ctrlr, u16 applid)
        pointers to callback functions for registration and deregistration of
        applications with the device
+       Calls to these functions are serialized by Kernel CAPI so that only
+       one call to any of them is active at any time.
 
 u16  (*send_message)(struct capi_ctr *ctrlr, struct sk_buff *skb)
        pointer to a callback function for sending a CAPI message to the
        device
+       Return value: CAPI error code
+       If the method returns 0 (CAPI_NOERROR) the driver has taken ownership
+       of the skb and the caller may no longer access it. If it returns a
+       non-zero (error) value then ownership of the skb returns to the caller
+       who may reuse or free it.
+       The return value should only be used to signal problems with respect
+       to accepting or queueing the message. Errors occurring during the
+       actual processing of the message should be signaled with an
+       appropriate reply message.
+       Calls to this function are not serialized by Kernel CAPI, ie. it must
+       be prepared to be re-entered.
 
 char *(*procinfo)(struct capi_ctr *ctrlr)
        pointer to a callback function returning the entry for the device in
@@ -138,6 +154,8 @@ read_proc_t *ctr_read_proc
        system entry, /proc/capi/controllers/<n>; will be called with a
        pointer to the device's capi_ctr structure as the last (data) argument
 
+Note: Callback functions are never called in interrupt context.
+
 - to be filled in before calling capi_ctr_ready():
 
 u8 manu[CAPI_MANUFACTURER_LEN]
@@ -153,6 +171,45 @@ u8 serial[CAPI_SERIAL_LEN]
        value to return for CAPI_GET_SERIAL
 
 
+4.3 The _cmsg Structure
+
+(declared in <linux/isdn/capiutil.h>)
+
+The _cmsg structure stores the contents of a CAPI 2.0 message in an easily
+accessible form. It contains members for all possible CAPI 2.0 parameters, of
+which only those appearing in the message type currently being processed are
+actually used. Unused members should be set to zero.
+
+Members are named after the CAPI 2.0 standard names of the parameters they
+represent. See <linux/isdn/capiutil.h> for the exact spelling. Member data
+types are:
+
+u8          for CAPI parameters of type 'byte'
+
+u16         for CAPI parameters of type 'word'
+
+u32         for CAPI parameters of type 'dword'
+
+_cstruct    for CAPI parameters of type 'struct' not containing any
+           variably-sized (struct) subparameters (eg. 'Called Party Number')
+           The member is a pointer to a buffer containing the parameter in
+           CAPI encoding (length + content). It may also be NULL, which will
+           be taken to represent an empty (zero length) parameter.
+
+_cmstruct   for CAPI parameters of type 'struct' containing 'struct'
+           subparameters ('Additional Info' and 'B Protocol')
+           The representation is a single byte containing one of the values:
+           CAPI_DEFAULT: the parameter is empty
+           CAPI_COMPOSE: the values of the subparameters are stored
+           individually in the corresponding _cmsg structure members
+
+Functions capi_cmsg2message() and capi_message2cmsg() are provided to convert
+messages between their transport encoding described in the CAPI 2.0 standard
+and their _cmsg structure representation. Note that capi_cmsg2message() does
+not know or check the size of its destination buffer. The caller must make
+sure it is big enough to accomodate the resulting CAPI message.
+
+
 5. Lower Layer Interface Functions
 
 (declared in <linux/isdn/capilli.h>)
@@ -166,7 +223,7 @@ int detach_capi_ctr(struct capi_ctr *ctrlr)
        register/unregister a device (controller) with Kernel CAPI
 
 void capi_ctr_ready(struct capi_ctr *ctrlr)
-void capi_ctr_reseted(struct capi_ctr *ctrlr)
+void capi_ctr_down(struct capi_ctr *ctrlr)
        signal controller ready/not ready
 
 void capi_ctr_suspend_output(struct capi_ctr *ctrlr)
@@ -211,3 +268,32 @@ CAPIMSG_CONTROL(m) CAPIMSG_SETCONTROL(m, contr)    Controller/PLCI/NCCI
                                                        (u32)
 CAPIMSG_DATALEN(m)     CAPIMSG_SETDATALEN(m, len)      Data Length (u16)
 
+
+Library functions for working with _cmsg structures
+(from <linux/isdn/capiutil.h>):
+
+unsigned capi_cmsg2message(_cmsg *cmsg, u8 *msg)
+       Assembles a CAPI 2.0 message from the parameters in *cmsg, storing the
+       result in *msg.
+
+unsigned capi_message2cmsg(_cmsg *cmsg, u8 *msg)
+       Disassembles the CAPI 2.0 message in *msg, storing the parameters in
+       *cmsg.
+
+unsigned capi_cmsg_header(_cmsg *cmsg, u16 ApplId, u8 Command, u8 Subcommand,
+                         u16 Messagenumber, u32 Controller)
+       Fills the header part and address field of the _cmsg structure *cmsg
+       with the given values, zeroing the remainder of the structure so only
+       parameters with non-default values need to be changed before sending
+       the message.
+
+void capi_cmsg_answer(_cmsg *cmsg)
+       Sets the low bit of the Subcommand field in *cmsg, thereby converting
+       _REQ to _CONF and _IND to _RESP.
+
+char *capi_cmd2str(u8 Command, u8 Subcommand)
+       Returns the CAPI 2.0 message name corresponding to the given command
+       and subcommand values, as a static ASCII string. The return value may
+       be NULL if the command/subcommand is not one of those defined in the
+       CAPI 2.0 standard.
+
index 02c0e9341dd846975b1c18187deb51c55d379b10..f9963103ae3dd605094d700f49d2d195182f8712 100644 (file)
@@ -149,10 +149,8 @@ GigaSet 307x Device Driver
      configuration files and chat scripts in the gigaset-VERSION/ppp directory
      in the driver packages from http://sourceforge.net/projects/gigaset307x/.
      Please note that the USB drivers are not able to change the state of the
-     control lines (the M105 driver can be configured to use some undocumented
-     control requests, if you really need the control lines, though). This means
-     you must use "Stupid Mode" if you are using wvdial or you should use the
-     nocrtscts option of pppd.
+     control lines. This means you must use "Stupid Mode" if you are using
+     wvdial or you should use the nocrtscts option of pppd.
      You must also assure that the ppp_async module is loaded with the parameter
      flag_time=0. You can do this e.g. by adding a line like
 
@@ -190,20 +188,19 @@ GigaSet 307x Device Driver
      You can also use /sys/class/tty/ttyGxy/cidmode for changing the CID mode
      setting (ttyGxy is ttyGU0 or ttyGB0).
 
-2.6. M105 Undocumented USB Requests
-     ------------------------------
-
-     The Gigaset M105 USB data box understands a couple of useful, but
-     undocumented USB commands. These requests are not used in normal
-     operation (for wireless access to the base), but are needed for access
-     to the M105's own configuration mode (registration to the base, baudrate
-     and line format settings, device status queries) via the gigacontr
-     utility. Their use is controlled by the kernel configuration option
-     "Support for undocumented USB requests" (CONFIG_GIGASET_UNDOCREQ). If you
-     encounter error code -ENOTTY when trying to use some features of the
-     M105, try setting that option to "y" via 'make {x,menu}config' and
-     recompiling the driver.
-
+2.6. Unregistered Wireless Devices (M101/M105)
+     -----------------------------------------
+     The main purpose of the ser_gigaset and usb_gigaset drivers is to allow
+     the M101 and M105 wireless devices to be used as ISDN devices for ISDN
+     connections through a Gigaset base. Therefore they assume that the device
+     is registered to a DECT base.
+
+     If the M101/M105 device is not registered to a base, initialization of
+     the device fails, and a corresponding error message is logged by the
+     driver. In that situation, a restricted set of functions is available
+     which includes, in particular, those necessary for registering the device
+     to a base or for switching it between Fixed Part and Portable Part
+     modes.
 
 3.   Troubleshooting
      ---------------
@@ -234,11 +231,12 @@ GigaSet 307x Device Driver
         Select Unimodem mode for all DECT data adapters. (see section 2.4.)
 
      Problem:
-        You want to configure your USB DECT data adapter (M105) but gigacontr
-        reports an error: "/dev/ttyGU0: Inappropriate ioctl for device".
+       Messages like this:
+           usb_gigaset 3-2:1.0: Could not initialize the device.
+       appear in your syslog.
      Solution:
-        Recompile the usb_gigaset driver with the kernel configuration option
-        CONFIG_GIGASET_UNDOCREQ set to 'y'. (see section 2.6.)
+       Check whether your M10x wireless device is correctly registered to the
+       Gigaset base. (see section 2.6.)
 
 3.2. Telling the driver to provide more information
      ----------------------------------------------
index 5f66ba295c5d376599e6942b4f917ad38d9dab9e..ad38006307725ff2a563d9e86e78230df0879e22 100644 (file)
@@ -491,6 +491,13 @@ and is between 256 and 4096 characters. It is defined in the file
                        Also note the kernel might malfunction if you disable
                        some critical bits.
 
+       cmo_free_hint=  [PPC] Format: { yes | no }
+                       Specify whether pages are marked as being inactive
+                       when they are freed.  This is used in CMO environments
+                       to determine OS memory pressure for page stealing by
+                       a hypervisor.
+                       Default: yes
+
        code_bytes      [X86] How many bytes of object code to print
                        in an oops report.
                        Range: 0 - 8192
index 463d9e029ef3a4a702a85410119827333e0ee7bc..cd79735013f94728c15359f292f5fad4b1d0f838 100644 (file)
@@ -36,10 +36,15 @@ This file contains
     6.2 local loopback of sent frames
     6.3 CAN controller hardware filters
     6.4 The virtual CAN driver (vcan)
-    6.5 currently supported CAN hardware
-    6.6 todo
+    6.5 The CAN network device driver interface
+      6.5.1 Netlink interface to set/get devices properties
+      6.5.2 Setting the CAN bit-timing
+      6.5.3 Starting and stopping the CAN network device
+    6.6 supported CAN hardware
 
-  7 Credits
+  7 Socket CAN resources
+
+  8 Credits
 
 ============================================================================
 
@@ -234,6 +239,8 @@ solution for a couple of reasons:
   the user application using the common CAN filter mechanisms. Inside
   this filter definition the (interested) type of errors may be
   selected. The reception of error frames is disabled by default.
+  The format of the CAN error frame is briefly decribed in the Linux
+  header file "include/linux/can/error.h".
 
 4. How to use Socket CAN
 ------------------------
@@ -605,61 +612,213 @@ solution for a couple of reasons:
   removal of vcan network devices can be managed with the ip(8) tool:
 
   - Create a virtual CAN network interface:
-       ip link add type vcan
+       ip link add type vcan
 
   - Create a virtual CAN network interface with a specific name 'vcan42':
-       ip link add dev vcan42 type vcan
+       ip link add dev vcan42 type vcan
 
   - Remove a (virtual CAN) network interface 'vcan42':
-       ip link del vcan42
-
-  The tool 'vcan' from the SocketCAN SVN repository on BerliOS is obsolete.
-
-  Virtual CAN network device creation in older Kernels:
-  In Linux Kernel versions < 2.6.24 the vcan driver creates 4 vcan
-  netdevices at module load time by default. This value can be changed
-  with the module parameter 'numdev'. E.g. 'modprobe vcan numdev=8'
-
-  6.5 currently supported CAN hardware
+       $ ip link del vcan42
+
+  6.5 The CAN network device driver interface
+
+  The CAN network device driver interface provides a generic interface
+  to setup, configure and monitor CAN network devices. The user can then
+  configure the CAN device, like setting the bit-timing parameters, via
+  the netlink interface using the program "ip" from the "IPROUTE2"
+  utility suite. The following chapter describes briefly how to use it.
+  Furthermore, the interface uses a common data structure and exports a
+  set of common functions, which all real CAN network device drivers
+  should use. Please have a look to the SJA1000 or MSCAN driver to
+  understand how to use them. The name of the module is can-dev.ko.
+
+  6.5.1 Netlink interface to set/get devices properties
+
+  The CAN device must be configured via netlink interface. The supported
+  netlink message types are defined and briefly described in
+  "include/linux/can/netlink.h". CAN link support for the program "ip"
+  of the IPROUTE2 utility suite is avaiable and it can be used as shown
+  below:
+
+  - Setting CAN device properties:
+
+    $ ip link set can0 type can help
+    Usage: ip link set DEVICE type can
+       [ bitrate BITRATE [ sample-point SAMPLE-POINT] ] |
+       [ tq TQ prop-seg PROP_SEG phase-seg1 PHASE-SEG1
+         phase-seg2 PHASE-SEG2 [ sjw SJW ] ]
+
+       [ loopback { on | off } ]
+       [ listen-only { on | off } ]
+       [ triple-sampling { on | off } ]
+
+       [ restart-ms TIME-MS ]
+       [ restart ]
+
+       Where: BITRATE       := { 1..1000000 }
+              SAMPLE-POINT  := { 0.000..0.999 }
+              TQ            := { NUMBER }
+              PROP-SEG      := { 1..8 }
+              PHASE-SEG1    := { 1..8 }
+              PHASE-SEG2    := { 1..8 }
+              SJW           := { 1..4 }
+              RESTART-MS    := { 0 | NUMBER }
+
+  - Display CAN device details and statistics:
+
+    $ ip -details -statistics link show can0
+    2: can0: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UP qlen 10
+      link/can
+      can <TRIPLE-SAMPLING> state ERROR-ACTIVE restart-ms 100
+      bitrate 125000 sample_point 0.875
+      tq 125 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1
+      sja1000: tseg1 1..16 tseg2 1..8 sjw 1..4 brp 1..64 brp-inc 1
+      clock 8000000
+      re-started bus-errors arbit-lost error-warn error-pass bus-off
+      41         17457      0          41         42         41
+      RX: bytes  packets  errors  dropped overrun mcast
+      140859     17608    17457   0       0       0
+      TX: bytes  packets  errors  dropped carrier collsns
+      861        112      0       41      0       0
+
+  More info to the above output:
+
+    "<TRIPLE-SAMPLING>"
+       Shows the list of selected CAN controller modes: LOOPBACK,
+       LISTEN-ONLY, or TRIPLE-SAMPLING.
+
+    "state ERROR-ACTIVE"
+       The current state of the CAN controller: "ERROR-ACTIVE",
+       "ERROR-WARNING", "ERROR-PASSIVE", "BUS-OFF" or "STOPPED"
+
+    "restart-ms 100"
+       Automatic restart delay time. If set to a non-zero value, a
+       restart of the CAN controller will be triggered automatically
+       in case of a bus-off condition after the specified delay time
+       in milliseconds. By default it's off.
+
+    "bitrate 125000 sample_point 0.875"
+       Shows the real bit-rate in bits/sec and the sample-point in the
+       range 0.000..0.999. If the calculation of bit-timing parameters
+       is enabled in the kernel (CONFIG_CAN_CALC_BITTIMING=y), the
+       bit-timing can be defined by setting the "bitrate" argument.
+       Optionally the "sample-point" can be specified. By default it's
+       0.000 assuming CIA-recommended sample-points.
+
+    "tq 125 prop-seg 6 phase-seg1 7 phase-seg2 2 sjw 1"
+       Shows the time quanta in ns, propagation segment, phase buffer
+       segment 1 and 2 and the synchronisation jump width in units of
+       tq. They allow to define the CAN bit-timing in a hardware
+       independent format as proposed by the Bosch CAN 2.0 spec (see
+       chapter 8 of http://www.semiconductors.bosch.de/pdf/can2spec.pdf).
+
+    "sja1000: tseg1 1..16 tseg2 1..8 sjw 1..4 brp 1..64 brp-inc 1
+     clock 8000000"
+       Shows the bit-timing constants of the CAN controller, here the
+       "sja1000". The minimum and maximum values of the time segment 1
+       and 2, the synchronisation jump width in units of tq, the
+       bitrate pre-scaler and the CAN system clock frequency in Hz.
+       These constants could be used for user-defined (non-standard)
+       bit-timing calculation algorithms in user-space.
+
+    "re-started bus-errors arbit-lost error-warn error-pass bus-off"
+       Shows the number of restarts, bus and arbitration lost errors,
+       and the state changes to the error-warning, error-passive and
+       bus-off state. RX overrun errors are listed in the "overrun"
+       field of the standard network statistics.
+
+  6.5.2 Setting the CAN bit-timing
+
+  The CAN bit-timing parameters can always be defined in a hardware
+  independent format as proposed in the Bosch CAN 2.0 specification
+  specifying the arguments "tq", "prop_seg", "phase_seg1", "phase_seg2"
+  and "sjw":
+
+    $ ip link set canX type can tq 125 prop-seg 6 \
+                               phase-seg1 7 phase-seg2 2 sjw 1
+
+  If the kernel option CONFIG_CAN_CALC_BITTIMING is enabled, CIA
+  recommended CAN bit-timing parameters will be calculated if the bit-
+  rate is specified with the argument "bitrate":
+
+    $ ip link set canX type can bitrate 125000
+
+  Note that this works fine for the most common CAN controllers with
+  standard bit-rates but may *fail* for exotic bit-rates or CAN system
+  clock frequencies. Disabling CONFIG_CAN_CALC_BITTIMING saves some
+  space and allows user-space tools to solely determine and set the
+  bit-timing parameters. The CAN controller specific bit-timing
+  constants can be used for that purpose. They are listed by the
+  following command:
+
+    $ ip -details link show can0
+    ...
+      sja1000: clock 8000000 tseg1 1..16 tseg2 1..8 sjw 1..4 brp 1..64 brp-inc 1
+
+  6.5.3 Starting and stopping the CAN network device
+
+  A CAN network device is started or stopped as usual with the command
+  "ifconfig canX up/down" or "ip link set canX up/down". Be aware that
+  you *must* define proper bit-timing parameters for real CAN devices
+  before you can start it to avoid error-prone default settings:
+
+    $ ip link set canX up type can bitrate 125000
+
+  A device may enter the "bus-off" state if too much errors occurred on
+  the CAN bus. Then no more messages are received or sent. An automatic
+  bus-off recovery can be enabled by setting the "restart-ms" to a
+  non-zero value, e.g.:
+
+    $ ip link set canX type can restart-ms 100
+
+  Alternatively, the application may realize the "bus-off" condition
+  by monitoring CAN error frames and do a restart when appropriate with
+  the command:
+
+    $ ip link set canX type can restart
+
+  Note that a restart will also create a CAN error frame (see also
+  chapter 3.4).
 
-  On the project website http://developer.berlios.de/projects/socketcan
-  there are different drivers available:
+  6.6 Supported CAN hardware
 
-    vcan:    Virtual CAN interface driver (if no real hardware is available)
-    sja1000: Philips SJA1000 CAN controller (recommended)
-    i82527:  Intel i82527 CAN controller
-    mscan:   Motorola/Freescale CAN controller (e.g. inside SOC MPC5200)
-    ccan:    CCAN controller core (e.g. inside SOC h7202)
-    slcan:   For a bunch of CAN adaptors that are attached via a
-             serial line ASCII protocol (for serial / USB adaptors)
+  Please check the "Kconfig" file in "drivers/net/can" to get an actual
+  list of the support CAN hardware. On the Socket CAN project website
+  (see chapter 7) there might be further drivers available, also for
+  older kernel versions.
 
-  Additionally the different CAN adaptors (ISA/PCI/PCMCIA/USB/Parport)
-  from PEAK Systemtechnik support the CAN netdevice driver model
-  since Linux driver v6.0: http://www.peak-system.com/linux/index.htm
+7. Socket CAN resources
+-----------------------
 
-  Please check the Mailing Lists on the berlios OSS project website.
+  You can find further resources for Socket CAN like user space tools,
+  support for old kernel versions, more drivers, mailing lists, etc.
+  at the BerliOS OSS project website for Socket CAN:
 
-  6.6 todo
+    http://developer.berlios.de/projects/socketcan
 
-  The configuration interface for CAN network drivers is still an open
-  issue that has not been finalized in the socketcan project. Also the
-  idea of having a library module (candev.ko) that holds functions
-  that are needed by all CAN netdevices is not ready to ship.
-  Your contribution is welcome.
+  If you have questions, bug fixes, etc., don't hesitate to post them to
+  the Socketcan-Users mailing list. But please search the archives first.
 
-7. Credits
+8. Credits
 ----------
 
-  Oliver Hartkopp (PF_CAN core, filters, drivers, bcm)
+  Oliver Hartkopp (PF_CAN core, filters, drivers, bcm, SJA1000 driver)
   Urs Thuermann (PF_CAN core, kernel integration, socket interfaces, raw, vcan)
   Jan Kizka (RT-SocketCAN core, Socket-API reconciliation)
-  Wolfgang Grandegger (RT-SocketCAN core & drivers, Raw Socket-API reviews)
+  Wolfgang Grandegger (RT-SocketCAN core & drivers, Raw Socket-API reviews,
+                       CAN device driver interface, MSCAN driver)
   Robert Schwebel (design reviews, PTXdist integration)
   Marc Kleine-Budde (design reviews, Kernel 2.6 cleanups, drivers)
   Benedikt Spranger (reviews)
   Thomas Gleixner (LKML reviews, coding style, posting hints)
-  Andrey Volkov (kernel subtree structure, ioctls, mscan driver)
+  Andrey Volkov (kernel subtree structure, ioctls, MSCAN driver)
   Matthias Brukner (first SJA1000 CAN netdevice implementation Q2/2003)
   Klaus Hitschler (PEAK driver integration)
   Uwe Koppe (CAN netdevices with PF_PACKET approach)
   Michael Schulze (driver layer loopback requirement, RT CAN drivers review)
+  Pavel Pisa (Bit-timing calculation)
+  Sascha Hauer (SJA1000 platform driver)
+  Sebastian Haas (SJA1000 EMS PCI driver)
+  Markus Plessing (SJA1000 EMS PCI driver)
+  Per Dalen (SJA1000 Kvaser PCI driver)
+  Sam Ravnborg (reviews, coding style, kbuild help)
diff --git a/Documentation/networking/ieee802154.txt b/Documentation/networking/ieee802154.txt
new file mode 100644 (file)
index 0000000..a0280ad
--- /dev/null
@@ -0,0 +1,76 @@
+
+               Linux IEEE 802.15.4 implementation
+
+
+Introduction
+============
+
+The Linux-ZigBee project goal is to provide complete implementation
+of IEEE 802.15.4 / ZigBee / 6LoWPAN protocols. IEEE 802.15.4 is a stack
+of protocols for organizing Low-Rate Wireless Personal Area Networks.
+
+Currently only IEEE 802.15.4 layer is implemented. We have choosen
+to use plain Berkeley socket API, the generic Linux networking stack
+to transfer IEEE 802.15.4 messages and a special protocol over genetlink
+for configuration/management
+
+
+Socket API
+==========
+
+int sd = socket(PF_IEEE802154, SOCK_DGRAM, 0);
+.....
+
+The address family, socket addresses etc. are defined in the
+include/net/ieee802154/af_ieee802154.h header or in the special header
+in our userspace package (see either linux-zigbee sourceforge download page
+or git tree at git://linux-zigbee.git.sourceforge.net/gitroot/linux-zigbee).
+
+One can use SOCK_RAW for passing raw data towards device xmit function. YMMV.
+
+
+MLME - MAC Level Management
+============================
+
+Most of IEEE 802.15.4 MLME interfaces are directly mapped on netlink commands.
+See the include/net/ieee802154/nl802154.h header. Our userspace tools package
+(see above) provides CLI configuration utility for radio interfaces and simple
+coordinator for IEEE 802.15.4 networks as an example users of MLME protocol.
+
+
+Kernel side
+=============
+
+Like with WiFi, there are several types of devices implementing IEEE 802.15.4.
+1) 'HardMAC'. The MAC layer is implemented in the device itself, the device
+   exports MLME and data API.
+2) 'SoftMAC' or just radio. These types of devices are just radio transceivers
+   possibly with some kinds of acceleration like automatic CRC computation and
+   comparation, automagic ACK handling, address matching, etc.
+
+Those types of devices require different approach to be hooked into Linux kernel.
+
+
+HardMAC
+=======
+
+See the header include/net/ieee802154/netdevice.h. You have to implement Linux
+net_device, with .type = ARPHRD_IEEE802154. Data is exchanged with socket family
+code via plain sk_buffs. The control block of sk_buffs will contain additional
+info as described in the struct ieee802154_mac_cb.
+
+To hook the MLME interface you have to populate the ml_priv field of your
+net_device with a pointer to struct ieee802154_mlme_ops instance. All fields are
+required.
+
+We provide an example of simple HardMAC driver at drivers/ieee802154/fakehard.c
+
+
+SoftMAC
+=======
+
+We are going to provide intermediate layer impelementing IEEE 802.15.4 MAC
+in software. This is currently WIP.
+
+See header include/net/ieee802154/mac802154.h and several drivers in
+drivers/ieee802154/
index b121c5db707fcf8708533acd7b73a51cbd286296..8be76235fe6724c43e0c2b39778f3f741e53b619 100644 (file)
@@ -168,7 +168,16 @@ tcp_dsack - BOOLEAN
        Allows TCP to send "duplicate" SACKs.
 
 tcp_ecn - BOOLEAN
-       Enable Explicit Congestion Notification in TCP.
+       Enable Explicit Congestion Notification (ECN) in TCP. ECN is only
+       used when both ends of the TCP flow support it. It is useful to
+       avoid losses due to congestion (when the bottleneck router supports
+       ECN).
+       Possible values are:
+               0 disable ECN
+               1 ECN enabled
+               2 Only server-side ECN enabled. If the other end does
+                 not support ECN, behavior is like with ECN disabled.
+       Default: 2
 
 tcp_fack - BOOLEAN
        Enable FACK congestion avoidance and fast retransmission.
@@ -1048,6 +1057,13 @@ disable_ipv6 - BOOLEAN
        address.
        Default: FALSE (enable IPv6 operation)
 
+       When this value is changed from 1 to 0 (IPv6 is being enabled),
+       it will dynamically create a link-local address on the given
+       interface and start Duplicate Address Detection, if necessary.
+
+       When this value is changed from 0 to 1 (IPv6 is being disabled),
+       it will dynamically delete all address on the given interface.
+
 accept_dad - INTEGER
        Whether to accept DAD (Duplicate Address Detection).
        0: Disable DAD
index 268e5c103dd8e764c03e2dfba3356c3b4a2c7610..9fd7e21296c8f500938e7bc272f3ef0528fc3917 100644 (file)
@@ -33,3 +33,40 @@ disable
 
                A reboot is required to enable IPv6.
 
+autoconf
+
+       Specifies whether to enable IPv6 address autoconfiguration
+       on all interfaces.  This might be used when one does not wish
+       for addresses to be automatically generated from prefixes
+       received in Router Advertisements.
+
+       The possible values and their effects are:
+
+       0
+               IPv6 address autoconfiguration is disabled on all interfaces.
+
+               Only the IPv6 loopback address (::1) and link-local addresses
+               will be added to interfaces.
+
+       1
+               IPv6 address autoconfiguration is enabled on all interfaces.
+
+               This is the default value.
+
+disable_ipv6
+
+       Specifies whether to disable IPv6 on all interfaces.
+       This might be used when no IPv6 addresses are desired.
+
+       The possible values and their effects are:
+
+       0
+               IPv6 is enabled on all interfaces.
+
+               This is the default value.
+
+       1
+               IPv6 is disabled on all interfaces.
+
+               No IPv6 addresses will be added to interfaces.
+
index 84906ef3ed6e969404a9fac550f9973254f0039d..b30e81ad5307e851c50d58386bb17eb68d2072c9 100644 (file)
@@ -12,38 +12,22 @@ following format:
 The radiotap format is discussed in
 ./Documentation/networking/radiotap-headers.txt.
 
-Despite 13 radiotap argument types are currently defined, most only make sense
+Despite many radiotap parameters being currently defined, most only make sense
 to appear on received packets.  The following information is parsed from the
 radiotap headers and used to control injection:
 
- * IEEE80211_RADIOTAP_RATE
-
-   rate in 500kbps units, automatic if invalid or not present
-
-
- * IEEE80211_RADIOTAP_ANTENNA
-
-   antenna to use, automatic if not present
-
-
- * IEEE80211_RADIOTAP_DBM_TX_POWER
-
-   transmit power in dBm, automatic if not present
-
-
  * IEEE80211_RADIOTAP_FLAGS
 
    IEEE80211_RADIOTAP_F_FCS: FCS will be removed and recalculated
    IEEE80211_RADIOTAP_F_WEP: frame will be encrypted if key available
    IEEE80211_RADIOTAP_F_FRAG: frame will be fragmented if longer than the
-                             current fragmentation threshold. Note that
-                             this flag is only reliable when software
-                             fragmentation is enabled)
+                             current fragmentation threshold.
+
 
 The injection code can also skip all other currently defined radiotap fields
 facilitating replay of captured radiotap headers directly.
 
-Here is an example valid radiotap header defining these three parameters
+Here is an example valid radiotap header defining some parameters
 
        0x00, 0x00, // <-- radiotap version
        0x0b, 0x00, // <- radiotap header length
@@ -72,8 +56,8 @@ interface), along the following lines:
 ...
        r = pcap_inject(ppcap, u8aSendBuffer, nLength);
 
-You can also find sources for a complete inject test applet here:
+You can also find a link to a complete inject application here:
 
-http://penumbra.warmcat.com/_twk/tiki-index.php?page=packetspammer
+http://wireless.kernel.org/en/users/Documentation/packetspammer
 
 Andy Green <andy@warmcat.com>
index c9074f9b78bb7f2b25df1607c37953fdc7b6aa47..1a77a3cfae540795d1d2ae0074cde85f15113f42 100644 (file)
@@ -38,9 +38,6 @@ ifinfomsg::if_flags & IFF_LOWER_UP:
 ifinfomsg::if_flags & IFF_DORMANT:
  Driver has signaled netif_dormant_on()
 
-These interface flags can also be queried without netlink using the
-SIOCGIFFLAGS ioctl.
-
 TLV IFLA_OPERSTATE
 
 contains RFC2863 state of the interface in numeric representation:
index 07c53d5960353fa571e99a73b67910d7b10d6125..a22fd85e37965d4d2290b240324e5855aa65fd65 100644 (file)
@@ -4,16 +4,18 @@
 
 This file documents the CONFIG_PACKET_MMAP option available with the PACKET
 socket interface on 2.4 and 2.6 kernels. This type of sockets is used for 
-capture network traffic with utilities like tcpdump or any other that uses 
-the libpcap library. 
-
-You can find the latest version of this document at
+capture network traffic with utilities like tcpdump or any other that needs
+raw access to network interface.
 
+You can find the latest version of this document at:
     http://pusa.uv.es/~ulisses/packet_mmap/
 
-Please send me your comments to
+Howto can be found at:
+    http://wiki.gnu-log.net (packet_mmap)
 
+Please send your comments to
     Ulisses Alonso Camaró <uaca@i.hate.spam.alumni.uv.es>
+    Johann Baudy <johann.baudy@gnu-log.net>
 
 -------------------------------------------------------------------------------
 + Why use PACKET_MMAP
@@ -25,19 +27,24 @@ to capture each packet, it requires two if you want to get packet's
 timestamp (like libpcap always does).
 
 In the other hand PACKET_MMAP is very efficient. PACKET_MMAP provides a size 
-configurable circular buffer mapped in user space. This way reading packets just 
-needs to wait for them, most of the time there is no need to issue a single 
-system call. By using a shared buffer between the kernel and the user 
-also has the benefit of minimizing packet copies.
-
-It's fine to use PACKET_MMAP to improve the performance of the capture process, 
-but it isn't everything. At least, if you are capturing at high speeds (this 
-is relative to the cpu speed), you should check if the device driver of your 
-network interface card supports some sort of interrupt load mitigation or 
-(even better) if it supports NAPI, also make sure it is enabled.
+configurable circular buffer mapped in user space that can be used to either
+send or receive packets. This way reading packets just needs to wait for them,
+most of the time there is no need to issue a single system call. Concerning
+transmission, multiple packets can be sent through one system call to get the
+highest bandwidth.
+By using a shared buffer between the kernel and the user also has the benefit
+of minimizing packet copies.
+
+It's fine to use PACKET_MMAP to improve the performance of the capture and
+transmission process, but it isn't everything. At least, if you are capturing
+at high speeds (this is relative to the cpu speed), you should check if the
+device driver of your network interface card supports some sort of interrupt
+load mitigation or (even better) if it supports NAPI, also make sure it is
+enabled. For transmission, check the MTU (Maximum Transmission Unit) used and
+supported by devices of your network.
 
 --------------------------------------------------------------------------------
-+ How to use CONFIG_PACKET_MMAP
++ How to use CONFIG_PACKET_MMAP to improve capture process
 --------------------------------------------------------------------------------
 
 From the user standpoint, you should use the higher level libpcap library, which
@@ -57,7 +64,7 @@ the low level details or want to improve libpcap by including PACKET_MMAP
 support.
 
 --------------------------------------------------------------------------------
-+ How to use CONFIG_PACKET_MMAP directly
++ How to use CONFIG_PACKET_MMAP directly to improve capture process
 --------------------------------------------------------------------------------
 
 From the system calls stand point, the use of PACKET_MMAP involves
@@ -66,6 +73,7 @@ the following process:
 
 [setup]     socket() -------> creation of the capture socket
             setsockopt() ---> allocation of the circular buffer (ring)
+                              option: PACKET_RX_RING
             mmap() ---------> mapping of the allocated buffer to the
                               user process
 
@@ -96,6 +104,65 @@ Next I will describe PACKET_MMAP settings and it's constraints,
 also the mapping of the circular buffer in the user process and 
 the use of this buffer.
 
+--------------------------------------------------------------------------------
++ How to use CONFIG_PACKET_MMAP directly to improve transmission process
+--------------------------------------------------------------------------------
+Transmission process is similar to capture as shown below.
+
+[setup]          socket() -------> creation of the transmission socket
+                 setsockopt() ---> allocation of the circular buffer (ring)
+                                   option: PACKET_TX_RING
+                 bind() ---------> bind transmission socket with a network interface
+                 mmap() ---------> mapping of the allocated buffer to the
+                                   user process
+
+[transmission]   poll() ---------> wait for free packets (optional)
+                 send() ---------> send all packets that are set as ready in
+                                   the ring
+                                   The flag MSG_DONTWAIT can be used to return
+                                   before end of transfer.
+
+[shutdown]  close() --------> destruction of the transmission socket and
+                              deallocation of all associated resources.
+
+Binding the socket to your network interface is mandatory (with zero copy) to
+know the header size of frames used in the circular buffer.
+
+As capture, each frame contains two parts:
+
+ --------------------
+| struct tpacket_hdr | Header. It contains the status of
+|                    | of this frame
+|--------------------|
+| data buffer        |
+.                    .  Data that will be sent over the network interface.
+.                    .
+ --------------------
+
+ bind() associates the socket to your network interface thanks to
+ sll_ifindex parameter of struct sockaddr_ll.
+
+ Initialization example:
+
+ struct sockaddr_ll my_addr;
+ struct ifreq s_ifr;
+ ...
+
+ strncpy (s_ifr.ifr_name, "eth0", sizeof(s_ifr.ifr_name));
+
+ /* get interface index of eth0 */
+ ioctl(this->socket, SIOCGIFINDEX, &s_ifr);
+
+ /* fill sockaddr_ll struct to prepare binding */
+ my_addr.sll_family = AF_PACKET;
+ my_addr.sll_protocol = ETH_P_ALL;
+ my_addr.sll_ifindex =  s_ifr.ifr_ifindex;
+
+ /* bind socket to eth0 */
+ bind(this->socket, (struct sockaddr *)&my_addr, sizeof(struct sockaddr_ll));
+
+ A complete tutorial is available at: http://wiki.gnu-log.net/
+
 --------------------------------------------------------------------------------
 + PACKET_MMAP settings
 --------------------------------------------------------------------------------
@@ -103,7 +170,10 @@ the use of this buffer.
 
 To setup PACKET_MMAP from user level code is done with a call like
 
+ - Capture process
      setsockopt(fd, SOL_PACKET, PACKET_RX_RING, (void *) &req, sizeof(req))
+ - Transmission process
+     setsockopt(fd, SOL_PACKET, PACKET_TX_RING, (void *) &req, sizeof(req))
 
 The most significant argument in the previous call is the req parameter, 
 this parameter must to have the following structure:
@@ -117,11 +187,11 @@ this parameter must to have the following structure:
     };
 
 This structure is defined in /usr/include/linux/if_packet.h and establishes a 
-circular buffer (ring) of unswappable memory mapped in the capture process. 
+circular buffer (ring) of unswappable memory.
 Being mapped in the capture process allows reading the captured frames and 
 related meta-information like timestamps without requiring a system call.
 
-Captured frames are grouped in blocks. Each block is a physically contiguous 
+Frames are grouped in blocks. Each block is a physically contiguous
 region of memory and holds tp_block_size/tp_frame_size frames. The total number 
 of blocks is tp_block_nr. Note that tp_frame_nr is a redundant parameter because
 
@@ -336,6 +406,7 @@ struct tpacket_hdr). If this field is 0 means that the frame is ready
 to be used for the kernel, If not, there is a frame the user can read 
 and the following flags apply:
 
++++ Capture process:
      from include/linux/if_packet.h
 
      #define TP_STATUS_COPY          2 
@@ -391,6 +462,37 @@ packets are in the ring:
 It doesn't incur in a race condition to first check the status value and 
 then poll for frames.
 
+
+++ Transmission process
+Those defines are also used for transmission:
+
+     #define TP_STATUS_AVAILABLE        0 // Frame is available
+     #define TP_STATUS_SEND_REQUEST     1 // Frame will be sent on next send()
+     #define TP_STATUS_SENDING          2 // Frame is currently in transmission
+     #define TP_STATUS_WRONG_FORMAT     4 // Frame format is not correct
+
+First, the kernel initializes all frames to TP_STATUS_AVAILABLE. To send a
+packet, the user fills a data buffer of an available frame, sets tp_len to
+current data buffer size and sets its status field to TP_STATUS_SEND_REQUEST.
+This can be done on multiple frames. Once the user is ready to transmit, it
+calls send(). Then all buffers with status equal to TP_STATUS_SEND_REQUEST are
+forwarded to the network device. The kernel updates each status of sent
+frames with TP_STATUS_SENDING until the end of transfer.
+At the end of each transfer, buffer status returns to TP_STATUS_AVAILABLE.
+
+    header->tp_len = in_i_size;
+    header->tp_status = TP_STATUS_SEND_REQUEST;
+    retval = send(this->socket, NULL, 0, 0);
+
+The user can also use poll() to check if a buffer is available:
+(status == TP_STATUS_SENDING)
+
+    struct pollfd pfd;
+    pfd.fd = fd;
+    pfd.revents = 0;
+    pfd.events = POLLOUT;
+    retval = poll(&pfd, 1, timeout);
+
 --------------------------------------------------------------------------------
 + THANKS
 --------------------------------------------------------------------------------
diff --git a/Documentation/powerpc/dts-bindings/can/sja1000.txt b/Documentation/powerpc/dts-bindings/can/sja1000.txt
new file mode 100644 (file)
index 0000000..d6d209d
--- /dev/null
@@ -0,0 +1,53 @@
+Memory mapped SJA1000 CAN controller from NXP (formerly Philips)
+
+Required properties:
+
+- compatible : should be "nxp,sja1000".
+
+- reg : should specify the chip select, address offset and size required
+       to map the registers of the SJA1000. The size is usually 0x80.
+
+- interrupts: property with a value describing the interrupt source
+       (number and sensitivity) required for the SJA1000.
+
+Optional properties:
+
+- nxp,external-clock-frequency : Frequency of the external oscillator
+       clock in Hz. Note that the internal clock frequency used by the
+       SJA1000 is half of that value. If not specified, a default value
+       of 16000000 (16 MHz) is used.
+
+- nxp,tx-output-mode : operation mode of the TX output control logic:
+       <0x0> : bi-phase output mode
+       <0x1> : normal output mode (default)
+       <0x2> : test output mode
+       <0x3> : clock output mode
+
+- nxp,tx-output-config : TX output pin configuration:
+       <0x01> : TX0 invert
+       <0x02> : TX0 pull-down (default)
+       <0x04> : TX0 pull-up
+       <0x06> : TX0 push-pull
+       <0x08> : TX1 invert
+       <0x10> : TX1 pull-down
+       <0x20> : TX1 pull-up
+       <0x30> : TX1 push-pull
+
+- nxp,clock-out-frequency : clock frequency in Hz on the CLKOUT pin.
+       If not specified or if the specified value is 0, the CLKOUT pin
+       will be disabled.
+
+- nxp,no-comparator-bypass : Allows to disable the CAN input comperator.
+
+For futher information, please have a look to the SJA1000 data sheet.
+
+Examples:
+
+can@3,100 {
+       compatible = "nxp,sja1000";
+       reg = <3 0x100 0x80>;
+       interrupts = <2 0>;
+       interrupt-parent = <&mpic>;
+       nxp,external-clock-frequency = <16000000>;
+};
+
diff --git a/Documentation/powerpc/dts-bindings/ecm.txt b/Documentation/powerpc/dts-bindings/ecm.txt
new file mode 100644 (file)
index 0000000..f514f29
--- /dev/null
@@ -0,0 +1,64 @@
+=====================================================================
+E500 LAW & Coherency Module Device Tree Binding
+Copyright (C) 2009 Freescale Semiconductor Inc.
+=====================================================================
+
+Local Access Window (LAW) Node
+
+The LAW node represents the region of CCSR space where local access
+windows are configured.  For ECM based devices this is the first 4k
+of CCSR space that includes CCSRBAR, ALTCBAR, ALTCAR, BPTR, and some
+number of local access windows as specified by fsl,num-laws.
+
+PROPERTIES
+
+  - compatible
+      Usage: required
+      Value type: <string>
+      Definition: Must include "fsl,ecm-law"
+
+  - reg
+      Usage: required
+      Value type: <prop-encoded-array>
+      Definition: A standard property.  The value specifies the
+          physical address offset and length of the CCSR space
+          registers.
+
+  - fsl,num-laws
+      Usage: required
+      Value type: <u32>
+      Definition: The value specifies the number of local access
+          windows for this device.
+
+=====================================================================
+
+E500 Coherency Module Node
+
+The E500 LAW node represents the region of CCSR space where ECM config
+and error reporting registers exist, this is the second 4k (0x1000)
+of CCSR space.
+
+PROPERTIES
+
+  - compatible
+      Usage: required
+      Value type: <string>
+      Definition: Must include "fsl,CHIP-ecm", "fsl,ecm" where
+      CHIP is the processor (mpc8572, mpc8544, etc.)
+
+  - reg
+      Usage: required
+      Value type: <prop-encoded-array>
+      Definition: A standard property.  The value specifies the
+          physical address offset and length of the CCSR space
+          registers.
+
+   - interrupts
+      Usage: required
+      Value type: <prop-encoded-array>
+
+   - interrupt-parent
+      Usage: required
+      Value type: <phandle>
+
+=====================================================================
index 78790d58dc2cb19ec93a290c4201fa94ce3bf6cf..6e37be1eeb2d2cc190780db3d01829acabbf950f 100644 (file)
@@ -17,6 +17,9 @@ Required properties:
 - model : precise model of the QE, Can be "QE", "CPM", or "CPM2"
 - reg : offset and length of the device registers.
 - bus-frequency : the clock frequency for QUICC Engine.
+- fsl,qe-num-riscs: define how many RISC engines the QE has.
+- fsl,qe-num-snums: define how many serial number(SNUM) the QE can use for the
+  threads.
 
 Recommended properties
 - brg-frequency : the internal clock source frequency for baud-rate
index 60084655776384b8ffbf210b18d71896c5c04c4d..5093ddf900da63bd61217d97899a3ac1435e01b5 100644 (file)
@@ -5,8 +5,7 @@ for MMC, SD, and SDIO types of memory cards.
 
 Required properties:
   - compatible : should be
-    "fsl,<chip>-esdhc", "fsl,mpc8379-esdhc" for MPC83xx processors.
-    "fsl,<chip>-esdhc", "fsl,mpc8536-esdhc" for MPC85xx processors.
+    "fsl,<chip>-esdhc", "fsl,esdhc"
   - reg : should contain eSDHC registers location and length.
   - interrupts : should contain eSDHC interrupt.
   - interrupt-parent : interrupt source phandle.
@@ -15,7 +14,7 @@ Required properties:
 Example:
 
 sdhci@2e000 {
-       compatible = "fsl,mpc8378-esdhc", "fsl,mpc8379-esdhc";
+       compatible = "fsl,mpc8378-esdhc", "fsl,esdhc";
        reg = <0x2e000 0x1000>;
        interrupts = <42 0x8>;
        interrupt-parent = <&ipic>;
diff --git a/Documentation/powerpc/dts-bindings/fsl/mcm.txt b/Documentation/powerpc/dts-bindings/fsl/mcm.txt
new file mode 100644 (file)
index 0000000..4ceda9b
--- /dev/null
@@ -0,0 +1,64 @@
+=====================================================================
+MPX LAW & Coherency Module Device Tree Binding
+Copyright (C) 2009 Freescale Semiconductor Inc.
+=====================================================================
+
+Local Access Window (LAW) Node
+
+The LAW node represents the region of CCSR space where local access
+windows are configured.  For MCM based devices this is the first 4k
+of CCSR space that includes CCSRBAR, ALTCBAR, ALTCAR, BPTR, and some
+number of local access windows as specified by fsl,num-laws.
+
+PROPERTIES
+
+  - compatible
+      Usage: required
+      Value type: <string>
+      Definition: Must include "fsl,mcm-law"
+
+  - reg
+      Usage: required
+      Value type: <prop-encoded-array>
+      Definition: A standard property.  The value specifies the
+          physical address offset and length of the CCSR space
+          registers.
+
+  - fsl,num-laws
+      Usage: required
+      Value type: <u32>
+      Definition: The value specifies the number of local access
+          windows for this device.
+
+=====================================================================
+
+MPX Coherency Module Node
+
+The MPX LAW node represents the region of CCSR space where MCM config
+and error reporting registers exist, this is the second 4k (0x1000)
+of CCSR space.
+
+PROPERTIES
+
+  - compatible
+      Usage: required
+      Value type: <string>
+      Definition: Must include "fsl,CHIP-mcm", "fsl,mcm" where
+      CHIP is the processor (mpc8641, mpc8610, etc.)
+
+  - reg
+      Usage: required
+      Value type: <prop-encoded-array>
+      Definition: A standard property.  The value specifies the
+          physical address offset and length of the CCSR space
+          registers.
+
+   - interrupts
+      Usage: required
+      Value type: <prop-encoded-array>
+
+   - interrupt-parent
+      Usage: required
+      Value type: <phandle>
+
+=====================================================================
index 4d3ee317a4a3e84181047ab417a3e2a88c4995bc..1b74b5f30af4b5c8180dbfd2e2b3cacbe99fa8c9 100644 (file)
-rfkill - RF switch subsystem support
-====================================
+rfkill - RF kill switch support
+===============================
 
-1 Introduction
-2 Implementation details
-3 Kernel driver guidelines
-3.1 wireless device drivers
-3.2 platform/switch drivers
-3.3 input device drivers
-4 Kernel API
-5 Userspace support
+1. Introduction
+2. Implementation details
+3. Kernel driver guidelines
+4. Kernel API
+5. Userspace support
 
 
-1. Introduction:
+1. Introduction
 
-The rfkill switch subsystem exists to add a generic interface to circuitry that
-can enable or disable the signal output of a wireless *transmitter* of any
-type.  By far, the most common use is to disable radio-frequency transmitters.
+The rfkill subsystem provides a generic interface to disabling any radio
+transmitter in the system. When a transmitter is blocked, it shall not
+radiate any power.
 
-Note that disabling the signal output means that the the transmitter is to be
-made to not emit any energy when "blocked".  rfkill is not about blocking data
-transmissions, it is about blocking energy emission.
+The subsystem also provides the ability to react on button presses and
+disable all transmitters of a certain type (or all). This is intended for
+situations where transmitters need to be turned off, for example on
+aircraft.
 
-The rfkill subsystem offers support for keys and switches often found on
-laptops to enable wireless devices like WiFi and Bluetooth, so that these keys
-and switches actually perform an action in all wireless devices of a given type
-attached to the system.
 
-The buttons to enable and disable the wireless transmitters are important in
-situations where the user is for example using his laptop on a location where
-radio-frequency transmitters _must_ be disabled (e.g. airplanes).
 
-Because of this requirement, userspace support for the keys should not be made
-mandatory.  Because userspace might want to perform some additional smarter
-tasks when the key is pressed, rfkill provides userspace the possibility to
-take over the task to handle the key events.
-
-===============================================================================
-2: Implementation details
+2. Implementation details
 
 The rfkill subsystem is composed of various components: the rfkill class, the
 rfkill-input module (an input layer handler), and some specific input layer
 events.
 
-The rfkill class provides kernel drivers with an interface that allows them to
-know when they should enable or disable a wireless network device transmitter.
-This is enabled by the CONFIG_RFKILL Kconfig option.
-
-The rfkill class support makes sure userspace will be notified of all state
-changes on rfkill devices through uevents.  It provides a notification chain
-for interested parties in the kernel to also get notified of rfkill state
-changes in other drivers.  It creates several sysfs entries which can be used
-by userspace.  See section "Userspace support".
-
-The rfkill-input module provides the kernel with the ability to implement a
-basic response when the user presses a key or button (or toggles a switch)
-related to rfkill functionality.  It is an in-kernel implementation of default
-policy of reacting to rfkill-related input events and neither mandatory nor
-required for wireless drivers to operate.  It is enabled by the
-CONFIG_RFKILL_INPUT Kconfig option.
-
-rfkill-input is a rfkill-related events input layer handler.  This handler will
-listen to all rfkill key events and will change the rfkill state of the
-wireless devices accordingly.  With this option enabled userspace could either
-do nothing or simply perform monitoring tasks.
-
-The rfkill-input module also provides EPO (emergency power-off) functionality
-for all wireless transmitters.  This function cannot be overridden, and it is
-always active.  rfkill EPO is related to *_RFKILL_ALL input layer events.
-
-
-Important terms for the rfkill subsystem:
-
-In order to avoid confusion, we avoid the term "switch" in rfkill when it is
-referring to an electronic control circuit that enables or disables a
-transmitter.  We reserve it for the physical device a human manipulates
-(which is an input device, by the way):
-
-rfkill switch:
-
-       A physical device a human manipulates.  Its state can be perceived by
-       the kernel either directly (through a GPIO pin, ACPI GPE) or by its
-       effect on a rfkill line of a wireless device.
-
-rfkill controller:
-
-       A hardware circuit that controls the state of a rfkill line, which a
-       kernel driver can interact with *to modify* that state (i.e. it has
-       either write-only or read/write access).
-
-rfkill line:
-
-       An input channel (hardware or software) of a wireless device, which
-       causes a wireless transmitter to stop emitting energy (BLOCK) when it
-       is active.  Point of view is extremely important here: rfkill lines are
-       always seen from the PoV of a wireless device (and its driver).
-
-soft rfkill line/software rfkill line:
-
-       A rfkill line the wireless device driver can directly change the state
-       of.  Related to rfkill_state RFKILL_STATE_SOFT_BLOCKED.
-
-hard rfkill line/hardware rfkill line:
-
-       A rfkill line that works fully in hardware or firmware, and that cannot
-       be overridden by the kernel driver.  The hardware device or the
-       firmware just exports its status to the driver, but it is read-only.
-       Related to rfkill_state RFKILL_STATE_HARD_BLOCKED.
-
-The enum rfkill_state describes the rfkill state of a transmitter:
-
-When a rfkill line or rfkill controller is in the RFKILL_STATE_UNBLOCKED state,
-the wireless transmitter (radio TX circuit for example) is *enabled*.  When the
-it is in the RFKILL_STATE_SOFT_BLOCKED or RFKILL_STATE_HARD_BLOCKED, the
-wireless transmitter is to be *blocked* from operating.
-
-RFKILL_STATE_SOFT_BLOCKED indicates that a call to toggle_radio() can change
-that state.  RFKILL_STATE_HARD_BLOCKED indicates that a call to toggle_radio()
-will not be able to change the state and will return with a suitable error if
-attempts are made to set the state to RFKILL_STATE_UNBLOCKED.
-
-RFKILL_STATE_HARD_BLOCKED is used by drivers to signal that the device is
-locked in the BLOCKED state by a hardwire rfkill line (typically an input pin
-that, when active, forces the transmitter to be disabled) which the driver
-CANNOT override.
-
-Full rfkill functionality requires two different subsystems to cooperate: the
-input layer and the rfkill class.  The input layer issues *commands* to the
-entire system requesting that devices registered to the rfkill class change
-state.  The way this interaction happens is not complex, but it is not obvious
-either:
-
-Kernel Input layer:
-
-       * Generates KEY_WWAN, KEY_WLAN, KEY_BLUETOOTH, SW_RFKILL_ALL, and
-         other such events when the user presses certain keys, buttons, or
-         toggles certain physical switches.
-
-       THE INPUT LAYER IS NEVER USED TO PROPAGATE STATUS, NOTIFICATIONS OR THE
-       KIND OF STUFF AN ON-SCREEN-DISPLAY APPLICATION WOULD REPORT.  It is
-       used to issue *commands* for the system to change behaviour, and these
-       commands may or may not be carried out by some kernel driver or
-       userspace application.  It follows that doing user feedback based only
-       on input events is broken, as there is no guarantee that an input event
-       will be acted upon.
-
-       Most wireless communication device drivers implementing rfkill
-       functionality MUST NOT generate these events, and have no reason to
-       register themselves with the input layer.  Doing otherwise is a common
-       misconception.  There is an API to propagate rfkill status change
-       information, and it is NOT the input layer.
-
-rfkill class:
-
-       * Calls a hook in a driver to effectively change the wireless
-         transmitter state;
-       * Keeps track of the wireless transmitter state (with help from
-         the driver);
-       * Generates userspace notifications (uevents) and a call to a
-         notification chain (kernel) when there is a wireless transmitter
-         state change;
-       * Connects a wireless communications driver with the common rfkill
-         control system, which, for example, allows actions such as
-         "switch all bluetooth devices offline" to be carried out by
-         userspace or by rfkill-input.
-
-       THE RFKILL CLASS NEVER ISSUES INPUT EVENTS.  THE RFKILL CLASS DOES
-       NOT LISTEN TO INPUT EVENTS.  NO DRIVER USING THE RFKILL CLASS SHALL
-       EVER LISTEN TO, OR ACT ON RFKILL INPUT EVENTS.  Doing otherwise is
-       a layering violation.
-
-       Most wireless data communication drivers in the kernel have just to
-       implement the rfkill class API to work properly.  Interfacing to the
-       input layer is not often required (and is very often a *bug*) on
-       wireless drivers.
-
-       Platform drivers often have to attach to the input layer to *issue*
-       (but never to listen to) rfkill events for rfkill switches, and also to
-       the rfkill class to export a control interface for the platform rfkill
-       controllers to the rfkill subsystem.  This does NOT mean the rfkill
-       switch is attached to a rfkill class (doing so is almost always wrong).
-       It just means the same kernel module is the driver for different
-       devices (rfkill switches and rfkill controllers).
-
-
-Userspace input handlers (uevents) or kernel input handlers (rfkill-input):
-
-       * Implements the policy of what should happen when one of the input
-         layer events related to rfkill operation is received.
-       * Uses the sysfs interface (userspace) or private rfkill API calls
-         to tell the devices registered with the rfkill class to change
-         their state (i.e. translates the input layer event into real
-         action).
-
-       * rfkill-input implements EPO by handling EV_SW SW_RFKILL_ALL 0
-         (power off all transmitters) in a special way: it ignores any
-         overrides and local state cache and forces all transmitters to the
-         RFKILL_STATE_SOFT_BLOCKED state (including those which are already
-         supposed to be BLOCKED).
-       * rfkill EPO will remain active until rfkill-input receives an
-         EV_SW SW_RFKILL_ALL 1 event.  While the EPO is active, transmitters
-         are locked in the blocked state (rfkill will refuse to unblock them).
-       * rfkill-input implements different policies that the user can
-         select for handling EV_SW SW_RFKILL_ALL 1.  It will unlock rfkill,
-         and either do nothing (leave transmitters blocked, but now unlocked),
-         restore the transmitters to their state before the EPO, or unblock
-         them all.
-
-Userspace uevent handler or kernel platform-specific drivers hooked to the
-rfkill notifier chain:
-
-       * Taps into the rfkill notifier chain or to KOBJ_CHANGE uevents,
-         in order to know when a device that is registered with the rfkill
-         class changes state;
-       * Issues feedback notifications to the user;
-       * In the rare platforms where this is required, synthesizes an input
-         event to command all *OTHER* rfkill devices to also change their
-         statues when a specific rfkill device changes state.
-
-
-===============================================================================
-3: Kernel driver guidelines
-
-Remember: point-of-view is everything for a driver that connects to the rfkill
-subsystem.  All the details below must be measured/perceived from the point of
-view of the specific driver being modified.
-
-The first thing one needs to know is whether his driver should be talking to
-the rfkill class or to the input layer.  In rare cases (platform drivers), it
-could happen that you need to do both, as platform drivers often handle a
-variety of devices in the same driver.
-
-Do not mistake input devices for rfkill controllers.  The only type of "rfkill
-switch" device that is to be registered with the rfkill class are those
-directly controlling the circuits that cause a wireless transmitter to stop
-working (or the software equivalent of them), i.e. what we call a rfkill
-controller.  Every other kind of "rfkill switch" is just an input device and
-MUST NOT be registered with the rfkill class.
-
-A driver should register a device with the rfkill class when ALL of the
-following conditions are met (they define a rfkill controller):
-
-1. The device is/controls a data communications wireless transmitter;
-
-2. The kernel can interact with the hardware/firmware to CHANGE the wireless
-   transmitter state (block/unblock TX operation);
-
-3. The transmitter can be made to not emit any energy when "blocked":
-   rfkill is not about blocking data transmissions, it is about blocking
-   energy emission;
-
-A driver should register a device with the input subsystem to issue
-rfkill-related events (KEY_WLAN, KEY_BLUETOOTH, KEY_WWAN, KEY_WIMAX,
-SW_RFKILL_ALL, etc) when ALL of the folowing conditions are met:
-
-1. It is directly related to some physical device the user interacts with, to
-   command the O.S./firmware/hardware to enable/disable a data communications
-   wireless transmitter.
-
-   Examples of the physical device are: buttons, keys and switches the user
-   will press/touch/slide/switch to enable or disable the wireless
-   communication device.
-
-2. It is NOT slaved to another device, i.e. there is no other device that
-   issues rfkill-related input events in preference to this one.
-
-   Please refer to the corner cases and examples section for more details.
-
-When in doubt, do not issue input events.  For drivers that should generate
-input events in some platforms, but not in others (e.g. b43), the best solution
-is to NEVER generate input events in the first place.  That work should be
-deferred to a platform-specific kernel module (which will know when to generate
-events through the rfkill notifier chain) or to userspace.  This avoids the
-usual maintenance problems with DMI whitelisting.
-
-
-Corner cases and examples:
-====================================
-
-1. If the device is an input device that, because of hardware or firmware,
-causes wireless transmitters to be blocked regardless of the kernel's will, it
-is still just an input device, and NOT to be registered with the rfkill class.
-
-2. If the wireless transmitter switch control is read-only, it is an input
-device and not to be registered with the rfkill class (and maybe not to be made
-an input layer event source either, see below).
-
-3. If there is some other device driver *closer* to the actual hardware the
-user interacted with (the button/switch/key) to issue an input event, THAT is
-the device driver that should be issuing input events.
-
-E.g:
-  [RFKILL slider switch] -- [GPIO hardware] -- [WLAN card rf-kill input]
-                           (platform driver)    (wireless card driver)
-
-The user is closer to the RFKILL slide switch plaform driver, so the driver
-which must issue input events is the platform driver looking at the GPIO
-hardware, and NEVER the wireless card driver (which is just a slave).  It is
-very likely that there are other leaves than just the WLAN card rf-kill input
-(e.g. a bluetooth card, etc)...
-
-On the other hand, some embedded devices do this:
-
-  [RFKILL slider switch] -- [WLAN card rf-kill input]
-                             (wireless card driver)
-
-In this situation, the wireless card driver *could* register itself as an input
-device and issue rf-kill related input events... but in order to AVOID the need
-for DMI whitelisting, the wireless card driver does NOT do it.  Userspace (HAL)
-or a platform driver (that exists only on these embedded devices) will do the
-dirty job of issuing the input events.
-
-
-COMMON MISTAKES in kernel drivers, related to rfkill:
-====================================
-
-1. NEVER confuse input device keys and buttons with input device switches.
-
-  1a. Switches are always set or reset.  They report the current state
-      (on position or off position).
-
-  1b. Keys and buttons are either in the pressed or not-pressed state, and
-      that's it.  A "button" that latches down when you press it, and
-      unlatches when you press it again is in fact a switch as far as input
-      devices go.
-
-Add the SW_* events you need for switches, do NOT try to emulate a button using
-KEY_* events just because there is no such SW_* event yet.  Do NOT try to use,
-for example, KEY_BLUETOOTH when you should be using SW_BLUETOOTH instead.
-
-2. Input device switches (sources of EV_SW events) DO store their current state
-(so you *must* initialize it by issuing a gratuitous input layer event on
-driver start-up and also when resuming from sleep), and that state CAN be
-queried from userspace through IOCTLs.  There is no sysfs interface for this,
-but that doesn't mean you should break things trying to hook it to the rfkill
-class to get a sysfs interface :-)
-
-3. Do not issue *_RFKILL_ALL events by default, unless you are sure it is the
-correct event for your switch/button.  These events are emergency power-off
-events when they are trying to turn the transmitters off.  An example of an
-input device which SHOULD generate *_RFKILL_ALL events is the wireless-kill
-switch in a laptop which is NOT a hotkey, but a real sliding/rocker switch.
-An example of an input device which SHOULD NOT generate *_RFKILL_ALL events by
-default, is any sort of hot key that is type-specific (e.g. the one for WLAN).
-
-
-3.1 Guidelines for wireless device drivers
-------------------------------------------
-
-(in this text, rfkill->foo means the foo field of struct rfkill).
-
-1. Each independent transmitter in a wireless device (usually there is only one
-transmitter per device) should have a SINGLE rfkill class attached to it.
-
-2. If the device does not have any sort of hardware assistance to allow the
-driver to rfkill the device, the driver should emulate it by taking all actions
-required to silence the transmitter.
-
-3. If it is impossible to silence the transmitter (i.e. it still emits energy,
-even if it is just in brief pulses, when there is no data to transmit and there
-is no hardware support to turn it off) do NOT lie to the users.  Do not attach
-it to a rfkill class.  The rfkill subsystem does not deal with data
-transmission, it deals with energy emission.  If the transmitter is emitting
-energy, it is not blocked in rfkill terms.
-
-4. It doesn't matter if the device has multiple rfkill input lines affecting
-the same transmitter, their combined state is to be exported as a single state
-per transmitter (see rule 1).
-
-This rule exists because users of the rfkill subsystem expect to get (and set,
-when possible) the overall transmitter rfkill state, not of a particular rfkill
-line.
-
-5. The wireless device driver MUST NOT leave the transmitter enabled during
-suspend and hibernation unless:
+The rfkill class is provided for kernel drivers to register their radio
+transmitter with the kernel, provide methods for turning it on and off and,
+optionally, letting the system know about hardware-disabled states that may
+be implemented on the device. This code is enabled with the CONFIG_RFKILL
+Kconfig option, which drivers can "select".
 
-       5.1. The transmitter has to be enabled for some sort of functionality
-       like wake-on-wireless-packet or autonomous packed forwarding in a mesh
-       network, and that functionality is enabled for this suspend/hibernation
-       cycle.
+The rfkill class code also notifies userspace of state changes, this is
+achieved via uevents. It also provides some sysfs files for userspace to
+check the status of radio transmitters. See the "Userspace support" section
+below.
 
-AND
 
-       5.2. The device was not on a user-requested BLOCKED state before
-       the suspend (i.e. the driver must NOT unblock a device, not even
-       to support wake-on-wireless-packet or remain in the mesh).
+The rfkill-input code implements a basic response to rfkill buttons -- it
+implements turning on/off all devices of a certain class (or all).
 
-In other words, there is absolutely no allowed scenario where a driver can
-automatically take action to unblock a rfkill controller (obviously, this deals
-with scenarios where soft-blocking or both soft and hard blocking is happening.
-Scenarios where hardware rfkill lines are the only ones blocking the
-transmitter are outside of this rule, since the wireless device driver does not
-control its input hardware rfkill lines in the first place).
+When the device is hard-blocked (either by a call to rfkill_set_hw_state()
+or from query_hw_block) set_block() will be invoked but drivers can well
+ignore the method call since they can use the return value of the function
+rfkill_set_hw_state() to sync the software state instead of keeping track
+of calls to set_block().
 
-6. During resume, rfkill will try to restore its previous state.
 
-7. After a rfkill class is suspended, it will *not* call rfkill->toggle_radio
-until it is resumed.
+The entire functionality is spread over more than one subsystem:
 
+ * The kernel input layer generates KEY_WWAN, KEY_WLAN etc. and
+   SW_RFKILL_ALL -- when the user presses a button. Drivers for radio
+   transmitters generally do not register to the input layer, unless the
+   device really provides an input device (i.e. a button that has no
+   effect other than generating a button press event)
 
-Example of a WLAN wireless driver connected to the rfkill subsystem:
---------------------------------------------------------------------
+ * The rfkill-input code hooks up to these events and switches the soft-block
+   of the various radio transmitters, depending on the button type.
 
-A certain WLAN card has one input pin that causes it to block the transmitter
-and makes the status of that input pin available (only for reading!) to the
-kernel driver.  This is a hard rfkill input line (it cannot be overridden by
-the kernel driver).
+ * The rfkill drivers turn off/on their transmitters as requested.
 
-The card also has one PCI register that, if manipulated by the driver, causes
-it to block the transmitter.  This is a soft rfkill input line.
+ * The rfkill class will generate userspace notifications (uevents) to tell
+   userspace what the current state is.
 
-It has also a thermal protection circuitry that shuts down its transmitter if
-the card overheats, and makes the status of that protection available (only for
-reading!) to the kernel driver.  This is also a hard rfkill input line.
 
-If either one of these rfkill lines are active, the transmitter is blocked by
-the hardware and forced offline.
 
-The driver should allocate and attach to its struct device *ONE* instance of
-the rfkill class (there is only one transmitter).
+3. Kernel driver guidelines
 
-It can implement the get_state() hook, and return RFKILL_STATE_HARD_BLOCKED if
-either one of its two hard rfkill input lines are active.  If the two hard
-rfkill lines are inactive, it must return RFKILL_STATE_SOFT_BLOCKED if its soft
-rfkill input line is active.  Only if none of the rfkill input lines are
-active, will it return RFKILL_STATE_UNBLOCKED.
 
-Since the device has a hardware rfkill line, it IS subject to state changes
-external to rfkill.  Therefore, the driver must make sure that it calls
-rfkill_force_state() to keep the status always up-to-date, and it must do a
-rfkill_force_state() on resume from sleep.
+Drivers for radio transmitters normally implement only the rfkill class.
+These drivers may not unblock the transmitter based on own decisions, they
+should act on information provided by the rfkill class only.
 
-Every time the driver gets a notification from the card that one of its rfkill
-lines changed state (polling might be needed on badly designed cards that don't
-generate interrupts for such events), it recomputes the rfkill state as per
-above, and calls rfkill_force_state() to update it.
+Platform drivers might implement input devices if the rfkill button is just
+that, a button. If that button influences the hardware then you need to
+implement an rfkill class instead. This also applies if the platform provides
+a way to turn on/off the transmitter(s).
 
-The driver should implement the toggle_radio() hook, that:
+During suspend/hibernation, transmitters should only be left enabled when
+wake-on wlan or similar functionality requires it and the device wasn't
+blocked before suspend/hibernate. Note that it may be necessary to update
+the rfkill subsystem's idea of what the current state is at resume time if
+the state may have changed over suspend.
 
-1. Returns an error if one of the hardware rfkill lines are active, and the
-caller asked for RFKILL_STATE_UNBLOCKED.
 
-2. Activates the soft rfkill line if the caller asked for state
-RFKILL_STATE_SOFT_BLOCKED.  It should do this even if one of the hard rfkill
-lines are active, effectively double-blocking the transmitter.
 
-3. Deactivates the soft rfkill line if none of the hardware rfkill lines are
-active and the caller asked for RFKILL_STATE_UNBLOCKED.
-
-===============================================================================
-4: Kernel API
+4. Kernel API
 
 To build a driver with rfkill subsystem support, the driver should depend on
-(or select) the Kconfig symbol RFKILL; it should _not_ depend on RKFILL_INPUT.
+(or select) the Kconfig symbol RFKILL.
 
 The hardware the driver talks to may be write-only (where the current state
 of the hardware is unknown), or read-write (where the hardware can be queried
 about its current state).
 
-The rfkill class will call the get_state hook of a device every time it needs
-to know the *real* current state of the hardware.  This can happen often, but
-it does not do any polling, so it is not enough on hardware that is subject
-to state changes outside of the rfkill subsystem.
-
-Therefore, calling rfkill_force_state() when a state change happens is
-mandatory when the device has a hardware rfkill line, or when something else
-like the firmware could cause its state to be changed without going through the
-rfkill class.
-
-Some hardware provides events when its status changes.  In these cases, it is
-best for the driver to not provide a get_state hook, and instead register the
-rfkill class *already* with the correct status, and keep it updated using
-rfkill_force_state() when it gets an event from the hardware.
-
-rfkill_force_state() must be used on the device resume handlers to update the
-rfkill status, should there be any chance of the device status changing during
-the sleep.
-
-There is no provision for a statically-allocated rfkill struct.  You must
-use rfkill_allocate() to allocate one.
-
-You should:
-       - rfkill_allocate()
-       - modify rfkill fields (flags, name)
-       - modify state to the current hardware state (THIS IS THE ONLY TIME
-         YOU CAN ACCESS state DIRECTLY)
-       - rfkill_register()
-
-The only way to set a device to the RFKILL_STATE_HARD_BLOCKED state is through
-a suitable return of get_state() or through rfkill_force_state().
+Calling rfkill_set_hw_state() when a state change happens is required from
+rfkill drivers that control devices that can be hard-blocked unless they also
+assign the poll_hw_block() callback (then the rfkill core will poll the
+device). Don't do this unless you cannot get the event in any other way.
 
-When a device is in the RFKILL_STATE_HARD_BLOCKED state, the only way to switch
-it to a different state is through a suitable return of get_state() or through
-rfkill_force_state().
 
-If toggle_radio() is called to set a device to state RFKILL_STATE_SOFT_BLOCKED
-when that device is already at the RFKILL_STATE_HARD_BLOCKED state, it should
-not return an error.  Instead, it should try to double-block the transmitter,
-so that its state will change from RFKILL_STATE_HARD_BLOCKED to
-RFKILL_STATE_SOFT_BLOCKED should the hardware blocking cease.
-
-Please refer to the source for more documentation.
-
-===============================================================================
-5: Userspace support
-
-rfkill devices issue uevents (with an action of "change"), with the following
-environment variables set:
-
-RFKILL_NAME
-RFKILL_STATE
-RFKILL_TYPE
 
-The ABI for these variables is defined by the sysfs attributes.  It is best
-to take a quick look at the source to make sure of the possible values.
+5. Userspace support
 
-It is expected that HAL will trap those, and bridge them to DBUS, etc.  These
-events CAN and SHOULD be used to give feedback to the user about the rfkill
-status of the system.
-
-Input devices may issue events that are related to rfkill.  These are the
-various KEY_* events and SW_* events supported by rfkill-input.c.
-
-******IMPORTANT******
-When rfkill-input is ACTIVE, userspace is NOT TO CHANGE THE STATE OF AN RFKILL
-SWITCH IN RESPONSE TO AN INPUT EVENT also handled by rfkill-input, unless it
-has set to true the user_claim attribute for that particular switch.  This rule
-is *absolute*; do NOT violate it.
-******IMPORTANT******
-
-Userspace must not assume it is the only source of control for rfkill switches.
-Their state CAN and WILL change due to firmware actions, direct user actions,
-and the rfkill-input EPO override for *_RFKILL_ALL.
-
-When rfkill-input is not active, userspace must initiate a rfkill status
-change by writing to the "state" attribute in order for anything to happen.
-
-Take particular care to implement EV_SW SW_RFKILL_ALL properly.  When that
-switch is set to OFF, *every* rfkill device *MUST* be immediately put into the
-RFKILL_STATE_SOFT_BLOCKED state, no questions asked.
-
-The following sysfs entries will be created:
+The following sysfs entries exist for every rfkill device:
 
        name: Name assigned by driver to this key (interface or driver name).
        type: Name of the key type ("wlan", "bluetooth", etc).
        state: Current state of the transmitter
                0: RFKILL_STATE_SOFT_BLOCKED
-                       transmitter is forced off, but one can override it
-                       by a write to the state attribute;
+                       transmitter is turned off by software
                1: RFKILL_STATE_UNBLOCKED
-                       transmiter is NOT forced off, and may operate if
-                       all other conditions for such operation are met
-                       (such as interface is up and configured, etc);
+                       transmitter is (potentially) active
                2: RFKILL_STATE_HARD_BLOCKED
                        transmitter is forced off by something outside of
-                       the driver's control.  One cannot set a device to
-                       this state through writes to the state attribute;
-       claim: 1: Userspace handles events, 0: Kernel handles events
-
-Both the "state" and "claim" entries are also writable. For the "state" entry
-this means that when 1 or 0 is written, the device rfkill state (if not yet in
-the requested state), will be will be toggled accordingly.
-
-For the "claim" entry writing 1 to it means that the kernel no longer handles
-key events even though RFKILL_INPUT input was enabled. When "claim" has been
-set to 0, userspace should make sure that it listens for the input events or
-check the sysfs "state" entry regularly to correctly perform the required tasks
-when the rkfill key is pressed.
-
-A note about input devices and EV_SW events:
-
-In order to know the current state of an input device switch (like
-SW_RFKILL_ALL), you will need to use an IOCTL.  That information is not
-available through sysfs in a generic way at this time, and it is not available
-through the rfkill class AT ALL.
+                       the driver's control.
+       claim: 0: Kernel handles events (currently always reads that value)
+
+rfkill devices also issue uevents (with an action of "change"), with the
+following environment variables set:
+
+RFKILL_NAME
+RFKILL_STATE
+RFKILL_TYPE
+
+The contents of these variables corresponds to the "name", "state" and
+"type" sysfs files explained above.
+
+An alternative userspace interface exists as a misc device /dev/rfkill,
+which allows userspace to obtain and set the state of rfkill devices and
+sets of devices. It also notifies userspace about device addition and
+removal. The API is a simple read/write API that is defined in
+linux/rfkill.h.
index a1fe87ad483222f643657c0422f6797a4feb24d4..2cb7566904b128a80bd507359f22031b800ff9b7 100644 (file)
@@ -947,6 +947,12 @@ P: Luis R. Rodriguez
 M:     lrodriguez@atheros.com
 P:     Jouni Malinen
 M:     jmalinen@atheros.com
+P:     Sujith Manoharan
+M:     Sujith.Manoharan@atheros.com
+P:     Vasanthakumar Thiagarajan
+M:     vasanth@atheros.com
+P:     Senthil Balasubramanian
+M:     senthilkumar@atheros.com
 L:     linux-wireless@vger.kernel.org
 L:     ath9k-devel@lists.ath9k.org
 S:     Supported
@@ -1339,6 +1345,13 @@ F:       drivers/net/can/
 F:     include/linux/can/
 F:     include/linux/can.h
 
+CAN NETWORK DRIVERS
+P:     Wolfgang Grandegger
+M:     wg@grandegger.com
+L:     socketcan-core@lists.berlios.de (subscribers-only)
+W:     http://developer.berlios.de/projects/socketcan/
+S:     Maintained
+
 CELL BROADBAND ENGINE ARCHITECTURE
 P:     Arnd Bergmann
 M:     arnd@arndb.de
@@ -2843,6 +2856,18 @@ L:       linux1394-devel@lists.sourceforge.net
 S:     Maintained
 F:     drivers/ieee1394/raw1394*
 
+IEEE 802.15.4 SUBSYSTEM
+P:     Dmitry Eremin-Solenikov
+M:     dbaryshkov@gmail.com
+P:     Sergey Lapin
+M:     slapin@ossfans.org
+L:     linux-zigbee-devel@lists.sourceforge.net
+W:     http://apps.sourceforge.net/trac/linux-zigbee
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/lumag/lowpan.git
+S:     Maintained
+F:     net/ieee802154/
+F:     drivers/ieee801254/
+
 INTEGRITY MEASUREMENT ARCHITECTURE (IMA)
 P:     Mimi Zohar
 M:     zohar@us.ibm.com
@@ -3136,6 +3161,7 @@ M:        samuel@sortiz.org
 L:     irda-users@lists.sourceforge.net (subscribers-only)
 W:     http://irda.sourceforge.net/
 S:     Maintained
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/sameo/irda-2.6.git
 F:     Documentation/networking/irda.txt
 F:     drivers/net/irda/
 F:     include/net/irda/
@@ -4621,8 +4647,8 @@ S:        Maintained
 F:     drivers/ata/sata_promise.*
 
 PS3 NETWORK SUPPORT
-P:     Masakazu Mokuno
-M:     mokuno@sm.sony.co.jp
+P:     Geoff Levand
+M:     geoffrey.levand@am.sony.com
 L:     netdev@vger.kernel.org
 L:     cbe-oss-dev@ozlabs.org
 S:     Supported
@@ -4823,7 +4849,7 @@ F:        drivers/net/r6040.c
 RDS - RELIABLE DATAGRAM SOCKETS
 P:     Andy Grover
 M:     andy.grover@oracle.com
-L:     rds-devel@oss.oracle.com
+L:     rds-devel@oss.oracle.com (moderated for non-subscribers)
 S:     Supported
 F:     net/rds/
 
@@ -4863,9 +4889,9 @@ S:        Supported
 F:     fs/reiserfs/
 
 RFKILL
-P:     Ivo van Doorn
-M:     IvDoorn@gmail.com
-L:     netdev@vger.kernel.org
+P:     Johannes Berg
+M:     johannes@sipsolutions.net
+L:     linux-wireless@vger.kernel.org
 S:     Maintained
 F      Documentation/rfkill.txt
 F:     net/rfkill/
index 69e2655249d295ee6b891c98b61d2c24297cf2ef..98099bda937069958f4722715cb4cc16af4398e4 100644 (file)
 #define        EOWNERDEAD      136     /* Owner died */
 #define        ENOTRECOVERABLE 137     /* State not recoverable */
 
+#define        ERFKILL         138     /* Operation not possible due to RF-kill */
+
 #endif
index 442b87476f97105963df1862efcf089bc542f7d0..93bb4247b7ed019e92a6b64806c86af2fe338c7f 100644 (file)
@@ -536,7 +536,7 @@ setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info,
        return err;
 }
 
-static inline void restart_syscall(struct pt_regs *regs)
+static inline void setup_syscall_restart(struct pt_regs *regs)
 {
        regs->ARM_r0 = regs->ARM_ORIG_r0;
        regs->ARM_pc -= thumb_mode(regs) ? 2 : 4;
@@ -571,7 +571,7 @@ handle_signal(unsigned long sig, struct k_sigaction *ka,
                        }
                        /* fallthrough */
                case -ERESTARTNOINTR:
-                       restart_syscall(regs);
+                       setup_syscall_restart(regs);
                }
        }
 
@@ -695,7 +695,7 @@ static int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall)
                if (regs->ARM_r0 == -ERESTARTNOHAND ||
                    regs->ARM_r0 == -ERESTARTSYS ||
                    regs->ARM_r0 == -ERESTARTNOINTR) {
-                       restart_syscall(regs);
+                       setup_syscall_restart(regs);
                }
        }
        single_step_set(current);
index fb0294bd43107442d4a0f3f569f67caf4ba59c29..c31e601eb49ccb069b99dcd806d4eabd8d27a34d 100644 (file)
@@ -35,21 +35,25 @@ static void tosa_bt_off(struct tosa_bt_data *data)
        gpio_set_value(data->gpio_reset, 0);
 }
 
-static int tosa_bt_toggle_radio(void *data, enum rfkill_state state)
+static int tosa_bt_set_block(void *data, bool blocked)
 {
-       pr_info("BT_RADIO going: %s\n",
-                       state == RFKILL_STATE_ON ? "on" : "off");
+       pr_info("BT_RADIO going: %s\n", blocked ? "off" : "on");
 
-       if (state == RFKILL_STATE_ON) {
+       if (!blocked) {
                pr_info("TOSA_BT: going ON\n");
                tosa_bt_on(data);
        } else {
                pr_info("TOSA_BT: going OFF\n");
                tosa_bt_off(data);
        }
+
        return 0;
 }
 
+static const struct rfkill_ops tosa_bt_rfkill_ops = {
+       .set_block = tosa_bt_set_block,
+};
+
 static int tosa_bt_probe(struct platform_device *dev)
 {
        int rc;
@@ -70,18 +74,14 @@ static int tosa_bt_probe(struct platform_device *dev)
        if (rc)
                goto err_pwr_dir;
 
-       rfk = rfkill_allocate(&dev->dev, RFKILL_TYPE_BLUETOOTH);
+       rfk = rfkill_alloc("tosa-bt", &dev->dev, RFKILL_TYPE_BLUETOOTH,
+                          &tosa_bt_rfkill_ops, data);
        if (!rfk) {
                rc = -ENOMEM;
                goto err_rfk_alloc;
        }
 
-       rfk->name = "tosa-bt";
-       rfk->toggle_radio = tosa_bt_toggle_radio;
-       rfk->data = data;
-#ifdef CONFIG_RFKILL_LEDS
-       rfk->led_trigger.name = "tosa-bt";
-#endif
+       rfkill_set_led_trigger_name(rfk, "tosa-bt");
 
        rc = rfkill_register(rfk);
        if (rc)
@@ -92,9 +92,7 @@ static int tosa_bt_probe(struct platform_device *dev)
        return 0;
 
 err_rfkill:
-       if (rfk)
-               rfkill_free(rfk);
-       rfk = NULL;
+       rfkill_destroy(rfk);
 err_rfk_alloc:
        tosa_bt_off(data);
 err_pwr_dir:
@@ -113,8 +111,10 @@ static int __devexit tosa_bt_remove(struct platform_device *dev)
 
        platform_set_drvdata(dev, NULL);
 
-       if (rfk)
+       if (rfk) {
                rfkill_unregister(rfk);
+               rfkill_destroy(rfk);
+       }
        rfk = NULL;
 
        tosa_bt_off(data);
index 168267a5dfb3e3f80775599990c5d54bba81acc3..117ad5920e53aefb56ce25e683002498b0fecfc0 100644 (file)
@@ -31,7 +31,6 @@
 #include <linux/input.h>
 #include <linux/gpio.h>
 #include <linux/pda_power.h>
-#include <linux/rfkill.h>
 #include <linux/spi/spi.h>
 
 #include <asm/setup.h>
index 803d7be0938f07fe96db54761e4a442f03689a4d..27227561bad67a7ebea577acffa3796f5998b8ea 100644 (file)
@@ -212,7 +212,7 @@ out:
        return err;
 }
 
-static inline void restart_syscall(struct pt_regs *regs)
+static inline void setup_syscall_restart(struct pt_regs *regs)
 {
        if (regs->r12 == -ERESTART_RESTARTBLOCK)
                regs->r8 = __NR_restart_syscall;
@@ -296,7 +296,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset, int syscall)
                        }
                        /* fall through */
                case -ERESTARTNOINTR:
-                       restart_syscall(regs);
+                       setup_syscall_restart(regs);
                }
        }
 
index e95d5ad9285dab575aa10f70e398c1c8368e0316..c99a41e29fe81b859a9384519b9308646624f6e6 100644 (file)
@@ -8,7 +8,7 @@
 #include <linux/sort.h>
 
 #include <asm/uaccess.h>
-#include <asm/module.h>
+#include <linux/module.h>
 
 static int cmp_ex(const void *a, const void *b)
 {
@@ -55,7 +55,7 @@ void sort_extable (struct exception_table_entry *start,
 
 static inline unsigned long ex_to_addr(const struct exception_table_entry *x)
 {
-       return (unsigned long)&x->insn + x->insn;
+       return (unsigned long)&x->addr + x->addr;
 }
 
 #ifdef CONFIG_MODULES
index 3c0d840e45773e867980116affb51aae255273f5..a0efc73819e4ae832f9b60dd351fb0fcfb37825c 100644 (file)
 #define        EOWNERDEAD      165     /* Owner died */
 #define        ENOTRECOVERABLE 166     /* State not recoverable */
 
+#define        ERFKILL         167     /* Operation not possible due to RF-kill */
+
 #define EDQUOT         1133    /* Quota exceeded */
 
 #ifdef __KERNEL__
index e2f3ddc796be0082a685c43a40a1e42c10a69357..9992abdd782da1fa2edc1ce9231273c93abcaaa5 100644 (file)
 #define EOWNERDEAD     254     /* Owner died */
 #define ENOTRECOVERABLE        255     /* State not recoverable */
 
+#define        ERFKILL         256     /* Operation not possible due to RF-kill */
 
 #endif
index cdc9a6ff4be823a356521e00b7d35eb15b28e013..93a61898b25936f5d0abeef302745f7ca25b91c3 100644 (file)
@@ -42,6 +42,10 @@ config GENERIC_HARDIRQS
        bool
        default y
 
+config GENERIC_HARDIRQS_NO__DO_IRQ
+       bool
+       default y
+
 config HAVE_SETUP_PER_CPU_AREA
        def_bool PPC64
 
@@ -296,9 +300,19 @@ config IOMMU_VMERGE
 config IOMMU_HELPER
        def_bool PPC64
 
+config SWIOTLB
+       bool "SWIOTLB support"
+       default n
+       select IOMMU_HELPER
+       ---help---
+         Support for IO bounce buffering for systems without an IOMMU.
+         This allows us to DMA to the full physical address space on
+         platforms where the size of a physical address is larger
+         than the bus address.  Not all platforms support this.
+
 config PPC_NEED_DMA_SYNC_OPS
        def_bool y
-       depends on NOT_COHERENT_CACHE
+       depends on (NOT_COHERENT_CACHE || SWIOTLB)
 
 config HOTPLUG_CPU
        bool "Support for enabling/disabling CPUs"
index a1098e23221fb1debd36fc62bf54740f1829a3e4..d79a902d155af69406d9d8b9199ea4519cd44669 100644 (file)
@@ -41,6 +41,19 @@ config HCALL_STATS
          This option will add a small amount of overhead to all hypervisor
          calls.
 
+config PPC_EMULATED_STATS
+       bool "Emulated instructions tracking"
+       depends on DEBUG_FS
+       help
+         Adds code to keep track of the number of instructions that are
+         emulated by the in-kernel emulator. Counters for the various classes
+         of emulated instructions are available under
+         powerpc/emulated_instructions/ in the root of the debugfs file
+         system. Optionally (controlled by
+         powerpc/emulated_instructions/do_warn in debugfs), rate-limited
+         warnings can be printed to the console when instructions are
+         emulated.
+
 config CODE_PATCHING_SELFTEST
        bool "Run self-tests of the code-patching code."
        depends on DEBUG_KERNEL
index 551fc58c05cf7d4299acf91b71fa0f395ac75ed9..bc35f4e2b81cd0cfa65a536dfc99e877410f268e 100644 (file)
@@ -142,6 +142,7 @@ head-$(CONFIG_FSL_BOOKE)    := arch/powerpc/kernel/head_fsl_booke.o
 
 head-$(CONFIG_PPC64)           += arch/powerpc/kernel/entry_64.o
 head-$(CONFIG_PPC_FPU)         += arch/powerpc/kernel/fpu.o
+head-$(CONFIG_ALTIVEC)         += arch/powerpc/kernel/vector.o
 
 core-y                         += arch/powerpc/kernel/ \
                                   arch/powerpc/mm/ \
index 53a7a6255909b10fe8d732fa27ba0b4b0f46a3e0..910944edd886fdfa42994adedfbe4757668bd084 100644 (file)
                device_type = "soc";
                compatible = "fsl,mpc8641-soc", "simple-bus";
                ranges = <0x0 0xfef00000 0x00100000>;
-               reg = <0xfef00000 0x100000>;    // CCSRBAR 1M
                bus-frequency = <33333333>;
 
+               mcm-law@0 {
+                       compatible = "fsl,mcm-law";
+                       reg = <0x0 0x1000>;
+                       fsl,num-laws = <10>;
+               };
+
+               mcm@1000 {
+                       compatible = "fsl,mpc8641-mcm", "fsl,mcm";
+                       reg = <0x1000 0x1000>;
+                       interrupts = <17 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
                i2c1: i2c@3000 {
                        #address-cells = <1>;
                        #size-cells = <0>;
index 1569117e5ddc6fd8ac0bd7f6afd53507ee5978c1..0f4c9ec2c3a619523108360f315b1fc0dd83fa73 100644 (file)
                device_type = "soc";
                compatible = "simple-bus";
                ranges = <0x0 0xfef00000 0x00100000>;
-               reg = <0xfef00000 0x100000>;    // CCSRBAR 1M
                bus-frequency = <33333333>;
 
+               mcm-law@0 {
+                       compatible = "fsl,mcm-law";
+                       reg = <0x0 0x1000>;
+                       fsl,num-laws = <10>;
+               };
+
+               mcm@1000 {
+                       compatible = "fsl,mpc8641-mcm", "fsl,mcm";
+                       reg = <0x1000 0x1000>;
+                       interrupts = <17 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
                i2c1: i2c@3000 {
                        #address-cells = <1>;
                        #size-cells = <0>;
index 6582dbd36da7ff5b99de958f7bec0841ca7270db..217f8aa6672579afef8b710e733d628ad7058b20 100644 (file)
                device_type = "soc";
                compatible = "simple-bus";
                ranges = <0x0 0xfef00000 0x00100000>;
-               reg = <0xfef00000 0x100000>;    // CCSRBAR 1M
                bus-frequency = <33333333>;
 
+               mcm-law@0 {
+                       compatible = "fsl,mcm-law";
+                       reg = <0x0 0x1000>;
+                       fsl,num-laws = <10>;
+               };
+
+               mcm@1000 {
+                       compatible = "fsl,mpc8641-mcm", "fsl,mcm";
+                       reg = <0x1000 0x1000>;
+                       interrupts = <17 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
                i2c1: i2c@3000 {
                        #address-cells = <1>;
                        #size-cells = <0>;
index c9cfd374bffb327ce8be53dadcd48d39935be113..bdb7fc0fa3327c53e0ccfc8bf054a12684766a20 100644 (file)
                ranges = <0x00000000 0xfdf00000 0x00100000>;
                bus-frequency = <0>;                            /* Fixed by bootwrapper */
 
+               ecm-law@0 {
+                       compatible = "fsl,ecm-law";
+                       reg = <0x0 0x1000>;
+                       fsl,num-laws = <8>;
+               };
+
+               ecm@1000 {
+                       compatible = "fsl,mpc8560-ecm", "fsl,ecm";
+                       reg = <0x1000 0x1000>;
+                       interrupts = <17 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
                memory-controller@2000 {
                        compatible = "fsl,mpc8540-memory-controller";
                        reg = <0x2000 0x1000>;
index 57c595bf10717f23036a9d292b6025c26f273afa..436c9c671dd9c86edabd0ca1054490e806b7c841 100644 (file)
                reg = <0xe0100000 0x480>;
                brg-frequency = <0>;
                bus-frequency = <198000000>;
+               fsl,qe-num-riscs = <1>;
+               fsl,qe-num-snums = <28>;
 
                muram@10000 {
                        #address-cells = <1>;
        };
 
        pci0: pci@e0008500 {
-               cell-index = <1>;
                interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
                interrupt-map = <
                                /* IDSEL 0x11 AD17 */
index 4319bd70a580beaa65a992eb92c6b94e91285c7c..9a0952f74b812555b3208d877618f3ff00f57891 100644 (file)
                reg = <0xe0100000 0x480>;
                brg-frequency = <0>;
                bus-frequency = <198000000>;
+               fsl,qe-num-riscs = <1>;
+               fsl,qe-num-snums = <28>;
 
                muram@10000 {
                        #address-cells = <1>;
        };
 
        pci0: pci@e0008500 {
-               cell-index = <1>;
                interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
                interrupt-map = <
                                /* IDSEL 0x10 AD16 (USB) */
index 1ae38f0ddef885d32e25d13e7bee99009ddb1766..e3eeaeda91876e037561277baef3d22170dc6f93 100644 (file)
        };
 
        pci0: pci@e0008500 {
-               cell-index = <1>;
                interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
                interrupt-map = <
                                /* IDSEL 0x10 - SATA */
        };
 
        pci1: pci@e0008600 {
-               cell-index = <2>;
                interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
                interrupt-map = <
                                /* IDSEL 0x0E - MiniPCI Slot */
index 662abe1fb80488f1dd97ba7cbcdd03469471086d..eb732115f01604efa1a839a6daf3b108e9c83ea9 100644 (file)
        };
 
        pci0: pci@e0008600 {
-               cell-index = <2>;
                interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
                interrupt-map = <
                                /* IDSEL 0x0F - PCI Slot */
index d9f0a2325fa4fddbc93f8019a94446f76d4d0cdc..a2553a6f90096bdc179c09b4877b8544df47bcdd 100644 (file)
        };
 
        pci0: pci@e0008500 {
-               cell-index = <1>;
                interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
                interrupt-map = <
 
        };
 
        pci1: pci@e0008600 {
-               cell-index = <2>;
                interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
                interrupt-map = <
 
index 6e34f170fa62ba3b38a60eab064138b7b75e34f6..39ff4c829cafd125e0db34484cea04df1a393e99 100644 (file)
                reg = <0xe0100000 0x480>;
                brg-frequency = <0>;
                bus-frequency = <396000000>;
+               fsl,qe-num-riscs = <2>;
+               fsl,qe-num-snums = <28>;
 
                muram@10000 {
                        #address-cells = <1>;
        };
 
        pci0: pci@e0008500 {
-               cell-index = <1>;
                interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
                interrupt-map = <
 
index 37b789510d68bc160b191a53717a916e293ea361..6315d6fcc58aa87aeb0acc2617c9366a441a4f66 100644 (file)
                        clock-frequency = <0>;
                        bus-frequency = <0>;
                        brg-frequency = <0>;
+                       fsl,qe-num-riscs = <2>;
+                       fsl,qe-num-snums = <28>;
 
                        muram@10000 {
                                #address-cells = <1>;
index 963708017e6c304fa5c11846e3c12abc903cf482..67bb372c94511ae2dd35d9e3478e2d2f96fa48e6 100644 (file)
        };
 
        pci0: pci@e0008500 {
-               cell-index = <0>;
                interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
                interrupt-map = <
 
index 651ff2f9db2d9e3ab963953752579aae34da3bf3..a955a577db810ffc68f6ad16f2e2f8f8ad19d884 100644 (file)
        };
 
        pci0: pci@e0008500 {
-               cell-index = <0>;
                interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
                interrupt-map = <
 
index d6f208b8297a834de4c97a3b4521650819311e41..d266ddbfc28d0551da3e68d2424636dd566fe41e 100644 (file)
        };
 
        pci0: pci@e0008500 {
-               cell-index = <0>;
                interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
                interrupt-map = <
 
index b31c5041350b18b983ef055ee1d2e79250741bb2..e781ad2f1f8aca20d0312636ac9f974b8898ab81 100644 (file)
                device_type = "soc";
                compatible = "simple-bus";
                ranges = <0x0 0xffe00000 0x100000>;
-               reg = <0xffe00000 0x1000>;
                bus-frequency = <0>;            // Filled out by uboot.
 
+               ecm-law@0 {
+                       compatible = "fsl,ecm-law";
+                       reg = <0x0 0x1000>;
+                       fsl,num-laws = <12>;
+               };
+
+               ecm@1000 {
+                       compatible = "fsl,mpc8536-ecm", "fsl,ecm";
+                       reg = <0x1000 0x1000>;
+                       interrupts = <17 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
                memory-controller@2000 {
                        compatible = "fsl,mpc8536-memory-controller";
                        reg = <0x2000 0x1000>;
        };
 
        pci0: pci@ffe08000 {
-               cell-index = <0>;
                compatible = "fsl,mpc8540-pci";
                device_type = "pci";
                interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
        };
 
        pci1: pcie@ffe09000 {
-               cell-index = <1>;
                compatible = "fsl,mpc8548-pcie";
                device_type = "pci";
                #interrupt-cells = <1>;
        };
 
        pci2: pcie@ffe0a000 {
-               cell-index = <2>;
                compatible = "fsl,mpc8548-pcie";
                device_type = "pci";
                #interrupt-cells = <1>;
        };
 
        pci3: pcie@ffe0b000 {
-               cell-index = <3>;
                compatible = "fsl,mpc8548-pcie";
                device_type = "pci";
                #interrupt-cells = <1>;
index ddd67be10b033f6afa6683aa67654ea66f173c30..9dc292962a9a395a6b6f6daace2313f1258720c8 100644 (file)
                device_type = "soc";
                compatible = "simple-bus";
                ranges = <0x0 0xe0000000 0x100000>;
-               reg = <0xe0000000 0x100000>;    // CCSRBAR 1M
                bus-frequency = <0>;
 
+               ecm-law@0 {
+                       compatible = "fsl,ecm-law";
+                       reg = <0x0 0x1000>;
+                       fsl,num-laws = <8>;
+               };
+
+               ecm@1000 {
+                       compatible = "fsl,mpc8540-ecm", "fsl,ecm";
+                       reg = <0x1000 0x1000>;
+                       interrupts = <17 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
                memory-controller@2000 {
                        compatible = "fsl,8540-memory-controller";
                        reg = <0x2000 0x1000>;
        };
 
        pci0: pci@e0008000 {
-               cell-index = <0>;
                interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
                interrupt-map = <
 
index e45097f44fbde4fecc1a2df04d0a8700283e391b..9a3ad311aedfc62402338cf470a2373417332307 100644 (file)
                device_type = "soc";
                compatible = "simple-bus";
                ranges = <0x0 0xe0000000 0x100000>;
-               reg = <0xe0000000 0x1000>;      // CCSRBAR 1M
                bus-frequency = <0>;
 
+               ecm-law@0 {
+                       compatible = "fsl,ecm-law";
+                       reg = <0x0 0x1000>;
+                       fsl,num-laws = <8>;
+               };
+
+               ecm@1000 {
+                       compatible = "fsl,mpc8541-ecm", "fsl,ecm";
+                       reg = <0x1000 0x1000>;
+                       interrupts = <17 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
                memory-controller@2000 {
                        compatible = "fsl,8541-memory-controller";
                        reg = <0x2000 0x1000>;
        };
 
        pci0: pci@e0008000 {
-               cell-index = <0>;
                interrupt-map-mask = <0x1f800 0x0 0x0 0x7>;
                interrupt-map = <
 
        };
 
        pci1: pci@e0009000 {
-               cell-index = <1>;
                interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
                interrupt-map = <
 
index 7c6932be01978222a964fa47f932991952b92959..98e94b465662c4dfef1b8a8805721251eb157078 100644 (file)
                compatible = "simple-bus";
 
                ranges = <0x0 0xe0000000 0x100000>;
-               reg = <0xe0000000 0x1000>;      // CCSRBAR 1M
                bus-frequency = <0>;            // Filled out by uboot.
 
+               ecm-law@0 {
+                       compatible = "fsl,ecm-law";
+                       reg = <0x0 0x1000>;
+                       fsl,num-laws = <10>;
+               };
+
+               ecm@1000 {
+                       compatible = "fsl,mpc8544-ecm", "fsl,ecm";
+                       reg = <0x1000 0x1000>;
+                       interrupts = <17 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
                memory-controller@2000 {
                        compatible = "fsl,8544-memory-controller";
                        reg = <0x2000 0x1000>;
        };
 
        pci0: pci@e0008000 {
-               cell-index = <0>;
                compatible = "fsl,mpc8540-pci";
                device_type = "pci";
                interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
        };
 
        pci1: pcie@e0009000 {
-               cell-index = <1>;
                compatible = "fsl,mpc8548-pcie";
                device_type = "pci";
                #interrupt-cells = <1>;
        };
 
        pci2: pcie@e000a000 {
-               cell-index = <2>;
                compatible = "fsl,mpc8548-pcie";
                device_type = "pci";
                #interrupt-cells = <1>;
        };
 
        pci3: pcie@e000b000 {
-               cell-index = <3>;
                compatible = "fsl,mpc8548-pcie";
                device_type = "pci";
                #interrupt-cells = <1>;
index 804e903532939c59caa7f1681a2c7a00fb1da89a..475be1433fe104ce4484d46454344a0c929e039e 100644 (file)
                device_type = "soc";
                compatible = "simple-bus";
                ranges = <0x0 0xe0000000 0x100000>;
-               reg = <0xe0000000 0x1000>;      // CCSRBAR
                bus-frequency = <0>;
 
+               ecm-law@0 {
+                       compatible = "fsl,ecm-law";
+                       reg = <0x0 0x1000>;
+                       fsl,num-laws = <10>;
+               };
+
+               ecm@1000 {
+                       compatible = "fsl,mpc8548-ecm", "fsl,ecm";
+                       reg = <0x1000 0x1000>;
+                       interrupts = <17 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
                memory-controller@2000 {
                        compatible = "fsl,8548-memory-controller";
                        reg = <0x2000 0x1000>;
        };
 
        pci0: pci@e0008000 {
-               cell-index = <0>;
                interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
                interrupt-map = <
                        /* IDSEL 0x4 (PCIX Slot 2) */
        };
 
        pci1: pci@e0009000 {
-               cell-index = <1>;
                interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
                interrupt-map = <
 
        };
 
        pci2: pcie@e000a000 {
-               cell-index = <2>;
                interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
                interrupt-map = <
 
index 9484f0729b1080bd2342e3efe622c3437cbcaf97..065b2f093de2527e60aef62abd9079bbcf9a5d16 100644 (file)
                device_type = "soc";
                compatible = "simple-bus";
                ranges = <0x0 0xe0000000 0x100000>;
-               reg = <0xe0000000 0x1000>;      // CCSRBAR 1M
                bus-frequency = <0>;
 
+               ecm-law@0 {
+                       compatible = "fsl,ecm-law";
+                       reg = <0x0 0x1000>;
+                       fsl,num-laws = <8>;
+               };
+
+               ecm@1000 {
+                       compatible = "fsl,mpc8555-ecm", "fsl,ecm";
+                       reg = <0x1000 0x1000>;
+                       interrupts = <17 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
                memory-controller@2000 {
                        compatible = "fsl,8555-memory-controller";
                        reg = <0x2000 0x1000>;
        };
 
        pci0: pci@e0008000 {
-               cell-index = <0>;
                interrupt-map-mask = <0x1f800 0x0 0x0 0x7>;
                interrupt-map = <
 
        };
 
        pci1: pci@e0009000 {
-               cell-index = <1>;
                interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
                interrupt-map = <
 
index cc2acf87d02fdac479cdb8ca99ad29c5decd1402..a5bb1ec70a5ac5805bd8c63dbaea192d995d498f 100644 (file)
                device_type = "soc";
                compatible = "simple-bus";
                ranges = <0x0 0xe0000000 0x100000>;
-               reg = <0xe0000000 0x200>;
                bus-frequency = <330000000>;
 
+               ecm-law@0 {
+                       compatible = "fsl,ecm-law";
+                       reg = <0x0 0x1000>;
+                       fsl,num-laws = <8>;
+               };
+
+               ecm@1000 {
+                       compatible = "fsl,mpc8560-ecm", "fsl,ecm";
+                       reg = <0x1000 0x1000>;
+                       interrupts = <17 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
                memory-controller@2000 {
                        compatible = "fsl,8540-memory-controller";
                        reg = <0x2000 0x1000>;
        };
 
        pci0: pci@e0008000 {
-               cell-index = <0>;
                #interrupt-cells = <1>;
                #size-cells = <2>;
                #address-cells = <3>;
index 9d52e3b250474782ebabc42cdd18d5b410f33044..00c2bbda70134db027f1d169d9d1814c4317d545 100644 (file)
@@ -26,6 +26,7 @@
                serial1 = &serial1;
                pci0 = &pci0;
                pci1 = &pci1;
+               rapidio0 = &rio0;
        };
 
        cpus {
                device_type = "soc";
                compatible = "simple-bus";
                ranges = <0x0 0xe0000000 0x100000>;
-               reg = <0xe0000000 0x1000>;
                bus-frequency = <0>;
 
+               ecm-law@0 {
+                       compatible = "fsl,ecm-law";
+                       reg = <0x0 0x1000>;
+                       fsl,num-laws = <10>;
+               };
+
+               ecm@1000 {
+                       compatible = "fsl,mpc8568-ecm", "fsl,ecm";
+                       reg = <0x1000 0x1000>;
+                       interrupts = <17 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
                memory-controller@2000 {
                        compatible = "fsl,8568-memory-controller";
                        reg = <0x2000 0x1000>;
                        device_type = "open-pic";
                };
 
+               msi@41600 {
+                       compatible = "fsl,mpc8568-msi", "fsl,mpic-msi";
+                       reg = <0x41600 0x80>;
+                       msi-available-ranges = <0 0x100>;
+                       interrupts = <
+                               0xe0 0
+                               0xe1 0
+                               0xe2 0
+                               0xe3 0
+                               0xe4 0
+                               0xe5 0
+                               0xe6 0
+                               0xe7 0>;
+                       interrupt-parent = <&mpic>;
+               };
+
                par_io@e0100 {
                        reg = <0xe0100 0x100>;
                        device_type = "par_io";
                reg = <0xe0080000 0x480>;
                brg-frequency = <0>;
                bus-frequency = <396000000>;
+               fsl,qe-num-riscs = <2>;
+               fsl,qe-num-snums = <28>;
 
                muram@10000 {
                        #address-cells = <1>;
        };
 
        pci0: pci@e0008000 {
-               cell-index = <0>;
                interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
                interrupt-map = <
                        /* IDSEL 0x12 AD18 */
 
        /* PCI Express */
        pci1: pcie@e000a000 {
-               cell-index = <2>;
                interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
                interrupt-map = <
 
                                  0x0 0x800000>;
                };
        };
+
+       rio0: rapidio@e00c00000 {
+               #address-cells = <2>;
+               #size-cells = <2>;
+               compatible = "fsl,mpc8568-rapidio", "fsl,rapidio-delta";
+               reg = <0xe00c0000 0x20000>;
+               ranges = <0x0 0x0 0xc0000000 0x0 0x20000000>;
+               interrupts = <48 2 /* error     */
+                             49 2 /* bell_outb */
+                             50 2 /* bell_inb  */
+                             53 2 /* msg1_tx   */
+                             54 2 /* msg1_rx   */
+                             55 2 /* msg2_tx   */
+                             56 2 /* msg2_rx   */>;
+               interrupt-parent = <&mpic>;
+       };
 };
diff --git a/arch/powerpc/boot/dts/mpc8569mds.dts b/arch/powerpc/boot/dts/mpc8569mds.dts
new file mode 100644 (file)
index 0000000..39c2927
--- /dev/null
@@ -0,0 +1,583 @@
+/*
+ * MPC8569E MDS Device Tree Source
+ *
+ * Copyright (C) 2009 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.
+ */
+
+/dts-v1/;
+
+/ {
+       model = "MPC8569EMDS";
+       compatible = "fsl,MPC8569EMDS";
+       #address-cells = <1>;
+       #size-cells = <1>;
+
+       aliases {
+               serial0 = &serial0;
+               serial1 = &serial1;
+               ethernet0 = &enet0;
+               ethernet1 = &enet1;
+               ethernet2 = &enet2;
+               ethernet3 = &enet3;
+               pci1 = &pci1;
+               rapidio0 = &rio0;
+       };
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               PowerPC,8569@0 {
+                       device_type = "cpu";
+                       reg = <0x0>;
+                       d-cache-line-size = <32>;       // 32 bytes
+                       i-cache-line-size = <32>;       // 32 bytes
+                       d-cache-size = <0x8000>;                // L1, 32K
+                       i-cache-size = <0x8000>;                // L1, 32K
+                       timebase-frequency = <0>;
+                       bus-frequency = <0>;
+                       clock-frequency = <0>;
+                       next-level-cache = <&L2>;
+               };
+       };
+
+       memory {
+               device_type = "memory";
+       };
+
+       localbus@e0005000 {
+               #address-cells = <2>;
+               #size-cells = <1>;
+               compatible = "fsl,mpc8569-elbc", "fsl,elbc", "simple-bus";
+               reg = <0xe0005000 0x1000>;
+               interrupts = <19 2>;
+               interrupt-parent = <&mpic>;
+
+               ranges = <0x0 0x0 0xfe000000 0x02000000
+                         0x1 0x0 0xf8000000 0x00008000
+                         0x2 0x0 0xf0000000 0x04000000
+                         0x3 0x0 0xfc000000 0x00008000
+                         0x4 0x0 0xf8008000 0x00008000
+                         0x5 0x0 0xf8010000 0x00008000>;
+
+               nor@0,0 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       compatible = "cfi-flash";
+                       reg = <0x0 0x0 0x02000000>;
+                       bank-width = <2>;
+                       device-width = <1>;
+               };
+
+               bcsr@1,0 {
+                       compatible = "fsl,mpc8569mds-bcsr";
+                       reg = <1 0 0x8000>;
+               };
+
+               nand@3,0 {
+                       compatible = "fsl,mpc8569-fcm-nand",
+                                    "fsl,elbc-fcm-nand";
+                       reg = <3 0 0x8000>;
+               };
+
+               pib@4,0 {
+                       compatible = "fsl,mpc8569mds-pib";
+                       reg = <4 0 0x8000>;
+               };
+
+               pib@5,0 {
+                       compatible = "fsl,mpc8569mds-pib";
+                       reg = <5 0 0x8000>;
+               };
+       };
+
+       soc@e0000000 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               device_type = "soc";
+               compatible = "fsl,mpc8569-immr", "simple-bus";
+               ranges = <0x0 0xe0000000 0x100000>;
+               bus-frequency = <0>;
+
+               ecm-law@0 {
+                       compatible = "fsl,ecm-law";
+                       reg = <0x0 0x1000>;
+                       fsl,num-laws = <10>;
+               };
+
+               ecm@1000 {
+                       compatible = "fsl,mpc8569-ecm", "fsl,ecm";
+                       reg = <0x1000 0x1000>;
+                       interrupts = <17 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
+               memory-controller@2000 {
+                       compatible = "fsl,mpc8569-memory-controller";
+                       reg = <0x2000 0x1000>;
+                       interrupt-parent = <&mpic>;
+                       interrupts = <18 2>;
+               };
+
+               i2c@3000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       cell-index = <0>;
+                       compatible = "fsl-i2c";
+                       reg = <0x3000 0x100>;
+                       interrupts = <43 2>;
+                       interrupt-parent = <&mpic>;
+                       dfsrr;
+
+                       rtc@68 {
+                               compatible = "dallas,ds1374";
+                               reg = <0x68>;
+                       };
+               };
+
+               i2c@3100 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       cell-index = <1>;
+                       compatible = "fsl-i2c";
+                       reg = <0x3100 0x100>;
+                       interrupts = <43 2>;
+                       interrupt-parent = <&mpic>;
+                       dfsrr;
+               };
+
+               serial0: serial@4500 {
+                       cell-index = <0>;
+                       device_type = "serial";
+                       compatible = "ns16550";
+                       reg = <0x4500 0x100>;
+                       clock-frequency = <0>;
+                       interrupts = <42 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
+               serial1: serial@4600 {
+                       cell-index = <1>;
+                       device_type = "serial";
+                       compatible = "ns16550";
+                       reg = <0x4600 0x100>;
+                       clock-frequency = <0>;
+                       interrupts = <42 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
+               L2: l2-cache-controller@20000 {
+                       compatible = "fsl,mpc8569-l2-cache-controller";
+                       reg = <0x20000 0x1000>;
+                       cache-line-size = <32>; // 32 bytes
+                       cache-size = <0x80000>; // L2, 512K
+                       interrupt-parent = <&mpic>;
+                       interrupts = <16 2>;
+               };
+
+               dma@21300 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       compatible = "fsl,mpc8569-dma", "fsl,eloplus-dma";
+                       reg = <0x21300 0x4>;
+                       ranges = <0x0 0x21100 0x200>;
+                       cell-index = <0>;
+                       dma-channel@0 {
+                               compatible = "fsl,mpc8569-dma-channel",
+                                               "fsl,eloplus-dma-channel";
+                               reg = <0x0 0x80>;
+                               cell-index = <0>;
+                               interrupt-parent = <&mpic>;
+                               interrupts = <20 2>;
+                       };
+                       dma-channel@80 {
+                               compatible = "fsl,mpc8569-dma-channel",
+                                               "fsl,eloplus-dma-channel";
+                               reg = <0x80 0x80>;
+                               cell-index = <1>;
+                               interrupt-parent = <&mpic>;
+                               interrupts = <21 2>;
+                       };
+                       dma-channel@100 {
+                               compatible = "fsl,mpc8569-dma-channel",
+                                               "fsl,eloplus-dma-channel";
+                               reg = <0x100 0x80>;
+                               cell-index = <2>;
+                               interrupt-parent = <&mpic>;
+                               interrupts = <22 2>;
+                       };
+                       dma-channel@180 {
+                               compatible = "fsl,mpc8569-dma-channel",
+                                               "fsl,eloplus-dma-channel";
+                               reg = <0x180 0x80>;
+                               cell-index = <3>;
+                               interrupt-parent = <&mpic>;
+                               interrupts = <23 2>;
+                       };
+               };
+
+               sdhci@2e000 {
+                       compatible = "fsl,mpc8569-esdhc", "fsl,esdhc";
+                       reg = <0x2e000 0x1000>;
+                       interrupts = <72 0x8>;
+                       interrupt-parent = <&mpic>;
+                       /* Filled in by U-Boot */
+                       clock-frequency = <0>;
+                       status = "disabled";
+               };
+
+               crypto@30000 {
+                       compatible = "fsl,sec3.1", "fsl,sec3.0", "fsl,sec2.4",
+                               "fsl,sec2.2", "fsl,sec2.1", "fsl,sec2.0";
+                       reg = <0x30000 0x10000>;
+                       interrupts = <45 2 58 2>;
+                       interrupt-parent = <&mpic>;
+                       fsl,num-channels = <4>;
+                       fsl,channel-fifo-len = <24>;
+                       fsl,exec-units-mask = <0xbfe>;
+                       fsl,descriptor-types-mask = <0x3ab0ebf>;
+               };
+
+               mpic: pic@40000 {
+                       interrupt-controller;
+                       #address-cells = <0>;
+                       #interrupt-cells = <2>;
+                       reg = <0x40000 0x40000>;
+                       compatible = "chrp,open-pic";
+                       device_type = "open-pic";
+               };
+
+               msi@41600 {
+                       compatible = "fsl,mpc8568-msi", "fsl,mpic-msi";
+                       reg = <0x41600 0x80>;
+                       msi-available-ranges = <0 0x100>;
+                       interrupts = <
+                               0xe0 0
+                               0xe1 0
+                               0xe2 0
+                               0xe3 0
+                               0xe4 0
+                               0xe5 0
+                               0xe6 0
+                               0xe7 0>;
+                       interrupt-parent = <&mpic>;
+               };
+
+               global-utilities@e0000 {
+                       compatible = "fsl,mpc8569-guts";
+                       reg = <0xe0000 0x1000>;
+                       fsl,has-rstcr;
+               };
+
+               par_io@e0100 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       reg = <0xe0100 0x100>;
+                       ranges = <0x0 0xe0100 0x100>;
+                       device_type = "par_io";
+                       num-ports = <7>;
+
+                       qe_pio_e: gpio-controller@80 {
+                               #gpio-cells = <2>;
+                               compatible = "fsl,mpc8569-qe-pario-bank",
+                                            "fsl,mpc8323-qe-pario-bank";
+                               reg = <0x80 0x18>;
+                               gpio-controller;
+                       };
+
+                       pio1: ucc_pin@01 {
+                               pio-map = <
+                       /* port  pin  dir  open_drain  assignment  has_irq */
+                                       0x2  0x1f 0x1  0x0  0x1  0x0    /* QE_MUX_MDC */
+                                       0x2  0x1e 0x3  0x0  0x2  0x0    /* QE_MUX_MDIO */
+                                       0x2  0x0b 0x2  0x0  0x1  0x0    /* CLK12*/
+                                       0x0  0x0  0x1  0x0  0x3  0x0    /* ENET1_TXD0_SER1_TXD0 */
+                                       0x0  0x1  0x1  0x0  0x3  0x0    /* ENET1_TXD1_SER1_TXD1 */
+                                       0x0  0x2  0x1  0x0  0x1  0x0    /* ENET1_TXD2_SER1_TXD2 */
+                                       0x0  0x3  0x1  0x0  0x2  0x0    /* ENET1_TXD3_SER1_TXD3 */
+                                       0x0  0x6  0x2  0x0  0x3  0x0    /* ENET1_RXD0_SER1_RXD0 */
+                                       0x0  0x7  0x2  0x0  0x1  0x0    /* ENET1_RXD1_SER1_RXD1 */
+                                       0x0  0x8  0x2  0x0  0x2  0x0    /* ENET1_RXD2_SER1_RXD2 */
+                                       0x0  0x9  0x2  0x0  0x2  0x0    /* ENET1_RXD3_SER1_RXD3 */
+                                       0x0  0x4  0x1  0x0  0x2  0x0    /* ENET1_TX_EN_SER1_RTS_B */
+                                       0x0  0xc  0x2  0x0  0x3  0x0    /* ENET1_RX_DV_SER1_CTS_B */
+                                       0x2  0x8  0x2  0x0  0x1  0x0    /* ENET1_GRXCLK */
+                                       0x2  0x14 0x1  0x0  0x2  0x0>;  /* ENET1_GTXCLK */
+                       };
+
+                       pio2: ucc_pin@02 {
+                               pio-map = <
+                       /* port  pin  dir  open_drain  assignment  has_irq */
+                                       0x2  0x1f 0x1  0x0  0x1  0x0    /* QE_MUX_MDC */
+                                       0x2  0x1e 0x3  0x0  0x2  0x0    /* QE_MUX_MDIO */
+                                       0x2  0x10 0x2  0x0  0x3  0x0    /* CLK17 */
+                                       0x0  0xe  0x1  0x0  0x2  0x0    /* ENET2_TXD0_SER2_TXD0 */
+                                       0x0  0xf  0x1  0x0  0x2  0x0    /* ENET2_TXD1_SER2_TXD1 */
+                                       0x0  0x10 0x1  0x0  0x1  0x0    /* ENET2_TXD2_SER2_TXD2 */
+                                       0x0  0x11 0x1  0x0  0x1  0x0    /* ENET2_TXD3_SER2_TXD3 */
+                                       0x0  0x14 0x2  0x0  0x2  0x0    /* ENET2_RXD0_SER2_RXD0 */
+                                       0x0  0x15 0x2  0x0  0x1  0x0    /* ENET2_RXD1_SER2_RXD1 */
+                                       0x0  0x16 0x2  0x0  0x1  0x0    /* ENET2_RXD2_SER2_RXD2 */
+                                       0x0  0x17 0x2  0x0  0x1  0x0    /* ENET2_RXD3_SER2_RXD3 */
+                                       0x0  0x12 0x1  0x0  0x2  0x0    /* ENET2_TX_EN_SER2_RTS_B */
+                                       0x0  0x1a 0x2  0x0  0x3  0x0    /* ENET2_RX_DV_SER2_CTS_B */
+                                       0x2  0x3  0x2  0x0  0x1  0x0    /* ENET2_GRXCLK */
+                                       0x2  0x2 0x1  0x0  0x2  0x0>;   /* ENET2_GTXCLK */
+                       };
+
+                       pio3: ucc_pin@03 {
+                               pio-map = <
+                       /* port  pin  dir  open_drain  assignment  has_irq */
+                                       0x2  0x1f 0x1  0x0  0x1  0x0    /* QE_MUX_MDC */
+                                       0x2  0x1e 0x3  0x0  0x2  0x0    /* QE_MUX_MDIO */
+                                       0x2  0x0b 0x2  0x0  0x1  0x0    /* CLK12*/
+                                       0x0  0x1d 0x1  0x0  0x2  0x0    /* ENET3_TXD0_SER3_TXD0 */
+                                       0x0  0x1e 0x1  0x0  0x3  0x0    /* ENET3_TXD1_SER3_TXD1 */
+                                       0x0  0x1f 0x1  0x0  0x2  0x0    /* ENET3_TXD2_SER3_TXD2 */
+                                       0x1  0x0  0x1  0x0  0x3  0x0    /* ENET3_TXD3_SER3_TXD3 */
+                                       0x1  0x3  0x2  0x0  0x3  0x0    /* ENET3_RXD0_SER3_RXD0 */
+                                       0x1  0x4  0x2  0x0  0x1  0x0    /* ENET3_RXD1_SER3_RXD1 */
+                                       0x1  0x5  0x2  0x0  0x2  0x0    /* ENET3_RXD2_SER3_RXD2 */
+                                       0x1  0x6  0x2  0x0  0x3  0x0    /* ENET3_RXD3_SER3_RXD3 */
+                                       0x1  0x1  0x1  0x0  0x1  0x0    /* ENET3_TX_EN_SER3_RTS_B */
+                                       0x1  0x9  0x2  0x0  0x3  0x0    /* ENET3_RX_DV_SER3_CTS_B */
+                                       0x2  0x9  0x2  0x0  0x2  0x0    /* ENET3_GRXCLK */
+                                       0x2  0x19 0x1  0x0  0x2  0x0>;  /* ENET3_GTXCLK */
+                       };
+
+                       pio4: ucc_pin@04 {
+                               pio-map = <
+                       /* port  pin  dir  open_drain  assignment  has_irq */
+                                       0x2  0x1f 0x1  0x0  0x1  0x0    /* QE_MUX_MDC */
+                                       0x2  0x1e 0x3  0x0  0x2  0x0    /* QE_MUX_MDIO */
+                                       0x2  0x10 0x2  0x0  0x3  0x0    /* CLK17 */
+                                       0x1  0xc  0x1  0x0  0x2  0x0    /* ENET4_TXD0_SER4_TXD0 */
+                                       0x1  0xd  0x1  0x0  0x2  0x0    /* ENET4_TXD1_SER4_TXD1 */
+                                       0x1  0xe  0x1  0x0  0x1  0x0    /* ENET4_TXD2_SER4_TXD2 */
+                                       0x1  0xf  0x1  0x0  0x2  0x0    /* ENET4_TXD3_SER4_TXD3 */
+                                       0x1  0x12 0x2  0x0  0x2  0x0    /* ENET4_RXD0_SER4_RXD0 */
+                                       0x1  0x13 0x2  0x0  0x1  0x0    /* ENET4_RXD1_SER4_RXD1 */
+                                       0x1  0x14 0x2  0x0  0x1  0x0    /* ENET4_RXD2_SER4_RXD2 */
+                                       0x1  0x15 0x2  0x0  0x2  0x0    /* ENET4_RXD3_SER4_RXD3 */
+                                       0x1  0x10 0x1  0x0  0x2  0x0    /* ENET4_TX_EN_SER4_RTS_B */
+                                       0x1  0x18 0x2  0x0  0x3  0x0    /* ENET4_RX_DV_SER4_CTS_B */
+                                       0x2  0x11 0x2  0x0  0x2  0x0    /* ENET4_GRXCLK */
+                                       0x2  0x18 0x1  0x0  0x2  0x0>;  /* ENET4_GTXCLK */
+                       };
+               };
+       };
+
+       qe@e0080000 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               device_type = "qe";
+               compatible = "fsl,qe";
+               ranges = <0x0 0xe0080000 0x40000>;
+               reg = <0xe0080000 0x480>;
+               brg-frequency = <0>;
+               bus-frequency = <0>;
+               fsl,qe-num-riscs = <4>;
+               fsl,qe-num-snums = <46>;
+
+               qeic: interrupt-controller@80 {
+                       interrupt-controller;
+                       compatible = "fsl,qe-ic";
+                       #address-cells = <0>;
+                       #interrupt-cells = <1>;
+                       reg = <0x80 0x80>;
+                       interrupts = <46 2 46 2>; //high:30 low:30
+                       interrupt-parent = <&mpic>;
+               };
+
+               spi@4c0 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "fsl,mpc8569-qe-spi", "fsl,spi";
+                       reg = <0x4c0 0x40>;
+                       cell-index = <0>;
+                       interrupts = <2>;
+                       interrupt-parent = <&qeic>;
+                       gpios = <&qe_pio_e 30 0>;
+                       mode = "cpu-qe";
+
+                       serial-flash@0 {
+                               compatible = "stm,m25p40";
+                               reg = <0>;
+                               spi-max-frequency = <25000000>;
+                       };
+               };
+
+               spi@500 {
+                       cell-index = <1>;
+                       compatible = "fsl,spi";
+                       reg = <0x500 0x40>;
+                       interrupts = <1>;
+                       interrupt-parent = <&qeic>;
+                       mode = "cpu";
+               };
+
+               enet0: ucc@2000 {
+                       device_type = "network";
+                       compatible = "ucc_geth";
+                       cell-index = <1>;
+                       reg = <0x2000 0x200>;
+                       interrupts = <32>;
+                       interrupt-parent = <&qeic>;
+                       local-mac-address = [ 00 00 00 00 00 00 ];
+                       rx-clock-name = "none";
+                       tx-clock-name = "clk12";
+                       pio-handle = <&pio1>;
+                       phy-handle = <&qe_phy0>;
+                       phy-connection-type = "rgmii-id";
+               };
+
+               mdio@2120 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <0x2120 0x18>;
+                       compatible = "fsl,ucc-mdio";
+
+                       qe_phy0: ethernet-phy@07 {
+                               interrupt-parent = <&mpic>;
+                               interrupts = <1 1>;
+                               reg = <0x7>;
+                               device_type = "ethernet-phy";
+                       };
+                       qe_phy1: ethernet-phy@01 {
+                               interrupt-parent = <&mpic>;
+                               interrupts = <2 1>;
+                               reg = <0x1>;
+                               device_type = "ethernet-phy";
+                       };
+                       qe_phy2: ethernet-phy@02 {
+                               interrupt-parent = <&mpic>;
+                               interrupts = <3 1>;
+                               reg = <0x2>;
+                               device_type = "ethernet-phy";
+                       };
+                       qe_phy3: ethernet-phy@03 {
+                               interrupt-parent = <&mpic>;
+                               interrupts = <4 1>;
+                               reg = <0x3>;
+                               device_type = "ethernet-phy";
+                       };
+               };
+
+               enet2: ucc@2200 {
+                       device_type = "network";
+                       compatible = "ucc_geth";
+                       cell-index = <3>;
+                       reg = <0x2200 0x200>;
+                       interrupts = <34>;
+                       interrupt-parent = <&qeic>;
+                       local-mac-address = [ 00 00 00 00 00 00 ];
+                       rx-clock-name = "none";
+                       tx-clock-name = "clk12";
+                       pio-handle = <&pio3>;
+                       phy-handle = <&qe_phy2>;
+                       phy-connection-type = "rgmii-id";
+               };
+
+               enet1: ucc@3000 {
+                       device_type = "network";
+                       compatible = "ucc_geth";
+                       cell-index = <2>;
+                       reg = <0x3000 0x200>;
+                       interrupts = <33>;
+                       interrupt-parent = <&qeic>;
+                       local-mac-address = [ 00 00 00 00 00 00 ];
+                       rx-clock-name = "none";
+                       tx-clock-name = "clk17";
+                       pio-handle = <&pio2>;
+                       phy-handle = <&qe_phy1>;
+                       phy-connection-type = "rgmii-id";
+               };
+
+               enet3: ucc@3200 {
+                       device_type = "network";
+                       compatible = "ucc_geth";
+                       cell-index = <4>;
+                       reg = <0x3200 0x200>;
+                       interrupts = <35>;
+                       interrupt-parent = <&qeic>;
+                       local-mac-address = [ 00 00 00 00 00 00 ];
+                       rx-clock-name = "none";
+                       tx-clock-name = "clk17";
+                       pio-handle = <&pio4>;
+                       phy-handle = <&qe_phy3>;
+                       phy-connection-type = "rgmii-id";
+               };
+
+               muram@10000 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       compatible = "fsl,qe-muram", "fsl,cpm-muram";
+                       ranges = <0x0 0x10000 0x20000>;
+
+                       data-only@0 {
+                               compatible = "fsl,qe-muram-data",
+                                            "fsl,cpm-muram-data";
+                               reg = <0x0 0x20000>;
+                       };
+               };
+
+       };
+
+       /* PCI Express */
+       pci1: pcie@e000a000 {
+               compatible = "fsl,mpc8548-pcie";
+               device_type = "pci";
+               #interrupt-cells = <1>;
+               #size-cells = <2>;
+               #address-cells = <3>;
+               reg = <0xe000a000 0x1000>;
+               interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
+               interrupt-map = <
+                       /* IDSEL 0x0 (PEX) */
+                       00000 0x0 0x0 0x1 &mpic 0x0 0x1
+                       00000 0x0 0x0 0x2 &mpic 0x1 0x1
+                       00000 0x0 0x0 0x3 &mpic 0x2 0x1
+                       00000 0x0 0x0 0x4 &mpic 0x3 0x1>;
+
+               interrupt-parent = <&mpic>;
+               interrupts = <26 2>;
+               bus-range = <0 255>;
+               ranges = <0x2000000 0x0 0xa0000000 0xa0000000 0x0 0x10000000
+                         0x1000000 0x0 0x00000000 0xe2800000 0x0 0x00800000>;
+               clock-frequency = <33333333>;
+               pcie@0 {
+                       reg = <0x0 0x0 0x0 0x0 0x0>;
+                       #size-cells = <2>;
+                       #address-cells = <3>;
+                       device_type = "pci";
+                       ranges = <0x2000000 0x0 0xa0000000
+                                 0x2000000 0x0 0xa0000000
+                                 0x0 0x10000000
+
+                                 0x1000000 0x0 0x0
+                                 0x1000000 0x0 0x0
+                                 0x0 0x800000>;
+               };
+       };
+
+       rio0: rapidio@e00c00000 {
+               #address-cells = <2>;
+               #size-cells = <2>;
+               compatible = "fsl,mpc8569-rapidio", "fsl,rapidio-delta";
+               reg = <0xe00c0000 0x20000>;
+               ranges = <0x0 0x0 0xc0000000 0x0 0x20000000>;
+               interrupts = <48 2 /* error     */
+                             49 2 /* bell_outb */
+                             50 2 /* bell_inb  */
+                             53 2 /* msg1_tx   */
+                             54 2 /* msg1_rx   */
+                             55 2 /* msg2_tx   */
+                             56 2 /* msg2_rx   */>;
+               interrupt-parent = <&mpic>;
+       };
+};
index 6e79a4169088554deec5f5231c9db5ea88f5bc1b..cafc1285c140778990d04e3096f81bcc032f0ffd 100644 (file)
                device_type = "soc";
                compatible = "simple-bus";
                ranges = <0x0 0 0xffe00000 0x100000>;
-               reg = <0 0xffe00000 0 0x1000>;  // CCSRBAR & soc regs, remove once parse code for immrbase fixed
                bus-frequency = <0>;            // Filled out by uboot.
 
+               ecm-law@0 {
+                       compatible = "fsl,ecm-law";
+                       reg = <0x0 0x1000>;
+                       fsl,num-laws = <12>;
+               };
+
+               ecm@1000 {
+                       compatible = "fsl,mpc8572-ecm", "fsl,ecm";
+                       reg = <0x1000 0x1000>;
+                       interrupts = <17 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
                memory-controller@2000 {
                        compatible = "fsl,mpc8572-memory-controller";
                        reg = <0x2000 0x1000>;
        };
 
        pci0: pcie@ffe08000 {
-               cell-index = <0>;
                compatible = "fsl,mpc8548-pcie";
                device_type = "pci";
                #interrupt-cells = <1>;
        };
 
        pci1: pcie@ffe09000 {
-               cell-index = <1>;
                compatible = "fsl,mpc8548-pcie";
                device_type = "pci";
                #interrupt-cells = <1>;
        };
 
        pci2: pcie@ffe0a000 {
-               cell-index = <2>;
                compatible = "fsl,mpc8548-pcie";
                device_type = "pci";
                #interrupt-cells = <1>;
index dbd81a76474265134e0b2c8e3bbd30d2d05efb12..f6365db3b97dbc62eed6d565f0d21c6b886f8ebb 100644 (file)
                device_type = "soc";
                compatible = "simple-bus";
                ranges = <0x0 0xf 0xffe00000 0x100000>;
-               reg = <0xf 0xffe00000 0 0x1000>;        // CCSRBAR & soc regs, remove once parse code for immrbase fixed
                bus-frequency = <0>;            // Filled out by uboot.
 
+               ecm-law@0 {
+                       compatible = "fsl,ecm-law";
+                       reg = <0x0 0x1000>;
+                       fsl,num-laws = <12>;
+               };
+
+               ecm@1000 {
+                       compatible = "fsl,mpc8572-ecm", "fsl,ecm";
+                       reg = <0x1000 0x1000>;
+                       interrupts = <17 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
                memory-controller@2000 {
                        compatible = "fsl,mpc8572-memory-controller";
                        reg = <0x2000 0x1000>;
        };
 
        pci0: pcie@fffe08000 {
-               cell-index = <0>;
                compatible = "fsl,mpc8548-pcie";
                device_type = "pci";
                #interrupt-cells = <1>;
                #address-cells = <3>;
                reg = <0xf 0xffe08000 0 0x1000>;
                bus-range = <0 255>;
-               ranges = <0x2000000 0x0 0xc0000000 0xc 0x00000000 0x0 0x20000000
+               ranges = <0x2000000 0x0 0xe0000000 0xc 0x00000000 0x0 0x20000000
                          0x1000000 0x0 0x00000000 0xf 0xffc00000 0x0 0x00010000>;
                clock-frequency = <33333333>;
                interrupt-parent = <&mpic>;
                        #size-cells = <2>;
                        #address-cells = <3>;
                        device_type = "pci";
-                       ranges = <0x2000000 0x0 0xc0000000
-                                 0x2000000 0x0 0xc0000000
+                       ranges = <0x2000000 0x0 0xe0000000
+                                 0x2000000 0x0 0xe0000000
                                  0x0 0x20000000
 
                                  0x1000000 0x0 0x0
                                reg = <0x0 0x0 0x0 0x0 0x0>;
                                #size-cells = <2>;
                                #address-cells = <3>;
-                               ranges = <0x2000000 0x0 0xc0000000
-                                         0x2000000 0x0 0xc0000000
+                               ranges = <0x2000000 0x0 0xe0000000
+                                         0x2000000 0x0 0xe0000000
                                          0x0 0x20000000
 
                                          0x1000000 0x0 0x0
        };
 
        pci1: pcie@fffe09000 {
-               cell-index = <1>;
                compatible = "fsl,mpc8548-pcie";
                device_type = "pci";
                #interrupt-cells = <1>;
                #address-cells = <3>;
                reg = <0xf 0xffe09000 0 0x1000>;
                bus-range = <0 255>;
-               ranges = <0x2000000 0x0 0xc0000000 0xc 0x20000000 0x0 0x20000000
+               ranges = <0x2000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x20000000
                          0x1000000 0x0 0x00000000 0xf 0xffc10000 0x0 0x00010000>;
                clock-frequency = <33333333>;
                interrupt-parent = <&mpic>;
                        #size-cells = <2>;
                        #address-cells = <3>;
                        device_type = "pci";
-                       ranges = <0x2000000 0x0 0xc0000000
-                                 0x2000000 0x0 0xc0000000
+                       ranges = <0x2000000 0x0 0xe0000000
+                                 0x2000000 0x0 0xe0000000
                                  0x0 0x20000000
 
                                  0x1000000 0x0 0x0
        };
 
        pci2: pcie@fffe0a000 {
-               cell-index = <2>;
                compatible = "fsl,mpc8548-pcie";
                device_type = "pci";
                #interrupt-cells = <1>;
                #address-cells = <3>;
                reg = <0xf 0xffe0a000 0 0x1000>;
                bus-range = <0 255>;
-               ranges = <0x2000000 0x0 0xc0000000 0xc 0x40000000 0x0 0x20000000
+               ranges = <0x2000000 0x0 0xe0000000 0xc 0x40000000 0x0 0x20000000
                          0x1000000 0x0 0x00000000 0xf 0xffc20000 0x0 0x00010000>;
                clock-frequency = <33333333>;
                interrupt-parent = <&mpic>;
                        #size-cells = <2>;
                        #address-cells = <3>;
                        device_type = "pci";
-                       ranges = <0x2000000 0x0 0xc0000000
-                                 0x2000000 0x0 0xc0000000
+                       ranges = <0x2000000 0x0 0xe0000000
+                                 0x2000000 0x0 0xe0000000
                                  0x0 0x20000000
 
                                  0x1000000 0x0 0x0
index 2bc0c71896538bb06183eb93b27f5fb618bdd4d7..5bd1011fde960d083d4ab496736eaf48388e0221 100644 (file)
                device_type = "soc";
                compatible = "simple-bus";
                ranges = <0x0 0xffe00000 0x100000>;
-               reg = <0xffe00000 0x1000>;      // CCSRBAR & soc regs, remove once parse code for immrbase fixed
                bus-frequency = <0>;            // Filled out by uboot.
 
+               ecm-law@0 {
+                       compatible = "fsl,ecm-law";
+                       reg = <0x0 0x1000>;
+                       fsl,num-laws = <12>;
+               };
+
+               ecm@1000 {
+                       compatible = "fsl,mpc8572-ecm", "fsl,ecm";
+                       reg = <0x1000 0x1000>;
+                       interrupts = <17 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
                memory-controller@2000 {
                        compatible = "fsl,mpc8572-memory-controller";
                        reg = <0x2000 0x1000>;
        };
 
        pci0: pcie@ffe08000 {
-               cell-index = <0>;
                compatible = "fsl,mpc8548-pcie";
                device_type = "pci";
                #interrupt-cells = <1>;
        };
 
        pci1: pcie@ffe09000 {
-               cell-index = <1>;
                compatible = "fsl,mpc8548-pcie";
                device_type = "pci";
                #interrupt-cells = <1>;
index 159cb3a875f0b13bf6773e7f41c1df29c69e7c3d..0efc3456e2976e6ee67673aabb5232fe69589b34 100644 (file)
@@ -58,7 +58,6 @@
                device_type = "soc";
                compatible = "simple-bus";
                ranges = <0x0 0xffe00000 0x100000>;
-               reg = <0xffe00000 0x1000>;      // CCSRBAR & soc regs, remove once parse code for immrbase fixed
                bus-frequency = <0>;            // Filled out by uboot.
 
                L2: l2-cache-controller@20000 {
        };
 
        pci2: pcie@ffe0a000 {
-               cell-index = <2>;
                compatible = "fsl,mpc8548-pcie";
                device_type = "pci";
                #interrupt-cells = <1>;
index 1bd3ebe114377baf5c0c748e05f5ee4a6a31bb87..cfc2c60d1f5f4ccd9aee8484bf3d6f78db26513c 100644 (file)
                device_type = "soc";
                compatible = "fsl,mpc8610-immr", "simple-bus";
                ranges = <0x0 0xe0000000 0x00100000>;
-               reg = <0xe0000000 0x1000>;
                bus-frequency = <0>;
 
+               mcm-law@0 {
+                       compatible = "fsl,mcm-law";
+                       reg = <0x0 0x1000>;
+                       fsl,num-laws = <10>;
+               };
+
+               mcm@1000 {
+                       compatible = "fsl,mpc8610-mcm", "fsl,mcm";
+                       reg = <0x1000 0x1000>;
+                       interrupts = <17 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
                i2c@3000 {
                        #address-cells = <1>;
                        #size-cells = <0>;
        };
 
        pci0: pci@e0008000 {
-               cell-index = <0>;
                compatible = "fsl,mpc8610-pci";
                device_type = "pci";
                #interrupt-cells = <1>;
        };
 
        pci1: pcie@e000a000 {
-               cell-index = <1>;
                compatible = "fsl,mpc8641-pcie";
                device_type = "pci";
                #interrupt-cells = <1>;
index d72beb192460043e81e54e34270f6bee081011d3..848320e4d3c4060049e6d78b1449aa24a62b8606 100644 (file)
                device_type = "soc";
                compatible = "simple-bus";
                ranges = <0x00000000 0xffe00000 0x00100000>;
-               reg = <0xffe00000 0x00001000>;  // CCSRBAR
                bus-frequency = <0>;
 
+               mcm-law@0 {
+                       compatible = "fsl,mcm-law";
+                       reg = <0x0 0x1000>;
+                       fsl,num-laws = <10>;
+               };
+
+               mcm@1000 {
+                       compatible = "fsl,mpc8641-mcm", "fsl,mcm";
+                       reg = <0x1000 0x1000>;
+                       interrupts = <17 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
                i2c@3000 {
                        #address-cells = <1>;
                        #size-cells = <0>;
        };
 
        pci0: pcie@ffe08000 {
-               cell-index = <0>;
                compatible = "fsl,mpc8641-pcie";
                device_type = "pci";
                #interrupt-cells = <1>;
        };
 
        pci1: pcie@ffe09000 {
-               cell-index = <1>;
                compatible = "fsl,mpc8641-pcie";
                device_type = "pci";
                #interrupt-cells = <1>;
diff --git a/arch/powerpc/boot/dts/mpc8641_hpcn_36b.dts b/arch/powerpc/boot/dts/mpc8641_hpcn_36b.dts
new file mode 100644 (file)
index 0000000..8be8e70
--- /dev/null
@@ -0,0 +1,609 @@
+/*
+ * MPC8641 HPCN Device Tree Source
+ *
+ * Copyright 2008-2009 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.
+ */
+
+/dts-v1/;
+
+/ {
+       model = "MPC8641HPCN";
+       compatible = "fsl,mpc8641hpcn";
+       #address-cells = <2>;
+       #size-cells = <2>;
+
+       aliases {
+               ethernet0 = &enet0;
+               ethernet1 = &enet1;
+               ethernet2 = &enet2;
+               ethernet3 = &enet3;
+               serial0 = &serial0;
+               serial1 = &serial1;
+               pci0 = &pci0;
+               pci1 = &pci1;
+       };
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               PowerPC,8641@0 {
+                       device_type = "cpu";
+                       reg = <0>;
+                       d-cache-line-size = <32>;       // 32 bytes
+                       i-cache-line-size = <32>;       // 32 bytes
+                       d-cache-size = <32768>;         // L1, 32K
+                       i-cache-size = <32768>;         // L1, 32K
+                       timebase-frequency = <0>;       // 33 MHz, from uboot
+                       bus-frequency = <0>;            // From uboot
+                       clock-frequency = <0>;          // From uboot
+               };
+               PowerPC,8641@1 {
+                       device_type = "cpu";
+                       reg = <1>;
+                       d-cache-line-size = <32>;       // 32 bytes
+                       i-cache-line-size = <32>;       // 32 bytes
+                       d-cache-size = <32768>;         // L1, 32K
+                       i-cache-size = <32768>;         // L1, 32K
+                       timebase-frequency = <0>;       // 33 MHz, from uboot
+                       bus-frequency = <0>;            // From uboot
+                       clock-frequency = <0>;          // From uboot
+               };
+       };
+
+       memory {
+               device_type = "memory";
+               reg = <0x0 0x00000000 0x0 0x40000000>;  // 1G at 0x0
+       };
+
+       localbus@fffe05000 {
+               #address-cells = <2>;
+               #size-cells = <1>;
+               compatible = "fsl,mpc8641-localbus", "simple-bus";
+               reg = <0x0f 0xffe05000 0x0 0x1000>;
+               interrupts = <19 2>;
+               interrupt-parent = <&mpic>;
+
+               ranges = <0 0 0xf 0xef800000 0x00800000
+                         2 0 0xf 0xffdf8000 0x00008000
+                         3 0 0xf 0xffdf0000 0x00008000>;
+
+               flash@0,0 {
+                       compatible = "cfi-flash";
+                       reg = <0 0 0x00800000>;
+                       bank-width = <2>;
+                       device-width = <2>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       partition@0 {
+                               label = "kernel";
+                               reg = <0x00000000 0x00300000>;
+                       };
+                       partition@300000 {
+                               label = "firmware b";
+                               reg = <0x00300000 0x00100000>;
+                               read-only;
+                       };
+                       partition@400000 {
+                               label = "fs";
+                               reg = <0x00400000 0x00300000>;
+                       };
+                       partition@700000 {
+                               label = "firmware a";
+                               reg = <0x00700000 0x00100000>;
+                               read-only;
+                       };
+               };
+       };
+
+       soc8641@fffe00000 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               device_type = "soc";
+               compatible = "simple-bus";
+               ranges = <0x00000000 0x0f 0xffe00000 0x00100000>;
+               bus-frequency = <0>;
+
+               mcm-law@0 {
+                       compatible = "fsl,mcm-law";
+                       reg = <0x0 0x1000>;
+                       fsl,num-laws = <10>;
+               };
+
+               mcm@1000 {
+                       compatible = "fsl,mpc8641-mcm", "fsl,mcm";
+                       reg = <0x1000 0x1000>;
+                       interrupts = <17 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
+               i2c@3000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       cell-index = <0>;
+                       compatible = "fsl-i2c";
+                       reg = <0x3000 0x100>;
+                       interrupts = <43 2>;
+                       interrupt-parent = <&mpic>;
+                       dfsrr;
+               };
+
+               i2c@3100 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       cell-index = <1>;
+                       compatible = "fsl-i2c";
+                       reg = <0x3100 0x100>;
+                       interrupts = <43 2>;
+                       interrupt-parent = <&mpic>;
+                       dfsrr;
+               };
+
+               dma@21300 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       compatible = "fsl,mpc8641-dma", "fsl,eloplus-dma";
+                       reg = <0x21300 0x4>;
+                       ranges = <0x0 0x21100 0x200>;
+                       cell-index = <0>;
+                       dma-channel@0 {
+                               compatible = "fsl,mpc8641-dma-channel",
+                                               "fsl,eloplus-dma-channel";
+                               reg = <0x0 0x80>;
+                               cell-index = <0>;
+                               interrupt-parent = <&mpic>;
+                               interrupts = <20 2>;
+                       };
+                       dma-channel@80 {
+                               compatible = "fsl,mpc8641-dma-channel",
+                                               "fsl,eloplus-dma-channel";
+                               reg = <0x80 0x80>;
+                               cell-index = <1>;
+                               interrupt-parent = <&mpic>;
+                               interrupts = <21 2>;
+                       };
+                       dma-channel@100 {
+                               compatible = "fsl,mpc8641-dma-channel",
+                                               "fsl,eloplus-dma-channel";
+                               reg = <0x100 0x80>;
+                               cell-index = <2>;
+                               interrupt-parent = <&mpic>;
+                               interrupts = <22 2>;
+                       };
+                       dma-channel@180 {
+                               compatible = "fsl,mpc8641-dma-channel",
+                                               "fsl,eloplus-dma-channel";
+                               reg = <0x180 0x80>;
+                               cell-index = <3>;
+                               interrupt-parent = <&mpic>;
+                               interrupts = <23 2>;
+                       };
+               };
+
+               enet0: ethernet@24000 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       cell-index = <0>;
+                       device_type = "network";
+                       model = "TSEC";
+                       compatible = "gianfar";
+                       reg = <0x24000 0x1000>;
+                       ranges = <0x0 0x24000 0x1000>;
+                       local-mac-address = [ 00 00 00 00 00 00 ];
+                       interrupts = <29 2 30 2 34 2>;
+                       interrupt-parent = <&mpic>;
+                       tbi-handle = <&tbi0>;
+                       phy-handle = <&phy0>;
+                       phy-connection-type = "rgmii-id";
+
+                       mdio@520 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "fsl,gianfar-mdio";
+                               reg = <0x520 0x20>;
+
+                               phy0: ethernet-phy@0 {
+                                       interrupt-parent = <&mpic>;
+                                       interrupts = <10 1>;
+                                       reg = <0>;
+                                       device_type = "ethernet-phy";
+                               };
+                               phy1: ethernet-phy@1 {
+                                       interrupt-parent = <&mpic>;
+                                       interrupts = <10 1>;
+                                       reg = <1>;
+                                       device_type = "ethernet-phy";
+                               };
+                               phy2: ethernet-phy@2 {
+                                       interrupt-parent = <&mpic>;
+                                       interrupts = <10 1>;
+                                       reg = <2>;
+                                       device_type = "ethernet-phy";
+                               };
+                               phy3: ethernet-phy@3 {
+                                       interrupt-parent = <&mpic>;
+                                       interrupts = <10 1>;
+                                       reg = <3>;
+                                       device_type = "ethernet-phy";
+                               };
+                               tbi0: tbi-phy@11 {
+                                       reg = <0x11>;
+                                       device_type = "tbi-phy";
+                               };
+                       };
+               };
+
+               enet1: ethernet@25000 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       cell-index = <1>;
+                       device_type = "network";
+                       model = "TSEC";
+                       compatible = "gianfar";
+                       reg = <0x25000 0x1000>;
+                       ranges = <0x0 0x25000 0x1000>;
+                       local-mac-address = [ 00 00 00 00 00 00 ];
+                       interrupts = <35 2 36 2 40 2>;
+                       interrupt-parent = <&mpic>;
+                       tbi-handle = <&tbi1>;
+                       phy-handle = <&phy1>;
+                       phy-connection-type = "rgmii-id";
+
+                       mdio@520 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "fsl,gianfar-tbi";
+                               reg = <0x520 0x20>;
+
+                               tbi1: tbi-phy@11 {
+                                       reg = <0x11>;
+                                       device_type = "tbi-phy";
+                               };
+                       };
+               };
+
+               enet2: ethernet@26000 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       cell-index = <2>;
+                       device_type = "network";
+                       model = "TSEC";
+                       compatible = "gianfar";
+                       reg = <0x26000 0x1000>;
+                       ranges = <0x0 0x26000 0x1000>;
+                       local-mac-address = [ 00 00 00 00 00 00 ];
+                       interrupts = <31 2 32 2 33 2>;
+                       interrupt-parent = <&mpic>;
+                       tbi-handle = <&tbi2>;
+                       phy-handle = <&phy2>;
+                       phy-connection-type = "rgmii-id";
+
+                       mdio@520 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "fsl,gianfar-tbi";
+                               reg = <0x520 0x20>;
+
+                               tbi2: tbi-phy@11 {
+                                       reg = <0x11>;
+                                       device_type = "tbi-phy";
+                               };
+                       };
+               };
+
+               enet3: ethernet@27000 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       cell-index = <3>;
+                       device_type = "network";
+                       model = "TSEC";
+                       compatible = "gianfar";
+                       reg = <0x27000 0x1000>;
+                       ranges = <0x0 0x27000 0x1000>;
+                       local-mac-address = [ 00 00 00 00 00 00 ];
+                       interrupts = <37 2 38 2 39 2>;
+                       interrupt-parent = <&mpic>;
+                       tbi-handle = <&tbi3>;
+                       phy-handle = <&phy3>;
+                       phy-connection-type = "rgmii-id";
+
+                       mdio@520 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "fsl,gianfar-tbi";
+                               reg = <0x520 0x20>;
+
+                               tbi3: tbi-phy@11 {
+                                       reg = <0x11>;
+                                       device_type = "tbi-phy";
+                               };
+                       };
+               };
+
+               serial0: serial@4500 {
+                       cell-index = <0>;
+                       device_type = "serial";
+                       compatible = "ns16550";
+                       reg = <0x4500 0x100>;
+                       clock-frequency = <0>;
+                       interrupts = <42 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
+               serial1: serial@4600 {
+                       cell-index = <1>;
+                       device_type = "serial";
+                       compatible = "ns16550";
+                       reg = <0x4600 0x100>;
+                       clock-frequency = <0>;
+                       interrupts = <28 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
+               mpic: pic@40000 {
+                       interrupt-controller;
+                       #address-cells = <0>;
+                       #interrupt-cells = <2>;
+                       reg = <0x40000 0x40000>;
+                       compatible = "chrp,open-pic";
+                       device_type = "open-pic";
+               };
+
+               global-utilities@e0000 {
+                       compatible = "fsl,mpc8641-guts";
+                       reg = <0xe0000 0x1000>;
+                       fsl,has-rstcr;
+               };
+       };
+
+       pci0: pcie@fffe08000 {
+               cell-index = <0>;
+               compatible = "fsl,mpc8641-pcie";
+               device_type = "pci";
+               #interrupt-cells = <1>;
+               #size-cells = <2>;
+               #address-cells = <3>;
+               reg = <0x0f 0xffe08000 0x0 0x1000>;
+               bus-range = <0x0 0xff>;
+               ranges = <0x02000000 0x0 0xe0000000 0x0c 0x00000000 0x0 0x20000000
+                         0x01000000 0x0 0x00000000 0x0f 0xffc00000 0x0 0x00010000>;
+               clock-frequency = <33333333>;
+               interrupt-parent = <&mpic>;
+               interrupts = <24 2>;
+               interrupt-map-mask = <0xff00 0 0 7>;
+               interrupt-map = <
+                       /* IDSEL 0x11 func 0 - PCI slot 1 */
+                       0x8800 0 0 1 &mpic 2 1
+                       0x8800 0 0 2 &mpic 3 1
+                       0x8800 0 0 3 &mpic 4 1
+                       0x8800 0 0 4 &mpic 1 1
+
+                       /* IDSEL 0x11 func 1 - PCI slot 1 */
+                       0x8900 0 0 1 &mpic 2 1
+                       0x8900 0 0 2 &mpic 3 1
+                       0x8900 0 0 3 &mpic 4 1
+                       0x8900 0 0 4 &mpic 1 1
+
+                       /* IDSEL 0x11 func 2 - PCI slot 1 */
+                       0x8a00 0 0 1 &mpic 2 1
+                       0x8a00 0 0 2 &mpic 3 1
+                       0x8a00 0 0 3 &mpic 4 1
+                       0x8a00 0 0 4 &mpic 1 1
+
+                       /* IDSEL 0x11 func 3 - PCI slot 1 */
+                       0x8b00 0 0 1 &mpic 2 1
+                       0x8b00 0 0 2 &mpic 3 1
+                       0x8b00 0 0 3 &mpic 4 1
+                       0x8b00 0 0 4 &mpic 1 1
+
+                       /* IDSEL 0x11 func 4 - PCI slot 1 */
+                       0x8c00 0 0 1 &mpic 2 1
+                       0x8c00 0 0 2 &mpic 3 1
+                       0x8c00 0 0 3 &mpic 4 1
+                       0x8c00 0 0 4 &mpic 1 1
+
+                       /* IDSEL 0x11 func 5 - PCI slot 1 */
+                       0x8d00 0 0 1 &mpic 2 1
+                       0x8d00 0 0 2 &mpic 3 1
+                       0x8d00 0 0 3 &mpic 4 1
+                       0x8d00 0 0 4 &mpic 1 1
+
+                       /* IDSEL 0x11 func 6 - PCI slot 1 */
+                       0x8e00 0 0 1 &mpic 2 1
+                       0x8e00 0 0 2 &mpic 3 1
+                       0x8e00 0 0 3 &mpic 4 1
+                       0x8e00 0 0 4 &mpic 1 1
+
+                       /* IDSEL 0x11 func 7 - PCI slot 1 */
+                       0x8f00 0 0 1 &mpic 2 1
+                       0x8f00 0 0 2 &mpic 3 1
+                       0x8f00 0 0 3 &mpic 4 1
+                       0x8f00 0 0 4 &mpic 1 1
+
+                       /* IDSEL 0x12 func 0 - PCI slot 2 */
+                       0x9000 0 0 1 &mpic 3 1
+                       0x9000 0 0 2 &mpic 4 1
+                       0x9000 0 0 3 &mpic 1 1
+                       0x9000 0 0 4 &mpic 2 1
+
+                       /* IDSEL 0x12 func 1 - PCI slot 2 */
+                       0x9100 0 0 1 &mpic 3 1
+                       0x9100 0 0 2 &mpic 4 1
+                       0x9100 0 0 3 &mpic 1 1
+                       0x9100 0 0 4 &mpic 2 1
+
+                       /* IDSEL 0x12 func 2 - PCI slot 2 */
+                       0x9200 0 0 1 &mpic 3 1
+                       0x9200 0 0 2 &mpic 4 1
+                       0x9200 0 0 3 &mpic 1 1
+                       0x9200 0 0 4 &mpic 2 1
+
+                       /* IDSEL 0x12 func 3 - PCI slot 2 */
+                       0x9300 0 0 1 &mpic 3 1
+                       0x9300 0 0 2 &mpic 4 1
+                       0x9300 0 0 3 &mpic 1 1
+                       0x9300 0 0 4 &mpic 2 1
+
+                       /* IDSEL 0x12 func 4 - PCI slot 2 */
+                       0x9400 0 0 1 &mpic 3 1
+                       0x9400 0 0 2 &mpic 4 1
+                       0x9400 0 0 3 &mpic 1 1
+                       0x9400 0 0 4 &mpic 2 1
+
+                       /* IDSEL 0x12 func 5 - PCI slot 2 */
+                       0x9500 0 0 1 &mpic 3 1
+                       0x9500 0 0 2 &mpic 4 1
+                       0x9500 0 0 3 &mpic 1 1
+                       0x9500 0 0 4 &mpic 2 1
+
+                       /* IDSEL 0x12 func 6 - PCI slot 2 */
+                       0x9600 0 0 1 &mpic 3 1
+                       0x9600 0 0 2 &mpic 4 1
+                       0x9600 0 0 3 &mpic 1 1
+                       0x9600 0 0 4 &mpic 2 1
+
+                       /* IDSEL 0x12 func 7 - PCI slot 2 */
+                       0x9700 0 0 1 &mpic 3 1
+                       0x9700 0 0 2 &mpic 4 1
+                       0x9700 0 0 3 &mpic 1 1
+                       0x9700 0 0 4 &mpic 2 1
+
+                       // IDSEL 0x1c  USB
+                       0xe000 0 0 1 &i8259 12 2
+                       0xe100 0 0 2 &i8259 9 2
+                       0xe200 0 0 3 &i8259 10 2
+                       0xe300 0 0 4 &i8259 11 2
+
+                       // IDSEL 0x1d  Audio
+                       0xe800 0 0 1 &i8259 6 2
+
+                       // IDSEL 0x1e Legacy
+                       0xf000 0 0 1 &i8259 7 2
+                       0xf100 0 0 1 &i8259 7 2
+
+                       // IDSEL 0x1f IDE/SATA
+                       0xf800 0 0 1 &i8259 14 2
+                       0xf900 0 0 1 &i8259 5 2
+                       >;
+
+               pcie@0 {
+                       reg = <0 0 0 0 0>;
+                       #size-cells = <2>;
+                       #address-cells = <3>;
+                       device_type = "pci";
+                       ranges = <0x02000000 0x0 0xe0000000
+                                 0x02000000 0x0 0xe0000000
+                                 0x0 0x20000000
+
+                                 0x01000000 0x0 0x00000000
+                                 0x01000000 0x0 0x00000000
+                                 0x0 0x00010000>;
+                       uli1575@0 {
+                               reg = <0 0 0 0 0>;
+                               #size-cells = <2>;
+                               #address-cells = <3>;
+                               ranges = <0x02000000 0x0 0xe0000000
+                                         0x02000000 0x0 0xe0000000
+                                         0x0 0x20000000
+                                         0x01000000 0x0 0x00000000
+                                         0x01000000 0x0 0x00000000
+                                         0x0 0x00010000>;
+                               isa@1e {
+                                       device_type = "isa";
+                                       #interrupt-cells = <2>;
+                                       #size-cells = <1>;
+                                       #address-cells = <2>;
+                                       reg = <0xf000 0 0 0 0>;
+                                       ranges = <1 0 0x01000000 0 0
+                                                 0x00001000>;
+                                       interrupt-parent = <&i8259>;
+
+                                       i8259: interrupt-controller@20 {
+                                               reg = <1 0x20 2
+                                                      1 0xa0 2
+                                                      1 0x4d0 2>;
+                                               interrupt-controller;
+                                               device_type = "interrupt-controller";
+                                               #address-cells = <0>;
+                                               #interrupt-cells = <2>;
+                                               compatible = "chrp,iic";
+                                               interrupts = <9 2>;
+                                               interrupt-parent = <&mpic>;
+                                       };
+
+                                       i8042@60 {
+                                               #size-cells = <0>;
+                                               #address-cells = <1>;
+                                               reg = <1 0x60 1 1 0x64 1>;
+                                               interrupts = <1 3 12 3>;
+                                               interrupt-parent =
+                                                       <&i8259>;
+
+                                               keyboard@0 {
+                                                       reg = <0>;
+                                                       compatible = "pnpPNP,303";
+                                               };
+
+                                               mouse@1 {
+                                                       reg = <1>;
+                                                       compatible = "pnpPNP,f03";
+                                               };
+                                       };
+
+                                       rtc@70 {
+                                               compatible =
+                                                       "pnpPNP,b00";
+                                               reg = <1 0x70 2>;
+                                       };
+
+                                       gpio@400 {
+                                               reg = <1 0x400 0x80>;
+                                       };
+                               };
+                       };
+               };
+
+       };
+
+       pci1: pcie@fffe09000 {
+               cell-index = <1>;
+               compatible = "fsl,mpc8641-pcie";
+               device_type = "pci";
+               #interrupt-cells = <1>;
+               #size-cells = <2>;
+               #address-cells = <3>;
+               reg = <0x0f 0xffe09000 0x0 0x1000>;
+               bus-range = <0x0 0xff>;
+               ranges = <0x02000000 0x0 0xe0000000 0x0c 0x20000000 0x0 0x20000000
+                         0x01000000 0x0 0x00000000 0x0f 0xffc10000 0x0 0x00010000>;
+               clock-frequency = <33333333>;
+               interrupt-parent = <&mpic>;
+               interrupts = <25 2>;
+               interrupt-map-mask = <0xf800 0 0 7>;
+               interrupt-map = <
+                       /* IDSEL 0x0 */
+                       0x0000 0 0 1 &mpic 4 1
+                       0x0000 0 0 2 &mpic 5 1
+                       0x0000 0 0 3 &mpic 6 1
+                       0x0000 0 0 4 &mpic 7 1
+                       >;
+               pcie@0 {
+                       reg = <0 0 0 0 0>;
+                       #size-cells = <2>;
+                       #address-cells = <3>;
+                       device_type = "pci";
+                       ranges = <0x02000000 0x0 0xe0000000
+                                 0x02000000 0x0 0xe0000000
+                                 0x0 0x20000000
+
+                                 0x01000000 0x0 0x00000000
+                                 0x01000000 0x0 0x00000000
+                                 0x0 0x00010000>;
+               };
+       };
+};
diff --git a/arch/powerpc/boot/dts/p2020ds.dts b/arch/powerpc/boot/dts/p2020ds.dts
new file mode 100644 (file)
index 0000000..1101914
--- /dev/null
@@ -0,0 +1,704 @@
+/*
+ * P2020 DS Device Tree Source
+ *
+ * Copyright 2009 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.
+ */
+
+/dts-v1/;
+/ {
+       model = "fsl,P2020";
+       compatible = "fsl,P2020DS";
+       #address-cells = <2>;
+       #size-cells = <2>;
+
+       aliases {
+               ethernet0 = &enet0;
+               ethernet1 = &enet1;
+               ethernet2 = &enet2;
+               serial0 = &serial0;
+               serial1 = &serial1;
+               pci0 = &pci0;
+               pci1 = &pci1;
+               pci2 = &pci2;
+       };
+
+       cpus {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               PowerPC,P2020@0 {
+                       device_type = "cpu";
+                       reg = <0x0>;
+                       next-level-cache = <&L2>;
+               };
+
+               PowerPC,P2020@1 {
+                       device_type = "cpu";
+                       reg = <0x1>;
+                       next-level-cache = <&L2>;
+               };
+       };
+
+       memory {
+               device_type = "memory";
+       };
+
+       localbus@ffe05000 {
+               #address-cells = <2>;
+               #size-cells = <1>;
+               compatible = "fsl,elbc", "simple-bus";
+               reg = <0 0xffe05000 0 0x1000>;
+               interrupts = <19 2>;
+               interrupt-parent = <&mpic>;
+
+               ranges = <0x0 0x0 0x0 0xe8000000 0x08000000
+                         0x1 0x0 0x0 0xe0000000 0x08000000
+                         0x2 0x0 0x0 0xffa00000 0x00040000
+                         0x3 0x0 0x0 0xffdf0000 0x00008000
+                         0x4 0x0 0x0 0xffa40000 0x00040000
+                         0x5 0x0 0x0 0xffa80000 0x00040000
+                         0x6 0x0 0x0 0xffac0000 0x00040000>;
+
+               nor@0,0 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       compatible = "cfi-flash";
+                       reg = <0x0 0x0 0x8000000>;
+                       bank-width = <2>;
+                       device-width = <1>;
+
+                       ramdisk@0 {
+                               reg = <0x0 0x03000000>;
+                               read-only;
+                       };
+
+                       diagnostic@3000000 {
+                               reg = <0x03000000 0x00e00000>;
+                               read-only;
+                       };
+
+                       dink@3e00000 {
+                               reg = <0x03e00000 0x00200000>;
+                               read-only;
+                       };
+
+                       kernel@4000000 {
+                               reg = <0x04000000 0x00400000>;
+                               read-only;
+                       };
+
+                       jffs2@4400000 {
+                               reg = <0x04400000 0x03b00000>;
+                       };
+
+                       dtb@7f00000 {
+                               reg = <0x07f00000 0x00080000>;
+                               read-only;
+                       };
+
+                       u-boot@7f80000 {
+                               reg = <0x07f80000 0x00080000>;
+                               read-only;
+                       };
+               };
+
+               nand@2,0 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       compatible = "fsl,elbc-fcm-nand";
+                       reg = <0x2 0x0 0x40000>;
+
+                       u-boot@0 {
+                               reg = <0x0 0x02000000>;
+                               read-only;
+                       };
+
+                       jffs2@2000000 {
+                               reg = <0x02000000 0x10000000>;
+                       };
+
+                       ramdisk@12000000 {
+                               reg = <0x12000000 0x08000000>;
+                               read-only;
+                       };
+
+                       kernel@1a000000 {
+                               reg = <0x1a000000 0x04000000>;
+                       };
+
+                       dtb@1e000000 {
+                               reg = <0x1e000000 0x01000000>;
+                               read-only;
+                       };
+
+                       empty@1f000000 {
+                               reg = <0x1f000000 0x21000000>;
+                       };
+               };
+
+               nand@4,0 {
+                       compatible = "fsl,elbc-fcm-nand";
+                       reg = <0x4 0x0 0x40000>;
+               };
+
+               nand@5,0 {
+                       compatible = "fsl,elbc-fcm-nand";
+                       reg = <0x5 0x0 0x40000>;
+               };
+
+               nand@6,0 {
+                       compatible = "fsl,elbc-fcm-nand";
+                       reg = <0x6 0x0 0x40000>;
+               };
+       };
+
+       soc@ffe00000 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               device_type = "soc";
+               compatible = "fsl,p2020-immr", "simple-bus";
+               ranges = <0x0 0 0xffe00000 0x100000>;
+               bus-frequency = <0>;            // Filled out by uboot.
+
+               ecm-law@0 {
+                       compatible = "fsl,ecm-law";
+                       reg = <0x0 0x1000>;
+                       fsl,num-laws = <12>;
+               };
+
+               ecm@1000 {
+                       compatible = "fsl,p2020-ecm", "fsl,ecm";
+                       reg = <0x1000 0x1000>;
+                       interrupts = <17 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
+               memory-controller@2000 {
+                       compatible = "fsl,p2020-memory-controller";
+                       reg = <0x2000 0x1000>;
+                       interrupt-parent = <&mpic>;
+                       interrupts = <18 2>;
+               };
+
+               i2c@3000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       cell-index = <0>;
+                       compatible = "fsl-i2c";
+                       reg = <0x3000 0x100>;
+                       interrupts = <43 2>;
+                       interrupt-parent = <&mpic>;
+                       dfsrr;
+               };
+
+               i2c@3100 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       cell-index = <1>;
+                       compatible = "fsl-i2c";
+                       reg = <0x3100 0x100>;
+                       interrupts = <43 2>;
+                       interrupt-parent = <&mpic>;
+                       dfsrr;
+               };
+
+               serial0: serial@4500 {
+                       cell-index = <0>;
+                       device_type = "serial";
+                       compatible = "ns16550";
+                       reg = <0x4500 0x100>;
+                       clock-frequency = <0>;
+                       interrupts = <42 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
+               serial1: serial@4600 {
+                       cell-index = <1>;
+                       device_type = "serial";
+                       compatible = "ns16550";
+                       reg = <0x4600 0x100>;
+                       clock-frequency = <0>;
+                       interrupts = <42 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
+               spi@7000 {
+                       compatible = "fsl,espi";
+                       reg = <0x7000 0x1000>;
+                       interrupts = <59 0x2>;
+                       interrupt-parent = <&mpic>;
+               };
+
+               dma@c300 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       compatible = "fsl,eloplus-dma";
+                       reg = <0xc300 0x4>;
+                       ranges = <0x0 0xc100 0x200>;
+                       cell-index = <1>;
+                       dma-channel@0 {
+                               compatible = "fsl,eloplus-dma-channel";
+                               reg = <0x0 0x80>;
+                               cell-index = <0>;
+                               interrupt-parent = <&mpic>;
+                               interrupts = <76 2>;
+                       };
+                       dma-channel@80 {
+                               compatible = "fsl,eloplus-dma-channel";
+                               reg = <0x80 0x80>;
+                               cell-index = <1>;
+                               interrupt-parent = <&mpic>;
+                               interrupts = <77 2>;
+                       };
+                       dma-channel@100 {
+                               compatible = "fsl,eloplus-dma-channel";
+                               reg = <0x100 0x80>;
+                               cell-index = <2>;
+                               interrupt-parent = <&mpic>;
+                               interrupts = <78 2>;
+                       };
+                       dma-channel@180 {
+                               compatible = "fsl,eloplus-dma-channel";
+                               reg = <0x180 0x80>;
+                               cell-index = <3>;
+                               interrupt-parent = <&mpic>;
+                               interrupts = <79 2>;
+                       };
+               };
+
+               gpio: gpio-controller@f000 {
+                       #gpio-cells = <2>;
+                       compatible = "fsl,mpc8572-gpio";
+                       reg = <0xf000 0x100>;
+                       interrupts = <47 0x2>;
+                       interrupt-parent = <&mpic>;
+                       gpio-controller;
+               };
+
+               L2: l2-cache-controller@20000 {
+                       compatible = "fsl,p2020-l2-cache-controller";
+                       reg = <0x20000 0x1000>;
+                       cache-line-size = <32>; // 32 bytes
+                       cache-size = <0x80000>; // L2, 512k
+                       interrupt-parent = <&mpic>;
+                       interrupts = <16 2>;
+               };
+
+               dma@21300 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       compatible = "fsl,eloplus-dma";
+                       reg = <0x21300 0x4>;
+                       ranges = <0x0 0x21100 0x200>;
+                       cell-index = <0>;
+                       dma-channel@0 {
+                               compatible = "fsl,eloplus-dma-channel";
+                               reg = <0x0 0x80>;
+                               cell-index = <0>;
+                               interrupt-parent = <&mpic>;
+                               interrupts = <20 2>;
+                       };
+                       dma-channel@80 {
+                               compatible = "fsl,eloplus-dma-channel";
+                               reg = <0x80 0x80>;
+                               cell-index = <1>;
+                               interrupt-parent = <&mpic>;
+                               interrupts = <21 2>;
+                       };
+                       dma-channel@100 {
+                               compatible = "fsl,eloplus-dma-channel";
+                               reg = <0x100 0x80>;
+                               cell-index = <2>;
+                               interrupt-parent = <&mpic>;
+                               interrupts = <22 2>;
+                       };
+                       dma-channel@180 {
+                               compatible = "fsl,eloplus-dma-channel";
+                               reg = <0x180 0x80>;
+                               cell-index = <3>;
+                               interrupt-parent = <&mpic>;
+                               interrupts = <23 2>;
+                       };
+               };
+
+               usb@22000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "fsl-usb2-dr";
+                       reg = <0x22000 0x1000>;
+                       interrupt-parent = <&mpic>;
+                       interrupts = <28 0x2>;
+                       phy_type = "ulpi";
+               };
+
+               enet0: ethernet@24000 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       cell-index = <0>;
+                       device_type = "network";
+                       model = "eTSEC";
+                       compatible = "gianfar";
+                       reg = <0x24000 0x1000>;
+                       ranges = <0x0 0x24000 0x1000>;
+                       local-mac-address = [ 00 00 00 00 00 00 ];
+                       interrupts = <29 2 30 2 34 2>;
+                       interrupt-parent = <&mpic>;
+                       tbi-handle = <&tbi0>;
+                       phy-handle = <&phy0>;
+                       phy-connection-type = "rgmii-id";
+
+                       mdio@520 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "fsl,gianfar-mdio";
+                               reg = <0x520 0x20>;
+
+                               phy0: ethernet-phy@0 {
+                                       interrupt-parent = <&mpic>;
+                                       interrupts = <3 1>;
+                                       reg = <0x0>;
+                               };
+                               phy1: ethernet-phy@1 {
+                                       interrupt-parent = <&mpic>;
+                                       interrupts = <3 1>;
+                                       reg = <0x1>;
+                               };
+                               phy2: ethernet-phy@2 {
+                                       interrupt-parent = <&mpic>;
+                                       interrupts = <3 1>;
+                                       reg = <0x2>;
+                               };
+                               tbi0: tbi-phy@11 {
+                                       reg = <0x11>;
+                                       device_type = "tbi-phy";
+                               };
+                       };
+               };
+
+               enet1: ethernet@25000 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       cell-index = <1>;
+                       device_type = "network";
+                       model = "eTSEC";
+                       compatible = "gianfar";
+                       reg = <0x25000 0x1000>;
+                       ranges = <0x0 0x25000 0x1000>;
+                       local-mac-address = [ 00 00 00 00 00 00 ];
+                       interrupts = <35 2 36 2 40 2>;
+                       interrupt-parent = <&mpic>;
+                       tbi-handle = <&tbi1>;
+                       phy-handle = <&phy1>;
+                       phy-connection-type = "rgmii-id";
+
+                       mdio@520 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "fsl,gianfar-tbi";
+                               reg = <0x520 0x20>;
+
+                               tbi1: tbi-phy@11 {
+                                       reg = <0x11>;
+                                       device_type = "tbi-phy";
+                               };
+                       };
+               };
+
+               enet2: ethernet@26000 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       cell-index = <2>;
+                       device_type = "network";
+                       model = "eTSEC";
+                       compatible = "gianfar";
+                       reg = <0x26000 0x1000>;
+                       ranges = <0x0 0x26000 0x1000>;
+                       local-mac-address = [ 00 00 00 00 00 00 ];
+                       interrupts = <31 2 32 2 33 2>;
+                       interrupt-parent = <&mpic>;
+                       tbi-handle = <&tbi2>;
+                       phy-handle = <&phy2>;
+                       phy-connection-type = "rgmii-id";
+
+                       mdio@520 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "fsl,gianfar-tbi";
+                               reg = <0x520 0x20>;
+
+                               tbi2: tbi-phy@11 {
+                                       reg = <0x11>;
+                                       device_type = "tbi-phy";
+                               };
+                       };
+               };
+
+               sdhci@2e000 {
+                       compatible = "fsl,p2020-esdhc", "fsl,esdhc";
+                       reg = <0x2e000 0x1000>;
+                       interrupts = <72 0x2>;
+                       interrupt-parent = <&mpic>;
+                       /* Filled in by U-Boot */
+                       clock-frequency = <0>;
+               };
+
+               crypto@30000 {
+                       compatible = "fsl,sec3.1", "fsl,sec3.0", "fsl,sec2.4",
+                                    "fsl,sec2.2", "fsl,sec2.1", "fsl,sec2.0";
+                       reg = <0x30000 0x10000>;
+                       interrupts = <45 2 58 2>;
+                       interrupt-parent = <&mpic>;
+                       fsl,num-channels = <4>;
+                       fsl,channel-fifo-len = <24>;
+                       fsl,exec-units-mask = <0xbfe>;
+                       fsl,descriptor-types-mask = <0x3ab0ebf>;
+               };
+
+               mpic: pic@40000 {
+                       interrupt-controller;
+                       #address-cells = <0>;
+                       #interrupt-cells = <2>;
+                       reg = <0x40000 0x40000>;
+                       compatible = "chrp,open-pic";
+                       device_type = "open-pic";
+               };
+
+               msi@41600 {
+                       compatible = "fsl,mpic-msi";
+                       reg = <0x41600 0x80>;
+                       msi-available-ranges = <0 0x100>;
+                       interrupts = <
+                               0xe0 0
+                               0xe1 0
+                               0xe2 0
+                               0xe3 0
+                               0xe4 0
+                               0xe5 0
+                               0xe6 0
+                               0xe7 0>;
+                       interrupt-parent = <&mpic>;
+               };
+
+               global-utilities@e0000 {        //global utilities block
+                       compatible = "fsl,p2020-guts";
+                       reg = <0xe0000 0x1000>;
+                       fsl,has-rstcr;
+               };
+       };
+
+       pci0: pcie@ffe08000 {
+               compatible = "fsl,mpc8548-pcie";
+               device_type = "pci";
+               #interrupt-cells = <1>;
+               #size-cells = <2>;
+               #address-cells = <3>;
+               reg = <0 0xffe08000 0 0x1000>;
+               bus-range = <0 255>;
+               ranges = <0x2000000 0x0 0x80000000 0 0x80000000 0x0 0x20000000
+                         0x1000000 0x0 0x00000000 0 0xffc00000 0x0 0x10000>;
+               clock-frequency = <33333333>;
+               interrupt-parent = <&mpic>;
+               interrupts = <24 2>;
+               interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
+               interrupt-map = <
+                       /* IDSEL 0x0 */
+                       0000 0x0 0x0 0x1 &mpic 0x8 0x1
+                       0000 0x0 0x0 0x2 &mpic 0x9 0x1
+                       0000 0x0 0x0 0x3 &mpic 0xa 0x1
+                       0000 0x0 0x0 0x4 &mpic 0xb 0x1
+                       >;
+               pcie@0 {
+                       reg = <0x0 0x0 0x0 0x0 0x0>;
+                       #size-cells = <2>;
+                       #address-cells = <3>;
+                       device_type = "pci";
+                       ranges = <0x2000000 0x0 0x80000000
+                                 0x2000000 0x0 0x80000000
+                                 0x0 0x20000000
+
+                                 0x1000000 0x0 0x0
+                                 0x1000000 0x0 0x0
+                                 0x0 0x10000>;
+               };
+       };
+
+       pci1: pcie@ffe09000 {
+               compatible = "fsl,mpc8548-pcie";
+               device_type = "pci";
+               #interrupt-cells = <1>;
+               #size-cells = <2>;
+               #address-cells = <3>;
+               reg = <0 0xffe09000 0 0x1000>;
+               bus-range = <0 255>;
+               ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000
+                         0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x10000>;
+               clock-frequency = <33333333>;
+               interrupt-parent = <&mpic>;
+               interrupts = <25 2>;
+               interrupt-map-mask = <0xff00 0x0 0x0 0x7>;
+               interrupt-map = <
+
+                       // IDSEL 0x11 func 0 - PCI slot 1
+                       0x8800 0x0 0x0 0x1 &i8259 0x9 0x2
+                       0x8800 0x0 0x0 0x2 &i8259 0xa 0x2
+
+                       // IDSEL 0x11 func 1 - PCI slot 1
+                       0x8900 0x0 0x0 0x1 &i8259 0x9 0x2
+                       0x8900 0x0 0x0 0x2 &i8259 0xa 0x2
+
+                       // IDSEL 0x11 func 2 - PCI slot 1
+                       0x8a00 0x0 0x0 0x1 &i8259 0x9 0x2
+                       0x8a00 0x0 0x0 0x2 &i8259 0xa 0x2
+
+                       // IDSEL 0x11 func 3 - PCI slot 1
+                       0x8b00 0x0 0x0 0x1 &i8259 0x9 0x2
+                       0x8b00 0x0 0x0 0x2 &i8259 0xa 0x2
+
+                       // IDSEL 0x11 func 4 - PCI slot 1
+                       0x8c00 0x0 0x0 0x1 &i8259 0x9 0x2
+                       0x8c00 0x0 0x0 0x2 &i8259 0xa 0x2
+
+                       // IDSEL 0x11 func 5 - PCI slot 1
+                       0x8d00 0x0 0x0 0x1 &i8259 0x9 0x2
+                       0x8d00 0x0 0x0 0x2 &i8259 0xa 0x2
+
+                       // IDSEL 0x11 func 6 - PCI slot 1
+                       0x8e00 0x0 0x0 0x1 &i8259 0x9 0x2
+                       0x8e00 0x0 0x0 0x2 &i8259 0xa 0x2
+
+                       // IDSEL 0x11 func 7 - PCI slot 1
+                       0x8f00 0x0 0x0 0x1 &i8259 0x9 0x2
+                       0x8f00 0x0 0x0 0x2 &i8259 0xa 0x2
+
+                       // IDSEL 0x1d  Audio
+                       0xe800 0x0 0x0 0x1 &i8259 0x6 0x2
+
+                       // IDSEL 0x1e Legacy
+                       0xf000 0x0 0x0 0x1 &i8259 0x7 0x2
+                       0xf100 0x0 0x0 0x1 &i8259 0x7 0x2
+
+                       // IDSEL 0x1f IDE/SATA
+                       0xf800 0x0 0x0 0x1 &i8259 0xe 0x2
+                       0xf900 0x0 0x0 0x1 &i8259 0x5 0x2
+                       >;
+
+               pcie@0 {
+                       reg = <0x0 0x0 0x0 0x0 0x0>;
+                       #size-cells = <2>;
+                       #address-cells = <3>;
+                       device_type = "pci";
+                       ranges = <0x2000000 0x0 0xa0000000
+                                 0x2000000 0x0 0xa0000000
+                                 0x0 0x20000000
+
+                                 0x1000000 0x0 0x0
+                                 0x1000000 0x0 0x0
+                                 0x0 0x10000>;
+                       uli1575@0 {
+                               reg = <0x0 0x0 0x0 0x0 0x0>;
+                               #size-cells = <2>;
+                               #address-cells = <3>;
+                               ranges = <0x2000000 0x0 0xa0000000
+                                         0x2000000 0x0 0xa0000000
+                                         0x0 0x20000000
+
+                                         0x1000000 0x0 0x0
+                                         0x1000000 0x0 0x0
+                                         0x0 0x10000>;
+                               isa@1e {
+                                       device_type = "isa";
+                                       #interrupt-cells = <2>;
+                                       #size-cells = <1>;
+                                       #address-cells = <2>;
+                                       reg = <0xf000 0x0 0x0 0x0 0x0>;
+                                       ranges = <0x1 0x0 0x1000000 0x0 0x0
+                                                 0x1000>;
+                                       interrupt-parent = <&i8259>;
+
+                                       i8259: interrupt-controller@20 {
+                                               reg = <0x1 0x20 0x2
+                                                      0x1 0xa0 0x2
+                                                      0x1 0x4d0 0x2>;
+                                               interrupt-controller;
+                                               device_type = "interrupt-controller";
+                                               #address-cells = <0>;
+                                               #interrupt-cells = <2>;
+                                               compatible = "chrp,iic";
+                                               interrupts = <4 1>;
+                                               interrupt-parent = <&mpic>;
+                                       };
+
+                                       i8042@60 {
+                                               #size-cells = <0>;
+                                               #address-cells = <1>;
+                                               reg = <0x1 0x60 0x1 0x1 0x64 0x1>;
+                                               interrupts = <1 3 12 3>;
+                                               interrupt-parent =
+                                                       <&i8259>;
+
+                                               keyboard@0 {
+                                                       reg = <0x0>;
+                                                       compatible = "pnpPNP,303";
+                                               };
+
+                                               mouse@1 {
+                                                       reg = <0x1>;
+                                                       compatible = "pnpPNP,f03";
+                                               };
+                                       };
+
+                                       rtc@70 {
+                                               compatible = "pnpPNP,b00";
+                                               reg = <0x1 0x70 0x2>;
+                                       };
+
+                                       gpio@400 {
+                                               reg = <0x1 0x400 0x80>;
+                                       };
+                               };
+                       };
+               };
+
+       };
+
+       pci2: pcie@ffe0a000 {
+               compatible = "fsl,mpc8548-pcie";
+               device_type = "pci";
+               #interrupt-cells = <1>;
+               #size-cells = <2>;
+               #address-cells = <3>;
+               reg = <0 0xffe0a000 0 0x1000>;
+               bus-range = <0 255>;
+               ranges = <0x2000000 0x0 0xc0000000 0 0xc0000000 0x0 0x20000000
+                         0x1000000 0x0 0x00000000 0 0xffc20000 0x0 0x10000>;
+               clock-frequency = <33333333>;
+               interrupt-parent = <&mpic>;
+               interrupts = <26 2>;
+               interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
+               interrupt-map = <
+                       /* IDSEL 0x0 */
+                       0000 0x0 0x0 0x1 &mpic 0x0 0x1
+                       0000 0x0 0x0 0x2 &mpic 0x1 0x1
+                       0000 0x0 0x0 0x3 &mpic 0x2 0x1
+                       0000 0x0 0x0 0x4 &mpic 0x3 0x1
+                       >;
+               pcie@0 {
+                       reg = <0x0 0x0 0x0 0x0 0x0>;
+                       #size-cells = <2>;
+                       #address-cells = <3>;
+                       device_type = "pci";
+                       ranges = <0x2000000 0x0 0xc0000000
+                                 0x2000000 0x0 0xc0000000
+                                 0x0 0x20000000
+
+                                 0x1000000 0x0 0x0
+                                 0x1000000 0x0 0x0
+                                 0x0 0x10000>;
+               };
+       };
+};
index a36dbbc48694749aefc10d74fdda78270bff3245..5fb6f6684b0eda8b724c2b4c2f741f3ba59b020c 100644 (file)
        };
 
        pci0: pci@e0008500 {
-               cell-index = <1>;
                interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
                interrupt-map = <
 
index b1f1416ac9988d254be577f200fc3ef59cb5abd6..9eefe00ed25358500beb19a58583a2bb3fb98a09 100644 (file)
                #size-cells = <1>;
                device_type = "soc";
                ranges = <0x00000000 0xe0000000 0x00100000>;
-               reg = <0xe0000000 0x00001000>;  // CCSRBAR
                bus-frequency = <0>;
                compatible = "simple-bus";
 
+               ecm-law@0 {
+                       compatible = "fsl,ecm-law";
+                       reg = <0x0 0x1000>;
+                       fsl,num-laws = <10>;
+               };
+
+               ecm@1000 {
+                       compatible = "fsl,mpc8548-ecm", "fsl,ecm";
+                       reg = <0x1000 0x1000>;
+                       interrupts = <17 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
                memory-controller@2000 {
                        compatible = "fsl,mpc8548-memory-controller";
                        reg = <0x2000 0x1000>;
        };
 
        pci0: pci@e0008000 {
-               cell-index = <0>;
                interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
                interrupt-map = <
                        /* IDSEL 0x01 (PCI-X slot) @66MHz */
        };
 
        pci2: pcie@e000a000 {
-               cell-index = <2>;
                interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
                interrupt-map = <
 
index c4564b81e47305e478aa6b6591118cd4712616f9..239d57a55cf41e48b6d10fc66f40762d4bfcfaf5 100644 (file)
                #size-cells = <1>;
                device_type = "soc";
                ranges = <0x0 0xff700000 0x00100000>;
-               reg = <0xff700000 0x00100000>;
                clock-frequency = <0>;
 
+               ecm-law@0 {
+                       compatible = "fsl,ecm-law";
+                       reg = <0x0 0x1000>;
+                       fsl,num-laws = <8>;
+               };
+
+               ecm@1000 {
+                       compatible = "fsl,mpc8560-ecm", "fsl,ecm";
+                       reg = <0x1000 0x1000>;
+                       interrupts = <17 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
                memory-controller@2000 {
                        compatible = "fsl,mpc8560-memory-controller";
                        reg = <0x2000 0x1000>;
        };
 
        pci0: pci@ff708000 {
-               cell-index = <0>;
                #interrupt-cells = <1>;
                #size-cells = <2>;
                #address-cells = <3>;
index e3e914e78caa2e6fdec7f5181e6a2e0a39d97a72..ee5538feb4555fa89a9198d08a5d8181fa054fbc 100644 (file)
                device_type = "soc";
                compatible = "simple-bus";
                ranges = <0x00000000 0xf8000000 0x00100000>;
-               reg = <0xf8000000 0x00001000>;  // CCSRBAR
                bus-frequency = <0>;
 
+               mcm-law@0 {
+                       compatible = "fsl,mcm-law";
+                       reg = <0x0 0x1000>;
+                       fsl,num-laws = <10>;
+               };
+
+               mcm@1000 {
+                       compatible = "fsl,mpc8641-mcm", "fsl,mcm";
+                       reg = <0x1000 0x1000>;
+                       interrupts = <17 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
                i2c@3000 {
                        #address-cells = <1>;
                        #size-cells = <0>;
        };
 
        pci0: pcie@f8008000 {
-               cell-index = <0>;
                compatible = "fsl,mpc8641-pcie";
                device_type = "pci";
                #interrupt-cells = <1>;
        };
 
        pci1: pcie@f8009000 {
-               cell-index = <1>;
                compatible = "fsl,mpc8641-pcie";
                device_type = "pci";
                #interrupt-cells = <1>;
index 43cc68bd3192620b90bd3b2e16105263bfffcc73..739dd0da2416fa9f39d76b001ed808e626d1e13b 100644 (file)
                                        };
                                };
 
+                               ndfc@3,0 {
+                                       compatible = "ibm,ndfc";
+                                       reg = <0x00000003 0x00000000 0x00002000>;
+                                       ccr = <0x00001000>;
+                                       bank-settings = <0x80002222>;
+                                       #address-cells = <1>;
+                                       #size-cells = <1>;
+
+                                       nand {
+                                               #address-cells = <1>;
+                                               #size-cells = <1>;
+
+                                               partition@0 {
+                                                       label = "u-boot";
+                                                       reg = <0x00000000 0x00084000>;
+                                               };
+                                               partition@84000 {
+                                                       label = "user";
+                                                       reg = <0x00000000 0x01f7c000>;
+                                               };
+                                       };
+                               };
                        };
 
                        UART0: serial@ef600300 {
index 7a6ae75a1e573a14afac948038fa469a662b012f..feb4ef6bd14466bd65739306dc4d231170ea873c 100644 (file)
                device_type = "soc";
 
                ranges = <0x00000000 0xe0000000 0x00100000>;
-               reg = <0xe0000000 0x00001000>;  // CCSRBAR 1M
                bus-frequency = <0>;            // Filled in by U-Boot
                compatible = "fsl,mpc8544-immr", "simple-bus";
 
+               ecm-law@0 {
+                       compatible = "fsl,ecm-law";
+                       reg = <0x0 0x1000>;
+                       fsl,num-laws = <10>;
+               };
+
+               ecm@1000 {
+                       compatible = "fsl,mpc8544-ecm", "fsl,ecm";
+                       reg = <0x1000 0x1000>;
+                       interrupts = <17 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
                memory-controller@2000 {
                        compatible = "fsl,mpc8544-memory-controller";
                        reg = <0x2000 0x1000>;
        };
 
        pci0: pci@e0008000 {
-               cell-index = <0>;
                #interrupt-cells = <1>;
                #size-cells = <2>;
                #address-cells = <3>;
index ea6b15152de39d15e0d3474b23a1771bc6a1f3f0..b670d03fbcd91ba172bb14d14fb8db519aa2fd2c 100644 (file)
                #size-cells = <1>;
                device_type = "soc";
                ranges = <0 0xfdf00000 0x100000>;
-               reg = <0xfdf00000 0x1000>;
                bus-frequency = <0>;
                compatible = "fsl,mpc8560-immr", "simple-bus";
 
+               ecm-law@0 {
+                       compatible = "fsl,ecm-law";
+                       reg = <0x0 0x1000>;
+                       fsl,num-laws = <8>;
+               };
+
+               ecm@1000 {
+                       compatible = "fsl,mpc8560-ecm", "fsl,ecm";
+                       reg = <0x1000 0x1000>;
+                       interrupts = <17 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
                memory-controller@2000 {
                        compatible = "fsl,mpc8540-memory-controller";
                        reg = <0x2000 0x1000>;
        };
 
        pci0: pci@fdf08000 {
-               cell-index = <0>;
                interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
                interrupt-map = <
 
index b6f1fc6eb9600f7ddb72ce3d65eaaf660da74eac..71347537b83e16f08d882547c57a7bdd562aad23 100644 (file)
                #size-cells = <1>;
                device_type = "soc";
                ranges = <0x0 0xe0000000 0x100000>;
-               reg = <0xe0000000 0x200>;
                bus-frequency = <0>;
                compatible = "fsl,mpc8540-immr", "simple-bus";
 
+               ecm-law@0 {
+                       compatible = "fsl,ecm-law";
+                       reg = <0x0 0x1000>;
+                       fsl,num-laws = <8>;
+               };
+
+               ecm@1000 {
+                       compatible = "fsl,mpc8540-ecm", "fsl,ecm";
+                       reg = <0x1000 0x1000>;
+                       interrupts = <17 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
                memory-controller@2000 {
                        compatible = "fsl,mpc8540-memory-controller";
                        reg = <0x2000 0x1000>;
        };
 
        pci0: pci@e0008000 {
-               cell-index = <0>;
                #interrupt-cells = <1>;
                #size-cells = <2>;
                #address-cells = <3>;
index fa6a3d54a8a5f44860b4ecda5bc869d398e28898..b30f63753d412582caad06dbddb909e369896a9c 100644 (file)
                #size-cells = <1>;
                device_type = "soc";
                ranges = <0x0 0xe0000000 0x100000>;
-               reg = <0xe0000000 0x200>;
                bus-frequency = <0>;
                compatible = "fsl,mpc8541-immr", "simple-bus";
 
+               ecm-law@0 {
+                       compatible = "fsl,ecm-law";
+                       reg = <0x0 0x1000>;
+                       fsl,num-laws = <8>;
+               };
+
+               ecm@1000 {
+                       compatible = "fsl,mpc8541-ecm", "fsl,ecm";
+                       reg = <0x1000 0x1000>;
+                       interrupts = <17 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
                memory-controller@2000 {
                        compatible = "fsl,mpc8540-memory-controller";
                        reg = <0x2000 0x1000>;
        };
 
        pci0: pci@e0008000 {
-               cell-index = <0>;
                #interrupt-cells = <1>;
                #size-cells = <2>;
                #address-cells = <3>;
index 00f7ed7a24552295020fdc632b52527863f38709..61f25e15fd66c36492599a19aadaeff7d26eefb2 100644 (file)
                #size-cells = <1>;
                device_type = "soc";
                ranges = <0x0 0xa0000000 0x100000>;
-               reg = <0xa0000000 0x1000>;      // CCSRBAR
                bus-frequency = <0>;
                compatible = "fsl,mpc8548-immr", "simple-bus";
 
+               ecm-law@0 {
+                       compatible = "fsl,ecm-law";
+                       reg = <0x0 0x1000>;
+                       fsl,num-laws = <10>;
+               };
+
+               ecm@1000 {
+                       compatible = "fsl,mpc8548-ecm", "fsl,ecm";
+                       reg = <0x1000 0x1000>;
+                       interrupts = <17 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
                memory-controller@2000 {
                        compatible = "fsl,mpc8548-memory-controller";
                        reg = <0x2000 0x1000>;
        };
 
        pci0: pci@a0008000 {
-               cell-index = <0>;
                #interrupt-cells = <1>;
                #size-cells = <2>;
                #address-cells = <3>;
        };
 
        pci1: pcie@a000a000 {
-               cell-index = <2>;
                interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
                interrupt-map = <
                        /* IDSEL 0x0 (PEX) */
index 673e4a778ac8129753a32bdd449c93cd3038b1e6..025759c7c955cb838d8af6b43909618e2c549901 100644 (file)
                #size-cells = <1>;
                device_type = "soc";
                ranges = <0x0 0xe0000000 0x100000>;
-               reg = <0xe0000000 0x1000>;      // CCSRBAR
                bus-frequency = <0>;
                compatible = "fsl,mpc8548-immr", "simple-bus";
 
+               ecm-law@0 {
+                       compatible = "fsl,ecm-law";
+                       reg = <0x0 0x1000>;
+                       fsl,num-laws = <10>;
+               };
+
+               ecm@1000 {
+                       compatible = "fsl,mpc8548-ecm", "fsl,ecm";
+                       reg = <0x1000 0x1000>;
+                       interrupts = <17 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
                memory-controller@2000 {
                        compatible = "fsl,mpc8548-memory-controller";
                        reg = <0x2000 0x1000>;
        };
 
        pci0: pci@e0008000 {
-               cell-index = <0>;
                #interrupt-cells = <1>;
                #size-cells = <2>;
                #address-cells = <3>;
        };
 
        pci1: pcie@e000a000 {
-               cell-index = <2>;
                interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
                interrupt-map = <
                        /* IDSEL 0x0 (PEX) */
index 6a99f1eef7ad2402b47e9ed8723121bf36dea151..95e287381836eaf6ce26cb131295a703f50e8a47 100644 (file)
                #size-cells = <1>;
                device_type = "soc";
                ranges = <0x0 0xe0000000 0x100000>;
-               reg = <0xe0000000 0x200>;
                bus-frequency = <0>;
                compatible = "fsl,mpc8555-immr", "simple-bus";
 
+               ecm-law@0 {
+                       compatible = "fsl,ecm-law";
+                       reg = <0x0 0x1000>;
+                       fsl,num-laws = <8>;
+               };
+
+               ecm@1000 {
+                       compatible = "fsl,mpc8555-ecm", "fsl,ecm";
+                       reg = <0x1000 0x1000>;
+                       interrupts = <17 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
                memory-controller@2000 {
                        compatible = "fsl,mpc8540-memory-controller";
                        reg = <0x2000 0x1000>;
        };
 
        pci0: pci@e0008000 {
-               cell-index = <0>;
                #interrupt-cells = <1>;
                #size-cells = <2>;
                #address-cells = <3>;
index b6c2d71defd3d4eb8d394d8d6900b04268d1cb56..ff70580a8f4cd800b474291b04d64788ed513075 100644 (file)
                #size-cells = <1>;
                device_type = "soc";
                ranges = <0x0 0xe0000000 0x100000>;
-               reg = <0xe0000000 0x200>;
                bus-frequency = <0>;
                compatible = "fsl,mpc8560-immr", "simple-bus";
 
+               ecm-law@0 {
+                       compatible = "fsl,ecm-law";
+                       reg = <0x0 0x1000>;
+                       fsl,num-laws = <8>;
+               };
+
+               ecm@1000 {
+                       compatible = "fsl,mpc8560-ecm", "fsl,ecm";
+                       reg = <0x1000 0x1000>;
+                       interrupts = <17 2>;
+                       interrupt-parent = <&mpic>;
+               };
+
                memory-controller@2000 {
                        compatible = "fsl,mpc8540-memory-controller";
                        reg = <0x2000 0x1000>;
        };
 
        pci0: pci@e0008000 {
-               cell-index = <0>;
                #interrupt-cells = <1>;
                #size-cells = <2>;
                #address-cells = <3>;
diff --git a/arch/powerpc/boot/dts/virtex440-ml510.dts b/arch/powerpc/boot/dts/virtex440-ml510.dts
new file mode 100644 (file)
index 0000000..81a8dc2
--- /dev/null
@@ -0,0 +1,465 @@
+/*
+ * Xilinx ML510 Reference Design support
+ *
+ * This DTS file was created for the ml510_bsb1_pcores_ppc440 reference design.
+ * The reference design contains a bug which prevent PCI DMA from working
+ * properly.  A description of the bug is given in the plbv46_pci section. It
+ * needs to be fixed by the user until Xilinx updates their reference design.
+ *
+ * Copyright 2009, Roderick Colenbrander
+ */
+
+/dts-v1/;
+/ {
+       #address-cells = <1>;
+       #size-cells = <1>;
+       compatible = "xlnx,ml510-ref-design", "xlnx,virtex440";
+       dcr-parent = <&ppc440_0>;
+       DDR2_SDRAM_DIMM0: memory@0 {
+               device_type = "memory";
+               reg = < 0x0 0x20000000 >;
+       } ;
+       alias {
+               ethernet0 = &Hard_Ethernet_MAC;
+               serial0 = &RS232_Uart_1;
+       } ;
+       chosen {
+               bootargs = "console=ttyS0 root=/dev/ram";
+               linux,stdout-path = "/plb@0/serial@83e00000";
+       } ;
+       cpus {
+               #address-cells = <1>;
+               #cpus = <0x1>;
+               #size-cells = <0>;
+               ppc440_0: cpu@0 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       clock-frequency = <300000000>;
+                       compatible = "PowerPC,440", "ibm,ppc440";
+                       d-cache-line-size = <0x20>;
+                       d-cache-size = <0x8000>;
+                       dcr-access-method = "native";
+                       dcr-controller ;
+                       device_type = "cpu";
+                       i-cache-line-size = <0x20>;
+                       i-cache-size = <0x8000>;
+                       model = "PowerPC,440";
+                       reg = <0>;
+                       timebase-frequency = <300000000>;
+                       xlnx,apu-control = <0x2000>;
+                       xlnx,apu-udi-0 = <0x0>;
+                       xlnx,apu-udi-1 = <0x0>;
+                       xlnx,apu-udi-10 = <0x0>;
+                       xlnx,apu-udi-11 = <0x0>;
+                       xlnx,apu-udi-12 = <0x0>;
+                       xlnx,apu-udi-13 = <0x0>;
+                       xlnx,apu-udi-14 = <0x0>;
+                       xlnx,apu-udi-15 = <0x0>;
+                       xlnx,apu-udi-2 = <0x0>;
+                       xlnx,apu-udi-3 = <0x0>;
+                       xlnx,apu-udi-4 = <0x0>;
+                       xlnx,apu-udi-5 = <0x0>;
+                       xlnx,apu-udi-6 = <0x0>;
+                       xlnx,apu-udi-7 = <0x0>;
+                       xlnx,apu-udi-8 = <0x0>;
+                       xlnx,apu-udi-9 = <0x0>;
+                       xlnx,dcr-autolock-enable = <0x1>;
+                       xlnx,dcu-rd-ld-cache-plb-prio = <0x0>;
+                       xlnx,dcu-rd-noncache-plb-prio = <0x0>;
+                       xlnx,dcu-rd-touch-plb-prio = <0x0>;
+                       xlnx,dcu-rd-urgent-plb-prio = <0x0>;
+                       xlnx,dcu-wr-flush-plb-prio = <0x0>;
+                       xlnx,dcu-wr-store-plb-prio = <0x0>;
+                       xlnx,dcu-wr-urgent-plb-prio = <0x0>;
+                       xlnx,dma0-control = <0x0>;
+                       xlnx,dma0-plb-prio = <0x0>;
+                       xlnx,dma0-rxchannelctrl = <0x1010000>;
+                       xlnx,dma0-rxirqtimer = <0x3ff>;
+                       xlnx,dma0-txchannelctrl = <0x1010000>;
+                       xlnx,dma0-txirqtimer = <0x3ff>;
+                       xlnx,dma1-control = <0x0>;
+                       xlnx,dma1-plb-prio = <0x0>;
+                       xlnx,dma1-rxchannelctrl = <0x1010000>;
+                       xlnx,dma1-rxirqtimer = <0x3ff>;
+                       xlnx,dma1-txchannelctrl = <0x1010000>;
+                       xlnx,dma1-txirqtimer = <0x3ff>;
+                       xlnx,dma2-control = <0x0>;
+                       xlnx,dma2-plb-prio = <0x0>;
+                       xlnx,dma2-rxchannelctrl = <0x1010000>;
+                       xlnx,dma2-rxirqtimer = <0x3ff>;
+                       xlnx,dma2-txchannelctrl = <0x1010000>;
+                       xlnx,dma2-txirqtimer = <0x3ff>;
+                       xlnx,dma3-control = <0x0>;
+                       xlnx,dma3-plb-prio = <0x0>;
+                       xlnx,dma3-rxchannelctrl = <0x1010000>;
+                       xlnx,dma3-rxirqtimer = <0x3ff>;
+                       xlnx,dma3-txchannelctrl = <0x1010000>;
+                       xlnx,dma3-txirqtimer = <0x3ff>;
+                       xlnx,endian-reset = <0x0>;
+                       xlnx,generate-plb-timespecs = <0x1>;
+                       xlnx,icu-rd-fetch-plb-prio = <0x0>;
+                       xlnx,icu-rd-spec-plb-prio = <0x0>;
+                       xlnx,icu-rd-touch-plb-prio = <0x0>;
+                       xlnx,interconnect-imask = <0xffffffff>;
+                       xlnx,mplb-allow-lock-xfer = <0x1>;
+                       xlnx,mplb-arb-mode = <0x0>;
+                       xlnx,mplb-awidth = <0x20>;
+                       xlnx,mplb-counter = <0x500>;
+                       xlnx,mplb-dwidth = <0x80>;
+                       xlnx,mplb-max-burst = <0x8>;
+                       xlnx,mplb-native-dwidth = <0x80>;
+                       xlnx,mplb-p2p = <0x0>;
+                       xlnx,mplb-prio-dcur = <0x2>;
+                       xlnx,mplb-prio-dcuw = <0x3>;
+                       xlnx,mplb-prio-icu = <0x4>;
+                       xlnx,mplb-prio-splb0 = <0x1>;
+                       xlnx,mplb-prio-splb1 = <0x0>;
+                       xlnx,mplb-read-pipe-enable = <0x1>;
+                       xlnx,mplb-sync-tattribute = <0x0>;
+                       xlnx,mplb-wdog-enable = <0x1>;
+                       xlnx,mplb-write-pipe-enable = <0x1>;
+                       xlnx,mplb-write-post-enable = <0x1>;
+                       xlnx,num-dma = <0x0>;
+                       xlnx,pir = <0xf>;
+                       xlnx,ppc440mc-addr-base = <0x0>;
+                       xlnx,ppc440mc-addr-high = <0x1fffffff>;
+                       xlnx,ppc440mc-arb-mode = <0x0>;
+                       xlnx,ppc440mc-bank-conflict-mask = <0x1800000>;
+                       xlnx,ppc440mc-control = <0xf810008f>;
+                       xlnx,ppc440mc-max-burst = <0x8>;
+                       xlnx,ppc440mc-prio-dcur = <0x2>;
+                       xlnx,ppc440mc-prio-dcuw = <0x3>;
+                       xlnx,ppc440mc-prio-icu = <0x4>;
+                       xlnx,ppc440mc-prio-splb0 = <0x1>;
+                       xlnx,ppc440mc-prio-splb1 = <0x0>;
+                       xlnx,ppc440mc-row-conflict-mask = <0x7ffe00>;
+                       xlnx,ppcdm-asyncmode = <0x0>;
+                       xlnx,ppcds-asyncmode = <0x0>;
+                       xlnx,user-reset = <0x0>;
+               } ;
+       } ;
+       plb_v46_0: plb@0 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "xlnx,plb-v46-1.03.a", "simple-bus";
+               ranges ;
+               FLASH: flash@fc000000 {
+                       bank-width = <2>;
+                       compatible = "xlnx,xps-mch-emc-2.00.a", "cfi-flash";
+                       reg = < 0xfc000000 0x2000000 >;
+                       xlnx,family = "virtex5";
+                       xlnx,include-datawidth-matching-0 = <0x1>;
+                       xlnx,include-datawidth-matching-1 = <0x0>;
+                       xlnx,include-datawidth-matching-2 = <0x0>;
+                       xlnx,include-datawidth-matching-3 = <0x0>;
+                       xlnx,include-negedge-ioregs = <0x0>;
+                       xlnx,include-plb-ipif = <0x1>;
+                       xlnx,include-wrbuf = <0x1>;
+                       xlnx,max-mem-width = <0x10>;
+                       xlnx,mch-native-dwidth = <0x20>;
+                       xlnx,mch-plb-clk-period-ps = <0x2710>;
+                       xlnx,mch-splb-awidth = <0x20>;
+                       xlnx,mch0-accessbuf-depth = <0x10>;
+                       xlnx,mch0-protocol = <0x0>;
+                       xlnx,mch0-rddatabuf-depth = <0x10>;
+                       xlnx,mch1-accessbuf-depth = <0x10>;
+                       xlnx,mch1-protocol = <0x0>;
+                       xlnx,mch1-rddatabuf-depth = <0x10>;
+                       xlnx,mch2-accessbuf-depth = <0x10>;
+                       xlnx,mch2-protocol = <0x0>;
+                       xlnx,mch2-rddatabuf-depth = <0x10>;
+                       xlnx,mch3-accessbuf-depth = <0x10>;
+                       xlnx,mch3-protocol = <0x0>;
+                       xlnx,mch3-rddatabuf-depth = <0x10>;
+                       xlnx,mem0-width = <0x10>;
+                       xlnx,mem1-width = <0x20>;
+                       xlnx,mem2-width = <0x20>;
+                       xlnx,mem3-width = <0x20>;
+                       xlnx,num-banks-mem = <0x1>;
+                       xlnx,num-channels = <0x2>;
+                       xlnx,priority-mode = <0x0>;
+                       xlnx,synch-mem-0 = <0x0>;
+                       xlnx,synch-mem-1 = <0x0>;
+                       xlnx,synch-mem-2 = <0x0>;
+                       xlnx,synch-mem-3 = <0x0>;
+                       xlnx,synch-pipedelay-0 = <0x2>;
+                       xlnx,synch-pipedelay-1 = <0x2>;
+                       xlnx,synch-pipedelay-2 = <0x2>;
+                       xlnx,synch-pipedelay-3 = <0x2>;
+                       xlnx,tavdv-ps-mem-0 = <0x1adb0>;
+                       xlnx,tavdv-ps-mem-1 = <0x3a98>;
+                       xlnx,tavdv-ps-mem-2 = <0x3a98>;
+                       xlnx,tavdv-ps-mem-3 = <0x3a98>;
+                       xlnx,tcedv-ps-mem-0 = <0x1adb0>;
+                       xlnx,tcedv-ps-mem-1 = <0x3a98>;
+                       xlnx,tcedv-ps-mem-2 = <0x3a98>;
+                       xlnx,tcedv-ps-mem-3 = <0x3a98>;
+                       xlnx,thzce-ps-mem-0 = <0x88b8>;
+                       xlnx,thzce-ps-mem-1 = <0x1b58>;
+                       xlnx,thzce-ps-mem-2 = <0x1b58>;
+                       xlnx,thzce-ps-mem-3 = <0x1b58>;
+                       xlnx,thzoe-ps-mem-0 = <0x1b58>;
+                       xlnx,thzoe-ps-mem-1 = <0x1b58>;
+                       xlnx,thzoe-ps-mem-2 = <0x1b58>;
+                       xlnx,thzoe-ps-mem-3 = <0x1b58>;
+                       xlnx,tlzwe-ps-mem-0 = <0x88b8>;
+                       xlnx,tlzwe-ps-mem-1 = <0x0>;
+                       xlnx,tlzwe-ps-mem-2 = <0x0>;
+                       xlnx,tlzwe-ps-mem-3 = <0x0>;
+                       xlnx,twc-ps-mem-0 = <0x1adb0>;
+                       xlnx,twc-ps-mem-1 = <0x3a98>;
+                       xlnx,twc-ps-mem-2 = <0x3a98>;
+                       xlnx,twc-ps-mem-3 = <0x3a98>;
+                       xlnx,twp-ps-mem-0 = <0x11170>;
+                       xlnx,twp-ps-mem-1 = <0x2ee0>;
+                       xlnx,twp-ps-mem-2 = <0x2ee0>;
+                       xlnx,twp-ps-mem-3 = <0x2ee0>;
+                       xlnx,xcl0-linesize = <0x4>;
+                       xlnx,xcl0-writexfer = <0x1>;
+                       xlnx,xcl1-linesize = <0x4>;
+                       xlnx,xcl1-writexfer = <0x1>;
+                       xlnx,xcl2-linesize = <0x4>;
+                       xlnx,xcl2-writexfer = <0x1>;
+                       xlnx,xcl3-linesize = <0x4>;
+                       xlnx,xcl3-writexfer = <0x1>;
+               } ;
+               Hard_Ethernet_MAC: xps-ll-temac@81c00000 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       compatible = "xlnx,compound";
+                       ethernet@81c00000 {
+                               compatible = "xlnx,xps-ll-temac-1.01.b";
+                               device_type = "network";
+                               interrupt-parent = <&xps_intc_0>;
+                               interrupts = < 8 2 >;
+                               llink-connected = <&Hard_Ethernet_MAC_fifo>;
+                               local-mac-address = [ 02 00 00 00 00 00 ];
+                               reg = < 0x81c00000 0x40 >;
+                               xlnx,bus2core-clk-ratio = <0x1>;
+                               xlnx,phy-type = <0x3>;
+                               xlnx,phyaddr = <0x1>;
+                               xlnx,rxcsum = <0x0>;
+                               xlnx,rxfifo = <0x8000>;
+                               xlnx,temac-type = <0x0>;
+                               xlnx,txcsum = <0x0>;
+                               xlnx,txfifo = <0x8000>;
+                       } ;
+               } ;
+               Hard_Ethernet_MAC_fifo: xps-ll-fifo@81a00000 {
+                       compatible = "xlnx,xps-ll-fifo-1.01.a";
+                       interrupt-parent = <&xps_intc_0>;
+                       interrupts = < 6 2 >;
+                       reg = < 0x81a00000 0x10000 >;
+                       xlnx,family = "virtex5";
+               } ;
+               IIC_EEPROM: i2c@81600000 {
+                       compatible = "xlnx,xps-iic-2.00.a";
+                       interrupt-parent = <&xps_intc_0>;
+                       interrupts = < 9 2 >;
+                       reg = < 0x81600000 0x10000 >;
+                       xlnx,clk-freq = <0x5f5e100>;
+                       xlnx,family = "virtex5";
+                       xlnx,gpo-width = <0x1>;
+                       xlnx,iic-freq = <0x186a0>;
+                       xlnx,scl-inertial-delay = <0x5>;
+                       xlnx,sda-inertial-delay = <0x5>;
+                       xlnx,ten-bit-adr = <0x0>;
+               } ;
+               LCD_OPTIONAL: gpio@81420000 {
+                       compatible = "xlnx,xps-gpio-1.00.a";
+                       reg = < 0x81420000 0x10000 >;
+                       xlnx,all-inputs = <0x0>;
+                       xlnx,all-inputs-2 = <0x0>;
+                       xlnx,dout-default = <0x0>;
+                       xlnx,dout-default-2 = <0x0>;
+                       xlnx,family = "virtex5";
+                       xlnx,gpio-width = <0xb>;
+                       xlnx,interrupt-present = <0x0>;
+                       xlnx,is-bidir = <0x1>;
+                       xlnx,is-bidir-2 = <0x1>;
+                       xlnx,is-dual = <0x0>;
+                       xlnx,tri-default = <0xffffffff>;
+                       xlnx,tri-default-2 = <0xffffffff>;
+               } ;
+               LEDs_4Bit: gpio@81400000 {
+                       compatible = "xlnx,xps-gpio-1.00.a";
+                       reg = < 0x81400000 0x10000 >;
+                       xlnx,all-inputs = <0x0>;
+                       xlnx,all-inputs-2 = <0x0>;
+                       xlnx,dout-default = <0x0>;
+                       xlnx,dout-default-2 = <0x0>;
+                       xlnx,family = "virtex5";
+                       xlnx,gpio-width = <0x4>;
+                       xlnx,interrupt-present = <0x0>;
+                       xlnx,is-bidir = <0x1>;
+                       xlnx,is-bidir-2 = <0x1>;
+                       xlnx,is-dual = <0x0>;
+                       xlnx,tri-default = <0xffffffff>;
+                       xlnx,tri-default-2 = <0xffffffff>;
+               } ;
+               RS232_Uart_1: serial@83e00000 {
+                       clock-frequency = <100000000>;
+                       compatible = "xlnx,xps-uart16550-2.00.b", "ns16550";
+                       current-speed = <9600>;
+                       device_type = "serial";
+                       interrupt-parent = <&xps_intc_0>;
+                       interrupts = < 11 2 >;
+                       reg = < 0x83e00000 0x10000 >;
+                       reg-offset = <0x1003>;
+                       reg-shift = <2>;
+                       xlnx,family = "virtex5";
+                       xlnx,has-external-rclk = <0x0>;
+                       xlnx,has-external-xin = <0x0>;
+                       xlnx,is-a-16550 = <0x1>;
+               } ;
+               SPI_EEPROM: xps-spi@feff8000 {
+                       compatible = "xlnx,xps-spi-2.00.b";
+                       interrupt-parent = <&xps_intc_0>;
+                       interrupts = < 10 2 >;
+                       reg = < 0xfeff8000 0x80 >;
+                       xlnx,family = "virtex5";
+                       xlnx,fifo-exist = <0x1>;
+                       xlnx,num-ss-bits = <0x1>;
+                       xlnx,num-transfer-bits = <0x8>;
+                       xlnx,sck-ratio = <0x80>;
+               } ;
+               SysACE_CompactFlash: sysace@83600000 {
+                       compatible = "xlnx,xps-sysace-1.00.a";
+                       interrupt-parent = <&xps_intc_0>;
+                       interrupts = < 7 2 >;
+                       reg = < 0x83600000 0x10000 >;
+                       xlnx,family = "virtex5";
+                       xlnx,mem-width = <0x10>;
+               } ;
+               plbv46_pci_0: plbv46-pci@85e00000 {
+                       #size-cells = <2>;
+                       #address-cells = <3>;
+                       compatible = "xlnx,plbv46-pci-1.03.a";
+                       device_type = "pci";
+                       reg = < 0x85e00000 0x10000 >;
+
+                       /*
+                        * The default ML510 BSB has C_IPIFBAR2PCIBAR_0 set to
+                        * 0 which means that a read/write to the memory mapped
+                        * i/o region (which starts at 0xa0000000) for pci
+                        * bar 0 on the plb side translates to 0.
+                        * It is important to set this value to 0xa0000000, so
+                        * that inbound and outbound pci transactions work
+                        * properly including DMA.
+                        */
+                       ranges = <0x02000000 0 0xa0000000 0xa0000000 0 0x20000000
+                                 0x01000000 0 0x00000000 0xf0000000 0 0x00010000>;
+
+                       #interrupt-cells = <1>;
+                       interrupt-parent = <&xps_intc_0>;
+                       interrupt-map-mask = <0xff00 0x0 0x0 0x7>;
+                       interrupt-map = <
+                               /* IRQ mapping for pci slots and ALI M1533
+                                * periperhals. In total there are 5 interrupt
+                                * lines connected to a xps_intc controller.
+                                * Four of them are PCI IRQ A, B, C, D and
+                                * which correspond to respectively xpx_intc
+                                * 5, 4, 3 and 2.  The fifth interrupt line is
+                                * connected to the south bridge and this one
+                                * uses irq 1 and is active high instead of
+                                * active low.
+                                *
+                                * The M1533 contains various peripherals
+                                * including AC97 audio, a modem, USB, IDE and
+                                * some power management stuff. The modem
+                                * isn't connected on the ML510 and the power
+                                * management core also isn't used.
+                                */
+
+                               /* IDSEL 0x16 / dev=6, bus=0 / PCI slot 3 */
+                               0x3000 0 0 1 &xps_intc_0 3 2
+                               0x3000 0 0 2 &xps_intc_0 2 2
+                               0x3000 0 0 3 &xps_intc_0 5 2
+                               0x3000 0 0 4 &xps_intc_0 4 2
+
+                               /* IDSEL 0x13 / dev=3, bus=1 / PCI slot 4 */
+                               /*
+                               0x11800 0 0 1 &xps_intc_0 5 0 2
+                               0x11800 0 0 2 &xps_intc_0 4 0 2
+                               0x11800 0 0 3 &xps_intc_0 3 0 2
+                               0x11800 0 0 4 &xps_intc_0 2 0 2
+                               */
+
+                               /* According to the datasheet + schematic
+                                * ABCD [FPGA] of slot 5 is mapped to DABC.
+                                * Testing showed that at least A maps to B,
+                                * the mapping of the other pins is a guess
+                                * and for that reason the lines have been
+                                * commented out.
+                                */
+                               /* IDSEL 0x15 / dev=5, bus=0 / PCI slot 5 */
+                               0x2800 0 0 1 &xps_intc_0 4 2
+                               /*
+                               0x2800 0 0 2 &xps_intc_0 3 2
+                               0x2800 0 0 3 &xps_intc_0 2 2
+                               0x2800 0 0 4 &xps_intc_0 5 2
+                               */
+
+                               /* IDSEL 0x12 / dev=2, bus=1 / PCI slot 6 */
+                               /*
+                               0x11000 0 0 1 &xps_intc_0 4 0 2
+                               0x11000 0 0 2 &xps_intc_0 3 0 2
+                               0x11000 0 0 3 &xps_intc_0 2 0 2
+                               0x11000 0 0 4 &xps_intc_0 5 0 2
+                               */
+
+                               /* IDSEL 0x11 / dev=1, bus=0 / AC97 audio */
+                               0x0800 0 0 1 &i8259 7 2
+
+                               /* IDSEL 0x1b / dev=11, bus=0 / IDE */
+                               0x5800 0 0 1 &i8259 14 2
+
+                               /* IDSEL 0x1f / dev 15, bus=0 / 2x USB 1.1 */
+                               0x7800 0 0 1 &i8259 7 2
+                       >;
+                       ali_m1533 {
+                               #size-cells = <1>;
+                               #address-cells = <2>;
+                               i8259: interrupt-controller@20 {
+                                       reg = <1 0x20 2
+                                                       1 0xa0 2
+                                                       1 0x4d0 2>;
+                                       interrupt-controller;
+                                       device_type = "interrupt-controller";
+                                       #address-cells = <0>;
+                                       #interrupt-cells = <2>;
+                                       compatible = "chrp,iic";
+
+                                       /* south bridge irq is active high */
+                                       interrupts = <1 3>;
+                                       interrupt-parent = <&xps_intc_0>;
+                               };
+                       };
+               } ;
+               xps_bram_if_cntlr_1: xps-bram-if-cntlr@ffff0000 {
+                       compatible = "xlnx,xps-bram-if-cntlr-1.00.a";
+                       reg = < 0xffff0000 0x10000 >;
+                       xlnx,family = "virtex5";
+               } ;
+               xps_intc_0: interrupt-controller@81800000 {
+                       #interrupt-cells = <0x2>;
+                       compatible = "xlnx,xps-intc-1.00.a";
+                       interrupt-controller ;
+                       reg = < 0x81800000 0x10000 >;
+                       xlnx,num-intr-inputs = <0xc>;
+               } ;
+               xps_tft_0: tft@86e00000 {
+                       compatible = "xlnx,xps-tft-1.00.a";
+                       reg = < 0x86e00000 0x10000 >;
+                       xlnx,dcr-splb-slave-if = <0x1>;
+                       xlnx,default-tft-base-addr = <0x0>;
+                       xlnx,family = "virtex5";
+                       xlnx,i2c-slave-addr = <0x76>;
+                       xlnx,mplb-awidth = <0x20>;
+                       xlnx,mplb-dwidth = <0x80>;
+                       xlnx,mplb-native-dwidth = <0x40>;
+                       xlnx,mplb-smallest-slave = <0x20>;
+                       xlnx,tft-interface = <0x1>;
+               } ;
+       } ;
+}  ;
index 7e183ff9a31797e5072b940b8298d626610d6b5f..01bfb56bbe802a96d2c4a965df1651483d5d8ae6 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Device Tree Source for PIKA Warp
  *
- * Copyright (c) 2008 PIKA Technologies
+ * Copyright (c) 2008-2009 PIKA Technologies
  *   Sean MacLennan <smaclennan@pikatech.com>
  *
  * This file is licensed under the terms of the GNU General Public
 
                                        partition@0 {
                                                label = "splash";
-                                               reg = <0x00000000 0x00020000>;
+                                               reg = <0x00000000 0x00010000>;
                                        };
                                        partition@300000 {
                                                label = "fpga";
                        };
 
                        GPIO0: gpio@ef600b00 {
-                               compatible = "ibm,gpio-440ep";
+                               compatible = "ibm,ppc4xx-gpio";
                                reg = <0xef600b00 0x00000048>;
                                #gpio-cells = <2>;
                                gpio-controller;
                        };
 
                        GPIO1: gpio@ef600c00 {
-                               compatible = "ibm,gpio-440ep";
+                               compatible = "ibm,ppc4xx-gpio";
                                reg = <0xef600c00 0x00000048>;
                                #gpio-cells = <2>;
                                gpio-controller;
+                       };
 
-                               led@31 {
-                                       compatible = "linux,gpio-led";
-                                       linux,name = ":green:";
-                                       gpios = <&GPIO1 31 0>;
-                               };              
-       
-                               led@30 {        
-                                       compatible = "linux,gpio-led";
-                                       linux,name = ":red:";
-                                       gpios = <&GPIO1 30 0>;
+                       power-leds {
+                               compatible = "gpio-leds";
+                               green {
+                                       gpios = <&GPIO1 0 0>;
+                                       default-state = "on";
+                               };
+                               red {
+                                       gpios = <&GPIO1 1 0>;
                                };
                        };
 
index a32ec8d323a05594a4fdbdb5c4de7ba054446720..173a5bb77ca1ab86ce7a6cd3cabd57ec46acbf11 100644 (file)
@@ -252,7 +252,7 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCCARD is not set
index 4e9d85f39da074df3a2f93540a0451f345ad9829..e9b8495cde0cd4a5ad6861a5770712a569557394 100644 (file)
@@ -254,7 +254,7 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCCARD is not set
index 9917a09bad3ae3ce07d99799f853b1df14f5e745..865725effe93bdb4df4d4cc3fa5ed2544989b66e 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Tue Jan 20 08:17:52 2009
+# Linux kernel version: 2.6.30-rc7
+# Wed Jun  3 10:18:16 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -27,6 +27,7 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_TIME_VSYSCALL=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 CONFIG_IRQ_PER_CPU=y
 CONFIG_STACKTRACE_SUPPORT=y
@@ -49,10 +50,12 @@ CONFIG_PPC_UDBG_16550=y
 # CONFIG_GENERIC_TBSYNC is not set
 CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
+CONFIG_DTC=y
 # CONFIG_DEFAULT_UIMAGE is not set
 CONFIG_PPC_DCR_NATIVE=y
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_PPC_DCR=y
+CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -67,9 +70,19 @@ CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
 CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_GROUP_SCHED=y
@@ -84,22 +97,24 @@ CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=y
-CONFIG_KALLSYMS_STRIP_GENERATED=y
 CONFIG_KALLSYMS_EXTRA_PASS=y
+# CONFIG_STRIP_ASM_SYMS is not set
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -109,10 +124,12 @@ CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
 CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
 # CONFIG_SLAB is not set
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 # CONFIG_KPROBES is not set
 CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
@@ -120,6 +137,7 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -132,7 +150,6 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_BLOCK=y
 CONFIG_LBD=y
-# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -148,11 +165,6 @@ CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_FREEZER is not set
 CONFIG_PPC4xx_PCI_EXPRESS=y
 
@@ -170,7 +182,7 @@ CONFIG_KILAUEA=y
 # CONFIG_MAKALU is not set
 # CONFIG_WALNUT is not set
 # CONFIG_XILINX_VIRTEX_GENERIC_BOARD is not set
-# CONFIG_PPC40x_SIMPLE is not set
+CONFIG_PPC40x_SIMPLE=y
 CONFIG_405EX=y
 # CONFIG_IPIC is not set
 # CONFIG_MPIC is not set
@@ -228,9 +240,12 @@ CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 CONFIG_PPC_4K_PAGES=y
 # CONFIG_PPC_16K_PAGES is not set
 # CONFIG_PPC_64K_PAGES is not set
+# CONFIG_PPC_256K_PAGES is not set
 CONFIG_FORCE_MAX_ZONEORDER=11
 CONFIG_PROC_DEVICETREE=y
 # CONFIG_CMDLINE_BOOL is not set
@@ -252,9 +267,10 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
 # CONFIG_HOTPLUG_PCI is not set
 # CONFIG_HAS_RAPIDIO is not set
@@ -272,14 +288,12 @@ CONFIG_PAGE_OFFSET=0xc0000000
 CONFIG_KERNEL_START=0xc0000000
 CONFIG_PHYSICAL_START=0x00000000
 CONFIG_TASK_SIZE=0xc0000000
-CONFIG_CONSISTENT_START=0xff100000
 CONFIG_CONSISTENT_SIZE=0x00200000
 CONFIG_NET=y
 
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -329,6 +343,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -341,7 +356,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
 # CONFIG_WIRELESS is not set
 # CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
@@ -445,7 +459,6 @@ CONFIG_MTD_PHYSMAP_OF=y
 # LPDDR flash memory drivers
 #
 # CONFIG_MTD_LPDDR is not set
-# CONFIG_MTD_QINFO_PROBE is not set
 
 #
 # UBI - Unsorted block images
@@ -498,6 +511,7 @@ CONFIG_HAVE_IDE=y
 # CONFIG_I2O is not set
 # CONFIG_MACINTOSH_DRIVERS is not set
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -512,6 +526,8 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_SUNGEM is not set
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_ETHOC is not set
+# CONFIG_DNET is not set
 # CONFIG_NET_TULIP is not set
 # CONFIG_HP100 is not set
 CONFIG_IBM_NEW_EMAC=y
@@ -540,7 +556,6 @@ CONFIG_IBM_NEW_EMAC_EMAC4=y
 #
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -678,6 +693,7 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_EDAC is not set
 # CONFIG_RTC_CLASS is not set
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
@@ -705,6 +721,11 @@ CONFIG_INOTIFY_USER=y
 # CONFIG_AUTOFS4_FS is not set
 # CONFIG_FUSE_FS is not set
 
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
 #
 # CD-ROM/DVD Filesystems
 #
@@ -749,6 +770,7 @@ CONFIG_CRAMFS=y
 # CONFIG_ROMFS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
@@ -760,7 +782,6 @@ CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -776,6 +797,7 @@ CONFIG_SUNRPC=y
 CONFIG_MSDOS_PARTITION=y
 # CONFIG_NLS is not set
 # CONFIG_DLM is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -790,11 +812,12 @@ CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
-CONFIG_PLIST=y
+CONFIG_DECOMPRESS_GZIP=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
 CONFIG_HAVE_LMB=y
+CONFIG_NLATTR=y
 
 #
 # Kernel hacking
@@ -812,6 +835,9 @@ CONFIG_DEBUG_KERNEL=y
 CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
 CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
 CONFIG_SCHED_DEBUG=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_TIMER_STATS is not set
@@ -841,9 +867,12 @@ CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_DEBUG_PAGEALLOC is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_TRACING_SUPPORT=y
 
 #
 # Tracers
@@ -851,17 +880,21 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 # CONFIG_FUNCTION_TRACER is not set
 # CONFIG_SCHED_TRACER is not set
 # CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
 # CONFIG_BOOT_TRACER is not set
 # CONFIG_TRACE_BRANCH_PROFILING is not set
 # CONFIG_STACK_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
 CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_DEBUG_STACKOVERFLOW is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
-# CONFIG_DEBUG_PAGEALLOC is not set
+# CONFIG_PPC_EMULATED_STATS is not set
 # CONFIG_CODE_PATCHING_SELFTEST is not set
 # CONFIG_FTR_FIXUP_SELFTEST is not set
 # CONFIG_MSI_BITMAP_SELFTEST is not set
@@ -892,10 +925,12 @@ CONFIG_CRYPTO_BLKCIPHER2=y
 CONFIG_CRYPTO_HASH=y
 CONFIG_CRYPTO_HASH2=y
 CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
 CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_MANAGER2=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 # CONFIG_CRYPTO_AUTHENC is not set
 # CONFIG_CRYPTO_TEST is not set
@@ -964,6 +999,7 @@ CONFIG_CRYPTO_DES=y
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -972,5 +1008,6 @@ CONFIG_CRYPTO_DES=y
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
 # CONFIG_CRYPTO_DEV_HIFN_795X is not set
+# CONFIG_CRYPTO_DEV_PPC4XX is not set
 # CONFIG_PPC_CLOCK is not set
 # CONFIG_VIRTUALIZATION is not set
index 58bf2ac2e0dda475f077fe6dae18a9cabb389874..1467475478730bf73837577c05ff90be2426ec00 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Tue Jan 20 08:17:53 2009
+# Linux kernel version: 2.6.30-rc7
+# Wed Jun  3 09:11:02 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -27,6 +27,7 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_TIME_VSYSCALL=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
 # CONFIG_HAVE_SETUP_PER_CPU_AREA is not set
 CONFIG_IRQ_PER_CPU=y
 CONFIG_STACKTRACE_SUPPORT=y
@@ -49,10 +50,12 @@ CONFIG_PPC_UDBG_16550=y
 # CONFIG_GENERIC_TBSYNC is not set
 CONFIG_AUDIT_ARCH=y
 CONFIG_GENERIC_BUG=y
+CONFIG_DTC=y
 # CONFIG_DEFAULT_UIMAGE is not set
 CONFIG_PPC_DCR_NATIVE=y
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_PPC_DCR=y
+CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -67,9 +70,19 @@ CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
 CONFIG_SYSVIPC_SYSCTL=y
 CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_GROUP_SCHED=y
@@ -84,22 +97,24 @@ CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
 CONFIG_KALLSYMS_ALL=y
-CONFIG_KALLSYMS_STRIP_GENERATED=y
 CONFIG_KALLSYMS_EXTRA_PASS=y
+# CONFIG_STRIP_ASM_SYMS is not set
 CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -109,10 +124,12 @@ CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
 CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
 # CONFIG_SLAB is not set
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 # CONFIG_KPROBES is not set
 CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
@@ -120,6 +137,7 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -132,7 +150,6 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_BLOCK=y
 CONFIG_LBD=y
-# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -148,11 +165,6 @@ CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_FREEZER is not set
 CONFIG_PPC4xx_PCI_EXPRESS=y
 
@@ -170,7 +182,7 @@ CONFIG_PPC4xx_PCI_EXPRESS=y
 CONFIG_MAKALU=y
 # CONFIG_WALNUT is not set
 # CONFIG_XILINX_VIRTEX_GENERIC_BOARD is not set
-# CONFIG_PPC40x_SIMPLE is not set
+CONFIG_PPC40x_SIMPLE=y
 CONFIG_405EX=y
 # CONFIG_IPIC is not set
 # CONFIG_MPIC is not set
@@ -228,9 +240,12 @@ CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
 CONFIG_PPC_4K_PAGES=y
 # CONFIG_PPC_16K_PAGES is not set
 # CONFIG_PPC_64K_PAGES is not set
+# CONFIG_PPC_256K_PAGES is not set
 CONFIG_FORCE_MAX_ZONEORDER=11
 CONFIG_PROC_DEVICETREE=y
 # CONFIG_CMDLINE_BOOL is not set
@@ -252,9 +267,10 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
 # CONFIG_HOTPLUG_PCI is not set
 # CONFIG_HAS_RAPIDIO is not set
@@ -272,14 +288,12 @@ CONFIG_PAGE_OFFSET=0xc0000000
 CONFIG_KERNEL_START=0xc0000000
 CONFIG_PHYSICAL_START=0x00000000
 CONFIG_TASK_SIZE=0xc0000000
-CONFIG_CONSISTENT_START=0xff100000
 CONFIG_CONSISTENT_SIZE=0x00200000
 CONFIG_NET=y
 
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -329,6 +343,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -341,7 +356,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
 # CONFIG_WIRELESS is not set
 # CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
@@ -445,7 +459,6 @@ CONFIG_MTD_PHYSMAP_OF=y
 # LPDDR flash memory drivers
 #
 # CONFIG_MTD_LPDDR is not set
-# CONFIG_MTD_QINFO_PROBE is not set
 
 #
 # UBI - Unsorted block images
@@ -498,6 +511,7 @@ CONFIG_HAVE_IDE=y
 # CONFIG_I2O is not set
 # CONFIG_MACINTOSH_DRIVERS is not set
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -512,6 +526,8 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_SUNGEM is not set
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_ETHOC is not set
+# CONFIG_DNET is not set
 # CONFIG_NET_TULIP is not set
 # CONFIG_HP100 is not set
 CONFIG_IBM_NEW_EMAC=y
@@ -540,7 +556,6 @@ CONFIG_IBM_NEW_EMAC_EMAC4=y
 #
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -678,6 +693,7 @@ CONFIG_SSB_POSSIBLE=y
 # CONFIG_EDAC is not set
 # CONFIG_RTC_CLASS is not set
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
@@ -705,6 +721,11 @@ CONFIG_INOTIFY_USER=y
 # CONFIG_AUTOFS4_FS is not set
 # CONFIG_FUSE_FS is not set
 
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
 #
 # CD-ROM/DVD Filesystems
 #
@@ -749,6 +770,7 @@ CONFIG_CRAMFS=y
 # CONFIG_ROMFS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
+# CONFIG_NILFS2_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3=y
@@ -760,7 +782,6 @@ CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -776,6 +797,7 @@ CONFIG_SUNRPC=y
 CONFIG_MSDOS_PARTITION=y
 # CONFIG_NLS is not set
 # CONFIG_DLM is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -790,11 +812,12 @@ CONFIG_CRC32=y
 # CONFIG_CRC7 is not set
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
-CONFIG_PLIST=y
+CONFIG_DECOMPRESS_GZIP=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
 CONFIG_HAVE_LMB=y
+CONFIG_NLATTR=y
 
 #
 # Kernel hacking
@@ -812,6 +835,9 @@ CONFIG_DEBUG_KERNEL=y
 CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
 CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
 CONFIG_SCHED_DEBUG=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_TIMER_STATS is not set
@@ -841,9 +867,12 @@ CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_DEBUG_PAGEALLOC is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_TRACING_SUPPORT=y
 
 #
 # Tracers
@@ -851,17 +880,21 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 # CONFIG_FUNCTION_TRACER is not set
 # CONFIG_SCHED_TRACER is not set
 # CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
 # CONFIG_BOOT_TRACER is not set
 # CONFIG_TRACE_BRANCH_PROFILING is not set
 # CONFIG_STACK_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
 CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_DEBUG_STACKOVERFLOW is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
-# CONFIG_DEBUG_PAGEALLOC is not set
+# CONFIG_PPC_EMULATED_STATS is not set
 # CONFIG_CODE_PATCHING_SELFTEST is not set
 # CONFIG_FTR_FIXUP_SELFTEST is not set
 # CONFIG_MSI_BITMAP_SELFTEST is not set
@@ -892,10 +925,12 @@ CONFIG_CRYPTO_BLKCIPHER2=y
 CONFIG_CRYPTO_HASH=y
 CONFIG_CRYPTO_HASH2=y
 CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
 CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_MANAGER2=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 # CONFIG_CRYPTO_AUTHENC is not set
 # CONFIG_CRYPTO_TEST is not set
@@ -964,6 +999,7 @@ CONFIG_CRYPTO_DES=y
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -972,5 +1008,6 @@ CONFIG_CRYPTO_DES=y
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
 # CONFIG_CRYPTO_DEV_HIFN_795X is not set
+# CONFIG_CRYPTO_DEV_PPC4XX is not set
 # CONFIG_PPC_CLOCK is not set
 # CONFIG_VIRTUALIZATION is not set
index f5698f962e58020894330d3fa1ab8c2f351f175a..416e79ac0711aeeb4d97ee4cab178de7a571d855 100644 (file)
@@ -258,7 +258,7 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCCARD is not set
index 1d72b0ac3f255ab1045683cc7b8bf892b126c79c..f7fd32c09424295eeeb30009d24d46de0d84273c 100644 (file)
@@ -258,7 +258,7 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCCARD is not set
index 959bdc43a49183b3c51be7c7161bc91fe5d6137e..e57f1e4c1795196a3f6fddb2abedc41fc143628a 100644 (file)
@@ -262,7 +262,7 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCCARD is not set
index f9a08ee49b9671b70ac67488b12a7516b4e5e7a4..5e85412eb9fae28f401d3b717244187c7d860da4 100644 (file)
@@ -262,7 +262,7 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCCARD is not set
@@ -716,7 +716,7 @@ CONFIG_SSB_POSSIBLE=y
 #
 # Multimedia drivers
 #
-CONFIG_DAB=y
+# CONFIG_DAB is not set
 # CONFIG_USB_DABUSB is not set
 
 #
@@ -725,7 +725,7 @@ CONFIG_DAB=y
 # CONFIG_AGP is not set
 # CONFIG_DRM is not set
 # CONFIG_VGASTATE is not set
-CONFIG_VIDEO_OUTPUT_CONTROL=m
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
 # CONFIG_FB is not set
 # CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
index be64aa644d1503db7a43d6c9e5aaecfc514ab4f7..b652f7dcab5a322bf59ede66ec39374a124074d3 100644 (file)
@@ -261,7 +261,7 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCCARD is not set
index f67250b24ec5c8ccb5e8f34cde965069e2e5cc35..c23a4ef13e45a5c8ccb899c2dc99f157dc894bf3 100644 (file)
@@ -256,7 +256,7 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCCARD is not set
index 9348c12bd7a61f5d899d328667245ee4b1514976..b25fad1343dc17cc304abab9c59bd3ffd8d75269 100644 (file)
@@ -260,7 +260,7 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCCARD is not set
index e665433762baefa83d3c6a09e995322235772f60..ed31d4f17b5a93102cbc2bbb14398a8cf927779d 100644 (file)
@@ -265,7 +265,7 @@ CONFIG_PCIEAER=y
 # CONFIG_PCIEASPM is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCCARD is not set
index 70d5c3fa32837f418b4b4bd25707824f4fef0690..e14e89a5e06b67afed0500ae5bf80e78ec8ef250 100644 (file)
@@ -262,7 +262,7 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCCARD is not set
 # CONFIG_HOTPLUG_PCI is not set
index a921fe3c371184ce7a5cb13d24d01c35123255d9..6400aae04dda9a6dbaa43a8259b3712b6e6acae0 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.29-rc2
-# Tue Jan 20 08:22:45 2009
+# Linux kernel version: 2.6.29
+# Tue Apr  7 17:04:52 2009
 #
 # CONFIG_PPC64 is not set
 
@@ -57,6 +57,7 @@ CONFIG_GENERIC_BUG=y
 CONFIG_PPC_DCR_NATIVE=y
 # CONFIG_PPC_DCR_MMIO is not set
 CONFIG_PPC_DCR=y
+CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
 CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
 
 #
@@ -74,6 +75,15 @@ CONFIG_POSIX_MQUEUE=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
 # CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_GROUP_SCHED=y
@@ -88,8 +98,12 @@ CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_NAMESPACES is not set
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
 CONFIG_EMBEDDED=y
 CONFIG_SYSCTL_SYSCALL=y
 CONFIG_KALLSYMS=y
@@ -99,10 +113,8 @@ CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
-CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
-CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
 CONFIG_TIMERFD=y
@@ -112,10 +124,12 @@ CONFIG_AIO=y
 CONFIG_VM_EVENT_COUNTERS=y
 CONFIG_PCI_QUIRKS=y
 CONFIG_SLUB_DEBUG=y
+CONFIG_COMPAT_BRK=y
 # CONFIG_SLAB is not set
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
 # CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
 CONFIG_HAVE_OPROFILE=y
 # CONFIG_KPROBES is not set
 CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
@@ -123,6 +137,7 @@ CONFIG_HAVE_IOREMAP_PROT=y
 CONFIG_HAVE_KPROBES=y
 CONFIG_HAVE_KRETPROBES=y
 CONFIG_HAVE_ARCH_TRACEHOOK=y
+# CONFIG_SLOW_WORK is not set
 # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
 CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
@@ -135,7 +150,6 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_BLOCK=y
 CONFIG_LBD=y
-# CONFIG_BLK_DEV_IO_TRACE is not set
 # CONFIG_BLK_DEV_BSG is not set
 # CONFIG_BLK_DEV_INTEGRITY is not set
 
@@ -151,11 +165,6 @@ CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
-CONFIG_CLASSIC_RCU=y
-# CONFIG_TREE_RCU is not set
-# CONFIG_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_PREEMPT_RCU_TRACE is not set
 # CONFIG_FREEZER is not set
 # CONFIG_PPC4xx_PCI_EXPRESS is not set
 
@@ -176,6 +185,7 @@ CONFIG_SEQUOIA=y
 # CONFIG_ARCHES is not set
 # CONFIG_CANYONLANDS is not set
 # CONFIG_GLACIER is not set
+# CONFIG_REDWOOD is not set
 # CONFIG_YOSEMITE is not set
 # CONFIG_XILINX_VIRTEX440_GENERIC_BOARD is not set
 CONFIG_PPC44x_SIMPLE=y
@@ -238,9 +248,13 @@ CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_VIRT_TO_BUS=y
 CONFIG_UNEVICTABLE_LRU=y
+CONFIG_HAVE_MLOCK=y
+CONFIG_HAVE_MLOCKED_PAGE_BIT=y
+CONFIG_STDBINUTILS=y
 CONFIG_PPC_4K_PAGES=y
 # CONFIG_PPC_16K_PAGES is not set
 # CONFIG_PPC_64K_PAGES is not set
+# CONFIG_PPC_256K_PAGES is not set
 CONFIG_FORCE_MAX_ZONEORDER=11
 CONFIG_PROC_DEVICETREE=y
 CONFIG_CMDLINE_BOOL=y
@@ -262,9 +276,10 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
 # CONFIG_PCCARD is not set
 # CONFIG_HOTPLUG_PCI is not set
 # CONFIG_HAS_RAPIDIO is not set
@@ -278,18 +293,16 @@ CONFIG_PCI_LEGACY=y
 # Default settings for advanced configuration options are used
 #
 CONFIG_LOWMEM_SIZE=0x30000000
+CONFIG_LOWMEM_CAM_NUM=3
 CONFIG_PAGE_OFFSET=0xc0000000
 CONFIG_KERNEL_START=0xc0000000
 CONFIG_PHYSICAL_START=0x00000000
 CONFIG_TASK_SIZE=0xc0000000
-CONFIG_CONSISTENT_START=0xff100000
-CONFIG_CONSISTENT_SIZE=0x00200000
 CONFIG_NET=y
 
 #
 # Networking options
 #
-CONFIG_COMPAT_NET_DEV_OPS=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 CONFIG_UNIX=y
@@ -339,6 +352,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_LAPB is not set
 # CONFIG_ECONET is not set
 # CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
 # CONFIG_NET_SCHED is not set
 # CONFIG_DCB is not set
 
@@ -351,7 +365,6 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
-# CONFIG_PHONET is not set
 # CONFIG_WIRELESS is not set
 # CONFIG_WIMAX is not set
 # CONFIG_RFKILL is not set
@@ -448,14 +461,23 @@ CONFIG_MTD_PHYSMAP_OF=y
 # CONFIG_MTD_DOC2000 is not set
 # CONFIG_MTD_DOC2001 is not set
 # CONFIG_MTD_DOC2001PLUS is not set
-# CONFIG_MTD_NAND is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+CONFIG_MTD_NAND_ECC_SMC=y
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+CONFIG_MTD_NAND_IDS=y
+CONFIG_MTD_NAND_NDFC=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_CAFE is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_NAND_FSL_ELBC is not set
 # CONFIG_MTD_ONENAND is not set
 
 #
 # LPDDR flash memory drivers
 #
 # CONFIG_MTD_LPDDR is not set
-# CONFIG_MTD_QINFO_PROBE is not set
 
 #
 # UBI - Unsorted block images
@@ -483,12 +505,16 @@ CONFIG_BLK_DEV_RAM_SIZE=35000
 # CONFIG_BLK_DEV_HD is not set
 CONFIG_MISC_DEVICES=y
 # CONFIG_PHANTOM is not set
-# CONFIG_EEPROM_93CX6 is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
 # CONFIG_HP_ILO is not set
 # CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
 CONFIG_HAVE_IDE=y
 # CONFIG_IDE is not set
 
@@ -515,6 +541,7 @@ CONFIG_HAVE_IDE=y
 # CONFIG_I2O is not set
 # CONFIG_MACINTOSH_DRIVERS is not set
 CONFIG_NETDEVICES=y
+CONFIG_COMPAT_NET_DEV_OPS=y
 # CONFIG_DUMMY is not set
 # CONFIG_BONDING is not set
 # CONFIG_MACVLAN is not set
@@ -529,6 +556,8 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_SUNGEM is not set
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_ETHOC is not set
+# CONFIG_DNET is not set
 # CONFIG_NET_TULIP is not set
 # CONFIG_HP100 is not set
 CONFIG_IBM_NEW_EMAC=y
@@ -568,6 +597,7 @@ CONFIG_NETDEV_1000=y
 # CONFIG_QLA3XXX is not set
 # CONFIG_ATL1 is not set
 # CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
 # CONFIG_JME is not set
 CONFIG_NETDEV_10000=y
 # CONFIG_CHELSIO_T1 is not set
@@ -577,6 +607,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_IXGBE is not set
 # CONFIG_IXGB is not set
 # CONFIG_S2IO is not set
+# CONFIG_VXGE is not set
 # CONFIG_MYRI10GE is not set
 # CONFIG_NETXEN_NIC is not set
 # CONFIG_NIU is not set
@@ -586,6 +617,7 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 # CONFIG_BNX2X is not set
 # CONFIG_QLGE is not set
 # CONFIG_SFC is not set
+# CONFIG_BE2NET is not set
 # CONFIG_TR is not set
 
 #
@@ -593,7 +625,6 @@ CONFIG_CHELSIO_T3_DEPENDS=y
 #
 # CONFIG_WLAN_PRE80211 is not set
 # CONFIG_WLAN_80211 is not set
-# CONFIG_IWLWIFI_LEDS is not set
 
 #
 # Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -734,7 +765,7 @@ CONFIG_USB_ARCH_HAS_EHCI=y
 #
 
 #
-# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
 #
 # CONFIG_USB_GADGET is not set
 
@@ -750,6 +781,7 @@ CONFIG_USB_ARCH_HAS_EHCI=y
 # CONFIG_EDAC is not set
 # CONFIG_RTC_CLASS is not set
 # CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_STAGING is not set
 
@@ -777,6 +809,11 @@ CONFIG_INOTIFY_USER=y
 # CONFIG_AUTOFS4_FS is not set
 # CONFIG_FUSE_FS is not set
 
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
 #
 # CD-ROM/DVD Filesystems
 #
@@ -842,7 +879,6 @@ CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
 CONFIG_NFS_COMMON=y
 CONFIG_SUNRPC=y
-# CONFIG_SUNRPC_REGISTER_V4 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_SMB_FS is not set
@@ -858,6 +894,7 @@ CONFIG_SUNRPC=y
 CONFIG_MSDOS_PARTITION=y
 # CONFIG_NLS is not set
 # CONFIG_DLM is not set
+# CONFIG_BINARY_PRINTF is not set
 
 #
 # Library routines
@@ -873,11 +910,12 @@ CONFIG_CRC32=y
 # CONFIG_LIBCRC32C is not set
 CONFIG_ZLIB_INFLATE=y
 CONFIG_ZLIB_DEFLATE=y
-CONFIG_PLIST=y
+CONFIG_DECOMPRESS_GZIP=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
 CONFIG_HAVE_LMB=y
+CONFIG_NLATTR=y
 
 #
 # Kernel hacking
@@ -924,9 +962,12 @@ CONFIG_SCHED_DEBUG=y
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_LATENCYTOP is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
+# CONFIG_DEBUG_PAGEALLOC is not set
 CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_DYNAMIC_FTRACE=y
 CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_TRACING_SUPPORT=y
 
 #
 # Tracers
@@ -934,17 +975,20 @@ CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
 # CONFIG_FUNCTION_TRACER is not set
 # CONFIG_SCHED_TRACER is not set
 # CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_EVENT_TRACER is not set
 # CONFIG_BOOT_TRACER is not set
 # CONFIG_TRACE_BRANCH_PROFILING is not set
 # CONFIG_STACK_TRACER is not set
-# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_KMEMTRACE is not set
+# CONFIG_WORKQUEUE_TRACER is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
 # CONFIG_SAMPLES is not set
 CONFIG_HAVE_ARCH_KGDB=y
 # CONFIG_KGDB is not set
 CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_DEBUG_STACKOVERFLOW is not set
 # CONFIG_DEBUG_STACK_USAGE is not set
-# CONFIG_DEBUG_PAGEALLOC is not set
 # CONFIG_CODE_PATCHING_SELFTEST is not set
 # CONFIG_FTR_FIXUP_SELFTEST is not set
 # CONFIG_MSI_BITMAP_SELFTEST is not set
@@ -952,20 +996,7 @@ CONFIG_PRINT_STACK_DEPTH=64
 # CONFIG_IRQSTACKS is not set
 # CONFIG_VIRQ_DEBUG is not set
 # CONFIG_BDI_SWITCH is not set
-CONFIG_PPC_EARLY_DEBUG=y
-# CONFIG_PPC_EARLY_DEBUG_LPAR is not set
-# CONFIG_PPC_EARLY_DEBUG_G5 is not set
-# CONFIG_PPC_EARLY_DEBUG_RTAS_PANEL is not set
-# CONFIG_PPC_EARLY_DEBUG_RTAS_CONSOLE is not set
-# CONFIG_PPC_EARLY_DEBUG_MAPLE is not set
-# CONFIG_PPC_EARLY_DEBUG_ISERIES is not set
-# CONFIG_PPC_EARLY_DEBUG_PAS_REALMODE is not set
-# CONFIG_PPC_EARLY_DEBUG_BEAT is not set
-CONFIG_PPC_EARLY_DEBUG_44x=y
-# CONFIG_PPC_EARLY_DEBUG_40x is not set
-# CONFIG_PPC_EARLY_DEBUG_CPM is not set
-CONFIG_PPC_EARLY_DEBUG_44x_PHYSLOW=0xef600300
-CONFIG_PPC_EARLY_DEBUG_44x_PHYSHIGH=0x1
+# CONFIG_PPC_EARLY_DEBUG is not set
 
 #
 # Security options
@@ -988,10 +1019,12 @@ CONFIG_CRYPTO_BLKCIPHER2=y
 CONFIG_CRYPTO_HASH=y
 CONFIG_CRYPTO_HASH2=y
 CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
 CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_MANAGER2=y
 # CONFIG_CRYPTO_GF128MUL is not set
 # CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
 # CONFIG_CRYPTO_CRYPTD is not set
 # CONFIG_CRYPTO_AUTHENC is not set
 # CONFIG_CRYPTO_TEST is not set
@@ -1060,6 +1093,7 @@ CONFIG_CRYPTO_DES=y
 # Compression
 #
 # CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
 # CONFIG_CRYPTO_LZO is not set
 
 #
@@ -1068,5 +1102,6 @@ CONFIG_CRYPTO_DES=y
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_HW=y
 # CONFIG_CRYPTO_DEV_HIFN_795X is not set
+# CONFIG_CRYPTO_DEV_PPC4XX is not set
 # CONFIG_PPC_CLOCK is not set
 # CONFIG_VIRTUALIZATION is not set
index 826700872d2648e036b9433decb9fa7990c20add..ef32cc4f82eb0e9fcd0539d37a89af502e441683 100644 (file)
@@ -260,7 +260,7 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCCARD is not set
index 1bf0a63614b1627a21c81dd2af48d3d16c394095..2518b8568c70c5538c96c9fed3b19e2d709abcac 100644 (file)
@@ -263,7 +263,7 @@ CONFIG_PCI_SYSCALL=y
 # CONFIG_PCIEPORTBUS is not set
 CONFIG_ARCH_SUPPORTS_MSI=y
 # CONFIG_PCI_MSI is not set
-CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_LEGACY is not set
 # CONFIG_PCI_DEBUG is not set
 # CONFIG_PCI_STUB is not set
 # CONFIG_PCCARD is not set
index 0f5e8ff59a855bcace108520e9f95ef9ff0c8901..990ff191da8bdb6db1e55dfa06d092502b6ef036 100644 (file)
 #include <asm/cpm.h>
 #include <sysdev/fsl_soc.h>
 
-#ifdef CONFIG_PPC_85xx
-#define CPM_MAP_ADDR (get_immrbase() + 0x80000)
-#endif
-
 /* CPM Command register.
 */
 #define CPM_CR_RST     ((uint)0x80000000)
index cb448d68452c9e01918937952cb1517563538927..3d9e887c3c0cfb0a970e30c6318b4b1804d08549 100644 (file)
 #include <linux/scatterlist.h>
 #include <linux/dma-attrs.h>
 #include <asm/io.h>
+#include <asm/swiotlb.h>
 
 #define DMA_ERROR_CODE         (~(dma_addr_t)0x0)
 
+/* Some dma direct funcs must be visible for use in other dma_ops */
+extern void *dma_direct_alloc_coherent(struct device *dev, size_t size,
+                                      dma_addr_t *dma_handle, gfp_t flag);
+extern void dma_direct_free_coherent(struct device *dev, size_t size,
+                                    void *vaddr, dma_addr_t dma_handle);
+
+extern unsigned long get_dma_direct_offset(struct device *dev);
+
 #ifdef CONFIG_NOT_COHERENT_CACHE
 /*
  * DMA-consistent mapping functions for PowerPCs that don't support
@@ -78,6 +87,8 @@ struct dma_mapping_ops {
                                dma_addr_t dma_address, size_t size,
                                enum dma_data_direction direction,
                                struct dma_attrs *attrs);
+       int             (*addr_needs_map)(struct device *dev, dma_addr_t addr,
+                               size_t size);
 #ifdef CONFIG_PPC_NEED_DMA_SYNC_OPS
        void            (*sync_single_range_for_cpu)(struct device *hwdev,
                                dma_addr_t dma_handle, unsigned long offset,
index d6b4a12cdeff3fccddd0c4691442f5e33fdf0963..014a624f4c8efb054bd46da4e5711713b3e76b68 100644 (file)
@@ -256,11 +256,11 @@ do {                                                              \
  * even if we have an executable stack.
  */
 # define elf_read_implies_exec(ex, exec_stk) (test_thread_flag(TIF_32BIT) ? \
-               (exec_stk != EXSTACK_DISABLE_X) : 0)
+               (exec_stk == EXSTACK_DEFAULT) : 0)
 #else 
 # define SET_PERSONALITY(ex) \
   set_personality(PER_LINUX | (current->personality & (~PER_MASK)))
-# define elf_read_implies_exec(ex, exec_stk) (exec_stk != EXSTACK_DISABLE_X)
+# define elf_read_implies_exec(ex, exec_stk) (exec_stk == EXSTACK_DEFAULT)
 #endif /* __powerpc64__ */
 
 extern int dcache_bsize;
diff --git a/arch/powerpc/include/asm/emulated_ops.h b/arch/powerpc/include/asm/emulated_ops.h
new file mode 100644 (file)
index 0000000..9154e85
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ *  Copyright 2007 Sony Corporation
+ *
+ *  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.
+ *
+ *  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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _ASM_POWERPC_EMULATED_OPS_H
+#define _ASM_POWERPC_EMULATED_OPS_H
+
+#include <asm/atomic.h>
+
+
+#ifdef CONFIG_PPC_EMULATED_STATS
+
+struct ppc_emulated_entry {
+       const char *name;
+       atomic_t val;
+};
+
+extern struct ppc_emulated {
+#ifdef CONFIG_ALTIVEC
+       struct ppc_emulated_entry altivec;
+#endif
+       struct ppc_emulated_entry dcba;
+       struct ppc_emulated_entry dcbz;
+       struct ppc_emulated_entry fp_pair;
+       struct ppc_emulated_entry isel;
+       struct ppc_emulated_entry mcrxr;
+       struct ppc_emulated_entry mfpvr;
+       struct ppc_emulated_entry multiple;
+       struct ppc_emulated_entry popcntb;
+       struct ppc_emulated_entry spe;
+       struct ppc_emulated_entry string;
+       struct ppc_emulated_entry unaligned;
+#ifdef CONFIG_MATH_EMULATION
+       struct ppc_emulated_entry math;
+#elif defined(CONFIG_8XX_MINIMAL_FPEMU)
+       struct ppc_emulated_entry 8xx;
+#endif
+#ifdef CONFIG_VSX
+       struct ppc_emulated_entry vsx;
+#endif
+} ppc_emulated;
+
+extern u32 ppc_warn_emulated;
+
+extern void ppc_warn_emulated_print(const char *type);
+
+#define PPC_WARN_EMULATED(type)                                                 \
+       do {                                                             \
+               atomic_inc(&ppc_emulated.type.val);                      \
+               if (ppc_warn_emulated)                                   \
+                       ppc_warn_emulated_print(ppc_emulated.type.name); \
+       } while (0)
+
+#else /* !CONFIG_PPC_EMULATED_STATS */
+
+#define PPC_WARN_EMULATED(type)        do { } while (0)
+
+#endif /* !CONFIG_PPC_EMULATED_STATS */
+
+#endif /* _ASM_POWERPC_EMULATED_OPS_H */
index e4094a5cb05b6f7de223dd6c15eaf888289d5240..cbd4dfa4bce2e7dc6c5343a310c028757e8cfa86 100644 (file)
@@ -8,8 +8,6 @@
  * 2 of the License, or (at your option) any later version.
  */
 
-#ifdef __ASSEMBLY__
-
 /*
  * Feature section common macros
  *
 /* 64 bits kernel, 32 bits code (ie. vdso32) */
 #define FTR_ENTRY_LONG         .llong
 #define FTR_ENTRY_OFFSET       .long 0xffffffff; .long
+#elif defined(CONFIG_PPC64)
+#define FTR_ENTRY_LONG         .llong
+#define FTR_ENTRY_OFFSET       .llong
 #else
-/* 64 bit kernel 64 bit code, or 32 bit kernel 32 bit code */
-#define FTR_ENTRY_LONG         PPC_LONG
-#define FTR_ENTRY_OFFSET       PPC_LONG
+#define FTR_ENTRY_LONG         .long
+#define FTR_ENTRY_OFFSET       .long
 #endif
 
 #define START_FTR_SECTION(label)       label##1:
@@ -141,6 +141,21 @@ label##5:                                          \
 #define ALT_FW_FTR_SECTION_END_IFCLR(msk)      \
        ALT_FW_FTR_SECTION_END_NESTED_IFCLR(msk, 97)
 
+#ifndef __ASSEMBLY__
+
+#define ASM_MMU_FTR_IF(section_if, section_else, msk, val)     \
+       stringify_in_c(BEGIN_MMU_FTR_SECTION)                   \
+       section_if "; "                                         \
+       stringify_in_c(MMU_FTR_SECTION_ELSE)                    \
+       section_else "; "                                       \
+       stringify_in_c(ALT_MMU_FTR_SECTION_END((msk), (val)))
+
+#define ASM_MMU_FTR_IFSET(section_if, section_else, msk)       \
+       ASM_MMU_FTR_IF(section_if, section_else, (msk), (msk))
+
+#define ASM_MMU_FTR_IFCLR(section_if, section_else, msk)       \
+       ASM_MMU_FTR_IF(section_if, section_else, (msk), 0)
+
 #endif /* __ASSEMBLY__ */
 
 /* LWSYNC feature sections */
index d2a65e8ca6ae08df08c17626dfa4acaf2d6103d9..f78f65c38f054d8d7f56fafee268c33d793a62c4 100644 (file)
 #define _ASM_POWERPC_LPPACA_H
 #ifdef __KERNEL__
 
+/* These definitions relate to hypervisors that only exist when using
+ * a server type processor
+ */
+#ifdef CONFIG_PPC_BOOK3S
+
 //=============================================================================
 //
 //     This control block contains the data that is shared between the
@@ -158,5 +163,6 @@ struct slb_shadow {
 
 extern struct slb_shadow slb_shadow[];
 
+#endif /* CONFIG_PPC_BOOK3S */
 #endif /* __KERNEL__ */
 #endif /* _ASM_POWERPC_LPPACA_H */
index 0efdb1dfdc5f577ea336d4a96fd8dd246d703514..11d1fc3a89629ae39d685e5d450a2f29160d3c56 100644 (file)
@@ -110,6 +110,10 @@ struct machdep_calls {
        void            (*show_percpuinfo)(struct seq_file *m, int i);
 
        void            (*init_IRQ)(void);
+
+       /* Return an irq, or NO_IRQ to indicate there are none pending.
+        * If for some reason there is no irq, but the interrupt
+        * shouldn't be counted as spurious, return NO_IRQ_IGNORE. */
        unsigned int    (*get_irq)(void);
 #ifdef CONFIG_KEXEC
        void            (*kexec_cpu_down)(int crash_shutdown, int secondary);
index cbf154387091542e24dbf47926e9b5a5e9a5d34a..fb57ded592f9f1b8ccdb6affbd245e7425159309 100644 (file)
  */
 #define MMU_FTR_NEED_DTLB_SW_LRU       ASM_CONST(0x00200000)
 
+/* This indicates that the processor uses the ISA 2.06 server tlbie
+ * mnemonics
+ */
+#define MMU_FTR_TLBIE_206              ASM_CONST(0x00400000)
+
 #ifndef __ASSEMBLY__
 #include <asm/cputable.h>
 
@@ -69,10 +74,10 @@ extern void early_init_mmu_secondary(void);
 #endif /* !__ASSEMBLY__ */
 
 
-#ifdef CONFIG_PPC64
+#if defined(CONFIG_PPC_STD_MMU_64)
 /* 64-bit classic hash table MMU */
 #  include <asm/mmu-hash64.h>
-#elif defined(CONFIG_PPC_STD_MMU)
+#elif defined(CONFIG_PPC_STD_MMU_32)
 /* 32-bit classic hash table MMU */
 #  include <asm/mmu-hash32.h>
 #elif defined(CONFIG_40x)
diff --git a/arch/powerpc/include/asm/mpc86xx.h b/arch/powerpc/include/asm/mpc86xx.h
deleted file mode 100644 (file)
index 15f650f..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * MPC86xx definitions
- *
- * Author: Jeff Brown
- *
- * Copyright 2004 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.
- */
-
-#ifdef __KERNEL__
-#ifndef __ASM_POWERPC_MPC86xx_H__
-#define __ASM_POWERPC_MPC86xx_H__
-
-#include <asm/mmu.h>
-
-#ifdef CONFIG_PPC_86xx
-
-#define CPU0_BOOT_RELEASE 0x01000000
-#define CPU1_BOOT_RELEASE 0x02000000
-#define CPU_ALL_RELEASED (CPU0_BOOT_RELEASE | CPU1_BOOT_RELEASE)
-#define MCM_PORT_CONFIG_OFFSET 0x1010
-
-/* Offset from CCSRBAR */
-#define MPC86xx_MCM_OFFSET      (0x00000)
-#define MPC86xx_MCM_SIZE        (0x02000)
-
-#endif /* CONFIG_PPC_86xx */
-#endif /* __ASM_POWERPC_MPC86xx_H__ */
-#endif /* __KERNEL__ */
index 6ef055723019f3048cb14866b8eedddce179ba04..c8a3cbfe02ffaea0bca9be6d35a9fa8ef218bf18 100644 (file)
@@ -43,6 +43,7 @@ struct task_struct;
  * processor.
  */
 struct paca_struct {
+#ifdef CONFIG_PPC_BOOK3S
        /*
         * Because hw_cpu_id, unlike other paca fields, is accessed
         * routinely from other CPUs (from the IRQ code), we stick to
@@ -51,7 +52,7 @@ struct paca_struct {
         */
 
        struct lppaca *lppaca_ptr;      /* Pointer to LpPaca for PLIC */
-
+#endif /* CONFIG_PPC_BOOK3S */
        /*
         * MAGIC: the spinlock functions in arch/powerpc/lib/locks.c 
         * load lock_token and paca_index with a single lwz
@@ -64,13 +65,16 @@ struct paca_struct {
        u64 kernel_toc;                 /* Kernel TOC address */
        u64 kernelbase;                 /* Base address of kernel */
        u64 kernel_msr;                 /* MSR while running in kernel */
+#ifdef CONFIG_PPC_STD_MMU_64
        u64 stab_real;                  /* Absolute address of segment table */
        u64 stab_addr;                  /* Virtual address of segment table */
+#endif /* CONFIG_PPC_STD_MMU_64 */
        void *emergency_sp;             /* pointer to emergency stack */
        u64 data_offset;                /* per cpu data offset */
        s16 hw_cpu_id;                  /* Physical processor number */
        u8 cpu_start;                   /* At startup, processor spins until */
                                        /* this becomes non-zero. */
+#ifdef CONFIG_PPC_STD_MMU_64
        struct slb_shadow *slb_shadow_ptr;
 
        /*
@@ -81,11 +85,13 @@ struct paca_struct {
        u64 exmc[10];           /* used for machine checks */
        u64 exslb[10];          /* used for SLB/segment table misses
                                 * on the linear mapping */
-
-       mm_context_t context;
+       /* SLB related definitions */
        u16 vmalloc_sllp;
        u16 slb_cache_ptr;
        u16 slb_cache[SLB_CACHE_ENTRIES];
+#endif /* CONFIG_PPC_STD_MMU_64 */
+
+       mm_context_t context;
 
        /*
         * then miscellaneous read-write fields
index 32cbf16f10eac9090640bbb9c8d4033870989892..4940662ee87ef09c512d46c437ed0e848e51a2d3 100644 (file)
@@ -231,6 +231,11 @@ extern void copy_user_page(void *to, void *from, unsigned long vaddr,
                struct page *p);
 extern int page_is_ram(unsigned long pfn);
 
+#ifdef CONFIG_PPC_SMLPAR
+void arch_free_page(struct page *page, int order);
+#define HAVE_ARCH_FREE_PAGE
+#endif
+
 struct vm_area_struct;
 
 typedef struct page *pgtable_t;
index 84007afabdb52a307d0f0a34fb7c8877091eb79a..4c61fa0b8d75f946bdd5de16ac72fc947c90e7fd 100644 (file)
@@ -86,17 +86,12 @@ struct pci_controller {
        void *io_base_alloc;
 #endif
        resource_size_t io_base_phys;
-#ifndef CONFIG_PPC64
        resource_size_t pci_io_size;
-#endif
 
        /* Some machines (PReP) have a non 1:1 mapping of
         * the PCI memory space in the CPU bus space
         */
        resource_size_t pci_mem_offset;
-#ifdef CONFIG_PPC64
-       unsigned long pci_io_size;
-#endif
 
        /* Some machines have a special region to forward the ISA
         * "memory" cycles such as VGA memory regions. Left to 0
@@ -140,10 +135,12 @@ struct pci_controller {
        struct resource io_resource;
        struct resource mem_resources[3];
        int global_number;              /* PCI domain number */
+
+       resource_size_t dma_window_base_cur;
+       resource_size_t dma_window_size;
+
 #ifdef CONFIG_PPC64
        unsigned long buid;
-       unsigned long dma_window_base_cur;
-       unsigned long dma_window_size;
 
        void *private_data;
 #endif /* CONFIG_PPC64 */
@@ -185,7 +182,6 @@ extern int early_find_capability(struct pci_controller *hose, int bus,
 extern void setup_indirect_pci(struct pci_controller* hose,
                               resource_size_t cfg_addr,
                               resource_size_t cfg_data, u32 flags);
-extern void setup_grackle(struct pci_controller *hose);
 #else  /* CONFIG_PPC64 */
 
 /*
@@ -221,6 +217,7 @@ struct pci_dn {
 #define PCI_DN(dn)     ((struct pci_dn *) (dn)->data)
 
 extern struct device_node *fetch_dev_dn(struct pci_dev *dev);
+extern void * update_dn_pci_info(struct device_node *dn, void *data);
 
 /* Get a device_node from a pci_dev.  This code must be fast except
  * in the case where the sysdata is incorrect and needs to be fixed
index c40db05f21e000a3682bf5a828ede9612cb710ec..8cd083c6150384eeca4c28a38d5a49e643efab1a 100644 (file)
 #error TASK_SIZE_USER64 exceeds pagetable range
 #endif
 
+#ifdef CONFIG_PPC_STD_MMU_64
 #if TASK_SIZE_USER64 > (1UL << (USER_ESID_BITS + SID_SHIFT))
 #error TASK_SIZE_USER64 exceeds user VSID range
 #endif
+#endif
 
 /*
  * Define the address range of the vmalloc VM area.
@@ -199,8 +201,11 @@ static inline unsigned long pte_update(struct mm_struct *mm,
        if (!huge)
                assert_pte_locked(mm, addr);
 
+#ifdef CONFIG_PPC_STD_MMU_64
        if (old & _PAGE_HASHPTE)
                hpte_need_flush(mm, addr, ptep, old, huge);
+#endif
+
        return old;
 }
 
index 640ccbbc0977a9fb57812b937157ba72651ab633..b74f16d45cb45f7945687003c399379730098f5f 100644 (file)
@@ -25,6 +25,7 @@
 #define PPC_INST_LSWI                  0x7c0004aa
 #define PPC_INST_LSWX                  0x7c00042a
 #define PPC_INST_LWSYNC                        0x7c2004ac
+#define PPC_INST_LXVD2X                        0x7c000698
 #define PPC_INST_MCRXR                 0x7c000400
 #define PPC_INST_MCRXR_MASK            0xfc0007fe
 #define PPC_INST_MFSPR_PVR             0x7c1f42a6
 
 #define PPC_INST_STSWI                 0x7c0005aa
 #define PPC_INST_STSWX                 0x7c00052a
+#define PPC_INST_STXVD2X               0x7c000798
+#define PPC_INST_TLBIE                 0x7c000264
 #define PPC_INST_TLBILX                        0x7c000024
 #define PPC_INST_WAIT                  0x7c00007c
 
 /* macros to insert fields into opcodes */
-#define __PPC_RA(a)    ((a & 0x1f) << 16)
-#define __PPC_RB(b)    ((b & 0x1f) << 11)
-#define __PPC_T_TLB(t) ((t & 0x3) << 21)
-#define __PPC_WC(w)    ((w & 0x3) << 21)
+#define __PPC_RA(a)    (((a) & 0x1f) << 16)
+#define __PPC_RB(b)    (((b) & 0x1f) << 11)
+#define __PPC_RS(s)    (((s) & 0x1f) << 21)
+#define __PPC_XS(s)    ((((s) & 0x1f) << 21) | (((s) & 0x20) >> 5))
+#define __PPC_T_TLB(t) (((t) & 0x3) << 21)
+#define __PPC_WC(w)    (((w) & 0x3) << 21)
 
 /* Deal with instructions that older assemblers aren't aware of */
 #define        PPC_DCBAL(a, b)         stringify_in_c(.long PPC_INST_DCBAL | \
 #define PPC_TLBILX_VA(a, b)    PPC_TLBILX(3, a, b)
 #define PPC_WAIT(w)            stringify_in_c(.long PPC_INST_WAIT | \
                                        __PPC_WC(w))
+#define PPC_TLBIE(lp,a)        stringify_in_c(.long PPC_INST_TLBIE | \
+                                              __PPC_RB(a) | __PPC_RS(lp))
+
+/*
+ * Define what the VSX XX1 form instructions will look like, then add
+ * the 128 bit load store instructions based on that.
+ */
+#define VSX_XX1(s, a, b)       (__PPC_XS(s) | __PPC_RA(a) | __PPC_RB(b))
+#define STXVD2X(s, a, b)       stringify_in_c(.long PPC_INST_STXVD2X | \
+                                              VSX_XX1((s), (a), (b)))
+#define LXVD2X(s, a, b)                stringify_in_c(.long PPC_INST_LXVD2X | \
+                                              VSX_XX1((s), (a), (b)))
 
 #endif /* _ASM_POWERPC_PPC_OPCODE_H */
index 384d90c9c272dda067b99ff4474c7194c6247c41..f9729529c20d2a2339951216cf9ed565c73491a6 100644 (file)
@@ -76,16 +76,6 @@ END_FTR_SECTION_IFCLR(CPU_FTR_PURR);                                 \
                                REST_10GPRS(22, base)
 #endif
 
-/*
- * Define what the VSX XX1 form instructions will look like, then add
- * the 128 bit load store instructions based on that.
- */
-#define VSX_XX1(xs, ra, rb)    (((xs) & 0x1f) << 21 | ((ra) << 16) |  \
-                                ((rb) << 11) | (((xs) >> 5)))
-
-#define STXVD2X(xs, ra, rb)    .long (0x7c000798 | VSX_XX1((xs), (ra), (rb)))
-#define LXVD2X(xs, ra, rb)     .long (0x7c000698 | VSX_XX1((xs), (ra), (rb)))
-
 #define SAVE_2GPRS(n, base)    SAVE_GPR(n, base); SAVE_GPR(n+1, base)
 #define SAVE_4GPRS(n, base)    SAVE_2GPRS(n, base); SAVE_2GPRS(n+2, base)
 #define SAVE_8GPRS(n, base)    SAVE_4GPRS(n, base); SAVE_4GPRS(n+4, base)
index c9c678fb2538d9e4f1c17cb54476663d8305485b..8c341490cfc5a9843719bb50a4590d3df24b024c 100644 (file)
@@ -135,7 +135,9 @@ do {                                                                              \
  * These are defined as per linux/ptrace.h, which see.
  */
 #define arch_has_single_step() (1)
+#define arch_has_block_step()  (!cpu_has_feature(CPU_FTR_601))
 extern void user_enable_single_step(struct task_struct *);
+extern void user_enable_block_step(struct task_struct *);
 extern void user_disable_single_step(struct task_struct *);
 
 #endif /* __ASSEMBLY__ */
@@ -288,4 +290,6 @@ extern void user_disable_single_step(struct task_struct *);
 #define PPC_PTRACE_PEEKUSR_3264  0x91
 #define PPC_PTRACE_POKEUSR_3264  0x90
 
+#define PTRACE_SINGLEBLOCK     0x100   /* resume execution until next branch */
+
 #endif /* _ASM_POWERPC_PTRACE_H */
index 2701753d9937513ee78b995893d8857da7710479..157c5ca581c8208b245c153e62f5804137ceda05 100644 (file)
@@ -22,7 +22,7 @@
 #include <asm/cpm.h>
 #include <asm/immap_qe.h>
 
-#define QE_NUM_OF_SNUM 28
+#define QE_NUM_OF_SNUM 256     /* There are 256 serial number in QE */
 #define QE_NUM_OF_BRGS 16
 #define QE_NUM_OF_PORTS        1024
 
@@ -152,6 +152,9 @@ unsigned int qe_get_brg_clk(void);
 int qe_setbrg(enum qe_clock brg, unsigned int rate, unsigned int multiplier);
 int qe_get_snum(void);
 void qe_put_snum(u8 snum);
+unsigned int qe_get_num_of_risc(void);
+unsigned int qe_get_num_of_snums(void);
+
 /* we actually use cpm_muram implementation, define this for convenience */
 #define qe_muram_init cpm_muram_init
 #define qe_muram_alloc cpm_muram_alloc
@@ -231,12 +234,16 @@ struct qe_bd {
 #define QE_ALIGNMENT_OF_PRAM   64
 
 /* RISC allocation */
-enum qe_risc_allocation {
-       QE_RISC_ALLOCATION_RISC1 = 1,   /* RISC 1 */
-       QE_RISC_ALLOCATION_RISC2 = 2,   /* RISC 2 */
-       QE_RISC_ALLOCATION_RISC1_AND_RISC2 = 3  /* Dynamically choose
-                                                  RISC 1 or RISC 2 */
-};
+#define QE_RISC_ALLOCATION_RISC1       0x1  /* RISC 1 */
+#define QE_RISC_ALLOCATION_RISC2       0x2  /* RISC 2 */
+#define QE_RISC_ALLOCATION_RISC3       0x4  /* RISC 3 */
+#define QE_RISC_ALLOCATION_RISC4       0x8  /* RISC 4 */
+#define QE_RISC_ALLOCATION_RISC1_AND_RISC2     (QE_RISC_ALLOCATION_RISC1 | \
+                                                QE_RISC_ALLOCATION_RISC2)
+#define QE_RISC_ALLOCATION_FOUR_RISCS  (QE_RISC_ALLOCATION_RISC1 | \
+                                        QE_RISC_ALLOCATION_RISC2 | \
+                                        QE_RISC_ALLOCATION_RISC3 | \
+                                        QE_RISC_ALLOCATION_RISC4)
 
 /* QE extended filtering Table Lookup Key Size */
 enum qe_fltr_tbl_lookup_key_size {
@@ -668,6 +675,8 @@ struct ucc_slow_pram {
 #define UCC_GETH_UPSMR_RMM      0x00001000
 #define UCC_GETH_UPSMR_CAM      0x00000400
 #define UCC_GETH_UPSMR_BRO      0x00000200
+#define UCC_GETH_UPSMR_SMM     0x00000080
+#define UCC_GETH_UPSMR_SGMM    0x00000020
 
 /* UCC Transmit On Demand Register (UTODR) */
 #define UCC_SLOW_TOD   0x8000
index fcf7d55afe4599e3049713156145997fa066e1e3..912bf597870f700188e907c7f424557108a86624 100644 (file)
@@ -21,7 +21,7 @@ struct scatterlist {
        unsigned int offset;
        unsigned int length;
 
-       /* For TCE support */
+       /* For TCE or SWIOTLB support */
        dma_addr_t dma_address;
        u32 dma_length;
 };
@@ -34,11 +34,7 @@ struct scatterlist {
  * is 0.
  */
 #define sg_dma_address(sg)     ((sg)->dma_address)
-#ifdef __powerpc64__
 #define sg_dma_len(sg)         ((sg)->dma_length)
-#else
-#define sg_dma_len(sg)         ((sg)->length)
-#endif
 
 #ifdef __powerpc64__
 #define ISA_DMA_THRESHOLD      (~0UL)
diff --git a/arch/powerpc/include/asm/swiotlb.h b/arch/powerpc/include/asm/swiotlb.h
new file mode 100644 (file)
index 0000000..30891d6
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2009 Becky Bruce, Freescale Semiconductor
+ *
+ * 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 __ASM_SWIOTLB_H
+#define __ASM_SWIOTLB_H
+
+#include <linux/swiotlb.h>
+
+extern struct dma_mapping_ops swiotlb_dma_ops;
+extern struct dma_mapping_ops swiotlb_pci_dma_ops;
+
+int swiotlb_arch_address_needs_mapping(struct device *, dma_addr_t,
+                                      size_t size);
+
+static inline void dma_mark_clean(void *addr, size_t size) {}
+
+extern unsigned int ppc_swiotlb_enable;
+int __init swiotlb_setup_bus_notifier(void);
+
+#endif /* __ASM_SWIOTLB_H */
index 2b2420a498843245dc5ec32e1a16496e5bd7561a..bb8e006a47c67655d9f68d2608abd438e0e21d48 100644 (file)
@@ -211,7 +211,7 @@ extern struct task_struct *_switch(struct thread_struct *prev,
 
 extern unsigned int rtas_data;
 extern int mem_init_done;      /* set on boot once kmalloc can be called */
-extern int init_bootmem_done;  /* set on !NUMA once bootmem is available */
+extern int init_bootmem_done;  /* set once bootmem is available */
 extern phys_addr_t memory_limit;
 extern unsigned long klimit;
 
diff --git a/arch/powerpc/include/asm/xilinx_pci.h b/arch/powerpc/include/asm/xilinx_pci.h
new file mode 100644 (file)
index 0000000..7a8275c
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Xilinx pci external definitions
+ *
+ * Copyright 2009 Roderick Colenbrander
+ * Copyright 2009 Secret Lab Technologies Ltd.
+ *
+ * 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 INCLUDE_XILINX_PCI
+#define INCLUDE_XILINX_PCI
+
+#ifdef CONFIG_XILINX_PCI
+extern void __init xilinx_pci_init(void);
+#else
+static inline void __init xilinx_pci_init(void) { return; }
+#endif
+
+#endif /* INCLUDE_XILINX_PCI */
index a2c683403c2bea4a76d8d946cfb673b4526687dc..a7def5f90cadbe2392b7ecfd6aa65f80570b1014 100644 (file)
@@ -36,7 +36,7 @@ obj-$(CONFIG_PPC64)           += setup_64.o sys_ppc32.o \
                                   firmware.o nvram_64.o
 obj64-$(CONFIG_RELOCATABLE)    += reloc_64.o
 obj-$(CONFIG_PPC64)            += vdso64/
-obj-$(CONFIG_ALTIVEC)          += vecemu.o vector.o
+obj-$(CONFIG_ALTIVEC)          += vecemu.o
 obj-$(CONFIG_PPC_970_NAP)      += idle_power4.o
 obj-$(CONFIG_PPC_OF)           += of_device.o of_platform.o prom_parse.o
 obj-$(CONFIG_PPC_CLOCK)                += clock.o
@@ -82,6 +82,7 @@ obj-$(CONFIG_SMP)             += smp.o
 obj-$(CONFIG_KPROBES)          += kprobes.o
 obj-$(CONFIG_PPC_UDBG_16550)   += legacy_serial.o udbg_16550.o
 obj-$(CONFIG_STACKTRACE)       += stacktrace.o
+obj-$(CONFIG_SWIOTLB)          += dma-swiotlb.o
 
 pci64-$(CONFIG_PPC64)          += pci_dn.o isa-bridge.o
 obj-$(CONFIG_PCI)              += pci_$(CONFIG_WORD_SIZE).o $(pci64-y) \
@@ -111,6 +112,7 @@ obj-y                               += ppc_save_regs.o
 endif
 
 extra-$(CONFIG_PPC_FPU)                += fpu.o
+extra-$(CONFIG_ALTIVEC)                += vector.o
 extra-$(CONFIG_PPC64)          += entry_64.o
 
 extra-y                                += systbl_chk.i
index 5ffcfaa77d6acf49d9902e2ab2aed650ab1fdc85..a5b632e52faea9dab9c63921430d572ca1e9f0f2 100644 (file)
@@ -24,6 +24,7 @@
 #include <asm/system.h>
 #include <asm/cache.h>
 #include <asm/cputable.h>
+#include <asm/emulated_ops.h>
 
 struct aligninfo {
        unsigned char len;
@@ -730,8 +731,10 @@ int fix_alignment(struct pt_regs *regs)
        areg = dsisr & 0x1f;            /* register to update */
 
 #ifdef CONFIG_SPE
-       if ((instr >> 26) == 0x4)
+       if ((instr >> 26) == 0x4) {
+               PPC_WARN_EMULATED(spe);
                return emulate_spe(regs, reg, instr);
+       }
 #endif
 
        instr = (dsisr >> 10) & 0x7f;
@@ -783,23 +786,28 @@ int fix_alignment(struct pt_regs *regs)
                        flags |= SPLT;
                        nb = 8;
                }
+               PPC_WARN_EMULATED(vsx);
                return emulate_vsx(addr, reg, areg, regs, flags, nb);
        }
 #endif
        /* A size of 0 indicates an instruction we don't support, with
         * the exception of DCBZ which is handled as a special case here
         */
-       if (instr == DCBZ)
+       if (instr == DCBZ) {
+               PPC_WARN_EMULATED(dcbz);
                return emulate_dcbz(regs, addr);
+       }
        if (unlikely(nb == 0))
                return 0;
 
        /* Load/Store Multiple instructions are handled in their own
         * function
         */
-       if (flags & M)
+       if (flags & M) {
+               PPC_WARN_EMULATED(multiple);
                return emulate_multiple(regs, addr, reg, nb,
                                        flags, instr, swiz);
+       }
 
        /* Verify the address of the operand */
        if (unlikely(user_mode(regs) &&
@@ -816,8 +824,12 @@ int fix_alignment(struct pt_regs *regs)
        }
 
        /* Special case for 16-byte FP loads and stores */
-       if (nb == 16)
+       if (nb == 16) {
+               PPC_WARN_EMULATED(fp_pair);
                return emulate_fp_pair(addr, reg, flags);
+       }
+
+       PPC_WARN_EMULATED(unaligned);
 
        /* If we are loading, get the data from user space, else
         * get it from register values
index e981d1ce1914b20994be3d63d2e0d5acba86deda..561b6465231105073ef991300d6aab206e1e0531 100644 (file)
@@ -122,8 +122,6 @@ int main(void)
        DEFINE(PACAKSAVE, offsetof(struct paca_struct, kstack));
        DEFINE(PACACURRENT, offsetof(struct paca_struct, __current));
        DEFINE(PACASAVEDMSR, offsetof(struct paca_struct, saved_msr));
-       DEFINE(PACASTABREAL, offsetof(struct paca_struct, stab_real));
-       DEFINE(PACASTABVIRT, offsetof(struct paca_struct, stab_addr));
        DEFINE(PACASTABRR, offsetof(struct paca_struct, stab_rr));
        DEFINE(PACAR1, offsetof(struct paca_struct, saved_r1));
        DEFINE(PACATOC, offsetof(struct paca_struct, kernel_toc));
@@ -132,35 +130,30 @@ int main(void)
        DEFINE(PACASOFTIRQEN, offsetof(struct paca_struct, soft_enabled));
        DEFINE(PACAHARDIRQEN, offsetof(struct paca_struct, hard_enabled));
        DEFINE(PACAPERFPEND, offsetof(struct paca_struct, perf_counter_pending));
-       DEFINE(PACASLBCACHE, offsetof(struct paca_struct, slb_cache));
-       DEFINE(PACASLBCACHEPTR, offsetof(struct paca_struct, slb_cache_ptr));
        DEFINE(PACACONTEXTID, offsetof(struct paca_struct, context.id));
-       DEFINE(PACAVMALLOCSLLP, offsetof(struct paca_struct, vmalloc_sllp));
 #ifdef CONFIG_PPC_MM_SLICES
        DEFINE(PACALOWSLICESPSIZE, offsetof(struct paca_struct,
                                            context.low_slices_psize));
        DEFINE(PACAHIGHSLICEPSIZE, offsetof(struct paca_struct,
                                            context.high_slices_psize));
        DEFINE(MMUPSIZEDEFSIZE, sizeof(struct mmu_psize_def));
+#endif /* CONFIG_PPC_MM_SLICES */
+#ifdef CONFIG_PPC_STD_MMU_64
+       DEFINE(PACASTABREAL, offsetof(struct paca_struct, stab_real));
+       DEFINE(PACASTABVIRT, offsetof(struct paca_struct, stab_addr));
+       DEFINE(PACASLBCACHE, offsetof(struct paca_struct, slb_cache));
+       DEFINE(PACASLBCACHEPTR, offsetof(struct paca_struct, slb_cache_ptr));
+       DEFINE(PACAVMALLOCSLLP, offsetof(struct paca_struct, vmalloc_sllp));
+#ifdef CONFIG_PPC_MM_SLICES
        DEFINE(MMUPSIZESLLP, offsetof(struct mmu_psize_def, sllp));
 #else
        DEFINE(PACACONTEXTSLLP, offsetof(struct paca_struct, context.sllp));
-
 #endif /* CONFIG_PPC_MM_SLICES */
        DEFINE(PACA_EXGEN, offsetof(struct paca_struct, exgen));
        DEFINE(PACA_EXMC, offsetof(struct paca_struct, exmc));
        DEFINE(PACA_EXSLB, offsetof(struct paca_struct, exslb));
-       DEFINE(PACAEMERGSP, offsetof(struct paca_struct, emergency_sp));
        DEFINE(PACALPPACAPTR, offsetof(struct paca_struct, lppaca_ptr));
-       DEFINE(PACAHWCPUID, offsetof(struct paca_struct, hw_cpu_id));
-       DEFINE(PACA_STARTPURR, offsetof(struct paca_struct, startpurr));
-       DEFINE(PACA_STARTSPURR, offsetof(struct paca_struct, startspurr));
-       DEFINE(PACA_USER_TIME, offsetof(struct paca_struct, user_time));
-       DEFINE(PACA_SYSTEM_TIME, offsetof(struct paca_struct, system_time));
        DEFINE(PACA_SLBSHADOWPTR, offsetof(struct paca_struct, slb_shadow_ptr));
-       DEFINE(PACA_DATA_OFFSET, offsetof(struct paca_struct, data_offset));
-       DEFINE(PACA_TRAP_SAVE, offsetof(struct paca_struct, trap_save));
-
        DEFINE(SLBSHADOW_STACKVSID,
               offsetof(struct slb_shadow, save_area[SLB_NUM_BOLTED - 1].vsid));
        DEFINE(SLBSHADOW_STACKESID,
@@ -170,6 +163,15 @@ int main(void)
        DEFINE(LPPACAANYINT, offsetof(struct lppaca, int_dword.any_int));
        DEFINE(LPPACADECRINT, offsetof(struct lppaca, int_dword.fields.decr_int));
        DEFINE(SLBSHADOW_SAVEAREA, offsetof(struct slb_shadow, save_area));
+#endif /* CONFIG_PPC_STD_MMU_64 */
+       DEFINE(PACAEMERGSP, offsetof(struct paca_struct, emergency_sp));
+       DEFINE(PACAHWCPUID, offsetof(struct paca_struct, hw_cpu_id));
+       DEFINE(PACA_STARTPURR, offsetof(struct paca_struct, startpurr));
+       DEFINE(PACA_STARTSPURR, offsetof(struct paca_struct, startspurr));
+       DEFINE(PACA_USER_TIME, offsetof(struct paca_struct, user_time));
+       DEFINE(PACA_SYSTEM_TIME, offsetof(struct paca_struct, system_time));
+       DEFINE(PACA_DATA_OFFSET, offsetof(struct paca_struct, data_offset));
+       DEFINE(PACA_TRAP_SAVE, offsetof(struct paca_struct, trap_save));
 #endif /* CONFIG_PPC64 */
 
        /* RTAS */
index 3e33fb933d991e885172675687e75195f5e52b57..4a24a2fc45740fc5b0622ec35c7550247be7f457 100644 (file)
@@ -427,7 +427,8 @@ static struct cpu_spec __initdata cpu_specs[] = {
                .cpu_name               = "POWER7 (architected)",
                .cpu_features           = CPU_FTRS_POWER7,
                .cpu_user_features      = COMMON_USER_POWER7,
-               .mmu_features           = MMU_FTR_HPTE_TABLE,
+               .mmu_features           = MMU_FTR_HPTE_TABLE |
+                       MMU_FTR_TLBIE_206,
                .icache_bsize           = 128,
                .dcache_bsize           = 128,
                .machine_check          = machine_check_generic,
@@ -441,7 +442,8 @@ static struct cpu_spec __initdata cpu_specs[] = {
                .cpu_name               = "POWER7 (raw)",
                .cpu_features           = CPU_FTRS_POWER7,
                .cpu_user_features      = COMMON_USER_POWER7,
-               .mmu_features           = MMU_FTR_HPTE_TABLE,
+               .mmu_features           = MMU_FTR_HPTE_TABLE |
+                       MMU_FTR_TLBIE_206,
                .icache_bsize           = 128,
                .dcache_bsize           = 128,
                .num_pmcs               = 6,
diff --git a/arch/powerpc/kernel/dma-swiotlb.c b/arch/powerpc/kernel/dma-swiotlb.c
new file mode 100644 (file)
index 0000000..68ccf11
--- /dev/null
@@ -0,0 +1,163 @@
+/*
+ * Contains routines needed to support swiotlb for ppc.
+ *
+ * Copyright (C) 2009 Becky Bruce, Freescale Semiconductor
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ *
+ */
+
+#include <linux/dma-mapping.h>
+#include <linux/pfn.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/pci.h>
+
+#include <asm/machdep.h>
+#include <asm/swiotlb.h>
+#include <asm/dma.h>
+#include <asm/abs_addr.h>
+
+int swiotlb __read_mostly;
+unsigned int ppc_swiotlb_enable;
+
+void *swiotlb_bus_to_virt(struct device *hwdev, dma_addr_t addr)
+{
+       unsigned long pfn = PFN_DOWN(swiotlb_bus_to_phys(hwdev, addr));
+       void *pageaddr = page_address(pfn_to_page(pfn));
+
+       if (pageaddr != NULL)
+               return pageaddr + (addr % PAGE_SIZE);
+       return NULL;
+}
+
+dma_addr_t swiotlb_phys_to_bus(struct device *hwdev, phys_addr_t paddr)
+{
+       return paddr + get_dma_direct_offset(hwdev);
+}
+
+phys_addr_t swiotlb_bus_to_phys(struct device *hwdev, dma_addr_t baddr)
+
+{
+       return baddr - get_dma_direct_offset(hwdev);
+}
+
+/*
+ * Determine if an address needs bounce buffering via swiotlb.
+ * Going forward I expect the swiotlb code to generalize on using
+ * a dma_ops->addr_needs_map, and this function will move from here to the
+ * generic swiotlb code.
+ */
+int
+swiotlb_arch_address_needs_mapping(struct device *hwdev, dma_addr_t addr,
+                                  size_t size)
+{
+       struct dma_mapping_ops *dma_ops = get_dma_ops(hwdev);
+
+       BUG_ON(!dma_ops);
+       return dma_ops->addr_needs_map(hwdev, addr, size);
+}
+
+/*
+ * Determine if an address is reachable by a pci device, or if we must bounce.
+ */
+static int
+swiotlb_pci_addr_needs_map(struct device *hwdev, dma_addr_t addr, size_t size)
+{
+       u64 mask = dma_get_mask(hwdev);
+       dma_addr_t max;
+       struct pci_controller *hose;
+       struct pci_dev *pdev = to_pci_dev(hwdev);
+
+       hose = pci_bus_to_host(pdev->bus);
+       max = hose->dma_window_base_cur + hose->dma_window_size;
+
+       /* check that we're within mapped pci window space */
+       if ((addr + size > max) | (addr < hose->dma_window_base_cur))
+               return 1;
+
+       return !is_buffer_dma_capable(mask, addr, size);
+}
+
+static int
+swiotlb_addr_needs_map(struct device *hwdev, dma_addr_t addr, size_t size)
+{
+       return !is_buffer_dma_capable(dma_get_mask(hwdev), addr, size);
+}
+
+
+/*
+ * At the moment, all platforms that use this code only require
+ * swiotlb to be used if we're operating on HIGHMEM.  Since
+ * we don't ever call anything other than map_sg, unmap_sg,
+ * map_page, and unmap_page on highmem, use normal dma_ops
+ * for everything else.
+ */
+struct dma_mapping_ops swiotlb_dma_ops = {
+       .alloc_coherent = dma_direct_alloc_coherent,
+       .free_coherent = dma_direct_free_coherent,
+       .map_sg = swiotlb_map_sg_attrs,
+       .unmap_sg = swiotlb_unmap_sg_attrs,
+       .dma_supported = swiotlb_dma_supported,
+       .map_page = swiotlb_map_page,
+       .unmap_page = swiotlb_unmap_page,
+       .addr_needs_map = swiotlb_addr_needs_map,
+       .sync_single_range_for_cpu = swiotlb_sync_single_range_for_cpu,
+       .sync_single_range_for_device = swiotlb_sync_single_range_for_device,
+       .sync_sg_for_cpu = swiotlb_sync_sg_for_cpu,
+       .sync_sg_for_device = swiotlb_sync_sg_for_device
+};
+
+struct dma_mapping_ops swiotlb_pci_dma_ops = {
+       .alloc_coherent = dma_direct_alloc_coherent,
+       .free_coherent = dma_direct_free_coherent,
+       .map_sg = swiotlb_map_sg_attrs,
+       .unmap_sg = swiotlb_unmap_sg_attrs,
+       .dma_supported = swiotlb_dma_supported,
+       .map_page = swiotlb_map_page,
+       .unmap_page = swiotlb_unmap_page,
+       .addr_needs_map = swiotlb_pci_addr_needs_map,
+       .sync_single_range_for_cpu = swiotlb_sync_single_range_for_cpu,
+       .sync_single_range_for_device = swiotlb_sync_single_range_for_device,
+       .sync_sg_for_cpu = swiotlb_sync_sg_for_cpu,
+       .sync_sg_for_device = swiotlb_sync_sg_for_device
+};
+
+static int ppc_swiotlb_bus_notify(struct notifier_block *nb,
+                                 unsigned long action, void *data)
+{
+       struct device *dev = data;
+
+       /* We are only intereted in device addition */
+       if (action != BUS_NOTIFY_ADD_DEVICE)
+               return 0;
+
+       /* May need to bounce if the device can't address all of DRAM */
+       if (dma_get_mask(dev) < lmb_end_of_DRAM())
+               set_dma_ops(dev, &swiotlb_dma_ops);
+
+       return NOTIFY_DONE;
+}
+
+static struct notifier_block ppc_swiotlb_plat_bus_notifier = {
+       .notifier_call = ppc_swiotlb_bus_notify,
+       .priority = 0,
+};
+
+static struct notifier_block ppc_swiotlb_of_bus_notifier = {
+       .notifier_call = ppc_swiotlb_bus_notify,
+       .priority = 0,
+};
+
+int __init swiotlb_setup_bus_notifier(void)
+{
+       bus_register_notifier(&platform_bus_type,
+                             &ppc_swiotlb_plat_bus_notifier);
+       bus_register_notifier(&of_platform_bus_type,
+                             &ppc_swiotlb_of_bus_notifier);
+
+       return 0;
+}
index 6b02793dc75b5bd3d95bd2d1ff767ec842fa4905..20a60d661ba867a2491fb09e0c6d48f5b2576bce 100644 (file)
@@ -19,7 +19,7 @@
  * default the offset is PCI_DRAM_OFFSET.
  */
 
-static unsigned long get_dma_direct_offset(struct device *dev)
+unsigned long get_dma_direct_offset(struct device *dev)
 {
        if (dev)
                return (unsigned long)dev->archdata.dma_data;
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
new file mode 100644 (file)
index 0000000..eb89811
--- /dev/null
@@ -0,0 +1,978 @@
+/*
+ * This file contains the 64-bit "server" PowerPC variant
+ * of the low level exception handling including exception
+ * vectors, exception return, part of the slb and stab
+ * handling and other fixed offset specific things.
+ *
+ * This file is meant to be #included from head_64.S due to
+ * position dependant assembly.
+ *
+ * Most of this originates from head_64.S and thus has the same
+ * copyright history.
+ *
+ */
+
+/*
+ * We layout physical memory as follows:
+ * 0x0000 - 0x00ff : Secondary processor spin code
+ * 0x0100 - 0x2fff : pSeries Interrupt prologs
+ * 0x3000 - 0x5fff : interrupt support, iSeries and common interrupt prologs
+ * 0x6000 - 0x6fff : Initial (CPU0) segment table
+ * 0x7000 - 0x7fff : FWNMI data area
+ * 0x8000 -        : Early init and support code
+ */
+
+
+/*
+ *   SPRG Usage
+ *
+ *   Register  Definition
+ *
+ *   SPRG0     reserved for hypervisor
+ *   SPRG1     temp - used to save gpr
+ *   SPRG2     temp - used to save gpr
+ *   SPRG3     virt addr of paca
+ */
+
+/*
+ * This is the start of the interrupt handlers for pSeries
+ * This code runs with relocation off.
+ * Code from here to __end_interrupts gets copied down to real
+ * address 0x100 when we are running a relocatable kernel.
+ * Therefore any relative branches in this section must only
+ * branch to labels in this section.
+ */
+       . = 0x100
+       .globl __start_interrupts
+__start_interrupts:
+
+       STD_EXCEPTION_PSERIES(0x100, system_reset)
+
+       . = 0x200
+_machine_check_pSeries:
+       HMT_MEDIUM
+       mtspr   SPRN_SPRG1,r13          /* save r13 */
+       EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common)
+
+       . = 0x300
+       .globl data_access_pSeries
+data_access_pSeries:
+       HMT_MEDIUM
+       mtspr   SPRN_SPRG1,r13
+BEGIN_FTR_SECTION
+       mtspr   SPRN_SPRG2,r12
+       mfspr   r13,SPRN_DAR
+       mfspr   r12,SPRN_DSISR
+       srdi    r13,r13,60
+       rlwimi  r13,r12,16,0x20
+       mfcr    r12
+       cmpwi   r13,0x2c
+       beq     do_stab_bolted_pSeries
+       mtcrf   0x80,r12
+       mfspr   r12,SPRN_SPRG2
+END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
+       EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, data_access_common)
+
+       . = 0x380
+       .globl data_access_slb_pSeries
+data_access_slb_pSeries:
+       HMT_MEDIUM
+       mtspr   SPRN_SPRG1,r13
+       mfspr   r13,SPRN_SPRG3          /* get paca address into r13 */
+       std     r3,PACA_EXSLB+EX_R3(r13)
+       mfspr   r3,SPRN_DAR
+       std     r9,PACA_EXSLB+EX_R9(r13)        /* save r9 - r12 */
+       mfcr    r9
+#ifdef __DISABLED__
+       /* Keep that around for when we re-implement dynamic VSIDs */
+       cmpdi   r3,0
+       bge     slb_miss_user_pseries
+#endif /* __DISABLED__ */
+       std     r10,PACA_EXSLB+EX_R10(r13)
+       std     r11,PACA_EXSLB+EX_R11(r13)
+       std     r12,PACA_EXSLB+EX_R12(r13)
+       mfspr   r10,SPRN_SPRG1
+       std     r10,PACA_EXSLB+EX_R13(r13)
+       mfspr   r12,SPRN_SRR1           /* and SRR1 */
+#ifndef CONFIG_RELOCATABLE
+       b       .slb_miss_realmode
+#else
+       /*
+        * We can't just use a direct branch to .slb_miss_realmode
+        * because the distance from here to there depends on where
+        * the kernel ends up being put.
+        */
+       mfctr   r11
+       ld      r10,PACAKBASE(r13)
+       LOAD_HANDLER(r10, .slb_miss_realmode)
+       mtctr   r10
+       bctr
+#endif
+
+       STD_EXCEPTION_PSERIES(0x400, instruction_access)
+
+       . = 0x480
+       .globl instruction_access_slb_pSeries
+instruction_access_slb_pSeries:
+       HMT_MEDIUM
+       mtspr   SPRN_SPRG1,r13
+       mfspr   r13,SPRN_SPRG3          /* get paca address into r13 */
+       std     r3,PACA_EXSLB+EX_R3(r13)
+       mfspr   r3,SPRN_SRR0            /* SRR0 is faulting address */
+       std     r9,PACA_EXSLB+EX_R9(r13)        /* save r9 - r12 */
+       mfcr    r9
+#ifdef __DISABLED__
+       /* Keep that around for when we re-implement dynamic VSIDs */
+       cmpdi   r3,0
+       bge     slb_miss_user_pseries
+#endif /* __DISABLED__ */
+       std     r10,PACA_EXSLB+EX_R10(r13)
+       std     r11,PACA_EXSLB+EX_R11(r13)
+       std     r12,PACA_EXSLB+EX_R12(r13)
+       mfspr   r10,SPRN_SPRG1
+       std     r10,PACA_EXSLB+EX_R13(r13)
+       mfspr   r12,SPRN_SRR1           /* and SRR1 */
+#ifndef CONFIG_RELOCATABLE
+       b       .slb_miss_realmode
+#else
+       mfctr   r11
+       ld      r10,PACAKBASE(r13)
+       LOAD_HANDLER(r10, .slb_miss_realmode)
+       mtctr   r10
+       bctr
+#endif
+
+       MASKABLE_EXCEPTION_PSERIES(0x500, hardware_interrupt)
+       STD_EXCEPTION_PSERIES(0x600, alignment)
+       STD_EXCEPTION_PSERIES(0x700, program_check)
+       STD_EXCEPTION_PSERIES(0x800, fp_unavailable)
+       MASKABLE_EXCEPTION_PSERIES(0x900, decrementer)
+       STD_EXCEPTION_PSERIES(0xa00, trap_0a)
+       STD_EXCEPTION_PSERIES(0xb00, trap_0b)
+
+       . = 0xc00
+       .globl  system_call_pSeries
+system_call_pSeries:
+       HMT_MEDIUM
+BEGIN_FTR_SECTION
+       cmpdi   r0,0x1ebe
+       beq-    1f
+END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE)
+       mr      r9,r13
+       mfspr   r13,SPRN_SPRG3
+       mfspr   r11,SPRN_SRR0
+       ld      r12,PACAKBASE(r13)
+       ld      r10,PACAKMSR(r13)
+       LOAD_HANDLER(r12, system_call_entry)
+       mtspr   SPRN_SRR0,r12
+       mfspr   r12,SPRN_SRR1
+       mtspr   SPRN_SRR1,r10
+       rfid
+       b       .       /* prevent speculative execution */
+
+/* Fast LE/BE switch system call */
+1:     mfspr   r12,SPRN_SRR1
+       xori    r12,r12,MSR_LE
+       mtspr   SPRN_SRR1,r12
+       rfid            /* return to userspace */
+       b       .
+
+       STD_EXCEPTION_PSERIES(0xd00, single_step)
+       STD_EXCEPTION_PSERIES(0xe00, trap_0e)
+
+       /* We need to deal with the Altivec unavailable exception
+        * here which is at 0xf20, thus in the middle of the
+        * prolog code of the PerformanceMonitor one. A little
+        * trickery is thus necessary
+        */
+       . = 0xf00
+       b       performance_monitor_pSeries
+
+       . = 0xf20
+       b       altivec_unavailable_pSeries
+
+       . = 0xf40
+       b       vsx_unavailable_pSeries
+
+#ifdef CONFIG_CBE_RAS
+       HSTD_EXCEPTION_PSERIES(0x1200, cbe_system_error)
+#endif /* CONFIG_CBE_RAS */
+       STD_EXCEPTION_PSERIES(0x1300, instruction_breakpoint)
+#ifdef CONFIG_CBE_RAS
+       HSTD_EXCEPTION_PSERIES(0x1600, cbe_maintenance)
+#endif /* CONFIG_CBE_RAS */
+       STD_EXCEPTION_PSERIES(0x1700, altivec_assist)
+#ifdef CONFIG_CBE_RAS
+       HSTD_EXCEPTION_PSERIES(0x1800, cbe_thermal)
+#endif /* CONFIG_CBE_RAS */
+
+       . = 0x3000
+
+/*** pSeries interrupt support ***/
+
+       /* moved from 0xf00 */
+       STD_EXCEPTION_PSERIES(., performance_monitor)
+       STD_EXCEPTION_PSERIES(., altivec_unavailable)
+       STD_EXCEPTION_PSERIES(., vsx_unavailable)
+
+/*
+ * An interrupt came in while soft-disabled; clear EE in SRR1,
+ * clear paca->hard_enabled and return.
+ */
+masked_interrupt:
+       stb     r10,PACAHARDIRQEN(r13)
+       mtcrf   0x80,r9
+       ld      r9,PACA_EXGEN+EX_R9(r13)
+       mfspr   r10,SPRN_SRR1
+       rldicl  r10,r10,48,1            /* clear MSR_EE */
+       rotldi  r10,r10,16
+       mtspr   SPRN_SRR1,r10
+       ld      r10,PACA_EXGEN+EX_R10(r13)
+       mfspr   r13,SPRN_SPRG1
+       rfid
+       b       .
+
+       .align  7
+do_stab_bolted_pSeries:
+       mtcrf   0x80,r12
+       mfspr   r12,SPRN_SPRG2
+       EXCEPTION_PROLOG_PSERIES(PACA_EXSLB, .do_stab_bolted)
+
+#ifdef CONFIG_PPC_PSERIES
+/*
+ * Vectors for the FWNMI option.  Share common code.
+ */
+       .globl system_reset_fwnmi
+      .align 7
+system_reset_fwnmi:
+       HMT_MEDIUM
+       mtspr   SPRN_SPRG1,r13          /* save r13 */
+       EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common)
+
+       .globl machine_check_fwnmi
+      .align 7
+machine_check_fwnmi:
+       HMT_MEDIUM
+       mtspr   SPRN_SPRG1,r13          /* save r13 */
+       EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common)
+
+#endif /* CONFIG_PPC_PSERIES */
+
+#ifdef __DISABLED__
+/*
+ * This is used for when the SLB miss handler has to go virtual,
+ * which doesn't happen for now anymore but will once we re-implement
+ * dynamic VSIDs for shared page tables
+ */
+slb_miss_user_pseries:
+       std     r10,PACA_EXGEN+EX_R10(r13)
+       std     r11,PACA_EXGEN+EX_R11(r13)
+       std     r12,PACA_EXGEN+EX_R12(r13)
+       mfspr   r10,SPRG1
+       ld      r11,PACA_EXSLB+EX_R9(r13)
+       ld      r12,PACA_EXSLB+EX_R3(r13)
+       std     r10,PACA_EXGEN+EX_R13(r13)
+       std     r11,PACA_EXGEN+EX_R9(r13)
+       std     r12,PACA_EXGEN+EX_R3(r13)
+       clrrdi  r12,r13,32
+       mfmsr   r10
+       mfspr   r11,SRR0                        /* save SRR0 */
+       ori     r12,r12,slb_miss_user_common@l  /* virt addr of handler */
+       ori     r10,r10,MSR_IR|MSR_DR|MSR_RI
+       mtspr   SRR0,r12
+       mfspr   r12,SRR1                        /* and SRR1 */
+       mtspr   SRR1,r10
+       rfid
+       b       .                               /* prevent spec. execution */
+#endif /* __DISABLED__ */
+
+       .align  7
+       .globl  __end_interrupts
+__end_interrupts:
+
+/*
+ * Code from here down to __end_handlers is invoked from the
+ * exception prologs above.  Because the prologs assemble the
+ * addresses of these handlers using the LOAD_HANDLER macro,
+ * which uses an addi instruction, these handlers must be in
+ * the first 32k of the kernel image.
+ */
+
+/*** Common interrupt handlers ***/
+
+       STD_EXCEPTION_COMMON(0x100, system_reset, .system_reset_exception)
+
+       /*
+        * Machine check is different because we use a different
+        * save area: PACA_EXMC instead of PACA_EXGEN.
+        */
+       .align  7
+       .globl machine_check_common
+machine_check_common:
+       EXCEPTION_PROLOG_COMMON(0x200, PACA_EXMC)
+       FINISH_NAP
+       DISABLE_INTS
+       bl      .save_nvgprs
+       addi    r3,r1,STACK_FRAME_OVERHEAD
+       bl      .machine_check_exception
+       b       .ret_from_except
+
+       STD_EXCEPTION_COMMON_LITE(0x900, decrementer, .timer_interrupt)
+       STD_EXCEPTION_COMMON(0xa00, trap_0a, .unknown_exception)
+       STD_EXCEPTION_COMMON(0xb00, trap_0b, .unknown_exception)
+       STD_EXCEPTION_COMMON(0xd00, single_step, .single_step_exception)
+       STD_EXCEPTION_COMMON(0xe00, trap_0e, .unknown_exception)
+       STD_EXCEPTION_COMMON_IDLE(0xf00, performance_monitor, .performance_monitor_exception)
+       STD_EXCEPTION_COMMON(0x1300, instruction_breakpoint, .instruction_breakpoint_exception)
+#ifdef CONFIG_ALTIVEC
+       STD_EXCEPTION_COMMON(0x1700, altivec_assist, .altivec_assist_exception)
+#else
+       STD_EXCEPTION_COMMON(0x1700, altivec_assist, .unknown_exception)
+#endif
+#ifdef CONFIG_CBE_RAS
+       STD_EXCEPTION_COMMON(0x1200, cbe_system_error, .cbe_system_error_exception)
+       STD_EXCEPTION_COMMON(0x1600, cbe_maintenance, .cbe_maintenance_exception)
+       STD_EXCEPTION_COMMON(0x1800, cbe_thermal, .cbe_thermal_exception)
+#endif /* CONFIG_CBE_RAS */
+
+       .align  7
+system_call_entry:
+       b       system_call_common
+
+/*
+ * Here we have detected that the kernel stack pointer is bad.
+ * R9 contains the saved CR, r13 points to the paca,
+ * r10 contains the (bad) kernel stack pointer,
+ * r11 and r12 contain the saved SRR0 and SRR1.
+ * We switch to using an emergency stack, save the registers there,
+ * and call kernel_bad_stack(), which panics.
+ */
+bad_stack:
+       ld      r1,PACAEMERGSP(r13)
+       subi    r1,r1,64+INT_FRAME_SIZE
+       std     r9,_CCR(r1)
+       std     r10,GPR1(r1)
+       std     r11,_NIP(r1)
+       std     r12,_MSR(r1)
+       mfspr   r11,SPRN_DAR
+       mfspr   r12,SPRN_DSISR
+       std     r11,_DAR(r1)
+       std     r12,_DSISR(r1)
+       mflr    r10
+       mfctr   r11
+       mfxer   r12
+       std     r10,_LINK(r1)
+       std     r11,_CTR(r1)
+       std     r12,_XER(r1)
+       SAVE_GPR(0,r1)
+       SAVE_GPR(2,r1)
+       SAVE_4GPRS(3,r1)
+       SAVE_2GPRS(7,r1)
+       SAVE_10GPRS(12,r1)
+       SAVE_10GPRS(22,r1)
+       lhz     r12,PACA_TRAP_SAVE(r13)
+       std     r12,_TRAP(r1)
+       addi    r11,r1,INT_FRAME_SIZE
+       std     r11,0(r1)
+       li      r12,0
+       std     r12,0(r11)
+       ld      r2,PACATOC(r13)
+1:     addi    r3,r1,STACK_FRAME_OVERHEAD
+       bl      .kernel_bad_stack
+       b       1b
+
+/*
+ * Here r13 points to the paca, r9 contains the saved CR,
+ * SRR0 and SRR1 are saved in r11 and r12,
+ * r9 - r13 are saved in paca->exgen.
+ */
+       .align  7
+       .globl data_access_common
+data_access_common:
+       mfspr   r10,SPRN_DAR
+       std     r10,PACA_EXGEN+EX_DAR(r13)
+       mfspr   r10,SPRN_DSISR
+       stw     r10,PACA_EXGEN+EX_DSISR(r13)
+       EXCEPTION_PROLOG_COMMON(0x300, PACA_EXGEN)
+       ld      r3,PACA_EXGEN+EX_DAR(r13)
+       lwz     r4,PACA_EXGEN+EX_DSISR(r13)
+       li      r5,0x300
+       b       .do_hash_page           /* Try to handle as hpte fault */
+
+       .align  7
+       .globl instruction_access_common
+instruction_access_common:
+       EXCEPTION_PROLOG_COMMON(0x400, PACA_EXGEN)
+       ld      r3,_NIP(r1)
+       andis.  r4,r12,0x5820
+       li      r5,0x400
+       b       .do_hash_page           /* Try to handle as hpte fault */
+
+/*
+ * Here is the common SLB miss user that is used when going to virtual
+ * mode for SLB misses, that is currently not used
+ */
+#ifdef __DISABLED__
+       .align  7
+       .globl  slb_miss_user_common
+slb_miss_user_common:
+       mflr    r10
+       std     r3,PACA_EXGEN+EX_DAR(r13)
+       stw     r9,PACA_EXGEN+EX_CCR(r13)
+       std     r10,PACA_EXGEN+EX_LR(r13)
+       std     r11,PACA_EXGEN+EX_SRR0(r13)
+       bl      .slb_allocate_user
+
+       ld      r10,PACA_EXGEN+EX_LR(r13)
+       ld      r3,PACA_EXGEN+EX_R3(r13)
+       lwz     r9,PACA_EXGEN+EX_CCR(r13)
+       ld      r11,PACA_EXGEN+EX_SRR0(r13)
+       mtlr    r10
+       beq-    slb_miss_fault
+
+       andi.   r10,r12,MSR_RI          /* check for unrecoverable exception */
+       beq-    unrecov_user_slb
+       mfmsr   r10
+
+.machine push
+.machine "power4"
+       mtcrf   0x80,r9
+.machine pop
+
+       clrrdi  r10,r10,2               /* clear RI before setting SRR0/1 */
+       mtmsrd  r10,1
+
+       mtspr   SRR0,r11
+       mtspr   SRR1,r12
+
+       ld      r9,PACA_EXGEN+EX_R9(r13)
+       ld      r10,PACA_EXGEN+EX_R10(r13)
+       ld      r11,PACA_EXGEN+EX_R11(r13)
+       ld      r12,PACA_EXGEN+EX_R12(r13)
+       ld      r13,PACA_EXGEN+EX_R13(r13)
+       rfid
+       b       .
+
+slb_miss_fault:
+       EXCEPTION_PROLOG_COMMON(0x380, PACA_EXGEN)
+       ld      r4,PACA_EXGEN+EX_DAR(r13)
+       li      r5,0
+       std     r4,_DAR(r1)
+       std     r5,_DSISR(r1)
+       b       handle_page_fault
+
+unrecov_user_slb:
+       EXCEPTION_PROLOG_COMMON(0x4200, PACA_EXGEN)
+       DISABLE_INTS
+       bl      .save_nvgprs
+1:     addi    r3,r1,STACK_FRAME_OVERHEAD
+       bl      .unrecoverable_exception
+       b       1b
+
+#endif /* __DISABLED__ */
+
+
+/*
+ * r13 points to the PACA, r9 contains the saved CR,
+ * r12 contain the saved SRR1, SRR0 is still ready for return
+ * r3 has the faulting address
+ * r9 - r13 are saved in paca->exslb.
+ * r3 is saved in paca->slb_r3
+ * We assume we aren't going to take any exceptions during this procedure.
+ */
+_GLOBAL(slb_miss_realmode)
+       mflr    r10
+#ifdef CONFIG_RELOCATABLE
+       mtctr   r11
+#endif
+
+       stw     r9,PACA_EXSLB+EX_CCR(r13)       /* save CR in exc. frame */
+       std     r10,PACA_EXSLB+EX_LR(r13)       /* save LR */
+
+       bl      .slb_allocate_realmode
+
+       /* All done -- return from exception. */
+
+       ld      r10,PACA_EXSLB+EX_LR(r13)
+       ld      r3,PACA_EXSLB+EX_R3(r13)
+       lwz     r9,PACA_EXSLB+EX_CCR(r13)       /* get saved CR */
+#ifdef CONFIG_PPC_ISERIES
+BEGIN_FW_FTR_SECTION
+       ld      r11,PACALPPACAPTR(r13)
+       ld      r11,LPPACASRR0(r11)             /* get SRR0 value */
+END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
+#endif /* CONFIG_PPC_ISERIES */
+
+       mtlr    r10
+
+       andi.   r10,r12,MSR_RI  /* check for unrecoverable exception */
+       beq-    2f
+
+.machine       push
+.machine       "power4"
+       mtcrf   0x80,r9
+       mtcrf   0x01,r9         /* slb_allocate uses cr0 and cr7 */
+.machine       pop
+
+#ifdef CONFIG_PPC_ISERIES
+BEGIN_FW_FTR_SECTION
+       mtspr   SPRN_SRR0,r11
+       mtspr   SPRN_SRR1,r12
+END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
+#endif /* CONFIG_PPC_ISERIES */
+       ld      r9,PACA_EXSLB+EX_R9(r13)
+       ld      r10,PACA_EXSLB+EX_R10(r13)
+       ld      r11,PACA_EXSLB+EX_R11(r13)
+       ld      r12,PACA_EXSLB+EX_R12(r13)
+       ld      r13,PACA_EXSLB+EX_R13(r13)
+       rfid
+       b       .       /* prevent speculative execution */
+
+2:
+#ifdef CONFIG_PPC_ISERIES
+BEGIN_FW_FTR_SECTION
+       b       unrecov_slb
+END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
+#endif /* CONFIG_PPC_ISERIES */
+       mfspr   r11,SPRN_SRR0
+       ld      r10,PACAKBASE(r13)
+       LOAD_HANDLER(r10,unrecov_slb)
+       mtspr   SPRN_SRR0,r10
+       ld      r10,PACAKMSR(r13)
+       mtspr   SPRN_SRR1,r10
+       rfid
+       b       .
+
+unrecov_slb:
+       EXCEPTION_PROLOG_COMMON(0x4100, PACA_EXSLB)
+       DISABLE_INTS
+       bl      .save_nvgprs
+1:     addi    r3,r1,STACK_FRAME_OVERHEAD
+       bl      .unrecoverable_exception
+       b       1b
+
+       .align  7
+       .globl hardware_interrupt_common
+       .globl hardware_interrupt_entry
+hardware_interrupt_common:
+       EXCEPTION_PROLOG_COMMON(0x500, PACA_EXGEN)
+       FINISH_NAP
+hardware_interrupt_entry:
+       DISABLE_INTS
+BEGIN_FTR_SECTION
+       bl      .ppc64_runlatch_on
+END_FTR_SECTION_IFSET(CPU_FTR_CTRL)
+       addi    r3,r1,STACK_FRAME_OVERHEAD
+       bl      .do_IRQ
+       b       .ret_from_except_lite
+
+#ifdef CONFIG_PPC_970_NAP
+power4_fixup_nap:
+       andc    r9,r9,r10
+       std     r9,TI_LOCAL_FLAGS(r11)
+       ld      r10,_LINK(r1)           /* make idle task do the */
+       std     r10,_NIP(r1)            /* equivalent of a blr */
+       blr
+#endif
+
+       .align  7
+       .globl alignment_common
+alignment_common:
+       mfspr   r10,SPRN_DAR
+       std     r10,PACA_EXGEN+EX_DAR(r13)
+       mfspr   r10,SPRN_DSISR
+       stw     r10,PACA_EXGEN+EX_DSISR(r13)
+       EXCEPTION_PROLOG_COMMON(0x600, PACA_EXGEN)
+       ld      r3,PACA_EXGEN+EX_DAR(r13)
+       lwz     r4,PACA_EXGEN+EX_DSISR(r13)
+       std     r3,_DAR(r1)
+       std     r4,_DSISR(r1)
+       bl      .save_nvgprs
+       addi    r3,r1,STACK_FRAME_OVERHEAD
+       ENABLE_INTS
+       bl      .alignment_exception
+       b       .ret_from_except
+
+       .align  7
+       .globl program_check_common
+program_check_common:
+       EXCEPTION_PROLOG_COMMON(0x700, PACA_EXGEN)
+       bl      .save_nvgprs
+       addi    r3,r1,STACK_FRAME_OVERHEAD
+       ENABLE_INTS
+       bl      .program_check_exception
+       b       .ret_from_except
+
+       .align  7
+       .globl fp_unavailable_common
+fp_unavailable_common:
+       EXCEPTION_PROLOG_COMMON(0x800, PACA_EXGEN)
+       bne     1f                      /* if from user, just load it up */
+       bl      .save_nvgprs
+       addi    r3,r1,STACK_FRAME_OVERHEAD
+       ENABLE_INTS
+       bl      .kernel_fp_unavailable_exception
+       BUG_OPCODE
+1:     bl      .load_up_fpu
+       b       fast_exception_return
+
+       .align  7
+       .globl altivec_unavailable_common
+altivec_unavailable_common:
+       EXCEPTION_PROLOG_COMMON(0xf20, PACA_EXGEN)
+#ifdef CONFIG_ALTIVEC
+BEGIN_FTR_SECTION
+       beq     1f
+       bl      .load_up_altivec
+       b       fast_exception_return
+1:
+END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
+#endif
+       bl      .save_nvgprs
+       addi    r3,r1,STACK_FRAME_OVERHEAD
+       ENABLE_INTS
+       bl      .altivec_unavailable_exception
+       b       .ret_from_except
+
+       .align  7
+       .globl vsx_unavailable_common
+vsx_unavailable_common:
+       EXCEPTION_PROLOG_COMMON(0xf40, PACA_EXGEN)
+#ifdef CONFIG_VSX
+BEGIN_FTR_SECTION
+       bne     .load_up_vsx
+1:
+END_FTR_SECTION_IFSET(CPU_FTR_VSX)
+#endif
+       bl      .save_nvgprs
+       addi    r3,r1,STACK_FRAME_OVERHEAD
+       ENABLE_INTS
+       bl      .vsx_unavailable_exception
+       b       .ret_from_except
+
+       .align  7
+       .globl  __end_handlers
+__end_handlers:
+
+/*
+ * Return from an exception with minimal checks.
+ * The caller is assumed to have done EXCEPTION_PROLOG_COMMON.
+ * If interrupts have been enabled, or anything has been
+ * done that might have changed the scheduling status of
+ * any task or sent any task a signal, you should use
+ * ret_from_except or ret_from_except_lite instead of this.
+ */
+fast_exc_return_irq:                   /* restores irq state too */
+       ld      r3,SOFTE(r1)
+       TRACE_AND_RESTORE_IRQ(r3);
+       ld      r12,_MSR(r1)
+       rldicl  r4,r12,49,63            /* get MSR_EE to LSB */
+       stb     r4,PACAHARDIRQEN(r13)   /* restore paca->hard_enabled */
+       b       1f
+
+       .globl  fast_exception_return
+fast_exception_return:
+       ld      r12,_MSR(r1)
+1:     ld      r11,_NIP(r1)
+       andi.   r3,r12,MSR_RI           /* check if RI is set */
+       beq-    unrecov_fer
+
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+       andi.   r3,r12,MSR_PR
+       beq     2f
+       ACCOUNT_CPU_USER_EXIT(r3, r4)
+2:
+#endif
+
+       ld      r3,_CCR(r1)
+       ld      r4,_LINK(r1)
+       ld      r5,_CTR(r1)
+       ld      r6,_XER(r1)
+       mtcr    r3
+       mtlr    r4
+       mtctr   r5
+       mtxer   r6
+       REST_GPR(0, r1)
+       REST_8GPRS(2, r1)
+
+       mfmsr   r10
+       rldicl  r10,r10,48,1            /* clear EE */
+       rldicr  r10,r10,16,61           /* clear RI (LE is 0 already) */
+       mtmsrd  r10,1
+
+       mtspr   SPRN_SRR1,r12
+       mtspr   SPRN_SRR0,r11
+       REST_4GPRS(10, r1)
+       ld      r1,GPR1(r1)
+       rfid
+       b       .       /* prevent speculative execution */
+
+unrecov_fer:
+       bl      .save_nvgprs
+1:     addi    r3,r1,STACK_FRAME_OVERHEAD
+       bl      .unrecoverable_exception
+       b       1b
+
+
+/*
+ * Hash table stuff
+ */
+       .align  7
+_STATIC(do_hash_page)
+       std     r3,_DAR(r1)
+       std     r4,_DSISR(r1)
+
+       andis.  r0,r4,0xa450            /* weird error? */
+       bne-    handle_page_fault       /* if not, try to insert a HPTE */
+BEGIN_FTR_SECTION
+       andis.  r0,r4,0x0020            /* Is it a segment table fault? */
+       bne-    do_ste_alloc            /* If so handle it */
+END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
+
+       /*
+        * On iSeries, we soft-disable interrupts here, then
+        * hard-enable interrupts so that the hash_page code can spin on
+        * the hash_table_lock without problems on a shared processor.
+        */
+       DISABLE_INTS
+
+       /*
+        * Currently, trace_hardirqs_off() will be called by DISABLE_INTS
+        * and will clobber volatile registers when irq tracing is enabled
+        * so we need to reload them. It may be possible to be smarter here
+        * and move the irq tracing elsewhere but let's keep it simple for
+        * now
+        */
+#ifdef CONFIG_TRACE_IRQFLAGS
+       ld      r3,_DAR(r1)
+       ld      r4,_DSISR(r1)
+       ld      r5,_TRAP(r1)
+       ld      r12,_MSR(r1)
+       clrrdi  r5,r5,4
+#endif /* CONFIG_TRACE_IRQFLAGS */
+       /*
+        * We need to set the _PAGE_USER bit if MSR_PR is set or if we are
+        * accessing a userspace segment (even from the kernel). We assume
+        * kernel addresses always have the high bit set.
+        */
+       rlwinm  r4,r4,32-25+9,31-9,31-9 /* DSISR_STORE -> _PAGE_RW */
+       rotldi  r0,r3,15                /* Move high bit into MSR_PR posn */
+       orc     r0,r12,r0               /* MSR_PR | ~high_bit */
+       rlwimi  r4,r0,32-13,30,30       /* becomes _PAGE_USER access bit */
+       ori     r4,r4,1                 /* add _PAGE_PRESENT */
+       rlwimi  r4,r5,22+2,31-2,31-2    /* Set _PAGE_EXEC if trap is 0x400 */
+
+       /*
+        * r3 contains the faulting address
+        * r4 contains the required access permissions
+        * r5 contains the trap number
+        *
+        * at return r3 = 0 for success
+        */
+       bl      .hash_page              /* build HPTE if possible */
+       cmpdi   r3,0                    /* see if hash_page succeeded */
+
+BEGIN_FW_FTR_SECTION
+       /*
+        * If we had interrupts soft-enabled at the point where the
+        * DSI/ISI occurred, and an interrupt came in during hash_page,
+        * handle it now.
+        * We jump to ret_from_except_lite rather than fast_exception_return
+        * because ret_from_except_lite will check for and handle pending
+        * interrupts if necessary.
+        */
+       beq     13f
+END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
+
+BEGIN_FW_FTR_SECTION
+       /*
+        * Here we have interrupts hard-disabled, so it is sufficient
+        * to restore paca->{soft,hard}_enable and get out.
+        */
+       beq     fast_exc_return_irq     /* Return from exception on success */
+END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES)
+
+       /* For a hash failure, we don't bother re-enabling interrupts */
+       ble-    12f
+
+       /*
+        * hash_page couldn't handle it, set soft interrupt enable back
+        * to what it was before the trap.  Note that .raw_local_irq_restore
+        * handles any interrupts pending at this point.
+        */
+       ld      r3,SOFTE(r1)
+       TRACE_AND_RESTORE_IRQ_PARTIAL(r3, 11f)
+       bl      .raw_local_irq_restore
+       b       11f
+
+/* Here we have a page fault that hash_page can't handle. */
+handle_page_fault:
+       ENABLE_INTS
+11:    ld      r4,_DAR(r1)
+       ld      r5,_DSISR(r1)
+       addi    r3,r1,STACK_FRAME_OVERHEAD
+       bl      .do_page_fault
+       cmpdi   r3,0
+       beq+    13f
+       bl      .save_nvgprs
+       mr      r5,r3
+       addi    r3,r1,STACK_FRAME_OVERHEAD
+       lwz     r4,_DAR(r1)
+       bl      .bad_page_fault
+       b       .ret_from_except
+
+13:    b       .ret_from_except_lite
+
+/* We have a page fault that hash_page could handle but HV refused
+ * the PTE insertion
+ */
+12:    bl      .save_nvgprs
+       mr      r5,r3
+       addi    r3,r1,STACK_FRAME_OVERHEAD
+       ld      r4,_DAR(r1)
+       bl      .low_hash_fault
+       b       .ret_from_except
+
+       /* here we have a segment miss */
+do_ste_alloc:
+       bl      .ste_allocate           /* try to insert stab entry */
+       cmpdi   r3,0
+       bne-    handle_page_fault
+       b       fast_exception_return
+
+/*
+ * r13 points to the PACA, r9 contains the saved CR,
+ * r11 and r12 contain the saved SRR0 and SRR1.
+ * r9 - r13 are saved in paca->exslb.
+ * We assume we aren't going to take any exceptions during this procedure.
+ * We assume (DAR >> 60) == 0xc.
+ */
+       .align  7
+_GLOBAL(do_stab_bolted)
+       stw     r9,PACA_EXSLB+EX_CCR(r13)       /* save CR in exc. frame */
+       std     r11,PACA_EXSLB+EX_SRR0(r13)     /* save SRR0 in exc. frame */
+
+       /* Hash to the primary group */
+       ld      r10,PACASTABVIRT(r13)
+       mfspr   r11,SPRN_DAR
+       srdi    r11,r11,28
+       rldimi  r10,r11,7,52    /* r10 = first ste of the group */
+
+       /* Calculate VSID */
+       /* This is a kernel address, so protovsid = ESID */
+       ASM_VSID_SCRAMBLE(r11, r9, 256M)
+       rldic   r9,r11,12,16    /* r9 = vsid << 12 */
+
+       /* Search the primary group for a free entry */
+1:     ld      r11,0(r10)      /* Test valid bit of the current ste    */
+       andi.   r11,r11,0x80
+       beq     2f
+       addi    r10,r10,16
+       andi.   r11,r10,0x70
+       bne     1b
+
+       /* Stick for only searching the primary group for now.          */
+       /* At least for now, we use a very simple random castout scheme */
+       /* Use the TB as a random number ;  OR in 1 to avoid entry 0    */
+       mftb    r11
+       rldic   r11,r11,4,57    /* r11 = (r11 << 4) & 0x70 */
+       ori     r11,r11,0x10
+
+       /* r10 currently points to an ste one past the group of interest */
+       /* make it point to the randomly selected entry                 */
+       subi    r10,r10,128
+       or      r10,r10,r11     /* r10 is the entry to invalidate       */
+
+       isync                   /* mark the entry invalid               */
+       ld      r11,0(r10)
+       rldicl  r11,r11,56,1    /* clear the valid bit */
+       rotldi  r11,r11,8
+       std     r11,0(r10)
+       sync
+
+       clrrdi  r11,r11,28      /* Get the esid part of the ste         */
+       slbie   r11
+
+2:     std     r9,8(r10)       /* Store the vsid part of the ste       */
+       eieio
+
+       mfspr   r11,SPRN_DAR            /* Get the new esid                     */
+       clrrdi  r11,r11,28      /* Permits a full 32b of ESID           */
+       ori     r11,r11,0x90    /* Turn on valid and kp                 */
+       std     r11,0(r10)      /* Put new entry back into the stab     */
+
+       sync
+
+       /* All done -- return from exception. */
+       lwz     r9,PACA_EXSLB+EX_CCR(r13)       /* get saved CR */
+       ld      r11,PACA_EXSLB+EX_SRR0(r13)     /* get saved SRR0 */
+
+       andi.   r10,r12,MSR_RI
+       beq-    unrecov_slb
+
+       mtcrf   0x80,r9                 /* restore CR */
+
+       mfmsr   r10
+       clrrdi  r10,r10,2
+       mtmsrd  r10,1
+
+       mtspr   SPRN_SRR0,r11
+       mtspr   SPRN_SRR1,r12
+       ld      r9,PACA_EXSLB+EX_R9(r13)
+       ld      r10,PACA_EXSLB+EX_R10(r13)
+       ld      r11,PACA_EXSLB+EX_R11(r13)
+       ld      r12,PACA_EXSLB+EX_R12(r13)
+       ld      r13,PACA_EXSLB+EX_R13(r13)
+       rfid
+       b       .       /* prevent speculative execution */
+
+/*
+ * Space for CPU0's segment table.
+ *
+ * On iSeries, the hypervisor must fill in at least one entry before
+ * we get control (with relocate on).  The address is given to the hv
+ * as a page number (see xLparMap below), so this must be at a
+ * fixed address (the linker can't compute (u64)&initial_stab >>
+ * PAGE_SHIFT).
+ */
+       . = STAB0_OFFSET        /* 0x6000 */
+       .globl initial_stab
+initial_stab:
+       .space  4096
+
+#ifdef CONFIG_PPC_PSERIES
+/*
+ * Data area reserved for FWNMI option.
+ * This address (0x7000) is fixed by the RPA.
+ */
+       .= 0x7000
+       .globl fwnmi_data_area
+fwnmi_data_area:
+#endif /* CONFIG_PPC_PSERIES */
+
+       /* iSeries does not use the FWNMI stuff, so it is safe to put
+        * this here, even if we later allow kernels that will boot on
+        * both pSeries and iSeries */
+#ifdef CONFIG_PPC_ISERIES
+        . = LPARMAP_PHYS
+       .globl xLparMap
+xLparMap:
+       .quad   HvEsidsToMap            /* xNumberEsids */
+       .quad   HvRangesToMap           /* xNumberRanges */
+       .quad   STAB0_PAGE              /* xSegmentTableOffs */
+       .zero   40                      /* xRsvd */
+       /* xEsids (HvEsidsToMap entries of 2 quads) */
+       .quad   PAGE_OFFSET_ESID        /* xKernelEsid */
+       .quad   PAGE_OFFSET_VSID        /* xKernelVsid */
+       .quad   VMALLOC_START_ESID      /* xKernelEsid */
+       .quad   VMALLOC_START_VSID      /* xKernelVsid */
+       /* xRanges (HvRangesToMap entries of 3 quads) */
+       .quad   HvPagesToMap            /* xPages */
+       .quad   0                       /* xOffset */
+       .quad   PAGE_OFFSET_VSID << (SID_SHIFT - HW_PAGE_SHIFT) /* xVPN */
+
+#endif /* CONFIG_PPC_ISERIES */
+
+#ifdef CONFIG_PPC_PSERIES
+        . = 0x8000
+#endif /* CONFIG_PPC_PSERIES */
index 2d182f119d1ddd28bc185b9c56d2bdbbdcfab560..1b12696cca060b6ea3693a41318570f8961a885f 100644 (file)
 #include <asm/code-patching.h>
 #include <asm/ftrace.h>
 
-#ifdef CONFIG_PPC32
-# define GET_ADDR(addr) addr
-#else
-/* PowerPC64's functions are data that points to the functions */
-# define GET_ADDR(addr) (*(unsigned long *)addr)
-#endif
 
 #ifdef CONFIG_DYNAMIC_FTRACE
-static unsigned int ftrace_nop_replace(void)
-{
-       return PPC_INST_NOP;
-}
-
 static unsigned int
 ftrace_call_replace(unsigned long ip, unsigned long addr, int link)
 {
        unsigned int op;
 
-       addr = GET_ADDR(addr);
+       addr = ppc_function_entry((void *)addr);
 
        /* if (link) set op to 'bl' else 'b' */
        op = create_branch((unsigned int *)ip, addr, link ? 1 : 0);
@@ -49,14 +38,6 @@ ftrace_call_replace(unsigned long ip, unsigned long addr, int link)
        return op;
 }
 
-#ifdef CONFIG_PPC64
-# define _ASM_ALIGN    " .align 3 "
-# define _ASM_PTR      " .llong "
-#else
-# define _ASM_ALIGN    " .align 2 "
-# define _ASM_PTR      " .long "
-#endif
-
 static int
 ftrace_modify_code(unsigned long ip, unsigned int old, unsigned int new)
 {
@@ -197,7 +178,7 @@ __ftrace_make_nop(struct module *mod,
        ptr = ((unsigned long)jmp[0] << 32) + jmp[1];
 
        /* This should match what was called */
-       if (ptr != GET_ADDR(addr)) {
+       if (ptr != ppc_function_entry((void *)addr)) {
                printk(KERN_ERR "addr does not match %lx\n", ptr);
                return -EINVAL;
        }
@@ -328,7 +309,7 @@ int ftrace_make_nop(struct module *mod,
        if (test_24bit_addr(ip, addr)) {
                /* within range */
                old = ftrace_call_replace(ip, addr, 1);
-               new = ftrace_nop_replace();
+               new = PPC_INST_NOP;
                return ftrace_modify_code(ip, old, new);
        }
 
@@ -466,7 +447,7 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
         */
        if (test_24bit_addr(ip, addr)) {
                /* within range */
-               old = ftrace_nop_replace();
+               old = PPC_INST_NOP;
                new = ftrace_call_replace(ip, addr, 1);
                return ftrace_modify_code(ip, old, new);
        }
@@ -570,7 +551,7 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr)
                return_hooker = (unsigned long)&mod_return_to_handler;
 #endif
 
-       return_hooker = GET_ADDR(return_hooker);
+       return_hooker = ppc_function_entry((void *)return_hooker);
 
        /*
         * Protect against fault, even if it shouldn't
index c01467f952d38b6552ace4c25815824f4d1560d3..48469463f89e7a309e93e5d536da4ec1f0373f99 100644 (file)
@@ -733,9 +733,11 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_NEED_DTLB_SW_LRU)
 AltiVecUnavailable:
        EXCEPTION_PROLOG
 #ifdef CONFIG_ALTIVEC
-       bne     load_up_altivec         /* if from user, just load it up */
+       beq     1f
+       bl      load_up_altivec         /* if from user, just load it up */
+       b       fast_exception_return
 #endif /* CONFIG_ALTIVEC */
-       addi    r3,r1,STACK_FRAME_OVERHEAD
+1:     addi    r3,r1,STACK_FRAME_OVERHEAD
        EXC_XFER_EE_LITE(0xf20, altivec_unavailable_exception)
 
 PerformanceMonitor:
@@ -743,101 +745,6 @@ PerformanceMonitor:
        addi    r3,r1,STACK_FRAME_OVERHEAD
        EXC_XFER_STD(0xf00, performance_monitor_exception)
 
-#ifdef CONFIG_ALTIVEC
-/* Note that the AltiVec support is closely modeled after the FP
- * support.  Changes to one are likely to be applicable to the
- * other!  */
-load_up_altivec:
-/*
- * Disable AltiVec for the task which had AltiVec previously,
- * and save its AltiVec registers in its thread_struct.
- * Enables AltiVec for use in the kernel on return.
- * On SMP we know the AltiVec units are free, since we give it up every
- * switch.  -- Kumar
- */
-       mfmsr   r5
-       oris    r5,r5,MSR_VEC@h
-       MTMSRD(r5)                      /* enable use of AltiVec now */
-       isync
-/*
- * For SMP, we don't do lazy AltiVec switching because it just gets too
- * horrendously complex, especially when a task switches from one CPU
- * to another.  Instead we call giveup_altivec in switch_to.
- */
-#ifndef CONFIG_SMP
-       tophys(r6,0)
-       addis   r3,r6,last_task_used_altivec@ha
-       lwz     r4,last_task_used_altivec@l(r3)
-       cmpwi   0,r4,0
-       beq     1f
-       add     r4,r4,r6
-       addi    r4,r4,THREAD    /* want THREAD of last_task_used_altivec */
-       SAVE_32VRS(0,r10,r4)
-       mfvscr  vr0
-       li      r10,THREAD_VSCR
-       stvx    vr0,r10,r4
-       lwz     r5,PT_REGS(r4)
-       add     r5,r5,r6
-       lwz     r4,_MSR-STACK_FRAME_OVERHEAD(r5)
-       lis     r10,MSR_VEC@h
-       andc    r4,r4,r10       /* disable altivec for previous task */
-       stw     r4,_MSR-STACK_FRAME_OVERHEAD(r5)
-1:
-#endif /* CONFIG_SMP */
-       /* enable use of AltiVec after return */
-       oris    r9,r9,MSR_VEC@h
-       mfspr   r5,SPRN_SPRG3           /* current task's THREAD (phys) */
-       li      r4,1
-       li      r10,THREAD_VSCR
-       stw     r4,THREAD_USED_VR(r5)
-       lvx     vr0,r10,r5
-       mtvscr  vr0
-       REST_32VRS(0,r10,r5)
-#ifndef CONFIG_SMP
-       subi    r4,r5,THREAD
-       sub     r4,r4,r6
-       stw     r4,last_task_used_altivec@l(r3)
-#endif /* CONFIG_SMP */
-       /* restore registers and return */
-       /* we haven't used ctr or xer or lr */
-       b       fast_exception_return
-
-/*
- * giveup_altivec(tsk)
- * Disable AltiVec for the task given as the argument,
- * and save the AltiVec registers in its thread_struct.
- * Enables AltiVec for use in the kernel on return.
- */
-
-       .globl  giveup_altivec
-giveup_altivec:
-       mfmsr   r5
-       oris    r5,r5,MSR_VEC@h
-       SYNC
-       MTMSRD(r5)                      /* enable use of AltiVec now */
-       isync
-       cmpwi   0,r3,0
-       beqlr-                          /* if no previous owner, done */
-       addi    r3,r3,THREAD            /* want THREAD of task */
-       lwz     r5,PT_REGS(r3)
-       cmpwi   0,r5,0
-       SAVE_32VRS(0, r4, r3)
-       mfvscr  vr0
-       li      r4,THREAD_VSCR
-       stvx    vr0,r4,r3
-       beq     1f
-       lwz     r4,_MSR-STACK_FRAME_OVERHEAD(r5)
-       lis     r3,MSR_VEC@h
-       andc    r4,r4,r3                /* disable AltiVec for previous task */
-       stw     r4,_MSR-STACK_FRAME_OVERHEAD(r5)
-1:
-#ifndef CONFIG_SMP
-       li      r5,0
-       lis     r4,last_task_used_altivec@ha
-       stw     r5,last_task_used_altivec@l(r4)
-#endif /* CONFIG_SMP */
-       blr
-#endif /* CONFIG_ALTIVEC */
 
 /*
  * This code is jumped to from the startup code to copy
index 50ef505b8fb6d0c9bedf58b22978292391ee83fa..012505ebd9f9223a7d6510c054ab02d769362c82 100644 (file)
@@ -12,8 +12,9 @@
  *  Adapted for 64bit PowerPC by Dave Engebretsen, Peter Bergner, and
  *    Mike Corrigan {engebret|bergner|mikejc}@us.ibm.com
  *
- *  This file contains the low-level support and setup for the
- *  PowerPC-64 platform, including trap and interrupt dispatch.
+ *  This file contains the entry point for the 64-bit kernel along
+ *  with some early initialization code common to all 64-bit powerpc
+ *  variants.
  *
  *  This program is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU General Public License
 #include <asm/exception.h>
 #include <asm/irqflags.h>
 
-/*
- * We layout physical memory as follows:
- * 0x0000 - 0x00ff : Secondary processor spin code
- * 0x0100 - 0x2fff : pSeries Interrupt prologs
- * 0x3000 - 0x5fff : interrupt support, iSeries and common interrupt prologs
- * 0x6000 - 0x6fff : Initial (CPU0) segment table
- * 0x7000 - 0x7fff : FWNMI data area
- * 0x8000 -        : Early init and support code
- */
-
-/*
- *   SPRG Usage
- *
- *   Register  Definition
- *
- *   SPRG0     reserved for hypervisor
- *   SPRG1     temp - used to save gpr
- *   SPRG2     temp - used to save gpr
- *   SPRG3     virt addr of paca
+/* The physical memory is layed out such that the secondary processor
+ * spin code sits at 0x0000...0x00ff. On server, the vectors follow
+ * using the layout described in exceptions-64s.S
  */
 
 /*
  * Entering into this code we make the following assumptions:
- *  For pSeries:
+ *
+ *  For pSeries or server processors:
  *   1. The MMU is off & open firmware is running in real mode.
  *   2. The kernel is entered at __start
  *
  *  For iSeries:
  *   1. The MMU is on (as it always is for iSeries)
  *   2. The kernel is entered at system_reset_iSeries
+ *
+ *  For Book3E processors:
+ *   1. The MMU is on running in AS0 in a state defined in ePAPR
+ *   2. The kernel is entered at __start
  */
 
        .text
@@ -166,1065 +156,14 @@ exception_marker:
        .text
 
 /*
- * This is the start of the interrupt handlers for pSeries
- * This code runs with relocation off.
- * Code from here to __end_interrupts gets copied down to real
- * address 0x100 when we are running a relocatable kernel.
- * Therefore any relative branches in this section must only
- * branch to labels in this section.
- */
-       . = 0x100
-       .globl __start_interrupts
-__start_interrupts:
-
-       STD_EXCEPTION_PSERIES(0x100, system_reset)
-
-       . = 0x200
-_machine_check_pSeries:
-       HMT_MEDIUM
-       mtspr   SPRN_SPRG1,r13          /* save r13 */
-       EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common)
-
-       . = 0x300
-       .globl data_access_pSeries
-data_access_pSeries:
-       HMT_MEDIUM
-       mtspr   SPRN_SPRG1,r13
-BEGIN_FTR_SECTION
-       mtspr   SPRN_SPRG2,r12
-       mfspr   r13,SPRN_DAR
-       mfspr   r12,SPRN_DSISR
-       srdi    r13,r13,60
-       rlwimi  r13,r12,16,0x20
-       mfcr    r12
-       cmpwi   r13,0x2c
-       beq     do_stab_bolted_pSeries
-       mtcrf   0x80,r12
-       mfspr   r12,SPRN_SPRG2
-END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
-       EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, data_access_common)
-
-       . = 0x380
-       .globl data_access_slb_pSeries
-data_access_slb_pSeries:
-       HMT_MEDIUM
-       mtspr   SPRN_SPRG1,r13
-       mfspr   r13,SPRN_SPRG3          /* get paca address into r13 */
-       std     r3,PACA_EXSLB+EX_R3(r13)
-       mfspr   r3,SPRN_DAR
-       std     r9,PACA_EXSLB+EX_R9(r13)        /* save r9 - r12 */
-       mfcr    r9
-#ifdef __DISABLED__
-       /* Keep that around for when we re-implement dynamic VSIDs */
-       cmpdi   r3,0
-       bge     slb_miss_user_pseries
-#endif /* __DISABLED__ */
-       std     r10,PACA_EXSLB+EX_R10(r13)
-       std     r11,PACA_EXSLB+EX_R11(r13)
-       std     r12,PACA_EXSLB+EX_R12(r13)
-       mfspr   r10,SPRN_SPRG1
-       std     r10,PACA_EXSLB+EX_R13(r13)
-       mfspr   r12,SPRN_SRR1           /* and SRR1 */
-#ifndef CONFIG_RELOCATABLE
-       b       .slb_miss_realmode
-#else
-       /*
-        * We can't just use a direct branch to .slb_miss_realmode
-        * because the distance from here to there depends on where
-        * the kernel ends up being put.
-        */
-       mfctr   r11
-       ld      r10,PACAKBASE(r13)
-       LOAD_HANDLER(r10, .slb_miss_realmode)
-       mtctr   r10
-       bctr
-#endif
-
-       STD_EXCEPTION_PSERIES(0x400, instruction_access)
-
-       . = 0x480
-       .globl instruction_access_slb_pSeries
-instruction_access_slb_pSeries:
-       HMT_MEDIUM
-       mtspr   SPRN_SPRG1,r13
-       mfspr   r13,SPRN_SPRG3          /* get paca address into r13 */
-       std     r3,PACA_EXSLB+EX_R3(r13)
-       mfspr   r3,SPRN_SRR0            /* SRR0 is faulting address */
-       std     r9,PACA_EXSLB+EX_R9(r13)        /* save r9 - r12 */
-       mfcr    r9
-#ifdef __DISABLED__
-       /* Keep that around for when we re-implement dynamic VSIDs */
-       cmpdi   r3,0
-       bge     slb_miss_user_pseries
-#endif /* __DISABLED__ */
-       std     r10,PACA_EXSLB+EX_R10(r13)
-       std     r11,PACA_EXSLB+EX_R11(r13)
-       std     r12,PACA_EXSLB+EX_R12(r13)
-       mfspr   r10,SPRN_SPRG1
-       std     r10,PACA_EXSLB+EX_R13(r13)
-       mfspr   r12,SPRN_SRR1           /* and SRR1 */
-#ifndef CONFIG_RELOCATABLE
-       b       .slb_miss_realmode
-#else
-       mfctr   r11
-       ld      r10,PACAKBASE(r13)
-       LOAD_HANDLER(r10, .slb_miss_realmode)
-       mtctr   r10
-       bctr
-#endif
-
-       MASKABLE_EXCEPTION_PSERIES(0x500, hardware_interrupt)
-       STD_EXCEPTION_PSERIES(0x600, alignment)
-       STD_EXCEPTION_PSERIES(0x700, program_check)
-       STD_EXCEPTION_PSERIES(0x800, fp_unavailable)
-       MASKABLE_EXCEPTION_PSERIES(0x900, decrementer)
-       STD_EXCEPTION_PSERIES(0xa00, trap_0a)
-       STD_EXCEPTION_PSERIES(0xb00, trap_0b)
-
-       . = 0xc00
-       .globl  system_call_pSeries
-system_call_pSeries:
-       HMT_MEDIUM
-BEGIN_FTR_SECTION
-       cmpdi   r0,0x1ebe
-       beq-    1f
-END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE)
-       mr      r9,r13
-       mfspr   r13,SPRN_SPRG3
-       mfspr   r11,SPRN_SRR0
-       ld      r12,PACAKBASE(r13)
-       ld      r10,PACAKMSR(r13)
-       LOAD_HANDLER(r12, system_call_entry)
-       mtspr   SPRN_SRR0,r12
-       mfspr   r12,SPRN_SRR1
-       mtspr   SPRN_SRR1,r10
-       rfid
-       b       .       /* prevent speculative execution */
-
-/* Fast LE/BE switch system call */
-1:     mfspr   r12,SPRN_SRR1
-       xori    r12,r12,MSR_LE
-       mtspr   SPRN_SRR1,r12
-       rfid            /* return to userspace */
-       b       .
-
-       STD_EXCEPTION_PSERIES(0xd00, single_step)
-       STD_EXCEPTION_PSERIES(0xe00, trap_0e)
-
-       /* We need to deal with the Altivec unavailable exception
-        * here which is at 0xf20, thus in the middle of the
-        * prolog code of the PerformanceMonitor one. A little
-        * trickery is thus necessary
-        */
-       . = 0xf00
-       b       performance_monitor_pSeries
-
-       . = 0xf20
-       b       altivec_unavailable_pSeries
-
-       . = 0xf40
-       b       vsx_unavailable_pSeries
-
-#ifdef CONFIG_CBE_RAS
-       HSTD_EXCEPTION_PSERIES(0x1200, cbe_system_error)
-#endif /* CONFIG_CBE_RAS */
-       STD_EXCEPTION_PSERIES(0x1300, instruction_breakpoint)
-#ifdef CONFIG_CBE_RAS
-       HSTD_EXCEPTION_PSERIES(0x1600, cbe_maintenance)
-#endif /* CONFIG_CBE_RAS */
-       STD_EXCEPTION_PSERIES(0x1700, altivec_assist)
-#ifdef CONFIG_CBE_RAS
-       HSTD_EXCEPTION_PSERIES(0x1800, cbe_thermal)
-#endif /* CONFIG_CBE_RAS */
-
-       . = 0x3000
-
-/*** pSeries interrupt support ***/
-
-       /* moved from 0xf00 */
-       STD_EXCEPTION_PSERIES(., performance_monitor)
-       STD_EXCEPTION_PSERIES(., altivec_unavailable)
-       STD_EXCEPTION_PSERIES(., vsx_unavailable)
-
-/*
- * An interrupt came in while soft-disabled; clear EE in SRR1,
- * clear paca->hard_enabled and return.
- */
-masked_interrupt:
-       stb     r10,PACAHARDIRQEN(r13)
-       mtcrf   0x80,r9
-       ld      r9,PACA_EXGEN+EX_R9(r13)
-       mfspr   r10,SPRN_SRR1
-       rldicl  r10,r10,48,1            /* clear MSR_EE */
-       rotldi  r10,r10,16
-       mtspr   SPRN_SRR1,r10
-       ld      r10,PACA_EXGEN+EX_R10(r13)
-       mfspr   r13,SPRN_SPRG1
-       rfid
-       b       .
-
-       .align  7
-do_stab_bolted_pSeries:
-       mtcrf   0x80,r12
-       mfspr   r12,SPRN_SPRG2
-       EXCEPTION_PROLOG_PSERIES(PACA_EXSLB, .do_stab_bolted)
-
-#ifdef CONFIG_PPC_PSERIES
-/*
- * Vectors for the FWNMI option.  Share common code.
- */
-       .globl system_reset_fwnmi
-      .align 7
-system_reset_fwnmi:
-       HMT_MEDIUM
-       mtspr   SPRN_SPRG1,r13          /* save r13 */
-       EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common)
-
-       .globl machine_check_fwnmi
-      .align 7
-machine_check_fwnmi:
-       HMT_MEDIUM
-       mtspr   SPRN_SPRG1,r13          /* save r13 */
-       EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common)
-
-#endif /* CONFIG_PPC_PSERIES */
-
-#ifdef __DISABLED__
-/*
- * This is used for when the SLB miss handler has to go virtual,
- * which doesn't happen for now anymore but will once we re-implement
- * dynamic VSIDs for shared page tables
- */
-slb_miss_user_pseries:
-       std     r10,PACA_EXGEN+EX_R10(r13)
-       std     r11,PACA_EXGEN+EX_R11(r13)
-       std     r12,PACA_EXGEN+EX_R12(r13)
-       mfspr   r10,SPRG1
-       ld      r11,PACA_EXSLB+EX_R9(r13)
-       ld      r12,PACA_EXSLB+EX_R3(r13)
-       std     r10,PACA_EXGEN+EX_R13(r13)
-       std     r11,PACA_EXGEN+EX_R9(r13)
-       std     r12,PACA_EXGEN+EX_R3(r13)
-       clrrdi  r12,r13,32
-       mfmsr   r10
-       mfspr   r11,SRR0                        /* save SRR0 */
-       ori     r12,r12,slb_miss_user_common@l  /* virt addr of handler */
-       ori     r10,r10,MSR_IR|MSR_DR|MSR_RI
-       mtspr   SRR0,r12
-       mfspr   r12,SRR1                        /* and SRR1 */
-       mtspr   SRR1,r10
-       rfid
-       b       .                               /* prevent spec. execution */
-#endif /* __DISABLED__ */
-
-       .align  7
-       .globl  __end_interrupts
-__end_interrupts:
-
-/*
- * Code from here down to __end_handlers is invoked from the
- * exception prologs above.  Because the prologs assemble the
- * addresses of these handlers using the LOAD_HANDLER macro,
- * which uses an addi instruction, these handlers must be in
- * the first 32k of the kernel image.
- */
-
-/*** Common interrupt handlers ***/
-
-       STD_EXCEPTION_COMMON(0x100, system_reset, .system_reset_exception)
-
-       /*
-        * Machine check is different because we use a different
-        * save area: PACA_EXMC instead of PACA_EXGEN.
-        */
-       .align  7
-       .globl machine_check_common
-machine_check_common:
-       EXCEPTION_PROLOG_COMMON(0x200, PACA_EXMC)
-       FINISH_NAP
-       DISABLE_INTS
-       bl      .save_nvgprs
-       addi    r3,r1,STACK_FRAME_OVERHEAD
-       bl      .machine_check_exception
-       b       .ret_from_except
-
-       STD_EXCEPTION_COMMON_LITE(0x900, decrementer, .timer_interrupt)
-       STD_EXCEPTION_COMMON(0xa00, trap_0a, .unknown_exception)
-       STD_EXCEPTION_COMMON(0xb00, trap_0b, .unknown_exception)
-       STD_EXCEPTION_COMMON(0xd00, single_step, .single_step_exception)
-       STD_EXCEPTION_COMMON(0xe00, trap_0e, .unknown_exception)
-       STD_EXCEPTION_COMMON_IDLE(0xf00, performance_monitor, .performance_monitor_exception)
-       STD_EXCEPTION_COMMON(0x1300, instruction_breakpoint, .instruction_breakpoint_exception)
-#ifdef CONFIG_ALTIVEC
-       STD_EXCEPTION_COMMON(0x1700, altivec_assist, .altivec_assist_exception)
-#else
-       STD_EXCEPTION_COMMON(0x1700, altivec_assist, .unknown_exception)
-#endif
-#ifdef CONFIG_CBE_RAS
-       STD_EXCEPTION_COMMON(0x1200, cbe_system_error, .cbe_system_error_exception)
-       STD_EXCEPTION_COMMON(0x1600, cbe_maintenance, .cbe_maintenance_exception)
-       STD_EXCEPTION_COMMON(0x1800, cbe_thermal, .cbe_thermal_exception)
-#endif /* CONFIG_CBE_RAS */
-
-       .align  7
-system_call_entry:
-       b       system_call_common
-
-/*
- * Here we have detected that the kernel stack pointer is bad.
- * R9 contains the saved CR, r13 points to the paca,
- * r10 contains the (bad) kernel stack pointer,
- * r11 and r12 contain the saved SRR0 and SRR1.
- * We switch to using an emergency stack, save the registers there,
- * and call kernel_bad_stack(), which panics.
- */
-bad_stack:
-       ld      r1,PACAEMERGSP(r13)
-       subi    r1,r1,64+INT_FRAME_SIZE
-       std     r9,_CCR(r1)
-       std     r10,GPR1(r1)
-       std     r11,_NIP(r1)
-       std     r12,_MSR(r1)
-       mfspr   r11,SPRN_DAR
-       mfspr   r12,SPRN_DSISR
-       std     r11,_DAR(r1)
-       std     r12,_DSISR(r1)
-       mflr    r10
-       mfctr   r11
-       mfxer   r12
-       std     r10,_LINK(r1)
-       std     r11,_CTR(r1)
-       std     r12,_XER(r1)
-       SAVE_GPR(0,r1)
-       SAVE_GPR(2,r1)
-       SAVE_4GPRS(3,r1)
-       SAVE_2GPRS(7,r1)
-       SAVE_10GPRS(12,r1)
-       SAVE_10GPRS(22,r1)
-       lhz     r12,PACA_TRAP_SAVE(r13)
-       std     r12,_TRAP(r1)
-       addi    r11,r1,INT_FRAME_SIZE
-       std     r11,0(r1)
-       li      r12,0
-       std     r12,0(r11)
-       ld      r2,PACATOC(r13)
-1:     addi    r3,r1,STACK_FRAME_OVERHEAD
-       bl      .kernel_bad_stack
-       b       1b
-
-/*
- * Here r13 points to the paca, r9 contains the saved CR,
- * SRR0 and SRR1 are saved in r11 and r12,
- * r9 - r13 are saved in paca->exgen.
- */
-       .align  7
-       .globl data_access_common
-data_access_common:
-       mfspr   r10,SPRN_DAR
-       std     r10,PACA_EXGEN+EX_DAR(r13)
-       mfspr   r10,SPRN_DSISR
-       stw     r10,PACA_EXGEN+EX_DSISR(r13)
-       EXCEPTION_PROLOG_COMMON(0x300, PACA_EXGEN)
-       ld      r3,PACA_EXGEN+EX_DAR(r13)
-       lwz     r4,PACA_EXGEN+EX_DSISR(r13)
-       li      r5,0x300
-       b       .do_hash_page           /* Try to handle as hpte fault */
-
-       .align  7
-       .globl instruction_access_common
-instruction_access_common:
-       EXCEPTION_PROLOG_COMMON(0x400, PACA_EXGEN)
-       ld      r3,_NIP(r1)
-       andis.  r4,r12,0x5820
-       li      r5,0x400
-       b       .do_hash_page           /* Try to handle as hpte fault */
-
-/*
- * Here is the common SLB miss user that is used when going to virtual
- * mode for SLB misses, that is currently not used
- */
-#ifdef __DISABLED__
-       .align  7
-       .globl  slb_miss_user_common
-slb_miss_user_common:
-       mflr    r10
-       std     r3,PACA_EXGEN+EX_DAR(r13)
-       stw     r9,PACA_EXGEN+EX_CCR(r13)
-       std     r10,PACA_EXGEN+EX_LR(r13)
-       std     r11,PACA_EXGEN+EX_SRR0(r13)
-       bl      .slb_allocate_user
-
-       ld      r10,PACA_EXGEN+EX_LR(r13)
-       ld      r3,PACA_EXGEN+EX_R3(r13)
-       lwz     r9,PACA_EXGEN+EX_CCR(r13)
-       ld      r11,PACA_EXGEN+EX_SRR0(r13)
-       mtlr    r10
-       beq-    slb_miss_fault
-
-       andi.   r10,r12,MSR_RI          /* check for unrecoverable exception */
-       beq-    unrecov_user_slb
-       mfmsr   r10
-
-.machine push
-.machine "power4"
-       mtcrf   0x80,r9
-.machine pop
-
-       clrrdi  r10,r10,2               /* clear RI before setting SRR0/1 */
-       mtmsrd  r10,1
-
-       mtspr   SRR0,r11
-       mtspr   SRR1,r12
-
-       ld      r9,PACA_EXGEN+EX_R9(r13)
-       ld      r10,PACA_EXGEN+EX_R10(r13)
-       ld      r11,PACA_EXGEN+EX_R11(r13)
-       ld      r12,PACA_EXGEN+EX_R12(r13)
-       ld      r13,PACA_EXGEN+EX_R13(r13)
-       rfid
-       b       .
-
-slb_miss_fault:
-       EXCEPTION_PROLOG_COMMON(0x380, PACA_EXGEN)
-       ld      r4,PACA_EXGEN+EX_DAR(r13)
-       li      r5,0
-       std     r4,_DAR(r1)
-       std     r5,_DSISR(r1)
-       b       handle_page_fault
-
-unrecov_user_slb:
-       EXCEPTION_PROLOG_COMMON(0x4200, PACA_EXGEN)
-       DISABLE_INTS
-       bl      .save_nvgprs
-1:     addi    r3,r1,STACK_FRAME_OVERHEAD
-       bl      .unrecoverable_exception
-       b       1b
-
-#endif /* __DISABLED__ */
-
-
-/*
- * r13 points to the PACA, r9 contains the saved CR,
- * r12 contain the saved SRR1, SRR0 is still ready for return
- * r3 has the faulting address
- * r9 - r13 are saved in paca->exslb.
- * r3 is saved in paca->slb_r3
- * We assume we aren't going to take any exceptions during this procedure.
- */
-_GLOBAL(slb_miss_realmode)
-       mflr    r10
-#ifdef CONFIG_RELOCATABLE
-       mtctr   r11
-#endif
-
-       stw     r9,PACA_EXSLB+EX_CCR(r13)       /* save CR in exc. frame */
-       std     r10,PACA_EXSLB+EX_LR(r13)       /* save LR */
-
-       bl      .slb_allocate_realmode
-
-       /* All done -- return from exception. */
-
-       ld      r10,PACA_EXSLB+EX_LR(r13)
-       ld      r3,PACA_EXSLB+EX_R3(r13)
-       lwz     r9,PACA_EXSLB+EX_CCR(r13)       /* get saved CR */
-#ifdef CONFIG_PPC_ISERIES
-BEGIN_FW_FTR_SECTION
-       ld      r11,PACALPPACAPTR(r13)
-       ld      r11,LPPACASRR0(r11)             /* get SRR0 value */
-END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
-#endif /* CONFIG_PPC_ISERIES */
-
-       mtlr    r10
-
-       andi.   r10,r12,MSR_RI  /* check for unrecoverable exception */
-       beq-    2f
-
-.machine       push
-.machine       "power4"
-       mtcrf   0x80,r9
-       mtcrf   0x01,r9         /* slb_allocate uses cr0 and cr7 */
-.machine       pop
-
-#ifdef CONFIG_PPC_ISERIES
-BEGIN_FW_FTR_SECTION
-       mtspr   SPRN_SRR0,r11
-       mtspr   SPRN_SRR1,r12
-END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
-#endif /* CONFIG_PPC_ISERIES */
-       ld      r9,PACA_EXSLB+EX_R9(r13)
-       ld      r10,PACA_EXSLB+EX_R10(r13)
-       ld      r11,PACA_EXSLB+EX_R11(r13)
-       ld      r12,PACA_EXSLB+EX_R12(r13)
-       ld      r13,PACA_EXSLB+EX_R13(r13)
-       rfid
-       b       .       /* prevent speculative execution */
-
-2:
-#ifdef CONFIG_PPC_ISERIES
-BEGIN_FW_FTR_SECTION
-       b       unrecov_slb
-END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
-#endif /* CONFIG_PPC_ISERIES */
-       mfspr   r11,SPRN_SRR0
-       ld      r10,PACAKBASE(r13)
-       LOAD_HANDLER(r10,unrecov_slb)
-       mtspr   SPRN_SRR0,r10
-       ld      r10,PACAKMSR(r13)
-       mtspr   SPRN_SRR1,r10
-       rfid
-       b       .
-
-unrecov_slb:
-       EXCEPTION_PROLOG_COMMON(0x4100, PACA_EXSLB)
-       DISABLE_INTS
-       bl      .save_nvgprs
-1:     addi    r3,r1,STACK_FRAME_OVERHEAD
-       bl      .unrecoverable_exception
-       b       1b
-
-       .align  7
-       .globl hardware_interrupt_common
-       .globl hardware_interrupt_entry
-hardware_interrupt_common:
-       EXCEPTION_PROLOG_COMMON(0x500, PACA_EXGEN)
-       FINISH_NAP
-hardware_interrupt_entry:
-       DISABLE_INTS
-BEGIN_FTR_SECTION
-       bl      .ppc64_runlatch_on
-END_FTR_SECTION_IFSET(CPU_FTR_CTRL)
-       addi    r3,r1,STACK_FRAME_OVERHEAD
-       bl      .do_IRQ
-       b       .ret_from_except_lite
-
-#ifdef CONFIG_PPC_970_NAP
-power4_fixup_nap:
-       andc    r9,r9,r10
-       std     r9,TI_LOCAL_FLAGS(r11)
-       ld      r10,_LINK(r1)           /* make idle task do the */
-       std     r10,_NIP(r1)            /* equivalent of a blr */
-       blr
-#endif
-
-       .align  7
-       .globl alignment_common
-alignment_common:
-       mfspr   r10,SPRN_DAR
-       std     r10,PACA_EXGEN+EX_DAR(r13)
-       mfspr   r10,SPRN_DSISR
-       stw     r10,PACA_EXGEN+EX_DSISR(r13)
-       EXCEPTION_PROLOG_COMMON(0x600, PACA_EXGEN)
-       ld      r3,PACA_EXGEN+EX_DAR(r13)
-       lwz     r4,PACA_EXGEN+EX_DSISR(r13)
-       std     r3,_DAR(r1)
-       std     r4,_DSISR(r1)
-       bl      .save_nvgprs
-       addi    r3,r1,STACK_FRAME_OVERHEAD
-       ENABLE_INTS
-       bl      .alignment_exception
-       b       .ret_from_except
-
-       .align  7
-       .globl program_check_common
-program_check_common:
-       EXCEPTION_PROLOG_COMMON(0x700, PACA_EXGEN)
-       bl      .save_nvgprs
-       addi    r3,r1,STACK_FRAME_OVERHEAD
-       ENABLE_INTS
-       bl      .program_check_exception
-       b       .ret_from_except
-
-       .align  7
-       .globl fp_unavailable_common
-fp_unavailable_common:
-       EXCEPTION_PROLOG_COMMON(0x800, PACA_EXGEN)
-       bne     1f                      /* if from user, just load it up */
-       bl      .save_nvgprs
-       addi    r3,r1,STACK_FRAME_OVERHEAD
-       ENABLE_INTS
-       bl      .kernel_fp_unavailable_exception
-       BUG_OPCODE
-1:     bl      .load_up_fpu
-       b       fast_exception_return
-
-       .align  7
-       .globl altivec_unavailable_common
-altivec_unavailable_common:
-       EXCEPTION_PROLOG_COMMON(0xf20, PACA_EXGEN)
-#ifdef CONFIG_ALTIVEC
-BEGIN_FTR_SECTION
-       beq     1f
-       bl      .load_up_altivec
-       b       fast_exception_return
-1:
-END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
-#endif
-       bl      .save_nvgprs
-       addi    r3,r1,STACK_FRAME_OVERHEAD
-       ENABLE_INTS
-       bl      .altivec_unavailable_exception
-       b       .ret_from_except
-
-       .align  7
-       .globl vsx_unavailable_common
-vsx_unavailable_common:
-       EXCEPTION_PROLOG_COMMON(0xf40, PACA_EXGEN)
-#ifdef CONFIG_VSX
-BEGIN_FTR_SECTION
-       bne     .load_up_vsx
-1:
-END_FTR_SECTION_IFSET(CPU_FTR_VSX)
-#endif
-       bl      .save_nvgprs
-       addi    r3,r1,STACK_FRAME_OVERHEAD
-       ENABLE_INTS
-       bl      .vsx_unavailable_exception
-       b       .ret_from_except
-
-       .align  7
-       .globl  __end_handlers
-__end_handlers:
-
-/*
- * Return from an exception with minimal checks.
- * The caller is assumed to have done EXCEPTION_PROLOG_COMMON.
- * If interrupts have been enabled, or anything has been
- * done that might have changed the scheduling status of
- * any task or sent any task a signal, you should use
- * ret_from_except or ret_from_except_lite instead of this.
+ * On server, we include the exception vectors code here as it
+ * relies on absolute addressing which is only possible within
+ * this compilation unit
  */
-fast_exc_return_irq:                   /* restores irq state too */
-       ld      r3,SOFTE(r1)
-       TRACE_AND_RESTORE_IRQ(r3);
-       ld      r12,_MSR(r1)
-       rldicl  r4,r12,49,63            /* get MSR_EE to LSB */
-       stb     r4,PACAHARDIRQEN(r13)   /* restore paca->hard_enabled */
-       b       1f
-
-       .globl  fast_exception_return
-fast_exception_return:
-       ld      r12,_MSR(r1)
-1:     ld      r11,_NIP(r1)
-       andi.   r3,r12,MSR_RI           /* check if RI is set */
-       beq-    unrecov_fer
-
-#ifdef CONFIG_VIRT_CPU_ACCOUNTING
-       andi.   r3,r12,MSR_PR
-       beq     2f
-       ACCOUNT_CPU_USER_EXIT(r3, r4)
-2:
+#ifdef CONFIG_PPC_BOOK3S
+#include "exceptions-64s.S"
 #endif
 
-       ld      r3,_CCR(r1)
-       ld      r4,_LINK(r1)
-       ld      r5,_CTR(r1)
-       ld      r6,_XER(r1)
-       mtcr    r3
-       mtlr    r4
-       mtctr   r5
-       mtxer   r6
-       REST_GPR(0, r1)
-       REST_8GPRS(2, r1)
-
-       mfmsr   r10
-       rldicl  r10,r10,48,1            /* clear EE */
-       rldicr  r10,r10,16,61           /* clear RI (LE is 0 already) */
-       mtmsrd  r10,1
-
-       mtspr   SPRN_SRR1,r12
-       mtspr   SPRN_SRR0,r11
-       REST_4GPRS(10, r1)
-       ld      r1,GPR1(r1)
-       rfid
-       b       .       /* prevent speculative execution */
-
-unrecov_fer:
-       bl      .save_nvgprs
-1:     addi    r3,r1,STACK_FRAME_OVERHEAD
-       bl      .unrecoverable_exception
-       b       1b
-
-#ifdef CONFIG_ALTIVEC
-/*
- * load_up_altivec(unused, unused, tsk)
- * Disable VMX for the task which had it previously,
- * and save its vector registers in its thread_struct.
- * Enables the VMX for use in the kernel on return.
- * On SMP we know the VMX is free, since we give it up every
- * switch (ie, no lazy save of the vector registers).
- * On entry: r13 == 'current' && last_task_used_altivec != 'current'
- */
-_STATIC(load_up_altivec)
-       mfmsr   r5                      /* grab the current MSR */
-       oris    r5,r5,MSR_VEC@h
-       mtmsrd  r5                      /* enable use of VMX now */
-       isync
-
-/*
- * For SMP, we don't do lazy VMX switching because it just gets too
- * horrendously complex, especially when a task switches from one CPU
- * to another.  Instead we call giveup_altvec in switch_to.
- * VRSAVE isn't dealt with here, that is done in the normal context
- * switch code. Note that we could rely on vrsave value to eventually
- * avoid saving all of the VREGs here...
- */
-#ifndef CONFIG_SMP
-       ld      r3,last_task_used_altivec@got(r2)
-       ld      r4,0(r3)
-       cmpdi   0,r4,0
-       beq     1f
-       /* Save VMX state to last_task_used_altivec's THREAD struct */
-       addi    r4,r4,THREAD
-       SAVE_32VRS(0,r5,r4)
-       mfvscr  vr0
-       li      r10,THREAD_VSCR
-       stvx    vr0,r10,r4
-       /* Disable VMX for last_task_used_altivec */
-       ld      r5,PT_REGS(r4)
-       ld      r4,_MSR-STACK_FRAME_OVERHEAD(r5)
-       lis     r6,MSR_VEC@h
-       andc    r4,r4,r6
-       std     r4,_MSR-STACK_FRAME_OVERHEAD(r5)
-1:
-#endif /* CONFIG_SMP */
-       /* Hack: if we get an altivec unavailable trap with VRSAVE
-        * set to all zeros, we assume this is a broken application
-        * that fails to set it properly, and thus we switch it to
-        * all 1's
-        */
-       mfspr   r4,SPRN_VRSAVE
-       cmpdi   0,r4,0
-       bne+    1f
-       li      r4,-1
-       mtspr   SPRN_VRSAVE,r4
-1:
-       /* enable use of VMX after return */
-       ld      r4,PACACURRENT(r13)
-       addi    r5,r4,THREAD            /* Get THREAD */
-       oris    r12,r12,MSR_VEC@h
-       std     r12,_MSR(r1)
-       li      r4,1
-       li      r10,THREAD_VSCR
-       stw     r4,THREAD_USED_VR(r5)
-       lvx     vr0,r10,r5
-       mtvscr  vr0
-       REST_32VRS(0,r4,r5)
-#ifndef CONFIG_SMP
-       /* Update last_task_used_math to 'current' */
-       subi    r4,r5,THREAD            /* Back to 'current' */
-       std     r4,0(r3)
-#endif /* CONFIG_SMP */
-       /* restore registers and return */
-       blr
-#endif /* CONFIG_ALTIVEC */
-
-#ifdef CONFIG_VSX
-/*
- * load_up_vsx(unused, unused, tsk)
- * Disable VSX for the task which had it previously,
- * and save its vector registers in its thread_struct.
- * Reuse the fp and vsx saves, but first check to see if they have
- * been saved already.
- * On entry: r13 == 'current' && last_task_used_vsx != 'current'
- */
-_STATIC(load_up_vsx)
-/* Load FP and VSX registers if they haven't been done yet */
-       andi.   r5,r12,MSR_FP
-       beql+   load_up_fpu             /* skip if already loaded */
-       andis.  r5,r12,MSR_VEC@h
-       beql+   load_up_altivec         /* skip if already loaded */
-
-#ifndef CONFIG_SMP
-       ld      r3,last_task_used_vsx@got(r2)
-       ld      r4,0(r3)
-       cmpdi   0,r4,0
-       beq     1f
-       /* Disable VSX for last_task_used_vsx */
-       addi    r4,r4,THREAD
-       ld      r5,PT_REGS(r4)
-       ld      r4,_MSR-STACK_FRAME_OVERHEAD(r5)
-       lis     r6,MSR_VSX@h
-       andc    r6,r4,r6
-       std     r6,_MSR-STACK_FRAME_OVERHEAD(r5)
-1:
-#endif /* CONFIG_SMP */
-       ld      r4,PACACURRENT(r13)
-       addi    r4,r4,THREAD            /* Get THREAD */
-       li      r6,1
-       stw     r6,THREAD_USED_VSR(r4) /* ... also set thread used vsr */
-       /* enable use of VSX after return */
-       oris    r12,r12,MSR_VSX@h
-       std     r12,_MSR(r1)
-#ifndef CONFIG_SMP
-       /* Update last_task_used_math to 'current' */
-       ld      r4,PACACURRENT(r13)
-       std     r4,0(r3)
-#endif /* CONFIG_SMP */
-       b       fast_exception_return
-#endif /* CONFIG_VSX */
-
-/*
- * Hash table stuff
- */
-       .align  7
-_STATIC(do_hash_page)
-       std     r3,_DAR(r1)
-       std     r4,_DSISR(r1)
-
-       andis.  r0,r4,0xa450            /* weird error? */
-       bne-    handle_page_fault       /* if not, try to insert a HPTE */
-BEGIN_FTR_SECTION
-       andis.  r0,r4,0x0020            /* Is it a segment table fault? */
-       bne-    do_ste_alloc            /* If so handle it */
-END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
-
-       /*
-        * On iSeries, we soft-disable interrupts here, then
-        * hard-enable interrupts so that the hash_page code can spin on
-        * the hash_table_lock without problems on a shared processor.
-        */
-       DISABLE_INTS
-
-       /*
-        * Currently, trace_hardirqs_off() will be called by DISABLE_INTS
-        * and will clobber volatile registers when irq tracing is enabled
-        * so we need to reload them. It may be possible to be smarter here
-        * and move the irq tracing elsewhere but let's keep it simple for
-        * now
-        */
-#ifdef CONFIG_TRACE_IRQFLAGS
-       ld      r3,_DAR(r1)
-       ld      r4,_DSISR(r1)
-       ld      r5,_TRAP(r1)
-       ld      r12,_MSR(r1)
-       clrrdi  r5,r5,4
-#endif /* CONFIG_TRACE_IRQFLAGS */
-       /*
-        * We need to set the _PAGE_USER bit if MSR_PR is set or if we are
-        * accessing a userspace segment (even from the kernel). We assume
-        * kernel addresses always have the high bit set.
-        */
-       rlwinm  r4,r4,32-25+9,31-9,31-9 /* DSISR_STORE -> _PAGE_RW */
-       rotldi  r0,r3,15                /* Move high bit into MSR_PR posn */
-       orc     r0,r12,r0               /* MSR_PR | ~high_bit */
-       rlwimi  r4,r0,32-13,30,30       /* becomes _PAGE_USER access bit */
-       ori     r4,r4,1                 /* add _PAGE_PRESENT */
-       rlwimi  r4,r5,22+2,31-2,31-2    /* Set _PAGE_EXEC if trap is 0x400 */
-
-       /*
-        * r3 contains the faulting address
-        * r4 contains the required access permissions
-        * r5 contains the trap number
-        *
-        * at return r3 = 0 for success
-        */
-       bl      .hash_page              /* build HPTE if possible */
-       cmpdi   r3,0                    /* see if hash_page succeeded */
-
-BEGIN_FW_FTR_SECTION
-       /*
-        * If we had interrupts soft-enabled at the point where the
-        * DSI/ISI occurred, and an interrupt came in during hash_page,
-        * handle it now.
-        * We jump to ret_from_except_lite rather than fast_exception_return
-        * because ret_from_except_lite will check for and handle pending
-        * interrupts if necessary.
-        */
-       beq     13f
-END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
-
-BEGIN_FW_FTR_SECTION
-       /*
-        * Here we have interrupts hard-disabled, so it is sufficient
-        * to restore paca->{soft,hard}_enable and get out.
-        */
-       beq     fast_exc_return_irq     /* Return from exception on success */
-END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES)
-
-       /* For a hash failure, we don't bother re-enabling interrupts */
-       ble-    12f
-
-       /*
-        * hash_page couldn't handle it, set soft interrupt enable back
-        * to what it was before the trap.  Note that .raw_local_irq_restore
-        * handles any interrupts pending at this point.
-        */
-       ld      r3,SOFTE(r1)
-       TRACE_AND_RESTORE_IRQ_PARTIAL(r3, 11f)
-       bl      .raw_local_irq_restore
-       b       11f
-
-/* Here we have a page fault that hash_page can't handle. */
-handle_page_fault:
-       ENABLE_INTS
-11:    ld      r4,_DAR(r1)
-       ld      r5,_DSISR(r1)
-       addi    r3,r1,STACK_FRAME_OVERHEAD
-       bl      .do_page_fault
-       cmpdi   r3,0
-       beq+    13f
-       bl      .save_nvgprs
-       mr      r5,r3
-       addi    r3,r1,STACK_FRAME_OVERHEAD
-       lwz     r4,_DAR(r1)
-       bl      .bad_page_fault
-       b       .ret_from_except
-
-13:    b       .ret_from_except_lite
-
-/* We have a page fault that hash_page could handle but HV refused
- * the PTE insertion
- */
-12:    bl      .save_nvgprs
-       mr      r5,r3
-       addi    r3,r1,STACK_FRAME_OVERHEAD
-       ld      r4,_DAR(r1)
-       bl      .low_hash_fault
-       b       .ret_from_except
-
-       /* here we have a segment miss */
-do_ste_alloc:
-       bl      .ste_allocate           /* try to insert stab entry */
-       cmpdi   r3,0
-       bne-    handle_page_fault
-       b       fast_exception_return
-
-/*
- * r13 points to the PACA, r9 contains the saved CR,
- * r11 and r12 contain the saved SRR0 and SRR1.
- * r9 - r13 are saved in paca->exslb.
- * We assume we aren't going to take any exceptions during this procedure.
- * We assume (DAR >> 60) == 0xc.
- */
-       .align  7
-_GLOBAL(do_stab_bolted)
-       stw     r9,PACA_EXSLB+EX_CCR(r13)       /* save CR in exc. frame */
-       std     r11,PACA_EXSLB+EX_SRR0(r13)     /* save SRR0 in exc. frame */
-
-       /* Hash to the primary group */
-       ld      r10,PACASTABVIRT(r13)
-       mfspr   r11,SPRN_DAR
-       srdi    r11,r11,28
-       rldimi  r10,r11,7,52    /* r10 = first ste of the group */
-
-       /* Calculate VSID */
-       /* This is a kernel address, so protovsid = ESID */
-       ASM_VSID_SCRAMBLE(r11, r9, 256M)
-       rldic   r9,r11,12,16    /* r9 = vsid << 12 */
-
-       /* Search the primary group for a free entry */
-1:     ld      r11,0(r10)      /* Test valid bit of the current ste    */
-       andi.   r11,r11,0x80
-       beq     2f
-       addi    r10,r10,16
-       andi.   r11,r10,0x70
-       bne     1b
-
-       /* Stick for only searching the primary group for now.          */
-       /* At least for now, we use a very simple random castout scheme */
-       /* Use the TB as a random number ;  OR in 1 to avoid entry 0    */
-       mftb    r11
-       rldic   r11,r11,4,57    /* r11 = (r11 << 4) & 0x70 */
-       ori     r11,r11,0x10
-
-       /* r10 currently points to an ste one past the group of interest */
-       /* make it point to the randomly selected entry                 */
-       subi    r10,r10,128
-       or      r10,r10,r11     /* r10 is the entry to invalidate       */
-
-       isync                   /* mark the entry invalid               */
-       ld      r11,0(r10)
-       rldicl  r11,r11,56,1    /* clear the valid bit */
-       rotldi  r11,r11,8
-       std     r11,0(r10)
-       sync
-
-       clrrdi  r11,r11,28      /* Get the esid part of the ste         */
-       slbie   r11
-
-2:     std     r9,8(r10)       /* Store the vsid part of the ste       */
-       eieio
-
-       mfspr   r11,SPRN_DAR            /* Get the new esid                     */
-       clrrdi  r11,r11,28      /* Permits a full 32b of ESID           */
-       ori     r11,r11,0x90    /* Turn on valid and kp                 */
-       std     r11,0(r10)      /* Put new entry back into the stab     */
-
-       sync
-
-       /* All done -- return from exception. */
-       lwz     r9,PACA_EXSLB+EX_CCR(r13)       /* get saved CR */
-       ld      r11,PACA_EXSLB+EX_SRR0(r13)     /* get saved SRR0 */
-
-       andi.   r10,r12,MSR_RI
-       beq-    unrecov_slb
-
-       mtcrf   0x80,r9                 /* restore CR */
-
-       mfmsr   r10
-       clrrdi  r10,r10,2
-       mtmsrd  r10,1
-
-       mtspr   SPRN_SRR0,r11
-       mtspr   SPRN_SRR1,r12
-       ld      r9,PACA_EXSLB+EX_R9(r13)
-       ld      r10,PACA_EXSLB+EX_R10(r13)
-       ld      r11,PACA_EXSLB+EX_R11(r13)
-       ld      r12,PACA_EXSLB+EX_R12(r13)
-       ld      r13,PACA_EXSLB+EX_R13(r13)
-       rfid
-       b       .       /* prevent speculative execution */
-
-/*
- * Space for CPU0's segment table.
- *
- * On iSeries, the hypervisor must fill in at least one entry before
- * we get control (with relocate on).  The address is given to the hv
- * as a page number (see xLparMap below), so this must be at a
- * fixed address (the linker can't compute (u64)&initial_stab >>
- * PAGE_SHIFT).
- */
-       . = STAB0_OFFSET        /* 0x6000 */
-       .globl initial_stab
-initial_stab:
-       .space  4096
-
-#ifdef CONFIG_PPC_PSERIES
-/*
- * Data area reserved for FWNMI option.
- * This address (0x7000) is fixed by the RPA.
- */
-       .= 0x7000
-       .globl fwnmi_data_area
-fwnmi_data_area:
-#endif /* CONFIG_PPC_PSERIES */
-
-       /* iSeries does not use the FWNMI stuff, so it is safe to put
-        * this here, even if we later allow kernels that will boot on
-        * both pSeries and iSeries */
-#ifdef CONFIG_PPC_ISERIES
-        . = LPARMAP_PHYS
-       .globl xLparMap
-xLparMap:
-       .quad   HvEsidsToMap            /* xNumberEsids */
-       .quad   HvRangesToMap           /* xNumberRanges */
-       .quad   STAB0_PAGE              /* xSegmentTableOffs */
-       .zero   40                      /* xRsvd */
-       /* xEsids (HvEsidsToMap entries of 2 quads) */
-       .quad   PAGE_OFFSET_ESID        /* xKernelEsid */
-       .quad   PAGE_OFFSET_VSID        /* xKernelVsid */
-       .quad   VMALLOC_START_ESID      /* xKernelEsid */
-       .quad   VMALLOC_START_VSID      /* xKernelVsid */
-       /* xRanges (HvRangesToMap entries of 3 quads) */
-       .quad   HvPagesToMap            /* xPages */
-       .quad   0                       /* xOffset */
-       .quad   PAGE_OFFSET_VSID << (SID_SHIFT - HW_PAGE_SHIFT) /* xVPN */
-
-#endif /* CONFIG_PPC_ISERIES */
-
-#ifdef CONFIG_PPC_PSERIES
-        . = 0x8000
-#endif /* CONFIG_PPC_PSERIES */
 
 /*
  * On pSeries and most other platforms, secondary processors spin
index 95f39f1e68d449036b0206735936513c60533cdc..5f9febc8d1431c4daebb711f1496f9e1069a1b7e 100644 (file)
@@ -256,7 +256,7 @@ label:
         * off DE in the DSRR1 value and clearing the debug status.           \
         */                                                                   \
        mfspr   r10,SPRN_DBSR;          /* check single-step/branch taken */  \
-       andis.  r10,r10,DBSR_IC@h;                                            \
+       andis.  r10,r10,(DBSR_IC|DBSR_BT)@h;                                  \
        beq+    2f;                                                           \
                                                                              \
        lis     r10,KERNELBASE@h;       /* check if exception in vectors */   \
@@ -271,7 +271,7 @@ label:
                                                                              \
        /* here it looks like we got an inappropriate debug exception. */     \
 1:     rlwinm  r9,r9,0,~MSR_DE;        /* clear DE in the CDRR1 value */     \
-       lis     r10,DBSR_IC@h;          /* clear the IC event */              \
+       lis     r10,(DBSR_IC|DBSR_BT)@h;        /* clear the IC event */      \
        mtspr   SPRN_DBSR,r10;                                                \
        /* restore state and get out */                                       \
        lwz     r10,_CCR(r11);                                                \
@@ -309,7 +309,7 @@ label:
         * off DE in the CSRR1 value and clearing the debug status.           \
         */                                                                   \
        mfspr   r10,SPRN_DBSR;          /* check single-step/branch taken */  \
-       andis.  r10,r10,DBSR_IC@h;                                            \
+       andis.  r10,r10,(DBSR_IC|DBSR_BT)@h;                                  \
        beq+    2f;                                                           \
                                                                              \
        lis     r10,KERNELBASE@h;       /* check if exception in vectors */   \
@@ -317,14 +317,14 @@ label:
        cmplw   r12,r10;                                                      \
        blt+    2f;                     /* addr below exception vectors */    \
                                                                              \
-       lis     r10,DebugCrit@h;                                                      \
+       lis     r10,DebugCrit@h;                                              \
        ori     r10,r10,DebugCrit@l;                                          \
        cmplw   r12,r10;                                                      \
        bgt+    2f;                     /* addr above exception vectors */    \
                                                                              \
        /* here it looks like we got an inappropriate debug exception. */     \
 1:     rlwinm  r9,r9,0,~MSR_DE;        /* clear DE in the CSRR1 value */     \
-       lis     r10,DBSR_IC@h;          /* clear the IC event */              \
+       lis     r10,(DBSR_IC|DBSR_BT)@h;        /* clear the IC event */      \
        mtspr   SPRN_DBSR,r10;                                                \
        /* restore state and get out */                                       \
        lwz     r10,_CCR(r11);                                                \
index 844d3f882a15051f4b4cba821c10c377d2529501..f7f376ea7b178792fa12927b0578230e9bc61915 100644 (file)
@@ -118,6 +118,7 @@ notrace void raw_local_irq_restore(unsigned long en)
        if (!en)
                return;
 
+#ifdef CONFIG_PPC_STD_MMU_64
        if (firmware_has_feature(FW_FEATURE_ISERIES)) {
                /*
                 * Do we need to disable preemption here?  Not really: in the
@@ -135,6 +136,7 @@ notrace void raw_local_irq_restore(unsigned long en)
                if (local_paca->lppaca_ptr->int_dword.any_int)
                        iseries_handle_interrupts();
        }
+#endif /* CONFIG_PPC_STD_MMU_64 */
 
        if (test_perf_counter_pending()) {
                clear_perf_counter_pending();
@@ -254,77 +256,84 @@ void fixup_irqs(cpumask_t map)
 }
 #endif
 
-void do_IRQ(struct pt_regs *regs)
-{
-       struct pt_regs *old_regs = set_irq_regs(regs);
-       unsigned int irq;
 #ifdef CONFIG_IRQSTACKS
+static inline void handle_one_irq(unsigned int irq)
+{
        struct thread_info *curtp, *irqtp;
-#endif
+       unsigned long saved_sp_limit;
+       struct irq_desc *desc;
 
-       irq_enter();
+       /* Switch to the irq stack to handle this */
+       curtp = current_thread_info();
+       irqtp = hardirq_ctx[smp_processor_id()];
+
+       if (curtp == irqtp) {
+               /* We're already on the irq stack, just handle it */
+               generic_handle_irq(irq);
+               return;
+       }
+
+       desc = irq_desc + irq;
+       saved_sp_limit = current->thread.ksp_limit;
+
+       irqtp->task = curtp->task;
+       irqtp->flags = 0;
+
+       /* Copy the softirq bits in preempt_count so that the
+        * softirq checks work in the hardirq context. */
+       irqtp->preempt_count = (irqtp->preempt_count & ~SOFTIRQ_MASK) |
+                              (curtp->preempt_count & SOFTIRQ_MASK);
+
+       current->thread.ksp_limit = (unsigned long)irqtp +
+               _ALIGN_UP(sizeof(struct thread_info), 16);
+
+       call_handle_irq(irq, desc, irqtp, desc->handle_irq);
+       current->thread.ksp_limit = saved_sp_limit;
+       irqtp->task = NULL;
+
+       /* Set any flag that may have been set on the
+        * alternate stack
+        */
+       if (irqtp->flags)
+               set_bits(irqtp->flags, &curtp->flags);
+}
+#else
+static inline void handle_one_irq(unsigned int irq)
+{
+       generic_handle_irq(irq);
+}
+#endif
 
+static inline void check_stack_overflow(void)
+{
 #ifdef CONFIG_DEBUG_STACKOVERFLOW
-       /* Debugging check for stack overflow: is there less than 2KB free? */
-       {
-               long sp;
+       long sp;
 
-               sp = __get_SP() & (THREAD_SIZE-1);
+       sp = __get_SP() & (THREAD_SIZE-1);
 
-               if (unlikely(sp < (sizeof(struct thread_info) + 2048))) {
-                       printk("do_IRQ: stack overflow: %ld\n",
-                               sp - sizeof(struct thread_info));
-                       dump_stack();
-               }
+       /* check for stack overflow: is there less than 2KB free? */
+       if (unlikely(sp < (sizeof(struct thread_info) + 2048))) {
+               printk("do_IRQ: stack overflow: %ld\n",
+                       sp - sizeof(struct thread_info));
+               dump_stack();
        }
 #endif
+}
 
-       /*
-        * Every platform is required to implement ppc_md.get_irq.
-        * This function will either return an irq number or NO_IRQ to
-        * indicate there are no more pending.
-        * The value NO_IRQ_IGNORE is for buggy hardware and means that this
-        * IRQ has already been handled. -- Tom
-        */
-       irq = ppc_md.get_irq();
+void do_IRQ(struct pt_regs *regs)
+{
+       struct pt_regs *old_regs = set_irq_regs(regs);
+       unsigned int irq;
 
-       if (irq != NO_IRQ && irq != NO_IRQ_IGNORE) {
-#ifdef CONFIG_IRQSTACKS
-               /* Switch to the irq stack to handle this */
-               curtp = current_thread_info();
-               irqtp = hardirq_ctx[smp_processor_id()];
-               if (curtp != irqtp) {
-                       struct irq_desc *desc = irq_desc + irq;
-                       void *handler = desc->handle_irq;
-                       unsigned long saved_sp_limit = current->thread.ksp_limit;
-                       if (handler == NULL)
-                               handler = &__do_IRQ;
-                       irqtp->task = curtp->task;
-                       irqtp->flags = 0;
-
-                       /* Copy the softirq bits in preempt_count so that the
-                        * softirq checks work in the hardirq context.
-                        */
-                       irqtp->preempt_count =
-                               (irqtp->preempt_count & ~SOFTIRQ_MASK) |
-                               (curtp->preempt_count & SOFTIRQ_MASK);
+       irq_enter();
 
-                       current->thread.ksp_limit = (unsigned long)irqtp +
-                               _ALIGN_UP(sizeof(struct thread_info), 16);
-                       call_handle_irq(irq, desc, irqtp, handler);
-                       current->thread.ksp_limit = saved_sp_limit;
-                       irqtp->task = NULL;
+       check_stack_overflow();
 
+       irq = ppc_md.get_irq();
 
-                       /* Set any flag that may have been set on the
-                        * alternate stack
-                        */
-                       if (irqtp->flags)
-                               set_bits(irqtp->flags, &curtp->flags);
-               } else
-#endif
-                       generic_handle_irq(irq);
-       } else if (irq != NO_IRQ_IGNORE)
+       if (irq != NO_IRQ && irq != NO_IRQ_IGNORE)
+               handle_one_irq(irq);
+       else if (irq != NO_IRQ_IGNORE)
                /* That's not SMP safe ... but who cares ? */
                ppc_spurious_interrupts++;
 
index 78b3f7840ade9d4246ef07ebb39660fc6fd35f82..2419cc706ff1cc798ac9898f0bb68ae0a2140857 100644 (file)
@@ -169,6 +169,9 @@ struct hvcall_ppp_data {
        u8      unallocated_weight;
        u16     active_procs_in_pool;
        u16     active_system_procs;
+       u16     phys_platform_procs;
+       u32     max_proc_cap_avail;
+       u32     entitled_proc_cap_avail;
 };
 
 /*
@@ -190,13 +193,18 @@ struct hvcall_ppp_data {
  *            XX - Unallocated Variable Processor Capacity Weight.
  *              XXXX - Active processors in Physical Processor Pool.
  *                  XXXX  - Processors active on platform.
+ *  R8 (QQQQRRRRRRSSSSSS). if ibm,partition-performance-parameters-level >= 1
+ *     XXXX - Physical platform procs allocated to virtualization.
+ *         XXXXXX - Max procs capacity % available to the partitions pool.
+ *               XXXXXX - Entitled procs capacity % available to the
+ *                        partitions pool.
  */
 static unsigned int h_get_ppp(struct hvcall_ppp_data *ppp_data)
 {
        unsigned long rc;
-       unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
+       unsigned long retbuf[PLPAR_HCALL9_BUFSIZE];
 
-       rc = plpar_hcall(H_GET_PPP, retbuf);
+       rc = plpar_hcall9(H_GET_PPP, retbuf);
 
        ppp_data->entitlement = retbuf[0];
        ppp_data->unallocated_entitlement = retbuf[1];
@@ -210,6 +218,10 @@ static unsigned int h_get_ppp(struct hvcall_ppp_data *ppp_data)
        ppp_data->active_procs_in_pool = (retbuf[3] >> 2 * 8) & 0xffff;
        ppp_data->active_system_procs = retbuf[3] & 0xffff;
 
+       ppp_data->phys_platform_procs = retbuf[4] >> 6 * 8;
+       ppp_data->max_proc_cap_avail = (retbuf[4] >> 3 * 8) & 0xffffff;
+       ppp_data->entitled_proc_cap_avail = retbuf[4] & 0xffffff;
+
        return rc;
 }
 
@@ -234,6 +246,8 @@ static unsigned h_pic(unsigned long *pool_idle_time,
 static void parse_ppp_data(struct seq_file *m)
 {
        struct hvcall_ppp_data ppp_data;
+       struct device_node *root;
+       const int *perf_level;
        int rc;
 
        rc = h_get_ppp(&ppp_data);
@@ -267,6 +281,28 @@ static void parse_ppp_data(struct seq_file *m)
        seq_printf(m, "capped=%d\n", ppp_data.capped);
        seq_printf(m, "unallocated_capacity=%lld\n",
                   ppp_data.unallocated_entitlement);
+
+       /* The last bits of information returned from h_get_ppp are only
+        * valid if the ibm,partition-performance-parameters-level
+        * property is >= 1.
+        */
+       root = of_find_node_by_path("/");
+       if (root) {
+               perf_level = of_get_property(root,
+                               "ibm,partition-performance-parameters-level",
+                                            NULL);
+               if (perf_level && (*perf_level >= 1)) {
+                       seq_printf(m,
+                           "physical_procs_allocated_to_virtualization=%d\n",
+                                  ppp_data.phys_platform_procs);
+                       seq_printf(m, "max_proc_capacity_available=%d\n",
+                                  ppp_data.max_proc_cap_avail);
+                       seq_printf(m, "entitled_proc_capacity_available=%d\n",
+                                  ppp_data.entitled_proc_cap_avail);
+               }
+
+               of_node_put(root);
+       }
 }
 
 /**
index b9530b2395a289847f011d8f3cbc5278e1cb8c76..a5cf9c1356a674c05d902bcf71e1b0c8a4b4bef1 100644 (file)
@@ -457,98 +457,6 @@ _GLOBAL(disable_kernel_fp)
        isync
        blr
 
-#ifdef CONFIG_ALTIVEC
-
-#if 0 /* this has no callers for now */
-/*
- * disable_kernel_altivec()
- * Disable the VMX.
- */
-_GLOBAL(disable_kernel_altivec)
-       mfmsr   r3
-       rldicl  r0,r3,(63-MSR_VEC_LG),1
-       rldicl  r3,r0,(MSR_VEC_LG+1),0
-       mtmsrd  r3                      /* disable use of VMX now */
-       isync
-       blr
-#endif /* 0 */
-
-/*
- * giveup_altivec(tsk)
- * Disable VMX for the task given as the argument,
- * and save the vector registers in its thread_struct.
- * Enables the VMX for use in the kernel on return.
- */
-_GLOBAL(giveup_altivec)
-       mfmsr   r5
-       oris    r5,r5,MSR_VEC@h
-       mtmsrd  r5                      /* enable use of VMX now */
-       isync
-       cmpdi   0,r3,0
-       beqlr-                          /* if no previous owner, done */
-       addi    r3,r3,THREAD            /* want THREAD of task */
-       ld      r5,PT_REGS(r3)
-       cmpdi   0,r5,0
-       SAVE_32VRS(0,r4,r3)
-       mfvscr  vr0
-       li      r4,THREAD_VSCR
-       stvx    vr0,r4,r3
-       beq     1f
-       ld      r4,_MSR-STACK_FRAME_OVERHEAD(r5)
-#ifdef CONFIG_VSX
-BEGIN_FTR_SECTION
-       lis     r3,(MSR_VEC|MSR_VSX)@h
-FTR_SECTION_ELSE
-       lis     r3,MSR_VEC@h
-ALT_FTR_SECTION_END_IFSET(CPU_FTR_VSX)
-#else
-       lis     r3,MSR_VEC@h
-#endif
-       andc    r4,r4,r3                /* disable FP for previous task */
-       std     r4,_MSR-STACK_FRAME_OVERHEAD(r5)
-1:
-#ifndef CONFIG_SMP
-       li      r5,0
-       ld      r4,last_task_used_altivec@got(r2)
-       std     r5,0(r4)
-#endif /* CONFIG_SMP */
-       blr
-
-#endif /* CONFIG_ALTIVEC */
-
-#ifdef CONFIG_VSX
-/*
- * __giveup_vsx(tsk)
- * Disable VSX for the task given as the argument.
- * Does NOT save vsx registers.
- * Enables the VSX for use in the kernel on return.
- */
-_GLOBAL(__giveup_vsx)
-       mfmsr   r5
-       oris    r5,r5,MSR_VSX@h
-       mtmsrd  r5                      /* enable use of VSX now */
-       isync
-
-       cmpdi   0,r3,0
-       beqlr-                          /* if no previous owner, done */
-       addi    r3,r3,THREAD            /* want THREAD of task */
-       ld      r5,PT_REGS(r3)
-       cmpdi   0,r5,0
-       beq     1f
-       ld      r4,_MSR-STACK_FRAME_OVERHEAD(r5)
-       lis     r3,MSR_VSX@h
-       andc    r4,r4,r3                /* disable VSX for previous task */
-       std     r4,_MSR-STACK_FRAME_OVERHEAD(r5)
-1:
-#ifndef CONFIG_SMP
-       li      r5,0
-       ld      r4,last_task_used_vsx@got(r2)
-       std     r5,0(r4)
-#endif /* CONFIG_SMP */
-       blr
-
-#endif /* CONFIG_VSX */
-
 /* kexec_wait(phys_cpu)
  *
  * wait for the flag to change, indicating this kernel is going away but
index c744b327bcabc866230198eda4dce37169ad0151..e9962c7f8a0999a8ff2662c17daa1d9b92b8891f 100644 (file)
@@ -18,6 +18,8 @@
  * field correctly */
 extern unsigned long __toc_start;
 
+#ifdef CONFIG_PPC_BOOK3S
+
 /*
  * The structure which the hypervisor knows about - this structure
  * should not cross a page boundary.  The vpa_init/register_vpa call
@@ -41,6 +43,10 @@ struct lppaca lppaca[] = {
        },
 };
 
+#endif /* CONFIG_PPC_BOOK3S */
+
+#ifdef CONFIG_PPC_STD_MMU_64
+
 /*
  * 3 persistent SLBs are registered here.  The buffer will be zero
  * initially, hence will all be invaild until we actually write them.
@@ -52,6 +58,8 @@ struct slb_shadow slb_shadow[] __cacheline_aligned = {
        },
 };
 
+#endif /* CONFIG_PPC_STD_MMU_64 */
+
 /* The Paca is an array with one entry per processor.  Each contains an
  * lppaca, which contains the information shared between the
  * hypervisor and Linux.
@@ -77,15 +85,19 @@ void __init initialise_pacas(void)
        for (cpu = 0; cpu < NR_CPUS; cpu++) {
                struct paca_struct *new_paca = &paca[cpu];
 
+#ifdef CONFIG_PPC_BOOK3S
                new_paca->lppaca_ptr = &lppaca[cpu];
+#endif
                new_paca->lock_token = 0x8000;
                new_paca->paca_index = cpu;
                new_paca->kernel_toc = kernel_toc;
                new_paca->kernelbase = (unsigned long) _stext;
                new_paca->kernel_msr = MSR_KERNEL;
                new_paca->hw_cpu_id = 0xffff;
-               new_paca->slb_shadow_ptr = &slb_shadow[cpu];
                new_paca->__current = &init_task;
+#ifdef CONFIG_PPC_STD_MMU_64
+               new_paca->slb_shadow_ptr = &slb_shadow[cpu];
+#endif /* CONFIG_PPC_STD_MMU_64 */
 
        }
 }
index 4fee63cb53ff99537a340b3faf913fe40bd51036..5a56e97c5ac00270d7481d88dade90e768b3d695 100644 (file)
@@ -1505,7 +1505,7 @@ void __init pcibios_resource_survey(void)
  * rest of the code later, for now, keep it as-is as our main
  * resource allocation function doesn't deal with sub-trees yet.
  */
-void __devinit pcibios_claim_one_bus(struct pci_bus *bus)
+void pcibios_claim_one_bus(struct pci_bus *bus)
 {
        struct pci_dev *dev;
        struct pci_bus *child_bus;
@@ -1533,7 +1533,6 @@ void __devinit pcibios_claim_one_bus(struct pci_bus *bus)
        list_for_each_entry(child_bus, &bus->children, node)
                pcibios_claim_one_bus(child_bus);
 }
-EXPORT_SYMBOL_GPL(pcibios_claim_one_bus);
 
 
 /* pcibios_finish_adding_to_bus
index d473634e39e3cf63e10de5d3f8aef5075eafd9a8..3ae1c666ff9276c3a26ed90ce7c406f4717ab2d1 100644 (file)
@@ -33,7 +33,6 @@ int pcibios_assign_bus_offset = 1;
 
 void pcibios_make_OF_bus_map(void);
 
-static void fixup_broken_pcnet32(struct pci_dev* dev);
 static void fixup_cpc710_pci64(struct pci_dev* dev);
 #ifdef CONFIG_PPC_OF
 static u8* pci_to_OF_bus_map;
@@ -71,16 +70,6 @@ fixup_hide_host_resource_fsl(struct pci_dev *dev)
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MOTOROLA, PCI_ANY_ID, fixup_hide_host_resource_fsl); 
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_FREESCALE, PCI_ANY_ID, fixup_hide_host_resource_fsl); 
 
-static void
-fixup_broken_pcnet32(struct pci_dev* dev)
-{
-       if ((dev->class>>8 == PCI_CLASS_NETWORK_ETHERNET)) {
-               dev->vendor = PCI_VENDOR_ID_AMD;
-               pci_write_config_word(dev, PCI_VENDOR_ID, PCI_VENDOR_ID_AMD);
-       }
-}
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TRIDENT,        PCI_ANY_ID,                     fixup_broken_pcnet32);
-
 static void
 fixup_cpc710_pci64(struct pci_dev* dev)
 {
@@ -447,14 +436,6 @@ static int __init pcibios_init(void)
 
 subsys_initcall(pcibios_init);
 
-/* the next one is stolen from the alpha port... */
-void __init
-pcibios_update_irq(struct pci_dev *dev, int irq)
-{
-       pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
-       /* XXX FIXME - update OF device tree node interrupt property */
-}
-
 static struct pci_controller*
 pci_bus_to_hose(int bus)
 {
index 96edb6f8babb161c4d3d4b8b41b5bac7d999867c..9e8902fa14c701a8ca21b6cc2434bb20a12a4dce 100644 (file)
@@ -43,16 +43,6 @@ unsigned long pci_probe_only = 1;
 unsigned long pci_io_base = ISA_IO_BASE;
 EXPORT_SYMBOL(pci_io_base);
 
-static void fixup_broken_pcnet32(struct pci_dev* dev)
-{
-       if ((dev->class>>8 == PCI_CLASS_NETWORK_ETHERNET)) {
-               dev->vendor = PCI_VENDOR_ID_AMD;
-               pci_write_config_word(dev, PCI_VENDOR_ID, PCI_VENDOR_ID_AMD);
-       }
-}
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TRIDENT, PCI_ANY_ID, fixup_broken_pcnet32);
-
-
 static u32 get_int_prop(struct device_node *np, const char *name, u32 def)
 {
        const u32 *prop;
@@ -430,6 +420,9 @@ int pcibios_unmap_io_space(struct pci_bus *bus)
         * so flushing the hash table is the only sane way to make sure
         * that no hash entries are covering that removed bridge area
         * while still allowing other busses overlapping those pages
+        *
+        * Note: If we ever support P2P hotplug on Book3E, we'll have
+        * to do an appropriate TLB flush here too
         */
        if (bus->self) {
                struct resource *res = bus->resource[0];
@@ -437,8 +430,10 @@ int pcibios_unmap_io_space(struct pci_bus *bus)
                pr_debug("IO unmapping for PCI-PCI bridge %s\n",
                         pci_name(bus->self));
 
+#ifdef CONFIG_PPC_STD_MMU_64
                __flush_hash_table_range(&init_mm, res->start + _IO_BASE,
                                         res->end + _IO_BASE + 1);
+#endif
                return 0;
        }
 
@@ -511,7 +506,7 @@ int __devinit pcibios_map_io_space(struct pci_bus *bus)
        pr_debug("IO mapping for PHB %s\n", hose->dn->full_name);
        pr_debug("  phys=0x%016llx, virt=0x%p (alloc=0x%p)\n",
                 hose->io_base_phys, hose->io_base_virt, hose->io_base_alloc);
-       pr_debug("  size=0x%016lx (alloc=0x%016lx)\n",
+       pr_debug("  size=0x%016llx (alloc=0x%016lx)\n",
                 hose->pci_io_size, size_page);
 
        /* Establish the mapping */
index 1c67de52e3ce5d44e2a91c08b1cedd661e240f4a..d5e36e5dc7c21368cb088c21013c961d9f232328 100644 (file)
@@ -27,7 +27,6 @@
 #include <asm/io.h>
 #include <asm/prom.h>
 #include <asm/pci-bridge.h>
-#include <asm/pSeries_reconfig.h>
 #include <asm/ppc-pci.h>
 #include <asm/firmware.h>
 
@@ -35,7 +34,7 @@
  * Traverse_func that inits the PCI fields of the device node.
  * NOTE: this *must* be done before read/write config to the device.
  */
-static void * __devinit update_dn_pci_info(struct device_node *dn, void *data)
+void * __devinit update_dn_pci_info(struct device_node *dn, void *data)
 {
        struct pci_controller *phb = data;
        const int *type =
@@ -184,29 +183,6 @@ struct device_node *fetch_dev_dn(struct pci_dev *dev)
 }
 EXPORT_SYMBOL(fetch_dev_dn);
 
-static int pci_dn_reconfig_notifier(struct notifier_block *nb, unsigned long action, void *node)
-{
-       struct device_node *np = node;
-       struct pci_dn *pci = NULL;
-       int err = NOTIFY_OK;
-
-       switch (action) {
-       case PSERIES_RECONFIG_ADD:
-               pci = np->parent->data;
-               if (pci)
-                       update_dn_pci_info(np, pci->phb);
-               break;
-       default:
-               err = NOTIFY_DONE;
-               break;
-       }
-       return err;
-}
-
-static struct notifier_block pci_dn_reconfig_nb = {
-       .notifier_call = pci_dn_reconfig_notifier,
-};
-
 /** 
  * pci_devs_phb_init - Initialize phbs and pci devs under them.
  * 
@@ -223,6 +199,4 @@ void __init pci_devs_phb_init(void)
        /* This must be done first so the device nodes have valid pci info! */
        list_for_each_entry_safe(phb, tmp, &hose_list, list_node)
                pci_devs_phb_init_dynamic(phb);
-
-       pSeries_reconfig_notifier_register(&pci_dn_reconfig_nb);
 }
index 7b44a33f03c230a07381f876f25da1fdb7871c6a..3e7135bbe40f648c9a76c82b57fbd72a4e2aba95 100644 (file)
@@ -650,7 +650,7 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
        p->thread.ksp_limit = (unsigned long)task_stack_page(p) +
                                _ALIGN_UP(sizeof(struct thread_info), 16);
 
-#ifdef CONFIG_PPC64
+#ifdef CONFIG_PPC_STD_MMU_64
        if (cpu_has_feature(CPU_FTR_SLB)) {
                unsigned long sp_vsid;
                unsigned long llp = mmu_psize_defs[mmu_linear_psize].sllp;
index ce01ff2474da8a68785e72f9246f9de9de86ce16..d4405b95bfaa708b4511e259d6a5e6b1a73582d9 100644 (file)
@@ -585,7 +585,7 @@ static void __init check_cpu_pa_features(unsigned long node)
                      ibm_pa_features, ARRAY_SIZE(ibm_pa_features));
 }
 
-#ifdef CONFIG_PPC64
+#ifdef CONFIG_PPC_STD_MMU_64
 static void __init check_cpu_slb_size(unsigned long node)
 {
        u32 *slb_size_ptr;
index 3635be61f89995bc43e5dfdbc6e0acc7327f1399..9fa2c7dcd05a4501034395e6f587523cffb969d0 100644 (file)
@@ -704,15 +704,34 @@ void user_enable_single_step(struct task_struct *task)
 
        if (regs != NULL) {
 #if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
+               task->thread.dbcr0 &= ~DBCR0_BT;
                task->thread.dbcr0 |= DBCR0_IDM | DBCR0_IC;
                regs->msr |= MSR_DE;
 #else
+               regs->msr &= ~MSR_BE;
                regs->msr |= MSR_SE;
 #endif
        }
        set_tsk_thread_flag(task, TIF_SINGLESTEP);
 }
 
+void user_enable_block_step(struct task_struct *task)
+{
+       struct pt_regs *regs = task->thread.regs;
+
+       if (regs != NULL) {
+#if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
+               task->thread.dbcr0 &= ~DBCR0_IC;
+               task->thread.dbcr0 = DBCR0_IDM | DBCR0_BT;
+               regs->msr |= MSR_DE;
+#else
+               regs->msr &= ~MSR_SE;
+               regs->msr |= MSR_BE;
+#endif
+       }
+       set_tsk_thread_flag(task, TIF_SINGLESTEP);
+}
+
 void user_disable_single_step(struct task_struct *task)
 {
        struct pt_regs *regs = task->thread.regs;
@@ -726,10 +745,10 @@ void user_disable_single_step(struct task_struct *task)
 
        if (regs != NULL) {
 #if defined(CONFIG_40x) || defined(CONFIG_BOOKE)
-               task->thread.dbcr0 &= ~(DBCR0_IC | DBCR0_IDM);
+               task->thread.dbcr0 &= ~(DBCR0_IC | DBCR0_BT | DBCR0_IDM);
                regs->msr &= ~MSR_DE;
 #else
-               regs->msr &= ~MSR_SE;
+               regs->msr &= ~(MSR_SE | MSR_BE);
 #endif
        }
        clear_tsk_thread_flag(task, TIF_SINGLESTEP);
index 8869001ab5d7691baae77296e6ca4bdd7aec010d..54e66da8f743f4363729d92d46a53404a56e2003 100644 (file)
@@ -93,10 +93,7 @@ static int rtas_pci_read_config(struct pci_bus *bus,
 {
        struct device_node *busdn, *dn;
 
-       if (bus->self)
-               busdn = pci_device_to_OF_node(bus->self);
-       else
-               busdn = bus->sysdata;   /* must be a phb */
+       busdn = pci_bus_to_OF_node(bus);
 
        /* Search only direct children of the bus */
        for (dn = busdn->child; dn; dn = dn->sibling) {
@@ -140,10 +137,7 @@ static int rtas_pci_write_config(struct pci_bus *bus,
 {
        struct device_node *busdn, *dn;
 
-       if (bus->self)
-               busdn = pci_device_to_OF_node(bus->self);
-       else
-               busdn = bus->sysdata;   /* must be a phb */
+       busdn = pci_bus_to_OF_node(bus);
 
        /* Search only direct children of the bus */
        for (dn = busdn->child; dn; dn = dn->sibling) {
index 9e1ca745d8f059afc2809353eaae248155b9c282..1d154248cf40e934aaf295d33e7ca466295ec91a 100644 (file)
@@ -39,6 +39,7 @@
 #include <asm/serial.h>
 #include <asm/udbg.h>
 #include <asm/mmu_context.h>
+#include <asm/swiotlb.h>
 
 #include "setup.h"
 
@@ -332,6 +333,11 @@ void __init setup_arch(char **cmdline_p)
                ppc_md.setup_arch();
        if ( ppc_md.progress ) ppc_md.progress("arch: exit", 0x3eab);
 
+#ifdef CONFIG_SWIOTLB
+       if (ppc_swiotlb_enable)
+               swiotlb_init();
+#endif
+
        paging_init();
 
        /* Initialize the MMU context management stuff */
index c410c606955da7770acacbaa1737a163db4c749d..f46548e6604550ac45309c07932efcb5db08a818 100644 (file)
@@ -61,6 +61,7 @@
 #include <asm/xmon.h>
 #include <asm/udbg.h>
 #include <asm/kexec.h>
+#include <asm/swiotlb.h>
 
 #include "setup.h"
 
@@ -417,9 +418,11 @@ void __init setup_system(void)
        if (ppc64_caches.iline_size != 0x80)
                printk("ppc64_caches.icache_line_size = 0x%x\n",
                       ppc64_caches.iline_size);
+#ifdef CONFIG_PPC_STD_MMU_64
        if (htab_address)
                printk("htab_address                  = 0x%p\n", htab_address);
        printk("htab_hash_mask                = 0x%lx\n", htab_hash_mask);
+#endif /* CONFIG_PPC_STD_MMU_64 */
        if (PHYSICAL_START > 0)
                printk("physical_start                = 0x%lx\n",
                       PHYSICAL_START);
@@ -511,8 +514,9 @@ void __init setup_arch(char **cmdline_p)
        irqstack_early_init();
        emergency_stack_init();
 
+#ifdef CONFIG_PPC_STD_MMU_64
        stabs_alloc();
-
+#endif
        /* set up the bootmem stuff with available memory */
        do_init_bootmem();
        sparse_init();
@@ -524,6 +528,11 @@ void __init setup_arch(char **cmdline_p)
        if (ppc_md.setup_arch)
                ppc_md.setup_arch();
 
+#ifdef CONFIG_SWIOTLB
+       if (ppc_swiotlb_enable)
+               swiotlb_init();
+#endif
+
        paging_init();
        ppc64_boot_msg(0x15, "Setup Done");
 }
index 48571ac56fb7f9747e9e2cea8b05d44acc44802e..bee1443da7634d3cf9a062d9223a11d4a63540de 100644 (file)
@@ -109,7 +109,7 @@ static void decrementer_set_mode(enum clock_event_mode mode,
 static struct clock_event_device decrementer_clockevent = {
        .name           = "decrementer",
        .rating         = 200,
-       .shift          = 16,
+       .shift          = 0,    /* To be filled in */
        .mult           = 0,    /* To be filled in */
        .irq            = 0,
        .set_next_event = decrementer_set_next_event,
@@ -843,6 +843,22 @@ static void decrementer_set_mode(enum clock_event_mode mode,
                decrementer_set_next_event(DECREMENTER_MAX, dev);
 }
 
+static void __init setup_clockevent_multiplier(unsigned long hz)
+{
+       u64 mult, shift = 32;
+
+       while (1) {
+               mult = div_sc(hz, NSEC_PER_SEC, shift);
+               if (mult && (mult >> 32UL) == 0UL)
+                       break;
+
+               shift--;
+       }
+
+       decrementer_clockevent.shift = shift;
+       decrementer_clockevent.mult = mult;
+}
+
 static void register_decrementer_clockevent(int cpu)
 {
        struct clock_event_device *dec = &per_cpu(decrementers, cpu).event;
@@ -860,8 +876,7 @@ static void __init init_decrementer_clockevent(void)
 {
        int cpu = smp_processor_id();
 
-       decrementer_clockevent.mult = div_sc(ppc_tb_freq, NSEC_PER_SEC,
-                                            decrementer_clockevent.shift);
+       setup_clockevent_multiplier(ppc_tb_freq);
        decrementer_clockevent.max_delta_ns =
                clockevent_delta2ns(DECREMENTER_MAX, &decrementer_clockevent);
        decrementer_clockevent.min_delta_ns =
index 678fbff0d206e8fdc47db0c6450be09bd8bfffb1..6f0ae1a9bfae6d78b31afdf15f1c22d554e5900d 100644 (file)
@@ -33,7 +33,9 @@
 #include <linux/backlight.h>
 #include <linux/bug.h>
 #include <linux/kdebug.h>
+#include <linux/debugfs.h>
 
+#include <asm/emulated_ops.h>
 #include <asm/pgtable.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
@@ -757,36 +759,44 @@ static int emulate_instruction(struct pt_regs *regs)
 
        /* Emulate the mfspr rD, PVR. */
        if ((instword & PPC_INST_MFSPR_PVR_MASK) == PPC_INST_MFSPR_PVR) {
+               PPC_WARN_EMULATED(mfpvr);
                rd = (instword >> 21) & 0x1f;
                regs->gpr[rd] = mfspr(SPRN_PVR);
                return 0;
        }
 
        /* Emulating the dcba insn is just a no-op.  */
-       if ((instword & PPC_INST_DCBA_MASK) == PPC_INST_DCBA)
+       if ((instword & PPC_INST_DCBA_MASK) == PPC_INST_DCBA) {
+               PPC_WARN_EMULATED(dcba);
                return 0;
+       }
 
        /* Emulate the mcrxr insn.  */
        if ((instword & PPC_INST_MCRXR_MASK) == PPC_INST_MCRXR) {
                int shift = (instword >> 21) & 0x1c;
                unsigned long msk = 0xf0000000UL >> shift;
 
+               PPC_WARN_EMULATED(mcrxr);
                regs->ccr = (regs->ccr & ~msk) | ((regs->xer >> shift) & msk);
                regs->xer &= ~0xf0000000UL;
                return 0;
        }
 
        /* Emulate load/store string insn. */
-       if ((instword & PPC_INST_STRING_GEN_MASK) == PPC_INST_STRING)
+       if ((instword & PPC_INST_STRING_GEN_MASK) == PPC_INST_STRING) {
+               PPC_WARN_EMULATED(string);
                return emulate_string_inst(regs, instword);
+       }
 
        /* Emulate the popcntb (Population Count Bytes) instruction. */
        if ((instword & PPC_INST_POPCNTB_MASK) == PPC_INST_POPCNTB) {
+               PPC_WARN_EMULATED(popcntb);
                return emulate_popcntb_inst(regs, instword);
        }
 
        /* Emulate isel (Integer Select) instruction */
        if ((instword & PPC_INST_ISEL_MASK) == PPC_INST_ISEL) {
+               PPC_WARN_EMULATED(isel);
                return emulate_isel(regs, instword);
        }
 
@@ -984,6 +994,8 @@ void SoftwareEmulation(struct pt_regs *regs)
 
 #ifdef CONFIG_MATH_EMULATION
        errcode = do_mathemu(regs);
+       if (errcode >= 0)
+               PPC_WARN_EMULATED(math);
 
        switch (errcode) {
        case 0:
@@ -1005,6 +1017,9 @@ void SoftwareEmulation(struct pt_regs *regs)
 
 #elif defined(CONFIG_8XX_MINIMAL_FPEMU)
        errcode = Soft_emulate_8xx(regs);
+       if (errcode >= 0)
+               PPC_WARN_EMULATED(8xx);
+
        switch (errcode) {
        case 0:
                emulate_single_step(regs);
@@ -1026,7 +1041,34 @@ void SoftwareEmulation(struct pt_regs *regs)
 
 void __kprobes DebugException(struct pt_regs *regs, unsigned long debug_status)
 {
-       if (debug_status & DBSR_IC) {   /* instruction completion */
+       /* Hack alert: On BookE, Branch Taken stops on the branch itself, while
+        * on server, it stops on the target of the branch. In order to simulate
+        * the server behaviour, we thus restart right away with a single step
+        * instead of stopping here when hitting a BT
+        */
+       if (debug_status & DBSR_BT) {
+               regs->msr &= ~MSR_DE;
+
+               /* Disable BT */
+               mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) & ~DBCR0_BT);
+               /* Clear the BT event */
+               mtspr(SPRN_DBSR, DBSR_BT);
+
+               /* Do the single step trick only when coming from userspace */
+               if (user_mode(regs)) {
+                       current->thread.dbcr0 &= ~DBCR0_BT;
+                       current->thread.dbcr0 |= DBCR0_IDM | DBCR0_IC;
+                       regs->msr |= MSR_DE;
+                       return;
+               }
+
+               if (notify_die(DIE_SSTEP, "block_step", regs, 5,
+                              5, SIGTRAP) == NOTIFY_STOP) {
+                       return;
+               }
+               if (debugger_sstep(regs))
+                       return;
+       } else if (debug_status & DBSR_IC) {    /* Instruction complete */
                regs->msr &= ~MSR_DE;
 
                /* Disable instruction completion */
@@ -1042,9 +1084,8 @@ void __kprobes DebugException(struct pt_regs *regs, unsigned long debug_status)
                if (debugger_sstep(regs))
                        return;
 
-               if (user_mode(regs)) {
-                       current->thread.dbcr0 &= ~DBCR0_IC;
-               }
+               if (user_mode(regs))
+                       current->thread.dbcr0 &= ~(DBCR0_IC);
 
                _exception(SIGTRAP, regs, TRAP_TRACE, regs->nip);
        } else if (debug_status & (DBSR_DAC1R | DBSR_DAC1W)) {
@@ -1088,6 +1129,7 @@ void altivec_assist_exception(struct pt_regs *regs)
 
        flush_altivec_to_thread(current);
 
+       PPC_WARN_EMULATED(altivec);
        err = emulate_altivec(regs);
        if (err == 0) {
                regs->nip += 4;         /* skip emulated instruction */
@@ -1286,3 +1328,79 @@ void kernel_bad_stack(struct pt_regs *regs)
 void __init trap_init(void)
 {
 }
+
+
+#ifdef CONFIG_PPC_EMULATED_STATS
+
+#define WARN_EMULATED_SETUP(type)      .type = { .name = #type }
+
+struct ppc_emulated ppc_emulated = {
+#ifdef CONFIG_ALTIVEC
+       WARN_EMULATED_SETUP(altivec),
+#endif
+       WARN_EMULATED_SETUP(dcba),
+       WARN_EMULATED_SETUP(dcbz),
+       WARN_EMULATED_SETUP(fp_pair),
+       WARN_EMULATED_SETUP(isel),
+       WARN_EMULATED_SETUP(mcrxr),
+       WARN_EMULATED_SETUP(mfpvr),
+       WARN_EMULATED_SETUP(multiple),
+       WARN_EMULATED_SETUP(popcntb),
+       WARN_EMULATED_SETUP(spe),
+       WARN_EMULATED_SETUP(string),
+       WARN_EMULATED_SETUP(unaligned),
+#ifdef CONFIG_MATH_EMULATION
+       WARN_EMULATED_SETUP(math),
+#elif defined(CONFIG_8XX_MINIMAL_FPEMU)
+       WARN_EMULATED_SETUP(8xx),
+#endif
+#ifdef CONFIG_VSX
+       WARN_EMULATED_SETUP(vsx),
+#endif
+};
+
+u32 ppc_warn_emulated;
+
+void ppc_warn_emulated_print(const char *type)
+{
+       if (printk_ratelimit())
+               pr_warning("%s used emulated %s instruction\n", current->comm,
+                          type);
+}
+
+static int __init ppc_warn_emulated_init(void)
+{
+       struct dentry *dir, *d;
+       unsigned int i;
+       struct ppc_emulated_entry *entries = (void *)&ppc_emulated;
+
+       if (!powerpc_debugfs_root)
+               return -ENODEV;
+
+       dir = debugfs_create_dir("emulated_instructions",
+                                powerpc_debugfs_root);
+       if (!dir)
+               return -ENOMEM;
+
+       d = debugfs_create_u32("do_warn", S_IRUGO | S_IWUSR, dir,
+                              &ppc_warn_emulated);
+       if (!d)
+               goto fail;
+
+       for (i = 0; i < sizeof(ppc_emulated)/sizeof(*entries); i++) {
+               d = debugfs_create_u32(entries[i].name, S_IRUGO | S_IWUSR, dir,
+                                      (u32 *)&entries[i].val.counter);
+               if (!d)
+                       goto fail;
+       }
+
+       return 0;
+
+fail:
+       debugfs_remove_recursive(dir);
+       return -ENOMEM;
+}
+
+device_initcall(ppc_warn_emulated_init);
+
+#endif /* CONFIG_PPC_EMULATED_STATS */
index 49ac3d6e1399a646309d3d4cdc049caedf02a721..ef36cbbc5882281ccb26ca2c0b4fd14bf23a06d3 100644 (file)
@@ -1,5 +1,215 @@
+#include <asm/processor.h>
 #include <asm/ppc_asm.h>
 #include <asm/reg.h>
+#include <asm/asm-offsets.h>
+#include <asm/cputable.h>
+#include <asm/thread_info.h>
+#include <asm/page.h>
+
+/*
+ * load_up_altivec(unused, unused, tsk)
+ * Disable VMX for the task which had it previously,
+ * and save its vector registers in its thread_struct.
+ * Enables the VMX for use in the kernel on return.
+ * On SMP we know the VMX is free, since we give it up every
+ * switch (ie, no lazy save of the vector registers).
+ */
+_GLOBAL(load_up_altivec)
+       mfmsr   r5                      /* grab the current MSR */
+       oris    r5,r5,MSR_VEC@h
+       MTMSRD(r5)                      /* enable use of AltiVec now */
+       isync
+
+/*
+ * For SMP, we don't do lazy VMX switching because it just gets too
+ * horrendously complex, especially when a task switches from one CPU
+ * to another.  Instead we call giveup_altvec in switch_to.
+ * VRSAVE isn't dealt with here, that is done in the normal context
+ * switch code. Note that we could rely on vrsave value to eventually
+ * avoid saving all of the VREGs here...
+ */
+#ifndef CONFIG_SMP
+       LOAD_REG_ADDRBASE(r3, last_task_used_altivec)
+       toreal(r3)
+       PPC_LL  r4,ADDROFF(last_task_used_altivec)(r3)
+       PPC_LCMPI       0,r4,0
+       beq     1f
+
+       /* Save VMX state to last_task_used_altivec's THREAD struct */
+       toreal(r4)
+       addi    r4,r4,THREAD
+       SAVE_32VRS(0,r5,r4)
+       mfvscr  vr0
+       li      r10,THREAD_VSCR
+       stvx    vr0,r10,r4
+       /* Disable VMX for last_task_used_altivec */
+       PPC_LL  r5,PT_REGS(r4)
+       toreal(r5)
+       PPC_LL  r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+       lis     r10,MSR_VEC@h
+       andc    r4,r4,r10
+       PPC_STL r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+1:
+#endif /* CONFIG_SMP */
+
+       /* Hack: if we get an altivec unavailable trap with VRSAVE
+        * set to all zeros, we assume this is a broken application
+        * that fails to set it properly, and thus we switch it to
+        * all 1's
+        */
+       mfspr   r4,SPRN_VRSAVE
+       cmpdi   0,r4,0
+       bne+    1f
+       li      r4,-1
+       mtspr   SPRN_VRSAVE,r4
+1:
+       /* enable use of VMX after return */
+#ifdef CONFIG_PPC32
+       mfspr   r5,SPRN_SPRG3           /* current task's THREAD (phys) */
+       oris    r9,r9,MSR_VEC@h
+#else
+       ld      r4,PACACURRENT(r13)
+       addi    r5,r4,THREAD            /* Get THREAD */
+       oris    r12,r12,MSR_VEC@h
+       std     r12,_MSR(r1)
+#endif
+       li      r4,1
+       li      r10,THREAD_VSCR
+       stw     r4,THREAD_USED_VR(r5)
+       lvx     vr0,r10,r5
+       mtvscr  vr0
+       REST_32VRS(0,r4,r5)
+#ifndef CONFIG_SMP
+       /* Update last_task_used_math to 'current' */
+       subi    r4,r5,THREAD            /* Back to 'current' */
+       fromreal(r4)
+       PPC_STL r4,ADDROFF(last_task_used_math)(r3)
+#endif /* CONFIG_SMP */
+       /* restore registers and return */
+       blr
+
+/*
+ * giveup_altivec(tsk)
+ * Disable VMX for the task given as the argument,
+ * and save the vector registers in its thread_struct.
+ * Enables the VMX for use in the kernel on return.
+ */
+_GLOBAL(giveup_altivec)
+       mfmsr   r5
+       oris    r5,r5,MSR_VEC@h
+       SYNC
+       MTMSRD(r5)                      /* enable use of VMX now */
+       isync
+       PPC_LCMPI       0,r3,0
+       beqlr-                          /* if no previous owner, done */
+       addi    r3,r3,THREAD            /* want THREAD of task */
+       PPC_LL  r5,PT_REGS(r3)
+       PPC_LCMPI       0,r5,0
+       SAVE_32VRS(0,r4,r3)
+       mfvscr  vr0
+       li      r4,THREAD_VSCR
+       stvx    vr0,r4,r3
+       beq     1f
+       PPC_LL  r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+#ifdef CONFIG_VSX
+BEGIN_FTR_SECTION
+       lis     r3,(MSR_VEC|MSR_VSX)@h
+FTR_SECTION_ELSE
+       lis     r3,MSR_VEC@h
+ALT_FTR_SECTION_END_IFSET(CPU_FTR_VSX)
+#else
+       lis     r3,MSR_VEC@h
+#endif
+       andc    r4,r4,r3                /* disable FP for previous task */
+       PPC_STL r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+1:
+#ifndef CONFIG_SMP
+       li      r5,0
+       LOAD_REG_ADDRBASE(r4,last_task_used_altivec)
+       PPC_STL r5,ADDROFF(last_task_used_altivec)(r4)
+#endif /* CONFIG_SMP */
+       blr
+
+#ifdef CONFIG_VSX
+
+#ifdef CONFIG_PPC32
+#error This asm code isn't ready for 32-bit kernels
+#endif
+
+/*
+ * load_up_vsx(unused, unused, tsk)
+ * Disable VSX for the task which had it previously,
+ * and save its vector registers in its thread_struct.
+ * Reuse the fp and vsx saves, but first check to see if they have
+ * been saved already.
+ */
+_GLOBAL(load_up_vsx)
+/* Load FP and VSX registers if they haven't been done yet */
+       andi.   r5,r12,MSR_FP
+       beql+   load_up_fpu             /* skip if already loaded */
+       andis.  r5,r12,MSR_VEC@h
+       beql+   load_up_altivec         /* skip if already loaded */
+
+#ifndef CONFIG_SMP
+       ld      r3,last_task_used_vsx@got(r2)
+       ld      r4,0(r3)
+       cmpdi   0,r4,0
+       beq     1f
+       /* Disable VSX for last_task_used_vsx */
+       addi    r4,r4,THREAD
+       ld      r5,PT_REGS(r4)
+       ld      r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+       lis     r6,MSR_VSX@h
+       andc    r6,r4,r6
+       std     r6,_MSR-STACK_FRAME_OVERHEAD(r5)
+1:
+#endif /* CONFIG_SMP */
+       ld      r4,PACACURRENT(r13)
+       addi    r4,r4,THREAD            /* Get THREAD */
+       li      r6,1
+       stw     r6,THREAD_USED_VSR(r4) /* ... also set thread used vsr */
+       /* enable use of VSX after return */
+       oris    r12,r12,MSR_VSX@h
+       std     r12,_MSR(r1)
+#ifndef CONFIG_SMP
+       /* Update last_task_used_math to 'current' */
+       ld      r4,PACACURRENT(r13)
+       std     r4,0(r3)
+#endif /* CONFIG_SMP */
+       b       fast_exception_return
+
+/*
+ * __giveup_vsx(tsk)
+ * Disable VSX for the task given as the argument.
+ * Does NOT save vsx registers.
+ * Enables the VSX for use in the kernel on return.
+ */
+_GLOBAL(__giveup_vsx)
+       mfmsr   r5
+       oris    r5,r5,MSR_VSX@h
+       mtmsrd  r5                      /* enable use of VSX now */
+       isync
+
+       cmpdi   0,r3,0
+       beqlr-                          /* if no previous owner, done */
+       addi    r3,r3,THREAD            /* want THREAD of task */
+       ld      r5,PT_REGS(r3)
+       cmpdi   0,r5,0
+       beq     1f
+       ld      r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+       lis     r3,MSR_VSX@h
+       andc    r4,r4,r3                /* disable VSX for previous task */
+       std     r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+1:
+#ifndef CONFIG_SMP
+       li      r5,0
+       ld      r4,last_task_used_vsx@got(r2)
+       std     r5,0(r4)
+#endif /* CONFIG_SMP */
+       blr
+
+#endif /* CONFIG_VSX */
+
 
 /*
  * The routines below are in assembler so we can closely control the
index b746f4ca4209aaa7c385272b098804bbbd7dcb0d..c4bcf072cb3ca5de9ccbec1098eeb5ca067e713b 100644 (file)
@@ -11,10 +11,11 @@ obj-y                               := fault.o mem.o pgtable.o gup.o \
                                   pgtable_$(CONFIG_WORD_SIZE).o
 obj-$(CONFIG_PPC_MMU_NOHASH)   += mmu_context_nohash.o tlb_nohash.o \
                                   tlb_nohash_low.o
-hash-$(CONFIG_PPC_NATIVE)      := hash_native_64.o
-obj-$(CONFIG_PPC64)            += hash_utils_64.o \
+obj-$(CONFIG_PPC64)            += mmap_64.o
+hash64-$(CONFIG_PPC_NATIVE)    := hash_native_64.o
+obj-$(CONFIG_PPC_STD_MMU_64)   += hash_utils_64.o \
                                   slb_low.o slb.o stab.o \
-                                  mmap_64.o $(hash-y)
+                                  mmap_64.o $(hash64-y)
 obj-$(CONFIG_PPC_STD_MMU_32)   += ppc_mmu_32.o
 obj-$(CONFIG_PPC_STD_MMU)      += hash_low_$(CONFIG_WORD_SIZE).o \
                                   tlb_hash$(CONFIG_WORD_SIZE).o \
index 34e5c0b219b92f5792a3ecc886740c0c130ca024..056d23a1b105f851757a082bcb04001e374a48b3 100644 (file)
@@ -27,6 +27,7 @@
 #include <asm/cputable.h>
 #include <asm/udbg.h>
 #include <asm/kexec.h>
+#include <asm/ppc-opcode.h>
 
 #ifdef DEBUG_LOW
 #define DBG_LOW(fmt...) udbg_printf(fmt)
@@ -49,14 +50,21 @@ static inline void __tlbie(unsigned long va, int psize, int ssize)
        case MMU_PAGE_4K:
                va &= ~0xffful;
                va |= ssize << 8;
-               asm volatile("tlbie %0,0" : : "r" (va) : "memory");
+               asm volatile(ASM_MMU_FTR_IFCLR("tlbie %0,0", PPC_TLBIE(%1,%0),
+                                              %2)
+                            : : "r" (va), "r"(0), "i" (MMU_FTR_TLBIE_206)
+                            : "memory");
                break;
        default:
                penc = mmu_psize_defs[psize].penc;
                va &= ~((1ul << mmu_psize_defs[psize].shift) - 1);
                va |= penc << 12;
                va |= ssize << 8;
-               asm volatile("tlbie %0,1" : : "r" (va) : "memory");
+               va |= 1; /* L */
+               asm volatile(ASM_MMU_FTR_IFCLR("tlbie %0,1", PPC_TLBIE(%1,%0),
+                                              %2)
+                            : : "r" (va), "r"(0), "i" (MMU_FTR_TLBIE_206)
+                            : "memory");
                break;
        }
 }
@@ -80,6 +88,7 @@ static inline void __tlbiel(unsigned long va, int psize, int ssize)
                va &= ~((1ul << mmu_psize_defs[psize].shift) - 1);
                va |= penc << 12;
                va |= ssize << 8;
+               va |= 1; /* L */
                asm volatile(".long 0x7c000224 | (%0 << 11) | (1 << 21)"
                             : : "r"(va) : "memory");
                break;
index 3e6a6543f53a9fa193d49081d1d6fcb3b8353776..68a821add28df21c09c2716cc2cb8ef5c77dc796 100644 (file)
@@ -66,6 +66,7 @@
 
 #include "mmu_decl.h"
 
+#ifdef CONFIG_PPC_STD_MMU_64
 #if PGTABLE_RANGE > USER_VSID_RANGE
 #warning Limited user VSID range means pagetable space is wasted
 #endif
@@ -73,6 +74,7 @@
 #if (TASK_SIZE_USER64 < PGTABLE_RANGE) && (TASK_SIZE_USER64 < USER_VSID_RANGE)
 #warning TASK_SIZE is smaller than it needs to be.
 #endif
+#endif /* CONFIG_PPC_STD_MMU_64 */
 
 phys_addr_t memstart_addr = ~0;
 phys_addr_t kernstart_addr;
index 030d0005b4d2c0682ca1adfd988b52000e73b7f2..8343986809c03fe2b3e952e411ec31a611fffe8b 100644 (file)
@@ -46,7 +46,7 @@ static unsigned int next_context, nr_free_contexts;
 static unsigned long *context_map;
 static unsigned long *stale_map[NR_CPUS];
 static struct mm_struct **context_mm;
-static spinlock_t context_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(context_lock);
 
 #define CTX_MAP_SIZE   \
        (sizeof(unsigned long) * (last_context / BITS_PER_LONG + 1))
@@ -73,7 +73,6 @@ static unsigned int steal_context_smp(unsigned int id)
        struct mm_struct *mm;
        unsigned int cpu, max;
 
- again:
        max = last_context - first_context;
 
        /* Attempt to free next_context first and then loop until we manage */
@@ -108,7 +107,9 @@ static unsigned int steal_context_smp(unsigned int id)
        spin_unlock(&context_lock);
        cpu_relax();
        spin_lock(&context_lock);
-       goto again;
+
+       /* This will cause the caller to try again */
+       return MMU_NO_CONTEXT;
 }
 #endif  /* CONFIG_SMP */
 
@@ -194,6 +195,8 @@ void switch_mmu_context(struct mm_struct *prev, struct mm_struct *next)
                WARN_ON(prev->context.active < 1);
                prev->context.active--;
        }
+
+ again:
 #endif /* CONFIG_SMP */
 
        /* If we already have a valid assigned context, skip all that */
@@ -212,7 +215,8 @@ void switch_mmu_context(struct mm_struct *prev, struct mm_struct *next)
 #ifdef CONFIG_SMP
                if (num_online_cpus() > 1) {
                        id = steal_context_smp(id);
-                       goto stolen;
+                       if (id == MMU_NO_CONTEXT)
+                               goto again;
                }
 #endif /* CONFIG_SMP */
                id = steal_context_up(id);
@@ -272,6 +276,7 @@ int init_new_context(struct task_struct *t, struct mm_struct *mm)
  */
 void destroy_context(struct mm_struct *mm)
 {
+       unsigned long flags;
        unsigned int id;
 
        if (mm->context.id == MMU_NO_CONTEXT)
@@ -279,18 +284,18 @@ void destroy_context(struct mm_struct *mm)
 
        WARN_ON(mm->context.active != 0);
 
-       spin_lock(&context_lock);
+       spin_lock_irqsave(&context_lock, flags);
        id = mm->context.id;
        if (id != MMU_NO_CONTEXT) {
                __clear_bit(id, context_map);
                mm->context.id = MMU_NO_CONTEXT;
 #ifdef DEBUG_MAP_CONSISTENCY
                mm->context.active = 0;
-               context_mm[id] = NULL;
 #endif
+               context_mm[id] = NULL;
                nr_free_contexts++;
        }
-       spin_unlock(&context_lock);
+       spin_unlock_irqrestore(&context_lock, flags);
 }
 
 #ifdef CONFIG_SMP
index 9047145095aa81ef8e04147ed92ea96155e08b1a..b037d95eeadcc0380b34901f8113518f3bf53fa7 100644 (file)
@@ -981,6 +981,8 @@ void __init do_init_bootmem(void)
                mark_reserved_regions_for_nid(nid);
                sparse_memory_present_with_active_regions(nid);
        }
+
+       init_bootmem_done = 1;
 }
 
 void __init paging_init(void)
index 91596f6ba1f497e4c277150922c105c662bc7a3c..62312abffa28793561a78f37aaf776bc85526ae1 100644 (file)
@@ -228,20 +228,6 @@ static void pmc_stop_ctrs(void)
        mtpmr(PMRN_PMGC0, pmgc0);
 }
 
-static void dump_pmcs(void)
-{
-       printk("pmgc0: %x\n", mfpmr(PMRN_PMGC0));
-       printk("pmc\t\tpmlca\t\tpmlcb\n");
-       printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC0),
-                       mfpmr(PMRN_PMLCA0), mfpmr(PMRN_PMLCB0));
-       printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC1),
-                       mfpmr(PMRN_PMLCA1), mfpmr(PMRN_PMLCB1));
-       printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC2),
-                       mfpmr(PMRN_PMLCA2), mfpmr(PMRN_PMLCB2));
-       printk("%8x\t%8x\t%8x\n", mfpmr(PMRN_PMC3),
-                       mfpmr(PMRN_PMLCA3), mfpmr(PMRN_PMLCB3));
-}
-
 static int fsl_emb_cpu_setup(struct op_counter_config *ctr)
 {
        int i;
index f39c953d5353027dd96ea484ca9f99ec37a4a22a..a6e43cb6f8252aa96d5a421609d1cbd82152bc60 100644 (file)
@@ -45,6 +45,7 @@ config KILAUEA
        depends on 40x
        default n
        select 405EX
+       select PPC40x_SIMPLE
        select PPC4xx_PCI_EXPRESS
        help
          This option enables support for the AMCC PPC405EX evaluation board.
@@ -56,6 +57,7 @@ config MAKALU
        select 405EX
        select PCI
        select PPC4xx_PCI_EXPRESS
+       select PPC40x_SIMPLE
        help
          This option enables support for the AMCC PPC405EX board.
 
index 9bab76a652a61e097ce0b9888307707523e2d640..56e89004c468cc3e43f1a8037354152be20130a2 100644 (file)
@@ -1,6 +1,4 @@
-obj-$(CONFIG_KILAUEA)                          += kilauea.o
 obj-$(CONFIG_HCU4)                             += hcu4.o
-obj-$(CONFIG_MAKALU)                           += makalu.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/kilauea.c b/arch/powerpc/platforms/40x/kilauea.c
deleted file mode 100644 (file)
index fd7d934..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Kilauea board specific routines
- *
- * Copyright 2007-2008 DENX Software Engineering, Stefan Roese <sr@denx.de>
- *
- * Based on the Walnut code by
- * Josh Boyer <jwboyer@linux.vnet.ibm.com>
- * Copyright 2007 IBM Corporation
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- */
-#include <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/pci-bridge.h>
-#include <asm/ppc4xx.h>
-
-static __initdata struct of_device_id kilauea_of_bus[] = {
-       { .compatible = "ibm,plb4", },
-       { .compatible = "ibm,opb", },
-       { .compatible = "ibm,ebc", },
-       {},
-};
-
-static int __init kilauea_device_probe(void)
-{
-       of_platform_bus_probe(NULL, kilauea_of_bus, NULL);
-
-       return 0;
-}
-machine_device_initcall(kilauea, kilauea_device_probe);
-
-static int __init kilauea_probe(void)
-{
-       unsigned long root = of_get_flat_dt_root();
-
-       if (!of_flat_dt_is_compatible(root, "amcc,kilauea"))
-               return 0;
-
-       ppc_pci_set_flags(PPC_PCI_REASSIGN_ALL_RSRC);
-
-       return 1;
-}
-
-define_machine(kilauea) {
-       .name                           = "Kilauea",
-       .probe                          = kilauea_probe,
-       .progress                       = udbg_progress,
-       .init_IRQ                       = uic_init_tree,
-       .get_irq                        = uic_get_irq,
-       .restart                        = ppc4xx_reset_system,
-       .calibrate_decr                 = generic_calibrate_decr,
-};
diff --git a/arch/powerpc/platforms/40x/makalu.c b/arch/powerpc/platforms/40x/makalu.c
deleted file mode 100644 (file)
index a6a1d60..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Makalu board specific routines
- *
- * Copyright 2007 DENX Software Engineering, Stefan Roese <sr@denx.de>
- *
- * Based on the Walnut code by
- * Josh Boyer <jwboyer@linux.vnet.ibm.com>
- * Copyright 2007 IBM Corporation
- *
- * This program is free software; you can redistribute  it and/or modify it
- * under  the terms of  the GNU General  Public License as published by the
- * Free Software Foundation;  either version 2 of the  License, or (at your
- * option) any later version.
- */
-#include <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/pci-bridge.h>
-#include <asm/ppc4xx.h>
-
-static __initdata struct of_device_id makalu_of_bus[] = {
-       { .compatible = "ibm,plb4", },
-       { .compatible = "ibm,opb", },
-       { .compatible = "ibm,ebc", },
-       {},
-};
-
-static int __init makalu_device_probe(void)
-{
-       of_platform_bus_probe(NULL, makalu_of_bus, NULL);
-
-       return 0;
-}
-machine_device_initcall(makalu, makalu_device_probe);
-
-static int __init makalu_probe(void)
-{
-       unsigned long root = of_get_flat_dt_root();
-
-       if (!of_flat_dt_is_compatible(root, "amcc,makalu"))
-               return 0;
-
-       ppc_pci_flags = PPC_PCI_REASSIGN_ALL_RSRC;
-
-       return 1;
-}
-
-define_machine(makalu) {
-       .name                           = "Makalu",
-       .probe                          = makalu_probe,
-       .progress                       = udbg_progress,
-       .init_IRQ                       = uic_init_tree,
-       .get_irq                        = uic_get_irq,
-       .restart                        = ppc4xx_reset_system,
-       .calibrate_decr                 = generic_calibrate_decr,
-};
index f40ac9b8f99f5c9791148b812c5e4bb8f5494b3a..5fd5a5974001c918f33080906e6570e107cc1531 100644 (file)
@@ -51,7 +51,10 @@ machine_device_initcall(ppc40x_simple, ppc40x_device_probe);
  * board.c file for it rather than adding it to this list.
  */
 static char *board[] __initdata = {
-       "amcc,acadia"
+       "amcc,acadia",
+       "amcc,haleakala",
+       "amcc,kilauea",
+       "amcc,makalu"
 };
 
 static int __init ppc40x_probe(void)
index fc7fb001276ce6ae6606440a34ed216eab0a91ec..d0fc6866b00ca04884a2a39bb1d0922763e5a6a0 100644 (file)
@@ -14,6 +14,7 @@
 #include <asm/prom.h>
 #include <asm/time.h>
 #include <asm/xilinx_intc.h>
+#include <asm/xilinx_pci.h>
 #include <asm/ppc4xx.h>
 
 static struct of_device_id xilinx_of_bus_ids[] __initdata = {
@@ -47,6 +48,7 @@ static int __init virtex_probe(void)
 define_machine(virtex) {
        .name                   = "Xilinx Virtex",
        .probe                  = virtex_probe,
+       .setup_arch             = xilinx_pci_init,
        .init_IRQ               = xilinx_intc_init_tree,
        .get_irq                = xilinx_intc_get_irq,
        .restart                = ppc4xx_reset_system,
index 0d83a6a0397d56e5777179c640483218cd9a82d9..90e3192611a4d52d5b19d2b8876912453fcdec84 100644 (file)
@@ -156,7 +156,7 @@ config YOSEMITE
 #        This option enables support for the IBM PPC440GX evaluation board.
 
 config XILINX_VIRTEX440_GENERIC_BOARD
-       bool "Generic Xilinx Virtex 440 board"
+       bool "Generic Xilinx Virtex 5 FXT board support"
        depends on 44x
        default n
        select XILINX_VIRTEX_5_FXT
@@ -171,6 +171,17 @@ config XILINX_VIRTEX440_GENERIC_BOARD
          Most Virtex 5 designs should use this unless it needs to do some
          special configuration at board probe time.
 
+config XILINX_ML510
+       bool "Xilinx ML510 extra support"
+       depends on XILINX_VIRTEX440_GENERIC_BOARD
+       select PPC_PCI_CHOICE
+       select XILINX_PCI if PCI
+       select PPC_INDIRECT_PCI if PCI
+       select PPC_I8259 if PCI
+       help
+         This option enables extra support for features on the Xilinx ML510
+         board.  The ML510 has a PCI bus with ALI south bridge.
+
 config PPC44x_SIMPLE
        bool "Simple PowerPC 44x board support"
        depends on 44x
index 01f51daace13943c2714d6b00751d38666915c12..ee6185aeaa3b9b98e0382267d31484105d7d7237 100644 (file)
@@ -4,3 +4,4 @@ obj-$(CONFIG_EBONY)     += ebony.o
 obj-$(CONFIG_SAM440EP)         += sam440ep.o
 obj-$(CONFIG_WARP)     += warp.o
 obj-$(CONFIG_XILINX_VIRTEX_5_FXT) += virtex.o
+obj-$(CONFIG_XILINX_ML510) += virtex_ml510.o
index 68637faf70ae91b8fcadc48496a1b47e8c042f09..cf96ccaa760cd98ca9efc3cedf12f653e7e8f43d 100644 (file)
@@ -16,6 +16,7 @@
 #include <asm/prom.h>
 #include <asm/time.h>
 #include <asm/xilinx_intc.h>
+#include <asm/xilinx_pci.h>
 #include <asm/reg.h>
 #include <asm/ppc4xx.h>
 #include "44x.h"
@@ -53,6 +54,7 @@ static int __init virtex_probe(void)
 define_machine(virtex) {
        .name                   = "Xilinx Virtex440",
        .probe                  = virtex_probe,
+       .setup_arch             = xilinx_pci_init,
        .init_IRQ               = xilinx_intc_init_tree,
        .get_irq                = xilinx_intc_get_irq,
        .calibrate_decr         = generic_calibrate_decr,
diff --git a/arch/powerpc/platforms/44x/virtex_ml510.c b/arch/powerpc/platforms/44x/virtex_ml510.c
new file mode 100644 (file)
index 0000000..ba4a6e3
--- /dev/null
@@ -0,0 +1,29 @@
+#include <asm/i8259.h>
+#include <linux/pci.h>
+#include "44x.h"
+
+/**
+ * ml510_ail_quirk
+ */
+static void __devinit ml510_ali_quirk(struct pci_dev *dev)
+{
+       /* Enable the IDE controller */
+       pci_write_config_byte(dev, 0x58, 0x4c);
+       /* Assign irq 14 to the primary ide channel */
+       pci_write_config_byte(dev, 0x44, 0x0d);
+       /* Assign irq 15 to the secondary ide channel */
+       pci_write_config_byte(dev, 0x75, 0x0f);
+       /* Set the ide controller in native mode */
+       pci_write_config_byte(dev, 0x09, 0xff);
+
+       /* INTB = disabled, INTA = disabled */
+       pci_write_config_byte(dev, 0x48, 0x00);
+       /* INTD = disabled, INTC = disabled */
+       pci_write_config_byte(dev, 0x4a, 0x00);
+       /* Audio = INT7, Modem = disabled. */
+       pci_write_config_byte(dev, 0x4b, 0x60);
+       /* USB = INT7 */
+       pci_write_config_byte(dev, 0x74, 0x06);
+}
+DECLARE_PCI_FIXUP_EARLY(0x10b9, 0x1533, ml510_ali_quirk);
+
index 960edf89be519b27fb782a9002b7bd18300edc1a..c5118802a281a776b7a3e23f9dddcbf8e36ea75a 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * PIKA Warp(tm) board specific routines
  *
- * Copyright (c) 2008 PIKA Technologies
+ * Copyright (c) 2008-2009 PIKA Technologies
  *   Sean MacLennan <smaclennan@pikatech.com>
  *
  * This program is free software; you can redistribute  it and/or modify it
@@ -15,6 +15,7 @@
 #include <linux/i2c.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
+#include <linux/of_gpio.h>
 
 #include <asm/machdep.h>
 #include <asm/prom.h>
@@ -23,6 +24,7 @@
 #include <asm/uic.h>
 #include <asm/ppc4xx.h>
 
+
 static __initdata struct of_device_id warp_of_bus[] = {
        { .compatible = "ibm,plb4", },
        { .compatible = "ibm,opb", },
@@ -55,6 +57,8 @@ define_machine(warp) {
 };
 
 
+static u32 post_info;
+
 /* I am not sure this is the best place for this... */
 static int __init warp_post_info(void)
 {
@@ -77,21 +81,21 @@ static int __init warp_post_info(void)
 
        iounmap(fpga);
 
-       if (post1 || post2)
+       if (post1 || post2) {
                printk(KERN_INFO "Warp POST %08x %08x\n", post1, post2);
-       else
+               post_info = 1;
+       } else
                printk(KERN_INFO "Warp POST OK\n");
 
        return 0;
 }
-machine_late_initcall(warp, warp_post_info);
 
 
 #ifdef CONFIG_SENSORS_AD7414
 
 static LIST_HEAD(dtm_shutdown_list);
 static void __iomem *dtm_fpga;
-static void __iomem *gpio_base;
+static unsigned green_led, red_led;
 
 
 struct dtm_shutdown {
@@ -134,14 +138,17 @@ int pika_dtm_unregister_shutdown(void (*func)(void *arg), void *arg)
 static irqreturn_t temp_isr(int irq, void *context)
 {
        struct dtm_shutdown *shutdown;
+       int value = 1;
 
        local_irq_disable();
 
+       gpio_set_value(green_led, 0);
+
        /* Run through the shutdown list. */
        list_for_each_entry(shutdown, &dtm_shutdown_list, list)
                shutdown->func(shutdown->arg);
 
-       printk(KERN_EMERG "\n\nCritical Temperature Shutdown\n");
+       printk(KERN_EMERG "\n\nCritical Temperature Shutdown\n\n");
 
        while (1) {
                if (dtm_fpga) {
@@ -149,52 +156,34 @@ static irqreturn_t temp_isr(int irq, void *context)
                        out_be32(dtm_fpga + 0x14, reset);
                }
 
-               if (gpio_base) {
-                       unsigned leds = in_be32(gpio_base);
-
-                       /* green off, red toggle */
-                       leds &= ~0x80000000;
-                       leds ^=  0x40000000;
-
-                       out_be32(gpio_base, leds);
-               }
-
+               gpio_set_value(red_led, value);
+               value ^= 1;
                mdelay(500);
        }
 }
 
 static int pika_setup_leds(void)
 {
-       struct device_node *np;
-       const u32 *gpios;
-       int len;
+       struct device_node *np, *child;
 
-       np = of_find_compatible_node(NULL, NULL, "linux,gpio-led");
+       np = of_find_compatible_node(NULL, NULL, "gpio-leds");
        if (!np) {
-               printk(KERN_ERR __FILE__ ": Unable to find gpio-led\n");
-               return -ENOENT;
-       }
-
-       gpios = of_get_property(np, "gpios", &len);
-       of_node_put(np);
-       if (!gpios || len < 4) {
-               printk(KERN_ERR __FILE__
-                      ": Unable to get gpios property (%d)\n", len);
+               printk(KERN_ERR __FILE__ ": Unable to find leds\n");
                return -ENOENT;
        }
 
-       np = of_find_node_by_phandle(gpios[0]);
-       if (!np) {
-               printk(KERN_ERR __FILE__ ": Unable to find gpio\n");
-               return -ENOENT;
-       }
+       for_each_child_of_node(np, child)
+               if (strcmp(child->name, "green") == 0) {
+                       green_led = of_get_gpio(child, 0);
+                       /* Turn back on the green LED */
+                       gpio_set_value(green_led, 1);
+               } else if (strcmp(child->name, "red") == 0) {
+                       red_led = of_get_gpio(child, 0);
+                       /* Set based on post */
+                       gpio_set_value(red_led, post_info);
+               }
 
-       gpio_base = of_iomap(np, 0);
        of_node_put(np);
-       if (!gpio_base) {
-               printk(KERN_ERR __FILE__ ": Unable to map gpio");
-               return -ENOMEM;
-       }
 
        return 0;
 }
@@ -270,10 +259,10 @@ static int pika_dtm_thread(void __iomem *fpga)
        }
 
 found_it:
-       i2c_put_adapter(adap);
-
        pika_setup_critical_temp(client);
 
+       i2c_put_adapter(adap);
+
        printk(KERN_INFO "PIKA DTM thread running.\n");
 
        while (!kthread_should_stop()) {
@@ -311,6 +300,9 @@ static int __init pika_dtm_start(void)
        if (dtm_fpga == NULL)
                return -ENOENT;
 
+       /* Must get post info before thread starts. */
+       warp_post_info();
+
        dtm_thread = kthread_run(pika_dtm_thread, dtm_fpga, "pika-dtm");
        if (IS_ERR(dtm_thread)) {
                iounmap(dtm_fpga);
@@ -333,6 +325,8 @@ int pika_dtm_unregister_shutdown(void (*func)(void *arg), void *arg)
        return 0;
 }
 
+machine_late_initcall(warp, warp_post_info);
+
 #endif
 
 EXPORT_SYMBOL(pika_dtm_register_shutdown);
index a2068faef6ea9c7b5b4fb2db804a32f33e1598b1..bcc69e1f77c10d800a40432522f121e80119314f 100644 (file)
@@ -34,7 +34,7 @@
 static int rtas_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
                            int len, u32 * val)
 {
-       struct pci_controller *hose = bus->sysdata;
+       struct pci_controller *hose = pci_bus_to_host(bus);
        unsigned long addr = (offset & 0xff) | ((devfn & 0xff) << 8)
            | (((bus->number - hose->first_busno) & 0xff) << 16)
            | (hose->global_number << 24);
@@ -49,7 +49,7 @@ static int rtas_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
 static int rtas_write_config(struct pci_bus *bus, unsigned int devfn,
                             int offset, int len, u32 val)
 {
-       struct pci_controller *hose = bus->sysdata;
+       struct pci_controller *hose = pci_bus_to_host(bus);
        unsigned long addr = (offset & 0xff) | ((devfn & 0xff) << 8)
            | (((bus->number - hose->first_busno) & 0xff) << 16)
            | (hose->global_number << 24);
index 87ff522f28b5ee2c5f13207acbb66945ba350097..dd43114e9684f11b2b0f4a225043ee0206bd3c5c 100644 (file)
@@ -107,7 +107,7 @@ static int
 mpc52xx_pci_read_config(struct pci_bus *bus, unsigned int devfn,
                                int offset, int len, u32 *val)
 {
-       struct pci_controller *hose = bus->sysdata;
+       struct pci_controller *hose = pci_bus_to_host(bus);
        u32 value;
 
        if (ppc_md.pci_exclude_device)
@@ -164,7 +164,7 @@ static int
 mpc52xx_pci_write_config(struct pci_bus *bus, unsigned int devfn,
                                int offset, int len, u32 val)
 {
-       struct pci_controller *hose = bus->sysdata;
+       struct pci_controller *hose = pci_bus_to_host(bus);
        u32 value, mask;
 
        if (ppc_md.pci_exclude_device)
index 0eb6d7f62241a38c43e47853e02183374ab752f2..51fcae41f08a1a6b710b4aab08c2586d3157f3b9 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/interrupt.h>
 #include <linux/fsl_devices.h>
 #include <linux/mdio-bitbang.h>
+#include <linux/of_mdio.h>
 #include <linux/of_platform.h>
 
 #include <asm/io.h>
@@ -115,7 +116,7 @@ static int __devinit ep8248e_mdio_probe(struct of_device *ofdev,
        struct mii_bus *bus;
        struct resource res;
        struct device_node *node;
-       int ret, i;
+       int ret;
 
        node = of_get_parent(ofdev->node);
        of_node_put(node);
@@ -130,17 +131,13 @@ static int __devinit ep8248e_mdio_probe(struct of_device *ofdev,
        if (!bus)
                return -ENOMEM;
 
-       bus->phy_mask = 0;
        bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
 
-       for (i = 0; i < PHY_MAX_ADDR; i++)
-               bus->irq[i] = -1;
-
        bus->name = "ep8248e-mdio-bitbang";
        bus->parent = &ofdev->dev;
        snprintf(bus->id, MII_BUS_ID_SIZE, "%x", res.start);
 
-       return mdiobus_register(bus);
+       return of_mdiobus_register(bus, ofdev->node);
 }
 
 static int ep8248e_mdio_remove(struct of_device *ofdev)
index 984db42cc8e76e6e964edb7558719bb94afa1630..6cf0f97486e25afc132eaf260a7bf30dac0a60da 100644 (file)
 
 #include <linux/seq_file.h>
 
-/* Backword-compatibility stuff for the drivers */
-#define CPM_MAP_ADDR           ((uint)0xf0000000)
-#define CPM_IRQ_OFFSET 0
-
 /* The ADS8260 has 16, 32-bit wide control/status registers, accessed
  * only on word boundaries.
  * Not all are used (yet), or are interesting to us (yet).
 #define BCSR3_FETHIEN2         ((uint)0x10000000)      /* 0 == enable*/
 #define BCSR3_FETH2_RST                ((uint)0x80000000)      /* 0 == reset */
 
-/* cpm serial driver works with constants below */
-
-#define SIU_INT_SMC1           ((uint)0x04+CPM_IRQ_OFFSET)
-#define SIU_INT_SMC2           ((uint)0x05+CPM_IRQ_OFFSET)
-#define SIU_INT_SCC1           ((uint)0x28+CPM_IRQ_OFFSET)
-#define SIU_INT_SCC2           ((uint)0x29+CPM_IRQ_OFFSET)
-#define SIU_INT_SCC3           ((uint)0x2a+CPM_IRQ_OFFSET)
-#define SIU_INT_SCC4           ((uint)0x2b+CPM_IRQ_OFFSET)
-
 #endif /* __MACH_ADS8260_DEFS */
 #endif /* __KERNEL__ */
index 7f066adc068cba54149af23479ce091bed8b61d4..43d385cedcd730e4595abcab85593488db868f4d 100644 (file)
@@ -34,6 +34,7 @@ config MPC85xx_MDS
        bool "Freescale MPC85xx MDS"
        select DEFAULT_UIMAGE
        select PHYLIB
+       select HAS_RAPIDIO
        help
          This option enables support for the MPC85xx MDS board
 
index de66de7a9ca2876a7bd27bd27e619cceac36c0ec..53d5851a6c977986789d6f7e73d88ab038504325 100644 (file)
@@ -163,7 +163,8 @@ static void __init mpc85xx_ds_setup_arch(void)
 #ifdef CONFIG_PCI
        for_each_node_by_type(np, "pci") {
                if (of_device_is_compatible(np, "fsl,mpc8540-pci") ||
-                   of_device_is_compatible(np, "fsl,mpc8548-pcie")) {
+                   of_device_is_compatible(np, "fsl,mpc8548-pcie") ||
+                   of_device_is_compatible(np, "fsl,p2020-pcie")) {
                        struct resource rsrc;
                        of_address_to_resource(np, 0, &rsrc);
                        if ((rsrc.start & 0xfffff) == primary_phb_addr)
@@ -195,9 +196,9 @@ static int __init mpc8544_ds_probe(void)
                primary_phb_addr = 0xb000;
 #endif
                return 1;
-       } else {
-               return 0;
        }
+
+       return 0;
 }
 
 static struct of_device_id __initdata mpc85xxds_ids[] = {
@@ -214,6 +215,7 @@ static int __init mpc85xxds_publish_devices(void)
 }
 machine_device_initcall(mpc8544_ds, mpc85xxds_publish_devices);
 machine_device_initcall(mpc8572_ds, mpc85xxds_publish_devices);
+machine_device_initcall(p2020_ds, mpc85xxds_publish_devices);
 
 /*
  * Called very early, device-tree isn't unflattened
@@ -227,9 +229,26 @@ static int __init mpc8572_ds_probe(void)
                primary_phb_addr = 0x8000;
 #endif
                return 1;
-       } else {
-               return 0;
        }
+
+       return 0;
+}
+
+/*
+ * Called very early, device-tree isn't unflattened
+ */
+static int __init p2020_ds_probe(void)
+{
+       unsigned long root = of_get_flat_dt_root();
+
+       if (of_flat_dt_is_compatible(root, "fsl,P2020DS")) {
+#ifdef CONFIG_PCI
+               primary_phb_addr = 0x9000;
+#endif
+               return 1;
+       }
+
+       return 0;
 }
 
 define_machine(mpc8544_ds) {
@@ -259,3 +278,17 @@ define_machine(mpc8572_ds) {
        .calibrate_decr         = generic_calibrate_decr,
        .progress               = udbg_progress,
 };
+
+define_machine(p2020_ds) {
+       .name                   = "P2020 DS",
+       .probe                  = p2020_ds_probe,
+       .setup_arch             = mpc85xx_ds_setup_arch,
+       .init_IRQ               = mpc85xx_ds_pic_init,
+#ifdef CONFIG_PCI
+       .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
+#endif
+       .get_irq                = mpic_get_irq,
+       .restart                = fsl_rstcr_restart,
+       .calibrate_decr         = generic_calibrate_decr,
+       .progress               = udbg_progress,
+};
index 7dd029034aec78e57338c54b10e42fae0550da42..b2c0a431997339e782c2ff1fe1847774d9361ff7 100644 (file)
@@ -206,23 +206,24 @@ static void __init mpc85xx_mds_setup_arch(void)
        }
 
        if (bcsr_regs) {
+               if (machine_is(mpc8568_mds)) {
 #define BCSR_UCC1_GETH_EN      (0x1 << 7)
 #define BCSR_UCC2_GETH_EN      (0x1 << 7)
 #define BCSR_UCC1_MODE_MSK     (0x3 << 4)
 #define BCSR_UCC2_MODE_MSK     (0x3 << 0)
 
-               /* Turn off UCC1 & UCC2 */
-               clrbits8(&bcsr_regs[8], BCSR_UCC1_GETH_EN);
-               clrbits8(&bcsr_regs[9], BCSR_UCC2_GETH_EN);
+                       /* Turn off UCC1 & UCC2 */
+                       clrbits8(&bcsr_regs[8], BCSR_UCC1_GETH_EN);
+                       clrbits8(&bcsr_regs[9], BCSR_UCC2_GETH_EN);
 
-               /* Mode is RGMII, all bits clear */
-               clrbits8(&bcsr_regs[11], BCSR_UCC1_MODE_MSK |
-                                        BCSR_UCC2_MODE_MSK);
-
-               /* Turn UCC1 & UCC2 on */
-               setbits8(&bcsr_regs[8], BCSR_UCC1_GETH_EN);
-               setbits8(&bcsr_regs[9], BCSR_UCC2_GETH_EN);
+                       /* Mode is RGMII, all bits clear */
+                       clrbits8(&bcsr_regs[11], BCSR_UCC1_MODE_MSK |
+                                                BCSR_UCC2_MODE_MSK);
 
+                       /* Turn UCC1 & UCC2 on */
+                       setbits8(&bcsr_regs[8], BCSR_UCC1_GETH_EN);
+                       setbits8(&bcsr_regs[9], BCSR_UCC2_GETH_EN);
+               }
                iounmap(bcsr_regs);
        }
 #endif /* CONFIG_QUICC_ENGINE */
@@ -257,7 +258,8 @@ static int __init board_fixups(void)
 
        return 0;
 }
-machine_arch_initcall(mpc85xx_mds, board_fixups);
+machine_arch_initcall(mpc8568_mds, board_fixups);
+machine_arch_initcall(mpc8569_mds, board_fixups);
 
 static struct of_device_id mpc85xx_ids[] = {
        { .type = "soc", },
@@ -276,7 +278,8 @@ static int __init mpc85xx_publish_devices(void)
 
        return 0;
 }
-machine_device_initcall(mpc85xx_mds, mpc85xx_publish_devices);
+machine_device_initcall(mpc8568_mds, mpc85xx_publish_devices);
+machine_device_initcall(mpc8569_mds, mpc85xx_publish_devices);
 
 static void __init mpc85xx_mds_pic_init(void)
 {
@@ -321,8 +324,8 @@ static int __init mpc85xx_mds_probe(void)
         return of_flat_dt_is_compatible(root, "MPC85xxMDS");
 }
 
-define_machine(mpc85xx_mds) {
-       .name           = "MPC85xx MDS",
+define_machine(mpc8568_mds) {
+       .name           = "MPC8568 MDS",
        .probe          = mpc85xx_mds_probe,
        .setup_arch     = mpc85xx_mds_setup_arch,
        .init_IRQ       = mpc85xx_mds_pic_init,
@@ -334,3 +337,24 @@ define_machine(mpc85xx_mds) {
        .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
 #endif
 };
+
+static int __init mpc8569_mds_probe(void)
+{
+       unsigned long root = of_get_flat_dt_root();
+
+       return of_flat_dt_is_compatible(root, "fsl,MPC8569EMDS");
+}
+
+define_machine(mpc8569_mds) {
+       .name           = "MPC8569 MDS",
+       .probe          = mpc8569_mds_probe,
+       .setup_arch     = mpc85xx_mds_setup_arch,
+       .init_IRQ       = mpc85xx_mds_pic_init,
+       .get_irq        = mpic_get_irq,
+       .restart        = fsl_rstcr_restart,
+       .calibrate_decr = generic_calibrate_decr,
+       .progress       = udbg_progress,
+#ifdef CONFIG_PCI
+       .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
+#endif
+};
index d79104669cdcea4aa4230b1871f649db2f558a4a..2efa052975e61716935c208b440890b19c860015 100644 (file)
@@ -28,7 +28,6 @@
 #include <asm/time.h>
 #include <asm/machdep.h>
 #include <asm/pci-bridge.h>
-#include <asm/mpc86xx.h>
 #include <asm/prom.h>
 #include <mm/mmu_decl.h>
 #include <asm/udbg.h>
index af14f852d747956c05762aef1ce072a5b5d5d2a4..90754e752bd827bafeb0680526cb6be41c55bee6 100644 (file)
@@ -28,7 +28,6 @@
 #include <asm/time.h>
 #include <asm/machdep.h>
 #include <asm/pci-bridge.h>
-#include <asm/mpc86xx.h>
 #include <asm/prom.h>
 #include <mm/mmu_decl.h>
 #include <asm/udbg.h>
index ea2360639652dbbfc7f46d07a2211e2acfd42902..72b31a6010a0dd9a302662d562e8106e97c2cd69 100644 (file)
@@ -28,7 +28,6 @@
 #include <asm/time.h>
 #include <asm/machdep.h>
 #include <asm/pci-bridge.h>
-#include <asm/mpc86xx.h>
 #include <asm/prom.h>
 #include <mm/mmu_decl.h>
 #include <asm/udbg.h>
index 3f49a6f893a30188de25da57470525f41ebdcb98..51eec0cd5519a1d1dbf775899267327be06d64dd 100644 (file)
@@ -28,7 +28,6 @@
 #include <asm/time.h>
 #include <asm/machdep.h>
 #include <asm/pci-bridge.h>
-#include <asm/mpc86xx.h>
 #include <asm/prom.h>
 #include <mm/mmu_decl.h>
 #include <asm/udbg.h>
index c4ec49b5f7f8e3c394b5997a2654bab460abba93..7e9e83c04a8ac631fad1677d0f55f8d60558a432 100644 (file)
@@ -24,7 +24,6 @@
 #include <asm/time.h>
 #include <asm/machdep.h>
 #include <asm/pci-bridge.h>
-#include <asm/mpc86xx.h>
 #include <asm/prom.h>
 #include <mm/mmu_decl.h>
 #include <asm/udbg.h>
index 014e26cda08d1b08d012b174ed1b1908132f1b96..d84bbb508ee7650719857bd6aaf1ee6c2f7ecee8 100644 (file)
@@ -20,7 +20,6 @@
 #include <asm/pgtable.h>
 #include <asm/pci-bridge.h>
 #include <asm/mpic.h>
-#include <asm/mpc86xx.h>
 #include <asm/cacheflush.h>
 
 #include <sysdev/fsl_soc.h>
 extern void __secondary_start_mpc86xx(void);
 extern unsigned long __secondary_hold_acknowledge;
 
+#define MCM_PORT_CONFIG_OFFSET 0x10
+
+/* Offset from CCSRBAR */
+#define MPC86xx_MCM_OFFSET      (0x1000)
+#define MPC86xx_MCM_SIZE        (0x1000)
 
 static void __init
 smp_86xx_release_core(int nr)
@@ -48,6 +52,8 @@ smp_86xx_release_core(int nr)
        pcr = in_be32(mcm_vaddr + (MCM_PORT_CONFIG_OFFSET >> 2));
        pcr |= 1 << (nr + 24);
        out_be32(mcm_vaddr + (MCM_PORT_CONFIG_OFFSET >> 2), pcr);
+
+       iounmap(mcm_vaddr);
 }
 
 
index 2886a36fc0856f6b378300551ea4ad5fef5ce561..51c8f331b6714b085a4822d620f2a3fb02f815f9 100644 (file)
@@ -25,7 +25,6 @@
 #include <asm/time.h>
 #include <asm/machdep.h>
 #include <asm/pci-bridge.h>
-#include <asm/mpc86xx.h>
 #include <asm/prom.h>
 #include <mm/mmu_decl.h>
 #include <asm/udbg.h>
index a5076668bad63b4872ffe7f0b405e56a1279d260..19412f76fa3b1dc3f98adcc80dfa3dd571437761 100644 (file)
 
 #include <sysdev/fsl_soc.h>
 
-#define MPC8xx_CPM_OFFSET      (0x9c0)
-#define CPM_MAP_ADDR           (get_immrbase() + MPC8xx_CPM_OFFSET)
-#define CPM_IRQ_OFFSET         16     // for compability with cpm_uart driver
-
 /* Bits of interest in the BCSRs.
  */
 #define BCSR1_ETHEN            ((uint)0x20000000)
index e3e87078d03f844327f51ec9841c291ab20b812a..04a8061045c4feb3991945be7d619f849ea8320c 100644 (file)
@@ -329,4 +329,8 @@ config MCU_MPC8349EMITX
          also register MCU GPIOs with the generic GPIO API, so you'll able
          to use MCU pins as GPIOs.
 
+config XILINX_PCI
+       bool "Xilinx PCI host bridge support"
+       depends on PCI && XILINX_VIRTEX
+
 endmenu
index 732ee93a8e988fd594eed27614d2034f2b71ed67..cca6b4fc719a2a3eb3b7d774c5c2c4d2329e8c8d 100644 (file)
@@ -10,7 +10,6 @@ menu "Processor support"
 choice
        prompt "Processor Type"
        depends on PPC32
-       default 6xx
        help
          There are five families of 32 bit PowerPC chips supported.
          The most common ones are the desktop and server CPUs (601, 603,
@@ -22,7 +21,7 @@ choice
 
          If unsure, select 52xx/6xx/7xx/74xx/82xx/83xx/86xx.
 
-config 6xx
+config PPC_BOOK3S
        bool "512x/52xx/6xx/7xx/74xx/82xx/83xx/86xx"
        select PPC_FPU
 
@@ -58,13 +57,11 @@ config E200
 
 endchoice
 
-# Until we have a choice of exclusive CPU types on 64-bit, we always
-# use PPC_BOOK3S. On 32-bit, this is equivalent to 6xx which is
-# "classic" MMU
-
 config PPC_BOOK3S
-       def_bool y
-       depends on PPC64 || 6xx
+       default y
+       depends on PPC64
+       select PPC_FPU
+
 
 config POWER4_ONLY
        bool "Optimize for POWER4"
@@ -75,6 +72,10 @@ config POWER4_ONLY
          The resulting binary will not work on POWER3 or RS64 processors
          when compiled with binutils 2.15 or later.
 
+config 6xx
+       def_bool y
+       depends on PPC32 && PPC_BOOK3S
+
 config POWER3
        bool
        depends on PPC64 && PPC_BOOK3S
@@ -203,9 +204,8 @@ config SPE
          If in doubt, say Y here.
 
 config PPC_STD_MMU
-       bool
-       depends on 6xx || PPC64
-       default y
+       def_bool y
+       depends on PPC_BOOK3S
 
 config PPC_STD_MMU_32
        def_bool y
@@ -263,8 +263,8 @@ config SMP
          If you don't know what to do here, say N.
 
 config NR_CPUS
-       int "Maximum number of CPUs (2-1024)"
-       range 2 1024
+       int "Maximum number of CPUs (2-8192)"
+       range 2 8192
        depends on SMP
        default "32" if PPC64
        default "4"
index f39a3b2a1667838c80bf762af0cac1512f4fcde2..00eaaa71630fde9252768167c20b1ce71cfd059d 100644 (file)
@@ -162,8 +162,7 @@ static int celleb_fake_pci_read_config(struct pci_bus *bus,
                unsigned int devfn, int where, int size, u32 *val)
 {
        char *config;
-       struct device_node *node;
-       struct pci_controller *hose;
+       struct pci_controller *hose = pci_bus_to_host(bus);
        unsigned int devno = devfn >> 3;
        unsigned int fn = devfn & 0x7;
 
@@ -171,8 +170,6 @@ static int celleb_fake_pci_read_config(struct pci_bus *bus,
        BUG_ON(where % size);
 
        pr_debug("    fake read: bus=0x%x, ", bus->number);
-       node = (struct device_node *)bus->sysdata;
-       hose = pci_find_hose_for_OF_device(node);
        config = get_fake_config_start(hose, devno, fn);
 
        pr_debug("devno=0x%x, where=0x%x, size=0x%x, ", devno, where, size);
@@ -192,8 +189,7 @@ static int celleb_fake_pci_write_config(struct pci_bus *bus,
                unsigned int devfn, int where, int size, u32 val)
 {
        char *config;
-       struct device_node *node;
-       struct pci_controller *hose;
+       struct pci_controller *hose = pci_bus_to_host(bus);
        struct celleb_pci_resource *res;
        unsigned int devno = devfn >> 3;
        unsigned int fn = devfn & 0x7;
@@ -201,8 +197,6 @@ static int celleb_fake_pci_write_config(struct pci_bus *bus,
        /* allignment check */
        BUG_ON(where % size);
 
-       node = (struct device_node *)bus->sysdata;
-       hose = pci_find_hose_for_OF_device(node);
        config = get_fake_config_start(hose, devno, fn);
 
        if (!config)
index 48ec88a38a120f225189a22fbc7c55100edf73a6..05b0db3ef6388bb4a5d6a7742be572f8b4c7f81c 100644 (file)
@@ -134,15 +134,11 @@ static int celleb_epci_read_config(struct pci_bus *bus,
 {
        PCI_IO_ADDR epci_base;
        PCI_IO_ADDR addr;
-       struct device_node *node;
-       struct pci_controller *hose;
+       struct pci_controller *hose = pci_bus_to_host(bus);
 
        /* allignment check */
        BUG_ON(where % size);
 
-       node = (struct device_node *)bus->sysdata;
-       hose = pci_find_hose_for_OF_device(node);
-
        if (!celleb_epci_get_epci_cfg(hose))
                return PCIBIOS_DEVICE_NOT_FOUND;
 
@@ -198,16 +194,11 @@ static int celleb_epci_write_config(struct pci_bus *bus,
 {
        PCI_IO_ADDR epci_base;
        PCI_IO_ADDR addr;
-       struct device_node *node;
-       struct pci_controller *hose;
+       struct pci_controller *hose = pci_bus_to_host(bus);
 
        /* allignment check */
        BUG_ON(where % size);
 
-       node = (struct device_node *)bus->sysdata;
-       hose = pci_find_hose_for_OF_device(node);
-
-
        if (!celleb_epci_get_epci_cfg(hose))
                return PCIBIOS_DEVICE_NOT_FOUND;
 
index 3e7e0f1568ef50d705de43fa889ce8722c2fd352..7fca09f990ba4fecc0bdc4e7fe5ad64a594d4043 100644 (file)
@@ -366,11 +366,7 @@ static void config_write_pciex_rc(unsigned int __iomem *base, uint32_t where,
 static int scc_pciex_read_config(struct pci_bus *bus, unsigned int devfn,
                                 int where, int size, unsigned int *val)
 {
-       struct device_node *dn;
-       struct pci_controller *phb;
-
-       dn = bus->sysdata;
-       phb = pci_find_hose_for_OF_device(dn);
+       struct pci_controller *phb = pci_bus_to_host(bus);
 
        if (bus->number == phb->first_busno && PCI_SLOT(devfn) != 1) {
                *val = ~0;
@@ -389,11 +385,7 @@ static int scc_pciex_read_config(struct pci_bus *bus, unsigned int devfn,
 static int scc_pciex_write_config(struct pci_bus *bus, unsigned int devfn,
                                  int where, int size, unsigned int val)
 {
-       struct device_node *dn;
-       struct pci_controller *phb;
-
-       dn = bus->sysdata;
-       phb = pci_find_hose_for_OF_device(dn);
+       struct pci_controller *phb = pci_bus_to_host(bus);
 
        if (bus->number == phb->first_busno && PCI_SLOT(devfn) != 1)
                return PCIBIOS_DEVICE_NOT_FOUND;
index 706eb5c7e2ee45c9cb71d5c09fc5517d12966df4..24b30b6909c4918280f0a914dd63a90a4cf01bde 100644 (file)
@@ -631,10 +631,6 @@ long spufs_create(struct nameidata *nd, unsigned int flags, mode_t mode,
        if (IS_ERR(dentry))
                goto out_dir;
 
-       ret = -EEXIST;
-       if (dentry->d_inode)
-               goto out_dput;
-
        mode &= ~current_umask();
 
        if (flags & SPU_CREATE_GANG)
@@ -648,8 +644,6 @@ long spufs_create(struct nameidata *nd, unsigned int flags, mode_t mode,
                fsnotify_mkdir(nd->path.dentry->d_inode, dentry);
        return ret;
 
-out_dput:
-       dput(dentry);
 out_dir:
        mutex_unlock(&nd->path.dentry->d_inode->i_mutex);
 out:
index f6b0c519d5a2b76e8d05f0df51600f9b9abba21e..8f67a394b2d068869cc045779e55e33bd7da4efd 100644 (file)
@@ -34,7 +34,7 @@ int gg2_read_config(struct pci_bus *bus, unsigned int devfn, int off,
                           int len, u32 *val)
 {
        volatile void __iomem *cfg_data;
-       struct pci_controller *hose = bus->sysdata;
+       struct pci_controller *hose = pci_bus_to_host(bus);
 
        if (bus->number > 7)
                return PCIBIOS_DEVICE_NOT_FOUND;
@@ -61,7 +61,7 @@ int gg2_write_config(struct pci_bus *bus, unsigned int devfn, int off,
                            int len, u32 val)
 {
        volatile void __iomem *cfg_data;
-       struct pci_controller *hose = bus->sysdata;
+       struct pci_controller *hose = pci_bus_to_host(bus);
 
        if (bus->number > 7)
                return PCIBIOS_DEVICE_NOT_FOUND;
@@ -96,7 +96,7 @@ static struct pci_ops gg2_pci_ops =
 int rtas_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
                     int len, u32 *val)
 {
-       struct pci_controller *hose = bus->sysdata;
+       struct pci_controller *hose = pci_bus_to_host(bus);
        unsigned long addr = (offset & 0xff) | ((devfn & 0xff) << 8)
                | (((bus->number - hose->first_busno) & 0xff) << 16)
                | (hose->global_number << 24);
@@ -111,7 +111,7 @@ int rtas_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
 int rtas_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
                      int len, u32 val)
 {
-       struct pci_controller *hose = bus->sysdata;
+       struct pci_controller *hose = pci_bus_to_host(bus);
        unsigned long addr = (offset & 0xff) | ((devfn & 0xff) << 8)
                | (((bus->number - hose->first_busno) & 0xff) << 16)
                | (hose->global_number << 24);
index 65a35f38e0622933d8c63e1de381e52fe936f3a7..fd23a1d4b39d28458bca7cc3322085e3975b0314 100644 (file)
@@ -51,13 +51,20 @@ u8 uli_pirq_to_irq[8] = {
        ULI_8259_NONE,          /* PIRQH */
 };
 
+static inline bool is_quirk_valid(void)
+{
+       return (machine_is(mpc86xx_hpcn) ||
+               machine_is(mpc8544_ds) ||
+               machine_is(p2020_ds) ||
+               machine_is(mpc8572_ds));
+}
+
 /* Bridge */
 static void __devinit early_uli5249(struct pci_dev *dev)
 {
        unsigned char temp;
 
-       if (!machine_is(mpc86xx_hpcn) && !machine_is(mpc8544_ds) &&
-                       !machine_is(mpc8572_ds))
+       if (!is_quirk_valid())
                return;
 
        pci_write_config_word(dev, PCI_COMMAND, PCI_COMMAND_IO |
@@ -80,8 +87,7 @@ static void __devinit quirk_uli1575(struct pci_dev *dev)
 {
        int i;
 
-       if (!machine_is(mpc86xx_hpcn) && !machine_is(mpc8544_ds) &&
-                       !machine_is(mpc8572_ds))
+       if (!is_quirk_valid())
                return;
 
        /*
@@ -149,8 +155,7 @@ static void __devinit quirk_final_uli1575(struct pci_dev *dev)
         * IRQ 14: Edge
         * IRQ 15: Edge
         */
-       if (!machine_is(mpc86xx_hpcn) && !machine_is(mpc8544_ds) &&
-                       !machine_is(mpc8572_ds))
+       if (!is_quirk_valid())
                return;
 
        outb(0xfa, 0x4d0);
@@ -176,8 +181,7 @@ static void __devinit quirk_uli5288(struct pci_dev *dev)
        unsigned char c;
        unsigned int d;
 
-       if (!machine_is(mpc86xx_hpcn) && !machine_is(mpc8544_ds) &&
-                       !machine_is(mpc8572_ds))
+       if (!is_quirk_valid())
                return;
 
        /* read/write lock */
@@ -201,8 +205,7 @@ static void __devinit quirk_uli5229(struct pci_dev *dev)
 {
        unsigned short temp;
 
-       if (!machine_is(mpc86xx_hpcn) && !machine_is(mpc8544_ds) &&
-                       !machine_is(mpc8572_ds))
+       if (!is_quirk_valid())
                return;
 
        pci_write_config_word(dev, PCI_COMMAND, PCI_COMMAND_INTX_DISABLE |
@@ -270,7 +273,6 @@ static void __devinit hpcd_quirk_uli1575(struct pci_dev *dev)
 static void __devinit hpcd_quirk_uli5288(struct pci_dev *dev)
 {
        unsigned char c;
-       unsigned short temp;
 
        if (!machine_is(mpc86xx_hpcd))
                return;
index 40219823d9b020c4430f436ab925d973891cf8ef..6c1e1011959ec36bdbca81b81bd77b3aa64b979a 100644 (file)
@@ -177,7 +177,7 @@ static struct iommu_table *iommu_table_find(struct iommu_table * tbl)
 static void pci_dma_dev_setup_iseries(struct pci_dev *pdev)
 {
        struct iommu_table *tbl;
-       struct device_node *dn = pdev->sysdata;
+       struct device_node *dn = pci_device_to_OF_node(pdev);
        struct pci_dn *pdn = PCI_DN(dn);
        const u32 *lsn = of_get_property(dn, "linux,logical-slot-number", NULL);
 
index 21cddc30220b6df8a8e6ddf8524df7ae8a0160dd..175aac8ca7e501216578401c8168429acced9af0 100644 (file)
@@ -318,6 +318,7 @@ static void __init iomm_table_allocate_entry(struct pci_dev *dev, int bar_num)
 {
        struct resource *bar_res = &dev->resource[bar_num];
        long bar_size = pci_resource_len(dev, bar_num);
+       struct device_node *dn = pci_device_to_OF_node(dev);
 
        /*
         * No space to allocate, quick exit, skip Allocation.
@@ -335,9 +336,9 @@ static void __init iomm_table_allocate_entry(struct pci_dev *dev, int bar_num)
         * Allocate the number of table entries needed for BAR.
         */
        while (bar_size > 0 ) {
-               iomm_table[current_iomm_table_entry] = dev->sysdata;
+               iomm_table[current_iomm_table_entry] = dn;
                ds_addr_table[current_iomm_table_entry] =
-                       iseries_ds_addr(dev->sysdata) | (bar_num << 24);
+                       iseries_ds_addr(dn) | (bar_num << 24);
                bar_size -= IOMM_TABLE_ENTRY_SIZE;
                ++current_iomm_table_entry;
        }
@@ -410,7 +411,7 @@ void __init iSeries_pcibios_fixup_resources(struct pci_dev *pdev)
        struct device_node *node;
        int i;
 
-       node = find_device_node(bus, pdev->devfn);
+       node = pci_device_to_OF_node(pdev);
        pr_debug("PCI: iSeries %s, pdev %p, node %p\n",
                 pci_name(pdev), pdev, node);
        if (!node) {
@@ -441,7 +442,6 @@ void __init iSeries_pcibios_fixup_resources(struct pci_dev *pdev)
                }
        }
 
-       pdev->sysdata = node;
        allocate_device_bars(pdev);
        iseries_device_information(pdev, bus, *sub_bus);
 }
index 75cc165d5bee6e73f0a07dc38edd60dcf442941d..3bf546797cbba702b3b0c41d05682f399aa41039 100644 (file)
@@ -29,7 +29,7 @@
 #include <linux/ioport.h>
 #include <linux/interrupt.h>
 #include <linux/phy.h>
-#include <linux/platform_device.h>
+#include <linux/of_mdio.h>
 #include <linux/of_platform.h>
 
 #define DELAY 1
@@ -39,6 +39,7 @@ static void __iomem *gpio_regs;
 struct gpio_priv {
        int mdc_pin;
        int mdio_pin;
+       int mdio_irqs[PHY_MAX_ADDR];
 };
 
 #define MDC_PIN(bus)   (((struct gpio_priv *)bus->priv)->mdc_pin)
@@ -218,12 +219,11 @@ static int __devinit gpio_mdio_probe(struct of_device *ofdev,
                                     const struct of_device_id *match)
 {
        struct device *dev = &ofdev->dev;
-       struct device_node *phy_dn, *np = ofdev->node;
+       struct device_node *np = ofdev->node;
        struct mii_bus *new_bus;
        struct gpio_priv *priv;
        const unsigned int *prop;
        int err;
-       int i;
 
        err = -ENOMEM;
        priv = kzalloc(sizeof(struct gpio_priv), GFP_KERNEL);
@@ -244,27 +244,7 @@ static int __devinit gpio_mdio_probe(struct of_device *ofdev,
        snprintf(new_bus->id, MII_BUS_ID_SIZE, "%x", *prop);
        new_bus->priv = priv;
 
-       new_bus->phy_mask = 0;
-
-       new_bus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL);
-
-       if (!new_bus->irq)
-               goto out_free_bus;
-
-       for (i = 0; i < PHY_MAX_ADDR; i++)
-               new_bus->irq[i] = NO_IRQ;
-
-       for (phy_dn = of_get_next_child(np, NULL);
-            phy_dn != NULL;
-            phy_dn = of_get_next_child(np, phy_dn)) {
-               const unsigned int *ip, *regp;
-
-               ip = of_get_property(phy_dn, "interrupts", NULL);
-               regp = of_get_property(phy_dn, "reg", NULL);
-               if (!ip || !regp || *regp >= PHY_MAX_ADDR)
-                       continue;
-               new_bus->irq[*regp] = irq_create_mapping(NULL, *ip);
-       }
+       new_bus->irq = priv->mdio_irqs;
 
        prop = of_get_property(np, "mdc-pin", NULL);
        priv->mdc_pin = *prop;
@@ -275,7 +255,7 @@ static int __devinit gpio_mdio_probe(struct of_device *ofdev,
        new_bus->parent = dev;
        dev_set_drvdata(dev, new_bus);
 
-       err = mdiobus_register(new_bus);
+       err = of_mdiobus_register(new_bus, np);
 
        if (err != 0) {
                printk(KERN_ERR "%s: Cannot register as MDIO bus, err %d\n",
@@ -286,8 +266,6 @@ static int __devinit gpio_mdio_probe(struct of_device *ofdev,
        return 0;
 
 out_free_irq:
-       kfree(new_bus->irq);
-out_free_bus:
        kfree(new_bus);
 out_free_priv:
        kfree(priv);
index 7039d8f1d3baa1dfdd73e2f9ac80a15fb1c9fb11..dce736349107b3b7aa427956a610250c43709458 100644 (file)
@@ -221,7 +221,7 @@ static irqreturn_t gatwick_action(int cpl, void *dev_id)
                        continue;
                irq += __ilog2(bits);
                spin_unlock_irqrestore(&pmac_pic_lock, flags);
-               __do_IRQ(irq);
+               generic_handle_irq(irq);
                spin_lock_irqsave(&pmac_pic_lock, flags);
                rc = IRQ_HANDLED;
        }
index 45936c9ed0ec5a1db19ee11d84facdcd85412740..86f69a4eb49bfc669012b2681500fd5f0c29e981 100644 (file)
@@ -655,7 +655,7 @@ static int __init pmac_probe(void)
 /* Move that to pci.c */
 static int pmac_pci_probe_mode(struct pci_bus *bus)
 {
-       struct device_node *node = bus->sysdata;
+       struct device_node *node = pci_bus_to_OF_node(bus);
 
        /* We need to use normal PCI probing for the AGP bus,
         * since the device for the AGP bridge isn't in the tree.
index a0927a3bacb79eee1a571d526e0c56236c27017d..f6e04bcc70ef8a1ede3735a6ebd9804302537ef6 100644 (file)
 #define DBG pr_debug
 #endif
 
-static irqreturn_t ipi_function_handler(int irq, void *msg)
-{
-       smp_message_recv((int)(long)msg);
-       return IRQ_HANDLED;
-}
-
 /**
   * ps3_ipi_virqs - a per cpu array of virqs for ipi use
   */
@@ -45,13 +39,6 @@ static irqreturn_t ipi_function_handler(int irq, void *msg)
 #define MSG_COUNT 4
 static DEFINE_PER_CPU(unsigned int, ps3_ipi_virqs[MSG_COUNT]);
 
-static const char *names[MSG_COUNT] = {
-       "ipi call",
-       "ipi reschedule",
-       "ipi migrate",
-       "ipi debug brk"
-};
-
 static void do_message_pass(int target, int msg)
 {
        int result;
@@ -119,8 +106,7 @@ static void __init ps3_smp_setup_cpu(int cpu)
                DBG("%s:%d: (%d, %d) => virq %u\n",
                        __func__, __LINE__, cpu, i, virqs[i]);
 
-               result = request_irq(virqs[i], ipi_function_handler,
-                       IRQF_DISABLED, names[i], (void*)(long)i);
+               result = smp_request_message_ipi(virqs[i], i);
 
                if (result)
                        virqs[i] = NO_IRQ;
index 3ee01b4f42577261f342b831ea64e022f84f7a9f..661c8e02bcba7b5e2dd48b9fc63c5c237a59f4b1 100644 (file)
@@ -388,7 +388,7 @@ static void pci_dma_bus_setup_pSeries(struct pci_bus *bus)
 
                while (pci->phb->dma_window_size * children > 0x80000000ul)
                        pci->phb->dma_window_size >>= 1;
-               pr_debug("No ISA/IDE, window size is 0x%lx\n",
+               pr_debug("No ISA/IDE, window size is 0x%llx\n",
                         pci->phb->dma_window_size);
                pci->phb->dma_window_base_cur = 0;
 
@@ -414,7 +414,7 @@ static void pci_dma_bus_setup_pSeries(struct pci_bus *bus)
        while (pci->phb->dma_window_size * children > 0x70000000ul)
                pci->phb->dma_window_size >>= 1;
 
-       pr_debug("ISA/IDE, window size is 0x%lx\n", pci->phb->dma_window_size);
+       pr_debug("ISA/IDE, window size is 0x%llx\n", pci->phb->dma_window_size);
 }
 
 
index 52a80e5840e87ee51c6ff33eea5fbdc83d9c7205..e3139fa5e556e78ddcdeacc4e4850b7aeeba6ed4 100644 (file)
@@ -609,3 +609,55 @@ void __init hpte_init_lpar(void)
        ppc_md.flush_hash_range = pSeries_lpar_flush_hash_range;
        ppc_md.hpte_clear_all   = pSeries_lpar_hptab_clear;
 }
+
+#ifdef CONFIG_PPC_SMLPAR
+#define CMO_FREE_HINT_DEFAULT 1
+static int cmo_free_hint_flag = CMO_FREE_HINT_DEFAULT;
+
+static int __init cmo_free_hint(char *str)
+{
+       char *parm;
+       parm = strstrip(str);
+
+       if (strcasecmp(parm, "no") == 0 || strcasecmp(parm, "off") == 0) {
+               printk(KERN_INFO "cmo_free_hint: CMO free page hinting is not active.\n");
+               cmo_free_hint_flag = 0;
+               return 1;
+       }
+
+       cmo_free_hint_flag = 1;
+       printk(KERN_INFO "cmo_free_hint: CMO free page hinting is active.\n");
+
+       if (strcasecmp(parm, "yes") == 0 || strcasecmp(parm, "on") == 0)
+               return 1;
+
+       return 0;
+}
+
+__setup("cmo_free_hint=", cmo_free_hint);
+
+static void pSeries_set_page_state(struct page *page, int order,
+                                  unsigned long state)
+{
+       int i, j;
+       unsigned long cmo_page_sz, addr;
+
+       cmo_page_sz = cmo_get_page_size();
+       addr = __pa((unsigned long)page_address(page));
+
+       for (i = 0; i < (1 << order); i++, addr += PAGE_SIZE) {
+               for (j = 0; j < PAGE_SIZE; j += cmo_page_sz)
+                       plpar_hcall_norets(H_PAGE_INIT, state, addr + j, 0);
+       }
+}
+
+void arch_free_page(struct page *page, int order)
+{
+       if (!cmo_free_hint_flag || !firmware_has_feature(FW_FEATURE_CMO))
+               return;
+
+       pSeries_set_page_state(page, order, H_PAGE_SET_UNUSED);
+}
+EXPORT_SYMBOL(arch_free_page);
+
+#endif
index afad9f5ac0ac2190d1cb4e6685ca479b42b542a0..b3cbac85592406011015a6c68a7dbd99663f151e 100644 (file)
@@ -19,7 +19,7 @@
 #include <linux/vmalloc.h>
 #include <linux/spinlock.h>
 #include <linux/cpu.h>
-#include <linux/delay.h>
+#include <linux/workqueue.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
@@ -387,36 +387,51 @@ static void do_event_scan(void)
        } while(error == 0);
 }
 
-static void do_event_scan_all_cpus(long delay)
+static void rtas_event_scan(struct work_struct *w);
+DECLARE_DELAYED_WORK(event_scan_work, rtas_event_scan);
+
+/*
+ * Delay should be at least one second since some machines have problems if
+ * we call event-scan too quickly.
+ */
+static unsigned long event_scan_delay = 1*HZ;
+static int first_pass = 1;
+
+static void rtas_event_scan(struct work_struct *w)
 {
-       int cpu;
+       unsigned int cpu;
+
+       do_event_scan();
 
        get_online_cpus();
-       cpu = first_cpu(cpu_online_map);
-       for (;;) {
-               set_cpus_allowed(current, cpumask_of_cpu(cpu));
-               do_event_scan();
-               set_cpus_allowed(current, CPU_MASK_ALL);
-
-               /* Drop hotplug lock, and sleep for the specified delay */
-               put_online_cpus();
-               msleep_interruptible(delay);
-               get_online_cpus();
-
-               cpu = next_cpu(cpu, cpu_online_map);
-               if (cpu == NR_CPUS)
-                       break;
+
+       cpu = next_cpu(smp_processor_id(), cpu_online_map);
+       if (cpu == NR_CPUS) {
+               cpu = first_cpu(cpu_online_map);
+
+               if (first_pass) {
+                       first_pass = 0;
+                       event_scan_delay = 30*HZ/rtas_event_scan_rate;
+
+                       if (surveillance_timeout != -1) {
+                               pr_debug("rtasd: enabling surveillance\n");
+                               enable_surveillance(surveillance_timeout);
+                               pr_debug("rtasd: surveillance enabled\n");
+                       }
+               }
        }
+
+       schedule_delayed_work_on(cpu, &event_scan_work,
+               __round_jiffies_relative(event_scan_delay, cpu));
+
        put_online_cpus();
 }
 
-static int rtasd(void *unused)
+static void start_event_scan(void)
 {
        unsigned int err_type;
        int rc;
 
-       daemonize("rtasd");
-
        printk(KERN_DEBUG "RTAS daemon started\n");
        pr_debug("rtasd: will sleep for %d milliseconds\n",
                 (30000 / rtas_event_scan_rate));
@@ -434,22 +449,8 @@ static int rtasd(void *unused)
                }
        }
 
-       /* First pass. */
-       do_event_scan_all_cpus(1000);
-
-       if (surveillance_timeout != -1) {
-               pr_debug("rtasd: enabling surveillance\n");
-               enable_surveillance(surveillance_timeout);
-               pr_debug("rtasd: surveillance enabled\n");
-       }
-
-       /* Delay should be at least one second since some
-        * machines have problems if we call event-scan too
-        * quickly. */
-       for (;;)
-               do_event_scan_all_cpus(30000/rtas_event_scan_rate);
-
-       return -EINVAL;
+       schedule_delayed_work_on(first_cpu(cpu_online_map), &event_scan_work,
+                                event_scan_delay);
 }
 
 static int __init rtas_init(void)
@@ -487,8 +488,7 @@ static int __init rtas_init(void)
        if (!entry)
                printk(KERN_ERR "Failed to create error_log proc entry\n");
 
-       if (kernel_thread(rtasd, NULL, CLONE_FS) < 0)
-               printk(KERN_ERR "Failed to start RTAS daemon\n");
+       start_event_scan();
 
        return 0;
 }
index ec341707e41b2fc7891173afc60298f8017107b4..8d75ea21296f7dafdf2465f59cf6c3ae0d846aa0 100644 (file)
@@ -63,6 +63,7 @@
 #include <asm/smp.h>
 #include <asm/firmware.h>
 #include <asm/eeh.h>
+#include <asm/pSeries_reconfig.h>
 
 #include "plpar_wrappers.h"
 #include "pseries.h"
@@ -254,6 +255,29 @@ static void __init pseries_discover_pic(void)
               " interrupt-controller\n");
 }
 
+static int pci_dn_reconfig_notifier(struct notifier_block *nb, unsigned long action, void *node)
+{
+       struct device_node *np = node;
+       struct pci_dn *pci = NULL;
+       int err = NOTIFY_OK;
+
+       switch (action) {
+       case PSERIES_RECONFIG_ADD:
+               pci = np->parent->data;
+               if (pci)
+                       update_dn_pci_info(np, pci->phb);
+               break;
+       default:
+               err = NOTIFY_DONE;
+               break;
+       }
+       return err;
+}
+
+static struct notifier_block pci_dn_reconfig_nb = {
+       .notifier_call = pci_dn_reconfig_notifier,
+};
+
 static void __init pSeries_setup_arch(void)
 {
        /* Discover PIC type and setup ppc_md accordingly */
@@ -271,6 +295,7 @@ static void __init pSeries_setup_arch(void)
        /* Find and initialize PCI host bridges */
        init_pci_config_tokens();
        find_and_init_phbs();
+       pSeries_reconfig_notifier_register(&pci_dn_reconfig_nb);
        eeh_init();
 
        pSeries_nvram_init();
index b33b28a6fe1235d97c837cb9615cb7e4bf0464bf..2d1c87dd5d1470e79400cb1f337c27f6c590ebdb 100644 (file)
@@ -34,6 +34,7 @@ obj-$(CONFIG_IPIC)            += ipic.o
 obj-$(CONFIG_4xx)              += uic.o
 obj-$(CONFIG_4xx_SOC)          += ppc4xx_soc.o
 obj-$(CONFIG_XILINX_VIRTEX)    += xilinx_intc.o
+obj-$(CONFIG_XILINX_PCI)       += xilinx_pci.o
 obj-$(CONFIG_OF_RTC)           += of_rtc.o
 ifeq ($(CONFIG_PCI),y)
 obj-$(CONFIG_4xx)              += ppc4xx_pci.o
index fd969f0e31214615bec76854e79b7d67c86a3cd3..eb5927212fab39134177bbbcd478fcfac85fabc8 100644 (file)
@@ -61,7 +61,7 @@ EXPORT_SYMBOL(cpm2_immr);
 void __init cpm2_reset(void)
 {
 #ifdef CONFIG_PPC_85xx
-       cpm2_immr = ioremap(CPM_MAP_ADDR, CPM_MAP_SIZE);
+       cpm2_immr = ioremap(get_immrbase() + 0x80000, CPM_MAP_SIZE);
 #else
        cpm2_immr = ioremap(get_immrbase(), CPM_MAP_SIZE);
 #endif
index f25ce818d40a16061e40209309c78c6fce4ad9c0..da38a1ff97bb47b0b58955191313dbec4b233ea5 100644 (file)
@@ -113,8 +113,13 @@ static void fsl_compose_msi_msg(struct pci_dev *pdev, int hwirq,
                                  struct msi_msg *msg)
 {
        struct fsl_msi *msi_data = fsl_msi;
+       struct pci_controller *hose = pci_bus_to_host(pdev->bus);
+       u32 base = 0;
 
-       msg->address_lo = msi_data->msi_addr_lo;
+       pci_bus_read_config_dword(hose->bus,
+               PCI_DEVFN(0, 0), PCI_BASE_ADDRESS_0, &base);
+
+       msg->address_lo = msi_data->msi_addr_lo + base;
        msg->address_hi = msi_data->msi_addr_hi;
        msg->data = hwirq;
 
@@ -271,7 +276,7 @@ static int __devinit fsl_of_msi_probe(struct of_device *dev,
        msi->irqhost->host_data = msi;
 
        msi->msi_addr_hi = 0x0;
-       msi->msi_addr_lo = res.start + features->msiir_offset;
+       msi->msi_addr_lo = features->msiir_offset + (res.start & 0xfffff);
 
        rc = fsl_msi_init_allocator(msi);
        if (rc) {
index 78021d8afc53dc7b5c7d50112eb70ca50d2dd320..ae88b1448018391d29b6aea018161cd80d708995 100644 (file)
@@ -23,6 +23,8 @@
 #include <linux/string.h>
 #include <linux/init.h>
 #include <linux/bootmem.h>
+#include <linux/lmb.h>
+#include <linux/log2.h>
 
 #include <asm/io.h>
 #include <asm/prom.h>
@@ -96,7 +98,13 @@ static void __init setup_pci_atmu(struct pci_controller *hose,
                                  struct resource *rsrc)
 {
        struct ccsr_pci __iomem *pci;
-       int i, j, n;
+       int i, j, n, mem_log, win_idx = 2;
+       u64 mem, sz, paddr_hi = 0;
+       u64 paddr_lo = ULLONG_MAX;
+       u32 pcicsrbar = 0, pcicsrbar_sz;
+       u32 piwar = PIWAR_EN | PIWAR_PF | PIWAR_TGI_LOCAL |
+                       PIWAR_READ_SNOOP | PIWAR_WRITE_SNOOP;
+       char *name = hose->dn->full_name;
 
        pr_debug("PCI memory map start 0x%016llx, size 0x%016llx\n",
                    (u64)rsrc->start, (u64)rsrc->end - (u64)rsrc->start + 1);
@@ -117,6 +125,9 @@ static void __init setup_pci_atmu(struct pci_controller *hose,
                if (!(hose->mem_resources[i].flags & IORESOURCE_MEM))
                        continue;
 
+               paddr_lo = min(paddr_lo, (u64)hose->mem_resources[i].start);
+               paddr_hi = max(paddr_hi, (u64)hose->mem_resources[i].end);
+
                n = setup_one_atmu(pci, j, &hose->mem_resources[i],
                                   hose->pci_mem_offset);
 
@@ -147,10 +158,105 @@ static void __init setup_pci_atmu(struct pci_controller *hose,
                }
        }
 
-       /* Setup 2G inbound Memory Window @ 1 */
-       out_be32(&pci->piw[2].pitar, 0x00000000);
-       out_be32(&pci->piw[2].piwbar,0x00000000);
-       out_be32(&pci->piw[2].piwar, PIWAR_2G);
+       /* convert to pci address space */
+       paddr_hi -= hose->pci_mem_offset;
+       paddr_lo -= hose->pci_mem_offset;
+
+       if (paddr_hi == paddr_lo) {
+               pr_err("%s: No outbound window space\n", name);
+               return ;
+       }
+
+       if (paddr_lo == 0) {
+               pr_err("%s: No space for inbound window\n", name);
+               return ;
+       }
+
+       /* setup PCSRBAR/PEXCSRBAR */
+       early_write_config_dword(hose, 0, 0, PCI_BASE_ADDRESS_0, 0xffffffff);
+       early_read_config_dword(hose, 0, 0, PCI_BASE_ADDRESS_0, &pcicsrbar_sz);
+       pcicsrbar_sz = ~pcicsrbar_sz + 1;
+
+       if (paddr_hi < (0x100000000ull - pcicsrbar_sz) ||
+               (paddr_lo > 0x100000000ull))
+               pcicsrbar = 0x100000000ull - pcicsrbar_sz;
+       else
+               pcicsrbar = (paddr_lo - pcicsrbar_sz) & -pcicsrbar_sz;
+       early_write_config_dword(hose, 0, 0, PCI_BASE_ADDRESS_0, pcicsrbar);
+
+       paddr_lo = min(paddr_lo, (u64)pcicsrbar);
+
+       pr_info("%s: PCICSRBAR @ 0x%x\n", name, pcicsrbar);
+
+       /* Setup inbound mem window */
+       mem = lmb_end_of_DRAM();
+       sz = min(mem, paddr_lo);
+       mem_log = __ilog2_u64(sz);
+
+       /* PCIe can overmap inbound & outbound since RX & TX are separated */
+       if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) {
+               /* Size window to exact size if power-of-two or one size up */
+               if ((1ull << mem_log) != mem) {
+                       if ((1ull << mem_log) > mem)
+                               pr_info("%s: Setting PCI inbound window "
+                                       "greater than memory size\n", name);
+                       mem_log++;
+               }
+
+               piwar |= (mem_log - 1);
+
+               /* Setup inbound memory window */
+               out_be32(&pci->piw[win_idx].pitar,  0x00000000);
+               out_be32(&pci->piw[win_idx].piwbar, 0x00000000);
+               out_be32(&pci->piw[win_idx].piwar,  piwar);
+               win_idx--;
+
+               hose->dma_window_base_cur = 0x00000000;
+               hose->dma_window_size = (resource_size_t)sz;
+       } else {
+               u64 paddr = 0;
+
+               /* Setup inbound memory window */
+               out_be32(&pci->piw[win_idx].pitar,  paddr >> 12);
+               out_be32(&pci->piw[win_idx].piwbar, paddr >> 12);
+               out_be32(&pci->piw[win_idx].piwar,  (piwar | (mem_log - 1)));
+               win_idx--;
+
+               paddr += 1ull << mem_log;
+               sz -= 1ull << mem_log;
+
+               if (sz) {
+                       mem_log = __ilog2_u64(sz);
+                       piwar |= (mem_log - 1);
+
+                       out_be32(&pci->piw[win_idx].pitar,  paddr >> 12);
+                       out_be32(&pci->piw[win_idx].piwbar, paddr >> 12);
+                       out_be32(&pci->piw[win_idx].piwar,  piwar);
+                       win_idx--;
+
+                       paddr += 1ull << mem_log;
+               }
+
+               hose->dma_window_base_cur = 0x00000000;
+               hose->dma_window_size = (resource_size_t)paddr;
+       }
+
+       if (hose->dma_window_size < mem) {
+#ifndef CONFIG_SWIOTLB
+               pr_err("%s: ERROR: Memory size exceeds PCI ATMU ability to "
+                       "map - enable CONFIG_SWIOTLB to avoid dma errors.\n",
+                        name);
+#endif
+               /* adjusting outbound windows could reclaim space in mem map */
+               if (paddr_hi < 0xffffffffull)
+                       pr_warning("%s: WARNING: Outbound window cfg leaves "
+                               "gaps in memory map. Adjusting the memory map "
+                               "could reduce unnecessary bounce buffering.\n",
+                               name);
+
+               pr_info("%s: DMA window size is 0x%llx\n", name,
+                       (u64)hose->dma_window_size);
+       }
 
        iounmap(pci);
 }
@@ -176,19 +282,9 @@ static void __init setup_pci_cmd(struct pci_controller *hose)
        }
 }
 
-static void __init setup_pci_pcsrbar(struct pci_controller *hose)
-{
-#ifdef CONFIG_PCI_MSI
-       phys_addr_t immr_base;
-
-       immr_base = get_immrbase();
-       early_write_config_dword(hose, 0, 0, PCI_BASE_ADDRESS_0, immr_base);
-#endif
-}
-
 void fsl_pcibios_fixup_bus(struct pci_bus *bus)
 {
-       struct pci_controller *hose = (struct pci_controller *) bus->sysdata;
+       struct pci_controller *hose = pci_bus_to_host(bus);
        int i;
 
        if ((bus->parent == hose->bus) &&
@@ -269,8 +365,6 @@ int __init fsl_add_bridge(struct device_node *dev, int is_primary)
        /* Setup PEX window registers */
        setup_pci_atmu(hose, &rsrc);
 
-       /* Setup PEXCSRBAR */
-       setup_pci_pcsrbar(hose);
        return 0;
 }
 
@@ -281,6 +375,8 @@ DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8543, quirk_fsl_pcie_header);
 DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8547E, quirk_fsl_pcie_header);
 DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8545E, quirk_fsl_pcie_header);
 DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8545, quirk_fsl_pcie_header);
+DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8569E, quirk_fsl_pcie_header);
+DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8569, quirk_fsl_pcie_header);
 DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8568E, quirk_fsl_pcie_header);
 DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8568, quirk_fsl_pcie_header);
 DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8567E, quirk_fsl_pcie_header);
@@ -296,6 +392,8 @@ DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8536, quirk_fsl_pcie_header);
 DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8641, quirk_fsl_pcie_header);
 DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8641D, quirk_fsl_pcie_header);
 DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_MPC8610, quirk_fsl_pcie_header);
+DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P2020E, quirk_fsl_pcie_header);
+DECLARE_PCI_FIXUP_HEADER(0x1957, PCI_DEVICE_ID_P2020, quirk_fsl_pcie_header);
 #endif /* CONFIG_PPC_85xx || CONFIG_PPC_86xx */
 
 #if defined(CONFIG_PPC_83xx) || defined(CONFIG_PPC_MPC512x)
@@ -324,7 +422,7 @@ struct mpc83xx_pcie_priv {
 
 static int mpc83xx_pcie_exclude_device(struct pci_bus *bus, unsigned int devfn)
 {
-       struct pci_controller *hose = bus->sysdata;
+       struct pci_controller *hose = pci_bus_to_host(bus);
 
        if (hose->indirect_type & PPC_INDIRECT_TYPE_NO_PCIE_LINK)
                return PCIBIOS_DEVICE_NOT_FOUND;
@@ -350,7 +448,7 @@ static int mpc83xx_pcie_exclude_device(struct pci_bus *bus, unsigned int devfn)
 static void __iomem *mpc83xx_pcie_remap_cfg(struct pci_bus *bus,
                                            unsigned int devfn, int offset)
 {
-       struct pci_controller *hose = bus->sysdata;
+       struct pci_controller *hose = pci_bus_to_host(bus);
        struct mpc83xx_pcie_priv *pcie = hose->dn->data;
        u8 bus_no = bus->number - hose->first_busno;
        u32 dev_base = bus_no << 24 | devfn << 16;
index 13f30c2a61e76a906684cff73f60709e5b5ccff4..a9d8bbebed80b231511bf862d594c769798a16d3 100644 (file)
 
 #define PCIE_LTSSM     0x0404          /* PCIE Link Training and Status */
 #define PCIE_LTSSM_L0  0x16            /* L0 state */
-#define PIWAR_2G       0xa0f5501e      /* Enable, Prefetch, Local Mem, Snoop R/W, 2G */
+#define PIWAR_EN               0x80000000      /* Enable */
+#define PIWAR_PF               0x20000000      /* prefetch */
+#define PIWAR_TGI_LOCAL                0x00f00000      /* target - local memory */
+#define PIWAR_READ_SNOOP       0x00050000
+#define PIWAR_WRITE_SNOOP      0x00005000
 
 /* PCI/PCI Express outbound window reg */
 struct pci_outbound_window_regs {
index abdb124e1e2f092178985da45115537fec6f6c4f..39db9d1155d27466ffe176887c7d9b2c320f288f 100644 (file)
@@ -1026,8 +1026,7 @@ int fsl_rio_setup(struct of_device *dev)
                return -EFAULT;
        }
        dev_info(&dev->dev, "Of-device full name %s\n", dev->node->full_name);
-       dev_info(&dev->dev, "Regs start 0x%08x size 0x%08x\n",  regs.start,
-                                               regs.end - regs.start + 1);
+       dev_info(&dev->dev, "Regs: %pR\n", &regs);
 
        dt_range = of_get_property(dev->node, "ranges", &rlen);
        if (!dt_range) {
@@ -1077,8 +1076,9 @@ int fsl_rio_setup(struct of_device *dev)
 
        INIT_LIST_HEAD(&port->dbells);
        port->iores.start = law_start;
-       port->iores.end = law_start + law_size;
+       port->iores.end = law_start + law_size - 1;
        port->iores.flags = IORESOURCE_MEM;
+       port->iores.name = "rio_io_win";
 
        priv->bellirq = irq_of_parse_and_map(dev->node, 2);
        priv->txirq = irq_of_parse_and_map(dev->node, 3);
@@ -1156,14 +1156,15 @@ int fsl_rio_setup(struct of_device *dev)
                out_be32((priv->regs_win + RIO_ISR_AACR), RIO_ISR_AACR_AA);
 
        /* Configure maintenance transaction window */
-       out_be32(&priv->maint_atmu_regs->rowbar, 0x000c0000);
-       out_be32(&priv->maint_atmu_regs->rowar, 0x80077015);
+       out_be32(&priv->maint_atmu_regs->rowbar, law_start >> 12);
+       out_be32(&priv->maint_atmu_regs->rowar, 0x80077015);    /* 4M */
 
        priv->maint_win = ioremap(law_start, RIO_MAINT_WIN_SIZE);
 
        /* Configure outbound doorbell window */
-       out_be32(&priv->dbell_atmu_regs->rowbar, 0x000c0400);
-       out_be32(&priv->dbell_atmu_regs->rowar, 0x8004200b);
+       out_be32(&priv->dbell_atmu_regs->rowbar,
+                       (law_start + RIO_MAINT_WIN_SIZE) >> 12);
+       out_be32(&priv->dbell_atmu_regs->rowar, 0x8004200b);    /* 4k */
        fsl_rio_doorbell_init(port);
 
        return 0;
index 5c64ccd402e23f250c84e49006232920d41b329b..95dbc643c4fc0ba2c411809b624e8fbc7bd1e734 100644 (file)
@@ -379,16 +379,10 @@ static int __init setup_rstcr(void)
        struct device_node *np;
        np = of_find_node_by_name(NULL, "global-utilities");
        if ((np && of_get_property(np, "fsl,has-rstcr", NULL))) {
-               const u32 *prop = of_get_property(np, "reg", NULL);
-               if (prop) {
-                       /* map reset control register
-                        * 0xE00B0 is offset of reset control register
-                        */
-                       rstcr = ioremap(get_immrbase() + *prop + 0xB0, 0xff);
-                       if (!rstcr)
-                               printk (KERN_EMERG "Error: reset control "
-                                               "register not mapped!\n");
-               }
+               rstcr = of_iomap(np, 0) + 0xb0;
+               if (!rstcr)
+                       printk (KERN_EMERG "Error: reset control register "
+                                       "not mapped!\n");
        } else
                printk (KERN_INFO "rstcr compatible register does not exist!\n");
        if (np)
index 7fd49c97501aa965058a12d9b62f484fdde0cc56..7ed8096766422759cf333062020c57f157566687 100644 (file)
@@ -24,7 +24,7 @@ static int
 indirect_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
                     int len, u32 *val)
 {
-       struct pci_controller *hose = bus->sysdata;
+       struct pci_controller *hose = pci_bus_to_host(bus);
        volatile void __iomem *cfg_data;
        u8 cfg_type = 0;
        u32 bus_no, reg;
@@ -82,7 +82,7 @@ static int
 indirect_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
                      int len, u32 val)
 {
-       struct pci_controller *hose = bus->sysdata;
+       struct pci_controller *hose = pci_bus_to_host(bus);
        volatile void __iomem *cfg_data;
        u8 cfg_type = 0;
        u32 bus_no, reg;
index 352d8c3ef5269c97e548789edccc49c420214a71..9c3af5045495bb67c0259998a39dd641c65e47ea 100644 (file)
@@ -613,23 +613,23 @@ static int irq_choose_cpu(unsigned int virt_irq)
 #define mpic_irq_to_hw(virq)   ((unsigned int)irq_map[virq].hwirq)
 
 /* Find an mpic associated with a given linux interrupt */
-static struct mpic *mpic_find(unsigned int irq, unsigned int *is_ipi)
+static struct mpic *mpic_find(unsigned int irq)
 {
-       unsigned int src = mpic_irq_to_hw(irq);
-       struct mpic *mpic;
-
        if (irq < NUM_ISA_INTERRUPTS)
                return NULL;
 
-       mpic = irq_desc[irq].chip_data;
+       return irq_desc[irq].chip_data;
+}
 
-       if (is_ipi)
-               *is_ipi = (src >= mpic->ipi_vecs[0] &&
-                          src <= mpic->ipi_vecs[3]);
+/* Determine if the linux irq is an IPI */
+static unsigned int mpic_is_ipi(struct mpic *mpic, unsigned int irq)
+{
+       unsigned int src = mpic_irq_to_hw(irq);
 
-       return mpic;
+       return (src >= mpic->ipi_vecs[0] && src <= mpic->ipi_vecs[3]);
 }
 
+
 /* Convert a cpu mask from logical to physical cpu numbers. */
 static inline u32 mpic_physmask(u32 cpumask)
 {
@@ -1383,8 +1383,7 @@ void __init mpic_set_serial_int(struct mpic *mpic, int enable)
 
 void mpic_irq_set_priority(unsigned int irq, unsigned int pri)
 {
-       unsigned int is_ipi;
-       struct mpic *mpic = mpic_find(irq, &is_ipi);
+       struct mpic *mpic = mpic_find(irq);
        unsigned int src = mpic_irq_to_hw(irq);
        unsigned long flags;
        u32 reg;
@@ -1393,7 +1392,7 @@ void mpic_irq_set_priority(unsigned int irq, unsigned int pri)
                return;
 
        spin_lock_irqsave(&mpic_lock, flags);
-       if (is_ipi) {
+       if (mpic_is_ipi(mpic, irq)) {
                reg = mpic_ipi_read(src - mpic->ipi_vecs[0]) &
                        ~MPIC_VECPRI_PRIORITY_MASK;
                mpic_ipi_write(src - mpic->ipi_vecs[0],
index 6a2d473c345a35595a58e5a2a4b1dd637b3dbb84..daefc93ddffec42eb4e15ccfb218e127ccee4032 100644 (file)
@@ -1295,7 +1295,7 @@ static void __iomem *ppc4xx_pciex_get_config_base(struct ppc4xx_pciex_port *port
 static int ppc4xx_pciex_read_config(struct pci_bus *bus, unsigned int devfn,
                                    int offset, int len, u32 *val)
 {
-       struct pci_controller *hose = (struct pci_controller *) bus->sysdata;
+       struct pci_controller *hose = pci_bus_to_host(bus);
        struct ppc4xx_pciex_port *port =
                &ppc4xx_pciex_ports[hose->indirect_type];
        void __iomem *addr;
@@ -1352,7 +1352,7 @@ static int ppc4xx_pciex_read_config(struct pci_bus *bus, unsigned int devfn,
 static int ppc4xx_pciex_write_config(struct pci_bus *bus, unsigned int devfn,
                                     int offset, int len, u32 val)
 {
-       struct pci_controller *hose = (struct pci_controller *) bus->sysdata;
+       struct pci_controller *hose = pci_bus_to_host(bus);
        struct ppc4xx_pciex_port *port =
                &ppc4xx_pciex_ports[hose->indirect_type];
        void __iomem *addr;
index 01bce3784b0acb89404c778a9e6ec20cfe0a13d7..b28b0e512d67d91a2c1fb108f94cc9eea90e4b03 100644 (file)
@@ -61,6 +61,7 @@ struct qe_immap __iomem *qe_immr;
 EXPORT_SYMBOL(qe_immr);
 
 static struct qe_snum snums[QE_NUM_OF_SNUM];   /* Dynamically allocated SNUMs */
+static unsigned int qe_num_of_snum;
 
 static phys_addr_t qebase = -1;
 
@@ -264,10 +265,14 @@ static void qe_snums_init(void)
                0x04, 0x05, 0x0C, 0x0D, 0x14, 0x15, 0x1C, 0x1D,
                0x24, 0x25, 0x2C, 0x2D, 0x34, 0x35, 0x88, 0x89,
                0x98, 0x99, 0xA8, 0xA9, 0xB8, 0xB9, 0xC8, 0xC9,
-               0xD8, 0xD9, 0xE8, 0xE9,
+               0xD8, 0xD9, 0xE8, 0xE9, 0x08, 0x09, 0x18, 0x19,
+               0x28, 0x29, 0x38, 0x39, 0x48, 0x49, 0x58, 0x59,
+               0x68, 0x69, 0x78, 0x79, 0x80, 0x81,
        };
 
-       for (i = 0; i < QE_NUM_OF_SNUM; i++) {
+       qe_num_of_snum = qe_get_num_of_snums();
+
+       for (i = 0; i < qe_num_of_snum; i++) {
                snums[i].num = snum_init[i];
                snums[i].state = QE_SNUM_STATE_FREE;
        }
@@ -280,7 +285,7 @@ int qe_get_snum(void)
        int i;
 
        spin_lock_irqsave(&qe_lock, flags);
-       for (i = 0; i < QE_NUM_OF_SNUM; i++) {
+       for (i = 0; i < qe_num_of_snum; i++) {
                if (snums[i].state == QE_SNUM_STATE_FREE) {
                        snums[i].state = QE_SNUM_STATE_USED;
                        snum = snums[i].num;
@@ -297,7 +302,7 @@ void qe_put_snum(u8 snum)
 {
        int i;
 
-       for (i = 0; i < QE_NUM_OF_SNUM; i++) {
+       for (i = 0; i < qe_num_of_snum; i++) {
                if (snums[i].num == snum) {
                        snums[i].state = QE_SNUM_STATE_FREE;
                        break;
@@ -575,3 +580,65 @@ struct qe_firmware_info *qe_get_firmware_info(void)
 }
 EXPORT_SYMBOL(qe_get_firmware_info);
 
+unsigned int qe_get_num_of_risc(void)
+{
+       struct device_node *qe;
+       int size;
+       unsigned int num_of_risc = 0;
+       const u32 *prop;
+
+       qe = of_find_compatible_node(NULL, NULL, "fsl,qe");
+       if (!qe) {
+               /* Older devices trees did not have an "fsl,qe"
+                * compatible property, so we need to look for
+                * the QE node by name.
+                */
+               qe = of_find_node_by_type(NULL, "qe");
+               if (!qe)
+                       return num_of_risc;
+       }
+
+       prop = of_get_property(qe, "fsl,qe-num-riscs", &size);
+       if (prop && size == sizeof(*prop))
+               num_of_risc = *prop;
+
+       of_node_put(qe);
+
+       return num_of_risc;
+}
+EXPORT_SYMBOL(qe_get_num_of_risc);
+
+unsigned int qe_get_num_of_snums(void)
+{
+       struct device_node *qe;
+       int size;
+       unsigned int num_of_snums;
+       const u32 *prop;
+
+       num_of_snums = 28; /* The default number of snum for threads is 28 */
+       qe = of_find_compatible_node(NULL, NULL, "fsl,qe");
+       if (!qe) {
+               /* Older devices trees did not have an "fsl,qe"
+                * compatible property, so we need to look for
+                * the QE node by name.
+                */
+               qe = of_find_node_by_type(NULL, "qe");
+               if (!qe)
+                       return num_of_snums;
+       }
+
+       prop = of_get_property(qe, "fsl,qe-num-snums", &size);
+       if (prop && size == sizeof(*prop)) {
+               num_of_snums = *prop;
+               if ((num_of_snums < 28) || (num_of_snums > QE_NUM_OF_SNUM)) {
+                       /* No QE ever has fewer than 28 SNUMs */
+                       pr_err("QE: number of snum is invalid\n");
+                       return -EINVAL;
+               }
+       }
+
+       of_node_put(qe);
+
+       return num_of_snums;
+}
+EXPORT_SYMBOL(qe_get_num_of_snums);
index 24e1f5a197ae31d3de4377a23e936449072e5e80..cf244a419e9650cd631189a26b59455a64ef5f3b 100644 (file)
@@ -63,7 +63,7 @@ tsi108_direct_write_config(struct pci_bus *bus, unsigned int devfunc,
                           int offset, int len, u32 val)
 {
        volatile unsigned char *cfg_addr;
-       struct pci_controller *hose = bus->sysdata;
+       struct pci_controller *hose = pci_bus_to_host(bus);
 
        if (ppc_md.pci_exclude_device)
                if (ppc_md.pci_exclude_device(hose, bus->number, devfunc))
@@ -149,7 +149,7 @@ tsi108_direct_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
                          int len, u32 * val)
 {
        volatile unsigned char *cfg_addr;
-       struct pci_controller *hose = bus->sysdata;
+       struct pci_controller *hose = pci_bus_to_host(bus);
        u32 temp;
 
        if (ppc_md.pci_exclude_device)
index c658b413c9b4c28d1b6cd8efb559987a34c1d050..3ee1fd37bbfc3b819107a8dd4d9b2496f59ecc84 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/of.h>
 #include <asm/io.h>
 #include <asm/processor.h>
+#include <asm/i8259.h>
 #include <asm/irq.h>
 
 /*
@@ -191,20 +192,14 @@ struct irq_host * __init
 xilinx_intc_init(struct device_node *np)
 {
        struct irq_host * irq;
-       struct resource res;
        void * regs;
-       int rc;
 
        /* Find and map the intc registers */
-       rc = of_address_to_resource(np, 0, &res);
-       if (rc) {
-               printk(KERN_ERR __FILE__ ": of_address_to_resource() failed\n");
+       regs = of_iomap(np, 0);
+       if (!regs) {
+               pr_err("xilinx_intc: could not map registers\n");
                return NULL;
        }
-       regs = ioremap(res.start, 32);
-
-       printk(KERN_INFO "Xilinx intc at 0x%08llx mapped to 0x%p\n",
-               (unsigned long long) res.start, regs);
 
        /* Setup interrupt controller */
        out_be32(regs + XINTC_IER, 0); /* disable all irqs */
@@ -217,6 +212,7 @@ xilinx_intc_init(struct device_node *np)
        if (!irq)
                panic(__FILE__ ": Cannot allocate IRQ host\n");
        irq->host_data = regs;
+
        return irq;
 }
 
@@ -227,23 +223,70 @@ int xilinx_intc_get_irq(void)
        return irq_linear_revmap(master_irqhost, in_be32(regs + XINTC_IVR));
 }
 
+#if defined(CONFIG_PPC_I8259)
+/*
+ * Support code for cascading to 8259 interrupt controllers
+ */
+static void xilinx_i8259_cascade(unsigned int irq, struct irq_desc *desc)
+{
+       unsigned int cascade_irq = i8259_irq();
+       if (cascade_irq)
+               generic_handle_irq(cascade_irq);
+
+       /* Let xilinx_intc end the interrupt */
+       desc->chip->ack(irq);
+       desc->chip->unmask(irq);
+}
+
+static void __init xilinx_i8259_setup_cascade(void)
+{
+       struct device_node *cascade_node;
+       int cascade_irq;
+
+       /* Initialize i8259 controller */
+       cascade_node = of_find_compatible_node(NULL, NULL, "chrp,iic");
+       if (!cascade_node)
+               return;
+
+       cascade_irq = irq_of_parse_and_map(cascade_node, 0);
+       if (!cascade_irq) {
+               pr_err("virtex_ml510: Failed to map cascade interrupt\n");
+               goto out;
+       }
+
+       i8259_init(cascade_node, 0);
+       set_irq_chained_handler(cascade_irq, xilinx_i8259_cascade);
+
+       /* Program irq 7 (usb/audio), 14/15 (ide) to level sensitive */
+       /* This looks like a dirty hack to me --gcl */
+       outb(0xc0, 0x4d0);
+       outb(0xc0, 0x4d1);
+
+ out:
+       of_node_put(cascade_node);
+}
+#else
+static inline void xilinx_i8259_setup_cascade(void) { return; }
+#endif /* defined(CONFIG_PPC_I8259) */
+
+static struct of_device_id xilinx_intc_match[] __initconst = {
+       { .compatible = "xlnx,opb-intc-1.00.c", },
+       { .compatible = "xlnx,xps-intc-1.00.a", },
+       {}
+};
+
+/*
+ * Initialize master Xilinx interrupt controller
+ */
 void __init xilinx_intc_init_tree(void)
 {
        struct device_node *np;
 
        /* find top level interrupt controller */
-       for_each_compatible_node(np, NULL, "xlnx,opb-intc-1.00.c") {
+       for_each_matching_node(np, xilinx_intc_match) {
                if (!of_get_property(np, "interrupts", NULL))
                        break;
        }
-       if (!np) {
-               for_each_compatible_node(np, NULL, "xlnx,xps-intc-1.00.a") {
-                       if (!of_get_property(np, "interrupts", NULL))
-                               break;
-               }
-       }
-
-       /* xilinx interrupt controller needs to be top level */
        BUG_ON(!np);
 
        master_irqhost = xilinx_intc_init(np);
@@ -251,4 +294,6 @@ void __init xilinx_intc_init_tree(void)
 
        irq_set_default_host(master_irqhost);
        of_node_put(np);
+
+       xilinx_i8259_setup_cascade();
 }
diff --git a/arch/powerpc/sysdev/xilinx_pci.c b/arch/powerpc/sysdev/xilinx_pci.c
new file mode 100644 (file)
index 0000000..1453b0e
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * PCI support for Xilinx plbv46_pci soft-core which can be used on
+ * Xilinx Virtex ML410 / ML510 boards.
+ *
+ * Copyright 2009 Roderick Colenbrander
+ * Copyright 2009 Secret Lab Technologies Ltd.
+ *
+ * The pci bridge fixup code was copied from ppc4xx_pci.c and was written
+ * by Benjamin Herrenschmidt.
+ * Copyright 2007 Ben. Herrenschmidt <benh@kernel.crashing.org>, IBM Corp.
+ *
+ * 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/ioport.h>
+#include <linux/of.h>
+#include <linux/pci.h>
+#include <mm/mmu_decl.h>
+#include <asm/io.h>
+#include <asm/xilinx_pci.h>
+
+#define XPLB_PCI_ADDR 0x10c
+#define XPLB_PCI_DATA 0x110
+#define XPLB_PCI_BUS  0x114
+
+#define PCI_HOST_ENABLE_CMD PCI_COMMAND_SERR | PCI_COMMAND_PARITY | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY
+
+static struct of_device_id xilinx_pci_match[] = {
+       { .compatible = "xlnx,plbv46-pci-1.03.a", },
+       {}
+};
+
+/**
+ * xilinx_pci_fixup_bridge - Block Xilinx PHB configuration.
+ */
+static void xilinx_pci_fixup_bridge(struct pci_dev *dev)
+{
+       struct pci_controller *hose;
+       int i;
+
+       if (dev->devfn || dev->bus->self)
+               return;
+
+       hose = pci_bus_to_host(dev->bus);
+       if (!hose)
+               return;
+
+       if (!of_match_node(xilinx_pci_match, hose->dn))
+               return;
+
+       /* Hide the PCI host BARs from the kernel as their content doesn't
+        * fit well in the resource management
+        */
+       for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
+               dev->resource[i].start = 0;
+               dev->resource[i].end = 0;
+               dev->resource[i].flags = 0;
+       }
+
+       dev_info(&dev->dev, "Hiding Xilinx plb-pci host bridge resources %s\n",
+                pci_name(dev));
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, xilinx_pci_fixup_bridge);
+
+/**
+ * xilinx_pci_exclude_device - Don't do config access for non-root bus
+ *
+ * This is a hack.  Config access to any bus other than bus 0 does not
+ * currently work on the ML510 so we prevent it here.
+ */
+static int
+xilinx_pci_exclude_device(struct pci_controller *hose, u_char bus, u8 devfn)
+{
+       return (bus != 0);
+}
+
+/**
+ * xilinx_pci_init - Find and register a Xilinx PCI host bridge
+ */
+void __init xilinx_pci_init(void)
+{
+       struct pci_controller *hose;
+       struct resource r;
+       void __iomem *pci_reg;
+       struct device_node *pci_node;
+
+       pci_node = of_find_matching_node(NULL, xilinx_pci_match);
+       if(!pci_node)
+               return;
+
+       if (of_address_to_resource(pci_node, 0, &r)) {
+               pr_err("xilinx-pci: cannot resolve base address\n");
+               return;
+       }
+
+       hose = pcibios_alloc_controller(pci_node);
+       if (!hose) {
+               pr_err("xilinx-pci: pcibios_alloc_controller() failed\n");
+               return;
+       }
+
+       /* Setup config space */
+       setup_indirect_pci(hose, r.start + XPLB_PCI_ADDR,
+                          r.start + XPLB_PCI_DATA,
+                          PPC_INDIRECT_TYPE_SET_CFG_TYPE);
+
+       /* According to the xilinx plbv46_pci documentation the soft-core starts
+        * a self-init when the bus master enable bit is set. Without this bit
+        * set the pci bus can't be scanned.
+        */
+       early_write_config_word(hose, 0, 0, PCI_COMMAND, PCI_HOST_ENABLE_CMD);
+
+       /* Set the max latency timer to 255 */
+       early_write_config_byte(hose, 0, 0, PCI_LATENCY_TIMER, 0xff);
+
+       /* Set the max bus number to 255 */
+       pci_reg = of_iomap(pci_node, 0);
+       out_8(pci_reg + XPLB_PCI_BUS, 0xff);
+       iounmap(pci_reg);
+
+       /* Nothing past the root bridge is working right now.  By default
+        * exclude config access to anything except bus 0 */
+       if (!ppc_md.pci_exclude_device)
+               ppc_md.pci_exclude_device = xilinx_pci_exclude_device;
+
+       /* Register the host bridge with the linux kernel! */
+       pci_process_bridge_OF_ranges(hose, pci_node, 1);
+
+       pr_info("xilinx-pci: Registered PCI host bridge\n");
+}
index 8dfad7d9a0043298867d6b523347c57457e114b8..e1f33a81e5e1f130cf3c1e0b82b4d9d751cf904b 100644 (file)
@@ -110,6 +110,7 @@ static int bsesc(void);
 static void dump(void);
 static void prdump(unsigned long, long);
 static int ppc_inst_dump(unsigned long, long, int);
+static void dump_log_buf(void);
 static void backtrace(struct pt_regs *);
 static void excprint(struct pt_regs *);
 static void prregs(struct pt_regs *);
@@ -197,6 +198,7 @@ Commands:\n\
   di   dump instructions\n\
   df   dump float values\n\
   dd   dump double values\n\
+  dl    dump the kernel log buffer\n\
   dr   dump stream of raw bytes\n\
   e    print exception information\n\
   f    flush cache\n\
@@ -2009,6 +2011,8 @@ dump(void)
                        nidump = MAX_DUMP;
                adrs += ppc_inst_dump(adrs, nidump, 1);
                last_cmd = "di\n";
+       } else if (c == 'l') {
+               dump_log_buf();
        } else if (c == 'r') {
                scanhex(&ndump);
                if (ndump == 0)
@@ -2122,6 +2126,49 @@ print_address(unsigned long addr)
        xmon_print_symbol(addr, "\t# ", "");
 }
 
+void
+dump_log_buf(void)
+{
+        const unsigned long size = 128;
+        unsigned long end, addr;
+        unsigned char buf[size + 1];
+
+        addr = 0;
+        buf[size] = '\0';
+
+        if (setjmp(bus_error_jmp) != 0) {
+                printf("Unable to lookup symbol __log_buf!\n");
+                return;
+        }
+
+        catch_memory_errors = 1;
+        sync();
+        addr = kallsyms_lookup_name("__log_buf");
+
+        if (! addr)
+                printf("Symbol __log_buf not found!\n");
+        else {
+                end = addr + (1 << CONFIG_LOG_BUF_SHIFT);
+                while (addr < end) {
+                        if (! mread(addr, buf, size)) {
+                                printf("Can't read memory at address 0x%lx\n", addr);
+                                break;
+                        }
+
+                        printf("%s", buf);
+
+                        if (strlen(buf) < size)
+                                break;
+
+                        addr += size;
+                }
+        }
+
+        sync();
+        /* wait a little while to see if we get a machine check */
+        __delay(200);
+        catch_memory_errors = 0;
+}
 
 /*
  * Memory operations - move, set, print differences
index a9ef172977de30856cc1f54dfa05363a99a0e383..4e2bc490d71412aea2db9428604612143ce74003 100644 (file)
 #define        EOWNERDEAD      132     /* Owner died */
 #define        ENOTRECOVERABLE 133     /* State not recoverable */
 
+#define        ERFKILL         134     /* Operation not possible due to RF-kill */
+
 #endif
index ef0ae207a7c82cb64f7a0a7758a91dc22b0f8fee..096d19aea2f7180b40be33870a0225ac822f71d3 100644 (file)
@@ -463,7 +463,7 @@ static void uv_heartbeat(unsigned long ignored)
        uv_set_scir_bits(bits);
 
        /* enable next timer period */
-       mod_timer(timer, jiffies + SCIR_CPU_HB_INTERVAL);
+       mod_timer_pinned(timer, jiffies + SCIR_CPU_HB_INTERVAL);
 }
 
 static void __cpuinit uv_heartbeat_enable(int cpu)
index 1266ead6ace0b9272ea4c1f24d5bc2e1c875e4f7..9e7d4e56c85ba2747a0463daefef1aa7fef1ac40 100644 (file)
@@ -107,3 +107,4 @@ obj-$(CONFIG_SSB)           += ssb/
 obj-$(CONFIG_VIRTIO)           += virtio/
 obj-$(CONFIG_STAGING)          += staging/
 obj-y                          += platform/
+obj-y                          += ieee802154/
index 07e20135f01b30873d1f4aca495d7278a81962cd..0bba148a2c61fc084d52a58df1b1498b20ef6034 100644 (file)
@@ -139,7 +139,7 @@ acpi_status acpi_ev_initialize_op_regions(void);
 acpi_status
 acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj,
                               u32 function,
-                              acpi_physical_address address,
+                              u32 region_offset,
                               u32 bit_width, acpi_integer * value);
 
 acpi_status
index 16e5210ae936288c17a76b0c7f82e93873b658fa..3d87362d17ed163851c3f5790fb4ecc4976e5c30 100644 (file)
@@ -362,9 +362,6 @@ extern u8 acpi_gbl_method_executing;
 extern u8 acpi_gbl_abort_method;
 extern u8 acpi_gbl_db_terminate_threads;
 
-ACPI_EXTERN int optind;
-ACPI_EXTERN char *optarg;
-
 ACPI_EXTERN u8 acpi_gbl_db_opt_tables;
 ACPI_EXTERN u8 acpi_gbl_db_opt_stats;
 ACPI_EXTERN u8 acpi_gbl_db_opt_ini_methods;
index 2ec394a328e95fea0f15d2e94aef9c32fda507dd..ee986edfa0da32704133b949624aa6ff75f3bea2 100644 (file)
@@ -205,6 +205,7 @@ struct acpi_namespace_node {
 #define ANOBJ_METHOD_LOCAL              0x08   /* Node is a method local */
 #define ANOBJ_SUBTREE_HAS_INI           0x10   /* Used to optimize device initialization */
 #define ANOBJ_EVALUATED                 0x20   /* Set on first evaluation of node */
+#define ANOBJ_ALLOCATED_BUFFER          0x40   /* Method AML buffer is dynamic (install_method) */
 
 #define ANOBJ_IS_EXTERNAL               0x08   /* i_aSL only: This object created via External() */
 #define ANOBJ_METHOD_NO_RETVAL          0x10   /* i_aSL only: Method has no return value */
@@ -788,11 +789,14 @@ struct acpi_bit_register_info {
 /* For control registers, both ignored and reserved bits must be preserved */
 
 /*
- * The ACPI spec says to ignore PM1_CTL.SCI_EN (bit 0)
- * but we need to be able to write ACPI_BITREG_SCI_ENABLE directly
- * as a BIOS workaround on some machines.
+ * For PM1 control, the SCI enable bit (bit 0, SCI_EN) is defined by the
+ * ACPI specification to be a "preserved" bit - "OSPM always preserves this
+ * bit position", section 4.7.3.2.1. However, on some machines the OS must
+ * write a one to this bit after resume for the machine to work properly.
+ * To enable this, we no longer attempt to preserve this bit. No machines
+ * are known to fail if the bit is not preserved. (May 2009)
  */
-#define ACPI_PM1_CONTROL_IGNORED_BITS           0x0200 /* Bits 9 */
+#define ACPI_PM1_CONTROL_IGNORED_BITS           0x0200 /* Bit 9 */
 #define ACPI_PM1_CONTROL_RESERVED_BITS          0xC1F8 /* Bits 14-15, 3-8 */
 #define ACPI_PM1_CONTROL_PRESERVED_BITS \
               (ACPI_PM1_CONTROL_IGNORED_BITS | ACPI_PM1_CONTROL_RESERVED_BITS)
index 46cb5b46d2803fd43bf7691bf0ee065fcf039dfc..94cdc2b8cb9385d6814005933810afd6d81e8d72 100644 (file)
@@ -99,10 +99,19 @@ acpi_ns_walk_namespace(acpi_object_type type,
                       acpi_walk_callback user_function,
                       void *context, void **return_value);
 
-struct acpi_namespace_node *acpi_ns_get_next_node(acpi_object_type type, struct acpi_namespace_node
-                                                 *parent, struct acpi_namespace_node
+struct acpi_namespace_node *acpi_ns_get_next_node(struct acpi_namespace_node
+                                                 *parent,
+                                                 struct acpi_namespace_node
                                                  *child);
 
+struct acpi_namespace_node *acpi_ns_get_next_node_typed(acpi_object_type type,
+                                                       struct
+                                                       acpi_namespace_node
+                                                       *parent,
+                                                       struct
+                                                       acpi_namespace_node
+                                                       *child);
+
 /*
  * nsparse - table parsing
  */
index ff851c5df698a465a3c5e3d730b0a00d7d14ea07..067f967eb389cf720b2ee7d9a25b840ca3477443 100644 (file)
@@ -483,7 +483,7 @@ typedef enum {
 
 #define AML_METHOD_ARG_COUNT        0x07
 #define AML_METHOD_SERIALIZED       0x08
-#define AML_METHOD_SYNCH_LEVEL      0xF0
+#define AML_METHOD_SYNC_LEVEL       0xF0
 
 /* METHOD_FLAGS_ARG_COUNT is not used internally, define additional flags */
 
index dab3f48f0b42938066b145c58a7b1c231139944d..02e6caad4a7610718bb4d52df924a86ef5bf10e4 100644 (file)
@@ -734,7 +734,8 @@ acpi_ds_init_object_from_op(struct acpi_walk_state *walk_state,
 
                        /* Local ID (0-7) is (AML opcode - base AML_LOCAL_OP) */
 
-                       obj_desc->reference.value = opcode - AML_LOCAL_OP;
+                       obj_desc->reference.value =
+                           ((u32)opcode) - AML_LOCAL_OP;
                        obj_desc->reference.class = ACPI_REFCLASS_LOCAL;
 
 #ifndef ACPI_NO_METHOD_EXECUTION
@@ -754,7 +755,7 @@ acpi_ds_init_object_from_op(struct acpi_walk_state *walk_state,
 
                        /* Arg ID (0-6) is (AML opcode - base AML_ARG_OP) */
 
-                       obj_desc->reference.value = opcode - AML_ARG_OP;
+                       obj_desc->reference.value = ((u32)opcode) - AML_ARG_OP;
                        obj_desc->reference.class = ACPI_REFCLASS_ARG;
 
 #ifndef ACPI_NO_METHOD_EXECUTION
index b4c87b5053e6d1c6daeff5d68013672466061378..584d766e6f124248c1b496731df225fd94fa0099 100644 (file)
@@ -1386,14 +1386,19 @@ acpi_ds_exec_end_control_op(struct acpi_walk_state * walk_state,
 
        case AML_BREAK_POINT_OP:
 
-               /* Call up to the OS service layer to handle this */
-
-               status =
-                   acpi_os_signal(ACPI_SIGNAL_BREAKPOINT,
-                                  "Executed AML Breakpoint opcode");
+               /*
+                * Set the single-step flag. This will cause the debugger (if present)
+                * to break to the console within the AML debugger at the start of the
+                * next AML instruction.
+                */
+               ACPI_DEBUGGER_EXEC(acpi_gbl_cm_single_step = TRUE);
+               ACPI_DEBUGGER_EXEC(acpi_os_printf
+                                  ("**break** Executed AML BreakPoint opcode\n"));
 
-               /* If and when it returns, all done. */
+               /* Call to the OSL in case OS wants a piece of the action */
 
+               status = acpi_os_signal(ACPI_SIGNAL_BREAKPOINT,
+                                       "Executed AML Breakpoint opcode");
                break;
 
        case AML_BREAK_OP:
index 40f92bf7dce5cc2e7bf33cd5fd83013d544d4328..e46c821cf57295b7064bd58a333d1692e373451e 100644 (file)
@@ -102,7 +102,7 @@ acpi_ds_result_pop(union acpi_operand_object **object,
        /* Return object of the top element and clean that top element result stack */
 
        walk_state->result_count--;
-       index = walk_state->result_count % ACPI_RESULTS_FRAME_OBJ_NUM;
+       index = (u32)walk_state->result_count % ACPI_RESULTS_FRAME_OBJ_NUM;
 
        *object = state->results.obj_desc[index];
        if (!*object) {
@@ -186,7 +186,7 @@ acpi_ds_result_push(union acpi_operand_object * object,
 
        /* Assign the address of object to the top free element of result stack */
 
-       index = walk_state->result_count % ACPI_RESULTS_FRAME_OBJ_NUM;
+       index = (u32)walk_state->result_count % ACPI_RESULTS_FRAME_OBJ_NUM;
        state->results.obj_desc[index] = object;
        walk_state->result_count++;
 
index 538d63264555b321d473ef95942f8602d9fe4a51..98c7f9c626531f00e2bb9933c02ff61c8c0d42df 100644 (file)
@@ -275,7 +275,7 @@ acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function)
  *
  * PARAMETERS:  region_obj          - Internal region object
  *              Function            - Read or Write operation
- *              Address             - Where in the space to read or write
+ *              region_offset       - Where in the region to read or write
  *              bit_width           - Field width in bits (8, 16, 32, or 64)
  *              Value               - Pointer to in or out value, must be
  *                                    full 64-bit acpi_integer
@@ -290,7 +290,7 @@ acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function)
 acpi_status
 acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj,
                               u32 function,
-                              acpi_physical_address address,
+                              u32 region_offset,
                               u32 bit_width, acpi_integer * value)
 {
        acpi_status status;
@@ -396,7 +396,8 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj,
        ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
                          "Handler %p (@%p) Address %8.8X%8.8X [%s]\n",
                          &region_obj->region.handler->address_space, handler,
-                         ACPI_FORMAT_NATIVE_UINT(address),
+                         ACPI_FORMAT_NATIVE_UINT(region_obj->region.address +
+                                                 region_offset),
                          acpi_ut_get_region_name(region_obj->region.
                                                  space_id)));
 
@@ -412,8 +413,9 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj,
 
        /* Call the handler */
 
-       status = handler(function, address, bit_width, value,
-                        handler_desc->address_space.context,
+       status = handler(function,
+                        (region_obj->region.address + region_offset),
+                        bit_width, value, handler_desc->address_space.context,
                         region_obj2->extra.region_context);
 
        if (ACPI_FAILURE(status)) {
index d0a080747ec35cf6c2754ca3c534cb618401800c..4721f58fe42c0653d6a6c14aee384ffbab2e708a 100644 (file)
@@ -51,7 +51,7 @@
 ACPI_MODULE_NAME("evxfevnt")
 
 /* Local prototypes */
-acpi_status
+static acpi_status
 acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
                       struct acpi_gpe_block_info *gpe_block, void *context);
 
@@ -785,7 +785,7 @@ ACPI_EXPORT_SYMBOL(acpi_get_gpe_device)
  *              block device. NULL if the GPE is one of the FADT-defined GPEs.
  *
  ******************************************************************************/
-acpi_status
+static acpi_status
 acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
                       struct acpi_gpe_block_info *gpe_block, void *context)
 {
index 3deb20a126b215d706b162ea761fa8eb3ead0344..277fd609611aec1a92eb5717c21724425ce4f61a 100644 (file)
@@ -47,6 +47,7 @@
 #include "acnamesp.h"
 #include "actables.h"
 #include "acdispat.h"
+#include "acevents.h"
 
 #define _COMPONENT          ACPI_EXECUTER
 ACPI_MODULE_NAME("exconfig")
@@ -57,6 +58,10 @@ acpi_ex_add_table(u32 table_index,
                  struct acpi_namespace_node *parent_node,
                  union acpi_operand_object **ddb_handle);
 
+static acpi_status
+acpi_ex_region_read(union acpi_operand_object *obj_desc,
+                   u32 length, u8 *buffer);
+
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ex_add_table
@@ -91,6 +96,7 @@ acpi_ex_add_table(u32 table_index,
 
        /* Init the table handle */
 
+       obj_desc->common.flags |= AOPOBJ_DATA_VALID;
        obj_desc->reference.class = ACPI_REFCLASS_TABLE;
        *ddb_handle = obj_desc;
 
@@ -229,6 +235,8 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state,
                                       walk_state);
                if (ACPI_FAILURE(status)) {
                        (void)acpi_ex_unload_table(ddb_handle);
+
+                       acpi_ut_remove_reference(ddb_handle);
                        return_ACPI_STATUS(status);
                }
        }
@@ -252,6 +260,47 @@ acpi_ex_load_table_op(struct acpi_walk_state *walk_state,
        return_ACPI_STATUS(status);
 }
 
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ex_region_read
+ *
+ * PARAMETERS:  obj_desc        - Region descriptor
+ *              Length          - Number of bytes to read
+ *              Buffer          - Pointer to where to put the data
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Read data from an operation region. The read starts from the
+ *              beginning of the region.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_ex_region_read(union acpi_operand_object *obj_desc, u32 length, u8 *buffer)
+{
+       acpi_status status;
+       acpi_integer value;
+       u32 region_offset = 0;
+       u32 i;
+
+       /* Bytewise reads */
+
+       for (i = 0; i < length; i++) {
+               status = acpi_ev_address_space_dispatch(obj_desc, ACPI_READ,
+                                                       region_offset, 8,
+                                                       &value);
+               if (ACPI_FAILURE(status)) {
+                       return status;
+               }
+
+               *buffer = (u8)value;
+               buffer++;
+               region_offset++;
+       }
+
+       return AE_OK;
+}
+
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ex_load_op
@@ -314,18 +363,23 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
                        }
                }
 
-               /*
-                * Map the table header and get the actual table length. The region
-                * length is not guaranteed to be the same as the table length.
-                */
-               table = acpi_os_map_memory(obj_desc->region.address,
-                                          sizeof(struct acpi_table_header));
+               /* Get the table header first so we can get the table length */
+
+               table = ACPI_ALLOCATE(sizeof(struct acpi_table_header));
                if (!table) {
                        return_ACPI_STATUS(AE_NO_MEMORY);
                }
 
+               status =
+                   acpi_ex_region_read(obj_desc,
+                                       sizeof(struct acpi_table_header),
+                                       ACPI_CAST_PTR(u8, table));
                length = table->length;
-               acpi_os_unmap_memory(table, sizeof(struct acpi_table_header));
+               ACPI_FREE(table);
+
+               if (ACPI_FAILURE(status)) {
+                       return_ACPI_STATUS(status);
+               }
 
                /* Must have at least an ACPI table header */
 
@@ -334,10 +388,19 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
                }
 
                /*
-                * The memory region is not guaranteed to remain stable and we must
-                * copy the table to a local buffer. For example, the memory region
-                * is corrupted after suspend on some machines. Dynamically loaded
-                * tables are usually small, so this overhead is minimal.
+                * The original implementation simply mapped the table, with no copy.
+                * However, the memory region is not guaranteed to remain stable and
+                * we must copy the table to a local buffer. For example, the memory
+                * region is corrupted after suspend on some machines. Dynamically
+                * loaded tables are usually small, so this overhead is minimal.
+                *
+                * The latest implementation (5/2009) does not use a mapping at all.
+                * We use the low-level operation region interface to read the table
+                * instead of the obvious optimization of using a direct mapping.
+                * This maintains a consistent use of operation regions across the
+                * entire subsystem. This is important if additional processing must
+                * be performed in the (possibly user-installed) operation region
+                * handler. For example, acpi_exec and ASLTS depend on this.
                 */
 
                /* Allocate a buffer for the table */
@@ -347,17 +410,16 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
                        return_ACPI_STATUS(AE_NO_MEMORY);
                }
 
-               /* Map the entire table and copy it */
+               /* Read the entire table */
 
-               table = acpi_os_map_memory(obj_desc->region.address, length);
-               if (!table) {
+               status = acpi_ex_region_read(obj_desc, length,
+                                            ACPI_CAST_PTR(u8,
+                                                          table_desc.pointer));
+               if (ACPI_FAILURE(status)) {
                        ACPI_FREE(table_desc.pointer);
-                       return_ACPI_STATUS(AE_NO_MEMORY);
+                       return_ACPI_STATUS(status);
                }
 
-               ACPI_MEMCPY(table_desc.pointer, table, length);
-               acpi_os_unmap_memory(table, length);
-
                table_desc.address = obj_desc->region.address;
                break;
 
@@ -454,6 +516,10 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
                return_ACPI_STATUS(status);
        }
 
+       /* Remove the reference by added by acpi_ex_store above */
+
+       acpi_ut_remove_reference(ddb_handle);
+
        /* Invoke table handler if present */
 
        if (acpi_gbl_table_handler) {
@@ -495,13 +561,18 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle)
 
        /*
         * Validate the handle
-        * Although the handle is partially validated in acpi_ex_reconfiguration(),
+        * Although the handle is partially validated in acpi_ex_reconfiguration()
         * when it calls acpi_ex_resolve_operands(), the handle is more completely
         * validated here.
+        *
+        * Handle must be a valid operand object of type reference. Also, the
+        * ddb_handle must still be marked valid (table has not been previously
+        * unloaded)
         */
        if ((!ddb_handle) ||
            (ACPI_GET_DESCRIPTOR_TYPE(ddb_handle) != ACPI_DESC_TYPE_OPERAND) ||
-           (ddb_handle->common.type != ACPI_TYPE_LOCAL_REFERENCE)) {
+           (ddb_handle->common.type != ACPI_TYPE_LOCAL_REFERENCE) ||
+           (!(ddb_handle->common.flags & AOPOBJ_DATA_VALID))) {
                return_ACPI_STATUS(AE_BAD_PARAMETER);
        }
 
@@ -509,6 +580,12 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle)
 
        table_index = table_desc->reference.value;
 
+       /* Ensure the table is still loaded */
+
+       if (!acpi_tb_is_table_loaded(table_index)) {
+               return_ACPI_STATUS(AE_NOT_EXIST);
+       }
+
        /* Invoke table handler if present */
 
        if (acpi_gbl_table_handler) {
@@ -530,8 +607,10 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle)
        (void)acpi_tb_release_owner_id(table_index);
        acpi_tb_set_table_loaded_flag(table_index, FALSE);
 
-       /* Table unloaded, remove a reference to the ddb_handle object */
-
-       acpi_ut_remove_reference(ddb_handle);
+       /*
+        * Invalidate the handle. We do this because the handle may be stored
+        * in a named object and may not be actually deleted until much later.
+        */
+       ddb_handle->common.flags &= ~AOPOBJ_DATA_VALID;
        return_ACPI_STATUS(AE_OK);
 }
index a57ad2564ab0c7c66a1594601efcf161971dd4be..02b25d233d994523323e673f3f7eb8e99efb4da4 100644 (file)
@@ -502,7 +502,7 @@ acpi_ex_create_method(u8 * aml_start,
                 * ACPI 2.0: sync_level = sync_level in method declaration
                 */
                obj_desc->method.sync_level = (u8)
-                   ((method_flags & AML_METHOD_SYNCH_LEVEL) >> 4);
+                   ((method_flags & AML_METHOD_SYNC_LEVEL) >> 4);
        }
 
        /* Attach the new object to the method Node */
index 89d141fdae0b463eb650d6224219ba2b42fd6ba6..ec524614e7087c42e3337614b319e2a2f67278ca 100644 (file)
@@ -120,9 +120,11 @@ static struct acpi_exdump_info acpi_ex_dump_event[2] = {
        {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(event.os_semaphore), "OsSemaphore"}
 };
 
-static struct acpi_exdump_info acpi_ex_dump_method[8] = {
+static struct acpi_exdump_info acpi_ex_dump_method[9] = {
        {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_method), NULL},
-       {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.param_count), "ParamCount"},
+       {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.method_flags), "Method Flags"},
+       {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.param_count),
+        "Parameter Count"},
        {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.sync_level), "Sync Level"},
        {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(method.mutex), "Mutex"},
        {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(method.owner_id), "Owner Id"},
index 99cee61e655d7ddae24b2e73061a119244826e80..d4075b8210217ecc5c503b54b4831aabe7ad83c2 100644 (file)
@@ -222,7 +222,7 @@ acpi_ex_access_region(union acpi_operand_object *obj_desc,
 {
        acpi_status status;
        union acpi_operand_object *rgn_desc;
-       acpi_physical_address address;
+       u32 region_offset;
 
        ACPI_FUNCTION_TRACE(ex_access_region);
 
@@ -243,7 +243,7 @@ acpi_ex_access_region(union acpi_operand_object *obj_desc,
         * 3) The current offset into the field
         */
        rgn_desc = obj_desc->common_field.region_obj;
-       address = rgn_desc->region.address +
+       region_offset =
            obj_desc->common_field.base_byte_offset + field_datum_byte_offset;
 
        if ((function & ACPI_IO_MASK) == ACPI_READ) {
@@ -260,16 +260,18 @@ acpi_ex_access_region(union acpi_operand_object *obj_desc,
                              obj_desc->common_field.access_byte_width,
                              obj_desc->common_field.base_byte_offset,
                              field_datum_byte_offset, ACPI_CAST_PTR(void,
-                                                                    address)));
+                                                                    (rgn_desc->
+                                                                     region.
+                                                                     address +
+                                                                     region_offset))));
 
        /* Invoke the appropriate address_space/op_region handler */
 
-       status = acpi_ev_address_space_dispatch(rgn_desc, function,
-                                               address,
-                                               ACPI_MUL_8(obj_desc->
-                                                          common_field.
-                                                          access_byte_width),
-                                               value);
+       status =
+           acpi_ev_address_space_dispatch(rgn_desc, function, region_offset,
+                                          ACPI_MUL_8(obj_desc->common_field.
+                                                     access_byte_width),
+                                          value);
 
        if (ACPI_FAILURE(status)) {
                if (status == AE_NOT_IMPLEMENTED) {
index d301c1f363ef0fceb3749ee679d8f1366ec7fb32..2f0114202b05dc8a86e77b31075d3e930e96718f 100644 (file)
@@ -83,6 +83,15 @@ void acpi_ex_unlink_mutex(union acpi_operand_object *obj_desc)
 
        if (obj_desc->mutex.prev) {
                (obj_desc->mutex.prev)->mutex.next = obj_desc->mutex.next;
+
+               /*
+                * Migrate the previous sync level associated with this mutex to the
+                * previous mutex on the list so that it may be preserved. This handles
+                * the case where several mutexes have been acquired at the same level,
+                * but are not released in opposite order.
+                */
+               (obj_desc->mutex.prev)->mutex.original_sync_level =
+                   obj_desc->mutex.original_sync_level;
        } else {
                thread->acquired_mutex_list = obj_desc->mutex.next;
        }
@@ -349,6 +358,7 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc,
                      struct acpi_walk_state *walk_state)
 {
        acpi_status status = AE_OK;
+       u8 previous_sync_level;
 
        ACPI_FUNCTION_TRACE(ex_release_mutex);
 
@@ -373,11 +383,12 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc,
             walk_state->thread->thread_id)
            && (obj_desc != acpi_gbl_global_lock_mutex)) {
                ACPI_ERROR((AE_INFO,
-                           "Thread %lX cannot release Mutex [%4.4s] acquired by thread %lX",
-                           (unsigned long)walk_state->thread->thread_id,
+                           "Thread %p cannot release Mutex [%4.4s] acquired by thread %p",
+                           ACPI_CAST_PTR(void, walk_state->thread->thread_id),
                            acpi_ut_get_node_name(obj_desc->mutex.node),
-                           (unsigned long)obj_desc->mutex.owner_thread->
-                           thread_id));
+                           ACPI_CAST_PTR(void,
+                                         obj_desc->mutex.owner_thread->
+                                         thread_id)));
                return_ACPI_STATUS(AE_AML_NOT_OWNER);
        }
 
@@ -391,10 +402,14 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc,
        }
 
        /*
-        * The sync level of the mutex must be less than or equal to the current
-        * sync level
+        * The sync level of the mutex must be equal to the current sync level. In
+        * other words, the current level means that at least one mutex at that
+        * level is currently being held. Attempting to release a mutex of a
+        * different level can only mean that the mutex ordering rule is being
+        * violated. This behavior is clarified in ACPI 4.0 specification.
         */
-       if (obj_desc->mutex.sync_level > walk_state->thread->current_sync_level) {
+       if (obj_desc->mutex.sync_level !=
+           walk_state->thread->current_sync_level) {
                ACPI_ERROR((AE_INFO,
                            "Cannot release Mutex [%4.4s], SyncLevel mismatch: mutex %d current %d",
                            acpi_ut_get_node_name(obj_desc->mutex.node),
@@ -403,14 +418,24 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc,
                return_ACPI_STATUS(AE_AML_MUTEX_ORDER);
        }
 
+       /*
+        * Get the previous sync_level from the head of the acquired mutex list.
+        * This handles the case where several mutexes at the same level have been
+        * acquired, but are not released in reverse order.
+        */
+       previous_sync_level =
+           walk_state->thread->acquired_mutex_list->mutex.original_sync_level;
+
        status = acpi_ex_release_mutex_object(obj_desc);
+       if (ACPI_FAILURE(status)) {
+               return_ACPI_STATUS(status);
+       }
 
        if (obj_desc->mutex.acquisition_depth == 0) {
 
-               /* Restore the original sync_level */
+               /* Restore the previous sync_level */
 
-               walk_state->thread->current_sync_level =
-                   obj_desc->mutex.original_sync_level;
+               walk_state->thread->current_sync_level = previous_sync_level;
        }
        return_ACPI_STATUS(status);
 }
index 90d606196c99595f871f249c33d931442e7610f0..6efd07a4f779c5975b864eb81989f60a9f84019f 100644 (file)
@@ -193,10 +193,12 @@ acpi_ex_do_debug_object(union acpi_operand_object *source_desc,
 
                case ACPI_REFCLASS_TABLE:
 
+                       /* Case for ddb_handle */
+
                        ACPI_DEBUG_PRINT_RAW((ACPI_DB_DEBUG_OBJECT,
                                              "Table Index 0x%X\n",
                                              source_desc->reference.value));
-                       break;
+                       return;
 
                default:
                        break;
index 7b2fb602b5cbf59a441a98950078e34a6d7f862b..23d5505cb1f779cf551730065e36e84580852975 100644 (file)
@@ -81,9 +81,9 @@ acpi_status acpi_hw_clear_acpi_status(void)
 
        ACPI_FUNCTION_TRACE(hw_clear_acpi_status);
 
-       ACPI_DEBUG_PRINT((ACPI_DB_IO, "About to write %04X to %0llX\n",
+       ACPI_DEBUG_PRINT((ACPI_DB_IO, "About to write %04X to %8.8X%8.8X\n",
                          ACPI_BITMASK_ALL_FIXED_STATUS,
-                         acpi_gbl_xpm1a_status.address));
+                         ACPI_FORMAT_UINT64(acpi_gbl_xpm1a_status.address)));
 
        lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock);
 
index aceb93111967f35a7f0a335c4bcb2798c4d56304..efc971ab7d6512dbc47607bd25d6d976f28ddff6 100644 (file)
@@ -334,9 +334,7 @@ void acpi_ns_delete_namespace_subtree(struct acpi_namespace_node *parent_node)
 
                /* Get the next node in this scope (NULL if none) */
 
-               child_node =
-                   acpi_ns_get_next_node(ACPI_TYPE_ANY, parent_node,
-                                         child_node);
+               child_node = acpi_ns_get_next_node(parent_node, child_node);
                if (child_node) {
 
                        /* Found a child node - detach any attached object */
@@ -345,8 +343,7 @@ void acpi_ns_delete_namespace_subtree(struct acpi_namespace_node *parent_node)
 
                        /* Check if this node has any children */
 
-                       if (acpi_ns_get_next_node
-                           (ACPI_TYPE_ANY, child_node, NULL)) {
+                       if (child_node->child) {
                                /*
                                 * There is at least one child of this node,
                                 * visit the node
@@ -432,9 +429,7 @@ void acpi_ns_delete_namespace_by_owner(acpi_owner_id owner_id)
                 * Get the next child of this parent node. When child_node is NULL,
                 * the first child of the parent is returned
                 */
-               child_node =
-                   acpi_ns_get_next_node(ACPI_TYPE_ANY, parent_node,
-                                         child_node);
+               child_node = acpi_ns_get_next_node(parent_node, child_node);
 
                if (deletion_node) {
                        acpi_ns_delete_children(deletion_node);
@@ -452,8 +447,7 @@ void acpi_ns_delete_namespace_by_owner(acpi_owner_id owner_id)
 
                        /* Check if this node has any children */
 
-                       if (acpi_ns_get_next_node
-                           (ACPI_TYPE_ANY, child_node, NULL)) {
+                       if (child_node->child) {
                                /*
                                 * There is at least one child of this node,
                                 * visit the node
index ae3dc10a7e817c4c9f11d7c5d6549e7cff2e0f61..af8e6bcee07e5544112299df765c540a7b4c0602 100644 (file)
@@ -149,7 +149,7 @@ char *acpi_ns_get_external_pathname(struct acpi_namespace_node *node)
 
        name_buffer = ACPI_ALLOCATE_ZEROED(size);
        if (!name_buffer) {
-               ACPI_ERROR((AE_INFO, "Allocation failure"));
+               ACPI_ERROR((AE_INFO, "Could not allocate %u bytes", (u32)size));
                return_PTR(NULL);
        }
 
index 3eb20bfda9d81a079c606d2e91ac85aa5dd8a859..60f3af08d28c3955fdee04607e99ce95befda017 100644 (file)
@@ -213,6 +213,15 @@ void acpi_ns_detach_object(struct acpi_namespace_node *node)
                return_VOID;
        }
 
+       if (node->flags & ANOBJ_ALLOCATED_BUFFER) {
+
+               /* Free the dynamic aml buffer */
+
+               if (obj_desc->common.type == ACPI_TYPE_METHOD) {
+                       ACPI_FREE(obj_desc->method.aml_start);
+               }
+       }
+
        /* Clear the entry in all cases */
 
        node->object = NULL;
index d9e8cbc6e679732d9a362d71f604a51d1683d223..7f8e066b12a3d20b79a986a7e771d65eef3a332c 100644 (file)
@@ -144,7 +144,7 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node,
 
        pathname = acpi_ns_get_external_pathname(node);
        if (!pathname) {
-               pathname = ACPI_CAST_PTR(char, predefined->info.name);
+               return AE_OK;   /* Could not get pathname, ignore */
        }
 
        /*
@@ -230,10 +230,7 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node,
        }
 
       exit:
-       if (pathname != predefined->info.name) {
-               ACPI_FREE(pathname);
-       }
-
+       ACPI_FREE(pathname);
        return (status);
 }
 
index f9b4f51bf8f2445fb7a48879b9d7298874a776ee..7e865639a928746abb4d94039dc771d8d40245fa 100644 (file)
 #include "accommon.h"
 #include "acnamesp.h"
 
+#ifdef ACPI_ASL_COMPILER
+#include "amlcode.h"
+#endif
+
 #define _COMPONENT          ACPI_NAMESPACE
 ACPI_MODULE_NAME("nssearch")
 
index 83e3aa6d4b9b65ddcec28881939908007ae39698..35539df5c75dc965800e555bd1432d8ef11c9767 100644 (file)
@@ -52,8 +52,7 @@ ACPI_MODULE_NAME("nswalk")
  *
  * FUNCTION:    acpi_ns_get_next_node
  *
- * PARAMETERS:  Type                - Type of node to be searched for
- *              parent_node         - Parent node whose children we are
+ * PARAMETERS:  parent_node         - Parent node whose children we are
  *                                    getting
  *              child_node          - Previous child that was found.
  *                                    The NEXT child will be returned
@@ -66,27 +65,68 @@ ACPI_MODULE_NAME("nswalk")
  *              within Scope is returned.
  *
  ******************************************************************************/
-struct acpi_namespace_node *acpi_ns_get_next_node(acpi_object_type type, struct acpi_namespace_node
-                                                 *parent_node, struct acpi_namespace_node
+struct acpi_namespace_node *acpi_ns_get_next_node(struct acpi_namespace_node
+                                                 *parent_node,
+                                                 struct acpi_namespace_node
                                                  *child_node)
 {
-       struct acpi_namespace_node *next_node = NULL;
-
        ACPI_FUNCTION_ENTRY();
 
        if (!child_node) {
 
                /* It's really the parent's _scope_ that we want */
 
-               next_node = parent_node->child;
+               return parent_node->child;
        }
 
-       else {
-               /* Start search at the NEXT node */
-
-               next_node = acpi_ns_get_next_valid_node(child_node);
+       /*
+        * Get the next node.
+        *
+        * If we are at the end of this peer list, return NULL
+        */
+       if (child_node->flags & ANOBJ_END_OF_PEER_LIST) {
+               return NULL;
        }
 
+       /* Otherwise just return the next peer */
+
+       return child_node->peer;
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ns_get_next_node_typed
+ *
+ * PARAMETERS:  Type                - Type of node to be searched for
+ *              parent_node         - Parent node whose children we are
+ *                                    getting
+ *              child_node          - Previous child that was found.
+ *                                    The NEXT child will be returned
+ *
+ * RETURN:      struct acpi_namespace_node - Pointer to the NEXT child or NULL if
+ *                                    none is found.
+ *
+ * DESCRIPTION: Return the next peer node within the namespace.  If Handle
+ *              is valid, Scope is ignored.  Otherwise, the first node
+ *              within Scope is returned.
+ *
+ ******************************************************************************/
+
+struct acpi_namespace_node *acpi_ns_get_next_node_typed(acpi_object_type type,
+                                                       struct
+                                                       acpi_namespace_node
+                                                       *parent_node,
+                                                       struct
+                                                       acpi_namespace_node
+                                                       *child_node)
+{
+       struct acpi_namespace_node *next_node = NULL;
+
+       ACPI_FUNCTION_ENTRY();
+
+       next_node = acpi_ns_get_next_node(parent_node, child_node);
+
+
        /* If any type is OK, we are done */
 
        if (type == ACPI_TYPE_ANY) {
@@ -186,9 +226,7 @@ acpi_ns_walk_namespace(acpi_object_type type,
                /* Get the next node in this scope.  Null if not found */
 
                status = AE_OK;
-               child_node =
-                   acpi_ns_get_next_node(ACPI_TYPE_ANY, parent_node,
-                                         child_node);
+               child_node = acpi_ns_get_next_node(parent_node, child_node);
                if (child_node) {
 
                        /* Found next child, get the type if we are not searching for ANY */
@@ -269,8 +307,7 @@ acpi_ns_walk_namespace(acpi_object_type type,
                         * function has specified that the maximum depth has been reached.
                         */
                        if ((level < max_depth) && (status != AE_CTRL_DEPTH)) {
-                               if (acpi_ns_get_next_node
-                                   (ACPI_TYPE_ANY, child_node, NULL)) {
+                               if (child_node->child) {
 
                                        /* There is at least one child of this node, visit it */
 
index 9589fea2499790bc4fc989baeb3700d49137390e..f23593d6add4857f146527e29b130fed13c47ff9 100644 (file)
@@ -45,6 +45,8 @@
 #include <acpi/acpi.h>
 #include "accommon.h"
 #include "acnamesp.h"
+#include "acparser.h"
+#include "amlcode.h"
 
 #define _COMPONENT          ACPI_NAMESPACE
 ACPI_MODULE_NAME("nsxfname")
@@ -358,3 +360,151 @@ acpi_get_object_info(acpi_handle handle, struct acpi_buffer * buffer)
 }
 
 ACPI_EXPORT_SYMBOL(acpi_get_object_info)
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_install_method
+ *
+ * PARAMETERS:  Buffer         - An ACPI table containing one control method
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Install a control method into the namespace. If the method
+ *              name already exists in the namespace, it is overwritten. The
+ *              input buffer must contain a valid DSDT or SSDT containing a
+ *              single control method.
+ *
+ ******************************************************************************/
+acpi_status acpi_install_method(u8 *buffer)
+{
+       struct acpi_table_header *table =
+           ACPI_CAST_PTR(struct acpi_table_header, buffer);
+       u8 *aml_buffer;
+       u8 *aml_start;
+       char *path;
+       struct acpi_namespace_node *node;
+       union acpi_operand_object *method_obj;
+       struct acpi_parse_state parser_state;
+       u32 aml_length;
+       u16 opcode;
+       u8 method_flags;
+       acpi_status status;
+
+       /* Parameter validation */
+
+       if (!buffer) {
+               return AE_BAD_PARAMETER;
+       }
+
+       /* Table must be a DSDT or SSDT */
+
+       if (!ACPI_COMPARE_NAME(table->signature, ACPI_SIG_DSDT) &&
+           !ACPI_COMPARE_NAME(table->signature, ACPI_SIG_SSDT)) {
+               return AE_BAD_HEADER;
+       }
+
+       /* First AML opcode in the table must be a control method */
+
+       parser_state.aml = buffer + sizeof(struct acpi_table_header);
+       opcode = acpi_ps_peek_opcode(&parser_state);
+       if (opcode != AML_METHOD_OP) {
+               return AE_BAD_PARAMETER;
+       }
+
+       /* Extract method information from the raw AML */
+
+       parser_state.aml += acpi_ps_get_opcode_size(opcode);
+       parser_state.pkg_end = acpi_ps_get_next_package_end(&parser_state);
+       path = acpi_ps_get_next_namestring(&parser_state);
+       method_flags = *parser_state.aml++;
+       aml_start = parser_state.aml;
+       aml_length = ACPI_PTR_DIFF(parser_state.pkg_end, aml_start);
+
+       /*
+        * Allocate resources up-front. We don't want to have to delete a new
+        * node from the namespace if we cannot allocate memory.
+        */
+       aml_buffer = ACPI_ALLOCATE(aml_length);
+       if (!aml_buffer) {
+               return AE_NO_MEMORY;
+       }
+
+       method_obj = acpi_ut_create_internal_object(ACPI_TYPE_METHOD);
+       if (!method_obj) {
+               ACPI_FREE(aml_buffer);
+               return AE_NO_MEMORY;
+       }
+
+       /* Lock namespace for acpi_ns_lookup, we may be creating a new node */
+
+       status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+       if (ACPI_FAILURE(status)) {
+               goto error_exit;
+       }
+
+       /* The lookup either returns an existing node or creates a new one */
+
+       status =
+           acpi_ns_lookup(NULL, path, ACPI_TYPE_METHOD, ACPI_IMODE_LOAD_PASS1,
+                          ACPI_NS_DONT_OPEN_SCOPE | ACPI_NS_ERROR_IF_FOUND,
+                          NULL, &node);
+
+       (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
+
+       if (ACPI_FAILURE(status)) {     /* ns_lookup */
+               if (status != AE_ALREADY_EXISTS) {
+                       goto error_exit;
+               }
+
+               /* Node existed previously, make sure it is a method node */
+
+               if (node->type != ACPI_TYPE_METHOD) {
+                       status = AE_TYPE;
+                       goto error_exit;
+               }
+       }
+
+       /* Copy the method AML to the local buffer */
+
+       ACPI_MEMCPY(aml_buffer, aml_start, aml_length);
+
+       /* Initialize the method object with the new method's information */
+
+       method_obj->method.aml_start = aml_buffer;
+       method_obj->method.aml_length = aml_length;
+
+       method_obj->method.param_count = (u8)
+           (method_flags & AML_METHOD_ARG_COUNT);
+
+       method_obj->method.method_flags = (u8)
+           (method_flags & ~AML_METHOD_ARG_COUNT);
+
+       if (method_flags & AML_METHOD_SERIALIZED) {
+               method_obj->method.sync_level = (u8)
+                   ((method_flags & AML_METHOD_SYNC_LEVEL) >> 4);
+       }
+
+       /*
+        * Now that it is complete, we can attach the new method object to
+        * the method Node (detaches/deletes any existing object)
+        */
+       status = acpi_ns_attach_object(node, method_obj, ACPI_TYPE_METHOD);
+
+       /*
+        * Flag indicates AML buffer is dynamic, must be deleted later.
+        * Must be set only after attach above.
+        */
+       node->flags |= ANOBJ_ALLOCATED_BUFFER;
+
+       /* Remove local reference to the method object */
+
+       acpi_ut_remove_reference(method_obj);
+       return status;
+
+error_exit:
+
+       ACPI_FREE(aml_buffer);
+       ACPI_FREE(method_obj);
+       return status;
+}
+ACPI_EXPORT_SYMBOL(acpi_install_method)
index 1c7efc15225f6a63dcf4fc5e8ff763bbe8f7e327..4071bad4458ed7d229bc04e30cb02abcb8efe26b 100644 (file)
@@ -162,6 +162,7 @@ ACPI_EXPORT_SYMBOL(acpi_get_type)
 acpi_status acpi_get_parent(acpi_handle handle, acpi_handle * ret_handle)
 {
        struct acpi_namespace_node *node;
+       struct acpi_namespace_node *parent_node;
        acpi_status status;
 
        if (!ret_handle) {
@@ -189,12 +190,12 @@ acpi_status acpi_get_parent(acpi_handle handle, acpi_handle * ret_handle)
 
        /* Get the parent entry */
 
-       *ret_handle =
-           acpi_ns_convert_entry_to_handle(acpi_ns_get_parent_node(node));
+       parent_node = acpi_ns_get_parent_node(node);
+       *ret_handle = acpi_ns_convert_entry_to_handle(parent_node);
 
        /* Return exception if parent is null */
 
-       if (!acpi_ns_get_parent_node(node)) {
+       if (!parent_node) {
                status = AE_NULL_ENTRY;
        }
 
@@ -268,7 +269,7 @@ acpi_get_next_object(acpi_object_type type,
 
        /* Internal function does the real work */
 
-       node = acpi_ns_get_next_node(type, parent_node, child_node);
+       node = acpi_ns_get_next_node_typed(type, parent_node, child_node);
        if (!node) {
                status = AE_NOT_FOUND;
                goto unlock_and_exit;
index 88b5a2c4814d0423f60a02e1c994d5cb6c9e9775..3c4dcc3d1069097f4255b92d5b2eaa68119b8424 100644 (file)
@@ -547,7 +547,7 @@ acpi_rs_get_pci_routing_table_length(union acpi_operand_object *package_object,
 
                if (!package_element ||
                    (package_element->common.type != ACPI_TYPE_PACKAGE)) {
-                       return_ACPI_STATUS (AE_AML_OPERAND_TYPE);
+                       return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
                }
 
                /*
@@ -593,9 +593,6 @@ acpi_rs_get_pci_routing_table_length(union acpi_operand_object *package_object,
                        } else {
                                temp_size_needed +=
                                    acpi_ns_get_pathname_length((*sub_object_list)->reference.node);
-                               if (!temp_size_needed) {
-                                       return_ACPI_STATUS(AE_BAD_PARAMETER);
-                               }
                        }
                } else {
                        /*
index 69a2aa5b5d831ae83ac0ba901732a121f918ad16..395212bcd19b470d756efa5328dfc9d21464c603 100644 (file)
@@ -338,13 +338,17 @@ acpi_resource_to_address64(struct acpi_resource *resource,
        switch (resource->type) {
        case ACPI_RESOURCE_TYPE_ADDRESS16:
 
-               address16 = (struct acpi_resource_address16 *)&resource->data;
+               address16 =
+                   ACPI_CAST_PTR(struct acpi_resource_address16,
+                                 &resource->data);
                ACPI_COPY_ADDRESS(out, address16);
                break;
 
        case ACPI_RESOURCE_TYPE_ADDRESS32:
 
-               address32 = (struct acpi_resource_address32 *)&resource->data;
+               address32 =
+                   ACPI_CAST_PTR(struct acpi_resource_address32,
+                                 &resource->data);
                ACPI_COPY_ADDRESS(out, address32);
                break;
 
index 71e655d14cb0759a71fff3da12188f6c8a0f0679..82b02dcb942e75f9cfe3871464da16dc839cfc6e 100644 (file)
@@ -284,9 +284,9 @@ void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length)
        if (length > sizeof(struct acpi_table_fadt)) {
                ACPI_WARNING((AE_INFO,
                              "FADT (revision %u) is longer than ACPI 2.0 version, "
-                             "truncating length 0x%X to 0x%zX",
-                             table->revision, (unsigned)length,
-                             sizeof(struct acpi_table_fadt)));
+                             "truncating length 0x%X to 0x%X",
+                             table->revision, length,
+                             (u32)sizeof(struct acpi_table_fadt)));
        }
 
        /* Clear the entire local FADT */
@@ -441,7 +441,7 @@ static void acpi_tb_convert_fadt(void)
                                                                   &acpi_gbl_FADT,
                                                                   fadt_info_table
                                                                   [i].length),
-                                                    address32);
+                                                    (u64) address32);
                }
        }
 }
@@ -469,7 +469,6 @@ static void acpi_tb_convert_fadt(void)
 static void acpi_tb_validate_fadt(void)
 {
        char *name;
-       u32 *address32;
        struct acpi_generic_address *address64;
        u8 length;
        u32 i;
@@ -505,15 +504,12 @@ static void acpi_tb_validate_fadt(void)
 
        for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) {
                /*
-                * Generate pointers to the 32-bit and 64-bit addresses, get the
-                * register length (width), and the register name
+                * Generate pointer to the 64-bit address, get the register
+                * length (width) and the register name
                 */
                address64 = ACPI_ADD_PTR(struct acpi_generic_address,
                                         &acpi_gbl_FADT,
                                         fadt_info_table[i].address64);
-               address32 =
-                   ACPI_ADD_PTR(u32, &acpi_gbl_FADT,
-                                fadt_info_table[i].address32);
                length =
                    *ACPI_ADD_PTR(u8, &acpi_gbl_FADT,
                                  fadt_info_table[i].length);
index f865d5a096de28e2ab57bb2c9c5d295f7e354243..63e82329a9e858ca81e1169daf1bf0f4f40e0e14 100644 (file)
@@ -472,7 +472,7 @@ acpi_status acpi_tb_delete_namespace_by_owner(u32 table_index)
         * lock may block, and also since the execution of a namespace walk
         * must be allowed to use the interpreter.
         */
-       acpi_ut_release_mutex(ACPI_MTX_INTERPRETER);
+       (void)acpi_ut_release_mutex(ACPI_MTX_INTERPRETER);
        status = acpi_ut_acquire_write_lock(&acpi_gbl_namespace_rw_lock);
 
        acpi_ns_delete_namespace_by_owner(owner_id);
index 919624f123d5ab4e6cb65b8ec23702c0d6d538ab..0f0c64bf8ac98d1cae2da0bdb073405d5f08d9e5 100644 (file)
@@ -676,6 +676,7 @@ acpi_ut_copy_simple_object(union acpi_operand_object *source_desc,
 {
        u16 reference_count;
        union acpi_operand_object *next_object;
+       acpi_status status;
 
        /* Save fields from destination that we don't want to overwrite */
 
@@ -768,6 +769,28 @@ acpi_ut_copy_simple_object(union acpi_operand_object *source_desc,
                }
                break;
 
+               /*
+                * For Mutex and Event objects, we cannot simply copy the underlying
+                * OS object. We must create a new one.
+                */
+       case ACPI_TYPE_MUTEX:
+
+               status = acpi_os_create_mutex(&dest_desc->mutex.os_mutex);
+               if (ACPI_FAILURE(status)) {
+                       return status;
+               }
+               break;
+
+       case ACPI_TYPE_EVENT:
+
+               status = acpi_os_create_semaphore(ACPI_NO_UNIT_LIMIT, 0,
+                                                 &dest_desc->event.
+                                                 os_semaphore);
+               if (ACPI_FAILURE(status)) {
+                       return status;
+               }
+               break;
+
        default:
                /* Nothing to do for other simple objects */
                break;
index 38821f53042c34c215d6776ba6599434b3273f5f..527d729f681506d160c0e93611f60439c0dcb740 100644 (file)
@@ -179,9 +179,9 @@ acpi_debug_print(u32 requested_debug_level,
        if (thread_id != acpi_gbl_prev_thread_id) {
                if (ACPI_LV_THREADS & acpi_dbg_level) {
                        acpi_os_printf
-                           ("\n**** Context Switch from TID %lX to TID %lX ****\n\n",
-                            (unsigned long)acpi_gbl_prev_thread_id,
-                            (unsigned long)thread_id);
+                           ("\n**** Context Switch from TID %p to TID %p ****\n\n",
+                            ACPI_CAST_PTR(void, acpi_gbl_prev_thread_id),
+                            ACPI_CAST_PTR(void, thread_id));
                }
 
                acpi_gbl_prev_thread_id = thread_id;
@@ -194,7 +194,7 @@ acpi_debug_print(u32 requested_debug_level,
        acpi_os_printf("%8s-%04ld ", module_name, line_number);
 
        if (ACPI_LV_THREADS & acpi_dbg_level) {
-               acpi_os_printf("[%04lX] ", (unsigned long)thread_id);
+               acpi_os_printf("[%p] ", ACPI_CAST_PTR(void, thread_id));
        }
 
        acpi_os_printf("[%02ld] %-22.22s: ",
index a5ee23bc4f5563bcece4fe2a628016cf7a8c4208..bc1710315088a7304cfaa86bc9237f7ca0afd75f 100644 (file)
@@ -75,6 +75,7 @@ static void acpi_ut_delete_internal_obj(union acpi_operand_object *object)
        union acpi_operand_object *handler_desc;
        union acpi_operand_object *second_desc;
        union acpi_operand_object *next_desc;
+       union acpi_operand_object **last_obj_ptr;
 
        ACPI_FUNCTION_TRACE_PTR(ut_delete_internal_obj, object);
 
@@ -223,6 +224,26 @@ static void acpi_ut_delete_internal_obj(union acpi_operand_object *object)
                         */
                        handler_desc = object->region.handler;
                        if (handler_desc) {
+                               next_desc =
+                                   handler_desc->address_space.region_list;
+                               last_obj_ptr =
+                                   &handler_desc->address_space.region_list;
+
+                               /* Remove the region object from the handler's list */
+
+                               while (next_desc) {
+                                       if (next_desc == object) {
+                                               *last_obj_ptr =
+                                                   next_desc->region.next;
+                                               break;
+                                       }
+
+                                       /* Walk the linked list of handler */
+
+                                       last_obj_ptr = &next_desc->region.next;
+                                       next_desc = next_desc->region.next;
+                               }
+
                                if (handler_desc->address_space.handler_flags &
                                    ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) {
 
index 1c9e250caefb0c0eb57809c543514b227bf89557..fbe782348b0bcf0111971398ac0dc752b2f6e92d 100644 (file)
@@ -1033,11 +1033,12 @@ acpi_error(const char *module_name, u32 line_number, const char *format, ...)
 {
        va_list args;
 
-       acpi_os_printf("ACPI Error (%s-%04d): ", module_name, line_number);
+       acpi_os_printf("ACPI Error: ");
 
        va_start(args, format);
        acpi_os_vprintf(format, args);
-       acpi_os_printf(" [%X]\n", ACPI_CA_VERSION);
+       acpi_os_printf(" %8.8X %s-%u\n", ACPI_CA_VERSION, module_name,
+                      line_number);
        va_end(args);
 }
 
@@ -1047,12 +1048,12 @@ acpi_exception(const char *module_name,
 {
        va_list args;
 
-       acpi_os_printf("ACPI Exception (%s-%04d): %s, ", module_name,
-                      line_number, acpi_format_exception(status));
+       acpi_os_printf("ACPI Exception: %s, ", acpi_format_exception(status));
 
        va_start(args, format);
        acpi_os_vprintf(format, args);
-       acpi_os_printf(" [%X]\n", ACPI_CA_VERSION);
+       acpi_os_printf(" %8.8X %s-%u\n", ACPI_CA_VERSION, module_name,
+                      line_number);
        va_end(args);
 }
 
@@ -1061,11 +1062,12 @@ acpi_warning(const char *module_name, u32 line_number, const char *format, ...)
 {
        va_list args;
 
-       acpi_os_printf("ACPI Warning (%s-%04d): ", module_name, line_number);
+       acpi_os_printf("ACPI Warning: ");
 
        va_start(args, format);
        acpi_os_vprintf(format, args);
-       acpi_os_printf(" [%X]\n", ACPI_CA_VERSION);
+       acpi_os_printf(" %8.8X %s-%u\n", ACPI_CA_VERSION, module_name,
+                      line_number);
        va_end(args);
 }
 
@@ -1074,10 +1076,6 @@ acpi_info(const char *module_name, u32 line_number, const char *format, ...)
 {
        va_list args;
 
-       /*
-        * Removed module_name, line_number, and acpica version, not needed
-        * for info output
-        */
        acpi_os_printf("ACPI: ");
 
        va_start(args, format);
index 26c93a748e64b10795e61eaf61991a980ceabc2f..80bb6515411791898cacbee2c3c71c92bcc85180 100644 (file)
@@ -230,17 +230,18 @@ acpi_status acpi_ut_acquire_mutex(acpi_mutex_handle mutex_id)
                        if (acpi_gbl_mutex_info[i].thread_id == this_thread_id) {
                                if (i == mutex_id) {
                                        ACPI_ERROR((AE_INFO,
-                                                   "Mutex [%s] already acquired by this thread [%X]",
+                                                   "Mutex [%s] already acquired by this thread [%p]",
                                                    acpi_ut_get_mutex_name
                                                    (mutex_id),
-                                                   this_thread_id));
+                                                   ACPI_CAST_PTR(void,
+                                                                 this_thread_id)));
 
                                        return (AE_ALREADY_ACQUIRED);
                                }
 
                                ACPI_ERROR((AE_INFO,
-                                           "Invalid acquire order: Thread %X owns [%s], wants [%s]",
-                                           this_thread_id,
+                                           "Invalid acquire order: Thread %p owns [%s], wants [%s]",
+                                           ACPI_CAST_PTR(void, this_thread_id),
                                            acpi_ut_get_mutex_name(i),
                                            acpi_ut_get_mutex_name(mutex_id)));
 
@@ -251,24 +252,24 @@ acpi_status acpi_ut_acquire_mutex(acpi_mutex_handle mutex_id)
 #endif
 
        ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
-                         "Thread %lX attempting to acquire Mutex [%s]\n",
-                         (unsigned long)this_thread_id,
+                         "Thread %p attempting to acquire Mutex [%s]\n",
+                         ACPI_CAST_PTR(void, this_thread_id),
                          acpi_ut_get_mutex_name(mutex_id)));
 
        status = acpi_os_acquire_mutex(acpi_gbl_mutex_info[mutex_id].mutex,
                                       ACPI_WAIT_FOREVER);
        if (ACPI_SUCCESS(status)) {
                ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
-                                 "Thread %lX acquired Mutex [%s]\n",
-                                 (unsigned long)this_thread_id,
+                                 "Thread %p acquired Mutex [%s]\n",
+                                 ACPI_CAST_PTR(void, this_thread_id),
                                  acpi_ut_get_mutex_name(mutex_id)));
 
                acpi_gbl_mutex_info[mutex_id].use_count++;
                acpi_gbl_mutex_info[mutex_id].thread_id = this_thread_id;
        } else {
                ACPI_EXCEPTION((AE_INFO, status,
-                               "Thread %lX could not acquire Mutex [%X]",
-                               (unsigned long)this_thread_id, mutex_id));
+                               "Thread %p could not acquire Mutex [%X]",
+                               ACPI_CAST_PTR(void, this_thread_id), mutex_id));
        }
 
        return (status);
@@ -293,9 +294,8 @@ acpi_status acpi_ut_release_mutex(acpi_mutex_handle mutex_id)
        ACPI_FUNCTION_NAME(ut_release_mutex);
 
        this_thread_id = acpi_os_get_thread_id();
-       ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
-                         "Thread %lX releasing Mutex [%s]\n",
-                         (unsigned long)this_thread_id,
+       ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Thread %p releasing Mutex [%s]\n",
+                         ACPI_CAST_PTR(void, this_thread_id),
                          acpi_ut_get_mutex_name(mutex_id)));
 
        if (mutex_id > ACPI_MAX_MUTEX) {
index 31693bc24444f3541c74dfccc9c9c384edf8fd5a..965ece2c7e4da6040454443395adb89240eaa475 100644 (file)
@@ -34,13 +34,6 @@ new_skb(ulong len)
                skb_reset_mac_header(skb);
                skb_reset_network_header(skb);
                skb->protocol = __constant_htons(ETH_P_AOE);
-               skb->priority = 0;
-               skb->next = skb->prev = NULL;
-
-               /* tell the network layer not to perform IP checksums
-                * or to get the NIC to do it
-                */
-               skb->ip_summed = CHECKSUM_NONE;
        }
        return skb;
 }
index 901bdd95655f3e8065ff3e4715f9acc63713fc66..2cc7b3266eaf6bd423d2f7af2cab55ef9b4bd31e 100644 (file)
@@ -415,6 +415,8 @@ static int dtl1_hci_send_frame(struct sk_buff *skb)
                hdev->stat.sco_tx++;
                nsh.type = 0x83;
                break;
+       default:
+               return -EILSEQ;
        };
 
        nsh.zero = 0;
index 0bbefba6469cee659e7b114e961a677e3fa65fa0..1df9dda2e377d8415366ae43fb1c44e57e2ed9d2 100644 (file)
@@ -40,7 +40,7 @@
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/hci_core.h>
 
-#define VERSION "1.2"
+#define VERSION "1.3"
 
 static int minor = MISC_DYNAMIC_MINOR;
 
@@ -51,14 +51,8 @@ struct vhci_data {
 
        wait_queue_head_t read_wait;
        struct sk_buff_head readq;
-
-       struct fasync_struct *fasync;
 };
 
-#define VHCI_FASYNC    0x0010
-
-static struct miscdevice vhci_miscdev;
-
 static int vhci_open_dev(struct hci_dev *hdev)
 {
        set_bit(HCI_RUNNING, &hdev->flags);
@@ -105,9 +99,6 @@ static int vhci_send_frame(struct sk_buff *skb)
        memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
        skb_queue_tail(&data->readq, skb);
 
-       if (data->flags & VHCI_FASYNC)
-               kill_fasync(&data->fasync, SIGIO, POLL_IN);
-
        wake_up_interruptible(&data->read_wait);
 
        return 0;
@@ -179,41 +170,31 @@ static inline ssize_t vhci_put_user(struct vhci_data *data,
 static ssize_t vhci_read(struct file *file,
                                char __user *buf, size_t count, loff_t *pos)
 {
-       DECLARE_WAITQUEUE(wait, current);
        struct vhci_data *data = file->private_data;
        struct sk_buff *skb;
        ssize_t ret = 0;
 
-       add_wait_queue(&data->read_wait, &wait);
        while (count) {
-               set_current_state(TASK_INTERRUPTIBLE);
-
                skb = skb_dequeue(&data->readq);
-               if (!skb) {
-                       if (file->f_flags & O_NONBLOCK) {
-                               ret = -EAGAIN;
-                               break;
-                       }
-
-                       if (signal_pending(current)) {
-                               ret = -ERESTARTSYS;
-                               break;
-                       }
-
-                       schedule();
-                       continue;
+               if (skb) {
+                       ret = vhci_put_user(data, skb, buf, count);
+                       if (ret < 0)
+                               skb_queue_head(&data->readq, skb);
+                       else
+                               kfree_skb(skb);
+                       break;
                }
 
-               if (access_ok(VERIFY_WRITE, buf, count))
-                       ret = vhci_put_user(data, skb, buf, count);
-               else
-                       ret = -EFAULT;
+               if (file->f_flags & O_NONBLOCK) {
+                       ret = -EAGAIN;
+                       break;
+               }
 
-               kfree_skb(skb);
-               break;
+               ret = wait_event_interruptible(data->read_wait,
+                                       !skb_queue_empty(&data->readq));
+               if (ret < 0)
+                       break;
        }
-       set_current_state(TASK_RUNNING);
-       remove_wait_queue(&data->read_wait, &wait);
 
        return ret;
 }
@@ -223,9 +204,6 @@ static ssize_t vhci_write(struct file *file,
 {
        struct vhci_data *data = file->private_data;
 
-       if (!access_ok(VERIFY_READ, buf, count))
-               return -EFAULT;
-
        return vhci_get_user(data, buf, count);
 }
 
@@ -259,11 +237,9 @@ static int vhci_open(struct inode *inode, struct file *file)
        skb_queue_head_init(&data->readq);
        init_waitqueue_head(&data->read_wait);
 
-       lock_kernel();
        hdev = hci_alloc_dev();
        if (!hdev) {
                kfree(data);
-               unlock_kernel();
                return -ENOMEM;
        }
 
@@ -284,12 +260,10 @@ static int vhci_open(struct inode *inode, struct file *file)
                BT_ERR("Can't register HCI device");
                kfree(data);
                hci_free_dev(hdev);
-               unlock_kernel();
                return -EBUSY;
        }
 
        file->private_data = data;
-       unlock_kernel();
 
        return nonseekable_open(inode, file);
 }
@@ -310,48 +284,25 @@ static int vhci_release(struct inode *inode, struct file *file)
        return 0;
 }
 
-static int vhci_fasync(int fd, struct file *file, int on)
-{
-       struct vhci_data *data = file->private_data;
-       int err = 0;
-
-       lock_kernel();
-       err = fasync_helper(fd, file, on, &data->fasync);
-       if (err < 0)
-               goto out;
-
-       if (on)
-               data->flags |= VHCI_FASYNC;
-       else
-               data->flags &= ~VHCI_FASYNC;
-
-out:
-       unlock_kernel();
-       return err;
-}
-
 static const struct file_operations vhci_fops = {
-       .owner          = THIS_MODULE,
        .read           = vhci_read,
        .write          = vhci_write,
        .poll           = vhci_poll,
        .ioctl          = vhci_ioctl,
        .open           = vhci_open,
        .release        = vhci_release,
-       .fasync         = vhci_fasync,
 };
 
 static struct miscdevice vhci_miscdev= {
-       .name           = "vhci",
-       .fops           = &vhci_fops,
+       .name   = "vhci",
+       .fops   = &vhci_fops,
+       .minor  = MISC_DYNAMIC_MINOR,
 };
 
 static int __init vhci_init(void)
 {
        BT_INFO("Virtual HCI driver ver %s", VERSION);
 
-       vhci_miscdev.minor = minor;
-
        if (misc_register(&vhci_miscdev) < 0) {
                BT_ERR("Can't register misc device with minor %d", minor);
                return -EIO;
@@ -369,9 +320,6 @@ static void __exit vhci_exit(void)
 module_init(vhci_init);
 module_exit(vhci_exit);
 
-module_param(minor, int, 0444);
-MODULE_PARM_DESC(minor, "Miscellaneous minor device number");
-
 MODULE_AUTHOR("Marcel Holtmann <marcel@holtmann.org>");
 MODULE_DESCRIPTION("Bluetooth virtual HCI driver ver " VERSION);
 MODULE_VERSION(VERSION);
index 5acd29e6e0430ee6bc16f3b4757a4fc76eb5cc06..3910ce112a95a47269b8dbe5154213ad2258bc90 100644 (file)
@@ -104,7 +104,7 @@ static int pty_write(struct tty_struct *tty, const unsigned char *buf,
        struct tty_struct *to = tty->link;
        int     c;
 
-       if (!to || tty->stopped)
+       if (!to || !to->ldisc || tty->stopped)
                return 0;
 
        c = to->receive_room;
@@ -148,7 +148,7 @@ static int pty_chars_in_buffer(struct tty_struct *tty)
        int count;
 
        /* We should get the line discipline lock for "tty->link" */
-       if (!to || !to->ldisc->ops->chars_in_buffer)
+       if (!to || !to->ldisc || !to->ldisc->ops->chars_in_buffer)
                return 0;
 
        /* The ldisc must report 0 if no characters available to be read */
@@ -183,7 +183,7 @@ static void pty_flush_buffer(struct tty_struct *tty)
        struct tty_struct *to = tty->link;
        unsigned long flags;
 
-       if (!to)
+       if (!to || !to->ldisc)
                return;
 
        if (to->ldisc->ops->flush_buffer)
index 39c8f86dedd49c9e60ebe1e4e218225416bf0375..94b3e06d73ec255316db59749e417ae2bee90ffe 100644 (file)
@@ -148,8 +148,10 @@ static struct tty_ldisc *tty_ldisc_try_get(int disc)
                }
        }
        spin_unlock_irqrestore(&tty_ldisc_lock, flags);
-       if (err)
+       if (err) {
+               kfree(ld);
                return ERR_PTR(err);
+       }
        return ld;
 }
 
@@ -262,7 +264,7 @@ const struct file_operations tty_ldiscs_proc_fops = {
  *     @ld: line discipline
  *
  *     Install an instance of a line discipline into a tty structure. The
- *     ldisc must have a reference count above zero to ensure it remains/
+ *     ldisc must have a reference count above zero to ensure it remains.
  *     The tty instance refcount starts at zero.
  *
  *     Locking:
index ffc9254f7e029d26c7cd0d0d38f75d7f32570e2c..042c8149a6d12248cdbbf2e212628cf497f8f1ea 100644 (file)
@@ -867,7 +867,7 @@ static int viotape_probe(struct vio_dev *vdev, const struct vio_device_id *id)
        int j;
        struct device_node *node = vdev->dev.archdata.of_node;
 
-       if (i > VIOTAPE_MAX_TAPE)
+       if (i >= VIOTAPE_MAX_TAPE)
                return -ENODEV;
        if (!node)
                return -ENODEV;
index 8b92a4666e02b12fdae1f4e2e86a1c7c7226f26d..e4476743f20330e4653e856ff42cee68b8952469 100644 (file)
@@ -756,12 +756,12 @@ static int __devinit iic_probe(struct of_device *ofdev,
                goto error_cleanup;
        }
 
-       /* Now register all the child nodes */
-       of_register_i2c_devices(adap, np);
-
        dev_info(&ofdev->dev, "using %s mode\n",
                 dev->fast_mode ? "fast (400 kHz)" : "standard (100 kHz)");
 
+       /* Now register all the child nodes */
+       of_register_i2c_devices(adap, np);
+
        return 0;
 
 error_cleanup:
diff --git a/drivers/ieee802154/Kconfig b/drivers/ieee802154/Kconfig
new file mode 100644 (file)
index 0000000..9b9f43a
--- /dev/null
@@ -0,0 +1,22 @@
+menuconfig IEEE802154_DRIVERS
+       tristate "IEEE 802.15.4 drivers"
+       depends on NETDEVICES && IEEE802154
+       default y
+       ---help---
+         Say Y here to get to see options for IEEE 802.15.4 Low-Rate
+         Wireless Personal Area Network device drivers. This option alone
+         does not add any kernel code.
+
+         If you say N, all options in this submenu will be skipped and
+         disabled.
+
+config IEEE802154_FAKEHARD
+       tristate "Fake LR-WPAN driver with several interconnected devices"
+       depends on  IEEE802154_DRIVERS
+       ---help---
+         Say Y here to enable the fake driver that serves as an example
+          of HardMAC device driver.
+
+          This driver can also be built as a module. To do so say M here.
+         The module will be called 'fakehard'.
+
diff --git a/drivers/ieee802154/Makefile b/drivers/ieee802154/Makefile
new file mode 100644 (file)
index 0000000..e0e8e1a
--- /dev/null
@@ -0,0 +1,3 @@
+obj-$(CONFIG_IEEE802154_FAKEHARD) += fakehard.o
+
+EXTRA_CFLAGS += -DDEBUG -DCONFIG_FFD
diff --git a/drivers/ieee802154/fakehard.c b/drivers/ieee802154/fakehard.c
new file mode 100644 (file)
index 0000000..0384144
--- /dev/null
@@ -0,0 +1,270 @@
+/*
+ * Sample driver for HardMAC IEEE 802.15.4 devices
+ *
+ * Copyright (C) 2009 Siemens AG
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Written by:
+ * Dmitry Eremin-Solenikov <dmitry.baryshkov@siemens.com>
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <linux/if_arp.h>
+
+#include <net/ieee802154/af_ieee802154.h>
+#include <net/ieee802154/netdevice.h>
+#include <net/ieee802154/mac_def.h>
+#include <net/ieee802154/nl802154.h>
+
+static u16 fake_get_pan_id(struct net_device *dev)
+{
+       BUG_ON(dev->type != ARPHRD_IEEE802154);
+
+       return 0xeba1;
+}
+
+static u16 fake_get_short_addr(struct net_device *dev)
+{
+       BUG_ON(dev->type != ARPHRD_IEEE802154);
+
+       return 0x1;
+}
+
+static u8 fake_get_dsn(struct net_device *dev)
+{
+       BUG_ON(dev->type != ARPHRD_IEEE802154);
+
+       return 0x00; /* DSN are implemented in HW, so return just 0 */
+}
+
+static u8 fake_get_bsn(struct net_device *dev)
+{
+       BUG_ON(dev->type != ARPHRD_IEEE802154);
+
+       return 0x00; /* BSN are implemented in HW, so return just 0 */
+}
+
+static int fake_assoc_req(struct net_device *dev,
+               struct ieee802154_addr *addr, u8 channel, u8 cap)
+{
+       /* We simply emulate it here */
+       return ieee802154_nl_assoc_confirm(dev, fake_get_short_addr(dev),
+                       IEEE802154_SUCCESS);
+}
+
+static int fake_assoc_resp(struct net_device *dev,
+               struct ieee802154_addr *addr, u16 short_addr, u8 status)
+{
+       return 0;
+}
+
+static int fake_disassoc_req(struct net_device *dev,
+               struct ieee802154_addr *addr, u8 reason)
+{
+       return ieee802154_nl_disassoc_confirm(dev, IEEE802154_SUCCESS);
+}
+
+static int fake_start_req(struct net_device *dev, struct ieee802154_addr *addr,
+                               u8 channel,
+                               u8 bcn_ord, u8 sf_ord, u8 pan_coord, u8 blx,
+                               u8 coord_realign)
+{
+       return 0;
+}
+
+static int fake_scan_req(struct net_device *dev, u8 type, u32 channels,
+               u8 duration)
+{
+       u8 edl[27] = {};
+       return ieee802154_nl_scan_confirm(dev, IEEE802154_SUCCESS, type,
+                       channels,
+                       type == IEEE802154_MAC_SCAN_ED ? edl : NULL);
+}
+
+static struct ieee802154_mlme_ops fake_mlme = {
+       .assoc_req = fake_assoc_req,
+       .assoc_resp = fake_assoc_resp,
+       .disassoc_req = fake_disassoc_req,
+       .start_req = fake_start_req,
+       .scan_req = fake_scan_req,
+
+       .get_pan_id = fake_get_pan_id,
+       .get_short_addr = fake_get_short_addr,
+       .get_dsn = fake_get_dsn,
+       .get_bsn = fake_get_bsn,
+};
+
+static int ieee802154_fake_open(struct net_device *dev)
+{
+       netif_start_queue(dev);
+       return 0;
+}
+
+static int ieee802154_fake_close(struct net_device *dev)
+{
+       netif_stop_queue(dev);
+       return 0;
+}
+
+static int ieee802154_fake_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+       skb->iif = dev->ifindex;
+       skb->dev = dev;
+       dev->stats.tx_packets++;
+       dev->stats.tx_bytes += skb->len;
+
+       dev->trans_start = jiffies;
+
+       /* FIXME: do hardware work here ... */
+
+       return 0;
+}
+
+
+static int ieee802154_fake_ioctl(struct net_device *dev, struct ifreq *ifr,
+               int cmd)
+{
+       struct sockaddr_ieee802154 *sa =
+               (struct sockaddr_ieee802154 *)&ifr->ifr_addr;
+       u16 pan_id, short_addr;
+
+       switch (cmd) {
+       case SIOCGIFADDR:
+               /* FIXME: fixed here, get from device IRL */
+               pan_id = fake_get_pan_id(dev);
+               short_addr = fake_get_short_addr(dev);
+               if (pan_id == IEEE802154_PANID_BROADCAST ||
+                   short_addr == IEEE802154_ADDR_BROADCAST)
+                       return -EADDRNOTAVAIL;
+
+               sa->family = AF_IEEE802154;
+               sa->addr.addr_type = IEEE802154_ADDR_SHORT;
+               sa->addr.pan_id = pan_id;
+               sa->addr.short_addr = short_addr;
+               return 0;
+       }
+       return -ENOIOCTLCMD;
+}
+
+static int ieee802154_fake_mac_addr(struct net_device *dev, void *p)
+{
+       return -EBUSY; /* HW address is built into the device */
+}
+
+static const struct net_device_ops fake_ops = {
+       .ndo_open               = ieee802154_fake_open,
+       .ndo_stop               = ieee802154_fake_close,
+       .ndo_start_xmit         = ieee802154_fake_xmit,
+       .ndo_do_ioctl           = ieee802154_fake_ioctl,
+       .ndo_set_mac_address    = ieee802154_fake_mac_addr,
+};
+
+
+static void ieee802154_fake_setup(struct net_device *dev)
+{
+       dev->addr_len           = IEEE802154_ADDR_LEN;
+       memset(dev->broadcast, 0xff, IEEE802154_ADDR_LEN);
+       dev->features           = NETIF_F_NO_CSUM;
+       dev->needed_tailroom    = 2; /* FCS */
+       dev->mtu                = 127;
+       dev->tx_queue_len       = 10;
+       dev->type               = ARPHRD_IEEE802154;
+       dev->flags              = IFF_NOARP | IFF_BROADCAST;
+       dev->watchdog_timeo     = 0;
+}
+
+
+static int __devinit ieee802154fake_probe(struct platform_device *pdev)
+{
+       struct net_device *dev =
+               alloc_netdev(0, "hardwpan%d", ieee802154_fake_setup);
+       int err;
+
+       if (!dev)
+               return -ENOMEM;
+
+       memcpy(dev->dev_addr, "\xba\xbe\xca\xfe\xde\xad\xbe\xef",
+                       dev->addr_len);
+       memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
+
+       dev->netdev_ops = &fake_ops;
+       dev->ml_priv = &fake_mlme;
+
+       /*
+        * If the name is a format string the caller wants us to do a
+        * name allocation.
+        */
+       if (strchr(dev->name, '%')) {
+               err = dev_alloc_name(dev, dev->name);
+               if (err < 0)
+                       goto out;
+       }
+
+       SET_NETDEV_DEV(dev, &pdev->dev);
+
+       platform_set_drvdata(pdev, dev);
+
+       err = register_netdev(dev);
+       if (err < 0)
+               goto out;
+
+
+       dev_info(&pdev->dev, "Added ieee802154 HardMAC hardware\n");
+       return 0;
+
+out:
+       unregister_netdev(dev);
+       return err;
+}
+
+static int __devexit ieee802154fake_remove(struct platform_device *pdev)
+{
+       struct net_device *dev = platform_get_drvdata(pdev);
+       unregister_netdev(dev);
+       free_netdev(dev);
+       return 0;
+}
+
+static struct platform_device *ieee802154fake_dev;
+
+static struct platform_driver ieee802154fake_driver = {
+       .probe = ieee802154fake_probe,
+       .remove = __devexit_p(ieee802154fake_remove),
+       .driver = {
+                       .name = "ieee802154hardmac",
+                       .owner = THIS_MODULE,
+       },
+};
+
+static __init int fake_init(void)
+{
+       ieee802154fake_dev = platform_device_register_simple(
+                       "ieee802154hardmac", -1, NULL, 0);
+       return platform_driver_register(&ieee802154fake_driver);
+}
+
+static __exit void fake_exit(void)
+{
+       platform_driver_unregister(&ieee802154fake_driver);
+       platform_device_unregister(ieee802154fake_dev);
+}
+
+module_init(fake_init);
+module_exit(fake_exit);
+MODULE_LICENSE("GPL");
+
index 47d588ba2a7f73e830c249b7546c441c93e26fcf..181b1f32325f3a009ce13af55c7aafa66dd67177 100644 (file)
@@ -1394,8 +1394,8 @@ void ipoib_cm_skb_too_long(struct net_device *dev, struct sk_buff *skb,
        struct ipoib_dev_priv *priv = netdev_priv(dev);
        int e = skb_queue_empty(&priv->cm.skb_queue);
 
-       if (skb->dst)
-               skb->dst->ops->update_pmtu(skb->dst, mtu);
+       if (skb_dst(skb))
+               skb_dst(skb)->ops->update_pmtu(skb_dst(skb), mtu);
 
        skb_queue_tail(&priv->cm.skb_queue, skb);
        if (e)
@@ -1455,13 +1455,15 @@ static ssize_t set_mode(struct device *d, struct device_attribute *attr,
        struct net_device *dev = to_net_dev(d);
        struct ipoib_dev_priv *priv = netdev_priv(dev);
 
+       if (!rtnl_trylock())
+               return restart_syscall();
+
        /* flush paths if we switch modes so that connections are restarted */
        if (IPOIB_CM_SUPPORTED(dev->dev_addr) && !strcmp(buf, "connected\n")) {
                set_bit(IPOIB_FLAG_ADMIN_CM, &priv->flags);
                ipoib_warn(priv, "enabling connected mode "
                           "will cause multicast packet drops\n");
 
-               rtnl_lock();
                dev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_TSO);
                rtnl_unlock();
                priv->tx_wr.send_flags &= ~IB_SEND_IP_CSUM;
@@ -1473,7 +1475,6 @@ static ssize_t set_mode(struct device *d, struct device_attribute *attr,
        if (!strcmp(buf, "datagram\n")) {
                clear_bit(IPOIB_FLAG_ADMIN_CM, &priv->flags);
 
-               rtnl_lock();
                if (test_bit(IPOIB_FLAG_CSUM, &priv->flags)) {
                        dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
                        if (priv->hca_caps & IB_DEVICE_UD_TSO)
@@ -1485,6 +1486,7 @@ static ssize_t set_mode(struct device *d, struct device_attribute *attr,
 
                return count;
        }
+       rtnl_unlock();
 
        return -EINVAL;
 }
index ab2c192c76bc5e726b65f3ea8cb58ddb8e50f695..e319d91f60a609be13d3e18c94df9477207178c6 100644 (file)
@@ -561,7 +561,7 @@ static void neigh_add_path(struct sk_buff *skb, struct net_device *dev)
        struct ipoib_neigh *neigh;
        unsigned long flags;
 
-       neigh = ipoib_neigh_alloc(skb->dst->neighbour, skb->dev);
+       neigh = ipoib_neigh_alloc(skb_dst(skb)->neighbour, skb->dev);
        if (!neigh) {
                ++dev->stats.tx_dropped;
                dev_kfree_skb_any(skb);
@@ -570,9 +570,9 @@ static void neigh_add_path(struct sk_buff *skb, struct net_device *dev)
 
        spin_lock_irqsave(&priv->lock, flags);
 
-       path = __path_find(dev, skb->dst->neighbour->ha + 4);
+       path = __path_find(dev, skb_dst(skb)->neighbour->ha + 4);
        if (!path) {
-               path = path_rec_create(dev, skb->dst->neighbour->ha + 4);
+               path = path_rec_create(dev, skb_dst(skb)->neighbour->ha + 4);
                if (!path)
                        goto err_path;
 
@@ -605,7 +605,7 @@ static void neigh_add_path(struct sk_buff *skb, struct net_device *dev)
                                goto err_drop;
                        }
                } else
-                       ipoib_send(dev, skb, path->ah, IPOIB_QPN(skb->dst->neighbour->ha));
+                       ipoib_send(dev, skb, path->ah, IPOIB_QPN(skb_dst(skb)->neighbour->ha));
        } else {
                neigh->ah  = NULL;
 
@@ -635,15 +635,15 @@ static void ipoib_path_lookup(struct sk_buff *skb, struct net_device *dev)
        struct ipoib_dev_priv *priv = netdev_priv(skb->dev);
 
        /* Look up path record for unicasts */
-       if (skb->dst->neighbour->ha[4] != 0xff) {
+       if (skb_dst(skb)->neighbour->ha[4] != 0xff) {
                neigh_add_path(skb, dev);
                return;
        }
 
        /* Add in the P_Key for multicasts */
-       skb->dst->neighbour->ha[8] = (priv->pkey >> 8) & 0xff;
-       skb->dst->neighbour->ha[9] = priv->pkey & 0xff;
-       ipoib_mcast_send(dev, skb->dst->neighbour->ha + 4, skb);
+       skb_dst(skb)->neighbour->ha[8] = (priv->pkey >> 8) & 0xff;
+       skb_dst(skb)->neighbour->ha[9] = priv->pkey & 0xff;
+       ipoib_mcast_send(dev, skb_dst(skb)->neighbour->ha + 4, skb);
 }
 
 static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev,
@@ -708,16 +708,16 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
        struct ipoib_neigh *neigh;
        unsigned long flags;
 
-       if (likely(skb->dst && skb->dst->neighbour)) {
-               if (unlikely(!*to_ipoib_neigh(skb->dst->neighbour))) {
+       if (likely(skb_dst(skb) && skb_dst(skb)->neighbour)) {
+               if (unlikely(!*to_ipoib_neigh(skb_dst(skb)->neighbour))) {
                        ipoib_path_lookup(skb, dev);
                        return NETDEV_TX_OK;
                }
 
-               neigh = *to_ipoib_neigh(skb->dst->neighbour);
+               neigh = *to_ipoib_neigh(skb_dst(skb)->neighbour);
 
                if (unlikely((memcmp(&neigh->dgid.raw,
-                                    skb->dst->neighbour->ha + 4,
+                                    skb_dst(skb)->neighbour->ha + 4,
                                     sizeof(union ib_gid))) ||
                             (neigh->dev != dev))) {
                        spin_lock_irqsave(&priv->lock, flags);
@@ -743,7 +743,7 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
                                return NETDEV_TX_OK;
                        }
                } else if (neigh->ah) {
-                       ipoib_send(dev, skb, neigh->ah, IPOIB_QPN(skb->dst->neighbour->ha));
+                       ipoib_send(dev, skb, neigh->ah, IPOIB_QPN(skb_dst(skb)->neighbour->ha));
                        return NETDEV_TX_OK;
                }
 
@@ -772,7 +772,7 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
                        if ((be16_to_cpup((__be16 *) skb->data) != ETH_P_ARP) &&
                            (be16_to_cpup((__be16 *) skb->data) != ETH_P_RARP)) {
                                ipoib_warn(priv, "Unicast, no %s: type %04x, QPN %06x %pI6\n",
-                                          skb->dst ? "neigh" : "dst",
+                                          skb_dst(skb) ? "neigh" : "dst",
                                           be16_to_cpup((__be16 *) skb->data),
                                           IPOIB_QPN(phdr->hwaddr),
                                           phdr->hwaddr + 4);
@@ -817,7 +817,7 @@ static int ipoib_hard_header(struct sk_buff *skb,
         * destination address onto the front of the skb so we can
         * figure out where to send the packet later.
         */
-       if ((!skb->dst || !skb->dst->neighbour) && daddr) {
+       if ((!skb_dst(skb) || !skb_dst(skb)->neighbour) && daddr) {
                struct ipoib_pseudoheader *phdr =
                        (struct ipoib_pseudoheader *) skb_push(skb, sizeof *phdr);
                memcpy(phdr->hwaddr, daddr, INFINIBAND_ALEN);
@@ -1053,6 +1053,7 @@ static void ipoib_setup(struct net_device *dev)
        dev->tx_queue_len        = ipoib_sendq_size * 2;
        dev->features            = (NETIF_F_VLAN_CHALLENGED     |
                                    NETIF_F_HIGHDMA);
+       dev->priv_flags         &= ~IFF_XMIT_DST_RELEASE;
 
        memcpy(dev->broadcast, ipv4_bcast_addr, INFINIBAND_ALEN);
 
index 425e31112ed707d18b7acf1fc9938280dd137a2a..a0e97532e7140f422fbd1e40b1a57626f8e2396b 100644 (file)
@@ -261,7 +261,7 @@ static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast,
 
                skb->dev = dev;
 
-               if (!skb->dst || !skb->dst->neighbour) {
+               if (!skb_dst(skb) || !skb_dst(skb)->neighbour) {
                        /* put pseudoheader back on for next time */
                        skb_push(skb, sizeof (struct ipoib_pseudoheader));
                }
@@ -707,10 +707,10 @@ void ipoib_mcast_send(struct net_device *dev, void *mgid, struct sk_buff *skb)
 
 out:
        if (mcast && mcast->ah) {
-               if (skb->dst            &&
-                   skb->dst->neighbour &&
-                   !*to_ipoib_neigh(skb->dst->neighbour)) {
-                       struct ipoib_neigh *neigh = ipoib_neigh_alloc(skb->dst->neighbour,
+               if (skb_dst(skb)                &&
+                   skb_dst(skb)->neighbour &&
+                   !*to_ipoib_neigh(skb_dst(skb)->neighbour)) {
+                       struct ipoib_neigh *neigh = ipoib_neigh_alloc(skb_dst(skb)->neighbour,
                                                                        skb->dev);
 
                        if (neigh) {
index 4c57f329dd50c630646a15cd7c01e03826d72885..e3bf00d8cd259cdb1f167b19aeb0bda4b9af6b86 100644 (file)
@@ -61,7 +61,8 @@ int ipoib_vlan_add(struct net_device *pdev, unsigned short pkey)
 
        ppriv = netdev_priv(pdev);
 
-       rtnl_lock();
+       if (!rtnl_trylock())
+               return restart_syscall();
        mutex_lock(&ppriv->vlan_mutex);
 
        /*
@@ -167,7 +168,8 @@ int ipoib_vlan_delete(struct net_device *pdev, unsigned short pkey)
 
        ppriv = netdev_priv(pdev);
 
-       rtnl_lock();
+       if (!rtnl_trylock())
+               return restart_syscall();
        mutex_lock(&ppriv->vlan_mutex);
        list_for_each_entry_safe(priv, tpriv, &ppriv->child_intfs, list) {
                if (priv->pkey == pkey) {
index 3d113c6e4a703242e32c0d9f57cc09be29516690..02bdca6f95c332aacf4c4be6578c7511b93e8ab8 100644 (file)
@@ -61,4 +61,6 @@ source "drivers/isdn/hardware/Kconfig"
 
 endif # ISDN_CAPI
 
+source "drivers/isdn/gigaset/Kconfig"
+
 endif # ISDN
index 29419a8d31dc3c72b09f38cc2010f7632b3dd931..16f2e465e5f90df5e24634ddcdf9849c32313780 100644 (file)
@@ -490,7 +490,14 @@ static void pars_2_message(_cmsg * cmsg)
        }
 }
 
-/*-------------------------------------------------------*/
+/**
+ * capi_cmsg2message() - assemble CAPI 2.0 message from _cmsg structure
+ * @cmsg:      _cmsg structure
+ * @msg:       buffer for assembled message
+ *
+ * Return value: 0 for success
+ */
+
 unsigned capi_cmsg2message(_cmsg * cmsg, u8 * msg)
 {
        cmsg->m = msg;
@@ -553,7 +560,14 @@ static void message_2_pars(_cmsg * cmsg)
        }
 }
 
-/*-------------------------------------------------------*/
+/**
+ * capi_message2cmsg() - disassemble CAPI 2.0 message into _cmsg structure
+ * @cmsg:      _cmsg structure
+ * @msg:       buffer for assembled message
+ *
+ * Return value: 0 for success
+ */
+
 unsigned capi_message2cmsg(_cmsg * cmsg, u8 * msg)
 {
        memset(cmsg, 0, sizeof(_cmsg));
@@ -573,7 +587,18 @@ unsigned capi_message2cmsg(_cmsg * cmsg, u8 * msg)
        return 0;
 }
 
-/*-------------------------------------------------------*/
+/**
+ * capi_cmsg_header() - initialize header part of _cmsg structure
+ * @cmsg:      _cmsg structure
+ * @_ApplId:   ApplID field value
+ * @_Command:  Command field value
+ * @_Subcommand:       Subcommand field value
+ * @_Messagenumber:    Message Number field value
+ * @_Controller:       Controller/PLCI/NCCI field value
+ *
+ * Return value: 0 for success
+ */
+
 unsigned capi_cmsg_header(_cmsg * cmsg, u16 _ApplId,
                          u8 _Command, u8 _Subcommand,
                          u16 _Messagenumber, u32 _Controller)
@@ -641,6 +666,14 @@ static char *mnames[] =
        [0x4e] = "MANUFACTURER_RESP"
 };
 
+/**
+ * capi_cmd2str() - convert CAPI 2.0 command/subcommand number to name
+ * @cmd:       command number
+ * @subcmd:    subcommand number
+ *
+ * Return value: static string, NULL if command/subcommand unknown
+ */
+
 char *capi_cmd2str(u8 cmd, u8 subcmd)
 {
        return mnames[command_2_index(cmd, subcmd)];
@@ -879,6 +912,11 @@ init:
        return cdb;
 }
 
+/**
+ * cdebbuf_free() - free CAPI debug buffer
+ * @cdb:       buffer to free
+ */
+
 void cdebbuf_free(_cdebbuf *cdb)
 {
        if (likely(cdb == g_debbuf)) {
@@ -891,6 +929,16 @@ void cdebbuf_free(_cdebbuf *cdb)
 }
 
 
+/**
+ * capi_message2str() - format CAPI 2.0 message for printing
+ * @msg:       CAPI 2.0 message
+ *
+ * Allocates a CAPI debug buffer and fills it with a printable representation
+ * of the CAPI 2.0 message in @msg.
+ * Return value: allocated debug buffer, NULL on error
+ * The returned buffer should be freed by a call to cdebbuf_free() after use.
+ */
+
 _cdebbuf *capi_message2str(u8 * msg)
 {
        _cdebbuf *cdb;
@@ -926,10 +974,23 @@ _cdebbuf *capi_message2str(u8 * msg)
        return cdb;
 }
 
+/**
+ * capi_cmsg2str() - format _cmsg structure for printing
+ * @cmsg:      _cmsg structure
+ *
+ * Allocates a CAPI debug buffer and fills it with a printable representation
+ * of the CAPI 2.0 message stored in @cmsg by a previous call to
+ * capi_cmsg2message() or capi_message2cmsg().
+ * Return value: allocated debug buffer, NULL on error
+ * The returned buffer should be freed by a call to cdebbuf_free() after use.
+ */
+
 _cdebbuf *capi_cmsg2str(_cmsg * cmsg)
 {
        _cdebbuf *cdb;
 
+       if (!cmsg->m)
+               return NULL;    /* no message */
        cdb = cdebbuf_alloc();
        if (!cdb)
                return NULL;
index f33170368cd1755dd390900014789598557b9a2a..57d26360f64e38f13a09591a1fec08da76bfa115 100644 (file)
@@ -377,14 +377,14 @@ void capi_ctr_ready(struct capi_ctr * card)
 EXPORT_SYMBOL(capi_ctr_ready);
 
 /**
- * capi_ctr_reseted() - signal CAPI controller reset
+ * capi_ctr_down() - signal CAPI controller not ready
  * @card:      controller descriptor structure.
  *
  * Called by hardware driver to signal that the controller is down and
  * unavailable for use.
  */
 
-void capi_ctr_reseted(struct capi_ctr * card)
+void capi_ctr_down(struct capi_ctr * card)
 {
        u16 appl;
 
@@ -413,7 +413,7 @@ void capi_ctr_reseted(struct capi_ctr * card)
        notify_push(KCI_CONTRDOWN, card->cnr, 0, 0);
 }
 
-EXPORT_SYMBOL(capi_ctr_reseted);
+EXPORT_SYMBOL(capi_ctr_down);
 
 /**
  * capi_ctr_suspend_output() - suspend controller
@@ -517,7 +517,7 @@ EXPORT_SYMBOL(attach_capi_ctr);
 int detach_capi_ctr(struct capi_ctr *card)
 {
         if (card->cardstate != CARD_DETECTED)
-               capi_ctr_reseted(card);
+               capi_ctr_down(card);
 
        ncards--;
 
index 9ca889adf120123010b343bf59f63dacfad17bdc..18ab8652aa57de39fca6516c1726446d7741c3e9 100644 (file)
@@ -1,5 +1,6 @@
 menuconfig ISDN_DRV_GIGASET
        tristate "Siemens Gigaset support"
+       depends on ISDN_I4L
        select CRC_CCITT
        select BITREVERSE
        help
@@ -42,11 +43,4 @@ config GIGASET_DEBUG
          This enables debugging code in the Gigaset drivers.
          If in doubt, say yes.
 
-config GIGASET_UNDOCREQ
-       bool "Support for undocumented USB requests"
-       help
-         This enables support for USB requests we only know from
-         reverse engineering (currently M105 only). If you need
-         features like configuration mode of M105, say yes.
-
 endif # ISDN_DRV_GIGASET
index 2a4ce96f04bd7ecfea5ce9111b231e076bc80a28..234cc5d53312ab90b339edd1c96a005fd10a7942 100644 (file)
@@ -174,9 +174,8 @@ byte_stuff:
 
                                if (unlikely(fcs != PPP_GOODFCS)) {
                                        dev_err(cs->dev,
-                                           "Packet checksum at %lu failed, "
-                                           "packet is corrupted (%u bytes)!\n",
-                                           bcs->rcvbytes, skb->len);
+                               "Checksum failed, %u bytes corrupted!\n",
+                                               skb->len);
                                        compskb = NULL;
                                        gigaset_rcv_error(compskb, cs, bcs);
                                        error = 1;
index 0048ce98bfa8d789dd2262db49bf672ec75f64b1..e4141bf8b2f3a705436115491bab35a18e198062 100644 (file)
@@ -565,8 +565,6 @@ static struct bc_state *gigaset_initbcs(struct bc_state *bcs,
        gig_dbg(DEBUG_INIT, "setting up bcs[%d]->at_state", channel);
        gigaset_at_init(&bcs->at_state, bcs, cs, -1);
 
-       bcs->rcvbytes = 0;
-
 #ifdef CONFIG_GIGASET_DEBUG
        bcs->emptycount = 0;
 #endif
@@ -672,14 +670,8 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels,
        cs->tty = NULL;
        cs->tty_dev = NULL;
        cs->cidmode = cidmode != 0;
-
-       //if(onechannel) { //FIXME
-               cs->tabnocid = gigaset_tab_nocid_m10x;
-               cs->tabcid = gigaset_tab_cid_m10x;
-       //} else {
-       //      cs->tabnocid = gigaset_tab_nocid;
-       //      cs->tabcid = gigaset_tab_cid;
-       //}
+       cs->tabnocid = gigaset_tab_nocid;
+       cs->tabcid = gigaset_tab_cid;
 
        init_waitqueue_head(&cs->waitqueue);
        cs->waiting = 0;
index e582a4887bc15b4055e73ac6f9a8556ef8538ddf..ec5169604a6a93dd714efcb9648390dea5075eee 100644 (file)
 
 
 // 100: init, 200: dle0, 250:dle1, 300: get cid (dial), 350: "hup" (no cid), 400: hup, 500: reset, 600: dial, 700: ring
-struct reply_t gigaset_tab_nocid_m10x[]= /* with dle mode */
+struct reply_t gigaset_tab_nocid[] =
 {
        /* resp_code, min_ConState, max_ConState, parameter, new_ConState, timeout, action, command */
 
@@ -280,7 +280,7 @@ struct reply_t gigaset_tab_nocid_m10x[]= /* with dle mode */
 };
 
 // 600: start dialing, 650: dial in progress, 800: connection is up, 700: ring, 400: hup, 750: accepted icall
-struct reply_t gigaset_tab_cid_m10x[] = /* for M10x */
+struct reply_t gigaset_tab_cid[] =
 {
        /* resp_code, min_ConState, max_ConState, parameter, new_ConState, timeout, action, command */
 
index 747178f03d2c3ec26f50c6d15decda33801b2942..a2f6125739eb23f4ad14478391ed987a5f5136d8 100644 (file)
@@ -282,8 +282,8 @@ struct reply_t {
        char    *command;       /* NULL==none */
 };
 
-extern struct reply_t gigaset_tab_cid_m10x[];
-extern struct reply_t gigaset_tab_nocid_m10x[];
+extern struct reply_t gigaset_tab_cid[];
+extern struct reply_t gigaset_tab_nocid[];
 
 struct inbuf_t {
        unsigned char           *rcvbuf;        /* usb-gigaset receive buffer */
@@ -384,7 +384,6 @@ struct bc_state {
        int trans_up;                   /* Counter of packages (upstream) */
 
        struct at_state_t at_state;
-       unsigned long rcvbytes;
 
        __u16 fcs;
        struct sk_buff *skb;
index 69a702f0db93f3fa70ccd7fc6c649e611f4f0a5f..9b22f9cf2f33b2bd4895bf15f5d3cb16e73918df 100644 (file)
@@ -544,11 +544,11 @@ int gigaset_register_to_LL(struct cardstate *cs, const char *isdnid)
 
        gig_dbg(DEBUG_ANY, "Register driver capabilities to LL");
 
-       //iif->id[sizeof(iif->id) - 1]=0;
-       //strncpy(iif->id, isdnid, sizeof(iif->id) - 1);
        if (snprintf(iif->id, sizeof iif->id, "%s_%u", isdnid, cs->minor_index)
-           >= sizeof iif->id)
-               return -ENOMEM; //FIXME EINVAL/...??
+           >= sizeof iif->id) {
+               pr_err("ID too long: %s\n", isdnid);
+               return 0;
+       }
 
        iif->owner = THIS_MODULE;
        iif->channels = cs->channels;
@@ -568,8 +568,10 @@ int gigaset_register_to_LL(struct cardstate *cs, const char *isdnid)
        iif->rcvcallb_skb = NULL;               /* Will be set by LL */
        iif->statcallb = NULL;                  /* Will be set by LL */
 
-       if (!register_isdn(iif))
+       if (!register_isdn(iif)) {
+               pr_err("register_isdn failed\n");
                return 0;
+       }
 
        cs->myid = iif->channels;               /* Set my device id */
        return 1;
index 820a30923feebff7006e2c5b3bad7751f16837c7..1ebfcab746623d8fd09acf35d6b753afc0963c12 100644 (file)
@@ -599,8 +599,7 @@ void gigaset_if_init(struct cardstate *cs)
        if (!IS_ERR(cs->tty_dev))
                dev_set_drvdata(cs->tty_dev, cs);
        else {
-               dev_warn(cs->dev,
-                        "could not register device to the tty subsystem\n");
+               pr_warning("could not register device to the tty subsystem\n");
                cs->tty_dev = NULL;
        }
        mutex_unlock(&cs->mutex);
index 29808c4fb1cb658ddc9c91f9187ef4cadb39afa4..db3a1e4cd4893e62af25041d478318035c2bad96 100644 (file)
@@ -246,6 +246,10 @@ static inline void dump_bytes(enum debuglevel level, const char *tag,
        unsigned char c;
        static char dbgline[3 * 32 + 1];
        int i = 0;
+
+       if (!(gigaset_debuglevel & level))
+               return;
+
        while (count-- > 0) {
                if (i > sizeof(dbgline) - 4) {
                        dbgline[i] = '\0';
index da6f3acf9fd05f23999a652b24ce0799aa575ca4..9715aad9c3f0c43b6d6617e15f43fae5242681c5 100644 (file)
@@ -79,5 +79,5 @@ void gigaset_init_dev_sysfs(struct cardstate *cs)
 
        gig_dbg(DEBUG_INIT, "setting up sysfs");
        if (device_create_file(cs->tty_dev, &dev_attr_cidmode))
-               dev_err(cs->dev, "could not create sysfs attribute\n");
+               pr_err("could not create sysfs attribute\n");
 }
index d7838516609997b67b41610f3a6d8fca8f2df221..4deb1ab0dbf8176987473f24e14ef05cf265565a 100644 (file)
@@ -153,8 +153,6 @@ static inline unsigned tiocm_to_gigaset(unsigned state)
        return ((state & TIOCM_DTR) ? 1 : 0) | ((state & TIOCM_RTS) ? 2 : 0);
 }
 
-#ifdef CONFIG_GIGASET_UNDOCREQ
-/* WARNING: EXPERIMENTAL! */
 static int gigaset_set_modem_ctrl(struct cardstate *cs, unsigned old_state,
                                  unsigned new_state)
 {
@@ -176,6 +174,11 @@ static int gigaset_set_modem_ctrl(struct cardstate *cs, unsigned old_state,
        return 0;
 }
 
+/*
+ * Set M105 configuration value
+ * using undocumented device commands reverse engineered from USB traces
+ * of the Siemens Windows driver
+ */
 static int set_value(struct cardstate *cs, u8 req, u16 val)
 {
        struct usb_device *udev = cs->hw.usb->udev;
@@ -205,8 +208,10 @@ static int set_value(struct cardstate *cs, u8 req, u16 val)
        return r < 0 ? r : (r2 < 0 ? r2 : 0);
 }
 
-/* WARNING: HIGHLY EXPERIMENTAL! */
-// don't use this in an interrupt/BH
+/*
+ * set the baud rate on the internal serial adapter
+ * using the undocumented parameter setting command
+ */
 static int gigaset_baud_rate(struct cardstate *cs, unsigned cflag)
 {
        u16 val;
@@ -237,8 +242,10 @@ static int gigaset_baud_rate(struct cardstate *cs, unsigned cflag)
        return set_value(cs, 1, val);
 }
 
-/* WARNING: HIGHLY EXPERIMENTAL! */
-// don't use this in an interrupt/BH
+/*
+ * set the line format on the internal serial adapter
+ * using the undocumented parameter setting command
+ */
 static int gigaset_set_line_ctrl(struct cardstate *cs, unsigned cflag)
 {
        u16 val = 0;
@@ -274,24 +281,6 @@ static int gigaset_set_line_ctrl(struct cardstate *cs, unsigned cflag)
        return set_value(cs, 3, val);
 }
 
-#else
-static int gigaset_set_modem_ctrl(struct cardstate *cs, unsigned old_state,
-                                 unsigned new_state)
-{
-       return -ENOTTY;
-}
-
-static int gigaset_set_line_ctrl(struct cardstate *cs, unsigned cflag)
-{
-       return -ENOTTY;
-}
-
-static int gigaset_baud_rate(struct cardstate *cs, unsigned cflag)
-{
-       return -ENOTTY;
-}
-#endif
-
 
  /*================================================================================================================*/
 static int gigaset_init_bchannel(struct bc_state *bcs)
@@ -362,10 +351,8 @@ static void gigaset_modem_fill(unsigned long data)
        } while (again);
 }
 
-/**
- *     gigaset_read_int_callback
- *
- *     It is called if the data was received from the device.
+/*
+ * Interrupt Input URB completion routine
  */
 static void gigaset_read_int_callback(struct urb *urb)
 {
@@ -567,18 +554,19 @@ static int gigaset_chars_in_buffer(struct cardstate *cs)
        return cs->cmdbytes;
 }
 
+/*
+ * set the break characters on the internal serial adapter
+ * using undocumented device commands reverse engineered from USB traces
+ * of the Siemens Windows driver
+ */
 static int gigaset_brkchars(struct cardstate *cs, const unsigned char buf[6])
 {
-#ifdef CONFIG_GIGASET_UNDOCREQ
        struct usb_device *udev = cs->hw.usb->udev;
 
        gigaset_dbg_buffer(DEBUG_USBREQ, "brkchars", 6, buf);
        memcpy(cs->hw.usb->bchars, buf, 6);
        return usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x19, 0x41,
                               0, 0, &buf, 6, 2000);
-#else
-       return -ENOTTY;
-#endif
 }
 
 static int gigaset_freebcshw(struct bc_state *bcs)
@@ -625,7 +613,6 @@ static int gigaset_initcshw(struct cardstate *cs)
        ucs->bchars[5] = 0x13;
        ucs->bulk_out_buffer = NULL;
        ucs->bulk_out_urb = NULL;
-       //ucs->urb_cmd_out = NULL;
        ucs->read_urb = NULL;
        tasklet_init(&cs->write_tasklet,
                     &gigaset_modem_fill, (unsigned long) cs);
@@ -742,7 +729,7 @@ static int gigaset_probe(struct usb_interface *interface,
        cs->dev = &interface->dev;
 
        /* save address of controller structure */
-       usb_set_intfdata(interface, cs); // dev_set_drvdata(&interface->dev, cs);
+       usb_set_intfdata(interface, cs);
 
        endpoint = &hostif->endpoint[0].desc;
 
@@ -921,8 +908,7 @@ static const struct gigaset_ops ops = {
        gigaset_m10x_input,
 };
 
-/**
- *     usb_gigaset_init
+/*
  * This function is called while kernel-module is loaded
  */
 static int __init usb_gigaset_init(void)
@@ -952,9 +938,7 @@ error:
        return -1;
 }
 
-
-/**
- *     usb_gigaset_exit
+/*
  * This function is called while unloading the kernel-module
  */
 static void __exit usb_gigaset_exit(void)
index abf05ec31760544b41928a84cb7286b58c6ac95b..a7c0083e78a7bc063e03505bc36ae2f5864ace44 100644 (file)
@@ -330,7 +330,7 @@ void b1_reset_ctr(struct capi_ctr *ctrl)
        spin_lock_irqsave(&card->lock, flags);
        capilib_release(&cinfo->ncci_head);
        spin_unlock_irqrestore(&card->lock, flags);
-       capi_ctr_reseted(ctrl);
+       capi_ctr_down(ctrl);
 }
 
 void b1_register_appl(struct capi_ctr *ctrl,
index da34b98e3de7425b0ed647a3224e5b1f4d035195..0e84aaae43fd430f1ca2a3a41a357e40f452e8c8 100644 (file)
@@ -759,7 +759,7 @@ void b1dma_reset_ctr(struct capi_ctr *ctrl)
        memset(cinfo->version, 0, sizeof(cinfo->version));
        capilib_release(&cinfo->ncci_head);
        spin_unlock_irqrestore(&card->lock, flags);
-       capi_ctr_reseted(ctrl);
+       capi_ctr_down(ctrl);
 }
 
 /* ------------------------------------------------------------- */
index 9df1d3f66c879e750201e9e16f8d8cbf4d14ccbb..6833301a45fc604f11a9f6833d852fe069c7bfaf 100644 (file)
@@ -681,7 +681,7 @@ static irqreturn_t c4_handle_interrupt(avmcard *card)
                        spin_lock_irqsave(&card->lock, flags);
                        capilib_release(&cinfo->ncci_head);
                        spin_unlock_irqrestore(&card->lock, flags);
-                       capi_ctr_reseted(&cinfo->capi_ctrl);
+                       capi_ctr_down(&cinfo->capi_ctrl);
                }
                card->nlogcontr = 0;
                return IRQ_HANDLED;
@@ -909,7 +909,7 @@ static void c4_reset_ctr(struct capi_ctr *ctrl)
         for (i=0; i < card->nr_controllers; i++) {
                cinfo = &card->ctrlinfo[i];
                memset(cinfo->version, 0, sizeof(cinfo->version));
-               capi_ctr_reseted(&cinfo->capi_ctrl);
+               capi_ctr_down(&cinfo->capi_ctrl);
        }
        card->nlogcontr = 0;
 }
index e7724493738c4673f14d49c039e94f28c9e3ada8..1c53fd49adb6e36f35445c9a86d76e6b9e70eaaa 100644 (file)
@@ -339,7 +339,7 @@ static void t1isa_reset_ctr(struct capi_ctr *ctrl)
        spin_lock_irqsave(&card->lock, flags);
        capilib_release(&cinfo->ncci_head);
        spin_unlock_irqrestore(&card->lock, flags);
-       capi_ctr_reseted(ctrl);
+       capi_ctr_down(ctrl);
 }
 
 static void t1isa_remove(struct pci_dev *pdev)
index fd112ae252cfb9d871c985df5aa88a8ddaffabf7..3024566dd099512fde781e368f02312b918820d1 100644 (file)
@@ -13,7 +13,7 @@ config MISDN_HFCPCI
 
 config MISDN_HFCMULTI
        tristate "Support for HFC multiport cards (HFC-4S/8S/E1)"
-       depends on PCI
+       depends on PCI || 8xx
        depends on MISDN
        help
          Enable support for cards with Cologne Chip AG's HFC multiport
@@ -23,6 +23,15 @@ config MISDN_HFCMULTI
           * HFC-8S (8 S/T interfaces on one chip)
           * HFC-E1 (E1 interface for 2Mbit ISDN)
 
+config MISDN_HFCMULTI_8xx
+       boolean "Support for XHFC embedded board in HFC multiport driver"
+       depends on MISDN
+       depends on MISDN_HFCMULTI
+       depends on 8xx
+       default 8xx
+       help
+         Enable support for the XHFC embedded solution from Speech Design.
+
 config MISDN_HFCUSB
        tristate "Support for HFC-S USB based TAs"
        depends on USB
index 663b77f578bea047cf134aee7bc739622a2cf910..0c773866efc7babb16ab2d604dca334a9b62d0d5 100644 (file)
 #define        PCI_ENA_REGIO   0x01
 #define        PCI_ENA_MEMIO   0x02
 
+#define XHFC_IRQ       4               /* SIU_IRQ2 */
+#define XHFC_MEMBASE   0xFE000000
+#define XHFC_MEMSIZE    0x00001000
+#define XHFC_OFFSET    0x00001000
+#define PA_XHFC_A0     0x0020          /* PA10 */
+#define PB_XHFC_IRQ1   0x00000100      /* PB23 */
+#define PB_XHFC_IRQ2   0x00000200      /* PB22 */
+#define PB_XHFC_IRQ3   0x00000400      /* PB21 */
+#define PB_XHFC_IRQ4   0x00000800      /* PB20 */
+
 /*
  * NOTE: some registers are assigned multiple times due to different modes
  *       also registers are assigned differen for HFC-4s/8s and HFC-E1
@@ -44,6 +54,7 @@ struct hfc_chan {
        int             conf;   /* conference setting of TX slot */
        int             txpending;      /* if there is currently data in */
                                        /* the FIFO 0=no, 1=yes, 2=splloop */
+       int             Zfill;  /* rx-fifo level on last hfcmulti_tx */
        int             rx_off; /* set to turn fifo receive off */
        int             coeff_count; /* curren coeff block */
        s32             *coeff; /* memory pointer to 8 coeff blocks */
@@ -62,6 +73,7 @@ struct hfcm_hw {
        u_char  r_sci_msk;
        u_char  r_tx0, r_tx1;
        u_char  a_st_ctrl0[8];
+       u_char  r_bert_wd_md;
        timer_t timer;
 };
 
@@ -79,6 +91,11 @@ struct hfcm_hw {
 #define        HFC_CFG_CRC4            10 /* disable CRC-4 Multiframe mode, */
                                        /* use double frame instead. */
 
+#define HFC_TYPE_E1            1 /* controller is HFC-E1 */
+#define HFC_TYPE_4S            4 /* controller is HFC-4S */
+#define HFC_TYPE_8S            8 /* controller is HFC-8S */
+#define HFC_TYPE_XHFC          5 /* controller is XHFC */
+
 #define        HFC_CHIP_EXRAM_128      0 /* external ram 128k */
 #define        HFC_CHIP_EXRAM_512      1 /* external ram 256k */
 #define        HFC_CHIP_REVISION0      2 /* old fifo handling */
@@ -86,19 +103,22 @@ struct hfcm_hw {
 #define        HFC_CHIP_PCM_MASTER     4 /* PCM is master */
 #define        HFC_CHIP_RX_SYNC        5 /* disable pll sync for pcm */
 #define        HFC_CHIP_DTMF           6 /* DTMF decoding is enabled */
-#define        HFC_CHIP_ULAW           7 /* ULAW mode */
-#define        HFC_CHIP_CLOCK2         8 /* double clock mode */
-#define        HFC_CHIP_E1CLOCK_GET    9 /* always get clock from E1 interface */
-#define        HFC_CHIP_E1CLOCK_PUT    10 /* always put clock from E1 interface */
-#define        HFC_CHIP_WATCHDOG       11 /* whether we should send signals */
+#define        HFC_CHIP_CONF           7 /* conference handling is enabled */
+#define        HFC_CHIP_ULAW           8 /* ULAW mode */
+#define        HFC_CHIP_CLOCK2         9 /* double clock mode */
+#define        HFC_CHIP_E1CLOCK_GET    10 /* always get clock from E1 interface */
+#define        HFC_CHIP_E1CLOCK_PUT    11 /* always put clock from E1 interface */
+#define        HFC_CHIP_WATCHDOG       12 /* whether we should send signals */
                                        /* to the watchdog */
-#define        HFC_CHIP_B410P          12 /* whether we have a b410p with echocan in */
+#define        HFC_CHIP_B410P          13 /* whether we have a b410p with echocan in */
                                        /* hw */
-#define        HFC_CHIP_PLXSD          13 /* whether we have a Speech-Design PLX */
+#define        HFC_CHIP_PLXSD          14 /* whether we have a Speech-Design PLX */
+#define        HFC_CHIP_EMBSD          15 /* whether we have a SD Embedded board */
 
 #define HFC_IO_MODE_PCIMEM     0x00 /* normal memory mapped IO */
 #define HFC_IO_MODE_REGIO      0x01 /* PCI io access */
 #define HFC_IO_MODE_PLXSD      0x02 /* access HFC via PLX9030 */
+#define HFC_IO_MODE_EMBSD      0x03 /* direct access */
 
 /* table entry in the PCI devices list */
 struct hm_map {
@@ -111,6 +131,7 @@ struct hm_map {
        int opticalsupport;
        int dip_type;
        int io_mode;
+       int irq;
 };
 
 struct hfc_multi {
@@ -118,7 +139,7 @@ struct hfc_multi {
        struct hm_map   *mtyp;
        int             id;
        int             pcm;    /* id of pcm bus */
-       int             type;
+       int             ctype;  /* controller type */
        int             ports;
 
        u_int           irq;    /* irq used by card */
@@ -158,10 +179,16 @@ struct hfc_multi {
                                int len);
        void            (*write_fifo)(struct hfc_multi *hc, u_char *data,
                                int len);
-       u_long          pci_origmembase, plx_origmembase, dsp_origmembase;
+       u_long          pci_origmembase, plx_origmembase;
        void __iomem    *pci_membase; /* PCI memory */
        void __iomem    *plx_membase; /* PLX memory */
-       u_char          *dsp_membase; /* DSP on PLX */
+       u_long          xhfc_origmembase;
+       u_char          *xhfc_membase;
+       u_long          *xhfc_memaddr, *xhfc_memdata;
+#ifdef CONFIG_MISDN_HFCMULTI_8xx
+       struct immap    *immap;
+#endif
+       u_long          pb_irqmsk;      /* Portbit mask to check the IRQ line */
        u_long          pci_iobase; /* PCI IO */
        struct hfcm_hw  hw;     /* remember data of write-only-registers */
 
diff --git a/drivers/isdn/hardware/mISDN/hfc_multi_8xx.h b/drivers/isdn/hardware/mISDN/hfc_multi_8xx.h
new file mode 100644 (file)
index 0000000..45ddced
--- /dev/null
@@ -0,0 +1,167 @@
+/*
+ * For License see notice in hfc_multi.c
+ *
+ * special IO and init functions for the embedded XHFC board
+ * from Speech Design
+ *
+ */
+
+#include <asm/8xx_immap.h>
+
+/* Change this to the value used by your board */
+#ifndef IMAP_ADDR
+#define IMAP_ADDR      0xFFF00000
+#endif
+
+static void
+#ifdef HFC_REGISTER_DEBUG
+HFC_outb_embsd(struct hfc_multi *hc, u_char reg, u_char val,
+               const char *function, int line)
+#else
+HFC_outb_embsd(struct hfc_multi *hc, u_char reg, u_char val)
+#endif
+{
+       hc->immap->im_ioport.iop_padat |= PA_XHFC_A0;
+       writeb(reg, hc->xhfc_memaddr);
+       hc->immap->im_ioport.iop_padat &= ~(PA_XHFC_A0);
+       writeb(val, hc->xhfc_memdata);
+}
+static u_char
+#ifdef HFC_REGISTER_DEBUG
+HFC_inb_embsd(struct hfc_multi *hc, u_char reg, const char *function, int line)
+#else
+HFC_inb_embsd(struct hfc_multi *hc, u_char reg)
+#endif
+{
+       hc->immap->im_ioport.iop_padat |= PA_XHFC_A0;
+       writeb(reg, hc->xhfc_memaddr);
+       hc->immap->im_ioport.iop_padat &= ~(PA_XHFC_A0);
+       return readb(hc->xhfc_memdata);
+}
+static u_short
+#ifdef HFC_REGISTER_DEBUG
+HFC_inw_embsd(struct hfc_multi *hc, u_char reg, const char *function, int line)
+#else
+HFC_inw_embsd(struct hfc_multi *hc, u_char reg)
+#endif
+{
+       hc->immap->im_ioport.iop_padat |= PA_XHFC_A0;
+       writeb(reg, hc->xhfc_memaddr);
+       hc->immap->im_ioport.iop_padat &= ~(PA_XHFC_A0);
+       return readb(hc->xhfc_memdata);
+}
+static void
+#ifdef HFC_REGISTER_DEBUG
+HFC_wait_embsd(struct hfc_multi *hc, const char *function, int line)
+#else
+HFC_wait_embsd(struct hfc_multi *hc)
+#endif
+{
+       hc->immap->im_ioport.iop_padat |= PA_XHFC_A0;
+       writeb(R_STATUS, hc->xhfc_memaddr);
+       hc->immap->im_ioport.iop_padat &= ~(PA_XHFC_A0);
+       while (readb(hc->xhfc_memdata) & V_BUSY)
+               cpu_relax();
+}
+
+/* write fifo data (EMBSD) */
+void
+write_fifo_embsd(struct hfc_multi *hc, u_char *data, int len)
+{
+       hc->immap->im_ioport.iop_padat |= PA_XHFC_A0;
+       *hc->xhfc_memaddr = A_FIFO_DATA0;
+       hc->immap->im_ioport.iop_padat &= ~(PA_XHFC_A0);
+       while (len) {
+               *hc->xhfc_memdata = *data;
+               data++;
+               len--;
+       }
+}
+
+/* read fifo data (EMBSD) */
+void
+read_fifo_embsd(struct hfc_multi *hc, u_char *data, int len)
+{
+       hc->immap->im_ioport.iop_padat |= PA_XHFC_A0;
+       *hc->xhfc_memaddr = A_FIFO_DATA0;
+       hc->immap->im_ioport.iop_padat &= ~(PA_XHFC_A0);
+       while (len) {
+               *data = (u_char)(*hc->xhfc_memdata);
+               data++;
+               len--;
+       }
+}
+
+static int
+setup_embedded(struct hfc_multi *hc, struct hm_map *m)
+{
+       printk(KERN_INFO
+           "HFC-multi: card manufacturer: '%s' card name: '%s' clock: %s\n",
+           m->vendor_name, m->card_name, m->clock2 ? "double" : "normal");
+
+       hc->pci_dev = NULL;
+       if (m->clock2)
+               test_and_set_bit(HFC_CHIP_CLOCK2, &hc->chip);
+
+       hc->leds = m->leds;
+       hc->ledstate = 0xAFFEAFFE;
+       hc->opticalsupport = m->opticalsupport;
+
+       hc->pci_iobase = 0;
+       hc->pci_membase = 0;
+       hc->xhfc_membase = NULL;
+       hc->xhfc_memaddr = NULL;
+       hc->xhfc_memdata = NULL;
+
+       /* set memory access methods */
+       if (m->io_mode) /* use mode from card config */
+               hc->io_mode = m->io_mode;
+       switch (hc->io_mode) {
+       case HFC_IO_MODE_EMBSD:
+               test_and_set_bit(HFC_CHIP_EMBSD, &hc->chip);
+               hc->slots = 128; /* required */
+               /* fall through */
+               hc->HFC_outb = HFC_outb_embsd;
+               hc->HFC_inb = HFC_inb_embsd;
+               hc->HFC_inw = HFC_inw_embsd;
+               hc->HFC_wait = HFC_wait_embsd;
+               hc->read_fifo = read_fifo_embsd;
+               hc->write_fifo = write_fifo_embsd;
+               hc->xhfc_origmembase = XHFC_MEMBASE + XHFC_OFFSET * hc->id;
+               hc->xhfc_membase = (u_char *)ioremap(hc->xhfc_origmembase,
+                               XHFC_MEMSIZE);
+               if (!hc->xhfc_membase) {
+                       printk(KERN_WARNING
+                           "HFC-multi: failed to remap xhfc address space. "
+                           "(internal error)\n");
+                       return -EIO;
+               }
+               hc->xhfc_memaddr = (u_long *)(hc->xhfc_membase + 4);
+               hc->xhfc_memdata = (u_long *)(hc->xhfc_membase);
+               printk(KERN_INFO
+                   "HFC-multi: xhfc_membase:%#lx xhfc_origmembase:%#lx "
+                   "xhfc_memaddr:%#lx xhfc_memdata:%#lx\n",
+                   (u_long)hc->xhfc_membase, hc->xhfc_origmembase,
+                   (u_long)hc->xhfc_memaddr, (u_long)hc->xhfc_memdata);
+               break;
+       default:
+               printk(KERN_WARNING "HFC-multi: Invalid IO mode.\n");
+               return -EIO;
+       }
+
+       /* Prepare the MPC8XX PortA 10 as output (address/data selector) */
+       hc->immap = (struct immap *)(IMAP_ADDR);
+       hc->immap->im_ioport.iop_papar &= ~(PA_XHFC_A0);
+       hc->immap->im_ioport.iop_paodr &= ~(PA_XHFC_A0);
+       hc->immap->im_ioport.iop_padir |=   PA_XHFC_A0;
+
+       /* Prepare the MPC8xx PortB __X__ as input (ISDN__X__IRQ) */
+       hc->pb_irqmsk = (PB_XHFC_IRQ1 << hc->id);
+       hc->immap->im_cpm.cp_pbpar &= ~(hc->pb_irqmsk);
+       hc->immap->im_cpm.cp_pbodr &= ~(hc->pb_irqmsk);
+       hc->immap->im_cpm.cp_pbdir &= ~(hc->pb_irqmsk);
+
+       /* At this point the needed config is done */
+       /* fifos are still not enabled */
+       return 0;
+}
index 0b28141e43bf51c1eef706659ba279872bb04807..e1dab30aed30aebeef28b6b85592ac3f54a717ea 100644 (file)
  *     If unsure, don't give this parameter.
  *
  * dslot:
- *     NOTE: only one poll value must be given for every card.
+ *     NOTE: only one dslot value must be given for every card.
  *     Also this value must be given for non-E1 cards. If omitted, the E1
  *     card has D-channel on time slot 16, which is default.
  *     If 1..15 or 17..31, an alternate time slot is used for D-channel.
  *     Selects interface with clock source for mISDN and applications.
  *     Set to card number starting with 1. Set to -1 to disable.
  *     By default, the first card is used as clock source.
+ *
+ * hwid:
+ *     NOTE: only one hwid value must be given once
+ *     Enable special embedded devices with XHFC controllers.
  */
 
 /*
@@ -206,6 +210,11 @@ static int clock;
 static uint    timer;
 static uint    clockdelay_te = CLKDEL_TE;
 static uint    clockdelay_nt = CLKDEL_NT;
+#define HWID_NONE      0
+#define HWID_MINIP4    1
+#define HWID_MINIP8    2
+#define HWID_MINIP16   3
+static uint    hwid = HWID_NONE;
 
 static int     HFC_cnt, Port_cnt, PCM_cnt = 99;
 
@@ -223,6 +232,7 @@ module_param_array(pcm, int, NULL, S_IRUGO | S_IWUSR);
 module_param_array(dslot, int, NULL, S_IRUGO | S_IWUSR);
 module_param_array(iomode, uint, NULL, S_IRUGO | S_IWUSR);
 module_param_array(port, uint, NULL, S_IRUGO | S_IWUSR);
+module_param(hwid, uint, S_IRUGO | S_IWUSR); /* The hardware ID */
 
 #ifdef HFC_REGISTER_DEBUG
 #define HFC_outb(hc, reg, val) \
@@ -252,6 +262,10 @@ module_param_array(port, uint, NULL, S_IRUGO | S_IWUSR);
 #define HFC_wait_nodebug(hc)           (hc->HFC_wait_nodebug(hc))
 #endif
 
+#ifdef CONFIG_MISDN_HFCMULTI_8xx
+#include "hfc_multi_8xx.h"
+#endif
+
 /* HFC_IO_MODE_PCIMEM */
 static void
 #ifdef HFC_REGISTER_DEBUG
@@ -261,7 +275,7 @@ HFC_outb_pcimem(struct hfc_multi *hc, u_char reg, u_char val,
 HFC_outb_pcimem(struct hfc_multi *hc, u_char reg, u_char val)
 #endif
 {
-       writeb(val, (hc->pci_membase)+reg);
+       writeb(val, hc->pci_membase + reg);
 }
 static u_char
 #ifdef HFC_REGISTER_DEBUG
@@ -270,7 +284,7 @@ HFC_inb_pcimem(struct hfc_multi *hc, u_char reg, const char *function, int line)
 HFC_inb_pcimem(struct hfc_multi *hc, u_char reg)
 #endif
 {
-       return readb((hc->pci_membase)+reg);
+       return readb(hc->pci_membase + reg);
 }
 static u_short
 #ifdef HFC_REGISTER_DEBUG
@@ -279,7 +293,7 @@ HFC_inw_pcimem(struct hfc_multi *hc, u_char reg, const char *function, int line)
 HFC_inw_pcimem(struct hfc_multi *hc, u_char reg)
 #endif
 {
-       return readw((hc->pci_membase)+reg);
+       return readw(hc->pci_membase + reg);
 }
 static void
 #ifdef HFC_REGISTER_DEBUG
@@ -288,7 +302,8 @@ HFC_wait_pcimem(struct hfc_multi *hc, const char *function, int line)
 HFC_wait_pcimem(struct hfc_multi *hc)
 #endif
 {
-       while (readb((hc->pci_membase)+R_STATUS) & V_BUSY);
+       while (readb(hc->pci_membase + R_STATUS) & V_BUSY)
+               cpu_relax();
 }
 
 /* HFC_IO_MODE_REGIO */
@@ -300,7 +315,7 @@ HFC_outb_regio(struct hfc_multi *hc, u_char reg, u_char val,
 HFC_outb_regio(struct hfc_multi *hc, u_char reg, u_char val)
 #endif
 {
-       outb(reg, (hc->pci_iobase)+4);
+       outb(reg, hc->pci_iobase + 4);
        outb(val, hc->pci_iobase);
 }
 static u_char
@@ -310,7 +325,7 @@ HFC_inb_regio(struct hfc_multi *hc, u_char reg, const char *function, int line)
 HFC_inb_regio(struct hfc_multi *hc, u_char reg)
 #endif
 {
-       outb(reg, (hc->pci_iobase)+4);
+       outb(reg, hc->pci_iobase + 4);
        return inb(hc->pci_iobase);
 }
 static u_short
@@ -320,7 +335,7 @@ HFC_inw_regio(struct hfc_multi *hc, u_char reg, const char *function, int line)
 HFC_inw_regio(struct hfc_multi *hc, u_char reg)
 #endif
 {
-       outb(reg, (hc->pci_iobase)+4);
+       outb(reg, hc->pci_iobase + 4);
        return inw(hc->pci_iobase);
 }
 static void
@@ -330,8 +345,9 @@ HFC_wait_regio(struct hfc_multi *hc, const char *function, int line)
 HFC_wait_regio(struct hfc_multi *hc)
 #endif
 {
-       outb(R_STATUS, (hc->pci_iobase)+4);
-       while (inb(hc->pci_iobase) & V_BUSY);
+       outb(R_STATUS, hc->pci_iobase + 4);
+       while (inb(hc->pci_iobase) & V_BUSY)
+               cpu_relax();
 }
 
 #ifdef HFC_REGISTER_DEBUG
@@ -350,14 +366,14 @@ HFC_outb_debug(struct hfc_multi *hc, u_char reg, u_char val,
        if (regname[0] == '\0')
                strcpy(regname, "register");
 
-       bits[7] = '0'+(!!(val&1));
-       bits[6] = '0'+(!!(val&2));
-       bits[5] = '0'+(!!(val&4));
-       bits[4] = '0'+(!!(val&8));
-       bits[3] = '0'+(!!(val&16));
-       bits[2] = '0'+(!!(val&32));
-       bits[1] = '0'+(!!(val&64));
-       bits[0] = '0'+(!!(val&128));
+       bits[7] = '0' + (!!(val & 1));
+       bits[6] = '0' + (!!(val & 2));
+       bits[5] = '0' + (!!(val & 4));
+       bits[4] = '0' + (!!(val & 8));
+       bits[3] = '0' + (!!(val & 16));
+       bits[2] = '0' + (!!(val & 32));
+       bits[1] = '0' + (!!(val & 64));
+       bits[0] = '0' + (!!(val & 128));
        printk(KERN_DEBUG
            "HFC_outb(chip %d, %02x=%s, 0x%02x=%s); in %s() line %d\n",
            hc->id, reg, regname, val, bits, function, line);
@@ -380,14 +396,14 @@ HFC_inb_debug(struct hfc_multi *hc, u_char reg, const char *function, int line)
        if (regname[0] == '\0')
                strcpy(regname, "register");
 
-       bits[7] = '0'+(!!(val&1));
-       bits[6] = '0'+(!!(val&2));
-       bits[5] = '0'+(!!(val&4));
-       bits[4] = '0'+(!!(val&8));
-       bits[3] = '0'+(!!(val&16));
-       bits[2] = '0'+(!!(val&32));
-       bits[1] = '0'+(!!(val&64));
-       bits[0] = '0'+(!!(val&128));
+       bits[7] = '0' + (!!(val & 1));
+       bits[6] = '0' + (!!(val & 2));
+       bits[5] = '0' + (!!(val & 4));
+       bits[4] = '0' + (!!(val & 8));
+       bits[3] = '0' + (!!(val & 16));
+       bits[2] = '0' + (!!(val & 32));
+       bits[1] = '0' + (!!(val & 64));
+       bits[0] = '0' + (!!(val & 128));
        printk(KERN_DEBUG
            "HFC_inb(chip %d, %02x=%s) = 0x%02x=%s; in %s() line %d\n",
            hc->id, reg, regname, val, bits, function, line);
@@ -467,6 +483,7 @@ write_fifo_pcimem(struct hfc_multi *hc, u_char *data, int len)
                len--;
        }
 }
+
 /* read fifo data (REGIO) */
 static void
 read_fifo_regio(struct hfc_multi *hc, u_char *data, int len)
@@ -512,7 +529,6 @@ read_fifo_pcimem(struct hfc_multi *hc, u_char *data, int len)
        }
 }
 
-
 static void
 enable_hwirq(struct hfc_multi *hc)
 {
@@ -928,7 +944,7 @@ hfcmulti_resync(struct hfc_multi *locked, struct hfc_multi *newmaster, int rm)
                        writel(pv, plx_acc_32);
                        if (test_bit(HFC_CHIP_PCM_MASTER, &hc->chip)) {
                                pcmmaster = hc;
-                               if (hc->type == 1) {
+                               if (hc->ctype == HFC_TYPE_E1) {
                                        if (debug & DEBUG_HFCMULTI_PLXSD)
                                                printk(KERN_DEBUG
                                                        "Schedule SYNC_I\n");
@@ -949,7 +965,8 @@ hfcmulti_resync(struct hfc_multi *locked, struct hfc_multi *newmaster, int rm)
                pv |= PLX_SYNC_O_EN;
                writel(pv, plx_acc_32);
                /* switch to jatt PLL, if not disabled by RX_SYNC */
-               if (hc->type == 1 && !test_bit(HFC_CHIP_RX_SYNC, &hc->chip)) {
+               if (hc->ctype == HFC_TYPE_E1
+                               && !test_bit(HFC_CHIP_RX_SYNC, &hc->chip)) {
                        if (debug & DEBUG_HFCMULTI_PLXSD)
                                printk(KERN_DEBUG "Schedule jatt PLL\n");
                        hc->e1_resync |= 2; /* switch to jatt */
@@ -961,7 +978,7 @@ hfcmulti_resync(struct hfc_multi *locked, struct hfc_multi *newmaster, int rm)
                                printk(KERN_DEBUG
                                        "id=%d (0x%p) = PCM master syncronized "
                                        "with QUARTZ\n", hc->id, hc);
-                       if (hc->type == 1) {
+                       if (hc->ctype == HFC_TYPE_E1) {
                                /* Use the crystal clock for the PCM
                                   master card */
                                if (debug & DEBUG_HFCMULTI_PLXSD)
@@ -972,7 +989,7 @@ hfcmulti_resync(struct hfc_multi *locked, struct hfc_multi *newmaster, int rm)
                                if (debug & DEBUG_HFCMULTI_PLXSD)
                                        printk(KERN_DEBUG
                                            "QUARTZ is automatically "
-                                           "enabled by HFC-%dS\n", hc->type);
+                                           "enabled by HFC-%dS\n", hc->ctype);
                        }
                        plx_acc_32 = hc->plx_membase + PLX_GPIOC;
                        pv = readl(plx_acc_32);
@@ -996,7 +1013,7 @@ plxsd_checksync(struct hfc_multi *hc, int rm)
        if (hc->syncronized) {
                if (syncmaster == NULL) {
                        if (debug & DEBUG_HFCMULTI_PLXSD)
-                               printk(KERN_WARNING "%s: GOT sync on card %d"
+                               printk(KERN_DEBUG "%s: GOT sync on card %d"
                                        " (id=%d)\n", __func__, hc->id + 1,
                                        hc->id);
                        hfcmulti_resync(hc, hc, rm);
@@ -1004,7 +1021,7 @@ plxsd_checksync(struct hfc_multi *hc, int rm)
        } else {
                if (syncmaster == hc) {
                        if (debug & DEBUG_HFCMULTI_PLXSD)
-                               printk(KERN_WARNING "%s: LOST sync on card %d"
+                               printk(KERN_DEBUG "%s: LOST sync on card %d"
                                        " (id=%d)\n", __func__, hc->id + 1,
                                        hc->id);
                        hfcmulti_resync(hc, NULL, rm);
@@ -1053,20 +1070,23 @@ release_io_hfcmulti(struct hfc_multi *hc)
                pv &= ~PLX_DSP_RES_N;
                writel(pv, plx_acc_32);
                if (debug & DEBUG_HFCMULTI_INIT)
-                       printk(KERN_WARNING "%s: PCM off: PLX_GPIO=%x\n",
+                       printk(KERN_DEBUG "%s: PCM off: PLX_GPIO=%x\n",
                                __func__, pv);
                spin_unlock_irqrestore(&plx_lock, plx_flags);
        }
 
        /* disable memory mapped ports / io ports */
        test_and_clear_bit(HFC_CHIP_PLXSD, &hc->chip); /* prevent resync */
-       pci_write_config_word(hc->pci_dev, PCI_COMMAND, 0);
+       if (hc->pci_dev)
+               pci_write_config_word(hc->pci_dev, PCI_COMMAND, 0);
        if (hc->pci_membase)
                iounmap(hc->pci_membase);
        if (hc->plx_membase)
                iounmap(hc->plx_membase);
        if (hc->pci_iobase)
                release_region(hc->pci_iobase, 8);
+       if (hc->xhfc_membase)
+               iounmap((void *)hc->xhfc_membase);
 
        if (hc->pci_dev) {
                pci_disable_device(hc->pci_dev);
@@ -1100,8 +1120,9 @@ init_chip(struct hfc_multi *hc)
        /* revision check */
        if (debug & DEBUG_HFCMULTI_INIT)
                printk(KERN_DEBUG "%s: entered\n", __func__);
-       val = HFC_inb(hc, R_CHIP_ID)>>4;
-       if (val != 0x8 && val != 0xc && val != 0xe) {
+       val = HFC_inb(hc, R_CHIP_ID);
+       if ((val >> 4) != 0x8 && (val >> 4) != 0xc && (val >> 4) != 0xe &&
+           (val >> 1) != 0x31) {
                printk(KERN_INFO "HFC_multi: unknown CHIP_ID:%x\n", (u_int)val);
                err = -EIO;
                goto out;
@@ -1109,8 +1130,9 @@ init_chip(struct hfc_multi *hc)
        rev = HFC_inb(hc, R_CHIP_RV);
        printk(KERN_INFO
            "HFC_multi: detected HFC with chip ID=0x%lx revision=%ld%s\n",
-           val, rev, (rev == 0) ? " (old FIFO handling)" : "");
-       if (rev == 0) {
+           val, rev, (rev == 0 && (hc->ctype != HFC_TYPE_XHFC)) ?
+               " (old FIFO handling)" : "");
+       if (hc->ctype != HFC_TYPE_XHFC && rev == 0) {
                test_and_set_bit(HFC_CHIP_REVISION0, &hc->chip);
                printk(KERN_WARNING
                    "HFC_multi: NOTE: Your chip is revision 0, "
@@ -1152,6 +1174,12 @@ init_chip(struct hfc_multi *hc)
                hc->Zlen = 8000;
                hc->DTMFbase = 0x2000;
        }
+       if (hc->ctype == HFC_TYPE_XHFC) {
+               hc->Flen = 0x8;
+               hc->Zmin = 0x0;
+               hc->Zlen = 64;
+               hc->DTMFbase = 0x0;
+       }
        hc->max_trans = poll << 1;
        if (hc->max_trans > hc->Zlen)
                hc->max_trans = hc->Zlen;
@@ -1176,7 +1204,7 @@ init_chip(struct hfc_multi *hc)
                writel(pv, plx_acc_32);
                spin_unlock_irqrestore(&plx_lock, plx_flags);
                if (debug & DEBUG_HFCMULTI_INIT)
-                       printk(KERN_WARNING "%s: slave/term: PLX_GPIO=%x\n",
+                       printk(KERN_DEBUG "%s: slave/term: PLX_GPIO=%x\n",
                                __func__, pv);
                /*
                 * If we are the 3rd PLXSD card or higher, we must turn
@@ -1204,13 +1232,17 @@ init_chip(struct hfc_multi *hc)
                        writel(pv, plx_acc_32);
                        spin_unlock_irqrestore(&plx_lock, plx_flags);
                        if (debug & DEBUG_HFCMULTI_INIT)
-                           printk(KERN_WARNING "%s: term off: PLX_GPIO=%x\n",
-                                       __func__, pv);
+                               printk(KERN_DEBUG
+                                   "%s: term off: PLX_GPIO=%x\n",
+                                   __func__, pv);
                }
                spin_unlock_irqrestore(&HFClock, hfc_flags);
                hc->hw.r_pcm_md0 = V_F0_LEN; /* shift clock for DSP */
        }
 
+       if (test_bit(HFC_CHIP_EMBSD, &hc->chip))
+               hc->hw.r_pcm_md0 = V_F0_LEN; /* shift clock for DSP */
+
        /* we only want the real Z2 read-pointer for revision > 0 */
        if (!test_bit(HFC_CHIP_REVISION0, &hc->chip))
                hc->hw.r_ram_sz |= V_FZ_MD;
@@ -1234,15 +1266,24 @@ init_chip(struct hfc_multi *hc)
 
        /* soft reset */
        HFC_outb(hc, R_CTRL, hc->hw.r_ctrl);
-       HFC_outb(hc, R_RAM_SZ, hc->hw.r_ram_sz);
+       if (hc->ctype == HFC_TYPE_XHFC)
+               HFC_outb(hc, 0x0C /* R_FIFO_THRES */,
+                               0x11 /* 16 Bytes TX/RX */);
+       else
+               HFC_outb(hc, R_RAM_SZ, hc->hw.r_ram_sz);
        HFC_outb(hc, R_FIFO_MD, 0);
-       hc->hw.r_cirm = V_SRES | V_HFCRES | V_PCMRES | V_STRES | V_RLD_EPR;
+       if (hc->ctype == HFC_TYPE_XHFC)
+               hc->hw.r_cirm = V_SRES | V_HFCRES | V_PCMRES | V_STRES;
+       else
+               hc->hw.r_cirm = V_SRES | V_HFCRES | V_PCMRES | V_STRES
+                       | V_RLD_EPR;
        HFC_outb(hc, R_CIRM, hc->hw.r_cirm);
        udelay(100);
        hc->hw.r_cirm = 0;
        HFC_outb(hc, R_CIRM, hc->hw.r_cirm);
        udelay(100);
-       HFC_outb(hc, R_RAM_SZ, hc->hw.r_ram_sz);
+       if (hc->ctype != HFC_TYPE_XHFC)
+               HFC_outb(hc, R_RAM_SZ, hc->hw.r_ram_sz);
 
        /* Speech Design PLX bridge pcm and sync mode */
        if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
@@ -1254,13 +1295,13 @@ init_chip(struct hfc_multi *hc)
                        pv |= PLX_MASTER_EN | PLX_SLAVE_EN_N;
                        pv |= PLX_SYNC_O_EN;
                        if (debug & DEBUG_HFCMULTI_INIT)
-                               printk(KERN_WARNING "%s: master: PLX_GPIO=%x\n",
+                               printk(KERN_DEBUG "%s: master: PLX_GPIO=%x\n",
                                        __func__, pv);
                } else {
                        pv &= ~(PLX_MASTER_EN | PLX_SLAVE_EN_N);
                        pv &= ~PLX_SYNC_O_EN;
                        if (debug & DEBUG_HFCMULTI_INIT)
-                               printk(KERN_WARNING "%s: slave: PLX_GPIO=%x\n",
+                               printk(KERN_DEBUG "%s: slave: PLX_GPIO=%x\n",
                                        __func__, pv);
                }
                writel(pv, plx_acc_32);
@@ -1278,13 +1319,16 @@ init_chip(struct hfc_multi *hc)
        HFC_outb(hc, R_PCM_MD0, hc->hw.r_pcm_md0 | 0xa0);
        if (test_bit(HFC_CHIP_PLXSD, &hc->chip))
                HFC_outb(hc, R_PCM_MD2, V_SYNC_SRC); /* sync via SYNC_I / O */
+       else if (test_bit(HFC_CHIP_EMBSD, &hc->chip))
+               HFC_outb(hc, R_PCM_MD2, 0x10); /* V_C2O_EN */
        else
                HFC_outb(hc, R_PCM_MD2, 0x00); /* sync from interface */
        HFC_outb(hc, R_PCM_MD0, hc->hw.r_pcm_md0 | 0x00);
        for (i = 0; i < 256; i++) {
                HFC_outb_nodebug(hc, R_SLOT, i);
                HFC_outb_nodebug(hc, A_SL_CFG, 0);
-               HFC_outb_nodebug(hc, A_CONF, 0);
+               if (hc->ctype != HFC_TYPE_XHFC)
+                       HFC_outb_nodebug(hc, A_CONF, 0);
                hc->slot_owner[i] = -1;
        }
 
@@ -1296,6 +1340,9 @@ init_chip(struct hfc_multi *hc)
                HFC_outb(hc, R_BRG_PCM_CFG, V_PCM_CLK);
        }
 
+       if (test_bit(HFC_CHIP_EMBSD, &hc->chip))
+               HFC_outb(hc, 0x02 /* R_CLK_CFG */, 0x40 /* V_CLKO_OFF */);
+
        /* B410P GPIO */
        if (test_bit(HFC_CHIP_B410P, &hc->chip)) {
                printk(KERN_NOTICE "Setting GPIOs\n");
@@ -1366,8 +1413,8 @@ controller_fail:
                                writel(pv, plx_acc_32);
                                spin_unlock_irqrestore(&plx_lock, plx_flags);
                                if (debug & DEBUG_HFCMULTI_INIT)
-                                   printk(KERN_WARNING "%s: master: PLX_GPIO"
-                                       "=%x\n", __func__, pv);
+                                       printk(KERN_DEBUG "%s: master: "
+                                           "PLX_GPIO=%x\n", __func__, pv);
                        }
                        hc->hw.r_pcm_md0 |= V_PCM_MD;
                        HFC_outb(hc, R_PCM_MD0, hc->hw.r_pcm_md0 | 0x00);
@@ -1401,7 +1448,7 @@ controller_fail:
                writel(pv, plx_acc_32);
                spin_unlock_irqrestore(&plx_lock, plx_flags);
                if (debug & DEBUG_HFCMULTI_INIT)
-                       printk(KERN_WARNING "%s: reset off: PLX_GPIO=%x\n",
+                       printk(KERN_DEBUG "%s: reset off: PLX_GPIO=%x\n",
                                __func__, pv);
        }
 
@@ -1424,7 +1471,7 @@ controller_fail:
        hc->hw.r_irqmsk_misc |= V_TI_IRQMSK;
 
        /* set E1 state machine IRQ */
-       if (hc->type == 1)
+       if (hc->ctype == HFC_TYPE_E1)
                hc->hw.r_irqmsk_misc |= V_STA_IRQMSK;
 
        /* set DTMF detection */
@@ -1444,7 +1491,8 @@ controller_fail:
                r_conf_en = V_CONF_EN | V_ULAW;
        else
                r_conf_en = V_CONF_EN;
-       HFC_outb(hc, R_CONF_EN, r_conf_en);
+       if (hc->ctype != HFC_TYPE_XHFC)
+               HFC_outb(hc, R_CONF_EN, r_conf_en);
 
        /* setting leds */
        switch (hc->leds) {
@@ -1468,16 +1516,23 @@ controller_fail:
                break;
        }
 
+       if (test_bit(HFC_CHIP_EMBSD, &hc->chip)) {
+               hc->hw.r_st_sync = 0x10; /* V_AUTO_SYNCI */
+               HFC_outb(hc, R_ST_SYNC, hc->hw.r_st_sync);
+       }
+
        /* set master clock */
        if (hc->masterclk >= 0) {
                if (debug & DEBUG_HFCMULTI_INIT)
                        printk(KERN_DEBUG "%s: setting ST master clock "
                            "to port %d (0..%d)\n",
                            __func__, hc->masterclk, hc->ports-1);
-               hc->hw.r_st_sync = hc->masterclk | V_AUTO_SYNC;
+               hc->hw.r_st_sync |= (hc->masterclk | V_AUTO_SYNC);
                HFC_outb(hc, R_ST_SYNC, hc->hw.r_st_sync);
        }
 
+
+
        /* setting misc irq */
        HFC_outb(hc, R_IRQMSK_MISC, hc->hw.r_irqmsk_misc);
        if (debug & DEBUG_HFCMULTI_INIT)
@@ -1817,8 +1872,8 @@ hfcmulti_dtmf(struct hfc_multi *hc)
                        coeff[(co<<1)|1] = mantissa;
                }
                if (debug & DEBUG_HFCMULTI_DTMF)
-                       printk("%s: DTMF ready %08x %08x %08x %08x "
-                           "%08x %08x %08x %08x\n", __func__,
+                       printk(" DTMF ready %08x %08x %08x %08x "
+                           "%08x %08x %08x %08x\n",
                            coeff[0], coeff[1], coeff[2], coeff[3],
                            coeff[4], coeff[5], coeff[6], coeff[7]);
                hc->chan[ch].coeff_count++;
@@ -1826,7 +1881,7 @@ hfcmulti_dtmf(struct hfc_multi *hc)
                        hc->chan[ch].coeff_count = 0;
                        skb = mI_alloc_skb(512, GFP_ATOMIC);
                        if (!skb) {
-                               printk(KERN_WARNING "%s: No memory for skb\n",
+                               printk(KERN_DEBUG "%s: No memory for skb\n",
                                    __func__);
                                continue;
                        }
@@ -1929,7 +1984,7 @@ next_frame:
                                Fspace = 1;
                }
                /* one frame only for ST D-channels, to allow resending */
-               if (hc->type != 1 && dch) {
+               if (hc->ctype != HFC_TYPE_E1 && dch) {
                        if (f1 != f2)
                                Fspace = 0;
                }
@@ -1945,6 +2000,9 @@ next_frame:
                                "%d!=%d\n", __func__, hc->id + 1, temp, z2);
                z2 = temp; /* repeat unti Z2 is equal */
        }
+       hc->chan[ch].Zfill = z1 - z2;
+       if (hc->chan[ch].Zfill < 0)
+               hc->chan[ch].Zfill += hc->Zlen;
        Zspace = z2 - z1;
        if (Zspace <= 0)
                Zspace += hc->Zlen;
@@ -1968,12 +2026,22 @@ next_frame:
                                            "slot_tx %d\n",
                                            __func__, ch, slot_tx);
                                /* connect slot */
-                               HFC_outb(hc, A_CON_HDLC, 0xc0 | 0x00 |
-                                   V_HDLC_TRP | V_IFF);
+                               if (hc->ctype == HFC_TYPE_XHFC)
+                                       HFC_outb(hc, A_CON_HDLC, 0xc0
+                                           | 0x07 << 2 | V_HDLC_TRP | V_IFF);
+                                               /* Enable FIFO, no interrupt */
+                               else
+                                       HFC_outb(hc, A_CON_HDLC, 0xc0 | 0x00 |
+                                           V_HDLC_TRP | V_IFF);
                                HFC_outb_nodebug(hc, R_FIFO, ch<<1 | 1);
                                HFC_wait_nodebug(hc);
-                               HFC_outb(hc, A_CON_HDLC, 0xc0 | 0x00 |
-                                   V_HDLC_TRP | V_IFF);
+                               if (hc->ctype == HFC_TYPE_XHFC)
+                                       HFC_outb(hc, A_CON_HDLC, 0xc0
+                                           | 0x07 << 2 | V_HDLC_TRP | V_IFF);
+                                               /* Enable FIFO, no interrupt */
+                               else
+                                       HFC_outb(hc, A_CON_HDLC, 0xc0 | 0x00 |
+                                           V_HDLC_TRP | V_IFF);
                                HFC_outb_nodebug(hc, R_FIFO, ch<<1);
                                HFC_wait_nodebug(hc);
                        }
@@ -2001,10 +2069,22 @@ next_frame:
                            "FIFO data: channel %d slot_tx %d\n",
                            __func__, ch, slot_tx);
                /* disconnect slot */
-               HFC_outb(hc, A_CON_HDLC, 0x80 | 0x00 | V_HDLC_TRP | V_IFF);
+               if (hc->ctype == HFC_TYPE_XHFC)
+                       HFC_outb(hc, A_CON_HDLC, 0x80
+                           | 0x07 << 2 | V_HDLC_TRP | V_IFF);
+                               /* Enable FIFO, no interrupt */
+               else
+                       HFC_outb(hc, A_CON_HDLC, 0x80 | 0x00 |
+                           V_HDLC_TRP | V_IFF);
                HFC_outb_nodebug(hc, R_FIFO, ch<<1 | 1);
                HFC_wait_nodebug(hc);
-               HFC_outb(hc, A_CON_HDLC, 0x80 | 0x00 | V_HDLC_TRP | V_IFF);
+               if (hc->ctype == HFC_TYPE_XHFC)
+                       HFC_outb(hc, A_CON_HDLC, 0x80
+                           | 0x07 << 2 | V_HDLC_TRP | V_IFF);
+                               /* Enable FIFO, no interrupt */
+               else
+                       HFC_outb(hc, A_CON_HDLC, 0x80 | 0x00 |
+                           V_HDLC_TRP | V_IFF);
                HFC_outb_nodebug(hc, R_FIFO, ch<<1);
                HFC_wait_nodebug(hc);
        }
@@ -2027,10 +2107,11 @@ next_frame:
                printk(KERN_DEBUG "%s(card %d): fifo(%d) has %d bytes space "
                    "left (z1=%04x, z2=%04x) sending %d of %d bytes %s\n",
                        __func__, hc->id + 1, ch, Zspace, z1, z2, ii-i, len-i,
-                       temp ? "HDLC":"TRANS");
+                       temp ? "HDLC" : "TRANS");
 
        /* Have to prep the audio data */
        hc->write_fifo(hc, d, ii - i);
+       hc->chan[ch].Zfill += ii - i;
        *idxp = ii;
 
        /* if not all data has been written */
@@ -2226,7 +2307,7 @@ next_frame:
                        if (dch)
                                recv_Dchannel(dch);
                        else
-                               recv_Bchannel(bch);
+                               recv_Bchannel(bch, MISDN_ID_ANY);
                        *sp = skb;
                        again++;
                        goto next_frame;
@@ -2258,7 +2339,7 @@ next_frame:
                            "(z1=%04x, z2=%04x) TRANS\n",
                                __func__, hc->id + 1, ch, Zsize, z1, z2);
                /* only bch is transparent */
-               recv_Bchannel(bch);
+               recv_Bchannel(bch, hc->chan[ch].Zfill);
                *sp = skb;
        }
 }
@@ -2323,7 +2404,7 @@ handle_timer_irq(struct hfc_multi *hc)
                spin_unlock_irqrestore(&HFClock, flags);
        }
 
-       if (hc->type != 1 || hc->e1_state == 1)
+       if (hc->ctype != HFC_TYPE_E1 || hc->e1_state == 1)
                for (ch = 0; ch <= 31; ch++) {
                        if (hc->created[hc->chan[ch].port]) {
                                hfcmulti_tx(hc, ch);
@@ -2346,7 +2427,7 @@ handle_timer_irq(struct hfc_multi *hc)
                                }
                        }
                }
-       if (hc->type == 1 && hc->created[0]) {
+       if (hc->ctype == HFC_TYPE_E1 && hc->created[0]) {
                dch = hc->chan[hc->dslot].dch;
                if (test_bit(HFC_CFG_REPORT_LOS, &hc->chan[hc->dslot].cfg)) {
                        /* LOS */
@@ -2606,7 +2687,10 @@ hfcmulti_interrupt(int intno, void *dev_id)
                "card %d, this is no bug.\n", hc->id + 1, irqsem);
        irqsem = hc->id + 1;
 #endif
-
+#ifdef CONFIG_MISDN_HFCMULTI_8xx
+       if (hc->immap->im_cpm.cp_pbdat & hc->pb_irqmsk)
+               goto irq_notforus;
+#endif
        if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
                spin_lock_irqsave(&plx_lock, flags);
                plx_acc = hc->plx_membase + PLX_INTCSR;
@@ -2646,7 +2730,7 @@ hfcmulti_interrupt(int intno, void *dev_id)
        }
        hc->irqcnt++;
        if (r_irq_statech) {
-               if (hc->type != 1)
+               if (hc->ctype != HFC_TYPE_E1)
                        ph_state_irq(hc, r_irq_statech);
        }
        if (status & V_EXT_IRQSTA)
@@ -2660,7 +2744,7 @@ hfcmulti_interrupt(int intno, void *dev_id)
                r_irq_misc = HFC_inb_nodebug(hc, R_IRQ_MISC);
                r_irq_misc &= hc->hw.r_irqmsk_misc; /* ignore disabled irqs */
                if (r_irq_misc & V_STA_IRQ) {
-                       if (hc->type == 1) {
+                       if (hc->ctype == HFC_TYPE_E1) {
                                /* state machine */
                                dch = hc->chan[hc->dslot].dch;
                                e1_syncsta = HFC_inb_nodebug(hc, R_SYNC_STA);
@@ -2699,13 +2783,13 @@ hfcmulti_interrupt(int intno, void *dev_id)
                        handle_timer_irq(hc);
                }
 
-               if (r_irq_misc & V_DTMF_IRQ) {
+               if (r_irq_misc & V_DTMF_IRQ)
                        hfcmulti_dtmf(hc);
-               }
+
                if (r_irq_misc & V_IRQ_PROC) {
                        static int irq_proc_cnt;
                        if (!irq_proc_cnt++)
-                               printk(KERN_WARNING "%s: got V_IRQ_PROC -"
+                               printk(KERN_DEBUG "%s: got V_IRQ_PROC -"
                                    " this should not happen\n", __func__);
                }
 
@@ -2782,7 +2866,8 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx,
                if (hc->slot_owner[oslot_tx<<1] == ch) {
                        HFC_outb(hc, R_SLOT, oslot_tx << 1);
                        HFC_outb(hc, A_SL_CFG, 0);
-                       HFC_outb(hc, A_CONF, 0);
+                       if (hc->ctype != HFC_TYPE_XHFC)
+                               HFC_outb(hc, A_CONF, 0);
                        hc->slot_owner[oslot_tx<<1] = -1;
                } else {
                        if (debug & DEBUG_HFCMULTI_MODE)
@@ -2835,7 +2920,9 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx,
                            flow_tx, routing, conf);
                HFC_outb(hc, R_SLOT, slot_tx << 1);
                HFC_outb(hc, A_SL_CFG, (ch<<1) | routing);
-               HFC_outb(hc, A_CONF, (conf < 0) ? 0 : (conf | V_CONF_SL));
+               if (hc->ctype != HFC_TYPE_XHFC)
+                       HFC_outb(hc, A_CONF,
+                               (conf < 0) ? 0 : (conf | V_CONF_SL));
                hc->slot_owner[slot_tx << 1] = ch;
                hc->chan[ch].slot_tx = slot_tx;
                hc->chan[ch].bank_tx = bank_tx;
@@ -2852,7 +2939,7 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx,
                else
                        flow_rx = 0xc0; /* ST->(FIFO,PCM) */
                /* put on slot */
-               routing = bank_rx?0x80:0xc0; /* reversed */
+               routing = bank_rx ? 0x80 : 0xc0; /* reversed */
                if (conf >= 0 || bank_rx > 1)
                        routing = 0x40; /* loop */
                if (debug & DEBUG_HFCMULTI_MODE)
@@ -2885,9 +2972,9 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx,
                HFC_outb(hc, A_IRQ_MSK, 0);
                HFC_outb(hc, R_INC_RES_FIFO, V_RES_F);
                HFC_wait(hc);
-               if (hc->chan[ch].bch && hc->type != 1) {
+               if (hc->chan[ch].bch && hc->ctype != HFC_TYPE_E1) {
                        hc->hw.a_st_ctrl0[hc->chan[ch].port] &=
-                           ((ch & 0x3) == 0)? ~V_B1_EN: ~V_B2_EN;
+                           ((ch & 0x3) == 0) ? ~V_B1_EN : ~V_B2_EN;
                        HFC_outb(hc, R_ST_SEL, hc->chan[ch].port);
                        /* undocumented: delay after R_ST_SEL */
                        udelay(1);
@@ -2961,8 +3048,13 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx,
                        /* enable TX fifo */
                        HFC_outb(hc, R_FIFO, ch << 1);
                        HFC_wait(hc);
-                       HFC_outb(hc, A_CON_HDLC, flow_tx | 0x00 |
-                           V_HDLC_TRP | V_IFF);
+                       if (hc->ctype == HFC_TYPE_XHFC)
+                               HFC_outb(hc, A_CON_HDLC, flow_tx | 0x07 << 2 |
+                                       V_HDLC_TRP | V_IFF);
+                                       /* Enable FIFO, no interrupt */
+                       else
+                               HFC_outb(hc, A_CON_HDLC, flow_tx | 0x00 |
+                                       V_HDLC_TRP | V_IFF);
                        HFC_outb(hc, A_SUBCH_CFG, 0);
                        HFC_outb(hc, A_IRQ_MSK, 0);
                        HFC_outb(hc, R_INC_RES_FIFO, V_RES_F);
@@ -2972,13 +3064,19 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx,
                        /* enable RX fifo */
                        HFC_outb(hc, R_FIFO, (ch<<1)|1);
                        HFC_wait(hc);
-                       HFC_outb(hc, A_CON_HDLC, flow_rx | 0x00 | V_HDLC_TRP);
+                       if (hc->ctype == HFC_TYPE_XHFC)
+                               HFC_outb(hc, A_CON_HDLC, flow_rx | 0x07 << 2 |
+                                       V_HDLC_TRP);
+                                       /* Enable FIFO, no interrupt*/
+                       else
+                               HFC_outb(hc, A_CON_HDLC, flow_rx | 0x00 |
+                                               V_HDLC_TRP);
                        HFC_outb(hc, A_SUBCH_CFG, 0);
                        HFC_outb(hc, A_IRQ_MSK, 0);
                        HFC_outb(hc, R_INC_RES_FIFO, V_RES_F);
                        HFC_wait(hc);
                }
-               if (hc->type != 1) {
+               if (hc->ctype != HFC_TYPE_E1) {
                        hc->hw.a_st_ctrl0[hc->chan[ch].port] |=
                            ((ch & 0x3) == 0) ? V_B1_EN : V_B2_EN;
                        HFC_outb(hc, R_ST_SEL, hc->chan[ch].port);
@@ -2999,7 +3097,7 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx,
                /* enable TX fifo */
                HFC_outb(hc, R_FIFO, ch<<1);
                HFC_wait(hc);
-               if (hc->type == 1 || hc->chan[ch].bch) {
+               if (hc->ctype == HFC_TYPE_E1 || hc->chan[ch].bch) {
                        /* E1 or B-channel */
                        HFC_outb(hc, A_CON_HDLC, flow_tx | 0x04);
                        HFC_outb(hc, A_SUBCH_CFG, 0);
@@ -3015,7 +3113,7 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx,
                HFC_outb(hc, R_FIFO, (ch<<1)|1);
                HFC_wait(hc);
                HFC_outb(hc, A_CON_HDLC, flow_rx | 0x04);
-               if (hc->type == 1 || hc->chan[ch].bch)
+               if (hc->ctype == HFC_TYPE_E1 || hc->chan[ch].bch)
                        HFC_outb(hc, A_SUBCH_CFG, 0); /* full 8 bits */
                else
                        HFC_outb(hc, A_SUBCH_CFG, 2); /* 2 bits dchannel */
@@ -3024,7 +3122,7 @@ mode_hfcmulti(struct hfc_multi *hc, int ch, int protocol, int slot_tx,
                HFC_wait(hc);
                if (hc->chan[ch].bch) {
                        test_and_set_bit(FLG_HDLC, &hc->chan[ch].bch->Flags);
-                       if (hc->type != 1) {
+                       if (hc->ctype != HFC_TYPE_E1) {
                                hc->hw.a_st_ctrl0[hc->chan[ch].port] |=
                                  ((ch&0x3) == 0) ? V_B1_EN : V_B2_EN;
                                HFC_outb(hc, R_ST_SEL, hc->chan[ch].port);
@@ -3104,7 +3202,7 @@ hfcm_l1callback(struct dchannel *dch, u_int cmd)
        case HW_RESET_REQ:
                /* start activation */
                spin_lock_irqsave(&hc->lock, flags);
-               if (hc->type == 1) {
+               if (hc->ctype == HFC_TYPE_E1) {
                        if (debug & DEBUG_HFCMULTI_MSG)
                                printk(KERN_DEBUG
                                    "%s: HW_RESET_REQ no BRI\n",
@@ -3125,7 +3223,7 @@ hfcm_l1callback(struct dchannel *dch, u_int cmd)
        case HW_DEACT_REQ:
                /* start deactivation */
                spin_lock_irqsave(&hc->lock, flags);
-               if (hc->type == 1) {
+               if (hc->ctype == HFC_TYPE_E1) {
                        if (debug & DEBUG_HFCMULTI_MSG)
                                printk(KERN_DEBUG
                                    "%s: HW_DEACT_REQ no BRI\n",
@@ -3159,7 +3257,7 @@ hfcm_l1callback(struct dchannel *dch, u_int cmd)
                break;
        case HW_POWERUP_REQ:
                spin_lock_irqsave(&hc->lock, flags);
-               if (hc->type == 1) {
+               if (hc->ctype == HFC_TYPE_E1) {
                        if (debug & DEBUG_HFCMULTI_MSG)
                                printk(KERN_DEBUG
                                    "%s: HW_POWERUP_REQ no BRI\n",
@@ -3236,7 +3334,7 @@ handle_dmsg(struct mISDNchannel *ch, struct sk_buff *skb)
                                    __func__, hc->chan[dch->slot].port,
                                    hc->ports-1);
                        /* start activation */
-                       if (hc->type == 1) {
+                       if (hc->ctype == HFC_TYPE_E1) {
                                ph_state_change(dch);
                                if (debug & DEBUG_HFCMULTI_STATE)
                                        printk(KERN_DEBUG
@@ -3269,7 +3367,7 @@ handle_dmsg(struct mISDNchannel *ch, struct sk_buff *skb)
                                    __func__, hc->chan[dch->slot].port,
                                    hc->ports-1);
                        /* start deactivation */
-                       if (hc->type == 1) {
+                       if (hc->ctype == HFC_TYPE_E1) {
                                if (debug & DEBUG_HFCMULTI_MSG)
                                        printk(KERN_DEBUG
                                            "%s: PH_DEACTIVATE no BRI\n",
@@ -3410,9 +3508,9 @@ handle_bmsg(struct mISDNchannel *ch, struct sk_buff *skb)
                switch (hh->id) {
                case HFC_SPL_LOOP_ON: /* set sample loop */
                        if (debug & DEBUG_HFCMULTI_MSG)
-                       printk(KERN_DEBUG
-                           "%s: HFC_SPL_LOOP_ON (len = %d)\n",
-                           __func__, skb->len);
+                               printk(KERN_DEBUG
+                                   "%s: HFC_SPL_LOOP_ON (len = %d)\n",
+                                   __func__, skb->len);
                        ret = 0;
                        break;
                case HFC_SPL_LOOP_OFF: /* set silence */
@@ -3489,6 +3587,8 @@ channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
                features->hfc_id = hc->id;
                if (test_bit(HFC_CHIP_DTMF, &hc->chip))
                        features->hfc_dtmf = 1;
+               if (test_bit(HFC_CHIP_CONF, &hc->chip))
+                       features->hfc_conf = 1;
                features->hfc_loops = 0;
                if (test_bit(HFC_CHIP_B410P, &hc->chip)) {
                        features->hfc_echocanhw = 1;
@@ -3619,14 +3719,13 @@ ph_state_change(struct dchannel *dch)
        int ch, i;
 
        if (!dch) {
-               printk(KERN_WARNING "%s: ERROR given dch is NULL\n",
-                   __func__);
+               printk(KERN_WARNING "%s: ERROR given dch is NULL\n", __func__);
                return;
        }
        hc = dch->hw;
        ch = dch->slot;
 
-       if (hc->type == 1) {
+       if (hc->ctype == HFC_TYPE_E1) {
                if (dch->dev.D.protocol == ISDN_P_TE_E1) {
                        if (debug & DEBUG_HFCMULTI_STATE)
                                printk(KERN_DEBUG
@@ -3641,14 +3740,15 @@ ph_state_change(struct dchannel *dch)
                switch (dch->state) {
                case (1):
                        if (hc->e1_state != 1) {
-                           for (i = 1; i <= 31; i++) {
-                               /* reset fifos on e1 activation */
-                               HFC_outb_nodebug(hc, R_FIFO, (i << 1) | 1);
-                               HFC_wait_nodebug(hc);
-                               HFC_outb_nodebug(hc,
-                                       R_INC_RES_FIFO, V_RES_F);
-                               HFC_wait_nodebug(hc);
-                           }
+                               for (i = 1; i <= 31; i++) {
+                                       /* reset fifos on e1 activation */
+                                       HFC_outb_nodebug(hc, R_FIFO,
+                                               (i << 1) | 1);
+                                       HFC_wait_nodebug(hc);
+                                       HFC_outb_nodebug(hc, R_INC_RES_FIFO,
+                                               V_RES_F);
+                                       HFC_wait_nodebug(hc);
+                               }
                        }
                        test_and_set_bit(FLG_ACTIVE, &dch->Flags);
                        _queue_data(&dch->dev.D, PH_ACTIVATE_IND,
@@ -3751,7 +3851,7 @@ hfcmulti_initmode(struct dchannel *dch)
        if (debug & DEBUG_HFCMULTI_INIT)
                printk(KERN_DEBUG "%s: entered\n", __func__);
 
-       if (hc->type == 1) {
+       if (hc->ctype == HFC_TYPE_E1) {
                hc->chan[hc->dslot].slot_tx = -1;
                hc->chan[hc->dslot].slot_rx = -1;
                hc->chan[hc->dslot].conf = -1;
@@ -3900,6 +4000,11 @@ hfcmulti_initmode(struct dchannel *dch)
                }
                if (!test_bit(HFC_CFG_NONCAP_TX, &hc->chan[i].cfg))
                        hc->hw.a_st_ctrl0[pt] |= V_TX_LI;
+               if (hc->ctype == HFC_TYPE_XHFC) {
+                       hc->hw.a_st_ctrl0[pt] |= 0x40 /* V_ST_PU_CTRL */;
+                       HFC_outb(hc, 0x35 /* A_ST_CTRL3 */,
+                               0x7c << 1 /* V_ST_PULSE */);
+               }
                /* line setup */
                HFC_outb(hc, A_ST_CTRL0,  hc->hw.a_st_ctrl0[pt]);
                /* disable E-channel */
@@ -3943,12 +4048,12 @@ open_dchannel(struct hfc_multi *hc, struct dchannel *dch,
                return -EINVAL;
        if ((dch->dev.D.protocol != ISDN_P_NONE) &&
            (dch->dev.D.protocol != rq->protocol)) {
-           if (debug & DEBUG_HFCMULTI_MODE)
-               printk(KERN_WARNING "%s: change protocol %x to %x\n",
-                   __func__, dch->dev.D.protocol, rq->protocol);
+               if (debug & DEBUG_HFCMULTI_MODE)
+                       printk(KERN_DEBUG "%s: change protocol %x to %x\n",
+                           __func__, dch->dev.D.protocol, rq->protocol);
        }
-       if ((dch->dev.D.protocol == ISDN_P_TE_S0)
-        && (rq->protocol != ISDN_P_TE_S0))
+       if ((dch->dev.D.protocol == ISDN_P_TE_S0) &&
+           (rq->protocol != ISDN_P_TE_S0))
                l1_event(dch->l1, CLOSE_CHANNEL);
        if (dch->dev.D.protocol != rq->protocol) {
                if (rq->protocol == ISDN_P_TE_S0) {
@@ -3986,7 +4091,7 @@ open_bchannel(struct hfc_multi *hc, struct dchannel *dch,
                return -EINVAL;
        if (rq->protocol == ISDN_P_NONE)
                return -EINVAL;
-       if (hc->type == 1)
+       if (hc->ctype == HFC_TYPE_E1)
                ch = rq->adr.channel;
        else
                ch = (rq->adr.channel - 1) + (dch->slot - 2);
@@ -4013,11 +4118,41 @@ open_bchannel(struct hfc_multi *hc, struct dchannel *dch,
 static int
 channel_dctrl(struct dchannel *dch, struct mISDN_ctrl_req *cq)
 {
+       struct hfc_multi        *hc = dch->hw;
        int     ret = 0;
+       int     wd_mode, wd_cnt;
 
        switch (cq->op) {
        case MISDN_CTRL_GETOP:
-               cq->op = 0;
+               cq->op = MISDN_CTRL_HFC_OP;
+               break;
+       case MISDN_CTRL_HFC_WD_INIT: /* init the watchdog */
+               wd_cnt = cq->p1 & 0xf;
+               wd_mode = !!(cq->p1 >> 4);
+               if (debug & DEBUG_HFCMULTI_MSG)
+                       printk(KERN_DEBUG "%s: MISDN_CTRL_HFC_WD_INIT mode %s"
+                           ", counter 0x%x\n", __func__,
+                           wd_mode ? "AUTO" : "MANUAL", wd_cnt);
+               /* set the watchdog timer */
+               HFC_outb(hc, R_TI_WD, poll_timer | (wd_cnt << 4));
+               hc->hw.r_bert_wd_md = (wd_mode ? V_AUTO_WD_RES : 0);
+               if (hc->ctype == HFC_TYPE_XHFC)
+                       hc->hw.r_bert_wd_md |= 0x40 /* V_WD_EN */;
+               /* init the watchdog register and reset the counter */
+               HFC_outb(hc, R_BERT_WD_MD, hc->hw.r_bert_wd_md | V_WD_RES);
+               if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
+                       /* enable the watchdog output for Speech-Design */
+                       HFC_outb(hc, R_GPIO_SEL,  V_GPIO_SEL7);
+                       HFC_outb(hc, R_GPIO_EN1,  V_GPIO_EN15);
+                       HFC_outb(hc, R_GPIO_OUT1, 0);
+                       HFC_outb(hc, R_GPIO_OUT1, V_GPIO_OUT15);
+               }
+               break;
+       case MISDN_CTRL_HFC_WD_RESET: /* reset the watchdog counter */
+               if (debug & DEBUG_HFCMULTI_MSG)
+                       printk(KERN_DEBUG "%s: MISDN_CTRL_HFC_WD_RESET\n",
+                           __func__);
+               HFC_outb(hc, R_BERT_WD_MD, hc->hw.r_bert_wd_md | V_WD_RES);
                break;
        default:
                printk(KERN_WARNING "%s: unknown Op %x\n",
@@ -4047,7 +4182,7 @@ hfcm_dctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
                switch (rq->protocol) {
                case ISDN_P_TE_S0:
                case ISDN_P_NT_S0:
-                       if (hc->type == 1) {
+                       if (hc->ctype == HFC_TYPE_E1) {
                                err = -EINVAL;
                                break;
                        }
@@ -4055,7 +4190,7 @@ hfcm_dctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
                        break;
                case ISDN_P_TE_E1:
                case ISDN_P_NT_E1:
-                       if (hc->type != 1) {
+                       if (hc->ctype != HFC_TYPE_E1) {
                                err = -EINVAL;
                                break;
                        }
@@ -4122,13 +4257,13 @@ init_card(struct hfc_multi *hc)
        disable_hwirq(hc);
        spin_unlock_irqrestore(&hc->lock, flags);
 
-       if (request_irq(hc->pci_dev->irq, hfcmulti_interrupt, IRQF_SHARED,
+       if (request_irq(hc->irq, hfcmulti_interrupt, IRQF_SHARED,
            "HFC-multi", hc)) {
                printk(KERN_WARNING "mISDN: Could not get interrupt %d.\n",
-                   hc->pci_dev->irq);
+                   hc->irq);
+               hc->irq = 0;
                return -EIO;
        }
-       hc->irq = hc->pci_dev->irq;
 
        if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
                spin_lock_irqsave(&plx_lock, plx_flags);
@@ -4187,7 +4322,7 @@ error:
        }
 
        if (debug & DEBUG_HFCMULTI_INIT)
-               printk(KERN_WARNING "%s: free irq %d\n", __func__, hc->irq);
+               printk(KERN_DEBUG "%s: free irq %d\n", __func__, hc->irq);
        if (hc->irq) {
                free_irq(hc->irq, hc);
                hc->irq = 0;
@@ -4235,6 +4370,10 @@ setup_pci(struct hfc_multi *hc, struct pci_dev *pdev,
        hc->ledstate = 0xAFFEAFFE;
        hc->opticalsupport = m->opticalsupport;
 
+       hc->pci_iobase = 0;
+       hc->pci_membase = NULL;
+       hc->plx_membase = NULL;
+
        /* set memory access methods */
        if (m->io_mode) /* use mode from card config */
                hc->io_mode = m->io_mode;
@@ -4242,44 +4381,12 @@ setup_pci(struct hfc_multi *hc, struct pci_dev *pdev,
        case HFC_IO_MODE_PLXSD:
                test_and_set_bit(HFC_CHIP_PLXSD, &hc->chip);
                hc->slots = 128; /* required */
-               /* fall through */
-       case HFC_IO_MODE_PCIMEM:
                hc->HFC_outb = HFC_outb_pcimem;
                hc->HFC_inb = HFC_inb_pcimem;
                hc->HFC_inw = HFC_inw_pcimem;
                hc->HFC_wait = HFC_wait_pcimem;
                hc->read_fifo = read_fifo_pcimem;
                hc->write_fifo = write_fifo_pcimem;
-               break;
-       case HFC_IO_MODE_REGIO:
-               hc->HFC_outb = HFC_outb_regio;
-               hc->HFC_inb = HFC_inb_regio;
-               hc->HFC_inw = HFC_inw_regio;
-               hc->HFC_wait = HFC_wait_regio;
-               hc->read_fifo = read_fifo_regio;
-               hc->write_fifo = write_fifo_regio;
-               break;
-       default:
-               printk(KERN_WARNING "HFC-multi: Invalid IO mode.\n");
-               pci_disable_device(hc->pci_dev);
-               return -EIO;
-       }
-       hc->HFC_outb_nodebug = hc->HFC_outb;
-       hc->HFC_inb_nodebug = hc->HFC_inb;
-       hc->HFC_inw_nodebug = hc->HFC_inw;
-       hc->HFC_wait_nodebug = hc->HFC_wait;
-#ifdef HFC_REGISTER_DEBUG
-       hc->HFC_outb = HFC_outb_debug;
-       hc->HFC_inb = HFC_inb_debug;
-       hc->HFC_inw = HFC_inw_debug;
-       hc->HFC_wait = HFC_wait_debug;
-#endif
-       hc->pci_iobase = 0;
-       hc->pci_membase = NULL;
-       hc->plx_membase = NULL;
-
-       switch (hc->io_mode) {
-       case HFC_IO_MODE_PLXSD:
                hc->plx_origmembase =  hc->pci_dev->resource[0].start;
                /* MEMBASE 1 is PLX PCI Bridge */
 
@@ -4327,6 +4434,12 @@ setup_pci(struct hfc_multi *hc, struct pci_dev *pdev,
                pci_write_config_word(hc->pci_dev, PCI_COMMAND, PCI_ENA_MEMIO);
                break;
        case HFC_IO_MODE_PCIMEM:
+               hc->HFC_outb = HFC_outb_pcimem;
+               hc->HFC_inb = HFC_inb_pcimem;
+               hc->HFC_inw = HFC_inw_pcimem;
+               hc->HFC_wait = HFC_wait_pcimem;
+               hc->read_fifo = read_fifo_pcimem;
+               hc->write_fifo = write_fifo_pcimem;
                hc->pci_origmembase = hc->pci_dev->resource[1].start;
                if (!hc->pci_origmembase) {
                        printk(KERN_WARNING
@@ -4343,12 +4456,18 @@ setup_pci(struct hfc_multi *hc, struct pci_dev *pdev,
                        pci_disable_device(hc->pci_dev);
                        return -EIO;
                }
-               printk(KERN_INFO "card %d: defined at MEMBASE %#lx (%#lx) IRQ %d "
-                   "HZ %d leds-type %d\n", hc->id, (u_long)hc->pci_membase,
+               printk(KERN_INFO "card %d: defined at MEMBASE %#lx (%#lx) IRQ "
+                   "%d HZ %d leds-type %d\n", hc->id, (u_long)hc->pci_membase,
                    hc->pci_origmembase, hc->pci_dev->irq, HZ, hc->leds);
                pci_write_config_word(hc->pci_dev, PCI_COMMAND, PCI_ENA_MEMIO);
                break;
        case HFC_IO_MODE_REGIO:
+               hc->HFC_outb = HFC_outb_regio;
+               hc->HFC_inb = HFC_inb_regio;
+               hc->HFC_inw = HFC_inw_regio;
+               hc->HFC_wait = HFC_wait_regio;
+               hc->read_fifo = read_fifo_regio;
+               hc->write_fifo = write_fifo_regio;
                hc->pci_iobase = (u_int) hc->pci_dev->resource[0].start;
                if (!hc->pci_iobase) {
                        printk(KERN_WARNING
@@ -4430,7 +4549,7 @@ release_port(struct hfc_multi *hc, struct dchannel *dch)
                dch->timer.function = NULL;
        }
 
-       if (hc->type == 1) { /* E1 */
+       if (hc->ctype == HFC_TYPE_E1) { /* E1 */
                /* remove sync */
                if (test_bit(HFC_CHIP_PLXSD, &hc->chip)) {
                        hc->syncronized = 0;
@@ -4508,7 +4627,7 @@ release_card(struct hfc_multi *hc)
        int     ch;
 
        if (debug & DEBUG_HFCMULTI_INIT)
-               printk(KERN_WARNING "%s: release card (%d) entered\n",
+               printk(KERN_DEBUG "%s: release card (%d) entered\n",
                    __func__, hc->id);
 
        /* unregister clock source */
@@ -4537,7 +4656,7 @@ release_card(struct hfc_multi *hc)
        /* release hardware & irq */
        if (hc->irq) {
                if (debug & DEBUG_HFCMULTI_INIT)
-                       printk(KERN_WARNING "%s: free irq %d\n",
+                       printk(KERN_DEBUG "%s: free irq %d\n",
                            __func__, hc->irq);
                free_irq(hc->irq, hc);
                hc->irq = 0;
@@ -4546,17 +4665,17 @@ release_card(struct hfc_multi *hc)
        release_io_hfcmulti(hc);
 
        if (debug & DEBUG_HFCMULTI_INIT)
-               printk(KERN_WARNING "%s: remove instance from list\n",
+               printk(KERN_DEBUG "%s: remove instance from list\n",
                     __func__);
        list_del(&hc->list);
 
        if (debug & DEBUG_HFCMULTI_INIT)
-               printk(KERN_WARNING "%s: delete instance\n", __func__);
+               printk(KERN_DEBUG "%s: delete instance\n", __func__);
        if (hc == syncmaster)
                syncmaster = NULL;
        kfree(hc);
        if (debug & DEBUG_HFCMULTI_INIT)
-               printk(KERN_WARNING "%s: card successfully removed\n",
+               printk(KERN_DEBUG "%s: card successfully removed\n",
                    __func__);
 }
 
@@ -4579,7 +4698,7 @@ init_e1_port(struct hfc_multi *hc, struct hm_map *m)
            (1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));
        dch->dev.D.send = handle_dmsg;
        dch->dev.D.ctrl = hfcm_dctrl;
-       dch->dev.nrbchan = (hc->dslot)?30:31;
+       dch->dev.nrbchan = (hc->dslot) ? 30 : 31;
        dch->slot = hc->dslot;
        hc->chan[hc->dslot].dch = dch;
        hc->chan[hc->dslot].port = 0;
@@ -4821,7 +4940,7 @@ init_multi_port(struct hfc_multi *hc, int pt)
        }
        /* disable E-channel */
        if (port[Port_cnt] & 0x004) {
-       if (debug & DEBUG_HFCMULTI_INIT)
+               if (debug & DEBUG_HFCMULTI_INIT)
                        printk(KERN_DEBUG
                            "%s: PROTOCOL disable E-channel: "
                            "card(%d) port(%d)\n",
@@ -4829,9 +4948,15 @@ init_multi_port(struct hfc_multi *hc, int pt)
                test_and_set_bit(HFC_CFG_DIS_ECHANNEL,
                    &hc->chan[i + 2].cfg);
        }
-       snprintf(name, MISDN_MAX_IDLEN - 1, "hfc-%ds.%d-%d",
-               hc->type, HFC_cnt + 1, pt + 1);
-       ret = mISDN_register_device(&dch->dev, &hc->pci_dev->dev, name);
+       if (hc->ctype == HFC_TYPE_XHFC) {
+               snprintf(name, MISDN_MAX_IDLEN - 1, "xhfc.%d-%d",
+                       HFC_cnt + 1, pt + 1);
+               ret = mISDN_register_device(&dch->dev, NULL, name);
+       } else {
+               snprintf(name, MISDN_MAX_IDLEN - 1, "hfc-%ds.%d-%d",
+                       hc->ctype, HFC_cnt + 1, pt + 1);
+               ret = mISDN_register_device(&dch->dev, &hc->pci_dev->dev, name);
+       }
        if (ret)
                goto free_chan;
        hc->created[pt] = 1;
@@ -4842,9 +4967,9 @@ free_chan:
 }
 
 static int
-hfcmulti_init(struct pci_dev *pdev, const struct pci_device_id *ent)
+hfcmulti_init(struct hm_map *m, struct pci_dev *pdev,
+    const struct pci_device_id *ent)
 {
-       struct hm_map   *m = (struct hm_map *)ent->driver_data;
        int             ret_err = 0;
        int             pt;
        struct hfc_multi        *hc;
@@ -4879,16 +5004,18 @@ hfcmulti_init(struct pci_dev *pdev, const struct pci_device_id *ent)
        }
        spin_lock_init(&hc->lock);
        hc->mtyp = m;
-       hc->type =  m->type;
+       hc->ctype =  m->type;
        hc->ports = m->ports;
        hc->id = HFC_cnt;
        hc->pcm = pcm[HFC_cnt];
        hc->io_mode = iomode[HFC_cnt];
-       if (dslot[HFC_cnt] < 0 && hc->type == 1) {
+       if (dslot[HFC_cnt] < 0 && hc->ctype == HFC_TYPE_E1) {
                hc->dslot = 0;
                printk(KERN_INFO "HFC-E1 card has disabled D-channel, but "
                        "31 B-channels\n");
-       } if (dslot[HFC_cnt] > 0 && dslot[HFC_cnt] < 32 && hc->type == 1) {
+       }
+       if (dslot[HFC_cnt] > 0 && dslot[HFC_cnt] < 32
+           && hc->ctype == HFC_TYPE_E1) {
                hc->dslot = dslot[HFC_cnt];
                printk(KERN_INFO "HFC-E1 card has alternating D-channel on "
                        "time slot %d\n", dslot[HFC_cnt]);
@@ -4910,8 +5037,11 @@ hfcmulti_init(struct pci_dev *pdev, const struct pci_device_id *ent)
        for (i = 0; i < (poll >> 1); i++)
                hc->silence_data[i] = hc->silence;
 
-       if (!(type[HFC_cnt] & 0x200))
-               test_and_set_bit(HFC_CHIP_DTMF, &hc->chip);
+       if (hc->ctype != HFC_TYPE_XHFC) {
+               if (!(type[HFC_cnt] & 0x200))
+                       test_and_set_bit(HFC_CHIP_DTMF, &hc->chip);
+               test_and_set_bit(HFC_CHIP_CONF, &hc->chip);
+       }
 
        if (type[HFC_cnt] & 0x800)
                test_and_set_bit(HFC_CHIP_PCM_SLAVE, &hc->chip);
@@ -4935,8 +5065,18 @@ hfcmulti_init(struct pci_dev *pdev, const struct pci_device_id *ent)
                printk(KERN_NOTICE "Watchdog enabled\n");
        }
 
-       /* setup pci, hc->slots may change due to PLXSD */
-       ret_err = setup_pci(hc, pdev, ent);
+       if (pdev && ent)
+               /* setup pci, hc->slots may change due to PLXSD */
+               ret_err = setup_pci(hc, pdev, ent);
+       else
+#ifdef CONFIG_MISDN_HFCMULTI_8xx
+               ret_err = setup_embedded(hc, m);
+#else
+       {
+               printk(KERN_WARNING "Embedded IO Mode not selected\n");
+               ret_err = -EIO;
+       }
+#endif
        if (ret_err) {
                if (hc == syncmaster)
                        syncmaster = NULL;
@@ -4944,7 +5084,17 @@ hfcmulti_init(struct pci_dev *pdev, const struct pci_device_id *ent)
                return ret_err;
        }
 
-       /* crate channels */
+       hc->HFC_outb_nodebug = hc->HFC_outb;
+       hc->HFC_inb_nodebug = hc->HFC_inb;
+       hc->HFC_inw_nodebug = hc->HFC_inw;
+       hc->HFC_wait_nodebug = hc->HFC_wait;
+#ifdef HFC_REGISTER_DEBUG
+       hc->HFC_outb = HFC_outb_debug;
+       hc->HFC_inb = HFC_inb_debug;
+       hc->HFC_inw = HFC_inw_debug;
+       hc->HFC_wait = HFC_wait_debug;
+#endif
+       /* create channels */
        for (pt = 0; pt < hc->ports; pt++) {
                if (Port_cnt >= MAX_PORTS) {
                        printk(KERN_ERR "too many ports (max=%d).\n",
@@ -4952,7 +5102,7 @@ hfcmulti_init(struct pci_dev *pdev, const struct pci_device_id *ent)
                        ret_err = -EINVAL;
                        goto free_card;
                }
-               if (hc->type == 1)
+               if (hc->ctype == HFC_TYPE_E1)
                        ret_err = init_e1_port(hc, m);
                else
                        ret_err = init_multi_port(hc, pt);
@@ -5036,6 +5186,7 @@ hfcmulti_init(struct pci_dev *pdev, const struct pci_device_id *ent)
                hc->iclock = mISDN_register_clock("HFCMulti", 0, clockctl, hc);
 
        /* initialize hardware */
+       hc->irq = (m->irq) ? : hc->pci_dev->irq;
        ret_err = init_card(hc);
        if (ret_err) {
                printk(KERN_ERR "init card returns %d\n", ret_err);
@@ -5074,7 +5225,7 @@ static void __devexit hfc_remove_pci(struct pci_dev *pdev)
                spin_unlock_irqrestore(&HFClock, flags);
        }  else {
                if (debug)
-                       printk(KERN_WARNING "%s: drvdata allready removed\n",
+                       printk(KERN_DEBUG "%s: drvdata allready removed\n",
                            __func__);
        }
 }
@@ -5086,45 +5237,48 @@ static void __devexit hfc_remove_pci(struct pci_dev *pdev)
 #define VENDOR_PRIM    "PrimuX"
 
 static const struct hm_map hfcm_map[] = {
-/*0*/  {VENDOR_BN, "HFC-1S Card (mini PCI)", 4, 1, 1, 3, 0, DIP_4S, 0},
-/*1*/  {VENDOR_BN, "HFC-2S Card", 4, 2, 1, 3, 0, DIP_4S, 0},
-/*2*/  {VENDOR_BN, "HFC-2S Card (mini PCI)", 4, 2, 1, 3, 0, DIP_4S, 0},
-/*3*/  {VENDOR_BN, "HFC-4S Card", 4, 4, 1, 2, 0, DIP_4S, 0},
-/*4*/  {VENDOR_BN, "HFC-4S Card (mini PCI)", 4, 4, 1, 2, 0, 0, 0},
-/*5*/  {VENDOR_CCD, "HFC-4S Eval (old)", 4, 4, 0, 0, 0, 0, 0},
-/*6*/  {VENDOR_CCD, "HFC-4S IOB4ST", 4, 4, 1, 2, 0, DIP_4S, 0},
-/*7*/  {VENDOR_CCD, "HFC-4S", 4, 4, 1, 2, 0, 0, 0},
-/*8*/  {VENDOR_DIG, "HFC-4S Card", 4, 4, 0, 2, 0, 0, HFC_IO_MODE_REGIO},
-/*9*/  {VENDOR_CCD, "HFC-4S Swyx 4xS0 SX2 QuadBri", 4, 4, 1, 2, 0, 0, 0},
-/*10*/ {VENDOR_JH, "HFC-4S (junghanns 2.0)", 4, 4, 1, 2, 0, 0, 0},
-/*11*/ {VENDOR_PRIM, "HFC-2S Primux Card", 4, 2, 0, 0, 0, 0, 0},
-
-/*12*/ {VENDOR_BN, "HFC-8S Card", 8, 8, 1, 0, 0, 0, 0},
+/*0*/  {VENDOR_BN, "HFC-1S Card (mini PCI)", 4, 1, 1, 3, 0, DIP_4S, 0, 0},
+/*1*/  {VENDOR_BN, "HFC-2S Card", 4, 2, 1, 3, 0, DIP_4S, 0, 0},
+/*2*/  {VENDOR_BN, "HFC-2S Card (mini PCI)", 4, 2, 1, 3, 0, DIP_4S, 0, 0},
+/*3*/  {VENDOR_BN, "HFC-4S Card", 4, 4, 1, 2, 0, DIP_4S, 0, 0},
+/*4*/  {VENDOR_BN, "HFC-4S Card (mini PCI)", 4, 4, 1, 2, 0, 0, 0, 0},
+/*5*/  {VENDOR_CCD, "HFC-4S Eval (old)", 4, 4, 0, 0, 0, 0, 0, 0},
+/*6*/  {VENDOR_CCD, "HFC-4S IOB4ST", 4, 4, 1, 2, 0, DIP_4S, 0, 0},
+/*7*/  {VENDOR_CCD, "HFC-4S", 4, 4, 1, 2, 0, 0, 0, 0},
+/*8*/  {VENDOR_DIG, "HFC-4S Card", 4, 4, 0, 2, 0, 0, HFC_IO_MODE_REGIO, 0},
+/*9*/  {VENDOR_CCD, "HFC-4S Swyx 4xS0 SX2 QuadBri", 4, 4, 1, 2, 0, 0, 0, 0},
+/*10*/ {VENDOR_JH, "HFC-4S (junghanns 2.0)", 4, 4, 1, 2, 0, 0, 0, 0},
+/*11*/ {VENDOR_PRIM, "HFC-2S Primux Card", 4, 2, 0, 0, 0, 0, 0, 0},
+
+/*12*/ {VENDOR_BN, "HFC-8S Card", 8, 8, 1, 0, 0, 0, 0, 0},
 /*13*/ {VENDOR_BN, "HFC-8S Card (+)", 8, 8, 1, 8, 0, DIP_8S,
-               HFC_IO_MODE_REGIO},
-/*14*/ {VENDOR_CCD, "HFC-8S Eval (old)", 8, 8, 0, 0, 0, 0, 0},
-/*15*/ {VENDOR_CCD, "HFC-8S IOB4ST Recording", 8, 8, 1, 0, 0, 0, 0},
+               HFC_IO_MODE_REGIO, 0},
+/*14*/ {VENDOR_CCD, "HFC-8S Eval (old)", 8, 8, 0, 0, 0, 0, 0, 0},
+/*15*/ {VENDOR_CCD, "HFC-8S IOB4ST Recording", 8, 8, 1, 0, 0, 0, 0, 0},
 
-/*16*/ {VENDOR_CCD, "HFC-8S IOB8ST", 8, 8, 1, 0, 0, 0, 0},
-/*17*/ {VENDOR_CCD, "HFC-8S", 8, 8, 1, 0, 0, 0, 0},
-/*18*/ {VENDOR_CCD, "HFC-8S", 8, 8, 1, 0, 0, 0, 0},
+/*16*/ {VENDOR_CCD, "HFC-8S IOB8ST", 8, 8, 1, 0, 0, 0, 0, 0},
+/*17*/ {VENDOR_CCD, "HFC-8S", 8, 8, 1, 0, 0, 0, 0, 0},
+/*18*/ {VENDOR_CCD, "HFC-8S", 8, 8, 1, 0, 0, 0, 0, 0},
 
-/*19*/ {VENDOR_BN, "HFC-E1 Card", 1, 1, 0, 1, 0, DIP_E1, 0},
-/*20*/ {VENDOR_BN, "HFC-E1 Card (mini PCI)", 1, 1, 0, 1, 0, 0, 0},
-/*21*/ {VENDOR_BN, "HFC-E1+ Card (Dual)", 1, 1, 0, 1, 0, DIP_E1, 0},
-/*22*/ {VENDOR_BN, "HFC-E1 Card (Dual)", 1, 1, 0, 1, 0, DIP_E1, 0},
+/*19*/ {VENDOR_BN, "HFC-E1 Card", 1, 1, 0, 1, 0, DIP_E1, 0, 0},
+/*20*/ {VENDOR_BN, "HFC-E1 Card (mini PCI)", 1, 1, 0, 1, 0, 0, 0, 0},
+/*21*/ {VENDOR_BN, "HFC-E1+ Card (Dual)", 1, 1, 0, 1, 0, DIP_E1, 0, 0},
+/*22*/ {VENDOR_BN, "HFC-E1 Card (Dual)", 1, 1, 0, 1, 0, DIP_E1, 0, 0},
 
-/*23*/ {VENDOR_CCD, "HFC-E1 Eval (old)", 1, 1, 0, 0, 0, 0, 0},
-/*24*/ {VENDOR_CCD, "HFC-E1 IOB1E1", 1, 1, 0, 1, 0, 0, 0},
-/*25*/ {VENDOR_CCD, "HFC-E1", 1, 1, 0, 1, 0, 0, 0},
+/*23*/ {VENDOR_CCD, "HFC-E1 Eval (old)", 1, 1, 0, 0, 0, 0, 0, 0},
+/*24*/ {VENDOR_CCD, "HFC-E1 IOB1E1", 1, 1, 0, 1, 0, 0, 0, 0},
+/*25*/ {VENDOR_CCD, "HFC-E1", 1, 1, 0, 1, 0, 0, 0, 0},
 
 /*26*/ {VENDOR_CCD, "HFC-4S Speech Design", 4, 4, 0, 0, 0, 0,
-               HFC_IO_MODE_PLXSD},
+               HFC_IO_MODE_PLXSD, 0},
 /*27*/ {VENDOR_CCD, "HFC-E1 Speech Design", 1, 1, 0, 0, 0, 0,
-               HFC_IO_MODE_PLXSD},
-/*28*/ {VENDOR_CCD, "HFC-4S OpenVox", 4, 4, 1, 0, 0, 0, 0},
-/*29*/ {VENDOR_CCD, "HFC-2S OpenVox", 4, 2, 1, 0, 0, 0, 0},
-/*30*/ {VENDOR_CCD, "HFC-8S OpenVox", 8, 8, 1, 0, 0, 0, 0},
+               HFC_IO_MODE_PLXSD, 0},
+/*28*/ {VENDOR_CCD, "HFC-4S OpenVox", 4, 4, 1, 0, 0, 0, 0, 0},
+/*29*/ {VENDOR_CCD, "HFC-2S OpenVox", 4, 2, 1, 0, 0, 0, 0, 0},
+/*30*/ {VENDOR_CCD, "HFC-8S OpenVox", 8, 8, 1, 0, 0, 0, 0, 0},
+/*31*/ {VENDOR_CCD, "XHFC-4S Speech Design", 5, 4, 0, 0, 0, 0,
+               HFC_IO_MODE_EMBSD, XHFC_IRQ},
+/*32*/ {VENDOR_JH, "HFC-8S (junghanns)", 8, 8, 1, 0, 0, 0, 0, 0},
 };
 
 #undef H
@@ -5178,6 +5332,8 @@ static struct pci_device_id hfmultipci_ids[] __devinitdata = {
                PCI_SUBDEVICE_ID_CCD_HFC8S, 0, 0, H(18)}, /* 8S */
        { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD,
                PCI_SUBDEVICE_ID_CCD_OV8S, 0, 0, H(30)}, /* OpenVox 8 */
+       { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_VENDOR_ID_CCD,
+               PCI_SUBDEVICE_ID_CCD_JH8S, 0, 0, H(32)}, /* Junganns 8S  */
 
 
        /* Cards with HFC-E1 Chip */
@@ -5201,6 +5357,10 @@ static struct pci_device_id hfmultipci_ids[] __devinitdata = {
                PCI_SUBDEVICE_ID_CCD_SPD4S, 0, 0, H(26)}, /* PLX PCI Bridge */
        { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030, PCI_VENDOR_ID_CCD,
                PCI_SUBDEVICE_ID_CCD_SPDE1, 0, 0, H(27)}, /* PLX PCI Bridge */
+
+       { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFCE1, PCI_VENDOR_ID_CCD,
+               PCI_SUBDEVICE_ID_CCD_JHSE1, 0, 0, H(25)}, /* Junghanns E1 */
+
        { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC4S, PCI_ANY_ID, PCI_ANY_ID,
                0, 0, 0},
        { PCI_VENDOR_ID_CCD, PCI_DEVICE_ID_CCD_HFC8S, PCI_ANY_ID, PCI_ANY_ID,
@@ -5231,7 +5391,7 @@ hfcmulti_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                    "Please contact the driver maintainer for support.\n");
                return -ENODEV;
        }
-       ret = hfcmulti_init(pdev, ent);
+       ret = hfcmulti_init(m, pdev, ent);
        if (ret)
                return ret;
        HFC_cnt++;
@@ -5261,6 +5421,8 @@ static int __init
 HFCmulti_init(void)
 {
        int err;
+       int i, xhfc = 0;
+       struct hm_map m;
 
        printk(KERN_INFO "mISDN: HFC-multi driver %s\n", HFC_MULTI_VERSION);
 
@@ -5308,11 +5470,43 @@ HFCmulti_init(void)
        if (!clock)
                clock = 1;
 
+       /* Register the embedded devices.
+        * This should be done before the PCI cards registration */
+       switch (hwid) {
+       case HWID_MINIP4:
+               xhfc = 1;
+               m = hfcm_map[31];
+               break;
+       case HWID_MINIP8:
+               xhfc = 2;
+               m = hfcm_map[31];
+               break;
+       case HWID_MINIP16:
+               xhfc = 4;
+               m = hfcm_map[31];
+               break;
+       default:
+               xhfc = 0;
+       }
+
+       for (i = 0; i < xhfc; ++i) {
+               err = hfcmulti_init(&m, NULL, NULL);
+               if (err) {
+                       printk(KERN_ERR "error registering embedded driver: "
+                               "%x\n", err);
+                       return -err;
+               }
+               HFC_cnt++;
+               printk(KERN_INFO "%d devices registered\n", HFC_cnt);
+       }
+
+       /* Register the PCI cards */
        err = pci_register_driver(&hfcmultipci_driver);
        if (err < 0) {
                printk(KERN_ERR "error registering pci driver: %x\n", err);
                return err;
        }
+
        return 0;
 }
 
index 641a9cd1a5323947a00ef1e14bb150265ca287b5..228ffbed1286fc850f8d5533cd5368f9c23288d2 100644 (file)
@@ -257,7 +257,7 @@ reset_hfcpci(struct hfc_pci *hc)
        Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1);
 
        /* Clear already pending ints */
-       if (Read_hfc(hc, HFCPCI_INT_S1));
+       val = Read_hfc(hc, HFCPCI_INT_S1);
 
        /* set NT/TE mode */
        hfcpci_setmode(hc);
@@ -452,7 +452,7 @@ hfcpci_empty_bfifo(struct bchannel *bch, struct bzfifo *bz,
                }
                bz->za[new_f2].z2 = cpu_to_le16(new_z2);
                bz->f2 = new_f2;        /* next buffer */
-               recv_Bchannel(bch);
+               recv_Bchannel(bch, MISDN_ID_ANY);
        }
 }
 
@@ -499,7 +499,8 @@ receive_dmsg(struct hfc_pci *hc)
                        df->f2 = ((df->f2 + 1) & MAX_D_FRAMES) |
                            (MAX_D_FRAMES + 1); /* next buffer */
                        df->za[df->f2 & D_FREG_MASK].z2 =
-                           cpu_to_le16((le16_to_cpu(zp->z2) + rcnt) & (D_FIFO_SIZE - 1));
+                           cpu_to_le16((le16_to_cpu(zp->z2) + rcnt) &
+                           (D_FIFO_SIZE - 1));
                } else {
                        dch->rx_skb = mI_alloc_skb(rcnt - 3, GFP_ATOMIC);
                        if (!dch->rx_skb) {
@@ -541,35 +542,45 @@ receive_dmsg(struct hfc_pci *hc)
  * check for transparent receive data and read max one 'poll' size if avail
  */
 static void
-hfcpci_empty_fifo_trans(struct bchannel *bch, struct bzfifo *bz, u_char *bdata)
+hfcpci_empty_fifo_trans(struct bchannel *bch, struct bzfifo *rxbz,
+       struct bzfifo *txbz, u_char *bdata)
 {
-        __le16 *z1r, *z2r;
-       int             new_z2, fcnt, maxlen;
-       u_char          *ptr, *ptr1;
+        __le16 *z1r, *z2r, *z1t, *z2t;
+       int     new_z2, fcnt_rx, fcnt_tx, maxlen;
+       u_char  *ptr, *ptr1;
 
-       z1r = &bz->za[MAX_B_FRAMES].z1;         /* pointer to z reg */
+       z1r = &rxbz->za[MAX_B_FRAMES].z1;       /* pointer to z reg */
        z2r = z1r + 1;
+       z1t = &txbz->za[MAX_B_FRAMES].z1;
+       z2t = z1t + 1;
 
-       fcnt = le16_to_cpu(*z1r) - le16_to_cpu(*z2r);
-       if (!fcnt)
+       fcnt_rx = le16_to_cpu(*z1r) - le16_to_cpu(*z2r);
+       if (!fcnt_rx)
                return; /* no data avail */
 
-       if (fcnt <= 0)
-               fcnt += B_FIFO_SIZE;    /* bytes actually buffered */
-       new_z2 = le16_to_cpu(*z2r) + fcnt;      /* new position in fifo */
+       if (fcnt_rx <= 0)
+               fcnt_rx += B_FIFO_SIZE; /* bytes actually buffered */
+       new_z2 = le16_to_cpu(*z2r) + fcnt_rx;   /* new position in fifo */
        if (new_z2 >= (B_FIFO_SIZE + B_SUB_VAL))
                new_z2 -= B_FIFO_SIZE;  /* buffer wrap */
 
-       if (fcnt > MAX_DATA_SIZE) {     /* flush, if oversized */
+       if (fcnt_rx > MAX_DATA_SIZE) {  /* flush, if oversized */
                *z2r = cpu_to_le16(new_z2);             /* new position */
                return;
        }
 
-       bch->rx_skb = mI_alloc_skb(fcnt, GFP_ATOMIC);
+       fcnt_tx = le16_to_cpu(*z2t) - le16_to_cpu(*z1t);
+       if (fcnt_tx <= 0)
+               fcnt_tx += B_FIFO_SIZE;
+                   /* fcnt_tx contains available bytes in tx-fifo */
+       fcnt_tx = B_FIFO_SIZE - fcnt_tx;
+                   /* remaining bytes to send (bytes in tx-fifo) */
+
+       bch->rx_skb = mI_alloc_skb(fcnt_rx, GFP_ATOMIC);
        if (bch->rx_skb) {
-               ptr = skb_put(bch->rx_skb, fcnt);
-               if (le16_to_cpu(*z2r) + fcnt <= B_FIFO_SIZE + B_SUB_VAL)
-                       maxlen = fcnt;  /* complete transfer */
+               ptr = skb_put(bch->rx_skb, fcnt_rx);
+               if (le16_to_cpu(*z2r) + fcnt_rx <= B_FIFO_SIZE + B_SUB_VAL)
+                       maxlen = fcnt_rx;       /* complete transfer */
                else
                        maxlen = B_FIFO_SIZE + B_SUB_VAL - le16_to_cpu(*z2r);
                            /* maximum */
@@ -577,14 +588,14 @@ hfcpci_empty_fifo_trans(struct bchannel *bch, struct bzfifo *bz, u_char *bdata)
                ptr1 = bdata + (le16_to_cpu(*z2r) - B_SUB_VAL);
                    /* start of data */
                memcpy(ptr, ptr1, maxlen);      /* copy data */
-               fcnt -= maxlen;
+               fcnt_rx -= maxlen;
 
-               if (fcnt) {     /* rest remaining */
+               if (fcnt_rx) {  /* rest remaining */
                        ptr += maxlen;
                        ptr1 = bdata;   /* start of buffer */
-                       memcpy(ptr, ptr1, fcnt);        /* rest */
+                       memcpy(ptr, ptr1, fcnt_rx);     /* rest */
                }
-               recv_Bchannel(bch);
+               recv_Bchannel(bch, fcnt_tx); /* bch, id */
        } else
                printk(KERN_WARNING "HFCPCI: receive out of memory\n");
 
@@ -600,26 +611,28 @@ main_rec_hfcpci(struct bchannel *bch)
        struct hfc_pci  *hc = bch->hw;
        int             rcnt, real_fifo;
        int             receive = 0, count = 5;
-       struct bzfifo   *bz;
+       struct bzfifo   *txbz, *rxbz;
        u_char          *bdata;
        struct zt       *zp;
 
        if ((bch->nr & 2) && (!hc->hw.bswapped)) {
-               bz = &((union fifo_area *)(hc->hw.fifos))->b_chans.rxbz_b2;
+               rxbz = &((union fifo_area *)(hc->hw.fifos))->b_chans.rxbz_b2;
+               txbz = &((union fifo_area *)(hc->hw.fifos))->b_chans.txbz_b2;
                bdata = ((union fifo_area *)(hc->hw.fifos))->b_chans.rxdat_b2;
                real_fifo = 1;
        } else {
-               bz = &((union fifo_area *)(hc->hw.fifos))->b_chans.rxbz_b1;
+               rxbz = &((union fifo_area *)(hc->hw.fifos))->b_chans.rxbz_b1;
+               txbz = &((union fifo_area *)(hc->hw.fifos))->b_chans.txbz_b1;
                bdata = ((union fifo_area *)(hc->hw.fifos))->b_chans.rxdat_b1;
                real_fifo = 0;
        }
 Begin:
        count--;
-       if (bz->f1 != bz->f2) {
+       if (rxbz->f1 != rxbz->f2) {
                if (bch->debug & DEBUG_HW_BCHANNEL)
                        printk(KERN_DEBUG "hfcpci rec ch(%x) f1(%d) f2(%d)\n",
-                           bch->nr, bz->f1, bz->f2);
-               zp = &bz->za[bz->f2];
+                           bch->nr, rxbz->f1, rxbz->f2);
+               zp = &rxbz->za[rxbz->f2];
 
                rcnt = le16_to_cpu(zp->z1) - le16_to_cpu(zp->z2);
                if (rcnt < 0)
@@ -630,8 +643,8 @@ Begin:
                            "hfcpci rec ch(%x) z1(%x) z2(%x) cnt(%d)\n",
                            bch->nr, le16_to_cpu(zp->z1),
                            le16_to_cpu(zp->z2), rcnt);
-               hfcpci_empty_bfifo(bch, bz, bdata, rcnt);
-               rcnt = bz->f1 - bz->f2;
+               hfcpci_empty_bfifo(bch, rxbz, bdata, rcnt);
+               rcnt = rxbz->f1 - rxbz->f2;
                if (rcnt < 0)
                        rcnt += MAX_B_FRAMES + 1;
                if (hc->hw.last_bfifo_cnt[real_fifo] > rcnt + 1) {
@@ -644,7 +657,7 @@ Begin:
                else
                        receive = 0;
        } else if (test_bit(FLG_TRANSPARENT, &bch->Flags)) {
-               hfcpci_empty_fifo_trans(bch, bz, bdata);
+               hfcpci_empty_fifo_trans(bch, rxbz, txbz, bdata);
                return;
        } else
                receive = 0;
@@ -954,6 +967,7 @@ static void
 ph_state_nt(struct dchannel *dch)
 {
        struct hfc_pci  *hc = dch->hw;
+       u_char  val;
 
        if (dch->debug)
                printk(KERN_DEBUG "%s: NT newstate %x\n",
@@ -967,7 +981,7 @@ ph_state_nt(struct dchannel *dch)
                        hc->hw.int_m1 &= ~HFCPCI_INTS_TIMER;
                        Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1);
                        /* Clear already pending ints */
-                       if (Read_hfc(hc, HFCPCI_INT_S1));
+                       val = Read_hfc(hc, HFCPCI_INT_S1);
                        Write_hfc(hc, HFCPCI_STATES, 4 | HFCPCI_LOAD_STATE);
                        udelay(10);
                        Write_hfc(hc, HFCPCI_STATES, 4);
@@ -1256,8 +1270,7 @@ mode_hfcpci(struct bchannel *bch, int bc, int protocol)
                rx_slot = (bc>>8) & 0xff;
                tx_slot = (bc>>16) & 0xff;
                bc = bc & 0xff;
-       } else if (test_bit(HFC_CFG_PCM, &hc->cfg) &&
-           (protocol > ISDN_P_NONE))
+       } else if (test_bit(HFC_CFG_PCM, &hc->cfg) && (protocol > ISDN_P_NONE))
                printk(KERN_WARNING "%s: no pcm channel id but HFC_CFG_PCM\n",
                    __func__);
        if (hc->chanlimit > 1) {
@@ -1315,8 +1328,8 @@ mode_hfcpci(struct bchannel *bch, int bc, int protocol)
        case (ISDN_P_B_RAW):
                bch->state = protocol;
                bch->nr = bc;
-               hfcpci_clear_fifo_rx(hc, (fifo2 & 2)?1:0);
-               hfcpci_clear_fifo_tx(hc, (fifo2 & 2)?1:0);
+               hfcpci_clear_fifo_rx(hc, (fifo2 & 2) ? 1 : 0);
+               hfcpci_clear_fifo_tx(hc, (fifo2 & 2) ? 1 : 0);
                if (bc & 2) {
                        hc->hw.sctrl |= SCTRL_B2_ENA;
                        hc->hw.sctrl_r |= SCTRL_B2_ENA;
@@ -1350,8 +1363,8 @@ mode_hfcpci(struct bchannel *bch, int bc, int protocol)
        case (ISDN_P_B_HDLC):
                bch->state = protocol;
                bch->nr = bc;
-               hfcpci_clear_fifo_rx(hc, (fifo2 & 2)?1:0);
-               hfcpci_clear_fifo_tx(hc, (fifo2 & 2)?1:0);
+               hfcpci_clear_fifo_rx(hc, (fifo2 & 2) ? 1 : 0);
+               hfcpci_clear_fifo_tx(hc, (fifo2 & 2) ? 1 : 0);
                if (bc & 2) {
                        hc->hw.sctrl |= SCTRL_B2_ENA;
                        hc->hw.sctrl_r |= SCTRL_B2_ENA;
@@ -1445,7 +1458,7 @@ set_hfcpci_rxtest(struct bchannel *bch, int protocol, int chan)
        switch (protocol) {
        case (ISDN_P_B_RAW):
                bch->state = protocol;
-               hfcpci_clear_fifo_rx(hc, (chan & 2)?1:0);
+               hfcpci_clear_fifo_rx(hc, (chan & 2) ? 1 : 0);
                if (chan & 2) {
                        hc->hw.sctrl_r |= SCTRL_B2_ENA;
                        hc->hw.fifo_en |= HFCPCI_FIFOEN_B2RX;
@@ -1470,7 +1483,7 @@ set_hfcpci_rxtest(struct bchannel *bch, int protocol, int chan)
                break;
        case (ISDN_P_B_HDLC):
                bch->state = protocol;
-               hfcpci_clear_fifo_rx(hc, (chan & 2)?1:0);
+               hfcpci_clear_fifo_rx(hc, (chan & 2) ? 1 : 0);
                if (chan & 2) {
                        hc->hw.sctrl_r |= SCTRL_B2_ENA;
                        hc->hw.last_bfifo_cnt[1] = 0;
@@ -1793,10 +1806,9 @@ init_card(struct hfc_pci *hc)
                        printk(KERN_WARNING
                            "HFC PCI: IRQ(%d) getting no interrupts "
                            "during init %d\n", hc->irq, 4 - cnt);
-                       if (cnt == 1) {
-                               spin_unlock_irqrestore(&hc->lock, flags);
-                               return -EIO;
-                       } else {
+                       if (cnt == 1)
+                               break;
+                       else {
                                reset_hfcpci(hc);
                                cnt--;
                        }
@@ -2035,7 +2047,8 @@ setup_hw(struct hfc_pci *hc)
                printk(KERN_WARNING "HFC-PCI: No IRQ for PCI card found\n");
                return 1;
        }
-       hc->hw.pci_io = (char __iomem *)(unsigned long)hc->pdev->resource[1].start;
+       hc->hw.pci_io =
+               (char __iomem *)(unsigned long)hc->pdev->resource[1].start;
 
        if (!hc->hw.pci_io) {
                printk(KERN_WARNING "HFC-PCI: No IO-Mem for PCI card found\n");
@@ -2277,7 +2290,7 @@ hfc_remove_pci(struct pci_dev *pdev)
                release_card(card);
        else
                if (debug)
-                       printk(KERN_WARNING "%s: drvdata already removed\n",
+                       printk(KERN_DEBUG "%s: drvdata already removed\n",
                            __func__);
 }
 
index 9c427fb204eec17f43e848c77f996b05914f592f..6b7704c41b947e4cc23b313c65caf40b64069367 100644 (file)
@@ -947,7 +947,7 @@ hfcsusb_rx_frame(struct usb_fifo *fifo, __u8 *data, unsigned int len,
                                if (fifo->dch)
                                        recv_Dchannel(fifo->dch);
                                if (fifo->bch)
-                                       recv_Bchannel(fifo->bch);
+                                       recv_Bchannel(fifo->bch, MISDN_ID_ANY);
                                if (fifo->ech)
                                        recv_Echannel(fifo->ech,
                                                     &hw->dch);
@@ -969,7 +969,7 @@ hfcsusb_rx_frame(struct usb_fifo *fifo, __u8 *data, unsigned int len,
        } else {
                /* deliver transparent data to layer2 */
                if (rx_skb->len >= poll)
-                       recv_Bchannel(fifo->bch);
+                       recv_Bchannel(fifo->bch, MISDN_ID_ANY);
        }
        spin_unlock(&hw->lock);
 }
index f1265667b06241205e9e60c8f7650c9175469904..3d337d924c23b81750153cdf1321a9153d33fa0e 100644 (file)
@@ -82,8 +82,9 @@ release_io_hfcpci(struct IsdnCardState *cs)
        Write_hfc(cs, HFCPCI_INT_M2, cs->hw.hfcpci.int_m2);
        pci_write_config_word(cs->hw.hfcpci.dev, PCI_COMMAND, 0);       /* disable memory mapped ports + busmaster */
        del_timer(&cs->hw.hfcpci.timer);
-       kfree(cs->hw.hfcpci.share_start);
-       cs->hw.hfcpci.share_start = NULL;
+       pci_free_consistent(cs->hw.hfcpci.dev, 0x8000,
+               cs->hw.hfcpci.fifos, cs->hw.hfcpci.dma);
+       cs->hw.hfcpci.fifos = NULL;
        iounmap((void *)cs->hw.hfcpci.pci_io);
 }
 
@@ -1663,8 +1664,19 @@ setup_hfcpci(struct IsdnCard *card)
                                             dev_hfcpci);
                i++;
                if (tmp_hfcpci) {
+                       dma_addr_t      dma_mask = DMA_BIT_MASK(32) & ~0x7fffUL;
                        if (pci_enable_device(tmp_hfcpci))
                                continue;
+                       if (pci_set_dma_mask(tmp_hfcpci, dma_mask)) {
+                               printk(KERN_WARNING
+                                       "HiSax hfc_pci: No suitable DMA available.\n");
+                               continue;
+                       }
+                       if (pci_set_consistent_dma_mask(tmp_hfcpci, dma_mask)) {
+                               printk(KERN_WARNING
+                                       "HiSax hfc_pci: No suitable consistent DMA available.\n");
+                               continue;
+                       }
                        pci_set_master(tmp_hfcpci);
                        if ((card->para[0]) && (card->para[0] != (tmp_hfcpci->resource[ 0].start & PCI_BASE_ADDRESS_IO_MASK)))
                                continue;
@@ -1693,22 +1705,29 @@ setup_hfcpci(struct IsdnCard *card)
                printk(KERN_WARNING "HFC-PCI: No IO-Mem for PCI card found\n");
                return (0);
        }
+
        /* Allocate memory for FIFOS */
-       /* Because the HFC-PCI needs a 32K physical alignment, we */
-       /* need to allocate the double mem and align the address */
-       if (!(cs->hw.hfcpci.share_start = kmalloc(65536, GFP_KERNEL))) {
-               printk(KERN_WARNING "HFC-PCI: Error allocating memory for FIFO!\n");
+       cs->hw.hfcpci.fifos = pci_alloc_consistent(cs->hw.hfcpci.dev,
+                                       0x8000, &cs->hw.hfcpci.dma);
+       if (!cs->hw.hfcpci.fifos) {
+               printk(KERN_WARNING "HFC-PCI: Error allocating FIFO memory!\n");
+               return 0;
+       }
+       if (cs->hw.hfcpci.dma & 0x7fff) {
+               printk(KERN_WARNING
+                   "HFC-PCI: Error DMA memory not on 32K boundary (%lx)\n",
+                   (u_long)cs->hw.hfcpci.dma);
+               pci_free_consistent(cs->hw.hfcpci.dev, 0x8000,
+                       cs->hw.hfcpci.fifos, cs->hw.hfcpci.dma);
                return 0;
        }
-       cs->hw.hfcpci.fifos = (void *)
-           (((ulong) cs->hw.hfcpci.share_start) & ~0x7FFF) + 0x8000;
-       pci_write_config_dword(cs->hw.hfcpci.dev, 0x80, (u_int) virt_to_bus(cs->hw.hfcpci.fifos));
+       pci_write_config_dword(cs->hw.hfcpci.dev, 0x80, (u32)cs->hw.hfcpci.dma);
        cs->hw.hfcpci.pci_io = ioremap((ulong) cs->hw.hfcpci.pci_io, 256);
        printk(KERN_INFO
-              "HFC-PCI: defined at mem %p fifo %p(%#x) IRQ %d HZ %d\n",
+              "HFC-PCI: defined at mem %p fifo %p(%lx) IRQ %d HZ %d\n",
               cs->hw.hfcpci.pci_io,
               cs->hw.hfcpci.fifos,
-              (u_int) virt_to_bus(cs->hw.hfcpci.fifos),
+              (u_long)cs->hw.hfcpci.dma,
               cs->irq, HZ);
 
        spin_lock_irqsave(&cs->lock, flags);
index f8527046f1973a879a8a07d8111972ea3a0422ea..0685c194696928e7293a737aa010df7af217125a 100644 (file)
@@ -703,7 +703,7 @@ struct hfcPCI_hw {
         int nt_timer;
         struct pci_dev *dev;
         unsigned char *pci_io; /* start of PCI IO memory */
-        void *share_start; /* shared memory for Fifos start */
+       dma_addr_t dma; /* dma handle for Fifos */
         void *fifos; /* FIFO memory */ 
         int last_bfifo_cnt[2]; /* marker saving last b-fifo frame count */
        struct timer_list timer;
index 53f6ad1235db652d02fb62e8821db4a297535941..4ffaa14b9fc4fd92a47a083b0521207471be7977 100644 (file)
@@ -67,7 +67,7 @@ hycapi_reset_ctr(struct capi_ctr *ctrl)
        printk(KERN_NOTICE "HYCAPI hycapi_reset_ctr\n");
 #endif
        capilib_release(&cinfo->ncci_head);
-       capi_ctr_reseted(ctrl);
+       capi_ctr_down(ctrl);
 }
 
 /******************************
@@ -347,7 +347,7 @@ int hycapi_capi_stop(hysdn_card *card)
        if(cinfo) {
                ctrl = &cinfo->capi_ctrl;
 /*             ctrl->suspend_output(ctrl); */
-               capi_ctr_reseted(ctrl);
+               capi_ctr_down(ctrl);
        }
        return 0;
 }
index 36778b270c303aa0a8ae57c4feb85966a3ebee92..ed3510f273d82b616c328c6f59367a9d262de6b7 100644 (file)
@@ -135,5 +135,3 @@ source "drivers/isdn/act2000/Kconfig"
 source "drivers/isdn/hysdn/Kconfig"
 
 endmenu
-
-source "drivers/isdn/gigaset/Kconfig"
index cb8943da4f122f8c3fdf2703d405160ddad309b5..34d54e7281fd13aabf5b72cbf4a471a6e433ddb8 100644 (file)
@@ -1069,7 +1069,7 @@ isdn_net_xmit(struct net_device *ndev, struct sk_buff *skb)
        lp = isdn_net_get_locked_lp(nd);
        if (!lp) {
                printk(KERN_WARNING "%s: all channels busy - requeuing!\n", ndev->name);
-               return 1;
+               return NETDEV_TX_BUSY;
        }
        /* we have our lp locked from now on */
 
@@ -1273,14 +1273,14 @@ isdn_net_start_xmit(struct sk_buff *skb, struct net_device *ndev)
                                        spin_unlock_irqrestore(&dev->lock, flags);
                                        isdn_net_dial();        /* Initiate dialing */
                                        netif_stop_queue(ndev);
-                                       return 1;       /* let upper layer requeue skb packet */
+                                       return NETDEV_TX_BUSY;  /* let upper layer requeue skb packet */
                                }
 #endif
                                /* Initiate dialing */
                                spin_unlock_irqrestore(&dev->lock, flags);
                                isdn_net_dial();
                                isdn_net_device_stop_queue(lp);
-                               return 1;
+                               return NETDEV_TX_BUSY;
                        } else {
                                isdn_net_unreachable(ndev, skb,
                                                     "No phone number");
index 1a2222cbb80541bc492d78cef045f0844a08fad6..b4d4522e50718347f02b88345cc93d50608d9252 100644 (file)
@@ -1592,7 +1592,7 @@ isdn_tty_open(struct tty_struct *tty, struct file *filp)
        int retval, line;
 
        line = tty->index;
-       if (line < 0 || line > ISDN_MAX_CHANNELS)
+       if (line < 0 || line >= ISDN_MAX_CHANNELS)
                return -ENODEV;
        info = &dev->mdm.info[line];
        if (isdn_tty_paranoia_check(info, tty->name, "isdn_tty_open"))
index 9426c9827e47307c24efa3de435651864cb7eb72..21d34be5af6a2300fa49b646515e0413eea77db0 100644 (file)
@@ -214,7 +214,7 @@ get_free_devid(void)
                if (!test_and_set_bit(i, (u_long *)&device_ids))
                        break;
        if (i > MAX_DEVICE_ID)
-               return -1;
+               return -EBUSY;
        return i;
 }
 
@@ -224,10 +224,10 @@ mISDN_register_device(struct mISDNdevice *dev,
 {
        int     err;
 
-       dev->id = get_free_devid();
-       err = -EBUSY;
-       if (dev->id < 0)
+       err = get_free_devid();
+       if (err < 0)
                goto error1;
+       dev->id = err;
 
        device_initialize(&dev->dev);
        if (name && name[0])
index 98a33c58f0911f4b7482eb40a949a9a2412407f2..18af86879c054456eff40f6c35f70836cabbfa40 100644 (file)
@@ -112,9 +112,11 @@ struct dsp_conf {
 
 #define DSP_DTMF_NPOINTS 102
 
-#define ECHOCAN_BUFLEN (4*128)
+#define ECHOCAN_BUFF_SIZE 0x400 /* must be 2**n */
+#define ECHOCAN_BUFF_MASK 0x3ff /* -1 */
 
 struct dsp_dtmf {
+       int             enable; /* dtmf is enabled */
        int             treshold; /* above this is dtmf (square of) */
        int             software; /* dtmf uses software decoding */
        int             hardware; /* dtmf uses hardware decoding */
@@ -123,7 +125,7 @@ struct dsp_dtmf {
                /* buffers one full dtmf frame */
        u8              lastwhat, lastdigit;
        int             count;
-       u8              digits[16]; /* just the dtmf result */
+       u8              digits[16]; /* dtmf result */
 };
 
 
@@ -150,6 +152,15 @@ struct dsp_tone {
        struct timer_list tl;
 };
 
+/***************
+ * echo stuff *
+ ***************/
+
+struct dsp_echo {
+       int             software; /* echo is generated by software */
+       int             hardware; /* echo is generated by hardware */
+};
+
 /*****************
  * general stuff *
  *****************/
@@ -160,7 +171,7 @@ struct dsp {
        struct mISDNchannel     *up;
        unsigned char   name[64];
        int             b_active;
-       int             echo; /* echo is enabled */
+       struct dsp_echo echo;
        int             rx_disabled; /* what the user wants */
        int             rx_is_off; /* what the card is */
        int             tx_mix;
@@ -261,5 +272,5 @@ extern int  dsp_pipeline_build(struct dsp_pipeline *pipeline, const char *cfg);
 extern void dsp_pipeline_process_tx(struct dsp_pipeline *pipeline, u8 *data,
                int len);
 extern void dsp_pipeline_process_rx(struct dsp_pipeline *pipeline, u8 *data,
-               int len);
+               int len, unsigned int txlen);
 
index de3795e3f43291ab2dd50df0bbc5f2975f4fb477..9c7c6451bf3db86a95b3309fc06a85b1020b98f2 100644 (file)
@@ -210,9 +210,8 @@ dsp_audio_generate_seven(void)
                j = 0;
                for (k = 0; k < 256; k++) {
                        if (dsp_audio_alaw_to_s32[k]
-                               < dsp_audio_alaw_to_s32[i]) {
-                       j++;
-                       }
+                           < dsp_audio_alaw_to_s32[i])
+                               j++;
                }
                sorted_alaw[j] = i;
        }
index 58c43e429f73229ad6938ce83a9a3e336f4a62b3..9c7c0d1ba55f1c80d13c1f21e9bb1f56010594f8 100644 (file)
@@ -163,8 +163,9 @@ dsp_cmx_debug(struct dsp *dsp)
 
        printk(KERN_DEBUG "-----Current DSP\n");
        list_for_each_entry(odsp, &dsp_ilist, list) {
-               printk(KERN_DEBUG "* %s echo=%d txmix=%d",
-                   odsp->name, odsp->echo, odsp->tx_mix);
+               printk(KERN_DEBUG "* %s hardecho=%d softecho=%d txmix=%d",
+                   odsp->name, odsp->echo.hardware, odsp->echo.software,
+                   odsp->tx_mix);
                if (odsp->conf)
                        printk(" (Conf %d)", odsp->conf->id);
                if (dsp == odsp)
@@ -177,10 +178,12 @@ dsp_cmx_debug(struct dsp *dsp)
                list_for_each_entry(member, &conf->mlist, list) {
                        printk(KERN_DEBUG
                            "  - member = %s (slot_tx %d, bank_tx %d, "
-                           "slot_rx %d, bank_rx %d hfc_conf %d)%s\n",
+                           "slot_rx %d, bank_rx %d hfc_conf %d "
+                           "tx_data %d rx_is_off %d)%s\n",
                            member->dsp->name, member->dsp->pcm_slot_tx,
                            member->dsp->pcm_bank_tx, member->dsp->pcm_slot_rx,
                            member->dsp->pcm_bank_rx, member->dsp->hfc_conf,
+                           member->dsp->tx_data, member->dsp->rx_is_off,
                            (member->dsp == dsp) ? " *this*" : "");
                }
        }
@@ -235,7 +238,7 @@ dsp_cmx_add_conf_member(struct dsp *dsp, struct dsp_conf *conf)
 
        member = kzalloc(sizeof(struct dsp_conf_member), GFP_ATOMIC);
        if (!member) {
-               printk(KERN_ERR "kmalloc struct dsp_conf_member failed\n");
+               printk(KERN_ERR "kzalloc struct dsp_conf_member failed\n");
                return -ENOMEM;
        }
        member->dsp = dsp;
@@ -314,7 +317,7 @@ static struct dsp_conf
 
        conf = kzalloc(sizeof(struct dsp_conf), GFP_ATOMIC);
        if (!conf) {
-               printk(KERN_ERR "kmalloc struct dsp_conf failed\n");
+               printk(KERN_ERR "kzalloc struct dsp_conf failed\n");
                return NULL;
        }
        INIT_LIST_HEAD(&conf->mlist);
@@ -385,7 +388,7 @@ dsp_cmx_hardware(struct dsp_conf *conf, struct dsp *dsp)
        int             freeunits[8];
        u_char          freeslots[256];
        int             same_hfc = -1, same_pcm = -1, current_conf = -1,
-           all_conf = 1;
+           all_conf = 1, tx_data = 0;
 
        /* dsp gets updated (no conf) */
        if (!conf) {
@@ -409,7 +412,7 @@ one_member:
                /* process hw echo */
                if (dsp->features.pcm_banks < 1)
                        return;
-               if (!dsp->echo) {
+               if (!dsp->echo.software && !dsp->echo.hardware) {
                        /* NO ECHO: remove PCM slot if assigned */
                        if (dsp->pcm_slot_tx >= 0 || dsp->pcm_slot_rx >= 0) {
                                if (dsp_debug & DEBUG_DSP_CMX)
@@ -427,10 +430,15 @@ one_member:
                        }
                        return;
                }
+               /* echo is enabled, find out if we use soft or hardware */
+               dsp->echo.software = dsp->tx_data;
+               dsp->echo.hardware = 0;
                /* ECHO: already echo */
                if (dsp->pcm_slot_tx >= 0 && dsp->pcm_slot_rx < 0 &&
-                   dsp->pcm_bank_tx == 2 && dsp->pcm_bank_rx == 2)
+                   dsp->pcm_bank_tx == 2 && dsp->pcm_bank_rx == 2) {
+                       dsp->echo.hardware = 1;
                        return;
+               }
                /* ECHO: if slot already assigned */
                if (dsp->pcm_slot_tx >= 0) {
                        dsp->pcm_slot_rx = dsp->pcm_slot_tx;
@@ -443,6 +451,7 @@ one_member:
                                    dsp->pcm_slot_tx);
                        dsp_cmx_hw_message(dsp, MISDN_CTRL_HFC_PCM_CONN,
                            dsp->pcm_slot_tx, 2, dsp->pcm_slot_rx, 2);
+                       dsp->echo.hardware = 1;
                        return;
                }
                /* ECHO: find slot */
@@ -472,6 +481,7 @@ one_member:
                                    "%s no slot available for echo\n",
                                    __func__);
                        /* no more slots available */
+                       dsp->echo.software = 1;
                        return;
                }
                /* assign free slot */
@@ -485,6 +495,7 @@ one_member:
                            __func__, dsp->name, dsp->pcm_slot_tx);
                dsp_cmx_hw_message(dsp, MISDN_CTRL_HFC_PCM_CONN,
                    dsp->pcm_slot_tx, 2, dsp->pcm_slot_rx, 2);
+               dsp->echo.hardware = 1;
                return;
        }
 
@@ -554,7 +565,7 @@ conf_software:
                        return;
                }
                /* check if member has echo turned on */
-               if (member->dsp->echo) {
+               if (member->dsp->echo.hardware || member->dsp->echo.software) {
                        if (dsp_debug & DEBUG_DSP_CMX)
                                printk(KERN_DEBUG
                                    "%s dsp %s cannot form a conf, because "
@@ -592,10 +603,9 @@ conf_software:
                if (member->dsp->tx_data) {
                        if (dsp_debug & DEBUG_DSP_CMX)
                                printk(KERN_DEBUG
-                                   "%s dsp %s cannot form a conf, because "
-                                   "tx_data is turned on\n",
+                                   "%s dsp %s tx_data is turned on\n",
                                    __func__, member->dsp->name);
-                       goto conf_software;
+                       tx_data = 1;
                }
                /* check if pipeline exists */
                if (member->dsp->pipeline.inuse) {
@@ -794,7 +804,7 @@ conf_software:
                            nextm->dsp->pcm_slot_tx, nextm->dsp->pcm_bank_tx,
                            nextm->dsp->pcm_slot_rx, nextm->dsp->pcm_bank_rx);
                        conf->hardware = 1;
-                       conf->software = 0;
+                       conf->software = tx_data;
                        return;
                /* if members have one bank (or on the same chip) */
                } else {
@@ -904,7 +914,7 @@ conf_software:
                            nextm->dsp->pcm_slot_tx, nextm->dsp->pcm_bank_tx,
                            nextm->dsp->pcm_slot_rx, nextm->dsp->pcm_bank_rx);
                        conf->hardware = 1;
-                       conf->software = 0;
+                       conf->software = tx_data;
                        return;
                }
        }
@@ -937,6 +947,10 @@ conf_software:
        if (current_conf >= 0) {
 join_members:
                list_for_each_entry(member, &conf->mlist, list) {
+                       /* if no conference engine on our chip, change to
+                        * software */
+                       if (!member->dsp->features.hfc_conf)
+                               goto conf_software;
                        /* in case of hdlc, change to software */
                        if (member->dsp->hdlc)
                                goto conf_software;
@@ -1295,17 +1309,25 @@ dsp_cmx_send_member(struct dsp *dsp, int len, s32 *c, int members)
        int r, rr, t, tt, o_r, o_rr;
        int preload = 0;
        struct mISDNhead *hh, *thh;
+       int tx_data_only = 0;
 
        /* don't process if: */
        if (!dsp->b_active) { /* if not active */
                dsp->last_tx = 0;
                return;
        }
-       if (dsp->pcm_slot_tx >= 0 && /* connected to pcm slot */
+       if (((dsp->conf && dsp->conf->hardware) || /* hardware conf */
+           dsp->echo.hardware) && /* OR hardware echo */
            dsp->tx_R == dsp->tx_W && /* AND no tx-data */
            !(dsp->tone.tone && dsp->tone.software)) { /* AND not soft tones */
-               dsp->last_tx = 0;
-               return;
+               if (!dsp->tx_data) { /* no tx_data for user space required */
+                       dsp->last_tx = 0;
+                       return;
+               }
+               if (dsp->conf && dsp->conf->software && dsp->conf->hardware)
+                       tx_data_only = 1;
+               if (dsp->conf->software && dsp->echo.hardware)
+                       tx_data_only = 1;
        }
 
 #ifdef CMX_DEBUG
@@ -1367,7 +1389,8 @@ dsp_cmx_send_member(struct dsp *dsp, int len, s32 *c, int members)
                while (r != rr && t != tt) {
 #ifdef CMX_TX_DEBUG
                        if (strlen(debugbuf) < 48)
-                           sprintf(debugbuf+strlen(debugbuf), " %02x", p[t]);
+                               sprintf(debugbuf+strlen(debugbuf), " %02x",
+                                   p[t]);
 #endif
                        *d++ = p[t]; /* write tx_buff */
                        t = (t+1) & CMX_BUFF_MASK;
@@ -1388,7 +1411,7 @@ dsp_cmx_send_member(struct dsp *dsp, int len, s32 *c, int members)
        /* PROCESS DATA (one member / no conf) */
        if (!conf || members <= 1) {
                /* -> if echo is NOT enabled */
-               if (!dsp->echo) {
+               if (!dsp->echo.software) {
                        /* -> send tx-data if available or use 0-volume */
                        while (r != rr && t != tt) {
                                *d++ = p[t]; /* write tx_buff */
@@ -1438,7 +1461,7 @@ dsp_cmx_send_member(struct dsp *dsp, int len, s32 *c, int members)
                o_r = (o_rr - rr + r) & CMX_BUFF_MASK;
                        /* start rx-pointer at current read position*/
                /* -> if echo is NOT enabled */
-               if (!dsp->echo) {
+               if (!dsp->echo.software) {
                        /*
                         * -> copy other member's rx-data,
                         * if tx-data is available, mix
@@ -1486,7 +1509,7 @@ dsp_cmx_send_member(struct dsp *dsp, int len, s32 *c, int members)
 #endif
        /* PROCESS DATA (three or more members) */
        /* -> if echo is NOT enabled */
-       if (!dsp->echo) {
+       if (!dsp->echo.software) {
                /*
                 * -> substract rx-data from conf-data,
                 * if tx-data is available, mix
@@ -1550,27 +1573,40 @@ send_packet:
         * becuase we want what we send, not what we filtered
         */
        if (dsp->tx_data) {
-               /* PREPARE RESULT */
-               txskb = mI_alloc_skb(len, GFP_ATOMIC);
-               if (!txskb) {
-                       printk(KERN_ERR
-                           "FATAL ERROR in mISDN_dsp.o: "
-                           "cannot alloc %d bytes\n", len);
+               if (tx_data_only) {
+                       hh->prim = DL_DATA_REQ;
+                       hh->id = 0;
+                       /* queue and trigger */
+                       skb_queue_tail(&dsp->sendq, nskb);
+                       schedule_work(&dsp->workq);
+                       /* exit because only tx_data is used */
+                       return;
                } else {
-                       thh = mISDN_HEAD_P(txskb);
-                       thh->prim = DL_DATA_REQ;
-                       thh->id = 0;
-                       memcpy(skb_put(txskb, len), nskb->data+preload, len);
-                       /* queue (trigger later) */
-                       skb_queue_tail(&dsp->sendq, txskb);
+                       txskb = mI_alloc_skb(len, GFP_ATOMIC);
+                       if (!txskb) {
+                               printk(KERN_ERR
+                                   "FATAL ERROR in mISDN_dsp.o: "
+                                   "cannot alloc %d bytes\n", len);
+                       } else {
+                               thh = mISDN_HEAD_P(txskb);
+                               thh->prim = DL_DATA_REQ;
+                               thh->id = 0;
+                               memcpy(skb_put(txskb, len), nskb->data+preload,
+                                       len);
+                               /* queue (trigger later) */
+                               skb_queue_tail(&dsp->sendq, txskb);
+                       }
                }
        }
+
+       /* send data only to card, if we don't just calculated tx_data */
        /* adjust volume */
        if (dsp->tx_volume)
                dsp_change_volume(nskb, dsp->tx_volume);
        /* pipeline */
        if (dsp->pipeline.inuse)
-               dsp_pipeline_process_tx(&dsp->pipeline, nskb->data, nskb->len);
+               dsp_pipeline_process_tx(&dsp->pipeline, nskb->data,
+                       nskb->len);
        /* crypt */
        if (dsp->bf_enable)
                dsp_bf_encrypt(dsp, nskb->data, nskb->len);
@@ -1592,7 +1628,8 @@ dsp_cmx_send(void *arg)
        struct dsp_conf_member *member;
        struct dsp *dsp;
        int mustmix, members;
-       s32 mixbuffer[MAX_POLL+100], *c;
+       static s32 mixbuffer[MAX_POLL+100];
+       s32 *c;
        u8 *p, *q;
        int r, rr;
        int jittercheck = 0, delay, i;
@@ -1890,10 +1927,8 @@ dsp_cmx_hdlc(struct dsp *dsp, struct sk_buff *skb)
 
        /* no conf */
        if (!dsp->conf) {
-               /* in case of hardware (echo) */
-               if (dsp->pcm_slot_tx >= 0)
-                       return;
-               if (dsp->echo) {
+               /* in case of software echo */
+               if (dsp->echo.software) {
                        nskb = skb_clone(skb, GFP_ATOMIC);
                        if (nskb) {
                                hh = mISDN_HEAD_P(nskb);
@@ -1909,7 +1944,7 @@ dsp_cmx_hdlc(struct dsp *dsp, struct sk_buff *skb)
        if (dsp->conf->hardware)
                return;
        list_for_each_entry(member, &dsp->conf->mlist, list) {
-               if (dsp->echo || member->dsp != dsp) {
+               if (dsp->echo.software || member->dsp != dsp) {
                        nskb = skb_clone(skb, GFP_ATOMIC);
                        if (nskb) {
                                hh = mISDN_HEAD_P(nskb);
index 47dbfe298b43ab4002e591a4da7702daa982e6dc..77ee2867c8b4dd8cb768e394f9cd7de5762b1321 100644 (file)
@@ -203,13 +203,13 @@ dsp_rx_off_member(struct dsp *dsp)
        else if (dsp->dtmf.software)
                rx_off = 0;
        /* echo in software */
-       else if (dsp->echo && dsp->pcm_slot_tx < 0)
+       else if (dsp->echo.software)
                rx_off = 0;
        /* bridge in software */
-       else if (dsp->conf) {
-               if (dsp->conf->software)
-                       rx_off = 0;
-       }
+       else if (dsp->conf && dsp->conf->software)
+               rx_off = 0;
+       /* data is not required by user space and not required
+        * for echo dtmf detection, soft-echo, soft-bridging */
 
        if (rx_off == dsp->rx_is_off)
                return;
@@ -280,7 +280,7 @@ dsp_fill_empty(struct dsp *dsp)
 static int
 dsp_control_req(struct dsp *dsp, struct mISDNhead *hh, struct sk_buff *skb)
 {
-       struct          sk_buff *nskb;
+       struct sk_buff  *nskb;
        int ret = 0;
        int cont;
        u8 *data;
@@ -306,15 +306,18 @@ dsp_control_req(struct dsp *dsp, struct mISDNhead *hh, struct sk_buff *skb)
                                        "to %d\n", *((int *)data));
                        dsp->dtmf.treshold = (*(int *)data) * 10000;
                }
+               dsp->dtmf.enable = 1;
                /* init goertzel */
                dsp_dtmf_goertzel_init(dsp);
 
                /* check dtmf hardware */
                dsp_dtmf_hardware(dsp);
+               dsp_rx_off(dsp);
                break;
        case DTMF_TONE_STOP: /* turn off DTMF */
                if (dsp_debug & DEBUG_DSP_CORE)
                        printk(KERN_DEBUG "%s: stop dtmf\n", __func__);
+               dsp->dtmf.enable = 0;
                dsp->dtmf.hardware = 0;
                dsp->dtmf.software = 0;
                break;
@@ -414,7 +417,7 @@ tone_off:
                dsp_rx_off(dsp);
                break;
        case DSP_ECHO_ON: /* enable echo */
-               dsp->echo = 1; /* soft echo */
+               dsp->echo.software = 1; /* soft echo */
                if (dsp_debug & DEBUG_DSP_CORE)
                        printk(KERN_DEBUG "%s: enable cmx-echo\n", __func__);
                dsp_cmx_hardware(dsp->conf, dsp);
@@ -423,7 +426,8 @@ tone_off:
                        dsp_cmx_debug(dsp);
                break;
        case DSP_ECHO_OFF: /* disable echo */
-               dsp->echo = 0;
+               dsp->echo.software = 0;
+               dsp->echo.hardware = 0;
                if (dsp_debug & DEBUG_DSP_CORE)
                        printk(KERN_DEBUG "%s: disable cmx-echo\n", __func__);
                dsp_cmx_hardware(dsp->conf, dsp);
@@ -556,7 +560,7 @@ tone_off:
                        dsp->pipeline.inuse = 1;
                        dsp_cmx_hardware(dsp->conf, dsp);
                        ret = dsp_pipeline_build(&dsp->pipeline,
-                               len > 0 ? (char *)data : NULL);
+                               len > 0 ? data : NULL);
                        dsp_cmx_hardware(dsp->conf, dsp);
                        dsp_rx_off(dsp);
                }
@@ -657,11 +661,10 @@ get_features(struct mISDNchannel *ch)
 static int
 dsp_function(struct mISDNchannel *ch,  struct sk_buff *skb)
 {
-       struct dsp                      *dsp = container_of(ch, struct dsp, ch);
+       struct dsp              *dsp = container_of(ch, struct dsp, ch);
        struct mISDNhead        *hh;
        int                     ret = 0;
-       u8                      *digits;
-       int                     cont;
+       u8                      *digits = NULL;
        u_long                  flags;
 
        hh = mISDN_HEAD_P(skb);
@@ -704,50 +707,55 @@ dsp_function(struct mISDNchannel *ch,  struct sk_buff *skb)
                        break;
                }
 
+               spin_lock_irqsave(&dsp_lock, flags);
+
                /* decrypt if enabled */
                if (dsp->bf_enable)
                        dsp_bf_decrypt(dsp, skb->data, skb->len);
                /* pipeline */
                if (dsp->pipeline.inuse)
                        dsp_pipeline_process_rx(&dsp->pipeline, skb->data,
-                               skb->len);
+                               skb->len, hh->id);
                /* change volume if requested */
                if (dsp->rx_volume)
                        dsp_change_volume(skb, dsp->rx_volume);
-
                /* check if dtmf soft decoding is turned on */
                if (dsp->dtmf.software) {
                        digits = dsp_dtmf_goertzel_decode(dsp, skb->data,
-                               skb->len, (dsp_options&DSP_OPT_ULAW)?1:0);
+                               skb->len, (dsp_options&DSP_OPT_ULAW) ? 1 : 0);
+               }
+               /* we need to process receive data if software */
+               if (dsp->conf && dsp->conf->software) {
+                       /* process data from card at cmx */
+                       dsp_cmx_receive(dsp, skb);
+               }
+
+               spin_unlock_irqrestore(&dsp_lock, flags);
+
+               /* send dtmf result, if any */
+               if (digits) {
                        while (*digits) {
+                               int k;
                                struct sk_buff *nskb;
                                if (dsp_debug & DEBUG_DSP_DTMF)
                                        printk(KERN_DEBUG "%s: digit"
                                            "(%c) to layer %s\n",
                                            __func__, *digits, dsp->name);
-                               cont = DTMF_TONE_VAL | *digits;
+                               k = *digits | DTMF_TONE_VAL;
                                nskb = _alloc_mISDN_skb(PH_CONTROL_IND,
-                                   MISDN_ID_ANY, sizeof(int), &cont,
-                                   GFP_ATOMIC);
+                                       MISDN_ID_ANY, sizeof(int), &k,
+                                       GFP_ATOMIC);
                                if (nskb) {
                                        if (dsp->up) {
                                                if (dsp->up->send(
                                                    dsp->up, nskb))
-                                               dev_kfree_skb(nskb);
+                                                       dev_kfree_skb(nskb);
                                        } else
                                                dev_kfree_skb(nskb);
                                }
                                digits++;
                        }
                }
-               /* we need to process receive data if software */
-               spin_lock_irqsave(&dsp_lock, flags);
-               if (dsp->pcm_slot_tx < 0 && dsp->pcm_slot_rx < 0) {
-                       /* process data from card at cmx */
-                       dsp_cmx_receive(dsp, skb);
-               }
-               spin_unlock_irqrestore(&dsp_lock, flags);
-
                if (dsp->rx_disabled) {
                        /* if receive is not allowed */
                        break;
@@ -787,7 +795,7 @@ dsp_function(struct mISDNchannel *ch,  struct sk_buff *skb)
                                        if (dsp->up) {
                                                if (dsp->up->send(
                                                    dsp->up, nskb))
-                                               dev_kfree_skb(nskb);
+                                                       dev_kfree_skb(nskb);
                                        } else
                                                dev_kfree_skb(nskb);
                                }
@@ -946,7 +954,7 @@ dsp_ctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
        int             err = 0;
 
        if (debug & DEBUG_DSP_CTRL)
-       printk(KERN_DEBUG "%s:(%x)\n", __func__, cmd);
+               printk(KERN_DEBUG "%s:(%x)\n", __func__, cmd);
 
        switch (cmd) {
        case OPEN_CHANNEL:
@@ -1169,9 +1177,9 @@ static int dsp_init(void)
 
        /* init conversion tables */
        dsp_audio_generate_law_tables();
-       dsp_silence = (dsp_options&DSP_OPT_ULAW)?0xff:0x2a;
-       dsp_audio_law_to_s32 = (dsp_options&DSP_OPT_ULAW)?dsp_audio_ulaw_to_s32:
-               dsp_audio_alaw_to_s32;
+       dsp_silence = (dsp_options&DSP_OPT_ULAW) ? 0xff : 0x2a;
+       dsp_audio_law_to_s32 = (dsp_options&DSP_OPT_ULAW) ?
+               dsp_audio_ulaw_to_s32 : dsp_audio_alaw_to_s32;
        dsp_audio_generate_s2law_table();
        dsp_audio_generate_seven();
        dsp_audio_generate_mix_table();
index efc371c1f0dc02a6f86d4f146fe348051aa111ab..9ae2d33b06f7c5a819157d20bfce9ad5d81bca19 100644 (file)
@@ -51,6 +51,9 @@ void dsp_dtmf_hardware(struct dsp *dsp)
 {
        int hardware = 1;
 
+       if (!dsp->dtmf.enable)
+               return;
+
        if (!dsp->features.hfc_dtmf)
                hardware = 0;
 
index 8a20af43308b3071e8f4f977314ee7432bb066e5..21dbd153ee26b32c9169eb6ccc1aab33e9f43b57 100644 (file)
@@ -91,7 +91,7 @@ int16_t amp)
                                        && det->tone_cycle_duration <= 475*8) {
                                        det->good_cycles++;
                                        if (det->good_cycles > 2)
-                                       det->hit = TRUE;
+                                               det->hit = TRUE;
                                }
                                det->tone_cycle_duration = 0;
                        }
index 18cf87c113e725cb9f7adc157963bb0105e3d5ea..e9941678edfa52ff51baa83b75a8d659017926b9 100644 (file)
@@ -55,20 +55,19 @@ static ssize_t
 attr_show_args(struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct mISDN_dsp_element *elem = dev_get_drvdata(dev);
-       ssize_t len = 0;
-       int i = 0;
+       int i;
+       char *p = buf;
 
        *buf = 0;
-       for (; i < elem->num_args; ++i)
-               len = sprintf(buf, "%sName:        %s\n%s%s%sDescription: %s\n"
-                       "\n", buf,
+       for (i = 0; i < elem->num_args; i++)
+               p += sprintf(p, "Name:        %s\n%s%s%sDescription: %s\n\n",
                          elem->args[i].name,
                          elem->args[i].def ? "Default:     " : "",
                          elem->args[i].def ? elem->args[i].def : "",
                          elem->args[i].def ? "\n" : "",
                          elem->args[i].desc);
 
-       return len;
+       return p - buf;
 }
 
 static struct device_attribute element_attributes[] = {
@@ -347,7 +346,8 @@ void dsp_pipeline_process_tx(struct dsp_pipeline *pipeline, u8 *data, int len)
                        entry->elem->process_tx(entry->p, data, len);
 }
 
-void dsp_pipeline_process_rx(struct dsp_pipeline *pipeline, u8 *data, int len)
+void dsp_pipeline_process_rx(struct dsp_pipeline *pipeline, u8 *data, int len,
+       unsigned int txlen)
 {
        struct dsp_pipeline_entry *entry;
 
@@ -356,7 +356,7 @@ void dsp_pipeline_process_rx(struct dsp_pipeline *pipeline, u8 *data, int len)
 
        list_for_each_entry_reverse(entry, &pipeline->list, list)
                if (entry->elem->process_rx)
-                       entry->elem->process_rx(entry->p, data, len);
+                       entry->elem->process_rx(entry->p, data, len, txlen);
 }
 
 
index 7a9af66f4b196b3e0ea79dff510e6c796df01038..1debf53670de6408f98ddbbbacd681a0cef9b93f 100644 (file)
@@ -253,18 +253,24 @@ static struct pattern {
        {8000, 0, 0, 0, 0, 0, 0, 0, 0, 0} },
 
        {TONE_GERMAN_DIALPBX,
-       {DATA_GA, DATA_S, DATA_GA, DATA_S, DATA_GA, DATA_S, NULL, NULL, NULL, NULL},
-       {SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, NULL, NULL, NULL, NULL},
+       {DATA_GA, DATA_S, DATA_GA, DATA_S, DATA_GA, DATA_S, NULL, NULL, NULL,
+               NULL},
+       {SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, SIZE_GA, SIZE_S, NULL, NULL, NULL,
+               NULL},
        {2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
 
        {TONE_GERMAN_OLDDIALPBX,
-       {DATA_GO, DATA_S, DATA_GO, DATA_S, DATA_GO, DATA_S, NULL, NULL, NULL, NULL},
-       {SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, NULL, NULL, NULL, NULL},
+       {DATA_GO, DATA_S, DATA_GO, DATA_S, DATA_GO, DATA_S, NULL, NULL, NULL,
+               NULL},
+       {SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, SIZE_GO, SIZE_S, NULL, NULL, NULL,
+               NULL},
        {2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
 
        {TONE_AMERICAN_DIALPBX,
-       {DATA_DT, DATA_S, DATA_DT, DATA_S, DATA_DT, DATA_S, NULL, NULL, NULL, NULL},
-       {SIZE_DT, SIZE_S, SIZE_DT, SIZE_S, SIZE_DT, SIZE_S, NULL, NULL, NULL, NULL},
+       {DATA_DT, DATA_S, DATA_DT, DATA_S, DATA_DT, DATA_S, NULL, NULL, NULL,
+               NULL},
+       {SIZE_DT, SIZE_S, SIZE_DT, SIZE_S, SIZE_DT, SIZE_S, NULL, NULL, NULL,
+               NULL},
        {2000, 2000, 2000, 2000, 2000, 12000, 0, 0, 0, 0} },
 
        {TONE_GERMAN_RINGING,
@@ -434,7 +440,7 @@ dsp_tone_hw_message(struct dsp *dsp, u8 *sample, int len)
 
        /* unlocking is not required, because we don't expect a response */
        nskb = _alloc_mISDN_skb(PH_CONTROL_REQ,
-               (len)?HFC_SPL_LOOP_ON:HFC_SPL_LOOP_OFF, len, sample,
+               (len) ? HFC_SPL_LOOP_ON : HFC_SPL_LOOP_OFF, len, sample,
                GFP_ATOMIC);
        if (nskb) {
                if (dsp->ch.peer) {
@@ -498,8 +504,7 @@ dsp_tone(struct dsp *dsp, int tone)
 
        /* we turn off the tone */
        if (!tone) {
-               if (dsp->features.hfc_loops)
-               if (timer_pending(&tonet->tl))
+               if (dsp->features.hfc_loops && timer_pending(&tonet->tl))
                        del_timer(&tonet->tl);
                if (dsp->features.hfc_loops)
                        dsp_tone_hw_message(dsp, NULL, 0);
index ab1168a110ae96104c7db2ea8ea12ae214d83fe1..0481a0cdf6db9a1915ea8423f4d389655e86c66f 100644 (file)
@@ -185,13 +185,13 @@ recv_Echannel(struct dchannel *ech, struct dchannel *dch)
 EXPORT_SYMBOL(recv_Echannel);
 
 void
-recv_Bchannel(struct bchannel *bch)
+recv_Bchannel(struct bchannel *bch, unsigned int id)
 {
        struct mISDNhead *hh;
 
        hh = mISDN_HEAD_P(bch->rx_skb);
        hh->prim = PH_DATA_IND;
-       hh->id = MISDN_ID_ANY;
+       hh->id = id;
        if (bch->rcount >= 64) {
                printk(KERN_WARNING "B-channel %p receive queue overflow, "
                        "fushing!\n", bch);
index a23d575449f607c70ad9a575ee9ac38b9ac39564..bc26c890d9a281b663c3ec5b832cc845ba6729de 100644 (file)
@@ -76,7 +76,7 @@ struct l1oip {
        struct sockaddr_in      sin_local;      /* local socket name */
        struct sockaddr_in      sin_remote;     /* remote socket name */
        struct msghdr           sendmsg;        /* ip message to send */
-       struct iovec            sendiov;        /* iov for message */
+       struct kvec             sendiov;        /* iov for message */
 
        /* frame */
        struct l1oip_chan       chan[128];      /* channel instances */
index e4ecba3d48dfcf75703aee66c5a443b9f39c2c62..bbfd1b863ed3da49f95138ed3389c2ba4336df05 100644 (file)
@@ -48,6 +48,7 @@ NOTE: The bytes are handled as they are law-encoded.
 
 #include <linux/vmalloc.h>
 #include <linux/mISDNif.h>
+#include <linux/in.h>
 #include "core.h"
 #include "l1oip.h"
 
index abe574989572098bac2b9e0899c99ee9d08e6dd7..990e6a7e6674dce0c866083fc576ce8acb1d9e52 100644 (file)
@@ -279,7 +279,6 @@ l1oip_socket_send(struct l1oip *hc, u8 localcodec, u8 channel, u32 chanmask,
        int multi = 0;
        u8 frame[len+32];
        struct socket *socket = NULL;
-       mm_segment_t oldfs;
 
        if (debug & DEBUG_L1OIP_MSG)
                printk(KERN_DEBUG "%s: sending data to socket (len = %d)\n",
@@ -308,8 +307,8 @@ l1oip_socket_send(struct l1oip *hc, u8 localcodec, u8 channel, u32 chanmask,
 
        /* assemble frame */
        *p++ = (L1OIP_VERSION<<6) /* version and coding */
-            | (hc->pri?0x20:0x00) /* type */
-            | (hc->id?0x10:0x00) /* id */
+            | (hc->pri ? 0x20 : 0x00) /* type */
+            | (hc->id ? 0x10 : 0x00) /* id */
             | localcodec;
        if (hc->id) {
                *p++ = hc->id>>24; /* id */
@@ -317,7 +316,7 @@ l1oip_socket_send(struct l1oip *hc, u8 localcodec, u8 channel, u32 chanmask,
                *p++ = hc->id>>8;
                *p++ = hc->id;
        }
-       *p++ = (multi == 1)?0x80:0x00 + channel; /* m-flag, channel */
+       *p++ = (multi == 1) ? 0x80 : 0x00 + channel; /* m-flag, channel */
        if (multi == 1)
                *p++ = len; /* length */
        *p++ = timebase>>8; /* time base */
@@ -352,10 +351,7 @@ l1oip_socket_send(struct l1oip *hc, u8 localcodec, u8 channel, u32 chanmask,
                        "= %d)\n", __func__, len);
        hc->sendiov.iov_base = frame;
        hc->sendiov.iov_len  = len;
-       oldfs = get_fs();
-       set_fs(KERNEL_DS);
-       len = sock_sendmsg(socket, &hc->sendmsg, len);
-       set_fs(oldfs);
+       len = kernel_sendmsg(socket, &hc->sendmsg, &hc->sendiov, 1, len);
        /* give socket back */
        hc->socket = socket; /* no locking required */
 
@@ -401,12 +397,12 @@ l1oip_socket_recv(struct l1oip *hc, u8 remotecodec, u8 channel, u16 timebase,
        }
 
        /* prepare message */
-       nskb = mI_alloc_skb((remotecodec == 3)?(len<<1):len, GFP_ATOMIC);
+       nskb = mI_alloc_skb((remotecodec == 3) ? (len<<1) : len, GFP_ATOMIC);
        if (!nskb) {
                printk(KERN_ERR "%s: No mem for skb.\n", __func__);
                return;
        }
-       p = skb_put(nskb, (remotecodec == 3)?(len<<1):len);
+       p = skb_put(nskb, (remotecodec == 3) ? (len<<1) : len);
 
        if (remotecodec == 1 && ulaw)
                l1oip_alaw_to_ulaw(buf, len, p);
@@ -458,7 +454,7 @@ l1oip_socket_recv(struct l1oip *hc, u8 remotecodec, u8 channel, u16 timebase,
                hc->chan[channel].disorder_flag ^= 1;
                if (nskb)
 #endif
-               queue_ch_frame(&bch->ch, PH_DATA_IND, rx_counter, nskb);
+                       queue_ch_frame(&bch->ch, PH_DATA_IND, rx_counter, nskb);
        }
 }
 
@@ -660,21 +656,29 @@ l1oip_socket_thread(void *data)
        struct l1oip *hc = (struct l1oip *)data;
        int ret = 0;
        struct msghdr msg;
-       struct iovec iov;
-       mm_segment_t oldfs;
        struct sockaddr_in sin_rx;
-       unsigned char recvbuf[1500];
+       unsigned char *recvbuf;
+       size_t recvbuf_size = 1500;
        int recvlen;
        struct socket *socket = NULL;
        DECLARE_COMPLETION(wait);
 
+       /* allocate buffer memory */
+       recvbuf = kmalloc(recvbuf_size, GFP_KERNEL);
+       if (!recvbuf) {
+               printk(KERN_ERR "%s: Failed to alloc recvbuf.\n", __func__);
+               ret = -ENOMEM;
+               goto fail;
+       }
+
        /* make daemon */
        allow_signal(SIGTERM);
 
        /* create socket */
        if (sock_create(PF_INET, SOCK_DGRAM, IPPROTO_UDP, &socket)) {
                printk(KERN_ERR "%s: Failed to create socket.\n", __func__);
-               return -EIO;
+               ret = -EIO;
+               goto fail;
        }
 
        /* set incoming address */
@@ -708,16 +712,12 @@ l1oip_socket_thread(void *data)
        msg.msg_namelen = sizeof(sin_rx);
        msg.msg_control = NULL;
        msg.msg_controllen = 0;
-       msg.msg_iov = &iov;
-       msg.msg_iovlen = 1;
 
        /* build send message */
        hc->sendmsg.msg_name = &hc->sin_remote;
        hc->sendmsg.msg_namelen = sizeof(hc->sin_remote);
        hc->sendmsg.msg_control = NULL;
        hc->sendmsg.msg_controllen = 0;
-       hc->sendmsg.msg_iov    = &hc->sendiov;
-       hc->sendmsg.msg_iovlen = 1;
 
        /* give away socket */
        spin_lock(&hc->socket_lock);
@@ -729,18 +729,18 @@ l1oip_socket_thread(void *data)
                printk(KERN_DEBUG "%s: socket created and open\n",
                        __func__);
        while (!signal_pending(current)) {
-               iov.iov_base = recvbuf;
-               iov.iov_len = sizeof(recvbuf);
-               oldfs = get_fs();
-               set_fs(KERNEL_DS);
-               recvlen = sock_recvmsg(socket, &msg, sizeof(recvbuf), 0);
-               set_fs(oldfs);
+               struct kvec iov = {
+                       .iov_base = recvbuf,
+                       .iov_len = sizeof(recvbuf),
+               };
+               recvlen = kernel_recvmsg(socket, &msg, &iov, 1,
+                                        sizeof(recvbuf), 0);
                if (recvlen > 0) {
                        l1oip_socket_parse(hc, &sin_rx, recvbuf, recvlen);
                } else {
                        if (debug & DEBUG_L1OIP_SOCKET)
-                           printk(KERN_WARNING "%s: broken pipe on socket\n",
-                               __func__);
+                               printk(KERN_WARNING
+                                   "%s: broken pipe on socket\n", __func__);
                }
        }
 
@@ -760,6 +760,9 @@ l1oip_socket_thread(void *data)
                        __func__);
 
 fail:
+       /* free recvbuf */
+       kfree(recvbuf);
+
        /* close socket */
        if (socket)
                sock_release(socket);
@@ -912,7 +915,7 @@ handle_dmsg(struct mISDNchannel *ch, struct sk_buff *skb)
                p = skb->data;
                l = skb->len;
                while (l) {
-                       ll = (l < L1OIP_MAX_PERFRAME)?l:L1OIP_MAX_PERFRAME;
+                       ll = (l < L1OIP_MAX_PERFRAME) ? l : L1OIP_MAX_PERFRAME;
                        l1oip_socket_send(hc, 0, dch->slot, 0,
                                hc->chan[dch->slot].tx_counter++, p, ll);
                        p += ll;
@@ -1160,7 +1163,7 @@ handle_bmsg(struct mISDNchannel *ch, struct sk_buff *skb)
                p = skb->data;
                l = skb->len;
                while (l) {
-                       ll = (l < L1OIP_MAX_PERFRAME)?l:L1OIP_MAX_PERFRAME;
+                       ll = (l < L1OIP_MAX_PERFRAME) ? l : L1OIP_MAX_PERFRAME;
                        l1oip_socket_send(hc, hc->codec, bch->slot, 0,
                                hc->chan[bch->slot].tx_counter, p, ll);
                        hc->chan[bch->slot].tx_counter += ll;
@@ -1318,8 +1321,8 @@ init_card(struct l1oip *hc, int pri, int bundle)
        spin_lock_init(&hc->socket_lock);
        hc->idx = l1oip_cnt;
        hc->pri = pri;
-       hc->d_idx = pri?16:3;
-       hc->b_num = pri?30:2;
+       hc->d_idx = pri ? 16 : 3;
+       hc->b_num = pri ? 30 : 2;
        hc->bundle = bundle;
        if (hc->pri)
                sprintf(hc->name, "l1oip-e1.%d", l1oip_cnt + 1);
@@ -1504,9 +1507,9 @@ l1oip_init(void)
 
                if (debug & DEBUG_L1OIP_INIT)
                        printk(KERN_DEBUG "%s: interface %d is %s with %s.\n",
-                               __func__, l1oip_cnt, pri?"PRI":"BRI",
-                               bundle?"bundled IP packet for all B-channels"
-                                :"seperate IP packets for every B-channel");
+                           __func__, l1oip_cnt, pri ? "PRI" : "BRI",
+                           bundle ? "bundled IP packet for all B-channels" :
+                           "seperate IP packets for every B-channel");
 
                hc = kzalloc(sizeof(struct l1oip), GFP_ATOMIC);
                if (!hc) {
index d6e2863f224a4aa6c0f76adac0681bf173ec81f9..9c2589e986d6b185c7f555b48f4de7c1d5653b2d 100644 (file)
@@ -99,7 +99,7 @@ l2m_debug(struct FsmInst *fi, char *fmt, ...)
        if (!(*debug & DEBUG_L2_FSM))
                return;
        va_start(va, fmt);
-       printk(KERN_DEBUG "l2 (tei %d): ", l2->tei);
+       printk(KERN_DEBUG "l2 (sapi %d tei %d): ", l2->sapi, l2->tei);
        vprintk(fmt, va);
        printk("\n");
        va_end(va);
@@ -1859,20 +1859,18 @@ ph_data_indication(struct layer2 *l2, struct mISDNhead *hh, struct sk_buff *skb)
                psapi >>= 2;
                ptei >>= 1;
                if (psapi != l2->sapi) {
-                       /* not our bussiness
-                        * printk(KERN_DEBUG "%s: sapi %d/%d sapi mismatch\n",
-                        *  __func__,
-                        *      psapi, l2->sapi);
-                        */
+                       /* not our bussiness */
+                       if (*debug & DEBUG_L2)
+                               printk(KERN_DEBUG "%s: sapi %d/%d mismatch\n",
+                                       __func__, psapi, l2->sapi);
                        dev_kfree_skb(skb);
                        return 0;
                }
                if ((ptei != l2->tei) && (ptei != GROUP_TEI)) {
-                       /* not our bussiness
-                        * printk(KERN_DEBUG "%s: tei %d/%d sapi %d mismatch\n",
-                        *  __func__,
-                        *      ptei, l2->tei, psapi);
-                        */
+                       /* not our bussiness */
+                       if (*debug & DEBUG_L2)
+                               printk(KERN_DEBUG "%s: tei %d/%d mismatch\n",
+                                       __func__, ptei, l2->tei);
                        dev_kfree_skb(skb);
                        return 0;
                }
@@ -1927,8 +1925,8 @@ l2_send(struct mISDNchannel *ch, struct sk_buff *skb)
        int                     ret = -EINVAL;
 
        if (*debug & DEBUG_L2_RECV)
-               printk(KERN_DEBUG "%s: prim(%x) id(%x) tei(%d)\n",
-                   __func__, hh->prim, hh->id, l2->tei);
+               printk(KERN_DEBUG "%s: prim(%x) id(%x) sapi(%d) tei(%d)\n",
+                   __func__, hh->prim, hh->id, l2->sapi, l2->tei);
        switch (hh->prim) {
        case PH_DATA_IND:
                ret = ph_data_indication(l2, hh, skb);
@@ -2068,7 +2066,8 @@ l2_ctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
 }
 
 struct layer2 *
-create_l2(struct mISDNchannel *ch, u_int protocol, u_long options, u_long arg)
+create_l2(struct mISDNchannel *ch, u_int protocol, u_long options, int tei,
+               int sapi)
 {
        struct layer2           *l2;
        struct channel_req      rq;
@@ -2089,7 +2088,7 @@ create_l2(struct mISDNchannel *ch, u_int protocol, u_long options, u_long arg)
                test_and_set_bit(FLG_LAPD, &l2->flag);
                test_and_set_bit(FLG_LAPD_NET, &l2->flag);
                test_and_set_bit(FLG_MOD128, &l2->flag);
-               l2->sapi = 0;
+               l2->sapi = sapi;
                l2->maxlen = MAX_DFRAME_LEN;
                if (test_bit(OPTION_L2_PMX, &options))
                        l2->window = 7;
@@ -2099,7 +2098,7 @@ create_l2(struct mISDNchannel *ch, u_int protocol, u_long options, u_long arg)
                        test_and_set_bit(FLG_PTP, &l2->flag);
                if (test_bit(OPTION_L2_FIXEDTEI, &options))
                        test_and_set_bit(FLG_FIXED_TEI, &l2->flag);
-               l2->tei = (u_int)arg;
+               l2->tei = tei;
                l2->T200 = 1000;
                l2->N200 = 3;
                l2->T203 = 10000;
@@ -2114,7 +2113,7 @@ create_l2(struct mISDNchannel *ch, u_int protocol, u_long options, u_long arg)
                test_and_set_bit(FLG_LAPD, &l2->flag);
                test_and_set_bit(FLG_MOD128, &l2->flag);
                test_and_set_bit(FLG_ORIG, &l2->flag);
-               l2->sapi = 0;
+               l2->sapi = sapi;
                l2->maxlen = MAX_DFRAME_LEN;
                if (test_bit(OPTION_L2_PMX, &options))
                        l2->window = 7;
@@ -2124,7 +2123,7 @@ create_l2(struct mISDNchannel *ch, u_int protocol, u_long options, u_long arg)
                        test_and_set_bit(FLG_PTP, &l2->flag);
                if (test_bit(OPTION_L2_FIXEDTEI, &options))
                        test_and_set_bit(FLG_FIXED_TEI, &l2->flag);
-               l2->tei = (u_int)arg;
+               l2->tei = tei;
                l2->T200 = 1000;
                l2->N200 = 3;
                l2->T203 = 10000;
@@ -2180,7 +2179,7 @@ x75create(struct channel_req *crq)
 
        if (crq->protocol != ISDN_P_B_X75SLP)
                return -EPROTONOSUPPORT;
-       l2 = create_l2(crq->ch, crq->protocol, 0, 0);
+       l2 = create_l2(crq->ch, crq->protocol, 0, 0, 0);
        if (!l2)
                return -ENOMEM;
        crq->ch = &l2->ch;
index 6293f80dc2d3762bfcb5579490a542271bf8890f..9547fb3707a31f6ad60f1b051d6c22892de49029 100644 (file)
@@ -90,7 +90,7 @@ enum {
 #define L2_STATE_COUNT (ST_L2_8+1)
 
 extern struct layer2   *create_l2(struct mISDNchannel *, u_int,
-                               u_long, u_long);
+                               u_long, int, int);
 extern int             tei_l2(struct layer2 *, u_int, u_long arg);
 
 
index 508945d1b9c1a4b3ac18a31471179f13097a8cc3..c36f521374562271c5c4dba4890303a99ffbc069 100644 (file)
@@ -209,7 +209,7 @@ mISDN_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
 
        if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
                err = -EFAULT;
-               goto drop;
+               goto done;
        }
 
        memcpy(mISDN_HEAD_P(skb), skb->data, MISDN_HEADER_LEN);
@@ -222,7 +222,7 @@ mISDN_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
        } else { /* use default for L2 messages */
                if ((sk->sk_protocol == ISDN_P_LAPD_TE) ||
                    (sk->sk_protocol == ISDN_P_LAPD_NT))
-                   mISDN_HEAD_ID(skb) = _pms(sk)->ch.nr;
+                       mISDN_HEAD_ID(skb) = _pms(sk)->ch.nr;
        }
 
        if (*debug & DEBUG_SOCKET)
@@ -230,19 +230,21 @@ mISDN_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
                     __func__, mISDN_HEAD_ID(skb));
 
        err = -ENODEV;
-       if (!_pms(sk)->ch.peer ||
-           (err = _pms(sk)->ch.recv(_pms(sk)->ch.peer, skb)))
-               goto drop;
-
-       err = len;
+       if (!_pms(sk)->ch.peer)
+               goto done;
+       err = _pms(sk)->ch.recv(_pms(sk)->ch.peer, skb);
+       if (err)
+               goto done;
+       else {
+               skb = NULL;
+               err = len;
+       }
 
 done:
+       if (skb)
+               kfree_skb(skb);
        release_sock(sk);
        return err;
-
-drop:
-       kfree_skb(skb);
-       goto done;
 }
 
 static int
@@ -292,7 +294,7 @@ static int
 data_sock_ioctl_bound(struct sock *sk, unsigned int cmd, void __user *p)
 {
        struct mISDN_ctrl_req   cq;
-       int                     err = -EINVAL, val;
+       int                     err = -EINVAL, val[2];
        struct mISDNchannel     *bchan, *next;
 
        lock_sock(sk);
@@ -328,12 +330,27 @@ data_sock_ioctl_bound(struct sock *sk, unsigned int cmd, void __user *p)
                        err = -EINVAL;
                        break;
                }
-               if (get_user(val, (int __user *)p)) {
+               val[0] = cmd;
+               if (get_user(val[1], (int __user *)p)) {
+                       err = -EFAULT;
+                       break;
+               }
+               err = _pms(sk)->dev->teimgr->ctrl(_pms(sk)->dev->teimgr,
+                   CONTROL_CHANNEL, val);
+               break;
+       case IMHOLD_L1:
+               if (sk->sk_protocol != ISDN_P_LAPD_NT
+                && sk->sk_protocol != ISDN_P_LAPD_TE) {
+                       err = -EINVAL;
+                       break;
+               }
+               val[0] = cmd;
+               if (get_user(val[1], (int __user *)p)) {
                        err = -EFAULT;
                        break;
                }
                err = _pms(sk)->dev->teimgr->ctrl(_pms(sk)->dev->teimgr,
-                   CONTROL_CHANNEL, &val);
+                   CONTROL_CHANNEL, val);
                break;
        default:
                err = -EINVAL;
index b452dead8fd04e3fc782ec81fe68914c75f7b6b5..e04bad6c5bafbf0a13d5978a73b2dd4429edf415 100644 (file)
@@ -122,8 +122,11 @@ da_deactivate(struct FsmInst *fi, int event, void *arg)
        }
        read_unlock_irqrestore(&mgr->lock, flags);
        /* All TEI are inactiv */
-       mISDN_FsmAddTimer(&mgr->datimer, DATIMER_VAL, EV_DATIMER, NULL, 1);
-       mISDN_FsmChangeState(fi, ST_L1_DEACT_PENDING);
+       if (!test_bit(OPTION_L1_HOLD, &mgr->options)) {
+               mISDN_FsmAddTimer(&mgr->datimer, DATIMER_VAL, EV_DATIMER,
+                       NULL, 1);
+               mISDN_FsmChangeState(fi, ST_L1_DEACT_PENDING);
+       }
 }
 
 static void
@@ -132,9 +135,11 @@ da_ui(struct FsmInst *fi, int event, void *arg)
        struct manager  *mgr = fi->userdata;
 
        /* restart da timer */
-       mISDN_FsmDelTimer(&mgr->datimer, 2);
-       mISDN_FsmAddTimer(&mgr->datimer, DATIMER_VAL, EV_DATIMER, NULL, 2);
-
+       if (!test_bit(OPTION_L1_HOLD, &mgr->options)) {
+               mISDN_FsmDelTimer(&mgr->datimer, 2);
+               mISDN_FsmAddTimer(&mgr->datimer, DATIMER_VAL, EV_DATIMER,
+                       NULL, 2);
+       }
 }
 
 static void
@@ -222,7 +227,7 @@ tei_debug(struct FsmInst *fi, char *fmt, ...)
        if (!(*debug & DEBUG_L2_TEIFSM))
                return;
        va_start(va, fmt);
-       printk(KERN_DEBUG "tei(%d): ", tm->l2->tei);
+       printk(KERN_DEBUG "sapi(%d) tei(%d): ", tm->l2->sapi, tm->l2->tei);
        vprintk(fmt, va);
        printk("\n");
        va_end(va);
@@ -421,7 +426,7 @@ done:
 }
 
 static void
-put_tei_msg(struct manager *mgr, u_char m_id, unsigned int ri, u_char tei)
+put_tei_msg(struct manager *mgr, u_char m_id, unsigned int ri, int tei)
 {
        struct sk_buff *skb;
        u_char bp[8];
@@ -435,9 +440,8 @@ put_tei_msg(struct manager *mgr, u_char m_id, unsigned int ri, u_char tei)
        bp[4] = ri >> 8;
        bp[5] = ri & 0xff;
        bp[6] = m_id;
-       bp[7] = (tei << 1) | 1;
-       skb = _alloc_mISDN_skb(PH_DATA_REQ, new_id(mgr),
-           8, bp, GFP_ATOMIC);
+       bp[7] = ((tei << 1) & 0xff) | 1;
+       skb = _alloc_mISDN_skb(PH_DATA_REQ, new_id(mgr), 8, bp, GFP_ATOMIC);
        if (!skb) {
                printk(KERN_WARNING "%s: no skb for tei msg\n", __func__);
                return;
@@ -772,7 +776,7 @@ tei_ph_data_ind(struct teimgr *tm, u_int mt, u_char *dp, int len)
 }
 
 static struct layer2 *
-create_new_tei(struct manager *mgr, int tei)
+create_new_tei(struct manager *mgr, int tei, int sapi)
 {
        u_long          opt = 0;
        u_long          flags;
@@ -781,12 +785,12 @@ create_new_tei(struct manager *mgr, int tei)
 
        if (!mgr->up)
                return NULL;
-       if (tei < 64)
+       if ((tei >= 0) && (tei < 64))
                test_and_set_bit(OPTION_L2_FIXEDTEI, &opt);
        if (mgr->ch.st->dev->Dprotocols
          & ((1 << ISDN_P_TE_E1) | (1 << ISDN_P_NT_E1)))
                test_and_set_bit(OPTION_L2_PMX, &opt);
-       l2 = create_l2(mgr->up, ISDN_P_LAPD_NT, (u_int)opt, (u_long)tei);
+       l2 = create_l2(mgr->up, ISDN_P_LAPD_NT, opt, tei, sapi);
        if (!l2) {
                printk(KERN_WARNING "%s:no memory for layer2\n", __func__);
                return NULL;
@@ -834,12 +838,17 @@ new_tei_req(struct manager *mgr, u_char *dp)
        ri += dp[1];
        if (!mgr->up)
                goto denied;
-       tei = get_free_tei(mgr);
+       if (!(dp[3] & 1)) /* Extension bit != 1 */
+               goto denied;
+       if (dp[3] != 0xff)
+               tei = dp[3] >> 1; /* 3GPP TS 08.56 6.1.11.2 */
+       else
+               tei = get_free_tei(mgr);
        if (tei < 0) {
                printk(KERN_WARNING "%s:No free tei\n", __func__);
                goto denied;
        }
-       l2 = create_new_tei(mgr, tei);
+       l2 = create_new_tei(mgr, tei, CTRL_SAPI);
        if (!l2)
                goto denied;
        else
@@ -853,8 +862,7 @@ static int
 ph_data_ind(struct manager *mgr, struct sk_buff *skb)
 {
        int             ret = -EINVAL;
-       struct layer2   *l2;
-       u_long          flags;
+       struct layer2   *l2, *nl2;
        u_char          mt;
 
        if (skb->len < 8) {
@@ -863,7 +871,6 @@ ph_data_ind(struct manager *mgr, struct sk_buff *skb)
                            __func__, skb->len);
                goto done;
        }
-       if (*debug  & DEBUG_L2_TEI)
 
        if ((skb->data[0] >> 2) != TEI_SAPI) /* not for us */
                goto done;
@@ -900,11 +907,9 @@ ph_data_ind(struct manager *mgr, struct sk_buff *skb)
                new_tei_req(mgr, &skb->data[4]);
                goto done;
        }
-       read_lock_irqsave(&mgr->lock, flags);
-       list_for_each_entry(l2, &mgr->layer2, list) {
+       list_for_each_entry_safe(l2, nl2, &mgr->layer2, list) {
                tei_ph_data_ind(l2->tm, mt, &skb->data[4], skb->len - 4);
        }
-       read_unlock_irqrestore(&mgr->lock, flags);
 done:
        return ret;
 }
@@ -971,8 +976,6 @@ create_teimgr(struct manager *mgr, struct channel_req *crq)
                        __func__, dev_name(&mgr->ch.st->dev->dev),
                        crq->protocol, crq->adr.dev, crq->adr.channel,
                        crq->adr.sapi, crq->adr.tei);
-       if (crq->adr.sapi != 0) /* not supported yet */
-               return -EINVAL;
        if (crq->adr.tei > GROUP_TEI)
                return -EINVAL;
        if (crq->adr.tei < 64)
@@ -1019,8 +1022,8 @@ create_teimgr(struct manager *mgr, struct channel_req *crq)
                }
                return 0;
        }
-       l2 = create_l2(crq->ch, crq->protocol, (u_int)opt,
-               (u_long)crq->adr.tei);
+       l2 = create_l2(crq->ch, crq->protocol, opt,
+               crq->adr.tei, crq->adr.sapi);
        if (!l2)
                return -ENOMEM;
        l2->tm = kzalloc(sizeof(struct teimgr), GFP_KERNEL);
@@ -1103,6 +1106,7 @@ free_teimanager(struct manager *mgr)
 {
        struct layer2   *l2, *nl2;
 
+       test_and_clear_bit(OPTION_L1_HOLD, &mgr->options);
        if (test_bit(MGR_OPT_NETWORK, &mgr->options)) {
                /* not locked lock is taken in release tei */
                mgr->up = NULL;
@@ -1133,13 +1137,26 @@ static int
 ctrl_teimanager(struct manager *mgr, void *arg)
 {
        /* currently we only have one option */
-       int     clean = *((int *)arg);
-
-       if (clean)
-               test_and_set_bit(OPTION_L2_CLEANUP, &mgr->options);
-       else
-               test_and_clear_bit(OPTION_L2_CLEANUP, &mgr->options);
-       return 0;
+       int     *val = (int *)arg;
+       int     ret = 0;
+
+       switch (val[0]) {
+       case IMCLEAR_L2:
+               if (val[1])
+                       test_and_set_bit(OPTION_L2_CLEANUP, &mgr->options);
+               else
+                       test_and_clear_bit(OPTION_L2_CLEANUP, &mgr->options);
+               break;
+       case IMHOLD_L1:
+               if (val[1])
+                       test_and_set_bit(OPTION_L1_HOLD, &mgr->options);
+               else
+                       test_and_clear_bit(OPTION_L1_HOLD, &mgr->options);
+               break;
+       default:
+               ret = -EINVAL;
+       }
+       return ret;
 }
 
 /* This function does create a L2 for fixed TEI in NT Mode */
@@ -1147,7 +1164,7 @@ static int
 check_data(struct manager *mgr, struct sk_buff *skb)
 {
        struct mISDNhead        *hh =  mISDN_HEAD_P(skb);
-       int                     ret, tei;
+       int                     ret, tei, sapi;
        struct layer2           *l2;
 
        if (*debug & DEBUG_L2_CTRL)
@@ -1159,20 +1176,27 @@ check_data(struct manager *mgr, struct sk_buff *skb)
                return -ENOTCONN;
        if (skb->len != 3)
                return -ENOTCONN;
-       if (skb->data[0] != 0)
-               /* only SAPI 0 command */
-               return -ENOTCONN;
+       if (skb->data[0] & 3) /* EA0 and CR must be  0 */
+               return -EINVAL;
+       sapi = skb->data[0] >> 2;
        if (!(skb->data[1] & 1)) /* invalid EA1 */
                return -EINVAL;
-       tei = skb->data[1] >> 0;
+       tei = skb->data[1] >> 1;
        if (tei > 63) /* not a fixed tei */
                return -ENOTCONN;
        if ((skb->data[2] & ~0x10) != SABME)
                return -ENOTCONN;
        /* We got a SABME for a fixed TEI */
-       l2 = create_new_tei(mgr, tei);
-       if (!l2)
+       if (*debug & DEBUG_L2_CTRL)
+               printk(KERN_DEBUG "%s: SABME sapi(%d) tei(%d)\n",
+                   __func__, sapi, tei);
+       l2 = create_new_tei(mgr, tei, sapi);
+       if (!l2) {
+               if (*debug & DEBUG_L2_CTRL)
+                       printk(KERN_DEBUG "%s: failed to create new tei\n",
+                           __func__);
                return -ENOMEM;
+       }
        ret = l2->ch.send(&l2->ch, skb);
        return ret;
 }
index bbd99d3282c0cf32299086fe8575450ca042b75f..5b7e9bf514f10c59e55f7439fc82b7c8bfabd81a 100644 (file)
@@ -259,7 +259,7 @@ mISDN_ioctl(struct inode *inode, struct file *filep, unsigned int cmd,
        return ret;
 }
 
-static struct file_operations mISDN_fops = {
+static const struct file_operations mISDN_fops = {
        .read           = mISDN_read,
        .poll           = mISDN_poll,
        .ioctl          = mISDN_ioctl,
index c0621d50c8a0ca1281881b68d587f1c8be81ec96..0ddf9044948aeeb0a8d8affefb1c1afec36c252d 100644 (file)
@@ -37,6 +37,7 @@
 #define CONFIG_REG   0x40
 #define MANUAL_MASK  0xe0
 #define AUTO_MASK    0x20
+#define INVERT_MASK  0x10
 
 static u8 TEMP_REG[3]    = {0x26, 0x25, 0x27}; /* local, sensor1, sensor2 */
 static u8 LIMIT_REG[3]   = {0x6b, 0x6a, 0x6c}; /* local, sensor1, sensor2 */
@@ -229,7 +230,8 @@ static void write_fan_speed(struct thermostat *th, int speed, int fan)
        
        if (speed >= 0) {
                manual = read_reg(th, MANUAL_MODE[fan]);
-               write_reg(th, MANUAL_MODE[fan], manual|MANUAL_MASK);
+               write_reg(th, MANUAL_MODE[fan],
+                       (manual|MANUAL_MASK) & (~INVERT_MASK));
                write_reg(th, FAN_SPD_SET[fan], speed);
        } else {
                /* back to automatic */
index c2804f26cb44256a56a1dbb54213bd9d45eaca60..a9e48e28b1dc79fdd0d04b24a30a9bbbe258edfb 100644 (file)
@@ -703,7 +703,7 @@ mpt_lan_sdu_send (struct sk_buff *skb, struct net_device *dev)
 
                printk (KERN_ERR "%s: no tx context available: %u\n",
                        __func__, priv->mpt_txfidx_tail);
-               return 1;
+               return NETDEV_TX_BUSY;
        }
 
        mf = mpt_get_msg_frame(LanCtx, mpt_dev);
@@ -713,7 +713,7 @@ mpt_lan_sdu_send (struct sk_buff *skb, struct net_device *dev)
 
                printk (KERN_ERR "%s: Unable to alloc request frame\n",
                        __func__);
-               return 1;
+               return NETDEV_TX_BUSY;
        }
 
        ctx = priv->mpt_txfidx[priv->mpt_txfidx_tail--];
index 6faefcffcb53beb920541702ad1b574e4d578a5f..8d1c60a3f0df9cdb1e178ae85b6605b1557364fb 100644 (file)
@@ -450,7 +450,8 @@ xpnet_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
                         "packet\n", sizeof(struct xpnet_pending_msg));
 
                dev->stats.tx_errors++;
-               return -ENOMEM;
+               dev_kfree_skb(skb);
+               return NETDEV_TX_OK;
        }
 
        /* get the beginning of the first cacheline and end of last */
index 1c5344aa57cc32473a0b019d7ab1205e3df2b9e0..367bec63620cf6ccff9ae115d873f94def35b8f2 100644 (file)
@@ -281,7 +281,7 @@ static int __init el1_probe1(struct net_device *dev, int ioaddr)
                autoirq = probe_irq_off(irq_mask);
 
                if (autoirq == 0) {
-                       printk(KERN_WARNING "%s probe at %#x failed to detect IRQ line.\n",
+                       pr_warning("%s probe at %#x failed to detect IRQ line.\n",
                                mname, ioaddr);
                        release_region(ioaddr, EL1_IO_EXTENT);
                        return -EAGAIN;
@@ -297,16 +297,16 @@ static int __init el1_probe1(struct net_device *dev, int ioaddr)
        if (autoirq)
                dev->irq = autoirq;
 
-       printk(KERN_INFO "%s: %s EtherLink at %#lx, using %sIRQ %d.\n",
+       pr_info("%s: %s EtherLink at %#lx, using %sIRQ %d.\n",
                        dev->name, mname, dev->base_addr,
                        autoirq ? "auto":"assigned ", dev->irq);
 
 #ifdef CONFIG_IP_MULTICAST
-       printk(KERN_WARNING "WARNING: Use of the 3c501 in a multicast kernel is NOT recommended.\n");
+       pr_warning("WARNING: Use of the 3c501 in a multicast kernel is NOT recommended.\n");
 #endif
 
        if (el_debug)
-               printk(KERN_DEBUG "%s", version);
+               pr_debug("%s", version);
 
        lp = netdev_priv(dev);
        memset(lp, 0, sizeof(struct net_local));
@@ -343,7 +343,7 @@ static int el_open(struct net_device *dev)
        unsigned long flags;
 
        if (el_debug > 2)
-               printk(KERN_DEBUG "%s: Doing el_open()...", dev->name);
+               pr_debug("%s: Doing el_open()...\n", dev->name);
 
        retval = request_irq(dev->irq, &el_interrupt, 0, dev->name, dev);
        if (retval)
@@ -374,7 +374,7 @@ static void el_timeout(struct net_device *dev)
        int ioaddr = dev->base_addr;
 
        if (el_debug)
-               printk(KERN_DEBUG "%s: transmit timed out, txsr %#2x axsr=%02x rxsr=%02x.\n",
+               pr_debug("%s: transmit timed out, txsr %#2x axsr=%02x rxsr=%02x.\n",
                        dev->name, inb(TX_STATUS),
                        inb(AX_STATUS), inb(RX_STATUS));
        dev->stats.tx_errors++;
@@ -483,14 +483,13 @@ static int el_start_xmit(struct sk_buff *skb, struct net_device *dev)
                        lp->loading = 0;
                        dev->trans_start = jiffies;
                        if (el_debug > 2)
-                               printk(KERN_DEBUG " queued xmit.\n");
+                               pr_debug(" queued xmit.\n");
                        dev_kfree_skb(skb);
                        return 0;
                }
                /* A receive upset our load, despite our best efforts */
                if (el_debug > 2)
-                       printk(KERN_DEBUG "%s: burped during tx load.\n",
-                               dev->name);
+                       pr_debug("%s: burped during tx load.\n", dev->name);
                spin_lock_irqsave(&lp->lock, flags);
        } while (1);
 }
@@ -540,11 +539,10 @@ static irqreturn_t el_interrupt(int irq, void *dev_id)
         */
 
        if (el_debug > 3)
-               printk(KERN_DEBUG "%s: el_interrupt() aux=%#02x",
-                                                       dev->name, axsr);
+               pr_debug("%s: el_interrupt() aux=%#02x\n", dev->name, axsr);
 
        if (lp->loading == 1 && !lp->txing)
-               printk(KERN_WARNING "%s: Inconsistent state loading while not in tx\n",
+               pr_warning("%s: Inconsistent state loading while not in tx\n",
                        dev->name);
 
        if (lp->txing) {
@@ -555,19 +553,17 @@ static irqreturn_t el_interrupt(int irq, void *dev_id)
                int txsr = inb(TX_STATUS);
 
                if (lp->loading == 1) {
-                       if (el_debug > 2) {
-                               printk(KERN_DEBUG "%s: Interrupt while loading [",
-                                       dev->name);
-                               printk(" txsr=%02x gp=%04x rp=%04x]\n",
-                                       txsr, inw(GP_LOW), inw(RX_LOW));
-                       }
+                       if (el_debug > 2)
+                               pr_debug("%s: Interrupt while loading [txsr=%02x gp=%04x rp=%04x]\n",
+                                       dev->name, txsr, inw(GP_LOW), inw(RX_LOW));
+
                        /* Force a reload */
                        lp->loading = 2;
                        spin_unlock(&lp->lock);
                        goto out;
                }
                if (el_debug > 6)
-                       printk(KERN_DEBUG " txsr=%02x gp=%04x rp=%04x",
+                       pr_debug("%s: txsr=%02x gp=%04x rp=%04x\n", dev->name,
                                        txsr, inw(GP_LOW), inw(RX_LOW));
 
                if ((axsr & 0x80) && (txsr & TX_READY) == 0) {
@@ -576,7 +572,7 @@ static irqreturn_t el_interrupt(int irq, void *dev_id)
                         *      on trying or reset immediately ?
                         */
                        if (el_debug > 1)
-                               printk(KERN_DEBUG "%s: Unusual interrupt during Tx, txsr=%02x axsr=%02x gp=%03x rp=%03x.\n",
+                               pr_debug("%s: Unusual interrupt during Tx, txsr=%02x axsr=%02x gp=%03x rp=%03x.\n",
                                        dev->name, txsr, axsr,
                                        inw(ioaddr + EL1_DATAPTR),
                                        inw(ioaddr + EL1_RXPTR));
@@ -587,7 +583,7 @@ static irqreturn_t el_interrupt(int irq, void *dev_id)
                         *      Timed out
                         */
                        if (el_debug)
-                               printk(KERN_DEBUG "%s: Transmit failed 16 times, Ethernet jammed?\n", dev->name);
+                               pr_debug("%s: Transmit failed 16 times, Ethernet jammed?\n", dev->name);
                        outb(AX_SYS, AX_CMD);
                        lp->txing = 0;
                        dev->stats.tx_aborted_errors++;
@@ -598,7 +594,7 @@ static irqreturn_t el_interrupt(int irq, void *dev_id)
                         */
 
                        if (el_debug > 6)
-                               printk(KERN_DEBUG " retransmitting after a collision.\n");
+                               pr_debug("%s: retransmitting after a collision.\n", dev->name);
                        /*
                         *      Poor little chip can't reset its own start
                         *      pointer
@@ -616,9 +612,8 @@ static irqreturn_t el_interrupt(int irq, void *dev_id)
                         */
                        dev->stats.tx_packets++;
                        if (el_debug > 6)
-                               printk(KERN_DEBUG " Tx succeeded %s\n",
-                                       (txsr & TX_RDY) ? "." :
-                                                       "but tx is busy!");
+                               pr_debug("%s: Tx succeeded %s\n", dev->name,
+                                       (txsr & TX_RDY) ? "." : "but tx is busy!");
                        /*
                         *      This is safe the interrupt is atomic WRT itself.
                         */
@@ -633,7 +628,8 @@ static irqreturn_t el_interrupt(int irq, void *dev_id)
 
                int rxsr = inb(RX_STATUS);
                if (el_debug > 5)
-                       printk(KERN_DEBUG " rxsr=%02x txsr=%02x rp=%04x", rxsr, inb(TX_STATUS), inw(RX_LOW));
+                       pr_debug("%s: rxsr=%02x txsr=%02x rp=%04x\n",
+                               dev->name, rxsr, inb(TX_STATUS), inw(RX_LOW));
                /*
                 *      Just reading rx_status fixes most errors.
                 */
@@ -643,7 +639,7 @@ static irqreturn_t el_interrupt(int irq, void *dev_id)
                        /* Handled to avoid board lock-up. */
                        dev->stats.rx_length_errors++;
                        if (el_debug > 5)
-                               printk(KERN_DEBUG " runt.\n");
+                               pr_debug("%s: runt.\n", dev->name);
                } else if (rxsr & RX_GOOD) {
                        /*
                         *      Receive worked.
@@ -654,12 +650,10 @@ static irqreturn_t el_interrupt(int irq, void *dev_id)
                         *      Nothing?  Something is broken!
                         */
                        if (el_debug > 2)
-                               printk(KERN_DEBUG "%s: No packet seen, rxsr=%02x **resetting 3c501***\n",
+                               pr_debug("%s: No packet seen, rxsr=%02x **resetting 3c501***\n",
                                        dev->name, rxsr);
                        el_reset(dev);
                }
-               if (el_debug > 3)
-                       printk(KERN_DEBUG ".\n");
        }
 
        /*
@@ -695,11 +689,11 @@ static void el_receive(struct net_device *dev)
        pkt_len = inw(RX_LOW);
 
        if (el_debug > 4)
-               printk(KERN_DEBUG " el_receive %d.\n", pkt_len);
+               pr_debug(" el_receive %d.\n", pkt_len);
 
        if (pkt_len < 60 || pkt_len > 1536) {
                if (el_debug)
-                       printk(KERN_DEBUG "%s: bogus packet, length=%d\n",
+                       pr_debug("%s: bogus packet, length=%d\n",
                                                dev->name, pkt_len);
                dev->stats.rx_over_errors++;
                return;
@@ -718,8 +712,7 @@ static void el_receive(struct net_device *dev)
 
        outw(0x00, GP_LOW);
        if (skb == NULL) {
-               printk(KERN_INFO "%s: Memory squeeze, dropping packet.\n",
-                                                               dev->name);
+               pr_info("%s: Memory squeeze, dropping packet.\n", dev->name);
                dev->stats.rx_dropped++;
                return;
        } else {
@@ -753,7 +746,7 @@ static void  el_reset(struct net_device *dev)
        int ioaddr = dev->base_addr;
 
        if (el_debug > 2)
-               printk(KERN_INFO "3c501 reset...");
+               pr_info("3c501 reset...\n");
        outb(AX_RESET, AX_CMD);         /* Reset the chip */
        /* Aux control, irq and loopback enabled */
        outb(AX_LOOP, AX_CMD);
@@ -787,7 +780,7 @@ static int el1_close(struct net_device *dev)
        int ioaddr = dev->base_addr;
 
        if (el_debug > 2)
-               printk(KERN_INFO "%s: Shutting down Ethernet card at %#x.\n",
+               pr_info("%s: Shutting down Ethernet card at %#x.\n",
                                                dev->name, ioaddr);
 
        netif_stop_queue(dev);
index 4f08bd995836760285741b40110cf591819fd1e6..134638a9759fabbdc9f06150fce3d9d5a2523904 100644 (file)
@@ -234,16 +234,16 @@ el2_probe1(struct net_device *dev, int ioaddr)
     }
 
     if (ei_debug  &&  version_printed++ == 0)
-       printk(version);
+       pr_debug("%s", version);
 
     dev->base_addr = ioaddr;
 
-    printk("%s: 3c503 at i/o base %#3x, node ", dev->name, ioaddr);
+    pr_info("%s: 3c503 at i/o base %#3x, node ", dev->name, ioaddr);
 
     /* Retrieve and print the ethernet address. */
     for (i = 0; i < 6; i++)
        dev->dev_addr[i] = inb(ioaddr + i);
-    printk("%pM", dev->dev_addr);
+    pr_cont("%pM", dev->dev_addr);
 
     /* Map the 8390 back into the window. */
     outb(ECNTRL_THIN, ioaddr + 0x406);
@@ -256,7 +256,8 @@ el2_probe1(struct net_device *dev, int ioaddr)
     outb_p(E8390_PAGE0, ioaddr + E8390_CMD);
 
     /* Probe for, turn on and clear the board's shared memory. */
-    if (ei_debug > 2) printk(" memory jumpers %2.2x ", membase_reg);
+    if (ei_debug > 2)
+       pr_cont(" memory jumpers %2.2x ", membase_reg);
     outb(EGACFR_NORM, ioaddr + 0x405); /* Enable RAM */
 
     /* This should be probed for (or set via an ioctl()) at run-time.
@@ -268,7 +269,7 @@ el2_probe1(struct net_device *dev, int ioaddr)
 #else
     ei_status.interface_num = dev->mem_end & 0xf;
 #endif
-    printk(", using %sternal xcvr.\n", ei_status.interface_num == 0 ? "in" : "ex");
+    pr_cont(", using %sternal xcvr.\n", ei_status.interface_num == 0 ? "in" : "ex");
 
     if ((membase_reg & 0xf0) == 0) {
        dev->mem_start = 0;
@@ -292,7 +293,7 @@ el2_probe1(struct net_device *dev, int ioaddr)
                writel(test_val, mem_base + i);
                if (readl(mem_base) != 0xba5eba5e
                    || readl(mem_base + i) != test_val) {
-                   printk("3c503: memory failure or memory address conflict.\n");
+                   pr_warning("3c503: memory failure or memory address conflict.\n");
                    dev->mem_start = 0;
                    ei_status.name = "3c503-PIO";
                    iounmap(mem_base);
@@ -344,7 +345,7 @@ el2_probe1(struct net_device *dev, int ioaddr)
     if (dev->irq == 2)
        dev->irq = 9;
     else if (dev->irq > 5 && dev->irq != 9) {
-       printk("3c503: configured interrupt %d invalid, will use autoIRQ.\n",
+       pr_warning("3c503: configured interrupt %d invalid, will use autoIRQ.\n",
               dev->irq);
        dev->irq = 0;
     }
@@ -359,7 +360,7 @@ el2_probe1(struct net_device *dev, int ioaddr)
        goto out1;
 
     if (dev->mem_start)
-       printk("%s: %s - %dkB RAM, 8kB shared mem window at %#6lx-%#6lx.\n",
+       pr_info("%s: %s - %dkB RAM, 8kB shared mem window at %#6lx-%#6lx.\n",
                dev->name, ei_status.name, (wordlength+1)<<3,
                dev->mem_start, dev->mem_end-1);
 
@@ -367,7 +368,7 @@ el2_probe1(struct net_device *dev, int ioaddr)
     {
        ei_status.tx_start_page = EL2_MB1_START_PG;
        ei_status.rx_start_page = EL2_MB1_START_PG + TX_PAGES;
-       printk("\n%s: %s, %dkB RAM, using programmed I/O (REJUMPER for SHARED MEMORY).\n",
+       pr_info("%s: %s, %dkB RAM, using programmed I/O (REJUMPER for SHARED MEMORY).\n",
               dev->name, ei_status.name, (wordlength+1)<<3);
     }
     release_region(ioaddr + 0x400, 8);
@@ -435,15 +436,16 @@ static void
 el2_reset_8390(struct net_device *dev)
 {
     if (ei_debug > 1) {
-       printk("%s: Resetting the 3c503 board...", dev->name);
-       printk("%#lx=%#02x %#lx=%#02x %#lx=%#02x...", E33G_IDCFR, inb(E33G_IDCFR),
+       pr_debug("%s: Resetting the 3c503 board...", dev->name);
+       pr_cont(" %#lx=%#02x %#lx=%#02x %#lx=%#02x...", E33G_IDCFR, inb(E33G_IDCFR),
               E33G_CNTRL, inb(E33G_CNTRL), E33G_GACFR, inb(E33G_GACFR));
     }
     outb_p(ECNTRL_RESET|ECNTRL_THIN, E33G_CNTRL);
     ei_status.txing = 0;
     outb_p(ei_status.interface_num==0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL);
     el2_init_card(dev);
-    if (ei_debug > 1) printk("done\n");
+    if (ei_debug > 1)
+       pr_cont("done\n");
 }
 
 /* Initialize the 3c503 GA registers after a reset. */
@@ -529,7 +531,7 @@ el2_block_output(struct net_device *dev, int count,
         {
             if(!boguscount--)
             {
-                printk("%s: FIFO blocked in el2_block_output.\n", dev->name);
+                pr_notice("%s: FIFO blocked in el2_block_output.\n", dev->name);
                 el2_reset_8390(dev);
                 goto blocked;
             }
@@ -581,7 +583,7 @@ el2_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_pag
     {
         if(!boguscount--)
         {
-            printk("%s: FIFO blocked in el2_get_8390_hdr.\n", dev->name);
+            pr_notice("%s: FIFO blocked in el2_get_8390_hdr.\n", dev->name);
             memset(hdr, 0x00, sizeof(struct e8390_pkt_hdr));
             el2_reset_8390(dev);
             goto blocked;
@@ -645,7 +647,7 @@ el2_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring
         {
             if(!boguscount--)
             {
-                printk("%s: FIFO blocked in el2_block_input.\n", dev->name);
+                pr_notice("%s: FIFO blocked in el2_block_input.\n", dev->name);
                 el2_reset_8390(dev);
                 goto blocked;
             }
@@ -707,7 +709,7 @@ init_module(void)
        for (this_dev = 0; this_dev < MAX_EL2_CARDS; this_dev++) {
                if (io[this_dev] == 0)  {
                        if (this_dev != 0) break; /* only autoprobe 1st one */
-                       printk(KERN_NOTICE "3c503.c: Presently autoprobing (not recommended) for a single card.\n");
+                       pr_notice("3c503.c: Presently autoprobing (not recommended) for a single card.\n");
                }
                dev = alloc_eip_netdev();
                if (!dev)
@@ -720,7 +722,7 @@ init_module(void)
                        continue;
                }
                free_netdev(dev);
-               printk(KERN_WARNING "3c503.c: No 3c503 card found (i/o = 0x%x).\n", io[this_dev]);
+               pr_warning("3c503.c: No 3c503 card found (i/o = 0x%x).\n", io[this_dev]);
                break;
        }
        if (found)
index 2de1c9cd7bdeffaff03be9c88a024047b31ec1ae..f71b3540275540bb927446d6958265d642e7f8bf 100644 (file)
  *
  *********************************************************/
 
-static const char filename[] = __FILE__;
+#define filename __FILE__
 
-static const char timeout_msg[] = "*** timeout at %s:%s (line %d) ***\n";
+#define timeout_msg "*** timeout at %s:%s (line %d) ***\n"
 #define TIMEOUT_MSG(lineno) \
-       printk(timeout_msg, filename,__func__,(lineno))
+       pr_notice(timeout_msg, filename, __func__, (lineno))
 
-static const char invalid_pcb_msg[] =
-"*** invalid pcb length %d at %s:%s (line %d) ***\n";
+#define invalid_pcb_msg "*** invalid pcb length %d at %s:%s (line %d) ***\n"
 #define INVALID_PCB_MSG(len) \
-       printk(invalid_pcb_msg, (len),filename,__func__,__LINE__)
+       pr_notice(invalid_pcb_msg, (len), filename, __func__, __LINE__)
 
-static char search_msg[] __initdata = KERN_INFO "%s: Looking for 3c505 adapter at address %#x...";
+#define search_msg "%s: Looking for 3c505 adapter at address %#x..."
 
-static char stilllooking_msg[] __initdata = "still looking...";
+#define stilllooking_msg "still looking..."
 
-static char found_msg[] __initdata = "found.\n";
+#define found_msg "found.\n"
 
-static char notfound_msg[] __initdata = "not found (reason = %d)\n";
+#define notfound_msg "not found (reason = %d)\n"
 
-static char couldnot_msg[] __initdata = KERN_INFO "%s: 3c505 not found\n";
+#define couldnot_msg "%s: 3c505 not found\n"
 
 /*********************************************************
  *
@@ -284,7 +283,7 @@ static inline void adapter_reset(struct net_device *dev)
 
        outb_control(orig_hcr, dev);
        if (!start_receive(dev, &adapter->tx_pcb))
-               printk(KERN_ERR "%s: start receive command failed \n", dev->name);
+               pr_err("%s: start receive command failed\n", dev->name);
 }
 
 /* Check to make sure that a DMA transfer hasn't timed out.  This should
@@ -296,7 +295,9 @@ static inline void check_3c505_dma(struct net_device *dev)
        elp_device *adapter = netdev_priv(dev);
        if (adapter->dmaing && time_after(jiffies, adapter->current_dma.start_time + 10)) {
                unsigned long flags, f;
-               printk(KERN_ERR "%s: DMA %s timed out, %d bytes left\n", dev->name, adapter->current_dma.direction ? "download" : "upload", get_dma_residue(dev->dma));
+               pr_err("%s: DMA %s timed out, %d bytes left\n", dev->name,
+                       adapter->current_dma.direction ? "download" : "upload",
+                       get_dma_residue(dev->dma));
                spin_lock_irqsave(&adapter->lock, flags);
                adapter->dmaing = 0;
                adapter->busy = 0;
@@ -321,7 +322,7 @@ static inline bool send_pcb_slow(unsigned int base_addr, unsigned char byte)
                if (inb_status(base_addr) & HCRE)
                        return false;
        }
-       printk(KERN_WARNING "3c505: send_pcb_slow timed out\n");
+       pr_warning("3c505: send_pcb_slow timed out\n");
        return true;
 }
 
@@ -333,7 +334,7 @@ static inline bool send_pcb_fast(unsigned int base_addr, unsigned char byte)
                if (inb_status(base_addr) & HCRE)
                        return false;
        }
-       printk(KERN_WARNING "3c505: send_pcb_fast timed out\n");
+       pr_warning("3c505: send_pcb_fast timed out\n");
        return true;
 }
 
@@ -386,7 +387,7 @@ static bool send_pcb(struct net_device *dev, pcb_struct * pcb)
        /* Avoid contention */
        if (test_and_set_bit(1, &adapter->send_pcb_semaphore)) {
                if (elp_debug >= 3) {
-                       printk(KERN_DEBUG "%s: send_pcb entered while threaded\n", dev->name);
+                       pr_debug("%s: send_pcb entered while threaded\n", dev->name);
                }
                return false;
        }
@@ -424,14 +425,15 @@ static bool send_pcb(struct net_device *dev, pcb_struct * pcb)
 
                case ASF_PCB_NAK:
 #ifdef ELP_DEBUG
-                       printk(KERN_DEBUG "%s: send_pcb got NAK\n", dev->name);
+                       pr_debug("%s: send_pcb got NAK\n", dev->name);
 #endif
                        goto abort;
                }
        }
 
        if (elp_debug >= 1)
-               printk(KERN_DEBUG "%s: timeout waiting for PCB acknowledge (status %02x)\n", dev->name, inb_status(dev->base_addr));
+               pr_debug("%s: timeout waiting for PCB acknowledge (status %02x)\n",
+                       dev->name, inb_status(dev->base_addr));
        goto abort;
 
       sti_abort:
@@ -481,7 +483,7 @@ static bool receive_pcb(struct net_device *dev, pcb_struct * pcb)
        while (((stat = get_status(dev->base_addr)) & ACRF) == 0 && time_before(jiffies, timeout));
        if (time_after_eq(jiffies, timeout)) {
                TIMEOUT_MSG(__LINE__);
-               printk(KERN_INFO "%s: status %02x\n", dev->name, stat);
+               pr_info("%s: status %02x\n", dev->name, stat);
                return false;
        }
        pcb->length = inb_command(dev->base_addr);
@@ -518,7 +520,7 @@ static bool receive_pcb(struct net_device *dev, pcb_struct * pcb)
        /* safety check total length vs data length */
        if (total_length != (pcb->length + 2)) {
                if (elp_debug >= 2)
-                       printk(KERN_WARNING "%s: mangled PCB received\n", dev->name);
+                       pr_warning("%s: mangled PCB received\n", dev->name);
                set_hsf(dev, HSF_PCB_NAK);
                return false;
        }
@@ -527,7 +529,7 @@ static bool receive_pcb(struct net_device *dev, pcb_struct * pcb)
                if (test_and_set_bit(0, (void *) &adapter->busy)) {
                        if (backlog_next(adapter->rx_backlog.in) == adapter->rx_backlog.out) {
                                set_hsf(dev, HSF_PCB_NAK);
-                               printk(KERN_WARNING "%s: PCB rejected, transfer in progress and backlog full\n", dev->name);
+                               pr_warning("%s: PCB rejected, transfer in progress and backlog full\n", dev->name);
                                pcb->command = 0;
                                return true;
                        } else {
@@ -552,7 +554,7 @@ static bool start_receive(struct net_device *dev, pcb_struct * tx_pcb)
        elp_device *adapter = netdev_priv(dev);
 
        if (elp_debug >= 3)
-               printk(KERN_DEBUG "%s: restarting receiver\n", dev->name);
+               pr_debug("%s: restarting receiver\n", dev->name);
        tx_pcb->command = CMD_RECEIVE_PACKET;
        tx_pcb->length = sizeof(struct Rcv_pkt);
        tx_pcb->data.rcv_pkt.buf_seg
@@ -586,7 +588,7 @@ static void receive_packet(struct net_device *dev, int len)
        skb = dev_alloc_skb(rlen + 2);
 
        if (!skb) {
-               printk(KERN_WARNING "%s: memory squeeze, dropping packet\n", dev->name);
+               pr_warning("%s: memory squeeze, dropping packet\n", dev->name);
                target = adapter->dma_buffer;
                adapter->current_dma.target = NULL;
                /* FIXME: stats */
@@ -604,7 +606,8 @@ static void receive_packet(struct net_device *dev, int len)
 
        /* if this happens, we die */
        if (test_and_set_bit(0, (void *) &adapter->dmaing))
-               printk(KERN_ERR "%s: rx blocked, DMA in progress, dir %d\n", dev->name, adapter->current_dma.direction);
+               pr_err("%s: rx blocked, DMA in progress, dir %d\n",
+                       dev->name, adapter->current_dma.direction);
 
        adapter->current_dma.direction = 0;
        adapter->current_dma.length = rlen;
@@ -623,14 +626,14 @@ static void receive_packet(struct net_device *dev, int len)
        release_dma_lock(flags);
 
        if (elp_debug >= 3) {
-               printk(KERN_DEBUG "%s: rx DMA transfer started\n", dev->name);
+               pr_debug("%s: rx DMA transfer started\n", dev->name);
        }
 
        if (adapter->rx_active)
                adapter->rx_active--;
 
        if (!adapter->busy)
-               printk(KERN_WARNING "%s: receive_packet called, busy not set.\n", dev->name);
+               pr_warning("%s: receive_packet called, busy not set.\n", dev->name);
 }
 
 /******************************************************
@@ -655,12 +658,13 @@ static irqreturn_t elp_interrupt(int irq, void *dev_id)
                 * has a DMA transfer finished?
                 */
                if (inb_status(dev->base_addr) & DONE) {
-                       if (!adapter->dmaing) {
-                               printk(KERN_WARNING "%s: phantom DMA completed\n", dev->name);
-                       }
-                       if (elp_debug >= 3) {
-                               printk(KERN_DEBUG "%s: %s DMA complete, status %02x\n", dev->name, adapter->current_dma.direction ? "tx" : "rx", inb_status(dev->base_addr));
-                       }
+                       if (!adapter->dmaing)
+                               pr_warning("%s: phantom DMA completed\n", dev->name);
+
+                       if (elp_debug >= 3)
+                               pr_debug("%s: %s DMA complete, status %02x\n", dev->name,
+                                       adapter->current_dma.direction ? "tx" : "rx",
+                                       inb_status(dev->base_addr));
 
                        outb_control(adapter->hcr_val & ~(DMAE | TCEN | DIR), dev);
                        if (adapter->current_dma.direction) {
@@ -682,7 +686,7 @@ static irqreturn_t elp_interrupt(int irq, void *dev_id)
                                int t = adapter->rx_backlog.length[adapter->rx_backlog.out];
                                adapter->rx_backlog.out = backlog_next(adapter->rx_backlog.out);
                                if (elp_debug >= 2)
-                                       printk(KERN_DEBUG "%s: receiving backlogged packet (%d)\n", dev->name, t);
+                                       pr_debug("%s: receiving backlogged packet (%d)\n", dev->name, t);
                                receive_packet(dev, t);
                        } else {
                                adapter->busy = 0;
@@ -713,21 +717,23 @@ static irqreturn_t elp_interrupt(int irq, void *dev_id)
                                        len = adapter->irx_pcb.data.rcv_resp.pkt_len;
                                        dlen = adapter->irx_pcb.data.rcv_resp.buf_len;
                                        if (adapter->irx_pcb.data.rcv_resp.timeout != 0) {
-                                               printk(KERN_ERR "%s: interrupt - packet not received correctly\n", dev->name);
+                                               pr_err("%s: interrupt - packet not received correctly\n", dev->name);
                                        } else {
                                                if (elp_debug >= 3) {
-                                                       printk(KERN_DEBUG "%s: interrupt - packet received of length %i (%i)\n", dev->name, len, dlen);
+                                                       pr_debug("%s: interrupt - packet received of length %i (%i)\n",
+                                                               dev->name, len, dlen);
                                                }
                                                if (adapter->irx_pcb.command == 0xff) {
                                                        if (elp_debug >= 2)
-                                                               printk(KERN_DEBUG "%s: adding packet to backlog (len = %d)\n", dev->name, dlen);
+                                                               pr_debug("%s: adding packet to backlog (len = %d)\n",
+                                                                       dev->name, dlen);
                                                        adapter->rx_backlog.length[adapter->rx_backlog.in] = dlen;
                                                        adapter->rx_backlog.in = backlog_next(adapter->rx_backlog.in);
                                                } else {
                                                        receive_packet(dev, dlen);
                                                }
                                                if (elp_debug >= 3)
-                                                       printk(KERN_DEBUG "%s: packet received\n", dev->name);
+                                                       pr_debug("%s: packet received\n", dev->name);
                                        }
                                        break;
 
@@ -737,7 +743,7 @@ static irqreturn_t elp_interrupt(int irq, void *dev_id)
                                case CMD_CONFIGURE_82586_RESPONSE:
                                        adapter->got[CMD_CONFIGURE_82586] = 1;
                                        if (elp_debug >= 3)
-                                               printk(KERN_DEBUG "%s: interrupt - configure response received\n", dev->name);
+                                               pr_debug("%s: interrupt - configure response received\n", dev->name);
                                        break;
 
                                        /*
@@ -746,7 +752,7 @@ static irqreturn_t elp_interrupt(int irq, void *dev_id)
                                case CMD_CONFIGURE_ADAPTER_RESPONSE:
                                        adapter->got[CMD_CONFIGURE_ADAPTER_MEMORY] = 1;
                                        if (elp_debug >= 3)
-                                               printk(KERN_DEBUG "%s: Adapter memory configuration %s.\n", dev->name,
+                                               pr_debug("%s: Adapter memory configuration %s.\n", dev->name,
                                                       adapter->irx_pcb.data.failed ? "failed" : "succeeded");
                                        break;
 
@@ -756,7 +762,7 @@ static irqreturn_t elp_interrupt(int irq, void *dev_id)
                                case CMD_LOAD_MULTICAST_RESPONSE:
                                        adapter->got[CMD_LOAD_MULTICAST_LIST] = 1;
                                        if (elp_debug >= 3)
-                                               printk(KERN_DEBUG "%s: Multicast address list loading %s.\n", dev->name,
+                                               pr_debug("%s: Multicast address list loading %s.\n", dev->name,
                                                       adapter->irx_pcb.data.failed ? "failed" : "succeeded");
                                        break;
 
@@ -766,7 +772,7 @@ static irqreturn_t elp_interrupt(int irq, void *dev_id)
                                case CMD_SET_ADDRESS_RESPONSE:
                                        adapter->got[CMD_SET_STATION_ADDRESS] = 1;
                                        if (elp_debug >= 3)
-                                               printk(KERN_DEBUG "%s: Ethernet address setting %s.\n", dev->name,
+                                               pr_debug("%s: Ethernet address setting %s.\n", dev->name,
                                                       adapter->irx_pcb.data.failed ? "failed" : "succeeded");
                                        break;
 
@@ -783,7 +789,7 @@ static irqreturn_t elp_interrupt(int irq, void *dev_id)
                                        dev->stats.rx_over_errors += adapter->irx_pcb.data.netstat.err_res;
                                        adapter->got[CMD_NETWORK_STATISTICS] = 1;
                                        if (elp_debug >= 3)
-                                               printk(KERN_DEBUG "%s: interrupt - statistics response received\n", dev->name);
+                                               pr_debug("%s: interrupt - statistics response received\n", dev->name);
                                        break;
 
                                        /*
@@ -791,17 +797,17 @@ static irqreturn_t elp_interrupt(int irq, void *dev_id)
                                         */
                                case CMD_TRANSMIT_PACKET_COMPLETE:
                                        if (elp_debug >= 3)
-                                               printk(KERN_DEBUG "%s: interrupt - packet sent\n", dev->name);
+                                               pr_debug("%s: interrupt - packet sent\n", dev->name);
                                        if (!netif_running(dev))
                                                break;
                                        switch (adapter->irx_pcb.data.xmit_resp.c_stat) {
                                        case 0xffff:
                                                dev->stats.tx_aborted_errors++;
-                                               printk(KERN_INFO "%s: transmit timed out, network cable problem?\n", dev->name);
+                                               pr_info("%s: transmit timed out, network cable problem?\n", dev->name);
                                                break;
                                        case 0xfffe:
                                                dev->stats.tx_fifo_errors++;
-                                               printk(KERN_INFO "%s: transmit timed out, FIFO underrun\n", dev->name);
+                                               pr_info("%s: transmit timed out, FIFO underrun\n", dev->name);
                                                break;
                                        }
                                        netif_wake_queue(dev);
@@ -811,11 +817,12 @@ static irqreturn_t elp_interrupt(int irq, void *dev_id)
                                         * some unknown PCB
                                         */
                                default:
-                                       printk(KERN_DEBUG "%s: unknown PCB received - %2.2x\n", dev->name, adapter->irx_pcb.command);
+                                       pr_debug("%s: unknown PCB received - %2.2x\n",
+                                               dev->name, adapter->irx_pcb.command);
                                        break;
                                }
                        } else {
-                               printk(KERN_WARNING "%s: failed to read PCB on interrupt\n", dev->name);
+                               pr_warning("%s: failed to read PCB on interrupt\n", dev->name);
                                adapter_reset(dev);
                        }
                }
@@ -844,13 +851,13 @@ static int elp_open(struct net_device *dev)
        int retval;
 
        if (elp_debug >= 3)
-               printk(KERN_DEBUG "%s: request to open device\n", dev->name);
+               pr_debug("%s: request to open device\n", dev->name);
 
        /*
         * make sure we actually found the device
         */
        if (adapter == NULL) {
-               printk(KERN_ERR "%s: Opening a non-existent physical device\n", dev->name);
+               pr_err("%s: Opening a non-existent physical device\n", dev->name);
                return -EAGAIN;
        }
        /*
@@ -880,17 +887,17 @@ static int elp_open(struct net_device *dev)
         * install our interrupt service routine
         */
        if ((retval = request_irq(dev->irq, &elp_interrupt, 0, dev->name, dev))) {
-               printk(KERN_ERR "%s: could not allocate IRQ%d\n", dev->name, dev->irq);
+               pr_err("%s: could not allocate IRQ%d\n", dev->name, dev->irq);
                return retval;
        }
        if ((retval = request_dma(dev->dma, dev->name))) {
                free_irq(dev->irq, dev);
-               printk(KERN_ERR "%s: could not allocate DMA%d channel\n", dev->name, dev->dma);
+               pr_err("%s: could not allocate DMA%d channel\n", dev->name, dev->dma);
                return retval;
        }
        adapter->dma_buffer = (void *) dma_mem_alloc(DMA_BUFFER_SIZE);
        if (!adapter->dma_buffer) {
-               printk(KERN_ERR "%s: could not allocate DMA buffer\n", dev->name);
+               pr_err("%s: could not allocate DMA buffer\n", dev->name);
                free_dma(dev->dma);
                free_irq(dev->irq, dev);
                return -ENOMEM;
@@ -906,7 +913,7 @@ static int elp_open(struct net_device *dev)
         * configure adapter memory: we need 10 multicast addresses, default==0
         */
        if (elp_debug >= 3)
-               printk(KERN_DEBUG "%s: sending 3c505 memory configuration command\n", dev->name);
+               pr_debug("%s: sending 3c505 memory configuration command\n", dev->name);
        adapter->tx_pcb.command = CMD_CONFIGURE_ADAPTER_MEMORY;
        adapter->tx_pcb.data.memconf.cmd_q = 10;
        adapter->tx_pcb.data.memconf.rcv_q = 20;
@@ -917,7 +924,7 @@ static int elp_open(struct net_device *dev)
        adapter->tx_pcb.length = sizeof(struct Memconf);
        adapter->got[CMD_CONFIGURE_ADAPTER_MEMORY] = 0;
        if (!send_pcb(dev, &adapter->tx_pcb))
-               printk(KERN_ERR "%s: couldn't send memory configuration command\n", dev->name);
+               pr_err("%s: couldn't send memory configuration command\n", dev->name);
        else {
                unsigned long timeout = jiffies + TIMEOUT;
                while (adapter->got[CMD_CONFIGURE_ADAPTER_MEMORY] == 0 && time_before(jiffies, timeout));
@@ -930,13 +937,13 @@ static int elp_open(struct net_device *dev)
         * configure adapter to receive broadcast messages and wait for response
         */
        if (elp_debug >= 3)
-               printk(KERN_DEBUG "%s: sending 82586 configure command\n", dev->name);
+               pr_debug("%s: sending 82586 configure command\n", dev->name);
        adapter->tx_pcb.command = CMD_CONFIGURE_82586;
        adapter->tx_pcb.data.configure = NO_LOOPBACK | RECV_BROAD;
        adapter->tx_pcb.length = 2;
        adapter->got[CMD_CONFIGURE_82586] = 0;
        if (!send_pcb(dev, &adapter->tx_pcb))
-               printk(KERN_ERR "%s: couldn't send 82586 configure command\n", dev->name);
+               pr_err("%s: couldn't send 82586 configure command\n", dev->name);
        else {
                unsigned long timeout = jiffies + TIMEOUT;
                while (adapter->got[CMD_CONFIGURE_82586] == 0 && time_before(jiffies, timeout));
@@ -952,7 +959,7 @@ static int elp_open(struct net_device *dev)
         */
        prime_rx(dev);
        if (elp_debug >= 3)
-               printk(KERN_DEBUG "%s: %d receive PCBs active\n", dev->name, adapter->rx_active);
+               pr_debug("%s: %d receive PCBs active\n", dev->name, adapter->rx_active);
 
        /*
         * device is now officially open!
@@ -982,7 +989,7 @@ static bool send_packet(struct net_device *dev, struct sk_buff *skb)
 
        if (test_and_set_bit(0, (void *) &adapter->busy)) {
                if (elp_debug >= 2)
-                       printk(KERN_DEBUG "%s: transmit blocked\n", dev->name);
+                       pr_debug("%s: transmit blocked\n", dev->name);
                return false;
        }
 
@@ -1004,7 +1011,7 @@ static bool send_packet(struct net_device *dev, struct sk_buff *skb)
        }
        /* if this happens, we die */
        if (test_and_set_bit(0, (void *) &adapter->dmaing))
-               printk(KERN_DEBUG "%s: tx: DMA %d in progress\n", dev->name, adapter->current_dma.direction);
+               pr_debug("%s: tx: DMA %d in progress\n", dev->name, adapter->current_dma.direction);
 
        adapter->current_dma.direction = 1;
        adapter->current_dma.start_time = jiffies;
@@ -1030,7 +1037,7 @@ static bool send_packet(struct net_device *dev, struct sk_buff *skb)
        release_dma_lock(flags);
 
        if (elp_debug >= 3)
-               printk(KERN_DEBUG "%s: DMA transfer started\n", dev->name);
+               pr_debug("%s: DMA transfer started\n", dev->name);
 
        return true;
 }
@@ -1044,9 +1051,10 @@ static void elp_timeout(struct net_device *dev)
        int stat;
 
        stat = inb_status(dev->base_addr);
-       printk(KERN_WARNING "%s: transmit timed out, lost %s?\n", dev->name, (stat & ACRF) ? "interrupt" : "command");
+       pr_warning("%s: transmit timed out, lost %s?\n", dev->name,
+                  (stat & ACRF) ? "interrupt" : "command");
        if (elp_debug >= 1)
-               printk(KERN_DEBUG "%s: status %#02x\n", dev->name, stat);
+               pr_debug("%s: status %#02x\n", dev->name, stat);
        dev->trans_start = jiffies;
        dev->stats.tx_dropped++;
        netif_wake_queue(dev);
@@ -1068,7 +1076,7 @@ static int elp_start_xmit(struct sk_buff *skb, struct net_device *dev)
        check_3c505_dma(dev);
 
        if (elp_debug >= 3)
-               printk(KERN_DEBUG "%s: request to send packet of length %d\n", dev->name, (int) skb->len);
+               pr_debug("%s: request to send packet of length %d\n", dev->name, (int) skb->len);
 
        netif_stop_queue(dev);
 
@@ -1077,13 +1085,13 @@ static int elp_start_xmit(struct sk_buff *skb, struct net_device *dev)
         */
        if (!send_packet(dev, skb)) {
                if (elp_debug >= 2) {
-                       printk(KERN_DEBUG "%s: failed to transmit packet\n", dev->name);
+                       pr_debug("%s: failed to transmit packet\n", dev->name);
                }
                spin_unlock_irqrestore(&adapter->lock, flags);
-               return 1;
+               return NETDEV_TX_BUSY;
        }
        if (elp_debug >= 3)
-               printk(KERN_DEBUG "%s: packet of length %d sent\n", dev->name, (int) skb->len);
+               pr_debug("%s: packet of length %d sent\n", dev->name, (int) skb->len);
 
        /*
         * start the transmit timeout
@@ -1107,7 +1115,7 @@ static struct net_device_stats *elp_get_stats(struct net_device *dev)
        elp_device *adapter = netdev_priv(dev);
 
        if (elp_debug >= 3)
-               printk(KERN_DEBUG "%s: request for stats\n", dev->name);
+               pr_debug("%s: request for stats\n", dev->name);
 
        /* If the device is closed, just return the latest stats we have,
           - we cannot ask from the adapter without interrupts */
@@ -1119,7 +1127,7 @@ static struct net_device_stats *elp_get_stats(struct net_device *dev)
        adapter->tx_pcb.length = 0;
        adapter->got[CMD_NETWORK_STATISTICS] = 0;
        if (!send_pcb(dev, &adapter->tx_pcb))
-               printk(KERN_ERR "%s: couldn't send get statistics command\n", dev->name);
+               pr_err("%s: couldn't send get statistics command\n", dev->name);
        else {
                unsigned long timeout = jiffies + TIMEOUT;
                while (adapter->got[CMD_NETWORK_STATISTICS] == 0 && time_before(jiffies, timeout));
@@ -1169,7 +1177,7 @@ static int elp_close(struct net_device *dev)
        elp_device *adapter = netdev_priv(dev);
 
        if (elp_debug >= 3)
-               printk(KERN_DEBUG "%s: request to close device\n", dev->name);
+               pr_debug("%s: request to close device\n", dev->name);
 
        netif_stop_queue(dev);
 
@@ -1213,7 +1221,7 @@ static void elp_set_mc_list(struct net_device *dev)
        unsigned long flags;
 
        if (elp_debug >= 3)
-               printk(KERN_DEBUG "%s: request to set multicast list\n", dev->name);
+               pr_debug("%s: request to set multicast list\n", dev->name);
 
        spin_lock_irqsave(&adapter->lock, flags);
 
@@ -1228,7 +1236,7 @@ static void elp_set_mc_list(struct net_device *dev)
                }
                adapter->got[CMD_LOAD_MULTICAST_LIST] = 0;
                if (!send_pcb(dev, &adapter->tx_pcb))
-                       printk(KERN_ERR "%s: couldn't send set_multicast command\n", dev->name);
+                       pr_err("%s: couldn't send set_multicast command\n", dev->name);
                else {
                        unsigned long timeout = jiffies + TIMEOUT;
                        while (adapter->got[CMD_LOAD_MULTICAST_LIST] == 0 && time_before(jiffies, timeout));
@@ -1247,14 +1255,14 @@ static void elp_set_mc_list(struct net_device *dev)
         * and wait for response
         */
        if (elp_debug >= 3)
-               printk(KERN_DEBUG "%s: sending 82586 configure command\n", dev->name);
+               pr_debug("%s: sending 82586 configure command\n", dev->name);
        adapter->tx_pcb.command = CMD_CONFIGURE_82586;
        adapter->tx_pcb.length = 2;
        adapter->got[CMD_CONFIGURE_82586] = 0;
        if (!send_pcb(dev, &adapter->tx_pcb))
        {
                spin_unlock_irqrestore(&adapter->lock, flags);
-               printk(KERN_ERR "%s: couldn't send 82586 configure command\n", dev->name);
+               pr_err("%s: couldn't send 82586 configure command\n", dev->name);
        }
        else {
                unsigned long timeout = jiffies + TIMEOUT;
@@ -1283,17 +1291,17 @@ static int __init elp_sense(struct net_device *dev)
        orig_HSR = inb_status(addr);
 
        if (elp_debug > 0)
-               printk(search_msg, name, addr);
+               pr_debug(search_msg, name, addr);
 
        if (orig_HSR == 0xff) {
                if (elp_debug > 0)
-                       printk(notfound_msg, 1);
+                       pr_cont(notfound_msg, 1);
                goto out;
        }
 
        /* Wait for a while; the adapter may still be booting up */
        if (elp_debug > 0)
-               printk(stilllooking_msg);
+               pr_cont(stilllooking_msg);
 
        if (orig_HSR & DIR) {
                /* If HCR.DIR is up, we pull it down. HSR.DIR should follow. */
@@ -1301,7 +1309,7 @@ static int __init elp_sense(struct net_device *dev)
                msleep(300);
                if (inb_status(addr) & DIR) {
                        if (elp_debug > 0)
-                               printk(notfound_msg, 2);
+                               pr_cont(notfound_msg, 2);
                        goto out;
                }
        } else {
@@ -1310,7 +1318,7 @@ static int __init elp_sense(struct net_device *dev)
                msleep(300);
                if (!(inb_status(addr) & DIR)) {
                        if (elp_debug > 0)
-                               printk(notfound_msg, 3);
+                               pr_cont(notfound_msg, 3);
                        goto out;
                }
        }
@@ -1318,7 +1326,7 @@ static int __init elp_sense(struct net_device *dev)
         * It certainly looks like a 3c505.
         */
        if (elp_debug > 0)
-               printk(found_msg);
+               pr_cont(found_msg);
 
        return 0;
 out:
@@ -1349,7 +1357,7 @@ static int __init elp_autodetect(struct net_device *dev)
 
        /* could not find an adapter */
        if (elp_debug > 0)
-               printk(couldnot_msg, dev->name);
+               pr_debug(couldnot_msg, dev->name);
 
        return 0;               /* Because of this, the layer above will return -ENODEV */
 }
@@ -1424,16 +1432,16 @@ static int __init elplus_setup(struct net_device *dev)
                        /* Nope, it's ignoring the command register.  This means that
                         * either it's still booting up, or it's died.
                         */
-                       printk(KERN_ERR "%s: command register wouldn't drain, ", dev->name);
+                       pr_err("%s: command register wouldn't drain, ", dev->name);
                        if ((inb_status(dev->base_addr) & 7) == 3) {
                                /* If the adapter status is 3, it *could* still be booting.
                                 * Give it the benefit of the doubt for 10 seconds.
                                 */
-                               printk("assuming 3c505 still starting\n");
+                               pr_cont("assuming 3c505 still starting\n");
                                timeout = jiffies + 10*HZ;
                                while (time_before(jiffies, timeout) && (inb_status(dev->base_addr) & 7));
                                if (inb_status(dev->base_addr) & 7) {
-                                       printk(KERN_ERR "%s: 3c505 failed to start\n", dev->name);
+                                       pr_err("%s: 3c505 failed to start\n", dev->name);
                                } else {
                                        okay = 1;  /* It started */
                                }
@@ -1441,7 +1449,7 @@ static int __init elplus_setup(struct net_device *dev)
                                /* Otherwise, it must just be in a strange
                                 * state.  We probably need to kick it.
                                 */
-                               printk("3c505 is sulking\n");
+                               pr_cont("3c505 is sulking\n");
                        }
                }
                for (tries = 0; tries < 5 && okay; tries++) {
@@ -1454,18 +1462,19 @@ static int __init elplus_setup(struct net_device *dev)
                        adapter->tx_pcb.length = 0;
                        cookie = probe_irq_on();
                        if (!send_pcb(dev, &adapter->tx_pcb)) {
-                               printk(KERN_ERR "%s: could not send first PCB\n", dev->name);
+                               pr_err("%s: could not send first PCB\n", dev->name);
                                probe_irq_off(cookie);
                                continue;
                        }
                        if (!receive_pcb(dev, &adapter->rx_pcb)) {
-                               printk(KERN_ERR "%s: could not read first PCB\n", dev->name);
+                               pr_err("%s: could not read first PCB\n", dev->name);
                                probe_irq_off(cookie);
                                continue;
                        }
                        if ((adapter->rx_pcb.command != CMD_ADDRESS_RESPONSE) ||
                            (adapter->rx_pcb.length != 6)) {
-                               printk(KERN_ERR "%s: first PCB wrong (%d, %d)\n", dev->name, adapter->rx_pcb.command, adapter->rx_pcb.length);
+                               pr_err("%s: first PCB wrong (%d, %d)\n", dev->name,
+                                       adapter->rx_pcb.command, adapter->rx_pcb.length);
                                probe_irq_off(cookie);
                                continue;
                        }
@@ -1474,32 +1483,32 @@ static int __init elplus_setup(struct net_device *dev)
                /* It's broken.  Do a hard reset to re-initialise the board,
                 * and try again.
                 */
-               printk(KERN_INFO "%s: resetting adapter\n", dev->name);
+               pr_info("%s: resetting adapter\n", dev->name);
                outb_control(adapter->hcr_val | FLSH | ATTN, dev);
                outb_control(adapter->hcr_val & ~(FLSH | ATTN), dev);
        }
-       printk(KERN_ERR "%s: failed to initialise 3c505\n", dev->name);
+       pr_err("%s: failed to initialise 3c505\n", dev->name);
        goto out;
 
       okay:
        if (dev->irq) {         /* Is there a preset IRQ? */
                int rpt = probe_irq_off(cookie);
                if (dev->irq != rpt) {
-                       printk(KERN_WARNING "%s: warning, irq %d configured but %d detected\n", dev->name, dev->irq, rpt);
+                       pr_warning("%s: warning, irq %d configured but %d detected\n", dev->name, dev->irq, rpt);
                }
                /* if dev->irq == probe_irq_off(cookie), all is well */
        } else                 /* No preset IRQ; just use what we can detect */
                dev->irq = probe_irq_off(cookie);
        switch (dev->irq) {    /* Legal, sane? */
        case 0:
-               printk(KERN_ERR "%s: IRQ probe failed: check 3c505 jumpers.\n",
+               pr_err("%s: IRQ probe failed: check 3c505 jumpers.\n",
                       dev->name);
                goto out;
        case 1:
        case 6:
        case 8:
        case 13:
-               printk(KERN_ERR "%s: Impossible IRQ %d reported by probe_irq_off().\n",
+               pr_err("%s: Impossible IRQ %d reported by probe_irq_off().\n",
                       dev->name, dev->irq);
                       goto out;
        }
@@ -1521,7 +1530,7 @@ static int __init elplus_setup(struct net_device *dev)
                        dev->dma = dev->mem_start & 7;
                }
                else {
-                       printk(KERN_WARNING "%s: warning, DMA channel not specified, using default\n", dev->name);
+                       pr_warning("%s: warning, DMA channel not specified, using default\n", dev->name);
                        dev->dma = ELP_DMA;
                }
        }
@@ -1529,11 +1538,8 @@ static int __init elplus_setup(struct net_device *dev)
        /*
         * print remainder of startup message
         */
-       printk(KERN_INFO "%s: 3c505 at %#lx, irq %d, dma %d, "
-              "addr %pM, ",
-              dev->name, dev->base_addr, dev->irq, dev->dma,
-              dev->dev_addr);
-
+       pr_info("%s: 3c505 at %#lx, irq %d, dma %d, addr %pM, ",
+               dev->name, dev->base_addr, dev->irq, dev->dma, dev->dev_addr);
        /*
         * read more information from the adapter
         */
@@ -1544,9 +1550,10 @@ static int __init elplus_setup(struct net_device *dev)
            !receive_pcb(dev, &adapter->rx_pcb) ||
            (adapter->rx_pcb.command != CMD_ADAPTER_INFO_RESPONSE) ||
            (adapter->rx_pcb.length != 10)) {
-               printk("not responding to second PCB\n");
+               pr_cont("not responding to second PCB\n");
        }
-       printk("rev %d.%d, %dk\n", adapter->rx_pcb.data.info.major_vers, adapter->rx_pcb.data.info.minor_vers, adapter->rx_pcb.data.info.RAM_sz);
+       pr_cont("rev %d.%d, %dk\n", adapter->rx_pcb.data.info.major_vers,
+               adapter->rx_pcb.data.info.minor_vers, adapter->rx_pcb.data.info.RAM_sz);
 
        /*
         * reconfigure the adapter memory to better suit our purposes
@@ -1563,10 +1570,10 @@ static int __init elplus_setup(struct net_device *dev)
            !receive_pcb(dev, &adapter->rx_pcb) ||
            (adapter->rx_pcb.command != CMD_CONFIGURE_ADAPTER_RESPONSE) ||
            (adapter->rx_pcb.length != 2)) {
-               printk(KERN_ERR "%s: could not configure adapter memory\n", dev->name);
+               pr_err("%s: could not configure adapter memory\n", dev->name);
        }
        if (adapter->rx_pcb.data.configure) {
-               printk(KERN_ERR "%s: adapter configuration failed\n", dev->name);
+               pr_err("%s: adapter configuration failed\n", dev->name);
        }
 
        dev->netdev_ops = &elp_netdev_ops;
@@ -1631,17 +1638,17 @@ int __init init_module(void)
                        dev->dma = dma[this_dev];
                } else {
                        dev->dma = ELP_DMA;
-                       printk(KERN_WARNING "3c505.c: warning, using default DMA channel,\n");
+                       pr_warning("3c505.c: warning, using default DMA channel,\n");
                }
                if (io[this_dev] == 0) {
                        if (this_dev) {
                                free_netdev(dev);
                                break;
                        }
-                       printk(KERN_NOTICE "3c505.c: module autoprobe not recommended, give io=xx.\n");
+                       pr_notice("3c505.c: module autoprobe not recommended, give io=xx.\n");
                }
                if (elplus_setup(dev) != 0) {
-                       printk(KERN_WARNING "3c505.c: Failed to register card at 0x%x.\n", io[this_dev]);
+                       pr_warning("3c505.c: Failed to register card at 0x%x.\n", io[this_dev]);
                        free_netdev(dev);
                        break;
                }
index fbbaf826deff829531a6dddaac7d652146df030b..96b86659381a7944b857d2aca0bd04d4a97a9801 100644 (file)
@@ -364,7 +364,7 @@ static const struct net_device_ops netdev_ops = {
 
 static int __init el16_probe1(struct net_device *dev, int ioaddr)
 {
-       static unsigned char init_ID_done, version_printed;
+       static unsigned char init_ID_done;
        int i, irq, irqval, retval;
        struct net_local *lp;
 
@@ -391,10 +391,7 @@ static int __init el16_probe1(struct net_device *dev, int ioaddr)
                goto out;
        }
 
-       if (net_debug  &&  version_printed++ == 0)
-               printk(version);
-
-       printk("%s: 3c507 at %#x,", dev->name, ioaddr);
+       pr_info("%s: 3c507 at %#x,", dev->name, ioaddr);
 
        /* We should make a few more checks here, like the first three octets of
           the S.A. for the manufacturer's code. */
@@ -403,7 +400,8 @@ static int __init el16_probe1(struct net_device *dev, int ioaddr)
 
        irqval = request_irq(irq, &el16_interrupt, 0, DRV_NAME, dev);
        if (irqval) {
-               printk(KERN_ERR "3c507: unable to get IRQ %d (irqval=%d).\n", irq, irqval);
+               pr_cont("\n");
+               pr_err("3c507: unable to get IRQ %d (irqval=%d).\n", irq, irqval);
                retval = -EAGAIN;
                goto out;
        }
@@ -414,7 +412,7 @@ static int __init el16_probe1(struct net_device *dev, int ioaddr)
        outb(0x01, ioaddr + MISC_CTRL);
        for (i = 0; i < 6; i++)
                dev->dev_addr[i] = inb(ioaddr + i);
-       printk(" %pM", dev->dev_addr);
+       pr_cont(" %pM", dev->dev_addr);
 
        if (mem_start)
                net_debug = mem_start & 7;
@@ -443,18 +441,18 @@ static int __init el16_probe1(struct net_device *dev, int ioaddr)
        dev->if_port = (inb(ioaddr + ROM_CONFIG) & 0x80) ? 1 : 0;
        dev->irq = inb(ioaddr + IRQ_CONFIG) & 0x0f;
 
-       printk(", IRQ %d, %sternal xcvr, memory %#lx-%#lx.\n", dev->irq,
+       pr_cont(", IRQ %d, %sternal xcvr, memory %#lx-%#lx.\n", dev->irq,
                   dev->if_port ? "ex" : "in", dev->mem_start, dev->mem_end-1);
 
        if (net_debug)
-               printk(version);
+               pr_debug("%s", version);
 
        lp = netdev_priv(dev);
        memset(lp, 0, sizeof(*lp));
        spin_lock_init(&lp->lock);
        lp->base = ioremap(dev->mem_start, RX_BUF_END);
        if (!lp->base) {
-               printk(KERN_ERR "3c507: unable to remap memory\n");
+               pr_err("3c507: unable to remap memory\n");
                retval = -EAGAIN;
                goto out1;
        }
@@ -488,20 +486,20 @@ static void el16_tx_timeout (struct net_device *dev)
        void __iomem *shmem = lp->base;
 
        if (net_debug > 1)
-               printk ("%s: transmit timed out, %s?  ", dev->name,
+               pr_debug("%s: transmit timed out, %s?  ", dev->name,
                        readw(shmem + iSCB_STATUS) & 0x8000 ? "IRQ conflict" :
                        "network cable problem");
        /* Try to restart the adaptor. */
        if (lp->last_restart == dev->stats.tx_packets) {
                if (net_debug > 1)
-                       printk ("Resetting board.\n");
+                       pr_cont("Resetting board.\n");
                /* Completely reset the adaptor. */
                init_82586_mem (dev);
                lp->tx_pkts_in_ring = 0;
        } else {
                /* Issue the channel attention signal and hope it "gets better". */
                if (net_debug > 1)
-                       printk ("Kicking board.\n");
+                       pr_cont("Kicking board.\n");
                writew(0xf000 | CUC_START | RX_START, shmem + iSCB_CMD);
                outb (0, ioaddr + SIGNAL_CA);   /* Issue channel-attn. */
                lp->last_restart = dev->stats.tx_packets;
@@ -553,7 +551,8 @@ static irqreturn_t el16_interrupt(int irq, void *dev_id)
        void __iomem *shmem;
 
        if (dev == NULL) {
-               printk ("net_interrupt(): irq %d for unknown device.\n", irq);
+               pr_err("%s: net_interrupt(): irq %d for unknown device.\n",
+                       dev->name, irq);
                return IRQ_NONE;
        }
 
@@ -566,7 +565,7 @@ static irqreturn_t el16_interrupt(int irq, void *dev_id)
        status = readw(shmem+iSCB_STATUS);
 
        if (net_debug > 4) {
-               printk("%s: 3c507 interrupt, status %4.4x.\n", dev->name, status);
+               pr_debug("%s: 3c507 interrupt, status %4.4x.\n", dev->name, status);
        }
 
        /* Disable the 82586's input to the interrupt line. */
@@ -577,7 +576,7 @@ static irqreturn_t el16_interrupt(int irq, void *dev_id)
          unsigned short tx_status = readw(shmem+lp->tx_reap);
          if (!(tx_status & 0x8000)) {
                if (net_debug > 5)
-                       printk("Tx command incomplete (%#x).\n", lp->tx_reap);
+                       pr_debug("Tx command incomplete (%#x).\n", lp->tx_reap);
                break;
          }
          /* Tx unsuccessful or some interesting status bit set. */
@@ -591,7 +590,7 @@ static irqreturn_t el16_interrupt(int irq, void *dev_id)
          }
          dev->stats.tx_packets++;
          if (net_debug > 5)
-                 printk("Reaped %x, Tx status %04x.\n" , lp->tx_reap, tx_status);
+                 pr_debug("Reaped %x, Tx status %04x.\n" , lp->tx_reap, tx_status);
          lp->tx_reap += TX_BUF_SIZE;
          if (lp->tx_reap > RX_BUF_START - TX_BUF_SIZE)
                lp->tx_reap = TX_BUF_START;
@@ -606,7 +605,7 @@ static irqreturn_t el16_interrupt(int irq, void *dev_id)
 
        if (status & 0x4000) { /* Packet received. */
                if (net_debug > 5)
-                       printk("Received packet, rx_head %04x.\n", lp->rx_head);
+                       pr_debug("Received packet, rx_head %04x.\n", lp->rx_head);
                el16_rx(dev);
        }
 
@@ -615,7 +614,7 @@ static irqreturn_t el16_interrupt(int irq, void *dev_id)
 
        if ((status & 0x0700) != 0x0200 && netif_running(dev)) {
                if (net_debug)
-                       printk("%s: Command unit stopped, status %04x, restarting.\n",
+                       pr_debug("%s: Command unit stopped, status %04x, restarting.\n",
                                   dev->name, status);
                /* If this ever occurs we should really re-write the idle loop, reset
                   the Tx list, and do a complete restart of the command unit.
@@ -627,7 +626,7 @@ static irqreturn_t el16_interrupt(int irq, void *dev_id)
                /* The Rx unit is not ready, it must be hung.  Restart the receiver by
                   initializing the rx buffers, and issuing an Rx start command. */
                if (net_debug)
-                       printk("%s: Rx unit stopped, status %04x, restarting.\n",
+                       pr_debug("%s: Rx unit stopped, status %04x, restarting.\n",
                                   dev->name, status);
                init_rx_bufs(dev);
                writew(RX_BUF_START,shmem+iSCB_RFA);
@@ -753,9 +752,8 @@ static void init_82586_mem(struct net_device *dev)
                int boguscnt = 50;
                while (readw(shmem+iSCB_STATUS) == 0)
                        if (--boguscnt == 0) {
-                               printk("%s: i82586 initialization timed out with status %04x, "
-                                          "cmd %04x.\n", dev->name,
-                                          readw(shmem+iSCB_STATUS), readw(shmem+iSCB_CMD));
+                               pr_warning("%s: i82586 initialization timed out with status %04x, cmd %04x.\n",
+                                       dev->name, readw(shmem+iSCB_STATUS), readw(shmem+iSCB_CMD));
                                break;
                        }
                /* Issue channel-attn -- the 82586 won't start. */
@@ -765,7 +763,7 @@ static void init_82586_mem(struct net_device *dev)
        /* Disable loopback and enable interrupts. */
        outb(0x84, ioaddr + MISC_CTRL);
        if (net_debug > 4)
-               printk("%s: Initialized 82586, status %04x.\n", dev->name,
+               pr_debug("%s: Initialized 82586, status %04x.\n", dev->name,
                           readw(shmem+iSCB_STATUS));
        return;
 }
@@ -810,7 +808,7 @@ static void hardware_send_packet(struct net_device *dev, void *buf, short length
                lp->tx_head = TX_BUF_START;
 
        if (net_debug > 4) {
-               printk("%s: 3c507 @%x send length = %d, tx_block %3x, next %3x.\n",
+               pr_debug("%s: 3c507 @%x send length = %d, tx_block %3x, next %3x.\n",
                           dev->name, ioaddr, length, tx_block, lp->tx_head);
        }
 
@@ -838,7 +836,7 @@ static void el16_rx(struct net_device *dev)
 
                if (rfd_cmd != 0 || data_buffer_addr != rx_head + 22
                        || (pkt_len & 0xC000) != 0xC000) {
-                       printk(KERN_ERR "%s: Rx frame at %#x corrupted, "
+                       pr_err("%s: Rx frame at %#x corrupted, "
                               "status %04x cmd %04x next %04x "
                               "data-buf @%04x %04x.\n",
                               dev->name, rx_head, frame_status, rfd_cmd,
@@ -858,8 +856,7 @@ static void el16_rx(struct net_device *dev)
                        pkt_len &= 0x3fff;
                        skb = dev_alloc_skb(pkt_len+2);
                        if (skb == NULL) {
-                               printk(KERN_ERR "%s: Memory squeeze, "
-                                      "dropping packet.\n",
+                               pr_err("%s: Memory squeeze, dropping packet.\n",
                                       dev->name);
                                dev->stats.rx_dropped++;
                                break;
@@ -926,7 +923,7 @@ MODULE_PARM_DESC(irq, "(ignored)");
 int __init init_module(void)
 {
        if (io == 0)
-               printk("3c507: You should not use auto-probing with insmod!\n");
+               pr_notice("3c507: You should not use auto-probing with insmod!\n");
        dev_3c507 = el16_probe(-1);
        return IS_ERR(dev_3c507) ? PTR_ERR(dev_3c507) : 0;
 }
index 682aad897081163acc8ba0fb864f2139f95b575b..d2137efbd455601295cf01cf0eeaf395c3ee0d13 100644 (file)
@@ -257,7 +257,7 @@ static int el3_isa_id_sequence(__be16 *phys_addr)
                            && !memcmp(phys_addr, el3_devs[i]->dev_addr,
                                       ETH_ALEN)) {
                                if (el3_debug > 3)
-                                       printk(KERN_DEBUG "3c509 with address %02x %02x %02x %02x %02x %02x was found by ISAPnP\n",
+                                       pr_debug("3c509 with address %02x %02x %02x %02x %02x %02x was found by ISAPnP\n",
                                                phys_addr[0] & 0xff, phys_addr[0] >> 8,
                                                phys_addr[1] & 0xff, phys_addr[1] >> 8,
                                                phys_addr[2] & 0xff, phys_addr[2] >> 8);
@@ -578,19 +578,18 @@ static int __devinit el3_common_init(struct net_device *dev)
 
        err = register_netdev(dev);
        if (err) {
-               printk(KERN_ERR "Failed to register 3c5x9 at %#3.3lx, IRQ %d.\n",
+               pr_err("Failed to register 3c5x9 at %#3.3lx, IRQ %d.\n",
                        dev->base_addr, dev->irq);
                release_region(dev->base_addr, EL3_IO_EXTENT);
                return err;
        }
 
-       printk(KERN_INFO "%s: 3c5x9 found at %#3.3lx, %s port, "
-              "address %pM, IRQ %d.\n",
+       pr_info("%s: 3c5x9 found at %#3.3lx, %s port, address %pM, IRQ %d.\n",
               dev->name, dev->base_addr, if_names[(dev->if_port & 0x03)],
               dev->dev_addr, dev->irq);
 
        if (el3_debug > 0)
-               printk(KERN_INFO "%s", version);
+               pr_info("%s", version);
        return 0;
 
 }
@@ -629,8 +628,8 @@ static int __init el3_mca_probe(struct device *device)
        irq = pos5 & 0x0f;
 
 
-       printk(KERN_INFO "3c529: found %s at slot %d\n",
-                  el3_mca_adapter_names[mdev->index], slot + 1);
+       pr_info("3c529: found %s at slot %d\n",
+               el3_mca_adapter_names[mdev->index], slot + 1);
 
        /* claim the slot */
        strncpy(mdev->name, el3_mca_adapter_names[mdev->index],
@@ -642,7 +641,7 @@ static int __init el3_mca_probe(struct device *device)
        irq = mca_device_transform_irq(mdev, irq);
        ioaddr = mca_device_transform_ioport(mdev, ioaddr);
        if (el3_debug > 2) {
-                       printk(KERN_DEBUG "3c529: irq %d  ioaddr 0x%x  ifport %d\n", irq, ioaddr, if_port);
+               pr_debug("3c529: irq %d  ioaddr 0x%x  ifport %d\n", irq, ioaddr, if_port);
        }
        EL3WINDOW(0);
        for (i = 0; i < 3; i++)
@@ -657,11 +656,11 @@ static int __init el3_mca_probe(struct device *device)
        netdev_boot_setup_check(dev);
 
        el3_dev_fill(dev, phys_addr, ioaddr, irq, if_port, EL3_MCA);
-       device->driver_data = dev;
+       dev_set_drvdata(device, dev);
        err = el3_common_init(dev);
 
        if (err) {
-               device->driver_data = NULL;
+               dev_set_drvdata(device, NULL);
                free_netdev(dev);
                return -ENOMEM;
        }
@@ -725,12 +724,12 @@ static int __init el3_eisa_probe (struct device *device)
 
 /* This remove works for all device types.
  *
- * The net dev must be stored in the driver_data field */
+ * The net dev must be stored in the driver data field */
 static int __devexit el3_device_remove (struct device *device)
 {
        struct net_device *dev;
 
-       dev  = device->driver_data;
+       dev = dev_get_drvdata(device);
 
        el3_common_remove (dev);
        return 0;
@@ -765,7 +764,7 @@ static ushort id_read_eeprom(int index)
                word = (word << 1) + (inb(id_port) & 0x01);
 
        if (el3_debug > 3)
-               printk(KERN_DEBUG "  3c509 EEPROM word %d %#4.4x.\n", index, word);
+               pr_debug("  3c509 EEPROM word %d %#4.4x.\n", index, word);
 
        return word;
 }
@@ -787,13 +786,13 @@ el3_open(struct net_device *dev)
 
        EL3WINDOW(0);
        if (el3_debug > 3)
-               printk(KERN_DEBUG "%s: Opening, IRQ %d   status@%x %4.4x.\n", dev->name,
+               pr_debug("%s: Opening, IRQ %d    status@%x %4.4x.\n", dev->name,
                           dev->irq, ioaddr + EL3_STATUS, inw(ioaddr + EL3_STATUS));
 
        el3_up(dev);
 
        if (el3_debug > 3)
-               printk(KERN_DEBUG "%s: Opened 3c509  IRQ %d  status %4.4x.\n",
+               pr_debug("%s: Opened 3c509  IRQ %d  status %4.4x.\n",
                           dev->name, dev->irq, inw(ioaddr + EL3_STATUS));
 
        return 0;
@@ -805,8 +804,7 @@ el3_tx_timeout (struct net_device *dev)
        int ioaddr = dev->base_addr;
 
        /* Transmitter timeout, serious problems. */
-       printk(KERN_WARNING "%s: transmit timed out, Tx_status %2.2x status %4.4x "
-                  "Tx FIFO room %d.\n",
+       pr_warning("%s: transmit timed out, Tx_status %2.2x status %4.4x Tx FIFO room %d.\n",
                   dev->name, inb(ioaddr + TX_STATUS), inw(ioaddr + EL3_STATUS),
                   inw(ioaddr + TX_FREE));
        dev->stats.tx_errors++;
@@ -830,7 +828,7 @@ el3_start_xmit(struct sk_buff *skb, struct net_device *dev)
        dev->stats.tx_bytes += skb->len;
 
        if (el3_debug > 4) {
-               printk(KERN_DEBUG "%s: el3_start_xmit(length = %u) called, status %4.4x.\n",
+               pr_debug("%s: el3_start_xmit(length = %u) called, status %4.4x.\n",
                           dev->name, skb->len, inw(ioaddr + EL3_STATUS));
        }
 #if 0
@@ -839,7 +837,7 @@ el3_start_xmit(struct sk_buff *skb, struct net_device *dev)
                ushort status = inw(ioaddr + EL3_STATUS);
                if (status & 0x0001             /* IRQ line active, missed one. */
                        && inw(ioaddr + EL3_STATUS) & 1) {                      /* Make sure. */
-                       printk(KERN_DEBUG "%s: Missed interrupt, status then %04x now %04x"
+                       pr_debug("%s: Missed interrupt, status then %04x now %04x"
                                   "  Tx %2.2x Rx %4.4x.\n", dev->name, status,
                                   inw(ioaddr + EL3_STATUS), inb(ioaddr + TX_STATUS),
                                   inw(ioaddr + RX_STATUS));
@@ -913,7 +911,7 @@ el3_interrupt(int irq, void *dev_id)
 
        if (el3_debug > 4) {
                status = inw(ioaddr + EL3_STATUS);
-               printk(KERN_DEBUG "%s: interrupt, status %4.4x.\n", dev->name, status);
+               pr_debug("%s: interrupt, status %4.4x.\n", dev->name, status);
        }
 
        while ((status = inw(ioaddr + EL3_STATUS)) &
@@ -924,7 +922,7 @@ el3_interrupt(int irq, void *dev_id)
 
                if (status & TxAvailable) {
                        if (el3_debug > 5)
-                               printk(KERN_DEBUG "     TX room bit was handled.\n");
+                               pr_debug("      TX room bit was handled.\n");
                        /* There's room in the FIFO for a full-sized packet. */
                        outw(AckIntr | TxAvailable, ioaddr + EL3_CMD);
                        netif_wake_queue (dev);
@@ -962,7 +960,7 @@ el3_interrupt(int irq, void *dev_id)
                }
 
                if (--i < 0) {
-                       printk(KERN_ERR "%s: Infinite loop in interrupt, status %4.4x.\n",
+                       pr_err("%s: Infinite loop in interrupt, status %4.4x.\n",
                                   dev->name, status);
                        /* Clear all interrupts. */
                        outw(AckIntr | 0xFF, ioaddr + EL3_CMD);
@@ -973,7 +971,7 @@ el3_interrupt(int irq, void *dev_id)
        }
 
        if (el3_debug > 4) {
-               printk(KERN_DEBUG "%s: exiting interrupt, status %4.4x.\n", dev->name,
+               pr_debug("%s: exiting interrupt, status %4.4x.\n", dev->name,
                           inw(ioaddr + EL3_STATUS));
        }
        spin_unlock(&lp->lock);
@@ -1021,7 +1019,7 @@ static void update_stats(struct net_device *dev)
        int ioaddr = dev->base_addr;
 
        if (el3_debug > 5)
-               printk("   Updating the statistics.\n");
+               pr_debug("   Updating the statistics.\n");
        /* Turn off statistics updates while reading. */
        outw(StatsDisable, ioaddr + EL3_CMD);
        /* Switch to the stats window, and read everything. */
@@ -1051,7 +1049,7 @@ el3_rx(struct net_device *dev)
        short rx_status;
 
        if (el3_debug > 5)
-               printk("   In rx_packet(), status %4.4x, rx_status %4.4x.\n",
+               pr_debug("   In rx_packet(), status %4.4x, rx_status %4.4x.\n",
                           inw(ioaddr+EL3_STATUS), inw(ioaddr+RX_STATUS));
        while ((rx_status = inw(ioaddr + RX_STATUS)) > 0) {
                if (rx_status & 0x4000) { /* Error, update stats. */
@@ -1073,7 +1071,7 @@ el3_rx(struct net_device *dev)
 
                        skb = dev_alloc_skb(pkt_len+5);
                        if (el3_debug > 4)
-                               printk("Receiving packet size %d status %4.4x.\n",
+                               pr_debug("Receiving packet size %d status %4.4x.\n",
                                           pkt_len, rx_status);
                        if (skb != NULL) {
                                skb_reserve(skb, 2);     /* Align IP on 16 byte */
@@ -1092,12 +1090,12 @@ el3_rx(struct net_device *dev)
                        outw(RxDiscard, ioaddr + EL3_CMD);
                        dev->stats.rx_dropped++;
                        if (el3_debug)
-                               printk("%s: Couldn't allocate a sk_buff of size %d.\n",
+                               pr_debug("%s: Couldn't allocate a sk_buff of size %d.\n",
                                           dev->name, pkt_len);
                }
                inw(ioaddr + EL3_STATUS);                               /* Delay. */
                while (inw(ioaddr + EL3_STATUS) & 0x1000)
-                       printk(KERN_DEBUG "     Waiting for 3c509 to discard packet, status %x.\n",
+                       pr_debug("      Waiting for 3c509 to discard packet, status %x.\n",
                                   inw(ioaddr + EL3_STATUS) );
        }
 
@@ -1118,7 +1116,7 @@ set_multicast_list(struct net_device *dev)
                static int old;
                if (old != dev->mc_count) {
                        old = dev->mc_count;
-                       printk("%s: Setting Rx mode to %d addresses.\n", dev->name, dev->mc_count);
+                       pr_debug("%s: Setting Rx mode to %d addresses.\n", dev->name, dev->mc_count);
                }
        }
        spin_lock_irqsave(&lp->lock, flags);
@@ -1141,7 +1139,7 @@ el3_close(struct net_device *dev)
        struct el3_private *lp = netdev_priv(dev);
 
        if (el3_debug > 2)
-               printk("%s: Shutting down ethercard.\n", dev->name);
+               pr_debug("%s: Shutting down ethercard.\n", dev->name);
 
        el3_down(dev);
 
@@ -1388,30 +1386,30 @@ el3_up(struct net_device *dev)
                EL3WINDOW(4);
                net_diag = inw(ioaddr + WN4_NETDIAG);
                net_diag = (net_diag | FD_ENABLE); /* temporarily assume full-duplex will be set */
-               printk("%s: ", dev->name);
+               pr_info("%s: ", dev->name);
                switch (dev->if_port & 0x0c) {
                        case 12:
                                /* force full-duplex mode if 3c5x9b */
                                if (sw_info & 0x000f) {
-                                       printk("Forcing 3c5x9b full-duplex mode");
+                                       pr_cont("Forcing 3c5x9b full-duplex mode");
                                        break;
                                }
                        case 8:
                                /* set full-duplex mode based on eeprom config setting */
                                if ((sw_info & 0x000f) && (sw_info & 0x8000)) {
-                                       printk("Setting 3c5x9b full-duplex mode (from EEPROM configuration bit)");
+                                       pr_cont("Setting 3c5x9b full-duplex mode (from EEPROM configuration bit)");
                                        break;
                                }
                        default:
                                /* xcvr=(0 || 4) OR user has an old 3c5x9 non "B" model */
-                               printk("Setting 3c5x9/3c5x9B half-duplex mode");
+                               pr_cont("Setting 3c5x9/3c5x9B half-duplex mode");
                                net_diag = (net_diag & ~FD_ENABLE); /* disable full duplex */
                }
 
                outw(net_diag, ioaddr + WN4_NETDIAG);
-               printk(" if_port: %d, sw_info: %4.4x\n", dev->if_port, sw_info);
+               pr_cont(" if_port: %d, sw_info: %4.4x\n", dev->if_port, sw_info);
                if (el3_debug > 3)
-                       printk("%s: 3c5x9 net diag word is now: %4.4x.\n", dev->name, net_diag);
+                       pr_debug("%s: 3c5x9 net diag word is now: %4.4x.\n", dev->name, net_diag);
                /* Enable link beat and jabber check. */
                outw(inw(ioaddr + WN4_MEDIA) | MEDIA_TP, ioaddr + WN4_MEDIA);
        }
@@ -1455,7 +1453,7 @@ el3_suspend(struct device *pdev, pm_message_t state)
        struct el3_private *lp;
        int ioaddr;
 
-       dev = pdev->driver_data;
+       dev = dev_get_drvdata(pdev);
        lp = netdev_priv(dev);
        ioaddr = dev->base_addr;
 
@@ -1479,7 +1477,7 @@ el3_resume(struct device *pdev)
        struct el3_private *lp;
        int ioaddr;
 
-       dev = pdev->driver_data;
+       dev = dev_get_drvdata(pdev);
        lp = netdev_priv(dev);
        ioaddr = dev->base_addr;
 
@@ -1539,7 +1537,7 @@ static int __init el3_init_module(void)
        }
        if (id_port >= 0x200) {
                id_port = 0;
-               printk(KERN_ERR "No I/O port available for 3c509 activation.\n");
+               pr_err("No I/O port available for 3c509 activation.\n");
        } else {
                ret = isa_register_driver(&el3_isa_driver, EL3_MAX_CARDS);
                if (!ret)
index 167bf23066eab6e5e376d4356acde830f2e06aaf..3e00fa8ea65f106544c7a5f67a4c6535d499c690 100644 (file)
@@ -420,7 +420,7 @@ int init_module(void)
        if (debug >= 0)
                corkscrew_debug = debug;
        if (corkscrew_debug)
-               printk(version);
+               pr_debug("%s", version);
        while (corkscrew_scan(-1))
                found++;
        return found ? 0 : -ENODEV;
@@ -437,7 +437,7 @@ struct net_device *tc515_probe(int unit)
 
        if (corkscrew_debug > 0 && !printed) {
                printed = 1;
-               printk(version);
+               pr_debug("%s", version);
        }
 
        return dev;
@@ -516,7 +516,7 @@ static struct net_device *corkscrew_scan(int unit)
                        if (pnp_device_attach(idev) < 0)
                                continue;
                        if (pnp_activate_dev(idev) < 0) {
-                               printk("pnp activate failed (out of resources?)\n");
+                               pr_warning("pnp activate failed (out of resources?)\n");
                                pnp_device_detach(idev);
                                continue;
                        }
@@ -531,9 +531,9 @@ static struct net_device *corkscrew_scan(int unit)
                                continue;
                        }
                        if(corkscrew_debug)
-                               printk ("ISAPNP reports %s at i/o 0x%x, irq %d\n",
+                               pr_debug("ISAPNP reports %s at i/o 0x%x, irq %d\n",
                                        (char*) corkscrew_isapnp_adapters[i].driver_data, ioaddr, irq);
-                       printk(KERN_INFO "3c515 Resource configuration register %#4.4x, DCR %4.4x.\n",
+                       pr_info("3c515 Resource configuration register %#4.4x, DCR %4.4x.\n",
                                inl(ioaddr + 0x2002), inw(ioaddr + 0x2000));
                        /* irq = inw(ioaddr + 0x2002) & 15; */ /* Use the irq from isapnp */
                        SET_NETDEV_DEV(dev, &idev->dev);
@@ -552,7 +552,7 @@ no_pnp:
                if (!check_device(ioaddr))
                        continue;
 
-               printk(KERN_INFO "3c515 Resource configuration register %#4.4x, DCR %4.4x.\n",
+               pr_info("3c515 Resource configuration register %#4.4x, DCR %4.4x.\n",
                     inl(ioaddr + 0x2002), inw(ioaddr + 0x2000));
                err = corkscrew_setup(dev, ioaddr, NULL, cards_found++);
                if (!err)
@@ -625,7 +625,7 @@ static int corkscrew_setup(struct net_device *dev, int ioaddr,
        list_add(&vp->list, &root_corkscrew_dev);
 #endif
 
-       printk(KERN_INFO "%s: 3Com %s at %#3x,", dev->name, vp->product_name, ioaddr);
+       pr_info("%s: 3Com %s at %#3x,", dev->name, vp->product_name, ioaddr);
 
        spin_lock_init(&vp->lock);
 
@@ -648,19 +648,19 @@ static int corkscrew_setup(struct net_device *dev, int ioaddr,
        }
        checksum = (checksum ^ (checksum >> 8)) & 0xff;
        if (checksum != 0x00)
-               printk(" ***INVALID CHECKSUM %4.4x*** ", checksum);
-       printk(" %pM", dev->dev_addr);
+               pr_cont(" ***INVALID CHECKSUM %4.4x*** ", checksum);
+       pr_cont(" %pM", dev->dev_addr);
        if (eeprom[16] == 0x11c7) {     /* Corkscrew */
                if (request_dma(dev->dma, "3c515")) {
-                       printk(", DMA %d allocation failed", dev->dma);
+                       pr_cont(", DMA %d allocation failed", dev->dma);
                        dev->dma = 0;
                } else
-                       printk(", DMA %d", dev->dma);
+                       pr_cont(", DMA %d", dev->dma);
        }
-       printk(", IRQ %d\n", dev->irq);
+       pr_cont(", IRQ %d\n", dev->irq);
        /* Tell them about an invalid IRQ. */
        if (corkscrew_debug && (dev->irq <= 0 || dev->irq > 15))
-               printk(KERN_WARNING " *** Warning: this IRQ is unlikely to work! ***\n");
+               pr_warning(" *** Warning: this IRQ is unlikely to work! ***\n");
 
        {
                char *ram_split[] = { "5:3", "3:1", "1:1", "3:5" };
@@ -669,9 +669,9 @@ static int corkscrew_setup(struct net_device *dev, int ioaddr,
                vp->available_media = inw(ioaddr + Wn3_Options);
                config = inl(ioaddr + Wn3_Config);
                if (corkscrew_debug > 1)
-                       printk(KERN_INFO "  Internal config register is %4.4x, transceivers %#x.\n",
+                       pr_info("  Internal config register is %4.4x, transceivers %#x.\n",
                                config, inw(ioaddr + Wn3_Options));
-               printk(KERN_INFO "  %dK %s-wide RAM %s Rx:Tx split, %s%s interface.\n",
+               pr_info("  %dK %s-wide RAM %s Rx:Tx split, %s%s interface.\n",
                        8 << config & Ram_size,
                        config & Ram_width ? "word" : "byte",
                        ram_split[(config & Ram_split) >> Ram_split_shift],
@@ -682,7 +682,7 @@ static int corkscrew_setup(struct net_device *dev, int ioaddr,
                dev->if_port = vp->default_media;
        }
        if (vp->media_override != 7) {
-               printk(KERN_INFO "  Media override to transceiver type %d (%s).\n",
+               pr_info("  Media override to transceiver type %d (%s).\n",
                       vp->media_override,
                       media_tbl[vp->media_override].name);
                dev->if_port = vp->media_override;
@@ -718,7 +718,7 @@ static int corkscrew_open(struct net_device *dev)
 
        if (vp->media_override != 7) {
                if (corkscrew_debug > 1)
-                       printk(KERN_INFO "%s: Media override to transceiver %d (%s).\n",
+                       pr_info("%s: Media override to transceiver %d (%s).\n",
                                dev->name, vp->media_override,
                                media_tbl[vp->media_override].name);
                dev->if_port = vp->media_override;
@@ -729,7 +729,7 @@ static int corkscrew_open(struct net_device *dev)
                        dev->if_port = media_tbl[dev->if_port].next;
 
                if (corkscrew_debug > 1)
-                       printk("%s: Initial media type %s.\n",
+                       pr_debug("%s: Initial media type %s.\n",
                               dev->name, media_tbl[dev->if_port].name);
 
                init_timer(&vp->timer);
@@ -744,7 +744,7 @@ static int corkscrew_open(struct net_device *dev)
        outl(config, ioaddr + Wn3_Config);
 
        if (corkscrew_debug > 1) {
-               printk("%s: corkscrew_open() InternalConfig %8.8x.\n",
+               pr_debug("%s: corkscrew_open() InternalConfig %8.8x.\n",
                       dev->name, config);
        }
 
@@ -777,7 +777,7 @@ static int corkscrew_open(struct net_device *dev)
 
        if (corkscrew_debug > 1) {
                EL3WINDOW(4);
-               printk("%s: corkscrew_open() irq %d media status %4.4x.\n",
+               pr_debug("%s: corkscrew_open() irq %d media status %4.4x.\n",
                       dev->name, dev->irq, inw(ioaddr + Wn4_Media));
        }
 
@@ -814,8 +814,7 @@ static int corkscrew_open(struct net_device *dev)
        if (vp->full_bus_master_rx) {   /* Boomerang bus master. */
                vp->cur_rx = vp->dirty_rx = 0;
                if (corkscrew_debug > 2)
-                       printk("%s:  Filling in the Rx ring.\n",
-                              dev->name);
+                       pr_debug("%s:  Filling in the Rx ring.\n", dev->name);
                for (i = 0; i < RX_RING_SIZE; i++) {
                        struct sk_buff *skb;
                        if (i < (RX_RING_SIZE - 1))
@@ -877,7 +876,7 @@ static void corkscrew_timer(unsigned long data)
        int ok = 0;
 
        if (corkscrew_debug > 1)
-               printk("%s: Media selection timer tick happened, %s.\n",
+               pr_debug("%s: Media selection timer tick happened, %s.\n",
                       dev->name, media_tbl[dev->if_port].name);
 
        spin_lock_irqsave(&vp->lock, flags);
@@ -894,12 +893,12 @@ static void corkscrew_timer(unsigned long data)
                        if (media_status & Media_LnkBeat) {
                                ok = 1;
                                if (corkscrew_debug > 1)
-                                       printk("%s: Media %s has link beat, %x.\n",
+                                       pr_debug("%s: Media %s has link beat, %x.\n",
                                                dev->name,
                                                media_tbl[dev->if_port].name,
                                                media_status);
                        } else if (corkscrew_debug > 1)
-                               printk("%s: Media %s is has no link beat, %x.\n",
+                               pr_debug("%s: Media %s is has no link beat, %x.\n",
                                        dev->name,
                                        media_tbl[dev->if_port].name,
                                        media_status);
@@ -907,7 +906,7 @@ static void corkscrew_timer(unsigned long data)
                        break;
                default:        /* Other media types handled by Tx timeouts. */
                        if (corkscrew_debug > 1)
-                               printk("%s: Media %s is has no indication, %x.\n",
+                               pr_debug("%s: Media %s is has no indication, %x.\n",
                                        dev->name,
                                        media_tbl[dev->if_port].name,
                                        media_status);
@@ -925,12 +924,12 @@ static void corkscrew_timer(unsigned long data)
                        if (dev->if_port == 8) {        /* Go back to default. */
                                dev->if_port = vp->default_media;
                                if (corkscrew_debug > 1)
-                                       printk("%s: Media selection failing, using default %s port.\n",
+                                       pr_debug("%s: Media selection failing, using default %s port.\n",
                                                dev->name,
                                                media_tbl[dev->if_port].name);
                        } else {
                                if (corkscrew_debug > 1)
-                                       printk("%s: Media selection failed, now trying %s port.\n",
+                                       pr_debug("%s: Media selection failed, now trying %s port.\n",
                                                dev->name,
                                                media_tbl[dev->if_port].name);
                                vp->timer.expires = jiffies + media_tbl[dev->if_port].wait;
@@ -953,7 +952,7 @@ static void corkscrew_timer(unsigned long data)
 
        spin_unlock_irqrestore(&vp->lock, flags);
        if (corkscrew_debug > 1)
-               printk("%s: Media selection timer finished, %s.\n",
+               pr_debug("%s: Media selection timer finished, %s.\n",
                       dev->name, media_tbl[dev->if_port].name);
 
 #endif                         /* AUTOMEDIA */
@@ -966,23 +965,21 @@ static void corkscrew_timeout(struct net_device *dev)
        struct corkscrew_private *vp = netdev_priv(dev);
        int ioaddr = dev->base_addr;
 
-       printk(KERN_WARNING
-              "%s: transmit timed out, tx_status %2.2x status %4.4x.\n",
+       pr_warning("%s: transmit timed out, tx_status %2.2x status %4.4x.\n",
               dev->name, inb(ioaddr + TxStatus),
               inw(ioaddr + EL3_STATUS));
        /* Slight code bloat to be user friendly. */
        if ((inb(ioaddr + TxStatus) & 0x88) == 0x88)
-               printk(KERN_WARNING
-                      "%s: Transmitter encountered 16 collisions -- network"
+               pr_warning("%s: Transmitter encountered 16 collisions --"
                       " network cable problem?\n", dev->name);
 #ifndef final_version
-       printk("  Flags; bus-master %d, full %d; dirty %d current %d.\n",
+       pr_debug("  Flags; bus-master %d, full %d; dirty %d current %d.\n",
               vp->full_bus_master_tx, vp->tx_full, vp->dirty_tx,
               vp->cur_tx);
-       printk("  Down list %8.8x vs. %p.\n", inl(ioaddr + DownListPtr),
+       pr_debug("  Down list %8.8x vs. %p.\n", inl(ioaddr + DownListPtr),
               &vp->tx_ring[0]);
        for (i = 0; i < TX_RING_SIZE; i++) {
-               printk("  %d: %p  length %8.8x status %8.8x\n", i,
+               pr_debug("  %d: %p  length %8.8x status %8.8x\n", i,
                       &vp->tx_ring[i],
                       vp->tx_ring[i].length, vp->tx_ring[i].status);
        }
@@ -1017,13 +1014,13 @@ static int corkscrew_start_xmit(struct sk_buff *skb,
                int i;
 
                if (vp->tx_full)        /* No room to transmit with */
-                       return 1;
+                       return NETDEV_TX_BUSY;
                if (vp->cur_tx != 0)
                        prev_entry = &vp->tx_ring[(vp->cur_tx - 1) % TX_RING_SIZE];
                else
                        prev_entry = NULL;
                if (corkscrew_debug > 3)
-                       printk("%s: Trying to send a packet, Tx index %d.\n",
+                       pr_debug("%s: Trying to send a packet, Tx index %d.\n",
                                dev->name, vp->cur_tx);
                /* vp->tx_full = 1; */
                vp->tx_skbuff[entry] = skb;
@@ -1102,7 +1099,7 @@ static int corkscrew_start_xmit(struct sk_buff *skb,
                while (--i > 0 && (tx_status = inb(ioaddr + TxStatus)) > 0) {
                        if (tx_status & 0x3C) { /* A Tx-disabling error occurred.  */
                                if (corkscrew_debug > 2)
-                                       printk("%s: Tx error, status %2.2x.\n",
+                                       pr_debug("%s: Tx error, status %2.2x.\n",
                                                dev->name, tx_status);
                                if (tx_status & 0x04)
                                        dev->stats.tx_fifo_errors++;
@@ -1143,7 +1140,7 @@ static irqreturn_t corkscrew_interrupt(int irq, void *dev_id)
        status = inw(ioaddr + EL3_STATUS);
 
        if (corkscrew_debug > 4)
-               printk("%s: interrupt, status %4.4x, timer %d.\n",
+               pr_debug("%s: interrupt, status %4.4x, timer %d.\n",
                        dev->name, status, latency);
        if ((status & 0xE000) != 0xE000) {
                static int donedidthis;
@@ -1151,7 +1148,7 @@ static irqreturn_t corkscrew_interrupt(int irq, void *dev_id)
                   Ignore a single early interrupt, but don't hang the machine for
                   other interrupt problems. */
                if (donedidthis++ > 100) {
-                       printk(KERN_ERR "%s: Bogus interrupt, bailing. Status %4.4x, start=%d.\n",
+                       pr_err("%s: Bogus interrupt, bailing. Status %4.4x, start=%d.\n",
                                   dev->name, status, netif_running(dev));
                        free_irq(dev->irq, dev);
                        dev->irq = -1;
@@ -1160,14 +1157,14 @@ static irqreturn_t corkscrew_interrupt(int irq, void *dev_id)
 
        do {
                if (corkscrew_debug > 5)
-                       printk("%s: In interrupt loop, status %4.4x.\n",
+                       pr_debug("%s: In interrupt loop, status %4.4x.\n",
                               dev->name, status);
                if (status & RxComplete)
                        corkscrew_rx(dev);
 
                if (status & TxAvailable) {
                        if (corkscrew_debug > 5)
-                               printk("        TX room bit was handled.\n");
+                               pr_debug("      TX room bit was handled.\n");
                        /* There's room in the FIFO for a full-sized packet. */
                        outw(AckIntr | TxAvailable, ioaddr + EL3_CMD);
                        netif_wake_queue(dev);
@@ -1212,19 +1209,20 @@ static irqreturn_t corkscrew_interrupt(int irq, void *dev_id)
                        if (status & StatsFull) {       /* Empty statistics. */
                                static int DoneDidThat;
                                if (corkscrew_debug > 4)
-                                       printk("%s: Updating stats.\n", dev->name);
+                                       pr_debug("%s: Updating stats.\n", dev->name);
                                update_stats(ioaddr, dev);
                                /* DEBUG HACK: Disable statistics as an interrupt source. */
                                /* This occurs when we have the wrong media type! */
                                if (DoneDidThat == 0 && inw(ioaddr + EL3_STATUS) & StatsFull) {
                                        int win, reg;
-                                       printk("%s: Updating stats failed, disabling stats as an"
-                                            " interrupt source.\n", dev->name);
+                                       pr_notice("%s: Updating stats failed, disabling stats as an interrupt source.\n",
+                                               dev->name);
                                        for (win = 0; win < 8; win++) {
                                                EL3WINDOW(win);
-                                               printk("\n Vortex window %d:", win);
+                                               pr_notice("Vortex window %d:", win);
                                                for (reg = 0; reg < 16; reg++)
-                                                       printk(" %2.2x", inb(ioaddr + reg));
+                                                       pr_cont(" %2.2x", inb(ioaddr + reg));
+                                               pr_cont("\n");
                                        }
                                        EL3WINDOW(7);
                                        outw(SetIntrEnb | TxAvailable |
@@ -1246,9 +1244,8 @@ static irqreturn_t corkscrew_interrupt(int irq, void *dev_id)
                }
 
                if (--i < 0) {
-                       printk(KERN_ERR "%s: Too much work in interrupt, status %4.4x.  "
-                            "Disabling functions (%4.4x).\n", dev->name,
-                            status, SetStatusEnb | ((~status) & 0x7FE));
+                       pr_err("%s: Too much work in interrupt, status %4.4x. Disabling functions (%4.4x).\n",
+                               dev->name, status, SetStatusEnb | ((~status) & 0x7FE));
                        /* Disable all pending interrupts. */
                        outw(SetStatusEnb | ((~status) & 0x7FE), ioaddr + EL3_CMD);
                        outw(AckIntr | 0x7FF, ioaddr + EL3_CMD);
@@ -1262,7 +1259,7 @@ static irqreturn_t corkscrew_interrupt(int irq, void *dev_id)
        spin_unlock(&lp->lock);
 
        if (corkscrew_debug > 4)
-               printk("%s: exiting interrupt, status %4.4x.\n", dev->name, status);
+               pr_debug("%s: exiting interrupt, status %4.4x.\n", dev->name, status);
        return IRQ_HANDLED;
 }
 
@@ -1273,13 +1270,13 @@ static int corkscrew_rx(struct net_device *dev)
        short rx_status;
 
        if (corkscrew_debug > 5)
-               printk("   In rx_packet(), status %4.4x, rx_status %4.4x.\n",
+               pr_debug("   In rx_packet(), status %4.4x, rx_status %4.4x.\n",
                     inw(ioaddr + EL3_STATUS), inw(ioaddr + RxStatus));
        while ((rx_status = inw(ioaddr + RxStatus)) > 0) {
                if (rx_status & 0x4000) {       /* Error, update stats. */
                        unsigned char rx_error = inb(ioaddr + RxErrors);
                        if (corkscrew_debug > 2)
-                               printk(" Rx error: status %2.2x.\n",
+                               pr_debug(" Rx error: status %2.2x.\n",
                                       rx_error);
                        dev->stats.rx_errors++;
                        if (rx_error & 0x01)
@@ -1299,7 +1296,7 @@ static int corkscrew_rx(struct net_device *dev)
 
                        skb = dev_alloc_skb(pkt_len + 5 + 2);
                        if (corkscrew_debug > 4)
-                               printk("Receiving packet size %d status %4.4x.\n",
+                               pr_debug("Receiving packet size %d status %4.4x.\n",
                                     pkt_len, rx_status);
                        if (skb != NULL) {
                                skb_reserve(skb, 2);    /* Align IP on 16 byte boundaries */
@@ -1318,7 +1315,7 @@ static int corkscrew_rx(struct net_device *dev)
                                                break;
                                continue;
                        } else if (corkscrew_debug)
-                               printk("%s: Couldn't allocate a sk_buff of size %d.\n", dev->name, pkt_len);
+                               pr_debug("%s: Couldn't allocate a sk_buff of size %d.\n", dev->name, pkt_len);
                }
                outw(RxDiscard, ioaddr + EL3_CMD);
                dev->stats.rx_dropped++;
@@ -1338,13 +1335,13 @@ static int boomerang_rx(struct net_device *dev)
        int rx_status;
 
        if (corkscrew_debug > 5)
-               printk("   In boomerang_rx(), status %4.4x, rx_status %4.4x.\n",
+               pr_debug("   In boomerang_rx(), status %4.4x, rx_status %4.4x.\n",
                        inw(ioaddr + EL3_STATUS), inw(ioaddr + RxStatus));
        while ((rx_status = vp->rx_ring[entry].status) & RxDComplete) {
                if (rx_status & RxDError) {     /* Error, update stats. */
                        unsigned char rx_error = rx_status >> 16;
                        if (corkscrew_debug > 2)
-                               printk(" Rx error: status %2.2x.\n",
+                               pr_debug(" Rx error: status %2.2x.\n",
                                       rx_error);
                        dev->stats.rx_errors++;
                        if (rx_error & 0x01)
@@ -1364,7 +1361,7 @@ static int boomerang_rx(struct net_device *dev)
 
                        dev->stats.rx_bytes += pkt_len;
                        if (corkscrew_debug > 4)
-                               printk("Receiving packet size %d status %4.4x.\n",
+                               pr_debug("Receiving packet size %d status %4.4x.\n",
                                     pkt_len, rx_status);
 
                        /* Check if the packet is long enough to just accept without
@@ -1385,7 +1382,7 @@ static int boomerang_rx(struct net_device *dev)
                                temp = skb_put(skb, pkt_len);
                                /* Remove this checking code for final release. */
                                if (isa_bus_to_virt(vp->rx_ring[entry].addr) != temp)
-                                           printk("%s: Warning -- the skbuff addresses do not match"
+                                       pr_warning("%s: Warning -- the skbuff addresses do not match"
                                             " in boomerang_rx: %p vs. %p / %p.\n",
                                             dev->name,
                                             isa_bus_to_virt(vp->
@@ -1427,12 +1424,11 @@ static int corkscrew_close(struct net_device *dev)
        netif_stop_queue(dev);
 
        if (corkscrew_debug > 1) {
-               printk("%s: corkscrew_close() status %4.4x, Tx status %2.2x.\n",
+               pr_debug("%s: corkscrew_close() status %4.4x, Tx status %2.2x.\n",
                     dev->name, inw(ioaddr + EL3_STATUS),
                     inb(ioaddr + TxStatus));
-               printk("%s: corkscrew close stats: rx_nocopy %d rx_copy %d"
-                      " tx_queued %d.\n", dev->name, rx_nocopy, rx_copy,
-                      queued_packet);
+               pr_debug("%s: corkscrew close stats: rx_nocopy %d rx_copy %d tx_queued %d.\n",
+                       dev->name, rx_nocopy, rx_copy, queued_packet);
        }
 
        del_timer(&vp->timer);
@@ -1534,7 +1530,7 @@ static void set_rx_mode(struct net_device *dev)
 
        if (dev->flags & IFF_PROMISC) {
                if (corkscrew_debug > 3)
-                       printk("%s: Setting promiscuous mode.\n",
+                       pr_debug("%s: Setting promiscuous mode.\n",
                               dev->name);
                new_mode = SetRxFilter | RxStation | RxMulticast | RxBroadcast | RxProm;
        } else if ((dev->mc_list) || (dev->flags & IFF_ALLMULTI)) {
index 8f734d74b513f66b33e3c89b7c8779125e832246..cdd955c4014c674d42bc3ea15f3446650b544bf0 100644 (file)
@@ -176,7 +176,7 @@ sizeof(nop_cmd) = 8;
     if(!p->scb->cmd) break; \
     DELAY_16(); \
     if(i == 1023) { \
-      printk(KERN_WARNING "%s:%d: scb_cmd timed out .. resetting i82586\n",\
+      pr_warning("%s:%d: scb_cmd timed out .. resetting i82586\n",\
        dev->name,__LINE__); \
       elmc_id_reset586(); } } }
 
@@ -291,7 +291,7 @@ static int elmc_open(struct net_device *dev)
        ret = request_irq(dev->irq, &elmc_interrupt, IRQF_SHARED | IRQF_SAMPLE_RANDOM,
                          dev->name, dev);
        if (ret) {
-               printk(KERN_ERR "%s: couldn't get irq %d\n", dev->name, dev->irq);
+               pr_err("%s: couldn't get irq %d\n", dev->name, dev->irq);
                elmc_id_reset586();
                return ret;
        }
@@ -371,9 +371,9 @@ static void alloc586(struct net_device *dev)
 
        DELAY(2);
 
-       if (p->iscp->busy) {
-               printk(KERN_ERR "%s: Init-Problems (alloc).\n", dev->name);
-       }
+       if (p->iscp->busy)
+               pr_err("%s: Init-Problems (alloc).\n", dev->name);
+
        memset((char *) p->scb, 0, sizeof(struct scb_struct));
 }
 
@@ -470,7 +470,7 @@ static int __init do_elmc_probe(struct net_device *dev)
        mca_set_adapter_procfn(slot, (MCA_ProcFn) elmc_getinfo, dev);
 
        /* if we get this far, adapter has been found - carry on */
-       printk(KERN_INFO "%s: 3c523 adapter found in slot %d\n", dev->name, slot + 1);
+       pr_info("%s: 3c523 adapter found in slot %d\n", dev->name, slot + 1);
 
        /* Now we extract configuration info from the card.
           The 3c523 provides information in two of the POS registers, but
@@ -507,7 +507,7 @@ static int __init do_elmc_probe(struct net_device *dev)
        memset(pr, 0, sizeof(struct priv));
        pr->slot = slot;
 
-       printk(KERN_INFO "%s: 3Com 3c523 Rev 0x%x at %#lx\n", dev->name, (int) revision,
+       pr_info("%s: 3Com 3c523 Rev 0x%x at %#lx\n", dev->name, (int) revision,
               dev->base_addr);
 
        /* Determine if we're using the on-board transceiver (i.e. coax) or
@@ -529,7 +529,7 @@ static int __init do_elmc_probe(struct net_device *dev)
 
        size = 0x4000;          /* check for 16K mem */
        if (!check586(dev, dev->mem_start, size)) {
-               printk(KERN_ERR "%s: memprobe, Can't find memory at 0x%lx!\n", dev->name,
+               pr_err("%s: memprobe, Can't find memory at 0x%lx!\n", dev->name,
                       dev->mem_start);
                retval = -ENODEV;
                goto err_out;
@@ -546,7 +546,7 @@ static int __init do_elmc_probe(struct net_device *dev)
        pr->num_recv_buffs = NUM_RECV_BUFFS_16;
 
        /* dump all the assorted information */
-       printk(KERN_INFO "%s: IRQ %d, %sternal xcvr, memory %#lx-%#lx.\n", dev->name,
+       pr_info("%s: IRQ %d, %sternal xcvr, memory %#lx-%#lx.\n", dev->name,
               dev->irq, dev->if_port ? "ex" : "in",
               dev->mem_start, dev->mem_end - 1);
 
@@ -555,7 +555,7 @@ static int __init do_elmc_probe(struct net_device *dev)
        for (i = 0; i < 6; i++)
                dev->dev_addr[i] = inb(dev->base_addr + i);
 
-       printk(KERN_INFO "%s: hardware address %pM\n",
+       pr_info("%s: hardware address %pM\n",
               dev->name, dev->dev_addr);
 
        dev->netdev_ops = &netdev_ops;
@@ -660,7 +660,7 @@ static int init586(struct net_device *dev)
        }
 
        if ((cfg_cmd->cmd_status & (STAT_OK | STAT_COMPL)) != (STAT_COMPL | STAT_OK)) {
-               printk(KERN_WARNING "%s (elmc): configure command failed: %x\n", dev->name, cfg_cmd->cmd_status);
+               pr_warning("%s (elmc): configure command failed: %x\n", dev->name, cfg_cmd->cmd_status);
                return 1;
        }
        /*
@@ -686,7 +686,8 @@ static int init586(struct net_device *dev)
        }
 
        if ((ias_cmd->cmd_status & (STAT_OK | STAT_COMPL)) != (STAT_OK | STAT_COMPL)) {
-               printk(KERN_WARNING "%s (elmc): individual address setup command failed: %04x\n", dev->name, ias_cmd->cmd_status);
+               pr_warning("%s (elmc): individual address setup command failed: %04x\n",
+                       dev->name, ias_cmd->cmd_status);
                return 1;
        }
        /*
@@ -707,7 +708,7 @@ static int init586(struct net_device *dev)
        s = jiffies;
        while (!(tdr_cmd->cmd_status & STAT_COMPL)) {
                if (time_after(jiffies, s + 30*HZ/100)) {
-                       printk(KERN_WARNING "%s: %d Problems while running the TDR.\n", dev->name, __LINE__);
+                       pr_warning("%s: %d Problems while running the TDR.\n", dev->name, __LINE__);
                        result = 1;
                        break;
                }
@@ -723,14 +724,14 @@ static int init586(struct net_device *dev)
                if (result & TDR_LNK_OK) {
                        /* empty */
                } else if (result & TDR_XCVR_PRB) {
-                       printk(KERN_WARNING "%s: TDR: Transceiver problem!\n", dev->name);
+                       pr_warning("%s: TDR: Transceiver problem!\n", dev->name);
                } else if (result & TDR_ET_OPN) {
-                       printk(KERN_WARNING "%s: TDR: No correct termination %d clocks away.\n", dev->name, result & TDR_TIMEMASK);
+                       pr_warning("%s: TDR: No correct termination %d clocks away.\n", dev->name, result & TDR_TIMEMASK);
                } else if (result & TDR_ET_SRT) {
                        if (result & TDR_TIMEMASK)      /* time == 0 -> strange :-) */
-                               printk(KERN_WARNING "%s: TDR: Detected a short circuit %d clocks away.\n", dev->name, result & TDR_TIMEMASK);
+                               pr_warning("%s: TDR: Detected a short circuit %d clocks away.\n", dev->name, result & TDR_TIMEMASK);
                } else {
-                       printk(KERN_WARNING "%s: TDR: Unknown status %04x\n", dev->name, result);
+                       pr_warning("%s: TDR: Unknown status %04x\n", dev->name, result);
                }
        }
        /*
@@ -774,11 +775,11 @@ static int init586(struct net_device *dev)
                /* I don't understand this: do we really need memory after the init? */
                int len = ((char *) p->iscp - (char *) ptr - 8) / 6;
                if (len <= 0) {
-                       printk(KERN_ERR "%s: Ooooops, no memory for MC-Setup!\n", dev->name);
+                       pr_err("%s: Ooooops, no memory for MC-Setup!\n", dev->name);
                } else {
                        if (len < num_addrs) {
                                num_addrs = len;
-                               printk(KERN_WARNING "%s: Sorry, can only apply %d MC-Address(es).\n",
+                               pr_warning("%s: Sorry, can only apply %d MC-Address(es).\n",
                                       dev->name, num_addrs);
                        }
                        mc_cmd = (struct mcsetup_cmd_struct *) ptr;
@@ -799,7 +800,7 @@ static int init586(struct net_device *dev)
                                        break;
                        }
                        if (!(mc_cmd->cmd_status & STAT_COMPL)) {
-                               printk(KERN_WARNING "%s: Can't apply multicast-address-list.\n", dev->name);
+                               pr_warning("%s: Can't apply multicast-address-list.\n", dev->name);
                        }
                }
        }
@@ -812,7 +813,7 @@ static int init586(struct net_device *dev)
                p->xmit_buffs[i] = (struct tbd_struct *) ptr;   /* TBD */
                ptr = (char *) ptr + sizeof(struct tbd_struct);
                if ((void *) ptr > (void *) p->iscp) {
-                       printk(KERN_ERR "%s: not enough shared-mem for your configuration!\n", dev->name);
+                       pr_err("%s: not enough shared-mem for your configuration!\n", dev->name);
                        return 1;
                }
                memset((char *) (p->xmit_cmds[i]), 0, sizeof(struct transmit_cmd_struct));
@@ -936,7 +937,8 @@ elmc_interrupt(int irq, void *dev_id)
                if (stat & STAT_CNA) {
                        /* CU went 'not ready' */
                        if (netif_running(dev)) {
-                               printk(KERN_WARNING "%s: oops! CU has left active state. stat: %04x/%04x.\n", dev->name, (int) stat, (int) p->scb->status);
+                               pr_warning("%s: oops! CU has left active state. stat: %04x/%04x.\n",
+                                       dev->name, (int) stat, (int) p->scb->status);
                        }
                }
 #endif
@@ -951,7 +953,8 @@ elmc_interrupt(int irq, void *dev_id)
                                p->scb->cmd = RUC_RESUME;
                                elmc_attn586();
                        } else {
-                               printk(KERN_WARNING "%s: Receiver-Unit went 'NOT READY': %04x/%04x.\n", dev->name, (int) stat, (int) p->scb->status);
+                               pr_warning("%s: Receiver-Unit went 'NOT READY': %04x/%04x.\n",
+                                       dev->name, (int) stat, (int) p->scb->status);
                                elmc_rnr_int(dev);
                        }
                }
@@ -995,11 +998,11 @@ static void elmc_rcv_int(struct net_device *dev)
                                        dev->stats.rx_dropped++;
                                }
                        } else {
-                               printk(KERN_WARNING "%s: received oversized frame.\n", dev->name);
+                               pr_warning("%s: received oversized frame.\n", dev->name);
                                dev->stats.rx_dropped++;
                        }
                } else {        /* frame !(ok), only with 'save-bad-frames' */
-                       printk(KERN_WARNING "%s: oops! rfd-error-status: %04x\n", dev->name, status);
+                       pr_warning("%s: oops! rfd-error-status: %04x\n", dev->name, status);
                        dev->stats.rx_errors++;
                }
                p->rfd_top->status = 0;
@@ -1028,7 +1031,7 @@ static void elmc_rnr_int(struct net_device *dev)
        alloc_rfa(dev, (char *) p->rfd_first);
        startrecv586(dev);      /* restart RU */
 
-       printk(KERN_WARNING "%s: Receive-Unit restarted. Status: %04x\n", dev->name, p->scb->status);
+       pr_warning("%s: Receive-Unit restarted. Status: %04x\n", dev->name, p->scb->status);
 
 }
 
@@ -1043,7 +1046,7 @@ static void elmc_xmt_int(struct net_device *dev)
 
        status = p->xmit_cmds[p->xmit_last]->cmd_status;
        if (!(status & STAT_COMPL)) {
-               printk(KERN_WARNING "%s: strange .. xmit-int without a 'COMPLETE'\n", dev->name);
+               pr_warning("%s: strange .. xmit-int without a 'COMPLETE'\n", dev->name);
        }
        if (status & STAT_OK) {
                dev->stats.tx_packets++;
@@ -1051,18 +1054,18 @@ static void elmc_xmt_int(struct net_device *dev)
        } else {
                dev->stats.tx_errors++;
                if (status & TCMD_LATECOLL) {
-                       printk(KERN_WARNING "%s: late collision detected.\n", dev->name);
+                       pr_warning("%s: late collision detected.\n", dev->name);
                        dev->stats.collisions++;
                } else if (status & TCMD_NOCARRIER) {
                        dev->stats.tx_carrier_errors++;
-                       printk(KERN_WARNING "%s: no carrier detected.\n", dev->name);
+                       pr_warning("%s: no carrier detected.\n", dev->name);
                } else if (status & TCMD_LOSTCTS) {
-                       printk(KERN_WARNING "%s: loss of CTS detected.\n", dev->name);
+                       pr_warning("%s: loss of CTS detected.\n", dev->name);
                } else if (status & TCMD_UNDERRUN) {
                        dev->stats.tx_fifo_errors++;
-                       printk(KERN_WARNING "%s: DMA underrun detected.\n", dev->name);
+                       pr_warning("%s: DMA underrun detected.\n", dev->name);
                } else if (status & TCMD_MAXCOLL) {
-                       printk(KERN_WARNING "%s: Max. collisions exceeded.\n", dev->name);
+                       pr_warning("%s: Max. collisions exceeded.\n", dev->name);
                        dev->stats.collisions += 16;
                }
        }
@@ -1099,10 +1102,11 @@ static void elmc_timeout(struct net_device *dev)
        struct priv *p = netdev_priv(dev);
        /* COMMAND-UNIT active? */
        if (p->scb->status & CU_ACTIVE) {
-#ifdef DEBUG
-               printk("%s: strange ... timeout with CU active?!?\n", dev->name);
-               printk("%s: X0: %04x N0: %04x N1: %04x %d\n", dev->name, (int) p->xmit_cmds[0]->cmd_status, (int) p->nop_cmds[0]->cmd_status, (int) p->nop_cmds[1]->cmd_status, (int) p->nop_point);
-#endif
+               pr_debug("%s: strange ... timeout with CU active?!?\n", dev->name);
+               pr_debug("%s: X0: %04x N0: %04x N1: %04x %d\n", dev->name,
+                       (int)p->xmit_cmds[0]->cmd_status,
+                       (int)p->nop_cmds[0]->cmd_status,
+                       (int)p->nop_cmds[1]->cmd_status, (int)p->nop_point);
                p->scb->cmd = CUC_ABORT;
                elmc_attn586();
                WAIT_4_SCB_CMD();
@@ -1112,10 +1116,10 @@ static void elmc_timeout(struct net_device *dev)
                WAIT_4_SCB_CMD();
                netif_wake_queue(dev);
        } else {
-#ifdef DEBUG
-               printk("%s: xmitter timed out, try to restart! stat: %04x\n", dev->name, p->scb->status);
-               printk("%s: command-stats: %04x %04x\n", dev->name, p->xmit_cmds[0]->cmd_status, p->xmit_cmds[1]->cmd_status);
-#endif
+               pr_debug("%s: xmitter timed out, try to restart! stat: %04x\n",
+                       dev->name, p->scb->status);
+               pr_debug("%s: command-stats: %04x %04x\n", dev->name,
+                       p->xmit_cmds[0]->cmd_status, p->xmit_cmds[1]->cmd_status);
                elmc_close(dev);
                elmc_open(dev);
        }
@@ -1162,7 +1166,7 @@ static int elmc_send_packet(struct sk_buff *skb, struct net_device *dev)
                        break;
                }
                if (i == 15) {
-                       printk(KERN_WARNING "%s: Can't start transmit-command.\n", dev->name);
+                       pr_warning("%s: Can't start transmit-command.\n", dev->name);
                }
        }
 #else
@@ -1287,11 +1291,12 @@ int __init init_module(void)
                free_netdev(dev);
                if (io[this_dev]==0)
                        break;
-               printk(KERN_WARNING "3c523.c: No 3c523 card found at io=%#x\n",io[this_dev]);
+               pr_warning("3c523.c: No 3c523 card found at io=%#x\n",io[this_dev]);
        }
 
        if(found==0) {
-               if(io[0]==0) printk(KERN_NOTICE "3c523.c: No 3c523 cards found\n");
+               if (io[0]==0)
+                       pr_notice("3c523.c: No 3c523 cards found\n");
                return -ENXIO;
        } else return 0;
 }
index b61073c42bf8641b1623243e5fa30d19299b79aa..aaa8a9f405d4f9877c4b68b41672390f48ac6193 100644 (file)
@@ -125,8 +125,6 @@ static const char* cardname = DRV_NAME;
 #define NET_DEBUG 2
 #endif
 
-#undef DEBUG_IRQ
-
 static unsigned int mc32_debug = NET_DEBUG;
 
 /* The number of low I/O ports used by the ethercard. */
@@ -351,15 +349,15 @@ static int __init mc32_probe1(struct net_device *dev, int slot)
        /* Time to play MCA games */
 
        if (mc32_debug  &&  version_printed++ == 0)
-               printk(KERN_DEBUG "%s", version);
+               pr_debug("%s", version);
 
-       printk(KERN_INFO "%s: %s found in slot %d:", dev->name, cardname, slot);
+       pr_info("%s: %s found in slot %d: ", dev->name, cardname, slot);
 
        POS = mca_read_stored_pos(slot, 2);
 
        if(!(POS&1))
        {
-               printk(" disabled.\n");
+               pr_cont("disabled.\n");
                return -ENODEV;
        }
 
@@ -370,7 +368,7 @@ static int __init mc32_probe1(struct net_device *dev, int slot)
        POS = mca_read_stored_pos(slot, 4);
        if(!(POS&1))
        {
-               printk("memory window disabled.\n");
+               pr_cont("memory window disabled.\n");
                return -ENODEV;
        }
 
@@ -379,7 +377,7 @@ static int __init mc32_probe1(struct net_device *dev, int slot)
        i=(POS>>4)&3;
        if(i==3)
        {
-               printk("invalid memory window.\n");
+               pr_cont("invalid memory window.\n");
                return -ENODEV;
        }
 
@@ -392,11 +390,11 @@ static int __init mc32_probe1(struct net_device *dev, int slot)
 
        if(!request_region(dev->base_addr, MC32_IO_EXTENT, cardname))
        {
-               printk("io 0x%3lX, which is busy.\n", dev->base_addr);
+               pr_cont("io 0x%3lX, which is busy.\n", dev->base_addr);
                return -EBUSY;
        }
 
-       printk("io 0x%3lX irq %d mem 0x%lX (%dK)\n",
+       pr_cont("io 0x%3lX irq %d mem 0x%lX (%dK)\n",
                dev->base_addr, dev->irq, dev->mem_start, i/1024);
 
 
@@ -416,7 +414,7 @@ static int __init mc32_probe1(struct net_device *dev, int slot)
                dev->dev_addr[i] = mca_read_pos(slot,3);
        }
 
-       printk("%s: Address %pM", dev->name, dev->dev_addr);
+       pr_info("%s: Address %pM ", dev->name, dev->dev_addr);
 
        mca_write_pos(slot, 6, 0);
        mca_write_pos(slot, 7, 0);
@@ -424,9 +422,9 @@ static int __init mc32_probe1(struct net_device *dev, int slot)
        POS = mca_read_stored_pos(slot, 4);
 
        if(POS&2)
-               printk(" : BNC port selected.\n");
+               pr_cont(": BNC port selected.\n");
        else
-               printk(" : AUI port selected.\n");
+               pr_cont(": AUI port selected.\n");
 
        POS=inb(dev->base_addr+HOST_CTRL);
        POS|=HOST_CTRL_ATTN|HOST_CTRL_RESET;
@@ -447,7 +445,7 @@ static int __init mc32_probe1(struct net_device *dev, int slot)
        err = request_irq(dev->irq, &mc32_interrupt, IRQF_SHARED | IRQF_SAMPLE_RANDOM, DRV_NAME, dev);
        if (err) {
                release_region(dev->base_addr, MC32_IO_EXTENT);
-               printk(KERN_ERR "%s: unable to get IRQ %d.\n", DRV_NAME, dev->irq);
+               pr_err("%s: unable to get IRQ %d.\n", DRV_NAME, dev->irq);
                goto err_exit_ports;
        }
 
@@ -463,7 +461,7 @@ static int __init mc32_probe1(struct net_device *dev, int slot)
                i++;
                if(i == 1000)
                {
-                       printk(KERN_ERR "%s: failed to boot adapter.\n", dev->name);
+                       pr_err("%s: failed to boot adapter.\n", dev->name);
                        err = -ENODEV;
                        goto err_exit_irq;
                }
@@ -475,10 +473,10 @@ static int __init mc32_probe1(struct net_device *dev, int slot)
        if(base>0)
        {
                if(base < 0x0C)
-                       printk(KERN_ERR "%s: %s%s.\n", dev->name, failures[base-1],
+                       pr_err("%s: %s%s.\n", dev->name, failures[base-1],
                                base<0x0A?" test failure":"");
                else
-                       printk(KERN_ERR "%s: unknown failure %d.\n", dev->name, base);
+                       pr_err("%s: unknown failure %d.\n", dev->name, base);
                err = -ENODEV;
                goto err_exit_irq;
        }
@@ -494,7 +492,7 @@ static int __init mc32_probe1(struct net_device *dev, int slot)
                        udelay(50);
                        if(n>100)
                        {
-                               printk(KERN_ERR "%s: mailbox read fail (%d).\n", dev->name, i);
+                               pr_err("%s: mailbox read fail (%d).\n", dev->name, i);
                                err = -ENODEV;
                                goto err_exit_irq;
                        }
@@ -527,7 +525,7 @@ static int __init mc32_probe1(struct net_device *dev, int slot)
        init_completion(&lp->execution_cmd);
        init_completion(&lp->xceiver_cmd);
 
-       printk("%s: Firmware Rev %d. %d RX buffers, %d TX buffers. Base of 0x%08X.\n",
+       pr_info("%s: Firmware Rev %d. %d RX buffers, %d TX buffers. Base of 0x%08X.\n",
                dev->name, lp->exec_box->data[12], lp->rx_len, lp->tx_len, lp->base);
 
        dev->netdev_ops         = &netdev_ops;
@@ -939,7 +937,7 @@ static int mc32_open(struct net_device *dev)
         */
 
        if(mc32_command(dev, 8, descnumbuffs, 4)) {
-               printk("%s: %s rejected our buffer configuration!\n",
+               pr_info("%s: %s rejected our buffer configuration!\n",
                       dev->name, cardname);
                mc32_close(dev);
                return -ENOBUFS;
@@ -995,7 +993,7 @@ static int mc32_open(struct net_device *dev)
 
 static void mc32_timeout(struct net_device *dev)
 {
-       printk(KERN_WARNING "%s: transmit timed out?\n", dev->name);
+       pr_warning("%s: transmit timed out?\n", dev->name);
        /* Try to restart the adaptor. */
        netif_wake_queue(dev);
 }
@@ -1032,7 +1030,7 @@ static int mc32_send_packet(struct sk_buff *skb, struct net_device *dev)
        netif_stop_queue(dev);
 
        if(atomic_read(&lp->tx_count)==0) {
-               return 1;
+               return NETDEV_TX_BUSY;
        }
 
        if (skb_padto(skb, ETH_ZLEN)) {
@@ -1335,11 +1333,9 @@ static irqreturn_t mc32_interrupt(int irq, void *dev_id)
        {
                status=inb(ioaddr+HOST_CMD);
 
-#ifdef DEBUG_IRQ
-               printk("Status TX%d RX%d EX%d OV%d BC%d\n",
+               pr_debug("Status TX%d RX%d EX%d OV%d BC%d\n",
                        (status&7), (status>>3)&7, (status>>6)&1,
                        (status>>7)&1, boguscount);
-#endif
 
                switch(status&7)
                {
@@ -1354,7 +1350,7 @@ static irqreturn_t mc32_interrupt(int irq, void *dev_id)
                                complete(&lp->xceiver_cmd);
                                break;
                        default:
-                               printk("%s: strange tx ack %d\n", dev->name, status&7);
+                               pr_notice("%s: strange tx ack %d\n", dev->name, status&7);
                }
                status>>=3;
                switch(status&7)
@@ -1376,7 +1372,7 @@ static irqreturn_t mc32_interrupt(int irq, void *dev_id)
                                mc32_start_transceiver(dev);
                                break;
                        default:
-                               printk("%s: strange rx ack %d\n",
+                               pr_notice("%s: strange rx ack %d\n",
                                        dev->name, status&7);
                }
                status>>=3;
index c56698402420ab5493c83fed72dc3f2b44089f47..c34aee91250b031176b3028563498ae62e0c0d1a 100644 (file)
@@ -828,14 +828,14 @@ static int vortex_resume(struct pci_dev *pdev)
                pci_restore_state(pdev);
                err = pci_enable_device(pdev);
                if (err) {
-                       printk(KERN_WARNING "%s: Could not enable device \n",
+                       pr_warning("%s: Could not enable device\n",
                                dev->name);
                        return err;
                }
                pci_set_master(pdev);
                if (request_irq(dev->irq, vp->full_bus_master_rx ?
                                &boomerang_interrupt : &vortex_interrupt, IRQF_SHARED, dev->name, dev)) {
-                       printk(KERN_WARNING "%s: Could not reserve IRQ %d\n", dev->name, dev->irq);
+                       pr_warning("%s: Could not reserve IRQ %d\n", dev->name, dev->irq);
                        pci_disable_device(pdev);
                        return -EBUSY;
                }
@@ -894,7 +894,7 @@ static int __devexit vortex_eisa_remove(struct device *device)
        dev = eisa_get_drvdata(edev);
 
        if (!dev) {
-               printk("vortex_eisa_remove called for Compaq device!\n");
+               pr_err("vortex_eisa_remove called for Compaq device!\n");
                BUG();
        }
 
@@ -1051,7 +1051,7 @@ static int __devinit vortex_probe1(struct device *gendev,
        struct eisa_device *edev = NULL;
 
        if (!printed_version) {
-               printk (version);
+               pr_info("%s", version);
                printed_version = 1;
        }
 
@@ -1068,7 +1068,7 @@ static int __devinit vortex_probe1(struct device *gendev,
        dev = alloc_etherdev(sizeof(*vp));
        retval = -ENOMEM;
        if (!dev) {
-               printk (KERN_ERR PFX "unable to allocate etherdev, aborting\n");
+               pr_err(PFX "unable to allocate etherdev, aborting\n");
                goto out;
        }
        SET_NETDEV_DEV(dev, gendev);
@@ -1100,9 +1100,9 @@ static int __devinit vortex_probe1(struct device *gendev,
 
        print_info = (vortex_debug > 1);
        if (print_info)
-               printk (KERN_INFO "See Documentation/networking/vortex.txt\n");
+               pr_info("See Documentation/networking/vortex.txt\n");
 
-       printk(KERN_INFO "%s: 3Com %s %s at %p.\n",
+       pr_info("%s: 3Com %s %s at %p.\n",
               print_name,
               pdev ? "PCI" : "EISA",
               vci->name,
@@ -1144,10 +1144,9 @@ static int __devinit vortex_probe1(struct device *gendev,
                           chip only. */
                        pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &pci_latency);
                        if (pci_latency < new_latency) {
-                               printk(KERN_INFO "%s: Overriding PCI latency"
-                                       " timer (CFLT) setting of %d, new value is %d.\n",
+                               pr_info("%s: Overriding PCI latency timer (CFLT) setting of %d, new value is %d.\n",
                                        print_name, pci_latency, new_latency);
-                                       pci_write_config_byte(pdev, PCI_LATENCY_TIMER, new_latency);
+                               pci_write_config_byte(pdev, PCI_LATENCY_TIMER, new_latency);
                        }
                }
        }
@@ -1236,17 +1235,17 @@ static int __devinit vortex_probe1(struct device *gendev,
                checksum = (checksum ^ (checksum >> 8)) & 0xff;
        }
        if ((checksum != 0x00) && !(vci->drv_flags & IS_TORNADO))
-               printk(" ***INVALID CHECKSUM %4.4x*** ", checksum);
+               pr_cont(" ***INVALID CHECKSUM %4.4x*** ", checksum);
        for (i = 0; i < 3; i++)
                ((__be16 *)dev->dev_addr)[i] = htons(eeprom[i + 10]);
        memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
        if (print_info)
-               printk(" %pM", dev->dev_addr);
+               pr_cont(" %pM", dev->dev_addr);
        /* Unfortunately an all zero eeprom passes the checksum and this
           gets found in the wild in failure cases. Crypto is hard 8) */
        if (!is_valid_ether_addr(dev->dev_addr)) {
                retval = -EINVAL;
-               printk(KERN_ERR "*** EEPROM MAC address is invalid.\n");
+               pr_err("*** EEPROM MAC address is invalid.\n");
                goto free_ring; /* With every pack */
        }
        EL3WINDOW(2);
@@ -1254,17 +1253,17 @@ static int __devinit vortex_probe1(struct device *gendev,
                iowrite8(dev->dev_addr[i], ioaddr + i);
 
        if (print_info)
-               printk(", IRQ %d\n", dev->irq);
+               pr_cont(", IRQ %d\n", dev->irq);
        /* Tell them about an invalid IRQ. */
        if (dev->irq <= 0 || dev->irq >= nr_irqs)
-               printk(KERN_WARNING " *** Warning: IRQ %d is unlikely to work! ***\n",
+               pr_warning(" *** Warning: IRQ %d is unlikely to work! ***\n",
                           dev->irq);
 
        EL3WINDOW(4);
        step = (ioread8(ioaddr + Wn4_NetDiag) & 0x1e) >> 1;
        if (print_info) {
-               printk(KERN_INFO "  product code %02x%02x rev %02x.%d date %02d-"
-                       "%02d-%02d\n", eeprom[6]&0xff, eeprom[6]>>8, eeprom[0x14],
+               pr_info("  product code %02x%02x rev %02x.%d date %02d-%02d-%02d\n",
+                       eeprom[6]&0xff, eeprom[6]>>8, eeprom[0x14],
                        step, (eeprom[4]>>5) & 15, eeprom[4] & 31, eeprom[4]>>9);
        }
 
@@ -1279,8 +1278,7 @@ static int __devinit vortex_probe1(struct device *gendev,
                }
 
                if (print_info) {
-                       printk(KERN_INFO "%s: CardBus functions mapped "
-                               "%16.16llx->%p\n",
+                       pr_info("%s: CardBus functions mapped %16.16llx->%p\n",
                                print_name,
                                (unsigned long long)pci_resource_start(pdev, 2),
                                vp->cb_fn_base);
@@ -1307,7 +1305,7 @@ static int __devinit vortex_probe1(struct device *gendev,
        if (vp->info1 & 0x8000) {
                vp->full_duplex = 1;
                if (print_info)
-                       printk(KERN_INFO "Full duplex capable\n");
+                       pr_info("Full duplex capable\n");
        }
 
        {
@@ -1319,9 +1317,9 @@ static int __devinit vortex_probe1(struct device *gendev,
                        vp->available_media = 0x40;
                config = ioread32(ioaddr + Wn3_Config);
                if (print_info) {
-                       printk(KERN_DEBUG "  Internal config register is %4.4x, "
-                                  "transceivers %#x.\n", config, ioread16(ioaddr + Wn3_Options));
-                       printk(KERN_INFO "  %dK %s-wide RAM %s Rx:Tx split, %s%s interface.\n",
+                       pr_debug("  Internal config register is %4.4x, transceivers %#x.\n",
+                               config, ioread16(ioaddr + Wn3_Options));
+                       pr_info("  %dK %s-wide RAM %s Rx:Tx split, %s%s interface.\n",
                                   8 << RAM_SIZE(config),
                                   RAM_WIDTH(config) ? "word" : "byte",
                                   ram_split[RAM_SPLIT(config)],
@@ -1336,7 +1334,7 @@ static int __devinit vortex_probe1(struct device *gendev,
        }
 
        if (vp->media_override != 7) {
-               printk(KERN_INFO "%s:  Media override to transceiver type %d (%s).\n",
+               pr_info("%s:  Media override to transceiver type %d (%s).\n",
                                print_name, vp->media_override,
                                media_tbl[vp->media_override].name);
                dev->if_port = vp->media_override;
@@ -1369,8 +1367,8 @@ static int __devinit vortex_probe1(struct device *gendev,
                        if (mii_status  &&  mii_status != 0xffff) {
                                vp->phys[phy_idx++] = phyx;
                                if (print_info) {
-                                       printk(KERN_INFO "  MII transceiver found at address %d,"
-                                               " status %4x.\n", phyx, mii_status);
+                                       pr_info("  MII transceiver found at address %d, status %4x.\n",
+                                               phyx, mii_status);
                                }
                                if ((mii_status & 0x0040) == 0)
                                        mii_preamble_required++;
@@ -1378,7 +1376,7 @@ static int __devinit vortex_probe1(struct device *gendev,
                }
                mii_preamble_required--;
                if (phy_idx == 0) {
-                       printk(KERN_WARNING"  ***WARNING*** No MII transceivers found!\n");
+                       pr_warning("  ***WARNING*** No MII transceivers found!\n");
                        vp->phys[0] = 24;
                } else {
                        vp->advertising = mdio_read(dev, vp->phys[0], MII_ADVERTISE);
@@ -1394,7 +1392,7 @@ static int __devinit vortex_probe1(struct device *gendev,
        if (vp->capabilities & CapBusMaster) {
                vp->full_bus_master_tx = 1;
                if (print_info) {
-                       printk(KERN_INFO "  Enabling bus-master transmits and %s receives.\n",
+                       pr_info("  Enabling bus-master transmits and %s receives.\n",
                        (vp->info2 & 1) ? "early" : "whole-frame" );
                }
                vp->full_bus_master_rx = (vp->info2 & 1) ? 1 : 2;
@@ -1414,7 +1412,7 @@ static int __devinit vortex_probe1(struct device *gendev,
                dev->netdev_ops =  &vortex_netdev_ops;
 
        if (print_info) {
-               printk(KERN_INFO "%s: scatter/gather %sabled. h/w checksums %sabled\n",
+               pr_info("%s: scatter/gather %sabled. h/w checksums %sabled\n",
                                print_name,
                                (dev->features & NETIF_F_SG) ? "en":"dis",
                                (dev->features & NETIF_F_IP_CSUM) ? "en":"dis");
@@ -1442,7 +1440,7 @@ free_region:
        if (vp->must_free_region)
                release_region(dev->base_addr, vci->io_size);
        free_netdev(dev);
-       printk(KERN_ERR PFX "vortex_probe1 fails.  Returns %d\n", retval);
+       pr_err(PFX "vortex_probe1 fails.  Returns %d\n", retval);
 out:
        return retval;
 }
@@ -1464,13 +1462,13 @@ issue_and_wait(struct net_device *dev, int cmd)
        for (i = 0; i < 100000; i++) {
                if (!(ioread16(ioaddr + EL3_STATUS) & CmdInProgress)) {
                        if (vortex_debug > 1)
-                               printk(KERN_INFO "%s: command 0x%04x took %d usecs\n",
+                               pr_info("%s: command 0x%04x took %d usecs\n",
                                           dev->name, cmd, i * 10);
                        return;
                }
                udelay(10);
        }
-       printk(KERN_ERR "%s: command 0x%04x did not complete! Status=0x%x\n",
+       pr_err("%s: command 0x%04x did not complete! Status=0x%x\n",
                           dev->name, cmd, ioread16(ioaddr + EL3_STATUS));
 }
 
@@ -1480,7 +1478,7 @@ vortex_set_duplex(struct net_device *dev)
        struct vortex_private *vp = netdev_priv(dev);
        void __iomem *ioaddr = vp->ioaddr;
 
-       printk(KERN_INFO "%s:  setting %s-duplex.\n",
+       pr_info("%s:  setting %s-duplex.\n",
                dev->name, (vp->full_duplex) ? "full" : "half");
 
        EL3WINDOW(3);
@@ -1522,7 +1520,7 @@ vortex_up(struct net_device *dev)
                        pci_restore_state(VORTEX_PCI(vp));
                err = pci_enable_device(VORTEX_PCI(vp));
                if (err) {
-                       printk(KERN_WARNING "%s: Could not enable device \n",
+                       pr_warning("%s: Could not enable device\n",
                                dev->name);
                        goto err_out;
                }
@@ -1533,14 +1531,14 @@ vortex_up(struct net_device *dev)
        config = ioread32(ioaddr + Wn3_Config);
 
        if (vp->media_override != 7) {
-               printk(KERN_INFO "%s: Media override to transceiver %d (%s).\n",
+               pr_info("%s: Media override to transceiver %d (%s).\n",
                           dev->name, vp->media_override,
                           media_tbl[vp->media_override].name);
                dev->if_port = vp->media_override;
        } else if (vp->autoselect) {
                if (vp->has_nway) {
                        if (vortex_debug > 1)
-                               printk(KERN_INFO "%s: using NWAY device table, not %d\n",
+                               pr_info("%s: using NWAY device table, not %d\n",
                                                                dev->name, dev->if_port);
                        dev->if_port = XCVR_NWAY;
                } else {
@@ -1549,13 +1547,13 @@ vortex_up(struct net_device *dev)
                        while (! (vp->available_media & media_tbl[dev->if_port].mask))
                                dev->if_port = media_tbl[dev->if_port].next;
                        if (vortex_debug > 1)
-                               printk(KERN_INFO "%s: first available media type: %s\n",
+                               pr_info("%s: first available media type: %s\n",
                                        dev->name, media_tbl[dev->if_port].name);
                }
        } else {
                dev->if_port = vp->default_media;
                if (vortex_debug > 1)
-                       printk(KERN_INFO "%s: using default media %s\n",
+                       pr_info("%s: using default media %s\n",
                                dev->name, media_tbl[dev->if_port].name);
        }
 
@@ -1570,13 +1568,13 @@ vortex_up(struct net_device *dev)
        vp->rx_oom_timer.function = rx_oom_timer;
 
        if (vortex_debug > 1)
-               printk(KERN_DEBUG "%s: Initial media type %s.\n",
+               pr_debug("%s: Initial media type %s.\n",
                           dev->name, media_tbl[dev->if_port].name);
 
        vp->full_duplex = vp->mii.force_media;
        config = BFINS(config, dev->if_port, 20, 4);
        if (vortex_debug > 6)
-               printk(KERN_DEBUG "vortex_up(): writing 0x%x to InternalConfig\n", config);
+               pr_debug("vortex_up(): writing 0x%x to InternalConfig\n", config);
        iowrite32(config, ioaddr + Wn3_Config);
 
        if (dev->if_port == XCVR_MII || dev->if_port == XCVR_NWAY) {
@@ -1602,7 +1600,7 @@ vortex_up(struct net_device *dev)
 
        if (vortex_debug > 1) {
                EL3WINDOW(4);
-               printk(KERN_DEBUG "%s: vortex_up() irq %d media status %4.4x.\n",
+               pr_debug("%s: vortex_up() irq %d media status %4.4x.\n",
                           dev->name, dev->irq, ioread16(ioaddr + Wn4_Media));
        }
 
@@ -1704,13 +1702,13 @@ vortex_open(struct net_device *dev)
        /* Use the now-standard shared IRQ implementation. */
        if ((retval = request_irq(dev->irq, vp->full_bus_master_rx ?
                                &boomerang_interrupt : &vortex_interrupt, IRQF_SHARED, dev->name, dev))) {
-               printk(KERN_ERR "%s: Could not reserve IRQ %d\n", dev->name, dev->irq);
+               pr_err("%s: Could not reserve IRQ %d\n", dev->name, dev->irq);
                goto err;
        }
 
        if (vp->full_bus_master_rx) { /* Boomerang bus master. */
                if (vortex_debug > 2)
-                       printk(KERN_DEBUG "%s:  Filling in the Rx ring.\n", dev->name);
+                       pr_debug("%s:  Filling in the Rx ring.\n", dev->name);
                for (i = 0; i < RX_RING_SIZE; i++) {
                        struct sk_buff *skb;
                        vp->rx_ring[i].next = cpu_to_le32(vp->rx_ring_dma + sizeof(struct boom_rx_desc) * (i+1));
@@ -1728,7 +1726,7 @@ vortex_open(struct net_device *dev)
                }
                if (i != RX_RING_SIZE) {
                        int j;
-                       printk(KERN_EMERG "%s: no memory for rx ring\n", dev->name);
+                       pr_emerg("%s: no memory for rx ring\n", dev->name);
                        for (j = 0; j < i; j++) {
                                if (vp->rx_skbuff[j]) {
                                        dev_kfree_skb(vp->rx_skbuff[j]);
@@ -1750,7 +1748,7 @@ err_free_irq:
        free_irq(dev->irq, dev);
 err:
        if (vortex_debug > 1)
-               printk(KERN_ERR "%s: vortex_open() fails: returning %d\n", dev->name, retval);
+               pr_err("%s: vortex_open() fails: returning %d\n", dev->name, retval);
 out:
        return retval;
 }
@@ -1766,9 +1764,9 @@ vortex_timer(unsigned long data)
        int media_status, old_window;
 
        if (vortex_debug > 2) {
-               printk(KERN_DEBUG "%s: Media selection timer tick happened, %s.\n",
+               pr_debug("%s: Media selection timer tick happened, %s.\n",
                           dev->name, media_tbl[dev->if_port].name);
-               printk(KERN_DEBUG "dev->watchdog_timeo=%d\n", dev->watchdog_timeo);
+               pr_debug("dev->watchdog_timeo=%d\n", dev->watchdog_timeo);
        }
 
        disable_irq_lockdep(dev->irq);
@@ -1781,12 +1779,12 @@ vortex_timer(unsigned long data)
                        netif_carrier_on(dev);
                        ok = 1;
                        if (vortex_debug > 1)
-                               printk(KERN_DEBUG "%s: Media %s has link beat, %x.\n",
+                               pr_debug("%s: Media %s has link beat, %x.\n",
                                           dev->name, media_tbl[dev->if_port].name, media_status);
                } else {
                        netif_carrier_off(dev);
                        if (vortex_debug > 1) {
-                               printk(KERN_DEBUG "%s: Media %s has no link beat, %x.\n",
+                               pr_debug("%s: Media %s has no link beat, %x.\n",
                                           dev->name, media_tbl[dev->if_port].name, media_status);
                        }
                }
@@ -1802,7 +1800,7 @@ vortex_timer(unsigned long data)
                break;
          default:                                      /* Other media types handled by Tx timeouts. */
                if (vortex_debug > 1)
-                 printk(KERN_DEBUG "%s: Media %s has no indication, %x.\n",
+                 pr_debug("%s: Media %s has no indication, %x.\n",
                                 dev->name, media_tbl[dev->if_port].name, media_status);
                ok = 1;
        }
@@ -1822,13 +1820,11 @@ vortex_timer(unsigned long data)
                if (dev->if_port == XCVR_Default) { /* Go back to default. */
                  dev->if_port = vp->default_media;
                  if (vortex_debug > 1)
-                       printk(KERN_DEBUG "%s: Media selection failing, using default "
-                                  "%s port.\n",
+                       pr_debug("%s: Media selection failing, using default %s port.\n",
                                   dev->name, media_tbl[dev->if_port].name);
                } else {
                        if (vortex_debug > 1)
-                               printk(KERN_DEBUG "%s: Media selection failed, now trying "
-                                          "%s port.\n",
+                               pr_debug("%s: Media selection failed, now trying %s port.\n",
                                           dev->name, media_tbl[dev->if_port].name);
                        next_tick = media_tbl[dev->if_port].wait;
                }
@@ -1843,13 +1839,13 @@ vortex_timer(unsigned long data)
                iowrite16(dev->if_port == XCVR_10base2 ? StartCoax : StopCoax,
                         ioaddr + EL3_CMD);
                if (vortex_debug > 1)
-                       printk(KERN_DEBUG "wrote 0x%08x to Wn3_Config\n", config);
+                       pr_debug("wrote 0x%08x to Wn3_Config\n", config);
                /* AKPM: FIXME: Should reset Rx & Tx here.  P60 of 3c90xc.pdf */
        }
 
 leave_media_alone:
        if (vortex_debug > 2)
-         printk(KERN_DEBUG "%s: Media selection timer finished, %s.\n",
+         pr_debug("%s: Media selection timer finished, %s.\n",
                         dev->name, media_tbl[dev->if_port].name);
 
        EL3WINDOW(old_window);
@@ -1865,21 +1861,21 @@ static void vortex_tx_timeout(struct net_device *dev)
        struct vortex_private *vp = netdev_priv(dev);
        void __iomem *ioaddr = vp->ioaddr;
 
-       printk(KERN_ERR "%s: transmit timed out, tx_status %2.2x status %4.4x.\n",
+       pr_err("%s: transmit timed out, tx_status %2.2x status %4.4x.\n",
                   dev->name, ioread8(ioaddr + TxStatus),
                   ioread16(ioaddr + EL3_STATUS));
        EL3WINDOW(4);
-       printk(KERN_ERR "  diagnostics: net %04x media %04x dma %08x fifo %04x\n",
+       pr_err("  diagnostics: net %04x media %04x dma %08x fifo %04x\n",
                        ioread16(ioaddr + Wn4_NetDiag),
                        ioread16(ioaddr + Wn4_Media),
                        ioread32(ioaddr + PktStatus),
                        ioread16(ioaddr + Wn4_FIFODiag));
        /* Slight code bloat to be user friendly. */
        if ((ioread8(ioaddr + TxStatus) & 0x88) == 0x88)
-               printk(KERN_ERR "%s: Transmitter encountered 16 collisions --"
+               pr_err("%s: Transmitter encountered 16 collisions --"
                           " network cable problem?\n", dev->name);
        if (ioread16(ioaddr + EL3_STATUS) & IntLatch) {
-               printk(KERN_ERR "%s: Interrupt posted but not delivered --"
+               pr_err("%s: Interrupt posted but not delivered --"
                           " IRQ blocked by another device?\n", dev->name);
                /* Bad idea here.. but we might as well handle a few events. */
                {
@@ -1903,7 +1899,7 @@ static void vortex_tx_timeout(struct net_device *dev)
 
        dev->stats.tx_errors++;
        if (vp->full_bus_master_tx) {
-               printk(KERN_DEBUG "%s: Resetting the Tx ring pointer.\n", dev->name);
+               pr_debug("%s: Resetting the Tx ring pointer.\n", dev->name);
                if (vp->cur_tx - vp->dirty_tx > 0  &&  ioread32(ioaddr + DownListPtr) == 0)
                        iowrite32(vp->tx_ring_dma + (vp->dirty_tx % TX_RING_SIZE) * sizeof(struct boom_tx_desc),
                                 ioaddr + DownListPtr);
@@ -1938,7 +1934,7 @@ vortex_error(struct net_device *dev, int status)
        unsigned char tx_status = 0;
 
        if (vortex_debug > 2) {
-               printk(KERN_ERR "%s: vortex_error(), status=0x%x\n", dev->name, status);
+               pr_err("%s: vortex_error(), status=0x%x\n", dev->name, status);
        }
 
        if (status & TxComplete) {                      /* Really "TxError" for us. */
@@ -1946,10 +1942,10 @@ vortex_error(struct net_device *dev, int status)
                /* Presumably a tx-timeout. We must merely re-enable. */
                if (vortex_debug > 2
                        || (tx_status != 0x88 && vortex_debug > 0)) {
-                       printk(KERN_ERR "%s: Transmit error, Tx status register %2.2x.\n",
+                       pr_err("%s: Transmit error, Tx status register %2.2x.\n",
                                   dev->name, tx_status);
                        if (tx_status == 0x82) {
-                               printk(KERN_ERR "Probably a duplex mismatch.  See "
+                               pr_err("Probably a duplex mismatch.  See "
                                                "Documentation/networking/vortex.txt\n");
                        }
                        dump_tx_ring(dev);
@@ -1975,13 +1971,13 @@ vortex_error(struct net_device *dev, int status)
        if (status & StatsFull) {                       /* Empty statistics. */
                static int DoneDidThat;
                if (vortex_debug > 4)
-                       printk(KERN_DEBUG "%s: Updating stats.\n", dev->name);
+                       pr_debug("%s: Updating stats.\n", dev->name);
                update_stats(ioaddr, dev);
                /* HACK: Disable statistics as an interrupt source. */
                /* This occurs when we have the wrong media type! */
                if (DoneDidThat == 0  &&
                        ioread16(ioaddr + EL3_STATUS) & StatsFull) {
-                       printk(KERN_WARNING "%s: Updating statistics failed, disabling "
+                       pr_warning("%s: Updating statistics failed, disabling "
                                   "stats as an interrupt source.\n", dev->name);
                        EL3WINDOW(5);
                        iowrite16(SetIntrEnb | (ioread16(ioaddr + 10) & ~StatsFull), ioaddr + EL3_CMD);
@@ -1998,7 +1994,7 @@ vortex_error(struct net_device *dev, int status)
                u16 fifo_diag;
                EL3WINDOW(4);
                fifo_diag = ioread16(ioaddr + Wn4_FIFODiag);
-               printk(KERN_ERR "%s: Host error, FIFO diagnostic register %4.4x.\n",
+               pr_err("%s: Host error, FIFO diagnostic register %4.4x.\n",
                           dev->name, fifo_diag);
                /* Adapter failure requires Tx/Rx reset and reinit. */
                if (vp->full_bus_master_tx) {
@@ -2006,7 +2002,7 @@ vortex_error(struct net_device *dev, int status)
                        /* 0x80000000 PCI master abort. */
                        /* 0x40000000 PCI target abort. */
                        if (vortex_debug)
-                               printk(KERN_ERR "%s: PCI bus error, bus status %8.8x\n", dev->name, bus_status);
+                               pr_err("%s: PCI bus error, bus status %8.8x\n", dev->name, bus_status);
 
                        /* In this case, blow the card away */
                        /* Must not enter D3 or we can't legally issue the reset! */
@@ -2075,7 +2071,7 @@ vortex_start_xmit(struct sk_buff *skb, struct net_device *dev)
                while (--i > 0  &&      (tx_status = ioread8(ioaddr + TxStatus)) > 0) {
                        if (tx_status & 0x3C) {         /* A Tx-disabling error occurred.  */
                                if (vortex_debug > 2)
-                                 printk(KERN_DEBUG "%s: Tx error, status %2.2x.\n",
+                                 pr_debug("%s: Tx error, status %2.2x.\n",
                                                 dev->name, tx_status);
                                if (tx_status & 0x04) dev->stats.tx_fifo_errors++;
                                if (tx_status & 0x38) dev->stats.tx_aborted_errors++;
@@ -2101,17 +2097,17 @@ boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev)
        unsigned long flags;
 
        if (vortex_debug > 6) {
-               printk(KERN_DEBUG "boomerang_start_xmit()\n");
-               printk(KERN_DEBUG "%s: Trying to send a packet, Tx index %d.\n",
+               pr_debug("boomerang_start_xmit()\n");
+               pr_debug("%s: Trying to send a packet, Tx index %d.\n",
                           dev->name, vp->cur_tx);
        }
 
        if (vp->cur_tx - vp->dirty_tx >= TX_RING_SIZE) {
                if (vortex_debug > 0)
-                       printk(KERN_WARNING "%s: BUG! Tx Ring full, refusing to send buffer.\n",
+                       pr_warning("%s: BUG! Tx Ring full, refusing to send buffer.\n",
                                   dev->name);
                netif_stop_queue(dev);
-               return 1;
+               return NETDEV_TX_BUSY;
        }
 
        vp->tx_skbuff[entry] = skb;
@@ -2204,7 +2200,7 @@ vortex_interrupt(int irq, void *dev_id)
        status = ioread16(ioaddr + EL3_STATUS);
 
        if (vortex_debug > 6)
-               printk("vortex_interrupt(). status=0x%4x\n", status);
+               pr_debug("vortex_interrupt(). status=0x%4x\n", status);
 
        if ((status & IntLatch) == 0)
                goto handler_exit;              /* No interrupt: shared IRQs cause this */
@@ -2219,19 +2215,19 @@ vortex_interrupt(int irq, void *dev_id)
                goto handler_exit;
 
        if (vortex_debug > 4)
-               printk(KERN_DEBUG "%s: interrupt, status %4.4x, latency %d ticks.\n",
+               pr_debug("%s: interrupt, status %4.4x, latency %d ticks.\n",
                           dev->name, status, ioread8(ioaddr + Timer));
 
        do {
                if (vortex_debug > 5)
-                               printk(KERN_DEBUG "%s: In interrupt loop, status %4.4x.\n",
+                               pr_debug("%s: In interrupt loop, status %4.4x.\n",
                                           dev->name, status);
                if (status & RxComplete)
                        vortex_rx(dev);
 
                if (status & TxAvailable) {
                        if (vortex_debug > 5)
-                               printk(KERN_DEBUG "     TX room bit was handled.\n");
+                               pr_debug("      TX room bit was handled.\n");
                        /* There's room in the FIFO for a full-sized packet. */
                        iowrite16(AckIntr | TxAvailable, ioaddr + EL3_CMD);
                        netif_wake_queue (dev);
@@ -2263,8 +2259,8 @@ vortex_interrupt(int irq, void *dev_id)
                }
 
                if (--work_done < 0) {
-                       printk(KERN_WARNING "%s: Too much work in interrupt, status "
-                                  "%4.4x.\n", dev->name, status);
+                       pr_warning("%s: Too much work in interrupt, status %4.4x.\n",
+                               dev->name, status);
                        /* Disable all pending interrupts. */
                        do {
                                vp->deferred |= status;
@@ -2281,7 +2277,7 @@ vortex_interrupt(int irq, void *dev_id)
        } while ((status = ioread16(ioaddr + EL3_STATUS)) & (IntLatch | RxComplete));
 
        if (vortex_debug > 4)
-               printk(KERN_DEBUG "%s: exiting interrupt, status %4.4x.\n",
+               pr_debug("%s: exiting interrupt, status %4.4x.\n",
                           dev->name, status);
 handler_exit:
        spin_unlock(&vp->lock);
@@ -2313,14 +2309,14 @@ boomerang_interrupt(int irq, void *dev_id)
        status = ioread16(ioaddr + EL3_STATUS);
 
        if (vortex_debug > 6)
-               printk(KERN_DEBUG "boomerang_interrupt. status=0x%4x\n", status);
+               pr_debug("boomerang_interrupt. status=0x%4x\n", status);
 
        if ((status & IntLatch) == 0)
                goto handler_exit;              /* No interrupt: shared IRQs can cause this */
 
        if (status == 0xffff) {         /* h/w no longer present (hotplug)? */
                if (vortex_debug > 1)
-                       printk(KERN_DEBUG "boomerang_interrupt(1): status = 0xffff\n");
+                       pr_debug("boomerang_interrupt(1): status = 0xffff\n");
                goto handler_exit;
        }
 
@@ -2330,16 +2326,16 @@ boomerang_interrupt(int irq, void *dev_id)
        }
 
        if (vortex_debug > 4)
-               printk(KERN_DEBUG "%s: interrupt, status %4.4x, latency %d ticks.\n",
+               pr_debug("%s: interrupt, status %4.4x, latency %d ticks.\n",
                           dev->name, status, ioread8(ioaddr + Timer));
        do {
                if (vortex_debug > 5)
-                               printk(KERN_DEBUG "%s: In interrupt loop, status %4.4x.\n",
+                               pr_debug("%s: In interrupt loop, status %4.4x.\n",
                                           dev->name, status);
                if (status & UpComplete) {
                        iowrite16(AckIntr | UpComplete, ioaddr + EL3_CMD);
                        if (vortex_debug > 5)
-                               printk(KERN_DEBUG "boomerang_interrupt->boomerang_rx\n");
+                               pr_debug("boomerang_interrupt->boomerang_rx\n");
                        boomerang_rx(dev);
                }
 
@@ -2374,7 +2370,7 @@ boomerang_interrupt(int irq, void *dev_id)
                                        dev_kfree_skb_irq(skb);
                                        vp->tx_skbuff[entry] = NULL;
                                } else {
-                                       printk(KERN_DEBUG "boomerang_interrupt: no skb!\n");
+                                       pr_debug("boomerang_interrupt: no skb!\n");
                                }
                                /* dev->stats.tx_packets++;  Counted below. */
                                dirty_tx++;
@@ -2382,7 +2378,7 @@ boomerang_interrupt(int irq, void *dev_id)
                        vp->dirty_tx = dirty_tx;
                        if (vp->cur_tx - dirty_tx <= TX_RING_SIZE - 1) {
                                if (vortex_debug > 6)
-                                       printk(KERN_DEBUG "boomerang_interrupt: wake queue\n");
+                                       pr_debug("boomerang_interrupt: wake queue\n");
                                netif_wake_queue (dev);
                        }
                }
@@ -2392,8 +2388,8 @@ boomerang_interrupt(int irq, void *dev_id)
                        vortex_error(dev, status);
 
                if (--work_done < 0) {
-                       printk(KERN_WARNING "%s: Too much work in interrupt, status "
-                                  "%4.4x.\n", dev->name, status);
+                       pr_warning("%s: Too much work in interrupt, status %4.4x.\n",
+                               dev->name, status);
                        /* Disable all pending interrupts. */
                        do {
                                vp->deferred |= status;
@@ -2413,7 +2409,7 @@ boomerang_interrupt(int irq, void *dev_id)
        } while ((status = ioread16(ioaddr + EL3_STATUS)) & IntLatch);
 
        if (vortex_debug > 4)
-               printk(KERN_DEBUG "%s: exiting interrupt, status %4.4x.\n",
+               pr_debug("%s: exiting interrupt, status %4.4x.\n",
                           dev->name, status);
 handler_exit:
        spin_unlock(&vp->lock);
@@ -2428,13 +2424,13 @@ static int vortex_rx(struct net_device *dev)
        short rx_status;
 
        if (vortex_debug > 5)
-               printk(KERN_DEBUG "vortex_rx(): status %4.4x, rx_status %4.4x.\n",
+               pr_debug("vortex_rx(): status %4.4x, rx_status %4.4x.\n",
                           ioread16(ioaddr+EL3_STATUS), ioread16(ioaddr+RxStatus));
        while ((rx_status = ioread16(ioaddr + RxStatus)) > 0) {
                if (rx_status & 0x4000) { /* Error, update stats. */
                        unsigned char rx_error = ioread8(ioaddr + RxErrors);
                        if (vortex_debug > 2)
-                               printk(KERN_DEBUG " Rx error: status %2.2x.\n", rx_error);
+                               pr_debug(" Rx error: status %2.2x.\n", rx_error);
                        dev->stats.rx_errors++;
                        if (rx_error & 0x01)  dev->stats.rx_over_errors++;
                        if (rx_error & 0x02)  dev->stats.rx_length_errors++;
@@ -2448,7 +2444,7 @@ static int vortex_rx(struct net_device *dev)
 
                        skb = dev_alloc_skb(pkt_len + 5);
                        if (vortex_debug > 4)
-                               printk(KERN_DEBUG "Receiving packet size %d status %4.4x.\n",
+                               pr_debug("Receiving packet size %d status %4.4x.\n",
                                           pkt_len, rx_status);
                        if (skb != NULL) {
                                skb_reserve(skb, 2);    /* Align IP on 16 byte boundaries */
@@ -2478,8 +2474,8 @@ static int vortex_rx(struct net_device *dev)
                                                break;
                                continue;
                        } else if (vortex_debug > 0)
-                               printk(KERN_NOTICE "%s: No memory to allocate a sk_buff of "
-                                          "size %d.\n", dev->name, pkt_len);
+                               pr_notice("%s: No memory to allocate a sk_buff of size %d.\n",
+                                       dev->name, pkt_len);
                        dev->stats.rx_dropped++;
                }
                issue_and_wait(dev, RxDiscard);
@@ -2498,7 +2494,7 @@ boomerang_rx(struct net_device *dev)
        int rx_work_limit = vp->dirty_rx + RX_RING_SIZE - vp->cur_rx;
 
        if (vortex_debug > 5)
-               printk(KERN_DEBUG "boomerang_rx(): status %4.4x\n", ioread16(ioaddr+EL3_STATUS));
+               pr_debug("boomerang_rx(): status %4.4x\n", ioread16(ioaddr+EL3_STATUS));
 
        while ((rx_status = le32_to_cpu(vp->rx_ring[entry].status)) & RxDComplete){
                if (--rx_work_limit < 0)
@@ -2506,7 +2502,7 @@ boomerang_rx(struct net_device *dev)
                if (rx_status & RxDError) { /* Error, update stats. */
                        unsigned char rx_error = rx_status >> 16;
                        if (vortex_debug > 2)
-                               printk(KERN_DEBUG " Rx error: status %2.2x.\n", rx_error);
+                               pr_debug(" Rx error: status %2.2x.\n", rx_error);
                        dev->stats.rx_errors++;
                        if (rx_error & 0x01)  dev->stats.rx_over_errors++;
                        if (rx_error & 0x02)  dev->stats.rx_length_errors++;
@@ -2520,7 +2516,7 @@ boomerang_rx(struct net_device *dev)
                        dma_addr_t dma = le32_to_cpu(vp->rx_ring[entry].addr);
 
                        if (vortex_debug > 4)
-                               printk(KERN_DEBUG "Receiving packet size %d status %4.4x.\n",
+                               pr_debug("Receiving packet size %d status %4.4x.\n",
                                           pkt_len, rx_status);
 
                        /* Check if the packet is long enough to just accept without
@@ -2566,7 +2562,7 @@ boomerang_rx(struct net_device *dev)
                        if (skb == NULL) {
                                static unsigned long last_jif;
                                if (time_after(jiffies, last_jif + 10 * HZ)) {
-                                       printk(KERN_WARNING "%s: memory shortage\n", dev->name);
+                                       pr_warning("%s: memory shortage\n", dev->name);
                                        last_jif = jiffies;
                                }
                                if ((vp->cur_rx - vp->dirty_rx) == RX_RING_SIZE)
@@ -2598,7 +2594,7 @@ rx_oom_timer(unsigned long arg)
        if ((vp->cur_rx - vp->dirty_rx) == RX_RING_SIZE)        /* This test is redundant, but makes me feel good */
                boomerang_rx(dev);
        if (vortex_debug > 1) {
-               printk(KERN_DEBUG "%s: rx_oom_timer %s\n", dev->name,
+               pr_debug("%s: rx_oom_timer %s\n", dev->name,
                        ((vp->cur_rx - vp->dirty_rx) != RX_RING_SIZE) ? "succeeded" : "retrying");
        }
        spin_unlock_irq(&vp->lock);
@@ -2655,9 +2651,9 @@ vortex_close(struct net_device *dev)
                vortex_down(dev, 1);
 
        if (vortex_debug > 1) {
-               printk(KERN_DEBUG"%s: vortex_close() status %4.4x, Tx status %2.2x.\n",
+               pr_debug("%s: vortex_close() status %4.4x, Tx status %2.2x.\n",
                           dev->name, ioread16(ioaddr + EL3_STATUS), ioread8(ioaddr + TxStatus));
-               printk(KERN_DEBUG "%s: vortex close stats: rx_nocopy %d rx_copy %d"
+               pr_debug("%s: vortex close stats: rx_nocopy %d rx_copy %d"
                           " tx_queued %d Rx pre-checksummed %d.\n",
                           dev->name, vp->rx_nocopy, vp->rx_copy, vp->queued_packet, vp->rx_csumhits);
        }
@@ -2666,8 +2662,7 @@ vortex_close(struct net_device *dev)
        if (vp->rx_csumhits &&
            (vp->drv_flags & HAS_HWCKSM) == 0 &&
            (vp->card_idx >= MAX_UNITS || hw_checksums[vp->card_idx] == -1)) {
-                       printk(KERN_WARNING "%s supports hardware checksums, and we're "
-                                               "not using them!\n", dev->name);
+               pr_warning("%s supports hardware checksums, and we're not using them!\n", dev->name);
        }
 #endif
 
@@ -2717,16 +2712,16 @@ dump_tx_ring(struct net_device *dev)
                        int i;
                        int stalled = ioread32(ioaddr + PktStatus) & 0x04;      /* Possible racy. But it's only debug stuff */
 
-                       printk(KERN_ERR "  Flags; bus-master %d, dirty %d(%d) current %d(%d)\n",
+                       pr_err("  Flags; bus-master %d, dirty %d(%d) current %d(%d)\n",
                                        vp->full_bus_master_tx,
                                        vp->dirty_tx, vp->dirty_tx % TX_RING_SIZE,
                                        vp->cur_tx, vp->cur_tx % TX_RING_SIZE);
-                       printk(KERN_ERR "  Transmit list %8.8x vs. %p.\n",
+                       pr_err("  Transmit list %8.8x vs. %p.\n",
                                   ioread32(ioaddr + DownListPtr),
                                   &vp->tx_ring[vp->dirty_tx % TX_RING_SIZE]);
                        issue_and_wait(dev, DownStall);
                        for (i = 0; i < TX_RING_SIZE; i++) {
-                               printk(KERN_ERR "  %d: @%p  length %8.8x status %8.8x\n", i,
+                               pr_err("  %d: @%p  length %8.8x status %8.8x\n", i,
                                           &vp->tx_ring[i],
 #if DO_ZEROCOPY
                                           le32_to_cpu(vp->tx_ring[i].frag[0].length),
@@ -2970,7 +2965,7 @@ static void set_rx_mode(struct net_device *dev)
 
        if (dev->flags & IFF_PROMISC) {
                if (vortex_debug > 3)
-                       printk(KERN_NOTICE "%s: Setting promiscuous mode.\n", dev->name);
+                       pr_notice("%s: Setting promiscuous mode.\n", dev->name);
                new_mode = SetRxFilter|RxStation|RxMulticast|RxBroadcast|RxProm;
        } else  if ((dev->mc_list)  ||  (dev->flags & IFF_ALLMULTI)) {
                new_mode = SetRxFilter|RxStation|RxMulticast|RxBroadcast;
@@ -3145,8 +3140,7 @@ static void acpi_set_WOL(struct net_device *dev)
                iowrite16(RxEnable, ioaddr + EL3_CMD);
 
                if (pci_enable_wake(VORTEX_PCI(vp), PCI_D3hot, 1)) {
-                       printk(KERN_INFO "%s: WOL not supported.\n",
-                                       pci_name(VORTEX_PCI(vp)));
+                       pr_info("%s: WOL not supported.\n", pci_name(VORTEX_PCI(vp)));
 
                        vp->enable_wol = 0;
                        return;
@@ -3164,7 +3158,7 @@ static void __devexit vortex_remove_one(struct pci_dev *pdev)
        struct vortex_private *vp;
 
        if (!dev) {
-               printk("vortex_remove_one called for Compaq device!\n");
+               pr_err("vortex_remove_one called for Compaq device!\n");
                BUG();
        }
 
index 7a331acc34add0b755b92c1c4379f4292c5b14e8..69f5b7d298a60b722dfe0b773713aca508d110d4 100644 (file)
@@ -541,7 +541,7 @@ int lance_start_xmit (struct sk_buff *skb, struct net_device *dev)
        unsigned long flags;
 
         if (!TX_BUFFS_AVAIL)
-                return -1;
+                return NETDEV_TX_LOCKED;
 
        netif_stop_queue (dev);
 
index 02330f3d5a55d35e1201e22aefc3b8e491f65f9f..50efde11ea6c8790e8f0e679d9faaeb15e40f6f6 100644 (file)
@@ -471,8 +471,7 @@ static void cp_rx_err_acct (struct cp_private *cp, unsigned rx_tail,
                            u32 status, u32 len)
 {
        if (netif_msg_rx_err (cp))
-               printk (KERN_DEBUG
-                       "%s: rx err, slot %d status 0x%x len %d\n",
+               pr_debug("%s: rx err, slot %d status 0x%x len %d\n",
                        cp->dev->name, rx_tail, status, len);
        cp->dev->stats.rx_errors++;
        if (status & RxErrFrame)
@@ -547,7 +546,7 @@ rx_status_loop:
                }
 
                if (netif_msg_rx_status(cp))
-                       printk(KERN_DEBUG "%s: rx slot %d status 0x%x len %d\n",
+                       pr_debug("%s: rx slot %d status 0x%x len %d\n",
                               dev->name, rx_tail, status, len);
 
                buflen = cp->rx_buf_sz + NET_IP_ALIGN;
@@ -626,7 +625,7 @@ static irqreturn_t cp_interrupt (int irq, void *dev_instance)
                return IRQ_NONE;
 
        if (netif_msg_intr(cp))
-               printk(KERN_DEBUG "%s: intr, status %04x cmd %02x cpcmd %04x\n",
+               pr_debug("%s: intr, status %04x cmd %02x cpcmd %04x\n",
                        dev->name, status, cpr8(Cmd), cpr16(CpCmd));
 
        cpw16(IntrStatus, status & ~cp_rx_intr_mask);
@@ -658,7 +657,7 @@ static irqreturn_t cp_interrupt (int irq, void *dev_instance)
 
                pci_read_config_word(cp->pdev, PCI_STATUS, &pci_status);
                pci_write_config_word(cp->pdev, PCI_STATUS, pci_status);
-               printk(KERN_ERR "%s: PCI bus error, status=%04x, PCI status=%04x\n",
+               pr_err("%s: PCI bus error, status=%04x, PCI status=%04x\n",
                       dev->name, status, pci_status);
 
                /* TODO: reset hardware */
@@ -705,7 +704,7 @@ static void cp_tx (struct cp_private *cp)
                if (status & LastFrag) {
                        if (status & (TxError | TxFIFOUnder)) {
                                if (netif_msg_tx_err(cp))
-                                       printk(KERN_DEBUG "%s: tx err, status 0x%x\n",
+                                       pr_debug("%s: tx err, status 0x%x\n",
                                               cp->dev->name, status);
                                cp->dev->stats.tx_errors++;
                                if (status & TxOWC)
@@ -722,7 +721,7 @@ static void cp_tx (struct cp_private *cp)
                                cp->dev->stats.tx_packets++;
                                cp->dev->stats.tx_bytes += skb->len;
                                if (netif_msg_tx_done(cp))
-                                       printk(KERN_DEBUG "%s: tx done, slot %d\n", cp->dev->name, tx_tail);
+                                       pr_debug("%s: tx done, slot %d\n", cp->dev->name, tx_tail);
                        }
                        dev_kfree_skb_irq(skb);
                }
@@ -755,9 +754,9 @@ static int cp_start_xmit (struct sk_buff *skb, struct net_device *dev)
        if (TX_BUFFS_AVAIL(cp) <= (skb_shinfo(skb)->nr_frags + 1)) {
                netif_stop_queue(dev);
                spin_unlock_irqrestore(&cp->lock, intr_flags);
-               printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n",
+               pr_err(PFX "%s: BUG! Tx Ring full when queue awake!\n",
                       dev->name);
-               return 1;
+               return NETDEV_TX_BUSY;
        }
 
 #if CP_VLAN_TAG_USED
@@ -882,7 +881,7 @@ static int cp_start_xmit (struct sk_buff *skb, struct net_device *dev)
        }
        cp->tx_head = entry;
        if (netif_msg_tx_queued(cp))
-               printk(KERN_DEBUG "%s: tx queued, slot %d, skblen %d\n",
+               pr_debug("%s: tx queued, slot %d, skblen %d\n",
                       dev->name, entry, skb->len);
        if (TX_BUFFS_AVAIL(cp) <= (MAX_SKB_FRAGS + 1))
                netif_stop_queue(dev);
@@ -996,7 +995,7 @@ static void cp_reset_hw (struct cp_private *cp)
                schedule_timeout_uninterruptible(10);
        }
 
-       printk(KERN_ERR "%s: hardware reset timeout\n", cp->dev->name);
+       pr_err("%s: hardware reset timeout\n", cp->dev->name);
 }
 
 static inline void cp_start_hw (struct cp_private *cp)
@@ -1166,7 +1165,7 @@ static int cp_open (struct net_device *dev)
        int rc;
 
        if (netif_msg_ifup(cp))
-               printk(KERN_DEBUG "%s: enabling interface\n", dev->name);
+               pr_debug("%s: enabling interface\n", dev->name);
 
        rc = cp_alloc_rings(cp);
        if (rc)
@@ -1201,7 +1200,7 @@ static int cp_close (struct net_device *dev)
        napi_disable(&cp->napi);
 
        if (netif_msg_ifdown(cp))
-               printk(KERN_DEBUG "%s: disabling interface\n", dev->name);
+               pr_debug("%s: disabling interface\n", dev->name);
 
        spin_lock_irqsave(&cp->lock, flags);
 
@@ -1224,7 +1223,7 @@ static void cp_tx_timeout(struct net_device *dev)
        unsigned long flags;
        int rc;
 
-       printk(KERN_WARNING "%s: Transmit timeout, status %2x %4x %4x %4x\n",
+       pr_warning("%s: Transmit timeout, status %2x %4x %4x %4x\n",
               dev->name, cpr8(Cmd), cpr16(CpCmd),
               cpr16(IntrStatus), cpr16(IntrMask));
 
@@ -1873,7 +1872,7 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
 #ifndef MODULE
        static int version_printed;
        if (version_printed++ == 0)
-               printk("%s", version);
+               pr_info("%s", version);
 #endif
 
        if (pdev->vendor == PCI_VENDOR_ID_REALTEK &&
@@ -1995,8 +1994,7 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
        if (rc)
                goto err_out_iomap;
 
-       printk (KERN_INFO "%s: RTL-8139C+ at 0x%lx, "
-               "%pM, IRQ %d\n",
+       pr_info("%s: RTL-8139C+ at 0x%lx, %pM, IRQ %d\n",
                dev->name,
                dev->base_addr,
                dev->dev_addr,
@@ -2113,7 +2111,7 @@ static struct pci_driver cp_driver = {
 static int __init cp_init (void)
 {
 #ifdef MODULE
-       printk("%s", version);
+       pr_info("%s", version);
 #endif
        return pci_register_driver(&cp_driver);
 }
index 1fc45431a6209c6ace608cff2ed87174fea4bd55..8ae72ec14456d4dc2e31141777a1bf35776fc78a 100644 (file)
 #undef RTL8139_NDEBUG
 
 
-#if RTL8139_DEBUG
-/* note: prints function name for you */
-#  define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __func__ , ## args)
-#else
-#  define DPRINTK(fmt, args...)
-#endif
-
 #ifdef RTL8139_NDEBUG
 #  define assert(expr) do {} while (0)
 #else
 #  define assert(expr) \
         if(unlikely(!(expr))) {                                        \
-        printk(KERN_ERR "Assertion failed! %s,%s,%s,line=%d\n",        \
+        pr_err("Assertion failed! %s,%s,%s,line=%d\n", \
        #expr, __FILE__, __func__, __LINE__);                   \
         }
 #endif
@@ -784,8 +777,8 @@ static __devinit struct net_device * rtl8139_init_board (struct pci_dev *pdev)
 
        /* set this immediately, we need to know before
         * we talk to the chip directly */
-       DPRINTK("PIO region size == 0x%02X\n", pio_len);
-       DPRINTK("MMIO region size == 0x%02lX\n", mmio_len);
+       pr_debug("PIO region size == 0x%02lX\n", pio_len);
+       pr_debug("MMIO region size == 0x%02lX\n", mmio_len);
 
 retry:
        if (use_io) {
@@ -865,19 +858,17 @@ retry:
                }
 
        /* 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 = 0x%lx\n", RTL_R32 (TxConfig));
+       dev_dbg(&pdev->dev, "unknown chip version, assuming RTL-8139\n");
+       dev_dbg(&pdev->dev, "TxConfig = 0x%lx\n", RTL_R32 (TxConfig));
        tp->chipset = 0;
 
 match:
-       DPRINTK ("chipset id (%d) == index %d, '%s'\n",
+       pr_debug("chipset id (%d) == index %d, '%s'\n",
                 version, i, rtl_chip_info[i].name);
 
        if (tp->chipset >= CH_8139B) {
                u8 new_tmp8 = tmp8 = RTL_R8 (Config1);
-               DPRINTK("PCI PM wakeup\n");
+               pr_debug("PCI PM wakeup\n");
                if ((rtl_chip_info[tp->chipset].flags & HasLWake) &&
                    (tmp8 & LWAKE))
                        new_tmp8 &= ~LWAKE;
@@ -896,7 +887,7 @@ match:
                        }
                }
        } else {
-               DPRINTK("Old chip wakeup\n");
+               pr_debug("Old chip wakeup\n");
                tmp8 = RTL_R8 (Config1);
                tmp8 &= ~(SLEEP | PWRDN);
                RTL_W8 (Config1, tmp8);
@@ -949,7 +940,7 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev,
        {
                static int printed_version;
                if (!printed_version++)
-                       printk (KERN_INFO RTL8139_DRIVER_NAME "\n");
+                       pr_info(RTL8139_DRIVER_NAME "\n");
        }
 #endif
 
@@ -965,7 +956,7 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev,
            pdev->device == PCI_DEVICE_ID_REALTEK_8139 &&
            pdev->subsystem_vendor == PCI_VENDOR_ID_ATHEROS &&
            pdev->subsystem_device == PCI_DEVICE_ID_REALTEK_8139) {
-               printk(KERN_INFO "8139too: OQO Model 2 detected. Forcing PIO\n");
+               pr_info("8139too: OQO Model 2 detected. Forcing PIO\n");
                use_io = 1;
        }
 
@@ -1018,21 +1009,20 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev,
        tp->mii.reg_num_mask = 0x1f;
 
        /* dev is fully set up and ready to use now */
-       DPRINTK("about to register device named %s (%p)...\n", dev->name, dev);
+       pr_debug("about to register device named %s (%p)...\n", dev->name, dev);
        i = register_netdev (dev);
        if (i) goto err_out;
 
        pci_set_drvdata (pdev, dev);
 
-       printk (KERN_INFO "%s: %s at 0x%lx, "
-               "%pM, IRQ %d\n",
+       pr_info("%s: %s at 0x%lx, %pM, IRQ %d\n",
                dev->name,
                board_info[ent->driver_data].name,
                dev->base_addr,
                dev->dev_addr,
                dev->irq);
 
-       printk (KERN_DEBUG "%s:  Identified 8139 chip type '%s'\n",
+       pr_debug("%s:  Identified 8139 chip type '%s'\n",
                dev->name, rtl_chip_info[tp->chipset].name);
 
        /* Find the connected MII xcvrs.
@@ -1046,14 +1036,12 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev,
                        if (mii_status != 0xffff  &&  mii_status != 0x0000) {
                                u16 advertising = mdio_read(dev, phy, 4);
                                tp->phys[phy_idx++] = phy;
-                               printk(KERN_INFO "%s: MII transceiver %d status 0x%4.4x "
-                                          "advertising %4.4x.\n",
+                               pr_info("%s: MII transceiver %d status 0x%4.4x advertising %4.4x.\n",
                                           dev->name, phy, mii_status, advertising);
                        }
                }
                if (phy_idx == 0) {
-                       printk(KERN_INFO "%s: No MII transceivers found!  Assuming SYM "
-                                  "transceiver.\n",
+                       pr_info("%s: No MII transceivers found! Assuming SYM transceiver.\n",
                                   dev->name);
                        tp->phys[0] = 32;
                }
@@ -1073,13 +1061,13 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev,
        if (board_idx < MAX_UNITS  &&  full_duplex[board_idx] > 0)
                tp->mii.full_duplex = full_duplex[board_idx];
        if (tp->mii.full_duplex) {
-               printk(KERN_INFO "%s: Media type forced to Full Duplex.\n", dev->name);
+               pr_info("%s: Media type forced to Full Duplex.\n", dev->name);
                /* Changing the MII-advertised media because might prevent
                   re-connection. */
                tp->mii.force_media = 1;
        }
        if (tp->default_port) {
-               printk(KERN_INFO "  Forcing %dMbps %s-duplex operation.\n",
+               pr_info("  Forcing %dMbps %s-duplex operation.\n",
                           (option & 0x20 ? 100 : 10),
                           (option & 0x10 ? "full" : "half"));
                mdio_write(dev, tp->phys[0], 0,
@@ -1342,7 +1330,7 @@ static int rtl8139_open (struct net_device *dev)
        netif_start_queue (dev);
 
        if (netif_msg_ifup(tp))
-               printk(KERN_DEBUG "%s: rtl8139_open() ioaddr %#llx IRQ %d"
+               pr_debug("%s: rtl8139_open() ioaddr %#llx IRQ %d"
                        " GP Pins %2.2x %s-duplex.\n", dev->name,
                        (unsigned long long)pci_resource_start (tp->pci_dev, 1),
                        dev->irq, RTL_R8 (MediaStatus),
@@ -1404,7 +1392,7 @@ static void rtl8139_hw_start (struct net_device *dev)
                RTL_W8 (Config3, RTL_R8 (Config3) & ~Cfg3_Magic);
        }
 
-       DPRINTK("init buffer addresses\n");
+       pr_debug("init buffer addresses\n");
 
        /* Lock Config[01234] and BMCR register writes */
        RTL_W8 (Cfg9346, Cfg9346_Lock);
@@ -1566,14 +1554,13 @@ static inline void rtl8139_thread_iter (struct net_device *dev,
                        tp->mii.full_duplex = duplex;
 
                        if (mii_lpa) {
-                               printk (KERN_INFO
-                                       "%s: Setting %s-duplex based on MII #%d link"
+                               pr_info("%s: Setting %s-duplex based on MII #%d link"
                                        " partner ability of %4.4x.\n",
                                        dev->name,
                                        tp->mii.full_duplex ? "full" : "half",
                                        tp->phys[0], mii_lpa);
                        } else {
-                               printk(KERN_INFO"%s: media is unconnected, link down, or incompatible connection\n",
+                               pr_info("%s: media is unconnected, link down, or incompatible connection\n",
                                       dev->name);
                        }
 #if 0
@@ -1588,11 +1575,11 @@ static inline void rtl8139_thread_iter (struct net_device *dev,
 
        rtl8139_tune_twister (dev, tp);
 
-       DPRINTK ("%s: Media selection tick, Link partner %4.4x.\n",
+       pr_debug("%s: Media selection tick, Link partner %4.4x.\n",
                 dev->name, RTL_R16 (NWayLPAR));
-       DPRINTK ("%s:  Other registers are IntMask %4.4x IntStatus %4.4x\n",
+       pr_debug("%s:  Other registers are IntMask %4.4x IntStatus %4.4x\n",
                 dev->name, RTL_R16 (IntrMask), RTL_R16 (IntrStatus));
-       DPRINTK ("%s:  Chip config %2.2x %2.2x.\n",
+       pr_debug("%s:  Chip config %2.2x %2.2x.\n",
                 dev->name, RTL_R8 (Config0),
                 RTL_R8 (Config1));
 }
@@ -1652,14 +1639,14 @@ static void rtl8139_tx_timeout_task (struct work_struct *work)
        int i;
        u8 tmp8;
 
-       printk (KERN_DEBUG "%s: Transmit timeout, status %2.2x %4.4x %4.4x "
-               "media %2.2x.\n", dev->name, RTL_R8 (ChipCmd),
+       pr_debug("%s: Transmit timeout, status %2.2x %4.4x %4.4x media %2.2x.\n",
+               dev->name, RTL_R8 (ChipCmd),
                RTL_R16(IntrStatus), RTL_R16(IntrMask), RTL_R8(MediaStatus));
        /* Emit info to figure out what went wrong. */
-       printk (KERN_DEBUG "%s: Tx queue start entry %ld  dirty entry %ld.\n",
+       pr_debug("%s: Tx queue start entry %ld  dirty entry %ld.\n",
                dev->name, tp->cur_tx, tp->dirty_tx);
        for (i = 0; i < NUM_TX_DESC; i++)
-               printk (KERN_DEBUG "%s:  Tx descriptor %d is %8.8lx.%s\n",
+               pr_debug("%s:  Tx descriptor %d is %8.8lx.%s\n",
                        dev->name, i, RTL_R32 (TxStatus0 + (i * 4)),
                        i == tp->dirty_tx % NUM_TX_DESC ?
                                " (queue head)" : "");
@@ -1741,7 +1728,7 @@ static int rtl8139_start_xmit (struct sk_buff *skb, struct net_device *dev)
        spin_unlock_irqrestore(&tp->lock, flags);
 
        if (netif_msg_tx_queued(tp))
-               printk (KERN_DEBUG "%s: Queued Tx packet size %u to slot %d.\n",
+               pr_debug("%s: Queued Tx packet size %u to slot %d.\n",
                        dev->name, len, entry);
 
        return 0;
@@ -1772,7 +1759,7 @@ static void rtl8139_tx_interrupt (struct net_device *dev,
                if (txstatus & (TxOutOfWindow | TxAborted)) {
                        /* There was an major error, log it. */
                        if (netif_msg_tx_err(tp))
-                               printk(KERN_DEBUG "%s: Transmit error, Tx status %8.8x.\n",
+                               pr_debug("%s: Transmit error, Tx status %8.8x.\n",
                                        dev->name, txstatus);
                        dev->stats.tx_errors++;
                        if (txstatus & TxAborted) {
@@ -1803,7 +1790,7 @@ static void rtl8139_tx_interrupt (struct net_device *dev,
 
 #ifndef RTL8139_NDEBUG
        if (tp->cur_tx - dirty_tx > NUM_TX_DESC) {
-               printk (KERN_ERR "%s: Out-of-sync dirty pointer, %ld vs. %ld.\n",
+               pr_err("%s: Out-of-sync dirty pointer, %ld vs. %ld.\n",
                        dev->name, dirty_tx, tp->cur_tx);
                dirty_tx += NUM_TX_DESC;
        }
@@ -1828,12 +1815,12 @@ static void rtl8139_rx_err (u32 rx_status, struct net_device *dev,
 #endif
 
        if (netif_msg_rx_err (tp))
-               printk(KERN_DEBUG "%s: Ethernet frame had errors, status %8.8x.\n",
+               pr_debug("%s: Ethernet frame had errors, status %8.8x.\n",
                        dev->name, rx_status);
        dev->stats.rx_errors++;
        if (!(rx_status & RxStatusOK)) {
                if (rx_status & RxTooLong) {
-                       DPRINTK ("%s: Oversized Ethernet frame, status %4.4x!\n",
+                       pr_debug("%s: Oversized Ethernet frame, status %4.4x!\n",
                                dev->name, rx_status);
                        /* A.C.: The chip hangs here. */
                }
@@ -1866,7 +1853,7 @@ static void rtl8139_rx_err (u32 rx_status, struct net_device *dev,
                        break;
        }
        if (tmp_work <= 0)
-               printk (KERN_WARNING PFX "rx stop wait too long\n");
+               pr_warning(PFX "rx stop wait too long\n");
        /* restart receive */
        tmp_work = 200;
        while (--tmp_work > 0) {
@@ -1877,7 +1864,7 @@ static void rtl8139_rx_err (u32 rx_status, struct net_device *dev,
                        break;
        }
        if (tmp_work <= 0)
-               printk (KERN_WARNING PFX "tx/rx enable wait too long\n");
+               pr_warning(PFX "tx/rx enable wait too long\n");
 
        /* and reinitialize all rx related registers */
        RTL_W8_F (Cfg9346, Cfg9346_Unlock);
@@ -1888,7 +1875,7 @@ static void rtl8139_rx_err (u32 rx_status, struct net_device *dev,
        RTL_W32 (RxConfig, tp->rx_config);
        tp->cur_rx = 0;
 
-       DPRINTK("init buffer addresses\n");
+       pr_debug("init buffer addresses\n");
 
        /* Lock Config[01234] and BMCR register writes */
        RTL_W8 (Cfg9346, Cfg9346_Lock);
@@ -1942,7 +1929,7 @@ static int rtl8139_rx(struct net_device *dev, struct rtl8139_private *tp,
        unsigned int cur_rx = tp->cur_rx;
        unsigned int rx_size = 0;
 
-       DPRINTK ("%s: In rtl8139_rx(), current %4.4x BufAddr %4.4x,"
+       pr_debug("%s: In rtl8139_rx(), current %4.4x BufAddr %4.4x,"
                 " free to %4.4x, Cmd %2.2x.\n", dev->name, (u16)cur_rx,
                 RTL_R16 (RxBufAddr),
                 RTL_R16 (RxBufPtr), RTL_R8 (ChipCmd));
@@ -1962,17 +1949,17 @@ static int rtl8139_rx(struct net_device *dev, struct rtl8139_private *tp,
                pkt_size = rx_size - 4;
 
                if (netif_msg_rx_status(tp))
-                       printk(KERN_DEBUG "%s:  rtl8139_rx() status %4.4x, size %4.4x,"
+                       pr_debug("%s:  rtl8139_rx() status %4.4x, size %4.4x,"
                                " cur %4.4x.\n", dev->name, rx_status,
                         rx_size, cur_rx);
 #if RTL8139_DEBUG > 2
                {
                        int i;
-                       DPRINTK ("%s: Frame contents ", dev->name);
+                       pr_debug("%s: Frame contents ", dev->name);
                        for (i = 0; i < 70; i++)
-                               printk (" %2.2x",
+                               pr_cont(" %2.2x",
                                        rx_ring[ring_offset + i]);
-                       printk (".\n");
+                       pr_cont(".\n");
                }
 #endif
 
@@ -1984,12 +1971,12 @@ static int rtl8139_rx(struct net_device *dev, struct rtl8139_private *tp,
                        if (!tp->fifo_copy_timeout)
                                tp->fifo_copy_timeout = jiffies + 2;
                        else if (time_after(jiffies, tp->fifo_copy_timeout)) {
-                               DPRINTK ("%s: hung FIFO. Reset.", dev->name);
+                               pr_debug("%s: hung FIFO. Reset.", dev->name);
                                rx_size = 0;
                                goto no_early_rx;
                        }
                        if (netif_msg_intr(tp)) {
-                               printk(KERN_DEBUG "%s: fifo copy in progress.",
+                               pr_debug("%s: fifo copy in progress.",
                                       dev->name);
                        }
                        tp->xstats.early_rx++;
@@ -2033,8 +2020,7 @@ no_early_rx:
                        netif_receive_skb (skb);
                } else {
                        if (net_ratelimit())
-                               printk (KERN_WARNING
-                                       "%s: Memory squeeze, dropping packet.\n",
+                               pr_warning("%s: Memory squeeze, dropping packet.\n",
                                        dev->name);
                        dev->stats.rx_dropped++;
                }
@@ -2049,12 +2035,10 @@ no_early_rx:
        if (unlikely(!received || rx_size == 0xfff0))
                rtl8139_isr_ack(tp);
 
-#if RTL8139_DEBUG > 1
-       DPRINTK ("%s: Done rtl8139_rx(), current %4.4x BufAddr %4.4x,"
+       pr_debug("%s: Done rtl8139_rx(), current %4.4x BufAddr %4.4x,"
                 " free to %4.4x, Cmd %2.2x.\n", dev->name, cur_rx,
                 RTL_R16 (RxBufAddr),
                 RTL_R16 (RxBufPtr), RTL_R8 (ChipCmd));
-#endif
 
        tp->cur_rx = cur_rx;
 
@@ -2075,7 +2059,7 @@ static void rtl8139_weird_interrupt (struct net_device *dev,
                                     void __iomem *ioaddr,
                                     int status, int link_changed)
 {
-       DPRINTK ("%s: Abnormal interrupt, status %8.8x.\n",
+       pr_debug("%s: Abnormal interrupt, status %8.8x.\n",
                 dev->name, status);
 
        assert (dev != NULL);
@@ -2104,7 +2088,7 @@ static void rtl8139_weird_interrupt (struct net_device *dev,
                pci_read_config_word (tp->pci_dev, PCI_STATUS, &pci_cmd_status);
                pci_write_config_word (tp->pci_dev, PCI_STATUS, pci_cmd_status);
 
-               printk (KERN_ERR "%s: PCI Bus error %4.4x.\n",
+               pr_err("%s: PCI Bus error %4.4x.\n",
                        dev->name, pci_cmd_status);
        }
 }
@@ -2198,7 +2182,7 @@ static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance)
  out:
        spin_unlock (&tp->lock);
 
-       DPRINTK ("%s: exiting interrupt, intr_status=%#4.4x.\n",
+       pr_debug("%s: exiting interrupt, intr_status=%#4.4x.\n",
                 dev->name, RTL_R16 (IntrStatus));
        return IRQ_RETVAL(handled);
 }
@@ -2249,7 +2233,7 @@ static int rtl8139_close (struct net_device *dev)
        napi_disable(&tp->napi);
 
        if (netif_msg_ifdown(tp))
-               printk(KERN_DEBUG "%s: Shutting down ethercard, status was 0x%4.4x.\n",
+               pr_debug("%s: Shutting down ethercard, status was 0x%4.4x.\n",
                        dev->name, RTL_R16 (IntrStatus));
 
        spin_lock_irqsave (&tp->lock, flags);
@@ -2292,11 +2276,11 @@ static int rtl8139_close (struct net_device *dev)
    other threads or interrupts aren't messing with the 8139.  */
 static void rtl8139_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
 {
-       struct rtl8139_private *np = netdev_priv(dev);
-       void __iomem *ioaddr = np->mmio_addr;
+       struct rtl8139_private *tp = netdev_priv(dev);
+       void __iomem *ioaddr = tp->mmio_addr;
 
-       spin_lock_irq(&np->lock);
-       if (rtl_chip_info[np->chipset].flags & HasLWake) {
+       spin_lock_irq(&tp->lock);
+       if (rtl_chip_info[tp->chipset].flags & HasLWake) {
                u8 cfg3 = RTL_R8 (Config3);
                u8 cfg5 = RTL_R8 (Config5);
 
@@ -2317,7 +2301,7 @@ static void rtl8139_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
                if (cfg5 & Cfg5_BWF)
                        wol->wolopts |= WAKE_BCAST;
        }
-       spin_unlock_irq(&np->lock);
+       spin_unlock_irq(&tp->lock);
 }
 
 
@@ -2326,19 +2310,19 @@ static void rtl8139_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
    aren't messing with the 8139.  */
 static int rtl8139_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
 {
-       struct rtl8139_private *np = netdev_priv(dev);
-       void __iomem *ioaddr = np->mmio_addr;
+       struct rtl8139_private *tp = netdev_priv(dev);
+       void __iomem *ioaddr = tp->mmio_addr;
        u32 support;
        u8 cfg3, cfg5;
 
-       support = ((rtl_chip_info[np->chipset].flags & HasLWake)
+       support = ((rtl_chip_info[tp->chipset].flags & HasLWake)
                   ? (WAKE_PHY | WAKE_MAGIC
                      | WAKE_UCAST | WAKE_MCAST | WAKE_BCAST)
                   : 0);
        if (wol->wolopts & ~support)
                return -EINVAL;
 
-       spin_lock_irq(&np->lock);
+       spin_lock_irq(&tp->lock);
        cfg3 = RTL_R8 (Config3) & ~(Cfg3_LinkUp | Cfg3_Magic);
        if (wol->wolopts & WAKE_PHY)
                cfg3 |= Cfg3_LinkUp;
@@ -2359,87 +2343,87 @@ static int rtl8139_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
        if (wol->wolopts & WAKE_BCAST)
                cfg5 |= Cfg5_BWF;
        RTL_W8 (Config5, cfg5); /* need not unlock via Cfg9346 */
-       spin_unlock_irq(&np->lock);
+       spin_unlock_irq(&tp->lock);
 
        return 0;
 }
 
 static void rtl8139_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
 {
-       struct rtl8139_private *np = netdev_priv(dev);
+       struct rtl8139_private *tp = netdev_priv(dev);
        strcpy(info->driver, DRV_NAME);
        strcpy(info->version, DRV_VERSION);
-       strcpy(info->bus_info, pci_name(np->pci_dev));
-       info->regdump_len = np->regs_len;
+       strcpy(info->bus_info, pci_name(tp->pci_dev));
+       info->regdump_len = tp->regs_len;
 }
 
 static int rtl8139_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
-       struct rtl8139_private *np = netdev_priv(dev);
-       spin_lock_irq(&np->lock);
-       mii_ethtool_gset(&np->mii, cmd);
-       spin_unlock_irq(&np->lock);
+       struct rtl8139_private *tp = netdev_priv(dev);
+       spin_lock_irq(&tp->lock);
+       mii_ethtool_gset(&tp->mii, cmd);
+       spin_unlock_irq(&tp->lock);
        return 0;
 }
 
 static int rtl8139_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
-       struct rtl8139_private *np = netdev_priv(dev);
+       struct rtl8139_private *tp = netdev_priv(dev);
        int rc;
-       spin_lock_irq(&np->lock);
-       rc = mii_ethtool_sset(&np->mii, cmd);
-       spin_unlock_irq(&np->lock);
+       spin_lock_irq(&tp->lock);
+       rc = mii_ethtool_sset(&tp->mii, cmd);
+       spin_unlock_irq(&tp->lock);
        return rc;
 }
 
 static int rtl8139_nway_reset(struct net_device *dev)
 {
-       struct rtl8139_private *np = netdev_priv(dev);
-       return mii_nway_restart(&np->mii);
+       struct rtl8139_private *tp = netdev_priv(dev);
+       return mii_nway_restart(&tp->mii);
 }
 
 static u32 rtl8139_get_link(struct net_device *dev)
 {
-       struct rtl8139_private *np = netdev_priv(dev);
-       return mii_link_ok(&np->mii);
+       struct rtl8139_private *tp = netdev_priv(dev);
+       return mii_link_ok(&tp->mii);
 }
 
 static u32 rtl8139_get_msglevel(struct net_device *dev)
 {
-       struct rtl8139_private *np = netdev_priv(dev);
-       return np->msg_enable;
+       struct rtl8139_private *tp = netdev_priv(dev);
+       return tp->msg_enable;
 }
 
 static void rtl8139_set_msglevel(struct net_device *dev, u32 datum)
 {
-       struct rtl8139_private *np = netdev_priv(dev);
-       np->msg_enable = datum;
+       struct rtl8139_private *tp = netdev_priv(dev);
+       tp->msg_enable = datum;
 }
 
 static int rtl8139_get_regs_len(struct net_device *dev)
 {
-       struct rtl8139_private *np;
+       struct rtl8139_private *tp;
        /* TODO: we are too slack to do reg dumping for pio, for now */
        if (use_io)
                return 0;
-       np = netdev_priv(dev);
-       return np->regs_len;
+       tp = netdev_priv(dev);
+       return tp->regs_len;
 }
 
 static void rtl8139_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *regbuf)
 {
-       struct rtl8139_private *np;
+       struct rtl8139_private *tp;
 
        /* TODO: we are too slack to do reg dumping for pio, for now */
        if (use_io)
                return;
-       np = netdev_priv(dev);
+       tp = netdev_priv(dev);
 
        regs->version = RTL_REGS_VER;
 
-       spin_lock_irq(&np->lock);
-       memcpy_fromio(regbuf, np->mmio_addr, regs->len);
-       spin_unlock_irq(&np->lock);
+       spin_lock_irq(&tp->lock);
+       memcpy_fromio(regbuf, tp->mmio_addr, regs->len);
+       spin_unlock_irq(&tp->lock);
 }
 
 static int rtl8139_get_sset_count(struct net_device *dev, int sset)
@@ -2454,12 +2438,12 @@ static int rtl8139_get_sset_count(struct net_device *dev, int sset)
 
 static void rtl8139_get_ethtool_stats(struct net_device *dev, struct ethtool_stats *stats, u64 *data)
 {
-       struct rtl8139_private *np = netdev_priv(dev);
+       struct rtl8139_private *tp = netdev_priv(dev);
 
-       data[0] = np->xstats.early_rx;
-       data[1] = np->xstats.tx_buf_mapped;
-       data[2] = np->xstats.tx_timeouts;
-       data[3] = np->xstats.rx_lost_in_ring;
+       data[0] = tp->xstats.early_rx;
+       data[1] = tp->xstats.tx_buf_mapped;
+       data[2] = tp->xstats.tx_timeouts;
+       data[3] = tp->xstats.rx_lost_in_ring;
 }
 
 static void rtl8139_get_strings(struct net_device *dev, u32 stringset, u8 *data)
@@ -2486,15 +2470,15 @@ static const struct ethtool_ops rtl8139_ethtool_ops = {
 
 static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
-       struct rtl8139_private *np = netdev_priv(dev);
+       struct rtl8139_private *tp = netdev_priv(dev);
        int rc;
 
        if (!netif_running(dev))
                return -EINVAL;
 
-       spin_lock_irq(&np->lock);
-       rc = generic_mii_ioctl(&np->mii, if_mii(rq), cmd, NULL);
-       spin_unlock_irq(&np->lock);
+       spin_lock_irq(&tp->lock);
+       rc = generic_mii_ioctl(&tp->mii, if_mii(rq), cmd, NULL);
+       spin_unlock_irq(&tp->lock);
 
        return rc;
 }
@@ -2527,7 +2511,7 @@ static void __set_rx_mode (struct net_device *dev)
        int i, rx_mode;
        u32 tmp;
 
-       DPRINTK ("%s:   rtl8139_set_rx_mode(%4.4x) done -- Rx config %8.8lx.\n",
+       pr_debug("%s:   rtl8139_set_rx_mode(%4.4x) done -- Rx config %8.8lx.\n",
                        dev->name, dev->flags, RTL_R32 (RxConfig));
 
        /* Note: do not reorder, GCC is clever about common statements. */
@@ -2643,7 +2627,7 @@ static int __init rtl8139_init_module (void)
         * even if no 8139 board is found.
         */
 #ifdef MODULE
-       printk (KERN_INFO RTL8139_DRIVER_NAME "\n");
+       pr_info(RTL8139_DRIVER_NAME "\n");
 #endif
 
        return pci_register_driver(&rtl8139_pci_driver);
index cca94b9c08ae5360428554fcff302620009488b4..77547545509b25c79aeab6b59cc92fd9e38eff5c 100644 (file)
@@ -122,13 +122,13 @@ static char version[] __initdata =
 #define ISCP_BUSY      0x00010000
 #define MACH_IS_APRICOT        0
 #else
-#define WSWAPrfd(x)     ((struct i596_rfd *)(x))
-#define WSWAPrbd(x)     ((struct i596_rbd *)(x))
-#define WSWAPiscp(x)    ((struct i596_iscp *)(x))
-#define WSWAPscb(x)     ((struct i596_scb *)(x))
-#define WSWAPcmd(x)     ((struct i596_cmd *)(x))
-#define WSWAPtbd(x)     ((struct i596_tbd *)(x))
-#define WSWAPchar(x)    ((char *)(x))
+#define WSWAPrfd(x)     ((struct i596_rfd *)((long)x))
+#define WSWAPrbd(x)     ((struct i596_rbd *)((long)x))
+#define WSWAPiscp(x)    ((struct i596_iscp *)((long)x))
+#define WSWAPscb(x)     ((struct i596_scb *)((long)x))
+#define WSWAPcmd(x)     ((struct i596_cmd *)((long)x))
+#define WSWAPtbd(x)     ((struct i596_tbd *)((long)x))
+#define WSWAPchar(x)    ((char *)((long)x))
 #define ISCP_BUSY      0x0001
 #define MACH_IS_APRICOT        1
 #endif
index ec3e22e6306fd115ab2153b7faef2ec0b985a746..21153dea8ebe7d0b1f9dbe36188099a8368c2dca 100644 (file)
@@ -74,14 +74,8 @@ EXPORT_SYMBOL(ei_netdev_ops);
 struct net_device *__alloc_ei_netdev(int size)
 {
        struct net_device *dev = ____alloc_ei_netdev(size);
-#ifdef CONFIG_COMPAT_NET_DEV_OPS
-       if (dev) {
-               dev->hard_start_xmit = ei_start_xmit;
-               dev->get_stats  = ei_get_stats;
-               dev->set_multicast_list = ei_set_multicast_list;
-               dev->tx_timeout = ei_tx_timeout;
-       }
-#endif
+       if (dev)
+               dev->netdev_ops = &ei_netdev_ops;
        return dev;
 }
 EXPORT_SYMBOL(__alloc_ei_netdev);
index da863c91d1d03d79df3c59785d09162190e0c581..d225c291fd934a03814e31f51b2f26d3e44a1955 100644 (file)
@@ -79,14 +79,8 @@ EXPORT_SYMBOL(eip_netdev_ops);
 struct net_device *__alloc_eip_netdev(int size)
 {
        struct net_device *dev = ____alloc_ei_netdev(size);
-#ifdef CONFIG_COMPAT_NET_DEV_OPS
-       if (dev) {
-               dev->hard_start_xmit = eip_start_xmit;
-               dev->get_stats  = eip_get_stats;
-               dev->set_multicast_list = eip_set_multicast_list;
-               dev->tx_timeout = eip_tx_timeout;
-       }
-#endif
+       if (dev)
+               dev->netdev_ops = &eip_netdev_ops;
        return dev;
 }
 EXPORT_SYMBOL(__alloc_eip_netdev);
@@ -97,16 +91,15 @@ void NS8390p_init(struct net_device *dev, int startp)
 }
 EXPORT_SYMBOL(NS8390p_init);
 
-#if defined(MODULE)
-
-int init_module(void)
+static int __init NS8390p_init_module(void)
 {
        return 0;
 }
 
-void cleanup_module(void)
+static void __exit NS8390p_cleanup_module(void)
 {
 }
 
-#endif /* MODULE */
+module_init(NS8390p_init_module);
+module_exit(NS8390p_cleanup_module);
 MODULE_LICENSE("GPL");
index 3111b6c7cbc3225e039de507559cdb334cbb2c30..01f282cd0989d7123b0cb1b74477cded1571919d 100644 (file)
@@ -1,4 +1,3 @@
-
 #
 # Network device configuration
 #
@@ -26,15 +25,6 @@ menuconfig NETDEVICES
 # that for each of the symbols.
 if NETDEVICES
 
-config COMPAT_NET_DEV_OPS
-       default y
-       bool "Enable older network device API compatibility"
-       ---help---
-          This option enables kernel compatibility with older network devices
-          that do not use net_device_ops interface.
-
-         If unsure, say Y.
-
 config IFB
        tristate "Intermediate Functional Block support"
        depends on NET_CLS_ACT
@@ -526,15 +516,16 @@ config STNIC
 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_SH7710 || CPU_SUBTYPE_SH7712 || \
+                CPU_SUBTYPE_SH7763 || CPU_SUBTYPE_SH7619 || \
+                CPU_SUBTYPE_SH7724)
        select CRC32
        select MII
        select MDIO_BITBANG
        select PHYLIB
        help
          Renesas SuperH Ethernet device driver.
-         This driver support SH7710, SH7712, SH7763 and SH7619.
+         This driver support SH7710, SH7712, SH7763, SH7619, and SH7724.
 
 config SUNLANCE
        tristate "Sun LANCE support"
@@ -927,6 +918,16 @@ config NET_NETX
          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
+       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 DM9000
        tristate "DM9000 support"
        depends on ARM || BLACKFIN || MIPS
@@ -1000,7 +1001,7 @@ config SMC911X
 
 config SMSC911X
        tristate "SMSC LAN911x/LAN921x families embedded ethernet support"
-       depends on ARM || SUPERH
+       depends on ARM || SUPERH || BLACKFIN
        select CRC32
        select MII
        select PHYLIB
@@ -1722,6 +1723,11 @@ config TLAN
 
          Please email feedback to <torben.mathiasen@compaq.com>.
 
+config KS8842
+       tristate "Micrel KSZ8842"
+       help
+         This platform driver is for Micrel KSZ8842 chip.
+
 config VIA_RHINE
        tristate "VIA Rhine support"
        depends on NET_PCI && PCI
@@ -1858,8 +1864,8 @@ config 68360_ENET
          the Motorola 68360 processor.
 
 config FEC
-       bool "FEC ethernet controller (of ColdFire CPUs)"
-       depends on M523x || M527x || M5272 || M528x || M520x || M532x || MACH_MX27
+       bool "FEC ethernet controller (of ColdFire and some i.MX CPUs)"
+       depends on M523x || M527x || M5272 || M528x || M520x || M532x || MACH_MX27 || ARCH_MX35
        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.
@@ -2362,7 +2368,7 @@ config UGETH_TX_ON_DEMAND
 
 config MV643XX_ETH
        tristate "Marvell Discovery (643XX) and Orion ethernet support"
-       depends on MV64360 || MV64X60 || (PPC_MULTIPLATFORM && PPC32) || PLAT_ORION
+       depends on MV64X60 || PPC32 || PLAT_ORION
        select INET_LRO
        select PHYLIB
        help
@@ -2373,6 +2379,14 @@ config MV643XX_ETH
          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"
+       select PHYLIB
+       depends on PPC_DCR_NATIVE
+       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
@@ -2446,10 +2460,14 @@ menuconfig NETDEV_10000
 
 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
@@ -2482,6 +2500,7 @@ config CHELSIO_T3
        tristate "Chelsio Communications T3 10Gb Ethernet support"
        depends on CHELSIO_T3_DEPENDS
        select FW_LOADER
+       select MDIO
        help
          This driver supports Chelsio T3-based gigabit and 10Gb Ethernet
          adapters.
@@ -2517,6 +2536,7 @@ config ENIC
 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
@@ -2679,6 +2699,7 @@ config TEHUTI
 config BNX2X
        tristate "Broadcom NetXtremeII 10Gb support"
        depends on PCI
+       select FW_LOADER
        select ZLIB_INFLATE
        select LIBCRC32C
        help
@@ -2715,6 +2736,8 @@ source "drivers/net/wan/Kconfig"
 
 source "drivers/atm/Kconfig"
 
+source "drivers/ieee802154/Kconfig"
+
 source "drivers/s390/net/Kconfig"
 
 config XEN_NETDEV_FRONTEND
index db30ebd7b262336bb3949da5db58e7173d4bfa64..d366fb2b40e99e2065408160243c12da9cc95c33 100644 (file)
@@ -2,6 +2,8 @@
 # Makefile for the Linux network (ethercard) device drivers.
 #
 
+obj-$(CONFIG_TI_DAVINCI_EMAC) += davinci_emac.o
+
 obj-$(CONFIG_E1000) += e1000/
 obj-$(CONFIG_E1000E) += e1000e/
 obj-$(CONFIG_IBM_NEW_EMAC) += ibm_newemac/
@@ -85,6 +87,7 @@ 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_VIA_RHINE) += via-rhine.o
 obj-$(CONFIG_VIA_VELOCITY) += via-velocity.o
 obj-$(CONFIG_ADAPTEC_STARFIRE) += starfire.o
@@ -96,6 +99,7 @@ obj-$(CONFIG_SH_ETH) += sh_eth.o
 #
 
 obj-$(CONFIG_MII) += mii.o
+obj-$(CONFIG_MDIO) += mdio.o
 obj-$(CONFIG_PHYLIB) += phy/
 
 obj-$(CONFIG_SUNDANCE) += sundance.o
@@ -135,6 +139,8 @@ obj-$(CONFIG_AX88796) += ax88796.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_QLA3XXX) += qla3xxx.o
 obj-$(CONFIG_QLGE) += qlge/
 
index 02f64d57864163d05c6e5714e694d635e4373070..85a18175730ba249ab36c5985a654e34df1eb05c 100644 (file)
@@ -564,7 +564,7 @@ static int lance_start_xmit (struct sk_buff *skb, struct net_device *dev)
 
        if (!TX_BUFFS_AVAIL){
                local_irq_restore(flags);
-               return -1;
+               return NETDEV_TX_LOCKED;
        }
 
 #ifdef DEBUG_DRIVER
index 57bc7152785050b893cad09fd85b2f639daf1696..08419ee1029069a60260156b202710d5d4cd7d3b 100644 (file)
@@ -2573,7 +2573,6 @@ restart:
                        netif_wake_queue(dev);
        }
 
-       dev->trans_start = jiffies;
        return NETDEV_TX_OK;
 
 overflow:
index da64ba88d7f8f362ac785570fa73c3c4ecf16935..78cea5e80b1d40b88b62bfe1eaa0a9702f9c81cb 100644 (file)
@@ -39,6 +39,7 @@
 static const char version[] = KERN_INFO "ipddp.c:v0.01 8/28/97 Bradford W. Johnson <johns393@maroon.tc.umn.edu>\n";
 
 static struct ipddp_route *ipddp_route_list;
+static DEFINE_SPINLOCK(ipddp_route_lock);
 
 #ifdef CONFIG_IPDDP_ENCAP
 static int ipddp_mode = IPDDP_ENCAP;
@@ -50,7 +51,7 @@ static int ipddp_mode = IPDDP_DECAP;
 static int ipddp_xmit(struct sk_buff *skb, struct net_device *dev);
 static int ipddp_create(struct ipddp_route *new_rt);
 static int ipddp_delete(struct ipddp_route *rt);
-static struct ipddp_route* ipddp_find_route(struct ipddp_route *rt);
+static struct ipddp_route* __ipddp_find_route(struct ipddp_route *rt);
 static int ipddp_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
 
 static const struct net_device_ops ipddp_netdev_ops = {
@@ -71,6 +72,7 @@ static struct net_device * __init ipddp_init(void)
        if (!dev)
                return ERR_PTR(-ENOMEM);
 
+       dev->priv_flags &= ~IFF_XMIT_DST_RELEASE;
        strcpy(dev->name, "ipddp%d");
 
        if (version_printed++ == 0)
@@ -113,11 +115,13 @@ static struct net_device * __init ipddp_init(void)
  */
 static int ipddp_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-       __be32 paddr = ((struct rtable*)skb->dst)->rt_gateway;
+       __be32 paddr = skb_rtable(skb)->rt_gateway;
         struct ddpehdr *ddp;
         struct ipddp_route *rt;
         struct atalk_addr *our_addr;
 
+       spin_lock(&ipddp_route_lock);
+
        /*
          * Find appropriate route to use, based only on IP number.
          */
@@ -126,8 +130,10 @@ static int ipddp_xmit(struct sk_buff *skb, struct net_device *dev)
                 if(rt->ip == paddr)
                         break;
         }
-        if(rt == NULL)
+        if(rt == NULL) {
+               spin_unlock(&ipddp_route_lock);
                 return 0;
+       }
 
         our_addr = atalk_find_dev_addr(rt->dev);
 
@@ -173,6 +179,8 @@ static int ipddp_xmit(struct sk_buff *skb, struct net_device *dev)
         if(aarp_send_ddp(rt->dev, skb, &rt->at, NULL) < 0)
                 dev_kfree_skb(skb);
 
+       spin_unlock(&ipddp_route_lock);
+
         return 0;
 }
 
@@ -195,7 +203,9 @@ static int ipddp_create(struct ipddp_route *new_rt)
                 return -ENETUNREACH;
         }
 
-       if (ipddp_find_route(rt)) {
+       spin_lock_bh(&ipddp_route_lock);
+       if (__ipddp_find_route(rt)) {
+               spin_unlock_bh(&ipddp_route_lock);
                kfree(rt);
                return -EEXIST;
        }
@@ -203,6 +213,8 @@ static int ipddp_create(struct ipddp_route *new_rt)
         rt->next = ipddp_route_list;
         ipddp_route_list = rt;
 
+       spin_unlock_bh(&ipddp_route_lock);
+
         return 0;
 }
 
@@ -215,6 +227,7 @@ static int ipddp_delete(struct ipddp_route *rt)
         struct ipddp_route **r = &ipddp_route_list;
         struct ipddp_route *tmp;
 
+       spin_lock_bh(&ipddp_route_lock);
         while((tmp = *r) != NULL)
         {
                 if(tmp->ip == rt->ip
@@ -222,19 +235,21 @@ static int ipddp_delete(struct ipddp_route *rt)
                         && tmp->at.s_node == rt->at.s_node)
                 {
                         *r = tmp->next;
+                       spin_unlock_bh(&ipddp_route_lock);
                         kfree(tmp);
                         return 0;
                 }
                 r = &tmp->next;
         }
 
+       spin_unlock_bh(&ipddp_route_lock);
         return (-ENOENT);
 }
 
 /*
  * Find a routing entry, we only return a FULL match
  */
-static struct ipddp_route* ipddp_find_route(struct ipddp_route *rt)
+static struct ipddp_route* __ipddp_find_route(struct ipddp_route *rt)
 {
         struct ipddp_route *f;
 
@@ -252,7 +267,7 @@ static struct ipddp_route* ipddp_find_route(struct ipddp_route *rt)
 static int ipddp_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 {
         struct ipddp_route __user *rt = ifr->ifr_data;
-        struct ipddp_route rcp;
+        struct ipddp_route rcp, rcp2, *rp;
 
         if(!capable(CAP_NET_ADMIN))
                 return -EPERM;
@@ -266,9 +281,19 @@ static int ipddp_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
                         return (ipddp_create(&rcp));
 
                 case SIOCFINDIPDDPRT:
-                        if(copy_to_user(rt, ipddp_find_route(&rcp), sizeof(struct ipddp_route)))
-                                return -EFAULT;
-                        return 0;
+                       spin_lock_bh(&ipddp_route_lock);
+                       rp = __ipddp_find_route(&rcp);
+                       if (rp)
+                               memcpy(&rcp2, rp, sizeof(rcp2));
+                       spin_unlock_bh(&ipddp_route_lock);
+
+                       if (rp) {
+                               if (copy_to_user(rt, &rcp2,
+                                                sizeof(struct ipddp_route)))
+                                       return -EFAULT;
+                               return 0;
+                       } else
+                               return -ENOENT;
 
                 case SIOCDELIPDDPRT:
                         return (ipddp_delete(&rcp));
index 7f4bc8ae5462190f777951c1eec6cf1e35dbd679..2e7419a6119181b29538720114e59b74bf15c578 100644 (file)
@@ -829,7 +829,7 @@ static int at91ether_start_xmit(struct sk_buff *skb, struct net_device *dev)
                dev->trans_start = jiffies;
        } else {
                printk(KERN_ERR "at91_ether.c: at91ether_start_xmit() called, but device is busy!\n");
-               return 1;       /* if we return anything but zero, dev.c:1055 calls kfree_skb(skb)
+               return NETDEV_TX_BUSY;  /* if we return anything but zero, dev.c:1055 calls kfree_skb(skb)
                                on this skb, he also reports -ENETDOWN and printk's, so either
                                we free and return(0) or don't free and return 1 */
        }
index b72b3d639f6ed425e5a3614545f9892790ab022e..fbf4645417d496941f5e6fdccba6c988ec136808 100644 (file)
@@ -253,7 +253,7 @@ static int ep93xx_rx(struct net_device *dev, int processed, int budget)
                skb = dev_alloc_skb(length + 2);
                if (likely(skb != NULL)) {
                        skb_reserve(skb, 2);
-                       dma_sync_single(NULL, ep->descs->rdesc[entry].buf_addr,
+                       dma_sync_single_for_cpu(NULL, ep->descs->rdesc[entry].buf_addr,
                                                length, DMA_FROM_DEVICE);
                        skb_copy_to_linear_data(skb, ep->rx_buf[entry], length);
                        skb_put(skb, length);
@@ -331,7 +331,7 @@ static int ep93xx_xmit(struct sk_buff *skb, struct net_device *dev)
        ep->descs->tdesc[entry].tdesc1 =
                TDESC1_EOF | (entry << 16) | (skb->len & 0xfff);
        skb_copy_and_csum_dev(skb, ep->tx_buf[entry]);
-       dma_sync_single(NULL, ep->descs->tdesc[entry].buf_addr,
+       dma_sync_single_for_cpu(NULL, ep->descs->tdesc[entry].buf_addr,
                                skb->len, DMA_TO_DEVICE);
        dev_kfree_skb(skb);
 
index ec8a1ae1e887dbb1cce9c4e771b4c74d3e406b9e..455037134aa339b075c9d1967cc322717fb32412 100644 (file)
@@ -526,7 +526,7 @@ ether3_sendpacket(struct sk_buff *skb, struct net_device *dev)
 
        if (priv(dev)->tx_tail == next_ptr) {
                local_irq_restore(flags);
-               return 1;       /* unable to queue */
+               return NETDEV_TX_BUSY;  /* unable to queue */
        }
 
        dev->trans_start = jiffies;
index b6d188115caff792889899236972a5926ace1de8..6f42ad728915b2683ee9ee66a9e11562c890453e 100644 (file)
@@ -562,8 +562,8 @@ static int eth_poll(struct napi_struct *napi, int budget)
                dma_unmap_single(&dev->dev, desc->data - NET_IP_ALIGN,
                                 RX_BUFF_SIZE, DMA_FROM_DEVICE);
 #else
-               dma_sync_single(&dev->dev, desc->data - NET_IP_ALIGN,
-                               RX_BUFF_SIZE, DMA_FROM_DEVICE);
+               dma_sync_single_for_cpu(&dev->dev, desc->data - NET_IP_ALIGN,
+                                       RX_BUFF_SIZE, DMA_FROM_DEVICE);
                memcpy_swab32((u32 *)skb->data, (u32 *)port->rx_buff_tab[n],
                              ALIGN(NET_IP_ALIGN + desc->pkt_len, 4) / 4);
 #endif
@@ -1151,7 +1151,7 @@ static int __devinit eth_init_one(struct platform_device *pdev)
        struct net_device *dev;
        struct eth_plat_info *plat = pdev->dev.platform_data;
        u32 regs_phys;
-       char phy_id[BUS_ID_SIZE];
+       char phy_id[MII_BUS_ID_SIZE + 3];
        int err;
 
        if (!(dev = alloc_etherdev(sizeof(struct port))))
@@ -1209,7 +1209,7 @@ static int __devinit eth_init_one(struct platform_device *pdev)
        __raw_writel(DEFAULT_CORE_CNTRL, &port->regs->core_control);
        udelay(50);
 
-       snprintf(phy_id, BUS_ID_SIZE, PHY_ID_FMT, "0", plat->phy);
+       snprintf(phy_id, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, "0", plat->phy);
        port->phydev = phy_connect(dev, phy_id, &ixp4xx_adjust_link, 0,
                                   PHY_INTERFACE_MODE_MII);
        if ((err = IS_ERR(port->phydev)))
index 45c5b7332cd36a6258f42310655c339446369574..e4afbd628c23e8f8b4594e44988d37e6842592cb 100644 (file)
@@ -271,7 +271,7 @@ static int atl1c_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
        struct atl1c_adapter *adapter = netdev_priv(netdev);
 
        if (wol->wolopts & (WAKE_ARP | WAKE_MAGICSECURE |
-                           WAKE_MCAST | WAKE_BCAST | WAKE_MCAST))
+                           WAKE_UCAST | WAKE_BCAST | WAKE_MCAST))
                return -EOPNOTSUPP;
        /* these settings will always override what we currently have */
        adapter->wol = 0;
index 83a12125b94e24f694a982ef9f0d0cac8c70f23d..cd547a205fb96d9d9a71f37cfbc57286686f31d2 100644 (file)
@@ -163,6 +163,24 @@ static inline void atl1c_irq_reset(struct atl1c_adapter *adapter)
        atl1c_irq_enable(adapter);
 }
 
+/*
+ * atl1c_wait_until_idle - wait up to AT_HW_MAX_IDLE_DELAY reads
+ * of the idle status register until the device is actually idle
+ */
+static u32 atl1c_wait_until_idle(struct atl1c_hw *hw)
+{
+       int timeout;
+       u32 data;
+
+       for (timeout = 0; timeout < AT_HW_MAX_IDLE_DELAY; timeout++) {
+               AT_READ_REG(hw, REG_IDLE_STATUS, &data);
+               if ((data & IDLE_STATUS_MASK) == 0)
+                       return 0;
+               msleep(1);
+       }
+       return data;
+}
+
 /*
  * atl1c_phy_config - Timer Call-back
  * @data: pointer to netdev cast into an unsigned long
@@ -220,11 +238,11 @@ static void atl1c_check_link_status(struct atl1c_adapter *adapter)
                /* link down */
                if (netif_carrier_ok(netdev)) {
                        hw->hibernate = true;
-                       atl1c_set_aspm(hw, false);
                        if (atl1c_stop_mac(hw) != 0)
                                if (netif_msg_hw(adapter))
                                        dev_warn(&pdev->dev,
                                                "stop mac failed\n");
+                       atl1c_set_aspm(hw, false);
                }
                netif_carrier_off(netdev);
        } else {
@@ -240,10 +258,10 @@ static void atl1c_check_link_status(struct atl1c_adapter *adapter)
                    adapter->link_duplex != duplex) {
                        adapter->link_speed  = speed;
                        adapter->link_duplex = duplex;
+                       atl1c_set_aspm(hw, true);
                        atl1c_enable_tx_ctrl(hw);
                        atl1c_enable_rx_ctrl(hw);
                        atl1c_setup_mac_ctrl(adapter);
-                       atl1c_set_aspm(hw, true);
                        if (netif_msg_link(adapter))
                                dev_info(&pdev->dev,
                                        "%s: %s NIC Link is Up<%d Mbps %s>\n",
@@ -1106,7 +1124,6 @@ static void atl1c_configure_dma(struct atl1c_adapter *adapter)
 static int atl1c_stop_mac(struct atl1c_hw *hw)
 {
        u32 data;
-       int timeout;
 
        AT_READ_REG(hw, REG_RXQ_CTRL, &data);
        data &= ~(RXQ1_CTRL_EN | RXQ2_CTRL_EN |
@@ -1117,25 +1134,13 @@ static int atl1c_stop_mac(struct atl1c_hw *hw)
        data &= ~TXQ_CTRL_EN;
        AT_WRITE_REG(hw, REG_TWSI_CTRL, data);
 
-       for (timeout = 0; timeout < AT_HW_MAX_IDLE_DELAY; timeout++) {
-               AT_READ_REG(hw, REG_IDLE_STATUS, &data);
-               if ((data & (IDLE_STATUS_RXQ_NO_IDLE |
-                       IDLE_STATUS_TXQ_NO_IDLE)) == 0)
-                       break;
-               msleep(1);
-       }
+       atl1c_wait_until_idle(hw);
 
        AT_READ_REG(hw, REG_MAC_CTRL, &data);
        data &= ~(MAC_CTRL_TX_EN | MAC_CTRL_RX_EN);
        AT_WRITE_REG(hw, REG_MAC_CTRL, data);
 
-       for (timeout = 0; timeout < AT_HW_MAX_IDLE_DELAY; timeout++) {
-               AT_READ_REG(hw, REG_IDLE_STATUS, &data);
-               if ((data & IDLE_STATUS_MASK) == 0)
-                       return 0;
-               msleep(1);
-       }
-       return data;
+       return (int)atl1c_wait_until_idle(hw);
 }
 
 static void atl1c_enable_rx_ctrl(struct atl1c_hw *hw)
@@ -1178,8 +1183,6 @@ static int atl1c_reset_mac(struct atl1c_hw *hw)
 {
        struct atl1c_adapter *adapter = (struct atl1c_adapter *)hw->adapter;
        struct pci_dev *pdev = adapter->pdev;
-       u32 idle_status_data = 0;
-       int timeout = 0;
        int ret;
 
        AT_WRITE_REG(hw, REG_IMR, 0);
@@ -1198,15 +1201,10 @@ static int atl1c_reset_mac(struct atl1c_hw *hw)
        AT_WRITE_FLUSH(hw);
        msleep(10);
        /* Wait at least 10ms for All module to be Idle */
-       for (timeout = 0; timeout < AT_HW_MAX_IDLE_DELAY; timeout++) {
-               AT_READ_REG(hw, REG_IDLE_STATUS, &idle_status_data);
-               if ((idle_status_data & IDLE_STATUS_MASK) == 0)
-                       break;
-               msleep(1);
-       }
-       if (timeout >= AT_HW_MAX_IDLE_DELAY) {
+
+       if (atl1c_wait_until_idle(hw)) {
                dev_err(&pdev->dev,
-                       "MAC state machine cann't be idle since"
+                       "MAC state machine can't be idle since"
                        " disabled for 10ms second\n");
                return -1;
        }
@@ -1242,9 +1240,7 @@ static void atl1c_set_aspm(struct atl1c_hw *hw, bool linkup)
 
        AT_READ_REG(hw, REG_PM_CTRL, &pm_ctrl_data);
 
-       pm_ctrl_data &= PM_CTRL_SERDES_PD_EX_L1;
-       pm_ctrl_data |= ~PM_CTRL_SERDES_BUDS_RX_L1_EN;
-       pm_ctrl_data |= ~PM_CTRL_SERDES_L1_EN;
+       pm_ctrl_data &= ~PM_CTRL_SERDES_PD_EX_L1;
        pm_ctrl_data &=  ~(PM_CTRL_L1_ENTRY_TIMER_MASK <<
                        PM_CTRL_L1_ENTRY_TIMER_SHIFT);
 
@@ -1254,19 +1250,11 @@ static void atl1c_set_aspm(struct atl1c_hw *hw, bool linkup)
                pm_ctrl_data |= PM_CTRL_SERDES_PLL_L1_EN;
                pm_ctrl_data &= ~PM_CTRL_CLK_SWH_L1;
 
-               if (hw->ctrl_flags & ATL1C_ASPM_L1_SUPPORT) {
-                       pm_ctrl_data |= AT_ASPM_L1_TIMER <<
-                               PM_CTRL_L1_ENTRY_TIMER_SHIFT;
-                       pm_ctrl_data |= PM_CTRL_ASPM_L1_EN;
-               } else
-                       pm_ctrl_data &= ~PM_CTRL_ASPM_L1_EN;
-
-               if (hw->ctrl_flags & ATL1C_ASPM_L0S_SUPPORT)
-                       pm_ctrl_data |= PM_CTRL_ASPM_L0S_EN;
-               else
-                       pm_ctrl_data &= ~PM_CTRL_ASPM_L0S_EN;
-
+               pm_ctrl_data |= PM_CTRL_SERDES_BUDS_RX_L1_EN;
+               pm_ctrl_data |= PM_CTRL_SERDES_L1_EN;
        } else {
+               pm_ctrl_data &= ~PM_CTRL_SERDES_BUDS_RX_L1_EN;
+               pm_ctrl_data &= ~PM_CTRL_SERDES_L1_EN;
                pm_ctrl_data &= ~PM_CTRL_ASPM_L0S_EN;
                pm_ctrl_data &= ~PM_CTRL_SERDES_PLL_L1_EN;
 
@@ -2123,7 +2111,6 @@ static int atl1c_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
        atl1c_tx_map(adapter, skb, tpd, type);
        atl1c_tx_queue(adapter, skb, tpd, type);
 
-       netdev->trans_start = jiffies;
        spin_unlock_irqrestore(&adapter->tx_lock, flags);
        return NETDEV_TX_OK;
 }
index 2bf63b4368e20abdeb844aece0845443454df838..ba48220df16a394cb157c8e9eb373de0408004a9 100644 (file)
@@ -429,7 +429,6 @@ struct atl1e_adapter {
        struct mii_if_info  mii;    /* MII interface info */
        struct atl1e_hw        hw;
        struct atl1e_hw_stats  hw_stats;
-       struct net_device_stats net_stats;
 
        bool have_msi;
        u32 wol;
index 1342418fb209fc430aba1574cb24e36b46c51114..9fc6d6d9060ec7bfe8293b08c02d10e90d9228c9 100644 (file)
@@ -1154,7 +1154,7 @@ static struct net_device_stats *atl1e_get_stats(struct net_device *netdev)
 {
        struct atl1e_adapter *adapter = netdev_priv(netdev);
        struct atl1e_hw_stats  *hw_stats = &adapter->hw_stats;
-       struct net_device_stats *net_stats = &adapter->net_stats;
+       struct net_device_stats *net_stats = &netdev->stats;
 
        net_stats->rx_packets = hw_stats->rx_ok;
        net_stats->tx_packets = hw_stats->tx_ok;
@@ -1182,7 +1182,7 @@ static struct net_device_stats *atl1e_get_stats(struct net_device *netdev)
        net_stats->tx_aborted_errors = hw_stats->tx_abort_col;
        net_stats->tx_window_errors  = hw_stats->tx_late_col;
 
-       return &adapter->net_stats;
+       return net_stats;
 }
 
 static void atl1e_update_hw_stats(struct atl1e_adapter *adapter)
@@ -1310,7 +1310,7 @@ static irqreturn_t atl1e_intr(int irq, void *data)
 
                /* link event */
                if (status & (ISR_GPHY | ISR_MANUAL)) {
-                       adapter->net_stats.tx_carrier_errors++;
+                       netdev->stats.tx_carrier_errors++;
                        atl1e_link_chg_event(adapter);
                        break;
                }
@@ -1602,7 +1602,7 @@ static u16 atl1e_cal_tdp_req(const struct sk_buff *skb)
        }
 
        if (skb_is_gso(skb)) {
-               if (skb->protocol == ntohs(ETH_P_IP) ||
+               if (skb->protocol == htons(ETH_P_IP) ||
                   (skb_shinfo(skb)->gso_type == SKB_GSO_TCPV6)) {
                        proto_hdr_len = skb_transport_offset(skb) +
                                        tcp_hdrlen(skb);
@@ -1795,8 +1795,7 @@ static void atl1e_tx_map(struct atl1e_adapter *adapter,
                        memcpy(use_tpd, tpd, sizeof(struct atl1e_tpd_desc));
 
                        tx_buffer = atl1e_get_tx_buffer(adapter, use_tpd);
-                       if (tx_buffer->skb)
-                               BUG();
+                       BUG_ON(tx_buffer->skb);
 
                        tx_buffer->skb = NULL;
                        tx_buffer->length =
@@ -1879,7 +1878,7 @@ static int atl1e_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
                                TPD_VLAN_SHIFT;
        }
 
-       if (skb->protocol == ntohs(ETH_P_8021Q))
+       if (skb->protocol == htons(ETH_P_8021Q))
                tpd->word3 |= 1 << TPD_VL_TAGGED_SHIFT;
 
        if (skb_network_offset(skb) != ETH_HLEN)
@@ -1895,7 +1894,7 @@ static int atl1e_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
        atl1e_tx_map(adapter, skb, tpd);
        atl1e_tx_queue(adapter, tpd_req, tpd);
 
-       netdev->trans_start = jiffies;
+       netdev->trans_start = jiffies; /* NETIF_F_LLTX driver :( */
        spin_unlock_irqrestore(&adapter->tx_lock, flags);
        return NETDEV_TX_OK;
 }
index 4e817126e280b177d10561d8ee76f881dd437257..94d7325caf4ffc5a893c274dc3cf56a0e957897a 100644 (file)
@@ -2213,8 +2213,7 @@ static void atl1_tx_map(struct atl1_adapter *adapter, struct sk_buff *skb,
        nr_frags = skb_shinfo(skb)->nr_frags;
        next_to_use = atomic_read(&tpd_ring->next_to_use);
        buffer_info = &tpd_ring->buffer_info[next_to_use];
-       if (unlikely(buffer_info->skb))
-               BUG();
+       BUG_ON(buffer_info->skb);
        /* put skb in last TPD */
        buffer_info->skb = NULL;
 
@@ -2280,8 +2279,8 @@ static void atl1_tx_map(struct atl1_adapter *adapter, struct sk_buff *skb,
                        ATL1_MAX_TX_BUF_LEN;
                for (i = 0; i < nseg; i++) {
                        buffer_info = &tpd_ring->buffer_info[next_to_use];
-                       if (unlikely(buffer_info->skb))
-                               BUG();
+                       BUG_ON(buffer_info->skb);
+
                        buffer_info->skb = NULL;
                        buffer_info->length = (buf_len > ATL1_MAX_TX_BUF_LEN) ?
                                ATL1_MAX_TX_BUF_LEN : buf_len;
@@ -2383,7 +2382,7 @@ static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 
        mss = skb_shinfo(skb)->gso_size;
        if (mss) {
-               if (skb->protocol == ntohs(ETH_P_IP)) {
+               if (skb->protocol == htons(ETH_P_IP)) {
                        proto_hdr_len = (skb_transport_offset(skb) +
                                         tcp_hdrlen(skb));
                        if (unlikely(proto_hdr_len > len)) {
@@ -2438,7 +2437,6 @@ static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
        atl1_tx_queue(adapter, count, ptpd);
        atl1_update_mailbox(adapter);
        mmiowb();
-       netdev->trans_start = jiffies;
        return NETDEV_TX_OK;
 }
 
index d58c105fc77939491f432e95648e3108f508ca24..d3c734f4d679956e3fb16d88473ebeee35568606 100644 (file)
@@ -957,7 +957,7 @@ static int au1000_tx(struct sk_buff *skb, struct net_device *dev)
                /* We've wrapped around and the transmitter is still busy */
                netif_stop_queue(dev);
                aup->tx_full = 1;
-               return 1;
+               return NETDEV_TX_BUSY;
        }
        else if (buff_stat & TX_T_DONE) {
                update_tx_stats(dev, ptxd->status);
index b70b81ec34c386f0520437f8cd96199cebc9e611..36d4d377ec2fc5df3a78a96f609aa6055e7ad167 100644 (file)
@@ -782,7 +782,7 @@ static int b44_rx(struct b44 *bp, int budget)
                drop_it:
                        b44_recycle_rx(bp, cons, bp->rx_prod);
                drop_it_no_recycle:
-                       bp->stats.rx_dropped++;
+                       bp->dev->stats.rx_dropped++;
                        goto next_pkt;
                }
 
@@ -1647,7 +1647,7 @@ static int b44_close(struct net_device *dev)
 static struct net_device_stats *b44_get_stats(struct net_device *dev)
 {
        struct b44 *bp = netdev_priv(dev);
-       struct net_device_stats *nstat = &bp->stats;
+       struct net_device_stats *nstat = &dev->stats;
        struct b44_hw_stats *hwstat = &bp->hw_stats;
 
        /* Convert HW stats into netdevice stats. */
index d24158e7f3097261633d22a342cbdb249e415d01..e1905a49279ff584a1328eadc371284814eeacac 100644 (file)
@@ -384,7 +384,6 @@ struct b44 {
 
        struct timer_list       timer;
 
-       struct net_device_stats stats;
        struct b44_hw_stats     hw_stats;
 
        struct ssb_device       *sdev;
index 5c378b5e8e41ee5865068df7fdd3215cd63e4a3a..66bb56874d9bd0bbc99b18284f836f2e6a2535ba 100644 (file)
@@ -168,6 +168,7 @@ static void netdev_stats_update(struct be_adapter *adapter)
        struct be_port_rxf_stats *port_stats =
                        &rxf_stats->port[adapter->port_num];
        struct net_device_stats *dev_stats = &adapter->stats.net_stats;
+       struct be_erx_stats *erx_stats = &hw_stats->erx;
 
        dev_stats->rx_packets = port_stats->rx_total_frames;
        dev_stats->tx_packets = port_stats->tx_unicastframes +
@@ -181,29 +182,33 @@ static void netdev_stats_update(struct be_adapter *adapter)
        dev_stats->rx_errors = port_stats->rx_crc_errors +
                port_stats->rx_alignment_symbol_errors +
                port_stats->rx_in_range_errors +
-               port_stats->rx_out_range_errors + port_stats->rx_frame_too_long;
-
-       /*  packet transmit problems */
-       dev_stats->tx_errors = 0;
-
-       /*  no space in linux buffers */
-       dev_stats->rx_dropped = 0;
-
-       /* no space available in linux */
-       dev_stats->tx_dropped = 0;
-
-       dev_stats->multicast = port_stats->tx_multicastframes;
-       dev_stats->collisions = 0;
+               port_stats->rx_out_range_errors +
+               port_stats->rx_frame_too_long +
+               port_stats->rx_dropped_too_small +
+               port_stats->rx_dropped_too_short +
+               port_stats->rx_dropped_header_too_small +
+               port_stats->rx_dropped_tcp_length +
+               port_stats->rx_dropped_runt +
+               port_stats->rx_tcp_checksum_errs +
+               port_stats->rx_ip_checksum_errs +
+               port_stats->rx_udp_checksum_errs;
+
+       /*  no space in linux buffers: best possible approximation */
+       dev_stats->rx_dropped = erx_stats->rx_drops_no_fragments[0];
 
        /* detailed rx errors */
        dev_stats->rx_length_errors = port_stats->rx_in_range_errors +
-               port_stats->rx_out_range_errors + port_stats->rx_frame_too_long;
+               port_stats->rx_out_range_errors +
+               port_stats->rx_frame_too_long;
+
        /* receive ring buffer overflow */
        dev_stats->rx_over_errors = 0;
+
        dev_stats->rx_crc_errors = port_stats->rx_crc_errors;
 
        /* frame alignment errors */
        dev_stats->rx_frame_errors = port_stats->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 = port_stats->rx_fifo_overflow +
@@ -211,6 +216,16 @@ static void netdev_stats_update(struct be_adapter *adapter)
                                        rxf_stats->rx_drops_no_pbuf;
        /* receiver missed packetd */
        dev_stats->rx_missed_errors = 0;
+
+       /*  packet transmit problems */
+       dev_stats->tx_errors = 0;
+
+       /* no space available in linux */
+       dev_stats->tx_dropped = 0;
+
+       dev_stats->multicast = port_stats->tx_multicastframes;
+       dev_stats->collisions = 0;
+
        /* detailed tx_errors */
        dev_stats->tx_aborted_errors = 0;
        dev_stats->tx_carrier_errors = 0;
@@ -337,13 +352,10 @@ static void be_tx_stats_update(struct be_adapter *adapter,
 /* Determine number of WRB entries needed to xmit data in an skb */
 static u32 wrb_cnt_for_skb(struct sk_buff *skb, bool *dummy)
 {
-       int cnt = 0;
-       while (skb) {
-               if (skb->len > skb->data_len)
-                       cnt++;
-               cnt += skb_shinfo(skb)->nr_frags;
-               skb = skb_shinfo(skb)->frag_list;
-       }
+       int cnt = (skb->len > skb->data_len);
+
+       cnt += skb_shinfo(skb)->nr_frags;
+
        /* to account for hdr wrb */
        cnt++;
        if (cnt & 1) {
@@ -409,31 +421,28 @@ static int make_tx_wrbs(struct be_adapter *adapter,
        hdr = queue_head_node(txq);
        queue_head_inc(txq);
 
-       while (skb) {
-               if (skb->len > skb->data_len) {
-                       int len = skb->len - skb->data_len;
-                       busaddr = pci_map_single(pdev, skb->data, len,
-                                       PCI_DMA_TODEVICE);
-                       wrb = queue_head_node(txq);
-                       wrb_fill(wrb, busaddr, len);
-                       be_dws_cpu_to_le(wrb, sizeof(*wrb));
-                       queue_head_inc(txq);
-                       copied += len;
-               }
+       if (skb->len > skb->data_len) {
+               int len = skb->len - skb->data_len;
+               busaddr = pci_map_single(pdev, skb->data, len,
+                                        PCI_DMA_TODEVICE);
+               wrb = queue_head_node(txq);
+               wrb_fill(wrb, busaddr, len);
+               be_dws_cpu_to_le(wrb, sizeof(*wrb));
+               queue_head_inc(txq);
+               copied += len;
+       }
 
-               for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
-                       struct skb_frag_struct *frag =
-                               &skb_shinfo(skb)->frags[i];
-                       busaddr = pci_map_page(pdev, frag->page,
-                                       frag->page_offset,
-                                       frag->size, PCI_DMA_TODEVICE);
-                       wrb = queue_head_node(txq);
-                       wrb_fill(wrb, busaddr, frag->size);
-                       be_dws_cpu_to_le(wrb, sizeof(*wrb));
-                       queue_head_inc(txq);
-                       copied += frag->size;
-               }
-               skb = skb_shinfo(skb)->frag_list;
+       for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+               struct skb_frag_struct *frag =
+                       &skb_shinfo(skb)->frags[i];
+               busaddr = pci_map_page(pdev, frag->page,
+                                      frag->page_offset,
+                                      frag->size, PCI_DMA_TODEVICE);
+               wrb = queue_head_node(txq);
+               wrb_fill(wrb, busaddr, frag->size);
+               be_dws_cpu_to_le(wrb, sizeof(*wrb));
+               queue_head_inc(txq);
+               copied += frag->size;
        }
 
        if (dummy_wrb) {
@@ -478,8 +487,6 @@ static int be_xmit(struct sk_buff *skb, struct net_device *netdev)
 
        be_txq_notify(&adapter->ctrl, txq->id, wrb_cnt);
 
-       netdev->trans_start = jiffies;
-
        be_tx_stats_update(adapter, wrb_cnt, copied, stopped);
        return NETDEV_TX_OK;
 }
@@ -637,6 +644,22 @@ static void be_rx_stats_update(struct be_adapter *adapter,
        stats->be_rx_bytes += pktsize;
 }
 
+static inline bool do_pkt_csum(struct be_eth_rx_compl *rxcp, bool cso)
+{
+       u8 l4_cksm, ip_version, ipcksm, tcpf = 0, udpf = 0, ipv6_chk;
+
+       l4_cksm = AMAP_GET_BITS(struct amap_eth_rx_compl, l4_cksm, rxcp);
+       ipcksm = AMAP_GET_BITS(struct amap_eth_rx_compl, ipcksm, rxcp);
+       ip_version = AMAP_GET_BITS(struct amap_eth_rx_compl, ip_version, rxcp);
+       if (ip_version) {
+               tcpf = AMAP_GET_BITS(struct amap_eth_rx_compl, tcpf, rxcp);
+               udpf = AMAP_GET_BITS(struct amap_eth_rx_compl, udpf, rxcp);
+       }
+       ipv6_chk = (ip_version && (tcpf || udpf));
+
+       return ((l4_cksm && ipv6_chk && ipcksm) && cso) ? false : true;
+}
+
 static struct be_rx_page_info *
 get_rx_page_info(struct be_adapter *adapter, u16 frag_idx)
 {
@@ -720,7 +743,7 @@ static void skb_fill_rx_data(struct be_adapter *adapter,
 
        if (pktsize <= rx_frag_size) {
                BUG_ON(num_rcvd != 1);
-               return;
+               goto done;
        }
 
        /* More frags present for this completion */
@@ -742,6 +765,7 @@ static void skb_fill_rx_data(struct be_adapter *adapter,
                memset(page_info, 0, sizeof(*page_info));
        }
 
+done:
        be_rx_stats_update(adapter, pktsize, num_rcvd);
        return;
 }
@@ -752,9 +776,7 @@ static void be_rx_compl_process(struct be_adapter *adapter,
 {
        struct sk_buff *skb;
        u32 vtp, vid;
-       int l4_cksm;
 
-       l4_cksm = AMAP_GET_BITS(struct amap_eth_rx_compl, l4_cksm, rxcp);
        vtp = AMAP_GET_BITS(struct amap_eth_rx_compl, vtp, rxcp);
 
        skb = netdev_alloc_skb(adapter->netdev, BE_HDR_LEN + NET_IP_ALIGN);
@@ -769,10 +791,10 @@ static void be_rx_compl_process(struct be_adapter *adapter,
 
        skb_fill_rx_data(adapter, skb, rxcp);
 
-       if (l4_cksm && adapter->rx_csum)
-               skb->ip_summed = CHECKSUM_UNNECESSARY;
-       else
+       if (do_pkt_csum(rxcp, adapter->rx_csum))
                skb->ip_summed = CHECKSUM_NONE;
+       else
+               skb->ip_summed = CHECKSUM_UNNECESSARY;
 
        skb->truesize = skb->len + sizeof(struct sk_buff);
        skb->protocol = eth_type_trans(skb, adapter->netdev);
@@ -854,12 +876,19 @@ static struct be_eth_rx_compl *be_rx_compl_get(struct be_adapter *adapter)
 
        be_dws_le_to_cpu(rxcp, sizeof(*rxcp));
 
-       rxcp->dw[offsetof(struct amap_eth_rx_compl, valid) / 32] = 0;
-
        queue_tail_inc(&adapter->rx_obj.cq);
        return rxcp;
 }
 
+/* To reset the valid bit, we need to reset the whole word as
+ * when walking the queue the valid entries are little-endian
+ * and invalid entries are host endian
+ */
+static inline void be_rx_compl_reset(struct be_eth_rx_compl *rxcp)
+{
+       rxcp->dw[offsetof(struct amap_eth_rx_compl, valid) / 32] = 0;
+}
+
 static inline struct page *be_alloc_pages(u32 size)
 {
        gfp_t alloc_flags = GFP_ATOMIC;
@@ -991,6 +1020,7 @@ static void be_rx_q_clean(struct be_adapter *adapter)
        /* First cleanup pending rx completions */
        while ((rxcp = be_rx_compl_get(adapter)) != NULL) {
                be_rx_compl_discard(adapter, rxcp);
+               be_rx_compl_reset(rxcp);
                be_cq_notify(&adapter->ctrl, rx_cq->id, true, 1);
        }
 
@@ -1026,8 +1056,13 @@ static void be_tx_queues_destroy(struct be_adapter *adapter)
        struct be_queue_info *q;
 
        q = &adapter->tx_obj.q;
-       if (q->created)
+       if (q->created) {
                be_cmd_q_destroy(&adapter->ctrl, q, QTYPE_TXQ);
+
+               /* No more tx completions can be rcvd now; clean up if there
+                * are any pending completions or pending tx requests */
+               be_tx_q_clean(adapter);
+       }
        be_queue_free(adapter, q);
 
        q = &adapter->tx_obj.cq;
@@ -1035,10 +1070,6 @@ static void be_tx_queues_destroy(struct be_adapter *adapter)
                be_cmd_q_destroy(&adapter->ctrl, q, QTYPE_CQ);
        be_queue_free(adapter, q);
 
-       /* No more tx completions can be rcvd now; clean up if there are
-        * any pending completions or pending tx requests */
-       be_tx_q_clean(adapter);
-
        q = &adapter->tx_eq.q;
        if (q->created)
                be_cmd_q_destroy(&adapter->ctrl, q, QTYPE_EQ);
@@ -1272,6 +1303,8 @@ int be_poll_rx(struct napi_struct *napi, int budget)
                        be_rx_compl_process_lro(adapter, rxcp);
                else
                        be_rx_compl_process(adapter, rxcp);
+
+               be_rx_compl_reset(rxcp);
        }
 
        lro_flush_all(&adapter->rx_obj.lro_mgr);
@@ -1527,7 +1560,7 @@ static int be_close(struct net_device *netdev)
        struct be_eq_obj *tx_eq = &adapter->tx_eq;
        int vec;
 
-       cancel_delayed_work(&adapter->work);
+       cancel_delayed_work_sync(&adapter->work);
 
        netif_stop_queue(netdev);
        netif_carrier_off(netdev);
@@ -1626,10 +1659,12 @@ static void be_netdev_init(struct net_device *netdev)
 
        netdev->features |= NETIF_F_SG | NETIF_F_HW_VLAN_RX | NETIF_F_TSO |
                NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_FILTER | NETIF_F_IP_CSUM |
-               NETIF_F_IPV6_CSUM | NETIF_F_TSO6;
+               NETIF_F_IPV6_CSUM;
 
        netdev->flags |= IFF_MULTICAST;
 
+       adapter->rx_csum = true;
+
        BE_SET_NETDEV_OPS(netdev, &be_netdev_ops);
 
        SET_ETHTOOL_OPS(netdev, &be_ethtool_ops);
index b4da18213324aec91753decc3ba83e25fe3422c2..c15fc281f79f93cad08aac3dee982194d46a8dfe 100644 (file)
@@ -194,13 +194,13 @@ static int desc_list_init(void)
                struct dma_descriptor *b = &(r->desc_b);
 
                /* allocate a new skb for next time receive */
-               new_skb = dev_alloc_skb(PKT_BUF_SZ + 2);
+               new_skb = dev_alloc_skb(PKT_BUF_SZ + NET_IP_ALIGN);
                if (!new_skb) {
                        printk(KERN_NOTICE DRV_NAME
                               ": init: low on mem - packet dropped\n");
                        goto init_error;
                }
-               skb_reserve(new_skb, 2);
+               skb_reserve(new_skb, NET_IP_ALIGN);
                r->skb = new_skb;
 
                /*
@@ -566,9 +566,9 @@ static void adjust_tx_list(void)
         */
        if (current_tx_ptr->next->next == tx_list_head) {
                while (tx_list_head->status.status_word == 0) {
-                       mdelay(1);
+                       udelay(10);
                        if (tx_list_head->status.status_word != 0
-                           || !(bfin_read_DMA2_IRQ_STATUS() & 0x08)) {
+                           || !(bfin_read_DMA2_IRQ_STATUS() & DMA_RUN)) {
                                goto adjust_head;
                        }
                        if (timeout_cnt-- < 0) {
@@ -606,93 +606,41 @@ static int bfin_mac_hard_start_xmit(struct sk_buff *skb,
                                struct net_device *dev)
 {
        u16 *data;
-
+       u32 data_align = (unsigned long)(skb->data) & 0x3;
        current_tx_ptr->skb = skb;
 
-       if (ANOMALY_05000285) {
-               /*
-                * TXDWA feature is not avaible to older revision < 0.3 silicon
-                * of BF537
-                *
-                * Only if data buffer is ODD WORD alignment, we do not
-                * need to memcpy
-                */
-               u32 data_align = (u32)(skb->data) & 0x3;
-               if (data_align == 0x2) {
-                       /* move skb->data to current_tx_ptr payload */
-                       data = (u16 *)(skb->data) - 1;
-                       *data = (u16)(skb->len);
-                       current_tx_ptr->desc_a.start_addr = (u32)data;
-                       /* this is important! */
-                       blackfin_dcache_flush_range((u32)data,
-                                       (u32)((u8 *)data + skb->len + 4));
-               } else {
-                       *((u16 *)(current_tx_ptr->packet)) = (u16)(skb->len);
-                       memcpy((u8 *)(current_tx_ptr->packet + 2), skb->data,
-                               skb->len);
-                       current_tx_ptr->desc_a.start_addr =
-                               (u32)current_tx_ptr->packet;
-                       if (current_tx_ptr->status.status_word != 0)
-                               current_tx_ptr->status.status_word = 0;
-                       blackfin_dcache_flush_range(
-                               (u32)current_tx_ptr->packet,
-                               (u32)(current_tx_ptr->packet + skb->len + 2));
-               }
+       if (data_align == 0x2) {
+               /* move skb->data to current_tx_ptr payload */
+               data = (u16 *)(skb->data) - 1;
+                               *data = (u16)(skb->len);
+               current_tx_ptr->desc_a.start_addr = (u32)data;
+               /* this is important! */
+               blackfin_dcache_flush_range((u32)data,
+                               (u32)((u8 *)data + skb->len + 4));
        } else {
-               /*
-                * TXDWA feature is avaible to revision < 0.3 silicon of
-                * BF537 and always avaible to BF52x
-                */
-               u32 data_align = (u32)(skb->data) & 0x3;
-               if (data_align == 0x0) {
-                       u16 sysctl = bfin_read_EMAC_SYSCTL();
-                       sysctl |= TXDWA;
-                       bfin_write_EMAC_SYSCTL(sysctl);
-
-                       /* move skb->data to current_tx_ptr payload */
-                       data = (u16 *)(skb->data) - 2;
-                       *data = (u16)(skb->len);
-                       current_tx_ptr->desc_a.start_addr = (u32)data;
-                       /* this is important! */
-                       blackfin_dcache_flush_range(
-                                       (u32)data,
-                                       (u32)((u8 *)data + skb->len + 4));
-               } else if (data_align == 0x2) {
-                       u16 sysctl = bfin_read_EMAC_SYSCTL();
-                       sysctl &= ~TXDWA;
-                       bfin_write_EMAC_SYSCTL(sysctl);
-
-                       /* move skb->data to current_tx_ptr payload */
-                       data = (u16 *)(skb->data) - 1;
-                       *data = (u16)(skb->len);
-                       current_tx_ptr->desc_a.start_addr = (u32)data;
-                       /* this is important! */
-                       blackfin_dcache_flush_range(
-                                       (u32)data,
-                                       (u32)((u8 *)data + skb->len + 4));
-               } else {
-                       u16 sysctl = bfin_read_EMAC_SYSCTL();
-                       sysctl &= ~TXDWA;
-                       bfin_write_EMAC_SYSCTL(sysctl);
-
-                       *((u16 *)(current_tx_ptr->packet)) = (u16)(skb->len);
-                       memcpy((u8 *)(current_tx_ptr->packet + 2), skb->data,
-                               skb->len);
-                       current_tx_ptr->desc_a.start_addr =
-                               (u32)current_tx_ptr->packet;
-                       if (current_tx_ptr->status.status_word != 0)
-                               current_tx_ptr->status.status_word = 0;
-                       blackfin_dcache_flush_range(
-                               (u32)current_tx_ptr->packet,
-                               (u32)(current_tx_ptr->packet + skb->len + 2));
-               }
+               *((u16 *)(current_tx_ptr->packet)) = (u16)(skb->len);
+               memcpy((u8 *)(current_tx_ptr->packet + 2), skb->data,
+                       skb->len);
+               current_tx_ptr->desc_a.start_addr =
+                       (u32)current_tx_ptr->packet;
+               if (current_tx_ptr->status.status_word != 0)
+                       current_tx_ptr->status.status_word = 0;
+               blackfin_dcache_flush_range(
+                       (u32)current_tx_ptr->packet,
+                       (u32)(current_tx_ptr->packet + skb->len + 2));
        }
 
+       /* make sure the internal data buffers in the core are drained
+        * so that the DMA descriptors are completely written when the
+        * DMA engine goes to fetch them below
+        */
+       SSYNC();
+
        /* enable this packet's dma */
        current_tx_ptr->desc_a.config |= DMAEN;
 
        /* tx dma is running, just return */
-       if (bfin_read_DMA2_IRQ_STATUS() & 0x08)
+       if (bfin_read_DMA2_IRQ_STATUS() & DMA_RUN)
                goto out;
 
        /* tx dma is not running */
@@ -718,7 +666,7 @@ static void bfin_mac_rx(struct net_device *dev)
 
        /* allocate a new skb for next time receive */
        skb = current_rx_ptr->skb;
-       new_skb = dev_alloc_skb(PKT_BUF_SZ + 2);
+       new_skb = dev_alloc_skb(PKT_BUF_SZ + NET_IP_ALIGN);
        if (!new_skb) {
                printk(KERN_NOTICE DRV_NAME
                       ": rx: low on mem - packet dropped\n");
@@ -726,7 +674,7 @@ static void bfin_mac_rx(struct net_device *dev)
                goto out;
        }
        /* reserve 2 bytes for RXDWA padding */
-       skb_reserve(new_skb, 2);
+       skb_reserve(new_skb, NET_IP_ALIGN);
        current_rx_ptr->skb = new_skb;
        current_rx_ptr->desc_a.start_addr = (unsigned long)new_skb->data - 2;
 
@@ -1022,7 +970,8 @@ static int __devinit bfin_mac_probe(struct platform_device *pdev)
 {
        struct net_device *ndev;
        struct bfin_mac_local *lp;
-       int rc, i;
+       struct platform_device *pd;
+       int rc;
 
        ndev = alloc_etherdev(sizeof(struct bfin_mac_local));
        if (!ndev) {
@@ -1047,13 +996,6 @@ static int __devinit bfin_mac_probe(struct platform_device *pdev)
                goto out_err_probe_mac;
        }
 
-       /* set the GPIO pins to Ethernet mode */
-       rc = peripheral_request_list(pin_req, DRV_NAME);
-       if (rc) {
-               dev_err(&pdev->dev, "Requesting peripherals failed!\n");
-               rc = -EFAULT;
-               goto out_err_setup_pin_mux;
-       }
 
        /*
         * Is it valid? (Did bootloader initialize it?)
@@ -1069,26 +1011,14 @@ static int __devinit bfin_mac_probe(struct platform_device *pdev)
 
        setup_mac_addr(ndev->dev_addr);
 
-       /* MDIO bus initial */
-       lp->mii_bus = mdiobus_alloc();
-       if (lp->mii_bus == NULL)
-               goto out_err_mdiobus_alloc;
-
-       lp->mii_bus->priv = ndev;
-       lp->mii_bus->read = bfin_mdiobus_read;
-       lp->mii_bus->write = bfin_mdiobus_write;
-       lp->mii_bus->reset = bfin_mdiobus_reset;
-       lp->mii_bus->name = "bfin_mac_mdio";
-       snprintf(lp->mii_bus->id, MII_BUS_ID_SIZE, "0");
-       lp->mii_bus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL);
-       for (i = 0; i < PHY_MAX_ADDR; ++i)
-               lp->mii_bus->irq[i] = PHY_POLL;
-
-       rc = mdiobus_register(lp->mii_bus);
-       if (rc) {
-               dev_err(&pdev->dev, "Cannot register MDIO bus!\n");
-               goto out_err_mdiobus_register;
+       if (!pdev->dev.platform_data) {
+               dev_err(&pdev->dev, "Cannot get platform device bfin_mii_bus!\n");
+               rc = -ENODEV;
+               goto out_err_probe_mac;
        }
+       pd = pdev->dev.platform_data;
+       lp->mii_bus = platform_get_drvdata(pd);
+       lp->mii_bus->priv = ndev;
 
        rc = mii_probe(ndev);
        if (rc) {
@@ -1107,7 +1037,7 @@ static int __devinit bfin_mac_probe(struct platform_device *pdev)
        /* now, enable interrupts */
        /* register irq handler */
        rc = request_irq(IRQ_MAC_RX, bfin_mac_interrupt,
-                       IRQF_DISABLED | IRQF_SHARED, "EMAC_RX", ndev);
+                       IRQF_DISABLED, "EMAC_RX", ndev);
        if (rc) {
                dev_err(&pdev->dev, "Cannot request Blackfin MAC RX IRQ!\n");
                rc = -EBUSY;
@@ -1130,11 +1060,8 @@ out_err_reg_ndev:
 out_err_request_irq:
 out_err_mii_probe:
        mdiobus_unregister(lp->mii_bus);
-out_err_mdiobus_register:
        mdiobus_free(lp->mii_bus);
-out_err_mdiobus_alloc:
        peripheral_free_list(pin_req);
-out_err_setup_pin_mux:
 out_err_probe_mac:
        platform_set_drvdata(pdev, NULL);
        free_netdev(ndev);
@@ -1149,8 +1076,7 @@ static int __devexit bfin_mac_remove(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, NULL);
 
-       mdiobus_unregister(lp->mii_bus);
-       mdiobus_free(lp->mii_bus);
+       lp->mii_bus->priv = NULL;
 
        unregister_netdev(ndev);
 
@@ -1188,6 +1114,74 @@ static int bfin_mac_resume(struct platform_device *pdev)
 #define bfin_mac_resume NULL
 #endif /* CONFIG_PM */
 
+static int __devinit bfin_mii_bus_probe(struct platform_device *pdev)
+{
+       struct mii_bus *miibus;
+       int rc, i;
+
+       /*
+        * We are setting up a network card,
+        * so set the GPIO pins to Ethernet mode
+        */
+       rc = peripheral_request_list(pin_req, DRV_NAME);
+       if (rc) {
+               dev_err(&pdev->dev, "Requesting peripherals failed!\n");
+               return rc;
+       }
+
+       rc = -ENOMEM;
+       miibus = mdiobus_alloc();
+       if (miibus == NULL)
+               goto out_err_alloc;
+       miibus->read = bfin_mdiobus_read;
+       miibus->write = bfin_mdiobus_write;
+       miibus->reset = bfin_mdiobus_reset;
+
+       miibus->parent = &pdev->dev;
+       miibus->name = "bfin_mii_bus";
+       snprintf(miibus->id, MII_BUS_ID_SIZE, "0");
+       miibus->irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL);
+       if (miibus->irq == NULL)
+               goto out_err_alloc;
+       for (i = 0; i < PHY_MAX_ADDR; ++i)
+               miibus->irq[i] = PHY_POLL;
+
+       rc = mdiobus_register(miibus);
+       if (rc) {
+               dev_err(&pdev->dev, "Cannot register MDIO bus!\n");
+               goto out_err_mdiobus_register;
+       }
+
+       platform_set_drvdata(pdev, miibus);
+       return 0;
+
+out_err_mdiobus_register:
+       mdiobus_free(miibus);
+out_err_alloc:
+       peripheral_free_list(pin_req);
+
+       return rc;
+}
+
+static int __devexit bfin_mii_bus_remove(struct platform_device *pdev)
+{
+       struct mii_bus *miibus = platform_get_drvdata(pdev);
+       platform_set_drvdata(pdev, NULL);
+       mdiobus_unregister(miibus);
+       mdiobus_free(miibus);
+       peripheral_free_list(pin_req);
+       return 0;
+}
+
+static struct platform_driver bfin_mii_bus_driver = {
+       .probe = bfin_mii_bus_probe,
+       .remove = __devexit_p(bfin_mii_bus_remove),
+       .driver = {
+               .name = "bfin_mii_bus",
+               .owner  = THIS_MODULE,
+       },
+};
+
 static struct platform_driver bfin_mac_driver = {
        .probe = bfin_mac_probe,
        .remove = __devexit_p(bfin_mac_remove),
@@ -1201,7 +1195,11 @@ static struct platform_driver bfin_mac_driver = {
 
 static int __init bfin_mac_init(void)
 {
-       return platform_driver_register(&bfin_mac_driver);
+       int ret;
+       ret = platform_driver_register(&bfin_mii_bus_driver);
+       if (!ret)
+               return platform_driver_register(&bfin_mac_driver);
+       return -ENODEV;
 }
 
 module_init(bfin_mac_init);
@@ -1209,6 +1207,7 @@ module_init(bfin_mac_init);
 static void __exit bfin_mac_cleanup(void)
 {
        platform_driver_unregister(&bfin_mac_driver);
+       platform_driver_unregister(&bfin_mii_bus_driver);
 }
 
 module_exit(bfin_mac_cleanup);
index 44d015f70d1c8ff92b30dfb81d17efa118fb9ba4..9578a3dfac01333a696050e0f95abc0aa8c6da46 100644 (file)
@@ -1247,6 +1247,16 @@ static const struct ethtool_ops bmac_ethtool_ops = {
        .get_link               = ethtool_op_get_link,
 };
 
+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_mac_address    = bmac_set_address,
+       .ndo_change_mtu         = eth_change_mtu,
+       .ndo_validate_addr      = eth_validate_addr,
+};
+
 static int __devinit bmac_probe(struct macio_dev *mdev, const struct of_device_id *match)
 {
        int j, rev, ret;
@@ -1308,12 +1318,8 @@ static int __devinit bmac_probe(struct macio_dev *mdev, const struct of_device_i
        bmac_enable_and_reset_chip(dev);
        bmwrite(dev, INTDISABLE, DisableAll);
 
-       dev->open = bmac_open;
-       dev->stop = bmac_close;
+       dev->netdev_ops = &bmac_netdev_ops;
        dev->ethtool_ops = &bmac_ethtool_ops;
-       dev->hard_start_xmit = bmac_output;
-       dev->set_multicast_list = bmac_set_multicast;
-       dev->set_mac_address = bmac_set_address;
 
        bmac_get_station_address(dev, addr);
        if (bmac_verify_checksum(dev) != 0)
index 3f5fcb0156a180a49977f200b7a16fe5e19f6a38..7e3738112c4e64297c00b0c74a7658d9df4a00c8 100644 (file)
@@ -48,6 +48,7 @@
 #include <linux/cache.h>
 #include <linux/firmware.h>
 #include <linux/log2.h>
+#include <linux/list.h>
 
 #if defined(CONFIG_CNIC) || defined(CONFIG_CNIC_MODULE)
 #define BCM_CNIC 1
@@ -703,8 +704,7 @@ bnx2_free_rx_mem(struct bnx2 *bp)
                                                    rxr->rx_desc_mapping[j]);
                        rxr->rx_desc_ring[j] = NULL;
                }
-               if (rxr->rx_buf_ring)
-                       vfree(rxr->rx_buf_ring);
+               vfree(rxr->rx_buf_ring);
                rxr->rx_buf_ring = NULL;
 
                for (j = 0; j < bp->rx_max_pg_ring; j++) {
@@ -714,8 +714,7 @@ bnx2_free_rx_mem(struct bnx2 *bp)
                                                    rxr->rx_pg_desc_mapping[j]);
                        rxr->rx_pg_desc_ring[j] = NULL;
                }
-               if (rxr->rx_pg_ring)
-                       vfree(rxr->rx_pg_ring);
+               vfree(rxr->rx_pg_ring);
                rxr->rx_pg_ring = NULL;
        }
 }
@@ -2788,14 +2787,15 @@ bnx2_tx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
                tx_buf = &txr->tx_buf_ring[sw_ring_cons];
                skb = tx_buf->skb;
 
+               /* prefetch skb_end_pointer() to speedup skb_shinfo(skb) */
+               prefetch(&skb->end);
+
                /* partial BD completions possible with TSO packets */
-               if (skb_is_gso(skb)) {
+               if (tx_buf->is_gso) {
                        u16 last_idx, last_ring_idx;
 
-                       last_idx = sw_cons +
-                               skb_shinfo(skb)->nr_frags + 1;
-                       last_ring_idx = sw_ring_cons +
-                               skb_shinfo(skb)->nr_frags + 1;
+                       last_idx = sw_cons + tx_buf->nr_frags + 1;
+                       last_ring_idx = sw_ring_cons + tx_buf->nr_frags + 1;
                        if (unlikely(last_ring_idx >= MAX_TX_DESC_CNT)) {
                                last_idx++;
                        }
@@ -2807,7 +2807,7 @@ bnx2_tx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
                skb_dma_unmap(&bp->pdev->dev, skb, DMA_TO_DEVICE);
 
                tx_buf->skb = NULL;
-               last = skb_shinfo(skb)->nr_frags;
+               last = tx_buf->nr_frags;
 
                for (i = 0; i < last; i++) {
                        sw_cons = NEXT_TX_BD(sw_cons);
@@ -2820,7 +2820,8 @@ bnx2_tx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
                if (tx_pkt == budget)
                        break;
 
-               hw_cons = bnx2_get_hw_tx_cons(bnapi);
+               if (hw_cons == sw_cons)
+                       hw_cons = bnx2_get_hw_tx_cons(bnapi);
        }
 
        txr->hw_tx_cons = hw_cons;
@@ -3492,7 +3493,7 @@ bnx2_set_rx_mode(struct net_device *dev)
 {
        struct bnx2 *bp = netdev_priv(dev);
        u32 rx_mode, sort_mode;
-       struct dev_addr_list *uc_ptr;
+       struct netdev_hw_addr *ha;
        int i;
 
        if (!netif_running(dev))
@@ -3551,21 +3552,19 @@ bnx2_set_rx_mode(struct net_device *dev)
                sort_mode |= BNX2_RPM_SORT_USER0_MC_HSH_EN;
        }
 
-       uc_ptr = NULL;
        if (dev->uc_count > BNX2_MAX_UNICAST_ADDRESSES) {
                rx_mode |= BNX2_EMAC_RX_MODE_PROMISCUOUS;
                sort_mode |= BNX2_RPM_SORT_USER0_PROM_EN |
                             BNX2_RPM_SORT_USER0_PROM_VLAN;
        } else if (!(dev->flags & IFF_PROMISC)) {
-               uc_ptr = dev->uc_list;
-
                /* Add all entries into to the match filter list */
-               for (i = 0; i < dev->uc_count; i++) {
-                       bnx2_set_mac_addr(bp, uc_ptr->da_addr,
+               i = 0;
+               list_for_each_entry(ha, &dev->uc_list, list) {
+                       bnx2_set_mac_addr(bp, ha->addr,
                                          i + BNX2_START_UNICAST_ADDRESS_INDEX);
                        sort_mode |= (1 <<
                                      (i + BNX2_START_UNICAST_ADDRESS_INDEX));
-                       uc_ptr = uc_ptr->next;
+                       i++;
                }
 
        }
@@ -5673,7 +5672,7 @@ bnx2_run_loopback(struct bnx2 *bp, int loopback_mode)
                dev_kfree_skb(skb);
                return -EIO;
        }
-       map = skb_shinfo(skb)->dma_maps[0];
+       map = skb_shinfo(skb)->dma_head;
 
        REG_WR(bp, BNX2_HC_COMMAND,
               bp->hc_cmd | BNX2_HC_COMMAND_COAL_NOW_WO_INT);
@@ -6353,7 +6352,7 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev)
        }
 
        sp = skb_shinfo(skb);
-       mapping = sp->dma_maps[0];
+       mapping = sp->dma_head;
 
        tx_buf = &txr->tx_buf_ring[ring_prod];
        tx_buf->skb = skb;
@@ -6366,6 +6365,8 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev)
        txbd->tx_bd_vlan_tag_flags = vlan_tag_flags | TX_BD_FLAGS_START;
 
        last_frag = skb_shinfo(skb)->nr_frags;
+       tx_buf->nr_frags = last_frag;
+       tx_buf->is_gso = skb_is_gso(skb);
 
        for (i = 0; i < last_frag; i++) {
                skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
@@ -6375,7 +6376,7 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev)
                txbd = &txr->tx_desc_ring[ring_prod];
 
                len = frag->size;
-               mapping = sp->dma_maps[i + 1];
+               mapping = sp->dma_maps[i];
 
                txbd->tx_bd_haddr_hi = (u64) mapping >> 32;
                txbd->tx_bd_haddr_lo = (u64) mapping & 0xffffffff;
@@ -6394,7 +6395,6 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev)
        mmiowb();
 
        txr->tx_prod = prod;
-       dev->trans_start = jiffies;
 
        if (unlikely(bnx2_tx_avail(bp, txr) <= MAX_SKB_FRAGS)) {
                netif_tx_stop_queue(txq);
index a1ff739bc9b5e5709f6e3093bf516ace7d148515..f1edfaa9e56acd87afd0cb41aa20cd23248f7880 100644 (file)
@@ -6556,6 +6556,8 @@ struct sw_pg {
 
 struct sw_tx_bd {
        struct sk_buff          *skb;
+       unsigned short          is_gso;
+       unsigned short          nr_frags;
 };
 
 #define SW_RXBD_RING_SIZE (sizeof(struct sw_bd) * RX_DESC_CNT)
index a329bee25550ded2b08b6903b889d702037464d6..8678457849f9ff32e5bb7b71c1af55fc43c7824f 100644 (file)
@@ -965,6 +965,21 @@ struct bnx2x {
        int                     gunzip_outlen;
 #define FW_BUF_SIZE                    0x8000
 
+       struct raw_op          *init_ops;
+       /* Init blocks offsets inside init_ops */
+       u16                    *init_ops_offsets;
+       /* Data blob - has 32 bit granularity */
+       u32                    *init_data;
+       /* Zipped PRAM blobs - raw data */
+       const u8               *tsem_int_table_data;
+       const u8               *tsem_pram_data;
+       const u8               *usem_int_table_data;
+       const u8               *usem_pram_data;
+       const u8               *xsem_int_table_data;
+       const u8               *xsem_pram_data;
+       const u8               *csem_int_table_data;
+       const u8               *csem_pram_data;
+        const struct firmware  *firmware;
 };
 
 
diff --git a/drivers/net/bnx2x_fw_file_hdr.h b/drivers/net/bnx2x_fw_file_hdr.h
new file mode 100644 (file)
index 0000000..3f5ee5d
--- /dev/null
@@ -0,0 +1,37 @@
+/* bnx2x_fw_file_hdr.h: FW binary file header structure.
+ *
+ * Copyright (c) 2007-2009 Broadcom Corporation
+ *
+ * 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.
+ *
+ * Maintained by: Eilon Greenstein <eilong@broadcom.com>
+ * Written by: Vladislav Zolotarov <vladz@broadcom.com>
+ * Based on the original idea of John Wright <john.wright@hp.com>.
+ */
+
+#ifndef BNX2X_INIT_FILE_HDR_H
+#define BNX2X_INIT_FILE_HDR_H
+
+struct bnx2x_fw_file_section {
+       __be32 len;
+       __be32 offset;
+};
+
+struct bnx2x_fw_file_hdr {
+       struct bnx2x_fw_file_section init_ops;
+       struct bnx2x_fw_file_section init_ops_offsets;
+       struct bnx2x_fw_file_section init_data;
+       struct bnx2x_fw_file_section tsem_int_table_data;
+       struct bnx2x_fw_file_section tsem_pram_data;
+       struct bnx2x_fw_file_section usem_int_table_data;
+       struct bnx2x_fw_file_section usem_pram_data;
+       struct bnx2x_fw_file_section csem_int_table_data;
+       struct bnx2x_fw_file_section csem_pram_data;
+       struct bnx2x_fw_file_section xsem_int_table_data;
+       struct bnx2x_fw_file_section xsem_pram_data;
+       struct bnx2x_fw_file_section fw_version;
+};
+
+#endif /* BNX2X_INIT_FILE_HDR_H */
index 39ba2936c0c2c93d16a9229597c35a79f6066e34..3ba4d888068f93b5c8b7fb220d0af2f9a48d2e0d 100644 (file)
@@ -1,4 +1,5 @@
 /* bnx2x_init.h: Broadcom Everest network driver.
+ *               Structures and macroes needed during the initialization.
  *
  * Copyright (c) 2007-2009 Broadcom Corporation
  *
@@ -8,6 +9,7 @@
  *
  * Maintained by: Eilon Greenstein <eilong@broadcom.com>
  * Written by: Eliezer Tamir
+ * Modified by: Vladislav Zolotarov <vladz@broadcom.com>
  */
 
 #ifndef BNX2X_INIT_H
 #define OP_WR_64               0x8 /* write 64 bit pattern */
 #define OP_WB                  0x9 /* copy a string using DMAE */
 
-/* Operation specific for E1 */
-#define OP_RD_E1               0xa /* read single register */
-#define OP_WR_E1               0xb /* write single register */
-#define OP_IW_E1               0xc /* write single register using mailbox */
-#define OP_SW_E1               0xd /* copy a string to the device */
-#define OP_SI_E1               0xe /* copy a string using mailbox */
-#define OP_ZR_E1               0xf /* clear memory */
-#define OP_ZP_E1               0x10 /* unzip then copy with DMAE */
-#define OP_WR_64_E1            0x11 /* write 64 bit pattern on E1 */
-#define OP_WB_E1               0x12 /* copy a string using DMAE */
-
-/* Operation specific for E1H */
-#define OP_RD_E1H              0x13 /* read single register */
-#define OP_WR_E1H              0x14 /* write single register */
-#define OP_IW_E1H              0x15 /* write single register using mailbox */
-#define OP_SW_E1H              0x16 /* copy a string to the device */
-#define OP_SI_E1H              0x17 /* copy a string using mailbox */
-#define OP_ZR_E1H              0x18 /* clear memory */
-#define OP_ZP_E1H              0x19 /* unzip then copy with DMAE */
-#define OP_WR_64_E1H           0x1a /* write 64 bit pattern on E1H */
-#define OP_WB_E1H              0x1b /* copy a string using DMAE */
-
 /* FPGA and EMUL specific operations */
-#define OP_WR_EMUL_E1H         0x1c /* write single register on E1H Emul */
-#define OP_WR_EMUL             0x1d /* write single register on Emulation */
-#define OP_WR_FPGA             0x1e /* write single register on FPGA */
-#define OP_WR_ASIC             0x1f /* write single register on ASIC */
+#define OP_WR_EMUL             0xa /* write single register on Emulation */
+#define OP_WR_FPGA             0xb /* write single register on FPGA */
+#define OP_WR_ASIC             0xc /* write single register on ASIC */
+
+/* Init stages */
+#define COMMON_STAGE            0
+#define PORT0_STAGE            1
+#define PORT1_STAGE            2
+/* Never reorder FUNCx stages !!! */
+#define FUNC0_STAGE            3
+#define FUNC1_STAGE            4
+#define FUNC2_STAGE            5
+#define FUNC3_STAGE            6
+#define FUNC4_STAGE            7
+#define FUNC5_STAGE            8
+#define FUNC6_STAGE            9
+#define FUNC7_STAGE            10
+#define STAGE_IDX_MAX          11
+
+#define STAGE_START            0
+#define STAGE_END              1
+
+
+/* Indices of blocks */
+#define PRS_BLOCK               0
+#define SRCH_BLOCK              1
+#define TSDM_BLOCK              2
+#define TCM_BLOCK               3
+#define BRB1_BLOCK              4
+#define TSEM_BLOCK              5
+#define PXPCS_BLOCK             6
+#define EMAC0_BLOCK             7
+#define EMAC1_BLOCK             8
+#define DBU_BLOCK               9
+#define MISC_BLOCK              10
+#define DBG_BLOCK               11
+#define NIG_BLOCK               12
+#define MCP_BLOCK               13
+#define UPB_BLOCK               14
+#define CSDM_BLOCK              15
+#define USDM_BLOCK              16
+#define CCM_BLOCK               17
+#define UCM_BLOCK               18
+#define USEM_BLOCK              19
+#define CSEM_BLOCK              20
+#define XPB_BLOCK               21
+#define DQ_BLOCK                22
+#define TIMERS_BLOCK            23
+#define XSDM_BLOCK              24
+#define QM_BLOCK                25
+#define PBF_BLOCK               26
+#define XCM_BLOCK               27
+#define XSEM_BLOCK              28
+#define CDU_BLOCK               29
+#define DMAE_BLOCK              30
+#define PXP_BLOCK               31
+#define CFC_BLOCK               32
+#define HC_BLOCK                33
+#define PXP2_BLOCK              34
+#define MISC_AEU_BLOCK          35
+
+/* Returns the index of start or end of a specific block stage in ops array*/
+#define BLOCK_OPS_IDX(block, stage, end) \
+       (2*(((block)*STAGE_IDX_MAX) + (stage)) + (end))
 
 
 struct raw_op {
@@ -118,292 +158,6 @@ union init_op {
        struct raw_op           raw;
 };
 
-#include "bnx2x_init_values.h"
-
-static void bnx2x_reg_wr_ind(struct bnx2x *bp, u32 addr, u32 val);
-static int bnx2x_gunzip(struct bnx2x *bp, u8 *zbuf, int len);
-
-static void bnx2x_init_str_wr(struct bnx2x *bp, u32 addr, const u32 *data,
-                             u32 len)
-{
-       int i;
-
-       for (i = 0; i < len; i++) {
-               REG_WR(bp, addr + i*4, data[i]);
-               if (!(i % 10000)) {
-                       touch_softlockup_watchdog();
-                       cpu_relax();
-               }
-       }
-}
-
-static void bnx2x_init_ind_wr(struct bnx2x *bp, u32 addr, const u32 *data,
-                             u16 len)
-{
-       int i;
-
-       for (i = 0; i < len; i++) {
-               REG_WR_IND(bp, addr + i*4, data[i]);
-               if (!(i % 10000)) {
-                       touch_softlockup_watchdog();
-                       cpu_relax();
-               }
-       }
-}
-
-static void bnx2x_write_big_buf(struct bnx2x *bp, u32 addr, u32 len)
-{
-       int offset = 0;
-
-       if (bp->dmae_ready) {
-               while (len > DMAE_LEN32_WR_MAX) {
-                       bnx2x_write_dmae(bp, bp->gunzip_mapping + offset,
-                                        addr + offset, DMAE_LEN32_WR_MAX);
-                       offset += DMAE_LEN32_WR_MAX * 4;
-                       len -= DMAE_LEN32_WR_MAX;
-               }
-               bnx2x_write_dmae(bp, bp->gunzip_mapping + offset,
-                                addr + offset, len);
-       } else
-               bnx2x_init_str_wr(bp, addr, bp->gunzip_buf, len);
-}
-
-static void bnx2x_init_fill(struct bnx2x *bp, u32 addr, int fill, u32 len)
-{
-       u32 buf_len = (((len * 4) > FW_BUF_SIZE) ? FW_BUF_SIZE : (len * 4));
-       u32 buf_len32 = buf_len / 4;
-       int i;
-
-       memset(bp->gunzip_buf, fill, buf_len);
-
-       for (i = 0; i < len; i += buf_len32) {
-               u32 cur_len = min(buf_len32, len - i);
-
-               bnx2x_write_big_buf(bp, addr + i * 4, cur_len);
-       }
-}
-
-static void bnx2x_init_wr_64(struct bnx2x *bp, u32 addr, const u32 *data,
-                            u32 len64)
-{
-       u32 buf_len32 = FW_BUF_SIZE / 4;
-       u32 len = len64 * 2;
-       u64 data64 = 0;
-       int i;
-
-       /* 64 bit value is in a blob: first low DWORD, then high DWORD */
-       data64 = HILO_U64((*(data + 1)), (*data));
-       len64 = min((u32)(FW_BUF_SIZE/8), len64);
-       for (i = 0; i < len64; i++) {
-               u64 *pdata = ((u64 *)(bp->gunzip_buf)) + i;
-
-               *pdata = data64;
-       }
-
-       for (i = 0; i < len; i += buf_len32) {
-               u32 cur_len = min(buf_len32, len - i);
-
-               bnx2x_write_big_buf(bp, addr + i * 4, cur_len);
-       }
-}
-
-/*********************************************************
-   There are different blobs for each PRAM section.
-   In addition, each blob write operation is divided into a few operations
-   in order to decrease the amount of phys. contiguous buffer needed.
-   Thus, when we select a blob the address may be with some offset
-   from the beginning of PRAM section.
-   The same holds for the INT_TABLE sections.
-**********************************************************/
-#define IF_IS_INT_TABLE_ADDR(base, addr) \
-                       if (((base) <= (addr)) && ((base) + 0x400 >= (addr)))
-
-#define IF_IS_PRAM_ADDR(base, addr) \
-                       if (((base) <= (addr)) && ((base) + 0x40000 >= (addr)))
-
-static const u32 *bnx2x_sel_blob(u32 addr, const u32 *data, int is_e1)
-{
-       IF_IS_INT_TABLE_ADDR(TSEM_REG_INT_TABLE, addr)
-               data = is_e1 ? tsem_int_table_data_e1 :
-                              tsem_int_table_data_e1h;
-       else
-               IF_IS_INT_TABLE_ADDR(CSEM_REG_INT_TABLE, addr)
-                       data = is_e1 ? csem_int_table_data_e1 :
-                                      csem_int_table_data_e1h;
-       else
-               IF_IS_INT_TABLE_ADDR(USEM_REG_INT_TABLE, addr)
-                       data = is_e1 ? usem_int_table_data_e1 :
-                                      usem_int_table_data_e1h;
-       else
-               IF_IS_INT_TABLE_ADDR(XSEM_REG_INT_TABLE, addr)
-                       data = is_e1 ? xsem_int_table_data_e1 :
-                                      xsem_int_table_data_e1h;
-       else
-               IF_IS_PRAM_ADDR(TSEM_REG_PRAM, addr)
-                       data = is_e1 ? tsem_pram_data_e1 : tsem_pram_data_e1h;
-       else
-               IF_IS_PRAM_ADDR(CSEM_REG_PRAM, addr)
-                       data = is_e1 ? csem_pram_data_e1 : csem_pram_data_e1h;
-       else
-               IF_IS_PRAM_ADDR(USEM_REG_PRAM, addr)
-                       data = is_e1 ? usem_pram_data_e1 : usem_pram_data_e1h;
-       else
-               IF_IS_PRAM_ADDR(XSEM_REG_PRAM, addr)
-                       data = is_e1 ? xsem_pram_data_e1 : xsem_pram_data_e1h;
-
-       return data;
-}
-
-static void bnx2x_init_wr_wb(struct bnx2x *bp, u32 addr, const u32 *data,
-                            u32 len, int gunzip, int is_e1, u32 blob_off)
-{
-       int offset = 0;
-
-       data = bnx2x_sel_blob(addr, data, is_e1) + blob_off;
-
-       if (gunzip) {
-               int rc;
-#ifdef __BIG_ENDIAN
-               int i, size;
-               u32 *temp;
-
-               temp = kmalloc(len, GFP_KERNEL);
-               size = (len / 4) + ((len % 4) ? 1 : 0);
-               for (i = 0; i < size; i++)
-                       temp[i] = swab32(data[i]);
-               data = temp;
-#endif
-               rc = bnx2x_gunzip(bp, (u8 *)data, len);
-               if (rc) {
-                       BNX2X_ERR("gunzip failed ! rc %d\n", rc);
-#ifdef __BIG_ENDIAN
-                       kfree(temp);
-#endif
-                       return;
-               }
-               len = bp->gunzip_outlen;
-#ifdef __BIG_ENDIAN
-               kfree(temp);
-               for (i = 0; i < len; i++)
-                       ((u32 *)bp->gunzip_buf)[i] =
-                                       swab32(((u32 *)bp->gunzip_buf)[i]);
-#endif
-       } else {
-               if ((len * 4) > FW_BUF_SIZE) {
-                       BNX2X_ERR("LARGE DMAE OPERATION ! "
-                                 "addr 0x%x  len 0x%x\n", addr, len*4);
-                       return;
-               }
-               memcpy(bp->gunzip_buf, data, len * 4);
-       }
-
-       if (bp->dmae_ready) {
-               while (len > DMAE_LEN32_WR_MAX) {
-                       bnx2x_write_dmae(bp, bp->gunzip_mapping + offset,
-                                        addr + offset, DMAE_LEN32_WR_MAX);
-                       offset += DMAE_LEN32_WR_MAX * 4;
-                       len -= DMAE_LEN32_WR_MAX;
-               }
-               bnx2x_write_dmae(bp, bp->gunzip_mapping + offset,
-                                addr + offset, len);
-       } else
-               bnx2x_init_ind_wr(bp, addr, bp->gunzip_buf, len);
-}
-
-static void bnx2x_init_block(struct bnx2x *bp, u32 op_start, u32 op_end)
-{
-       int is_e1       = CHIP_IS_E1(bp);
-       int is_e1h      = CHIP_IS_E1H(bp);
-       int is_emul_e1h = (CHIP_REV_IS_EMUL(bp) && is_e1h);
-       int hw_wr, i;
-       union init_op *op;
-       u32 op_type, addr, len;
-       const u32 *data, *data_base;
-
-       if (CHIP_REV_IS_FPGA(bp))
-               hw_wr = OP_WR_FPGA;
-       else if (CHIP_REV_IS_EMUL(bp))
-               hw_wr = OP_WR_EMUL;
-       else
-               hw_wr = OP_WR_ASIC;
-
-       if (is_e1)
-               data_base = init_data_e1;
-       else /* CHIP_IS_E1H(bp) */
-               data_base = init_data_e1h;
-
-       for (i = op_start; i < op_end; i++) {
-
-               op = (union init_op *)&(init_ops[i]);
-
-               op_type = op->str_wr.op;
-               addr = op->str_wr.offset;
-               len = op->str_wr.data_len;
-               data = data_base + op->str_wr.data_off;
-
-               /* careful! it must be in order */
-               if (unlikely(op_type > OP_WB)) {
-
-                       /* If E1 only */
-                       if (op_type <= OP_WB_E1) {
-                               if (is_e1)
-                                       op_type -= (OP_RD_E1 - OP_RD);
-
-                       /* If E1H only */
-                       } else if (op_type <= OP_WB_E1H) {
-                               if (is_e1h)
-                                       op_type -= (OP_RD_E1H - OP_RD);
-                       }
-
-                       /* HW/EMUL specific */
-                       if (op_type == hw_wr)
-                               op_type = OP_WR;
-
-                       /* EMUL on E1H is special */
-                       if ((op_type == OP_WR_EMUL_E1H) && is_emul_e1h)
-                               op_type = OP_WR;
-               }
-
-               switch (op_type) {
-               case OP_RD:
-                       REG_RD(bp, addr);
-                       break;
-               case OP_WR:
-                       REG_WR(bp, addr, op->write.val);
-                       break;
-               case OP_SW:
-                       bnx2x_init_str_wr(bp, addr, data, len);
-                       break;
-               case OP_WB:
-                       bnx2x_init_wr_wb(bp, addr, data, len, 0, is_e1, 0);
-                       break;
-               case OP_SI:
-                       bnx2x_init_ind_wr(bp, addr, data, len);
-                       break;
-               case OP_ZR:
-                       bnx2x_init_fill(bp, addr, 0, op->zero.len);
-                       break;
-               case OP_ZP:
-                       bnx2x_init_wr_wb(bp, addr, data, len, 1, is_e1,
-                                        op->str_wr.data_off);
-                       break;
-               case OP_WR_64:
-                       bnx2x_init_wr_64(bp, addr, data, len);
-                       break;
-               default:
-                       /* happens whenever an op is of a diff HW */
-#if 0
-                       DP(NETIF_MSG_HW, "skipping init operation  "
-                          "index %d[%d:%d]: type %d  addr 0x%x  "
-                          "len %d(0x%x)\n",
-                          i, op_start, op_end, op_type, addr, len, len);
-#endif
-                       break;
-               }
-       }
-}
-
-
 /****************************************************************************
 * PXP
 ****************************************************************************/
@@ -567,111 +321,6 @@ static const struct arb_line write_arb_addr[NUM_WR_Q-1] = {
                PXP2_REG_RQ_BW_WR_UBOUND30}
 };
 
-static void bnx2x_init_pxp(struct bnx2x *bp)
-{
-       u16 devctl;
-       int r_order, w_order;
-       u32 val, i;
-
-       pci_read_config_word(bp->pdev,
-                            bp->pcie_cap + PCI_EXP_DEVCTL, &devctl);
-       DP(NETIF_MSG_HW, "read 0x%x from devctl\n", devctl);
-       w_order = ((devctl & PCI_EXP_DEVCTL_PAYLOAD) >> 5);
-       if (bp->mrrs == -1)
-               r_order = ((devctl & PCI_EXP_DEVCTL_READRQ) >> 12);
-       else {
-               DP(NETIF_MSG_HW, "force read order to %d\n", bp->mrrs);
-               r_order = bp->mrrs;
-       }
-
-       if (r_order > MAX_RD_ORD) {
-               DP(NETIF_MSG_HW, "read order of %d  order adjusted to %d\n",
-                  r_order, MAX_RD_ORD);
-               r_order = MAX_RD_ORD;
-       }
-       if (w_order > MAX_WR_ORD) {
-               DP(NETIF_MSG_HW, "write order of %d  order adjusted to %d\n",
-                  w_order, MAX_WR_ORD);
-               w_order = MAX_WR_ORD;
-       }
-       if (CHIP_REV_IS_FPGA(bp)) {
-               DP(NETIF_MSG_HW, "write order adjusted to 1 for FPGA\n");
-               w_order = 0;
-       }
-       DP(NETIF_MSG_HW, "read order %d  write order %d\n", r_order, w_order);
-
-       for (i = 0; i < NUM_RD_Q-1; i++) {
-               REG_WR(bp, read_arb_addr[i].l, read_arb_data[i][r_order].l);
-               REG_WR(bp, read_arb_addr[i].add,
-                      read_arb_data[i][r_order].add);
-               REG_WR(bp, read_arb_addr[i].ubound,
-                      read_arb_data[i][r_order].ubound);
-       }
-
-       for (i = 0; i < NUM_WR_Q-1; i++) {
-               if ((write_arb_addr[i].l == PXP2_REG_RQ_BW_WR_L29) ||
-                   (write_arb_addr[i].l == PXP2_REG_RQ_BW_WR_L30)) {
-
-                       REG_WR(bp, write_arb_addr[i].l,
-                              write_arb_data[i][w_order].l);
-
-                       REG_WR(bp, write_arb_addr[i].add,
-                              write_arb_data[i][w_order].add);
-
-                       REG_WR(bp, write_arb_addr[i].ubound,
-                              write_arb_data[i][w_order].ubound);
-               } else {
-
-                       val = REG_RD(bp, write_arb_addr[i].l);
-                       REG_WR(bp, write_arb_addr[i].l,
-                              val | (write_arb_data[i][w_order].l << 10));
-
-                       val = REG_RD(bp, write_arb_addr[i].add);
-                       REG_WR(bp, write_arb_addr[i].add,
-                              val | (write_arb_data[i][w_order].add << 10));
-
-                       val = REG_RD(bp, write_arb_addr[i].ubound);
-                       REG_WR(bp, write_arb_addr[i].ubound,
-                              val | (write_arb_data[i][w_order].ubound << 7));
-               }
-       }
-
-       val =  write_arb_data[NUM_WR_Q-1][w_order].add;
-       val += write_arb_data[NUM_WR_Q-1][w_order].ubound << 10;
-       val += write_arb_data[NUM_WR_Q-1][w_order].l << 17;
-       REG_WR(bp, PXP2_REG_PSWRQ_BW_RD, val);
-
-       val =  read_arb_data[NUM_RD_Q-1][r_order].add;
-       val += read_arb_data[NUM_RD_Q-1][r_order].ubound << 10;
-       val += read_arb_data[NUM_RD_Q-1][r_order].l << 17;
-       REG_WR(bp, PXP2_REG_PSWRQ_BW_WR, val);
-
-       REG_WR(bp, PXP2_REG_RQ_WR_MBS0, w_order);
-       REG_WR(bp, PXP2_REG_RQ_WR_MBS1, w_order);
-       REG_WR(bp, PXP2_REG_RQ_RD_MBS0, r_order);
-       REG_WR(bp, PXP2_REG_RQ_RD_MBS1, r_order);
-
-       if (r_order == MAX_RD_ORD)
-               REG_WR(bp, PXP2_REG_RQ_PDR_LIMIT, 0xe00);
-
-       REG_WR(bp, PXP2_REG_WR_USDMDP_TH, (0x18 << w_order));
-
-       if (CHIP_IS_E1H(bp)) {
-               val = ((w_order == 0) ? 2 : 3);
-               REG_WR(bp, PXP2_REG_WR_HC_MPS, val);
-               REG_WR(bp, PXP2_REG_WR_USDM_MPS, val);
-               REG_WR(bp, PXP2_REG_WR_CSDM_MPS, val);
-               REG_WR(bp, PXP2_REG_WR_TSDM_MPS, val);
-               REG_WR(bp, PXP2_REG_WR_XSDM_MPS, val);
-               REG_WR(bp, PXP2_REG_WR_QM_MPS, val);
-               REG_WR(bp, PXP2_REG_WR_TM_MPS, val);
-               REG_WR(bp, PXP2_REG_WR_SRC_MPS, val);
-               REG_WR(bp, PXP2_REG_WR_DBG_MPS, val);
-               REG_WR(bp, PXP2_REG_WR_DMAE_MPS, 2); /* DMAE is special */
-               REG_WR(bp, PXP2_REG_WR_CDU_MPS, val);
-       }
-}
-
 
 /****************************************************************************
 * CDU
@@ -695,128 +344,12 @@ static void bnx2x_init_pxp(struct bnx2x *bp)
        (0x80 | ((_type) & 0xf << 3) | (CDU_CRC8(_cid, _region, _type) & 0x7))
 #define CDU_RSRVD_INVALIDATE_CONTEXT_VALUE(_val)       ((_val) & ~0x80)
 
-/*****************************************************************************
- * Description:
- *         Calculates crc 8 on a word value: polynomial 0-1-2-8
- *         Code was translated from Verilog.
- ****************************************************************************/
-static u8 calc_crc8(u32 data, u8 crc)
-{
-       u8 D[32];
-       u8 NewCRC[8];
-       u8 C[8];
-       u8 crc_res;
-       u8 i;
-
-       /* split the data into 31 bits */
-       for (i = 0; i < 32; i++) {
-               D[i] = data & 1;
-               data = data >> 1;
-       }
-
-       /* split the crc into 8 bits */
-       for (i = 0; i < 8; i++) {
-               C[i] = crc & 1;
-               crc = crc >> 1;
-       }
-
-       NewCRC[0] = D[31] ^ D[30] ^ D[28] ^ D[23] ^ D[21] ^ D[19] ^ D[18] ^
-               D[16] ^ D[14] ^ D[12] ^ D[8] ^ D[7] ^ D[6] ^ D[0] ^ C[4] ^
-               C[6] ^ C[7];
-       NewCRC[1] = D[30] ^ D[29] ^ D[28] ^ D[24] ^ D[23] ^ D[22] ^ D[21] ^
-               D[20] ^ D[18] ^ D[17] ^ D[16] ^ D[15] ^ D[14] ^ D[13] ^
-               D[12] ^ D[9] ^ D[6] ^ D[1] ^ D[0] ^ C[0] ^ C[4] ^ C[5] ^ C[6];
-       NewCRC[2] = D[29] ^ D[28] ^ D[25] ^ D[24] ^ D[22] ^ D[17] ^ D[15] ^
-               D[13] ^ D[12] ^ D[10] ^ D[8] ^ D[6] ^ D[2] ^ D[1] ^ D[0] ^
-               C[0] ^ C[1] ^ C[4] ^ C[5];
-       NewCRC[3] = D[30] ^ D[29] ^ D[26] ^ D[25] ^ D[23] ^ D[18] ^ D[16] ^
-               D[14] ^ D[13] ^ D[11] ^ D[9] ^ D[7] ^ D[3] ^ D[2] ^ D[1] ^
-               C[1] ^ C[2] ^ C[5] ^ C[6];
-       NewCRC[4] = D[31] ^ D[30] ^ D[27] ^ D[26] ^ D[24] ^ D[19] ^ D[17] ^
-               D[15] ^ D[14] ^ D[12] ^ D[10] ^ D[8] ^ D[4] ^ D[3] ^ D[2] ^
-               C[0] ^ C[2] ^ C[3] ^ C[6] ^ C[7];
-       NewCRC[5] = D[31] ^ D[28] ^ D[27] ^ D[25] ^ D[20] ^ D[18] ^ D[16] ^
-               D[15] ^ D[13] ^ D[11] ^ D[9] ^ D[5] ^ D[4] ^ D[3] ^ C[1] ^
-               C[3] ^ C[4] ^ C[7];
-       NewCRC[6] = D[29] ^ D[28] ^ D[26] ^ D[21] ^ D[19] ^ D[17] ^ D[16] ^
-               D[14] ^ D[12] ^ D[10] ^ D[6] ^ D[5] ^ D[4] ^ C[2] ^ C[4] ^
-               C[5];
-       NewCRC[7] = D[30] ^ D[29] ^ D[27] ^ D[22] ^ D[20] ^ D[18] ^ D[17] ^
-               D[15] ^ D[13] ^ D[11] ^ D[7] ^ D[6] ^ D[5] ^ C[3] ^ C[5] ^
-               C[6];
-
-       crc_res = 0;
-       for (i = 0; i < 8; i++)
-               crc_res |= (NewCRC[i] << i);
-
-       return crc_res;
-}
 
 /* registers addresses are not in order
    so these arrays help simplify the code */
-static const int cm_start[E1H_FUNC_MAX][9] = {
-       {MISC_FUNC0_START, TCM_FUNC0_START, UCM_FUNC0_START, CCM_FUNC0_START,
-        XCM_FUNC0_START, TSEM_FUNC0_START, USEM_FUNC0_START, CSEM_FUNC0_START,
-        XSEM_FUNC0_START},
-       {MISC_FUNC1_START, TCM_FUNC1_START, UCM_FUNC1_START, CCM_FUNC1_START,
-        XCM_FUNC1_START, TSEM_FUNC1_START, USEM_FUNC1_START, CSEM_FUNC1_START,
-        XSEM_FUNC1_START},
-       {MISC_FUNC2_START, TCM_FUNC2_START, UCM_FUNC2_START, CCM_FUNC2_START,
-        XCM_FUNC2_START, TSEM_FUNC2_START, USEM_FUNC2_START, CSEM_FUNC2_START,
-        XSEM_FUNC2_START},
-       {MISC_FUNC3_START, TCM_FUNC3_START, UCM_FUNC3_START, CCM_FUNC3_START,
-        XCM_FUNC3_START, TSEM_FUNC3_START, USEM_FUNC3_START, CSEM_FUNC3_START,
-        XSEM_FUNC3_START},
-       {MISC_FUNC4_START, TCM_FUNC4_START, UCM_FUNC4_START, CCM_FUNC4_START,
-        XCM_FUNC4_START, TSEM_FUNC4_START, USEM_FUNC4_START, CSEM_FUNC4_START,
-        XSEM_FUNC4_START},
-       {MISC_FUNC5_START, TCM_FUNC5_START, UCM_FUNC5_START, CCM_FUNC5_START,
-        XCM_FUNC5_START, TSEM_FUNC5_START, USEM_FUNC5_START, CSEM_FUNC5_START,
-        XSEM_FUNC5_START},
-       {MISC_FUNC6_START, TCM_FUNC6_START, UCM_FUNC6_START, CCM_FUNC6_START,
-        XCM_FUNC6_START, TSEM_FUNC6_START, USEM_FUNC6_START, CSEM_FUNC6_START,
-        XSEM_FUNC6_START},
-       {MISC_FUNC7_START, TCM_FUNC7_START, UCM_FUNC7_START, CCM_FUNC7_START,
-        XCM_FUNC7_START, TSEM_FUNC7_START, USEM_FUNC7_START, CSEM_FUNC7_START,
-        XSEM_FUNC7_START}
-};
-
-static const int cm_end[E1H_FUNC_MAX][9] = {
-       {MISC_FUNC0_END, TCM_FUNC0_END, UCM_FUNC0_END, CCM_FUNC0_END,
-        XCM_FUNC0_END, TSEM_FUNC0_END, USEM_FUNC0_END, CSEM_FUNC0_END,
-        XSEM_FUNC0_END},
-       {MISC_FUNC1_END, TCM_FUNC1_END, UCM_FUNC1_END, CCM_FUNC1_END,
-        XCM_FUNC1_END, TSEM_FUNC1_END, USEM_FUNC1_END, CSEM_FUNC1_END,
-        XSEM_FUNC1_END},
-       {MISC_FUNC2_END, TCM_FUNC2_END, UCM_FUNC2_END, CCM_FUNC2_END,
-        XCM_FUNC2_END, TSEM_FUNC2_END, USEM_FUNC2_END, CSEM_FUNC2_END,
-        XSEM_FUNC2_END},
-       {MISC_FUNC3_END, TCM_FUNC3_END, UCM_FUNC3_END, CCM_FUNC3_END,
-        XCM_FUNC3_END, TSEM_FUNC3_END, USEM_FUNC3_END, CSEM_FUNC3_END,
-        XSEM_FUNC3_END},
-       {MISC_FUNC4_END, TCM_FUNC4_END, UCM_FUNC4_END, CCM_FUNC4_END,
-        XCM_FUNC4_END, TSEM_FUNC4_END, USEM_FUNC4_END, CSEM_FUNC4_END,
-        XSEM_FUNC4_END},
-       {MISC_FUNC5_END, TCM_FUNC5_END, UCM_FUNC5_END, CCM_FUNC5_END,
-        XCM_FUNC5_END, TSEM_FUNC5_END, USEM_FUNC5_END, CSEM_FUNC5_END,
-        XSEM_FUNC5_END},
-       {MISC_FUNC6_END, TCM_FUNC6_END, UCM_FUNC6_END, CCM_FUNC6_END,
-        XCM_FUNC6_END, TSEM_FUNC6_END, USEM_FUNC6_END, CSEM_FUNC6_END,
-        XSEM_FUNC6_END},
-       {MISC_FUNC7_END, TCM_FUNC7_END, UCM_FUNC7_END, CCM_FUNC7_END,
-        XCM_FUNC7_END, TSEM_FUNC7_END, USEM_FUNC7_END, CSEM_FUNC7_END,
-        XSEM_FUNC7_END},
-};
-
-static const int hc_limits[E1H_FUNC_MAX][2] = {
-       {HC_FUNC0_START, HC_FUNC0_END},
-       {HC_FUNC1_START, HC_FUNC1_END},
-       {HC_FUNC2_START, HC_FUNC2_END},
-       {HC_FUNC3_START, HC_FUNC3_END},
-       {HC_FUNC4_START, HC_FUNC4_END},
-       {HC_FUNC5_START, HC_FUNC5_END},
-       {HC_FUNC6_START, HC_FUNC6_END},
-       {HC_FUNC7_START, HC_FUNC7_END}
+static const int cm_blocks[9] = {
+       MISC_BLOCK, TCM_BLOCK,  UCM_BLOCK,  CCM_BLOCK, XCM_BLOCK,
+       TSEM_BLOCK, USEM_BLOCK, CSEM_BLOCK, XSEM_BLOCK
 };
 
 #endif /* BNX2X_INIT_H */
diff --git a/drivers/net/bnx2x_init_ops.h b/drivers/net/bnx2x_init_ops.h
new file mode 100644 (file)
index 0000000..32552b9
--- /dev/null
@@ -0,0 +1,442 @@
+/* bnx2x_init_ops.h: Broadcom Everest network driver.
+ *               Static functions needed during the initialization.
+ *               This file is "included" in bnx2x_main.c.
+ *
+ * Copyright (c) 2007-2009 Broadcom Corporation
+ *
+ * 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.
+ *
+ * Maintained by: Eilon Greenstein <eilong@broadcom.com>
+ * Written by: Vladislav Zolotarov <vladz@broadcom.com>
+ */
+#ifndef BNX2X_INIT_OPS_H
+#define BNX2X_INIT_OPS_H
+
+static void bnx2x_reg_wr_ind(struct bnx2x *bp, u32 addr, u32 val);
+static int bnx2x_gunzip(struct bnx2x *bp, const u8 *zbuf, int len);
+
+static void bnx2x_init_str_wr(struct bnx2x *bp, u32 addr, const u32 *data,
+                             u32 len)
+{
+       int i;
+
+       for (i = 0; i < len; i++) {
+               REG_WR(bp, addr + i*4, data[i]);
+               if (!(i % 10000)) {
+                       touch_softlockup_watchdog();
+                       cpu_relax();
+               }
+       }
+}
+
+static void bnx2x_init_ind_wr(struct bnx2x *bp, u32 addr, const u32 *data,
+                             u16 len)
+{
+       int i;
+
+       for (i = 0; i < len; i++) {
+               REG_WR_IND(bp, addr + i*4, data[i]);
+               if (!(i % 10000)) {
+                       touch_softlockup_watchdog();
+                       cpu_relax();
+               }
+       }
+}
+
+static void bnx2x_write_big_buf(struct bnx2x *bp, u32 addr, u32 len)
+{
+       int offset = 0;
+
+       if (bp->dmae_ready) {
+               while (len > DMAE_LEN32_WR_MAX) {
+                       bnx2x_write_dmae(bp, bp->gunzip_mapping + offset,
+                                        addr + offset, DMAE_LEN32_WR_MAX);
+                       offset += DMAE_LEN32_WR_MAX * 4;
+                       len -= DMAE_LEN32_WR_MAX;
+               }
+               bnx2x_write_dmae(bp, bp->gunzip_mapping + offset,
+                                addr + offset, len);
+       } else
+               bnx2x_init_str_wr(bp, addr, bp->gunzip_buf, len);
+}
+
+static void bnx2x_init_fill(struct bnx2x *bp, u32 addr, int fill, u32 len)
+{
+       u32 buf_len = (((len * 4) > FW_BUF_SIZE) ? FW_BUF_SIZE : (len * 4));
+       u32 buf_len32 = buf_len / 4;
+       int i;
+
+       memset(bp->gunzip_buf, fill, buf_len);
+
+       for (i = 0; i < len; i += buf_len32) {
+               u32 cur_len = min(buf_len32, len - i);
+
+               bnx2x_write_big_buf(bp, addr + i * 4, cur_len);
+       }
+}
+
+static void bnx2x_init_wr_64(struct bnx2x *bp, u32 addr, const u32 *data,
+                            u32 len64)
+{
+       u32 buf_len32 = FW_BUF_SIZE / 4;
+       u32 len = len64 * 2;
+       u64 data64 = 0;
+       int i;
+
+       /* 64 bit value is in a blob: first low DWORD, then high DWORD */
+       data64 = HILO_U64((*(data + 1)), (*data));
+       len64 = min((u32)(FW_BUF_SIZE/8), len64);
+       for (i = 0; i < len64; i++) {
+               u64 *pdata = ((u64 *)(bp->gunzip_buf)) + i;
+
+               *pdata = data64;
+       }
+
+       for (i = 0; i < len; i += buf_len32) {
+               u32 cur_len = min(buf_len32, len - i);
+
+               bnx2x_write_big_buf(bp, addr + i * 4, cur_len);
+       }
+}
+
+/*********************************************************
+   There are different blobs for each PRAM section.
+   In addition, each blob write operation is divided into a few operations
+   in order to decrease the amount of phys. contiguous buffer needed.
+   Thus, when we select a blob the address may be with some offset
+   from the beginning of PRAM section.
+   The same holds for the INT_TABLE sections.
+**********************************************************/
+#define IF_IS_INT_TABLE_ADDR(base, addr) \
+                       if (((base) <= (addr)) && ((base) + 0x400 >= (addr)))
+
+#define IF_IS_PRAM_ADDR(base, addr) \
+                       if (((base) <= (addr)) && ((base) + 0x40000 >= (addr)))
+
+static const u8 *bnx2x_sel_blob(struct bnx2x *bp, u32 addr, const u8 *data)
+{
+       IF_IS_INT_TABLE_ADDR(TSEM_REG_INT_TABLE, addr)
+               data = bp->tsem_int_table_data;
+       else IF_IS_INT_TABLE_ADDR(CSEM_REG_INT_TABLE, addr)
+               data = bp->csem_int_table_data;
+       else IF_IS_INT_TABLE_ADDR(USEM_REG_INT_TABLE, addr)
+               data = bp->usem_int_table_data;
+       else IF_IS_INT_TABLE_ADDR(XSEM_REG_INT_TABLE, addr)
+               data = bp->xsem_int_table_data;
+       else IF_IS_PRAM_ADDR(TSEM_REG_PRAM, addr)
+               data = bp->tsem_pram_data;
+       else IF_IS_PRAM_ADDR(CSEM_REG_PRAM, addr)
+               data = bp->csem_pram_data;
+       else IF_IS_PRAM_ADDR(USEM_REG_PRAM, addr)
+               data = bp->usem_pram_data;
+       else IF_IS_PRAM_ADDR(XSEM_REG_PRAM, addr)
+               data = bp->xsem_pram_data;
+
+       return data;
+}
+
+static void bnx2x_write_big_buf_wb(struct bnx2x *bp, u32 addr, u32 len)
+{
+       int offset = 0;
+
+       if (bp->dmae_ready) {
+               while (len > DMAE_LEN32_WR_MAX) {
+                       bnx2x_write_dmae(bp, bp->gunzip_mapping + offset,
+                                        addr + offset, DMAE_LEN32_WR_MAX);
+                       offset += DMAE_LEN32_WR_MAX * 4;
+                       len -= DMAE_LEN32_WR_MAX;
+               }
+               bnx2x_write_dmae(bp, bp->gunzip_mapping + offset,
+                                addr + offset, len);
+       } else
+               bnx2x_init_ind_wr(bp, addr, bp->gunzip_buf, len);
+}
+
+static void bnx2x_init_wr_wb(struct bnx2x *bp, u32 addr, const u32 *data,
+                            u32 len)
+{
+       /* This is needed for NO_ZIP mode, currently supported
+          in little endian mode only */
+       data = (const u32*)bnx2x_sel_blob(bp, addr, (const u8*)data);
+
+       if ((len * 4) > FW_BUF_SIZE) {
+               BNX2X_ERR("LARGE DMAE OPERATION ! "
+                         "addr 0x%x  len 0x%x\n", addr, len*4);
+               return;
+       }
+       memcpy(bp->gunzip_buf, data, len * 4);
+
+       bnx2x_write_big_buf_wb(bp, addr, len);
+}
+
+static void bnx2x_init_wr_zp(struct bnx2x *bp, u32 addr,
+                            u32 len, u32 blob_off)
+{
+       int rc, i;
+        const u8 *data = NULL;
+
+       data = bnx2x_sel_blob(bp, addr, data) + 4*blob_off;
+
+       if (data == NULL) {
+               panic("Blob not found for addr 0x%x\n", addr);
+               return;
+       }
+
+       rc = bnx2x_gunzip(bp, data, len);
+       if (rc) {
+               BNX2X_ERR("gunzip failed ! addr 0x%x rc %d\n", addr, rc);
+               BNX2X_ERR("blob_offset=0x%x\n", blob_off);
+               return;
+       }
+
+       /* gunzip_outlen is in dwords */
+       len = bp->gunzip_outlen;
+       for (i = 0; i < len; i++)
+               ((u32 *)bp->gunzip_buf)[i] =
+                       cpu_to_le32(((u32 *)bp->gunzip_buf)[i]);
+
+       bnx2x_write_big_buf_wb(bp, addr, len);
+}
+
+static void bnx2x_init_block(struct bnx2x *bp, u32 block, u32 stage)
+{
+       int hw_wr, i;
+       u16 op_start =
+               bp->init_ops_offsets[BLOCK_OPS_IDX(block,stage,STAGE_START)];
+       u16 op_end =
+               bp->init_ops_offsets[BLOCK_OPS_IDX(block,stage,STAGE_END)];
+       union init_op *op;
+       u32 op_type, addr, len;
+       const u32 *data, *data_base;
+
+       /* If empty block */
+       if (op_start == op_end)
+               return;
+
+       if (CHIP_REV_IS_FPGA(bp))
+               hw_wr = OP_WR_FPGA;
+       else if (CHIP_REV_IS_EMUL(bp))
+               hw_wr = OP_WR_EMUL;
+       else
+               hw_wr = OP_WR_ASIC;
+
+       data_base = bp->init_data;
+
+       for (i = op_start; i < op_end; i++) {
+
+               op = (union init_op *)&(bp->init_ops[i]);
+
+               op_type = op->str_wr.op;
+               addr = op->str_wr.offset;
+               len = op->str_wr.data_len;
+               data = data_base + op->str_wr.data_off;
+
+               /* HW/EMUL specific */
+               if (unlikely((op_type > OP_WB) && (op_type == hw_wr)))
+                       op_type = OP_WR;
+
+               switch (op_type) {
+               case OP_RD:
+                       REG_RD(bp, addr);
+                       break;
+               case OP_WR:
+                       REG_WR(bp, addr, op->write.val);
+                       break;
+               case OP_SW:
+                       bnx2x_init_str_wr(bp, addr, data, len);
+                       break;
+               case OP_WB:
+                       bnx2x_init_wr_wb(bp, addr, data, len);
+                       break;
+               case OP_SI:
+                       bnx2x_init_ind_wr(bp, addr, data, len);
+                       break;
+               case OP_ZR:
+                       bnx2x_init_fill(bp, addr, 0, op->zero.len);
+                       break;
+               case OP_ZP:
+                       bnx2x_init_wr_zp(bp, addr, len,
+                                        op->str_wr.data_off);
+                       break;
+               case OP_WR_64:
+                       bnx2x_init_wr_64(bp, addr, data, len);
+                       break;
+               default:
+                       /* happens whenever an op is of a diff HW */
+#if 0
+                       DP(NETIF_MSG_HW, "skipping init operation  "
+                          "index %d[%d:%d]: type %d  addr 0x%x  "
+                          "len %d(0x%x)\n",
+                          i, op_start, op_end, op_type, addr, len, len);
+#endif
+                       break;
+               }
+       }
+}
+
+/* PXP */
+static void bnx2x_init_pxp(struct bnx2x *bp)
+{
+       u16 devctl;
+       int r_order, w_order;
+       u32 val, i;
+
+       pci_read_config_word(bp->pdev,
+                            bp->pcie_cap + PCI_EXP_DEVCTL, &devctl);
+       DP(NETIF_MSG_HW, "read 0x%x from devctl\n", devctl);
+       w_order = ((devctl & PCI_EXP_DEVCTL_PAYLOAD) >> 5);
+       if (bp->mrrs == -1)
+               r_order = ((devctl & PCI_EXP_DEVCTL_READRQ) >> 12);
+       else {
+               DP(NETIF_MSG_HW, "force read order to %d\n", bp->mrrs);
+               r_order = bp->mrrs;
+       }
+
+       if (r_order > MAX_RD_ORD) {
+               DP(NETIF_MSG_HW, "read order of %d  order adjusted to %d\n",
+                  r_order, MAX_RD_ORD);
+               r_order = MAX_RD_ORD;
+       }
+       if (w_order > MAX_WR_ORD) {
+               DP(NETIF_MSG_HW, "write order of %d  order adjusted to %d\n",
+                  w_order, MAX_WR_ORD);
+               w_order = MAX_WR_ORD;
+       }
+       if (CHIP_REV_IS_FPGA(bp)) {
+               DP(NETIF_MSG_HW, "write order adjusted to 1 for FPGA\n");
+               w_order = 0;
+       }
+       DP(NETIF_MSG_HW, "read order %d  write order %d\n", r_order, w_order);
+
+       for (i = 0; i < NUM_RD_Q-1; i++) {
+               REG_WR(bp, read_arb_addr[i].l, read_arb_data[i][r_order].l);
+               REG_WR(bp, read_arb_addr[i].add,
+                      read_arb_data[i][r_order].add);
+               REG_WR(bp, read_arb_addr[i].ubound,
+                      read_arb_data[i][r_order].ubound);
+       }
+
+       for (i = 0; i < NUM_WR_Q-1; i++) {
+               if ((write_arb_addr[i].l == PXP2_REG_RQ_BW_WR_L29) ||
+                   (write_arb_addr[i].l == PXP2_REG_RQ_BW_WR_L30)) {
+
+                       REG_WR(bp, write_arb_addr[i].l,
+                              write_arb_data[i][w_order].l);
+
+                       REG_WR(bp, write_arb_addr[i].add,
+                              write_arb_data[i][w_order].add);
+
+                       REG_WR(bp, write_arb_addr[i].ubound,
+                              write_arb_data[i][w_order].ubound);
+               } else {
+
+                       val = REG_RD(bp, write_arb_addr[i].l);
+                       REG_WR(bp, write_arb_addr[i].l,
+                              val | (write_arb_data[i][w_order].l << 10));
+
+                       val = REG_RD(bp, write_arb_addr[i].add);
+                       REG_WR(bp, write_arb_addr[i].add,
+                              val | (write_arb_data[i][w_order].add << 10));
+
+                       val = REG_RD(bp, write_arb_addr[i].ubound);
+                       REG_WR(bp, write_arb_addr[i].ubound,
+                              val | (write_arb_data[i][w_order].ubound << 7));
+               }
+       }
+
+       val =  write_arb_data[NUM_WR_Q-1][w_order].add;
+       val += write_arb_data[NUM_WR_Q-1][w_order].ubound << 10;
+       val += write_arb_data[NUM_WR_Q-1][w_order].l << 17;
+       REG_WR(bp, PXP2_REG_PSWRQ_BW_RD, val);
+
+       val =  read_arb_data[NUM_RD_Q-1][r_order].add;
+       val += read_arb_data[NUM_RD_Q-1][r_order].ubound << 10;
+       val += read_arb_data[NUM_RD_Q-1][r_order].l << 17;
+       REG_WR(bp, PXP2_REG_PSWRQ_BW_WR, val);
+
+       REG_WR(bp, PXP2_REG_RQ_WR_MBS0, w_order);
+       REG_WR(bp, PXP2_REG_RQ_WR_MBS1, w_order);
+       REG_WR(bp, PXP2_REG_RQ_RD_MBS0, r_order);
+       REG_WR(bp, PXP2_REG_RQ_RD_MBS1, r_order);
+
+       if (r_order == MAX_RD_ORD)
+               REG_WR(bp, PXP2_REG_RQ_PDR_LIMIT, 0xe00);
+
+       REG_WR(bp, PXP2_REG_WR_USDMDP_TH, (0x18 << w_order));
+
+       if (CHIP_IS_E1H(bp)) {
+               val = ((w_order == 0) ? 2 : 3);
+               REG_WR(bp, PXP2_REG_WR_HC_MPS, val);
+               REG_WR(bp, PXP2_REG_WR_USDM_MPS, val);
+               REG_WR(bp, PXP2_REG_WR_CSDM_MPS, val);
+               REG_WR(bp, PXP2_REG_WR_TSDM_MPS, val);
+               REG_WR(bp, PXP2_REG_WR_XSDM_MPS, val);
+               REG_WR(bp, PXP2_REG_WR_QM_MPS, val);
+               REG_WR(bp, PXP2_REG_WR_TM_MPS, val);
+               REG_WR(bp, PXP2_REG_WR_SRC_MPS, val);
+               REG_WR(bp, PXP2_REG_WR_DBG_MPS, val);
+               REG_WR(bp, PXP2_REG_WR_DMAE_MPS, 2); /* DMAE is special */
+               REG_WR(bp, PXP2_REG_WR_CDU_MPS, val);
+       }
+}
+
+/*****************************************************************************
+ * Description:
+ *         Calculates crc 8 on a word value: polynomial 0-1-2-8
+ *         Code was translated from Verilog.
+ ****************************************************************************/
+static u8 calc_crc8(u32 data, u8 crc)
+{
+       u8 D[32];
+       u8 NewCRC[8];
+       u8 C[8];
+       u8 crc_res;
+       u8 i;
+
+       /* split the data into 31 bits */
+       for (i = 0; i < 32; i++) {
+               D[i] = data & 1;
+               data = data >> 1;
+       }
+
+       /* split the crc into 8 bits */
+       for (i = 0; i < 8; i++) {
+               C[i] = crc & 1;
+               crc = crc >> 1;
+       }
+
+       NewCRC[0] = D[31] ^ D[30] ^ D[28] ^ D[23] ^ D[21] ^ D[19] ^ D[18] ^
+               D[16] ^ D[14] ^ D[12] ^ D[8] ^ D[7] ^ D[6] ^ D[0] ^ C[4] ^
+               C[6] ^ C[7];
+       NewCRC[1] = D[30] ^ D[29] ^ D[28] ^ D[24] ^ D[23] ^ D[22] ^ D[21] ^
+               D[20] ^ D[18] ^ D[17] ^ D[16] ^ D[15] ^ D[14] ^ D[13] ^
+               D[12] ^ D[9] ^ D[6] ^ D[1] ^ D[0] ^ C[0] ^ C[4] ^ C[5] ^ C[6];
+       NewCRC[2] = D[29] ^ D[28] ^ D[25] ^ D[24] ^ D[22] ^ D[17] ^ D[15] ^
+               D[13] ^ D[12] ^ D[10] ^ D[8] ^ D[6] ^ D[2] ^ D[1] ^ D[0] ^
+               C[0] ^ C[1] ^ C[4] ^ C[5];
+       NewCRC[3] = D[30] ^ D[29] ^ D[26] ^ D[25] ^ D[23] ^ D[18] ^ D[16] ^
+               D[14] ^ D[13] ^ D[11] ^ D[9] ^ D[7] ^ D[3] ^ D[2] ^ D[1] ^
+               C[1] ^ C[2] ^ C[5] ^ C[6];
+       NewCRC[4] = D[31] ^ D[30] ^ D[27] ^ D[26] ^ D[24] ^ D[19] ^ D[17] ^
+               D[15] ^ D[14] ^ D[12] ^ D[10] ^ D[8] ^ D[4] ^ D[3] ^ D[2] ^
+               C[0] ^ C[2] ^ C[3] ^ C[6] ^ C[7];
+       NewCRC[5] = D[31] ^ D[28] ^ D[27] ^ D[25] ^ D[20] ^ D[18] ^ D[16] ^
+               D[15] ^ D[13] ^ D[11] ^ D[9] ^ D[5] ^ D[4] ^ D[3] ^ C[1] ^
+               C[3] ^ C[4] ^ C[7];
+       NewCRC[6] = D[29] ^ D[28] ^ D[26] ^ D[21] ^ D[19] ^ D[17] ^ D[16] ^
+               D[14] ^ D[12] ^ D[10] ^ D[6] ^ D[5] ^ D[4] ^ C[2] ^ C[4] ^
+               C[5];
+       NewCRC[7] = D[30] ^ D[29] ^ D[27] ^ D[22] ^ D[20] ^ D[18] ^ D[17] ^
+               D[15] ^ D[13] ^ D[11] ^ D[7] ^ D[6] ^ D[5] ^ C[3] ^ C[5] ^
+               C[6];
+
+       crc_res = 0;
+       for (i = 0; i < 8; i++)
+               crc_res |= (NewCRC[i] << i);
+
+       return crc_res;
+}
+
+#endif /* BNX2X_INIT_OPS_H */
diff --git a/drivers/net/bnx2x_init_values.h b/drivers/net/bnx2x_init_values.h
deleted file mode 100644 (file)
index 1f22c9a..0000000
+++ /dev/null
@@ -1,16322 +0,0 @@
-#ifndef __BNX2X_INIT_VALUES_H__
-#define __BNX2X_INIT_VALUES_H__
-
-/* bnx2x_init_values.h: Broadcom NX2 10G network driver.
- *
- * Copyright (c) 2007-2009 Broadcom Corporation
- *
- * 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, except as noted below.
- *
- * This file contains firmware data derived from proprietary unpublished
- * source code, Copyright (c) 2007-2009 Broadcom Corporation.
- *
- * Permission is hereby granted for the distribution of this firmware data
- * in hexadecimal or equivalent format, provided this copyright notice is
- * accompanying it.
- *
- *
- * This array contains the list of operations needed to initialize the chip.
- *
- * For each block in the chip there are three init stages:
- * common - HW used by both ports,
- * port1 and port2 - initialization for a specific Ethernet port.
- * When a port is opened or closed, the management CPU tells the driver
- * whether to init/disable common HW in addition to the port HW.
- * This way the first port going up will first initializes the common HW,
- * and the last port going down also resets the common HW
- *
- * For each init stage/block there is a list of actions needed in a format:
- * {operation, register, data}
- * where:
- * OP_WR - write a value to the chip.
- * OP_RD - read a register (usually a clear on read register).
- * OP_SW - string write, write a section of consecutive addresses to the chip.
- * OP_SI - copy a string using indirect writes.
- * OP_ZR - clear a range of memory.
- * OP_ZP - unzip and copy using DMAE.
- * OP_WB - string copy using DMAE.
- *
- * The #defines mark the stages.
- *
- */
-
-static const struct raw_op init_ops[] = {
-#define PRS_COMMON_START        0
-       {OP_WR, PRS_REG_INC_VALUE, 0xf},
-       {OP_WR, PRS_REG_EVENT_ID_1, 0x45},
-       {OP_WR, PRS_REG_EVENT_ID_2, 0x84},
-       {OP_WR, PRS_REG_EVENT_ID_3, 0x6},
-       {OP_WR, PRS_REG_NO_MATCH_EVENT_ID, 0x4},
-       {OP_WR, PRS_REG_CM_HDR_TYPE_0, 0x0},
-       {OP_WR, PRS_REG_CM_HDR_TYPE_1, 0x12170000},
-       {OP_WR, PRS_REG_CM_HDR_TYPE_2, 0x22170000},
-       {OP_WR, PRS_REG_CM_HDR_TYPE_3, 0x32170000},
-       {OP_ZR, PRS_REG_CM_HDR_TYPE_4, 0x5},
-       {OP_WR, PRS_REG_CM_HDR_LOOPBACK_TYPE_1, 0x12150000},
-       {OP_WR, PRS_REG_CM_HDR_LOOPBACK_TYPE_2, 0x22150000},
-       {OP_WR, PRS_REG_CM_HDR_LOOPBACK_TYPE_3, 0x32150000},
-       {OP_ZR, PRS_REG_CM_HDR_LOOPBACK_TYPE_4, 0x4},
-       {OP_WR, PRS_REG_CM_NO_MATCH_HDR, 0x2100000},
-       {OP_WR, PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_0, 0x100000},
-       {OP_WR, PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_1, 0x10100000},
-       {OP_WR, PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_2, 0x20100000},
-       {OP_WR, PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_3, 0x30100000},
-       {OP_ZR_E1, PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_4, 0x4},
-       {OP_WR_E1H, PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_4, 0x40100000},
-       {OP_ZR_E1H, PRS_REG_CM_HDR_FLUSH_NO_LOAD_TYPE_5, 0x3},
-       {OP_WR, PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_0, 0x100000},
-       {OP_WR, PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_1, 0x12140000},
-       {OP_WR, PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_2, 0x22140000},
-       {OP_WR, PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_3, 0x32140000},
-       {OP_ZR_E1, PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_4, 0x4},
-       {OP_WR_E1H, PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_4, 0x42140000},
-       {OP_ZR_E1H, PRS_REG_CM_HDR_FLUSH_LOAD_TYPE_5, 0x3},
-       {OP_RD, PRS_REG_NUM_OF_PACKETS, 0x0},
-       {OP_RD, PRS_REG_NUM_OF_CFC_FLUSH_MESSAGES, 0x0},
-       {OP_RD, PRS_REG_NUM_OF_TRANSPARENT_FLUSH_MESSAGES, 0x0},
-       {OP_RD, PRS_REG_NUM_OF_DEAD_CYCLES, 0x0},
-       {OP_WR_E1H, PRS_REG_FCOE_TYPE, 0x8906},
-       {OP_WR, PRS_REG_FLUSH_REGIONS_TYPE_0, 0xff},
-       {OP_WR, PRS_REG_FLUSH_REGIONS_TYPE_1, 0xff},
-       {OP_WR, PRS_REG_FLUSH_REGIONS_TYPE_2, 0xff},
-       {OP_WR, PRS_REG_FLUSH_REGIONS_TYPE_3, 0xff},
-       {OP_WR, PRS_REG_FLUSH_REGIONS_TYPE_4, 0xff},
-       {OP_WR, PRS_REG_FLUSH_REGIONS_TYPE_5, 0xff},
-       {OP_WR, PRS_REG_FLUSH_REGIONS_TYPE_6, 0xff},
-       {OP_WR, PRS_REG_FLUSH_REGIONS_TYPE_7, 0xff},
-       {OP_WR, PRS_REG_PURE_REGIONS, 0x3e},
-       {OP_WR, PRS_REG_PACKET_REGIONS_TYPE_0, 0x0},
-       {OP_WR, PRS_REG_PACKET_REGIONS_TYPE_1, 0x3f},
-       {OP_WR, PRS_REG_PACKET_REGIONS_TYPE_2, 0x3f},
-       {OP_WR, PRS_REG_PACKET_REGIONS_TYPE_3, 0x3f},
-       {OP_WR_E1, PRS_REG_PACKET_REGIONS_TYPE_4, 0x0},
-       {OP_WR_E1H, PRS_REG_PACKET_REGIONS_TYPE_4, 0x3f},
-       {OP_WR, PRS_REG_PACKET_REGIONS_TYPE_5, 0x3f},
-       {OP_WR, PRS_REG_PACKET_REGIONS_TYPE_6, 0x3f},
-       {OP_WR, PRS_REG_PACKET_REGIONS_TYPE_7, 0x3f},
-#define PRS_COMMON_END          52
-#define SRCH_COMMON_START       52
-       {OP_WR_E1H, SRC_REG_E1HMF_ENABLE, 0x1},
-#define SRCH_COMMON_END         53
-#define TSDM_COMMON_START       53
-       {OP_WR_E1, TSDM_REG_CFC_RSP_START_ADDR, 0x411},
-       {OP_WR_E1H, TSDM_REG_CFC_RSP_START_ADDR, 0x211},
-       {OP_WR_E1, TSDM_REG_CMP_COUNTER_START_ADDR, 0x400},
-       {OP_WR_E1H, TSDM_REG_CMP_COUNTER_START_ADDR, 0x200},
-       {OP_WR_E1, TSDM_REG_Q_COUNTER_START_ADDR, 0x404},
-       {OP_WR_E1H, TSDM_REG_Q_COUNTER_START_ADDR, 0x204},
-       {OP_WR_E1, TSDM_REG_PCK_END_MSG_START_ADDR, 0x419},
-       {OP_WR_E1H, TSDM_REG_PCK_END_MSG_START_ADDR, 0x219},
-       {OP_WR, TSDM_REG_CMP_COUNTER_MAX0, 0xffff},
-       {OP_WR, TSDM_REG_CMP_COUNTER_MAX1, 0xffff},
-       {OP_WR, TSDM_REG_CMP_COUNTER_MAX2, 0xffff},
-       {OP_WR, TSDM_REG_CMP_COUNTER_MAX3, 0xffff},
-       {OP_ZR_E1, TSDM_REG_AGG_INT_EVENT_0, 0x2},
-       {OP_WR_E1H, TSDM_REG_AGG_INT_EVENT_0, 0x20},
-       {OP_WR_E1H, TSDM_REG_AGG_INT_EVENT_1, 0x0},
-       {OP_WR, TSDM_REG_AGG_INT_EVENT_2, 0x34},
-       {OP_WR, TSDM_REG_AGG_INT_EVENT_3, 0x35},
-       {OP_ZR_E1, TSDM_REG_AGG_INT_EVENT_4, 0x7c},
-       {OP_ZR_E1H, TSDM_REG_AGG_INT_EVENT_4, 0x1c},
-       {OP_WR_E1H, TSDM_REG_AGG_INT_T_0, 0x1},
-       {OP_ZR_E1H, TSDM_REG_AGG_INT_T_1, 0x5f},
-       {OP_WR, TSDM_REG_ENABLE_IN1, 0x7ffffff},
-       {OP_WR, TSDM_REG_ENABLE_IN2, 0x3f},
-       {OP_WR, TSDM_REG_ENABLE_OUT1, 0x7ffffff},
-       {OP_WR, TSDM_REG_ENABLE_OUT2, 0xf},
-       {OP_RD, TSDM_REG_NUM_OF_Q0_CMD, 0x0},
-       {OP_RD, TSDM_REG_NUM_OF_Q1_CMD, 0x0},
-       {OP_RD, TSDM_REG_NUM_OF_Q3_CMD, 0x0},
-       {OP_RD, TSDM_REG_NUM_OF_Q4_CMD, 0x0},
-       {OP_RD, TSDM_REG_NUM_OF_Q5_CMD, 0x0},
-       {OP_RD, TSDM_REG_NUM_OF_Q6_CMD, 0x0},
-       {OP_RD, TSDM_REG_NUM_OF_Q7_CMD, 0x0},
-       {OP_RD, TSDM_REG_NUM_OF_Q8_CMD, 0x0},
-       {OP_RD, TSDM_REG_NUM_OF_Q9_CMD, 0x0},
-       {OP_RD, TSDM_REG_NUM_OF_Q10_CMD, 0x0},
-       {OP_RD, TSDM_REG_NUM_OF_Q11_CMD, 0x0},
-       {OP_RD, TSDM_REG_NUM_OF_PKT_END_MSG, 0x0},
-       {OP_RD, TSDM_REG_NUM_OF_PXP_ASYNC_REQ, 0x0},
-       {OP_RD, TSDM_REG_NUM_OF_ACK_AFTER_PLACE, 0x0},
-       {OP_WR_E1, TSDM_REG_INIT_CREDIT_PXP_CTRL, 0x1},
-       {OP_WR_ASIC, TSDM_REG_TIMER_TICK, 0x3e8},
-       {OP_WR_EMUL, TSDM_REG_TIMER_TICK, 0x1},
-       {OP_WR_FPGA, TSDM_REG_TIMER_TICK, 0xa},
-#define TSDM_COMMON_END         96
-#define TCM_COMMON_START        96
-       {OP_WR, TCM_REG_XX_MAX_LL_SZ, 0x20},
-       {OP_WR, TCM_REG_XX_OVFL_EVNT_ID, 0x32},
-       {OP_WR, TCM_REG_TQM_TCM_HDR_P, 0x2150020},
-       {OP_WR, TCM_REG_TQM_TCM_HDR_S, 0x2150020},
-       {OP_WR, TCM_REG_TM_TCM_HDR, 0x30},
-       {OP_WR, TCM_REG_ERR_TCM_HDR, 0x8100000},
-       {OP_WR, TCM_REG_ERR_EVNT_ID, 0x33},
-       {OP_WR, TCM_REG_EXPR_EVNT_ID, 0x30},
-       {OP_WR, TCM_REG_STOP_EVNT_ID, 0x31},
-       {OP_WR, TCM_REG_STORM_WEIGHT, 0x2},
-       {OP_WR, TCM_REG_PRS_WEIGHT, 0x5},
-       {OP_WR, TCM_REG_PBF_WEIGHT, 0x6},
-       {OP_WR, TCM_REG_USEM_WEIGHT, 0x2},
-       {OP_WR, TCM_REG_CSEM_WEIGHT, 0x2},
-       {OP_WR, TCM_REG_CP_WEIGHT, 0x0},
-       {OP_WR, TCM_REG_TSDM_WEIGHT, 0x5},
-       {OP_WR, TCM_REG_TQM_P_WEIGHT, 0x2},
-       {OP_WR, TCM_REG_TQM_S_WEIGHT, 0x2},
-       {OP_WR, TCM_REG_TM_WEIGHT, 0x2},
-       {OP_WR, TCM_REG_TCM_TQM_USE_Q, 0x1},
-       {OP_WR, TCM_REG_GR_ARB_TYPE, 0x1},
-       {OP_WR, TCM_REG_GR_LD0_PR, 0x1},
-       {OP_WR, TCM_REG_GR_LD1_PR, 0x2},
-       {OP_WR, TCM_REG_CFC_INIT_CRD, 0x1},
-       {OP_WR, TCM_REG_FIC0_INIT_CRD, 0x40},
-       {OP_WR, TCM_REG_FIC1_INIT_CRD, 0x40},
-       {OP_WR, TCM_REG_TQM_INIT_CRD, 0x20},
-       {OP_WR, TCM_REG_XX_INIT_CRD, 0x13},
-       {OP_WR, TCM_REG_XX_MSG_NUM, 0x20},
-       {OP_ZR, TCM_REG_XX_TABLE, 0xa},
-       {OP_SW, TCM_REG_XX_DESCR_TABLE, 0x200000},
-       {OP_WR, TCM_REG_N_SM_CTX_LD_0, 0x7},
-       {OP_WR, TCM_REG_N_SM_CTX_LD_1, 0x7},
-       {OP_WR, TCM_REG_N_SM_CTX_LD_2, 0x8},
-       {OP_WR, TCM_REG_N_SM_CTX_LD_3, 0x8},
-       {OP_ZR_E1, TCM_REG_N_SM_CTX_LD_4, 0x4},
-       {OP_WR_E1H, TCM_REG_N_SM_CTX_LD_4, 0x1},
-       {OP_ZR_E1H, TCM_REG_N_SM_CTX_LD_5, 0x3},
-       {OP_WR, TCM_REG_TCM_REG0_SZ, 0x6},
-       {OP_WR_E1, TCM_REG_PHYS_QNUM0_0, 0xd},
-       {OP_WR_E1, TCM_REG_PHYS_QNUM0_1, 0x2d},
-       {OP_WR_E1, TCM_REG_PHYS_QNUM1_0, 0x7},
-       {OP_WR_E1, TCM_REG_PHYS_QNUM1_1, 0x27},
-       {OP_WR_E1, TCM_REG_PHYS_QNUM2_0, 0x7},
-       {OP_WR_E1, TCM_REG_PHYS_QNUM2_1, 0x27},
-       {OP_WR_E1, TCM_REG_PHYS_QNUM3_0, 0x7},
-       {OP_WR_E1, TCM_REG_PHYS_QNUM3_1, 0x27},
-       {OP_WR, TCM_REG_TCM_STORM0_IFEN, 0x1},
-       {OP_WR, TCM_REG_TCM_STORM1_IFEN, 0x1},
-       {OP_WR, TCM_REG_TCM_TQM_IFEN, 0x1},
-       {OP_WR, TCM_REG_STORM_TCM_IFEN, 0x1},
-       {OP_WR, TCM_REG_TQM_TCM_IFEN, 0x1},
-       {OP_WR, TCM_REG_TSDM_IFEN, 0x1},
-       {OP_WR, TCM_REG_TM_TCM_IFEN, 0x1},
-       {OP_WR, TCM_REG_PRS_IFEN, 0x1},
-       {OP_WR, TCM_REG_PBF_IFEN, 0x1},
-       {OP_WR, TCM_REG_USEM_IFEN, 0x1},
-       {OP_WR, TCM_REG_CSEM_IFEN, 0x1},
-       {OP_WR, TCM_REG_CDU_AG_WR_IFEN, 0x1},
-       {OP_WR, TCM_REG_CDU_AG_RD_IFEN, 0x1},
-       {OP_WR, TCM_REG_CDU_SM_WR_IFEN, 0x1},
-       {OP_WR, TCM_REG_CDU_SM_RD_IFEN, 0x1},
-       {OP_WR, TCM_REG_TCM_CFC_IFEN, 0x1},
-#define TCM_COMMON_END          159
-#define TCM_FUNC0_START         159
-       {OP_WR_E1H, TCM_REG_PHYS_QNUM0_0, 0xd},
-       {OP_WR_E1H, TCM_REG_PHYS_QNUM1_0, 0x7},
-       {OP_WR_E1H, TCM_REG_PHYS_QNUM2_0, 0x7},
-       {OP_WR_E1H, TCM_REG_PHYS_QNUM3_0, 0x7},
-#define TCM_FUNC0_END           163
-#define TCM_FUNC1_START         163
-       {OP_WR_E1H, TCM_REG_PHYS_QNUM0_1, 0x2d},
-       {OP_WR_E1H, TCM_REG_PHYS_QNUM1_1, 0x27},
-       {OP_WR_E1H, TCM_REG_PHYS_QNUM2_1, 0x27},
-       {OP_WR_E1H, TCM_REG_PHYS_QNUM3_1, 0x27},
-#define TCM_FUNC1_END           167
-#define TCM_FUNC2_START         167
-       {OP_WR_E1H, TCM_REG_PHYS_QNUM0_0, 0x1d},
-       {OP_WR_E1H, TCM_REG_PHYS_QNUM1_0, 0x17},
-       {OP_WR_E1H, TCM_REG_PHYS_QNUM2_0, 0x17},
-       {OP_WR_E1H, TCM_REG_PHYS_QNUM3_0, 0x17},
-#define TCM_FUNC2_END           171
-#define TCM_FUNC3_START         171
-       {OP_WR_E1H, TCM_REG_PHYS_QNUM0_1, 0x3d},
-       {OP_WR_E1H, TCM_REG_PHYS_QNUM1_1, 0x37},
-       {OP_WR_E1H, TCM_REG_PHYS_QNUM2_1, 0x37},
-       {OP_WR_E1H, TCM_REG_PHYS_QNUM3_1, 0x37},
-#define TCM_FUNC3_END           175
-#define TCM_FUNC4_START         175
-       {OP_WR_E1H, TCM_REG_PHYS_QNUM0_0, 0x4d},
-       {OP_WR_E1H, TCM_REG_PHYS_QNUM1_0, 0x47},
-       {OP_WR_E1H, TCM_REG_PHYS_QNUM2_0, 0x47},
-       {OP_WR_E1H, TCM_REG_PHYS_QNUM3_0, 0x47},
-#define TCM_FUNC4_END           179
-#define TCM_FUNC5_START         179
-       {OP_WR_E1H, TCM_REG_PHYS_QNUM0_1, 0x6d},
-       {OP_WR_E1H, TCM_REG_PHYS_QNUM1_1, 0x67},
-       {OP_WR_E1H, TCM_REG_PHYS_QNUM2_1, 0x67},
-       {OP_WR_E1H, TCM_REG_PHYS_QNUM3_1, 0x67},
-#define TCM_FUNC5_END           183
-#define TCM_FUNC6_START         183
-       {OP_WR_E1H, TCM_REG_PHYS_QNUM0_0, 0x5d},
-       {OP_WR_E1H, TCM_REG_PHYS_QNUM1_0, 0x57},
-       {OP_WR_E1H, TCM_REG_PHYS_QNUM2_0, 0x57},
-       {OP_WR_E1H, TCM_REG_PHYS_QNUM3_0, 0x57},
-#define TCM_FUNC6_END           187
-#define TCM_FUNC7_START         187
-       {OP_WR_E1H, TCM_REG_PHYS_QNUM0_1, 0x7d},
-       {OP_WR_E1H, TCM_REG_PHYS_QNUM1_1, 0x77},
-       {OP_WR_E1H, TCM_REG_PHYS_QNUM2_1, 0x77},
-       {OP_WR_E1H, TCM_REG_PHYS_QNUM3_1, 0x77},
-#define TCM_FUNC7_END           191
-#define BRB1_COMMON_START       191
-       {OP_SW, BRB1_REG_LL_RAM, 0x2000020},
-       {OP_WR, BRB1_REG_SOFT_RESET, 0x1},
-       {OP_RD, BRB1_REG_NUM_OF_FULL_CYCLES_4, 0x0},
-       {OP_SW, BRB1_REG_FREE_LIST_PRS_CRDT, 0x30220},
-       {OP_WR, BRB1_REG_SOFT_RESET, 0x0},
-#define BRB1_COMMON_END         196
-#define BRB1_PORT0_START        196
-       {OP_WR_E1, BRB1_REG_PAUSE_LOW_THRESHOLD_0, 0xb8},
-       {OP_WR_E1, BRB1_REG_PAUSE_HIGH_THRESHOLD_0, 0x114},
-       {OP_RD, BRB1_REG_NUM_OF_PAUSE_CYCLES_0, 0x0},
-       {OP_RD, BRB1_REG_NUM_OF_FULL_CYCLES_0, 0x0},
-#define BRB1_PORT0_END          200
-#define BRB1_PORT1_START        200
-       {OP_WR_E1, BRB1_REG_PAUSE_LOW_THRESHOLD_1, 0xb8},
-       {OP_WR_E1, BRB1_REG_PAUSE_HIGH_THRESHOLD_1, 0x114},
-       {OP_RD, BRB1_REG_NUM_OF_PAUSE_CYCLES_1, 0x0},
-       {OP_RD, BRB1_REG_NUM_OF_FULL_CYCLES_1, 0x0},
-#define BRB1_PORT1_END          204
-#define TSEM_COMMON_START       204
-       {OP_RD, TSEM_REG_MSG_NUM_FIC0, 0x0},
-       {OP_RD, TSEM_REG_MSG_NUM_FIC1, 0x0},
-       {OP_RD, TSEM_REG_MSG_NUM_FOC0, 0x0},
-       {OP_RD, TSEM_REG_MSG_NUM_FOC1, 0x0},
-       {OP_RD, TSEM_REG_MSG_NUM_FOC2, 0x0},
-       {OP_RD, TSEM_REG_MSG_NUM_FOC3, 0x0},
-       {OP_WR, TSEM_REG_ARB_ELEMENT0, 0x1},
-       {OP_WR, TSEM_REG_ARB_ELEMENT1, 0x2},
-       {OP_WR, TSEM_REG_ARB_ELEMENT2, 0x3},
-       {OP_WR, TSEM_REG_ARB_ELEMENT3, 0x0},
-       {OP_WR, TSEM_REG_ARB_ELEMENT4, 0x4},
-       {OP_WR, TSEM_REG_ARB_CYCLE_SIZE, 0x1},
-       {OP_WR, TSEM_REG_TS_0_AS, 0x0},
-       {OP_WR, TSEM_REG_TS_1_AS, 0x1},
-       {OP_WR, TSEM_REG_TS_2_AS, 0x4},
-       {OP_WR, TSEM_REG_TS_3_AS, 0x0},
-       {OP_WR, TSEM_REG_TS_4_AS, 0x1},
-       {OP_WR, TSEM_REG_TS_5_AS, 0x3},
-       {OP_WR, TSEM_REG_TS_6_AS, 0x0},
-       {OP_WR, TSEM_REG_TS_7_AS, 0x1},
-       {OP_WR, TSEM_REG_TS_8_AS, 0x4},
-       {OP_WR, TSEM_REG_TS_9_AS, 0x0},
-       {OP_WR, TSEM_REG_TS_10_AS, 0x1},
-       {OP_WR, TSEM_REG_TS_11_AS, 0x3},
-       {OP_WR, TSEM_REG_TS_12_AS, 0x0},
-       {OP_WR, TSEM_REG_TS_13_AS, 0x1},
-       {OP_WR, TSEM_REG_TS_14_AS, 0x4},
-       {OP_WR, TSEM_REG_TS_15_AS, 0x0},
-       {OP_WR, TSEM_REG_TS_16_AS, 0x4},
-       {OP_WR, TSEM_REG_TS_17_AS, 0x3},
-       {OP_ZR, TSEM_REG_TS_18_AS, 0x2},
-       {OP_WR, TSEM_REG_ENABLE_IN, 0x3fff},
-       {OP_WR, TSEM_REG_ENABLE_OUT, 0x3ff},
-       {OP_WR, TSEM_REG_FIC0_DISABLE, 0x0},
-       {OP_WR, TSEM_REG_FIC1_DISABLE, 0x0},
-       {OP_WR, TSEM_REG_PAS_DISABLE, 0x0},
-       {OP_WR, TSEM_REG_THREADS_LIST, 0xff},
-       {OP_ZR, TSEM_REG_PASSIVE_BUFFER, 0x400},
-       {OP_WR, TSEM_REG_FAST_MEMORY + 0x18bc0, 0x1},
-       {OP_WR, TSEM_REG_FAST_MEMORY + 0x18000, 0x34},
-       {OP_WR, TSEM_REG_FAST_MEMORY + 0x18040, 0x18},
-       {OP_WR, TSEM_REG_FAST_MEMORY + 0x18080, 0xc},
-       {OP_WR, TSEM_REG_FAST_MEMORY + 0x180c0, 0x20},
-       {OP_WR_ASIC, TSEM_REG_FAST_MEMORY + 0x18300, 0x7a120},
-       {OP_WR_EMUL, TSEM_REG_FAST_MEMORY + 0x18300, 0x138},
-       {OP_WR_FPGA, TSEM_REG_FAST_MEMORY + 0x18300, 0x1388},
-       {OP_WR, TSEM_REG_FAST_MEMORY + 0x183c0, 0x1f4},
-       {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x2000, 0xb2},
-       {OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x11480, 0x1},
-       {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x23c8, 0xc1},
-       {OP_WR_EMUL_E1H, TSEM_REG_FAST_MEMORY + 0x11480, 0x0},
-       {OP_SW_E1, TSEM_REG_FAST_MEMORY + 0x23c8 + 0x304, 0x10223},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x1000, 0x2b3},
-       {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1020, 0xc8},
-       {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x1000 + 0xacc, 0x10223},
-       {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1000, 0x2},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0xa020, 0xc8},
-       {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1c18, 0x4},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0xa000, 0x2},
-       {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1c10, 0x2},
-       {OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x1ad0, 0x0},
-       {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x800, 0x2},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x1ad8, 0x4},
-       {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x808, 0x2},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3678, 0x6},
-       {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x810, 0x4},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3670, 0x2},
-       {OP_SW_E1, TSEM_REG_FAST_MEMORY + 0x1fb0, 0x40224},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5000, 0x2},
-       {OP_SW_E1, TSEM_REG_FAST_MEMORY + 0x4cb0, 0x80228},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5008, 0x4},
-       {OP_ZP_E1, TSEM_REG_INT_TABLE, 0x930000},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5018, 0x4},
-       {OP_WR_64_E1, TSEM_REG_INT_TABLE + 0x360, 0x140230},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5028, 0x4},
-       {OP_ZP_E1, TSEM_REG_PRAM, 0x324f0000},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5038, 0x4},
-       {OP_ZP_E1, TSEM_REG_PRAM + 0x8000, 0x33250c94},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5048, 0x4},
-       {OP_ZP_E1, TSEM_REG_PRAM + 0x10000, 0xe4d195e},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5058, 0x4},
-       {OP_WR_64_E1, TSEM_REG_PRAM + 0x11e00, 0x5c400232},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5068, 0x4},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5078, 0x2},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x4000, 0x2},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x4008, 0x2},
-       {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x62c0, 0x200224},
-       {OP_ZP_E1H, TSEM_REG_INT_TABLE, 0x9b0000},
-       {OP_WR_64_E1H, TSEM_REG_INT_TABLE + 0x398, 0xd0244},
-       {OP_ZP_E1H, TSEM_REG_PRAM, 0x325e0000},
-       {OP_ZP_E1H, TSEM_REG_PRAM + 0x8000, 0x35960c98},
-       {OP_ZP_E1H, TSEM_REG_PRAM + 0x10000, 0x1aea19fe},
-       {OP_WR_64_E1H, TSEM_REG_PRAM + 0x143d0, 0x57860246},
-#define TSEM_COMMON_END         297
-#define TSEM_PORT0_START        297
-       {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x22c8, 0x20},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x2000, 0x16c},
-       {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x4000, 0x16c},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0xb000, 0x28},
-       {OP_WR_E1, TSEM_REG_FAST_MEMORY + 0x4b60, 0x0},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0xb140, 0xc},
-       {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1400, 0xa},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x32c0, 0x12},
-       {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1450, 0x6},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3350, 0x64},
-       {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1500, 0x2},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x8108, 0x2},
-       {OP_SW_E1, TSEM_REG_FAST_MEMORY + 0x1500 + 0x8, 0x50234},
-       {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1500 + 0x1c, 0x7},
-       {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1570, 0x12},
-       {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x9c0, 0x4c},
-       {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x800, 0x2},
-       {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x820, 0xe},
-       {OP_SW_E1, TSEM_REG_FAST_MEMORY + 0x1fb0, 0x20239},
-       {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x2908, 0x2},
-#define TSEM_PORT0_END          317
-#define TSEM_PORT1_START        317
-       {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x2348, 0x20},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x25b0, 0x16c},
-       {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x45b0, 0x16c},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0xb0a0, 0x28},
-       {OP_WR_E1, TSEM_REG_FAST_MEMORY + 0x4b64, 0x0},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0xb170, 0xc},
-       {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1428, 0xa},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3308, 0x12},
-       {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1468, 0x6},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x34e0, 0x64},
-       {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1538, 0x2},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x8110, 0x2},
-       {OP_SW_E1, TSEM_REG_FAST_MEMORY + 0x1538 + 0x8, 0x5023b},
-       {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x1538 + 0x1c, 0x7},
-       {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x15b8, 0x12},
-       {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0xaf0, 0x4c},
-       {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x808, 0x2},
-       {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x858, 0xe},
-       {OP_SW_E1, TSEM_REG_FAST_MEMORY + 0x1fb8, 0x20240},
-       {OP_ZR_E1, TSEM_REG_FAST_MEMORY + 0x2910, 0x2},
-#define TSEM_PORT1_END          337
-#define TSEM_FUNC0_START        337
-       {OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x2b60, 0x0},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3000, 0x2},
-       {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x3000 + 0x8, 0x50248},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3000 + 0x1c, 0x7},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x31c0, 0x8},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5000, 0x2},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5080, 0x12},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x4000, 0x2},
-#define TSEM_FUNC0_END          345
-#define TSEM_FUNC1_START        345
-       {OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x2b64, 0x0},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3038, 0x2},
-       {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x3038 + 0x8, 0x5024d},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3038 + 0x1c, 0x7},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x31e0, 0x8},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5010, 0x2},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x50c8, 0x12},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x4008, 0x2},
-#define TSEM_FUNC1_END          353
-#define TSEM_FUNC2_START        353
-       {OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x2b68, 0x0},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3070, 0x2},
-       {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x3070 + 0x8, 0x50252},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3070 + 0x1c, 0x7},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3200, 0x8},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5020, 0x2},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5110, 0x12},
-       {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x4010, 0x20257},
-#define TSEM_FUNC2_END          361
-#define TSEM_FUNC3_START        361
-       {OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x2b6c, 0x0},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x30a8, 0x2},
-       {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x30a8 + 0x8, 0x50259},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x30a8 + 0x1c, 0x7},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3220, 0x8},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5030, 0x2},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5158, 0x12},
-       {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x4018, 0x2025e},
-#define TSEM_FUNC3_END          369
-#define TSEM_FUNC4_START        369
-       {OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x2b70, 0x0},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x30e0, 0x2},
-       {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x30e0 + 0x8, 0x50260},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x30e0 + 0x1c, 0x7},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3240, 0x8},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5040, 0x2},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x51a0, 0x12},
-       {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x4020, 0x20265},
-#define TSEM_FUNC4_END          377
-#define TSEM_FUNC5_START        377
-       {OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x2b74, 0x0},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3118, 0x2},
-       {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x3118 + 0x8, 0x50267},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3118 + 0x1c, 0x7},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3260, 0x8},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5050, 0x2},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x51e8, 0x12},
-       {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x4028, 0x2026c},
-#define TSEM_FUNC5_END          385
-#define TSEM_FUNC6_START        385
-       {OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x2b78, 0x0},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3150, 0x2},
-       {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x3150 + 0x8, 0x5026e},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3150 + 0x1c, 0x7},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3280, 0x8},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5060, 0x2},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5230, 0x12},
-       {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x4030, 0x20273},
-#define TSEM_FUNC6_END          393
-#define TSEM_FUNC7_START        393
-       {OP_WR_E1H, TSEM_REG_FAST_MEMORY + 0x2b7c, 0x0},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3188, 0x2},
-       {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x3188 + 0x8, 0x50275},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x3188 + 0x1c, 0x7},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x32a0, 0x8},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5070, 0x2},
-       {OP_ZR_E1H, TSEM_REG_FAST_MEMORY + 0x5278, 0x12},
-       {OP_SW_E1H, TSEM_REG_FAST_MEMORY + 0x4038, 0x2027a},
-#define TSEM_FUNC7_END          401
-#define MISC_COMMON_START       401
-       {OP_WR_E1, MISC_REG_GRC_TIMEOUT_EN, 0x1},
-       {OP_WR, MISC_REG_PLL_STORM_CTRL_1, 0x71d2911},
-       {OP_WR, MISC_REG_PLL_STORM_CTRL_2, 0x0},
-       {OP_WR, MISC_REG_PLL_STORM_CTRL_3, 0x9c0424},
-       {OP_WR, MISC_REG_PLL_STORM_CTRL_4, 0x0},
-       {OP_WR, MISC_REG_LCPLL_CTRL_1, 0x209},
-       {OP_WR_E1, MISC_REG_SPIO, 0xff000000},
-#define MISC_COMMON_END         408
-#define MISC_FUNC0_START        408
-       {OP_WR_E1H, MISC_REG_NIG_WOL_P0, 0x0},
-#define MISC_FUNC0_END          409
-#define MISC_FUNC1_START        409
-       {OP_WR_E1H, MISC_REG_NIG_WOL_P1, 0x0},
-#define MISC_FUNC1_END          410
-#define MISC_FUNC2_START        410
-       {OP_WR_E1H, MISC_REG_NIG_WOL_P0, 0x0},
-#define MISC_FUNC2_END          411
-#define MISC_FUNC3_START        411
-       {OP_WR_E1H, MISC_REG_NIG_WOL_P1, 0x0},
-#define MISC_FUNC3_END          412
-#define MISC_FUNC4_START        412
-       {OP_WR_E1H, MISC_REG_NIG_WOL_P0, 0x0},
-#define MISC_FUNC4_END          413
-#define MISC_FUNC5_START        413
-       {OP_WR_E1H, MISC_REG_NIG_WOL_P1, 0x0},
-#define MISC_FUNC5_END          414
-#define MISC_FUNC6_START        414
-       {OP_WR_E1H, MISC_REG_NIG_WOL_P0, 0x0},
-#define MISC_FUNC6_END          415
-#define MISC_FUNC7_START        415
-       {OP_WR_E1H, MISC_REG_NIG_WOL_P1, 0x0},
-#define MISC_FUNC7_END          416
-#define NIG_COMMON_START        416
-       {OP_WR, NIG_REG_PBF_LB_IN_EN, 0x1},
-       {OP_WR, NIG_REG_PRS_REQ_IN_EN, 0x1},
-       {OP_WR, NIG_REG_EGRESS_DEBUG_IN_EN, 0x1},
-       {OP_WR, NIG_REG_BRB_LB_OUT_EN, 0x1},
-       {OP_WR, NIG_REG_PRS_EOP_OUT_EN, 0x1},
-#define NIG_COMMON_END          421
-#define NIG_PORT0_START         421
-       {OP_WR, NIG_REG_LLH0_CM_HEADER, 0x300000},
-       {OP_WR, NIG_REG_LLH0_EVENT_ID, 0x28},
-       {OP_WR, NIG_REG_LLH0_ERROR_MASK, 0x0},
-       {OP_WR, NIG_REG_LLH0_XCM_MASK, 0x4},
-       {OP_WR, NIG_REG_LLH0_BRB1_NOT_MCP, 0x1},
-       {OP_WR, NIG_REG_STATUS_INTERRUPT_PORT0, 0x0},
-       {OP_WR_E1H, NIG_REG_LLH0_CLS_TYPE, 0x1},
-       {OP_WR, NIG_REG_LLH0_XCM_INIT_CREDIT, 0x30},
-       {OP_WR, NIG_REG_BRB0_PAUSE_IN_EN, 0x1},
-       {OP_WR, NIG_REG_EGRESS_PBF0_IN_EN, 0x1},
-       {OP_WR, NIG_REG_BRB0_OUT_EN, 0x1},
-       {OP_WR, NIG_REG_XCM0_OUT_EN, 0x1},
-#define NIG_PORT0_END           433
-#define NIG_PORT1_START         433
-       {OP_WR, NIG_REG_LLH1_CM_HEADER, 0x300000},
-       {OP_WR, NIG_REG_LLH1_EVENT_ID, 0x28},
-       {OP_WR, NIG_REG_LLH1_ERROR_MASK, 0x0},
-       {OP_WR, NIG_REG_LLH1_XCM_MASK, 0x4},
-       {OP_WR, NIG_REG_LLH1_BRB1_NOT_MCP, 0x1},
-       {OP_WR, NIG_REG_STATUS_INTERRUPT_PORT1, 0x0},
-       {OP_WR_E1H, NIG_REG_LLH1_CLS_TYPE, 0x1},
-       {OP_WR, NIG_REG_LLH1_XCM_INIT_CREDIT, 0x30},
-       {OP_WR, NIG_REG_BRB1_PAUSE_IN_EN, 0x1},
-       {OP_WR, NIG_REG_EGRESS_PBF1_IN_EN, 0x1},
-       {OP_WR, NIG_REG_BRB1_OUT_EN, 0x1},
-       {OP_WR, NIG_REG_XCM1_OUT_EN, 0x1},
-#define NIG_PORT1_END           445
-#define UPB_COMMON_START        445
-       {OP_WR, GRCBASE_UPB + PB_REG_CONTROL, 0x20},
-#define UPB_COMMON_END          446
-#define CSDM_COMMON_START       446
-       {OP_WR_E1, CSDM_REG_CFC_RSP_START_ADDR, 0xa11},
-       {OP_WR_E1H, CSDM_REG_CFC_RSP_START_ADDR, 0x211},
-       {OP_WR_E1, CSDM_REG_CMP_COUNTER_START_ADDR, 0xa00},
-       {OP_WR_E1H, CSDM_REG_CMP_COUNTER_START_ADDR, 0x200},
-       {OP_WR_E1, CSDM_REG_Q_COUNTER_START_ADDR, 0xa04},
-       {OP_WR_E1H, CSDM_REG_Q_COUNTER_START_ADDR, 0x204},
-       {OP_WR, CSDM_REG_CMP_COUNTER_MAX0, 0xffff},
-       {OP_WR, CSDM_REG_CMP_COUNTER_MAX1, 0xffff},
-       {OP_WR, CSDM_REG_CMP_COUNTER_MAX2, 0xffff},
-       {OP_WR, CSDM_REG_CMP_COUNTER_MAX3, 0xffff},
-       {OP_WR, CSDM_REG_AGG_INT_EVENT_0, 0xc6},
-       {OP_WR, CSDM_REG_AGG_INT_EVENT_1, 0x0},
-       {OP_WR, CSDM_REG_AGG_INT_EVENT_2, 0x34},
-       {OP_WR, CSDM_REG_AGG_INT_EVENT_3, 0x35},
-       {OP_ZR, CSDM_REG_AGG_INT_EVENT_4, 0x1c},
-       {OP_WR, CSDM_REG_AGG_INT_T_0, 0x1},
-       {OP_ZR, CSDM_REG_AGG_INT_T_1, 0x5f},
-       {OP_WR, CSDM_REG_ENABLE_IN1, 0x7ffffff},
-       {OP_WR, CSDM_REG_ENABLE_IN2, 0x3f},
-       {OP_WR, CSDM_REG_ENABLE_OUT1, 0x7ffffff},
-       {OP_WR, CSDM_REG_ENABLE_OUT2, 0xf},
-       {OP_RD, CSDM_REG_NUM_OF_Q0_CMD, 0x0},
-       {OP_RD, CSDM_REG_NUM_OF_Q1_CMD, 0x0},
-       {OP_RD, CSDM_REG_NUM_OF_Q3_CMD, 0x0},
-       {OP_RD, CSDM_REG_NUM_OF_Q4_CMD, 0x0},
-       {OP_RD, CSDM_REG_NUM_OF_Q5_CMD, 0x0},
-       {OP_RD, CSDM_REG_NUM_OF_Q6_CMD, 0x0},
-       {OP_RD, CSDM_REG_NUM_OF_Q7_CMD, 0x0},
-       {OP_RD, CSDM_REG_NUM_OF_Q8_CMD, 0x0},
-       {OP_RD, CSDM_REG_NUM_OF_Q9_CMD, 0x0},
-       {OP_RD, CSDM_REG_NUM_OF_Q10_CMD, 0x0},
-       {OP_RD, CSDM_REG_NUM_OF_Q11_CMD, 0x0},
-       {OP_RD, CSDM_REG_NUM_OF_PKT_END_MSG, 0x0},
-       {OP_RD, CSDM_REG_NUM_OF_PXP_ASYNC_REQ, 0x0},
-       {OP_RD, CSDM_REG_NUM_OF_ACK_AFTER_PLACE, 0x0},
-       {OP_WR_E1, CSDM_REG_INIT_CREDIT_PXP_CTRL, 0x1},
-       {OP_WR_ASIC, CSDM_REG_TIMER_TICK, 0x3e8},
-       {OP_WR_EMUL, CSDM_REG_TIMER_TICK, 0x1},
-       {OP_WR_FPGA, CSDM_REG_TIMER_TICK, 0xa},
-#define CSDM_COMMON_END         485
-#define USDM_COMMON_START       485
-       {OP_WR_E1, USDM_REG_CFC_RSP_START_ADDR, 0xa11},
-       {OP_WR_E1H, USDM_REG_CFC_RSP_START_ADDR, 0x411},
-       {OP_WR_E1, USDM_REG_CMP_COUNTER_START_ADDR, 0xa00},
-       {OP_WR_E1H, USDM_REG_CMP_COUNTER_START_ADDR, 0x400},
-       {OP_WR_E1, USDM_REG_Q_COUNTER_START_ADDR, 0xa04},
-       {OP_WR_E1H, USDM_REG_Q_COUNTER_START_ADDR, 0x404},
-       {OP_WR_E1, USDM_REG_PCK_END_MSG_START_ADDR, 0xa21},
-       {OP_WR_E1H, USDM_REG_PCK_END_MSG_START_ADDR, 0x421},
-       {OP_WR, USDM_REG_CMP_COUNTER_MAX0, 0xffff},
-       {OP_WR, USDM_REG_CMP_COUNTER_MAX1, 0xffff},
-       {OP_WR, USDM_REG_CMP_COUNTER_MAX2, 0xffff},
-       {OP_WR, USDM_REG_CMP_COUNTER_MAX3, 0xffff},
-       {OP_WR, USDM_REG_AGG_INT_EVENT_0, 0x46},
-       {OP_WR, USDM_REG_AGG_INT_EVENT_1, 0x5},
-       {OP_WR, USDM_REG_AGG_INT_EVENT_2, 0x34},
-       {OP_WR, USDM_REG_AGG_INT_EVENT_3, 0x35},
-       {OP_ZR_E1, USDM_REG_AGG_INT_EVENT_4, 0x5c},
-       {OP_WR_E1H, USDM_REG_AGG_INT_EVENT_4, 0x7},
-       {OP_ZR_E1H, USDM_REG_AGG_INT_EVENT_5, 0x5b},
-       {OP_WR, USDM_REG_AGG_INT_MODE_0, 0x1},
-       {OP_ZR_E1, USDM_REG_AGG_INT_MODE_1, 0x1f},
-       {OP_ZR_E1H, USDM_REG_AGG_INT_MODE_1, 0x3},
-       {OP_WR_E1H, USDM_REG_AGG_INT_MODE_4, 0x1},
-       {OP_ZR_E1H, USDM_REG_AGG_INT_MODE_5, 0x1b},
-       {OP_WR, USDM_REG_ENABLE_IN1, 0x7ffffff},
-       {OP_WR, USDM_REG_ENABLE_IN2, 0x3f},
-       {OP_WR, USDM_REG_ENABLE_OUT1, 0x7ffffff},
-       {OP_WR, USDM_REG_ENABLE_OUT2, 0xf},
-       {OP_RD, USDM_REG_NUM_OF_Q0_CMD, 0x0},
-       {OP_RD, USDM_REG_NUM_OF_Q1_CMD, 0x0},
-       {OP_RD, USDM_REG_NUM_OF_Q2_CMD, 0x0},
-       {OP_RD, USDM_REG_NUM_OF_Q3_CMD, 0x0},
-       {OP_RD, USDM_REG_NUM_OF_Q4_CMD, 0x0},
-       {OP_RD, USDM_REG_NUM_OF_Q5_CMD, 0x0},
-       {OP_RD, USDM_REG_NUM_OF_Q6_CMD, 0x0},
-       {OP_RD, USDM_REG_NUM_OF_Q7_CMD, 0x0},
-       {OP_RD, USDM_REG_NUM_OF_Q8_CMD, 0x0},
-       {OP_RD, USDM_REG_NUM_OF_Q9_CMD, 0x0},
-       {OP_RD, USDM_REG_NUM_OF_Q10_CMD, 0x0},
-       {OP_RD, USDM_REG_NUM_OF_Q11_CMD, 0x0},
-       {OP_RD, USDM_REG_NUM_OF_PKT_END_MSG, 0x0},
-       {OP_RD, USDM_REG_NUM_OF_PXP_ASYNC_REQ, 0x0},
-       {OP_RD, USDM_REG_NUM_OF_ACK_AFTER_PLACE, 0x0},
-       {OP_WR_E1, USDM_REG_INIT_CREDIT_PXP_CTRL, 0x1},
-       {OP_WR_ASIC, USDM_REG_TIMER_TICK, 0x3e8},
-       {OP_WR_EMUL, USDM_REG_TIMER_TICK, 0x1},
-       {OP_WR_FPGA, USDM_REG_TIMER_TICK, 0xa},
-#define USDM_COMMON_END         532
-#define CCM_COMMON_START        532
-       {OP_WR, CCM_REG_XX_OVFL_EVNT_ID, 0x32},
-       {OP_WR, CCM_REG_CQM_CCM_HDR_P, 0x2150020},
-       {OP_WR, CCM_REG_CQM_CCM_HDR_S, 0x2150020},
-       {OP_WR, CCM_REG_ERR_CCM_HDR, 0x8100000},
-       {OP_WR, CCM_REG_ERR_EVNT_ID, 0x33},
-       {OP_WR, CCM_REG_STORM_WEIGHT, 0x2},
-       {OP_WR, CCM_REG_TSEM_WEIGHT, 0x0},
-       {OP_WR, CCM_REG_XSEM_WEIGHT, 0x5},
-       {OP_WR, CCM_REG_USEM_WEIGHT, 0x5},
-       {OP_ZR, CCM_REG_PBF_WEIGHT, 0x2},
-       {OP_WR, CCM_REG_CSDM_WEIGHT, 0x2},
-       {OP_WR, CCM_REG_CQM_P_WEIGHT, 0x3},
-       {OP_WR, CCM_REG_CQM_S_WEIGHT, 0x2},
-       {OP_WR, CCM_REG_CCM_CQM_USE_Q, 0x1},
-       {OP_WR, CCM_REG_CNT_AUX1_Q, 0x2},
-       {OP_WR, CCM_REG_CNT_AUX2_Q, 0x2},
-       {OP_WR, CCM_REG_INV_DONE_Q, 0x1},
-       {OP_WR, CCM_REG_GR_ARB_TYPE, 0x1},
-       {OP_WR, CCM_REG_GR_LD0_PR, 0x1},
-       {OP_WR, CCM_REG_GR_LD1_PR, 0x2},
-       {OP_WR, CCM_REG_CFC_INIT_CRD, 0x1},
-       {OP_WR, CCM_REG_CQM_INIT_CRD, 0x20},
-       {OP_WR, CCM_REG_FIC0_INIT_CRD, 0x40},
-       {OP_WR, CCM_REG_FIC1_INIT_CRD, 0x40},
-       {OP_WR, CCM_REG_XX_INIT_CRD, 0x3},
-       {OP_WR, CCM_REG_XX_MSG_NUM, 0x18},
-       {OP_ZR, CCM_REG_XX_TABLE, 0x12},
-       {OP_SW_E1, CCM_REG_XX_DESCR_TABLE, 0x240242},
-       {OP_SW_E1H, CCM_REG_XX_DESCR_TABLE, 0x24027c},
-       {OP_WR, CCM_REG_N_SM_CTX_LD_0, 0x1},
-       {OP_WR, CCM_REG_N_SM_CTX_LD_1, 0x2},
-       {OP_WR, CCM_REG_N_SM_CTX_LD_2, 0x8},
-       {OP_WR, CCM_REG_N_SM_CTX_LD_3, 0x8},
-       {OP_ZR, CCM_REG_N_SM_CTX_LD_4, 0x4},
-       {OP_WR, CCM_REG_CCM_REG0_SZ, 0x4},
-       {OP_WR_E1, CCM_REG_QOS_PHYS_QNUM0_0, 0x9},
-       {OP_WR_E1, CCM_REG_QOS_PHYS_QNUM0_1, 0x29},
-       {OP_WR_E1, CCM_REG_QOS_PHYS_QNUM1_0, 0xa},
-       {OP_WR_E1, CCM_REG_QOS_PHYS_QNUM1_1, 0x2a},
-       {OP_WR_E1, CCM_REG_QOS_PHYS_QNUM2_0, 0x7},
-       {OP_WR_E1, CCM_REG_QOS_PHYS_QNUM2_1, 0x27},
-       {OP_WR_E1, CCM_REG_QOS_PHYS_QNUM3_0, 0x7},
-       {OP_WR_E1, CCM_REG_QOS_PHYS_QNUM3_1, 0x27},
-       {OP_WR_E1, CCM_REG_PHYS_QNUM1_0, 0xc},
-       {OP_WR_E1, CCM_REG_PHYS_QNUM1_1, 0x2c},
-       {OP_WR_E1, CCM_REG_PHYS_QNUM2_0, 0xc},
-       {OP_WR_E1, CCM_REG_PHYS_QNUM2_1, 0x2c},
-       {OP_WR_E1, CCM_REG_PHYS_QNUM3_0, 0xc},
-       {OP_WR_E1, CCM_REG_PHYS_QNUM3_1, 0x2c},
-       {OP_WR, CCM_REG_CCM_STORM0_IFEN, 0x1},
-       {OP_WR, CCM_REG_CCM_STORM1_IFEN, 0x1},
-       {OP_WR, CCM_REG_CCM_CQM_IFEN, 0x1},
-       {OP_WR, CCM_REG_STORM_CCM_IFEN, 0x1},
-       {OP_WR, CCM_REG_CQM_CCM_IFEN, 0x1},
-       {OP_WR, CCM_REG_CSDM_IFEN, 0x1},
-       {OP_WR, CCM_REG_TSEM_IFEN, 0x1},
-       {OP_WR, CCM_REG_XSEM_IFEN, 0x1},
-       {OP_WR, CCM_REG_USEM_IFEN, 0x1},
-       {OP_WR, CCM_REG_PBF_IFEN, 0x1},
-       {OP_WR, CCM_REG_CDU_AG_WR_IFEN, 0x1},
-       {OP_WR, CCM_REG_CDU_AG_RD_IFEN, 0x1},
-       {OP_WR, CCM_REG_CDU_SM_WR_IFEN, 0x1},
-       {OP_WR, CCM_REG_CDU_SM_RD_IFEN, 0x1},
-       {OP_WR, CCM_REG_CCM_CFC_IFEN, 0x1},
-#define CCM_COMMON_END          596
-#define CCM_FUNC0_START         596
-       {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM0_0, 0x9},
-       {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM1_0, 0xa},
-       {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM2_0, 0x7},
-       {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM3_0, 0x7},
-       {OP_WR_E1H, CCM_REG_PHYS_QNUM1_0, 0xc},
-       {OP_WR_E1H, CCM_REG_PHYS_QNUM2_0, 0xb},
-       {OP_WR_E1H, CCM_REG_PHYS_QNUM3_0, 0x7},
-#define CCM_FUNC0_END           603
-#define CCM_FUNC1_START         603
-       {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM0_1, 0x29},
-       {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM1_1, 0x2a},
-       {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM2_1, 0x27},
-       {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM3_1, 0x27},
-       {OP_WR_E1H, CCM_REG_PHYS_QNUM1_1, 0x2c},
-       {OP_WR_E1H, CCM_REG_PHYS_QNUM2_1, 0x2b},
-       {OP_WR_E1H, CCM_REG_PHYS_QNUM3_1, 0x27},
-#define CCM_FUNC1_END           610
-#define CCM_FUNC2_START         610
-       {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM0_0, 0x19},
-       {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM1_0, 0x1a},
-       {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM2_0, 0x17},
-       {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM3_0, 0x17},
-       {OP_WR_E1H, CCM_REG_PHYS_QNUM1_0, 0x1c},
-       {OP_WR_E1H, CCM_REG_PHYS_QNUM2_0, 0x1b},
-       {OP_WR_E1H, CCM_REG_PHYS_QNUM3_0, 0x17},
-#define CCM_FUNC2_END           617
-#define CCM_FUNC3_START         617
-       {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM0_1, 0x39},
-       {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM1_1, 0x3a},
-       {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM2_1, 0x37},
-       {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM3_1, 0x37},
-       {OP_WR_E1H, CCM_REG_PHYS_QNUM1_1, 0x3c},
-       {OP_WR_E1H, CCM_REG_PHYS_QNUM2_1, 0x3b},
-       {OP_WR_E1H, CCM_REG_PHYS_QNUM3_1, 0x37},
-#define CCM_FUNC3_END           624
-#define CCM_FUNC4_START         624
-       {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM0_0, 0x49},
-       {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM1_0, 0x4a},
-       {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM2_0, 0x47},
-       {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM3_0, 0x47},
-       {OP_WR_E1H, CCM_REG_PHYS_QNUM1_0, 0x4c},
-       {OP_WR_E1H, CCM_REG_PHYS_QNUM2_0, 0x4b},
-       {OP_WR_E1H, CCM_REG_PHYS_QNUM3_0, 0x47},
-#define CCM_FUNC4_END           631
-#define CCM_FUNC5_START         631
-       {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM0_1, 0x69},
-       {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM1_1, 0x6a},
-       {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM2_1, 0x67},
-       {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM3_1, 0x67},
-       {OP_WR_E1H, CCM_REG_PHYS_QNUM1_1, 0x6c},
-       {OP_WR_E1H, CCM_REG_PHYS_QNUM2_1, 0x6b},
-       {OP_WR_E1H, CCM_REG_PHYS_QNUM3_1, 0x67},
-#define CCM_FUNC5_END           638
-#define CCM_FUNC6_START         638
-       {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM0_0, 0x59},
-       {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM1_0, 0x5a},
-       {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM2_0, 0x57},
-       {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM3_0, 0x57},
-       {OP_WR_E1H, CCM_REG_PHYS_QNUM1_0, 0x5c},
-       {OP_WR_E1H, CCM_REG_PHYS_QNUM2_0, 0x5b},
-       {OP_WR_E1H, CCM_REG_PHYS_QNUM3_0, 0x57},
-#define CCM_FUNC6_END           645
-#define CCM_FUNC7_START         645
-       {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM0_1, 0x79},
-       {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM1_1, 0x7a},
-       {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM2_1, 0x77},
-       {OP_WR_E1H, CCM_REG_QOS_PHYS_QNUM3_1, 0x77},
-       {OP_WR_E1H, CCM_REG_PHYS_QNUM1_1, 0x7c},
-       {OP_WR_E1H, CCM_REG_PHYS_QNUM2_1, 0x7b},
-       {OP_WR_E1H, CCM_REG_PHYS_QNUM3_1, 0x77},
-#define CCM_FUNC7_END           652
-#define UCM_COMMON_START        652
-       {OP_WR, UCM_REG_XX_OVFL_EVNT_ID, 0x32},
-       {OP_WR, UCM_REG_UQM_UCM_HDR_P, 0x2150020},
-       {OP_WR, UCM_REG_UQM_UCM_HDR_S, 0x2150020},
-       {OP_WR, UCM_REG_TM_UCM_HDR, 0x30},
-       {OP_WR, UCM_REG_ERR_UCM_HDR, 0x8100000},
-       {OP_WR, UCM_REG_ERR_EVNT_ID, 0x33},
-       {OP_WR, UCM_REG_EXPR_EVNT_ID, 0x30},
-       {OP_WR, UCM_REG_STOP_EVNT_ID, 0x31},
-       {OP_WR, UCM_REG_STORM_WEIGHT, 0x2},
-       {OP_WR, UCM_REG_TSEM_WEIGHT, 0x4},
-       {OP_WR, UCM_REG_CSEM_WEIGHT, 0x0},
-       {OP_WR, UCM_REG_XSEM_WEIGHT, 0x2},
-       {OP_WR, UCM_REG_DORQ_WEIGHT, 0x2},
-       {OP_WR, UCM_REG_CP_WEIGHT, 0x0},
-       {OP_WR, UCM_REG_USDM_WEIGHT, 0x2},
-       {OP_WR, UCM_REG_UQM_P_WEIGHT, 0x7},
-       {OP_WR, UCM_REG_UQM_S_WEIGHT, 0x2},
-       {OP_WR, UCM_REG_TM_WEIGHT, 0x2},
-       {OP_WR, UCM_REG_UCM_UQM_USE_Q, 0x1},
-       {OP_WR, UCM_REG_INV_CFLG_Q, 0x1},
-       {OP_WR, UCM_REG_GR_ARB_TYPE, 0x1},
-       {OP_WR, UCM_REG_GR_LD0_PR, 0x1},
-       {OP_WR, UCM_REG_GR_LD1_PR, 0x2},
-       {OP_WR, UCM_REG_CFC_INIT_CRD, 0x1},
-       {OP_WR, UCM_REG_FIC0_INIT_CRD, 0x40},
-       {OP_WR, UCM_REG_FIC1_INIT_CRD, 0x40},
-       {OP_WR, UCM_REG_TM_INIT_CRD, 0x4},
-       {OP_WR, UCM_REG_UQM_INIT_CRD, 0x20},
-       {OP_WR, UCM_REG_XX_INIT_CRD, 0xe},
-       {OP_WR, UCM_REG_XX_MSG_NUM, 0x1b},
-       {OP_ZR, UCM_REG_XX_TABLE, 0x12},
-       {OP_SW_E1, UCM_REG_XX_DESCR_TABLE, 0x1b0266},
-       {OP_SW_E1H, UCM_REG_XX_DESCR_TABLE, 0x1b02a0},
-       {OP_WR, UCM_REG_N_SM_CTX_LD_0, 0x10},
-       {OP_WR, UCM_REG_N_SM_CTX_LD_1, 0x7},
-       {OP_WR, UCM_REG_N_SM_CTX_LD_2, 0xf},
-       {OP_WR, UCM_REG_N_SM_CTX_LD_3, 0x10},
-       {OP_ZR_E1, UCM_REG_N_SM_CTX_LD_4, 0x4},
-       {OP_WR_E1H, UCM_REG_N_SM_CTX_LD_4, 0xb},
-       {OP_ZR_E1H, UCM_REG_N_SM_CTX_LD_5, 0x3},
-       {OP_WR, UCM_REG_UCM_REG0_SZ, 0x3},
-       {OP_WR_E1, UCM_REG_PHYS_QNUM0_0, 0xf},
-       {OP_WR_E1, UCM_REG_PHYS_QNUM0_1, 0x2f},
-       {OP_WR_E1, UCM_REG_PHYS_QNUM1_0, 0xe},
-       {OP_WR_E1, UCM_REG_PHYS_QNUM1_1, 0x2e},
-       {OP_WR, UCM_REG_UCM_STORM0_IFEN, 0x1},
-       {OP_WR, UCM_REG_UCM_STORM1_IFEN, 0x1},
-       {OP_WR, UCM_REG_UCM_UQM_IFEN, 0x1},
-       {OP_WR, UCM_REG_STORM_UCM_IFEN, 0x1},
-       {OP_WR, UCM_REG_UQM_UCM_IFEN, 0x1},
-       {OP_WR, UCM_REG_USDM_IFEN, 0x1},
-       {OP_WR, UCM_REG_TM_UCM_IFEN, 0x1},
-       {OP_WR, UCM_REG_UCM_TM_IFEN, 0x1},
-       {OP_WR, UCM_REG_TSEM_IFEN, 0x1},
-       {OP_WR, UCM_REG_CSEM_IFEN, 0x1},
-       {OP_WR, UCM_REG_XSEM_IFEN, 0x1},
-       {OP_WR, UCM_REG_DORQ_IFEN, 0x1},
-       {OP_WR, UCM_REG_CDU_AG_WR_IFEN, 0x1},
-       {OP_WR, UCM_REG_CDU_AG_RD_IFEN, 0x1},
-       {OP_WR, UCM_REG_CDU_SM_WR_IFEN, 0x1},
-       {OP_WR, UCM_REG_CDU_SM_RD_IFEN, 0x1},
-       {OP_WR, UCM_REG_UCM_CFC_IFEN, 0x1},
-#define UCM_COMMON_END          714
-#define UCM_FUNC0_START         714
-       {OP_WR_E1H, UCM_REG_PHYS_QNUM0_0, 0xf},
-       {OP_WR_E1H, UCM_REG_PHYS_QNUM1_0, 0xe},
-       {OP_WR_E1H, UCM_REG_PHYS_QNUM2_0, 0x0},
-       {OP_WR_E1H, UCM_REG_PHYS_QNUM3_0, 0x0},
-#define UCM_FUNC0_END           718
-#define UCM_FUNC1_START         718
-       {OP_WR_E1H, UCM_REG_PHYS_QNUM0_1, 0x2f},
-       {OP_WR_E1H, UCM_REG_PHYS_QNUM1_1, 0x2e},
-       {OP_WR_E1H, UCM_REG_PHYS_QNUM2_1, 0x0},
-       {OP_WR_E1H, UCM_REG_PHYS_QNUM3_1, 0x0},
-#define UCM_FUNC1_END           722
-#define UCM_FUNC2_START         722
-       {OP_WR_E1H, UCM_REG_PHYS_QNUM0_0, 0x1f},
-       {OP_WR_E1H, UCM_REG_PHYS_QNUM1_0, 0x1e},
-       {OP_WR_E1H, UCM_REG_PHYS_QNUM2_0, 0x0},
-       {OP_WR_E1H, UCM_REG_PHYS_QNUM3_0, 0x0},
-#define UCM_FUNC2_END           726
-#define UCM_FUNC3_START         726
-       {OP_WR_E1H, UCM_REG_PHYS_QNUM0_1, 0x3f},
-       {OP_WR_E1H, UCM_REG_PHYS_QNUM1_1, 0x3e},
-       {OP_WR_E1H, UCM_REG_PHYS_QNUM2_1, 0x0},
-       {OP_WR_E1H, UCM_REG_PHYS_QNUM3_1, 0x0},
-#define UCM_FUNC3_END           730
-#define UCM_FUNC4_START         730
-       {OP_WR_E1H, UCM_REG_PHYS_QNUM0_0, 0x4f},
-       {OP_WR_E1H, UCM_REG_PHYS_QNUM1_0, 0x4e},
-       {OP_WR_E1H, UCM_REG_PHYS_QNUM2_0, 0x0},
-       {OP_WR_E1H, UCM_REG_PHYS_QNUM3_0, 0x0},
-#define UCM_FUNC4_END           734
-#define UCM_FUNC5_START         734
-       {OP_WR_E1H, UCM_REG_PHYS_QNUM0_1, 0x6f},
-       {OP_WR_E1H, UCM_REG_PHYS_QNUM1_1, 0x6e},
-       {OP_WR_E1H, UCM_REG_PHYS_QNUM2_1, 0x0},
-       {OP_WR_E1H, UCM_REG_PHYS_QNUM3_1, 0x0},
-#define UCM_FUNC5_END           738
-#define UCM_FUNC6_START         738
-       {OP_WR_E1H, UCM_REG_PHYS_QNUM0_0, 0x5f},
-       {OP_WR_E1H, UCM_REG_PHYS_QNUM1_0, 0x5e},
-       {OP_WR_E1H, UCM_REG_PHYS_QNUM2_0, 0x0},
-       {OP_WR_E1H, UCM_REG_PHYS_QNUM3_0, 0x0},
-#define UCM_FUNC6_END           742
-#define UCM_FUNC7_START         742
-       {OP_WR_E1H, UCM_REG_PHYS_QNUM0_1, 0x7f},
-       {OP_WR_E1H, UCM_REG_PHYS_QNUM1_1, 0x7e},
-       {OP_WR_E1H, UCM_REG_PHYS_QNUM2_1, 0x0},
-       {OP_WR_E1H, UCM_REG_PHYS_QNUM3_1, 0x0},
-#define UCM_FUNC7_END           746
-#define USEM_COMMON_START       746
-       {OP_RD, USEM_REG_MSG_NUM_FIC0, 0x0},
-       {OP_RD, USEM_REG_MSG_NUM_FIC1, 0x0},
-       {OP_RD, USEM_REG_MSG_NUM_FOC0, 0x0},
-       {OP_RD, USEM_REG_MSG_NUM_FOC1, 0x0},
-       {OP_RD, USEM_REG_MSG_NUM_FOC2, 0x0},
-       {OP_RD, USEM_REG_MSG_NUM_FOC3, 0x0},
-       {OP_WR, USEM_REG_ARB_ELEMENT0, 0x1},
-       {OP_WR, USEM_REG_ARB_ELEMENT1, 0x2},
-       {OP_WR, USEM_REG_ARB_ELEMENT2, 0x3},
-       {OP_WR, USEM_REG_ARB_ELEMENT3, 0x0},
-       {OP_WR, USEM_REG_ARB_ELEMENT4, 0x4},
-       {OP_WR, USEM_REG_ARB_CYCLE_SIZE, 0x1},
-       {OP_WR, USEM_REG_TS_0_AS, 0x0},
-       {OP_WR, USEM_REG_TS_1_AS, 0x1},
-       {OP_WR, USEM_REG_TS_2_AS, 0x4},
-       {OP_WR, USEM_REG_TS_3_AS, 0x0},
-       {OP_WR, USEM_REG_TS_4_AS, 0x1},
-       {OP_WR, USEM_REG_TS_5_AS, 0x3},
-       {OP_WR, USEM_REG_TS_6_AS, 0x0},
-       {OP_WR, USEM_REG_TS_7_AS, 0x1},
-       {OP_WR, USEM_REG_TS_8_AS, 0x4},
-       {OP_WR, USEM_REG_TS_9_AS, 0x0},
-       {OP_WR, USEM_REG_TS_10_AS, 0x1},
-       {OP_WR, USEM_REG_TS_11_AS, 0x3},
-       {OP_WR, USEM_REG_TS_12_AS, 0x0},
-       {OP_WR, USEM_REG_TS_13_AS, 0x1},
-       {OP_WR, USEM_REG_TS_14_AS, 0x4},
-       {OP_WR, USEM_REG_TS_15_AS, 0x0},
-       {OP_WR, USEM_REG_TS_16_AS, 0x4},
-       {OP_WR, USEM_REG_TS_17_AS, 0x3},
-       {OP_ZR, USEM_REG_TS_18_AS, 0x2},
-       {OP_WR, USEM_REG_ENABLE_IN, 0x3fff},
-       {OP_WR, USEM_REG_ENABLE_OUT, 0x3ff},
-       {OP_WR, USEM_REG_FIC0_DISABLE, 0x0},
-       {OP_WR, USEM_REG_FIC1_DISABLE, 0x0},
-       {OP_WR, USEM_REG_PAS_DISABLE, 0x0},
-       {OP_WR, USEM_REG_THREADS_LIST, 0xffff},
-       {OP_ZR, USEM_REG_PASSIVE_BUFFER, 0x800},
-       {OP_WR, USEM_REG_FAST_MEMORY + 0x18bc0, 0x1},
-       {OP_WR, USEM_REG_FAST_MEMORY + 0x18000, 0x1a},
-       {OP_WR, USEM_REG_FAST_MEMORY + 0x18040, 0x4e},
-       {OP_WR, USEM_REG_FAST_MEMORY + 0x18080, 0x10},
-       {OP_WR, USEM_REG_FAST_MEMORY + 0x180c0, 0x20},
-       {OP_WR_ASIC, USEM_REG_FAST_MEMORY + 0x18300, 0x7a120},
-       {OP_WR_EMUL, USEM_REG_FAST_MEMORY + 0x18300, 0x138},
-       {OP_WR_FPGA, USEM_REG_FAST_MEMORY + 0x18300, 0x1388},
-       {OP_WR, USEM_REG_FAST_MEMORY + 0x183c0, 0x1f4},
-       {OP_WR_ASIC, USEM_REG_FAST_MEMORY + 0x18380, 0x1dcd6500},
-       {OP_WR_EMUL, USEM_REG_FAST_MEMORY + 0x18380, 0x4c4b4},
-       {OP_WR_FPGA, USEM_REG_FAST_MEMORY + 0x18380, 0x4c4b40},
-       {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x5000, 0xc2},
-       {OP_WR_EMUL_E1H, USEM_REG_FAST_MEMORY + 0x11480, 0x0},
-       {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1020, 0xc8},
-       {OP_WR_E1H, USEM_REG_FAST_MEMORY + 0x11480, 0x1},
-       {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1000, 0x2},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x2000, 0x102},
-       {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x4640, 0x40},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x8980, 0xc8},
-       {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x57f0, 0x4},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x8960, 0x2},
-       {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x57d8, 0x5},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3228, 0x4},
-       {OP_SW_E1, USEM_REG_FAST_MEMORY + 0x57d8 + 0x14, 0x10281},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3200, 0x9},
-       {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1c60, 0x20},
-       {OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x3200 + 0x24, 0x102bb},
-       {OP_SW_E1, USEM_REG_FAST_MEMORY + 0x2830, 0x20282},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3180, 0x20},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5000, 0x400},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4000, 0x2},
-       {OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x4000 + 0x8, 0x102bc},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4000 + 0xc, 0x3},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x6b68, 0x2},
-       {OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x6b68 + 0x8, 0x202bd},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x6b10, 0x2},
-       {OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x74c0, 0x202bf},
-       {OP_WR, USEM_REG_FAST_MEMORY + 0x10800, 0x1000000},
-       {OP_SW_E1, USEM_REG_FAST_MEMORY + 0x10c00, 0x100284},
-       {OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x10c00, 0x1002c1},
-       {OP_WR, USEM_REG_FAST_MEMORY + 0x10800, 0x0},
-       {OP_SW_E1, USEM_REG_FAST_MEMORY + 0x10c40, 0x100294},
-       {OP_SW_E1H, USEM_REG_FAST_MEMORY + 0x10c40, 0x1002d1},
-       {OP_ZP_E1, USEM_REG_INT_TABLE, 0xc30000},
-       {OP_ZP_E1H, USEM_REG_INT_TABLE, 0xd20000},
-       {OP_WR_64_E1, USEM_REG_INT_TABLE + 0x368, 0x1302a4},
-       {OP_WR_64_E1H, USEM_REG_INT_TABLE + 0x3a8, 0xb02e1},
-       {OP_ZP_E1, USEM_REG_PRAM, 0x314c0000},
-       {OP_ZP_E1H, USEM_REG_PRAM, 0x31b60000},
-       {OP_ZP_E1, USEM_REG_PRAM + 0x8000, 0x35ef0c53},
-       {OP_ZP_E1H, USEM_REG_PRAM + 0x8000, 0x36500c6e},
-       {OP_ZP_E1, USEM_REG_PRAM + 0x10000, 0x361319cf},
-       {OP_ZP_E1H, USEM_REG_PRAM + 0x10000, 0x37591a02},
-       {OP_ZP_E1, USEM_REG_PRAM + 0x18000, 0x7112754},
-       {OP_ZP_E1H, USEM_REG_PRAM + 0x18000, 0x286127d9},
-       {OP_WR_64_E1, USEM_REG_PRAM + 0x18ee0, 0x4e2402a6},
-       {OP_WR_64_E1H, USEM_REG_PRAM + 0x1ff40, 0x401802e3},
-#define USEM_COMMON_END         842
-#define USEM_PORT0_START        842
-       {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1400, 0xa0},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x9000, 0xa0},
-       {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1900, 0x10},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x9500, 0x40},
-       {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1980, 0x30},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x9700, 0x3c},
-       {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x4740, 0xb4},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x2450, 0xb4},
-       {OP_WR_E1, USEM_REG_FAST_MEMORY + 0x1d90, 0x0},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x2ad0, 0x2},
-       {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1b40, 0x4},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3080, 0x20},
-       {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1b60, 0x20},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x8000, 0x12c},
-       {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x5318, 0x98},
-       {OP_WR_E1H, USEM_REG_FAST_MEMORY + 0x3238, 0x0},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5000, 0x20},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5100, 0x20},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5200, 0x20},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5300, 0x20},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5400, 0x20},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5500, 0x20},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5600, 0x20},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5700, 0x20},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5800, 0x20},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5900, 0x20},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5a00, 0x20},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5b00, 0x20},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5c00, 0x20},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5d00, 0x20},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5e00, 0x20},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5f00, 0x20},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x6b78, 0x52},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x6e08, 0xc},
-#define USEM_PORT0_END          876
-#define USEM_PORT1_START        876
-       {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1680, 0xa0},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x9280, 0xa0},
-       {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1940, 0x10},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x9600, 0x40},
-       {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1a40, 0x30},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x97f0, 0x3c},
-       {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x4a10, 0xb4},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x2720, 0xb4},
-       {OP_WR_E1, USEM_REG_FAST_MEMORY + 0x1d94, 0x0},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x2ad8, 0x2},
-       {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1b50, 0x4},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3100, 0x20},
-       {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x1be0, 0x20},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x84b0, 0x12c},
-       {OP_ZR_E1, USEM_REG_FAST_MEMORY + 0x5578, 0x98},
-       {OP_WR_E1H, USEM_REG_FAST_MEMORY + 0x323c, 0x0},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5080, 0x20},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5180, 0x20},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5280, 0x20},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5380, 0x20},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5480, 0x20},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5580, 0x20},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5680, 0x20},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5780, 0x20},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5880, 0x20},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5980, 0x20},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5a80, 0x20},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5b80, 0x20},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5c80, 0x20},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5d80, 0x20},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5e80, 0x20},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x5f80, 0x20},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x6cc0, 0x52},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x6e38, 0xc},
-#define USEM_PORT1_END          910
-#define USEM_FUNC0_START        910
-       {OP_WR_E1H, USEM_REG_FAST_MEMORY + 0x2a30, 0x0},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3000, 0x4},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4018, 0x2},
-#define USEM_FUNC0_END          913
-#define USEM_FUNC1_START        913
-       {OP_WR_E1H, USEM_REG_FAST_MEMORY + 0x2a34, 0x0},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3010, 0x4},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4028, 0x2},
-#define USEM_FUNC1_END          916
-#define USEM_FUNC2_START        916
-       {OP_WR_E1H, USEM_REG_FAST_MEMORY + 0x2a38, 0x0},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3020, 0x4},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4038, 0x2},
-#define USEM_FUNC2_END          919
-#define USEM_FUNC3_START        919
-       {OP_WR_E1H, USEM_REG_FAST_MEMORY + 0x2a3c, 0x0},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3030, 0x4},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4048, 0x2},
-#define USEM_FUNC3_END          922
-#define USEM_FUNC4_START        922
-       {OP_WR_E1H, USEM_REG_FAST_MEMORY + 0x2a40, 0x0},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3040, 0x4},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4058, 0x2},
-#define USEM_FUNC4_END          925
-#define USEM_FUNC5_START        925
-       {OP_WR_E1H, USEM_REG_FAST_MEMORY + 0x2a44, 0x0},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3050, 0x4},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4068, 0x2},
-#define USEM_FUNC5_END          928
-#define USEM_FUNC6_START        928
-       {OP_WR_E1H, USEM_REG_FAST_MEMORY + 0x2a48, 0x0},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3060, 0x4},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4078, 0x2},
-#define USEM_FUNC6_END          931
-#define USEM_FUNC7_START        931
-       {OP_WR_E1H, USEM_REG_FAST_MEMORY + 0x2a4c, 0x0},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x3070, 0x4},
-       {OP_ZR_E1H, USEM_REG_FAST_MEMORY + 0x4088, 0x2},
-#define USEM_FUNC7_END          934
-#define CSEM_COMMON_START       934
-       {OP_RD, CSEM_REG_MSG_NUM_FIC0, 0x0},
-       {OP_RD, CSEM_REG_MSG_NUM_FIC1, 0x0},
-       {OP_RD, CSEM_REG_MSG_NUM_FOC0, 0x0},
-       {OP_RD, CSEM_REG_MSG_NUM_FOC1, 0x0},
-       {OP_RD, CSEM_REG_MSG_NUM_FOC2, 0x0},
-       {OP_RD, CSEM_REG_MSG_NUM_FOC3, 0x0},
-       {OP_WR, CSEM_REG_ARB_ELEMENT0, 0x1},
-       {OP_WR, CSEM_REG_ARB_ELEMENT1, 0x2},
-       {OP_WR, CSEM_REG_ARB_ELEMENT2, 0x3},
-       {OP_WR, CSEM_REG_ARB_ELEMENT3, 0x0},
-       {OP_WR, CSEM_REG_ARB_ELEMENT4, 0x4},
-       {OP_WR, CSEM_REG_ARB_CYCLE_SIZE, 0x1},
-       {OP_WR, CSEM_REG_TS_0_AS, 0x0},
-       {OP_WR, CSEM_REG_TS_1_AS, 0x1},
-       {OP_WR, CSEM_REG_TS_2_AS, 0x4},
-       {OP_WR, CSEM_REG_TS_3_AS, 0x0},
-       {OP_WR, CSEM_REG_TS_4_AS, 0x1},
-       {OP_WR, CSEM_REG_TS_5_AS, 0x3},
-       {OP_WR, CSEM_REG_TS_6_AS, 0x0},
-       {OP_WR, CSEM_REG_TS_7_AS, 0x1},
-       {OP_WR, CSEM_REG_TS_8_AS, 0x4},
-       {OP_WR, CSEM_REG_TS_9_AS, 0x0},
-       {OP_WR, CSEM_REG_TS_10_AS, 0x1},
-       {OP_WR, CSEM_REG_TS_11_AS, 0x3},
-       {OP_WR, CSEM_REG_TS_12_AS, 0x0},
-       {OP_WR, CSEM_REG_TS_13_AS, 0x1},
-       {OP_WR, CSEM_REG_TS_14_AS, 0x4},
-       {OP_WR, CSEM_REG_TS_15_AS, 0x0},
-       {OP_WR, CSEM_REG_TS_16_AS, 0x4},
-       {OP_WR, CSEM_REG_TS_17_AS, 0x3},
-       {OP_ZR, CSEM_REG_TS_18_AS, 0x2},
-       {OP_WR, CSEM_REG_ENABLE_IN, 0x3fff},
-       {OP_WR, CSEM_REG_ENABLE_OUT, 0x3ff},
-       {OP_WR, CSEM_REG_FIC0_DISABLE, 0x0},
-       {OP_WR, CSEM_REG_FIC1_DISABLE, 0x0},
-       {OP_WR, CSEM_REG_PAS_DISABLE, 0x0},
-       {OP_WR, CSEM_REG_THREADS_LIST, 0xffff},
-       {OP_ZR, CSEM_REG_PASSIVE_BUFFER, 0x800},
-       {OP_WR, CSEM_REG_FAST_MEMORY + 0x18bc0, 0x1},
-       {OP_WR, CSEM_REG_FAST_MEMORY + 0x18000, 0x10},
-       {OP_WR, CSEM_REG_FAST_MEMORY + 0x18040, 0x12},
-       {OP_WR, CSEM_REG_FAST_MEMORY + 0x18080, 0x30},
-       {OP_WR, CSEM_REG_FAST_MEMORY + 0x180c0, 0xe},
-       {OP_WR, CSEM_REG_FAST_MEMORY + 0x183c0, 0x1f4},
-       {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x5000, 0x42},
-       {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x11480, 0x1},
-       {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x1020, 0xc8},
-       {OP_WR_EMUL_E1H, CSEM_REG_FAST_MEMORY + 0x11480, 0x0},
-       {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x1000, 0x2},
-       {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x1000, 0x42},
-       {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x2000, 0xc0},
-       {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x7020, 0xc8},
-       {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x3070, 0x80},
-       {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x7000, 0x2},
-       {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x4280, 0x4},
-       {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x11e8, 0x0},
-       {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x25c0, 0x240},
-       {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3000, 0xc0},
-       {OP_SW_E1, CSEM_REG_FAST_MEMORY + 0x2ec8, 0x802a8},
-       {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x4070, 0x80},
-       {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x5280, 0x4},
-       {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x6700, 0x100},
-       {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x9000, 0x400},
-       {OP_SW_E1H, CSEM_REG_FAST_MEMORY + 0x6b08, 0x2002e5},
-       {OP_WR, CSEM_REG_FAST_MEMORY + 0x10800, 0x13fffff},
-       {OP_SW_E1, CSEM_REG_FAST_MEMORY + 0x10c00, 0x1002b0},
-       {OP_SW_E1H, CSEM_REG_FAST_MEMORY + 0x10c00, 0x100305},
-       {OP_WR, CSEM_REG_FAST_MEMORY + 0x10800, 0x0},
-       {OP_SW_E1, CSEM_REG_FAST_MEMORY + 0x10c40, 0x1002c0},
-       {OP_SW_E1H, CSEM_REG_FAST_MEMORY + 0x10c40, 0x100315},
-       {OP_ZP_E1, CSEM_REG_INT_TABLE, 0x710000},
-       {OP_ZP_E1H, CSEM_REG_INT_TABLE, 0x740000},
-       {OP_WR_64_E1, CSEM_REG_INT_TABLE + 0x380, 0x1002d0},
-       {OP_WR_64_E1H, CSEM_REG_INT_TABLE + 0x380, 0x100325},
-       {OP_ZP_E1, CSEM_REG_PRAM, 0x32290000},
-       {OP_ZP_E1H, CSEM_REG_PRAM, 0x32260000},
-       {OP_ZP_E1, CSEM_REG_PRAM + 0x8000, 0x23630c8b},
-       {OP_ZP_E1H, CSEM_REG_PRAM + 0x8000, 0x246e0c8a},
-       {OP_WR_64_E1, CSEM_REG_PRAM + 0xc930, 0x654002d2},
-       {OP_WR_64_E1H, CSEM_REG_PRAM + 0xcbb0, 0x64f00327},
-#define CSEM_COMMON_END         1014
-#define CSEM_PORT0_START        1014
-       {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x1400, 0xa0},
-       {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x8000, 0xa0},
-       {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x1900, 0x10},
-       {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x8500, 0x40},
-       {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x1980, 0x30},
-       {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x8700, 0x3c},
-       {OP_WR_E1, CSEM_REG_FAST_MEMORY + 0x5118, 0x0},
-       {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x4040, 0x6},
-       {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x2300, 0xe},
-       {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x3040, 0x6},
-       {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x2410, 0x30},
-#define CSEM_PORT0_END          1025
-#define CSEM_PORT1_START        1025
-       {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x1680, 0xa0},
-       {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x8280, 0xa0},
-       {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x1940, 0x10},
-       {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x8600, 0x40},
-       {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x1a40, 0x30},
-       {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x87f0, 0x3c},
-       {OP_WR_E1, CSEM_REG_FAST_MEMORY + 0x511c, 0x0},
-       {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x4058, 0x6},
-       {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x2338, 0xe},
-       {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x3058, 0x6},
-       {OP_ZR_E1, CSEM_REG_FAST_MEMORY + 0x24d0, 0x30},
-#define CSEM_PORT1_END          1036
-#define CSEM_FUNC0_START        1036
-       {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x1148, 0x0},
-       {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3300, 0x2},
-       {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x6040, 0x30},
-#define CSEM_FUNC0_END          1039
-#define CSEM_FUNC1_START        1039
-       {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x114c, 0x0},
-       {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3308, 0x2},
-       {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x6100, 0x30},
-#define CSEM_FUNC1_END          1042
-#define CSEM_FUNC2_START        1042
-       {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x1150, 0x0},
-       {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3310, 0x2},
-       {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x61c0, 0x30},
-#define CSEM_FUNC2_END          1045
-#define CSEM_FUNC3_START        1045
-       {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x1154, 0x0},
-       {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3318, 0x2},
-       {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x6280, 0x30},
-#define CSEM_FUNC3_END          1048
-#define CSEM_FUNC4_START        1048
-       {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x1158, 0x0},
-       {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3320, 0x2},
-       {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x6340, 0x30},
-#define CSEM_FUNC4_END          1051
-#define CSEM_FUNC5_START        1051
-       {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x115c, 0x0},
-       {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3328, 0x2},
-       {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x6400, 0x30},
-#define CSEM_FUNC5_END          1054
-#define CSEM_FUNC6_START        1054
-       {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x1160, 0x0},
-       {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3330, 0x2},
-       {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x64c0, 0x30},
-#define CSEM_FUNC6_END          1057
-#define CSEM_FUNC7_START        1057
-       {OP_WR_E1H, CSEM_REG_FAST_MEMORY + 0x1164, 0x0},
-       {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x3338, 0x2},
-       {OP_ZR_E1H, CSEM_REG_FAST_MEMORY + 0x6580, 0x30},
-#define CSEM_FUNC7_END          1060
-#define XPB_COMMON_START        1060
-       {OP_WR, GRCBASE_XPB + PB_REG_CONTROL, 0x20},
-#define XPB_COMMON_END          1061
-#define DQ_COMMON_START         1061
-       {OP_WR, DORQ_REG_MODE_ACT, 0x2},
-       {OP_WR, DORQ_REG_NORM_CID_OFST, 0x3},
-       {OP_WR, DORQ_REG_OUTST_REQ, 0x4},
-       {OP_WR, DORQ_REG_DPM_CID_ADDR, 0x8},
-       {OP_WR, DORQ_REG_RSP_INIT_CRD, 0x2},
-       {OP_WR, DORQ_REG_NORM_CMHEAD_TX, 0x90},
-       {OP_WR, DORQ_REG_CMHEAD_RX, 0x90},
-       {OP_WR, DORQ_REG_SHRT_CMHEAD, 0x800090},
-       {OP_WR, DORQ_REG_ERR_CMHEAD, 0x8140000},
-       {OP_WR, DORQ_REG_AGG_CMD0, 0x8a},
-       {OP_WR, DORQ_REG_AGG_CMD1, 0x80},
-       {OP_WR, DORQ_REG_AGG_CMD2, 0x90},
-       {OP_WR, DORQ_REG_AGG_CMD3, 0x80},
-       {OP_WR, DORQ_REG_SHRT_ACT_CNT, 0x6},
-       {OP_WR, DORQ_REG_DQ_FIFO_FULL_TH, 0x7d0},
-       {OP_WR, DORQ_REG_DQ_FIFO_AFULL_TH, 0x76c},
-       {OP_WR, DORQ_REG_REGN, 0x7c1004},
-       {OP_WR, DORQ_REG_IF_EN, 0xf},
-#define DQ_COMMON_END           1079
-#define TIMERS_COMMON_START     1079
-       {OP_ZR, TM_REG_CLIN_PRIOR0_CLIENT, 0x2},
-       {OP_WR, TM_REG_LIN_SETCLR_FIFO_ALFULL_THR, 0x1c},
-       {OP_WR, TM_REG_CFC_AC_CRDCNT_VAL, 0x1},
-       {OP_WR, TM_REG_CFC_CLD_CRDCNT_VAL, 0x1},
-       {OP_WR, TM_REG_CLOUT_CRDCNT0_VAL, 0x1},
-       {OP_WR, TM_REG_CLOUT_CRDCNT1_VAL, 0x1},
-       {OP_WR, TM_REG_CLOUT_CRDCNT2_VAL, 0x1},
-       {OP_WR, TM_REG_EXP_CRDCNT_VAL, 0x1},
-       {OP_WR_E1, TM_REG_PCIARB_CRDCNT_VAL, 0x1},
-       {OP_WR_E1H, TM_REG_PCIARB_CRDCNT_VAL, 0x2},
-       {OP_WR_ASIC, TM_REG_TIMER_TICK_SIZE, 0x3d090},
-       {OP_WR_EMUL, TM_REG_TIMER_TICK_SIZE, 0x9c},
-       {OP_WR_FPGA, TM_REG_TIMER_TICK_SIZE, 0x9c4},
-       {OP_WR, TM_REG_CL0_CONT_REGION, 0x8},
-       {OP_WR, TM_REG_CL1_CONT_REGION, 0xc},
-       {OP_WR, TM_REG_CL2_CONT_REGION, 0x10},
-       {OP_WR, TM_REG_TM_CONTEXT_REGION, 0x20},
-       {OP_WR, TM_REG_EN_TIMERS, 0x1},
-       {OP_WR, TM_REG_EN_REAL_TIME_CNT, 0x1},
-       {OP_WR, TM_REG_EN_CL0_INPUT, 0x1},
-       {OP_WR, TM_REG_EN_CL1_INPUT, 0x1},
-       {OP_WR, TM_REG_EN_CL2_INPUT, 0x1},
-#define TIMERS_COMMON_END       1101
-#define TIMERS_PORT0_START      1101
-       {OP_WR, TM_REG_LIN0_LOGIC_ADDR, 0x0},
-       {OP_WR, TM_REG_LIN0_PHY_ADDR_VALID, 0x0},
-       {OP_ZR, TM_REG_LIN0_PHY_ADDR, 0x2},
-#define TIMERS_PORT0_END        1104
-#define TIMERS_PORT1_START      1104
-       {OP_WR, TM_REG_LIN1_LOGIC_ADDR, 0x0},
-       {OP_WR, TM_REG_LIN1_PHY_ADDR_VALID, 0x0},
-       {OP_ZR, TM_REG_LIN1_PHY_ADDR, 0x2},
-#define TIMERS_PORT1_END        1107
-#define XSDM_COMMON_START       1107
-       {OP_WR_E1, XSDM_REG_CFC_RSP_START_ADDR, 0x614},
-       {OP_WR_E1H, XSDM_REG_CFC_RSP_START_ADDR, 0x424},
-       {OP_WR_E1, XSDM_REG_CMP_COUNTER_START_ADDR, 0x600},
-       {OP_WR_E1H, XSDM_REG_CMP_COUNTER_START_ADDR, 0x410},
-       {OP_WR_E1, XSDM_REG_Q_COUNTER_START_ADDR, 0x604},
-       {OP_WR_E1H, XSDM_REG_Q_COUNTER_START_ADDR, 0x414},
-       {OP_WR, XSDM_REG_CMP_COUNTER_MAX0, 0xffff},
-       {OP_WR, XSDM_REG_CMP_COUNTER_MAX1, 0xffff},
-       {OP_WR, XSDM_REG_CMP_COUNTER_MAX2, 0xffff},
-       {OP_WR, XSDM_REG_CMP_COUNTER_MAX3, 0xffff},
-       {OP_WR, XSDM_REG_AGG_INT_EVENT_0, 0x20},
-       {OP_WR, XSDM_REG_AGG_INT_EVENT_1, 0x20},
-       {OP_WR, XSDM_REG_AGG_INT_EVENT_2, 0x34},
-       {OP_WR, XSDM_REG_AGG_INT_EVENT_3, 0x35},
-       {OP_WR, XSDM_REG_AGG_INT_EVENT_4, 0x23},
-       {OP_WR, XSDM_REG_AGG_INT_EVENT_5, 0x24},
-       {OP_WR, XSDM_REG_AGG_INT_EVENT_6, 0x25},
-       {OP_WR, XSDM_REG_AGG_INT_EVENT_7, 0x26},
-       {OP_WR, XSDM_REG_AGG_INT_EVENT_8, 0x27},
-       {OP_WR, XSDM_REG_AGG_INT_EVENT_9, 0x29},
-       {OP_WR, XSDM_REG_AGG_INT_EVENT_10, 0x2a},
-       {OP_WR, XSDM_REG_AGG_INT_EVENT_11, 0x2b},
-       {OP_WR, XSDM_REG_AGG_INT_EVENT_12, 0x2c},
-       {OP_WR, XSDM_REG_AGG_INT_EVENT_13, 0x2d},
-       {OP_ZR, XSDM_REG_AGG_INT_EVENT_14, 0x52},
-       {OP_WR, XSDM_REG_AGG_INT_MODE_0, 0x1},
-       {OP_ZR, XSDM_REG_AGG_INT_MODE_1, 0x1f},
-       {OP_WR, XSDM_REG_ENABLE_IN1, 0x7ffffff},
-       {OP_WR, XSDM_REG_ENABLE_IN2, 0x3f},
-       {OP_WR, XSDM_REG_ENABLE_OUT1, 0x7ffffff},
-       {OP_WR, XSDM_REG_ENABLE_OUT2, 0xf},
-       {OP_RD, XSDM_REG_NUM_OF_Q0_CMD, 0x0},
-       {OP_RD, XSDM_REG_NUM_OF_Q1_CMD, 0x0},
-       {OP_RD, XSDM_REG_NUM_OF_Q3_CMD, 0x0},
-       {OP_RD, XSDM_REG_NUM_OF_Q4_CMD, 0x0},
-       {OP_RD, XSDM_REG_NUM_OF_Q5_CMD, 0x0},
-       {OP_RD, XSDM_REG_NUM_OF_Q6_CMD, 0x0},
-       {OP_RD, XSDM_REG_NUM_OF_Q7_CMD, 0x0},
-       {OP_RD, XSDM_REG_NUM_OF_Q8_CMD, 0x0},
-       {OP_RD, XSDM_REG_NUM_OF_Q9_CMD, 0x0},
-       {OP_RD, XSDM_REG_NUM_OF_Q10_CMD, 0x0},
-       {OP_RD, XSDM_REG_NUM_OF_Q11_CMD, 0x0},
-       {OP_RD, XSDM_REG_NUM_OF_PKT_END_MSG, 0x0},
-       {OP_RD, XSDM_REG_NUM_OF_PXP_ASYNC_REQ, 0x0},
-       {OP_RD, XSDM_REG_NUM_OF_ACK_AFTER_PLACE, 0x0},
-       {OP_WR_E1, XSDM_REG_INIT_CREDIT_PXP_CTRL, 0x1},
-       {OP_WR_ASIC, XSDM_REG_TIMER_TICK, 0x3e8},
-       {OP_WR_EMUL, XSDM_REG_TIMER_TICK, 0x1},
-       {OP_WR_FPGA, XSDM_REG_TIMER_TICK, 0xa},
-#define XSDM_COMMON_END         1156
-#define QM_COMMON_START         1156
-       {OP_WR, QM_REG_ACTCTRINITVAL_0, 0x6},
-       {OP_WR, QM_REG_ACTCTRINITVAL_1, 0x5},
-       {OP_WR, QM_REG_ACTCTRINITVAL_2, 0xa},
-       {OP_WR, QM_REG_ACTCTRINITVAL_3, 0x5},
-       {OP_WR, QM_REG_PCIREQAT, 0x2},
-       {OP_WR, QM_REG_CMINITCRD_0, 0x4},
-       {OP_WR, QM_REG_CMINITCRD_1, 0x4},
-       {OP_WR, QM_REG_CMINITCRD_2, 0x4},
-       {OP_WR, QM_REG_CMINITCRD_3, 0x4},
-       {OP_WR, QM_REG_CMINITCRD_4, 0x4},
-       {OP_WR, QM_REG_CMINITCRD_5, 0x4},
-       {OP_WR, QM_REG_CMINITCRD_6, 0x4},
-       {OP_WR, QM_REG_CMINITCRD_7, 0x4},
-       {OP_WR, QM_REG_OUTLDREQ, 0x4},
-       {OP_WR, QM_REG_CTXREG_0, 0x7c},
-       {OP_WR, QM_REG_CTXREG_1, 0x3d},
-       {OP_WR, QM_REG_CTXREG_2, 0x3f},
-       {OP_WR, QM_REG_CTXREG_3, 0x9c},
-       {OP_WR, QM_REG_ENSEC, 0x7},
-       {OP_ZR, QM_REG_QVOQIDX_0, 0x5},
-       {OP_WR, QM_REG_WRRWEIGHTS_0, 0x1010101},
-       {OP_WR, QM_REG_QVOQIDX_5, 0x0},
-       {OP_WR, QM_REG_QVOQIDX_6, 0x4},
-       {OP_WR, QM_REG_QVOQIDX_7, 0x4},
-       {OP_WR, QM_REG_QVOQIDX_8, 0x2},
-       {OP_WR, QM_REG_WRRWEIGHTS_1, 0x8012004},
-       {OP_WR, QM_REG_QVOQIDX_9, 0x5},
-       {OP_WR, QM_REG_QVOQIDX_10, 0x5},
-       {OP_WR, QM_REG_QVOQIDX_11, 0x5},
-       {OP_WR, QM_REG_QVOQIDX_12, 0x5},
-       {OP_WR, QM_REG_WRRWEIGHTS_2, 0x20081001},
-       {OP_WR, QM_REG_QVOQIDX_13, 0x8},
-       {OP_WR, QM_REG_QVOQIDX_14, 0x6},
-       {OP_WR, QM_REG_QVOQIDX_15, 0x7},
-       {OP_WR, QM_REG_QVOQIDX_16, 0x0},
-       {OP_WR, QM_REG_WRRWEIGHTS_3, 0x1010120},
-       {OP_ZR, QM_REG_QVOQIDX_17, 0x4},
-       {OP_WR, QM_REG_WRRWEIGHTS_4, 0x1010101},
-       {OP_ZR_E1, QM_REG_QVOQIDX_21, 0x4},
-       {OP_WR_E1H, QM_REG_QVOQIDX_21, 0x0},
-       {OP_WR_E1, QM_REG_WRRWEIGHTS_5, 0x1010101},
-       {OP_WR_E1H, QM_REG_QVOQIDX_22, 0x4},
-       {OP_ZR_E1, QM_REG_QVOQIDX_25, 0x4},
-       {OP_WR_E1H, QM_REG_QVOQIDX_23, 0x4},
-       {OP_WR_E1, QM_REG_WRRWEIGHTS_6, 0x1010101},
-       {OP_WR_E1H, QM_REG_QVOQIDX_24, 0x2},
-       {OP_ZR_E1, QM_REG_QVOQIDX_29, 0x3},
-       {OP_WR_E1H, QM_REG_WRRWEIGHTS_5, 0x8012004},
-       {OP_WR_E1H, QM_REG_QVOQIDX_25, 0x5},
-       {OP_WR_E1H, QM_REG_QVOQIDX_26, 0x5},
-       {OP_WR_E1H, QM_REG_QVOQIDX_27, 0x5},
-       {OP_WR_E1H, QM_REG_QVOQIDX_28, 0x5},
-       {OP_WR_E1H, QM_REG_WRRWEIGHTS_6, 0x20081001},
-       {OP_WR_E1H, QM_REG_QVOQIDX_29, 0x8},
-       {OP_WR_E1H, QM_REG_QVOQIDX_30, 0x6},
-       {OP_WR_E1H, QM_REG_QVOQIDX_31, 0x7},
-       {OP_WR, QM_REG_QVOQIDX_32, 0x1},
-       {OP_WR_E1, QM_REG_WRRWEIGHTS_7, 0x1010101},
-       {OP_WR_E1H, QM_REG_WRRWEIGHTS_7, 0x1010120},
-       {OP_WR, QM_REG_QVOQIDX_33, 0x1},
-       {OP_WR, QM_REG_QVOQIDX_34, 0x1},
-       {OP_WR, QM_REG_QVOQIDX_35, 0x1},
-       {OP_WR, QM_REG_QVOQIDX_36, 0x1},
-       {OP_WR, QM_REG_WRRWEIGHTS_8, 0x1010101},
-       {OP_WR, QM_REG_QVOQIDX_37, 0x1},
-       {OP_WR, QM_REG_QVOQIDX_38, 0x4},
-       {OP_WR, QM_REG_QVOQIDX_39, 0x4},
-       {OP_WR, QM_REG_QVOQIDX_40, 0x2},
-       {OP_WR, QM_REG_WRRWEIGHTS_9, 0x8012004},
-       {OP_WR, QM_REG_QVOQIDX_41, 0x5},
-       {OP_WR, QM_REG_QVOQIDX_42, 0x5},
-       {OP_WR, QM_REG_QVOQIDX_43, 0x5},
-       {OP_WR, QM_REG_QVOQIDX_44, 0x5},
-       {OP_WR, QM_REG_WRRWEIGHTS_10, 0x20081001},
-       {OP_WR, QM_REG_QVOQIDX_45, 0x8},
-       {OP_WR, QM_REG_QVOQIDX_46, 0x6},
-       {OP_WR, QM_REG_QVOQIDX_47, 0x7},
-       {OP_WR, QM_REG_QVOQIDX_48, 0x1},
-       {OP_WR, QM_REG_WRRWEIGHTS_11, 0x1010120},
-       {OP_WR, QM_REG_QVOQIDX_49, 0x1},
-       {OP_WR, QM_REG_QVOQIDX_50, 0x1},
-       {OP_WR, QM_REG_QVOQIDX_51, 0x1},
-       {OP_WR, QM_REG_QVOQIDX_52, 0x1},
-       {OP_WR, QM_REG_WRRWEIGHTS_12, 0x1010101},
-       {OP_WR, QM_REG_QVOQIDX_53, 0x1},
-       {OP_WR_E1, QM_REG_QVOQIDX_54, 0x1},
-       {OP_WR_E1H, QM_REG_QVOQIDX_54, 0x4},
-       {OP_WR_E1, QM_REG_QVOQIDX_55, 0x1},
-       {OP_WR_E1H, QM_REG_QVOQIDX_55, 0x4},
-       {OP_WR_E1, QM_REG_QVOQIDX_56, 0x1},
-       {OP_WR_E1H, QM_REG_QVOQIDX_56, 0x2},
-       {OP_WR_E1, QM_REG_WRRWEIGHTS_13, 0x1010101},
-       {OP_WR_E1H, QM_REG_WRRWEIGHTS_13, 0x8012004},
-       {OP_WR_E1, QM_REG_QVOQIDX_57, 0x1},
-       {OP_WR_E1H, QM_REG_QVOQIDX_57, 0x5},
-       {OP_WR_E1, QM_REG_QVOQIDX_58, 0x1},
-       {OP_WR_E1H, QM_REG_QVOQIDX_58, 0x5},
-       {OP_WR_E1, QM_REG_QVOQIDX_59, 0x1},
-       {OP_WR_E1H, QM_REG_QVOQIDX_59, 0x5},
-       {OP_WR_E1, QM_REG_QVOQIDX_60, 0x1},
-       {OP_WR_E1H, QM_REG_QVOQIDX_60, 0x5},
-       {OP_WR_E1, QM_REG_WRRWEIGHTS_14, 0x1010101},
-       {OP_WR_E1H, QM_REG_WRRWEIGHTS_14, 0x20081001},
-       {OP_WR_E1, QM_REG_QVOQIDX_61, 0x1},
-       {OP_WR_E1H, QM_REG_QVOQIDX_61, 0x8},
-       {OP_WR_E1, QM_REG_QVOQIDX_62, 0x1},
-       {OP_WR_E1H, QM_REG_QVOQIDX_62, 0x6},
-       {OP_WR_E1, QM_REG_QVOQIDX_63, 0x1},
-       {OP_WR_E1H, QM_REG_QVOQIDX_63, 0x7},
-       {OP_WR_E1, QM_REG_WRRWEIGHTS_15, 0x1010101},
-       {OP_WR_E1H, QM_REG_QVOQIDX_64, 0x0},
-       {OP_WR_E1, QM_REG_VOQQMASK_0_LSB, 0xffff003f},
-       {OP_WR_E1H, QM_REG_WRRWEIGHTS_15, 0x1010120},
-       {OP_ZR_E1, QM_REG_VOQQMASK_0_MSB, 0x2},
-       {OP_ZR_E1H, QM_REG_QVOQIDX_65, 0x4},
-       {OP_WR_E1, QM_REG_VOQQMASK_1_MSB, 0xffff003f},
-       {OP_WR_E1H, QM_REG_WRRWEIGHTS_16, 0x1010101},
-       {OP_WR_E1, QM_REG_VOQQMASK_2_LSB, 0x100},
-       {OP_WR_E1H, QM_REG_QVOQIDX_69, 0x0},
-       {OP_WR_E1, QM_REG_VOQQMASK_2_MSB, 0x100},
-       {OP_WR_E1H, QM_REG_QVOQIDX_70, 0x4},
-       {OP_WR_E1H, QM_REG_QVOQIDX_71, 0x4},
-       {OP_WR_E1H, QM_REG_QVOQIDX_72, 0x2},
-       {OP_WR_E1H, QM_REG_WRRWEIGHTS_17, 0x8012004},
-       {OP_WR_E1H, QM_REG_QVOQIDX_73, 0x5},
-       {OP_WR_E1H, QM_REG_QVOQIDX_74, 0x5},
-       {OP_WR_E1H, QM_REG_QVOQIDX_75, 0x5},
-       {OP_WR_E1H, QM_REG_QVOQIDX_76, 0x5},
-       {OP_WR_E1H, QM_REG_WRRWEIGHTS_18, 0x20081001},
-       {OP_WR_E1H, QM_REG_QVOQIDX_77, 0x8},
-       {OP_WR_E1H, QM_REG_QVOQIDX_78, 0x6},
-       {OP_WR_E1H, QM_REG_QVOQIDX_79, 0x7},
-       {OP_WR_E1H, QM_REG_QVOQIDX_80, 0x0},
-       {OP_WR_E1H, QM_REG_WRRWEIGHTS_19, 0x1010120},
-       {OP_ZR_E1H, QM_REG_QVOQIDX_81, 0x4},
-       {OP_WR_E1H, QM_REG_WRRWEIGHTS_20, 0x1010101},
-       {OP_WR_E1H, QM_REG_QVOQIDX_85, 0x0},
-       {OP_WR_E1H, QM_REG_QVOQIDX_86, 0x4},
-       {OP_WR_E1H, QM_REG_QVOQIDX_87, 0x4},
-       {OP_WR_E1H, QM_REG_QVOQIDX_88, 0x2},
-       {OP_WR_E1H, QM_REG_WRRWEIGHTS_21, 0x8012004},
-       {OP_WR_E1H, QM_REG_QVOQIDX_89, 0x5},
-       {OP_WR_E1H, QM_REG_QVOQIDX_90, 0x5},
-       {OP_WR_E1H, QM_REG_QVOQIDX_91, 0x5},
-       {OP_WR_E1H, QM_REG_QVOQIDX_92, 0x5},
-       {OP_WR_E1H, QM_REG_WRRWEIGHTS_22, 0x20081001},
-       {OP_WR_E1H, QM_REG_QVOQIDX_93, 0x8},
-       {OP_WR_E1H, QM_REG_QVOQIDX_94, 0x6},
-       {OP_WR_E1H, QM_REG_QVOQIDX_95, 0x7},
-       {OP_WR_E1H, QM_REG_QVOQIDX_96, 0x1},
-       {OP_WR_E1H, QM_REG_WRRWEIGHTS_23, 0x1010120},
-       {OP_WR_E1H, QM_REG_QVOQIDX_97, 0x1},
-       {OP_WR_E1H, QM_REG_QVOQIDX_98, 0x1},
-       {OP_WR_E1H, QM_REG_QVOQIDX_99, 0x1},
-       {OP_WR_E1H, QM_REG_QVOQIDX_100, 0x1},
-       {OP_WR_E1H, QM_REG_WRRWEIGHTS_24, 0x1010101},
-       {OP_WR_E1H, QM_REG_QVOQIDX_101, 0x1},
-       {OP_WR_E1H, QM_REG_QVOQIDX_102, 0x4},
-       {OP_WR_E1H, QM_REG_QVOQIDX_103, 0x4},
-       {OP_WR_E1H, QM_REG_QVOQIDX_104, 0x2},
-       {OP_WR_E1H, QM_REG_WRRWEIGHTS_25, 0x8012004},
-       {OP_WR_E1H, QM_REG_QVOQIDX_105, 0x5},
-       {OP_WR_E1H, QM_REG_QVOQIDX_106, 0x5},
-       {OP_WR_E1H, QM_REG_QVOQIDX_107, 0x5},
-       {OP_WR_E1H, QM_REG_QVOQIDX_108, 0x5},
-       {OP_WR_E1H, QM_REG_WRRWEIGHTS_26, 0x20081001},
-       {OP_WR_E1H, QM_REG_QVOQIDX_109, 0x8},
-       {OP_WR_E1H, QM_REG_QVOQIDX_110, 0x6},
-       {OP_WR_E1H, QM_REG_QVOQIDX_111, 0x7},
-       {OP_WR_E1H, QM_REG_QVOQIDX_112, 0x1},
-       {OP_WR_E1H, QM_REG_WRRWEIGHTS_27, 0x1010120},
-       {OP_WR_E1H, QM_REG_QVOQIDX_113, 0x1},
-       {OP_WR_E1H, QM_REG_QVOQIDX_114, 0x1},
-       {OP_WR_E1H, QM_REG_QVOQIDX_115, 0x1},
-       {OP_WR_E1H, QM_REG_QVOQIDX_116, 0x1},
-       {OP_WR_E1H, QM_REG_WRRWEIGHTS_28, 0x1010101},
-       {OP_WR_E1H, QM_REG_QVOQIDX_117, 0x1},
-       {OP_WR_E1H, QM_REG_QVOQIDX_118, 0x4},
-       {OP_WR_E1H, QM_REG_QVOQIDX_119, 0x4},
-       {OP_WR_E1H, QM_REG_QVOQIDX_120, 0x2},
-       {OP_WR_E1H, QM_REG_WRRWEIGHTS_29, 0x8012004},
-       {OP_WR_E1H, QM_REG_QVOQIDX_121, 0x5},
-       {OP_WR_E1H, QM_REG_QVOQIDX_122, 0x5},
-       {OP_WR_E1H, QM_REG_QVOQIDX_123, 0x5},
-       {OP_WR_E1H, QM_REG_QVOQIDX_124, 0x5},
-       {OP_WR_E1H, QM_REG_WRRWEIGHTS_30, 0x20081001},
-       {OP_WR_E1H, QM_REG_QVOQIDX_125, 0x8},
-       {OP_WR_E1H, QM_REG_QVOQIDX_126, 0x6},
-       {OP_WR_E1H, QM_REG_QVOQIDX_127, 0x7},
-       {OP_WR_E1H, QM_REG_WRRWEIGHTS_31, 0x1010120},
-       {OP_WR_E1H, QM_REG_VOQQMASK_0_LSB, 0x3f003f},
-       {OP_WR_E1H, QM_REG_VOQQMASK_0_MSB, 0x0},
-       {OP_WR_E1H, QM_REG_VOQQMASK_0_LSB_EXT_A, 0x3f003f},
-       {OP_WR_E1H, QM_REG_VOQQMASK_0_MSB_EXT_A, 0x0},
-       {OP_WR_E1H, QM_REG_VOQQMASK_1_LSB, 0x0},
-       {OP_WR_E1H, QM_REG_VOQQMASK_1_MSB, 0x3f003f},
-       {OP_WR_E1H, QM_REG_VOQQMASK_1_LSB_EXT_A, 0x0},
-       {OP_WR_E1H, QM_REG_VOQQMASK_1_MSB_EXT_A, 0x3f003f},
-       {OP_WR_E1H, QM_REG_VOQQMASK_2_LSB, 0x1000100},
-       {OP_WR_E1H, QM_REG_VOQQMASK_2_MSB, 0x1000100},
-       {OP_WR_E1H, QM_REG_VOQQMASK_2_LSB_EXT_A, 0x1000100},
-       {OP_WR_E1H, QM_REG_VOQQMASK_2_MSB_EXT_A, 0x1000100},
-       {OP_ZR, QM_REG_VOQQMASK_3_LSB, 0x2},
-       {OP_WR_E1, QM_REG_VOQQMASK_4_LSB, 0xc0},
-       {OP_WR_E1H, QM_REG_VOQQMASK_3_LSB_EXT_A, 0x0},
-       {OP_WR_E1, QM_REG_VOQQMASK_4_MSB, 0xc0},
-       {OP_WR_E1H, QM_REG_VOQQMASK_3_MSB_EXT_A, 0x0},
-       {OP_WR_E1, QM_REG_VOQQMASK_5_LSB, 0x1e00},
-       {OP_WR_E1H, QM_REG_VOQQMASK_4_LSB, 0xc000c0},
-       {OP_WR_E1, QM_REG_VOQQMASK_5_MSB, 0x1e00},
-       {OP_WR_E1H, QM_REG_VOQQMASK_4_MSB, 0xc000c0},
-       {OP_WR_E1, QM_REG_VOQQMASK_6_LSB, 0x4000},
-       {OP_WR_E1H, QM_REG_VOQQMASK_4_LSB_EXT_A, 0xc000c0},
-       {OP_WR_E1, QM_REG_VOQQMASK_6_MSB, 0x4000},
-       {OP_WR_E1H, QM_REG_VOQQMASK_4_MSB_EXT_A, 0xc000c0},
-       {OP_WR_E1, QM_REG_VOQQMASK_7_LSB, 0x8000},
-       {OP_WR_E1H, QM_REG_VOQQMASK_5_LSB, 0x1e001e00},
-       {OP_WR_E1, QM_REG_VOQQMASK_7_MSB, 0x8000},
-       {OP_WR_E1H, QM_REG_VOQQMASK_5_MSB, 0x1e001e00},
-       {OP_WR_E1, QM_REG_VOQQMASK_8_LSB, 0x2000},
-       {OP_WR_E1H, QM_REG_VOQQMASK_5_LSB_EXT_A, 0x1e001e00},
-       {OP_WR_E1, QM_REG_VOQQMASK_8_MSB, 0x2000},
-       {OP_WR_E1H, QM_REG_VOQQMASK_5_MSB_EXT_A, 0x1e001e00},
-       {OP_ZR_E1, QM_REG_VOQQMASK_9_LSB, 0x7},
-       {OP_WR_E1H, QM_REG_VOQQMASK_6_LSB, 0x40004000},
-       {OP_WR_E1H, QM_REG_VOQQMASK_6_MSB, 0x40004000},
-       {OP_WR_E1H, QM_REG_VOQQMASK_6_LSB_EXT_A, 0x40004000},
-       {OP_WR_E1H, QM_REG_VOQQMASK_6_MSB_EXT_A, 0x40004000},
-       {OP_WR_E1H, QM_REG_VOQQMASK_7_LSB, 0x80008000},
-       {OP_WR_E1H, QM_REG_VOQQMASK_7_MSB, 0x80008000},
-       {OP_WR_E1H, QM_REG_VOQQMASK_7_LSB_EXT_A, 0x80008000},
-       {OP_WR_E1H, QM_REG_VOQQMASK_7_MSB_EXT_A, 0x80008000},
-       {OP_WR_E1H, QM_REG_VOQQMASK_8_LSB, 0x20002000},
-       {OP_WR_E1H, QM_REG_VOQQMASK_8_MSB, 0x20002000},
-       {OP_WR_E1H, QM_REG_VOQQMASK_8_LSB_EXT_A, 0x20002000},
-       {OP_WR_E1H, QM_REG_VOQQMASK_8_MSB_EXT_A, 0x20002000},
-       {OP_ZR_E1H, QM_REG_VOQQMASK_9_LSB, 0x2},
-       {OP_WR_E1H, QM_REG_VOQQMASK_9_LSB_EXT_A, 0x0},
-       {OP_WR_E1H, QM_REG_VOQQMASK_9_MSB_EXT_A, 0x0},
-       {OP_WR_E1H, QM_REG_VOQQMASK_10_LSB, 0x0},
-       {OP_WR_E1H, QM_REG_VOQQMASK_10_MSB, 0x0},
-       {OP_WR_E1H, QM_REG_VOQQMASK_10_LSB_EXT_A, 0x0},
-       {OP_WR_E1H, QM_REG_VOQQMASK_10_MSB_EXT_A, 0x0},
-       {OP_WR_E1H, QM_REG_VOQQMASK_11_LSB, 0x0},
-       {OP_WR_E1H, QM_REG_VOQQMASK_11_MSB, 0x0},
-       {OP_WR_E1H, QM_REG_VOQQMASK_11_LSB_EXT_A, 0x0},
-       {OP_WR_E1H, QM_REG_VOQQMASK_11_MSB_EXT_A, 0x0},
-       {OP_WR_E1H, QM_REG_VOQPORT_0, 0x0},
-       {OP_WR, QM_REG_VOQPORT_1, 0x1},
-       {OP_ZR, QM_REG_VOQPORT_2, 0xa},
-       {OP_WR, QM_REG_CMINTVOQMASK_0, 0xc08},
-       {OP_WR, QM_REG_CMINTVOQMASK_1, 0x40},
-       {OP_WR, QM_REG_CMINTVOQMASK_2, 0x100},
-       {OP_WR, QM_REG_CMINTVOQMASK_3, 0x20},
-       {OP_WR, QM_REG_CMINTVOQMASK_4, 0x17},
-       {OP_WR, QM_REG_CMINTVOQMASK_5, 0x80},
-       {OP_WR, QM_REG_CMINTVOQMASK_6, 0x200},
-       {OP_WR, QM_REG_CMINTVOQMASK_7, 0x0},
-       {OP_WR_E1, QM_REG_HWAEMPTYMASK_LSB, 0xffff01ff},
-       {OP_WR_E1H, QM_REG_HWAEMPTYMASK_LSB, 0x1ff01ff},
-       {OP_WR_E1, QM_REG_HWAEMPTYMASK_MSB, 0xffff01ff},
-       {OP_WR_E1H, QM_REG_HWAEMPTYMASK_MSB, 0x1ff01ff},
-       {OP_WR_E1H, QM_REG_HWAEMPTYMASK_LSB_EXT_A, 0x1ff01ff},
-       {OP_WR_E1H, QM_REG_HWAEMPTYMASK_MSB_EXT_A, 0x1ff01ff},
-       {OP_WR, QM_REG_ENBYPVOQMASK, 0x13},
-       {OP_WR, QM_REG_VOQCREDITAFULLTHR, 0x13f},
-       {OP_WR, QM_REG_VOQINITCREDIT_0, 0x140},
-       {OP_WR, QM_REG_VOQINITCREDIT_1, 0x140},
-       {OP_ZR, QM_REG_VOQINITCREDIT_2, 0x2},
-       {OP_WR, QM_REG_VOQINITCREDIT_4, 0xc0},
-       {OP_ZR, QM_REG_VOQINITCREDIT_5, 0x7},
-       {OP_WR, QM_REG_TASKCRDCOST_0, 0x48},
-       {OP_WR, QM_REG_TASKCRDCOST_1, 0x48},
-       {OP_ZR, QM_REG_TASKCRDCOST_2, 0x2},
-       {OP_WR, QM_REG_TASKCRDCOST_4, 0x48},
-       {OP_ZR, QM_REG_TASKCRDCOST_5, 0x7},
-       {OP_WR, QM_REG_BYTECRDINITVAL, 0x8000},
-       {OP_WR, QM_REG_BYTECRDCOST, 0x25e4},
-       {OP_WR, QM_REG_BYTECREDITAFULLTHR, 0x7fff},
-       {OP_WR_E1, QM_REG_ENBYTECRD_LSB, 0x7},
-       {OP_WR_E1H, QM_REG_ENBYTECRD_LSB, 0x70007},
-       {OP_WR_E1, QM_REG_ENBYTECRD_MSB, 0x7},
-       {OP_WR_E1H, QM_REG_ENBYTECRD_MSB, 0x70007},
-       {OP_WR_E1H, QM_REG_ENBYTECRD_LSB_EXT_A, 0x70007},
-       {OP_WR_E1H, QM_REG_ENBYTECRD_MSB_EXT_A, 0x70007},
-       {OP_WR, QM_REG_BYTECRDPORT_LSB, 0x0},
-       {OP_WR, QM_REG_BYTECRDPORT_MSB, 0xffffffff},
-       {OP_WR_E1, QM_REG_FUNCNUMSEL_LSB, 0x0},
-       {OP_WR_E1H, QM_REG_BYTECRDPORT_LSB_EXT_A, 0x0},
-       {OP_WR_E1, QM_REG_FUNCNUMSEL_MSB, 0xffffffff},
-       {OP_WR_E1H, QM_REG_BYTECRDPORT_MSB_EXT_A, 0xffffffff},
-       {OP_WR_E1H, QM_REG_PQ2PCIFUNC_0, 0x0},
-       {OP_WR_E1H, QM_REG_PQ2PCIFUNC_1, 0x2},
-       {OP_WR_E1H, QM_REG_PQ2PCIFUNC_2, 0x1},
-       {OP_WR_E1H, QM_REG_PQ2PCIFUNC_3, 0x3},
-       {OP_WR_E1H, QM_REG_PQ2PCIFUNC_4, 0x4},
-       {OP_WR_E1H, QM_REG_PQ2PCIFUNC_5, 0x6},
-       {OP_WR_E1H, QM_REG_PQ2PCIFUNC_6, 0x5},
-       {OP_WR_E1H, QM_REG_PQ2PCIFUNC_7, 0x7},
-       {OP_WR, QM_REG_CMINTEN, 0xff},
-#define QM_COMMON_END           1456
-#define PBF_COMMON_START        1456
-       {OP_WR, PBF_REG_INIT, 0x1},
-       {OP_WR, PBF_REG_INIT_P4, 0x1},
-       {OP_WR, PBF_REG_MAC_LB_ENABLE, 0x1},
-       {OP_WR, PBF_REG_IF_ENABLE_REG, 0x7fff},
-       {OP_WR, PBF_REG_INIT_P4, 0x0},
-       {OP_WR, PBF_REG_INIT, 0x0},
-       {OP_WR, PBF_REG_DISABLE_NEW_TASK_PROC_P4, 0x0},
-#define PBF_COMMON_END          1463
-#define PBF_PORT0_START         1463
-       {OP_WR, PBF_REG_INIT_P0, 0x1},
-       {OP_WR, PBF_REG_MAC_IF0_ENABLE, 0x1},
-       {OP_WR, PBF_REG_INIT_P0, 0x0},
-       {OP_WR, PBF_REG_DISABLE_NEW_TASK_PROC_P0, 0x0},
-#define PBF_PORT0_END           1467
-#define PBF_PORT1_START         1467
-       {OP_WR, PBF_REG_INIT_P1, 0x1},
-       {OP_WR, PBF_REG_MAC_IF1_ENABLE, 0x1},
-       {OP_WR, PBF_REG_INIT_P1, 0x0},
-       {OP_WR, PBF_REG_DISABLE_NEW_TASK_PROC_P1, 0x0},
-#define PBF_PORT1_END           1471
-#define XCM_COMMON_START        1471
-       {OP_WR, XCM_REG_XX_OVFL_EVNT_ID, 0x32},
-       {OP_WR, XCM_REG_XQM_XCM_HDR_P, 0x3150020},
-       {OP_WR, XCM_REG_XQM_XCM_HDR_S, 0x3150020},
-       {OP_WR, XCM_REG_TM_XCM_HDR, 0x1000030},
-       {OP_WR, XCM_REG_ERR_XCM_HDR, 0x8100000},
-       {OP_WR, XCM_REG_ERR_EVNT_ID, 0x33},
-       {OP_WR, XCM_REG_EXPR_EVNT_ID, 0x30},
-       {OP_WR, XCM_REG_STOP_EVNT_ID, 0x31},
-       {OP_WR, XCM_REG_STORM_WEIGHT, 0x3},
-       {OP_WR, XCM_REG_TSEM_WEIGHT, 0x6},
-       {OP_WR, XCM_REG_CSEM_WEIGHT, 0x3},
-       {OP_WR, XCM_REG_USEM_WEIGHT, 0x3},
-       {OP_WR, XCM_REG_DORQ_WEIGHT, 0x2},
-       {OP_WR, XCM_REG_PBF_WEIGHT, 0x0},
-       {OP_WR, XCM_REG_NIG0_WEIGHT, 0x2},
-       {OP_WR, XCM_REG_CP_WEIGHT, 0x0},
-       {OP_WR, XCM_REG_XSDM_WEIGHT, 0x6},
-       {OP_WR, XCM_REG_XQM_P_WEIGHT, 0x4},
-       {OP_WR, XCM_REG_XQM_S_WEIGHT, 0x2},
-       {OP_WR, XCM_REG_TM_WEIGHT, 0x2},
-       {OP_WR, XCM_REG_XCM_XQM_USE_Q, 0x1},
-       {OP_WR, XCM_REG_XQM_BYP_ACT_UPD, 0x6},
-       {OP_WR, XCM_REG_UNA_GT_NXT_Q, 0x0},
-       {OP_WR, XCM_REG_AUX1_Q, 0x2},
-       {OP_WR, XCM_REG_AUX_CNT_FLG_Q_19, 0x1},
-       {OP_WR, XCM_REG_GR_ARB_TYPE, 0x1},
-       {OP_WR, XCM_REG_GR_LD0_PR, 0x1},
-       {OP_WR, XCM_REG_GR_LD1_PR, 0x2},
-       {OP_WR, XCM_REG_CFC_INIT_CRD, 0x1},
-       {OP_WR, XCM_REG_FIC0_INIT_CRD, 0x40},
-       {OP_WR, XCM_REG_FIC1_INIT_CRD, 0x40},
-       {OP_WR, XCM_REG_TM_INIT_CRD, 0x4},
-       {OP_WR, XCM_REG_XQM_INIT_CRD, 0x20},
-       {OP_WR, XCM_REG_XX_INIT_CRD, 0x2},
-       {OP_WR_E1, XCM_REG_XX_MSG_NUM, 0x1f},
-       {OP_WR_E1H, XCM_REG_XX_MSG_NUM, 0x20},
-       {OP_ZR, XCM_REG_XX_TABLE, 0x12},
-       {OP_SW_E1, XCM_REG_XX_DESCR_TABLE, 0x1f02d4},
-       {OP_SW_E1H, XCM_REG_XX_DESCR_TABLE, 0x1f0329},
-       {OP_WR, XCM_REG_N_SM_CTX_LD_0, 0xf},
-       {OP_WR, XCM_REG_N_SM_CTX_LD_1, 0x7},
-       {OP_WR, XCM_REG_N_SM_CTX_LD_2, 0xb},
-       {OP_WR, XCM_REG_N_SM_CTX_LD_3, 0xe},
-       {OP_ZR_E1, XCM_REG_N_SM_CTX_LD_4, 0x4},
-       {OP_WR_E1H, XCM_REG_N_SM_CTX_LD_4, 0xe},
-       {OP_ZR_E1H, XCM_REG_N_SM_CTX_LD_5, 0x3},
-       {OP_WR, XCM_REG_XCM_REG0_SZ, 0x4},
-       {OP_WR, XCM_REG_XCM_STORM0_IFEN, 0x1},
-       {OP_WR, XCM_REG_XCM_STORM1_IFEN, 0x1},
-       {OP_WR, XCM_REG_XCM_XQM_IFEN, 0x1},
-       {OP_WR, XCM_REG_STORM_XCM_IFEN, 0x1},
-       {OP_WR, XCM_REG_XQM_XCM_IFEN, 0x1},
-       {OP_WR, XCM_REG_XSDM_IFEN, 0x1},
-       {OP_WR, XCM_REG_TM_XCM_IFEN, 0x1},
-       {OP_WR, XCM_REG_XCM_TM_IFEN, 0x1},
-       {OP_WR, XCM_REG_TSEM_IFEN, 0x1},
-       {OP_WR, XCM_REG_CSEM_IFEN, 0x1},
-       {OP_WR, XCM_REG_USEM_IFEN, 0x1},
-       {OP_WR, XCM_REG_DORQ_IFEN, 0x1},
-       {OP_WR, XCM_REG_PBF_IFEN, 0x1},
-       {OP_WR, XCM_REG_NIG0_IFEN, 0x1},
-       {OP_WR, XCM_REG_NIG1_IFEN, 0x1},
-       {OP_WR, XCM_REG_CDU_AG_WR_IFEN, 0x1},
-       {OP_WR, XCM_REG_CDU_AG_RD_IFEN, 0x1},
-       {OP_WR, XCM_REG_CDU_SM_WR_IFEN, 0x1},
-       {OP_WR, XCM_REG_CDU_SM_RD_IFEN, 0x1},
-       {OP_WR, XCM_REG_XCM_CFC_IFEN, 0x1},
-#define XCM_COMMON_END          1538
-#define XCM_PORT0_START         1538
-       {OP_WR_E1, XCM_REG_GLB_DEL_ACK_TMR_VAL_0, 0xc8},
-       {OP_WR_E1, XCM_REG_GLB_DEL_ACK_MAX_CNT_0, 0x2},
-       {OP_WR_E1, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD00, 0x0},
-       {OP_WR_E1, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD10, 0x0},
-       {OP_WR_E1, XCM_REG_WU_DA_CNT_CMD00, 0x2},
-       {OP_WR_E1, XCM_REG_WU_DA_CNT_CMD10, 0x2},
-       {OP_WR_E1, XCM_REG_WU_DA_CNT_UPD_VAL00, 0xff},
-       {OP_WR_E1, XCM_REG_WU_DA_CNT_UPD_VAL10, 0xff},
-#define XCM_PORT0_END           1546
-#define XCM_PORT1_START         1546
-       {OP_WR_E1, XCM_REG_GLB_DEL_ACK_TMR_VAL_1, 0xc8},
-       {OP_WR_E1, XCM_REG_GLB_DEL_ACK_MAX_CNT_1, 0x2},
-       {OP_WR_E1, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD01, 0x0},
-       {OP_WR_E1, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD11, 0x0},
-       {OP_WR_E1, XCM_REG_WU_DA_CNT_CMD01, 0x2},
-       {OP_WR_E1, XCM_REG_WU_DA_CNT_CMD11, 0x2},
-       {OP_WR_E1, XCM_REG_WU_DA_CNT_UPD_VAL01, 0xff},
-       {OP_WR_E1, XCM_REG_WU_DA_CNT_UPD_VAL11, 0xff},
-#define XCM_PORT1_END           1554
-#define XCM_FUNC0_START         1554
-       {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_0, 0xc8},
-       {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_0, 0x2},
-       {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD00, 0x0},
-       {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD10, 0x0},
-       {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD00, 0x2},
-       {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD10, 0x2},
-       {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL00, 0xff},
-       {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL10, 0xff},
-       {OP_WR_E1H, XCM_REG_PHYS_QNUM3_0, 0x0},
-#define XCM_FUNC0_END           1563
-#define XCM_FUNC1_START         1563
-       {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_1, 0xc8},
-       {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_1, 0x2},
-       {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD01, 0x0},
-       {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD11, 0x0},
-       {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD01, 0x2},
-       {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD11, 0x2},
-       {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL01, 0xff},
-       {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL11, 0xff},
-       {OP_WR_E1H, XCM_REG_PHYS_QNUM3_1, 0x0},
-#define XCM_FUNC1_END           1572
-#define XCM_FUNC2_START         1572
-       {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_0, 0xc8},
-       {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_0, 0x2},
-       {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD00, 0x0},
-       {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD10, 0x0},
-       {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD00, 0x2},
-       {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD10, 0x2},
-       {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL00, 0xff},
-       {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL10, 0xff},
-       {OP_WR_E1H, XCM_REG_PHYS_QNUM3_0, 0x0},
-#define XCM_FUNC2_END           1581
-#define XCM_FUNC3_START         1581
-       {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_1, 0xc8},
-       {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_1, 0x2},
-       {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD01, 0x0},
-       {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD11, 0x0},
-       {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD01, 0x2},
-       {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD11, 0x2},
-       {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL01, 0xff},
-       {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL11, 0xff},
-       {OP_WR_E1H, XCM_REG_PHYS_QNUM3_1, 0x0},
-#define XCM_FUNC3_END           1590
-#define XCM_FUNC4_START         1590
-       {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_0, 0xc8},
-       {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_0, 0x2},
-       {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD00, 0x0},
-       {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD10, 0x0},
-       {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD00, 0x2},
-       {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD10, 0x2},
-       {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL00, 0xff},
-       {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL10, 0xff},
-       {OP_WR_E1H, XCM_REG_PHYS_QNUM3_0, 0x0},
-#define XCM_FUNC4_END           1599
-#define XCM_FUNC5_START         1599
-       {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_1, 0xc8},
-       {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_1, 0x2},
-       {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD01, 0x0},
-       {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD11, 0x0},
-       {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD01, 0x2},
-       {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD11, 0x2},
-       {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL01, 0xff},
-       {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL11, 0xff},
-       {OP_WR_E1H, XCM_REG_PHYS_QNUM3_1, 0x0},
-#define XCM_FUNC5_END           1608
-#define XCM_FUNC6_START         1608
-       {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_0, 0xc8},
-       {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_0, 0x2},
-       {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD00, 0x0},
-       {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD10, 0x0},
-       {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD00, 0x2},
-       {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD10, 0x2},
-       {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL00, 0xff},
-       {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL10, 0xff},
-       {OP_WR_E1H, XCM_REG_PHYS_QNUM3_0, 0x0},
-#define XCM_FUNC6_END           1617
-#define XCM_FUNC7_START         1617
-       {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_TMR_VAL_1, 0xc8},
-       {OP_WR_E1H, XCM_REG_GLB_DEL_ACK_MAX_CNT_1, 0x2},
-       {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD01, 0x0},
-       {OP_WR_E1H, XCM_REG_WU_DA_SET_TMR_CNT_FLG_CMD11, 0x0},
-       {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD01, 0x2},
-       {OP_WR_E1H, XCM_REG_WU_DA_CNT_CMD11, 0x2},
-       {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL01, 0xff},
-       {OP_WR_E1H, XCM_REG_WU_DA_CNT_UPD_VAL11, 0xff},
-       {OP_WR_E1H, XCM_REG_PHYS_QNUM3_1, 0x0},
-#define XCM_FUNC7_END           1626
-#define XSEM_COMMON_START       1626
-       {OP_RD, XSEM_REG_MSG_NUM_FIC0, 0x0},
-       {OP_RD, XSEM_REG_MSG_NUM_FIC1, 0x0},
-       {OP_RD, XSEM_REG_MSG_NUM_FOC0, 0x0},
-       {OP_RD, XSEM_REG_MSG_NUM_FOC1, 0x0},
-       {OP_RD, XSEM_REG_MSG_NUM_FOC2, 0x0},
-       {OP_RD, XSEM_REG_MSG_NUM_FOC3, 0x0},
-       {OP_WR, XSEM_REG_ARB_ELEMENT0, 0x1},
-       {OP_WR, XSEM_REG_ARB_ELEMENT1, 0x2},
-       {OP_WR, XSEM_REG_ARB_ELEMENT2, 0x3},
-       {OP_WR, XSEM_REG_ARB_ELEMENT3, 0x0},
-       {OP_WR, XSEM_REG_ARB_ELEMENT4, 0x4},
-       {OP_WR, XSEM_REG_ARB_CYCLE_SIZE, 0x1},
-       {OP_WR, XSEM_REG_TS_0_AS, 0x0},
-       {OP_WR, XSEM_REG_TS_1_AS, 0x1},
-       {OP_WR, XSEM_REG_TS_2_AS, 0x4},
-       {OP_WR, XSEM_REG_TS_3_AS, 0x0},
-       {OP_WR, XSEM_REG_TS_4_AS, 0x1},
-       {OP_WR, XSEM_REG_TS_5_AS, 0x3},
-       {OP_WR, XSEM_REG_TS_6_AS, 0x0},
-       {OP_WR, XSEM_REG_TS_7_AS, 0x1},
-       {OP_WR, XSEM_REG_TS_8_AS, 0x4},
-       {OP_WR, XSEM_REG_TS_9_AS, 0x0},
-       {OP_WR, XSEM_REG_TS_10_AS, 0x1},
-       {OP_WR, XSEM_REG_TS_11_AS, 0x3},
-       {OP_WR, XSEM_REG_TS_12_AS, 0x0},
-       {OP_WR, XSEM_REG_TS_13_AS, 0x1},
-       {OP_WR, XSEM_REG_TS_14_AS, 0x4},
-       {OP_WR, XSEM_REG_TS_15_AS, 0x0},
-       {OP_WR, XSEM_REG_TS_16_AS, 0x4},
-       {OP_WR, XSEM_REG_TS_17_AS, 0x3},
-       {OP_ZR, XSEM_REG_TS_18_AS, 0x2},
-       {OP_WR, XSEM_REG_ENABLE_IN, 0x3fff},
-       {OP_WR, XSEM_REG_ENABLE_OUT, 0x3ff},
-       {OP_WR, XSEM_REG_FIC0_DISABLE, 0x0},
-       {OP_WR, XSEM_REG_FIC1_DISABLE, 0x0},
-       {OP_WR, XSEM_REG_PAS_DISABLE, 0x0},
-       {OP_WR, XSEM_REG_THREADS_LIST, 0xffff},
-       {OP_ZR, XSEM_REG_PASSIVE_BUFFER, 0x800},
-       {OP_WR, XSEM_REG_FAST_MEMORY + 0x18bc0, 0x1},
-       {OP_WR, XSEM_REG_FAST_MEMORY + 0x18000, 0x0},
-       {OP_WR, XSEM_REG_FAST_MEMORY + 0x18040, 0x18},
-       {OP_WR, XSEM_REG_FAST_MEMORY + 0x18080, 0xc},
-       {OP_WR, XSEM_REG_FAST_MEMORY + 0x180c0, 0x66},
-       {OP_WR_ASIC, XSEM_REG_FAST_MEMORY + 0x18300, 0x7a120},
-       {OP_WR_EMUL, XSEM_REG_FAST_MEMORY + 0x18300, 0x138},
-       {OP_WR_FPGA, XSEM_REG_FAST_MEMORY + 0x18300, 0x1388},
-       {OP_WR, XSEM_REG_FAST_MEMORY + 0x183c0, 0x1f4},
-       {OP_WR_ASIC, XSEM_REG_FAST_MEMORY + 0x18340, 0x1f4},
-       {OP_WR_EMUL, XSEM_REG_FAST_MEMORY + 0x18340, 0x0},
-       {OP_WR_FPGA, XSEM_REG_FAST_MEMORY + 0x18340, 0x5},
-       {OP_WR_EMUL, XSEM_REG_FAST_MEMORY + 0x18380, 0x4c4b4},
-       {OP_WR_ASIC, XSEM_REG_FAST_MEMORY + 0x18380, 0x1dcd6500},
-       {OP_WR_EMUL_E1H, XSEM_REG_FAST_MEMORY + 0x11480, 0x0},
-       {OP_WR_FPGA, XSEM_REG_FAST_MEMORY + 0x18380, 0x4c4b40},
-       {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3d60, 0x4},
-       {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x11480, 0x1},
-       {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3d60 + 0x10, 0x202f3},
-       {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x29c8, 0x4},
-       {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3000, 0x48},
-       {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x29c8 + 0x10, 0x20348},
-       {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x1020, 0xc8},
-       {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2080, 0x48},
-       {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x1000, 0x2},
-       {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x9020, 0xc8},
-       {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3128, 0x8e},
-       {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x9000, 0x2},
-       {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x3368, 0x0},
-       {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x21a8, 0x86},
-       {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3370, 0x202f5},
-       {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2000, 0x20},
-       {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3b90, 0x402f7},
-       {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x23c8, 0x0},
-       {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3e20, 0x202fb},
-       {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x23d0, 0x2034a},
-       {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x1518, 0x1},
-       {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2498, 0x4034c},
-       {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x1830, 0x0},
-       {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x2c20, 0x0},
-       {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x1838, 0x0},
-       {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x2c10, 0x0},
-       {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x1820, 0x202fd},
-       {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2c08, 0x20350},
-       {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x4ac0, 0x2},
-       {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x3010, 0x1},
-       {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x4b00, 0x4},
-       {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x4040, 0x10},
-       {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x1f48, 0x202ff},
-       {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x4000, 0x100352},
-       {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x6ac0, 0x2},
-       {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x6b00, 0x4},
-       {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x8408, 0x20362},
-       {OP_WR, XSEM_REG_FAST_MEMORY + 0x10800, 0x0},
-       {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x10c00, 0x100301},
-       {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x10c00, 0x100364},
-       {OP_WR, XSEM_REG_FAST_MEMORY + 0x10800, 0x1000000},
-       {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x10c40, 0x80311},
-       {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x10c40, 0x80374},
-       {OP_WR, XSEM_REG_FAST_MEMORY + 0x10800, 0x2000000},
-       {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x10c60, 0x80319},
-       {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x10c60, 0x8037c},
-       {OP_ZP_E1, XSEM_REG_INT_TABLE, 0xb50000},
-       {OP_ZP_E1H, XSEM_REG_INT_TABLE, 0xbd0000},
-       {OP_WR_64_E1, XSEM_REG_INT_TABLE + 0x368, 0x130321},
-       {OP_WR_64_E1H, XSEM_REG_INT_TABLE + 0x3a8, 0xb0384},
-       {OP_ZP_E1, XSEM_REG_PRAM, 0x33660000},
-       {OP_ZP_E1H, XSEM_REG_PRAM, 0x34060000},
-       {OP_ZP_E1, XSEM_REG_PRAM + 0x8000, 0x38b30cda},
-       {OP_ZP_E1H, XSEM_REG_PRAM + 0x8000, 0x37960d02},
-       {OP_ZP_E1, XSEM_REG_PRAM + 0x10000, 0x3bb11b07},
-       {OP_ZP_E1H, XSEM_REG_PRAM + 0x10000, 0x3bc31ae8},
-       {OP_ZP_E1, XSEM_REG_PRAM + 0x18000, 0x2a2629f4},
-       {OP_ZP_E1H, XSEM_REG_PRAM + 0x18000, 0x382629d9},
-       {OP_WR_64_E1, XSEM_REG_PRAM + 0x1d6c0, 0x45280323},
-       {OP_ZP_E1H, XSEM_REG_PRAM + 0x20000, 0x124537e3},
-       {OP_WR_64_E1H, XSEM_REG_PRAM + 0x22220, 0x3bbc0386},
-#define XSEM_COMMON_END         1741
-#define XSEM_PORT0_START        1741
-       {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3ba0, 0x14},
-       {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0xc000, 0xfc},
-       {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3c40, 0x24},
-       {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x24a8, 0x14},
-       {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x1400, 0xa},
-       {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2548, 0x24},
-       {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x1450, 0x6},
-       {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2668, 0x24},
-       {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3378, 0xfc},
-       {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2788, 0x24},
-       {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x3b58, 0x0},
-       {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x28a8, 0x24},
-       {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3d78, 0x20325},
-       {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0xa000, 0x28},
-       {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3d88, 0x100327},
-       {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0xa140, 0xc},
-       {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x1500, 0x0},
-       {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x29e0, 0x20388},
-       {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x1508, 0x1},
-       {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x3000, 0x1},
-       {OP_ZR, XSEM_REG_FAST_MEMORY + 0x5020, 0x2},
-       {OP_ZR, XSEM_REG_FAST_MEMORY + 0x5030, 0x2},
-       {OP_ZR, XSEM_REG_FAST_MEMORY + 0x5000, 0x2},
-       {OP_ZR, XSEM_REG_FAST_MEMORY + 0x5010, 0x2},
-       {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x5040, 0x0},
-       {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x5208, 0x1},
-       {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x5048, 0xe},
-       {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x6ac8, 0x2038a},
-       {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x50b8, 0x1},
-       {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x6b10, 0x42},
-       {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x4ac8, 0x20337},
-       {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x6d20, 0x4},
-       {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x4b10, 0x42},
-       {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x4d20, 0x4},
-#define XSEM_PORT0_END          1775
-#define XSEM_PORT1_START        1775
-       {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3bf0, 0x14},
-       {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0xc3f0, 0xfc},
-       {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3cd0, 0x24},
-       {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x24f8, 0x14},
-       {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x1428, 0xa},
-       {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x25d8, 0x24},
-       {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x1468, 0x6},
-       {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x26f8, 0x24},
-       {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x3768, 0xfc},
-       {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2818, 0x24},
-       {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x3b5c, 0x0},
-       {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x2938, 0x24},
-       {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3d80, 0x20339},
-       {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0xa0a0, 0x28},
-       {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x3dc8, 0x10033b},
-       {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0xa170, 0xc},
-       {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x1504, 0x0},
-       {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x29e8, 0x2038c},
-       {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x150c, 0x1},
-       {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x3004, 0x1},
-       {OP_ZR, XSEM_REG_FAST_MEMORY + 0x5028, 0x2},
-       {OP_ZR, XSEM_REG_FAST_MEMORY + 0x5038, 0x2},
-       {OP_ZR, XSEM_REG_FAST_MEMORY + 0x5008, 0x2},
-       {OP_ZR, XSEM_REG_FAST_MEMORY + 0x5018, 0x2},
-       {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x5044, 0x0},
-       {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0x520c, 0x1},
-       {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x5080, 0xe},
-       {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x6ad0, 0x2038e},
-       {OP_WR_E1, XSEM_REG_FAST_MEMORY + 0x50bc, 0x1},
-       {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x6c18, 0x42},
-       {OP_SW_E1, XSEM_REG_FAST_MEMORY + 0x4ad0, 0x2034b},
-       {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x6d30, 0x4},
-       {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x4c18, 0x42},
-       {OP_ZR_E1, XSEM_REG_FAST_MEMORY + 0x4d30, 0x4},
-#define XSEM_PORT1_END          1809
-#define XSEM_FUNC0_START        1809
-       {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7e0, 0x0},
-       {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x29f0, 0x100390},
-       {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x5048, 0xe},
-#define XSEM_FUNC0_END          1812
-#define XSEM_FUNC1_START        1812
-       {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7e4, 0x0},
-       {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2a30, 0x1003a0},
-       {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x5080, 0xe},
-#define XSEM_FUNC1_END          1815
-#define XSEM_FUNC2_START        1815
-       {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7e8, 0x0},
-       {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2a70, 0x1003b0},
-       {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x50b8, 0xe},
-#define XSEM_FUNC2_END          1818
-#define XSEM_FUNC3_START        1818
-       {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7ec, 0x0},
-       {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2ab0, 0x1003c0},
-       {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x50f0, 0xe},
-#define XSEM_FUNC3_END          1821
-#define XSEM_FUNC4_START        1821
-       {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7f0, 0x0},
-       {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2af0, 0x1003d0},
-       {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x5128, 0xe},
-#define XSEM_FUNC4_END          1824
-#define XSEM_FUNC5_START        1824
-       {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7f4, 0x0},
-       {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2b30, 0x1003e0},
-       {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x5160, 0xe},
-#define XSEM_FUNC5_END          1827
-#define XSEM_FUNC6_START        1827
-       {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7f8, 0x0},
-       {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2b70, 0x1003f0},
-       {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x5198, 0xe},
-#define XSEM_FUNC6_END          1830
-#define XSEM_FUNC7_START        1830
-       {OP_WR_E1H, XSEM_REG_FAST_MEMORY + 0xc7fc, 0x0},
-       {OP_SW_E1H, XSEM_REG_FAST_MEMORY + 0x2bb0, 0x100400},
-       {OP_ZR_E1H, XSEM_REG_FAST_MEMORY + 0x51d0, 0xe},
-#define XSEM_FUNC7_END          1833
-#define CDU_COMMON_START        1833
-       {OP_WR, CDU_REG_CDU_CONTROL0, 0x1},
-       {OP_WR_E1H, CDU_REG_MF_MODE, 0x1},
-       {OP_WR, CDU_REG_CDU_CHK_MASK0, 0x3d000},
-       {OP_WR, CDU_REG_CDU_CHK_MASK1, 0x3d},
-       {OP_WB_E1, CDU_REG_L1TT, 0x200034d},
-       {OP_WB_E1H, CDU_REG_L1TT, 0x2000410},
-       {OP_WB_E1, CDU_REG_MATT, 0x20054d},
-       {OP_WB_E1H, CDU_REG_MATT, 0x280610},
-       {OP_ZR_E1, CDU_REG_MATT + 0x80, 0x2},
-       {OP_WB_E1, CDU_REG_MATT + 0x88, 0x6056d},
-       {OP_ZR, CDU_REG_MATT + 0xa0, 0x18},
-#define CDU_COMMON_END          1844
-#define DMAE_COMMON_START       1844
-       {OP_ZR, DMAE_REG_CMD_MEM, 0xe0},
-       {OP_WR, DMAE_REG_CRC16C_INIT, 0x0},
-       {OP_WR, DMAE_REG_CRC16T10_INIT, 0x1},
-       {OP_WR_E1, DMAE_REG_PXP_REQ_INIT_CRD, 0x1},
-       {OP_WR_E1H, DMAE_REG_PXP_REQ_INIT_CRD, 0x2},
-       {OP_WR, DMAE_REG_PCI_IFEN, 0x1},
-       {OP_WR, DMAE_REG_GRC_IFEN, 0x1},
-#define DMAE_COMMON_END         1851
-#define PXP_COMMON_START        1851
-       {OP_WB_E1, PXP_REG_HST_INBOUND_INT + 0x400, 0x50573},
-       {OP_WB_E1H, PXP_REG_HST_INBOUND_INT + 0x400, 0x50638},
-       {OP_WB_E1, PXP_REG_HST_INBOUND_INT + 0x420, 0x50578},
-       {OP_WB_E1H, PXP_REG_HST_INBOUND_INT, 0x5063d},
-       {OP_WB_E1, PXP_REG_HST_INBOUND_INT, 0x5057d},
-       {OP_WB_E1H, PXP_REG_HST_INBOUND_INT + 0x20, 0x50642},
-#define PXP_COMMON_END          1857
-#define CFC_COMMON_START        1857
-       {OP_ZR_E1H, CFC_REG_LINK_LIST, 0x100},
-       {OP_WR, CFC_REG_CONTROL0, 0x10},
-       {OP_WR, CFC_REG_DISABLE_ON_ERROR, 0x3fff},
-       {OP_WR, CFC_REG_INTERFACES, 0x280000},
-       {OP_WR, CFC_REG_LCREQ_WEIGHTS, 0x84924a},
-       {OP_WR, CFC_REG_INTERFACES, 0x0},
-#define CFC_COMMON_END          1863
-#define HC_COMMON_START         1863
-       {OP_ZR_E1, HC_REG_USTORM_ADDR_FOR_COALESCE, 0x4},
-#define HC_COMMON_END           1864
-#define HC_PORT0_START          1864
-       {OP_WR_E1, HC_REG_CONFIG_0, 0x1080},
-       {OP_ZR_E1, HC_REG_UC_RAM_ADDR_0, 0x2},
-       {OP_WR_E1, HC_REG_ATTN_NUM_P0, 0x10},
-       {OP_WR_E1, HC_REG_LEADING_EDGE_0, 0xffff},
-       {OP_WR_E1, HC_REG_TRAILING_EDGE_0, 0xffff},
-       {OP_WR_E1, HC_REG_AGG_INT_0, 0x0},
-       {OP_WR_E1, HC_REG_ATTN_IDX, 0x0},
-       {OP_ZR_E1, HC_REG_ATTN_BIT, 0x2},
-       {OP_WR_E1, HC_REG_VQID_0, 0x2b5},
-       {OP_WR_E1, HC_REG_PCI_CONFIG_0, 0x0},
-       {OP_ZR_E1, HC_REG_P0_PROD_CONS, 0x4a},
-       {OP_WR_E1, HC_REG_INT_MASK, 0x1ffff},
-       {OP_ZR_E1, HC_REG_PBA_COMMAND, 0x2},
-       {OP_WR_E1, HC_REG_CONFIG_0, 0x1a80},
-       {OP_ZR_E1, HC_REG_STATISTIC_COUNTERS, 0x24},
-       {OP_ZR_E1, HC_REG_STATISTIC_COUNTERS + 0x120, 0x4a},
-       {OP_ZR_E1, HC_REG_STATISTIC_COUNTERS + 0x370, 0x4a},
-       {OP_ZR_E1, HC_REG_STATISTIC_COUNTERS + 0x5c0, 0x4a},
-#define HC_PORT0_END            1882
-#define HC_PORT1_START          1882
-       {OP_WR_E1, HC_REG_CONFIG_1, 0x1080},
-       {OP_ZR_E1, HC_REG_UC_RAM_ADDR_1, 0x2},
-       {OP_WR_E1, HC_REG_ATTN_NUM_P1, 0x10},
-       {OP_WR_E1, HC_REG_LEADING_EDGE_1, 0xffff},
-       {OP_WR_E1, HC_REG_TRAILING_EDGE_1, 0xffff},
-       {OP_WR_E1, HC_REG_AGG_INT_1, 0x0},
-       {OP_WR_E1, HC_REG_ATTN_IDX + 0x4, 0x0},
-       {OP_ZR_E1, HC_REG_ATTN_BIT + 0x8, 0x2},
-       {OP_WR_E1, HC_REG_VQID_1, 0x2b5},
-       {OP_WR_E1, HC_REG_PCI_CONFIG_1, 0x0},
-       {OP_ZR_E1, HC_REG_P1_PROD_CONS, 0x4a},
-       {OP_WR_E1, HC_REG_INT_MASK + 0x4, 0x1ffff},
-       {OP_ZR_E1, HC_REG_PBA_COMMAND + 0x8, 0x2},
-       {OP_WR_E1, HC_REG_CONFIG_1, 0x1a80},
-       {OP_ZR_E1, HC_REG_STATISTIC_COUNTERS + 0x90, 0x24},
-       {OP_ZR_E1, HC_REG_STATISTIC_COUNTERS + 0x248, 0x4a},
-       {OP_ZR_E1, HC_REG_STATISTIC_COUNTERS + 0x498, 0x4a},
-       {OP_ZR_E1, HC_REG_STATISTIC_COUNTERS + 0x6e8, 0x4a},
-#define HC_PORT1_END            1900
-#define HC_FUNC0_START          1900
-       {OP_WR_E1H, HC_REG_CONFIG_0, 0x1080},
-       {OP_WR_E1H, HC_REG_FUNC_NUM_P0, 0x0},
-       {OP_WR_E1H, HC_REG_ATTN_NUM_P0, 0x10},
-       {OP_WR_E1H, HC_REG_ATTN_IDX, 0x0},
-       {OP_ZR_E1H, HC_REG_ATTN_BIT, 0x2},
-       {OP_WR_E1H, HC_REG_VQID_0, 0x2b5},
-       {OP_WR_E1H, HC_REG_PCI_CONFIG_0, 0x0},
-       {OP_ZR_E1H, HC_REG_P0_PROD_CONS, 0x4a},
-       {OP_WR_E1H, HC_REG_INT_MASK, 0x1ffff},
-       {OP_ZR_E1H, HC_REG_PBA_COMMAND, 0x2},
-       {OP_WR_E1H, HC_REG_CONFIG_0, 0x1a80},
-       {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS, 0x24},
-       {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x120, 0x4a},
-       {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x370, 0x4a},
-       {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x5c0, 0x4a},
-#define HC_FUNC0_END            1915
-#define HC_FUNC1_START          1915
-       {OP_WR_E1H, HC_REG_CONFIG_1, 0x1080},
-       {OP_WR_E1H, HC_REG_FUNC_NUM_P1, 0x1},
-       {OP_WR_E1H, HC_REG_ATTN_NUM_P1, 0x10},
-       {OP_WR_E1H, HC_REG_ATTN_IDX + 0x4, 0x0},
-       {OP_ZR_E1H, HC_REG_ATTN_BIT + 0x8, 0x2},
-       {OP_WR_E1H, HC_REG_VQID_1, 0x2b5},
-       {OP_WR_E1H, HC_REG_PCI_CONFIG_1, 0x0},
-       {OP_ZR_E1H, HC_REG_P1_PROD_CONS, 0x4a},
-       {OP_WR_E1H, HC_REG_INT_MASK + 0x4, 0x1ffff},
-       {OP_ZR_E1H, HC_REG_PBA_COMMAND + 0x8, 0x2},
-       {OP_WR_E1H, HC_REG_CONFIG_1, 0x1a80},
-       {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x90, 0x24},
-       {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x248, 0x4a},
-       {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x498, 0x4a},
-       {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x6e8, 0x4a},
-#define HC_FUNC1_END            1930
-#define HC_FUNC2_START          1930
-       {OP_WR_E1H, HC_REG_CONFIG_0, 0x1080},
-       {OP_WR_E1H, HC_REG_FUNC_NUM_P0, 0x2},
-       {OP_WR_E1H, HC_REG_ATTN_NUM_P0, 0x10},
-       {OP_WR_E1H, HC_REG_ATTN_IDX, 0x0},
-       {OP_ZR_E1H, HC_REG_ATTN_BIT, 0x2},
-       {OP_WR_E1H, HC_REG_VQID_0, 0x2b5},
-       {OP_WR_E1H, HC_REG_PCI_CONFIG_0, 0x0},
-       {OP_ZR_E1H, HC_REG_P0_PROD_CONS, 0x4a},
-       {OP_WR_E1H, HC_REG_INT_MASK, 0x1ffff},
-       {OP_ZR_E1H, HC_REG_PBA_COMMAND, 0x2},
-       {OP_WR_E1H, HC_REG_CONFIG_0, 0x1a80},
-       {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS, 0x24},
-       {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x120, 0x4a},
-       {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x370, 0x4a},
-       {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x5c0, 0x4a},
-#define HC_FUNC2_END            1945
-#define HC_FUNC3_START          1945
-       {OP_WR_E1H, HC_REG_CONFIG_1, 0x1080},
-       {OP_WR_E1H, HC_REG_FUNC_NUM_P1, 0x3},
-       {OP_WR_E1H, HC_REG_ATTN_NUM_P1, 0x10},
-       {OP_WR_E1H, HC_REG_ATTN_IDX + 0x4, 0x0},
-       {OP_ZR_E1H, HC_REG_ATTN_BIT + 0x8, 0x2},
-       {OP_WR_E1H, HC_REG_VQID_1, 0x2b5},
-       {OP_WR_E1H, HC_REG_PCI_CONFIG_1, 0x0},
-       {OP_ZR_E1H, HC_REG_P1_PROD_CONS, 0x4a},
-       {OP_WR_E1H, HC_REG_INT_MASK + 0x4, 0x1ffff},
-       {OP_ZR_E1H, HC_REG_PBA_COMMAND + 0x8, 0x2},
-       {OP_WR_E1H, HC_REG_CONFIG_1, 0x1a80},
-       {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x90, 0x24},
-       {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x248, 0x4a},
-       {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x498, 0x4a},
-       {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x6e8, 0x4a},
-#define HC_FUNC3_END            1960
-#define HC_FUNC4_START          1960
-       {OP_WR_E1H, HC_REG_CONFIG_0, 0x1080},
-       {OP_WR_E1H, HC_REG_FUNC_NUM_P0, 0x4},
-       {OP_WR_E1H, HC_REG_ATTN_NUM_P0, 0x10},
-       {OP_WR_E1H, HC_REG_ATTN_IDX, 0x0},
-       {OP_ZR_E1H, HC_REG_ATTN_BIT, 0x2},
-       {OP_WR_E1H, HC_REG_VQID_0, 0x2b5},
-       {OP_WR_E1H, HC_REG_PCI_CONFIG_0, 0x0},
-       {OP_ZR_E1H, HC_REG_P0_PROD_CONS, 0x4a},
-       {OP_WR_E1H, HC_REG_INT_MASK, 0x1ffff},
-       {OP_ZR_E1H, HC_REG_PBA_COMMAND, 0x2},
-       {OP_WR_E1H, HC_REG_CONFIG_0, 0x1a80},
-       {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS, 0x24},
-       {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x120, 0x4a},
-       {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x370, 0x4a},
-       {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x5c0, 0x4a},
-#define HC_FUNC4_END            1975
-#define HC_FUNC5_START          1975
-       {OP_WR_E1H, HC_REG_CONFIG_1, 0x1080},
-       {OP_WR_E1H, HC_REG_FUNC_NUM_P1, 0x5},
-       {OP_WR_E1H, HC_REG_ATTN_NUM_P1, 0x10},
-       {OP_WR_E1H, HC_REG_ATTN_IDX + 0x4, 0x0},
-       {OP_ZR_E1H, HC_REG_ATTN_BIT + 0x8, 0x2},
-       {OP_WR_E1H, HC_REG_VQID_1, 0x2b5},
-       {OP_WR_E1H, HC_REG_PCI_CONFIG_1, 0x0},
-       {OP_ZR_E1H, HC_REG_P1_PROD_CONS, 0x4a},
-       {OP_WR_E1H, HC_REG_INT_MASK + 0x4, 0x1ffff},
-       {OP_ZR_E1H, HC_REG_PBA_COMMAND + 0x8, 0x2},
-       {OP_WR_E1H, HC_REG_CONFIG_1, 0x1a80},
-       {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x90, 0x24},
-       {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x248, 0x4a},
-       {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x498, 0x4a},
-       {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x6e8, 0x4a},
-#define HC_FUNC5_END            1990
-#define HC_FUNC6_START          1990
-       {OP_WR_E1H, HC_REG_CONFIG_0, 0x1080},
-       {OP_WR_E1H, HC_REG_FUNC_NUM_P0, 0x6},
-       {OP_WR_E1H, HC_REG_ATTN_NUM_P0, 0x10},
-       {OP_WR_E1H, HC_REG_ATTN_IDX, 0x0},
-       {OP_ZR_E1H, HC_REG_ATTN_BIT, 0x2},
-       {OP_WR_E1H, HC_REG_VQID_0, 0x2b5},
-       {OP_WR_E1H, HC_REG_PCI_CONFIG_0, 0x0},
-       {OP_ZR_E1H, HC_REG_P0_PROD_CONS, 0x4a},
-       {OP_WR_E1H, HC_REG_INT_MASK, 0x1ffff},
-       {OP_ZR_E1H, HC_REG_PBA_COMMAND, 0x2},
-       {OP_WR_E1H, HC_REG_CONFIG_0, 0x1a80},
-       {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS, 0x24},
-       {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x120, 0x4a},
-       {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x370, 0x4a},
-       {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x5c0, 0x4a},
-#define HC_FUNC6_END            2005
-#define HC_FUNC7_START          2005
-       {OP_WR_E1H, HC_REG_CONFIG_1, 0x1080},
-       {OP_WR_E1H, HC_REG_FUNC_NUM_P1, 0x7},
-       {OP_WR_E1H, HC_REG_ATTN_NUM_P1, 0x10},
-       {OP_WR_E1H, HC_REG_ATTN_IDX + 0x4, 0x0},
-       {OP_ZR_E1H, HC_REG_ATTN_BIT + 0x8, 0x2},
-       {OP_WR_E1H, HC_REG_VQID_1, 0x2b5},
-       {OP_WR_E1H, HC_REG_PCI_CONFIG_1, 0x0},
-       {OP_ZR_E1H, HC_REG_P1_PROD_CONS, 0x4a},
-       {OP_WR_E1H, HC_REG_INT_MASK + 0x4, 0x1ffff},
-       {OP_ZR_E1H, HC_REG_PBA_COMMAND + 0x8, 0x2},
-       {OP_WR_E1H, HC_REG_CONFIG_1, 0x1a80},
-       {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x90, 0x24},
-       {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x248, 0x4a},
-       {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x498, 0x4a},
-       {OP_ZR_E1H, HC_REG_STATISTIC_COUNTERS + 0x6e8, 0x4a},
-#define HC_FUNC7_END            2020
-#define PXP2_COMMON_START       2020
-       {OP_WR_E1H, PXP2_REG_RQ_DRAM_ALIGN, 0x1},
-       {OP_WR, PXP2_REG_PGL_CONTROL0, 0xe38340},
-       {OP_WR, PXP2_REG_PGL_CONTROL1, 0x3c10},
-       {OP_WR_E1H, PXP2_REG_RQ_ELT_DISABLE, 0x1},
-       {OP_WR_E1H, PXP2_REG_WR_REV_MODE, 0x0},
-       {OP_WR, PXP2_REG_PGL_INT_TSDM_0, 0xffffffff},
-       {OP_WR, PXP2_REG_PGL_INT_TSDM_1, 0xffffffff},
-       {OP_WR, PXP2_REG_PGL_INT_TSDM_2, 0xffffffff},
-       {OP_WR, PXP2_REG_PGL_INT_TSDM_3, 0xffffffff},
-       {OP_WR, PXP2_REG_PGL_INT_TSDM_4, 0xffffffff},
-       {OP_WR, PXP2_REG_PGL_INT_TSDM_5, 0xffffffff},
-       {OP_WR, PXP2_REG_PGL_INT_TSDM_6, 0xffffffff},
-       {OP_WR, PXP2_REG_PGL_INT_TSDM_7, 0xffffffff},
-       {OP_WR_E1, PXP2_REG_PGL_INT_USDM_1, 0xffffffff},
-       {OP_WR, PXP2_REG_PGL_INT_USDM_2, 0xffffffff},
-       {OP_WR, PXP2_REG_PGL_INT_USDM_3, 0xffffffff},
-       {OP_WR, PXP2_REG_PGL_INT_USDM_4, 0xffffffff},
-       {OP_WR, PXP2_REG_PGL_INT_USDM_5, 0xffffffff},
-       {OP_WR, PXP2_REG_PGL_INT_USDM_6, 0xffffffff},
-       {OP_WR, PXP2_REG_PGL_INT_USDM_7, 0xffffffff},
-       {OP_WR_E1H, PXP2_REG_PGL_INT_XSDM_1, 0xffffffff},
-       {OP_WR, PXP2_REG_PGL_INT_XSDM_2, 0xffffffff},
-       {OP_WR, PXP2_REG_PGL_INT_XSDM_3, 0xffffffff},
-       {OP_WR, PXP2_REG_PGL_INT_XSDM_4, 0xffffffff},
-       {OP_WR, PXP2_REG_PGL_INT_XSDM_5, 0xffffffff},
-       {OP_WR, PXP2_REG_PGL_INT_XSDM_6, 0xffffffff},
-       {OP_WR, PXP2_REG_PGL_INT_XSDM_7, 0xffffffff},
-       {OP_WR, PXP2_REG_PGL_INT_CSDM_0, 0xffffffff},
-       {OP_WR, PXP2_REG_PGL_INT_CSDM_1, 0xffffffff},
-       {OP_WR, PXP2_REG_PGL_INT_CSDM_2, 0xffffffff},
-       {OP_WR, PXP2_REG_PGL_INT_CSDM_3, 0xffffffff},
-       {OP_WR, PXP2_REG_PGL_INT_CSDM_4, 0xffffffff},
-       {OP_WR, PXP2_REG_PGL_INT_CSDM_5, 0xffffffff},
-       {OP_WR, PXP2_REG_PGL_INT_CSDM_6, 0xffffffff},
-       {OP_WR, PXP2_REG_PGL_INT_CSDM_7, 0xffffffff},
-       {OP_WR_E1, PXP2_REG_PGL_INT_XSDM_0, 0xffff3330},
-       {OP_WR_E1H, PXP2_REG_PGL_INT_XSDM_0, 0xff802000},
-       {OP_WR_E1, PXP2_REG_PGL_INT_XSDM_1, 0xffff3340},
-       {OP_WR_E1H, PXP2_REG_PGL_INT_USDM_0, 0xf0005000},
-       {OP_WR_E1, PXP2_REG_PGL_INT_USDM_0, 0xf0003000},
-       {OP_WR_E1H, PXP2_REG_PGL_INT_USDM_1, 0xf0008000},
-       {OP_WR, PXP2_REG_RD_MAX_BLKS_VQ6, 0x8},
-       {OP_WR, PXP2_REG_RD_MAX_BLKS_VQ9, 0x8},
-       {OP_WR, PXP2_REG_RD_MAX_BLKS_VQ10, 0x8},
-       {OP_WR, PXP2_REG_RD_MAX_BLKS_VQ11, 0x2},
-       {OP_WR, PXP2_REG_RD_MAX_BLKS_VQ17, 0x4},
-       {OP_WR, PXP2_REG_RD_MAX_BLKS_VQ18, 0x5},
-       {OP_WR, PXP2_REG_RD_MAX_BLKS_VQ19, 0x4},
-       {OP_WR, PXP2_REG_RD_MAX_BLKS_VQ22, 0x0},
-       {OP_WR, PXP2_REG_RD_START_INIT, 0x1},
-       {OP_WR, PXP2_REG_WR_DMAE_TH, 0x3f},
-       {OP_WR, PXP2_REG_RQ_BW_RD_ADD0, 0x40},
-       {OP_WR, PXP2_REG_PSWRQ_BW_ADD1, 0x1808},
-       {OP_WR, PXP2_REG_PSWRQ_BW_ADD2, 0x803},
-       {OP_WR, PXP2_REG_PSWRQ_BW_ADD3, 0x803},
-       {OP_WR, PXP2_REG_RQ_BW_RD_ADD4, 0x40},
-       {OP_WR, PXP2_REG_RQ_BW_RD_ADD5, 0x3},
-       {OP_WR, PXP2_REG_PSWRQ_BW_ADD6, 0x803},
-       {OP_WR, PXP2_REG_PSWRQ_BW_ADD7, 0x803},
-       {OP_WR, PXP2_REG_PSWRQ_BW_ADD8, 0x803},
-       {OP_WR, PXP2_REG_PSWRQ_BW_ADD9, 0x10003},
-       {OP_WR, PXP2_REG_PSWRQ_BW_ADD10, 0x803},
-       {OP_WR, PXP2_REG_PSWRQ_BW_ADD11, 0x803},
-       {OP_WR, PXP2_REG_RQ_BW_RD_ADD12, 0x3},
-       {OP_WR, PXP2_REG_RQ_BW_RD_ADD13, 0x3},
-       {OP_WR, PXP2_REG_RQ_BW_RD_ADD14, 0x3},
-       {OP_WR, PXP2_REG_RQ_BW_RD_ADD15, 0x3},
-       {OP_WR, PXP2_REG_RQ_BW_RD_ADD16, 0x3},
-       {OP_WR, PXP2_REG_RQ_BW_RD_ADD17, 0x3},
-       {OP_WR, PXP2_REG_RQ_BW_RD_ADD18, 0x3},
-       {OP_WR, PXP2_REG_RQ_BW_RD_ADD19, 0x3},
-       {OP_WR, PXP2_REG_RQ_BW_RD_ADD20, 0x3},
-       {OP_WR, PXP2_REG_RQ_BW_RD_ADD22, 0x3},
-       {OP_WR, PXP2_REG_RQ_BW_RD_ADD23, 0x3},
-       {OP_WR, PXP2_REG_RQ_BW_RD_ADD24, 0x3},
-       {OP_WR, PXP2_REG_RQ_BW_RD_ADD25, 0x3},
-       {OP_WR, PXP2_REG_RQ_BW_RD_ADD26, 0x3},
-       {OP_WR, PXP2_REG_RQ_BW_RD_ADD27, 0x3},
-       {OP_WR, PXP2_REG_PSWRQ_BW_ADD28, 0x2403},
-       {OP_WR, PXP2_REG_RQ_BW_WR_ADD29, 0x2f},
-       {OP_WR, PXP2_REG_RQ_BW_WR_ADD30, 0x9},
-       {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND0, 0x19},
-       {OP_WR, PXP2_REG_PSWRQ_BW_UB1, 0x184},
-       {OP_WR, PXP2_REG_PSWRQ_BW_UB2, 0x183},
-       {OP_WR, PXP2_REG_PSWRQ_BW_UB3, 0x306},
-       {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND4, 0x19},
-       {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND5, 0x6},
-       {OP_WR, PXP2_REG_PSWRQ_BW_UB6, 0x306},
-       {OP_WR, PXP2_REG_PSWRQ_BW_UB7, 0x306},
-       {OP_WR, PXP2_REG_PSWRQ_BW_UB8, 0x306},
-       {OP_WR, PXP2_REG_PSWRQ_BW_UB9, 0xc86},
-       {OP_WR, PXP2_REG_PSWRQ_BW_UB10, 0x306},
-       {OP_WR, PXP2_REG_PSWRQ_BW_UB11, 0x306},
-       {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND12, 0x6},
-       {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND13, 0x6},
-       {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND14, 0x6},
-       {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND15, 0x6},
-       {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND16, 0x6},
-       {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND17, 0x6},
-       {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND18, 0x6},
-       {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND19, 0x6},
-       {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND20, 0x6},
-       {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND22, 0x6},
-       {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND23, 0x6},
-       {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND24, 0x6},
-       {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND25, 0x6},
-       {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND26, 0x6},
-       {OP_WR, PXP2_REG_RQ_BW_RD_UBOUND27, 0x6},
-       {OP_WR, PXP2_REG_PSWRQ_BW_UB28, 0x306},
-       {OP_WR, PXP2_REG_RQ_BW_WR_UBOUND29, 0x13},
-       {OP_WR, PXP2_REG_RQ_BW_WR_UBOUND30, 0x6},
-       {OP_WR, PXP2_REG_PSWRQ_BW_L1, 0x1004},
-       {OP_WR, PXP2_REG_PSWRQ_BW_L2, 0x1004},
-       {OP_WR, PXP2_REG_PSWRQ_BW_RD, 0x106440},
-       {OP_WR, PXP2_REG_PSWRQ_BW_WR, 0x106440},
-       {OP_WR_E1H, PXP2_REG_RQ_ILT_MODE, 0x1},
-       {OP_WR, PXP2_REG_RQ_RBC_DONE, 0x1},
-#define PXP2_COMMON_END         2137
-#define MISC_AEU_COMMON_START   2137
-       {OP_ZR, MISC_REG_AEU_GENERAL_ATTN_0, 0x16},
-       {OP_WR_E1H, MISC_REG_AEU_ENABLE1_NIG_0, 0x55540000},
-       {OP_WR_E1H, MISC_REG_AEU_ENABLE2_NIG_0, 0x55555555},
-       {OP_WR_E1H, MISC_REG_AEU_ENABLE3_NIG_0, 0x5555},
-       {OP_WR_E1H, MISC_REG_AEU_ENABLE4_NIG_0, 0xf0000000},
-       {OP_WR_E1H, MISC_REG_AEU_ENABLE1_PXP_0, 0x55540000},
-       {OP_WR_E1H, MISC_REG_AEU_ENABLE2_PXP_0, 0x55555555},
-       {OP_WR_E1H, MISC_REG_AEU_ENABLE3_PXP_0, 0x5555},
-       {OP_WR_E1H, MISC_REG_AEU_ENABLE4_PXP_0, 0xf0000000},
-       {OP_WR_E1H, MISC_REG_AEU_ENABLE1_NIG_1, 0x55540000},
-       {OP_WR_E1H, MISC_REG_AEU_ENABLE2_NIG_1, 0x55555555},
-       {OP_WR_E1H, MISC_REG_AEU_ENABLE3_NIG_1, 0x5555},
-       {OP_WR_E1H, MISC_REG_AEU_ENABLE4_NIG_1, 0xf0000000},
-       {OP_WR_E1H, MISC_REG_AEU_ENABLE1_PXP_1, 0x0},
-       {OP_WR_E1H, MISC_REG_AEU_ENABLE2_PXP_1, 0x10000},
-       {OP_WR_E1H, MISC_REG_AEU_ENABLE3_PXP_1, 0x5014},
-       {OP_WR_E1H, MISC_REG_AEU_ENABLE4_PXP_1, 0x0},
-       {OP_WR_E1H, MISC_REG_AEU_CLR_LATCH_SIGNAL, 0xc00},
-       {OP_WR_E1H, MISC_REG_AEU_GENERAL_MASK, 0x3},
-#define MISC_AEU_COMMON_END     2156
-#define MISC_AEU_PORT0_START    2156
-       {OP_WR_E1, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0, 0xbf5c0000},
-       {OP_WR_E1H, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0, 0xff5c0000},
-       {OP_WR_E1, MISC_REG_AEU_ENABLE2_FUNC_0_OUT_0, 0xfff51fef},
-       {OP_WR_E1H, MISC_REG_AEU_ENABLE2_FUNC_0_OUT_0, 0xfff55fff},
-       {OP_WR, MISC_REG_AEU_ENABLE3_FUNC_0_OUT_0, 0xffff},
-       {OP_WR_E1, MISC_REG_AEU_ENABLE4_FUNC_0_OUT_0, 0x500003e0},
-       {OP_WR_E1H, MISC_REG_AEU_ENABLE4_FUNC_0_OUT_0, 0xf00003e0},
-       {OP_WR, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_1, 0x0},
-       {OP_WR, MISC_REG_AEU_ENABLE2_FUNC_0_OUT_1, 0xa000},
-       {OP_ZR, MISC_REG_AEU_ENABLE3_FUNC_0_OUT_1, 0x5},
-       {OP_WR, MISC_REG_AEU_ENABLE4_FUNC_0_OUT_2, 0xfe00000},
-       {OP_ZR_E1, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_3, 0x14},
-       {OP_ZR_E1H, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_3, 0x7},
-       {OP_WR_E1, MISC_REG_AEU_ENABLE1_NIG_0, 0x55540000},
-       {OP_WR_E1H, MISC_REG_AEU_ENABLE4_FUNC_0_OUT_4, 0x400},
-       {OP_WR_E1, MISC_REG_AEU_ENABLE2_NIG_0, 0x55555555},
-       {OP_ZR_E1H, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_5, 0x3},
-       {OP_WR_E1, MISC_REG_AEU_ENABLE3_NIG_0, 0x5555},
-       {OP_WR_E1H, MISC_REG_AEU_ENABLE4_FUNC_0_OUT_5, 0x1000},
-       {OP_WR_E1, MISC_REG_AEU_ENABLE4_NIG_0, 0x0},
-       {OP_ZR_E1H, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_6, 0x3},
-       {OP_WR_E1, MISC_REG_AEU_ENABLE1_PXP_0, 0x55540000},
-       {OP_WR_E1H, MISC_REG_AEU_ENABLE4_FUNC_0_OUT_6, 0x4000},
-       {OP_WR_E1, MISC_REG_AEU_ENABLE2_PXP_0, 0x55555555},
-       {OP_ZR_E1H, MISC_REG_AEU_ENABLE1_FUNC_0_OUT_7, 0x3},
-       {OP_WR_E1, MISC_REG_AEU_ENABLE3_PXP_0, 0x5555},
-       {OP_WR_E1H, MISC_REG_AEU_ENABLE4_FUNC_0_OUT_7, 0x10000},
-       {OP_WR_E1, MISC_REG_AEU_ENABLE4_PXP_0, 0x0},
-       {OP_ZR_E1H, MISC_REG_AEU_INVERTER_1_FUNC_0, 0x4},
-       {OP_WR_E1, MISC_REG_AEU_INVERTER_1_FUNC_0, 0x0},
-       {OP_ZR_E1, MISC_REG_AEU_INVERTER_2_FUNC_0, 0x3},
-       {OP_WR_E1, MISC_REG_AEU_MASK_ATTN_FUNC_0, 0x7},
-#define MISC_AEU_PORT0_END      2188
-#define MISC_AEU_PORT1_START    2188
-       {OP_WR_E1, MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0, 0xbf5c0000},
-       {OP_WR_E1H, MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0, 0xff5c0000},
-       {OP_WR_E1, MISC_REG_AEU_ENABLE2_FUNC_1_OUT_0, 0xfff51fef},
-       {OP_WR_E1H, MISC_REG_AEU_ENABLE2_FUNC_1_OUT_0, 0xfff55fff},
-       {OP_WR, MISC_REG_AEU_ENABLE3_FUNC_1_OUT_0, 0xffff},
-       {OP_WR_E1, MISC_REG_AEU_ENABLE4_FUNC_1_OUT_0, 0x500003e0},
-       {OP_WR_E1H, MISC_REG_AEU_ENABLE4_FUNC_1_OUT_0, 0xf00003e0},
-       {OP_WR, MISC_REG_AEU_ENABLE1_FUNC_1_OUT_1, 0x0},
-       {OP_WR, MISC_REG_AEU_ENABLE2_FUNC_1_OUT_1, 0xa000},
-       {OP_ZR, MISC_REG_AEU_ENABLE3_FUNC_1_OUT_1, 0x5},
-       {OP_WR, MISC_REG_AEU_ENABLE4_FUNC_1_OUT_2, 0xfe00000},
-       {OP_ZR_E1, MISC_REG_AEU_ENABLE1_FUNC_1_OUT_3, 0x14},
-       {OP_ZR_E1H, MISC_REG_AEU_ENABLE1_FUNC_1_OUT_3, 0x7},
-       {OP_WR_E1, MISC_REG_AEU_ENABLE1_NIG_1, 0x55540000},
-       {OP_WR_E1H, MISC_REG_AEU_ENABLE4_FUNC_1_OUT_4, 0x800},
-       {OP_WR_E1, MISC_REG_AEU_ENABLE2_NIG_1, 0x55555555},
-       {OP_ZR_E1H, MISC_REG_AEU_ENABLE1_FUNC_1_OUT_5, 0x3},
-       {OP_WR_E1, MISC_REG_AEU_ENABLE3_NIG_1, 0x5555},
-       {OP_WR_E1H, MISC_REG_AEU_ENABLE4_FUNC_1_OUT_5, 0x2000},
-       {OP_WR_E1, MISC_REG_AEU_ENABLE4_NIG_1, 0x0},
-       {OP_ZR_E1H, MISC_REG_AEU_ENABLE1_FUNC_1_OUT_6, 0x3},
-       {OP_WR_E1, MISC_REG_AEU_ENABLE1_PXP_1, 0x55540000},
-       {OP_WR_E1H, MISC_REG_AEU_ENABLE4_FUNC_1_OUT_6, 0x8000},
-       {OP_WR_E1, MISC_REG_AEU_ENABLE2_PXP_1, 0x55555555},
-       {OP_ZR_E1H, MISC_REG_AEU_ENABLE1_FUNC_1_OUT_7, 0x3},
-       {OP_WR_E1, MISC_REG_AEU_ENABLE3_PXP_1, 0x5555},
-       {OP_WR_E1H, MISC_REG_AEU_ENABLE4_FUNC_1_OUT_7, 0x20000},
-       {OP_WR_E1, MISC_REG_AEU_ENABLE4_PXP_1, 0x0},
-       {OP_ZR_E1H, MISC_REG_AEU_INVERTER_1_FUNC_1, 0x4},
-       {OP_WR_E1, MISC_REG_AEU_INVERTER_1_FUNC_1, 0x0},
-       {OP_ZR_E1, MISC_REG_AEU_INVERTER_2_FUNC_1, 0x3},
-       {OP_WR_E1, MISC_REG_AEU_MASK_ATTN_FUNC_1, 0x7},
-#define MISC_AEU_PORT1_END      2220
-
-};
-
-static const u32 init_data_e1[] = {
-       0x00010000, 0x000204c0, 0x00030980, 0x00040e40, 0x00051300, 0x000617c0,
-       0x00071c80, 0x00082140, 0x00092600, 0x000a2ac0, 0x000b2f80, 0x000c3440,
-       0x000d3900, 0x000e3dc0, 0x000f4280, 0x00104740, 0x00114c00, 0x001250c0,
-       0x00135580, 0x00145a40, 0x00155f00, 0x001663c0, 0x00176880, 0x00186d40,
-       0x00197200, 0x001a76c0, 0x001b7b80, 0x001c8040, 0x001d8500, 0x001e89c0,
-       0x001f8e80, 0x00209340, 0x00002000, 0x00004000, 0x00006000, 0x00008000,
-       0x0000a000, 0x0000c000, 0x0000e000, 0x00010000, 0x00012000, 0x00014000,
-       0x00016000, 0x00018000, 0x0001a000, 0x0001c000, 0x0001e000, 0x00020000,
-       0x00022000, 0x00024000, 0x00026000, 0x00028000, 0x0002a000, 0x0002c000,
-       0x0002e000, 0x00030000, 0x00032000, 0x00034000, 0x00036000, 0x00038000,
-       0x0003a000, 0x0003c000, 0x0003e000, 0x00040000, 0x00042000, 0x00044000,
-       0x00046000, 0x00048000, 0x0004a000, 0x0004c000, 0x0004e000, 0x00050000,
-       0x00052000, 0x00054000, 0x00056000, 0x00058000, 0x0005a000, 0x0005c000,
-       0x0005e000, 0x00060000, 0x00062000, 0x00064000, 0x00066000, 0x00068000,
-       0x0006a000, 0x0006c000, 0x0006e000, 0x00070000, 0x00072000, 0x00074000,
-       0x00076000, 0x00078000, 0x0007a000, 0x0007c000, 0x0007e000, 0x00080000,
-       0x00082000, 0x00084000, 0x00086000, 0x00088000, 0x0008a000, 0x0008c000,
-       0x0008e000, 0x00090000, 0x00092000, 0x00094000, 0x00096000, 0x00098000,
-       0x0009a000, 0x0009c000, 0x0009e000, 0x000a0000, 0x000a2000, 0x000a4000,
-       0x000a6000, 0x000a8000, 0x000aa000, 0x000ac000, 0x000ae000, 0x000b0000,
-       0x000b2000, 0x000b4000, 0x000b6000, 0x000b8000, 0x000ba000, 0x000bc000,
-       0x000be000, 0x000c0000, 0x000c2000, 0x000c4000, 0x000c6000, 0x000c8000,
-       0x000ca000, 0x000cc000, 0x000ce000, 0x000d0000, 0x000d2000, 0x000d4000,
-       0x000d6000, 0x000d8000, 0x000da000, 0x000dc000, 0x000de000, 0x000e0000,
-       0x000e2000, 0x000e4000, 0x000e6000, 0x000e8000, 0x000ea000, 0x000ec000,
-       0x000ee000, 0x000f0000, 0x000f2000, 0x000f4000, 0x000f6000, 0x000f8000,
-       0x000fa000, 0x000fc000, 0x000fe000, 0x00100000, 0x00102000, 0x00104000,
-       0x00106000, 0x00108000, 0x0010a000, 0x0010c000, 0x0010e000, 0x00110000,
-       0x00112000, 0x00114000, 0x00116000, 0x00118000, 0x0011a000, 0x0011c000,
-       0x0011e000, 0x00120000, 0x00122000, 0x00124000, 0x00126000, 0x00128000,
-       0x0012a000, 0x0012c000, 0x0012e000, 0x00130000, 0x00132000, 0x00134000,
-       0x00136000, 0x00138000, 0x0013a000, 0x0013c000, 0x0013e000, 0x00140000,
-       0x00142000, 0x00144000, 0x00146000, 0x00148000, 0x0014a000, 0x0014c000,
-       0x0014e000, 0x00150000, 0x00152000, 0x00154000, 0x00156000, 0x00158000,
-       0x0015a000, 0x0015c000, 0x0015e000, 0x00160000, 0x00162000, 0x00164000,
-       0x00166000, 0x00168000, 0x0016a000, 0x0016c000, 0x0016e000, 0x00170000,
-       0x00172000, 0x00174000, 0x00176000, 0x00178000, 0x0017a000, 0x0017c000,
-       0x0017e000, 0x00180000, 0x00182000, 0x00184000, 0x00186000, 0x00188000,
-       0x0018a000, 0x0018c000, 0x0018e000, 0x00190000, 0x00192000, 0x00194000,
-       0x00196000, 0x00198000, 0x0019a000, 0x0019c000, 0x0019e000, 0x001a0000,
-       0x001a2000, 0x001a4000, 0x001a6000, 0x001a8000, 0x001aa000, 0x001ac000,
-       0x001ae000, 0x001b0000, 0x001b2000, 0x001b4000, 0x001b6000, 0x001b8000,
-       0x001ba000, 0x001bc000, 0x001be000, 0x001c0000, 0x001c2000, 0x001c4000,
-       0x001c6000, 0x001c8000, 0x001ca000, 0x001cc000, 0x001ce000, 0x001d0000,
-       0x001d2000, 0x001d4000, 0x001d6000, 0x001d8000, 0x001da000, 0x001dc000,
-       0x001de000, 0x001e0000, 0x001e2000, 0x001e4000, 0x001e6000, 0x001e8000,
-       0x001ea000, 0x001ec000, 0x001ee000, 0x001f0000, 0x001f2000, 0x001f4000,
-       0x001f6000, 0x001f8000, 0x001fa000, 0x001fc000, 0x001fe000, 0x00200000,
-       0x00202000, 0x00204000, 0x00206000, 0x00208000, 0x0020a000, 0x0020c000,
-       0x0020e000, 0x00210000, 0x00212000, 0x00214000, 0x00216000, 0x00218000,
-       0x0021a000, 0x0021c000, 0x0021e000, 0x00220000, 0x00222000, 0x00224000,
-       0x00226000, 0x00228000, 0x0022a000, 0x0022c000, 0x0022e000, 0x00230000,
-       0x00232000, 0x00234000, 0x00236000, 0x00238000, 0x0023a000, 0x0023c000,
-       0x0023e000, 0x00240000, 0x00242000, 0x00244000, 0x00246000, 0x00248000,
-       0x0024a000, 0x0024c000, 0x0024e000, 0x00250000, 0x00252000, 0x00254000,
-       0x00256000, 0x00258000, 0x0025a000, 0x0025c000, 0x0025e000, 0x00260000,
-       0x00262000, 0x00264000, 0x00266000, 0x00268000, 0x0026a000, 0x0026c000,
-       0x0026e000, 0x00270000, 0x00272000, 0x00274000, 0x00276000, 0x00278000,
-       0x0027a000, 0x0027c000, 0x0027e000, 0x00280000, 0x00282000, 0x00284000,
-       0x00286000, 0x00288000, 0x0028a000, 0x0028c000, 0x0028e000, 0x00290000,
-       0x00292000, 0x00294000, 0x00296000, 0x00298000, 0x0029a000, 0x0029c000,
-       0x0029e000, 0x002a0000, 0x002a2000, 0x002a4000, 0x002a6000, 0x002a8000,
-       0x002aa000, 0x002ac000, 0x002ae000, 0x002b0000, 0x002b2000, 0x002b4000,
-       0x002b6000, 0x002b8000, 0x002ba000, 0x002bc000, 0x002be000, 0x002c0000,
-       0x002c2000, 0x002c4000, 0x002c6000, 0x002c8000, 0x002ca000, 0x002cc000,
-       0x002ce000, 0x002d0000, 0x002d2000, 0x002d4000, 0x002d6000, 0x002d8000,
-       0x002da000, 0x002dc000, 0x002de000, 0x002e0000, 0x002e2000, 0x002e4000,
-       0x002e6000, 0x002e8000, 0x002ea000, 0x002ec000, 0x002ee000, 0x002f0000,
-       0x002f2000, 0x002f4000, 0x002f6000, 0x002f8000, 0x002fa000, 0x002fc000,
-       0x002fe000, 0x00300000, 0x00302000, 0x00304000, 0x00306000, 0x00308000,
-       0x0030a000, 0x0030c000, 0x0030e000, 0x00310000, 0x00312000, 0x00314000,
-       0x00316000, 0x00318000, 0x0031a000, 0x0031c000, 0x0031e000, 0x00320000,
-       0x00322000, 0x00324000, 0x00326000, 0x00328000, 0x0032a000, 0x0032c000,
-       0x0032e000, 0x00330000, 0x00332000, 0x00334000, 0x00336000, 0x00338000,
-       0x0033a000, 0x0033c000, 0x0033e000, 0x00340000, 0x00342000, 0x00344000,
-       0x00346000, 0x00348000, 0x0034a000, 0x0034c000, 0x0034e000, 0x00350000,
-       0x00352000, 0x00354000, 0x00356000, 0x00358000, 0x0035a000, 0x0035c000,
-       0x0035e000, 0x00360000, 0x00362000, 0x00364000, 0x00366000, 0x00368000,
-       0x0036a000, 0x0036c000, 0x0036e000, 0x00370000, 0x00372000, 0x00374000,
-       0x00376000, 0x00378000, 0x0037a000, 0x0037c000, 0x0037e000, 0x00380000,
-       0x00382000, 0x00384000, 0x00386000, 0x00388000, 0x0038a000, 0x0038c000,
-       0x0038e000, 0x00390000, 0x00392000, 0x00394000, 0x00396000, 0x00398000,
-       0x0039a000, 0x0039c000, 0x0039e000, 0x003a0000, 0x003a2000, 0x003a4000,
-       0x003a6000, 0x003a8000, 0x003aa000, 0x003ac000, 0x003ae000, 0x003b0000,
-       0x003b2000, 0x003b4000, 0x003b6000, 0x003b8000, 0x003ba000, 0x003bc000,
-       0x003be000, 0x003c0000, 0x003c2000, 0x003c4000, 0x003c6000, 0x003c8000,
-       0x003ca000, 0x003cc000, 0x003ce000, 0x003d0000, 0x003d2000, 0x003d4000,
-       0x003d6000, 0x003d8000, 0x003da000, 0x003dc000, 0x003de000, 0x003e0000,
-       0x003e2000, 0x003e4000, 0x003e6000, 0x003e8000, 0x003ea000, 0x003ec000,
-       0x003ee000, 0x003f0000, 0x003f2000, 0x003f4000, 0x003f6000, 0x003f8000,
-       0x003fa000, 0x003fc000, 0x003fe000, 0x003fe001, 0x00000000, 0x000001ff,
-       0x00000200, 0x00000001, 0x00000003, 0x00bebc20, 0x00000003, 0x00bebc20,
-       0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
-       0xffffffff, 0xffffffff, 0x00000000, 0x00007ff8, 0x00000000, 0x00003500,
-       0xffffffff, 0x00000000, 0xffffffff, 0x00000000, 0xffffffff, 0x00000003,
-       0x00bebc20, 0xffffffff, 0x00000000, 0xffffffff, 0x00000000, 0xffffffff,
-       0x00000003, 0x00bebc20, 0x00002000, 0x000040c0, 0x00006180, 0x00008240,
-       0x0000a300, 0x0000c3c0, 0x0000e480, 0x00010540, 0x00012600, 0x000146c0,
-       0x00016780, 0x00018840, 0x0001a900, 0x0001c9c0, 0x0001ea80, 0x00020b40,
-       0x00022c00, 0x00024cc0, 0x00026d80, 0x00028e40, 0x0002af00, 0x0002cfc0,
-       0x0002f080, 0x00031140, 0x00033200, 0x000352c0, 0x00037380, 0x00039440,
-       0x0003b500, 0x0003d5c0, 0x0003f680, 0x00041740, 0x00043800, 0x000458c0,
-       0x00047980, 0x00049a40, 0x00008000, 0x00010380, 0x00018700, 0x00020a80,
-       0x00028e00, 0x00031180, 0x00039500, 0x00041880, 0x00049c00, 0x00051f80,
-       0x0005a300, 0x00062680, 0x0006aa00, 0x00072d80, 0x0007b100, 0x00083480,
-       0x0008b800, 0x00093b80, 0x0009bf00, 0x000a4280, 0x000ac600, 0x000b4980,
-       0x000bcd00, 0x000c5080, 0x000cd400, 0x000d5780, 0x000ddb00, 0x00001900,
-       0x00000000, 0xffffffff, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
-       0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
-       0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
-       0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
-       0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
-       0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x00000000, 0x00007ff8,
-       0x00000000, 0x00001500, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
-       0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x40000000, 0x40000000,
-       0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
-       0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
-       0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
-       0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
-       0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
-       0x00000000, 0x00007ff8, 0x00000000, 0x00001500, 0x00001000, 0x00002080,
-       0x00003100, 0x00004180, 0x00005200, 0x00006280, 0x00007300, 0x00008380,
-       0x00009400, 0x0000a480, 0x0000b500, 0x0000c580, 0x0000d600, 0x0000e680,
-       0x0000f700, 0x00010780, 0x00011800, 0x00012880, 0x00013900, 0x00014980,
-       0x00015a00, 0x00016a80, 0x00017b00, 0x00018b80, 0x00019c00, 0x0001ac80,
-       0x0001bd00, 0x0001cd80, 0x0001de00, 0x0001ee80, 0x0001ff00, 0x10000000,
-       0x000028ad, 0x00000000, 0x00010001, 0x00350804, 0xccccccc1, 0xffffffff,
-       0xffffffff, 0x7058103c, 0x00000000, 0xcccc0201, 0xcccccccc, 0x00000000,
-       0xffffffff, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
-       0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
-       0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
-       0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
-       0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
-       0x40000000, 0x40000000, 0x40000000, 0x00000000, 0x00007ff8, 0x00000000,
-       0x00003500, 0x000e01b7, 0x011600d6, 0x0000ffff, 0x00000000, 0x0000ffff,
-       0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
-       0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
-       0x00000000, 0x00100000, 0x00000000, 0x007201bb, 0x012300f3, 0x0000ffff,
-       0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
-       0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff,
-       0x00000000, 0x0000ffff, 0x00000000, 0x00100000, 0x00000000, 0xfffffff3,
-       0x320fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0000cf3c,
-       0xcdcdcdcd, 0xfffffff1, 0x30efffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
-       0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xfffffff6, 0x305fffff, 0x0c30c30c,
-       0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xfffff406,
-       0x1cbfffff, 0x0c30c305, 0xc30c30c3, 0xcf300014, 0xf3cf3cf3, 0x0004cf3c,
-       0xcdcdcdcd, 0xfffffff2, 0x304fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
-       0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xfffffffa, 0x302fffff, 0x0c30c30c,
-       0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xfffffff7,
-       0x31efffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0020cf3c,
-       0xcdcdcdcd, 0xfffffff5, 0x302fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
-       0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xfffffff3, 0x310fffff, 0x0c30c30c,
-       0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xfffffff1,
-       0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0001cf3c,
-       0xcdcdcdcd, 0xfffffff6, 0x305fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
-       0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xfffff406, 0x1cbfffff, 0x0c30c305,
-       0xc30c30c3, 0xcf300014, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xfffffff2,
-       0x304fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0008cf3c,
-       0xcdcdcdcd, 0xfffffffa, 0x302fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
-       0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xfffffff7, 0x30efffff, 0x0c30c30c,
-       0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xfffffff5,
-       0x304fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0040cf3c,
-       0xcdcdcdcd, 0xfffffff3, 0x31efffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
-       0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xfffffff1, 0x310fffff, 0x0c30c30c,
-       0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xfffffff6,
-       0x305fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0002cf3c,
-       0xcdcdcdcd, 0xfffff406, 0x1cbfffff, 0x0c30c305, 0xc30c30c3, 0xcf300014,
-       0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xfffffff2, 0x304fffff, 0x0c30c30c,
-       0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xfffffffa,
-       0x302fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0010cf3c,
-       0xcdcdcdcd, 0xffffff97, 0x056fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cc000,
-       0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xfffffff5, 0x310fffff, 0x0c30c30c,
-       0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xfffffff3,
-       0x320fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0000cf3c,
-       0xcdcdcdcd, 0xfffffff1, 0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
-       0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xfffffff6, 0x305fffff, 0x0c30c30c,
-       0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xfffff406,
-       0x1cbfffff, 0x0c30c305, 0xc30c30c3, 0xcf300014, 0xf3cf3cf3, 0x0004cf3c,
-       0xcdcdcdcd, 0xfffffff2, 0x304fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
-       0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xffffff8a, 0x042fffff, 0x0c30c30c,
-       0xc30c30c3, 0xcf3cc000, 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xffffff97,
-       0x05cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cc000, 0xf3cf3cf3, 0x0020cf3c,
-       0xcdcdcdcd, 0xfffffff5, 0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
-       0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xfffffff3, 0x300fffff, 0x0c30c30c,
-       0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xfffffff1,
-       0x300fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0001cf3c,
-       0xcdcdcdcd, 0xfffffff6, 0x305fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
-       0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xfffff406, 0x1cbfffff, 0x0c30c305,
-       0xc30c30c3, 0xcf300014, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xfffffff2,
-       0x304fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0008cf3c,
-       0xcdcdcdcd, 0xfffffffa, 0x302fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300,
-       0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xffffff97, 0x040fffff, 0x0c30c30c,
-       0xc30c30c3, 0xcf3cc000, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xfffffff5,
-       0x300fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0040cf3c,
-       0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
-       0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
-       0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xffffffff,
-       0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0002cf3c,
-       0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
-       0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
-       0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xffffffff,
-       0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0010cf3c,
-       0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
-       0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
-       0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xffffffff,
-       0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0000cf3c,
-       0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
-       0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
-       0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xffffffff,
-       0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0004cf3c,
-       0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
-       0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
-       0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xffffffff,
-       0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0020cf3c,
-       0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
-       0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
-       0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xffffffff,
-       0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0001cf3c,
-       0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
-       0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
-       0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xffffffff,
-       0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0008cf3c,
-       0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc,
-       0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c,
-       0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xffffffff,
-       0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0040cf3c,
-       0xcdcdcdcd, 0x00100000, 0x00070100, 0x00028170, 0x000b8198, 0x00020250,
-       0x00010270, 0x000f0280, 0x00010370, 0x00080000, 0x00080080, 0x00028100,
-       0x000b8128, 0x000201e0, 0x00010200, 0x00070210, 0x00020280, 0x000f0000,
-       0x000800f0, 0x00028170, 0x000b8198, 0x00020250, 0x00010270, 0x000b8280,
-       0x00080338, 0x00100000, 0x00080100, 0x00028180, 0x000b81a8, 0x00020260,
-       0x00018280, 0x000e8298, 0x00080380, 0x00028000, 0x000b8028, 0x000200e0,
-       0x00010100, 0x00008110, 0x00000118, 0xcccccccc, 0xcccccccc, 0xcccccccc,
-       0xcccccccc, 0x00002000, 0xcccccccc, 0xcccccccc, 0xcccccccc, 0xcccccccc,
-       0x00002000, 0xcccccccc, 0xcccccccc, 0xcccccccc, 0xcccccccc, 0x00002000
-};
-
-static const u32 init_data_e1h[] = {
-       0x00010000, 0x000204c0, 0x00030980, 0x00040e40, 0x00051300, 0x000617c0,
-       0x00071c80, 0x00082140, 0x00092600, 0x000a2ac0, 0x000b2f80, 0x000c3440,
-       0x000d3900, 0x000e3dc0, 0x000f4280, 0x00104740, 0x00114c00, 0x001250c0,
-       0x00135580, 0x00145a40, 0x00155f00, 0x001663c0, 0x00176880, 0x00186d40,
-       0x00197200, 0x001a76c0, 0x001b7b80, 0x001c8040, 0x001d8500, 0x001e89c0,
-       0x001f8e80, 0x00209340, 0x00002000, 0x00004000, 0x00006000, 0x00008000,
-       0x0000a000, 0x0000c000, 0x0000e000, 0x00010000, 0x00012000, 0x00014000,
-       0x00016000, 0x00018000, 0x0001a000, 0x0001c000, 0x0001e000, 0x00020000,
-       0x00022000, 0x00024000, 0x00026000, 0x00028000, 0x0002a000, 0x0002c000,
-       0x0002e000, 0x00030000, 0x00032000, 0x00034000, 0x00036000, 0x00038000,
-       0x0003a000, 0x0003c000, 0x0003e000, 0x00040000, 0x00042000, 0x00044000,
-       0x00046000, 0x00048000, 0x0004a000, 0x0004c000, 0x0004e000, 0x00050000,
-       0x00052000, 0x00054000, 0x00056000, 0x00058000, 0x0005a000, 0x0005c000,
-       0x0005e000, 0x00060000, 0x00062000, 0x00064000, 0x00066000, 0x00068000,
-       0x0006a000, 0x0006c000, 0x0006e000, 0x00070000, 0x00072000, 0x00074000,
-       0x00076000, 0x00078000, 0x0007a000, 0x0007c000, 0x0007e000, 0x00080000,
-       0x00082000, 0x00084000, 0x00086000, 0x00088000, 0x0008a000, 0x0008c000,
-       0x0008e000, 0x00090000, 0x00092000, 0x00094000, 0x00096000, 0x00098000,
-       0x0009a000, 0x0009c000, 0x0009e000, 0x000a0000, 0x000a2000, 0x000a4000,
-       0x000a6000, 0x000a8000, 0x000aa000, 0x000ac000, 0x000ae000, 0x000b0000,
-       0x000b2000, 0x000b4000, 0x000b6000, 0x000b8000, 0x000ba000, 0x000bc000,
-       0x000be000, 0x000c0000, 0x000c2000, 0x000c4000, 0x000c6000, 0x000c8000,
-       0x000ca000, 0x000cc000, 0x000ce000, 0x000d0000, 0x000d2000, 0x000d4000,
-       0x000d6000, 0x000d8000, 0x000da000, 0x000dc000, 0x000de000, 0x000e0000,
-       0x000e2000, 0x000e4000, 0x000e6000, 0x000e8000, 0x000ea000, 0x000ec000,
-       0x000ee000, 0x000f0000, 0x000f2000, 0x000f4000, 0x000f6000, 0x000f8000,
-       0x000fa000, 0x000fc000, 0x000fe000, 0x00100000, 0x00102000, 0x00104000,
-       0x00106000, 0x00108000, 0x0010a000, 0x0010c000, 0x0010e000, 0x00110000,
-       0x00112000, 0x00114000, 0x00116000, 0x00118000, 0x0011a000, 0x0011c000,
-       0x0011e000, 0x00120000, 0x00122000, 0x00124000, 0x00126000, 0x00128000,
-       0x0012a000, 0x0012c000, 0x0012e000, 0x00130000, 0x00132000, 0x00134000,
-       0x00136000, 0x00138000, 0x0013a000, 0x0013c000, 0x0013e000, 0x00140000,
-       0x00142000, 0x00144000, 0x00146000, 0x00148000, 0x0014a000, 0x0014c000,
-       0x0014e000, 0x00150000, 0x00152000, 0x00154000, 0x00156000, 0x00158000,
-       0x0015a000, 0x0015c000, 0x0015e000, 0x00160000, 0x00162000, 0x00164000,
-       0x00166000, 0x00168000, 0x0016a000, 0x0016c000, 0x0016e000, 0x00170000,
-       0x00172000, 0x00174000, 0x00176000, 0x00178000, 0x0017a000, 0x0017c000,
-       0x0017e000, 0x00180000, 0x00182000, 0x00184000, 0x00186000, 0x00188000,
-       0x0018a000, 0x0018c000, 0x0018e000, 0x00190000, 0x00192000, 0x00194000,
-       0x00196000, 0x00198000, 0x0019a000, 0x0019c000, 0x0019e000, 0x001a0000,
-       0x001a2000, 0x001a4000, 0x001a6000, 0x001a8000, 0x001aa000, 0x001ac000,
-       0x001ae000, 0x001b0000, 0x001b2000, 0x001b4000, 0x001b6000, 0x001b8000,
-       0x001ba000, 0x001bc000, 0x001be000, 0x001c0000, 0x001c2000, 0x001c4000,
-       0x001c6000, 0x001c8000, 0x001ca000, 0x001cc000, 0x001ce000, 0x001d0000,
-       0x001d2000, 0x001d4000, 0x001d6000, 0x001d8000, 0x001da000, 0x001dc000,
-       0x001de000, 0x001e0000, 0x001e2000, 0x001e4000, 0x001e6000, 0x001e8000,
-       0x001ea000, 0x001ec000, 0x001ee000, 0x001f0000, 0x001f2000, 0x001f4000,
-       0x001f6000, 0x001f8000, 0x001fa000, 0x001fc000, 0x001fe000, 0x00200000,
-       0x00202000, 0x00204000, 0x00206000, 0x00208000, 0x0020a000, 0x0020c000,
-       0x0020e000, 0x00210000, 0x00212000, 0x00214000, 0x00216000, 0x00218000,
-       0x0021a000, 0x0021c000, 0x0021e000, 0x00220000, 0x00222000, 0x00224000,
-       0x00226000, 0x00228000, 0x0022a000, 0x0022c000, 0x0022e000, 0x00230000,
-       0x00232000, 0x00234000, 0x00236000, 0x00238000, 0x0023a000, 0x0023c000,
-       0x0023e000, 0x00240000, 0x00242000, 0x00244000, 0x00246000, 0x00248000,
-       0x0024a000, 0x0024c000, 0x0024e000, 0x00250000, 0x00252000, 0x00254000,
-       0x00256000, 0x00258000, 0x0025a000, 0x0025c000, 0x0025e000, 0x00260000,
-       0x00262000, 0x00264000, 0x00266000, 0x00268000, 0x0026a000, 0x0026c000,
-       0x0026e000, 0x00270000, 0x00272000, 0x00274000, 0x00276000, 0x00278000,
-       0x0027a000, 0x0027c000, 0x0027e000, 0x00280000, 0x00282000, 0x00284000,
-       0x00286000, 0x00288000, 0x0028a000, 0x0028c000, 0x0028e000, 0x00290000,
-       0x00292000, 0x00294000, 0x00296000, 0x00298000, 0x0029a000, 0x0029c000,
-       0x0029e000, 0x002a0000, 0x002a2000, 0x002a4000, 0x002a6000, 0x002a8000,
-       0x002aa000, 0x002ac000, 0x002ae000, 0x002b0000, 0x002b2000, 0x002b4000,
-       0x002b6000, 0x002b8000, 0x002ba000, 0x002bc000, 0x002be000, 0x002c0000,
-       0x002c2000, 0x002c4000, 0x002c6000, 0x002c8000, 0x002ca000, 0x002cc000,
-       0x002ce000, 0x002d0000, 0x002d2000, 0x002d4000, 0x002d6000, 0x002d8000,
-       0x002da000, 0x002dc000, 0x002de000, 0x002e0000, 0x002e2000, 0x002e4000,
-       0x002e6000, 0x002e8000, 0x002ea000, 0x002ec000, 0x002ee000, 0x002f0000,
-       0x002f2000, 0x002f4000, 0x002f6000, 0x002f8000, 0x002fa000, 0x002fc000,
-       0x002fe000, 0x00300000, 0x00302000, 0x00304000, 0x00306000, 0x00308000,
-       0x0030a000, 0x0030c000, 0x0030e000, 0x00310000, 0x00312000, 0x00314000,
-       0x00316000, 0x00318000, 0x0031a000, 0x0031c000, 0x0031e000, 0x00320000,
-       0x00322000, 0x00324000, 0x00326000, 0x00328000, 0x0032a000, 0x0032c000,
-       0x0032e000, 0x00330000, 0x00332000, 0x00334000, 0x00336000, 0x00338000,
-       0x0033a000, 0x0033c000, 0x0033e000, 0x00340000, 0x00342000, 0x00344000,
-       0x00346000, 0x00348000, 0x0034a000, 0x0034c000, 0x0034e000, 0x00350000,
-       0x00352000, 0x00354000, 0x00356000, 0x00358000, 0x0035a000, 0x0035c000,
-       0x0035e000, 0x00360000, 0x00362000, 0x00364000, 0x00366000, 0x00368000,
-       0x0036a000, 0x0036c000, 0x0036e000, 0x00370000, 0x00372000, 0x00374000,
-       0x00376000, 0x00378000, 0x0037a000, 0x0037c000, 0x0037e000, 0x00380000,
-       0x00382000, 0x00384000, 0x00386000, 0x00388000, 0x0038a000, 0x0038c000,
-       0x0038e000, 0x00390000, 0x00392000, 0x00394000, 0x00396000, 0x00398000,
-       0x0039a000, 0x0039c000, 0x0039e000, 0x003a0000, 0x003a2000, 0x003a4000,
-       0x003a6000, 0x003a8000, 0x003aa000, 0x003ac000, 0x003ae000, 0x003b0000,
-       0x003b2000, 0x003b4000, 0x003b6000, 0x003b8000, 0x003ba000, 0x003bc000,
-       0x003be000, 0x003c0000, 0x003c2000, 0x003c4000, 0x003c6000, 0x003c8000,
-       0x003ca000, 0x003cc000, 0x003ce000, 0x003d0000, 0x003d2000, 0x003d4000,
-       0x003d6000, 0x003d8000, 0x003da000, 0x003dc000, 0x003de000, 0x003e0000,
-       0x003e2000, 0x003e4000, 0x003e6000, 0x003e8000, 0x003ea000, 0x003ec000,
-       0x003ee000, 0x003f0000, 0x003f2000, 0x003f4000, 0x003f6000, 0x003f8000,
-       0x003fa000, 0x003fc000, 0x003fe000, 0x003fe001, 0x00000000, 0x000001ff,
-       0x00000200, 0x00000001, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
-       0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
-       0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
-       0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
-       0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
-       0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0x00007ff8,
-       0x00000000, 0x00003500, 0xffffffff, 0x00000000, 0xffffffff, 0x00000000,
-       0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, 0x00000000, 0xffffffff,
-       0xffffffff, 0x00000000, 0xffffffff, 0x00000000, 0xffffffff, 0x00000003,
-       0x00bebc20, 0xffffffff, 0x00000000, 0xffffffff, 0x00000000, 0xffffffff,
-       0x00000003, 0x00bebc20, 0xffffffff, 0x00000000, 0xffffffff, 0x00000000,
-       0xffffffff, 0x00000003, 0x00bebc20, 0xffffffff, 0x00000000, 0xffffffff,
-       0x00000000, 0xffffffff, 0x00000003, 0x00bebc20, 0xffffffff, 0x00000000,
-       0xffffffff, 0x00000000, 0xffffffff, 0x00000003, 0x00bebc20, 0xffffffff,
-       0x00000000, 0xffffffff, 0x00000000, 0xffffffff, 0x00000003, 0x00bebc20,
-       0x00002000, 0x000040c0, 0x00006180, 0x00008240, 0x0000a300, 0x0000c3c0,
-       0x0000e480, 0x00010540, 0x00012600, 0x000146c0, 0x00016780, 0x00018840,
-       0x0001a900, 0x0001c9c0, 0x0001ea80, 0x00020b40, 0x00022c00, 0x00024cc0,
-       0x00026d80, 0x00028e40, 0x0002af00, 0x0002cfc0, 0x0002f080, 0x00031140,
-       0x00033200, 0x000352c0, 0x00037380, 0x00039440, 0x0003b500, 0x0003d5c0,
-       0x0003f680, 0x00041740, 0x00043800, 0x000458c0, 0x00047980, 0x00049a40,
-       0x00008000, 0x00010380, 0x00018700, 0x00020a80, 0x00028e00, 0x00031180,
-       0x00039500, 0x00041880, 0x00049c00, 0x00051f80, 0x0005a300, 0x00062680,
-       0x0006aa00, 0x00072d80, 0x0007b100, 0x00083480, 0x0008b800, 0x00093b80,
-       0x0009bf00, 0x000a4280, 0x000ac600, 0x000b4980, 0x000bcd00, 0x000c5080,
-       0x000cd400, 0x000d5780, 0x000ddb00, 0x00001900, 0x00000028, 0x00100000,
-       0x00000000, 0x00000000, 0xffffffff, 0x40000000, 0x40000000, 0x40000000,
-       0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
-       0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
-       0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
-       0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
-       0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x00000000,
-       0x00007ff8, 0x00000000, 0x00001500, 0xffffffff, 0xffffffff, 0xffffffff,
-       0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
-       0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
-       0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
-       0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
-       0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x40000000,
-       0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
-       0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
-       0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
-       0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
-       0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
-       0x40000000, 0x00000000, 0x00007ff8, 0x00000000, 0x00001500, 0x00001000,
-       0x00002080, 0x00003100, 0x00004180, 0x00005200, 0x00006280, 0x00007300,
-       0x00008380, 0x00009400, 0x0000a480, 0x0000b500, 0x0000c580, 0x0000d600,
-       0x0000e680, 0x0000f700, 0x00010780, 0x00011800, 0x00012880, 0x00013900,
-       0x00014980, 0x00015a00, 0x00016a80, 0x00017b00, 0x00018b80, 0x00019c00,
-       0x0001ac80, 0x0001bd00, 0x0001cd80, 0x0001de00, 0x0001ee80, 0x0001ff00,
-       0x10000000, 0x000028ad, 0x00000000, 0x00010001, 0x00350804, 0xccccccc5,
-       0xffffffff, 0xffffffff, 0x7058103c, 0x00000000, 0xcccc0201, 0xcccccccc,
-       0xcccc0201, 0xcccccccc, 0xcccc0201, 0xcccccccc, 0xcccc0201, 0xcccccccc,
-       0xcccc0201, 0xcccccccc, 0xcccc0201, 0xcccccccc, 0xcccc0201, 0xcccccccc,
-       0xcccc0201, 0xcccccccc, 0x00000000, 0xffffffff, 0x40000000, 0x40000000,
-       0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
-       0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
-       0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
-       0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
-       0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000, 0x40000000,
-       0x00000000, 0x00007ff8, 0x00000000, 0x00003500, 0x000e0232, 0x011600d6,
-       0x00100000, 0x00000000, 0x00720236, 0x012300f3, 0x00100000, 0x00000000,
-       0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
-       0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
-       0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
-       0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
-       0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
-       0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
-       0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
-       0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
-       0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
-       0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
-       0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
-       0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
-       0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
-       0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
-       0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
-       0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
-       0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
-       0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
-       0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
-       0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
-       0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000, 0x0000ffff, 0x00000000,
-       0x0000ffff, 0x00000000, 0xfffffff3, 0x320fffff, 0x0c30c30c, 0xc30c30c3,
-       0xcf3cf300, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xfffffff1, 0x30efffff,
-       0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd,
-       0xfffffff6, 0x305fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3,
-       0x0002cf3c, 0xcdcdcdcd, 0xfffff406, 0x1cbfffff, 0x0c30c305, 0xc30c30c3,
-       0xcf300014, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xfffffff2, 0x304fffff,
-       0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd,
-       0xfffffffa, 0x302fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3,
-       0x0010cf3c, 0xcdcdcdcd, 0xfffffff7, 0x31efffff, 0x0c30c30c, 0xc30c30c3,
-       0xcf3cf300, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xfffffff5, 0x302fffff,
-       0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd,
-       0xfffffff3, 0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3,
-       0x0000cf3c, 0xcdcdcdcd, 0xfffffff1, 0x310fffff, 0x0c30c30c, 0xc30c30c3,
-       0xcf3cf300, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xfffffff6, 0x305fffff,
-       0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd,
-       0xfffff406, 0x1cbfffff, 0x0c30c305, 0xc30c30c3, 0xcf300014, 0xf3cf3cf3,
-       0x0004cf3c, 0xcdcdcdcd, 0xfffffff2, 0x304fffff, 0x0c30c30c, 0xc30c30c3,
-       0xcf3cf300, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xfffffffa, 0x302fffff,
-       0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd,
-       0xfffffff7, 0x30efffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3,
-       0x0020cf3c, 0xcdcdcdcd, 0xfffffff5, 0x304fffff, 0x0c30c30c, 0xc30c30c3,
-       0xcf3cf300, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xfffffff3, 0x31efffff,
-       0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd,
-       0xfffffff1, 0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3,
-       0x0001cf3c, 0xcdcdcdcd, 0xfffffff6, 0x305fffff, 0x0c30c30c, 0xc30c30c3,
-       0xcf3cf300, 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xfffff406, 0x1cbfffff,
-       0x0c30c305, 0xc30c30c3, 0xcf300014, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd,
-       0xfffffff2, 0x304fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3,
-       0x0008cf3c, 0xcdcdcdcd, 0xfffffffa, 0x302fffff, 0x0c30c30c, 0xc30c30c3,
-       0xcf3cf300, 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xffffff97, 0x056fffff,
-       0x0c30c30c, 0xc30c30c3, 0xcf3cc000, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd,
-       0xfffffff5, 0x310fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3,
-       0x0040cf3c, 0xcdcdcdcd, 0xfffffff3, 0x320fffff, 0x0c30c30c, 0xc30c30c3,
-       0xcf3cf300, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xfffffff1, 0x310fffff,
-       0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd,
-       0xfffffff6, 0x305fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3,
-       0x0002cf3c, 0xcdcdcdcd, 0xfffff406, 0x1cbfffff, 0x0c30c305, 0xc30c30c3,
-       0xcf300014, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xfffffff2, 0x304fffff,
-       0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd,
-       0xffffff8a, 0x042fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cc000, 0xf3cf3cf3,
-       0x0010cf3c, 0xcdcdcdcd, 0xffffff97, 0x05cfffff, 0x0c30c30c, 0xc30c30c3,
-       0xcf3cc000, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xfffffff5, 0x310fffff,
-       0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd,
-       0xfffffff3, 0x316fffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3,
-       0x0000cf3c, 0xcdcdcdcd, 0xfffffff1, 0x302fffff, 0x0c30c30c, 0xc30c30c3,
-       0xcf3cf300, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xfffffff6, 0x305fffff,
-       0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd,
-       0xfffffff6, 0x30bfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf314, 0xf3cf3cf3,
-       0x0004cf3c, 0xcdcdcdcd, 0xfffffff2, 0x304fffff, 0x0c30c30c, 0xc30c30c3,
-       0xcf3cf300, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xfffffffa, 0x302fffff,
-       0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd,
-       0xfffffff7, 0x31cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf300, 0xf3cf3cf3,
-       0x0020cf3c, 0xcdcdcdcd, 0xfffffff0, 0x307fffff, 0x0c30c30c, 0xc30c30c3,
-       0xcf3cf300, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff,
-       0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd,
-       0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3,
-       0x0001cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3,
-       0xcf3cf3cc, 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff,
-       0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd,
-       0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3,
-       0x0008cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3,
-       0xcf3cf3cc, 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff,
-       0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd,
-       0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3,
-       0x0040cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3,
-       0xcf3cf3cc, 0xf3cf3cf3, 0x0000cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff,
-       0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd,
-       0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3,
-       0x0002cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3,
-       0xcf3cf3cc, 0xf3cf3cf3, 0x0004cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff,
-       0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd,
-       0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3,
-       0x0010cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3,
-       0xcf3cf3cc, 0xf3cf3cf3, 0x0020cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff,
-       0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd,
-       0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3,
-       0x0000cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3,
-       0xcf3cf3cc, 0xf3cf3cf3, 0x0001cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff,
-       0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0002cf3c, 0xcdcdcdcd,
-       0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3,
-       0x0004cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3,
-       0xcf3cf3cc, 0xf3cf3cf3, 0x0008cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff,
-       0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3, 0x0010cf3c, 0xcdcdcdcd,
-       0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3, 0xcf3cf3cc, 0xf3cf3cf3,
-       0x0020cf3c, 0xcdcdcdcd, 0xffffffff, 0x30cfffff, 0x0c30c30c, 0xc30c30c3,
-       0xcf3cf3cc, 0xf3cf3cf3, 0x0040cf3c, 0xcdcdcdcd, 0x00100000, 0x00070100,
-       0x00028170, 0x000b8198, 0x00020250, 0x00010270, 0x000f0280, 0x00010370,
-       0x00080000, 0x00080080, 0x00028100, 0x000b8128, 0x000201e0, 0x00010200,
-       0x00070210, 0x00020280, 0x000f0000, 0x000800f0, 0x00028170, 0x000b8198,
-       0x00020250, 0x00010270, 0x000b8280, 0x00080338, 0x00100000, 0x00080100,
-       0x00028180, 0x000b81a8, 0x00020260, 0x00018280, 0x000e8298, 0x00080380,
-       0x000b0000, 0x000100b0, 0x000280c0, 0x000580e8, 0x00020140, 0x00010160,
-       0x000e0170, 0x00038250, 0xcccccccc, 0xcccccccc, 0xcccccccc, 0xcccccccc,
-       0x00002000, 0xcccccccc, 0xcccccccc, 0xcccccccc, 0xcccccccc, 0x00002000,
-       0xcccccccc, 0xcccccccc, 0xcccccccc, 0xcccccccc, 0x04002000
-};
-
-static const u32 tsem_int_table_data_e1[] = {
-       0x00088b1f, 0x00000000, 0x51fbff00, 0x03f0c0cf, 0x19d9458a, 0x1138fc18,
-       0x5980a1fc, 0xd8181998, 0x88039880, 0x81b8803d, 0x91a18191, 0xdafd7891,
-       0xbf760862, 0x6ec30330, 0x0211e620, 0x1082239a, 0xf354029f, 0x0f5fc806,
-       0x6512b315, 0x3a263860, 0x06a77ef0, 0x298d2ade, 0xc1124536, 0x1e4586de,
-       0x93476f19, 0xca8922ff, 0xff4041df, 0x65296340, 0x229dbe54, 0x04a65e84,
-       0xe4d1a5a1, 0xd7f2a1ed, 0x5192fea1, 0x0dee6ec6, 0xf8003ca8, 0x6065495c,
-       0x00606549
-};
-
-static const u32 tsem_pram_data_e1[] = {
-       0x00088b1f, 0x00000000, 0x7dedff00, 0xd554780b, 0x733ef0b5, 0x49999cce,
-       0x424e4cce, 0x4c22f212, 0x21a08812, 0x8a80af0c, 0x2201277f, 0x282039f5,
-       0x4201d458, 0xd4837908, 0xcdedaf4b, 0x11102484, 0x0547f435, 0x5088768b,
-       0x340da2d1, 0x0ec160d2, 0x6d7b1420, 0xc0faf06f, 0x480bf5ea, 0xb12f3141,
-       0xcbc57e20, 0xe7dad6bf, 0x264ce664, 0xafdbd880, 0xb4fdffff, 0xece7d9b8,
-       0xebdaf7b3, 0x7b5ad7b5, 0x75923ded, 0xc7bf9302, 0x03fc45d8, 0x8c4d4fe5,
-       0xf2c109b1, 0x80f66667, 0xc9b18727, 0x473afebd, 0x6d55633c, 0x9da23b19,
-       0x99ec258c, 0x50281421, 0x2c23d5fe, 0xbfdf8250, 0xf097c365, 0x4219b6ff,
-       0xd0977c3e, 0xc3e611e9, 0x02d5e4fb, 0x933a876b, 0xea0c319c, 0x4b19b98c,
-       0x126b2c64, 0x4b223fa3, 0xe0ff828d, 0x8f392573, 0x27fc34b1, 0x61467574,
-       0xc678c0ae, 0x5c531e32, 0x38a9d0d4, 0x843f7815, 0xbcd2c67f, 0x0731b725,
-       0xbc03cf63, 0xbcf071c9, 0x61de3a5a, 0xc22eefe5, 0x3af3a1df, 0xae58cd6a,
-       0x32773e30, 0x416589a7, 0xf3e33ebf, 0x3d6346ac, 0x4fe3d99b, 0xec3fc346,
-       0x8c517ecc, 0xb1138f30, 0xcb3c018c, 0x632f0e54, 0x5467b2bd, 0x6a9b1f10,
-       0x2c32a258, 0x852f0f58, 0x56338765, 0xed975e03, 0xf8165c16, 0x2f6c39fe,
-       0xbed7e631, 0x15ead66b, 0xa362593e, 0xb50404a1, 0x67eff4e4, 0x11bfcb11,
-       0x2b30fef1, 0xea4ab2a0, 0xaf805595, 0xfb765aaa, 0x67edfe95, 0x54e88933,
-       0x5bf6b929, 0x5adefc61, 0xf1866ae6, 0x02d59997, 0x91fb2fac, 0x7a83e5d3,
-       0x21476366, 0x36d0fa83, 0xc1198981, 0x9e00afef, 0x007f91db, 0xa52b2a1e,
-       0x740642de, 0xb02bddec, 0x871c0ce6, 0x776cbbf7, 0x0c65f306, 0x6658e70c,
-       0x32e73826, 0x74893a41, 0xd2073071, 0xf324bcc1, 0xcea84289, 0xb0f3dc54,
-       0x9de29f7f, 0xe7f4ed87, 0x38e60b49, 0xf25700bd, 0x57a06650, 0x9d3ab5b1,
-       0xea563265, 0xbe442969, 0x8decb538, 0x9e025855, 0xf7c02413, 0x08a78b7c,
-       0x5798a9fb, 0xa780cd9d, 0x8d1859e6, 0xff2db43f, 0x0cf80933, 0xc4c5f3ba,
-       0x76313f21, 0xf04f843c, 0x5a11f1cf, 0xde981c5d, 0xb08b2b97, 0x05f1091f,
-       0x1f011772, 0x26a0423f, 0x544d28e0, 0x29fc573a, 0xd0a0d86b, 0xc3595bfa,
-       0xe50069c6, 0x3f0cbc11, 0x0843ac61, 0x1cbd4be5, 0xb0ff3bba, 0x3c303b94,
-       0x04f3d3ff, 0xab7e1274, 0x1fc8b700, 0xbfd97615, 0xca61f812, 0xf7c0e6ab,
-       0x362a3f80, 0xd40b7e0b, 0xe8dbaf4d, 0x5e26f77d, 0x3765d80f, 0x16d74ff2,
-       0xbdf00ba8, 0x1bf1fda5, 0x155ebf91, 0x3b763359, 0xfa84ca22, 0x3b06a4e5,
-       0xc0750f1b, 0x578db147, 0xbbef362b, 0x692fbf1f, 0xf41b30b3, 0xf17bb157,
-       0x7d42371d, 0xc33361f1, 0x6b5b1526, 0x2fa814e5, 0x582d0bf1, 0xf0e029ef,
-       0xfe8976f9, 0xc7bed0ad, 0x1b389ed1, 0xc6ba73e8, 0x63329cca, 0xc4f6f675,
-       0xa567c059, 0xf8851dfe, 0xc176e95d, 0xf29f6885, 0xc943d6ea, 0xb917af38,
-       0x8b6d977c, 0x7f1d4e66, 0xab64f7f0, 0xbc1ef818, 0x64f3065f, 0xd662efd0,
-       0xb07a8854, 0xd93aeb62, 0xebe20f69, 0xe34a8d74, 0x8bdfc9f4, 0x577c0e30,
-       0xc2e08af9, 0x989a5629, 0x7bb0e517, 0xf3ce6db7, 0x56afce0a, 0xbce3b6ce,
-       0x6ed8cb56, 0x2efe7fb1, 0xfea5cd54, 0xbc2172cd, 0x59b4dd2f, 0xdb910e2e,
-       0x8c836db2, 0x1ac86d70, 0xd7208dec, 0xd7807841, 0x52f583b2, 0x0fa803d4,
-       0x233cbf25, 0x852acf84, 0xb2cbe258, 0x1a73226d, 0xddd388f8, 0x13fc2ef7,
-       0x6bdbe5f0, 0x74eabc27, 0x1aa7d3eb, 0x1aa8cedd, 0xbcdea51d, 0xf8f81119,
-       0xc003a471, 0x827884d3, 0x9f06ad72, 0x97cb3263, 0x9b877fa0, 0x3cbb02a9,
-       0xd999365f, 0xf563067c, 0xd2dd07b0, 0xd99750f5, 0xf582e652, 0x7bb1fa50,
-       0x0493d42a, 0x9f3867ef, 0xc25bc17a, 0x2496abd7, 0x9579e00f, 0xfce0e6c0,
-       0x30d0218f, 0xc0c955af, 0xa6f7809f, 0x8bcf7969, 0x3c7b0682, 0xb17f8bd6,
-       0x39fa8326, 0xa198fd43, 0xf7cbac9f, 0x324e16a3, 0x9616a3f4, 0x8dfcfde8,
-       0x595db1fa, 0x37854d3f, 0x2c29e118, 0x0491fbd5, 0xbf6f5768, 0x37a979b2,
-       0x73c2364f, 0x13f53973, 0xbcc5d53b, 0x1ae7ae0a, 0xb776b03f, 0xed95ef08,
-       0xb0d763b1, 0x5028be50, 0x0edb8005, 0x17ca1252, 0x0ca29331, 0x8eeb187c,
-       0x27a1d433, 0x4175e4f5, 0x958813fd, 0x45397c69, 0x9f90bd26, 0x43faa562,
-       0x85e90a29, 0x5ef06e87, 0x8e20eb83, 0x2ea192cd, 0x11ab477b, 0x14e01af8,
-       0x60961258, 0x7ff52417, 0xf1ccdabf, 0x217a9050, 0x5f7c18fb, 0x8ecdea65,
-       0xa635fa85, 0x6f116bfc, 0xe5eb812e, 0x63559128, 0x230b28bb, 0x233ab4fd,
-       0x085f79ef, 0x00871a9e, 0xbf6085fd, 0x126f668d, 0xdaf8d7f2, 0xc0127c67,
-       0xcc086ab7, 0x12ba0527, 0x60f8099e, 0xa43d5a3d, 0x69f10938, 0x43be4191,
-       0xfc6197c7, 0x06ff1a1c, 0xc71ba3c4, 0xbe3fe84f, 0x61927325, 0x897a6b7c,
-       0x0cab7c61, 0x4fbf03e3, 0xc6d66dad, 0xc0ddfc07, 0x99a134d8, 0x97a4b7c6,
-       0x65abf8d0, 0x3f186256, 0x5bfc6faa, 0x819efe70, 0x83799fe6, 0xa5e9fe71,
-       0x7ccbf9c6, 0x5f6ab3fe, 0xa28fc6d2, 0x5e16cff9, 0x2f4ff3e2, 0xf0b7f3e5,
-       0x77c6fb7e, 0x5effe1f4, 0x8077bf9c, 0x93592df1, 0x5a1ff38d, 0x85bf9c6e,
-       0xbb545f8f, 0xa15f1b53, 0x3b0917f1, 0x9687fcf9, 0xc5b2f8d3, 0x923e42eb,
-       0xfdaaa353, 0x81a44f68, 0x1d260c40, 0x0472a6e5, 0x1fa00518, 0x04990a86,
-       0x9c5143c7, 0x0145ceef, 0x7d4129bf, 0x5120fcc7, 0x352acfa0, 0x9edb2f9e,
-       0xa59ea32f, 0x376889f7, 0x6d453ff1, 0x6c37ad22, 0x1c3fc5bd, 0x136eede0,
-       0x5a2f587d, 0xa45f937f, 0xe5db8ef5, 0xf005c660, 0x1c9e5ff9, 0xaf3a1cd5,
-       0x935172f0, 0x418764f9, 0xbe3c388e, 0x1aa23602, 0x26476be0, 0x9fac1098,
-       0xc60a3d04, 0x7a0e3b2f, 0x6653cb14, 0x009c8f6e, 0x50e4cb3d, 0xf6e5a9b9,
-       0x93bd8f88, 0x5bbaf303, 0xc4a4ff83, 0xb9727df1, 0x9ffc47e0, 0x4654b75b,
-       0x09a8b4fd, 0x7910e98c, 0xd4e8d2af, 0x6fe2dbbb, 0x4e9f0816, 0x243dcfc4,
-       0x97fd8c8a, 0xde2fd766, 0xddf0c830, 0x486fe63c, 0xd70bf682, 0xc2a21fce,
-       0xc7307ffc, 0x53ed1632, 0x13548490, 0x354b31c9, 0xa7316f81, 0x15399d75,
-       0x31ccf72a, 0xb9faec1b, 0x07fd635e, 0xb77ac625, 0xa1366fd9, 0x6044b1bd,
-       0xfbdfa19b, 0xf5ef8daa, 0x71093671, 0x78daae9c, 0x78722777, 0x2c72c3ef,
-       0xae89563e, 0x5bfcabf7, 0x87aa9e1d, 0xeb402ccd, 0x43024765, 0xc812fa3a,
-       0x7caaf35e, 0xdef0e1de, 0x3dbab66f, 0x3ffdcf00, 0xe19f0912, 0x1ebc77f0,
-       0x1d8136ed, 0x4be1b1d7, 0xe1b7da33, 0xff8709f3, 0xf3e11581, 0xf7d46551,
-       0xcfe17df3, 0xf3849f39, 0xfe5b5553, 0xed2113a0, 0x3fbe5a2a, 0x7f0844e8,
-       0x619b6d95, 0xcff12fa8, 0xbc5fb435, 0xfde1be61, 0x8625a6a2, 0x971b0bf7,
-       0x7df3ea1a, 0x7fb4323f, 0xe1ad4560, 0x8fd57dfd, 0xa0ffde18, 0x3ea19d64,
-       0xd0d1bbd7, 0x9b399efe, 0xaf4def0d, 0xe513bc8f, 0x915deea8, 0x5671bae1,
-       0xda38f939, 0xc9156783, 0xb4f8f485, 0xe0e48926, 0xca938d74, 0x5671b6ee,
-       0xc583d72f, 0x5e9c4c0c, 0x71af9ce1, 0x4665ea32, 0xc2aff3fa, 0xea0f9f05,
-       0x849c137f, 0xcc83713f, 0x02c2c002, 0xe3e3eb8b, 0x7de4315e, 0x6fde65c7,
-       0xd71f4100, 0x11d8bdff, 0xf35579f9, 0x046aa1fc, 0xb72821ff, 0xb9d7152c,
-       0x0f7d6d1e, 0x302e5f7f, 0xc673e84f, 0xd79c9256, 0xb94ceb69, 0xf941f5cc,
-       0xf402e4ce, 0x40e5cbbf, 0xc6a5f576, 0xa2a4016b, 0x3ceb449e, 0xa401f901,
-       0x592fc0c0, 0xdceef906, 0x955c1227, 0xaf4013a8, 0xc19e63ae, 0x8133d426,
-       0x8d77e903, 0x49dc3842, 0xa04b6f54, 0x66b3bd75, 0x1213a0fa, 0xe543c7d2,
-       0xa87335a7, 0xa5e3593c, 0x094d44f2, 0xaa6bc795, 0x59a8eca9, 0x35c7e541,
-       0xaa3f2a3e, 0xcff2a469, 0x1e544d35, 0xe540d9ad, 0x2a7e357b, 0x54dc6bbb,
-       0xba2bf9f6, 0xecd78dfe, 0x80afcd55, 0x67ea8795, 0x43d4b9b4, 0x739276db,
-       0xf9ca1257, 0x365ce519, 0x8e67e3da, 0x31996382, 0xf9c2be30, 0xba3a606d,
-       0xf6295ec9, 0xf5c7fd03, 0xe28b6f7f, 0xd899b274, 0xd9a67074, 0xe17fc323,
-       0x7543905a, 0x16065909, 0x7b0cd724, 0xed617e84, 0x8e5d7a43, 0x9bddcc4e,
-       0x71e8133b, 0xe5bf99f2, 0xda75bf61, 0x407517fa, 0x059875a4, 0xbd21779e,
-       0xeb46f042, 0x9aabef5a, 0xfe0cbfbe, 0xd7f0faba, 0xfbfe8e9e, 0xfea54141,
-       0x985ab4cf, 0x13dc7884, 0x67e607ed, 0xef3f0e67, 0x965c7940, 0x444f5264,
-       0x565e83c0, 0x4aa864b4, 0x66d3fae8, 0x12699fac, 0x7ad0b7a6, 0x35998cec,
-       0x554af90a, 0xfa430c4f, 0xf7a95127, 0x56492cb3, 0x9ebc804f, 0xc31596de,
-       0x5f3f6fd7, 0x12c7b707, 0x485f82bf, 0xf0deffed, 0x0e8fd40c, 0xecad630f,
-       0x03ea2b13, 0xedf59778, 0xfd2672fd, 0x6c57e295, 0xda1cf98f, 0x7bf8160b,
-       0x1207e291, 0xab7ef5d5, 0x659f445a, 0x6edf3e34, 0x73be0f18, 0xc5f73eea,
-       0xadf14bcc, 0xc4864ec4, 0xf169d611, 0x366db2c6, 0xc4aeb8d5, 0x6d55ea1a,
-       0x9d61aac9, 0xfc807fc1, 0x42416ab3, 0xb8d729be, 0x1a5247a8, 0xdcaf8005,
-       0xab7ea4e4, 0xc2aede04, 0xe17b21da, 0xa72b5751, 0x9df040db, 0x94ec39ae,
-       0xac4bde40, 0x7c0201e0, 0xa7232d25, 0x6aeb9ea2, 0x7b444bad, 0xf33c4cb0,
-       0xf7c22790, 0x8d024d3b, 0xee6fc4b7, 0x1aa3ae35, 0x57e8307f, 0x167e4e7f,
-       0xd4864e53, 0xcedc4d3b, 0x80f7ef0e, 0xf0e5efd6, 0x48fdb953, 0xfece8de1,
-       0xfb6caa78, 0x1c92f642, 0x82f2ffc1, 0x57f1d278, 0x401cf26e, 0xedba5a7d,
-       0x9fa3d918, 0x0fd97d9a, 0xf53f425f, 0x44929f9f, 0x5e7d5271, 0x6129303e,
-       0x7c5a059c, 0x9ef7f817, 0xfd3d610f, 0x6ccddfec, 0x2ec7c00d, 0x6f782b40,
-       0x13335fd6, 0xa17d4133, 0x5ad05b56, 0xcfdd7146, 0x2a8edc4c, 0xd1071e62,
-       0xa1e53581, 0x4cc5d91d, 0x5d4f11d3, 0xb8c76dec, 0x329c3a10, 0x1667a4c9,
-       0x18ed1a36, 0xf50d7fb0, 0xf58c1bc5, 0x11333662, 0x7af149f5, 0x340bf333,
-       0xf7fbc33f, 0x7fe12a4d, 0x855eab31, 0xf9a4aaeb, 0x26540b23, 0x157c02a5,
-       0x6f3679bf, 0x4c5fc63e, 0xe3d10fdc, 0x38e24b23, 0x7ef1a5fc, 0x3fef0dd9,
-       0xf7771d69, 0x8b06488d, 0x89c6157f, 0x6d730c58, 0xfbf1fd65, 0x870fe16d,
-       0xfbaf5f57, 0x383469c5, 0xdb826dc4, 0x2f7f811f, 0xeba67c68, 0xd5445beb,
-       0x8ddc17e0, 0x21bf10f5, 0xb2e2d446, 0xee911322, 0x67d5aa5d, 0x14f7a18a,
-       0xb4edf7b7, 0xde80eab8, 0x0679373f, 0x4ec81389, 0xed2165c8, 0xd2f26e7e,
-       0xade14ef3, 0x995bb462, 0x3b45c814, 0xe218d614, 0x07e35953, 0x8b91ca31,
-       0x833b66f1, 0x6fe81475, 0x9fa0f841, 0xdb92f655, 0xbbc62e58, 0xbfa1de41,
-       0x87851cc7, 0x94dba805, 0x59fd8656, 0x7cf18c92, 0xaf58d39b, 0x1d207fc2,
-       0x3f8a3046, 0xc2908f45, 0xa86018f0, 0xe32eed0f, 0x84e851f3, 0x201fdd91,
-       0x8b10763e, 0x02556943, 0x26cf8c22, 0xfe7d9d49, 0x7bfa2656, 0x2f8a7e1c,
-       0x2ae5fb40, 0xc5a95f6f, 0x507f97cf, 0x12ee3830, 0x3ceaa8fa, 0x21419068,
-       0x7fbe3d75, 0x71fe625e, 0x3a6f41df, 0xd10d5561, 0xde4d739b, 0xd40f4869,
-       0x009f0893, 0x760d78e3, 0x2a1a9a60, 0xf8c20be7, 0x88e1aae3, 0x5dfd0667,
-       0x2ddef26e, 0xe387f426, 0xea4ffbaa, 0x4882ffd7, 0xfeeabcf3, 0xbfebf587,
-       0x15ff5232, 0x977979bf, 0xf4a9f80f, 0x803a4f57, 0x5267d999, 0xe80ba253,
-       0xc1b5be5e, 0xa9f97281, 0x5d2073e4, 0xd38bf33f, 0x16e7c923, 0xb74f9751,
-       0xff11e422, 0x7e9d1f10, 0xd03bd1e9, 0xd5b73aae, 0x607c52ac, 0x0160259b,
-       0x5d6caca6, 0x9b63e5c2, 0xafaf18e5, 0xb3f902fe, 0x2fa8cdaa, 0x32785f4a,
-       0x40cde311, 0x0e7fcd49, 0xb9507f90, 0x68852fe5, 0x5eb15577, 0xdfe17bd2,
-       0xe3e7f8e1, 0x2f981ec8, 0xaf7ff4c7, 0x6955f3ef, 0x7d6aa978, 0x84910bf4,
-       0xcdfc83a5, 0x9a25f6f0, 0x68a4ffbd, 0xdf38a78f, 0xf9113644, 0xf307c74c,
-       0xeebf7b73, 0x8f73a7c5, 0x5b9d3c01, 0xe421ddfe, 0xd727f284, 0x165a677b,
-       0xe735fcfe, 0x0dd4f2c0, 0xaed4317a, 0x6767d7d6, 0xeca7e69b, 0x39b965e1,
-       0xb03f40e0, 0xe5d9b37c, 0xfcbeba43, 0xc19e2ffc, 0x1607ccb8, 0xbfe870d7,
-       0xef83e5ec, 0xb2f500dd, 0xdbf8e61d, 0x211434f8, 0x2a974831, 0x6c62bbf8,
-       0xbfa50e90, 0x473b283e, 0x8e3fe7f1, 0x6ca3d20b, 0x8d993ec7, 0x298f8fea,
-       0x0ee4fb2d, 0x5a5d0225, 0x3fa2158e, 0x57e2f751, 0xcfafea32, 0xe0d8175e,
-       0xdcf8088c, 0x62ec907c, 0x51d113c4, 0xdd1f53a3, 0x0157dac2, 0xeabf505d,
-       0xff7f0a74, 0xc7fe9a2f, 0xc4399cfe, 0x86bcafcf, 0xb67f28fb, 0x25fe70b8,
-       0xc0e83caf, 0xaa929c79, 0xdb3f5f39, 0x7186e890, 0x44becc4b, 0xbcfe4a95,
-       0x121fb9e4, 0xf23e2dbf, 0x7f8a44c3, 0x89b27730, 0x325f056c, 0xa6d16fce,
-       0x62bf34d9, 0x2bbe25e6, 0xe0f45679, 0x8959e0fe, 0x4111df4d, 0xae24522e,
-       0x5b354f8f, 0xa7654d70, 0x7dc0e170, 0xff45b785, 0x2dff8a56, 0x0fcaf8a5,
-       0xb620fdf5, 0xad67ea8c, 0x885f4e9c, 0xac1abefa, 0xbafca13c, 0xd23b7565,
-       0xf710f4e7, 0x571b8c60, 0xe1a7c931, 0xfd08b843, 0x0da6478a, 0x4e61f4e6,
-       0x0efb4f29, 0x7c14fdf4, 0xcddbed8e, 0xe1ae5b6e, 0x2331763b, 0x6d72fe38,
-       0x0a3b807c, 0x8953d5ed, 0x9845ff60, 0xafa4a15f, 0x85576037, 0x7c8857f0,
-       0xf2df7973, 0x5d6f9708, 0xa633fdde, 0xbebffbe3, 0xbf07e5c3, 0xe0057b43,
-       0xf7a60c0a, 0xa40966fb, 0x102c2c0f, 0x98b7ae49, 0xbe36b935, 0xe004f9d7,
-       0xeddd7096, 0x3fec17e3, 0x764ff08e, 0xf87af16c, 0x565f442e, 0xfe8e78e1,
-       0xbb72e9fd, 0x04ff9358, 0x6cff28c9, 0x81fb9713, 0x8f1f09fd, 0xbffd984b,
-       0x15e50678, 0xaff713e4, 0x7b365fcb, 0x6f9fde70, 0xbddef03f, 0xb79fa720,
-       0xd46a72e8, 0x5a72e19f, 0x8b0273b2, 0x639fa724, 0x3924421a, 0xe511e785,
-       0x3e20e954, 0x4fe947fe, 0x85377f1d, 0x87d74fe1, 0x5c31e103, 0x7459fe1f,
-       0xf087d446, 0xd7961de7, 0xbe74ff9f, 0xf4adf9d3, 0x29431597, 0xa5f3a63e,
-       0x7c7d77ce, 0xbf5df3a9, 0x7f01a378, 0x182defe1, 0x3cb80183, 0x4714cdbb,
-       0xf7c3df28, 0x43bbe17f, 0x4f09e3a9, 0x58c65a6e, 0xf8d4a1d3, 0xac3fbad0,
-       0xded612de, 0x84f7561d, 0xd586f7b5, 0xcbed0dab, 0x3cc80edb, 0x686025af,
-       0x8678ae27, 0x1228327d, 0x5fb9fabf, 0xec85fada, 0x7a50be43, 0x4af37be9,
-       0x3c63b3e6, 0xf148af7c, 0xf1c01e91, 0x67a7182a, 0xf31f867b, 0x3c6c1a24,
-       0xf6a3d4ee, 0x6c5ed03a, 0xdef5e588, 0xea157904, 0xaf79fd3d, 0x7af5c78d,
-       0xd88ebd3c, 0xd8edfb10, 0x76f4911e, 0x8f4d9f87, 0x8ac267e4, 0xc1d47242,
-       0xe3cf7a06, 0x2544d3fd, 0x5fc6057d, 0x8617449a, 0xef6a8a74, 0x419e6071,
-       0x3bac9ecf, 0x45f3c0e7, 0x8db48a6f, 0x7b7683d8, 0x2dc7920c, 0x77f88725,
-       0x53df329f, 0xbf7e3193, 0x4579fb87, 0x11ecc36b, 0xa9f896b6, 0xa32e5958,
-       0xecbf053e, 0x82ff71b8, 0xd6a945cb, 0xe326c95f, 0xdc7bfd7b, 0xbdfb45c1,
-       0xbdf18b74, 0x34078b57, 0x863272eb, 0x71fcd18d, 0xf4d28f1e, 0xe73134f2,
-       0x8f4039ce, 0xc322c39e, 0x7b33fbfd, 0x99c7a244, 0x9ebf7ced, 0x23d7f6e2,
-       0x3e92f77f, 0x89d4f1d4, 0xac0f24f2, 0xfd5f3aaf, 0x9187bcaf, 0x987d766f,
-       0x3b2833fb, 0xfd907d77, 0xe6ffac5b, 0x590ff4fd, 0x5e53f6ff, 0x493ed1b7,
-       0xe276ebcf, 0x7fbd9ef7, 0xeb187f4c, 0x9f142dbb, 0xabfd79ee, 0x9e9fe45c,
-       0xd4129695, 0x80433d77, 0xec1f68fe, 0x83b72afd, 0xa27ad7d6, 0x99251fdb,
-       0xfe7b47db, 0x8f10b1f6, 0xed0acc25, 0x49a3d786, 0xb35eaa9e, 0x67ad3c51,
-       0xa17957ef, 0x9d77ff76, 0x7fb6a54f, 0x736763d9, 0xb17c2276, 0xeaa7df7c,
-       0x5f3fd7b7, 0xad17f98b, 0xf085e4fb, 0xbeefca7e, 0xda3d45c9, 0x43db93b3,
-       0xe78ee6dd, 0x68ee7f70, 0x6695dcfd, 0x0a3773c0, 0x9bac0a55, 0xa014cf0d,
-       0xcbc7f4dc, 0xbc271437, 0xfcf47c52, 0xc10f835f, 0xdd9df5cd, 0xde70156f,
-       0x21fc7f5f, 0x2dd785ea, 0x7cfa97c4, 0x25a96f3f, 0xf372e57b, 0x9c799876,
-       0x799dffe4, 0x992b810b, 0x3ff328f7, 0x2d7fbd37, 0xe12e8939, 0xcf9fd072,
-       0xf5443ef7, 0x822eed97, 0xfdf90af7, 0xf9f27ff6, 0xefba6b7f, 0x2e3bba04,
-       0x7ff2ef3f, 0x4c0f79f2, 0xd7ef37f7, 0x7e62aee8, 0xbeefd54b, 0xadbef821,
-       0x4ffb5b9e, 0xcd03ef2e, 0xd7ebb75f, 0x994d5c98, 0xaf439f18, 0xc569d601,
-       0xc311b33e, 0xcc466b85, 0x14ced154, 0xf52bf6c3, 0xfb99af72, 0x5bee224d,
-       0x086f9c62, 0xcd31f38f, 0x3d2da28f, 0x8a525a18, 0x94958ec9, 0x96bedc55,
-       0xc06eed5c, 0x176b9acb, 0x887728b8, 0xc5ea3d8d, 0x1764da7a, 0xfcc3afc5,
-       0xb9817ac9, 0xa56fb005, 0x8c396f6b, 0x84798dfe, 0xa5c96029, 0xab9618f2,
-       0x59a4b8b5, 0x8f7e0d95, 0xdbac6392, 0x45bac69c, 0x38cacfeb, 0xe624d6fc,
-       0x38b4f8c7, 0x798abf72, 0x8918e26d, 0xb1b75009, 0x17fa1f26, 0xf7e32496,
-       0x1ec0311b, 0x5abdcf12, 0xe1f6f63c, 0x1bbb6c71, 0x44d238f1, 0x2e4a6b71,
-       0xfcb8bc25, 0x8d9e786b, 0x55d788d5, 0x094f88ed, 0x7f6e5ffd, 0x34ccdf91,
-       0xbad2597f, 0xdc984690, 0xcd3b6336, 0x9d2cbe4f, 0xcbd25d38, 0x332d3a35,
-       0x43a745d0, 0xe818fa04, 0xdbf9e3a2, 0x2e9c27d2, 0x6fdff8e1, 0x07fe1276,
-       0x974e97a2, 0x50cdc534, 0xbf9acd5e, 0x49fd1530, 0x1879a7ac, 0xfe6b33ed,
-       0x66ef1482, 0xea93a43e, 0xf42f4862, 0xb7e002db, 0xf3fb7efd, 0x7aea2714,
-       0x081dd8e9, 0x456fd94f, 0x75fc0566, 0x00b3b76f, 0x65f92f7e, 0x5b4b43f4,
-       0x33fb8a45, 0x57779029, 0x6eafbec8, 0xcafd97f7, 0xdd29f34e, 0x06dff169,
-       0xfaee97df, 0xb0ec9724, 0xd7e4bd95, 0x38125ef8, 0xb91d7ddd, 0x2a5bafb8,
-       0x9c23ff71, 0x9e65625f, 0x3bb9d027, 0x6dc60e7a, 0xdf3c6d84, 0x1ee5b4b6,
-       0x7f90c5b3, 0x91dbd666, 0x28bdf05e, 0xc213be50, 0xa9e79a17, 0x2f9d1dfb,
-       0x36be1c0a, 0x76f31fb3, 0xe8edb74b, 0xe953f8c6, 0xc30b8b51, 0xbedb55d2,
-       0x298dfda0, 0xd1d97abf, 0x68b6fe41, 0xf3f43f88, 0xc489b7fb, 0x15ad951f,
-       0x9d4087e4, 0x25b2a2f8, 0x72ebfc72, 0xafd969fe, 0x01f2eef6, 0xfd7ecb0a,
-       0x5be30382, 0x3ab7dba7, 0x76dfffc8, 0x3f5bb8e9, 0x91e5bf3f, 0xa7f9fa4b,
-       0xbfe01ff1, 0xc58720dc, 0x220db649, 0xcbe0047f, 0xadef948b, 0xcbd95bf3,
-       0x38c39f67, 0xcfcee774, 0xcb78439f, 0xe7cbfbff, 0xaf609fd0, 0x88add4db,
-       0xa5de9797, 0xddfe9e38, 0x9dc7992c, 0x817c5fbb, 0x1fdd9fe2, 0x7f01df80,
-       0x4a9ef7ba, 0x7bb27f47, 0x1889d7c7, 0x77be592f, 0xef9c60da, 0x0ca757f2,
-       0x88f41166, 0xfadf225e, 0x1afe20af, 0xad03af4e, 0xe9efc807, 0xdfa37a02,
-       0x69b717d9, 0x3071e0a9, 0xd9af16a7, 0xddce391e, 0x7ad33e2f, 0x8d379dd7,
-       0x72ecd2c7, 0xd3882bb2, 0x1c7403bc, 0xdbf4057d, 0x7fe688fe, 0x175fa646,
-       0xb4e803fe, 0x677e8c2c, 0xfcfd175b, 0x3ad77c19, 0x4d38c068, 0xa6f00ae0,
-       0x27bfd1c7, 0xa3227fbb, 0x25fced7c, 0x6e90c5c5, 0xbb44c1b7, 0x8e9b3e5f,
-       0x9a9f0ffb, 0xe7e7ef7b, 0xc62a2c32, 0xbef74a1b, 0xfdd3f24f, 0x538a11ea,
-       0xdd9e2d33, 0xf0fefacd, 0x5396a3f8, 0xcec5b559, 0xfe1a3be3, 0x74e3fe31,
-       0xce2d73d0, 0x8f58f9c3, 0xf7140cff, 0xde799569, 0xafdf1e88, 0x16a1f2d8,
-       0x4bd2094f, 0x3a748498, 0x08fdc976, 0xe22a0f1d, 0x1c686261, 0xad7c7233,
-       0xd1adde2f, 0xf187e90b, 0x2538becb, 0x6e30d3d4, 0x67de17e5, 0xf741f411,
-       0xecff1e66, 0xa3ce4736, 0xbf9ae3d2, 0xff53970a, 0x2f33c595, 0xc5b7ff07,
-       0x52765f8f, 0xea78e1bf, 0x8f5910bc, 0x75f32dbf, 0xc5f7aaff, 0xbe4305ca,
-       0x7bc9b941, 0xa2b1f904, 0xcfcc98f5, 0x52f3f0a5, 0xb53b7cfa, 0x97ced1bc,
-       0xad778a44, 0x7a40396a, 0xe85f5c3c, 0xf0e1a6fb, 0xade0d09e, 0x44ebe36c,
-       0x5fbb4ee7, 0xf73a7e81, 0xae7e26ef, 0xe28c7edc, 0xfdb6876d, 0x5908ee5a,
-       0xf09d7157, 0xf9dfc087, 0x1e5cbeca, 0xec79e5b7, 0xd19ce3e1, 0x9ed561f4,
-       0x6d54e3c8, 0x4e30c2ff, 0xe645af99, 0xc7a5fdeb, 0xefb92d3b, 0xb74efec1,
-       0x79e6199b, 0xa7116e9e, 0xf5173a47, 0xea6eb6ae, 0xbd707ee7, 0x23fd7ca4,
-       0xf8cc5cfc, 0x1f28a3b7, 0xe991f97e, 0x63c4c61f, 0xfe878409, 0x9f396b5a,
-       0x9dc4feb6, 0x3d6ef48a, 0xeb88af72, 0x6fc42ed4, 0xf79f9d88, 0x3b14f54e,
-       0x8fbc85e8, 0x5d91e33c, 0xc4cdf5c3, 0xfc0326a3, 0x5c60ce30, 0x1fa1ea07,
-       0xf982a73c, 0xe88f086e, 0xf08e9c28, 0xb549aa88, 0x61e7fd09, 0x5e743c56,
-       0xacd7ef40, 0xb003cf1a, 0xd89ce30b, 0x1e4cd24f, 0x8bbe4c47, 0x3cfd3e97,
-       0xbf94714e, 0xa059e60e, 0xf02cd378, 0x7d7d927d, 0xe78641c6, 0xde5126bf,
-       0x78c59676, 0x554bac6e, 0xdfd0267c, 0x596ce4cf, 0xf949d937, 0x4258d707,
-       0x20580ff3, 0x6f51f917, 0x587defd7, 0x7e1a427e, 0x1a88fd02, 0x7e5a597c,
-       0x21d610c2, 0xc9bd7da0, 0x0e27cfce, 0xf84de255, 0xbd9af3fd, 0xec3f9fa9,
-       0xec315e77, 0xcee5e29c, 0xc94fc627, 0x05d43a5f, 0xcf7ab4fc, 0x8f5fcc14,
-       0x477f27bf, 0x12798aaa, 0xe7829e7f, 0xc85fe257, 0xf50c931f, 0x9c1fab13,
-       0xc8fff54a, 0xf50e931f, 0x8dff1a6f, 0xca04cbd7, 0x3d582d57, 0xebf22a7a,
-       0x2cf9cb55, 0xce5188c0, 0x75bc40ef, 0x7bba3e79, 0x1ff31391, 0x5f8e657a,
-       0x4376c1e6, 0xa5bc7126, 0x40ed1f29, 0x75350d3c, 0xfe7f22d4, 0xb157ef7c,
-       0x4c9c17a8, 0xaca8fc25, 0xc1fa455e, 0x2f1749a3, 0x9e174791, 0x93eba64f,
-       0x01f78acd, 0xf991e384, 0xe05ce823, 0xad332533, 0x98cf5f3c, 0x78d4c0c7,
-       0x469167a2, 0x1ad3844f, 0x58bf8f92, 0x5cfcc9f4, 0xafa6934c, 0x9e38aaa6,
-       0x2f172be0, 0xe1edf75e, 0x4be7507a, 0xc8695ced, 0x1087c679, 0x7de29f5e,
-       0xffd092c8, 0x161de33c, 0x9f7c0acf, 0x1d3e7c5c, 0x9f3f5bf9, 0x91ce7e18,
-       0x48a6bd49, 0x76b35ff6, 0x782071ce, 0x2aef563d, 0x77f3371c, 0x41879dce,
-       0xc91746be, 0x1ccd4c2e, 0x827c62bd, 0x5215cfc4, 0x4695439e, 0x971324bf,
-       0xa310f643, 0x8b1ed67d, 0xb9bf46e0, 0xf49541e7, 0x6dd15a77, 0x44f557e4,
-       0x3e60b467, 0xfcc3cf50, 0x4c66295c, 0xd90d1ca3, 0xbf401313, 0x5ce0e40f,
-       0x339c1c98, 0x71c673ae, 0xdb3a2e7b, 0x553fa83a, 0xb00c0feb, 0xe0b9e0c4,
-       0xe5eb911e, 0xc1271a9e, 0xf6f98431, 0xa57efae1, 0x18b56de3, 0xde02fdcf,
-       0xe8bc405f, 0xc0e5ff78, 0xa3457bf4, 0xe8912bdf, 0x74fe7e17, 0x6bfbc5be,
-       0xf8aa7f6c, 0x15742ad0, 0x869dcfc3, 0x6a4ab5d3, 0x78ae88da, 0x682f9ee2,
-       0x36e9d19d, 0x412b857a, 0xe3a0641a, 0xe8efd8eb, 0x10985f3d, 0x4f7e9d5e,
-       0xfdef900f, 0xcf5f0b07, 0x9c4bc7c2, 0x8de291d3, 0x1060feb4, 0xcf58212e,
-       0xf8d1e6b5, 0xde3c4d83, 0x10bdbfd3, 0x7fd03e71, 0x30f2a5e6, 0x2fde5573,
-       0x50fdffe0, 0xf110ffbe, 0xfe22223f, 0x03bc463f, 0xf6c63ffe, 0x4fff8057,
-       0xdd7f852e, 0xf4d32fae, 0x2bee1942, 0xc5fcff01, 0x13313339, 0x15142dc6,
-       0x5b25ffe2, 0xd21f6d45, 0x62725b7d, 0xb92c8f50, 0x199f7abe, 0xb3c970f8,
-       0x9169f102, 0x73fd5e76, 0x784b5ced, 0x1cf15f5e, 0xcbc9e91f, 0x49f9f7e7,
-       0x336d950f, 0xe410bf3e, 0xc7ca74db, 0x93f3f1f5, 0xe11726a2, 0x68a33ff8,
-       0xd628a2fa, 0x0e9c2ed0, 0x864daa43, 0x29e4f03c, 0x9f90fd7d, 0xbe726497,
-       0x3fb5f14f, 0x07c61998, 0xf8fc52dc, 0xbc63e200, 0xcdfb1530, 0xef56e4d7,
-       0xe30ae86f, 0x33e19f3a, 0x6acbfb9e, 0x1bfb9e34, 0x686294de, 0x4c86cd7f,
-       0xfe91fbc3, 0xafef0d6b, 0x50d636db, 0x8372d51f, 0xb6e8fda1, 0x4c7d4302,
-       0xfb4316e0, 0x1a678771, 0xefda13ea, 0x789fb435, 0xfde18174, 0x86a51df5,
-       0xba7e37f7, 0xa9bf50cc, 0xed0d5ff7, 0x5eb88b03, 0x94935fdc, 0x740ae786,
-       0x2a5fecbc, 0xbe7c549b, 0xe6a4db34, 0x744f3e86, 0xccb1733b, 0x357fa373,
-       0xb14cbc90, 0xae85a726, 0x6cccf9cf, 0xac536bd0, 0x55817ac6, 0xe07497e3,
-       0xcdfe2017, 0xa55ca356, 0x026bcf56, 0x2ca59bb3, 0xd2f94619, 0x58b75f20,
-       0xc5bb7eb9, 0xedfa657a, 0xaa7f6c4e, 0xece74032, 0x444be5c3, 0xd2a2caf9,
-       0xcca9fb47, 0x1b96f945, 0x4d3e466d, 0xccaf401a, 0xc3cf1ab3, 0x9b61ea8b,
-       0xfd139064, 0xd0a8f9f9, 0xdbe2c2e7, 0xa0676f28, 0x05a4e57e, 0x7d016eb7,
-       0xa97b2729, 0x9aaf9fd4, 0x97988a63, 0x3bf590f7, 0xfa1b49fa, 0x210f4fd9,
-       0xde92bb7e, 0xccf30a7e, 0x92f5e72a, 0x316c94bf, 0x775825e2, 0x5479e60d,
-       0x508e7e4e, 0x54dcffe5, 0xae2b78d3, 0x173cfaf7, 0x1133307d, 0x06d203f3,
-       0xd55e9ff0, 0x4d5cf1e6, 0xc345adc9, 0x14d53fb0, 0x7a45bf7a, 0xfd10aaa0,
-       0x1e5aa198, 0xc8a653f4, 0xd53f4af9, 0x0a8c19fa, 0x5503ed14, 0xaba0fb21,
-       0x048723f8, 0x9377f8f3, 0x17c8a7f7, 0xe7b7460b, 0x6ecb73f1, 0xabb24cd7,
-       0xd75f8254, 0xe78ae943, 0xe92bd429, 0x66731249, 0xf06787f4, 0x06636f3c,
-       0x338fafbc, 0xf7aa14b9, 0xe59e380a, 0x820d8cc7, 0x5bffeaf1, 0xf7eaf824,
-       0x3cf94f5f, 0xe29aa516, 0x993cfaa7, 0xc7afdfb6, 0xcd26cf8b, 0xd63c418a,
-       0x6e77db5f, 0xacfd6187, 0x7ec76de2, 0xd337aecf, 0x8205f5b8, 0x6f3ebde1,
-       0x741dc369, 0xe15d2b1e, 0x79862ef3, 0x3496dc23, 0x73fd570e, 0xb8234b02,
-       0x43d2f7fe, 0x8aecbfe8, 0x0dbc6176, 0xe889b1f0, 0x6738ceed, 0xf30f27d2,
-       0x34a418aa, 0x25fb21af, 0x96fa1fb2, 0x4cdbaf95, 0xf688959d, 0x4635f254,
-       0x66f5c5b8, 0xc51707f2, 0xe0af942a, 0xd1a159af, 0x55ef38d5, 0x9cef3349,
-       0xbdd4f00b, 0xfd4c3223, 0x2d347671, 0x15df043d, 0xfcbb46b7, 0xef78fece,
-       0x01387272, 0x6e10b7ee, 0xcd214371, 0xdc21da9b, 0x33d8173f, 0xde77c819,
-       0x14ff44e9, 0x977dc313, 0xd3fff870, 0xefc4e3ca, 0x879a5558, 0xeb7c549c,
-       0x16584196, 0xb51ddc91, 0x7fceb80e, 0xfcebe568, 0xeb08d687, 0xfdeee5fc,
-       0x7ed39f28, 0x6dd14b08, 0xeadaecd2, 0x197b50ec, 0xec49d6f4, 0x318baf57,
-       0x7ec5ce3f, 0x3ccbb607, 0x9719d94d, 0x1ed0cbb7, 0xedd3fe43, 0x8d5abfb1,
-       0x9e886476, 0xb3d34afd, 0x9ea15d5f, 0x4eed80bd, 0x68881bdd, 0x91c824c7,
-       0x1b38dcf5, 0x2a957fc7, 0x1be3ca33, 0x6d9f9e20, 0x0e1f6c8b, 0xce5d0eb4,
-       0xd68cc8cf, 0xefd754f9, 0xc560dfdc, 0x9c2fed32, 0x247fe0d9, 0xe329f71b,
-       0xedde5187, 0xaea4fd40, 0xf10d83f8, 0x886de3ab, 0xc04f88cd, 0xf9c6d3a3,
-       0x648b69c4, 0x1e03960f, 0x0e3c064d, 0xd903f6c7, 0xdfad5783, 0x6ee78c4b,
-       0x837c35ba, 0xbc71979e, 0xce3ebbae, 0xe545b8c3, 0xe7a473ec, 0x399c7aaf,
-       0xf74475c6, 0x011c61bf, 0xd77ddfe7, 0xb7716b7f, 0xd5178a0e, 0x0c4d7abd,
-       0x0a2aa7c6, 0x9586f4fa, 0xa49985db, 0x5976bb07, 0x576708dc, 0xece7cf1c,
-       0x10f135da, 0xaf3e39c6, 0x85299c39, 0xaf5d2dd8, 0x4333c91c, 0x8f3b5d7f,
-       0x209449e4, 0xd17e27e7, 0xfc5c57df, 0x128f3ccf, 0xc7d0273c, 0x0ebe566f,
-       0xf8f1b7ad, 0xc798d3c9, 0xf7b19a36, 0xfaf963a3, 0x1c7a6891, 0xe3bf479f,
-       0x7f7ea1f3, 0xc7e57054, 0xdd262b00, 0xab664c55, 0x00a68de5, 0x6e0a8f96,
-       0xbe55e311, 0x4d3cfc91, 0x911b1652, 0x4728fd01, 0x8e0803db, 0x8dd7a3a3,
-       0xa7ea29db, 0x0b2c3eea, 0xc402ef14, 0x2baf5c7b, 0x37fc7d09, 0xa1b38d87,
-       0xe14d215f, 0x7e77b77a, 0x29ef1f94, 0x8fb9344a, 0x6767aa80, 0xc58c2f0e,
-       0xe68b7ff7, 0xd258f2f2, 0x8e5c2689, 0x38a03970, 0x5a669bd4, 0x710d96df,
-       0xef822f27, 0xe7884d97, 0x9805e97e, 0x9639c87d, 0x0967e3c7, 0x00b90714,
-       0x14e78178, 0xb53e02fa, 0x3317cc4b, 0x89b0f416, 0x0bf055b9, 0xee4293ec,
-       0x68ffc1d9, 0x4d60fc76, 0x4d38f6ff, 0x45e0333e, 0xd5db1976, 0x5c0cee09,
-       0xfc81774f, 0xb4fa030d, 0x7ca958d5, 0x184d46ad, 0xa7b8f206, 0xafea8926,
-       0x0ca938d7, 0xe7a08cd4, 0x545c6bfb, 0xa7b5368f, 0x552c7ad3, 0xfe879baf,
-       0x0b12fdf5, 0xbc23b7bd, 0x8e567bc4, 0x97f9c887, 0x0093e62e, 0x3d352fae,
-       0x38d6fb52, 0xc6a7afe2, 0xfd31d400, 0x8ad9ffbf, 0x054d643f, 0xa3fa983d,
-       0x415359c3, 0x78129f8e, 0x181e02fe, 0x552e748e, 0xb7329f2f, 0xf0a9a2c4,
-       0x4df31b6b, 0xc8bcc24d, 0x8e153fde, 0xe8f6cc61, 0x1d4ea69f, 0xfdc7f309,
-       0xf6c614fe, 0xc7abdeda, 0xfba9d873, 0x818bab3f, 0xfc6dc8f9, 0x82899f3e,
-       0x7d4056a7, 0x0bf39b33, 0x98b53c93, 0x3773d9cf, 0xbefee273, 0x1b5ece3e,
-       0xdb7613b7, 0x51399db8, 0xe6c1fce0, 0x411e5aca, 0xbae86e6f, 0xef3ede11,
-       0x8f74d7c0, 0x2fb78c0f, 0x2f5e30d5, 0xfa0711c5, 0xd7ff752e, 0xe95c8eb4,
-       0x491f3d77, 0xc4847cfc, 0xe6ba2bf3, 0xfda66e26, 0xba1f6878, 0x4723da8f,
-       0xd2ded7b6, 0xed0681d6, 0x659fb7be, 0xa68372f0, 0xf5c62457, 0x05d16bff,
-       0x61b947bf, 0x5fda38de, 0x09e2d3aa, 0xe57a3a93, 0x2f7e76f9, 0x13d43e5c,
-       0x3c04784e, 0xd1a5d70f, 0x1e605533, 0x6048ffcc, 0x28028433, 0xdbcf36dd,
-       0xc2d24fd8, 0xd197be4d, 0x7165d85e, 0xe3a3d9a2, 0xd903eeab, 0x6121fa8a,
-       0x8fda31cf, 0x643a13aa, 0x8f97f7a4, 0xcb714d7c, 0x3275733a, 0x1b176dd5,
-       0xbdb4feb0, 0x99d6237a, 0x6fa9ebef, 0xd60c3f00, 0x13e3e1ce, 0x90bb63d4,
-       0x3b5829e8, 0x7e06ef57, 0xf5e665d8, 0x4b391f2f, 0x5ccbb1fc, 0xe18d9f3d,
-       0xef987af5, 0xaa6f58ae, 0x52905409, 0xe1fd65fb, 0xb7aeb09b, 0x77da92ff,
-       0x3f6e54db, 0xa40cde2a, 0x855d5f7f, 0x2ea43dba, 0xf2b33af1, 0xc55f9f52,
-       0x7f29af81, 0xe70f72b8, 0xce1bc447, 0xc3cdef13, 0x7a8ce975, 0xa4eb51d4,
-       0xd73673b8, 0x9f0301d7, 0xb753e7e9, 0x2a2cbc98, 0x085ecf44, 0xce42ff5b,
-       0x84a8b1d9, 0x38b4fe90, 0xbb033a76, 0x6f182b34, 0x2a2e64cd, 0x950f3187,
-       0xee96dbd9, 0xbb2db447, 0x7a89d5af, 0xfad73e2b, 0x68e89780, 0xd09e1ff4,
-       0xe8fae2f4, 0x01a31bfc, 0x7782f59e, 0xf17a888d, 0xe74ab365, 0xb2243a2f,
-       0x35b53b37, 0x5330ad8c, 0xf73b5cbd, 0x5de95e6d, 0xeef51233, 0x19ab9322,
-       0x4f0cb3d7, 0x2fbe19be, 0xaae19ddb, 0xe7bcc165, 0xc496d8b2, 0xef304ab1,
-       0xaa3faf59, 0xb546d9f1, 0xd2f786c9, 0x9543fbe8, 0x71d2eb6d, 0x7db3fb7f,
-       0xbd3c901f, 0x7c41951f, 0x447ad15c, 0xbf69daf6, 0x29f3c64c, 0xd6fad99f,
-       0xbef75a3f, 0x0b74196c, 0xeb2ff5ea, 0x79b8744d, 0x06f43d20, 0x38373fe8,
-       0xac6a87c8, 0x5dc2fe54, 0xde9a2d7d, 0xd3295105, 0xbfb4606c, 0x9156e990,
-       0xb9ade68f, 0x7c0ac1a6, 0x8eac82f4, 0x179b3e44, 0x5b7c4b95, 0xbe722b16,
-       0xdd07b964, 0x0dcfb692, 0x6535d4f5, 0x3c53bed3, 0x6f68c8be, 0x88526d54,
-       0xc80ec00f, 0xdca83e47, 0x7ee1f260, 0x4edac9a2, 0x45e77de7, 0x368fcd31,
-       0xaf5c4f9e, 0x6cdf3be9, 0xdcbddf1e, 0xf392c539, 0x511e7451, 0xe51fbfaf,
-       0x9128be24, 0x55ffb47c, 0xe741de72, 0x38fbbf18, 0xc879c356, 0x0428e3fe,
-       0x794e3e87, 0x57d21c70, 0x27ec1fe5, 0x6b8df83f, 0x4dd67b75, 0x3be5ac71,
-       0x9b05fcb4, 0xf3f6307b, 0x1827a6b4, 0x7780b1fa, 0xeeafa329, 0x1ccf4093,
-       0xf933d3ec, 0x90d3530d, 0x6cf7c1be, 0xb90f4192, 0xc1d3a025, 0xfbeead28,
-       0x51f6e47e, 0xf533ed61, 0xa986ccfa, 0xf3c3fb93, 0xb7582db4, 0x1be97b42,
-       0xe11d5f4b, 0xa1f573a3, 0xe3e9c5fd, 0xe9fd4bdf, 0xb51a97fc, 0xf80fa0f0,
-       0x27ac60ef, 0x7a7cf31f, 0xca273367, 0x8d4966e1, 0x21d08572, 0x37af8a35,
-       0x35afe725, 0xf7883fe0, 0x4ffd035c, 0xfb0d38d5, 0x968b8b8a, 0x549879d1,
-       0xc7cc5e9d, 0xca6d77cf, 0xfe27ec32, 0x16ae387f, 0x7000f70e, 0xc307fd4c,
-       0x5e30c231, 0x031c8e10, 0x870b577c, 0x7a6b3b18, 0x8f6bda06, 0x280f2898,
-       0x66b3e4d1, 0x6ff65da2, 0x0ca78a26, 0x880f3c67, 0xfb0de329, 0x2c7b99b4,
-       0x9efe31f3, 0xd2c3b129, 0xb7279458, 0xa9d716b3, 0x5f64489f, 0x39ab73c1,
-       0x726e870e, 0x204ffde3, 0x665fd495, 0x1f82b7b9, 0x82fbe6f2, 0x70d33efa,
-       0xbde3e595, 0xe7a39ba0, 0xfb8d18df, 0xaa1e7366, 0xe7983cc2, 0x352ff195,
-       0x92bc8330, 0x2c20d21d, 0xabe33b25, 0x701b87a8, 0x147076bf, 0xf6045bb7,
-       0xe4e1c370, 0xbcb9ef48, 0xf0f35b9e, 0x341b8c34, 0x8b5e74af, 0xcdb353fe,
-       0xf31fb2df, 0xe8531e76, 0x47acd6de, 0x50998dfd, 0x6899d717, 0xfd6314bd,
-       0xdf719adb, 0x176cc9fd, 0x68cd11da, 0x47fb60bf, 0x566bf214, 0xf0d338d5,
-       0x6d3a927e, 0x76b2d81d, 0xc1798ab2, 0x87148af5, 0x732addeb, 0x773c5cf5,
-       0x8dd1ee31, 0x51ebd60d, 0x071ab98f, 0x949ebca9, 0x339aeb8c, 0x7b463ad3,
-       0xae68c80f, 0xb1a8a675, 0x6ff0fac1, 0x3d20fac0, 0x9dc1b1b3, 0x2b2efd86,
-       0x883bfad5, 0xe2178a71, 0xef68bc34, 0xd2f4fb33, 0xcbcc06c6, 0xf5836b12,
-       0xaddf30a9, 0x353d72cf, 0xfb47fa18, 0xc3e3e60b, 0x877b057b, 0xca4e744b,
-       0x603b6306, 0x9991b67e, 0x0cd7dfb4, 0x2bef117a, 0xdfc91dee, 0xf234fbeb,
-       0xd3ed1370, 0x6f5c7b60, 0xbdbcc96c, 0x57df833c, 0x8a15db20, 0x307ac037,
-       0x149ef315, 0xf371ffa6, 0x8fb6a4b8, 0x01f78511, 0x75a3f084, 0xf73a32ed,
-       0xdc661d69, 0x8cd3979f, 0x16798975, 0xaa27bfa0, 0x4637e7c6, 0x8341f96b,
-       0x6dda0a58, 0x133e4dc3, 0xfcc91bb6, 0x02c75e54, 0x628d8f64, 0x8d1f541d,
-       0x1e16635e, 0x41d2725b, 0x2dcc71ab, 0x47aa38f2, 0x71313b44, 0xf2471eae,
-       0x74be414e, 0x61766b47, 0x7e3fef0a, 0xf7ca2cc6, 0xcdef69f5, 0x313d8633,
-       0x7eb5e60d, 0x50ceddc6, 0x2f5f4efb, 0x48adfb75, 0x68cbf983, 0xa0bda221,
-       0x364575db, 0xe5984f5e, 0xc6147a7e, 0x26cddb11, 0x58ad9fbc, 0x6f16638b,
-       0xbb444fc8, 0x5cdf68ac, 0x44d787b2, 0xd16cbb73, 0x77b219fa, 0x9af79e14,
-       0xfe7f764f, 0x183109ba, 0xb9b06fa7, 0xfe47ae62, 0xdfbf23fd, 0xb1ed4af5,
-       0x0a6bc4e6, 0xc19b1e50, 0x8ffbc6af, 0xcadd9a0e, 0x758be418, 0x6ccec8c3,
-       0xc7d6f28e, 0xffcdbf42, 0x41d574ea, 0xf73667fd, 0x4e3823f8, 0x8f7f1443,
-       0x6f2126f7, 0x3ff7edf6, 0x1e8c5c2f, 0xfdf0fc78, 0x91b183fe, 0x43bdf1ef,
-       0xfed05fc3, 0xd9dd90f0, 0xdcc4f660, 0xcbbdf087, 0xead679e7, 0x112f5189,
-       0x86b4fb67, 0xd67603e7, 0xe64058b8, 0xbd62d1f7, 0xdd3f68a4, 0x22d25caf,
-       0x097cdc50, 0x3a3d226b, 0xeed5894c, 0xc5e631a7, 0x4dbd1696, 0x795b4bed,
-       0x42d632fb, 0xe17a75ed, 0x8301b5bd, 0xf0ce3a1d, 0xdcd11dfd, 0x78acdd6f,
-       0xfffb431f, 0xc4d91991, 0x1167c04f, 0x07e22df3, 0x31b977d8, 0x371faf9a,
-       0xf6c8db62, 0xb863f128, 0xe05cb87d, 0xc207b3e7, 0x9379d553, 0xde0a3d61,
-       0x7ad3219f, 0x49f9add4, 0xeb7c9387, 0x7ff9846f, 0x244af59f, 0x23bddaa7,
-       0x425f8275, 0x33befaf9, 0x2d1bdeec, 0xa6ba680f, 0xcb43fe25, 0x6b3ef9ef,
-       0xfd0dc379, 0xf402cedc, 0x9eed61dd, 0x48a41412, 0xafd01979, 0x3adc1f41,
-       0xddbf58c2, 0x39dfac65, 0x7d3df229, 0xb4d46b6b, 0xd6aa7bd0, 0xf38e700e,
-       0x575e8d2d, 0x0b12df7f, 0x0b7bebcf, 0xf9815ee9, 0xc17fb494, 0x1b14faf3,
-       0xd91ea0f3, 0xfb46cfbf, 0xbc8a5521, 0x55164319, 0xbde2efe0, 0x9f9d8af0,
-       0x17ff4037, 0x998a05e3, 0x97de0fb7, 0x1251f7c4, 0x3c5a493c, 0x633495c3,
-       0x1b87b7d4, 0x0bca2afd, 0xdc46d896, 0x27e60d77, 0xe8edef1a, 0x0f38fe8a,
-       0xcf9863fd, 0xe84f8c6c, 0x3e7d5a71, 0x2c7f28ff, 0x39cfbb5a, 0x346b6e9c,
-       0xa30ba8f9, 0x39d23d73, 0xb973df07, 0x87bb52f9, 0x43c129ff, 0x26896879,
-       0xb3ac171e, 0x9c528eb9, 0xea0ff344, 0xf306b8b4, 0x56ef5d7d, 0x1095ecc2,
-       0xed7d22ff, 0x39f5f5d7, 0x38f377e4, 0x156a2d88, 0x360dc3ae, 0xfaa66ebd,
-       0x00a6e6d3, 0x5aaffdf9, 0x831f189c, 0x6718ddef, 0x411dcdf3, 0x065d5d7e,
-       0x0e7bc14b, 0xb4cbb0de, 0x6abdd6fe, 0xd8f5c669, 0xdb76f36d, 0xba49f242,
-       0xf9d1efec, 0xf9fd08a6, 0xf90dfd0c, 0xf8c1fd76, 0xfd7788ad, 0xa7f61bfd,
-       0xceff2202, 0x691bf949, 0xa17b1fed, 0x42cbb89e, 0xf7fd4f71, 0xe7cfca0f,
-       0x7a8cfdd1, 0x4e14137f, 0xd51ace87, 0x8e5d8f90, 0xe507377a, 0x67f49da0,
-       0x8320cb45, 0x69f5d4de, 0x681bf9c5, 0x57482cbf, 0xb5212e2d, 0x38aa5e93,
-       0xbc68bfff, 0x349e903b, 0xf7e9124e, 0x3549c781, 0x38e0e3e8, 0xf7700c93,
-       0xc132671f, 0xdac38fa1, 0x9fe70ca2, 0xae3ccceb, 0x33986672, 0x1e823626,
-       0x83714bd1, 0x60ff70c9, 0x62b2e49d, 0x4eca75ff, 0x287f3435, 0xef005f7c,
-       0xf02164c5, 0x867ac1d5, 0xf30b72c1, 0x3d405e52, 0x072213f6, 0x62a5d9a2,
-       0xf8c262bf, 0xc62ef9e9, 0xbdb945fe, 0x33727d10, 0x8bd82df2, 0x7e3b583f,
-       0x49ec0f95, 0x4769ecc9, 0x93764aba, 0x6b68f313, 0x45c51315, 0x64ac92eb,
-       0xca12adff, 0xbd739455, 0x2243a95f, 0x8f7df438, 0x9f29e681, 0xc33cd077,
-       0x9ffb3bef, 0x76a14f1b, 0x3b57eefd, 0x0f93d730, 0x93545bfd, 0x4e5d450b,
-       0x2127d853, 0x47ef0ff4, 0xec4520da, 0x8e9dbc27, 0x6ce901ff, 0x3d2070ee,
-       0x88a5e3ba, 0x951b1079, 0x310798ef, 0x271f4c2f, 0xe00ecd1c, 0x238742f7,
-       0xe5f48323, 0xa5f50546, 0xdc9fccfd, 0xb4cbd24e, 0x7fafadef, 0x56a984e6,
-       0xbc6c4f9e, 0xfe206f57, 0x7d62f1d3, 0xf3c641f3, 0x7f94bd53, 0x483c3972,
-       0xfb43cb82, 0xe2297600, 0x425836be, 0x4938fc86, 0x354fe631, 0x63e21e48,
-       0x56d54df3, 0x5b4927da, 0x927dc569, 0x063392d5, 0x37ded8fd, 0xf983fec1,
-       0xbe793a35, 0x6bff786a, 0xb4661ef0, 0xc4531573, 0x06a379fb, 0x34baafb0,
-       0x77d9acfa, 0xf501fe69, 0x3775c1e1, 0x71524e2a, 0x399b35dd, 0x4bad03bc,
-       0xe103bf7a, 0xfc7dd1eb, 0x392c1bf7, 0xffae3f56, 0x4a35e3e1, 0xbc3e4f1e,
-       0x7078046f, 0xcd31acdf, 0x546df84d, 0xd5fd1525, 0xcc5111e8, 0x656fea1a,
-       0x67f7a2cc, 0xccf1e3e2, 0x8f8c6b22, 0xe3a3979c, 0x1df2b769, 0x186f1ded,
-       0x8f7f0e5f, 0x7c21e8e2, 0xe84ca9d9, 0x91bb97cf, 0xfc381317, 0x5aa6f7a1,
-       0xbc458633, 0x7f1fb27f, 0xde4df186, 0xf7e74664, 0x19b94306, 0xeed56efa,
-       0xb5c0aa43, 0xf2f4fc0b, 0xc2a6147b, 0xe477e6fa, 0xc939405f, 0xcfcfdf6b,
-       0xf026b4d1, 0xefb51e7b, 0x625dc7c3, 0x12c8fee7, 0xcc654abb, 0xf12ff751,
-       0xdb5a37f7, 0x5e789ca3, 0xb22e35b1, 0xd763931f, 0xb49a68f3, 0xb41d0873,
-       0xcfb7a14f, 0xcddcc79b, 0x1b3dc50a, 0x257fe0ad, 0xa9ffb5f4, 0x82023fb6,
-       0xf9dce30b, 0xf99aebdb, 0x7f3e51f9, 0xfb62ab8c, 0x5c8ec4c4, 0x740efc41,
-       0xf70cc6db, 0x3b5855db, 0xe7ce51b2, 0x7699bc9a, 0x68eaa718, 0x5bd62247,
-       0x4e9d3edf, 0xb71d6f7e, 0x47777b37, 0x3fa0dc53, 0x79f96a7d, 0xcc29f3f2,
-       0xdd3fa837, 0xad00a5ca, 0xd3e7e5ab, 0xcd1c6f99, 0x0b8d67db, 0xc2d3bfbe,
-       0xc8b1a4d8, 0x884f1c00, 0x30f4489f, 0x7a064ddb, 0x675e3c80, 0x7881e8d7,
-       0x76b7a3ea, 0x76a74bef, 0xcd71e0bf, 0xf72a615f, 0xa5fbf5d7, 0xe5f7678e,
-       0x5b7dd05b, 0x13f736e5, 0x3b0b4f78, 0xe6be5222, 0xfefc29c2, 0x771685c4,
-       0x0b57da0c, 0x6a1453ff, 0xf3937f69, 0x7f0d22fd, 0xf745cc9d, 0xdad6f80e,
-       0x984ebef8, 0x54f1967f, 0xc23fb8fe, 0x44da8bf7, 0x305f1bca, 0xbf61f145,
-       0xbf05ed79, 0xe2f9fdc4, 0x773a68c6, 0xae7bf0be, 0x2dd76893, 0xc4e6c27c,
-       0xfe597bdf, 0x327e6641, 0xc9fcbbf4, 0xdf07d50c, 0x24f0af45, 0x27a05d59,
-       0x8853db1f, 0x3083457e, 0x0630be7f, 0x0ec7cafc, 0x98b8c2ac, 0xcf94cdf4,
-       0xf47f506d, 0x615677b1, 0x18b7e9bc, 0xf63b26e7, 0x63b442dd, 0xf4d0425f,
-       0xc1c03ffd, 0x5a4d874b, 0xa9aac4fd, 0x4daff2a0, 0x2a293568, 0x562765fa,
-       0xc4d939e1, 0x1318f738, 0xfd8ef78c, 0x6fec42b3, 0xcea313c1, 0xe7f7806d,
-       0xbec817ed, 0xdf693a00, 0x014f370b, 0xb278bbbb, 0x582d975e, 0x86668f8f,
-       0x3339be38, 0xd9da3e38, 0x8b7c7aad, 0x718cdd45, 0xd505e3f7, 0x3fe82453,
-       0xceaea1c3, 0xc4d8c919, 0x1baaf9f5, 0xc476cfc6, 0x98f18cdd, 0x837dbed6,
-       0x1f18d5f8, 0x03de656b, 0xd37f7866, 0xb66e43e3, 0x07e36202, 0x30a8c679,
-       0x29d641ff, 0xf4dfa7ab, 0x4463e41d, 0x0d59f3bf, 0x939204f6, 0xf4d28843,
-       0xc2defc15, 0xe34ef93e, 0x1f57db7c, 0xc3cfc1d1, 0x5e24f5e8, 0x59195d6f,
-       0xc312dc5f, 0x2a35baf9, 0x4d66fbf2, 0x03be003f, 0x8b6d7f14, 0x08cf0ff6,
-       0x1f900fea, 0xa79224eb, 0x807f5c75, 0x93b4cd1c, 0xefec46dc, 0xab6bcadb,
-       0xab79af76, 0xf8c68ee4, 0x30c7ae82, 0xcce38682, 0xfa0d3bb5, 0x017daf39,
-       0x3151d7e9, 0xc9c7872a, 0xc53093f1, 0xb59847a8, 0xdf743b3d, 0x3cda77fe,
-       0xe3d3ae33, 0x7439013f, 0x8ef969df, 0x9f9e4bfc, 0x7f38c72d, 0x9c1dbd88,
-       0x678a54c7, 0xfa17ebf4, 0xbbfd6a73, 0x5f04ae72, 0x15f065ea, 0xdcbaf84f,
-       0x19fd833c, 0xfbfd2fe3, 0xc17db593, 0x223ae326, 0xa4f38647, 0x7f8027ce,
-       0x2cfe8853, 0x9ea9f4d6, 0x6bbdd107, 0x064fe524, 0x31e7e5c7, 0xc4bfbe81,
-       0x81f25ddf, 0x963d453e, 0xc56fb927, 0x71ed79f6, 0xc0efda2a, 0xbf1af56f,
-       0x3a6fc849, 0xaae35b9d, 0xebbe69f3, 0xfa4bb204, 0x3ada41d9, 0xd024d79a,
-       0x9e0d99ef, 0x87e715e7, 0x7beba7c0, 0xeb55bfe8, 0xe7e73c7f, 0xf9f8fb67,
-       0xcd1f943e, 0x0eae679f, 0x1c3d5fba, 0x732885fe, 0xd5eb2109, 0xeb8a36ab,
-       0x5abb78eb, 0x85edd7fe, 0x25d701f2, 0xf8377d07, 0x84e1c068, 0x1e518b76,
-       0x7cb55f50, 0xb664f742, 0x7f0c89b6, 0x8de700b2, 0xd74f237a, 0x8795be93,
-       0x5bb2240a, 0x49d97a82, 0x37ae8bf6, 0xb06b5603, 0x2bb5b9fd, 0xaf51eb0b,
-       0xc7ecf76a, 0xc7c5a08b, 0x7348e106, 0x9277bb70, 0xddfc4597, 0x5dbb1cb8,
-       0x8f3423d7, 0xe80a2b8d, 0x6d2a855e, 0xe1d49d3d, 0x345378a3, 0x104271e2,
-       0x7d7afa1f, 0x15e3a5a7, 0x8197bced, 0xd83af51f, 0xaca69525, 0x7ef8ff60,
-       0xe7df0866, 0x841f3839, 0xeabbe7d3, 0x0f83c027, 0x0d43f0f1, 0xc75009ef,
-       0x04982d7b, 0xfde617eb, 0x6b5c50cc, 0x56e04232, 0x104e3eb8, 0x5d8f5c4d,
-       0x07e22e46, 0x58f7ed31, 0x41cf24ec, 0xe5bb707c, 0xe7168701, 0x3f29eed5,
-       0xa1390268, 0xcf3e367d, 0xd4c95dee, 0xddad6cef, 0x6f2f4bdf, 0x7496f2d6,
-       0xb5e2b17b, 0xf846cdd4, 0x1cbb7f79, 0x47792f1c, 0x8ed063dd, 0x5c51ee19,
-       0xb5e41fe8, 0xf98fdccf, 0xf07bd924, 0x7c820407, 0xe5c2dd9e, 0xc34bb814,
-       0x43db9bcb, 0xd874adfb, 0xbbfb3975, 0x28fb23cc, 0xcba457e7, 0x5a72217d,
-       0xbe3850e3, 0xc4167e60, 0xa3d464a7, 0x83f7f97a, 0xcf1fb3c3, 0x3e039525,
-       0x78eb6d50, 0xbf996d6b, 0x7c7286d2, 0x8e50b994, 0x9be65bbb, 0x315d2146,
-       0xa219cc11, 0x79f3d61f, 0xf02876e8, 0xe5f20b65, 0x1a10c73a, 0x7751f86f,
-       0x1fbc0e74, 0xc613768e, 0x7eec5b7d, 0x0efc23f4, 0xe2072eef, 0x14ef5673,
-       0x8cad4fdc, 0x85b5aeae, 0xdf6bef3c, 0x8f89ed06, 0x1fee22bd, 0xf8c03f95,
-       0x7cdaf1bd, 0x02cfa9a0, 0x20c855e3, 0x0f5459a7, 0x655ade20, 0x3ef7bede,
-       0x5611a5fa, 0xf97bf229, 0x95befd60, 0x536df3f8, 0xfd17d21c, 0xcb93b424,
-       0xee1a4f45, 0x16c1b27b, 0xe003ae17, 0x1fbf1077, 0x06c931b4, 0x4a1efffd,
-       0xc4d3d3d4, 0x6b8e74a5, 0xfb40965a, 0x8f7fba44, 0xa4fd0b7a, 0x4d17bf3b,
-       0x3c2ec8fc, 0xd3e30c38, 0x4e9cd109, 0xeb558fd0, 0x1b1d6ac7, 0x48ffbf94,
-       0x8efe491f, 0x141dbebe, 0xe0e7ea04, 0xd735d74d, 0xd841f885, 0x83ffea1f,
-       0xa5b48cc2, 0x1f9affc8, 0x7c61f647, 0x7b45dd70, 0xce21ac65, 0xebe0d3e6,
-       0x0a3e4748, 0x3ed147b5, 0x7d67b3ed, 0x0cdf57f3, 0xf4e2767a, 0x715e0096,
-       0x6e8acb5f, 0x6fe817fe, 0x36b3d81a, 0x8d3ec3c0, 0xf8660e2f, 0x3d4fdc44,
-       0xfba05c38, 0x79450fdc, 0xe095aa73, 0x5c5a8938, 0x33cb5120, 0xe5e28c4f,
-       0x1eb8620f, 0xaf863cfc, 0xbca837d7, 0x1c88e89e, 0xbdad9847, 0xeb89a9ff,
-       0x91f935f7, 0x684fd1f3, 0xedaaf5fa, 0xfc211cde, 0x8e13eebe, 0xdd7dda09,
-       0xe3c76f94, 0xfe340bfd, 0xe8873b06, 0xf8abb414, 0x876e9d7e, 0x4d9f6d9e,
-       0xf78213f5, 0x2c047bbd, 0x9f904f3d, 0xf148aef4, 0x6f58e2a1, 0x55a5e622,
-       0xcb8e4544, 0xf4f0d20c, 0x38a30d59, 0xcfdc29ef, 0xb7bfe6cb, 0x1b25f585,
-       0x1d7ba49e, 0xe29f994a, 0x1a1b45bd, 0xc8aebf68, 0x80a7302f, 0xc78799fe,
-       0x943a3581, 0x710d116e, 0xb552c5e7, 0xe4139b1c, 0xae1dfc5b, 0x9b25f7d0,
-       0x57ea19c6, 0x1816976f, 0x7a823bf2, 0xbfec90a7, 0x3e757ef0, 0x8f4fb70f,
-       0xf10d38d7, 0x861b05ee, 0x78cdf217, 0x73217ede, 0x36177cd1, 0x11ef1966,
-       0xb2b84c6e, 0x1ec1827b, 0x538445f5, 0x3fa8fd26, 0xf7f80e3f, 0x17f7c485,
-       0xe08c3a7c, 0x7bc38bf8, 0x8e018c5d, 0xc433e668, 0xdff326cf, 0xf8f1b429,
-       0xef8ff023, 0x7e407652, 0x07f577cc, 0x1fc01dae, 0xfa87fdc8, 0xb9937903,
-       0x024d65fe, 0x9c4ce0e5, 0x66cfb46a, 0x6e75f0c7, 0xc1b44c76, 0x679a2b3e,
-       0x6b57376c, 0x776b5737, 0xa84a38b9, 0xa164265d, 0xe9fde33e, 0x71951fbf,
-       0xffca6dfa, 0xedc310dc, 0x6eaa9fd7, 0xbbf40c6f, 0xd0773b56, 0xefdade6f,
-       0xf735ad4a, 0x5e5285e5, 0x1e6fe6e0, 0x09dfc3ac, 0xf601dde9, 0xfcc1e83f,
-       0x7ba0df67, 0x6eeff4ba, 0xb432d15f, 0xa954f008, 0x8bb973c9, 0x15dcafcf,
-       0x3f418790, 0xae1ce529, 0x827d96b4, 0x5a5df214, 0x22b76f09, 0x2ff06cc6,
-       0xffd5a27f, 0x6549c635, 0x1840495a, 0x3652ed06, 0xec24116d, 0x0b577f0f,
-       0x66a949e0, 0x93dfd0fe, 0xedcf194a, 0x6fc7db9a, 0x04e61616, 0x9a68d0f1,
-       0x5c62a391, 0x85da3135, 0xaa47cceb, 0x50f10eb7, 0xce8051fe, 0xa8fc4c49,
-       0xbdbb425d, 0x23d7755b, 0x7078eb7f, 0xae0a6a8a, 0x711fd1a3, 0xfcfa9b38,
-       0x30bebe62, 0x4766a8f6, 0xe976eb37, 0x42edc661, 0x5712a75a, 0x3efc308e,
-       0xb69c6261, 0xef32244e, 0x37da854e, 0xa327a232, 0xccae24f9, 0x2c76e66e,
-       0x2cb4f7a7, 0x3e7c16cf, 0xb1c8f06d, 0xd647df78, 0xbf8480da, 0x26dafe3b,
-       0x51fbc453, 0xc3fc359a, 0xf9c59e3c, 0x9cb8f3e9, 0x99dbd05e, 0xe84f8807,
-       0x3d3d10f2, 0xd8c1dfb2, 0xff3ef4e3, 0xe97bf8d9, 0x997acafe, 0xc74e4f7e,
-       0x69eab77f, 0xb4a6bc41, 0x3708166c, 0xdc7a78da, 0x5ca39f0e, 0xe78d971e,
-       0xfb94073a, 0x16873b15, 0xbd7dca85, 0x1cd9f44c, 0xdbafe796, 0xe1887ff7,
-       0x5890eaeb, 0x4bc43ecf, 0x8a3adb65, 0xc2d92cef, 0x4067f77f, 0xfe215cfc,
-       0x07ee1284, 0xfbe1cf94, 0x4acff95e, 0x7ab2ff44, 0xe5acfbfe, 0xb8f077db,
-       0x0b998fce, 0xcb7943f5, 0x0728a10e, 0x8773077f, 0x9f0428b0, 0xca7ee5a9,
-       0xaec6bf83, 0x5bd71fcb, 0x718efce1, 0x0e53b462, 0xe87eb8d9, 0xb87c57cc,
-       0xf669dc1f, 0xcebb6396, 0xe61768e4, 0xfff8e977, 0xe99b8efd, 0xa77db5dc,
-       0xa3658025, 0x8ac939a9, 0xcad70efb, 0x6eabe42e, 0xe9127bd5, 0x5a792713,
-       0x78d8fbf1, 0xbe16abbb, 0x58d85a75, 0x3c72b955, 0x8fe30c4c, 0x72e63f89,
-       0xf43aa493, 0x24b186bc, 0xeb9daa37, 0x67d7132d, 0x1e7ccc87, 0xf787193b,
-       0xb3ee3107, 0xe3878724, 0xf294dc68, 0xca1f9d00, 0x70d3bd38, 0x5fc830ce,
-       0x1b7dbfee, 0x2c3fff7e, 0x00284ba1, 0x0000284b, 0x00088b1f, 0x00000000,
-       0x7dd5ff00, 0xc5547c7b, 0xbddcf8f5, 0x0dd90afb, 0xdc3bf79b, 0x24280c10,
-       0x01049e6c, 0x878424d9, 0x28026e20, 0x47796bc8, 0xd2026c92, 0x6dfad0fe,
-       0xe5318316, 0x16d46b6b, 0x882ea945, 0x835ab696, 0xb80d06a2, 0x47d62228,
-       0x2d8aa523, 0x2220a5da, 0xfb1b6484, 0x6fcb56c0, 0xec9999ce, 0x0f0d9bde,
-       0x7cf9fb6b, 0xdcc98fe1, 0xe6739f79, 0x9ce7339c, 0xb5331d99, 0x228ca8cd,
-       0x389aa6a4, 0xfd2d34bc, 0x84e90ee9, 0xf00b9085, 0x8321226f, 0xf121326c,
-       0xbd3ca484, 0x582c524d, 0x1c5a7fbe, 0x052627d6, 0xaed84bbe, 0xa0af9686,
-       0x84225ba9, 0xa0e4258c, 0x31cc7881, 0x2ae8b484, 0xfd68d947, 0x7b488496,
-       0x663b2d13, 0x68db4573, 0x9d63967f, 0xeab4ac07, 0xa33e6398, 0xda4bf68b,
-       0x4264c7e9, 0x121230de, 0x8c1ddb41, 0x6dd3ed60, 0x42229074, 0x07891b26,
-       0x233d1bbf, 0xc1dfda14, 0xbfb083a1, 0xa6eab797, 0xc37b697a, 0x19d8b220,
-       0x9b74ef32, 0x6ca5db0e, 0xe8e921dd, 0x5a48b8f7, 0x513f321e, 0x595b01ef,
-       0xcc67cc26, 0x43844ed4, 0xae3d56dd, 0x1ce8c2a7, 0xb05466b6, 0x8fe868de,
-       0xe6ed7bd6, 0xfa7e8c4f, 0xbd2fc7fd, 0xbf50246f, 0xc1b47255, 0x37df5bfc,
-       0xa9a1c9ce, 0x4932e7e7, 0x613a6420, 0xf0bf36ff, 0xdfa151be, 0x70a6efa7,
-       0x76eaf5a2, 0xa32fd2ef, 0xc5a95769, 0x24268d23, 0x8b6bccf3, 0xdefd2148,
-       0x74112266, 0x5736dd6e, 0xfbce8d91, 0x0e535dcd, 0x58845149, 0x20f9339f,
-       0xc421f015, 0x06b4e19f, 0x3a5225e7, 0x722fce30, 0x10b3fd2a, 0x55ef46b2,
-       0x95ddf099, 0xb7eb4559, 0xccf830c6, 0x42e0cc1f, 0x157bec2c, 0x0b80975f,
-       0x8c0a7f1d, 0xdce5915f, 0x2454fd01, 0x329bd846, 0xaff99e61, 0xebdc2999,
-       0x823d92ec, 0x672b8d56, 0x579d0cf0, 0x79b84e65, 0xe2f1c06d, 0x44f8d963,
-       0x7180cfef, 0xefb2f109, 0xf9216932, 0x3873f6c1, 0x1f77e9be, 0x3a864efb,
-       0xd7f38273, 0x4d836fe2, 0xe861fac2, 0xa3ac116c, 0xc7cf98f6, 0x0f53ace8,
-       0xe6799674, 0xd043e230, 0xeab6cfcd, 0xd5fd1531, 0x5fd88cd9, 0x708f4d9d,
-       0x1a780cd9, 0x2c03534c, 0xcc1ba69a, 0xc7850f5e, 0x1f26f39b, 0x7e297292,
-       0x20fa316e, 0xb4b7437d, 0x48dfca16, 0xe8b7e361, 0xdf216b74, 0x34859772,
-       0x6e1d5e21, 0x376bcf98, 0x6a7e2147, 0x26bd1ae7, 0x9f8fcfda, 0x63de5897,
-       0x67fa12f1, 0x72f66bad, 0x22e24768, 0xfe024fec, 0x738c075c, 0x4ae9fdac,
-       0x51bf6e79, 0xb7a7dfa1, 0xf027fdb1, 0xe8c6db50, 0x0107ec4b, 0xbd3c20d7,
-       0xf024fdaa, 0x8db07f31, 0x17a505d1, 0xcecd7780, 0x3349db08, 0x0102eb1b,
-       0xe5568cfa, 0x6d93dbeb, 0xf3044727, 0xd007f035, 0x81620ec1, 0x79f2d679,
-       0xeeb9d3ce, 0x6755fd83, 0x50341ff6, 0x0d1f16d4, 0x881f7ee0, 0xffd66b7e,
-       0x0164fb3a, 0x0e93ab21, 0xadf62a61, 0x7f7aa861, 0x6f78e56f, 0x7bb69482,
-       0x4d4dd382, 0xcbee1b61, 0xb80d939a, 0x19532d9f, 0x231cb35f, 0x133c508e,
-       0xdebe43f2, 0x457db17b, 0x9964db64, 0x71e2bdc2, 0xfa44d6c9, 0xaba44fcf,
-       0xa36ce224, 0xf5b67dfd, 0x0025a8f5, 0xc82eafdf, 0x37ae98a4, 0x3777ad82,
-       0x3b5d3be7, 0xde91c029, 0xcc248c1b, 0x3fb72f7a, 0x01223be2, 0xec386b3c,
-       0x1f2e9ebb, 0x17a529fb, 0xf6c1cecf, 0xcf92e8ab, 0xf6eb3d3e, 0xbbbce94f,
-       0xcbb44c76, 0x4e4d3640, 0x7c409fa4, 0xa53b7d84, 0x4c99389f, 0x37de2895,
-       0x351ebdb4, 0xfcfbb68e, 0x81f3a397, 0xf7cdbf6f, 0xe5e799fd, 0xbb9700f5,
-       0x75ecf67e, 0x95e35e50, 0xce304d62, 0x95ffc7ce, 0xdea9fb42, 0x26100f51,
-       0xd57cbf4d, 0x74f5a7e8, 0xfbec6dde, 0xa836c1ce, 0xf713f9f7, 0x6ef0075f,
-       0xf2c26b6a, 0xc36c4f33, 0x7b3f6bfc, 0x683fdf76, 0x94675abd, 0x799dea1d,
-       0xa5e23f7e, 0xc077a5d6, 0xeba2077a, 0x33f6bbcd, 0xe126d97e, 0x1973237e,
-       0x2d74131f, 0x9ff3f7e8, 0x2a1b1e2d, 0x16f7c437, 0x833b9723, 0xcb391c98,
-       0x994d6ff7, 0xb3d205a5, 0x85cc44cf, 0xfe8dbaf5, 0xcf9868ec, 0x1f174628,
-       0xb6d47871, 0x2db831ad, 0xf9fb1ed8, 0x487bee80, 0x9e7d2873, 0x6b4ef4a2,
-       0x0050b8ed, 0xeb0afde3, 0x11257ad3, 0x2f37be14, 0x7cc12e38, 0x18354722,
-       0xbf9e706a, 0xd574e564, 0xebc5e5a1, 0xe96a3d18, 0x059b0be0, 0x907d8beb,
-       0x4d32bbb2, 0xb2603e41, 0xd6ce3e33, 0x6aed5297, 0xd7efd2b2, 0x65d973af,
-       0x4f97c78a, 0x4a9c9e1f, 0x211b3ff3, 0x65fe2015, 0x8f39c989, 0x5ba9c705,
-       0xd04e465f, 0xd9a2eaf9, 0x11b0497e, 0x07c8b5fd, 0xd7ba31b6, 0xf205bd13,
-       0x89f200fa, 0x072e16ba, 0x1279b077, 0x96632073, 0xae59db15, 0x83ce098d,
-       0x3058b3b6, 0x29b8c81f, 0x678ee407, 0xc51dca2e, 0x233df388, 0xe4f101f8,
-       0xee09cc2e, 0x711d04b7, 0x8c13fe01, 0x7e30b534, 0x4ffb4953, 0x8a4d2e8f,
-       0x09a60a2e, 0x16b95883, 0xf2f0b74e, 0x923b451f, 0x3b5e01a2, 0x60f25563,
-       0xdaf2be20, 0x6e4cddcd, 0xe91c72bf, 0x08740dd0, 0xaa4ebbe3, 0x6472f6e4,
-       0xf70e94ae, 0x5c3a471c, 0xabf8cede, 0xb8d4bdbb, 0x259ba68c, 0xefe61732,
-       0x7404f4e6, 0x9bf9a764, 0x7d71a3a2, 0xd9fcebee, 0x39baa7c0, 0x61ef75dd,
-       0x4e86f6f4, 0xbcf801e7, 0x36e47db1, 0xf95a0790, 0x113b5528, 0x6f8a6edf,
-       0xd67a0493, 0x67a0c3ba, 0x3b1355d5, 0x6ef757ec, 0x081a1fbe, 0x7b7707ee,
-       0x2fe872e5, 0x5d9a6e35, 0x992f5096, 0xeef34a9c, 0xfb04525a, 0xd96b652d,
-       0xd20ba01e, 0x20ab912e, 0x0ddced5f, 0xab8fafed, 0x2099cbb3, 0x9927b6f7,
-       0x47ebfd69, 0xcdfb6314, 0xf4294ae9, 0xb620a9e7, 0x706f2127, 0x9cdb3ca1,
-       0xf20ed23c, 0x88daedce, 0x0651177a, 0xb89ca1d9, 0xbea16bf4, 0x6c80b3db,
-       0xe3ecc292, 0xcb03923d, 0x08de91bd, 0x3b7a7eda, 0xeddc7fd3, 0x139f1f6c,
-       0xa1a911f0, 0xd78c1173, 0x788982fd, 0xbd9d20a4, 0x930a67b9, 0x509a2fb3,
-       0x746d9ece, 0x34541390, 0x10568c8f, 0x358e02af, 0xa03a99ad, 0x9966425b,
-       0xf8cb1e60, 0x4c0d5a3c, 0x3973446e, 0x9b2f7590, 0x1fbe72c7, 0x78eb4796,
-       0xaffbe46a, 0x9b05c995, 0xe0e41727, 0x921e3e39, 0x73970245, 0xe5bae874,
-       0xb527dc3e, 0xe2feb34f, 0xdbbc8e4c, 0xe855e842, 0x6c7a5a47, 0x6ca6e3e2,
-       0x3301203d, 0xa55ad949, 0x57d7e7da, 0x5d3d5f13, 0x755bf5e7, 0xa8b989be,
-       0xfc82dd37, 0x6c91837c, 0x77f7fa97, 0x5be3344f, 0x3cceb115, 0xcdd7e409,
-       0xfa3fd416, 0x8720e9f6, 0xb8f4022e, 0x84dec97c, 0xea1670ab, 0x09d3bd68,
-       0xede03b56, 0x5a8e1c47, 0xbdafab7d, 0xd19c0f46, 0x4325c9ea, 0x4186e969,
-       0x549e0173, 0xa198b75f, 0xa7b68d9d, 0x8fb612f5, 0xf213627b, 0xf7ec26ab,
-       0xeb1b68f6, 0xd859d627, 0xcb2e2c00, 0x27c98eb9, 0x7adc3dab, 0x9e85a3d2,
-       0x074f28bd, 0x82db33f4, 0xafc7e1fb, 0xbd194b48, 0x01284151, 0x41fdb23d,
-       0x5278fee8, 0x3d447a41, 0xf4e0ddca, 0xb647a786, 0xaf54dc5f, 0xd29b3d02,
-       0x27a65ae3, 0x4fdb085b, 0xa7232e8c, 0x7c007932, 0x159f542b, 0xefbb54fb,
-       0xedf6fd05, 0xefdccbfb, 0x1fb606dd, 0x801c29bb, 0xfce8fbde, 0x9be74665,
-       0x48fdd036, 0xfdd137cb, 0xffc214d8, 0x981fe7b5, 0x04079c27, 0x73663dbf,
-       0x745f0076, 0x19ab7f6f, 0x47f396c9, 0xc83fcbf7, 0x65de98be, 0x5fb4ca86,
-       0xa1afdd33, 0xe0a663f4, 0xea63e6b6, 0xb9113901, 0x8947ad5e, 0x266883f4,
-       0xdeb1bebf, 0xa3d24238, 0x55f1c3de, 0x007d73ab, 0x46f41e7c, 0x6324114a,
-       0x131bd33d, 0xde00e640, 0x417a47b6, 0x20484e3f, 0xccc2e7ae, 0x67df3f67,
-       0xfce29f02, 0xeac51090, 0xff7df2f7, 0x4ff7af29, 0x4b9c869e, 0x3a283f70,
-       0x0f2271d7, 0x3b448f2c, 0x172c2f3a, 0xd73be9f3, 0x137cd998, 0xbedecaee,
-       0xc18f0429, 0x3e75757d, 0x5eeb37e0, 0x25a97e9f, 0x8b908e38, 0xf981ba5a,
-       0xf581fc83, 0xb81a8e54, 0x7e7eeb5e, 0x71d0d33e, 0x7b5fdf04, 0xb482b8a8,
-       0x2bfbe0d5, 0x5635c7ee, 0x2522fa02, 0x9d2c4707, 0xe1befd57, 0x088d1f6c,
-       0xeafb4364, 0x314dd758, 0x9331dfb4, 0xdfa0fef8, 0xa09ce0ab, 0x0c531e27,
-       0xf5e0dde0, 0xd3f9e087, 0x8f7fd618, 0xe991ecd5, 0xd623b8fe, 0x3ded0d15,
-       0x03eec465, 0xe5077339, 0x896fb027, 0x4df808af, 0x0147f13d, 0x5d58c79c,
-       0xbf4031f1, 0xc9366772, 0xf257fca2, 0x63f7c2e7, 0x84b95111, 0xfb71f3f6,
-       0x85799f6f, 0xcaf85ab6, 0x03df85b9, 0x22317afa, 0x18e2e803, 0x513b97d5,
-       0x830656df, 0x944bddbe, 0xfc30b6c1, 0xcc0ba457, 0x20beb33a, 0x55663f98,
-       0x7a442f9f, 0x6fc30c4d, 0xe214f9fd, 0x09fe8589, 0x627bbf9e, 0x1f5df614,
-       0x56ea8230, 0x78833e7f, 0xeb1f7f68, 0x985b7548, 0x30c53771, 0xc84ddb7a,
-       0xf7e570d4, 0x0f7671f1, 0xb030fb65, 0x7f02f24d, 0xe1bf5eac, 0x07e532cf,
-       0x3eacebd5, 0xe831694c, 0x8f36d56f, 0xc7f3474f, 0xd11f8c0c, 0xc5cdb37f,
-       0xeb47b941, 0x0e03c7e9, 0x4b20f43c, 0x2e52e0f9, 0xbc3596b7, 0x13d825f9,
-       0x3cc4f5aa, 0xdcb3f69e, 0x4a983cec, 0x2cb33e8b, 0xbfb6028f, 0x25b73bf2,
-       0x5c4a5c80, 0x32eccad0, 0xf40d9264, 0x4331c95e, 0x317910be, 0xfa8f4b3d,
-       0xe29fe231, 0xe7188beb, 0x82f7c04c, 0x80f504c1, 0x7a45b705, 0xd07c213d,
-       0xa5a1e1cc, 0x7eb84f9b, 0x767feda5, 0xfe81196c, 0x739ca23a, 0xdc163e81,
-       0xcfc54e76, 0x53ff25ba, 0xad5d028f, 0x649fdab1, 0x433865dd, 0x623bfee8,
-       0xc43af3bc, 0x675e4f53, 0xa04cfaf6, 0x87c640df, 0x30eacf60, 0x940a3cd9,
-       0xa2cf111b, 0x291a9fdd, 0xe60ecbe3, 0x361e9e97, 0x196be819, 0xde0337b1,
-       0x1244b597, 0x033f084f, 0xc3e81805, 0x3f609e7d, 0x3cde3b4b, 0xaddcfc0a,
-       0x2c9d23f7, 0x8f105b35, 0x9c7af3ee, 0x74316907, 0x8a7b45f9, 0x8e5123fb,
-       0x9e7d60db, 0x9f47c67b, 0x263f491a, 0x7eb8efd2, 0xfdf0edd7, 0xe228c8a1,
-       0x4b78fa00, 0xf3a70ef6, 0x832b35ef, 0xeabc2863, 0x460e948d, 0x734e3763,
-       0xd243fe88, 0x77fc6aac, 0xcc25f5bc, 0x65d9b967, 0xc2be3904, 0x32a7cf41,
-       0x6457c9e0, 0xef8a151b, 0x9185f2f1, 0x45ef8f97, 0x6c7fbf7c, 0x661ff4a4,
-       0xe1c7dd1f, 0xa5ea23df, 0x71f27db0, 0x0e7ea906, 0x4a686bd2, 0x943c7ddb,
-       0x3e79f3e7, 0x604bd79b, 0x9f7c1df9, 0xeacb9c7c, 0xc5f1c769, 0x3b36fe30,
-       0xe015b1d6, 0x8cf9db45, 0x22fb1740, 0x16b7a8bc, 0xfc077e52, 0xea3a6d6d,
-       0xedaf94ad, 0xc4d97ac0, 0x4cf58d17, 0x03485728, 0xcfb07be5, 0xcf84148b,
-       0x274a52a6, 0xd7b03cb4, 0x04aedb64, 0xa9f02af1, 0x8c7b63c5, 0xc3c9eff4,
-       0xd43e9251, 0x61e5428e, 0xa3b30c7b, 0xd27f6118, 0x9e991899, 0x85f10c36,
-       0x3e5f2274, 0x608c6ebe, 0xf4fba078, 0x7bd418b5, 0xfba1397d, 0x97c704e5,
-       0x0f1f67e0, 0x8ab5e352, 0x5e6de1e3, 0x8d8c516f, 0x007b4fc9, 0x31c7ddf7,
-       0x165c7eac, 0x0f424393, 0xcb8703ff, 0xc8549a4d, 0xd5533195, 0x1c4dc5fa,
-       0x44c5379f, 0x087ebc09, 0x88f215f3, 0x345f17f2, 0x5e0b0fdd, 0x217f2135,
-       0xb0d9031b, 0x63bd68ff, 0x2c0a6e58, 0xe472a58a, 0x18dfaa26, 0x22ddb1f3,
-       0x3cefdf68, 0x85d04a3f, 0x3e9c8095, 0x1853d625, 0xe54f7e40, 0x296bae1d,
-       0xba437ca1, 0xd037fe34, 0xd694c93a, 0xd8560c87, 0x03a64ef9, 0x208fed02,
-       0xe147f40a, 0xb850e7fe, 0xc63bc76b, 0x319fe0e9, 0x96f11e92, 0x9f70f247,
-       0x7585ffbd, 0x9cf2ed21, 0x51d1eccd, 0xceb8ffbe, 0xe9fa0175, 0xd42dfdba,
-       0x7d198fcb, 0x3096add9, 0x63df46e5, 0xf2c1490f, 0x3d973fc5, 0x762fca46,
-       0xe4fd7677, 0xa5eeba66, 0x861db29d, 0x5fe77a5c, 0x7a031ddf, 0x0ec1a775,
-       0xdf2a46e7, 0xbcc3d5ef, 0x791e981b, 0x83a6a74c, 0x9f55dfb3, 0x1962d273,
-       0x83dea8be, 0x3be09cfa, 0x4adf7e42, 0x5c81577c, 0x461c465f, 0x66b4ff48,
-       0xe1420cd5, 0x0eb2c2b7, 0x6be7d1f9, 0xbc1ea1a7, 0x7cb07892, 0x4fe18b59,
-       0x4561f2a1, 0xeabf3aab, 0x56fe7561, 0x67df3aaf, 0x2f0f2e7f, 0x32c7a7df,
-       0xd94b3e3a, 0xb03fe03e, 0x3d05e4c1, 0x98af5b48, 0x3ca4cbd7, 0x24f813b1,
-       0x4760fb95, 0x48e11758, 0x6ebebe04, 0xc5e2696f, 0xe7f57cec, 0x10de21af,
-       0x37a8237d, 0x6c6f12e4, 0x63cb7eff, 0xf4238415, 0xe071f0ab, 0x2cb671bc,
-       0xc6263afc, 0x10653d0a, 0x8bbe27f6, 0x45e3827e, 0xcfea3ce1, 0x8f98079b,
-       0x5d9fdb05, 0x1b9c7e19, 0xa9b1c6fa, 0x7db064e4, 0xfc6b931c, 0xa3e82d1c,
-       0x7e127cfe, 0x07a17917, 0x31a5db07, 0xd9a48afd, 0xf906454e, 0x8b63b094,
-       0x224270fd, 0x3bb464e6, 0xebcfcfdd, 0x5fb05cf6, 0x083d009f, 0x6514e3f6,
-       0x714e9f9f, 0x66c6f7d9, 0xf70687eb, 0x941d768b, 0x43f8ceae, 0x58b2eef8,
-       0x6b8e1c6b, 0x57187627, 0xdba2fbd0, 0xe8bb062b, 0x6778ff7c, 0x546ba279,
-       0x30f53f28, 0xe85189bf, 0x9c95165f, 0xbc391a25, 0xd42dfdac, 0x95bea8bb,
-       0xd3e74c0d, 0xbd23b7bd, 0x04ce24af, 0xbd9ef3a0, 0xff5c33c3, 0xf315fc86,
-       0x6259e599, 0x9ba79820, 0x2abfee98, 0x1d599f3e, 0x99d3ef4c, 0xc71c061d,
-       0x025b1441, 0x7cd9a51e, 0xd3d4f329, 0xf9be84fc, 0x908e9183, 0x12fe7cf1,
-       0x9df0a7b4, 0xd4b253c0, 0x36f30495, 0xbc74b8c1, 0x824de208, 0x5dac69b4,
-       0xe4a27481, 0x3079b3d4, 0x0d264f3c, 0x675f5069, 0x9d6ccbf6, 0xd0090674,
-       0x985e0fbe, 0xc6fcf2b7, 0x568bbdd9, 0x158b77c0, 0xcf9188f9, 0xe52c4763,
-       0x2fe46687, 0xc9b75866, 0xfd1cfbe2, 0x94f53c64, 0x3d8fb829, 0x3bda0943,
-       0x02369106, 0xe72c5ae3, 0x1b58b03c, 0x8f9049b1, 0xe0faf5b0, 0x66ce70fc,
-       0x2346e8f1, 0x0b19dc9f, 0x677a527c, 0xf285e025, 0x19ff6665, 0xc3ef5ca8,
-       0x73e0b773, 0x4d7e7c31, 0x1325cf9c, 0xe2588706, 0xb01ef1c0, 0x40419cae,
-       0x49d65984, 0xd44b7ed0, 0x25eff454, 0x7969e000, 0x8abd54ec, 0xd53bc56f,
-       0xeab9c4f9, 0x9d4bb27c, 0x3f93d337, 0xcf928be8, 0x16217499, 0xc02359cf,
-       0xfce062de, 0xebcf99a2, 0x3d74a408, 0xfd3e71ef, 0xbb13f58d, 0x8eeebcfa,
-       0xe3b41231, 0xd0cd9825, 0xde57d53f, 0xcafa658b, 0x97281e27, 0xf3cfc803,
-       0xc0f9b626, 0x837cd3ae, 0x7e8bbf64, 0x1b2ab66f, 0x3d5494f4, 0xc76624d3,
-       0xf54adbd1, 0x865b7cb4, 0xe689becd, 0x1d7ec1eb, 0xd5b7f30b, 0x49f68d3c,
-       0x0247ab13, 0xdc8fe0cd, 0x8366c9b6, 0x81e5717a, 0x8bd046c9, 0x76db1057,
-       0xbfbe8612, 0xce86fba2, 0x53c809f7, 0x5e9c48bc, 0xf3290f22, 0x7cbc0d71,
-       0xc59dfc07, 0xe18b13f2, 0x65feca5c, 0x3a75e475, 0x90e0eec0, 0x77d62e51,
-       0xa16ebde4, 0xcecd65e3, 0xb3bc3b43, 0x0973f99c, 0x3463f7df, 0x905c6afb,
-       0x8f3cb1ce, 0x707587e7, 0x899c6ebb, 0x746d6bf9, 0x36666288, 0x8c71fac0,
-       0xfc44edfe, 0x5af2fb63, 0xfd07fc12, 0x47fb0795, 0x5829343e, 0x7467dc1c,
-       0xbdb37ca8, 0x1bd696a9, 0x87edf7a3, 0xa78e3c7d, 0xa37d3c79, 0xbf9406f4,
-       0x628b3a9d, 0x6d7db1d4, 0x861302ce, 0x14b80653, 0x04d07edb, 0x7c904cfd,
-       0xbd4c6698, 0x5fa609bf, 0xd147edc5, 0x06ef4649, 0x12a68eba, 0x77b4678a,
-       0xd820f9fc, 0x4907e5a5, 0x88e9e001, 0x0739c841, 0x7a15d39e, 0x3a1afb1c,
-       0xfd406c98, 0x2a932ffc, 0xd5013bf0, 0xd2bbce8c, 0xbe2116c6, 0x755f2c0f,
-       0xe36a3f28, 0xb337e464, 0x6abf32a6, 0x57b35cfd, 0x10ce4092, 0xbbd277e6,
-       0xb10a6f32, 0xc43f0897, 0x773206fb, 0x44f39857, 0x4fd31c6d, 0x3b3066ab,
-       0xa346fd6f, 0x1d537fca, 0x335eecc7, 0x8c8f26e3, 0xfcc47943, 0x5c7179a7,
-       0x46411b6f, 0xe10a9f00, 0xaf504523, 0x81edf4ab, 0x9cba8cf8, 0x8e3999f3,
-       0xfdea0302, 0xbe08df9c, 0xf6c41cee, 0xd2423cf3, 0x9367ae81, 0x87ffe406,
-       0x7e456f4b, 0x18f11373, 0x951f6f00, 0x310278b1, 0xd55359ef, 0xa71cd27a,
-       0x5cf37f3a, 0xf0c51ead, 0xe79dc621, 0x09579752, 0x5aaa783d, 0xfff05e0f,
-       0xb9468abe, 0xdd54f89a, 0xe7e02185, 0xc000f660, 0xe873f30b, 0x1bdc6e91,
-       0xbebc3f99, 0x388def3d, 0x127767d8, 0x4976cfbe, 0xb2ffd1cb, 0x82115a4b,
-       0xaf5ad4ff, 0xb8647204, 0x987dd855, 0x7934e4de, 0xc3df83f7, 0x91128359,
-       0x49e3cebc, 0x493c400e, 0xadbe907e, 0x57165665, 0x30b51c41, 0xa45b349f,
-       0x16fef41d, 0x65da3e5d, 0x2aaca25b, 0x0da6fa3b, 0x13d4054a, 0x44c558f6,
-       0x6e9c6df2, 0xd7779dc2, 0xbafe31c5, 0x71766259, 0x9e333ccf, 0x9cb3e32b,
-       0xbc413f2a, 0x9d828e4c, 0x229c6470, 0x63fda3ea, 0x5c95c1b3, 0x44af5340,
-       0xd2171197, 0xd11b265e, 0x4fe1a8ae, 0xb476b1f1, 0xce0fc7eb, 0x9cfd3b41,
-       0x2fb43c8e, 0xfd844b12, 0xffd8292a, 0xf4dbd99c, 0xdf53a710, 0xdcbf4db1,
-       0x7bbba412, 0x8d5cb8e2, 0xaf409124, 0xe7ba767d, 0x7ba7684c, 0x5ffce75c,
-       0xa35acba0, 0x2171ed0f, 0x07df8af4, 0x38ab8b92, 0x9cca18bd, 0xf9d056f3,
-       0xb46bbcf5, 0x1d19f9c3, 0xe7ffb46d, 0x9da344f7, 0x50455f51, 0x652c6d3e,
-       0xec07a47c, 0x9f1d745f, 0xf9e35745, 0x8ad4a360, 0x663ba3f2, 0x6af1d232,
-       0x073c01cb, 0x74a56f57, 0x569f2218, 0x6be750ef, 0xdf9e2748, 0x47ee9f6b,
-       0x0517c8cf, 0x56ef761f, 0xd4c323b7, 0xcb8f377c, 0x7da77c8b, 0x7d4c0556,
-       0x9d8b3dae, 0x8641e9c3, 0x1de8a3ae, 0x2eefb723, 0x008a9db0, 0x7494fb56,
-       0xc7adfd31, 0xfb665a7a, 0x2283c99f, 0x6e568e3e, 0xedbd7115, 0xe0bfca3a,
-       0xb0f42afc, 0x07f2c222, 0x92721d74, 0x42df382e, 0x7fe84ede, 0x7c084e42,
-       0x52109695, 0xa743f742, 0xc9434fe0, 0xed37c050, 0x0489f71f, 0xd8314391,
-       0x7dce07bf, 0x9478f8e3, 0xb7203c1e, 0x17b33a3d, 0x6a59abe8, 0x06693940,
-       0x9ba69f3d, 0x83ca1724, 0x323daa97, 0x692c7bc0, 0xd6833598, 0x8cee6f1b,
-       0x3a513804, 0x3f4a1239, 0xb197c44d, 0x11d1524b, 0xbf457796, 0x848e961d,
-       0xc47df33c, 0x74e998f4, 0x054fd0c5, 0x7a687e38, 0xc8e76240, 0xeb1f9629,
-       0xbadbfda1, 0x53274869, 0xf30f5789, 0xf1a9b0ab, 0x9d49253f, 0xa3f4a69f,
-       0x70c38c0f, 0x1f4e7870, 0x08772ea1, 0xfcd4477e, 0x857c932e, 0xc1f9187a,
-       0x5d80efc1, 0x193d7221, 0xd50dfa01, 0x6a1f7144, 0xb8ebe0e9, 0xf26fdd6f,
-       0xbf185c75, 0x13b70f49, 0x2bfc4b5f, 0xd3fa969f, 0xeb1bf759, 0x7a10a4e5,
-       0x65e2fb14, 0x907f8b03, 0xa9fe655e, 0xe5193312, 0x642afa03, 0x3fb14576,
-       0x8cfa05ae, 0x315dd209, 0xcf119eff, 0x19086ce9, 0xa1367402, 0x5327c23d,
-       0xfef1e4bc, 0xcbba05ae, 0xe223ea0f, 0xd254d15c, 0xa532be8f, 0x705fd42c,
-       0xa47d09df, 0xd26b6a40, 0xb91f0267, 0x1be609a7, 0xe3434f42, 0x512f808b,
-       0xda7dc27a, 0xcbaace4f, 0xf026f435, 0x52e5f42e, 0x367480d2, 0xea60a75b,
-       0xf2855cab, 0x5b32dcb5, 0xacdfed0f, 0x0936f462, 0xea0b31e8, 0xdca5e9ab,
-       0xe96bceac, 0x0ba88e91, 0x9f4b571d, 0x10dbd103, 0x5f2137a0, 0x6f4d2f63,
-       0x75bfe3d3, 0x7f1e9b7a, 0xd2d37a11, 0xbb5fe099, 0xa0e56c22, 0x4b57d73f,
-       0xde0a0f28, 0xf904d61d, 0xa89975e1, 0xb68aef4f, 0xdf5d7ea3, 0x3b0bcac0,
-       0xbdc4321d, 0xe5e3ad64, 0xc872ce99, 0xe5a7afd7, 0x23a2ebb4, 0xd8662e2c,
-       0xef3cac9d, 0xadd786ae, 0x587867a0, 0x6f3f97fb, 0xb968a396, 0x2fb799b7,
-       0x7c872d6d, 0xff6b0b7d, 0x46a9f819, 0xb79a7c43, 0x7d5fbe09, 0x1d9da66f,
-       0x3efe99ab, 0x9777af91, 0xd8ebdcf4, 0x5bb595ae, 0x883cd075, 0xe99ff9e0,
-       0x75f1d7e5, 0xd6cadc4e, 0xfae27719, 0x8ba50aa9, 0xea0f0115, 0xb574a76f,
-       0x06dfc8c5, 0x4a973f38, 0x4e9069ad, 0x5217eca1, 0x22ded987, 0xcc7e650f,
-       0x7b8874ed, 0x45fd99e2, 0xce20fff8, 0x9f4432a0, 0xd99e27b8, 0x84bd4563,
-       0xa0018a18, 0xa8ac4787, 0xa4ff0b5f, 0x812221ef, 0x723587bc, 0xbfac243d,
-       0x03564a72, 0x865311ea, 0x5fa53f08, 0x9b8e94bf, 0xc98be177, 0x3f43ece1,
-       0xe69ee3e2, 0x7a7d1371, 0x075337b2, 0x880bb174, 0xf4800524, 0x7f41afde,
-       0x487e05db, 0xa43ca426, 0xf2caf004, 0xbd7fe35b, 0x853c65a9, 0xef41aeaf,
-       0x2196a101, 0xccc9dc61, 0x1c1be24e, 0x53fe7fd5, 0xc467c4f4, 0xff362638,
-       0x1e544d95, 0x7e31d123, 0x8fe38736, 0xe90abf8c, 0xd3c73677, 0x2a7f05cf,
-       0x9fc00520, 0xddbc70e6, 0x347aa664, 0x8356c3f2, 0x133c6f86, 0xcb6a720f,
-       0xbabbfa80, 0xaa57c35c, 0xb92bb8f9, 0x092b7ede, 0x4a727ea0, 0x7a7a62f2,
-       0x6bdbd30b, 0xbf50472c, 0xe98479e9, 0x8fc4b5ed, 0xbed68ffa, 0x9d53b359,
-       0xe7536baf, 0xf9d5dbeb, 0x8e0f1c9e, 0xaea5b3d3, 0xd58aec18, 0x768bbf0f,
-       0x5fc16aec, 0x42fe6abc, 0x5fc67115, 0xed06ba1e, 0x6f98df51, 0x6f4f4d3c,
-       0xd0b8aac5, 0xfa9c02df, 0xb22f35ec, 0x613714f8, 0xeb1e8276, 0x4e70f988,
-       0xa4791a25, 0x9c7927e5, 0x86fb089f, 0x84792fe0, 0x8e7a23c9, 0x8241d77d,
-       0xd7ab5c7c, 0xbd73c4f5, 0x84d39f97, 0xfa0793fe, 0x35d3d00f, 0x4164480d,
-       0xdb7f6439, 0x9fc88724, 0xc0668579, 0xee99be73, 0x6c978067, 0x545971c9,
-       0xca05f0f4, 0x7bcf8199, 0xbd0d72ea, 0x2dd6f388, 0x81665e9c, 0xff8e8527,
-       0xe781c97b, 0x32b7c3ba, 0x5963997a, 0xd1faf487, 0xe22f466a, 0xe7e577dc,
-       0x4dfc873c, 0x747d79ce, 0x5ef54112, 0x17491e9a, 0x8fe67ce7, 0x1d1897af,
-       0xf87d55d4, 0x82cfe818, 0x246e1c2f, 0x3e10faf1, 0x64cd34d1, 0x934a3b06,
-       0xaa839d81, 0xbc5c7fa6, 0x38cf8434, 0x13134a22, 0x88ee5940, 0x5d6cfb47,
-       0x669c7aa4, 0x7fbbf3a9, 0x4fd2f380, 0xd44ed123, 0x954130fb, 0x70eb77a4,
-       0x6b3edb8c, 0x31527e60, 0x7707559f, 0x7ec3f3ee, 0x08ebff5c, 0x359f953d,
-       0x5ac5f792, 0xe4c4b65a, 0x6a7186ca, 0xb3233e74, 0x5fa27663, 0xb03b8c57,
-       0xf283d65d, 0x931af8d5, 0x106901c3, 0xefd2e1c6, 0xb5fea1d9, 0x4f8c89d1,
-       0x2aeb11df, 0xca0f8848, 0xa43f614b, 0xc6a49652, 0xc126fd04, 0x376606f8,
-       0x5c710bf9, 0x6361be32, 0xb69e7d88, 0x568f1b0f, 0xf5f8c096, 0x61ce29f7,
-       0x1da307de, 0xd39f30e5, 0x9a7b8fdc, 0x474efdfb, 0xcce03f31, 0x752cfabe,
-       0xf734f4f1, 0x518e9e13, 0xbd4487fb, 0x8ecc09a5, 0x6cd1b272, 0xbf07a8de,
-       0x1c6f313a, 0x21ec4946, 0x93c60353, 0xea78602c, 0x6dbd13d9, 0xa5ff8853,
-       0xfbf4a12e, 0xd87f9f30, 0xba43379c, 0x31b8f5bc, 0x23df0ed4, 0x0f77f3b1,
-       0x089e97a7, 0xeb718a96, 0x0fbf2a12, 0xe799ec78, 0xe5f63c47, 0x13bc8ac7,
-       0xc099effb, 0xfe5f6bf8, 0xb84f2c3b, 0xf5d843dd, 0x69f7f207, 0xd0547bfd,
-       0x044073b0, 0xfd6bcfb3, 0x3f050bf3, 0x05f9fee3, 0xec2d1f9c, 0x45827e60,
-       0x4a9cd266, 0x247717cb, 0x946e73b2, 0x9fe55b27, 0x515e44f7, 0xcba0863c,
-       0x3ecef49e, 0x2123f67f, 0xee3aecfe, 0xeb13accf, 0xdf5eaddb, 0xbadf0903,
-       0x8481fb3f, 0x6d6cfe30, 0xa08bc3dc, 0xe20b0c47, 0xc18dad61, 0x2dae42ad,
-       0xef6f7b07, 0xe8718272, 0xd65adf6b, 0xb5e0f604, 0x2a0b003f, 0xa7d431f2,
-       0x079c38eb, 0x53bc575a, 0x9d951447, 0x4251107d, 0x8aec9fe6, 0x4351e551,
-       0x4d03890f, 0xb5514ead, 0xaa186f4f, 0xfd643faa, 0x4cf2aa35, 0x9f2abe4f,
-       0xaaad72d5, 0x65ad55fe, 0x87f0fcaa, 0xcfd557af, 0xa3074323, 0x0c90ecfd,
-       0xb57221b6, 0x3e554ab7, 0xaa2de772, 0x86919ff6, 0xbd69e3cd, 0x79fe42dd,
-       0x8aa39d1c, 0x39ce7183, 0xed554b6d, 0x62b6a49b, 0x9f46f01f, 0xbd6893e4,
-       0xcb5f1c15, 0x62ff993b, 0x556afb74, 0xd8a367ff, 0x5fad183d, 0xa32e7696,
-       0x912ed61e, 0x7efea447, 0xfb8eeada, 0xa8ee219b, 0xf296bfbf, 0x356eda4d,
-       0xfe80bf3d, 0x8e6fd5a6, 0x5d3f7026, 0x7461490a, 0x0b0ba5ad, 0x5bbd7fea,
-       0xe627b465, 0xc687ec91, 0xc40cbc23, 0x5fc7f4ab, 0xae76612f, 0x76ada7de,
-       0xf559ff88, 0x47a432d6, 0x2e9a9253, 0x5d351422, 0xd3508e44, 0xa6aed585,
-       0x6a25c183, 0x3dc2d03a, 0x0ba6a1da, 0x43ffa7e2, 0x2ae02de0, 0x553b1ee0,
-       0x785a374d, 0xda0093e7, 0xc95eddd9, 0xfc6123ee, 0x70dbede2, 0x1fd2975d,
-       0xf86a89f5, 0x34701c16, 0x2c6e1059, 0x61e84cbe, 0x68ffae26, 0xaf4213fd,
-       0x7ae44b89, 0xf847ef15, 0x0f259a17, 0xfe7d51ea, 0x865f12c2, 0xa7f4132f,
-       0x44ecc206, 0xf0c4a4ce, 0x3efc4676, 0xc0519d90, 0x2620f675, 0x03886b2f,
-       0x882be1ed, 0xc9ddf90b, 0x3ed15bca, 0x63f2cab4, 0xad9ebbf4, 0x35527a62,
-       0xbf9f22f1, 0xaa02b8e2, 0xfb109287, 0x528e16ab, 0x02b3e487, 0x20f2e1bf,
-       0x79087485, 0x1378c2e0, 0x62e6864a, 0xad471f95, 0x30df82e7, 0xbd097f84,
-       0xe0278c57, 0x189af829, 0xe41a44cf, 0x1a17d824, 0x6846473e, 0x3b6a48fd,
-       0xe0f3b08d, 0x22fe2160, 0x44265dad, 0xe9916e0f, 0xcc90f238, 0x57f14226,
-       0xdda07360, 0xce7488af, 0xe625ef87, 0xc2bd26b6, 0x935713ed, 0x80c4fb3e,
-       0xfe12eaf2, 0xc91e59e8, 0x7f6668ff, 0x6bf0b43f, 0xf89fe5d3, 0x5e3c6d03,
-       0x55ef1052, 0x078f0f2f, 0xa76fea7a, 0x857d1fb4, 0x02eb23f6, 0xc3f6a1b1,
-       0x9206fbbe, 0x1373d71f, 0x424ddc71, 0x693710f4, 0x133f3c9b, 0x4e54c4ec,
-       0xecca4146, 0xab5da458, 0x8ed1eb07, 0x012ba3ac, 0x2121afba, 0x60ccda7e,
-       0xfee5e639, 0x74371179, 0x42e27d29, 0x3fc78da2, 0xc22778b0, 0x5f38a0f9,
-       0x139e740e, 0xcf701471, 0x2221fc16, 0x9139a84e, 0x4973839f, 0xf74ff42e,
-       0xb444a6db, 0x29fdd01f, 0xbec7ee85, 0xef2c22b8, 0xeb351fb7, 0xb2147117,
-       0x42ed10b5, 0x7bd742cb, 0x7a10f019, 0x3ea86fcb, 0x1234f780, 0x0dd7a615,
-       0x0381f63a, 0x553b0b8a, 0x46f59e71, 0x7b01807a, 0x8e3c8bc1, 0xafad4daf,
-       0xe3c89b3f, 0xe739f893, 0x181af052, 0x4eee3c1f, 0xf532e3e0, 0x27771130,
-       0x7f42f8e0, 0xc151efb8, 0xd8bcefb5, 0xe13df707, 0x72e02ee0, 0x29f3a8ae,
-       0x3d6c97c0, 0xeef00092, 0x83ee7288, 0xfd47e9fa, 0x705d24a7, 0x1772155e,
-       0xb6f6cbc6, 0xcf3f78cb, 0x5bc5813d, 0xc8c8f7b9, 0x4c3bba1a, 0x6ead37e8,
-       0xc2f51d7f, 0x68ca46ae, 0xa6761ea9, 0xbfa90e91, 0x0340bd88, 0x47ce81ef,
-       0x681f3d62, 0x75e22fd6, 0x7f7f3ae8, 0x3efc3809, 0xe42a1c1c, 0x9ee18351,
-       0x919c5f57, 0x1551903e, 0x75da1f42, 0xb0f4e66c, 0x013cef56, 0x4cef1dfd,
-       0x55fd0cdb, 0x53071dc8, 0x24eb3e00, 0xd1357fbc, 0x26cbeec4, 0x2574fbf3,
-       0xdc3b06fe, 0xb34a4e37, 0xe1a9fde0, 0xe09d91df, 0xdd78fe17, 0x4f70316d,
-       0x5c3ff44c, 0x4efde1d2, 0xe4fb9e42, 0x57f0428e, 0xa26fb02e, 0x162685b9,
-       0xddf99197, 0xe5165f48, 0x891aaf23, 0x61a3f619, 0x6bde0368, 0x68cb4409,
-       0xc9938cb7, 0x313ba024, 0x561f716f, 0xfafb877c, 0x7c52ef70, 0x2814d89f,
-       0x0ed34b58, 0xdd620f4e, 0x0503cb13, 0xfc20960d, 0x16a65c45, 0x3c385b3e,
-       0x66c6f1dc, 0xcdbb17d0, 0x52c9fce2, 0x9f23d362, 0xfb666759, 0xe255d8e6,
-       0xc2b3edfc, 0xe11dd4b9, 0xf6063c18, 0x7932fbdf, 0xb17f2692, 0xe3470639,
-       0xc7d415fa, 0xbb58d9d7, 0xbf071e6e, 0x44b2a3ee, 0x6f8e5f88, 0xa66f1f0a,
-       0x5c73b124, 0x8beff72d, 0x1f7ab5ef, 0x42d58dc6, 0xf04176bc, 0x6bc695fb,
-       0x01fc788b, 0x27ad10e1, 0xef78d1fa, 0x7ab179dc, 0x0e4bfcaf, 0x3ebebe7b,
-       0x0fe22749, 0xcf4defd1, 0x0be3615b, 0xf9d8934b, 0xe807182a, 0x7dc37bc7,
-       0x4a7b85f1, 0xce45c913, 0x0ef3eefb, 0x889fdc55, 0x9f9f7737, 0xfd7e7184,
-       0x29fda5fa, 0xe15c6096, 0x92dff040, 0x86e5e6c8, 0xd082bf78, 0xdefb0aef,
-       0x8f1c4e37, 0xc147f3df, 0xbb45fd3e, 0x7feaf78c, 0x75374871, 0xd779987b,
-       0x5db83127, 0x7dc7af13, 0x1c47d233, 0x2f8cc2db, 0x35fb89ea, 0x76aa9ee2,
-       0xfccbbb7e, 0x10fe608b, 0xbc6e1c47, 0xc48e9ca5, 0x30c777bc, 0x99f7b87c,
-       0xed059ef0, 0x77bde317, 0xe257f8c7, 0xf1a9b0be, 0xd7b73b7c, 0x9fdebeec,
-       0xa6bcf781, 0x40c33b31, 0x728de0f4, 0xd8f504fd, 0x4a65699b, 0x06fac53f,
-       0xffb216c9, 0x410f452e, 0x7854ebb8, 0x23770fed, 0xfbf457e2, 0x4fbe61f9,
-       0xe702c389, 0xbe5c25b7, 0x8351d92d, 0x1f38affa, 0x8cb0fe7d, 0x139f17f1,
-       0xbcf927e6, 0xcff3c255, 0xeb211752, 0xf95a1f29, 0x88334164, 0x844925b9,
-       0xbec3175c, 0x46e909df, 0xf97c9fb5, 0x87ecfdbd, 0xaeae5424, 0x57280d20,
-       0xdd58fe56, 0xfbdc9aae, 0xb49fd067, 0xdce1fbfe, 0xb1d6272e, 0x479e8939,
-       0x2629ef40, 0xd61f20c5, 0x3185f93e, 0x1f78194a, 0x777ca69c, 0xaff81e98,
-       0x46aed319, 0x48bfa61b, 0x44963c72, 0xc927b7f1, 0x9ed20db5, 0xbdff59f7,
-       0x7e4cbdb5, 0xb9438d6c, 0x2efd64d5, 0x087975f2, 0xc0f7ebe3, 0x1e14093b,
-       0x97d31326, 0x720d7412, 0x5e2dea14, 0xf1e387a4, 0x6266aa6b, 0x74049ede,
-       0x29cbf71f, 0xefce3153, 0x800e9197, 0x4752a6f7, 0x3625d81e, 0x997bb255,
-       0xb3f31366, 0xf6317f7b, 0x0c837035, 0x0cbfbb6b, 0x8eb6c1ce, 0xf7b03efd,
-       0x7cfee8b4, 0x5a57e210, 0x8bf163ae, 0xfeff3a09, 0xe2f190d4, 0xe049bd23,
-       0x691f8f87, 0x388f38c4, 0x21af34b9, 0xcdca5e24, 0x9edbd171, 0x1ec27685,
-       0xb61bb083, 0xa8bde045, 0x8183a1da, 0x18435c8f, 0x1bdc459e, 0xdf5421cc,
-       0x8470a2ed, 0xbf914ba0, 0x19f24da6, 0x12fdf0a2, 0xded4e3f4, 0x0f984be5,
-       0x7ae7ea72, 0xf98983f4, 0x5c9abdc5, 0x212efe06, 0x364be69f, 0xfae34766,
-       0xfe223cfc, 0x5cd97f31, 0xb8f3274e, 0x923f3f1e, 0xb1297bc1, 0x5bbb4067,
-       0x474a24cc, 0xf2fcd4b7, 0x675c22b6, 0xf41a218d, 0x19f7e105, 0x6f08cf58,
-       0x653f72ff, 0xa58df765, 0x72743640, 0x62e7c286, 0xf9c030fb, 0xdd9b3bb2,
-       0x88c323bb, 0xee8cfc03, 0x81b7c37d, 0x8834c27d, 0x7f29aff9, 0xa3e49732,
-       0x73866d5e, 0x44afadd4, 0x2f22f8f0, 0xc8ec4fbf, 0xfa9cf883, 0x8c7cb4aa,
-       0xc01a3913, 0x0dba3777, 0xc7dc0cfe, 0x5448ef94, 0xf2da0e36, 0xb87a19fd,
-       0xf54299af, 0xd92f9a35, 0x0fcb2f72, 0xd1d4aff5, 0x4f2d92fc, 0xfdd3d0cd,
-       0x7fc6bee1, 0x5b35f20a, 0xbe7cb176, 0xf34ca57f, 0x655e5bcd, 0x4960e1f5,
-       0x2dc1ec09, 0x68786707, 0xb9a267ff, 0xf1fbb7bc, 0xe5fbb59e, 0x3b50bae1,
-       0xe332636b, 0x9db8675b, 0x59264cf8, 0x1ef0055c, 0xb2febe11, 0x5a0f1d64,
-       0xac54c569, 0x4927b457, 0xf325dbe1, 0xf7e56e71, 0x924627a3, 0xb7e60896,
-       0x3c5144f3, 0x8e18e81c, 0x93afc77e, 0x6e9e9862, 0x38fbe3f3, 0x4f011fa2,
-       0x77189fd1, 0xe067c835, 0xac789acb, 0x3f8664ec, 0x1c46ce3a, 0xdd839867,
-       0xcb4aae2b, 0xbc51fc03, 0xf4de39e9, 0x8dbbfcec, 0x1bf68fcd, 0xa0728b9d,
-       0x07f8ec00, 0x33f5a2be, 0xd2d6f383, 0x93324149, 0x3136b72f, 0x3a206b7f,
-       0x6269e90b, 0xa5677f24, 0x668ebd50, 0xe4c6870e, 0x466f7e68, 0xc2512bc0,
-       0x1c389a71, 0xcf78fcd3, 0x5dd74af2, 0x775a1ff1, 0xf01cbe08, 0xf681ca5e,
-       0xf5b3b7ab, 0xcd7bf0c4, 0xd4188cfe, 0xf557eef7, 0xa6836677, 0xb8c1097d,
-       0x164c7736, 0x8227bfb6, 0xd93bf198, 0x332ed7de, 0xa0ade997, 0x2c778acf,
-       0x123ae788, 0x7bec47ea, 0xc58da2af, 0x39d70667, 0xd3af90a3, 0x6369d7c6,
-       0xe8aaf4eb, 0x64091c95, 0xa7f6b6cc, 0xf7f83ee3, 0x9f2a37f5, 0xe7daa7f7,
-       0x7d83fae1, 0xd65e103d, 0xd6f93a73, 0xa9e622f0, 0x9c1f6781, 0xf013f335,
-       0xed8dfd84, 0x52e9a946, 0x5926b3cc, 0xfb35939c, 0x8e1bf33b, 0xd5daca57,
-       0xb9e2cedd, 0xeba6a289, 0x3a99ddba, 0xed102b88, 0x1027c16a, 0x3dffb41f,
-       0x89edcc9a, 0x806d2469, 0x93c7c4f8, 0x0ddac28b, 0x9cf6bbf1, 0xe2cd13d8,
-       0x8af6b5d5, 0x277b789e, 0x9cf4afdc, 0x8c0aef63, 0xc06fd8d3, 0x259cf4cf,
-       0x5f282ed8, 0x9c73f9d4, 0x3fb7f63f, 0x7e603205, 0xe7b2a685, 0x47d53b15,
-       0x7e431cb6, 0xecb8385d, 0x7f9a4cb6, 0xc88ff935, 0xcb530bcf, 0xfca4c8be,
-       0x9fb27f7c, 0x7d9647e5, 0x5bf21431, 0x44feacfc, 0xefc0f3c7, 0x633fc789,
-       0xaf507252, 0x41592d78, 0x3ae5c9b8, 0x02647402, 0xc7ae8625, 0xe309aaf4,
-       0x075c04f6, 0xba4d0b4a, 0x6ff77086, 0x07a3eedf, 0x812957e6, 0xf3b0153f,
-       0x5f803b71, 0xf403b2af, 0xdf7bb144, 0x8eff7b3d, 0x483e5df7, 0x1e027576,
-       0x16bb23ea, 0x5dfcd265, 0x1fa09f91, 0x3dd0724f, 0xc515f601, 0xf9d01646,
-       0x9c9b5d4a, 0xd5913fa0, 0xe11eb376, 0x745eedca, 0xfc28178d, 0xf3f7d95e,
-       0x61b2a5ef, 0xb18f309c, 0xefd40f9c, 0xe06ff2fb, 0x633fadf7, 0x7af983b1,
-       0xdb96c76c, 0xdb1aff40, 0x4c97f6f1, 0x39fbb30e, 0xc163de62, 0x97bf49ae,
-       0xfe709bb4, 0x5eae3b63, 0xfdc7f501, 0xe80b23b6, 0x5f31c264, 0x9e85b013,
-       0xaaa52fbd, 0xcf90e5ee, 0x39d71a2e, 0xc04ddfa0, 0x54aa53e3, 0xf478460d,
-       0x857c7832, 0xf1dd67f1, 0x68fd9b87, 0x7fdf54fc, 0xfa3afaa2, 0x20c97b91,
-       0xc433f83b, 0xbdad7a7d, 0x5d2568f4, 0x213efd1f, 0xa2106740, 0x6f3c4f4f,
-       0x98248ca6, 0xaad1252f, 0x5939b97c, 0x96c2bf55, 0x929f2aa9, 0x7caab574,
-       0xcaa7929a, 0x56311f4f, 0x7b06ff55, 0x637f2aa9, 0xfd5534c9, 0x2aa5474a,
-       0x536be79f, 0xd4382fd5, 0x423f2eae, 0xfe43c064, 0x90ebfb51, 0xa0749d16,
-       0x74f8b5d9, 0x8e90ebc3, 0x87030bfd, 0xed7c5ed6, 0xe1d7b6f9, 0x6b17b0bb,
-       0xfb0933ef, 0xc5b2cdf1, 0x276f0c6b, 0x0567d24e, 0x75901fdf, 0x18d33eec,
-       0x94eaebab, 0xa67de0a2, 0xa62f6089, 0x7c58a848, 0x00e347ee, 0x3d980b4f,
-       0x062028ed, 0x68adbee3, 0x686a3c87, 0x2c0fe678, 0xf81d200e, 0x5cc084de,
-       0x9e27bad5, 0x5dd6a977, 0xe0d56e4a, 0x5f2a8d69, 0x555dbb61, 0x06d24a7f,
-       0xe534f955, 0xdd3c1a07, 0x60dfcaaf, 0xd3c1a2df, 0x7e9e0d36, 0xf4172aae,
-       0x5aedc1dd, 0x451ec0fb, 0xcefef1d3, 0x75c3c072, 0x8f8803a7, 0x72d6ce92,
-       0x47b5d3c0, 0x855f10db, 0xb039673e, 0x0d43e2cb, 0xa3ea43af, 0xf76831e7,
-       0xa612635a, 0xb4151a07, 0x1c6c1d6b, 0x46a1e981, 0x75ff7e3b, 0xefa60963,
-       0x7d303a34, 0xa62a71af, 0x4c4e8d9d, 0xb0db1adb, 0xed8d73fe, 0xdb162ecc,
-       0x3a45def7, 0x75ba07d8, 0x8278377e, 0x77923f17, 0xeecbf003, 0xc86efe41,
-       0x37ec45df, 0x25f9a24c, 0xbee844c0, 0x374f29fc, 0x80023aa4, 0xca1c3757,
-       0x18f1828a, 0x1e473a6d, 0xa477e1e8, 0x3ea1f84c, 0x37bb909d, 0xd16c9338,
-       0x79a66f2c, 0xb3c63644, 0x83a1f84d, 0x2033d712, 0x33a9d04a, 0xf7c806e1,
-       0x7772b044, 0x401b84ca, 0xfec6ff0f, 0xff3f4773, 0x61291df9, 0x9ccfe7fc,
-       0xd760ac56, 0x70d5fc39, 0x30e3c02b, 0x48396fb7, 0x4d09619e, 0x0679f54b,
-       0x0747b390, 0x80f0b7b8, 0xe009b4ae, 0xcfb3a6d0, 0xebef78c1, 0xb7e8040d,
-       0x5fe7624a, 0xca95cf51, 0x0dcf41e4, 0x1d4f3c26, 0x605639d1, 0x7814995c,
-       0x3dbce00c, 0xdee112a5, 0x00640d63, 0x4e29bcfc, 0x3c0f8f96, 0xf243d926,
-       0x079f0606, 0xb6fc6e52, 0x3858f3e1, 0x62913cf8, 0xcfb6fa63, 0x807a0e91,
-       0x74a91fc8, 0x3e7ec1d4, 0x0ab8ea52, 0x4d38cfef, 0xad3aff6c, 0x3ed0abde,
-       0x139a28e4, 0x9219e762, 0xd1f7606a, 0xd82262e1, 0x71916f3b, 0x39e16b9f,
-       0x7be99521, 0xce702748, 0xe789179c, 0xf63a2382, 0xfeb6819e, 0xb3d70e02,
-       0xe3dbc283, 0xbd32a616, 0xdd566ca2, 0xfed02f33, 0x6045d67a, 0xe1ce3dd7,
-       0x34f58fa8, 0x342ae850, 0x8e70dd3d, 0x1cec9b95, 0x9dbfe824, 0xf2d17f0f,
-       0xfb6e3a67, 0xfd68efeb, 0xda45d64f, 0xaed88651, 0xc2ddf841, 0x358c2f2b,
-       0xb0b4fea3, 0xe40cbd2a, 0x07ee7ce2, 0x27d5645c, 0x1f503ba0, 0x1727846d,
-       0x9af25b97, 0xcac90429, 0x3c234ab8, 0xb69d5525, 0xd5d219a6, 0xc237eec3,
-       0xa3b52913, 0x1a833576, 0x70b7475b, 0xff3ff211, 0x5e748dbb, 0x0acbd78b,
-       0xfb89cf3b, 0x145735ae, 0xf7e822cf, 0xa23b8f08, 0xeaf3c040, 0xd16f0e22,
-       0xd787116e, 0x3fae1489, 0x0b9c90e6, 0x67d63f6a, 0x0b5def40, 0xc01ecddf,
-       0xe72ea0cf, 0x4607e3fa, 0xfdf6ae36, 0xe2ee3112, 0x3afe7654, 0x0994a462,
-       0x4c2de4fa, 0xfdcee40e, 0xba22aee2, 0x9b0edcfe, 0x1615e30e, 0x7800bdd7,
-       0x78e76de8, 0xd8769034, 0x4b3cb34f, 0x221df93e, 0x8f754e26, 0xd2f252f7,
-       0x0f2b69de, 0x7e859795, 0xbca87967, 0x96b4092c, 0xf2145c83, 0x7d4ff851,
-       0x2f9cd58d, 0x3d3f2037, 0xf31eb8d0, 0x983d1b07, 0xe16c6a1e, 0xcb15b97c,
-       0x987c69df, 0xe72f65f3, 0x7bf13bcb, 0x4c5ce347, 0x58ba35f7, 0x9519ca3e,
-       0xecc4fb0a, 0x37c4f8c2, 0xf80898b6, 0x4c3b7ae7, 0x77419f18, 0xc68f63c4,
-       0x0991fc41, 0xe36a71ef, 0xbe7cb490, 0xf7761e8f, 0x0525377b, 0x1f8be9c6,
-       0xc8717d02, 0x9874f4c0, 0x4be05628, 0xe4fe8ff9, 0x0fafd006, 0xf4158a2b,
-       0xcdd482e9, 0xac50ef2c, 0x7c2f9a06, 0x8a5de794, 0x22ac04d5, 0x5be421f5,
-       0x358a3d87, 0x1f8be682, 0x7b95887d, 0xc7f33a09, 0x06f5ba3d, 0x2259f00f,
-       0x51fd801d, 0x449cce6e, 0xd79505c5, 0x5f6007a5, 0x325a494c, 0xcec5f609,
-       0x63e90514, 0x00e1b29a, 0xd88fa7e4, 0xfaab87a6, 0x46de4b0e, 0x57165768,
-       0x937687a9, 0x846cd6d2, 0xdd879376, 0x376d0faf, 0x8daed475, 0xdf619f90,
-       0x74fd07a6, 0xf8b1f027, 0x2f223f60, 0x169f05ca, 0x3ba37271, 0x720f289c,
-       0x0f289ddb, 0x66ca5c04, 0xf60dde57, 0xc976facf, 0x663cc126, 0x0a417d4b,
-       0x86e89310, 0xbf2949f7, 0x97f53ebe, 0x5db40dd6, 0xc5afe43d, 0x7c370ffc,
-       0xa6fbfcbb, 0xfbfc30d4, 0x41dfbe43, 0xfbdc43de, 0x0ef64687, 0x2e1c33cc,
-       0xac4b1df5, 0x712a8ef8, 0x7acf4159, 0x97f3cb9e, 0x9fe5a520, 0x7f8bb4f1,
-       0x70e7407f, 0x52ab38c1, 0x3fb21fb9, 0x6549a87f, 0x8f735ffb, 0xce728064,
-       0x6d52ea1f, 0xea3cf7aa, 0x76bfbb08, 0x6d3b38a9, 0xee36b89c, 0x3b693564,
-       0x1fecc8e8, 0xf70b526f, 0xc7fab2dc, 0x6a788b7f, 0xdf781c6d, 0xe3106ab9,
-       0xd78173a7, 0x496eba50, 0xde4f901d, 0xdc38097b, 0xfd0e0e1b, 0x9c5843d6,
-       0x2438bf7b, 0x5daeef1e, 0xb3c57117, 0xfc798d77, 0x827d76bb, 0xafaffa2e,
-       0xcf5fc195, 0xbbf54fe0, 0x157e60c7, 0xec04ad8b, 0xe7fca156, 0x3fe11777,
-       0x6df67e5a, 0x179bc9f1, 0x65bbe1d7, 0xf3d8f861, 0xb898f8e1, 0x854dafcf,
-       0xf3f70a9e, 0xde121e20, 0x7e738239, 0x1f6ba265, 0x1653d3f4, 0xce0e9bf8,
-       0xddec71a1, 0xaed183f0, 0x325df0fd, 0x1106b8b2, 0xe75a7c97, 0x6de815f9,
-       0x19fa3def, 0x106eb3f2, 0xbc8f7416, 0x97a0f341, 0x7ce6c3fd, 0x4647e013,
-       0xefa18df8, 0x7f140f8f, 0xff2e1bfb, 0xdf6ca7fa, 0x9ed43889, 0xa0665f6d,
-       0xfb12eefd, 0x54782062, 0x70fde3c8, 0x24b7a43f, 0x9767e512, 0xdef07c44,
-       0x02695771, 0xe95d2dea, 0xdfa43d46, 0x2bb8b9f6, 0xd7fb1b3d, 0x92bb8f9e,
-       0xdc6ccc4b, 0x7d2153c9, 0x2154f92f, 0xf0dfbdc8, 0xa376cbf8, 0xb03de0a7,
-       0x408d8f0f, 0x928dfeff, 0xa0e010bf, 0xbd77573d, 0xc94ca0b5, 0xa6be7fed,
-       0xeb049beb, 0xbbae3dab, 0xe95dbe1b, 0xfd76bb79, 0xb9c408df, 0x15ff5b8f,
-       0xaeeff781, 0x19ddfcfc, 0x5e80ab93, 0x12026ae1, 0xf545d319, 0x54bf9a09,
-       0x8939d6fc, 0x4333d39e, 0x6f25e5ce, 0x9e2e38b3, 0xfde7cf6a, 0xed5c09de,
-       0x960dc751, 0x5e308afa, 0xe147f645, 0x7b1d60bd, 0x73c4436f, 0xf3cfc9bd,
-       0x243ebcf4, 0x9d70ed0d, 0xfaf3aa19, 0xfa2d1f1d, 0x0881f21e, 0xa678ef8c,
-       0xcc3c44fd, 0xf19d8ff5, 0x0945793f, 0xedbd77d2, 0x9df4246f, 0xbdf5dac0,
-       0x86d77caa, 0x7056fbe0, 0x5ff6ab1f, 0x2a25ca32, 0x4f105ac7, 0xdae335e4,
-       0xda4af910, 0xef07dcfe, 0x55df94d1, 0xbe50c002, 0xd074cf36, 0x3cfc9576,
-       0x8de44844, 0x92aeda0e, 0x67891f9f, 0xe78f2b25, 0xb09f3df5, 0xff28ba7c,
-       0x7fac4ce3, 0x1c6fe895, 0x79164f2b, 0x22d5dfde, 0x9623789f, 0x25f68a67,
-       0xc6239f2c, 0xaded64af, 0xade4feac, 0x7a099cff, 0x33f7e08d, 0xe09cb8d2,
-       0xfe5152ef, 0xba2b4cef, 0xba8ebc68, 0xf107cb9c, 0x1dc5550e, 0x85df22d3,
-       0x6126dc7d, 0x9ded61ec, 0x9fe7b406, 0x0dcb698d, 0xe22f2fbd, 0x56e59c7a,
-       0x7baaf38c, 0x9976f871, 0x1e813bc7, 0xe9fb9cb3, 0xfa0b642b, 0x65ef7a61,
-       0x3d207e7c, 0x97fae570, 0x57ecf855, 0x46d3dfce, 0xef1d2547, 0xf1130fdc,
-       0xd619027e, 0xee02f189, 0x27c44934, 0x116abde0, 0x45971757, 0x8e7e701c,
-       0xbd82297b, 0x13b27aa7, 0x97caeff9, 0x6ebb7d98, 0xef28ebcb, 0xda0aca96,
-       0xea1ebe97, 0xe9f0075a, 0x2f77b2b6, 0x87dfae57, 0xc531f4fb, 0x8160fdc6,
-       0xbcf0a151, 0x3dfc3fb3, 0x8517f169, 0x3ffcbabf, 0x5dad7f0c, 0x5fd7dc5d,
-       0x7ff1857d, 0x07e656dd, 0xfd3c73b6, 0x7314a749, 0xf0023d78, 0x33a2b73a,
-       0x20865a3b, 0x778c4eee, 0x29df90ab, 0x6f56f382, 0xde009583, 0xdccea5bb,
-       0x5fe0c30f, 0x9f38ae7b, 0x69715441, 0xf7c3fb3b, 0xf7d04be9, 0xfa4dffd3,
-       0x8dfbd44e, 0x1f1bf076, 0x15e5ef65, 0x18c9fe77, 0x4ef41f1a, 0x0f073b1a,
-       0x317e676e, 0x2c171711, 0x713c32b7, 0xd55d53ff, 0xffc1e33b, 0xc4c3f624,
-       0xfe06d248, 0x76d74a04, 0xa076d74e, 0x41bf416b, 0x176d143f, 0xfa41be06,
-       0x912e2c25, 0xfdb7e9c3, 0x25e1fae1, 0x7fe1fae0, 0xa9bbae13, 0xdbfe8c3e,
-       0x4ed02217, 0x3ff385a3, 0xbc055c38, 0x0e2fd323, 0xfff4c8e7, 0xd3239c0c,
-       0x439d9515, 0xf9207bc0, 0x988fc5a4, 0x5a7d9877, 0xe9f64df4, 0x4f9c1923,
-       0x8f18fde9, 0x4c7bc5ab, 0x27bc3f7a, 0xef1c5fa4, 0x30fff2ea, 0xd370b5de,
-       0x9fdcb5a6, 0x985efdab, 0xfbbf203e, 0x7ff8e056, 0xb0b04fcd, 0x7caabf61,
-       0x54b7faf1, 0xef3c4be5, 0x415f965f, 0x5bfffbd8, 0x57e105fe, 0x2afcf998,
-       0xb51ff81d, 0xc43741f2, 0xc7a023f9, 0x7afe5f1b, 0xf93087d4, 0xb78c6cea,
-       0xe5af8dba, 0xff7ff18b, 0xbe947be4, 0xf66068be, 0x3ffb63d6, 0xfd392837,
-       0x79e165e9, 0xd084711d, 0xeff5c2d9, 0x5acf401b, 0x54fbd848, 0xa60ffada,
-       0xc6307b33, 0x30be5149, 0x710c4cd7, 0x9dcc1f94, 0xcf4beecb, 0x0c630705,
-       0x2d173ea6, 0x3e27a99f, 0xd2bb8f78, 0xd099f7a2, 0xffbea9ef, 0x75efe26e,
-       0xd558b893, 0x21d9783d, 0x9cdf9c63, 0xbd2fe612, 0xf786d2c5, 0xba1de787,
-       0x60f7dceb, 0x14f46f2f, 0x7177b8b1, 0xbaf7f0ff, 0x3e83f12b, 0x9c2a7a08,
-       0x5fee24fb, 0xff40635f, 0x2addb6ba, 0xca669fbe, 0xd9a38b12, 0xc533e2c3,
-       0x3beba4fe, 0xf767ca64, 0x48f7e060, 0xbe0c1b2a, 0x67a0b9e1, 0xbb3d47ef,
-       0x2e4364be, 0x927eafe0, 0x1b94dc74, 0xafd4ef3c, 0xd7b60bff, 0x7a6d67f2,
-       0x4fd5f6b9, 0xbd210f1a, 0xb1d17388, 0xb5e61f46, 0x1305d6f6, 0x93fd17ff,
-       0x6de2ff63, 0x57dc7482, 0xd0c70f8e, 0x3b1bfb75, 0x827b2dff, 0xbb0823b0,
-       0x214ed682, 0xbf7888f8, 0xe36e97d2, 0xa296b2ef, 0x59e883df, 0xc1edf82a,
-       0xd7f9fcfe, 0x27d717e9, 0x61ffe5d5, 0xf4b97cfe, 0xe4c49b5f, 0x8fee96aa,
-       0xed0cfd56, 0xb5be82cf, 0x6200bff4, 0x0bf8e852, 0x27bc25ea, 0xab55773e,
-       0xcdf49c61, 0xe5b57de9, 0x9b830664, 0xb15c2e46, 0x3c78503c, 0x0be78c87,
-       0x0ec6bc93, 0x87810f76, 0xefd5d3af, 0x48bc5303, 0xab971719, 0xfafff2ea,
-       0xa2e4e039, 0x8917266f, 0xcb489f4a, 0xe56eb7e8, 0xfe56eb12, 0xb90eeb9b,
-       0xd648b4a7, 0x40e3ef05, 0x81c435fc, 0xfdd978f6, 0x56ccead4, 0x5203ddfc,
-       0x7e028812, 0x995eeb77, 0xde8e9efd, 0x790e4fa1, 0xf88bad3f, 0x5c7a003e,
-       0x3bbd9e35, 0x769b8da4, 0xd5ea78f3, 0xbf78dd96, 0x9a0efb51, 0xf376cb88,
-       0xa1efb4fe, 0x9de2f689, 0x687bed03, 0x1c783253, 0x67c93e76, 0xe7172971,
-       0xcf20dda3, 0xdd35fc43, 0x5da2355f, 0x4ac7c6e1, 0x05a4f3ee, 0xa32732f1,
-       0x9799df1f, 0xa3be7171, 0xd32fff2e, 0x81dd6caf, 0x94aed8f7, 0x3a64477e,
-       0x827f40dc, 0x9bf1f72f, 0x6fc84c57, 0x3df33bc4, 0xf7c19e6b, 0x24be7a87,
-       0xd4bd97e8, 0xbb13e33b, 0x09c435d8, 0x564dbd27, 0xc771d78a, 0x1baf683c,
-       0xf785c47b, 0xe3bcc776, 0x927f8880, 0xc329c077, 0x233e85bc, 0xff209bf4,
-       0x78d9f7e2, 0xf2e5d59c, 0x37f52bb9, 0x8cfca7fe, 0xb75d5ee2, 0xbf0457c1,
-       0x13d9e0e7, 0xa103bf81, 0x1993ff9d, 0x93be8bba, 0x7ae511dc, 0x8b34f012,
-       0x5ef109cb, 0xdecc8572, 0x94edef49, 0xeeb85ed1, 0xabfb7e7f, 0xdb4b9547,
-       0xbd6dea15, 0x2265cf61, 0x7bb1d7ad, 0x0ae5f92d, 0x79c249c6, 0xc287ec0d,
-       0x7fada89e, 0x297b294a, 0xe35bed03, 0xdeda3df1, 0x067cd987, 0xfafd57c2,
-       0x603f8e00, 0x7ebf1f39, 0xf42d916f, 0x19f3959d, 0xdb43e77d, 0xdf107329,
-       0xff174b97, 0x332dced7, 0xa891e265, 0xbc91cd7c, 0x4c25ef4c, 0x3a405dff,
-       0x02445d31, 0xbb08ba98, 0xd894b0cf, 0x9c4e5d31, 0x5c55ae98, 0x3718195d,
-       0xf8c04814, 0x39ff17d3, 0xdce6e80a, 0x215ae375, 0xf2dbf146, 0xbef56923,
-       0xbd853c9e, 0x3fc2f497, 0xd9f4077f, 0xcb863ff3, 0xa2471be2, 0x1848641c,
-       0xa57bd33f, 0x54d7bb32, 0x17dc5df2, 0x325dfde2, 0x96e1f989, 0xfee26627,
-       0xc4cdf209, 0x826f826d, 0xb8e7393f, 0xdcc3c58e, 0xc67be12a, 0x6e1d7eed,
-       0x99159cb1, 0xb9ddf85e, 0x3cacddf6, 0x2bda2ea7, 0xd8ce7cd1, 0x26be5608,
-       0x4ff70bda, 0xee3f1216, 0xfb70c5cb, 0x4bfb8644, 0xdf8a2f8c, 0x8227a00b,
-       0xbf6d12a1, 0xeeccc3a2, 0x30ff1051, 0x70b9ffe0, 0x4f170a7e, 0xf1f18433,
-       0xbf1943d1, 0xb6a65d1f, 0xe5e50c87, 0xdf6529f7, 0x0cb47807, 0x810d6471,
-       0x9b9d31fa, 0x3b042c1e, 0x9f808e90, 0xb7b1b3e6, 0xb4535fa3, 0x1b29517b,
-       0x959ff501, 0x67bfbc58, 0x4c6fbf2f, 0xfea10902, 0x794ab5b1, 0x1a2bd42e,
-       0x40d3f8c2, 0x51df8570, 0x2f398674, 0xd1d1f88a, 0xbb436670, 0xd277c13c,
-       0x7e58959e, 0x6f5be3f2, 0x5f4168dc, 0xe3f40782, 0x44d71517, 0x91b46f18,
-       0xffcc0b10, 0x1b7efca7, 0xbb00c869, 0x4cc7aae8, 0x3e2fd03a, 0xee18e2a2,
-       0x9e81fcf7, 0x98fd21b7, 0xfd219b9e, 0x43373d23, 0x9b9e9c7a, 0xcf413d21,
-       0x38ae90cd, 0xccc7876f, 0x8e2189c9, 0xf0bfd0b9, 0x5be769f7, 0xd7f18439,
-       0x1af7f1be, 0x14fbfc71, 0x0fb7c217, 0xfe087bdf, 0xd1b3edde, 0x8b989481,
-       0xdecf5bd0, 0x749fa3bf, 0xff08b820, 0x0a7cb6a3, 0x6eee6bc7, 0xdcffca3d,
-       0xcad47f76, 0x872b7a90, 0xce7db118, 0xa0a3270b, 0x1f5b6eff, 0x5d121d7c,
-       0xcb1d4cf2, 0xb9fc7caf, 0x828e371b, 0x0fbe3bf9, 0xf9f74174, 0xdb73486a,
-       0xfc00fb7f, 0x1fed2a5e, 0xa47a24e3, 0x2f3c66c0, 0x85a1d668, 0xb3d75883,
-       0xa09b9dd1, 0x0c2fb3fd, 0xbe509585, 0x01bed843, 0xadc2923a, 0xe7ae0377,
-       0x10a05346, 0x78dd0bee, 0xa71b0e41, 0x8a529f7d, 0x7a064e70, 0xcaddfe43,
-       0x025f4653, 0x7f74df6f, 0xe223fb6b, 0xa5e015fd, 0xafa5c80a, 0xac2f40a2,
-       0xed04f1e4, 0x06fd87bb, 0x2439e9d6, 0xdabdf813, 0xfdea31d1, 0x49e38bb7,
-       0x8d7b39a4, 0xb3d7c04e, 0x830d4f7b, 0x7e2989f7, 0xc57bc186, 0x455c86db,
-       0x31ef7f42, 0x8f97ec67, 0xf587183c, 0xe769f7f1, 0x10156d91, 0xbcdf3337,
-       0xd2580dff, 0x0af1db42, 0x9c599b88, 0x74841d24, 0x19399289, 0x7dc465e2,
-       0x4a236583, 0x9a96c20f, 0x7d44af61, 0x4c9814ae, 0x37287c88, 0xd847f247,
-       0x558a3c85, 0xa524a7e5, 0x534feaaa, 0xd3e554b2, 0x95548c47, 0xd867718b,
-       0x46f5540b, 0xc28604c7, 0x83ae8e79, 0xa4ff03bd, 0x3986f18c, 0x7eb91c2f,
-       0x7ccfcd24, 0x43be0e6a, 0x9f2f2cf9, 0x17b95cf9, 0xe143d1f0, 0xd50aa469,
-       0x6c1f92e9, 0xd33a107e, 0xf76a179c, 0xa1d0713e, 0xe179c65c, 0x8184e712,
-       0xed164fde, 0xca04e7b5, 0xbe001f37, 0xd9c5fa39, 0x3edbf036, 0x14cbf63b,
-       0xcdfd4788, 0x0caefe10, 0x440c3f3f, 0x43fb7d37, 0xbcdd1852, 0xc3279325,
-       0xf2440dd0, 0xe9643a32, 0x7eecc3cc, 0xb5f295de, 0xa1af814f, 0x4243c0bd,
-       0x6b577f7f, 0xb46d1bdf, 0xb036e6ff, 0xc32bbd47, 0x7bbea50d, 0x6fe12b93,
-       0x64ef4839, 0x93bbb6f9, 0x07bbf0e3, 0xb73761f4, 0xb8520df7, 0xffbb553e,
-       0x60c2e4ee, 0x5c775939, 0x29dc9f55, 0x1bf2ab35, 0x7bf9d533, 0xdb439b4b,
-       0xad8fa40f, 0xd189787c, 0x6ef70395, 0x37bfb0a5, 0xfff3e62c, 0xd5800901,
-       0x00800020, 0x00000000, 0x00088b1f, 0x00000000, 0x19b5ff00, 0x6554540b,
-       0xcef7bbfa, 0x7860190b, 0x77421028, 0x840a4498, 0xb0285789, 0xd71ea08d,
-       0x8f4c1ada, 0xe5935654, 0xe04d7903, 0xe3d8f4b6, 0xb68fad18, 0x695b6d07,
-       0x9656356b, 0xb139e4e7, 0x36254644, 0xeb495bae, 0x66a254d6, 0x42d899e4,
-       0x7a26704c, 0xf75a9d6d, 0x5efffefb, 0x5b602e67, 0xe74ed69d, 0xffffef9f,
-       0x27ef7ffb, 0x70ca1490, 0xf60800ce, 0x9970ccac, 0xd6f70601, 0x8018e41a,
-       0xe2eff4d3, 0xf9b8daf0, 0xcf03837a, 0x3a380057, 0x01cfe3cc, 0x031401d6,
-       0x7b81295c, 0x5914f3a2, 0xff60e760, 0x2fbdf165, 0x00490801, 0xde8d179e,
-       0xe38456ed, 0x6e67065c, 0xf08d9ef8, 0xd918064e, 0xbfefff72, 0x25f5c22a,
-       0x8c0ee3b0, 0xbd0d43c4, 0x5c75d79b, 0x9fcd7114, 0x77d1d704, 0x98809679,
-       0x55706b80, 0x00e207b4, 0x3c636a9a, 0x679e3e62, 0x2e990e86, 0xa6f1c804,
-       0x01529bb5, 0xc0228a8e, 0x78074439, 0xe3ef14a0, 0x245f041b, 0xa4ef39a7,
-       0x67c8b9df, 0xe7c72fcc, 0x35b03245, 0xe99432bf, 0x7ed77bc6, 0xbf1ce787,
-       0xce91a203, 0x8f4a803f, 0x2e5c4c03, 0x19bdbb04, 0x3f233ffe, 0x1812bd4d,
-       0xf0619f90, 0x605aba1d, 0x25a9ccd7, 0xa7e92b00, 0x061dfb4c, 0x196fd890,
-       0xb2957f70, 0xe57cb2bf, 0xf08b10a5, 0x2040fd56, 0xa70fbd9b, 0x7fd5fff1,
-       0xf198376f, 0xda53f57c, 0x530f427d, 0xfbe52f90, 0x77b3f03a, 0x3de277eb,
-       0x235ef853, 0x8499fddc, 0x697636ef, 0xc7245fbf, 0xe0e60d24, 0x3828028f,
-       0x916db12d, 0xf1366bde, 0xdf4ae6f7, 0xea097bbd, 0xc925e9b1, 0xd1adc46e,
-       0x00e2d3dd, 0xa83983f9, 0xf2f1d4e4, 0x7a8cda6b, 0xa7c30c2a, 0xbdf34b76,
-       0xca175f74, 0x5e319ea8, 0xe2c960ce, 0x5f1c2cf8, 0x0bd7c573, 0xf735f101,
-       0x7ed0d0e8, 0x1146cf00, 0xcf3c08e4, 0xf2ae31ed, 0x07f4c39a, 0xfcc79c2d,
-       0x66132f9e, 0x1d75f2e7, 0x1ced01d1, 0x98bf702f, 0x093e8021, 0x60b541f1,
-       0x5f4b8edf, 0xc925724f, 0x9f004fbf, 0x589ec05c, 0x5cfd4264, 0x7da39fc1,
-       0x8fe02433, 0xe11d6c94, 0xfdc8a859, 0x7c7fd28a, 0x8b77e023, 0x434f167b,
-       0xd750e00a, 0x0cd43eb2, 0x0c6d906c, 0xe8f012df, 0xf17d2f49, 0xa416f4ce,
-       0x604932f3, 0x1f17dff6, 0x7f10161a, 0xd0b4455f, 0xeff7b026, 0xbe55f7a4,
-       0x74cef4fa, 0x8e6be337, 0x26f51065, 0x4e902e38, 0x47978f47, 0x183aae58,
-       0x712bf554, 0x9c7f2177, 0xfb3edd2b, 0xd1dbf412, 0x223160a5, 0x684b97bd,
-       0xabc30838, 0x49ab8fdc, 0xae5133d6, 0xe8813f82, 0x6e17966c, 0xe4bbf191,
-       0x97417bd6, 0x1d372118, 0x2f5533f7, 0xd3c71caa, 0xf72de2a1, 0xd1bf903b,
-       0x9fb3021d, 0xecccbb46, 0xe4fcb1b3, 0x7f104b83, 0x0bb25fa3, 0xeeb2cf48,
-       0x7e4847bd, 0x403b6b1d, 0xe7401e77, 0x2eb66eda, 0x527d9933, 0xd98be31e,
-       0x414688ad, 0x6056ad7c, 0x7c35a7c6, 0x0c7be61e, 0x7c3f51bc, 0x3804ce06,
-       0x9e7ceb18, 0xfbf35bf8, 0x1096fbcf, 0xe3ca1bb5, 0xad901f99, 0x3fa61b9d,
-       0x466000df, 0xa3db43fa, 0x3c304fbd, 0x6125af68, 0x27b13d7b, 0x9e0b70eb,
-       0xcf53789f, 0xc55f75cc, 0x416ea7c3, 0x68f6cd78, 0x0913e726, 0xf3a549e0,
-       0x3d7ba627, 0x18a56178, 0xb9216fea, 0xb7d8c677, 0x47f1f9e3, 0x13bb3fa7,
-       0xa767dae1, 0xf24c89d9, 0x7de5191f, 0xda011d3c, 0x7d953e7f, 0xef1c2907,
-       0xa52fc50a, 0x57dc6667, 0x24cfe74e, 0xaa8f09da, 0xa347a1bf, 0xfaf2801c,
-       0x16797c12, 0x8293bd34, 0x87c45067, 0xc79dc4eb, 0xdbcbb404, 0xc483ae0c,
-       0xfe47eaf7, 0xf90ca87a, 0x37e67aa9, 0xfa44cf0f, 0x0c9bdf6a, 0xaf584ef4,
-       0x6c40e2e3, 0xdffc9720, 0x915ffdc6, 0x288edd4f, 0x7111c7cb, 0x5e23a1a6,
-       0xa7753703, 0x888e3e5a, 0x65c07537, 0x8e82f50c, 0xfc57a9f8, 0x1d745eaa,
-       0x201aba25, 0x8422e3c0, 0x0557640c, 0x78a0e092, 0xc8c7ba10, 0xced63fe4,
-       0xd1916546, 0x8b822f51, 0x224179e2, 0x6fc85298, 0xc17e5c5d, 0x713fa67b,
-       0x9266ca17, 0xfbf54135, 0x223385ac, 0xf1bfb3ed, 0xcdcfb215, 0xc39f6646,
-       0x8d2f3c51, 0x391ff3c5, 0xc2bf7d9e, 0x87f305f4, 0xf5a4f933, 0x17385adf,
-       0x0aef141c, 0x9bc2e4da, 0xf4516d70, 0x29c52c72, 0x1dee4958, 0xc03aeff7,
-       0xe6f5b9e4, 0xbf7784a3, 0x0e0fe999, 0x0507b970, 0xf7d5279e, 0xa0429856,
-       0xb77a242b, 0xfdd57a31, 0xf3872dc1, 0xe0fef85c, 0x8079390b, 0xf24cbcf6,
-       0xe505fe0f, 0x7fc62a73, 0x3b5c36ec, 0x853bbff7, 0x7a58e0f2, 0xd9475beb,
-       0x2c3c2a7b, 0x4f5438f0, 0xf7fee07c, 0xa264ce99, 0x8b08c313, 0xcd77030f,
-       0x2b9bf260, 0xfe91c6e5, 0xf4b42783, 0x7d53a58d, 0x7d4fa55f, 0xcd37bd5f,
-       0x8e39322a, 0x9479fc18, 0x90cc5ff7, 0xc48d7c35, 0xcde2f3fa, 0x75e16fb4,
-       0x11c20244, 0x3f4356f6, 0x2635bf51, 0x5f48db8c, 0x6f608d4d, 0xa1efb603,
-       0xcfab89b8, 0x29f5e785, 0x03722b2f, 0x78ed09a7, 0x906762b1, 0x6eecc894,
-       0x5ebb7011, 0xabedc4ac, 0xe80f43a0, 0x75c4472f, 0xfda035bf, 0xa03c770d,
-       0x5dc64577, 0x74f151cf, 0xbb8f4fce, 0xa6c84a9e, 0x31623df8, 0x9e66bab3,
-       0x7bb1d055, 0xf74e90e9, 0x43eedcf0, 0x1a74f03b, 0xcf486ded, 0x8173a2e3,
-       0x6f53e515, 0x1f91e5f0, 0x2e3ddfa8, 0xb0fed8ba, 0xe9056070, 0x3cbe741b,
-       0x1bc4ef56, 0x233ac040, 0x77eed938, 0x25f65d50, 0xd412b8b0, 0xe2274d43,
-       0xdd12aa2d, 0x3c70e69d, 0x5167e354, 0x5ca3ee0e, 0xf55f682b, 0xa29bb457,
-       0x30fded7c, 0xb8f85a3f, 0x515dfb95, 0x98eee8a2, 0x576e5fc0, 0x1d06dcf4,
-       0x9e67f712, 0xb914cb47, 0x4522dd63, 0x4a8d2dd6, 0x9ac60f9c, 0x53f2123c,
-       0x82f51bb6, 0xb7ce9970, 0x028c5697, 0x9dfa8ad0, 0x5efe3e05, 0x539e36b7,
-       0xf2ca590e, 0xcbcb0e72, 0xaf7514b3, 0x7a40dc17, 0xc2fe5135, 0x2fc12ef5,
-       0x082bfad1, 0x1601d5b1, 0x06a8ad1d, 0x2701ceb6, 0x9b81e75b, 0x9da1f3ad,
-       0x83a00bad, 0x9f8297ad, 0xaf8170ad, 0xb83e580d, 0xf98832dd, 0x52bd7e18,
-       0xb45cbca4, 0xfc7ae264, 0x675e4571, 0xf9460797, 0x8f2f9f92, 0x614ae079,
-       0x2e4d9d74, 0xdd99b353, 0x923172ab, 0x5177e27d, 0xb5a14de0, 0x9dec0202,
-       0xf190c98b, 0xeb20d99d, 0x0702ae08, 0x48fee783, 0x5c069479, 0x04ee573a,
-       0xd89aa972, 0x7628764e, 0x5d364c52, 0x87d7d61c, 0x54171e56, 0x49d201bd,
-       0x3ebc60f9, 0x2ce88321, 0x5cfcae8a, 0xdaf190c6, 0x3a9df7b6, 0x8545a38c,
-       0x84362d95, 0xe53f590f, 0xf3e55970, 0xd91f0899, 0x9ba9d276, 0x595e7649,
-       0x1563b7a8, 0x39d86eba, 0x184dcf07, 0x4e50a3fc, 0x52824d92, 0xb1515d5c,
-       0x677e8079, 0x74ebac94, 0xdbc657e8, 0x5719c580, 0xd59f8014, 0xe46568b3,
-       0x7ebc3527, 0x7ae1635d, 0xbd706bdb, 0x60da7e4a, 0xc8cac5f2, 0x73759ad3,
-       0x6e5f2993, 0x3ff7f030, 0xbce72c9a, 0x22327282, 0x9841533e, 0x44f73c4f,
-       0xe4101c21, 0x186b5696, 0xf7c08fff, 0x77c21fcf, 0x5deb8a6b, 0x594dcf16,
-       0x534ffa40, 0x676779f2, 0x245d8a59, 0x3f8616fc, 0xd2d59310, 0x5207478a,
-       0x7bd21f9c, 0x776e18c1, 0x5eb95a1f, 0x329ab6ce, 0x27581f1d, 0xfbae0fd8,
-       0xe28f977a, 0x084827d0, 0xd599f3be, 0x34744035, 0x428c8189, 0xd11dd7d4,
-       0x27640cc7, 0xa80b1daa, 0x7fc8a5bc, 0x06bc039b, 0x96e51fe6, 0x2d98f533,
-       0xe5c107ec, 0xa5ca1ef8, 0xd2ace9c8, 0x8d4971e3, 0xa5ad1f7b, 0x3c2af6ae,
-       0xa2413c21, 0xad0a49a7, 0x1538bb20, 0x13e19eff, 0xb953a7e6, 0xabf12a3d,
-       0x6def4f67, 0x42741c69, 0xed361f84, 0x0fabe6f9, 0xa34ddf50, 0x0f5d3b66,
-       0x1696dffb, 0x1ab00bea, 0xd517c4d4, 0x1b75672f, 0x955fd47d, 0x397f3eed,
-       0xaf78abdd, 0xfa7146df, 0x1b40fee2, 0x9ec1cb95, 0x2fdc69c3, 0x6bfe3ad4,
-       0x93e4e7e1, 0x750512b9, 0x905ecbac, 0xabe446bc, 0x050bea99, 0xdc7c20f6,
-       0x47137684, 0xa9bf79f7, 0xbd0d95f6, 0x2fa819af, 0xc43c67c1, 0xff42ad6f,
-       0x5c37adaa, 0xad62f54a, 0xd62fdb57, 0x13d77bf5, 0xb43b75dd, 0xd9bf6afb,
-       0x4f5f7ca4, 0xea8d9af5, 0x26bded3e, 0xa8f337ea, 0x67eed3fe, 0xa6fd2a66,
-       0xa940ff92, 0x772a5733, 0xeb333f88, 0x235e0cff, 0x68fcd6f2, 0x7042dd8b,
-       0xe2ced9ba, 0x6606fd6d, 0xd87deac7, 0x446cc89a, 0x8ddadbf5, 0x5567eac0,
-       0x1b4ff98e, 0xfc8fa41d, 0x5d5993a7, 0xab3cf58c, 0xf09e3047, 0x22651efe,
-       0x173ddda0, 0x1114ca1f, 0xd93d73cf, 0x5fb7aa76, 0x7f80eb5e, 0x4fa6179d,
-       0x4ae7f7ad, 0xd40cab3b, 0x7d88dd47, 0xf7356e14, 0x4266d93e, 0xd01379b8,
-       0x3b2d240d, 0xe2a6ea8e, 0xe97812fd, 0x503ef01d, 0x1a976b8e, 0xbeb0524f,
-       0x9447908f, 0x09e4093c, 0xa2a379fa, 0x04ece8b7, 0xfd8c79cd, 0x71f7cd1c,
-       0xefda99a5, 0x6e7f0e3d, 0xfe73c509, 0x02e3bc7d, 0xc136fdcd, 0xcd91f76d,
-       0xbc3ff004, 0xb188ae57, 0xcd82bfc2, 0x17e7121d, 0x886fee68, 0xec9fb79d,
-       0xdd0bfcbb, 0x4b703b18, 0x01657764, 0x2f504780, 0xe7b586b3, 0x21db07c5,
-       0x1d47f116, 0x57998dd4, 0x16ea8078, 0x5fddaca3, 0x54c5daae, 0x4399aa98,
-       0xb73b919c, 0x9121d1fb, 0x9c0945d9, 0x117970f7, 0x5e0f59c9, 0x46dcbc79,
-       0x66fba569, 0x598bf303, 0x8a762dbd, 0x5a9d9347, 0x68d727f9, 0xd2ea9fe5,
-       0x956d3bca, 0x6ee9de56, 0x6dcfbcad, 0xead7cad5, 0xb6cfcad1, 0xfee69671,
-       0x0d4af6b4, 0x02f37d3c, 0xbdf3fdcd, 0xce70350b, 0xf734ab8e, 0xd32c7467,
-       0xaf77e79c, 0x76ab9cd6, 0x2e0ed636, 0xb18f35f4, 0x08c41133, 0x567aabfd,
-       0xff70a0ed, 0xff3c1aad, 0x1f6ffd6f, 0xc8a7ffa3, 0xbdde31d7, 0x37743b15,
-       0xd165ebb9, 0x999dae3c, 0x59eb9427, 0x9cb6f6bf, 0x77431558, 0x54e6fc95,
-       0xff941bf2, 0x0e16c391, 0x7df6fddb, 0x8e0acf14, 0xae88ab38, 0x1f7b80a2,
-       0xa192f385, 0xba38aaf6, 0x32d900ef, 0xe89c8f85, 0x02a5e5fe, 0x857e34e8,
-       0x3cb094f0, 0x93acf0af, 0xd972f0e2, 0x1636de77, 0x4be9c96e, 0xa120f3c2,
-       0x6a85e794, 0x22e81447, 0xeca152e4, 0x29e92503, 0xf3abf961, 0xc007ec23,
-       0x6880fd40, 0x2759b6f2, 0x9bec77aa, 0xb98f5625, 0x86f67d58, 0xa57362e0,
-       0x067f2645, 0x25dff7c5, 0xc4cedebb, 0xb44a76b8, 0x139eaccb, 0x54c46d02,
-       0xa4a31890, 0x76afa9e5, 0xed871f50, 0xff2bcd2c, 0xb56d4774, 0x6f919727,
-       0xb6f09409, 0x67f5fe99, 0xa2648eba, 0xcb0407fc, 0xf6fc42fa, 0x332759ad,
-       0x25197f28, 0xcd014494, 0xe9471c4f, 0x24dcccfc, 0x78c3f919, 0x0f65101b,
-       0xab73c289, 0x9390fac0, 0x08ccd8f4, 0x67a8ddff, 0xbe940b79, 0x5e451aec,
-       0x54b65f6a, 0x4f803fc1, 0x7e78c2ac, 0x4c1bf74d, 0xc329752e, 0x6dca1cca,
-       0x37fbe0b7, 0x5017354c, 0x428e0a5f, 0xd5e7ef3b, 0xfa4d2d3e, 0xed557929,
-       0xbf76cf6b, 0xd348652e, 0xc4cec32f, 0x6391e709, 0xbe615ee7, 0x9b03fbf9,
-       0x1a1e59a2, 0xe6ce94d8, 0x4ff7e18b, 0x71aff7b1, 0x93b1a3bf, 0xd7df5aeb,
-       0x9ef5dfd8, 0x81e7348f, 0x0d3e90a4, 0x4aec0ff9, 0xca35779d, 0x6305e46f,
-       0xa8abf509, 0x715b38b7, 0x3dc0fdf8, 0xbe10e7d3, 0xa7e7cdff, 0x6bfdbe4c,
-       0xa6ee6cfd, 0xed6c79f2, 0xd6070611, 0x963ad806, 0x55bfb54f, 0x20dfc357,
-       0x90e5ea9b, 0xd13ec930, 0x1b31e6bc, 0x67fa83ef, 0x7ca4a94f, 0xd06e9fdc,
-       0xc38b35f1, 0x0e26a5a9, 0x6b4f9bcf, 0x48de6f50, 0x00bf6dfd, 0x61ed010e,
-       0xec7ce0a9, 0x3abbe47a, 0xa36b95d9, 0x2875727a, 0xd0fe874f, 0x56b81f94,
-       0x1ebe7d40, 0xfe27caef, 0x53062c05, 0x599d1813, 0x890c37d4, 0x63013c9e,
-       0x764f4dc1, 0x3ffd5357, 0x8a73c934, 0xadad7632, 0x83fa9aab, 0x8ff70321,
-       0x847c9e5b, 0x16b7c3f9, 0xe77a4cd7, 0x31f24113, 0xf0497e7b, 0x16f6676e,
-       0xf88c2c30, 0xaf3a82bb, 0xfa9b7ea1, 0x5f14609b, 0xdff8db67, 0xacc72a5f,
-       0xae3c6d4b, 0x316b42dd, 0x2ceee5e9, 0xe8ca7bfa, 0x5f902366, 0x48873e20,
-       0x5cf87af8, 0x40f20a76, 0x6f560d75, 0x78285fac, 0xf8a3e8d5, 0x1675cea1,
-       0xbdecacdb, 0xd79f1b24, 0xf467dd24, 0xeefcb1b6, 0x3a46a8cf, 0xef58f5db,
-       0x1070df50, 0x846d1cd8, 0x7a1161e6, 0xfde36c59, 0xc008dc17, 0xd1b793cf,
-       0xc0ef4379, 0xdf278a31, 0x24aeba67, 0x72880c39, 0x8693c509, 0xdeacbdd8,
-       0xecc9b66b, 0xf197a43b, 0x4ee1718f, 0x382fcfd2, 0xfa455c0f, 0x7805306d,
-       0x03ccaadd, 0x91b726cf, 0x7287fee5, 0x9ecbfcd9, 0xf4a9f441, 0xb6cdfd22,
-       0x4a9db988, 0x1f9df87f, 0xae750bf6, 0x5b83c2a5, 0x9f916436, 0xbcf85ea1,
-       0x5bae1251, 0x0ff7c138, 0x963efa2a, 0xfe10f4e2, 0xf73e6ed5, 0xfb4ddb0b,
-       0xcf4947cd, 0x271666bd, 0x58fdf6cf, 0xf4f61b3e, 0x9f207932, 0x117f12d7,
-       0xc91bde7c, 0xe1cf48e7, 0x9fe57287, 0x9d305fcf, 0xb8291dff, 0x190c9bed,
-       0xfdd86fbf, 0xbbb211c6, 0xdf1e7506, 0x18339da5, 0x9aff6127, 0x1d1cd130,
-       0x5d444fb3, 0x9fbf5466, 0x8f7ed3aa, 0xa9cd3905, 0xa9dfc9bb, 0xbff0717e,
-       0xb8f9a98b, 0x846be94b, 0x1f2cebc0, 0x87f23e10, 0xe58782f5, 0xd18e7545,
-       0x23de6026, 0x585abadd, 0x35ce909e, 0xbb9ec9db, 0xe4fd06d0, 0x34473a07,
-       0xe98f5f9b, 0xb835bfa3, 0xd6fc9176, 0x4c9953bc, 0x9be7767d, 0x8d7e940b,
-       0xc562a9e7, 0x3f098b2e, 0xc71b9fd1, 0xa148b5ec, 0xf584c4af, 0x7c852650,
-       0x15e7c48f, 0xd363fcca, 0xef3e9aeb, 0x685932bf, 0x001e0053, 0x00000000
-};
-
-static const u32 usem_int_table_data_e1[] = {
-       0x00088b1f, 0x00000000, 0x51fbff00, 0x03f0c0cf, 0x1915c58a, 0x19d44418,
-       0x18344c18, 0x20685618, 0xb58969c4, 0x9fd329b8, 0x90c0c2c9, 0x40b9c40d,
-       0x7cc40f9c, 0xfc0c0c4c, 0x17ebc44c, 0xf5b04514, 0x84181904, 0x026ffc80,
-       0x85d70c0c, 0x8bbe1818, 0x03083030, 0xf1402ef9, 0x01ce2004, 0x58a06f62,
-       0x045e900b, 0x2c40ddc4, 0x7cdf8a22, 0x6bf20251, 0x37f95185, 0x847bf8d1,
-       0x1057ebf0, 0x47af2fc1, 0x161b1e40, 0x3e3f22d1, 0x3bd02922, 0x015f5810,
-       0xc7265f95, 0x0f27d0c0, 0xb8a87f8c, 0x4bfc9201, 0x0e5cbb20, 0x6096f6c2,
-       0xf2062860, 0x9bb0150d, 0x2f9403eb, 0x857dca01, 0xcc0003ca, 0x688cbacc,
-       0x00688cba
-};
-
-static const u32 usem_pram_data_e1[] = {
-       0x00088b1f, 0x00000000, 0x7de5ff00, 0x4514780b, 0x74f570b6, 0x9924ccf7,
-       0xf2124c99, 0x00493de0, 0x210e0311, 0x9970c044, 0x46a2c024, 0x141a020d,
-       0x84920275, 0x7e889790, 0x33feaeec, 0xa8a08901, 0x17acb9f1, 0x376141dd,
-       0x0c06e8b2, 0x60e03518, 0xba2eb300, 0xe7c045c1, 0x36bc8026, 0xb9f04324,
-       0x9d6f5ecb, 0xdd33d553, 0xc7c4099d, 0xffef7fde, 0xa55f9f8f, 0x71ebaaba,
-       0xe9d4e7de, 0x278f3242, 0xdf210a64, 0x9f968fc1, 0xf890848b, 0x206f5950,
-       0x8841922e, 0x6df466d7, 0x88cfa64c, 0x68e67a23, 0xd11d985a, 0xef435837,
-       0x9ed5cbe9, 0x186934a4, 0x1c790f21, 0x23e21258, 0x5ab54e84, 0x16f50520,
-       0xe0933ba8, 0x213e3a7d, 0x0ff8e8fd, 0x30f8e246, 0x1a18992d, 0xe0311067,
-       0xf9ad537b, 0x421eb089, 0xc3e6476a, 0x213b16fc, 0x9f9f7bfd, 0xa7eb888e,
-       0xf7c10def, 0xb59efa24, 0x6529efef, 0x13fd0e57, 0xf66ddff6, 0xf108146d,
-       0x71c7fcef, 0x8699ef58, 0x5d130e39, 0xd9b7766f, 0xbeea053f, 0xb6899f6c,
-       0xc0fb6ee7, 0xe5fed126, 0xda0944db, 0xf0233b0d, 0x8275cefd, 0xa695ea0f,
-       0xa4ae47d6, 0x9136c0f5, 0xf8d30f3c, 0x4092062d, 0x613371c8, 0xeb15873f,
-       0x5aac1145, 0x6dd77ebe, 0xa3495f30, 0xf7d04489, 0x2e88378f, 0x28d92fa8,
-       0xaf9d08f8, 0x8c07b5fc, 0xc578e803, 0xc23ea13e, 0x1f1beb41, 0x3ee83a33,
-       0xd8fcef97, 0x7ce146d6, 0x0e2663da, 0xa4a3ee23, 0x52908d3e, 0x03e996df,
-       0x9ba5fbe8, 0xbe802705, 0x4ed9dd74, 0x83695f58, 0xe3a45c3c, 0x228bae2d,
-       0xee6c918e, 0xd7cc08ef, 0xdbe7147c, 0xf9830f26, 0x65dfce4a, 0x6ee52404,
-       0xca2e9193, 0xdf603ae9, 0x3da7bcca, 0x053e716b, 0xd22fe59e, 0x8abf68f9,
-       0x6c270597, 0xdc40c2b1, 0xd7ce8eb0, 0xb05e0a22, 0x8daafec0, 0x7deaac23,
-       0x7d876e14, 0x1bd6fa94, 0x7d605ba7, 0x69458deb, 0xd716f1a1, 0x7d76a7fd,
-       0xdd13536b, 0xf3e3bd69, 0x748287b4, 0x4a5ea844, 0x4fe90b88, 0x8e8119f2,
-       0x85e7e795, 0xe2f7c418, 0xcc38913a, 0x3a15f1a1, 0xe9c07ef0, 0xf1958774,
-       0x12dbc701, 0x842ce03b, 0xc73b6eb7, 0x54c814a3, 0x8f94af8f, 0x7ae83e00,
-       0x2c763d6a, 0x6124f71f, 0x81c7a4f9, 0x33da7b70, 0x1eb5cb12, 0xc67f3e27,
-       0x75cb0133, 0xcf96171e, 0xe9606679, 0xbf63e4f3, 0x58053de7, 0xf1b8f06e,
-       0x253d6ff9, 0xaa79d658, 0xcf26f9f0, 0x7b372c32, 0x65fcf8bc, 0xeb2c2acf,
-       0x6e58b53d, 0xb2d17c05, 0x7ec3e3c1, 0x58753ddb, 0xf1ea7a36, 0x469eebf9,
-       0x3870d72c, 0xb648b2da, 0x7360e144, 0x3b453b11, 0x6573cd89, 0x9b1eb4cb,
-       0xf309eacf, 0x5a46d9bc, 0x3ad3704f, 0x3280cb85, 0xd689b67f, 0xf6b15407,
-       0x1c92f721, 0xf10fad33, 0x3594f6b2, 0x5a089cae, 0xed65a94f, 0x7379d623,
-       0x847d6922, 0xda8fb58f, 0xa289cfec, 0xacf551f5, 0xc9134c7d, 0x18fad0b5,
-       0xefa7ab3f, 0x695ae573, 0xd595bd3d, 0xe6f13f33, 0xb33d68da, 0xa93fbd8d,
-       0x2c3a27c3, 0x55b0f13d, 0x14202c76, 0xb9de4d57, 0x9bca892e, 0x5dc746ad,
-       0x7bc849c4, 0x892ef9de, 0xd90687ca, 0xde6ded85, 0x746eacc5, 0x77b77b61,
-       0x2edff629, 0xaa5db1bb, 0xb7db0fbe, 0x9ed8dd1b, 0xed835d50, 0xdb17b28d,
-       0x8a3f5647, 0x2f468ded, 0x5eaa4fb6, 0x65d7f58b, 0x55e7b61f, 0xaffec7af,
-       0xfed87d1b, 0x5c9bfdf8, 0x05fd6953, 0xe41dbdc1, 0x5dc10ade, 0x9e815242,
-       0xee4093ea, 0xf9f970d5, 0x6d1d101c, 0x446fe9af, 0x6efadc3e, 0xbfc00be6,
-       0xf507ebf8, 0x983edfa2, 0x89bce38c, 0x1c74c8e3, 0xa4e3e2f1, 0x334137bf,
-       0x257bfa4e, 0x382d38ca, 0xc6df444e, 0x24defad9, 0x2bde7aed, 0x0fd9c655,
-       0xdac2b4fc, 0xffa57db7, 0x9ebb4b39, 0xe329973f, 0x89eb847c, 0x1a7adbe9,
-       0xa7c2d03e, 0x7c2083e1, 0xf138e28e, 0xc64f5b7d, 0x327c2d41, 0xd3e1060e,
-       0xeff4e381, 0x070d38db, 0x3869f0b5, 0x97cf8418, 0x7dc19f08, 0x21c657db,
-       0x0e327c2d, 0x5ff3e105, 0xbee49eb8, 0x53fdb38d, 0x7fb67c2d, 0x498f841a,
-       0xef0cf580, 0x3f32bedb, 0xf327c2d3, 0xec7c20b3, 0x7da5ce38, 0x67fb671b,
-       0xff6cf85a, 0xfe9f082c, 0xbee8ce38, 0xaff32bed, 0xfe64f85a, 0x149f0835,
-       0xb633e001, 0xfc69eb6f, 0xc69f0b5c, 0xb9f083cf, 0xdf19c70c, 0x384cf5b7,
-       0x84cf85ae, 0x64f841e3, 0xf626bee0, 0xe3c69c6d, 0x1e34f85a, 0x3267c20f,
-       0x6fb9338e, 0x42709afb, 0x27099f0b, 0x8e99f082, 0xebbb64e3, 0xc7465198,
-       0xce3ef6b1, 0xf0b467eb, 0x104cfd79, 0x38e3d73e, 0xa938e8d3, 0x52671f17,
-       0x933e16a7, 0x29f0833a, 0xeaae71c0, 0x77af38db, 0x7af3e16a, 0x853e1067,
-       0x7db5ce38, 0x2ea4d7db, 0x75267c2d, 0x3b8cf831, 0xa36b9550, 0x3a1754ed,
-       0x95cafa45, 0x40972e1d, 0xd59da2eb, 0x8093bb45, 0xf62a225d, 0x89756906,
-       0xe6cb7df4, 0x8907f498, 0xb9c8eeda, 0x4ac7e813, 0xddb531ad, 0x52213d11,
-       0xb8c4e763, 0xb8f53562, 0xfd340319, 0x3453f3e3, 0xa30589ed, 0xddfded34,
-       0xc0fa9ae9, 0xfe9a4992, 0x3472ab83, 0xaecba1f5, 0xf64ff4d6, 0xa7a9a0de,
-       0xd359baae, 0x7ced787f, 0x6b25fb4d, 0x97ed354b, 0xea6896fa, 0x42fdd597,
-       0xfd747fd3, 0xe5fb4d72, 0xda6a0f8d, 0xd71ffac7, 0x3cb5c7d4, 0xbe3fe9a3,
-       0xfb4d79f5, 0x69378715, 0x6db627da, 0x3cafd4d5, 0xcecebaf9, 0x5f8fd8b3,
-       0xd022ebc6, 0x7f76613d, 0xf8f7e67f, 0x1bac46ad, 0x8ed05807, 0x722d65df,
-       0x35f8a31c, 0xd1c0b5be, 0x7017e28f, 0xf6457e0a, 0xda4b9280, 0x267bf3e8,
-       0xd3b12fb9, 0xdd18f7e7, 0xd8c3db97, 0x041e94a7, 0xc3a50492, 0xfdbea500,
-       0x63d19901, 0x23f3c0ce, 0x95fbe9da, 0x1888c086, 0xb312cf5a, 0x777e811b,
-       0x8a2fcc0a, 0xf4154914, 0xf411348b, 0xce481e0b, 0xa2abc17c, 0x298355d7,
-       0x71a10a1f, 0x24eec957, 0xaade33b0, 0x1d82f76e, 0xee983352, 0xcd21006b,
-       0x4bdfbb42, 0x0607b4fd, 0xe9b92517, 0xb5232678, 0x1bf3d5d3, 0x3869fce9,
-       0xebd00b7f, 0x7c7f307b, 0x294df9cf, 0x9bf33413, 0xe6689487, 0xfce91b37,
-       0xafde4276, 0xa7e7c53e, 0xc8449848, 0x3853845f, 0x094869bf, 0x9180ffce,
-       0xf9ea2bfa, 0x1ff38323, 0xd67ffd86, 0x2653fedb, 0xa43ff769, 0x237fbb54,
-       0xea91ffdb, 0x48fe7cb3, 0xe151ffdc, 0x90ffdb2c, 0x137fb652, 0xbf38371b,
-       0x93ff082d, 0x2f677f30, 0xb3529bf3, 0x5a1ffbb4, 0x89bfdda6, 0xfd5ddfcd,
-       0x82df9f2d, 0xbe139ff3, 0x5a1ffb65, 0x4d1bf386, 0x8fd0276e, 0x95646071,
-       0x1d4fce8f, 0x04490761, 0x40f3a172, 0xfd163239, 0x148497e4, 0x913dc75c,
-       0x8abede8c, 0xf286f4a4, 0x58fccbc6, 0x996c951f, 0xb4e2efd4, 0xb67378be,
-       0xb612e411, 0x21657f53, 0x8d1dea5f, 0x7937d222, 0x4e1be4d2, 0x28d9dbd7,
-       0xc77ea17a, 0x207d9393, 0xe44d2aff, 0x4f787cf6, 0xfe787e22, 0x9fa353f9,
-       0x5f4bef57, 0x8f95ac2e, 0x2df8a9b7, 0x90e547e8, 0x98165591, 0x1fa9aed7,
-       0xa1107ea1, 0xd427c5fe, 0x249420cf, 0xbe6cca8f, 0x04bfa8cf, 0x2fea36f5,
-       0xd5213b41, 0x75e25fb8, 0xae8c307d, 0x3f289f3f, 0x26f3ee17, 0x9e3a2964,
-       0xc8f7f8c4, 0xf807c11a, 0x14597db8, 0x3d687e05, 0x4d38de85, 0xfb0fee9d,
-       0x7c12ae07, 0x86380bcf, 0x9333e01b, 0xbd60478f, 0x67605eb4, 0xe8a21cef,
-       0xb0514fef, 0x8a40d560, 0xb338d08b, 0xa44e4b88, 0x5a59cfef, 0xa2e84328,
-       0x2f061055, 0x2059fa01, 0xe0119753, 0x69278de7, 0x7ae8389c, 0xf1b3b66f,
-       0x63e4ba67, 0x14f5aa6d, 0x3e5766c8, 0xa1414f5d, 0x359feb88, 0xd1fedb43,
-       0x619728ce, 0x3d572d0c, 0xc9ccf381, 0x54dfb6d7, 0x75cfada0, 0xef54eb6b,
-       0x6ef7a0c9, 0xa73fd129, 0x9cfba160, 0x5d2b8417, 0xade75d28, 0x56b70e1c,
-       0x5e0d5ec9, 0xda556dc1, 0x26e0a021, 0x5f7c2fb8, 0xf6ffd9ec, 0xa17ada65,
-       0xb05f5b57, 0xa73e374a, 0xff1ce39b, 0x683e8047, 0x83e80279, 0xa718f3c2,
-       0xd55c908f, 0xc18dc7d2, 0x50fa306d, 0x625c71f6, 0x8ebe3828, 0xdac2c7d1,
-       0x50f4f0a8, 0x9707a418, 0x7a14be9a, 0xc3d38db8, 0x8a1e9ca7, 0x6ae96ad7,
-       0x4cadf12e, 0xb2dfefa2, 0xe9e21766, 0xe8c850a0, 0x3d0a97e1, 0xc1e869b4,
-       0x8f41e9cd, 0x3d38dbbf, 0x4673f6dc, 0xb67c7a0f, 0x5b687a71, 0x29264e7b,
-       0xf14af13d, 0x3c53a9a0, 0x376ef0e8, 0x7c503d02, 0xf987a584, 0x8dd37dc1,
-       0xde02fad3, 0x9c5f03d6, 0x053db01e, 0x4e104ec0, 0xcf6a7ef8, 0x684e54fe,
-       0xc36bc5ea, 0x31b2bfe3, 0x6a98ee3b, 0x57f5e55d, 0xf5531dc5, 0x53375c5b,
-       0x9be45f53, 0xbc5fe9ab, 0xbed350b6, 0xa69176b0, 0x3baac17d, 0xef42f535,
-       0x6ffd35cf, 0x69ad565f, 0xb56ab5bf, 0x9296fda6, 0xb9f534c7, 0xfa6b5fee,
-       0x5eb054df, 0xff273ed3, 0xacfb4d45, 0xf5345b19, 0x34d7ae99, 0x2f3b0dfd,
-       0x31e81ebd, 0xc048a0eb, 0x71e638fe, 0xf71fdd20, 0xa4f2c48c, 0x717c89c7,
-       0xcb0133da, 0x4fcd8d7d, 0x7cbb495c, 0x26882819, 0x91167f4c, 0x2cf64218,
-       0xcaaf5777, 0x504e7d02, 0x7971feef, 0x1077b551, 0x07065395, 0xad6f39c2,
-       0x11c7f891, 0xe2528022, 0x50c407f3, 0x6d1b567b, 0x3dbdeb8f, 0xb614ad6f,
-       0x0a4dab3d, 0xe3e56e3b, 0x61ed4385, 0x7e2133e2, 0x3ec10326, 0xb9f6e2ea,
-       0x204cbdbe, 0x84e7eaf9, 0x8ffe472c, 0x5cfd3031, 0xa2726466, 0x1cff6b6c,
-       0x7fba8362, 0xe685d544, 0x95cca7ab, 0xaa91f408, 0xb5e2e3e1, 0x3ce46997,
-       0x3c6de881, 0xcd38d9d0, 0x5775c5f3, 0xd8ebde6a, 0x2bbae225, 0x7d508640,
-       0x07e48c3d, 0xfd97a00c, 0x8d6643cd, 0xceba7586, 0x355e401a, 0xd8fda3c6,
-       0x771199e1, 0xe63c024c, 0x53d27963, 0x8f71e580, 0x9e63cb1b, 0x788f2c12,
-       0xf36cb0aa, 0x33f2c32c, 0x4fcb178f, 0xfcb0ab3c, 0xe58b53c8, 0x2c5acf61,
-       0x587c7a0f, 0x61d4f01e, 0x1ea7bef9, 0x234f56cb, 0x171e9d96, 0x29bf0a96,
-       0xddd3d0f0, 0x4fa7ae49, 0x805dfd03, 0x07c4e2ce, 0x0a0d57aa, 0x8ae259d1,
-       0x59bdab87, 0xd6f371a1, 0x249d389a, 0x0861e868, 0x81e364f8, 0x5e9c4c5e,
-       0xade7b7c2, 0x9ed82f95, 0x1d8726d5, 0x7ff9f2bf, 0xf9cdbd0d, 0xa216f491,
-       0x7a3a81a7, 0x3d18bd4a, 0x87c7124d, 0xc18e69e8, 0xa71ff4ce, 0x1f6087a7,
-       0x628ffc61, 0xabc6ea30, 0x14573aec, 0x73f3678b, 0xb2d16a07, 0x7b9f3678,
-       0x15ae1d05, 0x48df3fed, 0xc8f773c0, 0x78808fbf, 0xaa61f77d, 0xdf7b9328,
-       0x7a5e9e9f, 0xfd0bbb87, 0x551f22a0, 0xb67ae3a2, 0xb8324447, 0x0cc81846,
-       0xeac84e92, 0xce75bfe1, 0x44bac34f, 0x9f7de162, 0xf3986673, 0x4f670228,
-       0xeb871789, 0x6357eb0a, 0xcfe3bc60, 0xca1323fc, 0xe6148639, 0x688b34df,
-       0x0bff13df, 0x506f804e, 0x499c991f, 0x0c0f0710, 0x3ed1da37, 0xf0b459f0,
-       0x667ad2f3, 0x29ab7e08, 0xdf515a8c, 0xfc2126d7, 0xa2357d86, 0x77e01f7f,
-       0x317f3931, 0x0df7ce78, 0xf3c097f8, 0x62f1f262, 0x1cb89172, 0xfdd2372f,
-       0x9d1ced77, 0xe403a0fe, 0xade185e0, 0xd7e95f9c, 0x7d28bcf3, 0x4aee3a2f,
-       0x75b8e850, 0x88f3a108, 0xefc71da2, 0xc984b86e, 0xdbeec52f, 0x05f5f266,
-       0xb59267af, 0xf9c53de3, 0xbbaf194f, 0xf81b05e5, 0x0c924b5b, 0xf06163f6,
-       0xf5e594a0, 0xda8b76c9, 0xd6d46cfe, 0x19856bbb, 0x3a2768f5, 0x068f67a2,
-       0x1fb7613d, 0x3b72061b, 0x9c654b09, 0xfb464925, 0x4ef72a31, 0x3346a5d7,
-       0xe4c7cf3f, 0x9418e6c1, 0x663da717, 0xaf53ffec, 0x9471b7a7, 0x40d210f5,
-       0x1e419a8e, 0xded4b6d3, 0xcf4af7fb, 0x3c4617d2, 0xbf926df7, 0x4cd0fb02,
-       0xfc0effff, 0x5d61220d, 0x5eb2b719, 0x872e9af4, 0xf3359be7, 0xca1cf7d1,
-       0x2977eb19, 0x891be217, 0x96e8571c, 0x5c638bea, 0x8bae2c9f, 0xcfed6bb0,
-       0xb2bd4d18, 0x635dbfb1, 0x541fc28f, 0x412a92fe, 0xe329fa02, 0x5925d3e4,
-       0x7d740956, 0x1090426f, 0xfd6056e8, 0x466dcdca, 0x95ce03b7, 0x5b7ade19,
-       0x4cdfc51f, 0x897c9289, 0x61cf16b9, 0x9d2fea4b, 0x4ce67a0a, 0x88048ac3,
-       0xbb162c1b, 0xf30fc9ef, 0x79312cbe, 0x0727c8bf, 0xa73df6b4, 0x55c7420f,
-       0x945c639e, 0xeaab8e58, 0x8f16061d, 0x009b8fd1, 0x1c5fc6e3, 0xf79b153e,
-       0x413b074f, 0xc68aa70f, 0xca3746b3, 0x665ffa45, 0xfc0a4e08, 0x13f314de,
-       0x697e3a24, 0x2dc63b5d, 0x11deca4e, 0xbc80bcbf, 0x4b3fb9ec, 0xd528f1d2,
-       0x15a4bcbe, 0x813f99e6, 0x371c444f, 0xf8e54c7d, 0x04c93fa9, 0x4f3910e4,
-       0x4862657b, 0x063bfb86, 0xf90cc862, 0x161bf33b, 0x4fbc01e7, 0xe547bf81,
-       0xdf241de6, 0xb5207886, 0x9cdfe099, 0x00198621, 0x7de433a7, 0x1e1538db,
-       0x87232572, 0x94829533, 0xf1c14c1e, 0xefc1fddd, 0xb4d41532, 0xb9e0638a,
-       0xc23ff8a4, 0x72471877, 0x50b7980b, 0x897b9ec0, 0x97e81ab9, 0x3f1a51fa,
-       0x9a51fa8d, 0x34a3f53a, 0x437222f5, 0x1425e402, 0x9f13293d, 0xb4d27080,
-       0x88ec928f, 0x555262c7, 0xafd1f603, 0xbe6dfc79, 0xe903489d, 0x7d5fcb3e,
-       0xee90b336, 0xc5896ae7, 0xf57394fd, 0x0e0cb145, 0xa33e25a5, 0x7f73d2cb,
-       0xddc61b47, 0x8c3f2548, 0x6fcfcec7, 0x051e6236, 0xdc994ab4, 0x7de949f4,
-       0xa20d89ff, 0xfd06c22b, 0xbd6573e8, 0xff7fdfc9, 0xf212fdfa, 0xb4a3ee38,
-       0xfa01266e, 0xc02791eb, 0x09d723f7, 0x7e185f2e, 0xaf74e42a, 0x013ba7e8,
-       0xf143e37e, 0xf574fbac, 0x4abe1cd5, 0xfb5d29fd, 0xfd2f960f, 0xbcbe4688,
-       0x93efba29, 0x027933c6, 0x00a417f0, 0x1e0fd7f2, 0xf8c7a93f, 0x7f1f81ab,
-       0x6907f1b2, 0xff8e9ef9, 0xfeba4fd4, 0xbfd63d61, 0xcbfadc3e, 0xbb697d5f,
-       0xd297ea97, 0x23653c3f, 0x494edf94, 0x8a4e09b5, 0x2b8db2f7, 0x3b902e6d,
-       0x7c06d792, 0xce27ca71, 0x870f4708, 0x06a57cb8, 0x78804588, 0xc749fc2b,
-       0xa1e9bd3f, 0xf89ec0eb, 0xc76ca36a, 0xc99d6a38, 0x5cf4a26f, 0x8f28b0d1,
-       0x3b7ac18c, 0x16703fab, 0x51b2bfe8, 0xd3a6a23e, 0x953ddfd2, 0x94357900,
-       0x921a0652, 0x7fa3f4a0, 0xf3e1b152, 0x546f60e9, 0xabf20092, 0xff983dfe,
-       0x87d4589b, 0x9ee8c685, 0x499818ed, 0xafd9f780, 0xb3a1e1b2, 0x6afe0da2,
-       0xbe9038c3, 0x37f7097f, 0x3f6b245a, 0x82b9273c, 0x54f2015c, 0x31f10781,
-       0x8bc5637f, 0x4ed31abf, 0xe1b1d3d7, 0x0541364f, 0xea4fc527, 0x9bf05fae,
-       0xcbbd1dd7, 0x87ca4eef, 0xd156bb6a, 0xee468e4f, 0xb2b13527, 0xaedbf64c,
-       0x6ca4f2a4, 0xd2f4ecbd, 0xbd2f65c7, 0x2067dbf0, 0xc9a1fd7e, 0xbf8e9c39,
-       0x073da5f8, 0xe2fad127, 0x3cbf722d, 0x908b0db6, 0x254bc210, 0x7a597ffd,
-       0xafa50f08, 0x463a31ec, 0xc6f7e7b3, 0x78b1f086, 0x19232ecb, 0xb91e13dd,
-       0x6d8cbbf5, 0xa9783096, 0x760e9f6f, 0xbf178adf, 0x3bbc8236, 0x892053b5,
-       0xb9e061c9, 0x85da0f7e, 0x23c42700, 0x6f1053c7, 0x1495feba, 0x145fa02f,
-       0x37dbe93c, 0xe3027971, 0x9e90d239, 0xce9d7e5f, 0xc991f25f, 0x792ffb09,
-       0xec1b2ef9, 0xc55484e3, 0x95d9fae8, 0x4adf2009, 0x1d826f64, 0xe4bcf64b,
-       0xde91bbb9, 0x9ddff78a, 0xae92e2c0, 0x95d406fe, 0xbfb0fede, 0xe0e6eb85,
-       0x1b888afe, 0x59e4aee9, 0xcb47df31, 0x6332252f, 0xb8be184b, 0xf2726656,
-       0x2354f3c4, 0x509dfdd0, 0x22fbc0f4, 0x627703d7, 0xbe6ef3dc, 0x62316a17,
-       0xc3334bfd, 0xc0d930d3, 0x2bd32ce5, 0xf0dd7a41, 0xd38bea00, 0x70895d83,
-       0xd21956be, 0xc437a80f, 0x1912d3fd, 0xc19e987e, 0xc99ea8f7, 0xbfd0e785,
-       0x8c457655, 0x7a87bcd1, 0x297f9945, 0x3bae9f9f, 0x13b5ec12, 0x8ffde109,
-       0xdf0acb9f, 0x4542bb53, 0x66fe2a5f, 0x3561befc, 0xdf856fe3, 0x4067337d,
-       0x180717fb, 0xa07bc0ff, 0xfcbae967, 0x6bbed889, 0xc0f280b6, 0xf8e1fc44,
-       0xf9cc837a, 0xd0aedb5a, 0x24b75d09, 0x05e8ab44, 0xf8458fc6, 0x7a2f5ea3,
-       0x92a7be92, 0x9f309597, 0x0a78e7ad, 0xfe7316df, 0xf96b219f, 0xef8bac9f,
-       0x99653e53, 0x33edfbec, 0x3f94afc0, 0x57e00ebd, 0xfdf61f39, 0x07cdcdb7,
-       0xfa7ca66f, 0x4f857ab7, 0xcf53f2b5, 0xef5b25a7, 0x7a9f4026, 0xa0dbfd3e,
-       0x4f96122a, 0x7cb0f3e9, 0x7feda83a, 0xf02a7e54, 0x45f802ab, 0xc8a7e085,
-       0xa8e0dec3, 0xd9568797, 0xd21e5611, 0xd99201df, 0xba14fe93, 0xf4ade853,
-       0x4143e5f7, 0x52e904ee, 0x5d20bba1, 0xdfa7742a, 0xfa7e16af, 0xc13249f6,
-       0x26bfe575, 0xd65cffa3, 0xe942f2c4, 0x66077b7b, 0xa85c9c20, 0xdeed48c6,
-       0x75d4fd81, 0xaf5eae9f, 0xd5d2efeb, 0xddfd75f3, 0xa6957aba, 0xb363597f,
-       0xfdfe2091, 0xb2e27e9a, 0xb8d1c867, 0x63eaf470, 0x59c3597e, 0xc2e817a3,
-       0xe5f7c012, 0x790bc4e5, 0x221d8186, 0x28ba05c6, 0x7e206b8c, 0xe7d939b1,
-       0x656372a5, 0x743f8b04, 0x58b603d9, 0x618cae5a, 0xb1bc40f5, 0xf29ee406,
-       0xe2c1103c, 0x01f95d8a, 0x9fca8c5b, 0x51126f6a, 0xc8f9b76e, 0x167e708c,
-       0x47c828d5, 0x76b7a46d, 0x4d35ee76, 0x06590cb4, 0xd15aa571, 0x1df83609,
-       0xe0d937d5, 0x29aba9dc, 0xfa02faf5, 0x451fe17c, 0x8ae97b4c, 0x75818db4,
-       0xea4baf11, 0x4e6ff2af, 0x59d3ef12, 0x9a0b7f74, 0xc7739f98, 0x423d9d1a,
-       0x153d20d6, 0x411a9659, 0xe27f529e, 0x86bcf688, 0x1f2945f1, 0xb69d64af,
-       0xd29f795d, 0xa5f3fa01, 0x6eedb41b, 0xa07f0fee, 0x3258c9f0, 0x2ca3fb96,
-       0xf2e5c30e, 0xfaed3134, 0xae8f8a02, 0x68989116, 0x4449bbbd, 0x166f747c,
-       0x234f107c, 0xb7e478de, 0x7940120a, 0x03a9c0a8, 0xbbd8c9f8, 0xf6d8eabc,
-       0x812fe669, 0x3c7fb66e, 0xd9693fe6, 0x11c3fdb1, 0xd5fd406f, 0x263e4343,
-       0xeee7fb3d, 0xff73c08c, 0xa4569dae, 0xef1daef7, 0xd425f90e, 0x6139335f,
-       0xbf3b5d9d, 0xd3f4031e, 0x0254dcb5, 0x306baef2, 0xd8aec78b, 0x3698f5f1,
-       0x33f7afd4, 0xfe6461fd, 0x3fd37761, 0x41fa133e, 0x76057749, 0xe428cec3,
-       0x23d7caa7, 0x6bbbdf30, 0x6e99d7c7, 0x9fb74fcb, 0xd1e79e0a, 0x5b052565,
-       0x2c317d61, 0x8df2a18f, 0xd3542f89, 0x761bcbf9, 0xf6d01719, 0x39ff37dc,
-       0xd768e406, 0x750f6656, 0x41cf6dca, 0xf194431e, 0xe29972dc, 0x8a9813ab,
-       0x33bfcd3a, 0xdf02e466, 0x3fcb84f4, 0x57d63e31, 0xaffca478, 0x62e08781,
-       0x33eacef2, 0x6fefb00b, 0xe318fb3f, 0x4ba4269a, 0xab7fbf65, 0xe57b46af,
-       0xfecefb62, 0x82df6e7f, 0x76fb2fbf, 0xfbef9bff, 0x7abbd738, 0xe749e83e,
-       0xfac1ee3b, 0xae27564b, 0xeef48fb7, 0xffc7fd85, 0x7bffeefb, 0xc52b7de3,
-       0xfbe2edbb, 0x5affcdfe, 0x36f1ffbc, 0x7e3b778e, 0x3fe6f3d7, 0x57df7d71,
-       0x6ff9bdce, 0xf6def78e, 0xadf5d8af, 0x067b2a86, 0xa9015f5d, 0x316182b5,
-       0x92dbbe37, 0xd76c80e1, 0x8f30fd73, 0xc34bce0e, 0x23014df8, 0x904d0bf3,
-       0xfb7e0747, 0x0b89411c, 0x1d751fa2, 0x1bae1fb7, 0xc8768254, 0x9987ae75,
-       0xb55520dd, 0xadfed366, 0x989c0b39, 0x0fd24973, 0x7b3ea1bb, 0xfd6baf32,
-       0xe204f7c9, 0x7f1da812, 0x2d35ce5d, 0xef5ed760, 0xa5eed112, 0x1fbbda25,
-       0x9ece990c, 0x3dfad04f, 0xfadadd73, 0xfada054d, 0x8dde3e1c, 0xc6ffad84,
-       0x7107c17c, 0x13f65355, 0x356710f1, 0x9089942d, 0x5542f90c, 0x98bfc12b,
-       0x7f7daf93, 0xe3c1f81f, 0x531c3c7f, 0x971c0a4d, 0xb6485c20, 0xfa48dce8,
-       0xeebe4700, 0x7d63d9d6, 0x244ccf90, 0x8de38327, 0x838c4ee5, 0xe65b7f73,
-       0x5596cbef, 0xb2cfc0ad, 0xfc56cfce, 0x4de0dee5, 0xe38dffb8, 0x2fe084a4,
-       0xbff444bb, 0xadff9d65, 0xe2fbe5e0, 0x8fe3c143, 0x3a97cbc5, 0xb8b20cbc,
-       0xccabf008, 0x16a985fd, 0xca0fab27, 0xc8de7827, 0x9fa905fd, 0x42d3788b,
-       0xcc8bdf79, 0x5f386ce6, 0x30148f33, 0x1afd71de, 0x3983f511, 0xe575c04d,
-       0x8f31904f, 0x7e4373f8, 0x6f3be026, 0xbf1515dc, 0x0270cb60, 0xb871173c,
-       0xb42a9117, 0xeff9c95f, 0x84cacbbe, 0xf6820673, 0x211722ef, 0xadbf52d7,
-       0x47f04b28, 0x4b157852, 0x0e9d1bc4, 0x1c816f71, 0xb5bdc4d1, 0x47fdf875,
-       0x8b9c6842, 0xbe4deff5, 0x5fe5d4fc, 0x323b3ca9, 0x1e41fa8c, 0x5849bb9e,
-       0xaff156dc, 0x70626f6f, 0x7c132cac, 0x7e774829, 0xee755f39, 0x83e71cf8,
-       0x0e3bdebf, 0xa3f664e5, 0xefd1a3a3, 0x6fd03977, 0x437ee4a8, 0x0d11d7b7,
-       0xa6eeae71, 0x9b3e7e54, 0x55cb536b, 0xfdcfdca5, 0x7e40bfee, 0xa6bb2d21,
-       0xf822b50a, 0xf1802471, 0x08d4ef5c, 0xfe4c31b2, 0x1931ffeb, 0x6154fd38,
-       0x627e001c, 0xfd91e026, 0xd1abe98a, 0xadbc2ab1, 0x3494f6b9, 0xe01e27a6,
-       0x0e754477, 0x0be163f9, 0x75c03e7e, 0xf4db447f, 0xadfb30fc, 0x5638b135,
-       0xe2df5bde, 0x34379c77, 0x9700cb25, 0x9a8aa61b, 0x2655fb73, 0x238d97ee,
-       0x795d60e3, 0x9b655d6f, 0x11697808, 0x66ddf09d, 0xa359d365, 0xb079cc3b,
-       0x3e309e1e, 0xca8fd5c4, 0xe78022ce, 0x082387d1, 0xf2efd1f8, 0xf834c673,
-       0x430d226e, 0x2b882e3a, 0xb5c39afe, 0x72c764d3, 0x1cb65e56, 0x6b4de74f,
-       0xa3858fb0, 0x7fbc01d4, 0xe3211827, 0xbd878921, 0x501bf4a7, 0x1bb5fac6,
-       0xf6e115ed, 0xed823c3f, 0xef3898bf, 0xfbfc2099, 0x51fb2de1, 0xec073fab,
-       0xae3ca983, 0x09ae83d2, 0x0cf747f2, 0x1bfa07c1, 0xe7ac61fc, 0xdf84efb1,
-       0xbeb3be55, 0x8559e981, 0xde70f5ee, 0xccace1cb, 0xe2c4dc7f, 0xfce27faf,
-       0x8159c0a5, 0x4abd7eaf, 0xa6af2a7f, 0xd751e3a8, 0x197d8e37, 0x268a9bec,
-       0x43a06ec1, 0x466d4855, 0xc6cac3e0, 0x6f3864c7, 0xe360eb99, 0x8c7f2912,
-       0xd3a09f3a, 0x9a3bf2c4, 0x0dbcafd3, 0x1adce4e8, 0xe242e813, 0x0dace3ba,
-       0x06bbf0e4, 0x7be19fe7, 0x227bef6a, 0x790178d9, 0xcea7b1f5, 0x8f525535,
-       0x9ceb8c9b, 0x432d9655, 0xb296ecf8, 0x8aa2725d, 0xb14d3a9e, 0x1f3caed8,
-       0x8748e650, 0x5c3e74e7, 0x1311f787, 0xd242ef81, 0xfbf15bea, 0x62aa5bd4,
-       0xd4961d18, 0x3d6232ef, 0xf32bfb19, 0xf9e8f329, 0x369e7669, 0x6e4178ef,
-       0x4b8020db, 0xd4bfc99e, 0x1f4e8619, 0x8ee72b33, 0xb84f53df, 0xf98edd28,
-       0x2c4f48ff, 0x1b44f455, 0xef2bb9e6, 0x3e3335cf, 0xc489e957, 0x49627a70,
-       0xf01123b5, 0x6a4764b0, 0x92c93022, 0x084b4e3f, 0xf03e27a7, 0x43e373b0,
-       0xaeeebbfc, 0x5c4f54d9, 0xb313d2ae, 0xf44e9023, 0x959ae5ef, 0xe88b8d73,
-       0xff6f0509, 0x03e6f2c3, 0xf86113d0, 0x56b346fb, 0x54d8dc4f, 0xc6e27a88,
-       0xfbe6a2d9, 0x17cd6baa, 0x09d913d3, 0x3b2eb173, 0xcfd0c2a3, 0x39bfdc07,
-       0x61fbf3c4, 0x6b17d01e, 0x9b8476cc, 0x26f46f5e, 0x55f6c7d7, 0x825fffae,
-       0x97d722b3, 0x43f761cc, 0x8243a4f4, 0x2e64bcf4, 0xd002eb95, 0x4beb9323,
-       0x4e71e56e, 0x07cd9c9d, 0x96a19b39, 0x0afdecb3, 0x950bd337, 0x9abfc98d,
-       0xae6fdb47, 0xda669d95, 0xdc90e6ff, 0xddcb54cd, 0xe1096635, 0x96ee43dc,
-       0xae7bb930, 0x4fda1c69, 0x53efedbd, 0x3ca96f2e, 0x430ce61b, 0xa2f3051f,
-       0x1ddfdf34, 0xda76fb1d, 0xef2fc02b, 0xfb7e788a, 0xf603b739, 0x033b7d8d,
-       0x7c53e9ec, 0xfcb8db3d, 0x5cf8f4eb, 0xc81ca953, 0xd3d983bd, 0x84459be5,
-       0xe303455f, 0x91618aff, 0x4fad073e, 0xcf16ff4f, 0x60ef1761, 0x0774b0e7,
-       0xfc2ad979, 0xadb77e2f, 0x1605ce06, 0x1cf017af, 0x005fbe19, 0x78731678,
-       0xe3173916, 0xdaf14a39, 0xe53fe7f0, 0xa6a2dfbc, 0x5f0f18f5, 0x2bf6d3e4,
-       0x29f5761f, 0x4cf247f0, 0xaf790f0c, 0xc9f5be08, 0xeba0cf90, 0xe78d5ce7,
-       0xdaf5e547, 0x7ef907e7, 0xb4fe8a17, 0xe4fbe857, 0xd3bfcccf, 0x1ea0fbc3,
-       0x123f252e, 0x5c29fb2e, 0x70f5fe32, 0xd40e0de9, 0x01f3c7be, 0x2b0e3c3d,
-       0x649d2572, 0x6e7e1f00, 0xf15ca170, 0x42e143be, 0xb1e3bbe7, 0x40fb9ae1,
-       0xbcb8738e, 0xf4d7706b, 0x02157e87, 0xb75e2bf6, 0xad024f65, 0x6327abcf,
-       0x78a178e1, 0x070f56ad, 0x03837ef5, 0xaabcfaf5, 0xc7e4022d, 0xfbdfe42e,
-       0xc31ef895, 0x5d6e547b, 0xed3cf546, 0xe4dd20bf, 0xfdf07386, 0x9b940111,
-       0x47c6dd0a, 0x8e25fb30, 0x03a3a1cb, 0x3f515302, 0xe4760a35, 0xd3047f47,
-       0x704f1457, 0xc4f34bbf, 0xbc73a7af, 0x2352b8b0, 0xc52563c3, 0xf4f3f01b,
-       0x63af5e26, 0x4a2de076, 0x39f05ebd, 0xbbab9004, 0x8c5f7664, 0x8e04e240,
-       0x847e9504, 0x04ecd5f3, 0xb4779e15, 0x28dffa33, 0x8f81f138, 0xf043f7fe,
-       0x33dd2bdc, 0xf4afa63b, 0x3e29c0ae, 0xfde78b42, 0xe379ad11, 0x9bf9c1fa,
-       0x737bc4e0, 0x9cf0629a, 0xbb2d58e8, 0xbf9525ff, 0xf00be7a7, 0xd1f7d43b,
-       0x438584cc, 0x088cf37e, 0x79c50fcc, 0xa65d9853, 0x7bfa4f96, 0xfe6fbe80,
-       0x45692551, 0xc7942c7b, 0x04de7ee8, 0x3410cde3, 0x09104ef9, 0x09ff3a03,
-       0x7cd5bfc6, 0x9249f181, 0xef96f31d, 0xedcf2bb2, 0x5e2cbbec, 0x799c1e6f,
-       0xef851e68, 0x13a255b9, 0x0c9ba85c, 0x2059838e, 0x09941e6f, 0x7db9cbf0,
-       0x81e98bb2, 0x853bd428, 0xefc51eef, 0x0e590ad9, 0x8fbc291a, 0x7ca397e9,
-       0xbd511f3d, 0x0a5882ed, 0xf70f1fa9, 0xee76cce0, 0x7880e69a, 0x95fec64b,
-       0x2b39ce70, 0x20f07ed7, 0xbb3573e0, 0xaac8e907, 0xeed3f45c, 0x7e4053ba,
-       0x06f14c3b, 0x9d99cfef, 0x9d20f07c, 0xf155d6f7, 0xcf396e78, 0x9c237f15,
-       0x27dbce63, 0xdfb41d3a, 0x16adeb82, 0x66bcc738, 0x2adc48a4, 0x5a4adcf8,
-       0xaf33be31, 0xb039ceea, 0x0faa12ee, 0xf72864c5, 0xfa844b4f, 0xafdf013a,
-       0xf08dbaf4, 0xdaeb66bd, 0x3a0cc6b3, 0x07ed117f, 0xc75caf60, 0x106e55fa,
-       0x5dfa909c, 0xca18f4d4, 0x020da2cb, 0x4ad3345e, 0x1b335fed, 0xe3a667d7,
-       0xefa3aeb6, 0xbc317ad3, 0x886ee30f, 0x27ce11b9, 0xf13ae92b, 0x78d509fd,
-       0xdf445d2e, 0x75a4cda3, 0xde389dc3, 0x810275a2, 0x264b03ef, 0x01323f24,
-       0x3b27dbc6, 0xaed0fda1, 0xdd611b5f, 0xfaf9d1b7, 0x8817f1d3, 0x3fa0d36d,
-       0xc760a5f9, 0x46ea87fb, 0x0baddc60, 0x542f0c36, 0xe63ac70d, 0x0c103b13,
-       0x651f3a92, 0x4efb0447, 0x755968b8, 0xcdabec0d, 0x406c9f1b, 0x046b3aba,
-       0xc28c7e3d, 0x3c874ddb, 0x2e79646a, 0xc6a3decd, 0xfd1c9536, 0xdf152228,
-       0x1b31a3bf, 0x921626f3, 0x709bcc7c, 0xa47b3357, 0x0f84657d, 0xb2ed6ae2,
-       0x6f3c087d, 0xe7c2695e, 0xfd312f9d, 0x0db839d3, 0xd627dbe3, 0x5fbe04c9,
-       0xf52eb15c, 0x89e3c069, 0x9bd232cd, 0x1bcb2cf8, 0xc5897e28, 0xb1d79ac9,
-       0x352c4f71, 0xa0b57bb2, 0x5f8bd69d, 0xb40af254, 0x51c8ac72, 0x2f4a728a,
-       0x6b72f497, 0x46d593d1, 0xf21ed920, 0x9474e96a, 0xef54a557, 0x90f5a100,
-       0x306a8357, 0x5797aa6e, 0xc8a2c495, 0x5f8874a9, 0xbe0f9616, 0xf1d02d6d,
-       0x8183ecad, 0x5f6bff56, 0xb77a053e, 0x49e04acc, 0x5a7f6485, 0x80417460,
-       0x6d35e65f, 0xa0f812f9, 0xde045e64, 0xf01c75c7, 0x26b37c00, 0x8bafcf0e,
-       0x6f08857c, 0x78b72f25, 0x95ce96ad, 0xb75ce3f8, 0xfd6a5c48, 0x5c451255,
-       0xee877eaa, 0xe74af4a3, 0xf051bdb9, 0x743ca881, 0xbbdefb5f, 0xc76eb033,
-       0xf6e32d75, 0xd22b1ac1, 0x9f9fa1f3, 0x7af4095d, 0x0102bddb, 0xdd789d7b,
-       0x2b0fa035, 0x880e0ad6, 0xcbdf170f, 0xefa62fde, 0xfd0fbac3, 0xa515d19a,
-       0x7fd0076f, 0xf6c7bac5, 0x820dff62, 0xb43fc603, 0x89ed10be, 0xb048af12,
-       0xfa3b437d, 0x614f540f, 0x57b3599e, 0xaffa004c, 0x0764dfb8, 0x23a14953,
-       0xf9db2e85, 0xecc4087d, 0xbe8b331c, 0x15160ab7, 0xc51e93df, 0x4fa82102,
-       0xbd2a4e81, 0x5fdace8c, 0x36409d92, 0xf64ba717, 0xae09fc1d, 0xe767c55f,
-       0x74ef874c, 0x047ea98a, 0x975e6d3a, 0xe23b046b, 0xfcc04f84, 0x49749e8a,
-       0x4a3b6a2c, 0x0567cba1, 0xd07baf26, 0x7b0e8ea3, 0x4ba71dd0, 0x5128fe85,
-       0xb6595fa3, 0xfdf0264f, 0xdd1e9ebd, 0x908dfd72, 0x32f851ff, 0x6f5d0fdd,
-       0xd1cfcd6e, 0x48e0575e, 0x2f5009eb, 0x8fde5892, 0x12e50fc2, 0xdefb0fcb,
-       0xbfcdd3eb, 0x87e78229, 0x2c883f01, 0xe74fc97f, 0x0bf37b7d, 0x66792f98,
-       0x6875fb53, 0xe941bcdf, 0xd9bfe000, 0x7fe8fc4a, 0x950e50f8, 0x6f988836,
-       0xe67f244d, 0xaedf952c, 0xfe2cbfe4, 0x5de11583, 0xcbe4d5ba, 0x6e97efa3,
-       0xf3063a3f, 0x30079611, 0x49bbc7bf, 0xde1fe760, 0xfdf031b6, 0xf2c4a950,
-       0xc176f470, 0xe71648f0, 0xaa2d78ea, 0xa136ec00, 0x57b3dd8e, 0x6c937f5a,
-       0x0775c552, 0x2f38ca45, 0x63e787ed, 0xb8678a5e, 0xa7d6011f, 0xc94ddfbe,
-       0x9178e9bf, 0xa3695fd1, 0x695cf68c, 0xc84e96dd, 0x6c3d2cc3, 0xb2b73f42,
-       0xfc11acee, 0xbc3fdcd8, 0x55f3f784, 0x3c9a8a36, 0x6ff91ebc, 0x04dfa275,
-       0xe50d5bf9, 0xeb437e78, 0x0faf58ed, 0xb17a079f, 0x7fc5ad3c, 0x4bddb1d8,
-       0x95f8b841, 0xbef0d9df, 0x368dd6be, 0xeea9eefc, 0x3da7f9c2, 0x57eaddf2,
-       0xeddf305f, 0x0941fc34, 0x5d48baeb, 0x931d60be, 0x997d746b, 0xc4e261f9,
-       0xa5eb7b41, 0x7c839f2f, 0x7fad8eec, 0x5bd60e7b, 0x9ee75ff6, 0xb21abc83,
-       0xf60ec233, 0x0fa6e548, 0x79559f30, 0xd99224af, 0xfe2f9d7f, 0x3b80f30e,
-       0x6139343f, 0x271dceb4, 0xd1bd8086, 0x04dbe5b9, 0xba5defc8, 0x73c61a63,
-       0x4dcb6e96, 0x05e26124, 0xeb74094a, 0xb21e43eb, 0x0dcd5f1e, 0x73ff98cd,
-       0xe41be286, 0xb17f3043, 0x83e59cbe, 0xe2de783a, 0xdef9f0e6, 0x1b14f23d,
-       0x193f5d66, 0xb30362e4, 0xaf9a2e0b, 0xf1e28078, 0x6fe03ef2, 0x4f2e6af3,
-       0x0cefe3c2, 0x54f141fc, 0x57cda913, 0xe161b2fc, 0xb6819e6f, 0xf35eb886,
-       0x807dfd15, 0x3e4f929b, 0x58f5d22b, 0xd6cdf024, 0x287e63df, 0x01cf2de0,
-       0x21cbf9f2, 0x293e1710, 0x10fe3007, 0xefc261d8, 0x1c774b2c, 0xdce9fe42,
-       0xb5f31fb6, 0xeeebcf09, 0xcb1fc124, 0x9eb1e5c3, 0x96560dca, 0x0fe1c8e7,
-       0x1b0e9079, 0x8ef9e73e, 0x3c958e8c, 0x1ff2dec8, 0xf853225b, 0x4f2c2a7d,
-       0xc7c37cb3, 0x8430af3c, 0xe002612f, 0x7982fda9, 0xec1c0aa5, 0xd42b8700,
-       0xf3e1bcf9, 0xdf79834c, 0x3f805f1c, 0x7cc1d390, 0x041f5a5d, 0xe13e9bf9,
-       0x0f230910, 0x3cb3d73a, 0xfc394ee0, 0x7e4accf7, 0x4f9eb36f, 0xebcb7d7d,
-       0xbffad8bd, 0x221a7c2f, 0x1eae381d, 0xc3e71d4e, 0x9ce3f1cb, 0xf7f07fef,
-       0xfe826521, 0x81cf93fb, 0xda1bcb1e, 0x899f788d, 0xfdf13fe2, 0x5a78f076,
-       0xf31126c7, 0x9bea6b3e, 0xe5eb8e51, 0x273f0545, 0x1bf7afd1, 0x468adebe,
-       0xb63a27a6, 0x3a167d5a, 0xaf5bc74e, 0x6c573d21, 0xd3bcc76e, 0x18af75bd,
-       0xcbe754db, 0xaa7c27a0, 0xbcbc77f5, 0x6dca0c6b, 0x7e98bf7e, 0x9b14631e,
-       0xfc29b2a7, 0xcf9b953c, 0xec59e66a, 0x2dda37ad, 0xb4ef9f17, 0xc609bae4,
-       0xeccadd3b, 0xe2f5d3a5, 0xf9985f0c, 0x49bd714f, 0x0f3b2d48, 0xef12faa5,
-       0x7bb2b359, 0x245b44d5, 0xad4b5fda, 0xf7470e13, 0x7988d283, 0x79aa2b2f,
-       0xce7dcc9e, 0x0af7c024, 0xd604d5eb, 0xabe012bb, 0xbb65e3f2, 0x26dd809b,
-       0xa867e527, 0xf59459cf, 0x8819fb1b, 0xa5ff854f, 0xe08919d6, 0x3bc9127f,
-       0x5d71d608, 0xe812d7ca, 0x8b0f56bf, 0x47f393df, 0x56f3c187, 0x8e27bec9,
-       0x553adb8e, 0xb5e84270, 0x34fbdd27, 0x2e998671, 0xf8b17ded, 0x5fdd1c0d,
-       0xf680d3b7, 0xb7e0d5a0, 0x1ac42ed3, 0x0e849ad1, 0xa43883ac, 0x0214fc04,
-       0xf41e21f3, 0xfdc16798, 0xcd4236c8, 0x94e7e853, 0x449ff734, 0xf774904f,
-       0xc30390a1, 0x385abd28, 0x39712abd, 0x8e9bfb2b, 0xacf786db, 0x6a91a4c4,
-       0x5635df20, 0x4f0dda37, 0xe869fbf0, 0x41e4246f, 0xa74892c4, 0x3a26fefa,
-       0x38fbe6af, 0x1ea6af3a, 0xe3d6d2e3, 0xc2c74866, 0xbe3897e9, 0x05a2e98e,
-       0xcd3310e1, 0x796bf8a0, 0xeb4213c3, 0x4e27898e, 0x6b5fb43f, 0x2801efc1,
-       0xfbd5797b, 0xebb458b0, 0xc8d3eba6, 0x36b4e889, 0x53ad81af, 0x1c4edcf3,
-       0xa5dfee02, 0xabd74e7d, 0x714617a9, 0x09112779, 0xdcc59de4, 0xbbfc384a,
-       0x5fbef035, 0x013837da, 0x5fb843f0, 0xcf9025ed, 0x41f7cd12, 0xb7f4d7e7,
-       0xcd807443, 0x0c871daf, 0x43bfabb2, 0xbfeb9cbd, 0x25fc9651, 0x329e9451,
-       0x62615687, 0x49125676, 0x9ba5efc3, 0x4a7ca1fa, 0x79839659, 0xa32d4227,
-       0x086b61ab, 0x00b0cdf2, 0x3fba9bcf, 0x9351ed12, 0xd2237899, 0xe2367be1,
-       0x1661d395, 0x7043cf1f, 0xa1d0372c, 0xd69455a4, 0x814d7be8, 0x8a42c31c,
-       0xa2687a84, 0xb94657e3, 0x9f28a3aa, 0x2774ccd6, 0xf6c2c619, 0x3bb95ede,
-       0x52f6b90b, 0xaa1a0888, 0x1969eef7, 0xef04228c, 0xbdde20f1, 0x6bc6807b,
-       0xec153a95, 0x6d7f9df0, 0x32eeb064, 0x9b5f7953, 0x3e8feac2, 0xdc2577b4,
-       0xcf6e9337, 0x49f6147f, 0x7851f6cc, 0xd58fe5de, 0x9bddf3dc, 0x39d6517e,
-       0x173f8372, 0x3abe05ee, 0x1df5eec0, 0x777e0d6e, 0xa3787a8f, 0xd1fba945,
-       0xd86fc88f, 0xbcad728f, 0x1bb63f7e, 0xa1cb4ea0, 0x81dcfe71, 0x472f9f74,
-       0x74969a1d, 0xa1af1d29, 0xd93e0930, 0xd0ea357f, 0x30eef81e, 0x578f8704,
-       0x82141eee, 0xc3fcb483, 0xd5932d3d, 0x0f70f870, 0x857d21d8, 0x7d0fabc3,
-       0xebe87088, 0x6c5d29be, 0x935cbc07, 0xd6fbc06d, 0xc16c38ae, 0x45fd0af8,
-       0xe3e23ea0, 0xbbe5efac, 0xa11fc56c, 0xd354ece3, 0x429ef297, 0x4dd1bd57,
-       0x628fb12a, 0xe96a6cf7, 0xf5ca2ba7, 0x25abac36, 0x358f75ca, 0xf78ff71e,
-       0x76e35c00, 0x0b8ea73b, 0xb8b135d1, 0xeefdc1c7, 0x5bf32ca3, 0xf2f254a3,
-       0x6225ec9a, 0x81c9c40a, 0xfb43e217, 0x8de65f89, 0x19f74118, 0xde6032ef,
-       0xfb8b28fc, 0x2b63cc20, 0x7721f808, 0x1ee20aec, 0xbe218827, 0xd9abe650,
-       0x9af5fcc1, 0x396f8342, 0x6015ef3b, 0xb47d10bc, 0xc023e8e9, 0x1db1a3e8,
-       0xa9a2a3e9, 0x6347d19d, 0x06644e75, 0x3f03373b, 0xc60496bf, 0xa23bde02,
-       0x51269abe, 0x151a1ffa, 0x91ba01a8, 0xe5a6e7bd, 0x3d708a5d, 0x7c3f161d,
-       0x7abeca7d, 0x4b6d6fc3, 0xe06943ca, 0xe033ee4f, 0x37029779, 0x858c5fa5,
-       0x58b6c5e5, 0xfc035fdd, 0xedb4272a, 0x6d6fed85, 0x36f31f79, 0xd86efb6c,
-       0x66dbef05, 0x42390c53, 0x5beed6f3, 0xd767f78e, 0xd87dd806, 0x05e024d1,
-       0x3c3bdebd, 0xe104ff18, 0x1a4f7601, 0xf91da3c0, 0x5eff1365, 0x7051ab2c,
-       0x1a1f9e81, 0x890deec5, 0xebf3b0b4, 0xd7111621, 0xcec2c439, 0xbdf7e259,
-       0x95bf8225, 0xfb01bf75, 0xa69943c7, 0xbcfdffde, 0xaf89a4bf, 0xe854f82b,
-       0x28d24a89, 0x4ce47fb8, 0xa2d13b8c, 0xa8d89fa1, 0xca78d514, 0x88788f7b,
-       0x47aa0ef3, 0xff3dd8af, 0x94abd02e, 0xfc00be7e, 0x968dfb04, 0x4a6e0023,
-       0x70cfa07f, 0x0defa1f8, 0x1e60f987, 0xecb617b0, 0x3de2225e, 0x6bc47d1a,
-       0x491bdc26, 0x914667fb, 0xfdf4adaa, 0x425a68cc, 0x13d78e3d, 0x2b207d79,
-       0x1a713f53, 0x3d7cfa04, 0xb64ebb8f, 0xc931fcf0, 0xd186ea3e, 0x5c766750,
-       0xea245256, 0xe16f8505, 0xb738080e, 0x75f9f896, 0x00c5204a, 0x58f85378,
-       0x56fc180a, 0x2452b4aa, 0x18f20187, 0x7dd0f1de, 0x9dcbbd4b, 0xdf652fab,
-       0xcf9fea71, 0xc1f9ebe4, 0x3d17f5f6, 0x099eefbe, 0xb7372df0, 0xad03723d,
-       0x0e7a5c57, 0x479707cf, 0xa1795c55, 0xebf42f7b, 0xdbfce77f, 0x4d874051,
-       0x7ec298df, 0xe1c3550f, 0xc029e2d6, 0xbdf932f7, 0xc951242e, 0xb1e55633,
-       0xcbb71b42, 0xf8299510, 0xffaced1c, 0xf8081140, 0xf0b14af4, 0x9e32547e,
-       0xe5d14e1f, 0x9f87fead, 0xc132f9c5, 0x71250030, 0xcf3628c9, 0x324ecc37,
-       0x9ce0ffd3, 0x173f1a69, 0xaf72477b, 0xdef1d2b0, 0x357cec21, 0x19aaae33,
-       0xc6c4c4ea, 0xfbda26cf, 0x6b13320a, 0xb8c2c6a7, 0xdf18c9d1, 0xdaeb35ca,
-       0xc812bd53, 0x8c9a9269, 0x88d38979, 0x7a633eca, 0x08eeed03, 0xe3902eba,
-       0x742c8cd7, 0xe7ede54e, 0x4d43ffe8, 0x2a99f6e4, 0xc72ae37f, 0x8d54e75c,
-       0xf78b52fd, 0x9fe9fd01, 0xf2e1ede2, 0xfce33e2c, 0x77c9e2df, 0x1eb3f9c2,
-       0xe10e399e, 0x27a3ab7e, 0xd470f5dc, 0xab815dc3, 0x9fd98e1e, 0x86c6a738,
-       0x2e1e9381, 0x48ed48d3, 0xdc0a63d0, 0xc77970f5, 0x9de2e8cc, 0xabde1334,
-       0xe0c48ef8, 0x23350ef8, 0x9ba41ea1, 0x01ef1168, 0xf5e28cce, 0xbab04737,
-       0x64a8ef82, 0xae1eb7c4, 0xc666387a, 0x58e3f7f1, 0x2f00bdff, 0xe202e509,
-       0xcc9ba147, 0x31ddaad4, 0xec507a2a, 0x2e1c69eb, 0xfb46bed4, 0x8ade3739,
-       0xafb02671, 0xe08425a7, 0xd6ce5b96, 0xf2dc3b95, 0xf4a9f83c, 0x72bfbc75,
-       0xff3fe10a, 0xca2f3c14, 0xce0555e4, 0xdad1be53, 0xa69ad3c9, 0xc338829f,
-       0x7efb9350, 0x1080cfa0, 0x1475e783, 0x707447ee, 0xd767bed7, 0xf870f5d6,
-       0xb131fc03, 0x3a14bc27, 0xe3c2c0fb, 0x20c8034e, 0xbcc797b0, 0xf20d1196,
-       0x86c5349b, 0x715c4b8d, 0x0e383f38, 0x63a457a7, 0xcf83b881, 0x423fa9ed,
-       0x5aa3ed8e, 0x36c72552, 0x96d3ee8b, 0x4c729ef8, 0x8e64d3c1, 0xbbc4c987,
-       0x934be20b, 0xd045f489, 0xed0e481f, 0xe7d95bbf, 0xf6103240, 0xc1c58379,
-       0x67df3fe4, 0xbcd4df70, 0xf8b3f984, 0x0b6659fc, 0x02435f7e, 0xce104752,
-       0x91df7829, 0x5a1b18d7, 0x4fbf9287, 0x66115486, 0x7bc3cdcf, 0xc85c29ae,
-       0x75a15177, 0x8482ac98, 0x75f0fdf7, 0x7b33a99c, 0x5bad8f21, 0x9d814774,
-       0x1bec21d7, 0xfc93fb83, 0xe9ff4023, 0xee35cfdb, 0xda7680ae, 0xf1fb08af,
-       0x59162ff5, 0xc3b021fc, 0xb93e7be4, 0xb2953b77, 0x8509ea35, 0xfbe0b37e,
-       0xde81cbd4, 0xdd6103fd, 0xd1d54053, 0xf659e772, 0x6376431d, 0xecf304ba,
-       0xff7966e9, 0x8125c439, 0xdfa7ab7d, 0xa1a74bef, 0x08604578, 0x5d8a29f8,
-       0x1eead536, 0x57cfa569, 0x9b66eff3, 0x05188ece, 0xf4c1f978, 0x4f4b4074,
-       0xba511d0a, 0xecf00f1a, 0x69fcf8ca, 0xcddfc730, 0x7a009738, 0x43dfb151,
-       0x026b8a76, 0x3b37a7ac, 0x3dd5897e, 0x3b017ac5, 0x2e67b15e, 0xdd9087e6,
-       0x74a641d4, 0xcbc71b74, 0xccab733c, 0x600fcdee, 0x48eafdfe, 0x473b5ee5,
-       0xb791d824, 0x54d94ead, 0xd586e707, 0x6b7efe2c, 0x83f1ac95, 0x86dd90dd,
-       0x66fbb3ef, 0x6da65f6f, 0xfe604cff, 0xfb57a17e, 0x3412589c, 0x9cf6edf7,
-       0xc035e0d7, 0x3123c3bc, 0xaf3f413f, 0x79fa7f7e, 0xe6adf3f5, 0x636ad57e,
-       0xcaa748ed, 0x6560592e, 0xaaf750f6, 0xcae0ebc7, 0xe7e0deba, 0x93480f36,
-       0xb5abf754, 0x082c8ead, 0x328c6f77, 0x79ef029e, 0x00e2cfc4, 0xc3dff255,
-       0xe59b83dd, 0xde81f166, 0x98161de6, 0xe1a0768a, 0xf608bf49, 0x4100b0fc,
-       0xe02b3bfb, 0xf8d02c32, 0xee4fcc01, 0xbdc007e1, 0xd65eb426, 0x01f98bb0,
-       0x4fe8d5f5, 0x027f5194, 0x387accf4, 0x17c01e9b, 0x41fe8694, 0xfc85dfd0,
-       0xcfb82ca9, 0x12c3fb92, 0x5ad497a5, 0xf5a37fd6, 0x096ae35d, 0x927755fc,
-       0xe363294c, 0x98d7efc3, 0x93555fa9, 0xf508224c, 0xf8785eab, 0xc06be9fd,
-       0x09758e5f, 0xad287f70, 0xf7fa58d7, 0xf8debfdd, 0xb81afef0, 0x65fa946f,
-       0x7f2aaceb, 0x78fe37b7, 0x0b918c04, 0x3dba47f0, 0xa1f0237f, 0x8a68af12,
-       0x111f7ce0, 0x8068bba4, 0x57274297, 0x7e8f9b2f, 0xe725c445, 0x589e4087,
-       0x16ffc716, 0x46c38f2b, 0x129ff7b1, 0xbf905bdd, 0x023f3adf, 0x8cefcbe2,
-       0x5cfe8a3c, 0xe7c59593, 0xd04a79f7, 0xb9f0527e, 0x3f702acb, 0xf8103fc9,
-       0xcdf1daed, 0x6497e071, 0x43de02c9, 0x9efb24da, 0x7900cf4c, 0x82bedb34,
-       0xa26b296e, 0x6b13bf11, 0xbc0ff08a, 0x35a7655b, 0x9b4cfbf1, 0xa81deece,
-       0x661e63ce, 0x4565ddcd, 0x308bf3fa, 0xeec6567e, 0x7befa0c3, 0xfd212fd3,
-       0x7f4012e1, 0x13fbf390, 0x61a8fcf0, 0x42e20d8f, 0x827efc1d, 0x09cd0d33,
-       0xbe5969f3, 0xf0362fe5, 0x70e7ded7, 0xe2b52338, 0xdb654a3d, 0x83ffbc44,
-       0x0b709bce, 0x161ba7c4, 0xf7efb264, 0x8a6777d8, 0x67ff4cfe, 0x167cc0f3,
-       0xc8efc434, 0xb2727b14, 0xf583ebd9, 0x188b5535, 0xbbac9e2f, 0xbf0a6c37,
-       0x5f6f4c37, 0x712ab49e, 0x87cc04e9, 0xf3676a5a, 0x594fc6f4, 0x9f12c4df,
-       0x24b2df8a, 0xcfeb08bf, 0xc08126fa, 0x5a679715, 0x03c89e52, 0xcec89e3f,
-       0x44ac30e1, 0xcafda376, 0x6fe89fcf, 0xbe43dc37, 0x6cde5793, 0x4aeb3738,
-       0xfdfb6624, 0x77600997, 0xe0b1fbb9, 0x8a07d322, 0x1be5377d, 0x6f557c6d,
-       0x8d34e6e7, 0x41207fbd, 0xa77fb378, 0x55eec022, 0x06ff61eb, 0x7bb587a6,
-       0xe10c7909, 0xf52dbe90, 0x2947b81a, 0x3b068ffd, 0x7c02dbcc, 0x3cf80f11,
-       0x54fcf787, 0xd08dff10, 0xda20d15e, 0x927eb0fd, 0x95f01971, 0x70283762,
-       0x6cdf3c69, 0x91d7431e, 0x5f60d675, 0x3378874e, 0xcffa05f0, 0x2fbcfee3,
-       0x5357f40e, 0x8273c240, 0xa3bbb3ac, 0x60e4a816, 0x3e0379d3, 0x5bfcf37f,
-       0xd881e7da, 0x2dbde0cb, 0xef17e606, 0x28f7fbde, 0x9e6f4b90, 0x82f1c6ef,
-       0xbb4f4376, 0x6b91e118, 0x67718315, 0xc44c5db5, 0xb79003ac, 0xaa9a2d35,
-       0xbb77a131, 0x7213fb37, 0xb4f495bf, 0x1ec0721f, 0x11d8c311, 0x3e74ce1c,
-       0x6f48f809, 0xe36e5c57, 0x24c1e6f1, 0x6ca3ee1d, 0x18b71f3c, 0x8a6e1fbf,
-       0x7d472fb2, 0xaea5eccc, 0xbf1fa7dd, 0x13ef9e06, 0xe711fdd9, 0xb7a7e445,
-       0xda1e2e76, 0x2a5be2a6, 0x5f4f1139, 0xf9db3ff5, 0xd5ffed06, 0x4716489e,
-       0xa9979c97, 0xf50877bf, 0xf97871f7, 0x38f3b007, 0xd7b800ef, 0x2fdb07e9,
-       0xfafc3d1d, 0xc3da1b3c, 0x1ea0e981, 0x376bac46, 0xac5bfe02, 0x90d9d7f9,
-       0x00a3eadf, 0x33925e2e, 0xf3804c90, 0x7403927a, 0x7626a815, 0xb5b627f0,
-       0x97800c18, 0x98c98d8c, 0x9f89b3a7, 0xafaa2e57, 0xe8ab2635, 0xef3f1162,
-       0x877b293a, 0x1f9eaac4, 0x72f931b0, 0x6fe94f72, 0x43e34f30, 0xc61e1913,
-       0x31b06cde, 0xd18afb7d, 0xe866cd7b, 0xdf80c477, 0xfbdeed0d, 0xcfb85efa,
-       0xc761d178, 0x3dff8858, 0xbf607362, 0x6a9b7dc6, 0xf1b7cf20, 0x5452d013,
-       0x14286caf, 0x37de740d, 0xefc58388, 0x1fd0180e, 0x893dc60f, 0xf9f60e2b,
-       0x1bcf5f10, 0xf9cd062d, 0xdefc1bd8, 0x326d7bdd, 0x89b12fb6, 0x2dadc788,
-       0x37a07139, 0xbbeeac5a, 0x8e2fa06d, 0x12c0d5b5, 0x629f7894, 0xb03c4daf,
-       0xf4d19af5, 0x061d89cf, 0x71dba03b, 0xf61179e0, 0x484938eb, 0xd87a408c,
-       0x8f3c746f, 0x3a37bc7a, 0x1d7478d8, 0x2abf016f, 0xff9aa7f0, 0x7f5a34a1,
-       0x858a55a3, 0xfe052efc, 0xf9943eca, 0xb5c4f51d, 0xe4ac82de, 0xb8817ada,
-       0x3a5f92b3, 0x7f944ece, 0xd2e9012f, 0x6a3d7368, 0xda0ef663, 0x30f727d7,
-       0xae15e8bb, 0xe1524947, 0x829f8050, 0x8b1b7aa7, 0xe9eb2a33, 0xdbdffe6d,
-       0xca549e98, 0x9bd74bef, 0xe9178764, 0x0fcb1b66, 0xe6fd7877, 0x6b23c854,
-       0xcf7fc54c, 0xfb679549, 0x93e7a47b, 0x1b057bda, 0xf8060cdb, 0x8762ac0e,
-       0x6de68310, 0x20ebed1f, 0x48f5499d, 0x09878d7f, 0xdd6971f2, 0x48ee2c9d,
-       0x7fbf0de5, 0x81d1cf0d, 0x7a79f87f, 0x1396817f, 0x18afd69b, 0xdbf5f088,
-       0x7042af80, 0x65037ca2, 0xe811ad55, 0x5652d175, 0xe973f316, 0xc8dd6b45,
-       0x58eb459f, 0x5b1ee17e, 0x0ce7ae32, 0x886257a7, 0x27f9001c, 0x657f0e2e,
-       0x6e9c79dd, 0xd13c354f, 0xfa52f30c, 0x73e013fa, 0x4f63e352, 0x7a1572c3,
-       0xc641b53d, 0xb5224a71, 0x7cadf6e7, 0x18076dbc, 0x20dc4fbd, 0x5ffdc0e7,
-       0x0ec4bd13, 0x3637ec71, 0x7e41146c, 0x9cf401bf, 0xf41cf8cc, 0x0f3dc9ed,
-       0xf402fd46, 0x4081bb5c, 0x2315fcbc, 0xe2a2d929, 0x5febdd8b, 0x696ff0d5,
-       0x1835f55d, 0x158b6f97, 0x7c2bce40, 0x15fdc0ab, 0xe42af3a3, 0xfc74ebff,
-       0x2fbd953f, 0xdfb03b47, 0x9fff9c13, 0x9ff94198, 0x10d98a3e, 0xaf38c023,
-       0x07dfc318, 0xa40ff5f7, 0x6d5ca0bf, 0xbf5721eb, 0xcdb57266, 0xafe74a96,
-       0xe31bb6b8, 0x71f5c10c, 0xaa6279ba, 0x02c93742, 0x6296bfc0, 0x8bc01870,
-       0x99e815c2, 0xdfb7cdda, 0xd95c8690, 0x0f39e122, 0xf9e2473f, 0x0277ca1f,
-       0xe486bf0a, 0x6eb7c299, 0xd5d83473, 0x8056ab53, 0xe7971f5d, 0x253cfa45,
-       0x52c687b8, 0xf80a767d, 0x383c8c38, 0x57c7e5c1, 0xf762fbb2, 0x7a000fee,
-       0x221ea12e, 0x13ac87ec, 0xa51780ec, 0xdd8eb1dd, 0x5a3c3ac3, 0x2bbf9cd0,
-       0xef0c1ff5, 0x41fb8f40, 0x7c634787, 0x3c84603a, 0xa63e11d5, 0x839088c7,
-       0x570c40fc, 0x5b3e000f, 0xcdd7f544, 0x4a75fd2a, 0x553a45ae, 0x347970e0,
-       0xc55f5f93, 0x95ff7db0, 0xe21585d3, 0x2f73aa85, 0x024890ea, 0x605167e3,
-       0xf8c22e7c, 0xba4cf6a7, 0xdafde90a, 0x076ef4f0, 0xfe162aff, 0x48f5a73d,
-       0xec33319f, 0x13cb1df8, 0x46223392, 0xb0f91f63, 0x57f1bddc, 0xfd01d7e8,
-       0x46f7bf02, 0xff4025ff, 0xfbdd0c24, 0xf0abdd28, 0xa501d0a7, 0x55a26b8b,
-       0x174f41f2, 0x02a379ca, 0xe7745797, 0x33474f95, 0x9780b079, 0x66f25e8e,
-       0x60fcfd94, 0x81ec9f3c, 0xcf0cf9e7, 0x7c02be21, 0x67e1f22b, 0x3dafe117,
-       0xaf6c76d1, 0xe60174f9, 0x73f2d4a9, 0x9f3e7aab, 0xd1a5eeb2, 0x4b7ce682,
-       0xca34ee7f, 0x5a2bbee2, 0x48ea3e77, 0x34c7d10b, 0xd92ecf6e, 0xff73c268,
-       0x7802d02d, 0xbdfecddb, 0xbb3de56c, 0x0a4f0d44, 0x4cd115ea, 0xe1f42b8e,
-       0xc3246658, 0x55f2ffa8, 0xc86ee172, 0xab59f9ff, 0xdd346f37, 0x77a316c7,
-       0x07e8b5f6, 0xf182af38, 0xd833caaf, 0xc6241f21, 0xde201765, 0x7c0a2481,
-       0x33cd8fb8, 0x1979d52e, 0xe70ec9fa, 0x0f079038, 0xf8297c73, 0x9bd0e055,
-       0xaf0deb9e, 0xe27c387b, 0x8e5ebb79, 0x9efe7314, 0x5c5dfbc2, 0xe045788e,
-       0x2f711b27, 0x59fd6117, 0xe505fe4c, 0x73c11648, 0x727597c9, 0x5e9fe5e4,
-       0x91acbc8e, 0xc2da1323, 0x0bfa11ca, 0x1bf1ffcb, 0x4b1da216, 0x63b7870e,
-       0x3d334677, 0x93fa0f1c, 0xb2f78bf6, 0x3987def3, 0xc48a52dd, 0x0ddac9bc,
-       0x5713cc26, 0x366d90e4, 0xaf7f81c9, 0x16fa06d9, 0x1f76cd7a, 0xc5e70c9e,
-       0x9c074649, 0x03929f5f, 0xd453f788, 0xfa45af01, 0xc7fbc7c8, 0x0223c8c3,
-       0x47ef12f1, 0x9cefd083, 0x9f213626, 0x5046992c, 0x78deee7f, 0x4955d205,
-       0x74008a5e, 0x23175a5b, 0x54ec7b40, 0x94e401bb, 0x962b8fb2, 0x71b0c819,
-       0xd40707c8, 0x6f0ae472, 0xcdbbfe15, 0x49dce343, 0x47210c72, 0x33fb3d1f,
-       0x8da8bc75, 0x22f1d5d6, 0xfbe07f5a, 0x468e8bc4, 0x78801e07, 0xae6c3fd1,
-       0x94779876, 0xea28ff25, 0x912ac4b7, 0xc5d6e4a8, 0x4a1fb7ec, 0x2e3c952f,
-       0x34a95a45, 0x81c4d04e, 0x6073ab6f, 0x582bf81c, 0xe380c54f, 0x7870c34f,
-       0x7b5846af, 0x1fa3ad9b, 0x13e40b97, 0x97e8f882, 0xfc42255f, 0x063b9145,
-       0x2fe2ac7b, 0xa197900b, 0x037fdbf0, 0xd7b57d1c, 0x00008000, 0x00088b1f,
-       0x00000000, 0x7dcdff00, 0xd5947809, 0xe77df0d5, 0x24cb2d9d, 0x7642c993,
-       0x03bbec26, 0x4eb1ab09, 0x04906008, 0x8d441007, 0xb0900938, 0xd2910364,
-       0x208196d6, 0x2b188a06, 0x0eb154b5, 0x4551fa14, 0xdb1ab61b, 0x1a4013a0,
-       0xad563414, 0x61a5afd8, 0x80891d91, 0xe58ad3fd, 0x7bdce73b, 0x264ef333,
-       0xe79f6a02, 0xcdcf0f0f, 0xcf7bde5d, 0x773dfb3d, 0x79632d49, 0x9b19223b,
-       0xed50b390, 0xccc9a906, 0x831b163c, 0x43632f1f, 0x087a3e79, 0x6b9859e6,
-       0xf26b6320, 0x01de7975, 0x9fc75d8c, 0xa269fd3b, 0x678e3e15, 0x30d6fe6c,
-       0xb53349eb, 0x7fe1d767, 0x268c5d79, 0x649f595f, 0x9fc7d93d, 0x24bf8f9f,
-       0x4c33ffc1, 0x2b1812cf, 0xe1a7e263, 0x70ffdfcb, 0xdfc7b418, 0x54dec655,
-       0x805689dd, 0x12dcdca7, 0xd8ceddd5, 0x13c7f933, 0x52d491dc, 0x223ddf87,
-       0xb97178c6, 0x71debde3, 0x55de798c, 0x0fc816d9, 0x4a3d1936, 0x64e2fc34,
-       0xe8826b76, 0x06947e0f, 0x041967c5, 0x55437ff9, 0xfe97632c, 0xc5f4a3ad,
-       0x32f2b89f, 0x7a8afbe0, 0xb439639d, 0x185068ab, 0xd1cc62cb, 0x19cd7995,
-       0x4785d58c, 0x5fd0620d, 0xa748bece, 0x292fca01, 0x8329af66, 0x870800d1,
-       0xa23fc241, 0xd41b7d35, 0xd8983757, 0xca5ec86a, 0xe119ac61, 0xd9a23bd5,
-       0x077e3f00, 0x0fa67e1d, 0x6bca00cc, 0x630b2e1d, 0xff78c29b, 0x7b64c29b,
-       0xb483347b, 0xecd192db, 0xd7a7c004, 0xf40d1633, 0x6983c481, 0x036e92f6,
-       0x1f3099f4, 0x8018f33d, 0x3eadd94e, 0xadd2f115, 0x9163aed5, 0xadf471fe,
-       0x4ddbe68c, 0x6039d76f, 0xf7813afc, 0x543b4d9d, 0xd873e03d, 0x156ada98,
-       0xf728d2d2, 0xa8f3c458, 0x2c6aaaec, 0xa8f7cd8f, 0xa59f686e, 0x00b3ed54,
-       0xe678d85e, 0xcce502d8, 0x848f8307, 0x18d616fa, 0x2398d905, 0x2828ce2d,
-       0xd9c6751f, 0x1de60038, 0xf60a62ed, 0x1a32d8c7, 0xcba45fbf, 0x38b2fd85,
-       0xfd0052a7, 0x2307fb0c, 0x767ec8bc, 0xec568d36, 0xf35c6f00, 0xc01ec518,
-       0xe24d305f, 0xfeccf5ab, 0x73d7ec53, 0xba40e748, 0x7398ebda, 0xfaefb423,
-       0x2c31bf72, 0xd2bedfca, 0xb778d0aa, 0x46b9ddbb, 0xd879f346, 0x9c8fdf0a,
-       0x0067ddee, 0xf1cf8678, 0x03da33ec, 0x519733e6, 0x1e2d297f, 0x11d2479a,
-       0x8ba60e77, 0xcfd4312d, 0xc6be33a8, 0x4baed001, 0xca07cc15, 0x543f9ad3,
-       0x5569af10, 0x71d20acd, 0x825ed367, 0x3f79b537, 0xea11814f, 0x7201dd20,
-       0x8f301755, 0xcd1d16c5, 0xa145b163, 0x99c5e574, 0x7fa82e89, 0x6c5eeac4,
-       0xc79fea19, 0x62771cca, 0xbebff415, 0x7cfb5ba9, 0xb7bc027b, 0x278867c1,
-       0xab72dfd9, 0xb269fa91, 0xf3847fb8, 0x72de9cab, 0x476f7900, 0x48a39fd3,
-       0x88e21a2e, 0x8e8709be, 0x96123d13, 0x78a0ce00, 0x0a85a1fd, 0x85f5aa83,
-       0x23a53340, 0xddb8279e, 0x8899318e, 0xf89f806f, 0x09311ac7, 0x8c62f2f8,
-       0x91c706bb, 0xd91427ed, 0xb45f5022, 0xcf77c5e7, 0x598e652e, 0xfbcf003d,
-       0x6eb2778b, 0x12f77748, 0xbb7b7ba4, 0x21878f81, 0xb38b313f, 0xa4bbfb16,
-       0xce38e9b0, 0xf942984b, 0x979e064b, 0x95abfaf8, 0xeb11ebe3, 0x7896c5a4,
-       0xf02b278e, 0xbc614bf1, 0x7a1eb05d, 0xb3bfcad7, 0xcd617e0b, 0x1e705f9c,
-       0xbb64bfa8, 0xdbdfa2dd, 0x3d5cee9d, 0x08cd93e7, 0xde11c8e7, 0xc3b7c87d,
-       0x90fb3cf3, 0xe098d3ff, 0x27ce3c93, 0xcfbefcc1, 0x467ea36a, 0x8865699d,
-       0xb9852cf7, 0xd32ee902, 0xa1ae10d7, 0x89a3dfc8, 0xb61e407f, 0x52c378e3,
-       0x800354aa, 0x13acc712, 0xdec67758, 0x5da9dab6, 0x3ee708e6, 0xd3ab37e4,
-       0x207cf245, 0x2be54ac2, 0xc07f3833, 0xfc407ff7, 0x2ed3cb05, 0x7e01a394,
-       0x7e438a39, 0x8fc8ec8c, 0xbcf013bf, 0x63a5e42d, 0x613feeff, 0x3acd71ff,
-       0x0c9d02a7, 0x65e9123f, 0xa2f874d0, 0x8fe1152a, 0x00ffc063, 0x358e6da0,
-       0xa52ce507, 0x5d20a1cc, 0x875c229b, 0x230fd4ad, 0x4732b9bd, 0xef86ade7,
-       0x893b46e6, 0x3ed8df7e, 0x366667ec, 0xc01f6fcc, 0xe115fc1e, 0xb6b07b03,
-       0x6ff4f508, 0x3d4469ff, 0xd7f2976a, 0x38a22434, 0x48ae3f80, 0xf7a7e0bd,
-       0x410bd271, 0x73d60ef4, 0xebf6f4c1, 0x039ead05, 0xf4e05d7c, 0x9f226770,
-       0x522f35c5, 0xead07eb9, 0xd1e8ceb5, 0x3a083f41, 0x7e708a5c, 0x0c5cf881,
-       0x7ae38832, 0x583eb346, 0x0e1d99de, 0x76a4898b, 0x1c3b45ff, 0xd1df1316,
-       0xadcceb0e, 0x47c01507, 0x576a8379, 0x8fd50a61, 0xff489cd9, 0x8714eb17,
-       0x41a4e509, 0x71787e25, 0x4bd93865, 0xbb67ef09, 0xdbb107a3, 0xcff21520,
-       0x8ec9dddc, 0xf188c656, 0xf18790ed, 0xd679592f, 0xc5277568, 0x1793e804,
-       0x4308be1b, 0x644ff73c, 0x62c64e03, 0x0ed6a70b, 0xf0290883, 0x537f09bd,
-       0x6b83af10, 0x69ac1454, 0x95269dee, 0xfb1dd6e8, 0xfe5ace1b, 0xbd700d9c,
-       0xceb46dbc, 0xf537c81d, 0x05ec6757, 0xb8232bf8, 0xf7b4be5d, 0x33e42f5a,
-       0x92f77f59, 0x3f7bd262, 0x13192b07, 0xeedf1fa0, 0x61eb8273, 0xd53d6856,
-       0x2a76871f, 0x850023d7, 0x7a3ee651, 0x70d427f4, 0x27f5aa87, 0x7baa3988,
-       0x7f107e02, 0xbf84e18d, 0x77209eea, 0x48e70419, 0xc5bf7fec, 0xfca092c8,
-       0xb623c80a, 0x037f7093, 0xe2074778, 0xaa6f0fd1, 0xe08454f5, 0x5f0fd50b,
-       0x0e905d3b, 0xd16abfd0, 0xb12e3cd3, 0xb3d20770, 0x4864e8ce, 0xe151cf7f,
-       0x55ba081f, 0xd4bb9e08, 0x1b88f430, 0x91e2f7e6, 0x7f7e0754, 0x984afea9,
-       0x46fd122e, 0x979c14f7, 0x851ad69a, 0xc35f70f6, 0x032dbe95, 0xc54dbf48,
-       0x4e872bf2, 0xbe03dcd8, 0x8466fcd1, 0x7e7687a6, 0x9ac8fa95, 0x6150ff40,
-       0x7cc17e7c, 0xfe3434a4, 0xf244194b, 0x7a1f50c7, 0x1ab799d2, 0xa072bde6,
-       0x997ba7e0, 0x983ee51d, 0xabab46de, 0x6e402622, 0xaaed15ff, 0x9c70b842,
-       0xcf342194, 0x741f9885, 0x41a66678, 0xc31bf387, 0x7f4a6ed0, 0xb0effd0f,
-       0x4eff7e21, 0xfe7dafce, 0x3a0daf3d, 0x3fbe68c4, 0xf80071c6, 0xaf803ae5,
-       0xeac18c12, 0xfb79c08c, 0x62e51e88, 0x48e6e57e, 0x61f30a9f, 0x5a170cbb,
-       0xd6e81ea4, 0x4fa07e11, 0x19e7c20d, 0x46e238ed, 0xd235fefa, 0xd1f88d51,
-       0x5fd15b37, 0xc6acf985, 0x28a2367a, 0x2fdfe711, 0xf505b9d2, 0x18cb4bfc,
-       0x57a5f3f1, 0x4c137798, 0x1d7efb76, 0xd646cbf1, 0x9fbef88f, 0x570cf2ee,
-       0x3af3c924, 0xb9ab3b84, 0xb77a8756, 0x43aed7a7, 0xb9b7da7d, 0x3e23a74e,
-       0x8622ff70, 0x5799e4fc, 0xff5f00f4, 0x37ea556d, 0x686f07e4, 0xaf40ef7e,
-       0x92f481cd, 0x7c16cb78, 0x43788d90, 0xbfaad083, 0xe3f662d0, 0x52c3e80d,
-       0x63fb1d6c, 0xf11d25ac, 0xe9faf8d4, 0x5fd02d5e, 0x67a71bc5, 0xfe2a5e20,
-       0x18262260, 0xd1be87f3, 0xe59fefc8, 0x2e67f684, 0xe872ad2c, 0x257a9fc1,
-       0x85d91ba6, 0x446cd632, 0x6ebca13f, 0xa01f4381, 0x76ffa5cf, 0x8f9cd0c8,
-       0xaa1a1ffd, 0xe78065b2, 0x5de18e2b, 0xd13b0858, 0xbfa12fee, 0x472fb006,
-       0xafcf11d8, 0xff734567, 0x20f646d1, 0xa5a1fdb8, 0x7a631c73, 0xa1dfde74,
-       0xbdd361c1, 0x907e7df0, 0x8634741f, 0x18b6b5db, 0x2141876e, 0x8bce113b,
-       0x3d78b7bf, 0xc8717450, 0xfd0c5147, 0x641f5dcc, 0x2e8f807a, 0xfe47e6b2,
-       0x35767288, 0xf971d692, 0x5cca3f83, 0xe5cbf166, 0xdcf8231d, 0x70ed78ef,
-       0xe7da1d94, 0xe717df6f, 0x1ddfc009, 0x9db57f4c, 0x5c7033af, 0x7d33e346,
-       0x07a42f4b, 0x04d9e3fb, 0xaff9a43b, 0xf9c715bf, 0x74874120, 0xdbf4245e,
-       0xc028b0ef, 0x525fcedf, 0xf3247c41, 0xe6666de5, 0xebc80d8d, 0x04b88d9b,
-       0x648b6f2e, 0x37b7685e, 0x7a4712c6, 0xa3259926, 0x5f14e99e, 0xe0cf8937,
-       0x43cf8972, 0xa3a6cf83, 0x2759f15f, 0x1b6f70fe, 0xf7ced76f, 0xd74fc14b,
-       0x7ceff3fb, 0x0aec3ea5, 0x8d845df1, 0x638ae9d3, 0xf7f41764, 0x1ebe8df2,
-       0xe4ed10d6, 0x4f1832fa, 0x8d2b5f6f, 0xdf7f7ec0, 0x050bca66, 0xfba6de97,
-       0x21ca7e76, 0x1fc02a80, 0x53baa6dc, 0x9c1fc26d, 0xbe8af90c, 0xbad1c657,
-       0xd08bf25a, 0x4f30777b, 0x306fca23, 0xf77a487f, 0xfadd01b0, 0x296672a3,
-       0x318bb748, 0x4237ce76, 0x047ca41e, 0x9d3831e3, 0x50ee6460, 0x62af80eb,
-       0x98c35e24, 0x23e1f407, 0xdf640d1b, 0xf8fb5f0f, 0xf7e04cde, 0xd60c1bd3,
-       0x9ce430e5, 0x3ea5f617, 0x0673f503, 0xe40aac9b, 0x3d7ddb4f, 0x5f4bee50,
-       0x0fc85d50, 0x923c37a7, 0xf3d21330, 0x0065bf20, 0x0346e947, 0xf8d9cf95,
-       0x159f9528, 0x42fa5d72, 0x97d47f7c, 0x4eaff787, 0xf9ce3a40, 0x486989ea,
-       0x6b46ed97, 0x9690c1ff, 0x631c536d, 0x6f3df002, 0xbf269873, 0xe0e6c75d,
-       0x995d243c, 0x47af6ee2, 0xa6d53f13, 0x1f7176fb, 0x04dfd69f, 0xa0aa72ff,
-       0x3029c4e3, 0x57a18aef, 0x77dfafc8, 0xc9ec9c20, 0xf92a919b, 0xffc1be8f,
-       0x20db9def, 0xde95fb9f, 0xa09dbe41, 0x674158f3, 0xb7a45cb0, 0x9f3ccc4b,
-       0xfc9ebafb, 0x4a8b5ccf, 0x91f686f8, 0x7bfea163, 0xf40fbda2, 0x5321ca2c,
-       0x848dd7b3, 0x0da36376, 0xf7d0ed0c, 0x19f2f37c, 0xdb3bc9d8, 0x025bc7f4,
-       0xd59a33e6, 0x387f41f6, 0xca821987, 0xcf2c7a9d, 0xc7cb6b35, 0x2cfbb8f6,
-       0xad630ffa, 0x77c972da, 0xfab4d88f, 0x7381df62, 0xf3009b3f, 0x92a4392b,
-       0x7d237cff, 0xafc22efc, 0x5dbf3a47, 0x3bbe0db8, 0xf872b02c, 0x4915e9da,
-       0x142357c8, 0xd3acf186, 0xe3cb42d7, 0x665ea41f, 0x7e3edf40, 0xe63816fa,
-       0xdc51e7b6, 0xa0b119ef, 0xdff08f3d, 0x7afb1ebc, 0x8d9b753d, 0xed8233c7,
-       0xfcdcb046, 0xfe46ecb7, 0x3dd2b7e0, 0x837f4a16, 0x5ced85e9, 0x89eb06ef,
-       0xe1213b60, 0xbcb7860a, 0x0fb1a74d, 0x191ea15f, 0x8c27681a, 0xc3be2764,
-       0x6d8370f5, 0x30f5c768, 0x2f8431f8, 0xad3d30cf, 0x6adfc1c3, 0x220376c4,
-       0x0039b1ed, 0xb76b0ad2, 0x167fb208, 0x405b7ef7, 0xb6ffaa1c, 0x8dea1d5a,
-       0x418cf8f6, 0xeb91a71b, 0x9d8477d5, 0x1cfa13a8, 0xceb4abd6, 0x4eee18df,
-       0xc9b8e3d4, 0x8c96c746, 0x48f9f88e, 0xcfccefb4, 0xbeac7e95, 0x8fb1fb86,
-       0x389a5d58, 0xa893eb19, 0x5fa2fb89, 0xd9edf28e, 0xfcf34e1b, 0x420d7154,
-       0xe733d439, 0xf4016ddf, 0xf87036a9, 0x8f89e183, 0x319276e5, 0xb207f917,
-       0xd0e8f67c, 0xd5895c7a, 0x679cfb53, 0xff474fef, 0x07c6d3ed, 0x7ebf51d2,
-       0xede7141a, 0x169e1e4c, 0xb0a4faf2, 0x2e223123, 0x11ca14f0, 0x9dda41e4,
-       0x55fbe1db, 0x57245d4b, 0x9d3a5d3f, 0x2e9667d2, 0xb613faa1, 0x9adf1a0c,
-       0x775767f3, 0x35c9d3c0, 0xd989d92a, 0x18af5746, 0x59a4eef8, 0x1385f147,
-       0xbb799155, 0xd19cb122, 0xb3f6727a, 0x0278b613, 0x6c277ee2, 0x6743a27a,
-       0xfd8f8cf3, 0x9cbdfa66, 0xbda144b5, 0x23d7e76a, 0x2db5ec1d, 0xac7fe316,
-       0x55db0125, 0xb6bdcd2a, 0xb7c71d29, 0x2c7c6732, 0xf59197f2, 0x0ba9b947,
-       0xb828f6e7, 0xe72c4a5d, 0x1fa1bfc3, 0x8a7efd0b, 0x9e842b76, 0x2f3a0bb1,
-       0xb1ed38b4, 0xc922efa4, 0x81b8275f, 0x728cbe5f, 0x60b84776, 0xd313d65d,
-       0x7c785d61, 0x2ac5b16e, 0xf0a9c3f8, 0x5fab8e75, 0x5bf8886c, 0x609ef167,
-       0x7811de38, 0xc9038e0d, 0x8681c654, 0xbcf9f2c6, 0xe26ab36d, 0x0eff1842,
-       0x79f9ff15, 0x1ba3d72c, 0x2a3c5bc3, 0x7c03c3ca, 0xdb25de3d, 0x2b7c60a3,
-       0x0736bf25, 0xc5775fe3, 0x2da5b8f2, 0xeb889dcf, 0xa344e4f6, 0x3736e303,
-       0xea038f2b, 0xc05f7c9c, 0xd63823ad, 0x7ac27b37, 0xcd095c01, 0xa4231cee,
-       0x0d317153, 0xaac2edf8, 0xa0dd2196, 0x6b23211d, 0x9157b87f, 0x92686c8b,
-       0x4028f429, 0x6772861a, 0x454f728c, 0x559b0cba, 0xfa718d55, 0xffbe3294,
-       0x77715670, 0x9c9f01b5, 0xa43c2b7d, 0xe8225c3f, 0xc9d194cf, 0x36b3fa68,
-       0xacae081b, 0x819f3fcd, 0xf9b59f7c, 0xa012bd2e, 0x1ac79687, 0xdf67fe68,
-       0xe295d79a, 0x58989f16, 0xea7a10cf, 0x1e5f8287, 0x69d87410, 0x8b7fcd0c,
-       0xac6fbb45, 0x55405bcf, 0xe2f9f569, 0x5b3880d8, 0xd265f945, 0xed6393e7,
-       0xfaf3ce34, 0x80c903ba, 0x3167e7cf, 0xe68a0787, 0xf148dd6d, 0xbac69dd7,
-       0xe4efb8f1, 0xa431d0a9, 0x7f03fefb, 0x7e8c9038, 0x60fb2ce4, 0xbfda23f4,
-       0x4ad2f43f, 0x0e7e7f2c, 0x4ff88c1b, 0x60ad3ef2, 0x619fe63c, 0x7faf84b5,
-       0x65b1316e, 0xbf7db718, 0x210ffc6e, 0xc74cbebf, 0xcf04bf50, 0xe832461b,
-       0x19f53112, 0xfd382374, 0xba4a0f51, 0x91190303, 0x886e921e, 0xee90edbf,
-       0xc11af2df, 0x2a9ae12f, 0xb6f3dee2, 0x7c8f1f6e, 0x53665c92, 0xe1204e30,
-       0x793d91ba, 0xd9dbf631, 0x0ed0ef93, 0x221b12bf, 0x0ec21d2e, 0x610d88ef,
-       0x2fed8387, 0x637738b3, 0xe1d91bbb, 0x36ff82e1, 0x7fed06c6, 0x08597ee0,
-       0xed8d0dba, 0x1fdf0f10, 0xe3ff621b, 0xdef0f146, 0x43ff72b1, 0xc97f0f1b,
-       0xad6ff5c8, 0x293c3d8d, 0x1374bc84, 0xb5d6ebe3, 0xc67ed11a, 0xf5212835,
-       0x518b62d9, 0x1c7e1fee, 0x125fb01b, 0xe0438fac, 0xefb628f7, 0x17b7cdbb,
-       0xe9890d5b, 0x5bee8111, 0xdeb0ebbf, 0x29ce310d, 0x22fb3f81, 0xf6a6fb46,
-       0x0afa462a, 0x141e5ef2, 0x371429f4, 0x934f38b0, 0xbec1badd, 0x1cd69dd5,
-       0x3ee483f2, 0xd6ab54d5, 0x938b8c4f, 0x239f9ced, 0xd89d699c, 0x3c097f89,
-       0x70dbfcc1, 0x4c45b8dc, 0xf7231fb3, 0x3caae261, 0xcd0b318a, 0x6af8a311,
-       0x32f758d7, 0x1d6bb403, 0x209b1cc9, 0xcd685d1f, 0x9b6a7d41, 0xfdc468e3,
-       0x7917959a, 0x02e57e3c, 0xfd4e5de6, 0x7732f9f0, 0x17ca2f37, 0x2e302dd2,
-       0xe1c71110, 0x72e38888, 0x1cd27606, 0x8f0ae1c7, 0x9293b00b, 0x3e75ba1e,
-       0x1adae895, 0xd0054eda, 0x77df46d5, 0x50efd742, 0x3771ed2e, 0x8cf71fe7,
-       0x19be05bb, 0x7c737718, 0x4b4c14f3, 0x8f04dfec, 0x0ff38997, 0x2cf80f1e,
-       0xf826ee2b, 0xee2deaec, 0x50881e8f, 0xa5dc5dbe, 0xc4275e23, 0x6b77d085,
-       0x487d75f2, 0x4770b35f, 0x233abb28, 0x7dbff22e, 0xa086645e, 0x179d2df7,
-       0x2d27f179, 0xdcb3a446, 0x06f090f7, 0xe591139f, 0x264a0d15, 0xf6733fae,
-       0xc075a35d, 0xd37fc6a5, 0x79e3a03a, 0x42ee3e0f, 0x678003e4, 0xcea03aac,
-       0x7977f207, 0xea56919b, 0x22ffb32a, 0x4df6e31b, 0x53b5e606, 0xefb6337b,
-       0x7efb78c7, 0x633656db, 0xd31faadc, 0x547ac47b, 0xa8fdceb9, 0x7ee39468,
-       0x8d5b2a4d, 0xbebcadf9, 0x6197998a, 0x847a3a5c, 0xf003d98e, 0x670ce319,
-       0xc67c00f6, 0x7934d9e6, 0x2f9e4eb9, 0x25778dc6, 0x32efbe6b, 0x7da69bbd,
-       0xa69fbb92, 0x10ce653e, 0x6aad3e4d, 0x577da694, 0xf981cfb0, 0x9addcf0c,
-       0x266bddf6, 0x6b3df26b, 0x3fb4d01f, 0xcd9eaacd, 0x9c7a79c6, 0xce003dcd,
-       0xdece0259, 0xdf358beb, 0x0dd5d7f5, 0xf920a1f3, 0xffee1f14, 0x326c16cd,
-       0xfa73c44b, 0xfa69e77a, 0x5e6aff3d, 0x9df80293, 0x19386b5d, 0x7c219f18,
-       0xea4b7e00, 0x8c1cf615, 0x5b5eba5b, 0xe9e1a73f, 0xce902995, 0xe7cb6af5,
-       0x829cbee1, 0xdf2dadfc, 0x823d73ad, 0x71ed9deb, 0xe228ce22, 0x7f03ac3d,
-       0x97b8d244, 0x9778f037, 0xc41de9ea, 0xb13a5a1f, 0x762fc96f, 0x44a62fc1,
-       0xd984bf2d, 0x7a52fcb5, 0x1f30e770, 0x88ff88eb, 0xe47c413e, 0x78017f81,
-       0xf895f897, 0x7cb438b7, 0x9de15df5, 0xdb91af31, 0x3ff96d0d, 0xb5f1b4e2,
-       0xe3ee917e, 0xd4aeb7a8, 0xbf71522f, 0x7df1e58d, 0x57f52bfb, 0x6bb21d07,
-       0xdb3ad7f6, 0x17173a4f, 0xfb175718, 0x3f709749, 0x137636f1, 0xfefb89fb,
-       0xd900f885, 0x1f801b77, 0xb98708d8, 0xcc30ff7d, 0xac147fbf, 0x760a6537,
-       0xb238cbe3, 0xd77dfe27, 0x587af86a, 0x085c5ff4, 0x9387dcaf, 0xf9e472e7,
-       0xe7c91621, 0x3c01fb29, 0xf143f1a8, 0x022d9ffc, 0xf7dbadd7, 0x96f5a42f,
-       0xc4c43f3c, 0x7e10bfb9, 0x3aefe93f, 0xfc8935fc, 0x6e78f081, 0x6d3123cf,
-       0xf9c407f7, 0x3bcf692e, 0xb7ee47eb, 0x7b2a9675, 0x6c3fda55, 0x9b1dc255,
-       0x5e93d842, 0xfd72dff1, 0x1c43a675, 0xe07c57ba, 0x2bd1ebfa, 0x00aed007,
-       0xb962fbde, 0x5af602c5, 0x5febdbf1, 0xbf114444, 0xbd541eb6, 0xb2e0a1bd,
-       0x036d1ed9, 0x6984363c, 0xab4c88ed, 0xf403c9cc, 0x3daf58b1, 0x11f727e7,
-       0x6367db83, 0x27fd80fb, 0x8fe34ef8, 0xfdc21cac, 0x6e78ecb5, 0xe488bfdf,
-       0x9114c1fe, 0x175a0caf, 0xbf70d655, 0xe9f8236c, 0x4cfd010d, 0xfb50b789,
-       0x533911a5, 0xc08e29e2, 0x332bbbd7, 0x5627f214, 0x21f90a2a, 0x5347a267,
-       0x9cb8b5fd, 0x623fc4c9, 0xbbe8299c, 0x6edaffc1, 0x38bb1e1c, 0x37fb238f,
-       0xe6f6f3c7, 0x4e94d1f8, 0xb88ab789, 0xf21fb5b3, 0x93846547, 0xa1aa35fa,
-       0xc7a6a5f7, 0xb5ad79f3, 0x6a27e930, 0x84e3fee2, 0xbf38c4de, 0xf9a3fb89,
-       0x71fc1363, 0x7f66a67e, 0xf1138c68, 0x773e857d, 0x53ba9ea2, 0x78b3bdd0,
-       0x758fb3bf, 0x75276e3f, 0x12fbf78c, 0x1dfbc643, 0x0fde28e3, 0x5e71ea5f,
-       0xa47f71c1, 0x2fcd8443, 0xb7c48f3f, 0xd45483db, 0x7746f54f, 0x5abbae35,
-       0x0eff8377, 0x2dbc7dc5, 0xf0301fb4, 0xae077750, 0xb06656af, 0xb7e416bd,
-       0x7fa18c65, 0x5ba2df5f, 0x6bf5061e, 0xf58acc3c, 0x75f03723, 0xbb7ae95b,
-       0x8069a703, 0x8865b075, 0x8bac1f5f, 0xd7bc218f, 0xc46e4cb7, 0xf73581fd,
-       0xa19a1b32, 0x1b9b565a, 0x06d0fe85, 0xf8dd7216, 0x09b39094, 0xd4557b39,
-       0xdfe8f117, 0x53d3a087, 0x0fa04e82, 0x879d22d6, 0xf0afbab7, 0x4fae38fd,
-       0xfae22548, 0x1bcebf74, 0x373f3d6a, 0xf21d773a, 0xe86f40c1, 0x0b5ac3f5,
-       0x1175b7e7, 0xdda8e7ae, 0xb5ee7e2e, 0x59dfea54, 0xba07a63a, 0x9d74114f,
-       0xdf9f81b2, 0x5faed760, 0xc89fa557, 0x7a867fa8, 0x8b5ef4a5, 0xa543e317,
-       0x821e190d, 0x7a38a5cb, 0x7868bea2, 0xd2f985df, 0xc62b2cac, 0x657f9c23,
-       0xe43ea9ca, 0xbfae3262, 0xd494ecf4, 0xe3c76427, 0xb269df68, 0x16b5b7e0,
-       0x0d473f3b, 0xfc008e28, 0xb6586e97, 0x7cefcf17, 0xfb466bf4, 0xd6d4474b,
-       0x54d9d861, 0x2192ce40, 0x2159ea98, 0xfef82bc5, 0x1fa2bdd5, 0x5c61bfcf,
-       0xa9dc7fb3, 0x3e69070d, 0x63cc0c47, 0xb4ba3e06, 0xfa3b3ee7, 0xcde32bdb,
-       0xfb93c714, 0xf75547b2, 0xf48464e3, 0xda0815ad, 0x56110dfd, 0x43fc7f8c,
-       0x82465df0, 0xc7d21f7b, 0x057c7cbd, 0x6596c1da, 0xa3c474a6, 0x1a92797b,
-       0xd7ba7007, 0xd1ef342a, 0x788c93cb, 0x8ae6617e, 0x4f50e3c1, 0x95ce610d,
-       0x2879df18, 0xd3948596, 0x9d7cf1f3, 0x60655c58, 0x849a68c6, 0x172fe311,
-       0xbf8a146b, 0x015bfee0, 0x988e67d0, 0xf7aaf95f, 0xec3f88a3, 0x1e186ff0,
-       0x733fe5cb, 0x1e494aaa, 0xe46bcec1, 0x19d58ca7, 0x799fa093, 0xdb39606b,
-       0xf1fdec8d, 0xc043fe0e, 0x3af2ef79, 0x5b257d6d, 0x7f9d39f3, 0x5befe061,
-       0xeb682ed0, 0xe8f2953f, 0xaba40e60, 0x8cc5b17b, 0x0b4684e7, 0x51ad14bc,
-       0x665fa8ac, 0xbf8c68ae, 0x9b33f20f, 0xb4f20754, 0xe8eb0bc4, 0x8f39d3ef,
-       0x693d4dcb, 0x6ed9703d, 0xdced82ef, 0x2bff5c51, 0x2c70f77a, 0x3dd6287f,
-       0xadf1d71c, 0x9e18589f, 0x06d6399b, 0x1ec618fe, 0xc5106ccd, 0xd06cac1f,
-       0x5a3b00a4, 0x6026b064, 0x16c3dfbc, 0xb7be3226, 0x779c0e65, 0xf90d79a5,
-       0x07e89581, 0x1f91f9f2, 0x672c50f8, 0x15d7d6d5, 0xeac39f3a, 0x9a07e40d,
-       0xd6781f85, 0xae009b5e, 0x6e3d7317, 0xde2d3920, 0x687e4316, 0x235c8af1,
-       0xaef16ff2, 0xe043d218, 0x63d87e07, 0xc78e9f98, 0x481e6456, 0xeb8b7e84,
-       0x96aa1c32, 0xb8ff5a7e, 0x5ba498e6, 0x4b4fbf47, 0xe8a193b7, 0x94d2f406,
-       0xff0824a7, 0x3d8bd04e, 0x477e4b16, 0x7ab782e1, 0xcb9e019a, 0xee746155,
-       0x83ff33a8, 0xbed1c6a5, 0xe6175c9e, 0xdfafb725, 0xcafcdf68, 0xb744a19a,
-       0xfde57a60, 0xb470e667, 0x16afec27, 0xa1ec7a86, 0xc9e1ecee, 0xc2b0fe50,
-       0xeaa1ebe5, 0xa72879f1, 0x6f5c0959, 0x6614b7be, 0xfdec6468, 0xece666a5,
-       0x4b07d8c5, 0x68ff94ad, 0x3fe52269, 0xf4a76a5e, 0x287da593, 0x68e2293d,
-       0x0180ce52, 0x25475f88, 0x951af970, 0x6cdee220, 0x8caa2251, 0x307cffbc,
-       0xa1c56754, 0x4d8c27d2, 0x271eec63, 0xdfc02320, 0x046f7e99, 0xdf3db912,
-       0x4b8eb062, 0x9571ff44, 0xd8befa42, 0x3da6bb75, 0x3c4625f8, 0x64facdff,
-       0x9ce9cbfa, 0x1938dd98, 0xfcfef0f8, 0x69fb4d58, 0xfc9a2935, 0xcd3b04e4,
-       0x775e527b, 0x8503f94d, 0xa2f935fd, 0x9e024036, 0xf8db302f, 0xb7d8aafe,
-       0xd7c6cc67, 0xf6de56eb, 0x2ef0d56a, 0xaf7807df, 0x7d50321e, 0x5d243d30,
-       0x31d7ad67, 0x73368037, 0xfa0dcc3d, 0x933b593d, 0x11fceae4, 0x95fdd90b,
-       0x1ddf32db, 0xdb63f901, 0x7ebfb40c, 0x5aec456c, 0xb63e3fdc, 0x418a3e2d,
-       0x32a95eea, 0x7ac1fa1f, 0xe80591ab, 0xcb15dcb7, 0x9156fce8, 0xf940e4d7,
-       0xf9efda2f, 0xd1dbcc95, 0x5120441f, 0xbd543e3e, 0xe7e8853e, 0x14befc24,
-       0xf902dde6, 0xf1afa033, 0x16ccf8c8, 0x8519d70e, 0xd9fcc0ad, 0xfaf5bfb0,
-       0xb171c03e, 0x8744b6a0, 0x50f501eb, 0x1dcbe93c, 0x2dbe432a, 0xfda0605c,
-       0xa91fb9bb, 0x94cf311b, 0xde9c2921, 0x64479d2a, 0x7fa8992f, 0x021c0ad6,
-       0xd6fd16ed, 0x77d689b4, 0x0f77e44c, 0xfc16aef4, 0x26747c89, 0x08633986,
-       0x3de08558, 0x46fc7ef7, 0xd3e3f7ac, 0xfde7083b, 0x32b5dea5, 0x5cebf801,
-       0xe9107789, 0x49e2c7b5, 0x7ef182ae, 0x96f5c8d2, 0xf140e507, 0x9cbf4beb,
-       0x9d3e272d, 0x38247069, 0x25655f48, 0xb93abea1, 0x98e740c6, 0x3519de99,
-       0x3b3fd689, 0x38e58f88, 0x71f6f527, 0x9ac9df08, 0x96fb860c, 0xf2546bc5,
-       0x78ff9007, 0xffe72f7b, 0x1b3755a7, 0x28d6fd0e, 0x23a5d66e, 0x60b23cdf,
-       0x9a639d38, 0xc141d621, 0x9033e07a, 0x7f2f7755, 0x7e1ede7e, 0xb56586ce,
-       0x181defe8, 0x7c158f38, 0xbfde44bc, 0xd650073c, 0xd1474fed, 0xd4dcbee5,
-       0xf0ed1a3d, 0xe2550fd9, 0x6addb3b3, 0x3d022587, 0x0ef6e82f, 0xcfe43efb,
-       0xe94e7817, 0xb854ff21, 0xae02677b, 0xd26b7457, 0x3e786e95, 0xdbdac4f6,
-       0xaf73bbe1, 0xe6241c18, 0x7f49e24b, 0x6e697bcc, 0x8ef3c0d7, 0x2f97f51d,
-       0x38bfef99, 0xe7c01493, 0x38dd7b7c, 0x775c00eb, 0xe21d84bb, 0xe6e3b1f8,
-       0xbac5e02a, 0xc343c14e, 0xcb50c4ec, 0x3d773c6a, 0x3024c413, 0xec42784e,
-       0x7a101f8f, 0x1109fa45, 0xa67e785d, 0x7b37f38e, 0x0dbf2155, 0xbffa347e,
-       0x944f9c52, 0xebea5f7a, 0xfb4b5632, 0xf81247c1, 0x8ab9c639, 0xe055da97,
-       0xa8a82ece, 0x420f2b12, 0x79356d97, 0x97d419bd, 0x480fd035, 0xfbe762ee,
-       0x9e57c643, 0x652db645, 0x417e7ccd, 0xbc19ceed, 0x1d19cd25, 0x75894ded,
-       0xf51b0ae3, 0xfc60706f, 0x69c854a4, 0xf5e2ad79, 0xdd9079f1, 0xd98af194,
-       0xdb066ec2, 0x28f60ea7, 0x0ecd0ec8, 0x56acb3b2, 0xde01576b, 0xc2471c48,
-       0x2ba70c1b, 0x987842c2, 0xbda17007, 0x0f7b712d, 0x15b8244c, 0x03b25007,
-       0x35cca53c, 0x01e70626, 0x477b3ef5, 0xd5e782f8, 0xcf315e01, 0x1c4bb860,
-       0xff70fb9f, 0x5187cf18, 0x1e6829bc, 0xfec11e92, 0x894ba49a, 0xa4b7e387,
-       0x7e7a2141, 0x3207eeda, 0x7e491b8a, 0x9d500581, 0x44d77bf6, 0xeba567d4,
-       0xf866ff40, 0xd3f247f9, 0x8517563c, 0x7cc152fc, 0xbe50932b, 0x46d3757c,
-       0xe1bedfa2, 0x49ca237d, 0x53d7cda1, 0x5c288317, 0xb4bcd3fb, 0x1044f580,
-       0xd7446f9e, 0x9c378a6f, 0xbdc65e95, 0x37b34f00, 0x41b0ceab, 0x1ce2769a,
-       0x60e48791, 0xc463c78e, 0xb11cc6f8, 0x9c11bfee, 0x6e7e7a95, 0x76f086fc,
-       0x5b7d27e2, 0x68baf3b8, 0x9fbf62fd, 0x943a33d5, 0xaff76a9e, 0xdffaec82,
-       0x217e3c0c, 0xbd55f1f5, 0x5025e293, 0x2aaefc2e, 0x079b8f2b, 0x2cb4f1e9,
-       0xc225e3d2, 0x4e71cbae, 0xf149dfad, 0xf768d9b7, 0x5d3fca03, 0xfee293b7,
-       0x476657c6, 0x6a7dffa1, 0x78b5ccfd, 0xb6d4ebbe, 0x4be76499, 0xde76939f,
-       0x1ff40c6d, 0xbd17d772, 0xdfe463f8, 0x9f1461ad, 0x16efd92f, 0xabd01eeb,
-       0x9ebeced0, 0x8eb651eb, 0xb452d5eb, 0x1ec80387, 0x8b76c6f6, 0x51bddc4b,
-       0xc9ca020e, 0xe99e2e4e, 0xe81eddfe, 0x11cbf177, 0xc2a10f0e, 0xdf91d3ea,
-       0x3da1f56e, 0xf1f85f2c, 0x0ee73c51, 0x1fa3fff6, 0xd90ffb48, 0x92f77a8d,
-       0xc26f282e, 0x1bab97ee, 0x27e8add3, 0x5ff13b08, 0x3439bfc0, 0xfe1087fe,
-       0x01ff118b, 0x6bc720fb, 0x06679e38, 0x1ac4ffe1, 0xdb95974e, 0xfae147ba,
-       0x774d78f1, 0x6f8eb3f2, 0x9ff849eb, 0xcff01ab5, 0x3f5a5fe3, 0x8ff006ab,
-       0x3fc408eb, 0xdfbc5bc0, 0xe0eff02e, 0x78e1aff8, 0x3a786b67, 0x3d9e03ab,
-       0xf1618e74, 0xf40e4daf, 0xf984ce1b, 0xb33a9fc8, 0x01d5655d, 0x83f4987e,
-       0xbfb560be, 0xe24d7f42, 0xe6af6e7f, 0x0a7fa841, 0x1453fe9f, 0x76ee61d2,
-       0x80efa41e, 0x82ece67f, 0xfc7fb8fe, 0x95e9bf76, 0x7e01f12e, 0xa9d24dd3,
-       0xd918b982, 0x1d3f86c5, 0xe28375c1, 0x786d4f84, 0xd7dc468f, 0xd7ded7a8,
-       0x851933c0, 0x382f8c36, 0x278466cc, 0x8a1ef835, 0xf91c619b, 0x9f3f3d9f,
-       0xbce490b1, 0x6dbe7355, 0xba19f322, 0xa758ffa0, 0xf2c6fdd0, 0x39513945,
-       0x55d4e30c, 0x2ee9c704, 0x78fce68a, 0xff23aab9, 0xfdc8ccb1, 0xf93fb948,
-       0xde0ff0ae, 0x25d7c2ed, 0xd2b175ef, 0x18c29777, 0x164b81d9, 0x23ef17a3,
-       0x112a7ac0, 0x31ecf7c7, 0x228edd11, 0xd57f804c, 0x6036e228, 0x1f4f9102,
-       0x1f4f9c64, 0x38a26c8c, 0x5e54ac39, 0xd0f8bb40, 0xfc839312, 0x8a68b8da,
-       0xf4203ed7, 0x2b9183dd, 0x1e1f685d, 0x313a348a, 0x783d7e85, 0x1a30ce88,
-       0x0df18786, 0xafba46c9, 0x796e6853, 0x0fbe9705, 0xd4789e27, 0x06dea00c,
-       0x55c637ee, 0xd75dd7e0, 0xc5d23b63, 0x9c6d1f4f, 0x743c32a7, 0xe055a3dc,
-       0x293a714b, 0xbe82639e, 0x2b8e01c3, 0xdcb12f68, 0x9df1e56e, 0x8b27400d,
-       0xe5c1be9f, 0x03f7c3cc, 0xe35cf0ca, 0x6419c628, 0x935fe104, 0xfaf2332f,
-       0x26afc4f0, 0xec66cbac, 0x103ecccf, 0x3a8656e9, 0x45f7d704, 0x978c5ed1,
-       0x25f183df, 0xe27aa61b, 0xe67ac997, 0x26b4f1d1, 0x89cccf12, 0x8144d378,
-       0x9823a9cf, 0xeef01a2f, 0x778da83b, 0xf9d3e7dd, 0xef7e037a, 0x911afbd1,
-       0xbb66753f, 0xb8e30ac1, 0xb82194f2, 0x7e5b292e, 0x25a6f073, 0xa5d7f39a,
-       0xcfc75e42, 0x80feb585, 0x041e21c7, 0xcdbc4561, 0xeafdb3d0, 0x8807ce10,
-       0xdd9b4a97, 0x2816ed43, 0x71950f14, 0xc1ff4936, 0x1d207dd0, 0x41f0141f,
-       0xf851353f, 0xbd3431bd, 0xf5ca26fa, 0xabad1d73, 0x9bb90be7, 0x9b6de52f,
-       0x27c6de56, 0x82bda9da, 0xede0307e, 0x26769141, 0xff44e317, 0x5cb912e3,
-       0x78e2dd64, 0x9d35b22c, 0x7908b7ce, 0xfef13729, 0x88f7f8e5, 0x8da24c74,
-       0x00f095fa, 0x7ec71ebf, 0x9001a074, 0x56d64f5f, 0x87347f93, 0x33b5c405,
-       0x5f24edfc, 0xebb7cc77, 0x4c75dd11, 0x10b3ad8d, 0xc2f7caf5, 0x1f47a81c,
-       0xacf5d634, 0x4ed8ec8a, 0xb214dbee, 0x3d230366, 0xc261e229, 0x23558cfe,
-       0xa1407ce9, 0x5e0fefc2, 0x7478b1ca, 0x31a718d1, 0x630b6910, 0xf13f3a14,
-       0xf27fb137, 0x89e2f450, 0x5185d728, 0x33a63d46, 0xfbf52b58, 0xe8b76b77,
-       0x33de18fb, 0x0e763156, 0x77c88f03, 0xa8d5b8c2, 0x8d7e7877, 0x4aa29b33,
-       0x21c77f22, 0xdee1e027, 0xca7f406b, 0x09df2f7f, 0x4b7a5ffd, 0xe93bb3d4,
-       0x0b8f4bfb, 0xf2e4f63e, 0x7d65cffc, 0x92afcf1e, 0xff3cf9f5, 0xe45feca4,
-       0x5faa0e9f, 0x4bff5416, 0x3ebc5f9e, 0x7e83df3f, 0xd2ce68eb, 0xd214a385,
-       0xbe847b53, 0x23ee5c28, 0xf6ea16fc, 0xf33474f2, 0xdc6eb2e9, 0x6ba2536e,
-       0xd51fda0f, 0xf682d272, 0x2764d5f7, 0x704f9fe5, 0x75c44b2f, 0x63c524d4,
-       0xa1fb7d44, 0xc4c1ec97, 0xed1fce4e, 0xf8e3c2e9, 0xbfa0929b, 0x05fb7ea1,
-       0x8c4eacfd, 0x1c7ef5bf, 0x80ae1c49, 0x26f99e7e, 0x23a7fcf0, 0x49be1b3c,
-       0xb592b33f, 0x487f48fd, 0x86be7549, 0xe32763f3, 0xe645e734, 0x8d11c4ff,
-       0xe78627f1, 0xf3f50045, 0x67a5d797, 0x5ff3ff42, 0x04bd3d7d, 0xe76125fd,
-       0xcc74da2b, 0xdb34f789, 0x1be7a518, 0x7de2313f, 0x8d5d8ab3, 0xaed071c6,
-       0x00dcd212, 0x9c04cab8, 0x93f4e760, 0x8373ec03, 0x3d8c1bd0, 0x5f37f7cd,
-       0x7a47ab3d, 0x9dd5d7ce, 0xf6ed0e7a, 0x3ee42528, 0xddf166cd, 0x17ce4ed1,
-       0xe87a15ef, 0x11b39a6a, 0x8c6bf9e7, 0xb73e4021, 0x60fb93ba, 0x855f1c49,
-       0x1ccdeec2, 0x01db3166, 0xe43f43cf, 0x1b2554fb, 0x3c608632, 0xd184cdf8,
-       0x6d7e24ef, 0xc795b53c, 0x3c781b53, 0xbcd6d0b5, 0x33379408, 0x31ad9526,
-       0x84d8c1df, 0x0339485f, 0xf36f8591, 0x9d5f324c, 0xc79b263f, 0x767f30bb,
-       0x506b63fd, 0xb9c29a6e, 0xf0d0fb1f, 0x17a8e181, 0x7422325a, 0x37e79056,
-       0x498c8be3, 0x8efcb143, 0x639e5871, 0x222af4b2, 0x8be232fc, 0xc75de337,
-       0x3db05f90, 0x46dc41c6, 0x307dfc5f, 0x2adbf70f, 0x0f75a79d, 0xda87708a,
-       0xc087fa77, 0x4ac931ab, 0x19901369, 0x870917fd, 0xf9fc1f1c, 0xdfd0cd45,
-       0x8349e5c9, 0x9f71db57, 0x3490c725, 0x467e3fd4, 0xe072fb82, 0xac7527f8,
-       0x6e292e17, 0x024b8e16, 0x5dee030e, 0xd95dbe03, 0xac06732a, 0x898f26f3,
-       0xcdefe4d0, 0xc0ce658f, 0x29bded38, 0xc2f4fc9a, 0x0ff69aee, 0xa9afeacc,
-       0x6735302f, 0xb1f80555, 0x1e49fb9d, 0x62d2a782, 0xee7f4709, 0xfc5f0def,
-       0xfff441e5, 0xf40eab36, 0xd9eee755, 0xa1db97f2, 0x4e3c65d5, 0x3b47f145,
-       0xc9cecbc5, 0xa77a28f3, 0xe85f703e, 0xf3a66b22, 0x03ed9d3e, 0x7cee75c9,
-       0x773a7eeb, 0x03ef5df6, 0xeb124af5, 0x086c21dd, 0x55cbc3da, 0xaebc511f,
-       0xefcf9222, 0x8cc7ebe2, 0xfb8a0fb8, 0xdf81d78a, 0xd10fc2ef, 0x50f36c3f,
-       0xfeb73b3c, 0x1d9bed18, 0xba7ae448, 0x1e817522, 0x42551def, 0x1c68768a,
-       0xe068abe8, 0x3646e697, 0xbbee1770, 0x1fb85866, 0xb19936de, 0x1e2be458,
-       0x884a69df, 0xf3d77ba1, 0xbca8f26b, 0xfa9c2da2, 0x1e6d4f7f, 0x5f09e747,
-       0xa1ff6853, 0xe5a1e520, 0x29b87e78, 0x11e033dc, 0x77e0b718, 0xde21e577,
-       0xf3f1762a, 0x9fea05b5, 0x5a4016b3, 0xdf479b56, 0x49aca817, 0x42617f01,
-       0x05bfb72e, 0xaf21f368, 0x46acb30e, 0x7d1aabbb, 0x3d479ebd, 0x9e90b463,
-       0x807b6e89, 0x336cafc6, 0x24f7f7d3, 0xd0d77f71, 0xdb1ae1c2, 0xc972a2e6,
-       0xba93530f, 0x860fd669, 0x7c7acdf8, 0xc2d0c397, 0x6dddfda8, 0xf39528fd,
-       0xafcfbb7d, 0x21ae3ee9, 0x14b8eafe, 0x71dbf798, 0x90dc958a, 0xa57c3d20,
-       0x0b34786a, 0xc7daa7a1, 0xf4e7e369, 0xdcfc6d4c, 0x738a615e, 0x31c0127e,
-       0x3d16b1f1, 0x48b107ee, 0x35f115b3, 0x7b60c471, 0xa97c8049, 0x2237ef7b,
-       0xdeeb0c7d, 0x369da237, 0x501b9a41, 0x33ce2e5f, 0x05e9eb04, 0x2f4f5249,
-       0x1dda54a3, 0xf9067576, 0x82ac33a9, 0xccfc8501, 0x7e54fa10, 0x1a6b4cdf,
-       0x1e6ee3a0, 0xc5347fc7, 0x45f502bd, 0xbe9b0e73, 0x7366f483, 0x7cc3ee3a,
-       0x9d03f057, 0x89f90acd, 0x751e742d, 0x0ebb08e2, 0x04abffe3, 0x6f8e525c,
-       0xa2c58f34, 0x5b2a7bfd, 0x77befd82, 0x4ecd9de7, 0x47f1afe8, 0x0f689999,
-       0x25cfb8e4, 0xcc297bf1, 0xd70d7ada, 0x446f9583, 0x0bde51d8, 0xfb863170,
-       0xb44c7b9d, 0xda72814e, 0xc37ca8cf, 0x89ef09b4, 0x7ac14654, 0x7dcfc615,
-       0x7c87cc33, 0x9866f8dc, 0xef46ed1e, 0x4873f774, 0x7b37dccf, 0xa1f5c18f,
-       0x67a4c1b3, 0x9f38f7e4, 0x09db3d27, 0x5bd237bc, 0xe5267cc1, 0xe5c35dd3,
-       0x69f048a5, 0xb73f90b1, 0x552ba390, 0xaf0e485d, 0xe340063c, 0xca63e93e,
-       0x27e85dc0, 0x7ef42dd8, 0x02cb9493, 0x79410f5c, 0x3a18ff41, 0x8dfd2bff,
-       0x6b2c3960, 0xe5bf52b3, 0xef21766d, 0xb94bca36, 0x6372162b, 0x2cc67e12,
-       0x53bbe7c1, 0x5e20efdc, 0xee41aa0a, 0x3f1f68a3, 0xcfc9e50b, 0xf22b4637,
-       0x624df017, 0x54fc8049, 0xd0cfde37, 0xb9c5313f, 0x41666f88, 0xcc9fe81a,
-       0xac4ff76e, 0xfe0012e3, 0x74322b89, 0x9da9df78, 0xe6f9db7f, 0x8f7ff8e6,
-       0x48e29790, 0x67f44f5f, 0x0e61550d, 0x397e873c, 0x2cf7ef8e, 0xb8f1c55c,
-       0x45cae0d0, 0x2fe162ff, 0xa1978a15, 0x697a81df, 0x632a91d8, 0xfee51c60,
-       0x0ecc41b6, 0xd6d29878, 0x1337d283, 0x0f1147dc, 0x04d36d45, 0xa37d06be,
-       0x4ea1c5fd, 0x7832471e, 0x198d8e4d, 0xab724718, 0x6933e748, 0xe04cfacc,
-       0x1d7ade7e, 0xbee4c3c5, 0x992b8ca3, 0x807cbcf0, 0x5f42fd1d, 0x37ef4e9b,
-       0x7299c704, 0xb0bfddb8, 0xbf7640d9, 0xc3cff1ac, 0x2e7f5074, 0xed05d9c3,
-       0x777a97c9, 0xbcf5f21b, 0x0d57dec9, 0xe4ff9f90, 0x7691a8ce, 0xf4eb3e3f,
-       0x47689ebe, 0x188f00eb, 0xa35baaef, 0xbfb979e6, 0xc9f7c113, 0x7e4b7f38,
-       0x79f3e60e, 0x9f88dd6d, 0xc89954ae, 0xbe015d0e, 0x48760165, 0xe7a91dda,
-       0x7c91fda5, 0xfae7ae5d, 0xda323cab, 0xb408c9eb, 0x395c933b, 0xf87d77c8,
-       0xddbf1a79, 0x1476b4d9, 0x38a5c1ca, 0xed28b73a, 0xbc1cb046, 0xd31c14b6,
-       0x8eed1d5e, 0xcf52ebd4, 0xfa35bb4b, 0xfe772fe5, 0x8a55cd15, 0xe032407b,
-       0xb73d6eeb, 0x2deb775f, 0xe3633fc4, 0x6f91e926, 0x1e8f5e6e, 0x98f47a13,
-       0x74568f46, 0x27060762, 0x741c9adf, 0x4cf3ed15, 0x3d447fdc, 0xa3dfd81f,
-       0xe0c7a329, 0x7327c63c, 0xc15dfb3b, 0x1ffe99dd, 0xfa6b7c9f, 0x88b2587f,
-       0xff40ddf7, 0xfd732617, 0x99efac1f, 0x73a7bf95, 0x2f5f4f69, 0x0ca383da,
-       0xc1da03ec, 0x16fb0886, 0x5ec80f61, 0xbf7b4784, 0x4d5c1ece, 0x7888599b,
-       0x1e0f610a, 0xf616fe4a, 0x94a1f240, 0x5227291b, 0x48e5822e, 0x9f84c5ca,
-       0xe9113ac2, 0x57bf1ef4, 0x6cf7ae50, 0x7b46fda3, 0xcf9460c4, 0x976e3f76,
-       0xc1d6f242, 0xf1f9084e, 0x6ed68bcb, 0xf290b948, 0x5ca7e522, 0x20ecc5c8,
-       0xd6a7d8b9, 0xf70a333d, 0x6bdd92cb, 0x72fde393, 0xd823b652, 0x57ca743e,
-       0xb3645918, 0xf218aae3, 0x81a43955, 0x44ea657c, 0xbe499e1e, 0xd968bf35,
-       0x6fd3f24d, 0xf4fcfbfe, 0xe9f84e9b, 0x3f0dbe7f, 0x3f63f475, 0x3c03b2ce,
-       0xdf40b257, 0x6df9f866, 0xfb8c3bc2, 0x7af9dd0f, 0x0497d600, 0x8d319377,
-       0xae133ee2, 0x2f8a2ab3, 0x7494be0a, 0x6cc0fe96, 0x93387711, 0xe1077ae2,
-       0x82c0f5c5, 0x447bd39b, 0xb35c5367, 0xb327d711, 0x03f40d21, 0x9b7ff33a,
-       0xbdef516f, 0x3e749371, 0xfb9dfc96, 0x4392c78d, 0xb1c78dfb, 0xb5d29bfc,
-       0xf8899720, 0x300b8fde, 0x29e138de, 0x0acb6791, 0x46d38f10, 0x3c9ffac8,
-       0xfa81ece9, 0x38b8c981, 0x53de39c5, 0xf4b3de45, 0x3f6818f0, 0x8fe619e1,
-       0xd8fd439b, 0xb8f6e8ec, 0xedfcc288, 0x3b1fe795, 0x51e886bc, 0xddcce5cb,
-       0x3ffbe7a2, 0x79059f22, 0x447e404b, 0x6f037e50, 0x616fa51f, 0x9045e781,
-       0x9c21949f, 0xff00aece, 0x7fdf8601, 0x5585ed05, 0xa8d71861, 0xd6f8db8c,
-       0xf56bd415, 0xb545ed0a, 0x14d581e3, 0xfbc55338, 0x735f94b9, 0xc23e09d8,
-       0xbe78bb03, 0x93ed4a4f, 0x37e8bd1e, 0xa1bddce0, 0xb9d2714e, 0xb78a1183,
-       0x7c47465b, 0xdad149f7, 0x6bd1fc27, 0x1e7867bf, 0x6fbe56ef, 0x8dd6cfbf,
-       0x6e99f7be, 0xb2fbfc61, 0xfe7f9f43, 0xefe70a5e, 0x21d15931, 0xa8a5c7eb,
-       0x37111fbc, 0x68a1f1a0, 0x7be85d4a, 0xb8c513b0, 0x425fb8cd, 0x24f6dcf8,
-       0x28d9b7e2, 0x93f2fdf1, 0x196377c8, 0x60cfc4d3, 0x9fdfca7c, 0x8d4172f2,
-       0x19d74f9e, 0x9bafaf84, 0xa91480ef, 0xf2f8fdbf, 0xf4cbd104, 0x8476f835,
-       0xfb5db7c0, 0xe8ebefbd, 0xf7c3ac35, 0x48e76f82, 0xf86a763e, 0x22ef5a3d,
-       0x538e8cfe, 0x5747e8ac, 0xe0d6c2b8, 0x9f2fc17a, 0x6cbe27bf, 0x1d03fb96,
-       0x02b5efe4, 0x890abf94, 0x4febcf47, 0x74bafca2, 0x3cb9eded, 0x7335f3b6,
-       0x52bc01f6, 0x7fbe0fc8, 0x27faf9e4, 0x7c092e31, 0xd794f541, 0x2c1dc007,
-       0xf941758f, 0x15f920ec, 0x03fa47f2, 0xa9e001ed, 0xb8b7ea27, 0x007b4663,
-       0xd04cfc9f, 0x27b8a2e9, 0xfb9a3cda, 0x78ddcd93, 0xfb8523ba, 0x7c09cf8f,
-       0x9bed126e, 0x90f003c3, 0x1f1fe1aa, 0xe6025bae, 0x3fba784d, 0x93fbce4e,
-       0x63d07c82, 0xbf5e36cd, 0x27a3e52d, 0x7cfed93d, 0xa6af7f70, 0x7880527c,
-       0xf1fff7f1, 0xee23f461, 0x91db7817, 0x27b0e472, 0xc139d052, 0xf0214eff,
-       0x5163bd07, 0x74a1fc8e, 0x761f8fe4, 0xd04f4fe4, 0x774ef4f7, 0x3a7bdf67,
-       0xfa0cef7e, 0xea3de19e, 0xd05eff9b, 0xae883f2d, 0x1d744179, 0x942f9413,
-       0xff46af79, 0x5c5cbd4a, 0x09e3f4ff, 0x54df1871, 0x9fbf38e8, 0xbd934f9f,
-       0xfc956f99, 0xf230e67b, 0xcf9f9fab, 0xd7279e12, 0xce79ba09, 0x787a893d,
-       0x51e1ea12, 0xd414fcfe, 0x5f3f9443, 0x7e61fb80, 0xea81757b, 0xed91abef,
-       0x7afd922f, 0xefec8560, 0x3a4bca33, 0xb225cf32, 0xbd0bf777, 0xa4ad3cc3,
-       0xf035e7f7, 0xfe7d3fef, 0x2b5fc3f3, 0x7841b50f, 0xf79410d9, 0x775fb504,
-       0x22b6fb03, 0x82c7fbe8, 0xe504d7ea, 0x6be507d7, 0xcd17dfb4, 0x8b0e4852,
-       0xc9fdf046, 0xe60cb960, 0xda522f8f, 0xf6ed63e3, 0xff24895c, 0x1357234e,
-       0xfafe79aa, 0xa829fff3, 0xa7c80c89, 0xb21e89b0, 0xc05a30ef, 0xb9d041fd,
-       0xc1f8151e, 0xbcde89d0, 0xecde99d8, 0x79ef6c13, 0xd7f03ffd, 0xd22fda24,
-       0x54fb25f8, 0x9551be6d, 0xbbbd4770, 0x5f603228, 0xe2265995, 0xfdf3baba,
-       0x6389889b, 0x22fc0352, 0x6744f84f, 0xfb653cc0, 0x575d5f71, 0xd4f8bc71,
-       0x719b89f0, 0xd8b4687f, 0x14f1b4d7, 0xf68aa5ec, 0x6fc452ba, 0x5d39e1c6,
-       0xebee176c, 0x0fd030b9, 0x70bd7562, 0x523f8d9e, 0xd550bbf9, 0x53c01f40,
-       0x79d3b311, 0xea7899d3, 0x47d43bbe, 0x0df92f47, 0x47efb77c, 0xd3b412ea,
-       0xd2c49747, 0xa945a639, 0x17dcefdc, 0x366135dd, 0x1e231be4, 0xf8db7d26,
-       0xf74a58c4, 0xad95ceaa, 0x353ae856, 0x5f646279, 0x3c268fac, 0x4fc43639,
-       0x9dfc065c, 0x38276a99, 0x426b36dc, 0xabdbfa3d, 0x085fb40d, 0xfc457e2d,
-       0x3069a4f3, 0x968bb7ae, 0xb0fda7f5, 0x1a4f9fe2, 0x8ab0f787, 0x3ed0371f,
-       0x4ace8b49, 0xeaf72271, 0x6a2e74b1, 0x7a910ad6, 0xcdf4a2ee, 0x1abafcff,
-       0xbeb569ef, 0x0efbd0a0, 0x7bad5c77, 0x9b9e1067, 0xf74ee9ac, 0x7580de2e,
-       0x3efb9e00, 0x17b7bebe, 0x089f21cf, 0xa473a2ab, 0x8bee9ed0, 0xbfb35e95,
-       0xdb0b313b, 0xd0e5d6ab, 0xa39414fe, 0x956a7cff, 0x41ef09ba, 0xc2594515,
-       0xa9f6fcf1, 0x75c518af, 0xa26e3d4e, 0x478e2277, 0x8fac67ba, 0xe8b8fba3,
-       0x8a53b3e9, 0x3c014a3d, 0x67d0da4c, 0x96126262, 0xfb7d049b, 0x1e011544,
-       0xfced748a, 0x24a4f643, 0xa527e786, 0x05b899f6, 0x97ea71e6, 0xd87ce9bd,
-       0xe4e754c1, 0x2fd7c054, 0x52539cd2, 0x6e5e11e3, 0x0ffcdeb7, 0xe3fc8fdf,
-       0xe404e285, 0x395287af, 0x56d1bf5f, 0xbef8109c, 0x3d45c977, 0x469bc1f1,
-       0x277a22fb, 0xc14d3c30, 0x41f03675, 0x67cdc62c, 0xf00b7589, 0x219d92f3,
-       0xa9e1abfc, 0xf1abd12a, 0x48d9f1a7, 0x0f5f3f5f, 0x19f5177f, 0x5f2037ad,
-       0x2d7321b1, 0xa693b9da, 0x0f44ec25, 0x91fe7ed6, 0x3c230bed, 0x7985b619,
-       0x7e3032c3, 0xfc871cea, 0x7aeb12cd, 0xc804b64d, 0x77ff68a1, 0xfbe73f0f,
-       0xeb8f6877, 0xfe7bbfbe, 0x9fb812d7, 0x4697db21, 0x5ce83c59, 0xf458b69c,
-       0xfaa38f48, 0x3cf0a7a5, 0x060bc95a, 0x2f2503b2, 0x8ad63fc4, 0x06f807fa,
-       0xf3c16be3, 0x81aa63fa, 0x933a31c7, 0xad18cf4b, 0x1331b25c, 0xc99dbe71,
-       0xdc86cd65, 0x3b239b89, 0x2b52cb97, 0x5ee34fd7, 0x9651efe0, 0x71e8b50e,
-       0x0bf4737f, 0x7ba16d6f, 0x86c20b74, 0xd289bde0, 0xaf444c17, 0x63c58b16,
-       0x13ef0dbd, 0x9031f458, 0xedca9b3e, 0x9f90bd69, 0xcde9955c, 0x7ba52843,
-       0xf0df7212, 0x9e6792ec, 0xe797e3c5, 0x70da7798, 0x2765dfc0, 0xbbcbd3e7,
-       0x063f8a54, 0x1f9623ef, 0x61cc69dc, 0x788fb137, 0x32c3fd83, 0xdfde22d6,
-       0xf07dfd0d, 0xa9abe1fe, 0x0687fbc1, 0x2a5e4fba, 0x37730ff6, 0xe9770428,
-       0x3fcf7e12, 0x8dc79637, 0xfa052e4f, 0x1ede691b, 0x0f3c10eb, 0x294eedcd,
-       0xf866bc53, 0x0b0daef5, 0x13d98e28, 0x6e7184f1, 0x89e26ef1, 0xae3a4730,
-       0x085e4bf3, 0xfe96fc23, 0x7e5fee6a, 0xfaf78599, 0xd702e20a, 0x2f91fbd5,
-       0xde197e38, 0x9cfd941f, 0x7a63f65e, 0x45f731a7, 0x7cc31f58, 0xabd8634a,
-       0xbd2067f7, 0x9f71d292, 0x5d2bb653, 0xbc5ea3fe, 0x61afac1d, 0x4ab45d1d,
-       0xecc7efe5, 0x041d9136, 0x01644f59, 0xad672cf7, 0x72346838, 0x8712c63b,
-       0xeedaff09, 0x1c769fbf, 0x6eeaf1ea, 0x2687b8a5, 0x51ef27f1, 0xfbf8e915,
-       0x853a8574, 0x268157ee, 0x97497ba3, 0x7b5fb953, 0x679f953a, 0xd0774a28,
-       0xb5f29cfd, 0x0cf2c726, 0x7dfb4fde, 0x95df584f, 0x684b9aeb, 0x26f7f33f,
-       0xae54ab8a, 0x45867308, 0x3b17f3f1, 0x6af9d006, 0x51f011bd, 0xe2fae766,
-       0xa56f98b2, 0x745dd27d, 0x8ecf419f, 0xdcbea1e8, 0x7963f5c2, 0x923de00c,
-       0x186e8a33, 0xe8c767be, 0x9bf624dc, 0x7c602834, 0x3f439445, 0xbf7f28f6,
-       0x83563a4d, 0xdf6c1b71, 0x31e21077, 0x8474da76, 0xe49515ef, 0x76b49019,
-       0xaf7dfa04, 0xdeb899a8, 0x6fb55a2e, 0xf9dfea1c, 0x8de307db, 0xeaf45609,
-       0xe63f6407, 0x88b7fa0b, 0x90c56773, 0x22b677c7, 0xb93cb8d2, 0x8a2f1e55,
-       0xef345348, 0xf2fac910, 0xbf1e0655, 0x8a8f3d07, 0xc7d97ca5, 0xa5b96fd4,
-       0x6ff50139, 0x30c36ef9, 0x6951d3d4, 0x978b2e5c, 0x011f65a5, 0x44362abe,
-       0x6583bbd3, 0xe623029e, 0xca156acb, 0x4f8bbffb, 0xbf3d3e47, 0xe428b5e2,
-       0xbe61139f, 0x5a97689e, 0xe8398417, 0xc795a1de, 0xe8afceeb, 0x6695f749,
-       0xf82d9b59, 0x45acc19e, 0xbfa86ddd, 0x467d5a8f, 0x975a3fac, 0xd3bcc3a1,
-       0xbcc6cd6a, 0xe51b7f53, 0x2df38bcf, 0xa57c83f4, 0x6d973a70, 0xbfc467db,
-       0xcc44324f, 0x1f2be2f7, 0x4ff8c2f4, 0x2f737a79, 0x07c02bb4, 0xcf1052bd,
-       0x9764292f, 0xf3f1b62b, 0x2a0f92ee, 0xee400f90, 0xa83e09e6, 0xf7daf5d8,
-       0x902a1e51, 0xf23a43fe, 0x7ef3f011, 0x71b1df2a, 0xefdfe31c, 0x76913e47,
-       0x0c2bf20c, 0xf1df8c36, 0xa71a667c, 0xe18f943f, 0xfc019ee5, 0x39fb5d1c,
-       0x741c8d04, 0x1a575f46, 0xcbc587b7, 0x5d6fa44c, 0x5a1e5c69, 0x428eed56,
-       0x657c5dfa, 0x67dc01df, 0x5601df29, 0x1e421eda, 0x712a3e04, 0x3f0451fe,
-       0x389517f9, 0xfcff28df, 0xc85ef9db, 0xf3e32561, 0xd4adf393, 0x7acbf98b,
-       0xc124fdf1, 0xe04c652f, 0x2e6f576b, 0x50ce4277, 0x0ebde98e, 0x4db73f31,
-       0xf7e50efb, 0x22dcfcc5, 0x28bad665, 0x17d20fc4, 0x103e0ff5, 0x04fa9469,
-       0xbedc5c9a, 0x4bf1ce91, 0x57f8497a, 0xdf403809, 0x7e6c6339, 0xf274b63a,
-       0xe095644e, 0x778f639b, 0xfc07af49, 0xcf4adf9d, 0xeabf116c, 0x7c93c603,
-       0x7dcbc723, 0x38ddd279, 0x87dfe86f, 0x8f71cbfd, 0xd8f4227a, 0xe5c651cf,
-       0xe52fc243, 0xa1fab732, 0x614707bb, 0xee968bbb, 0x9cde7003, 0xacd2ab8e,
-       0xfd13bdf4, 0x59def805, 0xfadc50af, 0x1fe75898, 0xa8b5fc7b, 0x7e7e01e2,
-       0x277c427f, 0x307f0cf9, 0x6de1263e, 0x7038f1b2, 0x0f52dc30, 0x9f73b849,
-       0x2c6eefb8, 0xbee3f097, 0x4a9f2051, 0x957e4a3c, 0xf982f5f7, 0xda4e7896,
-       0xfe73b54f, 0x463d4cae, 0x943a77e7, 0xfc27f707, 0x5ce213a2, 0xe33c6b79,
-       0x8915ff71, 0x8af735fb, 0xb40c8b18, 0xc08ed23f, 0x807d1acf, 0xa7bf69fd,
-       0x8b3ce716, 0xd690bb74, 0xc73ffa8d, 0xd0398cea, 0xe699d96f, 0x9dcef871,
-       0xb8ef43f4, 0x31a353ea, 0x9f8bb55e, 0x52fc9377, 0xc93f6176, 0xffb8b941,
-       0x83eab454, 0xefc8e182, 0xbed035bf, 0x63e3d14e, 0xcfdfe88d, 0x187332dd,
-       0x41ef01a2, 0xbb3f5ea0, 0xbf266879, 0x984d6059, 0x3621f786, 0x01ed333f,
-       0xaf559f28, 0xd80dbbd2, 0xd16fca0f, 0x5f1499a3, 0x52d6113d, 0xf8fd0a30,
-       0xf456a81f, 0x32df6fe3, 0x7f6c31f4, 0x0c6ba5bb, 0x39b1b63d, 0x7d4ef296,
-       0xe907d934, 0x8073caf7, 0xc7dee2d5, 0x3fde845f, 0xe22a9edc, 0x2f755ffc,
-       0xdd6f8fdc, 0xacef4618, 0x75ed1a14, 0x4f6f1c3e, 0x54675a17, 0x23eaf11a,
-       0xbf255bdd, 0x99918e6c, 0xb9508693, 0x0fca0939, 0x451f9a1a, 0x51f0723b,
-       0x3f7c60cb, 0x86d7a992, 0x9a7f7315, 0x6ac63bef, 0x70912ddf, 0x0fc6247c,
-       0xdf7e4fee, 0x1b08eb84, 0xefa44fdd, 0xedf8aecf, 0x6783b434, 0xe1b4f6b7,
-       0x09ef4fbc, 0xa703fba3, 0xcf77da0d, 0x57def56e, 0x79297df0, 0x9a74f56f,
-       0xfc938fd6, 0x377bc37e, 0x839ed37f, 0xa5b9d1bc, 0xdd194b0b, 0x8d397efb,
-       0x2263f7d1, 0xe789dabe, 0x4d6a4b08, 0x7307bc56, 0xf71ef912, 0xfcab76b3,
-       0xcb99a5fe, 0x99ddc9c1, 0xe4b7bf74, 0x525f3c6f, 0x3ef178a7, 0x9fa7fef2,
-       0xb30af3a0, 0xabc4cfc1, 0xf3feed09, 0xa1a7a7ba, 0xb8765c38, 0xfe7de257,
-       0xf9f95bcb, 0x32ef0e8a, 0x2079dc1c, 0xdfb9dec9, 0xcbfb5dfc, 0x9f110e32,
-       0x2fcfbdae, 0x4fd72cf1, 0x8c3f026f, 0xdbc7e218, 0x90e74b67, 0xa9617cbf,
-       0xca4bd29b, 0x23b7b5b1, 0xe9a25b1f, 0xeb1fc0be, 0xbdf1519f, 0x835df2a8,
-       0x783ae1af, 0xbd346454, 0xd2d9f293, 0x7a8fb425, 0xa5156961, 0x0e32de92,
-       0x46aec777, 0xfab3eefa, 0x9fbc06cc, 0xb46446fb, 0x90b603b0, 0xdeeced74,
-       0xb9d79cb1, 0x4afa701f, 0x9d6dcfb8, 0x6af38519, 0x61b63e7c, 0x2235d224,
-       0x5f7e8ada, 0x724738a9, 0xabf73d6a, 0x7fa398cf, 0x3df40f93, 0x024a61b3,
-       0xbb3737be, 0x5869def1, 0xb147b25e, 0xb1c07ae2, 0xae145267, 0xb7d53edb,
-       0xa8fde144, 0x7bcbd74f, 0x3bfa5e55, 0xd8f2a354, 0xca3f6c14, 0x0cf667a7,
-       0x7c8d75be, 0x9e82f232, 0x879ebfee, 0x5c938a72, 0x0938a70b, 0xb9e2c4fc,
-       0xf3afd991, 0x3afb4af8, 0x6ef3ac57, 0x347ef317, 0x31f726dd, 0x04773ca8,
-       0x61bd3f2f, 0xefec44e7, 0x158366ec, 0xb36cfee1, 0x079ffa81, 0xc01d33eb,
-       0x5f2b667b, 0xd71e60f7, 0xf2b767cb, 0x3abccdf5, 0x5f29bebe, 0xfbf27060,
-       0xcc7e5aa2, 0xef47680d, 0x5ef274fb, 0x9f273cc8, 0x97b03cdf, 0xbe60df38,
-       0x7475618d, 0x9e9bec8f, 0xdbe60d17, 0x855f92f9, 0xd7e7687e, 0xe044f8ce,
-       0xf91de513, 0xbcc3f255, 0xdedf7cf5, 0x07383756, 0x47f24ef9, 0xd5593bf0,
-       0x57dfc646, 0x7bd385d4, 0xed2293b8, 0x530fb406, 0x20c65ae2, 0xe74e3e5a,
-       0xab9a807e, 0x37bde273, 0xf90a6d56, 0x748acece, 0x744557ee, 0xdeefc465,
-       0xcf3f2b74, 0xc97fee29, 0x86922614, 0x84527b76, 0x343b0bed, 0xaefd3a79,
-       0xcfc0f47b, 0x3db76e93, 0xd8c1ddda, 0xee0bd32f, 0x267cc3d1, 0x7776da65,
-       0xbff3fc83, 0xb7f3c09a, 0x201a86d9, 0x78994cbf, 0xd7c818cf, 0x4a9f3ba7,
-       0xece7180f, 0x38692e96, 0x19ff283f, 0xbbc5d796, 0xa5698e7f, 0x49760fb8,
-       0x24b41d69, 0xfdfedfc3, 0x7fa3963d, 0x2df3fbb4, 0x18ee9606, 0x7f097980,
-       0xdd25b4e8, 0xf8f4abf9, 0x8cc5e58e, 0xf5e74e3d, 0x0e1efc3c, 0x09ccb8fc,
-       0xf38a4f78, 0x97bcb15b, 0x2f741353, 0x9fefc1c7, 0xf252fbc9, 0xff5f543e,
-       0xb70db27d, 0x92ec9f72, 0x2a1dff81, 0x0fbda9c5, 0x89fc34a6, 0xf6a9f9de,
-       0xa23096b0, 0x4d9ef683, 0x7753be39, 0xa20bdd1b, 0x6f4c87fb, 0x57337d27,
-       0xac683bfa, 0x29dff987, 0xfcfc8960, 0x1f82a3c1, 0x3d652f4f, 0x9fe8807a,
-       0xca39b77f, 0x985c700e, 0xfa85ebe8, 0xfddc3220, 0xe9d7c427, 0x0ba9d50d,
-       0xaa1ef0e3, 0xed0f91c9, 0x7df978cf, 0xb7e132ce, 0x42f1cdb2, 0x3bbea82f,
-       0x46535da1, 0x87684ddf, 0x757c17de, 0xfe97c321, 0x192bd423, 0xed049d7c,
-       0xde5d3ce8, 0xb1e2bbf2, 0x4fed85dd, 0x700d98f4, 0xbc06009b, 0xfa1e35a7,
-       0xf7a3611c, 0xfb4a98aa, 0x7efe5ecf, 0xa2799e92, 0xd5eef86c, 0x3ee2e933,
-       0x9413dd11, 0xeff89274, 0x1a181740, 0x999d59fd, 0xbeee1019, 0xfdfd036c,
-       0xf91f492f, 0xddc2e2ce, 0x7742fe3c, 0xe31e4524, 0xe2cda748, 0xb0759fef,
-       0xbf916f8b, 0xd1e9620a, 0x330d9fe8, 0x11c9db43, 0xf5d88d1b, 0xff2f6d77,
-       0x92fc2e9d, 0xe0706cc1, 0xa2a5923b, 0xd0b558cd, 0x2d5bef8e, 0x7bd3378c,
-       0xe85f0b25, 0x96c1fc4e, 0xb60590fc, 0x89621b63, 0xa866565f, 0xf5b9ff84,
-       0x2a1dde8c, 0xf3a64fa8, 0x36f5f994, 0x12daa34a, 0x6fecfca9, 0x7ae2c9de,
-       0xe0a7d389, 0xa68cba7f, 0xd3ff4b73, 0xd9d6529b, 0x6691a77b, 0xf0bbcfba,
-       0x0b6bb720, 0xc7bfcaa7, 0xbbafefc2, 0xc8ae3804, 0xb90b8a1a, 0xe753dc3a,
-       0xf0ba57ef, 0xe77e00be, 0x677d5034, 0xfc4a57ef, 0x82dd049a, 0x7a9cb3df,
-       0xde913330, 0x59ef147f, 0x9aed174e, 0xceb3bdc5, 0x4fbcb5de, 0x6a227bb4,
-       0xddf2135c, 0xc8696774, 0x9ef52d77, 0xcffa0730, 0x7a48d486, 0x373ee147,
-       0xf59a97f8, 0xf11e8b4c, 0xbf9b2d30, 0xba753973, 0xfd90deb6, 0x4373e939,
-       0x92778776, 0x4d8fa80c, 0xecfb6d2e, 0xf50ec2ae, 0xf6bf7d65, 0x2354d15d,
-       0xbe3d4fd9, 0x69f90b3b, 0xf4515de2, 0xbfffd10f, 0xff10b4ec, 0xb83bc49b,
-       0x112b2ccd, 0xbeadc2f5, 0xdbfffb27, 0xefc1b1fb, 0x03bf06c4, 0x42eb7fdb,
-       0xdd607e4d, 0x6fed350f, 0xa9ae5fab, 0xad5bec1f, 0xfa6ccfa9, 0xb43f2699,
-       0xfb4d39f9, 0x693647e1, 0xbcb647ea, 0xfdbfa9a4, 0xfe4d0ecc, 0x683fd68e,
-       0xb6d9dfda, 0x61cf9357, 0xe7da68ef, 0xe4d03f9a, 0x57ff5ac7, 0xc4aefed3,
-       0xf1fa9a13, 0xfa9af3f6, 0x68ae7d09, 0x2f8e05f2, 0x373fed35, 0x457757ba,
-       0x0cea22bf, 0x433aadf1, 0xf944f861, 0x6629a6e5, 0xba6b07d4, 0xf8247d0a,
-       0xd3b0b96f, 0x7ba307ac, 0x6cd563ac, 0x3d5ff11f, 0xc1a0bbff, 0xde7f4f76,
-       0x1ff8c4e5, 0x6bdf8d7b, 0x527f068b, 0x8c7e301f, 0xff02ccd3, 0x9e6c5dee,
-       0x778f9355, 0x77da6a25, 0xd4d76e99, 0x68fbb927, 0x38e653ea, 0xaab4f934,
-       0x5df69a11, 0xf9353897, 0xa69e4f0c, 0x971af77d, 0x76b3df26, 0xef7da6ba,
-       0x7d4d6ef5, 0x4d1cef5f, 0x55adff7d, 0xbac0fc9a, 0xb7f69a25, 0xf5347bd5,
-       0x9a357d83, 0x5aa6ccfa, 0xf3687e4d, 0xe1fb4d7a, 0xfa9abc47, 0x355b2d91,
-       0xa99fb7f5, 0x68efe4d3, 0xbfb4d7ad, 0xc9a7cdb3, 0x9a83b0e7, 0xf7e6b9f6,
-       0xd6b1f935, 0xefed344f, 0xa9a63c4a, 0xab3f6f1f, 0xce7e97a9, 0x6b9f3e84,
-       0x53df85cb, 0xe697f8e0, 0x6ef7f6fb, 0x1f742877, 0x6ed75cea, 0x96c57df2,
-       0x24fd1530, 0x6c99c517, 0xf5111078, 0xb727de15, 0x8539f3f1, 0x238aaf14,
-       0x944c887f, 0x810bcf1d, 0xab8510df, 0xf40c8cb6, 0xfefc23ab, 0xccf5ea5b,
-       0xdadff79b, 0xd5dcff84, 0xf288beee, 0xfb6eaf31, 0x989f7a38, 0x1c225679,
-       0x77bffdf2, 0x956dde83, 0x19f378e9, 0x17f00fa6, 0xa6d5860f, 0x389af90e,
-       0x05f378c1, 0xb6c1ef86, 0x22e22bf7, 0x17bdc7f8, 0x16bff406, 0xf7f817d6,
-       0x9a976b23, 0xffc76fe9, 0xf295a96c, 0x522696eb, 0x3a00fffe, 0x0047bf29,
-       0x000047bf, 0x00088b1f, 0x00000000, 0x7dedff00, 0x4554780b, 0xeedd7096,
-       0x9d248fdb, 0x777579d0, 0x493cdc9e, 0xf09d0848, 0x3a3e00d8, 0xc0406021,
-       0x490435e6, 0x41a8c1a4, 0xf881ba43, 0xbb75744f, 0xb2021031, 0x10d191b3,
-       0x0186c195, 0x099d1964, 0x09d1a32e, 0xe09af09a, 0x1c604c3a, 0x3719d9c5,
-       0x8ee2a3a0, 0xcfe31e10, 0x7fc38fee, 0x937ba9ce, 0x380e9dbe, 0xf7ff3afe,
-       0xb4fbfa3f, 0xab755538, 0x739d554e, 0x2aaa3cea, 0x89895ead, 0xde6d6322,
-       0xf39f4a1c, 0xc99899da, 0x316f36d8, 0x0ebddbc1, 0x72defd82, 0x9d7a774a,
-       0x5bcbbf94, 0xaf1ef041, 0xdebdd28b, 0x79f74a1a, 0x92fe543d, 0x9fe081b7,
-       0xb6947d7a, 0xff299b7b, 0xc10b6f15, 0x046dbc07, 0x53f5eabf, 0x4bdde1da,
-       0x76de1be9, 0x76f4ef2a, 0xb7a6fc10, 0x6f2ee08b, 0xbc87c10f, 0xf11f04bd,
-       0x98f8269e, 0x1ed28fb7, 0xbe9467ef, 0xf2a7eded, 0x0957bc77, 0xdbbf8ebe,
-       0xcd2afc19, 0x2631e49f, 0x7ae69730, 0xc9ccc21e, 0x00f63226, 0xff824bfe,
-       0xcc8846e2, 0x8cfdd8c2, 0xb0d73eff, 0x9413769a, 0x3ff2fe77, 0x74c60285,
-       0x1f8d8ca5, 0xf662690f, 0xc634c6ce, 0xe675b026, 0xd318724f, 0x63d75740,
-       0x4e09fb07, 0xd6191319, 0x2d75dfc3, 0x58c7dffe, 0x94bffc3c, 0x834c78e5,
-       0x14095369, 0x55befb42, 0x1a777f82, 0x3e20d755, 0xbf1c8dab, 0x95135a69,
-       0xf82c3e57, 0x5563020d, 0x8be9f322, 0x587dfb18, 0xc11b0154, 0x2e8f25d8,
-       0x2172c447, 0x04830edc, 0x443a8ff8, 0x2c5d7e0e, 0x9da5b18e, 0xd29b1d86,
-       0x84aaf106, 0xfdf035ef, 0x0c1a562b, 0x3a3d64ab, 0x1df203c4, 0x9ec618da,
-       0x4ba6b8b7, 0x8a60ff90, 0xf687a7c6, 0xed9fc999, 0x2dec648c, 0xe6066b8b,
-       0x77dcf25f, 0xc07f1b0c, 0x7ec6cf6c, 0xe2ba1b66, 0xfdff4117, 0x9df6b5c7,
-       0xe1f3f0d2, 0x6c67296e, 0xdfca0ddc, 0x02ec973c, 0xa2ffca3c, 0x9ffce175,
-       0xf85645d0, 0x492f01f3, 0x1a4a78e0, 0xeadb3a55, 0x7cf8825a, 0x47b9e919,
-       0xe5f85303, 0xacf6ab6d, 0xae552181, 0x82e11aca, 0x2582eeef, 0xcd8c1963,
-       0x418e9265, 0x38e67cf9, 0x2d4d069a, 0x17822e64, 0x6fa51f31, 0xb1aabbc5,
-       0x4fccc59d, 0x21b26bb0, 0x82b8d435, 0x78cb72f1, 0x947c65b9, 0xabab71f4,
-       0x20e5e38e, 0xba4c4ebc, 0xa5c71b23, 0x5596f5e0, 0x58737aa2, 0xefc476ff,
-       0x3f1783cb, 0xd2863211, 0x174077c7, 0xeb1e6826, 0x73ac3d31, 0xf7d18ea3,
-       0x7e088f8d, 0x2e856ba4, 0xb791992a, 0x0be418fb, 0xf4027481, 0xd2fc8451,
-       0x92373a9f, 0x0949e4e8, 0x92707c1a, 0x0b1fa7d6, 0xb3f8d4e3, 0x87d12d05,
-       0x1efc005e, 0x48fa0388, 0xea0e9e1f, 0xe00d219a, 0x67afa01f, 0xaff3bdb0,
-       0xce0e5dff, 0x49cdfb97, 0xa357ce12, 0xe801d606, 0xd6b6f7d8, 0x99925bbe,
-       0x94ed6014, 0x6ba47e31, 0x73edda26, 0xb17ae0c7, 0xdfa84ea5, 0xfb0d65ad,
-       0xfbf687f3, 0xb417ae2a, 0x2ba6c27f, 0x9cbb53f7, 0x9ff295cf, 0x63c5fae2,
-       0x5eadebca, 0x16ad69f5, 0xe8713ff0, 0x131a5e9c, 0x6f0d1c62, 0xe00666e7,
-       0x3338eeef, 0xe44261dd, 0x45e7f2fa, 0x949fe60e, 0x1fa144e9, 0xb5d23ead,
-       0x178814c3, 0xf9e817ef, 0xd13744e7, 0x4419cf40, 0xe0f89fcf, 0x690639d3,
-       0xfb4822c4, 0x20ba6a60, 0xd660bd75, 0x672cdd23, 0x99ab4a76, 0x6007d293,
-       0x9d7e91f9, 0x38f4a7be, 0x76b20fef, 0xbe2bafca, 0x7cf482d7, 0x8a95c6bf,
-       0xa5eb2d70, 0x2feb377c, 0x2dfcc1b3, 0xd47b5e6c, 0x6fcf5806, 0x025a6a79,
-       0xff3cefcc, 0xce98a3b2, 0xe27c25dd, 0x7a3f8893, 0xc13eaf10, 0xfa113eb3,
-       0x92a5fbbf, 0x3f9049f5, 0x85d7cb47, 0x175f2bfd, 0x8f047e45, 0x97a1f81b,
-       0xe341cb8f, 0xab9546d2, 0x09f2a1f8, 0x9da010e6, 0xff0683fe, 0xfe00b4ce,
-       0xdfe87e28, 0x898e5093, 0x7ae0f7fd, 0xc434dfbb, 0x083f7ae0, 0x29c71be2,
-       0x806b1838, 0x2ad690fe, 0x882a8863, 0xe1621fde, 0xb9f7ac76, 0xa79fdf4c,
-       0xcfefa230, 0x4060e605, 0xa67417bf, 0x5ae50166, 0x0456cbaa, 0xbe60acf8,
-       0x6ee50626, 0x38054bcd, 0xd725234f, 0x1fd744a7, 0xa61537b5, 0xa7f7fca1,
-       0xf7ff280a, 0x698dec19, 0x5d84fdaa, 0xe321408f, 0x3f9f3861, 0x0ec776c0,
-       0x3e284bc5, 0x14429ff6, 0xf33d0663, 0xbf888b19, 0xebe444d9, 0x57f13d44,
-       0x066d4e23, 0x3c94e3f6, 0x9feda1a6, 0xf9edf190, 0xef744b4a, 0x16ecf183,
-       0xf7c3f542, 0x60f8432b, 0x2c3f243f, 0xa7d1fa8c, 0xfa563e71, 0x64bea663,
-       0x6a75d027, 0x86974b84, 0xc716c182, 0xcb998be5, 0x4fb49e97, 0xe67d7133,
-       0xc8a8de4c, 0xdd8f6a65, 0x09d1e5c6, 0xf843e49d, 0x1d9a4944, 0x9c80d724,
-       0x97f8abbd, 0xbb8f11a7, 0x2d2ea68c, 0xdd16eca4, 0x7d94fa9f, 0xff707d30,
-       0x7fd94bbd, 0xeffbe16f, 0xefb5991c, 0xf1babb12, 0x3aecc67b, 0xfd972fc4,
-       0x6d8f995e, 0xf22adfb8, 0x0b7ec871, 0xf9c5eb03, 0x832b2513, 0xc7c0b574,
-       0xdc253abf, 0x36c47c8f, 0xf4f8d2e7, 0xfe0cfcb2, 0x58c15ade, 0x13c651a6,
-       0x19704bfe, 0x20ce6659, 0x5663549c, 0x9b1e29c1, 0x06c8feaa, 0xe69e5549,
-       0x679551cb, 0x7055db34, 0xaab14b56, 0x8736a8fe, 0x97f5ce0a, 0xede7eaab,
-       0x31e0aa75, 0xfaaa15ed, 0xaa5c3b63, 0x1aaec2f2, 0x1eb8f955, 0xd09e0a8f,
-       0xffaaa0db, 0xaa7da777, 0xcd7d49f2, 0x9f29f2aa, 0x5be0a8b5, 0xf554dbfb,
-       0x57eabf6f, 0x7fb09795, 0x354f9556, 0xd3c157ee, 0xeaabafcc, 0x16fb80bf,
-       0xb61dcff0, 0x0cfe556e, 0xbbeab8e9, 0xaa4e733b, 0x75e417e0, 0x270e2df6,
-       0xe72d68be, 0xfb6cd1fb, 0x5876aa07, 0xfebe68e7, 0x7b6f3c61, 0x510b1fcf,
-       0xf4d76e4e, 0x4add21a7, 0xf222735a, 0xdcf16671, 0x2c664043, 0x14aab1db,
-       0xf94e5bc5, 0x1d308753, 0x8a5fdced, 0x715f926c, 0x05a610f2, 0xd0a58bae,
-       0x44d7b31c, 0xc8b4c61f, 0x8ad53853, 0x3dcc34a8, 0xdf44e98c, 0x5728a9aa,
-       0x3f5c785f, 0x2a28f91a, 0x074fa146, 0x827d67d1, 0x7eb9f886, 0xf28fc9b1,
-       0x24c532c7, 0x96139032, 0xb1d65a1f, 0x9a8b4c02, 0x1af66d31, 0xfa0f5f99,
-       0xba519780, 0xfe666bc9, 0xaf67206c, 0x93fae08d, 0x43a795f7, 0x44ab233b,
-       0xe699aa33, 0x48258f51, 0xe5f5bed0, 0x765d9c96, 0xb0edd6c6, 0x42e5d7cf,
-       0xc59e19ff, 0x4e01a23b, 0x30058e63, 0x2398167f, 0x25b19936, 0xfa76df3b,
-       0x97c287f2, 0x244d9d33, 0x5cf6c417, 0x7694ffd4, 0x6e7e9637, 0xdf2198d7,
-       0x11e74bf7, 0xf1adf798, 0xc21df4e1, 0xa75f9925, 0xb60b475d, 0xf69ef90b,
-       0x4cfc7c10, 0x977fdf1a, 0x0a7d73a4, 0x66eb8487, 0xacc6cbe5, 0x808ca7a0,
-       0xa93adcb9, 0xf0ea0ce1, 0xa027d9a2, 0xe0d7627c, 0x892b907b, 0xe0832958,
-       0x4e01c3db, 0x6c625840, 0xc7eb967f, 0xc5d5afd8, 0xfa00d9d8, 0xc351a849,
-       0xcf9e615b, 0xa3e20e66, 0x89f1aa5b, 0x8fdd0630, 0xf43b769d, 0xc60aadb3,
-       0x3d56f00b, 0x7a9437d7, 0xf68c34a3, 0xf8d32ff7, 0xcdaece7e, 0xf49ea3b7,
-       0xe79e3ca5, 0x3e8bfdbc, 0xeb7b44ce, 0x3589a52a, 0xf205c11e, 0xb4e95acd,
-       0xae9ea0fb, 0x8423e611, 0x348bf2de, 0x1dd7be91, 0xa090447e, 0x1269a7de,
-       0x7e9589c1, 0x0d52771a, 0xbf801bb4, 0x6609f44d, 0xe63db7c8, 0x9b3f1013,
-       0xf06769d9, 0x885a331d, 0x3cc8d7fe, 0xcbf86b61, 0x0f418fa2, 0x769d79d3,
-       0x13bba7ac, 0x271f33e8, 0xb86663d4, 0x47e3c94e, 0xa3eb10b0, 0x0d3e86a4,
-       0x9f40dc73, 0xd47d4a8f, 0xddc5fb43, 0xe80b2926, 0xa6c585fb, 0xda211d8a,
-       0x9f9e54fb, 0xfeea310d, 0x1f3e5a2d, 0x6cbedc8a, 0xf0a8ebe6, 0xa6689af1,
-       0x526be392, 0x846f5bc6, 0xc8cdb5af, 0x6ef8015c, 0xd0cc7e85, 0x55abe1be,
-       0xe83f1c66, 0x4fea4ed0, 0xc764f2e4, 0x6ec8728f, 0x21c75e0a, 0x3f9408f4,
-       0xa3e908a2, 0x7c08dfcf, 0xdbd2a868, 0xfeb26f51, 0x7b809343, 0x116b2273,
-       0x5358be50, 0xdc447aca, 0xae5744d7, 0x793e8433, 0xd654ba33, 0x839fd94f,
-       0x3d774bd7, 0x9c12fde3, 0x31d57fef, 0x1f56c7d4, 0x05718f8f, 0x3a4c53d0,
-       0xd662cba7, 0x98fe45a2, 0xbd29dacc, 0x7a52f585, 0xd4a7eb1b, 0xa622ccc1,
-       0x694ecca5, 0x3a527319, 0x2d28799d, 0xce942d67, 0xce94ed64, 0x8294bd62,
-       0x93a9433d, 0x9aeec999, 0xa637fb07, 0xd293980b, 0xa50f31ef, 0x7e9ce999,
-       0xc10b582b, 0x4a76b377, 0x24ef803b, 0x8c01fa3d, 0x9c827694, 0x904df4c3,
-       0x79769873, 0xa3652625, 0xd287201f, 0xa53b5e23, 0x94c5bcc7, 0x541d78f6,
-       0x396f6def, 0x9d78efa5, 0x56f09e94, 0x75ebda50, 0xde53bd51, 0xf5df4a1a,
-       0xcf7d287a, 0x69e940db, 0xdfd28faf, 0x1d299b79, 0xc67e07a5, 0x2be9cdf9,
-       0xf53e7d44, 0x0243bd23, 0xe591ecf9, 0xe68761d2, 0xb8f1dc99, 0x40661a6e,
-       0x235b283a, 0x7359fd20, 0xa43f0e34, 0x0b56729b, 0xe1ba42f7, 0x0cdfd704,
-       0x0fd248d6, 0x82f56dad, 0x0876ed04, 0x5808da7d, 0xa9e9e9cb, 0x9f208d73,
-       0xbad93a4b, 0x19c23b08, 0xee81194f, 0xfd3ce876, 0x64bca03b, 0x08d734a7,
-       0xc8e4d67b, 0x8fb1ff53, 0xe93e54c3, 0x03346b08, 0xfb3d2b3c, 0xe38138a9,
-       0x7befc281, 0xaee6733b, 0x253c44cd, 0x34c5f3c2, 0xbf512c30, 0xfa44c47e,
-       0xd9db6175, 0x93c00d42, 0x68454c1a, 0xebd40617, 0xae1fba42, 0xf2b9705e,
-       0x9655b6dd, 0x0d879c46, 0x0e5a809f, 0x7d19a959, 0xd5f3ab85, 0x5ebe6aed,
-       0x837b4cff, 0x09eb03fe, 0x7f6f6837, 0x7d32a396, 0x3a7effc2, 0xdd6fa60f,
-       0x6bf68ff5, 0x8e640fc8, 0x5774fdc1, 0xfd339734, 0x04ee9fa0, 0xc8c577bc,
-       0x1a4cc6f0, 0x5c43ca17, 0xd29b0db7, 0x77803efd, 0x1f573985, 0xd47ff2c7,
-       0xd14277d8, 0xa6d770ae, 0xc933825c, 0xc621b13f, 0x8f931393, 0x97df3cfa,
-       0x0d1f935a, 0xbff80293, 0xafcb9d39, 0xe95cb7ad, 0x447681dd, 0xc16586b3,
-       0x979b3b77, 0x7681cc6f, 0xf419bc7e, 0xdc478007, 0x0b31bd5a, 0x6a37d3ca,
-       0x19656a26, 0x78fc7887, 0x4d9ef573, 0x8f255fa8, 0x7686c98e, 0x99796433,
-       0xb857db1a, 0x55bce806, 0x95a7b6af, 0x7e649ff4, 0xce6686a9, 0x954d6c82,
-       0x3a1df4ed, 0xdfb81156, 0xefc64cfd, 0xd53c5957, 0x57fdcedd, 0xfee19186,
-       0x25fc6027, 0xc3bfb923, 0xfe48ceb2, 0x7ff24b0e, 0xca03bc9d, 0x7634db2d,
-       0x6b44e954, 0xea1d5aed, 0x3b598bfb, 0x810ee3f2, 0xe14bef7f, 0x0a28217a,
-       0xec0373e9, 0xd3deadf2, 0xfc03328b, 0x9f0ab684, 0xc97bf680, 0x0fa15ac8,
-       0x07e49ff7, 0x2dfbb405, 0x15c12e15, 0x8781f689, 0xb965cfca, 0xf80e927e,
-       0xfbe12ad9, 0xb992fd40, 0xa15d7012, 0xd2768adf, 0x605158f3, 0xf8b3a77f,
-       0x3b07ac3c, 0x75d5f499, 0x782bc27a, 0x97654ebe, 0x95f6c01e, 0xff2e0c75,
-       0xabb7067e, 0x5d013d77, 0xe24c1f20, 0xdd89f376, 0xce3fa489, 0xa0770d69,
-       0xa9e274fd, 0x6f0465d1, 0x3d40ec99, 0xc9eec4f2, 0xb39d31d3, 0x3bd52665,
-       0xb41eb021, 0xb96ce787, 0xd4fcc45b, 0xdb0bc00c, 0x7a27a33b, 0x41e5b39c,
-       0xcb47fbf9, 0xe358bcb0, 0x91da09fb, 0x22fb8dc5, 0x1c9e4ed0, 0xa6124af9,
-       0xf57d3427, 0x5dffd0dd, 0xdc2bf666, 0xe31b9d9e, 0xfe1cb1fe, 0x74a9f731,
-       0xbfd7ea1d, 0xf5a74f4b, 0xc41ccf9c, 0xec835007, 0xf6f65bba, 0x8a4d061e,
-       0x3fded6dd, 0xe65ccc15, 0xc11f30e8, 0x5ecbb4b4, 0xd657d386, 0xe9823ce3,
-       0x194f5ef4, 0xa7e52faa, 0xba608e5b, 0x3bf5d724, 0xff179f9c, 0xbcaf7be1,
-       0xc7c8f008, 0x07a8cdeb, 0x37d13e65, 0xebf92763, 0x21f90c74, 0x45a7926b,
-       0x746c048b, 0x787ca0c6, 0x835169f6, 0xad21b9fb, 0xc3610c25, 0xb41ae97d,
-       0xb745770b, 0xb3b8d0d4, 0xe3ce19c2, 0x210fb0db, 0x3b45645d, 0x809f9063,
-       0x3e1d692f, 0x10d3e993, 0x634731ed, 0x1fcf187e, 0xe1ce17a8, 0x5af503f3,
-       0x27ea04c2, 0x13fb2046, 0xbfdc06d4, 0xddfef26d, 0x38093cc6, 0xcf48d61f,
-       0x64ebf40e, 0x67fe7095, 0xb02e9c91, 0xfa44d37a, 0x96cd9c84, 0xb89dcf16,
-       0xe897560e, 0x3ba40beb, 0xf40706d8, 0x19827491, 0x055bd7da, 0x219c830e,
-       0x7e87f0bc, 0x42c98b0c, 0xbf828d7a, 0x0bda02b5, 0x1c7033d0, 0xdf834cf3,
-       0x9b177429, 0x4235c7c1, 0x65acbfa6, 0xdf053dbc, 0x9f2e0cb8, 0x83496f01,
-       0x7c6568f8, 0x009a1c60, 0xd1ea027c, 0x66f006f8, 0x05d21b76, 0xa7817a48,
-       0xc703124c, 0x8471ad5f, 0x7a645da1, 0x4fe8fbf5, 0x02394289, 0xf753fe78,
-       0x69f22324, 0x327238f0, 0x46df08d2, 0x6f5187d0, 0xfce2e99f, 0x11e958db,
-       0x18423ec8, 0x3a2c9fc7, 0x35681fd0, 0x017416ad, 0xf326b5e3, 0xa5667a7d,
-       0xcae51ba7, 0x3b08e2cc, 0xac9df7d2, 0xf3999d7d, 0xc04c91f7, 0xf81b146f,
-       0x41c4d899, 0x4f47f0bd, 0x97127bbf, 0x97b59934, 0xf9fee2e4, 0x70b3fdf8,
-       0x3a3eb6fd, 0x4ff107b3, 0x3baa79cc, 0x5e741a06, 0x197dd794, 0x6ca4ebf7,
-       0x1c0e3f13, 0xe0079247, 0x8d44bf40, 0x41e81cba, 0x65742b05, 0x71a21a13,
-       0xe444d1bf, 0x7a819ccf, 0xe486944a, 0x6129c83b, 0x33fd4841, 0xf9e4ae88,
-       0xaee7d657, 0x375a4c8c, 0x03af89ab, 0x171bb7eb, 0x5583ca46, 0x6dfa09d6,
-       0x011f3604, 0xa658df74, 0xd7680bf5, 0xac28fd62, 0x919de2cf, 0x8769d743,
-       0x03399a4e, 0x1ac3f4e5, 0x74366ef3, 0x7edc815e, 0xc3ed7a4b, 0xf90e5471,
-       0x7dfc91a2, 0x436af801, 0xb8f5eac1, 0xac6dfd59, 0xb48cee6b, 0xc989f9a1,
-       0x3ee2660b, 0x68cb589b, 0x47cb83fd, 0x575ea63d, 0xa3c737b2, 0xbbf988ff,
-       0xce7ac1be, 0x8655de4c, 0xbaf07cfa, 0x1a97742a, 0x105f7a1b, 0xa65f3933,
-       0x954fd846, 0x92215e93, 0x114ce09e, 0xa2ed03e3, 0x1f7c190d, 0x1335fdba,
-       0x23ec43ed, 0x5cb71fa3, 0x93ef577b, 0xa50eb0b9, 0xae683457, 0x1cefa3b0,
-       0x484ce1fa, 0xddeafda7, 0xf50affd5, 0x1a657da6, 0xb06ff987, 0x10e819be,
-       0x9d80f5f1, 0x2fdaf001, 0xa3a0b4f6, 0xd992b1a4, 0xfa55df71, 0xf3f723d9,
-       0x49df9d0b, 0x645735f2, 0x820e493b, 0x2f401e65, 0x7e896900, 0x56731978,
-       0x68dd90b6, 0x5907cccd, 0xf6bd6e8d, 0xfe5fb425, 0xefd0cf49, 0xd242af38,
-       0xe7f8c095, 0x65ba4a55, 0x5917c7e8, 0xf311ea39, 0x3f94ec2b, 0xf3ced2bf,
-       0x417f3c8d, 0x17f28385, 0xbe783a54, 0x3e61f209, 0x7bf85616, 0x42eed0bd,
-       0x41a48c53, 0x93a5783f, 0x50355f97, 0x0f603bf9, 0x87c90264, 0xde49f987,
-       0xe1a67cb7, 0xb84f12f1, 0x0d5c005f, 0x123d4591, 0x1a7ddfce, 0x8624167b,
-       0x01999114, 0xe9c2b67e, 0xf3f942d7, 0x13809fcc, 0x6af546f9, 0xbfe43667,
-       0x719a2c91, 0xc0386f7c, 0xabf9c66e, 0xe9de6915, 0x351bf007, 0xd8cf14c9,
-       0x7dadfb21, 0x67e48c2b, 0xfc875d05, 0xa2456cac, 0xf2f0c7ac, 0x7ecdcb6d,
-       0x0e40c7d4, 0xdff63ad2, 0x001e9227, 0x1cedf0f2, 0xca5e8bd4, 0x484987b4,
-       0xb37e6ab7, 0xa12f2f54, 0x19992af6, 0x9559f2ed, 0x97c6bdbc, 0xea0d7e34,
-       0x3379a655, 0xf71a0e91, 0xafda3b32, 0x2a9f56cf, 0x9b78458b, 0x87e5cedd,
-       0x56342e5a, 0xe12e396f, 0x731a3c78, 0x7ee7d516, 0xe94f46ad, 0xc830ad2e,
-       0xd2deb4cf, 0x2a18fca0, 0xd83dec6f, 0xa955424e, 0xb3d4137d, 0x8fd138c0,
-       0xf3cf4dbd, 0x1488f77d, 0x8b54b067, 0x4182e65d, 0xa7914efe, 0x187c82d0,
-       0xc545f245, 0x525fa35f, 0xf9923fc3, 0xc45df814, 0x3176f971, 0x5d95c93b,
-       0x27207aea, 0x52af2835, 0x67f9d4da, 0x2fc504b2, 0xe0879aa5, 0xb87ab679,
-       0xe71e0bdc, 0xc2bab8e0, 0x34b8d146, 0xd7285c7c, 0x74d73f20, 0x2b73f288,
-       0xa124bb45, 0x853f6bbc, 0x92f51fe3, 0x9e00bac8, 0x13345d55, 0x66d669e9,
-       0x6643b90d, 0x0b925eb3, 0xe2b71b37, 0x671e08df, 0x6436f8f0, 0x1cdf6968,
-       0x1bd707d0, 0x7d6c1f49, 0xb8c1a4c4, 0xe15be822, 0x973857e8, 0x099e1a55,
-       0x532230f3, 0x6bafd7d6, 0x34693cb9, 0xacea9d11, 0xfa04e58f, 0xa5d1841f,
-       0xeebeb023, 0x72bcec7a, 0x68e91b8a, 0xac72c1dc, 0x93639658, 0x2a7c60fa,
-       0x933873ff, 0xd6f7e602, 0x7c1518fe, 0x5544d5fb, 0x2e1012fd, 0x8d53e581,
-       0x69f2aa79, 0xf82a71e6, 0x5514db0e, 0x54d219fd, 0xce677c15, 0xb3faaa9d,
-       0xf055f3ed, 0x544bc55d, 0xee3ae7f5, 0x2fcf9555, 0xbe55487f, 0x0546b9d0,
-       0x7bf8aa2f, 0xaec5fd55, 0x92f95546, 0xe555279a, 0x9293f6c1, 0x3f726696,
-       0xe79b56cf, 0x8be483a4, 0x0e46704b, 0x14a967ad, 0x3dd703fb, 0x53eb822a,
-       0xe51af5c1, 0xe04178f5, 0x48feb1fd, 0xe29df20d, 0x91ed637f, 0xd75cff2a,
-       0x3ec6c9e4, 0xec72fa13, 0xb2dd23ef, 0xc51fdc13, 0xc53bfcfc, 0x04fdd57f,
-       0x56f683d4, 0x715ba647, 0xabbf43bf, 0xf9fd0f4b, 0xb7bfe435, 0xb40bd736,
-       0xe7ae6e0f, 0x7aab957e, 0xc00d8ae6, 0x7ef38583, 0x828e78e5, 0x70447327,
-       0xcf1860ff, 0x95fb26df, 0x52bf439e, 0xb03f6336, 0x17787e28, 0xac509bb5,
-       0x467fa1f7, 0x7a08f6a8, 0x662e5b94, 0x07284836, 0x97ff5397, 0x5823ec2b,
-       0xd2567988, 0x398daf56, 0xbd5b7da0, 0xc61ead6f, 0x69399756, 0xbcd0b3cb,
-       0x1fc8c3cd, 0x94e668f3, 0xe7816b2d, 0xa25321ff, 0xf9104975, 0xf75f3f3c,
-       0xd03db9c6, 0xa5956b5f, 0x706ae508, 0xf3bb9279, 0x941bb1e2, 0xd5f2bf3f,
-       0xd1bfee0f, 0x671d75f7, 0x87ca029a, 0x24568bf5, 0x1d004732, 0x7ed08648,
-       0x74c81ff9, 0x27ac9ee5, 0x5a33d63f, 0xcfc893d7, 0xd7ff2617, 0xddf0bdc4,
-       0x3dcae979, 0xfe43a7a8, 0xea1f300f, 0xcf9ebcd1, 0x29e744bc, 0xbf40f352,
-       0x2c3bfd47, 0x941edd34, 0x95ad17db, 0x5a07e8fd, 0xd097a91d, 0x7e324fce,
-       0x0eea7e46, 0x83abb71d, 0x07e7f7ed, 0xb276edec, 0xedcbf7bf, 0xad5396ec,
-       0x8ccf7f99, 0xe45a263e, 0xf98840f8, 0x09b546d0, 0xab12af28, 0xf9024fc5,
-       0x4f523ba2, 0x498b047e, 0x6a983bf6, 0xc5017e54, 0x791dd06f, 0x6f7480bf,
-       0x7e415ae9, 0x6017f47a, 0x75e5077b, 0x2417f609, 0xe8b4ff19, 0xb51bd8e3,
-       0x23f206cf, 0x04fd1084, 0x27f8a1e1, 0xa3f1fb82, 0xccfb813e, 0x27d270ca,
-       0x397dc782, 0x6650e4b3, 0xff48f23c, 0x7e503bc9, 0x7ed1d29f, 0x84bd1c38,
-       0x1fcce149, 0x266f7ed0, 0x7223efb7, 0x91f95462, 0x0fe644f6, 0x64b35ff4,
-       0x321127f3, 0x48cc5b0c, 0x51c6df7d, 0xbcdbdfd8, 0xbb3a13bf, 0xd841f48d,
-       0x7bfed0f6, 0xeee7e64f, 0xab69465c, 0x01b7976c, 0x9cfa631f, 0xd9fa4cd7,
-       0x843fe036, 0x4a257bb7, 0x4a1cdefd, 0x54ed7a77, 0x4c5bcbbe, 0x83af1ef0,
-       0x72debde0, 0x9d79f74a, 0xb792ff94, 0x7a9fe082, 0x7bb6945d, 0x15ff286b,
-       0x03e087af, 0x5f8206de, 0x44507d45, 0xa533753f, 0xa85b786f, 0x46dbd3bc,
-       0x3f5e9bf0, 0xbdde5da5, 0xdbc87f94, 0x6f11f04e, 0xbcc7c107, 0x78f7045d,
-       0xdb7d287b, 0xeff94bdb, 0xdc134f78, 0xb1938f2b, 0xfa2f5ee6, 0x84a25c2b,
-       0xaeb3ddfa, 0xd7ea336a, 0x331a65b6, 0x9736f38a, 0x39fa0566, 0x78f255b6,
-       0x86956d9f, 0x87a040fc, 0xb39f51fa, 0xf8fa7b2d, 0x405f2a34, 0x49b15be5,
-       0xabac4a30, 0x56cafeb8, 0x159ea9ea, 0x77c1020f, 0xfd2b6adb, 0xb25b805a,
-       0xbadca9c3, 0xedbb244a, 0x3a278d79, 0x245deb9b, 0xae3aadbf, 0x1074283f,
-       0x22e9fb21, 0x974a44b2, 0xa3fc7365, 0x23ef4232, 0xfc4a5919, 0xc707b9a4,
-       0xf182ab67, 0xf555be21, 0x5a5f8c46, 0x49f183ef, 0x3aae3fa4, 0xc3247804,
-       0xc07f1178, 0x6cc2fc87, 0xad97d719, 0xaf08eb55, 0x94f365e4, 0xda346778,
-       0xfa9e6de9, 0xa56f84b9, 0x36cd7e48, 0xfbe8a1d7, 0xe7ca4e50, 0xe1f1ac7c,
-       0x50fe7f4e, 0xf082327c, 0xddb8c6df, 0xd2fa0c90, 0x00e310fe, 0xc7a9478b,
-       0x198f78fd, 0x26f1fa43, 0xb2627acb, 0x3d8ff9c0, 0x6dff122c, 0xc1f7a067,
-       0x7e81cf77, 0x503943e7, 0xfa156fba, 0x72cd1eab, 0x3c02cc4d, 0x3f8d247e,
-       0x531c0224, 0xaf4fdbce, 0x1ea0f717, 0xae7deb0d, 0x3e37f209, 0xb689d9b8,
-       0x6966ec71, 0xdb5bb22d, 0xd01357b2, 0xa82c95ff, 0xcb4947d7, 0x3bb63c65,
-       0xd5cf7b78, 0xb64fe48b, 0x76903aae, 0x865bf784, 0xfa8e26fd, 0x61ba187d,
-       0x1a481632, 0x55c91914, 0x2fec45e2, 0xe5cda1ec, 0x66fc5fd8, 0x215fd287,
-       0xe775f7f6, 0x65e3e469, 0xbc085756, 0x37279386, 0xb38b2393, 0x8e48e322,
-       0x9424b124, 0xb8ebcf23, 0xe49df2dc, 0x861d24fa, 0x1fb43499, 0xc4ae7e25,
-       0xe8e383d3, 0x243d3235, 0x61c74219, 0xfde80d57, 0xddb7aa3e, 0xe749c9b1,
-       0x0b3e304b, 0x6c75ab45, 0xeaf3ae05, 0xdaf37092, 0xa4a0f410, 0x018e505b,
-       0x468bdfdf, 0xb9b3b523, 0xe1a3b79c, 0x56cadced, 0x32625c11, 0x6bc842fb,
-       0x6e5a7d25, 0x4e2c81e7, 0xbe0f49b7, 0xae18f1b4, 0x3a3adbef, 0xc69cf413,
-       0x04ed11bf, 0xc92d09df, 0xfb6d44d7, 0x78013d8e, 0x79e3cb35, 0xb5cfef4e,
-       0x7b40ff23, 0x915728f9, 0x7fc9f25f, 0xcc0566c1, 0x5addf2bb, 0xa3fd8fd9,
-       0x29a21b6b, 0x2eb55cbe, 0x36a3f50c, 0xb07a2466, 0x85d13cea, 0x4560f401,
-       0x1f410cba, 0x4af4b2fb, 0x3254d53c, 0x7c32e311, 0x728a9e5f, 0x583ef009,
-       0xe1fb451d, 0xdeef65d4, 0x5be01639, 0xd47688ae, 0xe5ab9ecb, 0xfd2713e7,
-       0x26e74351, 0xdb9c7cde, 0xb7fdb77d, 0x7bf41eb2, 0xb3e9c827, 0x7a41e768,
-       0x77b3334b, 0x52dcbac1, 0xcdff226d, 0xb3c557ad, 0xb91a7681, 0x7da3c7a4,
-       0x5335fdc1, 0x803ca1fa, 0xa67d26fe, 0xaa330fae, 0xa1233d45, 0xab6f9d4f,
-       0x1a66703a, 0xcb56d3f4, 0xf6bb6e3f, 0x7d8471fe, 0x93f21af5, 0xf429f500,
-       0x4dfe4093, 0xe78097d1, 0x191a3716, 0x32eb73c9, 0x41e519a3, 0xe49c25b7,
-       0x1362db5f, 0x321ba1e9, 0x9ea18757, 0x8faaa86c, 0xdea474c6, 0xa77d03b7,
-       0x7dffbbdd, 0xe4812d9e, 0x817f3f2d, 0xfa0c5984, 0xae7abdc0, 0xb6faf8e4,
-       0x7944cb4c, 0xc3f2a1a9, 0x8b7dffbb, 0xac077d0f, 0x3490f085, 0x7e0f912c,
-       0xe29bbe00, 0x2fdf02d4, 0x444e6740, 0xabae74f8, 0x4243e507, 0x8b1baf9c,
-       0x56ce9ab6, 0xcae2f9d2, 0x5d33e238, 0x31e987b5, 0x18c8b2bf, 0x9f0ae7c8,
-       0xfffcb5fc, 0xbbe71cb4, 0x59b81c99, 0xf7e337bb, 0xbe73a59f, 0x369ece19,
-       0x154f230c, 0x9acf18fb, 0x4b6c8a63, 0x7d59eafb, 0xf6eafd48, 0xc567ce6c,
-       0x643e7e7a, 0x72f4c54e, 0xfaf8c38a, 0x96c73c44, 0xa9f9cd93, 0x714912cd,
-       0xd674b6e2, 0xdf037185, 0xf7f70d72, 0xdafff1c4, 0x3fc9d32a, 0xa2782ad4,
-       0x3e78197d, 0xeb8695c2, 0x147306d7, 0xa6b7fd09, 0xfcceb972, 0xabc6331e,
-       0x409a9da1, 0xf3dec1fc, 0x9198e9a9, 0x0bfe4c3e, 0xa49ef12d, 0xa3b7f00f,
-       0x17fd1c5f, 0xdadddfc1, 0xbf6f86af, 0x984b86aa, 0x354f054e, 0x6669e1aa,
-       0xe6c96c35, 0x361dfa7a, 0x490cfe75, 0x1ca7270d, 0x73f0d309, 0x7f01a6ed,
-       0xbbf044b3, 0xa07e0199, 0x01769a0d, 0xafa525e7, 0xadb2fc96, 0x93dfdca9,
-       0x73f6af5c, 0xb596b224, 0x6df90231, 0xfcb6f954, 0x73fa0255, 0x7cead56c,
-       0x8c150798, 0xbff48acb, 0x9f95d724, 0x02e9718d, 0x4b3aee7e, 0xc5cde9eb,
-       0x238b6875, 0xcf934a3e, 0x1fdd0d05, 0x95b8d0b7, 0x7c0f9076, 0xfa45e301,
-       0xe62f840f, 0xc76726ba, 0x05f03e73, 0x7df997ee, 0xa503e43a, 0x41f8e1bf,
-       0x3962c7e1, 0xab9ca26e, 0xa5b722b9, 0x97a9ab9c, 0x0475c7cf, 0x92b9c79d,
-       0x81e7465c, 0x09aef4ae, 0xc877c50f, 0xce6cbe67, 0x946e9877, 0xdf20d7cf,
-       0xef9cf4f9, 0xd5f0df30, 0xfd28672a, 0xafbcbcf0, 0xcc37b43c, 0xf8c071fc,
-       0xab47b656, 0x82477760, 0xd3bcf039, 0x740ff843, 0x3a3337ba, 0x0f2b5a47,
-       0xbf338be7, 0xe908d3db, 0x0b975a5b, 0xd66567d7, 0x338f3d59, 0xfe51ebf5,
-       0xdff7979e, 0x38dd820d, 0xdb94c05a, 0xbb668da5, 0xccbdfd11, 0x57f2a19f,
-       0xd5877e28, 0x31acd22b, 0x0188ff80, 0x4cd3823f, 0x33e34de7, 0x35118fc9,
-       0x2b3771d5, 0xccf73c04, 0xa2046f98, 0x554e85dc, 0x658fc790, 0x97d0fd97,
-       0x035e383c, 0xce02abfa, 0x0f441923, 0x3573b923, 0xe7014995, 0xff655bca,
-       0x9b1f00c5, 0x7f609796, 0x7896cc3f, 0xd679863c, 0xda9fff72, 0x6ab8665f,
-       0xd833b553, 0xdfaab27e, 0x722fd956, 0xfed5f6f3, 0xf4d5c337, 0x0ecfda61,
-       0xb21cdf6a, 0xd576c1fd, 0x11afbc7e, 0x3e436f1f, 0xb5ffce18, 0x1ba7965f,
-       0xf45e9e6c, 0xd818e97f, 0x06071495, 0x6a8898fa, 0xc369ff23, 0x5d5379f9,
-       0xa60fdab2, 0x1f927e63, 0x90d647cf, 0x3e6048fc, 0x9859df8a, 0x47d7f287,
-       0xbbf1e74d, 0x1371b960, 0x8798c179, 0xfd00dea1, 0x3f57f2a9, 0x46d3f7c2,
-       0x3c42eec1, 0xfff3c783, 0x89abdd8a, 0xfa4bdf1c, 0x64b84a73, 0xdbde81b8,
-       0xe32575ea, 0x3dc21bf7, 0xfeeb1835, 0x762ebb3c, 0x1b3de83d, 0x7c08c630,
-       0x71bb3576, 0xfb84cfbe, 0xf58fa724, 0x27a21a71, 0x1d96ddcb, 0xb27a00da,
-       0xa8695de8, 0xf2345af7, 0xa1fc2f39, 0x65bd6cbf, 0xfd10a6e7, 0x029bfa2b,
-       0x8f002b5b, 0x956dba00, 0xfe81e6f5, 0xd0ee2496, 0x3163b406, 0x3fa90ab8,
-       0xd2a35ce5, 0xeb37d35f, 0xf7ecab6f, 0xdeb3fa52, 0x559f1ea3, 0x59f1a1ef,
-       0xe947fde5, 0x2f8e2b6f, 0xb4dd5f04, 0x1e8ed93f, 0x7aa96fe8, 0x8783567c,
-       0x72d567c6, 0x7f40e1ff, 0xbfacdf4d, 0x931ef936, 0xe1d3e64d, 0x0e37fdce,
-       0x1a76ab9c, 0x29b4ae51, 0x7f7940fe, 0xbfb414bb, 0x37f796ad, 0x714bfbe5,
-       0xbddfe4e9, 0x18df33d4, 0xfdc35f6a, 0x247ac98c, 0x2648f593, 0xcf0891eb,
-       0x3ea67a99, 0xf0b0e81e, 0x22f9b6c5, 0x1e73e3ec, 0x153e333a, 0xf62f19e0,
-       0x5f6117cf, 0x99e2f39a, 0xc9f04903, 0xccbe2fcb, 0xe6787fcb, 0x9b94324a,
-       0x2fcdef7c, 0x962a3803, 0xde0ac7ef, 0x8db7bf4a, 0xbba37ae2, 0xbfee73e1,
-       0xfb8af904, 0x87aa6356, 0x42f17fa1, 0x32d47f72, 0xe94eefa8, 0x310f2cb7,
-       0x6eea4a2f, 0x467e4f38, 0xff287914, 0x40bfe1e6, 0xee53cfb4, 0xefab9467,
-       0x6d454467, 0x8c2ffd22, 0xef28cdf9, 0xba0e8c22, 0x28d6f84f, 0x642c1fbe,
-       0x376e0af6, 0x39f25948, 0x31cfba0d, 0xd76e58bf, 0xb1cfcb7c, 0xb1c6a17c,
-       0xdfd9ed1e, 0x478aaa4e, 0x173958f5, 0x7f783797, 0x1bf5d772, 0xbe0e1f9c,
-       0x23e7393f, 0x23c2eb81, 0x3ba5bfb8, 0xb9f7e257, 0xa886fc02, 0x9f370ef7,
-       0x7db8a3b5, 0x0e9f383f, 0x0e319f3e, 0xfee69f3e, 0xfeb0b5a8, 0xcb7ee8ee,
-       0x5d9fc413, 0xc86be721, 0x5fcd06bc, 0xd8a628fd, 0xb7a45a79, 0x32b7cd9b,
-       0xc1f9caaf, 0xa2ca4146, 0x794feafd, 0x3183fd2a, 0x8e2a14bb, 0xb819f483,
-       0x4e6deabf, 0x5d19fe86, 0xcf073d9c, 0x45fe3795, 0xde5cf21b, 0xd63e796e,
-       0xb9d38546, 0x3d28c6ce, 0x51dddbd9, 0x97fa1933, 0x9a74d345, 0x72a8b297,
-       0x8da96f3a, 0x8f68ed65, 0xd7239f06, 0xce9bb88e, 0x68ad6901, 0x703a4041,
-       0xa461d92e, 0xe8b989f8, 0xc5c8e786, 0x8f239d9b, 0x91cfc999, 0x7425e947,
-       0xea45b459, 0x7f239e43, 0xf7df146c, 0x713c71bb, 0x278c3f88, 0xa21c706d,
-       0x31d1c799, 0xf5f2023f, 0x7f231766, 0xc7de3cba, 0xea5075e4, 0x861ecc1b,
-       0xb7ab40f2, 0x68a7a84b, 0x613ef9c3, 0x4e5869b0, 0xf7c8bf08, 0xfbe8e947,
-       0x34cd724f, 0xd7231aaf, 0x5afce7cb, 0x7a4fe908, 0x4fe29475, 0xc3674d0a,
-       0x0d3cc9d1, 0xf0a7473f, 0x9e9302e1, 0x302df7ce, 0x0fd14ad9, 0xef0800b2,
-       0xfa8098b3, 0xf7e22db7, 0x0dbb4581, 0x5337e7e9, 0x6ff9ff6e, 0xb9f9ba18,
-       0x43353e7c, 0x4ee3f747, 0x8f61cc09, 0xd57e7a19, 0x869e8ce9, 0x66bb9a6e,
-       0xec87599d, 0xeff2e2f7, 0x867b6115, 0x167553e3, 0x779fec89, 0xa85ca146,
-       0x0f1f5b4e, 0x42caa2f0, 0x94dfdd1d, 0x08ee44e3, 0xd19fc72e, 0xa28e4eba,
-       0x51e7d178, 0x624748a5, 0xa3e22a7f, 0xea0289c4, 0x9e2a37bd, 0xd7e1cdea,
-       0x18dea0c5, 0x7f67d394, 0x1eb462ef, 0x127a50b6, 0x302c4fda, 0x07cb236e,
-       0xf302a3b4, 0x01627ed1, 0x2f2c27eb, 0x9085f6b6, 0x609a4a17, 0x0d5292db,
-       0xd0909e7c, 0xff92a942, 0xee5b43ac, 0x57aeb10f, 0xc6fd75e5, 0x601b4c76,
-       0x8ed0713b, 0x2ae5fb01, 0xd517dbce, 0x61e32ca7, 0x17657548, 0xe9b18ec9,
-       0x88933e15, 0x1e6106bf, 0x45fb04af, 0xd5b0de75, 0xfba14beb, 0x6d38f2fe,
-       0xa346d62b, 0x1c55031d, 0xbcdb9f48, 0x9965296d, 0xcec8e383, 0x8d13e991,
-       0x17a889b6, 0x5c725ff3, 0x97f40ccb, 0x74349b24, 0x5326013e, 0x6e612f75,
-       0x38b4f459, 0xccdd4534, 0x2ed0926e, 0x3f3d25ef, 0xf896bae1, 0x62f0e120,
-       0xa4ab7186, 0xef0176b8, 0x23f40d03, 0x97ae6fdf, 0x5c57b9e3, 0x048e3465,
-       0xcefec0eb, 0xf38d0ec8, 0x747945cd, 0x518e69e5, 0xe5d58fc2, 0xdcfc71c9,
-       0xe1d5fdc2, 0x3ae8097e, 0x4057b6a9, 0x380c0138, 0x5c27c5f4, 0x426b4c6f,
-       0x045af279, 0x6db58bf9, 0xf207cc99, 0x45745527, 0xfb3ce0e5, 0xc9a6ffa5,
-       0xdf0b0790, 0x9c207cad, 0xa136b3f4, 0x25d90665, 0x285869f7, 0x1c98cf3f,
-       0xc828c7ee, 0x609ffce1, 0x1ea94d6b, 0x44d3e987, 0xcf975f37, 0x1db39067,
-       0x9f11d9f4, 0x1c58fa2d, 0x759a7bd4, 0x9b73e9a1, 0x7ec0efdc, 0x185fcf21,
-       0x7f911973, 0x3b9382b5, 0xdbeef739, 0xce82cfb7, 0x55e74613, 0x8d7ac936,
-       0x4e444ed2, 0xd846153b, 0x45cf0c1d, 0xdf07660a, 0x9b3ecc07, 0xf9abd60f,
-       0x7b486d2b, 0x791cc1eb, 0xb26b491f, 0x4cb2fd61, 0x94fd0dbb, 0x1a55f7c1,
-       0x70da26d3, 0x0c671a7d, 0x7031a9d0, 0xcb4ee85f, 0x53cf1f7e, 0x2c747a99,
-       0x70591cf0, 0x2173c7aa, 0x972837b1, 0x1d3797cf, 0x9b42e7e2, 0x78bd454c,
-       0x14c9a10e, 0xfec74457, 0xa99cfc4c, 0x3a64df52, 0x64def246, 0x1356f1e7,
-       0xa2020fee, 0x3ba1e7c7, 0x83cd18ed, 0x0e5a6f52, 0x7b26ab97, 0x5bfbc317,
-       0xd53f76e1, 0x3e9d130b, 0x161fe00d, 0x4ffee8c7, 0x55f39198, 0x318fac04,
-       0x7e95ef80, 0xd1d1cb6f, 0x172535bc, 0x7e1096f5, 0x6704de22, 0x1b22b64d,
-       0xdf38dbed, 0xb4636fd0, 0xaf9cdf42, 0x5be7971f, 0x3e51a769, 0x434f7aff,
-       0x58b2fcce, 0xd73913f4, 0xa6bb60e4, 0x83b446e5, 0x6fe391b4, 0x6186ded8,
-       0x285e6bdb, 0xf238f7b7, 0xc8b23685, 0x50e9ed8c, 0xc3a0845e, 0xfe76e467,
-       0x30ede357, 0x97df74b3, 0x9f305a60, 0xa3de942d, 0xa38c46a4, 0xddfa1b8f,
-       0xebbf9637, 0x90247ed4, 0xfc717bbf, 0x1ecf932b, 0xee1ca12b, 0xdb2eda3f,
-       0x619d8a27, 0x2ededb91, 0x3ee87bf0, 0xef4edc21, 0x8776c836, 0x0f3d4c25,
-       0xf941f783, 0xe0ae5c3a, 0xc72ee6e7, 0x046b8a31, 0x77e5f3f3, 0xb40e8a3e,
-       0x73ef504f, 0x04bb7364, 0x1c4bb453, 0x610d9fb2, 0x9da01bf4, 0x80fdf0a2,
-       0xfa42b75f, 0x3f005ba7, 0x0d6fc803, 0x7b242bb4, 0xc90dbe88, 0xe7c8697d,
-       0x053bf2a9, 0x5cd7f643, 0x4785a72e, 0xfe434b3f, 0x4feb8b2e, 0xf982efc0,
-       0xae4785fc, 0x5e78e026, 0xce703198, 0xab43e286, 0x7bf3a717, 0x1cffc7d9,
-       0xfed10aed, 0x457feecd, 0x86b4dd9d, 0x5ce5c0f4, 0xdf5bfc0f, 0x8cbedb07,
-       0x821d9deb, 0xcda4efda, 0x5fe77ae5, 0x7acc7de4, 0x2df7a455, 0x2eb965ce,
-       0x0ab61f20, 0x7f28e5e6, 0xe7e11f53, 0x5e3f56e6, 0x2103d9ff, 0xed1841f8,
-       0x804e73fa, 0xacdc5c3d, 0xa35a3f27, 0x8dc47d29, 0xafc31ce2, 0x71cb87b3,
-       0x1e4b7d79, 0x24f3f235, 0x5b17ae2e, 0x39d3f75c, 0x23f3e095, 0x243bd5c3,
-       0xbea53dcb, 0x7947db01, 0xfe479a62, 0x23684b80, 0x964dbfa0, 0x7678c17b,
-       0xf3c864e2, 0x12b90463, 0x18456875, 0xed93abb6, 0x3f8aedb1, 0xe8c8a2a3,
-       0xb75ef808, 0x1a58c8b8, 0x8c8d2f40, 0x6e0ddf9f, 0x01dcceff, 0xafa55a7d,
-       0x459f70e8, 0xf89c50df, 0x433901a7, 0xcab8658a, 0x0ffa518e, 0x70163f3e,
-       0xf38c2c5e, 0x5a67b729, 0xe818dcf1, 0x962b6bb7, 0x6df9c48f, 0x582f5d15,
-       0x3ffa1e61, 0xe739d030, 0xecbe650f, 0xb872f993, 0x43b1f3f5, 0xf6318ca0,
-       0x97823b04, 0xc64e80d6, 0x68fe408f, 0xfb94d4cc, 0x5cb38c43, 0xfd08671e,
-       0xafdcd6fa, 0xe6975fa7, 0x51afd086, 0xc504767f, 0xd461021f, 0xf4211d9b,
-       0xec8213eb, 0xedcf900f, 0x1d49d09c, 0x270f307d, 0x6f611d6e, 0x919ee894,
-       0xf6045ec3, 0x32678bc3, 0x239f6f51, 0x23c7bc0c, 0x608c31db, 0x221623b0,
-       0x6799735e, 0xc50203df, 0x48ee5a51, 0x5c04eea3, 0xa7ad9b8f, 0x3711fb24,
-       0xdc613ac2, 0xb2daf5a1, 0x0ce2a119, 0x274038ff, 0xef02ba28, 0x042ac007,
-       0xc48695c4, 0x63e282cb, 0x38194e18, 0x5a1dabff, 0x7562aeff, 0x35e36afc,
-       0xac30bfee, 0x0427fe60, 0x2eaa1f3c, 0x0bae5f9f, 0xe2a9cf8e, 0xba9d0b5a,
-       0x887c7c60, 0x6f8cb26f, 0x2907b6ca, 0x452d3e0e, 0x64acfde4, 0xc707cf64,
-       0xbd850cbd, 0xc3ea2d0e, 0xf7f48c15, 0x9e363f60, 0x5eff2517, 0x09cf6305,
-       0x7d5ade74, 0x59e9e4df, 0x1cfbf8e7, 0x8fd8e52d, 0x50c3532d, 0xafbe0e3f,
-       0xf09bc4a0, 0x7de04c98, 0x22dde569, 0xe10d62cb, 0x53b77cc7, 0x8797e2b9,
-       0x4b12a6fa, 0x55eeb9c0, 0xdd3ea06c, 0x1e85f2a3, 0x59d6d6f7, 0x1c4fef14,
-       0x82ec29ef, 0xa33b24a2, 0x66aa4879, 0x3cc00764, 0x86fae2a8, 0xce345d94,
-       0xc58c354b, 0xaaa038f2, 0x7076013c, 0xbf184fa4, 0xe30fce2a, 0x76c1c154,
-       0x4deccde7, 0x0de64a43, 0xfccdf9e5, 0x5e39068d, 0x646e46f8, 0x633be91c,
-       0x77d418d8, 0xa69f8b2c, 0xeb04b8f5, 0x34597e81, 0x03c54284, 0x68fb4337,
-       0x5f90ba07, 0xc4dfd1e2, 0x30caef54, 0xc9f74887, 0xb38e6284, 0xf1e4eb10,
-       0xfc467ce1, 0x9507086d, 0x9859f80b, 0xbce0706c, 0xc3000c1b, 0x333d0590,
-       0x56be4026, 0x15af37f6, 0x33308898, 0x4fdc8ddb, 0xe36bbca8, 0x866d77a7,
-       0xff7407eb, 0xcfec30be, 0xfa53bfc7, 0xdb8ef219, 0xfb27be0d, 0x7dfc1ccd,
-       0x951df919, 0xff9b87fe, 0xfb6ddee1, 0x2777d4c3, 0x3267bf70, 0x20e56bd1,
-       0x4cbc12bd, 0x1efc47a6, 0x4abdc2e5, 0x0c77adb1, 0xfb3c37de, 0xfd1d8470,
-       0xf0e303e0, 0xefe5a9dd, 0xed75fdd1, 0x9361e00d, 0x8c0fbe48, 0xafef6e4b,
-       0x02fd171d, 0xbc06dae4, 0x4fe78434, 0x279d192a, 0xcf4ab8b0, 0x000e7489,
-       0x1392a0c6, 0x4013ef01, 0xf10e1b7b, 0xf15baf73, 0xb0710b9d, 0xd02bd45f,
-       0x4255b06e, 0x483b087e, 0xbf19ab49, 0xd5e0ac1f, 0x1a3d07a8, 0xf5c352e9,
-       0x3ea6d9e8, 0xe935cf11, 0xe445fae2, 0x2e68e71f, 0x37e807c7, 0x0bf9d19e,
-       0xce7c926d, 0xdfc4a471, 0xfbe4cb4d, 0x84cfd29b, 0xfe591ad1, 0x47fbd2f7,
-       0xd54e23b3, 0xf2c6764b, 0x442fc5f6, 0x11ecfcff, 0x00d3eaa7, 0xe167d82e,
-       0x2ba9d270, 0xecc66669, 0xd10bacfb, 0xef3b3f9f, 0x807495d4, 0x78d9f68b,
-       0x464614f9, 0x097df8ce, 0x319fd10b, 0xd559b461, 0xd7385bfe, 0xd53cdff1,
-       0xcf21341a, 0x5a36df63, 0xe8c94f39, 0xf3b3ad3e, 0x2e31a797, 0x47f654e9,
-       0xdf482e87, 0xde0b2281, 0x717f9323, 0x9d0f1451, 0x9dd9d329, 0x1452eef8,
-       0x68bb2dfa, 0xfa0d477e, 0x6bfe9fe9, 0x4382f4fc, 0xccca9779, 0x1bff812a,
-       0x2c2b981b, 0x99ee8023, 0x9f9d7343, 0x81b8a603, 0xffd28f82, 0x6960bc10,
-       0xbc4098c5, 0x0a3b51b6, 0x0d0a175e, 0xc70587a4, 0xfd082e87, 0x549cf1db,
-       0x2fd6cfc4, 0x10ba75c2, 0x002a9fd9, 0x9eb79e1c, 0x7c42edd6, 0x1ec176ff,
-       0x3af8eb00, 0xa22bef56, 0xd6a3fc75, 0x027a3d51, 0xdfc5dbbe, 0xe396686f,
-       0xbbc64f50, 0x019f687c, 0x32b9d1dd, 0xfc9e8a5f, 0x05e36548, 0xb03fa047,
-       0xcbf7346e, 0x69d3925c, 0x49cf1686, 0x01f74ba0, 0xfa85ad81, 0xf5976bee,
-       0xeecc9fa8, 0x3d47a33c, 0x19c0eeba, 0xad4bde3d, 0xa9da1843, 0x8477a6db,
-       0x32feffd2, 0x97f2ab5a, 0xd1d77629, 0xe8f5ec94, 0x16abab77, 0xeade1ee8,
-       0x6e1fb9d7, 0x251c32f5, 0xb2df7763, 0x55b8fc9f, 0x98f5eece, 0x477d652e,
-       0xc588ddf1, 0xdceaad2e, 0x089a92c0, 0xcabe3c55, 0x9782ab13, 0xc0eac0b6,
-       0x21b4bb3e, 0xc31df549, 0xef82cf5d, 0xd0fe0e28, 0xd790affe, 0x736db171,
-       0x16bbfa2f, 0xcc7ad4bb, 0x62b5ceec, 0x11ede20c, 0xfece1aec, 0x84b77e12,
-       0x00d2108f, 0x7de60abd, 0xa3d7075a, 0x648c2aea, 0x0c22549f, 0xab595af3,
-       0x7393e3f5, 0x54f45347, 0xa810eeee, 0xbb972ddc, 0x576e046b, 0xa975f2cb,
-       0x8392e38c, 0x75d1a727, 0x37a39f52, 0xa5df0033, 0x88e7e515, 0x437d651e,
-       0xc4855719, 0x290d8df5, 0xddb0e9ef, 0x5817dfa5, 0x4b8d1a6c, 0xa92d47a5,
-       0x1e55c351, 0xd59e905d, 0xbdf943a7, 0xff9d41b4, 0xbef2d1f3, 0x90f2c79e,
-       0x2d18de9f, 0x07189f88, 0xbca53fe1, 0x81ef0277, 0x0f3ad25d, 0xead67d22,
-       0xdf700abb, 0x1175a4bb, 0x7e4394ac, 0xb8afdf1d, 0xce01a2be, 0x751befc3,
-       0xa7de330e, 0x8814adf5, 0x00b0976e, 0xb06d27bd, 0xa1dac13e, 0x7722bf70,
-       0xe4f59cc3, 0x98283d0f, 0x13286f51, 0x83de221d, 0x8fc61c6f, 0x83e6517e,
-       0x1f2fac13, 0x2246caf1, 0x9eca7585, 0x99f6823f, 0xf996b7ec, 0x3d948e30,
-       0xc4bf204e, 0x4371809d, 0xc922a611, 0x37b03991, 0xad9a4184, 0xf920af6d,
-       0xe66f563e, 0x58da62ef, 0xfc70bca0, 0xbe701333, 0x0bb27510, 0xfde87b93,
-       0x9b6d39bd, 0xcc5ca22f, 0x3d1470cc, 0x193df805, 0xf27ffbc6, 0x16bfc175,
-       0x3fcba9da, 0x0ad3f246, 0xd6fd81e4, 0xda3964d9, 0x5acff6a1, 0xc121ae51,
-       0x7ea7cacc, 0x32f89413, 0xc3ed15d0, 0x9fa4a55d, 0x9f7ee558, 0xddb8942d,
-       0x2e7ca0fc, 0xe2d6f98d, 0xd1befaf9, 0xf495f28c, 0xcaabfb1b, 0x5e283104,
-       0xe61a3750, 0x4fada579, 0x5be9de75, 0xe901bf6c, 0x187db82c, 0x395e2abe,
-       0x8a2d7b4d, 0xcc1d77ee, 0xfee8deb0, 0x3ea8d694, 0x8733a4b7, 0x53bbdd07,
-       0xf6d99fcb, 0x777ba0a4, 0xeef74119, 0xddee82f2, 0x2df9efa9, 0xba094e74,
-       0xe7bea777, 0x54cdb067, 0xe6930fd5, 0x9c88e0a9, 0x23f555bb, 0xe7d5cbed,
-       0xbcff8eae, 0x77c74842, 0x2e7d7d06, 0xe0668798, 0xc198e28d, 0x0a2f247d,
-       0x3e1a432a, 0x6984cc2e, 0x0ba1a173, 0x9139a4e9, 0xe386e7db, 0xa0badb0f,
-       0x9788e31d, 0xfc6fe88c, 0x452fe089, 0x9f28c4fb, 0x18fd1953, 0xaf33ed53,
-       0x52be7015, 0x5cf2dbd2, 0x7d61f3b3, 0x494af7f2, 0xdee01dfc, 0x463eb8d1,
-       0xf9036c7c, 0xaf7e55e6, 0x476cac78, 0x5f3ced28, 0x0f353258, 0xcc7fcfbe,
-       0xece28331, 0xf07efc1d, 0xa78f3d4e, 0xe7e55ef8, 0xfa3bf35b, 0xfe008e34,
-       0xf5c7993e, 0xa59c6790, 0xeba91f14, 0xf9165d84, 0x1eaceda9, 0x75d465ef,
-       0x7ee14776, 0xab3ce056, 0x60c9bf47, 0x89cfbcbe, 0xaf68e1fd, 0x743dacff,
-       0x9e6d6d3c, 0x98e3f89e, 0x1eabd72c, 0x91bb72d6, 0xb9e16639, 0x575e4571,
-       0xabe3e7ed, 0xe7e7a85a, 0x1d1a3160, 0x9c836e42, 0xc396ab3e, 0x707ef50e,
-       0xca3d7f8b, 0xaadf900e, 0x4c174b7a, 0x12b7bb27, 0x31f236e4, 0x797573c8,
-       0x17c91372, 0x7caae790, 0x3c80de77, 0xdf0ebfcf, 0x426a769d, 0x8170f38e,
-       0xda78f348, 0xffe69535, 0xf4479819, 0x64333da7, 0xde7cf8de, 0xc65ebe6c,
-       0xb7580fb5, 0x2ebf7ae0, 0xf2f6ebe0, 0x7dfaf230, 0x0a775d79, 0x4c2845bd,
-       0xa270cedd, 0x634625db, 0x387b9e09, 0x1365f296, 0x7eaae1c6, 0xfd3dd02e,
-       0x6e3eeb7f, 0xbf5ffd41, 0xfd05a8ff, 0xa3f6ee61, 0x594db016, 0x8b5a4ead,
-       0x85d03c7a, 0xba9ef51d, 0x7fc22e8e, 0x6eb8fb65, 0x21d95fcc, 0xee3dfbd0,
-       0xd3a71703, 0x135f5938, 0x0e770bc6, 0xf28fd783, 0x37befeb8, 0x307ee24f,
-       0xfb89f417, 0xdf8301fd, 0x801d202f, 0x5ebc425c, 0x35e5f017, 0xb1a373b6,
-       0xf51e9422, 0x1f7cf26f, 0xe867a8d9, 0xef85afaf, 0x52c71c71, 0x488de98e,
-       0xb205fb47, 0x27edddb5, 0xfb604617, 0xfa863af5, 0x17df8285, 0xe21fbd29,
-       0xd6a83ff8, 0x3580a7a1, 0xbe696b56, 0x52d7a83f, 0x74fbda3b, 0xc15e2f04,
-       0xae1c55cf, 0x0929a8fe, 0x56a0fdda, 0x530c7ba0, 0x31f3fbef, 0xe0af1784,
-       0x3d305afa, 0x4c1af42b, 0x3bf4c19f, 0xbe6b4e84, 0xc91e9d19, 0xe4d5ef93,
-       0xe7dc02b1, 0x59a7dd61, 0xe11e7e91, 0xae2be3f7, 0x7fa1d61d, 0x6cc9bd33,
-       0x31e0027f, 0x0b7aff5a, 0xbcc389ca, 0x8776b0bc, 0x748de5c0, 0x5261f237,
-       0xbda19eb3, 0x971e7efb, 0x7ae3ef4b, 0xfad0e3c5, 0x31af8c05, 0xe51d37b1,
-       0x4f1c9a52, 0x2ac7457a, 0x905c53f6, 0xaf319bcb, 0x96ef54d9, 0xbd71e537,
-       0x40839143, 0xe4fdaee6, 0xc44f6d97, 0xcb2f147b, 0xe55341e7, 0xfa32b2f6,
-       0xf485cfa7, 0x672f4caa, 0xf8143c64, 0x6cff4cb2, 0x1f68cfdb, 0x59c72d9f,
-       0xd1743666, 0x833ccc79, 0x879453eb, 0xabdf52b3, 0x39ae7dc5, 0x3a7cedfd,
-       0x25378d67, 0xc9fbe226, 0xd27877fc, 0x60d6dba7, 0x9c372fdc, 0xe0ec31d6,
-       0x381e7453, 0x35bc6b2c, 0x49439c54, 0x7a2557dd, 0x6aeeb08f, 0x3c0aa53a,
-       0x7d39d0f7, 0x1701d91f, 0x5c9f13a7, 0x2ddea9b5, 0x7bc654fc, 0x5d3ef28c,
-       0x80f3f727, 0x8b8b169c, 0xf329eb06, 0x1c659e80, 0x2ed6586f, 0xab35af5a,
-       0x75a92158, 0xcefe29ec, 0x0149ed66, 0xa458bddf, 0x304ce873, 0x608defdf,
-       0xfc8b1f25, 0x3657241d, 0x748c4dc6, 0xd784fb2f, 0xd7af704c, 0xaf29f046,
-       0x61ade944, 0x687c88ce, 0x4f11e167, 0xe1dbce16, 0xde275694, 0x8ef0bc57,
-       0x336ba64e, 0xd32e2fbf, 0x2d4ee5da, 0xeb9c6233, 0xc2e3e800, 0x5cf7fe20,
-       0xddfba44d, 0xa0fec3bf, 0xbf0d959f, 0xaf677921, 0xed1d38b9, 0x33dac2a2,
-       0x1bbb084d, 0xf51d3cfe, 0xff610f89, 0xf41ebd20, 0x72809b7b, 0xd3bd24e4,
-       0x8635795d, 0xd35979da, 0xcbf91d3f, 0xf740a6f7, 0xb8ec3e6f, 0xfdf2b7a8,
-       0x7873dc89, 0xf2fd1c2f, 0xb9a3f2b3, 0xd42ce91c, 0x243afad0, 0xddeb3bd5,
-       0x0a2bffa3, 0x20d8c3d7, 0x7e0a7afd, 0xc865a3df, 0xfb4a9bbf, 0xe421cca3,
-       0xdff469ef, 0xb071f365, 0x15e5a1ec, 0x9e165f7a, 0xe990ac93, 0x3cbcb838,
-       0xa13fc07f, 0xebefca73, 0xa1fe0108, 0x3fdfc62a, 0x2ba7bb05, 0xaab8f81c,
-       0x67f92a73, 0x0dc23caa, 0xd1c333fd, 0xeb4dd7e1, 0x28cff718, 0x818dda30,
-       0x1bb44d7e, 0x1f7faa99, 0x252b077f, 0x74f786f3, 0x14897ddc, 0x666bafcf,
-       0x795aef14, 0xe7a53475, 0x2120df5f, 0xfbc318ff, 0x6b7ee95b, 0x8cec86b6,
-       0xfeb53e95, 0xcb80a533, 0x7c052985, 0x60f95cde, 0x01b0e52f, 0xa2ec097b,
-       0x5db9f37b, 0xa9887514, 0x7ce0a5ec, 0xf28c97b2, 0x13101d3d, 0xe04257ae,
-       0x6941477d, 0xca977e0d, 0xd9ce885a, 0x72fefc3b, 0xe4d738f0, 0xf8553e73,
-       0x35f2317a, 0xe7076fd2, 0xe776e0eb, 0x41ac9415, 0x4c38da3e, 0xe65cab7c,
-       0x8c6d95fb, 0x16ddcbe6, 0x05f4f343, 0x0296736b, 0x78017e5d, 0x0bd23de0,
-       0x3444674e, 0xe5c17f7c, 0x3df3c08c, 0x6ba81c8a, 0x36efa70b, 0xc58bce66,
-       0x48cda373, 0xf9ded0f7, 0x9c46a98e, 0x38da7be7, 0x7dfd29ff, 0x1638b5d8,
-       0xae8269f9, 0xf2876f5f, 0x5133cee4, 0x784df7a8, 0xf22c7e7d, 0xfe7870e1,
-       0xcf1918fd, 0x1e12c486, 0x70bd8797, 0x004f6ca2, 0xba27ee7e, 0x87fa9de8,
-       0x6fd1181a, 0x56ffabf7, 0xbe7c7c87, 0xfb8cc233, 0x230717e6, 0x0bcabde8,
-       0x3de81a6f, 0x7df95a9a, 0x7d742fd5, 0x7cbf4873, 0x22f74b5d, 0x47fe6fdd,
-       0xfba3f22b, 0x3b9d0355, 0xc373a87c, 0x6af7dc45, 0xc39c673b, 0x5f6b5677,
-       0xc3f2dbfa, 0xd25486ca, 0x3ff8148b, 0xbe2746bc, 0xe45e7bf3, 0x8ea1e272,
-       0xf77d217f, 0x0b976ba1, 0x17ca7cf0, 0x44c7ff07, 0xb7ee6b94, 0x79444f2e,
-       0xe5c5fee6, 0x7eee5889, 0x4a13c22d, 0xc05eb95f, 0x7eca3efd, 0xa8aef699,
-       0x90ad0ff2, 0x5d6d23e9, 0x3d07bd0b, 0x7b02e4e1, 0x130fbbe0, 0xac4e34b2,
-       0x65b7e13f, 0x7c05f7b1, 0xa457aeb7, 0x93f8e338, 0x01d51165, 0x814f7974,
-       0x7e2ff14e, 0x930ebf23, 0xf019c7df, 0x77f2f4e3, 0x8af6367f, 0x1aa37dfc,
-       0x83a1ee81, 0x5ee432fe, 0x8affad1a, 0x88df7a58, 0xc73bce89, 0x8b38478c,
-       0x3e6205de, 0x00ccd1e3, 0xaf71693d, 0x7400cba6, 0xe869d154, 0x57befd22,
-       0xacb0433c, 0xf173dd3f, 0x2134c8d3, 0xe7267f84, 0xe39434d4, 0xf81a7ec1,
-       0x8ade2245, 0x71e955be, 0xc1fe20a5, 0x15a59bfe, 0x287f9077, 0xd6937fd8,
-       0x8f666a2b, 0xe9dff7c7, 0xf78c2f3a, 0x8bf22369, 0xfae287a2, 0xffc1081d,
-       0x3970c66b, 0xbad5f0a6, 0x5dff1e5e, 0xcc6a5bd7, 0xe656b484, 0x9db003ab,
-       0x75fda0fa, 0xa377f39d, 0xb5dd611f, 0x60631145, 0x3bbdd6be, 0xfc813d8f,
-       0x66352e6f, 0xeed777e1, 0x1fcc2e30, 0xfee097a4, 0xf2e18ca6, 0x184f4072,
-       0x97cbdf66, 0xed5bfaf1, 0xe463397f, 0x87ff6cf3, 0x87607fef, 0xedc31d8f,
-       0x4fdc25f0, 0xe0f0edc2, 0xc791437d, 0x792ebb4a, 0x63ca879d, 0xc04877fe,
-       0xec79265e, 0xbd51231a, 0xb1b9cee4, 0xbbbf4764, 0x0d325620, 0xb4433f6d,
-       0x87f2626b, 0x71e8afb6, 0xa8e39f6e, 0x871ced11, 0x1749fb96, 0x99bef408,
-       0x9db9f7a2, 0xeee3e902, 0xeb1f9d4a, 0x2ef57829, 0x85d57ee0, 0x4c3f9d0e,
-       0x150fd418, 0xdca071fd, 0xa2b9502e, 0x637a2a4f, 0x71fb93af, 0xe5e78c17,
-       0x16b986b7, 0xd87d7ce1, 0x13f94615, 0xc67cf126, 0x0093479c, 0x813df45e,
-       0xfacbff11, 0xc1a742a4, 0xcea5e6fa, 0xd7be1b8c, 0x4fa64db3, 0x8352cf85,
-       0xbfd943f8, 0xdd39f39a, 0x1dfee1d7, 0x7ff7fb8b, 0xe0f2f4aa, 0x7eff6176,
-       0x466ff108, 0x1fbe121d, 0x19d15bff, 0x4aff3eca, 0x5efe0bd6, 0x23debf59,
-       0x72af8825, 0x7db8764e, 0x6fd64eb5, 0xce6f2b86, 0xbcfc7aff, 0xdfdf1e47,
-       0x8e779f8a, 0x9f43bff9, 0xf50bd01d, 0x4779c7a1, 0xc64fc941, 0x6b86bcc0,
-       0x739e743d, 0x1ecdf7b8, 0xb055f595, 0x7c745573, 0x41af4534, 0xc35dc8bb,
-       0xd1cd03fd, 0x7ec9afd2, 0xf7a5ae39, 0xef921e57, 0xd5783e73, 0xea2d694c,
-       0xd92e90c9, 0xd9de927b, 0xc6a3525d, 0xb77d19bf, 0x34aafdf8, 0xb157eb8a,
-       0x552bf232, 0xf19b4675, 0x7c737fbc, 0x2be431fb, 0xb4ad6edf, 0xc6feb03b,
-       0x237d72d1, 0x44d5b7f7, 0x618fdfd3, 0x95407a41, 0x57df5827, 0x645305eb,
-       0xfa70d13f, 0xc3ba2fc1, 0xd1e95cb8, 0x39d79f12, 0xd055dff9, 0xe0b97277,
-       0xbf23086e, 0x886bda09, 0x820d67d7, 0x5f3ddf1f, 0x4cfbd729, 0x13ff25ec,
-       0xcaa0d3c5, 0x2ca7ceb9, 0xd4dfb20e, 0xbb95a3f1, 0x33724b7e, 0x73148e38,
-       0x0d0b8e40, 0xd2268dc4, 0x60959079, 0xbc9fe24f, 0x5dd24b72, 0x1f80ff38,
-       0x71dc93f3, 0x9730fca8, 0xfb223e7a, 0x3cebc973, 0x7e2433fe, 0xc7933cd4,
-       0x95ddf08f, 0xa5c87e10, 0xc51d8f23, 0xb374a3bf, 0xc75d51b8, 0x3247ba49,
-       0xd208ff44, 0x518dae3b, 0x8a4719fb, 0xb23b8fdc, 0x7fa33053, 0x8f3ca46a,
-       0x9c31b77f, 0x7fe9eaf4, 0x79458ea8, 0xf9d3aca0, 0xcf5e7cb9, 0x04a5707f,
-       0x07f89bbf, 0xe3061cd1, 0xf507c5fa, 0xb0e249bf, 0xbbf09464, 0x63b408fa,
-       0x7561ffce, 0x2febce04, 0x2fbfc520, 0x3169daf1, 0x2bd23fa4, 0x0fd82dcb,
-       0xbfc80ba3, 0x45a5fb2c, 0x07230fd8, 0xdfc139fd, 0x6bbf976d, 0xfc853306,
-       0xf8f3af98, 0x6b82737e, 0xa6cfc126, 0xa61efe33, 0xffcefc83, 0xfe8d7402,
-       0x2c183ca2, 0x1a7f9fc6, 0xbc61d6ce, 0xf5de39a8, 0xb3d1f136, 0x08f9091a,
-       0x9338a7be, 0xfb44bf6f, 0xc6194e23, 0xfcf40a73, 0x0cea465d, 0xbcb46bd6,
-       0xc760098e, 0xb0093c62, 0xe6f18059, 0x53ae393c, 0x6c44ce10, 0x6b9d49ff,
-       0xf997be13, 0x5f68b764, 0x8f604c4b, 0x83bf77c5, 0x83824be3, 0x3895c5c7,
-       0x1f1f1293, 0x6024ce2e, 0xee9c053f, 0x8715b9f8, 0x25737180, 0xe7bec49e,
-       0x635720a4, 0xf7ce87b1, 0x48c8533f, 0x718b7fae, 0x21f9259e, 0xc83548e2,
-       0xd5cf2463, 0x394dc571, 0xfe9d10af, 0x3dc4f1b5, 0x1cb7d863, 0x13f3e2ff,
-       0xe8f8f78c, 0xb7b2164b, 0x51effabe, 0x5e76cfb4, 0x42f0fda6, 0x8fbe41bf,
-       0xecfdc7d0, 0x2ff23a9d, 0x2dbb005c, 0x3d9f603e, 0x3ddbcf9a, 0xe89539d4,
-       0x596f40ff, 0x2f3fd604, 0x777c6fe7, 0x48d9fcc1, 0xbd22bd97, 0xe3e78b07,
-       0xd03b0ed0, 0xbd404e2b, 0x975c5be5, 0xb1098fef, 0xd0f0c62e, 0xcbe44cef,
-       0xc05f947c, 0x07ea63e9, 0xd772fedc, 0x598a38f3, 0x72ee0b96, 0x63c1c93d,
-       0xf1411629, 0xc5435b9f, 0xa7ef5e59, 0x856aa37d, 0xbe1cf740, 0xa3a59c71,
-       0x82b7de5b, 0xd3e5d3fc, 0xe70e6e49, 0x9b880eb7, 0x15b7caab, 0x23879c0c,
-       0x815475ff, 0xe31dc699, 0xb3c12c29, 0xbff8ca87, 0x73b875c5, 0xfb3a086c,
-       0x695fdb16, 0x9fdb6eff, 0xb6ddf792, 0x6e3be6bf, 0x77de6d7f, 0xf1dee71b,
-       0xf57fe31d, 0xccff6e3b, 0xaf3f3c77, 0x73ffffe5, 0x70700300, 0x5cf83f9c,
-       0xdfbc7040, 0x1f3efc70, 0x36106d96, 0x6a4177f7, 0x42b57a8c, 0x462d5100,
-       0x0877a2ef, 0x71e24d66, 0x46658db0, 0xf0610eff, 0x5f32807c, 0x1db90b4b,
-       0xe8bfce61, 0x4e79858b, 0xc596f475, 0x126c9fa2, 0x82fd877f, 0x132acefc,
-       0x18cef4cd, 0xfbc04cd4, 0xa161cdf1, 0x7261aae3, 0x23edc37b, 0xdc9617cf,
-       0xfe9e3631, 0xfbc8436c, 0xfec82f1d, 0x23077347, 0xa51324bf, 0xafd47984,
-       0xd0fa8094, 0x3f3c2388, 0x76398baa, 0xda525e10, 0xa507b23c, 0x8b6fc434,
-       0x998def1c, 0xfe869d99, 0x0bd018e8, 0x14f81e31, 0x8e2905c6, 0x4a7aa665,
-       0xe58c1f7f, 0x31d16dfd, 0xe55bee81, 0xac4cf3f2, 0x9e2aa0f9, 0xebae8ef7,
-       0xc50265e3, 0xfe2396f3, 0xe574d2bf, 0x89934cef, 0xff37e618, 0x8ce29980,
-       0x48bd2627, 0x8956777f, 0xf331adef, 0x6ed1872a, 0x1cd63c06, 0xbbf4471c,
-       0xf7a4d0e4, 0x7733e9f1, 0x750f68a6, 0x17f1514f, 0x1dfd969c, 0x8940bf8a,
-       0xf65efd6b, 0xfe887c93, 0x221fba17, 0xab1dea51, 0x27f7b6f9, 0xfc10d8ef,
-       0xfee045bf, 0xb8afdf21, 0xde9c687f, 0x6e78119e, 0xaf3cb372, 0xdc78bacb,
-       0xecf7f142, 0xee33c793, 0x01976d11, 0x4d71d2f6, 0xcfb8f463, 0x094a6b8f,
-       0xe1c0b4c7, 0xf07de0d7, 0x35fbd5c5, 0xa285faca, 0xb2b1d6a3, 0x9fa7a31f,
-       0x12ff7ae2, 0x60ffe714, 0x30bf3f2c, 0xf1e390af, 0x0824d801, 0x1b12c9af,
-       0x711c7d51, 0x2a1b598b, 0x7605549e, 0xacb9e231, 0xccade399, 0x34975577,
-       0x7339fb15, 0xd309bfb4, 0xa9b49aa2, 0xbdaf6fe4, 0x9bfa84d8, 0x63e5dafb,
-       0x4cbf93b7, 0x713da12f, 0xefda9f4f, 0xa5a30ab6, 0xfd2784f1, 0x0cdf5a9d,
-       0x71e3ec91, 0x9fa24433, 0xb230aa98, 0x4c74635f, 0x2e78426b, 0xca8a8bd7,
-       0xcc22a6e3, 0x3e934416, 0x4523d458, 0xe83f97df, 0x51998b07, 0x74f38f1f,
-       0xe2aaf8b3, 0xcc35bb4f, 0xe7ae1af1, 0x5d5f1b5f, 0x74bbcef9, 0x971954ae,
-       0x9c4a2f32, 0xaaf8b874, 0x5dc1ce72, 0x2e75457e, 0x4ff62dc3, 0xb8e3ff47,
-       0xf2f46783, 0xfe334b39, 0xfe25611d, 0x8bf5ee3a, 0xe2557714, 0x45cf6eac,
-       0x3be1abd2, 0x0e3f7e3d, 0x06213f96, 0xf1e217df, 0x9ef157d7, 0xffef1e94,
-       0xd4bee999, 0xc5fdf21b, 0xe63f184e, 0xa1cde9bf, 0xa76bcbb4, 0x98b790f4,
-       0x45e77752, 0x387ed78a, 0x53ef1d56, 0xb49779e2, 0xd56333ce, 0x0e0923e7,
-       0xc369f78e, 0xddc6bfb9, 0x97bfa3a3, 0x48c77ee1, 0x73a4bbf2, 0xfaebdd19,
-       0x246ba4f2, 0xf1875de2, 0x38ba00b6, 0xe187b0ef, 0x9de7613b, 0xb38c30f6,
-       0xa73eeb8d, 0x752ff3c7, 0xfd1eaf62, 0x12718061, 0x1f744d1e, 0xf7cfc8b8,
-       0xdfd09676, 0x5c69bae3, 0x136fe3ac, 0xe59ffb17, 0x00210141, 0x00002101,
-       0x00088b1f, 0x00000000, 0x17b5ff00, 0x67534c5d, 0xb7b77cf4, 0x0bdf96e5,
-       0x72223f2a, 0xa29862c1, 0xa740c2dc, 0xac741631, 0x4a8a5c13, 0x66b50102,
-       0x2d09922e, 0xcbc2ccd9, 0x01893ad2, 0xb8b2c3dd, 0x26a9f364, 0x87b6e883,
-       0x6ead93fa, 0x840b0b55, 0xc3e22e25, 0x52c9719c, 0xba33330d, 0xd8dc6281,
-       0xdf39d85c, 0xd8bdb5bd, 0xa4da2cbd, 0xdf3f3d39, 0xfff9df39, 0x0730000a,
-       0xb956e7da, 0xf84ce706, 0xffc6cfa5, 0x4fa43d0f, 0xbddde38c, 0x1726eb4b,
-       0x3ebbf1c4, 0x036935c9, 0xce9c5df8, 0xf6002b94, 0x1c5ace87, 0xaccf1f04,
-       0xedfc2176, 0x4ab5dfc2, 0xd2f7803a, 0xee202d4c, 0x96a666fd, 0xd2afdef8,
-       0x4fe9027a, 0x8ed77bdb, 0x70045e97, 0x106b4196, 0xc12e55f9, 0xb8e08271,
-       0x4546fac3, 0x25c06e5c, 0x80fce938, 0xe89b34ad, 0xd9a55cc7, 0xf5f4137b,
-       0x00674539, 0xdaaf39e9, 0x09f489ac, 0x06a019bb, 0xc15c0ce9, 0x556bf624,
-       0x7fdfdb81, 0x4a4f2ad2, 0xdbf11c7a, 0xe036cc1d, 0x3c8150de, 0xf7c71e59,
-       0xfc028fd3, 0xd422666e, 0xb9e97402, 0xd77264b8, 0x3bafa8aa, 0x52816a3f,
-       0x5c5b4ca2, 0xdf5e30ab, 0x12acfd4b, 0xbefcf860, 0x170568e2, 0xa0172095,
-       0xe0373f4d, 0xb19c5bdc, 0x3d7fc010, 0x4698ca05, 0x4adf9113, 0x2a8e143f,
-       0xa769da22, 0xb6e5785f, 0x4c27f7fc, 0xcdba11ab, 0xbdc268fe, 0xc3829dda,
-       0x2eedc99a, 0x7920ce6d, 0x212fce31, 0xb74bd3a5, 0x51cc22ad, 0xf413e428,
-       0x025ac217, 0x36ada8d2, 0x0406ef6e, 0x7ca1b07e, 0xa488539b, 0x70d69da0,
-       0x6f50044a, 0xdf045395, 0xcd7b088b, 0x7c461281, 0x2be726f1, 0xbf11366f,
-       0x042aae4f, 0xcbe7e3f4, 0x09417916, 0x3464dfbf, 0xf3aa8e21, 0x3c52fed3,
-       0x953176af, 0x34ef6adc, 0x4193f1f2, 0xe3d6ee7e, 0xfc3433b2, 0x5ff72172,
-       0xcb9e0136, 0x8e38031d, 0x18f67776, 0x756eedcf, 0x3f7461de, 0x337fa0f8,
-       0x904d81ca, 0x6bde8907, 0x3b3aa394, 0x001ff18d, 0x43d62670, 0x0d41d537,
-       0xe7e1c641, 0x45d513e8, 0x582a0615, 0xbf373f11, 0xf974467e, 0xf062faf9,
-       0x5117f10c, 0xd80d567d, 0x024dbf28, 0xf5e10194, 0x9f412d92, 0x9eb9155f,
-       0xfc01650f, 0xde17d728, 0x7e30c83e, 0x915f8f7d, 0x4a6e505a, 0xd2ca97ae,
-       0x32f7b8e3, 0x401653d6, 0x036cf0f5, 0x9858fbc5, 0x794d1581, 0x28bef1f3,
-       0x6eb17d57, 0xbc4ead9c, 0x31dfe6a7, 0x3a44f9cc, 0x0d9a81d5, 0x61205f9a,
-       0x5817fcbc, 0x55ed1060, 0x491c3d35, 0xb2b9f8a3, 0xec8532d5, 0x23a50ed8,
-       0x6b126dee, 0x3c2ee118, 0x160ef840, 0xf6e7f090, 0x005b9d2b, 0xd8b754ed,
-       0x5bdc52af, 0x15aacc3a, 0x40dade88, 0x50596bf4, 0xff122937, 0xc4a97bc4,
-       0x55aa672f, 0x9eb3be21, 0x445f8df8, 0xade7aa44, 0x7865a514, 0x8d28cbb7,
-       0xeac1b37d, 0x551f500e, 0xf411a337, 0x3587476f, 0x84b5fe40, 0xce90cd9b,
-       0xbea041eb, 0xedcf5b7b, 0x328f45b7, 0x099f48a3, 0x5f916757, 0x16d3cc0b,
-       0xea356115, 0x7841c82e, 0xb005bee1, 0xb4e2bc1f, 0x73b94645, 0x05ac4c3e,
-       0xc49f4be0, 0x8327c861, 0xd7c03963, 0xc30e7cbe, 0x2fd3853e, 0x8c39cafa,
-       0x470e54f8, 0xa8356b7c, 0x959e3cca, 0xdd02fbe1, 0x7059a727, 0x7e6f9b25,
-       0xf9623ebd, 0x29ef0baa, 0xba3e7ba6, 0x93962eea, 0x5a20c7c8, 0x6ad6142c,
-       0x6730c9fd, 0x06c3e75e, 0xe881e3b2, 0x60a73a61, 0x460d61be, 0xef308421,
-       0xaa6febbf, 0xd96f9b52, 0xf193b802, 0x04faf467, 0x3cd02287, 0xfad24b7a,
-       0x5fc5787f, 0x48529e3c, 0xf31eb2b9, 0x413719e6, 0xd48fd20a, 0xbe7f736b,
-       0x4f18eb9e, 0xc0ddb8c0, 0xcf9c1278, 0xcbf8b56f, 0x74ad1f28, 0xa7e7248f,
-       0x0ac4faf4, 0xb432bb30, 0x4fbc329c, 0x600e6c47, 0x8f30b220, 0x4916211d,
-       0x19df3ec5, 0x244774de, 0x96e0c3d8, 0xd73c7e71, 0x46e6d87d, 0xb6f389a5,
-       0xf9268d33, 0xd54a5c13, 0x34592ce2, 0xf6d56fd8, 0x8b5d935a, 0xb56e0c73,
-       0x9471756b, 0xfbeb059a, 0x381679e8, 0xa9e7fd88, 0x734ebb18, 0xd001cf2c,
-       0x93c7c38b, 0xd1311e9f, 0xef990f3c, 0xd8e3993d, 0x0c8a791f, 0x3794391d,
-       0x41f6260c, 0x24077e81, 0x63946dc0, 0x6e611c91, 0x192dca25, 0x9f7d259f,
-       0x2f6e15d8, 0x01905777, 0xfe0450ba, 0x465f3483, 0x1a77502d, 0x639d77ed,
-       0x3bfa9070, 0xf70502e0, 0x1bf1e8fd, 0xdd214f87, 0xb4c98e73, 0x5783ba8e,
-       0x16ef9ef9, 0x78ff7827, 0xbc2d77c2, 0x3537831e, 0x0239887a, 0x403af249,
-       0x6eed1dfb, 0x6e687f46, 0x05301f74, 0xc36ed052, 0xbdafad39, 0x41404b0e,
-       0x1de8ac7c, 0xe79df091, 0x1cd1e419, 0xa5162653, 0x1980ff11, 0xafdc2502,
-       0xfd84baa6, 0xfc855f84, 0xd8cfed8e, 0xf4c0f1fe, 0x6bd52158, 0x0a235327,
-       0x8cb73fdf, 0x922f05fb, 0xed2fdf1b, 0xcd3361a1, 0x0643dc1b, 0x868eddb9,
-       0x713f343b, 0x4be918cf, 0xf9e7df0e, 0x53af2880, 0x7e062fdc, 0xe1633d8d,
-       0x58092c6d, 0x38731509, 0xca5536cf, 0x6eaddf3c, 0x1f18dcc6, 0x91757049,
-       0xc991709f, 0xc7e76f34, 0xf5aed1ab, 0x419fa341, 0xc877e62f, 0xd0c7d5a2,
-       0xa3f0163a, 0x94a2237c, 0x7b8ba1f7, 0x1cfd0cfc, 0x40aa62aa, 0x8c2120f1,
-       0x3e3d16c7, 0x6e1f802f, 0x70a9fc4b, 0xe01aae6c, 0x2b61ac35, 0x5ea353d6,
-       0x6e01000f, 0xd4e3f9a7, 0x8e23bd08, 0x2af9839a, 0xf9f8977f, 0xe055677d,
-       0xe814d4fc, 0x6bafd649, 0x6ab375ec, 0xf33dc90d, 0x7b2ed3f7, 0x47d3f792,
-       0x3b2276f8, 0x244ced7b, 0x2bbe30bf, 0x15efbfa9, 0x411ccb5d, 0xb5c981f4,
-       0x5975ce8f, 0xbea9ab22, 0x1cdc981f, 0xee91f18f, 0x8b82fda1, 0x91f516ef,
-       0x87cf8c00, 0xcc67e523, 0xa2769794, 0x125beec7, 0xe9b8e397, 0x0aa1fc69,
-       0xa1efdacf, 0xfda79aca, 0x17fa867e, 0x7f57cfab, 0x1dbcb26e, 0xa497f9a2,
-       0xe7d27e7e, 0x9912c01f, 0x3893cbf7, 0x6487b683, 0xaa3c75e0, 0xa67ef5ef,
-       0xc87b48fc, 0x06199dff, 0xed5cf895, 0x7ff4d0cf, 0xc18beba6, 0x9bf61d51,
-       0xf6f9b935, 0xfc39f427, 0x8a71c98b, 0xa4f2bdee, 0xdf824a00, 0xa0a982ab,
-       0x195df824, 0xf6e031ca, 0x7c8362c8, 0x81a978f5, 0xc2b1335f, 0xbd735fc0,
-       0x14bf80ca, 0x5f90675d, 0x01bd6bff, 0xc5bd30df, 0xcff1bf20, 0xd63c066d,
-       0xb95875bf, 0x4936e789, 0x0ae41baf, 0x157e8d3b, 0x2afd18f5, 0x15fa35ee,
-       0x37e25bd3, 0xdfacb7fa, 0xf64e5fe8, 0xde855c83, 0x91fcffa1, 0x2060fb49,
-       0x34f3c33c, 0x13029d35, 0xa8c44734, 0x66c21fb6, 0xf0a617be, 0x84a2e2ff,
-       0xd7a72c3c, 0x0919da3f, 0xb9d2b32f, 0x2b369d0f, 0x512edbbd, 0xfe3e600d,
-       0x2e76d705, 0x000ee017, 0x00000000
-};
-
-static const u32 csem_int_table_data_e1[] = {
-       0x00088b1f, 0x00000000, 0xe3e3ff00, 0x51f86066, 0xb8d3c10f, 0x72361818,
-       0x0143f821, 0x684333b7, 0x0606163e, 0xc77e2001, 0x9ef0c0c8, 0x38330491,
-       0x207eec10, 0x27880abb, 0x7dcf5071, 0xe52f1143, 0x5f5d9fa1, 0x153d76a0,
-       0x837f7818, 0x031083b0, 0x03309b83, 0x8408b483, 0x55045fbf, 0xc10851de,
-       0x99412e7e, 0xfa819f5d, 0xbbeb8d01, 0x00038031, 0x00000000
-};
-
-static const u32 csem_pram_data_e1[] = {
-       0x00088b1f, 0x00000000, 0x7de5ff00, 0xd5547c0b, 0x733ef7b5, 0x9993331e,
-       0x420f264c, 0x084f0042, 0x21842a20, 0x38880840, 0x8d069009, 0x8808089a,
-       0x420100ca, 0xa9113248, 0x676d5e97, 0x6ad11422, 0xa36d2d1b, 0x4101da97,
-       0x180d45a3, 0x1d0340e8, 0x5abc414c, 0x5b4a0a8d, 0x3c3141b5, 0xe878490a,
-       0xef5bd6c5, 0x33ef6b5e, 0x42667399, 0xfddfb6a2, 0x7f17dfbe, 0xecfb36fe,
-       0x7b5ef673, 0x7b5affad, 0x231fb5ed, 0xd313c659, 0x057c8415, 0x7213d77f,
-       0xf4842448, 0x0b3b4eeb, 0x108e3a68, 0xb0398e7f, 0xb4242055, 0x24edefef,
-       0x4db39085, 0x267355b3, 0x98c7fb21, 0xf2d3d743, 0x80fc81b3, 0xdd4f9699,
-       0xd121c479, 0x514ed57c, 0x3ed37282, 0xb1df7e2b, 0xde400851, 0xf1fd6e6b,
-       0xb5df34b5, 0x699b2453, 0x376424d5, 0xda425491, 0xa9fd842d, 0x6a5f98f1,
-       0x4daad965, 0xf682effb, 0x626683ca, 0x37b7dfa5, 0xafc86e89, 0x08042adc,
-       0xf76aaf6d, 0x5a00ca83, 0xd080b2df, 0x7e695568, 0x1a8a63eb, 0xfb03c84f,
-       0xb368ecfe, 0x67da7213, 0xfd82aa21, 0x491c6f28, 0x7b604548, 0x7dfa00e1,
-       0x65c136c5, 0x6c57f5a2, 0xf401d73c, 0xc3c93455, 0x8adf5a44, 0x47511b06,
-       0x22bfb6b0, 0x07cb5ed0, 0x794eded8, 0xfe57b428, 0x110a3de5, 0x1bb29fa1,
-       0x74a2abbe, 0x76b5bf40, 0xb1eafb4f, 0x559f8d3d, 0xe8f6d1cf, 0x0a2fd57b,
-       0xb562e82e, 0x8e807889, 0xb9d6dd8e, 0x7fa1db4f, 0xf8f0cab5, 0xdc2c7ec8,
-       0x08a8fd05, 0xed0a526c, 0x6526df40, 0xfaeec8e9, 0x87fc3456, 0xacfabe9e,
-       0x72889efe, 0x47da7a63, 0x3bbc3a59, 0xbb88415f, 0xa44bd691, 0xaa3a5280,
-       0x4207f9fb, 0xa1e32122, 0x96a8917e, 0xe4a9faee, 0x23fe0711, 0x0f949ff4,
-       0x81f1bdfe, 0x72dd99ad, 0x9904e95b, 0xbcedcb75, 0xea51cb93, 0x5fac8dca,
-       0xf20c7f4b, 0xf9d4f4a0, 0xee3e989c, 0x8374c34b, 0xfdbe454f, 0xd30237dc,
-       0x9f0b9f7a, 0xc3cbe93f, 0x8dcfa374, 0x22be53e9, 0x12be034c, 0x6fb36f7c,
-       0x7c5ba62e, 0x8cfe7c1e, 0x06d31caf, 0x7f3e0d5f, 0xd31ab7de, 0x3e3f3e6d,
-       0x1eb7d17f, 0x1d5f46d3, 0x5e403ba6, 0x05f26d34, 0xbe5dbdf0, 0xbe834c06,
-       0xc7be7c46, 0x11f4c417, 0x64c747ce, 0x3e512f92, 0x49c4dc38, 0x8a924ec5,
-       0xcd32f9dd, 0x7cb09527, 0x7cfe1dea, 0x3d53e685, 0x32f94f34, 0x6f9432a0,
-       0x3501f9a6, 0xfdf07cac, 0xf342c0a4, 0x7cacfd83, 0x02ee23c8, 0xa90fcd2b,
-       0x37c3e563, 0x68e20bfa, 0x9580787e, 0x542dbd5f, 0xabf9a360, 0x7679591b,
-       0xa76a9933, 0xcb10ecf9, 0x9ee1bce7, 0x39f34f1a, 0xfb9f2cad, 0x83aa7f81,
-       0xd8db73e6, 0x04ce93f7, 0x2d1ed544, 0xbab21d87, 0x6d595098, 0x4b70cff4,
-       0x515e6913, 0xca2e21ef, 0x6eadff1f, 0x43f29d29, 0xc8796376, 0x9bcb1f3f,
-       0xbf963714, 0xfcc32fe3, 0xe583d92e, 0x2c55fdc7, 0xfcb078af, 0x98bdff73,
-       0x2c7eca0f, 0x58fad4b7, 0xf963f15e, 0x58f5da80, 0x80391eff, 0x1f6b23e5,
-       0x4a3df2c3, 0x5f1fcb00, 0x1a7ba4fb, 0x3c11afcd, 0xd23c073f, 0x01649cb4,
-       0x4ad31a9e, 0x09d69e28, 0xf7e02e64, 0x8a3a0007, 0x0ae975cb, 0x3f8ee1ea,
-       0xfa0d3ee4, 0x90297f8b, 0xc3ccfa5f, 0xaffdf899, 0xd6991eb0, 0x4f5ef623,
-       0xba799bce, 0x2cde727a, 0x8069ead7, 0xfb58d6f7, 0x378ecf56, 0x79e9e927,
-       0x67ab42b3, 0xdf13d23b, 0xbce57eb7, 0xcf4f5935, 0x3d5a955b, 0xc49e907b,
-       0x74d3d1be, 0xa69fcf44, 0xb4fe6123, 0xfafd3d20, 0xf7b8cf46, 0xf719fcf4,
-       0x6f3f985e, 0x7de93d60, 0x3de9a7ab, 0xde9a7f3d, 0x08e7f30b, 0xdf506bf6,
-       0x7dee35fa, 0xbdc67f3d, 0x47cfe61f, 0xdf664f48, 0xa1f5d9ea, 0x3ebb3f9e,
-       0x04e7f30c, 0x6fac33d6, 0x48fdcafd, 0x8fdc9fcf, 0xc2e9fcc2, 0x5beaae7a,
-       0xd23ebb3d, 0x47d767f3, 0x817cfe61, 0x5bea8cf5, 0xa2ff72bf, 0x5fee4fe7,
-       0x0931fcc2, 0xbe98cf50, 0x54fc13d1, 0xa7e09fcf, 0xb0d8fe61, 0xa37df19e,
-       0xcf5daf27, 0x30f6bc9f, 0x9004527f, 0xd5bec4fb, 0xf3d76c13, 0xe61ed827,
-       0xe7ac20cf, 0x2bf5beba, 0x3f9e84ef, 0xfcc22779, 0xcafd8e19, 0xf40f7aa7,
-       0x7c4f5a10, 0x39ecf5cf, 0x9ecfe7ab, 0x8cfe61b3, 0xd3a67ac6, 0xaf7ab27a,
-       0x9e875267, 0xc23a933f, 0x7ac3c9fc, 0x9eadf466, 0xfe7a1d3d, 0xf308e9ec,
-       0x73f91f27, 0x35fadf53, 0x9fcf53a9, 0x3f8c9d49, 0x4cd70f63, 0x3a72d075,
-       0xfa44ba16, 0xdc67b5c9, 0x45e6816e, 0x4e8bcb27, 0x44bf0117, 0xd20dfcd4,
-       0xf7e916ea, 0x39896df6, 0xbf48930f, 0xfa14a0a3, 0xb1bd4f15, 0x2123bf48,
-       0xe7e74e2f, 0x7493ba24, 0x01a2e4f9, 0x95fbf7ba, 0xf795d10c, 0xaeb57b9f,
-       0xa393dd3c, 0x4f9467cb, 0xa83fbdd2, 0xbf9740a6, 0xba0df562, 0xb7fd33f7,
-       0xeb59f2ea, 0x3fbdd76f, 0xae916eac, 0x0afacafc, 0x8155f95d, 0x35fcba95,
-       0x7baeff0d, 0x03e3547f, 0xc1d1f2ba, 0x63e57587, 0xf2eb8f42, 0xa93d0f63,
-       0xeb7c7f7b, 0x84f95d66, 0xcaebcfa3, 0xd0edb627, 0xb93dafe5, 0xd9e7e0c7,
-       0xf0d7ed9d, 0x27b808bc, 0x574fefcc, 0xc50bdfd0, 0x0657982b, 0xdf8fd1d8,
-       0x3d54bf1f, 0xbcabe54e, 0xa14d58b2, 0x129905f2, 0x0fe7ae3a, 0x8db2bf28,
-       0x9277bf3e, 0x7d274ae7, 0x19e2af7e, 0x9fe18ced, 0x24083c52, 0x04d5520d,
-       0x41fcb1a9, 0x20b1e199, 0xc7e1cbe3, 0x535ef7e8, 0x9a44f0d7, 0xd7e62fef,
-       0x129e5e03, 0x38d3884c, 0x7bc0d491, 0xf3826671, 0x73330782, 0xe047f69f,
-       0xaa20fd75, 0xbd774287, 0x1a4f65eb, 0x6b9b19f8, 0x1f83f6df, 0xed106eb2,
-       0x9e4200d7, 0xf90ede16, 0x07efd287, 0xd0f34d2d, 0xf50accfa, 0x57db23d3,
-       0xb123fb68, 0xff6806fd, 0x37da1ec5, 0xb5d3c90f, 0xae5c196f, 0xd0a2df6b,
-       0x1fd49df6, 0x6f23fda8, 0x12610a9f, 0x7f0b2f21, 0x83cdf6c4, 0x07fdb1cb,
-       0x895f3a15, 0xdc2e3f6c, 0x77f4107e, 0x3e3fb41f, 0x4c87ff46, 0x707ff7d2,
-       0x0affbe85, 0xb52bffeb, 0x71fb78c7, 0xe116ffd8, 0xe0ffeb18, 0x337fd60a,
-       0xbedc37ab, 0x43ffcc23, 0x7b37ffd0, 0x64d67fea, 0xa8afff7d, 0xccdff7d4,
-       0xf6a77fda, 0x8edf6f14, 0x9c2bbfed, 0xa2bffd62, 0xcc57db12, 0x47e0171e,
-       0x09ab88c9, 0x40c9f6d0, 0x03fa986a, 0x903b685c, 0xa0a2488e, 0x6151e426,
-       0x6f71d208, 0xe7dbc31c, 0x686f1471, 0x9cf8fc6f, 0xcb65a804, 0x8e2ef3a5,
-       0xf2db15f5, 0x584bb015, 0x4b2be74e, 0x4165a938, 0x364df111, 0x28c30398,
-       0xd1411dbd, 0x0db2f90f, 0xfec005d7, 0x4164cd79, 0x91277c09, 0xf4ff3c10,
-       0x4736a367, 0x2e98cbf6, 0xdbdb93a9, 0x3c2df422, 0x23202a8f, 0xd37d286a,
-       0xbbe30401, 0x79d31ff3, 0x8bf3a110, 0x833ce80f, 0x227e4850, 0xa23ef6b3,
-       0xb7c825f3, 0x9412f9d1, 0xdf8b5213, 0xa70eead1, 0x384bfa51, 0x4c4b1ffd,
-       0x43be3f5f, 0x7ea9f808, 0x31bdfe7e, 0xb05d4f38, 0xde9946da, 0x7f42c74d,
-       0xfb4f2eb2, 0x753907e5, 0x360736ed, 0x155fc80b, 0xaa8a55f8, 0xf5e2c849,
-       0xddd79419, 0xc54fbfef, 0x7f594e9e, 0xfdcb711b, 0xae77fbe9, 0x69390612,
-       0xe6ddb3bb, 0xb84e361c, 0xd7a84c33, 0x4794c324, 0x634dadc8, 0x29035a64,
-       0xb71fcb75, 0xb33bb445, 0x5d9f9f48, 0xc877cfa2, 0xe944d96e, 0xc81528ea,
-       0x9cef5a26, 0xad72fab9, 0x8929bb1d, 0x57b799c9, 0x9be8ca92, 0x3c0e6903,
-       0xe79ca276, 0x1ab7d93a, 0x32c5de3d, 0x3c82c29d, 0xc808fdfd, 0xef829fd5,
-       0xfd64eedd, 0x573bd236, 0x684bb8b6, 0x142ee73f, 0x236f8003, 0x67da7ffd,
-       0x69b29b73, 0x32a7feba, 0xc7f74531, 0x8f3cff48, 0x328d3fb1, 0xcbf3c38c,
-       0x6e19cf8d, 0x3ffcb9da, 0xf4d07c06, 0xd283e004, 0xa3e39c7f, 0x7c32aedb,
-       0x9b9ecd78, 0x4f5d0f01, 0xcae50488, 0xc71b72f1, 0x3d3a92cb, 0xc8f1082e,
-       0x7365c720, 0x23879c85, 0xe3873070, 0x1ebd5960, 0xbf127737, 0x2e431e9c,
-       0xfa6c36f3, 0xdd1a9a61, 0x6e390fbf, 0x1fb23fe6, 0x4fdd13f9, 0xb8bba726,
-       0xd1acee9c, 0xe5c6df97, 0xeb97277a, 0x0ec7fadc, 0x6e41f350, 0xe8320357,
-       0x4d3ef7bb, 0x793a6d9e, 0x8d3cb87a, 0xe5c5de74, 0x98f7d779, 0xb6f48d3c,
-       0xd5b67971, 0x90c9905f, 0xf48d7a68, 0xd51d582d, 0xb9e4051f, 0x9e5b1fd0,
-       0xf27e60de, 0x55e788f1, 0x8f92338d, 0x8ad9e847, 0x7e5d5286, 0xee9e6079,
-       0x0bf565fd, 0xea4be575, 0x17caeb96, 0x975bbfaf, 0x9effe85f, 0xab05fdee,
-       0x77e5756b, 0x2ba43cd6, 0x98fe5f9f, 0xf3cf3f2e, 0x39fdee84, 0xcae93773,
-       0xa73c9767, 0xb4599f2b, 0x752f975d, 0x6fbdd6ef, 0x2dd577da, 0x8e37cf80,
-       0x89fc0488, 0x30275ccf, 0x4b99f82e, 0xc73bc176, 0xbae22a7d, 0xd30237dd,
-       0xe2173e93, 0x0f2fb4fe, 0x8b608ed3, 0x3a09c61d, 0x89252e2e, 0x6e9bccd4,
-       0x103f5dae, 0xe38269c6, 0xacd316e9, 0x4264ff5a, 0x91526d7e, 0x0af5c5df,
-       0x44258d09, 0xd386c180, 0x944625d1, 0x5e52f5b7, 0x727f0d4f, 0x5b717974,
-       0xc7dee7ec, 0x8ce15e17, 0xd6e97711, 0x7e019253, 0xbbf7274f, 0x0295e58d,
-       0x4e7c8929, 0xd7a803c8, 0x5bb8f8e7, 0xaffd30a9, 0x405e91dc, 0x0d0f901c,
-       0x7b5cb9af, 0xfde4148d, 0x3a592701, 0x7f565e3d, 0x13bece8d, 0x03f6ca88,
-       0x3dd58dbc, 0xad70d15f, 0xfb33bbee, 0x1abba445, 0x1844c56c, 0x375e4b16,
-       0xb50e1d81, 0x0a399e0c, 0x61bf74e8, 0xd82a7182, 0x33c2fd0f, 0xe3e4a2be,
-       0x04afc812, 0xb9be93d3, 0x3cfbb698, 0x95f71e98, 0xafb1fa63, 0xdf36d306,
-       0xf23f4c6a, 0xc0fd31f9, 0x3fd31eb7, 0x3d30eaf9, 0xf4c7abea, 0xd3005f3d,
-       0x4c06bec3, 0x6235f1df, 0x620beada, 0x6373e1da, 0x6f5de9aa, 0xc7c93bb8,
-       0xbf80d3e1, 0x78eb3818, 0xfaed5560, 0x3b38ddc9, 0xd6afba6f, 0xcf9bb03f,
-       0x8e66f5c5, 0x1e1d5487, 0x336080be, 0xf297ace2, 0xb0e3997a, 0x9763efa7,
-       0x6bff377b, 0xc4de36f0, 0x8a6fccfc, 0x653c6eb7, 0xd594f018, 0x89fa9e1b,
-       0x34f1bbe3, 0x7e64e4de, 0x8fd3c70f, 0xe6311fa0, 0x84e00515, 0xd7f08bf4,
-       0xa71636dc, 0xd409ebe6, 0x6a716553, 0xfa1af6de, 0x75fa2b6e, 0x6e301181,
-       0xb7f11f9c, 0x3f8710e1, 0x274cd47f, 0xcff73d7d, 0xf99e9388, 0xcdf9c6ee,
-       0xbc1d00d2, 0x5b9746c6, 0xad5f18e3, 0xe8445226, 0xb0d0f6b8, 0x468b5c67,
-       0x49225e62, 0x55c07df0, 0x5ea31f1a, 0x7f032bea, 0x9aebe37b, 0xa1b3cff8,
-       0xff27f6be, 0x78e90b9e, 0xe397f313, 0xdbf4445a, 0x1769e849, 0x2e3c37f0,
-       0x10695d99, 0xa61aeedf, 0x086fd138, 0xf3fcf5d8, 0x376e7cd3, 0x3ca21eff,
-       0xb771c56a, 0x37f90d2e, 0xe9e1f3f4, 0x6f5fe07d, 0x7e37bdf6, 0xf80c0a2e,
-       0x37b3f097, 0x5d9bd8fb, 0xc5f56e24, 0xe77fed20, 0x0f3951be, 0x870760ab,
-       0x0f5a79b0, 0xa5d6d6fc, 0xff7cf48c, 0x33b8e26b, 0xeb71c355, 0xf9db4260,
-       0xf9cbeb88, 0x40132ba6, 0x9c1eb42e, 0xe4ed741f, 0x722f7e7e, 0xafa99b3d,
-       0x2fac6bcf, 0x68c22141, 0xa2bc6eda, 0x6a420490, 0x22a3cf44, 0x6d5c6fce,
-       0xec1b887e, 0xa8d6b9b3, 0xfd3c6f30, 0x1a854866, 0xf385f1f5, 0xc0769e87,
-       0x9a656c3c, 0x863c79c9, 0xaab4b51c, 0x8f69d331, 0xf504af9c, 0x4275f3f9,
-       0xe7ce2351, 0xa35984d4, 0x3a719c60, 0xbb050f8f, 0x56a9869f, 0xc534cacf,
-       0xddda9c79, 0x09590dd3, 0x6017fe6c, 0x225b64f6, 0x3ed39bda, 0xcfffbe0b,
-       0x7aa7a7a6, 0x69087a34, 0xc0589f22, 0xacb2d39e, 0x51efdf9e, 0x0a8ba41f,
-       0xb34937c4, 0x37cc39fc, 0xaffff4ad, 0x12bd4086, 0xbd7ab5e6, 0x3cdfa28d,
-       0xd36f9e1a, 0x53bf47b5, 0xf857b5b5, 0x93bd67ae, 0x7b86bb48, 0xf957bf2a,
-       0x068af0fa, 0xc7ef53ab, 0xdef2ea26, 0xe753ba60, 0xc03fc2d7, 0x2411af71,
-       0x87255fc0, 0x5f64a75f, 0x0cda780f, 0xbf9843c1, 0x2abdec08, 0x51e29b4b,
-       0x015a5d51, 0x34f28b9f, 0xfe73abfc, 0xa9d4ed4c, 0x7a0265d7, 0x54a4be46,
-       0x20a9f2e5, 0x4c44cde2, 0xbf98bf34, 0x4569a8bd, 0xa75b8c31, 0x50fe6c4c,
-       0x301c4a46, 0x75272e3f, 0x3d4f10b9, 0xa0454c4b, 0x3bc9679f, 0xfa11b18e,
-       0xb0544e78, 0xf5ebc5d2, 0xdf9d3c7e, 0xeacbf2eb, 0xe4a5f9f5, 0x075854d6,
-       0x2641ba5f, 0x86ec0101, 0xe898fcbe, 0x91977ac4, 0x6e30759a, 0xbbc79cff,
-       0x94893916, 0xfaabe941, 0x17732fcd, 0x892e3a52, 0xd6d5fc6c, 0x31279771,
-       0x05662bfa, 0xff7d3714, 0xb7b1a693, 0xbf440b51, 0x7583ac0f, 0x71297f6d,
-       0xf2d1256d, 0x1bf4bafb, 0x81fcd5e9, 0x4e64f5a8, 0xe0834a47, 0x63b0c40e,
-       0x3d30248a, 0x6aeef6e3, 0x838ba9c9, 0x223e42e4, 0xf18df20e, 0x78744294,
-       0x067a2cda, 0x7e19e34b, 0xd4820f00, 0x4dbe78a5, 0xf55169fd, 0xfbf52d5f,
-       0x903fd627, 0xabab9fd6, 0x4a9ff73f, 0xfa28d0ff, 0x5fd5620b, 0x76179bf5,
-       0xa93da9f9, 0x0e67e978, 0x53c9c742, 0x8baa5d52, 0xeb72b5ca, 0x9a6e1d0f,
-       0x0efc949e, 0x80a9ebc0, 0xde4b1458, 0x76f2c3ab, 0xbb8805db, 0xfd693fc1,
-       0x11ff9fa7, 0xdf3e23c6, 0x9e313b2a, 0x990e60d6, 0x37563ea9, 0xd9262f2d,
-       0xf2c63f98, 0x21139e0f, 0xafe3d41f, 0xa59fd9e2, 0x8a0afec2, 0x0a5f1e14,
-       0xbd5b3fa1, 0x1c42d3e5, 0xea17489f, 0x683bf191, 0xda1252ff, 0x424a85bf,
-       0x13a53974, 0xce5e04e3, 0x8fd36f17, 0xf80e89ce, 0xdfce1b57, 0x7397ef8d,
-       0x14b974ff, 0xa36ed29f, 0x26409eff, 0xf8d43d80, 0x3fcc0241, 0x2fdcf35d,
-       0x7a518fb2, 0xdd796cce, 0x49f04421, 0x8df3a3d3, 0x47b57f8b, 0x76ded9ed,
-       0xf48b3d50, 0x4af1b483, 0xbabf720d, 0x7295a599, 0xd52d71c8, 0xb24dcafb,
-       0x571f4fcb, 0x33f4f0be, 0xf31c424f, 0x30d7668f, 0x178aff5a, 0x8937bc0e,
-       0x976c57e6, 0x37598a53, 0xb76a42ec, 0xfff4bc5c, 0x72dd39d5, 0x80f978a8,
-       0xcf628ea2, 0x96ea4fef, 0xfbed8ac7, 0x9a2a3215, 0xf71b531f, 0x18f66d2b,
-       0x563c6972, 0x9ac27e08, 0x814bfee7, 0x7da9e2f8, 0x199fe902, 0x0e9b9f83,
-       0x7c001fa0, 0x39723942, 0x7866e585, 0x02e54bdf, 0x93935af6, 0x6e46fcb1,
-       0x753ea04f, 0xc5f9e224, 0xf2fdb43d, 0xd05d993f, 0xef17f2ff, 0x4e3f4071,
-       0xd70c3548, 0x2a61fcbf, 0xd972afd8, 0x94c4ea9f, 0xea7f2f3d, 0x65b788bb,
-       0x15377f6f, 0x9dc449e3, 0xc7b1c26e, 0x5bfd0e9f, 0xf63671b2, 0x20f1296f,
-       0x297fcaee, 0xfa680496, 0xb68a4499, 0x0e8bd0c7, 0x362717ae, 0xf68c4753,
-       0x1fcc04ef, 0x23bf5ec1, 0x422abee2, 0xffa026ee, 0xa17de5df, 0x3fe6021e,
-       0x1d3930b3, 0xaf5c4c90, 0x8919b7a8, 0xb60f2dd7, 0x0f4e7c82, 0x7587f772,
-       0xfc912f16, 0x57c21f9c, 0xedf15eb4, 0x7c99fde9, 0xf2e52a88, 0x3f38e8ef,
-       0xfbc39e15, 0x9adbb2ad, 0x7c8efbad, 0xfeddd995, 0xa53ede2a, 0xe7c60e3b,
-       0xfdb1a913, 0xa6b201d5, 0x8e9c74f7, 0x7e8457c0, 0xf2df7d33, 0x4d6fd310,
-       0x45a503df, 0x30f17e50, 0x0ef81fd3, 0x574a3fc6, 0xef963fa8, 0x3da0259f,
-       0x58e6f3a0, 0xe645bd7a, 0xd72fad7a, 0x96e94270, 0xbc088484, 0xc849fd40,
-       0x595f5c7f, 0x177e81ba, 0xd0bd2f61, 0x3eba239e, 0x71976f4d, 0xfa053ffd,
-       0xfeb74d7f, 0xef4c8d93, 0xfc9ff67b, 0x07236e2c, 0xf412799e, 0x5fa7ea95,
-       0x4b957d05, 0xdd7fdfa0, 0xeddef2d6, 0xdaff4f54, 0xdea9e9a8, 0xb4f51a7e,
-       0x1278c77c, 0x6aff4f4b, 0x7a989177, 0xd4c79f4a, 0xe21b7b53, 0xfd94fff8,
-       0x2897f8d4, 0xd9a7f9eb, 0x68f89ec3, 0x4a2f87b4, 0x68d3f22a, 0x61dfe90f,
-       0x3f8d1b92, 0xde1a770d, 0x755d7e2a, 0x309dd805, 0x85dc352e, 0x2ee1a971,
-       0xe3ab7e2a, 0xcffcb19f, 0x74a26b10, 0x4fd4b7cd, 0xa5847981, 0x2bbce08b,
-       0xeb88967f, 0x048b96a6, 0xc880bef5, 0x7df06fb8, 0xf078cd53, 0xfdfca743,
-       0x52f7b3b6, 0xbf13e77a, 0xebe5d6cc, 0xbfebf464, 0xc9abeafc, 0x73b73fb4,
-       0xeca7cefe, 0x63ca89be, 0xe28424ae, 0x24f39d28, 0x82484fe2, 0x3e40acf8,
-       0x7e63a08e, 0x7f0f3eb9, 0xebbb5253, 0xaffdede9, 0xa6f90f3b, 0xb63edbe9,
-       0xa42ef576, 0x2979b143, 0x20a54f12, 0xef3fca57, 0x04302138, 0x549b52ed,
-       0x7aaf3112, 0xb79ddb9c, 0x0f1ccda7, 0x9cfe4bfe, 0xe70c0951, 0xeb7e7183,
-       0xbcebf6e5, 0xbb004d5f, 0x0b39be7e, 0x0fe7afe7, 0xb58f8e2d, 0xe385b26f,
-       0x575f00ec, 0x750bb4e9, 0x277dc522, 0xc5ff42e9, 0xad92b76f, 0xbefdd631,
-       0xe4f89b2f, 0xfe8dcb83, 0x736e5489, 0xd1e70e39, 0x2272134f, 0xa6eb36e4,
-       0x5a239253, 0x71f7f00e, 0xdbeb3cc4, 0x0d7017f2, 0xb6b16dfc, 0x88c49615,
-       0xf384fdd7, 0x5f2bca6f, 0x69d5fee0, 0xf012f9cd, 0xd45d9a71, 0xd41e39c5,
-       0x192475f4, 0x794d7409, 0xe3a3f965, 0x87bd8e29, 0x57ec1744, 0x539f36f5,
-       0xbbe6313c, 0xfd427e46, 0x901e47e0, 0x23afc89d, 0xe012c972, 0x56d991eb,
-       0xef96eb02, 0x58aaae2a, 0xb3374e74, 0x523cc878, 0xe138d9f2, 0xe6fe3eff,
-       0x150f89cf, 0xb79c7e50, 0xd1c0fdb3, 0x7f7a63f8, 0x6a0429de, 0xc8a1c005,
-       0x004229f2, 0xc48564e2, 0x0164e8f3, 0x48fafdf5, 0x2c1f95fb, 0xd5f6017d,
-       0x4e0b3754, 0x96af2d13, 0xb1c014da, 0x025db837, 0x9546fcff, 0x20de31b8,
-       0x159a8cd5, 0x203ad711, 0x96afc84b, 0x277eddbf, 0x2cc2f7f0, 0xdcba0133,
-       0x6039cf23, 0x3cd0bfdc, 0xa7a0f516, 0x47c1fd7e, 0xa0934ca6, 0x30f8821e,
-       0xc530a1e2, 0x9ecfcba6, 0xa8ba064a, 0xdb98a6dc, 0x90c571ee, 0xe18532df,
-       0xcdf6cfac, 0x7d99fff2, 0x1bed4c9b, 0x691cb5c3, 0x512b46df, 0x2c7fadf6,
-       0x56b2b6fb, 0x58b80fed, 0x3fab37b9, 0x6be575c8, 0xb2c5fa4b, 0xd8faaf6f,
-       0xbe35fdfc, 0x2073bb0f, 0x23a36fb5, 0x6a40dbec, 0x6dc462df, 0xffcd15d3,
-       0x59bec5ec, 0xeff477fe, 0x316fb055, 0xd1523bfa, 0xe6a2b7db, 0x456fb45a,
-       0x7edd4503, 0xcf852ca8, 0x6fb47ae7, 0x1b367f0b, 0x16cbb2f3, 0x57c03f03,
-       0x71af6fb0, 0x80ed073b, 0x38a45b9d, 0xdabefdb1, 0xdabed2b9, 0x3e25ffb9,
-       0xe56e766b, 0x239e7620, 0xcecc871a, 0x7664ccad, 0x665ee56e, 0x630e56e7,
-       0xdf68ce76, 0x1beca20a, 0x047abefb, 0x8be71efd, 0x83b8bf99, 0x95cf1796,
-       0x7efa165d, 0x5f9daab1, 0x691f19a8, 0x122916ef, 0xdeca39f2, 0x39e1ceb9,
-       0xddecde90, 0x86ef605b, 0x0a1b1da2, 0xc7c4647a, 0xba6d430d, 0xbe4772fd,
-       0x4bf5ff68, 0x107f2fa0, 0xbefd9e71, 0xf68bcd89, 0x163ed17d, 0xa7376ef4,
-       0xc98551e7, 0x47e7c3b3, 0x24753a7b, 0x43aaf7d3, 0x544e3871, 0xbfac0937,
-       0x15010bf7, 0x5dbf81c6, 0x9df2f9c2, 0x797cd97b, 0x83f1998e, 0xcec89bfc,
-       0x2c16505d, 0xdcc3c08c, 0xd718154b, 0x0b112b9c, 0x0e0baff8, 0xfc0a70dd,
-       0xd69705d6, 0x00bbbfa3, 0x89bec39e, 0x32eb6ded, 0x2e77bb68, 0xa1de7017,
-       0x1798efed, 0x3f7a97b6, 0xec737e76, 0x38531a7d, 0x13ee533d, 0xa72fb002,
-       0x2f107db7, 0x239bfd72, 0xc8bf21b6, 0xf8cc625b, 0x985ef6a4, 0x97c62e4f,
-       0x6fcc55aa, 0xf289f30e, 0xf9a2154d, 0xbc5d2544, 0x2f9bb530, 0xfda4ee77,
-       0xbfb9e94d, 0xf7a2df1a, 0x3e71b8e1, 0xd7bf80b3, 0x3e341f13, 0xf39ff547,
-       0xb8a9fa9d, 0x8fc8c79f, 0x5ccecd46, 0x5e814643, 0x3cf26fbe, 0xf4701e3a,
-       0x942f949f, 0x0de6dbce, 0xd9e79dd3, 0x9372f9c5, 0x54b4d8e7, 0x6a48f815,
-       0x97b76700, 0x4a903f6f, 0x3b8b77fb, 0xe6420733, 0x78a6ffb3, 0x62d0fe20,
-       0xa83b42ed, 0xcccd30e1, 0x8e57f870, 0x9c0323c3, 0x09bc70d3, 0xafd44e0a,
-       0xf1cec190, 0xca5e647d, 0x6f5fd067, 0x144f8f90, 0x859fa09f, 0x720578da,
-       0xa9bcffa1, 0x5bc5c999, 0x6e5ca023, 0x81075d26, 0x8229d5ef, 0x2aab442b,
-       0x21ff6e0c, 0xd57ab7ec, 0x9e839f4a, 0xcdae0b97, 0xf4f61d8c, 0x963898d4,
-       0x3718e162, 0x9b8c4609, 0x24bde00b, 0xc668b7d8, 0x1efceff6, 0x3f4647b3,
-       0xf5b98a65, 0xe533d008, 0x09b264df, 0x7fe8061e, 0xfa303811, 0xf07a5131,
-       0xa4fdf735, 0x2afdfb72, 0xfc0ec1c8, 0x1fc052ee, 0xf8d886f2, 0x257b95a3,
-       0x4df21a75, 0x8e904393, 0x1c98e32f, 0xc8dfa960, 0x3cb45be7, 0x6fde1fe0,
-       0x7ef86416, 0x324f9506, 0xfa6a9a2d, 0x7786a0e2, 0x2fcd1ab3, 0x47a42788,
-       0x6fb00dd8, 0xd596eb91, 0x4f91b7c1, 0xeea2ac37, 0x27cd1a99, 0x07603e4d,
-       0x28afc72f, 0x8fee09fd, 0x9bea7fb9, 0x599a4fea, 0xacfb3faf, 0x868faf5d,
-       0x015eda38, 0x4e690aed, 0xf20fc5d4, 0xd65e6ccc, 0xce20f562, 0x5d935ebb,
-       0xfb68d59b, 0x0b971573, 0xcf2257cc, 0x0e854def, 0xd3b1bac1, 0xfad13e4a,
-       0x2ce1843d, 0xd5783c72, 0xf5f941ea, 0x5e04ff54, 0x98fe4f7f, 0xb40eff96,
-       0x5516fb07, 0xf1c67b7d, 0xf5278b48, 0x6669afd6, 0x69be3f66, 0xbe76b4bf,
-       0x9783baee, 0x4dfc62b4, 0x2cd87f5b, 0xc32e7e7a, 0xd048b8fc, 0xca5073ad,
-       0x9ff2fd71, 0xe558ff50, 0xfc43f532, 0xfcf94428, 0x31a7b6ea, 0xf9f67d5e,
-       0xfe833763, 0x48adf8ac, 0x3a9f542c, 0x1093c5b6, 0x80a207db, 0x24d1509f,
-       0x91167ae2, 0x2333b942, 0xd6420cfc, 0x14bc7e30, 0x62a7768f, 0x4c503987,
-       0xf5d8afbf, 0xddc43649, 0xf6601e3a, 0xc73cffcf, 0x1b2dbfa3, 0x242bfbd6,
-       0x946f8eb6, 0x9f1cbdcf, 0xe6db7667, 0x1a16fd82, 0x8ad779d8, 0x39b239c6,
-       0x6550ce22, 0x7b5c5996, 0x59f70db7, 0x70139ffb, 0x17d0329f, 0xdb52ce79,
-       0x39e679ff, 0x822b9766, 0xcdce0072, 0xef6c3456, 0xc5783880, 0xaffa3351,
-       0x0a7386de, 0x5f53a7f8, 0x23fd017a, 0xc5d4506f, 0x8fe2a341, 0x0cc8620d,
-       0x2aa6b3f1, 0x7f3403b4, 0xb18df30c, 0xc5bdf0e3, 0xb4bc56c9, 0xb29f9777,
-       0xcfcbc570, 0x6cdcf03a, 0xc60756eb, 0x1f2e1b21, 0x378a8fff, 0xd9743e36,
-       0x8e69e378, 0xf5995f8f, 0x21a435eb, 0x9490e319, 0x1892dcbe, 0xee308b71,
-       0x29ecf85f, 0xb33b0f58, 0x014fafe3, 0xb8ff95bd, 0xe07dd4f0, 0x3ab3ed8f,
-       0x3ef6bc61, 0x13d7047f, 0x7376efb4, 0xee78ef3d, 0xe9875c59, 0x05d9a3f8,
-       0x3dec75b5, 0x23d61831, 0x917fb63a, 0x55db710a, 0x3ce3a77b, 0xa9ced56d,
-       0x798c49fd, 0x6e029680, 0x07587d03, 0xa5abca32, 0xd03065a9, 0x1bca9679,
-       0xfc70b65c, 0xc58ab1b8, 0x371e55e3, 0xbd7b16de, 0xdc4e2a2d, 0xeb96f334,
-       0x926efc60, 0x43e92a5d, 0x9530f8bc, 0xc83ee8e3, 0x9a43db6f, 0xbf298fbd,
-       0x2a0ff0b3, 0xf20df7a7, 0xc969acfb, 0xb2849eaf, 0xe31ee4a6, 0xf03ea1c5,
-       0xdbcf5b4d, 0x6c7f7662, 0xf1d9bd06, 0x83cf8c6b, 0x835ce8dc, 0xd9f0bc74,
-       0x9cb38860, 0xc2eebb94, 0xcd7b33fd, 0x62aa2fb8, 0x3fa8fbef, 0xc6df3b1d,
-       0xd7c232f5, 0xf8483ad5, 0xf083ad8f, 0x4b779c39, 0x73338b3c, 0x5a1c43fe,
-       0x1e73e075, 0xd638666f, 0xc53dd0e2, 0x6c2dd39f, 0xceb6913f, 0xcfe5b558,
-       0xf5c4310a, 0xd3903c85, 0x8baecbb1, 0x02707c6a, 0xae44261f, 0xf38ec4a7,
-       0xb8ddd787, 0xe07e40bc, 0x4bd7857f, 0xc4207e68, 0xfbc203cf, 0xe83d8624,
-       0x61d6c4d8, 0xfbd8e43a, 0x95f5b50f, 0x4f418b14, 0x575b7d03, 0xaffe8de9,
-       0x26191fcb, 0xf9a3e39b, 0xd8cbe674, 0x45827c76, 0x61fb76f8, 0xf5a8852a,
-       0xcfac0b7f, 0x60531d37, 0x638da1fe, 0xf0cf7f5a, 0xe799f279, 0xb1ef3c45,
-       0xed05b1ae, 0x545ed1b8, 0x341f1613, 0xd3833bd2, 0xe3641d5b, 0xf11d99c4,
-       0xe7ad3b01, 0x11bb2bcc, 0x8edbd5cf, 0xdf5a7e29, 0x959786c1, 0x52fd88b6,
-       0x22044e30, 0xe2f33fe8, 0x7eb66cfe, 0xc6e5e6c4, 0x76f0e676, 0xdbb1cdbc,
-       0xa73b6ef1, 0xbf85676b, 0x77e76151, 0x69dedf2e, 0xea073dc9, 0x132add3b,
-       0xba7fbfd8, 0xc40a2c51, 0x45927f68, 0x4cf2e2d6, 0x8978e86f, 0xd9e31de7,
-       0x493146f9, 0x557aff41, 0x84d1de7c, 0x15154814, 0x6a6b14e2, 0x35d2fed9,
-       0x81a577df, 0xde24d7bc, 0x756deb86, 0x533afe06, 0xbf10f99c, 0x192b4e70,
-       0xda357007, 0x49b7449b, 0xf8aaff47, 0x1e70fea2, 0xc7f72d7f, 0xf3c2e488,
-       0xb0a3a297, 0x3a23fa08, 0x8c6b4e4d, 0x5ed905f5, 0x7c113c42, 0xf3fa9d91,
-       0xb1cbe492, 0xeda3d42a, 0xb4b4a9a3, 0xa742c41e, 0x4b0ab71b, 0xfcddec79,
-       0x77ec4e59, 0x4f3e36e7, 0x99d51370, 0xc183f6ca, 0x23b9d1b8, 0xc68c9b21,
-       0xe29b890f, 0x0b9fc6d1, 0x07eff6db, 0x41d6b47b, 0xcf5489dc, 0x31555728,
-       0x8e8dce0b, 0x805908b1, 0xfe6f73d3, 0x6d6bd696, 0xd0fe7116, 0x85f6d769,
-       0xcf4113ba, 0xdc11e46c, 0xfe5007ff, 0x4e9bb92a, 0x0240bee3, 0xdf76a4af,
-       0xb45d312b, 0xfce7bce3, 0x10071646, 0x98bfd5c9, 0x2470e2cc, 0xf1f3f400,
-       0xf3a70564, 0x7ef0a43c, 0x3ae78299, 0x72f6bd96, 0x3930886e, 0xb92bf244,
-       0xb4be7f48, 0x86c8eade, 0x77e27975, 0x9939c2b7, 0xbf5f5e32, 0x53b9fd12,
-       0xd07e7eaa, 0x4f5c25d3, 0xf0b4baff, 0x32bfd810, 0xebb452cf, 0xcfeae7fd,
-       0x59f71aa5, 0x2fb0bd21, 0x93ddea8c, 0xabbef442, 0xd6c7e6f2, 0x7a397cc1,
-       0x011915ff, 0x482ac9fb, 0xe7ce0b9c, 0x97d068ac, 0x79bb03ef, 0xd893b015,
-       0xebef172f, 0xc36dbf95, 0xdc79317f, 0x0aebf965, 0xe2dbfbc1, 0xecb2ae31,
-       0x9f68c5b5, 0xfe7a69cc, 0x7f3d555a, 0x7c8c236d, 0xde39f3d4, 0x369be7a5,
-       0xcf89ecff, 0xf3fa7909, 0x4b3e46be, 0x021bc784, 0xb5110e2c, 0x09b82dbf,
-       0xd9f236e9, 0x0b76d7c8, 0x7ce2f75f, 0x96257fa5, 0x81b26654, 0x842974ee,
-       0xa3d4617a, 0x80487b0c, 0x094a0f7f, 0xae57e2d4, 0x69efb478, 0x19423fbc,
-       0x7a06cefb, 0x2ebd0224, 0xd13823d4, 0x46de7607, 0x5bb6703e, 0x909f5841,
-       0x59e9aeaf, 0xfe94f79e, 0xfa22d8fe, 0xefc046d5, 0x762bd468, 0x0489376e,
-       0x9e8264d6, 0x6e309cba, 0x6a2cfa37, 0x9ff70499, 0x286cb510, 0xc4e27bdc,
-       0x1f7cc7f4, 0x8248e74a, 0x431b82fb, 0x3ec15317, 0xeba738fd, 0xde7bb066,
-       0xec04a425, 0x6c71cde0, 0xa798b29e, 0xdc2ab77f, 0xed7b4eae, 0x59bef87a,
-       0x785ce156, 0xcb56f367, 0x4507c830, 0x9bc47fbc, 0xb4157758, 0x332cd1df,
-       0x812ccaba, 0xd8bf1061, 0x1dbb632b, 0x7cf19365, 0x6b6fd865, 0x3a40fb66,
-       0x2c713f9b, 0x1de7b08e, 0x055e9fc1, 0x4c27acf1, 0x0c9ff7b1, 0xfdf89ab7,
-       0xfc70df35, 0x7fda8c6d, 0xf6cadc37, 0x0878fdc7, 0xe97547ed, 0x330e3e79,
-       0xcb96b87d, 0x6f4bf7f9, 0x6ceffec0, 0x47185416, 0x6e3bc50a, 0x39fb451c,
-       0xe3c488f1, 0x392e2c30, 0x9bbfbf8e, 0x1f80d2b8, 0x0223af13, 0x3fc4f3e8,
-       0x35b7dc12, 0xce2966ae, 0xa0eb7eab, 0x7586cf38, 0xb05b8a52, 0xe8ec6773,
-       0x956f8fbf, 0x9c4cb874, 0x798169e6, 0x04a384e6, 0xa384eded, 0x123cf2fa,
-       0x369db110, 0x4f6bf3fd, 0x5605f3ea, 0x49076f8e, 0xf86f7c05, 0x3aba4452,
-       0x01eb88bb, 0xd9676f5a, 0xa6efbc00, 0xda9c22f3, 0x6297e9a5, 0x7e71ac51,
-       0xf281e026, 0xe08509eb, 0x52c4f2f8, 0x5fefc63b, 0x05715a59, 0x7f9feb8c,
-       0xac4573cf, 0x7611e073, 0xafed8129, 0xe2502772, 0x0ad7ae29, 0xe975df8c,
-       0xebf63125, 0x70d6386b, 0x7d39e1ad, 0xd6279c69, 0xad0fc4be, 0x58290fcc,
-       0x6050423a, 0x204fb65e, 0x078ed7c0, 0x373d973c, 0x640f27e3, 0xe0de3d00,
-       0x2db3f405, 0x963b82cd, 0xeacab19f, 0x07bef360, 0x1fb0b5fc, 0x94aa5eef,
-       0xae7b1f60, 0xabce0377, 0x2ba0876e, 0x5ba9677c, 0x9770e788, 0x8866c858,
-       0xe9754b67, 0xee03c6b7, 0x4758cea7, 0xc4b27de9, 0x427e7284, 0xfefd2176,
-       0xbe30422a, 0x03b5e3c0, 0x229b266f, 0xc0ff23cf, 0x95b0ff9a, 0xd5b0fbd6,
-       0xf6497289, 0xdfa004b8, 0xe5ffdff5, 0xbceebd00, 0x0e394664, 0xed1ff3e0,
-       0x4f9cadbb, 0x6bdce3a3, 0x3ca4ff01, 0xe5c3f505, 0xc965a871, 0xe5012f70,
-       0x54758c7b, 0xf24d2fcd, 0xe946db50, 0xf09bb249, 0x76e22e7e, 0xdf6d4eab,
-       0x45efe119, 0x090903e8, 0x69a5f604, 0x166854f6, 0xff14f142, 0x10f62ce3,
-       0xca9233cc, 0x0929bf69, 0xf5616256, 0xc2674ab5, 0x9f71aae7, 0x2e65c53b,
-       0xb8226e1c, 0xd2360daf, 0x9d9afd42, 0xdaf3ecd5, 0x66f68244, 0x605263ed,
-       0xa367ad0d, 0xf88566d4, 0x2d5ba649, 0x4944ad80, 0xbde78a92, 0x7d339507,
-       0x32fd65b4, 0x50afec31, 0x0ff31f65, 0xf5ac4171, 0xfcc38fba, 0xfc00bcf2,
-       0xf5d43eca, 0x2e35b80a, 0x75cf6b2b, 0x79fe82c0, 0x3f706ed8, 0xbb8f90ac,
-       0xb1353f13, 0xeba102fd, 0xb69dbf71, 0x1bb4668e, 0x15de0f54, 0x953eaf41,
-       0x75cf9e08, 0xb572ffd3, 0xf611772d, 0xb9938f83, 0xf4169ac1, 0x2d91c4dd,
-       0x5f6bc780, 0xa238bbc7, 0x3784c8ec, 0xde806b3c, 0x8c3f6a6f, 0xa2131878,
-       0x33e5c8fa, 0x2a7b8552, 0x943ce19c, 0xfcf95ab7, 0x949bdb8e, 0xd1fd71d2,
-       0x3338e5af, 0x6bd357f2, 0xace7bea3, 0xb198b576, 0xc13200d6, 0xba110ed8,
-       0xc0b350e9, 0x8221bd1e, 0x4f99df7f, 0xbae942f1, 0xfc0ef417, 0x19818bf3,
-       0xcd0d9b80, 0x7e82b1df, 0xa3f1e37c, 0xb11d7e99, 0xa227fabf, 0xf6cac3a7,
-       0x0f803b87, 0xf22ffbd5, 0x728423f1, 0xea95cb0e, 0x443c6447, 0xe711bdc3,
-       0x81ac5e9a, 0xf0b2330b, 0xf9011c7c, 0x0a234288, 0x3a364cd6, 0x7f9aaf81,
-       0xcfec26bd, 0x9eb9e226, 0xded64e55, 0xcbf3591a, 0xefe8165d, 0xfe82f8aa,
-       0xf5175b97, 0x97f3a25e, 0x5e30f388, 0x67e70ba9, 0x090a4bde, 0x7e0b7f24,
-       0xb9eb6905, 0xc4a57e3a, 0x0757e0c5, 0xfff8d1e8, 0x6d93fb27, 0x6a83cfec,
-       0x25ae7f77, 0x51b6df9e, 0x4f7b90bb, 0x05c33a7d, 0x89169c39, 0xd95ebe0b,
-       0x51e77e93, 0x2dd706fd, 0x7a0d9f4a, 0xea99b13c, 0x8f5a29b1, 0xde09725d,
-       0x6bdae75b, 0xd4677b43, 0x5fbc8beb, 0x7be31b5e, 0x1199e88d, 0x5371f307,
-       0x5dc060d7, 0x8b924ab6, 0x41d9b129, 0xb6afad91, 0x91c6eb26, 0x8fddf1e8,
-       0x2ff35276, 0xf8d2bf35, 0xe4afd85e, 0xcf1686e3, 0xff148214, 0xc7f7dfb4,
-       0x5f01e679, 0xfcd938d7, 0x829a0e13, 0xab03fcbf, 0xcfa00ee7, 0x0710fb46,
-       0x42231aeb, 0x125e2c99, 0x4f5be9d2, 0xe83365fa, 0xc248634f, 0xc74fcc71,
-       0xcf4261b1, 0x4b8bf4f4, 0xab52f464, 0xc0ca7e02, 0xab1ac25c, 0x7bafb826,
-       0x47bb3660, 0xbb0e6066, 0xe3dff1f7, 0x7dcc7ad8, 0xd0dc6c71, 0x4b581fd2,
-       0xc97e81ee, 0x739bf112, 0x40dd39be, 0xef0fc42a, 0x0ddf738f, 0xb914b0fc,
-       0x4e191fb1, 0xde2812e2, 0x0146a432, 0x552437f6, 0x1b8b02aa, 0x40ee3612,
-       0x28cbeb4a, 0xdc61f356, 0x16b6a0ca, 0xcd1920e2, 0x6cf5cfb1, 0x5dbf9388,
-       0xea29abbc, 0x3886ca3c, 0x541f6fe6, 0x8b937f68, 0x709479d9, 0x0f9286dc,
-       0xbf88edfc, 0xf1db3b0d, 0xf50f5b19, 0x1b3e3227, 0x30205fe7, 0xf3c497e8,
-       0x6488543f, 0x91f9c24d, 0x99df04df, 0xb23f382c, 0xd8235711, 0x58e297cf,
-       0xe09d755c, 0x9ff90f5a, 0xb8165d48, 0xffc3476f, 0xeadf278f, 0x8e2be892,
-       0xc367ceeb, 0xc3ea959c, 0x8eaf20f3, 0xaf87e7c9, 0x0d741ec5, 0x8b737866,
-       0x9aeffdba, 0x4eb282dc, 0x8788566e, 0x78ebda44, 0x1df7e705, 0xe60b9c42,
-       0x05cb1d43, 0xe160a746, 0x7d2403e7, 0x43db869c, 0x27781c6d, 0xb7e9132e,
-       0xbc18ff11, 0xb2e2cc1f, 0xfd1a3d00, 0x86a473e1, 0x73c69e73, 0xe15969a0,
-       0xee3a4db8, 0xe0512d93, 0xbe722f8e, 0x97fe86d9, 0xdff4c1d7, 0x60fe8788,
-       0x6e732e3c, 0x15abf292, 0xae5fdbe4, 0xdb7b0449, 0x0ee3ceff, 0x0f91af90,
-       0xcc7f829d, 0xfadf5841, 0x9f731c83, 0xa5a69688, 0x7f05280d, 0x0d3d2d34,
-       0xbd79ed53, 0x07198a5d, 0xeef5cd3c, 0x9eb5e31b, 0xc3f30c58, 0xb39fd0d3,
-       0x73de779e, 0x6177baa3, 0x8e3ebc7c, 0xd15ebbf1, 0x8026a8f8, 0x5de7759e,
-       0x927eec09, 0x90ff7644, 0x8373c993, 0x492a52cf, 0xd1b9ef91, 0xdc47e91f,
-       0x1181e633, 0xad9320d8, 0xbf166b88, 0x5065ced1, 0x97e4c743, 0xb9fae8c8,
-       0xec294c6f, 0xcc6d919f, 0x30dc5d2e, 0x254bdb1d, 0x5387580f, 0x312d2ebe,
-       0x73ae20b9, 0x1c9fd176, 0x517c1470, 0xe02e6b46, 0x91e888fd, 0xd431e36d,
-       0x65b7f38d, 0x88409573, 0x9ea52a42, 0x9726241a, 0xb8eeb819, 0xff7314d0,
-       0xe6c6ddb3, 0x4e71cddf, 0x06d2d34c, 0x8d8d9697, 0x39440fcc, 0x7aa47869,
-       0xae365e98, 0xc5309cfb, 0x6fb40a47, 0x994ea7d4, 0x40dd6104, 0x9c2987b3,
-       0xd63d9aff, 0xf40521f4, 0x4b01d60c, 0xe4d47da8, 0x9abf8439, 0xfc4af18a,
-       0xfd5f9a13, 0x8e03e602, 0xded00aeb, 0x8f5ffd51, 0xd98232fa, 0xd3d82b6f,
-       0xe7653888, 0xc107f7de, 0xdf87dffa, 0xeb0f10bf, 0xba917f40, 0x9e7ec1e2,
-       0x78ddffbc, 0xe1f43738, 0x715e2cfd, 0x351e6197, 0xfaecc6c1, 0x6c92b6a3,
-       0xdf02d7e8, 0x227ae77f, 0xb3564970, 0x01e58d75, 0x5c9e70d1, 0x554f2f7f,
-       0x9ee1b263, 0x5bd63f1e, 0x32e7efc5, 0xcb92a1ca, 0x4db6f961, 0xed0a864a,
-       0x7eb6dc7b, 0xa08f6e70, 0x14d93cbd, 0x8d11f38f, 0xc6db459e, 0xfa773028,
-       0xaf99b34b, 0x6ccab77f, 0xc317705c, 0xf387967a, 0xc1e748cd, 0x6fac367d,
-       0xfed8cfc9, 0xadb48594, 0x7abed4d5, 0x0b79d99a, 0x7c963f63, 0xa7f616a8,
-       0x90f25bc2, 0x7862f380, 0x4e3a7eff, 0x883f5679, 0x7ec65eeb, 0x31cdef1a,
-       0xe6d55f9e, 0xfcb8cb53, 0xf50788cb, 0x6b5cea2f, 0x369f5b33, 0x1fceffc6,
-       0xff61b2ca, 0x91fe3c6d, 0x79c0264b, 0x86871de8, 0x3eee5c24, 0x1efc33e5,
-       0x1a57b826, 0x823e93d2, 0x654db669, 0xbf3464f7, 0xaae02f7d, 0xef1db83a,
-       0xf6bafb19, 0x94f9aaa6, 0x6b30f603, 0x91fa8776, 0xa43f01ab, 0x97f9d04c,
-       0x282e9bd5, 0xf8cbbe6c, 0x7e7f0770, 0x1b37f407, 0x3fab59f6, 0x7ce54c9a,
-       0x317ca547, 0xbf321ef2, 0xa6ee7f4d, 0xfad5fdaf, 0x2b5bf5a9, 0xd1fbe2af,
-       0xf869df8c, 0x2c78e6cf, 0x6eba52db, 0x9ad16500, 0xf30627bd, 0x4e7868f3,
-       0x1197c347, 0x4948cb3f, 0x8110ba61, 0xb147e693, 0xcb3c9a5f, 0xfef216ea,
-       0xbaf8d3fb, 0x8fc41a5e, 0x118dc37a, 0xdb721d1f, 0x2367d060, 0xb87a3a3e,
-       0x3627e45f, 0xa99427e6, 0x678842ee, 0x9d763751, 0x394fc233, 0xbc1dd529,
-       0x0b6cf40f, 0xf8c479c3, 0xd7b99ccb, 0x57cf1c65, 0xe1fdabc6, 0xdb943d3e,
-       0x6017d844, 0x5a7bc3f6, 0xb73eed3b, 0x7c04a86b, 0xb4f4c22f, 0x7435c4af,
-       0xd2f97768, 0xc0382e27, 0x411cee8f, 0x11d38e30, 0x77f7a7af, 0xf9e91136,
-       0xa543971d, 0x3f8ffad4, 0xd2da8d83, 0xda1dfb8a, 0xa071e4bf, 0xb145cd2f,
-       0xfe27f9fa, 0x86f7e11d, 0x4cf5c5dd, 0xe02c979b, 0x99abbb72, 0xda2f67ad,
-       0x30f28a58, 0x437ad7ee, 0xd0661670, 0x638d3caa, 0x51bf9014, 0xdf5c4b3e,
-       0x51607dc1, 0xf08f2272, 0xdc1e017d, 0x2f5653a7, 0x28c3dc62, 0x93bb7cbf,
-       0x6b57a39d, 0x42b71e70, 0x790ebd8a, 0xb5f4dda5, 0xc7ec63fa, 0xed0126c2,
-       0x65fe91a4, 0x0dd76a5b, 0xd67fd020, 0x847ee8bf, 0xe25da206, 0x55fad4fd,
-       0xff785c46, 0x50fad440, 0x7224f5db, 0xe6f2f53f, 0xbf2fb8c5, 0xb09ff69a,
-       0x85c61238, 0x7a35fa34, 0x1428fd8d, 0x8816c8cf, 0x5c16aee3, 0xefa39f60,
-       0xeeeb7327, 0xb0d85c3f, 0xafc8207f, 0x66fb625d, 0xce02fddb, 0x203f3b0b,
-       0xbd607d6c, 0x3d69eb80, 0xed99afca, 0x8e59ea07, 0xe7dc0a35, 0x8851b657,
-       0xf565c729, 0x11a1aef9, 0x60796a76, 0x8ea86b86, 0x1fdc46de, 0x54a1a2b2,
-       0x9d807cf7, 0xfdb893c7, 0x48df4dee, 0x38cc624d, 0x9a5fa693, 0x97fa69be,
-       0x3cd9576f, 0xcc1c0a47, 0xfebb04c8, 0xa84bce18, 0xcedabe5d, 0xd1e607d7,
-       0xb89faa57, 0x581f5ba0, 0xb3e4c792, 0xe7c62c44, 0xca57d93d, 0x1e7d9d07,
-       0x7fefd767, 0xd1fdb6f8, 0x85e9a1fa, 0x5ea33fd6, 0xc5aff918, 0x30728cd5,
-       0x82e81ff2, 0x7b1bc1f9, 0x0407816d, 0xa74677d0, 0xe915af7f, 0x702b48ec,
-       0x3fc839c1, 0xce9407c0, 0x31dbf4ea, 0x9496235f, 0xc75e71da, 0xfae34de7,
-       0xe1c83f16, 0xab4ed67e, 0x473b2c7b, 0xb80c9254, 0x36db5298, 0xf8a4e2d3,
-       0x2174647c, 0xe53a2bdc, 0x1099b6b1, 0xc8f25efa, 0x5fb84298, 0xb6d6ca7e,
-       0xea2e2d77, 0x2d8ed5d7, 0x57e5fb84, 0xf680dd80, 0x10db9607, 0x89e53d57,
-       0x9579f2e7, 0x5cce3fbd, 0xcbdd9f32, 0x292bcacc, 0x3c742d8f, 0xfc3c3cab,
-       0x959fa0f7, 0x1045c5ad, 0x8884a9b7, 0xaacf1d37, 0x2d908edc, 0x93e78d9b,
-       0x6cdb7be8, 0xf076559e, 0xc5ad2eeb, 0xb0f2adf1, 0x0e44fa84, 0x44a8b8b1,
-       0xdfa56afb, 0x7ea38dad, 0xdaefe52f, 0xe60b8b24, 0x1fb9f4af, 0x936bb5e6,
-       0xf11aaadc, 0x7c1f935c, 0x35ac7407, 0xfdfb75b1, 0x684f0daf, 0xbf78ccbb,
-       0xc32647df, 0x67c5a43c, 0x9e58d4c1, 0x7cf138af, 0xc589be44, 0xbfe58c35,
-       0x512cecd2, 0xd5170033, 0xaf161487, 0x4fe07fa6, 0x17a61156, 0xeb9d84d5,
-       0xf04c3aaa, 0xa1f54b1c, 0x02c73c42, 0xd63ffcfb, 0x735ff0e1, 0x571ba58e,
-       0x92054f8c, 0xc08a5930, 0x55bb34f5, 0x9bfb1797, 0x887f4046, 0x7382e718,
-       0xa9866218, 0xbfed0766, 0x294d0578, 0x4ba7243f, 0xea5afb84, 0xe1114ea6,
-       0x3235a9be, 0x62623fdf, 0xf6b5cce7, 0xb47f389a, 0x64bdb4f4, 0xecfdc807,
-       0x36b9ad5b, 0xf3817eb6, 0x6bbfad61, 0x60113704, 0xe08075de, 0x149c80f9,
-       0xb3fc02d2, 0xe01e7711, 0x127b3ded, 0x375b37e7, 0x90197fa6, 0x97a6ccba,
-       0x57f78a55, 0xfa84591f, 0xdd304ae0, 0x6ff34993, 0x7cb197d9, 0x2642e986,
-       0xf6dbf085, 0xc6bf9672, 0xcd086174, 0xce5f6bbf, 0x49c0b0f2, 0xf623b607,
-       0x48ff428a, 0x7de38768, 0xc01afb9b, 0xf16264b7, 0x0515e917, 0x7db453d7,
-       0x44e96b21, 0x1ef8f00b, 0xa7884dd8, 0xdafc16d4, 0x02eaf106, 0x3dfb0ab7,
-       0x837bf336, 0xf1aa69be, 0x7099b455, 0xf02903fe, 0x4fce43ff, 0xc9a42e4d,
-       0x8bec0d7d, 0x6bee8d25, 0xb4ed1d60, 0xf606d3dd, 0xad1bec66, 0x377ec053,
-       0x5ca7f3bd, 0x0afc9fbc, 0x37d8cf56, 0xf6909ce8, 0x066fece7, 0x8f5c8a6d,
-       0xffcf6d3e, 0x62a3be14, 0x5054ff40, 0xaa0ee49d, 0x44dc6b87, 0xbe60b255,
-       0x362f9fac, 0xb69f6611, 0x82ce4ad9, 0x10c0c95c, 0xf6455b8e, 0x6bc84e92,
-       0x26b49cf6, 0x9b5f69f5, 0x845abd92, 0x23293971, 0xd8117478, 0x7bb1dfff,
-       0x1bb7043d, 0x14be73f7, 0xed8cd7be, 0xfec1b10f, 0x177fd010, 0xf2a7f349,
-       0x2f8b17f8, 0x88dc9493, 0x07ef3079, 0xec1a7efd, 0x63609f37, 0xbf6807fb,
-       0x63abb044, 0x58e98a88, 0x81656788, 0xdf983d28, 0xde8f1a43, 0xdc7feb47,
-       0x9649e2ca, 0x0f8ba206, 0x38b3c766, 0x8b074ccb, 0x8dc9c60f, 0x10ff82b7,
-       0xc1388e77, 0xa5fce87f, 0x22fee122, 0xae2379c9, 0x11341d8f, 0x3959f7a0,
-       0x99f584e0, 0x7524abae, 0xafaee933, 0xab5bcb93, 0xbd4571f7, 0x7372e20a,
-       0x7d3fcc1d, 0x7ee09f36, 0x4a53aee8, 0x934dd600, 0x91352c32, 0xf92b9ff1,
-       0x0b390f77, 0xfe21e332, 0x408e37bc, 0xc5f613fb, 0xbf0e4099, 0x056396de,
-       0x3c04bc3c, 0x32487ca2, 0xfa86ef3b, 0x7a502e92, 0xdb39f133, 0x63a92f27,
-       0x277f2812, 0xe15760dd, 0xad67a9be, 0x7ee0378d, 0x784c17d0, 0x8a4beebf,
-       0x2ff214ab, 0x609d579d, 0x6ccd9f7f, 0xbcfec38c, 0xbcfec260, 0xf575d714,
-       0xc3f74a4a, 0x4a7c5823, 0xec0911b2, 0x502a64b2, 0x73cfa6ef, 0x493cd9e3,
-       0xe3cbd3b3, 0x2e3cfe99, 0x200f3c10, 0x7f51f299, 0x9d3afdb4, 0xebf7045d,
-       0x2ad59bf4, 0x4ae38e02, 0x4851b8b5, 0xe4cf7884, 0xdb7e8212, 0xe78cbb64,
-       0x307f6072, 0xc29b1b9c, 0x0f94efed, 0x813d712a, 0xdc30e04a, 0xe762d97f,
-       0x75f168f7, 0x4e39ebc5, 0x226d23ae, 0x5dd791f8, 0x07882e22, 0x8a497f5d,
-       0xe74e47e9, 0x10233ef5, 0x97be8129, 0x0095517f, 0xef44f977, 0x2faf4de7,
-       0xe0e3053c, 0x39e18b54, 0x8f4889f8, 0x4ff7cf1b, 0x4fee1a77, 0xd6f3e78e,
-       0xe47064c1, 0x1d6d313e, 0xf238ba68, 0x8b53f409, 0x65f01714, 0x3efdddbb,
-       0x5bfa7bac, 0x38b97265, 0xb63e33e2, 0xa5c46f9f, 0xa1ff5c38, 0x2e03b4f8,
-       0xf3afaeae, 0xafbf695b, 0x07eaca1e, 0xb95d821c, 0xc92997f2, 0xf1cde760,
-       0xa968decc, 0x97c03b86, 0xcbe18133, 0x3f5bba39, 0xe267c557, 0x01be9a7b,
-       0x3d9ea0ee, 0xac7e6072, 0xd78a6575, 0xedd78055, 0xb3f38276, 0xe65ba51f,
-       0xed699e82, 0xf86789ec, 0x6aeba637, 0x7587ee57, 0x6c67ff1d, 0xe03698bc,
-       0xde391292, 0x3864e87f, 0x3375aaf3, 0xf3fda66f, 0xbf5c65da, 0x8be7e549,
-       0x1e92f122, 0x770d1781, 0xef16761d, 0x7533f0d1, 0x3c22bbf7, 0x2119fa9f,
-       0x9e124cce, 0x99f86887, 0x9c3867e2, 0x138d8872, 0xddc7e1bd, 0xe6069ce5,
-       0x87370a31, 0x280a6e18, 0xb7f7f03e, 0x118fc07a, 0x8af54f37, 0x3cf12f9b,
-       0x53bdaafc, 0x186ebb2f, 0x7df7e9f4, 0xb689d31a, 0x8f82fbd8, 0x56ef7e72,
-       0x06cc6eea, 0x8993717b, 0x48937f9d, 0xe714adc6, 0x7bb4e3bb, 0x20b26be5,
-       0xf6625dbf, 0x19b37b67, 0xbb76cfed, 0xd77183c7, 0xcb9e0b34, 0x0da79226,
-       0x06bbf5f6, 0xdfc8d458, 0xc72ef8d1, 0x9a1ca361, 0xeffc0278, 0xf3fc98d7,
-       0x1b81ca6e, 0x197a48ec, 0x93b8c393, 0xe21126ca, 0xfdfc8e42, 0xe04faf80,
-       0xc3c02d4e, 0x25ef0571, 0xa0ae3eaa, 0xbecdfc5d, 0xbe210bb7, 0x9e1feda9,
-       0xc2ede7b0, 0x3ef09182, 0xdc6bd9c3, 0x3c796aae, 0xd276014a, 0xc4fd2f70,
-       0xfd2679f0, 0x8025f2bd, 0x72eeec9f, 0x73eb7de3, 0x1d1784e0, 0x736d6e77,
-       0x60b3074d, 0x4e7d6fbc, 0x9b1f9d88, 0x1d3dd47d, 0x7dd4654c, 0xb70f1ceb,
-       0x715dd691, 0xdffdf462, 0x163e7c74, 0xd7fbf10f, 0xc1c40a43, 0x6b9a951b,
-       0x26a27cd8, 0xa68fec0b, 0xf947f877, 0x08e1f8d6, 0xc3ff7ddd, 0x88f3f8f8,
-       0x38f7624b, 0x4eb829b5, 0xdf6128f8, 0xeb71f235, 0x39f7ae2b, 0x0f9c5eab,
-       0xb96c70f6, 0x576dd71b, 0xfe7c4539, 0x64b21213, 0x125cbc81, 0xca3477ae,
-       0x4213d4ea, 0x2a447bf7, 0xe5a76119, 0x8dc5fa7b, 0x70eff685, 0xf00e4c78,
-       0x43aea42b, 0x4984ddf0, 0x6ec16339, 0x4dacc7db, 0xa34c7186, 0xb455d29b,
-       0x874dded5, 0xc7275746, 0x858e1dc9, 0xf678c726, 0xe0a1d81d, 0x7c0b76b1,
-       0x71a0e1af, 0xff2639ef, 0xfc803c08, 0x2c20f1bb, 0x07c6bc80, 0xfcb54f1b,
-       0xa10f1f3f, 0x1e9f2081, 0x087100f1, 0x43c2b7c7, 0xc355f016, 0xaed7f503,
-       0xfe68fe02, 0xf6c2a35a, 0x0d796a1d, 0x7cf64507, 0x10a5cf7c, 0xf6443fdc,
-       0x6d39d959, 0x57ae224f, 0x6d64ecbc, 0x3ed87e74, 0x6498ba98, 0xebf983b2,
-       0x8c89efda, 0x57e80909, 0xe106a18e, 0x06e3f40e, 0x71743da2, 0x4176917e,
-       0x71377b80, 0xf806796f, 0xd064a197, 0xe2e6318b, 0x877fe010, 0xf8064a6d,
-       0xc9b63987, 0x5daf8059, 0x0ebd5623, 0x01aed643, 0x516f2fe5, 0xcd27fdbb,
-       0x6af0b5ee, 0x746ff6b5, 0xbd74fb30, 0x020f9d9b, 0x87491dbb, 0x2c41ff66,
-       0x9a108740, 0x86cafa63, 0x0db9baf6, 0x41d039ec, 0x205fbaf9, 0xe41fe04d,
-       0x5329dc9b, 0x17ebcfc1, 0xcece8092, 0x860c5fbd, 0xf3716538, 0xde8147ab,
-       0xd43d6d62, 0x350f5fa5, 0xbf9ad1fa, 0x342bcda3, 0xcf9b487f, 0xe504df82,
-       0xd3b9fcd9, 0x26add6cc, 0x6e782c87, 0xeaf3f1f9, 0xbfae6e55, 0x3147ed12,
-       0xa42dc7ef, 0xeed2e915, 0xf399b91d, 0x9d10f8a3, 0x39436687, 0x3e513721,
-       0x1defc4dc, 0xbfa5c9b9, 0xbc96e157, 0x688ef7d8, 0xbef6f4f5, 0xd6b87c71,
-       0x6df46eb0, 0x763e43d3, 0xfa7fc8cf, 0xd2773cd8, 0xc12fd110, 0xce979a80,
-       0x327069ee, 0x62521c3e, 0xb9fb578f, 0xb5324efe, 0xe5b9c365, 0x8efe7bfd,
-       0x7b2be3e3, 0xf81efefe, 0x494f1389, 0x4eb5f604, 0x012e353a, 0xd2f3e7d7,
-       0xab593d70, 0x9369fbd7, 0x88e7b08d, 0x5777ed1f, 0xdc7a520e, 0xc167d00a,
-       0x1e67b7f4, 0x77d429ff, 0x2244b8f1, 0x2a144dcf, 0xc710a19e, 0xbfbfe42d,
-       0xfe605073, 0x907e5692, 0xf3c5eeff, 0x21b0b71c, 0xc48fbb42, 0x9be7211c,
-       0x9a193df8, 0x593a6f5c, 0x8eca4a74, 0xfdfc0f96, 0x5a0be233, 0xf399a15c,
-       0x11fcb48f, 0xa77cb7cf, 0xfc096ee9, 0x89a4eff3, 0xeed11dc4, 0xe0ce950c,
-       0x2f1ce223, 0x4a7e0c3b, 0xbd3f73cb, 0xde2b8e99, 0x4adc4437, 0xfede6de8,
-       0x5be4367a, 0x8ff798c5, 0x9dfbf918, 0xfef1bbe6, 0x2a092191, 0xfb5bd3d2,
-       0x38a6ae93, 0x27720d19, 0x65cbcfcc, 0xe51877f7, 0xff9ecafb, 0xd91b6e48,
-       0x927bbf33, 0xbf0e51bf, 0xeb80533d, 0xc3c9bd4e, 0xb47ddb88, 0xbfda7e9f,
-       0x9fa7ed10, 0xf8af63fa, 0xbdff989c, 0x1af30d2f, 0x9f7bbd5e, 0x4e7f064e,
-       0x64f4e9c3, 0xbb899b86, 0xec4c9a7f, 0xf232f2dd, 0xf30773ed, 0xd710e66b,
-       0x3fe99bec, 0x78ae0a77, 0xd27e17b4, 0x4ab3fb0a, 0x0e738d38, 0x41ffa217,
-       0xe31079f8, 0x1c473638, 0x7bdee789, 0xa19bddfd, 0x5b9832f9, 0xbf0578e3,
-       0x36b802c7, 0x6f45538e, 0xb2e049d4, 0x98ab4a15, 0xba7ee31d, 0xce519746,
-       0xf6094847, 0x8d3a27a3, 0xabd23038, 0xefdae7f9, 0x4c7e50c0, 0xddf5a24f,
-       0xff63e6aa, 0xce61c6a2, 0xdfc69e97, 0x9c95fa9e, 0x1cdee3c0, 0x4e4e17ff,
-       0xdbd80b7b, 0xe519be93, 0xecd72c66, 0x90342147, 0xfc1fa983, 0xa9092191,
-       0x97850fa8, 0xe3a6e214, 0x3fa8190c, 0xaf8a4eff, 0xe3ddbc40, 0xc27acf64,
-       0x1325f55b, 0xe37724f1, 0x663e0e4e, 0x96eddc03, 0x1f106cea, 0xba5ecebd,
-       0xda6f5406, 0xf0b305a7, 0x1336879e, 0xf4d99081, 0x102d73e6, 0x251ef047,
-       0xa0a03e78, 0xc054ff79, 0x56a5efe9, 0x5e75479c, 0x08b1e424, 0xbcd8333f,
-       0x587e06c6, 0x6f9d8530, 0x7448983b, 0x27f790fb, 0x8f06bc30, 0x1dd9bf9f,
-       0x2f12fca3, 0x29dc499f, 0xc72e38d9, 0x70a3fc63, 0x3ffb09bd, 0x481d704d,
-       0x9e65bf01, 0xce85f380, 0xa40e13bd, 0xee3b7a50, 0x333b444c, 0xdde0f83d,
-       0xc6882a4e, 0xcf8b1eff, 0x780a16bb, 0xeaa140cf, 0x59617cc2, 0x98dfee26,
-       0x99e48ff0, 0x433e50c5, 0x74cdf9c6, 0x788252b1, 0x2134d9d4, 0x7b8be607,
-       0xf85ab684, 0x297f5c1d, 0xfd38876b, 0x7cff30c9, 0x0c7938a7, 0xaa9c76fe,
-       0xefe187e5, 0x3cc31203, 0x0bced56d, 0x7cb4cdfb, 0xf7016cd5, 0x66774eef,
-       0x7e047f10, 0x7953d70a, 0x6cb8a58e, 0xb8005fee, 0x3fa4599e, 0xc4bb3837,
-       0xeb910246, 0xef138216, 0xf7c83b21, 0xfc097769, 0xe7ae7c5e, 0xcfbc7037,
-       0xfbac9b99, 0x3f3094ae, 0x6453bbd3, 0xb3e471f7, 0xf4d6a1df, 0x87ae46eb,
-       0xf1f9f037, 0x8e864f3c, 0xd288628e, 0x5b3f4088, 0x62e5be47, 0xa5cf0e1b,
-       0xe78707e2, 0x1c6ef6d3, 0x8ad79861, 0x17116b95, 0x6f1d6c69, 0x1382ec36,
-       0xdfea6ec1, 0x9f4f25bb, 0x97c7a18f, 0x3d9a13b5, 0xc457bd98, 0xf9d9c375,
-       0x8902cf94, 0xaebfd3f2, 0x726098bd, 0xd078801d, 0x78dc97ad, 0xbd944e8f,
-       0x1be8a0f8, 0x50df8bd9, 0x7aa3cc1d, 0x1f0264fd, 0x41910737, 0x8ba63760,
-       0x380a7edb, 0xa6e3a4ea, 0xb48e0639, 0xef9b4771, 0x063d5217, 0x6c3390dc,
-       0xa5fa659d, 0xa4efdc34, 0x76c3f7cd, 0xae25fa84, 0x6fd2fe18, 0xf774b212,
-       0x4aed847a, 0xe7225f84, 0x64bf7b7e, 0x9547f53a, 0x206fa01c, 0x7b458ff1,
-       0x42c97186, 0xf10518d8, 0x1873b4c1, 0x744af1e7, 0xf3e38afe, 0xb02f88d3,
-       0xb752427f, 0x15fd187e, 0xd63cce2d, 0x7a53f9a9, 0x8de3849c, 0xa57dd8b3,
-       0x810a4e1a, 0xb3ffa09f, 0xf4eb8c44, 0xfdad1b86, 0xa212f0de, 0x564c08f6,
-       0xfae1788f, 0xf2f175f7, 0x197c6d17, 0x05f6864a, 0x343e1a27, 0x9bc718bc,
-       0x83c434ff, 0xba6f1a7a, 0x0e6f197a, 0xaed1908c, 0x7cd7e6f7, 0xeaf3e4ea,
-       0x37a62704, 0x7f1b355c, 0xd82c6897, 0xf937f011, 0x6b8e15b8, 0x1c9c33d5,
-       0xc1245b68, 0xec1791fa, 0x1cb76647, 0xfff078b4, 0x81c4c600, 0x008000d5,
-       0x00000000, 0x00088b1f, 0x00000000, 0x7cbdff00, 0xd5547c0b, 0x67b7efb9,
-       0x332479ef, 0x49926649, 0x1d843c32, 0x09212108, 0x11bc210e, 0x11084937,
-       0x88a80ca2, 0x1f01d68f, 0x4d092060, 0x6f53d5ad, 0x52812133, 0xbd583d6c,
-       0xf4f47bd6, 0x41ed5837, 0x0108750d, 0x26702783, 0xd0f098a0, 0x7ac0f820,
-       0x452968da, 0x5a18921b, 0xf5cf6a0f, 0xf6b7df7c, 0x8326664e, 0x73def7a5,
-       0xd62e9f87, 0xf5af6b5e, 0x5ff9efad, 0x4a9b5adf, 0x500a9fc0, 0x982015b3,
-       0xe1f95006, 0x06484a86, 0x01203be8, 0x96d40314, 0xfe1b41c9, 0xb1fdb4b5,
-       0x0cdd45c7, 0x51df8956, 0xf5c02661, 0x950b7e20, 0x06e6c50e, 0xbc95e658,
-       0xd6801672, 0xe1bfde2e, 0x62a82592, 0xf9af7afd, 0xe89b1ee3, 0x5fff35fb,
-       0xb800c803, 0x197f7f51, 0x2ffb0ffd, 0x1860a4d3, 0x3b365d5f, 0x978dffba,
-       0xa6913fca, 0x62d72c02, 0x3e4fc39e, 0x22f2a793, 0xac24becc, 0x8fb74457,
-       0xcfb92673, 0xe32ff1d9, 0x32d7fc61, 0x65f3c5c0, 0xaff7516f, 0xc8ed77e9,
-       0x523d48f2, 0xace80166, 0xdb1971b7, 0x7f016e5e, 0x4d2581c8, 0x0065c450,
-       0x9d0a0152, 0x581998b8, 0x0d0164bf, 0x136308f9, 0x3ab9f7e0, 0xdf86131d,
-       0x07e3883f, 0x8e30dc70, 0x3801c81f, 0xfae4ef54, 0xae1ef56b, 0x2f82935f,
-       0x877fe3a4, 0xb8a8b0bf, 0xdfedc59e, 0xdf38fc51, 0x8f0a4be2, 0x93d69b3b,
-       0x71830b4f, 0xf73f9eb4, 0x0de3fd16, 0xb6bfdc30, 0xbf8b33fd, 0xf9ebf2f0,
-       0xa7e7f35b, 0xcd3f3ca8, 0xcf0c15ab, 0x180144bb, 0x9a5ceb83, 0x635fcd1b,
-       0xc6f9589e, 0xfeb96fca, 0x56fcac7e, 0x90c7acc4, 0x32a2f40f, 0xffc38a8d,
-       0xa6d0264b, 0x437e5e5f, 0xb3f8b1f2, 0xdb2305bd, 0x72c97e01, 0x974f1e1a,
-       0xbe2b7417, 0x19974142, 0xb752baf5, 0x40efd40b, 0xb2b9ca0a, 0x4889c213,
-       0x2be7f5d8, 0xf4a8513e, 0x9471f04a, 0x6c7c033e, 0x1e1e5bc8, 0xe425d17f,
-       0xbcf0da6b, 0x7764148b, 0x0b1f3d11, 0xa8eb3881, 0xea1471a1, 0x6c39601f,
-       0x155a61d9, 0x635c75c2, 0x547d3b81, 0xe0328a26, 0x937db894, 0xf6e3c4d3,
-       0x8266c5ff, 0x3e5e01ab, 0x48025998, 0x3cead79f, 0x42011306, 0xbff7e066,
-       0xdfb9524e, 0x240824e6, 0x74a0fce0, 0x945ec8db, 0xb45c8012, 0x25b4653b,
-       0x364388d8, 0xd91f612b, 0x8157bf61, 0x2fdbb406, 0x050ef78d, 0xc914076e,
-       0x4c738fe6, 0x7ef4598d, 0xf61e7bb8, 0xa8a4559b, 0xcb8bb0db, 0xda877eaa,
-       0x9d580efb, 0xfeff5ef4, 0x699877ef, 0x1780bf9c, 0x0ed78429, 0xe7da8158,
-       0xf241cc3b, 0xe3e48b1f, 0xfdeb09b2, 0xec560003, 0xb8557f3f, 0xd76e5014,
-       0x13a37740, 0xc724b9cb, 0x8d7bf238, 0xfece9bd6, 0xe50a31c3, 0xd39740b4,
-       0x956fdd02, 0x8fd9901e, 0x41c92694, 0x53f61ac8, 0x5a32ead7, 0x3a256c80,
-       0x7ae1b416, 0x4bdafdb1, 0xb4bf5c4a, 0xe1771f48, 0x9321419f, 0x7ad1085c,
-       0xf84da8bb, 0x14d012a3, 0x6d4b29c0, 0x97e4ed31, 0xce459e90, 0xc973e7e8,
-       0xef5ea277, 0xf84bf18e, 0xf7bcd133, 0x8bbcc53b, 0xf726bfe4, 0xb65ffae0,
-       0x43cdef68, 0x9a4e077a, 0x0e7c59e1, 0x6732b1e7, 0xd0da5f24, 0x973983ae,
-       0x07fd8bb7, 0xe9153513, 0xc7f49979, 0x9ad1f541, 0xfdf2f53a, 0x940cf6a7,
-       0xb9787760, 0x13028579, 0x7b4f1d58, 0x3df98632, 0xff3aaf82, 0x22d9f963,
-       0xf91d9341, 0x5bddb0bc, 0x0465ae46, 0x8f913b1f, 0x80c95ef8, 0x295cf3c6,
-       0x78fb0d1f, 0x46a25cf9, 0xb9f2fefa, 0xffcd1ad1, 0xfa6be92a, 0x3feffeb0,
-       0xfe48983b, 0x2aa8f913, 0x2e0317a8, 0xd659f79b, 0xa1f7a15f, 0x6dc13951,
-       0xf5d16f58, 0x81c4e5fc, 0xefc4f9a3, 0x67de4deb, 0xe3651a69, 0xe48515c4,
-       0x9c96b737, 0x0d2477c5, 0x7ed107a4, 0x7709d524, 0xfb401960, 0xa40b7d21,
-       0x1993eb02, 0x36f34042, 0x9534f06a, 0x29abe60b, 0x1c41efc4, 0xe341dbb3,
-       0xe7a429a9, 0x338bd7f0, 0xf923857d, 0x0a8f52de, 0xd6b4f385, 0x1b2534db,
-       0x93bd5f60, 0x1ef56deb, 0x57ad5f2e, 0x2c74dcb9, 0x8e20c1f9, 0x3459ab53,
-       0x7df86d25, 0x8fb0aa57, 0x8867e805, 0x052005ae, 0x0b73a803, 0x5ef5d61e,
-       0x249b8291, 0x27ae1392, 0x97289f82, 0x08dc9ec1, 0x4d2936fe, 0x35b26693,
-       0xf28bbcb0, 0x063efc4d, 0x59f3e0ff, 0xdca3fb23, 0x4baaeaa3, 0xbae67e62,
-       0x961724b4, 0x52f8743f, 0x6e916ca8, 0xb8017c39, 0x5bf512ee, 0xfe380be5,
-       0x7842f0f4, 0x74c3e310, 0x15f10c14, 0xfd13b77f, 0x402c3a33, 0xca80c1f2,
-       0xd3a45976, 0x492e7da3, 0x323e70e7, 0xe0c7af9d, 0x30cad67b, 0xe83ed1e9,
-       0x17be2349, 0xb4767cdb, 0xc843a428, 0xf66e9355, 0x9cde3848, 0x26578b74,
-       0xa6fa26d2, 0x75fe446f, 0xd884e3a4, 0x6323a3bf, 0xa6f68aac, 0x4fbc6f29,
-       0x1cd9ad76, 0xcc2b8161, 0x71113dbd, 0x719e133c, 0x9f22bc52, 0xbdf235f6,
-       0x01c977f3, 0x73886bf6, 0x9e758fc8, 0x7186f64a, 0xd92e6b9e, 0x7fd256bc,
-       0xf5ed117a, 0x54f26260, 0x5dd0cff2, 0xd6b8ebc6, 0x6f91d626, 0xd8bb17f6,
-       0x9f0f859f, 0x6dfef7c0, 0xe9fc8010, 0xca1fdd35, 0x9a94f480, 0x907b32f2,
-       0xe4d2c3ce, 0xfc9f2a14, 0x9701725d, 0x897b92a7, 0x764d073f, 0xa77de695,
-       0x46ce2d5e, 0x72ded17d, 0xd61d0098, 0x0a1cb782, 0xa1ea2795, 0xe5f51b38,
-       0x971b7aad, 0x5c9deb27, 0x70f7aa9e, 0x49db1879, 0x76c75e9f, 0xb037b7d2,
-       0xd85dea9d, 0x1c31e54e, 0xdba2ca97, 0x96bc7893, 0xb42c92db, 0xd0c9838e,
-       0xfa4fcc6c, 0xb70c4e14, 0x3fe01782, 0xab6afb1e, 0x978c2aed, 0x34a17f56,
-       0xb3f4f90d, 0xac142aaf, 0xee3c5b1f, 0xbb60bfa1, 0x1fa667f9, 0x9bde90db,
-       0x8f5a394e, 0xaa9edd63, 0xfa41d8fc, 0x9d112c79, 0xb9b59923, 0xa63a434b,
-       0xcd1c6f93, 0x3660d76c, 0x7af4d3d6, 0xd95d7cc0, 0xa595807c, 0x42e0f93d,
-       0xaf597125, 0x577f21b3, 0xa3dffdda, 0xabb025ba, 0xaa2aeca2, 0x7b248863,
-       0xb641cc97, 0x7b92b1f7, 0x95bbc605, 0x127fff0e, 0xd17b0dbf, 0x91a43fa4,
-       0x49a9987f, 0xbcb372e0, 0xe1a49383, 0x95bf46e7, 0x49ff458e, 0x25debafa,
-       0x98cd7db3, 0xc741692f, 0xfa35fb48, 0x96ab38cd, 0x9e66fc91, 0x72a26f2f,
-       0xeb8b8559, 0x9ab355be, 0x1ccbfec8, 0x94bf7b97, 0x65d07fdf, 0x512dbd66,
-       0x389c5fb0, 0x8e9bf468, 0x7bb8464a, 0xf8312ba0, 0x69f5e92c, 0xd612637f,
-       0x8ab27917, 0x0337dd64, 0xb63b5dd7, 0xebe57b51, 0xde576cad, 0xf2e12f24,
-       0x6990a899, 0x21d0bed8, 0x2a64c379, 0x4a6a3ff3, 0xe4a776a3, 0xd42db625,
-       0xa6289da6, 0xbbd96cf6, 0xd5a7ea90, 0xa7510a32, 0x2ef38594, 0xb9c5bf60,
-       0xbe1b5e29, 0xd0fc2a77, 0x85dfd245, 0x04de49b9, 0xf04af3f2, 0x7baa1ae9,
-       0x9506dead, 0x6958f1d6, 0x4aa38d32, 0x5bd6135e, 0x1ffd286e, 0x2f894744,
-       0xda892405, 0xd7e10a5d, 0xc3f77f27, 0x6bf62732, 0xd9012719, 0xde70a9cf,
-       0x85fe889f, 0x026a899d, 0xb38b69f9, 0xb16bde8c, 0x5c4dce48, 0xff5295f7,
-       0x7d598e40, 0x7e3dc71e, 0x41e39d9b, 0x8c055be5, 0x36df8e83, 0xe542e386,
-       0xa84bf35b, 0x78126e3c, 0xcaadf2bd, 0x41376e0a, 0xe54a9c98, 0xf7e2dfed,
-       0xb0fe97b6, 0x1fe38dcc, 0xdf62ef1b, 0x562a7282, 0xf624fc22, 0xbfde8907,
-       0x77fb9abd, 0x9d0f9948, 0x0b17fec5, 0x38ac8a52, 0x213bb97f, 0x58c57faa,
-       0x497d5457, 0x2562a8f6, 0x16564fc2, 0x6fd54564, 0xb38a9628, 0xe6fbfa23,
-       0x57d54427, 0xb38ab994, 0x54dffa23, 0xbeaa2a39, 0xa8aca6f2, 0x1cd342fa,
-       0x61ea3fe1, 0xf3b0997e, 0x20d965f9, 0xa9fc898c, 0x037df453, 0x3b26efdb,
-       0xa9f812ef, 0x09f885c8, 0x55d652e5, 0xd8b971cc, 0x00affbae, 0x92667b74,
-       0x2ebf17ff, 0x83de8f1c, 0x4999fe20, 0x16fc4878, 0x201e2376, 0xdc60a47c,
-       0xcca7a08e, 0x2bc71d11, 0xff27cd40, 0x84b9d15b, 0x67b954f1, 0x319a1979,
-       0xbdfa31f2, 0x8161f90a, 0x2ee86243, 0xa5c732ea, 0xf46c62b7, 0xabae06fb,
-       0x316be9d0, 0x09529bf9, 0x6eb4058b, 0x7ac635c2, 0xb72e3a0c, 0x8ef90a9e,
-       0xdfff1432, 0xfd2c575c, 0x7f791b00, 0xa0d74b11, 0x8881c74b, 0x760718a7,
-       0xc43e32a6, 0x3e1e3b9f, 0x254f7030, 0xa45737fa, 0xee48737f, 0xf79785e5,
-       0x97b8c66f, 0xb8c67bc3, 0x2cd0fbc6, 0xfbc6fcf3, 0x2955cf43, 0xd89df3fe,
-       0x73ce293f, 0xf9ff14b7, 0x17fdd173, 0x03a36a28, 0x4828f8ed, 0xfbf100de,
-       0x2410aab8, 0x35ad3d2b, 0x43e8b951, 0x747842bf, 0x1340d9f1, 0x837af395,
-       0xfeb8adc7, 0x956572eb, 0x1e060df2, 0x8cd75d8a, 0x3a4fb154, 0xabb5497a,
-       0x5012ded8, 0x68bfb4ed, 0xd3b55879, 0x8345aa3e, 0x6a2fda0a, 0x691b4d13,
-       0x63e5a1bf, 0x549cf589, 0x52f3e7e1, 0xca318e05, 0x5e7f6567, 0xb6d5962a,
-       0x8b09479e, 0x60317cd4, 0x94703021, 0x48c15e70, 0x0954779c, 0xa3be683a,
-       0xbe1d070f, 0xa57e3f08, 0x29146f38, 0xa7e93a5b, 0x91fa45a4, 0x16825b52,
-       0x391637e9, 0xaff5515d, 0xc7d8aa9c, 0xbd45467b, 0x159a9d77, 0x6bf10fd5,
-       0x46a0e12e, 0xe42ae40b, 0x5e894d47, 0x7cb177c2, 0xfd7d17fc, 0xe093875e,
-       0xaadd9813, 0x97138fec, 0x7f82a5bc, 0xa457cfb1, 0x6fea7d8a, 0x6e583d68,
-       0x35f4154f, 0xe2013ec9, 0x3e933710, 0x4f71d6c4, 0xc3c68aba, 0x77a43d91,
-       0x22e9bb5e, 0x4ef86f42, 0x29d7d5ea, 0xe9decfa8, 0xc44eefa6, 0x8ba923fa,
-       0x699e7d44, 0xffac04cf, 0xd45cb534, 0x374d36af, 0x057e017b, 0xc32baf8b,
-       0xe7dbba7a, 0xfb79c54f, 0x12ad8ecd, 0x24c519e2, 0x787b9141, 0x0588fbff,
-       0x160a29e3, 0x21734c95, 0xd8ab76ad, 0xa024d72f, 0x25fea3ff, 0xaafc4a9a,
-       0xdce43049, 0x1d714193, 0x9134ceee, 0x6ff630bf, 0x87be0b76, 0xfcd8e7ef,
-       0xc25f42b5, 0xa5fa2ac9, 0xca2ff7fb, 0x9ed8bd24, 0xe7f5e4ea, 0x21e799ef,
-       0x7d74857f, 0x7ffdfa97, 0x3c536ba4, 0x62cc9aba, 0xfc96de9e, 0xf9bb8a52,
-       0xd21c51e3, 0xbb70bcb0, 0x4213cfcf, 0xcb8c2ba8, 0xf5848f35, 0x4bc59746,
-       0x90fb7d38, 0x6cacaf7c, 0xb213f3d4, 0x9c8de85d, 0x1bb8da62, 0xfaeb9fcb,
-       0x3bcd14f2, 0x1819e683, 0x01f51cb7, 0x56e3039c, 0xe93a8a14, 0x0d172c83,
-       0xf81ede10, 0xf7979256, 0x7e0763c7, 0xbfac03fb, 0x97be4777, 0x8907f470,
-       0x82ab3f82, 0xb07b1a13, 0xbc1acd3e, 0x3e748c2a, 0x967fe694, 0x6b36e0f4,
-       0x9beb1270, 0x8d126363, 0xfbc0692f, 0x877f6310, 0x32d538fb, 0x1fee2471,
-       0x88d82f39, 0x11ccb7cf, 0x45e6367c, 0xee28da9e, 0x3c5b37bc, 0xf9c0e837,
-       0x06ff885b, 0xc074433d, 0x03c72758, 0x45a47910, 0x61e443b2, 0xbce260ff,
-       0x1f192d49, 0x359cf7d6, 0xcfaebef1, 0xe68057d8, 0x9b933d58, 0x27399e78,
-       0x6c4cc936, 0xd4ccff00, 0xb6af4859, 0xfa7de7ad, 0x7de8ee8c, 0x7f4eacfa,
-       0x9bdf03a9, 0x7cfc7ef5, 0xdc7d3cc8, 0x299410d9, 0x89e9cf5e, 0xdf4f37ee,
-       0x1f3bcfa7, 0x54cdfcfd, 0x868dbe3d, 0x8e7991d1, 0x33ff7d3a, 0x0a427c78,
-       0x3af929e9, 0x516ef919, 0x3a9d9865, 0xeb5a37ec, 0xf90e5fb1, 0x85971b47,
-       0x11779da7, 0xa8f56dfd, 0x93f216d0, 0x7b0d2e1e, 0x770d3c2a, 0x7988d4c2,
-       0xf837bd74, 0xe0bef838, 0xdc9eb4e3, 0xbac7cf9f, 0x410cd3b9, 0x739d7875,
-       0x820d3e75, 0xd3a0f3e0, 0xd99e7cc2, 0x61e9cbf5, 0x98f5647c, 0x5f588d40,
-       0x6a089a82, 0xe7b53f84, 0x65d546a6, 0xce3a3e43, 0x9f8fae98, 0x351d1de4,
-       0x0c37818e, 0x5a9abdf9, 0x643849de, 0xe31d63ba, 0x13d9948e, 0x3e2dc6a2,
-       0x64272b1e, 0x2476e11c, 0xd7089ff2, 0x70a2569f, 0x80772cc6, 0x3fb30038,
-       0xc9706254, 0x68ec9976, 0xe7e8d9ee, 0xc8cbb4e6, 0x84fc72ed, 0xef9f3fa9,
-       0xe9f9fbfe, 0x99f9a2d2, 0xcfcd1156, 0x3f345f74, 0xf3455733, 0x9a3f946d,
-       0x4dd6632f, 0x6abf6a89, 0x7d545163, 0xa37383fc, 0x006167fa, 0xdc4fac8c,
-       0xffaa24ba, 0xa22beda4, 0xba9f93ea, 0x5e7faa2d, 0x7b544d70, 0x2baacefe,
-       0xa8617f92, 0xb11faa2e, 0xf20df4d7, 0x1fedbabf, 0xeff9e6a2, 0x34a2ff96,
-       0xcbaf2f3d, 0x438e997f, 0xc7fa1a5c, 0x4538e1a2, 0x93f215e9, 0xbe37f6ae,
-       0xa04bfca0, 0x53bce544, 0x1b780960, 0xd909edb1, 0x1b5f9127, 0xa136ac83,
-       0xc13268df, 0x8ff7f23a, 0x879c4c9a, 0x2abcec34, 0xaa8be04d, 0x9ff7e134,
-       0xf8a69b46, 0xeccff066, 0x78449ede, 0xa0993643, 0xe29ae29b, 0xc671bf65,
-       0x716be101, 0x7034793e, 0x7934ab5e, 0xa899b2f6, 0x329bf287, 0xd1e51fef,
-       0x7d71507e, 0x3f1fc78d, 0x8b9ff941, 0xfa4a9b0e, 0x03faa72a, 0x7d70b714,
-       0x2461e7a1, 0x3eaf795e, 0x49f6893c, 0x67957d46, 0xbfea66e3, 0x93858eea,
-       0xf43aff68, 0x498e8efc, 0x88721165, 0x388adf5c, 0x697be8f8, 0xc4673f22,
-       0x6aacdb87, 0x6bca0f63, 0x3ffc2c9a, 0xa5ef85c6, 0x903ffae1, 0x9c0b361e,
-       0xbad33015, 0xde724e31, 0xba8085df, 0xe194cb0e, 0x8d7ea478, 0x84c1f54a,
-       0x26f9dc68, 0x08fb4411, 0xffc72a5b, 0xbb7f0d5b, 0x36f98f2e, 0x3fee88e8,
-       0xc144f778, 0xd7236fcf, 0x2c67df90, 0xdd061d62, 0xfc3f75e7, 0x7b87eea9,
-       0xe446ffc9, 0x78edd79b, 0xf5f0893c, 0xa7815c99, 0xe8cfe78d, 0x4d267d72,
-       0x3bf5e9e0, 0x79919c13, 0x2b90eac7, 0x36db5eaa, 0x423679ca, 0xeb1bd70f,
-       0xad0a4bf0, 0x3f6e8363, 0xc93d9dd5, 0xf1e301b7, 0xdc70d3a7, 0xbf171d9a,
-       0x37de8fbd, 0x3888640d, 0x6ef9e01a, 0xd7180f79, 0x4415f2df, 0xd297d2e1,
-       0x25e57e44, 0x95cb0ba2, 0xdf513858, 0x776c6256, 0xfcc6f951, 0x7c3bb272,
-       0xbeb0961e, 0x84cc13ac, 0xb3fb96d3, 0x53f4c4cc, 0x2f677de0, 0x9a5f6d2e,
-       0x04dcf3ca, 0xc5c5333e, 0x9d5dbf77, 0xc686fd44, 0x4319c633, 0x2bd459b9,
-       0x419cc057, 0x246b9af9, 0x9f380dc6, 0xeefb9e8d, 0xe299b318, 0xbbdf31af,
-       0x0ef0bfe0, 0xf00ac5ea, 0xf8c6b8f2, 0x7e51a900, 0x90cb03f8, 0xbf24ed1c,
-       0x98532eba, 0x677539f2, 0xd1fe7cac, 0xebf030df, 0xdfce9007, 0x57b17d55,
-       0xbb7fba42, 0xfb57e07a, 0x4fadf9f0, 0xb5c5dfa1, 0x87fddb66, 0xc3ce22d3,
-       0x917ddcce, 0xc8f10ced, 0x33924ff3, 0x25eac97a, 0xeaa0f8fb, 0xbc489ca5,
-       0x616d227f, 0xb307bd27, 0x479ee2d3, 0xab2beec4, 0x6ed93f48, 0x8699c655,
-       0xeba7de5e, 0x930bdd65, 0xd25d79f9, 0xfd447ad0, 0x57f39979, 0xbcac0775,
-       0xd7477fbf, 0xbf17aa87, 0x9f991998, 0x54bd416b, 0x7274a873, 0x2a9ce749,
-       0xf1cf66f2, 0x6fd4a9c1, 0x21efeca3, 0xe978393d, 0xefaa64e3, 0x5e4bf379,
-       0x6574dc0f, 0xf323f7f4, 0x9b5cf922, 0xf92ef034, 0x567dea93, 0xa550f295,
-       0xdd8ef2fb, 0x4e9af58e, 0x9eb83bf4, 0x239eae0b, 0x6a7ed34f, 0x979404bf,
-       0xb02709aa, 0x9569af73, 0xaac79482, 0x65bddb6a, 0x9aabd60c, 0xba931797,
-       0x3f0b26d6, 0x0522d356, 0xa7f03c69, 0x748a7f31, 0x357d28db, 0xb00b1fef,
-       0x18a8efbd, 0x787d5cff, 0x4ff459ea, 0x9d9f2d7d, 0xb4363a23, 0x763f3959,
-       0x196c292e, 0xd85ef383, 0xea02852d, 0xb9f6ddb0, 0x5d6a3ec4, 0xcd0b31e8,
-       0xe5b9eebb, 0xfb0f04d9, 0x90b49df6, 0xfad75c7f, 0xbcfeb958, 0x20fb8458,
-       0x9dfac5db, 0xf322931d, 0xfc21f749, 0x81f8c883, 0xf70805f4, 0x09e39082,
-       0xdaab3e5d, 0xbb123627, 0x7dedafd0, 0xe6bf625a, 0x3bdf9374, 0xffdfebb8,
-       0xffdde695, 0xff98932f, 0x7fc657c5, 0x4f1805f0, 0xc0f3e8d4, 0xda1653f9,
-       0x9ab4d61f, 0x173bc5cf, 0x77dbbefa, 0xf0c67b95, 0x571636fe, 0x3880b16f,
-       0xc10099b7, 0x381e29e7, 0x91ab2c06, 0x07511f9e, 0x0e7147a4, 0xdd60d658,
-       0x71467646, 0xc608e3c2, 0xb9d717db, 0xf70f9e15, 0x9de31b08, 0xedead657,
-       0x858f6aa5, 0x9e3570f2, 0x75e90b5e, 0x7113f84d, 0x51f6df5e, 0xbf6716b9,
-       0x7e16ed5c, 0xc303d0d3, 0xa7d2ebde, 0x87985db0, 0xc6c860e2, 0x66b85f76,
-       0xdd53e280, 0xda0ed47e, 0x03fcb817, 0x6f607744, 0x2beb4a82, 0xccc9f7dd,
-       0xfe79889e, 0x5187dba4, 0xa3f979af, 0xe7e266a9, 0x2aa68f9e, 0xfbcfc349,
-       0xe2eb1c32, 0xddaa55e5, 0x4e6f4e22, 0xb68f9df6, 0x186f0483, 0xb769ade7,
-       0xda07f9f3, 0xe28e96c1, 0x75b83b48, 0xf3d20edd, 0x168bd976, 0xcb6d3501,
-       0x3fdc0dfd, 0x91e24bc9, 0x480616db, 0x8fa7650f, 0x8afe13f5, 0xcfd4cdf3,
-       0xae52267d, 0xe91b7fdb, 0x4f08e291, 0xd46bcc8a, 0xd17e7a98, 0xb75c9121,
-       0xaf9a266b, 0xc96fd808, 0xef0f5f0e, 0x54338a9f, 0x9e1ec7da, 0xa7c40e51,
-       0x38901e9f, 0xf54e6b5f, 0xf922cd6f, 0xbfb9951e, 0x010bf0e5, 0x9bee973a,
-       0x9f44c506, 0x4e9fdeb1, 0xe38c830b, 0x2f042e6c, 0xff79bb4d, 0xdfd21e2d,
-       0x611fa69f, 0x86f7617c, 0x234afc80, 0xe7ca06e2, 0x61420bd8, 0xd721271a,
-       0x3ce32c57, 0xf3276e79, 0x7bf562cb, 0x4d941f29, 0x4d875c75, 0xfa23adf1,
-       0xb144ee6c, 0x657b1e9f, 0xb23eba79, 0x1bce857f, 0xe92f9cfd, 0xed3d0b33,
-       0x5f180abb, 0x399d1df3, 0xbe09a4d4, 0x6b2e76c1, 0x46a63adb, 0xf044dbc6,
-       0xdf79e8db, 0x44bc5bfe, 0xd75139bf, 0xb6448cf7, 0xfff9d88b, 0xe499f499,
-       0x35b35a6e, 0x7c4cf88b, 0x7bf64753, 0xf067ef5a, 0x2e7f1403, 0xaa922bd9,
-       0x8d0fcbc5, 0x4e3c9777, 0xea9cdd72, 0xf01575cb, 0xc300acf1, 0x76b8c49e,
-       0x57fffd87, 0xe91fff64, 0xf8a2dcfc, 0x4ddfc46d, 0xf16cdd7a, 0x7fb64ea9,
-       0x0ff34a9f, 0xfc746fad, 0xf6e9b5f5, 0xff8265ba, 0x4fb7d71b, 0x15399f5f,
-       0x4bc68df5, 0x4e67ee06, 0xff48060e, 0x78a0929a, 0xec3e3e13, 0xdd90f72a,
-       0xc5f4396d, 0xa6f7b238, 0x2807af24, 0xd66075af, 0x2dfbb22a, 0xfd636fa3,
-       0xbc85f4ff, 0x9e623922, 0xad256913, 0x697ebfe4, 0xcfe2cbac, 0x42fc75a5,
-       0x5d6323d7, 0xabdf6ee9, 0x11bc88ee, 0x915f758c, 0x9fbe80fe, 0x17f1eaf3,
-       0xff9c73f7, 0x2f4487eb, 0xd6ee279d, 0x3e02b771, 0x783b1bd6, 0x1a55c655,
-       0x1f7ba31c, 0xd8261d8d, 0xe4a6cb46, 0x5d39c454, 0x36326cb2, 0xb70d9a7d,
-       0x4c6c74e6, 0xebba6fed, 0xbd213496, 0x0b2021fb, 0xaf9d167c, 0xa4d24d00,
-       0x6bc53cc8, 0x14f3f155, 0xc91bf8cf, 0x9e56ff2e, 0xb4d84e62, 0xf7f292da,
-       0xbace2be7, 0x9f3df7a3, 0x2a2655ba, 0x31f42b94, 0x8a0c4e14, 0xa74c17bc,
-       0xf133537d, 0x067bff12, 0x2df6cad7, 0x5cdae5f5, 0xfbee4f68, 0x8b1d6db7,
-       0xd62d9776, 0xfa46f54f, 0x3dc0a77b, 0xd78ff943, 0x46ee30a6, 0xfef3273f,
-       0x12d3a9df, 0xc462b723, 0x88f7c06b, 0x27f2a352, 0x265f23e1, 0x4aed7e93,
-       0xb922df55, 0x7cc9740c, 0xe941244f, 0xd8e2b8b1, 0x03c23ed9, 0xd38bf7e8,
-       0xd6c43ec5, 0x6d17ce26, 0x317ec6aa, 0x269ce9c1, 0x79c5d847, 0x579fc8b7,
-       0x9c60f91f, 0x05dc3105, 0x02e4f1d3, 0xdec37f1c, 0xc34a6496, 0xf6f33fad,
-       0x5392ba4c, 0xe91df8a2, 0xa54ffeb8, 0xc236391d, 0x53835ba9, 0xf0a13f89,
-       0x93f21484, 0x94040a85, 0xf1f138a2, 0x14de22a9, 0x87c53cd7, 0x3ed850ff,
-       0xe5e12d7d, 0x2f58b0da, 0xa6c661cd, 0x7ae036bc, 0x2a635b5f, 0x6ffb578d,
-       0xbf934607, 0xe05d297a, 0x4d2f179a, 0xa02bef11, 0x74acff50, 0x41e7ae97,
-       0x5f0be513, 0x7d8cf3d2, 0xcfdc4c97, 0x6db0bf98, 0x3d44eca1, 0x3f6f0828,
-       0x76cd79c4, 0x4df24aab, 0x3f040e78, 0x771813da, 0x0c5c1ed6, 0x5dfae714,
-       0x7db095e0, 0x6fc0e257, 0x0e061f49, 0x773a5558, 0x876e704d, 0x977f1c54,
-       0x0f2b4f7e, 0x31c5b215, 0x2f98dcfc, 0x94e7fda1, 0xe0bd2413, 0x6504dff3,
-       0x88e35c3b, 0xd31277e4, 0xd5eba25d, 0x89b0c4ae, 0x260645ce, 0xe9875ee1,
-       0x7813a61a, 0x3cce835e, 0x2cbbfbf6, 0xe07ee703, 0xa49cba66, 0xe8207907,
-       0x2ac9f684, 0xa704d1f9, 0x7048ebc6, 0x3480deaa, 0xa9daae92, 0x6ed0fc08,
-       0x35e7251e, 0x6baed877, 0x36eb8713, 0x135d85b4, 0xff8f3f40, 0x8f3a36d5,
-       0x8393aa1f, 0xfefc3d99, 0x6c2fe92d, 0xf9cb1a6b, 0xa28c80bd, 0x949963b6,
-       0x7954eb4a, 0xb545e87d, 0x07c122f4, 0xb767afba, 0xfea1f689, 0xaa0ee7a8,
-       0xaf3f443b, 0x925f69d5, 0x8742f6c5, 0xf07843d7, 0xee7c297e, 0xded7b45a,
-       0x05297cc7, 0xd35eaeb8, 0xb19a07a1, 0x87569fdf, 0xe93ee872, 0x1aff5673,
-       0x3e57cfd2, 0x2148f35c, 0x665ddbf9, 0x9df9256f, 0x18cfc09e, 0x5668bf87,
-       0x1dd845b7, 0xe0c81d8c, 0xf33180fb, 0xf4d99ed4, 0xfdd7c233, 0xce9525fb,
-       0x03cdfbbd, 0x9aee88e3, 0xe85a3ff6, 0xfeed64be, 0x4b4f188f, 0x9a1afe19,
-       0x035b766f, 0x039b6bdf, 0x1b5ef9db, 0x9fbe43fa, 0x7f08f218, 0xe73a7832,
-       0x390886d9, 0xec2e913c, 0xe3fc060d, 0xebb55e29, 0xf6907af6, 0xedee58dd,
-       0x8d2275b8, 0x07cf57bf, 0xc035ef18, 0xf7c431a1, 0x971af04d, 0xa0fef3c6,
-       0x967a4152, 0x4eedaeff, 0xa3ffa22d, 0x3dbf02e9, 0x66702e9a, 0x89bf8676,
-       0xf1df5de8, 0xd69925b1, 0x8e343679, 0x4521b9f6, 0xf1c6714d, 0x1bf64323,
-       0xcab54f63, 0xd7fa8580, 0x2bf6079e, 0x14a6ef28, 0xef4bdf94, 0x8d594db6,
-       0x4ca2f7cf, 0xe2ae2852, 0xefe294fe, 0x0c6fb35e, 0xe7786ff5, 0xc7e4a9f3,
-       0xe74f481e, 0x607e7ff5, 0x1be278fd, 0x22497fea, 0x606ed9d9, 0x69d866bf,
-       0xbe29d901, 0x5ffa405f, 0xf63cf54c, 0xdd2cbbcb, 0xf72ed84b, 0x12ec809a,
-       0x01ed9ff5, 0xf849dff5, 0xf689c0ae, 0x664fefc0, 0x6dd5df3b, 0xa32718d2,
-       0xf5c49f5f, 0xbea91b92, 0xc9ccbbab, 0x05f74e76, 0xc35ec88a, 0x109c7887,
-       0x9d1224c0, 0xfca8be04, 0xe9993b88, 0xe7e5fc36, 0x86e3d06e, 0x75c5e29a,
-       0xca3965d8, 0xa4e2223e, 0xf4711ba8, 0x9edb33c9, 0xee817b40, 0x0fdc28d4,
-       0xffbf0bef, 0xd5563d5d, 0x59773ebd, 0xeeb3ae33, 0x07edcc84, 0x585e7df5,
-       0x7a4393d7, 0x86e2867e, 0xefdc5d3a, 0xb033e7a5, 0x675df74e, 0x094b1b6a,
-       0xd8aecd63, 0xb9ca987e, 0x412950be, 0xbaabf9c8, 0x99859b0f, 0xb5fe93e7,
-       0x9f2eba1e, 0x9ff5cdee, 0x920242b1, 0xc0e5fad8, 0xb5c45f6f, 0xf910703d,
-       0xe14e271f, 0x10ff5872, 0xcf018d6f, 0xc97ef6c8, 0x4bbd23f0, 0x5afb1f48,
-       0x123ae1e5, 0x4d8a8352, 0x3fd277f5, 0xbac016dd, 0x9f7b433f, 0x99c7e254,
-       0x3f49f7fe, 0x997e4ffb, 0xf7b96641, 0xb7c7d8b4, 0xd27cb45a, 0xb809d69f,
-       0xa7a38db5, 0x3c8ba5af, 0xe215b14f, 0xa57e4b9e, 0x009cc1c7, 0xfef1223c,
-       0x5106765c, 0x655a17ee, 0xe7f882cd, 0xce56043c, 0xe7a37f23, 0xfd01ef6f,
-       0x941fe1a7, 0xf57abdcf, 0x182bc21e, 0x627deeb7, 0x89bfb9c4, 0xbb6d69f4,
-       0x6b84ff04, 0xfc4cf75f, 0x5e46097b, 0x1db6beeb, 0x3ca0c647, 0xee8b9eab,
-       0x9ee861b7, 0xbdf7887b, 0xefa39a1b, 0xae957c1b, 0x308996e3, 0xea0b7091,
-       0xb307fb13, 0xd4569d02, 0xfd3257df, 0x7e5e109f, 0x84f824c9, 0xf2ed957e,
-       0x671eb713, 0x1a3f844a, 0x8f7c00b8, 0xe8676f28, 0x99d7dd30, 0xa5e59cdb,
-       0xa22ae639, 0x165b6e7d, 0x825019c7, 0x9837dd32, 0x19cbf9ad, 0xd3b4075f,
-       0x9d642f74, 0x89c127ee, 0xa3bf287f, 0x8e9d6baf, 0x460beee7, 0x82073dd3,
-       0xdacf348d, 0xd1fee29d, 0xbff19dfa, 0xc7d5a813, 0xc9d4f0d9, 0xac0e9423,
-       0xabf7450e, 0xdb53f9d5, 0x05bcfd16, 0x9f181278, 0xfccf7d11, 0xfc43ef4a,
-       0xc5f02cc9, 0x4638fadb, 0xc219b5fb, 0x7920d67f, 0x410ddf24, 0xb37a4839,
-       0x0b240a4e, 0xd58e0b7c, 0x865df748, 0x65f7e8be, 0x73f9d6ef, 0xbc2fae97,
-       0xfabf7c2e, 0xe7482919, 0x24ff7780, 0x427bfe9a, 0x1f49cbab, 0x5d6af562,
-       0x6df199b3, 0x10b46c15, 0xabd58dbe, 0xd97d21aa, 0x1638a16e, 0x7e354fab,
-       0x0b7432e9, 0x4b7ffe5c, 0x98737af7, 0xffeb4cf3, 0x3ca5e4a7, 0xdfadbdd4,
-       0x745e50b1, 0xf9087da4, 0xa27a1956, 0x5defebaf, 0x7c86edcf, 0x9614c0a7,
-       0x15da456f, 0xf1a283ee, 0x50cb6ef4, 0x7cf3929e, 0x38139d83, 0x51e86e3f,
-       0x3ae538ec, 0x14fc5f2e, 0xada17970, 0xa2f84ed4, 0x2bc9b8ff, 0x4c7f9ca9,
-       0x4c3e442e, 0xe103203f, 0x89f6fe8d, 0xfe90078f, 0x37c513a2, 0xfa7cbe52,
-       0xd83f8c09, 0xf8b3a7be, 0x115fe457, 0x7d91a4e1, 0x4ecaec2f, 0xc783bdfb,
-       0x7fddf8e1, 0x4af1e8bc, 0xcbc7c3f2, 0x095c698a, 0x787ee9db, 0x1a871e91,
-       0x7bd9178e, 0xfdd1e222, 0xbedf2219, 0x47fbf3c5, 0x78b05f69, 0xf94bd9b7,
-       0xff66c58e, 0xafa404a6, 0xdbc905e8, 0xe91db380, 0x8d24f43e, 0x52a4f68b,
-       0xeef166be, 0xf6a21def, 0xd3125dda, 0x28bedfdf, 0xc7c5177f, 0xb8a5eca0,
-       0x577edfd7, 0x7384bdc1, 0x7053dc0e, 0x477cc457, 0x595f8552, 0xe399957c,
-       0xfb68ef71, 0xcf292b2f, 0xff60eda9, 0x1eeafbd0, 0xb0577f0b, 0xae0f024b,
-       0xf0e788f3, 0xbd0f89af, 0x085a4efb, 0x9eb697e4, 0xf1c4f4b4, 0x017946cf,
-       0xce6171b7, 0xf0b76ebf, 0x7fbdca3d, 0x6b7ad0b0, 0xf388fb9e, 0x126d5569,
-       0x67aaa7fb, 0x794aa0e4, 0x58af039e, 0x9a6b3f48, 0x8accc825, 0x3b73376c,
-       0xffaa51f9, 0x65f859b1, 0xe8d7ef43, 0xbde86e7a, 0x746b0761, 0xd6d775ff,
-       0x17bf3d68, 0xf1a32db4, 0x579a7bfd, 0x7ba03df3, 0x5ff7c7b6, 0x4b5c1f86,
-       0x2b8c52fb, 0xee8a9f6b, 0x7e90df77, 0xc7bfd807, 0x3257c9fa, 0x3cd8f3f4,
-       0x1efd23c8, 0xaf19af0c, 0x7e7d3da0, 0xc43c6ab2, 0xd71e3bc9, 0x8f1180f1,
-       0x8e26c307, 0xfafdb167, 0x285a2eda, 0xfe76d68e, 0x796bf199, 0x872c67fb,
-       0xbe0ef6ca, 0xf83d7aaf, 0xaf1f1037, 0x093bb76f, 0x08f65747, 0x6ed25fbb,
-       0x6a25060d, 0x7c91350f, 0xef8a0ffb, 0x4aaf023b, 0xf740a38c, 0x7e756b7f,
-       0xb7f9d5ae, 0x6367f716, 0xbe8adee8, 0x772fbeff, 0xe2ba11c7, 0xdf3fa351,
-       0x993875d0, 0x8404b8f8, 0x12125a7f, 0x8790c9fe, 0xc6465f11, 0x936f81d1,
-       0x5bb7d73c, 0x52f8bef9, 0x6d2d3fdd, 0xc593df16, 0x51fe8bfa, 0xddff9176,
-       0x8d8de82b, 0xd1ad35a7, 0xd232bbfd, 0xea0fdfd9, 0xc313f878, 0xa8f2e8df,
-       0xe53b001c, 0xb2a897e7, 0x756fc837, 0xe77f342b, 0x63cf8954, 0x2989d53b,
-       0x194beef1, 0xce3a9be5, 0x28cbea37, 0x43fd864f, 0xc88eedce, 0x998dfc7d,
-       0xcd54af02, 0xcf240391, 0xb2cf7d88, 0xfbb8aca2, 0xba44c81e, 0xd77b18df,
-       0xee45a64f, 0x391db47b, 0xf23f67a4, 0xf7495e3c, 0x859b6a8c, 0x8d9be87f,
-       0x8e10a6e3, 0xb5c5c607, 0xed20d6cd, 0x4f516a4f, 0xd2307bf8, 0x76bfb20f,
-       0x07e91169, 0x991c1bee, 0x3a72cf48, 0x2ff5c4aa, 0x8e38c36f, 0xfb2f2fc3,
-       0x2baaf58c, 0xf91bac5b, 0x1f6f1996, 0x6a1fec61, 0x6a9c092e, 0x7a51af3c,
-       0xd3511f78, 0xb749ee2e, 0x5c62fa1e, 0x7fdbd216, 0xadc63fe0, 0xa64172c6,
-       0x25adbf88, 0xbee98fa1, 0x6cbbe7cf, 0x90e8f171, 0xd89a97bf, 0x3dcc6a0e,
-       0xf6578c19, 0x859c2e23, 0x4fedf37e, 0x7ad1df79, 0xca4ee128, 0xf1adf5c7,
-       0x837e778f, 0x13601a9c, 0xd04ddae3, 0x9ee125c4, 0xd6b81c48, 0xdd0fee29,
-       0xaa49c7ab, 0x7d7a8c3f, 0x505df62f, 0x03eecf14, 0x2349e65b, 0x1bf0dded,
-       0xafbebad5, 0x85b1d82f, 0xf163e08e, 0x476eb551, 0x2e39fc88, 0x1ba2e2c6,
-       0xb4f5a333, 0xc644ede1, 0xb25dfdb9, 0xc8c47293, 0x268c5fd7, 0x7ef887dc,
-       0xeb3c9c42, 0xf65ebaa7, 0x0dbee7ea, 0x9be665b3, 0x0d288e69, 0x63fc851c,
-       0xe93fe97d, 0xcb1c5208, 0x04caf83f, 0x9dfaff92, 0x2445e7d1, 0xdfdf3f3f,
-       0xaafcb20a, 0x433e7643, 0x3a5fda32, 0xd214caf8, 0xbfb786b3, 0xf97211cc,
-       0xbee2c722, 0x29467d3c, 0x6bff6249, 0x77fec492, 0x4c93d2af, 0xfddaaefb,
-       0xfef22fb2, 0xbbe721bc, 0x4501fd75, 0x65d7f3ec, 0x686f5caa, 0x3a617a17,
-       0x7f9c4a20, 0x98f3c8a5, 0xed11fe79, 0xdf2fa825, 0xe880b710, 0x9ad7d942,
-       0x6aef5807, 0x9e989a4f, 0x198393da, 0x05ef11d9, 0xf24cdc68, 0x801b0d7b,
-       0xc81d88fd, 0xefa52ebf, 0xf4beb10f, 0x59c604fd, 0x523c2647, 0x64adce29,
-       0xc0f5bf20, 0x239355db, 0x3d05fffd, 0xc1f103ee, 0x09e72843, 0x87cebf31,
-       0xcf42b04d, 0xae3d0813, 0xee2c71d2, 0x8ec89aaf, 0x5757f763, 0x0e1b938a,
-       0xc7f28158, 0xf9581fb5, 0x07e7d03e, 0x1dfef2d6, 0x9327f92e, 0xffbf019f,
-       0x381f2a6a, 0x3d3276b8, 0x7de0fcff, 0x53de7357, 0xaf9514da, 0x1e7d1008,
-       0x797f51c2, 0x97c276f7, 0x90e30a5d, 0xefd3aea2, 0x9eeaf9d2, 0x9b7f3356,
-       0xc677bd59, 0xc22481e3, 0xe94b454f, 0x9d3d9dbb, 0xe21feb0a, 0xd947032a,
-       0x289d4719, 0xe3851c66, 0x165c82f8, 0x71a4ab1f, 0x5314944f, 0xc9db0937,
-       0x1c274d9f, 0x55c618e5, 0x9cff3d06, 0xdfd9f829, 0x13f9c091, 0x3d082609,
-       0xba28ec83, 0xcebeb437, 0x9b436438, 0x86bdf51c, 0x4ceedef1, 0xd7b0ae71,
-       0xa490b3d0, 0x16ed1eb1, 0x3db686e5, 0xf58eb419, 0x49eb10e6, 0xb459b343,
-       0xd02512ef, 0xfe0ccdf9, 0xfc4038d8, 0x508f4639, 0xc12c4b2e, 0x77db84b1,
-       0xea079d0f, 0xe28239f7, 0xe7635d5e, 0x686efe44, 0x3b8f73b0, 0x4e39fc5e,
-       0xda4833e7, 0xcfb12cd1, 0xf3af6d89, 0xd1c67c88, 0x1e2fc233, 0x1c9fe85d,
-       0xa0063fcf, 0x25fbec44, 0xe6ad7e5d, 0x86e7788a, 0xdf223d1b, 0xe06c73b4,
-       0xef71e928, 0x373e04ee, 0xfc8975ec, 0x974b696c, 0xac9fdf42, 0x5066956f,
-       0xfb9f5a3c, 0x829f7f1e, 0x83f662f5, 0x6e7cfde1, 0xbbbcdd5a, 0xc7438b5c,
-       0x1f111eb5, 0x01dfe897, 0xbd57d08f, 0xd37814fd, 0x23da7df5, 0xaa735e74,
-       0xdf14ecd2, 0x4aef8999, 0xf9fdd06f, 0x199bd78d, 0xd5029d37, 0xc43fce2c,
-       0xdd32c539, 0xfba0df2f, 0x3bdf11f9, 0xe99b033f, 0x7bf6229c, 0xdfafc367,
-       0x02bf8fac, 0xf6371e34, 0x759bf5bb, 0x2fb3783c, 0x4ca5f9fa, 0x40e6071d,
-       0x10f3f90e, 0x1fbe17c6, 0x71c09791, 0xa4e1697a, 0xbe8338b8, 0xeff55703,
-       0xe434a9c0, 0x1ef790de, 0x1da3bfc7, 0xdfcd7e67, 0x80499c13, 0xc5ce7109,
-       0xe19fe386, 0xf2126e3f, 0xaa2dcfd6, 0x4346829d, 0x077017ee, 0x331f9916,
-       0xe7463ee4, 0x3df1ffff, 0x22505ca0, 0xcacf25f3, 0x3a1e31fe, 0x32f5b09f,
-       0x7015c6fe, 0x8d75c41c, 0xce35d7d3, 0x2edf111a, 0x571d5a8c, 0x97d7877f,
-       0xc471101a, 0x9e4765cd, 0x75627195, 0xfbefe248, 0x5f62c3aa, 0xf6265d5b,
-       0x02ad39b5, 0x49bcaea7, 0xbb126a0a, 0x9f44d3c3, 0x6ccb3fa1, 0x7a180f02,
-       0x5d2fc432, 0xf09da87f, 0x3e3a0dc1, 0xc9a3d588, 0xf94e5dd0, 0xc9345be6,
-       0x472af74b, 0x6abf3f7c, 0xeee4ebda, 0xa83fa72f, 0x22effc6f, 0xf7d1eac4,
-       0x0f12fe3d, 0x07bad3e5, 0xb8e21657, 0x38fef347, 0xe6a6f48e, 0x2df37632,
-       0x3b13888f, 0x7ca3811d, 0x3f45a4df, 0x6bc96fef, 0x747e21eb, 0x5ec7e302,
-       0x3a96f757, 0xbcf9ab81, 0xc09c3abf, 0xb75643df, 0xb0bbf9db, 0xc486d6ea,
-       0xdb7fe429, 0xeb1daf65, 0xcb27ad95, 0xc5959f88, 0xad4a3ee2, 0xb38bdc5d,
-       0x10b7fdb9, 0x3b7bd77d, 0x2df9cfa2, 0xfba8bf3d, 0xf58f3d06, 0xa3091b6b,
-       0xf9f7ffa5, 0x5f3a8d9b, 0x662ebaea, 0xfea9c14c, 0x26afe690, 0xfd7fec7d,
-       0xd71d0b45, 0xa5794ed5, 0x6d88ae9c, 0xefdca8f4, 0x268ee6fa, 0xf41af34a,
-       0xf93a6477, 0x707351f9, 0x82d2e32c, 0xd30fbb2b, 0xa98dffb0, 0x3afaa714,
-       0x225aa6ba, 0x0eb7bbf4, 0xf91c73fd, 0xb7498035, 0x494b855b, 0x25e3a15a,
-       0x07b5c761, 0x3e50670e, 0xb7ec97a2, 0x9277ca80, 0xdeacb1b3, 0x12792a7d,
-       0xa2bd96e1, 0xed19c21c, 0xa503f732, 0xa4e6e727, 0x3336fa48, 0x6242177d,
-       0x9c9e801c, 0xdb230b1b, 0xdb5fff1b, 0x27a4d3ff, 0x289eb6d5, 0x84f837fb,
-       0x3efe7cbb, 0xcad07037, 0xbce808f7, 0xc72115c6, 0x347f7457, 0x644b370b,
-       0x7ce873a7, 0x3b41227a, 0xbaa0ee05, 0x95256102, 0xb2c38bce, 0x96377fb8,
-       0x7d4cf7fd, 0xb84a59fe, 0xcee9ee83, 0xe737cfd1, 0x5bf73742, 0x6a5c0300,
-       0x8befe4e0, 0xe5cbc04b, 0x29785b6c, 0x5082f1c1, 0x099fbf88, 0x73ae2867,
-       0xe63bfd36, 0xe61ef238, 0x0ce7029b, 0x0e74c87e, 0xc51bee26, 0xd75ba7ae,
-       0xf09a59c7, 0xe81d043b, 0x086cee7e, 0x35fbb9f1, 0xbf9fa3d0, 0x3cc75fc7,
-       0xb9d1f7dc, 0x3b6835db, 0x208fcc89, 0xeb4f9ff7, 0xa7ade391, 0x198b2967,
-       0x9f449cca, 0x7d30ce14, 0x75f2bf6d, 0x4d6dd3f4, 0x35df57ca, 0xe283f7d0,
-       0x6f4b73e1, 0xd3ef1bfb, 0xd349627d, 0x97b1bef8, 0x7da6c7be, 0x1de9584e,
-       0x001363f2, 0xe6b3ddfe, 0xc66f6437, 0x07e01af7, 0xfb11e7be, 0xf72d06bd,
-       0x3df0c67c, 0xedfee335, 0x950ae0ce, 0x72ac6fee, 0xaddff8db, 0x9b8db229,
-       0x87ca794e, 0x21bffcd2, 0x6a40fabd, 0x2883c49e, 0x638c19c1, 0x83b2bd75,
-       0x2fd69b36, 0x22f7c669, 0xf432fac0, 0x006401ef, 0xb763b77f, 0x1e69ef8a,
-       0xa5b43d41, 0x74abf6b2, 0x2e1e1a0f, 0x6f2f0955, 0xf4bcd971, 0xe895ae5d,
-       0xdbd30fb5, 0x2ff71368, 0xb16bfb8c, 0x19b46c7c, 0x8daf4a79, 0x77cc7671,
-       0xfcda773e, 0xbfe89bff, 0x9324a93f, 0xcbfe6070, 0x3f7c3df3, 0x7758c129,
-       0xc3eb8d89, 0x37191af7, 0x6a7dd136, 0x1d31aba4, 0xe1e21ef8, 0xba149ca4,
-       0x25d8d51f, 0xa63753ee, 0x9b7fd807, 0xf3fb12fd, 0x4ed2cec6, 0x0e83078a,
-       0x6eabdf0b, 0xaa34f974, 0x4421d207, 0x3ef89ffe, 0x69bbe0df, 0xfd21ef98,
-       0xed91505e, 0xde5157d7, 0x4a1b9a7f, 0x6169bde9, 0xc0f1126d, 0xe5061ef8,
-       0x4e9519e0, 0x7befa3cf, 0xfbe4e281, 0x501c8617, 0x9d995831, 0xb90d7cba,
-       0xf8ef8d38, 0x3bea2535, 0x8f5e437e, 0x98b90a24, 0x44cc26e9, 0x71a5577e,
-       0xf061e563, 0x8f00bffd, 0x30b1ae40, 0x0030b1ae
-};
-
-static const u32 xsem_int_table_data_e1[] = {
-       0x00088b1f, 0x00000000, 0x243bff00, 0xa3f0c0c3, 0x4aef811e, 0xf1303031,
-       0x12d18aa2, 0x6064e3ef, 0x6062e010, 0xfbe20530, 0x330c0c3c, 0x204cf480,
-       0x6066e516, 0x1ae20310, 0xc40dde20, 0x19f8807b, 0x1039fc50, 0x1be200ef,
-       0xbefd103c, 0xfe0c0c4c, 0xc4081c40, 0x95fc40c1, 0x1be18181, 0x73f6f103,
-       0x4c30330a, 0x2ff04715, 0x249fd903, 0xc1ffe7e9, 0xe90c4386, 0xa071df6b,
-       0x10acf37d, 0x7b20467c, 0x9aaa15be, 0xcdf85605, 0xbf268858, 0x18bf8d08,
-       0x0372fe8f, 0x4d5afe54, 0x81b5b334, 0xcd4909e9, 0x6efc4d3a, 0x40aac741,
-       0x3101a9ff, 0x5ff1ad00, 0x000368ca, 0x00000000
-};
-
-static const u32 xsem_pram_data_e1[] = {
-       0x00088b1f, 0x00000000, 0x7de5ff00, 0xd5947809, 0xe77df0d5, 0x9926665d,
-       0x6c81bc99, 0x44d84eac, 0x4242740b, 0x61db101a, 0x8311688b, 0x9817054b,
-       0x264f6408, 0xdac7f520, 0x0040cfef, 0x8b435151, 0x03b45a35, 0x341b0504,
-       0x024180d8, 0x2d82e00e, 0x5d6ad8d5, 0xc8a0d2da, 0x1b80931a, 0xcefc5dfe,
-       0xc9bef739, 0x82264efb, 0xf5ffffb5, 0xf8f8fefb, 0xf77bee5c, 0xce73ddb3,
-       0xe28ef73d, 0x8b94c718, 0xff12fb18, 0xdd98c7be, 0xd71b18c6, 0x2356329d,
-       0xcf2d4ad2, 0x03d058cd, 0xac62ccff, 0x9785addc, 0x653633a7, 0x5ef91a87,
-       0x4837e412, 0x6de43b61, 0xde549d7b, 0x23e79ebe, 0xa0cfcd6e, 0xc83aa3fc,
-       0xdeded04b, 0x5065c0f2, 0x6643b9de, 0x91dbb11b, 0xc2963671, 0xe30731d8,
-       0xcf90597f, 0xc9c0ac66, 0xf61be5b3, 0x45f6c5cd, 0x84e6764d, 0x1577cafe,
-       0xf20cbcce, 0x86550785, 0x2f37ca55, 0xbe43fad3, 0x60352c38, 0x9f3263be,
-       0x1ca7685f, 0x3bf50cde, 0x37292d3c, 0x553b18b8, 0x8d5e60e5, 0x4b776ab1,
-       0x18a3f5ca, 0xcf6f092b, 0xf52576c5, 0x3a970f92, 0x97e6c765, 0xb6bae1fb,
-       0x97bb3e4a, 0xf12dd2b1, 0xcf923bcc, 0xfff84be1, 0xf91ca358, 0x862f941e,
-       0xb7e83275, 0x32e4d590, 0xab5fc719, 0xf0dddd79, 0xd3a5553b, 0x7cbe4638,
-       0xed038c2b, 0x7c969e2a, 0x1b0ac4b8, 0xf8c0340b, 0xb39cbbed, 0x7d70b937,
-       0x6e11b4cb, 0x1addd75c, 0xe70c2bd6, 0x717a74ef, 0x5cb41b7e, 0xbf592f28,
-       0xd5182b41, 0x96e95fdd, 0xd579d6be, 0x980d4d0e, 0x53d3a3ca, 0x47798c55,
-       0x184be774, 0xbf4037f3, 0xb36b094c, 0xff7f7746, 0x96322580, 0xcccbfd8c,
-       0x1feee8eb, 0x43df4920, 0x013fc16f, 0x6e3da15e, 0xb781ab82, 0xdbfc3ac5,
-       0xb3b78ddb, 0xd2a3c0ba, 0xdfee6d99, 0x3c401f48, 0x106a7cc0, 0x11ae904e,
-       0x644cf3f3, 0xdfe81493, 0xc4ba67e3, 0x918f5f7a, 0x9f2ca8d6, 0x420b58c1,
-       0x78cafda3, 0x116c6bc8, 0x93f631f3, 0xa9fed915, 0x059fbf90, 0x57bce2e6,
-       0xc4228148, 0x690d6313, 0x24abbf48, 0xffd71b36, 0x94349c03, 0xf407eaaf,
-       0x99af7009, 0x9649bd96, 0x3093dcc4, 0xbdc4f05f, 0x214fd4e9, 0x3f42a3f5,
-       0x8fdfcf43, 0xe9639b9e, 0x322dcf47, 0x7ea4a9fa, 0x4fd6179c, 0xeb04ee4d,
-       0x8c4b727c, 0x7ea4ee7e, 0x2eb617dc, 0xd6898afd, 0x46515cf9, 0xf54e24fd,
-       0x97d400b1, 0x2d607a0d, 0x5dca197e, 0xef6389f5, 0x98ba6665, 0xdff912bc,
-       0xa6625c0d, 0x389c848b, 0xfa261d0b, 0xd0f258fb, 0x5bec7e93, 0x44830f22,
-       0x5f1a3512, 0x5c91afeb, 0x41dfd498, 0xbbfa3bf9, 0x31dc2e48, 0x0eb17021,
-       0x59b1c0f3, 0x816bc83f, 0xe831eb6f, 0xb129e61a, 0x36bd4c34, 0xefcba34c,
-       0x261c3956, 0x88dbf80f, 0x683ed023, 0x08911ceb, 0xa4d2f5f9, 0x365c205f,
-       0x27c11b33, 0x5895664e, 0x48cece2f, 0x9e9ddd3e, 0x826429bd, 0x8041ead3,
-       0xdfbba97f, 0x0d206ad5, 0xbb2b6be9, 0xb6f48421, 0xa7ac106a, 0x854f633f,
-       0x14848fae, 0x20a83f68, 0xd769e10d, 0xe3cdbf80, 0x28fe306b, 0x1c19ff1a,
-       0x3f8e0777, 0xf6f8e7ae, 0xf1963921, 0x2c8b831d, 0x18343be3, 0x177de81f,
-       0x0f8c55bb, 0xd8c09bf0, 0x685ba1f3, 0x22e0fb7c, 0x8d6eff1a, 0x8fc65915,
-       0x05ff1aeb, 0xdea5f71c, 0x82643fd6, 0x4b83fd75, 0xf8d7ebac, 0x0b655ffa,
-       0xb471f8c5, 0x16875ffe, 0x2e0ff5f0, 0xf3b7ebe1, 0xf7c6bb7e, 0x75ffc174,
-       0xdeadf71c, 0xa2743fd6, 0x9517fd75, 0xe76fd759, 0xcacbbfe3, 0x1a2ef8c5,
-       0x1950bdff, 0x6545ff5f, 0x0f66be34, 0xb48e90f8, 0x61957101, 0x040d9f18,
-       0x19254886, 0x6474a7e5, 0xfda0c61f, 0xe084363a, 0xa71c4770, 0x80e2cfbb,
-       0xf2dd5cde, 0xa381858e, 0x08559e40, 0x9fad2f9a, 0xa59ca1a4, 0x0b7b9072,
-       0x341754c5, 0xb0dfb4c9, 0x70f0f675, 0x937b6f98, 0x82fcc21c, 0x65879775,
-       0xbcd8efda, 0xb0a76c3c, 0xf0ff7e08, 0xcd1bd1a1, 0x174e8aeb, 0x5ac7a8d6,
-       0xe7c47c2d, 0x46cc9a13, 0xa6fcc256, 0xeb8c1121, 0x39031fce, 0xbe7e40ca,
-       0xd314720f, 0x078c2ae3, 0x9c828fdf, 0x6f999a65, 0x3c7df196, 0x991cdec4,
-       0xff827282, 0xbc38531d, 0xc2912d8f, 0xd6cfff08, 0x3e50d22e, 0x0789ac2d,
-       0x23cf77a0, 0xb9d4f028, 0x28de1ecb, 0x08bd3c11, 0x15891b9f, 0xa033fb19,
-       0xb6801fb5, 0xa5afb6b0, 0xbc2c2ddd, 0xcfea0d32, 0x483f935f, 0x3cdff587,
-       0xc6563edb, 0x07f983fd, 0xd98f88d8, 0x630e5b00, 0xaad71bb3, 0xe3732003,
-       0x56fdf56c, 0x0139fb53, 0x22e6fe6b, 0x0d5dbe6b, 0x37d436ab, 0x01b6258a,
-       0xd2b5bdfa, 0x938c6e5a, 0x78e1f528, 0x20fde315, 0x56f7cf85, 0x67e2c74c,
-       0x573af09d, 0xf98d6de7, 0x5952ef04, 0xd6cbf684, 0x4ff84664, 0x9d017aa6,
-       0xbe7a3baf, 0x3f875573, 0xf733e60f, 0x19e0994e, 0xbdd6ff3d, 0x18db7ef1,
-       0x563f6b48, 0xd7a30491, 0x79ff3d13, 0xa3d7a34b, 0x1f961e93, 0xe9cefe8a,
-       0x829e9a24, 0x1efa934d, 0x6f2bd535, 0x51efb2b8, 0x6e957d13, 0x17c96599,
-       0xea58e787, 0x5be6d617, 0x14d617ca, 0xafe7ca5b, 0xe7c9645e, 0xd4b4ee87,
-       0x9974b79f, 0xcad6fca5, 0x37e52c7b, 0xe4b5ad17, 0xb11e04e7, 0xf671bfd4,
-       0x6db94b06, 0x20d725ef, 0x25bf551f, 0x3e37dc33, 0x007b1d75, 0x5d4fc1f5,
-       0x71f10f8a, 0xf88d2aa2, 0x979554e0, 0x4ca6f6d2, 0xc1cb8047, 0x16715402,
-       0xad086b2e, 0x9972889e, 0x5e2cfc91, 0x1a1433b6, 0xe4adda08, 0xb5c9f825,
-       0x09008b1a, 0x174fac4b, 0xa6ca771d, 0x94f3d6f2, 0x67a302d7, 0x5b972cf6,
-       0x6e0f7f63, 0xe508bfcc, 0x00f26f4e, 0x3ee006fe, 0xf7f621d7, 0x8932f2e8,
-       0x33bf99e5, 0xfcf89cb6, 0x65b3909c, 0x6507971a, 0xcc9bf6cf, 0x8c8f983c,
-       0xf1aafca8, 0x28a8001a, 0x4f3b5127, 0x2e007a46, 0x50cbd0b0, 0xedb77f0b,
-       0x155e6993, 0xa3c61328, 0x235bc9c8, 0x1c899ca1, 0x68dd7c18, 0x7eff879c,
-       0x29aef909, 0xb6f5f699, 0x8f7de9aa, 0x3c9f882a, 0xcd544f4a, 0x5558f4a6,
-       0x55a3d280, 0x5fbe9445, 0x6b694955, 0x0f4a52d5, 0xfd288557, 0x4a6ad553,
-       0xa1aaabdf, 0x5aaa9df4, 0x1550ff4a, 0xcabdb4a6, 0x0fc1a94f, 0x4937f25d,
-       0xaec2abe8, 0xf2879d80, 0x565ac567, 0xe216dd40, 0xf21a5f73, 0x67d759f9,
-       0x3f1f5023, 0xa19d8efb, 0xbc1bdfbe, 0x77ade9a2, 0x5f49fa3c, 0xfe030829,
-       0x3b967b33, 0x9c9e38e3, 0x819d3636, 0xf867ba3c, 0x46dbbe13, 0x92415e51,
-       0x37c90d81, 0xdfa31dcb, 0x75f08c61, 0x7f313c3e, 0x016b98e7, 0xfd1ec71f,
-       0x7bf6366b, 0x717fec4e, 0x87da6407, 0x0f936459, 0x1b8265f1, 0x3b9d6bed,
-       0x0f3fbc84, 0x82ea3efc, 0x0660cb5f, 0x274904e9, 0x68db3bfa, 0xb1c20a67,
-       0xc40c3e39, 0xdc1ececf, 0x5c7e41e4, 0x8fd3669c, 0x918380c6, 0xeba43796,
-       0xd3fef32e, 0xad9fcd64, 0x9037a691, 0x5c26f63c, 0x4ae91a3f, 0x430e8fd7,
-       0x6a51a7fc, 0x4d38b3f4, 0xbf028fd3, 0x3432da9e, 0x61dfef81, 0x27d60fbe,
-       0x5d82bd12, 0xd5fff548, 0x1fade9f3, 0x358c3e63, 0x281c0fb2, 0xe86ca00f,
-       0x1e9dedf9, 0xd13e5778, 0xcd5f10f2, 0x2fa867ea, 0x5fffc1c4, 0x157ec10e,
-       0x06fd1bca, 0xfd90e41b, 0xdebdf8db, 0xf3b41e32, 0xb637361a, 0x156e9deb,
-       0x2ba0cc76, 0x1a1a5790, 0x3a2764cb, 0x92beeb75, 0x9b07c968, 0x7d96e9fa,
-       0xfc01ff06, 0x4152820f, 0x541329ba, 0x56b8a1d4, 0x23bf304b, 0x2f013f28,
-       0x2bd78941, 0x016ab477, 0x0b63912f, 0xe5b719ea, 0xbde77418, 0xef208ff1,
-       0x6546fe4f, 0xdff962f7, 0xae505660, 0xf720c51a, 0x2f9f906c, 0x9635b772,
-       0x77b940ce, 0xf9f7c6d2, 0x83cf2c05, 0xab114f46, 0xe73d46c9, 0x8e9b6623,
-       0xfb11fff4, 0x64d3279d, 0x1a6cf86f, 0x6afe73ad, 0xfa0b3eeb, 0x585f2599,
-       0xb017cd6b, 0xde90536b, 0x2ca9d60b, 0x5a5f212c, 0x9d36bdcb, 0x95642dfa,
-       0x41dec8ab, 0xbdc6057b, 0x00ca674d, 0x73f95f98, 0x43e7658f, 0xae363bfe,
-       0x7bf61ba7, 0xff3e1f71, 0xe6b0a492, 0x1a0ff287, 0x19707f33, 0x55e1f6c3,
-       0x6e42a728, 0x7accdbe6, 0xceebefe2, 0xc6be7a3f, 0x8fc3d27e, 0x6f21e620,
-       0x18e1fc91, 0x9b34da76, 0x10adf424, 0xbae037a5, 0xbe6b7a4d, 0x2f918380,
-       0x19dfca8f, 0xe9a7ff95, 0xe859892d, 0xc81488ed, 0xfa7325b7, 0x52417d42,
-       0x37c0b53a, 0x47ad3fe9, 0xd2ffe5ff, 0xff4207fe, 0xeffe96d9, 0x3ff697fc,
-       0x57fcc7ac, 0xfcbfeac6, 0x433b6db9, 0x9e4a6f20, 0x60c3c879, 0xd4a93a1f,
-       0xef00f8a4, 0x7a579b65, 0x284e0e90, 0xf3d20f21, 0x3d3cb0c9, 0x46ec3d16,
-       0xa23f207a, 0x5da125df, 0xfe84ff85, 0xdf753d4f, 0x3e67dc4c, 0x64eaacdb,
-       0x47b16d2f, 0x15afc0ec, 0xd833c58d, 0xe11fca18, 0xc8cfbbf9, 0xd2b26f98,
-       0x0f93c967, 0x0dffa0a5, 0x13d84528, 0x2a97d211, 0xc5cc3eea, 0x3ac8287d,
-       0xdba2cf89, 0xfae7f8e1, 0xd7cc7c90, 0xc3967a12, 0x0fcf493c, 0x1b04b80a,
-       0xa3233bef, 0x72b593ef, 0xfd54683f, 0xd4ffa122, 0xc749dcdb, 0xdf6274c0,
-       0x7941df61, 0x8583c069, 0xbd53feb9, 0x4731e1f5, 0x756d3e60, 0x2648f1bf,
-       0x767c1938, 0x2ffe61b6, 0x2ef6f79e, 0x9d85db8f, 0x4c2eddd7, 0x424dbced,
-       0x69e66b6f, 0xa0f11a99, 0x41b65c5e, 0x73e085f5, 0x4f4db6d9, 0xea768a3c,
-       0x70df76bb, 0xdb74bfe8, 0x00987f4b, 0x6aedd2f9, 0x0cbe0cd2, 0x8dd29497,
-       0xbffc2097, 0x1e376c74, 0x92f57e4a, 0xbfcd1de6, 0x374fb8ff, 0xefb74a3e,
-       0x9ee8d8d3, 0xb0d298f0, 0xc5756b4f, 0x91c34bc0, 0xaaafd45c, 0xa1ae7eb7,
-       0xaf72793d, 0x63d352c4, 0x4bc373c0, 0x9c2027a4, 0x4f028f08, 0xaa8b785d,
-       0xa0bc041f, 0x14f0373c, 0x9080fe5d, 0x779fd83f, 0xd3f3d114, 0xf95fa3cf,
-       0xd70fbb3d, 0xedf4f45f, 0x71c75c1e, 0xf5d392a5, 0xfc532b63, 0x1a916e30,
-       0xe529d14a, 0xff1e8bdf, 0xe15bd121, 0xe14c3f1b, 0x9fbfa0f6, 0x50a6f68d,
-       0xc2df5c3f, 0xfad037f5, 0xe880580a, 0x3931e8ae, 0xa7e90c2f, 0x3dbe9b0a,
-       0xc8645f06, 0x6f8e2f9c, 0xd60b8504, 0x12ed1c77, 0x4efeb3f4, 0x7f266f0e,
-       0xfc8622c8, 0x3fc343ff, 0xfe5316ce, 0x93c70753, 0xbe09b643, 0x4ccf6d02,
-       0xb77775af, 0x0d4e7e20, 0x1fa2a7f2, 0x9094c82d, 0x25f48780, 0x31bf2bf4,
-       0x87e3952d, 0xd16c9579, 0x2980f40e, 0xb7eb1df8, 0x18e77ea8, 0x65f63b4b,
-       0x4bf8f77a, 0xef30f8c4, 0x8fbfdc38, 0x86a2b0a7, 0x55bbeb18, 0xf61ef836,
-       0x997d1371, 0x7bf39bf8, 0xbf9c3ddd, 0xcf0f7e0d, 0x9fe58e9a, 0x07f9c9bc,
-       0x08fee1db, 0x52a48af3, 0x25ebbef9, 0x16760792, 0x75d7c589, 0x6b6be0aa,
-       0x302741b9, 0x304a456f, 0xdff60bd1, 0xfe4fe087, 0xd07582b3, 0x832f24ce,
-       0x67a79e38, 0x16df067f, 0x251ffe0a, 0xad9ff95b, 0xbbdf7ce7, 0x7da2157e,
-       0x3f0d4cae, 0x2bf228f1, 0x8bc867f0, 0xe1e6aafc, 0x1fd74fba, 0xc04dc3f8,
-       0x0c1ba7a7, 0xcfcab53e, 0x7a2d3e68, 0xf484b376, 0xa7a7cd19, 0x891b408b,
-       0x3df0a7c5, 0xb5169f26, 0x9f953ffe, 0x8faefc06, 0x0f219f82, 0xb463837b,
-       0xf3633c3c, 0xe5a33c12, 0xc9bdfc21, 0x9fd27bb2, 0xbd067741, 0xfcb2fc95,
-       0x1817f222, 0x5dd06974, 0x741a5d17, 0x62ffc3d7, 0xf9745f81, 0xa005a460,
-       0x2a5dbc93, 0xcd6555d9, 0xda0c3cfc, 0x8b203cbd, 0x6da7e4e0, 0x3cbcd58c,
-       0x0f9cc920, 0xa21be547, 0xf2a3fbea, 0x03f55179, 0x4b4af951, 0x03a6b2fd,
-       0x47fc231a, 0x4becf52c, 0xc41f651f, 0xfd8c87b0, 0x4678d826, 0x0c5d210b,
-       0xde50d4ec, 0x0541cba9, 0x1ee0ff45, 0x0ec5ec99, 0x182af180, 0x3d3ea3a7,
-       0xb1b9021c, 0xf0edc9d2, 0xd3d3bd0e, 0x8995d207, 0xac99df3c, 0x67b942ad,
-       0x7274ef7c, 0x5e47473f, 0xe4d127a7, 0x2cd238a7, 0x0d6edc93, 0xfcb1e9b3,
-       0x10a3b020, 0x6f595bde, 0x39ffdce5, 0x5e0d764d, 0x8d68f68a, 0x771343ec,
-       0x3d1bb2c1, 0x68e92ae8, 0x6ccd7a1e, 0x55f0bef8, 0x3a558e99, 0x70633ce2,
-       0x57e42c5e, 0x89ec99fa, 0xb3f42c13, 0x6ccfe889, 0x82c576e6, 0x08fa5135,
-       0x54f4435b, 0xa1a25ae0, 0xe03b053c, 0x973fab7d, 0xe88945f3, 0xb5bd68af,
-       0x278f68dc, 0x95df685a, 0x03cb59d4, 0x65da3ec2, 0xcb0649f0, 0x86833920,
-       0x42e7da0f, 0x47934f2e, 0xf01b335d, 0x665071d1, 0xb6799e78, 0x9c7c2659,
-       0x97e7e7ad, 0xfc4c942c, 0x493ac156, 0x6a701a1e, 0x7ad27e43, 0x3b6d5797,
-       0x177d9cfe, 0x3fcecdd2, 0xa439f98e, 0x1ddf3b6d, 0xcff31bb1, 0x8ff83dbd,
-       0x29fd67ac, 0x37e49d7b, 0x26ebd8ee, 0xf3d8ef7a, 0x6177c1db, 0xfc9d977e,
-       0x3f7b1d75, 0xd7f4831f, 0x845edcb1, 0x1063aef2, 0xf7aa87b7, 0x95a63e7c,
-       0x8415d7f6, 0xc6b2a3b7, 0xbfe6a3f5, 0x3092961e, 0xdea15585, 0xf89e37b0,
-       0x93bcf829, 0x7b1d0bfc, 0xb80ecf3e, 0xa9eb75fe, 0x1d39e710, 0x59fb366e,
-       0xf7225f9c, 0x8f770783, 0xcf0cb4df, 0x69f71ba3, 0xca7ca1f3, 0x831f7f0b,
-       0x59e3b472, 0xabb50fae, 0x79e38fad, 0xe1fc8745, 0xdce01532, 0x9fd54c8e,
-       0x1194fbb1, 0x62a34393, 0xe4efe5c1, 0x7850b937, 0x4fb70a68, 0x21e1fdff,
-       0x73bcb9f9, 0xae121d87, 0x7fc38bfb, 0xd7b0b944, 0xac69744e, 0x32c374f7,
-       0xb7ce57d2, 0x7fcae1ee, 0xd0b83a17, 0x0b914b75, 0x7fd4f759, 0x5aff7c73,
-       0xa2fcd2f6, 0x9d27a0f9, 0xf283b9ef, 0x9a3edcdb, 0xfbd205ef, 0x7869ff82,
-       0xeef0167f, 0xabbaff39, 0xddd7cdff, 0x9d5fde3b, 0xe3aef02b, 0x85f07f79,
-       0xbefcd3bf, 0xf4db9cae, 0x0dee94df, 0x9b15febd, 0xa80ccdf7, 0xb8d59d3f,
-       0xb2b8b150, 0x19abff7c, 0xc0cafa50, 0xdf388903, 0x37e751c9, 0xc2a6fa46,
-       0x92c9a6ed, 0x9641ec8d, 0x907b0928, 0x840351db, 0x496030fe, 0x0321e901,
-       0xf5cfde06, 0x0ebbc506, 0x195f1fcf, 0xb147df3c, 0x3bec6c14, 0x97ebcc01,
-       0x9ed5bc8b, 0xfcc4b9fc, 0x603a3478, 0xa20ff7f0, 0xa0703b5e, 0xa42f7a4c,
-       0xe8beefa4, 0x97bfce99, 0xe7bb1669, 0x0ed5af4a, 0xdab24dca, 0x7f45534b,
-       0xff9f18d3, 0x0e149734, 0x0f261c03, 0xfa1269fa, 0x570f2747, 0x5cf90499,
-       0xf6815816, 0xb59754c5, 0xc33c06bf, 0xe1cdf719, 0x380d5768, 0x8797590e,
-       0x93241c70, 0x70bcf49f, 0xdc1379c4, 0x2f18c232, 0x871f14c3, 0x1f729f63,
-       0xbd859df9, 0x904d474d, 0x5aab5c57, 0xb4159f90, 0xc81c3997, 0xe5ec36ce,
-       0x84cde0de, 0x2188adfd, 0x032bf80d, 0xdad3bf65, 0x06dfd91f, 0x3e2ebe5e,
-       0x537e3c0c, 0x851bbcbc, 0x45ae8197, 0x74ebf20a, 0x62fa17b4, 0x1f9e0cfd,
-       0xdce85218, 0x570bd84d, 0xa4291778, 0x50cc0cf7, 0x8e855f10, 0x1cf0aba6,
-       0x6893e1c4, 0xd9b7171e, 0x64707f68, 0x91f70449, 0xdfe50ab5, 0x10e3e9b0,
-       0x7b2f33df, 0x0c9df4ee, 0x8d7ee6fd, 0xf1e53dc7, 0x7dbf8ff3, 0x8c44e5f9,
-       0x2c781417, 0x46afff84, 0x167aff3f, 0x2d380389, 0xa1285854, 0x25bdfa0f,
-       0xefc5bef6, 0xdfe3cd6d, 0xfbba5377, 0xdefd5f39, 0x3abfcae4, 0xd8e40e7d,
-       0x5df300fb, 0xe1a30e98, 0xfd5db315, 0xaf0e669d, 0x1e1621e0, 0xe42ae3c2,
-       0xe139d33c, 0x9ffe821d, 0x99b3d3fb, 0xea4ed768, 0xe5c09518, 0x17b230eb,
-       0x385ec282, 0x3e09bccb, 0xa1d7ca17, 0x79fe7409, 0x8ac77650, 0xec2adc2b,
-       0x7c625fed, 0x751da409, 0xfb4646ac, 0x1f92758d, 0x60e75437, 0xb7c4639b,
-       0x9f86abe4, 0xfe0de04a, 0x8f3c6ce4, 0x842fe3e1, 0xbc6609a6, 0xa938cdb5,
-       0x0789e98c, 0x74df7bfc, 0xe14df51e, 0xc23df68b, 0x35b3ab77, 0xfc862f37,
-       0x6fc05db8, 0xc82ffee6, 0xf36979ff, 0xefd21b06, 0xcb3675a5, 0x2aa96af9,
-       0x6cb1b1ec, 0xe66bce2c, 0x0b3ba77e, 0xf65072f1, 0xb0673c61, 0x88168cf9,
-       0x0d182e71, 0xfd1fec4f, 0x9d555be9, 0xdab76bf8, 0xbae11f30, 0x430723fb,
-       0x56977a3b, 0x9e6b1a53, 0x9e7cec03, 0xedc3590b, 0xfdffd263, 0xc3a93be0,
-       0xf68c9915, 0x7e131d67, 0x63fa688f, 0xb767c744, 0xafee30b0, 0x5ca2af68,
-       0x68cf5b38, 0xdc90077f, 0xf037768f, 0x7eccf7fb, 0xb69b8b9c, 0x82f512ff,
-       0xc749668a, 0xa50a8623, 0x6d3f4355, 0xc65129b0, 0x6bc3387d, 0xa3eabbc4,
-       0xc5f137af, 0xf8215556, 0xfbb0981e, 0xe3f71c66, 0x9ea18d36, 0xd3b17fe2,
-       0xc7f8fb83, 0x07c499cd, 0x57ebadbd, 0xa9aaec55, 0x972a3748, 0x30f4d187,
-       0x92ce3eaa, 0xf40e4cbf, 0x699afe47, 0x8be25d6f, 0x6befbf81, 0xbc173892,
-       0xfe16f940, 0xbdbe4cff, 0x80b7c869, 0xa3e2679c, 0xf90f5abe, 0xbe4b1a96,
-       0xa9bc962d, 0x7bc5f708, 0x5e22a686, 0x26aabf17, 0xdb6f92c7, 0xe739f8aa,
-       0xb94e2233, 0xdbe411a3, 0xadf24db7, 0x8c5be411, 0x5fbf9078, 0xff0b7ca8,
-       0x36dff0d7, 0xd6316f94, 0xf9566bab, 0x08f9a636, 0x8d31b7c9, 0xaf3c4b36,
-       0x7c9f3b5d, 0x47af9293, 0xeaa0f8fd, 0x3f418f8b, 0xfe3e84db, 0xc44b888c,
-       0xe5ce5071, 0x7f8d3a6a, 0xe2ee72a1, 0xff73950b, 0xe4367045, 0x8c1de2dc,
-       0xd27b9ce2, 0x8b739721, 0x939c8177, 0x9cb91e90, 0x7187bc5b, 0x7c945cbf,
-       0xbe43d91b, 0x115faa31, 0x4d83ede1, 0x02df0fe9, 0xabf58dfd, 0x1fd4073e,
-       0xc6ef2ddb, 0xae5de599, 0x7adc10a6, 0x1783bbc8, 0x0876ef26, 0x6c720779,
-       0x68d7ca08, 0x5b35f0fa, 0x8f77c1e3, 0x2bff5e3f, 0xcadf97e4, 0x86f8de74,
-       0xbd0f9f8d, 0x1678fe36, 0x6263d7d2, 0xdc848b3e, 0x510aaf6b, 0xe45e53ff,
-       0xf1772beb, 0x468af138, 0xd4561fae, 0xfc2f614b, 0x17c27733, 0x78bfce1a,
-       0x2152c48f, 0xebcecb3f, 0xf38d27b3, 0xc3233632, 0x720b0f44, 0xbfcfc94a,
-       0xf40e6140, 0x72ba97e3, 0x5bfea24f, 0xfefdc39a, 0xf17be2a5, 0xd0abadab,
-       0x88fc5dff, 0x46a5e744, 0xe711ab7c, 0xa26e23db, 0x77f91979, 0x6627e3a3,
-       0x99a9b88a, 0x1bc294bf, 0x947fc462, 0x7fe6b16e, 0x966ff822, 0x62f04adc,
-       0xe331cbaf, 0x5d7a8c38, 0xe0283a70, 0x7ed32754, 0x802705da, 0x27bd379b,
-       0x33d3009c, 0xe1ba5232, 0x585bfc52, 0xebef566f, 0xbd16e035, 0x5d7fc36e,
-       0x0de9fa2a, 0x7b9c060e, 0x1dc05fac, 0x939202ec, 0xa758f0d1, 0x33b5f975,
-       0xe8094e31, 0xe84ce486, 0x181700d7, 0x70d26f2f, 0x47977dcb, 0xd664fd05,
-       0xe1829a4c, 0xae30b30c, 0x6a0bca1c, 0x0fdcbd17, 0x1dee31e0, 0x4edc58ef,
-       0x0f609b2f, 0x56ec39e0, 0x41c92767, 0x35db0e83, 0x141c07ae, 0xbfddddf0,
-       0xf9d93272, 0x7a8e924d, 0x24e23048, 0xae0106b8, 0xa828ff78, 0x8106fc70,
-       0x0eff911e, 0x8719f23c, 0x8bc91ee3, 0x635c9dfe, 0x40bc42bf, 0x8e66ccfd,
-       0x22586097, 0x4eb164bc, 0xa8a97f3a, 0x84117c95, 0x8206d35f, 0xe19f219f,
-       0x93c665cf, 0x58957e89, 0x4c954bf4, 0xa8a965fb, 0xf35ed337, 0x99e7a407,
-       0x036caa4f, 0xfbfe1b81, 0x4f3e7a2a, 0x9e34501c, 0xb6bc04da, 0x085d3c21,
-       0x77ae4eb7, 0xfba0be45, 0x50794650, 0x39e05909, 0x5f73d1e5, 0x0671af09,
-       0x518e90bc, 0xcbe735be, 0x92682f98, 0x9ef4df58, 0x50f3c5eb, 0xef17bf33,
-       0x7ffbc239, 0x18b1f24c, 0xba60beeb, 0x8b9e85ee, 0xbcf16e80, 0x8eba37a4,
-       0xd23b5386, 0xe9bab7f3, 0xe76735f9, 0xe7a44ca1, 0x43f7123d, 0xce5a2734,
-       0x1e763d35, 0x09d5b5f7, 0xeeeb0f74, 0x6df5557c, 0xcb90c6f4, 0x7ed1ee82,
-       0xbb37df30, 0xf1821704, 0x141c5ba2, 0x18f347ef, 0xb353f5c2, 0x64e6de7c,
-       0xf567d7c9, 0x2edbbfde, 0x37278cc5, 0x3f2323f4, 0xf8c3c71a, 0x6f1826f9,
-       0xd178f764, 0x2fe183fb, 0xfabadf38, 0xbad9bfdb, 0x6ebe718c, 0xb590543c,
-       0xb88d5e10, 0xe05223a8, 0x73ea2a47, 0xfc4b25d3, 0xc85ccc15, 0x7fdc6fad,
-       0x7bdc96aa, 0xa74d2cff, 0xebb774fb, 0xe89d77c6, 0xe2674f33, 0xdbe26f7c,
-       0xec7fefb8, 0x5998e7e7, 0x44d6f636, 0xab263fdc, 0xe3eae90c, 0xa1f92a43,
-       0xe3ca9e3f, 0xedf9af6e, 0x3e5d0501, 0x3898f0d7, 0x8938cd76, 0xb037acec,
-       0x87a8f1eb, 0x047f983b, 0xef132fc1, 0xd5d465ed, 0x5f02f14c, 0xae12dd8f,
-       0xa537d4c6, 0xc435e933, 0x219924db, 0x7dfc5ade, 0x7f20b8a7, 0x032c87fb,
-       0x1fa0a05d, 0x07b1fb50, 0x9bd63259, 0x33264fe0, 0x27e37c66, 0xf3075e6f,
-       0xf6487f18, 0xacdea179, 0x03172e03, 0x7ae47a7d, 0xe0980b1b, 0xab858135,
-       0xfe34dfd1, 0x9c3affa8, 0x3be81177, 0xa8a44f78, 0x07b54379, 0x6a25ebf3,
-       0x72050c1f, 0x6d9eb03d, 0xbf7267b5, 0xea017285, 0xf5c13761, 0x4eb05ebc,
-       0x728861f2, 0x8a5af341, 0x93a82a2f, 0xb6e142e8, 0xbc1cc4b0, 0xfa03b0df,
-       0xda1eb6dd, 0x05fee167, 0xbadfb1ed, 0x875e6f33, 0x49e60772, 0xb9f9ebed,
-       0xf3b4017c, 0x2dd4bf22, 0xd78afea2, 0xb3ef0c4b, 0x7df3d514, 0xea90e8a9,
-       0x7dc6f2c3, 0x3b7ed08f, 0x97ebc603, 0x6450fb8e, 0xca0bdd2a, 0x2fba7494,
-       0xf84c1a19, 0x7f1c60eb, 0xf220fa6c, 0xabbc520b, 0x98a0c097, 0x64fe63e3,
-       0xb3f2421f, 0xeb4cb7c0, 0x96bcfd0b, 0x236e9c93, 0xe7433aba, 0xde0147ed,
-       0x1bf78001, 0x40e55e22, 0xab5a07ce, 0xc2fc5f69, 0x9b9f943e, 0x38a24d34,
-       0x8f2c858e, 0x8e6638e2, 0xebe6fae7, 0xe8c33b97, 0xed5d7be7, 0x0fdf881c,
-       0xefa76e5c, 0x1cb8dbed, 0x4ad41f6e, 0xebe3f6fe, 0x58f78655, 0x24cbd7aa,
-       0xabd78e2f, 0x7e563f74, 0x1431c78c, 0xc7fae36e, 0xdfbcf581, 0xe1b7a8e3,
-       0x439607b9, 0x11ab70be, 0xb4e5c0e7, 0xe8167f61, 0x90c2fe3c, 0xdd62e5bb,
-       0x75a1f63d, 0xd92434cb, 0x2e5b7968, 0x8b0971e4, 0x2d1cbd90, 0x1cf1cb77,
-       0x197c83dd, 0xeae6271d, 0x0e9063b6, 0x5d105f22, 0x19521c57, 0x07d231da,
-       0x9714b96d, 0x73a247b6, 0x92cdf18b, 0x8a1ae31f, 0x4987b1de, 0xcfe70eff,
-       0x2fee11fb, 0x8619daef, 0x3c431f2c, 0xb1ca9c80, 0xa7e9fe77, 0x1be4fdf0,
-       0x02088c0e, 0xb827c9ba, 0x59be711b, 0x4f3c799b, 0x52eb1bd6, 0x9b2f3ef0,
-       0x40e497da, 0x02ccad61, 0x52713926, 0x13775ff2, 0xd4741fdf, 0x667c0c77,
-       0xb8053569, 0xc1cb7ebf, 0x66ef55f7, 0xd8646315, 0x043d84ef, 0xf51f81f6,
-       0x6b5de29b, 0x1d133453, 0x9b59ef14, 0x55f7c322, 0x1aa61e22, 0x576857f7,
-       0x8a71f1ac, 0x06fa4af7, 0x3f4638d3, 0x2edabf46, 0x1ee86ede, 0x7fd6f69e,
-       0xd68fce31, 0xf286a9f9, 0x1e9fba22, 0x4fd2f7e3, 0xadcfefce, 0x395e6093,
-       0xac14cbaf, 0x8cc1f39e, 0x1d73e6a1, 0xcafc3523, 0x98da6fd9, 0x9cbf04df,
-       0xbf31c53f, 0xe38ddf09, 0x7f01ef80, 0x61493757, 0x23f984a7, 0xe516795a,
-       0x0af3e475, 0x98ae7fe1, 0x1aebcfca, 0x8158de33, 0x4b233f7c, 0xa1607a22,
-       0x8937d680, 0xfa2f35f4, 0x78b30bfd, 0x8f6842fb, 0x08f8d8fc, 0x13904fe7,
-       0x1523945e, 0x52e6d7eb, 0x8bc93afd, 0xc86e37fd, 0x28a47d27, 0x5e546647,
-       0xa3f48477, 0x4923a6a2, 0xb7c0c7c8, 0xa81f50eb, 0x51d76898, 0x68fc1b8e,
-       0xe2ebf7f0, 0xe8732b3e, 0xc67ef1a3, 0x8be646ff, 0x21f2d7c1, 0xf583d72e,
-       0x39831f9c, 0xdf5f5f9c, 0x2f0ae2a6, 0x9f89bf84, 0xfce16f8f, 0x43763f2a,
-       0x2f87de2e, 0xc3efccdc, 0x453f581f, 0x78fa7d43, 0xa6fda258, 0xbd737f27,
-       0xabbf9a35, 0x7defbe25, 0xe0d2fd5d, 0xe18f836f, 0xaf1c6aef, 0xef14f80c,
-       0xf5f3464f, 0x0fe1b54c, 0xaf7cc3b7, 0x03d61a79, 0xddf29df3, 0x26ad3d3b,
-       0x14f90939, 0x3c2817cc, 0x2b90cb9e, 0xfb8f0ae5, 0x8bf3dafb, 0xb76c3f1a,
-       0x677e47fa, 0xebf1e44f, 0xfdd12a75, 0x07b3f8f9, 0x7f205d9f, 0x9d5f285e,
-       0xf18d3f8f, 0x7ed63de5, 0x2de8277e, 0x8076bfba, 0xfae0046b, 0x8a26fd4a,
-       0xa9e8fdf3, 0x3f113323, 0xce81bba5, 0xddeabe91, 0x4e72822c, 0x557ed309,
-       0x3dd328d2, 0xb244a601, 0xf99b73af, 0x956dc798, 0x7a26e33e, 0x1ed6792a,
-       0x4bed019e, 0x86307e76, 0x779668e2, 0xe85a5c52, 0x872fa129, 0x1f20c75a,
-       0x7e3c2894, 0x042e5a2c, 0xd70fdc1c, 0x367e2bb6, 0xc2da4fae, 0x69288fdf,
-       0x9bb551b8, 0x746e25ce, 0x3a3d46a8, 0x1d010dd7, 0x9c5dfde3, 0x02ddf99f,
-       0x6dac6e23, 0x2513972b, 0x81d92a4d, 0xb7b65b25, 0xc970fc63, 0x77f2763b,
-       0xa19cb705, 0x9e5310fb, 0x94fe46d9, 0x396c9360, 0xb711eb7f, 0xd88e45b9,
-       0xb1b0ee31, 0x211dce9c, 0x0df2847f, 0xcf97e3b1, 0xfa585f17, 0x219d9ecc,
-       0xafe96100, 0x7ca0f49e, 0xd9b2d539, 0x7e877083, 0xba6e32bf, 0xc3669c47,
-       0xa7195f3d, 0x01ff0a79, 0x438f738c, 0x9c4635d8, 0xa4be96eb, 0xb2fcc247,
-       0x739c62f3, 0xdbe5e974, 0xef1c7d3e, 0x7b3db411, 0x6f9c71fa, 0x7e3e3fd9,
-       0xd8c1e31c, 0x77ed275e, 0xa2dea7c1, 0xdda36c38, 0xb5dfb126, 0xe2927d6f,
-       0xb5dfdbd7, 0xf6b7b0fb, 0x6307c73d, 0xf6fb603c, 0x6fd0522f, 0x34cf64b9,
-       0xd92eebf2, 0xc5952531, 0x148c2fd8, 0x017c36e9, 0xf8d1f3f1, 0x8078d03a,
-       0x023ed6e2, 0xebfca37c, 0x286dbb8a, 0x5ecc71e7, 0x1f5b6f11, 0x8f429efb,
-       0xebc6daf8, 0xe51cb9ae, 0x1fd7237e, 0xfb671bcf, 0xdbf1e026, 0x7abf8017,
-       0x1b102fc3, 0x3fe11f7f, 0xa2fb4f00, 0xe369f7f0, 0x8a3c5fc2, 0x7b7d8d65,
-       0x5c8db38d, 0x7b8cdc00, 0xfc380f10, 0x88c91c87, 0x5c525fe7, 0x866de233,
-       0x4f9ff717, 0x91fde307, 0x5ce76a13, 0xc7b85fba, 0x68bc63ae, 0x89b79ec9,
-       0xbc77da7f, 0x26687e41, 0xb3b423ee, 0x3f1e3fae, 0xd675892e, 0xae7c79b9,
-       0xefc63f80, 0x5df43d7a, 0x3a72e9c4, 0x7b77e236, 0x9d95db8b, 0xee36cf5c,
-       0xfdd79467, 0x76c3c451, 0x41ca4be3, 0xcaf91d3c, 0x0e036878, 0xddc390ba,
-       0xe3b1e871, 0x2beebba3, 0xfe217c08, 0x8aea1f70, 0xc0fc8733, 0x7a37e4b1,
-       0x0790c59b, 0xfc781bed, 0xfb1abb7a, 0x9711b05e, 0x3e688ffe, 0x3c585f0d,
-       0xffe6f9fa, 0x81d3e175, 0x4f724fca, 0x2dfdb538, 0x774f1cb6, 0x9eecdf4a,
-       0x7d149961, 0x1cebca6f, 0x473b7187, 0xbb83b434, 0xdeb16cec, 0x6f57e136,
-       0x78a64a7b, 0x070d55e5, 0xcb478e48, 0x2f7c0a8b, 0x337cc625, 0x9a2b7cc5,
-       0xf6d13ef8, 0x82ec3bac, 0xeff6da7e, 0xa8ae7a22, 0xd2f1423f, 0x95f96f2f,
-       0x8b8a6ad6, 0x6c227dc0, 0xd3db7f9a, 0xdc90c6fb, 0x44b2ef16, 0x8c49338f,
-       0x3d8e6c13, 0x8cfeb04e, 0x50d29c65, 0xcebba683, 0xc529de3f, 0x77f6237f,
-       0x83eb85aa, 0xe9e41aa7, 0x0fe318e1, 0x77d6aa73, 0xa4bf60a1, 0xfcdc67f7,
-       0x13d919bd, 0x12e5fa47, 0x093bce77, 0x146a9849, 0x4cbd55af, 0x87fd77c4,
-       0x5df10d2f, 0xe18abeed, 0x7c22577c, 0x551e7e4d, 0x4bd4300f, 0x2cbcb4d5,
-       0xcb442bf4, 0xc6c92d1b, 0x2ffc26c2, 0xf54f4f71, 0x644779d2, 0x70f3e220,
-       0xfb1571c6, 0x9f944bfd, 0x5b0a2fea, 0xfbf30a95, 0x2df2484b, 0xdfd97e83,
-       0xe794183e, 0x977fd9ee, 0xd963f11e, 0xb0aa57e2, 0xbb461e77, 0xa4e0bd84,
-       0xaf7906f8, 0x08f9de93, 0xf5a4ee3e, 0xf9f1d81e, 0xff5fa413, 0xb9f8cec2,
-       0x202f580f, 0xde750aaf, 0x9f1df1c7, 0xd457fe3f, 0x8c31b19f, 0xd438f85f,
-       0x3ea1bb47, 0x8e9cec9e, 0xa0c61367, 0x85f0a45f, 0x3ca266bb, 0xf4e78c2b,
-       0x6a4cf858, 0x3bfa1ab8, 0xc7f3cc96, 0x77a20db6, 0x759f4a25, 0x81e8dc53,
-       0xe055cf1d, 0x4cfed4be, 0xa97dc33c, 0xe7a105fd, 0x53bc52ff, 0xcd7aab55,
-       0x4cc5e3f1, 0xf3ef9af1, 0x12de6294, 0x2fc8c4af, 0xfe847c41, 0xba04a6aa,
-       0xaffa0407, 0xd48f9fa5, 0x447c3bce, 0xfcfea1c7, 0x3fa453fe, 0x7ae883ca,
-       0xcebdf946, 0x395ee221, 0xd77573b4, 0x059d6a0f, 0x9fd35f3c, 0xaa1693cb,
-       0xf853b0ff, 0xcf79458f, 0x87fd797e, 0xeeeefc84, 0x10afb787, 0xd344d0ef,
-       0x6fd146ef, 0x5fbf96e9, 0x959deb1c, 0xefa7f318, 0xc858943f, 0x76ca7a86,
-       0x857fbd27, 0x7de028ef, 0x3f1a9d85, 0x44f32ad7, 0xdd9b9de8, 0xc5971e42,
-       0x9ddde845, 0x581e62fe, 0xd1ccf31f, 0x9fbd34fa, 0x61939cf6, 0x0bf9595c,
-       0xbbe23f6e, 0xc7e7e77c, 0x71859e7e, 0x1714f189, 0xffc2fe5f, 0xb7283a22,
-       0x3f22e647, 0xb3b76e74, 0xdbe7c88d, 0xfc8c1d5f, 0x0646a6da, 0xf38af9f7,
-       0xbb06f2ba, 0x58bffef5, 0xdaaaa9c7, 0xbbbef0cb, 0xa4b6af71, 0x57f33917,
-       0x5fa3d727, 0x725ffa71, 0xdf5bbf12, 0x35553a73, 0x59df133b, 0x3897ea30,
-       0x77c5cb62, 0x137c5e51, 0x71eaee39, 0x9c5df53f, 0x25ac47cf, 0x153efd05,
-       0x3ca377a0, 0x3e92d92f, 0xfb04fd10, 0x043bc69d, 0x8fdc04de, 0xb25eabf6,
-       0xef3531a7, 0x7caa2733, 0xf430ca99, 0x54cc8cdf, 0x1b1d1d60, 0x67f414ce,
-       0x9cea4718, 0x9dee4b1d, 0x3ad3c676, 0x98f61c4a, 0x09cf9df7, 0x8d0f7aba,
-       0x1e3e64fe, 0xee3187f2, 0x724c357e, 0x2f388ef8, 0xbb012bd5, 0x6e97bf08,
-       0x79699399, 0xa1a9457f, 0x04a7c07a, 0x4eb662cf, 0x6fc932cb, 0xa5e2bc63,
-       0x264a9959, 0x4ffe577e, 0xddcabd17, 0x24a16678, 0x01150bd2, 0x9faeb663,
-       0xa2887ee5, 0x7e1039e6, 0x15d3cb1a, 0x86a54919, 0x358e3df8, 0x7502ea50,
-       0x5653bf8b, 0x9e4e50c9, 0xe8f6e710, 0x1bb4c2ef, 0xdc92775e, 0x6c620d0f,
-       0x07be3a78, 0x4dd04de1, 0x10f153f0, 0x5763e61e, 0x1797192a, 0x93b47433,
-       0x7d8050a5, 0x5d54f409, 0xe9133d35, 0x18fcfe11, 0x07a64907, 0xbfa3cfcc,
-       0x41ea05fc, 0x3dfca740, 0x70b2efbf, 0xc3188035, 0x3aafc981, 0xe877f199,
-       0xccc3bf56, 0x71a5c6f6, 0x68e77892, 0x1731c91f, 0x84ebfeeb, 0x94558a3c,
-       0xff09d5b7, 0x4473c1c8, 0xa822ce97, 0x58bbc617, 0xd7521e24, 0x9994e528,
-       0x90593dff, 0x3ea9d137, 0xcd1e5ad1, 0xa2d72017, 0xf8206dc6, 0x449fbf41,
-       0x5449fbf5, 0x557c9fbf, 0x829c06bf, 0x7c3e8d8e, 0x556562a7, 0x1f1b809e,
-       0x06e021cf, 0xef8919f0, 0x9c5b31e8, 0x13879c4f, 0x6cc4e35c, 0xf01f58ec,
-       0x4e971e5a, 0x612fb978, 0x41c6276f, 0x865aa4b3, 0x890aef76, 0x97f0d3ef,
-       0x63b532e7, 0xf0f883ba, 0xb94e311e, 0xc30af380, 0xbea3d53f, 0x1eaff493,
-       0xd5bd9df5, 0xdf5d8b8f, 0xe27cdbdd, 0xb127cf63, 0xe26bfe97, 0x75fff663,
-       0x0bc552e5, 0xe786bf6f, 0x49f25db6, 0xf55bd007, 0xd438f2cc, 0xfd8f1333,
-       0x70be95a3, 0xd031d33d, 0xa438ef8a, 0xb8b7a06f, 0xd1efd661, 0x7d1bd274,
-       0x40758be5, 0xe00fd5de, 0x7f189370, 0xf73f1d6a, 0xf70965be, 0xe87981d3,
-       0x8b37fac7, 0x0a3937fa, 0xc470dfc9, 0xbabfdfc6, 0x91eb96a5, 0xa658fcb7,
-       0xef1ee9f3, 0x803fe151, 0x2a5d6edf, 0xb1e92385, 0x7562d7de, 0x9e6e3f78,
-       0xbdfa3f18, 0xe6f300aa, 0xbd6396ae, 0xd2e9c557, 0xfd1757b8, 0x9602c54e,
-       0xb321de27, 0xd4eb3f7e, 0xcd67e4bb, 0x2c7deea8, 0x1ee816b4, 0x7ba04ff5,
-       0xebc7973c, 0xe2171462, 0x485c78d1, 0x4f3a20cb, 0xd9dfe433, 0xdc04de91,
-       0x307f99af, 0xeff3aeff, 0xa6f4af8b, 0x2a1def9a, 0xef2ce2e7, 0xbeab54f5,
-       0xea6f9434, 0xc15fd039, 0x0dced654, 0x39535e61, 0xfcc4ade8, 0x7249be18,
-       0xa3094d2a, 0x3cf4545c, 0xaf7a8856, 0xa8c3ef78, 0xd55d25af, 0x0ebe67a5,
-       0x4b8e6fff, 0xbc5cbe26, 0xb6f74bd6, 0xdbcf8b3f, 0x7b24f489, 0x57017c72,
-       0xed087a4f, 0xc6aeebe0, 0x5cf7a775, 0xf3e6b54f, 0x157dbe91, 0x6ffc8080,
-       0x4fce073e, 0xf6df7bb6, 0xa37efce2, 0xf4bbf432, 0x44ef8f84, 0x86cfca18,
-       0x887c5007, 0x0463309c, 0xbc46bf8e, 0x6ababa6f, 0xaa2ba524, 0xbc794898,
-       0xaf2a8adc, 0xea447348, 0xaa74e917, 0x1a556f77, 0xf95557e5, 0xebe03528,
-       0xfbd0d5f0, 0x7c618e93, 0xf02e877c, 0xf0136497, 0xe5fe900b, 0x73a4ab48,
-       0x195ea745, 0xd8df77c1, 0x7077d840, 0xc10d7a59, 0xf919d357, 0xe53ea135,
-       0x548798ed, 0xf8419dad, 0x564af452, 0xc56fe508, 0x5c228e07, 0x2d4bde9d,
-       0xd3da5aef, 0x7fbd46c6, 0x836f051a, 0xb871b6de, 0x7a712fdf, 0xfdfb868b,
-       0xe3178b6a, 0xb2bfee22, 0x82295deb, 0x1c43983b, 0xe7e6bfee, 0xdee13db4,
-       0x09be7b32, 0xe9eceeee, 0x04fbf704, 0x7016ef9c, 0xa87816ad, 0x46acf016,
-       0xa47e53b8, 0x3a44fbc8, 0xc47bd29d, 0x112bb7fb, 0x08ca901f, 0x7d878077,
-       0x30c98854, 0xf179ba1e, 0x7412eecf, 0x1fc8dbab, 0xfcf2bb2a, 0x127b7708,
-       0x05c3bb87, 0x06ba2078, 0x3cb17bb8, 0x5d54f044, 0x9f50ce1c, 0x15e441e3,
-       0x7e267b84, 0xb800f8e7, 0x871f8df7, 0x058270f2, 0xe4d25ace, 0x23fb830b,
-       0x124b7f7c, 0xbf0d1e7c, 0xafbf8d24, 0x6f77f06b, 0x88b571fa, 0xef16aeb7,
-       0x511c2227, 0xe00879af, 0x4f0e34c3, 0xc8a47dfe, 0x164d28fb, 0xe0357ff6,
-       0x161fcb01, 0x19c210fa, 0x73c51fd3, 0x56c93cfb, 0x38454fb9, 0xf2efe1f5,
-       0x1b10a4b0, 0x6878cd98, 0x85a5fe2f, 0xc6f31798, 0x4ad7aff9, 0x44aeb23f,
-       0x7de903bd, 0xdd6de918, 0xcf0daaab, 0x57a5e43f, 0xcb67ee59, 0x5e89fdb3,
-       0x42407f82, 0xc13ee6bd, 0x5e916b87, 0x1edc7e68, 0xe0e8295e, 0xeefef16e,
-       0xee7e823d, 0xa0fcfc17, 0x7e3e3741, 0x74cd643f, 0x9498c71e, 0x20ef1361,
-       0x4e399846, 0xc0d7d130, 0xd9179834, 0xe94a5e36, 0x8ef64b9d, 0x7e36f89d,
-       0x7d23f314, 0x6773be25, 0x9b43bf98, 0xa1f50fd7, 0xd9dde344, 0x39c4de89,
-       0xa23d3174, 0x6520f788, 0xc4b64f6e, 0xdab5df7c, 0x7e81dfb7, 0x13e6de99,
-       0xafa7f3ef, 0x6be2f184, 0xf54764dd, 0x59cde40d, 0x2d577908, 0xcb0c55d8,
-       0xc1707cb9, 0xf44d0bbc, 0x5f8bdf11, 0x595d7547, 0xf64af480, 0xa93fa438,
-       0xf844ea1d, 0xe8bdac02, 0xcd487abf, 0xc1fb87eb, 0xfdb18943, 0xb9e2b370,
-       0x7593c4bf, 0xb09fc5a9, 0x3b53f54e, 0xde55a27d, 0x43fb13ac, 0xfe56a99f,
-       0xcb83f630, 0xc59f7f44, 0x0f147e07, 0x6e729674, 0xa4cfc92a, 0x0fef636b,
-       0xc216aad5, 0x47aa39f7, 0xe50ebe73, 0xee6f5c6b, 0x9d187721, 0x8c0d9c83,
-       0x2ffe88d8, 0x3396be83, 0x8c42e72e, 0xbac693eb, 0x3ef4867e, 0x9d01f702,
-       0x01f71ee8, 0x34c3cbcc, 0x5b949ba2, 0x587fe46c, 0x5eecf825, 0x046b5fc1,
-       0x7c803d5f, 0x81df0235, 0x13fa51f6, 0x90eb4fc1, 0x12dd20ff, 0x78f5ce9f,
-       0x6197bef1, 0x8c772cc7, 0xab1cf7a5, 0x0fda365d, 0x61ed7794, 0xfb05da17,
-       0xf7e8ebc6, 0x7a59dd91, 0x59e58dc0, 0x43c03f0e, 0x91d2cc4a, 0x2f733e5e,
-       0xe2abe8b8, 0xf4fd015b, 0x72a2b0ae, 0x949ea47f, 0x451fdec7, 0x9ef453a7,
-       0xcb5faa80, 0x70fd3fd0, 0xe113a552, 0x8f3c70fc, 0xcfcdaad3, 0x3e03b826,
-       0xe29bc5b6, 0x5f6752a5, 0x1f1ef5d5, 0x2f70ff76, 0x12ec12ef, 0x0c0d82f2,
-       0xf92661b1, 0x7bde2b50, 0x1b10de64, 0xcb139269, 0xf432e787, 0x0f94f5eb,
-       0xcdcbc8bd, 0x90ae5e5c, 0x434bcb62, 0x65e4377f, 0xd2315cb4, 0xb74d1795,
-       0x5d54a7dc, 0x66f2463e, 0xc1ff6c64, 0xfcede3ef, 0xf3e66a1d, 0x2cf7a7e5,
-       0xdefd7807, 0x83d42f0c, 0xf7c57f0c, 0x5a27ac62, 0xcab89e3e, 0xf40357d8,
-       0xcd02d03e, 0xaff8f0fb, 0xfbad57dc, 0xd5b9e141, 0x9c140fa4, 0xa8b4a1cb,
-       0x11f13a76, 0x9318d3c3, 0xfd7c7c9d, 0xdf883d0f, 0x7ce2b5e3, 0xc61abd7c,
-       0x1b7da4b8, 0x0e607aef, 0xe3c175c0, 0xe38f9d32, 0x14d90d3d, 0xbcb2c2df,
-       0xef1ba7a4, 0xdf0f1e23, 0x31c731ee, 0xe9d4fc14, 0x37bffd47, 0x1f582c7a,
-       0x8d537fdb, 0x83bb44ff, 0x5da246f9, 0x675dfa01, 0x9fbff504, 0x18dde938,
-       0x18da1f23, 0x8fc733ef, 0xf15be918, 0xdc21ced3, 0x33f78adf, 0xab9dd217,
-       0xf4d79d0f, 0xdc7c17ce, 0xc733e863, 0x4547d273, 0x7dc0359c, 0xca7fc596,
-       0x098f49cf, 0xf473187f, 0xca271e52, 0x7b94bdbd, 0xd3133c78, 0xd3ff9763,
-       0x3d51a47e, 0xb821b4ec, 0xd3daf2fe, 0x2fa5deab, 0x6280f3d6, 0x60bdc711,
-       0x79787c63, 0x2059be0c, 0x102f07ee, 0x7d065de7, 0xd0df7f15, 0x465d39b3,
-       0xd4f4add3, 0x1fa74425, 0x5fc9541f, 0x87f4015b, 0xd4f4987a, 0x698f7a78,
-       0x3d9713d9, 0xf9c00b78, 0x95324393, 0x10739d97, 0x87ffb65d, 0x3bfce28f,
-       0xefd2ab7f, 0x70727c26, 0xb7ebc51a, 0xbb9ef78b, 0xedc5cef8, 0x5c5c1bda,
-       0xbb9c14ae, 0x8bbbe897, 0x35f3c2ae, 0x7382dbe4, 0x565e900f, 0x4ebdef80,
-       0x788f75c0, 0xe8229279, 0x1fb60277, 0xea1cbb92, 0x3e72b615, 0x15431361,
-       0x10de8fe4, 0x0637bbef, 0xf2e0df3f, 0x0b45e25a, 0xff50d75b, 0x24c3f40c,
-       0x02c85c53, 0x8507fbf1, 0xe584b878, 0x21a5887a, 0xd6f908df, 0x77d6ff4d,
-       0xd69ddbb0, 0xc2e91a75, 0xb04e75ae, 0xebdd61d8, 0x73e72efc, 0xb6146fa1,
-       0x7579f0e6, 0xe3e7e7ad, 0x7ba7ad63, 0x7da9131d, 0xf1ec627b, 0x1fe317ef,
-       0x9bc22aab, 0xbc44ac5b, 0xbe105bb7, 0xd5f7c35d, 0xf627d60a, 0x2aeb4c91,
-       0xc4b52dac, 0xe6d4152b, 0x857afbd3, 0xdbb5f3eb, 0x1753fb4c, 0x97fe425e,
-       0xc6eb0d27, 0x2e6bfdcb, 0xaea8bc23, 0x7e913bbc, 0x7c553d8f, 0xec5e7bc7,
-       0x84e9e397, 0x49531a16, 0x4f76eaf2, 0xf74dfbac, 0x56a9e347, 0x80ec09e0,
-       0x0c9e132c, 0x3fb744fc, 0x8efcb9b6, 0xe21cf0f7, 0x509afe11, 0x0a2bf2ef,
-       0xe1b1e97f, 0xd7a0a4f7, 0x040fa063, 0xdf7e082e, 0xf5cbc4b2, 0x6f813f0a,
-       0x77c63e03, 0x08c2e7d0, 0x379127b7, 0x4e3fb193, 0x5b83e70f, 0x1e82f8f7,
-       0xcf5ec526, 0x59eb5d6b, 0xc7a042ca, 0x3eb8d49c, 0xee7afbd1, 0x05c72162,
-       0x4f8ba7ac, 0xfa7c2df3, 0x385b9ada, 0x9ffc0a9f, 0xd10f7fdc, 0xbc70b1f5,
-       0x7a54e30f, 0x486bcf5b, 0xd062e307, 0x1b10b0c1, 0x8f7ffd95, 0xfe684e0e,
-       0x3ee08f11, 0xee15fb02, 0xde4fc5d3, 0xbf3cc63f, 0xfd27e2b7, 0x9aa5f69e,
-       0x0ea73b0b, 0xf41df64d, 0xfb277ed2, 0x434961aa, 0x633f815d, 0xa3cf12fb,
-       0x6e9fa19f, 0xc6cfe245, 0x578bd2c4, 0xc72e0556, 0xaaea8bf3, 0x8fd1cba2,
-       0x973d0aaa, 0xce9b9ea1, 0xd623177f, 0xcdcc7d7b, 0xaab2bbf1, 0x983fce92,
-       0x94f4c423, 0xd80077ee, 0x47f24c89, 0x7eab2e2b, 0x1d01a9a6, 0x789adffd,
-       0x025540a7, 0xd0b3d3ab, 0x1194945f, 0x1fefc132, 0xb2ee7e2e, 0x8ebf6d26,
-       0xe8761ae7, 0x8e60fd1f, 0x8b59ca81, 0x6545ecff, 0x93c05f41, 0x1c731cf1,
-       0x124bf06b, 0x46cf13f9, 0x5acf13f9, 0xf30491e6, 0x5b3b0afe, 0x1ce87871,
-       0x8fc26152, 0x5f01e02c, 0x5bbb1f68, 0x1e5cebe7, 0x607d21ef, 0xb23645d5,
-       0xff09d6eb, 0x2fd0cff4, 0xe851704d, 0xe0c301bc, 0xc096beb0, 0x73c4e1d7,
-       0xaded190c, 0xf8dde508, 0x4f4c9762, 0x4f984a1f, 0xf3095e64, 0x1564597d,
-       0x931d0fda, 0x3f20ef5a, 0xe69033a0, 0xd67ebc06, 0x84b0e5af, 0x817912e7,
-       0xb5ce118b, 0x0bc32872, 0x77217ff5, 0xc1bd6066, 0x1f4ef450, 0xf7845e9e,
-       0xf3a60212, 0x8eb421ce, 0x33dcbcee, 0x2552d17f, 0x6feffcea, 0x5fcb9b17,
-       0xc62ffa71, 0xf93b5479, 0x1f4960fb, 0x57be7448, 0x94ee75dd, 0x64f2fb47,
-       0xd123c737, 0x41d5d205, 0x559d37ae, 0xc87d09bc, 0xf3323d9f, 0x7c3ccb45,
-       0xec22bc96, 0x53a03ad1, 0xe832a73c, 0xb7e29863, 0xaf0d1d21, 0x3c66ef81,
-       0xfb77d0c6, 0xf079e8b8, 0x31b9fa98, 0xe897183f, 0xcb973e55, 0x7a28e3f7,
-       0xf9f12dd8, 0xdced8a87, 0x1921646e, 0x20c73af1, 0xcf05653c, 0x8fe33227,
-       0x8d77b5ec, 0x82b62773, 0x0b9e75e7, 0xb9cfc6de, 0xa733e7a3, 0x3c16eef9,
-       0xdcd399ef, 0x7b9e3e6f, 0xf8ba29ce, 0xab774c43, 0x51e3fb9d, 0x2250fc5e,
-       0xb7a6f67d, 0x21e3545e, 0x46e6f1dd, 0xae609f7a, 0x73bfef9b, 0xf88aa759,
-       0xe35d300f, 0x5a6156e7, 0x27cc6ddf, 0xfa2a0df2, 0x84896e1d, 0x721ab86f,
-       0xbe18beb7, 0xb9bdd51a, 0x425f3b07, 0xf41a05b4, 0x321b3a5c, 0x5ef935da,
-       0xaede79e6, 0xf14e0e0b, 0x838a47fb, 0x6ebdd5d6, 0x58c1c107, 0x7c24d427,
-       0xbc49c174, 0xa5c066cf, 0x37f1dd6b, 0xf8fe855f, 0x1cdce4de, 0x790fe8c7,
-       0x579f3c9c, 0xc13e9c34, 0x0b939022, 0xb91ffedd, 0xb77afca1, 0xcb4c2eff,
-       0x95839d1c, 0x5537c421, 0x0390af98, 0x1c00a517, 0xb8141a3e, 0xd1e11938,
-       0xf482f7d2, 0x2e4ec3fe, 0x1ba70e0f, 0x1bab6d7a, 0xc8bd9be9, 0xf7e35af5,
-       0x38ed5632, 0x008dff7e, 0xe55e8f9f, 0xcb95cdef, 0x22ee6bde, 0x62ccb2ff,
-       0x7a4621d9, 0x1e0df858, 0x7bc4db76, 0xf39d7cd1, 0x79ef0e14, 0xcf74f18d,
-       0xd952de6e, 0xbcfdbef2, 0x957e3ca5, 0xae632d29, 0x2b09d8b7, 0xecf75d04,
-       0xd11afd07, 0x3a5fccfd, 0xd92dde99, 0xc893e9a9, 0xa738f1cf, 0xfd53f9b3,
-       0x4ffdc632, 0x1f912d58, 0x6f51fc69, 0xe7e42b53, 0xc87d1387, 0x5ceff3ae,
-       0x97ef899c, 0x3f70b454, 0x28bcaa67, 0x7d203fe3, 0xefdf3f68, 0xe108bf31,
-       0x5d7bf2e4, 0x369af3a6, 0x474332b5, 0xe5d5be7a, 0x7f907947, 0xc45dffbd,
-       0x30e7e1a7, 0x40e7ddf6, 0xce38c00f, 0x39bc5bfc, 0x0df91f48, 0x0ea53f4e,
-       0x5c81c4a6, 0x039857cb, 0x298d54d3, 0x98e34c4e, 0xe5ecd303, 0x9daa7f42,
-       0x2783fa45, 0xf7c34f27, 0x9f9bf3c4, 0x17db14fc, 0x927d912a, 0x9bf29e89,
-       0xee82fd5f, 0x28f3f9c3, 0x5b5bf74e, 0x39dd8b34, 0xff9ac1ba, 0x9f359376,
-       0x33e6b111, 0x03f35a0f, 0x7d266d70, 0x1e1eff73, 0x9a7a529f, 0x1e7defdf,
-       0x3c22a060, 0x3e49d9b6, 0xce6d294e, 0xd38778c6, 0x586dbb4f, 0xdceffbbe,
-       0xeadceeee, 0xf72577a4, 0xe2c717bd, 0x6a1df092, 0x3f2c46e7, 0x8d90d71d,
-       0x4fa845fe, 0xbbb04b71, 0x71bb408e, 0xbd06a5e7, 0x69be2986, 0xfdf83fe7,
-       0xf6adce94, 0x9c51c630, 0xd3e4f5de, 0xb7a79f48, 0xec7d200e, 0xc3642979,
-       0x70f7437e, 0xf3884ffc, 0xe954e458, 0x7e3dab16, 0x1d01e842, 0xe879b527,
-       0xd6b8ba17, 0xc24beeba, 0xa8a77cd6, 0x7d331b7f, 0x10f8c74f, 0xdc34aaef,
-       0x7ec53767, 0xc173fdbf, 0xa53d4f17, 0x8b2b7419, 0x37991ef7, 0xe2befba5,
-       0xdb73eeee, 0x8e800325, 0x4316114a, 0x4697bfba, 0x0f85db8d, 0x38927fd1,
-       0xadfceb2f, 0x5539f04c, 0xef896455, 0xaafbd2e8, 0x4d53697c, 0xed4151fb,
-       0xd27c94be, 0xdca5f757, 0xca67da66, 0xb9481eb6, 0xdb6bfa19, 0xebefd0a2,
-       0xe279cd95, 0xf8490981, 0xf9c06e5d, 0xe7fa3962, 0xf25e1ada, 0x8bd03d60,
-       0xbde39ac7, 0xa5c76b0a, 0xe9f1354d, 0x834ba5d7, 0x0e74ca9f, 0x5a72e79f,
-       0x461ef172, 0x1dff2d69, 0x1b86d2be, 0xe11abbae, 0x4fdf9ebe, 0x9e5856cf,
-       0xb653fc0c, 0x8fef86fd, 0xc7c1ef86, 0x3e70f9c6, 0x2d24f8d9, 0x3fadbbde,
-       0xee76f743, 0x44ff71b5, 0x7b465c34, 0xfdef7e38, 0xe508ab81, 0xa2f7f412,
-       0x3fb52c6d, 0xe47d0368, 0x6bd0e4c4, 0xd3954337, 0x570fe1ac, 0x95965c53,
-       0x253e809e, 0x373ab7d4, 0xf48dbe4b, 0xb5f67975, 0x97fb5aa8, 0x943a3c51,
-       0x8a37b4c7, 0xa27ed6c3, 0x47a57cf1, 0x68f77e32, 0xa25e99a4, 0x119df5eb,
-       0x2ab7dfa2, 0xcd720a5b, 0x1d97efa4, 0xd878a1ad, 0x19c871e8, 0xc13b8a68,
-       0x7c4bd1fd, 0x027a14ec, 0x22d91c93, 0xcf287c5e, 0x48a7bbd3, 0xa5104097,
-       0x5ea9b297, 0x6cb5eb84, 0x4bcfa63a, 0x99640791, 0x33f203cb, 0x79278b6d,
-       0x3eb7a6d0, 0xa3a473f1, 0x1e74d1fa, 0xefdc5fd6, 0xe846f36e, 0x77e358bd,
-       0x9e74da71, 0x5276692f, 0x8fe9d53c, 0xcb979234, 0xeb138e30, 0xd9b4ed3f,
-       0xbd3b5f40, 0x8c64efbd, 0xe06b6e0b, 0x6a9f8aef, 0xfb593be8, 0x9a37fd8a,
-       0xf17d8def, 0xdf13fe08, 0x8bf8f54f, 0xacdfb83d, 0xa9d371e0, 0x2a332b7d,
-       0x68c9e063, 0x6655a497, 0x79d2bda0, 0x91b7cbab, 0x0ae953eb, 0xc8d3ddf9,
-       0xfc2f92af, 0x79e9f749, 0xbea07877, 0xe1faea1b, 0xe5073eff, 0xfc77e88d,
-       0xa1ddf640, 0x1f3eed0f, 0xa015905f, 0x03f4e3fb, 0x7cfe3036, 0xa0144585,
-       0xafb8f9b7, 0xc93ca18c, 0x25ebf9cf, 0xb05c238a, 0x7c1ebac6, 0x1fbcdae7,
-       0x292fe116, 0xb0b8c50e, 0xd68b4a06, 0x718bcb5b, 0xbc50f0ff, 0x94cbc517,
-       0x19cb59d4, 0xad1f908b, 0x7b4bfeac, 0xca7db82c, 0x6bf9f58c, 0xa3b9163c,
-       0x50f9dc92, 0x95f5a3ce, 0xd20037a2, 0x1cfec49b, 0x6d2733bc, 0x4b1da401,
-       0xc82da427, 0x7cee7bc4, 0x8ed3231f, 0x8fbf98f8, 0x45953a57, 0x7177f106,
-       0xa58fee18, 0x346452cd, 0xe42c1de6, 0xe3bfcb19, 0x6eb820fb, 0x63313df3,
-       0xf35eb8dd, 0xc726f677, 0x10cf71ab, 0x2f2e6bd7, 0xab287013, 0x3afc5bb7,
-       0x90a5ea13, 0x7f78dbfb, 0x55da95a9, 0xb7697e34, 0x5ff62bf4, 0x1399b7d8,
-       0x68a135f0, 0x798b8c83, 0x878e4ba8, 0x0f75892f, 0xdf80b0e5, 0xf4143743,
-       0x107d7e43, 0x02fecff5, 0x9f2439c0, 0x45809f84, 0x5c5e301c, 0xca9e5766,
-       0xfcf397b3, 0x8ae04f3e, 0xaf6081da, 0x873a01a9, 0xbde72f9a, 0x471bf78c,
-       0x425e0626, 0xf9b7ccbc, 0xb7c42b07, 0x17e411fe, 0xf0e1ca5d, 0x4bcad8f0,
-       0xc5d9632a, 0x933fbf02, 0x3e5ce81a, 0xa3ef8bb4, 0xd54eacee, 0x8bfef7ec,
-       0xfb094790, 0x4f5ee95b, 0xee890ee7, 0x1d223f13, 0x8fb6fba1, 0x6865e95c,
-       0x9e01a7c7, 0x223eee50, 0x5ef815b1, 0xace3565e, 0x9e212f45, 0x787ce2b3,
-       0x38de5fde, 0xd1772e49, 0x15beb9fa, 0xcf01b95f, 0x8de75283, 0x0e748b1c,
-       0x2d779eeb, 0xe3d0ff7c, 0xb9faf1a5, 0x96d3de38, 0x8f17d287, 0x16f3f1c2,
-       0x387c84bd, 0xa1ee8e3a, 0xdcac02a7, 0x8d5d287d, 0xcb1a547a, 0x60fa87d8,
-       0x58ef0cda, 0xe43fb9f4, 0xdb24e3e1, 0x50b379e4, 0xf3cb1bcf, 0xf92c7e7d,
-       0xae111237, 0xed5271a5, 0x17ce3a6c, 0xe85ea3bf, 0xcb823f40, 0x9529ef84,
-       0xea7e3819, 0x69269e50, 0x3c0f8a11, 0x99bde064, 0xd12de9c7, 0x25e9c919,
-       0x454a4c5f, 0x1b50ee3b, 0xbf20d418, 0xec340d0e, 0xf48b88cc, 0x792361f0,
-       0x2df7617d, 0x5ff7e0c9, 0xfa1b0692, 0xa1d7af0f, 0x513213fa, 0xf5c1beae,
-       0x7e5c4ff1, 0xa65f57f2, 0x4fbf8ec5, 0x0a78e048, 0x61638b9e, 0x3838ff93,
-       0x13d233fb, 0x2c3ce783, 0xf027da6c, 0x1c734dbd, 0x7ed15977, 0x72841dfa,
-       0x01f742d6, 0x71ac1bca, 0xc5c597e7, 0xf3a0d71e, 0x0b1b39e0, 0x1e3225f5,
-       0x21d7f688, 0xc2d573a9, 0x4b17ba24, 0x73c13be7, 0xc6990b1a, 0x63eb9e0f,
-       0x33cd77cd, 0xaee9fa85, 0x9af5acc7, 0x2c7aa73e, 0xe383d5a7, 0xb4adebb4,
-       0x29cf048f, 0x6fd8ced4, 0x90b6c23a, 0xeedcfc0a, 0xe21de5e5, 0x6fa8cf3c,
-       0x5b3ed7f4, 0xf8def713, 0x556de8bb, 0x2e007820, 0x219f368f, 0xf359747f,
-       0x418b823e, 0x89f0dd0f, 0x7c132167, 0x225baa52, 0x69ede036, 0x7bb86e0f,
-       0xc990d814, 0x871f05fb, 0x9feddd36, 0xbbf8e508, 0x8ebe260f, 0x73e2eacf,
-       0xd90f3312, 0x42172e64, 0x9d4f7775, 0xfa8bca68, 0x9b43ed5d, 0x340a98af,
-       0xb78a3595, 0x27c1e6bf, 0x4e4e595e, 0xdf111a8b, 0xcf3839df, 0xa23bca6d,
-       0x8fc82ef2, 0xa8f5e536, 0xf2a8a4f2, 0x40fca8b4, 0x1dcdbf5e, 0x40fb2c19,
-       0xd4f83fde, 0x9efbf815, 0x7322fd6d, 0x358f05f1, 0xf02bb6f2, 0xb3cb7cf7,
-       0x56d3eff8, 0xc93e4b34, 0xba2b3f24, 0xb55bf3ce, 0x0e10a3f9, 0x1ca32f2d,
-       0x74926b28, 0x0d5debd4, 0xc79423db, 0xbb535e76, 0x963f6e06, 0x76a11c35,
-       0xd23ff6bd, 0xef7c7c46, 0xdea9f7c8, 0xd89fcef9, 0x5befeb0c, 0x751e76f5,
-       0x4e2c0a44, 0x7f7eee48, 0xdbfb6dbd, 0x0a2fbfdd, 0xf9fbdbdf, 0x8d1c900f,
-       0xc41e07ba, 0xf9bab8f9, 0xbde380c4, 0x7bd2cf23, 0xdd1c7fb4, 0x03aa16fc,
-       0x2cce4bf1, 0x9fdda053, 0x438f8fcb, 0xb4df0b7d, 0x67e37dc5, 0xdc12f852,
-       0x81651e8f, 0x5bdc704b, 0xc3ef87cb, 0xac384c9f, 0xef863eb6, 0xf0786f95,
-       0x98142be5, 0xeb7761df, 0xb709fc20, 0xf06f094d, 0x7f2b727c, 0x1dff4551,
-       0xa0f0e7e1, 0xc83641d6, 0xa6c0993f, 0xeb787e53, 0x3d7f9863, 0x3faf04e1,
-       0xac9075ba, 0xf27209a3, 0xdf90a98a, 0xf7e6c7ac, 0x37ae04da, 0x369bf31b,
-       0x8453ffdc, 0xfbe32b0b, 0x76335e0d, 0x5b9d3c80, 0x66db6a72, 0x1fdcc780,
-       0xdb9c93c5, 0x55dd76dc, 0x50870479, 0xa611c61e, 0x7ed3780a, 0x215d7248,
-       0xee1fa27d, 0xf1ba7d81, 0xe2dc1ee9, 0xd2e2fda5, 0x37a8edca, 0x451dcea4,
-       0xc7a145fb, 0xddc9e92f, 0x52193869, 0x3ae92fa8, 0x8db2eb97, 0xef5223e2,
-       0xf51e9372, 0x033df8a0, 0x0fa23be0, 0x36cbc097, 0x096d9eb1, 0x80f6bfdc,
-       0xf3f51a67, 0xc47fe49e, 0x42ca6321, 0xc5a7f24e, 0xf372be91, 0x202b9006,
-       0x7989d7d7, 0x097b5baf, 0x466e29f9, 0xfc28f13f, 0x67d7efee, 0xbffeb754,
-       0xaef2032e, 0xdd6ebb6e, 0xf33f7f2c, 0x0dbaf6b9, 0x5b90dcbc, 0x7b79d2eb,
-       0xad4abf63, 0x3ea4e3e6, 0x5c46c978, 0x28c2bc47, 0xece17b7e, 0xd1971b11,
-       0xad2d7ffe, 0xfdfdf99f, 0x5a3f0ed0, 0x7a86c43c, 0xc29f81a9, 0x1257fee1,
-       0x89373d60, 0xf035efdf, 0xb74f8c64, 0x907f51e2, 0x3b407f41, 0xeb403135,
-       0x0c627d07, 0xfae06e0f, 0x3316d204, 0xad2997c1, 0xfffbf0e3, 0xfdb53820,
-       0x4ff4e02b, 0xc947779f, 0x0c379021, 0x7a5f2ffb, 0xedff72dc, 0x23d1013f,
-       0x8000702a, 0x00008000, 0x00088b1f, 0x00000000, 0x7dc5ff00, 0xd554780b,
-       0x733ef0b5, 0x9992bcce, 0x924c2664, 0x84e3c849, 0x71100840, 0xf0444312,
-       0x51888431, 0xd4503b69, 0x20717ad8, 0x9926023c, 0x4b62d5a8, 0x79120cff,
-       0x22341809, 0x0281c150, 0x06f55bc5, 0x701a8c45, 0xaf7a8a44, 0xb7ad8ef6,
-       0xff7f6c57, 0x4a8f8808, 0xd2f5a232, 0x5ad7fd97, 0xce64ef7b, 0xb6b4a924,
-       0xdc3ef9bd, 0xd9cfb3ee, 0xd7b5ed7b, 0xf6b5af6b, 0x4cf5a61e, 0xd8c05c0a,
-       0xce6a2566, 0x7c2c64ae, 0x61edf148, 0x67cf07f0, 0xf7fb193b, 0x95d5a0b4,
-       0xf19fd8c9, 0xe6c60aef, 0x2729bf7e, 0x8ded0658, 0x61cb1823, 0xcfbbf52c,
-       0xd500ded4, 0x7a3f4bb9, 0x3f7c0f7c, 0x8ca97bf7, 0x43ef03e9, 0xf7c18c8f,
-       0x5b6dbcef, 0xd2842ecf, 0x793519d2, 0xf986bca0, 0xef7bc056, 0x27435898,
-       0xbe0ef7f4, 0x5563097a, 0x35e5bbdf, 0xdbb19136, 0x93632a5d, 0xf8ab5b18,
-       0x258a9873, 0xbbe0db0b, 0x644b2cf0, 0x7d63114f, 0x0cd85311, 0x23b875fd,
-       0xb8c1175b, 0xf995d71d, 0x1f5fd0c2, 0xef867e63, 0xf7a54b2d, 0x4c3ddc3a,
-       0x744bf6c3, 0x0ec24017, 0x19faa17e, 0x5a37e3d4, 0x7814bb22, 0x76c2ce5e,
-       0x3e325f6c, 0xf3fa8612, 0x7f7d0e30, 0x0f644a63, 0x8f82cfb6, 0xa371dea0,
-       0xfe861237, 0x47622cec, 0xfa763a78, 0x8c1c3273, 0x05acaae5, 0x8228efe1,
-       0x2b59943a, 0x0701cdd9, 0x713fcfe2, 0x0f007396, 0x6899775f, 0x3d95a93e,
-       0xf437ff4f, 0x7ddbd6c7, 0xe1b0a063, 0xcf6f58ab, 0x3b997826, 0x66f88558,
-       0xb803fc1a, 0x89c81fea, 0xcce7c3ac, 0xb1eb8557, 0x479fe9da, 0x5520fff0,
-       0xb61ff847, 0x0ab635b3, 0x66d61528, 0x0bfc00cb, 0x43fb5878, 0x37630c00,
-       0x978000e3, 0xd670d7ff, 0x2bf3c3a9, 0x07ad0a5d, 0x556df9fc, 0xbc67cd8c,
-       0xd4f2fe7d, 0x58899577, 0x1a6b51aa, 0xa5735b3c, 0xef46c7bf, 0xe28f3fb1,
-       0x0bfa0da5, 0x25b7f132, 0x09ba44ee, 0xd86977e2, 0xba9defff, 0xfdf0eb03,
-       0xf8765c44, 0xfbe074be, 0xf9a3173a, 0xfc3955cf, 0x475535ac, 0xc8fc4afc,
-       0xd7c24eb2, 0x713f90fe, 0x724e393c, 0xfcbaf7bf, 0x00be2237, 0x0f74d1ef,
-       0x75a545e2, 0x63d7864d, 0x43b06f89, 0xd556dcfb, 0x33e0377d, 0xf349ccb8,
-       0x9cdef095, 0x158cbf1d, 0x74ffee0f, 0x8695736a, 0xe9c65ff3, 0x02b72d9d,
-       0x62f112e2, 0x5d03a819, 0x63f1642c, 0xe7886526, 0x8445f45a, 0xc247517f,
-       0x2fdff4f7, 0x49ef89ac, 0x92ba617e, 0x2ba0bf04, 0xdd70d15d, 0x375f0a82,
-       0x373e258b, 0x6e183650, 0x82d5cf89, 0x245d24ee, 0xe2357be3, 0x7c60d27b,
-       0xf93d2c7b, 0x99706fd8, 0xdc94f095, 0xfa11633f, 0xf03b21ee, 0x16ddd00f,
-       0xdd7a2145, 0x646a5772, 0x3da7f225, 0x19f117be, 0xad157c3a, 0x1492ef77,
-       0xdb2bc19d, 0x9441302c, 0x9c9d8733, 0x4a7a4b8f, 0x617a9f90, 0x9f587ece,
-       0x9dd5d7de, 0xc1024561, 0xeaebf358, 0xdeffa42e, 0xfde6af67, 0x19d548ac,
-       0x618843d4, 0xfe143718, 0xbc032b43, 0x2cc5349e, 0xe0175e34, 0xff09c257,
-       0x435fe17a, 0xe8bc80c5, 0xbf1c06c3, 0x9807cb8b, 0xe71a12e1, 0x1d6c29db,
-       0x526cdb8c, 0x6f6826fc, 0xb23e3a5e, 0x4361c392, 0x20146a3e, 0x9b589b35,
-       0xf7c03152, 0x2513a6cd, 0x36f195b7, 0x85bbde0d, 0xf78175f1, 0x5f002a8e,
-       0x4c7d6da3, 0xfa45ba45, 0xd8a5f687, 0xff80345e, 0xf9bff5e6, 0x7cdfc213,
-       0x8d1748c0, 0xb1e7198f, 0x8a9e9134, 0xb524e806, 0xd589e392, 0x8018c8b0,
-       0xa9ea29d7, 0x8a88b1b5, 0xcd565a78, 0x66e9024e, 0x8199e91e, 0xecace3f4,
-       0x0ca1f364, 0x11fcc07d, 0xf74a7b80, 0xc24697ce, 0x58daeefb, 0xb4374e3e,
-       0x4e8bb6ec, 0xbeb0345d, 0xba4bce12, 0x41cca937, 0x0077d1e3, 0x83bf7f8a,
-       0xfb371bde, 0x6ef2c482, 0xa4d32efa, 0xe0f6bd12, 0xcd1be423, 0x38c0a39f,
-       0x328c979b, 0x82a67ae1, 0xbcb9437c, 0xaeec7db0, 0x7f678415, 0x07b7ca09,
-       0x09ce80d3, 0x942abe9f, 0xeaeea52f, 0xbfa0bb5f, 0xffd5dca7, 0x138e258d,
-       0x47f4e270, 0xa648be90, 0x23bd64e7, 0x6e2ecbdf, 0x0c716f29, 0x17f01eff,
-       0x35be2de1, 0x4d0fcb9d, 0xffa2faa1, 0x475cef30, 0x374469f0, 0x222f6db7,
-       0xdac0dc79, 0x591ade89, 0xbbf482c4, 0x69c2c6c8, 0xe08b1740, 0x172874b5,
-       0x3d32b16f, 0x4496fd61, 0x2146f58c, 0x31616e0f, 0x7d96fefa, 0x2c35ed49,
-       0x26f684ea, 0x62a68b1b, 0x6f6c69d9, 0xef417166, 0x3e26b67f, 0xbe7c1d67,
-       0x77758b37, 0x20d444d7, 0x1dab7bcc, 0xbe065774, 0x33eb4ed0, 0x5a4ef965,
-       0x7f0af4cf, 0x4fa83dd1, 0x76fb355e, 0x27bedd01, 0xe7e24bd6, 0xbbf5575e,
-       0xd514f788, 0xdf8ff344, 0x9cfc2563, 0xeb8dbd02, 0xdd9b9f7f, 0xdeca1b3c,
-       0x7a3bdd56, 0x55c9a234, 0x1839db30, 0xb39eebcf, 0xb8dd2037, 0xb7c226dd,
-       0x65cc7e7c, 0xddd57aa6, 0x522bff02, 0x088abb23, 0x9e9113dd, 0x7d4946aa,
-       0x82ce26ca, 0x5666bbfa, 0xe6f509d7, 0xec411deb, 0x07ed07af, 0xb9b817a8,
-       0x5b7028de, 0x2eb27e68, 0x06e92be7, 0x52fea1c6, 0x84a5e22e, 0xc85b8c63,
-       0x7f89b641, 0xe6eff427, 0x493b2925, 0xafd3f6ff, 0x96fd1189, 0xd7882c05,
-       0x795c84e7, 0x3695ca4e, 0x9a2b972b, 0xa832ee6b, 0x9941f73f, 0x95e01d6f,
-       0x83de8295, 0x4a3f1bef, 0x5e9e91d1, 0xef5fe8f9, 0x9fb419fd, 0x5ba2c0fd,
-       0xd2017da1, 0x73dbac18, 0x6047970a, 0x8fd4307f, 0x38f6c08d, 0xb1c1e36e,
-       0xb41c7f64, 0xc846fb08, 0xe0b4c6cf, 0x4fd085d6, 0x3e9993e3, 0xbcf664a0,
-       0x5ee8f239, 0xf7643f6c, 0x1b7e81ed, 0x1b5e3853, 0xdf491b9f, 0x4e0f613f,
-       0x733cc377, 0x3c9f91ad, 0x05e37281, 0x677bd92b, 0xc2117459, 0xaed3b67f,
-       0x70277be0, 0x4250e95e, 0xeaf3829b, 0x043d9276, 0x10b39a7c, 0x36b93bbe,
-       0xe04bcf9b, 0x0986e4e9, 0xcd9b17c4, 0xb3f0bc7c, 0xc27fbd0a, 0x0391981c,
-       0x974f13f5, 0x534056fb, 0xb512c05f, 0xee873d00, 0xbd5e76e3, 0x7881df49,
-       0x09538762, 0xa11eb95e, 0x62678b8d, 0xf2e9687b, 0x1c7ca3af, 0xde51cf8e,
-       0xd9b904b3, 0xc805e2cb, 0x461adb4f, 0x9f514675, 0x91f38f74, 0x585e655a,
-       0x171ba07c, 0x9994f77f, 0xc87e35e3, 0xbe7cf44c, 0xb57ce3fd, 0x707fae2a,
-       0x65c8109c, 0xe48ff926, 0x1d5d4272, 0xfec8ceaa, 0x2d973d0c, 0xfb633aec,
-       0x1de0ceeb, 0xe6bfa06e, 0x9de7fffb, 0x38df8465, 0x9ed645c9, 0xca797c49,
-       0x748b9fec, 0x5a89aeeb, 0xf3e827e6, 0xeaaf820d, 0x63fec2ad, 0x1f224b51,
-       0x6aaaf6ca, 0x72cbdd23, 0x677fa0bd, 0xc1f7cb8c, 0x1fc126ed, 0x1ea2b4df,
-       0x6641c29b, 0x1c47a885, 0xfd4ebfd8, 0x6a20f94f, 0xe17a87a9, 0x9165a8f2,
-       0x004f9128, 0xcc1b51df, 0x2756d4fb, 0x03406fe7, 0x3268b3f6, 0x48b97d23,
-       0x02b5fb05, 0x3d5deb9f, 0x9fa72eb0, 0xfafa7376, 0xf0056023, 0xf7898f3d,
-       0x82ef60ac, 0x4da67b1c, 0x607ee289, 0x2eeb16de, 0xb5f2117b, 0x7ae2755f,
-       0x8e48576e, 0x569b6bcd, 0x4bea15b2, 0xeb405c0f, 0xd399369f, 0x9b88d2e5,
-       0x2114e2f4, 0x11adeb1f, 0x3fdfd90b, 0x01f21851, 0x74764ff4, 0x53947c23,
-       0x280f1831, 0x10f40dd7, 0x5d83a849, 0xcb93a534, 0x9cf20655, 0x524bd825,
-       0x671ca3de, 0x919ff649, 0x1f52c23e, 0xf4c7b971, 0x527b946c, 0x0aebdf2e,
-       0xae49b974, 0xf5c6ce8d, 0x72e4f585, 0x7842bf73, 0xa42d626d, 0xe81ea44f,
-       0x91e8571f, 0xeb986ad3, 0x2a26eb2b, 0xd117775f, 0x27594b78, 0x57a913e9,
-       0xd783a386, 0x7e0e84bf, 0xed007486, 0xe8b01f8d, 0xe35e3065, 0x9a6d1672,
-       0x44e74bc8, 0x4f5c8fd2, 0xc49eb8da, 0xf43ce532, 0x4c7eb265, 0x7ac987d6,
-       0xf5c2db30, 0x69675c9d, 0xe74f64cf, 0xe594c076, 0xfcc19511, 0x3ff9a636,
-       0x60349cce, 0xb2de84d7, 0xb10bf4d9, 0xe0a3601e, 0xd369c5bd, 0xf686ca6e,
-       0xc8fcc690, 0x9780a957, 0xbb7cf09d, 0xb36b7bb0, 0x2d7bdd39, 0x5acd7e9c,
-       0x703b9580, 0xcfb4625d, 0x1732678d, 0xe7c4a3d2, 0x577c2776, 0xfd71df81,
-       0x8dbdffd4, 0x7c24a5b5, 0x9d9cfd5f, 0xcfe7eae4, 0xb256233a, 0x6e858247,
-       0x57eb2fe8, 0x7b53b256, 0x3e92739f, 0xd0fa15ed, 0xd128f683, 0x5fae2acb,
-       0x21275d71, 0x648f5535, 0x35cafb48, 0x4a045123, 0xcdc9acfb, 0xf6c1aced,
-       0x8a2f6890, 0xcae9cf5d, 0xcfccfb4a, 0x62773ddd, 0x6861e01d, 0x588fff9f,
-       0xe981d0e7, 0xe787dfe5, 0xc7c380a1, 0x472c1fb1, 0xdfaab57a, 0xf406deb9,
-       0x1e5d4335, 0xd1e60bbf, 0xa170ef94, 0xfc29ab9e, 0x846f2ff5, 0xcc0787fa,
-       0xbceb8acc, 0x1b1d7a67, 0x5dfcbc35, 0xe89f3112, 0x5b97e049, 0x4deb19f6,
-       0xa87ac69d, 0xc82f58cb, 0x4f4e7a70, 0xfbe1d920, 0xd5b5d033, 0x4ec1f2da,
-       0xbcfad780, 0xa7d1f495, 0x067160ee, 0xfc535bca, 0x5ad9e218, 0xf444f1f8,
-       0x3fba846f, 0x02b4b051, 0x38cac4ed, 0x3faf91fe, 0x742bcfb7, 0x01b7810d,
-       0x899b31fc, 0x3ad60cf0, 0x85ce492f, 0x2c789f04, 0x845f0ffe, 0x9d9a2ff9,
-       0x9e9bbae2, 0xaa4e67f8, 0x60927b42, 0x572da164, 0x2dfb887f, 0xae096f78,
-       0xf059e9ff, 0xb0d5c01e, 0x46c3eb85, 0xbe434b16, 0xd3bb066d, 0x477c4b06,
-       0x5b875f06, 0x5155e2da, 0x8c8edff8, 0xa70871da, 0x802d27f6, 0xfb1ab1f4,
-       0xaf93b04d, 0xe07ae0cd, 0xd7767d96, 0xdd1e0329, 0x2ba87a86, 0x912a75c7,
-       0x61fc84ff, 0xb8968a79, 0x09577a1f, 0x6bf88b5e, 0xa658f5b2, 0xfc57f8c1,
-       0xf79233e9, 0xa7cd978b, 0x5d80c47d, 0xb4f9256d, 0x3d20aef8, 0xdf2b697f,
-       0x6ade9e17, 0xa7ef11d7, 0xe3fdf3b7, 0xc4473ce2, 0x857bff06, 0x8bdbdb9b,
-       0x19453be1, 0xbc64c78c, 0x55f0ffbd, 0xf7a3a45e, 0xdc2f1f19, 0xf78fedc9,
-       0x62af805d, 0xf7f60efe, 0xefd8177e, 0xaaf9e20a, 0x2e2e510f, 0xd0faaede,
-       0x9c87604e, 0xbc598fe4, 0x0b71cafd, 0xa7dfd81d, 0x5fa1a623, 0xe895c768,
-       0x02f7c289, 0x89d7ee11, 0xb5cf015d, 0x1d93171d, 0x95bb7477, 0xedb6e9c3,
-       0xf15c79c5, 0x4af89527, 0xda20b133, 0xff161dc7, 0xfd67e438, 0x70333de1,
-       0x959fde5d, 0x1ff7a26b, 0xf10b9857, 0x85965ee1, 0x5a2b17cf, 0x61b7f900,
-       0x899992cb, 0x866a4ef6, 0xad35eb4a, 0x8f567970, 0x7ae9f883, 0xdb4da3d4,
-       0xfc707f81, 0xf2ff6fd9, 0x3f224f46, 0x4cc55edd, 0xc3cbf609, 0xc27a235f,
-       0x6be028bf, 0x57d7c0b1, 0xaa6b2be5, 0x12968be4, 0xef8ba394, 0x0d71296e,
-       0xf3f45761, 0x0f9cc3c5, 0xb850cbef, 0xc32f20ff, 0x6e18cfb0, 0x3528e65f,
-       0xf9b15e91, 0x940f7f98, 0xc62db0d9, 0x0c81f7fd, 0x640fda8d, 0xfb5f7b70,
-       0x5efb6ddd, 0xcd4d7987, 0x80cf6e08, 0x97f3217a, 0x71ebbae3, 0xb1983557,
-       0xbbb26288, 0x6e56c3d8, 0x8edc6ac7, 0xf6c99cde, 0x8fd84bae, 0x997f6277,
-       0x62f61724, 0xffc7bd3f, 0xdaf10c78, 0x44f1f05c, 0xe7420fb4, 0x1fa0b33e,
-       0x90add1cd, 0x02f8773c, 0xd425e90c, 0x282d8b3d, 0x21c3901b, 0xc913d71f,
-       0x0653faf3, 0x3c84efdf, 0xfde7ea71, 0x3b7f9c11, 0xb73e9cdc, 0x3f214b2d,
-       0xc44f36e4, 0xb5ff408e, 0xa5ed2a7c, 0x67efc225, 0x5f94fddb, 0x288efa45,
-       0xd75831ae, 0x35f47f39, 0x30a88dcc, 0x8bbb87ce, 0x77d9dfc9, 0x854f9a60,
-       0x1feec736, 0x788519ad, 0xf0fb32ea, 0x27af877d, 0xe1f7e70d, 0x386993ee,
-       0x2add86bf, 0xf221bbcd, 0xb2c2d649, 0x33f0b901, 0xca3af825, 0x1c52e601,
-       0x0f94be38, 0x34feee1f, 0xfb83816b, 0x567f480b, 0xa7978d0e, 0x8e7ed3dc,
-       0x39715fdf, 0x1e8f975f, 0xee5046b7, 0xfd07647d, 0x3f6f2096, 0x777d7272,
-       0xefee432a, 0xdf500b3a, 0x2a6fd7f4, 0xf89ca135, 0xdfcf8b8e, 0x402ce963,
-       0x628dfc7e, 0x1ae967ec, 0x6c808b13, 0x5006b25f, 0xa3e8f203, 0x40299f47,
-       0x9ee1ff79, 0x27e60a67, 0x9dfc97c0, 0x78e57b2c, 0xfd266fc2, 0x344b1ea8,
-       0xef9bc70f, 0xe57f72b3, 0xf9547e30, 0xfdc2db3e, 0xab3e7da1, 0xbf28748e,
-       0xf1486beb, 0xc7db7da3, 0xe6ff246c, 0xacbf0b77, 0x83da3fdf, 0x7df918fb,
-       0x1e15ff52, 0x974a4f4e, 0xd483fe42, 0xe3c938b2, 0x7bde59bf, 0xe4133d60,
-       0xbff3ac3d, 0xd9345f21, 0x3246c7e2, 0xe20b0fa2, 0xd0ecd2cd, 0xad653f50,
-       0xbf15f4e4, 0x2afb44c3, 0x81d7ae4b, 0x928aecf2, 0x30133694, 0x6d2527a2,
-       0xf201c622, 0xfde94b73, 0xfba73570, 0x7f231670, 0x516b0e5b, 0xb8bb5e48,
-       0x326f3edf, 0xea83ad73, 0x9edc11ac, 0x16df32f1, 0x5dd698b5, 0xc490ff41,
-       0x480bd487, 0x3f1f283f, 0x3f446c52, 0x7642b74a, 0x9cea6aa7, 0x470efd8b,
-       0xc847134f, 0xa7a73ffd, 0x893ffafe, 0x188f269e, 0x3a829e8e, 0x36d793d1,
-       0x3f093d34, 0xcfbf79f1, 0xbfdc01c2, 0xdd7c0b66, 0xfc4ee427, 0x9bf49b0e,
-       0x99df382b, 0x3699bfa2, 0xfd455447, 0x9c7f33e1, 0x187dffe8, 0x27dc5fec,
-       0x0efda0e5, 0xf395c8e5, 0x16375a74, 0x417f41eb, 0xd236c5ea, 0x629af78f,
-       0x64af6845, 0x8fd96f8f, 0xb73d9174, 0xed2562ac, 0xa8dcf2ff, 0x92b7500f,
-       0x7559741f, 0x0488d4e0, 0xdf10e17b, 0xe5df34cf, 0xbbd3e7a7, 0x1a107db9,
-       0x387b216d, 0x7184a5d4, 0x96039b9d, 0x6b41da08, 0x095fee15, 0x3cebb06f,
-       0xa0afa3ee, 0x740fcfb8, 0x488a171e, 0x8ecf6fff, 0x35bd23ef, 0x91efc838,
-       0xf83a3f1c, 0x1fc7ca85, 0x8efc68c3, 0xeaaf1e72, 0xfee75ab8, 0x1d7eb115,
-       0x6e39fcb3, 0x18d607b4, 0x85c659f9, 0x18809cfa, 0x7afe6f18, 0xae43ad3b,
-       0xd2ccf1ca, 0x0cff5c6d, 0x67e40b96, 0x162c9ace, 0xfa6fc446, 0x05241cf9,
-       0xbb4573d6, 0xcb39378c, 0x79684502, 0xb7e9bbbf, 0xbd00a4af, 0x8e9fa166,
-       0x68c2ca6f, 0x987f93f7, 0xfc7dc9d7, 0xc90009a0, 0x5cffd6c5, 0x42697357,
-       0xf03fbc5d, 0x6b6bdcfd, 0xf6ef48f2, 0xa0d823b7, 0x6fdd658f, 0x351e31d7,
-       0xbd81aed0, 0xf852eb6b, 0xb5c761f7, 0x3c068e57, 0xfffc7228, 0x7f47eb5c,
-       0xc6199da1, 0x4b4f844b, 0xfd0cdfea, 0x7ef9743b, 0x784af6bc, 0x590ac1e1,
-       0x1fad66bf, 0x6ccfbbe0, 0x2a508fec, 0x1c8ac7be, 0x6dacd6ef, 0x0de7d6eb,
-       0x276005d8, 0x39911aec, 0x7eac1f60, 0x85fb667b, 0xebaa5630, 0x5dea0b53,
-       0x1e43e7a9, 0x648fec85, 0xe4203d7e, 0x572cdfc3, 0xf47641f5, 0x57241181,
-       0x4b20667b, 0xe483fec2, 0x80796876, 0xf6073da1, 0xdbc21748, 0xd3e3fc7b,
-       0xef7b422f, 0x1b1fdfec, 0xb77be3a9, 0x37bb45ce, 0xba234e74, 0x2353ed0d,
-       0x4dadd00a, 0x71e80bf0, 0x7a480b8a, 0x7412ea5a, 0x8c330eea, 0x521c7473,
-       0xbe898526, 0x83ae0a5a, 0xf8f7ccb5, 0xe438425f, 0xde7932be, 0xf7c11ebf,
-       0xead2a10f, 0xffd825ad, 0x9da1856e, 0x44f4aeb0, 0x37da02d6, 0x30b59bbd,
-       0x5d25bbe1, 0x973e120f, 0x890f33ec, 0xe08f5fc7, 0x67e6de71, 0xdca3f69f,
-       0x90a228f8, 0x22d0684c, 0xbd40a76b, 0x9684c1a1, 0xcc8cab20, 0x1ce291bb,
-       0x06361675, 0xed0477e6, 0xdf638426, 0x7053c337, 0x814ff0de, 0x8b02db47,
-       0xab6e9f48, 0x4e2839b3, 0x56ff3a54, 0xc52b83c2, 0x5758788f, 0xe3839d5a,
-       0xe19acf34, 0xd808f8a2, 0x7cded871, 0x2fc8b7d7, 0xd75ae124, 0x3b45ae65,
-       0xb9ec0aa7, 0xfcee00a7, 0x7d6a6b8c, 0xd523c7c0, 0x3bb7e5fd, 0xb43e5e30,
-       0x266eff1c, 0x25368ba7, 0x2546fe10, 0xa25941f9, 0x8bb0b35f, 0x8d9f8ddb,
-       0x2be218b0, 0xf6e08d9f, 0xd8e1a5ec, 0xc39f2474, 0xda2a4f5a, 0xffe621d3,
-       0x2ccff704, 0xd0f7d0e0, 0xe479713a, 0x3fc9d569, 0xdcf4f366, 0x5fb6217b,
-       0x85fed1aa, 0xe00f3d69, 0x3d6bbdb8, 0xf04c75be, 0x2aefd601, 0xbd4f7da3,
-       0x3278a827, 0x7d70bcf9, 0xaabd9f7b, 0xd288fd1c, 0xa8fb5aee, 0x5ae6f49d,
-       0x2d7f7ea7, 0x69dfd3ca, 0x16c01f3c, 0x7e874d8f, 0x833efe96, 0x8f6b5dc6,
-       0x0ff5c5ac, 0xbda954ef, 0x607411d8, 0xb9be4bbf, 0x2bd22265, 0x504a4473,
-       0xed3d9a8f, 0xb618e90c, 0xb12fe42b, 0xe30c0279, 0xf3c3d3c4, 0x45f50534,
-       0x1d333d92, 0x5fb455fd, 0xb6bf90f1, 0x18c7f05a, 0x36d382a0, 0x3fb68562,
-       0x6fb0188f, 0x1ce3f95e, 0xbb4a1f0d, 0xfee364c7, 0x14ba9af3, 0x5b2df686,
-       0x42663f15, 0xc627bd7f, 0xea6e0ed0, 0xa69c6854, 0xb82d27d2, 0x93a5b96f,
-       0xec4877f3, 0x057f0033, 0xf18c5768, 0xa07b0aa4, 0x5839fb8d, 0xc448d8ec,
-       0x3d7c63f3, 0x12f78319, 0xad8cabfc, 0xf440f2e0, 0x86711167, 0x0257e126,
-       0x3eed484d, 0xef5bb48f, 0xf3b7fd16, 0x59bb8c52, 0xc455f989, 0xf062b96b,
-       0x2af2cb87, 0x91fa7df1, 0xdfe40cf8, 0xfa17d038, 0xb32ab697, 0xcc29fd6e,
-       0xf1a4eb6f, 0xbcc1343e, 0x056a4e40, 0x0452073e, 0x7d7657bc, 0x86e90332,
-       0xd7e232d5, 0x6a69aee6, 0x6fc78393, 0x4ec85ed0, 0xed89d96d, 0x929737d9,
-       0xc8f8c67e, 0x35fe786c, 0x1cb3e70f, 0x79d7f707, 0x61170eef, 0x48fd33bc,
-       0xe29fd6e0, 0x90a417f8, 0xd61b35bf, 0xe54199c6, 0x796ff41a, 0xa88bf959,
-       0xf533bd7f, 0xc647840a, 0x382e30f5, 0x38e48cab, 0x8a7c33d5, 0x3794177f,
-       0x0e34dc78, 0x116aefec, 0x711e7c5e, 0xd119c40c, 0x62e3876f, 0xdecb0f1c,
-       0x7e46a89c, 0x7be7d07e, 0xacbb4e90, 0xccd7c42e, 0x42df97ae, 0xc6d33b7d,
-       0x9aee293a, 0xd3c4b764, 0x3a4419be, 0x7a733bed, 0xd7083dc7, 0x947d0775,
-       0x8f6492cf, 0xb739715c, 0x93da3fcb, 0xec3f23aa, 0xec1b7212, 0x797f1e47,
-       0x9323ef9c, 0xf6efc8ed, 0x23b72faf, 0x777febfb, 0x17c3923b, 0x28f3c3de,
-       0x890f7ca4, 0xc35f5f7d, 0x5fd434d9, 0xaed23d2b, 0xd8f7ca4d, 0xba3df22d,
-       0xd0f7ce87, 0x0ff8f276, 0xee494186, 0xae222dba, 0x43cef7e5, 0x84bb87ff,
-       0x7b2bc0e4, 0x3748c353, 0x64ed3b67, 0x4b6e6997, 0x7b6ae114, 0x3cc11ada,
-       0xe0453688, 0x578890eb, 0x2c1c4459, 0x834744a3, 0x4025a0e2, 0xa4fc3f72,
-       0xd2abc799, 0x85ee8f22, 0x1ce1e37a, 0xd462cf11, 0x54d9f87f, 0x8a6377c2,
-       0x37fd8e9e, 0x8608fbfe, 0x183eaa71, 0x09f9d70f, 0x87bb707b, 0x7fbc5ae2,
-       0xe75582f6, 0x8968b3f1, 0x33b0f01b, 0x93bfedc2, 0x05a8a6a5, 0x8993bde6,
-       0x32f59f3c, 0xd9e7c5ae, 0x8f2461b7, 0x8231a0cb, 0xdcb5b2fb, 0xe32f545f,
-       0x1fb98755, 0xa5c45eae, 0xf45ece4e, 0xb458a608, 0xb8b52d29, 0xdd7cfb4f,
-       0xdf9ff234, 0x2a2cff79, 0xfd18d7eb, 0x3fd08bfd, 0x3f103c5f, 0xf9f77e96,
-       0xf6e167cc, 0xd0ff80f3, 0xbe8cf604, 0xfd46ab46, 0x775cc459, 0xc3d03ea3,
-       0x43177ab0, 0x1a2506d9, 0x19600af1, 0x7ad6d3de, 0x57bd7052, 0x6f4899b7,
-       0x7e4cdb85, 0xcbd24f7c, 0x67ae1eab, 0xbd70f5df, 0xe08ea803, 0x336cb238,
-       0xe883788b, 0x4533056f, 0xbc2934b1, 0x6ad2ed5c, 0xb2dfd287, 0x8b7336bf,
-       0xcdda1a6d, 0x77f226f9, 0xd7f16e7f, 0xa338bf91, 0xcda9d684, 0x96a6b2d9,
-       0x7d2f13b7, 0xa8078f6e, 0x1b8d32fd, 0x40cf4c96, 0x8782fa79, 0xf19217c7,
-       0x58ddb0b6, 0x2cc38e4f, 0xf5eb1889, 0xa736382c, 0x120dc798, 0xf420bf9f,
-       0x8aebe7c4, 0x167dbe04, 0xfe72bb94, 0xde38f22b, 0x1cbcf94c, 0x875d5f95,
-       0xe30a3074, 0x725845ca, 0x84cc2abf, 0x99751fe0, 0x48fa2147, 0xcdcdb782,
-       0x96bc29e9, 0x5aff21fb, 0xfee193f8, 0xf82593d0, 0xb8c5efd8, 0x42cbbd65,
-       0xf5f3e871, 0x1a64a497, 0xf5fdb7f7, 0x96feffbf, 0xaad7e7ef, 0x45c6bf22,
-       0x8bbe6972, 0xe2a4e5cf, 0xe7c51bdb, 0x701fb00e, 0x0ad56b1e, 0xbfd32394,
-       0x3479a0e9, 0x8239061f, 0x3de5ac71, 0x9bd7a805, 0x304a7bab, 0x5f8c935e,
-       0xf2935684, 0xef9bde0c, 0xda08fd81, 0xf18c6b0d, 0x55f1c1b8, 0x2666617f,
-       0xee4e7bee, 0xd7f5197f, 0x2fe93b7e, 0xad17bff8, 0x16cfffc8, 0x388b5c91,
-       0x2e316383, 0xee894a14, 0xda1171f8, 0x6a8edc31, 0x44eeb6ea, 0x5b7e713b,
-       0xff0f7c42, 0xef18deb3, 0xc8326b63, 0x8c3aceef, 0x4e1e1bcf, 0xfc506efa,
-       0x65d69daf, 0x0e3825b3, 0x10f41df9, 0x599c1de5, 0xbeb86262, 0x116faaf5,
-       0x7633a92a, 0xc67e7da3, 0x466bd7c9, 0x3e3fd4a6, 0xebfabfb2, 0x57d9d683,
-       0x6f5ceb82, 0x7ec4c162, 0x619d709a, 0x3ac51b7d, 0xe2fa799f, 0x8fe75c12,
-       0x825c5ff7, 0xdcd9bceb, 0x29be47ee, 0x41af0775, 0x32ba9cfc, 0xe615f640,
-       0x9d1f20ef, 0x94de3d2f, 0xfd378f44, 0x2eb1e8e3, 0x59321f31, 0xe3f4363f,
-       0x3d1fa8cb, 0xe50f3d16, 0xf59b7cc1, 0xfc49ea2f, 0x679fd21b, 0xe3ff92b3,
-       0xdd3f1ff0, 0xdd18f948, 0xb227d92a, 0xb05ac3bf, 0xc3a3ed18, 0x617d796f,
-       0xd3fef865, 0xb5e5fd85, 0x59fa30b1, 0xda40bee4, 0x78f2c997, 0x03cf98b9,
-       0x8cdffe99, 0x3ce21bf8, 0x20dc7fd2, 0x3e45b1de, 0x6eef76e5, 0xc7fdc7c5,
-       0x6e4fe49d, 0x85cf343e, 0x220fe2fe, 0xfcdc7fdc, 0x8ff93974, 0x8a5e4497,
-       0xeb193e62, 0x1fb85c56, 0xddfbb259, 0x9003cc34, 0xe7d85efb, 0xf9499fde,
-       0xeffdc635, 0x69939107, 0x70003798, 0xa7708fbf, 0xa416e27a, 0xffd866fb,
-       0xb360de61, 0xfd863f16, 0xd9187b36, 0xc65d9505, 0xef8ca0fd, 0x48580b6e,
-       0x56eb6eee, 0xb3af2822, 0x3ca2c12c, 0xcf2c6bd4, 0x80753a75, 0xfe9922cf,
-       0x077e9017, 0x5dfeeae2, 0xa7fe9758, 0x44e9ad9e, 0xe6663dbf, 0xdb3ca177,
-       0x4cf214ea, 0xdbf6f923, 0x7591dd87, 0x6fc37609, 0x584edc23, 0x34c1f322,
-       0xbd60d516, 0x1ff1cd16, 0x7946f5c7, 0xf7924d1f, 0xaf197589, 0x494585bf,
-       0x9eb1352f, 0xc4b0bcfe, 0xf9e392f7, 0xf4370718, 0x75ca5ac3, 0xe4dd93f4,
-       0xab9c51f0, 0x6356cfeb, 0x9bef987b, 0x55961f81, 0x5cafd00c, 0xcdbf4907,
-       0x6a1d1fc2, 0xe90ab138, 0xb8a5d437, 0xe8dd7f70, 0x08dbf4e3, 0x9bcc2ffb,
-       0xd677e64d, 0x1d13cc69, 0xdd7fff8e, 0xff9c77cf, 0x9cac3d7f, 0x5bf8c7fa,
-       0x3f97efdf, 0xfce5ef9c, 0x7fbeffa5, 0xe70add9e, 0x2579a4cb, 0xfd935bef,
-       0x79df72ee, 0x8bf0f2be, 0xf17c7c24, 0x70c7c60f, 0x6b2530f2, 0x7242fde8,
-       0x96afe35c, 0xf8e0ff87, 0x1e8723c6, 0xa881334a, 0xf6145258, 0x6fcebb72,
-       0x50cf1788, 0x371e7e1d, 0x453e7955, 0x9f5ddc72, 0x9ceee221, 0x5a7a5f9f,
-       0x126af5a5, 0x43a6e1f1, 0xdabe1f4e, 0xf14c58e0, 0xe9f8e4d9, 0x067fb652,
-       0x1c72512e, 0xb8f911b5, 0xa9e3cbf8, 0x3d396517, 0x56749f24, 0xc90a7984,
-       0x392f5a79, 0x4c111d3e, 0x32eaef58, 0x410c08d8, 0xcc2d36d7, 0x4f9e1232,
-       0xf4f6e2cb, 0xc89f224b, 0x05e7e16b, 0xfaa673ee, 0x35e31f71, 0x7ca77cf1,
-       0xd67a604f, 0x02ef9424, 0xc0decf9f, 0x4797804c, 0x4f249dcc, 0x1f0e4dc2,
-       0xc7e93fca, 0x10effd91, 0xa5f38b71, 0x19676ff3, 0xfebfbce9, 0x85fbe24f,
-       0xdaffbe92, 0xc016ddb8, 0x181f818d, 0x186befd1, 0x4c1a2a67, 0x33f5c3b7,
-       0xcb2efd1c, 0x459edc0a, 0xa44ff178, 0x94f3e6fc, 0xf195a92f, 0x622fe893,
-       0xfa3aac07, 0xfce26d37, 0x239f5b0b, 0xaabeebf6, 0xcd979459, 0x73c88fcf,
-       0x8fd9c336, 0x9ff9fb1b, 0xf5fd8fdb, 0xc8fd93bf, 0x9c7681dc, 0x7e69a9e7,
-       0xed5ffbca, 0x5f71f804, 0xc875a8f8, 0xdcf22cf3, 0x5df997c5, 0xcdc3f6f6,
-       0xb0ef6ae9, 0xe563ff70, 0x34ff93e7, 0x34fbf9f9, 0xdf0ea3f4, 0x7be4584f,
-       0x9e22fcc6, 0xf82576c6, 0x9e3143b7, 0x8092f7af, 0x447f3e57, 0x6cf4c5e8,
-       0xa75c51ff, 0x6cdb8f8f, 0x9e4c1d2c, 0x9b172e4a, 0x2f8a0e03, 0xbcf27734,
-       0x8ce5e697, 0xfa3377e4, 0xafd0cb4f, 0xbda18b38, 0xf8233537, 0xf57efc33,
-       0x9ab08edb, 0xd9f77e8e, 0xdebbed0c, 0xa9febce3, 0x6c73f83b, 0xa1ef2d0f,
-       0xecc74678, 0xaaef288f, 0xae9fcfea, 0x7824adaa, 0xb1e08fc9, 0x7cadcf1a,
-       0x0fe3c591, 0xbf43fcb2, 0x5f93f13c, 0x9e06e3ff, 0xf8f21d9f, 0x908fe85d,
-       0x3d54f17e, 0xe6a67e46, 0xab68dc03, 0xd87cf952, 0x9e88f3f7, 0x2b4c0f9a,
-       0xeb29ff47, 0x9da397b4, 0x072bf55b, 0xbe3ef7ed, 0x24f2972b, 0x0fc13dea,
-       0x2b3a3e51, 0x5da35723, 0xa0e3085a, 0xfef1fbbd, 0x6e11cbab, 0xa336ff29,
-       0xdfc61cff, 0xc7fa34ec, 0xd9e78d99, 0x4f9bdd2f, 0x4762cbfb, 0x6fec53f0,
-       0x11c39db3, 0xa3ce23de, 0x3279bf08, 0xcfbe4bff, 0x4e344d56, 0x146db7f6,
-       0x6172972f, 0x6d0599b3, 0xe4f203c5, 0xf22e9678, 0x635e444c, 0xa79e2cf7,
-       0x8f0eea22, 0x81f3bf31, 0x238f2bcc, 0xb4b3c73c, 0xe61f96af, 0x402f9418,
-       0x187e62fd, 0x9c5805c5, 0xe7a92dfc, 0xca3d1db8, 0x727a2165, 0x9c51df02,
-       0xed09e806, 0xb1e34bf9, 0x6b9e78e9, 0x52f44774, 0x73e1f3c4, 0x3693c226,
-       0xd38a35eb, 0xbc7c2ba4, 0x6b3df5e2, 0xc61fa2c7, 0xb865e6f5, 0xabbb7aa4,
-       0x353a511a, 0x4d9f9023, 0x52968cfb, 0xbffaaf1c, 0xf29f3ccc, 0x17f92a50,
-       0x291a0a3a, 0x6df7b29f, 0x4e3ce1ab, 0x77661972, 0xa8e4fe53, 0xbc505fae,
-       0x194079c0, 0x72762f32, 0xd6f083b6, 0xa0cd8e1c, 0x3d4b9b1c, 0x43b56724,
-       0xb538a2bf, 0x094356b6, 0x7eccdac4, 0x0b439e13, 0xefe460af, 0x32e1d31c,
-       0x8a157ae1, 0xc3be98fc, 0xa418987f, 0x0f8c8afd, 0x937e7844, 0xee1567b9,
-       0x3d15b4c3, 0x3d718797, 0xcd4db80e, 0xbc5fd865, 0x872dfc99, 0x4fd21952,
-       0xddf15761, 0xb85ea153, 0xb0f145c6, 0x296ee7be, 0xcc2aff24, 0xf310cc73,
-       0xf336ca2c, 0x9aa50ffe, 0x9b699f50, 0xd5470f98, 0x04d559dc, 0x875083f7,
-       0x3c8a467e, 0x453f1955, 0xa9ea143f, 0xd7e0ecf4, 0xffb63f30, 0x14b2d21c,
-       0xe3490e7e, 0xb2e712fe, 0xf3c71fb7, 0xfc2c3b3d, 0xc391e79c, 0xdf936613,
-       0xe0a6ad6f, 0xe6ee7c3a, 0x663794f9, 0x42e70c9b, 0x847ff006, 0x1d4756f2,
-       0x6bd705fa, 0xaff61630, 0x68bd3999, 0xd13b3d6b, 0x2d38b8bf, 0x97ba7948,
-       0x8a5545b5, 0x3d4eb99f, 0xec27ab50, 0x3d70b673, 0xef8fbcd3, 0x35f793cb,
-       0x6e5fa65f, 0x2dda36cb, 0x927ff5fd, 0xfe83f2dd, 0xfdc6fff1, 0xf3ee330a,
-       0xe497ed92, 0x3b20dd7d, 0xe1bfa93c, 0x8f9918ec, 0x0e303d52, 0xd29da7b7,
-       0xf21b0a4e, 0xe21daa75, 0xd8cda17c, 0x5c23e5ff, 0xbf995f34, 0x5f52b593,
-       0xf1fa7981, 0xd7f2301f, 0x70a23cc9, 0x09f7cf35, 0xee746c9b, 0x29dacbd0,
-       0x8b24687f, 0xd3f90a2a, 0x6d7ce87a, 0xc111e636, 0x47b2eb77, 0x99dbbf51,
-       0xf24a8d6f, 0x6e105752, 0x509fe63b, 0xeb646abe, 0x3ae71c22, 0xc7638d07,
-       0x308b93fc, 0x15bfc085, 0x06f4ebe5, 0x05c85f1e, 0x9bf48c7d, 0xa1d39a3b,
-       0xa1e78ebd, 0x99133cc8, 0x50f12217, 0x3b9bf02d, 0xca115176, 0xf04ab5c1,
-       0x99ae7151, 0x4e0dffcb, 0xec195e71, 0x79c0cf6b, 0xfbc63ee4, 0xf898370f,
-       0xaf376479, 0xf9d18c77, 0xf82fa079, 0x728ebb39, 0x2832779e, 0xaf09253f,
-       0xc9e53f32, 0xe411e0b4, 0xcbf3e497, 0xd6124e92, 0x6f47ce8f, 0xfaedc43b,
-       0xcd0b06ea, 0x35c96fa3, 0x5bec97e4, 0xffa86262, 0x9cadbbab, 0xdbc692ee,
-       0x51616756, 0xd88b57ec, 0xf5ca7e51, 0x16bb32ff, 0xfd14b5d6, 0x6b5a47be,
-       0x38053a2f, 0xa01ada3e, 0x74aecfb2, 0xf9d217aa, 0xa928b9d2, 0xf9f2d89e,
-       0xe60e5ab5, 0x140bc4db, 0xb7e79920, 0xea93347e, 0xb077f199, 0xcf16eafe,
-       0xc39034d7, 0x3be2637d, 0xffff7814, 0xdbc47f79, 0x19731691, 0x87a1f77b,
-       0x5f1d8666, 0x91fddf41, 0x9c71e725, 0xc4d3bd41, 0xc8c5567a, 0x5df4245f,
-       0x5e879725, 0x25ec8587, 0x653fc8af, 0x151f2235, 0x5f503b23, 0x714e5399,
-       0x0fd3077b, 0x8f3db0c4, 0x7682cf9f, 0x6395ffa2, 0x26da7fb8, 0x49e582e8,
-       0x184f54bf, 0x22cadbe5, 0x2fdf7d37, 0x23580f8f, 0xc7c63fdc, 0x0be9e37f,
-       0xf325be28, 0xe573196a, 0xf280b9cf, 0xfbf50c6c, 0xa61ce2ec, 0x73c7cae6,
-       0xc2cd2bec, 0x36f515ee, 0x8bc53067, 0x043e44f3, 0x2b8dee7b, 0x7c865bbf,
-       0xf7e0e674, 0xbb5ca347, 0x82fb02ca, 0xeed8e421, 0xfac72e1c, 0x0a358ecc,
-       0x0ce3577c, 0xfac2f08e, 0x773a95bf, 0xa8291e06, 0x82cd311b, 0xf8581747,
-       0x9af11551, 0x3dc4e829, 0xaee7c387, 0x77982809, 0xc7ced2ba, 0x7e6a0ccd,
-       0x9c10f73a, 0x70075ca3, 0xbcb854af, 0xc9d28f86, 0xd3d52a8e, 0xa3611cf1,
-       0x0aaad738, 0xe74971b9, 0xf5ed1526, 0x35beb79f, 0xe006d355, 0x878885fb,
-       0x78c8a2ff, 0xcbdca23e, 0xce5962ed, 0x900bf556, 0xf0ad56fe, 0x12f336bc,
-       0xf8e9ce7c, 0x9565b4ca, 0x557da798, 0xfa254b6a, 0x4f3d0769, 0x0965e787,
-       0xaf7f2b75, 0xc02f16d1, 0xed0be673, 0x8f8849c1, 0x7bbde7cf, 0x3b87ca27,
-       0x0778df73, 0x30de24f3, 0xaf91390b, 0x98eef588, 0x79eb069e, 0xf22dd8ac,
-       0x0f446c3c, 0x3f72c6c7, 0xdb1e7f64, 0xfaf28538, 0xe7e1ce66, 0xb165af49,
-       0x9ef81eb6, 0x3ed0159c, 0xd9117263, 0xde453391, 0x02b78cc5, 0x9817e869,
-       0x435c4371, 0x5d9c3a39, 0xacd79574, 0xc3f024f7, 0x7eb1bad5, 0xfeb1a96d,
-       0xfeb19f35, 0x1a7fc98d, 0xd97f589b, 0xf48d9fee, 0xf3c2bcf4, 0x3097c33e,
-       0x47bdd117, 0x32fda309, 0x715c99e1, 0x27e7970e, 0x77d8abfe, 0x5199333d,
-       0xdb3ed67b, 0x20373c2e, 0x68aad7fd, 0xb665e09f, 0xef7e0cc2, 0xb8bbea03,
-       0x3d1cf222, 0x0761d314, 0x3f71756f, 0x816bbc2e, 0xd3ce0e7e, 0x46aa3f89,
-       0x4e9052da, 0x76261cb2, 0xa552f239, 0x239aec8d, 0xb9e4ee82, 0x058d2aea,
-       0x8602cf30, 0x1be5839c, 0xe88bd766, 0xc87f0ea7, 0x69dbe718, 0x8a5be51a,
-       0x415b1831, 0x5d0487f5, 0xfff2911f, 0x57589a07, 0xef1840e0, 0x1e5cfaec,
-       0x74652e87, 0x656cfe5e, 0xdd25d509, 0xae01fe4b, 0x41a18d1e, 0xe927f445,
-       0x0b4ea7f9, 0xbf7a83d1, 0x34bbf849, 0xea590213, 0xb8807092, 0xc93d42c9,
-       0x7195fec8, 0x6c9b7cba, 0x7ef8fcd7, 0x7e75930e, 0xd44b2bde, 0xaa6a29a1,
-       0xf2fcfd40, 0x3b7f48ef, 0x879c417c, 0xe746cd25, 0xa3e38693, 0x767f825d,
-       0x4b91f125, 0xe8f89abb, 0x3b92cea7, 0x9c6bee08, 0xa5afd42e, 0x0cba9730,
-       0x2a23fd2a, 0x4fce3bf0, 0x474f8a6a, 0xed66f9be, 0x825aa9f1, 0x9bef869c,
-       0xc6a9f7f8, 0x7df0bdef, 0x69f7c246, 0xe0d97df0, 0x6d3b77ef, 0xec44d351,
-       0x21ef4aa7, 0xc9a5187d, 0xade6235e, 0xaeeff166, 0xa3b17911, 0xd47de0d3,
-       0x3cc6a55b, 0x67d93613, 0xa4e4fca3, 0x94ab92bc, 0x57c839e5, 0xba9adb57,
-       0x97bfa07b, 0x655e3ac5, 0x82e67e0a, 0x2dcf2fe7, 0x57fc8a39, 0x98688b6b,
-       0x8b2d77d7, 0xedc5c2ae, 0xc47c169b, 0xe1f24c5d, 0x6693e459, 0x03363835,
-       0xedcc67ea, 0x222d6fa3, 0x9bce79fe, 0x495e1839, 0xa45e1227, 0x493fa417,
-       0xf770c92f, 0x3bd7e7af, 0x3b6f1129, 0x4a5851d8, 0x16b18abb, 0xe7ad779e,
-       0x880bcc0f, 0x65ad8668, 0x2f35da34, 0xdc93092f, 0x00fdcab8, 0x9cbd65e5,
-       0x944ffc1b, 0x7e177567, 0xcbe1a052, 0x716379de, 0xc6f000df, 0x95e137fe,
-       0xbca0e3f6, 0x862d0fe3, 0xf8e1e3bc, 0x421b8e4c, 0xfcc550bb, 0x47949de4,
-       0xf0e39a1c, 0x109179e1, 0x5256c1e6, 0xc2ec8afc, 0x6f6e14e7, 0xb09b1587,
-       0x3f37cee3, 0xaf7b7199, 0x33dedfa9, 0x9477d7e4, 0x6e3bb873, 0x35fde5d5,
-       0xc79c5edc, 0x4b393db8, 0x51742fb4, 0xefc3ccbb, 0x86fdc9d8, 0xd58f4f1d,
-       0x03b05fb1, 0xe9607ec9, 0x322ccec2, 0x7f839bde, 0xde40d64a, 0xb73366f8,
-       0x7c99b75f, 0x62e79455, 0x9ce2f7e1, 0x318cfe91, 0xff64fc7c, 0x628e6e62,
-       0xd7f74f88, 0xc5fe4eff, 0x3f307752, 0x585bfa07, 0x4c502fe6, 0x33f71708,
-       0x1c3e7d02, 0xd6fe9863, 0xfeed1a32, 0x9bcb59ab, 0xcfa262a6, 0xcfa41ce2,
-       0xc59f4009, 0x9d1cfa06, 0x24e5c993, 0xb3e925c2, 0x934b2e9f, 0x1782caf3,
-       0xee1d3f60, 0xa3355fce, 0xf56ddcbd, 0x9e5abcf1, 0x072c9827, 0xa059e012,
-       0xaa3c7871, 0xc24cf04a, 0x39e19371, 0xa4493e1f, 0xf9c66ccf, 0xc97e3861,
-       0x59d858d6, 0x2f2fc031, 0x083583db, 0xacdf3f7f, 0x41a3fbe2, 0xa20eab70,
-       0xe46febaf, 0x2a509471, 0x4f1847d7, 0x67f181c9, 0x5faff189, 0xfaf0e9cb,
-       0xdd10b17f, 0x8451f802, 0x9f68b67f, 0x7944ddd5, 0xcc6bb354, 0x00ed1227,
-       0x13a9b719, 0x94f1cdef, 0xe605919b, 0x4bc634cc, 0xf1e26eea, 0x8b58eb9a,
-       0x7ebde119, 0x3a9fb18e, 0xcc13feb6, 0xc9bbab0b, 0xd3983cf8, 0x8b19671f,
-       0xc2a39671, 0xfc07d08f, 0xd3f4fc82, 0xdf0fc5cc, 0xf63bf40a, 0xe8156587,
-       0x6b32ba77, 0x504deec9, 0xf1b6f1ff, 0xd669ff54, 0x06f3bfb7, 0xa128efb6,
-       0xb9260d7a, 0xf9083ee1, 0xd54df511, 0xc114d78d, 0xa2ed47b8, 0x39f95bdf,
-       0xb04a6f02, 0xe7bc1663, 0xf28a389d, 0xbc846b21, 0xdbc85be9, 0xc9d0bdaf,
-       0xd66f5e53, 0x9358dfc9, 0x79f5efc2, 0x2bbffcad, 0x66b73f30, 0x3c57a894,
-       0x47eb1e3f, 0x1ee84f95, 0x8726de80, 0xce6ff886, 0x09da7ee5, 0x1c744aa5,
-       0x4326a5e0, 0xe7c4dff4, 0xd1e2b335, 0x9a8fe45c, 0x04cfde6a, 0xc5b5b4df,
-       0x2ce99ef8, 0x6d737bd5, 0x250f2869, 0x70e7b59f, 0xa9ed2cfd, 0x67fbe080,
-       0x8db6effc, 0x36037e80, 0x0c5387c5, 0xdf977e4c, 0xe7e0e55f, 0x22fe02cb,
-       0xd3bcfd0d, 0xb37f3cfd, 0x0722b6da, 0x0f5fe7f7, 0x5e712a5a, 0x51f95b2e,
-       0x27d26fb4, 0xf9449b4f, 0x466636be, 0xdf74073d, 0xf1787c41, 0x48690527,
-       0xdd230e6c, 0x259aba4b, 0x48c6bde9, 0xdbafc0d7, 0x5cbf3272, 0xdae81b5e,
-       0xc3d7403e, 0xd700b9d9, 0xa9ae098f, 0x3fd5fd46, 0x265f124e, 0xbc9c3b8f,
-       0x7944bfc0, 0x275f003a, 0x661e5ff1, 0x7f2315c5, 0xecfe4bb6, 0xa62c3842,
-       0x29b39d18, 0xe9e37c54, 0x7630ea60, 0x1f2f8486, 0x8315ae7d, 0x4d3fc2e1,
-       0xcffc7fda, 0x3cf2fb83, 0xf9df0ed1, 0x5c00c659, 0x242bfe30, 0x7871570f,
-       0x5c2d2bb6, 0x5c7b08be, 0xe59be7ee, 0xf38cbb7c, 0xe7e14aad, 0x77e8bdde,
-       0xf97bdf21, 0xcfb87ef8, 0x7ce41d63, 0xcf6f4242, 0x169c05b1, 0xee75db98,
-       0x1b9fa27a, 0xb469f858, 0x8339968f, 0x74f117ff, 0x843e14c4, 0xcc859cfb,
-       0xa057f14f, 0x1272778f, 0x6f090dec, 0x879a9e32, 0xf3c9a791, 0xc0cfc649,
-       0xbec8c5ba, 0xfad8e793, 0xf39e7be7, 0xc7897694, 0x6577f462, 0x8654ff08,
-       0x452147f0, 0xc99e7ea1, 0x2fb87c52, 0xc853ee98, 0x6cc998be, 0xd6679724,
-       0xe19e7d72, 0xd487f6e0, 0xc7f1c3fb, 0x92339715, 0x991b3357, 0xe7c73738,
-       0xd9874c95, 0x2c0ee7ac, 0xadf4da67, 0xd1ef900b, 0xe007d14e, 0x7ee0e99f,
-       0x215cecec, 0x24cf583f, 0xf5fdf3d4, 0x67be7a41, 0xe49fca12, 0x9e66c9fb,
-       0x8cd2fee3, 0x99ca8c73, 0xa12777be, 0xeda8cf9e, 0xcc728499, 0x737bf2e9,
-       0x1fdc0d27, 0xd1c78c98, 0x871926b9, 0x4cfa2f3b, 0x3f191fe6, 0xc706736b,
-       0xcfd238e2, 0x55894671, 0x1e154be1, 0x583fe897, 0x76ec7484, 0xff434d15,
-       0xe81b1cc5, 0xcbba1823, 0x1730bc15, 0x008fede9, 0xf10e6e0f, 0x75e3c055,
-       0x347bc135, 0xe1e12c3e, 0x2b878136, 0xfb3d5e85, 0x89f14ab0, 0x43e97f1a,
-       0xbd084218, 0xe2116662, 0x45e93f57, 0x59d8bf79, 0xf8a2a030, 0xb24e63fe,
-       0x5abf1633, 0xb195f14f, 0x4f4c4c5b, 0x22e393d0, 0x327b8629, 0x30cbec26,
-       0xcce82fd4, 0x617fbc35, 0x7b4328d7, 0xa1bc7479, 0x2a57a2fd, 0xb149f50c,
-       0x2ff78629, 0x50daab7e, 0x1ae7a4bf, 0x3f53fbc3, 0x83a86d98, 0xde70d0c6,
-       0xd8559f7b, 0x65f79836, 0xbe196ff1, 0x19b6cdff, 0xf3bc60af, 0xb2f7d8a4,
-       0x0a563fb0, 0xe9205878, 0x637cdcf6, 0xaa25517f, 0xf3df2154, 0x79eb05bf,
-       0xc034f6be, 0x0bbf625c, 0xc4f68ddb, 0x7ac62de2, 0x55a6f743, 0xe7071b28,
-       0xe354b479, 0x79c93955, 0x79ae351e, 0x50cfa426, 0xe317d82e, 0x62ec1110,
-       0x8e1b33cc, 0xfd6cbfcf, 0x2fe8d84b, 0xfefe7f5b, 0xf5d90b16, 0xaa7d5f8b,
-       0xac8f0a2a, 0xdbfae35e, 0xa7fae375, 0xdfd71a96, 0x7fae33e9, 0xfae364fa,
-       0xf5c6fdbb, 0x5c6b511f, 0x7180ccff, 0x8cebb3fd, 0x34139feb, 0x06c8ffae,
-       0xb7e7fae3, 0x70bbd718, 0x8b3d7199, 0xed0d4bc2, 0xe52febc9, 0xdb9af165,
-       0x7a01ef8c, 0x2074094d, 0xa04168e9, 0xc677f281, 0x30cf7fb4, 0xc03d324e,
-       0xf744d1be, 0x6e3ec1bf, 0xf4fe729b, 0xfc8ad201, 0xf1f4c9bd, 0xeec2b96f,
-       0xfa017414, 0x0ae513a8, 0x614f17d8, 0xd8563759, 0xeda181fb, 0x12bf290b,
-       0xbee279f5, 0x36b93878, 0x7d894f48, 0x0a7ab0f2, 0x81f6c9f7, 0xf470f27d,
-       0x8fb31c7b, 0x4f5a8ec8, 0x5d1ba57e, 0xf14f8e1c, 0xcfe825d1, 0xf2f4827d,
-       0x32700071, 0xe71c7bc0, 0x4f1fe303, 0x8dfe4099, 0xd928b36f, 0x1982ffed,
-       0xcdd83096, 0xe2ada898, 0x953a4f3d, 0x2f6f42f5, 0x858ffe14, 0xb95be0f6,
-       0x9851efdc, 0xc5e6e385, 0x7b14bce8, 0xdd79c46d, 0xe3027123, 0x4f782008,
-       0xca011c61, 0x9ba73b5e, 0xf8ae52d3, 0xc049ee99, 0x4ae9fce7, 0x6ab5d929,
-       0xcd3de50a, 0xfd2141bf, 0x787fff34, 0x2cfa1719, 0x4cb95cb9, 0xd85db3e2,
-       0x482edc03, 0x149ac3c7, 0x07416277, 0xc2e7cde1, 0xb8fe8675, 0xfc47ff1f,
-       0x0ae3cd7c, 0xd06726d3, 0x675a3331, 0x0f3c6f5c, 0x9c38daa5, 0x0d999b8f,
-       0x058139f1, 0x57bc0ec9, 0xfbc6d103, 0x7bfbcf1b, 0xd3fa1463, 0x7cfff554,
-       0xcfe306ad, 0x9ffa2e38, 0xfe863e1d, 0x63ebd566, 0xf41abfe8, 0xba14c0fc,
-       0xcebfa324, 0x87f87bf8, 0xc27e9178, 0xbb2f413c, 0xbdfb8c9d, 0x2386fc92,
-       0x98c09055, 0xe7e663bf, 0x16dabdc3, 0xe63c9fbe, 0x984d635b, 0x37666337,
-       0x32fbe79e, 0x6df3087b, 0xc7e4274f, 0x790cbac3, 0x3cb4e98f, 0xb657efae,
-       0x71865c36, 0x07115ea2, 0x7835a7bb, 0xaab7ae19, 0x0e2f28f9, 0x277257ef,
-       0x40f16f7c, 0x6a9f027b, 0xdd43068e, 0x5e1008ec, 0x10b6b556, 0x3dc598dd,
-       0x6ef3ab50, 0xfc130573, 0x148e1712, 0xcc2d86f6, 0x984c595c, 0xc1f7f0c6,
-       0x55f38674, 0xc4e9da5d, 0x0bd5a87d, 0x2bca25fd, 0xfa2590ad, 0xb6b4d7ad,
-       0x94abdc10, 0xb33b1060, 0x3b51668e, 0xe1aadbe0, 0xbe785459, 0x67922af5,
-       0x3e6de716, 0x3867f7bc, 0xdabd59fc, 0xc87289e7, 0x8728d23f, 0x5db56fee,
-       0xd95af88e, 0x93c68cba, 0x756f6b78, 0x8df58e5d, 0xbed15ead, 0xb54dda82,
-       0x71f482ba, 0x8621681a, 0xc7ad1671, 0xb03d7189, 0x03c61933, 0x045b5ecd,
-       0xe1eac899, 0x05a3b2f0, 0x5d731f44, 0x8df4061c, 0xbc7d03e5, 0xfb4cccb3,
-       0x1df3dbd3, 0xafedfef4, 0x0fd1798f, 0x1e01607c, 0xf98aff51, 0xf0238ff4,
-       0x88721167, 0xf200c169, 0x23572595, 0x6b86747f, 0xdfe3ad36, 0xbbc49fda,
-       0x1f28cec5, 0x20ef92d4, 0xe17cebbb, 0xf7148d0c, 0x27bc0950, 0x44f00fe3,
-       0x8176f472, 0xe2efdba7, 0xefdbbe7e, 0xcec79460, 0xd55fc196, 0x148d5d00,
-       0x059b25f2, 0x056f6ca8, 0xeb8252c1, 0x0b416365, 0x49d675e8, 0xbfd1db2f,
-       0xcd7eed83, 0x4deaa18d, 0x58599e35, 0xaa7c9c6e, 0xbef1d91d, 0x618b3f4b,
-       0xc474be89, 0x4581ab97, 0xc51fccf0, 0x1d783d8e, 0x89a7af35, 0x5e3ab4f6,
-       0xe9ed174f, 0xf7cf5e01, 0x20d4a93f, 0x97f14960, 0xd5c6477c, 0x2dbe51a3,
-       0xb27cfc60, 0x3b60e7b8, 0x91c2f213, 0xdb06ab31, 0xbe74626f, 0x50ffb640,
-       0x4e38e7b4, 0x394629ac, 0xfdf8c73c, 0x6c878156, 0xe9f689c7, 0xb6319f14,
-       0xa64af8cb, 0xf42bece3, 0xfdb1997d, 0xd3bdf141, 0x1d363671, 0xc71b47db,
-       0x53da20df, 0x08ef3c1d, 0x473f21c4, 0x15efda2f, 0xc76c76ed, 0xed8d4bf1,
-       0x2bf8c56b, 0x43ad0095, 0xf8899f3f, 0x9d568ee4, 0xf67cc9ea, 0x7e0cc8ea,
-       0x99f0598e, 0xf21b196b, 0x23abfcdc, 0x9a4cbe79, 0x0ff7e3de, 0x7b650f21,
-       0xb8a34b86, 0x10b5eaaf, 0x421d591d, 0xec3e088e, 0x8b4a2397, 0xf717138f,
-       0x3d197f97, 0x8e7ee103, 0xfe00acf2, 0xbef39e90, 0x04c16263, 0x98db9679,
-       0xef0982c2, 0x1864177b, 0xe53759ea, 0xccf7de1a, 0x77686519, 0xb4378e54,
-       0xf13e58b3, 0xae826dc7, 0x0c2aca52, 0x02bef2ed, 0x923e73a6, 0xf479b576,
-       0x677bc314, 0xa474f54b, 0xcb57d3ed, 0x367cabfb, 0x39b70b94, 0x1f236547,
-       0x3275a4fe, 0xef20df1a, 0x8974a26c, 0xc9474bd2, 0xa2eab656, 0xc7f54a5e,
-       0x7aaf3cdc, 0xd78fab65, 0x6f9d188b, 0x4b5ad95e, 0x2f81c7f5, 0x56d7fcb1,
-       0xa07b953f, 0xfb0e160e, 0x43aff411, 0x7fa13b3f, 0xfd023fac, 0xfa1db963,
-       0xd087f2c7, 0x856fb63f, 0x10feb17e, 0x83e585c0, 0x7f3e0fd0, 0xfac7fa00,
-       0xd500d6a6, 0xa3ad6bef, 0x20d686fa, 0x36b6f795, 0xadb5f3d0, 0xdd5f542d,
-       0x7bca8cba, 0xae54c35a, 0xed435d6c, 0x1f37a116, 0x1f1fe713, 0x7dcfc69b,
-       0x467faf27, 0xeed5f29e, 0x4504a8bb, 0x93c8655e, 0x7dc3c8c8, 0x2f31a775,
-       0x7047f110, 0x931e39d8, 0xe02b18e1, 0x2b62cf18, 0xa0dcb952, 0x2e98eb38,
-       0xc0a9dddf, 0xf85b23a7, 0xc57517ba, 0x81a73da9, 0xcc56378f, 0x2cc27993,
-       0xef1f8aaf, 0x957af7c5, 0x8f2a7558, 0x831f9337, 0x553f0179, 0x9133dce2,
-       0x7084c479, 0x7f419369, 0x1fb3cc27, 0x270e6e5f, 0x78286de2, 0x7c78f22b,
-       0xe4ecad43, 0xb6d49bf7, 0x52cd9147, 0xbf742dfc, 0x102ead89, 0x04f4a0d5,
-       0xc24f7482, 0x603373f8, 0xed720593, 0x874ce5dc, 0xb8d1af32, 0x505dcaff,
-       0xa8e7d861, 0xfd3236e7, 0xccb7e822, 0x194a4fb8, 0x3be19b7d, 0x0cf7de5b,
-       0xddcf16ed, 0xb7f9f686, 0x22f2ad14, 0x8a32473e, 0xafd7593b, 0xd7003960,
-       0x044d8ec2, 0xbde05057, 0xfdf9d157, 0xefc5fbed, 0xfffb0844, 0x2f812ec7,
-       0xd7da7adb, 0x6af3758e, 0x84d87a49, 0xa7e3e7fa, 0xee8e49d2, 0xfe44c47d,
-       0x622c71ed, 0x01337942, 0xbf6c48cc, 0x56726f00, 0x151ccae9, 0x574ce5eb,
-       0x8b117eb1, 0xec08bed3, 0x17a43aff, 0xb11fffb0, 0x7e4cfd43, 0xbf3cc7f0,
-       0xba7a4a2b, 0x8967ac44, 0xd16d07dc, 0x73c3fd92, 0x635fc8f3, 0x26d6073c,
-       0xdc2b01f6, 0xef18d955, 0xff261ded, 0xd6fde9ce, 0x1eb005d4, 0x2a3a9cce,
-       0xba0df3e5, 0xd173c869, 0xbf2abecb, 0x623d016c, 0x086597e4, 0x9fca99ff,
-       0xaabba167, 0xf89c7479, 0xe52ccda6, 0x728e9e98, 0x4beea06c, 0x3ba2bb27,
-       0x89a3f087, 0x1adbd9f5, 0x3900fca4, 0xd377ed4f, 0x560f985c, 0xf74ff222,
-       0xb53adeb5, 0x661f2126, 0x52dfa0b7, 0x3d45ab16, 0xf2665a5a, 0xaf27a845,
-       0x1f617fc1, 0x73c7eedd, 0xf3055afa, 0xc71e18a1, 0xbabce9da, 0x794a85f6,
-       0x4b91da40, 0xb0760e98, 0xe16511c3, 0x997e81b2, 0x477c83f0, 0x5ccff5c8,
-       0xad0f3435, 0x3e47da40, 0x33ecddd4, 0x74863f87, 0x998759f7, 0x6309e5b3,
-       0x9183a97b, 0x6a545b9e, 0xa60ae889, 0x3dd3b423, 0x850eda8b, 0x1c2115e5,
-       0x50f3bdd3, 0x254c1f8f, 0x52dd4dba, 0x7bc35745, 0x79f5c14c, 0x1e99c700,
-       0x1a49a0fd, 0xd35ef057, 0xb42ecb04, 0x5e22c71b, 0xa5d19c70, 0x6285c784,
-       0x575afbbe, 0x159e9e10, 0xefcb68f3, 0x87873bc7, 0xcf78fcf9, 0xe90ea2e9,
-       0x73ce31bf, 0x37f56543, 0x95c6def0, 0x74d85531, 0x33ae7c46, 0x53ce26c7,
-       0x3802e006, 0x5538459f, 0xbffc9b84, 0x8f4d7e7c, 0xc819bf70, 0xbb8a5ab1,
-       0xc4b1324e, 0xa32cabb8, 0xc8cdfe42, 0x4ebc1173, 0x0ba9dcef, 0xdfac4a2e,
-       0xb8fd7444, 0x761fe7c2, 0xcd2f3c6a, 0xfd13d7ef, 0x7ee4ebc4, 0x487f9c59,
-       0xdff6f011, 0xe79e36e3, 0x6c583a61, 0x0d2de60b, 0x25fe1fb7, 0xc4a4ca2e,
-       0x18e830fd, 0x649d5718, 0x759f3ca3, 0x7f4b8f32, 0x337cc743, 0x8afcf12c,
-       0x6ae9d04d, 0xe4af31a7, 0x77b71e5c, 0xe8f589ce, 0xc6be71b3, 0x567964b8,
-       0xdd17bdc2, 0x91ffe4f5, 0x6ebecc71, 0xfd2e0f9e, 0x09044b6b, 0x78e51df4,
-       0xa5587be8, 0xee92e5f8, 0xa17df96b, 0x7ba01e87, 0x1d2fa156, 0xbc5ea1e9,
-       0xe8c6bf5f, 0x3bb059ef, 0x1f452ab0, 0xc45a57ec, 0x48d7e4c2, 0xfb2527f6,
-       0x279b7e91, 0x563e69f6, 0x93ca718e, 0xa58f8beb, 0x88a67ee0, 0x91dbb9d1,
-       0x8f7493ea, 0xedfb5831, 0x2b294f78, 0x24f4f7e3, 0x0525fbaf, 0x3ef3c216,
-       0x1c63aeb9, 0x37d867e4, 0xbefff389, 0x7d7ecf17, 0x96f3f40c, 0x81ce18ae,
-       0x099ba5bc, 0xae81e38f, 0xac64ecb1, 0xa0fba876, 0x5f4df3b2, 0xa5c0bced,
-       0x68d7dfc6, 0x9639eaea, 0xcbbc93aa, 0xfa7807ca, 0xad3efd8e, 0x4e27f88c,
-       0x575107bf, 0xb841e1c4, 0x7ecbfcf1, 0x137327d3, 0xbe7c60e9, 0x7c83edc6,
-       0xbf9357d3, 0xceb84635, 0x7599bd94, 0x1c6b870d, 0x3d1bd5c2, 0xb7689591,
-       0x0ff6b848, 0xa5fabf73, 0x934f155f, 0x0120fa8d, 0x12ff534f, 0x865bf69e,
-       0xc0966786, 0xf28e4fcf, 0xb70642fb, 0xd5fd457f, 0xccf78461, 0x51ebb163,
-       0xb3bc023c, 0x53de7f08, 0x15331459, 0x14acebf8, 0xe42959f4, 0xa8ce8f8e,
-       0x17dbd0b0, 0xa75e7e53, 0x7743dbc6, 0x79e08a2e, 0x0b8bdf02, 0xe0dfd10a,
-       0x7ba56e3c, 0x7949429e, 0x2f5cb222, 0x573fb1e6, 0xab0f1219, 0x78bcb9f3,
-       0xd4f9b5f1, 0x596fbddf, 0xed83ca19, 0x5ef5df22, 0xef0da757, 0xc47895ef,
-       0x2194057a, 0x2a117c4b, 0x3f2b7bba, 0x218ee9b3, 0xf1f133c6, 0x1be24bee,
-       0x572c9e39, 0xbb7297e4, 0xe2aa3954, 0x2efb8739, 0xd9ee937d, 0x2352afba,
-       0xe337fb99, 0xfe127d7f, 0x7d666fa3, 0x8acbd39d, 0x2aa3f47c, 0x037da5ef,
-       0xfe2521ea, 0x9fc432b3, 0x0ff34825, 0x3b656dbd, 0x6a78c195, 0xe72bf414,
-       0xe12fe727, 0x80b65e76, 0x7ae099ce, 0xc5abe020, 0xa44f52fb, 0xf387bd0b,
-       0xa9713d22, 0x4c89cfc6, 0xef5d68d2, 0xce853c9b, 0xf917ecf5, 0x2c4bf114,
-       0xc32efe43, 0xf76f0233, 0x0c45fb9e, 0x770da9ef, 0x055ee99b, 0xbf78f5a6,
-       0x7a147409, 0x9a7ba35d, 0xf16a9e81, 0x5f17a8de, 0xfb869b3b, 0x66f903e8,
-       0x3e40fb82, 0xe77d8797, 0x6f3a5ad4, 0x2e67daf3, 0x9ffe8135, 0x5d8557ce,
-       0x39e18b12, 0xfc158d9a, 0xd84380dc, 0x4ed78e01, 0x8efc2035, 0x2ab3dfc9,
-       0x4f767a09, 0xdbbe95be, 0xf9678968, 0x48740e30, 0xdfee5165, 0xfaeffba1,
-       0x38ba0bcf, 0x8f2b9a1e, 0xe8e09d92, 0x3de2f7e6, 0x5c13af9d, 0x7841f708,
-       0x33ee329e, 0x57b63d57, 0x06a378c2, 0xf8ba77be, 0xe24ca67a, 0x77dcd0f7,
-       0x785dcfe9, 0xc2ba5eef, 0x4be8fee8, 0x3906cc0a, 0xd7c45f5e, 0x1632b3a1,
-       0xe5fc851b, 0xb6af28d2, 0x0d9b7a33, 0x17c97aed, 0xf4a947a3, 0x97916add,
-       0x29727abe, 0xe3a499f1, 0x57c105b9, 0x02366e91, 0x76493c5f, 0x9d302c4e,
-       0xc72ae3f0, 0x95c7e3fc, 0x3fb71d58, 0x2fd42e2c, 0x819326a5, 0x380b8adf,
-       0xec12c8dd, 0xee77b252, 0xf52cb410, 0xc6c45b7d, 0xb7ffbf30, 0xa3a566e7,
-       0x2796da5d, 0x0dbf3ced, 0x095db5f1, 0x38e117a4, 0xbed2a5ff, 0x4ed7c5ef,
-       0x6db8e034, 0xdbe42f30, 0x58ea7e7b, 0x9b49f68f, 0x2a7c4fcb, 0x26dcd7c7,
-       0x9fbc1eb1, 0x2bff16fd, 0xbb8c6fe8, 0x47447df9, 0x43635ca6, 0x4cf787fa,
-       0xad7bcfd8, 0xd81a0bf8, 0x07f90d4f, 0xcf66ba16, 0xb116efc0, 0x6bb42ae0,
-       0x86a87517, 0x11ee177b, 0xb9e162f2, 0xd84d1614, 0xfc9c2c1f, 0xb6373a2d,
-       0x8b1a5cf0, 0x8f75bd82, 0x8f7d1738, 0x0ac45738, 0x443b3d38, 0xdfe515e9,
-       0x24bef7cc, 0xcbf995bd, 0xdf39f3bd, 0xb7e802b3, 0x14b1e949, 0xa71b10c1,
-       0xebce9efc, 0x62ead7bc, 0x780492d1, 0x0473cd07, 0xd38c268b, 0x1b39deff,
-       0x7d6067cd, 0xcc0efd39, 0x787841d7, 0x784bd5af, 0x91ffbe1c, 0xf40e3c06,
-       0xc780ca3f, 0xd097fdc1, 0x96b5eff8, 0x13ff497e, 0x375fe986, 0xefd03fc0,
-       0xf7b71a68, 0xa71ffcc8, 0x891ddf02, 0xf9edbdde, 0x331dfc4a, 0x017efd2b,
-       0xa6aceaeb, 0x338f8473, 0xe77a673a, 0x83bddfe1, 0xee779af9, 0x8c70f8b2,
-       0xae7c733e, 0x333d086f, 0x78c2b99a, 0xc72c979f, 0x7cd31417, 0xb4db9f92,
-       0x32f30b88, 0x0b9aa56d, 0xc6d11f7f, 0x71bb9162, 0x236952df, 0x42e32739,
-       0xe53fdfb2, 0x3b3cf2a9, 0x6f7907c9, 0x979112cb, 0x5e08ec57, 0xd4beeb81,
-       0x13fcded4, 0xd283f6f8, 0xcc373a36, 0x33f69b98, 0xe1a36e32, 0xa315bf2f,
-       0xf0c0305f, 0x7a13cdfc, 0xf77e0670, 0x18271043, 0xd82f51c7, 0xb5bcc41d,
-       0xb8df620d, 0xfaf31ec1, 0x0de6e412, 0xb357da05, 0xe893da17, 0xf72fd276,
-       0xdedd3946, 0x227e8050, 0xfcc4f635, 0xedb7cc22, 0xe976f711, 0x55778a16,
-       0xfefba31e, 0xff7dcbe6, 0x8ebce49a, 0xd1da377c, 0x8694ce32, 0x6b687779,
-       0xbef7e46c, 0x7af2a7d5, 0xa08c7ffd, 0xffb01073, 0xf9432d49, 0xfee55fb2,
-       0x3adf1120, 0x67d0e62b, 0xf94058db, 0xe41f22f7, 0x744bf76c, 0x35d9e4af,
-       0xebfd6863, 0xdd3ef85f, 0x973fb70b, 0x43beb1eb, 0xf563d24e, 0xde155f56,
-       0x973fb85b, 0x5a9dabdb, 0xc122ad34, 0x579d5d7e, 0xe3f9f24d, 0x894c6335,
-       0x0aef8ff1, 0xfa51b079, 0x1578b537, 0xb8f9679e, 0xd233fa32, 0xf4ec07a3,
-       0x83a6513b, 0xfba2abbf, 0xe95a372d, 0x0faa0177, 0x875cdb8e, 0x8d34c3fb,
-       0x074d91f2, 0x99cf04ed, 0x2d7efc75, 0x5de516fc, 0xf491c1d3, 0xa9f556fb,
-       0x6c27ca71, 0x6095f14a, 0xe0feafdc, 0xffd7ba54, 0x057186e4, 0x644eff28,
-       0xaf7405ea, 0xf43c06f1, 0x6343f509, 0x17b5f3f9, 0xe75579d3, 0x50e0d4c6,
-       0x8fa9107e, 0xdaefef92, 0xdbde5b9f, 0x6719f885, 0x7dfca1f3, 0xb8f1f14f,
-       0xd9f12bef, 0xf915c53a, 0xd77ad2f9, 0xbc7dfa69, 0x6f778efa, 0x43dcf462,
-       0x73f72b74, 0x0bd5e3c9, 0x12dfb57d, 0x4bbf8b9f, 0xe052bf56, 0x624efc5d,
-       0x7e9ca9bd, 0x7de24faf, 0xb73dd263, 0x24fd084f, 0x69af93cb, 0xd8205f74,
-       0x1fe80511, 0x4ad8793a, 0xe3727674, 0x2eaf3a04, 0x9c07abc7, 0x4f2f80b8,
-       0x7113e864, 0xf2169f5d, 0xdf257eaa, 0x30e7caa7, 0xe77f0c7e, 0xa5487e30,
-       0x573eaebc, 0x92e30d3c, 0xef593df2, 0x4ab74f9f, 0x3fb597bf, 0x6f5a45f7,
-       0xf48627a0, 0x49c17a64, 0x82f43a7a, 0xe7ae1775, 0x8c2c95c7, 0x5bf0cffe,
-       0x8ec7f7fc, 0xfd92b21c, 0xef9c77dc, 0x9fdd076f, 0xe01788e6, 0x17a1a1fd,
-       0xeb1c9246, 0xe0ef8fcb, 0xdf9db6f6, 0xf046f8ab, 0xcdff1162, 0xe611f711,
-       0xf9f79da0, 0xed147b21, 0x9e29283c, 0xbdbb6610, 0x2a70fcf4, 0x940fff43,
-       0xca63cf14, 0xeefd2f01, 0xdf176b0c, 0x3bfbe8c7, 0x5163820b, 0x0c59df2e,
-       0xfbf03bfd, 0xe7def453, 0x521782a3, 0x5cb18a0c, 0xf52e5e31, 0xa42c1f9b,
-       0x5e67cae7, 0xed2a7bfe, 0xed463da2, 0x62f06b21, 0x9cafc79a, 0xf310e76c,
-       0xeef7aafc, 0x41182d1d, 0x06e128eb, 0x98dd933c, 0x05b3978c, 0x3b7bf126,
-       0x74c91f1c, 0x5f9ebfd9, 0x5ffa1f02, 0x21f6bce8, 0xc6eb8ebe, 0x591cb859,
-       0x63ec813b, 0xc86296d6, 0x88715b9f, 0xbbd0c3df, 0xdceb49c1, 0x843ff667,
-       0x86fe28fa, 0xed7bf199, 0x3f4022c0, 0xf9a1e4c5, 0x4f9123e5, 0xcf2d64bf,
-       0xd1e8fbb3, 0x39e60bf7, 0xfbf25cf0, 0xd2c97386, 0xa49d085f, 0xe1c63fa1,
-       0x97e6d3d3, 0x255d7b71, 0x7aeff8f8, 0xf4eb346d, 0x0de16bbb, 0x711fc8e3,
-       0xa41fa2d2, 0x775b87df, 0x4ae90981, 0x77f2172d, 0xbc9f9f13, 0x7bde4b2f,
-       0x8a9f8c95, 0x7f9262c2, 0x33782c4d, 0x827ea1de, 0x61c259e9, 0x91fff746,
-       0x6984df7b, 0xe29f9a88, 0xf485acb6, 0xf67be0c2, 0xbbf25f2c, 0xf5bbff6c,
-       0xf42b5c2a, 0xd38795ef, 0xe07eaf50, 0x3a46fbe2, 0x5d7a8f7d, 0xc36cf3e5,
-       0x83af300f, 0x4e14a605, 0x879276a2, 0x5dbc281f, 0xf341b9ca, 0x7ec17a47,
-       0xebe83df0, 0x7fee429a, 0x710cae63, 0xc16c2bc8, 0x9fa94d3c, 0xc2668a42,
-       0xdca7f373, 0xe3d21a7a, 0x19c5b5a9, 0xc60f302b, 0xda2567ad, 0x8ca3a1d5,
-       0x78eb8bce, 0xf8c5f8df, 0x89fe32fb, 0x9fdbf7e8, 0x243bf461, 0xb4e4f3c3,
-       0xed89b99e, 0x9eb90a73, 0xf6285f9b, 0xe44c8599, 0x8de32657, 0xb162fbaf,
-       0xf0796aee, 0x2687da72, 0x4b78b7bd, 0xa487a0ba, 0x7fcfede7, 0x1ea0f297,
-       0x4913de36, 0xef185fb1, 0x612c5783, 0x532c42e5, 0x61bdaf28, 0x0d739713,
-       0xb92cceaf, 0x5ee9d78b, 0xef3b6985, 0x59e3dfa1, 0x12caebb0, 0xad16e5c6,
-       0x05c7a483, 0xb412fe05, 0x555be2e3, 0xc345f217, 0x51e09516, 0x56d73ecd,
-       0x8b7a7e78, 0x06bbec99, 0xbce9cf01, 0x9bad1a60, 0xe00b34c6, 0x4c16b4fd,
-       0xab75fb23, 0xa4a1ddf8, 0x6f7bc079, 0xe043156a, 0x99d7c6c7, 0x043c53f0,
-       0xa261bc1d, 0xbf805a75, 0xec70890b, 0x79bfc854, 0x33783f3a, 0xfec14fd6,
-       0xabe9cf1f, 0x7dd0969b, 0x3ef8c936, 0x7d120b6d, 0x91f3162e, 0x471e4cf8,
-       0xf10fb3e2, 0x2bd2f689, 0x85ef4853, 0x6291541e, 0x9fdd8bd9, 0xda7cbed2,
-       0x99df2ba1, 0x8137cf8a, 0x9ea3a2dd, 0x6fb3f51d, 0xa35b9ea3, 0xfe7a8c52,
-       0x962ce2a1, 0xff71afa4, 0x39f5ff39, 0x3d04a669, 0xf1c83ea9, 0xa4e73aa4,
-       0xcff7a42d, 0xebe91d7e, 0xaacbee84, 0xf1ef7848, 0x83b8fec2, 0x37eabd61,
-       0xc70d21fd, 0xa66f5869, 0xe975c979, 0x7ca079c3, 0x208d4f6b, 0xc5e5f7fd,
-       0x4eb95fa9, 0xeb8df4fd, 0xde09e920, 0x9742affb, 0xf24c2718, 0xb05154e8,
-       0x9d0437ca, 0xc6007a2c, 0x38b6fec5, 0xf3d2fee9, 0xa3e2571d, 0x5f05bd7f,
-       0x71d71d53, 0xd1f91147, 0x74686f4d, 0xfb44e0c8, 0xc7c80555, 0xd02fa0f5,
-       0xc4af516f, 0x647ba1df, 0x1ee9590f, 0xb74dfae6, 0xd5e38cdc, 0xb09ab71f,
-       0xabe1d4fd, 0x495c1226, 0x2a780aeb, 0xfbde8a18, 0xbe05e28a, 0x3d81fc04,
-       0xe72dfc41, 0xc1370093, 0xba29fb01, 0x08afa88f, 0x0e4133d6, 0xedc859bc,
-       0x65df782e, 0xf7e6fa21, 0xd7cff561, 0x575f3495, 0x64df7cd2, 0x17ccdf44,
-       0x782cf9a4, 0xe7c26adb, 0xb6bfee0b, 0xa73df704, 0x79a74dd6, 0x4ff0ca9d,
-       0x553afe44, 0x210ffd00, 0x0fdc172f, 0x0bfb2cf3, 0xd3b76cf3, 0xcf3b0d7a,
-       0xf60ef88c, 0x89f9e617, 0xcf3943a0, 0x0d3d34f7, 0xcf43f9f3, 0x2efd0caa,
-       0xc6c0fca1, 0xbf4ebca9, 0x73321713, 0x4a6d087a, 0xdedf7ca5, 0x04fbfe6e,
-       0x78c00e52, 0x260f49e7, 0xd55387a2, 0xd0c9e6fa, 0x3f07ffdf, 0x00b71737,
-       0x0000b717, 0x00088b1f, 0x00000000, 0x7dcdff00, 0xd554780b, 0x733effb5,
-       0x64932666, 0x08124c92, 0x3c984081, 0x49849009, 0x768a8802, 0x02d10478,
-       0x89794f0d, 0x42100793, 0x69b5a05e, 0x0240cd6b, 0x350d45a2, 0x01d45a2a,
-       0x0da2a281, 0xbc150a0a, 0x45622a03, 0xb68b57c5, 0x514026e5, 0x5ea0c679,
-       0xffd7b5ae, 0x4e7dadfa, 0x5490ce72, 0x7dfbdedb, 0xdf1f7cff, 0x5afd9f66,
-       0xd7b5ed7b, 0xe7bdaf5e, 0xcbaa3dc2, 0xe4e216ef, 0xff6f05dd, 0xf7a517bc,
-       0xfc812eaa, 0x02cddf58, 0x2cc38ff9, 0x934a14fe, 0xfe70a68b, 0xa56b9b65,
-       0xa689c422, 0xa141fdbf, 0x367d85fc, 0x0bf2a0b7, 0xcef74529, 0xea8f7e46,
-       0x2fed415a, 0x259f680c, 0xd8b97386, 0x5deae544, 0x2e509a23, 0xcae61e1e,
-       0x0df2f2a0, 0x09644261, 0x6856fbfe, 0x3be9237f, 0x6ba50b52, 0x34786f55,
-       0xfd2f4da5, 0x6fa5c944, 0x578f3756, 0xf724abf3, 0xb97e34dd, 0xf9ed5855,
-       0x399edca8, 0xf388472d, 0x03136d7b, 0x233f32d9, 0xb03fcb87, 0x5d8d7952,
-       0x7bf85af8, 0x0e6a7dad, 0xd2b6e28f, 0x0fa98b38, 0xfae94a91, 0xea60ef18,
-       0x938d317f, 0x8b7de342, 0x0e5c1fbf, 0xe7cb0edf, 0x9fa88a0b, 0xf6626d7b,
-       0xf55dd973, 0x4ddb34f4, 0x6d46f61d, 0x553b577b, 0x3cc62588, 0x2422a1e1,
-       0x477914bf, 0xa432be57, 0x7ca42abc, 0xa7cfbf47, 0x1f2f3914, 0x1fc6037f,
-       0x12c785d1, 0x2c3b8f0d, 0x72eb1df4, 0x44d8128f, 0xbab12dff, 0xfe09cbed,
-       0x9b88c6e7, 0x55a94fd1, 0x47cdae38, 0x5f9e0ebd, 0x86345589, 0x87bbe3e5,
-       0xa6f3e9eb, 0xe2c31afe, 0xced11f28, 0x89bd53e3, 0xda9e4376, 0xab9ae09b,
-       0x4ba7a3c1, 0x4ebb85b7, 0x7fa0f3ea, 0xa6b12d55, 0xbeeecd7c, 0x7c0693ae,
-       0xfa7fc52f, 0x3449bfd2, 0x8bc091fb, 0xdddaabfc, 0xe892307a, 0xcdf14da7,
-       0x17bf5375, 0x9d1d7e0e, 0x1f75e6ed, 0x9beb4459, 0x7f3ea6af, 0xbedbe698,
-       0x426cf547, 0xfdd86fbf, 0xe7fd0c4a, 0x6e0f8b9b, 0x2fd5efa7, 0xddbb89a7,
-       0xc50ff35d, 0x17dd85e3, 0xfbe953a3, 0x08f643f9, 0xb9e68c31, 0x9dac7e37,
-       0x5c4762e8, 0xaf78b77b, 0xef5dd6d5, 0x35b5bcef, 0xdea1aa7a, 0x3d1ad179,
-       0x252f40cd, 0x8bd62fbb, 0x5f9fc65c, 0xefc2efcd, 0xc7bd7d89, 0xf4bdf4aa,
-       0x5ac6fdf7, 0xc35fbd28, 0xf736bddb, 0x6e096b13, 0xcf309eff, 0xfcfb8216,
-       0x682db31b, 0x728dfe7f, 0xcbcdbd2d, 0x244f5fe9, 0x8b68fc63, 0xbc7d77a4,
-       0xf70b6e35, 0x7b696a53, 0x8fda1aec, 0x93ebbfa5, 0x55d290d2, 0xcfc96a5e,
-       0xb76f3ac4, 0xdc002fb5, 0x46b115e7, 0xe7eaeb89, 0xdb9bb77e, 0xc9f3df9f,
-       0x270fe063, 0x4f901dee, 0x41f94d64, 0x3f2a3eb9, 0xa64151ff, 0x7f3dfa8b,
-       0xf80f5f4f, 0xfb9b76c2, 0xbbb7a636, 0xf7d83ca2, 0xa7187f7a, 0xb9effd16,
-       0xe90fa462, 0xca5e1247, 0xb8e4fae7, 0xabbf257e, 0xfb8b68df, 0x17e0d1be,
-       0xb679b7bf, 0xeffcb250, 0x31627d69, 0x6ee7ec3f, 0x4d74a1d6, 0xf89b7098,
-       0xbb864ac9, 0x22ec7844, 0x030b964d, 0x228995bd, 0xc9b0befe, 0xf1117dfc,
-       0xbc5f7c09, 0x5cbdfcde, 0xa56ead34, 0x98092df9, 0x3fda0bbf, 0x6bec04fe,
-       0x5ec5affd, 0xff7a0514, 0x4f54cc36, 0x40fe35f8, 0x255f091f, 0xc7c11fb4,
-       0x8102519e, 0xbbdf5895, 0xe8679e54, 0xa775debc, 0x2287bb70, 0xab4167ff,
-       0x5b8f5d61, 0xf0913584, 0x1c2edc7a, 0x47e8f989, 0xf5fa8508, 0x6c0b0bef,
-       0x0f7726a1, 0x04b92afe, 0xc231af7c, 0x5bbe0822, 0x427ce05d, 0x49f7d8ac,
-       0x5d29fa32, 0x356de853, 0xe6c177c0, 0xd4e7e87d, 0xe25dfdbe, 0xf8ef54d7,
-       0x58d340d8, 0xddf8eb82, 0x1ba1a7aa, 0xb1af4eb8, 0xe1014088, 0x02212ee3,
-       0xf27f94f1, 0x5a62e493, 0x7cb6cf97, 0xa4625c92, 0x36cc457f, 0x129ea3d2,
-       0xef3ebc24, 0xfcd2ef61, 0x305cd38e, 0x5d7ad09f, 0x57866beb, 0x2ab867c7,
-       0x87a3bb6a, 0x54f740cf, 0x5577f59e, 0xf7efb178, 0xcfa002d9, 0x3c5f8dc8,
-       0xb9f40f38, 0xa14ae6d7, 0xa9f66bb1, 0x2de6955e, 0x0c81a8f6, 0x4f7b639c,
-       0x9ce05744, 0x52e053d9, 0xd9aef30d, 0x7ce116a3, 0x62fbbf39, 0xf7366942,
-       0x44edc533, 0xa03c07fb, 0xf8e09edf, 0xf7fd5b9b, 0xccd79ff8, 0x7f65ceff,
-       0xf8037090, 0x9953c6c0, 0x07c4efe0, 0x79a6e6ff, 0xc6fccf9e, 0xad10bc8e,
-       0x047f4123, 0xe09bb45f, 0x2af810bc, 0x8e5c105a, 0xd037aabd, 0xa5443acd,
-       0xff4f19d8, 0x09137c32, 0xf82e84be, 0x94a89e08, 0x56705d11, 0x38eddbbb,
-       0xa2382f67, 0x694fc173, 0x12f29342, 0x0dc9f3b4, 0x493a5afe, 0xbf1d7f10,
-       0x70cae167, 0x8a4d0bc8, 0x97be8c27, 0xdcf955ed, 0x191bdb2a, 0x3f1816c0,
-       0xd2f9c9c8, 0x1840d547, 0xa3a827e5, 0xea9b30ff, 0xf547be2f, 0xfb148ed0,
-       0x07f6de37, 0x8375d61b, 0x881ca04d, 0x344b5c03, 0xfdec96b8, 0x8d0a67e1,
-       0x2ddf78b3, 0xe2ce3007, 0x170f1407, 0xe8edf3a8, 0x8a43c977, 0x67405788,
-       0x3a46e3b6, 0xce64d85b, 0x0bad122f, 0xc1fc1554, 0x9ef09dfc, 0x96fd415c,
-       0xdd730eef, 0xa102f18d, 0x4abc42e5, 0xff68d4f0, 0x3b58cacf, 0xcfd500f7,
-       0x3c6768da, 0xe2170f9c, 0xb5abf608, 0x0d204135, 0x1d6326b6, 0x6bf9efcf,
-       0xe6b1d632, 0x2995ff77, 0xcebf59ba, 0xaa37b4fd, 0x2148a9d7, 0xc4514eae,
-       0xfba0a9b7, 0xba8a538b, 0x201b6fa9, 0x9b36c5f7, 0xca879fbf, 0x8afc6c0f,
-       0x3d85c1f9, 0x6eae81be, 0xbf6bb7e8, 0x892dc3fa, 0x02e18348, 0xd716f0e9,
-       0x2427d80d, 0x35be620f, 0xdb4f569b, 0x97f0f944, 0x44b9386c, 0xf793864d,
-       0x42c7f60b, 0x3efabf43, 0x80be06d9, 0x0fe48474, 0x1cf201b6, 0x7b9daa3d,
-       0x4c77f6db, 0x9e06e8c9, 0xd71b6ea3, 0x5c100db3, 0xd17759ef, 0x845bd05c,
-       0xbe0d1fc5, 0x775ebc2d, 0xa2b3c22f, 0x5d4357d1, 0x89ef82ad, 0xfed389a2,
-       0x47d385a2, 0x5139f085, 0xc05c785f, 0x620310b3, 0xf3de3f81, 0xccbecf8c,
-       0xadac7f37, 0xe8357821, 0x022b1fc4, 0xeaffe85b, 0x63508746, 0x46b5ed20,
-       0xce5451a3, 0x5206fbb4, 0xd503edb9, 0x1dde40a2, 0xc7a7afa0, 0xa5f7fd85,
-       0x718c4673, 0x2e1ff6fd, 0xaafe8899, 0x8c22a976, 0xd3b73bfa, 0xd44e8226,
-       0x7c02fda7, 0x9ec2fe1c, 0x57b4be02, 0x6b979011, 0x35ef8f28, 0x80deada3,
-       0xa4772f01, 0xd50f18d8, 0x9cf29929, 0x4d0f7ab6, 0xbbcf7ea2, 0xeb90ec4a,
-       0x26cb876d, 0x25b1bce2, 0xd701d896, 0x1d63c3fe, 0x58b75829, 0xd59bef2b,
-       0x8f71f57b, 0x547fd0b8, 0x6f0c07ec, 0x4445b663, 0xa3c6bb53, 0xa6460161,
-       0x30a1f243, 0xc18daf0d, 0x37770ef1, 0xe317e3eb, 0x2a28c493, 0x044ea9df,
-       0x255ce79c, 0x2da3ac2e, 0x0aeee896, 0x4ef36f6a, 0x0dfa9abc, 0x078b8d8b,
-       0xd2526b7c, 0x8abf3d78, 0xbf3865ad, 0xcfc2f122, 0x08b6b7fb, 0x65fec6f9,
-       0xe9bee32a, 0x35cfde21, 0xd47e390e, 0x51cf953e, 0xe343a571, 0x4abbefdb,
-       0xc9059c69, 0x0f4147be, 0xc46dfc9d, 0x39fc02ab, 0xf96162cb, 0xe735f1ac,
-       0xbd21f05a, 0xa48a6cfc, 0x563d7d37, 0xc0bab2f5, 0xe8d51e3f, 0xc8ab9573,
-       0xa7986f91, 0xc345b7ad, 0x78039157, 0x3a2f61da, 0x9da5f384, 0x3cdce3be,
-       0x01cd3890, 0x59ea853d, 0x7aa9cfd0, 0xf47631da, 0xfc01c33b, 0x3255ea2e,
-       0x8b16ed01, 0x6fd8d5da, 0x22abd78b, 0x8dabe068, 0xa2ee3936, 0x1822114b,
-       0x22ee35df, 0x7f6e3f5a, 0xe9045a29, 0x970c6ddc, 0xe4a31af5, 0x452379fe,
-       0xb50f9fee, 0xf969b4f9, 0x7baf997f, 0x5cfd7ccc, 0x96b61fec, 0x46fefe48,
-       0xa55bf50a, 0xa1484eb4, 0xec4eadf9, 0xa7bf03b0, 0x98225dea, 0xb2f78069,
-       0xa08bc679, 0x7acedc61, 0x9f3c1c97, 0x3370f5ae, 0x75f35dfc, 0xd54e1e32,
-       0x7b1e3227, 0x84c93fee, 0x53feaec7, 0xbcbc784d, 0xff1e4cff, 0x77d67d54,
-       0x87b43ff4, 0xf826ddfe, 0xe74dfabb, 0xdf6ec571, 0x3b97f040, 0x980fc45d,
-       0x505f886e, 0x3df15db9, 0xdbe4357e, 0xe404c28f, 0x7dc2afbe, 0xfe065c83,
-       0x65ce0df0, 0x4982e7d6, 0xd17eb7e0, 0xeecd69cc, 0xded0138b, 0xfb017c4d,
-       0x11af2f49, 0xf8270ced, 0x3583e885, 0x7cb9bab4, 0xf4106fb7, 0x4e8e1d22,
-       0xa775e679, 0x20fb42df, 0xa3dfdf6c, 0x582f8fb1, 0x2878a7db, 0x46abd96d,
-       0x7c75f71a, 0xb1a7a4aa, 0x6dc8be03, 0x68d5efa5, 0xb6ef7c47, 0x020e9797,
-       0xdac3aa7e, 0x81f70173, 0x8b96ff97, 0x7dabe473, 0xfbe2074b, 0xf2cfaa36,
-       0xdabdbd87, 0x5d2fe863, 0x5196fcb8, 0x5533a95d, 0xefd0ffee, 0xf435f6db,
-       0x89db1c03, 0x0b9209bd, 0x0a2aebab, 0x0d83c64e, 0xff07ef79, 0x58b7c412,
-       0x5d3dda1f, 0xeef9031d, 0x28799243, 0x948f7c3f, 0x100f861b, 0xe40a4b01,
-       0x83670fbe, 0xb08f544f, 0x470aa0bb, 0x79611de4, 0xc384623b, 0xbffd50a5,
-       0xdbe397f7, 0xa1a42f21, 0xe83c617d, 0xf164caf9, 0x1b6dc9ef, 0xf04ff642,
-       0x34edeabd, 0x3ada955e, 0xfbc29c65, 0x7c153f28, 0xde2fadfb, 0x04d7f4d6,
-       0x9c01cfac, 0xfbcf046b, 0xa9653f5a, 0xcf502bbe, 0xe7bd68e7, 0x7337aa0a,
-       0xe864df56, 0x7e9ac547, 0x52112626, 0x947e64ae, 0xe5c83b03, 0x83d4b6e7,
-       0x3e7c525e, 0xd7dfc1e0, 0x35f9c1e1, 0xfa384934, 0x62455e12, 0x8d1a7520,
-       0xa2d5213b, 0xc0140fdb, 0xe39b443d, 0x965afd33, 0x1939f2c7, 0xfd1d0388,
-       0x4b4ee3b3, 0xfc064ef5, 0x670ffd7a, 0x75f1cbcd, 0xf2e86e73, 0xb2deddbc,
-       0x57b6700c, 0xfc7f5939, 0xeed44500, 0x41615989, 0x8a7a1a35, 0xf9f40d73,
-       0x0e0b91a3, 0x8c7c26f6, 0x43cdf28f, 0xbc6fb3ff, 0xcaf2357e, 0x72f77881,
-       0xeb7173d0, 0xc2efd648, 0xbca3377d, 0x981be1d2, 0x373c5340, 0x062837c0,
-       0xbc517c87, 0x9451275c, 0xfc2dd453, 0x45629e12, 0xe518df8e, 0xc53f472b,
-       0x5d8f2396, 0x23d66f81, 0x8d106f6c, 0x739fb9bd, 0x9dde5176, 0xe1e3affc,
-       0xfd8f3698, 0x25ed7136, 0x75fedf9a, 0x82069e31, 0x1bceecb7, 0xba50d417,
-       0x109452d0, 0xdf704d54, 0x575d4a96, 0xf6078bfa, 0x9cee7925, 0x4ebb834d,
-       0xcaeadb83, 0x50e7ee34, 0x79741bb8, 0xeb0a17e5, 0xf947fc83, 0x81b1fd17,
-       0x661f29bb, 0x74c1f8b9, 0x16395b9c, 0x886c93b6, 0x7a45bda0, 0x9c1a3be4,
-       0x73bed28f, 0x35f7f1c4, 0x21189ef8, 0x683e27db, 0x507ec009, 0xaf0f7634,
-       0x4ed513d3, 0x15634a8f, 0x721db70b, 0xb2f0a950, 0x31d7fcfe, 0x4ad7db7f,
-       0xf54e6af3, 0xddbc07dd, 0xfe496f1c, 0x0df0e180, 0x6b790a9d, 0x3fc79cb4,
-       0x1e793790, 0xc6cb84d3, 0x6b589942, 0xcd31fc81, 0x50b2a725, 0xba63fb91,
-       0xde30daf0, 0x7ae3e14c, 0x7bb79def, 0x07bc4fa1, 0xbee0885d, 0xfbf9f851,
-       0x74e0111c, 0xfd72089e, 0xe72b449b, 0x7d137c75, 0xd24bdcdc, 0x547d27c7,
-       0xc056ffc6, 0xee646efd, 0xc79a3a80, 0x650687d4, 0xdcd57eb0, 0x5df3f19b,
-       0xe8d54f70, 0x6feff686, 0xbfd88eb1, 0x699fa833, 0xdfec8437, 0xf5f5bdf1,
-       0xfb47f8cc, 0xa74748e8, 0x4bece4fe, 0x5b4eb878, 0x4bbcebd2, 0xc2127f59,
-       0x8fd1f2c5, 0xa85b7db4, 0x5a2f453a, 0xd26e239f, 0x89960897, 0x62259663,
-       0x10afafbe, 0x3ad0156f, 0x15463ebe, 0xcbd35c0d, 0xfd68a6ed, 0xe13fe94d,
-       0x0f5bd833, 0xe1af608b, 0x92f0aed4, 0x8218d5ef, 0xbdba8a7b, 0x27ca9631,
-       0xc6bd27f6, 0xefaeefc0, 0xfd0ac3b5, 0xf37486ee, 0x66d949f7, 0x68b267fd,
-       0x94fe3152, 0xfb7ae6e1, 0xb3a22781, 0xfea553f7, 0x21888622, 0x0b7af2df,
-       0x1d3e718b, 0x2fda2e93, 0x69111c10, 0x2eb18fbe, 0x75ff27cb, 0x5615c601,
-       0xb7ea9f39, 0x1debb655, 0x288b7927, 0xa7ac9c50, 0xca532293, 0x4a7fc825,
-       0xd3d203f2, 0xcf4e6ef5, 0xf28f79d2, 0xce1ef5f3, 0x9d15a417, 0x6b25bf40,
-       0x7d62b73e, 0xf8970cee, 0x9a696f2e, 0x762ab000, 0x5a441cb7, 0x809a2c16,
-       0xa1d17663, 0xef4883da, 0x6adbd4ec, 0xe1d3be59, 0xd3a345be, 0xfda6a25b,
-       0xe1d68730, 0x87aa3d96, 0x4da603f3, 0x790bdc9f, 0xa27be71b, 0x444baaa3,
-       0x54572433, 0x012fdeab, 0xdb6f7797, 0xdf9a78c1, 0x18a3f527, 0xbdeacfee,
-       0xfa99f70c, 0x4a4e9c89, 0xe81bfa2b, 0x673e2bcc, 0xf6f26c79, 0xd5126b36,
-       0x5e2af42f, 0xbd6bdbec, 0xfda01022, 0xcf26deb7, 0x0e74f581, 0xc98f1f60,
-       0xade8f699, 0x67da7c02, 0x6671a34b, 0x10a4b0de, 0x55194ce3, 0x1bbd456c,
-       0x201921bf, 0xbf4e8ba5, 0xf9f5ee8b, 0x76eb6957, 0xf18565ee, 0x2d33b1d8,
-       0xf2c17206, 0x907d695d, 0xf5d4bf12, 0xade048dd, 0xe18592e3, 0xc11a38ec,
-       0x6ede86fa, 0xe648aef9, 0xd807cb3b, 0xb760c203, 0x2ceb433c, 0x99e6f20c,
-       0x36e27e67, 0xe2672b9e, 0x18fabe5a, 0x922fedfc, 0x736491bf, 0xbff011ea,
-       0xa03cfdfe, 0x9c9af393, 0x24467a4d, 0xcd6abfce, 0x84fe08ae, 0x690899fc,
-       0x6cf91dcf, 0x2fec58d2, 0x4e1c478c, 0xf32bfce8, 0x7f5287d9, 0x6f1aeeee,
-       0x8fc2cb5b, 0xb9fca11f, 0xa36fc580, 0x689ce9f3, 0xf03bff39, 0xb64ecddf,
-       0x10a9ddeb, 0xb77f383c, 0x967ce3f4, 0xc3a88d62, 0xbc022bf9, 0xb714b3bf,
-       0x55f88eb5, 0xf70f73e5, 0x44bdfd03, 0xe5451838, 0x648bad2f, 0xcd92f67e,
-       0xfd0eac73, 0xfbfb2a3d, 0x3d3fbdcd, 0x3de91bbe, 0xc53ff955, 0x31c5a4f2,
-       0xb57ecbfe, 0xd3da0864, 0x52fa2ef9, 0xa8bf4f7f, 0x3f69c304, 0x5fef34e7,
-       0x1be097d9, 0xd2cda1b6, 0xcdbcd28f, 0xa1d2034a, 0x04386e03, 0x690df3bb,
-       0xb05f6e6e, 0xc24d453d, 0xf817ec36, 0xee7c07f8, 0xec81e59b, 0xf6c7cfe6,
-       0xc1725d13, 0xf4e5a510, 0x2c358246, 0x8fbe68f9, 0xf3c4d7f1, 0xfa77b5d9,
-       0xe604f3fb, 0xe0071241, 0xf87bb62e, 0x37f80a1c, 0xf9cf3d62, 0xd7ac3cb2,
-       0x061ff915, 0x25f39d9d, 0xbd2e7078, 0x55fc7a40, 0xcacc7fa8, 0xf3717cf3,
-       0xebb0d1bb, 0x1c7e90c4, 0x5e487f0e, 0xafd404fb, 0x7e16e01a, 0xb1e03f6a,
-       0x3f0226eb, 0x6d773bd5, 0x1d2a7ee4, 0xe5b9e81e, 0x4c1e2ebb, 0xbd789c82,
-       0x0e8064f0, 0x2ffcca77, 0x2a3d7bc7, 0xe37cb54d, 0xa47f3297, 0xa445f388,
-       0xbf515a75, 0x0f47ca54, 0x689fe769, 0xc8fe65cd, 0x5aeeeda4, 0x31525faf,
-       0xf8a7d7ca, 0xadaec2fb, 0xde749b9f, 0xab61a555, 0x23fb65d8, 0x3325e763,
-       0x79e7be5e, 0x2dced767, 0xec87bfbd, 0xfd4e1fc2, 0x3b036cc0, 0x3cbb06fa,
-       0x7f10b7a7, 0xe7e8bd01, 0x0bfb8d34, 0xef6a5fec, 0x524d3f05, 0x849d9c95,
-       0xc287a48f, 0xbef8ce58, 0x598ecfe3, 0x2eb6e7cd, 0x4844d567, 0x0567c83e,
-       0xe5185fb5, 0x5bf30bbb, 0xc2f39da8, 0x1c86ceea, 0x7bca2332, 0x3a57be37,
-       0x073193da, 0x45ef3f3a, 0xb9255abe, 0x7720cd2b, 0xd7bee339, 0xe51759f9,
-       0xbe7cc66d, 0x91b1fd6f, 0x520c6704, 0xad22cf5d, 0x9c7e5ba3, 0xfc05bdba,
-       0xc93081f8, 0x980aa38f, 0x0bf3e91f, 0xda15ffed, 0x33e23ef7, 0xe279d1af,
-       0x738fdc23, 0x7af2b18e, 0x3ca96abe, 0xa170e748, 0x6c84011c, 0x79ce1d8d,
-       0x6fe1146f, 0xbe1553bc, 0x3d45f46e, 0x1e7af5a5, 0x2bd099f8, 0xb0af54d2,
-       0xfb1dac57, 0x5bcefbf7, 0x8d47d6d5, 0xbba9f9d0, 0x37767097, 0x5bcf396f,
-       0x01f447c2, 0xdf2ac65e, 0x5b0ebe6f, 0xc3ac41d1, 0x9f1e6738, 0x539ce38b,
-       0xc304f98f, 0x43df187f, 0x1f3a19e7, 0xf27ef8e1, 0xe1158fd2, 0x7dff60b7,
-       0xdafb676e, 0xd3eb5b5e, 0xee7c25bf, 0x81ed925d, 0xf005e89d, 0x68cff05e,
-       0x7bb3cb3b, 0x7c1f84a3, 0x84d4ef65, 0x2f45ec00, 0xdf044f41, 0x79642de8,
-       0x77bfacb8, 0x7f53950e, 0x5f68c2fd, 0x2f345ec0, 0x069feb42, 0x7d15fb46,
-       0x52837db8, 0xda0e66fb, 0xbe6488af, 0xf9203473, 0x706c7378, 0x9bdf4a9e,
-       0xa814cf3f, 0xd6045477, 0xeddea2a4, 0xe5435fd2, 0x6fd43549, 0x122192f3,
-       0xf951ffce, 0xf3ce68dc, 0x32738df6, 0x4cfb671f, 0x5f6f54f3, 0x697aaff8,
-       0x51bcd5eb, 0x3d83f796, 0x9429e514, 0x9b63f4a7, 0xab573fac, 0x974691f7,
-       0x0f99cfb4, 0x5a44a6f8, 0xd2fde741, 0x99d2c24b, 0xc2fb7929, 0x5948f3ef,
-       0xe728db06, 0xc29f5c56, 0xcbd9a3f4, 0x5b7c6b66, 0x1c0d0fef, 0xcb2f2123,
-       0xb70b39bf, 0x679e8384, 0x41b78796, 0xbe5a3bee, 0xfb7a0a32, 0x0c1a9f4c,
-       0xa3395c83, 0xaf29dbd0, 0xaf5c62a5, 0xd74cb71c, 0xc0a582ff, 0x0eedcbeb,
-       0xf7cb3771, 0x3ea302c1, 0x556fafa5, 0xa37898cb, 0x27615cde, 0x2cf042fe,
-       0x9a6df6d1, 0x7d3bd7d3, 0xebe9f404, 0xf4fa8de3, 0xe40f65a7, 0xc6d2fef2,
-       0x8def5b3b, 0xb90e993f, 0xfaa7226d, 0x0f7a9d78, 0x57e74dd6, 0x25db97a0,
-       0xfb6b08bd, 0xdf298b47, 0x07887b30, 0xd389eaf6, 0x1d6f4c1c, 0x1f2ce12d,
-       0xf08ecc37, 0xb0d76ec2, 0x06ed8c2b, 0x83fb6b37, 0x1ba628f4, 0xee28beff,
-       0xf32ed2a7, 0x3065cf95, 0x0f60bcdd, 0xe515b93c, 0x7fb3872f, 0x8e5a32b6,
-       0x24bbf95b, 0x29bd2e8d, 0x5fb17aab, 0x32a5e98e, 0xe5c31dc2, 0x7a678fbf,
-       0x57dc367a, 0x7d127c00, 0xd2bc5db2, 0x258ccc1e, 0xe8d31ffc, 0xfb237a0f,
-       0x98a36af5, 0xf796856e, 0xf59e3cfd, 0x797f9238, 0x437ddf3c, 0x7bb3ef39,
-       0x3ec42efb, 0xf0c91e5a, 0xf2c9731c, 0xbcb19563, 0xb7dfe60f, 0xc5fc30f4,
-       0xbcec8ac7, 0x55ed8e5f, 0x73fade59, 0x9f841a9d, 0x9acfa75b, 0x86dfc725,
-       0xe1baa8f9, 0xd4dde4a3, 0x5595fccf, 0x7e6ed093, 0x7053edc5, 0xf69af6de,
-       0x4369fb29, 0x4afcf3f7, 0x97d47fb3, 0xf98c9dee, 0x760764d5, 0x1e7ea41c,
-       0x116a739c, 0xee9fd3d6, 0x3ef5869b, 0xe17d6f6f, 0xeb77044f, 0x5eb23f8a,
-       0x6fb47d74, 0xd85fbe26, 0x5fae1bf3, 0x16bff2bd, 0xb6afce41, 0xcfd17a4a,
-       0x7e8d1ae3, 0x1e6f8645, 0x7cae57ea, 0xc881f59d, 0x7f9223ec, 0xf8fdfede,
-       0x5bbde9ce, 0xdda8505e, 0xd5bd88d2, 0x5c81aa9c, 0x94676b9c, 0x0692b460,
-       0xed3d4a7c, 0x8d182bac, 0xa459f175, 0x5b74b89c, 0x4b181f88, 0x7fd9a091,
-       0x16d2dda8, 0xf242bf19, 0x19f41d82, 0x7d297f5a, 0xf3df7ae7, 0x9168857b,
-       0xdf7763df, 0xf75cb57b, 0xfc387060, 0xb09b19ae, 0xfd76e7ee, 0x77e8d326,
-       0x872f4d0d, 0xacffce57, 0xeace5fb6, 0xbdb665fb, 0xb9005ed3, 0x7d33fceb,
-       0xfe76744c, 0x3f9cc1c9, 0x112bb4ad, 0x577f974a, 0x72465a78, 0x65b78d7c,
-       0x07e7e424, 0xe34befb5, 0xaf82465b, 0x384e7ce9, 0xff59725a, 0x85c96acf,
-       0x47f3abbe, 0xc992d451, 0x992d03df, 0x4582ff68, 0x8ff853da, 0x3a78a8e0,
-       0xd2dde369, 0x0cb7e10f, 0x26e87e47, 0x1a71f5e4, 0xe91f25c2, 0xa58fbe69,
-       0xf9e63b4b, 0xbd9bf639, 0x7ad07f54, 0x707ca9bb, 0x9adf9cc0, 0x03e7ed2e,
-       0xfa6fe243, 0xc3fbeda9, 0x213c8e70, 0x3fd7f5ba, 0xd4f38da3, 0x3c719d53,
-       0x0acfa6aa, 0x6e1f4eb7, 0x80dbdf29, 0xf13a8fef, 0xf1126b7d, 0x6398a5e5,
-       0x9e5fcf2a, 0xfb494f67, 0xbe790bcd, 0xe7179c24, 0xff821781, 0x67ca5885,
-       0x7892be43, 0x3e3af3d5, 0xf2bfe743, 0xb04945a3, 0xae947edf, 0x7d3cf9db,
-       0xde3a9740, 0xefa46c1a, 0x2e3f4364, 0x8569382f, 0x2c49ecde, 0xdaec1ab3,
-       0xd81cf3eb, 0xe4378b57, 0xd6748c39, 0x10e0adb0, 0xece21c49, 0x2007ab36,
-       0xf7035837, 0xd86f7e42, 0x05f8b6a6, 0x54bc3b97, 0xc0f3acff, 0x68b7a8db,
-       0xe43e6c43, 0xe2fdbd6d, 0xcb1223f5, 0xdd0e700c, 0x9c875e66, 0xd87e7316,
-       0x04fe736e, 0xffde80ce, 0xa0bcbb7c, 0xc8705f39, 0x83e4ff9c, 0x9c81675b,
-       0xbdff55cb, 0x3f89f42a, 0xf384384d, 0x5e17d3f1, 0x2cfac68c, 0x41d94bfd,
-       0x71a149e8, 0x0a6eb422, 0x56ff08f4, 0xb2e3e985, 0xf81e9178, 0x810f1e81,
-       0x93a4619d, 0x683fe10a, 0xfebcb94d, 0xcb32d119, 0x5955744b, 0x64e0bcb7,
-       0x57bf5741, 0x43b3acb6, 0xb71d0bce, 0x9c2ffda7, 0x6aec375e, 0xd964a3c5,
-       0xc5637555, 0xd62df809, 0xf4013bbe, 0x854bfc57, 0xe7e28ae5, 0xbe0abd07,
-       0xce63b6df, 0x9ace9c0d, 0xedd0f8c8, 0x2af78b7d, 0xbbca28c1, 0x5dba4946,
-       0x7d615eb8, 0x1cd1a4bd, 0x36b65747, 0xd9a6de24, 0xf778be5c, 0x9f86fffe,
-       0x18f1dcbe, 0x1e5c33c7, 0x05781827, 0xa7c55b7a, 0x153ded82, 0x330dbf9b,
-       0x2d79cb97, 0xbfe1e7d4, 0xaee1e396, 0xcf3a5592, 0xd0c893b7, 0x574bf0f9,
-       0xe1066a51, 0x8de6aafd, 0xbd9b94aa, 0x7597ecc5, 0xb0ce39da, 0x918221ca,
-       0x28a1cf04, 0xdf45d7bb, 0x628fae2f, 0x18516179, 0x9cf99fc9, 0x438e708a,
-       0xdda0c4f4, 0x965477a9, 0x25e2aa83, 0x571eaa1e, 0x56c5b002, 0xfc8a48c1,
-       0x04bf3213, 0xd25526de, 0x3f00d78f, 0x1798cdd6, 0xab6f524d, 0x03f706b4,
-       0xc0e79d2f, 0x4abd7336, 0x38d1e79a, 0xefe659c8, 0xeb9da2d5, 0x36feecd7,
-       0x60ddf8cc, 0x527d65df, 0xc8556bd7, 0x7aa70433, 0xb3cb0447, 0x402398c4,
-       0xef14ab57, 0x29150ec3, 0xefa0e39d, 0x2f964e25, 0xe7946ee6, 0x838c3347,
-       0x0dd78390, 0xae67b966, 0xbe04cde2, 0xd670bac4, 0x1fdca9a7, 0x64e58bde,
-       0x4e484396, 0x7daa3966, 0x12e39d8e, 0x825af39b, 0x1f9ac790, 0x0ad0f148,
-       0xf3e47f32, 0x96709ee8, 0x4aa79a7b, 0x5d79a7b9, 0x31ff6e1f, 0x390beb40,
-       0xf9b9e25a, 0xb71e1c9e, 0x89db2a9f, 0x200f523e, 0x7a133ab9, 0x41e5c102,
-       0x67472eb9, 0xb04afac5, 0x9bfcfaee, 0xe0a3db63, 0xf1e512c7, 0xd86e4bdf,
-       0xed879da2, 0xf003c2eb, 0x8a549c53, 0xf60c5a0e, 0xe4325ba9, 0xac7231f9,
-       0x8f56ab77, 0x966519fd, 0x80ff77a9, 0xd07b29e0, 0xe9486ee2, 0xf5e1075a,
-       0x27fe6266, 0x83e785d7, 0x958e46ee, 0x7963a7f6, 0x0e479f92, 0x73bf1c17,
-       0xedefd6bb, 0x9a531619, 0x48f44118, 0x942c9cfd, 0xe1a8edf6, 0xa4076c45,
-       0xbbb9ba35, 0x19359038, 0xb32a9cf2, 0x9afefd17, 0xa4e9e06e, 0xde52f18b,
-       0xd94cb93d, 0x72f2e124, 0x5fc8dfbc, 0xf0fdb385, 0xe8de76a4, 0x347441eb,
-       0x8d71cf82, 0xe8d3ad9f, 0x74cf5d66, 0xb98ba263, 0x3741b790, 0xd8b9e473,
-       0xfada5749, 0x7af0dd12, 0x485d13b7, 0x6be211ba, 0x4b742fb4, 0xdf443b79,
-       0x7bb7d4ea, 0x0e88b7d0, 0x6de8c89e, 0x074217a8, 0xf1181ac2, 0x252cfc8f,
-       0x2a4762a3, 0x564904b4, 0x2cdc47e1, 0xd7c646ce, 0x4ac0d65d, 0x55bfa782,
-       0xab00cbae, 0x653a3ba4, 0x5cf911fc, 0xd9f88bdf, 0x0b17fbe2, 0x4e2fd52f,
-       0x4ab76c12, 0x2626f927, 0xa409db8e, 0xb0aa0770, 0xf68a50e7, 0xffb231c5,
-       0xc46fa262, 0x5e7f51b3, 0xdcc69c4b, 0x2a7fc246, 0xfb407e58, 0xef6e7ce8,
-       0x5ef6c8b7, 0xd303a52b, 0x5f6a3ee4, 0x2bf8c615, 0x264073be, 0x58d264e8,
-       0x66249d33, 0x4f41394a, 0xbadd331b, 0x7e0890dc, 0x9838d250, 0xf08699cf,
-       0xd85daaa2, 0x7d48cfa7, 0x4df578a3, 0xbe004793, 0xd83de367, 0xeca7a7c2,
-       0x494aff60, 0x7f1f9ce3, 0x5b653d08, 0x98df7f38, 0x780f7be9, 0x17b8ad3f,
-       0x250fa2ec, 0x27b15f33, 0xcb5f7b52, 0xa3bf73d4, 0xc77f8a74, 0xa62390db,
-       0xfeb950cc, 0xb9ed2114, 0x338e51a2, 0x35b9ffd9, 0x3c9bfa91, 0x94f0e15a,
-       0xf25770b6, 0xb455f832, 0xd1a63df5, 0x98b84377, 0x70139cfd, 0xcd4cc80d,
-       0x24821f86, 0xe4e46ed4, 0xfd5a9901, 0xc806ca31, 0xc9c70343, 0x47d7a7fd,
-       0x2d37e83f, 0xcfb7ee53, 0xe7a77db4, 0xbf5caf09, 0x5b584d6c, 0x5b52345a,
-       0xf3a51070, 0x039ec6b2, 0x2a94999f, 0xde07ac26, 0x4d8aaa7f, 0x317b6f0c,
-       0x4ca885f3, 0x8f82f837, 0xfba65914, 0xee99836d, 0xb7b4c6db, 0xb6f949dd,
-       0x7ed2392d, 0x0bf3e9a7, 0x82e5825d, 0xef9231b6, 0x64896fb5, 0xd5cc73fe,
-       0xed27151a, 0x97dfac5d, 0xd7f1246a, 0xe17b86ba, 0xda752e37, 0x2c7e70db,
-       0xfb3a607c, 0x499b4bfb, 0xfd5c47bf, 0x4f7eb35a, 0x6658787a, 0xa87afa37,
-       0x019a0e5e, 0x55ad951d, 0x36070e98, 0x997dec78, 0xcc2e29cf, 0x4c19ccaf,
-       0xf32fff07, 0xf05c7384, 0x37fb7a65, 0xb091f784, 0xba0e0b1f, 0xd7c83a1a,
-       0x3716e30b, 0x1a7eb315, 0xfe63ed99, 0xbc255035, 0xd4cf1d10, 0xec126fe8,
-       0xd64be0a0, 0x97d8bed6, 0xdf6865af, 0x4e995ce3, 0xbe70eba6, 0x7366d06f,
-       0xb6be0265, 0x9c16e155, 0x4a5693b7, 0xe77da6fa, 0xbb80bdc0, 0xfc0222ac,
-       0x7ed6b8e0, 0xd16b0afe, 0x77f7ca46, 0x1c546b08, 0xe98f2be8, 0xfbe5903b,
-       0xe9f7eb0c, 0xc828c42f, 0xd76ba50d, 0xfa34b849, 0xe323d610, 0x4f9c69e3,
-       0xc3e4a4b7, 0x53d3a0ae, 0x766c6b20, 0x5d0308e6, 0x1e9850cc, 0x60873e68,
-       0x55979d9f, 0xfa728f92, 0x32f41fbe, 0x1d306c69, 0x6a85d871, 0x76abc725,
-       0xe20f0a24, 0x3b443a87, 0x241d23cb, 0xea3f808f, 0x27e7467c, 0x475e1744,
-       0xeb7ad742, 0x3d6b657c, 0xde784681, 0xf4e0ef56, 0xb0977aa9, 0x5ed84f12,
-       0x67f9c89f, 0xb69cddeb, 0xf7f167d4, 0x9c3deae7, 0x8a3f59df, 0x7bd42ff3,
-       0x7ebbbf39, 0xabbfa722, 0x84efe22f, 0x3a4be61f, 0x93f9d1df, 0x9f3a5f4e,
-       0x05aba50a, 0x33dc6684, 0x0fccf6a0, 0x79883e75, 0xf8bbf258, 0xa9cebe93,
-       0x113f914a, 0xceb450fc, 0x5428ff01, 0x22f33ecf, 0xdca3b9e1, 0x1da1f1c9,
-       0x0ec1f242, 0x8dcf83a7, 0x0dd8bb64, 0x32c340fb, 0x869ddb6f, 0xb95e7873,
-       0xba06ac22, 0x5c36a9bd, 0x7d740d58, 0x29ac5d73, 0xfdeebf3f, 0xff50fad7,
-       0x2df18b3f, 0xbb1cfac2, 0x7fa3d4e3, 0xdf8fefa4, 0xeb033a71, 0x796c704e,
-       0x1edee308, 0x2ad1c1a1, 0xceddbae1, 0x08c0d2f2, 0xcfe14fa9, 0x2d738861,
-       0xfb7d894e, 0x31e70437, 0xda061d6d, 0xc146b35d, 0x754ab32e, 0x1f2aa4ad,
-       0xfbe8bd63, 0x2af5b59f, 0x7c630ba9, 0xfb6a3496, 0x4cff18d4, 0x57de3cf8,
-       0x78a75cb0, 0xe91f8085, 0x41ec2ff8, 0x71c41192, 0x685011c5, 0xad94851c,
-       0xae17b0f9, 0xe428fd79, 0x10eea574, 0x873ed5cb, 0x8428e393, 0xd8d676df,
-       0x9077529f, 0xfed689eb, 0xc8c838a6, 0xf83b5ee1, 0xeb1b6805, 0x40759256,
-       0x268b9f60, 0x94f1ef85, 0xd6cbdf69, 0xe2f8a628, 0xe655337b, 0xac32878b,
-       0x14ca0e9c, 0x89a5139a, 0x5e9d29cf, 0x3c707f89, 0x9e535963, 0x2f81917d,
-       0x4bdf6897, 0x78a62cb3, 0x321943c7, 0x98106a2e, 0x6777a505, 0x3217daa5,
-       0xdc7373df, 0x24bf5ebd, 0xea757f2b, 0xe883f470, 0x8ff6aea0, 0xddb95a64,
-       0x84970ca1, 0x59e741c7, 0x74e9c714, 0x72e82e7b, 0xeff8a7cc, 0xeb3f0c95,
-       0x3ecf1559, 0x7bfc2cfd, 0xe30a7f15, 0x9862a9f3, 0x0ec8df66, 0xf2ce9c8c,
-       0x8ca9d78f, 0xd72dfc84, 0x7fd3fc7f, 0x547c4689, 0x57694ecd, 0x690db4a5,
-       0x6ce5edf5, 0xd0f6ab57, 0x9f0388fe, 0x5fcdfb35, 0xd14ff67d, 0xf897acad,
-       0x5bf8b493, 0xdeaaf78e, 0xc0e38279, 0xd0afb8f4, 0x37ca3576, 0x71eaa7ac,
-       0xb63fba01, 0xf78d9f70, 0x851ecd4d, 0x5d9a98f5, 0xe7c01317, 0x4aadf66a,
-       0x272e2ee8, 0x5e3d5fb4, 0xd5bfb740, 0xc39fb588, 0xc384487f, 0xffad0ff8,
-       0xaf546676, 0x62054353, 0x3b60aed5, 0x1c705588, 0x8e2d72c7, 0xc19023b3,
-       0xe49ee17e, 0xc4f59aed, 0xedbf49f0, 0x1063bab0, 0x88417caf, 0x53addd89,
-       0x7e7920fc, 0x047da39f, 0xed85f0bf, 0x1791cb2a, 0x7ef147b6, 0xff7edea8,
-       0x55dbc441, 0x8dd8566f, 0x308e2557, 0xaa77aade, 0x0fe061c2, 0xc50bb035,
-       0xd2e70cf7, 0x416aa3a7, 0x145a4b5f, 0xadf816ef, 0xde98ee1d, 0x35da7806,
-       0xd61a5afa, 0x45d79232, 0xf814ff83, 0x5cce419a, 0x8e7ef7b2, 0xe77aa413,
-       0x6df9ae59, 0x51b3c724, 0xce036f0f, 0xd80a1b33, 0x65a4bd4f, 0x05cb3547,
-       0x105d23db, 0xccdb4e69, 0xd1be29f7, 0x9346fbc6, 0x4fc0ced3, 0xaacff682,
-       0x4e030f2c, 0x5ad3cbec, 0xcedeab3c, 0xb3b64832, 0x0dfb7868, 0xae88e7f6,
-       0xda5a4bfa, 0xfea9d3a2, 0xe7dfbb27, 0xee4839d4, 0x23ce25e3, 0x3f4738b9,
-       0xf7c919d9, 0xf9d93eed, 0xd12f09eb, 0xc65ae778, 0xfb0c52f4, 0x1b20e06c,
-       0x41b73fd7, 0x25f301c6, 0x5a0fd611, 0xb6673e78, 0x27ac2927, 0x9f84df03,
-       0x8f9f3b33, 0xf63ef0b6, 0xab717bff, 0xc86b15b3, 0xb2eb847d, 0x5bfe8047,
-       0xed11fbb5, 0x7fe5fd9a, 0xed6affa7, 0xa4529b7b, 0x3bef238d, 0xc20e3d08,
-       0xd53beda5, 0x796efbc9, 0x2fef9d94, 0xbee6182c, 0xe8f81e71, 0x518e329b,
-       0x043f77f4, 0x3bc16ffd, 0x596f6cf1, 0x41f7736e, 0x36c38bfe, 0x282c13f6,
-       0xa1f51cf0, 0xed9d8c7e, 0x75b1224a, 0x6dadec04, 0xa8be5229, 0x933b435c,
-       0xe88fdc50, 0xacf84fcd, 0x8f84580c, 0xa50793f2, 0x523ebaf2, 0xd9daf16e,
-       0xfbe413ff, 0xc2ecc792, 0xfe2f7b8f, 0x5d7ea4e7, 0x0efd2a99, 0x517f608f,
-       0xcc17195a, 0x4edd878c, 0x69ca9ba3, 0x9fa06e54, 0x4cc14dca, 0xed674fc8,
-       0x72891ed2, 0xf9954de8, 0x46835eb2, 0xfd07e8a7, 0xceb8a5b6, 0x2bbbbcb3,
-       0xb0ef404a, 0xed2518bc, 0xdf09bf21, 0xaf386614, 0xe9241a6f, 0x07f341b8,
-       0xf848b7fa, 0xf8e41700, 0x4ca6f625, 0xb8fab9c8, 0x789ba24b, 0x78dab3bc,
-       0xa49a224b, 0xc78b44ff, 0xdf1e7d43, 0xd3bfd826, 0xcb1864fe, 0x1efba7cb,
-       0x9fe30179, 0xc730727e, 0x04a5b411, 0xf2e6ed16, 0xaee38e70, 0x082c2a78,
-       0x327b3f78, 0x9f58ed8a, 0xf61ca4d9, 0xcb025459, 0x1ea28761, 0x3afe805c,
-       0xe0298736, 0xc2299fa3, 0x2df2889e, 0xa80e59bd, 0x3f63afa8, 0x17b10549,
-       0x4e94afc8, 0xd9f7dc84, 0x276cc196, 0x950decfa, 0xf7d0292f, 0x13eef835,
-       0xc67e0b4d, 0x3ff4bff2, 0x6fea7e9e, 0xaff3bb83, 0xdb366c54, 0xd7f5f4c3,
-       0x2418efcb, 0x0c7703ed, 0xcac97a92, 0x7fe92e41, 0x30796c8b, 0xf929e795,
-       0xeb03ad03, 0x131fb47f, 0xd63f6f60, 0x714127b2, 0xccc1cf02, 0xdbef035f,
-       0x7a759ea4, 0x42fd8dbb, 0x79462f15, 0xe774fed9, 0xb0ef7c15, 0x78729542,
-       0xdbde4585, 0x99eed0ab, 0xb2674456, 0xcdf08b7d, 0x16fb6d7a, 0x8e471b55,
-       0x01d6d9fb, 0xd4109fd2, 0xf0e42ff2, 0x7149b83d, 0x2c69e6e2, 0x05c86d5f,
-       0x8e6e2f5e, 0x1a79f8e4, 0x87b88bc7, 0x5cfd9f8a, 0x116633e2, 0xae7407eb,
-       0xd4ae7f31, 0x9dd573f8, 0x5ee0c757, 0xe5477881, 0xad1712fb, 0xbfe03e9e,
-       0x4f7af8a1, 0x5f4b63e3, 0x41f99478, 0xc417ed25, 0xfcd52d59, 0x529f4bcb,
-       0xba5c9e58, 0x9887eafa, 0x136dbeef, 0xb6705fb8, 0xe368fee5, 0xf8d5ec7a,
-       0x0f7b5767, 0xf54a5fd7, 0xa337fb65, 0x36ad9e19, 0x5d09e00f, 0xfeddefc7,
-       0x6a5ff529, 0xf242d15f, 0xf3e5ee45, 0xdc8e28bf, 0x95f027f6, 0x676ce1ed,
-       0x7be7f5a3, 0x2d6c6746, 0x33ff308b, 0xbf3384cf, 0xf72b1339, 0x9e7427fd,
-       0xe780edfa, 0x5db1f787, 0x02e9bded, 0x80e2d0e7, 0xae1d5fb9, 0xafdf1afd,
-       0xc0c4f78a, 0xeb45534f, 0x7d68fe81, 0xdfedc47e, 0xd0fb71b1, 0x768e3cf9,
-       0xf4fb0c23, 0x9ba64899, 0xbae4fd33, 0x1076799c, 0xb16d679f, 0xde09de92,
-       0x674be864, 0x1b8a6562, 0x0a87a03e, 0x3387a497, 0x1ed85a63, 0xc1d94670,
-       0xb64d9b69, 0xfcd3a8ab, 0x897f44da, 0x26d01fa0, 0xb58ea9ec, 0x80c72047,
-       0xe7cc8fcf, 0xcefb8834, 0xd07376a1, 0xbebfce29, 0x84dcf259, 0xcf3e0578,
-       0xe3f61b7e, 0x733df0b4, 0x564f269f, 0x4fdcbf6e, 0xdcaa7588, 0xeb3fb0ae,
-       0x02fe7692, 0xddba5eea, 0xa972e89f, 0x6e22f15f, 0xb2e3696b, 0xa5fba025,
-       0x81e6ebb5, 0x2c79f5ee, 0xb75feed5, 0xd3c32a29, 0x27fb4e16, 0x74f1f2fb,
-       0x8a59aafc, 0x5c279f1e, 0x7b45f9fa, 0x2dcb2c38, 0x4db288e9, 0xa3655fd4,
-       0x49c796b2, 0x395bf5d1, 0xb84f1d3f, 0x5efb02cd, 0xb9df769b, 0x70ebf9a7,
-       0x524f04f6, 0x6d4fe496, 0x6f9ef229, 0xbef25bfb, 0x0a6fc5f6, 0x81fee262,
-       0xfa91c83c, 0x7f047f7a, 0x72106816, 0x96e7c68f, 0x704eaec2, 0xfb306e66,
-       0x9b36b273, 0x9bb643f3, 0xcd3bd9f3, 0xe6bddcf9, 0x7355e7bc, 0x7b7185de,
-       0xfa09e177, 0xa103e236, 0xbe85236f, 0xfa94ceed, 0xb7d0f236, 0xc6df4291,
-       0xc8dbe877, 0x1e46df43, 0xd0f236fa, 0xdf4291b7, 0x1a39f7c6, 0x7b352a9e,
-       0xe381d629, 0xeb84f6d4, 0x5fbc00f1, 0x6049cc2e, 0x52ac2a3e, 0x24b0bd1f,
-       0x4ec7e59b, 0x0754d33b, 0x38f499db, 0x7ca2b7a7, 0xc37ab2e3, 0x75647b7f,
-       0xc76e14df, 0xdf9ae7f6, 0x6573fb49, 0xf613b87e, 0x9f55d68e, 0x13d886ac,
-       0x444df288, 0xf6b60bfd, 0x556fc0ad, 0x6fec2bdd, 0x7ee15d6f, 0xfd7207e7,
-       0xc7a2eed8, 0xdce3152d, 0x7d26df03, 0x7b6fc649, 0x6a3b461c, 0xac485fa8,
-       0x3f21e435, 0xa1f39b35, 0x35f0207e, 0x355f69af, 0x6e3c1d31, 0xbe0bef6b,
-       0x0749e27f, 0xa13af3df, 0x6cc4edd9, 0xba63cb17, 0x8f29df3c, 0xc26ca3dd,
-       0x2b24bdf9, 0x1c77db8e, 0xd3dd30ca, 0x2f4b4d0b, 0xdabcb3e5, 0x58ab5f99,
-       0x8cd94e30, 0xaf59fb15, 0x73e68c4e, 0xb60d16e9, 0x0dff9041, 0x440e0f70,
-       0xe868e898, 0xbf10b8b6, 0xfd533f65, 0x4353bb61, 0x4c4396fc, 0x16d7d3e5,
-       0x17b5ef98, 0x1f2a6d5d, 0x878cef68, 0x96ff4873, 0xd64b9f06, 0xe7cce8b9,
-       0x4bd686f9, 0x847f3c56, 0x25bc56bf, 0x9a32d3e5, 0x7b40b787, 0xfe1f239f,
-       0xe014ef39, 0x16c5bcaf, 0x54bef38b, 0x9d44873b, 0xb72e5cf9, 0xae2bbf0a,
-       0x5dcaee8b, 0xed4b1bc2, 0x2536b4bf, 0x71dd1d33, 0x14255934, 0x2472192d,
-       0xe57d0837, 0x8246278d, 0x8dd4aaae, 0xbf2a2ec9, 0xc56c0955, 0x71d3ec45,
-       0xa4ae123b, 0xf8b4fff2, 0x75a2c91e, 0xef05b64a, 0xba3e0f9d, 0xbde04d23,
-       0x9f6b1391, 0x3cb8e68f, 0x6d92fe8d, 0xc1d008ae, 0xf59526c6, 0xd4cdd814,
-       0xd93a2eb8, 0x011f14d8, 0x8c7ca6bd, 0x717297e2, 0x0bdf49b4, 0x9aa147c5,
-       0xe69b8efd, 0x2a90f17b, 0xf36a40ef, 0xf592ee5c, 0xaf6cba45, 0xe7d7b3df,
-       0x47d3527b, 0x96be362b, 0x3f7d0b79, 0x2e7f783b, 0xd65784ae, 0x2f79e6ef,
-       0xdadf6cb5, 0x1d7bd297, 0xd7985dbe, 0x45c6b7f2, 0x7ce3495f, 0x87c65db9,
-       0x89f9b5ff, 0x4fc4fcc7, 0xc27a6cef, 0x8541fb0e, 0x1e876035, 0x46e4fe5c,
-       0xae18e23b, 0xbf91b6db, 0xcc56da2f, 0xbefd00f6, 0x7c7aa7da, 0xf28f86b3,
-       0x1706cab1, 0x60ffb3cd, 0x23ca4fc9, 0xa14b1c64, 0xdc35fa3a, 0x4db8b813,
-       0x66bcc3c9, 0xe3b0ed14, 0x1a3bff1e, 0x37dd09df, 0x17a7871d, 0xabbd86f6,
-       0xdf20f145, 0x89993ed3, 0x0f4472cb, 0x39b92fd3, 0x0869719d, 0x0a1fd5eb,
-       0x8e70bed2, 0xd7e88764, 0xcf695587, 0xad123c43, 0xd83db973, 0x85e43a6b,
-       0x0ffbe597, 0x8d0e7455, 0x2ede87ca, 0x169455c4, 0x744d568d, 0xd23e335e,
-       0x0b660fb4, 0xfea2bec3, 0xa67e8966, 0x69498cfc, 0xce37faa6, 0x67e21a18,
-       0x672aefce, 0xe99575fe, 0xdbaa975d, 0xe3856efd, 0xbf9ac67b, 0xd33b7a53,
-       0xf6a60dd9, 0xe99a6255, 0x9b25975d, 0x133c65df, 0x8fa1d995, 0x41f76b95,
-       0xb4dafb66, 0x9dfcadef, 0xafda6226, 0x7f3cd303, 0x8da5e794, 0x1dba08fd,
-       0x9ffe367d, 0x1979ddd6, 0x898f19d1, 0x3bd85bf8, 0xe479667c, 0x42a9eb08,
-       0x669543ae, 0x92caaa8f, 0xff2aa8f6, 0x9be23b11, 0x24d6ff09, 0x93754942,
-       0xaa46f6c2, 0x938a48ef, 0x7df1dbf9, 0x075ef9a7, 0xf284bbfa, 0xf6316a43,
-       0x35796857, 0x42e71bcd, 0xb047ec35, 0x6bfde983, 0x19f4eafd, 0xb43ecf7a,
-       0x3760df1f, 0x6d8ae7ef, 0x23f60e3b, 0x8a2f4cbc, 0x497c43cd, 0x5b54cb65,
-       0x74e5f671, 0x8bfdf3a6, 0x7fb616e5, 0x857e1c75, 0xdca3ace9, 0xddf191ea,
-       0xd51f18ff, 0x0d6f695e, 0x3445bfa5, 0x1799f81f, 0x013c54ed, 0x5e03d645,
-       0x432e81fa, 0x0dd492f0, 0x753c74be, 0x7ca42de2, 0x1c33fe31, 0x004a11f1,
-       0xbc32f27c, 0xfad478e8, 0x2c13e45f, 0x013c1267, 0x3fa42786, 0xff742a31,
-       0x20efc2dd, 0x84506c74, 0x3c6ef94b, 0xed24bb4c, 0xe4d30336, 0x2977dbbc,
-       0xb3ebc81e, 0x7bf9592e, 0xc914bd27, 0x9319f538, 0x93b3fbcc, 0x7ee48a7e,
-       0x81297999, 0xd36ffddb, 0x8fd177d1, 0x8d099fee, 0x5defd6ff, 0xddac1a2d,
-       0x46211a4b, 0xc44ffb7c, 0x4072ebaf, 0xe749e74f, 0xf0d2e379, 0xf6ed4cef,
-       0x951e5e1c, 0x3edaf1ca, 0xf3a88ecd, 0x4ed69f63, 0xca98b71f, 0xefa005dd,
-       0x17b009fe, 0x4b4c6eaf, 0xe317be36, 0x3b63655b, 0x788af26f, 0x5dc38b4e,
-       0x8a473809, 0x4d77c857, 0x27d5df8e, 0xe388fe01, 0x26bd6cab, 0x7fc7d751,
-       0xe4593c3a, 0xe9c85f20, 0xb3617589, 0x3d78768d, 0xed2c1a6d, 0x7e39fa35,
-       0x7a3872ce, 0xaadff636, 0x0508d15d, 0xfdeaba5a, 0xcf3a2e91, 0x8f7c5957,
-       0xef7f660f, 0x85cf3e46, 0xec2e636b, 0x513cba70, 0x0fb0aab1, 0xffcafdce,
-       0x9c31e579, 0xb615befb, 0x9fa3c804, 0x840aa07d, 0xc679d0ce, 0xe1a7c472,
-       0xdd3fae92, 0x10f7c912, 0x1784553f, 0xea25a6fe, 0xe9975cfe, 0x0b3bdd5c,
-       0x41deffe3, 0xb8c08ee3, 0x1889ad81, 0xc4cfe3d7, 0x1915beb8, 0x57d9dd31,
-       0xbd66b4f4, 0xeab6f394, 0xeecd64f6, 0x791ef90c, 0x6270f7c8, 0x1e47be41,
-       0xc8523df2, 0x4dbef8f7, 0x6c0c2ff3, 0x7e83cf68, 0xb22b1fea, 0x75bcf96a,
-       0xbf7e4166, 0x80f08945, 0x78a2dcff, 0xc1bc70fa, 0xc4def966, 0xd57590f2,
-       0x49da6bd3, 0xedd03306, 0x84392e0f, 0x8c6e6e31, 0xc7e53588, 0xea9afa39,
-       0x4c52ba17, 0x0e25d7e5, 0xef5f9536, 0x7fe533ce, 0xa9a57598, 0x18cf64fe,
-       0xa347fe53, 0x9fd537ae, 0xca6a9dea, 0xc7389f4f, 0x51667f54, 0xc6fca9b1,
-       0xe54c4bd9, 0x4ccb7c73, 0x3fe579f9, 0xa9bfd535, 0xdca98576, 0x9c565c2b,
-       0x77a17b77, 0x865fde11, 0x2de945de, 0x8d38656f, 0x9c7a3aeb, 0x7977dba5,
-       0x5072694e, 0x36dea1bf, 0xd7ee25d0, 0x68070e80, 0xc0be67f7, 0x7e1bd2b9,
-       0xf522a0c9, 0x417d23de, 0x42f5a137, 0x1e4747cb, 0x35a6e8b8, 0x7a2a7a2c,
-       0xc4f895a6, 0x140e2be8, 0xf57e51a4, 0xad338553, 0x5f465fc4, 0x54f9e07d,
-       0xb53d37ca, 0x3b0f964a, 0x51e51170, 0xf320df4f, 0x1a8b05d3, 0x7af90c8f,
-       0x31e69f86, 0x6ba907fa, 0xd26ed23d, 0xa769bc6d, 0x80f0883d, 0x01e04d78,
-       0x13e89069, 0x4fa201e9, 0x7d12afa4, 0x710ba596, 0xe913e890, 0xf13fd221,
-       0x7fa4f7fd, 0xfa4c3d22, 0x49b7d227, 0x847a44ff, 0xefa44ff4, 0xf4e6cfd5,
-       0xb71f7a83, 0x397d43fb, 0x6beb47a7, 0xf5c7fbf9, 0xb9fe9c75, 0x5ddfcfde,
-       0x433b7443, 0xba31ed90, 0x7e1aabff, 0x76edd847, 0xfd1acedb, 0x9e578ac2,
-       0xb2bfbaa7, 0x46b456a1, 0x5ab69f62, 0xba394f63, 0xf33d90fc, 0x6538ab5b,
-       0x0f5ebf90, 0xe10d26f7, 0x98bbfbf1, 0x8fdf6b6f, 0xf203e989, 0x520a9d69,
-       0x9f28297d, 0x2aba5f99, 0x0fc7f886, 0x81b5a9be, 0x74b43e5e, 0x0bfb7f7f,
-       0x87da4e8d, 0x8c873378, 0xebbbf2e8, 0xf8ceef7e, 0x1e5f831a, 0x8e3d6cfe,
-       0xf3c7f747, 0x473e219f, 0xf1eb93f7, 0xef6ad741, 0x707ee923, 0xef47fe3d,
-       0x6092f0b7, 0x1acd77be, 0x512dcb2b, 0x38c41156, 0x35cf9c7a, 0xc43c968e,
-       0xe9535c3b, 0x3eb738e4, 0x23ef1df4, 0xde2f3d52, 0x25fcdb99, 0xf2edcfd5,
-       0xe6d1f7bb, 0x8f3ce541, 0xb63e4bc2, 0xc5a35ed7, 0x43bda01d, 0x753bf396,
-       0xfc831188, 0xe1db2941, 0x7da8551e, 0x001c577e, 0xfaca47ea, 0xfe97f441,
-       0xdd178d15, 0xc4068fb5, 0x6e21e4b5, 0x93b5406c, 0x8c36c6e3, 0xb9bdf209,
-       0xded7b1e9, 0x4e22aad3, 0xd8c7e638, 0xfaa74f47, 0xefcf0266, 0xf00f73ee,
-       0x5c5a7e50, 0x53a46f5a, 0xebb5de43, 0x62e67d66, 0xe97c755d, 0x4bd7d778,
-       0x9e21b7c7, 0x5dfcf18a, 0x6eba17eb, 0xafa5eba1, 0x2ea5e153, 0x977f03fc,
-       0xfad74faf, 0xfffb3ec1, 0xb70cfacb, 0xcc7df0b6, 0x07874ab0, 0x7ad77d70,
-       0x262edcdd, 0xf1783ee0, 0xa441f725, 0x5f7cd24b, 0x8a967f80, 0xc05c1331,
-       0x81cd4b91, 0xdeb4279d, 0xef59eff2, 0x077a90e1, 0x7cd60ae2, 0xbd79769d,
-       0x1af521dd, 0x7ed60b62, 0x374ced2d, 0xe43d7ce2, 0xed1fb1b6, 0x1e3d70cd,
-       0xa3ccebc3, 0xf1a71c75, 0x96a243a3, 0xd7120fcf, 0xf1df58fc, 0xcb8f52da,
-       0xee72cc5e, 0x6e59a778, 0x514df09c, 0xd09dc623, 0xd68e442b, 0x6837e1fc,
-       0x9a275efd, 0x7bd0dfb8, 0xf26837f2, 0xf93de869, 0xf26886e7, 0x01488a65,
-       0x3c2f1a9f, 0xbded2e12, 0xd92ef183, 0x2f46926f, 0x8c556e69, 0x9f083d06,
-       0x55f1cc15, 0x8b9077bc, 0xbf9cfd71, 0xfd38045e, 0x3f7208a1, 0x22918993,
-       0x6c2123ff, 0x79039df2, 0xf55ab33f, 0x2ce427fd, 0xc2e65efd, 0xd8abdf70,
-       0x4e44af77, 0x28f78f99, 0x4b8c15c6, 0xe303bb47, 0x1c9f2cdd, 0xbcb1a470,
-       0x8b657d84, 0x6f7fdaeb, 0x6e92f9d0, 0x9106f795, 0x3a60dee2, 0xe9d7966d,
-       0x86fe41fc, 0xed0215ac, 0x71cdb826, 0x1ffb7a38, 0x6b0ac6ba, 0xfdfccf41,
-       0xfa7bb987, 0x66f3aec3, 0xb0f1a0ec, 0x7b19bf83, 0xf7cc78c5, 0x163ed8cd,
-       0x39d98699, 0xbd3179cd, 0xa74e793b, 0x26f1aee7, 0xcf7c6b08, 0x1af1d678,
-       0xcf1d4f8a, 0x2f5e02ff, 0x2fd78774, 0x37290b06, 0xa23e4a47, 0xac2ab7e3,
-       0x1f671ef3, 0xa5445c63, 0x33e9e243, 0xb87b8c80, 0x3cf15775, 0xfd17a93e,
-       0x7545ef81, 0xd43cb8a3, 0xc736250e, 0xc77f5e70, 0xef83ccec, 0x7c122746,
-       0xea7c39d7, 0xd9cbc250, 0x492660fc, 0x0d93e230, 0xfaef7c0d, 0x07aab3dc,
-       0xeaa57ff2, 0x4f01eb5e, 0x3f655379, 0x95e6f8a0, 0xc509f864, 0xa3e3eee6,
-       0xaf121d2b, 0x32b3feba, 0xa7f788ad, 0xca241570, 0x3de4d5f7, 0xe81e5d72,
-       0x8be3261f, 0x3dccfbf5, 0x232307c9, 0x1feb1f24, 0xbeaef926, 0xf38ed49e,
-       0x48cfd449, 0xf74953e2, 0xb03eb045, 0x1a4de5db, 0x78ca7f0a, 0x75a79261,
-       0x97a3bfbd, 0x5af03f7c, 0x68d0f991, 0x643f8fca, 0xef2a0113, 0xf14c2f18,
-       0x946f8564, 0xfa16bbf2, 0x44b098fd, 0xfc0cafd2, 0x611ddc20, 0x32346f7a,
-       0x8f94ce2b, 0xd533f4f2, 0x6a95198f, 0x0ef58f2a, 0x4fc79531, 0x7be537cc,
-       0xaa655d17, 0x58f667df, 0xefafbe53, 0xa4fd5306, 0xbca669f2, 0xe49297ce,
-       0x76a03127, 0xc0fda9ae, 0xfd5312ba, 0xf9857f14, 0xf7bf54fd, 0x9e025648,
-       0x697f9477, 0xbc87966b, 0x96116aaf, 0x90ef5d91, 0xde5a3afc, 0x5ce89907,
-       0x6491efc4, 0x0cccfd34, 0x8a8dfa8f, 0x46292673, 0xae24f7e1, 0x60f99b73,
-       0x3f39a261, 0x2af795de, 0x2b9c6e96, 0xa828fe34, 0x6a929e80, 0xf3efa6ad,
-       0x347c6a86, 0x9eb2e457, 0xefeb5dfe, 0xff5a621b, 0x4e5d7c50, 0x05e7cf0f,
-       0x6f9ed2dd, 0xf9ec179c, 0x9ec0bc46, 0x9ec3cc6f, 0x7b0fac6f, 0xf61cb1be,
-       0xc179637c, 0x8c1d3321, 0x83a66238, 0xe99a8e2b, 0xd0cfa740, 0xd5b2baf5,
-       0xa7c21f4c, 0xb07f94f8, 0x6a7f575e, 0xf5d09fa6, 0xd78b0921, 0x1153826f,
-       0xfbfca48f, 0x642eb5eb, 0x87d73abd, 0xf6f90df0, 0xbe50e0da, 0x48785b27,
-       0xe4b77815, 0xd79e6d51, 0x27e5ad0d, 0x7d5bb6c3, 0xae7de6bf, 0x5f4355d1,
-       0x871d5749, 0x1f070f9e, 0xffa4347d, 0x02f9fbd7, 0xfe3b3fa8, 0xf41db262,
-       0x45df2ed1, 0xee1f036b, 0x49b715dd, 0x77bcba7a, 0xe39533f2, 0x9a598e18,
-       0x82ebf014, 0xf036df18, 0x6bb39bcb, 0x1367f815, 0x458ed145, 0x8ff9cb88,
-       0x17e464b0, 0x77f7940c, 0xdf2b7645, 0xe2f9d07f, 0x17192482, 0xf35432d8,
-       0xdc647af3, 0xa543f3ce, 0xe3ca24dd, 0xe2e338e2, 0x83bf796c, 0x05e499d4,
-       0xe1c7c039, 0x47c041f0, 0x69df85b3, 0x39b9b56c, 0x86ffc46e, 0x83f7e02a,
-       0x72f90b1c, 0x35df2680, 0x0070e47c, 0x85eb41fe, 0x1c1d9ce9, 0x5be29870,
-       0x99736e87, 0x892d39f2, 0x76c3faa6, 0x79e54dbb, 0x79532cc1, 0x298f21c1,
-       0x28c8e23f, 0x8e2bfd53, 0x2bf94d7a, 0xea9a275b, 0x9169fd5f, 0xda249f29,
-       0x077e061f, 0x3e8f522a, 0xe2553433, 0x7e382dc9, 0xb19dc16f, 0xa6a7def2,
-       0xba72eb5f, 0xd3ecf71e, 0xde5439e8, 0x71f7681f, 0x5f43751c, 0x187be1e1,
-       0x129f4d0e, 0xa7c03d66, 0xde772dc5, 0xe39bf0a3, 0xe578f596, 0xd3417d4e,
-       0xdd39740f, 0x35ecaf10, 0x082f2bc6, 0xe03dfeeb, 0x3dd6d2ff, 0x7681fe14,
-       0x9f86df39, 0x88def9da, 0x3c28570e, 0xda38b533, 0xefee8e2d, 0x25b2d8f5,
-       0x1465259d, 0xfef41dfd, 0xcad3cd98, 0x365fdd6f, 0x4fd5a79e, 0x0bf0d5f4,
-       0xfba567bb, 0x305bc7bb, 0xbe67ce4c, 0xd4f372c5, 0x32cf8e6c, 0x3bdf83bd,
-       0x51fdea5b, 0xf3b74ab9, 0xe323105b, 0xdd8c44a7, 0x79edfa0d, 0x44cf893c,
-       0xfbe468bb, 0xff9c5a47, 0xee5b6b4d, 0xf3454419, 0x7bda4ded, 0xe81b0160,
-       0x9258d261, 0xd884f2c3, 0xb35765b6, 0xc7a2e493, 0x3f6cacea, 0x35ddbfe9,
-       0xceb8248b, 0x49031bfb, 0x407d01ef, 0xb4be81b6, 0x71e54721, 0x1b9ec1ae,
-       0x4df6fd81, 0xfb3d9c67, 0xced08405, 0x754fa90b, 0x874c6f43, 0xaffe3cfa,
-       0xf143ede3, 0x42adeba4, 0xd74c338b, 0xd7f1d2e0, 0xf0d07769, 0x707fdfa7,
-       0x6d15b32f, 0x8a3df272, 0xd2db8889, 0x4725afd7, 0x86ad65d2, 0x3f03d40f,
-       0xa15ea9ea, 0xfb031d9a, 0xc7708772, 0x43a1bab8, 0xc2bffd3d, 0x9eff8e8b,
-       0xc4f557ee, 0xc2f9421f, 0xeab7dd77, 0xd9ff4e89, 0x3e06577b, 0xb468e321,
-       0x5ba40975, 0x677d3fd8, 0x6f3f7994, 0x8d7696cc, 0xa2beda71, 0x6799ddf3,
-       0xf60217e6, 0xaa5586f1, 0x39e42fc6, 0xc4529c5e, 0x3a8b11ef, 0xe533cb17,
-       0xcfd62f1a, 0xc80f85d7, 0xf5aee0f7, 0x455c2516, 0x9b6692f9, 0x15a048d8,
-       0xf38fbbfb, 0x1b93bf66, 0x449efe71, 0x3726cdc0, 0x49b4b71a, 0xb94fec09,
-       0xc5ecbdfc, 0x5c7ef94e, 0x8bd9bbe8, 0x2f17fd35, 0x86df602a, 0xcfee65fa,
-       0x8f6bced6, 0xe12b7cf0, 0x0ba5bd67, 0x02de8d7e, 0xe8311df2, 0xf3b4aac3,
-       0x8e969c70, 0x24fc3737, 0xc2795df1, 0xce16446f, 0xb76b46f3, 0xf89d7471,
-       0x9d2afdd5, 0x1cc3c27e, 0x171a1faf, 0x4affd670, 0x1a7e7774, 0xd3d37fdd,
-       0xdff4e83e, 0xa85f877c, 0x1e8969c3, 0xff043e05, 0x57e8dbbf, 0x8248f3f9,
-       0x3127fd90, 0x6ab48ff0, 0xb98d89fd, 0xf44fdddd, 0xf1c5d8ad, 0xbe2cab10,
-       0xf25c40ff, 0xef1fea19, 0x3ce5deb0, 0xf8fb8090, 0xd3bb3493, 0xe4d6f3e5,
-       0x7ef2d1b0, 0xe55f8740, 0x2898eef5, 0x1f1373ef, 0xba77d815, 0x08aa7f1f,
-       0xfbaa42f6, 0x466b7c49, 0x3f75fe31, 0x14707149, 0x61b339c3, 0x484f0db1,
-       0x7b7c3eb6, 0xcbbb8461, 0x403ad27f, 0xe4f4e7c6, 0xc97e9947, 0xb8cdfdc3,
-       0x73f71574, 0xca453b2c, 0x2cf78d6b, 0xd90d9d03, 0x67986c26, 0xdffbadab,
-       0x23929819, 0xf852d1f7, 0xe21b7bd2, 0xac28567e, 0x84572c07, 0x7cc4071e,
-       0x6c5fcf5e, 0x3285f2d2, 0x992acb7f, 0xc5ded56f, 0x3bd9aada, 0x98a44f30,
-       0xedf0f40f, 0xf3043d9a, 0xe0798a40, 0xf21af83b, 0x83c86be0, 0xbe0f21af,
-       0x0d7c1486, 0x51444bdf, 0xfd2a9e72, 0xfb0de33d, 0xf19efe03, 0xfe09b906,
-       0xfe1e631e, 0xf87d631e, 0xf0e58c7b, 0xe1cb18f7, 0xe1e631ef, 0x87d631ef,
-       0x8798c7bf, 0x1f58c7bf, 0x1e631efe, 0x7d631efe, 0xe58c7bf8, 0xcb18f7f0,
-       0xe631efe1, 0xd631efe1, 0x58c7bf87, 0x629d737e, 0xacdd07f2, 0xba503bbd,
-       0xa3e98e3e, 0x2928b539, 0x3ff7d687, 0xc7e7ff23, 0xf3ac54b6, 0x6efc25de,
-       0x47845560, 0x44d373ae, 0x2116eeb9, 0x0e7db9d7, 0x76edf3af, 0xf1942f99,
-       0x03f4a1c2, 0x74f8cabf, 0x0a4157e9, 0xf8520abf, 0xafc29055, 0xfd2ade32,
-       0x57e1482a, 0x55f877c1, 0x82afc290, 0xa4157e14, 0x8520abf0, 0xfc29055f,
-       0xbf07682a, 0x55f8520a, 0x157e1df0, 0xe0abf0a4, 0x038231fb, 0x2e1d15fe,
-       0x26e9f9c8, 0xd0e8943d, 0x4cba87a4, 0xc6f9c879, 0x8df390fa, 0x8df390e5,
-       0x8df390e5, 0xc6f9c879, 0x8df390fa, 0x88f11bf9, 0xef296f71, 0xde41db1b,
-       0x9a73e637, 0x86c1affc, 0xf9c37935, 0x46b69157, 0x2e298f29, 0x9e72eb92,
-       0x58ff059a, 0x1c92b86b, 0x763921eb, 0x8d676fc5, 0x89f892bf, 0x2b976f16,
-       0x6f582dda, 0xbad37bf6, 0xe38282f9, 0x3bfe7383, 0x7f75cb91, 0xbad1ff2b,
-       0xac14ede7, 0x90cb6c37, 0x3dede970, 0xd522a5c2, 0xbbe577eb, 0xbe3a17af,
-       0xa5f98f5e, 0x28520e01, 0x910710f3, 0x1f33bb77, 0x2d5bedf1, 0x5d0b8c8a,
-       0x4372e329, 0xe349aae9, 0x3b2d5b4b, 0xbb50440e, 0x83c562f6, 0x5699077b,
-       0x0f96c871, 0x43e6d53c, 0x89cba89e, 0x6b83e2d5, 0x903c42af, 0x7f6eb70e,
-       0xf7c13e24, 0x0bb746dd, 0x738d197b, 0x8ec217cd, 0x64985bdf, 0xda04f297,
-       0xea1cdf41, 0x0c9bbc57, 0x4732bdf4, 0xff3e7b9e, 0xe8caabb2, 0xb5edd0fb,
-       0xdd1ee157, 0xeed908a4, 0x33478f37, 0x2a34a71e, 0xc9fef09b, 0x8bc2ede8,
-       0xd4bfb1fb, 0xddba1ee0, 0x71e32f65, 0x4eff7c5d, 0x4378b7ef, 0x2c17df32,
-       0x13e3ad16, 0xf0a127d9, 0xde3ae6fb, 0x62af7e68, 0x0fe2c47e, 0x2ffc8ec1,
-       0x7121c3df, 0xc3dcfbf1, 0x6c7866b9, 0xc4dbe221, 0xe40ef95e, 0xabc5e1e4,
-       0xbe5c137a, 0xf2077c80, 0x5f6a2f9a, 0xf966fce3, 0xcf93240e, 0xcf8f8648,
-       0x857e41c3, 0xe298ffdf, 0xe5e968df, 0x15e0bdc6, 0xdfd404b6, 0x0b503c2e,
-       0xaf790906, 0xb6579f55, 0x57096238, 0x95e22f40, 0x11fd0378, 0x7a0198e7,
-       0xf8d8f3c9, 0x56a9907d, 0x46fc0d97, 0x5d8a7397, 0x7542ec72, 0xf7df0c74,
-       0x2e13910b, 0xb8e6f636, 0x8e3d7f8d, 0x93ef83a4, 0xce15df2f, 0xf88f8572,
-       0xb9e6f807, 0x5977193c, 0x91c3ecb9, 0x38aed496, 0x8129d392, 0xf3df78ad,
-       0xe88eea74, 0x11cb0a51, 0xdb5fc087, 0x7be79f1a, 0x5eabc582, 0x1710fbe3,
-       0x96881f1b, 0x7fa4aaf7, 0x9bc34ca5, 0xa85a6f6e, 0x16994fad, 0x5ebc743f,
-       0xe74bcfbe, 0x71f7bf30, 0x72c6d1b1, 0x28bca846, 0x880feb84, 0xb46f2b73,
-       0xc5d3ddf1, 0x27578b6b, 0x777eee8a, 0xcfe32bc5, 0x349771b5, 0xa84e38da,
-       0x2b477b5c, 0x965877f4, 0xd2e8726a, 0x27efe66d, 0x4fe44272, 0xad44fdfd,
-       0xaf5bf14e, 0xa83964cc, 0xee71c6d6, 0xb94857f3, 0x0110ec48, 0xbf9867dc,
-       0xef059c62, 0xe5dfcc58, 0xd0dd28f5, 0x7c9a3bd1, 0x12830934, 0x8a5ea7de,
-       0xed32be60, 0xcfce3f52, 0xe9c894ba, 0xe4b2978d, 0xd11dac77, 0xbca16b4b,
-       0x26beff5f, 0x1c44cd17, 0xb2e40165, 0x1dd74c3e, 0x2218d744, 0x4357e357,
-       0x302bcabc, 0xf9b24fc3, 0x734e2156, 0xf7c146d2, 0x7e432691, 0x90d982a2,
-       0x2fb00aa7, 0x3ef90a52, 0xef8544c6, 0xbe1e4cb7, 0xb407db4c, 0x11f3042f,
-       0x37c3f77e, 0xf1006a7e, 0x3b7db337, 0x7d77582c, 0x6dfcf83f, 0x64e60efc,
-       0x7bc762bf, 0xcf4d3e81, 0x743de9d6, 0xd4882c5f, 0x694e63ec, 0x8fb4eaff,
-       0x9c7e5801, 0xc446f227, 0x2d802eb3, 0xb0b69fb3, 0x6ca8aa84, 0x1b9c9e59,
-       0x94236379, 0x6ed37fac, 0x9162df32, 0xfe489ff7, 0x717578e3, 0xe50fb0a4,
-       0xf92ad78b, 0xe1d79788, 0xd8d87afa, 0x777ac349, 0xe74941d1, 0x03eeccfe,
-       0x5df960bd, 0x4cff2619, 0xf84a5a68, 0x105a3ec6, 0xfc63fad3, 0x5c84d0d2,
-       0x889f1de1, 0xf9f5c877, 0x02e2208a, 0xdbf96ae7, 0x8ff2bd9e, 0x278c9c6b,
-       0xedcd8fce, 0x3fe22377, 0x38fe65fe, 0x7f1ab15f, 0xf14daa37, 0x3de57379,
-       0xdf5809c8, 0x7e76ecc8, 0xa66660c7, 0x212f9e4b, 0x72db9676, 0x845df2dd,
-       0x694b7b10, 0x846f3cb6, 0x8f3c9dd5, 0xb66e3afd, 0x3ef3ea57, 0x33df336e,
-       0x5cead3d5, 0xbff83769, 0xa0f127ba, 0x7ffbde45, 0xf1d812c4, 0xa06bd122,
-       0xe6016fb7, 0xbde208fb, 0xcf1f7e19, 0xa3477f4f, 0xef694f93, 0x74f4e865,
-       0xdf22eeac, 0xda712897, 0x9e81aadd, 0x7c28d6ca, 0x4ea4b11f, 0xadf627de,
-       0xfcbde451, 0x8f57ec1e, 0xdf9af9cf, 0x17fc7a51, 0xc350b211, 0x91fb7cef,
-       0x5d291cd7, 0xdd53fdf8, 0x7f926caf, 0x6f103306, 0x9c36b73f, 0x7afe41df,
-       0x018fd158, 0x87b6647f, 0xf11269d7, 0x1a9fd434, 0xbe29fbe3, 0x07238897,
-       0xf05c6f61, 0x7df8b7f3, 0x29bd9ae1, 0xf161eefc, 0x78d5bcee, 0x61ebe547,
-       0x89723bbe, 0x2e9d8b7e, 0xea90e43b, 0x973e58c6, 0xeed1f417, 0xf6768ba9,
-       0xf3ebe9e7, 0x0794ae60, 0x9c723c8a, 0x453e9a0b, 0x354db308, 0x7fe793d5,
-       0xedd43ee8, 0x95f6a1a2, 0xbe2af7d0, 0x7b029ecb, 0x5760dd89, 0xb631edd5,
-       0x7073e3ac, 0x77b7cf9e, 0xaf8dbbff, 0x4d4776eb, 0xa9d85d9f, 0xe84f66cf,
-       0x9d7fb903, 0xbd1d82e2, 0x11bee9cc, 0x8765f5f1, 0x14f0886c, 0xf2dce293,
-       0xe4bb92dd, 0xb72525bb, 0x9b3f31e6, 0xc7c9358f, 0xbc5187bd, 0x9402cb8f,
-       0xdfbcf7c6, 0x657bade7, 0x53d01ec0, 0xe0f7cbd0, 0x7b5e5ccb, 0x2a2e419c,
-       0xef4c526d, 0x17f9e818, 0x721da573, 0xc019a93e, 0xa6b74ddf, 0xd086f1d8,
-       0x108f127c, 0x46baf837, 0xaa3b7a27, 0x932571c7, 0xf941c552, 0x9dc114ae,
-       0xfe33c722, 0x9349514e, 0xaa063df9, 0xfedd72cf, 0xafee28dc, 0x4ef345d8,
-       0x3862ea41, 0xa78c0f09, 0x3fa87bf6, 0xebc38f37, 0xd80c1a51, 0x8f983760,
-       0xcfca1678, 0x186c0575, 0xbe51a4a7, 0x2b5be28f, 0x89adf1c7, 0x2e40e7b5,
-       0x03ecbab0, 0xa360f28c, 0xbe78cf7c, 0x0411fbf6, 0x65cbcb2f, 0xf3dc2784,
-       0x867defd2, 0x8358abe2, 0xd629acbf, 0xad365f2c, 0xe67d61b3, 0xc35ef0f4,
-       0x971d1a97, 0xfbe18e34, 0x2f5665f5, 0x69f097df, 0xb2ebfef8, 0x27e1bbf0,
-       0x90fcd399, 0x8d79052d, 0x3c097d2f, 0x829e06f7, 0xd23efc19, 0x678e70b2,
-       0xe26ae39e, 0xfbe276f9, 0xe40fc201, 0xe3115715, 0x8fc4e89b, 0x66b2c038,
-       0xc176faf3, 0x65df2513, 0xfde62e6f, 0xb3eac8b7, 0xac708cbb, 0xfb819fdf,
-       0xdf68735b, 0xe127fde3, 0xcc7df1f2, 0xc8dc0f53, 0x3806fbbf, 0x8f28e781,
-       0x3bde027b, 0xba61ba22, 0x4167e9d6, 0xfacfdc81, 0xacc35178, 0xec3f0ed2,
-       0xf7a9f6bb, 0x06f3e420, 0xffd86f5a, 0x76a7da7b, 0x71a4005c, 0xddf265ed,
-       0xab7dd0ba, 0x9f7d57ef, 0xdf56fbea, 0x8ad98fcf, 0x174a8982, 0xbdf3a1df,
-       0xf06eb9f6, 0x77834934, 0x84aeb6ae, 0xc18557d7, 0x986237ae, 0x53f3dfdc,
-       0xfd1ffbcd, 0xbd54dfa1, 0x03306c7c, 0xfaf53df7, 0xe3f3b8fa, 0x03ec3b64,
-       0x30ea5bd0, 0xe5fd674b, 0xe262df5c, 0xfc9da51f, 0x04aafb63, 0x0a1d8ff0,
-       0xdf96e1fb, 0xe5bee523, 0xe17bc8cf, 0xf8bf9667, 0x77aa2cf6, 0x0b8dc1fa,
-       0xca2ff78c, 0x2c5f9282, 0xfc0b7924, 0x0f269163, 0xe5f4cc6c, 0xe7ec330d,
-       0xc99ffbb2, 0xdb98fec4, 0x6f0a7792, 0xf9bcd1a8, 0x3f3fa3bd, 0x5787d2f3,
-       0x5dcebbb9, 0x6b251e7d, 0x3b15b5de, 0xf493788d, 0x0756777e, 0x38a55b9f,
-       0x6953e8b7, 0x61f33163, 0x8f7a4891, 0xa1eeb5d2, 0xa8dc50f4, 0x5a579cb0,
-       0xfea03237, 0xd2ebf22f, 0x8df953b5, 0xf4bd7d28, 0x73f45f77, 0xa67f8757,
-       0x35734eb6, 0x4c3d9e7a, 0xe5b9c3ee, 0xbc45f629, 0xf8ec53ff, 0x5a39cdbd,
-       0xf3329cf9, 0x72f5cef7, 0xd5fbf275, 0x9fb827d8, 0x58eaf584, 0xcbf6936b,
-       0x57ad97ed, 0x1d02e432, 0x9d9ac58e, 0x6f66a172, 0xcbc9a45c, 0x8d8b5eb4,
-       0x71f8b5eb, 0xcfa55eb9, 0xbc17f5be, 0xd3f34653, 0xef93a3de, 0xecb4940a,
-       0xb39b75e0, 0x852d9d66, 0x5864fdea, 0xa8fe298a, 0x05cf36b4, 0x35dcfd3b,
-       0x07e06d1b, 0xf126193f, 0xf3f74a16, 0x1d62f8b5, 0x148f38af, 0xaf473f83,
-       0x83b83e0f, 0x5975b9c6, 0x77f1b478, 0x3d1a02ed, 0xc6c6d697, 0xdad2bc61,
-       0x7fa17be2, 0xe840e7e9, 0x2e113bfe, 0xf50945f7, 0x6279fd87, 0x55ef878c,
-       0x377ed7cf, 0x43feb42f, 0xdafddd1a, 0x4cbfdf26, 0x92796c8a, 0x226a3be3,
-       0xe913e03c, 0x8c01ade9, 0xdc067a0b, 0x2f7c8b76, 0xf5b2bd33, 0xa241c073,
-       0x20f5c73c, 0x105b7bc5, 0xbf2813ed, 0x79ef22c9, 0xdd32aaa5, 0xa607e1a7,
-       0x5e8b9437, 0x5f1efcad, 0x2151bbe7, 0x9b176af4, 0x1fdde0d7, 0xefc12f7b,
-       0xa9f4e9a6, 0xa7d3a3f7, 0xcd3dbf4e, 0x9cf7d76f, 0xcd1489df, 0x49e592ce,
-       0x0bb8d076, 0xbfc41bee, 0xf35df16b, 0x35ef6bb4, 0x4c37ce76, 0x65c7defe,
-       0xfa974df3, 0x6df3cf52, 0x66e84c2e, 0xd4f3a1be, 0x431e89f7, 0x694fe9df,
-       0x1394fe92, 0xd4639d0a, 0x70b2c4ee, 0xe7d3ab8e, 0xbff5dba5, 0x8f87bdef,
-       0xf669c586, 0xc828d6aa, 0xdfb5f397, 0x99411151, 0x86a9f7c7, 0xaff9faef,
-       0xf3a75fbf, 0xdab593e9, 0xef5a28f9, 0x75167ec1, 0xf50f7c69, 0x2889d358,
-       0x627313bc, 0x6f4f848c, 0xde4dab77, 0x76511673, 0xbbcfde37, 0xfe3cd6e9,
-       0x8d8594bd, 0xbd9f587d, 0xf98d2ea9, 0x587e4dc2, 0x1ea74517, 0x83e348b0,
-       0xaf16b791, 0xd7f502be, 0xc2eff0a7, 0x4e7a742d, 0x43f6e7ad, 0x2313903d,
-       0x53daa79b, 0xfa961e59, 0xbb17ee82, 0x7c451155, 0x127c0d4f, 0x3fb2cbfb,
-       0xe2cfe71d, 0x983f52f5, 0xe06b1164, 0x50d81d3f, 0xf82fa134, 0xfc8ac3c4,
-       0xe60d9a3d, 0x0e86bcf7, 0x7c02fa2a, 0xbc5df426, 0x5e2d6d5b, 0xe482a7e8,
-       0x16d1d80e, 0x9e588b3a, 0x93e345bf, 0xf8db9ac7, 0xaf1d7ebd, 0x78bfe08f,
-       0x7ec42aa7, 0x1a276a14, 0xff07d9a8, 0x7b8faf1f, 0x0080003d, 0x00000000,
-       0x00088b1f, 0x00000000, 0x7cb5ff00, 0x65545c0b, 0xce7bf8da, 0xc0cc2b99,
-       0x1245c880, 0x85848b87, 0xd780c034, 0x508151da, 0xb9bba0bb, 0x658e21ba,
-       0x500665ca, 0xd7775ddb, 0xa6a18cfe, 0x45fa7d66, 0x80ed65a6, 0x76c36a97,
-       0xa8283448, 0x59990bc9, 0x6a37627f, 0x5b63b92f, 0xba402de6, 0x6dbfedfc,
-       0xbcf3cf7d, 0x511730e7, 0x6fbefddb, 0x797bf9fc, 0x9f5ef3df, 0xcfbcf3fb,
-       0x8c346339, 0x63181b75, 0x418e8b2a, 0x89486839, 0x8d8c9964, 0x615f6909,
-       0xf6c3894c, 0xc645db25, 0x7cfb4046, 0x1962c893, 0xfa31d72b, 0x1fbf8f7d,
-       0x3c1f7631, 0x42f3c337, 0x07d634a9, 0xcc37d7fd, 0xd6c972a0, 0xf1ae6dc2,
-       0x2509258c, 0x606393b1, 0xb66ae3c0, 0xce258a07, 0x2b307719, 0x8da4d3cc,
-       0x73c325d2, 0xc7292bb5, 0x496f9fe0, 0x0c4943e3, 0xd4699dc6, 0x7b4377cf,
-       0x414e6981, 0xba5f8c14, 0x325b2a33, 0x6f5dfbfb, 0xc91b1811, 0x4673a558,
-       0xcc614b1c, 0x67e1ddf1, 0x1fb0a94c, 0xf304d398, 0x7709e57f, 0xa38ba0bb,
-       0x82492dae, 0xb3aa3c23, 0x7fa058a7, 0x6f31d895, 0x4e73cc12, 0xa04def70,
-       0x5338e6fe, 0xe5a1fac0, 0xccc63ae9, 0xff398ce9, 0xcf3487cf, 0x3b89e2e7,
-       0x8778c016, 0xce047f73, 0x1ff8f553, 0x6c3201f2, 0xb2cf689d, 0x8dbce1e4,
-       0x1c124d7b, 0x56637b74, 0xbee39c09, 0xda46c7c7, 0xf79f2f33, 0xa8b668b6,
-       0xdbcbda04, 0x6957c118, 0xd48ee85f, 0x5eeddc20, 0x696131a6, 0x28689a62,
-       0x956c48cf, 0x52dbca07, 0x06b9a2d8, 0xe10dbb7f, 0x899eeb00, 0x025492dc,
-       0x9f7b15ed, 0x79433248, 0xa5ebc8d6, 0x9c7a7f7b, 0xddff4045, 0xd5e20d5a,
-       0x0b1a62ae, 0x25d7bb8c, 0xb250dcd8, 0x12c668f2, 0x7d6ea310, 0x59b19199,
-       0xaf9a7096, 0x630e7b62, 0xc17dfeb9, 0xab3f6a73, 0x8fb8c562, 0xd903f531,
-       0x8bfca1cb, 0xe21f7bca, 0x7ab52ff3, 0xf1192b8b, 0xfcbc2662, 0x84548b65,
-       0x05fbaeed, 0xfac05636, 0xac1a637e, 0x6ac9165f, 0xf4a17c71, 0xcf049b57,
-       0xb2101c57, 0x787b30b5, 0x1ee6b766, 0xd1169103, 0xd389b559, 0x75768ad9,
-       0x7fe02251, 0x2d408b45, 0x3357950e, 0x2f2abe1c, 0x80e6664d, 0xb6b656fd,
-       0x8eb0cc68, 0x09ce19a3, 0x539e1dfd, 0x5e78a59a, 0x7cb185b6, 0x89fe27c0,
-       0xa53e6bf8, 0x3f0037b9, 0x2e1cadd5, 0xbede56ce, 0x3b900338, 0x1362b699,
-       0x26dea0d2, 0x6b3ebd50, 0xaa35fcc2, 0xfcfe7ac0, 0x9a586935, 0x354c4e08,
-       0xf0025490, 0xa3d194dc, 0xd73bfc41, 0x5d42f3ca, 0x0d5eb01d, 0xde48e512,
-       0xf1c06a9e, 0x3caf1a66, 0xd146b677, 0x6c33af78, 0x3609bb03, 0x61506d51,
-       0x4434ef59, 0x56b3b960, 0x715950cc, 0x09166173, 0x1611dfe0, 0x6122c591,
-       0x3d5eaaca, 0x3b501240, 0xf6845870, 0x83fb48dc, 0x0c719f48, 0x33e802b8,
-       0x06057991, 0xf9dfdff4, 0x7fce2e59, 0x17df18cb, 0x5eaeb60c, 0x017e7d33,
-       0x8b26c3d0, 0x5f4c8e7c, 0xc8f1d22e, 0xb0af4043, 0x6cd5a7bf, 0xcf073e83,
-       0x42e6c257, 0x08c2cc3b, 0xb984dfcf, 0xafdfc0f7, 0xce226f31, 0x54de74cf,
-       0xcc9af71c, 0xc35a25a7, 0xf5f60106, 0x63fb149b, 0x053b8fb8, 0x116cf8f5,
-       0xc58d2071, 0xfe6afd7e, 0xc2796d9c, 0x4ffc03a6, 0xa367e8e7, 0x4062e645,
-       0xf1519aa2, 0xc163a406, 0x60ab6366, 0x0f3307fd, 0x2e80cbdd, 0x31d01e1e,
-       0x5eaf9c2d, 0x7d3dcfcf, 0x0094ec20, 0x2a8f46fd, 0xf4165916, 0x2958ab37,
-       0x29943ff4, 0x9fd8557a, 0x9fd8dce9, 0xbe6d0ae9, 0x8196590c, 0x7a88d0fc,
-       0x78eff51b, 0xca011bf3, 0xe1e2e944, 0xe2573848, 0x3d4b052f, 0x3c1b29f4,
-       0x85fff4fd, 0x5352f4b2, 0xfca1efcb, 0x19bda475, 0xb0727751, 0x501d94f8,
-       0xa3c9b0f6, 0xf9f264b3, 0xf1dff702, 0xa2226fab, 0xfabeff45, 0x7bef4e07,
-       0xcea58ad9, 0xe9b8c022, 0x9b57921d, 0xfa7ef975, 0xa9e361e3, 0x39e18fd4,
-       0x5ba20dfb, 0xe1ffb010, 0xd37f710f, 0x14af0675, 0x17d4e381, 0x38ff3a7c,
-       0x751d1e66, 0x284646fa, 0xb1913ef8, 0x8c3cdc58, 0x7068b81f, 0x6fb9c137,
-       0xa14ff991, 0x488b1eaf, 0xf191e9f8, 0xe991c0a4, 0x7e9122b2, 0x5e8ad5eb,
-       0x4cb385f0, 0xe8d67f3f, 0x5e0cff38, 0xff386d12, 0xcdd6b960, 0x8ec18a60,
-       0x5727d254, 0x007fa792, 0xd740ca79, 0xfb6a97bc, 0xf90fc233, 0x78fc074a,
-       0xc02f0c97, 0x25f9c33f, 0x64bbfe79, 0x1065ddb8, 0x127e9c39, 0x6e992702,
-       0xf650ba14, 0x5863982f, 0x9f1fb469, 0x47ddd7ec, 0x8f099323, 0xe383ffe3,
-       0xdfc213ef, 0x01d62737, 0xff51b11b, 0xfc784598, 0x579fc05f, 0xf80bfeb4,
-       0x9fc50eeb, 0xe23d7f57, 0xd2d171ef, 0x0880fc84, 0x26d2a1c8, 0x0658f9c2,
-       0x932ffe23, 0xe09b2cc2, 0xffe4767c, 0x8fef889b, 0xfc2bdf22, 0x37d8a63e,
-       0x49e4f51e, 0x7dc19ec6, 0xb50f44f9, 0x10a766a7, 0xbac75f9f, 0xf01db013,
-       0xf117379c, 0xe876d82e, 0xfb7d2c24, 0x5df5865e, 0x1ecb0615, 0x5bbf6f38,
-       0xfe61a974, 0x8ef72886, 0xc36eb0a5, 0x1716995d, 0xd59633b6, 0x3ca07286,
-       0xbe7a82cc, 0x85cb8a21, 0xa4e90586, 0x277e0f87, 0x73c2ad25, 0x34b3082c,
-       0x6c86ff41, 0xa01323df, 0x6cd630de, 0x57d74171, 0x1dbe9605, 0xd1d1cfc7,
-       0x38730d3a, 0x323c36dd, 0x057a8dda, 0x7af3cff4, 0x1e593fa8, 0x0d9cf0c6,
-       0x6884b68d, 0x2297cba0, 0x61b3a3ec, 0x4e24a3ff, 0xd0c90dd7, 0xa136e50e,
-       0x387dc164, 0x6fbe78df, 0x17b082df, 0xfa2cc2f7, 0xd0591034, 0xb195727e,
-       0x42a5e509, 0x73a57797, 0x75c63779, 0xc9c2076a, 0xd4659d35, 0x937ffcc2,
-       0xbb814be9, 0x556c6360, 0x0afe1fb4, 0x70c8c59d, 0x7a735617, 0xe5974d73,
-       0xd7733562, 0xe65f080b, 0x96f8070b, 0x42414169, 0xadd93469, 0xe5faefb8,
-       0xf7091780, 0x527fe1cf, 0x619ee564, 0x2847e7f8, 0x4c88f32c, 0x328fe404,
-       0x0ca3f9c6, 0x6fe908e9, 0x0051d015, 0x75df31fd, 0x65c3a751, 0x6bf1823a,
-       0x70d3258d, 0x3f85cfbd, 0x89e363e4, 0x87f34a7f, 0x3656675b, 0xf40b0397,
-       0x9fd899f6, 0x51148eed, 0xf130ae5f, 0x7f644ef5, 0xc5f51a36, 0x79bd5fc9,
-       0x23c7961d, 0x86cb6e4a, 0x7c16dbfe, 0xfce2845d, 0x353e096f, 0x0b6fe39e,
-       0xb468fffe, 0xbf56ca43, 0x43fef449, 0x192859f7, 0xaf4e5032, 0x15a67d04,
-       0xb074e4b0, 0x74463ef2, 0x896ac890, 0xfd65e36e, 0x47a30c05, 0x00f37539,
-       0xbcca8ed8, 0x9747fff0, 0xce896c74, 0xa2c69f5f, 0x7433ea82, 0x0bfd4109,
-       0xcf41c94d, 0x171f8d6f, 0x39a67cf4, 0x3b3ea83b, 0xff505263, 0x82d32ddb,
-       0x9c4e77ea, 0x8e7fd419, 0xdd504e6d, 0x1f244cc6, 0x738aea3a, 0xe1bb013f,
-       0xdc92bab5, 0xe397544f, 0xd0f6aa63, 0xe805b37e, 0x5f3bdb24, 0x91ea0935,
-       0x43265687, 0x11cb537d, 0xf43c4f5e, 0x66e03245, 0xf9d1cb73, 0x53dbd02a,
-       0x45f43c6f, 0x6d1fd40a, 0xa7cfe2e9, 0x40a362c0, 0x39bcb6ac, 0x9af805df,
-       0x8adf629b, 0xa9779af8, 0xf98a28f6, 0xbdccd7f7, 0xb942592f, 0x06746730,
-       0xc53727ec, 0xbf3e10fe, 0x759ef62b, 0x1ffb0091, 0x46ab5b7d, 0x5d98bf3c,
-       0xa1e915b2, 0xf3a722ff, 0x91978853, 0x96097eff, 0x8a61d903, 0x3c92bd9c,
-       0x03adf854, 0x1512c6f4, 0xa54749c2, 0xe544ceb7, 0x2a78baa1, 0xd999d48f,
-       0x57638012, 0xc795065d, 0x7ed42cea, 0x95226ebc, 0x546cea27, 0x4c575bbe,
-       0x095d7765, 0xb2ff0a95, 0x6a0d96bd, 0x2a974224, 0x4fceb4ea, 0x63d2578f,
-       0x69d92820, 0xf9d09f05, 0x39adbd4d, 0x9d75ce9b, 0x6959e909, 0x81f9da3f,
-       0x9dfa0459, 0x3d11d56a, 0x9b74354f, 0x475e5675, 0x22fbb8b9, 0xbc118af3,
-       0x5fb02a9f, 0xfd1b278c, 0x030ea998, 0x841b4bf5, 0xefd8597e, 0xf79404cd,
-       0x16356b53, 0x509e63b4, 0xf61e9733, 0x90df146f, 0x20e31d70, 0x05d86cca,
-       0x903ad518, 0x6ba07157, 0x63f439f1, 0x0f77283a, 0x4746f5f2, 0xf9472ed7,
-       0x60ccba34, 0x95f2e7a9, 0x08e24be4, 0x2fee026f, 0xda86a571, 0x198f628d,
-       0x9d5f60e5, 0x69d21677, 0x0ae72c81, 0x30ef5c34, 0x80bde411, 0x576dfb7c,
-       0xedf3da22, 0xd02f9edc, 0xfa44ec96, 0xfe7156ae, 0xf77a3165, 0xd5475c1e,
-       0xf42cf15d, 0xb44d89eb, 0xc568426c, 0x6069641f, 0x14d617b7, 0xeddca267,
-       0xaf885b61, 0x13fd5ec1, 0x338fdbd2, 0x9945df81, 0xf89e6048, 0x4da6f0e2,
-       0xd7adda02, 0xce5d21e7, 0x300f9ad5, 0xf65f07e0, 0xdcfbd100, 0x7a1e7348,
-       0xafecbe0a, 0x7cce3d79, 0x26e78040, 0x00bf3036, 0xe9cf55ea, 0xf0049f4d,
-       0x1513d3a9, 0x4b69af54, 0xc0127d30, 0x07f855a7, 0x09b747fa, 0x0ebb942a,
-       0x04a72b79, 0xb7c405fb, 0x0d73f8b3, 0x0680dfdf, 0xd98bd8ed, 0xb06fa266,
-       0x0fef4997, 0x9bba34cc, 0x2371bf60, 0xa057b36a, 0xce6994fd, 0xea497ec3,
-       0x63f40881, 0x1555bffa, 0x19efc9bb, 0x78c9f888, 0xd33d7d3f, 0x287b5121,
-       0x70e6b5dd, 0xcd26af7f, 0x50f119b0, 0x51d3af1d, 0x88b171d9, 0x92569d91,
-       0x4db97686, 0xd0cbfdc3, 0xb8737bf1, 0xaf5e491e, 0xa240b921, 0x0b6cb608,
-       0xc5dd4a63, 0xf8d63226, 0xbf21b08b, 0x34c9c007, 0xc83f6563, 0x41476235,
-       0x1b7f505a, 0x8e7a1ff6, 0x8ff31cf6, 0xbb49794f, 0x5e4aad63, 0x2965e90f,
-       0x183fa373, 0x72abc72a, 0xc0b965a3, 0x8c74fcf1, 0x9cf111be, 0xe77d0126,
-       0x504cc950, 0xb2338626, 0xd75f1337, 0x773e91bb, 0xa7fd39eb, 0x2ddcbc89,
-       0x309afef2, 0x577a42e6, 0xb94d87fc, 0x79b929f6, 0xe6978f34, 0x91b25a91,
-       0x879813ae, 0x24ec57d6, 0x43d81fa5, 0xaa02127a, 0xd7c47481, 0x161c4954,
-       0xa672279e, 0x448ce515, 0x4fb1b0fe, 0x5f77e403, 0x40aac478, 0x78e355fc,
-       0xe9b8e043, 0xef194e34, 0x4fb2255c, 0x245c9047, 0x89a6723a, 0x4b562fe4,
-       0xfe8088ec, 0xa0d6eb16, 0xf5c6539e, 0x14fc1c82, 0x9047f0f0, 0x087e588b,
-       0xffd710f2, 0x2c43c833, 0x10f20aff, 0x3c824fdb, 0xf207d2c4, 0x063fdb10,
-       0xbce58879, 0xe4568dbb, 0x69b69a9f, 0x7e20d3ec, 0x017ddb50, 0xc369def5,
-       0xa64391d3, 0xe1e4dea3, 0xe1cbaf9f, 0x2def457e, 0xa0fd9f1c, 0x00ffd1bf,
-       0x8a6b5cba, 0xef1eb2be, 0x1ef9b237, 0x7cb6d380, 0x27f4876e, 0x1cd2faf0,
-       0x226dd535, 0xb7e38edb, 0xfaf86be5, 0x3e396229, 0x79f345b7, 0xb245d37b,
-       0x9e4ea69f, 0x9e0724b6, 0x3da162db, 0xbdef5fc7, 0x8db73f81, 0x7a43ede2,
-       0x253e7e56, 0xeff8a4d7, 0x652fdce9, 0xbd012764, 0xff4afcd3, 0x3e7226f7,
-       0x4eefed0c, 0xc3dd8b13, 0x992de3c0, 0xd02f896f, 0x483e469e, 0x6a8be00e,
-       0x4285f133, 0x55fd0a87, 0xa73872e5, 0x073a6569, 0x43f042dd, 0x3a72831d,
-       0x25f64f4e, 0xe0c6c5c0, 0x9905bb3c, 0x01f9425f, 0x0a07d44a, 0xa07c283f,
-       0xf0227bd0, 0x3fed1099, 0xf421cdc7, 0xca8f94aa, 0x358ee8e7, 0xdaf09cfe,
-       0xdfa136a1, 0x87cc3377, 0xc1c513e3, 0xfe46ef77, 0xd19a358c, 0xc87c2cf5,
-       0x1c9c3b50, 0xc2effaeb, 0x570b9143, 0x7065c780, 0x5ff2f0d0, 0x39c90385,
-       0xbf48e394, 0xfdadc8c3, 0x5db2d139, 0x44f7e9ce, 0xd21f6d8e, 0x57a0bf51,
-       0xafd0dfa1, 0xd9dac367, 0x7f39f2db, 0x05547428, 0x89eb103a, 0xcbd4ce78,
-       0x9e729ee5, 0x632e73a1, 0xc2d2ff24, 0x9e287b78, 0xc8057395, 0x0139c3bf,
-       0xb8c61ff1, 0xd81d717d, 0x4d4fe817, 0x3ed335c9, 0x567e47fa, 0xcff995b6,
-       0x6f0e477f, 0x88944a7f, 0x32fd141e, 0x8b482ed4, 0xe90664e6, 0x3f42661d,
-       0xfc4b53af, 0xe67f05ee, 0x3e871825, 0x3fe49b21, 0x71e320bf, 0x1158fe70,
-       0xafbebbed, 0x63d42e0d, 0x4e06a37d, 0x6fbe300a, 0x6436183b, 0x136ed897,
-       0x07deef40, 0xd4f5063a, 0x2c7b9005, 0x7273b19d, 0x73cfa11c, 0x73fa24f1,
-       0xa6243b35, 0x3b4a5003, 0xf4879abe, 0x6d53b4b4, 0xf6d0b8a2, 0x3d218ec7,
-       0xcc156e9e, 0xb5f49768, 0xbfa1f1c2, 0xd6e8c1b3, 0xa822ff43, 0x0665ff63,
-       0xd7ccdb8d, 0x4383f8a3, 0x7d53ef5e, 0x85c60a75, 0x1350ec66, 0x2f3e97dc,
-       0x3b3ed1b9, 0x0aa57dbc, 0x02dda7eb, 0x4571838b, 0x04aeead2, 0x2d3e57a8,
-       0xce30b458, 0x8b3a2861, 0xe7ca82f1, 0xf30bc599, 0xc918b657, 0xa0da5dcf,
-       0x6017d8fe, 0xb7bb945f, 0x29eed06a, 0x5edc19df, 0x0eb83bb9, 0xeff922f8,
-       0x00f68668, 0x8e6dfcf9, 0xcdec8631, 0xed1b2c71, 0xe3c0d64d, 0xbf7c8ab9,
-       0x71756edc, 0xcb82ba39, 0x8cbec66d, 0xea5f7f45, 0x63e92afc, 0x91cfaf03,
-       0xfea0a7eb, 0x2f1c57f9, 0xe5aa5c0a, 0x604f3fb5, 0xb79c0f56, 0x426f53ba,
-       0xfdbabfff, 0xb71811ef, 0x51f309af, 0x22bd9f7c, 0xdbded099, 0x10b926d8,
-       0xfd0ecebe, 0x56e0112e, 0x8d3de07d, 0x5f7088d9, 0xadcaf64e, 0xe31eb5cc,
-       0x64515edc, 0xdd4744dd, 0xb666a714, 0x4f38a581, 0x84debb5f, 0x2bf54076,
-       0x8ddd741f, 0xd30203f5, 0xfb471e23, 0xee964e88, 0x2da58640, 0xfbe426dd,
-       0xbc4244e9, 0x913d9e22, 0x8865af84, 0xe033c477, 0x212cf11d, 0x51bc713e,
-       0x2274e6e3, 0x73f4fd51, 0xde0abf1c, 0x1acda48b, 0xe46caf6c, 0x63b19e78,
-       0xa230b6cf, 0xe9933503, 0x7a7ef080, 0xa6bbc727, 0x14669d73, 0x08636fd2,
-       0x876bb41d, 0x77f700e8, 0xe0841d19, 0x8df002bf, 0x0e942072, 0x93dff142,
-       0xd806e5c3, 0x429fa7df, 0x7e08dbfb, 0x23c7f301, 0x1ef55646, 0xcaf5818d,
-       0x973bcfa2, 0xf8d8fb43, 0x08da5897, 0xe4157f8a, 0xe66bfc62, 0x5d10eb3b,
-       0xc85eb33d, 0x57a97a46, 0x813cf6fb, 0x70a88b71, 0x27f4e38a, 0x32f9d9cf,
-       0xfa20bb9c, 0xd816a49b, 0x5a6bcd7f, 0xc928deba, 0x35ec8715, 0xf129978c,
-       0xc533c074, 0x5a1d9cc9, 0x2d6b171e, 0x73fa05b4, 0x5cfc09fd, 0xb2819a85,
-       0xc017e8e5, 0x608eb87c, 0x555e7ee3, 0x28178f07, 0x1295597e, 0x8e0e6837,
-       0x77a6081b, 0x2e455fa8, 0xc6a55f8f, 0x3b466cdd, 0xb3017ebc, 0x4d5ea587,
-       0xcc78f03f, 0x74dfb2d3, 0x0af1fb45, 0x1bb1427a, 0x6e382b99, 0x65a9c8a1,
-       0x8f1ef913, 0x6ab8e2fe, 0x76fdc604, 0x8a8f840b, 0x704f900e, 0xdab70ade,
-       0xf802166d, 0x19ffee49, 0xedc01bd2, 0xa0f6ab8c, 0x19dd2128, 0x990ebf68,
-       0x8e91ab3e, 0xd695bce0, 0x9cf02237, 0x38ae590e, 0x7f148dda, 0x8a5b64ab,
-       0x612aee90, 0xf430ef3d, 0x0b5cf954, 0xa2d729f9, 0xaccec527, 0xb7ee0d6e,
-       0xce487731, 0xe01eff8c, 0x396401bb, 0x992e7bd7, 0xf12332fe, 0x99906fde,
-       0x879f9123, 0xedc09ff4, 0x5cfe4537, 0x3c581dbf, 0x6e71de60, 0xac05531d,
-       0xa673e37f, 0x4f78faa0, 0x9bff507c, 0xcf41ccda, 0x4119bdb3, 0x598f73cf,
-       0xdd79ea82, 0x4ffa8313, 0x5416d0f8, 0x0e2be49f, 0x4ce53fea, 0x307d5049,
-       0x9573ce13, 0xe35bc1fb, 0x33fea085, 0xf9a0facd, 0x05446767, 0x320d07d5,
-       0x52bb647c, 0xce5f77b1, 0x686ef6e5, 0x76f7c0a9, 0x8a3af04b, 0xc4e77ebf,
-       0xd8e6f5e0, 0xa1fbd782, 0xfa0bd978, 0xc27e0554, 0xb15fa073, 0x13f81dfc,
-       0x9a13f02a, 0xfac09fc1, 0x604fe08b, 0x027f01e9, 0x7f025fdb, 0xe0adeb02,
-       0x20fd604f, 0x6f583ff8, 0xf2a62bab, 0x6a12ba95, 0xbafc16bf, 0xc98f75e4,
-       0xd7971eeb, 0x74e177fd, 0x5def9e42, 0x9c6ebe79, 0xdcffcd2f, 0xbc563c59,
-       0x2d3cfc04, 0x87c6acfa, 0x5f0ac37e, 0x062dc611, 0xc61892de, 0x7ddd99a5,
-       0xf5062eac, 0x338a08d9, 0xb78192b3, 0x7d52ae31, 0xc9b4d520, 0x0fecfa8c,
-       0xbef3e2ef, 0x7c8cc956, 0xefeda879, 0x85cf3811, 0x5f74614b, 0xef107a4a,
-       0x5461bf1b, 0x31cf04df, 0x05b33a0e, 0x37e90804, 0x0bb7e90f, 0x4ddd4a69,
-       0xcd25bdf7, 0x53c41a2d, 0x3c29f215, 0x0ea3cb7f, 0x635cfe7e, 0xf61373d0,
-       0xe54ab287, 0xb9c238a6, 0x2f3e6536, 0xf1a477f5, 0xcf73cf7b, 0x053f5e1d,
-       0xe2cb6ff5, 0x5e7f7811, 0xec5efcd5, 0xc7c157bd, 0xc85f07e7, 0x76cafba4,
-       0x9fe0cf98, 0x96aed9cf, 0x8eff7ceb, 0x68a296b4, 0x02cd1c54, 0x05c50b1b,
-       0x5fee85b6, 0x38f6daaa, 0x65556e50, 0x0066addc, 0x248f7e9f, 0xbdf837c7,
-       0xb8c4c391, 0x22f9e71d, 0x5f57ef02, 0xc3bd1cf7, 0x38edf886, 0xf6eb811c,
-       0xfe414ab7, 0xb72b68d3, 0x355b478f, 0xad0bbf84, 0x5ef02387, 0x30e7a377,
-       0x4bcabb87, 0xd7243fe7, 0x7824a1fb, 0xfe7449b7, 0xd0624b8a, 0x5586763d,
-       0xb66679a2, 0xb9e2358d, 0xbd7c3c7a, 0xb799ab1c, 0x825e2da7, 0xbf1e3ffb,
-       0x7b224f20, 0xca350410, 0xef661bf1, 0xcaa43b41, 0xf386d923, 0x79e40aef,
-       0x4e9cd4bb, 0xdfdb4adf, 0x78f8f285, 0xd26c88f1, 0x699f8a11, 0x916f76e5,
-       0x7a869ec6, 0x3660c7a4, 0x583f9d22, 0xfc446a9c, 0xdb12c21e, 0xec69778b,
-       0xe6c7bc06, 0xba98f5eb, 0x7aee9023, 0xb425735a, 0xf2f99477, 0xe88775e5,
-       0x2e6f087b, 0xbbb953c2, 0xf8f380d1, 0x73dbc7f1, 0x7fea26ac, 0x3cdefddc,
-       0x327aabb4, 0xe92ec9c2, 0xa7f230d2, 0x5db99aab, 0xd891d3dc, 0x924f7818,
-       0xf2fd9563, 0xdaf0910c, 0xfb96a6d7, 0x0587bddd, 0x39d353f5, 0xde0eec2f,
-       0xea7dc98f, 0x1dc7b451, 0xf50c4b4f, 0x1b5d43a2, 0x6cffe78b, 0xcafef067,
-       0xd43b3865, 0x00d8d8de, 0x0fb4757a, 0xe8818df1, 0x13e15dbc, 0xc153e133,
-       0xb7064f63, 0xf9e27ae7, 0x65a3a4bd, 0xe5f5d10f, 0x64eea4f1, 0x7f121ff4,
-       0xe778a3a9, 0xc567fcb5, 0xaff0086e, 0xea8bfa18, 0x313cd4e2, 0xbc1f6fc5,
-       0xb6ab6b96, 0xabbf448e, 0x1ecafc84, 0xac2cf606, 0x3a7b44e9, 0xb61ff292,
-       0xad83bae1, 0x76bfba6a, 0x7d66daea, 0xa0d97602, 0xf6051805, 0x2d53b83d,
-       0x0cd97bdf, 0x952ed768, 0xcccfdaed, 0xf4097cf6, 0x488d73af, 0x866473e7,
-       0x27d31f91, 0x5bcfbdcb, 0xbb24ef92, 0x426498e1, 0x8786687f, 0x668ec1db,
-       0x7b56d76e, 0x2a63ff92, 0x6acdedda, 0x8a60d4cc, 0xed94e21d, 0xddb2d390,
-       0x80cd7a7b, 0x4e9bfc86, 0x8c963d81, 0xbb5b2a79, 0x33b9e112, 0xb3d91673,
-       0xec99a94e, 0x83db6589, 0x6fb007ed, 0xcf55ea82, 0x7217da85, 0xdc13cb7c,
-       0xdb87f8ae, 0xc67643ac, 0x0a67f438, 0xc871a9a5, 0x78c82f0f, 0x959bfc55,
-       0xb7942de3, 0x9e6551b3, 0x1021c4a5, 0xfb9d355e, 0x6edf702b, 0xfc859847,
-       0x10af558d, 0xe4bffb5c, 0x3c7f4c7e, 0x33f47823, 0x36fedf0e, 0x6a35e74e,
-       0x48f98dc1, 0x34b64035, 0xaf704e9f, 0x6bb338c1, 0x13e48230, 0x17c8c563,
-       0x7f70162b, 0x5f3186d5, 0x7e156b28, 0xb7abd108, 0x54527ca8, 0xb3689c80,
-       0x02bf50a6, 0x3ea3b30d, 0x90b4695b, 0xe3a31b7e, 0x6ae17a76, 0xc3d2364f,
-       0xb5c7f018, 0x31f8f101, 0xfb010186, 0xc7807eed, 0xc27895ff, 0x1d49951c,
-       0x191fa015, 0x95fd435b, 0xf0a241f9, 0xdf9ad7f1, 0xfc1bf304, 0x23bc03f3,
-       0x585fde11, 0x93b7a42d, 0xfff728e6, 0xca97c4b5, 0xbd002e79, 0x63181c61,
-       0xc7378834, 0x9fc837ce, 0xf5eeb273, 0x8228ae38, 0xf708a3ef, 0x5e30f583,
-       0xe79651fe, 0xbcbc79b1, 0xf9152e4d, 0x7b6790d5, 0x95f50adf, 0x593ff679,
-       0x8899ae49, 0xb4ca573e, 0x9c4cf602, 0xbbf9186f, 0xf0891de2, 0x03f005fa,
-       0x5ac2fbf2, 0x64169cc1, 0xaf3a712f, 0x3cec4de1, 0x454ef4f3, 0xdd6cb838,
-       0xc6d79819, 0x5a2d7f38, 0x05a737a5, 0xbd2007de, 0x0251ffa3, 0x2fd1f2ff,
-       0x5372bfe3, 0x57946dc5, 0x8cd62ab5, 0xc83517f7, 0xa6d7290f, 0x87ba50ff,
-       0xb7a44edf, 0xa0b5a66a, 0x0b69a97e, 0xa1516e7d, 0x084dfe3d, 0x74c9245f,
-       0xe81768da, 0x5bf1bd7e, 0x95a38f15, 0xbb37140a, 0x4e911a0b, 0xcafd87e9,
-       0x7e71b9a7, 0xfba0b3cc, 0x391886ae, 0xee862bef, 0x9f227ee1, 0xf7952eff,
-       0xa3efe40d, 0xc6324f6a, 0xf93a8e71, 0xe602d53d, 0x52dd7ba1, 0x6f654dd6,
-       0x2f01f578, 0x8d1aee4d, 0x7607f87e, 0x1a91c52d, 0x511936d7, 0xb5b166ce,
-       0x031fbc26, 0xfbee7936, 0x1bdb2bdc, 0x9468f7a1, 0xc7e7959f, 0x92bccaf3,
-       0x83a03cf8, 0xf8a38033, 0x57c7cb9c, 0x02207fbd, 0xfefe7ee1, 0xca7ef3fd,
-       0xb9020fd0, 0xd654f305, 0xbdd064b6, 0x67758b8c, 0xabf1fbe4, 0x1fc153e0,
-       0xf08399b4, 0x0eb9670a, 0x0d9f33e0, 0xd36e63e4, 0xc0a9f0b5, 0xf03d4939,
-       0xe8250463, 0xa1439231, 0x5ee05678, 0x3cd56acd, 0xeefb56fe, 0xb3ffe802,
-       0xed19a2b5, 0x7ef0cbca, 0xf578fc0d, 0x28d791fc, 0x257b3f90, 0x5a78297c,
-       0xff54bcc8, 0xfb8f8a30, 0xf144a170, 0x7c69ffc3, 0x4bd9e435, 0xb7c2aef2,
-       0x257a7ca1, 0x2ab45cbe, 0xf8437f84, 0x2d2f8874, 0x7f002ff0, 0xc41155f6,
-       0x1d7e0a8f, 0x5193f066, 0x2d1875ff, 0x3e39766e, 0xfdc5dfd1, 0xec0ab654,
-       0xf087e149, 0xe3fc8fab, 0xad017c50, 0x541f50d8, 0xa9f305e7, 0xc92bc782,
-       0x7dee452d, 0x4d47bcc4, 0x7067dd02, 0x9685fe3e, 0xfb94e9f2, 0xe2dee50c,
-       0x6fae3cd1, 0xc08fcb42, 0xa27bc16e, 0x233d194d, 0xd5ebded1, 0x7bf0f328,
-       0x74d68fd7, 0xcd7cc68f, 0xb2f1a68f, 0x4cf3c357, 0x8c2dba94, 0x4a3f03c7,
-       0x6e10bad0, 0xa6e3091f, 0x91f01da3, 0x783bcbf0, 0xc6634e3d, 0xe9b882fa,
-       0xaaf7a826, 0x83e1f895, 0x5376fcb2, 0x0982d1f9, 0x604fd405, 0x661e1047,
-       0x3ad09581, 0x0c5d1082, 0xe7e8f9fb, 0x5ef07363, 0x03ff3940, 0xf48e3c79,
-       0x431cf91b, 0x095ff6f1, 0x045f6f14, 0xf784c3aa, 0x289fd302, 0x93f6814e,
-       0xa6cd4ebf, 0xc115cafb, 0x4dfea3eb, 0x56e538a6, 0x4b96e79a, 0x99c5ea03,
-       0xe90d7dfe, 0xbc8b82cd, 0xa0d8c97d, 0xf45b667c, 0xbb27ee38, 0x8f512353,
-       0xf06d7a29, 0x60437ed8, 0x1cacf51c, 0x8faa1e77, 0x5029247b, 0xf7b1be2f,
-       0xa79c74e1, 0xb2cae35c, 0xf98f3018, 0x1fb424a9, 0x943ef7ca, 0xdeed764e,
-       0x9fe8e98d, 0x9c3d3794, 0xb87aa36e, 0x1523fc9d, 0x7df9f73f, 0x0a6d7693,
-       0x9d6fa3b0, 0x52fbedc0, 0x68851bdd, 0xf1bacedf, 0xb71875f3, 0x816bfb1f,
-       0x590b70e2, 0xb7d43af7, 0xaf9c1965, 0xe48e8358, 0xf747cc3f, 0xddc67ba4,
-       0xfee51bbe, 0xabbf8cf1, 0xcdfea097, 0x657cd153, 0x0e39bdcc, 0x041b6fe3,
-       0xfbf9bf8a, 0xd77ba68f, 0x4d056bc5, 0x51ea0c7c, 0xc7fd779e, 0xe38228bc,
-       0xbbb21b3d, 0x356cbdb0, 0x75a59f6f, 0x3ce0f6b7, 0xcf28684f, 0x4a65140a,
-       0xf63dc049, 0x3df8f31f, 0x72cda2dd, 0xcebcb1be, 0x8db16dd8, 0xa3fce781,
-       0xfe567f8c, 0x3b83c901, 0xb6dcbc65, 0xf123bdfa, 0xdaa46f30, 0x2b9467fe,
-       0x3a7e3eef, 0x4159e50d, 0xa44cd9f4, 0xfb1ab1f3, 0xee781593, 0x2bc52d26,
-       0x528959ad, 0xb9cff41c, 0x5863da7f, 0xf8bd5a2e, 0xfb8c0ac9, 0x1f91d76e,
-       0x856feca6, 0x5fd11660, 0xd3f8dc3d, 0x676e107b, 0xa479e71e, 0x8faf1a2b,
-       0xe2fe5abb, 0x1f3c75b3, 0x1d3af9fc, 0x99d42f95, 0xb88e1998, 0xea9e2eaf,
-       0x5333afbf, 0xfa73e6c9, 0xaea6f252, 0xa5ee5f34, 0xb65bca30, 0x1e51d06e,
-       0xf6d6ae7d, 0x6bc01e55, 0xa6ce0dec, 0xc6b9f28d, 0x576cf8c2, 0x83840cf2,
-       0x2ef2e375, 0xe54f6134, 0xedeaff71, 0x64490d9e, 0xf53eaf87, 0xcf3c054c,
-       0x0ef92fcc, 0x5e76ebc7, 0xe1c178a4, 0x10ca87f6, 0x5a4de5de, 0xdcf93e7e,
-       0x8f4f1e67, 0xbce3127b, 0x7fc9a96f, 0xea79d9af, 0xde508d99, 0x26b979bb,
-       0xe87fde90, 0xf795bf79, 0xbabe2d73, 0x75fe1c12, 0x89387abe, 0xf809a7f8,
-       0xe7dff32a, 0x6bd59aab, 0xf3737e08, 0xc3e6c64b, 0x5da8cffe, 0x674fc849,
-       0x744cddc6, 0x0814eaee, 0x571c8afe, 0xf3e6a7c6, 0xd12ae8fb, 0x48ec99b3,
-       0x057f8e59, 0xf7c2239e, 0xd2cff68d, 0xaafe8ed1, 0xcf55c16d, 0x3d0eb07d,
-       0xe99b8c22, 0x9e7d0ca8, 0x62a7b1af, 0xc8be715e, 0xe7d0e7ed, 0x712be7b7,
-       0xc5b71e78, 0xa790109f, 0x458d84e2, 0x13fea346, 0x972061bc, 0x9eb76d9d,
-       0x06ffa155, 0xc1c7e17e, 0x38fb2876, 0x695faf40, 0xab2ad7bf, 0x5f951e71,
-       0x50f84eee, 0x3d00de64, 0xc617c93e, 0x0eeb01bc, 0xa6d02bf9, 0x049efba1,
-       0x37880b92, 0x6bea87cc, 0xf584d71f, 0xc78e1ab3, 0x97e083be, 0x930cb8f1,
-       0x3ce7fdf2, 0x0b3e7edb, 0x79e86ce5, 0x4f395fab, 0x7b68e1f4, 0xe740a2e8,
-       0x9556799f, 0xbff3ed75, 0x167cf7b1, 0xdaacefe2, 0x57fe8f97, 0x8597c69f,
-       0x957ea878, 0x157ff3cb, 0xc57b4a0e, 0x138f0d06, 0x23f2260a, 0x140ba50b,
-       0xc63be807, 0xedd500e3, 0x0e9e48bb, 0x4c78f076, 0x145dd88d, 0xda8bf187,
-       0xcf285d53, 0x5fb9e306, 0x28dbf306, 0xd65521cf, 0xa481aa83, 0x1ed72039,
-       0xee07a219, 0xfe419e0f, 0x1e3ce0d5, 0x6561e507, 0x2bb43385, 0x433f21ce,
-       0xe4aad97b, 0x67e748f5, 0x507323dc, 0xf59dbe3e, 0xdf8a6a8f, 0x926e1ebd,
-       0x30958ec8, 0x4e0878c7, 0x4b70e743, 0x2987d13c, 0xb3387176, 0xd1abf405,
-       0xbf24ef98, 0x9fbf38fa, 0xf381b9ab, 0xf3857b13, 0x1bed7393, 0xf980f89a,
-       0x93f3257e, 0x7ace4f62, 0x97c41ffd, 0x9edae70f, 0x470cbe40, 0xc5f38859,
-       0xb51e5247, 0x72871ef2, 0x90e8691f, 0x8962f8fd, 0x49b4d79e, 0x58e5ef0c,
-       0x0af291bc, 0xca16d98a, 0x3cc59cb7, 0x8f5e7953, 0xf029d1ef, 0x52ebf67c,
-       0x81a1e62e, 0xdbf74d3d, 0x34f66145, 0x15ead3cc, 0x1eae1905, 0x7d009ceb,
-       0xf73e7ef6, 0x024aa757, 0x8481b1e9, 0x6653b270, 0xe29677ce, 0x5a7e957e,
-       0x9833eb91, 0xe62cec87, 0x7bc2c81e, 0xc81de655, 0xa556fbc2, 0xc3d7bcdf,
-       0x322f496b, 0xc05e758f, 0x79f3a73a, 0xbc0bf3bc, 0x5279071f, 0x16c3df23,
-       0x436edf4a, 0x27456b7f, 0x15ec7fbf, 0x3cc03f93, 0x19c01733, 0xf01e7af1,
-       0x63fd436a, 0xf21b3667, 0x6e91f8cf, 0x7d9a9fe4, 0xbd7cc302, 0x136d76ea,
-       0xd5aa85c6, 0xe7a458be, 0x6bef6d8d, 0xf06b9e90, 0x8e3c765e, 0xdcbc7267,
-       0x35bf7944, 0xf5efc626, 0x00ffaeda, 0x63ce76e3, 0x553a8b5c, 0x003c51ef,
-       0x57ae36e5, 0xfe42dad5, 0xc97983bf, 0x073477ff, 0x3c60cdd3, 0xf287e78f,
-       0x737ce9c9, 0xdccc7f10, 0x1e63f9ce, 0x681b73e6, 0x675fc538, 0x5d91c7c6,
-       0xf1c71fe2, 0xafce9360, 0x3fa63b43, 0xfc7ca045, 0x5ad730fe, 0xe95c8fb4,
-       0x7fe9aedc, 0xbd2b05ed, 0x5b73a3f7, 0x3cf98c7f, 0x733bddb2, 0x149556c3,
-       0x1d999fb0, 0x1fd8de3c, 0x120fcac6, 0x21d7edde, 0x25b97c3e, 0xbe31f267,
-       0x777819a3, 0x4483c60a, 0x3d0d1f1e, 0x6b8e5d87, 0xfdfc671c, 0xb3df6528,
-       0x3cb91313, 0xa3a26e63, 0x5bbf392e, 0xc651d7c9, 0x504132df, 0x9fb8d1ee,
-       0xfaae5824, 0xd7de1a5e, 0xde2b9e60, 0x3bf960d7, 0xef161f39, 0xa2feb06b,
-       0xf78b0f9c, 0xf78ed835, 0x956f5835, 0xbef161f3, 0x5f78eb06, 0x722be583,
-       0xdc71ec3e, 0x6df1e52a, 0xa2e90a7c, 0x946d790b, 0x1d1bdebf, 0xdc151f52,
-       0x085a37bf, 0xa8128fae, 0xc6c269bf, 0x78ff30a7, 0xc52f9293, 0xc3b446cc,
-       0xfbf9c22a, 0x7b06a91a, 0xf3f404ec, 0x45ed778b, 0x9bf81e7f, 0x882b9fde,
-       0xef4a505e, 0x1968c497, 0x27dba3ca, 0x804f47d8, 0xcd8ec7f1, 0x724adb48,
-       0xecf74f52, 0x31bb3fbd, 0x6f7ae292, 0x25824c49, 0xaee465a7, 0x9a7d42b5,
-       0x85fa2041, 0x512a6ef9, 0x67984cfc, 0xab62c746, 0x1307cb8a, 0x9285cbda,
-       0xb3ae0963, 0x8b9f4122, 0xd588f872, 0x51fb819e, 0x6a345de0, 0x45da1a59,
-       0x07f36a5d, 0xbd759f18, 0x57e866a3, 0xa53c7129, 0x69d693df, 0x99bfb8f9,
-       0x736ba919, 0x36607e70, 0x0d367794, 0xd9fdc66b, 0x9ea170c4, 0x855997e4,
-       0x027f20f2, 0x66e99ba7, 0x357b1f6e, 0xfa345566, 0x62d361f5, 0x4bb75ef0,
-       0x1931f3c6, 0x3c65c7cf, 0x81573de3, 0x6173df8a, 0x585cf789, 0x2da3e686,
-       0x4db12fcf, 0x240f7820, 0xcdb3e605, 0x0097df92, 0xd4f7a10a, 0xf31c729c,
-       0x34ee594b, 0xcadc95e6, 0x9e6879c7, 0x778e392a, 0x6f7c1d5e, 0x8ff38ca8,
-       0xbdce5467, 0x166bcb89, 0xbf79e1a9, 0xe61731d7, 0x397dcf15, 0x7d50e281,
-       0x06a5d16e, 0x5e05cfbc, 0x5ec67947, 0x8b2efee6, 0x77337ce7, 0xabf51c7f,
-       0xcea9e397, 0x7c74eee8, 0xe64fa3af, 0xf07ea52f, 0xe4979e3b, 0x81ba81cc,
-       0xf3a123de, 0xa776e739, 0x4fbd4147, 0x5f488bd0, 0xbcfe26ce, 0x673fe647,
-       0x7c9f3c8a, 0x24f3a61e, 0x3bfa3e21, 0xf7c24e5f, 0xbc193710, 0xf7fcb94b,
-       0x66dc93a6, 0x6fcc74de, 0x4e782f3a, 0xadf1be62, 0x98a5296d, 0xed5e7f6f,
-       0xb3eb0679, 0x5d78d2db, 0x0a693968, 0x93d23e7c, 0xb7c8f984, 0x6296a5b6,
-       0x91f9f23e, 0x5944cf2d, 0x97eaea02, 0xcd73e24e, 0x98a56983, 0xeb5b3c9f,
-       0x7487563e, 0x5f4e7bf3, 0x4e077dfa, 0xdaaa7c23, 0x7d3efdb9, 0x2f0b81df,
-       0x603e7ea1, 0x7582bca4, 0xdf099213, 0x6ecfedf5, 0x6beb7a46, 0x6c3f1351,
-       0x99ff7e6a, 0x2d3f50df, 0x6b665985, 0xc90c563d, 0xba1db494, 0x3b35f71b,
-       0xd625f3dc, 0x89bc4f17, 0x047b31f6, 0x13a5ebe7, 0x4f914a73, 0xfbec0efb,
-       0xd9b3ea05, 0xe2d86091, 0x13d05e7e, 0x8ff72a7e, 0x40b8c02b, 0x0cbbb19f,
-       0x9dfeafe7, 0xec1fe796, 0x718e9b8f, 0xc09cff82, 0x6e2a31f3, 0xfa8492d8,
-       0xf9e57c56, 0xf8c1bfbd, 0x74f4efe6, 0xcd1353df, 0xa94abded, 0xe1397f31,
-       0xcc5ed76f, 0x5e7be95b, 0x15aff74f, 0xe2b39318, 0x2963ac7b, 0x3feaff3e,
-       0x78865eff, 0xee769428, 0x772ff6c5, 0x438445eb, 0x7916c68f, 0x8f61f233,
-       0x0acefc9a, 0x3bd15eb9, 0xdc27ef82, 0x8bf84457, 0xfa8492d9, 0xafc472b6,
-       0xcf7dc0ee, 0x833cb696, 0x567b0f7e, 0x670e774b, 0xc1b8079f, 0xd47bb3b8,
-       0xfb034998, 0x5e90aa30, 0xca5b0bce, 0xf7f9c49e, 0xf5e77ef0, 0xae9e085b,
-       0x5c33d73d, 0xd431fa0f, 0xad85e7c7, 0xf767ed41, 0x7e859b3c, 0xcddfb9e9,
-       0xa154ff26, 0x2a5f8573, 0xf4836b77, 0x58824922, 0x3fca5b8c, 0x02198b93,
-       0x0ee759e2, 0x927be8ee, 0x6b9fc7f9, 0x00357b56, 0x5b2d0aa3, 0x0acdf98b,
-       0xde26543f, 0xabe78c5a, 0xd1d31b14, 0xf5c8a97e, 0x9c5f2195, 0x3c5d33d5,
-       0xd65b7bf4, 0x6bad955b, 0x7c1da0e6, 0x45fcfda5, 0xc95f4796, 0x9b55f87c,
-       0xdf781dde, 0xb5fe5a18, 0xa84f998e, 0xb585f5fc, 0x95e5b25a, 0x78d6def9,
-       0x55afe81c, 0x71f97347, 0x8337fa12, 0xac93fb1c, 0x0aad16ef, 0x04eeffee,
-       0xad594f9e, 0xfea3a5f1, 0x7b7fe653, 0x87db8982, 0xca3a5f2a, 0xb371d0ab,
-       0xbcde5925, 0xa9bc9020, 0xd14e156c, 0xd20824fb, 0x2b3c3f58, 0xe6372e75,
-       0x87870d13, 0x0f197cf8, 0x70f1e612, 0xd66caabe, 0x4f30f4db, 0x022f9855,
-       0xd18725ed, 0x50768117, 0x6b122bdf, 0xa317d192, 0x5fe29fcc, 0x5653894f,
-       0xfd36d478, 0x71c1eb70, 0x865e4fd0, 0x5628037f, 0x537ce44f, 0xeb4e16de,
-       0x1f2f9331, 0x677cb6e9, 0xa73c38f0, 0xfb1f8029, 0x06c576da, 0xf70cebfa,
-       0xa751f74d, 0xfffa6f88, 0x07bd31f9, 0xb5b2295e, 0x4e794f78, 0x4083efe0,
-       0x3907de9d, 0x5677df27, 0x43086d7e, 0x95f739fa, 0x4fb8f883, 0x7b9c91f0,
-       0x7246cdb1, 0x23ed4fac, 0x626bb739, 0xf947af11, 0xbd6e50ca, 0x24a7f138,
-       0x7c12fa3f, 0xd29ef865, 0x2f8ea566, 0xd01d81cc, 0xe490b6d1, 0xe7896cc9,
-       0x6a5db051, 0x71138f13, 0xe1932f78, 0xde86d8c4, 0xd443f23a, 0x3a97b466,
-       0x42f72a27, 0x25f9ff1a, 0x31f53f3f, 0xe456bef3, 0xc50372cf, 0x6abec07d,
-       0xc0ed097e, 0x8c16b105, 0x4dc287a7, 0x898c5fb9, 0xe22966fe, 0x7da31de9,
-       0xbc3cc4ec, 0x9f91f4cf, 0xf64ed401, 0x5a6bf57c, 0xd5fb37f2, 0x7e517b03,
-       0x71f68db9, 0x0e9e0113, 0x547af74d, 0xbed41771, 0x67ed342e, 0x1c91bd21,
-       0x97d6f4e1, 0x07bf8bb9, 0x4e4fdf22, 0xfa00f192, 0x7d22358c, 0x87cf1c08,
-       0x409ff6db, 0x9dd7d379, 0x943a724a, 0x3db6ce9f, 0xe3728116, 0xaeefd043,
-       0x87c07880, 0x7ca59f8b, 0x0798f980, 0x6b3de502, 0xf837cf83, 0x2fc98fed,
-       0xda039b64, 0x821b1e91, 0x4170a1eb, 0xf106f4ba, 0x7df68b81, 0xc01bf23f,
-       0x777a6aa7, 0xa861c235, 0x52ea173e, 0x4850fd40, 0x2b3fa43d, 0xfdc3f6e1,
-       0xebcd1813, 0x25eded18, 0xcf1f7e3f, 0xbd07adef, 0xe103f546, 0xee2d3f74,
-       0xc315bd03, 0x8bea16f5, 0x8a6e88aa, 0xd01df55f, 0x83cabdd2, 0xe1259fed,
-       0x291e81f9, 0xfed5534e, 0xf7fa2c72, 0x699826eb, 0xb18fd07e, 0xa0731794,
-       0x11fd163d, 0x7a21dda5, 0x0cf7e5d2, 0x287e50b2, 0x9bc94eed, 0x42e5794e,
-       0x5f3e1677, 0x8719cb27, 0xeb097508, 0x10e1ce8c, 0x76b3df38, 0x287ce489,
-       0xf4c956de, 0x8b21f20a, 0xe15e39f2, 0x1e4503f1, 0xe572c854, 0x7267b610,
-       0xf72937fe, 0x84cf7852, 0x9c8c3f7c, 0x23815af8, 0xcef8a5ab, 0xbccd13fd,
-       0x79a78f2e, 0xe789fc79, 0x3e7abded, 0xc713252b, 0x45f79599, 0xd528f2fd,
-       0x0e505f2f, 0x781c93c4, 0xe70b1d50, 0xb0467caa, 0x8a90c3d4, 0xd04535d2,
-       0x2d532d9d, 0x1ab8a22f, 0x2e1ae7e6, 0x1d2857df, 0xf8e44e45, 0x1fb914ad,
-       0xa057b95e, 0x6a73a5fb, 0xf2076f7e, 0x580fde86, 0x08a6b056, 0x18beeff9,
-       0x5fd026a7, 0x4bfcd6be, 0xcbeb821b, 0xc514d76a, 0x95e7c30d, 0x8d76b6ab,
-       0x57cf9764, 0x8a2c6f61, 0xaede5f35, 0x5e9cfbec, 0xf574e7d9, 0xcc7840c8,
-       0x1234535f, 0x7fba65ca, 0xdcfc1e17, 0x5eb5dae7, 0x5d2d57ca, 0xb7c4f743,
-       0x8a0daa5c, 0xbe6b5eb3, 0x7ba6e60a, 0x3fed2b90, 0xde0874b4, 0x312b8c5e,
-       0xc43dafe0, 0x0137c067, 0xf4cbc5eb, 0x289f143a, 0xfd063c5f, 0x3c5f6653,
-       0x113e3026, 0x339be25a, 0xb88ae522, 0x2c3e04a8, 0x0f030cb3, 0x89d1ffa5,
-       0x3f1ace3c, 0xa8f1d391, 0x5e3b55d9, 0xe9d71462, 0xa57bf941, 0x22fe4cf7,
-       0xbf07efef, 0x9c233267, 0x9bd4ebf7, 0xdfd3fe30, 0x87c50df9, 0xe619d7fb,
-       0x03077bf3, 0x5de7804b, 0x029be3f1, 0x26abc0e3, 0xdc243b71, 0x9a9dedca,
-       0xe3d5f50c, 0xa1c6994b, 0x1bd912f8, 0xdf74e199, 0x05f6d7d2, 0x8efeb7e9,
-       0x8bde133c, 0x0dbb75f4, 0xff356fc8, 0xa8b17ffc, 0x3e3afb87, 0xbeb4bca5,
-       0x7ca33f6f, 0xde728db5, 0x3936a1e0, 0x6cdbabdf, 0xe2fef6c4, 0xbf6117bf,
-       0x8fe9724d, 0x98f8f02f, 0x83f12a52, 0x3bf9ff00, 0x4c7b53d4, 0x54c51f1b,
-       0x2db0ca99, 0x7fc0bf24, 0xe1bd468e, 0xe3982b8f, 0x04c38b86, 0x54d215c6,
-       0x2580ae3c, 0xd2d215c6, 0xeb015c78, 0x12c05718, 0x8ed80ae3, 0x63ac0571,
-       0x18eb015c, 0xc63ac057, 0xb8c4b015, 0x297fb602, 0x0fd1e7bf, 0x3dc78b82,
-       0x57f7240d, 0xc0337e62, 0xbf27656f, 0x47b95abf, 0x7c617ba2, 0xdff503cf,
-       0xad3b7965, 0x678ede72, 0xd607dd2b, 0x882c901c, 0xc41f7c22, 0x3bf98e95,
-       0x1e314703, 0x5822d354, 0x7db198d6, 0x6363ed3e, 0xa507de47, 0x6d47bed8,
-       0x4f44cd11, 0x828d9f1c, 0xd57c8f5b, 0x57e287b1, 0x949d7105, 0x2cd35fef,
-       0xcebb8c30, 0xd93f72d3, 0x0e6b4129, 0x1d92abdd, 0x9376d4ed, 0x9cf552ff,
-       0xef7c0e60, 0x45e266bb, 0x7dca1392, 0x88fe52f5, 0xf37a3d39, 0x6b3d2092,
-       0xf85779e3, 0x29c7ec27, 0x1d9377e7, 0x2d176012, 0x6c6c7bc5, 0xf7a5be97,
-       0xe0e09c4d, 0x9dae108e, 0xd1d95577, 0xb5f31eb2, 0x55fe687e, 0xdef924e1,
-       0x47bf9b3a, 0x92f8fc52, 0xbd60077d, 0xb25a2dc1, 0x609f6e53, 0x1e526dbf,
-       0x28d819e6, 0x53b472ee, 0x27d67e4f, 0x8a0faf5b, 0xd74a14bb, 0x8563dc51,
-       0x7dfd205a, 0x3b9f6ac4, 0x4672e809, 0x6f14bdf1, 0x246f1199, 0xf0e8563e,
-       0x4fc96b49, 0xe315de70, 0x0a9877f9, 0x34e7ecb5, 0xa5cf9c9f, 0x5eb0a9e0,
-       0x2cf7e370, 0xbd0b3316, 0xc008b03f, 0xe5517187, 0x188b1ffb, 0xe850afcf,
-       0x8156c56a, 0xbcbe8ae8, 0x84bdf010, 0x103df845, 0x6af77fd0, 0x289bfdb9,
-       0xc4f27bf2, 0xe28f3c4d, 0xfca7663e, 0x7d486591, 0xd7d7e912, 0x0f6ed07c,
-       0xdb892ebf, 0x9c38e6f7, 0x3571f17f, 0xc61707e5, 0x276e9edd, 0xf9405f3d,
-       0x6ef78213, 0xaf1bfbe9, 0xf3833f26, 0xb9aa8e27, 0x927801dc, 0xf485d59f,
-       0x3b1ef14a, 0xcaebc795, 0xbf229ca9, 0x5efa161f, 0xcbe77f43, 0xb0be382d,
-       0xf84160c6, 0xc03df15f, 0xffbfabb0, 0xebf394e6, 0x5c9ec512, 0x6be3c233,
-       0x51e10583, 0xef49d718, 0xf3caa589, 0xb25b9c3f, 0x8b69f109, 0x1f5c2e60,
-       0x00b669ef, 0x40f08b7c, 0x3dd1c602, 0x66cf7c36, 0x513053a0, 0x7265f53e,
-       0xcc3aeb74, 0x1349a953, 0x2daf184c, 0x1852db0a, 0xa517f30b, 0x7677d324,
-       0x1c78da6a, 0x4e4a0fb6, 0x92dc5307, 0x62aac7c0, 0xf1cf7e31, 0x3fb5cbe8,
-       0xdfcf293d, 0xb3e65b3e, 0x782f8efe, 0xe3b5f11e, 0xfbe9bbb4, 0xef4f4c1c,
-       0xf60fd3af, 0xd1c6fb35, 0xe855af14, 0xae39b068, 0x45a8e909, 0xa5a513d6,
-       0x8ed1a9ef, 0x37b3cc68, 0x96ca1c23, 0x4b175c5c, 0x4e3e1ce7, 0x87dfe4a6,
-       0xe502c9c6, 0xde46ffed, 0x5aba89fd, 0x5baddf2a, 0x9d776545, 0xe8079e8b,
-       0xbf08238b, 0x7d6f101f, 0xf130d27b, 0x4733a656, 0xbe05be92, 0x90edf1e7,
-       0xbbf02af8, 0x33efc018, 0xd9eea23a, 0x8348f680, 0xcdf782c6, 0xd2bcff98,
-       0xfde1f240, 0x59c6c349, 0x2819f815, 0xf4c83b2e, 0xe9878839, 0x112aa919,
-       0x926dff9e, 0x44e71410, 0x2273c1be, 0x7c8960df, 0xf9f952a3, 0xa30d69e6,
-       0x7da194ef, 0x40fb22e0, 0xbf5df84f, 0xd40ae406, 0x20a665ef, 0x442172b9,
-       0xf32380ae, 0xac5f7a33, 0x0936cb43, 0xe9cffcfe, 0x19ca5c50, 0xb878ce46,
-       0xe61d199c, 0xb3be9e79, 0xf9461d50, 0x44efc0c5, 0xf2374767, 0xac25bdbc,
-       0x461dd684, 0x3e7bd0de, 0x38188ef7, 0xbff414f9, 0xd90361f7, 0x9613eb39,
-       0xe477ffe6, 0x71279fcd, 0xdf813c78, 0xed5d5073, 0x059b0e7b, 0xb15d8fbc,
-       0xbe236590, 0xc439ef95, 0x7bf218c1, 0x39eff5ff, 0x123c988c, 0x0ae0e7bf,
-       0xdc439efa, 0x30e7be15, 0x6171b26a, 0x461cf7e0, 0x30b11e4d, 0xc60e7bf8,
-       0xb29df885, 0x39efc1ff, 0xbbce4fa4, 0x370e7bfc, 0xa0ff364e, 0x3d8039ef,
-       0x4fe3899b, 0x63c6d8e4, 0x3b9f2899, 0xe3e5fdf4, 0x97643df2, 0xb2c52f68,
-       0xa2a5c228, 0xc56dd176, 0x73d16df2, 0x5f03b63f, 0x1578444c, 0x037d963d,
-       0x5125977e, 0xf2bca1eb, 0x49b6ad27, 0xb96bff38, 0x3cf8c9b6, 0x2f5fde34,
-       0x73f60f9f, 0xcd0bf60b, 0xe2e8531f, 0x0e5cc9ae, 0xa9cb93cd, 0xc7bfc3f5,
-       0xbf326f3f, 0xbed6be4f, 0xe077bf61, 0xd9feca7a, 0xdc56c596, 0x4ef7ec0f,
-       0xb7ec27dc, 0x88664b04, 0xf80f7a0e, 0xc9757a72, 0x2e7462fb, 0x3fb38f90,
-       0x9528f6e1, 0x14772ae9, 0x1ea30dda, 0x7ee14770, 0xe80e3547, 0xdf907df1,
-       0x68f406ba, 0xf576fc3f, 0x7fdb1e80, 0xdaf9e36b, 0x9f6ff3a1, 0xf491fdcc,
-       0x7e3403a9, 0x4dddfc0c, 0x1440c1fe, 0xe5e96dda, 0x14ae3447, 0xf66d4f7a,
-       0x93764127, 0x8c7bf899, 0x01e636dc, 0x8c3d2191, 0x1e78c1d9, 0xe90c4163,
-       0xef1d4ab9, 0xfdc0f95a, 0x38d1d222, 0x803bec37, 0xaedfaefe, 0xaf7e0c1a,
-       0xaae34bd7, 0x5ec025e4, 0x64ee7a0b, 0x9474bf3c, 0x5ed08f2c, 0x39d9efc4,
-       0x77d08fcb, 0x0b8ec0a6, 0x79be8f99, 0x594f9430, 0xe6bfb3ad, 0x62be5333,
-       0x77a5bf50, 0xfa3d66ff, 0x5ba5e5b5, 0x2f17e435, 0xa58f5969, 0x269ef1c3,
-       0x197d918e, 0xcbec1fd4, 0xfb65faa0, 0xf547d90c, 0xc7d717fd, 0xd02eb30d,
-       0x13a456c1, 0xaa8e0e85, 0x4fd0e33d, 0xb30cea3d, 0x3c1df7f0, 0x269a5df4,
-       0x5df4bdf9, 0xcadd39ff, 0x5d3965f3, 0x3f1df8c0, 0xa9ea8e8c, 0xaf1df2bf,
-       0x1c8a956b, 0x8dcefa1c, 0x5e28b986, 0x7248cb39, 0xfff646ae, 0xc89897aa,
-       0xbaf8511e, 0xb539e55a, 0x18c5fb1e, 0x8a9bfe79, 0x7aabf7d1, 0xcf9451c4,
-       0xcfac3f4d, 0xacfba54a, 0x178f7ad8, 0x5db81de7, 0x15b9efa0, 0x5ab97384,
-       0x9e389628, 0x4447e785, 0xa7815dfe, 0x98487e51, 0x37bfc147, 0xbf972530,
-       0xf8cf103f, 0xca98db77, 0x369df21c, 0xed7a1e39, 0xeff1b4ef, 0xf7e7cd92,
-       0x25510d72, 0xf9f1cba5, 0xf9e81b82, 0x1f52efc1, 0x2afee2b1, 0x71b4ef94,
-       0x4e61bf7b, 0x557f3d06, 0x3d41af30, 0x5d807ae1, 0x7a6d3be9, 0xef80fbe4,
-       0xf887bdb3, 0xd9f7d6ba, 0x1c0fef94, 0x23c3705d, 0xbd1c397b, 0x3355ef78,
-       0xafe418cb, 0x3c3117ff, 0x56c0d29e, 0x000056c0
-};
-
-static const u32 tsem_int_table_data_e1h[] = {
-       0x00088b1f, 0x00000000, 0x51fbff00, 0x03f0c0cf, 0x3370278a, 0x45e39c30,
-       0x8381e9f0, 0x5fd32918, 0x50c0cec6, 0x4055c401, 0x3f880bbc, 0x7c3032b1,
-       0xff5e2566, 0xdb042935, 0x21818248, 0x88d7881e, 0x49a83031, 0xa41dc422,
-       0x03261819, 0xb150a1f9, 0x5f3a4047, 0x0f77328a, 0x80a69c16, 0x872ae629,
-       0x9163a760, 0x6819c647, 0x50e54bf2, 0xf40499f9, 0xa2be340f, 0xa2ffca8e,
-       0xa013a10a, 0xe4d157e2, 0x3be542bf, 0xa6bafea0, 0x4edcdd8e, 0xc35dfd32,
-       0xfc01a102, 0x9847b099, 0x009847b0
-};
-
-static const u32 tsem_pram_data_e1h[] = {
-       0x00088b1f, 0x00000000, 0x7dedff00, 0xd554780b, 0x733ef0b5, 0x7993331e,
-       0x31e424e4, 0x1e4e1081, 0x03086820, 0xb78a8884, 0xf6301027, 0xd57876d2,
-       0xaf0e2d58, 0x6b86f210, 0x7fb6bd2d, 0x78490806, 0x111fc1a8, 0x29e1d5ad,
-       0x311d82f6, 0x0388b622, 0xbdabd228, 0x557c5837, 0x0bd11feb, 0x2a44908a,
-       0xe5b5ef6a, 0x3ef6b5ee, 0x09939cc9, 0xafdb7b04, 0x7cfdffff, 0xc7ecee9f,
-       0xf5ed7bd9, 0xfdad6bda, 0x8131c918, 0xe4230da4, 0x06fbfc22, 0x109d9221,
-       0x9d37a132, 0xd72120e3, 0x66924218, 0x92ddfd2f, 0xbadc4214, 0xa349bfe2,
-       0xe4febba9, 0x5f5f9a1a, 0xa4aff0ec, 0x4d1f5b4d, 0x2d096a78, 0x2fa1efbf,
-       0x7cd04fc3, 0xad79ecfa, 0xce7eb4c5, 0x5d0fc924, 0x10ab1a1d, 0xd8e7ed02,
-       0x520176c2, 0x9097e581, 0x927fa130, 0x45f8e8af, 0x9fe8b884, 0x37fe9724,
-       0xa5b21c89, 0xd1e43e60, 0x99029ea0, 0x31364846, 0x7e6055fe, 0xf509fc36,
-       0xd0677744, 0x779e75ef, 0x7fec13e5, 0xdb0a5f8e, 0xf27347e9, 0x4dc87203,
-       0x6d08c6d3, 0xfb1dc749, 0xf908395d, 0xe4990cc0, 0xd8b68763, 0x0fca6ffe,
-       0xd214754c, 0x080b67fe, 0x49d9f9ff, 0xcc82da36, 0x3be1eda6, 0x1a1f4e22,
-       0xd99f67cc, 0xe0dfb8e8, 0x40dfdddf, 0x5fc0a7ff, 0xe5a1094b, 0x9e0c1ccb,
-       0xc5d9d9e4, 0x1989ce30, 0xbf4316d7, 0x3213a673, 0x9d4d5688, 0x4490f63d,
-       0x891aebf3, 0xcddb4edf, 0xcf1c0d29, 0xcbf8d981, 0xe80293a7, 0x60ee8e97,
-       0xffc45f7d, 0x64ef38eb, 0xcc3fde3e, 0xfa102b1e, 0x8a97f641, 0xa0725da9,
-       0x4bd153f9, 0x2d056a48, 0xee53191f, 0xd09a769f, 0xe6e9e4f2, 0x721340f6,
-       0xc425211d, 0x1aea7293, 0xc91677fa, 0xad4228ba, 0xee8c0b6a, 0x4a6b0fe5,
-       0x22f9fdff, 0x12fa01d0, 0x6a1fd6fb, 0xa0e9e99c, 0x7b375af8, 0xf4d08796,
-       0x0f2cc0f5, 0xd9f5efe0, 0xd68f10b3, 0x676673f6, 0xfb5e0227, 0x06feef1b,
-       0xfa08d03a, 0xb5b3c73d, 0xea48907e, 0x39fbf423, 0x31c3d13a, 0x9301dffd,
-       0x0964254d, 0xb34d1b30, 0xd2a6d525, 0xe88d6cfa, 0x95e33891, 0x3b69b102,
-       0x28994992, 0x0ff352e3, 0x2637bb61, 0x71c34ad9, 0xef0773e6, 0xb81a55c7,
-       0x6fa50e67, 0x751274d6, 0x2912ba51, 0x75e2c6aa, 0x1a548a5d, 0xddc7038e,
-       0x68425e1c, 0xe1c0cf7b, 0x02d86571, 0x47329fd0, 0xf5c2c40c, 0x42678003,
-       0x4ca24a6f, 0x18f8e6ee, 0xfbbf72fd, 0x338f506c, 0x8e00bb8f, 0xecaa9009,
-       0x0c8f0e3b, 0xb201937c, 0x43fc8296, 0xe02463c2, 0xb91eccfb, 0xe5070124,
-       0x17f0a18f, 0xa42dae15, 0x1412d47b, 0x47ec56b2, 0x0324a4f4, 0xde1157bd,
-       0x4f51290f, 0x42157e51, 0xd78b84ab, 0x129e6a5c, 0x35f06539, 0x193ba9f0,
-       0x5e1cbfc7, 0xe518a048, 0x88d43152, 0xe307c078, 0xed4df92b, 0xbacba502,
-       0x947ee5d1, 0x90218a6f, 0xe17e4333, 0x3bf457df, 0xbdccff37, 0xca91d29c,
-       0xd3396b91, 0x2cdf8a8f, 0x8e92eb67, 0xc82008b5, 0x0f49b964, 0x40241210,
-       0xeb6f0377, 0xbc78a2be, 0xfb5bbf04, 0xe7c86fdd, 0xc9983260, 0x053f9327,
-       0x79bd07fa, 0xf0077ed3, 0x5edf3af5, 0x5d6bcc07, 0x7a825efe, 0xe8c7d38a,
-       0x5daf95d7, 0x81d6ce52, 0xee808d7c, 0x9ea748c3, 0xc6a7d1f2, 0xa6767e02,
-       0x748bf72a, 0x08933b7e, 0x6b75d9ea, 0xd02b7848, 0xb5e594b5, 0xb5e1696f,
-       0x9d3b8e74, 0xd698bebc, 0xed06bcd3, 0x3adbbea9, 0x68870b49, 0x8d8b6b7e,
-       0x85ab1fb5, 0x311f9a45, 0x8a148491, 0xc2c56d4f, 0xbe5a4e95, 0x17eaa375,
-       0x34fd5eb5, 0x2d6725a2, 0xdeb2dfb4, 0xbdf00aa6, 0x3b23ad8f, 0x443849f3,
-       0x39b1dfc7, 0x69239bf9, 0xf9b2143e, 0xf24fd387, 0xd945faf8, 0x022844a5,
-       0x9c3a31b4, 0xae5c7921, 0xa9e50204, 0x7ecb7cbc, 0xa48ebfff, 0x5d363df0,
-       0x45a0aff2, 0x4ccfd63b, 0x769e28d0, 0x3f048168, 0xc0f07f4d, 0xccefcc7c,
-       0xdd00260c, 0x9f9c6e76, 0xc0f14c00, 0x461b99e6, 0xd2617b41, 0x6ce91d61,
-       0x1f47ffd6, 0x00ec3a28, 0x9e994b38, 0x7e0d6a4f, 0xbcf9a253, 0x89b91249,
-       0xadcf214e, 0x1fdbdc21, 0x4f5811b2, 0x8b6de8fb, 0xcdd44ebe, 0xb4eb5779,
-       0x5d7f818f, 0x2009160f, 0x86353bda, 0x923741e7, 0xbeec8af0, 0xc85cefe3,
-       0x5d2913ea, 0xbf2e0e80, 0x96675962, 0x4756f85a, 0x3c717079, 0x1c755ab9,
-       0x897a488f, 0x578bd690, 0x62469ffa, 0xf07ae9f0, 0xe9f58128, 0x8163e78a,
-       0x7ca05d27, 0x9cab830f, 0x1c1eb9ef, 0x6357caf7, 0x21b1f1e3, 0x7fa01eef,
-       0x6177c522, 0x50eb0424, 0x0a24617a, 0x57c9e2fc, 0x9a0bb034, 0xc5c93109,
-       0x7cfbd1a1, 0x1337201d, 0xaf583e22, 0x837e8dd7, 0x81568fc9, 0x6fe630f8,
-       0xb7e4f7b4, 0xc1fb5893, 0xf87287a8, 0x697853ce, 0xcb87bb39, 0x847f4f59,
-       0x732447ad, 0x4f75c21c, 0x5e7561e1, 0xc84c7d1c, 0x97cb940a, 0x817ae049,
-       0xedcddea6, 0x6c06a751, 0x7900dfae, 0x910240b7, 0x134ddf38, 0x42d27ad8,
-       0xe9a05d74, 0x162f44a3, 0x664b9d70, 0x2eb2d7fa, 0xbc9fd1f5, 0x16e9165d,
-       0xd468df40, 0x8734803e, 0x23cd31f8, 0x92474c01, 0x26af4c56, 0x49f34c11,
-       0xa405a63b, 0xaf43531b, 0x422a89f8, 0xfac4c47e, 0xa4e720c9, 0xe58b63da,
-       0x3264d0bb, 0x3cce3eb2, 0x73782d9a, 0xf8ebf890, 0xe75f021d, 0xfc8aa648,
-       0xf17af843, 0xe818b06e, 0xfc2854c5, 0xefccdbbb, 0x0ebe24e2, 0x693dea38,
-       0xdd335780, 0xcd54548d, 0xf06d5a7c, 0x1c2444a9, 0xc41f32c7, 0xd6b8cc63,
-       0xfb7356fe, 0x9c9f98c6, 0x491f23a2, 0x50cf666e, 0x71bdf438, 0x0828d1f0,
-       0xab419e7c, 0x29b23adc, 0xb6494bbf, 0x6b9a5ac8, 0xe8764f74, 0x893f2f38,
-       0x7ceb6747, 0xbe2af0ac, 0xa9b3c181, 0xcb0a9e07, 0xc297fa3a, 0xfea64ff3,
-       0x1db24ca4, 0x86a20bd6, 0xbc56de70, 0x42def9f6, 0xd2e4fe8f, 0x57d66991,
-       0x02d78a4a, 0x069f8587, 0xe37c7f68, 0xe47fea4b, 0x211bfac3, 0xa9ec2a41,
-       0xe60101f9, 0x1a40ad7f, 0xc85e2913, 0xa0eda268, 0x6af5cd70, 0x698b8ecc,
-       0x91f41937, 0x74c90b66, 0xee92cfbe, 0xe43ed023, 0xf41d9127, 0x6df367b3,
-       0x7d695ba5, 0x63b69faa, 0x1e4005fd, 0x0b6d1dae, 0x9fd1b940, 0xf5329e4e,
-       0x112efd47, 0xe836e1f0, 0xe4c3f163, 0x1fb436b1, 0x6fa27c95, 0xc75f2389,
-       0x1d157cb9, 0x9eb0ea71, 0xb094cab8, 0x8ffa1b33, 0xb53e4314, 0x5d61f89a,
-       0xe6cdd49f, 0x30e1c651, 0x59fa9de6, 0x6a7e0040, 0xc03b31f7, 0x3fd04855,
-       0x74da3254, 0xb4dd1ff0, 0x7e42f50e, 0x50531754, 0xd83fa23f, 0x5f3d9e1f,
-       0xd00bed3d, 0xb9d47d7e, 0x92be076a, 0x9fa0e9fc, 0xc8568f57, 0xf8bdfa60,
-       0xfff63b3b, 0x1862a7b9, 0x47cf9989, 0x0bb1d10d, 0xa670c1a9, 0x67a618e1,
-       0xed31da1b, 0xd30b786c, 0x594ae9fe, 0xebceda8e, 0xc0d7e27e, 0x3f0f101e,
-       0xc00f3447, 0x5c75d51d, 0x12a21c17, 0x82802eb3, 0xd36fff06, 0xdaf0bcd8,
-       0x086bc46c, 0x67d54de6, 0xe0367878, 0x9e000a5b, 0xc2223887, 0x77867cd2,
-       0x01d03fc0, 0x3c8e8bca, 0x5cf102b7, 0x9e02c64d, 0x0ca4c937, 0x13e03cf4,
-       0x827d89d6, 0x03800eed, 0xfe69f3f2, 0xc1fa8ffa, 0xf78659fb, 0x9e29978c,
-       0x4b494e00, 0x8eadc664, 0x913b95f2, 0x27d7120b, 0xf9927abd, 0xbdf6bdd9,
-       0xcf00eff6, 0xac894696, 0x68a6bc85, 0xf7b7114a, 0x15824a41, 0xdcdfc1d3,
-       0x28fd3e56, 0xe2b90bd8, 0x5a648757, 0x3a5eb43e, 0x4f2311d9, 0xfd746559,
-       0xb0c276a4, 0xecf2e6e5, 0x074f3990, 0xb7347f40, 0xc43e5cc5, 0x87aef5c6,
-       0xad1e4078, 0xe8b65af3, 0xd3fd7157, 0xea240d55, 0x02f26396, 0x1791a7c3,
-       0x423b13bc, 0x46cb7e74, 0x4c038c11, 0xb3f5b1b7, 0x7ca3be15, 0xd74f2f71,
-       0x5231fa5b, 0x46dba269, 0x193d30c6, 0xddba7d6f, 0x46ce3c56, 0x4db06bfb,
-       0x72a3671e, 0x042292e4, 0x5b9777ec, 0x93f9e3d1, 0x8e126dd3, 0xebb5209f,
-       0xfbab8522, 0x4adfe23a, 0xee4cbef1, 0x2c7c828e, 0x21fcd62b, 0x30fe4750,
-       0xd51263ca, 0x15f66261, 0x700253c1, 0x6c4a7850, 0xfb044e38, 0x0738a6e9,
-       0xcc997dfb, 0x4a365dfa, 0xf6376823, 0x3655e703, 0xd80ce119, 0x34fd0904,
-       0x1555974e, 0xa34df739, 0x9f554ed9, 0x2667fd05, 0x78c16705, 0x7e6fb946,
-       0x1963fa29, 0x2bf4ccc3, 0x0167d477, 0x2206547f, 0x4e7f80d3, 0x926c5f7b,
-       0x36b7bce9, 0xf144bf10, 0x702b9eff, 0x7357f41b, 0xb008fd7b, 0x5e06df7f,
-       0x3b2a0098, 0xa5ac7a80, 0xa25fa564, 0x148972e5, 0xca3f2995, 0x25bf0f13,
-       0x2a1a4017, 0x938b3886, 0x477d33d4, 0x35224bf5, 0xf5231cbd, 0xa27e218f,
-       0x72d03c80, 0x60256f55, 0xdba8380f, 0xef863270, 0x1e734c94, 0x7cd8fa6c,
-       0x72e37a7f, 0x27e79829, 0x09fe0387, 0x49dde9da, 0x26927fcc, 0xde000bfa,
-       0xa6ffaf7b, 0xc4fcf006, 0x67f93366, 0x5a4d7f56, 0x79696ffe, 0xfee26810,
-       0xd5fcb4b6, 0x80f1bcb4, 0x979c5697, 0x9432ca63, 0x24f0050b, 0xbf07f932,
-       0xe41d67be, 0xcf5bf878, 0x572f58db, 0xf835bc37, 0xa720e1c3, 0xa43f831d,
-       0x052d59c4, 0x3e42ff91, 0x1c28b5f0, 0x098f9992, 0x62134f78, 0x18176e52,
-       0x5a9c9bf6, 0xdc947488, 0x988ea9d2, 0x8fc0ddf5, 0xc1ddfcb2, 0xf4878e1f,
-       0x78ad4c6d, 0x0120a455, 0xd768d03f, 0xe018b713, 0xe234effa, 0x1fc479a9,
-       0xa47338a5, 0x7a6a78b0, 0xf30a285e, 0x09fd5272, 0x233dd3eb, 0xf0c56b5f,
-       0x3b0fc581, 0x3f20ad94, 0x61b68cb4, 0x7865b35c, 0xf90290e4, 0xd1406a0c,
-       0x5dca677a, 0x4c6d8821, 0xe37c63cd, 0xd4f5b3f4, 0x7e8c3c35, 0xbdbfa198,
-       0xad5e1f1c, 0x67b3f51c, 0x31ded9a2, 0x2b2701d6, 0xdb36f4a2, 0xa694ce51,
-       0xbe82c54f, 0x9b539a7e, 0x69e51a76, 0x233fb9a4, 0xe36ed1de, 0xc96b8bf1,
-       0x593768b5, 0xe1fd12e2, 0x71f86bcd, 0xdcbcd913, 0xfc1849d3, 0x5189f4e6,
-       0xcfd79bc4, 0x9bd866f0, 0x9bbf3e1e, 0xfc04234a, 0xf3f89ebe, 0xeb6f0ccd,
-       0x7fa28baf, 0x29ec7eb7, 0x85bd67b4, 0xce3f261d, 0xa1ca1ef8, 0x76c4fcfe,
-       0x18f6a1a8, 0x23711bcb, 0x19e9a78a, 0x61ebbd69, 0xaddbb72b, 0x92275374,
-       0x4763d062, 0x8315a747, 0x84b7bede, 0x3cab4ec2, 0x6297587a, 0x7ef2adf0,
-       0xdf867cd4, 0x7cd8cb7b, 0xd3f47b69, 0x93989def, 0xf266e304, 0x7f11b0f8,
-       0xebcbf1ee, 0x284f78cd, 0x2d85c4b4, 0x67eab77e, 0xcc4b52f4, 0x5f39abe5,
-       0x57a7222b, 0xe8ce192a, 0x4f3e3035, 0x84bcf832, 0xdf3279f1, 0xd12f4837,
-       0x921d010e, 0x4dff994a, 0x4df37e2c, 0x5e8c1d29, 0x00c88f37, 0xa9fefc3f,
-       0x97663edd, 0x7126ba30, 0xc6efbc7e, 0x71c80211, 0x40268972, 0xc33e727d,
-       0x13c53253, 0xa5c977ac, 0x4ef6efcc, 0x525db0d4, 0x0b5ba309, 0x5fe14c7c,
-       0x898a7403, 0x5b4b3b1f, 0x6b7fa075, 0x741d4ef1, 0xe1c53259, 0xd4cf0a20,
-       0xd81b0a52, 0x805fb49d, 0xc51853d7, 0x49525ab8, 0xfca5d870, 0x82a2427a,
-       0x10f887cd, 0xe94b686c, 0x7e58253c, 0x20b26268, 0xa7ef7ed0, 0x80f1c07c,
-       0x8f173c71, 0x785fdfa3, 0xfddcf512, 0xc8364df0, 0x1cebf6a9, 0x36a5279a,
-       0xf707f83f, 0xf108e697, 0xbcc6e7e2, 0x2acb83fb, 0x35f812c7, 0x9572fc31,
-       0x16dee3c8, 0x22475dfe, 0x57c82e6a, 0xa5f76f48, 0x830feaf5, 0x65e47aff,
-       0xfecbe312, 0x87a189f4, 0xb21824dd, 0x1fd5f765, 0xdef8ce92, 0x7940179e,
-       0x24ef03eb, 0x8a52afc6, 0x9136fcb9, 0x5e867fdb, 0x140792d1, 0x00a12727,
-       0xd72277ae, 0x02da4f4f, 0xf054c50b, 0x4eb8c3bb, 0xae74c8b8, 0xca9f1937,
-       0xe6a6ff9c, 0x4ae2bd33, 0x9776b089, 0x903aa78d, 0xa834d6df, 0xc65a1fa8,
-       0x439ed5de, 0x7866b0f1, 0x73be1f93, 0xb9196b8c, 0x3cdbf68d, 0x2b70797c,
-       0x30fdc00c, 0xac22bfd4, 0x8d5f8c83, 0x0e03307d, 0x61d21992, 0x7e09cc9f,
-       0x2467e011, 0x24905fdb, 0xeb8fb512, 0x4795df1d, 0x6967cde1, 0x0dc19f28,
-       0xb6ebc9fe, 0x6f9c2ae0, 0xa2946b7e, 0xc99bce9b, 0x42216acb, 0xebcc225c,
-       0xb21e7c72, 0x9f8ebe31, 0x025df7f6, 0xe1c4d3ec, 0xdb22dddf, 0x472d59a7,
-       0x7e085088, 0xf289ed1b, 0x6a6ceac9, 0xa381c797, 0xd56bf391, 0xc3f8672e,
-       0x89ab7e18, 0x75f29924, 0x1fc233fb, 0x7711fac6, 0x514fb80a, 0x4358d1cd,
-       0xcf00b23a, 0xf61a29ef, 0x48eb6b57, 0xe9177c83, 0x78025b4e, 0x8b8f0310,
-       0x5277fd74, 0x90b8c4be, 0xd6eb607b, 0x81a7f0e5, 0x4085d10c, 0x0fa9e4cb,
-       0x178e9879, 0x69e307dc, 0xd2bf2b2a, 0xf5f0e371, 0x4d7cb10b, 0x6a5957c4,
-       0x147f6be5, 0x129ddaf9, 0x9fb77ac5, 0x8fc1b5f1, 0xad1f9c89, 0xbf8c687c,
-       0xd6afc79e, 0x335f3e72, 0x708549a1, 0x9b51dadf, 0x2ce69e30, 0x7c015cda,
-       0x25aa32de, 0x64de7c0c, 0x17df35f0, 0xdb2efea1, 0xa35ad31f, 0x72264eb0,
-       0xeed456be, 0xeb7b9006, 0x38935d7c, 0xbe0534bc, 0x5f39b806, 0x93f807bf,
-       0xae08ddfd, 0x076bd7c1, 0x45bad7cc, 0xfed39b6f, 0xc2d927fc, 0xf1891ed7,
-       0xd7c067e7, 0xb30a4f00, 0x963edc63, 0xdfea7eca, 0x06e7e9c7, 0x6b99f989,
-       0xe5ac1cb9, 0x1fb6b072, 0x223ff839, 0x9afe03f3, 0xc98b3072, 0xe5a24381,
-       0x8cae9389, 0xd3b0251f, 0x9e7bc8e3, 0xe1b5fc24, 0xbc4334de, 0x27fe3c72,
-       0xbe84cd30, 0xcfd234f4, 0xe4c0e744, 0x73c98f3b, 0x76be727f, 0xfe387c68,
-       0xa7f46453, 0x26922ef8, 0xffbe395c, 0x7215705a, 0x43f0367e, 0xb728c582,
-       0x3a667a31, 0x86a92bc0, 0xd304799e, 0x28ad79a9, 0x81be86a7, 0x2bfa0a58,
-       0x3bc62b6a, 0x68ad999c, 0x98f3399f, 0x24fc31be, 0xb88d7ceb, 0x33d71378,
-       0x02217949, 0x853d9feb, 0x9eaa3f70, 0xcc9951f9, 0xd5e2301f, 0x18a8fd86,
-       0xbbd0d47e, 0x79a79f70, 0x97da3d78, 0x3bd637cd, 0x36c3ede2, 0xf077eefb,
-       0x3ed35f4d, 0x0e5a1aeb, 0xbbc9aefd, 0xc3b3c49f, 0xfb18798c, 0x6e3e4e46,
-       0xa8b51e73, 0x32df5c60, 0xc76adefc, 0xfeb26734, 0x7ae7be7a, 0xbbd1ee57,
-       0x54768f2c, 0x6f9f8c6e, 0x03e0c7e9, 0xa343e885, 0xe4183710, 0x4ce7091e,
-       0x3f04849a, 0x924dc7d8, 0x90729d20, 0x5aa97b1e, 0xff401689, 0x9cbc6627,
-       0x3db2f685, 0xbce406b8, 0x0380abe9, 0x53aba9e2, 0x96c6f35e, 0xe6f19d9f,
-       0xa56cc1b7, 0x7ee2d5df, 0xb148838e, 0xdc2763fb, 0x4b7ed1db, 0xe9c737c8,
-       0x09ae149c, 0xcc13c402, 0xbf8f0ae5, 0x72e69928, 0xa45fc799, 0xe7394b14,
-       0xbe34b90f, 0xeb93795e, 0x7602df15, 0x1cc4e74e, 0x713bd716, 0x30674f2b,
-       0xdbc73efe, 0xc234f375, 0x535feef5, 0xf6e5251f, 0xe29befc2, 0x9922f8c7,
-       0x3ebb4765, 0x2b9d852b, 0x26e7b120, 0xa26b5fe0, 0xccfc6244, 0xff9781a1,
-       0x61d4f108, 0x06cabe0b, 0xea156b3c, 0xdb465861, 0xc79c6ca5, 0x28f74263,
-       0x3ae6cf18, 0x02f5fb8b, 0x6a72e345, 0xdbf40b12, 0xef8521db, 0x3a52c0bd,
-       0x91057b8f, 0x37c0ecbf, 0x8c29d022, 0xb1448ba9, 0x303a43de, 0xe61b089f,
-       0x5187e0b9, 0x33c44bbf, 0xc61b614c, 0xf6cc7e8d, 0x7888d643, 0x03a8836e,
-       0xedc9bfb4, 0x4297f82a, 0x1ae77e88, 0x40be77f8, 0xc4c8316b, 0xc608b2e0,
-       0x7cedad93, 0xa039d853, 0xaffb7a3e, 0x5237df4f, 0x548f8173, 0x1ce8372c,
-       0x694ef514, 0x5ff2df42, 0x12f38189, 0xdc58abc6, 0x2a5f5acd, 0xde4017e9,
-       0x0bc2e5ac, 0x7e053a7f, 0x6467aaf4, 0x3ca7a3f4, 0x41bf4723, 0x045b35f3,
-       0x076d53f4, 0x770fe89d, 0x51f2c23e, 0xfb43a28f, 0x8c05db73, 0xdbd9d507,
-       0xe201bdef, 0x0488cf8a, 0x19708dfd, 0xe29d8bee, 0x59fb2673, 0x80079cbe,
-       0x9a1cb66a, 0xec57df0b, 0x77d813b7, 0xf16e79a8, 0xf9a06fb7, 0xf464c7c5,
-       0xac766a51, 0x657f6050, 0x40885849, 0xc1326bbe, 0xc4fb43f1, 0xbeda0ef0,
-       0x369edbcb, 0x2bfb0dc7, 0x455da20e, 0xa7b4f6e1, 0xa9f4a6cd, 0x0d353f0c,
-       0x2ddcabbe, 0x98ffc1f8, 0xa38eccf2, 0x9abbf419, 0xa73c0427, 0x45cbb550,
-       0x9cba18b4, 0xdfa3136a, 0x9d33f880, 0x8bc5f827, 0xc034eb49, 0x0d8ecd7b,
-       0xb713168a, 0x9230d33c, 0x7cdef668, 0x1c7413cd, 0x93ed5dfa, 0x58a61f82,
-       0xe041236b, 0x9ce7ce8f, 0x30dcdb65, 0x08ca15bf, 0x59abcc0f, 0xc38b7681,
-       0x7ec1f6f3, 0x8b78657a, 0x57d68d32, 0x2945b23e, 0xaaa7e18f, 0x2d10d75d,
-       0x6d4e3f86, 0xd4bf4dce, 0xae867b7a, 0x54f0b15b, 0x88b7a612, 0xc4665614,
-       0xc8767bec, 0x453f9c49, 0xdf06ff53, 0x18275e87, 0xef3d0ac7, 0x741abc41,
-       0xbd32a65b, 0xbcedd060, 0x7528e9ca, 0xb388cd17, 0xd02f7aaf, 0x2af10ec1,
-       0x1bfbd315, 0x6c6e987c, 0x9b3e90d0, 0xe1577f00, 0x7b9606be, 0x88629127,
-       0xa275788b, 0x3c9f52c2, 0x21962f5d, 0xf960124e, 0x8283dbb4, 0x1bf98976,
-       0x383926e9, 0xb75c820f, 0x964c4fc9, 0x49bebae8, 0x7e252e09, 0x77b4be3a,
-       0x6075c972, 0xc8e705a7, 0x1d9fb0a9, 0xe8f160ac, 0xa2e40f88, 0x7ccbef89,
-       0xd6f2664b, 0x7c60a194, 0x8bf7d364, 0x41eda1b6, 0x7d365e18, 0xec277cbf,
-       0xe67ed1ab, 0x1aae54ca, 0xee4fda65, 0x9b49fbe5, 0x4fd4d13b, 0xa30adcda,
-       0x8fd8c59f, 0x6cfd6073, 0x19bd7b9a, 0x4695b99e, 0x8fd8f53f, 0x4af36067,
-       0x199263bb, 0xb1aa3b9e, 0xfddbf49f, 0x06881f68, 0xdc7690ff, 0x4eef7517,
-       0xc496b71a, 0x1fe4d1f2, 0x2a1e78c3, 0x947cb155, 0x24c13138, 0xb27a494f,
-       0x74a83f29, 0x6a7da9b0, 0x9f54c720, 0x85b5765e, 0xbfa8dd2f, 0x8a814f31,
-       0xab38b126, 0xbd415832, 0x81d83c53, 0xbb06bbf9, 0x75dcef51, 0xb02af07d,
-       0xd05600f7, 0xc12977f3, 0xbe1c6a31, 0x0812f3a1, 0x1b34cfc6, 0x32ec7da4,
-       0x7939efbe, 0xde2357c8, 0xd9d7dfa7, 0xd12447ba, 0xf14a43fc, 0xadef3023,
-       0x8de3b332, 0x9d824338, 0xce6bfea0, 0x8a16da2e, 0x50cb6bc1, 0x6f422fca,
-       0xd0722dbf, 0x73b8fc07, 0x4a576ff5, 0xa1a6be14, 0x7a6e1e0a, 0xe1edfe5c,
-       0x9b99b510, 0x00fb9687, 0xea8576ff, 0x15f1d88f, 0x8e3e7e3a, 0xdfc61bbf,
-       0xd93b332b, 0x673dbe3a, 0x477c69a2, 0x7c698556, 0xa7c74287, 0xf56fb1f2,
-       0x8a7c7c3b, 0x7909ebbf, 0xc7077e56, 0xe05567b7, 0xa90acdf8, 0xd09f8d30,
-       0x9001fe33, 0xcdfdc39f, 0xf37ae73f, 0xcd2ab3fc, 0xfcd857f3, 0x80feae8f,
-       0xf3809f8f, 0x80fe597f, 0x92ab3fcd, 0xfacedfcd, 0xdbdf19ed, 0x6157ff83,
-       0x37f5affe, 0xe649dcff, 0x36ab0ff9, 0xc6cedfcf, 0x27f5637f, 0x8e377c7c,
-       0x09fca6ff, 0x6ab0ff9b, 0x07b15f1c, 0xca47c0fd, 0xf07a8490, 0xa461a99f,
-       0xa35d4061, 0x923a40e3, 0xc837a9c5, 0x5dc70839, 0x3eef8c09, 0xe6fca04f,
-       0x24a7d5ee, 0xea90254c, 0xd3ce5acb, 0x158bbb55, 0xd0842fe6, 0x41c4585f,
-       0xc45fb85d, 0xb46c8cf5, 0x78538787, 0x218bf73b, 0x78dc2fc8, 0xac5b9e23,
-       0x77dc13b3, 0xfa3056a7, 0xc0f1ff1f, 0xf3b1ade8, 0x5a8ba6b2, 0x13fecb65,
-       0xef38c783, 0xa6ab2454, 0xa78829fc, 0x127c3d50, 0x9e9a1ffc, 0xb478e996,
-       0x83f043fc, 0x1b958aae, 0x768c2e76, 0xce9f2277, 0xfe1cbbeb, 0xf7c31253,
-       0xdc053ba9, 0xc37cf847, 0xd9f40552, 0xc99756a2, 0x74e3a86f, 0x8ece7eea,
-       0x79c68dfb, 0x14505bbe, 0xc1fdf909, 0xbb051d6f, 0x41e6f171, 0x276eefa6,
-       0x1470d5e1, 0x79fac173, 0xff3a5543, 0xe3eccadb, 0xeb6b8c44, 0x9c1c5843,
-       0x49b8810c, 0x7906db59, 0x52dccd08, 0xf9ec9b26, 0xfce6835b, 0x7ce6156d,
-       0x6d961ca7, 0x112ccf60, 0xefda16c8, 0xcb65ebf7, 0x8e3600b9, 0x76e64957,
-       0xbbef1b25, 0xb4198694, 0x8e90fbe8, 0xe9156283, 0xdf65573a, 0xddd4f01a,
-       0xae28932d, 0xb8a91dc7, 0x454a140f, 0xb2a82dbf, 0x9de15b79, 0x00f43b2b,
-       0x8fee6785, 0x15a7c444, 0x2e838efe, 0xf3ed46dd, 0x907fcd8e, 0x9d6c7e21,
-       0x3bfe158f, 0xa3e75b96, 0xcc3eb02a, 0x19cb590b, 0xa9f9589f, 0x36f17f6e,
-       0xf37b3db3, 0xb5fb58b6, 0x530cd76a, 0x56f8497e, 0x9bc5fb53, 0x17ea99e7,
-       0xd5312eb5, 0x6a59682f, 0xfd0bcfca, 0x8efed4c8, 0xf54c2be5, 0x635fafdf,
-       0x62adbfaa, 0x6b7f2983, 0xfb5321f0, 0x98b6ca5b, 0x47076dea, 0x68e4077d,
-       0x9e22ebd5, 0x3ee0bdfd, 0x9bd82f75, 0xee12dc17, 0xed447e73, 0x33839015,
-       0xb4815ed4, 0xf478ff73, 0x2c1ea9a7, 0xf9a24d87, 0x2d5598ca, 0x0997a099,
-       0x6572cfea, 0x24d0aac2, 0xd7b0178a, 0x9b887ca9, 0x041d1215, 0x0f724cce,
-       0x318b771f, 0xa9971df5, 0x7d054cdf, 0xb17adf7c, 0xdd797e23, 0xd4c379d6,
-       0xaf6a7e38, 0xb02192dc, 0xce5975ce, 0xb569189f, 0xb1a73ce5, 0xeb817dbf,
-       0xe9856ad9, 0x19bdea83, 0x86736193, 0xe223e5fa, 0xf9ec9b9d, 0x0db0223e,
-       0x53feb048, 0x98861f81, 0x76aa6bf6, 0xfbe49ae5, 0xe11121ec, 0x409d05aa,
-       0x5217eaf5, 0x72028d60, 0x35923d16, 0xa1c0346b, 0xef4055af, 0x75c54fec,
-       0xe9436cfd, 0x3fafd836, 0xf4c010d3, 0x4c3286a3, 0x3104354f, 0x02a1b0fd,
-       0xf50d93d3, 0x2c347698, 0x86bdf4c7, 0x36efa610, 0xbbfa60b4, 0xdf4c5686,
-       0xe98cd86a, 0x4c610d1b, 0x4c741b3b, 0xd1e8790d, 0x0f6e01bf, 0x84d71b1b,
-       0x2e7cc3db, 0xe73da98d, 0xf7ff70c2, 0x11f3fbbc, 0x7f9fef60, 0x6cfb8ecb,
-       0xcacbe1fd, 0x51d3fd6f, 0x3ca57b47, 0x639d083c, 0x8133bd6b, 0x2369c9d1,
-       0xec1c64a5, 0xcff4ecff, 0xc4bcc7cf, 0xfd84f52e, 0xfa713c33, 0xfa5d7885,
-       0xf444e9e5, 0x949982ee, 0xfe1ea71e, 0xf7e822af, 0x607fac02, 0x71111c07,
-       0x6dd1261d, 0x95d7a07e, 0xe1784de2, 0x2f1059f7, 0xbf83d73b, 0x8b882cf6,
-       0xd8a8ab5d, 0x3b36f9ff, 0xf9d2f881, 0xcfbc2e03, 0x36d8fe75, 0x32e3c82f,
-       0x3d8e189f, 0x6b4d6147, 0xb761d922, 0xe736efc9, 0xa50ab7cf, 0x689a1e78,
-       0x0347b389, 0x3861a95f, 0xe0d9d20f, 0x67e8d4c3, 0x71c14f99, 0x65caecce,
-       0x5e7e3371, 0x424eec83, 0x277ea57e, 0x869fffb6, 0x0c7ebfa7, 0x23690878,
-       0x5e08381f, 0xdb98bb71, 0xf97efb7f, 0x814cfa49, 0x20392af8, 0x82f60e7f,
-       0x1177fe9d, 0x6122651c, 0x2eb7e8de, 0x63ec8622, 0x69b77ca0, 0x669dfa3c,
-       0x7317f4f8, 0xe6b7c52e, 0x042234fb, 0x9c46bf68, 0x80fe0aa4, 0x02f530f3,
-       0x788cabc6, 0x6ee49749, 0xc6f4c611, 0xbc78ea4b, 0xa1d1c6b8, 0xb9d16904,
-       0xee4bdcb6, 0x38699e9f, 0xaf39c2a6, 0x02ab470a, 0x64454fce, 0xb9e80954,
-       0xd2ab6d73, 0x12ac1ec0, 0x2f15dfcf, 0x67679b7e, 0x6125bd71, 0x8ebcdbb9,
-       0xb420fe72, 0x1d9ca35f, 0x8a9f7472, 0x31b59fc9, 0xefdadb3b, 0xf6c0fb04,
-       0x1f776a2d, 0xd683769f, 0xfbb54f17, 0x3e30553f, 0x5c53112e, 0x7bdfc0c9,
-       0x9d82604a, 0xd772a9e2, 0x7e8f68fb, 0xdc468724, 0xd4fd097d, 0x9f6e7e77,
-       0x88727ce9, 0xf338c3b4, 0x8881f227, 0x743bcb76, 0x15f8fd3d, 0xe4db9d99,
-       0xf67b80e7, 0xfebef995, 0xdf9b9e02, 0x84e78556, 0x8ff7de3e, 0x242dff68,
-       0x81d22f01, 0x1d8116b4, 0x4ad88e79, 0xc8e74f01, 0x31f1de6b, 0x3a95b874,
-       0x05ef404a, 0x863b662d, 0xfca6bfda, 0x7ce6cde2, 0x06999939, 0xa37ca4fa,
-       0xce02c24c, 0xb37f54cf, 0x177ec55d, 0x5826fa93, 0x8fee2557, 0x348957cc,
-       0x9ad5ea84, 0x34567f67, 0xb411c28f, 0x88c83f33, 0x66492cbf, 0x4a656076,
-       0xc27d8158, 0x7fc6da0f, 0x832006f7, 0x7104dc3d, 0xfc489228, 0xfc5f483b,
-       0x56fc295e, 0xbaf58d78, 0xc3881c4f, 0xe212ee21, 0xdad603ee, 0x86cf6e05,
-       0xe7c03d30, 0xc705f86d, 0x7615f92c, 0x2452de7e, 0x9cfdd022, 0x12d908ea,
-       0x851fdeb1, 0xbb5edc78, 0x7106957f, 0x7b6ac0fc, 0xdfdc6f6a, 0x0f649768,
-       0xe159f962, 0xf73c72d5, 0xf00b4520, 0xef8f21de, 0xc41f9c2b, 0x9c016f04,
-       0xdc40f523, 0x3a75ce1e, 0xdf215bbd, 0xf3c0a9e4, 0xef20751f, 0xbc7bbfb4,
-       0x9c418ed3, 0xa35a41da, 0xbb5fe53a, 0xa01fb2cf, 0x902ef399, 0x5067d04b,
-       0x09a2e780, 0x235cb9c6, 0x7e3cedcd, 0x2e31fe73, 0x4381748f, 0xdf39ee3e,
-       0xe14770e6, 0x2899093c, 0xb7f1ed9d, 0x63dfc072, 0x56fdc3f0, 0xcaa77f68,
-       0x7df2d7da, 0x9edf3bdd, 0x097c9e9c, 0xa5f7547d, 0xeb31c240, 0xadd49d48,
-       0x7dd61f00, 0xd7f96129, 0x5d1a9bd6, 0xe6f46355, 0x59f04a2b, 0x27a604fb,
-       0x8e813e01, 0x64dfbb13, 0x027087bd, 0x2f4261f8, 0x386d7c3f, 0x7f498852,
-       0x8f04a7bf, 0x6be383c5, 0xd3ebeff7, 0xbbe009ff, 0xf3feb1ff, 0x11dff4fa,
-       0x679afe0f, 0xd10becf7, 0x17f2b5f5, 0x10e1780f, 0x6b52c7d3, 0xacef9c1a,
-       0x0bdab1de, 0x1491f972, 0x3f5d02f2, 0xef718b0e, 0x0c3ba6e7, 0x70ddd3be,
-       0xf396b08f, 0xaf9f99dd, 0x2ff836fb, 0x5590ef9f, 0xb2ec0f8c, 0x2994ed47,
-       0x3096db6b, 0x7f65d8f9, 0xf19be59f, 0x7edd53bc, 0x7ca8beb3, 0x0d3481fc,
-       0xb885550f, 0xff451cff, 0x7ffb76a0, 0xabbb034c, 0xdea3748e, 0xe3077eb3,
-       0xf68c997f, 0xb1253cc0, 0x0e71bd6f, 0xa5e38eab, 0xde1d6dae, 0xbb6baf13,
-       0x9a1334f9, 0xad3bf40e, 0xbb7055df, 0x9f30e1df, 0x42f034df, 0x5feeccc2,
-       0x0583c4f5, 0xceb853ef, 0x2bc57f6e, 0x29f2c7e4, 0x23e77fd3, 0xa5fb1e0b,
-       0x755cbfd6, 0x6b18fd52, 0xb4eb1b5f, 0x2bfb9fb6, 0x2d5a5807, 0x0fe0bd47,
-       0xf1916f56, 0x9ef57bbc, 0x861f3b6d, 0x76dbccf8, 0x7fda70ff, 0xde979ed5,
-       0xabe69eb8, 0xa653929e, 0xe1b869b3, 0x9f41a29e, 0xf2dffa3a, 0xa8f4bd71,
-       0x4525fa7c, 0x7fcacd1b, 0x974bdc9c, 0x290ea7aa, 0x7c5f7464, 0x521c894c,
-       0x85b67ed8, 0xa7f7913e, 0xeab15f81, 0xd0142f89, 0x141f1f5f, 0x1c767a48,
-       0x09796e7c, 0x13c063ed, 0xabd393d2, 0xf6967e87, 0xa82e9475, 0xb2f42d17,
-       0xaf98fbb6, 0xc42fd007, 0x3f7f29e3, 0xb7d84bf9, 0x0fdd9df9, 0xf278a878,
-       0x9f30bc9f, 0xe33d52d3, 0x4ead9ff3, 0x1520fb83, 0xc54d2872, 0x3c579594,
-       0xbfe403fa, 0x907fc7c5, 0xeac5cec6, 0x575cfc19, 0xd173cc06, 0x9e707323,
-       0x7c8824e5, 0x7633f158, 0x4482fccf, 0x238a9f4a, 0xd839f727, 0xab7a763a,
-       0x4f11371d, 0xfb0242c3, 0xe189af18, 0x640f181d, 0x607f0de7, 0x65913fec,
-       0x60e0bf98, 0x30e45af4, 0xa5d1f1ee, 0xb77f9624, 0x9d03b737, 0xd3d50cce,
-       0x475c8e21, 0x87c710a4, 0x2bf69170, 0xce9a9f1e, 0x52681dcf, 0xea8eff11,
-       0x0e5029ff, 0xdd65dbed, 0x8efa6059, 0x1deecc5c, 0x3e3e4eff, 0xec013b85,
-       0xd469d3d7, 0xbf338c1e, 0x9d630e03, 0x0c5676a6, 0x3bc8c59f, 0x6bedff93,
-       0xf21bbc98, 0x0a519e1f, 0x609d9ff5, 0x81df0472, 0x8ae142fd, 0xa1fd63a6,
-       0x07ea02d9, 0x93c6893b, 0x9732edf3, 0x95bd7373, 0x12fc285f, 0x7c3dc7ac,
-       0x2324e303, 0x2dbed01d, 0x8fbf48df, 0xae30abd5, 0x86bf6fb7, 0xfae62f1c,
-       0x1f45ad60, 0x07524790, 0x2d5b7fb4, 0x0c3e7787, 0x35e54bf2, 0xcafc81a4,
-       0x27c15ef8, 0xf1bc8fbb, 0x9fb72a3d, 0x35b90c44, 0xdcab55eb, 0x409dec56,
-       0x27edc9e2, 0x2b893f6e, 0xae3cb4b7, 0x903bbadc, 0x7ad6ff9f, 0xd3e3c0d5,
-       0x7a1a3c16, 0x5a7c3fb2, 0x1db7e4f5, 0x493d5c5a, 0x45209dff, 0xe0d1f97d,
-       0x2aff8343, 0xcf06a5ff, 0xa9f0f50b, 0x7c3d87c1, 0x9f61f06a, 0x8f09a478,
-       0xe1bbfad6, 0xc0853a6f, 0xcfc63273, 0xfdb00fab, 0xd1ddfa67, 0x2f888521,
-       0xd239971d, 0x4a48747a, 0xc96c3e6c, 0x75ed2c47, 0x69603e4b, 0xebe4b41f,
-       0xf7abed4d, 0xb9d8511f, 0x9da9a89e, 0xe4a7fcb8, 0x01f13883, 0x6baa1d63,
-       0x010954fb, 0xf1bbb87f, 0x0925797b, 0xfe5e2079, 0xf2f188bc, 0x26e38a2e,
-       0xeed74e3a, 0x608f7c6c, 0x57c593b5, 0x2f6ed4ba, 0x93ab93d8, 0x553bbe58,
-       0x683d0269, 0x593b7794, 0xd02bafdc, 0xb18a4ded, 0x203fdeef, 0x08ef1ea2,
-       0x7e78d293, 0xa140de28, 0xfd20edf8, 0x80fdb3d5, 0x61d7b02e, 0x30ac84bc,
-       0xd154e3f0, 0xe21cb59d, 0xde22ad35, 0xe2b85b6b, 0x239c2f16, 0xfb903ae9,
-       0xbe5a329d, 0xdb22d7e8, 0x52e90ca6, 0xf81f8c46, 0x9a6d0911, 0xf5fec024,
-       0x059fe47a, 0xb85f9807, 0x797c7d70, 0x95dfe4a8, 0x4054efbb, 0xee7f52ef,
-       0x87beec64, 0x23c54fd1, 0xff03f296, 0x15a6e5c8, 0xdb951fe3, 0x1e41f5cd,
-       0xe4ec183f, 0x92c7bee7, 0xb77fdcb1, 0x9e0fdec5, 0xa77fe62a, 0xeba7d28c,
-       0x3ce04898, 0x2203f9c1, 0x6efce7d2, 0xe3007e76, 0xbf01d7fc, 0xe7b12b77,
-       0x7c82cea9, 0x1ebfd55d, 0xefccfb3b, 0x3e06ee8b, 0xc14ef7da, 0x767a694f,
-       0x7e23dbdf, 0xdf67f905, 0xf4877acc, 0xa0e53f6d, 0xba55f713, 0xff907a0e,
-       0x4dff9ebb, 0x7f90ddd6, 0xecf18ece, 0x145f83ae, 0xad753f00, 0x1e8057b4,
-       0xefe7e2ec, 0x45ff3d56, 0xbfae0741, 0xa9c7488d, 0x9f4fe64e, 0xef5ff03f,
-       0xf381fdc1, 0xc0ace807, 0x42e838be, 0xa5fbaaf9, 0x5d6fe313, 0x14517fcf,
-       0xa5fc27eb, 0xfbe5a9f3, 0x521e5d9d, 0x4be017b6, 0x7544fb62, 0x1b6ebabf,
-       0xd3512fbc, 0x40594876, 0xf0bca7eb, 0xafd002a7, 0xdd997b5d, 0x3c7729d4,
-       0x8179fb0a, 0xca340f35, 0x209d5e94, 0xff698364, 0x0128de6b, 0x978bea39,
-       0x715c613f, 0xfc58f8a0, 0x043e0d7f, 0x4f3fe99d, 0x29854c18, 0xdef8ff07,
-       0x0e27a03b, 0x8d2f91da, 0x59127ef9, 0xe5ccf681, 0xfff4dde6, 0xe885bcdc,
-       0x03bde640, 0xefe13de6, 0xc0d7de77, 0xbed4a1a1, 0xcf97d072, 0xf30bbf9f,
-       0x847e3c7b, 0xfefc8077, 0xfcf9dfd2, 0x7bee98af, 0x97bddd29, 0x7f87f79f,
-       0x9feef3e7, 0xcb9ebfee, 0x79c2aee9, 0xfe17ba98, 0xa95df084, 0xfe12939e,
-       0xbfbde5be, 0xfef61bf9, 0x35bf9b5a, 0x93cf1b27, 0x70b0c03a, 0x40b6667b,
-       0xc8ed7178, 0x9dd82a99, 0xd5ef3f62, 0x7e60484c, 0xf7b02895, 0x1650c821,
-       0xcfdc240f, 0xf80d6382, 0xdd9b880e, 0x4ddc933b, 0xc9137768, 0xbc53aedf,
-       0xbe7abdac, 0x911acf1f, 0x21056f71, 0x8fc9399f, 0xbf8b6ef1, 0x5d1028d9,
-       0x74aef6a0, 0x818f37f5, 0xb48f23df, 0x9805ed45, 0x33690fbe, 0xaaca638f,
-       0xdc87f262, 0x53bce6f9, 0xbcede733, 0xf061073f, 0x0c247c3b, 0xd4716cf1,
-       0xd3ce1561, 0x02256389, 0x4938a54f, 0x0efc086b, 0x7dfccfbb, 0x7ee10252,
-       0xc7865fef, 0xa716048a, 0xed718512, 0x9471e03a, 0x78dce30d, 0xe2f11b48,
-       0x08baf7c7, 0xf17baff7, 0xf80ed4da, 0x663fc094, 0xd5fa17f6, 0x12d3fb84,
-       0x691a42ef, 0x76e69dd3, 0x2cbe8fdc, 0xb25d189d, 0x969d39aa, 0xd062e899,
-       0x4c7d0e21, 0x7cf03174, 0xd2b1f4a5, 0xebff8ac5, 0xf75f1813, 0x2e832f47,
-       0xef1d6e99, 0x7fdcc9d7, 0x133f0128, 0x820199f2, 0x7fdcabfb, 0xbc745290,
-       0x7eaa24a7, 0x7e0097bc, 0xe01a945c, 0x86deef2f, 0x3f73a4f1, 0x00dbff7f,
-       0x44afd54f, 0xebf8a0e2, 0x5121eddc, 0x2b0a5ef8, 0xb6569fe0, 0x404fb889,
-       0xacd168a4, 0xc3627d98, 0x85faa80f, 0xb953e707, 0x4e9e1ed7, 0xf7dcafbf,
-       0x61da0141, 0xcfd1bb2b, 0x605cfd09, 0x14750f74, 0xa5703ec0, 0x2b11fcc4,
-       0x6049acbf, 0xcfb396f1, 0xae20cab9, 0xe762ec23, 0xb7232b7f, 0x7398f6c8,
-       0x9904a14d, 0x739e9bc5, 0x3d085ea1, 0x28f9e021, 0xdcf62f80, 0x9c87e1a9,
-       0xf060427d, 0x9df197ed, 0x4f5dca98, 0xaa7c4275, 0x1fbb2df2, 0x5dbaf8cc,
-       0xc87ee29f, 0xf1ec5f94, 0x2e1fa076, 0x7d12e29a, 0x44bb01e2, 0xb6da8fe4,
-       0x6843f41a, 0x36a2f91e, 0x2beffdc2, 0x7eab57f4, 0xb83efcf1, 0xf4f55670,
-       0x7f885ee3, 0xe1df699d, 0xaec0b8c5, 0xfae7c74b, 0x3591fff8, 0xd6ffffdc,
-       0x3b4f7669, 0x067fffbe, 0xf176a0fe, 0xfb9609d3, 0xb106bbab, 0xb44914f7,
-       0x71ef52e8, 0xf0b9ed55, 0xcfafc428, 0x51e4fdee, 0xcffabb80, 0xfc14787f,
-       0xa9d0720a, 0xba827dc2, 0xf18ebf9f, 0xdfbbe33e, 0xf9d03d70, 0x2f18e3c4,
-       0xfa9b7ced, 0xe75ff41f, 0xc0b3a7f3, 0xea7ceccf, 0x4f10698f, 0xa9f9f3b9,
-       0x9dce6ef8, 0x27494ccf, 0x9189f471, 0x0786ff02, 0xd2b5af10, 0x11db48ed,
-       0x51ce7ff4, 0xd9ff83ba, 0xd489d713, 0xc69978b0, 0xe3bb39e3, 0xc4fbc7c7,
-       0x7d66da6f, 0x4842c6e7, 0x0646bf65, 0x4139c710, 0x006639e9, 0xe3cddc74,
-       0x5d6f9175, 0x0e738e32, 0x3af4a0fe, 0x85e3a16b, 0x3d8f45b6, 0x836d750c,
-       0x44e38dfa, 0x233f8007, 0x413fbefe, 0xe40122ff, 0x60bfef68, 0x37e80cfc,
-       0x73b84e9d, 0xd82c85cf, 0xee48f8bf, 0x85ef8b9e, 0x21576f3c, 0xfcf9511e,
-       0x9d4f289b, 0xf8c71ccf, 0xf071e136, 0x8ff3d24e, 0x99f92bc5, 0x1eedbacc,
-       0x74e1ff16, 0xe690f880, 0x071e72c5, 0xc46d7c62, 0x0b8bfa87, 0x73b1718d,
-       0x40bec627, 0x7877f6cd, 0x6e97a5bc, 0xd7a044c2, 0xcfdc97fb, 0x02a0f030,
-       0x8d8dae1e, 0xc38fc67b, 0x2d3dc4f5, 0x427a0374, 0xae27b3bc, 0x7b13d849,
-       0xcde16175, 0xcef47178, 0xda5e2c2d, 0x8f3fc729, 0xaf41c465, 0x9fe25976,
-       0x3fc581e1, 0x2b8f372f, 0x9760d3c5, 0xf15afd86, 0xf8abf675, 0xae5bfdfa,
-       0xe85f9d81, 0xdaad7f77, 0x3de61f7c, 0x05dd3825, 0xef6d6bfb, 0xa7cf042b,
-       0x2b73b374, 0xf967be7c, 0x3fb3d3f9, 0xd62e3117, 0xfa823914, 0x8c3faadd,
-       0xbc2b57fd, 0x6b787077, 0xe3f5b3f7, 0xd84f5eec, 0x7b39fb4d, 0xebe439f8,
-       0x63efddda, 0xaee8ee5c, 0x988e95a7, 0x8fd616f5, 0xce7ccc70, 0x80a8793e,
-       0xdfe379c5, 0x3171ab1b, 0x40eeb37b, 0x76ea71fc, 0xa71a6a7f, 0x9851142a,
-       0xf1e9701d, 0x2dfa48ce, 0x7699dfd0, 0x3a4ddf19, 0xbee31113, 0xc9701c17,
-       0x95a11f7c, 0x475d0fc9, 0x71c09ef1, 0xf0a77f76, 0x573c04b5, 0xd2f1e77f,
-       0xb7fde077, 0x8358a93b, 0x82b6dfdd, 0x4fdb69f1, 0xef4021f4, 0x13dfe3b6,
-       0x07dafd61, 0xffb18df8, 0x4fd44e8b, 0x50fd50f1, 0x10a06ef4, 0x77aad5d8,
-       0x66cb7dae, 0x938e9f82, 0x2342eb0e, 0x83ee07ed, 0xbc39b9c0, 0x569dee57,
-       0xaa88f00a, 0x7d0a754d, 0xf9bb21e7, 0xafde557d, 0x21ef9aac, 0x6bc6af90,
-       0x266f8fd0, 0xcc664b8b, 0x9f165232, 0x87f7190c, 0xabc213ca, 0xaf7f7ce8,
-       0x28bb3706, 0x8d9e7c5e, 0x78112fd9, 0x06a26a27, 0x2e63d3f6, 0x4bc1de7e,
-       0x83bcecbc, 0x7aa3643b, 0xf6ff61fd, 0x9e08930d, 0x7c06d867, 0x819e73d9,
-       0x2f800b44, 0xea7d768d, 0x321de72d, 0x5a2a13e1, 0x17338722, 0xfd5025ee,
-       0x77866ab2, 0xf11fe42b, 0xb2cdf7b0, 0x3821f748, 0xdb8db0df, 0x1560d9a3,
-       0xe77df6e7, 0x6fbeebec, 0x78a53296, 0x853f30e9, 0x535ff5d3, 0xca7c5ce1,
-       0x0d4fc52d, 0x2d856951, 0xa3dc1a63, 0x78bc7949, 0xcfcd066c, 0x34f4ff5f,
-       0xe2f7ffac, 0xff3459b1, 0xb20e7b93, 0xcf012afa, 0xaeb0bec1, 0xeff01a76,
-       0xd9fb96d7, 0xb9663314, 0x77f0057f, 0x77eef02e, 0xae706917, 0xefe15ba2,
-       0xdda00465, 0x7f0c89d0, 0x9f77ee99, 0x98657f02, 0xf00563ad, 0x7fcf63eb,
-       0x16f78491, 0x2aa1fbf9, 0xdce15469, 0x789a2d15, 0xf3e712f1, 0xccfbbcfa,
-       0x498dcbf5, 0x3f8177c1, 0xbc8de79a, 0xef1d1a6f, 0x0e718ae1, 0xf2d00e76,
-       0x829aa34e, 0xe9c85d74, 0xcb3df84a, 0x8b3e7c45, 0x02c290c5, 0x7f5caddf,
-       0x5751ef19, 0x1ef4578b, 0xdbab8735, 0x67fbefd5, 0x3378007f, 0x007f8293,
-       0x3fdf59fc, 0xb815c57b, 0xe519f500, 0x5c7de25f, 0xeb333de3, 0xea4468bb,
-       0xfb3efb8e, 0x5a2efe56, 0x9bfef07f, 0x69ba283b, 0x682f39ff, 0x39518f7b,
-       0xf150b31b, 0x31cfd1c3, 0xd2fd0bcb, 0x0426c220, 0x1fa71076, 0xf788cf3c,
-       0xb822ee1f, 0x1765db5f, 0xbbaff074, 0x7d4549fe, 0x3a70b99e, 0xae5d5ffa,
-       0x339c08ec, 0xc35bbaea, 0x018a3d7d, 0xe869e401, 0xf828c481, 0x3e1e5487,
-       0xe7c3c8b7, 0x8f37fe66, 0xdb5175db, 0xa9fd81df, 0xa06a3fbc, 0xed8bdcc5,
-       0xee9e9912, 0x8e10d06a, 0x087424a1, 0x8e81fdd6, 0xebe6e397, 0x46cfa737,
-       0x9eeb9e9b, 0xee1ff880, 0x28ffc18e, 0xcc74bf77, 0xe63a3377, 0xd1d0e3bb,
-       0x7bdd6efa, 0x6858e0ae, 0x28fcba77, 0x7d675fbe, 0xdf4aceaf, 0x21f5a93a,
-       0xed2b3b78, 0xfeb8a7c0, 0xb31bf418, 0x29d22c7c, 0x00939e86, 0x3e07318e,
-       0x06bc01b5, 0xe7ec1f1d, 0x9ba9793c, 0xf1d673ad, 0x063acad2, 0x9fb4e307,
-       0xf74cd6e5, 0x451c0a0e, 0x69ca897e, 0x87c58dba, 0xb7efb6fa, 0x9d4b9cff,
-       0x59502cf3, 0x73ff14bf, 0xfe064f00, 0xfbf3756f, 0x7ff17dea, 0xf8a3b43b,
-       0x3fe61dbf, 0xbbcffc00, 0xfb0dfe14, 0x87eb8abf, 0xa29fd82a, 0xda1ff47c,
-       0x3a1cb4cc, 0x8dd134ee, 0x8764b072, 0xd931f7c8, 0x3e865ffb, 0xfd5d7259,
-       0xb917b821, 0xf20267e4, 0xfefe42eb, 0xfdfc27e5, 0xc1b9eb4b, 0xea10b2f2,
-       0x1f9fcbcb, 0xaa3ea30c, 0xff2e65da, 0xbbcf7767, 0xde785997, 0xad352417,
-       0x2b4ebdf7, 0xb9bbcffe, 0xb4e858de, 0xd72f7bc5, 0xdbd68748, 0x33cce74c,
-       0x83f4f4a6, 0xa6cfa0fe, 0xb8f189bd, 0xc409957f, 0xa5297413, 0x2019de10,
-       0xf4094285, 0xd7e5cc5b, 0x72d86fe8, 0x1d9ffaf3, 0xcc43df32, 0x43df316d,
-       0xbe6ade1c, 0x66d57887, 0x51c43df3, 0xc43df361, 0x338d766b, 0xae4747e5,
-       0xb31fb537, 0x3f29b27f, 0x534dfa36, 0x66c7f1fb, 0xda13f29a, 0x7f6a67bf,
-       0x4df35bed, 0x5475d7f5, 0xf86fea9a, 0x7f299968, 0x9b3ff763, 0x311747da,
-       0x61b878fd, 0x5bdc1179, 0x7872f030, 0xa15362a9, 0x9b08e97c, 0x9e5b105a,
-       0x90056ba6, 0x7fe0e916, 0x532f27f5, 0x8a2a3f1c, 0x898ba75d, 0x536fd26c,
-       0xd47ce61c, 0x8f7dfe6d, 0x35722c97, 0xcb527ea4, 0xbc1d9a08, 0x63cf0f24,
-       0xc63af953, 0x01b1dbf5, 0xa0dfb7ea, 0x9b46d57c, 0x2f956f20, 0x9a01bde3,
-       0xad8fd886, 0x1f9f77b0, 0xd4f99a72, 0xf95e8fd7, 0x0738db9d, 0x53facad4,
-       0x264bc6cb, 0x3fca3139, 0x172d8c2a, 0x73c74f16, 0xabf5fd40, 0xb35c16f8,
-       0x3bbc107d, 0xa3530f3c, 0x16cca9bc, 0x67dfdcf7, 0x7fd0bfee, 0x8ec7dcda,
-       0x7cf00cfa, 0x26daf7ce, 0x7b56bf38, 0x51fa377b, 0x5e337619, 0x5decf37a,
-       0x479e0363, 0xac3e481a, 0xb6fdc6f7, 0xebe13445, 0xd177ce36, 0xe0d333db,
-       0x3f66419c, 0x87a155fe, 0x1b47ebe9, 0x042cd742, 0xe98711c2, 0xb456795e,
-       0x39f81a6e, 0xeb79f8c3, 0xe7f8b64d, 0x0c3c92a0, 0x48a0e92f, 0xdd505ec1,
-       0x2b9c2f68, 0x4f0bd77f, 0x0f68dcc7, 0x38e87926, 0x17b4c7f3, 0xbad4fbb1,
-       0x5ee8e67f, 0x947d0db8, 0x026c0ee5, 0x93e592fd, 0x17dd9688, 0x83dbf49e,
-       0x788ef02d, 0xefcdb263, 0x00b77cc6, 0x4c7fd9e3, 0x5e3a20c8, 0x84459fe3,
-       0x75f0f1af, 0xeec83e78, 0xabb8c7ae, 0xcfc24f31, 0xe6711809, 0x89d9be0b,
-       0xabc6cf80, 0xe107ee7b, 0xdc17907b, 0xf7e876c1, 0xc71946c2, 0x982c9c6d,
-       0x4b798dea, 0xf78dbf9b, 0x6cdcb2be, 0xde74e5de, 0x933db700, 0xa8f8d5c1,
-       0xae113240, 0x28f4bdff, 0x5cfb35f8, 0xc507def8, 0xc7c010c7, 0x73fb3d39,
-       0x3a79319b, 0xee419aaf, 0x9ed16bad, 0x4ea7ef89, 0x8fa1e637, 0xe33bd134,
-       0xe2fc332a, 0xc6fd1946, 0x3c6e4945, 0x886e10ef, 0xe79afa72, 0xf99be4df,
-       0x5c295b9d, 0xf8884eab, 0xd1d6b6de, 0xfd28f4ba, 0xe5cdbcae, 0xf17d6b0f,
-       0xf0634e7f, 0x7ba7f852, 0x4f36de40, 0x79e3f9c3, 0x31ff806a, 0x0d9c3c81,
-       0x452c17fc, 0x236c183e, 0xc7d36fb0, 0x7930f04e, 0xd951ed9e, 0x72be357b,
-       0x85be8726, 0xfda76cd7, 0x5dfa7995, 0xb0f36ff7, 0x4f36ff75, 0x72ff759c,
-       0x975707ef, 0x54851fb5, 0x37b445d4, 0x111fa908, 0x3d53476b, 0x1bfd0e56,
-       0xc7f13179, 0xff6fd005, 0x65bf9a76, 0xede5f644, 0x80cfb034, 0xecfb0d0f,
-       0xaed98f4e, 0x3fbbd18c, 0xfbbd30f4, 0xf4c0cf43, 0xfda18fee, 0xe345efe9,
-       0x4aa935da, 0xb4f7bd7c, 0xac1fdd87, 0xe7821553, 0x0fd9fb03, 0xdae5c9d8,
-       0xd6feef3a, 0x1ff9cba5, 0x4f832e39, 0xfcfefacd, 0xf4112d31, 0x4207ca54,
-       0x86b777dc, 0x3c6dbf2c, 0xad9b6bd0, 0xf7cc3378, 0x78fe1667, 0xf59f4d68,
-       0x18f1cc2b, 0x6ac78b8e, 0x099b478a, 0x973c3b8f, 0xb6bf0fb0, 0xdf30afbe,
-       0xf8e4e9f3, 0x09bf7aa6, 0xeb373bc6, 0x6b8822bd, 0x1cf9ced4, 0x1ed7fef5,
-       0xaebccca7, 0x1d397e18, 0xa1e00567, 0x799fd673, 0xe303ae7c, 0xb99eab4a,
-       0x58e2112a, 0x7a0d9335, 0xaa7df044, 0x4839f9f3, 0xecfb7397, 0x2e79c03a,
-       0x3d139d99, 0xa3daefb7, 0xa4f8f710, 0x2c7258e1, 0x793dcf7d, 0xfda648bc,
-       0xbc7bdb9d, 0x7703c248, 0xd43bd361, 0x5b7f1735, 0xdef77014, 0x37e1e84b,
-       0x368f5b07, 0xe57c593a, 0x37173841, 0x6abfda86, 0x7a65f212, 0x285eed9a,
-       0x1dbf1d17, 0x395c21fc, 0xa62fe63f, 0xd04ab259, 0x7ec11633, 0xee373cd3,
-       0xc972f967, 0x9dfa6cc8, 0xe387ad12, 0x6af9c4cc, 0x04efc098, 0xf1444eb8,
-       0xef3c02f7, 0x3ef86076, 0x02b243f1, 0xbdffc29e, 0x78093c1a, 0x09ab3a4f,
-       0x77c41a89, 0x471e6e8a, 0xd30a6953, 0x3ab7ddbf, 0x848cf7f0, 0x53aaaf05,
-       0x3cdafea8, 0xdd8efd93, 0x920b63f9, 0x55691fc0, 0x0df2de99, 0xb463e1eb,
-       0x6be7078b, 0xe6231737, 0x40577c75, 0x921d1955, 0x8a6b6c33, 0xf9c78c35,
-       0x25fe98f3, 0x3dff1a52, 0x1eb7ca29, 0x1c43a6cd, 0xc5cef8d8, 0xfc522bbf,
-       0x7803cebf, 0xf0fcdb46, 0xabfb8f4e, 0x92ca386f, 0x28ccfb69, 0x945e5fbe,
-       0xc39de1c0, 0xfbef07de, 0xd345e34e, 0xd4b5187d, 0x27b74efc, 0xe214b4d0,
-       0x6defd0fc, 0x8bcef8c9, 0x38a29eb9, 0x0bbb9691, 0x0aaee5cd, 0x47e18f9a,
-       0xf6d677eb, 0xae925f86, 0x37f63832, 0xbf0f1038, 0x79fd506c, 0x340e8f94,
-       0xb07f30f8, 0xda34c341, 0x0fcb1230, 0x2f31f837, 0x986cf4da, 0x7faffa4f,
-       0xeebb1490, 0x9d54efc2, 0x75c3e18c, 0xf9ade472, 0x88df8f80, 0xaf15af88,
-       0xdefe478e, 0x3a8e9a34, 0x7367bd86, 0xfefec632, 0xd257f2e9, 0x0d5f284a,
-       0xd3afd1f9, 0xefc3c64a, 0x17f3b096, 0xf63a4170, 0x257aee1e, 0xe093f9a0,
-       0x34c63477, 0xfbc2863b, 0xc95bc1a4, 0xfd239458, 0xbbf089c5, 0x6c337b0b,
-       0x949a7eb4, 0x07f8ecd7, 0x64deab80, 0xe7e7afe7, 0x6c9f1f33, 0xbce3afd6,
-       0x0a66ff4c, 0x71bce3c5, 0x537e09f8, 0x39acfd00, 0x3307b9c6, 0xbf54891e,
-       0xeb8a76e1, 0xdfb3efe6, 0xc754485f, 0xf7bde1fb, 0xcec35ecd, 0xbec5f7a9,
-       0xff99bee7, 0xe1e2440e, 0x29176825, 0x103bf63e, 0x0f7b0a29, 0x4d930489,
-       0xe5cdedef, 0x0606ccfd, 0x1f57d09a, 0x15fde6cf, 0xfb0e791d, 0x8897df83,
-       0xf087eff5, 0xccd8c3df, 0x3574d3f5, 0xed4dec50, 0x5bd4676d, 0x7759ebbf,
-       0x0bd1216d, 0x890143f6, 0xed04bd80, 0xd4bb698a, 0xdc02030f, 0xd7ce33ef,
-       0xcdf80b3e, 0x93ddfdef, 0xebc3027d, 0x8a7d3c93, 0xd4494eff, 0xe3079813,
-       0x123c16fb, 0xca7603da, 0x6206bb3e, 0x8fe47452, 0xf8947ef8, 0xe701c53b,
-       0xbc0f53fc, 0xd9e5eecf, 0xbf38143a, 0x7c5bd2b8, 0x4551c413, 0xf3033ea5,
-       0x816f4ef7, 0xfa9e83fc, 0xdda3d887, 0x1f0137c5, 0x06f7f3a4, 0x01000408,
-       0xe1aa080e, 0x43fd638f, 0x64654eb3, 0x2bf2cc9f, 0x873637bd, 0x3f5f2132,
-       0xf208f80f, 0x7dbfb48d, 0xc021c149, 0x86e16e47, 0x423763e6, 0x037f68de,
-       0x5789ffb6, 0x3b8ffe65, 0x4af60d98, 0x79a55e4f, 0x625e4c4f, 0xa960e279,
-       0x239abf31, 0xd073c47f, 0x3bd807b5, 0x6607a95d, 0xd4cf3008, 0xff1033fd,
-       0xbcb7d5e7, 0x878c342b, 0x04eb608f, 0xf41b978b, 0xa6e1ee30, 0x79f783d9,
-       0x9d61f863, 0xc4c76cd7, 0x0fbc27dc, 0x1fd3ddf0, 0x36cbaf8f, 0xf74a9ef6,
-       0xc6efd88f, 0x547b030d, 0x86b9b884, 0xa3dc2e69, 0x70c1fea7, 0x98395c12,
-       0xcde35fd6, 0xb55e3a41, 0xa9cdfb3b, 0xa75f2f5a, 0x80772964, 0xf8b54e3e,
-       0x3f5cd935, 0x7f8b508f, 0x372b4893, 0xf0b5c10a, 0x8f686c9e, 0x937de2ac,
-       0x4728195d, 0x228eb967, 0x5f3183f5, 0xcbbfefcd, 0x476b832b, 0xc4591e81,
-       0x76556ef4, 0xdfa658a0, 0x8d973d57, 0xf0670bbf, 0x2452555d, 0xf7bb9c6d,
-       0x3791b75c, 0x21e4477e, 0xef09d5b5, 0x5afb18f2, 0x6437fbb5, 0xc7fd3ec1,
-       0x3b46de87, 0x36624971, 0x76d359c2, 0x69df815c, 0x7ca36da9, 0xd8fbbf47,
-       0xa3c763d9, 0xc887f25f, 0xbe026fa0, 0xc368d0fe, 0xd9fdddcb, 0xfd522f55,
-       0xea85d3a6, 0xd3038368, 0xd5fd7a9d, 0xf09c0ae0, 0x49c9b82e, 0x1cf1e9f9,
-       0xeafe055d, 0xf51eb7bc, 0x3a8ae3d8, 0xd3aff80a, 0xe066c3fb, 0x9124aae7,
-       0x5f0febf3, 0x7ef8f3d6, 0xb9efcd3d, 0xbfa6edb7, 0xa160df68, 0x7ba9fed9,
-       0x41fc8dc4, 0x02df92ed, 0xb66ed51f, 0xb3fd6085, 0xbef1da39, 0x1be82773,
-       0xfbe65fd4, 0xa6051b99, 0x5873430f, 0xf772fa1c, 0x74be2b34, 0xfd8c7091,
-       0xe99124bd, 0x84290aab, 0x5f1576fb, 0x2ffeb17a, 0xba69c71f, 0x1c77da0f,
-       0xe31bd637, 0x838ef754, 0xf6fd527c, 0x5fcff461, 0xafb0dabc, 0x77ffd475,
-       0x61cfc53e, 0xe874f538, 0xd0d941e7, 0xa4cfd427, 0x1ee78678, 0xf9243e79,
-       0x47a97908, 0x2e6dacff, 0xf6fa04c9, 0x7eb313d6, 0xb74a25d2, 0x3e781297,
-       0xc9737f74, 0x13ed38a4, 0x8c73ed2c, 0x7fb14ffc, 0x3a0f3c2b, 0xda0ef37b,
-       0xbd93fa5e, 0x6df00f27, 0x4bfa59b0, 0x86dfc636, 0xb7fc19fd, 0x65fbbbc7,
-       0xa5e9ef78, 0x10f140a4, 0x2068df66, 0x15245b87, 0xc0d1877f, 0x3ebe1ef3,
-       0x8d797c55, 0x78bdff09, 0x9f95302f, 0xfb4cd06e, 0x2e178ba1, 0x7b3f7bc3,
-       0x41563af8, 0xdb3eec42, 0x7da6b923, 0xc70fffd0, 0xb8a385d7, 0xfe4a381f,
-       0x328c70c6, 0x385e81e9, 0x5fe54df2, 0x69310e17, 0xec366976, 0xa1b1ad53,
-       0x0b66909f, 0x6ec07239, 0xf7ec5ffb, 0x0734201a, 0x61a899e7, 0xce57da6c,
-       0x079f6039, 0x448e79c6, 0x40e3498e, 0x056d749e, 0x913f53ac, 0xe5a1afd0,
-       0x8619390e, 0xfde1d56e, 0xd8952a2b, 0xb0754e5f, 0xe6f51986, 0xab876277,
-       0xe5a258a4, 0xb879d5e3, 0xdd94e5ee, 0xfdf60755, 0xcfe17736, 0xbc931357,
-       0x5ab27da2, 0xc7f68a58, 0x9b17c49a, 0x3d38df61, 0x0233d981, 0x58f9b179,
-       0x267abc46, 0xbdf72daf, 0x31c41378, 0xaed4aeb6, 0xab6e7f06, 0x0c391c33,
-       0x6e3df9eb, 0xdcaa3dfc, 0xf816e175, 0x83710abd, 0x314bd70d, 0x2b6bbc29,
-       0x6078179c, 0x8bec1f84, 0x40d760ad, 0x5c6e35fb, 0x421a5bff, 0xe2af2f68,
-       0xf5f6c0eb, 0xe7385493, 0x9296e8dc, 0x916bbd61, 0xb8056feb, 0x64efba5e,
-       0xd03ae3b3, 0x4196fe63, 0x80cbef3c, 0x71cb4d75, 0x14f5e58c, 0x68575b19,
-       0x3485c183, 0x44ffc3f2, 0x33d412ad, 0x6b0ed127, 0x04ab2f74, 0xbfd68e3b,
-       0x7a78a0ec, 0x85e3993c, 0xe8f4e7d7, 0xa0cd93a5, 0xbd15c507, 0xef3a12f9,
-       0x7a633f1d, 0x3fda09ea, 0xe7452bbc, 0x18778213, 0xe84947bb, 0xc1242587,
-       0x74d0c76f, 0x9dfb0e74, 0xbd17aa5b, 0x3849c7e8, 0x491f635f, 0x0f7ec519,
-       0x7ac3da1d, 0x83919093, 0x0cca98fb, 0xe2835ef6, 0x66fde371, 0xdd5677e3,
-       0xb3a7f8c4, 0x67df2978, 0x43de5971, 0x895fae70, 0x784ee99b, 0x4f862137,
-       0x0b7bcb15, 0x07cc0912, 0xcd544b7b, 0xe449bfe5, 0xd8834afb, 0xb70eadef,
-       0xa32ed085, 0x35e98452, 0xd9f68a24, 0xf981d268, 0xe66de031, 0x0d2c35c2,
-       0x278d8e2f, 0xbbe2c8ba, 0xc7ec1101, 0x788d5bb4, 0x44f5f04c, 0x96bfdeba,
-       0xfc36e3c8, 0x66538c77, 0x7d7ee214, 0x5fab1266, 0x0fbbc815, 0x338dbcec,
-       0xc69c61a6, 0xf58cefb0, 0x16dfb0d2, 0xab579872, 0xc17b5c42, 0x3a16ebb0,
-       0xb6753e59, 0x8868e0fe, 0x0b53b66b, 0x2fee1b34, 0xf96af8b3, 0xb034e2e6,
-       0xba1e16cb, 0x4ce4ed15, 0x8b65d995, 0x8250ce36, 0xdadee1a3, 0x8a07f43c,
-       0x84484c37, 0x4ed5847d, 0x8575e27f, 0xfbe267e8, 0xc7b503b9, 0x355da6b6,
-       0xab71e419, 0xca90128d, 0xeeb24bfb, 0xb17c0b1e, 0xcced0f21, 0xc6c109ad,
-       0xd6efda24, 0xabfcd67f, 0x4ea7fe68, 0x8c38f0bd, 0xd5813ab3, 0xc051bbc3,
-       0x12e73d9b, 0xc9bbe1b6, 0x3d6f8dfd, 0x1252f097, 0xa8ca7f7b, 0x7e536fff,
-       0x80007d7c, 0x00008000, 0x00088b1f, 0x00000000, 0x7dbdff00, 0xd5947c0b,
-       0x66fdf895, 0x666579be, 0xf263c992, 0xc2130922, 0x9e4e5e4b, 0x124c2280,
-       0x4cb443c2, 0xe8202a10, 0xa79034f0, 0xbadc5d48, 0x30040cff, 0x5706b650,
-       0x84ea2b11, 0xbbaac562, 0x351ba341, 0xb88080ea, 0xda446dd6, 0x8ffd16d2,
-       0x4810154a, 0xfed2b58a, 0x39cf65dd, 0x7cccdef7, 0xb5f01993, 0x3efeb4ff,
-       0xe7ddf7ee, 0xce73df79, 0x12e973bd, 0x2c614dfc, 0x5630a494, 0x51c1d8ca,
-       0x618cf58c, 0x24dea98c, 0x064dcf06, 0x34e2d26f, 0xa37efac6, 0xf5e1bb67,
-       0x926f6617, 0x25d8c6c3, 0x79fa2ed1, 0xa0b199aa, 0xcdb3b189, 0xc11c166e,
-       0x336699d8, 0x1f966b95, 0x9fa0c698, 0xb9850e9a, 0xc55b19f2, 0x3f6336da,
-       0x69923baf, 0x3d0155dc, 0xf4648e0b, 0x5bfe0977, 0xd528fcbd, 0xebc9dd5f,
-       0xaa0eb2d7, 0x4f3192bf, 0xf76b3c07, 0x1cd0595a, 0x51df5fae, 0x4a1f69ac,
-       0xd7bf51d2, 0x3b06fb25, 0x5bdd8c9c, 0x2abefc3d, 0x5d569f78, 0xfae1f662,
-       0x13e38e58, 0x87afa8ab, 0xebe63af7, 0x77aeb188, 0x49de5c04, 0xac4e8a82,
-       0x32b1d0ed, 0xe03ad6c6, 0x1ec62e9f, 0x6c7cd850, 0x15f7f6b7, 0xc2632919,
-       0x9e2ad6ed, 0xf898c70c, 0xa8bc6a70, 0x88d48167, 0xc467dab2, 0x345e35f5,
-       0x0ef3fbd2, 0x63075fb3, 0x3ff4c91e, 0x7fac2d70, 0x1953eb26, 0x909f53cc,
-       0xcd5d8e38, 0x71258b58, 0xba673e37, 0x08a17d0c, 0x53333038, 0xf8337e71,
-       0xc4ebf62b, 0x71944769, 0xed403ed8, 0xa98ed967, 0xc473400c, 0x8303735e,
-       0x90b037f7, 0xce060aca, 0x28fdfa0f, 0x2359dfb2, 0xdd1be5b5, 0x09ecf2da,
-       0x7e6332da, 0x9a4fd782, 0x1a4eca9b, 0x04fefdc2, 0x0311d6a6, 0x5802b72e,
-       0x5eed7eb1, 0x0464e04b, 0x923beb1e, 0xaec6e535, 0x88c9c0ac, 0x1ff16a71,
-       0x135ff059, 0x589d775f, 0xdf4607f7, 0x5bc00ead, 0x71190b3d, 0x46c140dd,
-       0xacc658ef, 0x7c45e616, 0xf16fd81d, 0xcfe812b0, 0x00b76e66, 0xabbb1b7c,
-       0xdef02595, 0x30ef876a, 0xe196273f, 0xfaf03569, 0x0e88058c, 0x39da8fe0,
-       0x5bed99bd, 0xb713e415, 0xcdfedaab, 0xff00dde7, 0x4f0293dd, 0x24ac3d95,
-       0x0ea3ac46, 0x5e1e91d6, 0x07eb39c7, 0x582f8865, 0xa5ec6fcf, 0xa6461748,
-       0xf3d78524, 0x5cb5e1ad, 0x5dc6af0b, 0x1837a236, 0x1844bde7, 0xcea761a7,
-       0xceb2846f, 0x7e4463dc, 0x3ce917b9, 0x1c72de06, 0x6f3c4c4a, 0xe0c73c43,
-       0xfcaceda7, 0x1cc7e43e, 0xc7181fe4, 0x6527eeb6, 0x8f818b27, 0xfa1737aa,
-       0x054dbea0, 0x547186fe, 0x08a9bff8, 0x6d3bd9c8, 0xe9d03255, 0xc3e73b29,
-       0x7a2e890d, 0x0abc50ee, 0xe75d35e2, 0xd5fa47c9, 0xcc43b827, 0x66a3f1c1,
-       0xcb601942, 0xf962c1ae, 0xefe81ebd, 0xcb1b9821, 0xf0098416, 0xcbc2c878,
-       0xefca392f, 0x6ee308dd, 0x0de5e64a, 0xd5b9bd3f, 0x16ca093f, 0xe5439e59,
-       0x416d0c87, 0xffdde03d, 0x44f5c982, 0x28f7b53e, 0x32305e58, 0x4d4c04f0,
-       0x2365843f, 0x4226a65e, 0xf4b720e7, 0x9b769a2f, 0xeed05ea0, 0xa78427fb,
-       0xfb39ff5c, 0x26363cf1, 0x4d7e7f66, 0xacdf797f, 0x53bf183f, 0xfbf87577,
-       0x419dc4d4, 0xc2e76f3d, 0xe7a72c76, 0x9ff43f03, 0x6d89a2fe, 0x0623e285,
-       0xda179b76, 0x632c5dd5, 0xd43908c1, 0xb679f023, 0x5b7241d9, 0xf943afbe,
-       0xa9f9063d, 0x7d70e487, 0xfe46aa47, 0x7f5cb94a, 0x7f4d5af1, 0xc27c8e39,
-       0x43dabd57, 0xe2feadf2, 0x121efa64, 0x736cf4f2, 0xf889e926, 0xc8d20ce3,
-       0x1338f0f5, 0x72f8b059, 0xefa24ce3, 0xcbe61c72, 0x06bdb922, 0xa4240ce7,
-       0x87bc8237, 0x750c2e71, 0x465f2525, 0x0276d99f, 0x67ac4591, 0x63341a9b,
-       0x07dcdbff, 0xfc18be1c, 0xb844e520, 0x1edb51bd, 0x811b23f4, 0x4863edf4,
-       0x7aacffb7, 0xd4fa91cc, 0x5038f066, 0x8af6a86f, 0x34372e23, 0x86647e4d,
-       0x5169280a, 0xd97f3d39, 0xd1e881b6, 0x411f706e, 0x3aeddafc, 0xafbe1f97,
-       0x483ce9b7, 0x730e2d27, 0x51bdf100, 0x7281c1b9, 0x076bf643, 0xb8f38f31,
-       0x7a421b60, 0xd57ade3d, 0x0f54898b, 0xa9199266, 0xc6f7ff1f, 0x0f17c583,
-       0x31bd8f1c, 0xfa0b88f1, 0x6e744b57, 0x910be00b, 0x1d0471fa, 0xdf63f744,
-       0x779cc6a9, 0xff093d74, 0x8436f8b8, 0xe7fe1112, 0x8119ba6d, 0x4d2ef318,
-       0x9e9bbe56, 0xdf25145a, 0x3c3b7f93, 0xd095ed88, 0x49f20a0f, 0xa32696fe,
-       0x90bc2dfc, 0x3922e958, 0x73b5ee9f, 0xb6e385b1, 0x7d9a8ed8, 0xed988fa4,
-       0x3ebfd913, 0xb849fd3e, 0x64aade18, 0x04601f88, 0x4ae37a86, 0x412bb070,
-       0x1597e22f, 0xd3e50caa, 0xa76f3a40, 0x77d7f4f9, 0xeb11e743, 0x0edd516f,
-       0x75fd6ba4, 0x99ca331e, 0xe6398ef5, 0xaa379410, 0x20f9d9ae, 0x02defa87,
-       0xb7d6127b, 0x1cc8ad29, 0xc15a8f8b, 0x2df9c46e, 0xd669d64d, 0x1d669f23,
-       0xf7e8dfe7, 0x9eb9925b, 0xb13fdd68, 0x9f1253c7, 0x79d2407e, 0xcb9b8f51,
-       0x5856c754, 0xe7c0de9f, 0x0763896b, 0xc1e37eca, 0x0b7ecb6b, 0xa87569c9,
-       0x44f68039, 0x549b78f4, 0xbe078f77, 0xf8f9826f, 0xc7c39cb1, 0x3aa254df,
-       0x16d74376, 0x47330257, 0x4b3837d4, 0x6c17fe08, 0xdf0f4c69, 0xc63d2137,
-       0xd3849798, 0x68efe4bc, 0xe8a2f93f, 0xc3b7f732, 0x5d0d10d9, 0xcba2c6b6,
-       0x4b37a879, 0x3999fcf9, 0x9343fe72, 0x8c7c8ebe, 0x49b29ba6, 0x977c83cc,
-       0x5876cf01, 0x66caa76f, 0x807d43ec, 0x9844d6b6, 0xe636cddf, 0x393e9900,
-       0x32677cb5, 0xe7acb7ac, 0x3f219180, 0x1d693a74, 0xf47da275, 0x8e14a6b8,
-       0x838a533f, 0x3dc7499e, 0xf8014f4f, 0xb824f676, 0x99d4f814, 0x0630fa02,
-       0xbc088f7c, 0x9fc6d633, 0xf21c686a, 0xb65fac8f, 0xc3767988, 0x6b0250f3,
-       0xb2bd8335, 0xc607c84f, 0x154fe7ee, 0x99c61718, 0xdde8cafd, 0xf58a2f64,
-       0x80b5021f, 0x43d3d3f5, 0x77fd14e3, 0x585edbc0, 0xeade047d, 0xdbc221cd,
-       0x6bdf46db, 0xe3c69f08, 0x772c74a1, 0x87933d1e, 0x70b670f8, 0x25efb5fb,
-       0x6ee9006b, 0xd3d67e20, 0x0e2eeafc, 0x81e2fe62, 0x8353ab78, 0x2eeb5fa4,
-       0x5877d1e6, 0x129cdfb7, 0x6c1b3efe, 0x2eb00986, 0x4270e666, 0x47c2c4f8,
-       0x896be0bb, 0xa3eb500f, 0x081f02ed, 0x3ec48fa7, 0x4eef1fa7, 0x780666e3,
-       0xefe66b3f, 0xdf246799, 0xfe7d0987, 0x005e4251, 0x0d1f33f7, 0x7a46ce07,
-       0x91e95d50, 0xe2cea77a, 0xac3e6fb9, 0x67abbd9b, 0x5963c04f, 0xed15ada5,
-       0x4f2665ab, 0xcb5dda12, 0xeb2bd3de, 0xc48409f3, 0x3c042b07, 0x5df732cf,
-       0x36ff3f88, 0xc209e38b, 0x97ff769f, 0xf8bca3bf, 0xa2bf681d, 0x9346ef4b,
-       0xcda56971, 0xf596fd8f, 0x876d3c54, 0xad5b2bf7, 0x2efd062e, 0x04fee29b,
-       0xf765bded, 0xf21b5c59, 0xa438bf71, 0x5dfa0b3c, 0x03be60fb, 0x9d7581e5,
-       0x06ecd337, 0xeb7ee093, 0x6de02b4c, 0x8964b293, 0x7dac0852, 0x1516ca7f,
-       0x57feacf0, 0x281667e5, 0xc17f755f, 0x8c75f316, 0x1cb282bd, 0xd0ff59ed,
-       0xfedf6899, 0xf646a712, 0x7f6fb72e, 0xca274479, 0x82a65bc5, 0xece5180a,
-       0xce60d9d4, 0xb78a532b, 0xf4fc6198, 0x0ea14f14, 0x32935bc6, 0xb7f62661,
-       0x7fb1bef4, 0x77df09dd, 0xa99acca4, 0x44de13e6, 0xcaccef7b, 0x926ed0a1,
-       0x54b3cf2c, 0x56697f42, 0x27a7b616, 0x090fbf00, 0x77f68f8f, 0xbdfdbf67,
-       0x1cd4e660, 0x53454bc0, 0xbffd0aa5, 0x96db729e, 0x36315731, 0x877281fe,
-       0x983fc607, 0x15a664b2, 0x9469dff0, 0xf16d97f5, 0xcc9d58c0, 0xbe0186f7,
-       0xbafef1ff, 0x9fa86699, 0x742dea96, 0xcd53fac0, 0x91996ff7, 0x65f81dfb,
-       0x4fbd12a4, 0x1271482c, 0x90461cdf, 0x33ebade6, 0xf82afd72, 0x71d3873d,
-       0x9424797f, 0x4ce511ed, 0x10dcee5e, 0x4e9c7e5b, 0x33b972e5, 0x8f77f621,
-       0xef004b90, 0xb3e90ea0, 0x96181acb, 0xc027961f, 0xc409e64f, 0x3cb9db5f,
-       0x639abe01, 0xd98e3e27, 0x5fe537df, 0xd3f53b80, 0xe8ac7aa9, 0x0d7290bf,
-       0x71c56666, 0x69764cbe, 0xcf5975e4, 0xbfb79252, 0xeb7c154a, 0x5671f0e2,
-       0x330ae56a, 0xb8470cf7, 0xc58b76c8, 0x4b47f33a, 0x88d052ff, 0xe2d6b9fc,
-       0xacf9c0c9, 0xc19e57dd, 0xd787632e, 0xf8d72c5d, 0x98ebc24b, 0xf407ef4a,
-       0x44b9fd0b, 0x5f31eeff, 0x57c95e07, 0x7d1a5780, 0xc33ad2bf, 0x3bfd69fd,
-       0x7ee3fb03, 0xc57a019e, 0x1b9e7b18, 0x415eb853, 0xe422ebf8, 0x5f214ada,
-       0x3d916a41, 0xabc5fe7e, 0x8fcd6f76, 0xf503771c, 0x7a7df80f, 0x412fee0a,
-       0x2b1ca2be, 0xb0b33d53, 0x8a4f597e, 0xa079ed03, 0xde828db7, 0x8937a454,
-       0xa694cee7, 0x76ef5a72, 0x863bb1c5, 0x3913f81d, 0x83c536af, 0x22c649f6,
-       0xc4497e9f, 0x87fca4fc, 0xff453bfe, 0x1f9e9c25, 0xc5e7a7ed, 0x2fc23fc8,
-       0xdf40dcc4, 0x5fce0763, 0x08ce36c1, 0x2582f5fd, 0x7091f380, 0x2ff4b6fb,
-       0xb8ba87ed, 0xda912a7a, 0x260f1c65, 0x219ea0ba, 0xb9f9c5c5, 0x6bc4e3e3,
-       0xe9755f51, 0xebe2e299, 0x2651b946, 0xe7bfa4e5, 0x764a8548, 0xbb2e584c,
-       0x72919ec8, 0x87366833, 0xbdbfdfeb, 0x9446c667, 0x2fbe26ab, 0x1483d34f,
-       0xe3cf0a2f, 0x2fae14e5, 0x2798f827, 0x24781d96, 0x08e52ed9, 0x75e1e3ad,
-       0x5863ec95, 0xd7e85d9f, 0xf93f2109, 0x664c9eb3, 0xf0e13ec2, 0xb67bfa90,
-       0xdcaff429, 0x47a5a64f, 0xa53b0659, 0xee105741, 0x89cfbf1f, 0x8263fba0,
-       0xf3f1a20e, 0xc013e55d, 0x48708fc1, 0xc872e14d, 0xed056509, 0x17f4150b,
-       0xb55cffc0, 0x3f35bdcd, 0x2e36de62, 0x1d7a9d8f, 0xe0576397, 0xfe54b48b,
-       0x3b25efbd, 0x1e1873f1, 0x2ff98edc, 0x1d76f701, 0xc17dc1ab, 0x09f01d21,
-       0xaf8da2d2, 0x598bfcf3, 0x29e7efd4, 0xeffeb93a, 0x1bb72e45, 0xd7ce3c61,
-       0xbfd63f64, 0x3b5da83c, 0xdcdfde7f, 0x658f4e54, 0x68853dc7, 0xdaf30cc7,
-       0x285fb8dc, 0xc07399eb, 0xdde1e500, 0x4b6b038a, 0xc1de1f3a, 0x4ba814f9,
-       0x67ade5c0, 0xa5b5fb22, 0xbefa3a72, 0x38fc31d6, 0xcbc457a7, 0xcd3e08e2,
-       0x7871b54d, 0x084cfac1, 0x472b554f, 0x9bfbf3e5, 0x0180f787, 0xf0075bd6,
-       0xe12db140, 0x64b1d9d6, 0xf8f90583, 0x1f237338, 0xa258ef9f, 0xdd788b1b,
-       0xebbec8c9, 0xf00f0f97, 0x147b4875, 0xe903b2e8, 0x5cd4eaf2, 0x71d86f1a,
-       0x7c0c758f, 0x1376861f, 0xec3b95fa, 0x4c57dc01, 0x4dcdf54e, 0xedce7845,
-       0x4a2064ab, 0xeb4dac1a, 0xfbef112d, 0x7d4177eb, 0x7e9f63a2, 0x36f3ce2c,
-       0xc2bab6c6, 0xfaa981eb, 0x6f5a1fd1, 0xa02d3e04, 0xd6e11072, 0xfbf5e469,
-       0xcf8a3316, 0x8cfbe834, 0xf7f41df8, 0xa3cfa22c, 0x2fc414ba, 0x6ed09bee,
-       0x737bd3ae, 0x67d7dc14, 0x07a8dc98, 0xf4421f60, 0x54c2c87e, 0x26fff40b,
-       0x574e513c, 0x8fd8efe9, 0x502aaaf0, 0xae242ddc, 0x60dc85da, 0xcd37dc41,
-       0x7a25629e, 0x39dd5f64, 0xbff51ab4, 0xfa09e395, 0xcc7e8b31, 0xff30a2e6,
-       0x2aef3afd, 0xfd48ffda, 0xa8514876, 0x8dd7439f, 0xb112ddde, 0x50fec22f,
-       0xaa521ffe, 0xfa40ee73, 0xb23afb17, 0x7ac2d30f, 0x2295ed17, 0xfdde245b,
-       0x3ca17e62, 0x7b48a3a4, 0x7ed3ed14, 0xb1dfd67b, 0xd9c83a65, 0x823a33f1,
-       0xd152073a, 0x01ff33f3, 0xf60551d6, 0x70e005ac, 0x33972a5b, 0xfafdf287,
-       0x30df9c44, 0x3abc3f58, 0xd31be09c, 0x938f0b64, 0xe90ffc2e, 0x482fee46,
-       0xbfcfe04f, 0xe73b72a7, 0x1e5c6927, 0x978d21fe, 0xfb6313d3, 0xf510be2b,
-       0x1f971354, 0xfcb9cb5b, 0x41b7ae8f, 0xedadfbf4, 0x668a31de, 0xef760f7f,
-       0xf76e5486, 0x885fb91a, 0x0a9613c7, 0x873b06fa, 0xabb614f0, 0xda503c78,
-       0xccf45fa1, 0xf372f2a3, 0xbfe8d97b, 0xe69fedbf, 0xb6f487dd, 0xf27a37f2,
-       0xf1149c57, 0xbec99582, 0xbfdc64f4, 0xabf6c427, 0x75d6273c, 0x1f9199ba,
-       0x1b8c53f8, 0x893dec82, 0xaf284371, 0x34e0f9da, 0x2cd5bfe4, 0xe5e0fe40,
-       0x5c51373b, 0x61407970, 0x69f7052e, 0x1627ee5e, 0x47bd58f8, 0xdf4bf1af,
-       0x931936ae, 0x77e984c7, 0x6e369b45, 0x58abb358, 0xf6f6fe53, 0x440b2569,
-       0xfcb0a1c8, 0xa3ef4699, 0x1ef495fb, 0xd47ea76d, 0xc3f8d2ec, 0x461cee97,
-       0x97f597eb, 0x77ad3731, 0x66816b59, 0xf395acde, 0x49f9bc49, 0xd4bb45ba,
-       0x469e731f, 0x008ffbcd, 0xff08fefe, 0x4353d2ff, 0xa92d1e69, 0xba40ffbe,
-       0xcac3cf09, 0xdabf1afc, 0xb027c724, 0x7ee16656, 0xff23a049, 0x5081ece5,
-       0x6fffa72a, 0x71d1f70f, 0xfee305f6, 0xca0beebf, 0xcc397126, 0x0c3614da,
-       0x6aa7e31e, 0xa0bfb4ed, 0xa7c52bbe, 0x616beb95, 0xa45f2d47, 0xd45177ad,
-       0x5dea28bb, 0x6912bfc9, 0x2805299f, 0x0d7f78d7, 0xcff38f82, 0xa0ba351c,
-       0x6e34f8de, 0x3d3916c7, 0x6cef5097, 0x438e24b3, 0x4b36ca7f, 0x52f5005e,
-       0x38bafaff, 0x48336d1d, 0x033b8a3f, 0x5ffed6e1, 0x88a8b677, 0x0fb07dc7,
-       0xfe587900, 0x8a1641e8, 0xae375390, 0x01cb3c53, 0xef2176de, 0x7d7cdcea,
-       0x71a0ee75, 0x5d93f428, 0xd395e7c7, 0x23515fb1, 0x08d4e5da, 0x419a5f7f,
-       0xc1cccfb3, 0x8d254e32, 0x9a9ce3cb, 0xea1432a0, 0xa3daef65, 0x875fd8a8,
-       0xbb337a42, 0x41130009, 0xdc25d957, 0xa4b1b9be, 0x2636595d, 0x5d56870c,
-       0xe00718f5, 0xeadd35a7, 0x8f737d46, 0x0d2437d3, 0x182279e7, 0xf8fcedc4,
-       0xda2a3d13, 0x7a753fef, 0x619cd20a, 0x8ef4b838, 0xd6a7d46c, 0x6d9e7c13,
-       0xae63fbfd, 0x4da22867, 0xdcddabfe, 0x23b3d19e, 0xa487db8c, 0x8c37d2af,
-       0xe727bd24, 0xf4229e97, 0x3df33a45, 0xadfaa367, 0x68c9f08c, 0x861be93d,
-       0x2cf6e6ef, 0x815577c7, 0xafbe0f77, 0xa8aab8ca, 0x6c17de05, 0xa14baa0b,
-       0x62bbcbdd, 0x85cb83fb, 0x4c75813e, 0x75c9f5c2, 0xc82e495c, 0x7e38867a,
-       0xd60fc90a, 0x1ff7b119, 0x2f7d2230, 0x216d347f, 0xa36eb7ce, 0x30949991,
-       0xf4ea7ffc, 0x64f9c6ce, 0x082bb477, 0x93dfe91b, 0x1dff4ae3, 0xfcfe477e,
-       0x96f928c8, 0xfe5c5fd3, 0x2cf7a75f, 0x1b67948f, 0x6927848d, 0xc7e7873f,
-       0x69d5fded, 0xeabecf5c, 0xf9c12ef4, 0x276d7434, 0x3daacf7f, 0xf9631a1f,
-       0xe2f9a3ab, 0x6a54704a, 0x6ea0bef8, 0xeb8039be, 0x25547f2f, 0x68dda83a,
-       0xdd5938a4, 0x9fb8fb33, 0x46e61ee7, 0xb1d75139, 0xe30e594f, 0x4fb33ed6,
-       0xd7011159, 0x05017541, 0x2ec233e7, 0xafcb90f9, 0x3f47ba68, 0x872dda32,
-       0x9c4e5c2d, 0x15f9b72d, 0x8359eb80, 0x9deb0eaf, 0xfdbab2cd, 0xbc3c61f9,
-       0x11fa6fb9, 0x3fb037cc, 0xb3e20a67, 0xd33bb755, 0x475af50c, 0x5f48dd19,
-       0x36fa753f, 0x54525c23, 0x4fb6276f, 0xd7bbb34e, 0x89975b43, 0xfbbca115,
-       0x1f1870ba, 0xefe32745, 0x85d3fce1, 0x91db8872, 0x813fc845, 0xa7b4bb34,
-       0x361dae48, 0xc73c75f0, 0x9eff7cf8, 0xe89079ea, 0x8d0a48f8, 0x54175d9b,
-       0x7f9d9fd0, 0x6b9239e6, 0x9d30ffb2, 0xe4891e79, 0xb3cf2bdf, 0x56f488c3,
-       0xf950e42b, 0x8f947ba3, 0x4bfde623, 0x6e91f430, 0xba019fb2, 0xfdf7d1b4,
-       0x3ea8d333, 0xbdf0b933, 0xe16aed42, 0x79088afb, 0x4311d723, 0xf5c3ecee,
-       0x1cf44ed8, 0xc82772e4, 0xbe628dfd, 0x157cf8d1, 0x9a7c1fe5, 0xde99ea06,
-       0x3123fd1b, 0x48787a2e, 0xe527f502, 0xbedf3440, 0xe51ce82a, 0xfe46cea5,
-       0xe52bb25a, 0x22bd64fc, 0x34fec567, 0xc10f4382, 0x4a977ea1, 0x7a32a9eb,
-       0xc111de87, 0xfd16bf0f, 0x03f9b81d, 0x07fdca23, 0xa25dfdfe, 0x8536fac7,
-       0xedacf1e2, 0xd43ce35d, 0xf4a7fe47, 0xe2ce6768, 0xf1db0126, 0xa784bbc2,
-       0x2e5c9d59, 0x53ee77d7, 0x74c2d997, 0xc0e67f9a, 0xf56748ad, 0xfb86261d,
-       0xdfbfa022, 0xe9a27c20, 0xca47c254, 0xb4f878dd, 0x9472e0ce, 0x47e48df9,
-       0x3e54fd85, 0xdca429fa, 0x4eaa7bfe, 0xfbf809f8, 0x1cbc690b, 0xa7df1fa6,
-       0xdcb08f08, 0xe45f10b5, 0x603a299f, 0x5bb87dc6, 0x5a7f3f21, 0xe4678725,
-       0xc6c7aabc, 0x54ce9b97, 0x50d437a1, 0x587b1cde, 0x7fcbf7be, 0x810bfed1,
-       0xe41f786f, 0xd410d9ef, 0xd1fe72f3, 0x7277cbf8, 0xce831b7d, 0x11d71bfe,
-       0x3da4dfad, 0xc9e6e920, 0x8f46aa5d, 0xea469dd8, 0x731b0ecf, 0x728ec79c,
-       0x61d8cf1e, 0xc76cfae0, 0xe500737a, 0x780b9bc9, 0xa17d995e, 0x43cf8831,
-       0xf875a5ba, 0x1f3650fd, 0x5ba755bf, 0x0dd6e583, 0x7842d636, 0x4b3a24f5,
-       0x19127e91, 0x1e5c8f97, 0x973cf03e, 0x5b7e7567, 0xeb3fc180, 0x5397737c,
-       0xe2cd39dc, 0xf333b8c6, 0xb3ce341d, 0xd72ba40f, 0x2e8dfb73, 0x83ab3f78,
-       0x03c49ff3, 0x2fa253c8, 0xae120fc9, 0xb8727861, 0xf8927e4b, 0x67f4bbf8,
-       0xa77cbd03, 0xda3daabc, 0x46dbdc78, 0xbe4ed5df, 0x706c3acf, 0xc7869fa1,
-       0x6fd1e217, 0xb3b7baed, 0xb51d824f, 0x7a2df33a, 0xfd85be4a, 0x27bf86ac,
-       0x3817bc09, 0x74afbeb9, 0x2da9ba72, 0xacbe20e9, 0xfc44d93d, 0xe5c19b6c,
-       0x5684ed9a, 0xcff6331e, 0xa8dbbd62, 0x63b5955d, 0x5477e61a, 0x7038ae3d,
-       0x6e4f1fbf, 0xfcf0aede, 0xbd774fb8, 0x72f98891, 0xf2b02bec, 0xe1629e31,
-       0xe4eb9deb, 0x5eece272, 0x7bd13800, 0xf672f193, 0x63fa95fb, 0xc20a63c1,
-       0xfac056b3, 0x139533ec, 0xec7e84ff, 0x61ee49bd, 0x9ecfe4b0, 0x3feee9b9,
-       0xeecfbcc1, 0xf746e299, 0x978b5a65, 0x69cfa7e8, 0x037ee371, 0xf40cf7c4,
-       0x78efae17, 0x685af123, 0xabe9fa77, 0xd76e508b, 0x799e798a, 0xe10ebf5e,
-       0x7fc9e1b2, 0x6bdf8c9b, 0x09aa4a03, 0xf8fbd9c7, 0xbe63677f, 0xf2469eea,
-       0xfd3cb517, 0x17f311ba, 0xfe768174, 0x03926f7e, 0xf9fe9deb, 0xef08c9f6,
-       0xfa168e96, 0xede7e67e, 0xe4f03e54, 0x77f6bdbf, 0x1378e3f4, 0xccef58dd,
-       0x2f09fbf3, 0xf2953e75, 0xf5d1e2db, 0xb9fb7d8e, 0x8f3d44bc, 0xcb9f307c,
-       0x92d74931, 0x793f4f7e, 0xbd48c4db, 0x0ab7df21, 0x026b4e7f, 0x099f23d7,
-       0xe0adadfe, 0x9ecfcef1, 0xfda7ccb5, 0x1c343181, 0x6375c5f7, 0x2ddc5d38,
-       0x71d751e0, 0x46c1a187, 0xdf9fa9ed, 0x73e3df02, 0x27e7d02c, 0x64852923,
-       0xd7ca25cf, 0x0faa57f9, 0xbfa026f5, 0x1f45e6e7, 0xeb1f382a, 0x2d432698,
-       0xfe69f3cd, 0xf91d561d, 0x6c6d6cbd, 0x38bffb3f, 0xe02ec26d, 0x59dd907c,
-       0x3922e39d, 0x8b0f7260, 0x6bb387b0, 0x27182d7c, 0xcfad7ebe, 0xbe3c07ad,
-       0xb4e8ea7c, 0x727e5041, 0xf84c52a4, 0xcf5c2bd7, 0x4e346df9, 0x81c1fa3d,
-       0x3e0b768f, 0xf5307749, 0xdc03921a, 0x32a5501f, 0xaa7e46d5, 0xf513923e,
-       0xee0f42ad, 0x736e7e11, 0x764dde5f, 0x26bb676a, 0xed061f62, 0xf72a366c,
-       0xf310fde5, 0xe7f8674a, 0x1971de93, 0xa467be69, 0xf27e603c, 0x8b7e4a7b,
-       0xbca11bf6, 0x57d1fcc1, 0x285de59d, 0x3d33e51f, 0xefe4bf8e, 0x74b8fbe2,
-       0x15ca174f, 0xa35537b6, 0x95c9e20f, 0xe79f3703, 0x0f95fb7a, 0x901b0e89,
-       0xdf7c710e, 0x5ede8d49, 0xe815c24e, 0x890fa5f0, 0x7177970e, 0x55d0daf9,
-       0xd4fdc46e, 0x69d7e10e, 0x7484f410, 0xbfe8fb84, 0x9c69933a, 0xe1a1c986,
-       0x0bcea728, 0x12ff3bba, 0x3a43b7a7, 0x0e01f91d, 0xdedd1eed, 0x8fd40ca2,
-       0xf0978d4a, 0xe6f800dd, 0xa3daf376, 0xd7d56768, 0x6bf23730, 0x07e0a743,
-       0xbe117bb0, 0xcbd55d0d, 0x6941bfb1, 0x0ddfc933, 0x41b4c976, 0x63a86e50,
-       0xd96fc8a5, 0x425e2abb, 0x7c5d60ba, 0x035d9e3f, 0x4dd22cf6, 0x9f5bbd5a,
-       0xdb8f7a8f, 0x2c8fd7bd, 0x723bf6a3, 0xf2e7145d, 0xf38a3157, 0x19fb40ef,
-       0x68d65df5, 0x36fb3f6e, 0x5cc5dd92, 0x6537e409, 0xd60d753e, 0x622ff06f,
-       0xcd11d794, 0xb4292fc7, 0x5808680f, 0x56681f29, 0x1a7fb717, 0x9f1f38ba,
-       0x4f91f093, 0xe4adcf43, 0xc4c17f8f, 0xd0fe11fc, 0xce9a5f37, 0x268becf5,
-       0x359fb3d2, 0xb0c7d87b, 0xbc85b7a0, 0x6dac7097, 0xdd21d7cb, 0x09937632,
-       0xcc4cb1e7, 0xf5c0cda3, 0x03d0b246, 0x3cf8db05, 0x77e174d4, 0xa789d74c,
-       0xe2e79b51, 0xe17f93f0, 0xc88f189c, 0x39e85d22, 0x797eba18, 0xeea4f890,
-       0x9a5fde19, 0x677853c9, 0xfb4abd04, 0x0b1e9a28, 0xbbd9b8c4, 0x4c282a0e,
-       0xd1cd77b2, 0x35f5f9f0, 0xeb08d82c, 0x2e977ebc, 0xd91c6538, 0x9e490b4d,
-       0x58b237af, 0xd2232af9, 0x9556fdb9, 0xbf442dea, 0x36cdd576, 0xb93fa477,
-       0xb3a3c12a, 0x24571da0, 0x12ded8fd, 0x4a9d1b8c, 0x6f11bbb7, 0xd25dd2e3,
-       0x5bd8d30e, 0xdcdff703, 0xcda1bc0e, 0x1ff70e3f, 0xf309f581, 0xda09ae29,
-       0x0edcfc8d, 0xf7fb8f68, 0x9cfed7dd, 0xb85bdfef, 0x070402ff, 0x6f5499c9,
-       0x9d8ffa09, 0x5cb5de05, 0xb1ddd93f, 0x93aaf3d6, 0xcdc0e7af, 0x3ee216b7,
-       0x8dae61b1, 0x5781e1f8, 0xde9ca594, 0xbee21140, 0x83f9c7da, 0xe13c7f01,
-       0x3b247a22, 0x1bc9a1aa, 0x9c8f4d88, 0xaec01a5f, 0xe81b3b42, 0x93b70d71,
-       0x13f38c6d, 0xbfb94ba7, 0x6915b947, 0x8d3e4acf, 0xbf497be6, 0x35ff7cfd,
-       0x81bcfdf9, 0x8079e3f3, 0x3f7bd203, 0xe9ccbf9d, 0xe07aeb7c, 0x15bef847,
-       0x4225b1f8, 0x7fef47fe, 0x1fb89e70, 0x1ef6f290, 0x3a5177a7, 0x6fdda1ca,
-       0xab50c66d, 0x2f0d8f94, 0x397e196f, 0x958ccbbb, 0xf0335fa1, 0x60fd246b,
-       0x445ed68c, 0x09ea3f4f, 0xfed8baeb, 0x6dd2bb8f, 0x3f3fcddf, 0xaee52f30,
-       0x7981d2f4, 0x73a8e929, 0xadbb6f10, 0xa58fb401, 0x3e7a291f, 0x499f044b,
-       0x03fdca7c, 0xfeb021c6, 0x37ef82fd, 0x888f7a89, 0x84bec467, 0xf3a5c1f8,
-       0xf679487d, 0x6c91f471, 0xb5f97df7, 0x2f5238e4, 0x8c8dd346, 0xaa7ae0a3,
-       0xd7afc4c7, 0xcfec5fb6, 0x29f8e8a2, 0x800b5fc1, 0x6dde7037, 0xc417e086,
-       0x19d8778f, 0x99f813e5, 0x71e31527, 0x7ce08daf, 0x386fb234, 0xfa66b7b6,
-       0x92ba44be, 0x8f7c5d7e, 0x115aaa71, 0x6bddacbf, 0x7f9e4408, 0xd18337b9,
-       0xb376bd38, 0x91fc0f5f, 0x87dbe99b, 0xcc15fded, 0xf33d441d, 0x2b8a168f,
-       0x8a5b8181, 0x8591a6f2, 0xefce1112, 0x205efb25, 0x0cf7d5fa, 0x39e3bf47,
-       0xdf0e3425, 0xdafe109f, 0xfb5fc213, 0xcf7bd77e, 0x17ad02be, 0xf16e72bf,
-       0x5ece918f, 0x7d21e4b4, 0xe7f4b09c, 0xdda125bf, 0x92b9817d, 0x690e772e,
-       0x55ef5991, 0x2767fc23, 0x7ffdb1ec, 0x373c0b6f, 0x532b788a, 0xb7c3ed19,
-       0x19f97067, 0xe3c4bf3e, 0xb4ebefad, 0x1cf937fe, 0xdfe1c193, 0x501ce719,
-       0xd7df0661, 0xfce10e74, 0x50aed7d8, 0xdd66afbc, 0x41eb3ffa, 0xb5acd42e,
-       0x9f09e907, 0x71ab8ed1, 0x283a83f8, 0xb970309f, 0xcd737f04, 0x07fd6165,
-       0xc849d4f5, 0xc5077e33, 0xfd0a96bf, 0xcde9acb5, 0xa15fa1bf, 0x49e66546,
-       0xf2c71845, 0x9f041e1e, 0x4f2db53e, 0xf2bff144, 0xa3a67747, 0xd458ca7e,
-       0xa6c1f226, 0x55fed03a, 0x2fe8373c, 0x6f672f59, 0x132764a9, 0x1ede001d,
-       0x22f6f0cc, 0xe24a2f1f, 0x7745c17e, 0x08fe035a, 0xf057b879, 0x7cfd3461,
-       0xcdbce710, 0x01151997, 0xaa616fec, 0xefd46ff7, 0x7234e79d, 0xfa12bced,
-       0x5f4823c5, 0x4fddd877, 0x22f2eef0, 0x05d263f3, 0x0e316bfc, 0xb7b1a204,
-       0xbaf867b0, 0xbee3a47c, 0x5fa1dfbc, 0xf0e4dbab, 0x91bbf0bb, 0xf176cbbe,
-       0xe3f141e2, 0xd2232e40, 0x8545c347, 0xf76961e8, 0xae51c79b, 0xa221a837,
-       0x1b66a593, 0xa2e1b1e1, 0xd5a9e9ca, 0xdb243670, 0xa4d7ee03, 0x6032d27a,
-       0x277bfe9e, 0x093c5325, 0x17c389f8, 0xe39c452a, 0x37c332f8, 0xf7e00328,
-       0x36f13590, 0x305d7fdc, 0x8f3092bb, 0xf408d1ad, 0xe7753570, 0x43d84735,
-       0xa5aec72c, 0xfeb7ee83, 0x6e5af386, 0xaf5119f6, 0xd134f0af, 0x4945b179,
-       0x98c752c1, 0xd24fbc48, 0xf5fd1a5f, 0xc8497ef1, 0x3c8df797, 0x9d20646f,
-       0xcf6c3c73, 0x39b2f510, 0xc79fbcbf, 0xe7c39e6a, 0xbb427828, 0x728887f7,
-       0x170f2891, 0x7979d2f5, 0xf797e09a, 0xd17af1c7, 0xe3152ce3, 0x99e1997c,
-       0x7682708c, 0xc7d22341, 0x673a166b, 0xfe404ac4, 0x935bbca1, 0xc82c764b,
-       0x770869b9, 0x4c982718, 0x67a44cf5, 0x41c81358, 0xa96f67c0, 0xb5b3e08b,
-       0xe305e81c, 0x289aaf41, 0x2bf1241e, 0xcf8d1af1, 0x77ca1985, 0x181f4fcb,
-       0x51985ebf, 0xcd7e303a, 0x17c250d8, 0xf38c4bd1, 0xf5f0f11f, 0x03c73b6b,
-       0x0cf2ebf0, 0xb1c183d2, 0x49b37c91, 0xb5ca51c0, 0x78b413f7, 0xe39d3cfd,
-       0xbbd45ea1, 0xda1f7684, 0xe23eeed1, 0x7853f7bf, 0xae02b4fd, 0xfe5da497,
-       0x5f2e024f, 0x529f6ba6, 0xd1fb44cf, 0xe2f214bf, 0x47ee74cb, 0x8ddebc07,
-       0x09fa95f3, 0x19304ce4, 0xebd178f8, 0x6c339226, 0xd5e51f63, 0x83ffbd40,
-       0xea645af0, 0xf41535bb, 0xdec10fca, 0xbb511631, 0x0647284b, 0x48c7efec,
-       0xd433b0ba, 0x0e19addb, 0xf4941f6e, 0x48d7b8f1, 0x0ca5aebe, 0x657287e4,
-       0x210c63fc, 0x6bf0e40b, 0xc142bf22, 0x6214aebc, 0x07f61767, 0x8c97ff70,
-       0xa3dc30d2, 0xe8213bc7, 0x450cd1e0, 0xb215bc25, 0xaddbc442, 0x5f6e7eef,
-       0x139e5d0c, 0x4d9365e7, 0xe7ec76be, 0x916fddec, 0x18c27e9d, 0x8b66de1c,
-       0x7c18ddf1, 0xfc2521ec, 0xf4a7b6fd, 0x98d5e37e, 0xc1f67e7f, 0x4bdd619b,
-       0x1c6ef47b, 0x5f3de972, 0xed1e33bc, 0xc5031eec, 0x6fdf406b, 0x4dde7153,
-       0xa13caedc, 0x67c1d2d3, 0x3df76977, 0x907a0baf, 0xdca572e7, 0x157cfa91,
-       0x93797373, 0xcb1bb890, 0x3b71dd1f, 0xce5dcb9d, 0x003d87bc, 0x666bd3f7,
-       0x3b7c5d92, 0xcf5e51f3, 0x39ed56b2, 0xda6d15db, 0x073bedf2, 0x3925c39c,
-       0xfd102abc, 0x2ba5f85e, 0xf3fbeb63, 0x333f2e82, 0x7afdf88a, 0xfdf8cc53,
-       0x09fc85ef, 0xb4fbd9c7, 0x2f57fbf1, 0x8c6fbf1f, 0xed87df8a, 0x3df8e888,
-       0x6113f7ef, 0x91bf606f, 0x2acffc71, 0xa3e3af62, 0x58b7690c, 0x9f19f935,
-       0x125bb00c, 0x45e37be9, 0xd8f99c4b, 0x2b67fde8, 0xd7d38f63, 0x5f368e3f,
-       0xe79edc20, 0xb5fdc809, 0x8bc693a4, 0x6567a459, 0xe1c7da59, 0x3df43976,
-       0xf4babcfa, 0xf8be4b6f, 0x2ce66158, 0x176d47f2, 0xf29bbc76, 0xbb463f33,
-       0xba72f908, 0x4c10b5eb, 0x278fd971, 0x8487570e, 0x1d7a26f9, 0x42675f40,
-       0x98d8f211, 0xfd234f69, 0x3a6e66eb, 0xfee82797, 0xe8abbbd6, 0xbdffcf7c,
-       0x322332a7, 0x53f72a6e, 0x8f69460d, 0x96fa34d9, 0x65e3e945, 0x1d916f5d,
-       0x70d7f606, 0x7a7f3e14, 0xc3d26ef5, 0x1d37992b, 0xd5f7bde9, 0xe56e7411,
-       0x3961eadb, 0x4bfc9b9f, 0x35bf3c0c, 0x3987ec8d, 0x75373e62, 0x67503b73,
-       0x1c6818f6, 0xd239730f, 0xe7cd8b69, 0x8554420b, 0xf3fd75f2, 0x631de747,
-       0x15fcc493, 0xbdf00f6c, 0x52d93c4e, 0xdbce265f, 0x31eae384, 0x8990260d,
-       0x6e8996cf, 0x28a73e17, 0x83cf955e, 0x6b1a79e3, 0x3afac1ca, 0xd7cf4873,
-       0xc7483309, 0xa2f0fdf6, 0x37945db2, 0xeb70bdce, 0xb36f7c0a, 0x8a313c93,
-       0x04cf4c79, 0x6dfc88b9, 0xb75c6666, 0x4d3c16c9, 0xf4f133f1, 0x8f88b857,
-       0xf91843fd, 0x07581241, 0xd9b53f9d, 0xb171f9ce, 0xb050e60e, 0x085c716c,
-       0x9ce27ee2, 0xf3c7e6c3, 0x672f20c4, 0x5f3fa265, 0xc44ad5f9, 0xee67c80b,
-       0x5df78a17, 0x11f3f20d, 0x88a5de42, 0x7908b5f9, 0x8adcc597, 0xe480c7b8,
-       0x95f6fddd, 0x267ee037, 0xa3f7798d, 0x71387bbc, 0x32fdc506, 0x93e68f98,
-       0xc8d5433a, 0x5b57a72d, 0x46af98ce, 0xe7053bcb, 0xbed3e597, 0x9413b337,
-       0xbd04a497, 0x69529799, 0xfd12361f, 0x37210631, 0x3e78598e, 0xcf3166c2,
-       0x8853333b, 0x78598e6e, 0xb6b7c25e, 0x7ddadc5b, 0x3f0a437d, 0xdd3e7fbf,
-       0xc0f1c66c, 0xe113b98e, 0x07cc7607, 0xdfce167e, 0x41d29c2c, 0x6f9b0279,
-       0xe01bdc54, 0x6bbb66fd, 0xeba40abd, 0x7f70a99f, 0xc728ea8f, 0x3cf69c7c,
-       0x44f31b87, 0xf7be451b, 0xf6a38b66, 0x9a63f219, 0xb7d63d78, 0xed96e319,
-       0xac0e1d5b, 0x37d95697, 0xaafb88cd, 0x9bb1cc15, 0xaff7a0c5, 0xbe608f80,
-       0xe032c73f, 0x63f41149, 0x85bae23d, 0xefbe20d6, 0xf0177fc1, 0xdc3294f2,
-       0x82bff2bf, 0x773a42ee, 0xd27a3cc9, 0x85dd8d97, 0xbc60d86f, 0xe485b982,
-       0xf256f7af, 0x72132fb8, 0x571cbc60, 0x61b5d9f0, 0x85efa7ba, 0x5bb43ca2,
-       0x4cd37ff8, 0x80ebae3c, 0x91c4ca21, 0xc69fac43, 0xe4cdc1f9, 0x6bd3e71f,
-       0xfb0ff858, 0x4ff70cab, 0xf86a6972, 0x60ef9873, 0xbbb322a8, 0x8dea0ea5,
-       0x91fb8357, 0xcf15afaf, 0x543cf142, 0xe5e9237e, 0x65cd9d1e, 0x373e71d4,
-       0xc3aba017, 0x94b847ab, 0x60b4b639, 0x4129d73f, 0xd8cde67a, 0x9fd382de,
-       0xc94cfc23, 0x9e00c699, 0x00996b37, 0xc8bf2678, 0xffa30f9f, 0xac2fff5a,
-       0xcc74f118, 0x279ef520, 0xb9ffe789, 0x0ed53d68, 0xce97593e, 0xc22e7b33,
-       0xcf3f28f9, 0x8b74d0c6, 0xa997fef8, 0xd7974955, 0x300f3cbb, 0xe5cf4b25,
-       0x871e0ce3, 0xa66f9c6d, 0x7146e5bc, 0x7d53030f, 0xf08c3ff9, 0xc5b8c8af,
-       0x7f3606bb, 0x46fd8c5f, 0x07b7164a, 0xfdc0dce6, 0x1f228dc2, 0xcc4f7e47,
-       0xbfb27ee2, 0x377b4e64, 0x1e3dec93, 0x949dfd6f, 0x48d9235f, 0xf2115f94,
-       0x5f248fe5, 0x278edfca, 0x85dfb47f, 0x29e799fc, 0x40bed036, 0xef2921c8,
-       0x68ef22bd, 0x1018f301, 0x1ee23d4f, 0xabe5a395, 0xccdd0e48, 0xf7fef47c,
-       0x00ff3c15, 0xfd80d308, 0x6b4334dd, 0x6af3cd3f, 0x8fcf37cb, 0x3e38afb6,
-       0x7c0bb8e4, 0xa473efda, 0x6b433c9d, 0x87fa2f27, 0xcf4992af, 0xfea2fc67,
-       0x3e70e0d2, 0x3e546351, 0x27c88351, 0x3c2aec6a, 0x4f911694, 0xf3cdd8d4,
-       0xaeba1a89, 0xedc44f94, 0xb029af29, 0xde24e31f, 0xec94d25a, 0x727f910d,
-       0x8a4ff310, 0xaf6e74c2, 0x0c3cf3b0, 0xa2bca1e6, 0xce95871c, 0x8aeab45d,
-       0x9adb8fc8, 0xddf8d768, 0x5577aeb7, 0xbfe93d61, 0x4843f995, 0xc3f6b137,
-       0x5f7c59d9, 0x7ee143b3, 0x3302ff74, 0x059d3bed, 0xc15c4d5e, 0xd1c767a9,
-       0xa66ef8af, 0x3f27d64b, 0x2f830ec9, 0x019e18ab, 0x8979d185, 0xb67af6fe,
-       0x5190fc91, 0xea99ca72, 0x338038a6, 0xf5f92c69, 0x921775e7, 0x2cd9923f,
-       0xb84a61ee, 0xdb7379ff, 0x69ebcc55, 0x97576eec, 0x3774c2db, 0x43ec4b36,
-       0xf48accac, 0x7bd7efda, 0xbd7e44ce, 0x30b79364, 0x19d7da0b, 0x8bbfe483,
-       0x1f7a57a0, 0x2ede5f4f, 0xe150c5e8, 0xe602b05d, 0xd18efbd7, 0x0a6bfb8d,
-       0xcfff41cc, 0x7e4c94bf, 0x230e7549, 0x9cb1b53d, 0xf45e93cb, 0x3e3ac193,
-       0xfaf7e64d, 0xa466ac6c, 0x4ca7cf5f, 0xc55e3a23, 0xe83d8702, 0x7405db47,
-       0xd2cf7918, 0x8eb96d1e, 0xa9fe9075, 0x3d00667b, 0xf2947c93, 0xf4b99eb8,
-       0x741b8c06, 0xa1b3db6a, 0x285c395a, 0xbcf147f4, 0xff982da9, 0xf2e3ac50,
-       0x0f772d91, 0xf5fb439a, 0x2c4f8e45, 0xa17f7228, 0xebaece5c, 0x73d29fb5,
-       0xa17ae7fe, 0xad1ff454, 0x3d854abf, 0x17e41937, 0x7da56fee, 0x7ca9f506,
-       0xcfadd750, 0x59e785d4, 0xbb49da22, 0x890bea50, 0x8c09f2af, 0xbbb579e1,
-       0x1a7c84b2, 0xbe2086c2, 0x13e27fa1, 0x29583705, 0xf71fbfd4, 0xf18ad785,
-       0xa8fc1e80, 0x733afdbf, 0xb36be900, 0xd2fa44d2, 0x3c3ff68c, 0xd23e2ab7,
-       0xe35eff0b, 0x4c7d23d7, 0xdd374d64, 0x9926f500, 0xb728ac7b, 0x31fe4e80,
-       0x585a7e92, 0xa29f6f30, 0x7efa23a1, 0x98edf936, 0x5af52474, 0x9edcf7f0,
-       0x74bcc599, 0x0fe793cf, 0xa83aeedc, 0xd8267df0, 0xeed1079f, 0x93375b7a,
-       0x2c2664e8, 0x3955eb03, 0x9e9ff8b4, 0xdf472da9, 0x5ad0c50f, 0x48744328,
-       0x9c540678, 0x51bdf44f, 0x98f7291e, 0xb3e5ee56, 0xf8de78af, 0x423fc396,
-       0x1d7583ff, 0x0ef6891b, 0x8fc4aa58, 0x27b0f4d1, 0xb78f7beb, 0x118ac9ec,
-       0x7e15e96f, 0x68586be5, 0x40ca33e5, 0x687f3b7a, 0x82333e9d, 0xbc7f252e,
-       0x1379e06c, 0xae3cebca, 0xc6ccc135, 0x252e1104, 0xf928ffdc, 0xd3a41ae3,
-       0x95fd3094, 0xa487f789, 0x06cc197c, 0xd75dbd23, 0x01ea0965, 0xbfa2853f,
-       0x8afe906b, 0xdc89f6c2, 0x184cb477, 0x98f96740, 0x4cf60e17, 0xb495d201,
-       0x8e958a4f, 0xfde73c16, 0xb6f74bfc, 0xe8237ce0, 0xc3842dea, 0x8ae80559,
-       0xf4036afc, 0x147bf6ad, 0x4bfc49dd, 0x359cba7b, 0x6e677ed1, 0xc1b3d702,
-       0xcf49dbea, 0xba24b882, 0xa70e737b, 0x21e62abb, 0x5a672bba, 0x6b34a97a,
-       0x0974d1cb, 0x74b4ea23, 0x8bba23e7, 0x7478d7a6, 0x4ee91837, 0x2bd4dbea,
-       0x48e7ddd3, 0x8fc5df77, 0x3eee9039, 0xa7c672cf, 0x937a68bb, 0xc59f6cf2,
-       0x75768951, 0xfa428d63, 0xa19df8a1, 0x511e582d, 0xf6764f9f, 0xd93764be,
-       0xfc4d8ddd, 0x478f497b, 0x0533798f, 0x7cf7c56b, 0x1b96256f, 0xe877c1d7,
-       0xcf18f4ba, 0x0f7a19ab, 0xa1b85eff, 0xbfbc0de9, 0xdbcfd1a0, 0x337a7cbf,
-       0x6c0a879d, 0xdbcbed16, 0xd8dcb12a, 0x8a7fdbca, 0x31abae71, 0x82d02dbf,
-       0x96daafef, 0x6fdbe6ef, 0x114fd76e, 0x3ca7ddeb, 0x6bb506f7, 0x3f6eede3,
-       0xe4604e6c, 0xfaf6e027, 0x29ceb164, 0xd33af8bb, 0x867ebe3e, 0x4563e80b,
-       0xb9ec9f9f, 0x6575744f, 0xece2ef24, 0xb695cbb3, 0x474e7c1c, 0xbc47a639,
-       0x43f55bbb, 0x37741c78, 0x3675710c, 0xf8c8d3f7, 0x5429e621, 0x5717d847,
-       0x443b7367, 0x614f4bd6, 0xfd8d7e74, 0x72fe4ecc, 0x3e0cdf19, 0x07d414c4,
-       0x976146b8, 0x4e778cc4, 0xbb22682f, 0x1960fa62, 0x4ba90ce7, 0x4bc2dc61,
-       0xe58b4f9f, 0xe6cb2a47, 0x9129f3f6, 0xd7df2177, 0x4875f204, 0x4890fb17,
-       0x90f0fce8, 0xdb9ed077, 0xe734cc97, 0xf3e5f6dc, 0xbcecd4f2, 0x01cd6e7f,
-       0x549aeaf8, 0xe58bf7bc, 0xf2b79429, 0x4c161e83, 0xff381c4a, 0x1a0b2ae9,
-       0xcf8a0f29, 0x518b657f, 0xe5c257dc, 0x3f813cda, 0xd1186936, 0xa7815cef,
-       0x17a16cea, 0xca31598b, 0x6f0279a9, 0x1937343f, 0x336ebeb8, 0x798fc944,
-       0x1e3f28d9, 0x6bcf6b8e, 0x97c947bf, 0x4aee311a, 0x62afc761, 0xfd3fe47d,
-       0xa7f1d844, 0xfc76e61e, 0xfe41d66a, 0x719fded3, 0x961ebe3b, 0xed12f487,
-       0xabddad07, 0x6877d72d, 0xdea00dcb, 0xaec6ffb1, 0x8633b928, 0x1f7ba5fb,
-       0x3f432fae, 0x77cecd64, 0x235dffc8, 0x2b404ce5, 0xe740c067, 0x51a1e672,
-       0xd6fabfe4, 0xd819e3f2, 0xf26995d5, 0x76c9ef4b, 0x5e77f846, 0x0d2e79e4,
-       0x7a11fb8c, 0xc16f23ed, 0xd28b2c7d, 0xa572d14f, 0xe915c850, 0x5bf290ff,
-       0xc6429bca, 0x77ec14f5, 0x9b60f1df, 0xe1ef3b28, 0xc4afa16c, 0x4dfa4dfe,
-       0x88547da4, 0xd7d211f6, 0xba2226a8, 0xbf727eb0, 0xe847d26d, 0x662505a5,
-       0x19917bc4, 0xa6e11bf8, 0xd9f58db7, 0x68f1f434, 0x83f7e5f6, 0xf451efda,
-       0x0b63f723, 0x84dcfd05, 0xff181891, 0xb81f720f, 0x5ccfd38a, 0xf4843de6,
-       0x9cd5fbf3, 0xf0bee47e, 0x3d03ef9b, 0xa07dc8fa, 0xdd7e4fdc, 0xdd3f60fd,
-       0x863ec058, 0xe95cb1e7, 0xfdf1e017, 0x45d38546, 0x3ddf9cfd, 0xf2c2c556,
-       0x733368e2, 0xb97086ab, 0x8cc9a665, 0x0316977e, 0x99cd2fdf, 0xd2d97ef5,
-       0xb413f908, 0xb8401f97, 0xf9276eb1, 0xdaadeb77, 0x3d2b3671, 0xf711fd77,
-       0xc95a8f55, 0x08e174af, 0xc2e59323, 0x0f9411ae, 0xc78199fe, 0x6e7ce55b,
-       0xb5f7bc3f, 0xb95bd410, 0xcc6296ee, 0x0255a82f, 0xb7c1d62f, 0x77beac0f,
-       0x756bbf91, 0x672f7141, 0xe427c50f, 0xbafdf1b8, 0xc6c7927e, 0xf73f5c03,
-       0xdf940929, 0x4787ef0b, 0x38fee9c6, 0xdcefcb88, 0xb807df4c, 0x5b47a91e,
-       0xf827f3fa, 0x1b30b413, 0xa7ce1294, 0x704de708, 0x985fcb7f, 0x13798ae7,
-       0x04e2231b, 0xbe663ed0, 0xcf2179db, 0x01726147, 0xba6567cc, 0x7fd717a7,
-       0x4f85c44a, 0xa9e23889, 0xfc571e44, 0xfe7d7f7b, 0x7ae20db4, 0x3b8894e8,
-       0xc6d14a9e, 0x44bd649b, 0x6cd93cf1, 0x60346ef6, 0x37799ebc, 0x3d70fe82,
-       0x7ca26a64, 0x5f1c4595, 0x6b252fbd, 0x1ac811ee, 0x106a3e54, 0xd399fbb4,
-       0xe3041fab, 0x9ed36f2c, 0xf715ea83, 0xba0af6db, 0xa7f0b5e9, 0x506b371c,
-       0xd76c28f5, 0xb3df80bb, 0x289e5fda, 0xbfea5ecb, 0xc910baf7, 0x8ff2fea3,
-       0x3a9ce242, 0xf8c893f7, 0x61f8bc40, 0xfa30bc74, 0xbc74699c, 0x37e4b17f,
-       0x245fef11, 0x6ee2d4e4, 0xd5b86f1e, 0x820f36cc, 0x6775b7ef, 0x26b8fc50,
-       0x135c3fd1, 0xbf5bf7ef, 0xa4879e51, 0x9edcdecf, 0xcff8f8fe, 0xf5e3e222,
-       0x2f5a3e22, 0x5da9d7d7, 0xcf0164df, 0x3e3e31ef, 0x60739079, 0x9f3a3c7c,
-       0x33b445e2, 0xac3c610c, 0x55b87071, 0xd12aebe9, 0x39617c4f, 0x35f73ca3,
-       0x416b2d6f, 0x2d9af23f, 0x615596e2, 0x380bd777, 0xd3975bc7, 0x8d2e63ab,
-       0xb9813ebf, 0xe593d622, 0xc994d14b, 0x33c88f92, 0xad93541d, 0x34db9f69,
-       0xf07f5344, 0xef9a51ba, 0x4d22fef9, 0x1af5a0b9, 0x6d61fd4d, 0x88f29a15,
-       0xea6bd79d, 0x4921b217, 0xa23b6fe4, 0xbb125f47, 0xf347302a, 0x85def47d,
-       0xb29ff69a, 0xa0931da6, 0x7b45a75e, 0x7bf3332f, 0x8594c67a, 0x76c7a9f3,
-       0xc3f4d52c, 0x29504a82, 0xf633df0b, 0x79a7b899, 0x878f0f79, 0x5ab5dd5c,
-       0xbead4e33, 0x1d18f08e, 0x7d622def, 0x086e37e4, 0x1b20ee28, 0xd55dff18,
-       0xaeed4ed5, 0x78c8f764, 0x2241c6c8, 0xb2cd97de, 0xd3475d39, 0xc3ec8d85,
-       0xe4f4bb0b, 0xc3642c7f, 0xf0449a1f, 0x6b80b032, 0x302efe20, 0xf0bb17ee,
-       0x798ddd8c, 0xb5bfb745, 0xca63e68c, 0xde05d2d4, 0x5eb9181f, 0x5d2d48eb,
-       0x3a5addd8, 0xa5a09a48, 0x27786883, 0xc174b47b, 0xcbbff042, 0x86753bc0,
-       0xb7fe6e96, 0xf081dce0, 0x5be186b5, 0x62d3d07c, 0xbcf1b823, 0x999f6935,
-       0x1d143d84, 0x4e7690d7, 0xbbb09070, 0x2e323f45, 0x93f159b1, 0x771fd55d,
-       0x0bcc109c, 0xd53da3e6, 0xc95fb8c4, 0x6fe5107b, 0xbd24bf0c, 0x9497e78f,
-       0xc09b9d70, 0xf32d67f5, 0x663efc92, 0x93a4fee1, 0x9fc8abd5, 0x913592b4,
-       0x9cd9fddd, 0xe8efc2e9, 0xca577aa7, 0x9f901853, 0x8b29f600, 0x06aed7f0,
-       0x1fef1a8b, 0xd2a7868a, 0x78ed04ad, 0x4b75986e, 0xfca3e07d, 0xedde0f15,
-       0x68ff89a9, 0x51e65fed, 0xb497e522, 0x1278e587, 0xc9ae529e, 0x49ac4c71,
-       0x117c899f, 0xc8d8e725, 0xd693f8e8, 0x41fd239f, 0xe3238e32, 0x9bfed14c,
-       0x55b8bb08, 0xc1d2718f, 0xce782df9, 0x21e1d8b7, 0xeb29613f, 0x4fdf05b9,
-       0xa8b47730, 0xb8bfe12e, 0x2ffbf58a, 0x2babeae2, 0xf26fb5c4, 0xf247a12b,
-       0x65b3c607, 0xff961c7c, 0xf1a11ff1, 0x8b95c524, 0xf2f398f3, 0xd3d22708,
-       0xfba6bf40, 0x8fd02bf8, 0x8a97d75e, 0x3130aaf5, 0xfdde223d, 0xf5a212a6,
-       0x367990fc, 0x6fdb9e45, 0x6ed31d60, 0xe8327f21, 0xa727bc49, 0x58bbfb93,
-       0xac3db457, 0x0759bf92, 0xafba412b, 0xde711165, 0x2a77f0fc, 0x659607eb,
-       0xec95d21e, 0x82f1a789, 0xe0a3ca72, 0xc84c53f9, 0x8cffb941, 0xf993cfb7,
-       0x4f7ef218, 0x94547799, 0x1c75f823, 0x03fd871b, 0x94e595bf, 0xf8017fa2,
-       0xc7e48953, 0xfa253cfe, 0xa31f803e, 0x31f32fd6, 0xf212f6f4, 0x5c8b2d1b,
-       0x8780d7ef, 0x9c7e5bb4, 0xc8e9e8c3, 0x3eb3d171, 0x3d6fc4e1, 0x47a4b9f8,
-       0x68da3f93, 0xfa0d0d84, 0x79145e13, 0xbb5a1d81, 0x9d1c96fd, 0xf7df1b80,
-       0xf15e095c, 0xf8f221f1, 0xaebe3e04, 0xf8f3261d, 0x0c971c24, 0x0d0afb84,
-       0x8ff7fb5c, 0x115f70fd, 0x2e12ee0b, 0x7e7b4ae7, 0xdbd2f881, 0xbc23a58f,
-       0x577aa617, 0xe3dcfd63, 0x5d144fa1, 0xfa555e78, 0x7b8794b3, 0xe74f4ba1,
-       0xe3ae1aff, 0x25e1b072, 0xf386893d, 0xb38a26dd, 0x41bd74d6, 0x66d9e176,
-       0xfc06b410, 0x72180cbd, 0x08fc65d8, 0xb78ef051, 0xd9eb924f, 0xe5f62390,
-       0xef32fd62, 0x39b9d607, 0x475e6627, 0xdfb41c3f, 0xf4aa1c05, 0x1cf09263,
-       0x92be7f59, 0x791797da, 0x3af45f5f, 0xfe78722a, 0xf7b329db, 0xc3efec3e,
-       0xd81d9c9e, 0xfbbe955f, 0x67c23670, 0xbbe742ad, 0x79f898a6, 0x5e712cdc,
-       0xc9a8426f, 0x3399e78d, 0x667df873, 0xf7a47e23, 0xfdf91c62, 0xe0a677b5,
-       0xffd93439, 0xe7474508, 0xee7b1947, 0xc12c7f83, 0x3722e6f8, 0xd8bf6fde,
-       0xba2fee24, 0x002c1acb, 0x91baf239, 0x186547df, 0x66e744d2, 0xe4f592fa,
-       0xb3d34cd7, 0x727748a9, 0xadbcf2de, 0x01f78f7c, 0x7cb15e60, 0xafa5a53f,
-       0x7bfa0d78, 0x75c83d04, 0x2beca94f, 0xe185b26e, 0xa33cf32f, 0xf82553e1,
-       0x1b43ee43, 0xd05b5ef0, 0xbccde7bf, 0x6daf7d1c, 0x5874feff, 0xf6363dff,
-       0x837eb8c8, 0x1e3493c5, 0x6bdc51f9, 0x278717fb, 0xa477df89, 0xbcf6a7bd,
-       0xbf97b7c8, 0xdeef1253, 0x51ccff9b, 0x827b97be, 0xcb85e5e2, 0x7078ffbc,
-       0x99564869, 0x739d357a, 0xdeae5ef7, 0x8fadff2b, 0x28bedfb9, 0xd3dff7be,
-       0xbcec6af9, 0xceb15ec5, 0x88617e70, 0xe7f729ce, 0x7e54be2d, 0x1a477bd9,
-       0x08d23ef0, 0xf6bcc838, 0xb48fbc06, 0xd0bf4638, 0xe576cb9f, 0xc4aa877b,
-       0x8f301abc, 0x3df23530, 0x38f0b7a7, 0x302f2269, 0xfb7c8894, 0x9d3d2ecb,
-       0x11e5ffe3, 0x31dd8cdd, 0xcb9b9de6, 0xa9ca32e1, 0x0e8d1f12, 0xe3b5fbf2,
-       0x79e793d5, 0xe8d8b9e4, 0x845675f9, 0x63f9c56e, 0xf1ac729e, 0x3f7cb91c,
-       0x99dde72b, 0xf0d1f1c2, 0x9bdf899a, 0xf27cf2aa, 0x4ad094ce, 0x168713e2,
-       0x1e04c3cf, 0xe50faf3b, 0x99b2b9d1, 0x8f10efdc, 0xfaa7261e, 0xc8be51ca,
-       0xd4caee7b, 0xc111c526, 0x87a2578f, 0x1af5dc30, 0xbb840ebc, 0x7ecbbe91,
-       0x7c151f4f, 0xdc363ccb, 0xfa112dcf, 0x5a9ec96e, 0x7ee587b2, 0x3d4ef4e9,
-       0x669c6fe5, 0xba72ae3c, 0xd0fda14d, 0xeb631f52, 0x7cad2e40, 0xaa3378a2,
-       0xb09925ae, 0x1efe1496, 0xe9661f7f, 0xbaf8a8c6, 0xbd495fd8, 0xbe5fc72a,
-       0xd7176b4d, 0x467f6db0, 0x51f4e9fb, 0xb0563f2e, 0x2b3fd226, 0x57f6d01f,
-       0xa7d667b3, 0xbce8cf38, 0x8fc21180, 0xec572d37, 0x1958ca57, 0x4f358fea,
-       0x9fc46e7c, 0x17c78960, 0x434ffbf8, 0x7ddff187, 0x8efe27c2, 0xc96f3e08,
-       0x1720fcf5, 0xf2ef3efd, 0xf5ceaef9, 0x7f45c9cd, 0x7e7cbbc9, 0x702eea17,
-       0x8d2bb33d, 0xfd8b5bf4, 0xfaff922e, 0xdffe5cc1, 0x0035f78b, 0x71264c9c,
-       0x49aeba6f, 0x4df6489f, 0x43ece880, 0x7e731de7, 0x26776540, 0xd3da43f2,
-       0xbf6067d3, 0x1eada7ce, 0x72d6df5c, 0x2ffa214f, 0xf3f356b6, 0x8f1366a1,
-       0x397e07df, 0x538600f1, 0xaf6c7686, 0xa39d1740, 0xfd107f7b, 0x3fbaad42,
-       0x98bcc61f, 0x5f3cc9d6, 0xda175d32, 0x3c62283f, 0x899035a7, 0x68e77df1,
-       0x9a4e6f7e, 0xcb90bcbe, 0x36276e7f, 0xe85c5c08, 0x627f202a, 0x17fa41af,
-       0x2e742c3b, 0x2eff8eab, 0xf1c628c6, 0x70eaf32f, 0xf176910e, 0xf9a666d9,
-       0x1d51869d, 0x4890d04a, 0x3c50a8f7, 0x30436ea8, 0x67d416fd, 0x4f14a94f,
-       0x7b4bf393, 0xe302ab3d, 0xdd8f5266, 0xbfb838a2, 0x0bfdd84d, 0x71e3fc98,
-       0x9e82f9b7, 0xff7b0816, 0xf7872b16, 0xc3cee652, 0x2ccd0b76, 0x76ac0751,
-       0x2947654b, 0x90d6b3ad, 0x8c85768c, 0x47b7c51f, 0x1ac9fb62, 0xe7e7617e,
-       0xe1be959e, 0xf419c9d8, 0x3f865d41, 0x693c85db, 0xffcfce18, 0x83cca1b1,
-       0xd786caf1, 0x30efd046, 0x3c781299, 0x1996e41c, 0x843a11ef, 0xbdd61efa,
-       0xc88b15ea, 0x73880a5b, 0xd8defccd, 0x453939c6, 0x78f11e74, 0x71ffdd1f,
-       0x23ca10de, 0x847906fe, 0x92bea637, 0xe01fbbfb, 0xd90debbd, 0xf941d760,
-       0x789fee74, 0x25684879, 0x92991bde, 0x47978977, 0x72c13e85, 0x6cc25e4e,
-       0x5685172a, 0x3e3ca1ea, 0x7197932f, 0x36040a03, 0x6cf06f35, 0xc92dda3f,
-       0x87702ec2, 0xc377bce8, 0x917423cb, 0x1e7758fe, 0x84676797, 0x3e4cf93f,
-       0xc20e6dbb, 0xfaec647b, 0xded27969, 0xc9f5a36e, 0x2cf6caf5, 0xffbb7633,
-       0x957e7210, 0xc53da738, 0x3c2d5aca, 0x044fe7fe, 0x1eec1c3c, 0x7fcbf141,
-       0xfde14dcd, 0x4f74423b, 0xfa27ec8f, 0xb8e41c77, 0x7bfe15ab, 0xf2a3e759,
-       0xcb977ebc, 0xb38c2be5, 0xea19c691, 0xe79be7e1, 0xfe2214e4, 0xc0aa6f00,
-       0xc9f7ca9b, 0xd07e7ced, 0x13fefe2f, 0xf46287e8, 0x0afc1ffb, 0xe787e7ea,
-       0x27274d1d, 0x5aab38c5, 0x2fb6dc78, 0x69e880b9, 0xf7dc558a, 0xc75da252,
-       0x9f6e3cf8, 0xc592f3ba, 0xaf091d79, 0x69c6850c, 0x09cc7011, 0xf6339f0d,
-       0xaffbaf9b, 0x8eeb4bff, 0xef0797c0, 0xc5d8396d, 0x9f1e37ef, 0xf485f1c7,
-       0xe076429c, 0x677f4d76, 0x9fb547d6, 0xae5f28c0, 0xda80a521, 0x6fee2bdf,
-       0x61d9f795, 0xdc71fcbb, 0x57bb45be, 0xfcc1a7de, 0x1c645993, 0x8cdeffb2,
-       0x70bf710e, 0x286f3aff, 0x8874eb11, 0xef223a75, 0xcfe7ec33, 0x73797d63,
-       0xb8e903ed, 0xfdfdfe1f, 0xfd12298d, 0x563cf869, 0xf1d7c87f, 0x1e5572f0,
-       0x1bdf2797, 0xa33ce45e, 0xe70fd9e0, 0x7849f9a8, 0xbb537f22, 0x94ba5a31,
-       0xf411ccf3, 0xf3bf8039, 0xe278e5bf, 0xbbfad97e, 0x7338be79, 0xbebae969,
-       0xf9875f33, 0x07ddb209, 0x34a0c078, 0x21bc27ec, 0x7327ec4f, 0xbc9c4e58,
-       0x339e6f47, 0xde917fa6, 0x7b27ef47, 0xd9efe593, 0xbd1afd69, 0x397bfe4e,
-       0x7efc73fe, 0xfca36b83, 0x7a8f183c, 0x176e16ce, 0xf2da2fd6, 0x037e0263,
-       0x797d54fd, 0x5312bf38, 0x3bf8f3c5, 0x4af3ab5b, 0x7760ab67, 0xdc552494,
-       0xa6e50f99, 0xfc93c6c7, 0xf154192e, 0xf3c83e79, 0xe04d8f35, 0x7c5747df,
-       0x79cb043e, 0x8a797913, 0xf79479e7, 0x9eccb460, 0x2bb6159a, 0xd173ccee,
-       0x1d4afab8, 0x42676bdd, 0x63d60623, 0xf944dd7a, 0xf1ae1280, 0x5d26259e,
-       0xbff3ac53, 0x03d3f4f7, 0xc04cbf8f, 0x1fd0ba7f, 0x2105fc28, 0xe82fe355,
-       0xcfe7e44d, 0x92fd5f7b, 0x9bdcd7ce, 0x079f5be7, 0x67ad1bed, 0xf287cd6f,
-       0x1407eb06, 0x603c53ef, 0xc61fa087, 0x608b60e5, 0xadd9cabe, 0xd89fb45e,
-       0x2559b76a, 0x18ff0ab8, 0xf007a9de, 0xa7b5e57b, 0x0f883c7e, 0x4c79c5e3,
-       0xf1a07214, 0x15fdbfb5, 0x678dc4e3, 0x1b346e6c, 0x7c3f7627, 0x135fda27,
-       0x1bfedfbb, 0x3cfcc3d7, 0x44f79c90, 0xfbc27ff4, 0x9a265d09, 0xabeec4ff,
-       0x6bfd6056, 0x402eebdf, 0x44eeb93a, 0x42c505b0, 0x3effabef, 0x880e7348,
-       0x7cd97a7d, 0x39f1b8d1, 0x013f8f09, 0x1e0893a0, 0xf8f0e73f, 0xced9f28a,
-       0x0e6e8f3b, 0x7b549391, 0x78ec0ade, 0x605f3b8a, 0x7b8c6e09, 0xd1fd73c8,
-       0xd5e3d57e, 0x7f783eb0, 0x20cc1f5d, 0x729e9ec2, 0x24820cd1, 0xc9672e5c,
-       0x39a5729a, 0xcabf534b, 0x3ef9af91, 0xcd2af33d, 0x42ae99f7, 0xc8d6794d,
-       0x37fa9a89, 0xe535cbba, 0x6a6613d9, 0xaa7b57ea, 0x60c2e535, 0xf17ea687,
-       0xf7ed2e91, 0x788f4c63, 0x7eee3a28, 0x27a59f03, 0x2d9ee43d, 0x06f4d53b,
-       0x85fe273e, 0xafda2383, 0x8ec5cd7c, 0xf4bdf037, 0x9f9f472b, 0x9be67e92,
-       0x3180b6f5, 0x53393fb6, 0x83df082d, 0xf3f1d7a0, 0xfb25ef53, 0x937880fe,
-       0xa0a6a7e7, 0x5090195f, 0x9fb9db75, 0x5c32efe2, 0x6efdc458, 0x943111c7,
-       0x7f276e4f, 0xd34371e5, 0x79e47fb3, 0xf728b903, 0xaf9bebae, 0x8b94f759,
-       0xcbbacd3e, 0x3c28aad9, 0x5729a1dd, 0xd4d6ee39, 0x5eb99e9f, 0x6ba67df3,
-       0xb69e144b, 0xba37ca6b, 0x53c28e1f, 0x9e9e147b, 0xf4977cd2, 0x5ffc2ddd,
-       0x0adfa1af, 0x3d42939e, 0xc9878895, 0x1f08faa7, 0x2ada7a13, 0x1cd74f11,
-       0x957c20ef, 0x2895bd04, 0x348ecb2e, 0x20cf81bd, 0xddb0cbec, 0x7a4ce681,
-       0x91766c1e, 0xf370ebff, 0x691e7a48, 0xfffbd376, 0xcf409e68, 0xe87b355f,
-       0x33cd9ff9, 0xecd3d9e8, 0x734767a5, 0xae7fd507, 0xcffb8bb9, 0xddeffb52,
-       0xc1bf45c8, 0x01a85d79, 0xc18ec623, 0x9e9e495b, 0xc79d084f, 0xeb7f06f2,
-       0x3420a9ec, 0x901d67f0, 0x9e207f2f, 0xfb4f2e45, 0x1e0e7860, 0x19fdf8cc,
-       0x43a37f22, 0x3b4429e7, 0x0fe3f47c, 0x32e6a7de, 0x37bd69b6, 0x183a7f13,
-       0x132866cb, 0x90f7e9b2, 0x93cfbc1e, 0xa8b3d8c3, 0xf7bee84a, 0xb9636707,
-       0xe79efc57, 0x241fc7e0, 0xc75bfc3b, 0xe2033dd9, 0xc707a3ec, 0x7b3fb388,
-       0x7f4765ca, 0x46afd1cf, 0x471e11d8, 0xc3cbdf85, 0x3bf80d0a, 0xa16ae51c,
-       0xf1ecf501, 0x5421e738, 0xe0c97953, 0x7bb75c52, 0x5f91e51e, 0xe1dfa06f,
-       0xfdf0a39b, 0xec97acaf, 0xf7a0fae2, 0xa7ed1346, 0x2b3ce98e, 0x957a3f90,
-       0xce10c7be, 0x14fe3d37, 0x7b5ea9e9, 0xafc21e5f, 0xbcbdf1fa, 0x4c7becec,
-       0x0d944771, 0x8f953e1c, 0x6fdb393f, 0x33e15efb, 0x0d11d71b, 0x1d83b99f,
-       0xf4115f7c, 0x201da2e4, 0x3daac7cb, 0x2c5714f5, 0x75c30cf7, 0x389af51c,
-       0x81ed7aff, 0xf237e461, 0xf08bce94, 0x360cf4ff, 0xa2e7fad0, 0xe83f44de,
-       0xd6207d42, 0x1f9e15ef, 0xa23dedcc, 0x2e67dc13, 0xe0bed2b0, 0xa3df8e98,
-       0xeedf5d10, 0xcfa3fbe2, 0x9c87dce2, 0xdc57be28, 0x0becff54, 0x5aef5fd0,
-       0xebdd750b, 0x58f6411d, 0x1740136f, 0x54f7ba68, 0xddfe39d3, 0xa12016e4,
-       0xf82def38, 0x6cfef82f, 0xfc5f9df7, 0xb07fea06, 0x1d26ead6, 0xf04518e2,
-       0x2f2a285b, 0xfd93354e, 0x6e4e78b4, 0x5bc5ea05, 0x56f0bc44, 0x614e9abb,
-       0xe8d93543, 0xdb967e80, 0x0403370a, 0x6ab4cad9, 0x5364fe23, 0x9b1dce4d,
-       0xe87ab9f1, 0x58f22376, 0x9b7d98dd, 0x07ad8cd1, 0xf9252e16, 0x19a77a17,
-       0x3adb75e6, 0xe7ef8bbd, 0xdadaf9e4, 0x22f7946f, 0xc898f7e9, 0xd020024f,
-       0xa5c9357e, 0x4949f668, 0x181f4e82, 0x6331e22c, 0xda4bd8d9, 0xe44ed778,
-       0xdf8bb3a3, 0x1e271e19, 0xec2efda1, 0x7b8adfc7, 0x4fefa39e, 0x5c3ae391,
-       0xcc75ff7c, 0xf6899408, 0x07ae42e4, 0x7cffcdc6, 0x7fac2943, 0x4743b75c,
-       0xd5b70d79, 0xb87880bf, 0x68f025d0, 0x4fc85d60, 0x7c97f937, 0x4c421bf0,
-       0xf0dce69a, 0xbba5f495, 0xa91951c7, 0xde424b2f, 0x397d48ca, 0x12adafa1,
-       0x8fd4a2f5, 0x211ae6c1, 0x8e489b8f, 0x475e6c1e, 0x7ecdc3e5, 0x6e691e7a,
-       0x8db8f215, 0x79aaffbe, 0x01c790a7, 0xd2f78f21, 0xf9e6eefb, 0xd9ad7cf4,
-       0xa985cf47, 0x6e11d7be, 0xd73b8e32, 0xdcbca3ec, 0x189b0f43, 0x742ef1c6,
-       0x038f289b, 0x47b1e238, 0xc94f30d2, 0xa344e744, 0xe5a295f3, 0x743d3f7c,
-       0xe5b7b80e, 0xfef7e46d, 0x17b4233c, 0xa7a7c707, 0x4765cca3, 0xe0f1f4b9,
-       0x8e8724f3, 0xb4765cba, 0x2e3e4fa7, 0xdd971eca, 0x0d3fe500, 0x71fd25ee,
-       0x9bb2e7d4, 0xe3c9fca0, 0xdfbbfcbd, 0xf940b765, 0xfc7dc1d3, 0xd051807b,
-       0x2fe0ecff, 0x33958e48, 0x47f220e5, 0x2a7f39a5, 0xd7d00ba8, 0x2f9107e5,
-       0x992e67a6, 0x60b17c8a, 0x72e88bb0, 0x41fd6ba6, 0xd91acf2c, 0x1515e2ae,
-       0x46e15b1e, 0x5691576c, 0xa9bb62ad, 0xc46c7739, 0x6e86d376, 0xcddb2357,
-       0x236fb318, 0xb7706f96, 0x2e9f68ab, 0x1a563940, 0xe59647ee, 0x65a72977,
-       0xddd5dd3e, 0xe307d25e, 0x0fa4bcba, 0xe62a5c24, 0xff426f56, 0xe2976367,
-       0xa9a5dfc0, 0x27f4ab98, 0x62ee6033, 0x0a93de03, 0x3dfffaf2, 0x87ac77ae,
-       0xf9623675, 0xadb72a1a, 0xedfa06ff, 0xe2f6007f, 0x8000e831, 0x00008000,
-       0x00088b1f, 0x00000000, 0x3cd5ff00, 0xe5547809, 0x9dcee7b5, 0x4c92642d,
-       0xe2420836, 0x96249964, 0x26b6432c, 0x0c486410, 0xf90130ee, 0x10196544,
-       0x044816c2, 0x7eab17eb, 0xe0171a19, 0xd16b8d69, 0xb5c46faa, 0x61e4b6af,
-       0x1d0958d4, 0x87d252aa, 0xb410553a, 0x88a47479, 0x119099f0, 0xc7d278dc,
-       0xf7fce73b, 0x24cee666, 0xbefd1480, 0xff938607, 0xcfd9fbfe, 0x005ffff9,
-       0xb3f85380, 0x34607f02, 0x3d2538fe, 0x0468048c, 0xd1bf67f1, 0x0395b26d,
-       0x8c0734ac, 0x412fa3a0, 0x6010aba3, 0x76960eaf, 0x24a40014, 0x0b7afcc3,
-       0x74b08d96, 0x5de7960b, 0x05480368, 0x20bada68, 0xda85816e, 0x6066e3bb,
-       0xe21745fb, 0x52ce38af, 0xe0546e05, 0x9bd40a93, 0x4f34899c, 0x1fd24d9a,
-       0x856fc7ca, 0x064a7850, 0x3d9ab7e8, 0x448004ba, 0x0dac7b93, 0xfb9bedc7,
-       0x8758834e, 0x31d688af, 0xeb1ebd6c, 0x6c3200e3, 0xca1f1e56, 0x5e541982,
-       0xc846ed09, 0xcff5b846, 0xda22a4fb, 0x2327c597, 0x5f434e84, 0xf9ec5f20,
-       0x63fe1654, 0xe0543d06, 0x6e03e97a, 0x70d79969, 0xea566020, 0x743967f1,
-       0x226670ec, 0x7ed45ede, 0x18bf046f, 0x7dfb43bf, 0xbe8de215, 0xbf697537,
-       0x0f5b5403, 0x0230438d, 0xd9dfb8cb, 0x855efe12, 0x878f0dff, 0xc3c06749,
-       0x10f0a1a4, 0x1af01fb5, 0xd7de8e41, 0xa66ecb0a, 0xc0bee473, 0xd1fcca9d,
-       0xf7218108, 0xf445f2a7, 0xfe05dafe, 0x25ff02f5, 0x5a74e736, 0x38fcdd5f,
-       0x8e005390, 0x4d79356d, 0xa9ffdc99, 0x1744293d, 0x2d837593, 0x5b5b3e9a,
-       0x00de8367, 0xcdd5adb0, 0x14bad7d0, 0x3f8076f4, 0xf97336b5, 0x2e16d6ad,
-       0x30f568ef, 0x8ebad9dc, 0xdb5a5fe1, 0xeb577eb9, 0xdbbf2e46, 0x6fe865ea,
-       0x5fbf917d, 0x86657f3b, 0xff4d12db, 0x45cec9d5, 0x7b9e8fc4, 0x3e9913aa,
-       0xc853f7b8, 0xc81a9eab, 0xc344b66f, 0x9d658301, 0x8f65c094, 0xd9e1f711,
-       0xc36de316, 0x8c73fd7d, 0x19c689bb, 0xad7e09a8, 0x4a437c43, 0x30d0f180,
-       0xbe9abdd2, 0x3a1c464b, 0xe4f56689, 0xeb0efe12, 0x6407bf3c, 0xd39b56d9,
-       0x383e47a5, 0x17558f1a, 0x6582dc00, 0x78f3ce0f, 0xfa85abaa, 0x48c07e41,
-       0x3fa29ce3, 0x097c7193, 0x3af07766, 0x0e1ca210, 0xb1e808c4, 0xd18f2c49,
-       0x40ddc850, 0x60f99fba, 0x1913e9e0, 0xcb3382b6, 0xa8f870c5, 0x9e03ab93,
-       0x6567a432, 0xd584c3ac, 0xa4f8127d, 0x46538412, 0xd38e00d6, 0x13d46e97,
-       0x5644149c, 0x9fc3c750, 0x6322dfc9, 0x14cbf186, 0x6b94d448, 0xed35a3cd,
-       0x9a99aceb, 0x5cf4befa, 0xb4d2ff1e, 0xfaed348b, 0xc59a5746, 0x232f53bc,
-       0x6f7465d8, 0x0974805c, 0x9b1c9956, 0x98bdfeb0, 0x062822f8, 0xbf1b1698,
-       0x317be089, 0x376a5e19, 0x14c9c0ed, 0x934e7dc0, 0x108b237d, 0xc6db9755,
-       0x99edc76b, 0x76c36353, 0x6957e657, 0x25c121d7, 0x1dabdfb4, 0xa7df3453,
-       0xe9ae5e57, 0x93fb32ef, 0xcef5ad08, 0xc6f7cd7a, 0x9f41af96, 0xe5b1300c,
-       0x014be824, 0x343afbc6, 0xecee94e3, 0xbf1fb4d2, 0xeb12641b, 0x378e7d92,
-       0x741f9609, 0x152ac4ca, 0x24df9b87, 0x3fa5f558, 0x4e01f683, 0x9f5159b0,
-       0x83dc8a4b, 0x963d0247, 0xcae52927, 0x812db7a0, 0xf21270e8, 0x89bf48f5,
-       0x6321c230, 0xbff2a963, 0x4c1f104e, 0x32002052, 0x16abf607, 0x3a79804b,
-       0x4598d78b, 0x1be5056a, 0xc906c1f5, 0x3847a691, 0x50540e47, 0x8a0428f9,
-       0x973aca08, 0x2a6bf89e, 0xb2a58f34, 0x0469dc09, 0xbf74483f, 0x2fdc7c4f,
-       0xe2c4da05, 0xcfc4c982, 0x68ff3f75, 0x17ac6dde, 0x5c261c62, 0xfebaefdf,
-       0xfd6b4a91, 0x91f53fbb, 0x7e216c37, 0xcd7eb26f, 0x8dcb5278, 0x7f19c72d,
-       0x2d6fb96a, 0x92e177cc, 0x9f680ddb, 0xaffe3610, 0xed0a76cc, 0x53a23ada,
-       0xb8c9fc23, 0x1ed420ba, 0xc418be3a, 0xbfea3177, 0x04d35a7a, 0x5ddfd7c2,
-       0x6f576c4e, 0x9e087210, 0x1c4ef545, 0x29463ea7, 0xa7d44f83, 0xb2a1ed2a,
-       0x6ae9cb9e, 0x6f68957d, 0x587bc757, 0x96ad1fb4, 0x522ef195, 0x9ca2cdcb,
-       0xa0f7cea9, 0xe5aa1728, 0x397170ff, 0x613fb44e, 0x29ef559b, 0x53ffe908,
-       0x0f18ddaa, 0xa06ec9e3, 0xc933903d, 0x1abb481e, 0xeda21f98, 0xb15eb685,
-       0x237ff317, 0x44c58c7b, 0xdf63cb8f, 0x90eeb921, 0xf1bae480, 0x8bd38376,
-       0xd49e7ff3, 0x12c6b451, 0xb7e7dfc2, 0x6abb7c08, 0xb6329ce3, 0xde6af95f,
-       0x3923e226, 0x85c8f76e, 0x563addf8, 0x4ea77ac7, 0xe88138b6, 0xfbd0af7b,
-       0xd848ff6a, 0x8686f2d0, 0xb2f5519e, 0x6cc1f3c4, 0xfaf9c1fc, 0xf4f51bef,
-       0x8e59c206, 0x9370973f, 0xdcf42999, 0x95add448, 0xea36f3f8, 0x3dd23359,
-       0x3a9c1b25, 0x1af29f6c, 0xf1a267ea, 0xc7d0bf41, 0x24f8c5af, 0x8f959c14,
-       0x6ff6c9bd, 0x8e528ca1, 0xcf2d7bf8, 0x7c89979d, 0x9fce347a, 0xd0db7c4b,
-       0x75d78db2, 0xe3cadd8d, 0x10583583, 0xcce2cf8e, 0x9e97fc28, 0x3fa5ff01,
-       0x8271fe26, 0x75cfa403, 0xbeb47428, 0x78b796e5, 0xef95cbbf, 0x43325fac,
-       0x472cb8ed, 0x39c68f97, 0x0e1f0832, 0x74074e85, 0x5f050ab6, 0xfabe1357,
-       0x1373fb17, 0xf9f0ecb1, 0x3ed9ba47, 0x88972aec, 0x4071cdee, 0xf92a3f74,
-       0x410ef68b, 0x0ed68eff, 0x5a5bcbb6, 0x84be18bb, 0x55bad073, 0x8d10dd7c,
-       0xc067f9df, 0x131ffcef, 0x01f4a3bf, 0xadfb03a3, 0x4e3c07da, 0x1180ff85,
-       0x2b4cf4c2, 0x27e225f1, 0xfae24ba1, 0x2120b93a, 0x138fa9a0, 0x738e52fe,
-       0xcae9f13c, 0x37aabb19, 0x98792148, 0x311d0b1c, 0x0ed7cc49, 0xc41daf85,
-       0x22ff2ad7, 0x11ea963f, 0xc49d6fcf, 0x37e0437e, 0xf3c0bfc4, 0x3bba78a8,
-       0x881baf1a, 0xabc1a78e, 0xc607feb6, 0xc7fa276b, 0xaf8237a4, 0x653778c4,
-       0x77f9e346, 0x7c555e0a, 0x7fe4536f, 0x236f3c38, 0x7f9ea73c, 0xb4cb6f3c,
-       0xf891b8f1, 0x453ece1e, 0xf75d47d2, 0x7e5a7210, 0x2d3a722e, 0xdff8aadb,
-       0x461677e8, 0xa26dfdd3, 0xf74359bb, 0x53c8339e, 0x4f298fcf, 0x848b7891,
-       0x3ab8128d, 0x3fdfd12c, 0xdf561ccb, 0x4e3c179d, 0xf8d6ce0a, 0x75bf9367,
-       0x29b3fc6b, 0xfd696118, 0xe5349bd8, 0x9aadeb3a, 0xada697f6, 0x6e5fd4d5,
-       0xbfa9af5b, 0x4d01ff32, 0x63c76af9, 0xd3e67e11, 0xe77afa9a, 0x73f5346f,
-       0xea6bb79b, 0x68f4b7e7, 0xfe7817ea, 0x78ab29aa, 0x1c0adadc, 0x356b6d2f,
-       0x65d3f12b, 0xfe03ab0c, 0x8b83125a, 0xdfd9070f, 0xd7b7f4ac, 0xafb24bb2,
-       0x32d1fd83, 0xc296ab9f, 0xcd9d8aaa, 0xb5f4126f, 0x2d78955a, 0xad5be18d,
-       0x3befd636, 0xee19f35a, 0xf128756c, 0x5dc3255a, 0x4e254ead, 0xb48c3173,
-       0xbb66af0b, 0x3d2164a7, 0x44bcbda6, 0xe980b807, 0xc167f87f, 0x77bc5a5e,
-       0xdce28ebc, 0x8e5eca35, 0xffb37f57, 0xe3afe436, 0x950726cd, 0x311fb77b,
-       0xf9a30ad8, 0x32b7ee65, 0x6cf8c338, 0x0d5fcb6e, 0x45cd67e4, 0x0863ba0f,
-       0xa59a9d39, 0xf7207e63, 0xcc2f5003, 0x05218336, 0xd9ecc1f5, 0xf80da392,
-       0x189207bb, 0x3f58dcfa, 0x133e0f4d, 0x7a2deb96, 0x979e299f, 0x3fa332e6,
-       0x132c4b3d, 0x50f07a4c, 0x7324a43d, 0x7d0d7e9c, 0x383ca1b4, 0xbf18b865,
-       0x1c3f22cf, 0xe96f5dfb, 0xbddd9030, 0xfa2fe76e, 0xb87ac36f, 0xf1ce53d3,
-       0x25625c3d, 0x3e792dfd, 0x371a9dd6, 0x3520bcbc, 0x5f1850e1, 0x4e19254f,
-       0xe1d1f8a5, 0x7adc5277, 0x9cf1c193, 0x05dfba2d, 0xc9a77eca, 0xc16ffb12,
-       0x4dde4dd7, 0x713e4852, 0xb84d3b7f, 0x01e226cf, 0xc1b367da, 0x7e445797,
-       0xb3f676f6, 0x16d72a9b, 0x2e9a9d11, 0x15313e91, 0xa69de285, 0x8fd92f96,
-       0x91cfd48f, 0x90f14cf0, 0xfe656fc3, 0x93badfdb, 0x8b8d45f9, 0x5c7d5b7a,
-       0x6ab80b2e, 0x39a3e3c3, 0xa64dff93, 0x4beaa7b8, 0x3c4cff11, 0x53fbdce9,
-       0xd5a077dc, 0x17e52fff, 0x9a82bcd4, 0x5bcc8867, 0xde647aa8, 0x6e0975ad,
-       0x2c9aefdc, 0x94f30651, 0x5ea3a674, 0xdedf5540, 0x9765159a, 0xbd3ac8ef,
-       0xffd6d67e, 0x6cf9fac0, 0x4d31bff9, 0xbe48d5d8, 0x05e337df, 0xe553ad03,
-       0x9ffe48ef, 0xfe707d43, 0xd7924d39, 0xf67a7a83, 0x44c37692, 0x7df9dce9,
-       0x88a0e5b9, 0xc2ed238b, 0x3607b6f7, 0x2b5c9ba6, 0x92617c73, 0x1e50726f,
-       0x4743a544, 0xcf3add34, 0x1fceb740, 0x76d16e93, 0x73bce0f1, 0xf1a08bb3,
-       0x8acbdfcf, 0xc83e27f2, 0xa91fbd3a, 0xf781ffad, 0x636b1d6d, 0xef4472b8,
-       0xea27593c, 0x01627c45, 0x80eff21d, 0x74b8e657, 0x3c7b6669, 0x195033c5,
-       0xb77d278c, 0xf2065bac, 0xd4ef410f, 0x5cfe468f, 0x1f67f0a2, 0x7e243ef8,
-       0x7ef7055c, 0x25980941, 0x22ae4bd5, 0x09f4b73d, 0xfc4f0843, 0x27f393af,
-       0xcb7e94ab, 0xda469d2d, 0xb567f2ef, 0x1a71d4ed, 0x1fc88a5f, 0x19fa5f57,
-       0x73f0ddb0, 0xa7556fde, 0x5977dfb6, 0x62872971, 0x084b1659, 0xa7d267ef,
-       0x1baec947, 0x5b27cac2, 0x3f20bf39, 0x9e03e0f3, 0xc4fa21b1, 0x71f14764,
-       0xf9e9f65c, 0x23ff5b58, 0xf71cb1f3, 0xf9e891ac, 0xbf78f97d, 0xeb4599dd,
-       0xa0f3f556, 0xc4c379de, 0xdca0677a, 0x37a4f226, 0x9e2daefd, 0x3804e4f8,
-       0x2a161d88, 0x6a85d2f9, 0x369d74be, 0xcfb93a5f, 0x49b979c7, 0x716dbd07,
-       0xbd89f748, 0x55dbce1e, 0x59b776ed, 0x5dd3fcb0, 0xa3fc994e, 0x64b96ff1,
-       0xdfeab75a, 0x484efea8, 0xbeb0e58f, 0xf66bbce3, 0xd53bebd9, 0x30f6aa2e,
-       0x06560ed2, 0xfec96bdb, 0xe3b6f84d, 0x2be7824d, 0xf7691eaf, 0x7a138bde,
-       0x57c1a8e2, 0x8cfc97be, 0xcf1c63d7, 0xaffaf441, 0xc67e16cb, 0x0302cf4c,
-       0x1f091fcb, 0x450cdbca, 0x764fae6e, 0xf54d975f, 0x99d0bd8a, 0xa3b2069d,
-       0x23df7275, 0xf95f12d7, 0xde1bce65, 0xbf07c77c, 0xccedb5ff, 0xeb2685f9,
-       0x863ff671, 0x749a338b, 0xa2f8a6e0, 0x4a56d6a4, 0x6dc50c7e, 0xf3544794,
-       0x9fed918a, 0xc8acd7b0, 0xb5573ce6, 0xd9eb49df, 0x1c33d628, 0xbe5a9abd,
-       0x8731e4d0, 0xbba9bf9b, 0x4c30badc, 0x16ca5e3e, 0xdbd22ef1, 0xa21cc87a,
-       0xc5f2d9f7, 0x65f8b7ff, 0x091e0c9a, 0xe4a16ced, 0x082ffe15, 0xf80e783f,
-       0x2083ce19, 0xf9583743, 0x38216a7c, 0x17022e18, 0xdbbb7cc3, 0x60337c4b,
-       0xbe248e08, 0xbbf57fea, 0xfe9be202, 0x57b6278b, 0x5f3bf9c1, 0x06fff48a,
-       0xfe78dbc6, 0xdbbe5781, 0x7039fc43, 0xf4ace187, 0x6764eac6, 0xe451f127,
-       0x53bbcb79, 0x01d73e64, 0x8b967afd, 0x03e8ab7a, 0x1b72a497, 0xe64cd8eb,
-       0x1cde908b, 0x37aab4f5, 0xc2bf6017, 0xd7ac744f, 0xb5e49960, 0x80aed363,
-       0x70ac458e, 0xa657a671, 0x2fa8a772, 0x95e8995c, 0x15585cb0, 0x4a6fea23,
-       0xc52642f4, 0xcb960143, 0x0fac00f9, 0x8bd08017, 0xf7938237, 0x96419189,
-       0x6f17fd84, 0x3e709735, 0xa4390216, 0x8e288bff, 0xb74e221a, 0x2f7908e6,
-       0xbefa12ce, 0x179b46b8, 0xc95b30f9, 0x4a6bdb1b, 0xe7561072, 0x1d12f738,
-       0x1bfc938b, 0x7ca32a1e, 0xa1360e90, 0x75567d7c, 0xaa779f2b, 0x35ed1afd,
-       0xcdbf84bd, 0xe2bc7012, 0x9f7936e9, 0x238ce713, 0xf2cdcfc3, 0xa807b5ed,
-       0x7b5a11dd, 0xc578f0f9, 0x47f71c7e, 0xd78795cb, 0x1bb14c57, 0x43f1fbe7,
-       0xe5cbcf25, 0xebe679ff, 0xf80b3bfa, 0x7e43c14c, 0x7ddda372, 0x046fd79c,
-       0x9ffad0b0, 0x40147114, 0x47e50673, 0xd2653c97, 0x11f19f91, 0x03c8639a,
-       0xddc61bf8, 0xe31bff04, 0xc77f8267, 0x27e099f8, 0xfc133f18, 0x04cfc607,
-       0x1e3b7f17, 0x8d802283, 0x4e4b4e39, 0x301ce879, 0x1c86bd72, 0xf9c1cf81,
-       0x7f3c8dbb, 0xf8cddd9d, 0xebf7a41d, 0x9973a5e0, 0x0bc189cd, 0x6fc34e92,
-       0xf0dfdd03, 0x7870e9f9, 0x2325cf51, 0xe853bfeb, 0x67a9d45a, 0x15d45ffb,
-       0x6b086f88, 0x918e4177, 0x395f0beb, 0x1fe34f18, 0xd7e20eb5, 0xa796e129,
-       0x82f944e9, 0x08332d67, 0x677675bf, 0xe51bed09, 0x51f6833c, 0x83c1f5d4,
-       0x7c78cb13, 0x75a364ab, 0xb8e51f04, 0x911f6221, 0xb5f75078, 0x81bfd139,
-       0x257e6ffa, 0x7a82768b, 0x10dc8407, 0xed43491f, 0xcff32d77, 0xccb05374,
-       0x7e9deb8a, 0x0a1e6e4a, 0x29f675ff, 0x5477e78c, 0xc7cf537e, 0xe952fe15,
-       0x1df2ae76, 0x6b901e39, 0x6ae77e84, 0xb236a5d2, 0xc9e3274b, 0xee57ac2f,
-       0xe6757419, 0xf4fb47bc, 0x6ec194ec, 0xc8d63e63, 0x5f8562df, 0x6dd85854,
-       0x36bd1174, 0x59ca1f77, 0xe4fa6164, 0xb3f6c62c, 0xbc9aec72, 0x89d56167,
-       0xe14a1fc7, 0xea9a56f6, 0xceba783a, 0x60dfe38a, 0x6d36fede, 0x93f5ae69,
-       0xcf2c44ba, 0x1076934f, 0x9ccb605c, 0xe5a3649a, 0x37fd797a, 0x41d94fe6,
-       0xa3957522, 0x29b9fd9e, 0xecc264a4, 0x9639ad43, 0xcb071f0e, 0x4d64d675,
-       0x31b4d2f9, 0xdb97f69a, 0x57f535b2, 0xd4d38fe6, 0xe55ef3ab, 0x2bb4d528,
-       0x51660a4e, 0x60fb875c, 0x64e780b9, 0x7da25daf, 0x1c62beef, 0x3f3da796,
-       0xca6e41cb, 0xda7ea566, 0xd12f5a96, 0x69f10063, 0x70ea8744, 0x1f47fae5,
-       0xe222c1a2, 0x67eec686, 0xe76d3876, 0x130c3710, 0x7100ac2f, 0xdc5c3f8e,
-       0xa02f1910, 0xf4907cfe, 0xd7abf167, 0xdc70db58, 0x2e2755cd, 0xef3ee1b0,
-       0x8238c1cc, 0x47128dec, 0x833fc70c, 0x04d92272, 0xf0c8f4ff, 0x03fc10dc,
-       0x1f850bf0, 0x3ef69c05, 0xdf0533fa, 0x4a7dbf5f, 0x07f38dfa, 0x57efc51e,
-       0xafbe4460, 0x6f78e8d8, 0xdea7e50d, 0xf9ce8191, 0x03ae24e1, 0x77e81beb,
-       0xb0f7c439, 0x46bbe9e8, 0x0f77f0a7, 0x94aba6b9, 0x731fdffc, 0x71aabf14,
-       0xcba35dfb, 0xf370f542, 0x70f69a27, 0xa6b774bb, 0xb6a6677c, 0xbb94ef7c,
-       0xe70ffbc3, 0x5c6c3597, 0x9ca37460, 0x392c3c36, 0x8be843bd, 0x28a4f5c1,
-       0x097ba1fa, 0xdb43dbeb, 0x716d1997, 0xe157edd1, 0x6cb79478, 0xaadec618,
-       0x193aea7a, 0x7faa879a, 0x71cf9d47, 0x08fbe77e, 0xcdf64f71, 0xc3b09af3,
-       0x8db8251f, 0x2fb27ce1, 0xf47b9c47, 0x1dc0f63f, 0xee79d35f, 0xeabe22eb,
-       0xa3f6144f, 0x9d33f3a8, 0x08f1610e, 0xd6455fc1, 0xd2ec8e80, 0x0f58d2c0,
-       0x2d359ca0, 0x8ae8f38b, 0x7e088fc9, 0x5e4f1e68, 0x9a0f2dc7, 0xeb1fce91,
-       0x3cbb1a74, 0x9616c140, 0xd9fd9efb, 0xf7e93b8c, 0xe92f7102, 0x2fb3ed7c,
-       0xad7d8407, 0x1e637a11, 0xb7629ff1, 0xd3565500, 0xc768305d, 0x5e10cf48,
-       0xbf6b9ca8, 0xc987fdf5, 0x7a11efcf, 0x370af283, 0xb4e05fb0, 0x1d0df368,
-       0xbbf8e72c, 0xd73efc2d, 0xb78feb59, 0xf3968dda, 0xd84647a8, 0x218779b5,
-       0x57fbc5f4, 0x5e9b3d22, 0xd05ef997, 0x04f6adb1, 0x911fd308, 0x28da6c78,
-       0xe5ab9cb3, 0xcbe55ba3, 0x830f6cbc, 0xd185f519, 0x83a706f8, 0x55b57fe5,
-       0xd27ab7cc, 0x4ec83337, 0x8bd6eeaf, 0xcdc32f4b, 0x5b064eb3, 0xb79b3cd8,
-       0x5d929699, 0x603fd753, 0xf749f455, 0x0a534957, 0x843b5c04, 0xc0bf457d,
-       0x417e4290, 0xecf1c4bd, 0x3551ee9e, 0x123da784, 0x3c256cf8, 0x5c6635c4,
-       0x1c314cdf, 0x5e50b77d, 0xf9f2d214, 0xd71aa59e, 0xacecf1aa, 0xf27659ee,
-       0x5cec3f63, 0x072907b8, 0xccd9ec93, 0x8782d74f, 0x893deefd, 0x93ca74ae,
-       0x3fee534c, 0xf60c49ec, 0x67bdbf91, 0xf744ac52, 0x3bfc7019, 0x5f757c69,
-       0xf4ae0c7b, 0x9297de66, 0x44fe752f, 0xf67b153e, 0x67aaa271, 0xa7dbe4eb,
-       0xf7e7495c, 0xf14ac073, 0xf85974ec, 0x2147f0d5, 0x6d5eaacf, 0x6c49fc92,
-       0xa633edaa, 0xa34f11db, 0xe4a97e5a, 0xf735db7d, 0xafd6cf00, 0x5fa38c1e,
-       0x567f9894, 0xb1bc4439, 0x47f3faaa, 0x57f9c5ae, 0xfe4fbc61, 0xedaec2dd,
-       0x917f08fb, 0x7c60fdf1, 0x7be62ff5, 0xd733e3a3, 0xcddfda32, 0x73df1c77,
-       0x69c7442d, 0xea817183, 0xcb173e5f, 0x58a8d6e7, 0xfc287c85, 0xee5b647a,
-       0x7f5835de, 0x66062fe4, 0xfd2737d7, 0x58ade8ea, 0x58b9f9be, 0x2491f3c6,
-       0x391d90f0, 0xebcf29b2, 0x744b06c1, 0x6fb25ec1, 0xcf8e25b0, 0x327b3e69,
-       0x512fb7ef, 0x76b7f27e, 0x7e4843f6, 0x7cc2e86c, 0xe88ff746, 0xb9a3cbfb,
-       0xbcc5b81f, 0xca5c8a0d, 0x5fde142f, 0x242ff54d, 0xa5427e73, 0x6327e1df,
-       0x7dac149c, 0x2b22be05, 0x92e7deb2, 0x5bdd10e7, 0x697ba15c, 0xf97c84bf,
-       0x06f708d5, 0xc7f2f7da, 0x89c3f3ff, 0x17da9fb8, 0x1555feae, 0x07d96fae,
-       0x84e340a9, 0xdfb43ae8, 0xb66b6c70, 0x3f057f90, 0xf18c5e2b, 0x27d30c1e,
-       0x35123b2b, 0xd1aea6e5, 0x7a6183de, 0x729ef068, 0x04e7c4a3, 0xed5c8a8d,
-       0xeddbba37, 0xfba5d794, 0x713f4ca9, 0xce84b51f, 0xf7ff08ab, 0x91ff1899,
-       0x5da2f67c, 0xf3566739, 0x4e60c93c, 0x0b75b923, 0x97dc0dfc, 0x31e289b7,
-       0xf1493d9f, 0x33b9823b, 0xb3f9c30a, 0x9c1bd577, 0x7b8931e7, 0x9f43318f,
-       0x13da77eb, 0xf9837db9, 0x699e4d4b, 0x4d09cb55, 0x015567fe, 0xd2501fb0,
-       0x89bd2b66, 0xba1487ce, 0x7aee9fdc, 0xf1def18d, 0x18bbabc0, 0xf2dc4f9f,
-       0xd3bbcd31, 0x5d83f4c2, 0x11163c4a, 0xbf98356f, 0x69efe450, 0xe87e7f8d,
-       0x9445bdb1, 0xcaf438ff, 0xd3ca22b8, 0x87fd942e, 0xf7c99d7e, 0x86dff69c,
-       0xf7cecb70, 0xb91e2f39, 0x0c7ba8de, 0x8d43d092, 0xba648fb4, 0xc77ae3ff,
-       0xf42e72ce, 0x850d81c3, 0x1f353f8c, 0xe864703d, 0xa75d5078, 0x3ebabe3a,
-       0xddb57c75, 0x5f22ecdf, 0x17f46fd0, 0x415ffd91, 0xfb6130e7, 0x17f78fea,
-       0xbbe85a25, 0x4913f855, 0xb7e30e58, 0x2abcf57f, 0xf06a7cf2, 0x47c9565c,
-       0xfdadd3ed, 0xaff91199, 0x8321e3af, 0x7eef5c3b, 0x752a73cf, 0xdafdeabd,
-       0xfd85ab7e, 0x2576939b, 0xe90e9f1f, 0x1deb0ed4, 0xb7bff23e, 0xc7e41c98,
-       0x905c9a27, 0x3469f88b, 0x9afef8fa, 0xe4d12fda, 0x7991efe6, 0x234481f9,
-       0x81e5bdd0, 0xf7fce554, 0x42bd602b, 0x9c16e871, 0xd756acb7, 0xd212c5bc,
-       0x2cfeaa87, 0x0bdf871b, 0x3ea91ee8, 0xdf2027e4, 0xdb6b1594, 0x2da3f687,
-       0xa0ae7bff, 0x6eb25963, 0x24b938c8, 0x1b65c857, 0x9e42c874, 0xa89d1d85,
-       0xbf0d1de0, 0xacd7ee1c, 0x40fcf452, 0x0743d9bc, 0x8ab713bb, 0xf513ab7b,
-       0x5104edbe, 0x124b400b, 0x89f4995d, 0xfab4baf1, 0x1cc86c9c, 0xd8e3cbb6,
-       0xc8504f2e, 0xccd4b77d, 0xf7435bf7, 0xc132fd5c, 0xd0c8218b, 0x413d5609,
-       0x4bc30324, 0x2a70c5c0, 0x0cbc3334, 0x015e19da, 0x02af0c1d, 0x89f8433f,
-       0x1ed80daf, 0xff656edc, 0x3a25f2e9, 0xd765cbb2, 0xcf97ed0e, 0x3c35f052,
-       0x57cb503e, 0xa63e3b9c, 0x8772f72a, 0x7cd8cbc5, 0x2f157be6, 0xec4fe226,
-       0x34de0317, 0xc0209382, 0x46264ce3, 0xdd78a6ce, 0x6b7ef7c6, 0xbae5c9c1,
-       0x6547c4b3, 0x1777adc0, 0xda97810c, 0x9e64f9a1, 0xb90327c2, 0xe951f8c0,
-       0x8dae48f5, 0x30dd2acb, 0x7b234c50, 0xc84f4d10, 0xc59675a0, 0xa7a71cd6,
-       0x5f3fb722, 0x7a8f5336, 0x66b4acb4, 0x5f90a90d, 0xe5154ee6, 0xd32f3589,
-       0xf3fb7d51, 0x71728a97, 0x81c1a94d, 0xcbdae85e, 0xfa825e66, 0x27dcadd9,
-       0xa011a337, 0xb672637b, 0x2b761738, 0x724dcaf7, 0x2fba5ae6, 0x580dba66,
-       0x0063b8df, 0x22d7ecfc, 0xb8bc91b7, 0xb37b1c45, 0x3aafd055, 0x2e4b7dd6,
-       0x2fb333d9, 0xb87486de, 0x28dd6d79, 0x18f79bb2, 0xa49ff8c5, 0x81bdc6da,
-       0xc49932f8, 0xbf7556bd, 0xc189ef58, 0xadb24072, 0xad0cc969, 0x59c75d4b,
-       0xe9d77bcc, 0x774fcde6, 0x023d206f, 0x15c70736, 0xbefb1463, 0x34c4cb65,
-       0x1d7030f4, 0x20475e56, 0x0b4d772e, 0xee91dd56, 0x1bc6847a, 0xf87c1388,
-       0x7529d108, 0x75cbe878, 0xc43b943e, 0xdfb581f7, 0xbd23eabc, 0x042e29f4,
-       0xae4df9c7, 0x475a71fb, 0x51902e93, 0x45fbf48a, 0x05007a2c, 0x9096be21,
-       0x0f107398, 0x1af04e6d, 0x77945e59, 0x99f9ca36, 0x8b03172a, 0x4fc43c71,
-       0x8b55cb99, 0xcc5422ee, 0x60937e6e, 0x16bdbba5, 0x179e686b, 0x724d3d68,
-       0xe4f881b0, 0xc607e268, 0xc76e594f, 0xf454fe0a, 0x9eb6f759, 0xa288c6db,
-       0xb2e4c20b, 0xaf89db69, 0x6f7486ff, 0x5071663a, 0x3e3c90f3, 0xe79c46b6,
-       0x46fa345a, 0x5d09d395, 0x9c383e26, 0xc5a2f5b8, 0x07d26ed4, 0xb7a4d9bd,
-       0xda06f727, 0xe81e7dc8, 0xc8463bde, 0x7fd7ea89, 0x7d8b9d23, 0xfc8cccf9,
-       0xf9104091, 0x839c5e23, 0x8af4fc73, 0xad5f0738, 0xeca93de4, 0x788b7de1,
-       0x573b8d54, 0xde2dbcf6, 0x6ff07985, 0x122bbd05, 0x713e967f, 0x6fc455e3,
-       0xd48bef91, 0x6949b478, 0x7bd7a2b7, 0xf227ed37, 0xc51351bd, 0xbfc345a3,
-       0xa27a6a37, 0xc8d1e396, 0xb9bd46f7, 0xb14afe4a, 0xa1f8a08f, 0xb436944b,
-       0x87c70b3f, 0xf709af46, 0x35c9fab6, 0xd3952b0e, 0xc7d60e2d, 0xe10e3d57,
-       0x6489e1ed, 0x9e5519e6, 0xd893ad97, 0x5af156bf, 0x49c9bcfc, 0x7e7e28eb,
-       0xe8cdfb14, 0xe97b8bef, 0xde913e4a, 0x837bd012, 0x2cc189cd, 0xb9ba67ba,
-       0xfe41df3b, 0x9d5a1ff8, 0x68430ff0, 0x503c6a7d, 0x4b54bf27, 0x2d8e87ef,
-       0x3f0b38c2, 0xa679eead, 0xd5e58ccd, 0x1055e9eb, 0x13f384a5, 0xdf2aafc8,
-       0xc6978329, 0xd543ef01, 0x39153b08, 0xc0e9a537, 0x188f8616, 0x0db008db,
-       0x29300f91, 0x4fcd8bf4, 0x39c7d4d2, 0x4ff4d02e, 0xd4d2cca8, 0xf788c5b7,
-       0xfa71e032, 0xef422a0b, 0x3f9d1248, 0x0083f4d1, 0xbd08adfe, 0x7e27b917,
-       0x4f7e4eea, 0x3ce06fe2, 0x2565f245, 0x7926f69a, 0x5dfc4cab, 0x435ea5fd,
-       0xa6529fcf, 0xb956f11b, 0x9c1cfd1b, 0xb69f4267, 0x01e0263e, 0x5bb317ea,
-       0x984bc9af, 0x85f2da6c, 0x629e4a79, 0xe4d58c2c, 0x2ef10629, 0x61d8fef8,
-       0x0545f31d, 0xbaaafce4, 0x006cf08c, 0x6f1a2daf, 0x5df840c7, 0x1c5ac6c7,
-       0x426a96f4, 0xc932cbcf, 0x8b4baa41, 0xb5b351ff, 0xd6ed1ff8, 0x52cc7be2,
-       0x9bd3be2d, 0xb0bef8b5, 0x4cd78b45, 0xd96f168f, 0xda6826eb, 0x346bdbdb,
-       0x578dbce5, 0xe45fda68, 0x8f29a19d, 0x4d7af17b, 0x858ec2fb, 0xaee2fa9a,
-       0x957a9ae5, 0x83e386cf, 0x11d5bef1, 0xdd03a6fc, 0x74a0f869, 0xf335cfe7,
-       0x9ff450fd, 0x05e8a79f, 0x2bd7fe85, 0xf8dde576, 0xb892f7c3, 0x7a158b4e,
-       0x50df3070, 0xee78e06d, 0x6d725b3d, 0xc505e91c, 0x7b14b9de, 0x894f3907,
-       0x1d9455b2, 0xa2bf717e, 0x36ab9f64, 0x2cf746de, 0x8a8afdc4, 0x09b5edc3,
-       0x1de23ed4, 0x494af4d6, 0xf91dde73, 0x67a66b2e, 0xd1209cad, 0x3f7144bd,
-       0x841ef231, 0xdeab3efa, 0x2739a319, 0x96bdee1f, 0x78c25f9a, 0x2f148c01,
-       0x3efccce8, 0x721fda31, 0x5fd9946c, 0xf6ffb373, 0x79cdc967, 0xfecc6ba7,
-       0xecefe20c, 0x79f5eeb1, 0x3aa3b788, 0x3dfd8d87, 0x00d6fde5, 0x2fdf8c6d,
-       0x3ca4ccf5, 0xbb8600e9, 0xdfd4d794, 0xbd2663b3, 0x5be5c45b, 0xac221503,
-       0xe68f3fa6, 0x71a41fb9, 0xbbd6480e, 0xbbefb14b, 0x20cf3e13, 0x73a2667b,
-       0xff3e12fe, 0xfc2f387e, 0xee147bfc, 0x406df50f, 0x79f0f367, 0x8e25cfee,
-       0xc1a73e53, 0x77e4c2aa, 0x4f79419d, 0xb9b6e22a, 0xb8d4be0a, 0xff328e6d,
-       0x29621c01, 0x5db9f3ea, 0xacbc667f, 0xe253eb48, 0x158766bd, 0xac71bfc7,
-       0x7bef84a5, 0x221d4b39, 0xb8e357de, 0xb1f7f231, 0x87ba67b3, 0x88ed22b5,
-       0x97869e26, 0x57cc8792, 0x42c5e646, 0x1fe316fb, 0x76cb1f58, 0x74fac0e8,
-       0xc6863fce, 0x85f9ca3f, 0xfbdacdb9, 0x3e5bf3dd, 0x02dff0d2, 0xfa9a27cf,
-       0x30d04a40, 0x781ff706, 0x1bd4f475, 0xaffd7f10, 0x9e282a98, 0xe4f5ba45,
-       0x0fc68795, 0x897797dc, 0xb4ce1bf0, 0x1d79cfcf, 0x5afdcabd, 0x5bfb9f75,
-       0xd03971f7, 0xefb8881a, 0xbfc4d1e4, 0x09fe342a, 0x0e8fc9f2, 0x431c234a,
-       0xe76673e5, 0x57a9388b, 0xabda7779, 0x55ed3bbc, 0x2af689de, 0x957b42ef,
-       0xbbeaa177, 0x9c095edd, 0x8e64bf74, 0x816a7ae4, 0x0f76efc4, 0x969b3ed1,
-       0x5de88b07, 0x60715363, 0xbbf3249e, 0x7df423dd, 0x45bb7788, 0x69f49592,
-       0x6ef435ea, 0xcf08f0f7, 0xd9d8b251, 0x50d789f9, 0x28d870bc, 0xc5f4a3e4,
-       0x7bd2666f, 0xdd53c7bd, 0x3fbf89c7, 0xf31f6495, 0x9f12ebf3, 0x6033832b,
-       0xef16719c, 0x13cbbf7a, 0xf32734e7, 0x0a89b9c4, 0xbd0be647, 0x9cb04a56,
-       0x2e6f72e8, 0x68dabbbf, 0x385777e2, 0x7617539f, 0x7df2221f, 0x4d1fc95c,
-       0x6a1fd23e, 0x5f2127de, 0xbbd3379c, 0xca675a39, 0x6ef126fd, 0xa0cfe02e,
-       0x0f747677, 0xbdf245ca, 0x1de29c1b, 0xf0a6de5e, 0xf90930f7, 0x45bd3dca,
-       0xb7a779a0, 0x7ec0e7b2, 0xe5af27d2, 0x53f393b9, 0x56c7ef43, 0x7f676fc6,
-       0xc6df20af, 0x797ae2f3, 0xee17a8ff, 0xc79cfa24, 0x7e56617c, 0xd7fff479,
-       0xf5bc3860, 0x5a3ff62f, 0xf77a1990, 0xaddef616, 0xaf2c3f20, 0x343faea7,
-       0x42e5e9ce, 0xe5a97bcd, 0x93dd8f43, 0x7486724b, 0x5948f911, 0x88633f9a,
-       0x05f3d3fe, 0x774feffd, 0x97f9a04d, 0x60bc8b37, 0x6fda6f88, 0xdce898f9,
-       0x3ef21963, 0x723fdabf, 0xf5b72b9f, 0x9f703e30, 0x617f68f3, 0xf08cbcfb,
-       0xbfb3eea5, 0x05a3ef7b, 0xdfdf73b6, 0x6e777df7, 0x6d71811a, 0x767950d2,
-       0x7e613eb4, 0x3fed4999, 0x8fedaf56, 0xb1e5390e, 0xd1de48bb, 0xe254e96f,
-       0xc4cbb21e, 0xee5daa17, 0x2920e254, 0x02ed83b0, 0x71724bcd, 0xfb61e4b7,
-       0xda3be6a8, 0x947fb424, 0x61af7057, 0x685f217b, 0x775f1071, 0x49f9ef22,
-       0x58cef41e, 0xc44773ce, 0x758b3fd7, 0xbc7844df, 0xa335aff9, 0xf2defe28,
-       0x38942b97, 0x72abd84e, 0x69cb3f85, 0x4147da7e, 0x996df302, 0x730abeb2,
-       0x55c9fb33, 0x5e4591e0, 0xac93c943, 0xdff1c1df, 0x141a01ff, 0x43d0aaaf,
-       0x000043d0
-};
-
-static const u32 usem_int_table_data_e1h[] = {
-       0x00088b1f, 0x00000000, 0x51fbff00, 0x03f0c0cf, 0x1894738a, 0x18357a18,
-       0x326b3618, 0x31686830, 0x20318830, 0xaf8568e4, 0x9fa65371, 0x8181959b,
-       0x81f98817, 0xd7881058, 0x6c303133, 0xff5e2260, 0xfb045111, 0xc303209e,
-       0x197f2051, 0x6614ee90, 0x64055860, 0x2fe2031f, 0x1080be40, 0x100c8303,
-       0x606115ff, 0xc1d20530, 0xc4036c40, 0x9bf145c7, 0x7c80827f, 0xbf2a08bc,
-       0x279f8d1b, 0x25ff5f8c, 0x0ff2fc11, 0xc363c808, 0xc7e41632, 0x7a052247,
-       0x29370207, 0xca8ff2a2, 0x543c3033, 0x51d06060, 0x919bf082, 0x6280ede4,
-       0xec21e4c7, 0xb8c09229, 0x28b5ca07, 0x2a773762, 0x5004fe50, 0x34894bce,
-       0x41d3dcf7, 0x8434afe5, 0x3ebc00d0, 0x03a8e414, 0x000003a8
-};
-
-static const u32 usem_pram_data_e1h[] = {
-       0x00088b1f, 0x00000000, 0x7de5ff00, 0xc5547c0b, 0x3d9cf8b9, 0x926eece7,
-       0x2126cddd, 0x26c2bc21, 0xb80d4401, 0x41a00c40, 0x94520f37, 0xa2a1e1a8,
-       0x24786c22, 0xf622ef21, 0xddbf1f62, 0x52c488f0, 0xd4c51f1b, 0xb051768b,
-       0x40368bd1, 0x5c1758d0, 0x6d8b459e, 0xd5a045e8, 0x5e40137a, 0xa540b206,
-       0xcffd45b6, 0xdd9ccdf7, 0x26364e73, 0xf6ffef6a, 0x9fdbfffe, 0xcccce61d,
-       0x7cdf3337, 0x9be6bdf3, 0x91be6489, 0xf21387d8, 0x256efc25, 0x108951e4,
-       0x9b4e1892, 0x9fc6933c, 0xedb10994, 0x3bea247e, 0x9e0c8499, 0xd146706b,
-       0x64085fa2, 0x21064b4e, 0x758d65c9, 0x793dfa46, 0xe8bc7d91, 0x9819c308,
-       0xbdbae47c, 0x720c8409, 0x8266f6d3, 0x7fe92fbf, 0xc637b73f, 0x79c87491,
-       0xe131a285, 0xbc9a4afa, 0x877bfa48, 0x149bbeaa, 0x48dda675, 0xfd51fbfb,
-       0x9085b720, 0x4678c31f, 0x40cba942, 0x78b8e8b2, 0xfd2e6f5d, 0xaf0e3a3f,
-       0x295be8cd, 0x1c1a2210, 0x242444b1, 0xa0482326, 0x679fbe9d, 0x49d7ed3c,
-       0xaa36a708, 0x49e74ac8, 0x0896b4c8, 0x808972f5, 0x76cd8878, 0x78e97b25,
-       0xe22e7d57, 0x220d57bc, 0x27d69da4, 0x684ed392, 0x61c4953a, 0x232dc7bd,
-       0xd57e4206, 0x07123fae, 0x199b1b85, 0xdc155e24, 0x0e210f06, 0xc7afc513,
-       0x8f2ae98c, 0xc4c9a79d, 0xab210d71, 0x574c0e3d, 0xfa634679, 0xdb27d0d8,
-       0xf9d00673, 0xe9d8320c, 0x63834848, 0x1191dda6, 0x2dc72786, 0x0938e730,
-       0xae2926c9, 0x2f5a54c4, 0x4dc840d1, 0xf342dc84, 0x19082375, 0x5084ec49,
-       0xbc933dfc, 0x019dca2c, 0x45e60779, 0x7cc37103, 0x2e033263, 0xc62de291,
-       0x1c95cf69, 0x1bf8efe1, 0x785fdf80, 0xc1d6152c, 0xefcc1b7d, 0xf0ece219,
-       0x46dd9e02, 0x7f5a26e7, 0x5e4ceca5, 0x468ae14a, 0xad832eda, 0x1e1094bb,
-       0x1fc04cdf, 0xc9cc8fed, 0x30d7acd5, 0xb4224718, 0xeb05dc73, 0x75b27164,
-       0x1574095a, 0xf2e61d61, 0x77655875, 0x38fd19d9, 0x11fa2449, 0xb1fa5aed,
-       0x8fe96864, 0xba9fb17e, 0xbf69e79e, 0x3bed424d, 0xbd3ce953, 0x4dce0c4b,
-       0xa160dbf4, 0x0af80051, 0x80c425bc, 0x41f92afd, 0x63a05265, 0x179e1ab4,
-       0xf6f7e9cb, 0xefcf730e, 0x52e2062d, 0x2a5372e8, 0xcec4777c, 0x6626e3a0,
-       0x6b4cec47, 0xe987f1cf, 0xc925d924, 0x4c0eef40, 0xac47041b, 0x477ce300,
-       0x9c049b24, 0xf6a4727f, 0x08edd3ff, 0x377ae1f1, 0xda5475f0, 0x3d203c51,
-       0x468b1f79, 0x3450883c, 0x17e70c39, 0xad17cf1c, 0x4a434f45, 0x5868e348,
-       0x875f9a5f, 0x79a663f4, 0xb09be62b, 0x3fca1edc, 0xacc9e58b, 0xba5e5d3e,
-       0x55e3bd18, 0x6eda1759, 0x4291c203, 0x38445e70, 0x9bbf5096, 0x94203f30,
-       0x1fd625ff, 0xb7f7eaca, 0xceed251f, 0xf9c29e0d, 0x003b2ebf, 0xd6dbc29f,
-       0x2e94adc0, 0x7c106e0e, 0xec0f9a26, 0x75fe418c, 0x9f0cfd7e, 0xd767e289,
-       0xea0b9338, 0x8398df9f, 0xefedbcf9, 0x5e5a24db, 0x20945db5, 0xd679d86f,
-       0x5bf141d6, 0xfc7f6a63, 0xb83dfa66, 0x602f245d, 0x9f71d377, 0x48b4e29d,
-       0x92f9633e, 0xdaad9628, 0xc01e6bb0, 0x91336b2d, 0xeaa70a28, 0x6f3bd2cd,
-       0x03d2f9a6, 0x552a8132, 0x838cea9b, 0x4f897e69, 0x8afc8168, 0x3f601f9d,
-       0x0ca4b9dd, 0xe039f7f6, 0x752f945b, 0xee93dadb, 0x7dcbdfa6, 0x7ea00a5b,
-       0x09c166f9, 0x7ebe5c4b, 0xbf0087d7, 0x211e55bc, 0xcd15f852, 0xdaa1c431,
-       0x17db792f, 0xade309df, 0x9426477a, 0xabb291ed, 0x1891190f, 0xe02346a4,
-       0x13d36ab5, 0xe79be046, 0x1fb0073c, 0x2f559f05, 0xbb687ed3, 0x2704d7ea,
-       0xc0daad4c, 0x3785cdf8, 0x68bce6a3, 0x19d57981, 0x37fb4147, 0xbd42351f,
-       0xebf15f52, 0xdf180e51, 0x8c016306, 0x6306fd73, 0x566f8a89, 0x3356ff34,
-       0xe94d53ae, 0xbd19dd03, 0xce39e7af, 0x397c95b7, 0xdf484015, 0x4338cf92,
-       0x339e87c5, 0x57fd21c4, 0x11c48b34, 0xdf781f81, 0x8760fbe7, 0xbe03f195,
-       0xc0ed4b5e, 0x75ebc21a, 0x4fd7cec9, 0x88cd660a, 0xe71ee7c0, 0xcb91a3f2,
-       0x7e41278f, 0x2e69f4d0, 0xf971d63f, 0xe271e4d1, 0x933d67f7, 0x71ef5d30,
-       0x67bcfa61, 0x4f3ea61a, 0xc17bd611, 0x8dd30733, 0x7f7e371e, 0x698653c9,
-       0xbf16a7b3, 0x8e59e2bf, 0x178f66e9, 0x59e6bfbf, 0xa78b6983, 0x9eadd311,
-       0x3d5b4c26, 0xbaf7ac3e, 0x36d319a7, 0xff7e0b4f, 0x530da7b5, 0xe98027bf,
-       0x9a5f584e, 0x98ed3c06, 0xc31cf6ee, 0x03a7af74, 0x9cf7eddb, 0xc72d74c1,
-       0xe49b2dbb, 0x366f1448, 0x18394117, 0x91cae85f, 0x88be3e69, 0x7ae693e5,
-       0x9f348c73, 0x8a79a6e4, 0x8195c1c7, 0x0fcd131c, 0x29e565ae, 0x66b9243f,
-       0xb2f14f9a, 0xaeb5b4f2, 0x4f9a28dc, 0xa3e5646b, 0xa3737bd6, 0x8f947e69,
-       0x39b75f95, 0xf3431b90, 0xf2b0b5d7, 0x67927eb1, 0x01b1f9a1, 0xd07f1f96,
-       0xf9a56795, 0x9f2cedf1, 0xcf37a1f5, 0x1d59f346, 0x5d4dfdac, 0x9a58bc81,
-       0xcac829bf, 0xf24ab96f, 0x2e4003ed, 0xb5cf980b, 0xd1c7e4e4, 0xe59dae7c,
-       0x4b16860b, 0xb7f4088e, 0x0858ee53, 0xb0867c22, 0x7e5125d1, 0xf1d8d3b3,
-       0x647d1510, 0x4baaf0a1, 0x2033fca2, 0xfe504593, 0x963af0b0, 0x19648c07,
-       0xbc2a3f94, 0x65bbe58d, 0x5cff9607, 0x46f2c038, 0x87ff9607, 0x7bf30870,
-       0xef961765, 0xf2c4fe10, 0xff961746, 0xf981385e, 0xcb1bb2fd, 0x962e853b,
-       0xfcb1ba37, 0x5753e949, 0xdf2fed3e, 0xdc2e9ee0, 0x5ddb7208, 0x6a597286,
-       0x597e0649, 0x04fff9cf, 0xaf2d0640, 0x3944641f, 0xacf3f3b8, 0xd3814517,
-       0x97c800f6, 0x05fa04bc, 0x485b3385, 0xc2827d04, 0x7386fb11, 0x349317cb,
-       0xa2f96e70, 0x20f3814c, 0x1fea89c2, 0xdc5f9d9c, 0x17cf1da4, 0x129c0ae5,
-       0x7fb5979c, 0xcbe5baf3, 0xbe78ed6c, 0xd4e054ac, 0xfeb89c20, 0x4f20278d,
-       0xc809c0d4, 0xe59c0aa5, 0x7fb12708, 0x271971e3, 0x8cb8e06b, 0x7538144b,
-       0xff506708, 0x378c04e0, 0xac63c76b, 0x863ce050, 0xbfd61e78, 0x534cb979,
-       0x5531e3b4, 0xc29e7029, 0x0ff6a4f1, 0x16ab6ece, 0x21adbb3f, 0x3847acfc,
-       0xaf37fb23, 0x3f169b5c, 0x7e10b6b9, 0x6b9c2136, 0xb76707fb, 0xdd9f8b4d,
-       0x5e7e10b6, 0xe98cfc43, 0x6372bcdf, 0x8dc9f8b5, 0x0de7e10d, 0xfeb8cf1c,
-       0xa26f678d, 0x137b3f16, 0x2009f843, 0x37fb1b9c, 0x2d24fc9e, 0x4293f27e,
-       0xe10779f8, 0x9c1fee4c, 0xfc5a49bd, 0xe10a4dec, 0x67080fe7, 0x95e6ff4a,
-       0x9f8b503f, 0xfc2181fc, 0x7270807c, 0xa94ccddc, 0xbdac70a4, 0x4c3fd9c3,
-       0xc3fd9f8b, 0x8939f842, 0x3852a670, 0x29c37de9, 0xa7e2d148, 0x9f842520,
-       0xb6e708f3, 0x9fd9c1fe, 0xfecfc5a2, 0xae7e1094, 0xfa3b9c20, 0xe182af37,
-       0x0c14fc5a, 0x55b9f867, 0x8672871a, 0xd8274eca, 0x9a19dfe7, 0xc13212e3,
-       0xd179624e, 0xf7a024ee, 0x433e8a88, 0xad225dda, 0x371cd96f, 0xd6a231fe,
-       0x068d726b, 0xaa56cf4a, 0x9af5a9e5, 0x1ad149d8, 0x15ce2a3d, 0x4c27c9af,
-       0x9fa9ac1b, 0x29a69458, 0x3ae7381f, 0xf720f94d, 0x487e4d78, 0xfa9a4dd9,
-       0x35736ac3, 0x6fcbe1f9, 0xf54fd4d7, 0xd3e4d4ce, 0xa9afdcd7, 0x8171b23f,
-       0xa69afca6, 0xb5f94d72, 0xfc9aa5be, 0xd7dfcdf5, 0xb2d31fd4, 0x437e5342,
-       0xf29a63db, 0x35278171, 0x9e0709f9, 0xb1bfd4d5, 0xf94d05fd, 0x68af63c4,
-       0x6c7727ca, 0x3e6fe4d5, 0xfd4d6bf3, 0x9addc129, 0xbd9fadfc, 0x439fa9ab,
-       0x6fab53fe, 0xd4d03f9b, 0xa13f6a9f, 0xf24eff29, 0x553d3a27, 0xccaf1f6b,
-       0x32afcc21, 0x01afd988, 0xc6f311ab, 0xa76616c1, 0x271c4b58, 0x7718fd29,
-       0xa00c742f, 0x033403f4, 0xe0ce5176, 0xe83a6bb2, 0xe4ddeff7, 0xbf4ec6be,
-       0xbee8cf7f, 0xbf411ec1, 0x9026f4a1, 0x061d4864, 0x8fe5f548, 0x73de8cca,
-       0xd51d5c87, 0x18d7db49, 0x68e2a382, 0xe73123fe, 0xf9c7a03e, 0x83ee0306,
-       0x42d49168, 0x411368bd, 0xd4d1e9bb, 0xaabd17ac, 0x1866b0fd, 0x308433d5,
-       0x3bb235dc, 0xc328f519, 0x9bd03af8, 0x79d187ea, 0xd164260d, 0xbcbb718a,
-       0x61fb6823, 0x8fe0c925, 0x3f991930, 0x91bfd424, 0xfd819ff6, 0x6bfe812f,
-       0x94dfe97a, 0xbfd34936, 0xd34ca539, 0xfb48d9bf, 0x90f213b7, 0xbfde26e1,
-       0xcb36fd19, 0xfec64c56, 0xd865294d, 0x6a46a3ff, 0x8ffba977, 0x88fff50e,
-       0x31ebf681, 0xc7b9bb30, 0xd26ed3fc, 0x5ca53fce, 0x9b237f3b, 0x2e434aff,
-       0xe71a3fef, 0x0e456abf, 0x394a7f9b, 0xc189bf9b, 0x0b6ff50d, 0xfa01bfe1,
-       0xfd2f69ff, 0xb5b3d29b, 0xa95e1ff3, 0xf589bf9d, 0x76e194ff, 0xfb05bfde,
-       0x6dc57a7f, 0x2bc3fe6c, 0xc9a37fb1, 0x31fa04ed, 0xf5ae890e, 0x50c9fed1,
-       0x040d256a, 0x40fda172, 0xfd1e3a3a, 0xd21a7708, 0x8bdf1c70, 0x2576f466,
-       0xf21bd29a, 0xc3b32f33, 0x5273947d, 0xd39aaabb, 0x1ce6c57a, 0x2c3df023,
-       0x3164224f, 0x36a2ea1f, 0x3c9be911, 0xa48df26d, 0x26d0bde3, 0xe8bf217a,
-       0xe03e29e9, 0x322635af, 0x49da08bf, 0x3fdf0024, 0x1798d9fe, 0xa7d2f3d4,
-       0x53e51b8b, 0xde45fc91, 0x96ba325c, 0x1002ef8e, 0x9c7f2a81, 0x186071da,
-       0x1eed487f, 0x139fed42, 0x23efeb32, 0xbe41ef6a, 0x687bda83, 0xe63a9338,
-       0xdebaf357, 0x5fc7411f, 0x0b9f9444, 0x6e2f79e7, 0x624f0a29, 0x5af8f7fb,
-       0x31eb07c1, 0x450c797f, 0xc53c787e, 0xbe4d04de, 0x07eac4c6, 0x2f7c136f,
-       0x0dc30808, 0xe1c199f8, 0xcd2f1811, 0x36b3b1cf, 0xb1de7747, 0x7dd1b05f,
-       0x5d0866b4, 0x599c308b, 0xa40f25c4, 0x565eefed, 0xa76b832c, 0x8186105d,
-       0xa166b09f, 0x3768024c, 0x0649137b, 0xde3a0e27, 0xfe0cedfb, 0x527c970c,
-       0x239b47ed, 0x74455d9b, 0x458a733c, 0x69acff1c, 0xed3ff2da, 0xc619718c,
-       0x53cd74d2, 0x45ddcfd8, 0xe77bf2da, 0xb9f7f368, 0x572a79b5, 0x0fab9065,
-       0x53bfe994, 0xdf8124b4, 0x001bf431, 0xe3907ce3, 0xd95ac1e1, 0x6a5759ab,
-       0x72951b76, 0x09b88470, 0x8bdb0bce, 0x5fcfeb3d, 0x7b17cdae, 0x6b85f9b5,
-       0xdd39f074, 0x7febe29c, 0xa683e81c, 0x283e81a7, 0xfa724f3e, 0x2d55f308,
-       0x9a13dc7d, 0x650fa306, 0xb624a71e, 0x33d6a704, 0x18dc58fa, 0x8a1e9913,
-       0x52e0f443, 0x0f4297d3, 0xfc3d38f3, 0x6943d399, 0xeeae9693, 0xc9d5be23,
-       0x6b03fdb4, 0x1d3ae177, 0x3d198a11, 0x87a140fc, 0xb83d0d0e, 0xd7e83d39,
-       0x87a71e6f, 0x7a308f79, 0x0767afd0, 0xa68e87a7, 0xeb4932cb, 0x1d74aeb9,
-       0x0eba7934, 0xa3b775ba, 0x47ae8a1f, 0x10587a44, 0x389d379a, 0x65e42fcd,
-       0xd38bd63d, 0x01a79603, 0x09e209da, 0xacf7a7db, 0x2684f94f, 0x7914da5f,
-       0x36da6bfd, 0xfaa93dac, 0xf2f2d55e, 0xbb7fb55a, 0x268b79a2, 0xa6f7c4bf,
-       0xd3697ea6, 0x717e4d2e, 0xfa9a3be3, 0xd21cd70b, 0x7fbd8be4, 0xbf9fd4d4,
-       0xfe5353bc, 0x4d59ed60, 0x176503f9, 0xdcfbf935, 0xbfd4d37f, 0x13f08e77,
-       0xa2eefe75, 0xeba89fa8, 0xa7169acf, 0x0d70cfc9, 0xec37d4d2, 0xa02ef6bc,
-       0x8bef83c7, 0x4f8ff404, 0xffd1a79d, 0x7653a9f9, 0x1e939d42, 0x5383ee07,
-       0x9e98d19e, 0x9f7138f1, 0xc24cf39c, 0x1edb42f4, 0x2a15c80b, 0xc8e04b47,
-       0x96e574a6, 0x20d935ba, 0xdfca09d7, 0xd46f958a, 0xb2128779, 0x8a639414,
-       0x2326c2ef, 0x44204c09, 0xc7c4e100, 0xe5551415, 0x37947d1d, 0xd0914151,
-       0x23b0bcb3, 0x279af7f2, 0x23db878b, 0xf7847f9c, 0x7a021935, 0xe72f7752,
-       0x29029524, 0x64277f52, 0xad81f205, 0x34a94f5c, 0xb9517e32, 0xb12e5075,
-       0xaa303e41, 0x6bfaabf6, 0x206c9ba1, 0x66ba49d0, 0x5d36973f, 0x04f7e1af,
-       0x4089cfbc, 0xdf34136f, 0xd66f9a2b, 0x25daebb4, 0x81abb8e2, 0xfdb95097,
-       0x527a292a, 0xd8153e04, 0x0c6b3293, 0x14f5d38c, 0x5112dbe6, 0x34f2ec8f,
-       0xc7f385af, 0x4c169e73, 0x30da78cf, 0xac09e53d, 0x93c07385, 0x1e98039e,
-       0xda63b4f7, 0xe98639e1, 0x4c0e9e47, 0xc19cf43f, 0x209e4ff4, 0x9f3cc7a6,
-       0x43c47a61, 0x0e70027e, 0xfe98cc7b, 0xb4c763c1, 0xe98c93dd, 0xfb0f8f05,
-       0x5f5df651, 0xcb867774, 0x7f4073ed, 0xbb6ce811, 0xcd6eac78, 0xbd9d30d0,
-       0xa423f2b9, 0x85cf0533, 0x0f4e264d, 0x087a1a49, 0x2377ed80, 0xe51f4bd0,
-       0xc3a7324d, 0x2e47dade, 0xbfe179af, 0x7caede87, 0xd30b7a4b, 0x3d1d10d3,
-       0x4f45f7a5, 0xe9e9aa1f, 0xe4cec18a, 0x1fa7a720, 0x7d6b73f3, 0x3b1251bf,
-       0x77e90ca7, 0x800cdbae, 0xdcfca5aa, 0x98699084, 0x5efbc4bf, 0xa3b5c149,
-       0x0d1be81e, 0xe8d2eb72, 0x73828fbf, 0xe8c74b87, 0x3ef6a7e2, 0xf49d3d3f,
-       0xda17778e, 0xba3e2543, 0xc61109e8, 0x1af0cd1b, 0xc8d32065, 0x461a4278,
-       0x905ce4be, 0xc4897981, 0x739f7b43, 0x3af38446, 0xc06b7542, 0x5d785f6f,
-       0x1632bd69, 0xf67a9de0, 0x5e90591f, 0xf475fae1, 0x7cf5111e, 0x09d17812,
-       0x25c90df8, 0xfc193393, 0x4691c1f3, 0x6409ea3b, 0xde7f16ba, 0x6bf835db,
-       0xcfce5548, 0x7f11931b, 0x1a8cae23, 0xf5fc0fd4, 0xc2fbdfc5, 0xf79802e7,
-       0xfb3e037f, 0xf17d8fe2, 0xbc72e245, 0xdfe746d6, 0xf8cc73bd, 0x07c01cc7,
-       0xcadf1abf, 0x3c7e9c79, 0xb5f492f9, 0x493bb8e8, 0x14f6e3a1, 0x24d85b88,
-       0xa5fe11da, 0x61626bd6, 0xfa70425d, 0xede14f58, 0xbd80a73f, 0x0b553e7f,
-       0xef074b2f, 0x6d1781d2, 0x4d2d7760, 0x3270d85e, 0x69283ac2, 0x835d4b55,
-       0xb687ad45, 0x1a97f369, 0x382d6985, 0xecec472e, 0x6a272031, 0x5edf181b,
-       0x6702a98e, 0xf6097269, 0x3d39ae73, 0x3e7bd996, 0xc7360fc6, 0xe738bf21,
-       0xfffac329, 0x06f4f1ec, 0x210f1947, 0x1984e4ad, 0x4b2d31f8, 0xaf7ebdef,
-       0xc5fd2cf4, 0x7edde788, 0x89e80af9, 0x97dffa66, 0x09107760, 0x9adc0af3,
-       0xba6bd116, 0xd66fbe01, 0x39db47f4, 0x2fe23394, 0xdf6abed3, 0x4294e448,
-       0xd45e54b7, 0xe780bd83, 0xd41a4b9b, 0xcb55597a, 0x9af93577, 0xd41a47b6,
-       0xfc055c7a, 0x525ff283, 0x3740482b, 0xba8c9c95, 0x811acb25, 0x8218af8e,
-       0x088f804f, 0xb9955eac, 0x9fa6e8c3, 0x75b2b7ce, 0xe77c6deb, 0x8854e63c,
-       0x3733283b, 0x597239e2, 0x20f9b5cb, 0xaeb7ce67, 0x5bf9024c, 0x5efa5e21,
-       0xbff68451, 0x5f2e0494, 0xcf56a0e4, 0x2841f4e7, 0xe9bcd55c, 0x17c212cf,
-       0x981977cd, 0xb70f465f, 0xbe91cb8d, 0xf9bd53f0, 0x8ecdc150, 0x6eaa789e,
-       0x237468bb, 0xcbffa45f, 0xc149e30a, 0xd454b15f, 0x9771d126, 0xffa27737,
-       0x1dec8ce2, 0xe0af83f5, 0x67e73d97, 0xa3153e49, 0xb497979a, 0x260b3f43,
-       0xe3888ef1, 0x1f280fde, 0x995bfb3f, 0x57221f00, 0x742cad69, 0xc7bb70cd,
-       0x61590c40, 0x6b4167bb, 0xfbe02145, 0xd1d3ebec, 0x8a445bee, 0xa40eb86c,
-       0x9cec0b31, 0x7180c4f3, 0x1fc9e755, 0xeb54136c, 0xe464b1f0, 0x305ca678,
-       0x1034bb89, 0xd8107bbe, 0xf539a65f, 0xf858e2ed, 0x9076292e, 0x15ca25f0,
-       0x17f180b7, 0x2f77d873, 0xfd01d731, 0x634a7b52, 0x4a7b51af, 0x94f6a793,
-       0x66425f26, 0x453c4126, 0xf132d3c9, 0x4d278809, 0x8ec941f9, 0xb5252be3,
-       0xfd1fa0f5, 0x16e1fb9c, 0x843489d8, 0x37aa87ca, 0xa62acb9e, 0x9892e9f3,
-       0x0f894bff, 0xc5654258, 0x5e5e5a20, 0x2cba33e6, 0xa277e73d, 0x943dc275,
-       0x163c03f3, 0xd1bf7007, 0x886be2c7, 0xaae2ca43, 0xf3ef5a4f, 0xba2ad81f,
-       0x8f506ca2, 0x9bc6577e, 0xafe7f5fa, 0x4f212f9f, 0x9bca3ce2, 0x561c6067,
-       0x3e07788f, 0x7059b91f, 0x27ec22f9, 0xf1341651, 0xc332092e, 0x1ad7e29f,
-       0x0f5fcbae, 0x6bdf9579, 0x1bfcaea2, 0x440197f3, 0x258a5fc3, 0x913970f7,
-       0xbfc013f1, 0x7f710520, 0xc9f8637d, 0x2f5fe03d, 0x844ff8df, 0xefbb543f,
-       0xff89fc29, 0xe88ff1d4, 0x48bcfe31, 0x78deabf0, 0x778875f5, 0xcfd5ff2c,
-       0xb7ee846c, 0x926352b3, 0xe57bae93, 0x1736d5a6, 0x6bc91df0, 0xd6717d83,
-       0x448b4e27, 0x7997df0f, 0x59711fdc, 0xc2bbf004, 0x73fc293f, 0x4ef8fcaf,
-       0x6caea3b0, 0x4fe8ed92, 0x4c05366d, 0x5bab9e94, 0xb1921497, 0xf964ef98,
-       0xfd022f47, 0xc7c9b4d7, 0xfe5a74d5, 0x41259fcb, 0x94a5107c, 0x48648621,
-       0x549f6803, 0x00b8fc6f, 0x121a8df4, 0x6faafdc4, 0x167ffd07, 0xd8b0f28f,
-       0x1cb3db18, 0xd049341d, 0x5a6afd9e, 0xb4517c7f, 0x69db7a41, 0xb2d46fe0,
-       0xbe90bf44, 0x3bb7195d, 0x00eb642a, 0xc913abe4, 0x0aabe044, 0xd98f885e,
-       0x7e5f2b1d, 0x1d276c66, 0xdfc6d757, 0xbe1504da, 0x52e97b14, 0xfc5fc2cb,
-       0x1f3bd1da, 0xa3f740bf, 0xe455bf5a, 0xdb8da394, 0x56967e4b, 0xc41b01ca,
-       0x906e5573, 0xb9fa5e9d, 0x5f17d5f2, 0xd9fc167a, 0x4739347f, 0xaf15f852,
-       0x13723bee, 0x916c57cd, 0x69b21407, 0xf0a48458, 0xffd0d4fa, 0xaf0f8f96,
-       0x7db6f947, 0xf618c746, 0xe1f187fd, 0xb2d8a975, 0xf4c648cb, 0xcb5e47c4,
-       0x2587632e, 0x74b4fac2, 0xb7fe8016, 0x1abfe5f2, 0xdd9def81, 0xa9819029,
-       0x61b9f011, 0x8087ea1f, 0xbe4f5c27, 0xd3f5a15e, 0xeba1afd5, 0xbf467202,
-       0x857afa5e, 0x5c00bf9c, 0xf4a1b388, 0x21afdafd, 0x264fee0e, 0xeca1e027,
-       0x306c87b5, 0x2d52d39f, 0x56e7f3a3, 0x2bbf0127, 0x7649bd93, 0xb2f7d94c,
-       0xfa461fe7, 0x70f43d2b, 0xba57f312, 0x76501906, 0x3cc1077a, 0x1bbfaf17,
-       0xdc4259e7, 0xcf658748, 0x9a3e4589, 0x69912a7e, 0x93ec225b, 0x9c9f7c4b,
-       0x2e2e817e, 0x4569e79d, 0xe441fc2e, 0xe8bbe172, 0xcf987d0f, 0x98906a85,
-       0xd6ccd4ff, 0xd06c80eb, 0xfd10d1c8, 0xe5147c6e, 0xae61b9c7, 0x56ee7081,
-       0x28179613, 0x5343c447, 0x6275b207, 0x51db0772, 0xdf0793b9, 0xecbb7ea1,
-       0x69ab1a8a, 0xe9467287, 0x9fef197f, 0xf41a3b8e, 0x9149d3b7, 0x46e191ed,
-       0x3d500f85, 0xaa674543, 0xfff6cefd, 0xdfb606c6, 0x9beffd95, 0xffca0d31,
-       0x23ed9872, 0x97720768, 0x10302b8e, 0x16cd77cb, 0x48983f90, 0xdf3ed220,
-       0xae7df328, 0x0bd3d72d, 0xc424bf1d, 0xfa06e8aa, 0x4075c789, 0x34f25f79,
-       0xa3e2af6d, 0xadafd035, 0x1f655c27, 0x707e7297, 0xf5c1f81e, 0xd6407e61,
-       0x5e2bf627, 0xbdf652b4, 0x5fec2cf4, 0x0ebd5fba, 0x1172bfd8, 0xcd93ffcc,
-       0x4fdc8e7b, 0x2d27edf7, 0xf2d5beca, 0x2dbefd55, 0xc630fadb, 0xedf7eb9f,
-       0x496b4327, 0xbf4b7dc4, 0x43b7dc47, 0xf847fe3b, 0x24c782aa, 0x2aaf96a3,
-       0x7c37b27c, 0x16e4f9ea, 0xd57881d9, 0x3bfa49f3, 0xd27ab24c, 0x0a8742a3,
-       0x47ff95fd, 0x47e070d5, 0xe8553a21, 0x0aa74430, 0xade7ea1d, 0xfcbea3c5,
-       0x522df023, 0x537a297a, 0x4a95f3c6, 0xa6038b3f, 0xc90ff6ed, 0x50b97c44,
-       0xfdc691cc, 0xf3a80643, 0x45be5d3e, 0xcba5df57, 0xbbeae917, 0x4d5af975,
-       0x3db6cafd, 0x10748246, 0x9713d4d0, 0x31393bff, 0xfadd1221, 0xf5a1bf98,
-       0x39ee11a2, 0xd88258d4, 0xbc415e5e, 0xdc191f10, 0x51b9e221, 0x3d71c537,
-       0xa73637f8, 0x8f94bcfa, 0x7e628eac, 0xd07b6e85, 0xd5d34f16, 0x4c1f2c71,
-       0x1f03d634, 0xa307be54, 0xbbb1df98, 0x538b6828, 0x7e9d5bd9, 0x8778f911,
-       0x0dbdf22f, 0xdd70692a, 0xd7b97a3b, 0x758f9ca1, 0x62c6db47, 0x3e29d17f,
-       0xa2a9c7a0, 0xf8396525, 0x27451aa1, 0xea8bece8, 0x79c1b5ee, 0xfd3fb755,
-       0xfbf439ae, 0x164477e2, 0x4975e38e, 0xd0765483, 0x975de219, 0xf05c402d,
-       0x859fa45a, 0x2d17667e, 0x3f791b5a, 0x2576f394, 0xe0466596, 0x390ed4bb,
-       0x51ef3eae, 0xd7ad94e0, 0xe74ff77d, 0xed11a6fb, 0xda8df2ff, 0x9fb73772,
-       0xfce4647f, 0xc7191c67, 0xbfe657ed, 0xaa7b7ce1, 0x1cd77198, 0x07dd3eba,
-       0xf9a26244, 0xd7117e4b, 0xc166d2e7, 0xe237fe07, 0x57fdc44d, 0xf546824d,
-       0xd82e887d, 0xcef4d75f, 0xffb6bac7, 0x4007eb39, 0x307faf47, 0xda69dff6,
-       0x471ffaf5, 0x37f905bd, 0x407ca68e, 0xdbcfd67a, 0x02f18519, 0x48ad3bdd,
-       0xde3bddff, 0xe401f94b, 0x613934df, 0xff3bdd9c, 0xa9e8163a, 0x0ca9857b,
-       0x30f760f8, 0xb95dbfe6, 0x3b63afe3, 0xc2aefe50, 0x1a366c75, 0xffc99f99,
-       0xdee08f8f, 0x9d3f25c2, 0x3c17e815, 0xd7e6beae, 0xf0823e51, 0xbea59aff,
-       0xe76df40f, 0x43e3cd53, 0xce64adba, 0x1c5f1856, 0x79a87f8b, 0x758bf26b,
-       0xd6aaffb4, 0xb485c65d, 0xcfedef3c, 0xfd1c62c7, 0x5d37a656, 0x879e3b90,
-       0xc66d87f8, 0x2994acef, 0x26c02f9e, 0x5df646a3, 0xb07935a6, 0xe5e27a8f,
-       0xf5a7f473, 0x1aef1f17, 0xaffd7d99, 0xc5c10f8f, 0x67d59ff8, 0x7fde6016,
-       0xf403e8fb, 0x2e909a83, 0xd27ef995, 0x4cfa8752, 0xfb3ef35f, 0xfa0e86bf,
-       0xd0216f3b, 0x4d9b799f, 0xfdebdaff, 0xeb81d1b8, 0x3d07dfa2, 0xf7c77ce9,
-       0xd5aaff30, 0x27ede389, 0xfd368fbd, 0x5beeb63f, 0xfadbbae9, 0xfe77f79e,
-       0xfbdde7c5, 0x8f33bfba, 0xce1dbbaf, 0xfede6b53, 0x75f7c71c, 0xffe95cf9,
-       0xf457ba52, 0xad4376fd, 0x6f8e933d, 0x82b4690e, 0xe25f7162, 0x03a64b25,
-       0x0f2f70a2, 0x383bf8c0, 0x57608d5f, 0xbf989935, 0x581824cd, 0x82dddabc,
-       0x3b4447e2, 0x5fae4eeb, 0x0cb439dc, 0x5d3b90f5, 0x827d413f, 0x39edb548,
-       0xee7b7eb4, 0x6ac62742, 0xdcc7f192, 0x853d9f90, 0xe6f6b5e7, 0x12e204ef,
-       0x677f7ea8, 0xa003f4ee, 0x12e5dee7, 0x29a60f51, 0xa7efbfea, 0x93efb014,
-       0x7dd0f6b4, 0xdefe6d6e, 0xddfcda39, 0x843dde1c, 0x229eff8d, 0x587e07c1,
-       0x8953ce53, 0x2d3597e0, 0x0a908996, 0xabb54671, 0xbbb8eec1, 0x197edb48,
-       0x7f2a6728, 0xe3c537e3, 0x5c78436f, 0x3921788a, 0xed03de22, 0xdc7c8f13,
-       0xf9c7b3ed, 0x489ace20, 0x7bc7864e, 0x37e89caa, 0xccb8f6e7, 0x3596cbdb,
-       0x659fb0ed, 0xd8ae1d9d, 0x9be1bdd3, 0xe11cfb70, 0x2ff185a4, 0xcfb444bb,
-       0xae7d9d65, 0x5dd7cbac, 0xbf1d650f, 0x073cbaed, 0x786372eb, 0x5c5a865d,
-       0xccabf604, 0x8b7c87ed, 0x1687e593, 0xe8ae7611, 0x00d2fac3, 0x8466f117,
-       0x9897d1e3, 0x9ce02b8b, 0x405a3ccc, 0x6b5dc87f, 0xe60f9445, 0x55c7010c,
-       0xf8c64934, 0x450d8fe3, 0x85deb059, 0x7f562613, 0x09c30d9f, 0xf1c25cf8,
-       0x516a425e, 0xbf57257f, 0x0b3b32fc, 0xea0825ce, 0x845c4bbf, 0xb8ed41dc,
-       0x10216c92, 0x126af10d, 0x078ec6f1, 0x8e40b93f, 0xdae4fc6b, 0x496efc3c,
-       0xabe9c30a, 0xe5fc6f7e, 0x17fe9d9f, 0x29c767e5, 0x3a427491, 0xd497bb12,
-       0x3f7cf776, 0xa54d63c3, 0xba434be0, 0xfbeac80b, 0xb66605d3, 0x87ebfe0f,
-       0xe64f9013, 0x2c4c74fc, 0xe26407f3, 0x6e1ac47d, 0x3af25c37, 0x760fc162,
-       0xcfce9fc9, 0x6a6cf373, 0x87a4aabe, 0x9ffe1db8, 0xd3489710, 0x51a17cee,
-       0x048b3b04, 0xcdebffd1, 0xc57bc28f, 0xcca376fa, 0x6bafbe06, 0x3f002fd1,
-       0xf2afee11, 0xa6d29479, 0x75aaf1b1, 0x59c77b5b, 0x75cf6c69, 0xd571df80,
-       0xc5b7ddf9, 0x80fdd82f, 0x1d5143d7, 0xe6114505, 0xafe3893b, 0xf0dff770,
-       0x7f4ceafe, 0x99780caa, 0xce6a2f99, 0xee669df9, 0x264098cf, 0x770ab8c0,
-       0x0c9b66df, 0x744072eb, 0x1ad57dc2, 0x3ba345ff, 0x1eb1f9c2, 0xfc1f009f,
-       0x676427f0, 0xc4f3e009, 0xd808a24f, 0x73f1efd5, 0xcfb80cc9, 0x1eae8191,
-       0x731df817, 0xb84fcccc, 0x74c76cce, 0x9c8e6156, 0x68cdfb48, 0x50838fb5,
-       0xfebcc1b5, 0xcb03b33a, 0x4a76f087, 0xac95c1bd, 0x5ed1a75e, 0xbffe691d,
-       0x79f8128b, 0x937bf399, 0x75bd7f84, 0x35a9f9cb, 0x41fa0b90, 0xd167e2be,
-       0xfdc135d3, 0xe09a6971, 0xf60df903, 0x050be630, 0x53de1fd4, 0x64cfafee,
-       0x7ba15672, 0xcdab9e3d, 0x1e02f7da, 0x887f78e7, 0x678287d3, 0xf1fabf05,
-       0xbf29f52a, 0x9fed55ba, 0xdc6dabba, 0x54dfa06b, 0x81bb05fb, 0x3a96aa82,
-       0x6b0fb08c, 0xe1909eda, 0x073ee67c, 0xa2a44b83, 0x83f8eab1, 0x0f166675,
-       0xcdfc67b2, 0x2e4e80f3, 0x2c8135af, 0x1745ae24, 0xdf87c06d, 0x0f7f3833,
-       0xdfde6c71, 0x57d36489, 0x3c0fabf0, 0x597cf2f6, 0xe715370d, 0x4732ab33,
-       0x03da7706, 0x81e4bb95, 0x675a7a2a, 0xe572c78e, 0x074ae0fb, 0xfb420fbe,
-       0x1f7871c3, 0x4fb81137, 0x8ed2d192, 0xa81f6cf7, 0x5874638d, 0x88cbb2d6,
-       0x7bcd54f9, 0xfa3f4a22, 0x50bb34fd, 0x30bcaf1b, 0xe02863af, 0x5814d0a5,
-       0xa7408ce6, 0x7394a393, 0x2729afca, 0xc76e945c, 0x27247ffe, 0xa2722996,
-       0x95e3e303, 0xe7df02f6, 0x3031392a, 0x5a589c92, 0xeb0818e7, 0xfa4774b0,
-       0x4b24d840, 0x149a99df, 0xefbc4e49, 0x47cce761, 0xeef67df9, 0xdc4e54d9,
-       0xb31392a0, 0xf44e90a3, 0xf6513eed, 0x42725f49, 0xcbffb759, 0x907de6fc,
-       0xf7f61113, 0x71393a17, 0xe518bf8f, 0x45b33dc4, 0x4facbdcd, 0x391394fb,
-       0x5e61f749, 0xa044c676, 0x7db9f79f, 0x0bdf9473, 0x5e407e80, 0x11d94664,
-       0xd1b97a6f, 0x53ff5f1b, 0xfffaf97f, 0xbe159e10, 0x3fda94be, 0x7448d4a6,
-       0x979e9048, 0xbaf947de, 0xf8c8f400, 0xb907d2fa, 0x67c7539f, 0x66cf808b,
-       0x6b2cf9aa, 0x7266ed5f, 0xf52da6a1, 0xfcb4b999, 0x09d946fe, 0x30fef2a2,
-       0xf352cddf, 0x5ea8ccdd, 0xe3196ef8, 0x13fd97bb, 0x6dea7f50, 0xfce67f7e,
-       0x11b3f296, 0x31f408ce, 0xe68c6e67, 0x7189dede, 0x06d8c9bf, 0x113de5fb,
-       0xe63f79cf, 0x71c1c07a, 0x7d04c9bf, 0x9e3e49fa, 0x2f3d7c79, 0x3e794878,
-       0x22de5fc5, 0x6d574fa6, 0xd57f1116, 0x57ff6cad, 0x073e0b37, 0xff8c17cd,
-       0x56d79e1b, 0xb5e760ec, 0x39850674, 0x78aff5aa, 0xce1ea3af, 0x08362a09,
-       0xf70cde78, 0xa59f001e, 0xce259f1c, 0x29573c0a, 0xc1fad26d, 0x2f6da21b,
-       0x1e101b90, 0x78abc3fa, 0x105342fd, 0x7f0a1dcf, 0x20373829, 0xabb6d49f,
-       0x59fb711a, 0x9a2a4fb0, 0x0d9ddf75, 0x3704ae78, 0xadaf41d4, 0x7b96d16a,
-       0x8b17bcf8, 0x146d8c81, 0xb33df93e, 0xf778f4f3, 0xf653f1e8, 0x8873f12d,
-       0x9ff327e2, 0xfe259f87, 0xf05e785d, 0xc7a2f175, 0x3f145d47, 0x324f181f,
-       0x6c7e3f61, 0xf17f2170, 0xbbe22bbe, 0x189e8b4e, 0xe50f79a9, 0xef2f1ca7,
-       0x83f5dc19, 0x80b55ea0, 0x6fd74af5, 0xf34497d9, 0x38c85b73, 0x6d286638,
-       0x90e3cad2, 0xa0756ffc, 0xbb5b9f7c, 0xdab88045, 0x60befcc5, 0x7c09ef99,
-       0xe5c1e63f, 0xfad3de54, 0xdc9bc70b, 0x287e5e70, 0x53fc882a, 0x409ddfa1,
-       0xfa6f94bf, 0x0c4e38f9, 0x9ca3e60e, 0xb8ec136a, 0x4c51032f, 0x8275d16e,
-       0x4cf66d77, 0x5f016bfe, 0x6a5fe617, 0x4358eb63, 0x75f60dd7, 0x5be79f81,
-       0x80f83e98, 0xe73b22ff, 0xd992eff4, 0x490238fb, 0x44e77e40, 0x8f915cfb,
-       0x939aee70, 0x1ddf5aa4, 0x37fe8c9d, 0xe0fc4e09, 0x36fbffa3, 0xbacbdbeb,
-       0x7f4cfa2a, 0xd3c157d7, 0x1f3add4e, 0x9c2f6a8a, 0x8272e780, 0xf20bdf13,
-       0xd179e1c7, 0xfef646c9, 0x1fae41cd, 0xd805f7e9, 0x78f7ea1f, 0x21c0c066,
-       0x145a7a2e, 0xbf6295c6, 0x533f4c69, 0x3bfd29f3, 0x6e375f48, 0xa3b486a9,
-       0x7f8e165e, 0x066edf74, 0xd04d3fb9, 0x19d149c4, 0x27ffbee1, 0xbea397c0,
-       0x36493e02, 0xc8797ca3, 0x19eebece, 0x1ef02466, 0x3235e5da, 0x06bdd1d2,
-       0xe06c91c7, 0x04c98f2f, 0x83e5c7f6, 0x3b9d1e37, 0xa445ca00, 0x26f7e28f,
-       0xa56b8354, 0x91aac598, 0x5c9847e2, 0xfffbc13a, 0xaed79513, 0xa097786b,
-       0x7ce27b07, 0xb674bf70, 0x0754d773, 0x0f325bf8, 0xcf7386ad, 0x23f67959,
-       0x1b1d6047, 0xc74fbbd8, 0x9da1e4d7, 0x0577d0f6, 0xe8c767dc, 0xbb9c017a,
-       0x391ea767, 0xe0f7c742, 0xb73c449a, 0xbc4aeb9c, 0xe731ce07, 0x0e9d141e,
-       0x5de16f5a, 0x7f9c0b56, 0x122d1f4e, 0x0f2f0ab7, 0xeff47692, 0xeefdadcc,
-       0xca4fb0dd, 0xf7843ca8, 0x87fcca9c, 0xfc840ea6, 0xd7db017a, 0xb846dd78,
-       0x74ded9e7, 0xfb4998d1, 0x00f5a12f, 0x59eb35dd, 0x028d9abd, 0xe25817be,
-       0x64f9027f, 0x1f0146c9, 0xfaa769c4, 0xf5c199af, 0xbed12981, 0xf9a7b69e,
-       0x700f6852, 0x03ddc637, 0x743593e7, 0x527ed89c, 0x97539e1d, 0x98b476d0,
-       0x2efc6fb4, 0x5eb25bc2, 0xb0af7020, 0xe3ea526c, 0x41de0093, 0x47e509d9,
-       0x08dcfd77, 0xfb479ee3, 0x2fe1441b, 0x42a63b14, 0xc103f27d, 0x152eef8e,
-       0xbafb8b5e, 0x623bef9b, 0x14e2cd1f, 0xefdca204, 0x2af1d493, 0xb869d125,
-       0xd7964a9f, 0x3abcc3d5, 0x06a989bc, 0x468ba7a4, 0x2927e390, 0x7f54ddbe,
-       0x7164613d, 0x27bc7b30, 0xfe2a1d8c, 0x1d3a32b9, 0xcb6a2fdb, 0x98b33e41,
-       0x853c6114, 0x23e98ebb, 0x7ca3ab9d, 0x94eb57e0, 0x7df029ed, 0x7e136acf,
-       0x932af0bf, 0x7586173b, 0xf4fb7fa0, 0xbdc0997a, 0xd3eb95c7, 0x9e3ac1d7,
-       0xe13b2cde, 0x8e7c40dc, 0xbe9411c5, 0x7b64fcca, 0xa7b833d6, 0xcb7f199b,
-       0x02eeee7b, 0x94a5dbe0, 0x7e70994f, 0xe2563e5a, 0xf53e4728, 0x4be3145c,
-       0xe7a57e7a, 0x1b8d6553, 0x65a1cb22, 0xd0e59105, 0x37ee7ad0, 0x6b9f2c8d,
-       0xbbe98588, 0xf078c9e3, 0x0d571663, 0xf404d79b, 0x70bb20fc, 0xf3781ed0,
-       0xdc819fd3, 0x3be2b4ad, 0x7d92d565, 0x83e8c09d, 0xeb9fff00, 0xec29f2df,
-       0x51b9b287, 0x29d90ef8, 0x47d80f58, 0x1cf0136b, 0x8c57c4bb, 0x79e25778,
-       0xf4b49b4b, 0xef21f8ae, 0xa5c48b73, 0x31655f96, 0x77aaa5c4, 0x6e9447f4,
-       0xdbf33f69, 0xcab01f04, 0xdcea3fa3, 0xe62670ff, 0xe5ae38ed, 0x6b583f5c,
-       0xfa3eba45, 0x40d5c5c8, 0x287ef3b7, 0x89dbd010, 0xf20f5dd7, 0x7049bab0,
-       0xf4b89f80, 0x297dac87, 0x3ee30f6d, 0x5f4673fa, 0xb01dce94, 0x3fd7aa0f,
-       0x6feb1fb1, 0xff001c14, 0xd46286e8, 0x22bcca27, 0x9d8df2c1, 0x79504768,
-       0x7b68f185, 0xec1262bc, 0x2655ea83, 0x1562b83b, 0xb3e8527a, 0x40a7bf93,
-       0xb3b1cecc, 0xb4673b68, 0x9eb2f903, 0x4239c52e, 0xfd029e48, 0xbd1978d4,
-       0x3b2abe75, 0x4df48b61, 0xbd1eec9f, 0xd0227f42, 0xfe98665f, 0x33cfacf6,
-       0xf69e3d02, 0x91671809, 0xf40bf407, 0x9fe2b2f9, 0x1eb51621, 0xea7d17d5,
-       0xfd07b0e9, 0xe958cbc1, 0xe854fa61, 0xc7874f51, 0x8c0f7225, 0x51d5a1fb,
-       0xfabc8f38, 0xce59ef37, 0xcf9e19f6, 0x923fd5e5, 0x44bafb04, 0x0a407162,
-       0x1624ab5e, 0x5c63d637, 0x0719d74f, 0xba7c67f5, 0x0e8acc71, 0x20f1edc9,
-       0x4a3ea9b7, 0xdf9fb402, 0xe3117e6c, 0xd2bfcf2b, 0x37ea2779, 0x003a516f,
-       0x92b66ffc, 0x3e21da00, 0xade547e4, 0x1369c622, 0x4b359029, 0x712bbf65,
-       0xb2bf1531, 0xb7cbbe22, 0xb4857c9a, 0x27ebf97d, 0xc25c62c6, 0x7b7fa60a,
-       0x39d8115f, 0x2c63b788, 0x972a3bdc, 0x5e8e7c58, 0x345df82f, 0xdebbc3b3,
-       0x7a03998c, 0xdeccd09b, 0xb96f2c17, 0xfca93657, 0x65a2fbbb, 0x939e1ea5,
-       0xc33ae979, 0x3e300afb, 0x4a76fbf5, 0xcbd74e5c, 0xdbcafe8c, 0xcae7d464,
-       0x805cb79b, 0x63f2cd78, 0x6b77b426, 0xc11a2f9a, 0xd5fbcd9e, 0xc41decab,
-       0xa7135136, 0xae3e23d7, 0x20980c59, 0x0ab5abae, 0xbe6871cf, 0x3c2df313,
-       0xc66bed1e, 0x6afc556f, 0x8a5eebc7, 0xbf6d8ac2, 0x857be1b4, 0x786c9bed,
-       0xabf9aa5f, 0xc47b55e3, 0xf034b5c3, 0x4e3bb878, 0x918fe413, 0xc1cee1e3,
-       0x7d21283f, 0x878dad16, 0xbf8ccd23, 0x456671d1, 0xa4350f7a, 0xe9fabd77,
-       0xddcf10f3, 0xe793f5b5, 0x5f95dc61, 0xe21e7e5c, 0x6882a86c, 0xe6a53d07,
-       0xfe31f795, 0x1f176955, 0x97a0edc3, 0xc3f1897f, 0x7268fe17, 0x3b0bb402,
-       0xfe80a74e, 0xdfcb6171, 0x782e2092, 0xe8a98ed9, 0x3db659df, 0xedbddf0f,
-       0xfa059ecd, 0x7e23f5f5, 0x7b6ebf59, 0x3c60f75a, 0xeeba79d0, 0x714227c0,
-       0x2c552d8e, 0xe3c1d47e, 0x8e47371b, 0xcf11ef17, 0xaeeb3ad8, 0x5b1fc029,
-       0x67d09e99, 0xba61e35c, 0x63f4379e, 0xf8f3371d, 0xbe3b96d5, 0x3cf1ae32,
-       0xd7ae83fc, 0x7c6d18b8, 0x8bada7e8, 0x942cf17f, 0x1af426b5, 0x07e818d7,
-       0xf47894fe, 0xd95da3cf, 0xdeb08931, 0xa4f181ff, 0x0e857eb0, 0xa69fd7e0,
-       0x8cf8bf80, 0x44bf441c, 0xef098770, 0x38ef966b, 0xc2e9fb8a, 0xef1843f6,
-       0xf85c784d, 0xb1fa1205, 0x03ee5df8, 0x6568d9aa, 0x1d7c90f1, 0x61d25e20,
-       0x2e3cefc3, 0x12b5d192, 0x9c5bd92f, 0x3498b2e4, 0x8b0b3efe, 0xf8daace7,
-       0x0c3f8f01, 0x09309baf, 0x2bf3abd6, 0x3c1550e3, 0x130f01d8, 0x91c071d5,
-       0x714352e3, 0x8375bac0, 0x1e3e04f5, 0xf9a5f38a, 0xe9ef10a1, 0x8a468e13,
-       0x81b0bf2b, 0x905f0fc5, 0x568fdf23, 0x626b82e2, 0xd7d6fb74, 0xbee078bf,
-       0xf175f1e6, 0xa1c63f34, 0x5f051ba1, 0xf323575d, 0x846327f7, 0x85b7646f,
-       0x0a549bee, 0x4f2cfbfa, 0x997dc0c4, 0xbe234ed6, 0x55d8a293, 0xdc5dbe7c,
-       0x8af5d6df, 0xf5a27188, 0xbf907b2d, 0x3547f9eb, 0x8fd1473f, 0x6f1f2377,
-       0x1f931b75, 0x3ead5b5d, 0xb5d3850b, 0xeba44dfb, 0x189dcdea, 0x79bfbaa7,
-       0x7543b19b, 0xc3f20cfe, 0xd77f1aa7, 0x22c6bb6b, 0xa2efe73f, 0xcad9fbe9,
-       0x3f8d63f9, 0x9b353f72, 0xa9fa6a2f, 0xed18b6f0, 0x3bfbbe96, 0x05eeb927,
-       0x99dae778, 0x45ae751e, 0xd08be69c, 0x6462cfff, 0x3237576e, 0xa395383f,
-       0x959c3ef8, 0xda2707bd, 0x5b2f51a2, 0x0c749d66, 0x665d21de, 0xcc5c6235,
-       0x471e3aca, 0x326723f3, 0xeb4af7ac, 0xbbc604ed, 0xb2abf01a, 0x9bbb65ef,
-       0x27273e80, 0xcfaa6517, 0x1bf19461, 0x4f881807, 0xd3ad8fbd, 0x4a7d8206,
-       0x1850ef24, 0x7f699dc7, 0xb62e4095, 0x9f7f987b, 0x02313d5c, 0xf64bb7be,
-       0x6e14097d, 0x04e0be7b, 0xba4f6cd7, 0x7e43f067, 0x1df69706, 0x4753bc5d,
-       0x69c977e7, 0x6ad13d40, 0x1569d808, 0x4f6a8d62, 0x41d70346, 0x5e12521c,
-       0x8978c0a5, 0x11e63cc7, 0x46d43f70, 0xf50adaa8, 0x5de6929c, 0x9249d895,
-       0x72159dee, 0x57a50478, 0xc557a70b, 0xff65675f, 0xf03b70a6, 0x0cb896fd,
-       0xbbe40752, 0x7d46ead6, 0x0b9b29e2, 0xdfd23fef, 0x88938868, 0xf54ed127,
-       0x5fb450bb, 0xda3b7dcd, 0xe71f26af, 0xa613e6d2, 0xc9232749, 0x8e3e049b,
-       0x7882d102, 0xe06a9b88, 0x70abb2fa, 0xdc785264, 0x19c48971, 0x2c3bf280,
-       0x6e808f78, 0x1e7aaf2f, 0xdc768b16, 0x3e1a7c74, 0xe1d19b11, 0x6a71b035,
-       0x0389dbbe, 0xe3a747df, 0xaf1bae3d, 0x70b56f26, 0x0911277e, 0xdcc59df8,
-       0x2ffe384e, 0x4abdf069, 0x224f8a2a, 0x38c2644c, 0xde2130e9, 0x83cf9625,
-       0x6fa9aff6, 0xeb01ef07, 0x0c870b5f, 0xb5efabb5, 0xe0e5c0de, 0x8a514b11,
-       0xac93ee85, 0xb818b5e1, 0xb82c9d9d, 0x65a04e4e, 0x9fc801fe, 0x61e796d2,
-       0xc8d08a5c, 0x5ac46ae8, 0x4466fb82, 0xad55c790, 0xd53d468a, 0xa8de2664,
-       0x8e3f70f1, 0xd0f1e578, 0x3f9f8f8b, 0x28185639, 0xa50d6928, 0x1fceda35,
-       0xa62c35cc, 0x4502d08b, 0x8b10fe14, 0x5ff40c6b, 0x6c9dc33f, 0x1bd30718,
-       0x2877bf56, 0xc16bdaee, 0x1ba86863, 0x14c0ffba, 0x2ef82164, 0xdd0ef108,
-       0x51b8720f, 0x0ec653c9, 0x463406ef, 0x332ef287, 0x698df7e5, 0xdaf37f2c,
-       0x7ef0f5a1, 0xe8bda74d, 0xc78c0b66, 0xcf0ebf6c, 0x9af102c3, 0x937bd5f7,
-       0x4738ca2f, 0xc1e40c6f, 0x07b7c7fb, 0x23c5fbd9, 0xfc7ba1ad, 0x59378f28,
-       0xed007c94, 0x43d6a28b, 0x5aaad7c8, 0x01b9610e, 0x9e1d34f2, 0x421bc810,
-       0x65bf79e7, 0xb5f2414c, 0x716b5e14, 0xb1c13c32, 0xbf6632d0, 0xb8c3c1a4,
-       0x61d9bdfa, 0x6e2b483c, 0x86e1e1d0, 0x858785af, 0x87a86f6b, 0x3bfa55f7,
-       0x0b174a6f, 0x73d35f00, 0xdb8ef80c, 0xf41663c4, 0x145fd0bf, 0x670e23ca,
-       0xbcf72f43, 0xc2853b15, 0x97d35729, 0xaba14ed2, 0x9d26e8de, 0xef63afd8,
-       0xe7e96a83, 0x87ae2ddf, 0x8b32de00, 0x8896dd2b, 0x0577c7f3, 0x8b8bbba6,
-       0x74c213f2, 0x09ee2c4d, 0x11feaef0, 0x5a1f82cb, 0xe9dafe54, 0x34c54b39,
-       0x011fde3a, 0x3c31b823, 0xdee5c49f, 0x9e7451a8, 0xc6032e89, 0xb8b11fd5,
-       0xdb3b4057, 0x6200609c, 0xf71226cb, 0xf70c4104, 0xfa8feca3, 0xaf8ecc1d,
-       0x56f8362f, 0xfc60f3b0, 0xfa611dbb, 0x47d1d0e8, 0x5b47d190, 0xb547d227,
-       0x47d193bf, 0x346e5d5b, 0x3b03573f, 0xc70491ba, 0x5937bac1, 0x61a40b0a,
-       0x82626e94, 0xb23740f5, 0xc282b6f7, 0x3aebc428, 0xf58f5f18, 0xe652e3e1,
-       0x36fadbd5, 0x71fb481e, 0x0799d806, 0xa61e780d, 0xb7a94de0, 0x46e2c2c3,
-       0x7ee6cdff, 0x99a9fa11, 0x961fb1d4, 0x3f81eb6f, 0xed875c60, 0xd05dcce0,
-       0xae9b36de, 0x6fdc2390, 0xf815c1e3, 0x7f23784e, 0x04963bd7, 0x7bd720bd,
-       0x3fdb07c7, 0xde807c21, 0xe8f80193, 0x0af2fdc4, 0xdd9667bf, 0xce40b826,
-       0xef618f0f, 0x616ebc90, 0x16bbf576, 0xaf4ca791, 0x5bb83c49, 0x7b2bfb04,
-       0x27eb0195, 0x9ea19a42, 0x5f5e2aff, 0x95ddf8d2, 0x89e85575, 0x7818d272,
-       0x78f9e4cf, 0xfd2d1ef7, 0xa9a4c7c4, 0x1eed29e0, 0x45a290f7, 0xee265094,
-       0xc810f05d, 0x3e3f4a55, 0x7231bb4d, 0x442de014, 0x233e943f, 0x776d0fad,
-       0x7c6bad88, 0x5b0be80c, 0xf1152ef6, 0xae7e8e5d, 0x47bc166b, 0xc567eb49,
-       0xb4adda90, 0x4d2c567d, 0xf3c09f21, 0x087e7903, 0x743fd34b, 0x7dfa041a,
-       0x9ecbf703, 0x922578e5, 0x6399bafd, 0xb8f4cf20, 0x9418e4ec, 0x85beca0b,
-       0x5ce05467, 0xdbe7e25b, 0x0334c169, 0x8fb29bac, 0x6021a0a5, 0x4d2b42a5,
-       0xce201872, 0xbb8f5de1, 0x7b0bce08, 0x5fb73be3, 0xea81eecb, 0xc7ce7fbf,
-       0xebf58df3, 0x2fb8f4bf, 0xb7e039fe, 0xf8f1dcca, 0xbeaf9a4c, 0x69fa32f6,
-       0xdf54c457, 0x68ef55fc, 0xeeffc7e8, 0x00c4dfd5, 0x333ffa1d, 0x353fbc45,
-       0xf1e8cace, 0xb60e6780, 0x04efe2cb, 0x1c4a8192, 0x15ce2ab2, 0x865eb8ca,
-       0xdf86994b, 0x05bacf51, 0xa7ac2059, 0xf6878a57, 0xae78a931, 0xae2eab78,
-       0xbb2f3955, 0x80fcc025, 0x42beb159, 0x74faefec, 0x3e49f7f6, 0x9992fa63,
-       0xa1ce0ffe, 0x3373f2a6, 0x5efb31d7, 0x09598710, 0x3f08f98d, 0x5afd1536,
-       0xfefb4439, 0xaf40d641, 0xf4f28064, 0x67978454, 0x13a795d6, 0x6b915bf4,
-       0x4df9c3ae, 0x0cfd2a25, 0x13a346e5, 0xd1f4f1f8, 0xf7f9fe94, 0xe1bff4cb,
-       0x867f3226, 0xcdb8ceca, 0xbe515f71, 0xc4696f46, 0xfb7e8577, 0x523f38b9,
-       0x2163c5fc, 0x4115173c, 0x8f1e803c, 0x95610eb9, 0xdf13d1d5, 0xf1e9fc7a,
-       0x8f51e0ad, 0x9d0f9cb7, 0x9e8ef1f9, 0x23e3d1f8, 0x5be97e7c, 0x7530eb0b,
-       0x4bf288b4, 0xfc4f7bc1, 0xedfaf5b0, 0x009eb4b5, 0x0df142f4, 0x30174cf8,
-       0x862b27be, 0x3a6c4fd3, 0x140b37e2, 0x0f4801c0, 0x55e3d798, 0x04acc78f,
-       0xd5813ede, 0x1af80fdf, 0xed00fc89, 0xb2dd6521, 0xc6f76bd2, 0xe8c4de41,
-       0xa7abd14c, 0xbd50bc72, 0xbce6f51a, 0x9bfa2b44, 0x9a9eaf40, 0x5e5bc614,
-       0xde571b15, 0x600bcb48, 0xfc0afe9f, 0x0608b1d1, 0x95bcc5df, 0x56e05ff0,
-       0xe2ca5f3c, 0xb7df0559, 0x93d5a67e, 0xce0bfaa7, 0xdc3dfe82, 0x05655ee4,
-       0x87108c7f, 0xff1479e7, 0xd7f875c7, 0xf36bb3b6, 0x0afc7c7a, 0x27b931fe,
-       0xab7a14de, 0x7cfd72b3, 0xfa0a1930, 0x3337d8f2, 0x137f8163, 0xbf447c7f,
-       0x4563c4c4, 0x6e9c3821, 0xe2059e91, 0xa7b77d0e, 0x763e0b7f, 0x15494a90,
-       0x7253bb1f, 0xd8deb3af, 0xeb298f93, 0xc7af8535, 0x05dde214, 0x4429a67e,
-       0x1ec84bfa, 0xffcf0d48, 0xb3f72b79, 0x6043210d, 0x1c585f9e, 0x79f3ff8c,
-       0xd54de686, 0x9b3fe84b, 0xb66d9ff7, 0x121bfde0, 0x7842ba94, 0x93f7c34e,
-       0xf0f8c6bc, 0xbd656438, 0xd3096a53, 0xfbe2e6e7, 0xe42f14d9, 0x38f098cb,
-       0x090559b6, 0xe3e20fdf, 0xf66cdf38, 0xd3db9c42, 0x2b0dfb92, 0x83843df8,
-       0x527e7163, 0x3fc81460, 0xb6e5f97d, 0x4e50d5bd, 0x3d6095eb, 0x910afe3e,
-       0x3b821ff9, 0x5217be4c, 0xe953d77b, 0xa13946f6, 0xdc3671d0, 0xe801bd7b,
-       0xb8c2283e, 0x655cfcfd, 0xcf7645e7, 0xabec45c1, 0xf6f0a7ae, 0x02f7625d,
-       0x81db28f2, 0xedfa7a7a, 0x49f34e8b, 0xd3b41e70, 0xcf22abd3, 0x5bfdf81b,
-       0x68bb3f45, 0xeb0fbf75, 0xe3efc0de, 0xba8e2ffa, 0x1be7d60e, 0x2d61d5d3,
-       0x44f4295d, 0xf438ebe9, 0xf1f99dd3, 0xdfcb503a, 0x049cbccb, 0xe3d151f2,
-       0xeb8afac3, 0x9bd7a863, 0xe6dc3f3e, 0x857eb2ee, 0x35e8af3e, 0x6423d97d,
-       0xd34644af, 0xebe3ce71, 0x2edcd733, 0x41c68bb3, 0x886fd38c, 0x73cbde56,
-       0x393e8344, 0x95ed21af, 0xac573866, 0x07f97e63, 0x3d8d656b, 0xbedb86ec,
-       0x67bd9ed8, 0xb6b97f3b, 0xef8a23fc, 0xcef8f141, 0x868ed6ad, 0x7e1491fd,
-       0xbf67b7cf, 0xc9c82f06, 0x31a32379, 0xafdf4e7e, 0x7efa7e7e, 0x7035fdf5,
-       0xd8c1aafb, 0xd2a9da38, 0x1636ec4f, 0xcd697d47, 0x14f0cd93, 0x73f86f5e,
-       0xd4b8879b, 0xa3ae6f7f, 0xa44e7a21, 0x781468f7, 0xc2e7be0a, 0x0fe098cb,
-       0x1eff95a8, 0x6cdd9de9, 0xf413f337, 0x6088efd6, 0x8683ea3e, 0xe82203a7,
-       0x048223f5, 0xa0ecf0f5, 0x6350b0cb, 0xb97b300f, 0xef003d87, 0x657cd0a4,
-       0x0f662eeb, 0x5da1d4b4, 0x0aed4951, 0xe01b3b90, 0x7cc1901d, 0x27681940,
-       0x885eec84, 0x7786caaf, 0x0c5db932, 0x37a5a74f, 0x1f33fab2, 0x8c35374f,
-       0x9dd5bb00, 0xce932f0c, 0xa8fb5db4, 0xf557da99, 0x508a24a9, 0x76c8aafb,
-       0x4ed677ed, 0xde3bdca2, 0xa4bbc025, 0x65a8ff34, 0xecedff72, 0x8fd1b699,
-       0xda81bf82, 0x54d9b767, 0xfb6f6f76, 0x039b66e3, 0xfedbd9f1, 0xcd17b4e8,
-       0xdf8a3804, 0xe421f282, 0xbe28fe07, 0xf442a3ff, 0x53780b17, 0xe5f6e5e8,
-       0x88ced10b, 0x0a6ae6ba, 0x736593c4, 0xb8db703a, 0xc186365f, 0x706189a9,
-       0x376e4a26, 0xfbbdd3f4, 0x3bf028ea, 0x04fa3bbf, 0x2b7e79da, 0xf41fdbf3,
-       0xe3a91594, 0x026d6bdb, 0x10c097a7, 0xdc777fd8, 0xec0127b8, 0xc0596c95,
-       0xb2fd4ef7, 0x99f1e9ef, 0xdb669fc0, 0x6629d257, 0xfde2364f, 0x60547f32,
-       0x3d2ac3c8, 0x4ddfcfce, 0x3fdc5ff5, 0xdcff1d44, 0xb5abcd6e, 0xc022f831,
-       0x7bdccecf, 0xde80f40c, 0xae584ee4, 0x2b9004b8, 0x24a1eae4, 0xdd6a5f3c,
-       0x689f0367, 0xe0e77f17, 0xa49eeb7c, 0xdaad3405, 0xb0369ff2, 0x3e38eae3,
-       0xf8ed4bce, 0x76e5535e, 0xa113df11, 0x003d26fd, 0x85d6eb7e, 0x1fdeec59,
-       0xc8a6afbb, 0xef9ff1d5, 0x9cc45219, 0x4cff7889, 0x98a737d1, 0x9f183ebd,
-       0x1dfd8ebf, 0xf7ba29cc, 0xefe56ec9, 0xcff5e993, 0xe2b26c67, 0xa9f8c32f,
-       0x4fd67665, 0xfb2bfb6f, 0x53e204b3, 0x296cbfed, 0xb3f8c220, 0xefc24b3f,
-       0x3da40fe7, 0x3df60855, 0x01239d91, 0xa2f644ac, 0xa7cfcb7e, 0xbc2f6fe8,
-       0x6793be7b, 0x3cbd6ede, 0x6e2466eb, 0xd004d72a, 0x9803dcc7, 0x07c991d3,
-       0xf5bbff45, 0x55dfad33, 0x722b07af, 0x6e3fd732, 0x780210d5, 0xfbc2cc77,
-       0x8c240713, 0xc9ebd2f7, 0xbd058353, 0x204fc3e8, 0x4d6d6d7d, 0xfe7b018f,
-       0x009f60df, 0xc65eb6dd, 0x49aa83f7, 0xc7781ee0, 0xb455baa9, 0x24fc6007,
-       0x67d87af3, 0xe0a13e8a, 0x1eeaeda5, 0x7fda58f3, 0x7d8345f6, 0x76f10505,
-       0x57682ff0, 0xc1fdf84f, 0xfe679004, 0x07e784a0, 0xc6f717d9, 0x45f1542c,
-       0x7e0355ff, 0x6eeafb7f, 0xfc60f7ed, 0x8b6ed0f5, 0x7bcbd981, 0x063dfff7,
-       0x57dbd4f8, 0x90bc212f, 0x6f53d13e, 0xcf3bfd46, 0xd1fc862a, 0x8899bd6a,
-       0xde2187d9, 0x152c6a6b, 0xfaef426b, 0x6487ce70, 0xd4f49595, 0x2778422b,
-       0xd0f0092e, 0xf0561f43, 0x3e33d3ac, 0x773d71b2, 0xef0f1918, 0x4d5db65e,
-       0xc77bc0a8, 0x0afb18fe, 0x8f4ccf94, 0xee7bdeea, 0xfdf0e9c9, 0x9ddec8a0,
-       0x7ee22ab8, 0x62b3bdda, 0xdf6a8778, 0xeb8a4e52, 0xc5d06576, 0xfad16f0b,
-       0x3345f657, 0xbce4baff, 0x224f7d5e, 0xf1c7df5c, 0xcecc1815, 0xe183bce9,
-       0xac6fa8bd, 0xb0f574cf, 0x4361fff7, 0x0058393d, 0xfad462e2, 0xffac234e,
-       0x3e8ad9bf, 0x25a5fc67, 0x978bf806, 0xb4210ee4, 0x9268b2df, 0xac15740b,
-       0x33b07623, 0x18301fb6, 0x37325d60, 0xcf5c62a5, 0x731cfc2b, 0x31a34b49,
-       0x4b174555, 0x19d839f8, 0xaf129bd9, 0x9632befa, 0xfb3397f1, 0x71817fca,
-       0x91347f1d, 0xd0f41191, 0xfe4cb185, 0xa77a336e, 0xc77a866f, 0x68df780d,
-       0xef5ffeef, 0x97937787, 0x038c731c, 0x5894e0bf, 0x0eda0fb6, 0x710f52be,
-       0x821f6dc1, 0x6672a2d4, 0xa068b163, 0x1c45befd, 0x9877afcc, 0x90d6bdfd,
-       0x12b8943f, 0xc5379e60, 0xd6fdbe32, 0xdce68301, 0xbefe2dec, 0x8cb1f5ef,
-       0x32c6a50f, 0x03d6dabf, 0x700b09b9, 0xc447b9ff, 0x64f01f82, 0x456c3d47,
-       0xe8a80fc5, 0x6f0f936f, 0xfe863e9d, 0xc1977273, 0x38edcb0e, 0xf30882fc,
-       0x24219c75, 0xf43d204e, 0xac6f0a39, 0x5d5bde1a, 0xc71d1e0c, 0x0aafd86e,
-       0xfe04a9fe, 0xbfcd0671, 0x43c52ed5, 0x7f82983c, 0xff4a1e65, 0xdae2168e,
-       0xe4adc160, 0xfe15fada, 0x31efe568, 0xe513b04c, 0x5d2033ef, 0x6eb9b76e,
-       0x6f72c589, 0xeccfe40a, 0x36d27a63, 0x72494f2e, 0x9fc070f1, 0x79f34eb2,
-       0xb7a78caa, 0xe3e7effe, 0x4bafd254, 0x0ec8afd7, 0x76cdd22f, 0xf0ee4f16,
-       0x10e9cc06, 0x8e96d677, 0x154a9f7f, 0x8e3f7b97, 0xfdf68cff, 0x830eb6c2,
-       0x558fee01, 0x50e210ef, 0xbea7eddd, 0xa933a21d, 0xedafe905, 0x5c7dc118,
-       0xe65dfcde, 0x9f72a48f, 0xe786ebbf, 0xf87fb0eb, 0x8120fb39, 0x1bfd93a6,
-       0xfc410e56, 0xafb06c06, 0xfba278c2, 0x46dad206, 0x92ebd023, 0xe52d2c65,
-       0x9a4bd5e7, 0x4b3fb8dc, 0xc478b3d6, 0x4ca9b165, 0x257a733e, 0xf8c1e886,
-       0x7b4dbade, 0x5c1ff08f, 0x7d6d9e7e, 0x4bf40f6a, 0x80fbebe9, 0x9eda9b8f,
-       0x55c30758, 0x46ecf5e8, 0x4594e119, 0x3df3cf6b, 0xb8cfccb1, 0xf7a330fd,
-       0x5ce51bc9, 0xb26c4f78, 0xbfc1d897, 0x4dc6d6fd, 0xb7eff022, 0xd9539e80,
-       0x7b79073e, 0x3163df66, 0xd6f907df, 0x47e02069, 0x652466df, 0x62fb545b,
-       0x343786ef, 0xb9bcb7fb, 0xebfa3a6e, 0xe005e23b, 0x55becaf3, 0xe8cdbef0,
-       0xfff70dbc, 0x9ffdba9d, 0xc2b7dacf, 0x4f7ad0ba, 0xd4fffdf1, 0xe9ffba34,
-       0x718db8a7, 0x66d9c002, 0xdccefc8c, 0xfe90df4b, 0xa3b57c42, 0x297d5f07,
-       0x6c1ff996, 0xeaffb4e9, 0xffa12e3b, 0x4e3e3421, 0x2be54f37, 0x002a9374,
-       0x0ae91bfe, 0x517c008e, 0x533d02bc, 0xccfe7a3d, 0x0795dc0c, 0xe1ff3c24,
-       0x2e3c4be7, 0x6a947704, 0x99f986bf, 0x6fdd6fb2, 0xf2b238c0, 0x9e82576b,
-       0x45e8509f, 0xb82b3cfa, 0x7953c787, 0x71f61676, 0x8eb07e04, 0xec8ae3e3,
-       0xff7debee, 0x65cf40c1, 0xf98462d4, 0x1d82f590, 0x772945d6, 0xbdef67ac,
-       0x94f0e61e, 0x2dbf87ef, 0xde3d83be, 0xf0cc3d21, 0x5c42341d, 0x931f28eb,
-       0xc5c84463, 0xb70c40fd, 0xb67d860f, 0xfbafca84, 0xacebf255, 0xaa7488dc,
-       0xce23e1e0, 0xb1c4aeb7, 0xc7ce3f79, 0x5d1f07e9, 0x82ff0aa2, 0x3f6c0924,
-       0xe7db028b, 0xbb3fc022, 0x90dba6ef, 0x4c88efde, 0xb7b076ef, 0x47efe1e2,
-       0x8cfa406d, 0x7bc7669b, 0xce494f2f, 0x7e8d38a8, 0xef74c3e4, 0xced067a6,
-       0xfd85fa03, 0x97fd1bde, 0x0893fd01, 0x74a3ef74, 0x853f5aaf, 0xfc5d280e,
-       0x7ca5f01d, 0x7285d3d7, 0x65e0a90e, 0x731cee9b, 0xe9e19daa, 0x8d5200ff,
-       0x8000b56e, 0x00008000, 0x00088b1f, 0x00000000, 0x7dbdff00, 0xd5547c09,
-       0xf37df8d5, 0x3332c966, 0xb2764c99, 0xa00c4930, 0x80490e2c, 0x084ed8b0,
-       0xc3884a20, 0x93a0d752, 0x364b0900, 0x94569510, 0x8b062081, 0xb62d1518,
-       0xef858320, 0x106d1b43, 0x268358a8, 0x622d1110, 0xa57fb1dc, 0x41459041,
-       0xed1fa822, 0xe73bf587, 0x33337bdc, 0x6a02266f, 0xefc7e1ff, 0xdf77dee6,
-       0xcf7ece5d, 0x6ec5f739, 0x843631d3, 0xae630731, 0x7d8c01e6, 0xf4bf3f8f,
-       0xa12d8c97, 0xcf3773e7, 0x8224715e, 0xf0f7cfd1, 0x5e79babf, 0xc776bd50,
-       0xe91c57af, 0xc5cfafe7, 0xffe0525f, 0x8967a671, 0x47f1558c, 0x89ef4cac,
-       0xfbc025b5, 0x6cd69d11, 0xe266b498, 0x03846319, 0x8319789f, 0x1c636ff6,
-       0x6faa3e54, 0x1f2bd3de, 0xe9cc31ca, 0x9b39a685, 0x998f1533, 0x1b3605b1,
-       0x27f967ad, 0xb0dd93d3, 0xc6c646de, 0xc59bbae3, 0xd9dd727c, 0x99c68536,
-       0x8f7329e0, 0x66678389, 0xa07b9e4f, 0x6607f9ff, 0x886d964f, 0x70a13ebf,
-       0x4018eabe, 0x7ec48c4b, 0x0c985563, 0xc9bf9fe6, 0x326533e4, 0xc49f05b6,
-       0xa3db2ac3, 0xfd329b7c, 0xccf4d9ef, 0x9633b7a5, 0x75a4cb6b, 0xb15aeac1,
-       0x646858ee, 0xdfbcc197, 0x9bb59666, 0x1dd5d1e1, 0xb081e2de, 0xef462d8f,
-       0x389989d4, 0x1c1af398, 0x9d629aff, 0x6a5801ed, 0x38a6cbac, 0x6992d007,
-       0xcf8fb65e, 0xeced9793, 0xeea1b2cf, 0x2db9e670, 0xf8128d8c, 0xc930ad62,
-       0x421c3f70, 0xd9e1c6f1, 0x20175e13, 0x1750867c, 0xd5e27e7a, 0x667d1ba8,
-       0x0144f3ff, 0x78632fbf, 0xd3c1adf9, 0x1d0e66db, 0x553e6027, 0xcacc6649,
-       0x5c554b3c, 0xdb6628ff, 0x773ff0e4, 0x1c2e628c, 0x57189a7f, 0x8ffacbb6,
-       0x10aeafa6, 0x78869afa, 0x22e88ead, 0xd053eaba, 0xbcc07469, 0x8bdd194c,
-       0xee98fac1, 0x80ac5eda, 0xbd71eaba, 0x29554800, 0xf6c7ebe0, 0xd7338d84,
-       0x01d99e23, 0x0cc9cb13, 0xcdb567dd, 0xd1b6e1c0, 0xe866fa30, 0xb865e097,
-       0x838bc003, 0xde3585e3, 0xdc6bf88a, 0xd7886268, 0xdc39636f, 0x68d953ac,
-       0x42b7f403, 0xc6f7247f, 0x57039ea9, 0xd931bd41, 0x9e6050e8, 0xc22e8613,
-       0xa0ab89fb, 0xadc3e88d, 0xbc4fbe20, 0xdf9ae23a, 0xa277bb40, 0x8bc0e58e,
-       0x05b08d5b, 0xa7bfc3a4, 0x482936f9, 0x27c42da7, 0xc1b2c7f3, 0xbede7826,
-       0xd5d11869, 0x052ce2ac, 0xe6ce76e9, 0xdb9f0558, 0x2a74d8c7, 0xd863eff3,
-       0x13e89542, 0x16dea0f8, 0xde618f80, 0xd5e1153a, 0x6c93ce3b, 0x11ec6588,
-       0x23e335db, 0x32ce81d2, 0xcc1b2459, 0x5f5043d8, 0xb46b7009, 0x4b1614bb,
-       0x0a7306f5, 0x236321f1, 0x0cadae08, 0xd518d4f0, 0x6045775d, 0x7f5e2cff,
-       0x86eaf1a4, 0x9ec63486, 0x22357189, 0xbb303e9e, 0x87f9c11f, 0x44a9d526,
-       0x7fae82e7, 0x127ece80, 0x2c2ed4bd, 0xe0f38762, 0x0e660ef7, 0x47901ba4,
-       0xf8066eb7, 0x9b3de895, 0xbd355d70, 0xc38e3e8e, 0x657cb6d5, 0x7ba184f4,
-       0x21788eb9, 0x8cc7d817, 0xaeef11f0, 0x7ecdcb53, 0x66c5b3b9, 0x52ed4c17,
-       0xfcfc5b26, 0x79eb7286, 0x593b9733, 0x98229a50, 0x7ec762d7, 0xac23a23e,
-       0xe5fae4c7, 0xdd62cad1, 0x3e185f78, 0xeb890d7e, 0xaccf9467, 0xf2ff7fe5,
-       0x1fd0a19b, 0x9f89577f, 0xc4fce35e, 0xc5a3f5e5, 0x3c22269f, 0xbdf09390,
-       0xeb1cc5db, 0xeadf3a97, 0x5fb9748b, 0x3ea09b65, 0x2af464d8, 0xe66db831,
-       0xf18a25b0, 0x945b0d90, 0xa820cb56, 0x2e614bff, 0x7fe9c3c0, 0xbfae54a9,
-       0x133e3dd7, 0xa1d9afde, 0x7e852e73, 0xf10a2d35, 0xf337b383, 0x371d0045,
-       0x31075947, 0xb770af18, 0xf68065d9, 0xc9044ad3, 0xd7009c65, 0x2feb9061,
-       0x8268cae8, 0xc02df5e7, 0x5d3d507f, 0xf5c6a808, 0x6c319dea, 0x83be1f80,
-       0x1fb47cde, 0x1bda00ec, 0x4f67c89d, 0x9ff1f245, 0x81f0cc8a, 0xbe528310,
-       0x4a0188e7, 0x6e825961, 0x62c67af4, 0x78504f00, 0x30b51cb1, 0x3c07a5db,
-       0x35e67a2b, 0x7546be00, 0x9f08aab5, 0x8e872eac, 0xe9f3fd99, 0x3bed18bb,
-       0x39d0ef4b, 0xd6d5f403, 0x7aabcfbd, 0x31d0eb80, 0x942af58d, 0x6f9e3189,
-       0x4623de10, 0x7b63d5d5, 0xf557b15c, 0xa57cff40, 0xe905b76e, 0x44e61aec,
-       0x24f92ab9, 0xc1b593ae, 0x81ec5972, 0xda15974e, 0xb5771c47, 0xc7fd800d,
-       0xe38299b8, 0x7c0dfd49, 0x0e9162c6, 0x44ca5de3, 0x3fe86718, 0x8e47c118,
-       0x68ef75b3, 0xbe3ef905, 0x18e28c63, 0x6be74a10, 0x38b7e398, 0xce9f77ae,
-       0x3475f889, 0x9406d733, 0x62ba7f13, 0xf64bc20c, 0xf5cb1def, 0xa78f48ca,
-       0xee154408, 0x1de70627, 0xb76fa37e, 0x6c33d601, 0xd1b77796, 0xd99fb011,
-       0xed4bc68c, 0x523ed2f4, 0xb10a780e, 0xd2c6b6cc, 0xb78e2338, 0x7e800db6,
-       0x1fb07549, 0x78ef4f68, 0xa6b8414f, 0x882875d7, 0x777badcf, 0x3ad37ad1,
-       0xf82979da, 0x176179eb, 0x5603db74, 0xdb23ed1d, 0xf2cdf5ca, 0x666f5c53,
-       0xadb27ac7, 0x2c7dfe09, 0xd724f42f, 0xf66bf8c1, 0x17ef7566, 0x2895eee5,
-       0x52e403e4, 0xc691ac6e, 0xe9eacbb9, 0xbdabfb8f, 0xd20f73b1, 0xdf7bf3e0,
-       0xb47f12b1, 0x137e13c4, 0xf84a7df7, 0xba485c48, 0x37d9ad98, 0xb179415f,
-       0xa67014a6, 0xca59c284, 0x7eb8358d, 0xf45b1fa2, 0x27cfa024, 0xd8829eed,
-       0xcca57b40, 0x20159d1e, 0x8f7be497, 0x19ee662f, 0xed6190b0, 0x16595be5,
-       0xb17ef7c9, 0xc27df201, 0x9122fbc0, 0x2e2c9a9e, 0x569fb617, 0xcf388dd8,
-       0xfb425833, 0x975e0633, 0xe0407af0, 0x52763b33, 0x870875b6, 0xf8e80d93,
-       0x4fde4899, 0x8dee8f2b, 0x83bb09d5, 0xe0eb0bd3, 0x08fb82f4, 0xc666bfb4,
-       0x748c3c72, 0x9cf48a79, 0xfee2a64e, 0x76f81786, 0x1b0edd23, 0xf48dddef,
-       0x9d04ce9f, 0xa274e78c, 0x63dbf7a5, 0x711d7cb9, 0xdc218bbc, 0x0ee615f3,
-       0xc654ef67, 0xbe29bb72, 0x0fd13463, 0xce1943f0, 0x4eb53437, 0x66dca035,
-       0x7fa809b6, 0xa0eb137e, 0xae05797e, 0x366f48dd, 0x79f89b97, 0xe9c6d9be,
-       0x07d39326, 0x1c273fbc, 0x3e436d3f, 0xa3e7e01a, 0x7347a478, 0x26de3d28,
-       0x011bf4e0, 0x3df1d0df, 0xf1f8e177, 0x02973a1d, 0x603b0c83, 0x3ae831f6,
-       0x49e8016c, 0xf40653e4, 0xcfb40b0f, 0x9f2215b2, 0x153956a5, 0xb302ebc4,
-       0xd7dc1efb, 0xf98d9472, 0x5f3acf48, 0x6c97bc3d, 0x7efe1173, 0x67689eb4,
-       0x90686c11, 0x2c40f59d, 0x9557e3b7, 0xfa7ebca1, 0x53ca235b, 0xbdbfe487,
-       0x01e5d1b9, 0x50c7f1f4, 0x0e123f7c, 0xa7395adf, 0x2e5fb7c5, 0x8039cb04,
-       0x0f8e5ad7, 0x77c7e76e, 0x7cb9502c, 0x3d6b9608, 0x3e4423e1, 0xc1fc3c08,
-       0xeb84daec, 0x4045c6cc, 0xfacd1de9, 0xfa4f7b61, 0xf358c5f8, 0x2f67b34f,
-       0x8c5f8fac, 0xc7d5084d, 0xd7ae88ba, 0x75478015, 0x6150ea8b, 0xec8bf50b,
-       0xfaffc42e, 0x7689c566, 0x9516eee1, 0xf2fd61e8, 0x729bd228, 0x8f6e5fbd,
-       0x84aec419, 0x6b3ff052, 0x5a7d258f, 0x5fe62b1b, 0xfcc0bf06, 0xbabc6da7,
-       0x3d79e6dd, 0x6fad0e50, 0xe11226f9, 0x71593fdc, 0x4abb411d, 0x85818fab,
-       0x84df7814, 0xd70829bf, 0x322a0dc1, 0xad9ef5d6, 0xf6f09526, 0x8c378e2e,
-       0x0a33be75, 0xa6a7f5d6, 0x7b40bad1, 0xaf8eeceb, 0xeb05dd6f, 0xfae68daf,
-       0xeb9a36b9, 0xcebbd3e7, 0xbb7a41f7, 0x9274e176, 0x9ef4c37b, 0xdce5038f,
-       0x730efd1b, 0x6d4acc39, 0xd4e3fb47, 0x68fbe52e, 0xa235a100, 0x0aed1e9f,
-       0x06a9ca35, 0x1c4415db, 0x1f0039f5, 0x145b5f84, 0x073eafc1, 0xd6932ef8,
-       0xd9d70279, 0x14b2316e, 0xfc0b3f68, 0xbae4fd88, 0xcf7ac47f, 0x9a6f5f84,
-       0xa0b468ed, 0xbebfd50b, 0x1e20bc6e, 0xa2d57c60, 0x669c7da7, 0x67c44e51,
-       0x10c5d1b3, 0xc283deff, 0xab78103e, 0xba773411, 0x0f01c865, 0x81fd6fec,
-       0x7fbe2734, 0x48d9c77a, 0x47ed199d, 0x7d876a8f, 0x565de9a9, 0x5bbb87d4,
-       0x39de5ece, 0xc19be480, 0xbb3beb0e, 0x33ddb0ef, 0xcfed47e0, 0xfd88bf6a,
-       0x0dcdead5, 0xaa227681, 0x1a945259, 0xda5a523a, 0x220ca9fe, 0x0f2863fe,
-       0x57cc19bd, 0x3e5efb0f, 0x54d3d050, 0xd7be40e6, 0xcdbb7be2, 0xe00f619d,
-       0xb736cddb, 0xf385d703, 0x3ed2e6a4, 0xe83eb0b3, 0x0679e9cd, 0x0c6fee1d,
-       0xed29bd43, 0xb44fb93d, 0xfd7323c7, 0x5ef693fb, 0xce73fef7, 0x68c7da0f,
-       0x74ec83df, 0xc52c740e, 0x282d5a73, 0x03320785, 0x784adff7, 0xacfb16a9,
-       0xaab7308e, 0xcdb62fb0, 0xca53b270, 0x7dd0ac83, 0xf3869e00, 0x780f387d,
-       0x377fcf10, 0x4e11eb3b, 0xda1b0efa, 0x91afb0af, 0x50560fb8, 0xf8708c96,
-       0x8c9aecc0, 0x2599fef2, 0xf4fae88c, 0x14f7ccb3, 0xbb4b7a6c, 0x0366e88e,
-       0xffe882bb, 0x5b99dd0a, 0xebe266dd, 0x7e7ef8b1, 0xe50ea347, 0xa1cf8e6f,
-       0x797ab943, 0x474eb347, 0x2f19e0f4, 0x0f5674e0, 0x54dfebeb, 0xba48fea7,
-       0x2e9e1498, 0xabf6f042, 0xb849bc40, 0x30f4128d, 0x3286e10a, 0xb27f4bb9,
-       0x370fc233, 0xb54b0bc0, 0x58c78e87, 0xa9c20667, 0x7d63c5ed, 0x9abc613a,
-       0x8add8f97, 0xabf9a970, 0xcc618889, 0x418f2f5f, 0x30b2ffba, 0x72735dbc,
-       0x0f5b9d71, 0x3dab78c4, 0x157be48b, 0xbda230eb, 0xaddd7200, 0xd2eb900f,
-       0xe867db8e, 0xf7f1c628, 0x12d9510d, 0xe759f380, 0x461624b0, 0x3f72c85f,
-       0x00396dda, 0xe155f47f, 0xfcc5e4f9, 0xda476e18, 0xb25afc83, 0x9678b7dc,
-       0xe7a18c7b, 0x8e0df6f1, 0xb14e7f24, 0xc87a1ec6, 0xa78dedce, 0x81cf5ced,
-       0x3ae17660, 0xe2c5fd4f, 0xa9d342f3, 0x0cadf7dc, 0xdb6a74e0, 0xa05e79bb,
-       0xe3ac53a3, 0xdf9097f6, 0xb9d336be, 0xfbf078ae, 0x7e2c4b79, 0xfb8abcfe,
-       0x2f55d852, 0x407569bc, 0xbb2de2ff, 0xf001bde3, 0xbfe98abb, 0x4ceba6ee,
-       0x8fef979c, 0x20fb3be9, 0x274bd83e, 0x16501d12, 0x3c6af8bf, 0x373803a7,
-       0x14ff450d, 0x633f8fe7, 0x5ddd8053, 0x3dc6b0bc, 0x1fc02f26, 0xf9922e73,
-       0x0efaeb02, 0xab891e23, 0xfda999cf, 0x9e25bb76, 0xd62f4de4, 0x8f4de50b,
-       0x7848baf0, 0x3c25db6a, 0x913e0df7, 0x97c5f681, 0x07c5d83d, 0xaf7ec1ec,
-       0xdc7b1637, 0xf5fc7263, 0xdea77dbf, 0x5ef30ee6, 0xacff188b, 0xda127873,
-       0xd6c6c57d, 0xe1f9c2cb, 0x0b5339e4, 0x57ce37a7, 0x7fb8e346, 0x1f1a6739,
-       0xeddb5d6e, 0x3fe69fba, 0x0aab07d8, 0xf44b0bb0, 0xdced379e, 0x326ab05f,
-       0x3f2e6bd4, 0xd9ce8e3b, 0xdc845e92, 0xdb798abb, 0xf4b57f90, 0xbefdf121,
-       0x4b2a5bc4, 0x693dbc45, 0x11ba7077, 0x43f920fc, 0x396d470b, 0xe13cc8c1,
-       0x75cf03ce, 0x799235c3, 0xbede1e41, 0xfe7a40c1, 0x4e1ff3cd, 0x3f7a03cd,
-       0x5b60d6b6, 0x5ace530a, 0x51ed3bb7, 0x360da7f4, 0x1fa814d9, 0x865eb473,
-       0x4eb95f7c, 0x1c3d2375, 0xe27b7b5b, 0x00bf2874, 0x7582adfe, 0x50306e54,
-       0x770dacfb, 0xc109fb50, 0x12eb95d7, 0x7cbca3fa, 0x4481fdb3, 0xeface3c4,
-       0xf11ebfee, 0xeb68c5b2, 0xaaca183f, 0x263dc526, 0x3673de00, 0xb7d50646,
-       0xdc2cd8e8, 0x532bc487, 0x1dcfdd3c, 0xdc631eb0, 0x6b63c44f, 0x18d51f88,
-       0x92ccedc7, 0x9aefb029, 0xbec96721, 0x8a27bddf, 0x662bc9f4, 0xd6c8ec95,
-       0xb7f3ffc1, 0xf45ea12b, 0x3649de9d, 0x58f3c09e, 0xce866781, 0x8a8fa040,
-       0x7a2f5e08, 0x68764f51, 0x78254591, 0x1d5c82b7, 0x65de4a43, 0x7efd0b1e,
-       0x4753df21, 0xfd0e1ead, 0x1818c6c6, 0xb45fa1ea, 0xa06629ce, 0x4e797f27,
-       0xc06769ff, 0x9733467e, 0x42e2ed1e, 0x5f6a0866, 0x0a7d6511, 0x4c185aed,
-       0x28b0fa8f, 0xd8f9f822, 0x813daecb, 0x5b58c4f6, 0xbfa4bb70, 0xbfa0389c,
-       0xb1b97efe, 0x8fe7cf7b, 0x567d804c, 0x9ec953ec, 0xde5c90be, 0x41cafb8f,
-       0xda51bf7c, 0x29bdef04, 0xf9e6f3a0, 0x9052cb63, 0x86140abe, 0xe763ae7e,
-       0x5ce5f3c3, 0x018c9f41, 0xf1f9fb9e, 0xbb39d13c, 0x7f6c8ebb, 0xeebcc15d,
-       0xe2ffae3a, 0xcb0fd9e5, 0xf73b4eab, 0x87f5686f, 0x53fe7f96, 0xf078a3fa,
-       0x0b5e19ab, 0xe585ff95, 0xfe5c2dc9, 0x5685e56a, 0x6975c85f, 0x4e7d5bd7,
-       0xcf13d20d, 0xd7e27909, 0xfe7a4617, 0x6b8f9e33, 0x9e8486e2, 0x219ec18f,
-       0xea877978, 0x760e5ce9, 0x6fd8edd7, 0x5711d980, 0x665a4b08, 0xb9468acb,
-       0xdcf164d6, 0x97e01719, 0xa8d4dfea, 0xedd1f943, 0xfb0431af, 0xf5f9e46d,
-       0xffbe389e, 0x875e38f2, 0xfb9d2bf3, 0x92794437, 0x2f6f38f5, 0x7e3033a3,
-       0x85fbcb25, 0xaf7690fc, 0x9da577b4, 0x7d59ed2b, 0xb367b703, 0x7e41dd63,
-       0x5fafd633, 0xed183f90, 0xef73e474, 0xe7da28ae, 0x107b8a67, 0x731569f2,
-       0xa017143d, 0x7c0deb07, 0xbcf5dafd, 0x13ec2716, 0x413b26e6, 0x1d1ccfb6,
-       0x8d6f9e5e, 0xc2ff53d3, 0x40ca6fc7, 0xb6b3ee3b, 0xce50339b, 0xfff1a67e,
-       0x0f0fc4f6, 0x507d7e0b, 0xe15893e8, 0xf9087827, 0xedc0ea08, 0xfef02dae,
-       0xe26ec58a, 0xbe2edfab, 0x1747ca91, 0x8fe7a42f, 0xfcd265c5, 0xdc77c2b6,
-       0x23a700d9, 0x17d2552b, 0x3eee8d33, 0x91def0b1, 0x1bf91d08, 0xc799d70e,
-       0x3b63336f, 0xcce5f3a3, 0xf26c27c7, 0x1f01f806, 0xe90c7dc3, 0x09af9f79,
-       0x9d2a5ebc, 0x2b4eb356, 0x7a6eadea, 0xb7a2103d, 0xa72f11db, 0xf6226759,
-       0xfa3a55ab, 0xf3a12934, 0xaf5cc83f, 0x2366bf61, 0xd37c8feb, 0x92f5c51c,
-       0x029bdfb6, 0x9ed0ab7f, 0xd433f285, 0xcce4615f, 0x7b5e823b, 0xc4ef5d5b,
-       0x9333bc91, 0x56eb4edd, 0x3ef44e29, 0xb4e707ce, 0xc639f10f, 0x975fd089,
-       0xc775b56d, 0xc779f855, 0x185c71fd, 0xfe4f5c7f, 0xee3aed1f, 0xd570e789,
-       0x296485fa, 0xc4c742fd, 0xd9c5167e, 0xe844fc82, 0x0fe70f0f, 0x48de3aba,
-       0xd510dbfb, 0xa8b8c5e9, 0x3e7e66f7, 0x55e51a4f, 0x5a95dfd0, 0xfe8858dc,
-       0x71c67fb0, 0xbc7da63f, 0xf1cf1927, 0x4e8d92bd, 0x2c5ce3f4, 0x76680e3f,
-       0x478138f1, 0xd358eb47, 0x03ec8de1, 0xf0ec4aeb, 0x34a11a14, 0xf8d226c4,
-       0x096eac49, 0x11fa0de2, 0xa3dbf230, 0x743c8a7c, 0x213c9743, 0x91a56147,
-       0xaddb77c8, 0xbc3c531e, 0x5d467437, 0x53edfa3d, 0xe23c78ab, 0x6de9e284,
-       0x1b8d0ecf, 0x5e3932cb, 0xbb88aff0, 0xd0346fe6, 0x3e37f2ba, 0xfcd1f146,
-       0x95eb578d, 0x1f943900, 0x27fea06f, 0x9bd39d5e, 0x851f18fc, 0x880ebf8f,
-       0x4662f4e7, 0x8a10e11f, 0xbfa58687, 0x313ff17e, 0xf609dcae, 0xef3cb050,
-       0x20243f17, 0x0cfaa16f, 0x3c7d73c9, 0xc07f23d7, 0xd358057c, 0x7cc8661f,
-       0x8fe40d85, 0xbe6c6add, 0xde51e306, 0xbc431d1a, 0x2bf9efb7, 0xcd676bc5,
-       0xb6bc5070, 0xcf7dfdfb, 0x3ff6c72c, 0x118362cc, 0x87be29fe, 0x7ccff415,
-       0xc9e3c91b, 0xb1326edf, 0xd9a5b025, 0x3c53376f, 0x8e954d78, 0xeed17ca1,
-       0xe832661b, 0xa0db5c78, 0x47f8e02b, 0x0ef12839, 0x7c446404, 0xfc21bc48,
-       0x6e3198b6, 0x5fad02fc, 0x7e80cbae, 0xc7dc04f0, 0x4e906b96, 0x15d9557a,
-       0x75c817f4, 0x4c9f485d, 0xfa69ff8a, 0xc3d467e4, 0x9c5fc5b7, 0x74819e1e,
-       0x5ac3d5ae, 0x7164dbfd, 0x0bbf6255, 0x4213e1e9, 0xd7894dfe, 0x7e3043c4,
-       0xc76f0616, 0xf00c1c84, 0xff19df8f, 0x1fe3fc23, 0xe3091ca1, 0xc8c67f1f,
-       0x9da36fe5, 0x0c2936dd, 0xe627bcbf, 0x32eeadd7, 0x6f8cfea2, 0xb3cac251,
-       0xc651ab6c, 0xfae05713, 0x2b44fc64, 0xb7c0c38f, 0xde5ffb11, 0x7b0bbad4,
-       0x165ec6e5, 0x15dbe68d, 0x37b9c3df, 0x046b3ccc, 0x30163b9f, 0xea3aa38a,
-       0xa82bc918, 0xb093b8fb, 0x0023f295, 0xb8e04f1f, 0x9d638a17, 0x1d9215b6,
-       0x8656e324, 0xf8f3e0d8, 0xcfd9789e, 0x6fc447f5, 0xe27a0f7a, 0xb05d624f,
-       0x5fb067ff, 0x141602fc, 0x9971919f, 0x62af3af8, 0xc47547cc, 0x3bdadfc8,
-       0xf304b3ce, 0x3386ba3f, 0x8f5053e7, 0xa215b529, 0x72cfb53c, 0x66fc61b6,
-       0x9fee29f9, 0xf98f3e5f, 0x79012a96, 0xca2c9e05, 0x05bc4203, 0x0a7607fa,
-       0xac53b6f9, 0x5fe4f41b, 0x5abaf9e3, 0xa4f403e2, 0x756e87c4, 0xed784aab,
-       0x02a7af0a, 0x43fedaf0, 0xf919fd78, 0xe48b9df2, 0x852f0fcb, 0x9171fe6e,
-       0x8c4bf374, 0x3b090c6f, 0x578867df, 0x67407ced, 0xbef88347, 0x78db3a07,
-       0xf9d2f189, 0xa7a89fe6, 0x5dfae142, 0x5c28427c, 0xfaeb1657, 0x5166bc91,
-       0xd57a70ce, 0x4ffe6096, 0x12d891e7, 0x1e7a5c86, 0x3b7bfac9, 0x1967888d,
-       0xd5eb9107, 0xf6c88fe6, 0x0f25169a, 0xbb859fcf, 0xe039d3cf, 0xe8bfdb74,
-       0x079a101c, 0x0f9de7c2, 0x39fc8de4, 0xdcd01d56, 0xa677fc0a, 0x752748c9,
-       0x377e3995, 0x7bf7fd0a, 0xa0e7cc0d, 0xffd811fe, 0x5ffbc60a, 0x03bcb4d1,
-       0x305757fd, 0x479c57bd, 0x1db9ef95, 0x7c7c8315, 0xf2955ec5, 0xfe66d8bf,
-       0x2c458ebc, 0x4c74ff41, 0x02398e81, 0x8aeb19e0, 0x78008e62, 0x07b78dc6,
-       0x7939e5d5, 0xc13798ae, 0xfde82bdd, 0x82b31ba4, 0xae78a7fa, 0x3a9e7a08,
-       0x9ea8372b, 0xa822375e, 0xa385ef7f, 0xde99ea83, 0x67fa836b, 0xaa0e4c37,
-       0x1cde34e7, 0xab18ffd4, 0xec147c7b, 0x5bfa3fb3, 0xebcc3f00, 0xd60cb8ea,
-       0xb7ac433b, 0xa0f29aef, 0x5afd81f7, 0x53381e31, 0xcf17c990, 0x00abdf8d,
-       0xff08671c, 0x39bee5ce, 0x55cfe341, 0x677e88ab, 0x048e1a36, 0xacf469fa,
-       0xc02a4f6b, 0x38a7c6b9, 0xb95ea15b, 0xecf9f826, 0xbde81b1d, 0xf6e0bed9,
-       0xeb839bb9, 0xd29cde83, 0xb901e79f, 0x4672bf29, 0x87dfb042, 0x9989d085,
-       0xb599f4e4, 0x7aa5ffdc, 0x24e86afb, 0x27ec5f18, 0xd0438dd2, 0x9839298d,
-       0xc11d226e, 0xfaf95374, 0x0708a1d6, 0xfba3fc2d, 0x0bc9e869, 0xfe007eff,
-       0x7d306716, 0xfb4ee169, 0xec567583, 0x95efd850, 0x6acfb850, 0x2a797879,
-       0x633b850b, 0x1fd7233e, 0x688fedc1, 0xd981fde0, 0x89ca18f3, 0xa8163bb3,
-       0xe3638718, 0xecff3c79, 0xed07af8e, 0x2f898473, 0x97c484e5, 0xf80425d6,
-       0xe97c647f, 0xaf19c634, 0x67111764, 0x844ffddc, 0x8f00c807, 0x0b11f301,
-       0x71dd119c, 0x3c7f48c5, 0x653f2b49, 0xb9e3fa09, 0xfe2bd204, 0xbc3d6c78,
-       0x03e6343d, 0xc653ae37, 0x8ebe64e5, 0x930a2bcc, 0x8497fc9f, 0xb40fcc04,
-       0x75f9e347, 0x3a7cfb4b, 0x22bcc977, 0xc302f226, 0x4fa4ffd8, 0x14d7f19a,
-       0x26760bb2, 0x0afebd70, 0x176dd78e, 0xa92fbc88, 0x471a7bd7, 0x2a7adfc6,
-       0xc52a5d95, 0x2894bb13, 0xf46153e7, 0x3f0947ca, 0xe685bf51, 0xa8147f8f,
-       0x38ee6a47, 0x0bf507bb, 0x6c63fdc0, 0x6f4058b7, 0xfdbd7e2b, 0xd12b68bb,
-       0xaaebd76b, 0x9c342faf, 0xd8c47089, 0x222d8e01, 0xe445afdf, 0xd6f5c9fb,
-       0xf4baa445, 0x9c1ed879, 0x8ae327ff, 0xc28dfdda, 0x3afe71fe, 0x976417bc,
-       0x76e5cf2c, 0x870169db, 0x276e160d, 0x9db91318, 0x1f39ab50, 0xfb7036d5,
-       0xacd7a40c, 0x8c718096, 0xdfea1689, 0x4c685cdf, 0xdf8471c4, 0x42a67965,
-       0x4572c576, 0x77e47b21, 0xfcf4d1b6, 0x868509cf, 0x6fffe844, 0x6011af31,
-       0x16636588, 0x93438f5f, 0xe892fe17, 0x68c252ff, 0x36898d2a, 0x5db67fe1,
-       0x6a91f481, 0x5da91976, 0x8aa71f0d, 0x1afbe44e, 0xb464f229, 0x42718071,
-       0xdfdfa26e, 0xe2d2edc4, 0xfe4189b1, 0xf18cf7fe, 0xd0afdfc2, 0x53942eeb,
-       0xef7814bf, 0xeaefffc9, 0xf1476b67, 0xaffff5ad, 0x7ffee48c, 0xf1081f19,
-       0x85c73bff, 0x1e23fff5, 0xfe7eeda2, 0x2dd893e9, 0x3e50d29f, 0xea7a30ed,
-       0xb5d5fcf1, 0x6878ec1d, 0xa4ebe7ee, 0x7dc0c0b8, 0x673c4ed9, 0xbb64cf2d,
-       0x4b6f482c, 0x7f3b4318, 0x696ea747, 0xe95f3c24, 0x3e7c3665, 0xbf3f2d7c,
-       0x3871ae55, 0x0e529b71, 0xfdc89d5c, 0x1f380687, 0xbdf1725b, 0x27186dc9,
-       0xd9953958, 0xb2350d51, 0xda2b22c6, 0xd8596b45, 0x4168e3f3, 0x770a134f,
-       0x4276fe51, 0x0fb7cf17, 0x7693a7ed, 0x73e2217e, 0x2ce79758, 0x7971cf8f,
-       0xcf112242, 0x5f3aeda9, 0xb27d73b8, 0xa46ae8ad, 0xf0be81af, 0xc29188e7,
-       0xbb32e64f, 0x03f8e227, 0xd87cf1b7, 0x677f294a, 0xf01e98e8, 0x75e0453e,
-       0xd79e5aca, 0xff7fcec1, 0x45ed2abd, 0x9433e346, 0x2d53952b, 0x5513f43e,
-       0x697a64b6, 0x99c56e5d, 0xe5a2f283, 0x2bd6376d, 0xe86df3f3, 0x9dfd7097,
-       0x91fb4729, 0xfcb8c9a9, 0x52a3b3d2, 0x8f1e909e, 0x64d438a7, 0xf1236f41,
-       0x72409cb0, 0xc034657e, 0x92ed72bb, 0xf3d7985d, 0xc5191ffe, 0x5da80e9b,
-       0x5fb07143, 0xe6167001, 0xa567a962, 0xa648b7e4, 0x718aa671, 0x7982ffbc,
-       0xfef3fc23, 0xda75e5aa, 0xf30301cf, 0x9d1d0046, 0x038379de, 0x09e5eeed,
-       0x93cfe411, 0xaa83da71, 0x42523ee7, 0x5c1aaefa, 0xd12d4dda, 0x9c83f436,
-       0x3a61f9de, 0xb93e4dc6, 0xed05ace7, 0xbbe87fd8, 0x7c2f982c, 0x16bbd17c,
-       0x93f1c017, 0x9de52a45, 0x86f42add, 0x897dfb84, 0x271fee1c, 0xdc2117ba,
-       0xddfc5b6f, 0x2a3cc0d0, 0xe88130b6, 0xa54fb679, 0x9cb75c90, 0x168d1cdd,
-       0xbabd774a, 0x2ea82e39, 0x89b540f5, 0xbf3b85d5, 0x69e824bc, 0x6306d376,
-       0xf7e703aa, 0x38fa42ac, 0x7474e7ae, 0xe7c59b7c, 0xa7aff4cd, 0x11b069bc,
-       0xb47f83ed, 0xea2b5898, 0x81877d33, 0x8abb49e7, 0x8f0ba015, 0x9d76bfc0,
-       0xa68e5e7b, 0xc63e66f1, 0xcc1947e5, 0xebe010b5, 0x724d9969, 0x998fbb41,
-       0x25c6389f, 0xae675c01, 0xe3fa1850, 0xc022ffb0, 0xfde1679f, 0xa5fda15f,
-       0x379967dd, 0xf9480e58, 0x3cf02955, 0x79f821bd, 0x696fcb65, 0x43cc199c,
-       0x27602079, 0x735f9e69, 0xd80af50c, 0x67ed4147, 0x519b66f6, 0x14496f8f,
-       0x6ca1edf1, 0xfef0f7d8, 0x18ec88ae, 0x927e184f, 0x36c5c9e5, 0x17cfd622,
-       0x7c795047, 0x5172a331, 0xaae3a722, 0x44efb796, 0xc766a97b, 0x738e2316,
-       0x9681f1c9, 0x999bd613, 0xe896ef5f, 0x1e21af3d, 0x28252cd9, 0xe1b3504e,
-       0x32ec91ac, 0xd1529f01, 0x00f08a5e, 0x1cc2dc3c, 0x503cf1ab, 0xc7f0655a,
-       0x5bffe0e9, 0x60c3bf72, 0xd1da80bf, 0xb5173991, 0xb94fb95f, 0x5abcf96f,
-       0xf30c7a05, 0x4583e4be, 0xd8cd1f42, 0x2f796938, 0xcefd5100, 0xfc9d1963,
-       0x78f649bc, 0x516bc091, 0x8f64fdc4, 0xe3d88517, 0xb7dc3dec, 0xe64ac7a4,
-       0xa5a23d24, 0xcc07493b, 0x23f7a06c, 0x4ddebd84, 0x120f2d6f, 0xcc3d245c,
-       0xe4685d5c, 0xc8c79be6, 0xb26f4aed, 0xa326d7f0, 0x30e816bf, 0xba063ec8,
-       0xed6baa0b, 0x9d0d2ff1, 0xb41f2819, 0xe7ccb876, 0x60e7c2d4, 0x9a5fcf22,
-       0xb38d70e1, 0x8073c00d, 0x85f9397b, 0x10ca46f1, 0x3dc6dbe4, 0x6edf2377,
-       0x0ff37ce4, 0x92b30f41, 0xf049113c, 0x9af4b3dc, 0xe77fc41a, 0xf2065312,
-       0x8a6967b3, 0x3dfd0f1a, 0xc39214ab, 0x18a697a3, 0x97d3ce11, 0x7c871e0d,
-       0x345ccb9d, 0x1638b4fe, 0x9c186ed6, 0x7947e5c4, 0x6319819d, 0xf4462908,
-       0x506a9f0b, 0x9a8c2fc8, 0x6be02264, 0xf557c096, 0xa4adb78a, 0x6ff01caf,
-       0xe01f5e28, 0x2aeab33f, 0xee701f09, 0x52c7cb08, 0x66b154af, 0x3b8c0a63,
-       0xd11b6567, 0x82479c31, 0x95b2d7fa, 0x66eaaf84, 0xd5dd7b4d, 0xb9d83f84,
-       0xb589cf11, 0xf79f823b, 0x8276124f, 0xbe913993, 0x225a773d, 0xb471af30,
-       0x4ad94f80, 0x6b7286c5, 0x84b6b2fa, 0x7d3ea01b, 0xed84eaaf, 0x8587c374,
-       0x1f2823fa, 0x1cdecced, 0x719c57f2, 0x9fb09238, 0x52edcac7, 0x8619ef45,
-       0x3ce2d3ed, 0xd8cfd0c3, 0x618591f5, 0x73a1df7e, 0x11e4732a, 0xfca20f95,
-       0x341b1b2a, 0x2fbec029, 0x3112d833, 0xf365e91e, 0xb83dc593, 0xd4f84088,
-       0x7e24ac46, 0x887e45a8, 0x34c3f3f0, 0xdda17b8c, 0x7942a2f3, 0x30476c84,
-       0x34709fbd, 0x9091c226, 0x9033efb9, 0x8a6f2e9c, 0xf971f3a5, 0xea2322b2,
-       0xb16df2d5, 0xf9c11f64, 0x86cbbdf4, 0x6879f1fa, 0x649ede59, 0x39bcb718,
-       0xe306a9d3, 0x19dcf431, 0x0d39ceb0, 0x8efe2487, 0x23bf80f4, 0x7807f0e1,
-       0x4f2f6a0b, 0xe0497212, 0x238a2d8d, 0xef3a5abd, 0x58089cd5, 0x48ba99d7,
-       0xe9ec93ca, 0x8c66c47c, 0xe903fca0, 0xabdf1abf, 0x7944cfdb, 0x0e57673e,
-       0xf169fc21, 0xd3dffe36, 0xcbbda187, 0x68616efe, 0x66cb4d67, 0xf6864db7,
-       0x6fce14db, 0x19afead3, 0xddc4768f, 0xbd9e5c49, 0xd5d07205, 0x41b7b197,
-       0x0e40ba0e, 0x11f20bbe, 0x4e2fefeb, 0x8b87faa6, 0xb47e541d, 0x47951fb8,
-       0xf25fbf84, 0xd102101d, 0x2e2492ed, 0xc9249717, 0x6482faf8, 0xffc66934,
-       0x3a21ddfb, 0x6c67de1b, 0x9d36309b, 0xc15cebb1, 0xa9c6f7fa, 0xd3b5fac1,
-       0x8c971b60, 0x0a15dbe7, 0xeee5a3d9, 0xe1fd4191, 0x7bc464dc, 0x9e5fac2b,
-       0x86f49dbf, 0xe81938c3, 0xb8e2a6f1, 0x37d7fea0, 0x9fd506a4, 0xfad07248,
-       0x0ecf8d26, 0xb4b9bf6a, 0xecbd507f, 0xa431919c, 0xf1014777, 0x679102cf,
-       0x8e770704, 0xfbef1b17, 0xa4b0dd75, 0x5fbd60bb, 0x73d033ef, 0x5e243e2d,
-       0x9951ac67, 0xbe9bc607, 0x2c1fe406, 0x74e348f1, 0x0e2fafe2, 0xb25ce858,
-       0x7f6f29bc, 0x350fd401, 0xe80f2819, 0x55b8b2d0, 0x6a1daf68, 0x2832b04a,
-       0x6155cb3d, 0x2c8cd8d7, 0x2d15de40, 0xa6f9425b, 0x93933e65, 0xef7697ec,
-       0xc0eeb293, 0x122e2af3, 0xd53de4f9, 0xfe10aad7, 0x67df045c, 0xe15ee922,
-       0xf127b071, 0x4ef4e12a, 0x0ae3aebe, 0x13f5865b, 0xb9f71f91, 0x6a71d60b,
-       0x0e856362, 0xbeea15fd, 0xcf9f9204, 0xb6e90cab, 0xf2819e74, 0xafbf660c,
-       0x533ac06e, 0xbe395372, 0x66a3ca55, 0x7c6898cf, 0x021405d6, 0x6d3c16fd,
-       0xae01ea7a, 0xfb7d78ff, 0x8203df40, 0x8e8e913e, 0x2c5732c7, 0xf5a1562d,
-       0xc276fe7e, 0x87ee7c06, 0xee106fa7, 0xfdc1bd7b, 0xefe01266, 0x20df0af3,
-       0x128b6f92, 0x70b4af88, 0xf2e4623f, 0xa07c8bcb, 0x9fa6e5f8, 0x7e9296cf,
-       0x26706e98, 0xe56e493a, 0x3adca0a7, 0x7640d2b2, 0xacbbd330, 0x3e8f4893,
-       0xe72c744f, 0x8c77a239, 0x691df5c3, 0x5f9864c8, 0xa552be51, 0x1fd20af3,
-       0xe7e3efef, 0x0f5587d4, 0xdbcc24d8, 0x525878a0, 0x3edcdd28, 0x5de5186f,
-       0x596ded6a, 0xeabc097e, 0xe64bb009, 0x8179e4ec, 0x3f53bf2c, 0x3ee06075,
-       0x3cf9f196, 0x4af94105, 0x1daf5955, 0x2ec8eb34, 0xc273c18c, 0xa254f789,
-       0x8d5913b3, 0x9f019343, 0x86bb7527, 0x2ff505de, 0xea8f7a26, 0xda223ea1,
-       0xeb842ff3, 0x0ccadd5c, 0xfaf30b25, 0x091aaf0f, 0xacfe7def, 0x2e6c49c1,
-       0xcf39fcec, 0x43fdeecc, 0x1bd815f6, 0xe1ddb8bd, 0xcffbc14a, 0x1acd1d73,
-       0xc7c3807b, 0x00204981, 0x056adb17, 0x7876376d, 0x3c01e588, 0x31d74f57,
-       0xe079e04f, 0xb1e3c8b0, 0xa873f324, 0x24a61bb4, 0x5d333973, 0xbd9be9c7,
-       0x037a70ac, 0x0f502afb, 0x173db948, 0xbf55aaf3, 0xbb72901e, 0xfe52358a,
-       0xdb99238a, 0x1f15b32f, 0x9835ddd9, 0x2bfd0289, 0x56683c6c, 0xf3e4d9b5,
-       0xb698d265, 0x7a60fb40, 0x73279732, 0x8e3ecf8c, 0x3ac95be4, 0xfd353ef8,
-       0x2af8373e, 0xf543323a, 0xc36d854f, 0x6f8d3b32, 0xb79fa270, 0x756bf052,
-       0x256be2a3, 0x51eb853b, 0x299d57e9, 0x3f56a8f4, 0x8d25e885, 0xd1a99a3e,
-       0x5831acbb, 0xe97ac2cf, 0xaf5cb2de, 0x68ee9d76, 0x0e61c10b, 0x6ff50bac,
-       0xa7b7c785, 0x38add684, 0xeb21a301, 0x31ee64a9, 0x780fb8b1, 0x5d08eade,
-       0x215f769f, 0xd4fb15eb, 0xf9c2bbae, 0xbbe62b55, 0x04293554, 0x243eed2f,
-       0x9c76b43e, 0x97854bc4, 0x45a2b7c3, 0xd67e7c21, 0xf2321f6d, 0x61ba4b6f,
-       0xe02ff0cd, 0xb047497d, 0x6f9412af, 0x1e41ab95, 0xd3d28667, 0x456cd61c,
-       0xad61a9ba, 0xdf9053cb, 0x1faf9b5a, 0xb5867e8e, 0xa9f9d36f, 0xa39aded4,
-       0x7a50058b, 0xbf8e5773, 0x17e74fca, 0x5cfc278a, 0xe9ddc3f0, 0xe01e9fa5,
-       0xeaa37335, 0xd4141c8a, 0x7a3fe44f, 0xbcb38e09, 0x63fa235e, 0xe53f0967,
-       0xab59d685, 0x2e5ff7e7, 0xcf015eb8, 0x0fdd7b9f, 0x7764f727, 0x76173f85,
-       0x3d1a5bdb, 0xfb81b1ff, 0xfe7ca55b, 0xff22ef5a, 0x3b0bb42e, 0xe3c6ceac,
-       0x9eb91a7d, 0xbd724f9e, 0x3979e842, 0x5b35d1cf, 0x13305e29, 0xf68080ed,
-       0xa56f56cf, 0xd9f1a578, 0xcbb45699, 0xbe99ae8f, 0x8f52f30a, 0xbd274d36,
-       0xa97bf95f, 0x40c63df7, 0x4d68a27b, 0x907bfad9, 0x5247378e, 0xdda2b15c,
-       0x2045ce23, 0x639fa167, 0x6cab970d, 0x95b39735, 0x90071fa8, 0xfd8bec7e,
-       0xf4f0acee, 0x68087e45, 0xe779bd27, 0x779fcf74, 0xfe77b8c2, 0x25e9da29,
-       0x755ad850, 0x5adbcf64, 0xcf563f51, 0xde20f0ff, 0xe07b01d3, 0x7b4b5ffd,
-       0x0645aa00, 0xea325b4f, 0x54076121, 0x6c321bab, 0xbd083768, 0x7f801ff1,
-       0xe7f87844, 0x11cbfc12, 0xdbf101fe, 0x9c381b4f, 0x7fe06ba7, 0xcbc72578,
-       0x2b6ca6f2, 0x6d3f2f9e, 0xebbb26c8, 0x821ca6d3, 0x00078cff, 0x1f5fdcfe,
-       0x0035776c, 0x817cf1fc, 0x96f587f0, 0xfc043bb7, 0x0dfe1c9d, 0x256cee1c,
-       0xc084672f, 0x57f94bd9, 0xe4d1fe77, 0x78e23b44, 0x57d92b64, 0xaca8b7c7,
-       0x932ec03e, 0xac37d176, 0xdfb449f1, 0xf767fc24, 0xf28418e9, 0xd7e1f4a7,
-       0xd98788ac, 0x3150785b, 0x95ccfe04, 0xeec7f144, 0xa8edbbf9, 0xdd5f116f,
-       0xe245d476, 0x19b986a9, 0xd796c7e9, 0x4239e00e, 0x45bf7171, 0xb66fbc8d,
-       0x19bef823, 0xda9592e6, 0x8ce2c5d1, 0xa4f5c088, 0x79d3ef69, 0xbebdc618,
-       0xd6eaf9cd, 0x5de7c4f9, 0x25b97941, 0xfe80d5ac, 0xd0acd636, 0x05eaed3d,
-       0x8642d685, 0x5a3ab571, 0x09453387, 0x56aecbca, 0x564f6475, 0x447c4519,
-       0x892455e4, 0xdc29497e, 0x629c902f, 0x2474f2a3, 0xda707d23, 0x7de1f462,
-       0x255f382a, 0x9ddefce3, 0x41dbc226, 0x5fc0135c, 0x333f0a35, 0xb7a442a8,
-       0xd3a7185b, 0x297bcc5b, 0x972707ae, 0xa71fa875, 0xc939342d, 0xa18f8dce,
-       0x42cdd2f8, 0x5e62ddde, 0x313d46ee, 0x61746ccd, 0x317ae309, 0x1a30d7f9,
-       0x0df987a6, 0xef748cbd, 0xf3a234b0, 0xdf123c59, 0x8ef87c96, 0x95ea5808,
-       0x1fa38e60, 0xf6dd7e18, 0x5e285c7d, 0xf609f8fc, 0x8546d74b, 0x170c8bf7,
-       0x2e5c5070, 0x609b3ff2, 0xc75828ec, 0x6f0714a8, 0x3fb8d877, 0xc9e02d7a,
-       0xb6afc7e2, 0xfc79799d, 0xb1f30ab2, 0xbc58f7f9, 0x5d541f24, 0xc8cabd50,
-       0x62794f9f, 0x34eaf143, 0x8e61dec6, 0x2ab78881, 0xee782194, 0x61f18b2f,
-       0xf43aef7c, 0xd4b1db87, 0xd64cbd13, 0x978eaf33, 0x0e3b660d, 0x25e3fdc7,
-       0x2abf9e02, 0x0031ad60, 0x83d7d6f7, 0xb437f3fd, 0x02fb5aea, 0xb7d3af7c,
-       0xea7d21b6, 0x1b061c22, 0xaf1ee3cc, 0xa539e2e4, 0xadc5e96a, 0xa689e2b7,
-       0xa0a3d5e2, 0xacf9e3ae, 0xfee6bf5d, 0x59805b89, 0xeab76e11, 0xcb9abb59,
-       0x52e100e9, 0xa978776b, 0xe2853cdf, 0x202e3237, 0x86183ff1, 0x2de3c40f,
-       0x4e307d62, 0x37df1583, 0x7cd7c786, 0x8ccc2f81, 0x15cfb846, 0xf257377c,
-       0xbf30535b, 0x0478823d, 0x2ed0553e, 0x22ddb806, 0xe2f89eca, 0x476e14a1,
-       0xcfc2943f, 0xe25cf7ef, 0x95dccc7c, 0x82797941, 0x7c4daa5f, 0x75ff397c,
-       0xc5307ca2, 0xf5cbe34e, 0x8a7ebd00, 0x0240e8e3, 0x691ebd20, 0x68fb27ac,
-       0xc3880b16, 0x49fbfa65, 0x77ad0eba, 0xf7dd11cb, 0x66bb1a58, 0x5f95e820,
-       0x8e513a44, 0xce6c62de, 0xf68733a9, 0x52e67193, 0xefa061d6, 0x993f4903,
-       0x55633fd0, 0x9535e533, 0xf41efc2a, 0x578b42e9, 0xc7e27607, 0x067bbe22,
-       0xa79c46ec, 0xfca15634, 0x773169af, 0x975f2096, 0x2c7a8d5a, 0xdff1163f,
-       0x8d17595b, 0x2b2d89ff, 0xdf8606e6, 0xe631504d, 0xa4f80b07, 0xadfb05d8,
-       0xebc3f947, 0xe4695d2b, 0x4ff5128d, 0x665c61f7, 0x03a079ea, 0x762e1faa,
-       0x5fa7bcc1, 0x91d9cf15, 0xfa7e7c62, 0xdecf413e, 0xe9de34e3, 0x53f3e4c7,
-       0xf90af9fc, 0x7f5e2bfc, 0xea2f8e50, 0x2f9e6b0f, 0x827f3cd1, 0xf89f5bd7,
-       0xf68bd8aa, 0xda4e68eb, 0x921423a5, 0x37214657, 0x12b6974a, 0xbb754b9c,
-       0xb59a3978, 0xdc2ff2ea, 0xdb8a64ef, 0xf7809298, 0x50588fce, 0xd533ff0f,
-       0x7e814c65, 0xfe79269f, 0x499ce586, 0x7288d78a, 0xe91f3df7, 0xf21e9285,
-       0xae428d27, 0xa6e5ea9f, 0x831ea5f7, 0xf1c3de71, 0xbb9c752f, 0xe4f9c743,
-       0x4d738cc7, 0x4738c86a, 0xfebecc7f, 0x24e1ca9c, 0x517691c7, 0xe94bba71,
-       0x663afc85, 0x70bf9064, 0x18cebdee, 0xcc314bf4, 0xcfd00377, 0x919cda5d,
-       0x7dcfe307, 0x0a8cc5ee, 0xbe849bb4, 0x32a739af, 0xdaa3c817, 0x5f950a73,
-       0xc4647db4, 0xdb35b37b, 0xa0e38cda, 0x45942d5f, 0x12aaeb01, 0xa77d04eb,
-       0xa7a01c9f, 0x4274bd8d, 0xf3cc3c6e, 0xa13b9e32, 0xd5ce7c47, 0x3dfd1f35,
-       0x4a11efea, 0x97f2f8d8, 0x7b077f62, 0xee611fb8, 0x6151e5c5, 0xee34576f,
-       0x390614f3, 0xfaa2fc60, 0xbf02f9f0, 0x1528eb12, 0x50fa6ffa, 0xe003844b,
-       0x1e3de43c, 0x9b58af5f, 0x62fe8b99, 0x04e8f263, 0x7e8f5b82, 0x67ee2ed6,
-       0xd67ee16d, 0x02c77b52, 0xbb994efc, 0xf883ec57, 0xbf09b2dd, 0x2c067c93,
-       0x378eef0b, 0x89bf7ac9, 0x3f714663, 0x7ef3d618, 0xf220f99f, 0x6e28decd,
-       0x361b4ecf, 0x43e50a30, 0xceb46667, 0x4facfc06, 0x4af7732a, 0xc6abf6c0,
-       0xc9a17b61, 0xe08ca7d2, 0xf42e88cb, 0xb8feee49, 0xfe8fec4e, 0x35b18f11,
-       0x87d806e1, 0xee950de7, 0x45067803, 0xcbc5c27b, 0xe5c5ef2f, 0x8d97bbb9,
-       0x0757b1e0, 0xaff5cceb, 0x760fce43, 0x180e82fd, 0x94d2c8ef, 0x30380fc1,
-       0x5d78531e, 0xfcff04af, 0xa33c92b3, 0xa23fe702, 0x68f07d63, 0x18ebb171,
-       0x1d71f02e, 0xf74a06c2, 0x80b7a028, 0x31e4def3, 0xa9f541d1, 0x15cc71c5,
-       0x9a9dbfe8, 0xb1bf541a, 0xffa83b34, 0x07fa33cd, 0xea689f3d, 0xb00bafc8,
-       0x97b67b67, 0x5a9f04bc, 0xed0a258b, 0xbe5a4fba, 0xb416e0f9, 0x4eaa3703,
-       0xef6759b4, 0x48c1f4dc, 0xf00675e8, 0x497e471b, 0x3ed1f907, 0x7a747997,
-       0x7e303e97, 0x50758a74, 0xd73ca2be, 0x68dc6c5e, 0xf29dadae, 0x78ae7f09,
-       0xe25ebcd1, 0x72cb9bfc, 0xa99e3f51, 0x79fc9f7b, 0xcfbe6635, 0xe21e2f53,
-       0xbd442ddf, 0x357f7402, 0xe2f688be, 0xc0fc1039, 0x0e3b45ff, 0x86cd9c51,
-       0xf7b44dc1, 0xf1e9e6d3, 0x942d64fe, 0x81c65fa8, 0xba018adc, 0x036368e9,
-       0x48de61b7, 0xe5db85a6, 0xbf90a6e7, 0xf7146f7c, 0x8c4decfb, 0xcc48efa5,
-       0xda86b86d, 0xd345ce6b, 0x1da96ff8, 0xfa2f28e3, 0x13e28505, 0x2da75313,
-       0x8decfdc5, 0x1db80ef2, 0xe7f89de6, 0xdc23c7ab, 0x7bf1b66a, 0x77d51302,
-       0x5941e7f2, 0xbd0d78d5, 0x7b65513f, 0x621fb015, 0xe342ddce, 0x001b444e,
-       0xcb50eaea, 0x5597a803, 0x3f9f6b63, 0x5a31bca0, 0x9ed4de48, 0x26f7a48b,
-       0xfdfd7114, 0x0c4f217b, 0x635d7c9d, 0xe7a24dcf, 0xbd7c2e92, 0xf7f282b2,
-       0xf51b090d, 0x4321bdf8, 0xaffd42a7, 0x4a9fd73d, 0xfa37dfb9, 0x2fbe91fd,
-       0x7af84860, 0xbe8de61c, 0xc8d8af11, 0xe3c8d12c, 0x62c375b3, 0xd5791858,
-       0x9e39cf3d, 0xc73a6c6f, 0x3bff8ff3, 0xe417f5cd, 0x9d4592c3, 0x31178c7a,
-       0xe10d8473, 0xd8305255, 0x67c01151, 0x8c9baeea, 0xeac31f88, 0xafa88db7,
-       0x0516504d, 0xf916af3c, 0xdd795a58, 0xfc83e422, 0x3fd49b8e, 0xd106792c,
-       0x4136ade7, 0x9e8f82a0, 0xdf2c7c16, 0x0e33a0ef, 0xf73b71e0, 0x79a6b7f3,
-       0xd13942de, 0x7c6ec851, 0x4767e49e, 0x7e69c606, 0x9e03f5ae, 0x1bb21423,
-       0xbeaf293b, 0xc3a1c0a4, 0xdd7bc0f8, 0xf3f3877a, 0x26d1f685, 0xca96fdf6,
-       0x6fb8e216, 0x1d97f2fd, 0xedaf182e, 0xd43cbcee, 0xcfde720b, 0x0b7bf17a,
-       0x1e75d6cc, 0x2fb587cf, 0xef903b47, 0x0ce1e227, 0x4d3ba2e3, 0x76816e74,
-       0xbed4778a, 0xef0a7a6c, 0xe15ad5bb, 0x17f30afc, 0x8ad912bd, 0x4af6dc74,
-       0xc7f51ea4, 0x9f3dbd1d, 0x5e8a7c21, 0xcf063be9, 0x9316ae8b, 0xe3fd919e,
-       0xb6f24a3a, 0x485ef587, 0x4ce9697e, 0x81a7a7f2, 0xa0994bf3, 0x7fc172d3,
-       0x6747c11e, 0x0f8892eb, 0x45822ecf, 0x91753c63, 0xda1b7032, 0x7d0b0e0b,
-       0xe5f24e97, 0x411f3c44, 0xb1fec4fb, 0xeaa18f74, 0x1f106c5c, 0x14cb9f56,
-       0xed471dfc, 0x05cadf92, 0x7d84989f, 0xb5d04331, 0x3f245bb4, 0x624f74b2,
-       0x6263ec2a, 0x95bdf03d, 0xc8f9fee2, 0x31ba7e4f, 0x80be90da, 0x022b926e,
-       0xedbea7f8, 0x8a768626, 0x744dde29, 0x40ca0333, 0xb766653b, 0x971b629d,
-       0x592feb08, 0x7bc3a996, 0x6a79f29b, 0x7fd1a5ea, 0x27c8aa44, 0xa0e6b730,
-       0x8ba86b5d, 0x9a7de274, 0x1e3cf133, 0x87057f34, 0xbb837ce3, 0xf98ced08,
-       0x3fe4284f, 0xe503fb43, 0x7503d0d2, 0xcabf40c6, 0x5106e74d, 0xb9ca7d3c,
-       0x2634a8cb, 0x38472e7b, 0x5ebb9d94, 0x8fd06be0, 0x710e3f8a, 0xc192bf71,
-       0xc86e7267, 0x4792bf44, 0x4f1f3c45, 0x0347b667, 0x546b7de3, 0xb8c98ff2,
-       0x9933f4a4, 0x804fdef0, 0xdf46fd3e, 0xa3df4198, 0x0a9dfad1, 0xb93ffeb9,
-       0xbffa40d1, 0xa19dedaa, 0x79fe783a, 0xf5092ba6, 0xa7837ac9, 0x6733f708,
-       0x0339efb2, 0xb83ee7d4, 0xe1dc3ad5, 0xbeb36787, 0x69f50735, 0xfd11c033,
-       0xd52bcd5f, 0xf76e3ef1, 0x1a38f344, 0xcf496fa7, 0x739f3a5a, 0x73e09b2e,
-       0x7a44ceb6, 0x2dd02ce8, 0x5243d00b, 0x2f3948ef, 0xeba48ff5, 0x5f973d6a,
-       0xca18e6d5, 0x9debf323, 0xa442ee49, 0x1f3c7ebb, 0x9e77afd0, 0xf902355a,
-       0xe53c74e0, 0x21bd4b5d, 0xc585e0f9, 0x244794c9, 0x03e492f5, 0x7ca5cf29,
-       0xf52f7497, 0xfd3fe8d6, 0xc3bfd6ef, 0x3cd293af, 0x7d02a577, 0xfae7ab5d,
-       0x85bd5aeb, 0xfc6c67e8, 0xcdd23d24, 0x43d1cbc5, 0x0a1e8e42, 0x3d35a392,
-       0xa94581e8, 0x1c5e7e52, 0x7c11cc1f, 0xedc4de33, 0x81f39448, 0x8da6b5e3,
-       0xb1f7087e, 0xd9eb953a, 0x3ddd6b9f, 0xa9d5ffc9, 0x97ff2697, 0xfc9c5ea4,
-       0xfe54efff, 0xbcad0a9d, 0xa3710fc7, 0xf3bd3fbc, 0x83ea1f72, 0x03f40c83,
-       0x6896c1ea, 0x0fa126c7, 0xc5445f48, 0x1f487ef8, 0xfe9ef614, 0xf5e1a9df,
-       0xff6c66c1, 0xd240fab1, 0xc91be497, 0xb42f9227, 0x62f9247c, 0xbce16fc2,
-       0x8b7a7888, 0xd6aa8fdf, 0x0e289b7b, 0x8c1e88e9, 0xc76dd9fc, 0xdf88536d,
-       0xe084f442, 0x04bf3f1f, 0x1fc90deb, 0xff245f92, 0x98fe0b54, 0xf243f829,
-       0xf9b56ec5, 0x0a9811d1, 0x08f9e690, 0x93e488e5, 0xfab5e7aa, 0x42ba47a1,
-       0x199b234f, 0xae90c75f, 0xa40ca1aa, 0xfc0f532b, 0xf512f070, 0xa48bbec2,
-       0xf3feafa7, 0x0f55f4f4, 0xa7e674f4, 0x1da853d0, 0x03be61fb, 0x1f3673d6,
-       0x9fa66de4, 0x8dfc26de, 0x9b21fb71, 0x46f6079f, 0x35ee7df1, 0x67ff93a6,
-       0xcf3cf7c2, 0x3303da57, 0xd241bf85, 0x01d81e69, 0xf8fc4369, 0xbcc0f3c7,
-       0x847b938b, 0x877c5367, 0x3327cf11, 0x03b40ca1, 0x537fb27a, 0xee4d2ed3,
-       0x17fe8a45, 0xb480f3c2, 0x1c6edd9f, 0xaf1e1690, 0x027ed303, 0xa262275e,
-       0xb22bf92a, 0x00a35c4b, 0xba890f3f, 0xc2094fb7, 0xf902faf1, 0x2e55b2fc,
-       0xd607ca3d, 0xf475ddfd, 0xcaa5bc77, 0x31fece7a, 0x8f099eb0, 0x1d1fbf32,
-       0x151d8f9e, 0x511fedd3, 0x717fbf98, 0x95fed65a, 0x451be7a4, 0x9ea74ade,
-       0x3d4483c7, 0x8096ea1f, 0xbea6817a, 0xeab7f796, 0x3e60593b, 0x928dd209,
-       0x0eecf1cb, 0xfa601fb0, 0x2fa8b3f6, 0xff430a6c, 0x86fc6d46, 0x5ca2cf57,
-       0x6c50a1db, 0xde0e1baa, 0xfa070481, 0x07d5383e, 0xc65d77ef, 0x78dbcdd8,
-       0x43b5f6fd, 0x132f7956, 0x1bdc06e3, 0x2e2b3432, 0x502847ca, 0xa199597c,
-       0x4d3dbef0, 0x1eb913ca, 0x0214f746, 0xaf9867de, 0x77ef2977, 0xd1674de7,
-       0x4ba6adfb, 0x5186ff98, 0xac6fefe1, 0xe4c6fd10, 0xfe7d84c7, 0xe1ca9a70,
-       0x3406fc2f, 0x694d343f, 0xff9f7f0e, 0x1d2fc109, 0x78213f18, 0xfe855a4e,
-       0x84a30eed, 0xc2157bb7, 0x41632c7b, 0x9f98347e, 0xbad71bea, 0x7cf41a4b,
-       0xbc0d2ebb, 0x77bf687e, 0x03db05a5, 0x5f069bf4, 0xf7801fa6, 0x77de61dd,
-       0xfadfbf04, 0x125af843, 0xdba0bef2, 0x5d8e9259, 0xa31ef441, 0xc67d1377,
-       0xb4362bc4, 0x91dc6ba3, 0xe0bcf12b, 0x12d2cfe7, 0x138c9b82, 0xb4dff084,
-       0xc8033192, 0x6fcf124e, 0xebfc855b, 0xe7f775d6, 0x1ae928fc, 0x5c0136af,
-       0xef07f5c9, 0xeb769cbf, 0x024ff42a, 0xaa73d05d, 0xadd603eb, 0x4d66c7e5,
-       0x7f86947d, 0xfc91ff05, 0x70007d40, 0x16f941ca, 0x08e8c87f, 0x044f93a0,
-       0x7c894e9c, 0xdcd18ef2, 0xe2c8ec9e, 0x3c6977e5, 0xa099f52e, 0x9e9253cb,
-       0x90e002a2, 0xf43f4416, 0xf60221f7, 0x29ba704d, 0xbdf3f25e, 0xbfc0c525,
-       0xfcfe761d, 0x66fed67f, 0x5fcd3795, 0xcff78ed7, 0x2096f7b5, 0xf7c7ba5c,
-       0x768fda2e, 0x6e024dc4, 0x67bdaddf, 0xc08077bf, 0xbbffa273, 0xf41f40ab,
-       0xa46a9e3d, 0x3e94250f, 0x2fa50d5e, 0xfa7de6af, 0xbd3d043b, 0x7950b7ff,
-       0xcfbcd2e0, 0x17107bf0, 0x5bc0beff, 0xe3af06b1, 0xa31d7835, 0xbaca97a9,
-       0x4afe482f, 0xe3be5cb9, 0xe312fbe1, 0xd0a9afd1, 0x3d3f2475, 0x3cf4483f,
-       0x77e926d7, 0x4fd5c115, 0x47ed0fcf, 0x2cdc9dfa, 0xf491b5e9, 0xc39424cf,
-       0x29f5fc23, 0xfea88728, 0xc5c60970, 0x91eafafc, 0x6fb72855, 0x1ffd9068,
-       0x2f37fea5, 0xa6ade393, 0x8c8f12e7, 0xeefa463d, 0xafa97ca6, 0x3fb9271e,
-       0xefbf85a7, 0xfeddff4c, 0x4687e41f, 0x6ad65c0d, 0xff4d5eea, 0x6fd017d5,
-       0x2fef34cb, 0xa95f3cd2, 0xd4d1afa9, 0x2fdf821b, 0x1f10a19b, 0x38f01596,
-       0xb52f96a5, 0xef4ae1f4, 0xf5ba73b6, 0xfb2662b9, 0x26af882e, 0xb5faf3d4,
-       0x1a4b1be9, 0x75f501cc, 0x5f384a9b, 0xf7016cc0, 0x7ae6419f, 0x4307a055,
-       0x20b3720f, 0xd9b907bd, 0xf9efab4f, 0xafe07ff3, 0x0a371429, 0xab764bb2,
-       0x5536f5c1, 0x75bbdbac, 0x810182ff, 0x4be7d5f1, 0x63dd5cf0, 0x5cdbc71c,
-       0x2ed02632, 0xae25cd62, 0xfeca7d80, 0x5efbbee3, 0xeb3cf9c5, 0xd1b25cfe,
-       0x114f718c, 0x12f3b4df, 0xfa8aa5f4, 0x6ff856ba, 0x2f1e61c6, 0x5aa293c6,
-       0x080fe673, 0xee6b27d8, 0xbb6cfb83, 0xb7dfe55b, 0x00fc07ab, 0x8398ca9c,
-       0x33a750f2, 0xb6a5e517, 0xfc2cc4c5, 0xf76f782f, 0xd442eadd, 0xc61707d3,
-       0x2bd35e51, 0xb17cfce9, 0xe277a63b, 0x45b7a84c, 0xb6f246df, 0x54b1feed,
-       0xcb5d52ee, 0x2d8c6cbb, 0x894af75e, 0x1e7c72f9, 0x3bba7043, 0x2592a5fd,
-       0xa6f7ef40, 0x8f7de83b, 0x03b896dd, 0x0c07eded, 0x0e043714, 0xe7e89278,
-       0x3c60d341, 0xe92d976f, 0xf2b1714f, 0xc38d26c7, 0xf7e5a47b, 0xd25e2819,
-       0x9f91b3a9, 0x58c0f3c8, 0xb19a93ca, 0xabde944c, 0xdfe57ca9, 0x7bc7ac7f,
-       0x14eb5da6, 0x55cd4efa, 0x6dff375f, 0x1b2bd410, 0xc67ee9b2, 0x9474e7cb,
-       0x9ae9fe17, 0x53cc3ebe, 0x47591c3e, 0x9fd0a5f9, 0x9e56bbee, 0xc92fec77,
-       0x0daafec7, 0x428e3853, 0x47cfda3b, 0xe14fa857, 0xab32ce3d, 0xbbf30a25,
-       0xc8c77e8f, 0x3ef473af, 0xe6ef7d13, 0xd6e7b353, 0x8f74f135, 0x767d2d09,
-       0x15587154, 0xf4dac380, 0x29c925fd, 0xf8126ed8, 0x032d6fdc, 0x75d32f3e,
-       0x93e90fd3, 0x5f5e588a, 0x92cdeebb, 0xa38fb04d, 0x7ca5f44f, 0xd70c84b1,
-       0xd78074ba, 0x93d70ce1, 0xd9fb8a54, 0xc79bfcaf, 0x593a5f25, 0xb5f4889e,
-       0xcbf5d059, 0x0313cae7, 0xc5416eff, 0xc1d13d29, 0x02c7462b, 0x5469eefa,
-       0x6ce782ba, 0xf43883a0, 0xe710cf9b, 0x85e7a016, 0x57d8c35b, 0x3db9d34b,
-       0x84dbf6d6, 0xba208e51, 0x29e498fe, 0xfea0379d, 0xa447fa62, 0x16988ee7,
-       0x77752e62, 0x1ddb243e, 0x34327049, 0x3322fa45, 0x1aea7fd1, 0x4ff3a2e7,
-       0x96c99f73, 0xfd143e00, 0xfcf2f13f, 0x3fa04fdf, 0xf13efb9e, 0x604b3ffe,
-       0xaff6433c, 0x68bc5ab4, 0x58b31c5c, 0x838f88f4, 0x3147c5fa, 0x9d62ad3f,
-       0xc540f481, 0x5d4584ba, 0x6e807f28, 0xdda6bfd0, 0xc0c32997, 0xc63d18fd,
-       0x192f3f57, 0x5e781693, 0xbbf24139, 0x377cbe27, 0xc6c944fd, 0x65f33d01,
-       0xa7cb8da5, 0xf7f8eb71, 0x58872b75, 0x7bbf74f4, 0xe89babdd, 0xc8bcf01e,
-       0x5157bc5c, 0xf844ceb9, 0xbc58b4ea, 0xbef12bb6, 0x0b1f4581, 0xae74a1e5,
-       0x0e19f54f, 0xca9147c2, 0x54b911f4, 0x190a3dd2, 0xf0b13c3f, 0x1d31c7d1,
-       0xbbe673f3, 0xefc0187e, 0xe9d38b8c, 0xf92a6d99, 0xc4f1b51f, 0x1ab7d7ea,
-       0x888fd90b, 0x4710f627, 0xe29d62ac, 0xe3e1e2bb, 0xe238da89, 0xbdc5d2bf,
-       0xa238eeb3, 0x5187be81, 0x4588e229, 0x7f5a156b, 0xbdfe42e5, 0xee38a292,
-       0x18b23e3f, 0xed2fa0e8, 0xc5cb6bdf, 0x7fae693c, 0x8be2992a, 0x5eaf5f80,
-       0x99fc8f3b, 0x5e1ce975, 0xb03be265, 0x199d2387, 0x58afde78, 0xae704917,
-       0x07f6727c, 0x7de3e44f, 0x81f189c0, 0xa09b6be7, 0xe19f180f, 0xce39683d,
-       0xd0f725b1, 0xd68b6777, 0xf31939c3, 0x73d963b4, 0xde226537, 0xde303252,
-       0x2e55fb29, 0xef0fbbbd, 0xd86ce707, 0x950ad977, 0xbb6b0f7f, 0xf021f489,
-       0xb80b327c, 0xd9633e2f, 0xd72346eb, 0xa8792c67, 0xfe1db3b0, 0xc29f6cfb,
-       0x4104fc73, 0x26b7b8ad, 0x5bef27e1, 0xf7f8e995, 0x0a754b36, 0x8902c3dd,
-       0x7e97f746, 0xa3fdc191, 0xcedc1979, 0xd270cb2d, 0x55ea9e3d, 0x4cd2e726,
-       0xbdf74e3e, 0x55e73875, 0x282a3aeb, 0x1317f9ae, 0x976a57f9, 0xad22ba45,
-       0xf9e31f3c, 0xad779401, 0xaa3c0237, 0xfc6e5c1c, 0xad63d042, 0x94d5d263,
-       0x0767ae9f, 0x5607eff0, 0xac9cb85b, 0x9bb8058e, 0x86e90139, 0x1939f7e2,
-       0xb8e253e5, 0xe6028329, 0x8c3b4457, 0xc7fab0e3, 0x0d63abdd, 0xfec1a7e8,
-       0x38420f97, 0x237f5dc6, 0x9559efae, 0xb4801af8, 0xbfed00aa, 0x3c3cd567,
-       0xd8ad9777, 0xf0e50e3d, 0xf1832ddc, 0x7b2b0546, 0x23d25dee, 0x3bfe0573,
-       0x395a3e45, 0x81bbf1d4, 0xb9706437, 0xdfb951e9, 0x2f0106e8, 0x79f20749,
-       0xf7030af5, 0x47bc83e3, 0xe4bd5301, 0xdab71a43, 0x728891d2, 0x81bb7ab8,
-       0x8cdf87ee, 0x973806eb, 0x751f492f, 0xdcaae800, 0x51df4310, 0x344ef2ad,
-       0x51aabd62, 0xbdffbaa1, 0xd3a40c84, 0x60bd962f, 0x1c39fa45, 0xfa839ad9,
-       0xa45e6ba9, 0xda29ee93, 0x8beedfb8, 0xaf743965, 0xc3ad8669, 0x9965df82,
-       0x8edb20b1, 0xada0fc72, 0x0fcf88d5, 0xb0ea6736, 0x46d9b2ee, 0xbfa5dd61,
-       0x885fea92, 0x41fa177c, 0x9e3852ba, 0x1b769aab, 0xdd2feff1, 0xd4e2e82b,
-       0x41f6efb3, 0x4675503f, 0x2fd41f47, 0x527d0740, 0x28cfce11, 0x9a6b9fa4,
-       0xa4bc1e78, 0x03a41a83, 0x8239bbe0, 0xbdb66a0e, 0x43f21770, 0x373fe20d,
-       0x9e808e94, 0xf9fda9db, 0x7f18e30d, 0x44e91dbf, 0x2fa833ea, 0xce3fa033,
-       0x058bebc8, 0x0c7da1fe, 0xe00ef76f, 0xf9dd75f9, 0xd07c4108, 0x66d77e13,
-       0x4c3e04e8, 0x8ad77724, 0xd8ae76fd, 0x9dfc456e, 0x1ef7767a, 0x3f54b78c,
-       0x11dada0f, 0x3c041f86, 0x56ff716a, 0x19d93f5a, 0xab5fb8b5, 0x74ddff7f,
-       0x96b0f82f, 0xfdc9fdf1, 0xfec5ead6, 0xfef173e5, 0x2acfb13a, 0xadb5e026,
-       0xc13be72f, 0xf4c7c867, 0x3fb121dd, 0xbbf83d8f, 0xfec5bbba, 0x6cc9449a,
-       0x0f8456cd, 0x0fe517e2, 0x28cb8fd0, 0x397409e5, 0xe50365b5, 0xc97c4bf7,
-       0xd7efbff5, 0x93fc2e2b, 0x9d8f1254, 0xb6f77c3d, 0xa1c9f045, 0x763292fb,
-       0xd8befc00, 0x240d9f4c, 0xcc07d57a, 0xce46e927, 0x49a7f457, 0x61bee2d7,
-       0x5f1c56fc, 0x1bd07bce, 0x0e71c7ad, 0x721fce32, 0x8b2f92fd, 0x3b5da7ea,
-       0x4efd8ad8, 0x5ed1b259, 0x3f7c7811, 0xbbef46c3, 0xf7806ed0, 0xf2143b5d,
-       0xe7121f5f, 0xbdf743fd, 0xe01f2d60, 0xc577f7a7, 0xe19d25ba, 0xe4c9fa0f,
-       0xb9daf77a, 0x6ebb583f, 0xbae48729, 0xe1bfee8b, 0xeb976c5a, 0x2051f8c7,
-       0x4a384a9d, 0xfaf7957a, 0x344b74b4, 0xdaaaf527, 0xa6d77d33, 0x9dfca21d,
-       0x78ed7690, 0x2c3a3ec2, 0x9ebbcdf2, 0xe77df956, 0x41edc965, 0x33188ef7,
-       0x259fea07, 0x15b6aef3, 0x49b73c62, 0x521e7ba1, 0x4acfc0af, 0x923e807d,
-       0xdef0c1f6, 0x36a57f3c, 0xf10275de, 0x63bc7559, 0x44927e1c, 0x7d57a5da,
-       0xa0c6aadd, 0xcf1b6aff, 0x53749383, 0xf89db275, 0x93dc5aa1, 0xeef15b2a,
-       0xf74861c4, 0xce281b4f, 0x58df7653, 0xb3fbda23, 0x8a1f4d37, 0x127bc0e0,
-       0x6c4fdf28, 0xe047921c, 0xebc4b661, 0xc6c4bef1, 0xbfc7af47, 0x87633a5f,
-       0xc1a1df4a, 0xcb8f9071, 0x7f23c8ee, 0xcec8e1eb, 0xaed02389, 0x436ab5ff,
-       0xa6e47ebb, 0xffb08b21, 0x58ef4b48, 0xc6d078fa, 0xf4bbaa38, 0xa427a431,
-       0x03f32c1d, 0x90bdc5eb, 0xaf9cdeec, 0x8a97757a, 0xefac0bc8, 0xaef9f183,
-       0xddf4910d, 0xa3a352a8, 0xdbe715b9, 0x8ee74499, 0x2526385a, 0x2b9ee9db,
-       0x8cb369d9, 0x9725222c, 0x453023da, 0xc74375f9, 0x5e4fa81d, 0x1832c3bf,
-       0xd4cb8bbf, 0xb9cb43f3, 0x90e3cd7d, 0x61dfc171, 0xeac8eb92, 0x3b57e9cd,
-       0x2f7f7c9e, 0x74ec2b9e, 0x3fde919f, 0xebe9ecb1, 0xd89e1f51, 0x7dc7639c,
-       0x4919db1f, 0x198e0bf7, 0x78e7bf82, 0xb4c2f7a9, 0x3de4a9f7, 0xc1defcd7,
-       0xfba49cf6, 0xb9cbde0b, 0x98f2d2ec, 0x74662e4e, 0x065cfc4f, 0xe8e4fee3,
-       0x7e62b6ef, 0xc9a34561, 0x8e64f786, 0x7c63fd20, 0xdf4abb6b, 0xdfbba201,
-       0xdb23af80, 0x703ee8f3, 0x5ebcc7c5, 0xf0f8acd1, 0xc3fb72fe, 0xc2fe53f7,
-       0xf137b04c, 0x3db7796a, 0xebe1fabd, 0x38ce0d91, 0x3bf1cb3d, 0xf3366700,
-       0xef908b7c, 0x75bebc3a, 0xffe38a4f, 0xfd2cfdbf, 0x077bd313, 0xf09347df,
-       0x57aae796, 0x720a2e80, 0x72fbf0fd, 0x9fb22cf1, 0x50f62e4f, 0xb4395a79,
-       0xb3d2246a, 0x15ee8625, 0x51e3b4bc, 0x5373bf15, 0x79f06dbd, 0x308f1f3c,
-       0x9ff7d0c7, 0x90bc5cbe, 0x17279a82, 0x8a3f89d7, 0x15f854b6, 0xb55e547c,
-       0xfbde8dad, 0x0b5e4772, 0xd97debde, 0x9ac5c31c, 0x3be820ab, 0x3dbf1299,
-       0xfb9657dd, 0x1cd7fcfa, 0x9fdd72cf, 0xc56e9e6f, 0x21fdb57d, 0xe23865ae,
-       0x86c63a37, 0xc8a56076, 0x86ba392f, 0x23c7d9db, 0x18abfe62, 0xed7c7cf0,
-       0x0efc4494, 0xa9b6ccd1, 0xc57b63d7, 0xe786c54e, 0x49cee703, 0x7dcf3c56,
-       0xe2b4efa6, 0xd6cfaa3d, 0x3e57fbc8, 0x237bbbfa, 0xd829b3c6, 0x9eab447f,
-       0x84293239, 0xfc32f44c, 0xcbee9ea4, 0xe4ed017e, 0x451f393f, 0x89f813fe,
-       0x99927cc3, 0x4bbf722f, 0x9c57f9f7, 0x7d8a46ff, 0xcbb6f7b7, 0x17b506f8,
-       0x63f6f015, 0xd096b76b, 0x68de4fdf, 0xbfbae1b0, 0xf1a068dc, 0x4db9c0e7,
-       0xbe3deb07, 0xb0839f99, 0x13e8e78e, 0x6779f99b, 0xef3f334e, 0xb833cf54,
-       0x60d2fdf8, 0xe80a2cba, 0xeb2ddf47, 0x7323bbe1, 0x737f7c5c, 0x7ee27f40,
-       0xb1bf442f, 0x9fee99ac, 0xa93e6a5d, 0xaaff7e96, 0x74dd1791, 0x08bd13db,
-       0x23ff22b8, 0x98ba4add, 0xf5c786b3, 0x0b83cded, 0x9d24fe91, 0x5803bf68,
-       0x3bfc646f, 0xfa28bab2, 0xb324f7ee, 0x62fa80c3, 0x18e77c4a, 0x075f4f04,
-       0x916aaf97, 0xe4f785ce, 0xec29bd58, 0x15dec477, 0xbc1a78f2, 0x7abbf74b,
-       0xcff7f8db, 0x59317dc4, 0x474abe82, 0xda293e7d, 0xba038dfe, 0xf2ffae74,
-       0xf5d03d3a, 0x3bf691a4, 0xd7809db2, 0x7af35ff5, 0x167b7d9e, 0x7def3fd4,
-       0xec3d3af6, 0xf695d26f, 0x2fa80621, 0x75cdf259, 0xc9b9e063, 0x3bd83ae1,
-       0x9b139e60, 0x7f71d292, 0xdb087ed0, 0x8e7a27a7, 0xee2b5960, 0xba569d8f,
-       0xf4cc2d06, 0xa77b7ff7, 0x0e4be0e5, 0xc0d3bd7f, 0xa73bbbe8, 0x87f5cb7b,
-       0xd70e9d2f, 0xa109dea9, 0xdd8ce5ed, 0x5e7cf947, 0x7e076f7e, 0x788911dc,
-       0x5dd38aaf, 0xd3c7bcb9, 0xe3c7b9a0, 0xe4d5f7e4, 0x7f792afd, 0xfdff72ea,
-       0x7297b5b3, 0x00ffecff, 0x4fb2f369, 0x00008000, 0x00088b1f, 0x00000000,
-       0x7de5ff00, 0x5554740b, 0x55b9e896, 0x2a493eb7, 0x54842549, 0xaa84a925,
-       0xc0902b7c, 0x310c7c25, 0x0403e548, 0x6a285888, 0xa205a0d4, 0x01148280,
-       0x55f4741d, 0x9a7c3061, 0x179f8ee9, 0x102d4622, 0xdd787195, 0x866db1d1,
-       0x3220538f, 0xb40e9afc, 0xd38ceb63, 0x68d1d01d, 0x38311b63, 0x6f360cf4,
-       0x4dce7def, 0x802a56ea, 0x6f7be7be, 0xf65e97ad, 0xee739f61, 0xffb3ecf9,
-       0x5f5bdf67, 0xa5eb2c19, 0x0f24c664, 0xa153ab63, 0x63595a74, 0xff7b9419,
-       0x68d2cfe9, 0xac839ac6, 0xc18f2e3b, 0xd3f5a35f, 0x7ccf5051, 0x2e504bba,
-       0xcd1a484b, 0x139960c6, 0x996fd062, 0x12aeb189, 0x6d3b26e8, 0x12d8c2cc,
-       0x019dfe09, 0x19caf9ff, 0x956c674b, 0x44edfe15, 0xf08742b8, 0x7f466683,
-       0x3f98059f, 0x1fd8c0df, 0x3925744f, 0x9d9d8cf5, 0xbb0c2e1d, 0xbc65fb18,
-       0x009ce6cf, 0x8ecd1ded, 0xbec634a6, 0xd4a4c37c, 0xd09eff43, 0x60f927df,
-       0xe67aa5fc, 0x6d9284ef, 0x24d8ce1f, 0xc3ea2f28, 0x61dfa053, 0x8db6f157,
-       0xa9cbbcf0, 0x3f9e0c63, 0xfce70aeb, 0x82c678f5, 0x32f2932e, 0x32777ea3,
-       0x9f1eeb80, 0x9dfb1c3e, 0xfe5d7d7d, 0x936eb03d, 0xec1258cc, 0x598c067b,
-       0x0030780e, 0x07c32fac, 0xb40e3442, 0xbea09307, 0x0e74f5c5, 0x2f307c23,
-       0x0dd8c89b, 0x06ebef8c, 0xf11fbc39, 0x196494c5, 0x6f9b37f7, 0x3283db0f,
-       0x3333a38c, 0x98bbae03, 0x4d3f5875, 0x8eb19800, 0x7f60c34b, 0x3263c066,
-       0x24c78096, 0xa1eaa6c6, 0xe9afac13, 0x0990fa97, 0x7884d7d6, 0x85d07014,
-       0xd72c7a23, 0xc58bf8c3, 0xbc8ecbbc, 0x58c1c46b, 0xeb07fe10, 0x5de62259,
-       0x3d7771dc, 0x9092cb9e, 0xc0b74ce1, 0x7ffa25f5, 0x72c79d0f, 0xf2feefd1,
-       0xe29c46ad, 0x7eda1dfe, 0xafa6d9cb, 0x52fcf0f5, 0xfdc46dd6, 0x6a8ceb2e,
-       0x0cf9a8ef, 0x977cbbd7, 0x99debeb6, 0xc2748698, 0x97b1b2c6, 0xe74d54f4,
-       0x99f448bd, 0xca746faa, 0x66e19fb8, 0x371304c5, 0xf4479f3d, 0xb00cdec2,
-       0x63ac7ec8, 0x8b4fd118, 0xb1e74f4b, 0x9cc49764, 0x7ebb18e3, 0x42731657,
-       0x61aefd53, 0xc85d2654, 0x5fcffaa0, 0x57de3639, 0xd75e7032, 0xc6ab6abf,
-       0x6aff5df5, 0x3aea9511, 0x4e1d049a, 0x867497d5, 0x2ce71d61, 0x9b800eb0,
-       0x8162c08e, 0xd66e9a7e, 0x99e11887, 0x57bfb199, 0x596bc72c, 0x424fa5df,
-       0xfd8a0e58, 0x3a24974a, 0x1f3c6484, 0x433d61ef, 0x031e627a, 0x79993bb5,
-       0xa05ca5cd, 0x398ebb1b, 0x24dfe063, 0x19ce2fce, 0x81ee9ccf, 0xfc583976,
-       0x87584ab3, 0x0941ae61, 0x5c737b41, 0x33e436d2, 0xe574f416, 0xe20d73c3,
-       0x4e38aeb9, 0x54ee0937, 0x1d2af3cd, 0xadfa2adc, 0x18769a4b, 0xb3c1b2e9,
-       0x5121e888, 0xc7acd4c9, 0x406a5fa4, 0x67d5b9fa, 0x623ba4f8, 0x585fa21c,
-       0x295e0dc7, 0x7378fc84, 0x50ddb683, 0x44ad75f9, 0x8e47d425, 0xfbf6d5e7,
-       0xd003d229, 0x717e103b, 0x9c0c3d24, 0xc3a3c583, 0x1224f073, 0xb9cccbbd,
-       0x5be012b9, 0xee181b0e, 0xf7cf14df, 0x97310e79, 0x0f80fd86, 0x8875e260,
-       0x2e4fa817, 0xc537e2d7, 0xb0e7c5a3, 0x867e2d3a, 0xb7fbb57b, 0xda6ae435,
-       0x35237c33, 0xcb8b59ed, 0xbfb67034, 0xc47fd342, 0xec0d6aea, 0xf4d4ce0a,
-       0xa37f5bcf, 0xbd682e06, 0xa8bfd35d, 0xbda6817d, 0xa69f7438, 0x268ed47d,
-       0xf9da5c0d, 0x98ffa688, 0xda6b8f5d, 0x6a3786c7, 0x7e1dc7da, 0xe84f034a,
-       0x7fe9a2da, 0x34db07cd, 0x5fba93ed, 0xdb5fb4d3, 0x9e0686f3, 0xd35bbbdc,
-       0x0385ca7f, 0x1d8ab81a, 0x31aff4d3, 0x4f0356ff, 0xa6abfeb5, 0xc7fb74ff,
-       0xce19f69a, 0x67da6a3f, 0xd2d1bfb9, 0x93973c6b, 0xa5ff2bd7, 0x9359ee79,
-       0x5f50dfef, 0xdd954b34, 0xebf48641, 0x35ba3e24, 0x0184a74d, 0x972a83fe,
-       0x1c9e1d04, 0xc1392561, 0xb78e59f2, 0x32b0e914, 0x6e7c7c8c, 0xe0f24497,
-       0x28bd28ab, 0x91ebd1ff, 0x4afd9da0, 0x22765e52, 0xc45d41dd, 0x331e29fc,
-       0x39d62393, 0x81aaceac, 0x9aed7b87, 0xa706b6fe, 0xe7c33da6, 0x2d67b4d6,
-       0xb6703456, 0x7fd35cbf, 0x068f6ac4, 0x34eb0576, 0x7bd6f3fd, 0x6b417035,
-       0x517fa683, 0x5ed34fbb, 0x69ac5a1c, 0xafc3b51f, 0x573b4b81, 0xd98ffa6b,
-       0x8fb4d415, 0xb4d7af0d, 0xaadc3b8f, 0xb5742781, 0xf35ffa6b, 0x3ed34841,
-       0xa6877ba9, 0x4e9edafd, 0x77b93c0d, 0x94ffa697, 0x5c0d610b, 0xfa688ec5,
-       0x6a4f98d7, 0x0fd6a9e0, 0xdba7fd35, 0x67da6b4f, 0xb4d73f38, 0x2cd076ab,
-       0x7adad7f7, 0xaf5d1761, 0x7cf359fc, 0x90c3dab0, 0x486f823e, 0xd613b34a,
-       0x3fe102eb, 0x777ce49c, 0x28ed1e9c, 0x8c14182f, 0x41ad2901, 0x420c92fd,
-       0x480ae90c, 0xe2a6358c, 0x20ac4028, 0xc15549b7, 0x4f68c9f3, 0x73aa9000,
-       0x1fa0fcb9, 0xeb5ad813, 0x1bb266a7, 0xdf40971c, 0x29bfc25d, 0xa0944b83,
-       0x85ebaa9f, 0x4ea166f9, 0x726f3a02, 0x582e3cf9, 0xaf9d7dcf, 0x6862cb4f,
-       0x705b0427, 0x9307a01d, 0x9e6f41bb, 0x79776388, 0x378f064b, 0x89780cc3,
-       0x5c48ef98, 0x32cca3ab, 0xcc33fcf4, 0xff7fa967, 0xae3e06b8, 0x8a6bfb04,
-       0xa0a7ff18, 0xfbb065ee, 0x37c0035a, 0x153d8c05, 0x4cfc12b0, 0x5b704ec0,
-       0x7b6549c0, 0x96e54dc0, 0x1ded4280, 0x5f827281, 0x0e087808, 0xdca8ea05,
-       0xfd52f016, 0xc10340f6, 0x547c04af, 0xa62c08ee, 0x9f80b5f2, 0x560677da,
-       0x40f3fc13, 0xc0ceca90, 0x237faa7a, 0x9bf04ad0, 0xdf827681, 0xdca8840a,
-       0xe541d815, 0xb52740ee, 0x22ec0def, 0x9840edf8, 0x30e070e0, 0x5d0207c1,
-       0x7c0c1f04, 0x40a1f040, 0x03879537, 0x0d1e543d, 0xf1fb52f4, 0x078205c0,
-       0x576b4bce, 0x2e576133, 0xd2c07412, 0x2f793db8, 0x85f6523f, 0xbb462d8e,
-       0x43a09177, 0x87983543, 0xcc867740, 0x2ecd6dc2, 0x13a06a3c, 0x71c9d137,
-       0x96af2fb4, 0x4070d04e, 0x33560d7a, 0x5a9bd237, 0xc9e954b6, 0x90ae0cfe,
-       0xbb732f42, 0x336feb88, 0xb537f553, 0x85283e37, 0x079b9ed0, 0xf811b276,
-       0x9f6123e6, 0xe5c7147c, 0xc1bf39f5, 0xa35f768d, 0x66c0af14, 0xb277fe01,
-       0x8c2fe03b, 0x5ed77fa4, 0x9fb456d3, 0xc235f5d4, 0xe7183a38, 0x5a2eecbf,
-       0x6c3b2357, 0xbd40f5c0, 0x72fc0f47, 0xe2dbe6c6, 0x2fbeba02, 0x2234175b,
-       0x85425913, 0x8cc644de, 0x48f3df76, 0xf7fce7e7, 0x17c1c21c, 0x9c429559,
-       0x78537ae7, 0x7f30adf8, 0xb2bd11ef, 0x5e3439cd, 0x00ceb796, 0xf6997de1,
-       0xa0773fb7, 0x17f75f1d, 0xe1cf0fbd, 0x21b12184, 0xe9dd7404, 0x3acf8892,
-       0xd94d3a5d, 0x02fdf766, 0xa26df9d7, 0xa01d4eff, 0x56ebdbf2, 0xb612b2bc,
-       0x20a2b8d4, 0xf055ed19, 0x5f680c0f, 0x034e61cf, 0x989b87ca, 0xea1c5de7,
-       0xf823e666, 0x52a41656, 0xe176f9b6, 0x21636ebe, 0xa6157d82, 0x8afb589c,
-       0x383bd75e, 0x752c70d8, 0xdd90f29a, 0xfbc70077, 0xeb43d136, 0x7a69313a,
-       0x5d4bee21, 0x49c33997, 0xdeb366fd, 0xdf7d7017, 0x53fafbee, 0x9d306f29,
-       0x61f488fc, 0x3fb06981, 0x3779c233, 0x38e0ef03, 0x214b0fcd, 0x3e9573a4,
-       0xa74cc11a, 0x7a851ff1, 0x805e9229, 0x4b7fd04e, 0x9399cdeb, 0x4dd2f448,
-       0x3e926ff2, 0xfa7b0468, 0x28542e84, 0x8c4e89e9, 0x5173ac12, 0xee49d01a,
-       0xc0f0f4d0, 0xe423287a, 0x17d9d020, 0xfe9fde38, 0xe2371ae1, 0x93dbf96d,
-       0x66b7889c, 0xd0079c1d, 0x9ea8f073, 0x442604ec, 0xd2dafebb, 0xb207f910,
-       0xc529cca2, 0x7172e373, 0x7ead9ebf, 0x4ddc863d, 0x74f4e5c8, 0x0ba86ec2,
-       0xef9cb8d1, 0x2e7d76d5, 0x2e7d473f, 0x15a6df3f, 0xc3d52d9f, 0xf81c4ffa,
-       0x8d2ce8dc, 0x3fd58fb1, 0x823f2879, 0x3aef97ae, 0x7e83cd3d, 0xb92eeb17,
-       0xbea07131, 0xd2abcc50, 0xe898de91, 0x5c896adb, 0xc75d3f57, 0xa75d22e7,
-       0x11e75d00, 0x768a7f5d, 0x33936cf9, 0xbb2856f9, 0x28613501, 0xc95a2f7d,
-       0x14c05c7f, 0x2f32172a, 0x0c808b95, 0xc1bd8e90, 0xf7888d27, 0xd52758fb,
-       0x777e503f, 0xbdf5d23a, 0xd9f91f3a, 0xd517594b, 0xb5bd672f, 0xaf37b478,
-       0x1daef35f, 0xeb537d56, 0x44915393, 0x7fcd0c6f, 0xdb39cb17, 0x4e834fa5,
-       0x5cec93e2, 0xe4b747c0, 0xe613227f, 0xd5677dbf, 0x3f505913, 0x85cfcf5b,
-       0xa2e7e31d, 0x7de891ca, 0xe0145f03, 0x78a6dff3, 0xa4fa5f68, 0x345f0d3a,
-       0x123cce3e, 0xcfbbd38c, 0x8ae6da14, 0xfbf293e0, 0xf28590ff, 0x13bdee4c,
-       0xdbf97bcf, 0xef3c54a6, 0xfbd718fb, 0xaf8d4792, 0x119efaa8, 0xe2cfdfbd,
-       0x85f7ec15, 0xb22fefa0, 0x17f7d119, 0x658a3812, 0xcb287603, 0xf2cbd9f1,
-       0x72f6f406, 0x88d1cedd, 0x95ebd027, 0x7df70e78, 0xd632d9dc, 0x9420fa85,
-       0xe1887683, 0xecd29335, 0x7617e8d2, 0x8d850129, 0x7f3e219f, 0x198ee38a,
-       0xfca92ebc, 0xeed19fd0, 0xd0591930, 0xce7c465c, 0x677f2226, 0x9abf891a,
-       0x3879b511, 0xb7e9d78f, 0x84ff1e0c, 0xefe1ef58, 0x841d3fb8, 0xc52cbcfd,
-       0x2feb879a, 0x3cc0fc53, 0x19d24724, 0x2e4773cd, 0x3e7563e7, 0xa076e966,
-       0xc1347e9d, 0x8f9e3b77, 0xfd52471a, 0xcfaec3c8, 0x667cf1f2, 0xe5506c57,
-       0xaec78d33, 0x84e972e3, 0xf84419c1, 0x014b9544, 0x6f2fd609, 0xa7ff286f,
-       0x371d700f, 0x8c612d98, 0xc34ab077, 0x35ff7ed9, 0xdf1f4077, 0xcae3eaa0,
-       0x1a8ef8a8, 0x018a61f7, 0x3ecc57d7, 0xf141f152, 0x0e4e551d, 0xb1b0bfd2,
-       0x889fc42e, 0x79c7f597, 0xce3fb9fe, 0x8d79c3a3, 0xe6328e42, 0xf8237b77,
-       0xae00d6d4, 0x307fc68b, 0xff8d7cb3, 0xd9c0d560, 0xffa6bb7e, 0x4d4ed588,
-       0xd6e82bbb, 0x57ade7b4, 0x6b417034, 0x517fa6b9, 0x170347bb, 0xfd34ea87,
-       0x6af0ed47, 0x06ced2e0, 0xbb31ff4d, 0xb1f69a7c, 0xf69ac5e1, 0x1afd8771,
-       0x6ad74278, 0x3e6bff4d, 0x27da6a08, 0xb4d7af75, 0xaad3db5f, 0xb6f72781,
-       0xb94ffa6b, 0x57b4d210, 0xb4d5bfb1, 0xd75f98d7, 0xf1c62fc0, 0xeb54e778,
-       0x9b9e683f, 0x81afdf6e, 0xf1e7885f, 0x23ce199a, 0xf9c5e7da, 0x278b6f06,
-       0x3ee5987e, 0xffdf69a9, 0x8dcdc8c8, 0x47a12fc0, 0xb67fe474, 0xc53d71d5,
-       0x1d39aa1a, 0xd7bef1c4, 0xe66a1f2b, 0xbaf7d1cb, 0x7a9d8e90, 0x75f2266b,
-       0x039cf97e, 0xd0ac7640, 0xc51aa2b3, 0xc9eebb9d, 0xf48e5803, 0x6c8d5ebe,
-       0xf270d253, 0x7da39600, 0x1903575f, 0xca716533, 0xf996583b, 0x70d8d6c7,
-       0xbce7ab89, 0xe0c4e583, 0xb3941a8a, 0xb17e2660, 0x3e7dd608, 0x846d9238,
-       0xaa652575, 0xd10f5e71, 0x1d0caaed, 0xdbaaf9f1, 0x4b37142c, 0xa322d6bf,
-       0xe81cdf3e, 0xec10791a, 0xd3a7f4dc, 0x69dc62d7, 0xa1f9d83d, 0xc017b022,
-       0x59f2c7ee, 0xe043ebb0, 0xbb046d1c, 0x604dcb1f, 0x73fd63f7, 0x9c23f760,
-       0x7ad974fe, 0xc9d56e7c, 0x6172ea7b, 0xca0f11fc, 0xd7533456, 0x0e2b7539,
-       0x0fec7ac0, 0x4b28ad1a, 0xe267ae8c, 0xec8eb09c, 0x0a8eb065, 0x51078b42,
-       0x3052ecfd, 0x1c39321c, 0x2becfd07, 0x1db81a74, 0x2eb045ff, 0x97cf8b58,
-       0xaedee93e, 0xb6f9f630, 0x8a1937b3, 0x5d799f61, 0x014d6db7, 0xe6799738,
-       0xf1d3be02, 0x93fc602c, 0x09cd8f79, 0x97860c96, 0x48ff7a14, 0x2cee4972,
-       0x16b53e46, 0xeb81947d, 0x85fd50da, 0x3ce2b3a2, 0x0839cc8f, 0x787e7eeb,
-       0x23e758bc, 0xaff2aa73, 0x79cf5c66, 0xef50ef94, 0x47218cef, 0xffe853fe,
-       0x2f5c7993, 0xe5159fc3, 0x08938d93, 0x949d81b3, 0xf376f20c, 0xd1a7d5a4,
-       0x41ad90a7, 0xbb23e509, 0x144fcf08, 0x7823c828, 0x1e44fc4a, 0x537947b2,
-       0xe733e454, 0x1f3678c1, 0xf1914ed8, 0x785ac5b1, 0x19e79c33, 0x0c7ac0c3,
-       0x3282e977, 0x92f0c1ec, 0x9e605157, 0x5fb0798e, 0xb51b3780, 0x8e9165fe,
-       0x9f717d91, 0x378beeba, 0xdda76829, 0xf0f5c797, 0xecbb8096, 0x7ffa0313,
-       0x4027d94a, 0xfd8b9947, 0xabe40f92, 0x04abd1ad, 0xd2e19fa1, 0x2237efdf,
-       0x3ac5df61, 0xfd639f51, 0x27bb089a, 0xb86b8c47, 0x19bc27a4, 0x6a4abd9a,
-       0xbd06fcc4, 0x618cefe4, 0xc9e69577, 0x4666b9fc, 0x1e7786ed, 0x5f309c96,
-       0xba486366, 0x4bf1c687, 0xc2dbd40a, 0xb1ab3ebc, 0xf0085a53, 0x3a4e791d,
-       0xac9c7507, 0x08feb0c5, 0xa0e5d93c, 0xede78564, 0xc425068f, 0x55eadd83,
-       0xdae22258, 0x52bdfc4b, 0xf57db4f0, 0x864fb2c4, 0x8abdbae1, 0xa59be717,
-       0xcadf9bf2, 0x2b1f3d70, 0xbd42a9bf, 0xc33d1bf6, 0x9c6f8cfb, 0x8c5a724a,
-       0xa9a5a87d, 0x973ccf5b, 0x729267f1, 0x9e93f11e, 0x2ce2ddbc, 0xf17dfe00,
-       0xd6c34b36, 0x47767418, 0x75b3a71e, 0xe2deaa99, 0x73d749eb, 0xeafaa93c,
-       0x1fa72b1b, 0x4cad6e55, 0xce3ab0e1, 0x24f1ecca, 0x8f5a8637, 0xf98e3dad,
-       0x19bbd622, 0xfde2b1e6, 0xac2b77cc, 0x21f03788, 0xcc9f34bc, 0xe7d6e9e5,
-       0x4637e4dd, 0x3e20cfd3, 0x5c9bd100, 0x1dd97486, 0x31ba066a, 0x682a33cd,
-       0x5bfeda2f, 0x2472848b, 0x284ab593, 0xb5d96d47, 0xe7d46587, 0x1bd8afb2,
-       0x12be8ec3, 0xa9e7a83f, 0xcf8325da, 0x2abbf9cf, 0x0c0d43b2, 0xe5c9b6e9,
-       0xa9f9e1b4, 0x6474da74, 0xe22faa78, 0x3a0bd73c, 0x7aad672e, 0xd60ad3e4,
-       0xeb256549, 0xd63af2a2, 0x5987a54b, 0x99ab2c65, 0xf32d6542, 0xf98d3952,
-       0xad63aca9, 0x9d64ce54, 0x2eb3d654, 0xa3bfc12a, 0xe4accbd2, 0x7608de87,
-       0x9973960c, 0x985bca97, 0x482dca9f, 0xfef013df, 0xdbe095a1, 0xbb952759,
-       0x459dff80, 0x53311f18, 0x39e417b9, 0x3c836f96, 0xf20c32c7, 0xf8c269dc,
-       0x83ca9b88, 0x43ca8501, 0x0f2a7281, 0xefd43c07, 0xca8ea068, 0x952f01e3,
-       0x540d0227, 0xd47c0576, 0x316054ef, 0xfc05ef95, 0x581fbe54, 0x8107e54d,
-       0x12ff9520, 0x91654f58, 0xe20ae411, 0x163ddddb, 0x8f9c9afd, 0xe8271e8d,
-       0x84f34fa3, 0xfdd1ebff, 0x78f1e2f7, 0x83ba3a8e, 0x94aed5b1, 0x6e6d1e90,
-       0xe504279d, 0x74937746, 0x4eeb9437, 0x64d63b70, 0xd93b244b, 0x724abed6,
-       0xa4bbb8c2, 0x9c027d6e, 0x0fbcdeed, 0x4f4198e7, 0x6b65ed54, 0x7f841413,
-       0xe819a4ff, 0xdfc1ab70, 0x7fda15bb, 0xcebfd2f5, 0xaece8331, 0xc7f53c48,
-       0xed4c38d7, 0x66b20e93, 0xf207c02b, 0x26993f4e, 0x10a075f1, 0xc7d2fe3e,
-       0xe3e4d673, 0x791cb93a, 0x368e05d5, 0x5b0f19fa, 0xdb18cfc8, 0x0eac667e,
-       0x2dab49e0, 0x471fe865, 0xf5b8a3f4, 0xdba2fd50, 0x563ae7d5, 0x1e2337a4,
-       0xee0a7dd6, 0x65e51389, 0xcf8c58f7, 0xbbab8e45, 0xfe99f9ba, 0xf647f332,
-       0x5e332e93, 0x54e79151, 0x7403ffde, 0x86df4d1e, 0xaebf1f4b, 0x3598f8a3,
-       0xf6faf515, 0x7a772e14, 0xdb43e3b3, 0x53dbdd60, 0x9f21bc05, 0x610eb5f6,
-       0x8dbad7d8, 0x6fc764b9, 0x1d36f38f, 0xd1bff6c1, 0x69a0db29, 0x636fbc7b,
-       0x14f9c131, 0xea9759af, 0xca5ea377, 0xb1fae049, 0x9c48f1cd, 0xffff8233,
-       0xe6eee422, 0xadaebeca, 0xd7ad4fe8, 0x6e7802b1, 0x1b05fadb, 0x4bce30dc,
-       0x022ec09b, 0xc2f27938, 0x9ed0050d, 0x513741bb, 0xae1e642f, 0x0b4da5e3,
-       0xe128d95f, 0x0b5323b8, 0x213cdc61, 0x7586733f, 0x74095d8f, 0xc6d466de,
-       0x63f5fa15, 0x8597e73e, 0xd019cc30, 0x5e2239bf, 0x1ac0d5b1, 0x4166f522,
-       0x35b7973e, 0x4c34bc45, 0xd33cf1e1, 0xe3d0f888, 0x11aaffb0, 0xbe93fe3c,
-       0x9ff14cd6, 0x9e7fc774, 0xe9ed0e9c, 0x4d053a1d, 0x74b6d95a, 0x9efd018d,
-       0xf22758db, 0x3f8956e3, 0x76e6cc1f, 0xb92c1832, 0x1efc2273, 0xf2ca37b0,
-       0xf6a7e223, 0x7184a086, 0x4b11aa8c, 0xa7378c25, 0x3093ee3b, 0xe0de91fe,
-       0xe8897c93, 0xfda9f927, 0x2b9f22ae, 0x6f67d61f, 0xf735e784, 0x3c0cbeb1,
-       0x81b79857, 0x566409f2, 0xecdf3916, 0x27878e22, 0xb43d2064, 0x691ad7df,
-       0x9af8d15d, 0x991eaee5, 0x1ce07c3f, 0xccbfdba3, 0xfdb8e7e7, 0xf9029871,
-       0x1f8f1260, 0x9339789c, 0x6dd9e5ec, 0x23f41ef1, 0xb2393c4f, 0x2aa7e096,
-       0x9eff683c, 0x1a62b978, 0x9a9fb396, 0x484efd49, 0x05c630ec, 0xbb753f66,
-       0x7939f58c, 0xef1c2eb0, 0x71e891b4, 0x89f753f6, 0xc5a91fe7, 0xf05d72f6,
-       0x2e9fd0ef, 0x012d7e6f, 0x891505e3, 0x7961646f, 0x6abdd742, 0x837fcc3f,
-       0xd51afd95, 0xda4377b5, 0x3fc1d4df, 0x6b993ce6, 0x378c78c0, 0xf3ce973f,
-       0xf031e626, 0xf92f077c, 0xba3b95b7, 0x8e8b01de, 0x5bd9d75d, 0x9ebad783,
-       0x5883d65d, 0x34158756, 0x61ed59a3, 0xa72c41ef, 0xd16bf975, 0xa0fba9bc,
-       0xdd9620f5, 0xc45e7d23, 0xedffabff, 0x055e3796, 0xab63c478, 0xe68768ac,
-       0x633dde3f, 0x0d2fc51b, 0x60a1f90c, 0x8f55bf92, 0xa6f66c04, 0xf6787ca2,
-       0xfa875919, 0x8d6ae4dd, 0x4f74d843, 0x4ce30eae, 0x175a53db, 0xe20bbed3,
-       0x28f1e219, 0x8ba421e8, 0x2a6f1482, 0x25f013f2, 0x829dc39d, 0x7e294d3e,
-       0x8bd60a6b, 0x7efe8e7b, 0xd85e1cf1, 0x4e35afdf, 0xa55279a2, 0x08cdc4a0,
-       0x42ec23b4, 0x7f33b79f, 0x96c3e206, 0xf18adfe8, 0xce2a82ad, 0xd3912cff,
-       0x996f7605, 0x10508f48, 0x3fd5bd3e, 0xe6c1cf0b, 0xe01bcfeb, 0xb06a0774,
-       0x25c93edf, 0x367fee98, 0x39061c4b, 0x3fc2eb43, 0x5ba4e78c, 0x51cec9d2,
-       0x806b6fd7, 0x0eec22f1, 0x968dc7dc, 0xba54e781, 0xf5f620db, 0xe60b2884,
-       0xf5d4f1f3, 0x7ae7cc6e, 0xd4edd61d, 0x62f47ae1, 0x5d0fb03d, 0xfa227ac4,
-       0xd7fafed1, 0xd23b14cd, 0x897e6305, 0x4729cc97, 0xcea17fee, 0xd71a3713,
-       0x615fd6ff, 0xe509295c, 0x67f3ac08, 0x919927fb, 0xf1f7a34f, 0xfb88be42,
-       0xfe8cbd80, 0xe71f4cc3, 0xbf46e6df, 0x0d94fe84, 0x43bfdc61, 0xd45c60f6,
-       0x0c926966, 0x39b5fb11, 0xd99e9eb8, 0x728fdfe8, 0x82796665, 0x8b3df482,
-       0x72b5ae75, 0x0f983efe, 0xfd622beb, 0x7136167f, 0xfe7c4ec0, 0xe24ef799,
-       0x67583a91, 0xcfea3155, 0xbca5eec7, 0xcc8fcd89, 0xcfeb8c3c, 0x3fb93f74,
-       0x7ef40615, 0x3e7dce2d, 0x77656f8f, 0x87bc9ac8, 0xc9acbf2c, 0xac58c88b,
-       0xd07a076d, 0xd95d2ac0, 0xa829d5a5, 0x2509746f, 0x9da06733, 0xf923a492,
-       0x9a4a720e, 0x8d1ed31b, 0x7f812ba2, 0xcdde7cf5, 0xb373a7cf, 0xb039f859,
-       0x737cc55e, 0x7aacd8a2, 0x336f304e, 0xd03279b0, 0x3ead737d, 0x8f1fa124,
-       0xb232f1fd, 0x26f70d97, 0xada73e0e, 0x19cce706, 0xd41fa728, 0x2aaf2959,
-       0x67a0af0a, 0x94fc99fe, 0x1da8d307, 0xc53365ea, 0xabd6233d, 0xcf6b058f,
-       0x3bfd4ae3, 0x0cce7858, 0x4cfae0d7, 0xa899dcc7, 0x32973367, 0xf6e8ff3a,
-       0xe7b547a2, 0x78ef7e4a, 0x50b1a38c, 0xe79c07f8, 0x5af6c74c, 0xcfa3efb4,
-       0x9cbba555, 0xc2f5b161, 0x2f5c0523, 0xa72824e4, 0x90aec8ea, 0x66f04ec9,
-       0xfd23c3cb, 0xb9f2efa4, 0x57e5301f, 0xec43d216, 0x1f087363, 0x3f5dc255,
-       0xa8738629, 0xfba1d3ee, 0x7e3ddec2, 0x5099e9e0, 0x7bf5fd4e, 0xdfa0c74d,
-       0xe32cefd4, 0xeb377eb0, 0xa081819e, 0xf90361e0, 0x7cbe6b8d, 0x440315a5,
-       0x414c8dcd, 0xe3ceabbd, 0x6efae028, 0x25e4218f, 0xb32c5af9, 0xd907246d,
-       0xf4114bc5, 0xe89e9002, 0x6f31b787, 0x91f92b63, 0x8612fcb6, 0xaccd3c79,
-       0x97d20ef3, 0xe30c8d67, 0x383637af, 0xffb0550d, 0x869d1b1b, 0x219f78f9,
-       0x23b43ab3, 0xa8506a6e, 0x8546a6fe, 0xfd799bd7, 0xd50f06dc, 0xf0f46dcf,
-       0x5bd40b7a, 0xd4290f30, 0x6f718015, 0x753aa4b6, 0xe8d01f78, 0x4c17ede5,
-       0xfc1c7ed4, 0x8c27cc01, 0xbc910b8f, 0xf1d1ed6f, 0x7c7f237b, 0x9ab58248,
-       0x3b0ecb12, 0xe8f77f11, 0xcc175014, 0x2b332d94, 0x7836cfc0, 0x7f687a43,
-       0x1032858e, 0x3617bb91, 0x7ea10b79, 0xe2b643b7, 0x7b8376fe, 0xc147f98b,
-       0x9de132a5, 0xbdde00fe, 0x3af741d8, 0x3efc455b, 0xf14cc4b8, 0x2875b066,
-       0x6496ccde, 0xb7863b0a, 0x86b02c77, 0x39031ed0, 0x7bd8e748, 0x00764c8f,
-       0x6ea3c3c8, 0xe6768bb4, 0xca9f182b, 0xb7e5aa5c, 0xaa0b85f4, 0x6646bc68,
-       0xbebd3f45, 0xbcd78f91, 0xa1d21753, 0x71b9655d, 0xf341d226, 0x3fa0a60e,
-       0x53c2ecfb, 0xee10c3b5, 0x3f2e1450, 0x79a172b4, 0x9c4753e1, 0xcebf1fb8,
-       0x79fd405a, 0x5fd9af1c, 0x0d2f5dbd, 0xb79d33f0, 0x0c7e4073, 0x61ca3796,
-       0x5e63271c, 0xc1f182b5, 0xc627d874, 0xbc8c3bf3, 0x4ca7783e, 0x0be92df7,
-       0xf475b0e5, 0x0b677f00, 0x1f23a614, 0xd17c9126, 0x9dc8d7f0, 0xc179f85a,
-       0x32efc0a7, 0x9db82bee, 0xd1673e51, 0x903f6d76, 0x57943a93, 0xfadaedd9,
-       0xe3fa8b5b, 0x443c1a02, 0xe7e6d9e3, 0x9f7a2f72, 0xc70afb03, 0x74bed115,
-       0xd7285f7c, 0x72d8bea0, 0x1b8bea80, 0x44e9c565, 0x0a79d779, 0x53b45ff7,
-       0xeb806166, 0x44cd9617, 0xa4dfaa7a, 0xf5c8f0a3, 0xc2e48bac, 0xc6adf695,
-       0x19f7a23b, 0xf2efbfbd, 0xa88e5cf5, 0x6613e0f6, 0x1edb07b2, 0x9ef0e8b6,
-       0x78adec15, 0x55dc2b8c, 0x402c1d54, 0x1dc8407b, 0x973d25c3, 0xa216cd27,
-       0x51ed8353, 0xa1fc6477, 0x13f55465, 0xd86fd405, 0x6e3c758d, 0x968efb41,
-       0xe3173f63, 0xe6d6ea4d, 0x13db5de3, 0xa63f951f, 0x729bc7cd, 0x7f2a3321,
-       0x7f2a2f2c, 0x7da6946c, 0x545c75aa, 0x51b5d8fe, 0x1a3563f9, 0x967b9678,
-       0xcaf5ffa6, 0x86f81a4d, 0xfd343bf2, 0xd6ee78e7, 0x7754dfb4, 0x66fda6bf,
-       0x7c0d4aef, 0x6b5fc36b, 0x6be6dffa, 0xb1dfb4d6, 0xf69a27f8, 0x2d49ff68,
-       0xf9701577, 0x3feed9be, 0xd06c0149, 0x3df791f7, 0x28de996a, 0x7b9e46f7,
-       0xa7b70252, 0xb9fdfba2, 0x8bfbd380, 0x058f9f12, 0x1c789aed, 0xf135d8f3,
-       0x854570ba, 0x71c61bb9, 0x21df951a, 0x0ee262dd, 0x6bb6bfbf, 0x3ff6d9ee,
-       0xbc60fd0e, 0x1b5cc4a6, 0xff8c3bea, 0x37b940fa, 0x5f747487, 0x4abf5b61,
-       0x69b83d22, 0x5cab8f15, 0xaf3c5230, 0x8eac1d7f, 0xdc46fbc6, 0xeceba96b,
-       0x2da47110, 0x85424718, 0xfd4199e4, 0x7ef1c656, 0xe3574d3f, 0x371a3e8e,
-       0xa418dca3, 0x7e85bcfc, 0xcdc0e309, 0x7bc5663e, 0x02cb7493, 0x069bff9a,
-       0x265d9925, 0xb016da2e, 0x67cc0f33, 0x635c155f, 0x527dbd84, 0xb3d4f7d0,
-       0xcfddbcf0, 0x5bd31e28, 0x1853edf0, 0xe143e98f, 0x219d7408, 0xf73f3c73,
-       0x5fcfeec0, 0xe6daf981, 0x5ca197a5, 0x5acf6e8d, 0x43ebf7be, 0x6e7f6997,
-       0xde1f5bd9, 0x1fe7b97b, 0x25ba75d8, 0x38c87da2, 0xf3264369, 0xe001d044,
-       0x80fde62c, 0xf9f5c85c, 0xc5230af2, 0xfc01aeb1, 0xbfbe0215, 0x89cff8aa,
-       0x3fb9e03b, 0x44eefb39, 0x65ea1d3b, 0x847e87ac, 0x9fe53fd7, 0x9c92fca3,
-       0xa3df6051, 0x9b171dfd, 0x7215c76e, 0x8d6d95ba, 0x6a0718bd, 0xd13a344a,
-       0xbb32cfcf, 0x07193eca, 0x7ee06d74, 0xfeffb475, 0xddbfbf5c, 0x9177fe49,
-       0x944b2718, 0x9e7f2b7a, 0x4e4c8399, 0x3114f717, 0x6a4fa1f0, 0x655e5097,
-       0x8d3f942e, 0x89fd8be4, 0xa4238a46, 0xc1dc445b, 0x171358b2, 0xfb06e350,
-       0x9095ef13, 0x4bc3d3ee, 0xf18f9e28, 0x5c6f1c02, 0x11d693a1, 0x32c82f1d,
-       0x86bad3e7, 0xd7f59f1e, 0xe6314827, 0x1a875a89, 0x279e889f, 0xea04f684,
-       0x64f16599, 0x7bef444f, 0x79556149, 0xd7e470e1, 0x51d393de, 0x90329f7e,
-       0x5e8a1c3e, 0x143ccf30, 0x42b4fe31, 0xfe63dfee, 0xe63d6478, 0xe3228787,
-       0xef41ccd9, 0x2a0c102b, 0x7bb18466, 0x77ce1143, 0xc277cf94, 0x1ec9d8a0,
-       0xfe87b504, 0xd7217d5f, 0x9730d303, 0x19f2386d, 0x81dbcbf7, 0x12dcb1af,
-       0xd67d92b0, 0xf087fc01, 0x9527010b, 0xca9b80a1, 0xda85016d, 0x09ca07b7,
-       0x21e0257e, 0x8ea04778, 0x5e02d7ca, 0x6819dfaa, 0x01e7f820, 0x819d951f,
-       0x46ff54c5, 0x9bf04fc0, 0xbf04d581, 0x0160f685, 0x53d7a9c6, 0x4ad03bb9,
-       0xed037bed, 0x081dbf04, 0xec0e1951, 0x8103faa0, 0x060f824e, 0x287c1176,
-       0x70f82610, 0x479530e0, 0x7f545d03, 0xc101f03c, 0xc93ee337, 0x15df58ae,
-       0x4f8578c0, 0xf77da276, 0x15a16fac, 0x7cfb6bed, 0x79c5159d, 0x04b74fbb,
-       0x8d1d1ce3, 0xef131efc, 0x040e3123, 0xed086876, 0x67fcfb39, 0xf6a54c8e,
-       0x19bed4b9, 0xc4a70487, 0xafdb82b6, 0xfa91996c, 0x0a2130d9, 0xda58eb9e,
-       0xdc03d218, 0xed4f185a, 0xf93215b6, 0xfce9cf6d, 0xeedc8529, 0x336df922,
-       0xa541fb70, 0x5c853583, 0xe429aede, 0x161f5cf7, 0xca4a73f1, 0x9e47ad8b,
-       0xa6ed542d, 0x7f7187f5, 0x3fb079f6, 0x55bcef5c, 0xb597bc66, 0x72b3a3dd,
-       0xcbdf937b, 0xb8bf603a, 0xc50f587e, 0x6e7cd985, 0xade6db2f, 0xe63975a5,
-       0xd6ed48df, 0xd05347a2, 0xaff76f4f, 0x6deb439a, 0xd9ae2994, 0x82903bee,
-       0x89cf6cf7, 0xf0db277c, 0x64a86f78, 0x8d9e7af0, 0xe3077f5a, 0xec03837e,
-       0xec63d7a5, 0x496ed303, 0xc71130cf, 0x331cd47b, 0xe829d78e, 0xfe7121d7,
-       0xc4ca0f63, 0xb0302f7f, 0x2db9e0fb, 0x5105df60, 0xb6bf540e, 0xbd55e302,
-       0x289dbe85, 0x8e779f37, 0x9c03203f, 0xcfc7c75a, 0x82bf255d, 0xf79c3476,
-       0xbf502de7, 0x5e4dbee1, 0x4db0ea5c, 0x6ec835ce, 0xcadff3ed, 0x4397f8c0,
-       0x5a8f9ed2, 0xf9f62dbe, 0xb78f8782, 0xf14c9565, 0x378adb64, 0xbcf9075d,
-       0x33ff91bb, 0xc38a3e8b, 0x5cde4c30, 0x86450ea7, 0x35fc9e63, 0xff7717ce,
-       0xcd423aa6, 0xdf3a8f26, 0x6aef9c58, 0xb1e234f1, 0xc62f9b5a, 0x279286ba,
-       0xbf239257, 0x81ef1429, 0x942cb164, 0xb819cf23, 0xe49e0adc, 0x052524f6,
-       0x8f3c1a4d, 0xe6a02f9a, 0x0be7440f, 0x29e05efc, 0xde62c4cb, 0x4fd67ee7,
-       0xd73a41bf, 0xbd1b3c17, 0x92e36794, 0x35874931, 0x7a12d819, 0xde2aa7ef,
-       0x3d0626ba, 0x2853e5a8, 0x1fc100c7, 0x2e713216, 0x38f8ea9b, 0x64ce3e3a,
-       0x2ae082b6, 0x4318358b, 0x33e5ab5e, 0x2b7f9c62, 0x759b74e4, 0x870dcedf,
-       0x1a8f7cf0, 0x8b6a3728, 0xfd01b42e, 0x3d09e084, 0x7d4cd7c9, 0x2257d6e7,
-       0x4117f5d6, 0xa18c5b9f, 0x6e87bc62, 0x504af187, 0x94bf22ae, 0xd582fc50,
-       0x7d5de047, 0x1d843fee, 0x75c5fcf0, 0x3cff7429, 0xda1c6d6f, 0x4ccced47,
-       0xf83360f4, 0xd046c653, 0x32e90d83, 0x8b387d06, 0xfc0e348c, 0xe226aa59,
-       0xcbd70cbd, 0x60972835, 0x2616fbdd, 0x99ac3e91, 0x31acdeff, 0xc9f65700,
-       0x65b2cf94, 0x9cd3cf29, 0xca3aeff4, 0x31fb7913, 0xf75df7ee, 0x9fbd2d50,
-       0x67ca2194, 0xb283cfd1, 0xc2533d72, 0x0b952e70, 0x99bf142d, 0x133e417c,
-       0x4851a7e9, 0x17fa3c7a, 0x6d735e3c, 0x0f79acaf, 0xb68f526d, 0x8f54603f,
-       0xb7464676, 0xef3edeb6, 0x6153d3cd, 0xfca5f69e, 0xbf8bf6e1, 0x7070823b,
-       0x24e28e95, 0x5064fbea, 0x4df14193, 0xf9819839, 0x8ccc1b9b, 0xbe6db9e4,
-       0x60f28ad9, 0xc93c7a7f, 0x2cdbf6bf, 0xcbae8764, 0x3b438a6f, 0x556f34d9,
-       0x8c23960a, 0x3b18adc1, 0x2dd5e6bd, 0x9127d937, 0x55f355bc, 0xec1cac82,
-       0xdc8dbb81, 0xf73e09c8, 0xe51954f4, 0x9967cf25, 0xa796eaf4, 0xadd8f983,
-       0xd4e1d695, 0xf9be4cb1, 0xba76f87e, 0xbeb896b7, 0x1da11a70, 0x7ca379e0,
-       0x7b4115d7, 0x3f705a46, 0x9cb66d36, 0x6b7ca469, 0xf982324c, 0xccfd0b0d,
-       0x658df588, 0x573e48e6, 0xf2fbe4f9, 0x87c63c7f, 0x0e595f87, 0x2bdc695c,
-       0x3e417bf1, 0xfca19be7, 0xf210d369, 0x1f8ff554, 0x8bfce029, 0xf57a4b6c,
-       0x7da6318c, 0xce22abf5, 0x9e46e567, 0x61bb32a7, 0xc3dd1d5a, 0xcc65bb04,
-       0xdc517be7, 0x27a7b50b, 0x7b713dd2, 0xbde30b2e, 0x8e817041, 0xf8d27bc7,
-       0xb98ded7f, 0x936a1f14, 0x3cc129fc, 0xb9f097cc, 0x01dafcf0, 0x7f308947,
-       0xeb970e5b, 0xe2b7e42c, 0xb38c357d, 0xe0fd7238, 0x74b505ef, 0xa61ec8cc,
-       0x789e85f8, 0x888c69cf, 0x1c5c63b7, 0xcfd117e3, 0xc2d5ee4d, 0xe1682e53,
-       0xc0d0662a, 0x3c2d6635, 0x3785aad5, 0x7d3b7115, 0x3f5b5dba, 0x1d85a9c3,
-       0x74e307d9, 0xc2dfcf3c, 0xf049e222, 0x447e5ef7, 0x68dd681c, 0x765f3efe,
-       0xcb8a52f7, 0x78f0e5b6, 0x3695638f, 0x42c591ce, 0x732fe212, 0xd63c5469,
-       0x863f66bd, 0xa30bed97, 0x5efc41e3, 0xa9a1f002, 0x7c8a3147, 0x9e68eaf0,
-       0xd23dde87, 0xce08bdb7, 0x5f0c60b3, 0x4d1dabc7, 0xdac53f74, 0x5caf88d3,
-       0xb0695f22, 0xe88a7cbe, 0xf90f1d40, 0x7fb11822, 0xf84887e4, 0x37be51a1,
-       0x8be41e70, 0x2cfea460, 0xfbd036e9, 0xa1be62ab, 0xcfe543f8, 0xa28f7172,
-       0x89f4dde6, 0x9bbcd4b1, 0x705f2255, 0x4ebe5457, 0x1936a39f, 0xaebee7fd,
-       0xf8b1f195, 0x682ef910, 0xe5887ce2, 0x837f9106, 0xe22c187c, 0xa6f5887c,
-       0x637856ef, 0x050b8bd9, 0x63bfdc5d, 0x224f86c9, 0x73acb7f6, 0xbe5e0685,
-       0x910de1eb, 0xe3f751f9, 0xbf08303f, 0xed7e519e, 0x2f9db152, 0x2bcbff4f,
-       0x48cd0ccd, 0xcf2807df, 0x319c1596, 0x5ea77bf2, 0x42eb9e23, 0xcc99ff61,
-       0x2fd1f2b3, 0xf2e211db, 0x37889d6c, 0x33155b34, 0x3b9981c6, 0x50c71355,
-       0x4b4d11e3, 0xd854b65c, 0x7c7f7247, 0x7ca56bc1, 0x14f9e1dc, 0xf1aa48df,
-       0x32c6cedc, 0x9c6453d6, 0xdd62066b, 0xc056c18e, 0xd957f9e9, 0xc0c74133,
-       0xf8174dbe, 0xb0fdc97b, 0x8f2467ec, 0xea68e42e, 0xa39c44db, 0x0b2dbf9f,
-       0x8b3e70aa, 0xb0fb49db, 0x1e1aff31, 0xd1c6d417, 0xe73de24c, 0x343be3c1,
-       0x7e226df5, 0xb5f1e572, 0x85d33971, 0x2fc621bc, 0x1adf1a8c, 0x7181fc73,
-       0xabbdf1b5, 0x714f37b8, 0x2e3a184f, 0xe9cdd236, 0xdfdd9d69, 0x83317185,
-       0x06667fe0, 0xf288993a, 0xe3e9ff80, 0xc1ae7e79, 0x198f8da1, 0xfa0baf30,
-       0x98b8973f, 0x3efa8ae4, 0x0599fdb5, 0x27cbca12, 0xa4e8fdf0, 0x5a24f2c1,
-       0xde44d88e, 0x811cb47c, 0xd37034f9, 0x36cf5cc3, 0xe50f8a4b, 0xfe7ef473,
-       0x7587f17f, 0xc8bbe389, 0x778eceae, 0x0f632e9a, 0x638205b7, 0xf175b9f1,
-       0x0778c5fe, 0x918ef77e, 0xe3944f69, 0xf88ceb7b, 0x298ec56c, 0xb60f3173,
-       0x13ebf04d, 0xa7a23a69, 0xb7d3dbf4, 0x29e823ea, 0xa173e8dd, 0x13ae9c3d,
-       0x87f85ff9, 0xd227b471, 0x318c6db7, 0xa9d76abf, 0xd601adb0, 0x6d8e7111,
-       0x9fee9ec2, 0xadcc8eef, 0xd27188fa, 0x34b1be4d, 0xa3fe7f5f, 0x87e5af98,
-       0xc459b7cd, 0x6cf9d4c3, 0x67f76a77, 0x7f69fa33, 0xd487a136, 0xfee336f9,
-       0x15d5f062, 0x75fe13e7, 0x69777cff, 0xf93367f7, 0xf5367f69, 0x7cea1b3b,
-       0x3e6c3f2d, 0x76cfe0bb, 0x3d97def1, 0x64377f9e, 0x9a23f7a8, 0xbdccf3fb,
-       0xed2f9466, 0xe850bc6a, 0xfa5173bb, 0x3be849ae, 0x6973f9f5, 0x3dff14b9,
-       0x7326f877, 0xfa873d2c, 0x933b098d, 0x09933b09, 0xd9e1133b, 0x0d57a735,
-       0xbbfc7a07, 0x95cf371d, 0xbecfaf41, 0x1cf8f4ff, 0xf1d9df80, 0xe832b98b,
-       0x9eafd9a9, 0x1e0b337e, 0xfbdbfe29, 0xe9f4fc38, 0x5bb4073e, 0xadcccf82,
-       0x18693805, 0xbaeacfd7, 0xb97779d5, 0x7cb95db9, 0x6f8f1e75, 0x3d459c82,
-       0x67e39cd6, 0xcafc7f18, 0x1f349bd1, 0xeecf2ffa, 0x03105f4d, 0x7cb96a2f,
-       0x1e7f2175, 0x9889c0ad, 0xaf48c6cf, 0xc7bea8dd, 0x8f7da752, 0x23692925,
-       0x2c7187d9, 0x96394564, 0xfbd0f660, 0x7316d797, 0x533370bd, 0xe15fb81a,
-       0x1c79102c, 0x4dcbdef4, 0x6b5c62e5, 0xfdb12fe5, 0x09e79d66, 0x79ff77f4,
-       0x68e1bcd2, 0x7379ab3e, 0x3bde06a3, 0xde7dfedd, 0xb1fd9e4f, 0x64e56dc4,
-       0x36998f1e, 0x7bdfc9ca, 0xa22b888b, 0x3e143c5d, 0xff73753f, 0x1e9f007e,
-       0x0f54cf8e, 0x37b5a7c7, 0xff9c0d69, 0xf4de94f2, 0xc34f89c7, 0x0835f131,
-       0xfbf851af, 0x7ea99b93, 0x88ed1ea0, 0xc55be12b, 0xd85f9aab, 0xc80b392c,
-       0x9a19675e, 0x14c660fc, 0x1e7bac67, 0x3d48cfa4, 0x197bb46b, 0x3486a3da,
-       0xeff98dc5, 0xc7d17fcd, 0x1573dbcc, 0x525ef88b, 0x367de53c, 0x1fc91927,
-       0x93349fdf, 0xb659fc61, 0xd4bc234c, 0x3e51d526, 0xeb187ea6, 0x3a357f44,
-       0x7c9f5d0f, 0xe909e53b, 0x4061e86d, 0xecc79fd9, 0xe95f2331, 0x5d92563f,
-       0x99570048, 0x295f2e87, 0x26753d0f, 0x324f43cf, 0xd85e313a, 0x998c689e,
-       0x9badfe87, 0x71fb5dfb, 0x1fb8697f, 0x886eff23, 0xe56c97d8, 0x9f58eef7,
-       0xab46f500, 0x5dfc518f, 0x615bffec, 0x4dfda907, 0xf9433f56, 0x4e2a37a0,
-       0xa9f45fb4, 0x77e07f5c, 0xe231dc5b, 0x0dbb5f28, 0xa3fdfcf4, 0x99cf5cac,
-       0xfb3eddb9, 0x27dfb137, 0x44962b28, 0xdd3624bc, 0x3737450d, 0x9dde78ea,
-       0x2d7397ca, 0x9c07ca46, 0xf7d3b16b, 0x2102e66c, 0xf446a4f6, 0xfe56eebf,
-       0xd8acb53e, 0x7b7e9e91, 0xfe5f94ed, 0x00b5e196, 0x66a7db97, 0xc2bde818,
-       0x28f31253, 0x5df383a9, 0xa994debd, 0xea1bccb8, 0x7645af4f, 0xc8c3182c,
-       0xc1757a4e, 0x4e95ad43, 0x8aea8ff2, 0x737d9e91, 0x770fa2a6, 0x77d8c363,
-       0x04f2ffb1, 0xfbd5cf2e, 0xfc09e5a5, 0x646bde7d, 0xffec6cdf, 0x4917c555,
-       0x725f48d5, 0x2bae0e6f, 0x33dd3fa2, 0x5b9ff445, 0xcffa813c, 0xf5ddafe6,
-       0xce3977d2, 0xc8f99da5, 0xec7ce8c7, 0xf429ecb1, 0xbde458b7, 0xe81f9086,
-       0xa3d64577, 0xce22c5bf, 0x6e505a53, 0x4f218eeb, 0x3ec332d4, 0xa042e46e,
-       0xb18c8cd7, 0xcff5aa54, 0xa175f47a, 0x90fce718, 0xec1fe738, 0x6ac3b4f7,
-       0x3df80e27, 0x843cefe0, 0xe172f8f8, 0xb0f1f4a9, 0xbf6a07a5, 0x6ec7bf26,
-       0x16ceffec, 0xb00371f9, 0x2db3bef6, 0xdf8c5bd0, 0x87886019, 0x8bf91189,
-       0x25f6bf62, 0xefd0526b, 0x20f4b381, 0xbc0476dd, 0x030d6b23, 0xe42cbfcf,
-       0xd2160b08, 0x2eb106f3, 0x0ceb5a47, 0x2c38bb8c, 0x6073ca3a, 0x6791aacc,
-       0xa6536a73, 0xbb0ba1a6, 0x2716299c, 0xe45df7fa, 0xfbe06417, 0x7c9f180d,
-       0xf78636e7, 0x9d69595f, 0xfd75da12, 0xc6f788f3, 0xe17b8957, 0xed2d5f3e,
-       0xefd6c327, 0x5ff23197, 0x507382d3, 0xc33df56e, 0x92f19457, 0xc691ddb6,
-       0x5dee1ff3, 0x02721f18, 0xed2d67bd, 0xb04f4fc2, 0x30f8700c, 0xa9719fa6,
-       0x7282d5d9, 0x140957e6, 0xe7b7d677, 0xfbc820b3, 0x1bfbecb0, 0xf9c877c2,
-       0x6c4f2e90, 0xb65b9e16, 0xb9ec9e28, 0x0675a976, 0xe8f731f9, 0xd178ac58,
-       0xa7ee62ce, 0x2b628ffc, 0x4fb5cfbf, 0x1f63f4e4, 0xb8e1723f, 0x77ffe7ab,
-       0x49f99e84, 0x7fde93b2, 0x4da3ed52, 0x8e47f843, 0x5f213a91, 0xf8115e84,
-       0x199f3333, 0x792f45f9, 0xc774b079, 0x96bdaf6b, 0x5b53e8ce, 0x841b4748,
-       0x138ea3fd, 0xc6a21f9f, 0xf243c578, 0xb87ab252, 0xedfab0be, 0x75af3841,
-       0xce63e9df, 0xfba085ff, 0xd90fd935, 0xd3ad7fb1, 0xfa32c6e7, 0x9c96983d,
-       0x3e78dd7b, 0xe9fb332d, 0x96baec95, 0x61dfce33, 0x28f0563e, 0x9fd837cf,
-       0xefc3685d, 0x1b0e5941, 0xe265d364, 0x27d046f1, 0x19d8cbce, 0xdeaf9146,
-       0x99e78072, 0xbaca58b6, 0xc5a1af30, 0x6a465692, 0x56f3c2d8, 0xcb16fed5,
-       0x1607d221, 0x5adfdf85, 0xb8487f50, 0x0947c04c, 0xe110ebae, 0x5077ed43,
-       0x128b5dc8, 0x5a5ef866, 0xfd4ad29c, 0x83d7b2cc, 0x34e6ca79, 0x6644f746,
-       0xe217f02b, 0xccc75f35, 0xbec9f431, 0x5a4fae62, 0xaabaca4a, 0x7e327d69,
-       0xd8b58eb9, 0xe7a4eccb, 0x7cf0ef11, 0xcf968673, 0x577813bf, 0xf91669c7,
-       0x4eae77b4, 0xc38ed609, 0x1bf79338, 0xcb16e7a4, 0xf5107302, 0xcbf8e25a,
-       0x391a678e, 0xd7fb78d4, 0x43bef18a, 0x2c4fae79, 0x0678e2b3, 0x8d15f7c6,
-       0x9c62e1f7, 0x7bfbd5ff, 0x47bd2cc0, 0x581d304d, 0x7deb1ed8, 0x13f3feac,
-       0xcfd1f2f7, 0xbc7960fd, 0x02871b56, 0x091eec79, 0x72565afb, 0xd53550e6,
-       0x0bd3f8f0, 0xfd519fc2, 0xf6317492, 0xbf7f120b, 0x2bc5283f, 0xe10c5df4,
-       0x69c7a4a7, 0x3ef030f1, 0x6f873f2d, 0xde1e781a, 0x7c4c6937, 0xd7cb4e87,
-       0x38ff1cdf, 0x059f9345, 0x7131ec7c, 0xde23c63f, 0x3888f5a7, 0x6f18c21d,
-       0x049d17a0, 0x89c7f7ff, 0xc33f9c1b, 0x4099acef, 0x5c60eb8e, 0xfa27e1c9,
-       0x5dba3936, 0xe239efc8, 0x78d10ffb, 0x2e48c9fe, 0x7a47a5af, 0x51af785c,
-       0x119bd69b, 0x7c5fdf8b, 0xee0642f8, 0xfd19c5e7, 0xdf743b79, 0xe769e2f4,
-       0xcbc402e6, 0x6ffbed11, 0x474df8ea, 0x22f8a7ce, 0xe5c0a5fd, 0x3a4b2fdf,
-       0xd92571b3, 0xddb80b8d, 0x7dfa7ff8, 0x73e617b3, 0xa497753b, 0x084fcf95,
-       0xfc141cb9, 0xd320bb60, 0x2aee43f7, 0x3a40adf2, 0x0bac936a, 0x3ce72e50,
-       0x9af2f3cc, 0xb3d55b1e, 0xb47f0628, 0xd5fdf28c, 0xbabf08c8, 0xe491bd7c,
-       0x3725b35e, 0x28f772f9, 0x9fbb9f43, 0xde7a94e4, 0x79988f55, 0xdb8f8abe,
-       0x7bbee9d1, 0x3a260f29, 0x7ea8653f, 0x449d23d5, 0x137f6a0f, 0xc5f28f8e,
-       0x15c52372, 0x818fa1ce, 0xb72b3b71, 0x59d7a233, 0xc098c889, 0x7d0663f1,
-       0x49607499, 0x106b8e1c, 0x6a0bdcfe, 0xcca1a45c, 0xde7889ec, 0xb9995b70,
-       0x9a4e823a, 0x8e0fcf19, 0x2337ff1e, 0xac22fb55, 0xa80c63b1, 0x94c6317f,
-       0x97ed9f26, 0xf278643b, 0x0395b4fc, 0x0ee3cc7c, 0xc5a3e743, 0x232dbe71,
-       0xf30dac7b, 0x5e0ec0d2, 0x0460b0d3, 0xf64db7e2, 0x3c0368bd, 0xa2687ef4,
-       0x0bdfea3c, 0x7c16ed3e, 0x05f9d43a, 0xd23001d9, 0x1d9c7b18, 0x80e297c4,
-       0x2327c64e, 0xebe7345f, 0xf63142ea, 0xf3ec5c79, 0x7878f632, 0xc7b3f7e4,
-       0x1afe890f, 0x6ded1c7b, 0x46fdd44f, 0xb6768c24, 0x7e3d8627, 0x05f11242,
-       0xc2742791, 0x0dd5dce0, 0x39313978, 0x5697be99, 0x5defc090, 0x527fa04e,
-       0xabc87e06, 0x7ed1f3a7, 0x7ff52d99, 0x43f84917, 0x47f0608c, 0x62f905fe,
-       0xb6bff30e, 0xe23e2248, 0x1b7835f7, 0x73e57e9f, 0xd19236de, 0xf9c036ba,
-       0xdb46fde1, 0x6233f9c5, 0x8ea467dd, 0x5037fd52, 0x13ef1165, 0x889d3c33,
-       0xf741acfb, 0x72f75174, 0x9fd36d78, 0xdc1fac77, 0xed7286ff, 0x8b86d9bd,
-       0x5a622e3c, 0x4b8f42c2, 0x6daa9798, 0x10cea9bf, 0xb9a82f7d, 0x6bd9bb4f,
-       0x7d0f5e88, 0xd621d417, 0x1f71dd9b, 0xcd4fbfdd, 0xa644f9e6, 0x04e28c65,
-       0xa66df7d1, 0x3d1e5db1, 0x8c0dcfda, 0x38e8fdec, 0x52a9e639, 0xb181b0fc,
-       0x79e5122d, 0x7973df6b, 0xfe73fea6, 0x3ad6947d, 0x760ec79c, 0xd1d3da10,
-       0xf7a849ef, 0x51f7ea5a, 0xdfab3c55, 0x4dbf4a8f, 0xc163eb47, 0xc6aed429,
-       0xb87bf1fd, 0xf911e955, 0x7f582be4, 0x2b7f7a7f, 0x9bdf7b18, 0xcf29eadb,
-       0x7fbc7320, 0xb29a186c, 0xc8784614, 0x6fc8c85a, 0xf2683c00, 0xdbd94c09,
-       0x16e79f69, 0x224c3633, 0x33da683c, 0xfdd3d340, 0x7e6d42c0, 0x0353ec01,
-       0x57abfb47, 0xd94d53f2, 0xf39597f9, 0x9a638a57, 0x94e4bdc4, 0x97fbe251,
-       0xed14aca5, 0x9edbf4a2, 0x0738f3a1, 0x5f7181e7, 0xdd629c74, 0xf1826e3b,
-       0x77fc8fd1, 0xe2cd2fc1, 0xaefd5b6e, 0xf4c8f30f, 0xce549b1e, 0xf30d2cd7,
-       0x12e97bf2, 0x8a6e7c46, 0x8fcc6667, 0x1e4c2a97, 0x04c9bbc4, 0x32596c30,
-       0xd4067332, 0x7b3c45eb, 0x8464c48d, 0xf3315599, 0x5dfaa3f8, 0x577d10a1,
-       0xd479a868, 0x20b22bef, 0x679d4e7f, 0x2ef577d0, 0x7bf93cf3, 0x6be7e8d6,
-       0xcea99e29, 0x87fe143f, 0xbfde8efa, 0x8137bcd5, 0x441d53c7, 0xf4038daf,
-       0x417cf04a, 0xca3cf88f, 0x66d5bb85, 0xfa29577b, 0x4c1e670f, 0x114a3650,
-       0xd2ce08fb, 0x7e03eff3, 0xd7faf1bf, 0xbc927761, 0x1897dfef, 0x8beefbef,
-       0xdae422fe, 0x09597c3a, 0x191a5ef3, 0xfba431e5, 0x29973faa, 0xa0f600ff,
-       0xdf111391, 0xd6f18049, 0x1fefce3d, 0x3e77e336, 0xc0e7fef0, 0x13edfe40,
-       0xd1f76c16, 0xbcd43677, 0x5da3cc5c, 0x3ef0325b, 0x837df472, 0x89c611bd,
-       0x99b26f98, 0x9f401305, 0x0531f4a4, 0xb9ecf3bf, 0x03a65468, 0xa07d6c7e,
-       0x93bf0150, 0xa5ee8999, 0x337ead2a, 0x0ae10eff, 0xef676916, 0xefa56e97,
-       0x64bf86bd, 0x3e14bf94, 0xc3ee88cf, 0x70c4c39f, 0xddf8ff2e, 0xcbe47afb,
-       0x7a5d7da9, 0xfb93f3d4, 0xf67fa4fc, 0xed3d4fd9, 0x9962e7e2, 0x751f9111,
-       0xcf545b1d, 0x979f8ae9, 0x5f27ea2c, 0xfdf86a30, 0x46a35eda, 0x5b17c81e,
-       0x65fd46be, 0x67aa89ea, 0xe3e33fd3, 0x2dde28f9, 0x53edb5db, 0xdbd03e44,
-       0xc35fdf2a, 0xbc73a1ae, 0xcf331698, 0xd5dce06e, 0x71e26e73, 0x79c7c674,
-       0x9ff7946e, 0xff404d46, 0xe87147c0, 0xd82fc464, 0xdd952917, 0x58798ecc,
-       0x8e994ce5, 0xf3b2bd72, 0xe487a41d, 0x3c0f3cb3, 0x5ffdfc7a, 0x7e8595be,
-       0x9dc99ec3, 0xed2f6859, 0x3d15f2f9, 0xd3d5578e, 0x193eb0cb, 0x58a41e4a,
-       0x10aa784c, 0xcf5033b4, 0xf59144e3, 0xe74a9eb4, 0xcfe4e565, 0x871a4e50,
-       0xd933df6e, 0x87e4c2c2, 0x3da02675, 0xfe7c7cc7, 0x57cab364, 0x70972fec,
-       0x9f81845e, 0x52ea54f6, 0x7b9f616a, 0x6c15919e, 0x46f3d3dc, 0xe7bfce02,
-       0x7acd39ec, 0xf322fe98, 0x5afbac45, 0x2b53ee71, 0x7efec97b, 0xf92bac4a,
-       0xa1c52f6c, 0x30de9553, 0xc3d4dbea, 0x37fefa7a, 0xc8bcf0b3, 0x38a14c61,
-       0xfc5eba9a, 0xd73e2a6e, 0x88de7282, 0x5632b3fb, 0x287eec28, 0x55832a33,
-       0xcc9a8f98, 0x6b484a76, 0x417d2b53, 0xa5e4e7a4, 0xad939e9c, 0xbf18c3fe,
-       0xa3af5e4f, 0x59f24538, 0xcbf406df, 0x0565cb92, 0xf84ae4c9, 0xb7f310ec,
-       0xf9d4f98a, 0xa88cf5d5, 0x7ee84bf4, 0x62e3b324, 0x132aaefe, 0xcc5abf8e,
-       0x59eb14ef, 0x2c3be8c5, 0x55ad67c9, 0x83272fe8, 0x33df419d, 0x9a79e2b8,
-       0xb745f335, 0x99d94f27, 0xb1e0e745, 0xe30ad91e, 0x365b64a5, 0xceb94154,
-       0x32ff23a1, 0x3c5187a9, 0x9d27a93d, 0x4f527de4, 0x8a2728a1, 0x0f4269fa,
-       0xd4933970, 0xaf2d50f3, 0xa4d2a16f, 0x3f8717ca, 0xda98fb8c, 0x717cb8cb,
-       0x98be4978, 0x517cb8d2, 0x9556b8e9, 0x325acc2b, 0x0ff7ea1f, 0x06b5acff,
-       0x73f77b9e, 0xbbe5fefe, 0xbcbe5cd9, 0xfbf725fb, 0xd3bf694d, 0x42aa5ca3,
-       0x4dfa05c3, 0x33edc0bb, 0xbaab1f95, 0x48113625, 0xe7839a63, 0xc8ba1f87,
-       0xd9843b9f, 0x63af00d5, 0x9529c912, 0xdd056b6e, 0x83eab3ae, 0x81fed849,
-       0x3477de89, 0x98e5ce39, 0x83fe1ec1, 0x7c41f7ae, 0x33f7f8ef, 0x415def7a,
-       0x437e82f5, 0x9a2e494b, 0xe4396c84, 0x3e416058, 0xae487984, 0xe918721e,
-       0x3a080ebc, 0xe9af673e, 0x5b3fc308, 0x69fcdfcc, 0xc1ffd43e, 0x9340eb9e,
-       0x1e973d4c, 0x885f2f41, 0xe82b3bf3, 0x7bdd29a6, 0xfc04c953, 0xcd1e62fe,
-       0x0dfece7b, 0xdcb27fbd, 0xc69f1ff6, 0x3aa72efa, 0x4f7cfa8e, 0xcf19a568,
-       0x1f9bd0f5, 0xabb4409f, 0x7b235fe3, 0x7ee3e4ef, 0xd0f89a33, 0x78cf3b12,
-       0xadf3fc90, 0x8b7f9688, 0xc80f864a, 0x91667abf, 0xe7121e79, 0x1e4259eb,
-       0xddb8554d, 0xe7e56f5e, 0x5fb25f55, 0x8b8afea6, 0xd2af55f6, 0x5ae4f28d,
-       0xf29b7fe4, 0x7d4bd124, 0xbd97a73e, 0x0a0f9e82, 0x63ecce7c, 0xed97e89d,
-       0x196e982f, 0xe23ef80b, 0x1cff13d2, 0x52c6bb19, 0x291dcf06, 0x024bf095,
-       0xd6c97a6c, 0xcf00a9b5, 0xa7a22452, 0x1dad92fa, 0x967fd04d, 0x03a94135,
-       0xb3f9e8f8, 0x0eaf3416, 0x9784bc05, 0xe3f872e9, 0x1b9e1754, 0xcaccd3c7,
-       0x4ffe8cb0, 0x8cbf63bd, 0xc46df6fa, 0x2ee311ab, 0x7567c11e, 0x6a571f04,
-       0x238fb82c, 0x2f2126a5, 0x5e51e33d, 0xd537cace, 0x7c75a18f, 0x1a4c6c7d,
-       0x506f77be, 0xa73c95f8, 0x7e82c9ff, 0x6b27ccea, 0xccdfa053, 0xd7196692,
-       0x912cd47b, 0xd7da3cfc, 0xc793f944, 0xd2ac393b, 0x74073d2d, 0x5b6fbc79,
-       0x6fb61273, 0xd53e4897, 0xe21d2f2b, 0xa7d38fea, 0x0b0f7e3a, 0x3077e1b6,
-       0xb7af29cf, 0xb1f53e60, 0xcccf05be, 0x7f1c3c01, 0xb8c43f53, 0xc0ad1f4d,
-       0x244cdf71, 0x356d9e3a, 0x8cb1f469, 0x5e84694e, 0xd36f1ead, 0x0d4af5c0,
-       0x29cfd3c5, 0x7806e592, 0xad5df3de, 0xd191397b, 0xbd77da52, 0xe14c7be8,
-       0xa1cc797c, 0xd63cbe23, 0x8a9cb8f7, 0xfb4659f0, 0xde769991, 0xb21a92fa,
-       0x5b29ceaf, 0x826744f5, 0x54f1d50f, 0x4f8a3e3a, 0x9ced1e23, 0x6df68fff,
-       0x1dbd20b3, 0xe323bf75, 0x89675d39, 0xa1d0571a, 0x5df0dfaa, 0xda9fa471,
-       0x7ef3fb51, 0x3851eb86, 0xd7946bfe, 0xd57d238f, 0xa7a2643b, 0x9afecaa3,
-       0x27bf8614, 0xffecd262, 0x9ac91dfe, 0xda7597f1, 0x5db47034, 0xdbfdcfb5,
-       0x0ec4cba7, 0xd847a466, 0x3ec2f947, 0xe0771fd2, 0x1768aefa, 0xf7e8eb29,
-       0x45d90649, 0x8a2edcf9, 0xbe5487b6, 0xb889d66e, 0x65c78eac, 0x58dff9a3,
-       0xf1eec3fa, 0x8e492ad8, 0xc65bbfbc, 0xbe9073ba, 0x8612a3e6, 0x75d01ef1,
-       0x15fc23a7, 0x078b6deb, 0xccad7c39, 0xbfbf6976, 0x3f37bfca, 0x1e77d4be,
-       0x367495e5, 0x6561df4c, 0x07e518ab, 0x9e786be8, 0xad665e11, 0x258bd488,
-       0x8d2df1fd, 0xd84ba45d, 0xac78859b, 0xf1e46b38, 0x38e89e8f, 0x851fea97,
-       0xae2bf225, 0x93ea2e52, 0xe67bb8f9, 0x7f6778f0, 0x938f3379, 0xe5fc0915,
-       0x5d691a94, 0xdcf7808a, 0xb59efb16, 0x41fa54a4, 0x07dfa2f9, 0xef8029df,
-       0x61e690af, 0xb1553d9e, 0xca5291d7, 0x9777b5e3, 0xa14af278, 0x15f12a2c,
-       0x3d5e2296, 0x77d35f60, 0x9f643dc5, 0x33bce3a9, 0xfd16e3ca, 0xbcc96146,
-       0xee8f0edc, 0x6863ed07, 0xe3d8869c, 0x7a38fb40, 0xf6ec6e7e, 0xfc39b843,
-       0x30fb237d, 0x0c0643d2, 0x52f2a664, 0x16e5e32a, 0x8846aefa, 0x1e0de7fb,
-       0x9146f3d2, 0x103788af, 0xf4c7fc91, 0x1cbe34f5, 0x58f7419e, 0x8325d82d,
-       0x7691f9fb, 0x6a84ac94, 0x6aade322, 0xdf94a8b9, 0x1528ce73, 0x604cf3ef,
-       0xa8afc813, 0xea3cfcbc, 0xc3cd43f3, 0xc85765ec, 0x63f35e7b, 0xc3fa49d3,
-       0xa55f27e4, 0x4a0e607d, 0x1f39df91, 0x4a89bf6a, 0xc28a1c94, 0x5cf350d3,
-       0x22dc79ed, 0xd76af6e8, 0xcc7a655d, 0x2ed1f94e, 0x056b07ce, 0xd5dbf57d,
-       0xbe3f1e3f, 0xfe861f3f, 0xfefbd9ca, 0x4a7ef893, 0x37a56842, 0x145e7ec6,
-       0xe531f9fb, 0xce70d3c1, 0xfba18c1b, 0x0799ded1, 0xd20263a7, 0xf1f2c77b,
-       0x9eb005f0, 0x2dfcc537, 0x6feb9596, 0x1c5b4785, 0x1ef998ba, 0x7a78fe6f,
-       0xd93f0da2, 0xdce395ff, 0xa7206dfb, 0xd07d1e5b, 0x7581b0ac, 0x15d96b30,
-       0xe347f9ce, 0x6d5d7513, 0x625e305b, 0xf7aabd4d, 0xaf5c5a14, 0x697de024,
-       0x764de7ed, 0xb4460efc, 0x43c6a03d, 0xc6a5bd54, 0xa4bb544d, 0x1fe3c1c2,
-       0x7bfced33, 0x69f6153d, 0xb20fdfa4, 0xaff21aae, 0x226d3b30, 0x19fd0ab1,
-       0xe4fb5add, 0x4657bf3a, 0x9eda2a3b, 0x45334da8, 0x7abd07d9, 0x1715df94,
-       0xfe54fdb5, 0xc454acf8, 0x17795451, 0xcf9a4765, 0xbb40499f, 0x670bedeb,
-       0x8d142e28, 0x5c2eeb9f, 0xaebd9fde, 0x83f74f5d, 0xb7ad71d1, 0xfdd2e42f,
-       0x1baf11a0, 0xcccad4c1, 0x808cc43f, 0x6b7b4c97, 0x18ec1195, 0xf82983a3,
-       0x58fc36dd, 0x8d0dc633, 0x7c9c7817, 0xd7fb9d84, 0x2fc18b89, 0x95335185,
-       0x78c17da0, 0xef48ce7c, 0xef5d99d3, 0x09bdbd91, 0x9e2186ea, 0xa6199ec7,
-       0x5307118b, 0xc08a63cf, 0xb7e66eef, 0x4d81efe3, 0xf7f78bb1, 0x59db462e,
-       0xa22d3cfc, 0x2d62e27f, 0x3ce22d3e, 0x435b8327, 0xd3ec79df, 0xe7116f3e,
-       0xfb1a596b, 0x63a3ec1c, 0x7aa2439f, 0xc5b6130e, 0x596c39e1, 0x758a4dbc,
-       0x2f8b990e, 0x845b0e7f, 0xefd2a95f, 0xb204acb4, 0xe8a6f7af, 0x7b41fbe8,
-       0xcb59c313, 0xb2fdfe31, 0xaccfde99, 0xb4367110, 0x6b9f10a4, 0x84bf97b7,
-       0xa371db71, 0x7b8e74f5, 0xbcffd125, 0x60feff8e, 0x1fea78cf, 0xf883b327,
-       0xfb0780bb, 0x1bbbe9aa, 0xd3bbfcd1, 0x33dd007a, 0x3db9ceb6, 0x839c016b,
-       0x9980fb25, 0xcf839bfb, 0x4a3fef07, 0x7b4bbe05, 0xa654b9f8, 0xbda3d49d,
-       0xec66f25e, 0x8fe351f3, 0x3a9da47b, 0xaa362b20, 0x98fc8baf, 0xeca33b91,
-       0x642db3e9, 0x47c65b67, 0x39c0f7d5, 0x9f8ebdd1, 0xa1d916ec, 0x87ebaf3d,
-       0x114aa738, 0x7d7f3087, 0xfb65e28a, 0x7e714efa, 0x25c6d1e9, 0xfe5df727,
-       0xe7135e9c, 0xa1c453b4, 0x00e22e7e, 0x7e7fc29d, 0xf2a4e023, 0xea9b80cd,
-       0x04280adf, 0x0b940aef, 0x77cfc161, 0x47cb3e56, 0x84aaaf17, 0xcf47edfb,
-       0x7f7dbf73, 0xbe83a862, 0x42de74ef, 0xbda417df, 0xdbbf144d, 0x2c727c07,
-       0x1fbf49ce, 0x4cdb3478, 0xa5a3b3f1, 0x8a7bfbbf, 0xd16b7cbb, 0xc70bb8f1,
-       0xeb4e7ab3, 0x6f184e70, 0xee8b855d, 0x47e036a5, 0xeeffa114, 0xffbe8932,
-       0x040e1b34, 0x3a5445ef, 0xf169f537, 0x65ff0f59, 0x1ddff195, 0x617f42c8,
-       0xa4e88b8c, 0x2273ef42, 0x4fba373e, 0x571e5f91, 0x871beed8, 0x7af18071,
-       0x14fbbe26, 0x3bac4534, 0xe0426f0e, 0x44895379, 0x0a1a73df, 0x86e5d1bf,
-       0xa32fae54, 0x3475ffeb, 0xdd1b83d7, 0x773ce8db, 0x50b2ba3b, 0xf913efaf,
-       0x2964b310, 0x285fbf48, 0x1cb1dd77, 0x65915bf6, 0xc011bb1f, 0x6853a32d,
-       0x4f4afbfd, 0xd8f81c53, 0x21c65785, 0x76b31dfd, 0x79ce305a, 0x53dfc9cc,
-       0xf9951387, 0xf29db77b, 0xa4f2312d, 0xe958f2d5, 0x95fdfa22, 0xef7cfc7f,
-       0xdf7cd1da, 0x0af5524c, 0xfb815b8c, 0xdef9424d, 0xc3f902b2, 0xfc83b998,
-       0xaa73e8cc, 0x88b35f70, 0xfc64f3de, 0xb6bf4f7b, 0x3f782c86, 0x0267ed1c,
-       0xff426c7d, 0x3d04f778, 0x5eadaf7d, 0xe782e7e6, 0x1fa4e788, 0x997e13a3,
-       0x65667c76, 0xc0fa633e, 0xde1d6079, 0xf13ad0d7, 0xadefaa3e, 0xf86292bf,
-       0xc9d683b5, 0xf9589efc, 0xcdcfd1b0, 0x9a20b276, 0x1615b386, 0x709fa176,
-       0x99c69f30, 0xcce3e56d, 0x9b7c7112, 0x1759ffa0, 0x81df9475, 0xcf80d6f4,
-       0x7927cc95, 0x50f5cc72, 0xb7ac1d57, 0x41c6ce1e, 0x569346fe, 0x5b39090e,
-       0xf745525f, 0x07dcc7bd, 0xbfbea3c6, 0xe1e574be, 0x9fc22732, 0xb74154d4,
-       0xd52fa529, 0x945a5d20, 0x4c2f8a2e, 0x5d74cb76, 0x36b97d78, 0x17afd14e,
-       0xb44bf4a3, 0x928fa8be, 0x54f7113b, 0xf9c4434e, 0x4b9f72cf, 0xab83a488,
-       0x2f1ccbc7, 0xd67baf7e, 0x1da71e05, 0xe9f7978c, 0x7803a573, 0xd8ef3e89,
-       0xa73e8978, 0xeaad3c01, 0x8c1dcbaa, 0xbf6f155f, 0x1ac9792e, 0x8d1be799,
-       0xaf8a1fb7, 0x4156d1e6, 0x579e5caf, 0x3b7dbe08, 0xb771443b, 0xeff94bb7,
-       0xff731d4b, 0xb3bfe296, 0x0d63a858, 0xcbe045ca, 0xe8f94239, 0x344ce423,
-       0xf4f8061e, 0xbf2e283f, 0x28b7f3fb, 0x21caaa2e, 0xea25f213, 0xea1fc113,
-       0x1f9099b9, 0xf02f6f91, 0x2d5e87ef, 0x457ca87f, 0x383f21eb, 0x1fcc8fa4,
-       0x5fc5dffc, 0x18cd717b, 0x52167617, 0xd1cab83c, 0xac7bc7a5, 0x3dd250c9,
-       0xd27f8892, 0xf5919c3a, 0x591c6e3c, 0xa12f714f, 0xa6b8d4f7, 0xbb3ebeda,
-       0x5518412b, 0xc24d47a4, 0xc4fd51de, 0x64538e7d, 0x54faaa7f, 0x57fef716,
-       0x08f74fab, 0xfb543a7d, 0x79bb73de, 0x43cbe7dc, 0x1c800f3d, 0xa46f9c9f,
-       0x0e4cb8ef, 0xa3dfcc3f, 0xfe498470, 0x9137746f, 0x69fb0c1f, 0xe604a346,
-       0xf3e64475, 0xf3bee5a9, 0xefd60a6d, 0x0af4bb95, 0x16ff07f5, 0x568603e0,
-       0x0d869dfa, 0x137d738f, 0xd651f457, 0xba83dee5, 0xe6994fb3, 0x61efc24a,
-       0xdf835f6f, 0x8c2a0b01, 0xb598ebbe, 0xee458bb4, 0xdc31a5f7, 0xff9c9daf,
-       0x68071dd6, 0x69ea1fdd, 0x035768dd, 0x9d964f9d, 0xcfe7050e, 0xfd23dbf6,
-       0xf7d97dec, 0xb7009dda, 0x086c697c, 0xa3c37ad1, 0xecf3017e, 0x078d5733,
-       0x73ed8d4b, 0x0bf5181f, 0x7346c7c0, 0xa3cc04d5, 0xdbdfb6ac, 0xdae51f3e,
-       0x60265bd9, 0xbcec1bfc, 0x83b7d456, 0xcdb7dff6, 0x5d3bbf8c, 0xd69f78ed,
-       0xabafa231, 0x5abfbf06, 0x48f7e0ed, 0x87bed1be, 0x7b404cc6, 0x73c1ec39,
-       0x0c9f344f, 0x164cdd22, 0x2f1765eb, 0xbd41fc51, 0x9e73d997, 0xf8ff47d3,
-       0x8fb80f40, 0x455cbf6b, 0x7db922f7, 0xa026f9ba, 0x3c7d75d5, 0xf1db0c7f,
-       0xbf58e07b, 0x001d8628, 0x4be75cf3, 0xcaebf3c6, 0xde8637ba, 0x36fbedcd,
-       0xf6e783e0, 0x44bc7064, 0xc31e6fb7, 0xafb882ed, 0x9272cfde, 0x7ff5c03d,
-       0xf312c0b0, 0xa9b7553b, 0x3b1ad2fa, 0x552d450f, 0x23daa579, 0x21b35f80,
-       0xc69bbf02, 0x7cfdff70, 0xf103a7a9, 0x7fe77df7, 0xe50b710a, 0xf6cf52f1,
-       0xae91c331, 0x97ad5f04, 0xee01c663, 0xc5a3f31c, 0x13416e2b, 0x73beabef,
-       0x86e96fe9, 0x7441dba6, 0xf8e95065, 0xffe3a221, 0xe27bf48b, 0x20efd0fb,
-       0x14fe7479, 0xd347c3dd, 0x03bf4ab1, 0x9be6c874, 0x79e80692, 0x7ec1ba28,
-       0xe806928b, 0xfb7ea87a, 0x931fbfce, 0xe9c607de, 0xabdd2cbd, 0xd059b7f4,
-       0x540f7a91, 0xfd79ce29, 0xfeec8cd7, 0xf5463da3, 0x7e35c677, 0xca3fe811,
-       0x72b0aea3, 0x37b47fb9, 0x3d19fb97, 0x9a9fba66, 0xbe295ee9, 0x235d0dbb,
-       0xf211adc6, 0x75dba67e, 0xeaaf3959, 0xfddf550b, 0x43777c4f, 0x00800098,
-       0x00000000, 0x00088b1f, 0x00000000, 0x7dedff00, 0xc754740b, 0xeebd6095,
-       0x91a93fd7, 0x16883e9e, 0xc085a092, 0xeb404616, 0x7d3d05ff, 0xa71f3210,
-       0x900b18c1, 0x04e08b4c, 0x60dd491b, 0x9e3d90e2, 0x123231a1, 0x1f62cd9f,
-       0xbd6678cc, 0x8c030d39, 0xc077b19d, 0x0b611c56, 0x3837e2dc, 0x71c6ec4b,
-       0x3c4c9c18, 0x6c0843c2, 0xc718d36c, 0xbc4ab243, 0x0f7adef7, 0x0b756bf5,
-       0xcceb43db, 0x40e75764, 0xaabd5ea9, 0xfeeb75ba, 0x7ad3d56f, 0xcecc6333,
-       0x53f817d8, 0x08acbc3d, 0x65cb191a, 0xfc05f3f4, 0xebf2e2db, 0xdf632b25,
-       0xb4cbeeb9, 0x2c93f943, 0x1e670adf, 0x355faf63, 0xb188acca, 0xf6e3a9ae,
-       0xfa87b3ea, 0x8c08758f, 0x127b4315, 0xef768674, 0x0077c154, 0x27d1311e,
-       0x7d1e9d2e, 0xfd4c9fde, 0x8795cdae, 0x9d32fab3, 0xaf7a6863, 0x59b18d3e,
-       0xca0e9bf8, 0x332d9320, 0x5aedcca0, 0xcca012c7, 0x9636f92c, 0xb12e624c,
-       0xf2933184, 0x6bcae99e, 0x39f015df, 0xfe831993, 0x56f595eb, 0x0d5d7f30,
-       0xcccf31c0, 0x3889f1bc, 0xc9c9d37a, 0x97cd5ed0, 0xd769e30a, 0xfe9fde1d,
-       0xe4f329a5, 0x572e3630, 0xfbcdf5a0, 0xf04cf98c, 0xeb6e756b, 0xe7033602,
-       0xd1cc7187, 0x1e60a9c7, 0x1d01e999, 0x2adb5ee5, 0xaa6b3fe8, 0xafe5e1c9,
-       0x6cdef84b, 0x3e1bdfc6, 0x4ac67ace, 0xe2d9c686, 0x54fac809, 0x4c498ec6,
-       0x6f5b2fe9, 0xf8e767c1, 0xb2857ac3, 0xcd6e533e, 0xebcbc455, 0x07e1c792,
-       0x860f6778, 0xcb1d6f8d, 0x55633a58, 0x8b9f699f, 0x387d6d0e, 0x58fb305c,
-       0x5f4fe5fa, 0x33467cc0, 0x5d398fc7, 0x5d79f847, 0x3e90fa32, 0xeed4ae2a,
-       0x4b189362, 0xfc87ec96, 0x992adcf0, 0x36053e1d, 0x7e53f633, 0x0402b8af,
-       0xc29fed04, 0x738014bf, 0x5aef6e9b, 0x16ddd027, 0xa21f4c6c, 0x4c0b2597,
-       0x2e96381a, 0x9bd4d449, 0xea69c79a, 0xd44f57cb, 0xdb736fec, 0x43fa9add,
-       0xea6a661b, 0x354a27ae, 0xd59d55f5, 0xef56f19a, 0xff69ab9c, 0x686feed6,
-       0x7f9e6bea, 0x747f5350, 0xe911caff, 0x885f1a22, 0x89e991b6, 0xd23b0579,
-       0x3a4d88bf, 0x9cc5cffc, 0xf7f7a3d3, 0x7ec27f21, 0xb7af6ebd, 0xd5fe82ad,
-       0xe78d3f57, 0xc5f4b4fd, 0xf90072bc, 0x17d956a3, 0x402bc798, 0xad528d7b,
-       0xf445be95, 0x4536635e, 0xee951be4, 0x11560ab6, 0xda66afc7, 0x6db0aafd,
-       0x7e47aebd, 0xebd01a2e, 0x3759be61, 0x2157fcb5, 0xc706fc35, 0xc7afcc67,
-       0xa5cb84f5, 0x9318eeff, 0x609e397a, 0xfc017fb5, 0x8cc9acc4, 0xa3c74795,
-       0x5db7a74a, 0x6f5f6337, 0xeafccadd, 0xa0582b7a, 0xda3ee90e, 0xfc3b67ba,
-       0x516b927a, 0x5ebe1dd6, 0x6feffe15, 0xef815f86, 0xf323ff5f, 0xdb1013ed,
-       0xe6fc88b2, 0xcfeb5ddf, 0x02402bb5, 0x7a1527bc, 0x278291a8, 0x0e908b12,
-       0x83650398, 0x51f99071, 0xc133d40e, 0x9652846f, 0x38af041c, 0x3034ef68,
-       0x7e71eb2a, 0xa6861071, 0x35eb45d2, 0x288dca0e, 0xa92c456f, 0xebc79cee,
-       0x875e068e, 0xd52ea8f7, 0x3ee7baf2, 0xea92875e, 0x43af275e, 0x5aefaa3f,
-       0xb8cef58c, 0x014489c0, 0x5825beeb, 0x5a1e0e37, 0x05ff4bca, 0xe4994a81,
-       0x5de83896, 0xec7ea7a7, 0x3707af22, 0xf2d0fa71, 0xf65e3183, 0x5f19b3f9,
-       0x813f3c3d, 0xfdc24dbf, 0x006fd75c, 0x828ad43c, 0xd5ef0ec3, 0x3f87320c,
-       0xe4d5f715, 0xe097d990, 0x3133a033, 0x8ccf886d, 0x4ab1982c, 0x0f793e20,
-       0xedcaadf1, 0xe968e3e1, 0x5af51eab, 0xfc3bec01, 0xe51931be, 0xfaa7a730,
-       0x2c12e0b2, 0xd013f9f1, 0xfc327b3e, 0x1f4e1e4b, 0x32a25c2a, 0x5fb5a55f,
-       0x32b6aa8f, 0x59b72618, 0x8559d117, 0xd92c9d79, 0x716dcb87, 0x2e2fe550,
-       0x56e1c22f, 0x1f39ade5, 0xfb1a6cf8, 0xb9967c3a, 0xaeb36a0a, 0xd9f0abbe,
-       0x933e30ba, 0x8496f7ad, 0x321019f0, 0xb7d9f0d3, 0x276e9e89, 0x83094e5f,
-       0x4f182675, 0x23e80cf6, 0xc05499ca, 0x3e244243, 0xb21bfb9b, 0x97c8a21f,
-       0x5817f037, 0x987e6e67, 0x5cf4519c, 0xfee7aab5, 0xdda2b3a8, 0x117a67e2,
-       0xc87c70cb, 0xd2313b2c, 0xbe3cb573, 0x6bba0609, 0x90f80ea8, 0x63be810f,
-       0x06dc151f, 0xcec99bcf, 0x805ab862, 0x31e2aac7, 0x71ad6e8c, 0xec909d2f,
-       0xecf505bc, 0x4e6e8518, 0xdf11a766, 0xc7bd76c3, 0xb59de442, 0x01f1cbe8,
-       0xc70937cd, 0xbf226673, 0xc6db40d5, 0x33fde182, 0x99f00fb1, 0x3e7cc835,
-       0x08eacf78, 0x46af5808, 0xf48d9efd, 0xfe51eacf, 0xe8095f57, 0xe5a5ea25,
-       0x00745b97, 0xa4013fbf, 0x517c8b57, 0x642e9c30, 0x7ee3d3e6, 0xaffdd57c,
-       0x90341fb6, 0xffdb0ebc, 0xcfb0419a, 0xd5394e00, 0x1afa20e4, 0xc8cf6464,
-       0x48c7c14e, 0xbc21acbe, 0xade3f6a8, 0x176826f6, 0x622e91e8, 0xf640b37b,
-       0xb36ca7d0, 0xf305f381, 0x867a55fa, 0x30afcbe7, 0x34ed1139, 0x7ed4f3cb,
-       0xfa23136c, 0x3c97b6a8, 0xb8476755, 0x44cc7606, 0x0abd24b8, 0xc7153f97,
-       0x70e260bd, 0x7f08daf9, 0xe4fe0ad5, 0x43331d41, 0x694fbfbb, 0xff5fa30f,
-       0xfcd3b720, 0x702bc44f, 0x43f0c8dd, 0x4ed007bf, 0xe5689306, 0x43ff03dd,
-       0x69dcf784, 0x01df3f77, 0xf028ae5d, 0x6e856ffc, 0x5124da3f, 0xf5cd3eb9,
-       0xc7a07cfd, 0x7c6e917f, 0x0fc866e2, 0xd5f74439, 0x9027cff6, 0xd9f1521e,
-       0x10f48637, 0xe8f84dc2, 0xdb8344b3, 0x387510aa, 0xe5bf0abc, 0x2a57c88c,
-       0x577c2a9c, 0x0bab7a7c, 0xe7b37bc6, 0xf61c135f, 0x454bf821, 0xfb847ee7,
-       0x674fc1cd, 0x92ef88b8, 0x34667635, 0xfc5266f9, 0x964ca488, 0x3ea2a62b,
-       0x85cc7388, 0x74cb8c75, 0x364cbad1, 0x02fd1da3, 0xf393274b, 0x82734860,
-       0xf7f08ccf, 0xd2ec37a7, 0xa9d6fb43, 0xfbc13322, 0x36bcb35b, 0x09fea75a,
-       0x9399eb86, 0xd60361e9, 0x6577f3e8, 0x9c11293e, 0xbf475083, 0xa2f1c6c7,
-       0xf8f4689f, 0xc75fb9e0, 0xc10a1cd6, 0xee02c1cb, 0xe7cd9d8f, 0x1e17dae5,
-       0x842976d9, 0xad0fda3f, 0xbdddd4d3, 0x2976dbdf, 0x106ede54, 0x3697dc44,
-       0xd9db8e85, 0x5ff404c0, 0xe13b455a, 0x903743a1, 0x2c6bf586, 0xae0a7e78,
-       0x008fe70f, 0x5be73fff, 0xd2ff3d62, 0x8ff650a9, 0xff69fee1, 0x0df91f24,
-       0x2b1ffcea, 0x5f38ffeb, 0xa6387317, 0xb3ba1e01, 0x9f70c5bf, 0x3f7c6c6a,
-       0x7a72504d, 0xf54372e6, 0x739e8677, 0x3ea55179, 0x73de3a0f, 0x1ce91d12,
-       0x994c76a8, 0x7de911f6, 0x71bbd227, 0x48b5bea8, 0xf08be8d7, 0x220573fe,
-       0x16c07bc1, 0xa15b3db9, 0x5c139d97, 0xdfe8d9dd, 0x6c73ab3f, 0xcbce2586,
-       0xe51e3adc, 0x7adb56fd, 0xe2e653a2, 0x38c058eb, 0xf4cbcebf, 0xd1e81978,
-       0x82b7fe79, 0x8dd62a42, 0xf886c2cc, 0xe70bf557, 0x01d13e89, 0xd7f2bbfd,
-       0x5ddd7199, 0x1c66f5b6, 0x82d684cf, 0xea3c386e, 0xe6ec0fba, 0xf4cbcef3,
-       0xb2e9e089, 0xc57bb9b9, 0xa33fa801, 0xee5e7bac, 0x6aaf6a3a, 0x09149ff4,
-       0x4367e07f, 0xf568e8dd, 0x87263ce2, 0x3ac246bd, 0xb2c66c73, 0xec89784f,
-       0x0dbf5513, 0x9dad4fe9, 0x91bafa72, 0x15d763e4, 0xf244cf9d, 0x07305e53,
-       0xbcaf9fde, 0x7b720d6d, 0xa3bf6bbe, 0x1cf7c45f, 0xf3e3f902, 0x764dbf73,
-       0x2e77359d, 0x56b3e7b7, 0x98549179, 0x3fa1f04f, 0x5bc54f31, 0x195f569e,
-       0xa0b7171d, 0xd4de30fa, 0x2c59d1ea, 0x2abe90c0, 0x70f3fcc2, 0x40bb3b7d,
-       0x5972d7b1, 0x2d2bda31, 0xc863df26, 0x420d960f, 0xe2a1c23a, 0x8e814575,
-       0x7c8620e8, 0x942667b0, 0xb465d95d, 0xd3ccfaaf, 0x5f980417, 0x4366df17,
-       0x8cdbd0be, 0xb31bc47e, 0xa80d1f8a, 0xffc24df3, 0xb7b22533, 0x2f848eb0,
-       0xfc79397d, 0x86c7966e, 0xb032eceb, 0xa7f248a6, 0xfdf380b6, 0x927e5907,
-       0x8ddad10f, 0x7bd2041b, 0x66377caa, 0xc237d932, 0x5c8cdb78, 0xd25f80ce,
-       0x3ebf402b, 0xffa017a4, 0xf7b35a17, 0x7ba205e9, 0xadf1e519, 0x12efb152,
-       0xfe1fb90b, 0xca898166, 0x547eca93, 0xc336717f, 0xaffc8235, 0x8430f2aa,
-       0xc7ca94df, 0xf1f26533, 0x732f224c, 0x2e3f7195, 0x5cdc7ce2, 0x5fb97b14,
-       0xfb7a339a, 0x8d7a4b1c, 0x90285287, 0x98dd79e8, 0xc52e4987, 0xa3396f12,
-       0x5da33788, 0xa7073fa1, 0x73fdb513, 0xaaffde45, 0xb274e620, 0xe51472b4,
-       0xa4e92c41, 0xde83cfe2, 0x79ff97cf, 0x68da47ec, 0x99a3e3ae, 0xe042d4f2,
-       0x2e9cbf93, 0x96e583df, 0xbbdb23d7, 0x772f63f3, 0x72801ed3, 0x37df04f1,
-       0x79b3e923, 0xfb97b185, 0x48bed14b, 0xf845f6e1, 0x3d15cbfc, 0xd2794b14,
-       0x11b36504, 0xff011fd6, 0xfcc28e8f, 0xef5073cb, 0xe5817b72, 0x0fa4b99e,
-       0x67e1dfb1, 0x3ec42eb2, 0x1c147b06, 0x0543b441, 0xeddd9239, 0x2d7efd8d,
-       0x643f487d, 0x5c61ccaf, 0x2ff3a81f, 0x7af8e12c, 0xb0e0147a, 0x25eade00,
-       0xc29baf6e, 0xbfcb50e0, 0x7dbd8c2d, 0xe043e92a, 0x1fbb0548, 0x444205cb,
-       0xd0a7af7b, 0x1a7e7318, 0xe2d9780b, 0xe4918d60, 0xefd8c9c9, 0xca0d9a4b,
-       0xd3cee9aa, 0x4b96d728, 0x5c60e787, 0x1ff8fbf9, 0x79d21be6, 0xc1a561be,
-       0xaeff45e5, 0xbc3bb24b, 0xac478c76, 0x7ccafaa2, 0x52af43bb, 0x94dfb63e,
-       0x6c05db7c, 0xe57d51d7, 0xda1f24ef, 0xd617dfc3, 0xf1c6c99d, 0xfb1deb36,
-       0x959dc618, 0xe78d837c, 0x9e36ac1b, 0x3c6d109f, 0x29b560ef, 0xcf1b0779,
-       0x4a6d583b, 0xf3c6c1de, 0x929b560e, 0xbcf1b077, 0xe4a6d583, 0xef3c6c1d,
-       0x7929b560, 0x3bcf1b07, 0xde6a6d58, 0x1538d3c1, 0x9e3691e3, 0x78dab077,
-       0xe36ac1de, 0x97980779, 0x3c6c1de7, 0xf17000ef, 0x722d83bc, 0x943ac1de,
-       0xf1ff2077, 0x67a49618, 0x547f5fb8, 0x7b06cfa9, 0x786334dd, 0xe76ab55e,
-       0x17182dfe, 0xfc7209ab, 0x5e783955, 0x77b414d9, 0x457e300a, 0x04dfb066,
-       0x114565fe, 0xb0d5f0c3, 0x13f3c3f9, 0xbde7d9dd, 0xb0a3fa02, 0x03bc2997,
-       0x18ea29e5, 0xfe7c3f7f, 0x3b577161, 0x65d6e78f, 0x3bf08b7e, 0x78482cbb,
-       0x8718e7c3, 0x13f253ad, 0xffad56b5, 0xb2e67f2a, 0x995f71f9, 0xf80899d4,
-       0xbb6d4590, 0x8c2ff988, 0xd7f15ebb, 0x6ab7dc61, 0x15771b50, 0xb8d41b33,
-       0x844bcf3c, 0xe1df39c1, 0x6b045f1c, 0x2a7f016a, 0xc1cfe601, 0x53ae15a4,
-       0xa45e7c12, 0x881bddb7, 0x453bbcbe, 0xaa6814c7, 0x9e606404, 0x6a2012a5,
-       0xc654d286, 0xf24cd2ac, 0xfe9d389b, 0xf1bdd4d7, 0x030f28d9, 0x6c04467a,
-       0xf9a83c23, 0xbf580485, 0x2bfc8334, 0x332aeff2, 0x3a47bffd, 0xcc82eb50,
-       0x5d8238f3, 0x2f80cd62, 0x5c266ef9, 0xceab9336, 0x45eb6f90, 0x73c335e6,
-       0x9b37e941, 0x2d4e2905, 0x76f28933, 0x6541ccb5, 0x695774d1, 0xcea3f011,
-       0x7ae175ec, 0x0966ecaa, 0xee3d85f9, 0xf148db3c, 0x32e97ae4, 0xf60049e0,
-       0x48da62f8, 0x2ec88a76, 0x451cf8ab, 0x2f1f48bb, 0xadc92278, 0x61ebd88a,
-       0x0a2a83b2, 0x2dc7c919, 0x7cfcb22c, 0xcfcb84ac, 0xdf5d4b37, 0xfbd73c44,
-       0x878fd516, 0xd0be8f2e, 0x6d9b794a, 0x5bc2f161, 0x6f628afd, 0x90e72447,
-       0xe901b93d, 0x8f04f17a, 0x1688e10d, 0xf62a78c7, 0x1b49ecf0, 0x767baec1,
-       0xd45aec14, 0x2aecb743, 0xfa9399fb, 0xb1ca3b50, 0xd0ba4f0e, 0x9092baef,
-       0xc3ddaa38, 0x8d67143c, 0x6979af1c, 0x9920e214, 0xfe13bfa8, 0xea639d0b,
-       0x87fb023a, 0x54bcfbe5, 0x428ef8e1, 0x634be387, 0xa0d317cf, 0x613e27d4,
-       0x771b8d0b, 0x970e0459, 0xf5c0d041, 0xfdff62b9, 0x78f624a0, 0x7d72812a,
-       0xf22efca9, 0xf974d561, 0x7caa5867, 0xbae1df3b, 0x2d29fc40, 0xf9024faa,
-       0x767f66bc, 0x0689ea01, 0x2ae35edb, 0x52d5f780, 0x3a22fdf9, 0x5b1ff46f,
-       0x1eb16e1e, 0xf7bc478f, 0xa3cb22b9, 0xc50911bb, 0x28de4fe4, 0x67e4fee2,
-       0xfe288784, 0x638bafe4, 0xea7b2fbe, 0xc9fc8673, 0x5b1ffe70, 0x639de3cc,
-       0x068e0147, 0xf1465728, 0xc28ca6eb, 0xbf5a8dfc, 0x443ebf6e, 0x854110ce,
-       0xdc6c69e6, 0xfc1163af, 0xba35973d, 0x147b37bf, 0xf310b1d6, 0xf591b571,
-       0x31c57dda, 0x7e96aff7, 0x3307ca03, 0xd0a9fd5b, 0x6f30bcc4, 0xb2be50da,
-       0x0fafd5c9, 0x383f738d, 0xe537e0e1, 0xb37e7008, 0xf272e638, 0xf91e9c7c,
-       0xe119bd75, 0x7e066ae9, 0x255fb08d, 0x9bffdc25, 0x9611e13b, 0x3a637688,
-       0xe411f743, 0x3637cf09, 0x83637e29, 0x2a767fa2, 0x2c53d472, 0xe52ce952,
-       0xe851b9f5, 0xfbcad7fa, 0xb69c4a8d, 0x2bf26251, 0xec7ff491, 0x38fce6e9,
-       0x71c6e728, 0xf30def38, 0xf453dfcf, 0xd3d89ec4, 0xa00c9ecf, 0x91b5b993,
-       0xf63075f1, 0x0274b174, 0xf6d4bfcc, 0xf8901cf4, 0x0d9b2fb0, 0x2e9c5f94,
-       0xef0c58bf, 0x57c28b6d, 0x69782b9f, 0xb03a3e86, 0x34a05bfb, 0x9010f942,
-       0xfa405481, 0x6fec55ed, 0x14308e01, 0xf1de0420, 0x3af4e7e8, 0xce7c1ee4,
-       0x7fe46d5c, 0xca1bc884, 0x3999569f, 0x83a774df, 0x0efe88ff, 0x9339d333,
-       0x9fcf20ae, 0xfcf26576, 0x6a3c3868, 0x456ff4fe, 0x71cf198f, 0xc4166577,
-       0xebddf285, 0x6f26989b, 0xe78575dc, 0x8a4fc185, 0xc949fad3, 0x8f8527e4,
-       0x74b9909f, 0x247fa85e, 0x021fdcc8, 0x5c50267f, 0xa917e43c, 0x7c98cffe,
-       0x7ff15cf9, 0xcd1dfd02, 0x4947119f, 0x07308b0f, 0x74ddff3e, 0x8f10dff9,
-       0x1fd3d023, 0x9fd3d0a3, 0x347fdfb0, 0x11cc627a, 0xf0cc68b7, 0x1eb2bb71,
-       0x708eb5b7, 0xd321203f, 0x54ce9119, 0x9b7a02fa, 0xe8763250, 0xb4f3217d,
-       0x4b136f4a, 0xbd3ebf8a, 0xf0bec05d, 0xafe1acef, 0xd149d6ec, 0x7ab59dfb,
-       0xfa0f28cc, 0xf19bd732, 0x99d4c49e, 0x6bce072e, 0x006c9911, 0x3e5cbb38,
-       0x007b9e33, 0x64bf2f3b, 0xcdc1bc84, 0x7e3f2e22, 0xdcffecad, 0x2aff9c09,
-       0x7dbe0b96, 0x6c4d7fc0, 0x4df70197, 0x4958ff7d, 0x7b88fdec, 0x35ee4872,
-       0xf7208c96, 0xe2f8565e, 0x2b5f0573, 0xe729d6da, 0xfb445899, 0xfdec5567,
-       0x942b348c, 0x45d75273, 0x745be3a4, 0x2285e787, 0xe21467ac, 0xe4c7e7e0,
-       0xcd4c3ce0, 0xfc406d2b, 0xf1c4563e, 0x7dfecd17, 0xb3fc146a, 0x4ad70089,
-       0xfd0199f6, 0xc7ff5969, 0x11e748ac, 0x39d9158e, 0x0390069c, 0x5995df80,
-       0xfc31b7ba, 0xb5a495d9, 0x67f7d487, 0x67aefe2b, 0x5267e414, 0xf1c3ce0e,
-       0x4c0e7e1a, 0x3ec5cf2d, 0x88b4b01e, 0x80ffb9fb, 0x73fc0efc, 0xe358a4a8,
-       0x64a8fee7, 0xb5f73f64, 0x1adc8f7f, 0xcba8e850, 0x7d9ed911, 0x40fbf621,
-       0xdd60e0e7, 0xb9157cef, 0xaa6f6e11, 0xdbd89ee5, 0x7a59697b, 0xd1c3879c,
-       0x24e7b4c8, 0x28dff16e, 0x8f5d2de0, 0x77e968f3, 0x5ffae325, 0x1a58c385,
-       0xe78c73f3, 0xff31e867, 0x7d79f9c3, 0x94be2ba9, 0x198f36ec, 0x07d837f5,
-       0xb95f6714, 0xcd1f2539, 0x6b67d82a, 0x93be96a9, 0xefa6474a, 0x403bd2e4,
-       0xfc9caadf, 0x534c6117, 0xa899bca8, 0xa5699bc8, 0x29afdfb1, 0x8e48af18,
-       0x632baf2c, 0x73dbe71f, 0x79744e77, 0xfb379eac, 0x4f1b4147, 0x8f25bd6e,
-       0x69474e63, 0x7921faa9, 0x7087eaac, 0x5e868d3c, 0x0bd10c48, 0xcce4510d,
-       0x3631c068, 0x9db51f04, 0x98afe502, 0xc0a6f98d, 0x39d89daf, 0x96c7dee4,
-       0x4f138851, 0xc87f8d0f, 0xa047af60, 0xb1a5dde3, 0xbca37fcf, 0xdb7c37e9,
-       0x47f9d236, 0x28c5d5a3, 0x3173623f, 0xb19fec3b, 0xf6f295b3, 0x94ad05c6,
-       0x029d6687, 0xf498fde5, 0xab79f92e, 0x30a7de6c, 0x9e5c367d, 0x5e398d6c,
-       0x97d8728b, 0x28c537f6, 0xf8ebcd7e, 0x37f93a4a, 0x153ca3af, 0xb347ee24,
-       0xf74ecc0d, 0xb97cafa4, 0x202f58fb, 0x9a2f3012, 0x763ee8c4, 0x7ac7e1a7,
-       0x051b47cc, 0xe65cfe3e, 0x974ff9e7, 0xf0a3fc77, 0x31a0e59e, 0x7f543b7f,
-       0xfb4d9a51, 0xcfe569de, 0xf39bf6bb, 0x9ea5849f, 0xc19e15b6, 0xa753e1f3,
-       0xec1c5327, 0x6b8f03c5, 0xbc5aecec, 0xdf7e80c7, 0x7e861e0b, 0x35d329a2,
-       0x9c3b2471, 0xae927f31, 0xa89a508c, 0xfa5e7a94, 0xf86d9d05, 0xf7f73bfb,
-       0xbd67e848, 0x724cc078, 0x9e81ea7f, 0xe32155f8, 0x3e719627, 0xfe3d06b6,
-       0x35af0019, 0x093273d3, 0xf92b1def, 0xce799173, 0x632bc2d4, 0x0f9d00a4,
-       0x6b5791df, 0x2ebba50e, 0x794cd6a9, 0x639d5ce4, 0xfceb1d8a, 0xf4fc431c,
-       0x4082fdda, 0x112edd7e, 0xe19aef50, 0xec7a86ba, 0xc3eb890d, 0x496b53a9,
-       0xe72a75ab, 0x2de4761e, 0xc7ef8039, 0xf1a7af4f, 0x7b64593b, 0xe5c658cc,
-       0x99068bf0, 0x80f17de6, 0x55c8e748, 0x7c69debc, 0x0f30cbd6, 0xa6dea3e0,
-       0xa7d87ba7, 0xe5114e8d, 0x8134e9d0, 0xdf2d82ed, 0xee8578e9, 0x0288ec99,
-       0xb94a2fef, 0xa96cca9f, 0xf7a77f44, 0x748f2e77, 0xbfa55f7e, 0xa96433c9,
-       0x49c0ed0c, 0xff94269e, 0x36e4b6cc, 0xdf24f17c, 0xe68743bf, 0xcffc03cf,
-       0x227fc17d, 0x6b21f70e, 0xf75c78cf, 0x6a76a507, 0x1f0f45bf, 0xb0f442bd,
-       0xe3efc8c5, 0x8e717578, 0x858eb003, 0xcf1101d6, 0x8352184f, 0x2a6de794,
-       0x8b74f2e3, 0x81630fca, 0x7d3de01f, 0xc507bf06, 0xcea9da26, 0x84270726,
-       0x559ea3de, 0x0597aca6, 0xc2f9f132, 0xd83777f8, 0xf6158c1d, 0xb08b37a6,
-       0xef8985fe, 0x7a86c86e, 0x5e78ef49, 0xb3f778cf, 0xb2b1896c, 0x9f5e0cde,
-       0x9367eef6, 0x9bd15ea0, 0x3095ebc9, 0x9bb078d4, 0xbd9ab37a, 0xa4be3879,
-       0x0f15bf19, 0xfd7f1472, 0x45d26f52, 0x28355f8c, 0x031f87eb, 0xfbece3ce,
-       0xe2ef3a47, 0x78fd5b34, 0x86c9832e, 0x3419f8b0, 0x6077dc85, 0xff2409a9,
-       0xf30bfbd4, 0xf63f7f45, 0x84fd99d7, 0x2759bbdf, 0xad8073d9, 0x7e145fdd,
-       0x5c2e7b79, 0xc8d96dee, 0x8c4e785c, 0xef0966b1, 0xd64c0833, 0x78e3c17d,
-       0x855f9c4e, 0x187f9d47, 0xc8b5b05c, 0x3d70439f, 0x70a8e34f, 0x7937cb5d,
-       0x6b7ade51, 0x0427ae59, 0xe084d74f, 0x456c180f, 0x0f1dacda, 0x1b5d3ee1,
-       0x40209c13, 0x1b7cb93d, 0xb1b5dbed, 0x8e081fc1, 0xef81ba90, 0x096f5b63,
-       0x289763ed, 0x9b9d21b7, 0x216ed68c, 0xb8eeb191, 0xe60c1984, 0xe5d631d9,
-       0x406e7bc5, 0xd8ef7477, 0x1c74659b, 0x8beb3800, 0xc7a1f9b4, 0x83fb3a15,
-       0x98e60f22, 0x01ce7976, 0x047bba5d, 0xdc70f786, 0xa88c3783, 0x5df616ff,
-       0xa4be6234, 0x11a2e7a3, 0xeb03bee9, 0xf3c74e30, 0x6ff988c6, 0xbd5eb963,
-       0x91e74a2f, 0x4f1c4bd6, 0x7aeeb2a7, 0xe9e0152a, 0xbdd02d58, 0x9247f5bc,
-       0x7d7d60e6, 0xb192ae2b, 0xe78755e5, 0x38b4b920, 0x72c29ffb, 0x95381b25,
-       0xccb4240a, 0x10f667a5, 0x4d62b93d, 0xe887b33c, 0x8a4f16c9, 0x1772bea6,
-       0x280cceec, 0xfa686637, 0xeafee531, 0x83f43632, 0x949a98e7, 0xdb665c7d,
-       0xeeb8c019, 0x3bc19732, 0xc2de3210, 0x3262cdbe, 0x1c11edc2, 0xcbd28d74,
-       0xe0ad3fcf, 0x1c52842b, 0xf7cf1f7a, 0xefc40af4, 0xba7a6d1d, 0xcbdcd3c7,
-       0x35e6aeed, 0x202ecf82, 0x0dbdf81e, 0xed40af77, 0xeba7deee, 0x1bef1193,
-       0x47000f00, 0x7d84f8da, 0x9347112c, 0x4ad5dce9, 0xdf775605, 0xb38e0339,
-       0xdd023be2, 0x9bbf5567, 0xb2bfc2a0, 0x91ce91a9, 0xa45e7c01, 0x4d9d754f,
-       0x5ce947f6, 0x9789cad5, 0x6187a80d, 0x3406977d, 0x5bd6d4f8, 0xcafada3c,
-       0xd1fada8d, 0xf29ee532, 0xf90d3634, 0x209978e9, 0xb52439e2, 0xf9d651fe,
-       0xe75ef1b7, 0x0a79d16e, 0xe8cdb3e9, 0x7efa819f, 0xbaa2e8b7, 0x3bcf0eda,
-       0xf89df118, 0xb1f100e1, 0xc5b9fc40, 0xf8354b20, 0x8176973d, 0xb60576e8,
-       0x0f67f3ab, 0xfd754fbd, 0x554dfaf0, 0x1b9c5aee, 0x4730bbe8, 0x90ed0905,
-       0x9316517a, 0x222f88f3, 0xbdf9779e, 0xa36f07c2, 0xeeb803f6, 0x7d852242,
-       0x44feebba, 0xbde6179f, 0x3a56cdeb, 0x215776e7, 0xf91d81d0, 0xd6e7475e,
-       0x2f79e3e6, 0x7903ef28, 0x2ef28168, 0x9226a1fd, 0x128d33ef, 0x9ce577c9,
-       0xe42f2a97, 0xb6e7b517, 0x219e67e6, 0xe7beeb3b, 0xb579d276, 0xc17239c9,
-       0x2d0fa8d3, 0x471dfe7c, 0x1866df04, 0x34ef23a7, 0x3271cfc9, 0x61d72f3f,
-       0x2f68e453, 0xfd7551c8, 0x50e3bfb0, 0x692261ae, 0x9bcd1e41, 0x5da9566e,
-       0xf8283926, 0xffe8756b, 0xdde6538e, 0x75a76d5f, 0x487a3da7, 0x316775c0,
-       0xe60166ef, 0x7c3a82bb, 0x55f950ec, 0xf8b5d7ed, 0x565de80b, 0x5b63b5af,
-       0x65e3d745, 0x6dbb5f30, 0x2dcfc8c0, 0x1fa88d06, 0xdef8e0ee, 0xf2c3e348,
-       0x50ee7475, 0x4730fbe2, 0x7680983f, 0x39a3face, 0xf608d8e3, 0xd3acde8d,
-       0x148311c8, 0xf33791a7, 0x67f2b573, 0x772b43a1, 0xa39651be, 0x4f245f69,
-       0xdfdfb4d3, 0x3fa9a858, 0xbcd4ace0, 0x9d5360ff, 0xcdb26ea6, 0xb16fbcd3,
-       0xe3d4d62f, 0xde6b9773, 0xa558e31f, 0xf5bd3769, 0xed0126a3, 0xc077b371,
-       0x06e87805, 0x1e4b28de, 0x12d323d2, 0xe32865e0, 0x2c562d0a, 0x744df3bb,
-       0x3c7bb64e, 0xec4497e8, 0x773a1dff, 0xc97c4e69, 0xdfe5035c, 0xfc5abe0b,
-       0xc9a00e7e, 0x3ddbf685, 0xf0e3684f, 0x5f38abc7, 0xb94365a9, 0x280ac1eb,
-       0x67b05ef3, 0x81e97bf0, 0xcc7f707b, 0x45db8c71, 0x2ec999af, 0x5376899a,
-       0xb071bf88, 0x397e66ba, 0xbe427bf6, 0xf582f917, 0xbc0a6932, 0x3b08cfb7,
-       0x35ee7a8b, 0xebcbf523, 0xe685d01d, 0xce597ff7, 0xceb3c1e5, 0xfc717bda,
-       0xb2d03e8e, 0x7dcf4fc8, 0xaebf4468, 0x013fafa3, 0xe70cd9f5, 0xcfb44687,
-       0x7a2b9e87, 0x61c60c4e, 0x0e1fe39c, 0x63de23e9, 0xa46e5edd, 0x722b4ff1,
-       0x7a3be5bd, 0xf78b4f3a, 0x864a6b37, 0xe1cb73e4, 0x63ef1fa0, 0x7bf3b4b7,
-       0x368e789b, 0xf9069c92, 0xbca861fc, 0xf41d367d, 0x4f1a4cc1, 0x97960fa3,
-       0x3edee9f9, 0xfbcd6fc8, 0x5c34972b, 0xc8257cc5, 0x4cf3ed71, 0xb1961e7e,
-       0x73fa0301, 0xed35d720, 0xfb95cb1b, 0xde58d39c, 0x2e072017, 0xdbdf2338,
-       0x9f8abb7d, 0xaae0b833, 0x16787da3, 0x47e789f0, 0x3f861d9f, 0xe1dbd78e,
-       0x81a465ed, 0x661bfd90, 0xff7157ff, 0x7228e5ea, 0xbfb2a2fb, 0x014084fb,
-       0x33b7550a, 0x8577e88e, 0xa5ed75b9, 0xcf97dc42, 0xdebfa2b7, 0xee8123f2,
-       0xffb2ffc1, 0xac3b34ad, 0x54f878df, 0x7697de1a, 0x86953a1f, 0x0cdb89f7,
-       0xcf68cdf6, 0x3dd07d03, 0x3f5e8ee4, 0xa87edfc1, 0xb79f1fb0, 0x140e0af7,
-       0xeb9eeec9, 0x364eb40d, 0xa3fd15b0, 0x3ae0517d, 0xabedce58, 0x2a76e5c3,
-       0x13982edd, 0xc98f7ef5, 0x1e9013e7, 0x5c213e40, 0x820fc047, 0xe66dbefa,
-       0xd4f648a6, 0x27df0565, 0xde1919b7, 0xfe836dfb, 0x59d38eb8, 0xbdf88da7,
-       0xb0c39685, 0x71d7012e, 0x1c7881ee, 0xa181837f, 0xf7c2a19d, 0x03e05671,
-       0xabfbff5c, 0x2dcf0c0d, 0x27ad596f, 0x81bfbf7c, 0x87fa27db, 0x0335bd7f,
-       0x2e80cbea, 0x270f3bf1, 0x9d38df56, 0xbfbee301, 0x7569db86, 0x2f881b0f,
-       0x6e13ad97, 0xa50e4bdd, 0xff6e956b, 0x70d3a146, 0xdba70dfa, 0xe6baf461,
-       0xdbebd1eb, 0x90ecb7e5, 0x61f7a819, 0x438ce7ff, 0x731efa3a, 0x1a7e401c,
-       0x0718613c, 0x2ada4f70, 0x63c3c039, 0xa7bef5d3, 0x9c6e50d2, 0x6df9ede0,
-       0x7f2e057b, 0x7d71cbec, 0x8646dd19, 0x2a2e08f7, 0xd95176fb, 0x0a0b3b37,
-       0x62cfc8f1, 0xa9ca1260, 0xf9ce256c, 0x1d35818a, 0xe452ff46, 0x8ffa67f2,
-       0x87b77b6d, 0x2b7fefd0, 0xcaab74e7, 0xe64669c5, 0xf7c56c3a, 0x045f8d0f,
-       0xe06cbce3, 0x282735e7, 0x09c94de3, 0x52822c36, 0xe4e5c157, 0xd438156f,
-       0x3e149ffa, 0x437f2760, 0xe6685cf8, 0xd1b79ff8, 0xf8eb8cdf, 0xbd75c999,
-       0x305fde1c, 0xea1b7ce1, 0x3f49eebd, 0xb9dfe3c9, 0xee1d9073, 0xa27ff056,
-       0x63cf37fc, 0x3532cfee, 0x72d7f68e, 0xe90969f4, 0x68a532d9, 0x30f148dc,
-       0xe66ccdf7, 0xbaba014a, 0x5aa54399, 0xaafc745f, 0x82fc8071, 0x2fc40deb,
-       0xb9e9d337, 0x0553efda, 0x8e46e9ee, 0x4a97d607, 0xb6e41b7a, 0x67921658,
-       0xfaa0f150, 0xfb2996e3, 0x5b1ebf69, 0xcfee28c7, 0x8f84d3d8, 0x84e76d15,
-       0x41e71856, 0x02b06c83, 0x3627cfbe, 0x8534bdad, 0x626c9fb1, 0x3a0b05cc,
-       0x5cccc9bb, 0x6c7d0377, 0xd81ea892, 0xbbfaa364, 0x5e54ec9b, 0xa2c738b6,
-       0xa4e079fe, 0xede20a67, 0x671ed644, 0xed73cc2d, 0x41f081ac, 0xfdf4063b,
-       0x376b4298, 0x0cccf4fa, 0x947a37ed, 0xf028adef, 0x8333743f, 0xfcbe40b9,
-       0x8e83e702, 0x467f1bed, 0xe6b1cf72, 0x49fa037a, 0xb7176df9, 0xf1bddd62,
-       0x5f680d77, 0x04fa007c, 0x7eec0ce9, 0x9e501366, 0x81da339c, 0xa66f9a0e,
-       0xeb2f38d0, 0x77c80d82, 0x430263de, 0xf7a0fcfa, 0xd71c71ba, 0xe12d7457,
-       0xe6744df9, 0x48ad2d9f, 0xfbb8fc22, 0x7f7c75f2, 0xf7a1748b, 0xf9effa29,
-       0x87ee0243, 0x9dfda379, 0x467fec4a, 0xb7af90cf, 0xa41306d7, 0x02f87208,
-       0xa3978b8c, 0x86581d70, 0xbd1937b7, 0x413cf053, 0xe1c74293, 0xfa158bed,
-       0x941b4c04, 0x213229ef, 0xc1239f8d, 0x5258169f, 0x41f93262, 0xe7e038fe,
-       0xabbabe96, 0x811e9622, 0xcff5a87d, 0x762187d8, 0xfc3a347c, 0x437e25b2,
-       0x4329c3e6, 0x4323f475, 0x1fa07fef, 0x82fbe919, 0xe3c9aca6, 0xb9778a46,
-       0x83bec007, 0xc300eafd, 0xf4829ec9, 0x4fca8d3e, 0x91d9748e, 0xc171cc7f,
-       0xd82fa83d, 0x3bf23a5d, 0x7b5abdda, 0x87e141a8, 0x7a1ec506, 0x3feb42b4,
-       0x5ed49f81, 0x84a4fdc1, 0x3fe34ce3, 0xff273f85, 0x057c8cc9, 0xfd834ef3,
-       0xfed22579, 0xc7aed554, 0x2ed8137e, 0x740673a2, 0xbe15f48e, 0xe0a8bfce,
-       0xebe5547a, 0x48d7c865, 0xaf9cbdbf, 0xa96dc7c3, 0x1c0bf9aa, 0x7b945b77,
-       0xf157f710, 0x139fdaf1, 0xe7ee5f08, 0x1f4f0852, 0xb59ce7b3, 0x031f9740,
-       0x2e80fb1c, 0xf19d39af, 0x9affd049, 0x6c9f19cb, 0x1d03921d, 0xbf53c5cf,
-       0xa717936d, 0x19fd42b4, 0xef187ba4, 0x8a3ade93, 0x1cf43e6f, 0xbe753fe7,
-       0x52cbfc0f, 0x0d8a9f90, 0xda03a341, 0x262efb33, 0x7c581da0, 0xe414fee4,
-       0x6e7068c3, 0xdce054ad, 0x4bdad8f8, 0xf01e9c29, 0x455aee1c, 0xf49fb9bf,
-       0x6bff111b, 0xdfa23237, 0xd97ed7fe, 0x49fc7c81, 0xfa84bc5f, 0xf1a3e3f0,
-       0xd7ff945e, 0x3a7c998e, 0x6f10fc81, 0x8fb5c822, 0x91f7030d, 0x2f4479bd,
-       0x3ee8ffa1, 0xc83ddbf6, 0x4cd7ee8f, 0xb5b1f968, 0x51d75d7d, 0xddf5b5ef,
-       0xf2c4557b, 0x87e5d1a5, 0xd38f8df6, 0x6ffad57a, 0x28ed9937, 0xb9113f47,
-       0xfbdb589c, 0x6bbfd92a, 0xc0cc6f07, 0x47c7ea38, 0xca094fff, 0x379bf735,
-       0xb99e504a, 0x8251b8df, 0xc71feeed, 0x2dd9227b, 0x84f4b371, 0x665f5557,
-       0xe26a27bf, 0xfa141b45, 0xd5dceec8, 0x57f00938, 0x03896e7c, 0x7b6ab6f3,
-       0x139d14f1, 0x79fe2fdf, 0x21c3ca7d, 0x22033afd, 0xce8a8de5, 0x0eafc7d5,
-       0xaa47cba1, 0x94ef9a0c, 0x0f38d57d, 0x2df7e2b6, 0x0275c56f, 0xec0efa3a,
-       0xbfc880b6, 0xf046bb2f, 0xf601bfa1, 0xb23f784b, 0x923daea7, 0x9910f742,
-       0xbd3f9ce8, 0x1c53eb08, 0x5628eddb, 0x8726a7cc, 0x02cb4bd8, 0xe809bf3a,
-       0xe4cfa9a8, 0x203f7b27, 0x62baa45e, 0xfd743d47, 0x85b26337, 0xdc9a7108,
-       0x1ca0e777, 0xc0d78f0f, 0x5b8418cf, 0xa7ceafb5, 0xa651f8f3, 0x042dd247,
-       0x993b9ab8, 0x161d7884, 0x4b9a69d7, 0xf8f0a2f1, 0xdbb03d8e, 0x93ecfd8c,
-       0xabc21275, 0x8fb8a5da, 0xc0e4113d, 0x7972565f, 0x6757f2a6, 0x3af5e780,
-       0xc9e6b503, 0x69577e50, 0xcc7491ef, 0xece9780b, 0xc600ffbb, 0x1f073a17,
-       0xf30e9f8c, 0x98b7be74, 0x9ae79e61, 0x829e6b54, 0x9ae706fd, 0xa21bc81f,
-       0x1af9f09b, 0x345db92a, 0xd6442f64, 0x5f0aa57f, 0x2c1e968f, 0xd0f3fcac,
-       0x579fe083, 0x7cff7254, 0x709f8f05, 0x7f5c3cff, 0x1d5972a8, 0xef82ad77,
-       0x2af972e1, 0x47e039d9, 0x5b5e5c93, 0x32f7a769, 0x90a516fb, 0x92defd7f,
-       0xf875bb14, 0x43a239f8, 0x7c379c97, 0x739ed57c, 0x6653e57b, 0x3d647bf4,
-       0x897ba7f1, 0x97fcc3e0, 0x9db9ff6a, 0xeee5d902, 0xdf0f8366, 0x2c0ae153,
-       0x07d8f1e1, 0x22cf8364, 0xaa89d90c, 0xddab791d, 0x6abb5021, 0x63f6aa57,
-       0xbbe3c9c0, 0xfb788a4b, 0x556b8b65, 0xa75c58e5, 0x97179e85, 0x398ce7f3,
-       0xf55fa14f, 0x918152e0, 0x4aec501c, 0xedc34e95, 0x72fb4fce, 0x438a4712,
-       0xa7d0af3d, 0xc21367ca, 0x63d543f8, 0x7e7054cf, 0x5e3d40eb, 0xf7fc7a88,
-       0x7c3cfb1a, 0x8fe3d05c, 0x463f5257, 0x2e7e8bfd, 0xebf9233a, 0xadfc6566,
-       0x4e05feea, 0x59bc20d6, 0xfd19b02c, 0xf5fa68cc, 0x139d8a7b, 0xc519fdad,
-       0x3f1dbc7e, 0xc8e4561f, 0xcbf3f168, 0x70f2b795, 0xf9f9a9ff, 0x8c687d96,
-       0xd557bf62, 0x1ffb86bc, 0x6a04f7a7, 0x97feff90, 0xe1eee281, 0xfaa53def,
-       0xecd3229f, 0xa32ca9cf, 0xf723fd0e, 0xe83f1e1a, 0x43bfb24e, 0x7a5bcc7e,
-       0x05ace386, 0xb8ed107f, 0x51266f47, 0x32f686d9, 0x385e2b94, 0x1588f947,
-       0x77f0b46b, 0xfb174c63, 0xf3a6cbaf, 0x9eac2d03, 0x7d2d4ce2, 0x5016d249,
-       0x0f63dd0a, 0xf2be469d, 0x0fdbd01e, 0x88ffbe84, 0xc799befa, 0xfba636e1,
-       0x661af728, 0xc278b40f, 0x7dad7eed, 0x8dc4a950, 0x6f09d9a2, 0x5cb85bf4,
-       0x3e27a339, 0xd378c0ef, 0x7d8cc64c, 0x37b82e5c, 0x474938f2, 0xfc04e6df,
-       0xd2bb6a08, 0x500c457e, 0x6bf28a1c, 0xbed5eaf0, 0x3ee8d3a7, 0x27cdac97,
-       0x39ffefb5, 0xbcf0cbc9, 0x970f7252, 0xbd36ee4b, 0xa12a4792, 0x83b797ef,
-       0xed0e393f, 0x1bfdbb4b, 0x8b807788, 0xc8de48f9, 0x3ecbb89a, 0xe9f4af25,
-       0x3f257f99, 0x2891c574, 0x79eea479, 0x7ca48f3c, 0x1e787727, 0x0ca9f4e9,
-       0x48f3edfb, 0xe8e7bd1d, 0xf2edcb1e, 0x5baaa649, 0x3b8a1c71, 0x7c79144e,
-       0x209f6277, 0x626abc61, 0xe9775f1f, 0xafb238b6, 0x3ab57e1b, 0xba81e505,
-       0xe22c9f4f, 0xfde4fdf8, 0x5fb06acf, 0xc944afc9, 0xe37aeb02, 0xcb3f0dfd,
-       0xd9bb75e0, 0xc436fd8e, 0xc9f33fa3, 0x23c7d6af, 0x1280df7e, 0x17c7e7f7,
-       0xc9f1c8c4, 0x667578a1, 0x959dc515, 0xfa08b578, 0x5c50cc70, 0x8bdfbc27,
-       0x746e5c55, 0x7142bb83, 0xef3c23cd, 0x9aee9ddf, 0x9ebff547, 0x29dff8c4,
-       0xfd1e2990, 0xc635d02a, 0x62c1a68d, 0x3ffd2f31, 0xe62758e3, 0xbac7ba91,
-       0xf47c427e, 0xf23b3ad7, 0xfca7f411, 0x9db0f793, 0x6a8623f4, 0x0333cf31,
-       0xf7405b3f, 0xdf295231, 0x8fb28f73, 0xa2cfe0e9, 0x2cd0095f, 0x34f43cc1,
-       0x2333df25, 0xfe38898e, 0xfb6b830e, 0xf52fcc54, 0xc4cd8e8b, 0x3c148e04,
-       0x779e196f, 0x2f9e6412, 0x6a4ff357, 0xfe5a3cde, 0x9479c049, 0xf3f056ef,
-       0xf980b296, 0xc4cf3574, 0xf9293a96, 0x43cca5b5, 0x807c42f7, 0xde73afb3,
-       0xcffc846b, 0xf21115c3, 0x982beb3f, 0xf3699f62, 0x5f73db8d, 0xaafd3a21,
-       0x78c3c679, 0xe68ee2ae, 0x0fdcecc5, 0x28bb830d, 0xf234d3e9, 0x6ff8febb,
-       0xfb67a409, 0xbc3e906e, 0x00b13416, 0x78071fc5, 0x40cfbddc, 0xe06b8671,
-       0xd10d8dbf, 0xf054efb3, 0xd5f78f71, 0x04f7fd11, 0xfdf1e3ea, 0xb7cf2bdf,
-       0x7ee4b7bd, 0x01bdf7b4, 0xc60b1dfe, 0x13d63fb8, 0x6ed18b10, 0xf2fb83b9,
-       0xf5846564, 0x7eb8e399, 0x52a3e70a, 0xab4aff85, 0xdeeb9e38, 0x7b987ee7,
-       0x48afcf03, 0x7b705c8a, 0x74fd5e78, 0xc6a09a56, 0xca45c7d3, 0x92091cbf,
-       0x447968de, 0x7cc9efa0, 0x33cbfcd9, 0xf1f391e9, 0x462f7a2b, 0x3634bfce,
-       0x168cfc90, 0x638f0ecf, 0xff2a9dff, 0x7638f3a6, 0xeb44957a, 0xd7e4f64e,
-       0xeb43638c, 0xb0fb83bf, 0x7d845674, 0x6fe383b8, 0xf1db1d9c, 0x3b63caeb,
-       0x1e3113fe, 0xc78c7b7f, 0x6c7961ff, 0x8abaebf3, 0xdbffc2d8, 0x1fdfc318,
-       0x57fffe09, 0xe78407cf, 0x0bcfc3ff, 0x30039f84, 0x17b0f5bd, 0x9d84badb,
-       0xefc33f41, 0x24d6bf8d, 0x93141c80, 0xce7dd3f6, 0x1f3ce505, 0xecdeadb6,
-       0x9d0c2bdb, 0xf5f1501b, 0x23f73568, 0x5eebbca5, 0x04d45efc, 0x829f5039,
-       0xfe72b2f1, 0x59ae4377, 0x898c5e78, 0xc9e63a52, 0xc5f4cde0, 0x5b749760,
-       0x5359e722, 0xe9a2f195, 0x35d58391, 0xe315678b, 0x7c8a3d1f, 0x4a87ff0e,
-       0xe5ea521c, 0x6899e9f7, 0xf34c5f4f, 0x1ed1d3da, 0x9fc93c4a, 0xbc99f827,
-       0x67b2e097, 0xdc7fe62f, 0x7be11b20, 0x26ffc946, 0x1b2bbbcf, 0x60c9d2e3,
-       0xf05e6217, 0x920fcc69, 0x7bd12b3f, 0x66977cea, 0x19ea3f71, 0x9f301303,
-       0xcfca9deb, 0xdf9eb139, 0xe6a6fd91, 0xfc1acef5, 0xca055a97, 0xfc23b5eb,
-       0xf3f9d53f, 0x442b65f6, 0xebcdf80c, 0xf8df2891, 0xe5dff976, 0x9e1e68ba,
-       0xe24c7be7, 0xbf409caf, 0xec78e019, 0xefd12168, 0xffe5e38a, 0xc7fe8cd4,
-       0x3cf09164, 0xe254afcc, 0x78941705, 0x502f1a87, 0xacff5bf3, 0xc03e49c4,
-       0x03940bf8, 0x72810f18, 0x9ddd2cfb, 0x67db4fd6, 0x67ffe045, 0xf21f1e04,
-       0x87c794fe, 0x9c8e8d0a, 0x7f94f3d0, 0x63ef8b35, 0x2fe79fab, 0x0fcf78d4,
-       0x7e14f595, 0xefc7ef4f, 0x9d6e15a1, 0x5f3d446e, 0x0e2b35b8, 0x4fb219cb,
-       0x5ef80697, 0x4eb0fab6, 0x7448bfdd, 0xe75957b4, 0xca4133b6, 0x961abdef,
-       0x8b34bff7, 0xa968679f, 0x097bfbe6, 0xd418a0ff, 0x6e229b1f, 0xb131f341,
-       0xca47d24a, 0x5f80b52b, 0x76b6708c, 0x7c55b873, 0x75edf8b7, 0x53c5cf38,
-       0x1658adc1, 0xa3aec9ac, 0xf5db7bb8, 0xb9bf68ad, 0xae9c6f07, 0xd19978a6,
-       0x43c4fe8e, 0xdbb8da03, 0xfe3cd513, 0xe01a2afe, 0x457bb788, 0xef0b8ff2,
-       0x927e8915, 0xbfe42c5b, 0xde981b26, 0xdc45f58a, 0x4c682a2e, 0x5b3ac3ad,
-       0x60f64492, 0xd27b19c1, 0x714379c3, 0x377be4b0, 0xdd3c458c, 0xc6aacf2e,
-       0xe45b2ed3, 0x5f9fb8e3, 0x7edacf35, 0x6f3a3df6, 0xc54baeaa, 0x8d2f9a8b,
-       0xcf556796, 0x3f1bb83d, 0x70d39cd3, 0x8c06c18b, 0xbd1e163f, 0x5fce5468,
-       0xa1ecb64a, 0x91e16c3c, 0x557f94eb, 0xcf6eadf3, 0xa1abb275, 0xf7fb119f,
-       0xd7f9e26c, 0x2c0e00d7, 0xb2dd617b, 0xdba1ef09, 0x7583eca8, 0x9b63f3e3,
-       0x6ff4a972, 0x7c795072, 0xf8951953, 0x64f4c999, 0xa75edbcc, 0x59d5edbc,
-       0x524dcec3, 0xe8b76f5e, 0x15f108fc, 0x7aa3f792, 0x1f4fde78, 0xee35e3c7,
-       0xbefa0633, 0x99acfba1, 0x5f4d77e4, 0x0ff444eb, 0x9ae73f3e, 0x60777088,
-       0x2e842dde, 0x961d913e, 0x9d83f424, 0xdbe60b0e, 0x1aaffb0a, 0x874c3cf1,
-       0x3c623018, 0xc0cf200c, 0x9eee8b23, 0x6fdcfceb, 0xf1058d5f, 0x58fcdb7b,
-       0x8fcfffef, 0x58fc957d, 0x273f3577, 0x0291caad, 0x8bde4ea7, 0xf2d919e5,
-       0xd89c8870, 0x94f9e4e6, 0x1127936d, 0x4e76ee1f, 0x321d5a4a, 0x8f23675e,
-       0x3bdf245f, 0xfcfa12d9, 0x1f3cd597, 0x67302c96, 0x33567924, 0xc7ddebfb,
-       0xd76e411b, 0x3ffbb244, 0xe5d029f9, 0x238ba04c, 0x90389edf, 0x343f19c7,
-       0x71adb71e, 0x2831c4f5, 0xd8982e9f, 0xd3af1e14, 0x5858e3c4, 0x5c5a2e5e,
-       0x4ea3456e, 0xa179d0b6, 0xdbd404e0, 0x2633f1e1, 0xbd702706, 0xbde0672e,
-       0x83319814, 0xf961b195, 0xdf305fb9, 0xfbc327cf, 0xa4751acb, 0x5d3cd42f,
-       0x36c8a341, 0x6c167d01, 0x3f28f834, 0xa45e28d7, 0xec6fc576, 0x90320a94,
-       0x6b383fce, 0x16ae3094, 0x34731f1e, 0x049eefee, 0x026d1dfd, 0x5dba0bdd,
-       0x073d4f1e, 0x3fdbd2de, 0xf96de307, 0x3d77576c, 0xac9fcff4, 0xf4fcf093,
-       0x3f1e7cf0, 0xd8a05dff, 0x3671e139, 0x4bb433a4, 0x1bf0e3c2, 0x38d83a15,
-       0xd7adeb9b, 0x1d537f14, 0x4e17ed47, 0xcd9d3f3f, 0xb8b46df5, 0xbc6551fe,
-       0x6d82c6ce, 0x177f7193, 0x93ea18e8, 0xf35ac6ce, 0x76f190e4, 0xdbe7e6cc,
-       0x60fcc19e, 0x907e686a, 0xf3c301e7, 0x2b9caa82, 0x037dffec, 0xc8377be2,
-       0x6e63d46b, 0x141fcf1b, 0x8339ab1e, 0x4e086372, 0xc377b7ae, 0xbec8079e,
-       0xbe312473, 0x457bfa2e, 0xc502a3de, 0x7c160ae7, 0xea1e3c76, 0xf74499cc,
-       0x2767dcb0, 0x3ca2b16f, 0xe316205a, 0x53b71ebd, 0xc26795b8, 0xeffdd27c,
-       0xbcefa1ac, 0x7f903e16, 0x81e5f70e, 0x0f9d0366, 0xfddef554, 0xf03534ef,
-       0xc64fbdf6, 0xe0ae7b61, 0x79f1d8b0, 0x763f7d23, 0xfa7e4bfe, 0x110b58bb,
-       0x81e7903a, 0xe44497b3, 0xd716cb9b, 0x151f23df, 0x4cf2522e, 0x3f4f5ccd,
-       0xc0c8b7d0, 0xead3cec8, 0x9f5913cd, 0x46e83c53, 0x8fe5215f, 0x43fcf052,
-       0x29be90de, 0x6c7a0a3c, 0x63d39dcc, 0x112d9d3f, 0x1e82673e, 0x17927843,
-       0xf87d3cf1, 0xf650effe, 0x8a5e9a3f, 0xff518726, 0xde63fbf0, 0x5c36c10c,
-       0xee31db8f, 0x3af68a53, 0xd3a2e394, 0x71661fdf, 0x628a4eba, 0xa149fdcf,
-       0xa7e7a8df, 0xcf27477a, 0x7fd987f4, 0xd563791e, 0x4df352ff, 0xa0f6bfaa,
-       0x65ab0f62, 0xbbfe5293, 0x72a037ef, 0x21bf788d, 0x86fdf239, 0x68090e87,
-       0x1bf7a8a7, 0xcd59194e, 0x4f3c54e1, 0xf277dcab, 0xe93b222d, 0x62fcdfd4,
-       0x78a98beb, 0x509049df, 0x3a1fb51d, 0x1dbe7a47, 0xa7b223ec, 0xe3cb7efa,
-       0xf9f887ad, 0xc8def6f0, 0xaddbdddf, 0x32f5dfd8, 0xaed1b923, 0xe86db79c,
-       0xb744f251, 0x8b8f96e2, 0xb74b71a1, 0x3d56303d, 0x7f23ebc7, 0x8cc71b4f,
-       0x60ecb716, 0xdbb73a41, 0xa07046b1, 0x39ddb87e, 0x79ca5ddc, 0x4c71a8dd,
-       0xb973e479, 0xb94c71e1, 0xb9c79b5a, 0xf7c4966f, 0x680825db, 0xce759aef,
-       0x7fb73a36, 0x9d22904c, 0xcd5a5ef3, 0x257cf4e5, 0xc8d0720f, 0x8560e3e9,
-       0xf06ff740, 0xfbee1e1e, 0x1efc63c1, 0x7e02c1ce, 0x7bcd470f, 0xa66bf7a8,
-       0xe83de50e, 0x2f7a9dfe, 0xc367bd47, 0x5ae08f98, 0x7d1c5cf4, 0xe1876bc7,
-       0xbddb8d90, 0x1a3f7e5e, 0x43e61065, 0x8913cc4d, 0x6bab6b5f, 0xef7a6ac4,
-       0x8f4fdb8e, 0x7bf04754, 0xe91f8a7d, 0x2fea8eae, 0xfad6afac, 0xf70f540b,
-       0xde54ee17, 0xecd98be3, 0x87fbfb4e, 0x9e8f1c63, 0xf1b63b32, 0xfb48ecc4,
-       0xfda2c5b6, 0x5e5aaf1e, 0xb0dfe456, 0xbb0dc5ef, 0x7af5c92f, 0xa7ff60b7,
-       0x1ba7ca4a, 0xcaae9f28, 0x7c31eed5, 0xe3291ffc, 0x294065a9, 0xd77ca3bb,
-       0xbc4a97f9, 0x7b944bac, 0x2f69ee10, 0xd397e368, 0x97e3690f, 0x35937b33,
-       0x78ff7cf5, 0x6785fbcd, 0x8bda6926, 0xda68f703, 0x68142f4b, 0x1503e5ea,
-       0xaf2bf79a, 0xb3ea6ad4, 0x65f8da82, 0x61c5cdf5, 0xb47d38f7, 0xdca01abe,
-       0xe6757ed0, 0xcbde6a6f, 0x575da358, 0xaebb4796, 0xebb51b89, 0xf6cdc752,
-       0xd397d76a, 0x325f5dad, 0xbef2e3e6, 0x7f2e3e7e, 0xc7c95db6, 0xdfb058e5,
-       0x2d938d33, 0xf7a9b768, 0xfef7d5a9, 0x5866372f, 0x007f40df, 0x00000000
-};
-
-static const u32 csem_int_table_data_e1h[] = {
-       0x00088b1f, 0x00000000, 0xe4b3ff00, 0x51f86066, 0xb97bc10f, 0x726e1818,
-       0x0143f821, 0xd08667cf, 0x0c0c2c6a, 0xc6cc401a, 0xcec0c0c4, 0x717ebc44,
-       0x1d7b044e, 0x4cc30307, 0x31c8de20, 0x481afef0, 0x7e879d7c, 0x42f3a976,
-       0x81c15968, 0x570837f7, 0xb430310a, 0xc430330a, 0x0cf84088, 0x55f2a8a2,
-       0xa9b60842, 0x39766524, 0x0003f502, 0x3471cc24, 0x00000380
-};
-
-static const u32 csem_pram_data_e1h[] = {
-       0x00088b1f, 0x00000000, 0x7de5ff00, 0xd554780b, 0x733ef0b5, 0x7993331e,
-       0x0f20f264, 0x0084f102, 0x021842a2, 0x27088784, 0x01a8c421, 0x54bc8083,
-       0x48433c26, 0xbfa81132, 0x2677bd6d, 0xb5ad1104, 0xbc1b6951, 0x14101de8,
-       0xd1a07515, 0x40e81c06, 0xdbdab114, 0xd5a8f8a8, 0x40445076, 0x8bcbc248,
-       0xaf7fd52d, 0xe649cfb5, 0xd4484c9c, 0xffffbff6, 0xdbf3f1fd, 0xd9cfb3ec,
-       0xdaf5ed7b, 0xf6bdad6b, 0x9a32c11e, 0xe4224e24, 0x65a3f85b, 0xf4842784,
-       0x0adb2ce9, 0x64918fda, 0x8b2ffc42, 0x108e36f2, 0xf08e77ee, 0xbc8451a4,
-       0x980b99b5, 0xcfbc3d69, 0x9fad0846, 0x603d34de, 0xff6422ce, 0xef02b308,
-       0x8f9ade9f, 0xbd2fc9f5, 0x7b6814e7, 0x00bc4bd5, 0x13bed375, 0x109d88ce,
-       0xa1e5b9af, 0xf6f3e96b, 0x85b27897, 0x93fc450e, 0x9085244d, 0xfec21663,
-       0x52fab22e, 0x6d56ab2b, 0xf4077fde, 0x2664de5b, 0xd54fda56, 0xaed365ee,
-       0x8765f5a5, 0x54af0244, 0xfa95ab6d, 0x00f2fad2, 0x9afa8417, 0x71c67f7d,
-       0x79480ada, 0x27212870, 0x5f22167d, 0x96ceeb49, 0x79f45994, 0x11676045,
-       0x83b15fbc, 0xfbe89b73, 0x7ff69b15, 0x3457fd0c, 0xda79038a, 0x36ed8aff,
-       0x63610f22, 0x1e604b7f, 0xbc01a64b, 0xc4886f55, 0x97e5eb4c, 0x70044956,
-       0xa54bd424, 0x61ff180e, 0x38c07649, 0x0d1c7087, 0xd0cf559f, 0xd577e871,
-       0x986e702f, 0x7889b55a, 0xddd69e00, 0xda4f39d6, 0xd2b55e61, 0xf77ef860,
-       0xb7bc127d, 0xb2f6502c, 0x36f80655, 0xe700454b, 0xd2d2cda6, 0xadfd9da1,
-       0x0ea6fed8, 0xd90d63ae, 0x76a89ea9, 0x47d27963, 0xacee6c88, 0x04a21057,
-       0x407700ed, 0xf3ac3e9a, 0x812e79f9, 0x3fd0d190, 0x674b644f, 0xc83094ff,
-       0xe8f7fe07, 0xf60f813f, 0xb2db023a, 0xd2b5e93a, 0x772dff45, 0x4bacebd2,
-       0x9ed09fa5, 0x56bfdd17, 0xa074043e, 0x5cfbd4f0, 0x4be23e58, 0x4f8372c3,
-       0xcafdbc46, 0x06cb0437, 0x3f9f1b9f, 0xe58b1be6, 0xe5829f26, 0x2c62be13,
-       0x7c52be03, 0x0e6f8b6f, 0x1e7d5b96, 0xaf94fe7c, 0xbeedcb1c, 0xacfe7c1a,
-       0x772c6eef, 0xfcf8fcf8, 0x2c7adf05, 0x2c7abe83, 0xb01af977, 0xf005f46c,
-       0xdb7d97bd, 0x05f26cb1, 0x5f1ef9f1, 0x5f219613, 0x407dcb18, 0x7d865a5f,
-       0xf01e582d, 0xabe5887d, 0x777e08be, 0xcb1c77d0, 0x3bbc5507, 0x817c9027,
-       0x10a9cde2, 0x92171517, 0x8be4a258, 0xca589eb4, 0xf9b729ea, 0x4f5a25f3,
-       0xc53ad0f1, 0x70cadf63, 0xfbd699be, 0xccf6b0d6, 0x8581487b, 0xacfd33d6,
-       0x4a83c07d, 0x07d69581, 0xc1f6b3d4, 0x7105fc9b, 0xc0383eb4, 0x11deafda,
-       0xfad1b02e, 0x9ed641d5, 0xed932213, 0x66139eb4, 0x94b7dcf5, 0xcf5a0ec9,
-       0xbcf5616d, 0x9d93fd8f, 0x61179eb4, 0x153f8fdf, 0xeb4f1c9e, 0xfb59dbe3,
-       0xd0a44bc4, 0x0913eb45, 0x7b02f587, 0xad02617e, 0xbd58b817, 0x20995fa8,
-       0x7dbfe0c7, 0xa1116462, 0x7fddb0bc, 0xd3a422b3, 0x455914ba, 0xfe9f14dc,
-       0x8b0f5839, 0xbfb43164, 0x84532fe5, 0x912eb471, 0x17fed0d5, 0x1fb6057f,
-       0x6f6c6510, 0xf6c2aff7, 0xed8c9203, 0xb07bdaa6, 0x60a8aafe, 0xbded727b,
-       0x92abfef8, 0x6b83ed82, 0x41fac21f, 0x63ed83d1, 0xef8d7f6b, 0xd83c941f,
-       0x80dac8fe, 0xffeb4852, 0x00b679c1, 0x9e71d75f, 0xfc0d9272, 0xa52b4c1a,
-       0x238ebafc, 0x1e3e4073, 0xf2a6a600, 0x525d2eb0, 0xfbedbf40, 0x3c93de47,
-       0x3276f2a7, 0xf53e97d4, 0xf3f61640, 0xd223f61c, 0xfb9ef87e, 0x58cdf899,
-       0xbf133f5d, 0x69fad729, 0xaceaf784, 0xdf67ebbd, 0xf0f5e337, 0xf5a1537c,
-       0x71fb17b3, 0x135e6ef4, 0x87a09dbf, 0xad4adbe7, 0x4fd8839f, 0x09e0ef42,
-       0xfd74638b, 0x5a65c584, 0x7ec47f3f, 0x1e0ef4fa, 0xeba71a45, 0x6b969147,
-       0xfd887cfd, 0x9faef7a4, 0x1ead74b0, 0xd685691e, 0xa7ec11cf, 0xa5e6ef7f,
-       0xc3d3af98, 0xfad2ae63, 0xcf748939, 0x073f5dea, 0x1cfc7a1c, 0xe7e07470,
-       0xa833c21c, 0x702af377, 0xe053f1ea, 0x25cfc0ec, 0xdeaae7ec, 0xa9c073f5,
-       0x6701cfc7, 0x0e447e07, 0x77ac35e6, 0xd7882af3, 0xbe20a7e3, 0x0e4e3f03,
-       0x3bd119e0, 0xa3ed5e78, 0x7dabcfc7, 0x8a93f03a, 0x1dee8cf0, 0x7a29853c,
-       0x74a614fc, 0x784647e0, 0x9faef5c6, 0xf8f45357, 0x03a53579, 0x3f61573f,
-       0x5e6ef5d7, 0xfc7aa985, 0xe076a614, 0xc9fb1727, 0x78476cf7, 0xd1c7ed08,
-       0xfb073f7d, 0xb073f1eb, 0xae7e077f, 0xd0a67ec5, 0xee7bb27e, 0x8f5328a7,
-       0x0ecca29f, 0x9e2214fc, 0x3f5de86f, 0xf8f53307, 0x81d99839, 0xcfd8a99f,
-       0xabcdded4, 0x7e3d0ae8, 0xf860ae8a, 0xc08c2499, 0x9dae8675, 0x727e9e6e,
-       0x857cbf7d, 0x2ef3efa3, 0x6e5de756, 0xaf0f7602, 0x45a433d9, 0xf6fbe9e1,
-       0x0fb9091d, 0xa6bb6890, 0x8fc076e0, 0xd1795a83, 0xd8fc4d76, 0x951d9d38,
-       0xeaea24a0, 0x757dc549, 0x1d29f7ef, 0x9d4f6ba0, 0x3daeb573, 0xabab93dd,
-       0xd78f9467, 0xa6bfdfbd, 0xe2bf5740, 0xef751bee, 0xd16ff967, 0xcfd7b3d5,
-       0xa83fbdd3, 0xfdaea17e, 0x5d0a86ca, 0x958155fb, 0xdb35faba, 0x7f7ba27f,
-       0xae8d7058, 0x03d3787d, 0xe111f6ba, 0x91f57447, 0xbdd31e87, 0x8b65ba3f,
-       0x87cc7dae, 0xc7daeacf, 0xeae97645, 0xa3df1ed7, 0xf6baff7b, 0xa4faba03,
-       0xbdd7bf8b, 0xd5de4f9f, 0x3f96dbdb, 0xe29fdeeb, 0x7ed74cfa, 0x0697da7d,
-       0x3aeed53b, 0xe75a8d76, 0xfa08ae41, 0x0974fe25, 0x43b0d5ed, 0xd7d4bac2,
-       0xc714fcce, 0xe528f952, 0x22c0e91f, 0x92f91939, 0x21bb51fe, 0x95f96fbf,
-       0xaefcfa11, 0x5d2b9ef1, 0x925df9f4, 0x862bb867, 0x8df9437d, 0xca506923,
-       0xed8d2826, 0xdf8c89f7, 0x0d2e320b, 0xf7bf423e, 0x2707da9a, 0x3e70fad0,
-       0xf1f2083f, 0xbb426732, 0x35278e3a, 0x999c5ef0, 0x5f74dfa0, 0xfe93de56,
-       0xdf587928, 0x5c19da9f, 0x45ebbf67, 0x51da1a4f, 0xc1f89fb5, 0x9fd759ce,
-       0x212fabce, 0x849f70af, 0xf7e903fd, 0x79a697fd, 0x89667f68, 0xe3d119fa,
-       0xa1fc744b, 0xe4187e38, 0x3f8c20e1, 0xe6f8ebba, 0xe3756301, 0x75cb325b,
-       0x3a245be3, 0xdf908bbe, 0x8eae7ed7, 0x9e30894f, 0xcfb93790, 0x66737c71,
-       0x9f7f8e39, 0xe8aefd44, 0xc63ae3f1, 0xbff9816f, 0x07fcdddf, 0x3fcfd78c,
-       0x7f3f42b3, 0xa3ffcd89, 0xf8ead3da, 0x3fff3871, 0xfcd9a773, 0xfcd82b33,
-       0x8edfaccd, 0xf81d9df1, 0xc7f8c08f, 0x9cdf19ba, 0xff3f413d, 0xf3f52a2b,
-       0x4ff1b337, 0xc7505ed6, 0x5ff8e3b7, 0xfcd81772, 0xf1c4a8af, 0x0dc7b325,
-       0xc46523fc, 0xf8e804d5, 0x7c551fa4, 0x742ec0a9, 0x2487281c, 0x6421a152,
-       0xe100371b, 0xf18e2bb8, 0x947157db, 0xf99f50df, 0x500939f1, 0xfd4799cd,
-       0x57d79546, 0x4097c8ec, 0xf53b61ef, 0xa0a896b7, 0x91e26e2e, 0x7306c9bf,
-       0xb7851060, 0x43f789b5, 0xeb86f17d, 0xbd5fa002, 0x14a0b266, 0x184813be,
-       0xcbfe7f9e, 0xe7a25b61, 0xd4972c65, 0x5122c78b, 0x07e1d6f2, 0x35219016,
-       0xc029be14, 0xeb3ba304, 0x0e3f529f, 0xa98fe31c, 0xffa843df, 0xc6c899f3,
-       0xf7f50bfb, 0xfea11ea0, 0xa4ce3a1e, 0xdda3bf16, 0xf0a34e1d, 0x7ff0aa97,
-       0xfd79302a, 0xe02e36f4, 0xd5f9f2a7, 0x7fa0478f, 0x1b6ee0bd, 0x1c277a45,
-       0x5d24fe65, 0x0fcbce9d, 0x6ddf6a74, 0x10e16c0e, 0x6be032bf, 0x21268a3a,
-       0x5067d68b, 0xffbe775c, 0x07a9bec1, 0xb7212739, 0xa54c4512, 0x9abedfef,
-       0xe3a2efeb, 0xb9cc52ce, 0x32521d6c, 0x24d7284c, 0x909634c3, 0x88471a5b,
-       0x5d3207b4, 0x448d3f11, 0x58a33b8d, 0xaa559f5f, 0x8a8ab7af, 0xb570a268,
-       0x66c8e74e, 0x39ecefda, 0x9c6d76fa, 0x4644a681, 0x52bc7567, 0xfa74938a,
-       0xb9943668, 0x7485d8f0, 0xdf62e39e, 0x1778f06a, 0x7e8c2489, 0x010fbfbc,
-       0xf193faba, 0x362e79bd, 0x73bc236f, 0x4a528b44, 0x8ca739e7, 0x1b7f000f,
-       0x9f68ffe1, 0xd0e5314d, 0x22a3fd72, 0x8f9d7531, 0x1eb9fe11, 0x22827ce3,
-       0xcbf3f3ac, 0xdf19cf8d, 0xffe9531c, 0x2d07f029, 0xa0fe00bf, 0xf9551ff0,
-       0x32af53a3, 0x3d9af0fe, 0xda1f80d3, 0xe904f237, 0xadcbf2aa, 0xa92cbf2a,
-       0x2105f3d7, 0xb8e8111e, 0xfb970e6c, 0xcc1f1440, 0x5960f956, 0x6e6f9e83,
-       0x3d317e27, 0x6ee65d06, 0x9a6f7cd8, 0x9f7e75dc, 0xff337ca8, 0x9f88fdc1,
-       0x7464f3ae, 0xd3a543ba, 0xf6fa35ed, 0xdeba555b, 0x4e75d2ae, 0x51afc3c3,
-       0xc9e641f5, 0xdde41101, 0x9e8d53fb, 0x3d3d1d11, 0x708d3d2a, 0xf3d2a1de,
-       0x7a331f8e, 0xa88de11a, 0x9c348cf4, 0xae80c913, 0x5be11af0, 0xf9977770,
-       0xccab5c60, 0xde9e9b1f, 0x4755fca6, 0x05579ea3, 0x3475586f, 0x6c56ce4a,
-       0x2fabae9f, 0xbdd5cc0f, 0x4ca1acbf, 0x7ea4bed7, 0xd17daeb9, 0xf5753bfa,
-       0x758fff32, 0xbbb82fef, 0x7b7ed756, 0xf6bafdcd, 0xeb0fe5f9, 0x1b3d73ea,
-       0x9ecfef75, 0x3ed759b3, 0x5d19f4ab, 0x9de28cfb, 0x6574faba, 0xd37deeb7,
-       0x066eabbe, 0x3deb7cfe, 0x713d809e, 0xc605fdc1, 0x45b82f33, 0xd473bc37,
-       0x1f5f2327, 0xf2c10df3, 0x7c8dcfb8, 0x1637d27f, 0x66a6d6cb, 0x7413ac3b,
-       0x124a5c5d, 0xcd326908, 0x0fdf5dab, 0xeb8269d6, 0xa9e4c869, 0xb37ad3f5,
-       0x28794649, 0x78489069, 0x2c1c2124, 0xed1c2a36, 0xa47b547c, 0xaa06f687,
-       0xb6ba93f8, 0x3f624497, 0x76523ef7, 0x7765f005, 0xcbfd03eb, 0x4da7bb00,
-       0xed8debb5, 0x8d291c95, 0x1ac84e7e, 0x626ac384, 0xc4a54776, 0x5772bfe4,
-       0x4271017a, 0xe6b83c3d, 0x2905e372, 0x9f02a793, 0x78e4eb64, 0x3a35c359,
-       0x9a204efd, 0x6df807dc, 0x8af9eea4, 0xbeead7ed, 0x479fb53b, 0x5741abb8,
-       0xb165838c, 0xe81333f4, 0xe67370e1, 0xa700618c, 0x4deb1472, 0x3c2ed07d,
-       0x755e2be5, 0xafd01074, 0xbee3cb14, 0xf31e5839, 0xea3cb079, 0x53f2c72b,
-       0x11960d5f, 0xfe58dddf, 0xf2c7e7c5, 0x2c7adf63, 0x63d5f23f, 0x01afa1f9,
-       0x017df7cb, 0xb6fb0f2c, 0x2f8ef963, 0xaf8b6588, 0x9f56cb09, 0x7726a582,
-       0x71ddf13d, 0x093e1d75, 0xcf8317fc, 0xed7f3aa4, 0x7c9d09fa, 0x87dfc716,
-       0xb9e1a67c, 0xf2acc1a4, 0x1f8e8a43, 0x4397c012, 0xbda1eb3e, 0xb0f95441,
-       0xb763efbb, 0x6bfcb77b, 0x0fea6df8, 0x7e4eb7e4, 0x53f030ca, 0x34fc4f76,
-       0xa7e28f8c, 0xb31726a9, 0xfa7e547b, 0x8623cc19, 0x8c0f315f, 0xf6513e90,
-       0x826f929a, 0xbaa56c75, 0x601f420f, 0x763aacfd, 0x05b77d1d, 0x10c0baed,
-       0x0ece3758, 0xd860dbf9, 0x21fb3847, 0xf7567e25, 0x49f233f3, 0xd05778f7,
-       0xa01a59bf, 0xdaea4f44, 0x78638d6e, 0x31489ab5, 0xfddaeba1, 0x2f729e83,
-       0x81758a1c, 0x01f7c224, 0x8c4774f7, 0x0cada97e, 0xaf09edf8, 0x72af8e75,
-       0x8f63bfa0, 0xca0f3dfd, 0x2f6626a9, 0x68f335c7, 0x93f093b7, 0xc76fc06e,
-       0xa77664ba, 0x7dbdbc41, 0xbb42e490, 0xe3d64c81, 0xc3a05fcf, 0x4714fddf,
-       0xd6eeb82d, 0x06fe21a7, 0xbd38357e, 0x49ebf817, 0xcf84f7bf, 0x7fef3085,
-       0xd27b3e01, 0x45e93d8f, 0x342fc8a2, 0xedb7f9d1, 0x80fb961b, 0x1e5ee30c,
-       0x9afedadf, 0x7e5f9e11, 0x4b6e3e47, 0x25b8f8d1, 0xa41f8093, 0xc6d9cbca,
-       0x2e81e32b, 0x40f4fd1d, 0x9f77ee4f, 0x7eff8264, 0xdfdf4b3a, 0xe2fec67d,
-       0xa70dc225, 0x89243ae3, 0x92bf53c4, 0xd1e36cf7, 0xfc47719f, 0x67d83710,
-       0xe0c9d773, 0xaffc9e37, 0xeb3d0cb0, 0x0f670be3, 0x3f04e93d, 0x5f1a656c,
-       0x1d063473, 0x982ab2b5, 0xf68f6355, 0xf5f49a57, 0x715cf5b3, 0xc725e710,
-       0xeb061ccf, 0xa8e6ab8c, 0x0d3f7a08, 0x959fad4b, 0x738e1269, 0x3c767b72,
-       0x4c02fff3, 0x4048ec9f, 0x67d2737d, 0xd9fff7c1, 0x8fd774f0, 0x8d210f06,
-       0xe80b33e4, 0xdd96da73, 0xcaddfbfd, 0x825e7083, 0x890929f8, 0x69bf815f,
-       0x3b7fffa5, 0xb015fa00, 0x0debf5ae, 0x70f37ef2, 0x3743be78, 0xd64efd1e,
-       0xbbe18cf6, 0x204ee5ee, 0xa7be34c7, 0xbaabfbf4, 0xbb62bdbf, 0xc76f46b5,
-       0xdeeae826, 0x9d1af4a6, 0x00ff0b5d, 0x1386bdc3, 0x54ab0960, 0xb04db0d9,
-       0xda7e07af, 0xf049c103, 0x5ef6385f, 0x79222595, 0x16971464, 0x6385d3e0,
-       0x6797fe35, 0xa9ea99ff, 0x048a6f13, 0xa25c8ce4, 0xaea9e550, 0x899bf220,
-       0x917d6898, 0xc6c2f6fa, 0x6eb02515, 0x26f9789d, 0x931643f4, 0xc7f82752,
-       0x0f3ea4e5, 0x89a7b5e2, 0xf3e418a9, 0x39c77934, 0xad1e4a32, 0x2e9d8482,
-       0xe3b7af5a, 0xabaf7fa9, 0xd7d06b2f, 0x525b9297, 0xe97edf60, 0x38049106,
-       0xf6fa1bd0, 0xf61779af, 0xacd48cbb, 0x57fb7583, 0xa16bbc6a, 0x5419088b,
-       0xf6fd556f, 0x0a32bcf1, 0x71604b87, 0x7a1f6d16, 0x7ff32279, 0x2406662a,
-       0x59ffbe85, 0xa95bc8e3, 0x07dfa206, 0xbc7ec1d6, 0x6f713a7f, 0xf7e95d23,
-       0xc237e15d, 0x5d03d9ab, 0x3855c3f6, 0x4a73b792, 0xcb1e8620, 0x67263814,
-       0x102bbeaa, 0xc7b8ba5c, 0x7bfd4334, 0xd13253f3, 0xde1ed3f1, 0x668c2793,
-       0xc0fc03fc, 0xe792ed09, 0xd69ff487, 0x7f82ffa5, 0x68fdff6a, 0xfeba79ff,
-       0xfb53fda7, 0xfe05d81f, 0xaffab179, 0x2ff3edfa, 0xa93ea9fb, 0x4e97f178,
-       0x13c9d742, 0x9b8a7d42, 0xdb72b5d2, 0x96854ebd, 0x13bf05c7, 0x8044f5f8,
-       0xef458e2f, 0x154e0587, 0x41cec542, 0x49fe0ddc, 0xecf93ffb, 0xf11e30cf,
-       0x85d136d5, 0xe6edb4f1, 0x61ca99b0, 0x12f2e375, 0x23f58392, 0x19df7eac,
-       0x7a4dea1e, 0xfa78abfe, 0x1f902997, 0x8d453942, 0x9ed1852f, 0x79fadead,
-       0x5e4fac11, 0x64728ed2, 0xbfc60efc, 0xaffa8898, 0xdaef8a4c, 0x38c4e14e,
-       0x8bc55781, 0x6767f1b7, 0x37942778, 0x82fa017c, 0xc7e8227a, 0x572bbf1b,
-       0x8235d4ed, 0x8d98f923, 0x190c7bfe, 0xc3517a03, 0x3b30090b, 0x5f99eeb5,
-       0x70a11ce7, 0xa6fada9d, 0x97c28b93, 0x83674f26, 0x8f73fe8b, 0x6ddebddc,
-       0x6d16f2a5, 0x96eb690f, 0xd7daa4dc, 0x8a565621, 0xf3e42761, 0xdd166e54,
-       0xf2b8fa7e, 0x7a9f27f9, 0x7f99e20c, 0xd107bb32, 0xff3c57fe, 0x69e3fbda,
-       0x314ec57d, 0xc34d84b9, 0xd274a5ce, 0xbfff4bc7, 0x1e93b73b, 0x4d79bf15,
-       0xe7b18792, 0xd27624f7, 0xfdcec565, 0x15d61912, 0xfb83931f, 0x063d88a5,
-       0x8a47827d, 0x7ba85ec0, 0x8825bfe6, 0xc7d89e33, 0x18acd491, 0x1afcdcf8,
-       0x278003da, 0xaf4aa7a4, 0xde19fa0e, 0x80ba52f7, 0xcbd236de, 0x5522def8,
-       0x90bf40bf, 0xfbf94167, 0x07903d85, 0x0dd991f5, 0x617f2878, 0xf3e61395,
-       0xf8c35085, 0x537bf1fc, 0x8b959f40, 0x961714fe, 0x13f979ec, 0x5bfe423f,
-       0x528ff6f6, 0x9444be30, 0x45ae1374, 0xe79874fe, 0x70b34d92, 0x07894b9e,
-       0x71fcb0f9, 0xcb4034be, 0xde29020b, 0xac4e4319, 0x2f939322, 0xd2e250b6,
-       0xfe017e79, 0x77efe824, 0xb436c0f8, 0xa024efbb, 0xcea47e0f, 0x580c5a85,
-       0xf46160bf, 0x2ebaabfa, 0xa33eb010, 0x7deb77f9, 0x93a7402d, 0xd85495fd,
-       0xc112f177, 0xfb83e2af, 0xbfcbf696, 0xd195253d, 0x9e42c889, 0xf75d1dfa,
-       0x7873c327, 0xac5445bf, 0xc8efba39, 0xe39d59b7, 0xa7c756af, 0x7ac1c770,
-       0x6c4a45fd, 0xd44f35fb, 0xb75d00f4, 0x4a2cf8a3, 0x6ffc99de, 0xbbc99fbd,
-       0xe981ff26, 0xfe7ed0c5, 0xf8239330, 0x0a43d60e, 0xdb153857, 0x50e4cff7,
-       0x3a3f503f, 0x156f9c96, 0xb7d73955, 0xc285f91b, 0x51f1702f, 0x24e3037c,
-       0xdf701d22, 0xfa06e965, 0xf51e947d, 0xaeceb8c2, 0xbc726afd, 0x455bf34c,
-       0x9b203ebd, 0xdee81e98, 0x9e23f2ae, 0x53c0c52a, 0x52fc818f, 0x20cbf579,
-       0xcc2962bf, 0xcd1dcbff, 0x72a3cfef, 0x935065fb, 0x355ebd5b, 0xaef96dca,
-       0xdc9624d1, 0x9377697e, 0x9f4b7298, 0x7b5b94c7, 0xfff9f904, 0xf0d55eb4,
-       0x78f00c38, 0x351e274d, 0x3e1dd93d, 0x90f27a8d, 0x8d5e2320, 0x1dfe927a,
-       0xf95d7926, 0x8d43e351, 0xab9e2aff, 0x51f402ba, 0x7c6a9f07, 0x1aa7c1d8,
-       0xef89761f, 0x6c68f0ea, 0x34fb00bf, 0x96f9ae14, 0x528ed38d, 0x4ed2d257,
-       0x7f26df70, 0xaafb8f26, 0xe584f396, 0xf3111081, 0xd5303f43, 0x753b068c,
-       0x3d6fdfe2, 0x7785177d, 0x2c8bf13e, 0x445ea02f, 0xb7d2ffbb, 0xf3a04edf,
-       0x79e2a799, 0x54fb453e, 0x0239974a, 0x70a38e17, 0x3f8815ce, 0xb7e2113e,
-       0x0a34f91c, 0xfae5f98e, 0x4c4dfc3a, 0xa7a7ece9, 0x9fabbff7, 0xb7cb7df2,
-       0x1d3f5d29, 0x50bbc844, 0x10bc388a, 0x81d357cd, 0xde7f14ae, 0x00605c51,
-       0x5088a9ea, 0xbd77e51a, 0xf3fb3220, 0xa319c2ed, 0x9fc9bec1, 0xf19e2c3d,
-       0x7bf460fb, 0x3b3eaabd, 0x41e397eb, 0x650d9fcf, 0xf67b7fa3, 0xac4722d0,
-       0x9566d0bc, 0xf7535ecf, 0x5cecda5d, 0xbff94f3d, 0x7da3b48d, 0xc95bb7e3,
-       0x82fb18b6, 0x5f4d451b, 0x7fa374ab, 0x8e7f1d3c, 0xe97387ca, 0x51b9f1a7,
-       0xf5399b74, 0x4aece084, 0x34fbf807, 0xa1fb0fca, 0x06be05f8, 0x235b36fc,
-       0xe231a545, 0xf8a9cf79, 0x6be0789b, 0x0c2dcfcc, 0xc7800be5, 0x8baf3b42,
-       0xc9a93c83, 0x143250eb, 0x60789ae0, 0x5347cff9, 0xe21ef63e, 0xeb8f90dd,
-       0x3c919d0d, 0x2361fc31, 0xb07fa13e, 0x2e888f33, 0x627bd7c4, 0xebc012e9,
-       0x04acb37b, 0x95df35f6, 0xe0b155dc, 0xf5b3332c, 0xbd292e66, 0xbffb8a30,
-       0xb3f9bf0f, 0x8a02e11d, 0x9676b38f, 0xff95ddf7, 0x759fdc98, 0x0e5a8171,
-       0xf56790f8, 0x71002e64, 0xf9e222b4, 0xe50e04f9, 0xfeb4527d, 0xfe9a6fca,
-       0x54f5e43c, 0x89973887, 0x110b57b6, 0xdbd8f809, 0xfb0053b4, 0x289926fd,
-       0x6a108f18, 0x8a8ccd86, 0x05111d7b, 0xdff357c4, 0xf80edde6, 0x4cd3373d,
-       0xe8652e00, 0x01d82719, 0x512342e7, 0xd79bba0e, 0x5a647c1f, 0x10fd08a1,
-       0x3f230fe4, 0x74db2514, 0x499359f5, 0xdba5373f, 0x95647344, 0xeafd063b,
-       0xbd67c624, 0xff966fd6, 0x04dbf4cf, 0x5f18dfaa, 0xedfad18b, 0x7df18926,
-       0x8d4b7e94, 0xd656dfa5, 0x17c0a9ca, 0xa766f72b, 0xbe575d02, 0x2c4fa4b1,
-       0x8fbaf6fd, 0xa86ff7f9, 0xfd6de679, 0x1e1b7ea8, 0x51fadfa5, 0xae2316fd,
-       0xa5ea5a3b, 0xcffcb37e, 0xa0ebdfc8, 0xb7cc62df, 0xa69fc558, 0xb5438adf,
-       0xfb8adfa8, 0xa97cbaf1, 0xfa4f5249, 0xb397ecad, 0x6dba2eb0, 0xf007f831,
-       0x0dedfa0a, 0x38c1cf55, 0x5dfee7a0, 0x3d277d72, 0x3d5bd557, 0x67843ff7,
-       0xecadcf4d, 0xd33da1cf, 0x9e990f95, 0xf4c5995b, 0x4cbdcadc, 0xc41cadcf,
-       0xbf519cf4, 0x6fd17415, 0x21eafbec, 0x23f47bf4, 0x1b7d7eb3, 0x23992f6d,
-       0xfdf42dba, 0x9f3b5912, 0x5a3a3351, 0xd4bbfddf, 0x9f73be8d, 0x3d2e73c1,
-       0x823fbbe9, 0x7a841bbe, 0x91c8206c, 0x1c6e3f91, 0xd3e5d368, 0xb1f5f7bd,
-       0x79045ee7, 0xfe8f03f9, 0xe62607f7, 0xfafbed27, 0xbb9048d8, 0xaa1e00f7,
-       0xf9519eef, 0x47e7d5af, 0x28793a7d, 0x7baaf793, 0x1baafe18, 0xd5df3639,
-       0x7586407c, 0xd1176fe0, 0x2f7dbe8f, 0x9b67a3f3, 0xc0d8fa5b, 0x225fffcf,
-       0x2bfd25ca, 0x87e28b29, 0x302b1739, 0xce2bb9ee, 0xccfc05b9, 0x80b10239,
-       0xd0e0bb1d, 0x7ec0278d, 0x3d71705d, 0xe00bbdda, 0xc8e92279, 0xa1db98fb,
-       0xebf6f527, 0xaf9da6bc, 0xf9ae9065, 0x8ccd1310, 0x7157132e, 0x5d59cd81,
-       0x5da823f3, 0xc62df986, 0xabdf893c, 0x47cd9ff3, 0x8fe45f10, 0xe5f8cc7c,
-       0x72788def, 0xad54bc33, 0xaa78f5e6, 0x89e262e1, 0x2ca4ba52, 0xb72f13a5,
-       0x975914bf, 0x39cbed01, 0xf38cb7f4, 0x9c66f0d6, 0xcd4786bf, 0xbea059bf,
-       0x24743f3f, 0x86889e66, 0x22f92ee7, 0xf80dde1a, 0x33d34b78, 0x206190d7,
-       0x3c981f97, 0x7c0d1f3f, 0x178a7bf4, 0x73ade70a, 0x2bcee907, 0x65e2a3bd,
-       0x6148e7aa, 0x24780c8a, 0xf367c035, 0x96be77ca, 0xb377e742, 0x210b9592,
-       0x937f59f5, 0x688f103c, 0x1ea3b6b6, 0x9470f8d4, 0x5985c999, 0xf5ef2bd5,
-       0x7ae21575, 0x50b9c4d3, 0x3d06c2be, 0x7999e6a7, 0xd7f261ef, 0xbaf7fdcc,
-       0x6788518c, 0x91482e58, 0x5d015eb6, 0x86a73fe8, 0x40bc5d18, 0x69cffa17,
-       0xe020fda4, 0x73993abd, 0xa6fde187, 0x3f02f79d, 0xcfa56ebd, 0x39cbce41,
-       0x0e8616f7, 0x65ca7a7b, 0xc58858f9, 0xc8cc18c7, 0x173f5ceb, 0x5d897bc0,
-       0xe68993ed, 0x8e00f796, 0x366e5489, 0xfd00c3c3, 0x46fe8a2f, 0x07c8c5fb,
-       0x7503e53d, 0x2ab9efc7, 0x3a075f9e, 0xeddf01d8, 0xde43d812, 0xb47f5b30,
-       0x1720af76, 0x3a34de22, 0x65f5d134, 0x2983a314, 0xd66f9e06, 0xbd9e2aea,
-       0xef844e21, 0x6ffea06f, 0x7ebb0712, 0xf8d41f5f, 0xc5772cdd, 0xd215c413,
-       0xe806f4a3, 0xcd7de8b7, 0x11b7a6ea, 0xa6ae375f, 0x15dc99e6, 0x407d1a5f,
-       0x6f0e5e0f, 0xd34fcadd, 0x61799891, 0x467e55df, 0xb3f2f599, 0xe6fedacf,
-       0xedab8870, 0x90af50e5, 0x7e2e8250, 0xecccd330, 0x07ab6696, 0x0dfdbcf9,
-       0xee45bdd1, 0xa8a67faa, 0x257f0174, 0x64e27cfa, 0x4de80898, 0xa67c9597,
-       0xe3007bcd, 0xe0f5e8b7, 0xe907ab75, 0x33ff5dd7, 0xedfecccc, 0xead31ece,
-       0x9078c3d7, 0xc7eb28d7, 0x5a47ae33, 0x79a7a95c, 0xbf71d479, 0x71b4bcef,
-       0x84beebbe, 0x3c60b497, 0xd89fdb4e, 0x89767bc3, 0x73163f60, 0x0a107dba,
-       0xfe6fee39, 0x59bffa13, 0xff7ddd1a, 0x530a3f10, 0xe3bebf3c, 0x9f638c49,
-       0x34c8f67e, 0xaf159f90, 0xe542c4f0, 0x838775af, 0x889e5984, 0x45427604,
-       0x5dfb8f23, 0xcde70844, 0xa833b288, 0xf1f0c327, 0x5ef503a2, 0xa0732ec5,
-       0xf15f7e84, 0x103967f2, 0xc35d6b7f, 0x59ff9ff4, 0x91fd1f95, 0xa807c81c,
-       0xbcfed810, 0xa88f3e91, 0xb76a79fc, 0x6fe80e6d, 0xc73b3b6e, 0x2d9c115b,
-       0x0ce2a39a, 0x16459bf7, 0xc36ddee7, 0x33ff6c3c, 0x0331e61c, 0x48e7d17c,
-       0x53d0fcb5, 0x5cbd30cf, 0xe00624d1, 0xf6c5703c, 0x1710ad9d, 0x8cd0f8af,
-       0xfb77abf6, 0xd3ec0919, 0xcf3e2fc9, 0xf1371bce, 0x976878ba, 0x3e76e438,
-       0x59f8866c, 0x01ea1563, 0xf5823f5a, 0xfbf71aa0, 0x15b2718e, 0xd97dee2f,
-       0xe2b8514f, 0xf13b4f37, 0x36cb705c, 0xb723c627, 0xa05f7e5f, 0x7831dc4b,
-       0x9c771abf, 0xf5c105fa, 0xf1dc7621, 0x2127caa4, 0x48ee3eb3, 0x3c6127b6,
-       0x5799c292, 0xd17e231a, 0x5fcfffc1, 0xcdf60278, 0xf2faed4e, 0xf2bb8009,
-       0xfc4f739b, 0x2a93e294, 0xdbac1720, 0xc3df67de, 0xbbed067d, 0xd27d55f7,
-       0xb8d3ccfa, 0x27fad34f, 0x6b7a1bb3, 0x2645fbdd, 0xeeb453ec, 0xe2053afc,
-       0x4ef7abb8, 0xf56d7f41, 0x4953934b, 0x2b407f0c, 0xbd037f81, 0xd23227d8,
-       0x39b1b9ad, 0x4d3ce013, 0x77eb0ee9, 0x58393c47, 0xb2f4e2c5, 0x11de471a,
-       0x4bae5f7b, 0xc671b8dc, 0x3ac1d7cd, 0x65ba28de, 0xf1f88bd2, 0xe1cf4a61,
-       0x0ee3a0bd, 0x38209f75, 0xe3f1b2f5, 0x4a0ff0d3, 0x7d660baf, 0xe342fe1c,
-       0x0c7cff92, 0xba931ada, 0x7b871f8d, 0xdf6d3f81, 0x2159bf6f, 0x5da39016,
-       0x1edc61cf, 0x0f7d47e8, 0x85fcfad2, 0x1cbb884c, 0xc0efdb17, 0x66bdebfc,
-       0xd8aaa3cc, 0x53ca01fb, 0xe36f4beb, 0xf7511abe, 0xc7495adf, 0x5127db1f,
-       0x56ef3a7d, 0xab3b8b07, 0xb4b88074, 0x6ae7c4ec, 0xb5f199fc, 0x2eee9716,
-       0x32d63d1e, 0xabbfed80, 0x5b5591fb, 0x43112cff, 0x0b1b9fbc, 0xd9723af4,
-       0x0f0d547d, 0x98c3c02e, 0xd896fde8, 0xfd8efff1, 0x80dd0316, 0x758f609e,
-       0x7ad0a7ec, 0x07ab883f, 0xed620fb8, 0x666eb5df, 0x62ad34fb, 0x6d45bcec,
-       0xc5a465ff, 0xe812efb0, 0x4f4bbedd, 0x78aef8f3, 0xb42706ca, 0x9d7c574f,
-       0xbf5b14ba, 0xd4e16adf, 0xe7be037b, 0x67257ebe, 0x05981bcc, 0x78d5597c,
-       0x4a7b0244, 0xf9b4df5b, 0xe7fd529e, 0x78f2cf53, 0xb05d644e, 0x51bbf519,
-       0x1613547f, 0x5bc23437, 0xab7a616e, 0x1fad89ba, 0x023976a7, 0xa9cfda76,
-       0xaf91bb03, 0x911c77ab, 0x83bfb4fc, 0x45237fdb, 0x60acf2a2, 0xc14408fd,
-       0xfd85ea7f, 0x897f6c39, 0x71c6ebf9, 0xf1c752ee, 0xe38f6286, 0x374671dd,
-       0x507f0ace, 0x2e7ee762, 0x4149de3f, 0x9dfd0d99, 0xe409116c, 0xf20c9ffd,
-       0xe31881c5, 0x5a88b5cf, 0x0fc98b3c, 0x1cf1475d, 0xbb9d83a6, 0xb42513e4,
-       0xc63b57bb, 0xfde7087e, 0x19243b57, 0xb57517e2, 0xeeb52f2c, 0x4069dcdf,
-       0x5b84baef, 0xdeae3f71, 0xb2575f80, 0x1ae21f2b, 0x51d2c2ae, 0xbd46aec0,
-       0x7498a093, 0x1476aff0, 0xce14caa7, 0x469daab5, 0x0b9e3704, 0xc5459de5,
-       0x65de1f30, 0xec635972, 0x52f6883b, 0x8bc289e2, 0xe39fd2e8, 0xca469724,
-       0x7f968fd0, 0x39696953, 0x052e8d88, 0xb1858c53, 0x99fcddec, 0xdb779c2e,
-       0x507fd50e, 0x614aec88, 0x8eb06479, 0xcf8aedb4, 0x43f1c321, 0xb47e50a2,
-       0x1db9cfa9, 0x5e83f7fb, 0x4a24eb5a, 0x8a339502, 0x86cf9955, 0x2c23acf3,
-       0xe9f0365c, 0x857aff99, 0xf10d6bf6, 0xd9b457e8, 0x25527cb5, 0x46cce401,
-       0x41bcc41e, 0x936fe560, 0xe634e13a, 0x25781213, 0x298d3eea, 0xa1fd1dbc,
-       0x7c589bb3, 0xff572780, 0xcf8b027a, 0xafc00091, 0x542b2fae, 0xe212cf38,
-       0x3bfbc30e, 0x580f181c, 0x9422c6f6, 0x3443a01f, 0xf58a92be, 0xac1b5ee7,
-       0x67f01cce, 0xbf555a36, 0xc0b4afc6, 0x6ac59b39, 0xf54a7dbf, 0x18a962e7,
-       0x975e41fa, 0xe5faf2a8, 0x9843a2d2, 0x8a59e68f, 0x8e753e7a, 0x31acdcfe,
-       0xaa204b4f, 0xfe601c9f, 0xadbc9773, 0xb708cda6, 0xc56b7f31, 0xc35d7d76,
-       0x37a027e3, 0x127402af, 0x80e2e5fb, 0x3237e23d, 0x4613d7f8, 0x9afc777d,
-       0xb5f8f4d3, 0xdafc7aca, 0xa7f11886, 0xadc3afc7, 0x97e697c7, 0xf8df8776,
-       0xc873fab1, 0x8afc2aff, 0x548ed556, 0x4aff4af1, 0x654c292d, 0x42e9dc03,
-       0x28c2e518, 0x30f61947, 0x9feeff07, 0xafc5a81c, 0xefd40edc, 0xb87cea69,
-       0x1b3becc5, 0xf00f11c8, 0xe08e51ba, 0x79e82024, 0x75d8f91b, 0xfac40acc,
-       0x4d7b7c8c, 0x355cf4f7, 0x0b23d5fd, 0x809b57e9, 0x3f23877f, 0x89bef3b0,
-       0x05975024, 0xc176ea72, 0x59f41dfa, 0xb8458bdc, 0x17b885f7, 0x5efb820f,
-       0xa43e585c, 0x0db4abe6, 0x306e7825, 0x029f3e18, 0xdca1e9fa, 0xf7a069f6,
-       0x29484bbc, 0xc51fc1e8, 0x0f03f3b1, 0x38bf65a8, 0x85abd549, 0xef824c6f,
-       0xe70ca243, 0xdb42dbd5, 0xdea0832c, 0x2a3de3c4, 0xabfa84de, 0x90d6fc60,
-       0x6c5ae0c8, 0x38820c09, 0xc7115ec8, 0x013c5d6d, 0xd87665cf, 0x2f96216f,
-       0xccfa16d2, 0x9f4a28b9, 0x7a3d36b7, 0x36b9c415, 0xa9e7629a, 0x7e9ab14c,
-       0xec1bfad8, 0xc537b792, 0x1eeaf2ca, 0x51e7401a, 0xbaacfd3d, 0xb879330e,
-       0xabf3a556, 0xf9c46f4b, 0x64e214bf, 0xf88a4758, 0x461a6edb, 0x3dee39e7,
-       0xb0cf8d41, 0xf528e578, 0x2fd03afd, 0xdfeb5fa8, 0xddc3e9e5, 0xe7020547,
-       0x2cd546f4, 0x15eb7f45, 0xca73e527, 0x704a7917, 0x616df024, 0xcdef0128,
-       0xd04c7ef1, 0x22dd1fae, 0x4f33f8e8, 0x22f3575d, 0x44c05e54, 0x3edf50f9,
-       0xec18222e, 0xfc0f00a0, 0xfd71ed75, 0xd55685f3, 0x149272ee, 0x970df3e0,
-       0x5ef20e78, 0x7b89dadb, 0x6dbb850d, 0xa3845f71, 0xfa9c3ced, 0xbe25e5a5,
-       0xbf7ad638, 0x62f8caca, 0x9d7044a3, 0x8ed4b8d9, 0x4b03c5f1, 0xf580ae2b,
-       0x7b1fabfd, 0x8e7588ae, 0xc53f4a3c, 0x252c7cb3, 0xfe058c9e, 0xbc31cb5e,
-       0xc697a7d7, 0xf8d7f7c8, 0x8d6fe359, 0xc697d3af, 0x35e56279, 0x7665637e,
-       0x21d2c15a, 0xdafe049c, 0xe38f0e3e, 0x5cf1aeb6, 0x9f8ddcf6, 0x7800c9ac,
-       0xd0e74dbc, 0x3884b6ee, 0xb1bd9625, 0xfec4eac1, 0x6bf8d75b, 0x2eef8f21,
-       0x27a09c2a, 0x0377efbb, 0x813f5bfa, 0x677c2ca0, 0x73c32fa9, 0x642c4bbc,
-       0x85bbc40b, 0x1c5bf4fa, 0x6f93ffc0, 0x7de14758, 0xeb84d4ac, 0x8dd146eb,
-       0x08abfbf0, 0x1a83f8c1, 0x8d37edcf, 0xcf3e8e6c, 0xff3584fc, 0xc7a52b59,
-       0xd21756b3, 0xe6e3c925, 0x3ff77e00, 0xf209dbfe, 0x8cd176dd, 0xfaabec74,
-       0xaf77da43, 0x36dd9959, 0x0ad94e33, 0x64f293df, 0xc7b71394, 0x123c5ee9,
-       0x78a04dee, 0x4ea3928f, 0xbbf1f9fa, 0x71d50f44, 0xbb449e14, 0x2892f909,
-       0xc5d2ec8a, 0x4728fd29, 0x30905c9a, 0x4d8f2047, 0x885cabd3, 0x1ca83b0b,
-       0xc3d8b28c, 0x962477e0, 0x105379d3, 0xfac2c4ac, 0x754e116b, 0x3cc6cb9c,
-       0x7997ca79, 0x608a3870, 0x71121448, 0xdf4d7fa1, 0x6d7a7a6a, 0x59794102,
-       0xa810b0fb, 0x126cfda3, 0xaf885622, 0x01722964, 0x0a251aa4, 0xef179e32,
-       0xff304e5f, 0x78fd96d2, 0x42dd8742, 0x37c47e85, 0xfb5882fc, 0x869c7c79,
-       0x401fcf2f, 0x6a1ce46f, 0x8de6003f, 0x73c6cadb, 0x3b4166bf, 0xa87f43bd,
-       0xba9158f6, 0xdcfb8efe, 0xc209f2c4, 0x3ef44893, 0x687f519b, 0xebb8c9f6,
-       0xbf606b22, 0x189fdc68, 0x055bb49c, 0xcead1bbe, 0xa89f43b7, 0x1098e6eb,
-       0xfbf427d5, 0x66c8d0dc, 0xf72b07b8, 0x5dc72663, 0x3f21c9f4, 0xbefbf80f,
-       0x17c8c47a, 0x2e54c223, 0x32a1f6d5, 0xeae1a7dc, 0x19fb43a8, 0x9e49de83,
-       0xed152a3e, 0x8cdf955c, 0xdbe4d678, 0x77b9f728, 0x0ccd9bbb, 0x1a47e62e,
-       0x275c21c6, 0xe836721c, 0xb078b7a5, 0x29f2dbf7, 0xbf5c281e, 0xf4a3f902,
-       0xb81f384b, 0x21bfe601, 0xe415bd74, 0x27af7be4, 0x5475fa21, 0xbcd3f69e,
-       0x0fae3e27, 0xc04e27ae, 0xf3fef543, 0x46127aea, 0x01c8777a, 0x78e89395,
-       0x46ffc689, 0xa3e4d77e, 0xc8de2e0e, 0x047673c6, 0x0b9e59d6, 0x663065e2,
-       0x7805c9b2, 0x3aedecd5, 0xfe25bed5, 0x56ffb474, 0x1eba88bb, 0x4f800665,
-       0x5ecd44ea, 0xe3a25b77, 0x051dab53, 0x4fdb97a9, 0xfea45ef5, 0x1b39d459,
-       0xfe8ed0af, 0x84a2f79b, 0xfe37bfcf, 0x7914289a, 0x898dfc3a, 0x7f15dd1b,
-       0xb08471f1, 0x9ffec2fb, 0x230cdf9f, 0x7727dc7f, 0xe25aefce, 0xf5422579,
-       0xf5aade47, 0x3f193675, 0xd7969c39, 0xfb682f55, 0x01e9dd9f, 0xa98fbca3,
-       0x70c66fac, 0xeef20f4b, 0x25f8a9b5, 0xb3e80664, 0xb76a61f1, 0xff957564,
-       0xbcfceaf3, 0xb6f78636, 0x8307db5b, 0x3de7ad3c, 0x2f687135, 0xb0264c46,
-       0xb413762b, 0x8ffbdc7b, 0x5bde513a, 0x4feb7492, 0x8fc0bb57, 0xa7d9a9f2,
-       0x7c6a5d9a, 0x552ec3af, 0x3e2d1bd7, 0x795135ca, 0x193cf0a1, 0x1c03f1e7,
-       0xbfe62e75, 0xd05701c2, 0x3d584f63, 0x365fc075, 0xd838973a, 0xce12192f,
-       0xb096f162, 0x93bb3e4e, 0xde419b47, 0xb03f1482, 0xfae9f9fe, 0x1eeb8837,
-       0x0971b19e, 0x85aa5e0c, 0x97e9bec0, 0xd560d847, 0xfbc7f304, 0x6bfbb0e5,
-       0xfbb2e5fa, 0x31c73732, 0xa18b65fb, 0xfa5ac27c, 0x144bcc18, 0xfb9cdf88,
-       0x5006e1fd, 0x64f90e21, 0xf800d29c, 0x382b14b0, 0x71170c8f, 0x19de9473,
-       0xbc839042, 0x994ac489, 0xd247f163, 0xfb48ffb9, 0xf39128cb, 0x06323f81,
-       0x9a373c12, 0x9e7d8a11, 0xf13895e8, 0x8debd987, 0xbcc1ce5d, 0x41cfcaa2,
-       0xa937ce89, 0xe9839d84, 0xf050fb88, 0x8eadbf01, 0xadb2715b, 0xab3ed817,
-       0xd9e1813f, 0xc101bfe8, 0x5a825e60, 0x822257bf, 0x2bfd1135, 0xdfaff03f,
-       0xcaff4164, 0xd041dc46, 0xb1c41fb7, 0xce3aecf8, 0xbfea1ebd, 0x702dda10,
-       0x37268fcf, 0x343c3c9a, 0x40b716e1, 0x775e755f, 0x5f7c0736, 0x00ef172a,
-       0x9c275b9e, 0x6716bc1d, 0xf8c99ed2, 0xf975e14e, 0x9afd1af6, 0xacfd1d44,
-       0xd6895710, 0x08690ef3, 0x5cadedd8, 0xaafc1b9c, 0x831ce5d6, 0xe7a8b397,
-       0x3cdd0411, 0x1fcc6cd3, 0xe7f55369, 0x90b2e3df, 0x84f5b51f, 0xc63d6fce,
-       0xe8f30d7f, 0x386a8738, 0x973c6a77, 0x11dd969a, 0x7cc74a07, 0xee0952dc,
-       0x43672332, 0xbce3b436, 0x124cf6ce, 0x6a64bce3, 0x5cf31ac4, 0xbc5256b0,
-       0x4b780d7d, 0x40126b15, 0xcedea71f, 0x1f1188f4, 0xc47f9c6d, 0xfb47d841,
-       0x1f331883, 0xd2d32b45, 0x4c584a6e, 0xbf4b4fdf, 0x79ed4b01, 0x19885d83,
-       0x71b24c57, 0x64dcec3f, 0xfc18b103, 0xed1b24cd, 0x9de7b4ef, 0xff1415f7,
-       0x37bb8c76, 0x37bc31c4, 0x37bc31c4, 0xe53e1a48, 0xcebf9078, 0xf7975bba,
-       0x4967c1b4, 0xd10f2010, 0xb9f28e9f, 0xdde8c5c4, 0xf682bef9, 0xdca21f4d,
-       0xc4941730, 0x436c9106, 0x21f167be, 0xafc87ced, 0x4024cf7c, 0x96db94be,
-       0x16fbfaa5, 0x0604df46, 0x530df9f7, 0xb214dc70, 0xe2983ac6, 0xc9a96979,
-       0xd3a3710d, 0xc2723f0b, 0x1985e991, 0x0f20792d, 0x1b8f79a7, 0x984a97e6,
-       0x8e6cb85f, 0x2ed30814, 0xc2a81b93, 0x01ba7462, 0x4ccb3bf7, 0xc7aef331,
-       0xe9fed8d8, 0x961738d1, 0x90d36969, 0x92f59d4e, 0x8c4bf004, 0x35e54a7c,
-       0xcea8f17d, 0x6f94cc73, 0x790c5b14, 0x1349136b, 0x185beb87, 0xb1ac95f1,
-       0x35b7aab3, 0x39064979, 0x52ab7d84, 0x3a3547aa, 0x4d5f500f, 0xfe28b8c1,
-       0xbfd7a171, 0x79c37f06, 0x45ea015d, 0x10c88e4d, 0xa0ade7a6, 0xa1e2a377,
-       0xe83f7b6d, 0x9f8efb0f, 0x0739dbfc, 0x55fd3bec, 0x9e807768, 0xbbcf7e3d,
-       0xf4c7380e, 0x2e2c3dc9, 0x4fc18772, 0xfa63645b, 0x74ad8f7f, 0x8177e01e,
-       0x9e791fef, 0x77257e28, 0xe593fdb3, 0xde70de01, 0x506f7f5d, 0x70c93055,
-       0xf11f908f, 0x1fdea55a, 0x46c7a466, 0x2cb78b1b, 0xca59b1df, 0x4f7c6190,
-       0x5c7f8c25, 0x378f43f5, 0xd1dfd03a, 0x63b859e0, 0xd9be0484, 0x7566435f,
-       0x6445bdff, 0x025287eb, 0x151e67fb, 0x0f38466f, 0x2f6af7aa, 0x8fcb25f9,
-       0xdd63a329, 0x27b0f54d, 0x187bcec4, 0x13e4b1e7, 0x129528b9, 0x1cfdc96f,
-       0xfef0ddfa, 0xf33d743d, 0xee1f7ddc, 0xd9e719b3, 0x051f5ef5, 0x2a65b3fd,
-       0x6de78dbd, 0x3ed88597, 0x41e262f8, 0xfe72ecf9, 0xc5cec436, 0x678de318,
-       0x00db650f, 0xa9b0bf0f, 0x323cc4f1, 0xef6dce06, 0xfe20343a, 0x9f56f772,
-       0x828bef52, 0x3ca1bb7b, 0xce5823ee, 0xe2902303, 0xf6f432bf, 0xd55fc05d,
-       0x3ef13b4d, 0x8faaefb4, 0x9c2742aa, 0xe9ad4b90, 0x6e876a25, 0x8b20f903,
-       0x5a7d9d39, 0xc49cf9bd, 0x9f866afc, 0xb7e7d4db, 0x20723e01, 0xd9fe5bdf,
-       0xdbef4a04, 0xd1f3c52a, 0x6f3da5f7, 0xf7c3efd3, 0x3cdabe76, 0xed6b79b5,
-       0x9c5e6a55, 0x0e4d3bf1, 0xb97ca9e6, 0x75f4eb78, 0xea8a297d, 0xa9917ef6,
-       0xf3c3939e, 0x2d9f1a42, 0xe945a523, 0xa349f831, 0x84df076f, 0xd3f38e7e,
-       0xbeb8bae8, 0x3f83c54c, 0x4c4fdd4d, 0x91957883, 0xa73a7a8f, 0x32462add,
-       0x7c8dbe41, 0x7dcddad2, 0xb31b2128, 0x4acb162f, 0xa8cfc411, 0x15cebbf9,
-       0x171cdf65, 0x14fe0fea, 0xe32b6ee4, 0x083d0efb, 0xf7e8314e, 0xff5c4537,
-       0x54e43a57, 0xe90fffb8, 0x13f20e37, 0x4f787ecc, 0x4f98e71b, 0x808a0651,
-       0x4f2c62ff, 0x81954afa, 0x97db3a83, 0x04e73c6e, 0x086dbbfb, 0xab51b8c1,
-       0x69ef0f43, 0xe37a8f1b, 0x4a8f4ab4, 0x3f9be5a1, 0xdadace83, 0xc7177982,
-       0xa771a92e, 0x58e2e64b, 0x39d8b4f3, 0x7778bddd, 0xf9a872a8, 0xfa540b35,
-       0xfb6211dd, 0x4d370be9, 0xc9747a47, 0xa1fd54bf, 0xf50e46b2, 0x4b3e918e,
-       0x3e63d7dc, 0x3e40a2da, 0x5e85df7e, 0xbba441e4, 0xda776e91, 0x371eec5d,
-       0x7b8246a1, 0xe26d8eed, 0x8571ff70, 0x73ff7b10, 0x9df4ddb6, 0x479c63e6,
-       0xdb2ff077, 0x2faebb5a, 0x908ff981, 0xf08dcf80, 0x425ff36b, 0xd4a7a614,
-       0x2f3776f9, 0xf2c49912, 0x7f75d434, 0x815b9c39, 0x790793fd, 0xc6adcf96,
-       0x35f834a1, 0x28f38d78, 0x7cf12be2, 0x8f035b41, 0xf877d979, 0x77067dd9,
-       0xfd70e5ac, 0x9a4e8eed, 0x7bf6d15e, 0x30ca9baa, 0xfb43cb6f, 0xedb63b01,
-       0x29f6c263, 0xcf7873d6, 0x0cf4b75b, 0xeea57cb1, 0xa30849e8, 0x374a62db,
-       0xdebb3ff0, 0x0caf909f, 0x0a27de8c, 0x8c0ca0dc, 0x4122b7de, 0xb15957cc,
-       0xf9eeba7d, 0x8e35768d, 0x9ef5eaa5, 0x24d48fe4, 0x696f8cc4, 0x9fc9a6f2,
-       0xda778f26, 0x0a6f6665, 0x59198381, 0xd1879f80, 0x7afaa1bf, 0x3df99d9e,
-       0xafa5cd0f, 0xa73c6f54, 0x3258a7db, 0x096bd196, 0xbbcf825f, 0x0f14bbd3,
-       0xd8bdbd3a, 0xf8c3cfae, 0xe6d1f3a1, 0x3689c9a1, 0x189ca33f, 0x43d237bf,
-       0xe919ef8b, 0xc007a462, 0x5bc67e09, 0x35816d7b, 0x38b7ce14, 0xaf7fb706,
-       0x4d6ee115, 0xb9c0ac9b, 0xf9f4eacd, 0x3e01fe58, 0xb0fb074c, 0x768eceb4,
-       0x8d87eaae, 0x225c5dea, 0x5ecbb557, 0xd9232ab2, 0x24d2a7b9, 0xb58993e0,
-       0x17161991, 0x583e8f21, 0xa4f7045c, 0x32387c4e, 0xbff14203, 0x5646f07e,
-       0xd77916df, 0xfcfb86e2, 0x690a8a4b, 0x2fd071fd, 0x95fa2fa0, 0x6efbe0db,
-       0xf973c4eb, 0x1fdeccba, 0xcf9d2e65, 0xed66b1ee, 0xb33ed495, 0xf2aef5d0,
-       0x4157e0f0, 0x4a5b2b7e, 0x542e218a, 0xba781109, 0xce2955de, 0xad872db0,
-       0x7be9e3fb, 0x4f3cd91f, 0x76ee21d9, 0x8bae2d71, 0x94058795, 0xc588722f,
-       0x573a0567, 0x6d6efd2b, 0x2993b51c, 0x5a26d77e, 0xd317e0dc, 0x97f07ee7,
-       0xb22a26d7, 0xa35cf51c, 0x70077c1f, 0x7cb135ac, 0x0c6ffd82, 0xc65c8f8e,
-       0x23efd82e, 0x34cfe025, 0x1a582cfb, 0x1725f3db, 0x37c8e79e, 0xb18978b1,
-       0x76bb6dfd, 0x00ce49ae, 0x243ea8be, 0x1fc3fca1, 0x84559fd8, 0x613549c9,
-       0x0eaad0e7, 0x53773c13, 0xcf08a87d, 0x84b9c0dd, 0xe07a754f, 0xa6ee735f,
-       0x9e18af93, 0x44ae040a, 0xd0b71a88, 0xf9d5d56e, 0x9810d354, 0xdce3e10f,
-       0xcf846e70, 0xa2ecd530, 0xa0afe7f3, 0xe087c525, 0xff70f372, 0x89e4fd4c,
-       0x559fdc3c, 0x2d79aa27, 0xbe3e7626, 0xe557dd63, 0x39fb2b4f, 0xdd028f4a,
-       0x25b1ff4f, 0x53f6c6cf, 0xe6d6afd0, 0x8429c75b, 0x35ed7f03, 0x7219e782,
-       0xe0334993, 0xb19446cf, 0x47166fc0, 0x6c97caa2, 0x65fe9b3f, 0x9b36e940,
-       0x7e53237e, 0x9fc1faff, 0xe3bbff22, 0x68b2ab4d, 0x59f8739d, 0x2e74c33d,
-       0xef30b28b, 0x6bf565a8, 0xd006e74c, 0xc358e8ba, 0x4af1b0ea, 0xa3b33e17,
-       0x143fc8ae, 0xba3171c6, 0x01ae50ee, 0x2c4c16fe, 0x901c23ae, 0xcb477f70,
-       0x794b5957, 0xe2d1f806, 0x5d747a60, 0x3673c16d, 0x28179b88, 0xec4fe432,
-       0xfa41ef51, 0x5786a5be, 0x7f4266de, 0x7fc04a09, 0x53e183bc, 0x54690ba3,
-       0x5e3c81ae, 0x81ae5412, 0x0e7ebd7d, 0x7e83a24f, 0x96adf23f, 0x1bcfa089,
-       0x0f28f9df, 0x82bf73ef, 0x2df233f5, 0xf9d243ea, 0xff6dfe9c, 0xe4fbd1cd,
-       0xa9f91cfd, 0x03251df0, 0xec9cafda, 0x3951b722, 0x2c8853ac, 0xad9f8365,
-       0x091b2ff7, 0xd91f4fd3, 0xa070af4a, 0x3ae3093e, 0x67bb13f6, 0x7e8dd400,
-       0xec496933, 0x949dde55, 0x17ee3773, 0x7d346625, 0x85d610b8, 0x4a7bb1df,
-       0xfcc14538, 0xee3b17d3, 0x9718236b, 0x373891b2, 0x9b898dc4, 0xd453f9a4,
-       0xf1899af8, 0x945e7255, 0x87ceacff, 0x79085f7e, 0x2c6c63f2, 0x8fce81bf,
-       0x823afd07, 0x848e58c8, 0xa0365938, 0x3df583d8, 0x4fe1f824, 0x588fff69,
-       0xb2ca7c59, 0x8fe2e89d, 0xb7160e65, 0xe2c9c079, 0xf062718f, 0xe22bb016,
-       0xd81710ce, 0x4b8f6d15, 0x0bcfee02, 0xdf709bae, 0xe309a0ee, 0x018b4fdc,
-       0xb517ec17, 0x5bc8255f, 0x6d7f6748, 0x7eb5dd2a, 0xabe4911f, 0x0bf7ee20,
-       0x9d3fab27, 0xbb8f304f, 0x801484fd, 0x0cc4dcfd, 0x3c744d4b, 0xd9839e69,
-       0x1573bfbb, 0x043a04cc, 0x1811c6f7, 0x38becc7f, 0xb9e3d013, 0xe056b91d,
-       0x4701178b, 0x66890f14, 0x5fd09dd7, 0x6f0a39e2, 0xf9673e16, 0x223c82fd,
-       0xfc77e29e, 0xee19768d, 0x1ada7ad1, 0x56f311bc, 0xbde1379f, 0xee4a2fc1,
-       0xf17f50e9, 0x3d02ecac, 0x305674fc, 0xbcf3e70e, 0x62f3e709, 0x2bd5fb5c,
-       0x0c0fdc29, 0xc12ef161, 0xcfd00446, 0xbe40a982, 0xae5f3e93, 0xafa6b1f2,
-       0xd11c8137, 0xc11c23fa, 0x29820c73, 0xcb48e51f, 0x276b6a27, 0x67d44f98,
-       0xfc0f0b66, 0x8b5d371c, 0x8879853b, 0x25284d17, 0xb04dcf68, 0x05ce788b,
-       0xbce199f2, 0x0f5544db, 0xb2b8fc4f, 0xbb07e584, 0x9ebdc30f, 0x7ef576cd,
-       0x739f7530, 0xd727ca92, 0xa16f0891, 0x245dd7ed, 0x4d27886e, 0x8fdfa8ba,
-       0x5f60ca78, 0x57fb514e, 0xf0855dda, 0xede89f38, 0x450d29bf, 0x2c3d6027,
-       0xfc008a20, 0x6862d934, 0x09d23b07, 0x9febf0f7, 0xfd50e03f, 0x19924cdc,
-       0xeda6c79d, 0x87e14d43, 0xb5fb446e, 0x5e037258, 0x0f95da76, 0xdfc03f20,
-       0xc5cb9222, 0xb1f29f25, 0x1721c37c, 0x2cae046d, 0x8769fca4, 0x50dd5cf9,
-       0x79d2b7ef, 0xf5903d5f, 0xfa087c0f, 0x93c7cae5, 0x8fdf4093, 0x95a5e957,
-       0x7f01df1a, 0x7f19e2b9, 0xca7786b9, 0x2c8ed3e7, 0x37934f7c, 0x67e83be0,
-       0x1f98188f, 0xf29bbf6b, 0xafc0d3eb, 0xfd04ed3b, 0x5ba59fb8, 0x699c80e6,
-       0x7caab4e3, 0xd5d72c6d, 0xbf0fdcae, 0xc0bfe4fb, 0xbec28dd6, 0x75e8a517,
-       0x83024fbf, 0xcfd72bd7, 0x68790698, 0xccf31176, 0x5173d452, 0x1e92fcd1,
-       0xdf1a2fc5, 0x9c59dab5, 0xc99fe348, 0xe1e5dfbb, 0x840be4f9, 0x8748b2b8,
-       0xcff1a2bf, 0xf7187f44, 0xe6122781, 0x67f9189f, 0x93fc3757, 0x40165e7f,
-       0x9fe1756f, 0xba7f8c43, 0x0fda1be3, 0xe4616bde, 0xaa1c779f, 0xff2dddbd,
-       0xfcf3c25c, 0xbe4ef7ab, 0x93657eec, 0x6a9f9f4f, 0x62d9c72c, 0x54bb2fe7,
-       0xea96efbc, 0xbd01ca6f, 0xcec4d531, 0xe32409ef, 0xeeef0a16, 0xfcdeed38,
-       0xefa86c9a, 0xda1e9814, 0x1ea33219, 0x78f769da, 0x669b7e30, 0x0557e761,
-       0x23ce044f, 0xe45afbb8, 0xd921dfe8, 0x587660ee, 0xfb8f0c50, 0x37f1ec02,
-       0x9d8c1f18, 0x2a43cb9a, 0xa662fa5a, 0x971d4617, 0xcfefc336, 0xbfccea3d,
-       0x06967c00, 0x79dfa3b8, 0xcf784a8f, 0x0951f552, 0xf76fe3f5, 0xf1045dbd,
-       0x79cf2d51, 0x8bb79ecc, 0xfbc2860a, 0xa1fedf8c, 0x8ead65ea, 0x5f404047,
-       0x1fddee1a, 0x4b1e71d7, 0x297e6f7f, 0x674e51f0, 0xf93ef1bb, 0x3fdb1c60,
-       0x11644d99, 0xb4719886, 0xdeb85ef4, 0xfcaf78cc, 0xff3b30ec, 0x27b0f336,
-       0x2af2bdf6, 0x37ef187f, 0x8a77f6a7, 0xe7efec13, 0x6841f65a, 0xdd6cc884,
-       0xd7354a0e, 0x26a33f30, 0x9349f81b, 0xf8a3fc43, 0x44327e0b, 0xb706bbf7,
-       0xd07ff3a9, 0xa9fbb02d, 0x4bee1222, 0xefb09cfe, 0x363aea82, 0x40f4c9ca,
-       0xe617eaee, 0xcb239c03, 0xcba06695, 0xd7162eb3, 0x5b0905f9, 0x6e6e81b2,
-       0x8253f701, 0x0bf93ca2, 0x223df3ae, 0xd3b10e94, 0xe27d3df6, 0x8ff8c246,
-       0x9c633d3a, 0xed099f60, 0x31bbe087, 0x824773e3, 0x588fb71e, 0x9aeb049b,
-       0xab853706, 0x13bd9b78, 0x81ae0d0e, 0x8f97c64e, 0x00c6cb3a, 0xd03be01e,
-       0x8e474d4b, 0x8d7be059, 0xcf7b821f, 0xe2883e30, 0x4e83e00b, 0x4016e0be,
-       0xa283c35d, 0xfdb7cfae, 0x8b42f88b, 0x17c8f46b, 0x7e70b710, 0x0b98be2f,
-       0x05f23578, 0xce3ce7b5, 0x505cf618, 0xc6937962, 0xe7b13fe7, 0x896efbe3,
-       0xd913de60, 0x6bbf6567, 0x7dc049e8, 0xd8b8df90, 0x1c9f6d98, 0x28a6a4cb,
-       0x7664e559, 0x2a3bf6bd, 0xda1cc223, 0xa2a8239f, 0xbced0db8, 0xdd27a87e,
-       0x31c8fe2a, 0x46fb838e, 0x033e3731, 0x1270d0ec, 0xcc236bd8, 0x87906125,
-       0x1989b65d, 0xdae63f60, 0xfcc36426, 0xfab21e5f, 0x5ed2584d, 0x9bfe5bee,
-       0x7da772ad, 0x66c3e9a5, 0xfc6d5bb5, 0x4c7f2a35, 0x2779d852, 0x70d1ebd0,
-       0x9003eb68, 0xc2e0e009, 0xdadf4db3, 0x22878f50, 0x00936f14, 0xfd878a0e,
-       0xfb04691c, 0x24a4df21, 0xb03b064f, 0x3800584f, 0x9d7ef6db, 0x92cef109,
-       0x021febd0, 0x3eda25bc, 0x0fbf5bac, 0x35b7b46b, 0x3ff3487b, 0xf3497b34,
-       0x82aec17b, 0x1fd532f6, 0xbed99971, 0x05b084d8, 0xe47853ef, 0xa2957cac,
-       0xe740b3ca, 0xe3cea251, 0x7082d266, 0x4ca9f769, 0x7251f153, 0x39abfa88,
-       0x54c84ed0, 0xeaa9878a, 0xdd532a7d, 0x6e22fbfa, 0x3efb1b1e, 0x9e9fad15,
-       0x1bae37de, 0xa3f61ad7, 0xc879687e, 0xf94feec7, 0xc3f98fbd, 0x7ef007e3,
-       0xb1dfd601, 0x09feec59, 0x21c3c317, 0x763af629, 0xf1eb9551, 0x9c0e48a6,
-       0xe7bfdec7, 0x1e6eb8ef, 0xf7f7f3d8, 0x771c8ec1, 0x97902042, 0xa8c4fe3b,
-       0x180fcc78, 0x695f232b, 0x6f3f7afd, 0x9cf611b4, 0xccdeff44, 0x728f0a41,
-       0xc167c025, 0x8f5395f2, 0x9dfd0a3c, 0xe8902a3f, 0x92451f73, 0xe5c42067,
-       0x1ddfd48b, 0x7b31c83a, 0xa83f6b4a, 0x11c7defe, 0x21216f95, 0xc567bb43,
-       0xa9e7451c, 0x1a1ffdea, 0x2f1ea75d, 0x74e4213e, 0xfdfc0fa5, 0x5a10e233,
-       0xaa9ce1fc, 0x9ff3490f, 0xf5ce7cf0, 0x600a778d, 0xc69f5fbf, 0xdc6a2513,
-       0xe9ea641b, 0x4e21c547, 0x6ff60d3a, 0x4e8f33f3, 0xb7e5bc83, 0xf4814c78,
-       0x99be7686, 0x3e16f503, 0x462abde6, 0xba1f5efc, 0x9955ef13, 0xa3e4cf1b,
-       0x5fc7f1a7, 0x3864f94d, 0x3b309dd0, 0x4bdd8f30, 0x81efa462, 0x1491ff3d,
-       0xbe3dda19, 0x91bfa3bb, 0x2a9caf0e, 0x9eac7dc0, 0xdbe461e8, 0xfe9e747d,
-       0x5377e12b, 0xbf8fc42d, 0xfac2ea9b, 0xac34beab, 0xddeafc6b, 0xd81264fb,
-       0x4e9f1a79, 0x337c6249, 0x49a3f76e, 0x2f49dec4, 0xc586de23, 0xc97ffe33,
-       0xee25d9aa, 0xa3e8d359, 0x843ae977, 0x2d27ea8c, 0xaa563790, 0x70fb3ac2,
-       0x4425da11, 0x5c62cf3d, 0xb7f366df, 0xda75014d, 0xccfeefd3, 0xf57acb94,
-       0x6fc5397b, 0x0eb00bd5, 0x99ab0916, 0x78ed531e, 0x9d231e0d, 0x08a523df,
-       0x19f0777f, 0xe708c0f9, 0xf6f91d4b, 0xda07ae0a, 0x18cce0ef, 0xc6262598,
-       0x8f868798, 0xc7ae8499, 0x8f5fbdd9, 0xdbd78c6f, 0x178ee7ef, 0xdad011fe,
-       0xe919bc9d, 0xf4d76c66, 0x900c1147, 0xec1fa58b, 0x29f1b993, 0x8ba2df48,
-       0x3ae85112, 0xcfe9fa43, 0x2b9293f5, 0xb956df91, 0xf8eeb3d8, 0x4f22faad,
-       0xf93b233c, 0xd87a6c4e, 0x5bb77c06, 0x1c41b7a8, 0xf4fb3af5, 0xc2bd103a,
-       0xe2660bcf, 0x131115fd, 0x94dad081, 0x886699d0, 0x243f7833, 0x20a1be78,
-       0xf0327fb4, 0x0b42abe9, 0xe76d59fa, 0xca387909, 0xd50a6cee, 0x6b2ec0d9,
-       0xf3e7664a, 0x5d10260e, 0x78c5f4fe, 0x8e9a6fa6, 0xc4a69d9e, 0x62ee1f68,
-       0x28833cfc, 0x9ff439c9, 0x7f29eb45, 0xc7dc1f80, 0x42927181, 0x325afdce,
-       0x39732dd8, 0xf6da23f4, 0x992d798e, 0x7b7adbc2, 0x2999ea02, 0xe9ddf74d,
-       0xfe0884a2, 0x6f3e2463, 0xfef0e32f, 0x8dd92284, 0x59c5a2f5, 0xf98df7e8,
-       0x09466926, 0xa220dfb4, 0xaf8533df, 0x755e2014, 0xabc38d3a, 0x9170f63c,
-       0x623df85a, 0x0e3674ff, 0xc093f971, 0x24a77d3f, 0x66fe0469, 0x07d5ac9e,
-       0x122eefe1, 0xfab6ff83, 0xcdfb73a5, 0x2cf57db4, 0xa78df30e, 0x3f8832b8,
-       0xd68a7f8a, 0x5baf384b, 0xc005a942, 0xf58a33d7, 0xaac31ee7, 0xd4ab393d,
-       0xfbd10246, 0xe50b9cf9, 0xfdb5a0fa, 0xf11dfc56, 0xf98122bd, 0xa37e7269,
-       0xe7b3efca, 0x9bbee924, 0xa9dd984e, 0xaa4dd5c9, 0xfaa8ddfc, 0x193d73cd,
-       0x094bf1ba, 0x40fe87b3, 0x64810bda, 0x7ed8b8f7, 0x96f6b4f4, 0x25e1f3c3,
-       0xd068dfbe, 0x310d3787, 0xe57cbdf8, 0x348be45a, 0xc8f78dce, 0x37edf5b8,
-       0x8dd7d58f, 0x0fd46bf2, 0x8f8b20b3, 0x3427aaef, 0x2f6b307d, 0x683c422f,
-       0x33c53e56, 0xbb7ac5da, 0x317d27bd, 0x7d1bae26, 0x17be4971, 0xfa2e90cc,
-       0xefe2e3e2, 0x4b7e2fa5, 0x54b196dd, 0x578edfae, 0xa4fecdd7, 0x298de83f,
-       0x81478efc, 0xbae8da8f, 0x47c18e69, 0xc5a3bada, 0x1ca88a01, 0xc5381ea3,
-       0x5ca663f6, 0x91fe274c, 0x0e80719d, 0x12ed423d, 0xa97b0c77, 0xe51b3e35,
-       0x68ef43ab, 0x2eca257a, 0xb87ef311, 0xda85325d, 0xc02e52a3, 0x2be10fd7,
-       0x2925ef52, 0x882b8482, 0xc19da61f, 0xa0579038, 0xcfae2cfe, 0x817f224f,
-       0x3b12e3fe, 0xaf68c3e5, 0x0ae87168, 0xe94f6697, 0x1e23a5f9, 0xc3dd9339,
-       0x1149f1aa, 0x7fe413e0, 0x04fb8f26, 0x7fd41bff, 0x8000b303, 0x00008000,
-       0x00088b1f, 0x00000000, 0x7cc5ff00, 0x55547809, 0xf579f096, 0x55492d5e,
-       0x146caa92, 0xb612f08b, 0x84582484, 0x5916ec80, 0xa014a358, 0x8168cb80,
-       0x9a126b0b, 0x69ee9c71, 0x0242a6ff, 0x83b74343, 0xe8cedad2, 0x3ad857f4,
-       0x08b41a83, 0xd09d0301, 0x584c5015, 0xf82e0834, 0x1a6d1ad9, 0x84490ed1,
-       0xbfbb46d6, 0x739cffcf, 0x2aaa4bef, 0xffff4d85, 0xb49fdf3f, 0xdeefb97d,
-       0x67b9ef77, 0x979ee73f, 0xb3559bdb, 0xf6e008ad, 0x14078a99, 0x77f1d000,
-       0xe042c022, 0xadacc37f, 0xc78ef016, 0x69fcd7be, 0xe7f80d87, 0x9c2ffc3b,
-       0xa42cfc90, 0x900bcf50, 0xce54b009, 0x7d57fc5f, 0x3c5e3d33, 0x52fe7a27,
-       0x92b9fd98, 0xf81b700c, 0xf71c30cd, 0xff8ec5f3, 0xc7154bec, 0x7e8b2e97,
-       0x4a4ce99e, 0xff8790bf, 0xbe230118, 0xd4ca0153, 0x22b79dba, 0x5527ddbc,
-       0x334c558f, 0x390ffed1, 0x350ffec5, 0x7c800c97, 0x1674df80, 0x3db1f8a7,
-       0x1c2111b6, 0xd1bad00d, 0xec71edc6, 0xefc5f107, 0x3c66e7e8, 0x21fc059f,
-       0x52b4b607, 0x4801b721, 0xc4ed1805, 0xff602745, 0x0d3f9e2a, 0xc02486c7,
-       0x5c2473ef, 0xe7af00d9, 0xf104e798, 0x5eb8c3bd, 0xe30dd700, 0xf75c01fa,
-       0xf72746c8, 0xe6e8db5f, 0x442e0dfe, 0xfac0066a, 0x37af2714, 0x8776f72f,
-       0xe35bdf1f, 0x50e7e6cc, 0xf844da3e, 0x7b2fe036, 0x1004086a, 0xac77afdf,
-       0x807494d0, 0xb1e2b72a, 0x01d1f566, 0x8e58e34f, 0xbe25cbf3, 0x102ab72b,
-       0x1fe5e7c4, 0xc4072bae, 0xee33575f, 0x2aa9f887, 0xfc368355, 0x63d34967,
-       0x0cdf453b, 0xdefa08d6, 0x33028e22, 0x86cd16b5, 0x28f02cfb, 0xf1f7151e,
-       0x6ff78936, 0x1d412af5, 0x278b79ff, 0x63871e9a, 0xae58bee8, 0x0ffe80b3,
-       0x47305bdf, 0x9d718609, 0xdfa29305, 0xd6757c5b, 0xfed8cae7, 0xe898b47c,
-       0xbf3fb63e, 0xb7744edc, 0xc1863fe3, 0x95fba230, 0x8d6fa58b, 0xc5ba3e85,
-       0x8e74b1b6, 0x9d16bf1d, 0x673a27ef, 0xc6ce9b5c, 0xce8b7ffb, 0x904e110f,
-       0x1bf470be, 0x30049e8b, 0x1a07e9bb, 0x55f679d1, 0x32add78d, 0x861433ce,
-       0xd4fe79d2, 0xb76ff859, 0xaafcdf42, 0xfe2d2fa6, 0xe79f6b82, 0x22bfed6f,
-       0x69fde745, 0xdf7e6f5f, 0x8034f3be, 0xf9ce78c1, 0x8df8d139, 0xbd2c6ba5,
-       0x62f7ca16, 0xe635b5e9, 0xa05d061c, 0x60689913, 0x555fbc1c, 0xd16b8e19,
-       0x162e97ad, 0x7e4f08ff, 0x5f8071ff, 0xd6fab9f3, 0x76827493, 0xe02057cd,
-       0x03c84732, 0x052075f2, 0x0ade5be9, 0xec0444e1, 0x3e738b96, 0x28f5a8d7,
-       0x39c469f0, 0x8353e7e8, 0xfadf6ace, 0xb2075765, 0x96fb19fc, 0x14b01069,
-       0x972173d2, 0xd255f0b1, 0x7e69233a, 0xcb68f980, 0x10b2d32e, 0x05ba639e,
-       0x9b51f5ee, 0x4e03da28, 0x9d1a07a1, 0xfbb75e26, 0x6e099b2b, 0xf0e57804,
-       0xf8406280, 0x09e7563c, 0x33218bd2, 0xc945fbf0, 0x9cdfcf3a, 0xdc048104,
-       0x9b76b41f, 0x2b44f90f, 0x3941c806, 0x825906d3, 0x9d64b835, 0xdc91f616,
-       0xa8347b75, 0xd1bbb946, 0xe048ef78, 0x6c92402e, 0xa99474fe, 0x0fde8b26,
-       0x79c54fb7, 0xfa6a1537, 0xb2e29c36, 0xf1a03fea, 0x93ab66ae, 0xf83eebde,
-       0x5a662dcf, 0x20f02be7, 0x335af084, 0x4f8e1532, 0xa4839873, 0x93d4ca37,
-       0xddfb09aa, 0x8fa4003d, 0x970b2da6, 0x3a6dd200, 0xb138d7b4, 0x8c74429d,
-       0xd0bfbf43, 0xde843379, 0x9a74881a, 0x4334e921, 0x6692abea, 0x4946f595,
-       0xac841a92, 0xb374fd3e, 0x408cd1a4, 0xee0a497b, 0x3c53433b, 0xf9bfd835,
-       0x8fc516aa, 0xba3e932f, 0x951f4fb1, 0x3dbdf5c9, 0x019686ba, 0xff344266,
-       0x3d0a3596, 0x798b6254, 0xbe0fed2e, 0xe6557cc9, 0x429f1e8c, 0xfbf913ba,
-       0x825e8c62, 0xa653fb18, 0x03b935fe, 0xc58af0f1, 0x8454defb, 0x19b4e7bb,
-       0x70e7c59e, 0xfb933b11, 0xc631a7e3, 0x07b6c51e, 0x757a270f, 0xe215eb84,
-       0x07f50723, 0xd7b1f579, 0xa3b63f9e, 0xf18e98a7, 0x0d22dd4a, 0xcf2d99b2,
-       0xf0fb33ba, 0x92bf0fde, 0xad78b10e, 0xdbde7a97, 0x8e8d7ce8, 0xad8f0fdb,
-       0x979ed8b3, 0x48d749fc, 0xf8bdfdf5, 0x95e5e434, 0xe25e890b, 0x0c2e57ff,
-       0x4afdb2f2, 0x0c3e59d2, 0xfe783879, 0x51e92272, 0x21aea7c4, 0x6cb8f49f,
-       0x9f99679e, 0x06841c85, 0xc36e0a8e, 0xc12485fe, 0xf624aff7, 0xbc23cf1c,
-       0x3cf262df, 0xeb68db4b, 0x202a2f87, 0xd175b9fd, 0xe2803379, 0x2887e505,
-       0x84ee8a4f, 0xa00db1bb, 0x05ff113c, 0x72482152, 0xd0108662, 0x785e35be,
-       0xd319da9a, 0xfbc214f4, 0xddb35c65, 0x29e9eb41, 0xd7f0f7c4, 0x057d132b,
-       0xbf5ff1fd, 0xee1a7c11, 0xe6d1b0d3, 0x1c2f50d3, 0x7ee4e8d8, 0xb73746e3,
-       0xdcea3687, 0xfc913a6e, 0xaa1ff243, 0x169f16bc, 0xa5e657a1, 0x0330fd0a,
-       0x35c10ef5, 0x00609403, 0x23c66f79, 0x7288f2c0, 0x10a4dc10, 0x393cf0bd,
-       0xfa44f87d, 0xe888ee5c, 0x3b56ad43, 0x82a59321, 0x67985ee9, 0x09d1f7e2,
-       0xd59f3e08, 0x3fd23e7f, 0xfc8cbfaa, 0xefc38416, 0xb0b996f2, 0xb37c390d,
-       0x7adf885d, 0x4bd1e965, 0xf4b9fdc0, 0x43b95ebc, 0x8feb84bd, 0x1f84cf0f,
-       0x8f18bda2, 0xe2bc2184, 0xff045dcf, 0x100b1684, 0xb2b0d07d, 0xf21a167c,
-       0x5ca2b5f9, 0x8448fdc0, 0xef8c1bbe, 0xc4c3cb59, 0x23a0074f, 0x645ef08d,
-       0x7e49d9f3, 0x3f04b997, 0xdddb9578, 0x3937ae0a, 0x0951e2c3, 0xf1bee1b4,
-       0x2d7f11eb, 0xce21b819, 0x1cc9696f, 0xb713e7a2, 0xc93ef1bd, 0x08e6d7b7,
-       0xcc986cab, 0xf6111d9d, 0xe33c007c, 0x74927f24, 0x476877dc, 0x0e4e3f5a,
-       0x6abb9eb0, 0x6b5e9209, 0x09ec933d, 0xafd33ee3, 0xacbfd8da, 0x6e5117a7,
-       0x8f26270f, 0x42133d65, 0x63f2430d, 0x6d98e713, 0x3c23aff6, 0x7a3e65a0,
-       0xedfbdf0a, 0xafd20065, 0x543fdbd3, 0x312d0fc9, 0x40e80ee5, 0xa32a8f38,
-       0xf27da853, 0x6e7ce4e3, 0x127724cf, 0xec9b0e7e, 0xcefbed3a, 0x0474bd46,
-       0x8da9cbf2, 0xf9023a50, 0x368dade3, 0x746f4f6e, 0xa3667b72, 0x38a3db9b,
-       0x3af3fc4e, 0xbd7f138e, 0x6fd4e381, 0x4f6a71c3, 0x7ad43ae0, 0x489872df,
-       0xe5bc677e, 0xbc2da8d0, 0xfadb892b, 0x742c933b, 0x50c9c38e, 0xfc4fec67,
-       0x370c4e14, 0x2ee50780, 0xdb53fdd5, 0xad3f680d, 0x1c6502fe, 0xf754d4c0,
-       0xae3a6d5c, 0x8fe87b3b, 0x19f1c2be, 0x6a7ec3a9, 0x3b6f7843, 0x893868e3,
-       0xf5c7d2fd, 0x3f883a9f, 0x92a2244f, 0xb7643c24, 0xc7365179, 0xc418d293,
-       0x24c2f768, 0xfd19a7ec, 0xc8a5b9ec, 0x3a4a4b0a, 0xb005c0f2, 0x73e1b1f3,
-       0x25df886d, 0x513fff76, 0x9b6812df, 0xfa9d3a53, 0xbc927010, 0xcb20e62b,
-       0x7d2510fb, 0xadbfda11, 0xd4c4ff0e, 0xabc07f08, 0xf48d21fc, 0x02af44c3,
-       0x77a674ae, 0xf7d2a470, 0xd5b798dc, 0x15313651, 0x2ed7f7f9, 0xc269f995,
-       0x741bc534, 0x635f97f4, 0x7af384de, 0xe26fd129, 0xd4b559c5, 0xe2e3982e,
-       0x4dd96fbe, 0xa5ff24b5, 0x5fbd6b8e, 0x5c87efc2, 0xc547d666, 0x638bce1a,
-       0xe3798d17, 0xffc8c991, 0x0c4b69ee, 0x7d7c4b3e, 0x84935fd6, 0x567732fd,
-       0x34752aa1, 0x6bb5df70, 0xbf978d1b, 0xe572c0de, 0x59e8f249, 0xa5ed8ac4,
-       0xd33e3869, 0x24c278a1, 0xa93ed32a, 0xa771a34d, 0xcdb421e2, 0x553b8ef4,
-       0x5423e344, 0x9fea4ccf, 0xd89d4bd5, 0x4e66d19e, 0x66f384bd, 0x6c78a4e7,
-       0xf099def8, 0xff10ae8f, 0xf249ccce, 0x1714e824, 0xa4ae9f04, 0xa9eac7be,
-       0x8f1ce9d6, 0x3ad32495, 0x6131e2ba, 0x92d6febf, 0x147045ff, 0x514052fb,
-       0x91a5dc68, 0xc7e4fb1f, 0xe275293f, 0x0aa1fabc, 0x099cfc90, 0xe091fee7,
-       0xa89ad99f, 0xf5402027, 0xbd296716, 0x9c516f57, 0x2befb89b, 0x5181f9a1,
-       0x5c79fd66, 0x769de4f7, 0x6fe507b6, 0x745fb3e5, 0x6cc1cef2, 0x9adfca17,
-       0x49ed4c56, 0xcbdbf093, 0xc39f2adf, 0x930826e3, 0xebbf2952, 0x1dbdf81f,
-       0x4d293f25, 0x0c4ff5c7, 0x416eb173, 0x116a953a, 0x83e70d7a, 0x55dfef42,
-       0x945bf3c1, 0x8f3a3f01, 0xa7e4aff3, 0xff715a14, 0x5109e959, 0x710ce7f3,
-       0x8de7f545, 0x45aa5818, 0xfcf2b1d8, 0xadfea8ac, 0x88e94a45, 0x69bef988,
-       0x45fd5109, 0x11d2aea5, 0x2b6ff311, 0x5fd5181f, 0x54565b72, 0xb269a67f,
-       0xa11b1fd0, 0x7dc854bc, 0x9bfb2979, 0x0a87acd9, 0x1bee629d, 0x8e3f7e38,
-       0x7f09b617, 0xfe85d0aa, 0xb4a5d214, 0x80fd88ad, 0xc68f7c36, 0x8f52ec8b,
-       0x3ddda005, 0xfc80ec91, 0xf62fe209, 0x6677658b, 0x6305fa3b, 0xb768ae89,
-       0x752fe023, 0xfaf1db44, 0xcc27e144, 0x0bad7f01, 0x75a739e9, 0x6557fb1e,
-       0x6145d5e9, 0xbf467c20, 0x2a370b1f, 0x13779dd1, 0xac6ab61f, 0x890ce737,
-       0xd4adafd9, 0xf48c7ec1, 0xb7c8e6ef, 0xe0217d8c, 0xc6ff276d, 0xffb18738,
-       0x4733ceb5, 0xe17ec69d, 0xacd73adf, 0xa9a5859c, 0xcf5fe171, 0x9c2c4cfe,
-       0x4f32a979, 0xfb15fe81, 0xeca9ad85, 0x7a4fe22f, 0xf0c13f3c, 0xcf51ca7f,
-       0x9cf522b9, 0x585f4943, 0x673d6d70, 0xff2d7bac, 0x78d758cf, 0xde54ea1f,
-       0xf7bf78df, 0x7fc4aeb9, 0x27e71bbe, 0xae9e79c5, 0x5cfe7fc4, 0x9a19fcf4,
-       0x7940e35e, 0x278a0e3e, 0xa93f7840, 0x959ae46b, 0x52d6f59c, 0x5fa1f65b,
-       0xf670b723, 0xb52d40f9, 0x27833b53, 0xb9fe78ad, 0xf94eaa39, 0xea2fc307,
-       0x0aa56717, 0x55f8e47f, 0x78e3aedd, 0x53b7407d, 0x88ff51dc, 0xaaf8a76e,
-       0x28730bde, 0x370ef48e, 0xc438a7ad, 0xf62d879b, 0xfa154def, 0xdf7c857e,
-       0xfea90f68, 0x857f0415, 0xf251e3ad, 0xe9bf2a49, 0x1c5f10b1, 0xbf2f7f27,
-       0x5c77bfbf, 0xbf683a0b, 0x1d048fe3, 0x7e7d08be, 0x22defebd, 0xe20ca662,
-       0xa917c553, 0x096c4a4f, 0x51fd48be, 0xf54574e6, 0x83ff93c7, 0x0f76cdef,
-       0xae6f7a8c, 0x0f35159e, 0xf21cd8fd, 0x902c6a87, 0x353e91a3, 0xcfc87a25,
-       0xefe3c58b, 0x0e3df9e5, 0x6051b927, 0x7f55d74e, 0x29e4fb1c, 0x7d8bf811,
-       0xc4553dbe, 0x9ec88373, 0x52273ae3, 0x556b6e75, 0xd0e6709f, 0x887e267f,
-       0xbaac63ed, 0x95c3d68c, 0x1e77c4dd, 0xba0ae9bb, 0xe3d2f0e0, 0x686ae7f3,
-       0x4de33dff, 0xfb1c38ff, 0x215f1ec7, 0xfb4d53fa, 0xfadfb1b2, 0x7fa27df8,
-       0xd9bc69a3, 0xb819ec83, 0xf9296e7f, 0x7fbee90b, 0x9b75fa27, 0xd4155b1d,
-       0xa8099503, 0x4cd5b0d7, 0xf7a6140a, 0x2ddbc7c5, 0xc0915f68, 0x175e6cc8,
-       0x156ec0d2, 0xc26574f1, 0x13d920d0, 0x13abd8ad, 0x0c132ade, 0x9264777a,
-       0x09da879d, 0xdd9d7151, 0xfbe1ef82, 0x0bff3665, 0xc9c26f82, 0x87a5ea3a,
-       0x200d960e, 0xea9138fe, 0xede43c64, 0x7d26ea9b, 0x21edf085, 0x01fffefb,
-       0xf078e6be, 0x3ec59ad5, 0x2579f59d, 0x86f38f64, 0x3e947921, 0x3a6a15fa,
-       0x21084f3f, 0xeebfb0ef, 0xb1fe5375, 0x90f165c6, 0xf2427eff, 0x35b6f5ef,
-       0xdaa18f32, 0x29a91f05, 0xb17bf5a6, 0xcff25b7d, 0x6a2fb919, 0x910ba1be,
-       0x33d9c03f, 0xe8815174, 0x6aa87f13, 0xe1f90f61, 0xe490ff3d, 0x83f9f8a1,
-       0x183f8144, 0x8fd1f3d2, 0x777bf9f1, 0xf1b679e7, 0x65a78173, 0x0e9aecc1,
-       0x06b38fec, 0xe3fca06f, 0x47ff34a1, 0xad3b8784, 0x87cc91c1, 0xb449f58e,
-       0x8e05e28f, 0x0ff88c53, 0x32dd3ce3, 0x705c7fbc, 0x46c1fded, 0x64e96576,
-       0x7f637781, 0xe88db1c4, 0xf124def1, 0xe10780dc, 0x303e26e8, 0x0785eae0,
-       0x8f393886, 0xd4ff2200, 0x2e8be325, 0xa7ec8f5a, 0xdc7910ea, 0xff38983f,
-       0x8ac24552, 0x4de77dfd, 0x791a0f1c, 0xfb1022e0, 0x49b53e4d, 0xf803e065,
-       0x96a2513b, 0xcb5c695e, 0x7684fdf1, 0xf6fe262d, 0x2a9d3db2, 0xd5a9bfdf,
-       0xf6a0e25f, 0x5379e8fd, 0x093f1c65, 0x59c52a82, 0xc6623b93, 0x467fe71b,
-       0x18bd4feb, 0x4d293cfd, 0x3041c3da, 0xb24f3228, 0x974dc641, 0x10a7664f,
-       0x2b186b1f, 0x8b0f48a8, 0xd4a4c2ae, 0xb0d33d3e, 0x4959e711, 0x2db8da9f,
-       0x8fbceb38, 0x88dc69f6, 0xf49a3f0c, 0x435b9baa, 0xc2ce0aee, 0x623630bd,
-       0x0617291f, 0x2fbf2f1e, 0x23ae38f0, 0xb0d397e7, 0x43356e6f, 0xc3c3ef50,
-       0x0c2f8914, 0xbbfe38df, 0xf6c1d17c, 0x62db626b, 0xead9e495, 0x711e8136,
-       0x113d04be, 0x6c7d08f4, 0xea8d49cf, 0xb59e92ab, 0xca7ed109, 0x924fb978,
-       0x7ad45067, 0xd062bf86, 0xacea50f3, 0xc663f256, 0xdfb1563b, 0x3b293292,
-       0x93a2fd6a, 0x042ef8d1, 0x63e2979f, 0x71c087cf, 0x5ab3c4c0, 0x29327f94,
-       0x63f983bc, 0xcfd187d2, 0xee8f9ca7, 0xfcc9a697, 0xaedd2c56, 0xfb184f85,
-       0x7fe969cb, 0xde5d3e3f, 0xcda67c68, 0x8667c689, 0x039f1a2f, 0x6be34596,
-       0x1f1a3fa0, 0x898d5783, 0x7d61bf1a, 0xd87f5461, 0xcd44a70f, 0x198342cf,
-       0x75be1fd9, 0x91fcd45e, 0xf545163b, 0x67753f47, 0xe0dcfcd4, 0xbcf1a88a,
-       0x2efe6bdd, 0x368417fa, 0x3427cd44, 0xfe87be9b, 0x4bfe3637, 0x53ff7ed4,
-       0xa18daff4, 0xe7d256ff, 0xa85e8813, 0xecfb0b37, 0xa425b919, 0x6f4d5d3f,
-       0x9b79437c, 0xf9ceb140, 0xf03cc0aa, 0x2fd8e0d4, 0x7a429f54, 0xdaa2306e,
-       0xd6a37a84, 0x1ec8ab04, 0x71326a3c, 0xf390d31e, 0x3f84d317, 0xc89a62f2,
-       0x7b78197b, 0xd922ed1a, 0x43ea5541, 0x248efa73, 0x935453f2, 0xfec9da09,
-       0x1fd61e69, 0xbe101ce7, 0x0755f719, 0x4ac5e701, 0x982d2792, 0xbea8fc88,
-       0xa9fc72a9, 0x8e83f20e, 0xe4e6a4f6, 0x9f8453ce, 0x4e9b0e2b, 0xfaa6ab7c,
-       0xf0df6403, 0xa1e7a19c, 0xdef39fbf, 0xf1495846, 0xe65fd196, 0xe699bf5e,
-       0xe67bbb2f, 0x7b7f8a48, 0xacaddf9f, 0x43a08d2c, 0xc51739e4, 0xa40eabf1,
-       0xd867fb09, 0xdc7ec313, 0x3a6bd569, 0x538c3ed0, 0xbb407d85, 0xf10d2071,
-       0x88f281f1, 0x0169f859, 0xed1f9d33, 0xb827df2a, 0x80df21d0, 0xdd9f4a6d,
-       0xe643bfd2, 0xda3b20fa, 0x00937d6f, 0xf74438a3, 0x1de33df0, 0x955dfe86,
-       0xecbbf8cb, 0xf97f9e88, 0xaf02e1fe, 0x90f620f7, 0xe22ce70e, 0x17fc063c,
-       0x42fe5ea5, 0xd24ee5ea, 0xebf911c7, 0x2676bb55, 0x2e7e7f91, 0xc6e3f847,
-       0x3a49dff3, 0xe54d2eff, 0x9dddaff3, 0x047cfeb0, 0xae422ade, 0xe3557ea8,
-       0xf991f5c0, 0x39c6b5cd, 0xe7468afc, 0xa8e52758, 0xf923b5a2, 0xfe7f604e,
-       0xb75c34c3, 0x7b95d772, 0xa6fbd00e, 0x67614c9e, 0xd2dfbc03, 0x82e380f7,
-       0x28817fa5, 0xcd33b6bf, 0xa67570cc, 0x09613889, 0xbbe44e36, 0xb803e825,
-       0xda637da8, 0x7c3fe22c, 0xbfb0561e, 0xa4cc15a0, 0xb3fa16bf, 0x33f484cc,
-       0x3f6779e0, 0x69cfed1e, 0x1b73ef3a, 0xfb7ef8f8, 0x922a7bdd, 0xd6340fd8,
-       0x8141d633, 0x3def3f20, 0x499cc057, 0x0ae99f79, 0x9fb817fb, 0xeefb9e8d,
-       0xec99bc1e, 0xbbdfb1b0, 0x0ef4bfe0, 0xf022c5f2, 0xfac6baf0, 0x1134d740,
-       0x4b03f97a, 0x44ed1d2f, 0xa66d0dbf, 0x3685e530, 0xbdf2b39c, 0xcf75774a,
-       0x9c230fcb, 0x66f9af1f, 0x7f7082bf, 0xbfe7bcb4, 0x3bf3e00e, 0x4741529e,
-       0xfdd9f1be, 0xbc447a5a, 0x2bfeee79, 0xafe86f2c, 0x2924ff3c, 0x1eac97a5,
-       0xd60f9392, 0x322a34bc, 0x9f4e485e, 0xf74e9099, 0xe2d2933b, 0xc6c46fde,
-       0x3f886ba5, 0xf6757e59, 0x5cbe0d4b, 0xc372f92d, 0xf9f9a30b, 0xf3dea486,
-       0x2af3fe88, 0x3436c1e7, 0xf1af395b, 0x3587e48e, 0x31337e2f, 0x8f57cf32,
-       0xa95ba97c, 0xf74b7275, 0x09fa3aa6, 0x1e5e4efb, 0xeaab71cb, 0x1e73a2cf,
-       0x3269fabe, 0xf9bdf7f5, 0x6e079f2d, 0xbbf83ebb, 0x78917911, 0x79ea4aae,
-       0xc54af497, 0xf94eab01, 0xb90392ac, 0x7ec2ee27, 0x1fea2b65, 0x5725cf3c,
-       0x29a7b1c7, 0x00a83b1e, 0xc32ab7e5, 0x2be4ac09, 0xe520941b, 0xee34d6c3,
-       0xfb1832dd, 0x1616ea6b, 0x2556bb11, 0x59567d0b, 0xb13704af, 0xe9873e1f,
-       0xa365285c, 0xbfee50e4, 0xd778e3e5, 0x85feb171, 0x3cf6b08d, 0xf55d9dc6,
-       0x38205e5f, 0x395a35d6, 0x292176cf, 0xfb8c196c, 0x84abda5e, 0xdc9f7a02,
-       0x1c44b976, 0x98f42ab6, 0xf55df685, 0xe411c2dc, 0x381d7636, 0xb93d216d,
-       0x59b1e1aa, 0x309179f2, 0x8b9641ff, 0x9595bbb5, 0xd5ac7991, 0xa4420ee8,
-       0x02f842fd, 0x40eafb13, 0x2cfa494e, 0x435e1a6b, 0xb6bd42e8, 0xf58569ff,
-       0x97e242da, 0xf9ef0e0f, 0xdf686fdd, 0x923dff83, 0x7d745ff1, 0x805f07f8,
-       0xb94a8bfd, 0x633c5c0f, 0xb2b2f8a1, 0xde217cc1, 0xba6352fd, 0xcfda1eef,
-       0xfd638f88, 0x10162dee, 0x10d93ff7, 0x82ec9e7c, 0x1cb2c7a3, 0x9a57f9e1,
-       0xce68f080, 0xec0acb1e, 0xc8ce48db, 0xc11db85e, 0xbef57178, 0x84f18d74,
-       0x78fac4b1, 0x3921a0f7, 0x5877a25e, 0xe9579f28, 0x5f10b4ee, 0x173f8657,
-       0x9f8dfff7, 0x89c6f2cc, 0x574e5fb7, 0x273f33a4, 0x6437de4a, 0x30b9618c,
-       0x90c3daf7, 0x60bee58d, 0xa9d90f45, 0x3b91070d, 0xbfb7a214, 0xec0ee087,
-       0x7ce9d04f, 0x9f3e0725, 0xcfb111d8, 0xf47ca51f, 0xf95e59e6, 0xf099ac64,
-       0xb193efb9, 0xf3df525a, 0xaac74cae, 0x97997978, 0xdedd85d3, 0x18bbec9c,
-       0x9e09072d, 0xd95bee30, 0x147be764, 0x2d2d8394, 0x70729145, 0xc45daac7,
-       0x07aa4de7, 0x1b2a0225, 0x79abfa17, 0xc887927e, 0x0cce36a3, 0x4eaa1f10,
-       0xfc27f31f, 0x289bf715, 0xff508fef, 0x3ff74dcd, 0x39ac724d, 0x1e646560,
-       0xf1d4d2a4, 0xe88516ab, 0xa26bc3ba, 0xf5810afd, 0x75f0ea96, 0x94553c70,
-       0x7bdc53a9, 0x202cc274, 0x59bcfd3c, 0x39afbce1, 0x8b35bfd5, 0xe55c7be8,
-       0x2fa396f9, 0xbbbee804, 0x11141c6b, 0x7f79c67c, 0x2a0c2e3e, 0x00b9b3ae,
-       0xe6edb43c, 0xc4dd4b83, 0x38cf3fbf, 0xdd867ec6, 0x2bd20213, 0x503fe835,
-       0x1f9ec7de, 0x093ad30a, 0x1522be39, 0xee9359f7, 0x58b4be64, 0x27ca1efd,
-       0x36fb203d, 0xe08ab7cd, 0x8a27a5b3, 0xf5c87bf8, 0x48baf9e5, 0x6f74cdfe,
-       0x4b7ce7e9, 0x69f05997, 0x71c00dd7, 0x4cfcd722, 0xe32f21a6, 0xb83b06cd,
-       0xd6546aad, 0x44d7da46, 0x79e8dbf0, 0x1ea5c1d7, 0x2d9cdf82, 0x91333df9,
-       0xff7622e5, 0xa99f888f, 0x62b4c0ce, 0x99e1166b, 0x9ff7a6f0, 0x7be4a1f7,
-       0xf9a01f03, 0x115e4873, 0xfcbc6f54, 0xf8bd3f92, 0x7375d12c, 0x95c72faa,
-       0xc2bcd7cf, 0xc6277629, 0xff9c3b95, 0x31b7c901, 0x89f095bf, 0xfcd16fef,
-       0x51efc236, 0xc5b35f89, 0xfe593ba7, 0xdfed3a7d, 0xf141be7b, 0x3c8df7cf,
-       0xff6c96df, 0xcfef9ef7, 0x54e67cf2, 0x2f5a37e4, 0x399e7819, 0xfe201839,
-       0xa2824dab, 0xa8f8f84d, 0xe49b966b, 0x6f91cb6e, 0xd7bc9286, 0x40dc7926,
-       0x9be6b179, 0x6fdc9196, 0xf3277419, 0xe42f17ff, 0xfb11aa16, 0x7f17a724,
-       0x2f3be745, 0xe2c5b1cf, 0x7c73a1cf, 0x9c69cf2c, 0xefba496b, 0xf911e92f,
-       0x7e921826, 0xd7b3fc5d, 0x7194d7b8, 0x61da479e, 0x8f38f38c, 0x5c890dd8,
-       0xfa57b67f, 0x98f81ae1, 0xd1e0ec7f, 0xc2f2bfd9, 0xa92baa09, 0x36c13169,
-       0xb5253e3a, 0x92fdee22, 0x0c119355, 0xb2186d7a, 0x8d3435d3, 0x39d89f3b,
-       0x3ee116af, 0xf8550108, 0x0cf9d169, 0x255e2af0, 0xdaf18f32, 0x63cbeb9a,
-       0x21afe33c, 0x63cd8d79, 0x969b0e4c, 0x23ae525b, 0xbcdaf19f, 0xd18cf9b8,
-       0x5171d119, 0xc0ce8641, 0x7f047285, 0x4189c286, 0xf1833791, 0x26eabf94,
-       0x9fe3855b, 0xde5999e3, 0x9b1cae95, 0x13e0ed0b, 0x3adb6c4f, 0x8470e50d,
-       0x6bf503c0, 0xf1f5c988, 0xe6f507ec, 0xc31b5e47, 0x3dea387e, 0x4e02f395,
-       0x1d0c4b09, 0x137fd08b, 0x2a27a541, 0xf63e12bf, 0xdbf1326d, 0x2dfd549e,
-       0x9b4f4fa2, 0x092875ca, 0x15c5875a, 0x900eee47, 0xe076807f, 0x3e84339f,
-       0x7b8a35b7, 0x65ee9b4b, 0x74e0993d, 0xe423538e, 0xd8432f24, 0x1f638aa5,
-       0x2ca0b50c, 0x4c9d325d, 0xd7f5c7ce, 0xa64fafed, 0x73dade34, 0xd2a44f6f,
-       0xff353b9f, 0xff3c0c82, 0x51aeca17, 0xb75bf236, 0x7e12c706, 0xae6ce142,
-       0x20d02ccf, 0x87f615a0, 0x3c29eaa7, 0x9504ba14, 0x5b71a54f, 0x257e34d0,
-       0x58555ff1, 0x30f6979c, 0x6dcc8aa3, 0xd5dfb854, 0xeb4a9358, 0x79b6fd55,
-       0x97afe910, 0xf39f8432, 0xf13cd5e2, 0xcd1a06be, 0x25c33fbf, 0xa2682a99,
-       0x324be37c, 0x5575d94f, 0xfec679e5, 0x55338d05, 0x7e41f227, 0xce11c778,
-       0x7559368b, 0x73c26fa2, 0x94d1f020, 0xd5687ec0, 0x7640d9e1, 0x1e05dbaf,
-       0x24f7c705, 0xfc447cf6, 0xd56cd3d0, 0xc1373ee9, 0x715203b9, 0x1eb23dfd,
-       0xb619172c, 0xdcf7d1de, 0xe9a12fd8, 0x24439497, 0xe57be0be, 0x4c076d04,
-       0x3be24477, 0xc959d849, 0xc3127b57, 0xe967ba26, 0x59efdf41, 0x4e0fab86,
-       0x380d7de0, 0xec0ed973, 0xf85cf4b1, 0xe5c33a71, 0x05c83e24, 0x8d342701,
-       0x26af49d6, 0x8e7cbd38, 0x09eea704, 0xaae1fd28, 0x208e8b1a, 0xa4a3cfca,
-       0xc9f4a6cc, 0x5f625577, 0xb0b286df, 0xfca41b27, 0x9d2b6eb7, 0x8547d916,
-       0xfdefa933, 0xf8e278ff, 0x9c21dab6, 0x48a80bff, 0x49b63b7f, 0x214e74a9,
-       0xde122857, 0x0781428c, 0xdbb40baa, 0x7cef78c4, 0x2a4773e4, 0xe79e7fdb,
-       0xf3ed3ab1, 0xf85e58b2, 0x0ff0d17e, 0x17c2521f, 0x76d2466e, 0xc94be63e,
-       0x9a7573c7, 0x875c3c8e, 0x3cb8fef3, 0xfd8c2a34, 0x79ffab16, 0x3f57cfe2,
-       0x80bdb15c, 0xb31eeff4, 0x4ff49ca7, 0xf671e047, 0xeb345fcb, 0x0ee422db,
-       0x7264f486, 0x3ecc61dd, 0x3d36e755, 0xf776fe4e, 0xfba74541, 0xcf736ef4,
-       0xb2bb8250, 0xd50b33e9, 0xfc1d5663, 0xb2ebfd84, 0xda5eff4c, 0x3563526f,
-       0x864dcfd7, 0x873f5c1d, 0x20eb917a, 0x4fa16e43, 0xf51d9f2e, 0x1d04756c,
-       0x06f293de, 0x6461fe3d, 0xbca49abf, 0x1c38a61e, 0x772dfddb, 0xf7f5a70c,
-       0xf180fccb, 0x191c355e, 0x04df784c, 0x3c6b71af, 0x5c6a0eef, 0xaef79cbf,
-       0xc46f5eed, 0xfe52d3fc, 0x56fdcb4f, 0x20dffa67, 0x7cb6d778, 0xc2d2a16a,
-       0xa1a1f3aa, 0x3486f714, 0x4719c53d, 0x6fcaf48f, 0x69553c8c, 0x5f9a163d,
-       0xaf581175, 0x536bbd20, 0xbd2f7e90, 0x396638db, 0x348fdf3e, 0x8b3b2149,
-       0xe3d92af1, 0x60df66fd, 0xcefd5f9a, 0x8f4963d7, 0xf020241d, 0xaf375f7f,
-       0x4378461d, 0x244e2ffe, 0xac0bdb39, 0xcd390cd7, 0xf7c53927, 0x8bff89f3,
-       0x7acb9fa8, 0x7da58f79, 0x7ee5cb1e, 0x225c9013, 0x203cb3ff, 0xdfc93bff,
-       0x3ca277cb, 0x59a3fbf0, 0x9bb4f7ce, 0xa337ecbc, 0xfdc91f5e, 0xdfd4c5e2,
-       0x64ea5ed3, 0x843aa739, 0xf0d79242, 0x04275e11, 0x45f2d740, 0xfd22f80a,
-       0x648cbcff, 0xf1242f71, 0xd8433939, 0x9e8e5083, 0xd873c1e2, 0x3e4a3555,
-       0xe8a5ec22, 0x9a5a7b4b, 0xbf6d97f9, 0x26524698, 0xda5384ed, 0xd678ff49,
-       0x6d28fffb, 0xa7d786d5, 0x73c3a82c, 0xf2a5386e, 0xf71961f8, 0x1c9f2585,
-       0xb21af991, 0xa89a7a1b, 0x13e7a61f, 0xe5f54fb0, 0x4bebbd13, 0x9a4d1cc8,
-       0xb528e3b3, 0x12a17c53, 0x2da6db72, 0x166a3f6b, 0xfc479e62, 0x6e6470d7,
-       0x75e3d51e, 0x0242b39f, 0x6df0d882, 0x222f47cf, 0x8c3e1e1e, 0xa7638ff8,
-       0x7fcc38f0, 0x060d7fe8, 0x6ef1ff77, 0x4091ea45, 0xc7e27cd2, 0xafb506ae,
-       0x2254808f, 0xfddf5363, 0x007b7da4, 0x677fe76d, 0x2267077a, 0xf00ccf3e,
-       0xfa7ddb73, 0xcb124cdb, 0x5c4567fd, 0xe6f160df, 0x6434ff11, 0x871ba863,
-       0x2299ad4f, 0x856453ef, 0x379cf7b8, 0x18390a67, 0x0aed8015, 0x33aaebc7,
-       0xd4bf7488, 0xe82d7aa0, 0xc0845d2f, 0x6fa4a992, 0x01f75e64, 0xfc5e3f90,
-       0x283cfa45, 0xdf900fbb, 0xc1eb7682, 0x11d6c45f, 0x316fd978, 0xeb0058f2,
-       0x2b5fc44d, 0x0ff8149b, 0x67aac5c4, 0x93afe7a2, 0x1babf275, 0x8c1b1d77,
-       0x5cf35d74, 0x2df938cc, 0xe211ff7c, 0x5d5d7878, 0xcdc33d74, 0x197fd299,
-       0x7fc9c30e, 0x3d62be41, 0xd5a0d661, 0x60ac7c8a, 0xf6224314, 0x0be04992,
-       0x67cb2bf5, 0x8a6f61be, 0xb9ea5e85, 0x94a75c04, 0x94743bbb, 0xd4a681ea,
-       0x8f687965, 0x9f189a29, 0xee2598d2, 0x4aa0b4a7, 0xbc930c75, 0x77ec59fe,
-       0xa967bc07, 0xd49564de, 0x5fc4e097, 0xd3c8fbca, 0xddfe92af, 0x9d6c60ea,
-       0x9553c0a8, 0x8219379c, 0xcaefb435, 0x69dea2dd, 0xf9e8eeed, 0xeb4f1255,
-       0x8c7d3a9e, 0xa11585d2, 0xa7897198, 0x3a98c6aa, 0xdc38b116, 0xadef299f,
-       0xf5fb7d64, 0xd1fc5bd6, 0xb78dfc2c, 0xf8c63ae5, 0xef914ce6, 0x1063c4ad,
-       0xd505d77d, 0x2ad1f120, 0xfc2c9025, 0xc72c705e, 0xb067ddf3, 0xbdcfac81,
-       0x3ee9e25f, 0x7e7c3fc9, 0x19e2bf7c, 0xfdc57df1, 0x7f868b3f, 0x832cf80d,
-       0x0d83f9f1, 0xde50b03f, 0x56df9631, 0xffd999d5, 0x13f1235d, 0x7a6b5fcb,
-       0x858767f9, 0x7f2c5bec, 0x6b95fa55, 0xf6fc2fc0, 0x0df85bff, 0xcb91af3a,
-       0x398735ac, 0x09f6b53f, 0xabf943c5, 0xf7ab9d6b, 0x7f7cf23c, 0x359eb9ef,
-       0xc6063de8, 0xa4e7bd30, 0x63bd175d, 0x96bdedfd, 0xe726bcde, 0x66b72f05,
-       0xe0dd3e73, 0x6675d8ab, 0xf67dbf49, 0xbd7fc253, 0x276258d4, 0xa4fba3ff,
-       0x9ce8a3c9, 0xc02e4caf, 0x566f8ff3, 0xee91fc81, 0x033be1a6, 0xa9e17f08,
-       0x5f94c5a2, 0xed0a7f1f, 0xb707dd13, 0x0257fd16, 0xd27b07df, 0xb667ee48,
-       0xbdfb488d, 0xfb61d783, 0x70b27dde, 0xe9e93967, 0xb445a593, 0x54e382ae,
-       0xed285e9f, 0x42c9f554, 0xbd84477b, 0xc8a64dfa, 0xff716fcf, 0x1b8a51fe,
-       0x7b35ef66, 0xdb323f28, 0x8094dfec, 0xa0be15f0, 0xb771aa78, 0x9e47ed63,
-       0xbe5175a4, 0xf38acd28, 0x8d08e9fe, 0x1851ed57, 0xb2a6eefe, 0x3f643dbc,
-       0xec87aa83, 0x7dd37762, 0x1f920ff9, 0xfe40fcd4, 0x1dfb117d, 0x66fa154b,
-       0xb6660df6, 0xec839dd7, 0xbca72ebf, 0xeb1777a8, 0xfb43ce8d, 0xc37dfc2c,
-       0x78dc051e, 0xa3ee63ce, 0x3a1e132f, 0x50b69c0f, 0x70d25010, 0x4711d2da,
-       0x25ed1b7f, 0x9cc2f30c, 0xe161ddaf, 0x7ffdcdfa, 0x2b79d0b0, 0xf384fb9f,
-       0x7e286b6f, 0x19ef3f20, 0x3a77bf95, 0x85aafcda, 0x4eb2b4f8, 0x91590181,
-       0x271e66e3, 0xcffd4afd, 0x369e84ea, 0xe4857ff8, 0x0dff8377, 0xf5215879,
-       0xe35b7dda, 0xffa1bbf3, 0x96ef041e, 0x03deb841, 0x0eb9cb75, 0xd11d81e9,
-       0xfc5257f3, 0x17cd237a, 0xa9f2befc, 0xbdd5f1e8, 0xfd601e7c, 0xbf47ab1f,
-       0x2e7ff433, 0x5f9f12e4, 0xa618af0e, 0x7d7d3ca1, 0x8830cd7a, 0x293caf93,
-       0x6ec306fd, 0xd89b0e5f, 0xebcec5ee, 0x2162bc6a, 0xfad55b7b, 0x6773f627,
-       0xf4c97d35, 0xe16a6f28, 0xc05bd97a, 0x79f08ebf, 0x49dd934b, 0x877976fe,
-       0x9af303d0, 0x42a0c1ac, 0xa25aa1e3, 0xf161f773, 0x90e049bd, 0x4816fec2,
-       0xe252b8bd, 0xe3c4a575, 0x06e38c4a, 0x8c8c7d53, 0xbc652be3, 0xd7673abe,
-       0xa9292a31, 0xdaebe394, 0x1e13268e, 0x5bd081e7, 0x6f4242f3, 0xec31f419,
-       0x40beac50, 0xd10f770b, 0x95936d77, 0x4be7d6eb, 0x0ebf35bd, 0x5fd296f5,
-       0xb40f747f, 0x7ef1fc8b, 0xddac7701, 0x9e886cad, 0xfc201aef, 0x7fd2cbd8,
-       0x4d101c2e, 0xb01ef297, 0x9e7f7e53, 0xfc827aae, 0xfb46bb56, 0x7e458eb7,
-       0xf55bf5c3, 0xeaf129e1, 0x4df68cb5, 0xfd181719, 0xc3679405, 0x0ee721f9,
-       0xffdc6447, 0x7f84039f, 0x1ab266b3, 0xc446ba20, 0xb30a0b49, 0x7349c6e2,
-       0x8637f409, 0x71b3f7dc, 0x77927191, 0xb7e228d7, 0x2cef757f, 0xaaa6baa7,
-       0xba2fa13a, 0x29bae126, 0xfb03f7e4, 0xd67555d1, 0x5533c520, 0x7dfc2fc8,
-       0xc909f11a, 0x46529363, 0xc671827c, 0x42feb4ed, 0xf3c4eaba, 0xfb446c2f,
-       0x2c2fcb8e, 0xabf992fd, 0x3738846d, 0xbc406de2, 0x3788c3b8, 0xbf0aaf2a,
-       0xa95e78d6, 0x51dc7075, 0xb5ea24d9, 0x337c8e1b, 0xede10b34, 0xd0f3fe6e,
-       0x3e4f54e5, 0x86e7d840, 0x54a7d0e2, 0x1ef5f457, 0xb5ff5c5b, 0xb52bff57,
-       0xe6950f2c, 0x6bf64c8e, 0x791fa20e, 0xb7d1ea13, 0xa538e0bf, 0xbdc248e1,
-       0x5aebcf94, 0xfce61fe1, 0xc3553a1e, 0x3783f626, 0xe4b72d41, 0x8dfa451f,
-       0x4ea29d2b, 0x3f6941e9, 0xf208ffa9, 0x773883f5, 0xf97f6146, 0x8549f437,
-       0x10d5ebe4, 0xe95532d8, 0xa42a07af, 0xdfcdacdc, 0xf6ae85b5, 0x0aa7fd63,
-       0x31184f29, 0xf58cbdb0, 0x8633fe9f, 0x4edfab5f, 0xbbb8ff64, 0xae52754d,
-       0xabfbf119, 0x6227e441, 0x271d905c, 0xe485fb5f, 0x7f794ecf, 0x65493d5c,
-       0x8b2699fc, 0x10b7f0d6, 0xdd37cc8f, 0xb2411da7, 0x5f87796f, 0x583e26cd,
-       0xdefa3bbb, 0xe7e8e889, 0xc8a0b1ba, 0x7cec8547, 0xbf8c6517, 0x31d5f874,
-       0x6fd56fc4, 0xd04a3b7f, 0x96519be7, 0x67c36bf4, 0xe2228ab4, 0xe2229366,
-       0x475afde6, 0x556bc532, 0x645f5507, 0xef41bf3d, 0x813ca597, 0xf503f226,
-       0xabe67403, 0x1fc126ea, 0xe2d166a6, 0x7e444bfe, 0xf7fbccc8, 0xbe462f1b,
-       0x067b1ef9, 0x40f21704, 0xf987b995, 0x89b4eaaf, 0x7d3aa9e1, 0xc4447339,
-       0x775a017b, 0xeabfe900, 0xc4fac075, 0xe76fa40e, 0xd891f7d3, 0x027eff9f,
-       0xb2c761fb, 0xfb8b97b7, 0x7f48152f, 0x9af6fc3d, 0x60f691d1, 0x2f7100e2,
-       0x3707840e, 0x10bf3f79, 0x6c3c4bfb, 0xbf324582, 0xaf79f820, 0x2e309b8c,
-       0x9c40737b, 0xfd7aecb8, 0x2b66eae9, 0xeab9fe50, 0x19d72b03, 0x92bcdd7d,
-       0xeab87ee3, 0x06fa4d1f, 0xa91bfefc, 0xcaf0f87d, 0xebfcf4d1, 0xe46fabc3,
-       0x29b2a97c, 0x2011cf2a, 0x5fe4dcf8, 0x5deef57d, 0x69b67fe4, 0xb6149fec,
-       0xee977d9d, 0x9835f769, 0x8ad1dbf9, 0x067613fd, 0x2aafc892, 0x11df4f9c,
-       0x98d56bed, 0x32dfd0ff, 0xfb3b2bfc, 0xd88aa757, 0x7c75c2bf, 0x4e8b6e41,
-       0xa7bad394, 0x9a688b8a, 0xd7a4e382, 0xe57f93c6, 0x0cb7f3e8, 0xf8933e78,
-       0xe0496eec, 0xd9028bbc, 0x4460cf82, 0x1aebdc14, 0x64ff675e, 0xf51aa35d,
-       0xdef188fd, 0x7b88065f, 0x3e0cef87, 0xe65e290b, 0x5da2bda3, 0x932fb8d7,
-       0x1cd6b1ce, 0xaea93e62, 0x3df18b33, 0x07ba05a2, 0x411fc09a, 0x273f0807,
-       0x65d211e8, 0x8438259e, 0xbdbdfafc, 0x2eb28af7, 0xf5ea2824, 0xf3875a6a,
-       0x5b974c77, 0xb3c7a5f7, 0x9ee92743, 0xe3be1d07, 0x8a1e2259, 0x5badff1d,
-       0x9f8e41e4, 0xf8f1fa13, 0x78e8ff4c, 0xc500327a, 0x48a05f22, 0xef8835fa,
-       0x35e763ed, 0xfe787ad3, 0xc70243dd, 0xf73b8f89, 0x63fdf026, 0x75e44ba7,
-       0x34dbea4b, 0x6d661efa, 0xec813283, 0xf79cdad2, 0xec197bf8, 0x5c9e9117,
-       0xf7c83e1b, 0x7b7515af, 0xc0e37967, 0xec2dddb1, 0x9df93cc3, 0x7cf8ec72,
-       0x3c067e39, 0xdb9e3219, 0x673ef74e, 0xf14ecdca, 0xeef89bdd, 0xd7a956f5,
-       0x6662df17, 0xe80cea3f, 0x227f7166, 0x481639ee, 0xd4ab7dbd, 0x63dfb1f7,
-       0x76fdfa1b, 0x67c2ceb9, 0x73dd3360, 0x7d9f7ec4, 0x170ff4bb, 0xefd79781,
-       0xf4bd5df7, 0xfeff6313, 0xea5b8942, 0x8a3051f5, 0xed087af4, 0xe45bd70d,
-       0x9eddb026, 0xae32305f, 0xa9df41df, 0x753bf2eb, 0x57fa0d6a, 0xf6c7bee7,
-       0xb9cb78f0, 0x86fbf997, 0x1d900973, 0xcfad9ee7, 0xe47a1a1e, 0x79774136,
-       0x14e151ef, 0xbff41a30, 0x645a1184, 0xffa0cd7e, 0xff0e9283, 0x394575c7,
-       0x63e645a0, 0x07fea90e, 0x475419dd, 0x38fec9dd, 0x21ed809e, 0x3ca86b9e,
-       0x846b50d7, 0x7034bb9d, 0xee3e5c79, 0x406a5f3b, 0x6e7493d8, 0xecad725b,
-       0x14845637, 0x22b0eefe, 0x9b7fa20c, 0x51caf9c2, 0xbf5c2d0d, 0xf154a4b1,
-       0x3c5a8578, 0x7c19f04b, 0xfc26c0b4, 0x7a5f8303, 0x88f925f1, 0xb85fc9c6,
-       0xb10bfa55, 0xda1a34fc, 0x4bfad167, 0xea878abd, 0x47c9af36, 0x4ebdc6cb,
-       0xf8b5eee1, 0x4cd2f908, 0x9f96317a, 0x1ffb735e, 0xb775fc25, 0x80525e5f,
-       0xfdcf1feb, 0x4ff1286c, 0xe8e435e5, 0xddbf4945, 0xae71c08e, 0x7597a963,
-       0x8db9f504, 0x5697841d, 0xd3b2bf60, 0x8365bed5, 0x8eb9b7f0, 0xc09c22a0,
-       0x4d15a5f5, 0xad6efe76, 0x713aa1a2, 0x26e3e90c, 0x7ec763d5, 0x52e9c379,
-       0x179423ca, 0x2a973a89, 0xabbba8bb, 0xbbba8bb2, 0xe7fee9b9, 0xeff813dc,
-       0x11d74403, 0xb57e3a58, 0x3ef87be1, 0x9335df56, 0x7fe1370f, 0x4b350f4e,
-       0xbb686cfc, 0xc4863992, 0x887fdd34, 0xfd7eeee0, 0x8a7d0b45, 0xd5e63551,
-       0xd6825459, 0xde79d6ec, 0xb52d752d, 0xe0365694, 0x429dbbb7, 0x43839aef,
-       0xbfcd6fd8, 0xea9b7abe, 0x258c6f83, 0xd2d5d5fb, 0xc112d636, 0x501b9def,
-       0x63a1c76f, 0x1ca49835, 0xca2adc6b, 0x0947e922, 0x3e6aaeb9, 0x8bf9499a,
-       0x7ce7924e, 0x1e49df6a, 0xdec56d81, 0xc923c933, 0x5a2fd99f, 0x4d4bbd63,
-       0xad03cf2a, 0x49edd463, 0x666df091, 0xc4852ef8, 0xa31d003a, 0x8e441716,
-       0xd6bffcd7, 0x3e851707, 0x07d288e8, 0x16429e06, 0x0388efe0, 0xa75cad87,
-       0xae3ff740, 0x036a3a08, 0xc26efd05, 0x76e48a60, 0x0f7bdd32, 0x834f9727,
-       0x41afa9bb, 0xfba54b58, 0xea2ab0e9, 0xbeb086fb, 0xbff7289f, 0x50b70b49,
-       0x7964f03d, 0xda053a5f, 0xe80cde79, 0x4e0bd6e1, 0x18ba0efe, 0xb24edc3c,
-       0x5a53e785, 0xe2143f2b, 0x99c27bef, 0x4d82eb9a, 0x871d6f7e, 0xd3787dde,
-       0x0f8182e0, 0x44d5ee95, 0x79ec533d, 0xfc28186e, 0x42bc9bbc, 0x414b910f,
-       0x2093c0f5, 0xd3f9f7c4, 0xebde43a1, 0x54c73fc7, 0x1ee90b8c, 0x31ba3a6f,
-       0x208f8c89, 0xe7469fcf, 0xa79de351, 0x19933e63, 0x9f049d4a, 0x7d34ce12,
-       0x73febf67, 0x28355374, 0xebefbde5, 0x5171fae9, 0xa7a83ddf, 0xa9f78de9,
-       0x7af1597e, 0x43d9beb9, 0xfc538ddf, 0x7b3ad613, 0xc03659f5, 0x722b8198,
-       0xfbe84e06, 0xc0fc046e, 0xdfb12475, 0x277c448d, 0xfe231702, 0xe751922e,
-       0x48b83bbb, 0x65913aa7, 0x7bfe36e9, 0xa1b6853b, 0x79af29e3, 0x339fcd28,
-       0x7dea8330, 0x62f246eb, 0xfb02705a, 0xecbf92b9, 0x78449de0, 0xf7c6bc50,
-       0xd37cc02b, 0x320bf7fb, 0xb227bf81, 0x3e77c55b, 0x6d1f91db, 0x3a052ca9,
-       0x23c35fd5, 0xd3f93a25, 0x0f365c5b, 0x256c477d, 0x707dedb8, 0x1d44d8d7,
-       0xd44d8d48, 0x72f51879, 0xb1ad78b1, 0x8f4e7919, 0x98f1fd8d, 0x627e90ef,
-       0x7842dff3, 0x98a9287a, 0xde530eff, 0x5cdcd32b, 0x7fbf250f, 0xf03049aa,
-       0xe7e36c50, 0xec94f57d, 0x3d52d667, 0x9359c237, 0x78ff5c01, 0x0a546934,
-       0xb4d565d5, 0x9aee7a89, 0x77eb008c, 0x7d615fb3, 0xd25ad35f, 0xb2e2f64a,
-       0xdd75c2c3, 0x07512e35, 0xd080c81f, 0x3d347af3, 0xa0f419a6, 0x8f594bfb,
-       0x5c65d064, 0x7bd0943a, 0x91dec2e3, 0xdb429384, 0xfdd037cb, 0x7470b8c2,
-       0x69d2197d, 0xf7a9d135, 0xc9cd1e3b, 0x7d061ef5, 0xd9987190, 0x06ee929d,
-       0xdfc69cbd, 0x516af023, 0xa0c08f7f, 0x4144f6e3, 0xe055332f, 0x7577e70c,
-       0x4e96375a, 0x14e11bff, 0x4bb0bac1, 0x00004bb0
-};
-
-static const u32 xsem_int_table_data_e1h[] = {
-       0x00088b1f, 0x00000000, 0x93cbff00, 0x51f86065, 0xd2f9c08f, 0xbcde0c0c,
-       0xc4b462a8, 0x0c0c5c0c, 0x0e5c4041, 0x7b401ac4, 0xdbe9016f, 0xcdce1c40,
-       0xc40110c0, 0x1ff881fb, 0x6207ff10, 0x04d6200d, 0x79405fe2, 0x5b1ba845,
-       0xda181898, 0x8803b880, 0x875880bb, 0x97418191, 0x93fb7891, 0xde181984,
-       0x7af82389, 0xcd0c0c12, 0xfff3f452, 0x5631c360, 0x29efb5f4, 0x174e3ed0,
-       0x19c73f04, 0x505c2498, 0xe0bb70d5, 0x4d078337, 0xcf8d179e, 0x9e7f4787,
-       0x5cbf2a21, 0x4d3f950b, 0x23e18187, 0x2d0a9a92, 0xc7416efc, 0x0c0c468a,
-       0xabc4464a, 0xca8c60df, 0xd081300f, 0xb1adf900, 0x0003a809, 0x00000000
-};
-
-static const u32 xsem_pram_data_e1h[] = {
-       0x00088b1f, 0x00000000, 0x7de5ff00, 0xd5547c09, 0xf37df0f5, 0x66499996,
-       0x0d909326, 0x8a027108, 0x081380a8, 0xc3b44069, 0x8e22a222, 0x260dc55b,
-       0x1037d902, 0xfdaff0fd, 0x2d361032, 0x4682d0d6, 0xa0c0748b, 0x0d0482c1,
-       0x00e02418, 0xd52ff82e, 0x5b7bbfd8, 0x16c34a0c, 0x7e1b8092, 0xce7fe5b5,
-       0xef25f7b9, 0x6d80264d, 0xfdfb5fbf, 0xe6f169bf, 0x5ddf7bbc, 0x3dcf76ce,
-       0x14fbdcf7, 0xf89628db, 0xe0cec663, 0x2cabd20f, 0xdd51b18c, 0xa0db6ce9,
-       0x74fa87a1, 0x6559ffe7, 0x4287ead3, 0x6ed0ab1e, 0x9cfdd61e, 0x7e5485b1,
-       0x386b8c40, 0xf4d31cbb, 0x8f0e1b10, 0x9616c96d, 0x6e7dd8cc, 0x0901bf46,
-       0x912974be, 0x5615ceb1, 0x780cbaf7, 0x085c7aae, 0x20c8f7df, 0xf7c25077,
-       0x1652c93c, 0xbaa23fe4, 0xbecc01d7, 0x6cb3233f, 0xe0da66c6, 0xc3fc0f6f,
-       0x7cbea07a, 0x63106cac, 0x059969ea, 0x77ea7fa0, 0x3403a512, 0x00efc336,
-       0x6c2df978, 0xfeeed0dc, 0xecfd13b9, 0xe8b78073, 0x5b7e89f9, 0x097f90c0,
-       0xecffa893, 0x5faa4afb, 0xf2f16f6f, 0x073e6c5b, 0x8d941636, 0x7f963bcf,
-       0x8be7c2e9, 0x7aa16e9b, 0xd82c5318, 0xc8b772cf, 0x635cfc4f, 0xbbfaee96,
-       0x76a214f1, 0x04d3d874, 0x3188feed, 0xb6bfb5e9, 0xd543c032, 0x0563d556,
-       0xaad84cbc, 0x700c7f86, 0x84295ae9, 0x9d9765b0, 0xfb4bc031, 0x9d870e6a,
-       0x9fcb0f9a, 0xaa1805a8, 0xff36b728, 0xdbc40afc, 0xa3ad9956, 0xf784fc66,
-       0x3bc71b56, 0x9e70e46b, 0x6ba5839d, 0xf7c74f77, 0xccad1a0b, 0x6e95f50e,
-       0x057a9fcf, 0x54fbf9c0, 0xd74a4586, 0x01fad02f, 0xea92185c, 0xcf18ee11,
-       0x36e0fda8, 0xca1eb439, 0x939ab877, 0x1ff1836f, 0xcf31b4ab, 0x676fd0c5,
-       0x80adf273, 0x96d0a287, 0xd15ef849, 0x2c8bc946, 0xfaeb6134, 0x7bc2fb37,
-       0xaf241ba5, 0x5c52f015, 0x433ccb17, 0xc0ce1f78, 0x3906d6bf, 0x9fc863fc,
-       0x1964e30b, 0x49ead748, 0x57f6c64c, 0x37671e68, 0x0e558e9e, 0x376b1e61,
-       0xda01ba5c, 0x5ecaf781, 0xc438bc94, 0x200b0b32, 0xb76fb65f, 0x81d67b4f,
-       0x0da05be3, 0x96b8e276, 0x3f2e586a, 0xeecdbb94, 0xd5adfec1, 0xd17e4126,
-       0x9e5ab5ea, 0x75c5fe81, 0xcd8f3197, 0x419aafd0, 0x88fe4629, 0x9b018f4c,
-       0xc453fb18, 0xf91eaf98, 0x37690944, 0x9fa2e419, 0x2ef44f14, 0xf54d93ae,
-       0x4b192603, 0x007eff82, 0x82be027f, 0x57849d3b, 0x05736e9d, 0x3b74e91f,
-       0x2987e425, 0xfac6d99d, 0x48e7f4f5, 0x754fe807, 0x5fd29ba5, 0xba52a654,
-       0xf443d2b2, 0x07f10279, 0x6fd172e9, 0x4e3658d7, 0x3e5d7681, 0x4b3146e6,
-       0xa71be298, 0xe7e09c02, 0x01ddf270, 0xf19673c9, 0x6a13e9eb, 0x72651720,
-       0x53e49b15, 0x05ac02fa, 0xb42f30e6, 0x9be8dcaf, 0xd7b19a38, 0x1c71e059,
-       0x502922ff, 0xac657480, 0x740fd53e, 0x1e812259, 0xc52d7c01, 0x961e0241,
-       0x067e05f4, 0x4f713d3a, 0x24b2b3f6, 0x70889ac6, 0x668f73de, 0x54353d50,
-       0x0cf50a8f, 0xc93d773a, 0xf54c73d3, 0xd02f4f24, 0xf54b59eb, 0x9eafcfd8,
-       0x318fa627, 0x917a67f7, 0x580bcf5e, 0xfcf3916e, 0x633c95c6, 0x333fb9ac,
-       0x949ea84a, 0x002cbdbb, 0x7f9d65e5, 0x864fb358, 0xf8c6c77c, 0x23328f11,
-       0x86df8d1f, 0xaa4139f5, 0x97147c8c, 0xa7926313, 0x09825f78, 0x9fb933ee,
-       0x7f927ca9, 0x653f29a0, 0x7c11a5da, 0x5eb770e9, 0x54e86026, 0xfea35e38,
-       0xd234fd6a, 0xd9fae33b, 0x9fa07e08, 0x03cef483, 0xbb170263, 0x57d8dfa1,
-       0x407ff406, 0x8eee5c0b, 0x2e3037c2, 0xea62a589, 0x991a60b1, 0x78e554bf,
-       0xfbffdf1b, 0xfde107c1, 0xe0e74b72, 0x4bff8078, 0x8e21f71a, 0x4ca88ffb,
-       0x32316e81, 0x3172c0ab, 0x6ffa4656, 0xb3f64669, 0x975e0341, 0x917e000d,
-       0xa65debba, 0x1f915206, 0x4115825b, 0x3025cfe4, 0x8c7eb041, 0xe115641d,
-       0xfef085e0, 0xc454bc80, 0xfd0355bf, 0x835f6c61, 0xfb5287f6, 0x5b7ed8ad,
-       0x075bed2f, 0xb7da98e6, 0xda9817a5, 0x3ed069b7, 0x706747c8, 0xf01f68be,
-       0x93b18637, 0x6fb53e6c, 0xf6a02f4d, 0xc0ac6a97, 0x574c7ed4, 0xbb60dffb,
-       0x49fb63df, 0x703fc651, 0xe9fc798c, 0x6bf1e645, 0x416cfc7c, 0x431fb450,
-       0x20a497e3, 0x117a7f1f, 0xd795bf1f, 0xabbed5db, 0x049aff0b, 0x5ea43aed,
-       0xac683fc6, 0x9417fc79, 0xe56fc798, 0x2c17bbed, 0xa83bed13, 0x196978fd,
-       0x2505ff1f, 0x0d66bed4, 0xb48f9178, 0x211531fe, 0x40d34f9c, 0x07485280,
-       0x921d28fa, 0x93e818c0, 0x8481b2df, 0x38620787, 0x03137ddf, 0xd6e8e6fc,
-       0x12042ca7, 0x9970f308, 0x8de2e9e0, 0x3f3e34e3, 0x9f5e6907, 0xab3aba2d,
-       0x8cf9a651, 0x2e86b4ad, 0x37b6fe82, 0x678441ca, 0x2432bcad, 0x760a7cd3,
-       0xb0a7be02, 0xf3ff3e30, 0x8ceb61aa, 0x674c8ae3, 0x2dadab57, 0xd2eab906,
-       0x90d9e3ef, 0x055fe80a, 0x6ea8c132, 0x34f415b8, 0x39fc3d03, 0x0f4c63e8,
-       0x392edcab, 0x5d9c7a04, 0x059b946c, 0xb2092edc, 0xff4087f7, 0xdffa227f,
-       0xb77c70aa, 0x884293ce, 0xcc566fff, 0xcd9f50d1, 0xa4058eae, 0x5ca3f777,
-       0xbb73a9d0, 0x14f64435, 0x9f88074c, 0x191449db, 0x1baed3fb, 0x305c94de,
-       0x31f4d63f, 0x0b3777bd, 0xf2854e2d, 0x0ee79733, 0xeff8c370, 0x211d669a,
-       0x7cc4fce3, 0xc7242dfd, 0x8725bfac, 0x2b0d69b1, 0xdc00fed4, 0xbcfd4d3e,
-       0x1dfef0c5, 0x577c3301, 0x576e1981, 0xed05aa43, 0xad894299, 0xa9ef7a85,
-       0xedebe730, 0x3812964c, 0x3f7b455d, 0x85f41c01, 0x3a60f747, 0x89bb1f02,
-       0xfcddd3ae, 0xe53fbd5d, 0x4c2ca90f, 0x124b71f3, 0x5127fa23, 0x8f9b80b9,
-       0xd3bfb23b, 0x0fcf9b55, 0xa0fe99fd, 0xec8cf84c, 0x58aecb7f, 0xd9ec059f,
-       0x552f9a96, 0xf1c8c164, 0xc67ff644, 0xb8f1c8fc, 0x721f9c35, 0x39cf9183,
-       0x53f2449f, 0x5fb8e379, 0x53f0321e, 0xbfb5fd69, 0xaf78643c, 0x1326eeb8,
-       0xc3ba185c, 0x26bf3e54, 0xbb3f94d7, 0x3f94d0ba, 0x131cd973, 0xd07c1b9c,
-       0xfcc67e54, 0x7bfca605, 0xe5311e2a, 0xc2b055df, 0x7811df04, 0xf6fe54ca,
-       0xf94d6b69, 0xdc975d96, 0xf5547288, 0xde70cc81, 0xfad1daf8, 0xbf37b473,
-       0xa45e2876, 0x57b011c7, 0x818e0e50, 0x7b6982bd, 0xabb248e3, 0x31e60f41,
-       0x4b56a130, 0xc6cb83fb, 0xa4665ea2, 0xefd2433f, 0xc634c183, 0x843c979e,
-       0x6346b93f, 0x89616061, 0x71f17425, 0x6fc86ca7, 0x0d7e4739, 0x9ec8fa08,
-       0xf44b72f9, 0x72ebe5e7, 0xd3bd402f, 0x5f803e9b, 0x3ae79c7f, 0x99103d84,
-       0xbf31225f, 0x7ebeb9f1, 0x7ae25cba, 0x53ac44be, 0x3bea5e4a, 0x0e10b99e,
-       0x5b38ae0f, 0x5480f57b, 0xfd6893d4, 0x803f2127, 0x51e81814, 0x24c8375c,
-       0x65bb6ddf, 0xea1957ea, 0x99abd004, 0x4257bfcc, 0x9bde133d, 0xec30cb7e,
-       0xd475ef87, 0x8931acfb, 0xcab6f5e6, 0xa43cbfc9, 0x94fc7d22, 0x469ca91e,
-       0x80656b69, 0x059543d2, 0x595e7e94, 0xe54b6941, 0x540f4a7c, 0x63fd2906,
-       0x3f4a32e5, 0xf4a6acad, 0x4a1acae3, 0x510cac3f, 0xa3e95eda, 0x2e879754,
-       0xf617ebfd, 0xc0b758b0, 0x8b0f6e03, 0xb2822cb1, 0xdee724cd, 0x53f39454,
-       0xa3066f8e, 0x63ea7fbd, 0xde8ca260, 0x6fc915f1, 0x47d1d3bd, 0x085e4af6,
-       0xcf4fa798, 0xa70c7b7c, 0x26c2dd93, 0x8f47d033, 0xf79cf45c, 0x2b04a1de,
-       0xa9c032c8, 0x519c9bde, 0x0fb985ea, 0x3a2e75e9, 0x70e75f31, 0x3eb7675c,
-       0xac6c97fd, 0x206972f7, 0xcaf7879f, 0xf0b30f34, 0xd7a45eb3, 0xf49bc50f,
-       0x5bd29fda, 0x2e89dca0, 0x33a735fc, 0x6e48e748, 0x8354ffaa, 0xc7882995,
-       0x2e10d8a6, 0x7bed4f8d, 0x38f285d6, 0x3eae5537, 0x7c77b234, 0x5467d695,
-       0x29e30c3b, 0xa7c3346f, 0xdcc9a5aa, 0xbb89e07f, 0x95f21875, 0x45d0fabb,
-       0x4a54ff48, 0xa6e67af5, 0xb1ced46a, 0x7c7141ba, 0x79f10efe, 0xf13c6370,
-       0xa93bac2b, 0x3fbb3ffc, 0xf7a3d5bd, 0xf606b187, 0x01f50d85, 0xf73a0de4,
-       0xdd07a8fa, 0x3f34af95, 0xfd49abd2, 0x1885ed06, 0x206677f8, 0xac10abd6,
-       0x2f5e5bd7, 0xe397ad07, 0xf6a68df3, 0xbe8f3de0, 0x7af7c7a6, 0xb5855be7,
-       0x7d04e3ea, 0xe7f0a575, 0xabd9d714, 0xbc4af3cd, 0xec6f2e09, 0x679a6d5b,
-       0x7f900ff0, 0xc8292156, 0x9b82253f, 0x32c7143a, 0x6a97fa09, 0xe5bd50f1,
-       0x6a572f12, 0x1e02d16b, 0xb466c762, 0xd1cdee33, 0xfb73cff9, 0x1fdf401f,
-       0x1ecaadfd, 0xd7e17cc5, 0xb06cf551, 0xe7e82d6f, 0x0dbdd011, 0xef5053c5,
-       0x3d76dd1d, 0x98b327d9, 0xa48b85df, 0x8d9d5602, 0x6609ce76, 0x7ffc8c99,
-       0x35defd82, 0xc8deb0d2, 0x9fd468b7, 0xf3cccb99, 0x2667d82c, 0x0cc6bf38,
-       0x939bb1e7, 0x56f3df91, 0xa0b730aa, 0x6ff39a5c, 0xbe49b8b7, 0x12c559f2,
-       0x3f08ef5a, 0xa66ebdd8, 0x2fb907f4, 0xec99e57d, 0x87e8a1dc, 0xf75bfae0,
-       0x7026140f, 0x3128a53b, 0xff20f9a4, 0x3f91868b, 0xfbe182b9, 0xa7a825a1,
-       0x5de64e82, 0xefd27acf, 0xb23ff687, 0xd27cfabf, 0xfa214fc3, 0xbe49d721,
-       0xda759450, 0xd84916c3, 0x974a415b, 0x76eb718b, 0x5c044d6b, 0x47d7011b,
-       0xbf377fc0, 0xbf133225, 0x35025aa5, 0x5fce2496, 0x4a482f68, 0x47f816a7,
-       0x51ed4fea, 0xb53fed7f, 0x3fa834fe, 0xfd7f54db, 0x0bfeb53f, 0x29bff47b,
-       0xafa5fd5a, 0x0416da6c, 0x79b4537d, 0x3cc18b95, 0x4ea95474, 0x4bdd02f6,
-       0x21762fd6, 0x82511c1f, 0xa3e7e42e, 0x34727921, 0x22d2f87e, 0xe7cca2fc,
-       0x855d7090, 0xc7fd427f, 0x54d9f85e, 0x59bee7b4, 0xbd69baaf, 0x5b0d6754,
-       0x1acb4e41, 0xdfa0a70a, 0x1c83e017, 0x46527a5e, 0x9fccd1b8, 0x4aafcf45,
-       0x701eff46, 0x844f588a, 0xab2a5ec9, 0x9c24f3fd, 0x2759ca87, 0x7be459c9,
-       0x04e9fed8, 0x5ab98fd2, 0xe87ccf5c, 0xe5f9d927, 0x0de52f02, 0xbb293b3f,
-       0x30f6bd30, 0x4cb013ea, 0x7c8f0ec8, 0x41d840af, 0xc4ce2c87, 0xb1425856,
-       0xa11fb11f, 0xc2f1d4de, 0xaa0edc42, 0xf0e4f0da, 0xb6afd083, 0x24badfda,
-       0x7974be03, 0xf33f553b, 0x7a7aafd7, 0x62edcbd7, 0x5efdd7bd, 0x34f3de88,
-       0x89adfb0a, 0xd86a25a7, 0xc971f685, 0x841bd55a, 0x9e9b25c7, 0x5c69ee7d,
-       0xf5627eaf, 0x17f5045e, 0xc3e37a6f, 0x6f170031, 0xf0a71351, 0xe4a43861,
-       0xc394fa6e, 0xba23f9bf, 0xf2f451e9, 0x18679a1b, 0x4270fe7f, 0xb78a5d37,
-       0xb0d8d6ec, 0x5098f89e, 0x716b5bbf, 0xfd4fa144, 0x676849c1, 0x56f86d55,
-       0xd1e575c3, 0xc94b125d, 0xb5cf8288, 0x80bd906f, 0x0a7a2278, 0x2fd1757a,
-       0xd0397ca2, 0x247af505, 0xbdcb22bd, 0x1465fa81, 0x93fd17af, 0xbe2fdfc0,
-       0x4fec7e8a, 0x43c45ead, 0xb9f78bc1, 0x95873c70, 0xcfe7ce0a, 0x3f464e2c,
-       0x4c1a817d, 0x9fca5376, 0x9fb9ac17, 0xbdff2ff8, 0xfaf993fb, 0x42d7d7d0,
-       0x2fb05573, 0xeaf6738e, 0x799c68db, 0x587c402c, 0x0fec8cf0, 0xc2b5fa41,
-       0x22896f26, 0x9732c527, 0x80ebc393, 0xc3ce30b8, 0xbf414eb8, 0xd0e5efee,
-       0xcc8ff27a, 0xee0fa861, 0x6cf1fdd7, 0x8b5fc12e, 0xb27184fd, 0xdae75f45,
-       0xbb5bfc4c, 0x74e919b4, 0x052f806c, 0x4ce56afd, 0x487c0a09, 0xf95ea067,
-       0x3853abbd, 0xc947989d, 0x5d81ef16, 0x639f0130, 0x67d566f9, 0x8f7a6e1f,
-       0x6ee8c99d, 0x1f689e7f, 0xf3831dfa, 0x5664e1f9, 0x7c651f50, 0x07aeb235,
-       0xf0375e60, 0xb9de4199, 0xc23ed7fc, 0xff975de5, 0x31934dd0, 0xb9f7abff,
-       0x387be11c, 0xc2bf425f, 0xfbbf9429, 0x83f48956, 0xc9a38595, 0xe42aad79,
-       0xc91f9cdc, 0x457fd02f, 0x0df0338a, 0x744093b6, 0xde5abf20, 0xa8df784a,
-       0x575db157, 0x39757acf, 0x20fa17ce, 0x707d064f, 0x603eb759, 0xe81eb9ab,
-       0xf20aeedd, 0x7a1a9bf5, 0x5f9469ee, 0x07a0d790, 0xe3f557e5, 0xdc6f8ff8,
-       0x209de1fb, 0x75ebc7b7, 0xd5eb35b9, 0x782db948, 0x7c84bd69, 0xc7b7291a,
-       0x894ac00b, 0x3cf0b726, 0xb416dcaa, 0xaaf44bfc, 0x65c7c78e, 0xf5d55eb3,
-       0x8cf86f64, 0xca9793d4, 0x127aa89e, 0xecb3ef7e, 0xf3a8fc9e, 0x457fcea1,
-       0x80bd29bf, 0x9f3a09fc, 0xc5d87cea, 0xf61f3aa7, 0xf098cff0, 0x3b7f9918,
-       0xc10c04f2, 0x7f255dbf, 0xdf134962, 0xdef7838f, 0xf8459fec, 0xc734d1f2,
-       0x9fecdfaa, 0x11438468, 0x79447d70, 0x8fec045f, 0x80881f28, 0x4be54c2b,
-       0x8c6af71a, 0x2a6c20f8, 0x2bff9d67, 0x759445f6, 0x950f3eac, 0x82d49c37,
-       0x9d691fc8, 0x753fea1a, 0xe8a89821, 0x9329dc3f, 0x7003b0ff, 0xe9da04bc,
-       0x0a1198d8, 0x6c591e82, 0x0ecdebe7, 0x012ba777, 0x1cf1c5d2, 0x96d24cee,
-       0x9fd41ea0, 0x1fb9da77, 0xe9dfc3a4, 0x31f8378a, 0xa4c9360e, 0x6c425bc7,
-       0x093f3472, 0xdf8434cc, 0x3e5bd616, 0xe0768ff7, 0x87b633be, 0xcf40cefb,
-       0xfa4765ab, 0x56bf5c7c, 0x23605ecb, 0xedc16b36, 0x77a1742e, 0x71ba0d34,
-       0xfd9f3c1a, 0x6db7ccb6, 0xafa53e82, 0x8471dd61, 0x2b189f05, 0x72de7ee1,
-       0x4d999fe2, 0x6b321d7c, 0x28797479, 0x39e5ef12, 0x77a869e6, 0xb9f0fd61,
-       0xd7ac0fd1, 0xe23ab053, 0x42f5d379, 0x3d69aa6e, 0xce6b5458, 0xd4f5880f,
-       0xc9feba37, 0x7fa49964, 0xeb84a170, 0xafb7a17a, 0x38de8796, 0xb1d3e80d,
-       0xbfb8664f, 0x2649aa7a, 0xc8da9cfa, 0x305953f7, 0x8cafe489, 0xd4be9275,
-       0xf286d6f1, 0x7aef7175, 0x9feb6dac, 0x3e421fb2, 0xe187f6da, 0x6db482bf,
-       0x778327db, 0x47cafc20, 0x3d607fe9, 0x65d84fcb, 0xc7733f27, 0x7ff1272e,
-       0xa5dfcec7, 0x76f0843f, 0x3af7f92b, 0x1c3b7d76, 0xa163b1f9, 0x60f500b5,
-       0x7ebe00c7, 0xedf9daaa, 0x7f9a16f0, 0x331d1117, 0x7de88d14, 0x072fe9aa,
-       0x54e02e30, 0xed0a8c13, 0x24b15d8b, 0xdaafe55f, 0xb1d11fc9, 0x80ecdbf3,
-       0x9e379fe3, 0xd3ffb132, 0x5ed364e1, 0x73c5fec2, 0x8ef979bf, 0xc02ecfd1,
-       0xdd86f1fd, 0x9fc84cda, 0x875fdaf0, 0x78ed7ea3, 0xed4ddb89, 0xdc1acb6a,
-       0x48ba18df, 0xbd02a85e, 0xfac851da, 0xd16fb631, 0x4728f1c4, 0x57f2f13d,
-       0x2f9cb3f2, 0x7c28263e, 0x8feffb3d, 0xf5c7c90f, 0x9364339f, 0x1ddfdc70,
-       0x89ea03f8, 0x4be2565d, 0xebc7bc7d, 0x733d9017, 0xfbdf71ae, 0x52dc6e3f,
-       0xbdc67cf8, 0xff9cdfe0, 0xfa878aad, 0x3d072917, 0x03e77cf9, 0x7a726f04,
-       0xc9e7bfa9, 0xa7ff6bef, 0xa025fdd1, 0xe3dcebbb, 0x4b3fff0e, 0x0ba7b7f7,
-       0x3e31bbba, 0xbfb5fca0, 0xa87eff52, 0x37f96b9e, 0xe36f7ba7, 0xb7fdedd7,
-       0x33f79e2c, 0x5664fca1, 0xe2c340ed, 0x6f3dd2da, 0x5bee4267, 0xb1e37b69,
-       0xf623e3bf, 0x5e34f47b, 0xf1b6fee5, 0xed03efb8, 0xac4978b2, 0xab3af917,
-       0xfa2fb0bf, 0x3b23cbcf, 0x63da7fa4, 0xc5304f64, 0x2bf712b3, 0xe99f4adf,
-       0x360bd8a5, 0xc200e3e2, 0x6c052bee, 0x4afe6f5e, 0x4adc3e62, 0xfd7e9fed,
-       0xd373b43e, 0x83b264d2, 0xf7fb2521, 0xfe64d775, 0xad3344bc, 0x98f5ae87,
-       0x129347d7, 0x89a8ebcd, 0x19abbea2, 0x0ed5ffef, 0x3c021429, 0xcbf01f8c,
-       0x8ea7f444, 0x126548bf, 0x605893c0, 0x263bae11, 0x9df5cc3a, 0x836c7dc0,
-       0xc5eff1bf, 0x3c2ec4e3, 0x47e95c0e, 0xc9900e3c, 0x3c4e7aaf, 0x6f09bf62,
-       0xc78c2199, 0xe3978a61, 0x4bd4a131, 0x1eb16a7e, 0x1da26ec7, 0x349638a3,
-       0xb82b3ca3, 0xa078e69e, 0x9ebeb875, 0x4cdf0dee, 0xd115cfac, 0x257f8ea4,
-       0xcdd9f64d, 0x5cfad1f5, 0xa50fcba7, 0x7fc74e87, 0xaac92e94, 0x8e692e99,
-       0xebca0a39, 0x8c3f5c64, 0x1c99f2c4, 0xb42a0b4e, 0x0fd624df, 0x28e678d7,
-       0xa4278041, 0xaf482a65, 0x22f6db7c, 0x79b51f8c, 0xc5c7ea25, 0x1f9a166d,
-       0xe112596c, 0x428d487d, 0xf7167bf0, 0xd4f7a428, 0xfe395e2b, 0xbb3f4320,
-       0xba06e34f, 0x7c97ef9f, 0xd8cce67f, 0xf0c7f46c, 0xde7fc61f, 0x59b7eb00,
-       0x063859ab, 0x615b34f0, 0xf404b8c1, 0x73ec4b93, 0x0cdc9f93, 0xe4aaefe3,
-       0x55ce7aee, 0xf2bd37be, 0x015f4ecf, 0x45f9f63d, 0x94c76d8c, 0xc6288a6f,
-       0x9a8ff6f5, 0xf7cabe38, 0x1e40d0b3, 0x0dfb2187, 0xab2f8afb, 0xcaf33fdc,
-       0x891a5f1f, 0x1d71dceb, 0x7eb8e343, 0xa971e2cd, 0x8a70bd62, 0x0ebce279,
-       0xe283afd4, 0x9f74bf68, 0xe7168cec, 0xbfac41b8, 0x28f1837f, 0xb2d47690,
-       0x57d7196a, 0xbefc93ac, 0x5b1b5ac1, 0x661e251f, 0x7e116a8d, 0xf8374122,
-       0x7fb8d9c9, 0x0d9fdbc3, 0xe919c6af, 0xa8e536d6, 0x1d27bc32, 0x61b9f7f0,
-       0xc51feaff, 0x11f7ae2f, 0x2dec1bbf, 0xf451fc93, 0xdfc0bd47, 0x91df3dd4,
-       0xa6d2f49f, 0xdfe416b5, 0xa62d6b4b, 0x553ad8fd, 0xb04631f8, 0xa9afd811,
-       0x2cceec7b, 0xd93ecba4, 0xe5a5f18b, 0x40b5274d, 0x48c47d94, 0xe8fd627c,
-       0xdd556f7f, 0xb50eeed4, 0x75e2267e, 0xc31b09c7, 0xad76f575, 0x3f5a38ba,
-       0x7ef2b4ef, 0xf7f566ce, 0xf7f8cf0d, 0x0eb8efc3, 0xae3c7847, 0xf0996b3f,
-       0x1ff24483, 0x553e3e23, 0xbf3842c7, 0xf5157ae2, 0x8c8da9c2, 0xc94077e6,
-       0x06feb863, 0xd1b1ff79, 0xe37173af, 0x5da0df96, 0xb924d650, 0x4ca24b71,
-       0x8fd0d169, 0x2f18de5b, 0xe99c3ce3, 0xdd6fe3d1, 0xc8356ec3, 0x10aaab45,
-       0xd98ef6be, 0xfbb61771, 0xd0c69b65, 0xdebdf14e, 0xfc79c2e9, 0x2491a6cb,
-       0xeb8dbd07, 0x34564ae5, 0x841ce311, 0x87e48c3e, 0x4c631ba1, 0xa07215f0,
-       0x54d7ca1f, 0x6f3ccb6b, 0xd32dfa14, 0x788fb124, 0xf42dfa9e, 0x7b7e99ff,
-       0x016fd75f, 0x23906fd9, 0x419bc0bf, 0xd344a5bf, 0x4f25736f, 0xee7de20a,
-       0x482941ce, 0xab6fb9d7, 0xdbf4d149, 0x2fbe4aa6, 0x4dc459ba, 0x7e803477,
-       0xdfa0dcbb, 0x45bf401a, 0xa3191f89, 0x73fa7ee9, 0xbfd0b7e8, 0xa136fe46,
-       0xde328b7e, 0x74fe041b, 0xe9bc36fd, 0xe1b7e920, 0x3c53160d, 0xf84d44f0,
-       0x6fd57a9b, 0x68add252, 0xbd53ef1f, 0x67f851b1, 0x37c7b093, 0x6c46388b,
-       0x955cf507, 0x5cf4c3f6, 0xb9eaf9de, 0x759e117f, 0x2b77373d, 0x9ee8b8a3,
-       0xdcf5c87c, 0xe7a0eddc, 0xae47e424, 0x64eee6e7, 0xa1172fdc, 0xd0f486df,
-       0x97ca8c6f, 0xe5fbf985, 0xde4f198d, 0xf08df50d, 0x941b5ea9, 0xefadd11f,
-       0x5df51946, 0xbe8bd695, 0xfa7e77db, 0x77d0ab6e, 0xa206c7a0, 0x0fe48d7e,
-       0xde39936f, 0xc3e8c77c, 0x79465f1b, 0xfb4c9df9, 0xf859ef92, 0xa33bd1fe,
-       0x7f21670f, 0xf3fa2a7d, 0xd9e9c6a2, 0xfaa4195e, 0xc7cebc27, 0xfb91ba57,
-       0xb81acbcb, 0x2b56587d, 0xe7f03c87, 0x69df31a4, 0x9dc2ffd8, 0xf8014b12,
-       0x13f56b26, 0x9febb40e, 0x1f589957, 0xf034c94d, 0x629cacc3, 0xd957fbf2,
-       0xfcf0eb5d, 0xd9852cd1, 0xec5fbfd0, 0xed147498, 0xbe1ce2e0, 0x9e2c501f,
-       0xb3b071eb, 0x4464f4bb, 0x9ce3483c, 0x9eb3fb37, 0xad531671, 0x9f53ae9c,
-       0xb7184295, 0x22ee33da, 0xb8a17a44, 0x5dfcfcce, 0xc9377f21, 0xf62f842d,
-       0xee351cae, 0x85d72f43, 0x4f027da7, 0x9e131780, 0x3c545242, 0x64a7a501,
-       0xa5e37726, 0x4b2d77f0, 0xf0a05f70, 0x91f68929, 0xe3adc723, 0x3afc722d,
-       0x773f751e, 0xbf2fa8b1, 0x6b9d2d69, 0x8e8bc48a, 0x747c48e7, 0x1f023de1,
-       0x7e5d69ef, 0xd71891ed, 0x7a437c04, 0x809ff826, 0x3fc76817, 0xf9d322ee,
-       0x5e048f9b, 0x9b8f5646, 0x370fe180, 0xe43a1c61, 0x79ccd5e7, 0x63e02fb3,
-       0x119ec7d4, 0x315e9d38, 0x7dc01ac6, 0x4ef60dda, 0x1f3a83d2, 0x3e72b30e,
-       0xd95e84d4, 0x3c62afd1, 0x251bf3ad, 0xe521da37, 0xb5e13b61, 0x0ed1f81c,
-       0xf53ef645, 0x578124cd, 0x6aaf9d37, 0xd013f314, 0x26eb82c1, 0xf10abe7d,
-       0x9b2358f3, 0xebca5d38, 0x58b25d38, 0x94c7ed27, 0x30de48d5, 0x71aca78c,
-       0xeba1c50e, 0x0e7e19fa, 0xf0a29d23, 0x7f8d12af, 0xb39b3a19, 0x62cde7bb,
-       0xb5aa6e51, 0xe7dc43fa, 0xb1f20a99, 0xfe10d896, 0x3efe1677, 0x2450fc57,
-       0x78132ebd, 0x757884db, 0xb93afe20, 0x8efe15fd, 0xf9e969ce, 0x84d04ae5,
-       0x9f4f09d7, 0x53b7fce6, 0xac5fa0f2, 0xcfc86f0b, 0xc74a3f90, 0xd233f21b,
-       0x465729a1, 0xddf00f38, 0x78e7a327, 0x28d4bf71, 0x0f3b85f7, 0x919ffaf2,
-       0xb8ca2cbc, 0xff7f307f, 0x4deebe40, 0xc55987de, 0xf7f0413a, 0xfdcef63b,
-       0x77bf9123, 0xd12fdc4a, 0xf7da6f14, 0xd7cac1bc, 0x20ec1b4d, 0xf6dfb807,
-       0xe75deab6, 0xae1fa9e9, 0xc03972b2, 0xe0c784f5, 0x0704baf7, 0x75a6f182,
-       0xa4178a36, 0xf6e40c7e, 0x6f5f51aa, 0x5ba4b3b2, 0x7faf7ab3, 0x37bfa88a,
-       0x8787497b, 0x47a87b61, 0x21bda11b, 0xce45eddd, 0xe0ffba17, 0x43bae35c,
-       0x3bdfcff0, 0x1f9dbd2e, 0xce554f1a, 0x4c5f699a, 0xb54aab8f, 0xd1515e04,
-       0x992c9bbe, 0xe7a0b7e2, 0x70ffce82, 0xa36ab7fd, 0xa59faf7a, 0xd08ec8da,
-       0x2d5ecbcf, 0xf010583b, 0x254fa5f6, 0xe32b0179, 0x7f38b183, 0x1079878c,
-       0x8ff72f92, 0xca6ee8fa, 0xed9f6997, 0x29f5dfc6, 0x1bc87dc5, 0xbb1d0c79,
-       0xfb225331, 0x6cac3de1, 0x36e1da34, 0x268ab3e6, 0x47e73f21, 0xd73c21f1,
-       0x3d5b5992, 0x3d7203c1, 0x85542ea2, 0x674277a9, 0xaf483be2, 0x7a433271,
-       0x4cfafb35, 0xbef7f9c0, 0xdc4cb33f, 0x813b078a, 0x8fb119ea, 0x31b96125,
-       0xce5a24be, 0xeaf86e8c, 0x7fa05bfd, 0x5ecbf7a3, 0x69bb940f, 0x7281c3af,
-       0x85b56436, 0x19780c05, 0xe85542c3, 0xc87d1a77, 0x83ea0b77, 0xf07bb002,
-       0xd341497c, 0xc2172ada, 0xbf7a25ab, 0xe498183c, 0xaa6dfe82, 0x32e93939,
-       0x0e500bd4, 0xcd5f29ab, 0x4ad795cb, 0xce710c5e, 0xf1415a6b, 0x12b57948,
-       0x14dc601d, 0xd78d9892, 0xbd41b21b, 0xfbc3569b, 0xc17f3859, 0xed6f58fb,
-       0x416ff7c9, 0xa4fd03bd, 0xfdf237f7, 0xcf783cfa, 0x3b527283, 0x5c2bea87,
-       0x073c312d, 0xcf91b053, 0x55fb054f, 0xec37e62f, 0xdde68a7e, 0xdf5ed029,
-       0xc28f9c0c, 0xd13ce913, 0xe74dc948, 0x80be1f38, 0x0e0756f4, 0xa5f05f18,
-       0x4909f8f3, 0xa3fd62c0, 0x6dfd7fdb, 0x9e535cfc, 0x07d68177, 0x272779ea,
-       0xfc42c329, 0xe1f69274, 0x03be010f, 0x79379c56, 0x9cdecb3c, 0xc316b42f,
-       0x1b6398fc, 0x6acfef44, 0x1e71471c, 0xe29f99b3, 0xe68ea63c, 0x57bbe776,
-       0xefe843da, 0x4ced577b, 0xaf7be7c3, 0xf6f3d2b4, 0xb70f5c4d, 0xbf21680f,
-       0x2ad5e1fb, 0x552ff3c3, 0x13d265ab, 0x74aa3787, 0x867e576e, 0x6fe437c7,
-       0xdec876e2, 0xc3debcd5, 0x9b7edc75, 0x936dccf0, 0x5fce1e70, 0xeaf9cfcf,
-       0x875f5a7a, 0x4d0bb9e6, 0x9ea45bf3, 0xa970f5d5, 0xf54147c0, 0x8f4fda5a,
-       0xfaa5bbd4, 0x6fa1187c, 0x9d9f714b, 0x24c3d3f6, 0x91f5a547, 0x6e8e65f1,
-       0x43f20dbf, 0xefe23bf8, 0xc32afdb2, 0x45f48d75, 0x678a24db, 0xf21ef9c3,
-       0x3e493747, 0xf8287b8c, 0x7b221ad8, 0xe33b943c, 0xf99e703f, 0xc8f0cac4,
-       0x03d22b48, 0xb58e54f4, 0x84bf8ff3, 0xb3df47e7, 0xf010e461, 0x5fe12e4f,
-       0x5ace138f, 0xb27ee3cf, 0x8c995bde, 0xc4d98de7, 0xf207a43e, 0x3016646b,
-       0x92a38de8, 0xf93b96ef, 0xfb46e0fc, 0x966ba747, 0xf3879d56, 0xeb8d916c,
-       0x957acf47, 0x0bc78bce, 0x3e0bd618, 0xb70a77b4, 0x0cd648af, 0x73b850fc,
-       0x0ea83245, 0xcbc444b6, 0xe6738954, 0xa76f1a85, 0x5ee49770, 0xaf47686b,
-       0xdb57af47, 0xb41bdfce, 0xd5bda793, 0xa3fd885f, 0xa1ad7e71, 0xa7ac88de,
-       0xd4bdfb47, 0xa75ff393, 0xffb9e257, 0x0a65779c, 0x62f9cf76, 0x3ee320ca,
-       0x7eea9e8f, 0x2df7ece6, 0x5fc067cc, 0x98631fce, 0x86ef40cf, 0x40ff2051,
-       0xb91a1bbf, 0xea30d73d, 0x459a56a0, 0xbde51bb0, 0xcba3f84c, 0xbbfdf226,
-       0x16f7cc86, 0xc94ffca1, 0x581f8892, 0x49f5a030, 0x83cdfb24, 0x59f900fb,
-       0x787cfdfc, 0xe1b2e51f, 0xa0a72e29, 0x4fa83c2f, 0x98af56ca, 0x256be544,
-       0xb0dfd60f, 0x92ec9736, 0x51991c82, 0xb241ed7e, 0x0f1a0a93, 0x833ca226,
-       0x7b44aefc, 0xd5ac6ca0, 0x9758ea8d, 0xdfce5d4b, 0x9961e715, 0xcf0c3dcd,
-       0x5876e077, 0xf796f934, 0x72b76133, 0xe1cf2cb9, 0x26eefb72, 0x3e784715,
-       0xad724e72, 0x728cb1cb, 0xc72dd59c, 0xd04f577b, 0x870fae50, 0x99a38a24,
-       0xe5007a80, 0xe71e837c, 0xf3d8edc4, 0xd973f395, 0xbf20a599, 0x72ea5f38,
-       0xa475cbae, 0x2d2b373c, 0xee3f62b7, 0xe34ed2bb, 0xf6d57098, 0xfae3ef0f,
-       0x275ff68a, 0x3260f55c, 0x853cc7ea, 0x78e979c7, 0x5c78552d, 0xad7e8f60,
-       0x3df5a05c, 0xf445fe9f, 0xd9ab33e3, 0x8b6f125f, 0xb5eff1e7, 0xb9fdf12a,
-       0x9c87b3e4, 0x9e7ca79d, 0x4b9d5caf, 0xe5f6f53e, 0xe27ae69d, 0xf5476991,
-       0xf01dafac, 0xbe3c0618, 0x8a59f1b5, 0xc2f13e0f, 0x8748a9c1, 0xe7c01de2,
-       0x9d1b5fc8, 0x4e7a8c2c, 0x55bcd109, 0x39d320d4, 0xb384a603, 0xe51a716f,
-       0x1575c798, 0x3f12766f, 0x0d64bd15, 0x8bf7814d, 0x9c317db6, 0x76166ae2,
-       0xf05adc52, 0x072f6105, 0x1ca3865b, 0xbe3c2914, 0xfc2f522c, 0xe7edc6da,
-       0xd3b1edb6, 0x1d527c70, 0xa8a2dfbf, 0x6ad576fe, 0xc278a7d8, 0x50bb52a6,
-       0x8379f68e, 0xfe78c7c0, 0xbc67fb17, 0x2b8f4157, 0xf5c0db6b, 0x1aa35144,
-       0x8a327bc2, 0x63b4b6ea, 0xc7d171bc, 0x957ff256, 0xf3a49dd7, 0x6f361314,
-       0x794aff22, 0x8fda6ca3, 0x59df11eb, 0x18ad8727, 0x4a50d897, 0x1f0090fb,
-       0xc45eb824, 0xf8c0fe53, 0x3bcde2c3, 0x850105b7, 0xef3f2fc5, 0xac72fd42,
-       0xf10bbd79, 0x359ef50e, 0x3c47bade, 0x2223fd67, 0xc386f39e, 0x2f4b6f74,
-       0xf0c79cf1, 0xb794100f, 0x4e78e66d, 0xec87d756, 0xb667e84b, 0x47feca3f,
-       0xe9be7d97, 0x1e7835eb, 0xe3a5eda1, 0x25dfb06b, 0x0d72fb7f, 0x5db189c6,
-       0xcaf79a76, 0xe280f85f, 0xbef7f5b7, 0xc87f09b0, 0xfe29e786, 0xab13fdbd,
-       0xdf6b6b17, 0xe31d3879, 0x7cb7db06, 0xccfe8c97, 0x26af3b79, 0xadbcef7f,
-       0x94585213, 0x914f4379, 0x11e7437f, 0xb7491f7f, 0x297b0dbd, 0xd004ed9e,
-       0x5760f51d, 0x297d6e9c, 0x88f67f8f, 0xd18ddcf8, 0x88f43bcf, 0xe5b86dc7,
-       0xff512bc6, 0xf27b7037, 0xefb9719c, 0x3f2f3d03, 0x146e3a0f, 0x37f5d7f1,
-       0xf72e359c, 0xf401fe04, 0x74cdd8b2, 0xf661bafc, 0xbcc69faf, 0xc6bd3e86,
-       0x03cf86e5, 0x8a79fa7f, 0xa73e6c77, 0xa5e8e51d, 0x343c50df, 0x078a6fd2,
-       0xd3afa3e7, 0x11ca3cf1, 0xce3a73b5, 0xad3b9d3f, 0xd14fdf74, 0x9e488fce,
-       0x47beb7da, 0xce266a7e, 0xaeb3b435, 0x973f8f1f, 0x9d6b78c4, 0xd0579e3c,
-       0x3d7de301, 0xe22e7a2e, 0xeb5f397a, 0xc5bdbef1, 0x1f6d5ef9, 0xe00fee28,
-       0xb5a5c8f1, 0xb3f1107f, 0x729374dd, 0xcf075e90, 0xe3ad471a, 0x72f42dc1,
-       0xf47b1c77, 0x38aeeab8, 0x21ba08f6, 0xea9e713d, 0x3807538a, 0x49f9046d,
-       0x2e768a3e, 0x8f2d7da2, 0xa3576f7f, 0xe3d6379f, 0xf4117dda, 0x9bdbc7d6,
-       0x7b72e8bc, 0x50fc71ae, 0x4266d13c, 0xb57c4f52, 0xbf5d1f7d, 0x7f4bb4cf,
-       0xebbefad7, 0x148954bc, 0x5eeb1e79, 0x86d2cbe4, 0xeccfe483, 0xf18b7f5a,
-       0x7bff09b6, 0xc5320bdb, 0xdfa92f39, 0x523dfa4b, 0xbde1947f, 0x7bfa512d,
-       0xe7d85dbf, 0x68fe7c8d, 0x7219c97b, 0x7b6d3d40, 0x975f13b6, 0x71483c6d,
-       0xbdd66fd6, 0xe218b5ac, 0x08fe7027, 0xf6d3c619, 0xa4e1eee2, 0x30fdc5cf,
-       0x8954ed91, 0xa29bca76, 0xf1be53b7, 0xe29da9a4, 0x76e6bd60, 0x63bdbb9c,
-       0xac76ef8a, 0xb73358ef, 0xcbd58f13, 0xf6d14393, 0xd8aaec69, 0x29e6afef,
-       0x0f74a3cc, 0x7bdf938e, 0xc862bb23, 0xcce79cee, 0x112e38f9, 0xbae28d53,
-       0x388816aa, 0x537a9fb0, 0xce55de91, 0x77f618eb, 0xe0d7e231, 0x01dd51ff,
-       0x9aaaf686, 0xbf42cfea, 0xd1dea443, 0x642c2d12, 0xe73cf7a0, 0xed0f14e4,
-       0x90d3848b, 0x0f32079e, 0x67ef58ab, 0xcfabfe11, 0x0524b614, 0x5059f7fa,
-       0x7a802ef2, 0x0c5ff7d9, 0xd67b3bf0, 0x8781c3af, 0xa9bf9365, 0x0079dacc,
-       0x35ec2bd7, 0xc847ed3b, 0x7f74ecbb, 0x3b1af948, 0xd6ef778d, 0xbb239f6f,
-       0xc656d7fb, 0x556087f7, 0xb996f783, 0xb7871d79, 0x2fe6bb7e, 0xcbe35768,
-       0x1afe7ed0, 0x89eb8f28, 0xfeb4b18d, 0x8e2978e9, 0x7fcb51ee, 0xa8a9a1ed,
-       0x3963f2d7, 0x4e6fe63f, 0x7d415509, 0x6e1c49ad, 0xee8034dd, 0xc97e28ab,
-       0x7ba5f149, 0x8652beb7, 0xe6fb54f3, 0x60330c58, 0xfb09afed, 0x7ee237ff,
-       0x63d51aad, 0x642f338c, 0x2e78c78a, 0x536118a8, 0x3f23135c, 0xfa11c906,
-       0xe8e31ab1, 0xc5d8113c, 0xa84e7aa6, 0x89780f9d, 0xf8fd838f, 0x3f70aa39,
-       0xe59107d4, 0x76fdfcf4, 0xdcbd8e7e, 0xba39ef0a, 0x9d6b97cb, 0xeeae1c79,
-       0x3349f5c7, 0xe744ff95, 0xb3df9173, 0x23fe5e5e, 0x7aaedebd, 0xe265fbf8,
-       0xfe489b7e, 0x57a5d43d, 0xb4717afe, 0xf4a25bfb, 0x2fdf9e9f, 0xed05a0b1,
-       0xba762d96, 0x67ef0bb7, 0xdb0e73c0, 0x55ffbe34, 0xfdd30ae2, 0x3e843b39,
-       0xd309892e, 0x44fd3e7d, 0xc23cb03f, 0x22f2d6cc, 0x15f4bdd2, 0xb3f8c33b,
-       0x3e9cd7d2, 0xb6e977a4, 0x957f5b6f, 0xb18bf185, 0x7d2bd7e4, 0x1f117fed,
-       0xd3c35a94, 0x2dbcfee9, 0xe7f78656, 0x3b796db5, 0x4db5e51d, 0x9c27a70d,
-       0xb4af5f65, 0x57be6ade, 0x58e38c40, 0xbc42e865, 0xaf3f4177, 0x9e8bd45b,
-       0xdb8632b9, 0x9f18f6d7, 0xdde48635, 0xb1d44f7c, 0xc641c6ca, 0x9e45fbf3,
-       0x7fb17ae8, 0x9d8ffa8c, 0x38f47743, 0x263fdaf7, 0xe699ed09, 0x96407464,
-       0xfa8e3d81, 0xe4eea8bc, 0x7c1ff430, 0x6fdfa316, 0xf9c389e0, 0x73ad33e8,
-       0xcfbfea18, 0x19873bd2, 0x952399e7, 0x92a28f36, 0x8ed2875f, 0xfaf327b5,
-       0xb5378c31, 0xf7a68b4f, 0x12c4c586, 0x8e1e8afe, 0x7a8e7a8d, 0xabe70c4c,
-       0x531f6834, 0x43e5176c, 0x2d33f76f, 0x31b87a44, 0x49ebc3c6, 0xbcf8690b,
-       0x20fb6eb8, 0x950a1e23, 0x72072a6a, 0x642cf84a, 0x832cb52b, 0x2bdbd6fe,
-       0x28f0ef9c, 0xf2813f74, 0x55f8ba7f, 0x3933a6ee, 0x518e3191, 0x5c6614e0,
-       0xe7eb33f2, 0x6fd51448, 0xcc69fc43, 0x646456ef, 0xf7926a95, 0xa94f5618,
-       0x7e2ecc03, 0x43055a5f, 0xec44793d, 0x0c1fa3ef, 0x3d7c6ed3, 0x383f7a48,
-       0x328bb180, 0x4f09bef0, 0xbf80db9c, 0x3eb3706b, 0x2b69e309, 0x5317d718,
-       0x488f68dc, 0x033b00c1, 0x595554fc, 0x03df8837, 0x2f187cc2, 0xf42c2649,
-       0xf37ee5cf, 0x8083b43b, 0x843df94f, 0x1550b157, 0x86c318a0, 0x9e3aefc9,
-       0x96f3fbf1, 0xeb8ccc7d, 0x0741128f, 0x7a4ddc16, 0x7fbac1cc, 0x5aa3009d,
-       0x155b7d45, 0xdc1cb7f7, 0x59b8739f, 0x58c3ed18, 0x42c70b07, 0x1caa18ea,
-       0x2bbfca33, 0x5f03600b, 0xf39ac7ba, 0xf402e523, 0xf5bb445a, 0xf7a83f84,
-       0xbf7a88ab, 0xabf7a88a, 0xe3abd5b3, 0x2836dca9, 0x58a5ef03, 0xf02f595c,
-       0x09b3dbc6, 0x867e01bc, 0xcc7f3de0, 0xfb15e312, 0x18d784e6, 0x962b1bd1,
-       0x8e6eba07, 0xfa7e20c9, 0x4eaedc59, 0x8966978c, 0xc3d70c35, 0xbefd248b,
-       0x1877e64f, 0x1b6e63de, 0xa223e1c9, 0xcf02cd9d, 0x55bf748b, 0xb276f28f,
-       0xb7947abf, 0x263e56f7, 0x6f67797a, 0xde8d89fd, 0xea5ef89f, 0x5a8d8eaf,
-       0x4bd50fff, 0xf47daf65, 0x76efee0e, 0xa03727e9, 0x6e676cde, 0x1a54fd46,
-       0x16b7fadf, 0x4cedc27a, 0xde999a5b, 0xc0dfc831, 0x9a17316f, 0x49f2479f,
-       0xf472fe14, 0x29df7185, 0x61f3bbda, 0xe74d5e7e, 0xbe315c83, 0x9f7cb589,
-       0xdc79eefc, 0x46cb078f, 0x25dfe61f, 0xe1aeeff2, 0x0fdde3f6, 0x1b0fb4cb,
-       0xc1d5bf79, 0xe1efcdff, 0x801f07b8, 0x5f33ddbc, 0xa233850a, 0xdec5dbdd,
-       0x677a878f, 0xde44fe88, 0x9e601583, 0x68e4cb49, 0xbe7160f7, 0x45e1cfd4,
-       0x8b317fde, 0x66fdc5f9, 0x3159e7e6, 0x22dbe26e, 0x0f55a425, 0x82c79eed,
-       0xd1ef802b, 0xc7be04fe, 0x9c592ffd, 0x8d2e66c7, 0x9adfd7c7, 0xa77fd260,
-       0x70e27886, 0x8baf66be, 0x7cfe6ee7, 0x149eb5ee, 0xe54579e3, 0x1ee9ac74,
-       0x9bd52aa0, 0x3d4dfa8a, 0x80f33d7d, 0x07a76a1c, 0x1f218f31, 0x7e1256ec,
-       0x3d24f30c, 0x5084aa95, 0x3f6e2a2f, 0x37bb47cb, 0x5eb3f39e, 0xaebc4b5e,
-       0x177ccecb, 0xe6461dfe, 0x5dcfff81, 0xdff3a1e1, 0xa7fc3957, 0x5d95fe71,
-       0xa380de39, 0xb7043f27, 0xe15771f2, 0x8e7a33b8, 0x7af34aa7, 0x0ebedec9,
-       0xcbf245e6, 0x3fd86d79, 0xc8f9ead9, 0xadfbfd83, 0xd30fd0ca, 0x23de3f13,
-       0x153fc821, 0x24714fea, 0xc194dc72, 0xbc72fed8, 0xfff4146f, 0xe8bf7132,
-       0x52264aa2, 0x08b7571e, 0x34a51fef, 0x913ea447, 0x8f72a64e, 0x974a7b8a,
-       0xd5297a54, 0x56f36bf1, 0xb6983dd3, 0x36fb790b, 0xa25fa0b7, 0x402fe045,
-       0xb52d97f6, 0xed1df682, 0xde308aee, 0x60d2c727, 0xb961c1de, 0x9abf09ab,
-       0x13bf919b, 0x456c13ca, 0x66b55218, 0x7149d10a, 0xc87cb057, 0x0604754f,
-       0xe37da2c7, 0x6987df31, 0xd6711d4d, 0xf8bb31fb, 0xfbc7136d, 0xb7e71263,
-       0xa63fbc48, 0x6e307b36, 0xbb6bb1e2, 0xbc22abee, 0xe38872c3, 0x7ef93ffd,
-       0x37bc4f6e, 0xc0699b4f, 0x327b33bb, 0x0267fde1, 0x5e054bcf, 0xaa1d04ab,
-       0xc4ab3e04, 0xe255afbd, 0x812adcde, 0x3bc42adf, 0x7b888fa4, 0x3d23177b,
-       0xef119520, 0xa1d6bfc0, 0x7b432641, 0x520f0f7c, 0xb75be087, 0xb2a4fc85,
-       0xbc43efc3, 0xde39135b, 0x03a00e6d, 0xdde035f1, 0xc241f983, 0x78e0eaa7,
-       0x0e9cf286, 0xef105602, 0xa739f123, 0xb6fde007, 0x87d424d8, 0xd6784c63,
-       0x1f9fc712, 0xf3e29fde, 0xf390a25b, 0x6a25fc48, 0x5d605efc, 0x8fb37bbe,
-       0x765c44ab, 0x1197b895, 0xcd7688f1, 0xbb0fc02a, 0x3f93e398, 0x2f60221f,
-       0xfd6249a5, 0xc074055f, 0x3d8527fc, 0x74c67884, 0xb75f2c67, 0x762a5a24,
-       0x04a788ab, 0x4b0fdf7e, 0x6cb4b20c, 0xf18043c6, 0x1e641a97, 0xe1fdf584,
-       0xc8ff335a, 0x7ee2256e, 0xc893cf49, 0x56df2b6f, 0x2f7fb82d, 0x74debfcf,
-       0xe69e5bae, 0xfe10f78b, 0x35da1203, 0xb872133f, 0xfa85f902, 0x8bc3d7c7,
-       0x152c1f05, 0x223f06f7, 0x2131e7f8, 0x7ceb8fcf, 0x48e7e5e3, 0xf1e64f96,
-       0x1699898e, 0x9862bf71, 0xe309e319, 0x834cf5bd, 0xc6dad17e, 0x9fdd2943,
-       0x92b63ec9, 0x650ec6dc, 0xf8afe43e, 0xf10c1f8f, 0x7dfd70fb, 0xd78a1ed1,
-       0xeb1dbfef, 0x0e83bf89, 0x711587b4, 0xd7cca4cf, 0xef51cd93, 0xeef2ad8d,
-       0xa65fa1b1, 0xbeecfeb7, 0x73f11b69, 0x1e44e5de, 0xbfe027d6, 0x8ec03663,
-       0xc157581a, 0xc81bd62f, 0xa57a8c5e, 0xebfc49c6, 0x1be7fe80, 0x17b624f8,
-       0xc754ceff, 0x5f501bb5, 0x240680bc, 0x6a2fc130, 0xcf11d906, 0xfa0f7380,
-       0xfea956b1, 0xac2f38be, 0x8fee8f8a, 0xdf2c65fb, 0x5d657087, 0xac2bf26a,
-       0x9ef47d54, 0xef59ac7b, 0x44f314ac, 0x9cb344c2, 0x4fc2f3e8, 0x39577d45,
-       0x5fb13b02, 0x9227a7c9, 0x1cde273c, 0x52a89e7d, 0xf7de20b5, 0xcb8c3551,
-       0xe3573077, 0xfd0f73f6, 0xe49f68c3, 0x3af06054, 0x7ce983f4, 0x7d7190b6,
-       0xaedc6417, 0x04f5c7d4, 0xe715bdf2, 0x3ff13703, 0xcb0807ce, 0xdefc6a17,
-       0xe42dbbe3, 0xe4225887, 0x672151ed, 0xfd7c85cb, 0x8acbe51c, 0x297b58f7,
-       0xab9085fd, 0x90872895, 0xe0cd8f1e, 0x3fb8bcf6, 0x2ccf5f4c, 0xfba08db4,
-       0x161cab22, 0x4f94179a, 0xae0721ac, 0x768f760f, 0x7647ffa3, 0x4e03b966,
-       0xfba2cfcc, 0x2cf8a5dc, 0x37cdf237, 0x9c1759ce, 0xc8161e2d, 0x2b16f74f,
-       0xea4bf72a, 0x8957c8f7, 0xf75408fb, 0xd5fd0ccd, 0xd856264f, 0x9635de29,
-       0xe4d787c7, 0x81de1366, 0x86b19d1e, 0xb4ca5a75, 0xfbeebaeb, 0xec9feac3,
-       0xef835ee5, 0x6960de85, 0x41a17641, 0xfb88d44f, 0xc8279924, 0xc5f41886,
-       0x31268bc2, 0xd4f5eff4, 0xcde8bd13, 0x2e6f5cf5, 0x4deba292, 0xf5d78edd,
-       0xd17ea466, 0x4c17c5d3, 0x54bf9d36, 0x7a465e1d, 0x3f744867, 0xcac3b242,
-       0xd7992ff7, 0x33d19b9b, 0xec95f01f, 0xed0be030, 0xf16fdd21, 0x89e328e3,
-       0xae4793d4, 0x00d7e7d3, 0x4b343bdd, 0xfa393cf3, 0x79abf3ac, 0xfd3fc85e,
-       0x794fcd08, 0x5a5347a7, 0xd92d7350, 0x69770c23, 0x1c2ef70c, 0x0bbf7d5e,
-       0x46b87be9, 0x56af9fec, 0x74bf1843, 0x197166b8, 0x0f76d5c1, 0x2fdc66d2,
-       0x3de1741e, 0xc8d6b34d, 0x247e9fb4, 0xf14e9826, 0x399fdf9f, 0x63e21b23,
-       0x9a5dac16, 0x6b38fc8e, 0x373a52dd, 0x37c1247b, 0x59806fd8, 0x79ec8796,
-       0xbcc6fefd, 0xb43ead67, 0xdbe37bc7, 0xfdd1d5bc, 0x27f8553d, 0x779853ae,
-       0x7643ae08, 0x8674c6bb, 0xfc8e0f81, 0x82eb4ec2, 0x8ed82d2a, 0x58bad570,
-       0x2555837c, 0x280fbf44, 0x0fb571d5, 0xf0ea94e9, 0x73298b5d, 0x4f7ed024,
-       0xdbc472ef, 0x3b5f456f, 0x2d3ebbee, 0x3a0245ee, 0xbbf264dd, 0x56d77df2,
-       0xb66347e1, 0x4463f25e, 0x7c97a7be, 0x62938f17, 0x7ff9e8ee, 0x6869ffb7,
-       0x315df58f, 0xe6b4bf8e, 0xe84f92f8, 0xa11f7989, 0xcf8bc450, 0x5a1b175a,
-       0x66ce4518, 0xb3c7f389, 0xce997ec4, 0xebd7858f, 0xe3e739f6, 0x5e973e48,
-       0xfaf884b8, 0xcd2a7dcb, 0xafc0656b, 0x17a5efa8, 0x507dd346, 0xe2bb9e0b,
-       0xfc0b8c71, 0xf94cbf6a, 0xc4eda725, 0xf53fedc7, 0xce8239d2, 0x9df4a9df,
-       0x5df6af88, 0xda01e74d, 0x3ad3fdc5, 0x7c9cd29e, 0xc1c6bc3d, 0xe9de50f5,
-       0x743c919f, 0xa66857f1, 0x779e7286, 0x5e5ce7fa, 0x31d9fef0, 0xdeebec38,
-       0xe0a1771c, 0x2cd7806b, 0x2169349f, 0xc2df9bd4, 0x0d8d8ae5, 0x7b1f9196,
-       0xd1f7ac6d, 0xc6bff228, 0xb5f931e1, 0xf3965bf2, 0x4caec0f7, 0xcc99c434,
-       0xc87bdf12, 0x65efcd3f, 0x4b20ee65, 0xfa127945, 0xcc0e5bb0, 0xdbb772f7,
-       0xd3d4e3cd, 0x79c6bb17, 0xd6fd6985, 0xe8abce3d, 0x53b09e79, 0x13465bf2,
-       0x5f9e3ddc, 0x9e368e8d, 0xa58c71ee, 0xd1f1edf2, 0xb450ffdb, 0xc0595adf,
-       0x8b4fa07c, 0x79bffdc4, 0xd434fba1, 0xe3ab791f, 0xb8c32413, 0x4d8a6bf2,
-       0x35794ff1, 0x5fdf74b9, 0xed5ceafe, 0x76bc835e, 0x36cd85d1, 0x4743e5d1,
-       0xd532e880, 0x40e3dfe1, 0xf0a17cb9, 0x583d4f81, 0x11d3a72f, 0x82bc382d,
-       0xae7ddbf4, 0x3ea7e768, 0x8d53a48c, 0x1fac13a0, 0xd2740cb2, 0x7ef913e9,
-       0x07d2faeb, 0x8bfdc53e, 0x45edf8a7, 0x08b1ebbd, 0xc74465fa, 0xf383a75f,
-       0x0fd82b6b, 0xdfc2f381, 0xbbf8a665, 0xe827f15e, 0x7f47e3ad, 0x51dff60e,
-       0x944efb94, 0x1f5851cd, 0xe17387e7, 0xc17dbbad, 0x8fa2e30f, 0xf3a9c527,
-       0x04167cc3, 0x71aa3e01, 0xf1f7a3fb, 0xb682c43c, 0x974f18f3, 0xf1362e9c,
-       0x01738a43, 0xff415397, 0x211e7ba3, 0xc50d6ebe, 0xbd19ed7a, 0xd9c5278f,
-       0x185c1f0b, 0xffb34364, 0x11c1f1ef, 0x29f837cd, 0xde60479c, 0xf0bd79c2,
-       0x1b86c7f9, 0x18ea97fb, 0x79c4e697, 0xf6fcfaa9, 0xbde383b7, 0x1e1d70fb,
-       0xab7b275c, 0x8e254860, 0xbf7c60c0, 0x37f4f5c8, 0x145bdfe8, 0x68f0c4ff,
-       0xcae2f476, 0xdfa0977d, 0x99b2aab5, 0xc5d85552, 0x0ce2ed0c, 0x688f5dfe,
-       0x2b5e05f7, 0xcae2ebf4, 0xb5b7ee66, 0x70db9905, 0x323b00cf, 0x8ad8fc92,
-       0x69cf6cc3, 0x7e8dc06a, 0x83dc4d73, 0x65812aa0, 0x67e85919, 0x1a0ccc4a,
-       0x938d77f0, 0x4f2cd7ef, 0xfdc6e3dd, 0x8fd42b10, 0x9a5b33fe, 0x77e4ca72,
-       0xe5995d7b, 0xd7e93a04, 0x7ab0c744, 0x1f91249f, 0x1f8454f2, 0x1fa994f2,
-       0x7da6cd89, 0x28bc488a, 0x281dfe36, 0xb3ff0985, 0x9dfe87c0, 0x3e6ea5a4,
-       0x8fc295ce, 0xaffa04fd, 0x363b022f, 0xc1f645d6, 0x7c2c0b92, 0xe853687d,
-       0x3c6b2bbe, 0xf1c5af2f, 0xff71d871, 0x59f5c643, 0xde276098, 0xd5d32610,
-       0xf1c2128b, 0xdc2123cc, 0xe0978587, 0x5c63a37a, 0xfcf803cb, 0xd7207b79,
-       0xa6ff7809, 0x0901f36f, 0x81fc33f7, 0x35cf118b, 0x03d33072, 0x772d7fe5,
-       0x74b96266, 0x8138fac8, 0x39e017a7, 0x9f618087, 0xdcd7df94, 0xe13dcb0d,
-       0x112be60b, 0x5fdf86fb, 0xc7b7cc6c, 0x1fb02af8, 0x4acbdf91, 0xfda242fc,
-       0x074cfc41, 0x34fdff9f, 0xf2772f3f, 0x07f10575, 0x6e3ed7f2, 0x3c529d3f,
-       0x87efb871, 0xb4dd79d8, 0xbcf363ef, 0x114f686e, 0xe05ad8eb, 0x4fb0c557,
-       0xb3e2a177, 0x545d3f20, 0xfd8dcf0d, 0x2727628d, 0xf2dae838, 0xdebd76a8,
-       0x83af3c3f, 0x4f4f94f8, 0x92247b22, 0xed74762f, 0x69eff027, 0x9e33a1dd,
-       0xf1c388b2, 0xfad1ff4c, 0xfdae93ee, 0x761c45aa, 0x5efca873, 0x69fe3fbe,
-       0x99c51c6e, 0xa3b8fdea, 0xda336969, 0xf53477c5, 0xbcf8899d, 0x3fe2e0a3,
-       0xed43ba63, 0xfa8b13dc, 0xce897ee2, 0xc1f9dd97, 0xa42c6aeb, 0x475fdf5b,
-       0x2f3c1ff7, 0xeb3a71e4, 0x01fe9154, 0x7ef8d6e6, 0x47df8857, 0xae02bcc5,
-       0x715fd157, 0xdb743877, 0xf3dd000d, 0x3406e87a, 0xebefa6f7, 0x43d5037c,
-       0x893ddea0, 0xf7f494f6, 0x726fbd1a, 0x35d7bf98, 0xe346c57e, 0x8daf1ee9,
-       0x0f8fafc6, 0xeff84a7a, 0xf7b88fc2, 0xf8c7c74d, 0x77dc7c99, 0x1d75dec4,
-       0xe03acb3b, 0x3fb0db0e, 0xde3e78f3, 0x7cfc489f, 0x1fa05985, 0xf6fa745f,
-       0xe33e3f20, 0xbd45edf4, 0x4ceb6257, 0xbc920657, 0xcbcf85bc, 0xc905c0e4,
-       0x0313fe30, 0x21271702, 0x9cfb9a1e, 0xc07fbd97, 0x80fbf9ce, 0x81f7f39d,
-       0x5baf9d0c, 0xecd7c89c, 0x538d2274, 0x92c77eff, 0xbb1f87ad, 0xc4fbf81d,
-       0xbb3efcdb, 0xe373d952, 0x9697e443, 0x3e2e3199, 0xfc203d32, 0x7c5d2d0c,
-       0x433bc7c8, 0xa332f2e1, 0xc1ce9621, 0x9b2f98cc, 0x319fdbee, 0x32c3c79f,
-       0xadf879a5, 0x22c275a6, 0xb3d2d711, 0x4483f41e, 0xfe7333d6, 0x6517ba04,
-       0x471ee69b, 0x9c35917e, 0xf44e66cf, 0x608e78c9, 0xf68932cc, 0xf21f47f1,
-       0x3c00b634, 0x45ef1433, 0xe0f99d31, 0xfbc20d7f, 0xb99aca51, 0x9e45347f,
-       0x4853f993, 0xf3e1ed57, 0x1073c23d, 0xc79f0e4f, 0x69cfd861, 0xdd322b53,
-       0x38f7cfc8, 0x7207a87c, 0x827df56f, 0x22fdd574, 0x0afbbcfa, 0x171801d8,
-       0x27b77b9a, 0xb724f907, 0xd4a3eede, 0xd01894c6, 0xb30ab96b, 0x31a29a61,
-       0x0c698ec5, 0xbd9a61b3, 0x354fd850, 0xe0fd9137, 0x786bf1ca, 0xd36e79bf,
-       0xfbe35ff3, 0xb7784af9, 0xdcabe064, 0xa3bfb7a6, 0x3f3e7673, 0x565efdc5,
-       0x9fd699a7, 0xf0cdeac3, 0x38668de5, 0x47866c33, 0x65c333ee, 0x67683638,
-       0xe11ef88c, 0x86569d9e, 0xde2b2bdf, 0xf438a56c, 0xa0ae7157, 0xe93b5e78,
-       0x4dc509c5, 0x712718d9, 0x05a745fc, 0xfe3b95fd, 0x59c532fa, 0x658a6e74,
-       0xfbb86718, 0x831618d3, 0xed9bbc71, 0x18bf30eb, 0xd9fe8768, 0xb5f6cde2,
-       0xedb34f18, 0x434f9d52, 0xedb50f14, 0x4bbcfc6f, 0x086b06e7, 0x6f8e2ee3,
-       0xe445fe7f, 0xfa1be3cb, 0xaaf61d93, 0x7d60b414, 0xdd3847c1, 0x3ebd08c7,
-       0xe2f5e846, 0xfc7af33a, 0xaf6e970a, 0xfce287ba, 0xe3812637, 0x2fb2b5bb,
-       0x2577c587, 0x8c6dfb74, 0x40dd67b0, 0x7687cfcf, 0xd08879d3, 0x7ba179cf,
-       0x6bd11f35, 0xb3ea0c41, 0x0cdaa38e, 0x5c5d4bf4, 0xcea3c663, 0xcc8497df,
-       0x24ba27cf, 0xcf0ce7a1, 0xc55e3033, 0xe71524b3, 0xdfa367ef, 0x8bbd7f53,
-       0xbc2f19db, 0x20f2e9a0, 0x992a7b8b, 0xb2ae70c7, 0x79b3ef5b, 0x089e31fd,
-       0xfbb035e9, 0xbb447179, 0x2eb1fd7a, 0xda5fcf2e, 0x448279f8, 0x95638781,
-       0xe86ec8fb, 0x7d2b23b2, 0x380689be, 0x727766af, 0x776fe12e, 0xf986bdf2,
-       0xdec364aa, 0x4e30bbe4, 0x8f414eae, 0xe3b92b36, 0x498f9fb9, 0x3d72e7c4,
-       0x11f313f6, 0x6ff56d8f, 0xd81cb0b8, 0x718c23d9, 0x5735f967, 0xe41a26fb,
-       0xb9f287fe, 0x3712b74e, 0x392bcbc7, 0x9cf093cd, 0xff0d7148, 0xfd71618e,
-       0x80dcb76d, 0xcfcd5ef8, 0xcc2b67d3, 0x963c832f, 0xfaedb96c, 0xfcbcf061,
-       0xec5e5199, 0x2b71540f, 0x78de2f3e, 0x3d15ce92, 0x8efee16a, 0x0504fa48,
-       0x13fa3d9f, 0x39ea0147, 0xcb75efa8, 0x9f7f7a08, 0x239bec05, 0xdcef83e3,
-       0xb38e4505, 0xa06f0ffa, 0x9f3330f8, 0x684bdf02, 0x97ae75bf, 0xe9e8ebbc,
-       0xd19becc2, 0xa02df754, 0x8fc87978, 0x0c297eba, 0xa489eb99, 0x6fc16aef,
-       0xe4621bf0, 0x7d72c893, 0xdce904a6, 0xd07cc974, 0x43ff0693, 0x8a6aa1c9,
-       0x076c8dcf, 0xc1985823, 0xe181da0e, 0x9b972875, 0xfc169c78, 0x88b65b24,
-       0x61c41f63, 0xf915c7ba, 0xf8a21811, 0x83d13652, 0x4d99bd78, 0x37d754c6,
-       0xc3f5396d, 0x52abfcb1, 0xa2bf73cb, 0xe7249cfa, 0xdd30ee6d, 0x9c4fdb6f,
-       0x70f36f47, 0x8feeff58, 0x64d45f9e, 0xe3aeb8a7, 0xbfd23427, 0x149e300b,
-       0xb768bfcb, 0x3d68c058, 0x78cfa5be, 0xab6e538c, 0x1fa5f7e7, 0x5e33efab,
-       0x1ebccb3b, 0xf9f44fa9, 0x39fe20f6, 0xbe7afd1a, 0x83ce1726, 0x771c788b,
-       0xcc8a9f4a, 0xd274288a, 0x2ad44bdf, 0xd3fd7132, 0xbbc38f79, 0xcc14f08e,
-       0x9fefc850, 0x5c9a7e4a, 0xe83a9fe1, 0x02edbff6, 0xaca139ba, 0xec25fe0f,
-       0xdfa1d793, 0xfbd90bf3, 0xf7507b80, 0xacacfd3e, 0xa3df9d00, 0xfb40f40f,
-       0x56161533, 0xe266df80, 0x609c353c, 0xae674f9a, 0x719e2896, 0x78f372d6,
-       0xe36ebef0, 0xaac05afc, 0x5622dea9, 0x6ac1694f, 0xce217e73, 0x273c2e47,
-       0x8a76e3c7, 0xfaf9cd6a, 0x8d92c0b9, 0xf0d1ac67, 0xc7d335f6, 0xc702fbe7,
-       0xa36cdd27, 0x2ab7ddfe, 0x6977ef8e, 0x6df387cc, 0xe9272ae7, 0xa01662ff,
-       0xe629dc7e, 0x7307f2fd, 0xed20b37d, 0x37d33f98, 0xcb9e0fab, 0x2d23f3e7,
-       0xf99e4919, 0x13c57ebd, 0xbf007859, 0xbce187cf, 0x8524dc5b, 0x036c2187,
-       0x9fc11d51, 0x3826bde3, 0x3679e37e, 0x6e38fc7d, 0x3ef673e3, 0x9e116fa7,
-       0xb8f9929b, 0x0225f98d, 0xad1b251f, 0x98d17f26, 0x79d0528d, 0x6aaf9e39,
-       0x1acaf7a1, 0xf54d58ce, 0xec1d798a, 0xba076601, 0x2b58298d, 0x755660e3,
-       0x25d0f1e9, 0x1ccbced1, 0x755c7810, 0x945f5e5b, 0xbed1c7db, 0x9d1027ed,
-       0xf84a7a43, 0x06d858a3, 0xec8cc5ed, 0x7b3f2982, 0xe2938721, 0x26a6bd1e,
-       0x4a2fbe8d, 0x653361fb, 0x0e789bff, 0xd03e32b3, 0x99da0e37, 0x2ba5f169,
-       0xc1bebf24, 0xcf9d6fe4, 0x88e4f0f1, 0xa22a4b8a, 0x3a75b7ac, 0x53d5213f,
-       0x3b70409c, 0x599da79f, 0x20c06a9d, 0xb8e32317, 0xd3db8cbe, 0x3a8fe742,
-       0xfe744ab7, 0x20e929f9, 0xea7e0f9d, 0xff430f5a, 0x09d02a40, 0x1253eff5,
-       0xfcf7845b, 0x34dc3565, 0x73a40de7, 0xe3178c56, 0xc61b4a0f, 0x1a0ea5c9,
-       0x62e3b73f, 0xbee2d62b, 0x218cca54, 0x61df9023, 0x866e33dc, 0x3ce3a3e7,
-       0x075f5ed4, 0xc2ea7ba7, 0xa1dcc660, 0xce7fbed8, 0xc38f281b, 0x7cbce862,
-       0x99cae00a, 0xb432e940, 0xe65952cf, 0x5333b46e, 0xa04678a7, 0x8b957f4f,
-       0x916493b7, 0xf684dc67, 0x270e08e3, 0xd6f92c3c, 0xa0ae1311, 0xfcac5276,
-       0x1cf87a93, 0xfa1b4ded, 0x7a061c27, 0xc4c8a84f, 0xf10653f6, 0xa70b5134,
-       0xbbfb3d61, 0x75a01ee8, 0x23373cc8, 0xbbef3d7d, 0x2eb82971, 0x0b06dfdc,
-       0xfb63d075, 0x97fdf4d3, 0xfbec83b0, 0xf2f0870b, 0x97994ec2, 0x24e7cfc9,
-       0x15f6eba6, 0xfaa1d72f, 0x5ea246e2, 0xf9db8f7d, 0xe47c395f, 0xeb42bf07,
-       0xa0803ce5, 0x58e9f953, 0x0bcc3216, 0x21bed3e5, 0xb4fcb3fb, 0xef1cf4cb,
-       0x95c63509, 0xa1ec1497, 0xb2943bef, 0x509f3a66, 0x838e6f5a, 0x7a2622bf,
-       0x979f3abb, 0x3059969f, 0xf99abb6a, 0x2c3ee9f9, 0xb95a27d8, 0xd3f3f364,
-       0xfc6e1992, 0xe8539456, 0x7169cb39, 0x0a71fae1, 0x67a847ce, 0x7aa09642,
-       0xda5d3779, 0x79a62ddd, 0xe1c3dda8, 0xa8bfb10e, 0xb7f5ebe7, 0x39c4d34f,
-       0x7bcf7e3d, 0x2028255b, 0x4dd3cfc0, 0x5ddfc927, 0xf09bb4d2, 0x3745f3a3,
-       0xd059629e, 0xaae4a780, 0x6405b0e6, 0xfdb8e9fc, 0x025e874b, 0xcba3d924,
-       0x7d4b3bf3, 0xbf1f2163, 0xef90616b, 0x792eacd8, 0xcab37527, 0xf0fd0b22,
-       0x6389d2ee, 0xdf2f308d, 0x35f37efd, 0xb2b78113, 0x6bf7f286, 0x6b7bdee3,
-       0x7506c621, 0x4ce83b9d, 0xb00d3bf7, 0x0076022d, 0xbb00cc3c, 0x2313f223,
-       0xe02353f2, 0xcdbe5e34, 0xbd974e19, 0xfb8e6d8c, 0xf4051ae0, 0xf0df5b5c,
-       0x6479bc74, 0xd747d579, 0x4b8ef7e0, 0x7bf7f8b3, 0xaf249acb, 0x65a3d064,
-       0xe4871e5e, 0x3368b6f0, 0x9a1e2287, 0x507d44df, 0x71b928d2, 0xdfa8e0fd,
-       0xdf182612, 0xabde18f3, 0x92d3ebe7, 0x5ef483fa, 0xb10ff5af, 0x3a3f3c90,
-       0x772a73e4, 0x362dfdae, 0xaf3dfcc5, 0x52bbf6de, 0x50b7812d, 0xc7f7eadf,
-       0xa8f96db7, 0x20aa7bfb, 0x7d7ded7f, 0x469f497b, 0xc72f5b9c, 0xe5ba38fe,
-       0xa3e3c745, 0x7dd14e43, 0xd6187fba, 0x079a01f4, 0x2e4ef3b1, 0xff75abc0,
-       0x14787a54, 0x27785fda, 0x4f1fce2f, 0x704ba148, 0x059a7a5e, 0xef76c12e,
-       0x3768bd29, 0x80ec6a7e, 0x5e0cf2da, 0xdc4df309, 0x01ffc249, 0xfc00cb67,
-       0xc7e9dd64, 0xa4e1c2ff, 0xe609ba16, 0xafefeab6, 0x1ecdefc1, 0xc032d018,
-       0x8ff7f002, 0xe0993a5f, 0x419e5a8b, 0x04eac2f8, 0x196b0f0e, 0x03fbc320,
-       0x23267d83, 0xa3bbd6fd, 0xa109fdcb, 0xc5fef46f, 0x891df60e, 0x84aafb43,
-       0x2c783bcf, 0x757a06da, 0x4db1d17a, 0xd31f01eb, 0xf49623ff, 0x5bb6fadd,
-       0x1e13f3ae, 0x6f8c7e82, 0xa6f8114c, 0xbbf49179, 0x5f44f642, 0xba130b9c,
-       0x6f4ce9e9, 0x71bcd0f6, 0xb416c569, 0x0fa6521f, 0x55e379a5, 0xee27ef97,
-       0xe9e9dd51, 0xc4fe9e24, 0x5bfae6ed, 0x46bc50b6, 0xb24e43ca, 0xdf171eab,
-       0x23b90067, 0xba0870fe, 0x3c7cdc58, 0x73190dff, 0x80001bd1, 0x00008000,
-       0x00088b1f, 0x00000000, 0x7dddff00, 0xc594780d, 0xbbbcf0b5, 0x26effeef,
-       0xb24d9bbb, 0xf379f909, 0x71100843, 0xa9189313, 0x18884dd6, 0x220bb531,
-       0x49716b62, 0xc93049f8, 0x2d16ad46, 0x544859bd, 0x46d10882, 0xe1b80a04,
-       0xfd2b6202, 0x1a8c4582, 0xf68882e8, 0x72dfbd2b, 0xbd3fadeb, 0x8a7e1bd7,
-       0xb4564288, 0xeb6dea5c, 0x2666739d, 0x5c9377d9, 0x9f7b7aa8, 0xbe8f8be7,
-       0xcef33bce, 0xfe73399c, 0xb3339ce6, 0x9086bb1a, 0x258e4264, 0x4ec730dc,
-       0xe631df9f, 0x224c9d15, 0xf433bba4, 0xc84b499c, 0xc421127b, 0x09f04845,
-       0x0e7b6853, 0xd1eddf21, 0xb4897504, 0x734de1de, 0x44b2d116, 0xc345bd7c,
-       0xd57fbde5, 0xd2b3e5de, 0xd32d3172, 0x9912abe7, 0xbd33f58b, 0xfe5a0e69,
-       0xa7aefe02, 0x9f561ee5, 0x58ad25ae, 0x7fbec39f, 0xe5dc84aa, 0x76d4cfa3,
-       0x7d296e3a, 0xb5b89dae, 0x916b8e9d, 0x0bca1789, 0x5d6c16e7, 0x736a614e,
-       0x897842cc, 0x51269bd7, 0xe6364ef8, 0x76d1566a, 0xc8afa7bf, 0x515c8435,
-       0x97b0cde0, 0xff40f9d1, 0x44d21c74, 0x3c369527, 0x37981cfe, 0x7ad7afad,
-       0xcf3a64b3, 0x39fe1ddb, 0xe35ebed0, 0xd0b4429d, 0x77c0b789, 0x8823b405,
-       0x3b76399f, 0x40f227b6, 0xffffbc19, 0xb8954f08, 0x4f115fee, 0x7534ef77,
-       0xf8242c9d, 0xb7fd05f7, 0x2aa1d7b9, 0xbad2fa07, 0xcb871a4e, 0xd0ffc377,
-       0x24ad4871, 0x2c3a1493, 0x8d6e22ab, 0xbfe836ff, 0x7a07e979, 0x513781a2,
-       0xf02ff43d, 0xeb0a4ebe, 0x82fce952, 0x76cf24fb, 0xb2cfdec2, 0xe8959211,
-       0x21e613bf, 0xc3f79ee0, 0xd17f34e6, 0x3f2c7cf0, 0x76e6a978, 0xe4b79c5a,
-       0xf4edaecc, 0x590f79fb, 0xdb865108, 0x9d711ed3, 0xb8cf7fdf, 0x9f495c9a,
-       0x86b0defa, 0x19fdebe2, 0xb69cb3c4, 0x1a435f7b, 0x73efff00, 0x743f95bc,
-       0x853211f7, 0xb5d95f90, 0xd0499df8, 0xbddbe483, 0x53b7e288, 0xd0234122,
-       0xd23d4cc3, 0xd28860c3, 0xfeb095c3, 0xfbe87d74, 0x872707ee, 0x067d7482,
-       0x619100c9, 0xbec4153e, 0xbfa9895d, 0x29eb00a3, 0xb44d049d, 0x0e68da3e,
-       0x5e80956d, 0x50a5a028, 0x5feb093f, 0x07fad895, 0x38e230ef, 0x1d1933dd,
-       0x433a3776, 0xb6001cc1, 0xc6de008b, 0x7694a3a2, 0x64487482, 0xb69994ef,
-       0xe36c7c61, 0x3a52c172, 0xb4dbe2f0, 0xe4dab23f, 0xb01f4f19, 0xbb943284,
-       0x4a3c7152, 0xbe91ab0f, 0xfd470664, 0xab42d38f, 0x394f5c70, 0x36a3cbac,
-       0x1f787cef, 0x014591fd, 0xc89937f8, 0x7d09634a, 0xe8c3a44a, 0xe1c0eba4,
-       0x134f5d21, 0x60bb83a0, 0x7f878a00, 0x536f386f, 0xd89ffbe8, 0x08038425,
-       0x484e58cd, 0x75f5611d, 0xa4c72ccb, 0x86d4f029, 0xddf4090d, 0x03bc1bca,
-       0xd972be82, 0xf3fb48d3, 0xeb22ba73, 0x83c036a3, 0x804bbe1f, 0x29b73ffe,
-       0xefd32856, 0xd3f2c0a7, 0xbf870bef, 0x7df039ff, 0xe0c7c019, 0x65166d27,
-       0x1f8c34bb, 0x80b9fcf1, 0x6f69ebaf, 0x9c6278ec, 0xd98f7ef8, 0xf007ffbd,
-       0x4e1ef145, 0xb45e0174, 0xf0f1aeb8, 0xc7d1f4ba, 0x5e7eb44d, 0x82b1d69b,
-       0xd4bfd3e2, 0xf015f386, 0xbd1a95de, 0xec8de48e, 0xa5a594ff, 0x2ff9865c,
-       0x964f7465, 0x62e22819, 0x2e1fa2f1, 0x485dd253, 0xd23587a2, 0xf0e5ef28,
-       0x517f8001, 0xf8f7cc77, 0x621abfdf, 0x21be09db, 0x3f07148a, 0x92452ba7,
-       0x12fcdd61, 0x3ebd375b, 0x56e40f3a, 0x9f02dc3c, 0x8de5c6ff, 0x7c788ba0,
-       0xbbe01bff, 0x5dbe246c, 0xe84c81fa, 0x80d4bfd7, 0x9fef8a78, 0xf77e1090,
-       0x4d0489b4, 0x4bd6ee94, 0xfaebd212, 0x90212d07, 0xe8a6839b, 0x6067c00e,
-       0xdeb88dff, 0x0acd1ae7, 0xea364da1, 0xf705bf19, 0x171f18db, 0xdc80140c,
-       0xece7473b, 0xee73eba5, 0xa09eda37, 0xa4208024, 0xadda37e5, 0x5ee7ff40,
-       0xb3f589be, 0x5a10a2dc, 0xe986000e, 0x7fe081b8, 0x578a11b6, 0xc7119669,
-       0x0a57b13f, 0x8fbea019, 0x5e4639e2, 0x36ffa39e, 0x8dcb0c94, 0x3800a841,
-       0x07082cfa, 0x8e23699d, 0x59335df7, 0xd16fc745, 0xad0d5e48, 0x2932596f,
-       0x31e0ced4, 0x16d5cac6, 0x4a90e90d, 0x45bff986, 0xdee0bc73, 0xa7275622,
-       0x60ac7970, 0x851243bb, 0x3ab8c9b3, 0x05fa05a2, 0x4bf5a03e, 0x78673ea0,
-       0x7f565a1d, 0x479817f4, 0x7d351ecb, 0x9eaf3d34, 0xba5892c7, 0x17a619ca,
-       0x17c3294b, 0xf1a126a9, 0x2f1b5e14, 0x21226a5b, 0xe963e02d, 0x2ae27234,
-       0xc0e0f4da, 0x5b23a074, 0xa3a92f69, 0xe269c0cf, 0xa7b8510d, 0x36bcf7f6,
-       0xd477b68e, 0xba613244, 0xcdbfa581, 0xf0d5793b, 0xaf380b3a, 0x4b427fe9,
-       0x7e1e38ac, 0xeef14147, 0x89bb62b6, 0x7d88aeb3, 0x92efc0ae, 0x0f2f4c35,
-       0x1fe02bc0, 0x75cde999, 0xfd526f5c, 0x617af28a, 0xafd404d7, 0xce40ffa0,
-       0xf4c0953d, 0x903dc831, 0xaa8e6d33, 0x9e741cab, 0x14d56766, 0xc71b1947,
-       0x27e98367, 0xa788fea1, 0x243d78eb, 0xb5e6a5da, 0xc75ab716, 0x0cf9476e,
-       0x90dd16f1, 0x2c88e4c8, 0xafd17961, 0x10ab3d75, 0xe6e9193e, 0x2839cdde,
-       0x97481b97, 0x89bce81e, 0xc740f484, 0x98248c8b, 0x1162e940, 0x9f48966d,
-       0x881bd78b, 0x8d7eb312, 0x89b97521, 0x49bb85cb, 0x7bbfbf04, 0x357d5c67,
-       0x7d68db09, 0x2d8491b3, 0xd755ecf0, 0x8e7d50b7, 0x85f7d67c, 0xe93df621,
-       0x8bbdf366, 0x3aa3bbaf, 0x79d3f5a4, 0xdd51306f, 0x5d0684ea, 0x97533eb8,
-       0x267ae0f5, 0x1e737896, 0x2bf2bd06, 0xa52b679d, 0xf5f03fdb, 0x6639f812,
-       0xbc00aaaf, 0x9c1ab59b, 0x0361f47f, 0xd524e7e2, 0x6bfeb0e3, 0x59aee41d,
-       0x8dae79f4, 0x8075f378, 0x2cd67b26, 0xaf3c48db, 0x00d4c57a, 0xd0e0d374,
-       0xd32ae8a8, 0xf972c3a1, 0xe5ff8e0a, 0x1cd6d096, 0xa014f744, 0xa15cf2a7,
-       0x9994c957, 0x474c7cb4, 0x6e5a3bed, 0x43f56399, 0x4f60037f, 0x0efdf2d0,
-       0x77eecf26, 0x453d71e8, 0xd057cc59, 0xfb071d0d, 0x9ec55f33, 0x43658e02,
-       0x74609fed, 0xbaf0f5c3, 0xea0f7346, 0xd5fa21e1, 0x22dfa410, 0xfaf01e9f,
-       0xf32b970a, 0xf8a16ec1, 0x1412857e, 0x2f608fc8, 0x3e295fb3, 0xe5a52de6,
-       0x79174e57, 0x67402956, 0xf2bcde4c, 0x4159331d, 0xccf37c87, 0x27fb1f4f,
-       0xb4fe7f5a, 0xfad0315e, 0x746b4005, 0x88915efd, 0xbe0bc617, 0xbe810868,
-       0x7b33d26c, 0x15ff69b4, 0xfbd19ecc, 0x71842c37, 0xc079d05e, 0x084a69de,
-       0xeb03b73d, 0xa2943cd3, 0x863aabc9, 0x16cbe0cf, 0xf439bdf6, 0xa0bb9fb3,
-       0xa413d53e, 0xff26a3ed, 0x74d75846, 0x7a889283, 0xc25ad7f9, 0x381709c6,
-       0x878f5e28, 0x9c7ddd98, 0x4e304956, 0xa1fb0dbf, 0x90b69a7c, 0x33a273f6,
-       0xe543e715, 0x2759da2f, 0x82b618d6, 0x34375dfc, 0x8fed84ae, 0xd3d37ceb,
-       0x8bf8f968, 0xb4e59ec5, 0x0fa7d06a, 0x073d29eb, 0xafbb32d6, 0x016ca35e,
-       0x16fd90fc, 0x8f58879c, 0xb5c59ac0, 0xb2581f50, 0x8f9016ec, 0xc839f163,
-       0x3723127b, 0x166891cf, 0x86c6d3f0, 0xe830dedc, 0x1e89fe95, 0x4dc4af54,
-       0x8dd29f17, 0xa93db59d, 0xee8df863, 0x5f3d21d3, 0x1740ff6e, 0x43d33972,
-       0xca804e30, 0x0ff82265, 0x594c72e5, 0xad995a3b, 0x5495e063, 0xeba9df6e,
-       0x47fc1253, 0x9e5a5d60, 0x97f78ffc, 0x145e302a, 0x4ae922e5, 0xa93cbe46,
-       0xba03cef3, 0xf5875475, 0xfd7a3175, 0x99d983a4, 0x076e06f5, 0x963eb092,
-       0x797d450f, 0xc5ee9a95, 0x7fa704f3, 0xf7c9845b, 0xce1af591, 0x401ab71f,
-       0x20654d8f, 0x23d06c93, 0xc15fe856, 0x0e9ea7fe, 0x3969ebeb, 0xbf58597b,
-       0x4f813f88, 0x46c3be28, 0x1b93ef3a, 0x29bf8c6c, 0x459fa01a, 0xe5f50415,
-       0x63b52d22, 0xd2bde04b, 0xe5d74037, 0xa40e8bd4, 0x8a67f22f, 0xf9ef8a15,
-       0x5033b784, 0xb1ca97bb, 0x30a43a97, 0xafe60bec, 0xe5356c37, 0xb57b5f00,
-       0xcdcf5836, 0xf9b1ca12, 0x1b05951d, 0x9ec97968, 0x13fd702b, 0x2e5d182a,
-       0x2f503909, 0xb1f2e54e, 0xa3d210de, 0x8933fe1d, 0xf6883ec0, 0x1374f68f,
-       0x64ad28fd, 0xae401e24, 0x1421e8ab, 0xd1f6a653, 0x57265ed4, 0x24e79509,
-       0xf2126ec6, 0x8938e41e, 0xf4d503b3, 0x88fa1411, 0xa4a23dc9, 0x7213dc82,
-       0x97dd98f9, 0x3e3b44e8, 0x97d6153f, 0x9b9327ae, 0x6bc425bb, 0x7d456933,
-       0xd0c0f422, 0x9c8f5cb8, 0xbe9906d2, 0xcf813c32, 0xae0e677c, 0x8bd212eb,
-       0x95e844fa, 0xdf20e8b1, 0x88fbe1a9, 0xbc60e9d1, 0x9afec153, 0x75f0934e,
-       0x65a6bc74, 0x853cdc24, 0x50536d3d, 0x693d323f, 0x9e127a64, 0x97d0cbe6,
-       0x5e31faf1, 0xc1ebc61f, 0x77d33d54, 0x3d859d62, 0xd98d3a93, 0x85975301,
-       0xfc08a4b4, 0x94eade35, 0x26bb61e4, 0xa8d18ef0, 0x1f65095c, 0x9ef905c9,
-       0x2a62f950, 0xc4c80fad, 0xa1657c0b, 0xefa1e978, 0xb7fb7337, 0xd7cd9527,
-       0xabf467ad, 0xd8a47d93, 0xc112eb0a, 0x99346f7d, 0x051e81d8, 0xe8db373e,
-       0x1df02577, 0xefa1b7e3, 0x1cc3a48d, 0x2bd57df3, 0x173fd426, 0x0c85b65e,
-       0xb3f88f68, 0x94bfb41d, 0x4ed01bdf, 0x0d8af73d, 0xae39e9f5, 0xefc25d0f,
-       0x7e611e40, 0x41aebe16, 0x008e3552, 0xc6334bed, 0xf6140881, 0xd983b359,
-       0x21ed2359, 0x99139f5e, 0x80cae8c3, 0x8e0bcdfb, 0x4ca00781, 0x7fa021e1,
-       0x7e32716e, 0x5699ec0f, 0x3efa43fc, 0x187ab3e0, 0x40c5fdf6, 0xf7ed06af,
-       0x7d2918e7, 0x8b2ed74d, 0xd1e7483e, 0x83b5699c, 0xfeceab7e, 0x41dddfd7,
-       0xd1ee1fcb, 0xf3ac0311, 0x497369f6, 0xb7f2d8ee, 0x3e3ba431, 0x772fc310,
-       0x9b9754ef, 0x40e5d57b, 0xbf7cba9f, 0x653ae6d3, 0xf9e1d941, 0xc1b5d282,
-       0x87ba7ad0, 0xd5786bc2, 0x8668fa80, 0x1390ffd3, 0x7a26ade4, 0xc86cf018,
-       0xf80a78fe, 0x9ffd023b, 0x5034f048, 0x31148a36, 0x5f5f03fc, 0xb6cfcd30,
-       0x61b7828f, 0x06a311fc, 0x75ad4cf1, 0x173944f6, 0xd2e27ce0, 0x403c3f7b,
-       0x9668bfe7, 0xdf02bed9, 0xcacb6b78, 0x18449ec1, 0x4dfd6049, 0x8bbec21f,
-       0xf5846bb6, 0xb693353f, 0xac3570a3, 0x89b0fa67, 0x6f801244, 0x69dda85b,
-       0x1bfc4ba4, 0x77776fce, 0xf4c3cb44, 0x359dbb7f, 0xf94e0113, 0xe80fb22f,
-       0x37e851e3, 0xeade4ec6, 0x4bfc7264, 0x463299fb, 0x02b699f8, 0x038d9afe,
-       0xfe3a4afa, 0x0cf97ff5, 0xa5e2fde5, 0x823ee1af, 0xb33e63ce, 0xc80a4dab,
-       0x1e0fc5a7, 0xdf62f7c0, 0x8ad32a76, 0x36d7b6fb, 0xa1d95818, 0xcda9f2c7,
-       0xb8b95f6c, 0x3cc10a57, 0x931759a5, 0x6c2f412a, 0x640dd9d6, 0xf1e35e24,
-       0xb7a6c1f8, 0xf5efc013, 0xf61d2201, 0xc7b3127b, 0xb809adec, 0x135a507f,
-       0xac0cbec0, 0x9043f1bf, 0x6b378b8f, 0x902f603d, 0xcff4367d, 0xc37cde2c,
-       0xe85685c4, 0x4aa4d3e7, 0xb96d13f0, 0xd0543c01, 0x7e6217ce, 0xf4f5c89e,
-       0x6ae5bcbd, 0xd0f1f805, 0x62ff0666, 0xd0077187, 0xd17ff5d1, 0x1ac97f22,
-       0xb93b07e2, 0x089def5b, 0xda6cad7c, 0xe7d61d3e, 0x1ae99983, 0x224bbf6c,
-       0x638bc076, 0x5fbc0a69, 0xe03ec92c, 0x8df586e3, 0x4f76b1b5, 0xc7f9939d,
-       0xa597b32a, 0xaf91580c, 0x6d3e80e6, 0x08f94cde, 0xdef59fc6, 0x0d70eeef,
-       0x6b3495f3, 0xa1532dfd, 0x1e7567ff, 0x7b21bbe0, 0x90b7d366, 0x4c2fe0be,
-       0xe398b5f1, 0x99f2abeb, 0xa4f822c1, 0xeae400b5, 0x05ad15e2, 0x8cec51f6,
-       0x44d93e21, 0x213272f9, 0xf9129da7, 0x1993fc02, 0x63bed54e, 0xb59a7dac,
-       0xc67a8350, 0xedde21e8, 0xb74a99f4, 0xb71fb0c9, 0x6f58c925, 0x7d23d24b,
-       0x77ba7fcb, 0xbce86fe7, 0x2ffa749e, 0x26ccbe80, 0x6bd062de, 0x455ed44a,
-       0x35405acd, 0x136461da, 0xcc89afb3, 0x92eb85fc, 0x31558ec9, 0x125373fb,
-       0x39504fdb, 0x73f405f1, 0x1f3fddee, 0x64b6fc06, 0xec053c7d, 0xcfc5c085,
-       0xb35fe0f4, 0xdf284bf6, 0x011f1ead, 0xcff409ba, 0x868a0b24, 0xc3c072e5,
-       0xbcfc46f4, 0x98e924e6, 0xb145751c, 0x82974a9f, 0x41076ee5, 0xd4b8da7a,
-       0x46fef68c, 0x4004c857, 0x2b7cadff, 0xee46a7ec, 0xfb6e340f, 0x740b5785,
-       0xe3ec921e, 0xfe30aca1, 0x17986c18, 0x3e71d2d2, 0xc41796dc, 0x8f4a9ef2,
-       0xb759d696, 0x5ccae3fd, 0xce9f53c0, 0x9eaded03, 0xdf980481, 0x244edb87,
-       0xb61afcc0, 0x0dde7169, 0x16524fa1, 0x09cb0d16, 0x905fc69d, 0x5d827604,
-       0x42f8c2b2, 0xedb87c5e, 0x560594d3, 0x7d403fe6, 0x5e3a3a5a, 0xc9cacecc,
-       0xdff5fdf0, 0x6672eb64, 0x72042197, 0xf9898cf0, 0x33bb45f7, 0xaeffa636,
-       0xcdfe124b, 0x3fd02cde, 0xa2796543, 0xf7c4e406, 0x2efe6ced, 0xf0166f7d,
-       0xba9247e5, 0xb52b259f, 0x52e54424, 0x84894ae3, 0xf33fcca8, 0x20594bdc,
-       0xfedc3fff, 0x0c5d5652, 0x89dff17c, 0x6a498de7, 0xaff09a7f, 0x0ce1f4ba,
-       0x63ceaf18, 0x31cc7e60, 0x3da2abfc, 0xa4fccf59, 0x816b9483, 0x8377c50e,
-       0xd82f660d, 0x18c483bb, 0x5d5b9702, 0x7ad7f73f, 0xd82ef9bd, 0xe3ef88d7,
-       0xf40d5ffa, 0xfa92e144, 0x5827f424, 0x9f28a28a, 0x77fcb4bf, 0x918cf5d1,
-       0x8d9d74ff, 0xc6cd4eb0, 0x0471e1e8, 0x780f43e9, 0x6558b7d3, 0xed2957d0,
-       0xf7a2be8c, 0xe59f706b, 0x814c2732, 0xdd3e80b8, 0x76f9056d, 0x43b9817d,
-       0xb3ef0893, 0x333ed042, 0x0bbf10bd, 0x0ffa3156, 0xc3f410a6, 0x095691a5,
-       0xe676b4fd, 0x20a8cfe7, 0xf8b455f6, 0xe76624b3, 0xbd6789b8, 0x5fd70f36,
-       0xc70738c2, 0x400fd08b, 0xcf2f2047, 0x23a44648, 0x7b425fa9, 0x9de9ab54,
-       0x458efd07, 0xbac52b57, 0x2a1aba72, 0xeae89dff, 0x23c74149, 0x20afcae8,
-       0xa38db95d, 0x23f715d3, 0x127b765f, 0x36bec1f4, 0x2d6be395, 0xfbd13f97,
-       0x2eafc28d, 0x796b7cc1, 0x6b46b57f, 0xc47a0b58, 0xd638fba3, 0xda89bc3f,
-       0x4a7fb0c5, 0x3e9ebb03, 0x57cfb5c7, 0x6448dd70, 0x9608fc00, 0x2fa88dab,
-       0x7244d31f, 0x9d498ec0, 0xe81bbad4, 0x515e7523, 0x0bee3b49, 0x17a01c33,
-       0x7fa2d740, 0x1f34e974, 0x1c5823b3, 0x8f533a28, 0x07969cfb, 0x8ecc7d2b,
-       0x097e41a8, 0xa02936ac, 0xe7f5a707, 0x08fa072c, 0x031e232c, 0x86cf71d2,
-       0x9dcfe045, 0xac80f56d, 0xb225f113, 0x9d77cd52, 0x05538b12, 0x0f18226f,
-       0x0d338e1b, 0xe821f96c, 0xf422c6ff, 0x8ff90c9b, 0x8dea09f3, 0xd6438dcb,
-       0xde2136ad, 0xd068fc45, 0x25741146, 0x3fb191fa, 0x7a646892, 0x407ca468,
-       0x054a73ff, 0xa1eb7f11, 0x3cca2e9c, 0x5ff823de, 0x456ca3c4, 0xc8b01cbe,
-       0xbf399c2b, 0x049c4332, 0xb36c77fc, 0x00fd8416, 0x19598dfa, 0x694fcadd,
-       0x50e92028, 0xaaab9ffb, 0xbcca6233, 0xc1f7d0fd, 0x5f573755, 0xa877fa8b,
-       0x7aa6c01e, 0x26bd9459, 0xc355e205, 0x83b532f5, 0xff127d8d, 0x1be6e2be,
-       0x941eaaa8, 0xee7ff8c4, 0xd11f82f4, 0xc5e35444, 0xf5c727c2, 0x5bfda3af,
-       0x383ede15, 0xefe826ee, 0x7e5112a9, 0xe14bd3a0, 0xf753ab5b, 0xdfe52887,
-       0xf78c4143, 0xaf0e537f, 0x6c319d5a, 0xe17b501f, 0xc36549cf, 0xefa3c276,
-       0x495d76d5, 0x3fd8b2c7, 0x15fe83d5, 0x92e03efa, 0xe7890ed0, 0xf49704d7,
-       0x656becd5, 0xe09d7d84, 0x74f5f662, 0x2fba4960, 0x581df941, 0xdf6023e6,
-       0xe9c4bb52, 0xe3e4bb42, 0xfd680753, 0x1f9f59b9, 0xbb40a71e, 0xbec1e67b,
-       0x4651702a, 0xa9d81bf9, 0x6f94490d, 0xaeccfd8c, 0xe31cfaa6, 0x967e8205,
-       0x38fd39d8, 0x97fc0482, 0x32a4fbdd, 0x5a4277a0, 0x6ba36eb3, 0x379703f9,
-       0xfbe1c713, 0x9779f8cd, 0x205f98bb, 0xa1b55850, 0x26dffa00, 0x5617b011,
-       0x594f1e15, 0x63a9fb80, 0xbe630b29, 0x0a7bec6b, 0x53b8d9f1, 0xcb1e2a37,
-       0x7804e1a9, 0x45f9796c, 0x338dc82f, 0x42650921, 0x04ea1c83, 0x41a1b6bb,
-       0x29211603, 0x03bfcd0d, 0xf5731fe3, 0x5f9d3c64, 0x8177d706, 0xa706b79d,
-       0xbfe9bcc2, 0xd1b57d12, 0xc4e508b7, 0x2b46b9c6, 0xeb0a91c6, 0xd83c41ee,
-       0xc3c05ecd, 0x34aac2aa, 0xe665a718, 0x4dc63b74, 0xf5073da8, 0x077e0f2d,
-       0xae0245fd, 0x1aba7d55, 0xa9ca77b0, 0x0a0bf75d, 0x4673a677, 0xf5f2878d,
-       0xe2eeed38, 0x5710acfb, 0xff8e5d1f, 0x174664bf, 0xf82f921d, 0x8ff452ed,
-       0x677f5892, 0x1fb31f76, 0x55e9716f, 0x5c5bf1fe, 0x36bdaecc, 0xe4069918,
-       0xb01e5fb2, 0x201d5d80, 0x5f604fde, 0x65567c4d, 0x9313ae3b, 0x0536ae5f,
-       0xd74666fd, 0x425763c0, 0xee32b5fd, 0xf03c8867, 0x5cf71863, 0x8ab3cba7,
-       0xf2803e70, 0x90214583, 0xfe5cfbc7, 0x96fac2ef, 0xdcf57b73, 0x831637cb,
-       0x5fd8517f, 0x5099cf9d, 0x94da766f, 0x4e406b27, 0x796649fe, 0x6468c603,
-       0xc967ed1a, 0xb71c4ee7, 0x84ea14d3, 0x68f60ff5, 0xeac9beb1, 0xdbf4045f,
-       0x29faeb78, 0x0d608798, 0xd51e8015, 0xd008bab9, 0xa0bedd31, 0xf2e8c51f,
-       0x4f238811, 0x2597ce0b, 0x767117d0, 0x63f034cd, 0x85c5bee1, 0xce2adc7e,
-       0x1529e31f, 0x2b22329c, 0x34917c74, 0xf9bce76c, 0xbc32d9e7, 0xc68ff614,
-       0xd5eefcc8, 0xec04cd73, 0xf448f25c, 0xf8fc06b0, 0x7b0108ae, 0xc257b9b8,
-       0x5f0b9a71, 0xe5fec3d0, 0xdfc65eee, 0xa0dfbe01, 0x78c2cbf8, 0xedc2cb94,
-       0x67460e81, 0x1c787224, 0xb679f9e0, 0x76d0849e, 0x42577e31, 0xc0793396,
-       0xf8f3d3fb, 0x37f73343, 0xf5884d51, 0xcec25cab, 0x5b8ea158, 0x49d771f0,
-       0xf016af11, 0xfca92c5a, 0xc3d9e2e4, 0x183c4fbf, 0x1bfc0e9d, 0x7e05f4a5,
-       0xccd20da7, 0xf3a75e7b, 0xc93650db, 0x9b98a603, 0x04b69392, 0xa45253de,
-       0xfbed2f78, 0x0dd03a64, 0xafc821a9, 0xda957d2d, 0xeb8b2b66, 0xa58c5e60,
-       0x53ea07b5, 0xfd442aef, 0x5993710c, 0x1cb3fdf4, 0xe65669af, 0x08af73c7,
-       0x341c40e6, 0x9eefa0f1, 0x2bfc61d7, 0x4d87e8cc, 0x73636ba5, 0xf82573e2,
-       0xf8a4dcbd, 0x7767e800, 0xf00252ad, 0xc41f7888, 0x0d16670b, 0x3d38e3e7,
-       0x7d2b7792, 0x983976ee, 0x6a40cedf, 0x1f785e00, 0x1fc70eb2, 0xe3079fc1,
-       0x9e0f7c42, 0x32c2d2e7, 0xc0c9fffa, 0xefb8ed96, 0x483e6037, 0xef1bdf6d,
-       0x35adfe80, 0xc78c5e92, 0xd52dd9c6, 0x02beb789, 0xf6783ff4, 0x018796d4,
-       0x7af6dbae, 0xce25ef30, 0x9bfeb91e, 0xb33f3ecc, 0x3f00a2dd, 0x9b72e56c,
-       0x27c88fda, 0x3f6c5dc1, 0x1e476f19, 0x27f7a975, 0xddafe543, 0x05f0648e,
-       0x0b3cb3b7, 0x7c03df21, 0x70d837ff, 0xd7f4013e, 0x13c10dbf, 0x8db20f97,
-       0x8ff483e7, 0xe6f20f9e, 0xe8104b0e, 0x09af7ce1, 0x8f3292fd, 0x45b59d7b,
-       0x7524001f, 0x01cf0e38, 0x72581b79, 0xca1ae7e6, 0x8b0f727f, 0x8f12c923,
-       0x4b4afd33, 0x6bcc5c58, 0x808bff07, 0x774c765b, 0x3e408b7b, 0x713779b2,
-       0xb39351bf, 0x2ef16140, 0x94d43796, 0x7b002e10, 0x87ae55ea, 0x5e2ccc9a,
-       0x87d0e835, 0x26a35d61, 0x185d1fff, 0x93df62d7, 0xd8941a5f, 0x884f56b8,
-       0x0a2775d9, 0x9d3d6135, 0x07d80f67, 0x59ab6eb0, 0x9f286b7c, 0xc7a1bf60,
-       0x5890e2c0, 0x41ccec1e, 0xe22f5939, 0x3f99fb56, 0xa7c79eae, 0xf45acc4e,
-       0x745ca40c, 0xb035ad48, 0xaab0bb3f, 0x0fe8fd12, 0x9f13393c, 0x7ed52bf5,
-       0xa7e045ff, 0x238e1bcf, 0x1d7bff0b, 0xbd99e8f1, 0xd447ec3c, 0x5945fb50,
-       0xbe815729, 0x15f621cc, 0x2095ff20, 0xe9abad5d, 0xc13e83b3, 0x12349768,
-       0xa77239d8, 0xfbeb0ccb, 0xf5068768, 0xe343b054, 0xcf027685, 0x8fccc939,
-       0xf3324d74, 0x0aa5d06b, 0xd9e238c1, 0x0771e3a1, 0xa272dfde, 0x2353c309,
-       0x76a3e7b1, 0x7d3466b9, 0xd0ebfa2d, 0x4fc11ab5, 0xa0d4cd17, 0xde82fbdf,
-       0xc6fd173b, 0x790202ce, 0xd6b61d54, 0x1eac3595, 0x2982e779, 0xebfac3ea,
-       0x12486664, 0x33f209c5, 0xcbe79935, 0x616de1c5, 0x1f1cba97, 0xa90c698f,
-       0x3fc4f5cb, 0xc58f2d21, 0xa7df620f, 0x75f93326, 0xc70e5561, 0xe3f307b7,
-       0x6797fcc4, 0x3269bc30, 0xb33733d9, 0x41d02e6a, 0x7397c42e, 0xabfcc9e0,
-       0x7f082674, 0x092e75ee, 0xde0e23e9, 0x80da300e, 0x3c593abe, 0x3f856ff4,
-       0xe4caee1e, 0xbc1fae14, 0xd65f886e, 0x8f18f5db, 0x493f5cbe, 0x0e5ab25d,
-       0xfebf950d, 0x27db2cfd, 0x9e796a75, 0x50e51d8d, 0xe5cd9d9d, 0x11d9e484,
-       0x6a56f786, 0x3a3cc02f, 0x3f6025b5, 0x8ad5bb4c, 0x6fd968f3, 0xf3703f42,
-       0xd02c81b2, 0x03552de3, 0x89b71005, 0x2b402fc7, 0xdb45f90b, 0xfee8b9d5,
-       0xd884ec03, 0x4b5f3c76, 0xfef5671d, 0xf60cb920, 0xbf762739, 0xb76afa01,
-       0xfd15f509, 0xf00603bf, 0x839cbcb3, 0x3687ccf6, 0x0bb41b7f, 0x9e5bc398,
-       0x85bb01cd, 0xfdcd4dd9, 0x0bb01e86, 0xe2623aeb, 0xd59ff07c, 0x591fb8ea,
-       0x3bff44e9, 0x6fbf56e9, 0xddf714d8, 0x17603888, 0xbd3af3ae, 0x3bf0227f,
-       0x7f983bd5, 0x8351b670, 0x5af50379, 0xb79022cf, 0x7b6a4d67, 0xad8dacfc,
-       0x75a196d7, 0xb5bda0f6, 0xf675cc65, 0xd73ac014, 0xb63f886b, 0x6758669f,
-       0x7c4dbeba, 0x78becf9d, 0xf3ac0175, 0x2eafbbc7, 0xa75e7580, 0xdf02f2eb,
-       0x5bfc39b4, 0x27bf6993, 0x3da1f06f, 0x2f58f225, 0x24f71e97, 0x432bfdab,
-       0xff21ffe5, 0x30fa58ca, 0x5a87043c, 0x4af4ba1f, 0x3a83c806, 0xd5bfe1a3,
-       0xaa37f08b, 0x4068cf1f, 0x3ffec77f, 0x0766ba7f, 0x2d7e81c8, 0xbfa223da,
-       0x0f3fb2fd, 0xeffda1ec, 0x69413db8, 0xb91bfeec, 0x246dd85f, 0x88abf041,
-       0x27b0807d, 0x5bf1e5e3, 0x251f3e7c, 0xbb006f7b, 0x8dfacbe6, 0x633bf81b,
-       0xe76653e8, 0xcc3c936e, 0x7e8bdc6f, 0xf37d96e4, 0x3e27e0ed, 0xe37e621d,
-       0xd18b1796, 0x7a18dc6f, 0x65790c2d, 0xc3b25fa4, 0xdb71a3fe, 0x07c804b1,
-       0xba5cfb10, 0x8c933daf, 0xefdea8f4, 0x489d0e9e, 0x0a01fc80, 0x71e82577,
-       0x07aa2b8b, 0xfba16fba, 0x6c23c83d, 0xa187a391, 0xc11716df, 0x3ed2973c,
-       0xc44ffef5, 0xf4fa3779, 0xf6377728, 0xd790214b, 0x4e7f7a29, 0x9235e806,
-       0x2078c761, 0xc98bb3e7, 0xb294d4de, 0xf7baf8d8, 0xe1e4e4f3, 0x0d81b07c,
-       0x03bf4889, 0x83b5e23a, 0xe360db3c, 0xf9464cf2, 0x8e4dc7f6, 0x630fcb10,
-       0x6218ffed, 0xc8a34276, 0x5849930b, 0x68b5eba6, 0x585df7b6, 0xe1f7906f,
-       0x5b1f7938, 0xbbfb7116, 0x52f51849, 0xca181933, 0x176d8b0f, 0x7887d71f,
-       0xd21faab8, 0x1f80ac5a, 0x07ab4eec, 0xb8f881e0, 0xf6c83eba, 0x961f94eb,
-       0xafd30c96, 0xbf410758, 0x1d0fdc2d, 0x08fe3868, 0x4fa06fd0, 0xd77d83b2,
-       0xdbf461e4, 0x905bf744, 0xefcf1b47, 0x379d57a4, 0x97ff163a, 0xd1f5a8a6,
-       0xe4eff950, 0x453ebd5f, 0xfe62f7cd, 0x343f6fc2, 0xf1897ecf, 0xe2bcdc65,
-       0xfef1a9f7, 0xbccfb176, 0x2738795c, 0x870f2d45, 0x79677fca, 0x2eb43758,
-       0x1d50f2f1, 0xe59bf8cf, 0x5c70ffe1, 0x4f7d99e3, 0x03bec027, 0xa7d878ec,
-       0x63aedcac, 0xfd1413f9, 0xe9e2f1b1, 0xc597ab5a, 0x5ea2b54f, 0xa657871d,
-       0xe33c38f3, 0xd45ed7eb, 0xf335bae2, 0x3ef37138, 0x369a079b, 0x9c631758,
-       0xba7e3e36, 0x0e9eec84, 0x471f154b, 0xce7e026d, 0x753c74bb, 0x8f8b0a75,
-       0x20725852, 0x6f3e216f, 0xa7eb35eb, 0x7598fe49, 0x1ba22aaf, 0xdbe85182,
-       0x33890728, 0x14c6fde6, 0xc6bf5766, 0x7adc8bf3, 0xad608e76, 0xfd85e2cd,
-       0xf2c35b8c, 0xf2e07e9f, 0x18bc826d, 0xfaf1c2a3, 0x4344edf2, 0xae8cf2f1,
-       0xb04ae517, 0x3901ead9, 0xa237fc28, 0x5e3c8bff, 0x3ffad971, 0xfcf7de8e,
-       0x3c7bd30f, 0xf18bf67e, 0xddb8d6fe, 0x151b8a7a, 0xe3a4105f, 0xca5f1023,
-       0x63bf4919, 0x1d1633f5, 0x1df14d1f, 0xfe766149, 0xb857cc14, 0x2963394c,
-       0x3f009e8d, 0x5063d911, 0x7e09afc0, 0xab8fd412, 0xaa3e78d3, 0xe6267ca7,
-       0x2573b369, 0x58ce1ce2, 0x4307e476, 0xc8ecc3eb, 0x9f5cc60f, 0xde47672f,
-       0x087df0ee, 0xd2b27674, 0x1e01e78b, 0x61f851b5, 0x619cf87f, 0xe22e73d4,
-       0xfca5c63c, 0xd1c45f2d, 0x4bff17d5, 0x3a92d472, 0x75f95d96, 0x13cfd1cb,
-       0x763a7fc0, 0xff9e413f, 0x45bc4119, 0x6b6449f7, 0x103b5f8c, 0x197bf961,
-       0xfef15e1c, 0xa1bef83f, 0x999bd521, 0xfc7fdf4a, 0x1248d1ae, 0x652e9ea9,
-       0x67c5b172, 0x4b42b8c5, 0x697fcb2f, 0x8e504659, 0xb4df80b7, 0x3389fc08,
-       0x4f7dd809, 0x2013fd3a, 0xf7d1ee8f, 0x226d41ac, 0x1167dbf8, 0xbdcef3b0,
-       0x9c33cacb, 0x6798c9fe, 0xe3006cb7, 0xceb3dd18, 0xf9561e60, 0x523e9f17,
-       0xa2f08a53, 0x5065c13f, 0x3db9679f, 0xf133c995, 0x6f843d9c, 0x3ff3fa2f,
-       0xdaf9606e, 0x0ed79701, 0x0fe1097e, 0x8c1128b7, 0x61ecb42b, 0x96b95bc6,
-       0x30fc87cd, 0x65a9e903, 0xf831654f, 0xa9af494d, 0xf2ddec18, 0xdf715bdf,
-       0xe983f1f7, 0xcfb12798, 0x7c02afe5, 0x37434ad8, 0x4d9a7d81, 0xf7bb01c7,
-       0x1537dde3, 0xfe42dc03, 0x39bf03ad, 0x4d9d7f1d, 0x462717ed, 0x64bf7796,
-       0x33ee2647, 0x5afeac9b, 0x133aff98, 0x9db82383, 0xfee14f9f, 0x17fe78f2,
-       0xd5aa9f7c, 0xdfa938e0, 0x5c9c6235, 0x3a7585c8, 0x0de637e2, 0x9e1293cb,
-       0xf1701867, 0x99fec73c, 0x97854f2c, 0xbe752ead, 0x37c947e7, 0x253c0094,
-       0x8b57f2a9, 0xe4475967, 0xb2a4940b, 0x5cea9678, 0xb322e5a2, 0x7aed73a7,
-       0x4adb27a4, 0x9454e2c2, 0xbfaec09e, 0x06991a36, 0xbbf2bce7, 0x9e02d7c3,
-       0x20d45ff7, 0x4799e49e, 0x28933e30, 0x56f2f1b1, 0x004e740f, 0xadfd8c7f,
-       0x954960eb, 0xa0157b2e, 0xefa749f4, 0xffe45481, 0xaf1842d6, 0x2c745fea,
-       0x059f72bf, 0x59dd0cfd, 0x795f984d, 0xea833dee, 0x33fc4e7c, 0x3e605648,
-       0x6fdf6e65, 0xdb604e31, 0x279a8d23, 0x15aa44fb, 0x1825a6f9, 0x36398e99,
-       0xce50bad7, 0x1f7efbca, 0xee43bb04, 0x91024194, 0x03579d0e, 0xcb82d3e7,
-       0xc7f5fa09, 0xb035db77, 0x3f3cd95e, 0x7fff7066, 0xbee3f14e, 0x4205c445,
-       0x3749bf2c, 0xc7ec08f0, 0xdf03e5e4, 0xec7ac20c, 0xc05a6871, 0xb68baa7f,
-       0x9f65dfa0, 0xd9acfd05, 0xbe2b797d, 0x2bd9cb41, 0x1b0718ed, 0x6ceee57c,
-       0xf3a7e7cc, 0x3cca3f1c, 0xf9654a1f, 0x8b3ef248, 0xfc99f406, 0xa8c0f104,
-       0x0aa523b2, 0x968a7ee1, 0x07df3f69, 0x8e1e4a7a, 0x0a3f829b, 0xaa4354f4,
-       0xcdd0077f, 0xa5a4b9d0, 0x892e7666, 0x2db5a79f, 0x9c176f7d, 0xfdc2d9f7,
-       0x4ff707b9, 0xbffe859e, 0x7582594e, 0xf960e0b8, 0xb2a42f95, 0xfc48e278,
-       0xd63cc41f, 0x65bf7ddc, 0x02e28d7a, 0x8c7597fa, 0x574ee45e, 0x5f19f80f,
-       0xde63f049, 0x611d75ee, 0xeccdc62d, 0xa35c7f27, 0xd677ecc4, 0xb2d33d33,
-       0xe3cfed93, 0xd29737f7, 0x921ebf2f, 0x0cbf4c33, 0x764eff95, 0xf4e2efcb,
-       0x6fbcdfca, 0x5efdea21, 0xbf12fdbc, 0x8f611bbf, 0x9637f5c7, 0x50f2231d,
-       0x61c786aa, 0xd84db4f6, 0x9e554149, 0x9f95954e, 0xfbaa343b, 0x47649f5f,
-       0x3b79107a, 0x72caed29, 0xfe8fdbc8, 0x4edfa088, 0x3c8915e4, 0xcb1560a2,
-       0x8c6a09f7, 0x4dd12e78, 0x687f30ba, 0x124b091c, 0xf006d7fa, 0xe42a6dfc,
-       0x4fefd111, 0xff62e6a4, 0xa567899b, 0x22a6e516, 0xc826fc01, 0xb802493f,
-       0xc1161b43, 0x7159b778, 0x9fe4133c, 0x033ee124, 0xc7dd39f9, 0x35a756f2,
-       0x3a43b8b0, 0x4e50cfd5, 0x697467cf, 0x3cc7ab9a, 0x22579156, 0x5e044ff2,
-       0xd3be38aa, 0x01ca2c27, 0x54f228b9, 0xe53d99d6, 0x39c11760, 0x1cbf3868,
-       0xbcf3346c, 0x776fd613, 0x4f9e2e63, 0x2979b2fe, 0xf91678f1, 0x7f44fa29,
-       0xe46cbba6, 0x37416739, 0x7089eb31, 0xecc7dc6d, 0x3d06aafc, 0x71b063ce,
-       0x072bfa06, 0xec04351b, 0x037eaa81, 0xf1b8c3a3, 0x93d5ce36, 0x872bf430,
-       0x054f204c, 0xceca5c3d, 0x085beba5, 0x6d83e0fe, 0x524ef33b, 0xd6d43fde,
-       0x9341cf8b, 0x12bdabd4, 0x03cea1cf, 0xb48df5c9, 0x1af95afc, 0x6689b7c8,
-       0x6a849449, 0x96faafd3, 0x60c4f54c, 0x287df472, 0x7be1bedf, 0xba3e3cac,
-       0x9beda245, 0xed623ed3, 0xa9d33681, 0xefff5ed8, 0x57eb41b5, 0x267f7fd0,
-       0x351cf9f1, 0xebf464ee, 0x3f41123c, 0xa57fd712, 0xadba3e4c, 0xdc9fb47a,
-       0x54951f3c, 0x8854fcf3, 0x7b72d0f8, 0xefc6315a, 0x13d944ad, 0x030cfa81,
-       0xe30827b3, 0xccf1f687, 0xf4e46d6f, 0xbf843240, 0xf208206a, 0x81c73dae,
-       0xe7c90fdf, 0xf310863d, 0x8ff1b19b, 0x9e0578be, 0xb679124b, 0x6733d884,
-       0x36f9815f, 0x135af2aa, 0xdb29a73f, 0x7bbce133, 0xc1db8ebb, 0xe6c47cbc,
-       0x04f3885f, 0xddf6a4be, 0x507e1bd1, 0x7674fc04, 0x41f30fef, 0xa7a8ddce,
-       0xe45184fb, 0x933a595a, 0xeb3a836b, 0xb77e894a, 0x016fe6c6, 0x32c77c3a,
-       0x311c3a6f, 0xa9549b9a, 0xc1bc0077, 0xd780b4e7, 0x8e274e64, 0x473e0cd9,
-       0x3c824fb5, 0x1b1376d4, 0x7b2fd937, 0x7f845cf1, 0x851b74b6, 0xf2625dbb,
-       0x88947e9b, 0x92a15576, 0x26c87108, 0xcb55ee7e, 0xcb9688e5, 0x1b6e7f91,
-       0xc1a997c8, 0x13ef4d78, 0x7fe7b05a, 0xbfe2e3cb, 0x9f9f51cd, 0xb83371e8,
-       0x569673c5, 0xcfe802b9, 0x523aaba5, 0xab40e94b, 0xfd7084f7, 0x37186d32,
-       0x772b603e, 0xa5efd00f, 0x42951fec, 0xe67b773e, 0xbe214a8f, 0xdc7a75a7,
-       0x8f7298be, 0x357fd19b, 0x59bc03b4, 0xefc14b5a, 0x97f5b5fb, 0xfa2bfb48,
-       0xf50dfdf2, 0x35706063, 0x7059a319, 0x9359fe6e, 0xffac3b7f, 0x30c7f985,
-       0xfa40fc2e, 0xaf21f7d1, 0xd18ea8e3, 0xe793305d, 0x69ee93e3, 0x0eee9409,
-       0x5e7839e7, 0x1ebf8b0a, 0xa8fcc09e, 0xfcb17e54, 0xe61289d1, 0x66ced621,
-       0x266f62e7, 0xfa018e91, 0x68593a3d, 0x1c8af4fd, 0x796b7fb4, 0x77f4c89e,
-       0x7eb0097c, 0xca8f6fd3, 0xb2c7f720, 0xeb746ee7, 0x3e188194, 0x975149be,
-       0x97542e6f, 0x9751e5bf, 0x97f15dbf, 0x9365b109, 0xe8107bd9, 0xdf8955f5,
-       0xb10d7147, 0xa4ba7f23, 0x935dd820, 0xe7e74a5f, 0xe53e5989, 0xf17ef94f,
-       0xf5820aa5, 0x5b8d3b29, 0xfdcf508d, 0x3f5e5aef, 0xd98c4dd9, 0xea07c44e,
-       0xf3c4a8e9, 0x93185d32, 0xb1ef7b22, 0x6d343f33, 0xecfda7ab, 0x1f20af9d,
-       0xe43558a7, 0xa5ebc09b, 0x04c3b446, 0x289bb45f, 0x963c537d, 0x819a338f,
-       0x9e75dbde, 0xd697d0f5, 0x2f40506c, 0xb1182657, 0xc83fed6f, 0x9b96d7a8,
-       0xcb4ec40c, 0x63371f07, 0x3e265cb9, 0x20a123c8, 0x51e786ce, 0x0ad4279d,
-       0x60eda5f3, 0x160eedbe, 0xeb96d757, 0x7ed3cf51, 0x3e0f5d71, 0x9c1109a1,
-       0xf98ca57f, 0xc1661ca6, 0x7c247477, 0x6be734ff, 0x518486ad, 0x7bb3a58e,
-       0xfed10e39, 0xbf83dfa1, 0xdfa0f6d2, 0x13b950ae, 0x271bcfea, 0xc0a8b9e0,
-       0x592f79d0, 0xda15c003, 0x67e87cb9, 0x3f04f2e7, 0xa542f90b, 0x852bbe5e,
-       0xf8149030, 0x053b050f, 0xfb8204ec, 0xccb71100, 0xd97a8a34, 0x0da6fd0b,
-       0xe0e767b5, 0x56997852, 0x60253585, 0x27f1bca7, 0xe4b1c3a0, 0x931a6145,
-       0xe429e213, 0xc3c316c5, 0x19af6a47, 0xef0a3d6d, 0x9b0cf2c7, 0x84c7ad9d,
-       0xad4be00c, 0xe8064279, 0x478776cd, 0x0b94c5f1, 0xae6a76e9, 0xdb45f013,
-       0x35adf2d1, 0x18e5f2c7, 0xc69854fd, 0xe76d00e4, 0x1ef0a24d, 0xc0192934,
-       0xdb8ca3bf, 0x7cb5c6cc, 0xe9bae3bd, 0x41ddb4b8, 0xb6971d1b, 0x843266db,
-       0x8da30935, 0x78c0a15f, 0xa2971a97, 0x833f911d, 0x93a503af, 0x0ec1f820,
-       0xaf4834da, 0xf2be7833, 0x1e3664c1, 0xffe75429, 0xf8e99be4, 0xcea65f98,
-       0xda51b9f7, 0xfa7a01d4, 0x56c25369, 0x3837cfa0, 0xfcb61cdd, 0x69d83e43,
-       0x382bcc6f, 0x71267284, 0xd1100779, 0xf28bd20c, 0x0bc1c846, 0xa1cac769,
-       0x8de1e54c, 0x0fde7469, 0x079d1ee4, 0x3c721f9d, 0xa5f68f9d, 0x56935bd9,
-       0x417e1236, 0xa06e029f, 0x218be053, 0x5f838d3a, 0xa5b91bd0, 0x37251317,
-       0x9e173b53, 0xa425eec2, 0x2bc5e595, 0xa3f3c399, 0xd8dd3e44, 0x18d1e6ca,
-       0x746fb844, 0xe6f318fc, 0xffe718ee, 0xf735c01e, 0xbef04fca, 0x3f9ee222,
-       0x1477f601, 0xc96979de, 0xc6f07bff, 0xca97f9db, 0xcf8b1f0f, 0xacd2f8c5,
-       0x1e1f989d, 0x7cc56d98, 0x3f3c69f1, 0xc1a0d036, 0x0fdd00b8, 0x85a23ee2,
-       0x97204318, 0x5cbb72a7, 0x45785b9c, 0xe0d6fe62, 0x7d45068b, 0xde7c513f,
-       0xe97982b8, 0xbf2c65c1, 0x6f7ec87c, 0x1f7ed056, 0x9cfc73d2, 0x93317744,
-       0x28f7dded, 0xe689fbea, 0x44fdf513, 0x7121ed0b, 0x32948a6f, 0xdddfbf9c,
-       0xbbfe9043, 0x9f58b96d, 0x88fa65ae, 0xa3e9837c, 0xbaa21cee, 0x399d691f,
-       0x94f31134, 0x46c15e78, 0x6ff83fc8, 0x9a7e0bf2, 0xc2fca926, 0xc9afe543,
-       0xf0e6dc2f, 0x5b3a02ef, 0x92cde458, 0xebd63d28, 0xd2987f99, 0x8108a6eb,
-       0x7cd6c574, 0x44dda7d8, 0xe4d2df5a, 0x02febd21, 0xa53275e9, 0xbd153cd7,
-       0x15fc61ee, 0xe82d2144, 0x0b4e8875, 0xfd00f3e3, 0x6edc60fb, 0x5befef47,
-       0x6fd35f60, 0x683cb0f0, 0x2f19d796, 0x59e0621f, 0x5c783320, 0xf3c22d5a,
-       0x0f13f43a, 0x4df0e5cf, 0x12a69d2c, 0xf1631fc6, 0x824caa4f, 0xfe6192b6,
-       0x6ffd9931, 0x7c43b8c1, 0xcfdb08f4, 0x6b5b808e, 0x739a7a45, 0x057f8b07,
-       0x802ecc2c, 0x1d1a5838, 0x7f1f267f, 0xdaafa74e, 0x4a66ed01, 0xfa610f0c,
-       0x167f850f, 0xdfd99faf, 0xb370798c, 0x63c775aa, 0x2f2120ed, 0x2e6ddc45,
-       0x7dab7f6f, 0xd2f20ea6, 0xe3aad767, 0x64ef735d, 0xb339b6f1, 0x25ccfdd5,
-       0x7cc13fab, 0x03aad24d, 0x53bdcdfc, 0xda49ff5d, 0x026c9c50, 0x710ec9c4,
-       0xe520d03f, 0xd7a3e013, 0xba6f1793, 0x84f9d287, 0x8095149f, 0x9486f0df,
-       0xd04f6dc6, 0x271bb3f2, 0x94f5f961, 0x28ff7eef, 0xc0296fd4, 0xe25c3572,
-       0xe056fb04, 0x8567ca43, 0xc8cc77e5, 0xc27d0049, 0xe087bdfb, 0xdfd9b77b,
-       0x73b6933d, 0x3cc5c94f, 0xd7ee6ad6, 0xeac85c18, 0xc6d2be6f, 0x52ef9552,
-       0x6d5c5fd0, 0x1d35f766, 0x04bb7e29, 0x73abaaf2, 0xd5e4b979, 0x243e5049,
-       0x3af7827d, 0xcab66b9c, 0xe92d0eb0, 0xb93ecfcc, 0xa44f0a50, 0xf276a978,
-       0xbcd99bfe, 0x4b9e4b6a, 0xaea93e07, 0xf64cfd62, 0x41e67654, 0x2c79cd3b,
-       0x26374b9f, 0xbf05fe00, 0x957df0e5, 0x5c7d2bb0, 0x3de4bc4e, 0xfb4491d6,
-       0x0f2519f5, 0x7157d14c, 0x664bdd8c, 0x7d03e765, 0xfc191cde, 0x2cbcd3f4,
-       0xb8cab6ef, 0xe1e40d3c, 0x297d7e2d, 0x2c6ecbcc, 0x1179043e, 0x65951589,
-       0x246da798, 0xfe94beb8, 0x3f03a7c7, 0x5649fd5e, 0x559d1002, 0xbe82ff4d,
-       0xafba0a66, 0xe537d356, 0x65e9c9db, 0x2adf9697, 0xd30d36fa, 0x3ef658f7,
-       0xe102ab85, 0xaf5a86fa, 0xc7138d0d, 0x8ee3f19f, 0x2fe03725, 0xc30efe56,
-       0x987c8bd7, 0x798dd901, 0x825da7c0, 0x38026f4f, 0x9e089af4, 0x3c96ca8f,
-       0x7180f093, 0x7a88c785, 0x055f8e2f, 0x33e0997c, 0x1709192f, 0x6ec2c9fc,
-       0xf02e7f65, 0x7af064a3, 0x38979dfa, 0xe3a2e187, 0x7a0e91df, 0xcf0611fc,
-       0xc995a966, 0x112fbe19, 0x311697fe, 0x7cf53edf, 0x1eeccdcb, 0xcbf83703,
-       0x3c527630, 0xcbee0869, 0x9f310758, 0xb3e7d700, 0x9e9b3e8d, 0x4736edce,
-       0xedcfd23d, 0x283aa354, 0xff74c25e, 0xd41e700f, 0x7ec1f704, 0x62f1216f,
-       0x47d29cfc, 0x6ec63d20, 0xe3c6f012, 0xb90c65a9, 0x789f3f1a, 0x5baf0cfc,
-       0xe29e0d24, 0x7cd0e1fc, 0xf19e732f, 0xaf4b8af6, 0xb93a5bf6, 0xec39d17f,
-       0xfa842c4f, 0xa0f6625a, 0xe123d13f, 0xda96af7e, 0x6ba7201f, 0x71fa086b,
-       0xfa0d569c, 0x321d8513, 0xff5c9f16, 0x6ab7264d, 0xf73f089b, 0x4f17e6c8,
-       0xe064a98f, 0x1ad6787e, 0x800b0d95, 0xaaac1bff, 0x56b50673, 0x4e788f16,
-       0x503211c8, 0xa87f7a06, 0x0fef423c, 0x8a1c8194, 0xf6ae7fbf, 0x3b7bf322,
-       0xacf84a2f, 0x032b1cf5, 0x19acefbd, 0x56790328, 0x14fef767, 0x13dc55d6,
-       0xbdcf8f19, 0x97911ae9, 0x1a745972, 0x0e2247cf, 0x7fe6c47a, 0x3fc63d39,
-       0xa08a5675, 0xcbb5759f, 0xcfe7e7ce, 0xd8767a01, 0xefc12a73, 0xaad8db34,
-       0xd138bb03, 0xce903fe1, 0x5f17e8e4, 0x9a17e6c0, 0x56de3c52, 0x66587fed,
-       0xee1e22c3, 0x81b878e5, 0x9bf3d9eb, 0xa90fb8b4, 0x0d3e16f6, 0x9bc0a0a1,
-       0xbe42123a, 0x147ea2f5, 0xa79dc6f7, 0xda185506, 0x7d436f3f, 0xf557f8bb,
-       0xb09b2718, 0x1894435e, 0x6431397d, 0x327fdd56, 0x5553a779, 0x5d37a2be,
-       0xbecafed5, 0x717d555c, 0xfeaa9278, 0x544b37aa, 0x54c8b2e5, 0xdfabfb55,
-       0xaf9552a9, 0x6aa19819, 0x3df403bf, 0x4e37e3c5, 0xffbd52cf, 0x37f4e368,
-       0x5d7d3e21, 0xefaa3bf4, 0x043f704f, 0x85237a09, 0x040bfe74, 0x53ac5ebd,
-       0x9acd4f7d, 0x7c0e54b0, 0xac16fecf, 0x95f77966, 0xfdb16314, 0xdb52ec2d,
-       0x28903713, 0x84b62be6, 0x40984f24, 0xbeba9dde, 0xf107afb1, 0x0f7ba97a,
-       0x6be6b826, 0xc69754c0, 0x22633b51, 0x0d5c8220, 0xf1638379, 0xbfd6a5fb,
-       0xa97fe480, 0xd5b837f5, 0xd4526feb, 0x54296feb, 0xa3cdbfaf, 0x0ac4ff5e,
-       0xbc3bfaf5, 0xaa4ff5ea, 0xb27faf51, 0xa9febd4f, 0x9febd573, 0xffaf57e6,
-       0xbaf506b8, 0xd7aab667, 0x7aa97b3b, 0x4b82735d, 0x74f1f554, 0xc849e820,
-       0xf795bccf, 0xa453dbaa, 0x42e86268, 0x5f02d9d0, 0x8d63e603, 0x35487aef,
-       0x4c7d3c5e, 0xf48f3c20, 0xe547d22b, 0x727f6e38, 0xa97aa0ba, 0xda325c6a,
-       0x73c03719, 0xff6e04ee, 0x33b746fb, 0xd58afc84, 0xe6fbb1eb, 0x08dae4b1,
-       0xd1f7c57d, 0xd82bea63, 0xf7869b47, 0xefd163d1, 0x59ea84bb, 0xfa357c1c,
-       0x33b0eecf, 0x999a0e38, 0x5429ff3d, 0xd1db435d, 0xde141536, 0x743e6177,
-       0x93cd77fc, 0x1df20fd1, 0x7183abd2, 0x7c1124ef, 0x7c5123ce, 0x755d89fa,
-       0xf10165be, 0x645fb9e9, 0xc9a9e009, 0x7a0e5038, 0xa3fcc2ff, 0xee7c63ef,
-       0xdd65d248, 0xe21c7207, 0x3909e33f, 0x49c9e5c5, 0xf2d10388, 0x27f71339,
-       0x8ae2897a, 0xee29e7c1, 0x269bacf7, 0x5a259ea1, 0xd5b1e633, 0x9ea12edd,
-       0xf60ffbaa, 0xf4c71f6c, 0x52e788da, 0x6e2ed781, 0xa13b301f, 0x62dd0e0f,
-       0xadf890fc, 0xec7a8f68, 0x3fb4deb0, 0x47f98716, 0xdbb17f76, 0x25dce0c8,
-       0x89c2b911, 0xdd7106c7, 0x7ce1fd61, 0xe0c8db9b, 0x4623a5db, 0xe264efc0,
-       0x31f0fb47, 0xd63c8a99, 0xefd624ef, 0x17f05cd1, 0x7e6fcd9a, 0xa9f21aab,
-       0xf472e0e5, 0xa88f7fdf, 0xb677f7fd, 0xffbfe84a, 0x3e9b851e, 0x1b8f76dd,
-       0xef28b2f4, 0x1e21b802, 0xfbe8ed00, 0x04ab7754, 0xadafb1fe, 0xb10f3dbf,
-       0xbfb25f76, 0x83087ea1, 0x3d60fe0b, 0x83367f85, 0xd281b7d2, 0x11efb6cb,
-       0xfbc61ff4, 0xa969c76b, 0x31fc8106, 0xc097bb1d, 0xfb67af2d, 0xbb1ec3e2,
-       0x7444cfca, 0x7a47380e, 0xf20e7b29, 0x9cc54fbe, 0x3474a0d3, 0x1fbafdea,
-       0xa47cb065, 0x44c8b6f6, 0xe39e4b88, 0xdb87d771, 0x56b2c4de, 0x265e60f6,
-       0x88e5f7dc, 0xa2ef5ef9, 0x4e7231f5, 0x63efd2b6, 0xeace8de4, 0x1e6bcbc3,
-       0xbc608b69, 0x25efc753, 0x5ee3347b, 0xbfc63fbb, 0x6e38cef2, 0xc4831927,
-       0x69b8429e, 0x4f4eff4f, 0x5a3f4023, 0x762a7cbb, 0xd3706d1f, 0xeef562fe,
-       0x1b1264c5, 0xf6d9587f, 0x88fdc20e, 0x6743f7e4, 0x36127c86, 0x641b7c51,
-       0xdf4d0338, 0xe511b86f, 0xaf76deaf, 0x1aa1ee07, 0xb7067f0b, 0x7e56217c,
-       0xdf8e387e, 0xe7e5c5cf, 0xc9d16d93, 0xdb7b4e30, 0x5d6f0a80, 0xfdf1176d,
-       0xc452369a, 0x7ac43fea, 0xf4828d4d, 0x42d28a73, 0xf27ae204, 0xc1fc0d80,
-       0x10263ed4, 0x8db9d67f, 0xb8306f18, 0xa2e4bc18, 0x9e63e90b, 0x3e00c19d,
-       0x1f4a4cbf, 0xe1d52fef, 0x4cbefafe, 0xefbfb62b, 0x780fe337, 0x29eadf29,
-       0xc37fb41a, 0x61c7867c, 0xf973d3f8, 0x0fbf6449, 0x5d3e80e4, 0xd38538c6,
-       0xf1d70b3e, 0xf027f6cb, 0xcc1137ae, 0x5a67d647, 0x5cb85ed1, 0x6a19dd38,
-       0x8fe3c7bc, 0xffe509e2, 0xf74f1c7d, 0x93fcc83d, 0xf04fddf7, 0x4a59053c,
-       0xe987caff, 0x87971c6a, 0xcf87c4a9, 0x082a36ae, 0x465eb00d, 0xed409fe2,
-       0x8d8bd211, 0x82a7e04d, 0x80ecaf7a, 0xaa2788d4, 0xb9e1335d, 0x1764e2a6,
-       0x6bdae3b0, 0x13c08b3f, 0x2f801162, 0xc109037b, 0xab98bc55, 0xf877c740,
-       0xd7813959, 0xe565cc27, 0xe89f5e44, 0xef4ce563, 0x0035520b, 0xcb471716,
-       0xca6f3ab4, 0x80bc7907, 0xfcf173b0, 0x84cd8d7e, 0x73ab0bcb, 0xdfd43566,
-       0x8b9cf049, 0xaf09ffa8, 0x5f1eb34f, 0x637a0799, 0x0dfbfab6, 0xd6a90f1c,
-       0x30d35de3, 0x17aea6de, 0xeb64acf1, 0xfbf137f9, 0x53fd7522, 0xf59b7bfc,
-       0xd41a647c, 0x7fc7abe7, 0xac5bd79c, 0xca8def2c, 0x037f767e, 0xd78c7faf,
-       0xc61ea09b, 0x5af5642f, 0x6f09df71, 0x18e1c9d7, 0x431e33e2, 0xbf33260c,
-       0x233696f2, 0xbf3c57f2, 0x73f707dd, 0x9bf30d95, 0xf519297d, 0x32fb86de,
-       0x5049dc98, 0x51debc06, 0x77a8a2e4, 0x37cc65da, 0x48f5bad0, 0x972b064f,
-       0x871f9c27, 0xead489e4, 0xe4c64461, 0x9ae8a5f4, 0x9005f012, 0x0ff4596b,
-       0xfbe33ae8, 0x918fe21a, 0x664de973, 0x83e58fe2, 0x39554e05, 0x5574cee5,
-       0x5cecd77b, 0x74b5bd55, 0xcc9eaa92, 0xdc9f2276, 0x5ccbe9cb, 0x17aaa254,
-       0x6d9065f7, 0xb59d9dbc, 0x554fe5d3, 0xa85f3bb5, 0x9f8d0224, 0xa3dc49ba,
-       0x7c8231e6, 0x9b96d7b8, 0xb3f8fc0a, 0x4e440ab6, 0xf627e53b, 0x1ba7f3b4,
-       0x54fa598c, 0xcb10b978, 0x7e583bcf, 0x879b7b7f, 0x9e087395, 0xab6f6faf,
-       0xca2ef2c1, 0x69fcf09f, 0xdb9f179b, 0xcfa15969, 0x2bfda47f, 0xda1e9fb4,
-       0xa19f943f, 0x3373c3fd, 0x3f9e1fed, 0xfd43fda1, 0x942fda06, 0xc170a69f,
-       0x0fda29f3, 0xed31ffbc, 0xb44fca1f, 0xb6bcb0f9, 0x1f962e6d, 0xf3e3f36f,
-       0x7c06b6b1, 0x8ad6d9df, 0x96db47e5, 0xb6e1f3e2, 0xdbdb3e20, 0x2f7d6256,
-       0xf9e793a7, 0x2be7dc79, 0xf103bdd9, 0x219fdfeb, 0x9d2fbb61, 0x154a539f,
-       0x3f2ab97a, 0xfc033fa7, 0xfceabd02, 0xc21fc054, 0x8c786261, 0x0668e387,
-       0x91270fb3, 0x930b72c8, 0x1f07181f, 0x6159e7df, 0xae35fca1, 0x4e7bad95,
-       0xd3eb145f, 0x4778d81a, 0x5c409db9, 0xce519241, 0xbb439b8e, 0xcaa45273,
-       0xd007f2c2, 0x14dc430f, 0x5aece53f, 0x21e64672, 0x5725c00d, 0x331e3d50,
-       0x397c21af, 0xb7809c18, 0x57fde0d1, 0x696d378e, 0xa75fbb2f, 0x6c0c2ba6,
-       0xe2b6f666, 0xb9c63afd, 0x9f4cb0be, 0xef1f9f2e, 0x717498e9, 0x5224dd3a,
-       0x9bf176f9, 0x8ccfa144, 0x31fef526, 0x6a89417d, 0xb8bda67f, 0xd1572886,
-       0xfbd48b7e, 0xbdfe733c, 0x198cefaa, 0xf5eaa90f, 0xfaaa15ae, 0x1e73bbba,
-       0xc73e0371, 0x6199b8b1, 0x210272f5, 0x4fdd85e4, 0x4ce65c20, 0x92738f36,
-       0x605f7ec2, 0x133dff37, 0xd6797fbe, 0x5c65f1ce, 0x09f2fb8d, 0x482c560e,
-       0x0f406a0c, 0x448bfc7d, 0x9e3b7f94, 0x7e9fa0d1, 0x40690922, 0xe6a64cde,
-       0x015fd424, 0xf16b8c37, 0x942d26aa, 0x85a2898b, 0x8a2455f2, 0x7fba3afb,
-       0xf5d264d1, 0x9ffad16b, 0xd9f2d131, 0x2cb3ff4c, 0xfa8c30bf, 0x67af80ba,
-       0xadc7d881, 0xdcfde397, 0x37f44cc6, 0x7625cfa9, 0x874bfdf0, 0x970df989,
-       0xc153ca3b, 0x46373e0e, 0x7dcda83e, 0x14058de2, 0x63b4b6df, 0x1fef14f8,
-       0x9ea33457, 0x94cbcfd7, 0xf75e5abe, 0xd44faa7a, 0xf307937c, 0xcffa5b38,
-       0x6b76e029, 0xff228fc9, 0x3c84e874, 0x9e411253, 0x893d970d, 0x3b1e6624,
-       0x93c9deda, 0x11fa2151, 0x375f326f, 0x4ff95f31, 0x4bc87695, 0xd179e02c,
-       0xf2d2db3b, 0x7f0fc7ab, 0x5074e3ef, 0xa0352248, 0x348b0b5f, 0xe074109e,
-       0x31fcabb5, 0x2f2efca6, 0x4b930b9c, 0xf2c40788, 0xf785d244, 0xd57fc829,
-       0x7c9a3e62, 0x50a21af0, 0x0d6ad8fb, 0x70d16093, 0x75fb84bf, 0xfce5cfbe,
-       0x9c6af667, 0xec259c8f, 0x74e80f26, 0x1bd599f2, 0xacfc3a01, 0xf4d8c75b,
-       0xd0bebab8, 0x2def504a, 0x1487d42a, 0xebcbee09, 0xe5407bc2, 0xc8c9122d,
-       0xb9a63801, 0xdf7e83e7, 0xb63a416b, 0x9fc72fac, 0xe359b830, 0x0efc40af,
-       0xc2357b28, 0x9aeda2e8, 0x82b7eb27, 0xf001393d, 0xdcbc0562, 0x430d5f91,
-       0x1e2217e7, 0x2f79f217, 0xc8e8f3e4, 0x833fc21c, 0x70bc7887, 0x6ea2ef1f,
-       0xcf528fe1, 0xaad2f1f3, 0xa2bdc36f, 0xff2d11ed, 0x3e352299, 0x5322e957,
-       0x70c34be6, 0x66173851, 0xb8015c82, 0xd80f82af, 0x919f9afc, 0x941cc6c8,
-       0x6f68356b, 0x3f306994, 0x9b2e9e3d, 0x8fdc9932, 0x7dd9d866, 0x4853eee4,
-       0x93e5c3cf, 0xc2482c6f, 0x5bb333fd, 0x8fcb326c, 0x58957af4, 0xe12af7bf,
-       0x72e7e45f, 0xa1de1ccc, 0xb127057b, 0x892b60bc, 0xb4bc87ac, 0x2bf5f6b1,
-       0xdc707332, 0xb53d7de1, 0xa53f205d, 0x5c7988cc, 0xa13e44ab, 0x69995472,
-       0x57384f63, 0xfa74e465, 0xf79d4da8, 0x6fcf9db3, 0x418f5f3b, 0xf27bc8a3,
-       0x9cc716d6, 0xafeba9f3, 0x88963f47, 0xff720ed3, 0x1d59a0e1, 0xa4e46d57,
-       0xaba87830, 0xc1f10cca, 0x6da7162e, 0xdd99bfec, 0xc7efbb6b, 0xed302f78,
-       0xa87a0153, 0x57ebede7, 0x0b58fdaa, 0x5f91fa77, 0xf164fde3, 0x398a317e,
-       0xe31fec3d, 0x335b62fd, 0x43c27ef9, 0x7b0e218a, 0x61de7562, 0x7277ec33,
-       0x1f0f9e08, 0xef017da7, 0x81bba6dd, 0x974fb82e, 0xa3fbb114, 0x54ffd7e2,
-       0xb2f11e96, 0x78efac53, 0x3ba5da2b, 0xd81c98cb, 0x2dfce079, 0x2b3f69e3,
-       0xf9d52473, 0x3a399580, 0x29b7a75c, 0x97b3c37d, 0xeed19a90, 0xa9943b29,
-       0xef726af9, 0xc1eff55a, 0x1c0df734, 0xff2828b6, 0x1fba035e, 0x4279fc3c,
-       0x1451f211, 0x08c4bf7f, 0xc19930c2, 0x76b3e70d, 0x17993e6b, 0x676f0f4b,
-       0x36ff58ca, 0x0d2f8ba7, 0xae1ab557, 0xa56f45b3, 0xfd7060cc, 0xb9c6e40e,
-       0x5894f1f0, 0xb5c0467b, 0x03df8c7b, 0xe2abf0f8, 0x1fad42a9, 0xfa74f062,
-       0x6ed3c3bf, 0xfcf0e8fd, 0xb3f3c395, 0x9b5eec43, 0x515ff591, 0xe1ab759f,
-       0x647cfb3d, 0x0a49880e, 0x7f115fef, 0x182993ee, 0xebf8e613, 0x59f4e52d,
-       0x078fe5ca, 0xc09150cf, 0x1e63577b, 0x924caf66, 0xbe5ca16a, 0x2cf77f00,
-       0x02c3ef93, 0xbf9e3f1a, 0x4619ef21, 0x64d77f95, 0x9ddeba31, 0x878a8d2e,
-       0xcf362cd2, 0xb2ea4703, 0xd8f1bfc1, 0x7202063b, 0xbfcf3361, 0x6bdecc7e,
-       0x05a67b84, 0x425ca11e, 0x747d019f, 0xc7bc2811, 0x2a333f4a, 0xd3c651d6,
-       0xc6d6f1b0, 0x4f188df1, 0x1564a73c, 0x3a557b32, 0x387385a4, 0x0b7daf6b,
-       0x5b5b7fef, 0xfdeca32a, 0x1d5ff8d2, 0x5bf0ff87, 0x7a30b729, 0xe1459299,
-       0x90fe916b, 0x0e5a6df0, 0x2a7fd148, 0xbd157c82, 0xa01fe71f, 0x4691ec78,
-       0x8b2d29e2, 0x9f988bd1, 0xdb80bf98, 0x5c02dd76, 0x06bbdb07, 0xbca51a54,
-       0x8917d0bd, 0xbcc1ff5c, 0x2b5c5f50, 0x654c73b3, 0xdafbae32, 0xee78a98a,
-       0x17cf376c, 0x1fa35e89, 0x164477f5, 0x763dbc70, 0xb811b7f1, 0xafd83947,
-       0x883ffbc3, 0x15bee03c, 0x8dff1fee, 0x5389f78c, 0xfb81aa7a, 0x391c0ecc,
-       0xebfb009f, 0x843a59f9, 0x87973e7b, 0x35b51783, 0xc8ec1e78, 0x0c6d7667,
-       0x6965d7fd, 0x89127db9, 0x35af39c0, 0x8b3cec25, 0xd603db95, 0x001b2723,
-       0x43c56b7e, 0xde862906, 0x10196566, 0x68fa35ae, 0x17f6878a, 0x6125a7d8,
-       0x7bc1ffe6, 0xb3ce8719, 0x5a1e19da, 0xbda10f4a, 0xf767ed60, 0x2965d635,
-       0xb852ce4c, 0xe6f7d2f7, 0xebd99f89, 0x8e94bea1, 0xbdfc3b97, 0xd3d6cecd,
-       0x4beec65c, 0x3fed7b5a, 0xc83ee1db, 0x471df844, 0x79f2efd8, 0x7292b80a,
-       0x48dfbc35, 0xcbf81724, 0x5abe632e, 0x235ef86f, 0x2f82fbd8, 0x62d5cade,
-       0x39f947bb, 0x0a2b4789, 0x4cae7043, 0xdb35b1d0, 0xcc1640ff, 0x0bc5f28f,
-       0x7c44ef68, 0xf63f10d3, 0xdf33c862, 0x32e64525, 0x076f443b, 0x68d42c3e,
-       0xe116fc54, 0x549e26eb, 0x73dda3fd, 0xa15da73f, 0x46423bf7, 0xfe4de702,
-       0x22667178, 0x191da7d8, 0x1af3dec2, 0x259b5f01, 0x8c0e625f, 0xdc5a2ff3,
-       0x72381e0f, 0xedc601bc, 0xbe02f3a0, 0xeb75f87d, 0x3a53b06a, 0x53e45eec,
-       0xd0ecbe31, 0xfd60f5f0, 0xdf7bd6ec, 0xd4647f04, 0x3acdeec1, 0x11867538,
-       0xd3b69fe8, 0xa07f3f40, 0x04f0f7fb, 0xfd1aa7e8, 0xb3ed0b06, 0x8b77c3a6,
-       0xb011ff88, 0x6b75176f, 0x3c83f755, 0xc2c5e5cc, 0x8e12168b, 0xac2c2fd9,
-       0x6b9e0ef8, 0x0131785c, 0xcfcc3fdf, 0xcfcc3fed, 0xf8e2edbd, 0x5f3f9978,
-       0xfb8afacf, 0xde9c4f6f, 0x8eddfe4a, 0xbbf7c63a, 0xa59afd60, 0xfaa83d01,
-       0xc73f5335, 0x687f64f3, 0x21b093b3, 0xf311de06, 0x98e1224c, 0x5dda8771,
-       0x52709134, 0xfa32faec, 0x15af9e1d, 0xe6d0ffeb, 0xdd8e3c46, 0x1e1538ff,
-       0x53cffb87, 0xff6471e1, 0x87ff5805, 0xf44bc2b6, 0xfe8c793f, 0x0ff05473,
-       0xef8f9bf7, 0x7bac1dcf, 0xeef942d6, 0xc6c57860, 0xf7e14b57, 0x7bf80cf7,
-       0xb7afa41b, 0xeeb9cf0a, 0xfa0e7822, 0x7a7ffd81, 0x1f52f21f, 0xc0f7aad8,
-       0xe8ba8318, 0x7a28cf3c, 0x83d89f26, 0x789cef70, 0x87959dbe, 0xdeff1ceb,
-       0x90ec8728, 0x942c6a67, 0x8ce7a0ed, 0x015a1224, 0x235297fb, 0xdf1139ca,
-       0x34fefd12, 0xb392ab53, 0x46a17ee2, 0x68d87f9e, 0x26aff161, 0xac2cffab,
-       0x574d12ff, 0x1f68cfcb, 0xf03b0ba7, 0x0e213b7c, 0xf888d7dc, 0xc5fb0c8e,
-       0xf97d703c, 0x9b0b9c08, 0x0cffe397, 0x1509fbbe, 0xd1ef102b, 0x0fcdb15e,
-       0xf38f79f9, 0xa6e3e47d, 0x2313db88, 0xf2d9753f, 0xba1bb357, 0xecb7e8e2,
-       0x8cc23b77, 0x40d9757e, 0xcfc8dabf, 0x7ce072eb, 0x67bf00e3, 0xb9fb414e,
-       0xde30f4ae, 0xfc275947, 0xf3e32b02, 0x601d3256, 0x54788b4f, 0x8217e402,
-       0xdd86b0dd, 0x616f5853, 0x275ffae5, 0xba17b9e1, 0x8114b21f, 0x65add99c,
-       0x071e22fe, 0x1e61cf3b, 0x02c9ae34, 0x7cf20efc, 0xaffdf397, 0xe7a7bde1,
-       0x3a478e57, 0x0fe5ffa8, 0xddc31ef1, 0x0d9f4ce9, 0x3ea1b3ee, 0xca7837ab,
-       0xddcd5ee1, 0xed6ecce9, 0x2509c395, 0xa3ec7631, 0xa7285519, 0x5e395e3f,
-       0x19271b13, 0xc2e4cd9f, 0x94ffe11a, 0xce70e5a3, 0xf0d2e3ea, 0xdd3ea13f,
-       0x1bdfc263, 0x53fdecd3, 0xbabfde39, 0x63bf80c6, 0xe277b551, 0x5fb0b9ba,
-       0x1f31904c, 0x84d7b35b, 0xc55d9cf0, 0x6f8383ee, 0xef35ee41, 0xcbbf871d,
-       0x62896f56, 0xd9b364de, 0xc1f10053, 0xc0dfbdfa, 0xf1389fdf, 0x902cc4f8,
-       0x9593c783, 0xfb6fbc2c, 0x3a748a71, 0x26fbe3ef, 0x579df7b0, 0xdb6ab9e3,
-       0x347f8b1a, 0x4bd088ff, 0xedcdf7f1, 0xd73e2f4e, 0x6899f807, 0x5e1c80f4,
-       0x675fe438, 0xbfd607f7, 0x24a59d19, 0xf306ffa0, 0xa7edea17, 0xeb1df7f0,
-       0x49dd8fbb, 0x42e93e30, 0xbcfb15fa, 0xb9eb71f8, 0x8faddafe, 0xd5df83ce,
-       0xf8e76fab, 0x59f7bfe7, 0xdfc629af, 0x5ff8149b, 0xf31f7713, 0xc5de38f7,
-       0x1911c4f3, 0x76a4b9ef, 0x8ff81645, 0x2037ec4e, 0x33589dbd, 0x1057ef19,
-       0x5853d5e3, 0x8f4f94ed, 0xb029953b, 0x15b20bbe, 0xb676ff36, 0xe9ef157f,
-       0xbdf811f8, 0x2d3ee8ce, 0xda0dafe6, 0xc71009a3, 0x7944ed14, 0x5afd3e68,
-       0xddb7bdfc, 0xdd7007e9, 0xa0115d29, 0x6d2fcd2b, 0xbf03b7a8, 0xf71bbf64,
-       0x82092971, 0x8ef8349f, 0x077bf701, 0x9ed019f7, 0x9d977c1e, 0xef711fcf,
-       0x059a359f, 0x7e06dcf7, 0xdae50e39, 0x0b746660, 0x784dbfb3, 0x51e0e4cf,
-       0x5e3cd5ff, 0xd1efc69c, 0xefbb034c, 0x18533ec2, 0xc4fa3eec, 0x6c9043b8,
-       0xfdfbe373, 0x882fbc16, 0x24f9d93e, 0x7f1b8f69, 0xf1748937, 0xfdf823ef,
-       0x09fe5903, 0xc81fa720, 0xe15bfda3, 0xeed893fb, 0x4affae42, 0x9211598c,
-       0xc74bc7ce, 0xd9fd337e, 0xccfa5ef8, 0xa80f7ecd, 0xb047d78b, 0x5ff0603e,
-       0xbdf8f38d, 0x328cf48d, 0x5f7aafcf, 0x49d97de4, 0x6e028eb8, 0x23b4678a,
-       0x93d2f1e3, 0x029ff6cd, 0x3974f11f, 0x80979eb4, 0x7832fc0f, 0xb63ec0bf,
-       0xea26ab8e, 0x9ce93c99, 0xde32f68c, 0x27931430, 0x07df7cb8, 0x3a839748,
-       0x97a0d3ef, 0x847547a2, 0x2d48c3dd, 0x5457f003, 0x16f576b0, 0x7010f7e6,
-       0x07e7e19c, 0x1e593b1a, 0x3ee799e1, 0x856f9ac8, 0xa81ff3f3, 0xff0bcfce,
-       0x0124ed21, 0x8f5633fc, 0xc4575092, 0xc22d76ec, 0x6e8f7ec5, 0xdfc14e8d,
-       0x3e3e0c0b, 0x2712fd11, 0xbc5ecaf4, 0x15d57607, 0x6d27a01a, 0x4fbf9731,
-       0xfb8979b0, 0x6d3dc4dd, 0xc81978f1, 0x99b2fa66, 0x3b82eff8, 0x25138ffe,
-       0xf14b0785, 0xff744abe, 0x52cd206b, 0x7e589af6, 0x9185ea3b, 0x2fea42f7,
-       0xff827bf1, 0xb053e5bb, 0x9f806556, 0xd5e80260, 0x7fb676d3, 0x40225bc4,
-       0x3cd96bbf, 0xb803e03b, 0x4ef882ff, 0x5bc45e83, 0x4e1e2825, 0x9e3eac4b,
-       0x1bbc84ce, 0x1ba00f81, 0xa3be17e8, 0x9d9e7f7d, 0x763ff6c3, 0x17943f27,
-       0xaa5e43d4, 0x490157d0, 0x0f7dc0d6, 0x024a1d27, 0xcec9e5d0, 0xc872e73c,
-       0x292871f7, 0xe076f6b1, 0x0e7bc110, 0x73ff3814, 0x922efc35, 0x05f80a77,
-       0xfed53b77, 0x5e787888, 0xfd401ca8, 0xc6985ff3, 0x800053c5, 0x00008000,
-       0x00088b1f, 0x00000000, 0x7db5ff00, 0xd554780b, 0x733effb5, 0x79332666,
-       0x84841e4e, 0xe4249840, 0x09308401, 0x0741410f, 0x68151048, 0x85280978,
-       0x42100793, 0x17b6881e, 0x240cdb5b, 0x41b45a20, 0x768bd151, 0xb4544140,
-       0x03414141, 0x58a50077, 0x56d56351, 0x880dcb6d, 0xa8311fbc, 0xadadff97,
-       0xfb5bf5ff, 0x90ce649c, 0xf9b7b5a8, 0x67d9d83e, 0x7b5ad7bf, 0x3bdaf5ed,
-       0x3f437cdf, 0x756109d7, 0x10f4422b, 0x116dce22, 0xa3109862, 0x42f382dc,
-       0x11c885d8, 0xca8df3fc, 0x5c3adb89, 0x8df88588, 0xdaf9aaaa, 0x2bc89eb5,
-       0x1f5c2deb, 0x774675e3, 0xb5f1bdf1, 0x28f250ff, 0x084c21b3, 0x5d3dfe87,
-       0x1e310f88, 0x90ea7b8d, 0x460ca7dd, 0x09ac2e1a, 0x75ac5442, 0xa51a45fa,
-       0xbacc4e6f, 0x4285e653, 0x5c6cc775, 0xe34ad899, 0xca2a6f96, 0x1fb29112,
-       0xd0aaf341, 0xea9e55e7, 0x0a8752cd, 0xeaa8f6d1, 0xebf684da, 0x6a8f9e55,
-       0xa51eb8f3, 0xdbd627ef, 0x9fa9cb5c, 0x273e7d0a, 0xc5d16b7a, 0x0ab794b9,
-       0xf280bdab, 0x45da2d56, 0x54782efd, 0xb177f62d, 0x81f7aa3e, 0xf80ba0b5,
-       0x3a894d60, 0x1ea8327c, 0xe39469d6, 0x7268f7bf, 0xc2fcd157, 0x63cc77e9,
-       0xd1f7e2a3, 0xd1f44efc, 0xfc7f21e6, 0x82b13093, 0x45daeaf2, 0x2bdceed1,
-       0xa1c27de1, 0x01727b45, 0x031eb95f, 0x18e3a19e, 0x7808bcf0, 0xbabd20c6,
-       0xabf04bc5, 0xa0f5487d, 0x4be6bece, 0x98df80d1, 0xae47453d, 0x61b5f7c1,
-       0xecda8c22, 0xcefe9c3b, 0x8b8f34ad, 0x3d4155ab, 0x193dd28a, 0xdbc68289,
-       0x2e7cf96e, 0x4dbf73e0, 0xd2917acc, 0x47a7b7d2, 0x46fd285b, 0x21f51fa7,
-       0x6a352709, 0xae7cf47a, 0x98b93edf, 0x9edcc7f2, 0x7aa082c4, 0x2ce9d63f,
-       0x6b655f14, 0x718d16ff, 0x78d8d62a, 0x2e5e065d, 0xbf341d62, 0xfe118d8b,
-       0x8b9704e5, 0x5fb8dbbd, 0xbf464f03, 0x4183c015, 0xa56f544f, 0xe38fa5db,
-       0x114717b3, 0xe1b4d35c, 0x64e82e9e, 0x2e3483c1, 0xe51f5bfa, 0xff7de675,
-       0x74780d71, 0x25969be0, 0x8f03fc0c, 0xbc6da44f, 0xde59be97, 0x93d10ab3,
-       0x7d78d0e0, 0xcbdf42aa, 0x850984f6, 0xda532bfa, 0x9c09288e, 0xac14fb77,
-       0x8c3cf17f, 0x9871f657, 0xf7c7e505, 0xf3c79f5e, 0xc12bc10a, 0x7a2bb529,
-       0x96d698bf, 0xdf8209ea, 0x736d3ec5, 0x7d06be79, 0xe79bce74, 0x4c37bb51,
-       0x4c5c5f60, 0x76467c23, 0xf801b1c2, 0x5df5c619, 0x6f6fa676, 0xb1d7e01e,
-       0x7ac8575e, 0xfdeb215d, 0x0b7d3040, 0x29ebc68f, 0x82cc24ff, 0xdc0fe5ef,
-       0x71a6e594, 0x8e3bdf8e, 0xce3c75d7, 0x75fd879b, 0xcffa953c, 0xe59d72bd,
-       0x733ad00f, 0x8d9d65bf, 0xb757c64e, 0x7b6b8ceb, 0x3acb7c42, 0x6874ea37,
-       0xab33f3ac, 0xfa8ada3b, 0x9cb155bb, 0x14fb6a8a, 0xcc8d7fdf, 0xd0d056bb,
-       0x0f4936b5, 0xfc236bb5, 0x6685d7c0, 0x6e7f04db, 0xf1a01f27, 0x583d27be,
-       0x8f8e1e98, 0x023c3f75, 0xea9f75f4, 0x9701b9f2, 0x9cfcef21, 0x57efc7f2,
-       0xb1f9025d, 0x0fc47e12, 0xc70fe02c, 0x73278b53, 0xb5cdaf7e, 0xb4f9fa82,
-       0x047f6ff1, 0x63dc5cfd, 0x5f5e0b73, 0x90b3fdf1, 0xaf82f9a7, 0xc66e5c11,
-       0xebce54b8, 0xd619ef57, 0xe8f17288, 0xbba65760, 0x0214be0b, 0xaa358ae7,
-       0x01d21f69, 0x3ed5e3c1, 0x3ac6e290, 0x8713380c, 0xa83a9acd, 0x4fc81e13,
-       0x9709d41f, 0x9ad0bb5a, 0xfb12fbf8, 0xfc414194, 0x9749f00c, 0x3cff44e7,
-       0xa2d2c7c9, 0xc873f683, 0x8ff942fc, 0xff48cf51, 0xcc57c1d2, 0x705178fc,
-       0x1950e09e, 0xc21c5f92, 0xca42aa37, 0xb7ca43ab, 0xf99cfaf7, 0x13f8e840,
-       0x31bee4d3, 0xc3aa58e0, 0x9145bb71, 0xc53ee47c, 0x2d7e89bf, 0x4bedbab5,
-       0x8e2ffe69, 0x4fd0f311, 0xae385599, 0xced97de5, 0x8ab52beb, 0x7c02b086,
-       0x633d70f7, 0x435fd4dd, 0xc3e51c58, 0x7aa21f25, 0x7941ec13, 0xf31adf83,
-       0xf0934f09, 0x5bc5d230, 0x83c78d9d, 0x14dd59e0, 0xeed7ca6b, 0xee3c6e4a,
-       0xc62fcce8, 0x6ff4c92f, 0x387ead22, 0xaa7f22e0, 0x8c1eb577, 0xb249fa20,
-       0xd469e168, 0xff83c5ef, 0x66eb9d1b, 0x262f0fbc, 0xe9a816fc, 0xf5a61d2f,
-       0x3d56edb6, 0x9befd09b, 0x5f11fcf2, 0x1b787a5f, 0x9bd9af7d, 0x7775ee21,
-       0x8e143fae, 0x8a5d7717, 0x17efa74e, 0x05c3d90e, 0xcda501c9, 0xd1ed63f1,
-       0x84babfbc, 0xbb875bbb, 0x6b05dfd1, 0xa094f46b, 0x6b44177a, 0x7a20d4f4,
-       0xa975dd29, 0xfc31e44e, 0x1f106a7c, 0x8f4f74ff, 0x2f7d2ab1, 0xb1af7dfb,
-       0xe9c74a16, 0x736fdefd, 0xe686b93f, 0xe61ddbed, 0xbef34cd9, 0x0b2ce6f0,
-       0xb3785fda, 0xea7f4f42, 0x4fb3f4e5, 0xb47e3153, 0x31bbd245, 0x293488de,
-       0x8e59954f, 0xfc1a313e, 0x699ed5ff, 0xe59d69f5, 0x2c829665, 0xad9b79e0,
-       0x7de62e6d, 0x95ab1141, 0xc67eceb8, 0xfdb9b9a5, 0x9f27dd85, 0xf4f87f00,
-       0x60053efe, 0x6776172b, 0x7e5469e7, 0x5921e3e1, 0xc2f7ea2e, 0xf01ec97d,
-       0xf7366d85, 0xeede994f, 0xdf60f289, 0x9c61fd1b, 0xf77fe825, 0xa435c355,
-       0x52f9cb1f, 0xe3934f3e, 0xce8294fa, 0xee2da37e, 0xbf028f5f, 0xb3cdbdf8,
-       0x7fa59299, 0x8b19e8cf, 0x773f61f5, 0xd5b28781, 0xe26dc261, 0xde782b27,
-       0x8763c2a5, 0x1172841c, 0xa2e55f44, 0x6fcfbf98, 0x405f7f34, 0x17df027c,
-       0xaf7f37ae, 0x5aab8d10, 0xfc8b7d69, 0xf682efe6, 0xfb112f8f, 0xe269f8da,
-       0xd6f17ef3, 0xf54cc26f, 0x0fe74f84, 0xa5c7e60e, 0xc7c11fb4, 0xfefc579e,
-       0x3defc015, 0x7433af2a, 0xd2d3cb5d, 0x448f1d78, 0x6b6e63fc, 0x598f5e10,
-       0xe0893584, 0x1c2ecc7a, 0x47e80549, 0xbeab9c08, 0xcdfe613d, 0xfedee4d4,
-       0x3296a55f, 0xe0b24bdf, 0x05c3b83c, 0xedfd47ce, 0x7e8a9939, 0x791756ca,
-       0x77e6835b, 0xe47de6d1, 0xdf5790e7, 0xf54d7e23, 0x37f58d8e, 0x1d79a58e,
-       0xd4f557bb, 0x33af3177, 0xe3f99f24, 0x28f71e09, 0xf2843fc2, 0x2d4c9ccf,
-       0xde9cbc21, 0x34b5327c, 0x3115fe98, 0x8d1e982b, 0xebc26694, 0xf489ac82,
-       0xeb05ad18, 0x89d7ad09, 0x0d7cf35f, 0xb1553a78, 0x787a2ba4, 0xe54f7414,
-       0x05577f39, 0x3d9acee4, 0x33e83f36, 0x0f17e362, 0x6cfa0adf, 0xda40b9b6,
-       0x2f547bb5, 0x5bb174e4, 0x1ce267f5, 0xba34fe6b, 0xeecce712, 0x68352e21,
-       0x170e74dd, 0xb0b97ce3, 0x596252eb, 0x1933f72e, 0x9eed44f2, 0xdfa03c87,
-       0x5cf1e6ee, 0xf1affa9a, 0xff99af3f, 0x20fdcf9d, 0x81f046f1, 0xc0b2278d,
-       0x3e0f89df, 0x99fd8697, 0x791db5f5, 0x83875a21, 0x2c7e68fe, 0x7ff45fbf,
-       0xa3a5f2c5, 0xbbfaf559, 0x349ec3c0, 0x07ffc33b, 0xcd026fcf, 0x7e73b12f,
-       0xe03d9f34, 0x6b3cc6cb, 0x9c766ddc, 0xd11d17b3, 0xb4a7e079, 0x89f989a0,
-       0x06e4f9fa, 0x289b2d7f, 0xee16bf88, 0x09c2bf9e, 0xf151a179, 0x6f280f40,
-       0x2adcf956, 0xddfaa0df, 0xecc29784, 0x213bf6bb, 0xe5443e9f, 0x3abc74d4,
-       0xa8b38fea, 0x54fbc2fe, 0xf8dbefce, 0x80da3fd3, 0x11360dd7, 0x47863c06,
-       0x63c7d26f, 0x3e916879, 0x37cd45bf, 0xb7a0569d, 0x013d51ec, 0xe51cdfb4,
-       0xd5b2f7c1, 0xf4c163b6, 0x50bf1f35, 0x2bd7f37f, 0xf81a40fe, 0xc2fcb984,
-       0x27ce9f30, 0x5c6fbe42, 0x027f7535, 0x89eb2b52, 0x72e6fc8b, 0xf34ebcfc,
-       0xdf7fd5a9, 0x17a6b99a, 0x29c173f0, 0xabf60b44, 0x1df595b5, 0x054d6811,
-       0xfeec2f1e, 0xac78152c, 0xb27ff57d, 0xebf81744, 0x51cd4fd8, 0x84222709,
-       0xc6e74b38, 0xfdd01637, 0x5dc5c9a5, 0x8fb17fd4, 0x6d5b17dc, 0x63905ebe,
-       0x8afc6ff7, 0xddc5c1f9, 0x17575f5a, 0x5fb9dbf4, 0x124b4e7d, 0x205380d2,
-       0xbae4da1d, 0xe484fb11, 0x1f417bc1, 0xdd4d569b, 0x6be77944, 0xa2424836,
-       0xf7923336, 0xfcc7f60b, 0x7d8d7ea0, 0x017c15b2, 0x1fc930e9, 0xe523ec5e,
-       0xbcbad584, 0xfb5f75b0, 0xe62ecce4, 0x26cd3ab3, 0x923edbcf, 0x2b4dcc6f,
-       0x9c874f0e, 0x0345f161, 0x75ebc21f, 0x157c1027, 0x97eabe9d, 0x3df0512d,
-       0xda723449, 0xfa71345b, 0x245a10b8, 0x0b8f0bea, 0x4fa21670, 0x7bc7e02c,
-       0x31abd79e, 0x8e89fcdf, 0xd06af03b, 0xf8562f83, 0xeaefd337, 0x63508746,
-       0x46b5ed20, 0xa0d451a3, 0x4beebfa9, 0x540fb6e5, 0x3ed49fd6, 0x2e3d3e06,
-       0xc8cbf7e0, 0xf8c131e9, 0x74b877db, 0xdeabfa02, 0xf52e7a49, 0x4d877e77,
-       0x5957a004, 0x3d50bf69, 0xec2fe1db, 0xcd4be069, 0x5cbc808a, 0xaf7c794b,
-       0xfaf5651d, 0x9792e083, 0x9a91e12e, 0xbb70c59e, 0x9a1ef560, 0x9573fa08,
-       0xdbd721da, 0xc04f970e, 0x2a4b6379, 0xfb5e63b5, 0xa4758f0e, 0x56b16f01,
-       0x9aab37de, 0x5c5b718d, 0xf62a3fe8, 0x436f9e03, 0x534445ae, 0xc28f86bb,
-       0x874c0cfc, 0x3a6143e4, 0x85021b5c, 0xf817770e, 0x14c289f1, 0x77ca8231,
-       0xcf3013a8, 0x1752aef3, 0x958b68f0, 0x9b308776, 0x9af40277, 0x78b8d8b0,
-       0x7a446fcc, 0xabffcf06, 0xcf3c25d8, 0x80bc48af, 0x7af241be, 0xbd0df231,
-       0x7d8655cb, 0x8fbc23e3, 0xfc721d6b, 0x9f2a3da8, 0x43a462a3, 0xbbefdbe7,
-       0xc89c68ca, 0xd024dabe, 0xa89f3183, 0xf00baf61, 0x858b1ce7, 0x3786b3e5,
-       0x2f80d722, 0xd21be518, 0xf819bd25, 0x75609958, 0xae3c7f81, 0x574ae7d3,
-       0x6820a3b1, 0x161eb69d, 0x0ec55e1d, 0xbdbb69c0, 0x97ce10f8, 0x738efa36,
-       0x54d27f73, 0xaa14f407, 0x273f4167, 0x64c768ea, 0x0ee9dfa3, 0x424177c0,
-       0x5bb478e9, 0xc2ac9628, 0x5eb85b7e, 0x3e208115, 0xe39360db, 0x211cb82e,
-       0xc73a4302, 0xe3f8405d, 0xf9a397f6, 0xd653837b, 0xfb92886b, 0x2974cee7,
-       0xd3d4ae2f, 0x83fa7ab5, 0xccc7baf9, 0xfec7cfd7, 0xe4a94b71, 0x53a677ef,
-       0xeb4ad5bf, 0xab268878, 0x80edda92, 0x973a89ef, 0xcd058408, 0xc6758af7,
-       0x38d0408b, 0x3b2ef51d, 0x183e2045, 0x47c66e1f, 0xb9237ae7, 0x125d44fc,
-       0xfefbb1c3, 0xec704c53, 0x04c33fec, 0xcffb2bc7, 0x7513f2e2, 0xffd1df39,
-       0x4ffa6ec0, 0xb3bfcd33, 0x5dfc7edf, 0x82fad2ec, 0x22eddcbf, 0xd374c07e,
-       0xbb2676ca, 0x7606fda2, 0x9871f12f, 0x95f7dc80, 0x0576cb53, 0xe96d87f1,
-       0x0b9f5d76, 0xfadf80a4, 0x6b4e3ac4, 0x8f1a5d77, 0x0be26ef6, 0xcbd0e76c,
-       0xcf1b456b, 0xfa02fc13, 0xbab648bd, 0x96977cb9, 0x98c8bd0d, 0xf33c8747,
-       0x859f48bb, 0x9ed841f6, 0x1f6347bf, 0x4db6b45f, 0xa9aa7d86, 0xde088d59,
-       0xfdf407d7, 0x17cfb631, 0xd5d7b079, 0xbdf11da0, 0x9c5dee9f, 0x84d4f80d,
-       0xde61e5b5, 0x2dfef7fb, 0x57c8e70f, 0xc5f7167b, 0x9f54adf7, 0x5b7b0fe5,
-       0xbfa8278d, 0xb3e5c27e, 0x9b4ce88c, 0xfa1ffdf5, 0xfa9eeb7d, 0x36c7985e,
-       0x2e483dd8, 0x56f659ac, 0xb078f1c6, 0xe083ef21, 0x16f8825f, 0xa6bb43eb,
-       0xdf2063a9, 0x0f32487d, 0x96ee87e5, 0x3ed0c372, 0x83496fc2, 0x2ce1f7dc,
-       0x619a89f0, 0xe1541776, 0x9616fcf0, 0x3987c3b7, 0x9f9f385c, 0xebc193ed,
-       0xc84e43b3, 0x78a2fb40, 0xf154e7a6, 0x1b6dc9af, 0xe04ff642, 0x68db350f,
-       0x75b56abc, 0xf78538f2, 0xa9f031d1, 0x78bfb79a, 0x135fd747, 0x8c5a9f81,
-       0x5f78f04b, 0x432127ef, 0x9a7a893b, 0xabbef5a3, 0x9b8cdea8, 0x1fa15393,
-       0x99fae895, 0x19404898, 0x1068fcc9, 0x9e5720ec, 0x7a0f52db, 0xc034d14d,
-       0xf0ec97c1, 0x981afce0, 0x71c91c22, 0xf4fed0d8, 0x57ee34a9, 0x2ec316e9,
-       0x03de60aa, 0xdf3d35f4, 0x2c6969ab, 0x38fe939f, 0x3b3fd1d0, 0xfbc325ae,
-       0xa30bf077, 0xdf3787fe, 0xe2eb483a, 0x79e430dc, 0x36e9bdbb, 0x3aadb3cc,
-       0x9847f592, 0xc9eed0f3, 0x2a02c39b, 0xc8b68aec, 0x3fe7d0d5, 0xb07b988a,
-       0xfee3c107, 0x83222d28, 0x799acdda, 0x95e42ac3, 0xa5eef1fd, 0xd692e7a0,
-       0xd3e7c0e1, 0x83262d4e, 0x6872afc6, 0x8969137d, 0xd968fbe7, 0x8be43831,
-       0x449e25e3, 0x2ee2a0f1, 0x53e72fe7, 0x0ff1c8a2, 0xe8496947, 0xf2d2c4a7,
-       0x66f855c4, 0x837b616d, 0xfdc1e868, 0x8a8bb79c, 0x037fe4ae, 0x75f4470e,
-       0x6b89b3ec, 0xf6fad32f, 0xd4f18dad, 0xefcb7cd3, 0x96b7399e, 0xe296f9d2,
-       0x9a6a80c4, 0x55d61677, 0x9be92be5, 0x79f3f24c, 0x65ef3e9b, 0xaeadbcfa,
-       0x1cfde0ac, 0x437aef3a, 0xc285f95e, 0x50ff20fa, 0xac5f15fe, 0x87ca5eff,
-       0x307d2e59, 0x20d6e70d, 0x3649db0b, 0x22ded384, 0x7d5df23d, 0xbed38f9e,
-       0xf7f1c473, 0x149ef8d5, 0x3d27db2e, 0x7ec3f16c, 0x37763c50, 0x9ac9e9e3,
-       0x634a8f48, 0x1db70895, 0xf0995072, 0xd9fc5cb2, 0x69edbf98, 0x661575a5,
-       0x6e01d768, 0xa92de2f3, 0xb43cf01f, 0x6f205381, 0xf8eb928d, 0xd7937916,
-       0x6cb85531, 0x3589942c, 0x531fc816, 0xf329725d, 0xa63fb915, 0xe30daf09,
-       0xd71a10cd, 0xbb05c3fb, 0x1fc4fa17, 0xbcd10ba0, 0x7f1f0a67, 0x9cfc2d9f,
-       0x5c022ade, 0x95a2c7ff, 0x89bc06f3, 0x4825e63e, 0x53d938fa, 0x8cdff865,
-       0x9117bf79, 0xad1967d7, 0xd923ca63, 0xad5fac99, 0xf9f0c1eb, 0xd14f79ae,
-       0xeff686e9, 0xfd83f43c, 0x99fa9d3b, 0xfec8637a, 0xe061ec2d, 0xf6dbf333,
-       0x877b4b51, 0x4c9914fe, 0x475eb870, 0xc5def5e9, 0xa9153fac, 0xf847c291,
-       0xfaa51969, 0xf21c7721, 0xa0484f2e, 0xb9fddc75, 0xb77e83d4, 0x843dbc5c,
-       0x46377fca, 0xd2dcf515, 0x64d4f2cb, 0xbdc99fbd, 0x9d869fc7, 0x2408b0f5,
-       0x17b9a50c, 0x8f5ed65d, 0x564ef9a1, 0x52c435b7, 0xa4de84f9, 0xbdf104c7,
-       0x5bb6121b, 0xd8ddd7a1, 0x627dfccf, 0x99df59ae, 0xc0551a24, 0x7350f279,
-       0x0f807dbd, 0x0c8ad7d1, 0x0188b7a9, 0xdfee8062, 0x47fbb963, 0x13ed1f7a,
-       0x0be1d92f, 0xbb433579, 0x3a5c7007, 0x18b9b3e9, 0x7ae55857, 0xd951de6a,
-       0xe48c779e, 0xdf9d2f2c, 0x84e8ebc7, 0x08f29308, 0x6e48a7f2, 0xcea67a40,
-       0x3a39e9cd, 0xa17e51e7, 0x67eb23ce, 0x7d803f14, 0x73faba56, 0xb772f02b,
-       0x6ef9c253, 0x761faa67, 0xc6a68ab5, 0xe55e98f1, 0x4883a6ae, 0xe3c503cb,
-       0x382ecc71, 0xd220e4b4, 0xb6f43bbb, 0x5fdd0e25, 0x5dbff3c0, 0xa3dbd3a7,
-       0x8834dea6, 0xbbedc9f6, 0xf6ebdfa5, 0x4da7533e, 0xc6de404a, 0xa8e8eef9,
-       0x3422b2fa, 0xa8cf22da, 0xb758cdde, 0xc1e8f9b7, 0xc9e75a78, 0xff3c11ba,
-       0x9e5e75d3, 0x09bad9ff, 0xa33dfe9c, 0x27ae39f8, 0x6c79673e, 0xd6a3b6d2,
-       0xe45faa14, 0xb7d8bc55, 0xdf857ad7, 0xdeb1744f, 0xf581cf26, 0x1f600e74,
-       0xf534198f, 0xe9303bf1, 0xda276d0c, 0x5171b8cf, 0x3c99c611, 0x7a8ac4a2,
-       0x2216bf33, 0x4e93ad3e, 0x8dee8bbf, 0xf8eb57f5, 0x6157bf3b, 0x1bdf9e78,
-       0xdf6cf0cb, 0xf9031191, 0x8ccee960, 0x6f89489e, 0x046f7a1a, 0xd97ed7e0,
-       0xff6df3c2, 0x8ef59c28, 0x774bf6d0, 0x7a89ec0e, 0x22df0967, 0xfb3cde48,
-       0x83b87ffc, 0x71b395cf, 0x027d5f4d, 0xc957f6fe, 0x39b248df, 0x5ff818f1,
-       0xd01e5eef, 0xce5d05cb, 0x02233d26, 0x6e8d5fe7, 0x427f0457, 0xb4b86cfe,
-       0x217f0ee7, 0x17f62c65, 0x9c1373c6, 0xb9191cc3, 0x7f7087c7, 0xfd467e47,
-       0x9258fcbd, 0xb9effa07, 0x63a48fed, 0xf34dadfc, 0xfa8c793f, 0xf8b7ef3f,
-       0x9d4e746c, 0x5e174d17, 0x2a7e1f05, 0x777bed92, 0x9c2f342b, 0x717b9bc3,
-       0x86b1473e, 0x2c39c32f, 0x73cfbcfc, 0x1975b714, 0x17aaadf1, 0x7a05ed1f,
-       0x30608d7c, 0x5b5fca82, 0xed7cc11b, 0xc8e79b35, 0xb8f7f432, 0xfbe9efec,
-       0x0bb63cef, 0x05d57de9, 0x65fa5277, 0xa1e31c46, 0x034581fc, 0x79ce9ed0,
-       0x3dfd4c91, 0x80128af7, 0xbad06abf, 0x69922b7d, 0x1c37837e, 0x34a2f4b5,
-       0x1ea529ff, 0x373ec0e9, 0xf9fd821e, 0x6e6e196f, 0x9a5b643f, 0xd96d829a,
-       0x75c9ffcb, 0xe59bfe7c, 0x9f75dc82, 0x3a25ed8f, 0x4a0183e5, 0x348d99d3,
-       0x8fd4b0d7, 0x6386340a, 0x6767af23, 0x6ff7b4f3, 0x49075815, 0x8977981e,
-       0x91e7c3dd, 0x7811b7df, 0x78e5af3e, 0xf62bbf58, 0x3b7a0a3d, 0x707a25af,
-       0xfa4cbd3e, 0x7fa8d5fc, 0x7cebcac4, 0xa2f7a9e5, 0x2189df61, 0xbf09d93d,
-       0x78db7e48, 0xe3eeafd4, 0xf587f016, 0x09fae279, 0x8ecd4f80, 0x9fb91b9d,
-       0xfa07872a, 0x4bcec56e, 0x2f205307, 0x993c20de, 0x321dc7a0, 0xaf42abff,
-       0x56a5a547, 0xe652fc6c, 0x5f398a5b, 0xfc27da4c, 0xca4ca2fe, 0xe7e88f49,
-       0x63cd68a0, 0xee24c97e, 0xafd7c4ee, 0xebe518a8, 0xb0c97cd3, 0x27e71b6f,
-       0xfda97b9d, 0xb2ec65b0, 0x5bd8cb7d, 0xdf2e1953, 0xebb3dcf3, 0xdfd197e7,
-       0x73e17623, 0xdf303f52, 0xc1be9ec0, 0xcdebcf2e, 0x2f4067c4, 0xe34d79c6,
-       0xed93f5e6, 0x29afe0bd, 0x076832aa, 0x91e523c1, 0xbe379630, 0x62b3f8ef,
-       0x6df9f156, 0xe1b55bc8, 0xd9f22f92, 0x885fed41, 0x37eeaed2, 0x7932760c,
-       0x3bab0bde, 0xe3c8f217, 0xfa6bde51, 0x96d5bcb1, 0x39d0358a, 0x53e61d7a,
-       0x95fc92a3, 0x457f2411, 0x73af7dc6, 0x2de51034, 0x5beffb42, 0xcd046c7f,
-       0xf1290633, 0x86a468ef, 0x485a45de, 0x7d39fc97, 0xf3f8135b, 0x3f926143,
-       0xbe610d47, 0x7433ac64, 0x07c4039c, 0x6f3be234, 0x11a339d0, 0x3917183f,
-       0x7d78cac6, 0x907552dd, 0x3922e5ce, 0x1ada0802, 0xdef3943b, 0x61638228,
-       0x2eb42aa4, 0x252347f4, 0x3ac7cdbc, 0x984427c7, 0xc42515ea, 0xbf8fb1da,
-       0x1d55faef, 0x3cb86a4f, 0x8370d4bf, 0x7413babf, 0xfac87dbf, 0x776f7ae5,
-       0x3abe630e, 0xeb7ef956, 0xdf15b22e, 0x8b8f3c09, 0x7373e7cc, 0x2394e45c,
-       0xd475e09a, 0x7ae87be1, 0x1c25d743, 0xfa8e4fdf, 0x167c2289, 0xedcfc7ec,
-       0xb66b776c, 0x5bf73eb5, 0xa2f36b82, 0x47ec0f5c, 0x70bed32f, 0xb54e9f80,
-       0x0cdb9cb3, 0x37ea92d9, 0x5c7170f7, 0xdfba6bcb, 0x6f5b37dc, 0xbe7c14ef,
-       0xc5eecf34, 0x615ef47e, 0x48ec1034, 0xd26fd2f5, 0x16f25b6c, 0xe5e6ebce,
-       0x819a1e29, 0x69efc150, 0x97e47ccb, 0x095ebcfc, 0x817f0adc, 0x40bb73ef,
-       0xfeb175fd, 0x5f94e9d5, 0x9e0c8bf7, 0x8fa447cf, 0x8abc62d7, 0xeb5be670,
-       0x71c9bd62, 0xff979f04, 0xb279f2a1, 0x91f29f2e, 0x6ed9d7cc, 0x378a6eb3,
-       0x04ad7e19, 0x36eb6f1d, 0xb05ef2ca, 0x4d3ca293, 0x26c4ffb6, 0xd7a2dfeb,
-       0xfbf1d04b, 0xb4a74eb1, 0x683f99ff, 0xa0ac2393, 0x95fb77ff, 0x46fbc6be,
-       0x17e19378, 0x933cac7a, 0x54b7986d, 0xf4c690de, 0x66d3dba4, 0xe8dcfce9,
-       0xc31c0d17, 0x9fcb4f21, 0x3b37f3d9, 0x2a33df41, 0x1f21479c, 0x22b1547e,
-       0x0cfd7a0a, 0x21840d4d, 0x917a6abe, 0x4bae43b7, 0x395eb8c7, 0x1fa1b96e,
-       0xdf00ca06, 0x710e6dbd, 0x81ffcb2f, 0x96fac121, 0xfa45e781, 0x1a6eadbe,
-       0x7eb060f3, 0xfe27695d, 0x72e51833, 0x6a45573f, 0xd57d07bf, 0xc1e1baee,
-       0x54fbbd60, 0xbc7943f9, 0xcf71f4ef, 0x3c1f79d5, 0x6f39099e, 0xb8c6a702,
-       0xf011fa1d, 0xd5f6fd49, 0xefda73cf, 0xdaf00b3e, 0x92fa94e4, 0x85e3edb5,
-       0x359faf94, 0x09f7cf80, 0xd85e1d53, 0x8477daf5, 0xadaf61f9, 0xc5ee159f,
-       0x44f7eaba, 0x985761f9, 0xd21befa7, 0x6fbbf8bb, 0xade98dbb, 0x667feeca,
-       0xdaabb50b, 0x89e99fdb, 0x96ed95e8, 0x642357be, 0x6d37b479, 0xf79450e5,
-       0xcd79fa64, 0xf2e18ee6, 0xe5c15537, 0x58ac81e1, 0x539b7782, 0x1375853b,
-       0xbcfdb2bd, 0x1fbf2eca, 0xfa12e9d1, 0x96fffb25, 0x42bf7144, 0x8f3f6bcf,
-       0x584f7d67, 0x91f3c9bd, 0xaf207dbf, 0x7dcbb347, 0x7ea46a21, 0xe725c478,
-       0x9e39a475, 0x8f4185f7, 0xdcb78a47, 0xef809593, 0xfcd2af24, 0x0d4cb2fe,
-       0xd06e1fc0, 0xf2f5329f, 0xbb5157db, 0xd9555f4f, 0xd7e7336f, 0xfbe30f8b,
-       0x13d5159c, 0x6bbcad39, 0xf5cb9f32, 0xa2eea71f, 0xa7a984f2, 0xe06bbfd8,
-       0xd9954e7f, 0xe9989a9f, 0xdf813355, 0x83f6ff5c, 0xd9e1ff54, 0xaf001627,
-       0x473533c3, 0xf6dbec26, 0x4cff97d6, 0xfe5d6df3, 0x36a3d627, 0xf8116b44,
-       0xd3f7717e, 0xc566bf5c, 0x7e802cff, 0x74956350, 0xb5db9c63, 0x91bf3d3a,
-       0xffa2c5a9, 0x63bf15aa, 0xb722223d, 0xbbd7f245, 0x3a3f1fbe, 0x65f9bcd3,
-       0x0e2dda85, 0x54e1ae6f, 0xfce1e7f5, 0xa204ab3b, 0x2b860c95, 0x5ce775eb,
-       0x47e06881, 0x72b948b3, 0xbf10d6f1, 0xa8925031, 0xdda88bdb, 0x8f5526e2,
-       0x41dbf457, 0x17f5a1a7, 0xf7ae77d3, 0x8a57bf3d, 0x763df926, 0x30d7fdd7,
-       0xfe0045fe, 0x64cf33ae, 0x9c3d026e, 0x5674f9df, 0x34369fb0, 0x72be72bd,
-       0x7df4e7fd, 0xd8be8e73, 0xc2db6f40, 0x0b85f64c, 0xf4eb24cf, 0xc2e9e926,
-       0xe7ecd933, 0xd9f7d44e, 0x0967c505, 0x085fbb47, 0x9e10678e, 0x971ce1a6,
-       0x0e1a6de3, 0x9d61fbb9, 0x6f8e2e2f, 0x67be0e1a, 0x68e141f0, 0x41bb63ca,
-       0xf41e534e, 0x8a7f8364, 0xfe2ca6e2, 0x42ca6fee, 0xd22d97fb, 0xa7cc630e,
-       0x8e14b9f2, 0xf0b5a27b, 0x6e7caefe, 0x8de426e0, 0x929dea71, 0x253bd4ef,
-       0xb75d097f, 0xe8ed2996, 0x1ee64fa4, 0x3ea4b3a7, 0x5c82f496, 0xde6593e4,
-       0x370bf329, 0x6fe1d894, 0xbcc9b7af, 0xfd897d6b, 0x35f7e618, 0x4fc4b569,
-       0xc5bf7473, 0xdda97f02, 0xfafefb0b, 0x3f1ce1e5, 0xcf3edb31, 0x7af6694b,
-       0x035c69bb, 0xe6fdfd0f, 0xf9f48bef, 0x0b890df4, 0xedb6a5ea, 0xf639c30b,
-       0x8e32e8a4, 0xb4a64960, 0x6cfb3ee3, 0xaa917c47, 0x6dc2dbeb, 0xea5ba1d0,
-       0x8fd78c1b, 0xef5e06ed, 0x2ff9a148, 0x5ea5e3d6, 0xfab848b6, 0xe37c959e,
-       0x052d7ce5, 0xc005d5e7, 0x2c5ce71d, 0xef2173e5, 0x7919bc49, 0xf0a15f03,
-       0x82f1f15d, 0x9f95d814, 0xc7f694c8, 0x8f2c7c50, 0xe513de1a, 0xd4cf5c06,
-       0xdc00ca1d, 0xa89d758d, 0x68e97af3, 0xafbfb4eb, 0x8c6877cf, 0x30477c8f,
-       0x1d6fd77d, 0x20248872, 0xd5ab6e71, 0x5bd42583, 0xbf43f7fd, 0x36aadfa8,
-       0x3b9704f9, 0x91739780, 0xbd41dffb, 0x0b621b05, 0xed180fa0, 0xf22fae17,
-       0x7bcd0796, 0x5e3356e0, 0xf3993506, 0xf3997783, 0x0d06715b, 0xe5dbe7fb,
-       0x21f9cc07, 0x93f9cc87, 0x3371dc1f, 0xea854fb6, 0xbe855fbb, 0x87f1e7f3,
-       0x7a9f4e70, 0xe06895f9, 0xcb5ff16b, 0x0b8f420f, 0x3c21678d, 0x7c73d02a,
-       0x97a6145b, 0xba5ae22b, 0xdc4643e1, 0x30627606, 0xdf0a54dd, 0x95da6b41,
-       0xa68acff5, 0x6744bd9b, 0xcfdecb55, 0xecb37a90, 0x5ad36477, 0xd0cee43b,
-       0x3be3bb71, 0xc6ebd222, 0x21192a3e, 0x365eaecb, 0xfe8a7c4e, 0x1e37bcd6,
-       0x2bf258f4, 0x929be585, 0x075fb297, 0x3edd1cdd, 0x6f4e46fb, 0x30f0c09e,
-       0x9b0b92ec, 0xe5144095, 0x8744235d, 0x8bf11f7f, 0xf1210da5, 0xe2426b9f,
-       0xcb99d682, 0xf7daee17, 0x504710ff, 0xe38278e1, 0x678cae2e, 0x5e801ff4,
-       0xb04a7959, 0xa9f2aa7d, 0xe5ccc26f, 0xf5f35d72, 0xade71875, 0xf1cb5df0,
-       0xaacb577b, 0xa3fe38e2, 0x4ba8e973, 0xcb73853b, 0x5eaf7738, 0xf29551b7,
-       0xfd84b7bc, 0x8e7691c8, 0x8876ac8b, 0xebcd0440, 0xebdd9450, 0xd697efa2,
-       0xb2bcb147, 0xe85ce480, 0x270a948b, 0x627a4dc7, 0xbbc4eed0, 0xd565cb2a,
-       0xd51e12f1, 0xb0fc51bf, 0xa8c3571d, 0x3293fc8b, 0xd80448bf, 0xf23a0bbe,
-       0xf803ad06, 0x468bce0b, 0x59565fa9, 0x9f00fb03, 0xab68738e, 0xad155eb9,
-       0xc838a3f3, 0x35efe67b, 0xd7eb8da2, 0x2c26faee, 0x3d907bf8, 0x435ef59a,
-       0xf97556ff, 0x3865fd4a, 0x20744fcb, 0x6cbe8384, 0xeebedcba, 0x6823921e,
-       0x7b0d2b7d, 0xdf295af8, 0x9e51b2dd, 0x679f2463, 0xd6eb4e01, 0xef867c92,
-       0xce206fa4, 0xf70a2c44, 0xea5ef94b, 0x6766eb0b, 0xf2f45cb1, 0x400a5e3f,
-       0x487b691f, 0xbad2bb61, 0xbaefd97c, 0x3973fafb, 0xe3c2a7f8, 0xb61cb184,
-       0xde518a6e, 0x4f91f587, 0xc864c530, 0x1ef7faf9, 0x4bdefe6e, 0x3ec166f5,
-       0xb2741e22, 0xfb90c47d, 0x2ebeb90d, 0x1ac9cb56, 0x75feb9d6, 0xf0516db1,
-       0xf88a89bb, 0x6cb725ef, 0x36e3cfd6, 0x2afc3f5a, 0x83e295c7, 0xf5198ff0,
-       0x73c96646, 0xef58f865, 0xfb1ebd16, 0x532dca5f, 0xe68ebdee, 0xc5b0fe55,
-       0x81a17b0d, 0x66f5e107, 0xd7c70e01, 0x77400b3a, 0x7b4ac7c3, 0xc97c91d9,
-       0x0a8623e7, 0xab1a378e, 0xcb363bf7, 0xc2934a62, 0x9fa91e89, 0x1ed245e3,
-       0x98b4351f, 0x132496ed, 0x6e2aebcc, 0x4fdeb265, 0xf7f8bdb9, 0x4f98bba3,
-       0x4a145d07, 0x6df8fbf9, 0x2f3926ca, 0x0e27c72f, 0xf6c9c07f, 0x39fae3ce,
-       0xe881e064, 0x0fcb1868, 0x0d8b5f3a, 0xa0b59ba1, 0xa0879c07, 0x6e982507,
-       0x8b7174cc, 0xee2be122, 0xbaf7f293, 0xe8379958, 0xf13ff482, 0x229ba0bf,
-       0x4eeff0c1, 0xdbd6340f, 0x74481e9d, 0xd07408b0, 0x0e842f51, 0xec3fd584,
-       0xa542fcdb, 0x2b876223, 0xab148284, 0x17ce21f0, 0xebc32467, 0xb11fab1e,
-       0x12adbd78, 0x92ac7d2f, 0xf1b4e8ee, 0x7d701785, 0x4b7de22f, 0xbc285c1e,
-       0x4524bf54, 0x1fad7db0, 0x713155c9, 0x45204edc, 0xbb0a8e58, 0x5f68a513,
-       0x2ffb2312, 0xfe3829e9, 0x5af3fa8e, 0x36e674e2, 0xc15efe1c, 0x47da0572,
-       0x9f7b7017, 0x5af7b645, 0x219bed29, 0x95b698f5, 0x5cbf1c61, 0x2c9f7772,
-       0xb1c4c9d0, 0xa2393a66, 0xde9195d3, 0x8dd6ed94, 0xf0249e75, 0xfe86d283,
-       0x3bd4de7c, 0x0277ab8b, 0xb047cf9f, 0xeab259fc, 0x618693c7, 0x7bc42f7e,
-       0x9333c280, 0xa83fb3b7, 0x4ff661b4, 0xb4be843e, 0x2bdfc9d5, 0x59f5b5b2,
-       0xf715ff90, 0xa1f49ddc, 0x7b01c674, 0x9ad7b512, 0x957f9ca6, 0xedbec9d2,
-       0x989e40ef, 0xfae55d3c, 0x3fb48593, 0xce39068b, 0xd6e7df24, 0xd26fea24,
-       0x69c38528, 0xa95d3a8e, 0xa40fc1b7, 0x2ca9f7e3, 0xe47f9745, 0x5592813d,
-       0x73d2b27d, 0xc9213fe1, 0xfd390bb8, 0x18fea353, 0xa5e40365, 0xfee4e3be,
-       0x1fa3ea33, 0x4b3a7bf4, 0xd5bf55ca, 0x09e462e1, 0x7cbf5cae, 0x8cd1d875,
-       0x40b6a468, 0xfde9a536, 0x7584bec7, 0xe3174c4e, 0x77ee03d7, 0xcf1362aa,
-       0xf984adb7, 0x1b965442, 0x4291abf4, 0xd6e3facd, 0x8f27ccfe, 0x7a3b698e,
-       0x6e8fe537, 0x8ced241e, 0xbe617dba, 0x707cb04b, 0x77e48c74, 0x98239b6d,
-       0x5ab88ffe, 0x3da4e2a3, 0x650ded8e, 0xb67c493a, 0xf87efeac, 0xed22cbb9,
-       0xcc7e7147, 0xc71a687f, 0x53ad9427, 0x07b86103, 0x6f6cc6b0, 0xded48aa8,
-       0xb5087ec6, 0x07da841b, 0xa3a03340, 0xd30a35f2, 0x8f7adf61, 0x9cf9993d,
-       0xcafac2e2, 0x70fd0323, 0x9c7b940e, 0x857cc71c, 0x826be0fd, 0xb9d870fb,
-       0xb5890705, 0x009f6b67, 0x258d254e, 0xe446efac, 0xfabfcc6a, 0xec1704aa,
-       0x26fe9d17, 0xbe0b5ec2, 0xc64d6d64, 0x9655fcbe, 0x3130f19b, 0xc91595ce,
-       0xfbe4ed74, 0xae6d4711, 0xe8efcc2c, 0xe705a74a, 0x9215c4ed, 0x39df69be,
-       0x1ee18f70, 0x3f0708ab, 0xfb259ad8, 0x5adcb39d, 0xbdf291bc, 0x151ac21d,
-       0x67cafa07, 0x5fd85efa, 0x75e62dfb, 0x046217ea, 0x35b289e4, 0x74bce56b,
-       0x96d610fa, 0xe71a78c2, 0x02b4e6d4, 0xe43a01d8, 0xdb63fedb, 0xba0ec701,
-       0x3d30ae98, 0xc10e7ad0, 0xbfde9c8e, 0xe9ca32f4, 0xcbd03efb, 0x7e81b1c4,
-       0x522f1b88, 0xb6be38ab, 0xe078493d, 0x6d176c77, 0x93b48f2c, 0x67be023c,
-       0x9f8319f0, 0x1d785d10, 0xdef89d89, 0x22534752, 0xceb5be1e, 0x75b3e9c1,
-       0x7825612e, 0xe24bab6f, 0x6e750bfc, 0x72ea9b4e, 0x758bfbf8, 0xa8efce1e,
-       0x97f9c11b, 0xdf9cbceb, 0xd3813755, 0xf98aeb57, 0x08afc1bb, 0x0c97cc3e,
-       0x27f063be, 0x3e0cbe83, 0x73574a15, 0x17b8cc09, 0x1f99ed41, 0xeb107c1a,
-       0xf27414b0, 0xe9cf0327, 0x092fb14a, 0xceb450fc, 0x5228ff06, 0x0aff3dcf,
-       0x22bdb9c1, 0xed22ed92, 0xf6c1f242, 0x079f0748, 0x0bb176a9, 0xdbfa89f6,
-       0x0eef47bc, 0xad6f873a, 0x88358450, 0xc4bc7f8e, 0x7441ac29, 0xac596f3c,
-       0xd9673f29, 0xa4f46ffb, 0xd18ddffe, 0x1e69b372, 0xe2797e47, 0xf7d13ff1,
-       0x4cf2fcdf, 0xf34ef026, 0xc608fcd8, 0x9f5c2bbd, 0xd79cab47, 0x9796765d,
-       0x7d4b86fa, 0xd4b86fab, 0x08e3f0b7, 0xa23dcf8a, 0x2d24a3e3, 0xb1a79df6,
-       0x9baeec6f, 0xb44ec047, 0xfa4bde52, 0xf2a3f804, 0x2bf8e8bf, 0x70c6165d,
-       0xf7d06d2d, 0x36dc706b, 0xb258f5c1, 0xf14ef960, 0xd7bf010a, 0x03d85fb1,
-       0x63882b24, 0x40afc38a, 0x6be52276, 0xab98ec0e, 0xe411f77f, 0x21d96576,
-       0x4735b396, 0x087fc724, 0x705ced9f, 0x83b2ca7f, 0xf6b44f5c, 0x466fc536,
-       0xc1daf50c, 0xc0e34037, 0x7ece695f, 0x1a2efd81, 0x547fbe15, 0x5f2f7fae,
-       0xa2e298ad, 0xf2ab6467, 0x959645de, 0x4259f3d3, 0xf91a473f, 0x96e832bc,
-       0x61c708f8, 0xdbe63796, 0xe7f10417, 0x597bfd52, 0xa714c58e, 0x9d967f79,
-       0xcd8f39fb, 0x9bdefd49, 0xcf9f6e93, 0xf7cdcffc, 0xa5fa8c05, 0x60ab0539,
-       0x835d2e4f, 0xf6cea6a8, 0x7d56d925, 0x7fa92e5e, 0x8b5ce839, 0x2ea2f8e2,
-       0x9e4307cf, 0x475f8539, 0xef59fcf2, 0xb9e17caa, 0xac8fe017, 0x9f1873fc,
-       0x75839553, 0x7fae4afb, 0x839634f8, 0x70ca91bc, 0xff12e1c8, 0x35fdcf85,
-       0xb55d711a, 0x97bda43b, 0x6b48a3d2, 0xfb60aaee, 0xf6878d5e, 0xadf81c49,
-       0xfaffefd9, 0xfbe67f0b, 0x14b0849d, 0xe3986e3d, 0x7c766ad4, 0xb06bf1ca,
-       0x7286f9c7, 0x1d5f1c7f, 0xf956beda, 0x4257f59a, 0x68a7c32c, 0x3c8997cf,
-       0x12979d8f, 0xf76ae7c1, 0x2aec4cac, 0x1fb4288e, 0xb0c1ce23, 0x358ad5ff,
-       0x59cfc39f, 0x9384d77b, 0xff65de92, 0xca1eeda1, 0x31384a8e, 0xeec62050,
-       0x5893b62a, 0x2c9fc705, 0xed38edd5, 0x63f64cfe, 0xd7772777, 0x2446a7ae,
-       0xdd5bb592, 0xbeb38831, 0xae84c428, 0xb649f4f0, 0xd3cf6b94, 0xfb3f823e,
-       0xe59536e2, 0xa2db8bca, 0x6cd43f78, 0xe220f07b, 0x529e6b04, 0x2d58edd8,
-       0xafce385a, 0x1c2a8766, 0xec1de7c1, 0xcfddf147, 0x5173f173, 0x8b5f404b,
-       0x66ef149a, 0xc3bb4f9a, 0x6823d31d, 0xbe80af3e, 0x87173488, 0xff470d35,
-       0x079ffcc6, 0x37920b7f, 0xc83f3517, 0xef548df1, 0xbf37cb02, 0x3c38e08d,
-       0xc1dec93a, 0x186ecf3c, 0x45f5fec2, 0x586bdb4d, 0xe116d83e, 0x8ce9e982,
-       0xe40f7ccd, 0x81de3e80, 0x9c8f296c, 0x67d1edd5, 0x1f59505f, 0x2fb13cc2,
-       0xb871e8cf, 0xf537bb46, 0x4b666f76, 0x5b26a7f9, 0xfea34fee, 0xd1a3a6a2,
-       0xc9fea8fd, 0xfa73ef5d, 0x166fbebe, 0x3df0b645, 0x223b93cf, 0xc9e09ef8,
-       0xfe39ff1d, 0x7cef1a35, 0x250498d3, 0xc89d9f68, 0xba7dc9b6, 0xf32fc641,
-       0x13d61725, 0x673d789a, 0xac28a5b7, 0xa4de032f, 0xf1dd9fb7, 0x3643df12,
-       0x1c1febe4, 0xb14b382f, 0x18a3dc86, 0x8d72083d, 0xd7bf55a3, 0x63dba6d1,
-       0xaffa6ffe, 0x5927bfd1, 0xe471f58a, 0xc4610d3d, 0xbd64b86f, 0x27b73522,
-       0xc1dcddf6, 0x97b899ee, 0x7192de2d, 0xfbb7a297, 0x737fe811, 0xbb678ddf,
-       0xbb9b52cb, 0x1c5ff227, 0xe0958526, 0xce887733, 0x875a9257, 0x347bbec1,
-       0x8615ca4d, 0xb56aad3f, 0xbf04bc22, 0x3e67445e, 0xd0aafde4, 0x49c90760,
-       0x563d7c67, 0x71daf161, 0x99d9463e, 0x3bb7ea2e, 0x75bec137, 0xec7c2ec4,
-       0x29d17b7f, 0xd2e927fd, 0xf618f20f, 0x7155a517, 0xd878ac81, 0xa9ba74f1,
-       0x41e54a9a, 0x29b553f4, 0xea390590, 0x2bda5d9c, 0xa9fd0e51, 0xabd640aa,
-       0xfd14e9d7, 0x69a3dfa0, 0xf72c0bae, 0xd0128cee, 0x44af2c3f, 0xd3c8bb49,
-       0x41614dce, 0x1cbf76e7, 0xc777118b, 0x66df4afe, 0x0bcc3f39, 0x7b22fcf2,
-       0x5de41663, 0xd145dc63, 0x39de3c8d, 0xe145bc7d, 0xa39fd28d, 0x3ea211c7,
-       0xec136f8f, 0x267b6a77, 0x33e6e58c, 0x632f2dc9, 0xf4cf33fc, 0xa387b8e7,
-       0xbb05fe69, 0xf1c9dcb8, 0x86cf95e7, 0xd3df3005, 0x5db144cf, 0xca4db4eb,
-       0x12a3a763, 0x143b1e59, 0xf65cf0f5, 0xa6153d63, 0x5a742ec0, 0x9424f611,
-       0xf2c1ee6f, 0x32dd6540, 0x1254d7f6, 0x4b1c817b, 0x7fc804e9, 0x67f737a7,
-       0x37e9d17b, 0x415cbe55, 0xbbe357df, 0xfee71a26, 0x0880f58c, 0x799e23b6,
-       0x83fd6ff6, 0x5a463bfd, 0x3ed994f9, 0x5183d066, 0xf923945e, 0xd48e5160,
-       0x71c86e53, 0xd11d5a71, 0xaf3a70f4, 0xc207f253, 0xb481eb03, 0xef61131f,
-       0x3bb4d23f, 0x9c048951, 0x09ff5903, 0xfa956fb8, 0x366d99d6, 0xbe5553f6,
-       0x3b65e512, 0xf157ddd4, 0x554ac97d, 0x1695e3ca, 0xf950df79, 0xffb656e5,
-       0x2ce33fd4, 0xde083c00, 0x6db6dfac, 0xe471f556, 0xf4b7a7b8, 0x808d7e91,
-       0x10797f9e, 0xc62635fb, 0x59537989, 0x0790dace, 0x2a7a5eb8, 0x69fee382,
-       0x34e22f1c, 0x73f67f2a, 0x0598cf09, 0xc1d027ac, 0x4ab9fccd, 0x77d5cfe7,
-       0xfb83135f, 0x955de210, 0xb25c79ef, 0xff827a7a, 0xd1ebc286, 0xbf3f9d1c,
-       0x83f338fc, 0x8837da2a, 0xfbac5b0f, 0xab3f1713, 0x78b95cb0, 0x308f35d5,
-       0x26c77ddf, 0x5ce22f70, 0xc1d183d3, 0x91cfa8f8, 0xbdb3b0fc, 0xa62feb87,
-       0x5bfdb2fa, 0x2d9f3cd1, 0x13e60f36, 0xddefc78a, 0x07f559fe, 0x226cafb5,
-       0xcaef22f9, 0x2d125ff5, 0xf833fd3f, 0xfb2736cb, 0x7cff0951, 0xadacea3f,
-       0x7fd60169, 0xf32779f6, 0x72b1b39d, 0xf3a49fdf, 0xf98d97d4, 0xb66bf4dc,
-       0x9a61fccb, 0xd0b439c0, 0x98d7ee6f, 0x9b1cead7, 0x4f78b7a4, 0xd544fc0c,
-       0x47f40f84, 0xb711f9f8, 0xedc6d77f, 0x40b3d743, 0x4fb1d76f, 0xba608f9f,
-       0xe24bdb39, 0xd90bece5, 0x8d1d9e7c, 0xf34ef495, 0x74de854d, 0xb8a65636,
-       0xa87a0499, 0x387a4974, 0xed89a63b, 0xed956702, 0xc9b51e9c, 0x74cb9576,
-       0x5fd13b7f, 0xb407e812, 0x63aabb09, 0x19e40b4d, 0x05e1f9f0, 0x4f70069c,
-       0x0e8ed43b, 0xd7f9c53a, 0xe333efaa, 0xebf6051d, 0x89a79fb0, 0xba6bc7ef,
-       0xedb5593c, 0xf0257f4a, 0x614db554, 0x197fda7f, 0x13acd0fd, 0xd1003f0c,
-       0xc29f62e5, 0x6e2c22ef, 0xfb116db8, 0xbdac96d3, 0xac6f7415, 0x6f7eb163,
-       0xf2a2a8fc, 0x693a8e7c, 0x395ee4ff, 0xdfdf019e, 0xef1d28e7, 0xf38cb875,
-       0x3bf0f68b, 0x47496e39, 0xfea46d94, 0x35941aaa, 0xa19a4e3c, 0x19f5cae7,
-       0xd8b02270, 0xaa3be761, 0x6eeed3df, 0xbb3cc6fd, 0x9d31cf9b, 0x934d1fcf,
-       0xdedb93f7, 0x2fccf796, 0x26243d7d, 0x41e45bee, 0xf46061be, 0xd063b887,
-       0x22f3f520, 0x35f61cf8, 0xcf34ebec, 0xff660dac, 0xe653ce4e, 0xe66d80fc,
-       0x730eee7c, 0x9cd9af3e, 0xce6ebcf7, 0x0ee309ff, 0xf41384eb, 0x4235c46f,
-       0xfd0a46ff, 0xf5261ddb, 0x7fa1e46f, 0x8dfe8523, 0x91bfd0ef, 0x3c8dfe87,
-       0xa1e46ff4, 0xfe85237f, 0xfeeeef8d, 0xba554e12, 0xe07814bd, 0x4eddbab8,
-       0xf7813e23, 0x89d9c5cb, 0x558547cc, 0x1717a5ea, 0xd8fcb2e5, 0xe29a6f61,
-       0x11937b60, 0xad18958f, 0x1c47f785, 0x2ab2d280, 0xb1db8d39, 0x55f6ba1d,
-       0x2aae8769, 0xeec24670, 0xe4f2bad1, 0xa73d882a, 0xd418b4a3, 0xdb6b68bf,
-       0x2f56f802, 0xff7ec03b, 0x77eee5d6, 0x63f893af, 0x5f118bfb, 0x0f738255,
-       0x25f49b7c, 0x71ee7719, 0x4353db04, 0x4d6244fd, 0xd3f21e50, 0xd43e733a,
-       0xe6be042f, 0x46abed35, 0x6c6fc7c6, 0xfbe0c96d, 0xe0e33e9f, 0xea9f69fb,
-       0xcb313bf6, 0x2198f2c1, 0x1bce23cf, 0x9f7a5970, 0x95e709b2, 0xc31c7fa7,
-       0xa650fdb9, 0x68617ee9, 0x0879765a, 0xf91df3cb, 0xe3058a35, 0xbe5f4f94,
-       0xcd6af58f, 0xedd2e7cb, 0xd7b2dcfa, 0xeef34c5b, 0xd1370fef, 0x71adc0d1,
-       0x5ecc7e21, 0x7783faa6, 0x31f887a5, 0xa7ca9807, 0xbe6219ad, 0x8d7c5f8f,
-       0xbdafbca9, 0xa1cf6e23, 0xfce4b9fb, 0xa5ceb25c, 0x6f5e02c8, 0xc554bd68,
-       0x6ff827f3, 0x4e52dbc5, 0xc673a72d, 0x2bbfaf1b, 0x9d7f0052, 0x57e03277,
-       0x858b64d1, 0x3f4cad9d, 0xf332c487, 0x15615cb9, 0x275c573e, 0x84b855dd,
-       0x7fda9637, 0x654c6d69, 0x47e5fa3a, 0x68812aa9, 0x3c9680d1, 0xde8bafe8,
-       0xe838727c, 0x98dd5aaa, 0x3bf2a2ea, 0x5c16ff14, 0xb7133f20, 0x9524713d,
-       0x495aa927, 0xaa73c27f, 0x1cff702d, 0x19edd1f0, 0x7ca4ef02, 0x68a5e6ba,
-       0xe9d41f8e, 0x0ae6d52f, 0x6c6c1d07, 0x814f5954, 0xeb8d4cfd, 0x8d8d93a4,
-       0x6bd0e1f1, 0x3e28c62a, 0x5c06c7c8, 0x8508fa0c, 0xefefc907, 0x97bd69ba,
-       0x94f7c90e, 0x752e758c, 0x41a2fac9, 0x07de37b6, 0x5c7bd630, 0x372b47d7,
-       0x3b7591be, 0x7fd73f7d, 0x7e1b9e5f, 0xbc5dbadc, 0x6d96c5ee, 0x7d29925b,
-       0x85dda1c7, 0x7b7d2d75, 0x1a48f45c, 0x326dcbe7, 0x75b3fdae, 0x23e13e4f,
-       0xe3777a7e, 0x0fe87693, 0x9dbf5695, 0x6679cddf, 0x0ef11da3, 0xc8dd6fd7,
-       0x2d6c17df, 0x71807b61, 0x1194eecf, 0xa3c3ad97, 0xc1b2ac62, 0xde3ceb45,
-       0x1585ca5f, 0xa69e32e1, 0x46f51d48, 0x55b5d602, 0xa6bac7c9, 0xe3b76f17,
-       0xf58781fd, 0xa6fba17a, 0xa2b4f0fd, 0x357bb01e, 0xd4c71c29, 0x11993edd,
-       0x64fbcfe8, 0x4e34e5da, 0xc81e5fa7, 0x8287de7a, 0x239c2fb4, 0xf5fa21b9,
-       0xf5da5561, 0x4ef9559a, 0x30903d98, 0x5ec2f20d, 0x35456ef9, 0x0a23439d,
-       0x710bb7a0, 0xa3c5a535, 0xd79d1354, 0xf6984616, 0xb4112cc1, 0x9bbfa8af,
-       0x7e532f45, 0x530cc4fa, 0x07d399fd, 0x0b9df886, 0x7f99cb3a, 0x8f7a6d5d,
-       0x9f2efaa6, 0xc7bb615b, 0x4a77f358, 0xbb3a62ef, 0x5abed4d1, 0x47bd354c,
-       0xf7a9e8b3, 0x6544ce18, 0x54e1c476, 0x6658f7e8, 0xeff54769, 0x169dfcad,
-       0x7dafda62, 0x927f3c33, 0xfd8da5e7, 0x7d3d8609, 0xe8cf7e16, 0xef0cbcea,
-       0xbc451788, 0x9a1dec30, 0x61691e59, 0x3c48553d, 0xa8f6eb54, 0x8f691cea,
-       0xd8b5f6aa, 0xf04d8f11, 0x4810a6b7, 0xb6151a6a, 0x477d5237, 0xdfcc9c4a,
-       0xcc3bef85, 0xdfd052f7, 0x521f9465, 0x42bfb04b, 0xdd686bcb, 0x606a1738,
-       0xd83b6247, 0x076c9384, 0xfbd1c633, 0xf434e837, 0xfed0807d, 0x33700c06,
-       0xbadcaeff, 0x822f60fd, 0xd8e2b4cf, 0x549dc47c, 0x95b14d35, 0x6f495ee4,
-       0x54bfff06, 0x7ebf6161, 0x4c03e1fb, 0x5615ed6f, 0xff4b8c8f, 0x78d4b876,
-       0x9435dda5, 0xbad0170e, 0xb05e7fe0, 0x15f8f143, 0xe9f00f59, 0x810cfa05,
-       0x70174a4f, 0x01d5e033, 0x7e7290bf, 0xe2286e3f, 0x0a7be426, 0x1425c057,
-       0x0b38fa9e, 0x2772c134, 0xf3cfcbcd, 0x8c57e90a, 0xb78fdd08, 0xb0ffd9db,
-       0xe52e1141, 0xf531e1bb, 0xf4e3b4b2, 0x6feb90cd, 0x2078a9db, 0xd97cdfbf,
-       0xe83bdfca, 0xd9c658a7, 0xde689f4f, 0x54f41daf, 0x8ccff72c, 0xeedc89cb,
-       0xdf5745df, 0xff864f45, 0xdd7e3426, 0x19e647b8, 0x1ab7dfa0, 0xf37d8626,
-       0x1be1c44f, 0xe77741f2, 0xe439c74c, 0x9910f1d2, 0xbcf9e5de, 0xe39d2a34,
-       0xbedd35cc, 0x4d69f068, 0x5b8c676f, 0x78eee542, 0x7e6f7bd0, 0x43557167,
-       0xfbf06a46, 0x1b4ada37, 0x975381db, 0xe25a73c7, 0x7ce22574, 0xdf2e5929,
-       0x4f763969, 0x29f844cf, 0x25b4ad8e, 0x8faea44c, 0x553439dd, 0x88be420c,
-       0x86d74fd3, 0xcfb60acd, 0x032de91b, 0x9c61f9e4, 0x872de7ef, 0x3f6167a3,
-       0x8d19dcae, 0x2bc5a190, 0xa2ee1fdf, 0xa2d9be73, 0xfec01a2d, 0xce7c8de0,
-       0x3cc6d70b, 0x390ce7d8, 0x516572a3, 0x5503c84f, 0x04f038ff, 0xb96d01e4,
-       0xea72112d, 0x81540fe9, 0xe73a1ad0, 0xe538be58, 0x6a7df494, 0xabdf0473,
-       0x2f08a53c, 0xd48b51fc, 0xd32e797d, 0x337cdb79, 0xd2708fc6, 0xae30c3b8,
-       0xc6124b7f, 0x30b2f8f5, 0x333cb6ae, 0x8bbb2ba6, 0x97aed691, 0xc316dff2,
-       0xa3dbacce, 0x0f23f721, 0x4b645fb9, 0xc8791fb9, 0xf72148fd, 0xfc0d7be3,
-       0xd71bf00e, 0x6f43e5b7, 0x39158df5, 0x8e1cf84b, 0x7f5c81cc, 0x01ee12bb,
-       0xf15dba3f, 0x8478e4f4, 0xf9e5620f, 0x2357821b, 0xb246dd1d, 0x5edd1059,
-       0x8221d977, 0x88c6ebe3, 0x9c7e5358, 0xbf54d923, 0x2a6695c8, 0xbfa93ebf,
-       0x7706fca9, 0x537f29be, 0xfd5348ce, 0xa6319e49, 0xdc468ffc, 0xc53faa60,
-       0x9f94c53b, 0xa9b66136, 0x12e28cfe, 0x59ccf953, 0xb3e54c8b, 0xf94cdbb5,
-       0x34ee2b5b, 0x92f1ffd5, 0xaf72a6e5, 0x0e715970, 0x231f4336, 0x3e85efb8,
-       0x6fede946, 0xe3064667, 0x4b38d475, 0x350cef97, 0x56fa900d, 0x39f7ae74,
-       0x09ee25d0, 0xe8fb0e81, 0xe2f680f7, 0xbf06199c, 0xfa914065, 0xe8324b70,
-       0x685eb426, 0xfd88a8f9, 0x6594f097, 0x9f6ee7ff, 0x313e2561, 0x43fdaaea,
-       0xfb7f2832, 0x5619e6c0, 0xaea32fe2, 0x3a52ffd9, 0xdcf17fe5, 0xf07cb237,
-       0x57284bfe, 0xfccbf772, 0xc822c134, 0x9bce06af, 0x8c75a3e1, 0x8d7d2eba,
-       0xba53da47, 0x5235538c, 0x9d7101c0, 0x00d20380, 0xfdd227d1, 0x5f489f44,
-       0xb72cfa27, 0xe8907109, 0xd221e913, 0xf7fdf14b, 0x3d2297a4, 0xd2297a4c,
-       0x452f4877, 0x297a42da, 0xcdd43fd2, 0x3a83f4e2, 0xb1fddb8d, 0x8fd382ae,
-       0xf7f096ea, 0x7196ea4f, 0x1f3a97fa, 0x8064ff7f, 0xb0087f61, 0x8bf0c69d,
-       0x091fc0d5, 0xdb2ede7b, 0xb1bf60b9, 0xabe795e2, 0x5facc7e1, 0xb0235a22,
-       0xb1ad5b4f, 0xfe9d1c27, 0xadf9eec9, 0x92089c55, 0xdee19ccb, 0xf8f006cf,
-       0xb7cc5dbd, 0xc447eff5, 0x84053eb4, 0xb5d34fa7, 0x3307e0b3, 0xc656ca0a,
-       0xeeb8ff10, 0xd03625eb, 0xae9687cb, 0xd5efa3ef, 0x03a7dbf9, 0xf7e86dbd,
-       0xa65dfd5a, 0xae321d6b, 0x6b6b5af0, 0xbfdbdb3d, 0x03c46e14, 0xefec33ed,
-       0x5ef958f7, 0xe085f2b1, 0xc104e8fc, 0x5b2ffaf9, 0x5af10e38, 0xcf892797,
-       0xc46f3d1d, 0xfdf87505, 0xef1413f1, 0x8de1f863, 0x2fc29f78, 0x3e41c75a,
-       0x77691d18, 0x0dc48587, 0x2fbedfc0, 0xbcc68fea, 0xc3277df8, 0x97d4ffbf,
-       0xf2f78022, 0xb5fe3f0c, 0xd834968e, 0xe1df4615, 0x33c704f0, 0xe57afe19,
-       0xe715168b, 0x64af1189, 0x3bcc638c, 0x15fd4aca, 0x5d23c674, 0x47ca6aeb,
-       0x757d465c, 0x93d7f724, 0x49dde3be, 0xb955e7aa, 0xec3e535d, 0x22aba3c7,
-       0x8ce9423d, 0xafa9e813, 0x3af1ea9b, 0x38d0bf0b, 0x1eb4624e, 0x1c7e8127,
-       0x01df9cb2, 0x48109d1c, 0xa39ffbc6, 0xb03dd897, 0xb88e3e83, 0xb8ce82b3,
-       0x088fd405, 0x2798c7da, 0x15f7edfa, 0xbcf217cd, 0x9df0cbd7, 0x29f492e6,
-       0x3f5e7adc, 0x2c6385af, 0x3d54bbdb, 0xfae61c5f, 0xcfd1046b, 0x90da19ad,
-       0x1fdfd481, 0x7ccc8c94, 0x7a3217d6, 0x094fdf60, 0x0bb04779, 0xf03119fa,
-       0xbc7e84ff, 0x05bdef12, 0xe942e1db, 0x418fc0c8, 0xbbde064f, 0x0e832ba3,
-       0x18d0e282, 0x65711def, 0xf4a17f7a, 0x199d1dd6, 0x43ad75f4, 0x8cf001d2,
-       0xae8320f8, 0xf89a2f94, 0x2ae8eb1e, 0x067f9f07, 0xc5d2855d, 0xe9257495,
-       0x0e27feb4, 0xba4aefee, 0xc007a4ea, 0x55d387e5, 0xf8f38a8b, 0x79a7a59f,
-       0xee3c626d, 0x765c97ff, 0xabda441f, 0x7c17b69f, 0x198c4ca6, 0x2e13120f,
-       0x62ec1075, 0xba32f5a1, 0x7f4a17a9, 0xbc6eeda1, 0x6e465da2, 0xfa71bb70,
-       0xaeda1959, 0x047aed12, 0x71c21bb7, 0xf7e96f11, 0x1a72de08, 0x999e2d71,
-       0xb90e5390, 0x2f2df26d, 0x27cc8de1, 0xf3a719ba, 0x096243f3, 0xee24bf9f,
-       0x854f40fa, 0xcb8d693a, 0x42fac85d, 0x71d76461, 0xedea3705, 0xdc5d7fc7,
-       0x4f8cf980, 0x37e3cb30, 0xf5fcf2ea, 0x0ffb91a2, 0xc6e1477d, 0xce59ebdc,
-       0x61477d0f, 0xfe3d40f3, 0x81a44d20, 0x8f0a17df, 0x0efe9f9c, 0xcfbea146,
-       0xc9ba7453, 0x5462ab70, 0x6a9bee1c, 0xaf321c56, 0x3c8c1de3, 0xfce3eb8c,
-       0xe9cfc20d, 0xfdc0224d, 0x0903a24c, 0x61091ff9, 0xc85fef93, 0xaa35bafb,
-       0x5790dff6, 0x4fba7b8d, 0xb057b53b, 0x4c440fcf, 0x4a77839e, 0xd7190dc6,
-       0x17f6ed0f, 0xdbce59ba, 0xb960c8ef, 0x16d2fb13, 0xde27c9d7, 0x5fba73a4,
-       0x8a37bca6, 0xfb46f714, 0x3bfa79d1, 0xbf91c73a, 0x40b96731, 0x736ef1bb,
-       0xfed193bc, 0x6138d726, 0x9cfeef8d, 0x776f29bc, 0xdecdd86f, 0x042ecd8a,
-       0xbd8adf7e, 0x7deb10aa, 0x45a7b62b, 0x4e7661a6, 0xafd2bd07, 0xa0d8b92b,
-       0xc6f1cefb, 0xc1dd78f3, 0x286b80d9, 0xff380d3c, 0xeb1eb800, 0x077bae0a,
-       0xaa379608, 0xad5f2423, 0xd57c908e, 0x58757380, 0x9ede7dc7, 0x5527f1c1,
-       0xf9af090e, 0x5611aecb, 0x2c17f512, 0x93f9c91b, 0xb807c275, 0x6092c69f,
-       0xf7b10f10, 0xce58eb09, 0x9ddcef1b, 0xe8bdf87d, 0x2ae79a24, 0x983ff687,
-       0x4082b9df, 0xe2844916, 0xbe7a86e4, 0x05fe7f8f, 0xaa7d03d5, 0xf1af754a,
-       0x96facec0, 0x7d71ef2a, 0xfe15207d, 0xd754f158, 0x0e55e8f1, 0x9f435f09,
-       0x98afd21c, 0x5fb1adf7, 0x80befe85, 0x0ef55f21, 0xc6dcf193, 0xe4eef73d,
-       0x92e1e1ad, 0x930ef5af, 0xebc0d8fc, 0xee7ebb06, 0x89c33f53, 0x3afca68f,
-       0x98abf59c, 0x2e4c6f58, 0xc28583ec, 0x76189fa4, 0xf904f695, 0x22b5ca7e,
-       0x945191eb, 0x13643c2f, 0x076f2a7e, 0x92794043, 0x1fb6b3f4, 0xef82a4ba,
-       0xfc294517, 0x6f71863e, 0x22c92c29, 0xc27c41dc, 0xbd370ee9, 0x13911b4b,
-       0x7947ca67, 0xc7ea997a, 0x9537488c, 0x98077ac7, 0x1427e3ca, 0x8a3df298,
-       0xefd536af, 0x29ac6b39, 0x68ddac9f, 0x31529faa, 0xf83794d5, 0x24fc8a58,
-       0xc5b92cfa, 0xb2efbed4, 0x34fd5352, 0x5ca9a55f, 0x319b3bc5, 0x25b7ab40,
-       0x81cf1127, 0xd58c9fca, 0xe3de434b, 0xf0cb08b5, 0xfe6b77ce, 0xcbde5a33,
-       0x80b91099, 0x6cc9afdf, 0x9e7999fc, 0x2c6b44ea, 0xcdbbd7a5, 0xc928b17c,
-       0xb9171f9c, 0x71df814f, 0x9fcccb9c, 0x4d589653, 0xeae51ff9, 0xe44f34fc,
-       0xbbe3ddb1, 0x300daff0, 0x4e143fe1, 0x7efc0f44, 0xef9d3b68, 0xcdebcc3e,
-       0x070f7e32, 0x75e0937e, 0x0c126fc0, 0x824df807, 0x049bf0f3, 0x24df87d7,
-       0x937e1cb8, 0x8721f2e0, 0xd61ff8cc, 0x55ffc662, 0x6ff1991f, 0x787765d0,
-       0xa66ad91a, 0x9a29a10f, 0xba782df2, 0x7e9994e6, 0x1d73f142, 0x09b15b89,
-       0x09e287c0, 0xbe387fb8, 0x8be08656, 0x37f7c3f0, 0x31477bdb, 0xd7d71e7e,
-       0x20606d75, 0x3a2e97df, 0x6fbc0aa4, 0x71f3ac63, 0x6d3fdcfd, 0x89731ad5,
-       0x5dcefccf, 0x763e0490, 0xdb7e909d, 0x4f1655f1, 0x207fba80, 0x29d99c64,
-       0x3fa843da, 0xaa52fe2b, 0x26d2741d, 0x0e7bcfdf, 0x95d8797c, 0x123eb2f1,
-       0xf6bef84f, 0x27be54cf, 0xa8d2c475, 0x8eaf8f80, 0x9f009ed1, 0x84bb9799,
-       0x8a249bd7, 0x5c402fb7, 0xa5857fd4, 0xafb73f22, 0x722dc7bc, 0x89fef95b,
-       0xa6e727c1, 0x2da9b8c8, 0xdd7fbab9, 0x9ea7e323, 0x777295c9, 0x71c5c794,
-       0xf2b925de, 0x8ba90d7e, 0x010773a9, 0xd99d873e, 0x0b3acf80, 0x8ad9ebbf,
-       0x9d09e47b, 0x0f21c8f7, 0xa3ecfe43, 0x1ff57fcb, 0x47581c3b, 0x3a617af6,
-       0x1dfbfb7f, 0x81e2f8a6, 0xfca65d5b, 0x5324a6a0, 0xdcbbc1fd, 0x40fcf2a6,
-       0xc87ca98e, 0x3f298f21, 0xa98465ac, 0x791f55fe, 0xad91f94d, 0xaff54c13,
-       0xca6c5539, 0x47b688a7, 0x8abedf01, 0xcd1c53b4, 0xb9fa974d, 0xe4dc705b,
-       0xe563bbdc, 0x7edd5f7d, 0x46fbc861, 0xd3a6b9dc, 0xd11ea875, 0xe8e52ed7,
-       0xf52164fa, 0x1fae8746, 0xa13eb30a, 0x1de371e9, 0xe67c58f7, 0x5e2371b8,
-       0xd0ef43bc, 0x7b8e8af5, 0xe2f19d34, 0xf178e0de, 0xbf5d61b9, 0xc75e7d1f,
-       0xfbfce87b, 0xeb7ae5da, 0xbdf3b4ef, 0xa15e631d, 0x96c949f3, 0xd1d9bb74,
-       0xbfaabdf5, 0x46fb4ae5, 0x25f1666b, 0x3613fdd0, 0x6dff2b4f, 0xf3c62b84,
-       0xb75e22b4, 0xcf7617fe, 0x8f77f70a, 0x5cb07737, 0x658b1ccf, 0x8e5c94de,
-       0xddfd338b, 0x92418884, 0x7583adbe, 0x78c84afb, 0xdc646373, 0xbbb1889a,
-       0x8fddbf41, 0x6499e127, 0xff7c0d17, 0xf167bf4b, 0xf74d35e3, 0xbd8e68a1,
-       0xce3f7f51, 0x4c3d036f, 0x59f24b1c, 0x5b13c93e, 0x49143d7a, 0xcb13ca72,
-       0x8a9f6cac, 0x3757fe7b, 0xde75fafb, 0xfa4be99f, 0xb203e810, 0x07a8f40e,
-       0xb72954f2, 0x2beb920c, 0xb8eebf52, 0x187ec0e7, 0x43f3f421, 0x174fbc70,
-       0x6874c6f4, 0x75dfe3ac, 0xdba0c1ef, 0xfa193850, 0x3be3d0af, 0xd2f319fb,
-       0x07ec67e1, 0xfdc67e03, 0xb66df713, 0x7c914de2, 0xe202658f, 0x6dfc0ce5,
-       0xc6f693c9, 0x503c3a05, 0xbba8fc0f, 0x6e6a457a, 0xedf7ec0c, 0xeae31dc2,
-       0xea3b0e82, 0x62e09bff, 0xfbbbbfc0, 0x87f1dd6d, 0x5df0be50, 0xa3baddf7,
-       0xdef67fd3, 0x909f105b, 0x5e3a4bf1, 0x1c2cfdfc, 0x94777017, 0x323f3f79,
-       0x9189f248, 0xe4fdf483, 0xccd6fd23, 0x0ffc042f, 0x9d552bf5, 0xbcf3c85f,
-       0xdf98ad24, 0x8af9c6af, 0x37f35bfb, 0x8847f94a, 0x87abc4e2, 0xe36f8fc2,
-       0x7ad7cbfb, 0x4a6ddb05, 0xde3f151b, 0x75f12af9, 0x9fb30fad, 0x0772cdcf,
-       0x26c83bbf, 0x46576a4d, 0x5da5f6ed, 0xc2facef9, 0x60eef948, 0x0beafbe8,
-       0x2f19bd75, 0x86df606a, 0x19eebdfa, 0x3cb1fba4, 0x9cf2c3c2, 0xa150d71e,
-       0x37a0e9d7, 0x0e6f7cbf, 0x31f6327a, 0x671f1ca5, 0x3f0dcdc0, 0x3cce90d4,
-       0x073c37c1, 0xb58379e7, 0x0ec5f8cb, 0xab7e1af8, 0x61ecbf0e, 0x1a1127be,
-       0x77ce718f, 0x3f2bba20, 0xeb1fe198, 0xf8741f6e, 0xefc3bec7, 0x89691ed6,
-       0x69f1dfc6, 0x67df26df, 0xfd5bf4e9, 0x22cbb865, 0xf03153fd, 0xfdeab53f,
-       0x5d798d89, 0x96d50fdd, 0x9438e4ef, 0x73b68b66, 0x2cefad10, 0x7b778ff5,
-       0x9fdc89ef, 0x26117788, 0x2ba976ea, 0xcdcbadd7, 0x8fe914a3, 0xef8ca9f6,
-       0x5ef209f6, 0x8151f13d, 0x4fc4677d, 0x0481114c, 0x4a1f86a4, 0xe1923d5b,
-       0x4aa1f86f, 0x9e792302, 0xda17ea33, 0xeb68e4f0, 0x851577a3, 0x53fd3bbb,
-       0x5c647dad, 0xaa7e7754, 0xb9f39769, 0xaf97e9bf, 0x183e7ee1, 0xb6e52694,
-       0x036efb86, 0x2ad80d9d, 0xab67586c, 0x4bbfebad, 0xabf3a851, 0x3d9ae812,
-       0x96ade282, 0x962fbc2b, 0xbf88c22a, 0xe46f3e62, 0xf9ea352f, 0x7dbf9922,
-       0xeab7cca5, 0xd16da7ef, 0x275820ed, 0x7a07ac52, 0x4edd36f9, 0xc5207582,
-       0x7c1df03a, 0x35f0790d, 0x90d7c1e4, 0x0a435f07, 0xa5ef86be, 0x761538a2,
-       0x0ad3f85b, 0xfc07f683, 0x72418569, 0xc169fc13, 0x82d3f879, 0x169fc3eb,
-       0x5a7f0e5c, 0x69fc3970, 0xd3f879c1, 0x9fc3eb82, 0x3f879c16, 0xfc3eb82d,
-       0xf879c169, 0xc3eb82d3, 0x0e5c169f, 0x39705a7f, 0x79c169fc, 0xeb82d3f8,
-       0x5c169fc3, 0x62996f3e, 0xd3cdb7f2, 0x5b287fdf, 0x51f4cf1f, 0x9b1c5198,
-       0xeffdf847, 0xc4fc7f88, 0x373c0e96, 0x2edd022f, 0x48f70ead, 0x904e373c,
-       0x8908b778, 0x8cd9b6e7, 0x32ecbbe7, 0xb4e3245f, 0x7e07e943, 0xf49b42ab,
-       0xdf85215b, 0x56fc290a, 0x2ab7e148, 0x2b7e94cc, 0xe15bf0a4, 0x4856fc3b,
-       0x0a42b7e1, 0xf85215bf, 0x6fc290ad, 0x2b7e1485, 0x0adf83b4, 0xf856fc29,
-       0x5215bf0e, 0xfdf0adf8, 0xfe03cd08, 0x905e632b, 0xf499fbf3, 0x9343a252,
-       0xe532ea5e, 0xd707e721, 0x5c1f9c87, 0xb83f390e, 0x707e721c, 0x707e721e,
-       0xc1f9c87d, 0xdc8349f9, 0xef20bfbc, 0xbc83b707, 0xd41f9c1f, 0xb6037be8,
-       0x2e1b49ab, 0x35b48ebc, 0x7142794a, 0x2f353109, 0x8bfc2673, 0x35254ead,
-       0x6d8423d6, 0x859980f9, 0x38f4d794, 0x66d13cc7, 0xae39be01, 0x05a6f080,
-       0x0f65c704, 0x5cc97ffa, 0xf9b3f86e, 0xbf9ef087, 0x50deb043, 0x35afdfa3,
-       0x4b847bda, 0xefd46a45, 0x2f5d77cc, 0x1ea37c74, 0x79a0cbf3, 0x8f996290,
-       0xbbfc9378, 0xaf700b22, 0x91458b60, 0x642bb8f1, 0x5d28743c, 0xe793caad,
-       0xf6cb16fb, 0x5388e1fd, 0xb83c5129, 0x156591ef, 0x80056c87, 0x7e0292d3,
-       0x562f2af7, 0xab92d75f, 0xcc658711, 0x124bb0db, 0x867be09f, 0xbd84daa3,
-       0xfd19c69c, 0xefe3b085, 0x4bb44c73, 0xa0ed0279, 0x29f40e6f, 0xf4414dde,
-       0x9e4f2cbd, 0xb6ef9a7b, 0xfbe9cbab, 0xae4b6dc0, 0x89c5fdc6, 0xd3ddb2e1,
-       0x386689bf, 0xf8506e4e, 0x6da8ce9e, 0xc9fb8bc2, 0x3a7e75cb, 0x5ecb9b70,
-       0xf8bae3ce, 0x6fd1a3de, 0xbe5486c9, 0x5a2259a7, 0x450f710b, 0x3df8550c,
-       0xb46e037c, 0xbeb1d7be, 0xb02ada2c, 0xfbe0ff2f, 0x7e2e244f, 0xa34ffb9f,
-       0x2116c687, 0xcb3450ae, 0x0d2742f7, 0x83d9592d, 0xe5f9a5e6, 0xbfa3a17b,
-       0xe706f258, 0x85ef929f, 0xe70cf932, 0x9879f1f9, 0xfdf853ed, 0x8dbec995,
-       0xee370496, 0x25b72f65, 0xe136fea2, 0xf5055881, 0x8d8af708, 0x168ae575,
-       0xbd01538b, 0x41f10388, 0x639c47f4, 0xdf25e83a, 0x59f7e363, 0x365d58a6,
-       0xce431bf0, 0xb1c97129, 0x3151d48b, 0x4432cf7c, 0xd0d4b84e, 0x7e62e383,
-       0x3b4e9c78, 0xba5fe7df, 0x8572c9d3, 0xbe615eb6, 0xc65f3e79, 0xf6dd56bb,
-       0x7a4b70e1, 0x99ce9c67, 0xbc16ff34, 0x7d267b03, 0x8508f47b, 0x79bd88e5,
-       0x0da3d704, 0xcd3df12f, 0xf06f9592, 0x0d4b943d, 0xfbcb450f, 0x52ffd26c,
-       0xb0cdc3ae, 0xf1d7cd3b, 0x69c7ae53, 0xef93ab1d, 0xcc39d33a, 0x6a5caeef,
-       0x119cb1b0, 0xf21a2f2a, 0x911ef1a7, 0xc23fae10, 0x60d153ce, 0x0bc03be3,
-       0x4aac94d7, 0x91ca5712, 0x7339758b, 0xe38d8351, 0xf7f42ab2, 0x6eff42d4,
-       0x1e3d62cf, 0xf356f16b, 0x42f24ff7, 0x7de350e4, 0xc94ebd4d, 0xb06607db,
-       0xc6c4b43c, 0xcb39cdfe, 0xb6247ca5, 0x93ee3f0b, 0xce3e59cc, 0xe666f782,
-       0x947af4ec, 0x5de9e82e, 0xd89a4e5d, 0x4ff864ea, 0xfcc11cb9, 0x14e5ea65,
-       0x397cdfce, 0x9799d399, 0xee2adc65, 0x5a6e8122, 0x073be48b, 0xd1f2ebef,
-       0xc6b1c40c, 0xc9eb3e43, 0xf44eddf4, 0x74f2218d, 0xabc035be, 0x3878801c,
-       0x44ada6d1, 0x8dc4ec9c, 0x4d83ef82, 0xfd451c82, 0x155c82cf, 0x5691fd8f,
-       0x2661f7c4, 0x68bf7c28, 0xf4dbd0d2, 0x43fb40fd, 0xf7e13f30, 0x29c2b457,
-       0xcd39c47e, 0x805bb6d2, 0x685f637f, 0x5efca3be, 0x629f24ea, 0x9a923bc7,
-       0x741b6fae, 0xe63fba1f, 0xb276e846, 0xeb076948, 0xb26193b0, 0xb7c92478,
-       0xd3e4266a, 0xf66db0b9, 0x608109d2, 0xcb2b951f, 0xd576fc7b, 0x419206cc,
-       0xc9fb55ff, 0xde458b1c, 0x9039233f, 0x96880bef, 0x2f949ea2, 0x4014a359,
-       0xf5e6323f, 0x38ec67b9, 0x3a4eb0cf, 0xa7d8ed28, 0xd2e51ef2, 0x7e4d327b,
-       0x8cb4d09b, 0x34fd8de0, 0x27f5a637, 0xf468610a, 0x1c2de160, 0x85ebf781,
-       0x005428f1, 0xe8b798f1, 0x3bc1eaf9, 0x973ab4ff, 0x91f9c4e1, 0xa6687dbf,
-       0xe05ff22f, 0x6b147393, 0x4b1bdff0, 0x0d5768b2, 0x50f7c1ee, 0x11bf03c7,
-       0x9efc6db9, 0x4bb64a44, 0x7b10a9f2, 0x8960f54b, 0x4bbb50c7, 0x773cae59,
-       0x7a9dd584, 0xdc7bfb2b, 0xd634b76c, 0xbe66cc7d, 0xf3a46be7, 0x5ee7eb07,
-       0x9ee7bfdd, 0xf916c3ca, 0x1663c2fe, 0x8857f6ff, 0xd0f72f5e, 0x8fbd6066,
-       0xe79ede21, 0x8cfaf1af, 0xf83a4cf7, 0x896efe95, 0x96474f41, 0x2afbe25d,
-       0xb77691a5, 0xe54f441a, 0x0fbe15ab, 0xde4cba5a, 0x2b56d6e7, 0x6e845df2,
-       0x99bf58ec, 0x9efcbffd, 0x117e6fd5, 0xf8750b2e, 0xbcb7b1ce, 0x84eb48e1,
-       0x3d979fef, 0x347c9360, 0x0efb8990, 0xf2712cb7, 0x7b9fd9bb, 0x0f06ab8a,
-       0x8c3c9e03, 0xe5d871a7, 0x8c4b7f54, 0x4bdf04b6, 0xd841cb45, 0xfcfee71d,
-       0xba8f7e6d, 0xdf8d39b6, 0x95d92cbf, 0xd9ef0abf, 0x7ed1ee7c, 0x4497f582,
-       0x4790ecba, 0xf9621a6a, 0x53db9e7c, 0xda2bcfbf, 0xe067cfd8, 0xd2c1bee7,
-       0xbe7d778e, 0xaea2e71c, 0x6cc01157, 0xbaf54c53, 0xf61a63b6, 0x4b3b50d1,
-       0xdf21bbe8, 0xdd815765, 0x5f641ec4, 0xb632ec35, 0x71b3639c, 0x77b1cfae,
-       0xf73ef7fd, 0xf437f3ea, 0x7a1df9da, 0x9ef8ee6d, 0x2ad7ff90, 0xcbd3d82e,
-       0x7133dd23, 0x90fca1bf, 0x62b4910d, 0xbe5b9c62, 0x7c8f731f, 0x8ef4a63f,
-       0x7367e67c, 0xdc029380, 0xfbc9193b, 0xe94fdcb8, 0xfbf7ee90, 0xf40f6bad,
-       0x0a7a0dd9, 0x821df978, 0x1ed79772, 0x951f2417, 0x77a62a35, 0x0bfc8c24,
-       0x97c95583, 0xfc00dd48, 0x9a477c7e, 0xcd396f1d, 0xf1093121, 0x27417b99,
-       0x51db3ac3, 0x993f8e3d, 0xca0e2e98, 0xfe14bdf7, 0x2f18e4bb, 0x955beff8,
-       0xc3df9a36, 0xdf2cfaa0, 0xc51c1aed, 0x68b895fd, 0x5d4869dd, 0x03824f3c,
-       0x3eeda9c3, 0xe3cdcfea, 0x02ca3e30, 0x07ec1b7e, 0x42f71073, 0x7e5c5bf9,
-       0x6d29c61b, 0x68d4ef90, 0xda38e46b, 0x20fb58ea, 0x975607c8, 0x5cb04fbd,
-       0xbddf20d8, 0xddffa39e, 0xcb2f9a11, 0x2704e5cd, 0xee33b3dc, 0xabc286dd,
-       0x797f9f44, 0xce59ac63, 0x036b5c6c, 0xf377667e, 0xdd39c65e, 0x30da5d0e,
-       0x2837df86, 0xbef97ab7, 0xfbc3a68a, 0xf79cdbb3, 0x7b325fc2, 0x34b623dd,
-       0xb065ffca, 0xe9cf6b94, 0x7a6271fb, 0xa9df9320, 0xf1c9cdba, 0x8d5db3e3,
-       0x780edebc, 0x81f0443f, 0x662ae2dc, 0xf89d1378, 0xbe596f10, 0xcedf8cce,
-       0x77c944f9, 0xf095d7fc, 0xd5605bfe, 0x79e0aeec, 0x8997dfac, 0xb4d9a1f8,
-       0x970ef1ef, 0x1f7c6970, 0x3343c4f6, 0x6205eff9, 0xe6cf1c9e, 0xbbc78f71,
-       0x4c374453, 0x18fd06d7, 0xf18df3f7, 0xb4ab1eac, 0x6bbe7bc7, 0x420f7a9f,
-       0x7c27af4e, 0xddd00fc3, 0x02e3b53e, 0x2f6b8d26, 0x5e07ef97, 0xfdf4efc1,
-       0x6a01fffa, 0x00d36c91, 0x0000d36c, 0x00088b1f, 0x00000000, 0x7dedff00,
-       0x65555c7b, 0xd6bbf0ba, 0xc0d857da, 0x51b08b66, 0x62020dc0, 0x10106d11,
-       0x80a17515, 0x636a735b, 0x8dc42937, 0x910150b7, 0xf39fa8ac, 0xa96f0db1,
-       0x962a2695, 0x8da6b675, 0xb2707595, 0xd99b1b46, 0x0f5d9a6a, 0x39d38d3a,
-       0x32cdb653, 0x34d209bb, 0x99d37d9f, 0xde79e7be, 0x0daf60b5, 0xf9a675a4,
-       0x3efcefce, 0x7df5e3fc, 0xee7d7bd7, 0x765ef3cf, 0xb24c6322, 0x98783631,
-       0x8c81b183, 0x45931819, 0x77a13fc8, 0x6302edfb, 0xbeac7195, 0x28d2132d,
-       0x0b6bff56, 0xdfe3df63, 0xa2749ef8, 0x8f2c6453, 0x5da0dbb1, 0x10af7c1b,
-       0xd6ccabd9, 0x29d33df3, 0x148af7d0, 0xd41dd336, 0x7ec3fb1e, 0x13efd5e3,
-       0x338b69fc, 0xe3abea7b, 0xbb78d856, 0x9a7ed0a9, 0xdd8beb05, 0x3ea81bf5,
-       0x26e9b3cf, 0x3632c591, 0x87ff04db, 0x7b4894a5, 0x32e6c456, 0x7057b0d6,
-       0xe1a8a11a, 0x18b18941, 0xf08b9f48, 0xbec664b1, 0x3bcdf868, 0xcfbd40b7,
-       0x64af6f37, 0x35e67b43, 0x398a3fc7, 0xf7363046, 0x0c733652, 0xa5de6c60,
-       0x0f569431, 0x073864f3, 0xf8dbd506, 0xc607ba5c, 0xfb2dadbf, 0x5a307fdc,
-       0x30e59fb7, 0xbf73fef6, 0xe868e3fd, 0xde9f3197, 0x3acf4d7d, 0xa13ead66,
-       0xc304b2af, 0x4d73af8d, 0x83155746, 0x18b6ce79, 0xcd14121c, 0x64c55e5e,
-       0x33b32798, 0x13e41a67, 0x422bcc75, 0x16fd6cbf, 0xf3eb04d9, 0xb557fe30,
-       0x5da9905c, 0x824fbe63, 0x7a860cf5, 0xdf5e1cc6, 0x58f7f00c, 0x4884670c,
-       0x912de8a8, 0xcdbc1903, 0xf83d29f7, 0x21a90c1d, 0x89ef07a7, 0x5ecc1d0a,
-       0x7b6d0657, 0x330305f0, 0x65eb0f96, 0xfceaae1c, 0xbff32aa7, 0xfb20bd6d,
-       0x4e0ddea0, 0x2757cf07, 0x7ac1e61b, 0x364face7, 0x5cb486cc, 0x473e5ef9,
-       0x2f8dde5b, 0xccaf8aab, 0x4f587695, 0x57c71b57, 0xe13d3ad7, 0x2f4f6bab,
-       0xa931257c, 0x00771e67, 0x8e00d8be, 0xe382362f, 0x57c0530b, 0xa82f33a5,
-       0x7c70bfde, 0xedfe7ecd, 0xd0765e0f, 0xceffa8fa, 0x1dbe8d07, 0xb6acffd0,
-       0xf2b784bd, 0xc9f41bd5, 0x99ceaf50, 0xdb51704c, 0xb6cfaecf, 0x6de78032,
-       0x1debb7ab, 0xe8eefc16, 0x9521ee93, 0x413f1059, 0x6790099e, 0x3bbc40ba,
-       0x397ea7a2, 0x9c617ba4, 0x91cd8b25, 0x719edaec, 0x3cf428b6, 0x86da3ebb,
-       0xafaecde3, 0x7165887a, 0xf66777fa, 0x66b3bfe6, 0xa0b317ce, 0xb3cfe43f,
-       0xe424ce45, 0xd4510a8b, 0x3e9a9bf0, 0x79837884, 0x35e0063d, 0xdbc3fe23,
-       0x0c38469e, 0x6ce6145e, 0xa9a94f86, 0x8b8e1f01, 0x36f38cf4, 0x826bcc88,
-       0x8135a97a, 0x548f388b, 0x876c28a0, 0x528d8469, 0x1df90b16, 0x4802ed30,
-       0xee9e2453, 0xc3f5f273, 0x677e3f77, 0x5c3c8131, 0xa1cf4abf, 0x3b606af4,
-       0xfe00a757, 0xd9cc310d, 0x4fa1e8ec, 0x3e951fb5, 0x6fedfa55, 0x70ae7b7d,
-       0x3993677d, 0x3386593c, 0x56e304c9, 0xb9cc3c3e, 0x3afcb846, 0x0f00610d,
-       0x817ad05b, 0x7d6c0b58, 0x903537ac, 0x0fcd7657, 0x24a5b7ad, 0x86f58fb6,
-       0x93e553ae, 0xc3ce2639, 0x015127c0, 0xfad77798, 0xf10c51a1, 0xca2f302d,
-       0xcd8bb39d, 0x5d5bce22, 0x504d53d7, 0xbbb6e619, 0x33e944c9, 0xc368c04d,
-       0x764d3e00, 0xe4df3fca, 0x29adb4a0, 0x9ddbca83, 0x633f9a36, 0x80698881,
-       0x85308aa7, 0x8f3cfdff, 0xe54165e5, 0xee9c6d53, 0x11035b4e, 0xfd3920b6,
-       0x0d79bd71, 0x0efa428b, 0xccfc883c, 0x5db2871a, 0xf5e9d430, 0x4cc42367,
-       0x3f3e4fa4, 0x7d12ddb5, 0x163fc927, 0x02ec7061, 0x24b19b96, 0xe02374fb,
-       0x38f2ee6b, 0x9b129027, 0xe49438d1, 0xb46f0cc2, 0x7eb00093, 0xcc78430b,
-       0xf860e453, 0x2395aa92, 0xb26b7eb1, 0xe6718055, 0x5ae79c5a, 0xced5fda9,
-       0x4b7bf1fb, 0x93252199, 0x9026caaa, 0x72287763, 0xdcc0896c, 0xa07787c8,
-       0x12fe449c, 0xfea2a50f, 0xf055a3b9, 0x56cf291b, 0x21d7000b, 0x78d2eecd,
-       0x055b1394, 0xbb6c0ee7, 0xa9a9e40d, 0x0d769e47, 0x7a817f73, 0xf4077d81,
-       0x255ffd07, 0x5d710220, 0xca1c726d, 0x75824df1, 0xb979c317, 0x059f080d,
-       0x6e9c9d0a, 0xc8e11339, 0xa3eb81ec, 0x65105ff8, 0x288b23cc, 0x3d141b6f,
-       0x79406486, 0x310e4e45, 0xca41f870, 0x3a3f11da, 0xa0e909a7, 0xc51292cb,
-       0x886f28fa, 0xf2c38948, 0xc912ad39, 0xaa9e9545, 0x7c2835d5, 0xa3be1733,
-       0x2a912bde, 0x56be9162, 0x74a44cb6, 0xcd9286ce, 0x24e3a05e, 0x9a3b1dc1,
-       0xb867a3d6, 0x13b5399e, 0x55bc47af, 0x9b4630ef, 0x7a496f00, 0x104e526f,
-       0xbed9ce3f, 0xbb41892a, 0xd3cddbf3, 0x5b17fe51, 0xa1a38acb, 0xd16dbcfd,
-       0x1e9052d9, 0x7ae6ca49, 0xc4ed4164, 0xacf00638, 0x2791fbf9, 0xe78fa0ac,
-       0xe8569f42, 0x70b69bff, 0xd4aa179f, 0x924fed34, 0x31dee780, 0xa1b3e279,
-       0xe0f142fe, 0x1f50a32d, 0xe2a7be08, 0xce23bea9, 0x503c87da, 0x0fc073d3,
-       0xdaf7a00e, 0xf51ef5ff, 0xd6f895f3, 0xbed0e5f5, 0x4885f6a6, 0xa6e167ec,
-       0xa15be43f, 0x49e8a0fc, 0x173ffec3, 0x45653fb6, 0x9edd6c02, 0xee7c7a85,
-       0x4f28b4a6, 0xf917f21f, 0xbd51f100, 0xaaf8205f, 0x517c33e5, 0xc7bb8406,
-       0x4c560ccf, 0xf480ccad, 0x8d625e7e, 0xf6a80f68, 0x323e5a8c, 0xf3adcb9b,
-       0x9093eb51, 0xb53fe64e, 0xccf50925, 0x5f3c1167, 0x6fadd4f1, 0xecf2dca0,
-       0xaf101a34, 0x38331d1e, 0x41799f51, 0x551d22bf, 0x93c6ff03, 0x04ae61dd,
-       0x0eca2a7a, 0x6fceb827, 0x51fa411d, 0xa77c179d, 0xcc74cff2, 0xd218f385,
-       0x748d99dc, 0x7f9d67ff, 0xcff3e22e, 0x17a766f5, 0xf5cd99f1, 0x4bd79fdb,
-       0x05ee58a5, 0xe47b4186, 0x885febcf, 0xd8f4b548, 0xfbd2256f, 0xd67684b2,
-       0xea36428b, 0x76ccf0ed, 0x1bb22cc3, 0x9d59d118, 0xc359d395, 0xe0e97d01,
-       0xa8c7b218, 0x37e746a4, 0x05af85f4, 0x9dd5bd8a, 0x80d7b7df, 0x87b3527c,
-       0x6d3511db, 0x508ec867, 0x855a92ed, 0x39ee179f, 0xda857643, 0x871f6eae,
-       0x5e3eed4b, 0xc801955e, 0x80e5cd1d, 0x0aba4200, 0xfbf905f1, 0xd3d7f5fe,
-       0x7bf26997, 0xb5df7f29, 0x750f2e56, 0xb7a8499d, 0x349c64d6, 0x976bfe20,
-       0x5e42fd2b, 0xbcde341f, 0x2f0481ec, 0xc16a1f2c, 0xfd8d0ef6, 0x9a2fbb50,
-       0xc36bfbda, 0x97bea356, 0x4c3a2ceb, 0xa42d6b9b, 0x8bd5b7ff, 0x9c5cba19,
-       0xed13985c, 0x916183b9, 0x07472859, 0x06653c2e, 0x3b6a0248, 0xbe50888f,
-       0x2f73ca3a, 0x031c67d2, 0x6f5090ae, 0x5fb405f8, 0x74f95e3b, 0x6e3ff604,
-       0x066be048, 0xbf0bd753, 0xf20c5e9b, 0x2d981964, 0x06671f64, 0x0f1d2046,
-       0xf4e5cc3c, 0x1ab67ae3, 0xb9d31bf5, 0xf72834d9, 0x3c42dca3, 0xdbe61b7f,
-       0x1dffff05, 0xfec60ff3, 0x143fc999, 0xd0a4bddb, 0x5968dba7, 0xaebcc02d,
-       0x8359ea1e, 0xd041be4b, 0x222d935f, 0xac34a40e, 0xdfe7a1d7, 0x82757b55,
-       0xc113a722, 0xc8bb408e, 0x416ec830, 0xf3366e3a, 0xccb209f5, 0xf71e611a,
-       0x8d9e1e67, 0xa76d7a7a, 0x9d611989, 0xc8c33a13, 0xe41c4d7e, 0x6cd6bd22,
-       0x2dbd224e, 0x02ac7438, 0x14ce1fea, 0xcfac3afd, 0xcfac3e4c, 0xae76214c,
-       0x9db19668, 0x6fb5f070, 0x960fbe51, 0x82891e2e, 0x47be0df5, 0x9d433670,
-       0x8f73aeca, 0x15a41bff, 0xfdec7697, 0x2dff4857, 0xe113b3ca, 0x75cbba7a,
-       0x5ba803c6, 0x39336d6b, 0xc160deb9, 0xef7838eb, 0xb13691b7, 0x9d1d7e67,
-       0x4dfb9ee7, 0x2726a62e, 0x07099fea, 0xa11fd225, 0xc3b0e9f3, 0x3d5287c4,
-       0x2c3b3bb2, 0xb0104fa2, 0x70f791fe, 0x164c137e, 0xbaf684bf, 0xb065ff49,
-       0xc48e617e, 0x935773e8, 0x83df614a, 0x938b1091, 0xd1747d47, 0x38eb7642,
-       0x3a550f85, 0xdb9b2b7b, 0x72296f8f, 0x73338555, 0xaf582cc8, 0xd66cf0a8,
-       0x1022faab, 0xf87b32ce, 0xaf529176, 0x932892eb, 0xf46d5e1d, 0xebb2e831,
-       0x33d250e0, 0x3fd9c9fd, 0xf601dda0, 0xf954f2c4, 0x5327845d, 0x0acdeef4,
-       0x2dfd54fc, 0xacdffd29, 0x8b66f1c0, 0x5376e1c8, 0x7a14dc08, 0x1e97a50a,
-       0xdb41887a, 0xeccf1ba3, 0x51a3f6be, 0x6bdf84c9, 0xfd78e61e, 0xedfaf090,
-       0xcd802b5b, 0x4dbfa0d8, 0x0cfefc21, 0xb98bf578, 0xedaf023f, 0x9bf578a1,
-       0x375e2187, 0xa0676489, 0xa376881d, 0xb5c0e507, 0x60f6e794, 0x51392306,
-       0xd7398529, 0x8077e324, 0x87c91643, 0x541f28a3, 0x15c430b9, 0xe9f506b8,
-       0x71e57069, 0x8db1017e, 0x10a4e797, 0xf6b0245d, 0xbc072c78, 0x277da1e7,
-       0x7e668699, 0xe5b7720c, 0xdfdedf01, 0x82cd3f40, 0x983ceb6f, 0x8b66f78f,
-       0x0eb7ed13, 0xc3d5e89f, 0x59a25a3c, 0xbf187ed6, 0x4e55fe65, 0x4533962f,
-       0xf8374c6e, 0xef837ed0, 0xbdf88d49, 0xe97f7f9c, 0x441f67ef, 0x8d33acfb,
-       0xb25abad1, 0x67da3a59, 0xf419652d, 0xdcaab7fd, 0xb7823079, 0xddf4e32f,
-       0x43e6df32, 0xa3e8f43d, 0x27a8e1be, 0xf1cbb65a, 0x510d4836, 0x981cf89e,
-       0xd38920ff, 0x94324b7d, 0x7059ba43, 0x7ec5cf97, 0x0df3e1ae, 0xff3d8794,
-       0x4e657414, 0xe506d105, 0x76231ba7, 0xe9555ca0, 0x2e30f074, 0xcf7887df,
-       0x7938456c, 0x7a8cb027, 0x8543ffe8, 0x0bf854de, 0x008d36c0, 0x3c1098f7,
-       0xa31774a8, 0xca585fc0, 0x413bcfe9, 0xf31d4f59, 0x0091bfa1, 0x38070953,
-       0xf0c11a57, 0xd5967483, 0x6ff38d93, 0x91f80c5e, 0x0f1c1d70, 0xdd5645a7,
-       0x155f07d6, 0x0df128e6, 0xa6f90218, 0xa9be7192, 0x7a42ba44, 0x0aba046c,
-       0x481647a2, 0xae173e88, 0x83ca15d0, 0x1cb8f708, 0xc257e758, 0xf0b1f21f,
-       0xa694ffad, 0xa4ce35f7, 0x1e2f2e1c, 0x734a7b33, 0xd04def48, 0x656f9dd8,
-       0xfa889a7f, 0xafbdf4e5, 0x149a6025, 0xeb8c9ee5, 0xd7fe5cd8, 0x1fff1452,
-       0xb8f407c6, 0xffcb0f8e, 0x2dda224f, 0x235f4b95, 0x79d2bffa, 0x37989996,
-       0x5d1ee01c, 0x00fd382c, 0x462d79bf, 0x16f824e7, 0x0c755c57, 0x6ad659e1,
-       0x56911874, 0x1c8d62d8, 0x408f2b3b, 0xda1d8a37, 0x39ba246a, 0xf4894bf7,
-       0x8b92b9c1, 0x0f800eaf, 0x4e0856e7, 0x32d657ac, 0x3790256c, 0xa816292b,
-       0xa057995e, 0x1ca9657a, 0x051a275f, 0xaf4037a2, 0xde283b25, 0x8ef5a731,
-       0x13df88a9, 0xa40f5fc5, 0x187ac1f8, 0x2e63e547, 0x959e48de, 0x56abf529,
-       0xbb47911b, 0xacb597bf, 0x3ffc88ba, 0xde521bd3, 0xec53e93a, 0x5b51acb7,
-       0x8235c6ee, 0x4e57771d, 0x07ca0c44, 0xefce64e6, 0x40f24811, 0x93fa0ff2,
-       0x447140bb, 0xc20f30cf, 0x61bc89c3, 0x99eba47a, 0xdba05708, 0xdd7ca5e8,
-       0xbe0aa733, 0x99ceb049, 0x1f67ce16, 0xfbbe0996, 0x09ff3e05, 0x5065ef40,
-       0x5d740b1e, 0x38e4c316, 0xe626dd48, 0x2e79c70f, 0xca09f61d, 0xd438d3db,
-       0x8fefaa28, 0xf75ca1b4, 0xb78911e8, 0xe5a52f32, 0xede947cc, 0x98f34fcc,
-       0x74933ac1, 0xfc93af90, 0xf38e312b, 0x0367b32b, 0x8b5fd7d2, 0xe0169c4e,
-       0x4239ddfb, 0x439428de, 0xdd68038d, 0x701f5b97, 0x067680a5, 0x5fac41aa,
-       0x147ee396, 0x4ccab3fb, 0x74ab718f, 0x995a8e95, 0x17d61537, 0x9be2debb,
-       0x6b8beb04, 0xf5c21cf5, 0x38374fa6, 0x1383ef10, 0x74133af8, 0x543f9fdc,
-       0x81a3606e, 0x183f360e, 0xdb3a43e6, 0xda2035bc, 0x03e6fea1, 0x97cc0180,
-       0xf0bc14af, 0x4e61eadd, 0x7559d38c, 0xfeed111e, 0x188f56a2, 0xe1a7e208,
-       0x394441b2, 0x23d3be91, 0x5ab49ea2, 0x353d53d7, 0x4fd4ac5f, 0x59067937,
-       0x4e9e4ec9, 0xa15c33f4, 0xd49fb51f, 0x045f8356, 0x4ac917b8, 0x57b7997d,
-       0x9e8a61fb, 0x3961db56, 0xab7a67d2, 0x453f4fa3, 0x3f505b4d, 0x08f88f83,
-       0x7bd205c6, 0xfd711fca, 0x1bf084da, 0x36abf378, 0x2103374c, 0x9d1c71f8,
-       0x79e34cc7, 0x15d33cf8, 0xbfbf87da, 0x63e38f7f, 0xb9bbf01e, 0xe422fef5,
-       0x1f00cda3, 0x9de6f3c4, 0xcfd4ccb3, 0x799a59f4, 0xf286a931, 0x4b070825,
-       0xa23c75ef, 0xd53d2fcc, 0xbd695a23, 0xe76843ce, 0xe28ccba5, 0x763f6a01,
-       0xf405741d, 0x857a776a, 0x90cbcc7a, 0x47b8945a, 0x4eb38e3a, 0x5d31ff40,
-       0x6b4957c1, 0xf63361fd, 0x5f1466e3, 0xfe85cf4c, 0x8426fea1, 0xfc37a183,
-       0x5e99e742, 0x4273e7cc, 0xf18edfa9, 0xe76c7494, 0x74431158, 0xd5d7e7c5,
-       0x1c6214ea, 0xa08fb197, 0x7e90c9fd, 0x0cb8c29e, 0x7e4ecfa4, 0xb42e4a6d,
-       0x97d1fe7f, 0x52d0b476, 0x0fb33e0e, 0xf5ab56e5, 0x9c709be6, 0xff9f2283,
-       0x5de2724d, 0x206ddf98, 0x53be9a3d, 0x7944db4e, 0xebfd1393, 0x55df56ae,
-       0x2cbd422f, 0xeb64c618, 0x0a138f3d, 0x3a15da9c, 0xcb793938, 0x53ef5c20,
-       0x582c7745, 0x5f87ed02, 0x3b8d38f7, 0x94fcca7c, 0x9b0fc816, 0x30abcbf8,
-       0xc78e5f7f, 0xfee4023c, 0xde5fd2b0, 0x6ae50fb6, 0x821cfce9, 0x4576c597,
-       0xda39a9f2, 0xbf02f5e3, 0x52dc4737, 0xd2b8fc8e, 0x24487066, 0xfa19eb77,
-       0x7711cd59, 0xe5bfb1db, 0x4c26f9d1, 0x36bfd60d, 0x6e3c9ca1, 0x1e2131c9,
-       0x18132d9a, 0x0aaceb96, 0x4f1bbe9e, 0x885240fa, 0x73847772, 0xe5744cba,
-       0x0c272864, 0xbcad0609, 0x2f7971d6, 0xb43e1dd9, 0xf5acba9f, 0x60cc8148,
-       0x7ca05409, 0x69795493, 0x3c717a71, 0xa3b4e2c9, 0x9142b4bf, 0xaf862c37,
-       0xf73960d3, 0x5eaf389f, 0x962e63fd, 0x867f4b50, 0x4128ccb0, 0x9bda3ff9,
-       0x573e10c6, 0xbbc58353, 0x6844f518, 0x70205d7f, 0x4fa38e50, 0x7e337647,
-       0x5eddee48, 0x7a341bb2, 0x7a5e5ba4, 0xf221f5a2, 0x7a811e52, 0x792058a2,
-       0x0ceb61e9, 0x0c12feb8, 0x3c5c00b2, 0x545eb8db, 0xce267bf9, 0x49e5f005,
-       0x5e5c9165, 0x2673e4e9, 0xd1efc60e, 0x452a5cae, 0x5e021e22, 0xc3e9e0c9,
-       0x9378f79f, 0x9d1e507f, 0xa987fa41, 0x21fe9007, 0x0fe144fd, 0x6f078a8f,
-       0x50a3f5d9, 0xd912cb5f, 0x85cb9503, 0xe2cfb436, 0x6947d1bc, 0x2edcc5be,
-       0xa6bf9768, 0x892a1cf5, 0x7979444b, 0xc799d962, 0xbebd41ef, 0xfff49c29,
-       0x5667a5a4, 0xa66e3c60, 0x211a7057, 0x7d1a59ef, 0x6f987bf7, 0x905d3a34,
-       0x81f0ab3f, 0x914597fb, 0xb8084f68, 0x759e8cce, 0x83321656, 0xf139e29b,
-       0x3b409633, 0x34e0a34f, 0xa1e07a3b, 0xef527ac7, 0x37bc05f5, 0xfad0fe46,
-       0xa8d7bc3f, 0x3e7759c8, 0xc6a2d9ca, 0x700a87e4, 0x7cf5eb5d, 0xd7d18d9e,
-       0x3927de53, 0x1cb97639, 0x3fd8a99e, 0x57b3a59e, 0xc0f7c3c6, 0xcef9416a,
-       0xc8a956f1, 0x88e340e5, 0x0d3f1863, 0x3e48172c, 0xa252bc79, 0x5ccdda1f,
-       0xef784d9e, 0x5d900a28, 0xb43de5d8, 0x722b5a92, 0x3674a3de, 0x94588c17,
-       0xe3dfa76f, 0xfe479ffe, 0x9bb62563, 0x83b5a2d3, 0x0cfd0226, 0x67bcb840,
-       0xf1e9fd26, 0xefbad196, 0xea6945f0, 0xd38ead55, 0x8bab3de4, 0xe7b0c7ae,
-       0x52277bac, 0x3992af3c, 0x2ade9122, 0xc1376e65, 0xe61b259f, 0x4f9d5733,
-       0x2ac7b731, 0xa27ec18b, 0xb07b5aef, 0x3389fec7, 0x78a8df20, 0x3a13f154,
-       0x19765eef, 0xacd076e3, 0xdd7ada75, 0x16301076, 0xe5caba8a, 0x32bf76da,
-       0xb9459fbb, 0xe038dee8, 0xaeabf21b, 0x80821e50, 0x266e7f21, 0xa61f71e3,
-       0xced543e8, 0x517a592f, 0x6668728f, 0xc23d45e3, 0x1fd2e673, 0x385fa7e6,
-       0xa1bef3b5, 0x3ebb4a20, 0xbf934e39, 0x534435d1, 0x30f766ff, 0xa75bf7cd,
-       0x5ef9ab5f, 0xc9a919ee, 0x5e3d5edf, 0xfd467f53, 0x7a1cad24, 0xa3d69a37,
-       0x79bfa7e2, 0xa3e8a5bf, 0x12ec4277, 0xe23a9d35, 0xbf91133f, 0xe4672c3f,
-       0x33787cbf, 0x1d31f8d3, 0xe7822423, 0xf93d5c80, 0xc8e5f731, 0xbf208fef,
-       0xa1f44fc9, 0x7343f3c2, 0xa228c9a1, 0x7ee4627f, 0x725fa879, 0x5e503990,
-       0xfdb1d4ce, 0xff8f5442, 0x9cf30e67, 0xe3bafec7, 0xf10f4b0d, 0x1f884378,
-       0xff78a573, 0xbfcc0670, 0x4d79790f, 0x16c3f72e, 0xffaf36ee, 0xb58e0838,
-       0xfc9ad16d, 0xebf1fda2, 0x3bd60e3f, 0xae1d044b, 0x93e146b3, 0x7da0165a,
-       0xa0e8bb52, 0x40c4eafe, 0x583be62c, 0xf4b46c67, 0x0a8b838f, 0x258f800f,
-       0xa9de2837, 0x193fc3fa, 0x9e0a453e, 0x1a70b4cb, 0x90e3cb93, 0x29108f5f,
-       0xc7239cdd, 0xf103fee7, 0xf49eb41c, 0xdc7fbcdc, 0xc847227a, 0x9f9f0859,
-       0xe3dfaf1b, 0x17940f1e, 0x7f0b908e, 0xfe4cb826, 0x47a5c247, 0xd82f47cf,
-       0x72a3fa0d, 0xfdfb819d, 0xbf5c33de, 0xfefd7237, 0xf68fb47c, 0x44f39b87,
-       0xed070ee7, 0xe93ed297, 0x618d7ba1, 0x59df1819, 0x797d23a1, 0x8190997a,
-       0x2126c2fe, 0x0f36fc8c, 0xc81648ab, 0xc878b9be, 0xaa31fd48, 0x3afded07,
-       0x0551f390, 0xe4096b3e, 0x71e5ccdf, 0x716e35b1, 0xf5038a4a, 0x1eac1ff6,
-       0xe27a8b8a, 0xfd9e1e11, 0x696be130, 0x2bee45df, 0x6bd0127e, 0x8512d1e5,
-       0xd5cc5f8f, 0x2e1f3ad1, 0x949db914, 0x1f70ba2a, 0xa9d81563, 0x96065768,
-       0x915f28eb, 0x6d59e9c7, 0x9d0a1ff7, 0x14dd94c7, 0xda88f386, 0x7d7dba24,
-       0x2e51fb8c, 0x793d0f8f, 0xb3ed1857, 0x68742a01, 0xd6bddbef, 0xaf582e69,
-       0x8d96d0bd, 0xdcdadfb6, 0x4d6fea68, 0xcf159746, 0x748cfca1, 0xfe8eca78,
-       0x8cfac0a0, 0xe655cd33, 0x580feeab, 0xe936fe94, 0x9da2bf41, 0x1e289822,
-       0xf91af161, 0xb16715f9, 0x1ccade26, 0xa76e0b02, 0xf428f3d6, 0x1b42c76a,
-       0xeff697e1, 0x5db178d5, 0x1ba417a1, 0xcf4abbc4, 0x8983fda1, 0xe9cc8dec,
-       0x15d9f389, 0xe51a8e52, 0x8f748dd9, 0x1f90eafd, 0x07fe5cbc, 0xe3c4be6e,
-       0xded7de2c, 0xe18879c3, 0x0c9c525f, 0x5fce4aec, 0xbee2434b, 0x024f913f,
-       0x40cf0e66, 0xde1e5684, 0xdac9d0ab, 0x48de827f, 0x3ebc02ba, 0x8fe5cb9c,
-       0x36fdc0ab, 0xb2c73bca, 0xfba230d4, 0x96270b1f, 0x51384560, 0x3872ba5e,
-       0x1f3df379, 0xcc749e10, 0x7f71b46f, 0x72e1f90b, 0x31c2a47c, 0xbe9e6449,
-       0x3c88f2f4, 0xca1bfbe5, 0x6ab7ae7e, 0x61d90fc8, 0x02c57728, 0xcc2cd2c6,
-       0xffb6bc61, 0x8f9c0e7a, 0x396ae885, 0x96aee5d2, 0xcfe43094, 0xcabc6564,
-       0x0ca7d29b, 0x205fa077, 0x040ed018, 0xe3c0c3bf, 0x574edc3f, 0xb94f7ae5,
-       0x72c47ed6, 0x1f8f664f, 0xeaf7daa6, 0x82973c77, 0x59f3aae3, 0xfd61d8a5,
-       0x125577cd, 0xdca2724b, 0x808f765a, 0x5ab1dcf0, 0x717df8d4, 0x0325615e,
-       0x7fce3e3f, 0x8efd13af, 0xcdafb038, 0xf575cf28, 0x5e083382, 0x0a817b81,
-       0xf8871338, 0xe24fe02b, 0x8967bd3a, 0x57c7425e, 0x85abb1d7, 0x5de71b8f,
-       0x9f90c82c, 0xa02f5154, 0x9956b7df, 0xa3055c7f, 0x3e9969ef, 0x9e21e301,
-       0xe38a5616, 0x03335655, 0x332af5c6, 0xf2865399, 0x7443c6ca, 0x02b9edde,
-       0x206f2539, 0x4f3a4fc9, 0xa4f02ae3, 0x4d1d01e7, 0x7643284d, 0x864bb867,
-       0x167f89f1, 0x4cb5a71d, 0x59efa2f0, 0x843ce2d4, 0x11d001fe, 0x2d3c7dc5,
-       0xe75f1a01, 0x5d7271e5, 0x80e9c18b, 0x658d4875, 0x5521ffb4, 0xd4329c1b,
-       0xdf29b63b, 0x2d95f18f, 0x0ddfdc8d, 0xd67493f5, 0xd1c3d7fa, 0x9910ab5f,
-       0x790a0144, 0x5659fa2a, 0x30562e85, 0xf7ee3b77, 0x41fe1933, 0xdca548bb,
-       0x2a6f3d5a, 0xd0e52266, 0x13dc8378, 0x6b9e409f, 0xd3b240dc, 0x678daa94,
-       0xc92b2d48, 0x7d6233af, 0x890faca8, 0xa5d54877, 0xac971714, 0xf35bf2da,
-       0x8e086222, 0x9e1e3c59, 0x8d88ef73, 0x727cc2b7, 0x1fe3797f, 0x41873d30,
-       0xfe5b8033, 0x4c073bb2, 0xac16ff87, 0xa62378d8, 0xe8cebc4f, 0xe08fc19c,
-       0xfa8c6657, 0xe8fafcf1, 0xb2abf295, 0xb9d00f26, 0xd27dafc2, 0x094f1abf,
-       0xfe954fe5, 0x4d4ef943, 0x7f865ed7, 0x120526d7, 0xdf4f0f91, 0xdb03323b,
-       0x73de3657, 0x5f88c7c8, 0x77d00705, 0x117177a5, 0x5660ba23, 0x5e5bd097,
-       0x490b3784, 0x1f37bfec, 0x3b7c863f, 0x13e7effe, 0x95df087f, 0x63ce8c09,
-       0xf649fd81, 0xdfaa9a9c, 0x3eb9f223, 0x246790bd, 0xc1464ebc, 0x053bac0a,
-       0xc7bee0da, 0x2b4e6078, 0xf02e7fa4, 0x4de38b3c, 0xef9e3c81, 0x6b40fd7b,
-       0x4b37ae0c, 0xa78ef5c7, 0x76e68edb, 0xa8ffb748, 0x06590fd8, 0xdced0536,
-       0x771126c0, 0xc0e0596e, 0xe2d63be7, 0xc9b96bbe, 0xcaeb0699, 0xf448dfba,
-       0xf68a0484, 0xa7689651, 0xb6aee5b8, 0x9f69cb8f, 0xd2c0d1b1, 0x0ee06e28,
-       0x006473c3, 0x4caab0cf, 0xacc357b2, 0x857aaf68, 0x1e88aaa4, 0x22f5087b,
-       0xef2cb40a, 0x30ac53ad, 0xb042aefe, 0xec7b3347, 0x59fed51c, 0xeb4c9f9c,
-       0x6820ed57, 0x8fddb0c7, 0x0b4aa7e5, 0x19bb224b, 0xf7fb83e6, 0x90264cb6,
-       0xff5213ed, 0xd92332f4, 0x7baf76af, 0x5bb470ca, 0xa0e6a797, 0x9ae30add,
-       0xfd7f6e24, 0xbb67ca3b, 0x285ef94e, 0x49b9e0e6, 0x05801f75, 0x8718d174,
-       0xfeaaed53, 0xe763a5e7, 0x9505b954, 0x9f2f9b7f, 0x59ff7ec1, 0x5563dd72,
-       0x634d4de8, 0xe9e079f8, 0xcf8dbd0a, 0x9e9a5337, 0x73dbb3ff, 0xfe93aea7,
-       0x39feeb79, 0x9ffae1d7, 0xffd88eb1, 0x3cd8f821, 0x3ac67ff9, 0x4ff2996e,
-       0x5f37875c, 0x43cfc86e, 0xe746d679, 0x7e2eec88, 0xdee41c2e, 0xcb9cbc3d,
-       0x09938b39, 0x74ffc764, 0xfd84d779, 0x1c1f419d, 0x7778a1cf, 0x67183a08,
-       0x88a1a588, 0x8ca5cdec, 0x2c8681f6, 0x4340fbe5, 0x224d3a96, 0x6e1603da,
-       0xec520e27, 0xb94b41ce, 0x9ca719dd, 0x118b882b, 0x3fd4327d, 0xca5bcbf6,
-       0xbee0c6e7, 0xd5ec9190, 0xf5dd36e6, 0x5e53d416, 0x868fce89, 0xd2d289da,
-       0x5f9c4a95, 0xf6aa9f6b, 0x79e31a68, 0xb4b3b2fd, 0xa3daa74f, 0xb4f29443,
-       0x603f7ca5, 0x1ed68b48, 0xdad6ab8d, 0x1082fa8f, 0xbaa9733b, 0xeb49d07f,
-       0xe9d72dd3, 0xa87ffcf1, 0xb07b89dd, 0xab0714a8, 0xfeb4067a, 0xf630d74d,
-       0xf9f77e74, 0x1fdc1c8c, 0xd05ab99a, 0xcf5539e8, 0x7e282402, 0x43e3e2a4,
-       0x3f8873d4, 0x5fb534f7, 0xaf3e6fd2, 0x2e4c7048, 0x539cd74f, 0x1e7eec62,
-       0x3a73712f, 0x11eaf5fa, 0xddaed16b, 0x37c6eeb7, 0xfd697d31, 0x04e5e19d,
-       0x6f54f5af, 0xebc6cb7f, 0x7650ff30, 0xe6123dbb, 0x53a8d0f5, 0xefd009ef,
-       0x85e33c6a, 0x2978b3eb, 0x9e14b68f, 0x7ab3d08b, 0xa4dbdfda, 0x0d9f4c0f,
-       0x45122be5, 0x23be911c, 0x1832981d, 0x59309f9d, 0x35f57e78, 0x30e3ee8c,
-       0x1a9f5ce5, 0xd73d0987, 0xc7c3cab7, 0xc4f00559, 0x18963573, 0x39a91f7e,
-       0x08e9fee1, 0x818766ef, 0x8b3939e1, 0x624fee72, 0xa82aaed5, 0xbf7edc77,
-       0x0bee167d, 0x7e881867, 0x26ce98a4, 0x9ed993c4, 0x71c2af63, 0xcd35e242,
-       0x2037e929, 0xfbb5bc59, 0x20679ef0, 0xc9cf7b7d, 0x2a9d312f, 0xf3c3efb5,
-       0x88465225, 0xbf6bd29f, 0x9bdc1198, 0x4a5f3387, 0x6e3b9632, 0x754e9110,
-       0x869a6feb, 0x50c154fe, 0x4f581ae7, 0x1bf30258, 0xbd611e60, 0x7b7989f6,
-       0xce9c20a9, 0xf59648d5, 0xdfd80d15, 0x7fba08a8, 0xae03bec0, 0x4df3a7cb,
-       0x80f657f4, 0x0e3a47a8, 0xc38ff653, 0x1fed7b32, 0x30c2fcd3, 0x3b59e14d,
-       0x7a15c3e4, 0xca7b635f, 0x6b77fb87, 0x106e5213, 0x69f53d1d, 0xbbd6195f,
-       0xab1bbbf2, 0x26fd5f68, 0x9fcf1593, 0xcafb2985, 0xa574e3a1, 0x43675b3a,
-       0x6418b46a, 0x55f11673, 0xe0725f0f, 0xe68353d8, 0x9cfaf501, 0x736e3aa7,
-       0xda83c71e, 0x64c2d19f, 0xf74323b4, 0x81fb43ad, 0x56be7079, 0x31fda9ea,
-       0x01e746d6, 0x518b8874, 0xa7abb57d, 0xe9df0db9, 0xff1fbb24, 0xcc82e382,
-       0x35fc431a, 0xcedb55ac, 0x0dcfca9c, 0x2a18f4a8, 0xfdd0a52f, 0x6f7ad4f7,
-       0x9f81e138, 0x1fad0827, 0xf6d0d70a, 0x5833b7f0, 0xe160ddde, 0xa95d88fb,
-       0xac22b99d, 0x473da57b, 0xbf5a7f33, 0xef7fd3d0, 0xbe6d3cfd, 0xb9f6364c,
-       0x7d07943e, 0x4e8277cd, 0x6c596fbb, 0x8d2fb6d1, 0x25777ed1, 0x4592f368,
-       0x6d91dfe9, 0x8e1af3a2, 0xf79e137c, 0x18d8f953, 0x8af7efe2, 0x2efa2adf,
-       0x1e74c991, 0x79de9375, 0xe3c4e50e, 0x01d24033, 0xf82c3c7d, 0x552e58cc,
-       0x0f515bb4, 0x93d3adc6, 0xaefc7a9c, 0xbde0ce5b, 0x6ba016a0, 0xf771e584,
-       0xc56e9b47, 0xf148b17c, 0x70fb9b0d, 0xcb51d239, 0x37bf5f77, 0x3a9fcf1b,
-       0x5bce740d, 0x75b1b73d, 0x1e2b61ac, 0x94cb8a0b, 0xfdf069cd, 0x84e62aa1,
-       0x6323b099, 0xfc712363, 0x15a2d12d, 0xd1f3ddf5, 0x718efff5, 0x8c19e694,
-       0xe14219f6, 0x46d23757, 0x756e3672, 0x5bf780b6, 0x5f9b1e1e, 0x06317289,
-       0xaf9465fc, 0xc57dca90, 0xf015c717, 0xc5b6c0f8, 0xbe23c52f, 0xdb0f5837,
-       0xa2159e69, 0x52d8a713, 0x8b7fe5c1, 0x7b3ed185, 0x3752a8f3, 0x72ec4d1e,
-       0x8b3c0ec9, 0x41dee2d8, 0x2d595ef3, 0x9cacd972, 0xc8580197, 0xbe9c3951,
-       0xfd4a360c, 0xb3346e98, 0x972839f8, 0x7ce8c292, 0x81f67f50, 0x57cb84b4,
-       0xe9cc6f6c, 0x1143debf, 0x5cc8f18d, 0x9fe467cb, 0x6dfd0b9f, 0xf299b19d,
-       0x538d3caa, 0xdfbbbbe8, 0x1bba3d10, 0x36724bf0, 0x9e2ce41a, 0x878e63c7,
-       0xf575b789, 0x3a20b4c2, 0x7c8055d5, 0x2ee7e2cd, 0xbebb7e30, 0x87e334a8,
-       0x9b9d4cfc, 0x5518e5cb, 0x97ebbb1e, 0xda05dc61, 0x635f51fb, 0x0fce783f,
-       0xb7d71952, 0x443fa851, 0x830cf37e, 0xe839ef03, 0x430e402a, 0x56825d7b,
-       0xc9181c4f, 0xc1fb35f1, 0xa09eccbb, 0x728c4d38, 0xbea3661e, 0xeb069cde,
-       0x744338d9, 0x6c78076e, 0xfa1068a9, 0x55c4c78a, 0x0d997e70, 0xde6fd1f5,
-       0x1b139152, 0x8c669ebc, 0x36d0c073, 0xdb9f0fd7, 0xbfc885d3, 0xbc79235d,
-       0x1cdd67bd, 0x3f4071be, 0x479a87a8, 0x6ae6ae97, 0x557241da, 0x6d6de567,
-       0x073a7aae, 0xcfc155d9, 0xf813ad5d, 0xc4a4827e, 0xf28b9bcb, 0x4bf4bf49,
-       0x492b152f, 0x57e2849f, 0xe5fd3f9d, 0x9911e907, 0x8719f1f1, 0x4cceb49b,
-       0xda07e1fa, 0x4af9743b, 0x1e0bd47d, 0x62ba7f6d, 0xf8e33651, 0xaf105fa8,
-       0x7bc5e63a, 0x95fda193, 0x3a16fc2a, 0xe069c91f, 0x8d9db1ed, 0xdbf48bf8,
-       0xc8e00169, 0xa1ce82e9, 0x3c38f7b3, 0x7c3a24b7, 0x2e01f86b, 0xae7487d2,
-       0x78f7a52b, 0x658e098f, 0x7de8efb8, 0xe7f3a25d, 0xcd4f7aa1, 0xb13070ab,
-       0x3e9ce736, 0x0f9c4dec, 0xa76935ea, 0x01fa89d7, 0xed8a97d0, 0x094b2a36,
-       0x5cd4b3bb, 0xd7ade8e0, 0xab6d5cba, 0x937282af, 0x03f69983, 0x99534c3c,
-       0x79c0307f, 0x1ccf33ed, 0x3df58abf, 0xf803ae0e, 0xe6bce099, 0xe63347f9,
-       0xedf37b40, 0xb9b426ad, 0xf5a1cf43, 0x76a4ef6e, 0x4cab4b71, 0x23c519d3,
-       0x86b95465, 0xafd90b08, 0xe48674cc, 0xc6c934b3, 0x3d10a7ed, 0x50f80eb9,
-       0x644af08f, 0x38d0af04, 0x49f8e871, 0xdefcc905, 0x1a52e2e4, 0xa7454377,
-       0x5d90e31e, 0x4ec57aae, 0xefa9f4f2, 0x7bb1fb42, 0xff23a73a, 0xc81a1577,
-       0xc1f87e1e, 0xcf119349, 0xc51265de, 0x7bd17ad1, 0x233dbac8, 0x1cae9cf5,
-       0x7f28cd8b, 0xdbb9ccb7, 0xfec3e8ec, 0x8b3152d8, 0x965a2fce, 0xa5633b70,
-       0x88e481bd, 0xe7b942a5, 0x71cbd8a2, 0xa213bfaa, 0x3754b727, 0x9bdef198,
-       0x8590de7a, 0xed97dbd8, 0xbbbd1fbf, 0xf18bf961, 0x2aee4fa8, 0x79c78869,
-       0x4ff0896f, 0xd5df1377, 0xf2029f93, 0xf1e51e38, 0x920e91a2, 0x7ff2dd2f,
-       0x0e3b39c6, 0x5569181e, 0x43db8af8, 0x417fe25f, 0x928d66bf, 0x1c6014a7,
-       0x8e44b52d, 0x74bc6076, 0x00d3bbdf, 0x7abd93ae, 0xfb8d63f2, 0x2fc1f481,
-       0x49382632, 0x681e9e5f, 0xac9d22b0, 0x8f46fc6a, 0xe2ce6bf7, 0x7fe855e9,
-       0x87b70255, 0x9818c556, 0xa1f342df, 0x2e754f45, 0xf5a7a866, 0x0137dc09,
-       0x798fc5bf, 0xfd102316, 0xbaf18e4c, 0x298700ad, 0x30bbbe31, 0xd7ac4aad,
-       0x129c60d9, 0xf080b447, 0xc563a29d, 0x9daf1e06, 0x115cf385, 0x59c511f3,
-       0xd1c5a727, 0xc5a3547d, 0xc9fbc3ad, 0xf6d5677a, 0x8bce8cb5, 0xb015bc51,
-       0x8ce1f74a, 0xb6bdc718, 0xeeab8e27, 0xdcf1a913, 0x04290575, 0xffc1212f,
-       0xcb23e22d, 0x1ef1101a, 0x403e987e, 0x46aaf8f6, 0xcd41f913, 0x91da3b09,
-       0xf823323d, 0x3e7aa43e, 0xb163e017, 0x0c567c02, 0x95d69bbc, 0x17bb1494,
-       0x91faa5e7, 0x50af20f1, 0xcc2565de, 0x4beb8a9b, 0x4aedc37a, 0x0cc67a86,
-       0x1660365d, 0xa2b9eae0, 0xc61eac78, 0xd8583c21, 0xabfb4c38, 0x40d122bf,
-       0xf2d0d8f1, 0x5c780b27, 0x21050b32, 0x135eebae, 0x755dcfdd, 0xaaf7bee0,
-       0x301e7e50, 0x6767c939, 0xffbc1481, 0x66771dde, 0xaeddff7c, 0xdbb5bf9c,
-       0xa63f740d, 0xf8ccbe3b, 0xe71abcbe, 0xd9e51a88, 0x31f2788c, 0xc7f421c7,
-       0x8f71abfe, 0x4fca461b, 0x6dac7f60, 0x63c515c0, 0x68eac6c2, 0x8529279f,
-       0x05f78279, 0x5feb2956, 0x7a870dd5, 0x75f5ea3b, 0xf6079428, 0x378d870f,
-       0x2226bbe7, 0x88ec46dd, 0x47dafd47, 0x171343bc, 0x79287bc1, 0xfa6204b1,
-       0x9c79aa93, 0x3cea6624, 0x5348778a, 0x0ad93ef9, 0xdcfc6016, 0x7c84c0a0,
-       0xfd4beaba, 0xe887700d, 0x927accd7, 0x90ae9193, 0x7f2f48b8, 0x6576e645,
-       0xa2dbdc88, 0x02f1f9f0, 0xcf91ee25, 0x93e7bff2, 0x5228bb25, 0x1889f7d9,
-       0xe8724295, 0xd90a5711, 0x411cc443, 0x9d9cbef0, 0x87b15073, 0x8f9ca77e,
-       0x83e72bf7, 0x83e72b0f, 0x0b77c55f, 0x863f90c0, 0x7a4016ef, 0xe549c9bc,
-       0x2815346f, 0x6fe399ca, 0x4892ee45, 0xf9941fb2, 0xadf994e9, 0x25734eb0,
-       0x6d567e03, 0x5879d3d3, 0xe984c263, 0xaf32cf68, 0xdb119edc, 0x7587ef73,
-       0x9efcbfc2, 0x095da773, 0x3a4f3a1e, 0x3ff7cac7, 0x542d7c55, 0xb612afea,
-       0xc75f9019, 0x36e16a76, 0xc6a452fe, 0xda622cae, 0x4d1397f3, 0x4bf53443,
-       0x97f3daac, 0x6ad7ec93, 0x68764fbe, 0x975e5fcf, 0x1f643e31, 0x0b574b56,
-       0x806e8013, 0x7d33aa4e, 0xd685ff34, 0xcd7b8a52, 0x74c7b90d, 0x3f36ab47,
-       0x2fcda7df, 0xabcdaddc, 0x46c3c9e7, 0x9230f429, 0xf131fc8d, 0x0cf7e44e,
-       0x0107ef85, 0x3ab36fbf, 0xcfda1199, 0xf8bf7816, 0x1b00c61e, 0x76c94bed,
-       0xe3ac238c, 0x5cb09ff7, 0xc3bdcbc7, 0xbe7af695, 0xdb8ec56f, 0x4b1dbee8,
-       0x06ede1cc, 0xfc7eeff0, 0x72f1a48e, 0xfe87af0e, 0xa21bd612, 0xe5c353f4,
-       0xfe459c93, 0x33ec9b82, 0x62b36b23, 0xc2fe016a, 0xe9399a34, 0xab0c759e,
-       0x9075bf27, 0x51327f72, 0x43bca4e8, 0x3e6186b0, 0xf0a67045, 0xe48f85f8,
-       0xfe4950c3, 0x89f12a75, 0xf447745b, 0xb90d97e6, 0xaaf007ba, 0x910286f8,
-       0x5623e2e4, 0xd8f9ef46, 0xbf13f75c, 0xb016c36e, 0x8f6b336e, 0xf87a1549,
-       0x61bcede7, 0x5c135fc4, 0xb52fda0e, 0x780b2415, 0x8588a52e, 0x4536cb9c,
-       0xc4a3e869, 0x5f42171a, 0x4be84243, 0x9d7f7f4b, 0x3945d5ec, 0xe842ce90,
-       0xe5be2ff0, 0xaf182c51, 0x05fa8f4c, 0x7689d58f, 0xca9e054a, 0x754f9602,
-       0xee319b46, 0x73d18b67, 0x3fd8a579, 0xab9f4aa5, 0xb2eb59e4, 0x566bfbe1,
-       0xf6e649d1, 0xf13d2dba, 0x96df1825, 0xea35f600, 0x5c919963, 0x1fd3b07d,
-       0x7fd43576, 0x65fffc04, 0xeb1bfd0c, 0x65efbc64, 0x5f10e4b5, 0x7949623f,
-       0xd05ef300, 0x437f58e8, 0xe5aff731, 0xef826ce8, 0x05bea151, 0xc23da5ef,
-       0xc1a94cf2, 0xfebc2df5, 0x5164597a, 0x31189f90, 0x9dbfea82, 0xcef86667,
-       0xd9a07781, 0x63ec7187, 0xdd77acf2, 0x7b7feb41, 0xaf07d714, 0xa8f11c19,
-       0x7c991e0f, 0xd287a677, 0x685f8d74, 0xbee4104b, 0x8f8517ce, 0x92bd7236,
-       0x78c7e25b, 0x34c2747c, 0xfd039957, 0xe90bb71d, 0xf112e742, 0xfd375be8,
-       0xa87e2b44, 0x0fc106e4, 0x5d749b4b, 0xe3ff430e, 0x35770b11, 0xd59e291e,
-       0x02f98652, 0xd903ee91, 0xd9ebe25c, 0x7e02aeb8, 0xe54af0fe, 0x181ea871,
-       0xbfdb9a32, 0x3c448693, 0xdffa1430, 0xb15a2450, 0x2b7a0dff, 0x4ef1e7dd,
-       0x1757e466, 0xe097eabb, 0x11096dbc, 0xda6fcf0c, 0xbe781a0a, 0x00ccc0d8,
-       0xbd6b934f, 0x4a69f117, 0xf6c08cf5, 0x7a7e0747, 0x5b19ed1c, 0x703a4882,
-       0xaef9cba2, 0x2817eb1b, 0x79e29df1, 0x9b3c70eb, 0x599ab445, 0xb9541c0f,
-       0xcbc99ebe, 0x0ab2ffc9, 0x0accdef4, 0xce0d436b, 0x708491e7, 0xae6df3b2,
-       0x79e20b06, 0xd13d40c3, 0x7f224941, 0xc2556a57, 0xffcc0ab4, 0x7191a062,
-       0x1f2ff3be, 0x5381fe8a, 0x5b3575a0, 0xc75e681a, 0xc139892e, 0xa9a896ef,
-       0xcf85a1d9, 0xf8f146ef, 0xf1e30990, 0xf5b79f80, 0x8b9a9ccc, 0x78a7a3f4,
-       0x6b7c7f53, 0x7ece5d73, 0x2afe61fb, 0x110b0394, 0xc29785be, 0xfa404f98,
-       0xfe61293d, 0x5b017f77, 0x60d9d680, 0x6e41fec1, 0xbfa2fabb, 0x7e9cd188,
-       0x4b0e0b9b, 0xd7824ef8, 0x341f1021, 0x444e4e5b, 0xb528783e, 0xa1e8e88c,
-       0x899a8f82, 0xfcf3862f, 0xeef779db, 0x137a3c41, 0xe77f69c3, 0x315982a1,
-       0x60bef4c1, 0x32f44894, 0x4e616fee, 0x9463e23f, 0x91fbf881, 0x8c56c708,
-       0xccf3794f, 0x824bbf64, 0x986cd975, 0x2862c4e7, 0x5da2fe87, 0x7ef13e62,
-       0x0b8f0575, 0xd57e302b, 0xf8843b65, 0x31664a90, 0x3949ae7e, 0xef9114f7,
-       0xb435435c, 0x25956ffa, 0xd8cfde97, 0x4270d092, 0xbb20b6d9, 0x5722906a,
-       0x45889406, 0x5906df28, 0xeb655db8, 0xbb940594, 0xaa47fba1, 0xed29d7be,
-       0xa65b328c, 0x371b54a3, 0x7d7015d2, 0xe97f6a1b, 0xc35edc2c, 0xae8fbc3f,
-       0x893f35cf, 0x317438e7, 0x197f7ada, 0x0a739ca5, 0x3a54afb1, 0x7ae560df,
-       0xd1ae4362, 0xa1bd7487, 0x2a59db98, 0x47f2ab1f, 0x872abf85, 0xef7e7bd4,
-       0x5195f628, 0x87365e4e, 0xe599eae4, 0xd4076f78, 0xc317739e, 0xfa56897b,
-       0x1f72aefe, 0x6f6294f1, 0x5bd8a7bd, 0x5bd8a1ff, 0x05bda3ef, 0x835186f9,
-       0x1437bf08, 0x08dd762e, 0x20901af3, 0x3a14df11, 0xedc44c4e, 0x271971af,
-       0x61d97d2c, 0x0ea2d111, 0x348f05e3, 0x36497bf2, 0x1598ed97, 0x95cf59f1,
-       0x766b2cf9, 0xbcbb3469, 0x7ae3f27c, 0xe43ed1d2, 0xb9557beb, 0x994c794f,
-       0xfe6571ff, 0x57f3286f, 0x43498fed, 0xbca132be, 0xefaf10df, 0xfc297e47,
-       0xb9d0a729, 0xb57950a8, 0xe908c401, 0xfc9122eb, 0xe778209f, 0x25bde46a,
-       0x4ef5f720, 0x1e68c959, 0x7660dbbf, 0x7c462c57, 0xa714664e, 0x27aae89d,
-       0xb90365b9, 0xf8b37245, 0xca6ceb5c, 0xe5833847, 0x6381519e, 0x8e5acbb1,
-       0x4638be72, 0x24571f4f, 0x5bbdd0a4, 0x1d0efed5, 0x0cf072f7, 0x82a66795,
-       0xf3e25ef5, 0x6c7247ff, 0x8ee3e32c, 0xfd3a24bd, 0x4f1cde5c, 0x91237926,
-       0x5fed0a7c, 0x636f3795, 0xbe2064cc, 0xfba1644f, 0x610a7700, 0x9de7844e,
-       0x3f307c28, 0xff7dd197, 0x673d8ac1, 0x01d1de57, 0xceb8a14e, 0xf5b04ed8,
-       0xfc7af883, 0x1bf75325, 0x8f8edc6c, 0x9a27e4d6, 0x4bf535e2, 0xef9ac9ac,
-       0x35c3ec93, 0xb23b27df, 0x32ebf935, 0xffea6946, 0xc9a459c2, 0x593050df,
-       0x2e4cbf53, 0x6665e4d3, 0x0e4877a5, 0xfa1eed36, 0xa7fd1eb1, 0xa71fa1b6,
-       0xa14f86f5, 0x0e0bf0f1, 0xa3b5e160, 0x00e8678b, 0x87518546, 0xfc864cef,
-       0x6793d1c6, 0x0aef80e8, 0x3afe1f07, 0xd3685819, 0x7f3c29e8, 0x53afe1f5,
-       0xf465bf20, 0x863f3c75, 0x3adcf091, 0x2f0cea7a, 0xea1c59e0, 0xd0347479,
-       0xea972df1, 0xf83da28f, 0xe6d365c7, 0x4ef84b26, 0x06625940, 0x8a6ce7cc,
-       0x7efc61e7, 0x15acec73, 0xfc761178, 0x8f74f577, 0x79a337ed, 0xfc8b8ebb,
-       0x8b8e8d5d, 0xbb0d1dfc, 0x53f6f1c8, 0xcbbef553, 0x7e9a0e04, 0x64115fdf,
-       0xfd05af7e, 0xdc6939cd, 0xfd14c4df, 0xdfd14c4d, 0xcdfd14c4, 0x6fee7a39,
-       0x26fe8a62, 0x89bfa396, 0x324d5be9, 0xb934efa5, 0x726f6d28, 0xbf7dda53,
-       0x6ae729e0, 0xef380a3d, 0x985b8b4f, 0x1117e4c3, 0x4ae7a14e, 0x4f9df43a,
-       0x45ca7ed0, 0x12fbc0e6, 0x394e2287, 0x39acbf70, 0x2e7444cf, 0x4c3bb674,
-       0x9730bdf0, 0xb62f9be7, 0x617e503b, 0x8e9eed1e, 0x946cb6e8, 0x16b5cdbf,
-       0x35bbee27, 0x23c7f45f, 0x1bd6149f, 0x714cdee8, 0xe9c52767, 0xbdfc2d0a,
-       0xc7114384, 0x91e3288e, 0x9179da5c, 0x277c45f9, 0xb0eedcc7, 0x3f60e32a,
-       0xea326e30, 0x3025c2b7, 0xbf5bf52e, 0xb0a9fa98, 0x842b8f74, 0xe1fa6b8c,
-       0x410a2771, 0x3176a6e3, 0xc701177a, 0xf5c66875, 0xfc3f744b, 0x78c25fa2,
-       0xd3b44761, 0x354d718e, 0x21df8c5f, 0xdfcf45bf, 0xf8742c5f, 0xb893d425,
-       0x5bef89bd, 0x33d881c6, 0x1f0d79d3, 0x47a865c9, 0x5d9db971, 0x9a179d7c,
-       0x9f900bfc, 0x6077958a, 0x7ba58cc0, 0x730c4c9b, 0x9128bea2, 0x38363bbe,
-       0xe339df17, 0x1b15a0ef, 0x1f90dbdd, 0xde5c74eb, 0xdf3318b0, 0xcfb5d057,
-       0x3bd415ff, 0xec983b19, 0x4bfb0495, 0xb404752c, 0x44cae45f, 0x5b24e3bb,
-       0x7568724f, 0x8f7fe794, 0x31be7a06, 0xf4505eb3, 0x7763f527, 0xfdc0ef85,
-       0x86578e88, 0x4d1f21e5, 0x645e3a33, 0x1f7fbfc0, 0x3cfc44dd, 0x8791ca2d,
-       0x7dfdac2f, 0x8f9e0af4, 0x3788bc73, 0x69acad83, 0x8ffc7146, 0xf1452f3f,
-       0xa79a740d, 0x7fb43a0a, 0x765373d4, 0x063613d1, 0xfaeb54e0, 0xd7e7c0ca,
-       0x7078c069, 0xc10718d4, 0x4661e06f, 0x273a98e7, 0xe076f847, 0xfa80df7e,
-       0xb2878c6c, 0xd61e474c, 0xd277d24b, 0xef8ef27d, 0xa827fdf8, 0x50537919,
-       0x8389fefc, 0xf8afab92, 0xdc31c9e3, 0x6a945d4e, 0xa8788759, 0x944c9bb3,
-       0xe748bc1e, 0x9dce9982, 0xd96bf18a, 0xa97bf7d0, 0xfae18eaf, 0x41a57921,
-       0x74410231, 0x30e594c2, 0x0cbde6a6, 0xbbf6d0f4, 0x8bdfbac3, 0x43327003,
-       0xdef3c89a, 0xeb178f1d, 0xac65f534, 0xe31dfddf, 0xbda7acf4, 0x8fcddbfc,
-       0xc6554f2f, 0xc7997a43, 0xd50c7fc8, 0x6d0b6b3b, 0x843f3bea, 0xcc63c7e7,
-       0x523de9db, 0x14877949, 0x4e315aea, 0x3de8ce11, 0x37bfc1ae, 0x9e819afb,
-       0x3d399a76, 0xdd3c8aa7, 0xeafaf229, 0xbbeaa53b, 0x7a14cf6b, 0xa3cc2b6e,
-       0x8fd4fc7e, 0xdf1b37b4, 0x6d6788cb, 0x6efabe34, 0x012f5a94, 0x2b0920f4,
-       0xe23a675d, 0xfb1250ab, 0x63e7e784, 0x1d20e68a, 0xb2f2685c, 0xcdf4824f,
-       0xc6c8f085, 0x49d5fc60, 0x3f5af7da, 0xda81331f, 0x1b6beda9, 0x284fb227,
-       0x3a27e978, 0x69154daa, 0x624ebd1f, 0x9c3be2af, 0xa80d5920, 0xa776d597,
-       0x78e2de40, 0xc5fc82ef, 0xbb903df4, 0x3ed1e89f, 0xfbe94e9d, 0x3f2a1e4d,
-       0x694d54dd, 0xca9ea9a0, 0xa46a6a3f, 0x23db96f4, 0x167f9172, 0x3ec65fed,
-       0xdaf7a209, 0x1027bd36, 0xd4553f94, 0x51ad1d37, 0x7254e8e8, 0x1c9fdfdf,
-       0x53bbedc3, 0x3b3e38e3, 0xf7c0dec0, 0x972e80da, 0xdbfd6d5b, 0xfdca1d1d,
-       0xf9e3a3ae, 0x3c4765fe, 0xc31f2fcf, 0x64596efd, 0xe8fed8ad, 0x3fef0378,
-       0xefc6ac45, 0x7bf78db2, 0x77a45d2a, 0xb1357ea4, 0x5831fee8, 0x73ca163f,
-       0xaea7f27a, 0x41e5dfe2, 0xaf9d5cbc, 0x42b6fdfa, 0x61eefaab, 0x8fcf7f3a,
-       0x7a02f7df, 0xfad5fea7, 0x3e702663, 0x4befad0c, 0x43c9e7e5, 0xc2a9f1e1,
-       0x6817c4b7, 0x241f2367, 0x9d45f107, 0xa542f883, 0xd6fe9543, 0xa7387216,
-       0x0f3a151a, 0x07eee7e7, 0x76842ea3, 0xb4cce383, 0xbbe3208f, 0x9d9eb0cb,
-       0xa12fc282, 0x63bca0fc, 0xca83f2ac, 0x0fbd2a07, 0xefe33e06, 0x8c75f334,
-       0x5f79fa95, 0x7b475958, 0x845dc46c, 0x2b7a83d7, 0x12b1adea, 0xb0792f7f,
-       0xedcef5d8, 0x11b19fc8, 0x96918c0e, 0xf7d4b2ac, 0xfe3ec725, 0x9543c2af,
-       0xa3c0fd0b, 0xca0c1c17, 0x123fc3bb, 0x50e7240e, 0xf6fd238e, 0x8c4eb721,
-       0x177629b1, 0xc7cfdfa7, 0x1d226fc8, 0x1d660875, 0x30e87bde, 0xf05f7df7,
-       0x0ebe78e8, 0x16d68e95, 0xe3074a32, 0x96f6873a, 0xba7aea7b, 0x230779d7,
-       0xc61a97f9, 0xacf143cb, 0xfe482bae, 0xa979c19d, 0xec0c64f0, 0xa127e81f,
-       0xe8ef42c6, 0xe0e856dd, 0xd3f036fc, 0x67ac0dca, 0x3e8a35fd, 0xf8944c7b,
-       0x7e8ac87b, 0xa4172ee9, 0x1a996599, 0xcf4743bd, 0xefe15f3a, 0x5645fb8a,
-       0xa372ef8d, 0x171c1d6f, 0xe5c8521f, 0x3cf4d743, 0x2f13f711, 0xf742d5fc,
-       0xea0c2f8b, 0xcef68d3c, 0x533d5685, 0x2a9b23de, 0x8b9dde80, 0xf90c133e,
-       0xf39ef2a5, 0x0ef7e8e7, 0x176d7a83, 0xb5bda34f, 0x4cc4ab68, 0xeb609e78,
-       0x3d20b737, 0x4f457bcd, 0x5b9a99e7, 0x7a471e37, 0xc04fb73c, 0x85d96fe7,
-       0x31c5027d, 0x7c225b6b, 0x0a5fa866, 0xc77fac79, 0xe3c7c96e, 0x39c5328b,
-       0x3ef1946a, 0xa0a5d731, 0xeb713e5d, 0xfb843a5d, 0x8b02edbc, 0xb48f7e83,
-       0xdf0c79de, 0x8db7391d, 0x366b2fdf, 0xf9c0ee47, 0x0ceb4a97, 0xc17ca083,
-       0x635e5e76, 0xf70cfd29, 0xcd3c1743, 0x60b3fe28, 0x8ff9046f, 0x1ff45af3,
-       0x8eec8205, 0xfcda6dea, 0x4066d67c, 0x53b0583a, 0x07b35e5b, 0x79f241f2,
-       0x2f12a150, 0x29b2ce19, 0xe3c2d25e, 0xef7caa07, 0xb97b5f6d, 0xde506d1c,
-       0x897f66ff, 0x5f0ff7a5, 0x23e926f9, 0x2997cf0b, 0xff9033f9, 0x178e1bea,
-       0xca752e15, 0xb3c55fd8, 0x675836dc, 0x2b662bdd, 0x0775edfa, 0x79e246ce,
-       0x016145b0, 0xbd99177a, 0xded1592c, 0xe4bf607b, 0x1ed6f845, 0xfb893f34,
-       0x9e2f7598, 0xa13c6030, 0xb262df74, 0xef312657, 0xfd9bf44a, 0x89dac8a2,
-       0x7de9da8e, 0xce77265f, 0x1c2e7ec3, 0x0ed15b30, 0x4ff97ba8, 0xfcc76ec7,
-       0xa7dd028b, 0x201890bc, 0x55b7993a, 0x0c437ba2, 0x1efcb42d, 0xaf10913a,
-       0x28b6e788, 0x0ee58f7a, 0x19e23bc4, 0x4648eef0, 0xd071e13a, 0xf44b4f79,
-       0xd9b5b9bd, 0xf9cff580, 0xbc557e38, 0x094b4a97, 0xe71e0bcf, 0x75b89cf8,
-       0xa430e6d7, 0x64f5a783, 0x76811f8f, 0x0d3b7883, 0xe15e181d, 0xc5d85ffd,
-       0xd37791cf, 0x376301c1, 0x2f3ce01d, 0xa7c00747, 0x472ff7a4, 0x97e89d07,
-       0xddffbf92, 0x0ed0c7b9, 0x87e7e08f, 0xd51b77d5, 0x2e071a77, 0xdf14753c,
-       0xbfb34ae7, 0xa5777640, 0xc5da8bed, 0x9d09de8c, 0x4be78853, 0x02bdbf26,
-       0xca7277d1, 0x2f14d9b3, 0x6d7607d5, 0x744378c1, 0x3ac7c538, 0xe1b6cb92,
-       0xb6c598fb, 0xc2f6936f, 0xcefd163a, 0xeb11e748, 0x3fc67e15, 0xbea2073c,
-       0xa7780c4b, 0x07b519f3, 0xc65cfc8d, 0xe1fbed3e, 0xce9cf11d, 0x959d0c4b,
-       0x804fd18b, 0x411c70fe, 0xc2e9fee6, 0x451dfc83, 0xa85c9fd5, 0x47b8a7be,
-       0x60836efb, 0x3dea9b7d, 0x70429850, 0xd6371a18, 0x73797681, 0x0d84f339,
-       0xc17d21fd, 0x5c7ca9df, 0xb5fa8bf1, 0x1bd1fb27, 0xbcc91daa, 0x15daf721,
-       0x014775b9, 0xbbd1e39f, 0x7be1d0df, 0xf93b1d8c, 0x3fcc3bef, 0x062af208,
-       0x1af519f7, 0xd4a753b9, 0x0fe914ff, 0x5bde76e0, 0x052892ff, 0x8bf797cb,
-       0xa79a9fb1, 0x48753f79, 0xf5571457, 0xfe830e6f, 0x33d36cbe, 0x4c0597e4,
-       0x23fb3791, 0x4bd46e28, 0xbedcecbe, 0x50f7cd12, 0x76085aba, 0x94222e26,
-       0x69f6eabe, 0xa85d3deb, 0x670e7bec, 0xfff9e0d7, 0x90e031af, 0xba5f23d7,
-       0x8e67e9df, 0x6eefe428, 0xef68287d, 0x056b0fef, 0x77ea0f96, 0x63c4cfb8,
-       0xeafe4aa4, 0xfe4d56dd, 0xa6bb369a, 0x1dfbb5fe, 0xfed9ef9a, 0x11f7cd0c,
-       0x7c9a9dc7, 0xa6817b5e, 0x64f7c8fe, 0xc0547e4d, 0xe63fa9a5, 0xef935bbc,
-       0xf4f584ca, 0xe9a8cf61, 0xa9a0bb24, 0xd661d93f, 0x465d7ff4, 0x65df26b4,
-       0xd8a3e051, 0xfbfdaa99, 0xff6e42a7, 0x7c2aa686, 0x8ed4e17f, 0x37edfaa3,
-       0x2bc76814, 0x5de3b593, 0x1df05e29, 0xff9e9d41, 0xf8a6027e, 0x34ba09fb,
-       0x9809fbfe, 0xc04fdfc7, 0x013f7f14, 0xe4dd7fcb, 0xa6befca4, 0x04bfca02,
-       0xf7e6097e, 0xe9829f83, 0x609fe0cb, 0x77e0e5f9, 0xb8f7194c, 0xca1bee32,
-       0x4e153fb8, 0xbdfd296f, 0xef87f4a3, 0x3df4ea0d, 0x795d6bdf, 0xe3e025e2,
-       0x7467db22, 0x086e595f, 0xa31c6294, 0xe18975f3, 0xf1e667f9, 0x418a6f1d,
-       0xa18036fd, 0x9ddcc49d, 0x6e3ee26f, 0xad438bdd, 0x81efae78, 0x07787ffd,
-       0x27d85fbf, 0xf0e6bc51, 0xd891b3fe, 0xc29797cf, 0xe90a30e9, 0x7cd7c845,
-       0x0d7e502b, 0x6773c77c, 0xca4af793, 0xa46d67bb, 0x554cbeef, 0x2fba3ef3,
-       0xd7b3deed, 0xb85a7880, 0x7f7d2f7b, 0xf35af81d, 0xcd76f77d, 0x87d62b77,
-       0x47cea174, 0xf7cf8571, 0xa9f9fdab, 0x7f2a4d7e, 0xddf3fe3f, 0x418e5647,
-       0x6ab7bc7d, 0x17b5c600, 0x3b1139ee, 0xf1f007fb, 0x66cf4bd5, 0x3da81ea2,
-       0xd1e72920, 0x07b57f78, 0xcf9e4af4, 0x6f7526bf, 0x63379e29, 0xb3ba047b,
-       0x4f5b25f4, 0xee16c4e7, 0x728355df, 0xedc66176, 0xb57f8a7a, 0x83bc4a49,
-       0x6350d3bf, 0x6baedc65, 0xdf123afb, 0xdb7dffa9, 0x1ef1ebd1, 0x23c1c774,
-       0xc74c5ef4, 0x4fe3493e, 0xf1cb1d8d, 0xf72c763b, 0x77dcbeff, 0x09cf1224,
-       0x8476d03e, 0xa7e75dc3, 0xf2561ff5, 0xbc12901d, 0xfeb44bf7, 0xcd2497f9,
-       0xc0b801ef, 0xcdfba171, 0x7022d3fb, 0xf8db275d, 0x7d40d378, 0xd56a7950,
-       0x1bff9c1c, 0xe53cf2f6, 0xddfa327d, 0xaeab8ea1, 0x767285db, 0xe7d49b61,
-       0xd839f779, 0x98efcc2f, 0xebe9d39e, 0x1b1c2fa9, 0xc37f7004, 0x749b2035,
-       0x62af5284, 0xa59bd72c, 0xea2a4f06, 0x47169391, 0xfdf9d204, 0x8811a1ae,
-       0x6298c3df, 0xba49ebb9, 0x1f60be07, 0xb5a4ef1f, 0xeee9123d, 0x5211bee4,
-       0x2dcbfef0, 0xe9ba7aca, 0x5e6f1bbb, 0x6fb553c2, 0xe9fb05bb, 0x9f2f1fc1,
-       0xf54ad636, 0xb89df0df, 0x93aced05, 0xc0ddfc19, 0xfe460663, 0xdc3dc2f5,
-       0x70793e4e, 0xfbe0f6f0, 0x7c14d359, 0x7df06474, 0xf5fb0bf5, 0x77dbbd4a,
-       0x3d3d4d31, 0xed4ed7c7, 0x33beac7c, 0x5e7da10f, 0x6744b8f3, 0xf5f46a1d,
-       0x4ffeb8b1, 0x57e769b7, 0x46b9c0ad, 0x0d8d8fef, 0x039ad7a2, 0x21637cdd,
-       0xf2a03f3a, 0xa9f08389, 0x8664f1e2, 0xe765e7c4, 0xecd5f8ef, 0xdd7445dd,
-       0xe3c4be3b, 0x31ef83b7, 0x74be2939, 0xb55a7f19, 0x2dfc821b, 0xbd23bdfa,
-       0x989e686b, 0x9c1f63d2, 0x1a1f942e, 0x987e879b, 0x93ccfc9b, 0x185bec0c,
-       0xebed16b3, 0x891dfa28, 0xd76e38cd, 0xffbd3d3e, 0xb03a6b5f, 0xef23df00,
-       0xc0a30272, 0xe9b6bbbc, 0x4667dfbb, 0x629e773b, 0xf0ea7ee7, 0x7fa04be4,
-       0xb489976b, 0x923d9abe, 0x5c17cf0f, 0x57dee450, 0x406f937b, 0x2e39ad7a,
-       0x9a3fd159, 0x70fc96d8, 0x77e92e61, 0xdaeb57b2, 0xb75c9db8, 0x58bb205b,
-       0x156a43b5, 0x629ce43b, 0xd65b9f07, 0x57e3edc9, 0xea11b604, 0x7b030dad,
-       0x9b5de604, 0xdaec8539, 0xcadd695a, 0x473c0ec1, 0xe61bb5a5, 0xe7443c1f,
-       0xd1cec0ae, 0xaddc2f94, 0x69b6d7cd, 0xf8bfaaf3, 0x3b6ed8d2, 0x37fa3863,
-       0x1c615225, 0x0a9bc3f2, 0xe77f555e, 0xf49c6bce, 0xe80f27fb, 0xb8d4531c,
-       0xd16bc204, 0xc7cc2f2b, 0xc26afb79, 0x347fe49c, 0xdae096fe, 0xd7ee17f1,
-       0x1bdee074, 0xf0e333f2, 0xe9cfd8ed, 0xf05e917c, 0x2cbaefe1, 0xfd815d42,
-       0x32df0499, 0xbb7b3b8c, 0x293e4922, 0xca1a08e7, 0x632affb9, 0xb2a6180c,
-       0xe7f72c7e, 0x38eaf543, 0x0e8a405d, 0xb1811392, 0xd8af5429, 0xde57cfc0,
-       0xfd24e119, 0xedc4c436, 0x6e2621f5, 0x75d10faf, 0x85dfa32e, 0x7df02418,
-       0x6997ac8e, 0x9d6d60ff, 0x0417f685, 0xe10e957b, 0x955076b1, 0x887de90e,
-       0xfd032db5, 0x8c5f353a, 0xec7b33df, 0x478b5283, 0x8cece387, 0x047d9417,
-       0x74cb4fae, 0x90747d56, 0x996c657e, 0x3dea7e66, 0x7e7d9fcc, 0xa59f9856,
-       0xef807e67, 0x75ff6c28, 0x86ec93ae, 0xf7f532a4, 0x2e49ea1a, 0x12fcf0a8,
-       0x7018bde8, 0x816c7745, 0x1db66a6e, 0x96b2ff22, 0x76c4afb5, 0x1d7c91a5,
-       0xbefe06a5, 0x4f186951, 0xfcb8e375, 0xa5d2512a, 0xc3f6b4e3, 0x7eb27191,
-       0xc63ba41c, 0xf2e34db9, 0x79953f68, 0x6f0d7d61, 0x43d677f3, 0x13943ee5,
-       0x7c0d7d3d, 0x466ff288, 0xd54d60bd, 0xbf9c69d8, 0x6ea2f116, 0xf6f85a3e,
-       0xea27c493, 0xc66acc39, 0xa3667bf9, 0xc41a9ad9, 0xdf908b17, 0xc377ded0,
-       0x138c7cbf, 0xeb6abff0, 0xe9973a7c, 0xa2b58c69, 0xfa48b75f, 0x7e25f692,
-       0xda2ddf2c, 0xcdfbcdaf, 0x11fdfe9c, 0x1949f902, 0x0de3bae3, 0x0a498fc4,
-       0x08f76c7f, 0xfb600e74, 0xcf1e3a77, 0x7e2810ab, 0x36143377, 0x624994da,
-       0xba22eabd, 0xe333724f, 0x4b596347, 0x3dbbf28c, 0x796fb431, 0x9beeb293,
-       0x2843fe75, 0xdbea8e57, 0x749e3192, 0xc4e4d6b4, 0x1b59cbfe, 0xc15a6fbd,
-       0x153d29da, 0x9fa2f75e, 0x2226f73a, 0x63c9fddd, 0xf6d678a4, 0x50223be5,
-       0xe5b167be, 0x044fdc56, 0xb7c6ec50, 0x73b3fb01, 0xd51df742, 0x2f60c4fb,
-       0x027d21c7, 0x1d2127fe, 0xd8dc079c, 0x5fb77a73, 0x2317c7f8, 0x2c5f7f11,
-       0x5b96e179, 0x9d5ffa19, 0xa82d47e4, 0x5df7465f, 0x33da9c81, 0xaaf07bf2,
-       0x5bc55de2, 0xf01d5e37, 0xb0af182f, 0x938404a6, 0xc91965f4, 0xe8917fa5,
-       0xf0e5d69c, 0xbc7dc2aa, 0x0e3b9f82, 0x8a15f970, 0xb70f156f, 0x43f5bbe2,
-       0x236eef49, 0xc923313c, 0xb87a50cb, 0x3080be1c, 0xc4d93ce9, 0xa1f92318,
-       0x4f2e4583, 0x2813cf07, 0xf33b795e, 0xf48012bc, 0xf5f7f096, 0xc70adefc,
-       0xb782855b, 0x2fdf313f, 0x71ff9232, 0xce323b78, 0x606e34dd, 0xe50dbe6f,
-       0xb2f8fed3, 0x37fce1c6, 0x18fa5f55, 0x3f0863f2, 0x376bf087, 0x2ff09d1e,
-       0xc69e8f08, 0x6ecbe248, 0xae7b4b7c, 0x7fe22f4c, 0x5fb58e30, 0xaf93f9f0,
-       0x46055f80, 0xf8f8bfbf, 0x54dead38, 0xa5c2a6f1, 0x07e0b8bf, 0x2ad47fcc,
-       0xe70abed0, 0x748dbbe3, 0x57dd43ff, 0x5e4ff751, 0x5cf5c719, 0xd801fa68,
-       0xb55fb84b, 0x40e4e326, 0x194f33b4, 0xfef87ed4, 0xdacb07ef, 0xb6f7f113,
-       0xe9e2283e, 0xddff0329, 0x872f350f, 0x07e4b8f1, 0xc22f46f1, 0xf86103e9,
-       0x1f33d404, 0xcf5cf708, 0x070671f3, 0x26e3cbe6, 0x53903de0, 0x798e357a,
-       0xf07f12bf, 0x8f9479f1, 0x027aa62c, 0x074a5dff, 0xf61ddefe, 0x1736082b,
-       0xbb83e7cc, 0x9d7de8d2, 0x718d7dee, 0x467f0edc, 0xdc774759, 0xe2815eff,
-       0x355133fe, 0x84c4fee1, 0x877c2e2d, 0x437df4f3, 0xb4df69b3, 0xea3e3b41,
-       0x978a64fd, 0xfee7e06e, 0xabea752e, 0xb75bf482, 0xc8be2dbe, 0xd1e4e7cb,
-       0xbfa88cef, 0x86db2747, 0xc7dcff73, 0xd550df7f, 0x5fc75d67, 0x73c704b0,
-       0xdfe2533f, 0x0fe1f9dd, 0xc3eb0526, 0x4dad4f43, 0x0daa7ec7, 0x05a72cde,
-       0xb1ee877f, 0xaa5bb424, 0x4e955a9f, 0x0f53f4f6, 0x545fa3a4, 0xba6d63bd,
-       0x0f70f94c, 0xbe3a65f9, 0x1b9e2fee, 0xd4f3e745, 0xdccaf6fe, 0x1d30a8af,
-       0x3dbd412a, 0x56afeae5, 0xda41fee0, 0xffc5027d, 0x15f6b066, 0x332b67a8,
-       0x16b15f38, 0xe87fc913, 0x776bf68f, 0x4ec5ff0d, 0x646f0794, 0x81cfd59c,
-       0x203e127a, 0xd5df1035, 0xdfa3adf2, 0x7fcd5c09, 0x7ea7b027, 0x56ffed22,
-       0x9de8172d, 0xfcf519ab, 0xf1a4f377, 0x59c704d1, 0xd18fb3ab, 0x794b57fb,
-       0x6fa314f9, 0x67ec49df, 0x3fdf818b, 0xe094ee64, 0xb29270fb, 0x9d73385f,
-       0xca717bf2, 0x639b6938, 0x53af07b7, 0x591df652, 0xdf2477ea, 0x32f0506e,
-       0x5789e975, 0x54efd0ed, 0x1e3cc7bd, 0xe9b3bfbe, 0x619faa5c, 0x3a33f41c,
-       0xf066985f, 0xd71f3a3c, 0x7148c3bd, 0xc1acdcd2, 0xcfd41c52, 0x11b45259,
-       0xab4b99d3, 0x728f9d1e, 0xcd94d5b8, 0xf9f2358f, 0x114e0835, 0xed91f4e5,
-       0xb842ceb7, 0x7fc4df9d, 0xfb61abff, 0xc2ddfa30, 0xafdee4fe, 0xf9eff89a,
-       0xa264dd3d, 0x2b26d9f4, 0xcfeba3c3, 0xff29d935, 0x4a0e4daf, 0xcd3cf4d9,
-       0xd7f4d8ef, 0xe14b88df, 0xb973bbf4, 0x3bf4cdab, 0x39460d88, 0x2bc03c75,
-       0x1ddaaaed, 0xc2eb280f, 0xbdb2b8f7, 0x0e1113c9, 0x3e2c0fb9, 0x75b3a686,
-       0x7d97df3c, 0x24eae4f3, 0x2c77d614, 0x7cc4f33d, 0x78fb7ef8, 0x270835f7,
-       0x148bb6d3, 0x607238a7, 0xbbc22555, 0xaf91877a, 0xf9f7594f, 0x8f71e94d,
-       0x75f97c62, 0x160dc53d, 0xc4f33b6d, 0x877f0c03, 0x9821b177, 0xbd74afde,
-       0x7ee78f57, 0xaaf8e5e6, 0x78fc383f, 0x449b5abe, 0xf803b3fc, 0xf3a7f32a,
-       0xcba5a2d5, 0xc6cb7e08, 0xb8426fbb, 0x937bd79d, 0x0fce9f90, 0xee744b1f,
-       0xf820457d, 0xdbbc72ab, 0xbfe056af, 0x575b6c50, 0xc723dc98, 0x04b961bf,
-       0x3e0743df, 0xf9fb474d, 0x3fe5fd9b, 0x6097eeb8, 0x1861fedd, 0x1a5133af,
-       0xe0df3dfa, 0xf584ea19, 0x3ef3f7e5, 0x6af1d2e8, 0x539f9ffc, 0x36213fc0,
-       0xe6219df8, 0xd4f9828d, 0x61fc141c, 0x26cfa859, 0xbf43a67d, 0x8fcffc11,
-       0x198ce734, 0x9f4828fb, 0xcbdf37f7, 0x4fd875a5, 0x1ddc8f5a, 0xfcc89ef9,
-       0x547b7a41, 0x83f98c20, 0x73f6edc6, 0xfb40cca0, 0x1724f14e, 0x2e786f10,
-       0xe181c2ec, 0x99ff303b, 0xc2f1e381, 0xf14f604b, 0xf2931078, 0xd9f9d67b,
-       0x50b22f81, 0xb7ae86ce, 0x882fe5ee, 0xaff66a3e, 0xfad028ba, 0xcba67f27,
-       0x0ffafcba, 0x1645f53d, 0x7d33efe2, 0xb6fd1f20, 0x1640860b, 0xb7eea1e2,
-       0x58ff9e5c, 0xf3e5a838, 0xf7e81b57, 0x1304eb3a, 0xf48949d1, 0x2e1fc525,
-       0x87f1e71c, 0x924f03ba, 0xc83aed3c, 0xc48b40e3, 0x8c38d2f6, 0x399fd49b,
-       0xcbacf286, 0xe831fdce, 0x2b71de9f, 0x41e8aa1c, 0xde12675d, 0x4dd83bf7,
-       0x3c8fdc0f, 0x0c3bfc8f, 0xf3a369fb, 0x9c2b2cbd, 0x39f15da1, 0x7c30f3f2,
-       0x257930bf, 0xdf79f9d2, 0x8f941cc0, 0xadfd666f, 0xbf86e28e, 0xb27ba70f,
-       0xe6926db5, 0x3af7799c, 0x703f127c, 0x29fb54c4, 0xe7c1c99c, 0x1b8e0cb9,
-       0x837e6ec8, 0xba2e13ef, 0x7b13f38a, 0xed53f399, 0x7b0643f2, 0x15bb7f50,
-       0xc8ed527e, 0x1bffbf29, 0x85b3e5f1, 0xd504fd32, 0xffc7a54f, 0x4cf7fe9f,
-       0x33412fff, 0x800063ec, 0x00008000, 0x00088b1f, 0x00000000, 0x5aa5ff00,
-       0x5554700d, 0xbdef3e96, 0xdd2749fe, 0x12421349, 0x42068408, 0x03621a88,
-       0xc4d67281, 0x206efce9, 0x6b01bb33, 0x8d08c42d, 0x749d2422, 0x6aece882,
-       0x021a6eb9, 0x367564ac, 0x1d47598c, 0x809f9b47, 0x9476ec28, 0x0da0c040,
-       0x6ba2cb0a, 0x3a26aa45, 0xab545b55, 0xa6e00eac, 0xd63b8223, 0x3be7b8e2,
-       0x1dddb5ef, 0xa6ed4fe2, 0xee7dba8a, 0x9ee7b9cf, 0xce77ce7b, 0x52b48f3d,
-       0x6a22ca22, 0x2a08cdcf, 0x6ea6ff0a, 0x6d4445a2, 0xf67f2429, 0xaf1f4541,
-       0x7dbc64d3, 0x58c9a340, 0xce08eb93, 0x4754419e, 0x459a26dd, 0x654284b4,
-       0x29bf71a4, 0x795bcbf2, 0x6d0dfebc, 0x61931741, 0xb06aad1b, 0x7aa6d513,
-       0x1314360b, 0xaacaab0d, 0x0bcc6286, 0x4b9d2e95, 0x7efe0df4, 0x879b744a,
-       0x2a224f99, 0xf60f14d3, 0x169c9d1b, 0x8b5dc9dc, 0x491bfb97, 0xeaa7984d,
-       0x534f98f3, 0xa3827c08, 0xd81d4b25, 0x9964b468, 0x8eef3e23, 0x07d6d237,
-       0xd2a14e31, 0xf9f6123b, 0x68858f4b, 0xcb17d121, 0x650faa17, 0xdaae79f2,
-       0x51337403, 0x29ed768d, 0x70ddf785, 0x05564ccc, 0xafbc67fc, 0x670239f2,
-       0xfa65ea34, 0x790a4752, 0x4bceccac, 0x1bcf0f1e, 0xd8293b99, 0x3f6fe7c5,
-       0xe78990a0, 0xeeb11db5, 0x6d79e14c, 0x9bb648e6, 0xf036ddf7, 0xdb878b3b,
-       0x2cf7fef6, 0xcf58b9ae, 0x9e433647, 0x6dfa1514, 0x174ff277, 0xce607f91,
-       0x3f3177fb, 0xf44d69ff, 0x67bd37ed, 0x05d7d621, 0x5afd8f9e, 0x82d5f60e,
-       0x56f0a56e, 0x3cfdda27, 0x9bbf48af, 0xe5dff86f, 0xb386575c, 0xf8be7e38,
-       0xa7a25d39, 0x69f8bd18, 0xd602f73e, 0x43eb468b, 0x21ee5976, 0x6e717b96,
-       0x252e8ece, 0x5fae9d71, 0x4b69768f, 0x9d15cb0e, 0x6615b8a9, 0x6c0d4d15,
-       0x851f4276, 0x1797b38a, 0xb97f5f47, 0x9bf42d74, 0x9dbd2c12, 0x90b517cf,
-       0xc7e2c7dc, 0x04b49bb6, 0x6a0f1679, 0x3443dc1e, 0xc90e9a95, 0xe2a77bbd,
-       0x61bca83e, 0xd61267a9, 0x2b7bbe8d, 0x7955196f, 0x73fafdbd, 0x7975ca04,
-       0xc9a9b0ce, 0xd7721b7d, 0x80ede5e7, 0xc400d9fe, 0xfaa94e8e, 0xc7951efe,
-       0xbfd7c7e7, 0x46a79c68, 0xf089ce2b, 0x9dc506f8, 0x9f671ce3, 0xf587bb58,
-       0xe9ef86be, 0xb46fbe45, 0x6938752f, 0xfda26ccd, 0xff42b91d, 0xda4b8773,
-       0xf4914750, 0x16e1d2bf, 0x2dc760fa, 0xf0ea1f42, 0x51d03d08, 0x8ed1ed27,
-       0x033fe906, 0x708cff51, 0xe2ec20a0, 0x4a6d7c14, 0x1cce1e9c, 0x9e494f43,
-       0x24a99c3f, 0x991453d3, 0x3cb870ff, 0xa5fa6018, 0x939ca732, 0xc0d1ca8d,
-       0x4b4e68fa, 0xb40ca12f, 0x674a41f9, 0x037bb1bb, 0x3ffbb61e, 0x43daedd4,
-       0x4bcfc533, 0xf33aaf30, 0xdbf846ce, 0x692b2ce5, 0x1ec3cfac, 0xde63dfef,
-       0x0555d3e9, 0x683fd1db, 0xfef95b73, 0x94dc5787, 0xff47bd01, 0xb78d234d,
-       0xb05a28ae, 0x0ae994b9, 0xcc7622bb, 0xc86e6efc, 0x4fc6bb66, 0xb83553e6,
-       0xe3a4d4ba, 0x02b67384, 0xc1aeb7fd, 0xdb261b3e, 0xfc795816, 0x57f7b94a,
-       0xf7a627d8, 0x0aeb29da, 0xd98bd0bc, 0xf3cabef5, 0xa66eff02, 0x80f79e5e,
-       0xdf649dc3, 0x822bcb47, 0x45c59bb0, 0x07cf36b3, 0xd9ba767f, 0xf5bb3fbc,
-       0x51e7c87e, 0xc14e94d3, 0xb8099731, 0xf3fdc410, 0x452e953e, 0x716c30ec,
-       0x7f993299, 0x2b22b538, 0x194eebc0, 0xb8da7df7, 0x7dc633ef, 0xd5fdc3bf,
-       0xfdcbbedc, 0x1fb88768, 0x9e988aed, 0xd085a34d, 0x0da7f05f, 0xef44792f,
-       0xa3a0f9a3, 0x3b0e5a66, 0xd33f025c, 0x81bf27f1, 0x5ca278e5, 0x036ee397,
-       0x6b6e867f, 0x85d7d3e8, 0x858b4f84, 0x4bffb0bc, 0x9f609f58, 0xf5f175b1,
-       0x9bb2ed24, 0xe7c29029, 0x20b6c3a0, 0x895344f4, 0x0ecb5f80, 0x692e08e7,
-       0xcf8ab329, 0x017a644f, 0xabd29e09, 0xae5e7d56, 0x85fc216b, 0x8cfb2475,
-       0x9980d504, 0x399fc4ed, 0xf2c99854, 0x167e188e, 0x49fd0fa3, 0xcff6fc13,
-       0xd7db9a67, 0xfe7cfd14, 0x13854365, 0xa9b15eb0, 0x4eff33b0, 0xe1acfc7d,
-       0x0699fe87, 0x943ce33f, 0x7dc7ca12, 0xce1d8f44, 0x2ee987bf, 0x1ead787b,
-       0x8285c207, 0x5c2e14df, 0x42549c06, 0xd44dc8e7, 0xaf7dfc77, 0x47d027e9,
-       0xfdd079e8, 0xd3af7fc7, 0x6739df4a, 0x50a4f8e2, 0xfd04e2be, 0x3df74181,
-       0x409dc13f, 0x87395f9b, 0xdfa6cb71, 0x3327ab7b, 0xa783586e, 0xff37603b,
-       0xed97dba2, 0xd027ff40, 0x2b11cb5b, 0x0f2b2ec1, 0x0af67ff4, 0x3bf4b78f,
-       0xa8fb80dc, 0xbbe88667, 0xc7dec8f3, 0x7d236f61, 0xae87f166, 0xfe7bbffd,
-       0x25679911, 0x35bd5b98, 0xcfbc4a54, 0xe37fe3d1, 0xb49f6135, 0x6fd015d0,
-       0x39179c57, 0xfeea27ea, 0xa9f1543d, 0xf5bd0037, 0xc46bf81f, 0x0a0cfab5,
-       0x65e96ec0, 0xe46647be, 0x6a86f57b, 0xc771e12a, 0x6ff04ad0, 0x86eac97b,
-       0xcd5efa9d, 0x5f1f84a9, 0xfb14ccf3, 0x3bb1be6b, 0x3d57711f, 0x23cf6fba,
-       0x23679859, 0xc99edbc8, 0xf57ac476, 0xdd163b69, 0x6bb7f72f, 0xf7206fcf,
-       0x64ed1b3e, 0x03cccd3e, 0x99ef35fb, 0xd1f00c1d, 0xe3fafb5e, 0x1a87b895,
-       0xe83db9ed, 0xa6dbb2bf, 0x2d670f42, 0xf8728c9e, 0xbbb359e1, 0xba0ceb17,
-       0x2ea27879, 0x56a45a4f, 0x3bab2fee, 0x37d7711f, 0x80bfe1f1, 0xf75af5dc,
-       0x3ce2cff3, 0x3884ad7b, 0xeb1f6171, 0xe85dd78d, 0x2dc7cf35, 0x9873ec8f,
-       0x94972f60, 0x82cf95ee, 0xef3eaf7f, 0xf45bad92, 0x439de819, 0x11e78fd8,
-       0x6525f2e2, 0x85ff527b, 0x5e25bdde, 0x97c5dfd6, 0x09bd8bea, 0x17f31bf6,
-       0x526b6edf, 0x6024147c, 0xbf19f25c, 0x3b2019c9, 0x8366dfc7, 0x99e878bc,
-       0xbe296791, 0x737ee2fe, 0x6a3ac2d8, 0x94e6d2b6, 0xf83fb8cc, 0x0ebcfef2,
-       0x3ba9f3e7, 0x34c7910a, 0x84ac882f, 0x51b05c5f, 0x7bcf2e4a, 0xbe5f88db,
-       0x2a971b83, 0x4f2ddf25, 0xc7ee854d, 0x38f57357, 0x16c07576, 0x1ddf280c,
-       0x83a3fe8f, 0x8eccef9c, 0x67af77d3, 0x7e71297e, 0xad425b6f, 0x2db7de6e,
-       0x738fc753, 0xe33f7f3c, 0xcfb19558, 0xe79287aa, 0x299152df, 0x8966d3f6,
-       0xc60e2214, 0x88ac2ff8, 0x10a45ae1, 0x5d763578, 0xe013d23d, 0xe08acbc8,
-       0xf2a0ef88, 0xa86e96a1, 0x4fae3b34, 0xa8204a5f, 0x0f7f8c95, 0x7b8c8bb9,
-       0x55ef5e60, 0xdbe57ee8, 0x98d8f36f, 0x246a4b4f, 0xab53791d, 0x7c8e9223,
-       0x46a8e468, 0xcbeb8d3b, 0x199ff18a, 0x4649afdf, 0xf6643fb8, 0x8fdbc6d8,
-       0x6f3c438f, 0x2ab37e1d, 0xfdd0a93e, 0x4d2069a6, 0x646723f6, 0xe9b6ec11,
-       0x3875e4b9, 0x1fc133a7, 0x65760647, 0x8fe2137b, 0xaa3b90cf, 0x137e287c,
-       0x7ca3fafd, 0xa54f81d8, 0xf6ab0acd, 0x65b1af22, 0x3a294d0a, 0xe5b1b01d,
-       0xa7b4befb, 0x5e2e7ec2, 0x1e3f156d, 0x73822251, 0x0aae27b9, 0x23988c3e,
-       0xca8e7382, 0x18fc11ff, 0x09591099, 0xb4adcadc, 0xc9f196af, 0x1e2e9591,
-       0xa0c2b2ff, 0x03e491a7, 0x57322785, 0xb5ea4f03, 0x3711b7d1, 0x09d99769,
-       0x7be9893f, 0xa227a19d, 0x783b86c7, 0xb3410ffc, 0x4e61f10b, 0x0be462a5,
-       0xb5f9f896, 0x908d3fb8, 0xf841c0eb, 0xdddd9367, 0xfdc1a32b, 0xbc1f20af,
-       0xe5dddb33, 0x326f5eba, 0xcacae587, 0xee2d6afc, 0xfbdd3b29, 0xdfcc158f,
-       0x07c91c5f, 0x4bb5b1ce, 0xdd7b6a1c, 0x47fb13ba, 0x807ba3cd, 0xde1c175f,
-       0x9f582b27, 0xada196ad, 0x67d22ca5, 0xa429c8e6, 0x6f604bf8, 0xbdba2382,
-       0xb2ef148d, 0x561e9f08, 0x9767eb2a, 0x4b940f71, 0xa1f603b4, 0xe6fcf7e8,
-       0x00efabc0, 0x6686466f, 0xf58f4e09, 0x4f030ba7, 0x3e3703a6, 0x981ef8e0,
-       0x60ffef13, 0xfa0b5ef5, 0xc3b8bf97, 0x9ef6e112, 0xbbe7c9cd, 0x0cf6ed7c,
-       0x9e3d0bf8, 0xec7b0fd0, 0xeac7a649, 0x4e197605, 0xe88083f2, 0x29c79cfd,
-       0x0e54b7f2, 0xdf0f41b5, 0xd698cbd2, 0x6313e812, 0xa9f331e8, 0xce1fcf41,
-       0xb6f84879, 0x430f0b4e, 0xcc07236f, 0xe4ef7c04, 0x7f7426b8, 0x1aef105a,
-       0xadc700f5, 0x216e3d2c, 0x0fa4b45e, 0x8cbdc4ad, 0x989d5bf4, 0xa7c8e9bf,
-       0xdb3f38f9, 0xdbce3e63, 0x3670e472, 0xf78dcec1, 0x6cc7c704, 0x1ff4b78c,
-       0x24bbc6c9, 0x86aadfd6, 0x4717210a, 0x47e012b8, 0x85afdfac, 0x8b7f210b,
-       0xf1825432, 0xf996e428, 0x49a06b4c, 0xe8aad1ce, 0x34474f7e, 0xf7b1f9c1,
-       0x6e8551f6, 0x250f8caf, 0x1d3707c8, 0xb11254bd, 0xd9a0f1c7, 0xe81395c0,
-       0xdffdd62f, 0x09c0c8b9, 0xbf0cda5e, 0xbc27071f, 0xf5a3dc31, 0xae7dc816,
-       0xb63b9742, 0x3bcaf85e, 0x6de32023, 0x992a5daf, 0xc6758c59, 0xa3c04a3c,
-       0x017c7159, 0x0e0ae40e, 0xf367326c, 0x2bcf7cb9, 0xd25e4eee, 0x96b1b8dc,
-       0xd33ad3a7, 0x6bd0b5fd, 0x5de40513, 0xb1ae5637, 0x8570f476, 0x553ebf7e,
-       0xf6fb8f7f, 0x964ec128, 0x7d6322eb, 0x9bc17cee, 0x5d67f030, 0xf85ac6f5,
-       0x7e597ddf, 0xf9bbe24b, 0xedaff887, 0xadd7a649, 0x339b58df, 0x1efb9f8e,
-       0x126a7eda, 0xd9afcf5d, 0xdb36a3bb, 0x4c7f7d75, 0x98b68bee, 0x49e6959c,
-       0xbe58fa89, 0xb71276b1, 0xaffe52eb, 0x7dcfd0fa, 0x8c3588f1, 0xb5facbb8,
-       0xfdb7fce0, 0x0925bd71, 0x5f807fb7, 0x9d6b0533, 0xfe5bbe33, 0x12ab6db1,
-       0x4f80561e, 0xe2bd5fec, 0x0937ec67, 0x18aa6dfb, 0x5a68a753, 0x37791d3d,
-       0x4f4f5779, 0x6d8c53ac, 0xa8a72819, 0x49bd88b7, 0xd2b87ecb, 0x623e8e3d,
-       0xd4ae6ff3, 0x864d9f64, 0x6fa94f1d, 0x1e15e679, 0x53ccb97f, 0x557ec956,
-       0xbf92a9ae, 0xa6a7dd8f, 0x860fcf52, 0x80bf1db2, 0xcd07453d, 0xb949f84e,
-       0x4f33eba6, 0xfc2efcbd, 0xe1db2f31, 0x357e64ea, 0xbcfa6955, 0xea273663,
-       0x5f63d140, 0xffe07be5, 0xa5cbec5b, 0xd3b262ce, 0x953f1e64, 0x3df0573b,
-       0xc6c7cfb6, 0x7aa5693e, 0x645ed3be, 0x533afefe, 0x3adbe3b1, 0xc51be493,
-       0x12d9c169, 0xf890bf87, 0xe85c1d16, 0xf7c05cd4, 0xd6fe1da0, 0x677ff5fe,
-       0x0c8f0e23, 0x0bba67fe, 0xd3ed75b8, 0xb6cfd874, 0x81d38f81, 0x6606270f,
-       0x1d9ed039, 0x1fd03972, 0x16b8fbad, 0x368cbaf3, 0x8b30675e, 0xf636b19c,
-       0x13d58e7e, 0xcdd1de12, 0x73af6bd0, 0x614b2fdb, 0x82dda9ef, 0xce8efc63,
-       0xd788fc44, 0xe3395c19, 0xeb1265d5, 0xf5b3050c, 0xd45a033a, 0x7acc0a19,
-       0xea34019d, 0x6751680c, 0x0cea3f40, 0x006751a0, 0x68033a8d, 0xa2d019d4,
-       0x2bfe80ce, 0xbcb16ba8, 0x50de4e51, 0xecd1aadf, 0xf40fff82, 0xf5e4416a,
-       0x74d31c0f, 0xc412877a, 0xfbc67f7d, 0xaf460e23, 0x28b075e8, 0xe77953c7,
-       0xfbcb341f, 0x5eda1a20, 0xd6f71337, 0x5571b9af, 0xd9371117, 0xa3cddb14,
-       0x6a1f5127, 0x1bdc53ef, 0x2e5fe85d, 0x5c1b6c72, 0xfa237ef8, 0xd56ecd7b,
-       0x9abafb85, 0x6f97fa8d, 0x58ea57b0, 0x2cc739d5, 0x15fbcf72, 0xeffde1ca,
-       0x64efeab0, 0x2cbdc6bf, 0x9545b0f7, 0x1d6fda3c, 0xcb4bf792, 0x4d738a8b,
-       0x7eda1e42, 0x1382e7cb, 0x9df4b69d, 0xb21fd790, 0xc524d739, 0x7de48f57,
-       0xc174fc7e, 0x45433c8d, 0xa7d5af4c, 0x7b5edf90, 0xf9213801, 0xb47e4248,
-       0x33fcd9d6, 0x5da467e4, 0x7efce133, 0x644ee87e, 0x6d3dd6f9, 0xb09228fe,
-       0x9930737f, 0x6df60df6, 0x99c823cd, 0x034a8fdc, 0x943fb2e2, 0x74aa1fdc,
-       0xc6927d64, 0x3cd1e63f, 0xff755be4, 0x3f40e6b4, 0xdbb977ef, 0x61caf92a,
-       0x2570f78f, 0xb349f1fb, 0x272fea47, 0xbde4d98f, 0x9cfb7e75, 0x8d4bfaa4,
-       0x1fea5536, 0xc48acc1b, 0xdee52bf1, 0xaacbb063, 0xeea57bba, 0x10eb9552,
-       0xe1d98e7f, 0x3786f2d1, 0x5cc377c0, 0x6abfd497, 0xe10bf4ac, 0xf72f7ec7,
-       0x7f16683c, 0x8254e9ab, 0xc9abd32a, 0xad7f816d, 0x3d8a7562, 0x298fed99,
-       0x78ab0fec, 0xbb04c6af, 0x915db0da, 0x100a42bc, 0x8695e7ac, 0xfe0d573e,
-       0xfb0a57eb, 0x3d56bdcb, 0x5553ce0f, 0xc5d79fe1, 0xdfe78b71, 0xfc0b5e47,
-       0x55c71d66, 0x5f671cb4, 0x37bf708f, 0x9ebe6a6d, 0xc072bbe7, 0x3319f57f,
-       0x726a4f01, 0x95e85e7e, 0xfced5f78, 0x095bef84, 0x737da5df, 0xa8e1f7d3,
-       0xc8493e89, 0x759a4f6b, 0xca7d61fc, 0xec14eb7b, 0x5e3eea55, 0x3474cf69,
-       0x8ca2bb49, 0x340bffc4, 0xe02f6f3d, 0x4a6672bb, 0xeb0fa2dd, 0x6eedda6b,
-       0x0b863fe8, 0xbefc8dbb, 0xe796e540, 0x5bd54eed, 0xdc29d30b, 0xca5b8d3f,
-       0xe7617e14, 0x5c71d47c, 0x3d4f3fc2, 0x7d05c0bb, 0x4377697c, 0xc739351f,
-       0x31dde1e6, 0x72ffe0cb, 0xdc55c359, 0x029d2797, 0x438f9fd8, 0x5adfacdd,
-       0x5d41481c, 0x50d1e43d, 0x38a63f27, 0x1ebfaef1, 0x716fb74f, 0x140acfc2,
-       0xb5b7ea27, 0xd935dda9, 0xe676bfcc, 0x9cf0370c, 0x61ea55f1, 0x76eadc23,
-       0x53506b70, 0x6ca6b5f4, 0xff0df3d4, 0x54a6f729, 0xd7f78a4d, 0x1d147e1b,
-       0xf11d22fc, 0x6dd447f5, 0x807f8377, 0x835eee6c, 0xfea0ec3f, 0xbf5269a6,
-       0xe5d1d98d, 0x613b39fd, 0xf4ab5347, 0xef8d8d75, 0x0c4f9199, 0xc1cde6dd,
-       0x7cd72bfe, 0xce5b25be, 0x8cbd7e39, 0xb8033771, 0x165eb63b, 0x463df1c3,
-       0x6b781dfd, 0x26baea32, 0x326baea3, 0xa326baea, 0xea326bae, 0xaea326ba,
-       0xbaea326b, 0x6baea326, 0x26baea32, 0x97ae13a9, 0x878eddf6, 0x08ea1da4,
-       0xbc4278c8, 0xc7eab9b8, 0x55175dd5, 0xa577538d, 0xc4865714, 0xbd7bf65d,
-       0xcea63dde, 0x26aefeca, 0xe0d57bf8, 0x431e7b84, 0x7163d25e, 0x6b5438b3,
-       0x603c16f1, 0x54f07c17, 0x8d6f5b8d, 0xf52ecfe9, 0x9b64cbd9, 0x2ca87b8f,
-       0x5152659a, 0x23ee34c7, 0xdf84ef56, 0x1bf09ce0, 0xd31bf0b4, 0xfcdfb8ec,
-       0x5daec2d6, 0x0109e7aa, 0x726c13c9, 0x32375bbf, 0x2f7d30ae, 0xe5709339,
-       0xc2b831b3, 0x90159a0f, 0x95a0ed63, 0x233f74ba, 0x37254ff8, 0x0e3f9c7f,
-       0x9c7484ce, 0xda1a9699, 0xb5a67d87, 0x1791baa5, 0x9d8bbfb3, 0x88a6dc9d,
-       0x06a1afbf, 0xbc1c77d9, 0x7c9e4749, 0x73d1c4ef, 0xf7f9e1bf, 0xf25d83fe,
-       0xd793ad9d, 0xe0fffa2e, 0xae954d4d, 0x84775f8f, 0x9659e77d, 0x43b654ea,
-       0x16d5578e, 0xb8ba922a, 0x50fe2a9a, 0x58ae3da3, 0xd377a380, 0xb577dc3c,
-       0xc839e1b5, 0x2efec399, 0xa32cdfef, 0x6a1a6bbe, 0xd9f4cbde, 0xbe373cec,
-       0x3dcd4dab, 0x800b0544, 0xb0c57547, 0xadd4b3ab, 0x1963dd60, 0xbf83bfde,
-       0xa7cc5edc, 0x96fee356, 0xb3b69753, 0xce63ee4b, 0x32fbdc42, 0xf51fabab,
-       0x9e6f2d86, 0xb2c27a90, 0xd442d70c, 0x79bcb61b, 0x5c73a75a, 0xe51b8afd,
-       0xabab13b2, 0x66f8827f, 0x109f3eeb, 0x09a1fd67, 0xc0fb7449, 0x09f3eee4,
-       0x3f05ae71, 0x3f4e9df8, 0xafb84c53, 0x5c944356, 0xf21dbbd5, 0x4bfeebf9,
-       0xa8d3cf7f, 0xaaa7c9c4, 0x749c5c74, 0xe7b0c282, 0xf90ec5d1, 0x713397fe,
-       0xdbd43cfd, 0x10b5d8a8, 0xfdaf38f3, 0xe2f8ec35, 0xc1a79ead, 0x7738cf27,
-       0x3579f10e, 0x0d90c758, 0xbbe319ed, 0xdbd529e4, 0x3d36b688, 0x357e9260,
-       0x6df68a58, 0xfa20f435, 0x81762fd9, 0xf393ed4f, 0x3a622c6e, 0xb79a1acf,
-       0xe9788ede, 0x73fe8dd9, 0xec5e9e65, 0xdfeeb637, 0xe58f9c69, 0xc37987d9,
-       0xf9e4aa85, 0x6dea37c3, 0x55c22ecc, 0x371d0e3a, 0x93aca8fc, 0x58e7fbe4,
-       0xa55e39fb, 0xfdf9781a, 0x47bcb372, 0x7e4c4f20, 0x0a5d5eea, 0xa3de5879,
-       0x61afbc86, 0x5299ec9c, 0x7b6ef98f, 0xc77ec80d, 0x7c653b0d, 0xe3af396c,
-       0xa685b4a3, 0x0de404e0, 0x4e0d1e53, 0x7653bc80, 0xdc5cda8c, 0xb51810be,
-       0xe1787f21, 0xe86d476f, 0x7543c17f, 0x56bfe1e3, 0xc2df09ad, 0x3f5951b2,
-       0x921af79d, 0x04e8c277, 0x4d856fe4, 0x6c02596f, 0xe69e73b7, 0xb7f2937d,
-       0xd3638922, 0xfe9a5b0d, 0x87b04aa8, 0xe490cfe9, 0x259d54ab, 0xdd14bee3,
-       0x3e8f7dff, 0x6e8ec2a8, 0x09dcb208, 0x69e737f6, 0x1248e5d3, 0x6bacb0df,
-       0xf3837031, 0x3f71a4b5, 0x3cbe4733, 0xe423c0c5, 0x378c8d8f, 0xbeb7a6fe,
-       0x79c8be42, 0x8c7e18dc, 0x261c314d, 0xebef5dc4, 0x20fc1711, 0xbbdade79,
-       0xf78ad91e, 0x76e3536d, 0xd78fbc8b, 0xdb456df4, 0x259efada, 0x4cbf2487,
-       0x65f9cf9a, 0x9c9d7d12, 0x7b68e463, 0x39adf3f0, 0x76cbece3, 0x0ed12d70,
-       0x37439a4e, 0xd27abde0, 0x480eea9f, 0x0fdd091c, 0x6ad9d97c, 0xecae2377,
-       0xd8a555fa, 0xa9f5b7d7, 0xfaa98f32, 0xa751d947, 0x52540fcc, 0x87e6fc11,
-       0xe1e011da, 0x0c3c24ec, 0x8972dd48, 0xddae7043, 0xadb60778, 0x123e4a71,
-       0x5336ebf3, 0x98adc3e8, 0xef90e597, 0x45b70c11, 0x6f7c2ca6, 0x4aeee29a,
-       0x2ece2bc8, 0x9d041599, 0x830a19dd, 0x15cfe8ef, 0xd5c8ea37, 0xd6ae3a69,
-       0x7bad0da8, 0x352dfc79, 0x5bf1b82c, 0x6ff307e0, 0x7697acb7, 0xb14cd945,
-       0x290a5cdb, 0x7067fffa, 0x3d7bc42d, 0x67ad3df6, 0x20efb05b, 0xf04afbde,
-       0x8fa8b599, 0xe45d95fe, 0x80d50689, 0x33d3cf99, 0x7bb70481, 0xb8942cee,
-       0xc686a513, 0x2cff91fb, 0x6a3a954f, 0x13d704cf, 0xd3da6ef8, 0xf5e4a37c,
-       0xc7a4fe87, 0x29a5d1fb, 0x3d71e46e, 0x711b5cf3, 0x5d479eae, 0xa29afe32,
-       0xa13c0bf3, 0xa967a7eb, 0xe69ece7e, 0xc59f794c, 0x8767a1ee, 0xbfbe3267,
-       0xe5bc3259, 0x1803a8d5, 0x667b1fdf, 0x4fb73f70, 0xde770d29, 0x75733e07,
-       0xb9945779, 0xde4edee4, 0x7b13e379, 0xf1867d74, 0x897dac1d, 0xfefde923,
-       0xcb80febf, 0x002220b3, 0x00000000
-};
-
-#endif /*__BNX2X_INIT_VALUES_H__*/
index ad5ef25add3e0dde70a1ab8c7f2d01c5116dd81d..fbf1352e9c1cbd5701202a65ed95f962c6e6d486 100644 (file)
 
 #include "bnx2x.h"
 #include "bnx2x_init.h"
+#include "bnx2x_init_ops.h"
 #include "bnx2x_dump.h"
 
-#define DRV_MODULE_VERSION     "1.48.105"
-#define DRV_MODULE_RELDATE     "2009/03/02"
+#define DRV_MODULE_VERSION     "1.48.105-1"
+#define DRV_MODULE_RELDATE     "2009/04/22"
 #define BNX2X_BC_VER           0x040200
 
+#include <linux/firmware.h>
+#include "bnx2x_fw_file_hdr.h"
+/* FW files */
+#define FW_FILE_PREFIX_E1              "bnx2x-e1-"
+#define FW_FILE_PREFIX_E1H             "bnx2x-e1h-"
+
 /* Time in jiffies before concluding the transmitter is hung */
 #define TX_TIMEOUT             (5*HZ)
 
@@ -1539,7 +1546,7 @@ static int bnx2x_rx_int(struct bnx2x_fastpath *fp, int budget)
                                                    len, cqe, comp_ring_cons);
 #ifdef BNX2X_STOP_ON_ERROR
                                        if (bp->panic)
-                                               return -EINVAL;
+                                               return 0;
 #endif
 
                                        bnx2x_update_sge_prod(fp,
@@ -5232,13 +5239,15 @@ static void bnx2x_gunzip_end(struct bnx2x *bp)
        }
 }
 
-static int bnx2x_gunzip(struct bnx2x *bp, u8 *zbuf, int len)
+static int bnx2x_gunzip(struct bnx2x *bp, const u8 *zbuf, int len)
 {
        int n, rc;
 
        /* check gzip header */
-       if ((zbuf[0] != 0x1f) || (zbuf[1] != 0x8b) || (zbuf[2] != Z_DEFLATED))
+       if ((zbuf[0] != 0x1f) || (zbuf[1] != 0x8b) || (zbuf[2] != Z_DEFLATED)) {
+               BNX2X_ERR("Bad gzip header\n");
                return -EINVAL;
+       }
 
        n = 10;
 
@@ -5247,7 +5256,7 @@ static int bnx2x_gunzip(struct bnx2x *bp, u8 *zbuf, int len)
        if (zbuf[3] & FNAME)
                while ((zbuf[n++] != 0) && (n < len));
 
-       bp->strm->next_in = zbuf + n;
+       bp->strm->next_in = (typeof(bp->strm->next_in))zbuf + n;
        bp->strm->avail_in = len - n;
        bp->strm->next_out = bp->gunzip_buf;
        bp->strm->avail_out = FW_BUF_SIZE;
@@ -5369,8 +5378,8 @@ static int bnx2x_int_mem_test(struct bnx2x *bp)
        msleep(50);
        REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, 0x03);
        msleep(50);
-       bnx2x_init_block(bp, BRB1_COMMON_START, BRB1_COMMON_END);
-       bnx2x_init_block(bp, PRS_COMMON_START, PRS_COMMON_END);
+       bnx2x_init_block(bp, BRB1_BLOCK, COMMON_STAGE);
+       bnx2x_init_block(bp, PRS_BLOCK, COMMON_STAGE);
 
        DP(NETIF_MSG_HW, "part2\n");
 
@@ -5434,8 +5443,8 @@ static int bnx2x_int_mem_test(struct bnx2x *bp)
        msleep(50);
        REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, 0x03);
        msleep(50);
-       bnx2x_init_block(bp, BRB1_COMMON_START, BRB1_COMMON_END);
-       bnx2x_init_block(bp, PRS_COMMON_START, PRS_COMMON_END);
+       bnx2x_init_block(bp, BRB1_BLOCK, COMMON_STAGE);
+       bnx2x_init_block(bp, PRS_BLOCK, COMMON_STAGE);
 #ifndef BCM_ISCSI
        /* set NIC mode */
        REG_WR(bp, PRS_REG_NIC_MODE, 1);
@@ -5510,7 +5519,7 @@ static int bnx2x_init_common(struct bnx2x *bp)
        REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, 0xffffffff);
        REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET, 0xfffc);
 
-       bnx2x_init_block(bp, MISC_COMMON_START, MISC_COMMON_END);
+       bnx2x_init_block(bp, MISC_BLOCK, COMMON_STAGE);
        if (CHIP_IS_E1H(bp))
                REG_WR(bp, MISC_REG_E1HMF_MODE, IS_E1HMF(bp));
 
@@ -5518,14 +5527,14 @@ static int bnx2x_init_common(struct bnx2x *bp)
        msleep(30);
        REG_WR(bp, MISC_REG_LCPLL_CTRL_REG_2, 0x0);
 
-       bnx2x_init_block(bp, PXP_COMMON_START, PXP_COMMON_END);
+       bnx2x_init_block(bp, PXP_BLOCK, COMMON_STAGE);
        if (CHIP_IS_E1(bp)) {
                /* enable HW interrupt from PXP on USDM overflow
                   bit 16 on INT_MASK_0 */
                REG_WR(bp, PXP_REG_PXP_INT_MASK_0, 0);
        }
 
-       bnx2x_init_block(bp, PXP2_COMMON_START, PXP2_COMMON_END);
+       bnx2x_init_block(bp, PXP2_BLOCK, COMMON_STAGE);
        bnx2x_init_pxp(bp);
 
 #ifdef __BIG_ENDIAN
@@ -5571,60 +5580,60 @@ static int bnx2x_init_common(struct bnx2x *bp)
        REG_WR(bp, PXP2_REG_RQ_DISABLE_INPUTS, 0);
        REG_WR(bp, PXP2_REG_RD_DISABLE_INPUTS, 0);
 
-       bnx2x_init_block(bp, DMAE_COMMON_START, DMAE_COMMON_END);
+       bnx2x_init_block(bp, DMAE_BLOCK, COMMON_STAGE);
 
        /* clean the DMAE memory */
        bp->dmae_ready = 1;
        bnx2x_init_fill(bp, TSEM_REG_PRAM, 0, 8);
 
-       bnx2x_init_block(bp, TCM_COMMON_START, TCM_COMMON_END);
-       bnx2x_init_block(bp, UCM_COMMON_START, UCM_COMMON_END);
-       bnx2x_init_block(bp, CCM_COMMON_START, CCM_COMMON_END);
-       bnx2x_init_block(bp, XCM_COMMON_START, XCM_COMMON_END);
+       bnx2x_init_block(bp, TCM_BLOCK, COMMON_STAGE);
+       bnx2x_init_block(bp, UCM_BLOCK, COMMON_STAGE);
+       bnx2x_init_block(bp, CCM_BLOCK, COMMON_STAGE);
+       bnx2x_init_block(bp, XCM_BLOCK, COMMON_STAGE);
 
        bnx2x_read_dmae(bp, XSEM_REG_PASSIVE_BUFFER, 3);
        bnx2x_read_dmae(bp, CSEM_REG_PASSIVE_BUFFER, 3);
        bnx2x_read_dmae(bp, TSEM_REG_PASSIVE_BUFFER, 3);
        bnx2x_read_dmae(bp, USEM_REG_PASSIVE_BUFFER, 3);
 
-       bnx2x_init_block(bp, QM_COMMON_START, QM_COMMON_END);
+       bnx2x_init_block(bp, QM_BLOCK, COMMON_STAGE);
        /* soft reset pulse */
        REG_WR(bp, QM_REG_SOFT_RESET, 1);
        REG_WR(bp, QM_REG_SOFT_RESET, 0);
 
 #ifdef BCM_ISCSI
-       bnx2x_init_block(bp, TIMERS_COMMON_START, TIMERS_COMMON_END);
+       bnx2x_init_block(bp, TIMERS_BLOCK, COMMON_STAGE);
 #endif
 
-       bnx2x_init_block(bp, DQ_COMMON_START, DQ_COMMON_END);
+       bnx2x_init_block(bp, DQ_BLOCK, COMMON_STAGE);
        REG_WR(bp, DORQ_REG_DPM_CID_OFST, BCM_PAGE_SHIFT);
        if (!CHIP_REV_IS_SLOW(bp)) {
                /* enable hw interrupt from doorbell Q */
                REG_WR(bp, DORQ_REG_DORQ_INT_MASK, 0);
        }
 
-       bnx2x_init_block(bp, BRB1_COMMON_START, BRB1_COMMON_END);
-       bnx2x_init_block(bp, PRS_COMMON_START, PRS_COMMON_END);
+       bnx2x_init_block(bp, BRB1_BLOCK, COMMON_STAGE);
+       bnx2x_init_block(bp, PRS_BLOCK, COMMON_STAGE);
        REG_WR(bp, PRS_REG_A_PRSU_20, 0xf);
        /* set NIC mode */
        REG_WR(bp, PRS_REG_NIC_MODE, 1);
        if (CHIP_IS_E1H(bp))
                REG_WR(bp, PRS_REG_E1HOV_MODE, IS_E1HMF(bp));
 
-       bnx2x_init_block(bp, TSDM_COMMON_START, TSDM_COMMON_END);
-       bnx2x_init_block(bp, CSDM_COMMON_START, CSDM_COMMON_END);
-       bnx2x_init_block(bp, USDM_COMMON_START, USDM_COMMON_END);
-       bnx2x_init_block(bp, XSDM_COMMON_START, XSDM_COMMON_END);
+       bnx2x_init_block(bp, TSDM_BLOCK, COMMON_STAGE);
+       bnx2x_init_block(bp, CSDM_BLOCK, COMMON_STAGE);
+       bnx2x_init_block(bp, USDM_BLOCK, COMMON_STAGE);
+       bnx2x_init_block(bp, XSDM_BLOCK, COMMON_STAGE);
 
        bnx2x_init_fill(bp, TSTORM_INTMEM_ADDR, 0, STORM_INTMEM_SIZE(bp));
        bnx2x_init_fill(bp, USTORM_INTMEM_ADDR, 0, STORM_INTMEM_SIZE(bp));
        bnx2x_init_fill(bp, CSTORM_INTMEM_ADDR, 0, STORM_INTMEM_SIZE(bp));
        bnx2x_init_fill(bp, XSTORM_INTMEM_ADDR, 0, STORM_INTMEM_SIZE(bp));
 
-       bnx2x_init_block(bp, TSEM_COMMON_START, TSEM_COMMON_END);
-       bnx2x_init_block(bp, USEM_COMMON_START, USEM_COMMON_END);
-       bnx2x_init_block(bp, CSEM_COMMON_START, CSEM_COMMON_END);
-       bnx2x_init_block(bp, XSEM_COMMON_START, XSEM_COMMON_END);
+       bnx2x_init_block(bp, TSEM_BLOCK, COMMON_STAGE);
+       bnx2x_init_block(bp, USEM_BLOCK, COMMON_STAGE);
+       bnx2x_init_block(bp, CSEM_BLOCK, COMMON_STAGE);
+       bnx2x_init_block(bp, XSEM_BLOCK, COMMON_STAGE);
 
        /* sync semi rtc */
        REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_CLEAR,
@@ -5632,16 +5641,16 @@ static int bnx2x_init_common(struct bnx2x *bp)
        REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET,
               0x80000000);
 
-       bnx2x_init_block(bp, UPB_COMMON_START, UPB_COMMON_END);
-       bnx2x_init_block(bp, XPB_COMMON_START, XPB_COMMON_END);
-       bnx2x_init_block(bp, PBF_COMMON_START, PBF_COMMON_END);
+       bnx2x_init_block(bp, UPB_BLOCK, COMMON_STAGE);
+       bnx2x_init_block(bp, XPB_BLOCK, COMMON_STAGE);
+       bnx2x_init_block(bp, PBF_BLOCK, COMMON_STAGE);
 
        REG_WR(bp, SRC_REG_SOFT_RST, 1);
        for (i = SRC_REG_KEYRSS0_0; i <= SRC_REG_KEYRSS1_9; i += 4) {
                REG_WR(bp, i, 0xc0cac01a);
                /* TODO: replace with something meaningful */
        }
-       bnx2x_init_block(bp, SRCH_COMMON_START, SRCH_COMMON_END);
+       bnx2x_init_block(bp, SRCH_BLOCK, COMMON_STAGE);
        REG_WR(bp, SRC_REG_SOFT_RST, 0);
 
        if (sizeof(union cdu_context) != 1024)
@@ -5649,7 +5658,7 @@ static int bnx2x_init_common(struct bnx2x *bp)
                printk(KERN_ALERT PFX "please adjust the size of"
                       " cdu_context(%ld)\n", (long)sizeof(union cdu_context));
 
-       bnx2x_init_block(bp, CDU_COMMON_START, CDU_COMMON_END);
+       bnx2x_init_block(bp, CDU_BLOCK, COMMON_STAGE);
        val = (4 << 24) + (0 << 12) + 1024;
        REG_WR(bp, CDU_REG_CDU_GLOBAL_PARAMS, val);
        if (CHIP_IS_E1(bp)) {
@@ -5658,7 +5667,7 @@ static int bnx2x_init_common(struct bnx2x *bp)
                REG_WR(bp, CDU_REG_CDU_DEBUG, 0);
        }
 
-       bnx2x_init_block(bp, CFC_COMMON_START, CFC_COMMON_END);
+       bnx2x_init_block(bp, CFC_BLOCK, COMMON_STAGE);
        REG_WR(bp, CFC_REG_INIT_REG, 0x7FF);
        /* enable context validation interrupt from CFC */
        REG_WR(bp, CFC_REG_CFC_INT_MASK, 0);
@@ -5666,20 +5675,25 @@ static int bnx2x_init_common(struct bnx2x *bp)
        /* set the thresholds to prevent CFC/CDU race */
        REG_WR(bp, CFC_REG_DEBUG0, 0x20020000);
 
-       bnx2x_init_block(bp, HC_COMMON_START, HC_COMMON_END);
-       bnx2x_init_block(bp, MISC_AEU_COMMON_START, MISC_AEU_COMMON_END);
+       bnx2x_init_block(bp, HC_BLOCK, COMMON_STAGE);
+       bnx2x_init_block(bp, MISC_AEU_BLOCK, COMMON_STAGE);
 
        /* PXPCS COMMON comes here */
+       bnx2x_init_block(bp, PXPCS_BLOCK, COMMON_STAGE);
        /* Reset PCIE errors for debug */
        REG_WR(bp, 0x2814, 0xffffffff);
        REG_WR(bp, 0x3820, 0xffffffff);
 
        /* EMAC0 COMMON comes here */
+       bnx2x_init_block(bp, EMAC0_BLOCK, COMMON_STAGE);
        /* EMAC1 COMMON comes here */
+       bnx2x_init_block(bp, EMAC1_BLOCK, COMMON_STAGE);
        /* DBU COMMON comes here */
+       bnx2x_init_block(bp, DBU_BLOCK, COMMON_STAGE);
        /* DBG COMMON comes here */
+       bnx2x_init_block(bp, DBG_BLOCK, COMMON_STAGE);
 
-       bnx2x_init_block(bp, NIG_COMMON_START, NIG_COMMON_END);
+       bnx2x_init_block(bp, NIG_BLOCK, COMMON_STAGE);
        if (CHIP_IS_E1H(bp)) {
                REG_WR(bp, NIG_REG_LLH_MF_MODE, IS_E1HMF(bp));
                REG_WR(bp, NIG_REG_LLH_E1HOV_MODE, IS_E1HMF(bp));
@@ -5763,6 +5777,7 @@ static int bnx2x_init_common(struct bnx2x *bp)
 static int bnx2x_init_port(struct bnx2x *bp)
 {
        int port = BP_PORT(bp);
+       int init_stage = port ? PORT1_STAGE : PORT0_STAGE;
        u32 low, high;
        u32 val;
 
@@ -5771,7 +5786,9 @@ static int bnx2x_init_port(struct bnx2x *bp)
        REG_WR(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4, 0);
 
        /* Port PXP comes here */
+       bnx2x_init_block(bp, PXP_BLOCK, init_stage);
        /* Port PXP2 comes here */
+       bnx2x_init_block(bp, PXP2_BLOCK, init_stage);
 #ifdef BCM_ISCSI
        /* Port0  1
         * Port1  385 */
@@ -5798,21 +5815,19 @@ static int bnx2x_init_port(struct bnx2x *bp)
        REG_WR(bp, PXP2_REG_PSWRQ_SRC0_L2P + func*4, PXP_ONE_ILT(i));
 #endif
        /* Port CMs come here */
-       bnx2x_init_block(bp, (port ? XCM_PORT1_START : XCM_PORT0_START),
-                            (port ? XCM_PORT1_END : XCM_PORT0_END));
+       bnx2x_init_block(bp, XCM_BLOCK, init_stage);
 
        /* Port QM comes here */
 #ifdef BCM_ISCSI
        REG_WR(bp, TM_REG_LIN0_SCAN_TIME + func*4, 1024/64*20);
        REG_WR(bp, TM_REG_LIN0_MAX_ACTIVE_CID + func*4, 31);
 
-       bnx2x_init_block(bp, func ? TIMERS_PORT1_START : TIMERS_PORT0_START,
-                            func ? TIMERS_PORT1_END : TIMERS_PORT0_END);
+       bnx2x_init_block(bp, TIMERS_BLOCK, init_stage);
 #endif
        /* Port DQ comes here */
+       bnx2x_init_block(bp, DQ_BLOCK, init_stage);
 
-       bnx2x_init_block(bp, (port ? BRB1_PORT1_START : BRB1_PORT0_START),
-                            (port ? BRB1_PORT1_END : BRB1_PORT0_END));
+       bnx2x_init_block(bp, BRB1_BLOCK, init_stage);
        if (CHIP_REV_IS_SLOW(bp) && !CHIP_IS_E1H(bp)) {
                /* no pause for emulation and FPGA */
                low = 0;
@@ -5837,25 +5852,27 @@ static int bnx2x_init_port(struct bnx2x *bp)
 
 
        /* Port PRS comes here */
+       bnx2x_init_block(bp, PRS_BLOCK, init_stage);
        /* Port TSDM comes here */
+       bnx2x_init_block(bp, TSDM_BLOCK, init_stage);
        /* Port CSDM comes here */
+       bnx2x_init_block(bp, CSDM_BLOCK, init_stage);
        /* Port USDM comes here */
+       bnx2x_init_block(bp, USDM_BLOCK, init_stage);
        /* Port XSDM comes here */
+       bnx2x_init_block(bp, XSDM_BLOCK, init_stage);
 
-       bnx2x_init_block(bp, port ? TSEM_PORT1_START : TSEM_PORT0_START,
-                            port ? TSEM_PORT1_END : TSEM_PORT0_END);
-       bnx2x_init_block(bp, port ? USEM_PORT1_START : USEM_PORT0_START,
-                            port ? USEM_PORT1_END : USEM_PORT0_END);
-       bnx2x_init_block(bp, port ? CSEM_PORT1_START : CSEM_PORT0_START,
-                            port ? CSEM_PORT1_END : CSEM_PORT0_END);
-       bnx2x_init_block(bp, port ? XSEM_PORT1_START : XSEM_PORT0_START,
-                            port ? XSEM_PORT1_END : XSEM_PORT0_END);
+       bnx2x_init_block(bp, TSEM_BLOCK, init_stage);
+       bnx2x_init_block(bp, USEM_BLOCK, init_stage);
+       bnx2x_init_block(bp, CSEM_BLOCK, init_stage);
+       bnx2x_init_block(bp, XSEM_BLOCK, init_stage);
 
        /* Port UPB comes here */
+       bnx2x_init_block(bp, UPB_BLOCK, init_stage);
        /* Port XPB comes here */
+       bnx2x_init_block(bp, XPB_BLOCK, init_stage);
 
-       bnx2x_init_block(bp, port ? PBF_PORT1_START : PBF_PORT0_START,
-                            port ? PBF_PORT1_END : PBF_PORT0_END);
+       bnx2x_init_block(bp, PBF_BLOCK, init_stage);
 
        /* configure PBF to work without PAUSE mtu 9000 */
        REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 0);
@@ -5885,18 +5902,17 @@ static int bnx2x_init_port(struct bnx2x *bp)
        /* Port SRCH comes here */
 #endif
        /* Port CDU comes here */
+       bnx2x_init_block(bp, CDU_BLOCK, init_stage);
        /* Port CFC comes here */
+       bnx2x_init_block(bp, CFC_BLOCK, init_stage);
 
        if (CHIP_IS_E1(bp)) {
                REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, 0);
                REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, 0);
        }
-       bnx2x_init_block(bp, port ? HC_PORT1_START : HC_PORT0_START,
-                            port ? HC_PORT1_END : HC_PORT0_END);
+       bnx2x_init_block(bp, HC_BLOCK, init_stage);
 
-       bnx2x_init_block(bp, port ? MISC_AEU_PORT1_START :
-                                   MISC_AEU_PORT0_START,
-                            port ? MISC_AEU_PORT1_END : MISC_AEU_PORT0_END);
+       bnx2x_init_block(bp, MISC_AEU_BLOCK, init_stage);
        /* init aeu_mask_attn_func_0/1:
         *  - SF mode: bits 3-7 are masked. only bits 0-2 are in use
         *  - MF mode: bit 3 is masked. bits 0-2 are in use as in SF
@@ -5905,13 +5921,17 @@ static int bnx2x_init_port(struct bnx2x *bp)
               (IS_E1HMF(bp) ? 0xF7 : 0x7));
 
        /* Port PXPCS comes here */
+       bnx2x_init_block(bp, PXPCS_BLOCK, init_stage);
        /* Port EMAC0 comes here */
+       bnx2x_init_block(bp, EMAC0_BLOCK, init_stage);
        /* Port EMAC1 comes here */
+       bnx2x_init_block(bp, EMAC1_BLOCK, init_stage);
        /* Port DBU comes here */
+       bnx2x_init_block(bp, DBU_BLOCK, init_stage);
        /* Port DBG comes here */
+       bnx2x_init_block(bp, DBG_BLOCK, init_stage);
 
-       bnx2x_init_block(bp, port ? NIG_PORT1_START : NIG_PORT0_START,
-                            port ? NIG_PORT1_END : NIG_PORT0_END);
+       bnx2x_init_block(bp, NIG_BLOCK, init_stage);
 
        REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 1);
 
@@ -5931,7 +5951,9 @@ static int bnx2x_init_port(struct bnx2x *bp)
        }
 
        /* Port MCP comes here */
+       bnx2x_init_block(bp, MCP_BLOCK, init_stage);
        /* Port DMAE comes here */
+       bnx2x_init_block(bp, DMAE_BLOCK, init_stage);
 
        switch (XGXS_EXT_PHY_TYPE(bp->link_params.ext_phy_config)) {
        case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
@@ -6036,7 +6058,7 @@ static int bnx2x_init_func(struct bnx2x *bp)
        if (CHIP_IS_E1H(bp)) {
                for (i = 0; i < 9; i++)
                        bnx2x_init_block(bp,
-                                        cm_start[func][i], cm_end[func][i]);
+                                        cm_blocks[i], FUNC0_STAGE + func);
 
                REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port*8, 1);
                REG_WR(bp, NIG_REG_LLH0_FUNC_VLAN_ID + port*8, bp->e1hov);
@@ -6049,7 +6071,7 @@ static int bnx2x_init_func(struct bnx2x *bp)
                REG_WR(bp, HC_REG_LEADING_EDGE_0 + port*8, 0);
                REG_WR(bp, HC_REG_TRAILING_EDGE_0 + port*8, 0);
        }
-       bnx2x_init_block(bp, hc_limits[func][0], hc_limits[func][1]);
+       bnx2x_init_block(bp, HC_BLOCK, FUNC0_STAGE + func);
 
        /* Reset PCIE errors for debug */
        REG_WR(bp, 0x2114, 0xffffffff);
@@ -10595,7 +10617,6 @@ static int bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
        mmiowb();
 
        fp->tx_bd_prod += nbd;
-       dev->trans_start = jiffies;
 
        if (unlikely(bnx2x_tx_avail(fp) < MAX_SKB_FRAGS + 3)) {
                /* We want bnx2x_tx_int to "see" the updated tx_bd_prod
@@ -11082,6 +11103,190 @@ static int __devinit bnx2x_get_pcie_speed(struct bnx2x *bp)
        val = (val & PCICFG_LINK_SPEED) >> PCICFG_LINK_SPEED_SHIFT;
        return val;
 }
+static int __devinit bnx2x_check_firmware(struct bnx2x *bp)
+{
+       struct bnx2x_fw_file_hdr *fw_hdr;
+       struct bnx2x_fw_file_section *sections;
+       u16 *ops_offsets;
+       u32 offset, len, num_ops;
+       int i;
+       const struct firmware *firmware = bp->firmware;
+       const u8 * fw_ver;
+
+       if (firmware->size < sizeof(struct bnx2x_fw_file_hdr))
+               return -EINVAL;
+
+       fw_hdr = (struct bnx2x_fw_file_hdr *)firmware->data;
+       sections = (struct bnx2x_fw_file_section *)fw_hdr;
+
+       /* Make sure none of the offsets and sizes make us read beyond
+        * the end of the firmware data */
+       for (i = 0; i < sizeof(*fw_hdr) / sizeof(*sections); i++) {
+               offset = be32_to_cpu(sections[i].offset);
+               len = be32_to_cpu(sections[i].len);
+               if (offset + len > firmware->size) {
+                       printk(KERN_ERR PFX "Section %d length is out of bounds\n", i);
+                       return -EINVAL;
+               }
+       }
+
+       /* Likewise for the init_ops offsets */
+       offset = be32_to_cpu(fw_hdr->init_ops_offsets.offset);
+       ops_offsets = (u16 *)(firmware->data + offset);
+       num_ops = be32_to_cpu(fw_hdr->init_ops.len) / sizeof(struct raw_op);
+
+       for (i = 0; i < be32_to_cpu(fw_hdr->init_ops_offsets.len) / 2; i++) {
+               if (be16_to_cpu(ops_offsets[i]) > num_ops) {
+                       printk(KERN_ERR PFX "Section offset %d is out of bounds\n", i);
+                       return -EINVAL;
+               }
+       }
+
+       /* Check FW version */
+       offset = be32_to_cpu(fw_hdr->fw_version.offset);
+       fw_ver = firmware->data + offset;
+       if ((fw_ver[0] != BCM_5710_FW_MAJOR_VERSION) ||
+           (fw_ver[1] != BCM_5710_FW_MINOR_VERSION) ||
+           (fw_ver[2] != BCM_5710_FW_REVISION_VERSION) ||
+           (fw_ver[3] != BCM_5710_FW_ENGINEERING_VERSION)) {
+               printk(KERN_ERR PFX "Bad FW version:%d.%d.%d.%d."
+                                   " Should be %d.%d.%d.%d\n",
+                      fw_ver[0], fw_ver[1], fw_ver[2],
+                      fw_ver[3], BCM_5710_FW_MAJOR_VERSION,
+                      BCM_5710_FW_MINOR_VERSION,
+                      BCM_5710_FW_REVISION_VERSION,
+                      BCM_5710_FW_ENGINEERING_VERSION);
+                return -EINVAL;
+       }
+
+       return 0;
+}
+
+static void inline be32_to_cpu_n(const u8 *_source, u8 *_target, u32 n)
+{
+       u32 i;
+       const __be32 *source = (const __be32*)_source;
+       u32 *target = (u32*)_target;
+
+       for (i = 0; i < n/4; i++)
+               target[i] = be32_to_cpu(source[i]);
+}
+
+/*
+   Ops array is stored in the following format:
+   {op(8bit), offset(24bit, big endian), data(32bit, big endian)}
+ */
+static void inline bnx2x_prep_ops(const u8 *_source, u8 *_target, u32 n)
+{
+       u32 i, j, tmp;
+       const __be32 *source = (const __be32*)_source;
+       struct raw_op *target = (struct raw_op*)_target;
+
+       for (i = 0, j = 0; i < n/8; i++, j+=2) {
+               tmp = be32_to_cpu(source[j]);
+               target[i].op = (tmp >> 24) & 0xff;
+               target[i].offset =  tmp & 0xffffff;
+               target[i].raw_data = be32_to_cpu(source[j+1]);
+       }
+}
+static void inline be16_to_cpu_n(const u8 *_source, u8 *_target, u32 n)
+{
+       u32 i;
+       u16 *target = (u16*)_target;
+       const __be16 *source = (const __be16*)_source;
+
+       for (i = 0; i < n/2; i++)
+               target[i] = be16_to_cpu(source[i]);
+}
+
+#define BNX2X_ALLOC_AND_SET(arr, lbl, func) \
+       do {   \
+               u32 len = be32_to_cpu(fw_hdr->arr.len);   \
+               bp->arr = kmalloc(len, GFP_KERNEL);  \
+               if (!bp->arr) { \
+                       printk(KERN_ERR PFX "Failed to allocate %d bytes for "#arr"\n", len); \
+                       goto lbl; \
+               } \
+               func(bp->firmware->data + \
+                       be32_to_cpu(fw_hdr->arr.offset), \
+                       (u8*)bp->arr, len); \
+       } while (0)
+
+
+static int __devinit bnx2x_init_firmware(struct bnx2x *bp, struct device *dev)
+{
+       char fw_file_name[40] = {0};
+        int rc, offset;
+       struct bnx2x_fw_file_hdr *fw_hdr;
+
+       /* Create a FW file name */
+       if (CHIP_IS_E1(bp))
+                offset = sprintf(fw_file_name, FW_FILE_PREFIX_E1);
+       else
+               offset = sprintf(fw_file_name, FW_FILE_PREFIX_E1H);
+
+       sprintf(fw_file_name + offset, "%d.%d.%d.%d.fw",
+               BCM_5710_FW_MAJOR_VERSION,
+                BCM_5710_FW_MINOR_VERSION,
+                BCM_5710_FW_REVISION_VERSION,
+                BCM_5710_FW_ENGINEERING_VERSION);
+
+       printk(KERN_INFO PFX "Loading %s\n", fw_file_name);
+
+       rc = request_firmware(&bp->firmware, fw_file_name, dev);
+       if (rc) {
+               printk(KERN_ERR PFX "Can't load firmware file %s\n", fw_file_name);
+               goto request_firmware_exit;
+       }
+
+       rc = bnx2x_check_firmware(bp);
+       if (rc) {
+               printk(KERN_ERR PFX "Corrupt firmware file %s\n", fw_file_name);
+               goto request_firmware_exit;
+       }
+
+       fw_hdr = (struct bnx2x_fw_file_hdr *)bp->firmware->data;
+
+       /* Initialize the pointers to the init arrays */
+       /* Blob */
+       BNX2X_ALLOC_AND_SET(init_data, request_firmware_exit, be32_to_cpu_n);
+
+       /* Opcodes */
+       BNX2X_ALLOC_AND_SET(init_ops, init_ops_alloc_err, bnx2x_prep_ops);
+
+       /* Offsets */
+       BNX2X_ALLOC_AND_SET(init_ops_offsets, init_offsets_alloc_err, be16_to_cpu_n);
+
+       /* STORMs firmware */
+       bp->tsem_int_table_data = bp->firmware->data +
+               be32_to_cpu(fw_hdr->tsem_int_table_data.offset);
+       bp->tsem_pram_data      = bp->firmware->data +
+               be32_to_cpu(fw_hdr->tsem_pram_data.offset);
+       bp->usem_int_table_data = bp->firmware->data +
+               be32_to_cpu(fw_hdr->usem_int_table_data.offset);
+       bp->usem_pram_data      = bp->firmware->data +
+               be32_to_cpu(fw_hdr->usem_pram_data.offset);
+       bp->xsem_int_table_data = bp->firmware->data +
+               be32_to_cpu(fw_hdr->xsem_int_table_data.offset);
+       bp->xsem_pram_data      = bp->firmware->data +
+               be32_to_cpu(fw_hdr->xsem_pram_data.offset);
+       bp->csem_int_table_data = bp->firmware->data +
+               be32_to_cpu(fw_hdr->csem_int_table_data.offset);
+       bp->csem_pram_data      = bp->firmware->data +
+               be32_to_cpu(fw_hdr->csem_pram_data.offset);
+
+       return 0;
+init_offsets_alloc_err:
+       kfree(bp->init_ops);
+init_ops_alloc_err:
+       kfree(bp->init_data);
+request_firmware_exit:
+       release_firmware(bp->firmware);
+
+       return rc;
+}
+
+
 
 static int __devinit bnx2x_init_one(struct pci_dev *pdev,
                                    const struct pci_device_id *ent)
@@ -11116,6 +11321,13 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev,
        if (rc)
                goto init_one_exit;
 
+       /* Set init arrays */
+       rc = bnx2x_init_firmware(bp, &pdev->dev);
+       if (rc) {
+               printk(KERN_ERR PFX "Error loading firmware\n");
+               goto init_one_exit;
+       }
+
        rc = register_netdev(dev);
        if (rc) {
                dev_err(&pdev->dev, "Cannot register net device\n");
@@ -11163,6 +11375,11 @@ static void __devexit bnx2x_remove_one(struct pci_dev *pdev)
 
        unregister_netdev(dev);
 
+       kfree(bp->init_ops_offsets);
+       kfree(bp->init_ops);
+       kfree(bp->init_data);
+       release_firmware(bp->firmware);
+
        if (bp->regview)
                iounmap(bp->regview);
 
@@ -11412,13 +11629,20 @@ static struct pci_driver bnx2x_pci_driver = {
 
 static int __init bnx2x_init(void)
 {
+       int ret;
+
        bnx2x_wq = create_singlethread_workqueue("bnx2x");
        if (bnx2x_wq == NULL) {
                printk(KERN_ERR PFX "Cannot create workqueue\n");
                return -ENOMEM;
        }
 
-       return pci_register_driver(&bnx2x_pci_driver);
+       ret = pci_register_driver(&bnx2x_pci_driver);
+       if (ret) {
+               printk(KERN_ERR PFX "Cannot register driver\n");
+               destroy_workqueue(bnx2x_wq);
+       }
+       return ret;
 }
 
 static void __exit bnx2x_cleanup(void)
@@ -11431,3 +11655,4 @@ static void __exit bnx2x_cleanup(void)
 module_init(bnx2x_init);
 module_exit(bnx2x_cleanup);
 
+
index faf094abef7f2fb105e531bbc62704e8110ee514..d4b570886c6e979c50ac08130b406e6d8fea7cb9 100644 (file)
@@ -1850,9 +1850,10 @@ static u16 aggregator_identifier;
  * Can be called only after the mac address of the bond is set.
  */
 void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution, int lacp_fast)
-{                         
+{
        // check that the bond is not initialized yet
-       if (MAC_ADDRESS_COMPARE(&(BOND_AD_INFO(bond).system.sys_mac_addr), &(bond->dev->dev_addr))) {
+       if (MAC_ADDRESS_COMPARE(&(BOND_AD_INFO(bond).system.sys_mac_addr),
+                               bond->dev->dev_addr)) {
 
                aggregator_identifier = 0;
 
index a306230381c8f69c0ba83523430a16cfb1bef8a3..2c46a154f2c604d956b0d1ee2384b1280eb95288 100644 (file)
 #include <asm/byteorder.h>
 #include <linux/skbuff.h>
 #include <linux/netdevice.h>
+#include <linux/if_ether.h>
 
 // General definitions
-#define BOND_ETH_P_LACPDU       0x8809
-#define PKT_TYPE_LACPDU         cpu_to_be16(BOND_ETH_P_LACPDU)
+#define PKT_TYPE_LACPDU         cpu_to_be16(ETH_P_SLOW)
 #define AD_TIMER_INTERVAL       100 /*msec*/
 
 #define MULTICAST_LACPDU_ADDR    {0x01, 0x80, 0xC2, 0x00, 0x00, 0x02}
index 74824028f85c988b370f587e7934828f03c4d6bc..d927f71af8a31b9096b4ded0f9b18ab47a847116 100644 (file)
 #include <linux/ctype.h>
 #include <linux/inet.h>
 #include <linux/bitops.h>
+#include <linux/io.h>
 #include <asm/system.h>
-#include <asm/io.h>
 #include <asm/dma.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 #include <linux/errno.h>
 #include <linux/netdevice.h>
 #include <linux/inetdevice.h>
@@ -89,19 +89,19 @@ static int max_bonds        = BOND_DEFAULT_MAX_BONDS;
 static int num_grat_arp = 1;
 static int num_unsol_na = 1;
 static int miimon      = BOND_LINK_MON_INTERV;
-static int updelay     = 0;
-static int downdelay   = 0;
+static int updelay;
+static int downdelay;
 static int use_carrier = 1;
-static char *mode      = NULL;
-static char *primary   = NULL;
-static char *lacp_rate = NULL;
-static char *ad_select  = NULL;
-static char *xmit_hash_policy = NULL;
+static char *mode;
+static char *primary;
+static char *lacp_rate;
+static char *ad_select;
+static char *xmit_hash_policy;
 static int arp_interval = BOND_LINK_ARP_INTERV;
-static char *arp_ip_target[BOND_MAX_ARP_TARGETS] = { NULL, };
-static char *arp_validate = NULL;
-static char *fail_over_mac = NULL;
-struct bond_params bonding_defaults;
+static char *arp_ip_target[BOND_MAX_ARP_TARGETS];
+static char *arp_validate;
+static char *fail_over_mac;
+static struct bond_params bonding_defaults;
 
 module_param(max_bonds, int, 0);
 MODULE_PARM_DESC(max_bonds, "Max number of bonded devices");
@@ -151,14 +151,14 @@ static const char * const version =
 LIST_HEAD(bond_dev_list);
 
 #ifdef CONFIG_PROC_FS
-static struct proc_dir_entry *bond_proc_dir = NULL;
+static struct proc_dir_entry *bond_proc_dir;
 #endif
 
-static __be32 arp_target[BOND_MAX_ARP_TARGETS] = { 0, } ;
-static int arp_ip_count        = 0;
+static __be32 arp_target[BOND_MAX_ARP_TARGETS];
+static int arp_ip_count;
 static int bond_mode   = BOND_MODE_ROUNDROBIN;
-static int xmit_hashtype= BOND_XMIT_POLICY_LAYER2;
-static int lacp_fast   = 0;
+static int xmit_hashtype = BOND_XMIT_POLICY_LAYER2;
+static int lacp_fast;
 
 
 const struct bond_parm_tbl bond_lacp_tbl[] = {
@@ -210,6 +210,7 @@ struct bond_parm_tbl ad_select_tbl[] = {
 /*-------------------------- Forward declarations ---------------------------*/
 
 static void bond_send_gratuitous_arp(struct bonding *bond);
+static int bond_init(struct net_device *bond_dev);
 static void bond_deinit(struct net_device *bond_dev);
 
 /*---------------------------- General routines -----------------------------*/
@@ -221,7 +222,7 @@ static const char *bond_mode_name(int mode)
                [BOND_MODE_ACTIVEBACKUP] = "fault-tolerance (active-backup)",
                [BOND_MODE_XOR] = "load balancing (xor)",
                [BOND_MODE_BROADCAST] = "fault-tolerance (broadcast)",
-               [BOND_MODE_8023AD]= "IEEE 802.3ad Dynamic link aggregation",
+               [BOND_MODE_8023AD] = "IEEE 802.3ad Dynamic link aggregation",
                [BOND_MODE_TLB] = "transmit load balancing",
                [BOND_MODE_ALB] = "adaptive load balancing",
        };
@@ -246,12 +247,11 @@ static int bond_add_vlan(struct bonding *bond, unsigned short vlan_id)
        struct vlan_entry *vlan;
 
        pr_debug("bond: %s, vlan id %d\n",
-               (bond ? bond->dev->name: "None"), vlan_id);
+               (bond ? bond->dev->name : "None"), vlan_id);
 
        vlan = kzalloc(sizeof(struct vlan_entry), GFP_KERNEL);
-       if (!vlan) {
+       if (!vlan)
                return -ENOMEM;
-       }
 
        INIT_LIST_HEAD(&vlan->vlan_list);
        vlan->vlan_id = vlan_id;
@@ -351,16 +351,15 @@ static int bond_has_challenged_slaves(struct bonding *bond)
  *
  * Returns %NULL if list is empty, bond->next_vlan if @curr is %NULL,
  * or @curr->next otherwise (even if it is @curr itself again).
- * 
+ *
  * Caller must hold bond->lock
  */
 struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr)
 {
        struct vlan_entry *next, *last;
 
-       if (list_empty(&bond->vlan_list)) {
+       if (list_empty(&bond->vlan_list))
                return NULL;
-       }
 
        if (!curr) {
                next = list_entry(bond->vlan_list.next,
@@ -382,11 +381,11 @@ struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr)
 
 /**
  * bond_dev_queue_xmit - Prepare skb for xmit.
- * 
+ *
  * @bond: bond device that got this skb for tx.
  * @skb: hw accel VLAN tagged skb to transmit
  * @slave_dev: slave that is supposed to xmit this skbuff
- * 
+ *
  * When the bond gets an skb to transmit that is
  * already hardware accelerated VLAN tagged, and it
  * needs to relay this skb to a slave that is not
@@ -394,7 +393,8 @@ struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr)
  * i.e. strip the hwaccel tag and re-insert it as part
  * of the payload.
  */
-int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_device *slave_dev)
+int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb,
+                       struct net_device *slave_dev)
 {
        unsigned short uninitialized_var(vlan_id);
 
@@ -428,7 +428,7 @@ int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_de
  * b. The operation is protected by the RTNL semaphore in the 8021q code,
  * c. Holding a lock with BH disabled while directly calling a base driver
  *    entry point is generally a BAD idea.
- * 
+ *
  * The design of synchronization/protection for this operation in the 8021q
  * module is good for one or more VLAN devices over a single physical device
  * and cannot be extended for a teaming solution like bonding, so there is a
@@ -443,7 +443,8 @@ int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_de
  * @bond_dev: bonding net device that got called
  * @grp: vlan group being registered
  */
-static void bond_vlan_rx_register(struct net_device *bond_dev, struct vlan_group *grp)
+static void bond_vlan_rx_register(struct net_device *bond_dev,
+                                 struct vlan_group *grp)
 {
        struct bonding *bond = netdev_priv(bond_dev);
        struct slave *slave;
@@ -485,7 +486,7 @@ static void bond_vlan_rx_add_vid(struct net_device *bond_dev, uint16_t vid)
 
        res = bond_add_vlan(bond, vid);
        if (res) {
-               printk(KERN_ERR DRV_NAME
+               pr_err(DRV_NAME
                       ": %s: Error: Failed to add vlan id %d\n",
                       bond_dev->name, vid);
        }
@@ -520,7 +521,7 @@ static void bond_vlan_rx_kill_vid(struct net_device *bond_dev, uint16_t vid)
 
        res = bond_del_vlan(bond, vid);
        if (res) {
-               printk(KERN_ERR DRV_NAME
+               pr_err(DRV_NAME
                       ": %s: Error: Failed to remove vlan id %d\n",
                       bond_dev->name, vid);
        }
@@ -551,7 +552,8 @@ out:
        write_unlock_bh(&bond->lock);
 }
 
-static void bond_del_vlans_from_slave(struct bonding *bond, struct net_device *slave_dev)
+static void bond_del_vlans_from_slave(struct bonding *bond,
+                                     struct net_device *slave_dev)
 {
        const struct net_device_ops *slave_ops = slave_dev->netdev_ops;
        struct vlan_entry *vlan;
@@ -673,7 +675,7 @@ static int bond_update_speed_duplex(struct slave *slave)
  * if <dev> supports MII link status reporting, check its link status.
  *
  * We either do MII/ETHTOOL ioctls, or check netif_carrier_ok(),
- * depening upon the setting of the use_carrier parameter.
+ * depending upon the setting of the use_carrier parameter.
  *
  * Return either BMSR_LSTATUS, meaning that the link is up (or we
  * can't tell and just pretend it is), or 0, meaning that the link is
@@ -685,16 +687,29 @@ static int bond_update_speed_duplex(struct slave *slave)
  * It'd be nice if there was a good way to tell if a driver supports
  * netif_carrier, but there really isn't.
  */
-static int bond_check_dev_link(struct bonding *bond, struct net_device *slave_dev, int reporting)
+static int bond_check_dev_link(struct bonding *bond,
+                              struct net_device *slave_dev, int reporting)
 {
        const struct net_device_ops *slave_ops = slave_dev->netdev_ops;
-       static int (* ioctl)(struct net_device *, struct ifreq *, int);
+       static int (*ioctl)(struct net_device *, struct ifreq *, int);
        struct ifreq ifr;
        struct mii_ioctl_data *mii;
 
        if (bond->params.use_carrier)
                return netif_carrier_ok(slave_dev) ? BMSR_LSTATUS : 0;
 
+       /* Try to get link status using Ethtool first. */
+       if (slave_dev->ethtool_ops) {
+               if (slave_dev->ethtool_ops->get_link) {
+                       u32 link;
+
+                       link = slave_dev->ethtool_ops->get_link(slave_dev);
+
+                       return link ? BMSR_LSTATUS : 0;
+               }
+       }
+
+       /* Ethtool can't be used, fallback to MII ioctls. */
        ioctl = slave_ops->ndo_do_ioctl;
        if (ioctl) {
                /* TODO: set pointer to correct ioctl on a per team member */
@@ -714,23 +729,8 @@ static int bond_check_dev_link(struct bonding *bond, struct net_device *slave_de
                mii = if_mii(&ifr);
                if (IOCTL(slave_dev, &ifr, SIOCGMIIPHY) == 0) {
                        mii->reg_num = MII_BMSR;
-                       if (IOCTL(slave_dev, &ifr, SIOCGMIIREG) == 0) {
-                               return (mii->val_out & BMSR_LSTATUS);
-                       }
-               }
-       }
-
-       /*
-        * Some drivers cache ETHTOOL_GLINK for a period of time so we only
-        * attempt to get link status from it if the above MII ioctls fail.
-        */
-       if (slave_dev->ethtool_ops) {
-               if (slave_dev->ethtool_ops->get_link) {
-                       u32 link;
-
-                       link = slave_dev->ethtool_ops->get_link(slave_dev);
-
-                       return link ? BMSR_LSTATUS : 0;
+                       if (IOCTL(slave_dev, &ifr, SIOCGMIIREG) == 0)
+                               return mii->val_out & BMSR_LSTATUS;
                }
        }
 
@@ -740,7 +740,7 @@ static int bond_check_dev_link(struct bonding *bond, struct net_device *slave_de
         * cannot report link status).  If not reporting, pretend
         * we're ok.
         */
-       return (reporting ? -1 : BMSR_LSTATUS);
+       return reporting ? -1 : BMSR_LSTATUS;
 }
 
 /*----------------------------- Multicast list ------------------------------*/
@@ -748,7 +748,8 @@ static int bond_check_dev_link(struct bonding *bond, struct net_device *slave_de
 /*
  * Returns 0 if dmi1 and dmi2 are the same, non-0 otherwise
  */
-static inline int bond_is_dmi_same(struct dev_mc_list *dmi1, struct dev_mc_list *dmi2)
+static inline int bond_is_dmi_same(const struct dev_mc_list *dmi1,
+                                  const struct dev_mc_list *dmi2)
 {
        return memcmp(dmi1->dmi_addr, dmi2->dmi_addr, dmi1->dmi_addrlen) == 0 &&
                        dmi1->dmi_addrlen == dmi2->dmi_addrlen;
@@ -757,14 +758,14 @@ static inline int bond_is_dmi_same(struct dev_mc_list *dmi1, struct dev_mc_list
 /*
  * returns dmi entry if found, NULL otherwise
  */
-static struct dev_mc_list *bond_mc_list_find_dmi(struct dev_mc_list *dmi, struct dev_mc_list *mc_list)
+static struct dev_mc_list *bond_mc_list_find_dmi(struct dev_mc_list *dmi,
+                                                struct dev_mc_list *mc_list)
 {
        struct dev_mc_list *idmi;
 
        for (idmi = mc_list; idmi; idmi = idmi->next) {
-               if (bond_is_dmi_same(dmi, idmi)) {
+               if (bond_is_dmi_same(dmi, idmi))
                        return idmi;
-               }
        }
 
        return NULL;
@@ -826,15 +827,14 @@ static void bond_mc_add(struct bonding *bond, void *addr, int alen)
 {
        if (USES_PRIMARY(bond->params.mode)) {
                /* write lock already acquired */
-               if (bond->curr_active_slave) {
+               if (bond->curr_active_slave)
                        dev_mc_add(bond->curr_active_slave->dev, addr, alen, 0);
-               }
        } else {
                struct slave *slave;
                int i;
-               bond_for_each_slave(bond, slave, i) {
+
+               bond_for_each_slave(bond, slave, i)
                        dev_mc_add(slave->dev, addr, alen, 0);
-               }
        }
 }
 
@@ -846,9 +846,9 @@ static void bond_mc_delete(struct bonding *bond, void *addr, int alen)
 {
        if (USES_PRIMARY(bond->params.mode)) {
                /* write lock already acquired */
-               if (bond->curr_active_slave) {
-                       dev_mc_delete(bond->curr_active_slave->dev, addr, alen, 0);
-               }
+               if (bond->curr_active_slave)
+                       dev_mc_delete(bond->curr_active_slave->dev, addr,
+                                     alen, 0);
        } else {
                struct slave *slave;
                int i;
@@ -872,9 +872,8 @@ static void bond_resend_igmp_join_requests(struct bonding *bond)
        rcu_read_lock();
        in_dev = __in_dev_get_rcu(bond->dev);
        if (in_dev) {
-               for (im = in_dev->mc_list; im; im = im->next) {
+               for (im = in_dev->mc_list; im; im = im->next)
                        ip_mc_rejoin_group(im);
-               }
        }
 
        rcu_read_unlock();
@@ -893,7 +892,8 @@ static void bond_mc_list_destroy(struct bonding *bond)
                kfree(dmi);
                dmi = bond->mc_list;
        }
-        bond->mc_list = NULL;
+
+       bond->mc_list = NULL;
 }
 
 /*
@@ -926,14 +926,14 @@ static int bond_mc_list_copy(struct dev_mc_list *mc_list, struct bonding *bond,
 /*
  * flush all members of flush->mc_list from device dev->mc_list
  */
-static void bond_mc_list_flush(struct net_device *bond_dev, struct net_device *slave_dev)
+static void bond_mc_list_flush(struct net_device *bond_dev,
+                              struct net_device *slave_dev)
 {
        struct bonding *bond = netdev_priv(bond_dev);
        struct dev_mc_list *dmi;
 
-       for (dmi = bond_dev->mc_list; dmi; dmi = dmi->next) {
+       for (dmi = bond_dev->mc_list; dmi; dmi = dmi->next)
                dev_mc_delete(slave_dev, dmi->dmi_addr, dmi->dmi_addrlen, 0);
-       }
 
        if (bond->params.mode == BOND_MODE_8023AD) {
                /* del lacpdu mc addr from mc list */
@@ -950,44 +950,40 @@ static void bond_mc_list_flush(struct net_device *bond_dev, struct net_device *s
  * old active slaves (if any) according to the multicast mode, and
  * promiscuous flags unconditionally.
  */
-static void bond_mc_swap(struct bonding *bond, struct slave *new_active, struct slave *old_active)
+static void bond_mc_swap(struct bonding *bond, struct slave *new_active,
+                        struct slave *old_active)
 {
        struct dev_mc_list *dmi;
 
-       if (!USES_PRIMARY(bond->params.mode)) {
+       if (!USES_PRIMARY(bond->params.mode))
                /* nothing to do -  mc list is already up-to-date on
                 * all slaves
                 */
                return;
-       }
 
        if (old_active) {
-               if (bond->dev->flags & IFF_PROMISC) {
+               if (bond->dev->flags & IFF_PROMISC)
                        dev_set_promiscuity(old_active->dev, -1);
-               }
 
-               if (bond->dev->flags & IFF_ALLMULTI) {
+               if (bond->dev->flags & IFF_ALLMULTI)
                        dev_set_allmulti(old_active->dev, -1);
-               }
 
-               for (dmi = bond->dev->mc_list; dmi; dmi = dmi->next) {
-                       dev_mc_delete(old_active->dev, dmi->dmi_addr, dmi->dmi_addrlen, 0);
-               }
+               for (dmi = bond->dev->mc_list; dmi; dmi = dmi->next)
+                       dev_mc_delete(old_active->dev, dmi->dmi_addr,
+                                     dmi->dmi_addrlen, 0);
        }
 
        if (new_active) {
                /* FIXME: Signal errors upstream. */
-               if (bond->dev->flags & IFF_PROMISC) {
+               if (bond->dev->flags & IFF_PROMISC)
                        dev_set_promiscuity(new_active->dev, 1);
-               }
 
-               if (bond->dev->flags & IFF_ALLMULTI) {
+               if (bond->dev->flags & IFF_ALLMULTI)
                        dev_set_allmulti(new_active->dev, 1);
-               }
 
-               for (dmi = bond->dev->mc_list; dmi; dmi = dmi->next) {
-                       dev_mc_add(new_active->dev, dmi->dmi_addr, dmi->dmi_addrlen, 0);
-               }
+               for (dmi = bond->dev->mc_list; dmi; dmi = dmi->next)
+                       dev_mc_add(new_active->dev, dmi->dmi_addr,
+                                  dmi->dmi_addrlen, 0);
                bond_resend_igmp_join_requests(bond);
        }
 }
@@ -1041,7 +1037,7 @@ static void bond_do_fail_over_mac(struct bonding *bond,
 
                rv = dev_set_mac_address(new_active->dev, &saddr);
                if (rv) {
-                       printk(KERN_ERR DRV_NAME
+                       pr_err(DRV_NAME
                               ": %s: Error %d setting MAC of slave %s\n",
                               bond->dev->name, -rv, new_active->dev->name);
                        goto out;
@@ -1055,7 +1051,7 @@ static void bond_do_fail_over_mac(struct bonding *bond,
 
                rv = dev_set_mac_address(old_active->dev, &saddr);
                if (rv)
-                       printk(KERN_ERR DRV_NAME
+                       pr_err(DRV_NAME
                               ": %s: Error %d setting MAC of slave %s\n",
                               bond->dev->name, -rv, new_active->dev->name);
 out:
@@ -1063,7 +1059,7 @@ out:
                write_lock_bh(&bond->curr_slave_lock);
                break;
        default:
-               printk(KERN_ERR DRV_NAME
+               pr_err(DRV_NAME
                       ": %s: bond_do_fail_over_mac impossible: bad policy %d\n",
                       bond->dev->name, bond->params.fail_over_mac);
                break;
@@ -1088,17 +1084,17 @@ static struct slave *bond_find_best_slave(struct bonding *bond)
        new_active = old_active = bond->curr_active_slave;
 
        if (!new_active) { /* there were no active slaves left */
-               if (bond->slave_cnt > 0) {  /* found one slave */
+               if (bond->slave_cnt > 0)   /* found one slave */
                        new_active = bond->first_slave;
-               } else {
+               else
                        return NULL; /* still no slave, return NULL */
-               }
        }
 
-       /* first try the primary link; if arping, a link must tx/rx traffic
-        * before it can be considered the curr_active_slave - also, we would skip
-        * slaves between the curr_active_slave and primary_slave that may be up
-        * and able to arp
+       /*
+        * first try the primary link; if arping, a link must tx/rx
+        * traffic before it can be considered the curr_active_slave.
+        * also, we would skip slaves between the curr_active_slave
+        * and primary_slave that may be up and able to arp
         */
        if ((bond->primary_slave) &&
            (!bond->params.arp_interval) &&
@@ -1146,16 +1142,15 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
 {
        struct slave *old_active = bond->curr_active_slave;
 
-       if (old_active == new_active) {
+       if (old_active == new_active)
                return;
-       }
 
        if (new_active) {
                new_active->jiffies = jiffies;
 
                if (new_active->link == BOND_LINK_BACK) {
                        if (USES_PRIMARY(bond->params.mode)) {
-                               printk(KERN_INFO DRV_NAME
+                               pr_info(DRV_NAME
                                       ": %s: making interface %s the new "
                                       "active one %d ms earlier.\n",
                                       bond->dev->name, new_active->dev->name,
@@ -1165,15 +1160,14 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
                        new_active->delay = 0;
                        new_active->link = BOND_LINK_UP;
 
-                       if (bond->params.mode == BOND_MODE_8023AD) {
+                       if (bond->params.mode == BOND_MODE_8023AD)
                                bond_3ad_handle_link_change(new_active, BOND_LINK_UP);
-                       }
 
                        if (bond_is_lb(bond))
                                bond_alb_handle_link_change(bond, new_active, BOND_LINK_UP);
                } else {
                        if (USES_PRIMARY(bond->params.mode)) {
-                               printk(KERN_INFO DRV_NAME
+                               pr_info(DRV_NAME
                                       ": %s: making interface %s the new "
                                       "active one.\n",
                                       bond->dev->name, new_active->dev->name);
@@ -1181,9 +1175,8 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
                }
        }
 
-       if (USES_PRIMARY(bond->params.mode)) {
+       if (USES_PRIMARY(bond->params.mode))
                bond_mc_swap(bond, new_active, old_active);
-       }
 
        if (bond_is_lb(bond)) {
                bond_alb_handle_active_change(bond, new_active);
@@ -1196,9 +1189,8 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
        }
 
        if (bond->params.mode == BOND_MODE_ACTIVEBACKUP) {
-               if (old_active) {
+               if (old_active)
                        bond_set_slave_inactive_flags(old_active);
-               }
 
                if (new_active) {
                        bond_set_slave_active_flags(new_active);
@@ -1228,7 +1220,7 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
  * bond_select_active_slave - select a new active slave, if needed
  * @bond: our bonding struct
  *
- * This functions shoud be called when one of the following occurs:
+ * This functions should be called when one of the following occurs:
  * - The old curr_active_slave has been released or lost its link.
  * - The primary_slave has got its link back.
  * - A slave has got its link back and there's no old curr_active_slave.
@@ -1248,11 +1240,11 @@ void bond_select_active_slave(struct bonding *bond)
                        return;
 
                if (netif_carrier_ok(bond->dev)) {
-                       printk(KERN_INFO DRV_NAME
+                       pr_info(DRV_NAME
                               ": %s: first active interface up!\n",
                               bond->dev->name);
                } else {
-                       printk(KERN_INFO DRV_NAME ": %s: "
+                       pr_info(DRV_NAME ": %s: "
                               "now running without any active interface !\n",
                               bond->dev->name);
                }
@@ -1294,13 +1286,11 @@ static void bond_attach_slave(struct bonding *bond, struct slave *new_slave)
  */
 static void bond_detach_slave(struct bonding *bond, struct slave *slave)
 {
-       if (slave->next) {
+       if (slave->next)
                slave->next->prev = slave->prev;
-       }
 
-       if (slave->prev) {
+       if (slave->prev)
                slave->prev->next = slave->next;
-       }
 
        if (bond->first_slave == slave) { /* slave is the first slave */
                if (bond->slave_cnt > 1) { /* there are more slave */
@@ -1331,7 +1321,7 @@ static int bond_sethwaddr(struct net_device *bond_dev,
        (NETIF_F_VLAN_CHALLENGED | NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_TX | \
         NETIF_F_HW_VLAN_FILTER)
 
-/* 
+/*
  * Compute the common dev->feature set available to all slaves.  Some
  * feature bits are managed elsewhere, so preserve those feature bits
  * on the master device.
@@ -1399,14 +1389,14 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
 
        if (!bond->params.use_carrier && slave_dev->ethtool_ops == NULL &&
                slave_ops->ndo_do_ioctl == NULL) {
-               printk(KERN_WARNING DRV_NAME
+               pr_warning(DRV_NAME
                       ": %s: Warning: no link monitoring support for %s\n",
                       bond_dev->name, slave_dev->name);
        }
 
        /* bond must be initialized by bond_open() before enslaving */
        if (!(bond_dev->flags & IFF_UP)) {
-               printk(KERN_WARNING DRV_NAME
+               pr_warning(DRV_NAME
                        " %s: master_dev is not up in bond_enslave\n",
                        bond_dev->name);
        }
@@ -1422,14 +1412,14 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
        if (slave_dev->features & NETIF_F_VLAN_CHALLENGED) {
                pr_debug("%s: NETIF_F_VLAN_CHALLENGED\n", slave_dev->name);
                if (!list_empty(&bond->vlan_list)) {
-                       printk(KERN_ERR DRV_NAME
+                       pr_err(DRV_NAME
                               ": %s: Error: cannot enslave VLAN "
                               "challenged slave %s on VLAN enabled "
                               "bond %s\n", bond_dev->name, slave_dev->name,
                               bond_dev->name);
                        return -EPERM;
                } else {
-                       printk(KERN_WARNING DRV_NAME
+                       pr_warning(DRV_NAME
                               ": %s: Warning: enslaved VLAN challenged "
                               "slave %s. Adding VLANs will be blocked as "
                               "long as %s is part of bond %s\n",
@@ -1449,12 +1439,12 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
 
        /*
         * Old ifenslave binaries are no longer supported.  These can
-        * be identified with moderate accurary by the state of the slave:
+        * be identified with moderate accuracy by the state of the slave:
         * the current ifenslave will set the interface down prior to
         * enslaving it; the old ifenslave will not.
         */
        if ((slave_dev->flags & IFF_UP)) {
-               printk(KERN_ERR DRV_NAME ": %s is up. "
+               pr_err(DRV_NAME ": %s is up. "
                       "This may be due to an out of date ifenslave.\n",
                       slave_dev->name);
                res = -EPERM;
@@ -1472,7 +1462,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
                if (slave_dev->type != ARPHRD_ETHER)
                        bond_setup_by_slave(bond_dev, slave_dev);
        } else if (bond_dev->type != slave_dev->type) {
-               printk(KERN_ERR DRV_NAME ": %s ether type (%d) is different "
+               pr_err(DRV_NAME ": %s ether type (%d) is different "
                        "from other slaves (%d), can not enslave it.\n",
                        slave_dev->name,
                        slave_dev->type, bond_dev->type);
@@ -1482,14 +1472,14 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
 
        if (slave_ops->ndo_set_mac_address == NULL) {
                if (bond->slave_cnt == 0) {
-                       printk(KERN_WARNING DRV_NAME
+                       pr_warning(DRV_NAME
                               ": %s: Warning: The first slave device "
                               "specified does not support setting the MAC "
                               "address. Setting fail_over_mac to active.",
                               bond_dev->name);
                        bond->params.fail_over_mac = BOND_FOM_ACTIVE;
                } else if (bond->params.fail_over_mac != BOND_FOM_ACTIVE) {
-                       printk(KERN_ERR DRV_NAME
+                       pr_err(DRV_NAME
                                ": %s: Error: The slave device specified "
                                "does not support setting the MAC address, "
                                "but fail_over_mac is not set to active.\n"
@@ -1539,7 +1529,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
        /* open the slave since the application closed it */
        res = dev_open(slave_dev);
        if (res) {
-               pr_debug("Openning slave %s failed\n", slave_dev->name);
+               pr_debug("Opening slave %s failed\n", slave_dev->name);
                goto err_unset_master;
        }
 
@@ -1551,9 +1541,8 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
                 * it might fail and we do not want to have to undo everything
                 */
                res = bond_alb_init_slave(bond, new_slave);
-               if (res) {
+               if (res)
                        goto err_close;
-               }
        }
 
        /* If the mode USES_PRIMARY, then the new slave gets the
@@ -1578,9 +1567,9 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
 
                netif_addr_lock_bh(bond_dev);
                /* upload master's mc_list to new slave */
-               for (dmi = bond_dev->mc_list; dmi; dmi = dmi->next) {
-                       dev_mc_add (slave_dev, dmi->dmi_addr, dmi->dmi_addrlen, 0);
-               }
+               for (dmi = bond_dev->mc_list; dmi; dmi = dmi->next)
+                       dev_mc_add(slave_dev, dmi->dmi_addr,
+                                  dmi->dmi_addrlen, 0);
                netif_addr_unlock_bh(bond_dev);
        }
 
@@ -1621,7 +1610,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
                         * supported); thus, we don't need to change
                         * the messages for netif_carrier.
                         */
-                       printk(KERN_WARNING DRV_NAME
+                       pr_warning(DRV_NAME
                               ": %s: Warning: MII and ETHTOOL support not "
                               "available for interface %s, and "
                               "arp_interval/arp_ip_target module parameters "
@@ -1630,7 +1619,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
                               bond_dev->name, slave_dev->name);
                } else if (link_reporting == -1) {
                        /* unable get link status using mii/ethtool */
-                       printk(KERN_WARNING DRV_NAME
+                       pr_warning(DRV_NAME
                               ": %s: Warning: can't get link status from "
                               "interface %s; the network driver associated "
                               "with this interface does not support MII or "
@@ -1662,13 +1651,13 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
 
        if (bond_update_speed_duplex(new_slave) &&
            (new_slave->link != BOND_LINK_DOWN)) {
-               printk(KERN_WARNING DRV_NAME
+               pr_warning(DRV_NAME
                       ": %s: Warning: failed to get speed and duplex from %s, "
                       "assumed to be 100Mb/sec and Full.\n",
                       bond_dev->name, new_slave->dev->name);
 
                if (bond->params.mode == BOND_MODE_8023AD) {
-                       printk(KERN_WARNING DRV_NAME
+                       pr_warning(DRV_NAME
                               ": %s: Warning: Operation of 802.3ad mode requires ETHTOOL "
                               "support in base driver for proper aggregator "
                               "selection.\n", bond_dev->name);
@@ -1677,9 +1666,8 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
 
        if (USES_PRIMARY(bond->params.mode) && bond->params.primary[0]) {
                /* if there is a primary slave, remember it */
-               if (strcmp(bond->params.primary, new_slave->dev->name) == 0) {
+               if (strcmp(bond->params.primary, new_slave->dev->name) == 0)
                        bond->primary_slave = new_slave;
-               }
        }
 
        write_lock_bh(&bond->curr_slave_lock);
@@ -1726,9 +1714,9 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
                 * anyway (it holds no special properties of the bond device),
                 * so we can change it without calling change_active_interface()
                 */
-               if (!bond->curr_active_slave) {
+               if (!bond->curr_active_slave)
                        bond->curr_active_slave = new_slave;
-               }
+
                break;
        } /* switch(bond_mode) */
 
@@ -1742,7 +1730,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
        if (res)
                goto err_close;
 
-       printk(KERN_INFO DRV_NAME
+       pr_info(DRV_NAME
               ": %s: enslaving %s as a%s interface with a%s link.\n",
               bond_dev->name, slave_dev->name,
               new_slave->state == BOND_STATE_ACTIVE ? "n active" : " backup",
@@ -1774,7 +1762,7 @@ err_free:
 
 err_undo_flags:
        bond_dev->features = old_features;
+
        return res;
 }
 
@@ -1799,7 +1787,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
        /* slave is not a slave or master is not master of this slave */
        if (!(slave_dev->flags & IFF_SLAVE) ||
            (slave_dev->master != bond_dev)) {
-               printk(KERN_ERR DRV_NAME
+               pr_err(DRV_NAME
                       ": %s: Error: cannot release %s.\n",
                       bond_dev->name, slave_dev->name);
                return -EINVAL;
@@ -1810,7 +1798,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
        slave = bond_get_slave_by_dev(bond, slave_dev);
        if (!slave) {
                /* not a slave of this bond */
-               printk(KERN_INFO DRV_NAME
+               pr_info(DRV_NAME
                       ": %s: %s not enslaved\n",
                       bond_dev->name, slave_dev->name);
                write_unlock_bh(&bond->lock);
@@ -1821,7 +1809,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
                mac_addr_differ = memcmp(bond_dev->dev_addr, slave->perm_hwaddr,
                                         ETH_ALEN);
                if (!mac_addr_differ && (bond->slave_cnt > 1))
-                       printk(KERN_WARNING DRV_NAME
+                       pr_warning(DRV_NAME
                               ": %s: Warning: the permanent HWaddr of %s - "
                               "%pM - is still in use by %s. "
                               "Set the HWaddr of %s to a different address "
@@ -1839,7 +1827,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
                bond_3ad_unbind_slave(slave);
        }
 
-       printk(KERN_INFO DRV_NAME
+       pr_info(DRV_NAME
               ": %s: releasing %s interface %s\n",
               bond_dev->name,
               (slave->state == BOND_STATE_ACTIVE)
@@ -1855,13 +1843,11 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
 
        bond_compute_features(bond);
 
-       if (bond->primary_slave == slave) {
+       if (bond->primary_slave == slave)
                bond->primary_slave = NULL;
-       }
 
-       if (oldcurrent == slave) {
+       if (oldcurrent == slave)
                bond_change_active_slave(bond, NULL);
-       }
 
        if (bond_is_lb(bond)) {
                /* Must be called only after the slave has been
@@ -1903,18 +1889,18 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
                if (list_empty(&bond->vlan_list)) {
                        bond_dev->features |= NETIF_F_VLAN_CHALLENGED;
                } else {
-                       printk(KERN_WARNING DRV_NAME
+                       pr_warning(DRV_NAME
                               ": %s: Warning: clearing HW address of %s while it "
                               "still has VLANs.\n",
                               bond_dev->name, bond_dev->name);
-                       printk(KERN_WARNING DRV_NAME
+                       pr_warning(DRV_NAME
                               ": %s: When re-adding slaves, make sure the bond's "
                               "HW address matches its VLANs'.\n",
                               bond_dev->name);
                }
        } else if ((bond_dev->features & NETIF_F_VLAN_CHALLENGED) &&
                   !bond_has_challenged_slaves(bond)) {
-               printk(KERN_INFO DRV_NAME
+               pr_info(DRV_NAME
                       ": %s: last VLAN challenged slave %s "
                       "left bond %s. VLAN blocking is removed\n",
                       bond_dev->name, slave_dev->name, bond_dev->name);
@@ -1934,14 +1920,12 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
         */
        if (!USES_PRIMARY(bond->params.mode)) {
                /* unset promiscuity level from slave */
-               if (bond_dev->flags & IFF_PROMISC) {
+               if (bond_dev->flags & IFF_PROMISC)
                        dev_set_promiscuity(slave_dev, -1);
-               }
 
                /* unset allmulti level from slave */
-               if (bond_dev->flags & IFF_ALLMULTI) {
+               if (bond_dev->flags & IFF_ALLMULTI)
                        dev_set_allmulti(slave_dev, -1);
-               }
 
                /* flush master's mc_list from slave */
                netif_addr_lock_bh(bond_dev);
@@ -1974,41 +1958,36 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
 * Destroy a bonding device.
 * Must be under rtnl_lock when this function is called.
 */
-void bond_destroy(struct bonding *bond)
-{
-       bond_deinit(bond->dev);
-       bond_destroy_sysfs_entry(bond);
-       unregister_netdevice(bond->dev);
-}
-
-static void bond_destructor(struct net_device *bond_dev)
+static void bond_uninit(struct net_device *bond_dev)
 {
        struct bonding *bond = netdev_priv(bond_dev);
 
+       bond_deinit(bond_dev);
+       bond_destroy_sysfs_entry(bond);
+
        if (bond->wq)
                destroy_workqueue(bond->wq);
 
        netif_addr_lock_bh(bond_dev);
        bond_mc_list_destroy(bond);
        netif_addr_unlock_bh(bond_dev);
-
-       free_netdev(bond_dev);
 }
 
 /*
-* First release a slave and than destroy the bond if no more slaves iare left.
+* First release a slave and than destroy the bond if no more slaves are left.
 * Must be under rtnl_lock when this function is called.
 */
-int  bond_release_and_destroy(struct net_device *bond_dev, struct net_device *slave_dev)
+int  bond_release_and_destroy(struct net_device *bond_dev,
+                             struct net_device *slave_dev)
 {
        struct bonding *bond = netdev_priv(bond_dev);
        int ret;
 
        ret = bond_release(bond_dev, slave_dev);
        if ((ret == 0) && (bond->slave_cnt == 0)) {
-               printk(KERN_INFO DRV_NAME ": %s: destroying bond %s.\n",
+               pr_info(DRV_NAME ": %s: destroying bond %s.\n",
                       bond_dev->name, bond_dev->name);
-               bond_destroy(bond);
+               unregister_netdevice(bond_dev);
        }
        return ret;
 }
@@ -2027,9 +2006,8 @@ static int bond_release_all(struct net_device *bond_dev)
 
        netif_carrier_off(bond_dev);
 
-       if (bond->slave_cnt == 0) {
+       if (bond->slave_cnt == 0)
                goto out;
-       }
 
        bond->current_arp_slave = NULL;
        bond->primary_slave = NULL;
@@ -2039,9 +2017,8 @@ static int bond_release_all(struct net_device *bond_dev)
                /* Inform AD package of unbinding of slave
                 * before slave is detached from the list.
                 */
-               if (bond->params.mode == BOND_MODE_8023AD) {
+               if (bond->params.mode == BOND_MODE_8023AD)
                        bond_3ad_unbind_slave(slave);
-               }
 
                slave_dev = slave->dev;
                bond_detach_slave(bond, slave);
@@ -2070,14 +2047,12 @@ static int bond_release_all(struct net_device *bond_dev)
                 */
                if (!USES_PRIMARY(bond->params.mode)) {
                        /* unset promiscuity level from slave */
-                       if (bond_dev->flags & IFF_PROMISC) {
+                       if (bond_dev->flags & IFF_PROMISC)
                                dev_set_promiscuity(slave_dev, -1);
-                       }
 
                        /* unset allmulti level from slave */
-                       if (bond_dev->flags & IFF_ALLMULTI) {
+                       if (bond_dev->flags & IFF_ALLMULTI)
                                dev_set_allmulti(slave_dev, -1);
-                       }
 
                        /* flush master's mc_list from slave */
                        netif_addr_lock_bh(bond_dev);
@@ -2112,20 +2087,20 @@ static int bond_release_all(struct net_device *bond_dev)
         */
        memset(bond_dev->dev_addr, 0, bond_dev->addr_len);
 
-       if (list_empty(&bond->vlan_list)) {
+       if (list_empty(&bond->vlan_list))
                bond_dev->features |= NETIF_F_VLAN_CHALLENGED;
-       else {
-               printk(KERN_WARNING DRV_NAME
+       else {
+               pr_warning(DRV_NAME
                       ": %s: Warning: clearing HW address of %s while it "
                       "still has VLANs.\n",
                       bond_dev->name, bond_dev->name);
-               printk(KERN_WARNING DRV_NAME
+               pr_warning(DRV_NAME
                       ": %s: When re-adding slaves, make sure the bond's "
                       "HW address matches its VLANs'.\n",
                       bond_dev->name);
        }
 
-       printk(KERN_INFO DRV_NAME
+       pr_info(DRV_NAME
               ": %s: released all slaves\n",
               bond_dev->name);
 
@@ -2143,8 +2118,8 @@ out:
  *  - <slave_dev> is already active.
  *  - The link state of <slave_dev> is not BOND_LINK_UP.
  *  - <slave_dev> is not running.
- * In these cases, this fuction does nothing.
- * In the other cases, currnt_slave pointer is changed and 0 is returned.
+ * In these cases, this function does nothing.
+ * In the other cases, current_slave pointer is changed and 0 is returned.
  */
 static int bond_ioctl_change_active(struct net_device *bond_dev, struct net_device *slave_dev)
 {
@@ -2153,15 +2128,12 @@ static int bond_ioctl_change_active(struct net_device *bond_dev, struct net_devi
        struct slave *new_active = NULL;
        int res = 0;
 
-       if (!USES_PRIMARY(bond->params.mode)) {
+       if (!USES_PRIMARY(bond->params.mode))
                return -EINVAL;
-       }
 
        /* Verify that master_dev is indeed the master of slave_dev */
-       if (!(slave_dev->flags & IFF_SLAVE) ||
-           (slave_dev->master != bond_dev)) {
+       if (!(slave_dev->flags & IFF_SLAVE) || (slave_dev->master != bond_dev))
                return -EINVAL;
-       }
 
        read_lock(&bond->lock);
 
@@ -2186,9 +2158,8 @@ static int bond_ioctl_change_active(struct net_device *bond_dev, struct net_devi
                write_lock_bh(&bond->curr_slave_lock);
                bond_change_active_slave(bond, new_active);
                write_unlock_bh(&bond->curr_slave_lock);
-       } else {
+       } else
                res = -EINVAL;
-       }
 
        read_unlock(&bond->lock);
 
@@ -2240,6 +2211,9 @@ static int bond_miimon_inspect(struct bonding *bond)
 {
        struct slave *slave;
        int i, link_state, commit = 0;
+       bool ignore_updelay;
+
+       ignore_updelay = !bond->curr_active_slave ? true : false;
 
        bond_for_each_slave(bond, slave, i) {
                slave->new_link = BOND_LINK_NOCHANGE;
@@ -2254,7 +2228,7 @@ static int bond_miimon_inspect(struct bonding *bond)
                        slave->link = BOND_LINK_FAIL;
                        slave->delay = bond->params.downdelay;
                        if (slave->delay) {
-                               printk(KERN_INFO DRV_NAME
+                               pr_info(DRV_NAME
                                       ": %s: link status down for %s"
                                       "interface %s, disabling it in %d ms.\n",
                                       bond->dev->name,
@@ -2273,7 +2247,7 @@ static int bond_miimon_inspect(struct bonding *bond)
                                 */
                                slave->link = BOND_LINK_UP;
                                slave->jiffies = jiffies;
-                               printk(KERN_INFO DRV_NAME
+                               pr_info(DRV_NAME
                                       ": %s: link status up again after %d "
                                       "ms for interface %s.\n",
                                       bond->dev->name,
@@ -2300,10 +2274,11 @@ static int bond_miimon_inspect(struct bonding *bond)
                        slave->delay = bond->params.updelay;
 
                        if (slave->delay) {
-                               printk(KERN_INFO DRV_NAME
+                               pr_info(DRV_NAME
                                       ": %s: link status up for "
                                       "interface %s, enabling it in %d ms.\n",
                                       bond->dev->name, slave->dev->name,
+                                      ignore_updelay ? 0 :
                                       bond->params.updelay *
                                       bond->params.miimon);
                        }
@@ -2311,7 +2286,7 @@ static int bond_miimon_inspect(struct bonding *bond)
                case BOND_LINK_BACK:
                        if (!link_state) {
                                slave->link = BOND_LINK_DOWN;
-                               printk(KERN_INFO DRV_NAME
+                               pr_info(DRV_NAME
                                       ": %s: link status down again after %d "
                                       "ms for interface %s.\n",
                                       bond->dev->name,
@@ -2322,9 +2297,13 @@ static int bond_miimon_inspect(struct bonding *bond)
                                continue;
                        }
 
+                       if (ignore_updelay)
+                               slave->delay = 0;
+
                        if (slave->delay <= 0) {
                                slave->new_link = BOND_LINK_UP;
                                commit++;
+                               ignore_updelay = false;
                                continue;
                        }
 
@@ -2361,7 +2340,7 @@ static void bond_miimon_commit(struct bonding *bond)
                                slave->state = BOND_STATE_BACKUP;
                        }
 
-                       printk(KERN_INFO DRV_NAME
+                       pr_info(DRV_NAME
                               ": %s: link status definitely "
                               "up for interface %s.\n",
                               bond->dev->name, slave->dev->name);
@@ -2390,7 +2369,7 @@ static void bond_miimon_commit(struct bonding *bond)
                            bond->params.mode == BOND_MODE_8023AD)
                                bond_set_slave_inactive_flags(slave);
 
-                       printk(KERN_INFO DRV_NAME
+                       pr_info(DRV_NAME
                               ": %s: link status definitely down for "
                               "interface %s, disabling it\n",
                               bond->dev->name, slave->dev->name);
@@ -2399,8 +2378,7 @@ static void bond_miimon_commit(struct bonding *bond)
                                bond_3ad_handle_link_change(slave,
                                                            BOND_LINK_DOWN);
 
-                       if (bond->params.mode == BOND_MODE_TLB ||
-                           bond->params.mode == BOND_MODE_ALB)
+                       if (bond_is_lb(bond))
                                bond_alb_handle_link_change(bond, slave,
                                                            BOND_LINK_DOWN);
 
@@ -2410,7 +2388,7 @@ static void bond_miimon_commit(struct bonding *bond)
                        continue;
 
                default:
-                       printk(KERN_ERR DRV_NAME
+                       pr_err(DRV_NAME
                               ": %s: invalid new link %d on slave %s\n",
                               bond->dev->name, slave->new_link,
                               slave->dev->name);
@@ -2531,18 +2509,18 @@ static void bond_arp_send(struct net_device *slave_dev, int arp_op, __be32 dest_
 
        pr_debug("arp %d on slave %s: dst %x src %x vid %d\n", arp_op,
               slave_dev->name, dest_ip, src_ip, vlan_id);
-              
+
        skb = arp_create(arp_op, ETH_P_ARP, dest_ip, slave_dev, src_ip,
                         NULL, slave_dev->dev_addr, NULL);
 
        if (!skb) {
-               printk(KERN_ERR DRV_NAME ": ARP packet allocation failed\n");
+               pr_err(DRV_NAME ": ARP packet allocation failed\n");
                return;
        }
        if (vlan_id) {
                skb = vlan_put_tag(skb, vlan_id);
                if (!skb) {
-                       printk(KERN_ERR DRV_NAME ": failed to insert VLAN tag\n");
+                       pr_err(DRV_NAME ": failed to insert VLAN tag\n");
                        return;
                }
        }
@@ -2582,7 +2560,7 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave)
                rv = ip_route_output_key(&init_net, &rt, &fl);
                if (rv) {
                        if (net_ratelimit()) {
-                               printk(KERN_WARNING DRV_NAME
+                               pr_warning(DRV_NAME
                             ": %s: no route to arp_ip_target %pI4\n",
                                       bond->dev->name, &fl.fl4_dst);
                        }
@@ -2619,7 +2597,7 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave)
                }
 
                if (net_ratelimit()) {
-                       printk(KERN_WARNING DRV_NAME
+                       pr_warning(DRV_NAME
               ": %s: no path to arp_ip_target %pI4 via rt.dev %s\n",
                               bond->dev->name, &fl.fl4_dst,
                               rt->u.dst.dev ? rt->u.dst.dev->name : "NULL");
@@ -2767,13 +2745,11 @@ void bond_loadbalance_arp_mon(struct work_struct *work)
 
        delta_in_ticks = msecs_to_jiffies(bond->params.arp_interval);
 
-       if (bond->kill_timers) {
+       if (bond->kill_timers)
                goto out;
-       }
 
-       if (bond->slave_cnt == 0) {
+       if (bond->slave_cnt == 0)
                goto re_arm;
-       }
 
        read_lock(&bond->curr_slave_lock);
        oldcurrent = bond->curr_active_slave;
@@ -2789,7 +2765,7 @@ void bond_loadbalance_arp_mon(struct work_struct *work)
         */
        bond_for_each_slave(bond, slave, i) {
                if (slave->link != BOND_LINK_UP) {
-                       if (time_before_eq(jiffies, slave->dev->trans_start + delta_in_ticks) &&
+                       if (time_before_eq(jiffies, dev_trans_start(slave->dev) + delta_in_ticks) &&
                            time_before_eq(jiffies, slave->dev->last_rx + delta_in_ticks)) {
 
                                slave->link  = BOND_LINK_UP;
@@ -2801,14 +2777,14 @@ void bond_loadbalance_arp_mon(struct work_struct *work)
                                 * is closed.
                                 */
                                if (!oldcurrent) {
-                                       printk(KERN_INFO DRV_NAME
+                                       pr_info(DRV_NAME
                                               ": %s: link status definitely "
                                               "up for interface %s, ",
                                               bond->dev->name,
                                               slave->dev->name);
                                        do_failover = 1;
                                } else {
-                                       printk(KERN_INFO DRV_NAME
+                                       pr_info(DRV_NAME
                                               ": %s: interface %s is now up\n",
                                               bond->dev->name,
                                               slave->dev->name);
@@ -2821,24 +2797,22 @@ void bond_loadbalance_arp_mon(struct work_struct *work)
                         * when the source ip is 0, so don't take the link down
                         * if we don't know our ip yet
                         */
-                       if (time_after_eq(jiffies, slave->dev->trans_start + 2*delta_in_ticks) ||
+                       if (time_after_eq(jiffies, dev_trans_start(slave->dev) + 2*delta_in_ticks) ||
                            (time_after_eq(jiffies, slave->dev->last_rx + 2*delta_in_ticks))) {
 
                                slave->link  = BOND_LINK_DOWN;
                                slave->state = BOND_STATE_BACKUP;
 
-                               if (slave->link_failure_count < UINT_MAX) {
+                               if (slave->link_failure_count < UINT_MAX)
                                        slave->link_failure_count++;
-                               }
 
-                               printk(KERN_INFO DRV_NAME
+                               pr_info(DRV_NAME
                                       ": %s: interface %s is now down.\n",
                                       bond->dev->name,
                                       slave->dev->name);
 
-                               if (slave == oldcurrent) {
+                               if (slave == oldcurrent)
                                        do_failover = 1;
-                               }
                        }
                }
 
@@ -2849,9 +2823,8 @@ void bond_loadbalance_arp_mon(struct work_struct *work)
                 * do - all replies will be rx'ed on same link causing slaves
                 * to be unstable during low/no traffic periods
                 */
-               if (IS_UP(slave->dev)) {
+               if (IS_UP(slave->dev))
                        bond_arp_send_all(bond, slave);
-               }
        }
 
        if (do_failover) {
@@ -2932,7 +2905,7 @@ static int bond_ab_arp_inspect(struct bonding *bond, int delta_in_ticks)
                 *    the bond has an IP address)
                 */
                if ((slave->state == BOND_STATE_ACTIVE) &&
-                   (time_after_eq(jiffies, slave->dev->trans_start +
+                   (time_after_eq(jiffies, dev_trans_start(slave->dev) +
                                    2 * delta_in_ticks) ||
                      (time_after_eq(jiffies, slave_last_rx(bond, slave)
                                     + 2 * delta_in_ticks)))) {
@@ -2976,13 +2949,13 @@ static void bond_ab_arp_commit(struct bonding *bond, int delta_in_ticks)
                        write_lock_bh(&bond->curr_slave_lock);
 
                        if (!bond->curr_active_slave &&
-                           time_before_eq(jiffies, slave->dev->trans_start +
+                           time_before_eq(jiffies, dev_trans_start(slave->dev) +
                                           delta_in_ticks)) {
                                slave->link = BOND_LINK_UP;
                                bond_change_active_slave(bond, slave);
                                bond->current_arp_slave = NULL;
 
-                               printk(KERN_INFO DRV_NAME
+                               pr_info(DRV_NAME
                                       ": %s: %s is up and now the "
                                       "active interface\n",
                                       bond->dev->name, slave->dev->name);
@@ -2998,7 +2971,7 @@ static void bond_ab_arp_commit(struct bonding *bond, int delta_in_ticks)
                                bond_set_slave_inactive_flags(slave);
                                bond->current_arp_slave = NULL;
 
-                               printk(KERN_INFO DRV_NAME
+                               pr_info(DRV_NAME
                                       ": %s: backup interface %s is now up\n",
                                       bond->dev->name, slave->dev->name);
                        }
@@ -3014,7 +2987,7 @@ static void bond_ab_arp_commit(struct bonding *bond, int delta_in_ticks)
                        slave->link = BOND_LINK_DOWN;
 
                        if (slave == bond->curr_active_slave) {
-                               printk(KERN_INFO DRV_NAME
+                               pr_info(DRV_NAME
                                       ": %s: link status down for active "
                                       "interface %s, disabling it\n",
                                       bond->dev->name, slave->dev->name);
@@ -3033,7 +3006,7 @@ static void bond_ab_arp_commit(struct bonding *bond, int delta_in_ticks)
                                bond->current_arp_slave = NULL;
 
                        } else if (slave->state == BOND_STATE_BACKUP) {
-                               printk(KERN_INFO DRV_NAME
+                               pr_info(DRV_NAME
                                       ": %s: backup interface %s is now down\n",
                                       bond->dev->name, slave->dev->name);
 
@@ -3042,7 +3015,7 @@ static void bond_ab_arp_commit(struct bonding *bond, int delta_in_ticks)
                        break;
 
                default:
-                       printk(KERN_ERR DRV_NAME
+                       pr_err(DRV_NAME
                               ": %s: impossible: new_link %d on slave %s\n",
                               bond->dev->name, slave->new_link,
                               slave->dev->name);
@@ -3076,7 +3049,7 @@ static void bond_ab_arp_probe(struct bonding *bond)
        read_lock(&bond->curr_slave_lock);
 
        if (bond->current_arp_slave && bond->curr_active_slave)
-               printk("PROBE: c_arp %s && cas %s BAD\n",
+               pr_info(DRV_NAME "PROBE: c_arp %s && cas %s BAD\n",
                       bond->current_arp_slave->dev->name,
                       bond->curr_active_slave->dev->name);
 
@@ -3126,7 +3099,7 @@ static void bond_ab_arp_probe(struct bonding *bond)
 
                        bond_set_slave_inactive_flags(slave);
 
-                       printk(KERN_INFO DRV_NAME
+                       pr_info(DRV_NAME
                               ": %s: backup interface %s is now down.\n",
                               bond->dev->name, slave->dev->name);
                }
@@ -3176,9 +3149,8 @@ void bond_activebackup_arp_mon(struct work_struct *work)
        bond_ab_arp_probe(bond);
 
 re_arm:
-       if (bond->params.arp_interval) {
+       if (bond->params.arp_interval)
                queue_delayed_work(bond->wq, &bond->arp_work, delta_in_ticks);
-       }
 out:
        read_unlock(&bond->lock);
 }
@@ -3200,14 +3172,12 @@ static void *bond_info_seq_start(struct seq_file *seq, loff_t *pos)
        read_lock(&dev_base_lock);
        read_lock(&bond->lock);
 
-       if (*pos == 0) {
+       if (*pos == 0)
                return SEQ_START_TOKEN;
-       }
 
        bond_for_each_slave(bond, slave, i) {
-               if (++off == *pos) {
+               if (++off == *pos)
                        return slave;
-               }
        }
 
        return NULL;
@@ -3219,9 +3189,8 @@ static void *bond_info_seq_next(struct seq_file *seq, void *v, loff_t *pos)
        struct slave *slave = v;
 
        ++*pos;
-       if (v == SEQ_START_TOKEN) {
+       if (v == SEQ_START_TOKEN)
                return bond->first_slave;
-       }
 
        slave = slave->next;
 
@@ -3284,14 +3253,14 @@ static void bond_info_show_master(struct seq_file *seq)
 
 
        /* ARP information */
-       if(bond->params.arp_interval > 0) {
-               int printed=0;
+       if (bond->params.arp_interval > 0) {
+               int printed = 0;
                seq_printf(seq, "ARP Polling Interval (ms): %d\n",
                                bond->params.arp_interval);
 
                seq_printf(seq, "ARP IP target/s (n.n.n.n form):");
 
-               for(i = 0; (i < BOND_MAX_ARP_TARGETS) ;i++) {
+               for (i = 0; (i < BOND_MAX_ARP_TARGETS); i++) {
                        if (!bond->params.arp_targets[i])
                                break;
                        if (printed)
@@ -3331,7 +3300,8 @@ static void bond_info_show_master(struct seq_file *seq)
        }
 }
 
-static void bond_info_show_slave(struct seq_file *seq, const struct slave *slave)
+static void bond_info_show_slave(struct seq_file *seq,
+                                const struct slave *slave)
 {
        struct bonding *bond = seq->private;
 
@@ -3347,12 +3317,11 @@ static void bond_info_show_slave(struct seq_file *seq, const struct slave *slave
                const struct aggregator *agg
                        = SLAVE_AD_INFO(slave).port.aggregator;
 
-               if (agg) {
+               if (agg)
                        seq_printf(seq, "Aggregator ID: %d\n",
                                   agg->aggregator_identifier);
-               } else {
+               else
                        seq_puts(seq, "Aggregator ID: N/A\n");
-               }
        }
 }
 
@@ -3361,9 +3330,8 @@ static int bond_info_seq_show(struct seq_file *seq, void *v)
        if (v == SEQ_START_TOKEN) {
                seq_printf(seq, "%s\n", version);
                bond_info_show_master(seq);
-       } else {
+       } else
                bond_info_show_slave(seq, v);
-       }
 
        return 0;
 }
@@ -3408,13 +3376,12 @@ static int bond_create_proc_entry(struct bonding *bond)
                bond->proc_entry = proc_create_data(bond_dev->name,
                                                    S_IRUGO, bond_proc_dir,
                                                    &bond_info_fops, bond);
-               if (bond->proc_entry == NULL) {
-                       printk(KERN_WARNING DRV_NAME
+               if (bond->proc_entry == NULL)
+                       pr_warning(DRV_NAME
                               ": Warning: Cannot create /proc/net/%s/%s\n",
                               DRV_NAME, bond_dev->name);
-               } else {
+               else
                        memcpy(bond->proc_file_name, bond_dev->name, IFNAMSIZ);
-               }
        }
 
        return 0;
@@ -3437,7 +3404,7 @@ static void bond_create_proc_dir(void)
        if (!bond_proc_dir) {
                bond_proc_dir = proc_mkdir(DRV_NAME, init_net.proc_net);
                if (!bond_proc_dir)
-                       printk(KERN_WARNING DRV_NAME
+                       pr_warning(DRV_NAME
                                ": Warning: cannot create /proc/net/%s\n",
                                DRV_NAME);
        }
@@ -3453,8 +3420,28 @@ static void bond_destroy_proc_dir(void)
                bond_proc_dir = NULL;
        }
 }
+
+#else /* !CONFIG_PROC_FS */
+
+static int bond_create_proc_entry(struct bonding *bond)
+{
+}
+
+static void bond_remove_proc_entry(struct bonding *bond)
+{
+}
+
+static void bond_create_proc_dir(void)
+{
+}
+
+static void bond_destroy_proc_dir(void)
+{
+}
+
 #endif /* CONFIG_PROC_FS */
 
+
 /*-------------------------- netdev event handling --------------------------*/
 
 /*
@@ -3462,18 +3449,17 @@ static void bond_destroy_proc_dir(void)
  */
 static int bond_event_changename(struct bonding *bond)
 {
-#ifdef CONFIG_PROC_FS
        bond_remove_proc_entry(bond);
        bond_create_proc_entry(bond);
-#endif
-       down_write(&(bonding_rwsem));
-        bond_destroy_sysfs_entry(bond);
-        bond_create_sysfs_entry(bond);
-       up_write(&(bonding_rwsem));
+
+       bond_destroy_sysfs_entry(bond);
+       bond_create_sysfs_entry(bond);
+
        return NOTIFY_DONE;
 }
 
-static int bond_master_netdev_event(unsigned long event, struct net_device *bond_dev)
+static int bond_master_netdev_event(unsigned long event,
+                                   struct net_device *bond_dev)
 {
        struct bonding *event_bond = netdev_priv(bond_dev);
 
@@ -3490,7 +3476,8 @@ static int bond_master_netdev_event(unsigned long event, struct net_device *bond
        return NOTIFY_DONE;
 }
 
-static int bond_slave_netdev_event(unsigned long event, struct net_device *slave_dev)
+static int bond_slave_netdev_event(unsigned long event,
+                                  struct net_device *slave_dev)
 {
        struct net_device *bond_dev = slave_dev->master;
        struct bonding *bond = netdev_priv(bond_dev);
@@ -3568,7 +3555,8 @@ static int bond_slave_netdev_event(unsigned long event, struct net_device *slave
  * locks for us to safely manipulate the slave devices (RTNL lock,
  * dev_probe_lock).
  */
-static int bond_netdev_event(struct notifier_block *this, unsigned long event, void *ptr)
+static int bond_netdev_event(struct notifier_block *this,
+                            unsigned long event, void *ptr)
 {
        struct net_device *event_dev = (struct net_device *)ptr;
 
@@ -3923,9 +3911,9 @@ static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd
        switch (cmd) {
        case SIOCGMIIPHY:
                mii = if_mii(ifr);
-               if (!mii) {
+               if (!mii)
                        return -EINVAL;
-               }
+
                mii->phy_id = 0;
                /* Fall Through */
        case SIOCGMIIREG:
@@ -3934,18 +3922,18 @@ static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd
                 * instead of SIOCGMIIPHY.
                 */
                mii = if_mii(ifr);
-               if (!mii) {
+               if (!mii)
                        return -EINVAL;
-               }
+
 
                if (mii->reg_num == 1) {
                        struct bonding *bond = netdev_priv(bond_dev);
                        mii->val_out = 0;
                        read_lock(&bond->lock);
                        read_lock(&bond->curr_slave_lock);
-                       if (netif_carrier_ok(bond->dev)) {
+                       if (netif_carrier_ok(bond->dev))
                                mii->val_out = BMSR_LSTATUS;
-                       }
+
                        read_unlock(&bond->curr_slave_lock);
                        read_unlock(&bond->lock);
                }
@@ -3955,32 +3943,26 @@ static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd
        case SIOCBONDINFOQUERY:
                u_binfo = (struct ifbond __user *)ifr->ifr_data;
 
-               if (copy_from_user(&k_binfo, u_binfo, sizeof(ifbond))) {
+               if (copy_from_user(&k_binfo, u_binfo, sizeof(ifbond)))
                        return -EFAULT;
-               }
 
                res = bond_info_query(bond_dev, &k_binfo);
-               if (res == 0) {
-                       if (copy_to_user(u_binfo, &k_binfo, sizeof(ifbond))) {
-                               return -EFAULT;
-                       }
-               }
+               if (res == 0 &&
+                   copy_to_user(u_binfo, &k_binfo, sizeof(ifbond)))
+                       return -EFAULT;
 
                return res;
        case BOND_SLAVE_INFO_QUERY_OLD:
        case SIOCBONDSLAVEINFOQUERY:
                u_sinfo = (struct ifslave __user *)ifr->ifr_data;
 
-               if (copy_from_user(&k_sinfo, u_sinfo, sizeof(ifslave))) {
+               if (copy_from_user(&k_sinfo, u_sinfo, sizeof(ifslave)))
                        return -EFAULT;
-               }
 
                res = bond_slave_info_query(bond_dev, &k_sinfo);
-               if (res == 0) {
-                       if (copy_to_user(u_sinfo, &k_sinfo, sizeof(ifslave))) {
-                               return -EFAULT;
-                       }
-               }
+               if (res == 0 &&
+                   copy_to_user(u_sinfo, &k_sinfo, sizeof(ifslave)))
+                       return -EFAULT;
 
                return res;
        default:
@@ -3988,18 +3970,16 @@ static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd
                break;
        }
 
-       if (!capable(CAP_NET_ADMIN)) {
+       if (!capable(CAP_NET_ADMIN))
                return -EPERM;
-       }
 
-       down_write(&(bonding_rwsem));
        slave_dev = dev_get_by_name(&init_net, ifr->ifr_slave);
 
        pr_debug("slave_dev=%p: \n", slave_dev);
 
-       if (!slave_dev) {
+       if (!slave_dev)
                res = -ENODEV;
-       else {
+       else {
                pr_debug("slave_dev->name=%s: \n", slave_dev->name);
                switch (cmd) {
                case BOND_ENSLAVE_OLD:
@@ -4025,7 +4005,6 @@ static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd
                dev_put(slave_dev);
        }
 
-       up_write(&(bonding_rwsem));
        return res;
 }
 
@@ -4037,30 +4016,30 @@ static void bond_set_multicast_list(struct net_device *bond_dev)
        /*
         * Do promisc before checking multicast_mode
         */
-       if ((bond_dev->flags & IFF_PROMISC) && !(bond->flags & IFF_PROMISC)) {
+       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 (!(bond_dev->flags & IFF_PROMISC) && (bond->flags & IFF_PROMISC)) {
+
+       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)) {
+       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)) {
+
+       if (!(bond_dev->flags & IFF_ALLMULTI) && (bond->flags & IFF_ALLMULTI))
                bond_set_allmulti(bond, -1);
-       }
+
 
        read_lock(&bond->lock);
 
@@ -4068,16 +4047,14 @@ static void bond_set_multicast_list(struct net_device *bond_dev)
 
        /* looking for addresses to add to slaves' mc list */
        for (dmi = bond_dev->mc_list; dmi; dmi = dmi->next) {
-               if (!bond_mc_list_find_dmi(dmi, bond->mc_list)) {
+               if (!bond_mc_list_find_dmi(dmi, bond->mc_list))
                        bond_mc_add(bond, dmi->dmi_addr, dmi->dmi_addrlen);
-               }
        }
 
        /* looking for addresses to delete from slaves' list */
        for (dmi = bond->mc_list; dmi; dmi = dmi->next) {
-               if (!bond_mc_list_find_dmi(dmi, bond_dev->mc_list)) {
+               if (!bond_mc_list_find_dmi(dmi, bond_dev->mc_list))
                        bond_mc_delete(bond, dmi->dmi_addr, dmi->dmi_addrlen);
-               }
        }
 
        /* save master's multicast list */
@@ -4197,9 +4174,8 @@ static int bond_set_mac_address(struct net_device *bond_dev, void *addr)
        if (bond->params.fail_over_mac == BOND_FOM_ACTIVE)
                return 0;
 
-       if (!is_valid_ether_addr(sa->sa_data)) {
+       if (!is_valid_ether_addr(sa->sa_data))
                return -EADDRNOTAVAIL;
-       }
 
        /* Can't hold bond->lock with bh disabled here since
         * some base drivers panic. On the other hand we can't
@@ -4270,9 +4246,8 @@ static int bond_xmit_roundrobin(struct sk_buff *skb, struct net_device *bond_dev
 
        read_lock(&bond->lock);
 
-       if (!BOND_IS_OK(bond)) {
+       if (!BOND_IS_OK(bond))
                goto out;
-       }
 
        /*
         * Concurrent TX may collide on rr_tx_counter; we accept that
@@ -4282,9 +4257,8 @@ static int bond_xmit_roundrobin(struct sk_buff *skb, struct net_device *bond_dev
 
        bond_for_each_slave(bond, slave, i) {
                slave_no--;
-               if (slave_no < 0) {
+               if (slave_no < 0)
                        break;
-               }
        }
 
        start_at = slave;
@@ -4319,9 +4293,8 @@ static int bond_xmit_activebackup(struct sk_buff *skb, struct net_device *bond_d
        read_lock(&bond->lock);
        read_lock(&bond->curr_slave_lock);
 
-       if (!BOND_IS_OK(bond)) {
+       if (!BOND_IS_OK(bond))
                goto out;
-       }
 
        if (!bond->curr_active_slave)
                goto out;
@@ -4329,10 +4302,10 @@ static int bond_xmit_activebackup(struct sk_buff *skb, struct net_device *bond_d
        res = bond_dev_queue_xmit(bond, skb, bond->curr_active_slave->dev);
 
 out:
-       if (res) {
+       if (res)
                /* no suitable interface, frame not sent */
                dev_kfree_skb(skb);
-       }
+
        read_unlock(&bond->curr_slave_lock);
        read_unlock(&bond->lock);
        return 0;
@@ -4353,17 +4326,15 @@ static int bond_xmit_xor(struct sk_buff *skb, struct net_device *bond_dev)
 
        read_lock(&bond->lock);
 
-       if (!BOND_IS_OK(bond)) {
+       if (!BOND_IS_OK(bond))
                goto out;
-       }
 
        slave_no = bond->xmit_hash_policy(skb, bond_dev, bond->slave_cnt);
 
        bond_for_each_slave(bond, slave, i) {
                slave_no--;
-               if (slave_no < 0) {
+               if (slave_no < 0)
                        break;
-               }
        }
 
        start_at = slave;
@@ -4399,17 +4370,15 @@ static int bond_xmit_broadcast(struct sk_buff *skb, struct net_device *bond_dev)
 
        read_lock(&bond->lock);
 
-       if (!BOND_IS_OK(bond)) {
+       if (!BOND_IS_OK(bond))
                goto out;
-       }
 
        read_lock(&bond->curr_slave_lock);
        start_at = bond->curr_active_slave;
        read_unlock(&bond->curr_slave_lock);
 
-       if (!start_at) {
+       if (!start_at)
                goto out;
-       }
 
        bond_for_each_slave_from(bond, slave, i, start_at) {
                if (IS_UP(slave->dev) &&
@@ -4418,7 +4387,7 @@ static int bond_xmit_broadcast(struct sk_buff *skb, struct net_device *bond_dev)
                        if (tx_dev) {
                                struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC);
                                if (!skb2) {
-                                       printk(KERN_ERR DRV_NAME
+                                       pr_err(DRV_NAME
                                               ": %s: Error: bond_xmit_broadcast(): "
                                               "skb_clone() failed\n",
                                               bond_dev->name);
@@ -4435,15 +4404,14 @@ static int bond_xmit_broadcast(struct sk_buff *skb, struct net_device *bond_dev)
                }
        }
 
-       if (tx_dev) {
+       if (tx_dev)
                res = bond_dev_queue_xmit(bond, skb, tx_dev);
-       }
 
 out:
-       if (res) {
+       if (res)
                /* no suitable interface, frame not sent */
                dev_kfree_skb(skb);
-       }
+
        /* frame sent to all suitable interfaces */
        read_unlock(&bond->lock);
        return 0;
@@ -4487,7 +4455,7 @@ static int bond_start_xmit(struct sk_buff *skb, struct net_device *dev)
                return bond_alb_xmit(skb, dev);
        default:
                /* Should never happen, mode already checked */
-               printk(KERN_ERR DRV_NAME ": %s: Error: Unknown bonding mode %d\n",
+               pr_err(DRV_NAME ": %s: Error: Unknown bonding mode %d\n",
                     dev->name, bond->params.mode);
                WARN_ON_ONCE(1);
                dev_kfree_skb(skb);
@@ -4524,7 +4492,7 @@ void bond_set_mode_ops(struct bonding *bond, int mode)
                break;
        default:
                /* Should never happen, mode already checked */
-               printk(KERN_ERR DRV_NAME
+               pr_err(DRV_NAME
                       ": %s: Error: Unknown bonding mode %d\n",
                       bond_dev->name,
                       mode);
@@ -4551,6 +4519,8 @@ static const struct ethtool_ops bond_ethtool_ops = {
 };
 
 static const struct net_device_ops bond_netdev_ops = {
+       .ndo_init               = bond_init,
+       .ndo_uninit             = bond_uninit,
        .ndo_open               = bond_open,
        .ndo_stop               = bond_close,
        .ndo_start_xmit         = bond_start_xmit,
@@ -4565,48 +4535,34 @@ static const struct net_device_ops bond_netdev_ops = {
        .ndo_vlan_rx_kill_vid   = bond_vlan_rx_kill_vid,
 };
 
-/*
- * Does not allocate but creates a /proc entry.
- * Allowed to fail.
- */
-static int bond_init(struct net_device *bond_dev, struct bond_params *params)
+static void bond_setup(struct net_device *bond_dev)
 {
        struct bonding *bond = netdev_priv(bond_dev);
 
-       pr_debug("Begin bond_init for %s\n", bond_dev->name);
-
        /* initialize rwlocks */
        rwlock_init(&bond->lock);
        rwlock_init(&bond->curr_slave_lock);
 
-       bond->params = *params; /* copy params struct */
-
-       bond->wq = create_singlethread_workqueue(bond_dev->name);
-       if (!bond->wq)
-               return -ENOMEM;
+       bond->params = bonding_defaults;
 
        /* Initialize pointers */
-       bond->first_slave = NULL;
-       bond->curr_active_slave = NULL;
-       bond->current_arp_slave = NULL;
-       bond->primary_slave = NULL;
        bond->dev = bond_dev;
-       bond->send_grat_arp = 0;
-       bond->send_unsol_na = 0;
-       bond->setup_by_slave = 0;
        INIT_LIST_HEAD(&bond->vlan_list);
 
        /* Initialize the device entry points */
+       ether_setup(bond_dev);
        bond_dev->netdev_ops = &bond_netdev_ops;
        bond_dev->ethtool_ops = &bond_ethtool_ops;
        bond_set_mode_ops(bond, bond->params.mode);
 
-       bond_dev->destructor = bond_destructor;
+       bond_dev->destructor = free_netdev;
 
        /* Initialize the device options */
        bond_dev->tx_queue_len = 0;
        bond_dev->flags |= IFF_MASTER|IFF_MULTICAST;
        bond_dev->priv_flags |= IFF_BONDING;
+       bond_dev->priv_flags &= ~IFF_XMIT_DST_RELEASE;
+
        if (bond->params.arp_interval)
                bond_dev->priv_flags |= IFF_MASTER_ARPMON;
 
@@ -4631,12 +4587,6 @@ static int bond_init(struct net_device *bond_dev, struct bond_params *params)
                               NETIF_F_HW_VLAN_RX |
                               NETIF_F_HW_VLAN_FILTER);
 
-#ifdef CONFIG_PROC_FS
-       bond_create_proc_entry(bond);
-#endif
-       list_add_tail(&bond->bond_list, &bond_dev_list);
-
-       return 0;
 }
 
 static void bond_work_cancel_all(struct bonding *bond)
@@ -4671,9 +4621,7 @@ static void bond_deinit(struct net_device *bond_dev)
 
        bond_work_cancel_all(bond);
 
-#ifdef CONFIG_PROC_FS
        bond_remove_proc_entry(bond);
-#endif
 }
 
 /* Unregister and free all bond devices.
@@ -4689,12 +4637,10 @@ static void bond_free_all(void)
                bond_work_cancel_all(bond);
                /* Release the bonded slaves */
                bond_release_all(bond_dev);
-               bond_destroy(bond);
+               unregister_netdevice(bond_dev);
        }
 
-#ifdef CONFIG_PROC_FS
        bond_destroy_proc_dir();
-#endif
 }
 
 /*------------------------- Module initialization ---------------------------*/
@@ -4742,7 +4688,7 @@ static int bond_check_params(struct bond_params *params)
        if (mode) {
                bond_mode = bond_parse_parm(mode, bond_mode_tbl);
                if (bond_mode == -1) {
-                       printk(KERN_ERR DRV_NAME
+                       pr_err(DRV_NAME
                               ": Error: Invalid bonding mode \"%s\"\n",
                               mode == NULL ? "NULL" : mode);
                        return -EINVAL;
@@ -4752,16 +4698,16 @@ static int bond_check_params(struct bond_params *params)
        if (xmit_hash_policy) {
                if ((bond_mode != BOND_MODE_XOR) &&
                    (bond_mode != BOND_MODE_8023AD)) {
-                       printk(KERN_INFO DRV_NAME
+                       pr_info(DRV_NAME
                               ": xor_mode param is irrelevant in mode %s\n",
                               bond_mode_name(bond_mode));
                } else {
                        xmit_hashtype = bond_parse_parm(xmit_hash_policy,
                                                        xmit_hashtype_tbl);
                        if (xmit_hashtype == -1) {
-                               printk(KERN_ERR DRV_NAME
-                               ": Error: Invalid xmit_hash_policy \"%s\"\n",
-                               xmit_hash_policy == NULL ? "NULL" :
+                               pr_err(DRV_NAME
+                                      ": Error: Invalid xmit_hash_policy \"%s\"\n",
+                                      xmit_hash_policy == NULL ? "NULL" :
                                       xmit_hash_policy);
                                return -EINVAL;
                        }
@@ -4770,13 +4716,13 @@ static int bond_check_params(struct bond_params *params)
 
        if (lacp_rate) {
                if (bond_mode != BOND_MODE_8023AD) {
-                       printk(KERN_INFO DRV_NAME
+                       pr_info(DRV_NAME
                               ": lacp_rate param is irrelevant in mode %s\n",
                               bond_mode_name(bond_mode));
                } else {
                        lacp_fast = bond_parse_parm(lacp_rate, bond_lacp_tbl);
                        if (lacp_fast == -1) {
-                               printk(KERN_ERR DRV_NAME
+                               pr_err(DRV_NAME
                                       ": Error: Invalid lacp rate \"%s\"\n",
                                       lacp_rate == NULL ? "NULL" : lacp_rate);
                                return -EINVAL;
@@ -4787,14 +4733,14 @@ static int bond_check_params(struct bond_params *params)
        if (ad_select) {
                params->ad_select = bond_parse_parm(ad_select, ad_select_tbl);
                if (params->ad_select == -1) {
-                       printk(KERN_ERR DRV_NAME
+                       pr_err(DRV_NAME
                               ": Error: Invalid ad_select \"%s\"\n",
                               ad_select == NULL ? "NULL" : ad_select);
                        return -EINVAL;
                }
 
                if (bond_mode != BOND_MODE_8023AD) {
-                       printk(KERN_WARNING DRV_NAME
+                       pr_warning(DRV_NAME
                               ": ad_select param only affects 802.3ad mode\n");
                }
        } else {
@@ -4802,7 +4748,7 @@ static int bond_check_params(struct bond_params *params)
        }
 
        if (max_bonds < 0 || max_bonds > INT_MAX) {
-               printk(KERN_WARNING DRV_NAME
+               pr_warning(DRV_NAME
                       ": Warning: max_bonds (%d) not in range %d-%d, so it "
                       "was reset to BOND_DEFAULT_MAX_BONDS (%d)\n",
                       max_bonds, 0, INT_MAX, BOND_DEFAULT_MAX_BONDS);
@@ -4810,7 +4756,7 @@ static int bond_check_params(struct bond_params *params)
        }
 
        if (miimon < 0) {
-               printk(KERN_WARNING DRV_NAME
+               pr_warning(DRV_NAME
                       ": Warning: miimon module parameter (%d), "
                       "not in range 0-%d, so it was reset to %d\n",
                       miimon, INT_MAX, BOND_LINK_MON_INTERV);
@@ -4818,7 +4764,7 @@ static int bond_check_params(struct bond_params *params)
        }
 
        if (updelay < 0) {
-               printk(KERN_WARNING DRV_NAME
+               pr_warning(DRV_NAME
                       ": Warning: updelay module parameter (%d), "
                       "not in range 0-%d, so it was reset to 0\n",
                       updelay, INT_MAX);
@@ -4826,7 +4772,7 @@ static int bond_check_params(struct bond_params *params)
        }
 
        if (downdelay < 0) {
-               printk(KERN_WARNING DRV_NAME
+               pr_warning(DRV_NAME
                       ": Warning: downdelay module parameter (%d), "
                       "not in range 0-%d, so it was reset to 0\n",
                       downdelay, INT_MAX);
@@ -4834,7 +4780,7 @@ static int bond_check_params(struct bond_params *params)
        }
 
        if ((use_carrier != 0) && (use_carrier != 1)) {
-               printk(KERN_WARNING DRV_NAME
+               pr_warning(DRV_NAME
                       ": Warning: use_carrier module parameter (%d), "
                       "not of valid value (0/1), so it was set to 1\n",
                       use_carrier);
@@ -4842,14 +4788,14 @@ static int bond_check_params(struct bond_params *params)
        }
 
        if (num_grat_arp < 0 || num_grat_arp > 255) {
-               printk(KERN_WARNING DRV_NAME
+               pr_warning(DRV_NAME
                       ": Warning: num_grat_arp (%d) not in range 0-255 so it "
                       "was reset to 1 \n", num_grat_arp);
                num_grat_arp = 1;
        }
 
        if (num_unsol_na < 0 || num_unsol_na > 255) {
-               printk(KERN_WARNING DRV_NAME
+               pr_warning(DRV_NAME
                       ": Warning: num_unsol_na (%d) not in range 0-255 so it "
                       "was reset to 1 \n", num_unsol_na);
                num_unsol_na = 1;
@@ -4858,12 +4804,12 @@ static int bond_check_params(struct bond_params *params)
        /* reset values for 802.3ad */
        if (bond_mode == BOND_MODE_8023AD) {
                if (!miimon) {
-                       printk(KERN_WARNING DRV_NAME
+                       pr_warning(DRV_NAME
                               ": Warning: miimon must be specified, "
                               "otherwise bonding will not detect link "
                               "failure, speed and duplex which are "
                               "essential for 802.3ad operation\n");
-                       printk(KERN_WARNING "Forcing miimon to 100msec\n");
+                       pr_warning("Forcing miimon to 100msec\n");
                        miimon = 100;
                }
        }
@@ -4872,12 +4818,12 @@ static int bond_check_params(struct bond_params *params)
        if ((bond_mode == BOND_MODE_TLB) ||
            (bond_mode == BOND_MODE_ALB)) {
                if (!miimon) {
-                       printk(KERN_WARNING DRV_NAME
+                       pr_warning(DRV_NAME
                               ": Warning: miimon must be specified, "
                               "otherwise bonding will not detect link "
                               "failure and link speed which are essential "
                               "for TLB/ALB load balancing\n");
-                       printk(KERN_WARNING "Forcing miimon to 100msec\n");
+                       pr_warning("Forcing miimon to 100msec\n");
                        miimon = 100;
                }
        }
@@ -4897,7 +4843,7 @@ static int bond_check_params(struct bond_params *params)
                        /* just warn the user the up/down delay will have
                         * no effect since miimon is zero...
                         */
-                       printk(KERN_WARNING DRV_NAME
+                       pr_warning(DRV_NAME
                               ": Warning: miimon module parameter not set "
                               "and updelay (%d) or downdelay (%d) module "
                               "parameter is set; updelay and downdelay have "
@@ -4907,7 +4853,7 @@ static int bond_check_params(struct bond_params *params)
        } else {
                /* don't allow arp monitoring */
                if (arp_interval) {
-                       printk(KERN_WARNING DRV_NAME
+                       pr_warning(DRV_NAME
                               ": Warning: miimon (%d) and arp_interval (%d) "
                               "can't be used simultaneously, disabling ARP "
                               "monitoring\n",
@@ -4916,7 +4862,7 @@ static int bond_check_params(struct bond_params *params)
                }
 
                if ((updelay % miimon) != 0) {
-                       printk(KERN_WARNING DRV_NAME
+                       pr_warning(DRV_NAME
                               ": Warning: updelay (%d) is not a multiple "
                               "of miimon (%d), updelay rounded to %d ms\n",
                               updelay, miimon, (updelay / miimon) * miimon);
@@ -4925,7 +4871,7 @@ static int bond_check_params(struct bond_params *params)
                updelay /= miimon;
 
                if ((downdelay % miimon) != 0) {
-                       printk(KERN_WARNING DRV_NAME
+                       pr_warning(DRV_NAME
                               ": Warning: downdelay (%d) is not a multiple "
                               "of miimon (%d), downdelay rounded to %d ms\n",
                               downdelay, miimon,
@@ -4936,7 +4882,7 @@ static int bond_check_params(struct bond_params *params)
        }
 
        if (arp_interval < 0) {
-               printk(KERN_WARNING DRV_NAME
+               pr_warning(DRV_NAME
                       ": Warning: arp_interval module parameter (%d) "
                       ", not in range 0-%d, so it was reset to %d\n",
                       arp_interval, INT_MAX, BOND_LINK_ARP_INTERV);
@@ -4949,7 +4895,7 @@ static int bond_check_params(struct bond_params *params)
                /* not complete check, but should be good enough to
                   catch mistakes */
                if (!isdigit(arp_ip_target[arp_ip_count][0])) {
-                       printk(KERN_WARNING DRV_NAME
+                       pr_warning(DRV_NAME
                               ": Warning: bad arp_ip_target module parameter "
                               "(%s), ARP monitoring will not be performed\n",
                               arp_ip_target[arp_ip_count]);
@@ -4962,7 +4908,7 @@ static int bond_check_params(struct bond_params *params)
 
        if (arp_interval && !arp_ip_count) {
                /* don't allow arping if no arp_ip_target given... */
-               printk(KERN_WARNING DRV_NAME
+               pr_warning(DRV_NAME
                       ": Warning: arp_interval module parameter (%d) "
                       "specified without providing an arp_ip_target "
                       "parameter, arp_interval was reset to 0\n",
@@ -4972,12 +4918,12 @@ static int bond_check_params(struct bond_params *params)
 
        if (arp_validate) {
                if (bond_mode != BOND_MODE_ACTIVEBACKUP) {
-                       printk(KERN_ERR DRV_NAME
-              ": arp_validate only supported in active-backup mode\n");
+                       pr_err(DRV_NAME
+                              ": arp_validate only supported in active-backup mode\n");
                        return -EINVAL;
                }
                if (!arp_interval) {
-                       printk(KERN_ERR DRV_NAME
+                       pr_err(DRV_NAME
                               ": arp_validate requires arp_interval\n");
                        return -EINVAL;
                }
@@ -4985,7 +4931,7 @@ static int bond_check_params(struct bond_params *params)
                arp_validate_value = bond_parse_parm(arp_validate,
                                                     arp_validate_tbl);
                if (arp_validate_value == -1) {
-                       printk(KERN_ERR DRV_NAME
+                       pr_err(DRV_NAME
                               ": Error: invalid arp_validate \"%s\"\n",
                               arp_validate == NULL ? "NULL" : arp_validate);
                        return -EINVAL;
@@ -4994,20 +4940,20 @@ static int bond_check_params(struct bond_params *params)
                arp_validate_value = 0;
 
        if (miimon) {
-               printk(KERN_INFO DRV_NAME
+               pr_info(DRV_NAME
                       ": MII link monitoring set to %d ms\n",
                       miimon);
        } else if (arp_interval) {
                int i;
 
-               printk(KERN_INFO DRV_NAME
-                      ": ARP monitoring set to %d ms, validate %s, with %d target(s):",
+               pr_info(DRV_NAME ": ARP monitoring set to %d ms,"
+                      " validate %s, with %d target(s):",
                       arp_interval,
                       arp_validate_tbl[arp_validate_value].modename,
                       arp_ip_count);
 
                for (i = 0; i < arp_ip_count; i++)
-                       printk (" %s", arp_ip_target[i]);
+                       printk(" %s", arp_ip_target[i]);
 
                printk("\n");
 
@@ -5015,7 +4961,7 @@ static int bond_check_params(struct bond_params *params)
                /* miimon and arp_interval not set, we need one so things
                 * work as expected, see bonding.txt for details
                 */
-               printk(KERN_WARNING DRV_NAME
+               pr_warning(DRV_NAME
                       ": Warning: either miimon or arp_interval and "
                       "arp_ip_target module parameters must be specified, "
                       "otherwise bonding will not detect link failures! see "
@@ -5026,7 +4972,7 @@ static int bond_check_params(struct bond_params *params)
                /* currently, using a primary only makes sense
                 * in active backup, TLB or ALB modes
                 */
-               printk(KERN_WARNING DRV_NAME
+               pr_warning(DRV_NAME
                       ": Warning: %s primary device specified but has no "
                       "effect in %s mode\n",
                       primary, bond_mode_name(bond_mode));
@@ -5037,14 +4983,14 @@ static int bond_check_params(struct bond_params *params)
                fail_over_mac_value = bond_parse_parm(fail_over_mac,
                                                      fail_over_mac_tbl);
                if (fail_over_mac_value == -1) {
-                       printk(KERN_ERR DRV_NAME
+                       pr_err(DRV_NAME
                               ": Error: invalid fail_over_mac \"%s\"\n",
                               arp_validate == NULL ? "NULL" : arp_validate);
                        return -EINVAL;
                }
 
                if (bond_mode != BOND_MODE_ACTIVEBACKUP)
-                       printk(KERN_WARNING DRV_NAME
+                       pr_warning(DRV_NAME
                               ": Warning: fail_over_mac only affects "
                               "active-backup mode.\n");
        } else {
@@ -5094,37 +5040,53 @@ static void bond_set_lockdep_class(struct net_device *dev)
        netdev_for_each_tx_queue(dev, bond_set_lockdep_class_one, NULL);
 }
 
+/*
+ * Called from registration process
+ */
+static int bond_init(struct net_device *bond_dev)
+{
+       struct bonding *bond = netdev_priv(bond_dev);
+
+       pr_debug("Begin bond_init for %s\n", bond_dev->name);
+
+       bond->wq = create_singlethread_workqueue(bond_dev->name);
+       if (!bond->wq)
+               return -ENOMEM;
+
+       bond_set_lockdep_class(bond_dev);
+
+       netif_carrier_off(bond_dev);
+
+       bond_create_proc_entry(bond);
+       list_add_tail(&bond->bond_list, &bond_dev_list);
+
+       return 0;
+}
+
 /* Create a new bond based on the specified name and bonding parameters.
  * If name is NULL, obtain a suitable "bond%d" name for us.
  * Caller must NOT hold rtnl_lock; we need to release it here before we
  * set up our sysfs entries.
  */
-int bond_create(char *name, struct bond_params *params)
+int bond_create(const char *name)
 {
        struct net_device *bond_dev;
-       struct bonding *bond;
        int res;
 
        rtnl_lock();
-       down_write(&bonding_rwsem);
-
        /* Check to see if the bond already exists. */
-       if (name) {
-               list_for_each_entry(bond, &bond_dev_list, bond_list)
-                       if (strnicmp(bond->dev->name, name, IFNAMSIZ) == 0) {
-                               printk(KERN_ERR DRV_NAME
-                              ": cannot add bond %s; it already exists\n",
-                                      name);
-                               res = -EPERM;
-                               goto out_rtnl;
-                       }
+       /* FIXME: pass netns from caller */
+       if (name && __dev_get_by_name(&init_net, name)) {
+               pr_err(DRV_NAME ": cannot add bond %s; already exists\n",
+                      name);
+               res = -EEXIST;
+               goto out_rtnl;
        }
 
        bond_dev = alloc_netdev(sizeof(struct bonding), name ? name : "",
-                               ether_setup);
+                               bond_setup);
        if (!bond_dev) {
-               printk(KERN_ERR DRV_NAME
-                      ": %s: eek! can't alloc netdev!\n",
+               pr_err(DRV_NAME ": %s: eek! can't alloc netdev!\n",
                       name);
                res = -ENOMEM;
                goto out_rtnl;
@@ -5136,43 +5098,24 @@ int bond_create(char *name, struct bond_params *params)
                        goto out_netdev;
        }
 
-       /* bond_init() must be called after dev_alloc_name() (for the
-        * /proc files), but before register_netdevice(), because we
-        * need to set function pointers.
-        */
-
-       res = bond_init(bond_dev, params);
-       if (res < 0) {
-               goto out_netdev;
-       }
-
        res = register_netdevice(bond_dev);
-       if (res < 0) {
+       if (res < 0)
                goto out_bond;
-       }
-
-       bond_set_lockdep_class(bond_dev);
-
-       netif_carrier_off(bond_dev);
 
-       up_write(&bonding_rwsem);
-       rtnl_unlock(); /* allows sysfs registration of net device */
        res = bond_create_sysfs_entry(netdev_priv(bond_dev));
        if (res < 0)
                goto out_unreg;
 
+       rtnl_unlock();
        return 0;
 
 out_unreg:
-       rtnl_lock();
-       down_write(&bonding_rwsem);
        unregister_netdevice(bond_dev);
 out_bond:
        bond_deinit(bond_dev);
 out_netdev:
        free_netdev(bond_dev);
 out_rtnl:
-       up_write(&bonding_rwsem);
        rtnl_unlock();
        return res;
 }
@@ -5182,21 +5125,16 @@ static int __init bonding_init(void)
        int i;
        int res;
 
-       printk(KERN_INFO "%s", version);
+       pr_info("%s", version);
 
        res = bond_check_params(&bonding_defaults);
-       if (res) {
+       if (res)
                goto out;
-       }
 
-#ifdef CONFIG_PROC_FS
        bond_create_proc_dir();
-#endif
-
-       init_rwsem(&bonding_rwsem);
 
        for (i = 0; i < max_bonds; i++) {
-               res = bond_create(NULL, &bonding_defaults);
+               res = bond_create(NULL);
                if (res)
                        goto err;
        }
@@ -5238,13 +5176,3 @@ MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_VERSION);
 MODULE_DESCRIPTION(DRV_DESCRIPTION ", v" DRV_VERSION);
 MODULE_AUTHOR("Thomas Davis, tadavis@lbl.gov and many others");
-MODULE_SUPPORTED_DEVICE("most ethernet devices");
-
-/*
- * Local variables:
- *  c-indent-level: 8
- *  c-basic-offset: 8
- *  tab-width: 8
- * End:
- */
-
index d2873153522645d81187d1ebf2e2f560760d2aa4..55bf34f59bbf60fe673bd4d4671aa53a03302157 100644 (file)
@@ -1,4 +1,3 @@
-
 /*
  * Copyright(c) 2004-2005 Intel Corporation. All rights reserved.
  *
 #include <linux/ctype.h>
 #include <linux/inet.h>
 #include <linux/rtnetlink.h>
+#include <linux/etherdevice.h>
 #include <net/net_namespace.h>
 
 #include "bonding.h"
 
-#define to_dev(obj)    container_of(obj,struct device,kobj)
+#define to_dev(obj)    container_of(obj, struct device, kobj)
 #define to_bond(cd)    ((struct bonding *)(netdev_priv(to_net_dev(cd))))
 
-/*---------------------------- Declarations -------------------------------*/
-
-static int expected_refcount = -1;
-/*--------------------------- Data Structures -----------------------------*/
-
-/* Bonding sysfs lock.  Why can't we just use the subsystem lock?
- * Because kobject_register tries to acquire the subsystem lock.  If
- * we already hold the lock (which we would if the user was creating
- * a new bond through the sysfs interface), we deadlock.
- * This lock is only needed when deleting a bond - we need to make sure
- * that we don't collide with an ongoing ioctl.
- */
-
-struct rw_semaphore bonding_rwsem;
-
-
-
-
-/*------------------------------ Functions --------------------------------*/
-
 /*
  * "show" function for the bond_masters attribute.
  * The class parameter is ignored.
@@ -70,7 +50,7 @@ static ssize_t bonding_show_bonds(struct class *cls, char *buf)
        int res = 0;
        struct bonding *bond;
 
-       down_read(&(bonding_rwsem));
+       rtnl_lock();
 
        list_for_each_entry(bond, &bond_dev_list, bond_list) {
                if (res > (PAGE_SIZE - IFNAMSIZ)) {
@@ -84,10 +64,22 @@ static ssize_t bonding_show_bonds(struct class *cls, char *buf)
        }
        if (res)
                buf[res-1] = '\n'; /* eat the leftover space */
-       up_read(&(bonding_rwsem));
+
+       rtnl_unlock();
        return res;
 }
 
+static struct net_device *bond_get_by_name(const char *ifname)
+{
+       struct bonding *bond;
+
+       list_for_each_entry(bond, &bond_dev_list, bond_list) {
+               if (strncmp(bond->dev->name, ifname, IFNAMSIZ) == 0)
+                       return bond->dev;
+       }
+       return NULL;
+}
+
 /*
  * "store" function for the bond_masters attribute.  This is what
  * creates and deletes entire bonds.
@@ -96,12 +88,12 @@ static ssize_t bonding_show_bonds(struct class *cls, char *buf)
  *
  */
 
-static ssize_t bonding_store_bonds(struct class *cls, const char *buffer, size_t count)
+static ssize_t bonding_store_bonds(struct class *cls,
+                                  const char *buffer, size_t count)
 {
        char command[IFNAMSIZ + 1] = {0, };
        char *ifname;
        int rv, res = count;
-       struct bonding *bond;
 
        sscanf(buffer, "%16s", command); /* IFNAMSIZ*/
        ifname = command + 1;
@@ -110,67 +102,48 @@ static ssize_t bonding_store_bonds(struct class *cls, const char *buffer, size_t
                goto err_no_cmd;
 
        if (command[0] == '+') {
-               printk(KERN_INFO DRV_NAME
+               pr_info(DRV_NAME
                        ": %s is being created...\n", ifname);
-               rv = bond_create(ifname, &bonding_defaults);
+               rv = bond_create(ifname);
                if (rv) {
-                       printk(KERN_INFO DRV_NAME ": Bond creation failed.\n");
+                       pr_info(DRV_NAME ": Bond creation failed.\n");
                        res = rv;
                }
-               goto out;
-       }
+       } else if (command[0] == '-') {
+               struct net_device *bond_dev;
 
-       if (command[0] == '-') {
                rtnl_lock();
-               down_write(&bonding_rwsem);
-
-               list_for_each_entry(bond, &bond_dev_list, bond_list)
-                       if (strnicmp(bond->dev->name, ifname, IFNAMSIZ) == 0) {
-                               /* check the ref count on the bond's kobject.
-                                * If it's > expected, then there's a file open,
-                                * and we have to fail.
-                                */
-                               if (atomic_read(&bond->dev->dev.kobj.kref.refcount)
-                                                       > expected_refcount){
-                                       printk(KERN_INFO DRV_NAME
-                                               ": Unable remove bond %s due to open references.\n",
-                                               ifname);
-                                       res = -EPERM;
-                                       goto out_unlock;
-                               }
-                               printk(KERN_INFO DRV_NAME
-                                       ": %s is being deleted...\n",
-                                       bond->dev->name);
-                               bond_destroy(bond);
-                               goto out_unlock;
-                       }
-
-               printk(KERN_ERR DRV_NAME
-                       ": unable to delete non-existent bond %s\n", ifname);
-               res = -ENODEV;
-               goto out_unlock;
-       }
-
-err_no_cmd:
-       printk(KERN_ERR DRV_NAME
-               ": no command found in bonding_masters. Use +ifname or -ifname.\n");
-       return -EPERM;
-
-out_unlock:
-       up_write(&bonding_rwsem);
-       rtnl_unlock();
+               bond_dev = bond_get_by_name(ifname);
+               if (bond_dev) {
+                       pr_info(DRV_NAME ": %s is being deleted...\n",
+                               ifname);
+                       unregister_netdevice(bond_dev);
+               } else {
+                       pr_err(DRV_NAME ": unable to delete non-existent %s\n",
+                              ifname);
+                       res = -ENODEV;
+               }
+               rtnl_unlock();
+       } else
+               goto err_no_cmd;
 
        /* Always return either count or an error.  If you return 0, you'll
         * get called forever, which is bad.
         */
-out:
        return res;
+
+err_no_cmd:
+       pr_err(DRV_NAME ": no command found in bonding_masters."
+              " Use +ifname or -ifname.\n");
+       return -EPERM;
 }
+
 /* class attribute for bond_masters file.  This ends up in /sys/class/net */
 static CLASS_ATTR(bonding_masters,  S_IWUSR | S_IRUGO,
                  bonding_show_bonds, bonding_store_bonds);
 
-int bond_create_slave_symlinks(struct net_device *master, struct net_device *slave)
+int bond_create_slave_symlinks(struct net_device *master,
+                              struct net_device *slave)
 {
        char linkname[IFNAMSIZ+7];
        int ret = 0;
@@ -181,19 +154,20 @@ int bond_create_slave_symlinks(struct net_device *master, struct net_device *sla
        if (ret)
                return ret;
        /* next, create a link from the master to the slave */
-       sprintf(linkname,"slave_%s",slave->name);
+       sprintf(linkname, "slave_%s", slave->name);
        ret = sysfs_create_link(&(master->dev.kobj), &(slave->dev.kobj),
                                linkname);
        return ret;
 
 }
 
-void bond_destroy_slave_symlinks(struct net_device *master, struct net_device *slave)
+void bond_destroy_slave_symlinks(struct net_device *master,
+                                struct net_device *slave)
 {
        char linkname[IFNAMSIZ+7];
 
        sysfs_remove_link(&(slave->dev.kobj), "master");
-       sprintf(linkname,"slave_%s",slave->name);
+       sprintf(linkname, "slave_%s", slave->name);
        sysfs_remove_link(&(master->dev.kobj), linkname);
 }
 
@@ -251,8 +225,8 @@ static ssize_t bonding_store_slaves(struct device *d,
 
        /* Note:  We can't hold bond->lock here, as bond_create grabs it. */
 
-       rtnl_lock();
-       down_write(&(bonding_rwsem));
+       if (!rtnl_trylock())
+               return restart_syscall();
 
        sscanf(buffer, "%16s", command); /* IFNAMSIZ*/
        ifname = command + 1;
@@ -264,46 +238,47 @@ static ssize_t bonding_store_slaves(struct device *d,
 
                /* Got a slave name in ifname.  Is it already in the list? */
                found = 0;
-               read_lock(&bond->lock);
-               bond_for_each_slave(bond, slave, i)
-                       if (strnicmp(slave->dev->name, ifname, IFNAMSIZ) == 0) {
-                               printk(KERN_ERR DRV_NAME
-                                      ": %s: Interface %s is already enslaved!\n",
-                                      bond->dev->name, ifname);
-                               ret = -EPERM;
-                               read_unlock(&bond->lock);
-                               goto out;
-                       }
 
-               read_unlock(&bond->lock);
-               printk(KERN_INFO DRV_NAME ": %s: Adding slave %s.\n",
-                      bond->dev->name, ifname);
-               dev = dev_get_by_name(&init_net, ifname);
+               /* FIXME: get netns from sysfs object */
+               dev = __dev_get_by_name(&init_net, ifname);
                if (!dev) {
-                       printk(KERN_INFO DRV_NAME
+                       pr_info(DRV_NAME
                               ": %s: Interface %s does not exist!\n",
                               bond->dev->name, ifname);
-                       ret = -EPERM;
+                       ret = -ENODEV;
                        goto out;
                }
-               else
-                       dev_put(dev);
 
                if (dev->flags & IFF_UP) {
-                       printk(KERN_ERR DRV_NAME
+                       pr_err(DRV_NAME
                               ": %s: Error: Unable to enslave %s "
                               "because it is already up.\n",
                               bond->dev->name, dev->name);
                        ret = -EPERM;
                        goto out;
                }
+
+               read_lock(&bond->lock);
+               bond_for_each_slave(bond, slave, i)
+                       if (slave->dev == dev) {
+                               pr_err(DRV_NAME
+                                      ": %s: Interface %s is already enslaved!\n",
+                                      bond->dev->name, ifname);
+                               ret = -EPERM;
+                               read_unlock(&bond->lock);
+                               goto out;
+                       }
+               read_unlock(&bond->lock);
+
+               pr_info(DRV_NAME ": %s: Adding slave %s.\n",
+                       bond->dev->name, ifname);
+
                /* If this is the first slave, then we need to set
                   the master's hardware address to be the same as the
                   slave's. */
-               if (!(*((u32 *) & (bond->dev->dev_addr[0])))) {
+               if (is_zero_ether_addr(bond->dev->dev_addr))
                        memcpy(bond->dev->dev_addr, dev->dev_addr,
                               dev->addr_len);
-               }
 
                /* Set the slave's MTU to match the bond */
                original_mtu = dev->mtu;
@@ -317,9 +292,9 @@ static ssize_t bonding_store_slaves(struct device *d,
                bond_for_each_slave(bond, slave, i)
                        if (strnicmp(slave->dev->name, ifname, IFNAMSIZ) == 0)
                                slave->original_mtu = original_mtu;
-               if (res) {
+               if (res)
                        ret = res;
-               }
+
                goto out;
        }
 
@@ -333,7 +308,7 @@ static ssize_t bonding_store_slaves(struct device *d,
                                break;
                        }
                if (dev) {
-                       printk(KERN_INFO DRV_NAME ": %s: Removing slave %s\n",
+                       pr_info(DRV_NAME ": %s: Removing slave %s\n",
                                bond->dev->name, dev->name);
                                res = bond_release(bond->dev, dev);
                        if (res) {
@@ -342,9 +317,9 @@ static ssize_t bonding_store_slaves(struct device *d,
                        }
                        /* set the slave MTU to the default */
                        dev_set_mtu(dev, original_mtu);
-               }
-               else {
-                       printk(KERN_ERR DRV_NAME ": unable to remove non-existent slave %s for bond %s.\n",
+               } else {
+                       pr_err(DRV_NAME ": unable to remove non-existent"
+                              " slave %s for bond %s.\n",
                                ifname, bond->dev->name);
                        ret = -ENODEV;
                }
@@ -352,16 +327,16 @@ static ssize_t bonding_store_slaves(struct device *d,
        }
 
 err_no_cmd:
-       printk(KERN_ERR DRV_NAME ": no command found in slaves file for bond %s. Use +ifname or -ifname.\n", bond->dev->name);
+       pr_err(DRV_NAME ": no command found in slaves file for bond %s. Use +ifname or -ifname.\n", bond->dev->name);
        ret = -EPERM;
 
 out:
-       up_write(&(bonding_rwsem));
        rtnl_unlock();
        return ret;
 }
 
-static DEVICE_ATTR(slaves, S_IRUGO | S_IWUSR, bonding_show_slaves, bonding_store_slaves);
+static DEVICE_ATTR(slaves, S_IRUGO | S_IWUSR, bonding_show_slaves,
+                  bonding_store_slaves);
 
 /*
  * Show and set the bonding mode.  The bond interface must be down to
@@ -385,16 +360,15 @@ static ssize_t bonding_store_mode(struct device *d,
        struct bonding *bond = to_bond(d);
 
        if (bond->dev->flags & IFF_UP) {
-               printk(KERN_ERR DRV_NAME
-                      ": unable to update mode of %s because interface is up.\n",
-                      bond->dev->name);
+               pr_err(DRV_NAME ": unable to update mode of %s"
+                      " because interface is up.\n", bond->dev->name);
                ret = -EPERM;
                goto out;
        }
 
        new_value = bond_parse_parm(buf, bond_mode_tbl);
        if (new_value < 0)  {
-               printk(KERN_ERR DRV_NAME
+               pr_err(DRV_NAME
                       ": %s: Ignoring invalid mode value %.*s.\n",
                       bond->dev->name,
                       (int)strlen(buf) - 1, buf);
@@ -409,17 +383,19 @@ static ssize_t bonding_store_mode(struct device *d,
 
                bond->params.mode = new_value;
                bond_set_mode_ops(bond, bond->params.mode);
-               printk(KERN_INFO DRV_NAME ": %s: setting mode to %s (%d).\n",
-                       bond->dev->name, bond_mode_tbl[new_value].modename, new_value);
+               pr_info(DRV_NAME ": %s: setting mode to %s (%d).\n",
+                      bond->dev->name, bond_mode_tbl[new_value].modename,
+                      new_value);
        }
 out:
        return ret;
 }
-static DEVICE_ATTR(mode, S_IRUGO | S_IWUSR, bonding_show_mode, bonding_store_mode);
+static DEVICE_ATTR(mode, S_IRUGO | S_IWUSR,
+                  bonding_show_mode, bonding_store_mode);
 
 /*
- * Show and set the bonding transmit hash method.  The bond interface must be down to
- * change the xmit hash policy.
+ * Show and set the bonding transmit hash method.
+ * The bond interface must be down to change the xmit hash policy.
  */
 static ssize_t bonding_show_xmit_hash(struct device *d,
                                      struct device_attribute *attr,
@@ -440,7 +416,7 @@ static ssize_t bonding_store_xmit_hash(struct device *d,
        struct bonding *bond = to_bond(d);
 
        if (bond->dev->flags & IFF_UP) {
-               printk(KERN_ERR DRV_NAME
+               pr_err(DRV_NAME
                       "%s: Interface is up. Unable to update xmit policy.\n",
                       bond->dev->name);
                ret = -EPERM;
@@ -449,7 +425,7 @@ static ssize_t bonding_store_xmit_hash(struct device *d,
 
        new_value = bond_parse_parm(buf, xmit_hashtype_tbl);
        if (new_value < 0)  {
-               printk(KERN_ERR DRV_NAME
+               pr_err(DRV_NAME
                       ": %s: Ignoring invalid xmit hash policy value %.*s.\n",
                       bond->dev->name,
                       (int)strlen(buf) - 1, buf);
@@ -458,13 +434,15 @@ static ssize_t bonding_store_xmit_hash(struct device *d,
        } else {
                bond->params.xmit_policy = new_value;
                bond_set_mode_ops(bond, bond->params.mode);
-               printk(KERN_INFO DRV_NAME ": %s: setting xmit hash policy to %s (%d).\n",
-                       bond->dev->name, xmit_hashtype_tbl[new_value].modename, new_value);
+               pr_info(DRV_NAME ": %s: setting xmit hash policy to %s (%d).\n",
+                       bond->dev->name,
+                       xmit_hashtype_tbl[new_value].modename, new_value);
        }
 out:
        return ret;
 }
-static DEVICE_ATTR(xmit_hash_policy, S_IRUGO | S_IWUSR, bonding_show_xmit_hash, bonding_store_xmit_hash);
+static DEVICE_ATTR(xmit_hash_policy, S_IRUGO | S_IWUSR,
+                  bonding_show_xmit_hash, bonding_store_xmit_hash);
 
 /*
  * Show and set arp_validate.
@@ -489,39 +467,41 @@ static ssize_t bonding_store_arp_validate(struct device *d,
 
        new_value = bond_parse_parm(buf, arp_validate_tbl);
        if (new_value < 0) {
-               printk(KERN_ERR DRV_NAME
+               pr_err(DRV_NAME
                       ": %s: Ignoring invalid arp_validate value %s\n",
                       bond->dev->name, buf);
                return -EINVAL;
        }
        if (new_value && (bond->params.mode != BOND_MODE_ACTIVEBACKUP)) {
-               printk(KERN_ERR DRV_NAME
+               pr_err(DRV_NAME
                       ": %s: arp_validate only supported in active-backup mode.\n",
                       bond->dev->name);
                return -EINVAL;
        }
-       printk(KERN_INFO DRV_NAME ": %s: setting arp_validate to %s (%d).\n",
+       pr_info(DRV_NAME ": %s: setting arp_validate to %s (%d).\n",
               bond->dev->name, arp_validate_tbl[new_value].modename,
               new_value);
 
-       if (!bond->params.arp_validate && new_value) {
+       if (!bond->params.arp_validate && new_value)
                bond_register_arp(bond);
-       } else if (bond->params.arp_validate && !new_value) {
+       else if (bond->params.arp_validate && !new_value)
                bond_unregister_arp(bond);
-       }
 
        bond->params.arp_validate = new_value;
 
        return count;
 }
 
-static DEVICE_ATTR(arp_validate, S_IRUGO | S_IWUSR, bonding_show_arp_validate, bonding_store_arp_validate);
+static DEVICE_ATTR(arp_validate, S_IRUGO | S_IWUSR, bonding_show_arp_validate,
+                  bonding_store_arp_validate);
 
 /*
  * Show and store fail_over_mac.  User only allowed to change the
  * value when there are no slaves.
  */
-static ssize_t bonding_show_fail_over_mac(struct device *d, struct device_attribute *attr, char *buf)
+static ssize_t bonding_show_fail_over_mac(struct device *d,
+                                         struct device_attribute *attr,
+                                         char *buf)
 {
        struct bonding *bond = to_bond(d);
 
@@ -530,13 +510,15 @@ static ssize_t bonding_show_fail_over_mac(struct device *d, struct device_attrib
                       bond->params.fail_over_mac);
 }
 
-static ssize_t bonding_store_fail_over_mac(struct device *d, struct device_attribute *attr, const char *buf, size_t count)
+static ssize_t bonding_store_fail_over_mac(struct device *d,
+                                          struct device_attribute *attr,
+                                          const char *buf, size_t count)
 {
        int new_value;
        struct bonding *bond = to_bond(d);
 
        if (bond->slave_cnt != 0) {
-               printk(KERN_ERR DRV_NAME
+               pr_err(DRV_NAME
                       ": %s: Can't alter fail_over_mac with slaves in bond.\n",
                       bond->dev->name);
                return -EPERM;
@@ -544,21 +526,22 @@ static ssize_t bonding_store_fail_over_mac(struct device *d, struct device_attri
 
        new_value = bond_parse_parm(buf, fail_over_mac_tbl);
        if (new_value < 0) {
-               printk(KERN_ERR DRV_NAME
+               pr_err(DRV_NAME
                       ": %s: Ignoring invalid fail_over_mac value %s.\n",
                       bond->dev->name, buf);
                return -EINVAL;
        }
 
        bond->params.fail_over_mac = new_value;
-       printk(KERN_INFO DRV_NAME ": %s: Setting fail_over_mac to %s (%d).\n",
+       pr_info(DRV_NAME ": %s: Setting fail_over_mac to %s (%d).\n",
               bond->dev->name, fail_over_mac_tbl[new_value].modename,
               new_value);
 
        return count;
 }
 
-static DEVICE_ATTR(fail_over_mac, S_IRUGO | S_IWUSR, bonding_show_fail_over_mac, bonding_store_fail_over_mac);
+static DEVICE_ATTR(fail_over_mac, S_IRUGO | S_IWUSR,
+                  bonding_show_fail_over_mac, bonding_store_fail_over_mac);
 
 /*
  * Show and set the arp timer interval.  There are two tricky bits
@@ -583,28 +566,28 @@ static ssize_t bonding_store_arp_interval(struct device *d,
        struct bonding *bond = to_bond(d);
 
        if (sscanf(buf, "%d", &new_value) != 1) {
-               printk(KERN_ERR DRV_NAME
+               pr_err(DRV_NAME
                       ": %s: no arp_interval value specified.\n",
                       bond->dev->name);
                ret = -EINVAL;
                goto out;
        }
        if (new_value < 0) {
-               printk(KERN_ERR DRV_NAME
+               pr_err(DRV_NAME
                       ": %s: Invalid arp_interval value %d not in range 1-%d; rejected.\n",
                       bond->dev->name, new_value, INT_MAX);
                ret = -EINVAL;
                goto out;
        }
 
-       printk(KERN_INFO DRV_NAME
+       pr_info(DRV_NAME
               ": %s: Setting ARP monitoring interval to %d.\n",
               bond->dev->name, new_value);
        bond->params.arp_interval = new_value;
        if (bond->params.arp_interval)
                bond->dev->priv_flags |= IFF_MASTER_ARPMON;
        if (bond->params.miimon) {
-               printk(KERN_INFO DRV_NAME
+               pr_info(DRV_NAME
                       ": %s: ARP monitoring cannot be used with MII monitoring. "
                       "%s Disabling MII monitoring.\n",
                       bond->dev->name, bond->dev->name);
@@ -615,7 +598,7 @@ static ssize_t bonding_store_arp_interval(struct device *d,
                }
        }
        if (!bond->params.arp_targets[0]) {
-               printk(KERN_INFO DRV_NAME
+               pr_info(DRV_NAME
                       ": %s: ARP monitoring has been set up, "
                       "but no ARP targets have been specified.\n",
                       bond->dev->name);
@@ -641,7 +624,8 @@ static ssize_t bonding_store_arp_interval(struct device *d,
 out:
        return ret;
 }
-static DEVICE_ATTR(arp_interval, S_IRUGO | S_IWUSR , bonding_show_arp_interval, bonding_store_arp_interval);
+static DEVICE_ATTR(arp_interval, S_IRUGO | S_IWUSR,
+                  bonding_show_arp_interval, bonding_store_arp_interval);
 
 /*
  * Show and set the arp targets.
@@ -677,7 +661,7 @@ static ssize_t bonding_store_arp_targets(struct device *d,
        /* look for adds */
        if (buf[0] == '+') {
                if ((newtarget == 0) || (newtarget == htonl(INADDR_BROADCAST))) {
-                       printk(KERN_ERR DRV_NAME
+                       pr_err(DRV_NAME
                               ": %s: invalid ARP target %pI4 specified for addition\n",
                               bond->dev->name, &newtarget);
                        ret = -EINVAL;
@@ -686,14 +670,14 @@ static ssize_t bonding_store_arp_targets(struct device *d,
                /* look for an empty slot to put the target in, and check for dupes */
                for (i = 0; (i < BOND_MAX_ARP_TARGETS) && !done; i++) {
                        if (targets[i] == newtarget) { /* duplicate */
-                               printk(KERN_ERR DRV_NAME
+                               pr_err(DRV_NAME
                                       ": %s: ARP target %pI4 is already present\n",
                                       bond->dev->name, &newtarget);
                                ret = -EINVAL;
                                goto out;
                        }
                        if (targets[i] == 0) {
-                               printk(KERN_INFO DRV_NAME
+                               pr_info(DRV_NAME
                                       ": %s: adding ARP target %pI4.\n",
                                       bond->dev->name, &newtarget);
                                done = 1;
@@ -701,17 +685,16 @@ static ssize_t bonding_store_arp_targets(struct device *d,
                        }
                }
                if (!done) {
-                       printk(KERN_ERR DRV_NAME
+                       pr_err(DRV_NAME
                               ": %s: ARP target table is full!\n",
                               bond->dev->name);
                        ret = -EINVAL;
                        goto out;
                }
 
-       }
-       else if (buf[0] == '-') {
+       } else if (buf[0] == '-')       {
                if ((newtarget == 0) || (newtarget == htonl(INADDR_BROADCAST))) {
-                       printk(KERN_ERR DRV_NAME
+                       pr_err(DRV_NAME
                               ": %s: invalid ARP target %pI4 specified for removal\n",
                               bond->dev->name, &newtarget);
                        ret = -EINVAL;
@@ -721,7 +704,7 @@ static ssize_t bonding_store_arp_targets(struct device *d,
                for (i = 0; (i < BOND_MAX_ARP_TARGETS) && !done; i++) {
                        if (targets[i] == newtarget) {
                                int j;
-                               printk(KERN_INFO DRV_NAME
+                               pr_info(DRV_NAME
                                       ": %s: removing ARP target %pI4.\n",
                                       bond->dev->name, &newtarget);
                                for (j = i; (j < (BOND_MAX_ARP_TARGETS-1)) && targets[j+1]; j++)
@@ -732,15 +715,15 @@ static ssize_t bonding_store_arp_targets(struct device *d,
                        }
                }
                if (!done) {
-                       printk(KERN_INFO DRV_NAME
+                       pr_info(DRV_NAME
                               ": %s: unable to remove nonexistent ARP target %pI4.\n",
                               bond->dev->name, &newtarget);
                        ret = -EINVAL;
                        goto out;
                }
-       }
-       else {
-               printk(KERN_ERR DRV_NAME ": no command found in arp_ip_targets file for bond %s. Use +<addr> or -<addr>.\n",
+       } else {
+               pr_err(DRV_NAME ": no command found in arp_ip_targets file"
+                      " for bond %s. Use +<addr> or -<addr>.\n",
                        bond->dev->name);
                ret = -EPERM;
                goto out;
@@ -773,7 +756,7 @@ static ssize_t bonding_store_downdelay(struct device *d,
        struct bonding *bond = to_bond(d);
 
        if (!(bond->params.miimon)) {
-               printk(KERN_ERR DRV_NAME
+               pr_err(DRV_NAME
                       ": %s: Unable to set down delay as MII monitoring is disabled\n",
                       bond->dev->name);
                ret = -EPERM;
@@ -781,14 +764,14 @@ static ssize_t bonding_store_downdelay(struct device *d,
        }
 
        if (sscanf(buf, "%d", &new_value) != 1) {
-               printk(KERN_ERR DRV_NAME
+               pr_err(DRV_NAME
                       ": %s: no down delay value specified.\n",
                       bond->dev->name);
                ret = -EINVAL;
                goto out;
        }
        if (new_value < 0) {
-               printk(KERN_ERR DRV_NAME
+               pr_err(DRV_NAME
                       ": %s: Invalid down delay value %d not in range %d-%d; rejected.\n",
                       bond->dev->name, new_value, 1, INT_MAX);
                ret = -EINVAL;
@@ -803,15 +786,17 @@ static ssize_t bonding_store_downdelay(struct device *d,
                               bond->params.miimon);
                }
                bond->params.downdelay = new_value / bond->params.miimon;
-               printk(KERN_INFO DRV_NAME ": %s: Setting down delay to %d.\n",
-                      bond->dev->name, bond->params.downdelay * bond->params.miimon);
+               pr_info(DRV_NAME ": %s: Setting down delay to %d.\n",
+                      bond->dev->name,
+                      bond->params.downdelay * bond->params.miimon);
 
        }
 
 out:
        return ret;
 }
-static DEVICE_ATTR(downdelay, S_IRUGO | S_IWUSR , bonding_show_downdelay, bonding_store_downdelay);
+static DEVICE_ATTR(downdelay, S_IRUGO | S_IWUSR,
+                  bonding_show_downdelay, bonding_store_downdelay);
 
 static ssize_t bonding_show_updelay(struct device *d,
                                    struct device_attribute *attr,
@@ -831,7 +816,7 @@ static ssize_t bonding_store_updelay(struct device *d,
        struct bonding *bond = to_bond(d);
 
        if (!(bond->params.miimon)) {
-               printk(KERN_ERR DRV_NAME
+               pr_err(DRV_NAME
                       ": %s: Unable to set up delay as MII monitoring is disabled\n",
                       bond->dev->name);
                ret = -EPERM;
@@ -839,14 +824,14 @@ static ssize_t bonding_store_updelay(struct device *d,
        }
 
        if (sscanf(buf, "%d", &new_value) != 1) {
-               printk(KERN_ERR DRV_NAME
+               pr_err(DRV_NAME
                       ": %s: no up delay value specified.\n",
                       bond->dev->name);
                ret = -EINVAL;
                goto out;
        }
        if (new_value < 0) {
-               printk(KERN_ERR DRV_NAME
+               pr_err(DRV_NAME
                       ": %s: Invalid down delay value %d not in range %d-%d; rejected.\n",
                       bond->dev->name, new_value, 1, INT_MAX);
                ret = -EINVAL;
@@ -861,7 +846,7 @@ static ssize_t bonding_store_updelay(struct device *d,
                               bond->params.miimon);
                }
                bond->params.updelay = new_value / bond->params.miimon;
-               printk(KERN_INFO DRV_NAME ": %s: Setting up delay to %d.\n",
+               pr_info(DRV_NAME ": %s: Setting up delay to %d.\n",
                       bond->dev->name, bond->params.updelay * bond->params.miimon);
 
        }
@@ -869,7 +854,8 @@ static ssize_t bonding_store_updelay(struct device *d,
 out:
        return ret;
 }
-static DEVICE_ATTR(updelay, S_IRUGO | S_IWUSR , bonding_show_updelay, bonding_store_updelay);
+static DEVICE_ATTR(updelay, S_IRUGO | S_IWUSR,
+                  bonding_show_updelay, bonding_store_updelay);
 
 /*
  * Show and set the LACP interval.  Interface must be down, and the mode
@@ -894,7 +880,7 @@ static ssize_t bonding_store_lacp(struct device *d,
        struct bonding *bond = to_bond(d);
 
        if (bond->dev->flags & IFF_UP) {
-               printk(KERN_ERR DRV_NAME
+               pr_err(DRV_NAME
                       ": %s: Unable to update LACP rate because interface is up.\n",
                       bond->dev->name);
                ret = -EPERM;
@@ -902,7 +888,7 @@ static ssize_t bonding_store_lacp(struct device *d,
        }
 
        if (bond->params.mode != BOND_MODE_8023AD) {
-               printk(KERN_ERR DRV_NAME
+               pr_err(DRV_NAME
                       ": %s: Unable to update LACP rate because bond is not in 802.3ad mode.\n",
                       bond->dev->name);
                ret = -EPERM;
@@ -913,19 +899,20 @@ static ssize_t bonding_store_lacp(struct device *d,
 
        if ((new_value == 1) || (new_value == 0)) {
                bond->params.lacp_fast = new_value;
-               printk(KERN_INFO DRV_NAME
-                      ": %s: Setting LACP rate to %s (%d).\n",
-                      bond->dev->name, bond_lacp_tbl[new_value].modename, new_value);
+               pr_info(DRV_NAME ": %s: Setting LACP rate to %s (%d).\n",
+                       bond->dev->name, bond_lacp_tbl[new_value].modename,
+                       new_value);
        } else {
-               printk(KERN_ERR DRV_NAME
+               pr_err(DRV_NAME
                       ": %s: Ignoring invalid LACP rate value %.*s.\n",
-                       bond->dev->name, (int)strlen(buf) - 1, buf);
+                      bond->dev->name, (int)strlen(buf) - 1, buf);
                ret = -EINVAL;
        }
 out:
        return ret;
 }
-static DEVICE_ATTR(lacp_rate, S_IRUGO | S_IWUSR, bonding_show_lacp, bonding_store_lacp);
+static DEVICE_ATTR(lacp_rate, S_IRUGO | S_IWUSR,
+                  bonding_show_lacp, bonding_store_lacp);
 
 static ssize_t bonding_show_ad_select(struct device *d,
                                      struct device_attribute *attr,
@@ -947,7 +934,7 @@ static ssize_t bonding_store_ad_select(struct device *d,
        struct bonding *bond = to_bond(d);
 
        if (bond->dev->flags & IFF_UP) {
-               printk(KERN_ERR DRV_NAME
+               pr_err(DRV_NAME
                       ": %s: Unable to update ad_select because interface "
                       "is up.\n", bond->dev->name);
                ret = -EPERM;
@@ -958,12 +945,12 @@ static ssize_t bonding_store_ad_select(struct device *d,
 
        if (new_value != -1) {
                bond->params.ad_select = new_value;
-               printk(KERN_INFO DRV_NAME
+               pr_info(DRV_NAME
                       ": %s: Setting ad_select to %s (%d).\n",
                       bond->dev->name, ad_select_tbl[new_value].modename,
                       new_value);
        } else {
-               printk(KERN_ERR DRV_NAME
+               pr_err(DRV_NAME
                       ": %s: Ignoring invalid ad_select value %.*s.\n",
                       bond->dev->name, (int)strlen(buf) - 1, buf);
                ret = -EINVAL;
@@ -971,8 +958,8 @@ static ssize_t bonding_store_ad_select(struct device *d,
 out:
        return ret;
 }
-
-static DEVICE_ATTR(ad_select, S_IRUGO | S_IWUSR, bonding_show_ad_select, bonding_store_ad_select);
+static DEVICE_ATTR(ad_select, S_IRUGO | S_IWUSR,
+                  bonding_show_ad_select, bonding_store_ad_select);
 
 /*
  * Show and set the number of grat ARP to send after a failover event.
@@ -994,14 +981,14 @@ static ssize_t bonding_store_n_grat_arp(struct device *d,
        struct bonding *bond = to_bond(d);
 
        if (sscanf(buf, "%d", &new_value) != 1) {
-               printk(KERN_ERR DRV_NAME
+               pr_err(DRV_NAME
                       ": %s: no num_grat_arp value specified.\n",
                       bond->dev->name);
                ret = -EINVAL;
                goto out;
        }
        if (new_value < 0 || new_value > 255) {
-               printk(KERN_ERR DRV_NAME
+               pr_err(DRV_NAME
                       ": %s: Invalid num_grat_arp value %d not in range 0-255; rejected.\n",
                       bond->dev->name, new_value);
                ret = -EINVAL;
@@ -1012,10 +999,11 @@ static ssize_t bonding_store_n_grat_arp(struct device *d,
 out:
        return ret;
 }
-static DEVICE_ATTR(num_grat_arp, S_IRUGO | S_IWUSR, bonding_show_n_grat_arp, bonding_store_n_grat_arp);
+static DEVICE_ATTR(num_grat_arp, S_IRUGO | S_IWUSR,
+                  bonding_show_n_grat_arp, bonding_store_n_grat_arp);
 
 /*
- * Show and set the number of unsolicted NA's to send after a failover event.
+ * Show and set the number of unsolicited NA's to send after a failover event.
  */
 static ssize_t bonding_show_n_unsol_na(struct device *d,
                                       struct device_attribute *attr,
@@ -1034,25 +1022,26 @@ static ssize_t bonding_store_n_unsol_na(struct device *d,
        struct bonding *bond = to_bond(d);
 
        if (sscanf(buf, "%d", &new_value) != 1) {
-               printk(KERN_ERR DRV_NAME
+               pr_err(DRV_NAME
                       ": %s: no num_unsol_na value specified.\n",
                       bond->dev->name);
                ret = -EINVAL;
                goto out;
        }
+
        if (new_value < 0 || new_value > 255) {
-               printk(KERN_ERR DRV_NAME
+               pr_err(DRV_NAME
                       ": %s: Invalid num_unsol_na value %d not in range 0-255; rejected.\n",
                       bond->dev->name, new_value);
                ret = -EINVAL;
                goto out;
-       } else {
+       } else
                bond->params.num_unsol_na = new_value;
-       }
 out:
        return ret;
 }
-static DEVICE_ATTR(num_unsol_na, S_IRUGO | S_IWUSR, bonding_show_n_unsol_na, bonding_store_n_unsol_na);
+static DEVICE_ATTR(num_unsol_na, S_IRUGO | S_IWUSR,
+                  bonding_show_n_unsol_na, bonding_store_n_unsol_na);
 
 /*
  * Show and set the MII monitor interval.  There are two tricky bits
@@ -1077,37 +1066,37 @@ static ssize_t bonding_store_miimon(struct device *d,
        struct bonding *bond = to_bond(d);
 
        if (sscanf(buf, "%d", &new_value) != 1) {
-               printk(KERN_ERR DRV_NAME
+               pr_err(DRV_NAME
                       ": %s: no miimon value specified.\n",
                       bond->dev->name);
                ret = -EINVAL;
                goto out;
        }
        if (new_value < 0) {
-               printk(KERN_ERR DRV_NAME
+               pr_err(DRV_NAME
                       ": %s: Invalid miimon value %d not in range %d-%d; rejected.\n",
                       bond->dev->name, new_value, 1, INT_MAX);
                ret = -EINVAL;
                goto out;
        } else {
-               printk(KERN_INFO DRV_NAME
+               pr_info(DRV_NAME
                       ": %s: Setting MII monitoring interval to %d.\n",
                       bond->dev->name, new_value);
                bond->params.miimon = new_value;
-               if(bond->params.updelay)
-                       printk(KERN_INFO DRV_NAME
+               if (bond->params.updelay)
+                       pr_info(DRV_NAME
                              ": %s: Note: Updating updelay (to %d) "
                              "since it is a multiple of the miimon value.\n",
                              bond->dev->name,
                              bond->params.updelay * bond->params.miimon);
-               if(bond->params.downdelay)
-                       printk(KERN_INFO DRV_NAME
+               if (bond->params.downdelay)
+                       pr_info(DRV_NAME
                              ": %s: Note: Updating downdelay (to %d) "
                              "since it is a multiple of the miimon value.\n",
                              bond->dev->name,
                              bond->params.downdelay * bond->params.miimon);
                if (bond->params.arp_interval) {
-                       printk(KERN_INFO DRV_NAME
+                       pr_info(DRV_NAME
                               ": %s: MII monitoring cannot be used with "
                               "ARP monitoring. Disabling ARP monitoring...\n",
                               bond->dev->name);
@@ -1141,7 +1130,8 @@ static ssize_t bonding_store_miimon(struct device *d,
 out:
        return ret;
 }
-static DEVICE_ATTR(miimon, S_IRUGO | S_IWUSR, bonding_show_miimon, bonding_store_miimon);
+static DEVICE_ATTR(miimon, S_IRUGO | S_IWUSR,
+                  bonding_show_miimon, bonding_store_miimon);
 
 /*
  * Show and set the primary slave.  The store function is much
@@ -1171,12 +1161,13 @@ static ssize_t bonding_store_primary(struct device *d,
        struct slave *slave;
        struct bonding *bond = to_bond(d);
 
-       rtnl_lock();
+       if (!rtnl_trylock())
+               return restart_syscall();
        read_lock(&bond->lock);
        write_lock_bh(&bond->curr_slave_lock);
 
        if (!USES_PRIMARY(bond->params.mode)) {
-               printk(KERN_INFO DRV_NAME
+               pr_info(DRV_NAME
                       ": %s: Unable to set primary slave; %s is in mode %d\n",
                       bond->dev->name, bond->dev->name, bond->params.mode);
        } else {
@@ -1184,7 +1175,7 @@ static ssize_t bonding_store_primary(struct device *d,
                        if (strnicmp
                            (slave->dev->name, buf,
                             strlen(slave->dev->name)) == 0) {
-                               printk(KERN_INFO DRV_NAME
+                               pr_info(DRV_NAME
                                       ": %s: Setting %s as primary slave.\n",
                                       bond->dev->name, slave->dev->name);
                                bond->primary_slave = slave;
@@ -1196,13 +1187,13 @@ static ssize_t bonding_store_primary(struct device *d,
                /* if we got here, then we didn't match the name of any slave */
 
                if (strlen(buf) == 0 || buf[0] == '\n') {
-                       printk(KERN_INFO DRV_NAME
+                       pr_info(DRV_NAME
                               ": %s: Setting primary slave to None.\n",
                               bond->dev->name);
                        bond->primary_slave = NULL;
                                bond_select_active_slave(bond);
                } else {
-                       printk(KERN_INFO DRV_NAME
+                       pr_info(DRV_NAME
                               ": %s: Unable to set %.*s as primary slave as it is not a slave.\n",
                               bond->dev->name, (int)strlen(buf) - 1, buf);
                }
@@ -1214,7 +1205,8 @@ out:
 
        return count;
 }
-static DEVICE_ATTR(primary, S_IRUGO | S_IWUSR, bonding_show_primary, bonding_store_primary);
+static DEVICE_ATTR(primary, S_IRUGO | S_IWUSR,
+                  bonding_show_primary, bonding_store_primary);
 
 /*
  * Show and set the use_carrier flag.
@@ -1237,7 +1229,7 @@ static ssize_t bonding_store_carrier(struct device *d,
 
 
        if (sscanf(buf, "%d", &new_value) != 1) {
-               printk(KERN_ERR DRV_NAME
+               pr_err(DRV_NAME
                       ": %s: no use_carrier value specified.\n",
                       bond->dev->name);
                ret = -EINVAL;
@@ -1245,17 +1237,18 @@ static ssize_t bonding_store_carrier(struct device *d,
        }
        if ((new_value == 0) || (new_value == 1)) {
                bond->params.use_carrier = new_value;
-               printk(KERN_INFO DRV_NAME ": %s: Setting use_carrier to %d.\n",
+               pr_info(DRV_NAME ": %s: Setting use_carrier to %d.\n",
                       bond->dev->name, new_value);
        } else {
-               printk(KERN_INFO DRV_NAME
+               pr_info(DRV_NAME
                       ": %s: Ignoring invalid use_carrier value %d.\n",
                       bond->dev->name, new_value);
        }
 out:
        return count;
 }
-static DEVICE_ATTR(use_carrier, S_IRUGO | S_IWUSR, bonding_show_carrier, bonding_store_carrier);
+static DEVICE_ATTR(use_carrier, S_IRUGO | S_IWUSR,
+                  bonding_show_carrier, bonding_store_carrier);
 
 
 /*
@@ -1284,19 +1277,20 @@ static ssize_t bonding_store_active_slave(struct device *d,
 {
        int i;
        struct slave *slave;
-        struct slave *old_active = NULL;
-        struct slave *new_active = NULL;
+       struct slave *old_active = NULL;
+       struct slave *new_active = NULL;
        struct bonding *bond = to_bond(d);
 
-       rtnl_lock();
+       if (!rtnl_trylock())
+               return restart_syscall();
        read_lock(&bond->lock);
        write_lock_bh(&bond->curr_slave_lock);
 
-       if (!USES_PRIMARY(bond->params.mode)) {
-               printk(KERN_INFO DRV_NAME
-                      ": %s: Unable to change active slave; %s is in mode %d\n",
-                      bond->dev->name, bond->dev->name, bond->params.mode);
-       else {
+       if (!USES_PRIMARY(bond->params.mode))
+               pr_info(DRV_NAME ": %s: Unable to change active slave;"
+                       " %s is in mode %d\n",
+                       bond->dev->name, bond->dev->name, bond->params.mode);
+       else {
                bond_for_each_slave(bond, slave, i) {
                        if (strnicmp
                            (slave->dev->name, buf,
@@ -1335,18 +1329,18 @@ static ssize_t bonding_store_active_slave(struct device *d,
                /* if we got here, then we didn't match the name of any slave */
 
                if (strlen(buf) == 0 || buf[0] == '\n') {
-                       printk(KERN_INFO DRV_NAME
-                              ": %s: Setting active slave to None.\n",
-                              bond->dev->name);
+                       pr_info(DRV_NAME
+                               ": %s: Setting active slave to None.\n",
+                               bond->dev->name);
                        bond->primary_slave = NULL;
-                               bond_select_active_slave(bond);
+                       bond_select_active_slave(bond);
                } else {
-                       printk(KERN_INFO DRV_NAME
-                              ": %s: Unable to set %.*s as active slave as it is not a slave.\n",
-                              bond->dev->name, (int)strlen(buf) - 1, buf);
+                       pr_info(DRV_NAME ": %s: Unable to set %.*s"
+                               " as active slave as it is not a slave.\n",
+                               bond->dev->name, (int)strlen(buf) - 1, buf);
                }
        }
-out:
+ out:
        write_unlock_bh(&bond->curr_slave_lock);
        read_unlock(&bond->lock);
        rtnl_unlock();
@@ -1354,7 +1348,8 @@ out:
        return count;
 
 }
-static DEVICE_ATTR(active_slave, S_IRUGO | S_IWUSR, bonding_show_active_slave, bonding_store_active_slave);
+static DEVICE_ATTR(active_slave, S_IRUGO | S_IWUSR,
+                  bonding_show_active_slave, bonding_store_active_slave);
 
 
 /*
@@ -1371,7 +1366,7 @@ static ssize_t bonding_show_mii_status(struct device *d,
        curr = bond->curr_active_slave;
        read_unlock(&bond->curr_slave_lock);
 
-       return sprintf(buf, "%s\n", (curr) ? "up" : "down");
+       return sprintf(buf, "%s\n", curr ? "up" : "down");
 }
 static DEVICE_ATTR(mii_status, S_IRUGO, bonding_show_mii_status, NULL);
 
@@ -1388,7 +1383,9 @@ static ssize_t bonding_show_ad_aggregator(struct device *d,
 
        if (bond->params.mode == BOND_MODE_8023AD) {
                struct ad_info ad_info;
-               count = sprintf(buf, "%d\n", (bond_3ad_get_active_agg_info(bond, &ad_info)) ?  0 : ad_info.aggregator_id);
+               count = sprintf(buf, "%d\n",
+                               (bond_3ad_get_active_agg_info(bond, &ad_info))
+                               ?  0 : ad_info.aggregator_id);
        }
 
        return count;
@@ -1408,7 +1405,9 @@ static ssize_t bonding_show_ad_num_ports(struct device *d,
 
        if (bond->params.mode == BOND_MODE_8023AD) {
                struct ad_info ad_info;
-               count = sprintf(buf, "%d\n", (bond_3ad_get_active_agg_info(bond, &ad_info)) ?  0: ad_info.ports);
+               count = sprintf(buf, "%d\n",
+                               (bond_3ad_get_active_agg_info(bond, &ad_info))
+                               ?  0 : ad_info.ports);
        }
 
        return count;
@@ -1428,7 +1427,9 @@ static ssize_t bonding_show_ad_actor_key(struct device *d,
 
        if (bond->params.mode == BOND_MODE_8023AD) {
                struct ad_info ad_info;
-               count = sprintf(buf, "%d\n", (bond_3ad_get_active_agg_info(bond, &ad_info)) ?  0 : ad_info.actor_key);
+               count = sprintf(buf, "%d\n",
+                               (bond_3ad_get_active_agg_info(bond, &ad_info))
+                               ?  0 : ad_info.actor_key);
        }
 
        return count;
@@ -1448,7 +1449,9 @@ static ssize_t bonding_show_ad_partner_key(struct device *d,
 
        if (bond->params.mode == BOND_MODE_8023AD) {
                struct ad_info ad_info;
-               count = sprintf(buf, "%d\n", (bond_3ad_get_active_agg_info(bond, &ad_info)) ?  0 : ad_info.partner_key);
+               count = sprintf(buf, "%d\n",
+                               (bond_3ad_get_active_agg_info(bond, &ad_info))
+                               ?  0 : ad_info.partner_key);
        }
 
        return count;
@@ -1468,9 +1471,8 @@ static ssize_t bonding_show_ad_partner_mac(struct device *d,
 
        if (bond->params.mode == BOND_MODE_8023AD) {
                struct ad_info ad_info;
-               if (!bond_3ad_get_active_agg_info(bond, &ad_info)) {
+               if (!bond_3ad_get_active_agg_info(bond, &ad_info))
                        count = sprintf(buf, "%pM\n", ad_info.partner_system);
-               }
        }
 
        return count;
@@ -1538,6 +1540,7 @@ int bond_create_sysfs(void)
                        printk(KERN_ERR
                               "network device named %s already exists in sysfs",
                               class_attr_bonding_masters.attr.name);
+               ret = 0;
        }
 
        return ret;
@@ -1562,12 +1565,8 @@ int bond_create_sysfs_entry(struct bonding *bond)
        int err;
 
        err = sysfs_create_group(&(dev->dev.kobj), &bonding_group);
-       if (err) {
+       if (err)
                printk(KERN_EMERG "eek! didn't create group!\n");
-       }
-
-       if (expected_refcount < 1)
-               expected_refcount = atomic_read(&bond->dev->dev.kobj.kref.refcount);
 
        return err;
 }
index ca849d2adf98d7a79861b6c333a6f0357fe789cf..6290a502742e324ddf952054369834f3d9cc4215 100644 (file)
@@ -286,8 +286,7 @@ static inline unsigned long slave_last_rx(struct bonding *bond,
 static inline void bond_set_slave_inactive_flags(struct slave *slave)
 {
        struct bonding *bond = netdev_priv(slave->dev->master);
-       if (bond->params.mode != BOND_MODE_TLB &&
-           bond->params.mode != BOND_MODE_ALB)
+       if (!bond_is_lb(bond))
                slave->state = BOND_STATE_BACKUP;
        slave->dev->priv_flags |= IFF_SLAVE_INACTIVE;
        if (slave_do_arp_validate(bond, slave))
@@ -322,8 +321,7 @@ static inline void bond_unset_master_alb_flags(struct bonding *bond)
 
 struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr);
 int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_device *slave_dev);
-int bond_create(char *name, struct bond_params *params);
-void bond_destroy(struct bonding *bond);
+int bond_create(const char *name);
 int  bond_release_and_destroy(struct net_device *bond_dev, struct net_device *slave_dev);
 int bond_create_sysfs(void);
 void bond_destroy_sysfs(void);
@@ -350,12 +348,8 @@ extern const struct bond_parm_tbl bond_mode_tbl[];
 extern const struct bond_parm_tbl xmit_hashtype_tbl[];
 extern const struct bond_parm_tbl arp_validate_tbl[];
 extern const struct bond_parm_tbl fail_over_mac_tbl[];
-extern struct bond_params bonding_defaults;
 extern struct bond_parm_tbl ad_select_tbl[];
 
-/* exported from bond_sysfs.c */
-extern struct rw_semaphore bonding_rwsem;
-
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 void bond_send_unsolicited_na(struct bonding *bond);
 void bond_register_ipv6_notifier(void);
index 57def0d573716941b0f86b8aeeb0b2f216031434..d5e18812bf497f615465a6f1a5c9f7708976fefe 100644 (file)
@@ -12,6 +12,68 @@ config CAN_VCAN
          This driver can also be built as a module.  If so, the module
          will be called vcan.
 
+config CAN_DEV
+       tristate "Platform CAN drivers with Netlink support"
+       depends on CAN
+       default Y
+       ---help---
+         Enables the common framework for platform CAN drivers with Netlink
+         support. This is the standard library for CAN drivers.
+         If unsure, say Y.
+
+config CAN_CALC_BITTIMING
+       bool "CAN bit-timing calculation"
+       depends on CAN_DEV
+       default Y
+       ---help---
+         If enabled, CAN bit-timing parameters will be calculated for the
+         bit-rate specified via Netlink argument "bitrate" when the device
+         get started. This works fine for the most common CAN controllers
+         with standard bit-rates but may fail for exotic bit-rates or CAN
+         source clock frequencies. Disabling saves some space, but then the
+         bit-timing parameters must be specified directly using the Netlink
+         arguments "tq", "prop_seg", "phase_seg1", "phase_seg2" and "sjw".
+         If unsure, say Y.
+
+config CAN_SJA1000
+       depends on CAN_DEV
+       tristate "Philips SJA1000"
+       ---help---
+         Driver for the SJA1000 CAN controllers from Philips or NXP
+
+config CAN_SJA1000_PLATFORM
+       depends on CAN_SJA1000
+       tristate "Generic Platform Bus based SJA1000 driver"
+       ---help---
+         This driver adds support for the SJA1000 chips connected to
+         the "platform bus" (Linux abstraction for directly to the
+         processor attached devices).  Which can be found on various
+         boards from Phytec (http://www.phytec.de) like the PCM027,
+         PCM038.
+
+config CAN_SJA1000_OF_PLATFORM
+       depends on CAN_SJA1000 && PPC_OF
+       tristate "Generic OF Platform Bus based SJA1000 driver"
+       ---help---
+         This driver adds support for the SJA1000 chips connected to
+         the OpenFirmware "platform bus" found on embedded systems with
+         OpenFirmware bindings, e.g. if you have a PowerPC based system
+         you may want to enable this option.
+
+config CAN_EMS_PCI
+       tristate "EMS CPC-PCI and CPC-PCIe Card"
+       depends on PCI && CAN_SJA1000
+       ---help---
+         This driver is for the one or two channel CPC-PCI and CPC-PCIe
+         cards from EMS Dr. Thomas Wuensche (http://www.ems-wuensche.de).
+
+config CAN_KVASER_PCI
+       tristate "Kvaser PCIcanx and Kvaser PCIcan PCI Cards"
+       depends on PCI && CAN_SJA1000
+       ---help---
+         This driver is for the the PCIcanx and PCIcan cards (1, 2 or
+         4 channel) from Kvaser (http://www.kvaser.com).
+
 config CAN_DEBUG_DEVICES
        bool "CAN devices debugging messages"
        depends on CAN
index c4bead705cd958877231557d67a7f105b2730aa8..523a941b358b1bd47aaa36888142b25963e7107d 100644 (file)
@@ -3,3 +3,10 @@
 #
 
 obj-$(CONFIG_CAN_VCAN)         += vcan.o
+
+obj-$(CONFIG_CAN_DEV)          += can-dev.o
+can-dev-y                      := dev.o
+
+obj-$(CONFIG_CAN_SJA1000)      += sja1000/
+
+ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c
new file mode 100644 (file)
index 0000000..574dadd
--- /dev/null
@@ -0,0 +1,657 @@
+/*
+ * Copyright (C) 2005 Marc Kleine-Budde, Pengutronix
+ * Copyright (C) 2006 Andrey Volkov, Varma Electronics
+ * Copyright (C) 2008-2009 Wolfgang Grandegger <wg@grandegger.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the version 2 of the GNU General Public License
+ * 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/module.h>
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <linux/if_arp.h>
+#include <linux/can.h>
+#include <linux/can/dev.h>
+#include <linux/can/netlink.h>
+#include <net/rtnetlink.h>
+
+#define MOD_DESC "CAN device driver interface"
+
+MODULE_DESCRIPTION(MOD_DESC);
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Wolfgang Grandegger <wg@grandegger.com>");
+
+#ifdef CONFIG_CAN_CALC_BITTIMING
+#define CAN_CALC_MAX_ERROR 50 /* in one-tenth of a percent */
+
+/*
+ * Bit-timing calculation derived from:
+ *
+ * Code based on LinCAN sources and H8S2638 project
+ * Copyright 2004-2006 Pavel Pisa - DCE FELK CVUT cz
+ * Copyright 2005      Stanislav Marek
+ * email: pisa@cmp.felk.cvut.cz
+ *
+ * Calculates proper bit-timing parameters for a specified bit-rate
+ * and sample-point, which can then be used to set the bit-timing
+ * registers of the CAN controller. You can find more information
+ * in the header file linux/can/netlink.h.
+ */
+static int can_update_spt(const struct can_bittiming_const *btc,
+                         int sampl_pt, int tseg, int *tseg1, int *tseg2)
+{
+       *tseg2 = tseg + 1 - (sampl_pt * (tseg + 1)) / 1000;
+       if (*tseg2 < btc->tseg2_min)
+               *tseg2 = btc->tseg2_min;
+       if (*tseg2 > btc->tseg2_max)
+               *tseg2 = btc->tseg2_max;
+       *tseg1 = tseg - *tseg2;
+       if (*tseg1 > btc->tseg1_max) {
+               *tseg1 = btc->tseg1_max;
+               *tseg2 = tseg - *tseg1;
+       }
+       return 1000 * (tseg + 1 - *tseg2) / (tseg + 1);
+}
+
+static int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt)
+{
+       struct can_priv *priv = netdev_priv(dev);
+       const struct can_bittiming_const *btc = priv->bittiming_const;
+       long rate, best_rate = 0;
+       long best_error = 1000000000, error = 0;
+       int best_tseg = 0, best_brp = 0, brp = 0;
+       int tsegall, tseg = 0, tseg1 = 0, tseg2 = 0;
+       int spt_error = 1000, spt = 0, sampl_pt;
+       u64 v64;
+
+       if (!priv->bittiming_const)
+               return -ENOTSUPP;
+
+       /* Use CIA recommended sample points */
+       if (bt->sample_point) {
+               sampl_pt = bt->sample_point;
+       } else {
+               if (bt->bitrate > 800000)
+                       sampl_pt = 750;
+               else if (bt->bitrate > 500000)
+                       sampl_pt = 800;
+               else
+                       sampl_pt = 875;
+       }
+
+       /* tseg even = round down, odd = round up */
+       for (tseg = (btc->tseg1_max + btc->tseg2_max) * 2 + 1;
+            tseg >= (btc->tseg1_min + btc->tseg2_min) * 2; tseg--) {
+               tsegall = 1 + tseg / 2;
+               /* Compute all possible tseg choices (tseg=tseg1+tseg2) */
+               brp = priv->clock.freq / (tsegall * bt->bitrate) + tseg % 2;
+               /* chose brp step which is possible in system */
+               brp = (brp / btc->brp_inc) * btc->brp_inc;
+               if ((brp < btc->brp_min) || (brp > btc->brp_max))
+                       continue;
+               rate = priv->clock.freq / (brp * tsegall);
+               error = bt->bitrate - rate;
+               /* tseg brp biterror */
+               if (error < 0)
+                       error = -error;
+               if (error > best_error)
+                       continue;
+               best_error = error;
+               if (error == 0) {
+                       spt = can_update_spt(btc, sampl_pt, tseg / 2,
+                                            &tseg1, &tseg2);
+                       error = sampl_pt - spt;
+                       if (error < 0)
+                               error = -error;
+                       if (error > spt_error)
+                               continue;
+                       spt_error = error;
+               }
+               best_tseg = tseg / 2;
+               best_brp = brp;
+               best_rate = rate;
+               if (error == 0)
+                       break;
+       }
+
+       if (best_error) {
+               /* Error in one-tenth of a percent */
+               error = (best_error * 1000) / bt->bitrate;
+               if (error > CAN_CALC_MAX_ERROR) {
+                       dev_err(dev->dev.parent,
+                               "bitrate error %ld.%ld%% too high\n",
+                               error / 10, error % 10);
+                       return -EDOM;
+               } else {
+                       dev_warn(dev->dev.parent, "bitrate error %ld.%ld%%\n",
+                                error / 10, error % 10);
+               }
+       }
+
+       /* real sample point */
+       bt->sample_point = can_update_spt(btc, sampl_pt, best_tseg,
+                                         &tseg1, &tseg2);
+
+       v64 = (u64)best_brp * 1000000000UL;
+       do_div(v64, priv->clock.freq);
+       bt->tq = (u32)v64;
+       bt->prop_seg = tseg1 / 2;
+       bt->phase_seg1 = tseg1 - bt->prop_seg;
+       bt->phase_seg2 = tseg2;
+       bt->sjw = 1;
+       bt->brp = best_brp;
+       /* real bit-rate */
+       bt->bitrate = priv->clock.freq / (bt->brp * (tseg1 + tseg2 + 1));
+
+       return 0;
+}
+#else /* !CONFIG_CAN_CALC_BITTIMING */
+static int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt)
+{
+       dev_err(dev->dev.parent, "bit-timing calculation not available\n");
+       return -EINVAL;
+}
+#endif /* CONFIG_CAN_CALC_BITTIMING */
+
+/*
+ * Checks the validity of the specified bit-timing parameters prop_seg,
+ * phase_seg1, phase_seg2 and sjw and tries to determine the bitrate
+ * prescaler value brp. You can find more information in the header
+ * file linux/can/netlink.h.
+ */
+static int can_fixup_bittiming(struct net_device *dev, struct can_bittiming *bt)
+{
+       struct can_priv *priv = netdev_priv(dev);
+       const struct can_bittiming_const *btc = priv->bittiming_const;
+       int tseg1, alltseg;
+       u64 brp64;
+
+       if (!priv->bittiming_const)
+               return -ENOTSUPP;
+
+       tseg1 = bt->prop_seg + bt->phase_seg1;
+       if (!bt->sjw)
+               bt->sjw = 1;
+       if (bt->sjw > btc->sjw_max ||
+           tseg1 < btc->tseg1_min || tseg1 > btc->tseg1_max ||
+           bt->phase_seg2 < btc->tseg2_min || bt->phase_seg2 > btc->tseg2_max)
+               return -ERANGE;
+
+       brp64 = (u64)priv->clock.freq * (u64)bt->tq;
+       if (btc->brp_inc > 1)
+               do_div(brp64, btc->brp_inc);
+       brp64 += 500000000UL - 1;
+       do_div(brp64, 1000000000UL); /* the practicable BRP */
+       if (btc->brp_inc > 1)
+               brp64 *= btc->brp_inc;
+       bt->brp = (u32)brp64;
+
+       if (bt->brp < btc->brp_min || bt->brp > btc->brp_max)
+               return -EINVAL;
+
+       alltseg = bt->prop_seg + bt->phase_seg1 + bt->phase_seg2 + 1;
+       bt->bitrate = priv->clock.freq / (bt->brp * alltseg);
+       bt->sample_point = ((tseg1 + 1) * 1000) / alltseg;
+
+       return 0;
+}
+
+int can_get_bittiming(struct net_device *dev, struct can_bittiming *bt)
+{
+       struct can_priv *priv = netdev_priv(dev);
+       int err;
+
+       /* Check if the CAN device has bit-timing parameters */
+       if (priv->bittiming_const) {
+
+               /* Non-expert mode? Check if the bitrate has been pre-defined */
+               if (!bt->tq)
+                       /* Determine bit-timing parameters */
+                       err = can_calc_bittiming(dev, bt);
+               else
+                       /* Check bit-timing params and calculate proper brp */
+                       err = can_fixup_bittiming(dev, bt);
+               if (err)
+                       return err;
+       }
+
+       return 0;
+}
+
+/*
+ * Local echo of CAN messages
+ *
+ * CAN network devices *should* support a local echo functionality
+ * (see Documentation/networking/can.txt). To test the handling of CAN
+ * interfaces that do not support the local echo both driver types are
+ * implemented. In the case that the driver does not support the echo
+ * the IFF_ECHO remains clear in dev->flags. This causes the PF_CAN core
+ * to perform the echo as a fallback solution.
+ */
+static void can_flush_echo_skb(struct net_device *dev)
+{
+       struct can_priv *priv = netdev_priv(dev);
+       struct net_device_stats *stats = &dev->stats;
+       int i;
+
+       for (i = 0; i < CAN_ECHO_SKB_MAX; i++) {
+               if (priv->echo_skb[i]) {
+                       kfree_skb(priv->echo_skb[i]);
+                       priv->echo_skb[i] = NULL;
+                       stats->tx_dropped++;
+                       stats->tx_aborted_errors++;
+               }
+       }
+}
+
+/*
+ * Put the skb on the stack to be looped backed locally lateron
+ *
+ * The function is typically called in the start_xmit function
+ * of the device driver. The driver must protect access to
+ * priv->echo_skb, if necessary.
+ */
+void can_put_echo_skb(struct sk_buff *skb, struct net_device *dev, int idx)
+{
+       struct can_priv *priv = netdev_priv(dev);
+
+       /* check flag whether this packet has to be looped back */
+       if (!(dev->flags & IFF_ECHO) || skb->pkt_type != PACKET_LOOPBACK) {
+               kfree_skb(skb);
+               return;
+       }
+
+       if (!priv->echo_skb[idx]) {
+               struct sock *srcsk = skb->sk;
+
+               if (atomic_read(&skb->users) != 1) {
+                       struct sk_buff *old_skb = skb;
+
+                       skb = skb_clone(old_skb, GFP_ATOMIC);
+                       kfree_skb(old_skb);
+                       if (!skb)
+                               return;
+               } else
+                       skb_orphan(skb);
+
+               skb->sk = srcsk;
+
+               /* make settings for echo to reduce code in irq context */
+               skb->protocol = htons(ETH_P_CAN);
+               skb->pkt_type = PACKET_BROADCAST;
+               skb->ip_summed = CHECKSUM_UNNECESSARY;
+               skb->dev = dev;
+
+               /* save this skb for tx interrupt echo handling */
+               priv->echo_skb[idx] = skb;
+       } else {
+               /* locking problem with netif_stop_queue() ?? */
+               dev_err(dev->dev.parent, "%s: BUG! echo_skb is occupied!\n",
+                       __func__);
+               kfree_skb(skb);
+       }
+}
+EXPORT_SYMBOL_GPL(can_put_echo_skb);
+
+/*
+ * Get the skb from the stack and loop it back locally
+ *
+ * The function is typically called when the TX done interrupt
+ * is handled in the device driver. The driver must protect
+ * access to priv->echo_skb, if necessary.
+ */
+void can_get_echo_skb(struct net_device *dev, int idx)
+{
+       struct can_priv *priv = netdev_priv(dev);
+
+       if ((dev->flags & IFF_ECHO) && priv->echo_skb[idx]) {
+               netif_rx(priv->echo_skb[idx]);
+               priv->echo_skb[idx] = NULL;
+       }
+}
+EXPORT_SYMBOL_GPL(can_get_echo_skb);
+
+/*
+ * CAN device restart for bus-off recovery
+ */
+void can_restart(unsigned long data)
+{
+       struct net_device *dev = (struct net_device *)data;
+       struct can_priv *priv = netdev_priv(dev);
+       struct net_device_stats *stats = &dev->stats;
+       struct sk_buff *skb;
+       struct can_frame *cf;
+       int err;
+
+       BUG_ON(netif_carrier_ok(dev));
+
+       /*
+        * No synchronization needed because the device is bus-off and
+        * no messages can come in or go out.
+        */
+       can_flush_echo_skb(dev);
+
+       /* send restart message upstream */
+       skb = dev_alloc_skb(sizeof(struct can_frame));
+       if (skb == NULL) {
+               err = -ENOMEM;
+               goto out;
+       }
+       skb->dev = dev;
+       skb->protocol = htons(ETH_P_CAN);
+       cf = (struct can_frame *)skb_put(skb, sizeof(struct can_frame));
+       memset(cf, 0, sizeof(struct can_frame));
+       cf->can_id = CAN_ERR_FLAG | CAN_ERR_RESTARTED;
+       cf->can_dlc = CAN_ERR_DLC;
+
+       netif_rx(skb);
+
+       dev->last_rx = jiffies;
+       stats->rx_packets++;
+       stats->rx_bytes += cf->can_dlc;
+
+       dev_dbg(dev->dev.parent, "restarted\n");
+       priv->can_stats.restarts++;
+
+       /* Now restart the device */
+       err = priv->do_set_mode(dev, CAN_MODE_START);
+
+out:
+       netif_carrier_on(dev);
+       if (err)
+               dev_err(dev->dev.parent, "Error %d during restart", err);
+}
+
+int can_restart_now(struct net_device *dev)
+{
+       struct can_priv *priv = netdev_priv(dev);
+
+       /*
+        * A manual restart is only permitted if automatic restart is
+        * disabled and the device is in the bus-off state
+        */
+       if (priv->restart_ms)
+               return -EINVAL;
+       if (priv->state != CAN_STATE_BUS_OFF)
+               return -EBUSY;
+
+       /* Runs as soon as possible in the timer context */
+       mod_timer(&priv->restart_timer, jiffies);
+
+       return 0;
+}
+
+/*
+ * CAN bus-off
+ *
+ * This functions should be called when the device goes bus-off to
+ * tell the netif layer that no more packets can be sent or received.
+ * If enabled, a timer is started to trigger bus-off recovery.
+ */
+void can_bus_off(struct net_device *dev)
+{
+       struct can_priv *priv = netdev_priv(dev);
+
+       dev_dbg(dev->dev.parent, "bus-off\n");
+
+       netif_carrier_off(dev);
+       priv->can_stats.bus_off++;
+
+       if (priv->restart_ms)
+               mod_timer(&priv->restart_timer,
+                         jiffies + (priv->restart_ms * HZ) / 1000);
+}
+EXPORT_SYMBOL_GPL(can_bus_off);
+
+static void can_setup(struct net_device *dev)
+{
+       dev->type = ARPHRD_CAN;
+       dev->mtu = sizeof(struct can_frame);
+       dev->hard_header_len = 0;
+       dev->addr_len = 0;
+       dev->tx_queue_len = 10;
+
+       /* New-style flags. */
+       dev->flags = IFF_NOARP;
+       dev->features = NETIF_F_NO_CSUM;
+}
+
+/*
+ * Allocate and setup space for the CAN network device
+ */
+struct net_device *alloc_candev(int sizeof_priv)
+{
+       struct net_device *dev;
+       struct can_priv *priv;
+
+       dev = alloc_netdev(sizeof_priv, "can%d", can_setup);
+       if (!dev)
+               return NULL;
+
+       priv = netdev_priv(dev);
+
+       priv->state = CAN_STATE_STOPPED;
+
+       init_timer(&priv->restart_timer);
+
+       return dev;
+}
+EXPORT_SYMBOL_GPL(alloc_candev);
+
+/*
+ * Free space of the CAN network device
+ */
+void free_candev(struct net_device *dev)
+{
+       free_netdev(dev);
+}
+EXPORT_SYMBOL_GPL(free_candev);
+
+/*
+ * Common open function when the device gets opened.
+ *
+ * This function should be called in the open function of the device
+ * driver.
+ */
+int open_candev(struct net_device *dev)
+{
+       struct can_priv *priv = netdev_priv(dev);
+
+       if (!priv->bittiming.tq && !priv->bittiming.bitrate) {
+               dev_err(dev->dev.parent, "bit-timing not yet defined\n");
+               return -EINVAL;
+       }
+
+       setup_timer(&priv->restart_timer, can_restart, (unsigned long)dev);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(open_candev);
+
+/*
+ * Common close function for cleanup before the device gets closed.
+ *
+ * This function should be called in the close function of the device
+ * driver.
+ */
+void close_candev(struct net_device *dev)
+{
+       struct can_priv *priv = netdev_priv(dev);
+
+       if (del_timer_sync(&priv->restart_timer))
+               dev_put(dev);
+       can_flush_echo_skb(dev);
+}
+EXPORT_SYMBOL_GPL(close_candev);
+
+/*
+ * CAN netlink interface
+ */
+static const struct nla_policy can_policy[IFLA_CAN_MAX + 1] = {
+       [IFLA_CAN_STATE]        = { .type = NLA_U32 },
+       [IFLA_CAN_CTRLMODE]     = { .len = sizeof(struct can_ctrlmode) },
+       [IFLA_CAN_RESTART_MS]   = { .type = NLA_U32 },
+       [IFLA_CAN_RESTART]      = { .type = NLA_U32 },
+       [IFLA_CAN_BITTIMING]    = { .len = sizeof(struct can_bittiming) },
+       [IFLA_CAN_BITTIMING_CONST]
+                               = { .len = sizeof(struct can_bittiming_const) },
+       [IFLA_CAN_CLOCK]        = { .len = sizeof(struct can_clock) },
+};
+
+static int can_changelink(struct net_device *dev,
+                         struct nlattr *tb[], struct nlattr *data[])
+{
+       struct can_priv *priv = netdev_priv(dev);
+       int err;
+
+       /* We need synchronization with dev->stop() */
+       ASSERT_RTNL();
+
+       if (data[IFLA_CAN_CTRLMODE]) {
+               struct can_ctrlmode *cm;
+
+               /* Do not allow changing controller mode while running */
+               if (dev->flags & IFF_UP)
+                       return -EBUSY;
+               cm = nla_data(data[IFLA_CAN_CTRLMODE]);
+               priv->ctrlmode &= ~cm->mask;
+               priv->ctrlmode |= cm->flags;
+       }
+
+       if (data[IFLA_CAN_BITTIMING]) {
+               struct can_bittiming bt;
+
+               /* Do not allow changing bittiming while running */
+               if (dev->flags & IFF_UP)
+                       return -EBUSY;
+               memcpy(&bt, nla_data(data[IFLA_CAN_BITTIMING]), sizeof(bt));
+               if ((!bt.bitrate && !bt.tq) || (bt.bitrate && bt.tq))
+                       return -EINVAL;
+               err = can_get_bittiming(dev, &bt);
+               if (err)
+                       return err;
+               memcpy(&priv->bittiming, &bt, sizeof(bt));
+
+               if (priv->do_set_bittiming) {
+                       /* Finally, set the bit-timing registers */
+                       err = priv->do_set_bittiming(dev);
+                       if (err)
+                               return err;
+               }
+       }
+
+       if (data[IFLA_CAN_RESTART_MS]) {
+               /* Do not allow changing restart delay while running */
+               if (dev->flags & IFF_UP)
+                       return -EBUSY;
+               priv->restart_ms = nla_get_u32(data[IFLA_CAN_RESTART_MS]);
+       }
+
+       if (data[IFLA_CAN_RESTART]) {
+               /* Do not allow a restart while not running */
+               if (!(dev->flags & IFF_UP))
+                       return -EINVAL;
+               err = can_restart_now(dev);
+               if (err)
+                       return err;
+       }
+
+       return 0;
+}
+
+static int can_fill_info(struct sk_buff *skb, const struct net_device *dev)
+{
+       struct can_priv *priv = netdev_priv(dev);
+       struct can_ctrlmode cm = {.flags = priv->ctrlmode};
+       enum can_state state = priv->state;
+
+       if (priv->do_get_state)
+               priv->do_get_state(dev, &state);
+       NLA_PUT_U32(skb, IFLA_CAN_STATE, state);
+       NLA_PUT(skb, IFLA_CAN_CTRLMODE, sizeof(cm), &cm);
+       NLA_PUT_U32(skb, IFLA_CAN_RESTART_MS, priv->restart_ms);
+       NLA_PUT(skb, IFLA_CAN_BITTIMING,
+               sizeof(priv->bittiming), &priv->bittiming);
+       NLA_PUT(skb, IFLA_CAN_CLOCK, sizeof(cm), &priv->clock);
+       if (priv->bittiming_const)
+               NLA_PUT(skb, IFLA_CAN_BITTIMING_CONST,
+                       sizeof(*priv->bittiming_const), priv->bittiming_const);
+
+       return 0;
+
+nla_put_failure:
+       return -EMSGSIZE;
+}
+
+static int can_fill_xstats(struct sk_buff *skb, const struct net_device *dev)
+{
+       struct can_priv *priv = netdev_priv(dev);
+
+       NLA_PUT(skb, IFLA_INFO_XSTATS,
+               sizeof(priv->can_stats), &priv->can_stats);
+
+       return 0;
+
+nla_put_failure:
+       return -EMSGSIZE;
+}
+
+static struct rtnl_link_ops can_link_ops __read_mostly = {
+       .kind           = "can",
+       .maxtype        = IFLA_CAN_MAX,
+       .policy         = can_policy,
+       .setup          = can_setup,
+       .changelink     = can_changelink,
+       .fill_info      = can_fill_info,
+       .fill_xstats    = can_fill_xstats,
+};
+
+/*
+ * Register the CAN network device
+ */
+int register_candev(struct net_device *dev)
+{
+       dev->rtnl_link_ops = &can_link_ops;
+       return register_netdev(dev);
+}
+EXPORT_SYMBOL_GPL(register_candev);
+
+/*
+ * Unregister the CAN network device
+ */
+void unregister_candev(struct net_device *dev)
+{
+       unregister_netdev(dev);
+}
+EXPORT_SYMBOL_GPL(unregister_candev);
+
+static __init int can_dev_init(void)
+{
+       int err;
+
+       err = rtnl_link_register(&can_link_ops);
+       if (!err)
+               printk(KERN_INFO MOD_DESC "\n");
+
+       return err;
+}
+module_init(can_dev_init);
+
+static __exit void can_dev_exit(void)
+{
+       rtnl_link_unregister(&can_link_ops);
+}
+module_exit(can_dev_exit);
+
+MODULE_ALIAS_RTNL_LINK("can");
diff --git a/drivers/net/can/sja1000/Makefile b/drivers/net/can/sja1000/Makefile
new file mode 100644 (file)
index 0000000..9d0c08d
--- /dev/null
@@ -0,0 +1,11 @@
+#
+#  Makefile for the SJA1000 CAN controller drivers.
+#
+
+obj-$(CONFIG_CAN_SJA1000) += sja1000.o
+obj-$(CONFIG_CAN_SJA1000_PLATFORM) += sja1000_platform.o
+obj-$(CONFIG_CAN_SJA1000_OF_PLATFORM) += sja1000_of_platform.o
+obj-$(CONFIG_CAN_EMS_PCI) += ems_pci.o
+obj-$(CONFIG_CAN_KVASER_PCI) += kvaser_pci.o
+
+ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
diff --git a/drivers/net/can/sja1000/ems_pci.c b/drivers/net/can/sja1000/ems_pci.c
new file mode 100644 (file)
index 0000000..121b641
--- /dev/null
@@ -0,0 +1,320 @@
+/*
+ * Copyright (C) 2007 Wolfgang Grandegger <wg@grandegger.com>
+ * Copyright (C) 2008 Markus Plessing <plessing@ems-wuensche.com>
+ * Copyright (C) 2008 Sebastian Haas <haas@ems-wuensche.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the version 2 of the GNU General Public License
+ * 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/kernel.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#include <linux/delay.h>
+#include <linux/pci.h>
+#include <linux/can.h>
+#include <linux/can/dev.h>
+#include <linux/io.h>
+
+#include "sja1000.h"
+
+#define DRV_NAME  "ems_pci"
+
+MODULE_AUTHOR("Sebastian Haas <haas@ems-wuenche.com>");
+MODULE_DESCRIPTION("Socket-CAN driver for EMS CPC-PCI/PCIe CAN cards");
+MODULE_SUPPORTED_DEVICE("EMS CPC-PCI/PCIe CAN card");
+MODULE_LICENSE("GPL v2");
+
+#define EMS_PCI_MAX_CHAN 2
+
+struct ems_pci_card {
+       int channels;
+
+       struct pci_dev *pci_dev;
+       struct net_device *net_dev[EMS_PCI_MAX_CHAN];
+
+       void __iomem *conf_addr;
+       void __iomem *base_addr;
+};
+
+#define EMS_PCI_CAN_CLOCK (16000000 / 2)
+
+/*
+ * Register definitions and descriptions are from LinCAN 0.3.3.
+ *
+ * PSB4610 PITA-2 bridge control registers
+ */
+#define PITA2_ICR           0x00       /* Interrupt Control Register */
+#define PITA2_ICR_INT0      0x00000002 /* [RC] INT0 Active/Clear */
+#define PITA2_ICR_INT0_EN   0x00020000 /* [RW] Enable INT0 */
+
+#define PITA2_MISC          0x1c       /* Miscellaneous Register */
+#define PITA2_MISC_CONFIG   0x04000000 /* Multiplexed parallel interface */
+
+/*
+ * The board configuration is probably following:
+ * RX1 is connected to ground.
+ * TX1 is not connected.
+ * CLKO is not connected.
+ * Setting the OCR register to 0xDA is a good idea.
+ * This means  normal output mode , push-pull and the correct polarity.
+ */
+#define EMS_PCI_OCR         (OCR_TX0_PUSHPULL | OCR_TX1_PUSHPULL)
+
+/*
+ * In the CDR register, you should set CBP to 1.
+ * You will probably also want to set the clock divider value to 7
+ * (meaning direct oscillator output) because the second SJA1000 chip
+ * is driven by the first one CLKOUT output.
+ */
+#define EMS_PCI_CDR             (CDR_CBP | CDR_CLKOUT_MASK)
+#define EMS_PCI_MEM_SIZE        4096  /* Size of the remapped io-memory */
+#define EMS_PCI_CAN_BASE_OFFSET 0x400 /* offset where the controllers starts */
+#define EMS_PCI_CAN_CTRL_SIZE   0x200 /* memory size for each controller */
+
+#define EMS_PCI_PORT_BYTES  0x4     /* Each register occupies 4 bytes */
+
+#define EMS_PCI_VENDOR_ID   0x110a  /* PCI device and vendor ID */
+#define EMS_PCI_DEVICE_ID   0x2104
+
+static struct pci_device_id ems_pci_tbl[] = {
+       {EMS_PCI_VENDOR_ID, EMS_PCI_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
+       {0,}
+};
+MODULE_DEVICE_TABLE(pci, ems_pci_tbl);
+
+/*
+ * Helper to read internal registers from card logic (not CAN)
+ */
+static u8 ems_pci_readb(struct ems_pci_card *card, unsigned int port)
+{
+       return readb(card->base_addr + (port * EMS_PCI_PORT_BYTES));
+}
+
+static u8 ems_pci_read_reg(const struct sja1000_priv *priv, int port)
+{
+       return readb(priv->reg_base + (port * EMS_PCI_PORT_BYTES));
+}
+
+static void ems_pci_write_reg(const struct sja1000_priv *priv, int port, u8 val)
+{
+       writeb(val, priv->reg_base + (port * EMS_PCI_PORT_BYTES));
+}
+
+static void ems_pci_post_irq(const struct sja1000_priv *priv)
+{
+       struct ems_pci_card *card = (struct ems_pci_card *)priv->priv;
+
+       /* reset int flag of pita */
+       writel(PITA2_ICR_INT0_EN | PITA2_ICR_INT0, card->conf_addr
+               + PITA2_ICR);
+}
+
+/*
+ * Check if a CAN controller is present at the specified location
+ * by trying to set 'em into the PeliCAN mode
+ */
+static inline int ems_pci_check_chan(const struct sja1000_priv *priv)
+{
+       unsigned char res;
+
+       /* Make sure SJA1000 is in reset mode */
+       ems_pci_write_reg(priv, REG_MOD, 1);
+
+       ems_pci_write_reg(priv, REG_CDR, CDR_PELICAN);
+
+       /* read reset-values */
+       res = ems_pci_read_reg(priv, REG_CDR);
+
+       if (res == CDR_PELICAN)
+               return 1;
+
+       return 0;
+}
+
+static void ems_pci_del_card(struct pci_dev *pdev)
+{
+       struct ems_pci_card *card = pci_get_drvdata(pdev);
+       struct net_device *dev;
+       int i = 0;
+
+       for (i = 0; i < card->channels; i++) {
+               dev = card->net_dev[i];
+
+               if (!dev)
+                       continue;
+
+               dev_info(&pdev->dev, "Removing %s.\n", dev->name);
+               unregister_sja1000dev(dev);
+               free_sja1000dev(dev);
+       }
+
+       if (card->base_addr != NULL)
+               pci_iounmap(card->pci_dev, card->base_addr);
+
+       if (card->conf_addr != NULL)
+               pci_iounmap(card->pci_dev, card->conf_addr);
+
+       kfree(card);
+
+       pci_disable_device(pdev);
+       pci_set_drvdata(pdev, NULL);
+}
+
+static void ems_pci_card_reset(struct ems_pci_card *card)
+{
+       /* Request board reset */
+       writeb(0, card->base_addr);
+}
+
+/*
+ * Probe PCI device for EMS CAN signature and register each available
+ * CAN channel to SJA1000 Socket-CAN subsystem.
+ */
+static int __devinit ems_pci_add_card(struct pci_dev *pdev,
+                                       const struct pci_device_id *ent)
+{
+       struct sja1000_priv *priv;
+       struct net_device *dev;
+       struct ems_pci_card *card;
+       int err, i;
+
+       /* Enabling PCI device */
+       if (pci_enable_device(pdev) < 0) {
+               dev_err(&pdev->dev, "Enabling PCI device failed\n");
+               return -ENODEV;
+       }
+
+       /* Allocating card structures to hold addresses, ... */
+       card = kzalloc(sizeof(struct ems_pci_card), GFP_KERNEL);
+       if (card == NULL) {
+               dev_err(&pdev->dev, "Unable to allocate memory\n");
+               pci_disable_device(pdev);
+               return -ENOMEM;
+       }
+
+       pci_set_drvdata(pdev, card);
+
+       card->pci_dev = pdev;
+
+       card->channels = 0;
+
+       /* Remap PITA configuration space, and controller memory area */
+       card->conf_addr = pci_iomap(pdev, 0, EMS_PCI_MEM_SIZE);
+       if (card->conf_addr == NULL) {
+               err = -ENOMEM;
+               goto failure_cleanup;
+       }
+
+       card->base_addr = pci_iomap(pdev, 1, EMS_PCI_MEM_SIZE);
+       if (card->base_addr == NULL) {
+               err = -ENOMEM;
+               goto failure_cleanup;
+       }
+
+       /* Configure PITA-2 parallel interface (enable MUX) */
+       writel(PITA2_MISC_CONFIG, card->conf_addr + PITA2_MISC);
+
+       /* Check for unique EMS CAN signature */
+       if (ems_pci_readb(card, 0) != 0x55 ||
+           ems_pci_readb(card, 1) != 0xAA ||
+           ems_pci_readb(card, 2) != 0x01 ||
+           ems_pci_readb(card, 3) != 0xCB ||
+           ems_pci_readb(card, 4) != 0x11) {
+               dev_err(&pdev->dev, "Not EMS Dr. Thomas Wuensche interface\n");
+               err = -ENODEV;
+               goto failure_cleanup;
+       }
+
+       ems_pci_card_reset(card);
+
+       /* Detect available channels */
+       for (i = 0; i < EMS_PCI_MAX_CHAN; i++) {
+               dev = alloc_sja1000dev(0);
+               if (dev == NULL) {
+                       err = -ENOMEM;
+                       goto failure_cleanup;
+               }
+
+               card->net_dev[i] = dev;
+               priv = netdev_priv(dev);
+               priv->priv = card;
+               priv->irq_flags = IRQF_SHARED;
+
+               dev->irq = pdev->irq;
+               priv->reg_base = card->base_addr + EMS_PCI_CAN_BASE_OFFSET
+                                       + (i * EMS_PCI_CAN_CTRL_SIZE);
+
+               /* Check if channel is present */
+               if (ems_pci_check_chan(priv)) {
+                       priv->read_reg  = ems_pci_read_reg;
+                       priv->write_reg = ems_pci_write_reg;
+                       priv->post_irq  = ems_pci_post_irq;
+                       priv->can.clock.freq = EMS_PCI_CAN_CLOCK;
+                       priv->ocr = EMS_PCI_OCR;
+                       priv->cdr = EMS_PCI_CDR;
+
+                       SET_NETDEV_DEV(dev, &pdev->dev);
+
+                       /* Enable interrupts from card */
+                       writel(PITA2_ICR_INT0_EN, card->conf_addr + PITA2_ICR);
+
+                       /* Register SJA1000 device */
+                       err = register_sja1000dev(dev);
+                       if (err) {
+                               dev_err(&pdev->dev, "Registering device failed "
+                                                       "(err=%d)\n", err);
+                               free_sja1000dev(dev);
+                               goto failure_cleanup;
+                       }
+
+                       card->channels++;
+
+                       dev_info(&pdev->dev, "Channel #%d at 0x%p, irq %d\n",
+                                       i + 1, priv->reg_base, dev->irq);
+               } else {
+                       free_sja1000dev(dev);
+               }
+       }
+
+       return 0;
+
+failure_cleanup:
+       dev_err(&pdev->dev, "Error: %d. Cleaning Up.\n", err);
+
+       ems_pci_del_card(pdev);
+
+       return err;
+}
+
+static struct pci_driver ems_pci_driver = {
+       .name = DRV_NAME,
+       .id_table = ems_pci_tbl,
+       .probe = ems_pci_add_card,
+       .remove = ems_pci_del_card,
+};
+
+static int __init ems_pci_init(void)
+{
+       return pci_register_driver(&ems_pci_driver);
+}
+
+static void __exit ems_pci_exit(void)
+{
+       pci_unregister_driver(&ems_pci_driver);
+}
+
+module_init(ems_pci_init);
+module_exit(ems_pci_exit);
+
diff --git a/drivers/net/can/sja1000/kvaser_pci.c b/drivers/net/can/sja1000/kvaser_pci.c
new file mode 100644 (file)
index 0000000..7dd7769
--- /dev/null
@@ -0,0 +1,412 @@
+/*
+ * Copyright (C) 2008 Per Dalen <per.dalen@cnw.se>
+ *
+ * Parts of this software are based on (derived) the following:
+ *
+ * - Kvaser linux driver, version 4.72 BETA
+ *   Copyright (C) 2002-2007 KVASER AB
+ *
+ * - Lincan driver, version 0.3.3, OCERA project
+ *   Copyright (C) 2004 Pavel Pisa
+ *   Copyright (C) 2001 Arnaud Westenberg
+ *
+ * - Socketcan SJA1000 drivers
+ *   Copyright (C) 2007 Wolfgang Grandegger <wg@grandegger.com>
+ *   Copyright (c) 2002-2007 Volkswagen Group Electronic Research
+ *   Copyright (c) 2003 Matthias Brukner, Trajet Gmbh, Rebenring 33,
+ *   38106 Braunschweig, GERMANY
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the version 2 of the GNU General Public License
+ * 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/kernel.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#include <linux/delay.h>
+#include <linux/pci.h>
+#include <linux/can.h>
+#include <linux/can/dev.h>
+#include <linux/io.h>
+
+#include "sja1000.h"
+
+#define DRV_NAME  "kvaser_pci"
+
+MODULE_AUTHOR("Per Dalen <per.dalen@cnw.se>");
+MODULE_DESCRIPTION("Socket-CAN driver for KVASER PCAN PCI cards");
+MODULE_SUPPORTED_DEVICE("KVASER PCAN PCI CAN card");
+MODULE_LICENSE("GPL v2");
+
+#define MAX_NO_OF_CHANNELS        4 /* max no of channels on a single card */
+
+struct kvaser_pci {
+       int channel;
+       struct pci_dev *pci_dev;
+       struct net_device *slave_dev[MAX_NO_OF_CHANNELS-1];
+       void __iomem *conf_addr;
+       void __iomem *res_addr;
+       int no_channels;
+       u8 xilinx_ver;
+};
+
+#define KVASER_PCI_CAN_CLOCK      (16000000 / 2)
+
+/*
+ * The board configuration is probably following:
+ * RX1 is connected to ground.
+ * TX1 is not connected.
+ * CLKO is not connected.
+ * Setting the OCR register to 0xDA is a good idea.
+ * This means  normal output mode , push-pull and the correct polarity.
+ */
+#define KVASER_PCI_OCR            (OCR_TX0_PUSHPULL | OCR_TX1_PUSHPULL)
+
+/*
+ * In the CDR register, you should set CBP to 1.
+ * You will probably also want to set the clock divider value to 0
+ * (meaning divide-by-2), the Pelican bit, and the clock-off bit
+ * (you will have no need for CLKOUT anyway).
+ */
+#define KVASER_PCI_CDR            (CDR_CBP | CDR_CLKOUT_MASK)
+
+/*
+ * These register values are valid for revision 14 of the Xilinx logic.
+ */
+#define XILINX_VERINT             7   /* Lower nibble simulate interrupts,
+                                        high nibble version number. */
+
+#define XILINX_PRESUMED_VERSION   14
+
+/*
+ * Important S5920 registers
+ */
+#define S5920_INTCSR              0x38
+#define S5920_PTCR                0x60
+#define INTCSR_ADDON_INTENABLE_M  0x2000
+
+
+#define KVASER_PCI_PORT_BYTES     0x20
+
+#define PCI_CONFIG_PORT_SIZE      0x80      /* size of the config io-memory */
+#define PCI_PORT_SIZE             0x80      /* size of a channel io-memory */
+#define PCI_PORT_XILINX_SIZE      0x08      /* size of a xilinx io-memory */
+
+#define KVASER_PCI_VENDOR_ID1     0x10e8    /* the PCI device and vendor IDs */
+#define KVASER_PCI_DEVICE_ID1     0x8406
+
+#define KVASER_PCI_VENDOR_ID2     0x1a07    /* the PCI device and vendor IDs */
+#define KVASER_PCI_DEVICE_ID2     0x0008
+
+static struct pci_device_id kvaser_pci_tbl[] = {
+       {KVASER_PCI_VENDOR_ID1, KVASER_PCI_DEVICE_ID1, PCI_ANY_ID, PCI_ANY_ID,},
+       {KVASER_PCI_VENDOR_ID2, KVASER_PCI_DEVICE_ID2, PCI_ANY_ID, PCI_ANY_ID,},
+       { 0,}
+};
+
+MODULE_DEVICE_TABLE(pci, kvaser_pci_tbl);
+
+static u8 kvaser_pci_read_reg(const struct sja1000_priv *priv, int port)
+{
+       return ioread8(priv->reg_base + port);
+}
+
+static void kvaser_pci_write_reg(const struct sja1000_priv *priv,
+                                int port, u8 val)
+{
+       iowrite8(val, priv->reg_base + port);
+}
+
+static void kvaser_pci_disable_irq(struct net_device *dev)
+{
+       struct sja1000_priv *priv = netdev_priv(dev);
+       struct kvaser_pci *board = priv->priv;
+       u32 intcsr;
+
+       /* Disable interrupts from card */
+       intcsr = ioread32(board->conf_addr + S5920_INTCSR);
+       intcsr &= ~INTCSR_ADDON_INTENABLE_M;
+       iowrite32(intcsr, board->conf_addr + S5920_INTCSR);
+}
+
+static void kvaser_pci_enable_irq(struct net_device *dev)
+{
+       struct sja1000_priv *priv = netdev_priv(dev);
+       struct kvaser_pci *board = priv->priv;
+       u32 tmp_en_io;
+
+       /* Enable interrupts from card */
+       tmp_en_io = ioread32(board->conf_addr + S5920_INTCSR);
+       tmp_en_io |= INTCSR_ADDON_INTENABLE_M;
+       iowrite32(tmp_en_io, board->conf_addr + S5920_INTCSR);
+}
+
+static int number_of_sja1000_chip(void __iomem *base_addr)
+{
+       u8 status;
+       int i;
+
+       for (i = 0; i < MAX_NO_OF_CHANNELS; i++) {
+               /* reset chip */
+               iowrite8(MOD_RM, base_addr +
+                        (i * KVASER_PCI_PORT_BYTES) + REG_MOD);
+               status = ioread8(base_addr +
+                                (i * KVASER_PCI_PORT_BYTES) + REG_MOD);
+               /* check reset bit */
+               if (!(status & MOD_RM))
+                       break;
+       }
+
+       return i;
+}
+
+static void kvaser_pci_del_chan(struct net_device *dev)
+{
+       struct sja1000_priv *priv;
+       struct kvaser_pci *board;
+       int i;
+
+       if (!dev)
+               return;
+       priv = netdev_priv(dev);
+       board = priv->priv;
+       if (!board)
+               return;
+
+       dev_info(&board->pci_dev->dev, "Removing device %s\n",
+                dev->name);
+
+       /* Disable PCI interrupts */
+       kvaser_pci_disable_irq(dev);
+
+       for (i = 0; i < board->no_channels - 1; i++) {
+               if (board->slave_dev[i]) {
+                       dev_info(&board->pci_dev->dev, "Removing device %s\n",
+                                board->slave_dev[i]->name);
+                       unregister_sja1000dev(board->slave_dev[i]);
+                       free_sja1000dev(board->slave_dev[i]);
+               }
+       }
+       unregister_sja1000dev(dev);
+
+       pci_iounmap(board->pci_dev, priv->reg_base);
+       pci_iounmap(board->pci_dev, board->conf_addr);
+       pci_iounmap(board->pci_dev, board->res_addr);
+
+       free_sja1000dev(dev);
+}
+
+static int kvaser_pci_add_chan(struct pci_dev *pdev, int channel,
+                              struct net_device **master_dev,
+                              void __iomem *conf_addr,
+                              void __iomem *res_addr,
+                              void __iomem *base_addr)
+{
+       struct net_device *dev;
+       struct sja1000_priv *priv;
+       struct kvaser_pci *board;
+       int err, init_step;
+
+       dev = alloc_sja1000dev(sizeof(struct kvaser_pci));
+       if (dev == NULL)
+               return -ENOMEM;
+
+       priv = netdev_priv(dev);
+       board = priv->priv;
+
+       board->pci_dev = pdev;
+       board->channel = channel;
+
+       /* S5920 */
+       board->conf_addr = conf_addr;
+
+       /* XILINX board wide address */
+       board->res_addr = res_addr;
+
+       if (channel == 0) {
+               board->xilinx_ver =
+                       ioread8(board->res_addr + XILINX_VERINT) >> 4;
+               init_step = 2;
+
+               /* Assert PTADR# - we're in passive mode so the other bits are
+                  not important */
+               iowrite32(0x80808080UL, board->conf_addr + S5920_PTCR);
+
+               /* Enable interrupts from card */
+               kvaser_pci_enable_irq(dev);
+       } else {
+               struct sja1000_priv *master_priv = netdev_priv(*master_dev);
+               struct kvaser_pci *master_board = master_priv->priv;
+               master_board->slave_dev[channel - 1] = dev;
+               master_board->no_channels = channel + 1;
+               board->xilinx_ver = master_board->xilinx_ver;
+       }
+
+       priv->reg_base = base_addr + channel * KVASER_PCI_PORT_BYTES;
+
+       priv->read_reg = kvaser_pci_read_reg;
+       priv->write_reg = kvaser_pci_write_reg;
+
+       priv->can.clock.freq = KVASER_PCI_CAN_CLOCK;
+
+       priv->ocr = KVASER_PCI_OCR;
+       priv->cdr = KVASER_PCI_CDR;
+
+       priv->irq_flags = IRQF_SHARED;
+       dev->irq = pdev->irq;
+
+       init_step = 4;
+
+       dev_info(&pdev->dev, "reg_base=%p conf_addr=%p irq=%d\n",
+                priv->reg_base, board->conf_addr, dev->irq);
+
+       SET_NETDEV_DEV(dev, &pdev->dev);
+
+       /* Register SJA1000 device */
+       err = register_sja1000dev(dev);
+       if (err) {
+               dev_err(&pdev->dev, "Registering device failed (err=%d)\n",
+                       err);
+               goto failure;
+       }
+
+       if (channel == 0)
+               *master_dev = dev;
+
+       return 0;
+
+failure:
+       kvaser_pci_del_chan(dev);
+       return err;
+}
+
+static int __devinit kvaser_pci_init_one(struct pci_dev *pdev,
+                                        const struct pci_device_id *ent)
+{
+       int err;
+       struct net_device *master_dev = NULL;
+       struct sja1000_priv *priv;
+       struct kvaser_pci *board;
+       int no_channels;
+       void __iomem *base_addr = NULL;
+       void __iomem *conf_addr = NULL;
+       void __iomem *res_addr = NULL;
+       int i;
+
+       dev_info(&pdev->dev, "initializing device %04x:%04x\n",
+                pdev->vendor, pdev->device);
+
+       err = pci_enable_device(pdev);
+       if (err)
+               goto failure;
+
+       err = pci_request_regions(pdev, DRV_NAME);
+       if (err)
+               goto failure_release_pci;
+
+       /* S5920 */
+       conf_addr = pci_iomap(pdev, 0, PCI_CONFIG_PORT_SIZE);
+       if (conf_addr == NULL) {
+               err = -ENODEV;
+               goto failure_release_regions;
+       }
+
+       /* XILINX board wide address */
+       res_addr = pci_iomap(pdev, 2, PCI_PORT_XILINX_SIZE);
+       if (res_addr == NULL) {
+               err = -ENOMEM;
+               goto failure_iounmap;
+       }
+
+       base_addr = pci_iomap(pdev, 1, PCI_PORT_SIZE);
+       if (base_addr == NULL) {
+               err = -ENOMEM;
+               goto failure_iounmap;
+       }
+
+       no_channels = number_of_sja1000_chip(base_addr);
+       if (no_channels == 0) {
+               err = -ENOMEM;
+               goto failure_iounmap;
+       }
+
+       for (i = 0; i < no_channels; i++) {
+               err = kvaser_pci_add_chan(pdev, i, &master_dev,
+                                         conf_addr, res_addr,
+                                         base_addr);
+               if (err)
+                       goto failure_cleanup;
+       }
+
+       priv = netdev_priv(master_dev);
+       board = priv->priv;
+
+       dev_info(&pdev->dev, "xilinx version=%d number of channels=%d\n",
+                board->xilinx_ver, board->no_channels);
+
+       pci_set_drvdata(pdev, master_dev);
+       return 0;
+
+failure_cleanup:
+       kvaser_pci_del_chan(master_dev);
+
+failure_iounmap:
+       if (conf_addr != NULL)
+               pci_iounmap(pdev, conf_addr);
+       if (res_addr != NULL)
+               pci_iounmap(pdev, res_addr);
+       if (base_addr != NULL)
+               pci_iounmap(pdev, base_addr);
+
+failure_release_regions:
+       pci_release_regions(pdev);
+
+failure_release_pci:
+       pci_disable_device(pdev);
+
+failure:
+       return err;
+
+}
+
+static void __devexit kvaser_pci_remove_one(struct pci_dev *pdev)
+{
+       struct net_device *dev = pci_get_drvdata(pdev);
+
+       kvaser_pci_del_chan(dev);
+
+       pci_release_regions(pdev);
+       pci_disable_device(pdev);
+       pci_set_drvdata(pdev, NULL);
+}
+
+static struct pci_driver kvaser_pci_driver = {
+       .name = DRV_NAME,
+       .id_table = kvaser_pci_tbl,
+       .probe = kvaser_pci_init_one,
+       .remove = __devexit_p(kvaser_pci_remove_one),
+};
+
+static int __init kvaser_pci_init(void)
+{
+       return pci_register_driver(&kvaser_pci_driver);
+}
+
+static void __exit kvaser_pci_exit(void)
+{
+       pci_unregister_driver(&kvaser_pci_driver);
+}
+
+module_init(kvaser_pci_init);
+module_exit(kvaser_pci_exit);
diff --git a/drivers/net/can/sja1000/sja1000.c b/drivers/net/can/sja1000/sja1000.c
new file mode 100644 (file)
index 0000000..571f133
--- /dev/null
@@ -0,0 +1,637 @@
+/*
+ * sja1000.c -  Philips SJA1000 network device driver
+ *
+ * Copyright (c) 2003 Matthias Brukner, Trajet Gmbh, Rebenring 33,
+ * 38106 Braunschweig, GERMANY
+ *
+ * Copyright (c) 2002-2007 Volkswagen Group Electronic Research
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Volkswagen nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * Alternatively, provided that this notice is retained in full, this
+ * software may be distributed under the terms of the GNU General
+ * Public License ("GPL") version 2, in which case the provisions of the
+ * GPL apply INSTEAD OF those given above.
+ *
+ * The provided data structures and external interfaces from this code
+ * are not restricted to be used by modules with a GPL compatible license.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * Send feedback to <socketcan-users@lists.berlios.de>
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/interrupt.h>
+#include <linux/ptrace.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/netdevice.h>
+#include <linux/if_arp.h>
+#include <linux/if_ether.h>
+#include <linux/skbuff.h>
+#include <linux/delay.h>
+
+#include <linux/can.h>
+#include <linux/can/dev.h>
+#include <linux/can/error.h>
+#include <linux/can/dev.h>
+
+#include "sja1000.h"
+
+#define DRV_NAME "sja1000"
+
+MODULE_AUTHOR("Oliver Hartkopp <oliver.hartkopp@volkswagen.de>");
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_DESCRIPTION(DRV_NAME "CAN netdevice driver");
+
+static struct can_bittiming_const sja1000_bittiming_const = {
+       .name = DRV_NAME,
+       .tseg1_min = 1,
+       .tseg1_max = 16,
+       .tseg2_min = 1,
+       .tseg2_max = 8,
+       .sjw_max = 4,
+       .brp_min = 1,
+       .brp_max = 64,
+       .brp_inc = 1,
+};
+
+static int sja1000_probe_chip(struct net_device *dev)
+{
+       struct sja1000_priv *priv = netdev_priv(dev);
+
+       if (priv->reg_base && (priv->read_reg(priv, 0) == 0xFF)) {
+               printk(KERN_INFO "%s: probing @0x%lX failed\n",
+                      DRV_NAME, dev->base_addr);
+               return 0;
+       }
+       return -1;
+}
+
+static void set_reset_mode(struct net_device *dev)
+{
+       struct sja1000_priv *priv = netdev_priv(dev);
+       unsigned char status = priv->read_reg(priv, REG_MOD);
+       int i;
+
+       /* disable interrupts */
+       priv->write_reg(priv, REG_IER, IRQ_OFF);
+
+       for (i = 0; i < 100; i++) {
+               /* check reset bit */
+               if (status & MOD_RM) {
+                       priv->can.state = CAN_STATE_STOPPED;
+                       return;
+               }
+
+               priv->write_reg(priv, REG_MOD, MOD_RM); /* reset chip */
+               udelay(10);
+               status = priv->read_reg(priv, REG_MOD);
+       }
+
+       dev_err(dev->dev.parent, "setting SJA1000 into reset mode failed!\n");
+}
+
+static void set_normal_mode(struct net_device *dev)
+{
+       struct sja1000_priv *priv = netdev_priv(dev);
+       unsigned char status = priv->read_reg(priv, REG_MOD);
+       int i;
+
+       for (i = 0; i < 100; i++) {
+               /* check reset bit */
+               if ((status & MOD_RM) == 0) {
+                       priv->can.state = CAN_STATE_ERROR_ACTIVE;
+                       /* enable all interrupts */
+                       priv->write_reg(priv, REG_IER, IRQ_ALL);
+                       return;
+               }
+
+               /* set chip to normal mode */
+               priv->write_reg(priv, REG_MOD, 0x00);
+               udelay(10);
+               status = priv->read_reg(priv, REG_MOD);
+       }
+
+       dev_err(dev->dev.parent, "setting SJA1000 into normal mode failed!\n");
+}
+
+static void sja1000_start(struct net_device *dev)
+{
+       struct sja1000_priv *priv = netdev_priv(dev);
+
+       /* leave reset mode */
+       if (priv->can.state != CAN_STATE_STOPPED)
+               set_reset_mode(dev);
+
+       /* Clear error counters and error code capture */
+       priv->write_reg(priv, REG_TXERR, 0x0);
+       priv->write_reg(priv, REG_RXERR, 0x0);
+       priv->read_reg(priv, REG_ECC);
+
+       /* leave reset mode */
+       set_normal_mode(dev);
+}
+
+static int sja1000_set_mode(struct net_device *dev, enum can_mode mode)
+{
+       struct sja1000_priv *priv = netdev_priv(dev);
+
+       if (!priv->open_time)
+               return -EINVAL;
+
+       switch (mode) {
+       case CAN_MODE_START:
+               sja1000_start(dev);
+               if (netif_queue_stopped(dev))
+                       netif_wake_queue(dev);
+               break;
+
+       default:
+               return -EOPNOTSUPP;
+       }
+
+       return 0;
+}
+
+static int sja1000_set_bittiming(struct net_device *dev)
+{
+       struct sja1000_priv *priv = netdev_priv(dev);
+       struct can_bittiming *bt = &priv->can.bittiming;
+       u8 btr0, btr1;
+
+       btr0 = ((bt->brp - 1) & 0x3f) | (((bt->sjw - 1) & 0x3) << 6);
+       btr1 = ((bt->prop_seg + bt->phase_seg1 - 1) & 0xf) |
+               (((bt->phase_seg2 - 1) & 0x7) << 4);
+       if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES)
+               btr1 |= 0x80;
+
+       dev_info(dev->dev.parent,
+                "setting BTR0=0x%02x BTR1=0x%02x\n", btr0, btr1);
+
+       priv->write_reg(priv, REG_BTR0, btr0);
+       priv->write_reg(priv, REG_BTR1, btr1);
+
+       return 0;
+}
+
+/*
+ * initialize SJA1000 chip:
+ *   - reset chip
+ *   - set output mode
+ *   - set baudrate
+ *   - enable interrupts
+ *   - start operating mode
+ */
+static void chipset_init(struct net_device *dev)
+{
+       struct sja1000_priv *priv = netdev_priv(dev);
+
+       /* set clock divider and output control register */
+       priv->write_reg(priv, REG_CDR, priv->cdr | CDR_PELICAN);
+
+       /* set acceptance filter (accept all) */
+       priv->write_reg(priv, REG_ACCC0, 0x00);
+       priv->write_reg(priv, REG_ACCC1, 0x00);
+       priv->write_reg(priv, REG_ACCC2, 0x00);
+       priv->write_reg(priv, REG_ACCC3, 0x00);
+
+       priv->write_reg(priv, REG_ACCM0, 0xFF);
+       priv->write_reg(priv, REG_ACCM1, 0xFF);
+       priv->write_reg(priv, REG_ACCM2, 0xFF);
+       priv->write_reg(priv, REG_ACCM3, 0xFF);
+
+       priv->write_reg(priv, REG_OCR, priv->ocr | OCR_MODE_NORMAL);
+}
+
+/*
+ * transmit a CAN message
+ * message layout in the sk_buff should be like this:
+ * xx xx xx xx  ff      ll   00 11 22 33 44 55 66 77
+ * [  can-id ] [flags] [len] [can data (up to 8 bytes]
+ */
+static int sja1000_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+       struct sja1000_priv *priv = netdev_priv(dev);
+       struct net_device_stats *stats = &dev->stats;
+       struct can_frame *cf = (struct can_frame *)skb->data;
+       uint8_t fi;
+       uint8_t dlc;
+       canid_t id;
+       uint8_t dreg;
+       int i;
+
+       netif_stop_queue(dev);
+
+       fi = dlc = cf->can_dlc;
+       id = cf->can_id;
+
+       if (id & CAN_RTR_FLAG)
+               fi |= FI_RTR;
+
+       if (id & CAN_EFF_FLAG) {
+               fi |= FI_FF;
+               dreg = EFF_BUF;
+               priv->write_reg(priv, REG_FI, fi);
+               priv->write_reg(priv, REG_ID1, (id & 0x1fe00000) >> (5 + 16));
+               priv->write_reg(priv, REG_ID2, (id & 0x001fe000) >> (5 + 8));
+               priv->write_reg(priv, REG_ID3, (id & 0x00001fe0) >> 5);
+               priv->write_reg(priv, REG_ID4, (id & 0x0000001f) << 3);
+       } else {
+               dreg = SFF_BUF;
+               priv->write_reg(priv, REG_FI, fi);
+               priv->write_reg(priv, REG_ID1, (id & 0x000007f8) >> 3);
+               priv->write_reg(priv, REG_ID2, (id & 0x00000007) << 5);
+       }
+
+       for (i = 0; i < dlc; i++)
+               priv->write_reg(priv, dreg++, cf->data[i]);
+
+       stats->tx_bytes += dlc;
+       dev->trans_start = jiffies;
+
+       can_put_echo_skb(skb, dev, 0);
+
+       priv->write_reg(priv, REG_CMR, CMD_TR);
+
+       return 0;
+}
+
+static void sja1000_rx(struct net_device *dev)
+{
+       struct sja1000_priv *priv = netdev_priv(dev);
+       struct net_device_stats *stats = &dev->stats;
+       struct can_frame *cf;
+       struct sk_buff *skb;
+       uint8_t fi;
+       uint8_t dreg;
+       canid_t id;
+       uint8_t dlc;
+       int i;
+
+       skb = dev_alloc_skb(sizeof(struct can_frame));
+       if (skb == NULL)
+               return;
+       skb->dev = dev;
+       skb->protocol = htons(ETH_P_CAN);
+
+       fi = priv->read_reg(priv, REG_FI);
+       dlc = fi & 0x0F;
+
+       if (fi & FI_FF) {
+               /* extended frame format (EFF) */
+               dreg = EFF_BUF;
+               id = (priv->read_reg(priv, REG_ID1) << (5 + 16))
+                   | (priv->read_reg(priv, REG_ID2) << (5 + 8))
+                   | (priv->read_reg(priv, REG_ID3) << 5)
+                   | (priv->read_reg(priv, REG_ID4) >> 3);
+               id |= CAN_EFF_FLAG;
+       } else {
+               /* standard frame format (SFF) */
+               dreg = SFF_BUF;
+               id = (priv->read_reg(priv, REG_ID1) << 3)
+                   | (priv->read_reg(priv, REG_ID2) >> 5);
+       }
+
+       if (fi & FI_RTR)
+               id |= CAN_RTR_FLAG;
+
+       cf = (struct can_frame *)skb_put(skb, sizeof(struct can_frame));
+       memset(cf, 0, sizeof(struct can_frame));
+       cf->can_id = id;
+       cf->can_dlc = dlc;
+       for (i = 0; i < dlc; i++)
+               cf->data[i] = priv->read_reg(priv, dreg++);
+
+       while (i < 8)
+               cf->data[i++] = 0;
+
+       /* release receive buffer */
+       priv->write_reg(priv, REG_CMR, CMD_RRB);
+
+       netif_rx(skb);
+
+       dev->last_rx = jiffies;
+       stats->rx_packets++;
+       stats->rx_bytes += dlc;
+}
+
+static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status)
+{
+       struct sja1000_priv *priv = netdev_priv(dev);
+       struct net_device_stats *stats = &dev->stats;
+       struct can_frame *cf;
+       struct sk_buff *skb;
+       enum can_state state = priv->can.state;
+       uint8_t ecc, alc;
+
+       skb = dev_alloc_skb(sizeof(struct can_frame));
+       if (skb == NULL)
+               return -ENOMEM;
+       skb->dev = dev;
+       skb->protocol = htons(ETH_P_CAN);
+       cf = (struct can_frame *)skb_put(skb, sizeof(struct can_frame));
+       memset(cf, 0, sizeof(struct can_frame));
+       cf->can_id = CAN_ERR_FLAG;
+       cf->can_dlc = CAN_ERR_DLC;
+
+       if (isrc & IRQ_DOI) {
+               /* data overrun interrupt */
+               dev_dbg(dev->dev.parent, "data overrun interrupt\n");
+               cf->can_id |= CAN_ERR_CRTL;
+               cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW;
+               stats->rx_over_errors++;
+               stats->rx_errors++;
+               priv->write_reg(priv, REG_CMR, CMD_CDO);        /* clear bit */
+       }
+
+       if (isrc & IRQ_EI) {
+               /* error warning interrupt */
+               dev_dbg(dev->dev.parent, "error warning interrupt\n");
+
+               if (status & SR_BS) {
+                       state = CAN_STATE_BUS_OFF;
+                       cf->can_id |= CAN_ERR_BUSOFF;
+                       can_bus_off(dev);
+               } else if (status & SR_ES) {
+                       state = CAN_STATE_ERROR_WARNING;
+               } else
+                       state = CAN_STATE_ERROR_ACTIVE;
+       }
+       if (isrc & IRQ_BEI) {
+               /* bus error interrupt */
+               priv->can.can_stats.bus_error++;
+               stats->rx_errors++;
+
+               ecc = priv->read_reg(priv, REG_ECC);
+
+               cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
+
+               switch (ecc & ECC_MASK) {
+               case ECC_BIT:
+                       cf->data[2] |= CAN_ERR_PROT_BIT;
+                       break;
+               case ECC_FORM:
+                       cf->data[2] |= CAN_ERR_PROT_FORM;
+                       break;
+               case ECC_STUFF:
+                       cf->data[2] |= CAN_ERR_PROT_STUFF;
+                       break;
+               default:
+                       cf->data[2] |= CAN_ERR_PROT_UNSPEC;
+                       cf->data[3] = ecc & ECC_SEG;
+                       break;
+               }
+               /* Error occured during transmission? */
+               if ((ecc & ECC_DIR) == 0)
+                       cf->data[2] |= CAN_ERR_PROT_TX;
+       }
+       if (isrc & IRQ_EPI) {
+               /* error passive interrupt */
+               dev_dbg(dev->dev.parent, "error passive interrupt\n");
+               if (status & SR_ES)
+                       state = CAN_STATE_ERROR_PASSIVE;
+               else
+                       state = CAN_STATE_ERROR_ACTIVE;
+       }
+       if (isrc & IRQ_ALI) {
+               /* arbitration lost interrupt */
+               dev_dbg(dev->dev.parent, "arbitration lost interrupt\n");
+               alc = priv->read_reg(priv, REG_ALC);
+               priv->can.can_stats.arbitration_lost++;
+               stats->rx_errors++;
+               cf->can_id |= CAN_ERR_LOSTARB;
+               cf->data[0] = alc & 0x1f;
+       }
+
+       if (state != priv->can.state && (state == CAN_STATE_ERROR_WARNING ||
+                                        state == CAN_STATE_ERROR_PASSIVE)) {
+               uint8_t rxerr = priv->read_reg(priv, REG_RXERR);
+               uint8_t txerr = priv->read_reg(priv, REG_TXERR);
+               cf->can_id |= CAN_ERR_CRTL;
+               if (state == CAN_STATE_ERROR_WARNING) {
+                       priv->can.can_stats.error_warning++;
+                       cf->data[1] = (txerr > rxerr) ?
+                               CAN_ERR_CRTL_TX_WARNING :
+                               CAN_ERR_CRTL_RX_WARNING;
+               } else {
+                       priv->can.can_stats.error_passive++;
+                       cf->data[1] = (txerr > rxerr) ?
+                               CAN_ERR_CRTL_TX_PASSIVE :
+                               CAN_ERR_CRTL_RX_PASSIVE;
+               }
+       }
+
+       priv->can.state = state;
+
+       netif_rx(skb);
+
+       dev->last_rx = jiffies;
+       stats->rx_packets++;
+       stats->rx_bytes += cf->can_dlc;
+
+       return 0;
+}
+
+irqreturn_t sja1000_interrupt(int irq, void *dev_id)
+{
+       struct net_device *dev = (struct net_device *)dev_id;
+       struct sja1000_priv *priv = netdev_priv(dev);
+       struct net_device_stats *stats = &dev->stats;
+       uint8_t isrc, status;
+       int n = 0;
+
+       /* Shared interrupts and IRQ off? */
+       if (priv->read_reg(priv, REG_IER) == IRQ_OFF)
+               return IRQ_NONE;
+
+       if (priv->pre_irq)
+               priv->pre_irq(priv);
+
+       while ((isrc = priv->read_reg(priv, REG_IR)) && (n < SJA1000_MAX_IRQ)) {
+               n++;
+               status = priv->read_reg(priv, REG_SR);
+
+               if (isrc & IRQ_WUI)
+                       dev_warn(dev->dev.parent, "wakeup interrupt\n");
+
+               if (isrc & IRQ_TI) {
+                       /* transmission complete interrupt */
+                       stats->tx_packets++;
+                       can_get_echo_skb(dev, 0);
+                       netif_wake_queue(dev);
+               }
+               if (isrc & IRQ_RI) {
+                       /* receive interrupt */
+                       while (status & SR_RBS) {
+                               sja1000_rx(dev);
+                               status = priv->read_reg(priv, REG_SR);
+                       }
+               }
+               if (isrc & (IRQ_DOI | IRQ_EI | IRQ_BEI | IRQ_EPI | IRQ_ALI)) {
+                       /* error interrupt */
+                       if (sja1000_err(dev, isrc, status))
+                               break;
+               }
+       }
+
+       if (priv->post_irq)
+               priv->post_irq(priv);
+
+       if (n >= SJA1000_MAX_IRQ)
+               dev_dbg(dev->dev.parent, "%d messages handled in ISR", n);
+
+       return (n) ? IRQ_HANDLED : IRQ_NONE;
+}
+EXPORT_SYMBOL_GPL(sja1000_interrupt);
+
+static int sja1000_open(struct net_device *dev)
+{
+       struct sja1000_priv *priv = netdev_priv(dev);
+       int err;
+
+       /* set chip into reset mode */
+       set_reset_mode(dev);
+
+       /* common open */
+       err = open_candev(dev);
+       if (err)
+               return err;
+
+       /* register interrupt handler, if not done by the device driver */
+       if (!(priv->flags & SJA1000_CUSTOM_IRQ_HANDLER)) {
+               err = request_irq(dev->irq, &sja1000_interrupt, priv->irq_flags,
+                                 dev->name, (void *)dev);
+               if (err) {
+                       close_candev(dev);
+                       return -EAGAIN;
+               }
+       }
+
+       /* init and start chi */
+       sja1000_start(dev);
+       priv->open_time = jiffies;
+
+       netif_start_queue(dev);
+
+       return 0;
+}
+
+static int sja1000_close(struct net_device *dev)
+{
+       struct sja1000_priv *priv = netdev_priv(dev);
+
+       netif_stop_queue(dev);
+       set_reset_mode(dev);
+
+       if (!(priv->flags & SJA1000_CUSTOM_IRQ_HANDLER))
+               free_irq(dev->irq, (void *)dev);
+
+       close_candev(dev);
+
+       priv->open_time = 0;
+
+       return 0;
+}
+
+struct net_device *alloc_sja1000dev(int sizeof_priv)
+{
+       struct net_device *dev;
+       struct sja1000_priv *priv;
+
+       dev = alloc_candev(sizeof(struct sja1000_priv) + sizeof_priv);
+       if (!dev)
+               return NULL;
+
+       priv = netdev_priv(dev);
+
+       priv->dev = dev;
+       priv->can.bittiming_const = &sja1000_bittiming_const;
+       priv->can.do_set_bittiming = sja1000_set_bittiming;
+       priv->can.do_set_mode = sja1000_set_mode;
+
+       if (sizeof_priv)
+               priv->priv = (void *)priv + sizeof(struct sja1000_priv);
+
+       return dev;
+}
+EXPORT_SYMBOL_GPL(alloc_sja1000dev);
+
+void free_sja1000dev(struct net_device *dev)
+{
+       free_candev(dev);
+}
+EXPORT_SYMBOL_GPL(free_sja1000dev);
+
+static const struct net_device_ops sja1000_netdev_ops = {
+       .ndo_open               = sja1000_open,
+       .ndo_stop               = sja1000_close,
+       .ndo_start_xmit         = sja1000_start_xmit,
+};
+
+int register_sja1000dev(struct net_device *dev)
+{
+       if (!sja1000_probe_chip(dev))
+               return -ENODEV;
+
+       dev->flags |= IFF_ECHO; /* we support local echo */
+       dev->netdev_ops = &sja1000_netdev_ops;
+
+       set_reset_mode(dev);
+       chipset_init(dev);
+
+       return register_candev(dev);
+}
+EXPORT_SYMBOL_GPL(register_sja1000dev);
+
+void unregister_sja1000dev(struct net_device *dev)
+{
+       set_reset_mode(dev);
+       unregister_candev(dev);
+}
+EXPORT_SYMBOL_GPL(unregister_sja1000dev);
+
+static __init int sja1000_init(void)
+{
+       printk(KERN_INFO "%s CAN netdevice driver\n", DRV_NAME);
+
+       return 0;
+}
+
+module_init(sja1000_init);
+
+static __exit void sja1000_exit(void)
+{
+       printk(KERN_INFO "%s: driver removed\n", DRV_NAME);
+}
+
+module_exit(sja1000_exit);
diff --git a/drivers/net/can/sja1000/sja1000.h b/drivers/net/can/sja1000/sja1000.h
new file mode 100644 (file)
index 0000000..302d2c7
--- /dev/null
@@ -0,0 +1,181 @@
+/*
+ * sja1000.h -  Philips SJA1000 network device driver
+ *
+ * Copyright (c) 2003 Matthias Brukner, Trajet Gmbh, Rebenring 33,
+ * 38106 Braunschweig, GERMANY
+ *
+ * Copyright (c) 2002-2007 Volkswagen Group Electronic Research
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Volkswagen nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * Alternatively, provided that this notice is retained in full, this
+ * software may be distributed under the terms of the GNU General
+ * Public License ("GPL") version 2, in which case the provisions of the
+ * GPL apply INSTEAD OF those given above.
+ *
+ * The provided data structures and external interfaces from this code
+ * are not restricted to be used by modules with a GPL compatible license.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * Send feedback to <socketcan-users@lists.berlios.de>
+ *
+ */
+
+#ifndef SJA1000_DEV_H
+#define SJA1000_DEV_H
+
+#include <linux/can/dev.h>
+#include <linux/can/platform/sja1000.h>
+
+#define SJA1000_MAX_IRQ 20     /* max. number of interrupts handled in ISR */
+
+/* SJA1000 registers - manual section 6.4 (Pelican Mode) */
+#define REG_MOD                0x00
+#define REG_CMR                0x01
+#define REG_SR         0x02
+#define REG_IR         0x03
+#define REG_IER                0x04
+#define REG_ALC                0x0B
+#define REG_ECC                0x0C
+#define REG_EWL                0x0D
+#define REG_RXERR      0x0E
+#define REG_TXERR      0x0F
+#define REG_ACCC0      0x10
+#define REG_ACCC1      0x11
+#define REG_ACCC2      0x12
+#define REG_ACCC3      0x13
+#define REG_ACCM0      0x14
+#define REG_ACCM1      0x15
+#define REG_ACCM2      0x16
+#define REG_ACCM3      0x17
+#define REG_RMC                0x1D
+#define REG_RBSA       0x1E
+
+/* Common registers - manual section 6.5 */
+#define REG_BTR0       0x06
+#define REG_BTR1       0x07
+#define REG_OCR                0x08
+#define REG_CDR                0x1F
+
+#define REG_FI         0x10
+#define SFF_BUF                0x13
+#define EFF_BUF                0x15
+
+#define FI_FF          0x80
+#define FI_RTR         0x40
+
+#define REG_ID1                0x11
+#define REG_ID2                0x12
+#define REG_ID3                0x13
+#define REG_ID4                0x14
+
+#define CAN_RAM                0x20
+
+/* mode register */
+#define MOD_RM         0x01
+#define MOD_LOM                0x02
+#define MOD_STM                0x04
+#define MOD_AFM                0x08
+#define MOD_SM         0x10
+
+/* commands */
+#define CMD_SRR                0x10
+#define CMD_CDO                0x08
+#define CMD_RRB                0x04
+#define CMD_AT         0x02
+#define CMD_TR         0x01
+
+/* interrupt sources */
+#define IRQ_BEI                0x80
+#define IRQ_ALI                0x40
+#define IRQ_EPI                0x20
+#define IRQ_WUI                0x10
+#define IRQ_DOI                0x08
+#define IRQ_EI         0x04
+#define IRQ_TI         0x02
+#define IRQ_RI         0x01
+#define IRQ_ALL                0xFF
+#define IRQ_OFF                0x00
+
+/* status register content */
+#define SR_BS          0x80
+#define SR_ES          0x40
+#define SR_TS          0x20
+#define SR_RS          0x10
+#define SR_TCS         0x08
+#define SR_TBS         0x04
+#define SR_DOS         0x02
+#define SR_RBS         0x01
+
+#define SR_CRIT (SR_BS|SR_ES)
+
+/* ECC register */
+#define ECC_SEG                0x1F
+#define ECC_DIR                0x20
+#define ECC_ERR                6
+#define ECC_BIT                0x00
+#define ECC_FORM       0x40
+#define ECC_STUFF      0x80
+#define ECC_MASK       0xc0
+
+/*
+ * Flags for sja1000priv.flags
+ */
+#define SJA1000_CUSTOM_IRQ_HANDLER 0x1
+
+/*
+ * SJA1000 private data structure
+ */
+struct sja1000_priv {
+       struct can_priv can;    /* must be the first member */
+       int open_time;
+       struct sk_buff *echo_skb;
+
+       /* the lower-layer is responsible for appropriate locking */
+       u8 (*read_reg) (const struct sja1000_priv *priv, int reg);
+       void (*write_reg) (const struct sja1000_priv *priv, int reg, u8 val);
+       void (*pre_irq) (const struct sja1000_priv *priv);
+       void (*post_irq) (const struct sja1000_priv *priv);
+
+       void *priv;             /* for board-specific data */
+       struct net_device *dev;
+
+       void __iomem *reg_base;  /* ioremap'ed address to registers */
+       unsigned long irq_flags; /* for request_irq() */
+
+       u16 flags;              /* custom mode flags */
+       u8 ocr;                 /* output control register */
+       u8 cdr;                 /* clock divider register */
+};
+
+struct net_device *alloc_sja1000dev(int sizeof_priv);
+void free_sja1000dev(struct net_device *dev);
+int register_sja1000dev(struct net_device *dev);
+void unregister_sja1000dev(struct net_device *dev);
+
+irqreturn_t sja1000_interrupt(int irq, void *dev_id);
+
+#endif /* SJA1000_DEV_H */
diff --git a/drivers/net/can/sja1000/sja1000_of_platform.c b/drivers/net/can/sja1000/sja1000_of_platform.c
new file mode 100644 (file)
index 0000000..3373560
--- /dev/null
@@ -0,0 +1,235 @@
+/*
+ * Driver for SJA1000 CAN controllers on the OpenFirmware platform bus
+ *
+ * Copyright (C) 2008-2009 Wolfgang Grandegger <wg@grandegger.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the version 2 of the GNU General Public License
+ * 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.
+ */
+
+/* This is a generic driver for SJA1000 chips on the OpenFirmware platform
+ * bus found on embedded PowerPC systems. You need a SJA1000 CAN node
+ * definition in your flattened device tree source (DTS) file similar to:
+ *
+ *   can@3,100 {
+ *           compatible = "nxp,sja1000";
+ *           reg = <3 0x100 0x80>;
+ *           interrupts = <2 0>;
+ *           interrupt-parent = <&mpic>;
+ *           nxp,external-clock-frequency = <16000000>;
+ *   };
+ *
+ * See "Documentation/powerpc/dts-bindings/can/sja1000.txt" for further
+ * information.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#include <linux/delay.h>
+#include <linux/can.h>
+#include <linux/can/dev.h>
+
+#include <linux/of_platform.h>
+#include <asm/prom.h>
+
+#include "sja1000.h"
+
+#define DRV_NAME "sja1000_of_platform"
+
+MODULE_AUTHOR("Wolfgang Grandegger <wg@grandegger.com>");
+MODULE_DESCRIPTION("Socket-CAN driver for SJA1000 on the OF platform bus");
+MODULE_LICENSE("GPL v2");
+
+#define SJA1000_OFP_CAN_CLOCK  (16000000 / 2)
+
+#define SJA1000_OFP_OCR        OCR_TX0_PULLDOWN
+#define SJA1000_OFP_CDR        (CDR_CBP | CDR_CLK_OFF)
+
+static u8 sja1000_ofp_read_reg(const struct sja1000_priv *priv, int reg)
+{
+       return in_8(priv->reg_base + reg);
+}
+
+static void sja1000_ofp_write_reg(const struct sja1000_priv *priv,
+                                 int reg, u8 val)
+{
+       out_8(priv->reg_base + reg, val);
+}
+
+static int __devexit sja1000_ofp_remove(struct of_device *ofdev)
+{
+       struct net_device *dev = dev_get_drvdata(&ofdev->dev);
+       struct sja1000_priv *priv = netdev_priv(dev);
+       struct device_node *np = ofdev->node;
+       struct resource res;
+
+       dev_set_drvdata(&ofdev->dev, NULL);
+
+       unregister_sja1000dev(dev);
+       free_sja1000dev(dev);
+       iounmap(priv->reg_base);
+       irq_dispose_mapping(dev->irq);
+
+       of_address_to_resource(np, 0, &res);
+       release_mem_region(res.start, resource_size(&res));
+
+       return 0;
+}
+
+static int __devinit sja1000_ofp_probe(struct of_device *ofdev,
+                                      const struct of_device_id *id)
+{
+       struct device_node *np = ofdev->node;
+       struct net_device *dev;
+       struct sja1000_priv *priv;
+       struct resource res;
+       const u32 *prop;
+       int err, irq, res_size, prop_size;
+       void __iomem *base;
+
+       err = of_address_to_resource(np, 0, &res);
+       if (err) {
+               dev_err(&ofdev->dev, "invalid address\n");
+               return err;
+       }
+
+       res_size = resource_size(&res);
+
+       if (!request_mem_region(res.start, res_size, DRV_NAME)) {
+               dev_err(&ofdev->dev, "couldn't request %#llx..%#llx\n",
+                       (unsigned long long)res.start,
+                       (unsigned long long)res.end);
+               return -EBUSY;
+       }
+
+       base = ioremap_nocache(res.start, res_size);
+       if (!base) {
+               dev_err(&ofdev->dev, "couldn't ioremap %#llx..%#llx\n",
+                       (unsigned long long)res.start,
+                       (unsigned long long)res.end);
+               err = -ENOMEM;
+               goto exit_release_mem;
+       }
+
+       irq = irq_of_parse_and_map(np, 0);
+       if (irq == NO_IRQ) {
+               dev_err(&ofdev->dev, "no irq found\n");
+               err = -ENODEV;
+               goto exit_unmap_mem;
+       }
+
+       dev = alloc_sja1000dev(0);
+       if (!dev) {
+               err = -ENOMEM;
+               goto exit_dispose_irq;
+       }
+
+       priv = netdev_priv(dev);
+
+       priv->read_reg = sja1000_ofp_read_reg;
+       priv->write_reg = sja1000_ofp_write_reg;
+
+       prop = of_get_property(np, "nxp,external-clock-frequency", &prop_size);
+       if (prop && (prop_size ==  sizeof(u32)))
+               priv->can.clock.freq = *prop / 2;
+       else
+               priv->can.clock.freq = SJA1000_OFP_CAN_CLOCK; /* default */
+
+       prop = of_get_property(np, "nxp,tx-output-mode", &prop_size);
+       if (prop && (prop_size == sizeof(u32)))
+               priv->ocr |= *prop & OCR_MODE_MASK;
+       else
+               priv->ocr |= OCR_MODE_NORMAL; /* default */
+
+       prop = of_get_property(np, "nxp,tx-output-config", &prop_size);
+       if (prop && (prop_size == sizeof(u32)))
+               priv->ocr |= (*prop << OCR_TX_SHIFT) & OCR_TX_MASK;
+       else
+               priv->ocr |= OCR_TX0_PULLDOWN; /* default */
+
+       prop = of_get_property(np, "nxp,clock-out-frequency", &prop_size);
+       if (prop && (prop_size == sizeof(u32)) && *prop) {
+               u32 divider = priv->can.clock.freq * 2 / *prop;
+
+               if (divider > 1)
+                       priv->cdr |= divider / 2 - 1;
+               else
+                       priv->cdr |= CDR_CLKOUT_MASK;
+       } else {
+               priv->cdr |= CDR_CLK_OFF; /* default */
+       }
+
+       prop = of_get_property(np, "nxp,no-comparator-bypass", NULL);
+       if (!prop)
+               priv->cdr |= CDR_CBP; /* default */
+
+       priv->irq_flags = IRQF_SHARED;
+       priv->reg_base = base;
+
+       dev->irq = irq;
+
+       dev_info(&ofdev->dev,
+                "reg_base=0x%p irq=%d clock=%d ocr=0x%02x cdr=0x%02x\n",
+                priv->reg_base, dev->irq, priv->can.clock.freq,
+                priv->ocr, priv->cdr);
+
+       dev_set_drvdata(&ofdev->dev, dev);
+       SET_NETDEV_DEV(dev, &ofdev->dev);
+
+       err = register_sja1000dev(dev);
+       if (err) {
+               dev_err(&ofdev->dev, "registering %s failed (err=%d)\n",
+                       DRV_NAME, err);
+               goto exit_free_sja1000;
+       }
+
+       return 0;
+
+exit_free_sja1000:
+       free_sja1000dev(dev);
+exit_dispose_irq:
+       irq_dispose_mapping(irq);
+exit_unmap_mem:
+       iounmap(base);
+exit_release_mem:
+       release_mem_region(res.start, res_size);
+
+       return err;
+}
+
+static struct of_device_id __devinitdata sja1000_ofp_table[] = {
+       {.compatible = "nxp,sja1000"},
+       {},
+};
+
+static struct of_platform_driver sja1000_ofp_driver = {
+       .owner = THIS_MODULE,
+       .name = DRV_NAME,
+       .probe = sja1000_ofp_probe,
+       .remove = __devexit_p(sja1000_ofp_remove),
+       .match_table = sja1000_ofp_table,
+};
+
+static int __init sja1000_ofp_init(void)
+{
+       return of_register_platform_driver(&sja1000_ofp_driver);
+}
+module_init(sja1000_ofp_init);
+
+static void __exit sja1000_ofp_exit(void)
+{
+       return of_unregister_platform_driver(&sja1000_ofp_driver);
+};
+module_exit(sja1000_ofp_exit);
diff --git a/drivers/net/can/sja1000/sja1000_platform.c b/drivers/net/can/sja1000/sja1000_platform.c
new file mode 100644 (file)
index 0000000..628374c
--- /dev/null
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2005 Sascha Hauer, Pengutronix
+ * Copyright (C) 2007 Wolfgang Grandegger <wg@grandegger.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the version 2 of the GNU General Public License
+ * 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/kernel.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#include <linux/delay.h>
+#include <linux/pci.h>
+#include <linux/platform_device.h>
+#include <linux/irq.h>
+#include <linux/can.h>
+#include <linux/can/dev.h>
+#include <linux/can/platform/sja1000.h>
+#include <linux/io.h>
+
+#include "sja1000.h"
+
+#define DRV_NAME "sja1000_platform"
+
+MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
+MODULE_DESCRIPTION("Socket-CAN driver for SJA1000 on the platform bus");
+MODULE_LICENSE("GPL v2");
+
+static u8 sp_read_reg(const struct sja1000_priv *priv, int reg)
+{
+       return ioread8(priv->reg_base + reg);
+}
+
+static void sp_write_reg(const struct sja1000_priv *priv, int reg, u8 val)
+{
+       iowrite8(val, priv->reg_base + reg);
+}
+
+static int sp_probe(struct platform_device *pdev)
+{
+       int err;
+       void __iomem *addr;
+       struct net_device *dev;
+       struct sja1000_priv *priv;
+       struct resource *res_mem, *res_irq;
+       struct sja1000_platform_data *pdata;
+
+       pdata = pdev->dev.platform_data;
+       if (!pdata) {
+               dev_err(&pdev->dev, "No platform data provided!\n");
+               err = -ENODEV;
+               goto exit;
+       }
+
+       res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+       if (!res_mem || !res_irq) {
+               err = -ENODEV;
+               goto exit;
+       }
+
+       if (!request_mem_region(res_mem->start, resource_size(res_mem),
+                               DRV_NAME)) {
+               err = -EBUSY;
+               goto exit;
+       }
+
+       addr = ioremap_nocache(res_mem->start, resource_size(res_mem));
+       if (!addr) {
+               err = -ENOMEM;
+               goto exit_release;
+       }
+
+       dev = alloc_sja1000dev(0);
+       if (!dev) {
+               err = -ENOMEM;
+               goto exit_iounmap;
+       }
+       priv = netdev_priv(dev);
+
+       dev->irq = res_irq->start;
+       priv->irq_flags = res_irq->flags & IRQF_TRIGGER_MASK;
+       priv->reg_base = addr;
+       priv->read_reg = sp_read_reg;
+       priv->write_reg = sp_write_reg;
+       priv->can.clock.freq = pdata->clock;
+       priv->ocr = pdata->ocr;
+       priv->cdr = pdata->cdr;
+
+       dev_set_drvdata(&pdev->dev, dev);
+       SET_NETDEV_DEV(dev, &pdev->dev);
+
+       err = register_sja1000dev(dev);
+       if (err) {
+               dev_err(&pdev->dev, "registering %s failed (err=%d)\n",
+                       DRV_NAME, err);
+               goto exit_free;
+       }
+
+       dev_info(&pdev->dev, "%s device registered (reg_base=%p, irq=%d)\n",
+                DRV_NAME, priv->reg_base, dev->irq);
+       return 0;
+
+ exit_free:
+       free_sja1000dev(dev);
+ exit_iounmap:
+       iounmap(addr);
+ exit_release:
+       release_mem_region(res_mem->start, resource_size(res_mem));
+ exit:
+       return err;
+}
+
+static int sp_remove(struct platform_device *pdev)
+{
+       struct net_device *dev = dev_get_drvdata(&pdev->dev);
+       struct sja1000_priv *priv = netdev_priv(dev);
+       struct resource *res;
+
+       unregister_sja1000dev(dev);
+       dev_set_drvdata(&pdev->dev, NULL);
+
+       if (priv->reg_base)
+               iounmap(priv->reg_base);
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       release_mem_region(res->start, resource_size(res));
+
+       free_sja1000dev(dev);
+
+       return 0;
+}
+
+static struct platform_driver sp_driver = {
+       .probe = sp_probe,
+       .remove = sp_remove,
+       .driver = {
+               .name = DRV_NAME,
+               .owner = THIS_MODULE,
+       },
+};
+
+static int __init sp_init(void)
+{
+       return platform_driver_register(&sp_driver);
+}
+
+static void __exit sp_exit(void)
+{
+       platform_driver_unregister(&sp_driver);
+}
+
+module_init(sp_init);
+module_exit(sp_exit);
index f5222764061c4677b8e9ac2f2661d3f5b7eb0107..eb066673c2a0513e225f2633ffce24e5b0e9a808 100644 (file)
@@ -2934,7 +2934,7 @@ static int cas_start_xmit(struct sk_buff *skb, struct net_device *dev)
         *      individual queues.
         */
        if (cas_xmit_tx_ringN(cp, ring++ & N_TX_RINGS_MASK, skb))
-               return 1;
+               return NETDEV_TX_BUSY;
        dev->trans_start = jiffies;
        return 0;
 }
index 4bd2455b0fe31b50bc20fba8f6a35e90ccc323fd..699d22c5fe094f03919aefd7e2672a412955ab19 100644 (file)
@@ -46,7 +46,7 @@
 #include <linux/pci.h>
 #include <linux/ethtool.h>
 #include <linux/if_vlan.h>
-#include <linux/mii.h>
+#include <linux/mdio.h>
 #include <linux/crc32.h>
 #include <linux/init.h>
 #include <asm/io.h>
index 79d855e267e0238a5d314d3c72098529f1df5a90..1f095a9fc73993432d15cb500db7bbb6b9c4695f 100644 (file)
 
 struct mdio_ops {
        void (*init)(adapter_t *adapter, const struct board_info *bi);
-       int  (*read)(adapter_t *adapter, int phy_addr, int mmd_addr,
-                    int reg_addr, unsigned int *val);
-       int  (*write)(adapter_t *adapter, int phy_addr, int mmd_addr,
-                     int reg_addr, unsigned int val);
+       int  (*read)(struct net_device *dev, int phy_addr, int mmd_addr,
+                    u16 reg_addr);
+       int  (*write)(struct net_device *dev, int phy_addr, int mmd_addr,
+                     u16 reg_addr, u16 val);
+       unsigned mode_support;
 };
 
 /* PHY interrupt types */
@@ -83,11 +84,12 @@ struct cphy_ops {
        int (*set_speed_duplex)(struct cphy *phy, int speed, int duplex);
        int (*get_link_status)(struct cphy *phy, int *link_ok, int *speed,
                               int *duplex, int *fc);
+
+       u32 mmds;
 };
 
 /* A PHY instance */
 struct cphy {
-       int addr;                            /* PHY address */
        int state;      /* Link status state machine */
        adapter_t *adapter;                  /* associated adapter */
 
@@ -101,56 +103,61 @@ struct cphy {
        u32 elmer_gpo;
 
        const struct cphy_ops *ops;            /* PHY operations */
-       int (*mdio_read)(adapter_t *adapter, int phy_addr, int mmd_addr,
-                        int reg_addr, unsigned int *val);
-       int (*mdio_write)(adapter_t *adapter, int phy_addr, int mmd_addr,
-                         int reg_addr, unsigned int val);
+       struct mdio_if_info mdio;
        struct cphy_instance *instance;
 };
 
 /* Convenience MDIO read/write wrappers */
-static inline int mdio_read(struct cphy *cphy, int mmd, int reg,
-                           unsigned int *valp)
+static inline int cphy_mdio_read(struct cphy *cphy, int mmd, int reg,
+                                unsigned int *valp)
 {
-       return cphy->mdio_read(cphy->adapter, cphy->addr, mmd, reg, valp);
+       int rc = cphy->mdio.mdio_read(cphy->mdio.dev, cphy->mdio.prtad, mmd,
+                                     reg);
+       *valp = (rc >= 0) ? rc : -1;
+       return (rc >= 0) ? 0 : rc;
 }
 
-static inline int mdio_write(struct cphy *cphy, int mmd, int reg,
-                            unsigned int val)
+static inline int cphy_mdio_write(struct cphy *cphy, int mmd, int reg,
+                                 unsigned int val)
 {
-       return cphy->mdio_write(cphy->adapter, cphy->addr, mmd, reg, val);
+       return cphy->mdio.mdio_write(cphy->mdio.dev, cphy->mdio.prtad, mmd,
+                                    reg, val);
 }
 
 static inline int simple_mdio_read(struct cphy *cphy, int reg,
                                   unsigned int *valp)
 {
-       return mdio_read(cphy, 0, reg, valp);
+       return cphy_mdio_read(cphy, MDIO_DEVAD_NONE, reg, valp);
 }
 
 static inline int simple_mdio_write(struct cphy *cphy, int reg,
                                    unsigned int val)
 {
-       return mdio_write(cphy, 0, reg, val);
+       return cphy_mdio_write(cphy, MDIO_DEVAD_NONE, reg, val);
 }
 
 /* Convenience initializer */
-static inline void cphy_init(struct cphy *phy, adapter_t *adapter,
+static inline void cphy_init(struct cphy *phy, struct net_device *dev,
                             int phy_addr, struct cphy_ops *phy_ops,
                             const struct mdio_ops *mdio_ops)
 {
+       struct adapter *adapter = netdev_priv(dev);
        phy->adapter = adapter;
-       phy->addr    = phy_addr;
        phy->ops     = phy_ops;
        if (mdio_ops) {
-               phy->mdio_read  = mdio_ops->read;
-               phy->mdio_write = mdio_ops->write;
+               phy->mdio.prtad = phy_addr;
+               phy->mdio.mmds = phy_ops->mmds;
+               phy->mdio.mode_support = mdio_ops->mode_support;
+               phy->mdio.mdio_read = mdio_ops->read;
+               phy->mdio.mdio_write = mdio_ops->write;
        }
+       phy->mdio.dev = dev;
 }
 
 /* Operations of the PHY-instance factory */
 struct gphy {
        /* Construct a PHY instance with the given PHY address */
-       struct cphy *(*create)(adapter_t *adapter, int phy_addr,
+       struct cphy *(*create)(struct net_device *dev, int phy_addr,
                               const struct mdio_ops *mdio_ops);
 
        /*
index fa06994f973770e4f46c27d902e8fc0c7a28ed10..082cdb28b5101fd4bfc1cf0d1f174170da3dfbbd 100644 (file)
@@ -589,7 +589,7 @@ static int get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
        }
 
        cmd->port = (cmd->supported & SUPPORTED_TP) ? PORT_TP : PORT_FIBRE;
-       cmd->phy_address = p->phy->addr;
+       cmd->phy_address = p->phy->mdio.prtad;
        cmd->transceiver = XCVR_EXTERNAL;
        cmd->autoneg = p->link_config.autoneg;
        cmd->maxtxpkt = 0;
@@ -849,39 +849,9 @@ static const struct ethtool_ops t1_ethtool_ops = {
 static int t1_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
 {
        struct adapter *adapter = dev->ml_priv;
-       struct mii_ioctl_data *data = if_mii(req);
-
-       switch (cmd) {
-       case SIOCGMIIPHY:
-               data->phy_id = adapter->port[dev->if_port].phy->addr;
-               /* FALLTHRU */
-       case SIOCGMIIREG: {
-               struct cphy *phy = adapter->port[dev->if_port].phy;
-               u32 val;
-
-               if (!phy->mdio_read)
-                       return -EOPNOTSUPP;
-               phy->mdio_read(adapter, data->phy_id, 0, data->reg_num & 0x1f,
-                              &val);
-               data->val_out = val;
-               break;
-       }
-       case SIOCSMIIREG: {
-               struct cphy *phy = adapter->port[dev->if_port].phy;
-
-               if (!capable(CAP_NET_ADMIN))
-                   return -EPERM;
-               if (!phy->mdio_write)
-                       return -EOPNOTSUPP;
-               phy->mdio_write(adapter, data->phy_id, 0, data->reg_num & 0x1f,
-                               data->val_in);
-               break;
-       }
+       struct mdio_if_info *mdio = &adapter->port[dev->if_port].phy->mdio;
 
-       default:
-               return -EOPNOTSUPP;
-       }
-       return 0;
+       return mdio_mii_ioctl(mdio, if_mii(req), cmd);
 }
 
 static int t1_change_mtu(struct net_device *dev, int new_mtu)
index 0632be0d6494310b1b11cd87cc202cb721491216..809047a99e96a983579bc7c6cf7c28ea6326fec8 100644 (file)
@@ -353,15 +353,16 @@ static struct cphy_ops mv88e1xxx_ops = {
        .get_link_status      = mv88e1xxx_get_link_status,
 };
 
-static struct cphy *mv88e1xxx_phy_create(adapter_t *adapter, int phy_addr,
+static struct cphy *mv88e1xxx_phy_create(struct net_device *dev, int phy_addr,
                                         const struct mdio_ops *mdio_ops)
 {
+       struct adapter *adapter = netdev_priv(dev);
        struct cphy *cphy = kzalloc(sizeof(*cphy), GFP_KERNEL);
 
        if (!cphy)
                return NULL;
 
-       cphy_init(cphy, adapter, phy_addr, &mv88e1xxx_ops, mdio_ops);
+       cphy_init(cphy, dev, phy_addr, &mv88e1xxx_ops, mdio_ops);
 
        /* Configure particular PHY's to run in a different mode. */
        if ((board_info(adapter)->caps & SUPPORTED_TP) &&
index cd856041af34dfe861c54be45e84ce630102d6c8..f7136b2fd1e5c946f8ee320a087cfbc872982039 100644 (file)
@@ -53,7 +53,7 @@ static int led_init(struct cphy *cphy)
         * Writing these bits maps control to another
         * register. mmd(0x1) addr(0x7)
         */
-       mdio_write(cphy, 0x3, 0x8304, 0xdddd);
+       cphy_mdio_write(cphy, MDIO_MMD_PCS, 0x8304, 0xdddd);
        return 0;
 }
 
@@ -62,14 +62,14 @@ static int led_link(struct cphy *cphy, u32 do_enable)
        u32 led = 0;
 #define LINK_ENABLE_BIT 0x1
 
-       mdio_read(cphy, 0x1, 0x7, &led);
+       cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, MDIO_CTRL2, &led);
 
        if (do_enable & LINK_ENABLE_BIT) {
                led |= LINK_ENABLE_BIT;
-               mdio_write(cphy, 0x1, 0x7, led);
+               cphy_mdio_write(cphy, MDIO_MMD_PMAPMD, MDIO_CTRL2, led);
        } else {
                led &= ~LINK_ENABLE_BIT;
-               mdio_write(cphy, 0x1, 0x7, led);
+               cphy_mdio_write(cphy, MDIO_MMD_PMAPMD, MDIO_CTRL2, led);
        }
        return 0;
 }
@@ -86,7 +86,8 @@ static int mv88x201x_reset(struct cphy *cphy, int wait)
 static int mv88x201x_interrupt_enable(struct cphy *cphy)
 {
        /* Enable PHY LASI interrupts. */
-       mdio_write(cphy, 0x1, 0x9002, 0x1);
+       cphy_mdio_write(cphy, MDIO_MMD_PMAPMD, MDIO_PMA_LASI_CTRL,
+                       MDIO_PMA_LASI_LSALARM);
 
        /* Enable Marvell interrupts through Elmer0. */
        if (t1_is_asic(cphy->adapter)) {
@@ -102,7 +103,7 @@ static int mv88x201x_interrupt_enable(struct cphy *cphy)
 static int mv88x201x_interrupt_disable(struct cphy *cphy)
 {
        /* Disable PHY LASI interrupts. */
-       mdio_write(cphy, 0x1, 0x9002, 0x0);
+       cphy_mdio_write(cphy, MDIO_MMD_PMAPMD, MDIO_PMA_LASI_CTRL, 0x0);
 
        /* Disable Marvell interrupts through Elmer0. */
        if (t1_is_asic(cphy->adapter)) {
@@ -122,25 +123,25 @@ static int mv88x201x_interrupt_clear(struct cphy *cphy)
 
 #ifdef MV88x2010_LINK_STATUS_BUGS
        /* Required to read twice before clear takes affect. */
-       mdio_read(cphy, 0x1, 0x9003, &val);
-       mdio_read(cphy, 0x1, 0x9004, &val);
-       mdio_read(cphy, 0x1, 0x9005, &val);
+       cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, MDIO_PMA_LASI_RXSTAT, &val);
+       cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, MDIO_PMA_LASI_TXSTAT, &val);
+       cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, MDIO_PMA_LASI_STAT, &val);
 
        /* Read this register after the others above it else
         * the register doesn't clear correctly.
         */
-       mdio_read(cphy, 0x1, 0x1, &val);
+       cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, MDIO_STAT1, &val);
 #endif
 
        /* Clear link status. */
-       mdio_read(cphy, 0x1, 0x1, &val);
+       cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, MDIO_STAT1, &val);
        /* Clear PHY LASI interrupts. */
-       mdio_read(cphy, 0x1, 0x9005, &val);
+       cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, MDIO_PMA_LASI_STAT, &val);
 
 #ifdef MV88x2010_LINK_STATUS_BUGS
        /* Do it again. */
-       mdio_read(cphy, 0x1, 0x9003, &val);
-       mdio_read(cphy, 0x1, 0x9004, &val);
+       cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, MDIO_PMA_LASI_RXSTAT, &val);
+       cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, MDIO_PMA_LASI_TXSTAT, &val);
 #endif
 
        /* Clear Marvell interrupts through Elmer0. */
@@ -172,13 +173,12 @@ static int mv88x201x_get_link_status(struct cphy *cphy, int *link_ok,
                                     int *speed, int *duplex, int *fc)
 {
        u32 val = 0;
-#define LINK_STATUS_BIT 0x4
 
        if (link_ok) {
                /* Read link status. */
-               mdio_read(cphy, 0x1, 0x1, &val);
-               val &= LINK_STATUS_BIT;
-               *link_ok = (val == LINK_STATUS_BIT);
+               cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, MDIO_STAT1, &val);
+               val &= MDIO_STAT1_LSTATUS;
+               *link_ok = (val == MDIO_STAT1_LSTATUS);
                /* Turn on/off Link LED */
                led_link(cphy, *link_ok);
        }
@@ -205,9 +205,11 @@ static struct cphy_ops mv88x201x_ops = {
        .interrupt_handler = mv88x201x_interrupt_handler,
        .get_link_status   = mv88x201x_get_link_status,
        .set_loopback      = mv88x201x_set_loopback,
+       .mmds              = (MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS |
+                             MDIO_DEVS_PHYXS | MDIO_DEVS_WIS),
 };
 
-static struct cphy *mv88x201x_phy_create(adapter_t *adapter, int phy_addr,
+static struct cphy *mv88x201x_phy_create(struct net_device *dev, int phy_addr,
                                         const struct mdio_ops *mdio_ops)
 {
        u32 val;
@@ -216,15 +218,15 @@ static struct cphy *mv88x201x_phy_create(adapter_t *adapter, int phy_addr,
        if (!cphy)
                return NULL;
 
-       cphy_init(cphy, adapter, phy_addr, &mv88x201x_ops, mdio_ops);
+       cphy_init(cphy, dev, phy_addr, &mv88x201x_ops, mdio_ops);
 
        /* Commands the PHY to enable XFP's clock. */
-       mdio_read(cphy, 0x3, 0x8300, &val);
-       mdio_write(cphy, 0x3, 0x8300, val | 1);
+       cphy_mdio_read(cphy, MDIO_MMD_PCS, 0x8300, &val);
+       cphy_mdio_write(cphy, MDIO_MMD_PCS, 0x8300, val | 1);
 
        /* Clear link status. Required because of a bug in the PHY.  */
-       mdio_read(cphy, 0x1, 0x8, &val);
-       mdio_read(cphy, 0x3, 0x8, &val);
+       cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, MDIO_STAT2, &val);
+       cphy_mdio_read(cphy, MDIO_MMD_PCS, MDIO_STAT2, &val);
 
        /* Allows for Link,Ack LED turn on/off */
        led_init(cphy);
index 040acd29995a2c5681f2816c620b43e64e0d17f0..4c6028512d102ef937662b60382929dacb84df4d 100644 (file)
@@ -43,11 +43,11 @@ static int my3126_interrupt_handler(struct cphy *cphy)
        adapter = cphy->adapter;
 
        if (cphy->count == 50) {
-               mdio_read(cphy, 0x1, 0x1, &val);
+               cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, MDIO_STAT1, &val);
                val16 = (u16) val;
                status = cphy->bmsr ^ val16;
 
-               if (status & BMSR_LSTATUS)
+               if (status & MDIO_STAT1_LSTATUS)
                        t1_link_changed(adapter, 0);
                cphy->bmsr = val16;
 
@@ -114,14 +114,14 @@ static int my3126_get_link_status(struct cphy *cphy,
        adapter_t *adapter;
 
        adapter = cphy->adapter;
-       mdio_read(cphy, 0x1, 0x1, &val);
+       cphy_mdio_read(cphy, MDIO_MMD_PMAPMD, MDIO_STAT1, &val);
        val16 = (u16) val;
 
        /* Populate elmer_gpo with the register value */
        t1_tpi_read(adapter, A_ELMER0_GPO, &val);
        cphy->elmer_gpo = val;
 
-       *link_ok = (val16 & BMSR_LSTATUS);
+       *link_ok = (val16 & MDIO_STAT1_LSTATUS);
 
        if (*link_ok) {
                /* Turn on the LED. */
@@ -163,9 +163,11 @@ static struct cphy_ops my3126_ops = {
        .interrupt_handler      = my3126_interrupt_handler,
        .get_link_status        = my3126_get_link_status,
        .set_loopback           = my3126_set_loopback,
+       .mmds                   = (MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS |
+                                  MDIO_DEVS_PHYXS),
 };
 
-static struct cphy *my3126_phy_create(adapter_t *adapter,
+static struct cphy *my3126_phy_create(struct net_device *dev,
                        int phy_addr, const struct mdio_ops *mdio_ops)
 {
        struct cphy *cphy = kzalloc(sizeof (*cphy), GFP_KERNEL);
@@ -173,7 +175,7 @@ static struct cphy *my3126_phy_create(adapter_t *adapter,
        if (!cphy)
                return NULL;
 
-       cphy_init(cphy, adapter, phy_addr, &my3126_ops, mdio_ops);
+       cphy_init(cphy, dev, phy_addr, &my3126_ops, mdio_ops);
        INIT_DELAYED_WORK(&cphy->phy_update, my3216_poll);
        cphy->bmsr = 0;
 
index 58f6fc055f6a55cd1e9e3bc52af92b96cd31c9a4..3711d64e45effadfe4569c3cb37c7e40e476c414 100644 (file)
@@ -1149,8 +1149,8 @@ static inline void write_tx_desc(struct cmdQ_e *e, dma_addr_t mapping,
                                 unsigned int len, unsigned int gen,
                                 unsigned int eop)
 {
-       if (unlikely(len > SGE_TX_DESC_MAX_PLEN))
-               BUG();
+       BUG_ON(len > SGE_TX_DESC_MAX_PLEN);
+
        e->addr_lo = (u32)mapping;
        e->addr_hi = (u64)mapping >> 32;
        e->len_gen = V_CMD_LEN(len) | V_CMD_GEN1(gen);
@@ -1879,7 +1879,6 @@ int t1_start_xmit(struct sk_buff *skb, struct net_device *dev)
                cpl->vlan_valid = 0;
 
 send:
-       dev->trans_start = jiffies;
        ret = t1_sge_tx(skb, adapter, 0, dev);
 
        /* If transmit busy, and we reallocated skb's due to headroom limit,
index 7adf30230c4f7123d03d91e2f9c500f26d4a49f8..17720c6e5bfe028b8a5dbfd927f52a0af6c8929b 100644 (file)
@@ -284,32 +284,29 @@ static void mi1_mdio_init(adapter_t *adapter, const struct board_info *bi)
 /*
  * Elmer MI1 MDIO read/write operations.
  */
-static int mi1_mdio_read(adapter_t *adapter, int phy_addr, int mmd_addr,
-                        int reg_addr, unsigned int *valp)
+static int mi1_mdio_read(struct net_device *dev, int phy_addr, int mmd_addr,
+                        u16 reg_addr)
 {
+       struct adapter *adapter = dev->ml_priv;
        u32 addr = V_MI1_REG_ADDR(reg_addr) | V_MI1_PHY_ADDR(phy_addr);
-
-       if (mmd_addr)
-               return -EINVAL;
+       unsigned int val;
 
        spin_lock(&adapter->tpi_lock);
        __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_ADDR, addr);
        __t1_tpi_write(adapter,
                        A_ELMER0_PORT0_MI1_OP, MI1_OP_DIRECT_READ);
        mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP);
-       __t1_tpi_read(adapter, A_ELMER0_PORT0_MI1_DATA, valp);
+       __t1_tpi_read(adapter, A_ELMER0_PORT0_MI1_DATA, &val);
        spin_unlock(&adapter->tpi_lock);
-       return 0;
+       return val;
 }
 
-static int mi1_mdio_write(adapter_t *adapter, int phy_addr, int mmd_addr,
-                         int reg_addr, unsigned int val)
+static int mi1_mdio_write(struct net_device *dev, int phy_addr, int mmd_addr,
+                         u16 reg_addr, u16 val)
 {
+       struct adapter *adapter = dev->ml_priv;
        u32 addr = V_MI1_REG_ADDR(reg_addr) | V_MI1_PHY_ADDR(phy_addr);
 
-       if (mmd_addr)
-               return -EINVAL;
-
        spin_lock(&adapter->tpi_lock);
        __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_ADDR, addr);
        __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_DATA, val);
@@ -324,16 +321,19 @@ static int mi1_mdio_write(adapter_t *adapter, int phy_addr, int mmd_addr,
 static const struct mdio_ops mi1_mdio_ops = {
        .init = mi1_mdio_init,
        .read = mi1_mdio_read,
-       .write = mi1_mdio_write
+       .write = mi1_mdio_write,
+       .mode_support = MDIO_SUPPORTS_C22
 };
 #endif
 
 #endif
 
-static int mi1_mdio_ext_read(adapter_t *adapter, int phy_addr, int mmd_addr,
-                            int reg_addr, unsigned int *valp)
+static int mi1_mdio_ext_read(struct net_device *dev, int phy_addr, int mmd_addr,
+                            u16 reg_addr)
 {
+       struct adapter *adapter = dev->ml_priv;
        u32 addr = V_MI1_REG_ADDR(mmd_addr) | V_MI1_PHY_ADDR(phy_addr);
+       unsigned int val;
 
        spin_lock(&adapter->tpi_lock);
 
@@ -350,14 +350,15 @@ static int mi1_mdio_ext_read(adapter_t *adapter, int phy_addr, int mmd_addr,
        mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP);
 
        /* Read the data. */
-       __t1_tpi_read(adapter, A_ELMER0_PORT0_MI1_DATA, valp);
+       __t1_tpi_read(adapter, A_ELMER0_PORT0_MI1_DATA, &val);
        spin_unlock(&adapter->tpi_lock);
-       return 0;
+       return val;
 }
 
-static int mi1_mdio_ext_write(adapter_t *adapter, int phy_addr, int mmd_addr,
-                             int reg_addr, unsigned int val)
+static int mi1_mdio_ext_write(struct net_device *dev, int phy_addr,
+                             int mmd_addr, u16 reg_addr, u16 val)
 {
+       struct adapter *adapter = dev->ml_priv;
        u32 addr = V_MI1_REG_ADDR(mmd_addr) | V_MI1_PHY_ADDR(phy_addr);
 
        spin_lock(&adapter->tpi_lock);
@@ -380,7 +381,8 @@ static int mi1_mdio_ext_write(adapter_t *adapter, int phy_addr, int mmd_addr,
 static const struct mdio_ops mi1_mdio_ext_ops = {
        .init = mi1_mdio_init,
        .read = mi1_mdio_ext_read,
-       .write = mi1_mdio_ext_write
+       .write = mi1_mdio_ext_write,
+       .mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22
 };
 
 enum {
@@ -1133,8 +1135,8 @@ int __devinit t1_init_sw_modules(adapter_t *adapter,
                struct cmac *mac;
                int phy_addr = bi->mdio_phybaseaddr + i;
 
-               adapter->port[i].phy = bi->gphy->create(adapter, phy_addr,
-                                                       bi->mdio_ops);
+               adapter->port[i].phy = bi->gphy->create(adapter->port[i].dev,
+                                                       phy_addr, bi->mdio_ops);
                if (!adapter->port[i].phy) {
                        CH_ERR("%s: PHY %d initialization failed\n",
                               adapter->name, i);
index 3f476c7c07365ab0d2bfcda55d0a86435d9096d8..58afafbd3b9cb9695bcf6fe570c07b493a30d881 100644 (file)
@@ -202,7 +202,7 @@ struct cpmac_priv {
        void __iomem *regs;
        struct mii_bus *mii_bus;
        struct phy_device *phy;
-       char phy_name[BUS_ID_SIZE];
+       char phy_name[MII_BUS_ID_SIZE + 3];
        int oldlink, oldspeed, oldduplex;
        u32 msg_enable;
        struct net_device *dev;
@@ -615,13 +615,13 @@ static void cpmac_end_xmit(struct net_device *dev, int queue)
 
                dev_kfree_skb_irq(desc->skb);
                desc->skb = NULL;
-               if (netif_subqueue_stopped(dev, queue))
+               if (__netif_subqueue_stopped(dev, queue))
                        netif_wake_subqueue(dev, queue);
        } else {
                if (netif_msg_tx_err(priv) && net_ratelimit())
                        printk(KERN_WARNING
                               "%s: end_xmit: spurious interrupt\n", dev->name);
-               if (netif_subqueue_stopped(dev, queue))
+               if (__netif_subqueue_stopped(dev, queue))
                        netif_wake_subqueue(dev, queue);
        }
 }
@@ -731,7 +731,6 @@ static void cpmac_clear_tx(struct net_device *dev)
 
 static void cpmac_hw_error(struct work_struct *work)
 {
-       int i;
        struct cpmac_priv *priv =
                container_of(work, struct cpmac_priv, reset_work);
 
@@ -818,7 +817,6 @@ static irqreturn_t cpmac_irq(int irq, void *dev_id)
 
 static void cpmac_tx_timeout(struct net_device *dev)
 {
-       int i;
        struct cpmac_priv *priv = netdev_priv(dev);
 
        spin_lock(&priv->lock);
@@ -1093,11 +1091,24 @@ static int cpmac_stop(struct net_device *dev)
        return 0;
 }
 
+static const struct net_device_ops cpmac_netdev_ops = {
+       .ndo_open               = cpmac_open,
+       .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_so_ioctl           = cpmac_ioctl,
+       .ndo_set_config         = cpmac_config,
+       .ndo_change_mtu         = eth_change_mtu,
+       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_set_mac_address    = eth_mac_addr,
+};
+
 static int external_switch;
 
 static int __devinit cpmac_probe(struct platform_device *pdev)
 {
-       int rc, phy_id, i;
+       int rc, phy_id;
        char *mdio_bus_id = "0";
        struct resource *mem;
        struct cpmac_priv *priv;
@@ -1143,14 +1154,8 @@ static int __devinit cpmac_probe(struct platform_device *pdev)
 
        dev->irq = platform_get_irq_byname(pdev, "irq");
 
-       dev->open               = cpmac_open;
-       dev->stop               = cpmac_stop;
-       dev->set_config         = cpmac_config;
-       dev->hard_start_xmit    = cpmac_start_xmit;
-       dev->do_ioctl           = cpmac_ioctl;
-       dev->set_multicast_list = cpmac_set_multicast_list;
-       dev->tx_timeout         = cpmac_tx_timeout;
-       dev->ethtool_ops        = &cpmac_ethtool_ops;
+       dev->netdev_ops = &cpmac_netdev_ops;
+       dev->ethtool_ops = &cpmac_ethtool_ops;
 
        netif_napi_add(dev, &priv->napi, cpmac_poll, 64);
 
index 7433b88eed7e958f0666d02bafac62657add0bc0..3eee666a9cd26773fa4712704cf7066ec7f0cbc5 100644 (file)
@@ -1551,7 +1551,7 @@ static int net_send_packet(struct sk_buff *skb, struct net_device *dev)
 
                spin_unlock_irq(&lp->lock);
                if (net_debug) printk("cs89x0: Tx buffer not free!\n");
-               return 1;
+               return NETDEV_TX_BUSY;
        }
        /* Write the contents of the packet */
        writewords(dev->base_addr, TX_FRAME_PORT,skb->data,(skb->len+1) >>1);
index 3434679853213206b3c3ec12b5ea86466894a0b7..29aff78c7820dc7389efd2622cee6d6006b89097 100644 (file)
@@ -5,4 +5,4 @@
 obj-$(CONFIG_CHELSIO_T3) += cxgb3.o
 
 cxgb3-objs := cxgb3_main.o ael1002.o vsc8211.o t3_hw.o mc5.o \
-             xgmac.o sge.o l2t.o cxgb3_offload.o
+             xgmac.o sge.o l2t.o cxgb3_offload.o aq100x.o
index c888e97c9671b0cef29f3e698f454b94830b5473..1694fad387206daf30cadbec9f9b3b6a3c2d2cc8 100644 (file)
@@ -195,7 +195,7 @@ struct sge_qset {           /* an SGE queue set */
        struct sge_rspq rspq;
        struct sge_fl fl[SGE_RXQ_PER_SET];
        struct sge_txq txq[SGE_TXQ_PER_SET];
-       struct napi_gro_fraginfo lro_frag_tbl;
+       int nomem;
        int lro_enabled;
        void *lro_va;
        struct net_device *netdev;
@@ -253,6 +253,8 @@ struct adapter {
        struct mutex mdio_lock;
        spinlock_t stats_lock;
        spinlock_t work_lock;
+
+       struct sk_buff *nofail_skb;
 };
 
 static inline u32 t3_read_reg(struct adapter *adapter, u32 reg_addr)
index e1b22490ff597e439bbb1deb90b3638d59dfdb6f..9fe008ec9ba5922f2170842fe84506e522ed0894 100644 (file)
 #include "regs.h"
 
 enum {
-       PMD_RSD     = 10,   /* PMA/PMD receive signal detect register */
-       PCS_STAT1_X = 24,   /* 10GBASE-X PCS status 1 register */
-       PCS_STAT1_R = 32,   /* 10GBASE-R PCS status 1 register */
-       XS_LN_STAT  = 24    /* XS lane status register */
-};
-
-enum {
-       AEL100X_TX_DISABLE = 9,
        AEL100X_TX_CONFIG1 = 0xc002,
        AEL1002_PWR_DOWN_HI = 0xc011,
        AEL1002_PWR_DOWN_LO = 0xc012,
@@ -52,12 +44,33 @@ enum {
        AEL_I2C_STAT = 0xc30c,
        AEL2005_GPIO_CTRL = 0xc214,
        AEL2005_GPIO_STAT = 0xc215,
+
+       AEL2020_GPIO_INTR   = 0xc103,   /* Latch High (LH) */
+       AEL2020_GPIO_CTRL   = 0xc108,   /* Store Clear (SC) */
+       AEL2020_GPIO_STAT   = 0xc10c,   /* Read Only (RO) */
+       AEL2020_GPIO_CFG    = 0xc110,   /* Read Write (RW) */
+
+       AEL2020_GPIO_SDA    = 0,        /* IN: i2c serial data */
+       AEL2020_GPIO_MODDET = 1,        /* IN: Module Detect */
+       AEL2020_GPIO_0      = 3,        /* IN: unassigned */
+       AEL2020_GPIO_1      = 2,        /* OUT: unassigned */
+       AEL2020_GPIO_LSTAT  = AEL2020_GPIO_1, /* wired to link status LED */
 };
 
 enum { edc_none, edc_sr, edc_twinax };
 
 /* PHY module I2C device address */
-#define MODULE_DEV_ADDR 0xa0
+enum {
+       MODULE_DEV_ADDR = 0xa0,
+       SFF_DEV_ADDR    = 0xa2,
+};
+
+/* PHY transceiver type */
+enum {
+       phy_transtype_unknown = 0,
+       phy_transtype_sfp     = 3,
+       phy_transtype_xfp     = 6,
+};
 
 #define AEL2005_MODDET_IRQ 4
 
@@ -74,8 +87,8 @@ static int set_phy_regs(struct cphy *phy, const struct reg_val *rv)
 
        for (err = 0; rv->mmd_addr && !err; rv++) {
                if (rv->clear_bits == 0xffff)
-                       err = mdio_write(phy, rv->mmd_addr, rv->reg_addr,
-                                        rv->set_bits);
+                       err = t3_mdio_write(phy, rv->mmd_addr, rv->reg_addr,
+                                           rv->set_bits);
                else
                        err = t3_mdio_change_bits(phy, rv->mmd_addr,
                                                  rv->reg_addr, rv->clear_bits,
@@ -86,21 +99,54 @@ static int set_phy_regs(struct cphy *phy, const struct reg_val *rv)
 
 static void ael100x_txon(struct cphy *phy)
 {
-       int tx_on_gpio = phy->addr == 0 ? F_GPIO7_OUT_VAL : F_GPIO2_OUT_VAL;
+       int tx_on_gpio =
+               phy->mdio.prtad == 0 ? F_GPIO7_OUT_VAL : F_GPIO2_OUT_VAL;
 
        msleep(100);
        t3_set_reg_field(phy->adapter, A_T3DBG_GPIO_EN, 0, tx_on_gpio);
        msleep(30);
 }
 
+/*
+ * Read an 8-bit word from a device attached to the PHY's i2c bus.
+ */
+static int ael_i2c_rd(struct cphy *phy, int dev_addr, int word_addr)
+{
+       int i, err;
+       unsigned int stat, data;
+
+       err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL_I2C_CTRL,
+                           (dev_addr << 8) | (1 << 8) | word_addr);
+       if (err)
+               return err;
+
+       for (i = 0; i < 200; i++) {
+               msleep(1);
+               err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, AEL_I2C_STAT, &stat);
+               if (err)
+                       return err;
+               if ((stat & 3) == 1) {
+                       err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, AEL_I2C_DATA,
+                                          &data);
+                       if (err)
+                               return err;
+                       return data >> 8;
+               }
+       }
+       CH_WARN(phy->adapter, "PHY %u i2c read of dev.addr %#x.%#x timed out\n",
+               phy->mdio.prtad, dev_addr, word_addr);
+       return -ETIMEDOUT;
+}
+
 static int ael1002_power_down(struct cphy *phy, int enable)
 {
        int err;
 
-       err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL100X_TX_DISABLE, !!enable);
+       err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, MDIO_PMA_TXDIS, !!enable);
        if (!err)
-               err = t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, MII_BMCR,
-                                         BMCR_PDOWN, enable ? BMCR_PDOWN : 0);
+               err = mdio_set_flag(&phy->mdio, phy->mdio.prtad,
+                                   MDIO_MMD_PMAPMD, MDIO_CTRL1,
+                                   MDIO_CTRL1_LPOWER, enable);
        return err;
 }
 
@@ -109,11 +155,11 @@ static int ael1002_reset(struct cphy *phy, int wait)
        int err;
 
        if ((err = ael1002_power_down(phy, 0)) ||
-           (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL100X_TX_CONFIG1, 1)) ||
-           (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL1002_PWR_DOWN_HI, 0)) ||
-           (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL1002_PWR_DOWN_LO, 0)) ||
-           (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL1002_XFI_EQL, 0x18)) ||
-           (err = t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, AEL1002_LB_EN,
+           (err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL100X_TX_CONFIG1, 1)) ||
+           (err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL1002_PWR_DOWN_HI, 0)) ||
+           (err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL1002_PWR_DOWN_LO, 0)) ||
+           (err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL1002_XFI_EQL, 0x18)) ||
+           (err = t3_mdio_change_bits(phy, MDIO_MMD_PMAPMD, AEL1002_LB_EN,
                                       0, 1 << 5)))
                return err;
        return 0;
@@ -132,12 +178,15 @@ static int get_link_status_r(struct cphy *phy, int *link_ok, int *speed,
 {
        if (link_ok) {
                unsigned int stat0, stat1, stat2;
-               int err = mdio_read(phy, MDIO_DEV_PMA_PMD, PMD_RSD, &stat0);
+               int err = t3_mdio_read(phy, MDIO_MMD_PMAPMD,
+                                      MDIO_PMA_RXDET, &stat0);
 
                if (!err)
-                       err = mdio_read(phy, MDIO_DEV_PCS, PCS_STAT1_R, &stat1);
+                       err = t3_mdio_read(phy, MDIO_MMD_PCS,
+                                          MDIO_PCS_10GBRT_STAT1, &stat1);
                if (!err)
-                       err = mdio_read(phy, MDIO_DEV_XGXS, XS_LN_STAT, &stat2);
+                       err = t3_mdio_read(phy, MDIO_MMD_PHYXS,
+                                          MDIO_PHYXS_LNSTAT, &stat2);
                if (err)
                        return err;
                *link_ok = (stat0 & stat1 & (stat2 >> 12)) & 1;
@@ -157,6 +206,7 @@ static struct cphy_ops ael1002_ops = {
        .intr_handler = ael1002_intr_noop,
        .get_link_status = get_link_status_r,
        .power_down = ael1002_power_down,
+       .mmds = MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS | MDIO_DEVS_PHYXS,
 };
 
 int t3_ael1002_phy_prep(struct cphy *phy, struct adapter *adapter,
@@ -171,13 +221,13 @@ int t3_ael1002_phy_prep(struct cphy *phy, struct adapter *adapter,
 
 static int ael1006_reset(struct cphy *phy, int wait)
 {
-       return t3_phy_reset(phy, MDIO_DEV_PMA_PMD, wait);
+       return t3_phy_reset(phy, MDIO_MMD_PMAPMD, wait);
 }
 
 static int ael1006_power_down(struct cphy *phy, int enable)
 {
-       return t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, MII_BMCR,
-                                  BMCR_PDOWN, enable ? BMCR_PDOWN : 0);
+       return mdio_set_flag(&phy->mdio, phy->mdio.prtad, MDIO_MMD_PMAPMD,
+                            MDIO_CTRL1, MDIO_CTRL1_LPOWER, enable);
 }
 
 static struct cphy_ops ael1006_ops = {
@@ -188,6 +238,7 @@ static struct cphy_ops ael1006_ops = {
        .intr_handler = t3_phy_lasi_intr_handler,
        .get_link_status = get_link_status_r,
        .power_down = ael1006_power_down,
+       .mmds = MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS | MDIO_DEVS_PHYXS,
 };
 
 int t3_ael1006_phy_prep(struct cphy *phy, struct adapter *adapter,
@@ -200,12 +251,57 @@ int t3_ael1006_phy_prep(struct cphy *phy, struct adapter *adapter,
        return 0;
 }
 
+/*
+ * Decode our module type.
+ */
+static int ael2xxx_get_module_type(struct cphy *phy, int delay_ms)
+{
+       int v;
+
+       if (delay_ms)
+               msleep(delay_ms);
+
+       /* see SFF-8472 for below */
+       v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 3);
+       if (v < 0)
+               return v;
+
+       if (v == 0x10)
+               return phy_modtype_sr;
+       if (v == 0x20)
+               return phy_modtype_lr;
+       if (v == 0x40)
+               return phy_modtype_lrm;
+
+       v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 6);
+       if (v < 0)
+               return v;
+       if (v != 4)
+               goto unknown;
+
+       v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 10);
+       if (v < 0)
+               return v;
+
+       if (v & 0x80) {
+               v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 0x12);
+               if (v < 0)
+                       return v;
+               return v > 10 ? phy_modtype_twinax_long : phy_modtype_twinax;
+       }
+unknown:
+       return phy_modtype_unknown;
+}
+
+/*
+ * Code to support the Aeluros/NetLogic 2005 10Gb PHY.
+ */
 static int ael2005_setup_sr_edc(struct cphy *phy)
 {
        static struct reg_val regs[] = {
-               { MDIO_DEV_PMA_PMD, 0xc003, 0xffff, 0x181 },
-               { MDIO_DEV_PMA_PMD, 0xc010, 0xffff, 0x448a },
-               { MDIO_DEV_PMA_PMD, 0xc04a, 0xffff, 0x5200 },
+               { MDIO_MMD_PMAPMD, 0xc003, 0xffff, 0x181 },
+               { MDIO_MMD_PMAPMD, 0xc010, 0xffff, 0x448a },
+               { MDIO_MMD_PMAPMD, 0xc04a, 0xffff, 0x5200 },
                { 0, 0, 0, 0 }
        };
        static u16 sr_edc[] = {
@@ -490,8 +586,8 @@ static int ael2005_setup_sr_edc(struct cphy *phy)
        msleep(50);
 
        for (i = 0; i < ARRAY_SIZE(sr_edc) && !err; i += 2)
-               err = mdio_write(phy, MDIO_DEV_PMA_PMD, sr_edc[i],
-                                sr_edc[i + 1]);
+               err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, sr_edc[i],
+                                   sr_edc[i + 1]);
        if (!err)
                phy->priv = edc_sr;
        return err;
@@ -500,12 +596,12 @@ static int ael2005_setup_sr_edc(struct cphy *phy)
 static int ael2005_setup_twinax_edc(struct cphy *phy, int modtype)
 {
        static struct reg_val regs[] = {
-               { MDIO_DEV_PMA_PMD, 0xc04a, 0xffff, 0x5a00 },
+               { MDIO_MMD_PMAPMD, 0xc04a, 0xffff, 0x5a00 },
                { 0, 0, 0, 0 }
        };
        static struct reg_val preemphasis[] = {
-               { MDIO_DEV_PMA_PMD, 0xc014, 0xffff, 0xfe16 },
-               { MDIO_DEV_PMA_PMD, 0xc015, 0xffff, 0xa000 },
+               { MDIO_MMD_PMAPMD, 0xc014, 0xffff, 0xfe16 },
+               { MDIO_MMD_PMAPMD, 0xc015, 0xffff, 0xa000 },
                { 0, 0, 0, 0 }
        };
        static u16 twinax_edc[] = {
@@ -887,132 +983,73 @@ static int ael2005_setup_twinax_edc(struct cphy *phy, int modtype)
        msleep(50);
 
        for (i = 0; i < ARRAY_SIZE(twinax_edc) && !err; i += 2)
-               err = mdio_write(phy, MDIO_DEV_PMA_PMD, twinax_edc[i],
-                                twinax_edc[i + 1]);
+               err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, twinax_edc[i],
+                                   twinax_edc[i + 1]);
        if (!err)
                phy->priv = edc_twinax;
        return err;
 }
 
-static int ael2005_i2c_rd(struct cphy *phy, int dev_addr, int word_addr)
-{
-       int i, err;
-       unsigned int stat, data;
-
-       err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL_I2C_CTRL,
-                        (dev_addr << 8) | (1 << 8) | word_addr);
-       if (err)
-               return err;
-
-       for (i = 0; i < 5; i++) {
-               msleep(1);
-               err = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL_I2C_STAT, &stat);
-               if (err)
-                       return err;
-               if ((stat & 3) == 1) {
-                       err = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL_I2C_DATA,
-                                       &data);
-                       if (err)
-                               return err;
-                       return data >> 8;
-               }
-       }
-       CH_WARN(phy->adapter, "PHY %u I2C read of addr %u timed out\n",
-               phy->addr, word_addr);
-       return -ETIMEDOUT;
-}
-
-static int get_module_type(struct cphy *phy, int delay_ms)
+static int ael2005_get_module_type(struct cphy *phy, int delay_ms)
 {
        int v;
        unsigned int stat;
 
-       v = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, &stat);
+       v = t3_mdio_read(phy, MDIO_MMD_PMAPMD, AEL2005_GPIO_CTRL, &stat);
        if (v)
                return v;
 
        if (stat & (1 << 8))                    /* module absent */
                return phy_modtype_none;
 
-       if (delay_ms)
-               msleep(delay_ms);
-
-       /* see SFF-8472 for below */
-       v = ael2005_i2c_rd(phy, MODULE_DEV_ADDR, 3);
-       if (v < 0)
-               return v;
-
-       if (v == 0x10)
-               return phy_modtype_sr;
-       if (v == 0x20)
-               return phy_modtype_lr;
-       if (v == 0x40)
-               return phy_modtype_lrm;
-
-       v = ael2005_i2c_rd(phy, MODULE_DEV_ADDR, 6);
-       if (v < 0)
-               return v;
-       if (v != 4)
-               goto unknown;
-
-       v = ael2005_i2c_rd(phy, MODULE_DEV_ADDR, 10);
-       if (v < 0)
-               return v;
-
-       if (v & 0x80) {
-               v = ael2005_i2c_rd(phy, MODULE_DEV_ADDR, 0x12);
-               if (v < 0)
-                       return v;
-               return v > 10 ? phy_modtype_twinax_long : phy_modtype_twinax;
-       }
-unknown:
-       return phy_modtype_unknown;
+       return ael2xxx_get_module_type(phy, delay_ms);
 }
 
 static int ael2005_intr_enable(struct cphy *phy)
 {
-       int err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, 0x200);
+       int err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL2005_GPIO_CTRL, 0x200);
        return err ? err : t3_phy_lasi_intr_enable(phy);
 }
 
 static int ael2005_intr_disable(struct cphy *phy)
 {
-       int err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, 0x100);
+       int err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL2005_GPIO_CTRL, 0x100);
        return err ? err : t3_phy_lasi_intr_disable(phy);
 }
 
 static int ael2005_intr_clear(struct cphy *phy)
 {
-       int err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, 0xd00);
+       int err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL2005_GPIO_CTRL, 0xd00);
        return err ? err : t3_phy_lasi_intr_clear(phy);
 }
 
 static int ael2005_reset(struct cphy *phy, int wait)
 {
        static struct reg_val regs0[] = {
-               { MDIO_DEV_PMA_PMD, 0xc001, 0, 1 << 5 },
-               { MDIO_DEV_PMA_PMD, 0xc017, 0, 1 << 5 },
-               { MDIO_DEV_PMA_PMD, 0xc013, 0xffff, 0xf341 },
-               { MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0x8000 },
-               { MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0x8100 },
-               { MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0x8000 },
-               { MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0 },
+               { MDIO_MMD_PMAPMD, 0xc001, 0, 1 << 5 },
+               { MDIO_MMD_PMAPMD, 0xc017, 0, 1 << 5 },
+               { MDIO_MMD_PMAPMD, 0xc013, 0xffff, 0xf341 },
+               { MDIO_MMD_PMAPMD, 0xc210, 0xffff, 0x8000 },
+               { MDIO_MMD_PMAPMD, 0xc210, 0xffff, 0x8100 },
+               { MDIO_MMD_PMAPMD, 0xc210, 0xffff, 0x8000 },
+               { MDIO_MMD_PMAPMD, 0xc210, 0xffff, 0 },
                { 0, 0, 0, 0 }
        };
        static struct reg_val regs1[] = {
-               { MDIO_DEV_PMA_PMD, 0xca00, 0xffff, 0x0080 },
-               { MDIO_DEV_PMA_PMD, 0xca12, 0xffff, 0 },
+               { MDIO_MMD_PMAPMD, 0xca00, 0xffff, 0x0080 },
+               { MDIO_MMD_PMAPMD, 0xca12, 0xffff, 0 },
                { 0, 0, 0, 0 }
        };
 
        int err;
        unsigned int lasi_ctrl;
 
-       err = mdio_read(phy, MDIO_DEV_PMA_PMD, LASI_CTRL, &lasi_ctrl);
+       err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, MDIO_PMA_LASI_CTRL,
+                          &lasi_ctrl);
        if (err)
                return err;
 
-       err = t3_phy_reset(phy, MDIO_DEV_PMA_PMD, 0);
+       err = t3_phy_reset(phy, MDIO_MMD_PMAPMD, 0);
        if (err)
                return err;
 
@@ -1024,7 +1061,7 @@ static int ael2005_reset(struct cphy *phy, int wait)
 
        msleep(50);
 
-       err = get_module_type(phy, 0);
+       err = ael2005_get_module_type(phy, 0);
        if (err < 0)
                return err;
        phy->modtype = err;
@@ -1051,18 +1088,18 @@ static int ael2005_intr_handler(struct cphy *phy)
        unsigned int stat;
        int ret, edc_needed, cause = 0;
 
-       ret = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_STAT, &stat);
+       ret = t3_mdio_read(phy, MDIO_MMD_PMAPMD, AEL2005_GPIO_STAT, &stat);
        if (ret)
                return ret;
 
        if (stat & AEL2005_MODDET_IRQ) {
-               ret = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL,
-                                0xd00);
+               ret = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL2005_GPIO_CTRL,
+                                   0xd00);
                if (ret)
                        return ret;
 
                /* modules have max 300 ms init time after hot plug */
-               ret = get_module_type(phy, 300);
+               ret = ael2005_get_module_type(phy, 300);
                if (ret < 0)
                        return ret;
 
@@ -1098,6 +1135,7 @@ static struct cphy_ops ael2005_ops = {
        .intr_handler    = ael2005_intr_handler,
        .get_link_status = get_link_status_r,
        .power_down      = ael1002_power_down,
+       .mmds            = MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS | MDIO_DEVS_PHYXS,
 };
 
 int t3_ael2005_phy_prep(struct cphy *phy, struct adapter *adapter,
@@ -1107,10 +1145,666 @@ int t3_ael2005_phy_prep(struct cphy *phy, struct adapter *adapter,
                  SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE |
                  SUPPORTED_IRQ, "10GBASE-R");
        msleep(125);
-       return t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, AEL_OPT_SETTINGS, 0,
+       return t3_mdio_change_bits(phy, MDIO_MMD_PMAPMD, AEL_OPT_SETTINGS, 0,
                                   1 << 5);
 }
 
+/*
+ * Setup EDC and other parameters for operation with an optical module.
+ */
+static int ael2020_setup_sr_edc(struct cphy *phy)
+{
+       static struct reg_val regs[] = {
+               /* set CDR offset to 10 */
+               { MDIO_MMD_PMAPMD, 0xcc01, 0xffff, 0x488a },
+
+               /* adjust 10G RX bias current */
+               { MDIO_MMD_PMAPMD, 0xcb1b, 0xffff, 0x0200 },
+               { MDIO_MMD_PMAPMD, 0xcb1c, 0xffff, 0x00f0 },
+               { MDIO_MMD_PMAPMD, 0xcc06, 0xffff, 0x00e0 },
+
+               /* end */
+               { 0, 0, 0, 0 }
+       };
+       int err;
+
+       err = set_phy_regs(phy, regs);
+       msleep(50);
+       if (err)
+               return err;
+
+       phy->priv = edc_sr;
+       return 0;
+}
+
+/*
+ * Setup EDC and other parameters for operation with an TWINAX module.
+ */
+static int ael2020_setup_twinax_edc(struct cphy *phy, int modtype)
+{
+       /* set uC to 40MHz */
+       static struct reg_val uCclock40MHz[] = {
+               { MDIO_MMD_PMAPMD, 0xff28, 0xffff, 0x4001 },
+               { MDIO_MMD_PMAPMD, 0xff2a, 0xffff, 0x0002 },
+               { 0, 0, 0, 0 }
+       };
+
+       /* activate uC clock */
+       static struct reg_val uCclockActivate[] = {
+               { MDIO_MMD_PMAPMD, 0xd000, 0xffff, 0x5200 },
+               { 0, 0, 0, 0 }
+       };
+
+       /* set PC to start of SRAM and activate uC */
+       static struct reg_val uCactivate[] = {
+               { MDIO_MMD_PMAPMD, 0xd080, 0xffff, 0x0100 },
+               { MDIO_MMD_PMAPMD, 0xd092, 0xffff, 0x0000 },
+               { 0, 0, 0, 0 }
+       };
+
+       /* TWINAX EDC firmware */
+       static u16 twinax_edc[] = {
+               0xd800, 0x4009,
+               0xd801, 0x2fff,
+               0xd802, 0x300f,
+               0xd803, 0x40aa,
+               0xd804, 0x401c,
+               0xd805, 0x401e,
+               0xd806, 0x2ff4,
+               0xd807, 0x3dc4,
+               0xd808, 0x2035,
+               0xd809, 0x3035,
+               0xd80a, 0x6524,
+               0xd80b, 0x2cb2,
+               0xd80c, 0x3012,
+               0xd80d, 0x1002,
+               0xd80e, 0x26e2,
+               0xd80f, 0x3022,
+               0xd810, 0x1002,
+               0xd811, 0x27d2,
+               0xd812, 0x3022,
+               0xd813, 0x1002,
+               0xd814, 0x2822,
+               0xd815, 0x3012,
+               0xd816, 0x1002,
+               0xd817, 0x2492,
+               0xd818, 0x3022,
+               0xd819, 0x1002,
+               0xd81a, 0x2772,
+               0xd81b, 0x3012,
+               0xd81c, 0x1002,
+               0xd81d, 0x23d2,
+               0xd81e, 0x3022,
+               0xd81f, 0x1002,
+               0xd820, 0x22cd,
+               0xd821, 0x301d,
+               0xd822, 0x27f2,
+               0xd823, 0x3022,
+               0xd824, 0x1002,
+               0xd825, 0x5553,
+               0xd826, 0x0307,
+               0xd827, 0x2522,
+               0xd828, 0x3022,
+               0xd829, 0x1002,
+               0xd82a, 0x2142,
+               0xd82b, 0x3012,
+               0xd82c, 0x1002,
+               0xd82d, 0x4016,
+               0xd82e, 0x5e63,
+               0xd82f, 0x0344,
+               0xd830, 0x2142,
+               0xd831, 0x3012,
+               0xd832, 0x1002,
+               0xd833, 0x400e,
+               0xd834, 0x2522,
+               0xd835, 0x3022,
+               0xd836, 0x1002,
+               0xd837, 0x2b52,
+               0xd838, 0x3012,
+               0xd839, 0x1002,
+               0xd83a, 0x2742,
+               0xd83b, 0x3022,
+               0xd83c, 0x1002,
+               0xd83d, 0x25e2,
+               0xd83e, 0x3022,
+               0xd83f, 0x1002,
+               0xd840, 0x2fa4,
+               0xd841, 0x3dc4,
+               0xd842, 0x6624,
+               0xd843, 0x414b,
+               0xd844, 0x56b3,
+               0xd845, 0x03c6,
+               0xd846, 0x866b,
+               0xd847, 0x400c,
+               0xd848, 0x2712,
+               0xd849, 0x3012,
+               0xd84a, 0x1002,
+               0xd84b, 0x2c4b,
+               0xd84c, 0x309b,
+               0xd84d, 0x56b3,
+               0xd84e, 0x03c3,
+               0xd84f, 0x866b,
+               0xd850, 0x400c,
+               0xd851, 0x2272,
+               0xd852, 0x3022,
+               0xd853, 0x1002,
+               0xd854, 0x2742,
+               0xd855, 0x3022,
+               0xd856, 0x1002,
+               0xd857, 0x25e2,
+               0xd858, 0x3022,
+               0xd859, 0x1002,
+               0xd85a, 0x2fb4,
+               0xd85b, 0x3dc4,
+               0xd85c, 0x6624,
+               0xd85d, 0x56b3,
+               0xd85e, 0x03c3,
+               0xd85f, 0x866b,
+               0xd860, 0x401c,
+               0xd861, 0x2c45,
+               0xd862, 0x3095,
+               0xd863, 0x5b53,
+               0xd864, 0x2372,
+               0xd865, 0x3012,
+               0xd866, 0x13c2,
+               0xd867, 0x5cc3,
+               0xd868, 0x2712,
+               0xd869, 0x3012,
+               0xd86a, 0x1312,
+               0xd86b, 0x2b52,
+               0xd86c, 0x3012,
+               0xd86d, 0x1002,
+               0xd86e, 0x2742,
+               0xd86f, 0x3022,
+               0xd870, 0x1002,
+               0xd871, 0x2582,
+               0xd872, 0x3022,
+               0xd873, 0x1002,
+               0xd874, 0x2142,
+               0xd875, 0x3012,
+               0xd876, 0x1002,
+               0xd877, 0x628f,
+               0xd878, 0x2985,
+               0xd879, 0x33a5,
+               0xd87a, 0x25e2,
+               0xd87b, 0x3022,
+               0xd87c, 0x1002,
+               0xd87d, 0x5653,
+               0xd87e, 0x03d2,
+               0xd87f, 0x401e,
+               0xd880, 0x6f72,
+               0xd881, 0x1002,
+               0xd882, 0x628f,
+               0xd883, 0x2304,
+               0xd884, 0x3c84,
+               0xd885, 0x6436,
+               0xd886, 0xdff4,
+               0xd887, 0x6436,
+               0xd888, 0x2ff5,
+               0xd889, 0x3005,
+               0xd88a, 0x8656,
+               0xd88b, 0xdfba,
+               0xd88c, 0x56a3,
+               0xd88d, 0xd05a,
+               0xd88e, 0x2972,
+               0xd88f, 0x3012,
+               0xd890, 0x1392,
+               0xd891, 0xd05a,
+               0xd892, 0x56a3,
+               0xd893, 0xdfba,
+               0xd894, 0x0383,
+               0xd895, 0x6f72,
+               0xd896, 0x1002,
+               0xd897, 0x2b45,
+               0xd898, 0x3005,
+               0xd899, 0x4178,
+               0xd89a, 0x5653,
+               0xd89b, 0x0384,
+               0xd89c, 0x2a62,
+               0xd89d, 0x3012,
+               0xd89e, 0x1002,
+               0xd89f, 0x2f05,
+               0xd8a0, 0x3005,
+               0xd8a1, 0x41c8,
+               0xd8a2, 0x5653,
+               0xd8a3, 0x0382,
+               0xd8a4, 0x0002,
+               0xd8a5, 0x4218,
+               0xd8a6, 0x2474,
+               0xd8a7, 0x3c84,
+               0xd8a8, 0x6437,
+               0xd8a9, 0xdff4,
+               0xd8aa, 0x6437,
+               0xd8ab, 0x2ff5,
+               0xd8ac, 0x3c05,
+               0xd8ad, 0x8757,
+               0xd8ae, 0xb888,
+               0xd8af, 0x9787,
+               0xd8b0, 0xdff4,
+               0xd8b1, 0x6724,
+               0xd8b2, 0x866a,
+               0xd8b3, 0x6f72,
+               0xd8b4, 0x1002,
+               0xd8b5, 0x2641,
+               0xd8b6, 0x3021,
+               0xd8b7, 0x1001,
+               0xd8b8, 0xc620,
+               0xd8b9, 0x0000,
+               0xd8ba, 0xc621,
+               0xd8bb, 0x0000,
+               0xd8bc, 0xc622,
+               0xd8bd, 0x00ce,
+               0xd8be, 0xc623,
+               0xd8bf, 0x007f,
+               0xd8c0, 0xc624,
+               0xd8c1, 0x0032,
+               0xd8c2, 0xc625,
+               0xd8c3, 0x0000,
+               0xd8c4, 0xc627,
+               0xd8c5, 0x0000,
+               0xd8c6, 0xc628,
+               0xd8c7, 0x0000,
+               0xd8c8, 0xc62c,
+               0xd8c9, 0x0000,
+               0xd8ca, 0x0000,
+               0xd8cb, 0x2641,
+               0xd8cc, 0x3021,
+               0xd8cd, 0x1001,
+               0xd8ce, 0xc502,
+               0xd8cf, 0x53ac,
+               0xd8d0, 0xc503,
+               0xd8d1, 0x2cd3,
+               0xd8d2, 0xc600,
+               0xd8d3, 0x2a6e,
+               0xd8d4, 0xc601,
+               0xd8d5, 0x2a2c,
+               0xd8d6, 0xc605,
+               0xd8d7, 0x5557,
+               0xd8d8, 0xc60c,
+               0xd8d9, 0x5400,
+               0xd8da, 0xc710,
+               0xd8db, 0x0700,
+               0xd8dc, 0xc711,
+               0xd8dd, 0x0f06,
+               0xd8de, 0xc718,
+               0xd8df, 0x0700,
+               0xd8e0, 0xc719,
+               0xd8e1, 0x0f06,
+               0xd8e2, 0xc720,
+               0xd8e3, 0x4700,
+               0xd8e4, 0xc721,
+               0xd8e5, 0x0f06,
+               0xd8e6, 0xc728,
+               0xd8e7, 0x0700,
+               0xd8e8, 0xc729,
+               0xd8e9, 0x1207,
+               0xd8ea, 0xc801,
+               0xd8eb, 0x7f50,
+               0xd8ec, 0xc802,
+               0xd8ed, 0x7760,
+               0xd8ee, 0xc803,
+               0xd8ef, 0x7fce,
+               0xd8f0, 0xc804,
+               0xd8f1, 0x520e,
+               0xd8f2, 0xc805,
+               0xd8f3, 0x5c11,
+               0xd8f4, 0xc806,
+               0xd8f5, 0x3c51,
+               0xd8f6, 0xc807,
+               0xd8f7, 0x4061,
+               0xd8f8, 0xc808,
+               0xd8f9, 0x49c1,
+               0xd8fa, 0xc809,
+               0xd8fb, 0x3840,
+               0xd8fc, 0xc80a,
+               0xd8fd, 0x0000,
+               0xd8fe, 0xc821,
+               0xd8ff, 0x0002,
+               0xd900, 0xc822,
+               0xd901, 0x0046,
+               0xd902, 0xc844,
+               0xd903, 0x182f,
+               0xd904, 0xc013,
+               0xd905, 0xf341,
+               0xd906, 0xc084,
+               0xd907, 0x0030,
+               0xd908, 0xc904,
+               0xd909, 0x1401,
+               0xd90a, 0xcb0c,
+               0xd90b, 0x0004,
+               0xd90c, 0xcb0e,
+               0xd90d, 0xa00a,
+               0xd90e, 0xcb0f,
+               0xd90f, 0xc0c0,
+               0xd910, 0xcb10,
+               0xd911, 0xc0c0,
+               0xd912, 0xcb11,
+               0xd913, 0x00a0,
+               0xd914, 0xcb12,
+               0xd915, 0x0007,
+               0xd916, 0xc241,
+               0xd917, 0xa000,
+               0xd918, 0xc243,
+               0xd919, 0x7fe0,
+               0xd91a, 0xc604,
+               0xd91b, 0x000e,
+               0xd91c, 0xc609,
+               0xd91d, 0x00f5,
+               0xd91e, 0xc611,
+               0xd91f, 0x000e,
+               0xd920, 0xc660,
+               0xd921, 0x9600,
+               0xd922, 0xc687,
+               0xd923, 0x0004,
+               0xd924, 0xc60a,
+               0xd925, 0x04f5,
+               0xd926, 0x0000,
+               0xd927, 0x2641,
+               0xd928, 0x3021,
+               0xd929, 0x1001,
+               0xd92a, 0xc620,
+               0xd92b, 0x14e5,
+               0xd92c, 0xc621,
+               0xd92d, 0xc53d,
+               0xd92e, 0xc622,
+               0xd92f, 0x3cbe,
+               0xd930, 0xc623,
+               0xd931, 0x4452,
+               0xd932, 0xc624,
+               0xd933, 0xc5c5,
+               0xd934, 0xc625,
+               0xd935, 0xe01e,
+               0xd936, 0xc627,
+               0xd937, 0x0000,
+               0xd938, 0xc628,
+               0xd939, 0x0000,
+               0xd93a, 0xc62c,
+               0xd93b, 0x0000,
+               0xd93c, 0x0000,
+               0xd93d, 0x2b84,
+               0xd93e, 0x3c74,
+               0xd93f, 0x6435,
+               0xd940, 0xdff4,
+               0xd941, 0x6435,
+               0xd942, 0x2806,
+               0xd943, 0x3006,
+               0xd944, 0x8565,
+               0xd945, 0x2b24,
+               0xd946, 0x3c24,
+               0xd947, 0x6436,
+               0xd948, 0x1002,
+               0xd949, 0x2b24,
+               0xd94a, 0x3c24,
+               0xd94b, 0x6436,
+               0xd94c, 0x4045,
+               0xd94d, 0x8656,
+               0xd94e, 0x5663,
+               0xd94f, 0x0302,
+               0xd950, 0x401e,
+               0xd951, 0x1002,
+               0xd952, 0x2807,
+               0xd953, 0x31a7,
+               0xd954, 0x20c4,
+               0xd955, 0x3c24,
+               0xd956, 0x6724,
+               0xd957, 0x1002,
+               0xd958, 0x2807,
+               0xd959, 0x3187,
+               0xd95a, 0x20c4,
+               0xd95b, 0x3c24,
+               0xd95c, 0x6724,
+               0xd95d, 0x1002,
+               0xd95e, 0x24f4,
+               0xd95f, 0x3c64,
+               0xd960, 0x6436,
+               0xd961, 0xdff4,
+               0xd962, 0x6436,
+               0xd963, 0x1002,
+               0xd964, 0x2006,
+               0xd965, 0x3d76,
+               0xd966, 0xc161,
+               0xd967, 0x6134,
+               0xd968, 0x6135,
+               0xd969, 0x5443,
+               0xd96a, 0x0303,
+               0xd96b, 0x6524,
+               0xd96c, 0x00fb,
+               0xd96d, 0x1002,
+               0xd96e, 0x20d4,
+               0xd96f, 0x3c24,
+               0xd970, 0x2025,
+               0xd971, 0x3005,
+               0xd972, 0x6524,
+               0xd973, 0x1002,
+               0xd974, 0xd019,
+               0xd975, 0x2104,
+               0xd976, 0x3c24,
+               0xd977, 0x2105,
+               0xd978, 0x3805,
+               0xd979, 0x6524,
+               0xd97a, 0xdff4,
+               0xd97b, 0x4005,
+               0xd97c, 0x6524,
+               0xd97d, 0x2e8d,
+               0xd97e, 0x303d,
+               0xd97f, 0x2408,
+               0xd980, 0x35d8,
+               0xd981, 0x5dd3,
+               0xd982, 0x0307,
+               0xd983, 0x8887,
+               0xd984, 0x63a7,
+               0xd985, 0x8887,
+               0xd986, 0x63a7,
+               0xd987, 0xdffd,
+               0xd988, 0x00f9,
+               0xd989, 0x1002,
+               0xd98a, 0x0000,
+       };
+       int i, err;
+
+       /* set uC clock and activate it */
+       err = set_phy_regs(phy, uCclock40MHz);
+       msleep(500);
+       if (err)
+               return err;
+       err = set_phy_regs(phy, uCclockActivate);
+       msleep(500);
+       if (err)
+               return err;
+
+       /* write TWINAX EDC firmware into PHY */
+       for (i = 0; i < ARRAY_SIZE(twinax_edc) && !err; i += 2)
+               err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, twinax_edc[i],
+                                   twinax_edc[i + 1]);
+       /* activate uC */
+       err = set_phy_regs(phy, uCactivate);
+       if (!err)
+               phy->priv = edc_twinax;
+       return err;
+}
+
+/*
+ * Return Module Type.
+ */
+static int ael2020_get_module_type(struct cphy *phy, int delay_ms)
+{
+       int v;
+       unsigned int stat;
+
+       v = t3_mdio_read(phy, MDIO_MMD_PMAPMD, AEL2020_GPIO_STAT, &stat);
+       if (v)
+               return v;
+
+       if (stat & (0x1 << (AEL2020_GPIO_MODDET*4))) {
+               /* module absent */
+               return phy_modtype_none;
+       }
+
+       return ael2xxx_get_module_type(phy, delay_ms);
+}
+
+/*
+ * Enable PHY interrupts.  We enable "Module Detection" interrupts (on any
+ * state transition) and then generic Link Alarm Status Interrupt (LASI).
+ */
+static int ael2020_intr_enable(struct cphy *phy)
+{
+       int err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL2020_GPIO_CTRL,
+                               0x2 << (AEL2020_GPIO_MODDET*4));
+       return err ? err : t3_phy_lasi_intr_enable(phy);
+}
+
+/*
+ * Disable PHY interrupts.  The mirror of the above ...
+ */
+static int ael2020_intr_disable(struct cphy *phy)
+{
+       int err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL2020_GPIO_CTRL,
+                               0x1 << (AEL2020_GPIO_MODDET*4));
+       return err ? err : t3_phy_lasi_intr_disable(phy);
+}
+
+/*
+ * Clear PHY interrupt state.
+ */
+static int ael2020_intr_clear(struct cphy *phy)
+{
+       /*
+        * The GPIO Interrupt register on the AEL2020 is a "Latching High"
+        * (LH) register which is cleared to the current state when it's read.
+        * Thus, we simply read the register and discard the result.
+        */
+       unsigned int stat;
+       int err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, AEL2020_GPIO_INTR, &stat);
+       return err ? err : t3_phy_lasi_intr_clear(phy);
+}
+
+/*
+ * Reset the PHY and put it into a canonical operating state.
+ */
+static int ael2020_reset(struct cphy *phy, int wait)
+{
+       static struct reg_val regs0[] = {
+               /* Erratum #2: CDRLOL asserted, causing PMA link down status */
+               { MDIO_MMD_PMAPMD, 0xc003, 0xffff, 0x3101 },
+
+               /* force XAUI to send LF when RX_LOS is asserted */
+               { MDIO_MMD_PMAPMD, 0xcd40, 0xffff, 0x0001 },
+
+               /* RX_LOS pin is active high */
+               { MDIO_MMD_PMAPMD, AEL_OPT_SETTINGS,
+                       0x0020, 0x0020 },
+
+               /* output Module's Loss Of Signal (LOS) to LED */
+               { MDIO_MMD_PMAPMD, AEL2020_GPIO_CFG+AEL2020_GPIO_LSTAT,
+                       0xffff, 0x0004 },
+               { MDIO_MMD_PMAPMD, AEL2020_GPIO_CTRL,
+                       0xffff, 0x8 << (AEL2020_GPIO_LSTAT*4) },
+
+               /* end */
+               { 0, 0, 0, 0 }
+       };
+       int err;
+       unsigned int lasi_ctrl;
+
+       /* grab current interrupt state */
+       err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, MDIO_PMA_LASI_CTRL,
+                          &lasi_ctrl);
+       if (err)
+               return err;
+
+       err = t3_phy_reset(phy, MDIO_MMD_PMAPMD, 125);
+       if (err)
+               return err;
+       msleep(100);
+
+       /* basic initialization for all module types */
+       phy->priv = edc_none;
+       err = set_phy_regs(phy, regs0);
+       if (err)
+               return err;
+
+       /* determine module type and perform appropriate initialization */
+       err = ael2020_get_module_type(phy, 0);
+       if (err < 0)
+               return err;
+       phy->modtype = (u8)err;
+       if (err == phy_modtype_twinax || err == phy_modtype_twinax_long)
+               err = ael2020_setup_twinax_edc(phy, err);
+       else
+               err = ael2020_setup_sr_edc(phy);
+       if (err)
+               return err;
+
+       /* reset wipes out interrupts, reenable them if they were on */
+       if (lasi_ctrl & 1)
+               err = ael2005_intr_enable(phy);
+       return err;
+}
+
+/*
+ * Handle a PHY interrupt.
+ */
+static int ael2020_intr_handler(struct cphy *phy)
+{
+       unsigned int stat;
+       int ret, edc_needed, cause = 0;
+
+       ret = t3_mdio_read(phy, MDIO_MMD_PMAPMD, AEL2020_GPIO_INTR, &stat);
+       if (ret)
+               return ret;
+
+       if (stat & (0x1 << AEL2020_GPIO_MODDET)) {
+               /* modules have max 300 ms init time after hot plug */
+               ret = ael2020_get_module_type(phy, 300);
+               if (ret < 0)
+                       return ret;
+
+               phy->modtype = (u8)ret;
+               if (ret == phy_modtype_none)
+                       edc_needed = phy->priv;       /* on unplug retain EDC */
+               else if (ret == phy_modtype_twinax ||
+                        ret == phy_modtype_twinax_long)
+                       edc_needed = edc_twinax;
+               else
+                       edc_needed = edc_sr;
+
+               if (edc_needed != phy->priv) {
+                       ret = ael2020_reset(phy, 0);
+                       return ret ? ret : cphy_cause_module_change;
+               }
+               cause = cphy_cause_module_change;
+       }
+
+       ret = t3_phy_lasi_intr_handler(phy);
+       if (ret < 0)
+               return ret;
+
+       ret |= cause;
+       return ret ? ret : cphy_cause_link_change;
+}
+
+static struct cphy_ops ael2020_ops = {
+       .reset           = ael2020_reset,
+       .intr_enable     = ael2020_intr_enable,
+       .intr_disable    = ael2020_intr_disable,
+       .intr_clear      = ael2020_intr_clear,
+       .intr_handler    = ael2020_intr_handler,
+       .get_link_status = get_link_status_r,
+       .power_down      = ael1002_power_down,
+       .mmds            = MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS | MDIO_DEVS_PHYXS,
+};
+
+int t3_ael2020_phy_prep(struct cphy *phy, struct adapter *adapter, int phy_addr,
+                       const struct mdio_ops *mdio_ops)
+{
+       cphy_init(phy, adapter, phy_addr, &ael2020_ops, mdio_ops,
+                 SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE |
+                 SUPPORTED_IRQ, "10GBASE-R");
+       msleep(125);
+       return 0;
+}
+
 /*
  * Get link status for a 10GBASE-X device.
  */
@@ -1119,12 +1813,15 @@ static int get_link_status_x(struct cphy *phy, int *link_ok, int *speed,
 {
        if (link_ok) {
                unsigned int stat0, stat1, stat2;
-               int err = mdio_read(phy, MDIO_DEV_PMA_PMD, PMD_RSD, &stat0);
+               int err = t3_mdio_read(phy, MDIO_MMD_PMAPMD,
+                                      MDIO_PMA_RXDET, &stat0);
 
                if (!err)
-                       err = mdio_read(phy, MDIO_DEV_PCS, PCS_STAT1_X, &stat1);
+                       err = t3_mdio_read(phy, MDIO_MMD_PCS,
+                                          MDIO_PCS_10GBX_STAT1, &stat1);
                if (!err)
-                       err = mdio_read(phy, MDIO_DEV_XGXS, XS_LN_STAT, &stat2);
+                       err = t3_mdio_read(phy, MDIO_MMD_PHYXS,
+                                          MDIO_PHYXS_LNSTAT, &stat2);
                if (err)
                        return err;
                *link_ok = (stat0 & (stat1 >> 12) & (stat2 >> 12)) & 1;
@@ -1144,6 +1841,7 @@ static struct cphy_ops qt2045_ops = {
        .intr_handler = t3_phy_lasi_intr_handler,
        .get_link_status = get_link_status_x,
        .power_down = ael1006_power_down,
+       .mmds = MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS | MDIO_DEVS_PHYXS,
 };
 
 int t3_qt2045_phy_prep(struct cphy *phy, struct adapter *adapter,
@@ -1159,9 +1857,10 @@ int t3_qt2045_phy_prep(struct cphy *phy, struct adapter *adapter,
         * Some cards where the PHY is supposed to be at address 0 actually
         * have it at 1.
         */
-       if (!phy_addr && !mdio_read(phy, MDIO_DEV_PMA_PMD, MII_BMSR, &stat) &&
+       if (!phy_addr &&
+           !t3_mdio_read(phy, MDIO_MMD_PMAPMD, MDIO_STAT1, &stat) &&
            stat == 0xffff)
-               phy->addr = 1;
+               phy->mdio.prtad = 1;
        return 0;
 }
 
@@ -1175,15 +1874,16 @@ static int xaui_direct_get_link_status(struct cphy *phy, int *link_ok,
 {
        if (link_ok) {
                unsigned int status;
+               int prtad = phy->mdio.prtad;
 
                status = t3_read_reg(phy->adapter,
-                                    XGM_REG(A_XGM_SERDES_STAT0, phy->addr)) |
+                                    XGM_REG(A_XGM_SERDES_STAT0, prtad)) |
                    t3_read_reg(phy->adapter,
-                               XGM_REG(A_XGM_SERDES_STAT1, phy->addr)) |
+                                   XGM_REG(A_XGM_SERDES_STAT1, prtad)) |
                    t3_read_reg(phy->adapter,
-                               XGM_REG(A_XGM_SERDES_STAT2, phy->addr)) |
+                               XGM_REG(A_XGM_SERDES_STAT2, prtad)) |
                    t3_read_reg(phy->adapter,
-                               XGM_REG(A_XGM_SERDES_STAT3, phy->addr));
+                               XGM_REG(A_XGM_SERDES_STAT3, prtad));
                *link_ok = !(status & F_LOWSIG0);
        }
        if (speed)
@@ -1211,7 +1911,7 @@ static struct cphy_ops xaui_direct_ops = {
 int t3_xaui_direct_phy_prep(struct cphy *phy, struct adapter *adapter,
                            int phy_addr, const struct mdio_ops *mdio_ops)
 {
-       cphy_init(phy, adapter, phy_addr, &xaui_direct_ops, mdio_ops,
+       cphy_init(phy, adapter, MDIO_PRTAD_NONE, &xaui_direct_ops, mdio_ops,
                  SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_TP,
                  "10GBASE-CX4");
        return 0;
diff --git a/drivers/net/cxgb3/aq100x.c b/drivers/net/cxgb3/aq100x.c
new file mode 100644 (file)
index 0000000..b1fd5bf
--- /dev/null
@@ -0,0 +1,355 @@
+/*
+ * Copyright (c) 2005-2008 Chelsio, Inc. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include "common.h"
+#include "regs.h"
+
+enum {
+       /* MDIO_DEV_PMA_PMD registers */
+       AQ_LINK_STAT    = 0xe800,
+       AQ_IMASK_PMA    = 0xf000,
+
+       /* MDIO_DEV_XGXS registers */
+       AQ_XAUI_RX_CFG  = 0xc400,
+       AQ_XAUI_TX_CFG  = 0xe400,
+
+       /* MDIO_DEV_ANEG registers */
+       AQ_1G_CTRL      = 0xc400,
+       AQ_ANEG_STAT    = 0xc800,
+
+       /* MDIO_DEV_VEND1 registers */
+       AQ_FW_VERSION   = 0x0020,
+       AQ_IFLAG_GLOBAL = 0xfc00,
+       AQ_IMASK_GLOBAL = 0xff00,
+};
+
+enum {
+       IMASK_PMA       = 1 << 2,
+       IMASK_GLOBAL    = 1 << 15,
+       ADV_1G_FULL     = 1 << 15,
+       ADV_1G_HALF     = 1 << 14,
+       ADV_10G_FULL    = 1 << 12,
+       AQ_RESET        = (1 << 14) | (1 << 15),
+       AQ_LOWPOWER     = 1 << 12,
+};
+
+static int aq100x_reset(struct cphy *phy, int wait)
+{
+       /*
+        * Ignore the caller specified wait time; always wait for the reset to
+        * complete. Can take up to 3s.
+        */
+       int err = t3_phy_reset(phy, MDIO_MMD_VEND1, 3000);
+
+       if (err)
+               CH_WARN(phy->adapter, "PHY%d: reset failed (0x%x).\n",
+                       phy->mdio.prtad, err);
+
+       return err;
+}
+
+static int aq100x_intr_enable(struct cphy *phy)
+{
+       int err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AQ_IMASK_PMA, IMASK_PMA);
+       if (err)
+               return err;
+
+       err = t3_mdio_write(phy, MDIO_MMD_VEND1, AQ_IMASK_GLOBAL, IMASK_GLOBAL);
+       return err;
+}
+
+static int aq100x_intr_disable(struct cphy *phy)
+{
+       return t3_mdio_write(phy, MDIO_MMD_VEND1, AQ_IMASK_GLOBAL, 0);
+}
+
+static int aq100x_intr_clear(struct cphy *phy)
+{
+       unsigned int v;
+
+       t3_mdio_read(phy, MDIO_MMD_VEND1, AQ_IFLAG_GLOBAL, &v);
+       t3_mdio_read(phy, MDIO_MMD_PMAPMD, MDIO_STAT1, &v);
+
+       return 0;
+}
+
+static int aq100x_intr_handler(struct cphy *phy)
+{
+       int err;
+       unsigned int cause, v;
+
+       err = t3_mdio_read(phy, MDIO_MMD_VEND1, AQ_IFLAG_GLOBAL, &cause);
+       if (err)
+               return err;
+
+       /* Read (and reset) the latching version of the status */
+       t3_mdio_read(phy, MDIO_MMD_PMAPMD, MDIO_STAT1, &v);
+
+       return cphy_cause_link_change;
+}
+
+static int aq100x_power_down(struct cphy *phy, int off)
+{
+       return mdio_set_flag(&phy->mdio, phy->mdio.prtad,
+                            MDIO_MMD_PMAPMD, MDIO_CTRL1,
+                            MDIO_CTRL1_LPOWER, off);
+}
+
+static int aq100x_autoneg_enable(struct cphy *phy)
+{
+       int err;
+
+       err = aq100x_power_down(phy, 0);
+       if (!err)
+               err = mdio_set_flag(&phy->mdio, phy->mdio.prtad,
+                                   MDIO_MMD_AN, MDIO_CTRL1,
+                                   BMCR_ANENABLE | BMCR_ANRESTART, 1);
+
+       return err;
+}
+
+static int aq100x_autoneg_restart(struct cphy *phy)
+{
+       int err;
+
+       err = aq100x_power_down(phy, 0);
+       if (!err)
+               err = mdio_set_flag(&phy->mdio, phy->mdio.prtad,
+                                   MDIO_MMD_AN, MDIO_CTRL1,
+                                   BMCR_ANENABLE | BMCR_ANRESTART, 1);
+
+       return err;
+}
+
+static int aq100x_advertise(struct cphy *phy, unsigned int advertise_map)
+{
+       unsigned int adv;
+       int err;
+
+       /* 10G advertisement */
+       adv = 0;
+       if (advertise_map & ADVERTISED_10000baseT_Full)
+               adv |= ADV_10G_FULL;
+       err = t3_mdio_change_bits(phy, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL,
+                                 ADV_10G_FULL, adv);
+       if (err)
+               return err;
+
+       /* 1G advertisement */
+       adv = 0;
+       if (advertise_map & ADVERTISED_1000baseT_Full)
+               adv |= ADV_1G_FULL;
+       if (advertise_map & ADVERTISED_1000baseT_Half)
+               adv |= ADV_1G_HALF;
+       err = t3_mdio_change_bits(phy, MDIO_MMD_AN, AQ_1G_CTRL,
+                                 ADV_1G_FULL | ADV_1G_HALF, adv);
+       if (err)
+               return err;
+
+       /* 100M, pause advertisement */
+       adv = 0;
+       if (advertise_map & ADVERTISED_100baseT_Half)
+               adv |= ADVERTISE_100HALF;
+       if (advertise_map & ADVERTISED_100baseT_Full)
+               adv |= ADVERTISE_100FULL;
+       if (advertise_map & ADVERTISED_Pause)
+               adv |= ADVERTISE_PAUSE_CAP;
+       if (advertise_map & ADVERTISED_Asym_Pause)
+               adv |= ADVERTISE_PAUSE_ASYM;
+       err = t3_mdio_change_bits(phy, MDIO_MMD_AN, MDIO_AN_ADVERTISE,
+                                 0xfe0, adv);
+
+       return err;
+}
+
+static int aq100x_set_loopback(struct cphy *phy, int mmd, int dir, int enable)
+{
+       return mdio_set_flag(&phy->mdio, phy->mdio.prtad,
+                            MDIO_MMD_PMAPMD, MDIO_CTRL1,
+                            BMCR_LOOPBACK, enable);
+}
+
+static int aq100x_set_speed_duplex(struct cphy *phy, int speed, int duplex)
+{
+       /* no can do */
+       return -1;
+}
+
+static int aq100x_get_link_status(struct cphy *phy, int *link_ok,
+                                 int *speed, int *duplex, int *fc)
+{
+       int err;
+       unsigned int v;
+
+       if (link_ok) {
+               err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, AQ_LINK_STAT, &v);
+               if (err)
+                       return err;
+
+               *link_ok = v & 1;
+               if (!*link_ok)
+                       return 0;
+       }
+
+       err = t3_mdio_read(phy, MDIO_MMD_AN, AQ_ANEG_STAT, &v);
+       if (err)
+               return err;
+
+       if (speed) {
+               switch (v & 0x6) {
+               case 0x6:
+                       *speed = SPEED_10000;
+                       break;
+               case 0x4:
+                       *speed = SPEED_1000;
+                       break;
+               case 0x2:
+                       *speed = SPEED_100;
+                       break;
+               case 0x0:
+                       *speed = SPEED_10;
+                       break;
+               }
+       }
+
+       if (duplex)
+               *duplex = v & 1 ? DUPLEX_FULL : DUPLEX_HALF;
+
+       return 0;
+}
+
+static struct cphy_ops aq100x_ops = {
+       .reset             = aq100x_reset,
+       .intr_enable       = aq100x_intr_enable,
+       .intr_disable      = aq100x_intr_disable,
+       .intr_clear        = aq100x_intr_clear,
+       .intr_handler      = aq100x_intr_handler,
+       .autoneg_enable    = aq100x_autoneg_enable,
+       .autoneg_restart   = aq100x_autoneg_restart,
+       .advertise         = aq100x_advertise,
+       .set_loopback      = aq100x_set_loopback,
+       .set_speed_duplex  = aq100x_set_speed_duplex,
+       .get_link_status   = aq100x_get_link_status,
+       .power_down        = aq100x_power_down,
+       .mmds              = MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS | MDIO_DEVS_PHYXS,
+};
+
+int t3_aq100x_phy_prep(struct cphy *phy, struct adapter *adapter, int phy_addr,
+                      const struct mdio_ops *mdio_ops)
+{
+       unsigned int v, v2, gpio, wait;
+       int err;
+
+       cphy_init(phy, adapter, phy_addr, &aq100x_ops, mdio_ops,
+                 SUPPORTED_1000baseT_Full | SUPPORTED_10000baseT_Full |
+                 SUPPORTED_Autoneg | SUPPORTED_AUI, "1000/10GBASE-T");
+
+       /*
+        * The PHY has been out of reset ever since the system powered up.  So
+        * we do a hard reset over here.
+        */
+       gpio = phy_addr ? F_GPIO10_OUT_VAL : F_GPIO6_OUT_VAL;
+       t3_set_reg_field(adapter, A_T3DBG_GPIO_EN, gpio, 0);
+       msleep(1);
+       t3_set_reg_field(adapter, A_T3DBG_GPIO_EN, gpio, gpio);
+
+       /*
+        * Give it enough time to load the firmware and get ready for mdio.
+        */
+       msleep(1000);
+       wait = 500; /* in 10ms increments */
+       do {
+               err = t3_mdio_read(phy, MDIO_MMD_VEND1, MDIO_CTRL1, &v);
+               if (err || v == 0xffff) {
+
+                       /* Allow prep_adapter to succeed when ffff is read */
+
+                       CH_WARN(adapter, "PHY%d: reset failed (0x%x, 0x%x).\n",
+                               phy_addr, err, v);
+                       goto done;
+               }
+
+               v &= AQ_RESET;
+               if (v)
+                       msleep(10);
+       } while (v && --wait);
+       if (v) {
+               CH_WARN(adapter, "PHY%d: reset timed out (0x%x).\n",
+                       phy_addr, v);
+
+               goto done; /* let prep_adapter succeed */
+       }
+
+       /* Datasheet says 3s max but this has been observed */
+       wait = (500 - wait) * 10 + 1000;
+       if (wait > 3000)
+               CH_WARN(adapter, "PHY%d: reset took %ums\n", phy_addr, wait);
+
+       /* Firmware version check. */
+       t3_mdio_read(phy, MDIO_MMD_VEND1, AQ_FW_VERSION, &v);
+       if (v != 30) {
+               CH_WARN(adapter, "PHY%d: unsupported firmware %d\n",
+                       phy_addr, v);
+               return 0; /* allow t3_prep_adapter to succeed */
+       }
+
+       /*
+        * The PHY should start in really-low-power mode.  Prepare it for normal
+        * operations.
+        */
+       err = t3_mdio_read(phy, MDIO_MMD_VEND1, MDIO_CTRL1, &v);
+       if (err)
+               return err;
+       if (v & AQ_LOWPOWER) {
+               err = t3_mdio_change_bits(phy, MDIO_MMD_VEND1, MDIO_CTRL1,
+                                         AQ_LOWPOWER, 0);
+               if (err)
+                       return err;
+               msleep(10);
+       } else
+               CH_WARN(adapter, "PHY%d does not start in low power mode.\n",
+                       phy_addr);
+
+       /*
+        * Verify XAUI settings, but let prep succeed no matter what.
+        */
+       v = v2 = 0;
+       t3_mdio_read(phy, MDIO_MMD_PHYXS, AQ_XAUI_RX_CFG, &v);
+       t3_mdio_read(phy, MDIO_MMD_PHYXS, AQ_XAUI_TX_CFG, &v2);
+       if (v != 0x1b || v2 != 0x1b)
+               CH_WARN(adapter,
+                       "PHY%d: incorrect XAUI settings (0x%x, 0x%x).\n",
+                       phy_addr, v, v2);
+
+done:
+       return err;
+}
index e508dc32f3ec620e1e7cdd6c2594711f429ed244..d21b705501a9040a9ec72ffce732e214ef3bd312 100644 (file)
@@ -39,7 +39,7 @@
 #include <linux/init.h>
 #include <linux/netdevice.h>
 #include <linux/ethtool.h>
-#include <linux/mii.h>
+#include <linux/mdio.h>
 #include "version.h"
 
 #define CH_ERR(adap, fmt, ...)   dev_err(&adap->pdev->dev, fmt, ## __VA_ARGS__)
@@ -184,10 +184,11 @@ struct cphy;
 struct adapter;
 
 struct mdio_ops {
-       int (*read)(struct adapter *adapter, int phy_addr, int mmd_addr,
-                   int reg_addr, unsigned int *val);
-       int (*write)(struct adapter *adapter, int phy_addr, int mmd_addr,
-                    int reg_addr, unsigned int val);
+       int (*read)(struct net_device *dev, int phy_addr, int mmd_addr,
+                   u16 reg_addr);
+       int (*write)(struct net_device *dev, int phy_addr, int mmd_addr,
+                    u16 reg_addr, u16 val);
+       unsigned mode_support;
 };
 
 struct adapter_info {
@@ -520,27 +521,6 @@ enum {
        MAC_RXFIFO_SIZE = 32768
 };
 
-/* IEEE 802.3 specified MDIO devices */
-enum {
-       MDIO_DEV_PMA_PMD = 1,
-       MDIO_DEV_WIS = 2,
-       MDIO_DEV_PCS = 3,
-       MDIO_DEV_XGXS = 4,
-       MDIO_DEV_ANEG = 7,
-       MDIO_DEV_VEND1 = 30,
-       MDIO_DEV_VEND2 = 31
-};
-
-/* LASI control and status registers */
-enum {
-       RX_ALARM_CTRL = 0x9000,
-       TX_ALARM_CTRL = 0x9001,
-       LASI_CTRL = 0x9002,
-       RX_ALARM_STAT = 0x9003,
-       TX_ALARM_STAT = 0x9004,
-       LASI_STAT = 0x9005
-};
-
 /* PHY loopback direction */
 enum {
        PHY_LOOPBACK_TX = 1,
@@ -583,11 +563,12 @@ struct cphy_ops {
        int (*get_link_status)(struct cphy *phy, int *link_ok, int *speed,
                               int *duplex, int *fc);
        int (*power_down)(struct cphy *phy, int enable);
+
+       u32 mmds;
 };
 
 /* A PHY instance */
 struct cphy {
-       u8 addr;                        /* PHY address */
        u8 modtype;                     /* PHY module type */
        short priv;                     /* scratch pad */
        unsigned int caps;              /* PHY capabilities */
@@ -595,23 +576,23 @@ struct cphy {
        const char *desc;               /* PHY description */
        unsigned long fifo_errors;      /* FIFO over/under-flows */
        const struct cphy_ops *ops;     /* PHY operations */
-       int (*mdio_read)(struct adapter *adapter, int phy_addr, int mmd_addr,
-                        int reg_addr, unsigned int *val);
-       int (*mdio_write)(struct adapter *adapter, int phy_addr, int mmd_addr,
-                         int reg_addr, unsigned int val);
+       struct mdio_if_info mdio;
 };
 
 /* Convenience MDIO read/write wrappers */
-static inline int mdio_read(struct cphy *phy, int mmd, int reg,
-                           unsigned int *valp)
+static inline int t3_mdio_read(struct cphy *phy, int mmd, int reg,
+                              unsigned int *valp)
 {
-       return phy->mdio_read(phy->adapter, phy->addr, mmd, reg, valp);
+       int rc = phy->mdio.mdio_read(phy->mdio.dev, phy->mdio.prtad, mmd, reg);
+       *valp = (rc >= 0) ? rc : -1;
+       return (rc >= 0) ? 0 : rc;
 }
 
-static inline int mdio_write(struct cphy *phy, int mmd, int reg,
-                            unsigned int val)
+static inline int t3_mdio_write(struct cphy *phy, int mmd, int reg,
+                               unsigned int val)
 {
-       return phy->mdio_write(phy->adapter, phy->addr, mmd, reg, val);
+       return phy->mdio.mdio_write(phy->mdio.dev, phy->mdio.prtad, mmd,
+                                   reg, val);
 }
 
 /* Convenience initializer */
@@ -620,14 +601,16 @@ static inline void cphy_init(struct cphy *phy, struct adapter *adapter,
                             const struct mdio_ops *mdio_ops,
                              unsigned int caps, const char *desc)
 {
-       phy->addr = phy_addr;
        phy->caps = caps;
        phy->adapter = adapter;
        phy->desc = desc;
        phy->ops = phy_ops;
        if (mdio_ops) {
-               phy->mdio_read = mdio_ops->read;
-               phy->mdio_write = mdio_ops->write;
+               phy->mdio.prtad = phy_addr;
+               phy->mdio.mmds = phy_ops->mmds;
+               phy->mdio.mode_support = mdio_ops->mode_support;
+               phy->mdio.mdio_read = mdio_ops->read;
+               phy->mdio.mdio_write = mdio_ops->write;
        }
 }
 
@@ -819,8 +802,12 @@ int t3_ael1006_phy_prep(struct cphy *phy, struct adapter *adapter,
                        int phy_addr, const struct mdio_ops *mdio_ops);
 int t3_ael2005_phy_prep(struct cphy *phy, struct adapter *adapter,
                        int phy_addr, const struct mdio_ops *mdio_ops);
+int t3_ael2020_phy_prep(struct cphy *phy, struct adapter *adapter,
+                       int phy_addr, const struct mdio_ops *mdio_ops);
 int t3_qt2045_phy_prep(struct cphy *phy, struct adapter *adapter, int phy_addr,
                       const struct mdio_ops *mdio_ops);
 int t3_xaui_direct_phy_prep(struct cphy *phy, struct adapter *adapter,
                            int phy_addr, const struct mdio_ops *mdio_ops);
+int t3_aq100x_phy_prep(struct cphy *phy, struct adapter *adapter,
+                           int phy_addr, const struct mdio_ops *mdio_ops);
 #endif                         /* __CHELSIO_COMMON_H */
index 17858b9a583050e6c7aefb2055fcd6740db9a858..538dda4422dca039b01715e8ca10892af4954ea1 100644 (file)
@@ -37,7 +37,7 @@
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/if_vlan.h>
-#include <linux/mii.h>
+#include <linux/mdio.h>
 #include <linux/sockios.h>
 #include <linux/workqueue.h>
 #include <linux/proc_fs.h>
@@ -91,6 +91,8 @@ static const struct pci_device_id cxgb3_pci_tbl[] = {
        CH_DEVICE(0x31, 3),     /* T3B20 */
        CH_DEVICE(0x32, 1),     /* T3B02 */
        CH_DEVICE(0x35, 6),     /* T3C20-derived T3C10 */
+       CH_DEVICE(0x36, 3),     /* S320E-CR */
+       CH_DEVICE(0x37, 7),     /* N320E-G2 */
        {0,}
 };
 
@@ -431,40 +433,78 @@ static int init_tp_parity(struct adapter *adap)
        for (i = 0; i < 16; i++) {
                struct cpl_smt_write_req *req;
 
-               skb = alloc_skb(sizeof(*req), GFP_KERNEL | __GFP_NOFAIL);
+               skb = alloc_skb(sizeof(*req), GFP_KERNEL);
+               if (!skb)
+                       skb = adap->nofail_skb;
+               if (!skb)
+                       goto alloc_skb_fail;
+
                req = (struct cpl_smt_write_req *)__skb_put(skb, sizeof(*req));
                memset(req, 0, sizeof(*req));
                req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
                OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_SMT_WRITE_REQ, i));
                req->iff = i;
                t3_mgmt_tx(adap, skb);
+               if (skb == adap->nofail_skb) {
+                       await_mgmt_replies(adap, cnt, i + 1);
+                       adap->nofail_skb = alloc_skb(sizeof(*greq), GFP_KERNEL);
+                       if (!adap->nofail_skb)
+                               goto alloc_skb_fail;
+               }
        }
 
        for (i = 0; i < 2048; i++) {
                struct cpl_l2t_write_req *req;
 
-               skb = alloc_skb(sizeof(*req), GFP_KERNEL | __GFP_NOFAIL);
+               skb = alloc_skb(sizeof(*req), GFP_KERNEL);
+               if (!skb)
+                       skb = adap->nofail_skb;
+               if (!skb)
+                       goto alloc_skb_fail;
+
                req = (struct cpl_l2t_write_req *)__skb_put(skb, sizeof(*req));
                memset(req, 0, sizeof(*req));
                req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
                OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_L2T_WRITE_REQ, i));
                req->params = htonl(V_L2T_W_IDX(i));
                t3_mgmt_tx(adap, skb);
+               if (skb == adap->nofail_skb) {
+                       await_mgmt_replies(adap, cnt, 16 + i + 1);
+                       adap->nofail_skb = alloc_skb(sizeof(*greq), GFP_KERNEL);
+                       if (!adap->nofail_skb)
+                               goto alloc_skb_fail;
+               }
        }
 
        for (i = 0; i < 2048; i++) {
                struct cpl_rte_write_req *req;
 
-               skb = alloc_skb(sizeof(*req), GFP_KERNEL | __GFP_NOFAIL);
+               skb = alloc_skb(sizeof(*req), GFP_KERNEL);
+               if (!skb)
+                       skb = adap->nofail_skb;
+               if (!skb)
+                       goto alloc_skb_fail;
+
                req = (struct cpl_rte_write_req *)__skb_put(skb, sizeof(*req));
                memset(req, 0, sizeof(*req));
                req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
                OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_RTE_WRITE_REQ, i));
                req->l2t_idx = htonl(V_L2T_W_IDX(i));
                t3_mgmt_tx(adap, skb);
+               if (skb == adap->nofail_skb) {
+                       await_mgmt_replies(adap, cnt, 16 + 2048 + i + 1);
+                       adap->nofail_skb = alloc_skb(sizeof(*greq), GFP_KERNEL);
+                       if (!adap->nofail_skb)
+                               goto alloc_skb_fail;
+               }
        }
 
-       skb = alloc_skb(sizeof(*greq), GFP_KERNEL | __GFP_NOFAIL);
+       skb = alloc_skb(sizeof(*greq), GFP_KERNEL);
+       if (!skb)
+               skb = adap->nofail_skb;
+       if (!skb)
+               goto alloc_skb_fail;
+
        greq = (struct cpl_set_tcb_field *)__skb_put(skb, sizeof(*greq));
        memset(greq, 0, sizeof(*greq));
        greq->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
@@ -473,8 +513,17 @@ static int init_tp_parity(struct adapter *adap)
        t3_mgmt_tx(adap, skb);
 
        i = await_mgmt_replies(adap, cnt, 16 + 2048 + 2048 + 1);
+       if (skb == adap->nofail_skb) {
+               i = await_mgmt_replies(adap, cnt, 16 + 2048 + 2048 + 1);
+               adap->nofail_skb = alloc_skb(sizeof(*greq), GFP_KERNEL);
+       }
+
        t3_tp_set_offload_mode(adap, 0);
        return i;
+
+alloc_skb_fail:
+       t3_tp_set_offload_mode(adap, 0);
+       return -ENOMEM;
 }
 
 /**
@@ -869,7 +918,12 @@ static int send_pktsched_cmd(struct adapter *adap, int sched, int qidx, int lo,
        struct mngt_pktsched_wr *req;
        int ret;
 
-       skb = alloc_skb(sizeof(*req), GFP_KERNEL | __GFP_NOFAIL);
+       skb = alloc_skb(sizeof(*req), GFP_KERNEL);
+       if (!skb)
+               skb = adap->nofail_skb;
+       if (!skb)
+               return -ENOMEM;
+
        req = (struct mngt_pktsched_wr *)skb_put(skb, sizeof(*req));
        req->wr_hi = htonl(V_WR_OP(FW_WROPCODE_MNGT));
        req->mngt_opcode = FW_MNGTOPCODE_PKTSCHED_SET;
@@ -879,6 +933,12 @@ static int send_pktsched_cmd(struct adapter *adap, int sched, int qidx, int lo,
        req->max = hi;
        req->binding = port;
        ret = t3_mgmt_tx(adap, skb);
+       if (skb == adap->nofail_skb) {
+               adap->nofail_skb = alloc_skb(sizeof(struct cpl_set_tcb_field),
+                                            GFP_KERNEL);
+               if (!adap->nofail_skb)
+                       ret = -ENOMEM;
+       }
 
        return ret;
 }
@@ -1593,7 +1653,7 @@ static int get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
        }
 
        cmd->port = (cmd->supported & SUPPORTED_TP) ? PORT_TP : PORT_FIBRE;
-       cmd->phy_address = p->phy.addr;
+       cmd->phy_address = p->phy.mdio.prtad;
        cmd->transceiver = XCVR_EXTERNAL;
        cmd->autoneg = p->link_config.autoneg;
        cmd->maxtxpkt = 0;
@@ -2308,70 +2368,25 @@ static int cxgb_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
        struct mii_ioctl_data *data = if_mii(req);
        struct port_info *pi = netdev_priv(dev);
        struct adapter *adapter = pi->adapter;
-       int ret, mmd;
 
        switch (cmd) {
-       case SIOCGMIIPHY:
-               data->phy_id = pi->phy.addr;
+       case SIOCGMIIREG:
+       case SIOCSMIIREG:
+               /* Convert phy_id from older PRTAD/DEVAD format */
+               if (is_10G(adapter) &&
+                   !mdio_phy_id_is_c45(data->phy_id) &&
+                   (data->phy_id & 0x1f00) &&
+                   !(data->phy_id & 0xe0e0))
+                       data->phy_id = mdio_phy_id_c45(data->phy_id >> 8,
+                                                      data->phy_id & 0x1f);
                /* FALLTHRU */
-       case SIOCGMIIREG:{
-               u32 val;
-               struct cphy *phy = &pi->phy;
-
-               if (!phy->mdio_read)
-                       return -EOPNOTSUPP;
-               if (is_10G(adapter)) {
-                       mmd = data->phy_id >> 8;
-                       if (!mmd)
-                               mmd = MDIO_DEV_PCS;
-                       else if (mmd > MDIO_DEV_VEND2)
-                               return -EINVAL;
-
-                       ret =
-                               phy->mdio_read(adapter, data->phy_id & 0x1f,
-                                               mmd, data->reg_num, &val);
-               } else
-                       ret =
-                               phy->mdio_read(adapter, data->phy_id & 0x1f,
-                                               0, data->reg_num & 0x1f,
-                                               &val);
-               if (!ret)
-                       data->val_out = val;
-               break;
-       }
-       case SIOCSMIIREG:{
-               struct cphy *phy = &pi->phy;
-
-               if (!capable(CAP_NET_ADMIN))
-                       return -EPERM;
-               if (!phy->mdio_write)
-                       return -EOPNOTSUPP;
-               if (is_10G(adapter)) {
-                       mmd = data->phy_id >> 8;
-                       if (!mmd)
-                               mmd = MDIO_DEV_PCS;
-                       else if (mmd > MDIO_DEV_VEND2)
-                               return -EINVAL;
-
-                       ret =
-                               phy->mdio_write(adapter,
-                                               data->phy_id & 0x1f, mmd,
-                                               data->reg_num,
-                                               data->val_in);
-               } else
-                       ret =
-                               phy->mdio_write(adapter,
-                                               data->phy_id & 0x1f, 0,
-                                               data->reg_num & 0x1f,
-                                               data->val_in);
-               break;
-       }
+       case SIOCGMIIPHY:
+               return mdio_mii_ioctl(&pi->phy.mdio, data, cmd);
        case SIOCCHIOCTL:
                return cxgb_extension_ioctl(dev, req->ifr_data);
        default:
                return -EOPNOTSUPP;
        }
-       return ret;
 }
 
 static int cxgb_change_mtu(struct net_device *dev, int new_mtu)
@@ -3063,6 +3078,14 @@ static int __devinit init_one(struct pci_dev *pdev,
                goto out_disable_device;
        }
 
+       adapter->nofail_skb =
+               alloc_skb(sizeof(struct cpl_set_tcb_field), GFP_KERNEL);
+       if (!adapter->nofail_skb) {
+               dev_err(&pdev->dev, "cannot allocate nofail buffer\n");
+               err = -ENOMEM;
+               goto out_free_adapter;
+       }
+
        adapter->regs = ioremap_nocache(mmio_start, mmio_len);
        if (!adapter->regs) {
                dev_err(&pdev->dev, "cannot map device registers\n");
@@ -3106,7 +3129,6 @@ static int __devinit init_one(struct pci_dev *pdev,
                netdev->mem_start = mmio_start;
                netdev->mem_end = mmio_start + mmio_len - 1;
                netdev->features |= NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO;
-               netdev->features |= NETIF_F_LLTX;
                netdev->features |= NETIF_F_GRO;
                if (pci_using_dac)
                        netdev->features |= NETIF_F_HIGHDMA;
@@ -3220,6 +3242,8 @@ static void __devexit remove_one(struct pci_dev *pdev)
                                free_netdev(adapter->port[i]);
 
                iounmap(adapter->regs);
+               if (adapter->nofail_skb)
+                       kfree_skb(adapter->nofail_skb);
                kfree(adapter);
                pci_release_regions(pdev);
                pci_disable_device(pdev);
index 620d80be6aacb1d3806d3f42f786c9f5b52bc6a3..f9f54b57b28ca9af177f00b52923f607f2979f64 100644 (file)
@@ -566,13 +566,31 @@ static void t3_process_tid_release_list(struct work_struct *work)
                spin_unlock_bh(&td->tid_release_lock);
 
                skb = alloc_skb(sizeof(struct cpl_tid_release),
-                               GFP_KERNEL | __GFP_NOFAIL);
+                               GFP_KERNEL);
+               if (!skb)
+                       skb = td->nofail_skb;
+               if (!skb) {
+                       spin_lock_bh(&td->tid_release_lock);
+                       p->ctx = (void *)td->tid_release_list;
+                       td->tid_release_list = (struct t3c_tid_entry *)p;
+                       break;
+               }
                mk_tid_release(skb, p - td->tid_maps.tid_tab);
                cxgb3_ofld_send(tdev, skb);
                p->ctx = NULL;
+               if (skb == td->nofail_skb)
+                       td->nofail_skb =
+                               alloc_skb(sizeof(struct cpl_tid_release),
+                                       GFP_KERNEL);
                spin_lock_bh(&td->tid_release_lock);
        }
+       td->release_list_incomplete = (td->tid_release_list == NULL) ? 0 : 1;
        spin_unlock_bh(&td->tid_release_lock);
+
+       if (!td->nofail_skb)
+               td->nofail_skb =
+                       alloc_skb(sizeof(struct cpl_tid_release),
+                               GFP_KERNEL);
 }
 
 /* use ctx as a next pointer in the tid release list */
@@ -585,7 +603,7 @@ void cxgb3_queue_tid_release(struct t3cdev *tdev, unsigned int tid)
        p->ctx = (void *)td->tid_release_list;
        p->client = NULL;
        td->tid_release_list = p;
-       if (!p->ctx)
+       if (!p->ctx || td->release_list_incomplete)
                schedule_work(&td->tid_release_task);
        spin_unlock_bh(&td->tid_release_lock);
 }
@@ -1274,6 +1292,9 @@ int cxgb3_offload_activate(struct adapter *adapter)
        if (list_empty(&adapter_list))
                register_netevent_notifier(&nb);
 
+       t->nofail_skb = alloc_skb(sizeof(struct cpl_tid_release), GFP_KERNEL);
+       t->release_list_incomplete = 0;
+
        add_adapter(adapter);
        return 0;
 
@@ -1298,6 +1319,8 @@ void cxgb3_offload_deactivate(struct adapter *adapter)
        T3C_DATA(tdev) = NULL;
        t3_free_l2t(L2DATA(tdev));
        L2DATA(tdev) = NULL;
+       if (t->nofail_skb)
+               kfree_skb(t->nofail_skb);
        kfree(t);
 }
 
index a8e8e5fcdf84d55c5daa3aafd0f4d1081cab4f5a..55945f422aec0f70e2f608d1dd55cc23375003ae 100644 (file)
@@ -191,6 +191,9 @@ struct t3c_data {
        struct t3c_tid_entry *tid_release_list;
        spinlock_t tid_release_lock;
        struct work_struct tid_release_task;
+
+       struct sk_buff *nofail_skb;
+       unsigned int release_list_incomplete;
 };
 
 /*
index b3ee2bc1a005158610b4af65470e81575c61f04e..29c79eb43beb7041462f71b309339bc2b3158c93 100644 (file)
@@ -653,7 +653,8 @@ static void t3_reset_qset(struct sge_qset *q)
        q->txq_stopped = 0;
        q->tx_reclaim_timer.function = NULL; /* for t3_stop_sge_timers() */
        q->rx_reclaim_timer.function = NULL;
-       q->lro_frag_tbl.nr_frags = q->lro_frag_tbl.len = 0;
+       q->nomem = 0;
+       napi_free_frags(&q->napi);
 }
 
 
@@ -1239,7 +1240,6 @@ int t3_eth_xmit(struct sk_buff *skb, struct net_device *dev)
        q = &qs->txq[TXQ_ETH];
        txq = netdev_get_tx_queue(dev, qidx);
 
-       spin_lock(&q->lock);
        reclaim_completed_tx(adap, q, TX_RECLAIM_CHUNK);
 
        credits = q->size - q->in_use;
@@ -1250,7 +1250,6 @@ int t3_eth_xmit(struct sk_buff *skb, struct net_device *dev)
                dev_err(&adap->pdev->dev,
                        "%s: Tx ring %u full while queue awake!\n",
                        dev->name, q->cntxt_id & 7);
-               spin_unlock(&q->lock);
                return NETDEV_TX_BUSY;
        }
 
@@ -1284,9 +1283,6 @@ int t3_eth_xmit(struct sk_buff *skb, struct net_device *dev)
        if (vlan_tx_tag_present(skb) && pi->vlan_grp)
                qs->port_stats[SGE_PSTAT_VLANINS]++;
 
-       dev->trans_start = jiffies;
-       spin_unlock(&q->lock);
-
        /*
         * We do not use Tx completion interrupts to free DMAd Tx packets.
         * This is good for performamce but means that we rely on new Tx
@@ -2073,20 +2069,19 @@ static void lro_add_page(struct adapter *adap, struct sge_qset *qs,
                         struct sge_fl *fl, int len, int complete)
 {
        struct rx_sw_desc *sd = &fl->sdesc[fl->cidx];
+       struct sk_buff *skb = NULL;
        struct cpl_rx_pkt *cpl;
-       struct skb_frag_struct *rx_frag = qs->lro_frag_tbl.frags;
-       int nr_frags = qs->lro_frag_tbl.nr_frags;
-       int frag_len = qs->lro_frag_tbl.len;
+       struct skb_frag_struct *rx_frag;
+       int nr_frags;
        int offset = 0;
 
-       if (!nr_frags) {
-               offset = 2 + sizeof(struct cpl_rx_pkt);
-               qs->lro_va = cpl = sd->pg_chunk.va + 2;
+       if (!qs->nomem) {
+               skb = napi_get_frags(&qs->napi);
+               qs->nomem = !skb;
        }
 
        fl->credits--;
 
-       len -= offset;
        pci_dma_sync_single_for_cpu(adap->pdev,
                                    pci_unmap_addr(sd, dma_addr),
                                    fl->buf_size - SGE_PG_RSVD,
@@ -2099,21 +2094,38 @@ static void lro_add_page(struct adapter *adap, struct sge_qset *qs,
                               fl->alloc_size,
                               PCI_DMA_FROMDEVICE);
 
+       if (!skb) {
+               put_page(sd->pg_chunk.page);
+               if (complete)
+                       qs->nomem = 0;
+               return;
+       }
+
+       rx_frag = skb_shinfo(skb)->frags;
+       nr_frags = skb_shinfo(skb)->nr_frags;
+
+       if (!nr_frags) {
+               offset = 2 + sizeof(struct cpl_rx_pkt);
+               qs->lro_va = sd->pg_chunk.va + 2;
+       }
+       len -= offset;
+
        prefetch(qs->lro_va);
 
        rx_frag += nr_frags;
        rx_frag->page = sd->pg_chunk.page;
        rx_frag->page_offset = sd->pg_chunk.offset + offset;
        rx_frag->size = len;
-       frag_len += len;
-       qs->lro_frag_tbl.nr_frags++;
-       qs->lro_frag_tbl.len = frag_len;
 
+       skb->len += len;
+       skb->data_len += len;
+       skb->truesize += len;
+       skb_shinfo(skb)->nr_frags++;
 
        if (!complete)
                return;
 
-       qs->lro_frag_tbl.ip_summed = CHECKSUM_UNNECESSARY;
+       skb->ip_summed = CHECKSUM_UNNECESSARY;
        cpl = qs->lro_va;
 
        if (unlikely(cpl->vlan_valid)) {
@@ -2122,15 +2134,11 @@ static void lro_add_page(struct adapter *adap, struct sge_qset *qs,
                struct vlan_group *grp = pi->vlan_grp;
 
                if (likely(grp != NULL)) {
-                       vlan_gro_frags(&qs->napi, grp, ntohs(cpl->vlan),
-                                      &qs->lro_frag_tbl);
-                       goto out;
+                       vlan_gro_frags(&qs->napi, grp, ntohs(cpl->vlan));
+                       return;
                }
        }
-       napi_gro_frags(&qs->napi, &qs->lro_frag_tbl);
-
-out:
-       qs->lro_frag_tbl.nr_frags = qs->lro_frag_tbl.len = 0;
+       napi_gro_frags(&qs->napi);
 }
 
 /**
@@ -2299,8 +2307,6 @@ no_mem:
                        if (fl->use_pages) {
                                void *addr = fl->sdesc[fl->cidx].pg_chunk.va;
 
-                               prefetch(&qs->lro_frag_tbl);
-
                                prefetch(addr);
 #if L1_CACHE_BYTES < 128
                                prefetch(addr + L1_CACHE_BYTES);
@@ -2846,11 +2852,12 @@ static void sge_timer_tx(unsigned long data)
        unsigned int tbd[SGE_TXQ_PER_SET] = {0, 0};
        unsigned long next_period;
 
-       if (spin_trylock(&qs->txq[TXQ_ETH].lock)) {
-               tbd[TXQ_ETH] = reclaim_completed_tx(adap, &qs->txq[TXQ_ETH],
-                                                   TX_RECLAIM_TIMER_CHUNK);
-               spin_unlock(&qs->txq[TXQ_ETH].lock);
+       if (__netif_tx_trylock(qs->tx_q)) {
+                tbd[TXQ_ETH] = reclaim_completed_tx(adap, &qs->txq[TXQ_ETH],
+                                                     TX_RECLAIM_TIMER_CHUNK);
+               __netif_tx_unlock(qs->tx_q);
        }
+
        if (spin_trylock(&qs->txq[TXQ_OFLD].lock)) {
                tbd[TXQ_OFLD] = reclaim_completed_tx(adap, &qs->txq[TXQ_OFLD],
                                                     TX_RECLAIM_TIMER_CHUNK);
@@ -2858,8 +2865,8 @@ static void sge_timer_tx(unsigned long data)
        }
 
        next_period = TX_RECLAIM_PERIOD >>
-                     (max(tbd[TXQ_ETH], tbd[TXQ_OFLD]) /
-                      TX_RECLAIM_TIMER_CHUNK);
+                      (max(tbd[TXQ_ETH], tbd[TXQ_OFLD]) /
+                      TX_RECLAIM_TIMER_CHUNK);
        mod_timer(&qs->tx_reclaim_timer, jiffies + next_period);
 }
 
index 4950d5d789ae8c66e53ec4061789303e674a1923..870d44992c70819308a85580f0607e30daabea71 100644 (file)
@@ -204,35 +204,33 @@ static void mi1_init(struct adapter *adap, const struct adapter_info *ai)
 /*
  * MI1 read/write operations for clause 22 PHYs.
  */
-static int t3_mi1_read(struct adapter *adapter, int phy_addr, int mmd_addr,
-                      int reg_addr, unsigned int *valp)
+static int t3_mi1_read(struct net_device *dev, int phy_addr, int mmd_addr,
+                      u16 reg_addr)
 {
+       struct port_info *pi = netdev_priv(dev);
+       struct adapter *adapter = pi->adapter;
        int ret;
        u32 addr = V_REGADDR(reg_addr) | V_PHYADDR(phy_addr);
 
-       if (mmd_addr)
-               return -EINVAL;
-
        mutex_lock(&adapter->mdio_lock);
        t3_set_reg_field(adapter, A_MI1_CFG, V_ST(M_ST), V_ST(1));
        t3_write_reg(adapter, A_MI1_ADDR, addr);
        t3_write_reg(adapter, A_MI1_OP, V_MDI_OP(2));
        ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0, MDIO_ATTEMPTS, 10);
        if (!ret)
-               *valp = t3_read_reg(adapter, A_MI1_DATA);
+               ret = t3_read_reg(adapter, A_MI1_DATA);
        mutex_unlock(&adapter->mdio_lock);
        return ret;
 }
 
-static int t3_mi1_write(struct adapter *adapter, int phy_addr, int mmd_addr,
-                    int reg_addr, unsigned int val)
+static int t3_mi1_write(struct net_device *dev, int phy_addr, int mmd_addr,
+                       u16 reg_addr, u16 val)
 {
+       struct port_info *pi = netdev_priv(dev);
+       struct adapter *adapter = pi->adapter;
        int ret;
        u32 addr = V_REGADDR(reg_addr) | V_PHYADDR(phy_addr);
 
-       if (mmd_addr)
-               return -EINVAL;
-
        mutex_lock(&adapter->mdio_lock);
        t3_set_reg_field(adapter, A_MI1_CFG, V_ST(M_ST), V_ST(1));
        t3_write_reg(adapter, A_MI1_ADDR, addr);
@@ -244,8 +242,9 @@ static int t3_mi1_write(struct adapter *adapter, int phy_addr, int mmd_addr,
 }
 
 static const struct mdio_ops mi1_mdio_ops = {
-       t3_mi1_read,
-       t3_mi1_write
+       .read = t3_mi1_read,
+       .write = t3_mi1_write,
+       .mode_support = MDIO_SUPPORTS_C22
 };
 
 /*
@@ -268,9 +267,11 @@ static int mi1_wr_addr(struct adapter *adapter, int phy_addr, int mmd_addr,
 /*
  * MI1 read/write operations for indirect-addressed PHYs.
  */
-static int mi1_ext_read(struct adapter *adapter, int phy_addr, int mmd_addr,
-                       int reg_addr, unsigned int *valp)
+static int mi1_ext_read(struct net_device *dev, int phy_addr, int mmd_addr,
+                       u16 reg_addr)
 {
+       struct port_info *pi = netdev_priv(dev);
+       struct adapter *adapter = pi->adapter;
        int ret;
 
        mutex_lock(&adapter->mdio_lock);
@@ -280,15 +281,17 @@ static int mi1_ext_read(struct adapter *adapter, int phy_addr, int mmd_addr,
                ret = t3_wait_op_done(adapter, A_MI1_OP, F_BUSY, 0,
                                      MDIO_ATTEMPTS, 10);
                if (!ret)
-                       *valp = t3_read_reg(adapter, A_MI1_DATA);
+                       ret = t3_read_reg(adapter, A_MI1_DATA);
        }
        mutex_unlock(&adapter->mdio_lock);
        return ret;
 }
 
-static int mi1_ext_write(struct adapter *adapter, int phy_addr, int mmd_addr,
-                        int reg_addr, unsigned int val)
+static int mi1_ext_write(struct net_device *dev, int phy_addr, int mmd_addr,
+                        u16 reg_addr, u16 val)
 {
+       struct port_info *pi = netdev_priv(dev);
+       struct adapter *adapter = pi->adapter;
        int ret;
 
        mutex_lock(&adapter->mdio_lock);
@@ -304,8 +307,9 @@ static int mi1_ext_write(struct adapter *adapter, int phy_addr, int mmd_addr,
 }
 
 static const struct mdio_ops mi1_mdio_ext_ops = {
-       mi1_ext_read,
-       mi1_ext_write
+       .read = mi1_ext_read,
+       .write = mi1_ext_write,
+       .mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22
 };
 
 /**
@@ -325,10 +329,10 @@ int t3_mdio_change_bits(struct cphy *phy, int mmd, int reg, unsigned int clear,
        int ret;
        unsigned int val;
 
-       ret = mdio_read(phy, mmd, reg, &val);
+       ret = t3_mdio_read(phy, mmd, reg, &val);
        if (!ret) {
                val &= ~clear;
-               ret = mdio_write(phy, mmd, reg, val | set);
+               ret = t3_mdio_write(phy, mmd, reg, val | set);
        }
        return ret;
 }
@@ -348,15 +352,16 @@ int t3_phy_reset(struct cphy *phy, int mmd, int wait)
        int err;
        unsigned int ctl;
 
-       err = t3_mdio_change_bits(phy, mmd, MII_BMCR, BMCR_PDOWN, BMCR_RESET);
+       err = t3_mdio_change_bits(phy, mmd, MDIO_CTRL1, MDIO_CTRL1_LPOWER,
+                                 MDIO_CTRL1_RESET);
        if (err || !wait)
                return err;
 
        do {
-               err = mdio_read(phy, mmd, MII_BMCR, &ctl);
+               err = t3_mdio_read(phy, mmd, MDIO_CTRL1, &ctl);
                if (err)
                        return err;
-               ctl &= BMCR_RESET;
+               ctl &= MDIO_CTRL1_RESET;
                if (ctl)
                        msleep(1);
        } while (ctl && --wait);
@@ -377,7 +382,7 @@ int t3_phy_advertise(struct cphy *phy, unsigned int advert)
        int err;
        unsigned int val = 0;
 
-       err = mdio_read(phy, 0, MII_CTRL1000, &val);
+       err = t3_mdio_read(phy, MDIO_DEVAD_NONE, MII_CTRL1000, &val);
        if (err)
                return err;
 
@@ -387,7 +392,7 @@ int t3_phy_advertise(struct cphy *phy, unsigned int advert)
        if (advert & ADVERTISED_1000baseT_Full)
                val |= ADVERTISE_1000FULL;
 
-       err = mdio_write(phy, 0, MII_CTRL1000, val);
+       err = t3_mdio_write(phy, MDIO_DEVAD_NONE, MII_CTRL1000, val);
        if (err)
                return err;
 
@@ -404,7 +409,7 @@ int t3_phy_advertise(struct cphy *phy, unsigned int advert)
                val |= ADVERTISE_PAUSE_CAP;
        if (advert & ADVERTISED_Asym_Pause)
                val |= ADVERTISE_PAUSE_ASYM;
-       return mdio_write(phy, 0, MII_ADVERTISE, val);
+       return t3_mdio_write(phy, MDIO_DEVAD_NONE, MII_ADVERTISE, val);
 }
 
 /**
@@ -427,7 +432,7 @@ int t3_phy_advertise_fiber(struct cphy *phy, unsigned int advert)
                val |= ADVERTISE_1000XPAUSE;
        if (advert & ADVERTISED_Asym_Pause)
                val |= ADVERTISE_1000XPSE_ASYM;
-       return mdio_write(phy, 0, MII_ADVERTISE, val);
+       return t3_mdio_write(phy, MDIO_DEVAD_NONE, MII_ADVERTISE, val);
 }
 
 /**
@@ -444,7 +449,7 @@ int t3_set_phy_speed_duplex(struct cphy *phy, int speed, int duplex)
        int err;
        unsigned int ctl;
 
-       err = mdio_read(phy, 0, MII_BMCR, &ctl);
+       err = t3_mdio_read(phy, MDIO_DEVAD_NONE, MII_BMCR, &ctl);
        if (err)
                return err;
 
@@ -462,34 +467,36 @@ int t3_set_phy_speed_duplex(struct cphy *phy, int speed, int duplex)
        }
        if (ctl & BMCR_SPEED1000) /* auto-negotiation required for GigE */
                ctl |= BMCR_ANENABLE;
-       return mdio_write(phy, 0, MII_BMCR, ctl);
+       return t3_mdio_write(phy, MDIO_DEVAD_NONE, MII_BMCR, ctl);
 }
 
 int t3_phy_lasi_intr_enable(struct cphy *phy)
 {
-       return mdio_write(phy, MDIO_DEV_PMA_PMD, LASI_CTRL, 1);
+       return t3_mdio_write(phy, MDIO_MMD_PMAPMD, MDIO_PMA_LASI_CTRL,
+                            MDIO_PMA_LASI_LSALARM);
 }
 
 int t3_phy_lasi_intr_disable(struct cphy *phy)
 {
-       return mdio_write(phy, MDIO_DEV_PMA_PMD, LASI_CTRL, 0);
+       return t3_mdio_write(phy, MDIO_MMD_PMAPMD, MDIO_PMA_LASI_CTRL, 0);
 }
 
 int t3_phy_lasi_intr_clear(struct cphy *phy)
 {
        u32 val;
 
-       return mdio_read(phy, MDIO_DEV_PMA_PMD, LASI_STAT, &val);
+       return t3_mdio_read(phy, MDIO_MMD_PMAPMD, MDIO_PMA_LASI_STAT, &val);
 }
 
 int t3_phy_lasi_intr_handler(struct cphy *phy)
 {
        unsigned int status;
-       int err = mdio_read(phy, MDIO_DEV_PMA_PMD, LASI_STAT, &status);
+       int err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, MDIO_PMA_LASI_STAT,
+                              &status);
 
        if (err)
                return err;
-       return (status & 1) ?  cphy_cause_link_change : 0;
+       return (status & MDIO_PMA_LASI_LSALARM) ? cphy_cause_link_change : 0;
 }
 
 static const struct adapter_info t3_adap_info[] = {
@@ -519,6 +526,11 @@ static const struct adapter_info t3_adap_info[] = {
         F_GPIO10_OEN | F_GPIO1_OUT_VAL | F_GPIO6_OUT_VAL | F_GPIO10_OUT_VAL,
         { S_GPIO9 }, SUPPORTED_10000baseT_Full | SUPPORTED_AUI,
         &mi1_mdio_ext_ops, "Chelsio T310" },
+       {1, 0, 0,
+        F_GPIO1_OEN | F_GPIO6_OEN | F_GPIO7_OEN |
+        F_GPIO1_OUT_VAL | F_GPIO6_OUT_VAL,
+        { S_GPIO9 }, SUPPORTED_10000baseT_Full | SUPPORTED_AUI,
+        &mi1_mdio_ext_ops, "Chelsio N320E-G2" },
 };
 
 /*
@@ -545,6 +557,8 @@ static const struct port_type_info port_types[] = {
        { t3_qt2045_phy_prep },
        { t3_ael1006_phy_prep },
        { NULL },
+       { t3_aq100x_phy_prep },
+       { t3_ael2020_phy_prep },
 };
 
 #define VPD_ENTRY(name, len) \
@@ -3864,6 +3878,7 @@ int t3_prep_adapter(struct adapter *adapter, const struct adapter_info *ai,
                        return -EINVAL;
                }
 
+               p->phy.mdio.dev = adapter->port[i];
                ret = pti->phy_prep(&p->phy, adapter, ai->phy_base_addr + j,
                                    ai->mdio_ops);
                if (ret)
@@ -3923,7 +3938,7 @@ int t3_replay_prep_adapter(struct adapter *adapter)
                        ;
 
                pti = &port_types[adapter->params.vpd.port_type[j]];
-               ret = pti->phy_prep(&p->phy, adapter, p->phy.addr, NULL);
+               ret = pti->phy_prep(&p->phy, adapter, p->phy.mdio.prtad, NULL);
                if (ret)
                        return ret;
                p->phy.ops->power_down(&p->phy, 1);
index 7bf963ec55483792e3ac4edfdd042870d14afeed..9d0bd9dd9ab1344155479a7ea2d42f788c8a83b3 100644 (file)
 #define DRV_DESC "Chelsio T3 Network Driver"
 #define DRV_NAME "cxgb3"
 /* Driver version */
-#define DRV_VERSION "1.1.2-ko"
+#define DRV_VERSION "1.1.3-ko"
 
 /* Firmware version */
 #define FW_VERSION_MAJOR 7
-#define FW_VERSION_MINOR 1
+#define FW_VERSION_MINOR 4
 #define FW_VERSION_MICRO 0
 #endif                         /* __CHELSIO_VERSION_H */
index d07130971b8f4bba321784ce079d51c54e905ec4..4f9a1c2724f4eb175bdb631f8ec1cc790cf0ec5f 100644 (file)
@@ -91,17 +91,18 @@ enum {
  */
 static int vsc8211_reset(struct cphy *cphy, int wait)
 {
-       return t3_phy_reset(cphy, 0, 0);
+       return t3_phy_reset(cphy, MDIO_DEVAD_NONE, 0);
 }
 
 static int vsc8211_intr_enable(struct cphy *cphy)
 {
-       return mdio_write(cphy, 0, VSC8211_INTR_ENABLE, INTR_MASK);
+       return t3_mdio_write(cphy, MDIO_DEVAD_NONE, VSC8211_INTR_ENABLE,
+                            INTR_MASK);
 }
 
 static int vsc8211_intr_disable(struct cphy *cphy)
 {
-       return mdio_write(cphy, 0, VSC8211_INTR_ENABLE, 0);
+       return t3_mdio_write(cphy, MDIO_DEVAD_NONE, VSC8211_INTR_ENABLE, 0);
 }
 
 static int vsc8211_intr_clear(struct cphy *cphy)
@@ -109,18 +110,20 @@ static int vsc8211_intr_clear(struct cphy *cphy)
        u32 val;
 
        /* Clear PHY interrupts by reading the register. */
-       return mdio_read(cphy, 0, VSC8211_INTR_STATUS, &val);
+       return t3_mdio_read(cphy, MDIO_DEVAD_NONE, VSC8211_INTR_STATUS, &val);
 }
 
 static int vsc8211_autoneg_enable(struct cphy *cphy)
 {
-       return t3_mdio_change_bits(cphy, 0, MII_BMCR, BMCR_PDOWN | BMCR_ISOLATE,
+       return t3_mdio_change_bits(cphy, MDIO_DEVAD_NONE, MII_BMCR,
+                                  BMCR_PDOWN | BMCR_ISOLATE,
                                   BMCR_ANENABLE | BMCR_ANRESTART);
 }
 
 static int vsc8211_autoneg_restart(struct cphy *cphy)
 {
-       return t3_mdio_change_bits(cphy, 0, MII_BMCR, BMCR_PDOWN | BMCR_ISOLATE,
+       return t3_mdio_change_bits(cphy, MDIO_DEVAD_NONE, MII_BMCR,
+                                  BMCR_PDOWN | BMCR_ISOLATE,
                                   BMCR_ANRESTART);
 }
 
@@ -130,9 +133,9 @@ static int vsc8211_get_link_status(struct cphy *cphy, int *link_ok,
        unsigned int bmcr, status, lpa, adv;
        int err, sp = -1, dplx = -1, pause = 0;
 
-       err = mdio_read(cphy, 0, MII_BMCR, &bmcr);
+       err = t3_mdio_read(cphy, MDIO_DEVAD_NONE, MII_BMCR, &bmcr);
        if (!err)
-               err = mdio_read(cphy, 0, MII_BMSR, &status);
+               err = t3_mdio_read(cphy, MDIO_DEVAD_NONE, MII_BMSR, &status);
        if (err)
                return err;
 
@@ -142,7 +145,8 @@ static int vsc8211_get_link_status(struct cphy *cphy, int *link_ok,
                 * once more to get the current link state.
                 */
                if (!(status & BMSR_LSTATUS))
-                       err = mdio_read(cphy, 0, MII_BMSR, &status);
+                       err = t3_mdio_read(cphy, MDIO_DEVAD_NONE, MII_BMSR,
+                                          &status);
                if (err)
                        return err;
                *link_ok = (status & BMSR_LSTATUS) != 0;
@@ -156,7 +160,8 @@ static int vsc8211_get_link_status(struct cphy *cphy, int *link_ok,
                else
                        sp = SPEED_10;
        } else if (status & BMSR_ANEGCOMPLETE) {
-               err = mdio_read(cphy, 0, VSC8211_AUX_CTRL_STAT, &status);
+               err = t3_mdio_read(cphy, MDIO_DEVAD_NONE, VSC8211_AUX_CTRL_STAT,
+                                  &status);
                if (err)
                        return err;
 
@@ -170,9 +175,11 @@ static int vsc8211_get_link_status(struct cphy *cphy, int *link_ok,
                        sp = SPEED_1000;
 
                if (fc && dplx == DUPLEX_FULL) {
-                       err = mdio_read(cphy, 0, MII_LPA, &lpa);
+                       err = t3_mdio_read(cphy, MDIO_DEVAD_NONE, MII_LPA,
+                                          &lpa);
                        if (!err)
-                               err = mdio_read(cphy, 0, MII_ADVERTISE, &adv);
+                               err = t3_mdio_read(cphy, MDIO_DEVAD_NONE,
+                                                  MII_ADVERTISE, &adv);
                        if (err)
                                return err;
 
@@ -202,9 +209,9 @@ static int vsc8211_get_link_status_fiber(struct cphy *cphy, int *link_ok,
        unsigned int bmcr, status, lpa, adv;
        int err, sp = -1, dplx = -1, pause = 0;
 
-       err = mdio_read(cphy, 0, MII_BMCR, &bmcr);
+       err = t3_mdio_read(cphy, MDIO_DEVAD_NONE, MII_BMCR, &bmcr);
        if (!err)
-               err = mdio_read(cphy, 0, MII_BMSR, &status);
+               err = t3_mdio_read(cphy, MDIO_DEVAD_NONE, MII_BMSR, &status);
        if (err)
                return err;
 
@@ -214,7 +221,8 @@ static int vsc8211_get_link_status_fiber(struct cphy *cphy, int *link_ok,
                 * once more to get the current link state.
                 */
                if (!(status & BMSR_LSTATUS))
-                       err = mdio_read(cphy, 0, MII_BMSR, &status);
+                       err = t3_mdio_read(cphy, MDIO_DEVAD_NONE, MII_BMSR,
+                                          &status);
                if (err)
                        return err;
                *link_ok = (status & BMSR_LSTATUS) != 0;
@@ -228,9 +236,10 @@ static int vsc8211_get_link_status_fiber(struct cphy *cphy, int *link_ok,
                else
                        sp = SPEED_10;
        } else if (status & BMSR_ANEGCOMPLETE) {
-               err = mdio_read(cphy, 0, MII_LPA, &lpa);
+               err = t3_mdio_read(cphy, MDIO_DEVAD_NONE, MII_LPA, &lpa);
                if (!err)
-                       err = mdio_read(cphy, 0, MII_ADVERTISE, &adv);
+                       err = t3_mdio_read(cphy, MDIO_DEVAD_NONE, MII_ADVERTISE,
+                                          &adv);
                if (err)
                        return err;
 
@@ -270,23 +279,23 @@ static int vsc8211_set_automdi(struct cphy *phy, int enable)
 {
        int err;
 
-       err = mdio_write(phy, 0, VSC8211_EXT_PAGE_AXS, 0x52b5);
+       err = t3_mdio_write(phy, MDIO_DEVAD_NONE, VSC8211_EXT_PAGE_AXS, 0x52b5);
        if (err)
                return err;
 
-       err = mdio_write(phy, 0, 18, 0x12);
+       err = t3_mdio_write(phy, MDIO_DEVAD_NONE, 18, 0x12);
        if (err)
                return err;
 
-       err = mdio_write(phy, 0, 17, enable ? 0x2803 : 0x3003);
+       err = t3_mdio_write(phy, MDIO_DEVAD_NONE, 17, enable ? 0x2803 : 0x3003);
        if (err)
                return err;
 
-       err = mdio_write(phy, 0, 16, 0x87fa);
+       err = t3_mdio_write(phy, MDIO_DEVAD_NONE, 16, 0x87fa);
        if (err)
                return err;
 
-       err = mdio_write(phy, 0, VSC8211_EXT_PAGE_AXS, 0);
+       err = t3_mdio_write(phy, MDIO_DEVAD_NONE, VSC8211_EXT_PAGE_AXS, 0);
        if (err)
                return err;
 
@@ -315,7 +324,7 @@ static int vsc8211_intr_handler(struct cphy *cphy)
        unsigned int cause;
        int err, cphy_cause = 0;
 
-       err = mdio_read(cphy, 0, VSC8211_INTR_STATUS, &cause);
+       err = t3_mdio_read(cphy, MDIO_DEVAD_NONE, VSC8211_INTR_STATUS, &cause);
        if (err)
                return err;
 
@@ -367,12 +376,13 @@ int t3_vsc8211_phy_prep(struct cphy *phy, struct adapter *adapter,
                  SUPPORTED_TP | SUPPORTED_IRQ, "10/100/1000BASE-T");
        msleep(20);       /* PHY needs ~10ms to start responding to MDIO */
 
-       err = mdio_read(phy, 0, VSC8211_EXT_CTRL, &val);
+       err = t3_mdio_read(phy, MDIO_DEVAD_NONE, VSC8211_EXT_CTRL, &val);
        if (err)
                return err;
        if (val & VSC_CTRL_MEDIA_MODE_HI) {
                /* copper interface, just need to configure the LEDs */
-               return mdio_write(phy, 0, VSC8211_LED_CTRL, 0x100);
+               return t3_mdio_write(phy, MDIO_DEVAD_NONE, VSC8211_LED_CTRL,
+                                    0x100);
        }
 
        phy->caps = SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg |
@@ -380,20 +390,20 @@ int t3_vsc8211_phy_prep(struct cphy *phy, struct adapter *adapter,
        phy->desc = "1000BASE-X";
        phy->ops = &vsc8211_fiber_ops;
 
-       err = mdio_write(phy, 0, VSC8211_EXT_PAGE_AXS, 1);
+       err = t3_mdio_write(phy, MDIO_DEVAD_NONE, VSC8211_EXT_PAGE_AXS, 1);
        if (err)
                return err;
 
-       err = mdio_write(phy, 0, VSC8211_SIGDET_CTRL, 1);
+       err = t3_mdio_write(phy, MDIO_DEVAD_NONE, VSC8211_SIGDET_CTRL, 1);
        if (err)
                return err;
 
-       err = mdio_write(phy, 0, VSC8211_EXT_PAGE_AXS, 0);
+       err = t3_mdio_write(phy, MDIO_DEVAD_NONE, VSC8211_EXT_PAGE_AXS, 0);
        if (err)
                return err;
 
-       err = mdio_write(phy, 0, VSC8211_EXT_CTRL,
-                        val | VSC_CTRL_CLAUSE37_VIEW);
+       err = t3_mdio_write(phy, MDIO_DEVAD_NONE, VSC8211_EXT_CTRL,
+                           val | VSC_CTRL_CLAUSE37_VIEW);
        if (err)
                return err;
 
diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c
new file mode 100644 (file)
index 0000000..0e9b9f9
--- /dev/null
@@ -0,0 +1,2830 @@
+/*
+ * DaVinci Ethernet Medium Access Controller
+ *
+ * DaVinci EMAC is based upon CPPI 3.0 TI DMA engine
+ *
+ * Copyright (C) 2009 Texas Instruments.
+ *
+ * ---------------------------------------------------------------------------
+ *
+ * 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.
+ * ---------------------------------------------------------------------------
+ * History:
+ * 0-5 A number of folks worked on this driver in bits and pieces but the major
+ *     contribution came from Suraj Iyer and Anant Gole
+ * 6.0 Anant Gole - rewrote the driver as per Linux conventions
+ * 6.1 Chaithrika U S - added support for Gigabit and RMII features,
+ *     PHY layer usage
+ */
+
+/** Pending Items in this driver:
+ * 1. Use Linux cache infrastcture for DMA'ed memory (dma_xxx functions)
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/errno.h>
+#include <linux/in.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/ethtool.h>
+#include <linux/highmem.h>
+#include <linux/proc_fs.h>
+#include <linux/ctype.h>
+#include <linux/version.h>
+#include <linux/spinlock.h>
+#include <linux/dma-mapping.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/semaphore.h>
+#include <linux/phy.h>
+#include <linux/bitops.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
+
+#include <asm/irq.h>
+#include <asm/page.h>
+
+#include <mach/emac.h>
+
+static int debug_level;
+module_param(debug_level, int, 0);
+MODULE_PARM_DESC(debug_level, "DaVinci EMAC debug level (NETIF_MSG bits)");
+
+/* Netif debug messages possible */
+#define DAVINCI_EMAC_DEBUG     (NETIF_MSG_DRV | \
+                               NETIF_MSG_PROBE | \
+                               NETIF_MSG_LINK | \
+                               NETIF_MSG_TIMER | \
+                               NETIF_MSG_IFDOWN | \
+                               NETIF_MSG_IFUP | \
+                               NETIF_MSG_RX_ERR | \
+                               NETIF_MSG_TX_ERR | \
+                               NETIF_MSG_TX_QUEUED | \
+                               NETIF_MSG_INTR | \
+                               NETIF_MSG_TX_DONE | \
+                               NETIF_MSG_RX_STATUS | \
+                               NETIF_MSG_PKTDATA | \
+                               NETIF_MSG_HW | \
+                               NETIF_MSG_WOL)
+
+/* version info */
+#define EMAC_MAJOR_VERSION     6
+#define EMAC_MINOR_VERSION     1
+#define EMAC_MODULE_VERSION    "6.1"
+MODULE_VERSION(EMAC_MODULE_VERSION);
+static const char emac_version_string[] = "TI DaVinci EMAC Linux v6.1";
+
+/* Configuration items */
+#define EMAC_DEF_PASS_CRC              (0) /* Do not pass CRC upto frames */
+#define EMAC_DEF_QOS_EN                        (0) /* EMAC proprietary QoS disabled */
+#define EMAC_DEF_NO_BUFF_CHAIN         (0) /* No buffer chain */
+#define EMAC_DEF_MACCTRL_FRAME_EN      (0) /* Discard Maccontrol frames */
+#define EMAC_DEF_SHORT_FRAME_EN                (0) /* Discard short frames */
+#define EMAC_DEF_ERROR_FRAME_EN                (0) /* Discard error frames */
+#define EMAC_DEF_PROM_EN               (0) /* Promiscous disabled */
+#define EMAC_DEF_PROM_CH               (0) /* Promiscous channel is 0 */
+#define EMAC_DEF_BCAST_EN              (1) /* Broadcast enabled */
+#define EMAC_DEF_BCAST_CH              (0) /* Broadcast channel is 0 */
+#define EMAC_DEF_MCAST_EN              (1) /* Multicast enabled */
+#define EMAC_DEF_MCAST_CH              (0) /* Multicast channel is 0 */
+
+#define EMAC_DEF_TXPRIO_FIXED          (1) /* TX Priority is fixed */
+#define EMAC_DEF_TXPACING_EN           (0) /* TX pacing NOT supported*/
+
+#define EMAC_DEF_BUFFER_OFFSET         (0) /* Buffer offset to DMA (future) */
+#define EMAC_DEF_MIN_ETHPKTSIZE                (60) /* Minimum ethernet pkt size */
+#define EMAC_DEF_MAX_FRAME_SIZE                (1500 + 14 + 4 + 4)
+#define EMAC_DEF_TX_CH                 (0) /* Default 0th channel */
+#define EMAC_DEF_RX_CH                 (0) /* Default 0th channel */
+#define EMAC_DEF_MDIO_TICK_MS          (10) /* typically 1 tick=1 ms) */
+#define EMAC_DEF_MAX_TX_CH             (1) /* Max TX channels configured */
+#define EMAC_DEF_MAX_RX_CH             (1) /* Max RX channels configured */
+#define EMAC_POLL_WEIGHT               (64) /* Default NAPI poll weight */
+
+/* Buffer descriptor parameters */
+#define EMAC_DEF_TX_MAX_SERVICE                (32) /* TX max service BD's */
+#define EMAC_DEF_RX_MAX_SERVICE                (64) /* should = netdev->weight */
+
+/* EMAC register related defines */
+#define EMAC_ALL_MULTI_REG_VALUE       (0xFFFFFFFF)
+#define EMAC_NUM_MULTICAST_BITS                (64)
+#define EMAC_TEARDOWN_VALUE            (0xFFFFFFFC)
+#define EMAC_TX_CONTROL_TX_ENABLE_VAL  (0x1)
+#define EMAC_RX_CONTROL_RX_ENABLE_VAL  (0x1)
+#define EMAC_MAC_HOST_ERR_INTMASK_VAL  (0x2)
+#define EMAC_RX_UNICAST_CLEAR_ALL      (0xFF)
+#define EMAC_INT_MASK_CLEAR            (0xFF)
+
+/* RX MBP register bit positions */
+#define EMAC_RXMBP_PASSCRC_MASK                BIT(30)
+#define EMAC_RXMBP_QOSEN_MASK          BIT(29)
+#define EMAC_RXMBP_NOCHAIN_MASK                BIT(28)
+#define EMAC_RXMBP_CMFEN_MASK          BIT(24)
+#define EMAC_RXMBP_CSFEN_MASK          BIT(23)
+#define EMAC_RXMBP_CEFEN_MASK          BIT(22)
+#define EMAC_RXMBP_CAFEN_MASK          BIT(21)
+#define EMAC_RXMBP_PROMCH_SHIFT                (16)
+#define EMAC_RXMBP_PROMCH_MASK         (0x7 << 16)
+#define EMAC_RXMBP_BROADEN_MASK                BIT(13)
+#define EMAC_RXMBP_BROADCH_SHIFT       (8)
+#define EMAC_RXMBP_BROADCH_MASK                (0x7 << 8)
+#define EMAC_RXMBP_MULTIEN_MASK                BIT(5)
+#define EMAC_RXMBP_MULTICH_SHIFT       (0)
+#define EMAC_RXMBP_MULTICH_MASK                (0x7)
+#define EMAC_RXMBP_CHMASK              (0x7)
+
+/* EMAC register definitions/bit maps used */
+# define EMAC_MBP_RXPROMISC            (0x00200000)
+# define EMAC_MBP_PROMISCCH(ch)                (((ch) & 0x7) << 16)
+# define EMAC_MBP_RXBCAST              (0x00002000)
+# define EMAC_MBP_BCASTCHAN(ch)                (((ch) & 0x7) << 8)
+# define EMAC_MBP_RXMCAST              (0x00000020)
+# define EMAC_MBP_MCASTCHAN(ch)                ((ch) & 0x7)
+
+/* EMAC mac_control register */
+#define EMAC_MACCONTROL_TXPTYPE                (0x200)
+#define EMAC_MACCONTROL_TXPACEEN       (0x40)
+#define EMAC_MACCONTROL_MIIEN          (0x20)
+#define EMAC_MACCONTROL_GIGABITEN      (0x80)
+#define EMAC_MACCONTROL_GIGABITEN_SHIFT (7)
+#define EMAC_MACCONTROL_FULLDUPLEXEN   (0x1)
+#define EMAC_MACCONTROL_RMIISPEED_MASK BIT(15)
+
+/* GIGABIT MODE related bits */
+#define EMAC_DM646X_MACCONTORL_GMIIEN  BIT(5)
+#define EMAC_DM646X_MACCONTORL_GIG     BIT(7)
+#define EMAC_DM646X_MACCONTORL_GIGFORCE        BIT(17)
+
+/* EMAC mac_status register */
+#define EMAC_MACSTATUS_TXERRCODE_MASK  (0xF00000)
+#define EMAC_MACSTATUS_TXERRCODE_SHIFT (20)
+#define EMAC_MACSTATUS_TXERRCH_MASK    (0x7)
+#define EMAC_MACSTATUS_TXERRCH_SHIFT   (16)
+#define EMAC_MACSTATUS_RXERRCODE_MASK  (0xF000)
+#define EMAC_MACSTATUS_RXERRCODE_SHIFT (12)
+#define EMAC_MACSTATUS_RXERRCH_MASK    (0x7)
+#define EMAC_MACSTATUS_RXERRCH_SHIFT   (8)
+
+/* EMAC RX register masks */
+#define EMAC_RX_MAX_LEN_MASK           (0xFFFF)
+#define EMAC_RX_BUFFER_OFFSET_MASK     (0xFFFF)
+
+/* MAC_IN_VECTOR (0x180) register bit fields */
+#define EMAC_DM644X_MAC_IN_VECTOR_HOST_INT           (0x20000)
+#define EMAC_DM644X_MAC_IN_VECTOR_STATPEND_INT       (0x10000)
+#define EMAC_DM644X_MAC_IN_VECTOR_RX_INT_VEC         (0x0100)
+#define EMAC_DM644X_MAC_IN_VECTOR_TX_INT_VEC         (0x01)
+
+/** NOTE:: For DM646x the IN_VECTOR has changed */
+#define EMAC_DM646X_MAC_IN_VECTOR_RX_INT_VEC   BIT(EMAC_DEF_RX_CH)
+#define EMAC_DM646X_MAC_IN_VECTOR_TX_INT_VEC   BIT(16 + EMAC_DEF_TX_CH)
+
+/* CPPI bit positions */
+#define EMAC_CPPI_SOP_BIT              BIT(31)
+#define EMAC_CPPI_EOP_BIT              BIT(30)
+#define EMAC_CPPI_OWNERSHIP_BIT                BIT(29)
+#define EMAC_CPPI_EOQ_BIT              BIT(28)
+#define EMAC_CPPI_TEARDOWN_COMPLETE_BIT BIT(27)
+#define EMAC_CPPI_PASS_CRC_BIT         BIT(26)
+#define EMAC_RX_BD_BUF_SIZE            (0xFFFF)
+#define EMAC_BD_LENGTH_FOR_CACHE       (16) /* only CPPI bytes */
+#define EMAC_RX_BD_PKT_LENGTH_MASK     (0xFFFF)
+
+/* Max hardware defines */
+#define EMAC_MAX_TXRX_CHANNELS          (8)  /* Max hardware channels */
+#define EMAC_DEF_MAX_MULTICAST_ADDRESSES (64) /* Max mcast addr's */
+
+/* EMAC Peripheral Device Register Memory Layout structure */
+#define EMAC_TXIDVER           0x0
+#define EMAC_TXCONTROL         0x4
+#define EMAC_TXTEARDOWN                0x8
+#define EMAC_RXIDVER           0x10
+#define EMAC_RXCONTROL         0x14
+#define EMAC_RXTEARDOWN                0x18
+#define EMAC_TXINTSTATRAW      0x80
+#define EMAC_TXINTSTATMASKED   0x84
+#define EMAC_TXINTMASKSET      0x88
+#define EMAC_TXINTMASKCLEAR    0x8C
+#define EMAC_MACINVECTOR       0x90
+
+#define EMAC_DM646X_MACEOIVECTOR       0x94
+
+#define EMAC_RXINTSTATRAW      0xA0
+#define EMAC_RXINTSTATMASKED   0xA4
+#define EMAC_RXINTMASKSET      0xA8
+#define EMAC_RXINTMASKCLEAR    0xAC
+#define EMAC_MACINTSTATRAW     0xB0
+#define EMAC_MACINTSTATMASKED  0xB4
+#define EMAC_MACINTMASKSET     0xB8
+#define EMAC_MACINTMASKCLEAR   0xBC
+
+#define EMAC_RXMBPENABLE       0x100
+#define EMAC_RXUNICASTSET      0x104
+#define EMAC_RXUNICASTCLEAR    0x108
+#define EMAC_RXMAXLEN          0x10C
+#define EMAC_RXBUFFEROFFSET    0x110
+#define EMAC_RXFILTERLOWTHRESH 0x114
+
+#define EMAC_MACCONTROL                0x160
+#define EMAC_MACSTATUS         0x164
+#define EMAC_EMCONTROL         0x168
+#define EMAC_FIFOCONTROL       0x16C
+#define EMAC_MACCONFIG         0x170
+#define EMAC_SOFTRESET         0x174
+#define EMAC_MACSRCADDRLO      0x1D0
+#define EMAC_MACSRCADDRHI      0x1D4
+#define EMAC_MACHASH1          0x1D8
+#define EMAC_MACHASH2          0x1DC
+#define EMAC_MACADDRLO         0x500
+#define EMAC_MACADDRHI         0x504
+#define EMAC_MACINDEX          0x508
+
+/* EMAC HDP and Completion registors */
+#define EMAC_TXHDP(ch)         (0x600 + (ch * 4))
+#define EMAC_RXHDP(ch)         (0x620 + (ch * 4))
+#define EMAC_TXCP(ch)          (0x640 + (ch * 4))
+#define EMAC_RXCP(ch)          (0x660 + (ch * 4))
+
+/* EMAC statistics registers */
+#define EMAC_RXGOODFRAMES      0x200
+#define EMAC_RXBCASTFRAMES     0x204
+#define EMAC_RXMCASTFRAMES     0x208
+#define EMAC_RXPAUSEFRAMES     0x20C
+#define EMAC_RXCRCERRORS       0x210
+#define EMAC_RXALIGNCODEERRORS 0x214
+#define EMAC_RXOVERSIZED       0x218
+#define EMAC_RXJABBER          0x21C
+#define EMAC_RXUNDERSIZED      0x220
+#define EMAC_RXFRAGMENTS       0x224
+#define EMAC_RXFILTERED                0x228
+#define EMAC_RXQOSFILTERED     0x22C
+#define EMAC_RXOCTETS          0x230
+#define EMAC_TXGOODFRAMES      0x234
+#define EMAC_TXBCASTFRAMES     0x238
+#define EMAC_TXMCASTFRAMES     0x23C
+#define EMAC_TXPAUSEFRAMES     0x240
+#define EMAC_TXDEFERRED                0x244
+#define EMAC_TXCOLLISION       0x248
+#define EMAC_TXSINGLECOLL      0x24C
+#define EMAC_TXMULTICOLL       0x250
+#define EMAC_TXEXCESSIVECOLL   0x254
+#define EMAC_TXLATECOLL                0x258
+#define EMAC_TXUNDERRUN                0x25C
+#define EMAC_TXCARRIERSENSE    0x260
+#define EMAC_TXOCTETS          0x264
+#define EMAC_NETOCTETS         0x280
+#define EMAC_RXSOFOVERRUNS     0x284
+#define EMAC_RXMOFOVERRUNS     0x288
+#define EMAC_RXDMAOVERRUNS     0x28C
+
+/* EMAC DM644x control registers */
+#define EMAC_CTRL_EWCTL                (0x4)
+#define EMAC_CTRL_EWINTTCNT    (0x8)
+
+/* EMAC MDIO related */
+/* Mask & Control defines */
+#define MDIO_CONTROL_CLKDIV    (0xFF)
+#define MDIO_CONTROL_ENABLE    BIT(30)
+#define MDIO_USERACCESS_GO     BIT(31)
+#define MDIO_USERACCESS_WRITE  BIT(30)
+#define MDIO_USERACCESS_READ   (0)
+#define MDIO_USERACCESS_REGADR (0x1F << 21)
+#define MDIO_USERACCESS_PHYADR (0x1F << 16)
+#define MDIO_USERACCESS_DATA   (0xFFFF)
+#define MDIO_USERPHYSEL_LINKSEL        BIT(7)
+#define MDIO_VER_MODID         (0xFFFF << 16)
+#define MDIO_VER_REVMAJ                (0xFF   << 8)
+#define MDIO_VER_REVMIN                (0xFF)
+
+#define MDIO_USERACCESS(inst)  (0x80 + (inst * 8))
+#define MDIO_USERPHYSEL(inst)  (0x84 + (inst * 8))
+#define MDIO_CONTROL           (0x04)
+
+/* EMAC DM646X control module registers */
+#define EMAC_DM646X_CMRXINTEN  (0x14)
+#define EMAC_DM646X_CMTXINTEN  (0x18)
+
+/* EMAC EOI codes for C0 */
+#define EMAC_DM646X_MAC_EOI_C0_RXEN    (0x01)
+#define EMAC_DM646X_MAC_EOI_C0_TXEN    (0x02)
+
+/** net_buf_obj: EMAC network bufferdata structure
+ *
+ * EMAC network buffer data structure
+ */
+struct emac_netbufobj {
+       void *buf_token;
+       char *data_ptr;
+       int length;
+};
+
+/** net_pkt_obj: EMAC network packet data structure
+ *
+ * EMAC network packet data structure - supports buffer list (for future)
+ */
+struct emac_netpktobj {
+       void *pkt_token; /* data token may hold tx/rx chan id */
+       struct emac_netbufobj *buf_list; /* array of network buffer objects */
+       int num_bufs;
+       int pkt_length;
+};
+
+/** emac_tx_bd: EMAC TX Buffer descriptor data structure
+ *
+ * EMAC TX Buffer descriptor data structure
+ */
+struct emac_tx_bd {
+       int h_next;
+       int buff_ptr;
+       int off_b_len;
+       int mode; /* SOP, EOP, ownership, EOQ, teardown,Qstarv, length */
+       struct emac_tx_bd __iomem *next;
+       void *buf_token;
+};
+
+/** emac_txch: EMAC TX Channel data structure
+ *
+ * EMAC TX Channel data structure
+ */
+struct emac_txch {
+       /* Config related */
+       u32 num_bd;
+       u32 service_max;
+
+       /* CPPI specific */
+       u32 alloc_size;
+       void __iomem *bd_mem;
+       struct emac_tx_bd __iomem *bd_pool_head;
+       struct emac_tx_bd __iomem *active_queue_head;
+       struct emac_tx_bd __iomem *active_queue_tail;
+       struct emac_tx_bd __iomem *last_hw_bdprocessed;
+       u32 queue_active;
+       u32 teardown_pending;
+       u32 *tx_complete;
+
+       /** statistics */
+       u32 proc_count;     /* TX: # of times emac_tx_bdproc is called */
+       u32 mis_queued_packets;
+       u32 queue_reinit;
+       u32 end_of_queue_add;
+       u32 out_of_tx_bd;
+       u32 no_active_pkts; /* IRQ when there were no packets to process */
+       u32 active_queue_count;
+};
+
+/** emac_rx_bd: EMAC RX Buffer descriptor data structure
+ *
+ * EMAC RX Buffer descriptor data structure
+ */
+struct emac_rx_bd {
+       int h_next;
+       int buff_ptr;
+       int off_b_len;
+       int mode;
+       struct emac_rx_bd __iomem *next;
+       void *data_ptr;
+       void *buf_token;
+};
+
+/** emac_rxch: EMAC RX Channel data structure
+ *
+ * EMAC RX Channel data structure
+ */
+struct emac_rxch {
+       /* configuration info */
+       u32 num_bd;
+       u32 service_max;
+       u32 buf_size;
+       char mac_addr[6];
+
+       /** CPPI specific */
+       u32 alloc_size;
+       void __iomem *bd_mem;
+       struct emac_rx_bd __iomem *bd_pool_head;
+       struct emac_rx_bd __iomem *active_queue_head;
+       struct emac_rx_bd __iomem *active_queue_tail;
+       u32 queue_active;
+       u32 teardown_pending;
+
+       /* packet and buffer objects */
+       struct emac_netpktobj pkt_queue;
+       struct emac_netbufobj buf_queue;
+
+       /** statistics */
+       u32 proc_count; /* number of times emac_rx_bdproc is called */
+       u32 processed_bd;
+       u32 recycled_bd;
+       u32 out_of_rx_bd;
+       u32 out_of_rx_buffers;
+       u32 queue_reinit;
+       u32 end_of_queue_add;
+       u32 end_of_queue;
+       u32 mis_queued_packets;
+};
+
+/* emac_priv: EMAC private data structure
+ *
+ * EMAC adapter private data structure
+ */
+struct emac_priv {
+       u32 msg_enable;
+       struct net_device *ndev;
+       struct platform_device *pdev;
+       struct napi_struct napi;
+       char mac_addr[6];
+       spinlock_t tx_lock;
+       spinlock_t rx_lock;
+       void __iomem *remap_addr;
+       u32 emac_base_phys;
+       void __iomem *emac_base;
+       void __iomem *ctrl_base;
+       void __iomem *emac_ctrl_ram;
+       u32 ctrl_ram_size;
+       struct emac_txch *txch[EMAC_DEF_MAX_TX_CH];
+       struct emac_rxch *rxch[EMAC_DEF_MAX_RX_CH];
+       u32 link; /* 1=link on, 0=link off */
+       u32 speed; /* 0=Auto Neg, 1=No PHY, 10,100, 1000 - mbps */
+       u32 duplex; /* Link duplex: 0=Half, 1=Full */
+       u32 rx_buf_size;
+       u32 isr_count;
+       u8 rmii_en;
+       u8 version;
+       struct net_device_stats net_dev_stats;
+       u32 mac_hash1;
+       u32 mac_hash2;
+       u32 multicast_hash_cnt[EMAC_NUM_MULTICAST_BITS];
+       u32 rx_addr_type;
+       /* periodic timer required for MDIO polling */
+       struct timer_list periodic_timer;
+       u32 periodic_ticks;
+       u32 timer_active;
+       u32 phy_mask;
+       /* mii_bus,phy members */
+       struct mii_bus *mii_bus;
+       struct phy_device *phydev;
+       spinlock_t lock;
+};
+
+/* clock frequency for EMAC */
+static struct clk *emac_clk;
+static unsigned long emac_bus_frequency;
+static unsigned long mdio_max_freq;
+
+/* EMAC internal utility function */
+static inline u32 emac_virt_to_phys(void __iomem *addr)
+{
+       return (u32 __force) io_v2p(addr);
+}
+
+/* Cache macros - Packet buffers would be from skb pool which is cached */
+#define EMAC_VIRT_NOCACHE(addr) (addr)
+#define EMAC_CACHE_INVALIDATE(addr, size) \
+       dma_cache_maint((void *)addr, size, DMA_FROM_DEVICE)
+#define EMAC_CACHE_WRITEBACK(addr, size) \
+       dma_cache_maint((void *)addr, size, DMA_TO_DEVICE)
+#define EMAC_CACHE_WRITEBACK_INVALIDATE(addr, size) \
+       dma_cache_maint((void *)addr, size, DMA_BIDIRECTIONAL)
+
+/* DM644x does not have BD's in cached memory - so no cache functions */
+#define BD_CACHE_INVALIDATE(addr, size)
+#define BD_CACHE_WRITEBACK(addr, size)
+#define BD_CACHE_WRITEBACK_INVALIDATE(addr, size)
+
+/* EMAC TX Host Error description strings */
+static char *emac_txhost_errcodes[16] = {
+       "No error", "SOP error", "Ownership bit not set in SOP buffer",
+       "Zero Next Buffer Descriptor Pointer Without EOP",
+       "Zero Buffer Pointer", "Zero Buffer Length", "Packet Length Error",
+       "Reserved", "Reserved", "Reserved", "Reserved", "Reserved",
+       "Reserved", "Reserved", "Reserved", "Reserved"
+};
+
+/* EMAC RX Host Error description strings */
+static char *emac_rxhost_errcodes[16] = {
+       "No error", "Reserved", "Ownership bit not set in input buffer",
+       "Reserved", "Zero Buffer Pointer", "Reserved", "Reserved",
+       "Reserved", "Reserved", "Reserved", "Reserved", "Reserved",
+       "Reserved", "Reserved", "Reserved", "Reserved"
+};
+
+/* Helper macros */
+#define emac_read(reg)           ioread32(priv->emac_base + (reg))
+#define emac_write(reg, val)      iowrite32(val, priv->emac_base + (reg))
+
+#define emac_ctrl_read(reg)      ioread32((priv->ctrl_base + (reg)))
+#define emac_ctrl_write(reg, val) iowrite32(val, (priv->ctrl_base + (reg)))
+
+#define emac_mdio_read(reg)      ioread32(bus->priv + (reg))
+#define emac_mdio_write(reg, val) iowrite32(val, (bus->priv + (reg)))
+
+/**
+ * emac_dump_regs: Dump important EMAC registers to debug terminal
+ * @priv: The DaVinci EMAC private adapter structure
+ *
+ * Executes ethtool set cmd & sets phy mode
+ *
+ */
+static void emac_dump_regs(struct emac_priv *priv)
+{
+       struct device *emac_dev = &priv->ndev->dev;
+
+       /* Print important registers in EMAC */
+       dev_info(emac_dev, "EMAC Basic registers\n");
+       dev_info(emac_dev, "EMAC: EWCTL: %08X, EWINTTCNT: %08X\n",
+               emac_ctrl_read(EMAC_CTRL_EWCTL),
+               emac_ctrl_read(EMAC_CTRL_EWINTTCNT));
+       dev_info(emac_dev, "EMAC: TXID: %08X %s, RXID: %08X %s\n",
+               emac_read(EMAC_TXIDVER),
+               ((emac_read(EMAC_TXCONTROL)) ? "enabled" : "disabled"),
+               emac_read(EMAC_RXIDVER),
+               ((emac_read(EMAC_RXCONTROL)) ? "enabled" : "disabled"));
+       dev_info(emac_dev, "EMAC: TXIntRaw:%08X, TxIntMasked: %08X, "\
+               "TxIntMasSet: %08X\n", emac_read(EMAC_TXINTSTATRAW),
+               emac_read(EMAC_TXINTSTATMASKED), emac_read(EMAC_TXINTMASKSET));
+       dev_info(emac_dev, "EMAC: RXIntRaw:%08X, RxIntMasked: %08X, "\
+               "RxIntMasSet: %08X\n", emac_read(EMAC_RXINTSTATRAW),
+               emac_read(EMAC_RXINTSTATMASKED), emac_read(EMAC_RXINTMASKSET));
+       dev_info(emac_dev, "EMAC: MacIntRaw:%08X, MacIntMasked: %08X, "\
+               "MacInVector=%08X\n", emac_read(EMAC_MACINTSTATRAW),
+               emac_read(EMAC_MACINTSTATMASKED), emac_read(EMAC_MACINVECTOR));
+       dev_info(emac_dev, "EMAC: EmuControl:%08X, FifoControl: %08X\n",
+               emac_read(EMAC_EMCONTROL), emac_read(EMAC_FIFOCONTROL));
+       dev_info(emac_dev, "EMAC: MBPEnable:%08X, RXUnicastSet: %08X, "\
+               "RXMaxLen=%08X\n", emac_read(EMAC_RXMBPENABLE),
+               emac_read(EMAC_RXUNICASTSET), emac_read(EMAC_RXMAXLEN));
+       dev_info(emac_dev, "EMAC: MacControl:%08X, MacStatus: %08X, "\
+               "MacConfig=%08X\n", emac_read(EMAC_MACCONTROL),
+               emac_read(EMAC_MACSTATUS), emac_read(EMAC_MACCONFIG));
+       dev_info(emac_dev, "EMAC: TXHDP[0]:%08X, RXHDP[0]: %08X\n",
+               emac_read(EMAC_TXHDP(0)), emac_read(EMAC_RXHDP(0)));
+       dev_info(emac_dev, "EMAC Statistics\n");
+       dev_info(emac_dev, "EMAC: rx_good_frames:%d\n",
+               emac_read(EMAC_RXGOODFRAMES));
+       dev_info(emac_dev, "EMAC: rx_broadcast_frames:%d\n",
+               emac_read(EMAC_RXBCASTFRAMES));
+       dev_info(emac_dev, "EMAC: rx_multicast_frames:%d\n",
+               emac_read(EMAC_RXMCASTFRAMES));
+       dev_info(emac_dev, "EMAC: rx_pause_frames:%d\n",
+               emac_read(EMAC_RXPAUSEFRAMES));
+       dev_info(emac_dev, "EMAC: rx_crcerrors:%d\n",
+               emac_read(EMAC_RXCRCERRORS));
+       dev_info(emac_dev, "EMAC: rx_align_code_errors:%d\n",
+               emac_read(EMAC_RXALIGNCODEERRORS));
+       dev_info(emac_dev, "EMAC: rx_oversized_frames:%d\n",
+               emac_read(EMAC_RXOVERSIZED));
+       dev_info(emac_dev, "EMAC: rx_jabber_frames:%d\n",
+               emac_read(EMAC_RXJABBER));
+       dev_info(emac_dev, "EMAC: rx_undersized_frames:%d\n",
+               emac_read(EMAC_RXUNDERSIZED));
+       dev_info(emac_dev, "EMAC: rx_fragments:%d\n",
+               emac_read(EMAC_RXFRAGMENTS));
+       dev_info(emac_dev, "EMAC: rx_filtered_frames:%d\n",
+               emac_read(EMAC_RXFILTERED));
+       dev_info(emac_dev, "EMAC: rx_qos_filtered_frames:%d\n",
+               emac_read(EMAC_RXQOSFILTERED));
+       dev_info(emac_dev, "EMAC: rx_octets:%d\n",
+               emac_read(EMAC_RXOCTETS));
+       dev_info(emac_dev, "EMAC: tx_goodframes:%d\n",
+               emac_read(EMAC_TXGOODFRAMES));
+       dev_info(emac_dev, "EMAC: tx_bcastframes:%d\n",
+               emac_read(EMAC_TXBCASTFRAMES));
+       dev_info(emac_dev, "EMAC: tx_mcastframes:%d\n",
+               emac_read(EMAC_TXMCASTFRAMES));
+       dev_info(emac_dev, "EMAC: tx_pause_frames:%d\n",
+               emac_read(EMAC_TXPAUSEFRAMES));
+       dev_info(emac_dev, "EMAC: tx_deferred_frames:%d\n",
+               emac_read(EMAC_TXDEFERRED));
+       dev_info(emac_dev, "EMAC: tx_collision_frames:%d\n",
+               emac_read(EMAC_TXCOLLISION));
+       dev_info(emac_dev, "EMAC: tx_single_coll_frames:%d\n",
+               emac_read(EMAC_TXSINGLECOLL));
+       dev_info(emac_dev, "EMAC: tx_mult_coll_frames:%d\n",
+               emac_read(EMAC_TXMULTICOLL));
+       dev_info(emac_dev, "EMAC: tx_excessive_collisions:%d\n",
+               emac_read(EMAC_TXEXCESSIVECOLL));
+       dev_info(emac_dev, "EMAC: tx_late_collisions:%d\n",
+               emac_read(EMAC_TXLATECOLL));
+       dev_info(emac_dev, "EMAC: tx_underrun:%d\n",
+               emac_read(EMAC_TXUNDERRUN));
+       dev_info(emac_dev, "EMAC: tx_carrier_sense_errors:%d\n",
+               emac_read(EMAC_TXCARRIERSENSE));
+       dev_info(emac_dev, "EMAC: tx_octets:%d\n",
+               emac_read(EMAC_TXOCTETS));
+       dev_info(emac_dev, "EMAC: net_octets:%d\n",
+               emac_read(EMAC_NETOCTETS));
+       dev_info(emac_dev, "EMAC: rx_sof_overruns:%d\n",
+               emac_read(EMAC_RXSOFOVERRUNS));
+       dev_info(emac_dev, "EMAC: rx_mof_overruns:%d\n",
+               emac_read(EMAC_RXMOFOVERRUNS));
+       dev_info(emac_dev, "EMAC: rx_dma_overruns:%d\n",
+               emac_read(EMAC_RXDMAOVERRUNS));
+}
+
+/*************************************************************************
+ *  EMAC MDIO/Phy Functionality
+ *************************************************************************/
+/**
+ * emac_get_drvinfo: Get EMAC driver information
+ * @ndev: The DaVinci EMAC network adapter
+ * @info: ethtool info structure containing name and version
+ *
+ * Returns EMAC driver information (name and version)
+ *
+ */
+static void emac_get_drvinfo(struct net_device *ndev,
+                            struct ethtool_drvinfo *info)
+{
+       strcpy(info->driver, emac_version_string);
+       strcpy(info->version, EMAC_MODULE_VERSION);
+}
+
+/**
+ * emac_get_settings: Get EMAC settings
+ * @ndev: The DaVinci EMAC network adapter
+ * @ecmd: ethtool command
+ *
+ * Executes ethool get command
+ *
+ */
+static int emac_get_settings(struct net_device *ndev,
+                            struct ethtool_cmd *ecmd)
+{
+       struct emac_priv *priv = netdev_priv(ndev);
+       if (priv->phy_mask)
+               return phy_ethtool_gset(priv->phydev, ecmd);
+       else
+               return -EOPNOTSUPP;
+
+}
+
+/**
+ * emac_set_settings: Set EMAC settings
+ * @ndev: The DaVinci EMAC network adapter
+ * @ecmd: ethtool command
+ *
+ * Executes ethool set command
+ *
+ */
+static int emac_set_settings(struct net_device *ndev, struct ethtool_cmd *ecmd)
+{
+       struct emac_priv *priv = netdev_priv(ndev);
+       if (priv->phy_mask)
+               return phy_ethtool_sset(priv->phydev, ecmd);
+       else
+               return -EOPNOTSUPP;
+
+}
+
+/**
+ * ethtool_ops: DaVinci EMAC Ethtool structure
+ *
+ * Ethtool support for EMAC adapter
+ *
+ */
+static const struct ethtool_ops ethtool_ops = {
+       .get_drvinfo = emac_get_drvinfo,
+       .get_settings = emac_get_settings,
+       .set_settings = emac_set_settings,
+       .get_link = ethtool_op_get_link,
+};
+
+/**
+ * emac_update_phystatus: Update Phy status
+ * @priv: The DaVinci EMAC private adapter structure
+ *
+ * Updates phy status and takes action for network queue if required
+ * based upon link status
+ *
+ */
+static void emac_update_phystatus(struct emac_priv *priv)
+{
+       u32 mac_control;
+       u32 new_duplex;
+       u32 cur_duplex;
+       struct net_device *ndev = priv->ndev;
+
+       mac_control = emac_read(EMAC_MACCONTROL);
+       cur_duplex = (mac_control & EMAC_MACCONTROL_FULLDUPLEXEN) ?
+                       DUPLEX_FULL : DUPLEX_HALF;
+       if (priv->phy_mask)
+               new_duplex = priv->phydev->duplex;
+       else
+               new_duplex = DUPLEX_FULL;
+
+       /* We get called only if link has changed (speed/duplex/status) */
+       if ((priv->link) && (new_duplex != cur_duplex)) {
+               priv->duplex = new_duplex;
+               if (DUPLEX_FULL == priv->duplex)
+                       mac_control |= (EMAC_MACCONTROL_FULLDUPLEXEN);
+               else
+                       mac_control &= ~(EMAC_MACCONTROL_FULLDUPLEXEN);
+       }
+
+       if (priv->speed == SPEED_1000 && (priv->version == EMAC_VERSION_2)) {
+               mac_control = emac_read(EMAC_MACCONTROL);
+               mac_control |= (EMAC_DM646X_MACCONTORL_GMIIEN |
+                               EMAC_DM646X_MACCONTORL_GIG |
+                               EMAC_DM646X_MACCONTORL_GIGFORCE);
+       } else {
+               /* Clear the GIG bit and GIGFORCE bit */
+               mac_control &= ~(EMAC_DM646X_MACCONTORL_GIGFORCE |
+                                       EMAC_DM646X_MACCONTORL_GIG);
+
+               if (priv->rmii_en && (priv->speed == SPEED_100))
+                       mac_control |= EMAC_MACCONTROL_RMIISPEED_MASK;
+               else
+                       mac_control &= ~EMAC_MACCONTROL_RMIISPEED_MASK;
+       }
+
+       /* Update mac_control if changed */
+       emac_write(EMAC_MACCONTROL, mac_control);
+
+       if (priv->link) {
+               /* link ON */
+               if (!netif_carrier_ok(ndev))
+                       netif_carrier_on(ndev);
+       /* reactivate the transmit queue if it is stopped */
+               if (netif_running(ndev) && netif_queue_stopped(ndev))
+                       netif_wake_queue(ndev);
+       } else {
+               /* link OFF */
+               if (netif_carrier_ok(ndev))
+                       netif_carrier_off(ndev);
+               if (!netif_queue_stopped(ndev))
+                       netif_stop_queue(ndev);
+       }
+}
+
+/**
+ * hash_get: Calculate hash value from mac address
+ * @addr: mac address to delete from hash table
+ *
+ * Calculates hash value from mac address
+ *
+ */
+static u32 hash_get(u8 *addr)
+{
+       u32 hash;
+       u8 tmpval;
+       int cnt;
+       hash = 0;
+
+       for (cnt = 0; cnt < 2; cnt++) {
+               tmpval = *addr++;
+               hash ^= (tmpval >> 2) ^ (tmpval << 4);
+               tmpval = *addr++;
+               hash ^= (tmpval >> 4) ^ (tmpval << 2);
+               tmpval = *addr++;
+               hash ^= (tmpval >> 6) ^ (tmpval);
+       }
+
+       return hash & 0x3F;
+}
+
+/**
+ * hash_add: Hash function to add mac addr from hash table
+ * @priv: The DaVinci EMAC private adapter structure
+ * mac_addr: mac address to delete from hash table
+ *
+ * Adds mac address to the internal hash table
+ *
+ */
+static int hash_add(struct emac_priv *priv, u8 *mac_addr)
+{
+       struct device *emac_dev = &priv->ndev->dev;
+       u32 rc = 0;
+       u32 hash_bit;
+       u32 hash_value = hash_get(mac_addr);
+
+       if (hash_value >= EMAC_NUM_MULTICAST_BITS) {
+               if (netif_msg_drv(priv)) {
+                       dev_err(emac_dev, "DaVinci EMAC: hash_add(): Invalid "\
+                               "Hash %08x, should not be greater than %08x",
+                               hash_value, (EMAC_NUM_MULTICAST_BITS - 1));
+               }
+               return -1;
+       }
+
+       /* set the hash bit only if not previously set */
+       if (priv->multicast_hash_cnt[hash_value] == 0) {
+               rc = 1; /* hash value changed */
+               if (hash_value < 32) {
+                       hash_bit = BIT(hash_value);
+                       priv->mac_hash1 |= hash_bit;
+               } else {
+                       hash_bit = BIT((hash_value - 32));
+                       priv->mac_hash2 |= hash_bit;
+               }
+       }
+
+       /* incr counter for num of mcast addr's mapped to "this" hash bit */
+       ++priv->multicast_hash_cnt[hash_value];
+
+       return rc;
+}
+
+/**
+ * hash_del: Hash function to delete mac addr from hash table
+ * @priv: The DaVinci EMAC private adapter structure
+ * mac_addr: mac address to delete from hash table
+ *
+ * Removes mac address from the internal hash table
+ *
+ */
+static int hash_del(struct emac_priv *priv, u8 *mac_addr)
+{
+       u32 hash_value;
+       u32 hash_bit;
+
+       hash_value = hash_get(mac_addr);
+       if (priv->multicast_hash_cnt[hash_value] > 0) {
+               /* dec cntr for num of mcast addr's mapped to this hash bit */
+               --priv->multicast_hash_cnt[hash_value];
+       }
+
+       /* if counter still > 0, at least one multicast address refers
+        * to this hash bit. so return 0 */
+       if (priv->multicast_hash_cnt[hash_value] > 0)
+               return 0;
+
+       if (hash_value < 32) {
+               hash_bit = BIT(hash_value);
+               priv->mac_hash1 &= ~hash_bit;
+       } else {
+               hash_bit = BIT((hash_value - 32));
+               priv->mac_hash2 &= ~hash_bit;
+       }
+
+       /* return 1 to indicate change in mac_hash registers reqd */
+       return 1;
+}
+
+/* EMAC multicast operation */
+#define EMAC_MULTICAST_ADD     0
+#define EMAC_MULTICAST_DEL     1
+#define EMAC_ALL_MULTI_SET     2
+#define EMAC_ALL_MULTI_CLR     3
+
+/**
+ * emac_add_mcast: Set multicast address in the EMAC adapter (Internal)
+ * @priv: The DaVinci EMAC private adapter structure
+ * @action: multicast operation to perform
+ * mac_addr: mac address to set
+ *
+ * Set multicast addresses in EMAC adapter - internal function
+ *
+ */
+static void emac_add_mcast(struct emac_priv *priv, u32 action, u8 *mac_addr)
+{
+       struct device *emac_dev = &priv->ndev->dev;
+       int update = -1;
+
+       switch (action) {
+       case EMAC_MULTICAST_ADD:
+               update = hash_add(priv, mac_addr);
+               break;
+       case EMAC_MULTICAST_DEL:
+               update = hash_del(priv, mac_addr);
+               break;
+       case EMAC_ALL_MULTI_SET:
+               update = 1;
+               priv->mac_hash1 = EMAC_ALL_MULTI_REG_VALUE;
+               priv->mac_hash2 = EMAC_ALL_MULTI_REG_VALUE;
+               break;
+       case EMAC_ALL_MULTI_CLR:
+               update = 1;
+               priv->mac_hash1 = 0;
+               priv->mac_hash2 = 0;
+               memset(&(priv->multicast_hash_cnt[0]), 0,
+               sizeof(priv->multicast_hash_cnt[0]) *
+                      EMAC_NUM_MULTICAST_BITS);
+               break;
+       default:
+               if (netif_msg_drv(priv))
+                       dev_err(emac_dev, "DaVinci EMAC: add_mcast"\
+                               ": bad operation %d", action);
+               break;
+       }
+
+       /* write to the hardware only if the register status chances */
+       if (update > 0) {
+               emac_write(EMAC_MACHASH1, priv->mac_hash1);
+               emac_write(EMAC_MACHASH2, priv->mac_hash2);
+       }
+}
+
+/**
+ * emac_dev_mcast_set: Set multicast address in the EMAC adapter
+ * @ndev: The DaVinci EMAC network adapter
+ *
+ * Set multicast addresses in EMAC adapter
+ *
+ */
+static void emac_dev_mcast_set(struct net_device *ndev)
+{
+       u32 mbp_enable;
+       struct emac_priv *priv = netdev_priv(ndev);
+
+       mbp_enable = emac_read(EMAC_RXMBPENABLE);
+       if (ndev->flags & IFF_PROMISC) {
+               mbp_enable &= (~EMAC_MBP_PROMISCCH(EMAC_DEF_PROM_CH));
+               mbp_enable |= (EMAC_MBP_RXPROMISC);
+       } else {
+               mbp_enable = (mbp_enable & ~EMAC_MBP_RXPROMISC);
+               if ((ndev->flags & IFF_ALLMULTI) ||
+                   (ndev->mc_count > EMAC_DEF_MAX_MULTICAST_ADDRESSES)) {
+                       mbp_enable = (mbp_enable | EMAC_MBP_RXMCAST);
+                       emac_add_mcast(priv, EMAC_ALL_MULTI_SET, NULL);
+               }
+               if (ndev->mc_count > 0) {
+                       struct dev_mc_list *mc_ptr;
+                       mbp_enable = (mbp_enable | EMAC_MBP_RXMCAST);
+                       emac_add_mcast(priv, EMAC_ALL_MULTI_CLR, NULL);
+                       /* program multicast address list into EMAC hardware */
+                       for (mc_ptr = ndev->mc_list; mc_ptr;
+                            mc_ptr = mc_ptr->next) {
+                               emac_add_mcast(priv, EMAC_MULTICAST_ADD,
+                                              (u8 *)mc_ptr->dmi_addr);
+                       }
+               } else {
+                       mbp_enable = (mbp_enable & ~EMAC_MBP_RXMCAST);
+                       emac_add_mcast(priv, EMAC_ALL_MULTI_CLR, NULL);
+               }
+       }
+       /* Set mbp config register */
+       emac_write(EMAC_RXMBPENABLE, mbp_enable);
+}
+
+/*************************************************************************
+ *  EMAC Hardware manipulation
+ *************************************************************************/
+
+/**
+ * emac_int_disable: Disable EMAC module interrupt (from adapter)
+ * @priv: The DaVinci EMAC private adapter structure
+ *
+ * Disable EMAC interrupt on the adapter
+ *
+ */
+static void emac_int_disable(struct emac_priv *priv)
+{
+       if (priv->version == EMAC_VERSION_2) {
+               unsigned long flags;
+
+               local_irq_save(flags);
+
+               /* Program C0_Int_En to zero to turn off
+               * interrupts to the CPU */
+               emac_ctrl_write(EMAC_DM646X_CMRXINTEN, 0x0);
+               emac_ctrl_write(EMAC_DM646X_CMTXINTEN, 0x0);
+               /* NOTE: Rx Threshold and Misc interrupts are not disabled */
+
+               local_irq_restore(flags);
+
+       } else {
+               /* Set DM644x control registers for interrupt control */
+               emac_ctrl_write(EMAC_CTRL_EWCTL, 0x0);
+       }
+}
+
+/**
+ * emac_int_enable: Enable EMAC module interrupt (from adapter)
+ * @priv: The DaVinci EMAC private adapter structure
+ *
+ * Enable EMAC interrupt on the adapter
+ *
+ */
+static void emac_int_enable(struct emac_priv *priv)
+{
+       if (priv->version == EMAC_VERSION_2) {
+               emac_ctrl_write(EMAC_DM646X_CMRXINTEN, 0xff);
+               emac_ctrl_write(EMAC_DM646X_CMTXINTEN, 0xff);
+
+               /* In addition to turning on interrupt Enable, we need
+                * ack by writing appropriate values to the EOI
+                * register */
+
+               /* NOTE: Rx Threshold and Misc interrupts are not enabled */
+
+               /* ack rxen only then a new pulse will be generated */
+               emac_write(EMAC_DM646X_MACEOIVECTOR,
+                       EMAC_DM646X_MAC_EOI_C0_RXEN);
+
+               /* ack txen- only then a new pulse will be generated */
+               emac_write(EMAC_DM646X_MACEOIVECTOR,
+                       EMAC_DM646X_MAC_EOI_C0_TXEN);
+
+       } else {
+               /* Set DM644x control registers for interrupt control */
+               emac_ctrl_write(EMAC_CTRL_EWCTL, 0x1);
+       }
+}
+
+/**
+ * emac_irq: EMAC interrupt handler
+ * @irq: interrupt number
+ * @dev_id: EMAC network adapter data structure ptr
+ *
+ * EMAC Interrupt handler - we only schedule NAPI and not process any packets
+ * here. EVen the interrupt status is checked (TX/RX/Err) in NAPI poll function
+ *
+ * Returns interrupt handled condition
+ */
+static irqreturn_t emac_irq(int irq, void *dev_id)
+{
+       struct net_device *ndev = (struct net_device *)dev_id;
+       struct emac_priv *priv = netdev_priv(ndev);
+
+       ++priv->isr_count;
+       if (likely(netif_running(priv->ndev))) {
+               emac_int_disable(priv);
+               napi_schedule(&priv->napi);
+       } else {
+               /* we are closing down, so dont process anything */
+       }
+       return IRQ_HANDLED;
+}
+
+/** EMAC on-chip buffer descriptor memory
+ *
+ * WARNING: Please note that the on chip memory is used for both TX and RX
+ * buffer descriptor queues and is equally divided between TX and RX desc's
+ * If the number of TX or RX descriptors change this memory pointers need
+ * to be adjusted. If external memory is allocated then these pointers can
+ * pointer to the memory
+ *
+ */
+#define EMAC_TX_BD_MEM(priv)   ((priv)->emac_ctrl_ram)
+#define EMAC_RX_BD_MEM(priv)   ((priv)->emac_ctrl_ram + \
+                               (((priv)->ctrl_ram_size) >> 1))
+
+/**
+ * emac_init_txch: TX channel initialization
+ * @priv: The DaVinci EMAC private adapter structure
+ * @ch: RX channel number
+ *
+ * Called during device init to setup a TX channel (allocate buffer desc
+ * create free pool and keep ready for transmission
+ *
+ * Returns success(0) or mem alloc failures error code
+ */
+static int emac_init_txch(struct emac_priv *priv, u32 ch)
+{
+       struct device *emac_dev = &priv->ndev->dev;
+       u32 cnt, bd_size;
+       void __iomem *mem;
+       struct emac_tx_bd __iomem *curr_bd;
+       struct emac_txch *txch = NULL;
+
+       txch = kzalloc(sizeof(struct emac_txch), GFP_KERNEL);
+       if (NULL == txch) {
+               dev_err(emac_dev, "DaVinci EMAC: TX Ch mem alloc failed");
+               return -ENOMEM;
+       }
+       priv->txch[ch] = txch;
+       txch->service_max = EMAC_DEF_TX_MAX_SERVICE;
+       txch->active_queue_head = NULL;
+       txch->active_queue_tail = NULL;
+       txch->queue_active = 0;
+       txch->teardown_pending = 0;
+
+       /* allocate memory for TX CPPI channel on a 4 byte boundry */
+       txch->tx_complete = kzalloc(txch->service_max * sizeof(u32),
+                                   GFP_KERNEL);
+       if (NULL == txch->tx_complete) {
+               dev_err(emac_dev, "DaVinci EMAC: Tx service mem alloc failed");
+               kfree(txch);
+               return -ENOMEM;
+       }
+
+       /* allocate buffer descriptor pool align every BD on four word
+        * boundry for future requirements */
+       bd_size = (sizeof(struct emac_tx_bd) + 0xF) & ~0xF;
+       txch->num_bd = (priv->ctrl_ram_size >> 1) / bd_size;
+       txch->alloc_size = (((bd_size * txch->num_bd) + 0xF) & ~0xF);
+
+       /* alloc TX BD memory */
+       txch->bd_mem = EMAC_TX_BD_MEM(priv);
+       __memzero((void __force *)txch->bd_mem, txch->alloc_size);
+
+       /* initialize the BD linked list */
+       mem = (void __force __iomem *)
+                       (((u32 __force) txch->bd_mem + 0xF) & ~0xF);
+       txch->bd_pool_head = NULL;
+       for (cnt = 0; cnt < txch->num_bd; cnt++) {
+               curr_bd = mem + (cnt * bd_size);
+               curr_bd->next = txch->bd_pool_head;
+               txch->bd_pool_head = curr_bd;
+       }
+
+       /* reset statistics counters */
+       txch->out_of_tx_bd = 0;
+       txch->no_active_pkts = 0;
+       txch->active_queue_count = 0;
+
+       return 0;
+}
+
+/**
+ * emac_cleanup_txch: Book-keep function to clean TX channel resources
+ * @priv: The DaVinci EMAC private adapter structure
+ * @ch: TX channel number
+ *
+ * Called to clean up TX channel resources
+ *
+ */
+static void emac_cleanup_txch(struct emac_priv *priv, u32 ch)
+{
+       struct emac_txch *txch = priv->txch[ch];
+
+       if (txch) {
+               if (txch->bd_mem)
+                       txch->bd_mem = NULL;
+               kfree(txch->tx_complete);
+               kfree(txch);
+               priv->txch[ch] = NULL;
+       }
+}
+
+/**
+ * emac_net_tx_complete: TX packet completion function
+ * @priv: The DaVinci EMAC private adapter structure
+ * @net_data_tokens: packet token - skb pointer
+ * @num_tokens: number of skb's to free
+ * @ch: TX channel number
+ *
+ * Frees the skb once packet is transmitted
+ *
+ */
+static int emac_net_tx_complete(struct emac_priv *priv,
+                               void **net_data_tokens,
+                               int num_tokens, u32 ch)
+{
+       u32 cnt;
+
+       if (unlikely(num_tokens && netif_queue_stopped(priv->ndev)))
+               netif_start_queue(priv->ndev);
+       for (cnt = 0; cnt < num_tokens; cnt++) {
+               struct sk_buff *skb = (struct sk_buff *)net_data_tokens[cnt];
+               if (skb == NULL)
+                       continue;
+               priv->net_dev_stats.tx_packets++;
+               priv->net_dev_stats.tx_bytes += skb->len;
+               dev_kfree_skb_any(skb);
+       }
+       return 0;
+}
+
+/**
+ * emac_txch_teardown: TX channel teardown
+ * @priv: The DaVinci EMAC private adapter structure
+ * @ch: TX channel number
+ *
+ * Called to teardown TX channel
+ *
+ */
+static void emac_txch_teardown(struct emac_priv *priv, u32 ch)
+{
+       struct device *emac_dev = &priv->ndev->dev;
+       u32 teardown_cnt = 0xFFFFFFF0; /* Some high value */
+       struct emac_txch *txch = priv->txch[ch];
+       struct emac_tx_bd __iomem *curr_bd;
+
+       while ((emac_read(EMAC_TXCP(ch)) & EMAC_TEARDOWN_VALUE) !=
+              EMAC_TEARDOWN_VALUE) {
+               /* wait till tx teardown complete */
+               cpu_relax(); /* TODO: check if this helps ... */
+               --teardown_cnt;
+               if (0 == teardown_cnt) {
+                       dev_err(emac_dev, "EMAC: TX teardown aborted\n");
+                       break;
+               }
+       }
+       emac_write(EMAC_TXCP(ch), EMAC_TEARDOWN_VALUE);
+
+       /* process sent packets and return skb's to upper layer */
+       if (1 == txch->queue_active) {
+               curr_bd = txch->active_queue_head;
+               while (curr_bd != NULL) {
+                       emac_net_tx_complete(priv, (void __force *)
+                                       &curr_bd->buf_token, 1, ch);
+                       if (curr_bd != txch->active_queue_tail)
+                               curr_bd = curr_bd->next;
+                       else
+                               break;
+               }
+               txch->bd_pool_head = txch->active_queue_head;
+               txch->active_queue_head =
+               txch->active_queue_tail = NULL;
+       }
+}
+
+/**
+ * emac_stop_txch: Stop TX channel operation
+ * @priv: The DaVinci EMAC private adapter structure
+ * @ch: TX channel number
+ *
+ * Called to stop TX channel operation
+ *
+ */
+static void emac_stop_txch(struct emac_priv *priv, u32 ch)
+{
+       struct emac_txch *txch = priv->txch[ch];
+
+       if (txch) {
+               txch->teardown_pending = 1;
+               emac_write(EMAC_TXTEARDOWN, 0);
+               emac_txch_teardown(priv, ch);
+               txch->teardown_pending = 0;
+               emac_write(EMAC_TXINTMASKCLEAR, BIT(ch));
+       }
+}
+
+/**
+ * emac_tx_bdproc: TX buffer descriptor (packet) processing
+ * @priv: The DaVinci EMAC private adapter structure
+ * @ch: TX channel number to process buffer descriptors for
+ * @budget: number of packets allowed to process
+ * @pending: indication to caller that packets are pending to process
+ *
+ * Processes TX buffer descriptors after packets are transmitted - checks
+ * ownership bit on the TX * descriptor and requeues it to free pool & frees
+ * the SKB buffer. Only "budget" number of packets are processed and
+ * indication of pending packets provided to the caller
+ *
+ * Returns number of packets processed
+ */
+static int emac_tx_bdproc(struct emac_priv *priv, u32 ch, u32 budget)
+{
+       struct device *emac_dev = &priv->ndev->dev;
+       unsigned long flags;
+       u32 frame_status;
+       u32 pkts_processed = 0;
+       u32 tx_complete_cnt = 0;
+       struct emac_tx_bd __iomem *curr_bd;
+       struct emac_txch *txch = priv->txch[ch];
+       u32 *tx_complete_ptr = txch->tx_complete;
+
+       if (unlikely(1 == txch->teardown_pending)) {
+               if (netif_msg_tx_err(priv) && net_ratelimit()) {
+                       dev_err(emac_dev, "DaVinci EMAC:emac_tx_bdproc: "\
+                               "teardown pending\n");
+               }
+               return 0;  /* dont handle any pkt completions */
+       }
+
+       ++txch->proc_count;
+       spin_lock_irqsave(&priv->tx_lock, flags);
+       curr_bd = txch->active_queue_head;
+       if (NULL == curr_bd) {
+               emac_write(EMAC_TXCP(ch),
+                          emac_virt_to_phys(txch->last_hw_bdprocessed));
+               txch->no_active_pkts++;
+               spin_unlock_irqrestore(&priv->tx_lock, flags);
+               return 0;
+       }
+       BD_CACHE_INVALIDATE(curr_bd, EMAC_BD_LENGTH_FOR_CACHE);
+       frame_status = curr_bd->mode;
+       while ((curr_bd) &&
+             ((frame_status & EMAC_CPPI_OWNERSHIP_BIT) == 0) &&
+             (pkts_processed < budget)) {
+               emac_write(EMAC_TXCP(ch), emac_virt_to_phys(curr_bd));
+               txch->active_queue_head = curr_bd->next;
+               if (frame_status & EMAC_CPPI_EOQ_BIT) {
+                       if (curr_bd->next) {    /* misqueued packet */
+                               emac_write(EMAC_TXHDP(ch), curr_bd->h_next);
+                               ++txch->mis_queued_packets;
+                       } else {
+                               txch->queue_active = 0; /* end of queue */
+                       }
+               }
+               *tx_complete_ptr = (u32) curr_bd->buf_token;
+               ++tx_complete_ptr;
+               ++tx_complete_cnt;
+               curr_bd->next = txch->bd_pool_head;
+               txch->bd_pool_head = curr_bd;
+               --txch->active_queue_count;
+               pkts_processed++;
+               txch->last_hw_bdprocessed = curr_bd;
+               curr_bd = txch->active_queue_head;
+               if (curr_bd) {
+                       BD_CACHE_INVALIDATE(curr_bd, EMAC_BD_LENGTH_FOR_CACHE);
+                       frame_status = curr_bd->mode;
+               }
+       } /* end of pkt processing loop */
+
+       emac_net_tx_complete(priv,
+                            (void *)&txch->tx_complete[0],
+                            tx_complete_cnt, ch);
+       spin_unlock_irqrestore(&priv->tx_lock, flags);
+       return pkts_processed;
+}
+
+#define EMAC_ERR_TX_OUT_OF_BD -1
+
+/**
+ * emac_send: EMAC Transmit function (internal)
+ * @priv: The DaVinci EMAC private adapter structure
+ * @pkt: packet pointer (contains skb ptr)
+ * @ch: TX channel number
+ *
+ * Called by the transmit function to queue the packet in EMAC hardware queue
+ *
+ * Returns success(0) or error code (typically out of desc's)
+ */
+static int emac_send(struct emac_priv *priv, struct emac_netpktobj *pkt, u32 ch)
+{
+       unsigned long flags;
+       struct emac_tx_bd __iomem *curr_bd;
+       struct emac_txch *txch;
+       struct emac_netbufobj *buf_list;
+
+       txch = priv->txch[ch];
+       buf_list = pkt->buf_list;   /* get handle to the buffer array */
+
+       /* check packet size and pad if short */
+       if (pkt->pkt_length < EMAC_DEF_MIN_ETHPKTSIZE) {
+               buf_list->length += (EMAC_DEF_MIN_ETHPKTSIZE - pkt->pkt_length);
+               pkt->pkt_length = EMAC_DEF_MIN_ETHPKTSIZE;
+       }
+
+       spin_lock_irqsave(&priv->tx_lock, flags);
+       curr_bd = txch->bd_pool_head;
+       if (curr_bd == NULL) {
+               txch->out_of_tx_bd++;
+               spin_unlock_irqrestore(&priv->tx_lock, flags);
+               return EMAC_ERR_TX_OUT_OF_BD;
+       }
+
+       txch->bd_pool_head = curr_bd->next;
+       curr_bd->buf_token = buf_list->buf_token;
+       /* FIXME buff_ptr = dma_map_single(... data_ptr ...) */
+       curr_bd->buff_ptr = virt_to_phys(buf_list->data_ptr);
+       curr_bd->off_b_len = buf_list->length;
+       curr_bd->h_next = 0;
+       curr_bd->next = NULL;
+       curr_bd->mode = (EMAC_CPPI_SOP_BIT | EMAC_CPPI_OWNERSHIP_BIT |
+                        EMAC_CPPI_EOP_BIT | pkt->pkt_length);
+
+       /* flush the packet from cache if write back cache is present */
+       BD_CACHE_WRITEBACK_INVALIDATE(curr_bd, EMAC_BD_LENGTH_FOR_CACHE);
+
+       /* send the packet */
+       if (txch->active_queue_head == NULL) {
+               txch->active_queue_head = curr_bd;
+               txch->active_queue_tail = curr_bd;
+               if (1 != txch->queue_active) {
+                       emac_write(EMAC_TXHDP(ch),
+                                       emac_virt_to_phys(curr_bd));
+                       txch->queue_active = 1;
+               }
+               ++txch->queue_reinit;
+       } else {
+               register struct emac_tx_bd __iomem *tail_bd;
+               register u32 frame_status;
+
+               tail_bd = txch->active_queue_tail;
+               tail_bd->next = curr_bd;
+               txch->active_queue_tail = curr_bd;
+               tail_bd = EMAC_VIRT_NOCACHE(tail_bd);
+               tail_bd->h_next = (int)emac_virt_to_phys(curr_bd);
+               frame_status = tail_bd->mode;
+               if (frame_status & EMAC_CPPI_EOQ_BIT) {
+                       emac_write(EMAC_TXHDP(ch), emac_virt_to_phys(curr_bd));
+                       frame_status &= ~(EMAC_CPPI_EOQ_BIT);
+                       tail_bd->mode = frame_status;
+                       ++txch->end_of_queue_add;
+               }
+       }
+       txch->active_queue_count++;
+       spin_unlock_irqrestore(&priv->tx_lock, flags);
+       return 0;
+}
+
+/**
+ * emac_dev_xmit: EMAC Transmit function
+ * @skb: SKB pointer
+ * @ndev: The DaVinci EMAC network adapter
+ *
+ * Called by the system to transmit a packet  - we queue the packet in
+ * EMAC hardware transmit queue
+ *
+ * Returns success(NETDEV_TX_OK) or error code (typically out of desc's)
+ */
+static int emac_dev_xmit(struct sk_buff *skb, struct net_device *ndev)
+{
+       struct device *emac_dev = &ndev->dev;
+       int ret_code;
+       struct emac_netbufobj tx_buf; /* buffer obj-only single frame support */
+       struct emac_netpktobj tx_packet;  /* packet object */
+       struct emac_priv *priv = netdev_priv(ndev);
+
+       /* If no link, return */
+       if (unlikely(!priv->link)) {
+               if (netif_msg_tx_err(priv) && net_ratelimit())
+                       dev_err(emac_dev, "DaVinci EMAC: No link to transmit");
+               return NETDEV_TX_BUSY;
+       }
+
+       /* Build the buffer and packet objects - Since only single fragment is
+        * supported, need not set length and token in both packet & object.
+        * Doing so for completeness sake & to show that this needs to be done
+        * in multifragment case
+        */
+       tx_packet.buf_list = &tx_buf;
+       tx_packet.num_bufs = 1; /* only single fragment supported */
+       tx_packet.pkt_length = skb->len;
+       tx_packet.pkt_token = (void *)skb;
+       tx_buf.length = skb->len;
+       tx_buf.buf_token = (void *)skb;
+       tx_buf.data_ptr = skb->data;
+       EMAC_CACHE_WRITEBACK((unsigned long)skb->data, skb->len);
+       ndev->trans_start = jiffies;
+       ret_code = emac_send(priv, &tx_packet, EMAC_DEF_TX_CH);
+       if (unlikely(ret_code != 0)) {
+               if (ret_code == EMAC_ERR_TX_OUT_OF_BD) {
+                       if (netif_msg_tx_err(priv) && net_ratelimit())
+                               dev_err(emac_dev, "DaVinci EMAC: xmit() fatal"\
+                                       " err. Out of TX BD's");
+                       netif_stop_queue(priv->ndev);
+               }
+               priv->net_dev_stats.tx_dropped++;
+               return NETDEV_TX_BUSY;
+       }
+
+       return NETDEV_TX_OK;
+}
+
+/**
+ * emac_dev_tx_timeout: EMAC Transmit timeout function
+ * @ndev: The DaVinci EMAC network adapter
+ *
+ * Called when system detects that a skb timeout period has expired
+ * potentially due to a fault in the adapter in not being able to send
+ * it out on the wire. We teardown the TX channel assuming a hardware
+ * error and re-initialize the TX channel for hardware operation
+ *
+ */
+static void emac_dev_tx_timeout(struct net_device *ndev)
+{
+       struct emac_priv *priv = netdev_priv(ndev);
+       struct device *emac_dev = &ndev->dev;
+
+       if (netif_msg_tx_err(priv))
+               dev_err(emac_dev, "DaVinci EMAC: xmit timeout, restarting TX");
+
+       priv->net_dev_stats.tx_errors++;
+       emac_int_disable(priv);
+       emac_stop_txch(priv, EMAC_DEF_TX_CH);
+       emac_cleanup_txch(priv, EMAC_DEF_TX_CH);
+       emac_init_txch(priv, EMAC_DEF_TX_CH);
+       emac_write(EMAC_TXHDP(0), 0);
+       emac_write(EMAC_TXINTMASKSET, BIT(EMAC_DEF_TX_CH));
+       emac_int_enable(priv);
+}
+
+/**
+ * emac_net_alloc_rx_buf: Allocate a skb for RX
+ * @priv: The DaVinci EMAC private adapter structure
+ * @buf_size: size of SKB data buffer to allocate
+ * @data_token: data token returned (skb handle for storing in buffer desc)
+ * @ch: RX channel number
+ *
+ * Called during RX channel setup - allocates skb buffer of required size
+ * and provides the skb handle and allocated buffer data pointer to caller
+ *
+ * Returns skb data pointer or 0 on failure to alloc skb
+ */
+static void *emac_net_alloc_rx_buf(struct emac_priv *priv, int buf_size,
+               void **data_token, u32 ch)
+{
+       struct net_device *ndev = priv->ndev;
+       struct device *emac_dev = &ndev->dev;
+       struct sk_buff *p_skb;
+
+       p_skb = dev_alloc_skb(buf_size);
+       if (unlikely(NULL == p_skb)) {
+               if (netif_msg_rx_err(priv) && net_ratelimit())
+                       dev_err(emac_dev, "DaVinci EMAC: failed to alloc skb");
+               return NULL;
+       }
+
+       /* set device pointer in skb and reserve space for extra bytes */
+       p_skb->dev = ndev;
+       skb_reserve(p_skb, NET_IP_ALIGN);
+       *data_token = (void *) p_skb;
+       EMAC_CACHE_WRITEBACK_INVALIDATE((unsigned long)p_skb->data, buf_size);
+       return p_skb->data;
+}
+
+/**
+ * emac_init_rxch: RX channel initialization
+ * @priv: The DaVinci EMAC private adapter structure
+ * @ch: RX channel number
+ * @param: mac address for RX channel
+ *
+ * Called during device init to setup a RX channel (allocate buffers and
+ * buffer descriptors, create queue and keep ready for reception
+ *
+ * Returns success(0) or mem alloc failures error code
+ */
+static int emac_init_rxch(struct emac_priv *priv, u32 ch, char *param)
+{
+       struct device *emac_dev = &priv->ndev->dev;
+       u32 cnt, bd_size;
+       void __iomem *mem;
+       struct emac_rx_bd __iomem *curr_bd;
+       struct emac_rxch *rxch = NULL;
+
+       rxch = kzalloc(sizeof(struct emac_rxch), GFP_KERNEL);
+       if (NULL == rxch) {
+               dev_err(emac_dev, "DaVinci EMAC: RX Ch mem alloc failed");
+               return -ENOMEM;
+       }
+       priv->rxch[ch] = rxch;
+       rxch->buf_size = priv->rx_buf_size;
+       rxch->service_max = EMAC_DEF_RX_MAX_SERVICE;
+       rxch->queue_active = 0;
+       rxch->teardown_pending = 0;
+
+       /* save mac address */
+       for (cnt = 0; cnt < 6; cnt++)
+               rxch->mac_addr[cnt] = param[cnt];
+
+       /* allocate buffer descriptor pool align every BD on four word
+        * boundry for future requirements */
+       bd_size = (sizeof(struct emac_rx_bd) + 0xF) & ~0xF;
+       rxch->num_bd = (priv->ctrl_ram_size >> 1) / bd_size;
+       rxch->alloc_size = (((bd_size * rxch->num_bd) + 0xF) & ~0xF);
+       rxch->bd_mem = EMAC_RX_BD_MEM(priv);
+       __memzero((void __force *)rxch->bd_mem, rxch->alloc_size);
+       rxch->pkt_queue.buf_list = &rxch->buf_queue;
+
+       /* allocate RX buffer and initialize the BD linked list */
+       mem = (void __force __iomem *)
+                       (((u32 __force) rxch->bd_mem + 0xF) & ~0xF);
+       rxch->active_queue_head = NULL;
+       rxch->active_queue_tail = mem;
+       for (cnt = 0; cnt < rxch->num_bd; cnt++) {
+               curr_bd = mem + (cnt * bd_size);
+               /* for future use the last parameter contains the BD ptr */
+               curr_bd->data_ptr = emac_net_alloc_rx_buf(priv,
+                                   rxch->buf_size,
+                                   (void __force **)&curr_bd->buf_token,
+                                   EMAC_DEF_RX_CH);
+               if (curr_bd->data_ptr == NULL) {
+                       dev_err(emac_dev, "DaVinci EMAC: RX buf mem alloc " \
+                               "failed for ch %d\n", ch);
+                       kfree(rxch);
+                       return -ENOMEM;
+               }
+
+               /* populate the hardware descriptor */
+               curr_bd->h_next = emac_virt_to_phys(rxch->active_queue_head);
+               /* FIXME buff_ptr = dma_map_single(... data_ptr ...) */
+               curr_bd->buff_ptr = virt_to_phys(curr_bd->data_ptr);
+               curr_bd->off_b_len = rxch->buf_size;
+               curr_bd->mode = EMAC_CPPI_OWNERSHIP_BIT;
+
+               /* write back to hardware memory */
+               BD_CACHE_WRITEBACK_INVALIDATE((u32) curr_bd,
+                                             EMAC_BD_LENGTH_FOR_CACHE);
+               curr_bd->next = rxch->active_queue_head;
+               rxch->active_queue_head = curr_bd;
+       }
+
+       /* At this point rxCppi->activeQueueHead points to the first
+          RX BD ready to be given to RX HDP and rxch->active_queue_tail
+          points to the last RX BD
+        */
+       return 0;
+}
+
+/**
+ * emac_rxch_teardown: RX channel teardown
+ * @priv: The DaVinci EMAC private adapter structure
+ * @ch: RX channel number
+ *
+ * Called during device stop to teardown RX channel
+ *
+ */
+static void emac_rxch_teardown(struct emac_priv *priv, u32 ch)
+{
+       struct device *emac_dev = &priv->ndev->dev;
+       u32 teardown_cnt = 0xFFFFFFF0; /* Some high value */
+
+       while ((emac_read(EMAC_RXCP(ch)) & EMAC_TEARDOWN_VALUE) !=
+              EMAC_TEARDOWN_VALUE) {
+               /* wait till tx teardown complete */
+               cpu_relax(); /* TODO: check if this helps ... */
+               --teardown_cnt;
+               if (0 == teardown_cnt) {
+                       dev_err(emac_dev, "EMAC: RX teardown aborted\n");
+                       break;
+               }
+       }
+       emac_write(EMAC_RXCP(ch), EMAC_TEARDOWN_VALUE);
+}
+
+/**
+ * emac_stop_rxch: Stop RX channel operation
+ * @priv: The DaVinci EMAC private adapter structure
+ * @ch: RX channel number
+ *
+ * Called during device stop to stop RX channel operation
+ *
+ */
+static void emac_stop_rxch(struct emac_priv *priv, u32 ch)
+{
+       struct emac_rxch *rxch = priv->rxch[ch];
+
+       if (rxch) {
+               rxch->teardown_pending = 1;
+               emac_write(EMAC_RXTEARDOWN, ch);
+               /* wait for teardown complete */
+               emac_rxch_teardown(priv, ch);
+               rxch->teardown_pending = 0;
+               emac_write(EMAC_RXINTMASKCLEAR, BIT(ch));
+       }
+}
+
+/**
+ * emac_cleanup_rxch: Book-keep function to clean RX channel resources
+ * @priv: The DaVinci EMAC private adapter structure
+ * @ch: RX channel number
+ *
+ * Called during device stop to clean up RX channel resources
+ *
+ */
+static void emac_cleanup_rxch(struct emac_priv *priv, u32 ch)
+{
+       struct emac_rxch *rxch = priv->rxch[ch];
+       struct emac_rx_bd __iomem *curr_bd;
+
+       if (rxch) {
+               /* free the receive buffers previously allocated */
+               curr_bd = rxch->active_queue_head;
+               while (curr_bd) {
+                       if (curr_bd->buf_token) {
+                               dev_kfree_skb_any((struct sk_buff *)\
+                                                 curr_bd->buf_token);
+                       }
+                       curr_bd = curr_bd->next;
+               }
+               if (rxch->bd_mem)
+                       rxch->bd_mem = NULL;
+               kfree(rxch);
+               priv->rxch[ch] = NULL;
+       }
+}
+
+/**
+ * emac_set_type0addr: Set EMAC Type0 mac address
+ * @priv: The DaVinci EMAC private adapter structure
+ * @ch: RX channel number
+ * @mac_addr: MAC address to set in device
+ *
+ * Called internally to set Type0 mac address of the adapter (Device)
+ *
+ * Returns success (0) or appropriate error code (none as of now)
+ */
+static void emac_set_type0addr(struct emac_priv *priv, u32 ch, char *mac_addr)
+{
+       u32 val;
+       val = ((mac_addr[5] << 8) | (mac_addr[4]));
+       emac_write(EMAC_MACSRCADDRLO, val);
+
+       val = ((mac_addr[3] << 24) | (mac_addr[2] << 16) | \
+              (mac_addr[1] << 8) | (mac_addr[0]));
+       emac_write(EMAC_MACSRCADDRHI, val);
+       val = emac_read(EMAC_RXUNICASTSET);
+       val |= BIT(ch);
+       emac_write(EMAC_RXUNICASTSET, val);
+       val = emac_read(EMAC_RXUNICASTCLEAR);
+       val &= ~BIT(ch);
+       emac_write(EMAC_RXUNICASTCLEAR, val);
+}
+
+/**
+ * emac_set_type1addr: Set EMAC Type1 mac address
+ * @priv: The DaVinci EMAC private adapter structure
+ * @ch: RX channel number
+ * @mac_addr: MAC address to set in device
+ *
+ * Called internally to set Type1 mac address of the adapter (Device)
+ *
+ * Returns success (0) or appropriate error code (none as of now)
+ */
+static void emac_set_type1addr(struct emac_priv *priv, u32 ch, char *mac_addr)
+{
+       u32 val;
+       emac_write(EMAC_MACINDEX, ch);
+       val = ((mac_addr[5] << 8) | mac_addr[4]);
+       emac_write(EMAC_MACADDRLO, val);
+       val = ((mac_addr[3] << 24) | (mac_addr[2] << 16) | \
+              (mac_addr[1] << 8) | (mac_addr[0]));
+       emac_write(EMAC_MACADDRHI, val);
+       emac_set_type0addr(priv, ch, mac_addr);
+}
+
+/**
+ * emac_set_type2addr: Set EMAC Type2 mac address
+ * @priv: The DaVinci EMAC private adapter structure
+ * @ch: RX channel number
+ * @mac_addr: MAC address to set in device
+ * @index: index into RX address entries
+ * @match: match parameter for RX address matching logic
+ *
+ * Called internally to set Type2 mac address of the adapter (Device)
+ *
+ * Returns success (0) or appropriate error code (none as of now)
+ */
+static void emac_set_type2addr(struct emac_priv *priv, u32 ch,
+                              char *mac_addr, int index, int match)
+{
+       u32 val;
+       emac_write(EMAC_MACINDEX, index);
+       val = ((mac_addr[3] << 24) | (mac_addr[2] << 16) | \
+              (mac_addr[1] << 8) | (mac_addr[0]));
+       emac_write(EMAC_MACADDRHI, val);
+       val = ((mac_addr[5] << 8) | mac_addr[4] | ((ch & 0x7) << 16) | \
+              (match << 19) | BIT(20));
+       emac_write(EMAC_MACADDRLO, val);
+       emac_set_type0addr(priv, ch, mac_addr);
+}
+
+/**
+ * emac_setmac: Set mac address in the adapter (internal function)
+ * @priv: The DaVinci EMAC private adapter structure
+ * @ch: RX channel number
+ * @mac_addr: MAC address to set in device
+ *
+ * Called internally to set the mac address of the adapter (Device)
+ *
+ * Returns success (0) or appropriate error code (none as of now)
+ */
+static void emac_setmac(struct emac_priv *priv, u32 ch, char *mac_addr)
+{
+       struct device *emac_dev = &priv->ndev->dev;
+
+       if (priv->rx_addr_type == 0) {
+               emac_set_type0addr(priv, ch, mac_addr);
+       } else if (priv->rx_addr_type == 1) {
+               u32 cnt;
+               for (cnt = 0; cnt < EMAC_MAX_TXRX_CHANNELS; cnt++)
+                       emac_set_type1addr(priv, ch, mac_addr);
+       } else if (priv->rx_addr_type == 2) {
+               emac_set_type2addr(priv, ch, mac_addr, ch, 1);
+               emac_set_type0addr(priv, ch, mac_addr);
+       } else {
+               if (netif_msg_drv(priv))
+                       dev_err(emac_dev, "DaVinci EMAC: Wrong addressing\n");
+       }
+}
+
+/**
+ * emac_dev_setmac_addr: Set mac address in the adapter
+ * @ndev: The DaVinci EMAC network adapter
+ * @addr: MAC address to set in device
+ *
+ * Called by the system to set the mac address of the adapter (Device)
+ *
+ * Returns success (0) or appropriate error code (none as of now)
+ */
+static int emac_dev_setmac_addr(struct net_device *ndev, void *addr)
+{
+       struct emac_priv *priv = netdev_priv(ndev);
+       struct emac_rxch *rxch = priv->rxch[EMAC_DEF_RX_CH];
+       struct device *emac_dev = &priv->ndev->dev;
+       struct sockaddr *sa = addr;
+
+       /* Store mac addr in priv and rx channel and set it in EMAC hw */
+       memcpy(priv->mac_addr, sa->sa_data, ndev->addr_len);
+       memcpy(rxch->mac_addr, sa->sa_data, ndev->addr_len);
+       memcpy(ndev->dev_addr, sa->sa_data, ndev->addr_len);
+       emac_setmac(priv, EMAC_DEF_RX_CH, rxch->mac_addr);
+
+       if (netif_msg_drv(priv))
+               dev_notice(emac_dev, "DaVinci EMAC: emac_dev_setmac_addr %pM\n",
+                                       priv->mac_addr);
+
+       return 0;
+}
+
+/**
+ * emac_addbd_to_rx_queue: Recycle RX buffer descriptor
+ * @priv: The DaVinci EMAC private adapter structure
+ * @ch: RX channel number to process buffer descriptors for
+ * @curr_bd: current buffer descriptor
+ * @buffer: buffer pointer for descriptor
+ * @buf_token: buffer token (stores skb information)
+ *
+ * Prepares the recycled buffer descriptor and addes it to hardware
+ * receive queue - if queue empty this descriptor becomes the head
+ * else addes the descriptor to end of queue
+ *
+ */
+static void emac_addbd_to_rx_queue(struct emac_priv *priv, u32 ch,
+               struct emac_rx_bd __iomem *curr_bd,
+               char *buffer, void *buf_token)
+{
+       struct emac_rxch *rxch = priv->rxch[ch];
+
+       /* populate the hardware descriptor */
+       curr_bd->h_next = 0;
+       /* FIXME buff_ptr = dma_map_single(... buffer ...) */
+       curr_bd->buff_ptr = virt_to_phys(buffer);
+       curr_bd->off_b_len = rxch->buf_size;
+       curr_bd->mode = EMAC_CPPI_OWNERSHIP_BIT;
+       curr_bd->next = NULL;
+       curr_bd->data_ptr = buffer;
+       curr_bd->buf_token = buf_token;
+
+       /* write back  */
+       BD_CACHE_WRITEBACK_INVALIDATE(curr_bd, EMAC_BD_LENGTH_FOR_CACHE);
+       if (rxch->active_queue_head == NULL) {
+               rxch->active_queue_head = curr_bd;
+               rxch->active_queue_tail = curr_bd;
+               if (0 != rxch->queue_active) {
+                       emac_write(EMAC_RXHDP(ch),
+                                  emac_virt_to_phys(rxch->active_queue_head));
+                       rxch->queue_active = 1;
+               }
+       } else {
+               struct emac_rx_bd __iomem *tail_bd;
+               u32 frame_status;
+
+               tail_bd = rxch->active_queue_tail;
+               rxch->active_queue_tail = curr_bd;
+               tail_bd->next = curr_bd;
+               tail_bd = EMAC_VIRT_NOCACHE(tail_bd);
+               tail_bd->h_next = emac_virt_to_phys(curr_bd);
+               frame_status = tail_bd->mode;
+               if (frame_status & EMAC_CPPI_EOQ_BIT) {
+                       emac_write(EMAC_RXHDP(ch),
+                                       emac_virt_to_phys(curr_bd));
+                       frame_status &= ~(EMAC_CPPI_EOQ_BIT);
+                       tail_bd->mode = frame_status;
+                       ++rxch->end_of_queue_add;
+               }
+       }
+       ++rxch->recycled_bd;
+}
+
+/**
+ * emac_net_rx_cb: Prepares packet and sends to upper layer
+ * @priv: The DaVinci EMAC private adapter structure
+ * @net_pkt_list: Network packet list (received packets)
+ *
+ * Invalidates packet buffer memory and sends the received packet to upper
+ * layer
+ *
+ * Returns success or appropriate error code (none as of now)
+ */
+static int emac_net_rx_cb(struct emac_priv *priv,
+                         struct emac_netpktobj *net_pkt_list)
+{
+       struct sk_buff *p_skb;
+       p_skb = (struct sk_buff *)net_pkt_list->pkt_token;
+       /* set length of packet */
+       skb_put(p_skb, net_pkt_list->pkt_length);
+       EMAC_CACHE_INVALIDATE((unsigned long)p_skb->data, p_skb->len);
+       p_skb->protocol = eth_type_trans(p_skb, priv->ndev);
+       p_skb->dev->last_rx = jiffies;
+       netif_receive_skb(p_skb);
+       priv->net_dev_stats.rx_bytes += net_pkt_list->pkt_length;
+       priv->net_dev_stats.rx_packets++;
+       return 0;
+}
+
+/**
+ * emac_rx_bdproc: RX buffer descriptor (packet) processing
+ * @priv: The DaVinci EMAC private adapter structure
+ * @ch: RX channel number to process buffer descriptors for
+ * @budget: number of packets allowed to process
+ * @pending: indication to caller that packets are pending to process
+ *
+ * Processes RX buffer descriptors - checks ownership bit on the RX buffer
+ * descriptor, sends the receive packet to upper layer, allocates a new SKB
+ * and recycles the buffer descriptor (requeues it in hardware RX queue).
+ * Only "budget" number of packets are processed and indication of pending
+ * packets provided to the caller.
+ *
+ * Returns number of packets processed (and indication of pending packets)
+ */
+static int emac_rx_bdproc(struct emac_priv *priv, u32 ch, u32 budget)
+{
+       unsigned long flags;
+       u32 frame_status;
+       u32 pkts_processed = 0;
+       char *new_buffer;
+       struct emac_rx_bd __iomem *curr_bd;
+       struct emac_rx_bd __iomem *last_bd;
+       struct emac_netpktobj *curr_pkt, pkt_obj;
+       struct emac_netbufobj buf_obj;
+       struct emac_netbufobj *rx_buf_obj;
+       void *new_buf_token;
+       struct emac_rxch *rxch = priv->rxch[ch];
+
+       if (unlikely(1 == rxch->teardown_pending))
+               return 0;
+       ++rxch->proc_count;
+       spin_lock_irqsave(&priv->rx_lock, flags);
+       pkt_obj.buf_list = &buf_obj;
+       curr_pkt = &pkt_obj;
+       curr_bd = rxch->active_queue_head;
+       BD_CACHE_INVALIDATE(curr_bd, EMAC_BD_LENGTH_FOR_CACHE);
+       frame_status = curr_bd->mode;
+
+       while ((curr_bd) &&
+              ((frame_status & EMAC_CPPI_OWNERSHIP_BIT) == 0) &&
+              (pkts_processed < budget)) {
+
+               new_buffer = emac_net_alloc_rx_buf(priv, rxch->buf_size,
+                                       &new_buf_token, EMAC_DEF_RX_CH);
+               if (unlikely(NULL == new_buffer)) {
+                       ++rxch->out_of_rx_buffers;
+                       goto end_emac_rx_bdproc;
+               }
+
+               /* populate received packet data structure */
+               rx_buf_obj = &curr_pkt->buf_list[0];
+               rx_buf_obj->data_ptr = (char *)curr_bd->data_ptr;
+               rx_buf_obj->length = curr_bd->off_b_len & EMAC_RX_BD_BUF_SIZE;
+               rx_buf_obj->buf_token = curr_bd->buf_token;
+               curr_pkt->pkt_token = curr_pkt->buf_list->buf_token;
+               curr_pkt->num_bufs = 1;
+               curr_pkt->pkt_length =
+                       (frame_status & EMAC_RX_BD_PKT_LENGTH_MASK);
+               emac_write(EMAC_RXCP(ch), emac_virt_to_phys(curr_bd));
+               ++rxch->processed_bd;
+               last_bd = curr_bd;
+               curr_bd = last_bd->next;
+               rxch->active_queue_head = curr_bd;
+
+               /* check if end of RX queue ? */
+               if (frame_status & EMAC_CPPI_EOQ_BIT) {
+                       if (curr_bd) {
+                               ++rxch->mis_queued_packets;
+                               emac_write(EMAC_RXHDP(ch),
+                                          emac_virt_to_phys(curr_bd));
+                       } else {
+                               ++rxch->end_of_queue;
+                               rxch->queue_active = 0;
+                       }
+               }
+
+               /* recycle BD */
+               emac_addbd_to_rx_queue(priv, ch, last_bd, new_buffer,
+                                      new_buf_token);
+
+               /* return the packet to the user - BD ptr passed in
+                * last parameter for potential *future* use */
+               spin_unlock_irqrestore(&priv->rx_lock, flags);
+               emac_net_rx_cb(priv, curr_pkt);
+               spin_lock_irqsave(&priv->rx_lock, flags);
+               curr_bd = rxch->active_queue_head;
+               if (curr_bd) {
+                       BD_CACHE_INVALIDATE(curr_bd, EMAC_BD_LENGTH_FOR_CACHE);
+                       frame_status = curr_bd->mode;
+               }
+               ++pkts_processed;
+       }
+
+end_emac_rx_bdproc:
+       spin_unlock_irqrestore(&priv->rx_lock, flags);
+       return pkts_processed;
+}
+
+/**
+ * emac_hw_enable: Enable EMAC hardware for packet transmission/reception
+ * @priv: The DaVinci EMAC private adapter structure
+ *
+ * Enables EMAC hardware for packet processing - enables PHY, enables RX
+ * for packet reception and enables device interrupts and then NAPI
+ *
+ * Returns success (0) or appropriate error code (none right now)
+ */
+static int emac_hw_enable(struct emac_priv *priv)
+{
+       u32 ch, val, mbp_enable, mac_control;
+
+       /* Soft reset */
+       emac_write(EMAC_SOFTRESET, 1);
+       while (emac_read(EMAC_SOFTRESET))
+               cpu_relax();
+
+       /* Disable interrupt & Set pacing for more interrupts initially */
+       emac_int_disable(priv);
+
+       /* Full duplex enable bit set when auto negotiation happens */
+       mac_control =
+               (((EMAC_DEF_TXPRIO_FIXED) ? (EMAC_MACCONTROL_TXPTYPE) : 0x0) |
+               ((priv->speed == 1000) ? EMAC_MACCONTROL_GIGABITEN : 0x0) |
+               ((EMAC_DEF_TXPACING_EN) ? (EMAC_MACCONTROL_TXPACEEN) : 0x0) |
+               ((priv->duplex == DUPLEX_FULL) ? 0x1 : 0));
+       emac_write(EMAC_MACCONTROL, mac_control);
+
+       mbp_enable =
+               (((EMAC_DEF_PASS_CRC) ? (EMAC_RXMBP_PASSCRC_MASK) : 0x0) |
+               ((EMAC_DEF_QOS_EN) ? (EMAC_RXMBP_QOSEN_MASK) : 0x0) |
+                ((EMAC_DEF_NO_BUFF_CHAIN) ? (EMAC_RXMBP_NOCHAIN_MASK) : 0x0) |
+                ((EMAC_DEF_MACCTRL_FRAME_EN) ? (EMAC_RXMBP_CMFEN_MASK) : 0x0) |
+                ((EMAC_DEF_SHORT_FRAME_EN) ? (EMAC_RXMBP_CSFEN_MASK) : 0x0) |
+                ((EMAC_DEF_ERROR_FRAME_EN) ? (EMAC_RXMBP_CEFEN_MASK) : 0x0) |
+                ((EMAC_DEF_PROM_EN) ? (EMAC_RXMBP_CAFEN_MASK) : 0x0) |
+                ((EMAC_DEF_PROM_CH & EMAC_RXMBP_CHMASK) << \
+                       EMAC_RXMBP_PROMCH_SHIFT) |
+                ((EMAC_DEF_BCAST_EN) ? (EMAC_RXMBP_BROADEN_MASK) : 0x0) |
+                ((EMAC_DEF_BCAST_CH & EMAC_RXMBP_CHMASK) << \
+                       EMAC_RXMBP_BROADCH_SHIFT) |
+                ((EMAC_DEF_MCAST_EN) ? (EMAC_RXMBP_MULTIEN_MASK) : 0x0) |
+                ((EMAC_DEF_MCAST_CH & EMAC_RXMBP_CHMASK) << \
+                       EMAC_RXMBP_MULTICH_SHIFT));
+       emac_write(EMAC_RXMBPENABLE, mbp_enable);
+       emac_write(EMAC_RXMAXLEN, (EMAC_DEF_MAX_FRAME_SIZE &
+                                  EMAC_RX_MAX_LEN_MASK));
+       emac_write(EMAC_RXBUFFEROFFSET, (EMAC_DEF_BUFFER_OFFSET &
+                                        EMAC_RX_BUFFER_OFFSET_MASK));
+       emac_write(EMAC_RXFILTERLOWTHRESH, 0);
+       emac_write(EMAC_RXUNICASTCLEAR, EMAC_RX_UNICAST_CLEAR_ALL);
+       priv->rx_addr_type = (emac_read(EMAC_MACCONFIG) >> 8) & 0xFF;
+
+       val = emac_read(EMAC_TXCONTROL);
+       val |= EMAC_TX_CONTROL_TX_ENABLE_VAL;
+       emac_write(EMAC_TXCONTROL, val);
+       val = emac_read(EMAC_RXCONTROL);
+       val |= EMAC_RX_CONTROL_RX_ENABLE_VAL;
+       emac_write(EMAC_RXCONTROL, val);
+       emac_write(EMAC_MACINTMASKSET, EMAC_MAC_HOST_ERR_INTMASK_VAL);
+
+       for (ch = 0; ch < EMAC_DEF_MAX_TX_CH; ch++) {
+               emac_write(EMAC_TXHDP(ch), 0);
+               emac_write(EMAC_TXINTMASKSET, BIT(ch));
+       }
+       for (ch = 0; ch < EMAC_DEF_MAX_RX_CH; ch++) {
+               struct emac_rxch *rxch = priv->rxch[ch];
+               emac_setmac(priv, ch, rxch->mac_addr);
+               emac_write(EMAC_RXINTMASKSET, BIT(ch));
+               rxch->queue_active = 1;
+               emac_write(EMAC_RXHDP(ch),
+                          emac_virt_to_phys(rxch->active_queue_head));
+       }
+
+       /* Enable MII */
+       val = emac_read(EMAC_MACCONTROL);
+       val |= (EMAC_MACCONTROL_MIIEN);
+       emac_write(EMAC_MACCONTROL, val);
+
+       /* Enable NAPI and interrupts */
+       napi_enable(&priv->napi);
+       emac_int_enable(priv);
+       return 0;
+
+}
+
+/**
+ * emac_poll: EMAC NAPI Poll function
+ * @ndev: The DaVinci EMAC network adapter
+ * @budget: Number of receive packets to process (as told by NAPI layer)
+ *
+ * NAPI Poll function implemented to process packets as per budget. We check
+ * the type of interrupt on the device and accordingly call the TX or RX
+ * packet processing functions. We follow the budget for RX processing and
+ * also put a cap on number of TX pkts processed through config param. The
+ * NAPI schedule function is called if more packets pending.
+ *
+ * Returns number of packets received (in most cases; else TX pkts - rarely)
+ */
+static int emac_poll(struct napi_struct *napi, int budget)
+{
+       unsigned int mask;
+       struct emac_priv *priv = container_of(napi, struct emac_priv, napi);
+       struct net_device *ndev = priv->ndev;
+       struct device *emac_dev = &ndev->dev;
+       u32 status = 0;
+       u32 num_pkts = 0;
+
+       if (!netif_running(ndev))
+               return 0;
+
+       /* Check interrupt vectors and call packet processing */
+       status = emac_read(EMAC_MACINVECTOR);
+
+       mask = EMAC_DM644X_MAC_IN_VECTOR_TX_INT_VEC;
+
+       if (priv->version == EMAC_VERSION_2)
+               mask = EMAC_DM646X_MAC_IN_VECTOR_TX_INT_VEC;
+
+       if (status & mask) {
+               num_pkts = emac_tx_bdproc(priv, EMAC_DEF_TX_CH,
+                                         EMAC_DEF_TX_MAX_SERVICE);
+       } /* TX processing */
+
+       if (num_pkts)
+               return budget;
+
+       mask = EMAC_DM644X_MAC_IN_VECTOR_RX_INT_VEC;
+
+       if (priv->version == EMAC_VERSION_2)
+               mask = EMAC_DM646X_MAC_IN_VECTOR_RX_INT_VEC;
+
+       if (status & mask) {
+               num_pkts = emac_rx_bdproc(priv, EMAC_DEF_RX_CH, budget);
+       } /* RX processing */
+
+       if (num_pkts < budget) {
+               napi_complete(napi);
+               emac_int_enable(priv);
+       }
+
+       if (unlikely(status & EMAC_DM644X_MAC_IN_VECTOR_HOST_INT)) {
+               u32 ch, cause;
+               dev_err(emac_dev, "DaVinci EMAC: Fatal Hardware Error\n");
+               netif_stop_queue(ndev);
+               napi_disable(&priv->napi);
+
+               status = emac_read(EMAC_MACSTATUS);
+               cause = ((status & EMAC_MACSTATUS_TXERRCODE_MASK) >>
+                        EMAC_MACSTATUS_TXERRCODE_SHIFT);
+               if (cause) {
+                       ch = ((status & EMAC_MACSTATUS_TXERRCH_MASK) >>
+                             EMAC_MACSTATUS_TXERRCH_SHIFT);
+                       if (net_ratelimit()) {
+                               dev_err(emac_dev, "TX Host error %s on ch=%d\n",
+                                       &emac_txhost_errcodes[cause][0], ch);
+                       }
+               }
+               cause = ((status & EMAC_MACSTATUS_RXERRCODE_MASK) >>
+                        EMAC_MACSTATUS_RXERRCODE_SHIFT);
+               if (cause) {
+                       ch = ((status & EMAC_MACSTATUS_RXERRCH_MASK) >>
+                             EMAC_MACSTATUS_RXERRCH_SHIFT);
+                       if (netif_msg_hw(priv) && net_ratelimit())
+                               dev_err(emac_dev, "RX Host error %s on ch=%d\n",
+                                       &emac_rxhost_errcodes[cause][0], ch);
+               }
+       } /* Host error processing */
+
+       return num_pkts;
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+/**
+ * emac_poll_controller: EMAC Poll controller function
+ * @ndev: The DaVinci EMAC network adapter
+ *
+ * Polled functionality used by netconsole and others in non interrupt mode
+ *
+ */
+void emac_poll_controller(struct net_device *ndev)
+{
+       struct emac_priv *priv = netdev_priv(ndev);
+
+       emac_int_disable(priv);
+       emac_irq(ndev->irq, priv);
+       emac_int_enable(priv);
+}
+#endif
+
+/* PHY/MII bus related */
+
+/* Wait until mdio is ready for next command */
+#define MDIO_WAIT_FOR_USER_ACCESS\
+               while ((emac_mdio_read((MDIO_USERACCESS(0))) &\
+                       MDIO_USERACCESS_GO) != 0)
+
+static int emac_mii_read(struct mii_bus *bus, int phy_id, int phy_reg)
+{
+       unsigned int phy_data = 0;
+       unsigned int phy_control;
+
+       /* Wait until mdio is ready for next command */
+       MDIO_WAIT_FOR_USER_ACCESS;
+
+       phy_control = (MDIO_USERACCESS_GO |
+                      MDIO_USERACCESS_READ |
+                      ((phy_reg << 21) & MDIO_USERACCESS_REGADR) |
+                      ((phy_id << 16) & MDIO_USERACCESS_PHYADR) |
+                      (phy_data & MDIO_USERACCESS_DATA));
+       emac_mdio_write(MDIO_USERACCESS(0), phy_control);
+
+       /* Wait until mdio is ready for next command */
+       MDIO_WAIT_FOR_USER_ACCESS;
+
+       return emac_mdio_read(MDIO_USERACCESS(0)) & MDIO_USERACCESS_DATA;
+
+}
+
+static int emac_mii_write(struct mii_bus *bus, int phy_id,
+                         int phy_reg, u16 phy_data)
+{
+
+       unsigned int control;
+
+       /*  until mdio is ready for next command */
+       MDIO_WAIT_FOR_USER_ACCESS;
+
+       control = (MDIO_USERACCESS_GO |
+                  MDIO_USERACCESS_WRITE |
+                  ((phy_reg << 21) & MDIO_USERACCESS_REGADR) |
+                  ((phy_id << 16) & MDIO_USERACCESS_PHYADR) |
+                  (phy_data & MDIO_USERACCESS_DATA));
+       emac_mdio_write(MDIO_USERACCESS(0), control);
+
+       return 0;
+}
+
+static int emac_mii_reset(struct mii_bus *bus)
+{
+       unsigned int clk_div;
+       int mdio_bus_freq = emac_bus_frequency;
+
+       if (mdio_max_freq & mdio_bus_freq)
+               clk_div = ((mdio_bus_freq / mdio_max_freq) - 1);
+       else
+               clk_div = 0xFF;
+
+       clk_div &= MDIO_CONTROL_CLKDIV;
+
+       /* Set enable and clock divider in MDIOControl */
+       emac_mdio_write(MDIO_CONTROL, (clk_div | MDIO_CONTROL_ENABLE));
+
+       return 0;
+
+}
+
+static int mii_irqs[PHY_MAX_ADDR] = { PHY_POLL, PHY_POLL };
+
+/* emac_driver: EMAC MII bus structure */
+
+static struct mii_bus *emac_mii;
+
+static void emac_adjust_link(struct net_device *ndev)
+{
+       struct emac_priv *priv = netdev_priv(ndev);
+       struct phy_device *phydev = priv->phydev;
+       unsigned long flags;
+       int new_state = 0;
+
+       spin_lock_irqsave(&priv->lock, flags);
+
+       if (phydev->link) {
+               /* check the mode of operation - full/half duplex */
+               if (phydev->duplex != priv->duplex) {
+                       new_state = 1;
+                       priv->duplex = phydev->duplex;
+               }
+               if (phydev->speed != priv->speed) {
+                       new_state = 1;
+                       priv->speed = phydev->speed;
+               }
+               if (!priv->link) {
+                       new_state = 1;
+                       priv->link = 1;
+               }
+
+       } else if (priv->link) {
+               new_state = 1;
+               priv->link = 0;
+               priv->speed = 0;
+               priv->duplex = ~0;
+       }
+       if (new_state) {
+               emac_update_phystatus(priv);
+               phy_print_status(priv->phydev);
+       }
+
+       spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+/*************************************************************************
+ *  Linux Driver Model
+ *************************************************************************/
+
+/**
+ * emac_devioctl: EMAC adapter ioctl
+ * @ndev: The DaVinci EMAC network adapter
+ * @ifrq: request parameter
+ * @cmd: command parameter
+ *
+ * EMAC driver ioctl function
+ *
+ * Returns success(0) or appropriate error code
+ */
+static int emac_devioctl(struct net_device *ndev, struct ifreq *ifrq, int cmd)
+{
+       dev_warn(&ndev->dev, "DaVinci EMAC: ioctl not supported\n");
+
+       if (!(netif_running(ndev)))
+               return -EINVAL;
+
+       /* TODO: Add phy read and write and private statistics get feature */
+
+       return -EOPNOTSUPP;
+}
+
+/**
+ * emac_dev_open: EMAC device open
+ * @ndev: The DaVinci EMAC network adapter
+ *
+ * Called when system wants to start the interface. We init TX/RX channels
+ * and enable the hardware for packet reception/transmission and start the
+ * network queue.
+ *
+ * Returns 0 for a successful open, or appropriate error code
+ */
+static int emac_dev_open(struct net_device *ndev)
+{
+       struct device *emac_dev = &ndev->dev;
+       u32 rc, cnt, ch;
+       int phy_addr;
+       struct resource *res;
+       int q, m;
+       int i = 0;
+       int k = 0;
+       struct emac_priv *priv = netdev_priv(ndev);
+
+       netif_carrier_off(ndev);
+       for (cnt = 0; cnt <= ETH_ALEN; cnt++)
+               ndev->dev_addr[cnt] = priv->mac_addr[cnt];
+
+       /* Configuration items */
+       priv->rx_buf_size = EMAC_DEF_MAX_FRAME_SIZE + NET_IP_ALIGN;
+
+       /* Clear basic hardware */
+       for (ch = 0; ch < EMAC_MAX_TXRX_CHANNELS; ch++) {
+               emac_write(EMAC_TXHDP(ch), 0);
+               emac_write(EMAC_RXHDP(ch), 0);
+               emac_write(EMAC_RXHDP(ch), 0);
+               emac_write(EMAC_RXINTMASKCLEAR, EMAC_INT_MASK_CLEAR);
+               emac_write(EMAC_TXINTMASKCLEAR, EMAC_INT_MASK_CLEAR);
+       }
+       priv->mac_hash1 = 0;
+       priv->mac_hash2 = 0;
+       emac_write(EMAC_MACHASH1, 0);
+       emac_write(EMAC_MACHASH2, 0);
+
+       /* multi ch not supported - open 1 TX, 1RX ch by default */
+       rc = emac_init_txch(priv, EMAC_DEF_TX_CH);
+       if (0 != rc) {
+               dev_err(emac_dev, "DaVinci EMAC: emac_init_txch() failed");
+               return rc;
+       }
+       rc = emac_init_rxch(priv, EMAC_DEF_RX_CH, priv->mac_addr);
+       if (0 != rc) {
+               dev_err(emac_dev, "DaVinci EMAC: emac_init_rxch() failed");
+               return rc;
+       }
+
+       /* Request IRQ */
+
+       while ((res = platform_get_resource(priv->pdev, IORESOURCE_IRQ, k))) {
+               for (i = res->start; i <= res->end; i++) {
+                       if (request_irq(i, emac_irq, IRQF_DISABLED,
+                                       ndev->name, ndev))
+                               goto rollback;
+               }
+               k++;
+       }
+
+       /* Start/Enable EMAC hardware */
+       emac_hw_enable(priv);
+
+       /* find the first phy */
+       priv->phydev = NULL;
+       if (priv->phy_mask) {
+               emac_mii_reset(priv->mii_bus);
+               for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) {
+                       if (priv->mii_bus->phy_map[phy_addr]) {
+                               priv->phydev = priv->mii_bus->phy_map[phy_addr];
+                               break;
+                       }
+               }
+
+               if (!priv->phydev) {
+                       printk(KERN_ERR "%s: no PHY found\n", ndev->name);
+                       return -1;
+               }
+
+               priv->phydev = phy_connect(ndev, dev_name(&priv->phydev->dev),
+                               &emac_adjust_link, 0, PHY_INTERFACE_MODE_MII);
+
+               if (IS_ERR(priv->phydev)) {
+                       printk(KERN_ERR "%s: Could not attach to PHY\n",
+                                                               ndev->name);
+                       return PTR_ERR(priv->phydev);
+               }
+
+               priv->link = 0;
+               priv->speed = 0;
+               priv->duplex = ~0;
+
+               printk(KERN_INFO "%s: attached PHY driver [%s] "
+                       "(mii_bus:phy_addr=%s, id=%x)\n", ndev->name,
+                       priv->phydev->drv->name, dev_name(&priv->phydev->dev),
+                       priv->phydev->phy_id);
+       } else{
+               /* No PHY , fix the link, speed and duplex settings */
+               priv->link = 1;
+               priv->speed = SPEED_100;
+               priv->duplex = DUPLEX_FULL;
+               emac_update_phystatus(priv);
+       }
+
+       if (!netif_running(ndev)) /* debug only - to avoid compiler warning */
+               emac_dump_regs(priv);
+
+       if (netif_msg_drv(priv))
+               dev_notice(emac_dev, "DaVinci EMAC: Opened %s\n", ndev->name);
+
+       if (priv->phy_mask)
+               phy_start(priv->phydev);
+
+       return 0;
+
+rollback:
+
+       dev_err(emac_dev, "DaVinci EMAC: request_irq() failed");
+
+       for (q = k; k >= 0; k--) {
+               for (m = i; m >= res->start; m--)
+                       free_irq(m, ndev);
+               res = platform_get_resource(priv->pdev, IORESOURCE_IRQ, k-1);
+               m = res->end;
+       }
+       return -EBUSY;
+}
+
+/**
+ * emac_dev_stop: EMAC device stop
+ * @ndev: The DaVinci EMAC network adapter
+ *
+ * Called when system wants to stop or down the interface. We stop the network
+ * queue, disable interrupts and cleanup TX/RX channels.
+ *
+ * We return the statistics in net_device_stats structure pulled from emac
+ */
+static int emac_dev_stop(struct net_device *ndev)
+{
+       struct resource *res;
+       int i = 0;
+       int irq_num;
+       struct emac_priv *priv = netdev_priv(ndev);
+       struct device *emac_dev = &ndev->dev;
+
+       /* inform the upper layers. */
+       netif_stop_queue(ndev);
+       napi_disable(&priv->napi);
+
+       netif_carrier_off(ndev);
+       emac_int_disable(priv);
+       emac_stop_txch(priv, EMAC_DEF_TX_CH);
+       emac_stop_rxch(priv, EMAC_DEF_RX_CH);
+       emac_cleanup_txch(priv, EMAC_DEF_TX_CH);
+       emac_cleanup_rxch(priv, EMAC_DEF_RX_CH);
+       emac_write(EMAC_SOFTRESET, 1);
+
+       if (priv->phydev)
+               phy_disconnect(priv->phydev);
+
+       /* Free IRQ */
+       while ((res = platform_get_resource(priv->pdev, IORESOURCE_IRQ, i))) {
+               for (irq_num = res->start; irq_num <= res->end; irq_num++)
+                       free_irq(irq_num, priv->ndev);
+               i++;
+       }
+
+       if (netif_msg_drv(priv))
+               dev_notice(emac_dev, "DaVinci EMAC: %s stopped\n", ndev->name);
+
+       return 0;
+}
+
+/**
+ * emac_dev_getnetstats: EMAC get statistics function
+ * @ndev: The DaVinci EMAC network adapter
+ *
+ * Called when system wants to get statistics from the device.
+ *
+ * We return the statistics in net_device_stats structure pulled from emac
+ */
+static struct net_device_stats *emac_dev_getnetstats(struct net_device *ndev)
+{
+       struct emac_priv *priv = netdev_priv(ndev);
+
+       /* update emac hardware stats and reset the registers*/
+
+       priv->net_dev_stats.multicast += emac_read(EMAC_RXMCASTFRAMES);
+       emac_write(EMAC_RXMCASTFRAMES, EMAC_ALL_MULTI_REG_VALUE);
+
+       priv->net_dev_stats.collisions += (emac_read(EMAC_TXCOLLISION) +
+                                          emac_read(EMAC_TXSINGLECOLL) +
+                                          emac_read(EMAC_TXMULTICOLL));
+       emac_write(EMAC_TXCOLLISION, EMAC_ALL_MULTI_REG_VALUE);
+       emac_write(EMAC_TXSINGLECOLL, EMAC_ALL_MULTI_REG_VALUE);
+       emac_write(EMAC_TXMULTICOLL, EMAC_ALL_MULTI_REG_VALUE);
+
+       priv->net_dev_stats.rx_length_errors += (emac_read(EMAC_RXOVERSIZED) +
+                                               emac_read(EMAC_RXJABBER) +
+                                               emac_read(EMAC_RXUNDERSIZED));
+       emac_write(EMAC_RXOVERSIZED, EMAC_ALL_MULTI_REG_VALUE);
+       emac_write(EMAC_RXJABBER, EMAC_ALL_MULTI_REG_VALUE);
+       emac_write(EMAC_RXUNDERSIZED, EMAC_ALL_MULTI_REG_VALUE);
+
+       priv->net_dev_stats.rx_over_errors += (emac_read(EMAC_RXSOFOVERRUNS) +
+                                              emac_read(EMAC_RXMOFOVERRUNS));
+       emac_write(EMAC_RXSOFOVERRUNS, EMAC_ALL_MULTI_REG_VALUE);
+       emac_write(EMAC_RXMOFOVERRUNS, EMAC_ALL_MULTI_REG_VALUE);
+
+       priv->net_dev_stats.rx_fifo_errors += emac_read(EMAC_RXDMAOVERRUNS);
+       emac_write(EMAC_RXDMAOVERRUNS, EMAC_ALL_MULTI_REG_VALUE);
+
+       priv->net_dev_stats.tx_carrier_errors +=
+               emac_read(EMAC_TXCARRIERSENSE);
+       emac_write(EMAC_TXCARRIERSENSE, EMAC_ALL_MULTI_REG_VALUE);
+
+       priv->net_dev_stats.tx_fifo_errors = emac_read(EMAC_TXUNDERRUN);
+       emac_write(EMAC_TXUNDERRUN, EMAC_ALL_MULTI_REG_VALUE);
+
+       return &priv->net_dev_stats;
+}
+
+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_mac_address    = emac_dev_setmac_addr,
+       .ndo_do_ioctl           = emac_devioctl,
+       .ndo_tx_timeout         = emac_dev_tx_timeout,
+       .ndo_get_stats          = emac_dev_getnetstats,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+       .ndo_poll_controller    = emac_poll_controller,
+#endif
+};
+
+/**
+ * davinci_emac_probe: EMAC device probe
+ * @pdev: The DaVinci EMAC device that we are removing
+ *
+ * Called when probing for emac devicesr. We get details of instances and
+ * resource information from platform init and register a network device
+ * and allocate resources necessary for driver to perform
+ */
+static int __devinit davinci_emac_probe(struct platform_device *pdev)
+{
+       int rc = 0;
+       struct resource *res;
+       struct net_device *ndev;
+       struct emac_priv *priv;
+       unsigned long size;
+       struct emac_platform_data *pdata;
+       struct device *emac_dev;
+
+       /* obtain emac clock from kernel */
+       emac_clk = clk_get(&pdev->dev, NULL);
+       if (IS_ERR(emac_clk)) {
+               printk(KERN_ERR "DaVinci EMAC: Failed to get EMAC clock\n");
+               return -EBUSY;
+       }
+       emac_bus_frequency = clk_get_rate(emac_clk);
+       /* TODO: Probe PHY here if possible */
+
+       ndev = alloc_etherdev(sizeof(struct emac_priv));
+       if (!ndev) {
+               printk(KERN_ERR "DaVinci EMAC: Error allocating net_device\n");
+               clk_put(emac_clk);
+               return -ENOMEM;
+       }
+
+       platform_set_drvdata(pdev, ndev);
+       priv = netdev_priv(ndev);
+       priv->pdev = pdev;
+       priv->ndev = ndev;
+       priv->msg_enable = netif_msg_init(debug_level, DAVINCI_EMAC_DEBUG);
+
+       spin_lock_init(&priv->tx_lock);
+       spin_lock_init(&priv->rx_lock);
+       spin_lock_init(&priv->lock);
+
+       pdata = pdev->dev.platform_data;
+       if (!pdata) {
+               printk(KERN_ERR "DaVinci EMAC: No platfrom data\n");
+               return -ENODEV;
+       }
+
+       /* MAC addr and PHY mask , RMII enable info from platform_data */
+       memcpy(priv->mac_addr, pdata->mac_addr, 6);
+       priv->phy_mask = pdata->phy_mask;
+       priv->rmii_en = pdata->rmii_en;
+       priv->version = pdata->version;
+       emac_dev = &ndev->dev;
+       /* Get EMAC platform data */
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!res) {
+               dev_err(emac_dev, "DaVinci EMAC: Error getting res\n");
+               rc = -ENOENT;
+               goto probe_quit;
+       }
+
+       priv->emac_base_phys = res->start + pdata->ctrl_reg_offset;
+       size = res->end - res->start + 1;
+       if (!request_mem_region(res->start, size, ndev->name)) {
+               dev_err(emac_dev, "DaVinci EMAC: failed request_mem_region() \
+                                        for regs\n");
+               rc = -ENXIO;
+               goto probe_quit;
+       }
+
+       priv->remap_addr = ioremap(res->start, size);
+       if (!priv->remap_addr) {
+               dev_err(emac_dev, "Unable to map IO\n");
+               rc = -ENOMEM;
+               release_mem_region(res->start, size);
+               goto probe_quit;
+       }
+       priv->emac_base = priv->remap_addr + pdata->ctrl_reg_offset;
+       ndev->base_addr = (unsigned long)priv->remap_addr;
+
+       priv->ctrl_base = priv->remap_addr + pdata->ctrl_mod_reg_offset;
+       priv->ctrl_ram_size = pdata->ctrl_ram_size;
+       priv->emac_ctrl_ram = priv->remap_addr + pdata->ctrl_ram_offset;
+
+       res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+       if (!res) {
+               dev_err(emac_dev, "DaVinci EMAC: Error getting irq res\n");
+               rc = -ENOENT;
+               goto no_irq_res;
+       }
+       ndev->irq = res->start;
+
+       if (!is_valid_ether_addr(priv->mac_addr)) {
+               /* Use random MAC if none passed */
+               random_ether_addr(priv->mac_addr);
+               printk(KERN_WARNING "%s: using random MAC addr: %pM\n",
+                               __func__, priv->mac_addr);
+       }
+
+       ndev->netdev_ops = &emac_netdev_ops;
+       SET_ETHTOOL_OPS(ndev, &ethtool_ops);
+       netif_napi_add(ndev, &priv->napi, emac_poll, EMAC_POLL_WEIGHT);
+
+       /* register the network device */
+       SET_NETDEV_DEV(ndev, &pdev->dev);
+       rc = register_netdev(ndev);
+       if (rc) {
+               dev_err(emac_dev, "DaVinci EMAC: Error in register_netdev\n");
+               rc = -ENODEV;
+               goto netdev_reg_err;
+       }
+
+       clk_enable(emac_clk);
+
+       /* MII/Phy intialisation, mdio bus registration */
+       emac_mii = mdiobus_alloc();
+       if (emac_mii == NULL) {
+               dev_err(emac_dev, "DaVinci EMAC: Error allocating mii_bus\n");
+               rc = -ENOMEM;
+               goto mdio_alloc_err;
+       }
+
+       priv->mii_bus = emac_mii;
+       emac_mii->name  = "emac-mii",
+       emac_mii->read  = emac_mii_read,
+       emac_mii->write = emac_mii_write,
+       emac_mii->reset = emac_mii_reset,
+       emac_mii->irq   = mii_irqs,
+       emac_mii->phy_mask = ~(priv->phy_mask);
+       emac_mii->parent = &pdev->dev;
+       emac_mii->priv = priv->remap_addr + pdata->mdio_reg_offset;
+       snprintf(priv->mii_bus->id, MII_BUS_ID_SIZE, "%x", priv->pdev->id);
+       mdio_max_freq = pdata->mdio_max_freq;
+       emac_mii->reset(emac_mii);
+
+       /* Register the MII bus */
+       rc = mdiobus_register(emac_mii);
+       if (rc)
+               goto mdiobus_quit;
+
+       if (netif_msg_probe(priv)) {
+               dev_notice(emac_dev, "DaVinci EMAC Probe found device "\
+                          "(regs: %p, irq: %d)\n",
+                          (void *)priv->emac_base_phys, ndev->irq);
+       }
+       return 0;
+
+mdiobus_quit:
+       mdiobus_free(emac_mii);
+
+netdev_reg_err:
+mdio_alloc_err:
+no_irq_res:
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       release_mem_region(res->start, res->end - res->start + 1);
+       iounmap(priv->remap_addr);
+
+probe_quit:
+       clk_put(emac_clk);
+       free_netdev(ndev);
+       return rc;
+}
+
+/**
+ * davinci_emac_remove: EMAC device remove
+ * @pdev: The DaVinci EMAC device that we are removing
+ *
+ * Called when removing the device driver. We disable clock usage and release
+ * the resources taken up by the driver and unregister network device
+ */
+static int __devexit davinci_emac_remove(struct platform_device *pdev)
+{
+       struct resource *res;
+       struct net_device *ndev = platform_get_drvdata(pdev);
+       struct emac_priv *priv = netdev_priv(ndev);
+
+       dev_notice(&ndev->dev, "DaVinci EMAC: davinci_emac_remove()\n");
+
+       clk_disable(emac_clk);
+       platform_set_drvdata(pdev, NULL);
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       mdiobus_unregister(priv->mii_bus);
+       mdiobus_free(priv->mii_bus);
+
+       release_mem_region(res->start, res->end - res->start + 1);
+
+       unregister_netdev(ndev);
+       free_netdev(ndev);
+       iounmap(priv->remap_addr);
+
+       clk_disable(emac_clk);
+       clk_put(emac_clk);
+
+       return 0;
+}
+
+/**
+ * davinci_emac_driver: EMAC platform driver structure
+ *
+ * We implement only probe and remove functions - suspend/resume and
+ * others not supported by this module
+ */
+static struct platform_driver davinci_emac_driver = {
+       .driver = {
+               .name    = "davinci_emac",
+               .owner   = THIS_MODULE,
+       },
+       .probe = davinci_emac_probe,
+       .remove = __devexit_p(davinci_emac_remove),
+};
+
+/**
+ * davinci_emac_init: EMAC driver module init
+ *
+ * Called when initializing the driver. We register the driver with
+ * the platform.
+ */
+static int __init davinci_emac_init(void)
+{
+       return platform_driver_register(&davinci_emac_driver);
+}
+module_init(davinci_emac_init);
+
+/**
+ * davinci_emac_exit: EMAC driver module exit
+ *
+ * Called when exiting the driver completely. We unregister the driver with
+ * the platform and exit
+ */
+static void __exit davinci_emac_exit(void)
+{
+       platform_driver_unregister(&davinci_emac_driver);
+}
+module_exit(davinci_emac_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("DaVinci EMAC Maintainer: Anant Gole <anantgole@ti.com>");
+MODULE_AUTHOR("DaVinci EMAC Maintainer: Chaithrika U S <chaithrika@ti.com>");
+MODULE_DESCRIPTION("DaVinci EMAC Ethernet driver");
index de63f1d41d32c32918978360270a96505d1adfab..e1af089064bc8eb17e08dddf03022bc184b306de 100644 (file)
@@ -38,14 +38,6 @@ static const char version[] = "de600.c: $Revision: 1.41-2.5 $,  Bjorn Ekwall (bj
 /* Add more time here if your adapter won't work OK: */
 #define DE600_SLOW_DOWN        udelay(delay_time)
 
-/* use 0 for production, 1 for verification, >2 for debug */
-#ifdef DE600_DEBUG
-#define PRINTK(x) if (de600_debug >= 2) printk x
-#else
-#define DE600_DEBUG 0
-#define PRINTK(x) /**/
-#endif
-
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
@@ -67,10 +59,6 @@ static const char version[] = "de600.c: $Revision: 1.41-2.5 $,  Bjorn Ekwall (bj
 
 #include "de600.h"
 
-static unsigned int de600_debug = DE600_DEBUG;
-module_param(de600_debug, int, 0);
-MODULE_PARM_DESC(de600_debug, "DE-600 debug level (0-2)");
-
 static unsigned int check_lost = 1;
 module_param(check_lost, bool, 0);
 MODULE_PARM_DESC(check_lost, "If set then check for unplugged de600");
@@ -180,20 +168,20 @@ static int de600_start_xmit(struct sk_buff *skb, struct net_device *dev)
        if (free_tx_pages <= 0) {       /* Do timeouts, to avoid hangs. */
                tickssofar = jiffies - dev->trans_start;
                if (tickssofar < 5)
-                       return 1;
+                       return NETDEV_TX_BUSY;
                /* else */
                printk(KERN_WARNING "%s: transmit timed out (%d), %s?\n", dev->name, tickssofar, "network cable problem");
                /* Restart the adapter. */
                spin_lock_irqsave(&de600_lock, flags);
                if (adapter_init(dev)) {
                        spin_unlock_irqrestore(&de600_lock, flags);
-                       return 1;
+                       return NETDEV_TX_BUSY;
                }
                spin_unlock_irqrestore(&de600_lock, flags);
        }
 
        /* Start real output */
-       PRINTK(("de600_start_xmit:len=%d, page %d/%d\n", skb->len, tx_fifo_in, free_tx_pages));
+       pr_debug("de600_start_xmit:len=%d, page %d/%d\n", skb->len, tx_fifo_in, free_tx_pages);
 
        if ((len = skb->len) < RUNT)
                len = RUNT;
@@ -211,7 +199,7 @@ static int de600_start_xmit(struct sk_buff *skb, struct net_device *dev)
                if (was_down || (de600_read_byte(READ_DATA, dev) != 0xde)) {
                        if (adapter_init(dev)) {
                                spin_unlock_irqrestore(&de600_lock, flags);
-                               return 1;
+                               return NETDEV_TX_BUSY;
                        }
                }
        }
@@ -259,7 +247,7 @@ static irqreturn_t de600_interrupt(int irq, void *dev_id)
        irq_status = de600_read_status(dev);
 
        do {
-               PRINTK(("de600_interrupt (%02X)\n", irq_status));
+               pr_debug("de600_interrupt (%02X)\n", irq_status);
 
                if (irq_status & RX_GOOD)
                        de600_rx_intr(dev);
@@ -407,8 +395,7 @@ static struct net_device * __init de600_probe(void)
 
        printk(KERN_INFO "%s: D-Link DE-600 pocket adapter", dev->name);
        /* Alpha testers must have the version number to report bugs. */
-       if (de600_debug > 1)
-               printk(version);
+       pr_debug("%s", version);
 
        /* probe for adapter */
        err = -ENODEV;
index d52f34cc95269c961daae470697ce94f6b714c1a..55d2bb67cffa66c9ecefcf7762bbad050c9727dd 100644 (file)
@@ -48,7 +48,6 @@ static const char version[] =
  * Compile-time options: (see below for descriptions)
  * -DDE620_IO=0x378    (lpt1)
  * -DDE620_IRQ=7       (lpt1)
- * -DDE602_DEBUG=...
  * -DSHUTDOWN_WHEN_LOST
  * -DCOUNT_LOOPS
  * -DLOWSPEED
@@ -98,15 +97,6 @@ static const char version[] =
 #define SHUTDOWN_WHEN_LOST
  */
 
-/*
- * Enable debugging by "-DDE620_DEBUG=3" when compiling,
- * OR by enabling the following #define
- *
- * use 0 for production, 1 for verification, >2 for debug
- *
-#define DE620_DEBUG 3
- */
-
 #ifdef LOWSPEED
 /*
  * Enable this #define if you want to see debugging output that show how long
@@ -160,14 +150,6 @@ typedef unsigned char byte;
 #define RUNT 60                /* Too small Ethernet packet */
 #define GIANT 1514     /* largest legal size packet, no fcs */
 
-#ifdef DE620_DEBUG /* Compile-time configurable */
-#define PRINTK(x) if (de620_debug >= 2) printk x
-#else
-#define DE620_DEBUG 0
-#define PRINTK(x) /**/
-#endif
-
-
 /*
  * Force media with insmod:
  *     insmod de620.o bnc=1
@@ -186,8 +168,6 @@ static int io  = DE620_IO;
 static int irq = DE620_IRQ;
 static int clone = DE620_CLONE;
 
-static unsigned int de620_debug = DE620_DEBUG;
-
 static spinlock_t de620_lock;
 
 module_param(bnc, int, 0);
@@ -195,13 +175,11 @@ module_param(utp, int, 0);
 module_param(io, int, 0);
 module_param(irq, int, 0);
 module_param(clone, int, 0);
-module_param(de620_debug, int, 0);
 MODULE_PARM_DESC(bnc, "DE-620 set BNC medium (0-1)");
 MODULE_PARM_DESC(utp, "DE-620 set UTP medium (0-1)");
 MODULE_PARM_DESC(io, "DE-620 I/O base address,required");
 MODULE_PARM_DESC(irq, "DE-620 IRQ number,required");
 MODULE_PARM_DESC(clone, "Check also for non-D-Link DE-620 clones (0-1)");
-MODULE_PARM_DESC(de620_debug, "DE-620 debug level (0-2)");
 
 /***********************************************
  *                                             *
@@ -533,9 +511,9 @@ static int de620_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
        /* Start real output */
 
-       spin_lock_irqsave(&de620_lock, flags)
-       PRINTK(("de620_start_xmit: len=%d, bufs 0x%02x\n",
-               (int)skb->len, using_txbuf));
+       spin_lock_irqsave(&de620_lock, flags);
+       pr_debug("de620_start_xmit: len=%d, bufs 0x%02x\n",
+               (int)skb->len, using_txbuf);
 
        /* select a free tx buffer. if there is one... */
        switch (using_txbuf) {
@@ -553,7 +531,7 @@ static int de620_start_xmit(struct sk_buff *skb, struct net_device *dev)
        case (TXBF0 | TXBF1): /* NONE!!! */
                printk(KERN_WARNING "%s: No tx-buffer available!\n", dev->name);
                spin_unlock_irqrestore(&de620_lock, flags);
-               return 1;
+               return NETDEV_TX_BUSY;
        }
        de620_write_block(dev, buffer, skb->len, len-skb->len);
 
@@ -585,12 +563,12 @@ de620_interrupt(int irq_in, void *dev_id)
        /* Read the status register (_not_ the status port) */
        irq_status = de620_get_register(dev, R_STS);
 
-       PRINTK(("de620_interrupt (%2.2X)\n", irq_status));
+       pr_debug("de620_interrupt (%2.2X)\n", irq_status);
 
        if (irq_status & RXGOOD) {
                do {
                        again = de620_rx_intr(dev);
-                       PRINTK(("again=%d\n", again));
+                       pr_debug("again=%d\n", again);
                }
                while (again && (++bogus_count < 100));
        }
@@ -622,7 +600,7 @@ static int de620_rx_intr(struct net_device *dev)
        byte pagelink;
        byte curr_page;
 
-       PRINTK(("de620_rx_intr: next_rx_page = %d\n", next_rx_page));
+       pr_debug("de620_rx_intr: next_rx_page = %d\n", next_rx_page);
 
        /* Tell the adapter that we are going to read data, and from where */
        de620_send_command(dev, W_CR | RRN);
@@ -631,8 +609,9 @@ static int de620_rx_intr(struct net_device *dev)
 
        /* Deep breath, and away we goooooo */
        de620_read_block(dev, (byte *)&header_buf, sizeof(struct header_buf));
-       PRINTK(("page status=0x%02x, nextpage=%d, packetsize=%d\n",
-       header_buf.status, header_buf.Rx_NextPage, header_buf.Rx_ByteCount));
+       pr_debug("page status=0x%02x, nextpage=%d, packetsize=%d\n",
+               header_buf.status, header_buf.Rx_NextPage,
+               header_buf.Rx_ByteCount);
 
        /* Plausible page header? */
        pagelink = header_buf.Rx_NextPage;
@@ -683,7 +662,7 @@ static int de620_rx_intr(struct net_device *dev)
                        buffer = skb_put(skb,size);
                        /* copy the packet into the buffer */
                        de620_read_block(dev, buffer, size);
-                       PRINTK(("Read %d bytes\n", size));
+                       pr_debug("Read %d bytes\n", size);
                        skb->protocol=eth_type_trans(skb,dev);
                        netif_rx(skb); /* deliver it "upstairs" */
                        /* count all receives */
@@ -696,7 +675,7 @@ static int de620_rx_intr(struct net_device *dev)
        /* NOTE! We're _not_ checking the 'EMPTY'-flag! This seems better... */
        curr_page = de620_get_register(dev, R_CPR);
        de620_set_register(dev, W_NPRF, next_rx_page);
-       PRINTK(("next_rx_page=%d CPR=%d\n", next_rx_page, curr_page));
+       pr_debug("next_rx_page=%d CPR=%d\n", next_rx_page, curr_page);
 
        return (next_rx_page != curr_page); /* That was slightly tricky... */
 }
@@ -830,8 +809,7 @@ struct net_device * __init de620_probe(int unit)
                netdev_boot_setup_check(dev);
        }
 
-       if (de620_debug)
-               printk(version);
+       pr_debug("%s", version);
 
        printk(KERN_INFO "D-Link DE-620 pocket adapter");
 
@@ -878,14 +856,13 @@ struct net_device * __init de620_probe(int unit)
        /* base_addr and irq are already set, see above! */
 
        /* dump eeprom */
-       if (de620_debug) {
-               printk("\nEEPROM contents:\n");
-               printk("RAM_Size = 0x%02X\n", nic_data.RAM_Size);
-               printk("NodeID = %pM\n", nic_data.NodeID);
-               printk("Model = %d\n", nic_data.Model);
-               printk("Media = %d\n", nic_data.Media);
-               printk("SCR = 0x%02x\n", nic_data.SCR);
-       }
+       pr_debug("\nEEPROM contents:\n"
+               "RAM_Size = 0x%02X\n"
+               "NodeID = %pM\n"
+               "Model = %d\n"
+               "Media = %d\n"
+               "SCR = 0x%02x\n", nic_data.RAM_Size, nic_data.NodeID,
+               nic_data.Model, nic_data.Media, nic_data.SCR);
 
        err = register_netdev(dev);
        if (err)
index b62405a6918040764d68639660ad902754653671..2b22e580c4ded83e7873fbbe5502f10c208aae0f 100644 (file)
@@ -895,6 +895,7 @@ static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev)
        struct lance_private *lp = netdev_priv(dev);
        volatile struct lance_regs *ll = lp->ll;
        volatile u16 *ib = (volatile u16 *)dev->mem_start;
+       unsigned long flags;
        int entry, len;
 
        len = skb->len;
@@ -907,6 +908,8 @@ static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
        dev->stats.tx_bytes += len;
 
+       spin_lock_irqsave(&lp->lock, flags);
+
        entry = lp->tx_new;
        *lib_ptr(ib, btx_ring[entry].length, lp->type) = (-len);
        *lib_ptr(ib, btx_ring[entry].misc, lp->type) = 0;
@@ -925,6 +928,8 @@ static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev)
        /* Kick the lance: transmit now */
        writereg(&ll->rdp, LE_C0_INEA | LE_C0_TDMD);
 
+       spin_unlock_irqrestore(&lp->lock, flags);
+
        dev->trans_start = jiffies;
        dev_kfree_skb(skb);
 
index 4ec055dc7174ceed6f17302d132a484151ab7671..102b8d4397144bf624ae4ab752fb4f45ab3b3002 100644 (file)
@@ -3318,7 +3318,7 @@ static int dfx_xmt_queue_pkt(
        {
                skb_pull(skb,3);
                spin_unlock_irqrestore(&bp->lock, flags);
-               return(1);                      /* requeue packet for later */
+               return NETDEV_TX_BUSY;  /* requeue packet for later */
        }
 
        /*
index 357f565851edf7865c576ab4489a839c811ba369..97ea2d6d3fe16cc5ac72d68739633d9da8bae637 100644 (file)
@@ -810,7 +810,7 @@ static int __init depca_hw_init (struct net_device *dev, struct device *device)
 
        dev->mem_start = 0;
 
-       device->driver_data = dev;
+       dev_set_drvdata(device, dev);
        SET_NETDEV_DEV (dev, device);
 
        status = register_netdev(dev);
@@ -957,7 +957,7 @@ static int depca_start_xmit(struct sk_buff *skb, struct net_device *dev)
                if (TX_BUFFS_AVAIL)
                        netif_start_queue(dev);
        } else
-               status = -1;
+               status = NETDEV_TX_LOCKED;
 
       out:
        return status;
@@ -1614,7 +1614,7 @@ static int __devexit depca_device_remove (struct device *device)
        struct depca_private *lp;
        int bus;
 
-       dev  = device->driver_data;
+       dev  = dev_get_drvdata(device);
        lp   = netdev_priv(dev);
 
        unregister_netdev (dev);
@@ -1839,7 +1839,7 @@ static int load_packet(struct net_device *dev, struct sk_buff *skb)
 
                lp->tx_new = (++end) & lp->txRingMask;  /* update current pointers */
        } else {
-               status = -1;
+               status = NETDEV_TX_LOCKED;
        }
 
        return status;
index 4a1b554654ebe573a159e515a7795b22af049a88..895d72143ee049757c3750ae096cad3c8387c02a 100644 (file)
@@ -539,7 +539,7 @@ rio_tx_timeout (struct net_device *dev)
                dev->name, readl (ioaddr + TxStatus));
        rio_free_tx(dev, 0);
        dev->if_port = 0;
-       dev->trans_start = jiffies;
+       dev->trans_start = jiffies; /* prevent tx timeout */
 }
 
  /* allocate and initialize Tx and Rx descriptors */
@@ -610,7 +610,7 @@ start_xmit (struct sk_buff *skb, struct net_device *dev)
 
        if (np->link_status == 0) {     /* Link Down */
                dev_kfree_skb(skb);
-               return 0;
+               return NETDEV_TX_OK;
        }
        ioaddr = dev->base_addr;
        entry = np->cur_tx % TX_RING_SIZE;
@@ -665,9 +665,7 @@ start_xmit (struct sk_buff *skb, struct net_device *dev)
                writel (0, dev->base_addr + TFDListPtr1);
        }
 
-       /* NETDEV WATCHDOG timer */
-       dev->trans_start = jiffies;
-       return 0;
+       return NETDEV_TX_OK;
 }
 
 static irqreturn_t
index d8350860c0f8db5e6c622f4962586d8024c2636f..dd771dea6ae62f6e1292f4bf674abcfe961b6aaf 100644 (file)
@@ -756,7 +756,7 @@ dm9000_start_xmit(struct sk_buff *skb, struct net_device *dev)
        dm9000_dbg(db, 3, "%s:\n", __func__);
 
        if (db->tx_pkt_cnt > 1)
-               return 1;
+               return NETDEV_TX_BUSY;
 
        spin_lock_irqsave(&db->lock, flags);
 
@@ -1170,6 +1170,21 @@ dm9000_stop(struct net_device *ndev)
        return 0;
 }
 
+static const struct net_device_ops dm9000_netdev_ops = {
+       .ndo_open               = dm9000_open,
+       .ndo_stop               = dm9000_stop,
+       .ndo_start_xmit         = dm9000_start_xmit,
+       .ndo_tx_timeout         = dm9000_timeout,
+       .ndo_set_multicast_list = dm9000_hash_table,
+       .ndo_do_ioctl           = dm9000_ioctl,
+       .ndo_change_mtu         = eth_change_mtu,
+       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_set_mac_address    = eth_mac_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+       .ndo_poll_controller    = dm9000_poll_controller,
+#endif
+};
+
 #define res_size(_r) (((_r)->end - (_r)->start) + 1)
 
 /*
@@ -1339,18 +1354,9 @@ dm9000_probe(struct platform_device *pdev)
        /* driver system function */
        ether_setup(ndev);
 
-       ndev->open               = &dm9000_open;
-       ndev->hard_start_xmit    = &dm9000_start_xmit;
-       ndev->tx_timeout         = &dm9000_timeout;
-       ndev->watchdog_timeo = msecs_to_jiffies(watchdog);
-       ndev->stop               = &dm9000_stop;
-       ndev->set_multicast_list = &dm9000_hash_table;
-       ndev->ethtool_ops        = &dm9000_ethtool_ops;
-       ndev->do_ioctl           = &dm9000_ioctl;
-
-#ifdef CONFIG_NET_POLL_CONTROLLER
-       ndev->poll_controller    = &dm9000_poll_controller;
-#endif
+       ndev->netdev_ops        = &dm9000_netdev_ops;
+       ndev->watchdog_timeo    = msecs_to_jiffies(watchdog);
+       ndev->ethtool_ops       = &dm9000_ethtool_ops;
 
        db->msg_enable       = NETIF_MSG_LINK;
        db->mii.phy_id_mask  = 0x1f;
index af5364f4955065421f50a30180ba378915dcc50a..f7929e89eb036128d715523e26a78f957c3ce071 100644 (file)
  *     FIXES:
  * 2005/12/02 - Michael O'Donnell <Michael.ODonnell at stratus dot com>
  *     - Stratus87247: protect MDI control register manipulations
+ * 2009/06/01 - Andreas Mohr <andi at lisas dot de>
+ *      - add clean lowlevel I/O emulation for cards with MII-lacking PHYs
  */
 
 #include <linux/module.h>
@@ -372,6 +374,7 @@ enum eeprom_op {
 
 enum eeprom_offsets {
        eeprom_cnfg_mdix  = 0x03,
+       eeprom_phy_iface  = 0x06,
        eeprom_id         = 0x0A,
        eeprom_config_asf = 0x0D,
        eeprom_smbus_addr = 0x90,
@@ -381,6 +384,18 @@ enum eeprom_cnfg_mdix {
        eeprom_mdix_enabled = 0x0080,
 };
 
+enum eeprom_phy_iface {
+       NoSuchPhy = 0,
+       I82553AB,
+       I82553C,
+       I82503,
+       DP83840,
+       S80C240,
+       S80C24,
+       I82555,
+       DP83840A = 10,
+};
+
 enum eeprom_id {
        eeprom_id_wol = 0x0020,
 };
@@ -545,6 +560,7 @@ struct nic {
        u32 msg_enable                          ____cacheline_aligned;
        struct net_device *netdev;
        struct pci_dev *pdev;
+       u16 (*mdio_ctrl)(struct nic *nic, u32 addr, u32 dir, u32 reg, u16 data);
 
        struct rx *rxs                          ____cacheline_aligned;
        struct rx *rx_to_use;
@@ -899,7 +915,21 @@ err_unlock:
        return err;
 }
 
-static u16 mdio_ctrl(struct nic *nic, u32 addr, u32 dir, u32 reg, u16 data)
+static int mdio_read(struct net_device *netdev, int addr, int reg)
+{
+       struct nic *nic = netdev_priv(netdev);
+       return nic->mdio_ctrl(nic, addr, mdi_read, reg, 0);
+}
+
+static void mdio_write(struct net_device *netdev, int addr, int reg, int data)
+{
+       struct nic *nic = netdev_priv(netdev);
+
+       nic->mdio_ctrl(nic, addr, mdi_write, reg, data);
+}
+
+/* the standard mdio_ctrl() function for usual MII-compliant hardware */
+static u16 mdio_ctrl_hw(struct nic *nic, u32 addr, u32 dir, u32 reg, u16 data)
 {
        u32 data_out = 0;
        unsigned int i;
@@ -938,30 +968,83 @@ static u16 mdio_ctrl(struct nic *nic, u32 addr, u32 dir, u32 reg, u16 data)
        return (u16)data_out;
 }
 
-static int mdio_read(struct net_device *netdev, int addr, int reg)
-{
-       return mdio_ctrl(netdev_priv(netdev), addr, mdi_read, reg, 0);
+/* slightly tweaked mdio_ctrl() function for phy_82552_v specifics */
+static u16 mdio_ctrl_phy_82552_v(struct nic *nic,
+                                u32 addr,
+                                u32 dir,
+                                u32 reg,
+                                u16 data)
+{
+       if ((reg == MII_BMCR) && (dir == mdi_write)) {
+               if (data & (BMCR_ANRESTART | BMCR_ANENABLE)) {
+                       u16 advert = mdio_read(nic->netdev, nic->mii.phy_id,
+                                                       MII_ADVERTISE);
+
+                       /*
+                        * Workaround Si issue where sometimes the part will not
+                        * autoneg to 100Mbps even when advertised.
+                        */
+                       if (advert & ADVERTISE_100FULL)
+                               data |= BMCR_SPEED100 | BMCR_FULLDPLX;
+                       else if (advert & ADVERTISE_100HALF)
+                               data |= BMCR_SPEED100;
+               }
+       }
+       return mdio_ctrl_hw(nic, addr, dir, reg, data);
 }
 
-static void mdio_write(struct net_device *netdev, int addr, int reg, int data)
-{
-       struct nic *nic = netdev_priv(netdev);
-
-       if  ((nic->phy == phy_82552_v) && (reg == MII_BMCR) &&
-            (data & (BMCR_ANRESTART | BMCR_ANENABLE))) {
-               u16 advert = mdio_read(netdev, nic->mii.phy_id, MII_ADVERTISE);
-
-               /*
-                * Workaround Si issue where sometimes the part will not
-                * autoneg to 100Mbps even when advertised.
-                */
-               if (advert & ADVERTISE_100FULL)
-                       data |= BMCR_SPEED100 | BMCR_FULLDPLX;
-               else if (advert & ADVERTISE_100HALF)
-                       data |= BMCR_SPEED100;
+/* Fully software-emulated mdio_ctrl() function for cards without
+ * MII-compliant PHYs.
+ * For now, this is mainly geared towards 80c24 support; in case of further
+ * requirements for other types (i82503, ...?) either extend this mechanism
+ * or split it, whichever is cleaner.
+ */
+static u16 mdio_ctrl_phy_mii_emulated(struct nic *nic,
+                                     u32 addr,
+                                     u32 dir,
+                                     u32 reg,
+                                     u16 data)
+{
+       /* might need to allocate a netdev_priv'ed register array eventually
+        * to be able to record state changes, but for now
+        * some fully hardcoded register handling ought to be ok I guess. */
+
+       if (dir == mdi_read) {
+               switch (reg) {
+               case MII_BMCR:
+                       /* Auto-negotiation, right? */
+                       return  BMCR_ANENABLE |
+                               BMCR_FULLDPLX;
+               case MII_BMSR:
+                       return  BMSR_LSTATUS /* for mii_link_ok() */ |
+                               BMSR_ANEGCAPABLE |
+                               BMSR_10FULL;
+               case MII_ADVERTISE:
+                       /* 80c24 is a "combo card" PHY, right? */
+                       return  ADVERTISE_10HALF |
+                               ADVERTISE_10FULL;
+               default:
+                       DPRINTK(HW, DEBUG,
+               "%s:addr=%d, reg=%d, data=0x%04X: unimplemented emulation!\n",
+               dir == mdi_read ? "READ" : "WRITE", addr, reg, data);
+                       return 0xFFFF;
+               }
+       } else {
+               switch (reg) {
+               default:
+                       DPRINTK(HW, DEBUG,
+               "%s:addr=%d, reg=%d, data=0x%04X: unimplemented emulation!\n",
+               dir == mdi_read ? "READ" : "WRITE", addr, reg, data);
+                       return 0xFFFF;
+               }
        }
-
-       mdio_ctrl(netdev_priv(netdev), addr, mdi_write, reg, data);
+}
+static inline int e100_phy_supports_mii(struct nic *nic)
+{
+       /* for now, just check it by comparing whether we
+          are using MII software emulation.
+       */
+       return (nic->mdio_ctrl != mdio_ctrl_phy_mii_emulated);
 }
 
 static void e100_get_defaults(struct nic *nic)
@@ -1013,7 +1096,8 @@ static void e100_configure(struct nic *nic, struct cb *cb, struct sk_buff *skb)
        config->standard_stat_counter = 0x1;    /* 1=standard, 0=extended */
        config->rx_discard_short_frames = 0x1;  /* 1=discard, 0=pass */
        config->tx_underrun_retry = 0x3;        /* # of underrun retries */
-       config->mii_mode = 0x1;                 /* 1=MII mode, 0=503 mode */
+       if (e100_phy_supports_mii(nic))
+               config->mii_mode = 1;           /* 1=MII mode, 0=i82503 mode */
        config->pad10 = 0x6;
        config->no_source_addr_insertion = 0x1; /* 1=no, 0=yes */
        config->preamble_length = 0x2;          /* 0=1, 1=3, 2=7, 3=15 bytes */
@@ -1270,6 +1354,42 @@ static void e100_dump(struct nic *nic, struct cb *cb, struct sk_buff *skb)
                offsetof(struct mem, dump_buf));
 }
 
+static int e100_phy_check_without_mii(struct nic *nic)
+{
+       u8 phy_type;
+       int without_mii;
+
+       phy_type = (nic->eeprom[eeprom_phy_iface] >> 8) & 0x0f;
+
+       switch (phy_type) {
+       case NoSuchPhy: /* Non-MII PHY; UNTESTED! */
+       case I82503: /* Non-MII PHY; UNTESTED! */
+       case S80C24: /* Non-MII PHY; tested and working */
+               /* paragraph from the FreeBSD driver, "FXP_PHY_80C24":
+                * The Seeq 80c24 AutoDUPLEX(tm) Ethernet Interface Adapter
+                * doesn't have a programming interface of any sort.  The
+                * media is sensed automatically based on how the link partner
+                * is configured.  This is, in essence, manual configuration.
+                */
+               DPRINTK(PROBE, INFO,
+                        "found MII-less i82503 or 80c24 or other PHY\n");
+
+               nic->mdio_ctrl = mdio_ctrl_phy_mii_emulated;
+               nic->mii.phy_id = 0; /* is this ok for an MII-less PHY? */
+
+               /* these might be needed for certain MII-less cards...
+                * nic->flags |= ich;
+                * nic->flags |= ich_10h_workaround; */
+
+               without_mii = 1;
+               break;
+       default:
+               without_mii = 0;
+               break;
+       }
+       return without_mii;
+}
+
 #define NCONFIG_AUTO_SWITCH    0x0080
 #define MII_NSC_CONG           MII_RESV1
 #define NSC_CONG_ENABLE                0x0100
@@ -1290,9 +1410,21 @@ static int e100_phy_init(struct nic *nic)
                if (!((bmcr == 0xFFFF) || ((stat == 0) && (bmcr == 0))))
                        break;
        }
-       DPRINTK(HW, DEBUG, "phy_addr = %d\n", nic->mii.phy_id);
-       if (addr == 32)
-               return -EAGAIN;
+       if (addr == 32) {
+               /* uhoh, no PHY detected: check whether we seem to be some
+                * weird, rare variant which is *known* to not have any MII.
+                * But do this AFTER MII checking only, since this does
+                * lookup of EEPROM values which may easily be unreliable. */
+               if (e100_phy_check_without_mii(nic))
+                       return 0; /* simply return and hope for the best */
+               else {
+                       /* for unknown cases log a fatal error */
+                       DPRINTK(HW, ERR,
+                               "Failed to locate any known PHY, aborting.\n");
+                       return -EAGAIN;
+               }
+       } else
+               DPRINTK(HW, DEBUG, "phy_addr = %d\n", nic->mii.phy_id);
 
        /* Isolate all the PHY ids */
        for (addr = 0; addr < 32; addr++)
@@ -1320,6 +1452,9 @@ static int e100_phy_init(struct nic *nic)
        if (nic->phy == phy_82552_v) {
                u16 advert = mdio_read(netdev, nic->mii.phy_id, MII_ADVERTISE);
 
+               /* assign special tweaked mdio_ctrl() function */
+               nic->mdio_ctrl = mdio_ctrl_phy_82552_v;
+
                /* Workaround Si not advertising flow-control during autoneg */
                advert |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
                mdio_write(netdev, nic->mii.phy_id, MII_ADVERTISE, advert);
@@ -1581,7 +1716,7 @@ static int e100_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
                /* This is a hard error - log it. */
                DPRINTK(TX_ERR, DEBUG, "Out of Tx resources, returning skb\n");
                netif_stop_queue(netdev);
-               return 1;
+               return NETDEV_TX_BUSY;
        }
 
        netdev->trans_start = jiffies;
@@ -2585,6 +2720,7 @@ static int __devinit e100_probe(struct pci_dev *pdev,
        nic->netdev = netdev;
        nic->pdev = pdev;
        nic->msg_enable = (1 << debug) - 1;
+       nic->mdio_ctrl = mdio_ctrl_hw;
        pci_set_drvdata(pdev, netdev);
 
        if ((err = pci_enable_device(pdev))) {
@@ -2822,12 +2958,13 @@ static pci_ers_result_t e100_io_error_detected(struct pci_dev *pdev, pci_channel
        struct net_device *netdev = pci_get_drvdata(pdev);
        struct nic *nic = netdev_priv(netdev);
 
-       /* Similar to calling e100_down(), but avoids adapter I/O. */
-       e100_close(netdev);
-
-       /* Detach; put netif into a state similar to hotplug unplug. */
-       napi_enable(&nic->napi);
        netif_device_detach(netdev);
+
+       if (state == pci_channel_io_perm_failure)
+               return PCI_ERS_RESULT_DISCONNECT;
+
+       if (netif_running(netdev))
+               e100_down(nic);
        pci_disable_device(pdev);
 
        /* Request a slot reset. */
index fffb006b7d95c968d168eb81d2cab697e05ee455..8d36743c814008981e720e1b75300adbc5b9e936 100644 (file)
@@ -498,6 +498,8 @@ int e1000_up(struct e1000_adapter *adapter)
 
        e1000_irq_enable(adapter);
 
+       netif_wake_queue(adapter->netdev);
+
        /* fire a link change interrupt to start the watchdog */
        ew32(ICS, E1000_ICS_LSC);
        return 0;
@@ -1234,15 +1236,14 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
            !e1000_check_mng_mode(hw))
                e1000_get_hw_control(adapter);
 
-       /* tell the stack to leave us alone until e1000_open() is called */
-       netif_carrier_off(netdev);
-       netif_stop_queue(netdev);
-
        strcpy(netdev->name, "eth%d");
        err = register_netdev(netdev);
        if (err)
                goto err_register;
 
+       /* carrier off reporting is important to ethtool even BEFORE open */
+       netif_carrier_off(netdev);
+
        DPRINTK(PROBE, INFO, "Intel(R) PRO/1000 Network Connection\n");
 
        cards_found++;
@@ -1441,6 +1442,8 @@ static int e1000_open(struct net_device *netdev)
        if (test_bit(__E1000_TESTING, &adapter->flags))
                return -EBUSY;
 
+       netif_carrier_off(netdev);
+
        /* allocate transmit descriptors */
        err = e1000_setup_all_tx_resources(adapter);
        if (err)
@@ -2327,7 +2330,8 @@ static void e1000_set_rx_mode(struct net_device *netdev)
 {
        struct e1000_adapter *adapter = netdev_priv(netdev);
        struct e1000_hw *hw = &adapter->hw;
-       struct dev_addr_list *uc_ptr;
+       struct netdev_hw_addr *ha;
+       bool use_uc = false;
        struct dev_addr_list *mc_ptr;
        u32 rctl;
        u32 hash_value;
@@ -2366,12 +2370,11 @@ static void e1000_set_rx_mode(struct net_device *netdev)
                        rctl |= E1000_RCTL_VFE;
        }
 
-       uc_ptr = NULL;
        if (netdev->uc_count > rar_entries - 1) {
                rctl |= E1000_RCTL_UPE;
        } else if (!(netdev->flags & IFF_PROMISC)) {
                rctl &= ~E1000_RCTL_UPE;
-               uc_ptr = netdev->uc_list;
+               use_uc = true;
        }
 
        ew32(RCTL, rctl);
@@ -2389,13 +2392,20 @@ static void e1000_set_rx_mode(struct net_device *netdev)
         * if there are not 14 addresses, go ahead and clear the filters
         * -- with 82571 controllers only 0-13 entries are filled here
         */
+       i = 1;
+       if (use_uc)
+               list_for_each_entry(ha, &netdev->uc_list, list) {
+                       if (i == rar_entries)
+                               break;
+                       e1000_rar_set(hw, ha->addr, i++);
+               }
+
+       WARN_ON(i == rar_entries);
+
        mc_ptr = netdev->mc_list;
 
-       for (i = 1; i < rar_entries; i++) {
-               if (uc_ptr) {
-                       e1000_rar_set(hw, uc_ptr->da_addr, i);
-                       uc_ptr = uc_ptr->next;
-               } else if (mc_ptr) {
+       for (; i < rar_entries; i++) {
+               if (mc_ptr) {
                        e1000_rar_set(hw, mc_ptr->da_addr, i);
                        mc_ptr = mc_ptr->next;
                } else {
@@ -2405,7 +2415,6 @@ static void e1000_set_rx_mode(struct net_device *netdev)
                        E1000_WRITE_FLUSH();
                }
        }
-       WARN_ON(uc_ptr != NULL);
 
        /* load any remaining addresses into the hash table */
 
@@ -2590,7 +2599,6 @@ static void e1000_watchdog(unsigned long data)
                        ew32(TCTL, tctl);
 
                        netif_carrier_on(netdev);
-                       netif_wake_queue(netdev);
                        mod_timer(&adapter->phy_info_timer, round_jiffies(jiffies + 2 * HZ));
                        adapter->smartspeed = 0;
                } else {
@@ -2607,7 +2615,6 @@ static void e1000_watchdog(unsigned long data)
                        printk(KERN_INFO "e1000: %s NIC Link is Down\n",
                               netdev->name);
                        netif_carrier_off(netdev);
-                       netif_stop_queue(netdev);
                        mod_timer(&adapter->phy_info_timer, round_jiffies(jiffies + 2 * HZ));
 
                        /* 80003ES2LAN workaround--
@@ -2645,6 +2652,8 @@ static void e1000_watchdog(unsigned long data)
                         * (Do the reset outside of interrupt context). */
                        adapter->tx_timeout_count++;
                        schedule_work(&adapter->reset_task);
+                       /* return immediately since reset is imminent */
+                       return;
                }
        }
 
@@ -2989,7 +2998,7 @@ static int e1000_tx_map(struct e1000_adapter *adapter,
                        size -= 4;
 
                buffer_info->length = size;
-               buffer_info->dma = map[0] + offset;
+               buffer_info->dma = skb_shinfo(skb)->dma_head + offset;
                buffer_info->time_stamp = jiffies;
                buffer_info->next_to_watch = i;
 
@@ -3030,7 +3039,7 @@ static int e1000_tx_map(struct e1000_adapter *adapter,
                                size -= 4;
 
                        buffer_info->length = size;
-                       buffer_info->dma = map[f + 1] + offset;
+                       buffer_info->dma = map[f] + offset;
                        buffer_info->time_stamp = jiffies;
                        buffer_info->next_to_watch = i;
 
@@ -3362,7 +3371,6 @@ static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 
        if (count) {
                e1000_tx_queue(adapter, tx_ring, tx_flags, count);
-               netdev->trans_start = jiffies;
                /* Make sure there is space in the ring for the next send. */
                e1000_maybe_stop_tx(netdev, tx_ring, MAX_SKB_FRAGS + 2);
 
index 6c01a2072c8704d35f9697fffa1cd96e4a4f8253..b53b40ba88a806b545a2981d54e49f7ed44de6dc 100644 (file)
@@ -71,6 +71,7 @@ static s32 e1000_setup_link_82571(struct e1000_hw *hw);
 static void e1000_clear_hw_cntrs_82571(struct e1000_hw *hw);
 static bool e1000_check_mng_mode_82574(struct e1000_hw *hw);
 static s32 e1000_led_on_82574(struct e1000_hw *hw);
+static void e1000_put_hw_semaphore_82571(struct e1000_hw *hw);
 
 /**
  *  e1000_init_phy_params_82571 - Init PHY func ptrs.
@@ -212,6 +213,9 @@ static s32 e1000_init_mac_params_82571(struct e1000_adapter *adapter)
        struct e1000_hw *hw = &adapter->hw;
        struct e1000_mac_info *mac = &hw->mac;
        struct e1000_mac_operations *func = &mac->ops;
+       u32 swsm = 0;
+       u32 swsm2 = 0;
+       bool force_clear_smbi = false;
 
        /* Set media type */
        switch (adapter->pdev->device) {
@@ -276,6 +280,50 @@ static s32 e1000_init_mac_params_82571(struct e1000_adapter *adapter)
                break;
        }
 
+       /*
+        * Ensure that the inter-port SWSM.SMBI lock bit is clear before
+        * first NVM or PHY acess. This should be done for single-port
+        * devices, and for one port only on dual-port devices so that
+        * for those devices we can still use the SMBI lock to synchronize
+        * inter-port accesses to the PHY & NVM.
+        */
+       switch (hw->mac.type) {
+       case e1000_82571:
+       case e1000_82572:
+               swsm2 = er32(SWSM2);
+
+               if (!(swsm2 & E1000_SWSM2_LOCK)) {
+                       /* Only do this for the first interface on this card */
+                       ew32(SWSM2,
+                           swsm2 | E1000_SWSM2_LOCK);
+                       force_clear_smbi = true;
+               } else
+                       force_clear_smbi = false;
+               break;
+       default:
+               force_clear_smbi = true;
+               break;
+       }
+
+       if (force_clear_smbi) {
+               /* Make sure SWSM.SMBI is clear */
+               swsm = er32(SWSM);
+               if (swsm & E1000_SWSM_SMBI) {
+                       /* This bit should not be set on a first interface, and
+                        * indicates that the bootagent or EFI code has
+                        * improperly left this bit enabled
+                        */
+                       hw_dbg(hw, "Please update your 82571 Bootagent\n");
+               }
+               ew32(SWSM, swsm & ~E1000_SWSM_SMBI);
+       }
+
+       /*
+        * Initialze device specific counter of SMBI acquisition
+        * timeouts.
+        */
+        hw->dev_spec.e82571.smb_counter = 0;
+
        return 0;
 }
 
@@ -341,8 +389,10 @@ static s32 e1000_get_variants_82571(struct e1000_adapter *adapter)
                        if (e1000_read_nvm(&adapter->hw, NVM_INIT_3GIO_3, 1,
                                       &eeprom_data) < 0)
                                break;
-                       if (eeprom_data & NVM_WORD1A_ASPM_MASK)
-                               adapter->flags &= ~FLAG_HAS_JUMBO_FRAMES;
+                       if (!(eeprom_data & NVM_WORD1A_ASPM_MASK)) {
+                               adapter->flags |= FLAG_HAS_JUMBO_FRAMES;
+                               adapter->max_hw_frame_size = DEFAULT_JUMBO;
+                       }
                }
                break;
        default:
@@ -411,11 +461,37 @@ static s32 e1000_get_phy_id_82571(struct e1000_hw *hw)
 static s32 e1000_get_hw_semaphore_82571(struct e1000_hw *hw)
 {
        u32 swsm;
-       s32 timeout = hw->nvm.word_size + 1;
+       s32 sw_timeout = hw->nvm.word_size + 1;
+       s32 fw_timeout = hw->nvm.word_size + 1;
        s32 i = 0;
 
+       /*
+        * If we have timedout 3 times on trying to acquire
+        * the inter-port SMBI semaphore, there is old code
+        * operating on the other port, and it is not
+        * releasing SMBI. Modify the number of times that
+        * we try for the semaphore to interwork with this
+        * older code.
+        */
+       if (hw->dev_spec.e82571.smb_counter > 2)
+               sw_timeout = 1;
+
+       /* Get the SW semaphore */
+       while (i < sw_timeout) {
+               swsm = er32(SWSM);
+               if (!(swsm & E1000_SWSM_SMBI))
+                       break;
+
+               udelay(50);
+               i++;
+       }
+
+       if (i == sw_timeout) {
+               hw_dbg(hw, "Driver can't access device - SMBI bit is set.\n");
+               hw->dev_spec.e82571.smb_counter++;
+       }
        /* Get the FW semaphore. */
-       for (i = 0; i < timeout; i++) {
+       for (i = 0; i < fw_timeout; i++) {
                swsm = er32(SWSM);
                ew32(SWSM, swsm | E1000_SWSM_SWESMBI);
 
@@ -426,9 +502,9 @@ static s32 e1000_get_hw_semaphore_82571(struct e1000_hw *hw)
                udelay(50);
        }
 
-       if (i == timeout) {
+       if (i == fw_timeout) {
                /* Release semaphores */
-               e1000e_put_hw_semaphore(hw);
+               e1000_put_hw_semaphore_82571(hw);
                hw_dbg(hw, "Driver can't access the NVM\n");
                return -E1000_ERR_NVM;
        }
@@ -447,9 +523,7 @@ static void e1000_put_hw_semaphore_82571(struct e1000_hw *hw)
        u32 swsm;
 
        swsm = er32(SWSM);
-
-       swsm &= ~E1000_SWSM_SWESMBI;
-
+       swsm &= ~(E1000_SWSM_SMBI | E1000_SWSM_SWESMBI);
        ew32(SWSM, swsm);
 }
 
@@ -1585,6 +1659,7 @@ static void e1000_clear_hw_cntrs_82571(struct e1000_hw *hw)
 static struct e1000_mac_operations e82571_mac_ops = {
        /* .check_mng_mode: mac type dependent */
        /* .check_for_link: media type dependent */
+       .id_led_init            = e1000e_id_led_init,
        .cleanup_led            = e1000e_cleanup_led_generic,
        .clear_hw_cntrs         = e1000_clear_hw_cntrs_82571,
        .get_bus_info           = e1000e_get_bus_info_pcie,
@@ -1596,6 +1671,7 @@ static struct e1000_mac_operations e82571_mac_ops = {
        .init_hw                = e1000_init_hw_82571,
        .setup_link             = e1000_setup_link_82571,
        /* .setup_physical_interface: media type dependent */
+       .setup_led              = e1000e_setup_led_generic,
 };
 
 static struct e1000_phy_operations e82_phy_ops_igp = {
@@ -1672,6 +1748,7 @@ struct e1000_info e1000_82571_info = {
                                  | FLAG_TARC_SPEED_MODE_BIT /* errata */
                                  | FLAG_APME_CHECK_PORT_B,
        .pba                    = 38,
+       .max_hw_frame_size      = DEFAULT_JUMBO,
        .get_variants           = e1000_get_variants_82571,
        .mac_ops                = &e82571_mac_ops,
        .phy_ops                = &e82_phy_ops_igp,
@@ -1688,6 +1765,7 @@ struct e1000_info e1000_82572_info = {
                                  | FLAG_HAS_CTRLEXT_ON_LOAD
                                  | FLAG_TARC_SPEED_MODE_BIT, /* errata */
        .pba                    = 38,
+       .max_hw_frame_size      = DEFAULT_JUMBO,
        .get_variants           = e1000_get_variants_82571,
        .mac_ops                = &e82571_mac_ops,
        .phy_ops                = &e82_phy_ops_igp,
@@ -1706,6 +1784,7 @@ struct e1000_info e1000_82573_info = {
                                  | FLAG_HAS_ERT
                                  | FLAG_HAS_SWSM_ON_LOAD,
        .pba                    = 20,
+       .max_hw_frame_size      = ETH_FRAME_LEN + ETH_FCS_LEN,
        .get_variants           = e1000_get_variants_82571,
        .mac_ops                = &e82571_mac_ops,
        .phy_ops                = &e82_phy_ops_m88,
@@ -1724,6 +1803,7 @@ struct e1000_info e1000_82574_info = {
                                  | FLAG_HAS_AMT
                                  | FLAG_HAS_CTRLEXT_ON_LOAD,
        .pba                    = 20,
+       .max_hw_frame_size      = ETH_FRAME_LEN + ETH_FCS_LEN,
        .get_variants           = e1000_get_variants_82571,
        .mac_ops                = &e82571_mac_ops,
        .phy_ops                = &e82_phy_ops_bm,
@@ -1740,6 +1820,7 @@ struct e1000_info e1000_82583_info = {
                                  | FLAG_HAS_AMT
                                  | FLAG_HAS_CTRLEXT_ON_LOAD,
        .pba                    = 20,
+       .max_hw_frame_size      = DEFAULT_JUMBO,
        .get_variants           = e1000_get_variants_82571,
        .mac_ops                = &e82571_mac_ops,
        .phy_ops                = &e82_phy_ops_bm,
index 243aa499fe902a481a38288b5b264edb5c2efb9f..8890c97e1120436cc68c3b930a8bf78e9cb24369 100644 (file)
@@ -56,6 +56,7 @@
 /* Wake Up Control */
 #define E1000_WUC_APME       0x00000001 /* APM Enable */
 #define E1000_WUC_PME_EN     0x00000002 /* PME Enable */
+#define E1000_WUC_PHY_WAKE   0x00000100 /* if PHY supports wakeup */
 
 /* Wake Up Filter Control */
 #define E1000_WUFC_LNKC 0x00000001 /* Link Status Change Wakeup Enable */
 #define E1000_WUFC_BC   0x00000010 /* Broadcast Wakeup Enable */
 #define E1000_WUFC_ARP  0x00000020 /* ARP Request Packet Wakeup Enable */
 
+/* Wake Up Status */
+#define E1000_WUS_LNKC         E1000_WUFC_LNKC
+#define E1000_WUS_MAG          E1000_WUFC_MAG
+#define E1000_WUS_EX           E1000_WUFC_EX
+#define E1000_WUS_MC           E1000_WUFC_MC
+#define E1000_WUS_BC           E1000_WUFC_BC
+
 /* Extended Device Control */
 #define E1000_CTRL_EXT_SDP7_DATA 0x00000080 /* Value of SW Definable Pin 7 */
 #define E1000_CTRL_EXT_EE_RST    0x00002000 /* Reinitialize from EEPROM */
@@ -77,6 +85,7 @@
 #define E1000_CTRL_EXT_IAME           0x08000000 /* Interrupt acknowledge Auto-mask */
 #define E1000_CTRL_EXT_INT_TIMER_CLR  0x20000000 /* Clear Interrupt timers after IMS clear */
 #define E1000_CTRL_EXT_PBA_CLR        0x80000000 /* PBA Clear */
+#define E1000_CTRL_EXT_PHYPDEN        0x00100000
 
 /* Receive Descriptor bit definitions */
 #define E1000_RXD_STAT_DD       0x01    /* Descriptor Done */
 #define E1000_RCTL_DTYP_PS        0x00000400    /* Packet Split descriptor */
 #define E1000_RCTL_RDMTS_HALF     0x00000000    /* Rx desc min threshold size */
 #define E1000_RCTL_MO_SHIFT       12            /* multicast offset shift */
+#define E1000_RCTL_MO_3           0x00003000    /* multicast offset 15:4 */
 #define E1000_RCTL_BAM            0x00008000    /* broadcast enable */
 /* these buffer sizes are valid if E1000_RCTL_BSEX is 0 */
 #define E1000_RCTL_SZ_2048        0x00000000    /* Rx buffer size 2048 */
 #define E1000_RCTL_VFE            0x00040000    /* vlan filter enable */
 #define E1000_RCTL_CFIEN          0x00080000    /* canonical form enable */
 #define E1000_RCTL_CFI            0x00100000    /* canonical form indicator */
+#define E1000_RCTL_PMCF           0x00800000    /* pass MAC control frames */
 #define E1000_RCTL_BSEX           0x02000000    /* Buffer size extension */
 #define E1000_RCTL_SECRC          0x04000000    /* Strip Ethernet CRC */
 
 #define AUTONEG_ADVERTISE_SPEED_DEFAULT   E1000_ALL_SPEED_DUPLEX
 
 /* LED Control */
+#define E1000_PHY_LED0_MODE_MASK          0x00000007
+#define E1000_PHY_LED0_IVRT               0x00000008
+#define E1000_PHY_LED0_MASK               0x0000001F
+
 #define E1000_LEDCTL_LED0_MODE_MASK       0x0000000F
 #define E1000_LEDCTL_LED0_MODE_SHIFT      0
 #define E1000_LEDCTL_LED0_IVRT            0x00000040
 #define E1000_LEDCTL_LED0_BLINK           0x00000080
 
+#define E1000_LEDCTL_MODE_LINK_UP       0x2
 #define E1000_LEDCTL_MODE_LED_ON        0xE
 #define E1000_LEDCTL_MODE_LED_OFF       0xF
 
 #define E1000_SWSM_SWESMBI      0x00000002 /* FW Semaphore bit */
 #define E1000_SWSM_DRV_LOAD     0x00000008 /* Driver Loaded Bit */
 
+#define E1000_SWSM2_LOCK        0x00000002 /* Secondary driver semaphore bit */
+
 /* Interrupt Cause Read */
 #define E1000_ICR_TXDW          0x00000001 /* Transmit desc written back */
 #define E1000_ICR_LSC           0x00000004 /* Link Status Change */
 #define AUTO_READ_DONE_TIMEOUT      10
 
 /* Flow Control */
+#define E1000_FCRTH_RTH  0x0000FFF8     /* Mask Bits[15:3] for RTH */
+#define E1000_FCRTL_RTL  0x0000FFF8     /* Mask Bits[15:3] for RTL */
 #define E1000_FCRTL_XONE 0x80000000     /* Enable XON frame transmission */
 
 /* Transmit Configuration Word */
 #define IFE_C_E_PHY_ID       0x02A80310
 #define BME1000_E_PHY_ID     0x01410CB0
 #define BME1000_E_PHY_ID_R2  0x01410CB1
+#define I82577_E_PHY_ID      0x01540050
+#define I82578_E_PHY_ID      0x004DD040
 
 /* M88E1000 Specific Registers */
 #define M88E1000_PHY_SPEC_CTRL     0x10  /* PHY Specific Control Register */
 #define M88EC018_EPSCR_DOWNSHIFT_COUNTER_MASK  0x0E00
 #define M88EC018_EPSCR_DOWNSHIFT_COUNTER_5X    0x0800
 
+#define I82578_EPSCR_DOWNSHIFT_ENABLE          0x0020
+#define I82578_EPSCR_DOWNSHIFT_COUNTER_MASK    0x001C
+
 /* BME1000 PHY Specific Control Register */
 #define BME1000_PSCR_ENABLE_DOWNSHIFT   0x0800 /* 1 = enable downshift */
 
index 44f0bf23dafc241de92c7dfde76d4f9c5d4e24a3..981936c1fb46759846cad4b379471fe61ee1a99e 100644 (file)
@@ -96,6 +96,51 @@ struct e1000_info;
 /* Number of packet split data buffers (not including the header buffer) */
 #define PS_PAGE_BUFFERS                        (MAX_PS_BUFFERS - 1)
 
+#define DEFAULT_JUMBO                  9234
+
+/* BM/HV Specific Registers */
+#define BM_PORT_CTRL_PAGE                 769
+
+#define PHY_UPPER_SHIFT                   21
+#define BM_PHY_REG(page, reg) \
+       (((reg) & MAX_PHY_REG_ADDRESS) |\
+        (((page) & 0xFFFF) << PHY_PAGE_SHIFT) |\
+        (((reg) & ~MAX_PHY_REG_ADDRESS) << (PHY_UPPER_SHIFT - PHY_PAGE_SHIFT)))
+
+/* PHY Wakeup Registers and defines */
+#define BM_RCTL         PHY_REG(BM_WUC_PAGE, 0)
+#define BM_WUC          PHY_REG(BM_WUC_PAGE, 1)
+#define BM_WUFC         PHY_REG(BM_WUC_PAGE, 2)
+#define BM_WUS          PHY_REG(BM_WUC_PAGE, 3)
+#define BM_RAR_L(_i)    (BM_PHY_REG(BM_WUC_PAGE, 16 + ((_i) << 2)))
+#define BM_RAR_M(_i)    (BM_PHY_REG(BM_WUC_PAGE, 17 + ((_i) << 2)))
+#define BM_RAR_H(_i)    (BM_PHY_REG(BM_WUC_PAGE, 18 + ((_i) << 2)))
+#define BM_RAR_CTRL(_i) (BM_PHY_REG(BM_WUC_PAGE, 19 + ((_i) << 2)))
+#define BM_MTA(_i)      (BM_PHY_REG(BM_WUC_PAGE, 128 + ((_i) << 1)))
+
+#define BM_RCTL_UPE           0x0001          /* Unicast Promiscuous Mode */
+#define BM_RCTL_MPE           0x0002          /* Multicast Promiscuous Mode */
+#define BM_RCTL_MO_SHIFT      3               /* Multicast Offset Shift */
+#define BM_RCTL_MO_MASK       (3 << 3)        /* Multicast Offset Mask */
+#define BM_RCTL_BAM           0x0020          /* Broadcast Accept Mode */
+#define BM_RCTL_PMCF          0x0040          /* Pass MAC Control Frames */
+#define BM_RCTL_RFCE          0x0080          /* Rx Flow Control Enable */
+
+#define HV_SCC_UPPER           PHY_REG(778, 16) /* Single Collision Count */
+#define HV_SCC_LOWER           PHY_REG(778, 17)
+#define HV_ECOL_UPPER          PHY_REG(778, 18) /* Excessive Collision Count */
+#define HV_ECOL_LOWER          PHY_REG(778, 19)
+#define HV_MCC_UPPER           PHY_REG(778, 20) /* Multiple Collision Count */
+#define HV_MCC_LOWER           PHY_REG(778, 21)
+#define HV_LATECOL_UPPER       PHY_REG(778, 23) /* Late Collision Count */
+#define HV_LATECOL_LOWER       PHY_REG(778, 24)
+#define HV_COLC_UPPER          PHY_REG(778, 25) /* Collision Count */
+#define HV_COLC_LOWER          PHY_REG(778, 26)
+#define HV_DC_UPPER            PHY_REG(778, 27) /* Defer Count */
+#define HV_DC_LOWER            PHY_REG(778, 28)
+#define HV_TNCRS_UPPER         PHY_REG(778, 29) /* Transmit with no CRS */
+#define HV_TNCRS_LOWER         PHY_REG(778, 30)
+
 enum e1000_boards {
        board_82571,
        board_82572,
@@ -106,6 +151,7 @@ enum e1000_boards {
        board_ich8lan,
        board_ich9lan,
        board_ich10lan,
+       board_pchlan,
 };
 
 struct e1000_queue_stats {
@@ -293,6 +339,7 @@ struct e1000_adapter {
        u32 eeprom_wol;
        u32 wol;
        u32 pba;
+       u32 max_hw_frame_size;
 
        bool fc_autoneg;
 
@@ -302,6 +349,7 @@ struct e1000_adapter {
        unsigned int flags2;
        struct work_struct downshift_task;
        struct work_struct update_phy_task;
+       struct work_struct led_blink_task;
 };
 
 struct e1000_info {
@@ -309,6 +357,7 @@ struct e1000_info {
        unsigned int            flags;
        unsigned int            flags2;
        u32                     pba;
+       u32                     max_hw_frame_size;
        s32                     (*get_variants)(struct e1000_adapter *);
        struct e1000_mac_operations *mac_ops;
        struct e1000_phy_operations *phy_ops;
@@ -351,6 +400,7 @@ struct e1000_info {
 
 /* CRC Stripping defines */
 #define FLAG2_CRC_STRIPPING               (1 << 0)
+#define FLAG2_HAS_PHY_WAKEUP              (1 << 1)
 
 #define E1000_RX_DESC_PS(R, i)     \
        (&(((union e1000_rx_desc_packet_split *)((R).desc))[i]))
@@ -404,6 +454,7 @@ extern struct e1000_info e1000_82583_info;
 extern struct e1000_info e1000_ich8_info;
 extern struct e1000_info e1000_ich9_info;
 extern struct e1000_info e1000_ich10_info;
+extern struct e1000_info e1000_pch_info;
 extern struct e1000_info e1000_es2_info;
 
 extern s32 e1000e_read_pba_num(struct e1000_hw *hw, u32 *pba_num);
@@ -425,6 +476,7 @@ extern void e1000e_disable_gig_wol_ich8lan(struct e1000_hw *hw);
 extern s32 e1000e_check_for_copper_link(struct e1000_hw *hw);
 extern s32 e1000e_check_for_fiber_link(struct e1000_hw *hw);
 extern s32 e1000e_check_for_serdes_link(struct e1000_hw *hw);
+extern s32 e1000e_setup_led_generic(struct e1000_hw *hw);
 extern s32 e1000e_cleanup_led_generic(struct e1000_hw *hw);
 extern s32 e1000e_led_on_generic(struct e1000_hw *hw);
 extern s32 e1000e_led_off_generic(struct e1000_hw *hw);
@@ -493,6 +545,15 @@ extern s32 e1000e_phy_reset_dsp(struct e1000_hw *hw);
 extern s32 e1000e_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data);
 extern s32 e1000e_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data);
 extern s32 e1000e_check_downshift(struct e1000_hw *hw);
+extern s32 e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data);
+extern s32 e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data);
+extern s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw, bool slow);
+extern s32 e1000_link_stall_workaround_hv(struct e1000_hw *hw);
+extern s32 e1000_copper_link_setup_82577(struct e1000_hw *hw);
+extern s32 e1000_check_polarity_82577(struct e1000_hw *hw);
+extern s32 e1000_get_phy_info_82577(struct e1000_hw *hw);
+extern s32 e1000_phy_force_speed_duplex_82577(struct e1000_hw *hw);
+extern s32 e1000_get_cable_length_82577(struct e1000_hw *hw);
 
 static inline s32 e1000_phy_hw_reset(struct e1000_hw *hw)
 {
index 8964838c686b7fcb83fcd745574fc453cddb246d..ae5d73689353acf48a1146392f6a1fe50bd06a13 100644 (file)
@@ -1366,6 +1366,7 @@ static void e1000_clear_hw_cntrs_80003es2lan(struct e1000_hw *hw)
 }
 
 static struct e1000_mac_operations es2_mac_ops = {
+       .id_led_init            = e1000e_id_led_init,
        .check_mng_mode         = e1000e_check_mng_mode_generic,
        /* check_for_link dependent on media type */
        .cleanup_led            = e1000e_cleanup_led_generic,
@@ -1379,6 +1380,7 @@ static struct e1000_mac_operations es2_mac_ops = {
        .init_hw                = e1000_init_hw_80003es2lan,
        .setup_link             = e1000e_setup_link,
        /* setup_physical_interface dependent on media type */
+       .setup_led              = e1000e_setup_led_generic,
 };
 
 static struct e1000_phy_operations es2_phy_ops = {
@@ -1422,6 +1424,7 @@ struct e1000_info e1000_es2_info = {
                                  | FLAG_DISABLE_FC_PAUSE_TIME /* errata */
                                  | FLAG_TIPG_MEDIUM_FOR_80003ESLAN,
        .pba                    = 38,
+       .max_hw_frame_size      = DEFAULT_JUMBO,
        .get_variants           = e1000_get_variants_80003es2lan,
        .mac_ops                = &es2_mac_ops,
        .phy_ops                = &es2_phy_ops,
index 4d25ede88369ddefe384465c91a0a7111011cdff..1bf4d2a5d34f8b7421839033c7dd4cedb748bc1c 100644 (file)
@@ -167,6 +167,15 @@ static int e1000_get_settings(struct net_device *netdev,
 
        ecmd->autoneg = ((hw->phy.media_type == e1000_media_type_fiber) ||
                         hw->mac.autoneg) ? AUTONEG_ENABLE : AUTONEG_DISABLE;
+
+       /* MDI-X => 2; MDI =>1; Invalid =>0 */
+       if ((hw->phy.media_type == e1000_media_type_copper) &&
+           !hw->mac.get_link_status)
+               ecmd->eth_tp_mdix = hw->phy.is_mdix ? ETH_TP_MDI_X :
+                                                     ETH_TP_MDI;
+       else
+               ecmd->eth_tp_mdix = ETH_TP_MDI_INVALID;
+
        return 0;
 }
 
@@ -776,6 +785,7 @@ static int e1000_reg_test(struct e1000_adapter *adapter, u64 *data)
        u32 after;
        u32 i;
        u32 toggle;
+       u32 mask;
 
        /*
         * The status register is Read Only, so a write should fail.
@@ -788,17 +798,9 @@ static int e1000_reg_test(struct e1000_adapter *adapter, u64 *data)
        case e1000_80003es2lan:
                toggle = 0x7FFFF3FF;
                break;
-       case e1000_82573:
-       case e1000_82574:
-       case e1000_82583:
-       case e1000_ich8lan:
-       case e1000_ich9lan:
-       case e1000_ich10lan:
+        default:
                toggle = 0x7FFFF033;
                break;
-       default:
-               toggle = 0xFFFFF833;
-               break;
        }
 
        before = er32(STATUS);
@@ -844,11 +846,18 @@ static int e1000_reg_test(struct e1000_adapter *adapter, u64 *data)
                REG_PATTERN_TEST(E1000_TXCW, 0xC000FFFF, 0x0000FFFF);
        REG_PATTERN_TEST(E1000_TDBAL, 0xFFFFFFF0, 0xFFFFFFFF);
        REG_PATTERN_TEST(E1000_TIDV, 0x0000FFFF, 0x0000FFFF);
+       mask = 0x8003FFFF;
+       switch (mac->type) {
+       case e1000_ich10lan:
+       case e1000_pchlan:
+               mask |= (1 << 18);
+               break;
+       default:
+               break;
+       }
        for (i = 0; i < mac->rar_entry_count; i++)
                REG_PATTERN_TEST_ARRAY(E1000_RA, ((i << 1) + 1),
-                                      ((mac->type == e1000_ich10lan) ?
-                                          0x8007FFFF : 0x8003FFFF),
-                                      0xFFFFFFFF);
+                                      mask, 0xFFFFFFFF);
 
        for (i = 0; i < mac->mta_reg_count; i++)
                REG_PATTERN_TEST_ARRAY(E1000_MTA, i, 0xFFFFFFFF, 0xFFFFFFFF);
@@ -1786,15 +1795,22 @@ static int e1000_set_wol(struct net_device *netdev,
 /* bit defines for adapter->led_status */
 #define E1000_LED_ON           0
 
-static void e1000_led_blink_callback(unsigned long data)
+static void e1000e_led_blink_task(struct work_struct *work)
 {
-       struct e1000_adapter *adapter = (struct e1000_adapter *) data;
+       struct e1000_adapter *adapter = container_of(work,
+                                       struct e1000_adapter, led_blink_task);
 
        if (test_and_change_bit(E1000_LED_ON, &adapter->led_status))
                adapter->hw.mac.ops.led_off(&adapter->hw);
        else
                adapter->hw.mac.ops.led_on(&adapter->hw);
+}
+
+static void e1000_led_blink_callback(unsigned long data)
+{
+       struct e1000_adapter *adapter = (struct e1000_adapter *) data;
 
+       schedule_work(&adapter->led_blink_task);
        mod_timer(&adapter->blink_timer, jiffies + E1000_ID_INTERVAL);
 }
 
@@ -1807,7 +1823,9 @@ static int e1000_phys_id(struct net_device *netdev, u32 data)
                data = INT_MAX;
 
        if ((hw->phy.type == e1000_phy_ife) ||
+           (hw->mac.type == e1000_pchlan) ||
            (hw->mac.type == e1000_82574)) {
+               INIT_WORK(&adapter->led_blink_task, e1000e_led_blink_task);
                if (!adapter->blink_timer.function) {
                        init_timer(&adapter->blink_timer);
                        adapter->blink_timer.function =
index d8b82296f41e042cc3a7c9b486349d58b25e1802..163c1c0cfee7004b7fdcf7935300aacb3431b049 100644 (file)
@@ -193,7 +193,11 @@ enum e1e_registers {
        E1000_RXCSUM   = 0x05000, /* Rx Checksum Control - RW */
        E1000_RFCTL    = 0x05008, /* Receive Filter Control */
        E1000_MTA      = 0x05200, /* Multicast Table Array - RW Array */
-       E1000_RA       = 0x05400, /* Receive Address - RW Array */
+       E1000_RAL_BASE = 0x05400, /* Receive Address Low - RW */
+#define E1000_RAL(_n)   (E1000_RAL_BASE + ((_n) * 8))
+#define E1000_RA        (E1000_RAL(0))
+       E1000_RAH_BASE = 0x05404, /* Receive Address High - RW */
+#define E1000_RAH(_n)   (E1000_RAH_BASE + ((_n) * 8))
        E1000_VFTA     = 0x05600, /* VLAN Filter Table Array - RW Array */
        E1000_WUC      = 0x05800, /* Wakeup Control - RW */
        E1000_WUFC     = 0x05808, /* Wakeup Filter Control - RW */
@@ -210,6 +214,7 @@ enum e1e_registers {
        E1000_FACTPS    = 0x05B30, /* Function Active and Power State to MNG */
        E1000_SWSM      = 0x05B50, /* SW Semaphore */
        E1000_FWSM      = 0x05B54, /* FW Semaphore */
+       E1000_SWSM2     = 0x05B58, /* Driver-only SW semaphore */
        E1000_HICR      = 0x08F00, /* Host Interface Control */
 };
 
@@ -253,7 +258,7 @@ enum e1e_registers {
 #define IGP01E1000_PLHR_SS_DOWNGRADE   0x8000
 
 #define IGP01E1000_PSSR_POLARITY_REVERSED      0x0002
-#define IGP01E1000_PSSR_MDIX                   0x0008
+#define IGP01E1000_PSSR_MDIX                   0x0800
 #define IGP01E1000_PSSR_SPEED_MASK             0xC000
 #define IGP01E1000_PSSR_SPEED_1000MBPS         0xC000
 
@@ -368,6 +373,10 @@ enum e1e_registers {
 #define E1000_DEV_ID_ICH10_R_BM_V              0x10CE
 #define E1000_DEV_ID_ICH10_D_BM_LM             0x10DE
 #define E1000_DEV_ID_ICH10_D_BM_LF             0x10DF
+#define E1000_DEV_ID_PCH_M_HV_LM               0x10EA
+#define E1000_DEV_ID_PCH_M_HV_LC               0x10EB
+#define E1000_DEV_ID_PCH_D_HV_DM               0x10EF
+#define E1000_DEV_ID_PCH_D_HV_DC               0x10F0
 
 #define E1000_REVISION_4 4
 
@@ -383,6 +392,7 @@ enum e1000_mac_type {
        e1000_ich8lan,
        e1000_ich9lan,
        e1000_ich10lan,
+       e1000_pchlan,
 };
 
 enum e1000_media_type {
@@ -417,6 +427,8 @@ enum e1000_phy_type {
        e1000_phy_igp_3,
        e1000_phy_ife,
        e1000_phy_bm,
+       e1000_phy_82578,
+       e1000_phy_82577,
 };
 
 enum e1000_bus_width {
@@ -720,6 +732,7 @@ struct e1000_host_mng_command_info {
 
 /* Function pointers and static data for the MAC. */
 struct e1000_mac_operations {
+       s32  (*id_led_init)(struct e1000_hw *);
        bool (*check_mng_mode)(struct e1000_hw *);
        s32  (*check_for_link)(struct e1000_hw *);
        s32  (*cleanup_led)(struct e1000_hw *);
@@ -733,11 +746,13 @@ struct e1000_mac_operations {
        s32  (*init_hw)(struct e1000_hw *);
        s32  (*setup_link)(struct e1000_hw *);
        s32  (*setup_physical_interface)(struct e1000_hw *);
+       s32  (*setup_led)(struct e1000_hw *);
 };
 
 /* Function pointers for the PHY. */
 struct e1000_phy_operations {
        s32  (*acquire_phy)(struct e1000_hw *);
+       s32  (*check_polarity)(struct e1000_hw *);
        s32  (*check_reset_block)(struct e1000_hw *);
        s32  (*commit_phy)(struct e1000_hw *);
        s32  (*force_speed_duplex)(struct e1000_hw *);
@@ -869,6 +884,7 @@ struct e1000_fc_info {
 struct e1000_dev_spec_82571 {
        bool laa_is_present;
        bool alt_mac_addr_is_present;
+       u32 smb_counter;
 };
 
 struct e1000_shadow_ram {
index 6d1aab6316baec1a720f6fc4200e4b569bb9233e..9e23f50fb9cdfa32be3428fbc540e3312d16018e 100644 (file)
  * 82567LF-3 Gigabit Network Connection
  * 82567LM-3 Gigabit Network Connection
  * 82567LM-4 Gigabit Network Connection
+ * 82577LM Gigabit Network Connection
+ * 82577LC Gigabit Network Connection
+ * 82578DM Gigabit Network Connection
+ * 82578DC Gigabit Network Connection
  */
 
 #include <linux/netdevice.h>
 #define IGP3_VR_CTRL_DEV_POWERDOWN_MODE_MASK 0x0300
 #define IGP3_VR_CTRL_MODE_SHUTDOWN     0x0200
 
+#define HV_LED_CONFIG          PHY_REG(768, 30) /* LED Configuration */
+
 /* ICH GbE Flash Hardware Sequencing Flash Status Register bit breakdown */
 /* Offset 04h HSFSTS */
 union ich8_hws_flash_status {
@@ -186,6 +192,14 @@ static s32 e1000_read_flash_data_ich8lan(struct e1000_hw *hw, u32 offset,
 static s32 e1000_setup_copper_link_ich8lan(struct e1000_hw *hw);
 static s32 e1000_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw);
 static s32 e1000_get_cfg_done_ich8lan(struct e1000_hw *hw);
+static s32 e1000_cleanup_led_ich8lan(struct e1000_hw *hw);
+static s32 e1000_led_on_ich8lan(struct e1000_hw *hw);
+static s32 e1000_led_off_ich8lan(struct e1000_hw *hw);
+static s32 e1000_id_led_init_pchlan(struct e1000_hw *hw);
+static s32 e1000_setup_led_pchlan(struct e1000_hw *hw);
+static s32 e1000_cleanup_led_pchlan(struct e1000_hw *hw);
+static s32 e1000_led_on_pchlan(struct e1000_hw *hw);
+static s32 e1000_led_off_pchlan(struct e1000_hw *hw);
 
 static inline u16 __er16flash(struct e1000_hw *hw, unsigned long reg)
 {
@@ -212,6 +226,41 @@ static inline void __ew32flash(struct e1000_hw *hw, unsigned long reg, u32 val)
 #define ew16flash(reg,val)     __ew16flash(hw, (reg), (val))
 #define ew32flash(reg,val)     __ew32flash(hw, (reg), (val))
 
+/**
+ *  e1000_init_phy_params_pchlan - Initialize PHY function pointers
+ *  @hw: pointer to the HW structure
+ *
+ *  Initialize family-specific PHY parameters and function pointers.
+ **/
+static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw)
+{
+       struct e1000_phy_info *phy = &hw->phy;
+       s32 ret_val = 0;
+
+       phy->addr                     = 1;
+       phy->reset_delay_us           = 100;
+
+       phy->ops.check_polarity       = e1000_check_polarity_ife_ich8lan;
+       phy->ops.read_phy_reg         = e1000_read_phy_reg_hv;
+       phy->ops.write_phy_reg        = e1000_write_phy_reg_hv;
+       phy->autoneg_mask             = AUTONEG_ADVERTISE_SPEED_DEFAULT;
+
+       phy->id = e1000_phy_unknown;
+       e1000e_get_phy_id(hw);
+       phy->type = e1000e_get_phy_type_from_id(phy->id);
+
+       if (phy->type == e1000_phy_82577) {
+               phy->ops.check_polarity = e1000_check_polarity_82577;
+               phy->ops.force_speed_duplex =
+                       e1000_phy_force_speed_duplex_82577;
+               phy->ops.get_cable_length   = e1000_get_cable_length_82577;
+               phy->ops.get_phy_info = e1000_get_phy_info_82577;
+               phy->ops.commit_phy = e1000e_phy_sw_reset;
+       }
+
+       return ret_val;
+}
+
 /**
  *  e1000_init_phy_params_ich8lan - Initialize PHY function pointers
  *  @hw: pointer to the HW structure
@@ -273,6 +322,8 @@ static s32 e1000_init_phy_params_ich8lan(struct e1000_hw *hw)
                break;
        }
 
+       phy->ops.check_polarity = e1000_check_polarity_ife_ich8lan;
+
        return 0;
 }
 
@@ -358,6 +409,36 @@ static s32 e1000_init_mac_params_ich8lan(struct e1000_adapter *adapter)
        /* Set if manageability features are enabled. */
        mac->arc_subsystem_valid = 1;
 
+       /* LED operations */
+       switch (mac->type) {
+       case e1000_ich8lan:
+       case e1000_ich9lan:
+       case e1000_ich10lan:
+               /* ID LED init */
+               mac->ops.id_led_init = e1000e_id_led_init;
+               /* setup LED */
+               mac->ops.setup_led = e1000e_setup_led_generic;
+               /* cleanup LED */
+               mac->ops.cleanup_led = e1000_cleanup_led_ich8lan;
+               /* turn on/off LED */
+               mac->ops.led_on = e1000_led_on_ich8lan;
+               mac->ops.led_off = e1000_led_off_ich8lan;
+               break;
+       case e1000_pchlan:
+               /* ID LED init */
+               mac->ops.id_led_init = e1000_id_led_init_pchlan;
+               /* setup LED */
+               mac->ops.setup_led = e1000_setup_led_pchlan;
+               /* cleanup LED */
+               mac->ops.cleanup_led = e1000_cleanup_led_pchlan;
+               /* turn on/off LED */
+               mac->ops.led_on = e1000_led_on_pchlan;
+               mac->ops.led_off = e1000_led_off_pchlan;
+               break;
+       default:
+               break;
+       }
+
        /* Enable PCS Lock-loss workaround for ICH8 */
        if (mac->type == e1000_ich8lan)
                e1000e_set_kmrn_lock_loss_workaround_ich8lan(hw, 1);
@@ -378,10 +459,18 @@ static s32 e1000_get_variants_ich8lan(struct e1000_adapter *adapter)
        if (rc)
                return rc;
 
-       rc = e1000_init_phy_params_ich8lan(hw);
+       if (hw->mac.type == e1000_pchlan)
+               rc = e1000_init_phy_params_pchlan(hw);
+       else
+               rc = e1000_init_phy_params_ich8lan(hw);
        if (rc)
                return rc;
 
+       if (adapter->hw.phy.type == e1000_phy_ife) {
+               adapter->flags &= ~FLAG_HAS_JUMBO_FRAMES;
+               adapter->max_hw_frame_size = ETH_FRAME_LEN + ETH_FCS_LEN;
+       }
+
        if ((adapter->hw.mac.type == e1000_ich8lan) &&
            (adapter->hw.phy.type == e1000_phy_igp_3))
                adapter->flags |= FLAG_LSC_GIG_SPEED_DROP;
@@ -410,12 +499,15 @@ static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw)
 
        while (timeout) {
                extcnf_ctrl = er32(EXTCNF_CTRL);
-               extcnf_ctrl |= E1000_EXTCNF_CTRL_SWFLAG;
-               ew32(EXTCNF_CTRL, extcnf_ctrl);
 
-               extcnf_ctrl = er32(EXTCNF_CTRL);
-               if (extcnf_ctrl & E1000_EXTCNF_CTRL_SWFLAG)
-                       break;
+               if (!(extcnf_ctrl & E1000_EXTCNF_CTRL_SWFLAG)) {
+                       extcnf_ctrl |= E1000_EXTCNF_CTRL_SWFLAG;
+                       ew32(EXTCNF_CTRL, extcnf_ctrl);
+
+                       extcnf_ctrl = er32(EXTCNF_CTRL);
+                       if (extcnf_ctrl & E1000_EXTCNF_CTRL_SWFLAG)
+                               break;
+               }
                mdelay(1);
                timeout--;
        }
@@ -554,6 +646,53 @@ static s32 e1000_phy_force_speed_duplex_ich8lan(struct e1000_hw *hw)
        return 0;
 }
 
+/**
+ *  e1000_hv_phy_workarounds_ich8lan - A series of Phy workarounds to be
+ *  done after every PHY reset.
+ **/
+static s32 e1000_hv_phy_workarounds_ich8lan(struct e1000_hw *hw)
+{
+       s32 ret_val = 0;
+
+       if (hw->mac.type != e1000_pchlan)
+               return ret_val;
+
+       if (((hw->phy.type == e1000_phy_82577) &&
+            ((hw->phy.revision == 1) || (hw->phy.revision == 2))) ||
+           ((hw->phy.type == e1000_phy_82578) && (hw->phy.revision == 1))) {
+               /* Disable generation of early preamble */
+               ret_val = e1e_wphy(hw, PHY_REG(769, 25), 0x4431);
+               if (ret_val)
+                       return ret_val;
+
+               /* Preamble tuning for SSC */
+               ret_val = e1e_wphy(hw, PHY_REG(770, 16), 0xA204);
+               if (ret_val)
+                       return ret_val;
+       }
+
+       if (hw->phy.type == e1000_phy_82578) {
+               /*
+                * Return registers to default by doing a soft reset then
+                * writing 0x3140 to the control register.
+                */
+               if (hw->phy.revision < 2) {
+                       e1000e_phy_sw_reset(hw);
+                       ret_val = e1e_wphy(hw, PHY_CONTROL, 0x3140);
+               }
+       }
+
+       /* Select page 0 */
+       ret_val = hw->phy.ops.acquire_phy(hw);
+       if (ret_val)
+               return ret_val;
+       hw->phy.addr = 1;
+       e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT, 0);
+       hw->phy.ops.release_phy(hw);
+
+       return ret_val;
+}
+
 /**
  *  e1000_phy_hw_reset_ich8lan - Performs a PHY reset
  *  @hw: pointer to the HW structure
@@ -575,6 +714,12 @@ static s32 e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw)
        if (ret_val)
                return ret_val;
 
+       if (hw->mac.type == e1000_pchlan) {
+               ret_val = e1000_hv_phy_workarounds_ich8lan(hw);
+               if (ret_val)
+                       return ret_val;
+       }
+
        /*
         * Initialize the PHY from the NVM on ICH platforms.  This
         * is needed due to an issue where the NVM configuration is
@@ -701,7 +846,7 @@ static s32 e1000_get_phy_info_ife_ich8lan(struct e1000_hw *hw)
        phy->polarity_correction = (!(data & IFE_PSC_AUTO_POLARITY_DISABLE));
 
        if (phy->polarity_correction) {
-               ret_val = e1000_check_polarity_ife_ich8lan(hw);
+               ret_val = phy->ops.check_polarity(hw);
                if (ret_val)
                        return ret_val;
        } else {
@@ -741,6 +886,8 @@ static s32 e1000_get_phy_info_ich8lan(struct e1000_hw *hw)
                break;
        case e1000_phy_igp_3:
        case e1000_phy_bm:
+       case e1000_phy_82578:
+       case e1000_phy_82577:
                return e1000e_get_phy_info_igp(hw);
                break;
        default:
@@ -1851,6 +1998,79 @@ static s32 e1000_valid_led_default_ich8lan(struct e1000_hw *hw, u16 *data)
        return 0;
 }
 
+/**
+ *  e1000_id_led_init_pchlan - store LED configurations
+ *  @hw: pointer to the HW structure
+ *
+ *  PCH does not control LEDs via the LEDCTL register, rather it uses
+ *  the PHY LED configuration register.
+ *
+ *  PCH also does not have an "always on" or "always off" mode which
+ *  complicates the ID feature.  Instead of using the "on" mode to indicate
+ *  in ledctl_mode2 the LEDs to use for ID (see e1000e_id_led_init()),
+ *  use "link_up" mode.  The LEDs will still ID on request if there is no
+ *  link based on logic in e1000_led_[on|off]_pchlan().
+ **/
+static s32 e1000_id_led_init_pchlan(struct e1000_hw *hw)
+{
+       struct e1000_mac_info *mac = &hw->mac;
+       s32 ret_val;
+       const u32 ledctl_on = E1000_LEDCTL_MODE_LINK_UP;
+       const u32 ledctl_off = E1000_LEDCTL_MODE_LINK_UP | E1000_PHY_LED0_IVRT;
+       u16 data, i, temp, shift;
+
+       /* Get default ID LED modes */
+       ret_val = hw->nvm.ops.valid_led_default(hw, &data);
+       if (ret_val)
+               goto out;
+
+       mac->ledctl_default = er32(LEDCTL);
+       mac->ledctl_mode1 = mac->ledctl_default;
+       mac->ledctl_mode2 = mac->ledctl_default;
+
+       for (i = 0; i < 4; i++) {
+               temp = (data >> (i << 2)) & E1000_LEDCTL_LED0_MODE_MASK;
+               shift = (i * 5);
+               switch (temp) {
+               case ID_LED_ON1_DEF2:
+               case ID_LED_ON1_ON2:
+               case ID_LED_ON1_OFF2:
+                       mac->ledctl_mode1 &= ~(E1000_PHY_LED0_MASK << shift);
+                       mac->ledctl_mode1 |= (ledctl_on << shift);
+                       break;
+               case ID_LED_OFF1_DEF2:
+               case ID_LED_OFF1_ON2:
+               case ID_LED_OFF1_OFF2:
+                       mac->ledctl_mode1 &= ~(E1000_PHY_LED0_MASK << shift);
+                       mac->ledctl_mode1 |= (ledctl_off << shift);
+                       break;
+               default:
+                       /* Do nothing */
+                       break;
+               }
+               switch (temp) {
+               case ID_LED_DEF1_ON2:
+               case ID_LED_ON1_ON2:
+               case ID_LED_OFF1_ON2:
+                       mac->ledctl_mode2 &= ~(E1000_PHY_LED0_MASK << shift);
+                       mac->ledctl_mode2 |= (ledctl_on << shift);
+                       break;
+               case ID_LED_DEF1_OFF2:
+               case ID_LED_ON1_OFF2:
+               case ID_LED_OFF1_OFF2:
+                       mac->ledctl_mode2 &= ~(E1000_PHY_LED0_MASK << shift);
+                       mac->ledctl_mode2 |= (ledctl_off << shift);
+                       break;
+               default:
+                       /* Do nothing */
+                       break;
+               }
+       }
+
+out:
+       return ret_val;
+}
+
 /**
  *  e1000_get_bus_info_ich8lan - Get/Set the bus type and width
  *  @hw: pointer to the HW structure
@@ -1960,6 +2180,9 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw)
        kab |= E1000_KABGTXD_BGSQLBIAS;
        ew32(KABGTXD, kab);
 
+       if (hw->mac.type == e1000_pchlan)
+               ret_val = e1000_hv_phy_workarounds_ich8lan(hw);
+
        return ret_val;
 }
 
@@ -1985,7 +2208,7 @@ static s32 e1000_init_hw_ich8lan(struct e1000_hw *hw)
        e1000_initialize_hw_bits_ich8lan(hw);
 
        /* Initialize identification LED */
-       ret_val = e1000e_id_led_init(hw);
+       ret_val = mac->ops.id_led_init(hw);
        if (ret_val) {
                hw_dbg(hw, "Error initializing identification LED\n");
                return ret_val;
@@ -2030,6 +2253,16 @@ static s32 e1000_init_hw_ich8lan(struct e1000_hw *hw)
        ctrl_ext |= E1000_CTRL_EXT_RO_DIS;
        ew32(CTRL_EXT, ctrl_ext);
 
+       /*
+        * The 82578 Rx buffer will stall if wakeup is enabled in host and
+        * the ME.  Reading the BM_WUC register will clear the host wakeup bit.
+        * Reset the phy after disabling host wakeup to reset the Rx buffer.
+        */
+       if (hw->phy.type == e1000_phy_82578) {
+               e1e_rphy(hw, BM_WUC, &i);
+               e1000e_phy_hw_reset_generic(hw);
+       }
+
        /*
         * Clear all of the statistics registers (clear on read).  It is
         * important that we do this after we have tried to establish link
@@ -2054,6 +2287,9 @@ static void e1000_initialize_hw_bits_ich8lan(struct e1000_hw *hw)
        /* Extended Device Control */
        reg = er32(CTRL_EXT);
        reg |= (1 << 22);
+       /* Enable PHY low-power state when MAC is at D3 w/o WoL */
+       if (hw->mac.type >= e1000_pchlan)
+               reg |= E1000_CTRL_EXT_PHYPDEN;
        ew32(CTRL_EXT, reg);
 
        /* Transmit Descriptor Control 0 */
@@ -2112,8 +2348,13 @@ static s32 e1000_setup_link_ich8lan(struct e1000_hw *hw)
         * the default flow control setting, so we explicitly
         * set it to full.
         */
-       if (hw->fc.requested_mode == e1000_fc_default)
-               hw->fc.requested_mode = e1000_fc_full;
+       if (hw->fc.requested_mode == e1000_fc_default) {
+               /* Workaround h/w hang when Tx flow control enabled */
+               if (hw->mac.type == e1000_pchlan)
+                       hw->fc.requested_mode = e1000_fc_rx_pause;
+               else
+                       hw->fc.requested_mode = e1000_fc_full;
+       }
 
        /*
         * Save off the requested flow control mode for use later.  Depending
@@ -2130,6 +2371,14 @@ static s32 e1000_setup_link_ich8lan(struct e1000_hw *hw)
                return ret_val;
 
        ew32(FCTTV, hw->fc.pause_time);
+       if ((hw->phy.type == e1000_phy_82578) ||
+           (hw->phy.type == e1000_phy_82577)) {
+               ret_val = hw->phy.ops.write_phy_reg(hw,
+                                            PHY_REG(BM_PORT_CTRL_PAGE, 27),
+                                            hw->fc.pause_time);
+               if (ret_val)
+                       return ret_val;
+       }
 
        return e1000e_set_fc_watermarks(hw);
 }
@@ -2169,18 +2418,26 @@ static s32 e1000_setup_copper_link_ich8lan(struct e1000_hw *hw)
        if (ret_val)
                return ret_val;
 
-       if (hw->phy.type == e1000_phy_igp_3) {
+       switch (hw->phy.type) {
+       case e1000_phy_igp_3:
                ret_val = e1000e_copper_link_setup_igp(hw);
                if (ret_val)
                        return ret_val;
-       } else if (hw->phy.type == e1000_phy_bm) {
+               break;
+       case e1000_phy_bm:
+       case e1000_phy_82578:
                ret_val = e1000e_copper_link_setup_m88(hw);
                if (ret_val)
                        return ret_val;
-       }
-
-       if (hw->phy.type == e1000_phy_ife) {
-               ret_val = e1e_rphy(hw, IFE_PHY_MDIX_CONTROL, &reg_data);
+               break;
+       case e1000_phy_82577:
+               ret_val = e1000_copper_link_setup_82577(hw);
+               if (ret_val)
+                       return ret_val;
+               break;
+       case e1000_phy_ife:
+               ret_val = hw->phy.ops.read_phy_reg(hw, IFE_PHY_MDIX_CONTROL,
+                                              &reg_data);
                if (ret_val)
                        return ret_val;
 
@@ -2198,9 +2455,13 @@ static s32 e1000_setup_copper_link_ich8lan(struct e1000_hw *hw)
                        reg_data |= IFE_PMC_AUTO_MDIX;
                        break;
                }
-               ret_val = e1e_wphy(hw, IFE_PHY_MDIX_CONTROL, reg_data);
+               ret_val = hw->phy.ops.write_phy_reg(hw, IFE_PHY_MDIX_CONTROL,
+                                               reg_data);
                if (ret_val)
                        return ret_val;
+               break;
+       default:
+               break;
        }
        return e1000e_setup_copper_link(hw);
 }
@@ -2417,18 +2678,26 @@ void e1000e_gig_downshift_workaround_ich8lan(struct e1000_hw *hw)
  *  'LPLU Enabled' and 'Gig Disable' to force link speed negotiation
  *  to a lower speed.
  *
- *  Should only be called for ICH9 and ICH10 devices.
+ *  Should only be called for applicable parts.
  **/
 void e1000e_disable_gig_wol_ich8lan(struct e1000_hw *hw)
 {
        u32 phy_ctrl;
 
-       if ((hw->mac.type == e1000_ich10lan) ||
-           (hw->mac.type == e1000_ich9lan)) {
+       switch (hw->mac.type) {
+       case e1000_ich9lan:
+       case e1000_ich10lan:
+       case e1000_pchlan:
                phy_ctrl = er32(PHY_CTRL);
                phy_ctrl |= E1000_PHY_CTRL_D0A_LPLU |
                            E1000_PHY_CTRL_GBE_DISABLE;
                ew32(PHY_CTRL, phy_ctrl);
+
+               /* Workaround SWFLAG unexpectedly set during S0->Sx */
+               if (hw->mac.type == e1000_pchlan)
+                       udelay(500);
+       default:
+               break;
        }
 
        return;
@@ -2481,6 +2750,92 @@ static s32 e1000_led_off_ich8lan(struct e1000_hw *hw)
        return 0;
 }
 
+/**
+ *  e1000_setup_led_pchlan - Configures SW controllable LED
+ *  @hw: pointer to the HW structure
+ *
+ *  This prepares the SW controllable LED for use.
+ **/
+static s32 e1000_setup_led_pchlan(struct e1000_hw *hw)
+{
+       return hw->phy.ops.write_phy_reg(hw, HV_LED_CONFIG,
+                                       (u16)hw->mac.ledctl_mode1);
+}
+
+/**
+ *  e1000_cleanup_led_pchlan - Restore the default LED operation
+ *  @hw: pointer to the HW structure
+ *
+ *  Return the LED back to the default configuration.
+ **/
+static s32 e1000_cleanup_led_pchlan(struct e1000_hw *hw)
+{
+       return hw->phy.ops.write_phy_reg(hw, HV_LED_CONFIG,
+                                       (u16)hw->mac.ledctl_default);
+}
+
+/**
+ *  e1000_led_on_pchlan - Turn LEDs on
+ *  @hw: pointer to the HW structure
+ *
+ *  Turn on the LEDs.
+ **/
+static s32 e1000_led_on_pchlan(struct e1000_hw *hw)
+{
+       u16 data = (u16)hw->mac.ledctl_mode2;
+       u32 i, led;
+
+       /*
+        * If no link, then turn LED on by setting the invert bit
+        * for each LED that's mode is "link_up" in ledctl_mode2.
+        */
+       if (!(er32(STATUS) & E1000_STATUS_LU)) {
+               for (i = 0; i < 3; i++) {
+                       led = (data >> (i * 5)) & E1000_PHY_LED0_MASK;
+                       if ((led & E1000_PHY_LED0_MODE_MASK) !=
+                           E1000_LEDCTL_MODE_LINK_UP)
+                               continue;
+                       if (led & E1000_PHY_LED0_IVRT)
+                               data &= ~(E1000_PHY_LED0_IVRT << (i * 5));
+                       else
+                               data |= (E1000_PHY_LED0_IVRT << (i * 5));
+               }
+       }
+
+       return hw->phy.ops.write_phy_reg(hw, HV_LED_CONFIG, data);
+}
+
+/**
+ *  e1000_led_off_pchlan - Turn LEDs off
+ *  @hw: pointer to the HW structure
+ *
+ *  Turn off the LEDs.
+ **/
+static s32 e1000_led_off_pchlan(struct e1000_hw *hw)
+{
+       u16 data = (u16)hw->mac.ledctl_mode1;
+       u32 i, led;
+
+       /*
+        * If no link, then turn LED off by clearing the invert bit
+        * for each LED that's mode is "link_up" in ledctl_mode1.
+        */
+       if (!(er32(STATUS) & E1000_STATUS_LU)) {
+               for (i = 0; i < 3; i++) {
+                       led = (data >> (i * 5)) & E1000_PHY_LED0_MASK;
+                       if ((led & E1000_PHY_LED0_MODE_MASK) !=
+                           E1000_LEDCTL_MODE_LINK_UP)
+                               continue;
+                       if (led & E1000_PHY_LED0_IVRT)
+                               data &= ~(E1000_PHY_LED0_IVRT << (i * 5));
+                       else
+                               data |= (E1000_PHY_LED0_IVRT << (i * 5));
+               }
+       }
+
+       return hw->phy.ops.write_phy_reg(hw, HV_LED_CONFIG, data);
+}
+
 /**
  *  e1000_get_cfg_done_ich8lan - Read config done bit
  *  @hw: pointer to the HW structure
@@ -2488,7 +2843,7 @@ static s32 e1000_led_off_ich8lan(struct e1000_hw *hw)
  *  Read the management control register for the config done bit for
  *  completion status.  NOTE: silicon which is EEPROM-less will fail trying
  *  to read the config done bit, so an error is *ONLY* logged and returns
- *  E1000_SUCCESS.  If we were to return with error, EEPROM-less silicon
+ *  0.  If we were to return with error, EEPROM-less silicon
  *  would not be able to be reset or change link.
  **/
 static s32 e1000_get_cfg_done_ich8lan(struct e1000_hw *hw)
@@ -2498,7 +2853,8 @@ static s32 e1000_get_cfg_done_ich8lan(struct e1000_hw *hw)
        e1000e_get_cfg_done(hw);
 
        /* If EEPROM is not marked present, init the IGP 3 PHY manually */
-       if (hw->mac.type != e1000_ich10lan) {
+       if ((hw->mac.type != e1000_ich10lan) &&
+           (hw->mac.type != e1000_pchlan)) {
                if (((er32(EECD) & E1000_EECD_PRES) == 0) &&
                    (hw->phy.type == e1000_phy_igp_3)) {
                        e1000e_phy_init_script_igp3(hw);
@@ -2524,6 +2880,7 @@ static s32 e1000_get_cfg_done_ich8lan(struct e1000_hw *hw)
 static void e1000_clear_hw_cntrs_ich8lan(struct e1000_hw *hw)
 {
        u32 temp;
+       u16 phy_data;
 
        e1000e_clear_hw_cntrs_base(hw);
 
@@ -2541,22 +2898,42 @@ static void e1000_clear_hw_cntrs_ich8lan(struct e1000_hw *hw)
        temp = er32(IAC);
        temp = er32(ICRXOC);
 
+       /* Clear PHY statistics registers */
+       if ((hw->phy.type == e1000_phy_82578) ||
+           (hw->phy.type == e1000_phy_82577)) {
+               hw->phy.ops.read_phy_reg(hw, HV_SCC_UPPER, &phy_data);
+               hw->phy.ops.read_phy_reg(hw, HV_SCC_LOWER, &phy_data);
+               hw->phy.ops.read_phy_reg(hw, HV_ECOL_UPPER, &phy_data);
+               hw->phy.ops.read_phy_reg(hw, HV_ECOL_LOWER, &phy_data);
+               hw->phy.ops.read_phy_reg(hw, HV_MCC_UPPER, &phy_data);
+               hw->phy.ops.read_phy_reg(hw, HV_MCC_LOWER, &phy_data);
+               hw->phy.ops.read_phy_reg(hw, HV_LATECOL_UPPER, &phy_data);
+               hw->phy.ops.read_phy_reg(hw, HV_LATECOL_LOWER, &phy_data);
+               hw->phy.ops.read_phy_reg(hw, HV_COLC_UPPER, &phy_data);
+               hw->phy.ops.read_phy_reg(hw, HV_COLC_LOWER, &phy_data);
+               hw->phy.ops.read_phy_reg(hw, HV_DC_UPPER, &phy_data);
+               hw->phy.ops.read_phy_reg(hw, HV_DC_LOWER, &phy_data);
+               hw->phy.ops.read_phy_reg(hw, HV_TNCRS_UPPER, &phy_data);
+               hw->phy.ops.read_phy_reg(hw, HV_TNCRS_LOWER, &phy_data);
+       }
 }
 
 static struct e1000_mac_operations ich8_mac_ops = {
+       .id_led_init            = e1000e_id_led_init,
        .check_mng_mode         = e1000_check_mng_mode_ich8lan,
        .check_for_link         = e1000e_check_for_copper_link,
-       .cleanup_led            = e1000_cleanup_led_ich8lan,
+       /* cleanup_led dependent on mac type */
        .clear_hw_cntrs         = e1000_clear_hw_cntrs_ich8lan,
        .get_bus_info           = e1000_get_bus_info_ich8lan,
        .get_link_up_info       = e1000_get_link_up_info_ich8lan,
-       .led_on                 = e1000_led_on_ich8lan,
-       .led_off                = e1000_led_off_ich8lan,
+       /* led_on dependent on mac type */
+       /* led_off dependent on mac type */
        .update_mc_addr_list    = e1000e_update_mc_addr_list_generic,
        .reset_hw               = e1000_reset_hw_ich8lan,
        .init_hw                = e1000_init_hw_ich8lan,
        .setup_link             = e1000_setup_link_ich8lan,
        .setup_physical_interface= e1000_setup_copper_link_ich8lan,
+       /* id_led_init dependent on mac type */
 };
 
 static struct e1000_phy_operations ich8_phy_ops = {
@@ -2595,6 +2972,7 @@ struct e1000_info e1000_ich8_info = {
                                  | FLAG_HAS_FLASH
                                  | FLAG_APME_IN_WUC,
        .pba                    = 8,
+       .max_hw_frame_size      = ETH_FRAME_LEN + ETH_FCS_LEN,
        .get_variants           = e1000_get_variants_ich8lan,
        .mac_ops                = &ich8_mac_ops,
        .phy_ops                = &ich8_phy_ops,
@@ -2613,6 +2991,7 @@ struct e1000_info e1000_ich9_info = {
                                  | FLAG_HAS_FLASH
                                  | FLAG_APME_IN_WUC,
        .pba                    = 10,
+       .max_hw_frame_size      = DEFAULT_JUMBO,
        .get_variants           = e1000_get_variants_ich8lan,
        .mac_ops                = &ich8_mac_ops,
        .phy_ops                = &ich8_phy_ops,
@@ -2631,6 +3010,25 @@ struct e1000_info e1000_ich10_info = {
                                  | FLAG_HAS_FLASH
                                  | FLAG_APME_IN_WUC,
        .pba                    = 10,
+       .max_hw_frame_size      = DEFAULT_JUMBO,
+       .get_variants           = e1000_get_variants_ich8lan,
+       .mac_ops                = &ich8_mac_ops,
+       .phy_ops                = &ich8_phy_ops,
+       .nvm_ops                = &ich8_nvm_ops,
+};
+
+struct e1000_info e1000_pch_info = {
+       .mac                    = e1000_pchlan,
+       .flags                  = FLAG_IS_ICH
+                                 | FLAG_HAS_WOL
+                                 | FLAG_RX_CSUM_ENABLED
+                                 | FLAG_HAS_CTRLEXT_ON_LOAD
+                                 | FLAG_HAS_AMT
+                                 | FLAG_HAS_FLASH
+                                 | FLAG_HAS_JUMBO_FRAMES
+                                 | FLAG_APME_IN_WUC,
+       .pba                    = 26,
+       .max_hw_frame_size      = 4096,
        .get_variants           = e1000_get_variants_ich8lan,
        .mac_ops                = &ich8_mac_ops,
        .phy_ops                = &ich8_phy_ops,
index 18a4f5902f3b5bff2ba1eb4b9b1a7a442a7119a8..be6d9e9903741650ff5fe83ff1797d112a4c53ce 100644 (file)
@@ -378,6 +378,12 @@ s32 e1000e_check_for_copper_link(struct e1000_hw *hw)
 
        mac->get_link_status = 0;
 
+       if (hw->phy.type == e1000_phy_82578) {
+               ret_val = e1000_link_stall_workaround_hv(hw);
+               if (ret_val)
+                       return ret_val;
+       }
+
        /*
         * Check if there was DownShift, must be checked
         * immediately after link-up
@@ -1405,6 +1411,38 @@ s32 e1000e_id_led_init(struct e1000_hw *hw)
        return 0;
 }
 
+/**
+ *  e1000e_setup_led_generic - Configures SW controllable LED
+ *  @hw: pointer to the HW structure
+ *
+ *  This prepares the SW controllable LED for use and saves the current state
+ *  of the LED so it can be later restored.
+ **/
+s32 e1000e_setup_led_generic(struct e1000_hw *hw)
+{
+       u32 ledctl;
+
+       if (hw->mac.ops.setup_led != e1000e_setup_led_generic) {
+               return -E1000_ERR_CONFIG;
+       }
+
+       if (hw->phy.media_type == e1000_media_type_fiber) {
+               ledctl = er32(LEDCTL);
+               hw->mac.ledctl_default = ledctl;
+               /* Turn off LED0 */
+               ledctl &= ~(E1000_LEDCTL_LED0_IVRT |
+                           E1000_LEDCTL_LED0_BLINK |
+                           E1000_LEDCTL_LED0_MODE_MASK);
+               ledctl |= (E1000_LEDCTL_MODE_LED_OFF <<
+                          E1000_LEDCTL_LED0_MODE_SHIFT);
+               ew32(LEDCTL, ledctl);
+       } else if (hw->phy.media_type == e1000_media_type_copper) {
+               ew32(LEDCTL, hw->mac.ledctl_mode1);
+       }
+
+       return 0;
+}
+
 /**
  *  e1000e_cleanup_led_generic - Set LED config to default operation
  *  @hw: pointer to the HW structure
index ca82f19a7ed183b8139f65e40279f530e8239e6c..677f60490f679d8aa80536a66bc060f479e1a283 100644 (file)
@@ -48,7 +48,7 @@
 
 #include "e1000.h"
 
-#define DRV_VERSION "0.3.3.4-k4"
+#define DRV_VERSION "1.0.2-k2"
 char e1000e_driver_name[] = "e1000e";
 const char e1000e_driver_version[] = DRV_VERSION;
 
@@ -62,6 +62,7 @@ static const struct e1000_info *e1000_info_tbl[] = {
        [board_ich8lan]         = &e1000_ich8_info,
        [board_ich9lan]         = &e1000_ich9_info,
        [board_ich10lan]        = &e1000_ich10_info,
+       [board_pchlan]          = &e1000_pch_info,
 };
 
 #ifdef DEBUG
@@ -2255,8 +2256,6 @@ static void e1000_configure_tx(struct e1000_adapter *adapter)
                ew32(TARC(1), tarc);
        }
 
-       e1000e_config_collision_dist(hw);
-
        /* Setup Transmit Descriptor Settings for eop descriptor */
        adapter->txd_cmd = E1000_TXD_CMD_EOP | E1000_TXD_CMD_IFCS;
 
@@ -2269,6 +2268,8 @@ static void e1000_configure_tx(struct e1000_adapter *adapter)
 
        ew32(TCTL, tctl);
 
+       e1000e_config_collision_dist(hw);
+
        adapter->tx_queue_len = adapter->netdev->tx_queue_len;
 }
 
@@ -2308,6 +2309,23 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter)
        if (adapter->flags2 & FLAG2_CRC_STRIPPING)
                rctl |= E1000_RCTL_SECRC;
 
+       /* Workaround Si errata on 82577 PHY - configure IPG for jumbos */
+       if ((hw->phy.type == e1000_phy_82577) && (rctl & E1000_RCTL_LPE)) {
+               u16 phy_data;
+
+               e1e_rphy(hw, PHY_REG(770, 26), &phy_data);
+               phy_data &= 0xfff8;
+               phy_data |= (1 << 2);
+               e1e_wphy(hw, PHY_REG(770, 26), phy_data);
+
+               e1e_rphy(hw, 22, &phy_data);
+               phy_data &= 0x0fff;
+               phy_data |= (1 << 14);
+               e1e_wphy(hw, 0x10, 0x2823);
+               e1e_wphy(hw, 0x11, 0x0003);
+               e1e_wphy(hw, 22, phy_data);
+       }
+
        /* Setup buffer sizes */
        rctl &= ~E1000_RCTL_SZ_4096;
        rctl |= E1000_RCTL_BSEX;
@@ -2751,23 +2769,25 @@ void e1000e_reset(struct e1000_adapter *adapter)
        /*
         * flow control settings
         *
-        * The high water mark must be low enough to fit one full frame
+        * The high water mark must be low enough to fit two full frame
         * (or the size used for early receive) above it in the Rx FIFO.
         * Set it to the lower of:
         * - 90% of the Rx FIFO size, and
         * - the full Rx FIFO size minus the early receive size (for parts
         *   with ERT support assuming ERT set to E1000_ERT_2048), or
-        * - the full Rx FIFO size minus one full frame
+        * - the full Rx FIFO size minus two full frames
         */
-       if (adapter->flags & FLAG_HAS_ERT)
+       if ((adapter->flags & FLAG_HAS_ERT) &&
+           (adapter->netdev->mtu > ETH_DATA_LEN))
                hwm = min(((pba << 10) * 9 / 10),
                          ((pba << 10) - (E1000_ERT_2048 << 3)));
        else
                hwm = min(((pba << 10) * 9 / 10),
-                         ((pba << 10) - adapter->max_frame_size));
+                         ((pba << 10) - (2 * adapter->max_frame_size)));
 
-       fc->high_water = hwm & 0xFFF8; /* 8-byte granularity */
-       fc->low_water = fc->high_water - 8;
+       fc->high_water = hwm & E1000_FCRTH_RTH; /* 8-byte granularity */
+       fc->low_water = (fc->high_water - (2 * adapter->max_frame_size));
+       fc->low_water &= E1000_FCRTL_RTL; /* 8-byte granularity */
 
        if (adapter->flags & FLAG_DISABLE_FC_PAUSE_TIME)
                fc->pause_time = 0xFFFF;
@@ -2787,6 +2807,8 @@ void e1000e_reset(struct e1000_adapter *adapter)
                e1000_get_hw_control(adapter);
 
        ew32(WUC, 0);
+       if (adapter->flags2 & FLAG2_HAS_PHY_WAKEUP)
+               e1e_wphy(&adapter->hw, BM_WUC, 0);
 
        if (mac->ops.init_hw(hw))
                e_err("Hardware Error\n");
@@ -2799,7 +2821,8 @@ void e1000e_reset(struct e1000_adapter *adapter)
        e1000e_reset_adaptive(hw);
        e1000_get_phy_info(hw);
 
-       if (!(adapter->flags & FLAG_SMART_POWER_DOWN)) {
+       if ((adapter->flags & FLAG_HAS_SMART_POWER_DOWN) &&
+           !(adapter->flags & FLAG_SMART_POWER_DOWN)) {
                u16 phy_data = 0;
                /*
                 * speed up time to link by disabling smart power down, ignore
@@ -2826,6 +2849,8 @@ int e1000e_up(struct e1000_adapter *adapter)
                e1000_configure_msix(adapter);
        e1000_irq_enable(adapter);
 
+       netif_wake_queue(adapter->netdev);
+
        /* fire a link change interrupt to start the watchdog */
        ew32(ICS, E1000_ICS_LSC);
        return 0;
@@ -2848,7 +2873,7 @@ void e1000e_down(struct e1000_adapter *adapter)
        ew32(RCTL, rctl & ~E1000_RCTL_EN);
        /* flush and sleep below */
 
-       netif_tx_stop_all_queues(netdev);
+       netif_stop_queue(netdev);
 
        /* disable transmits in the hardware */
        tctl = er32(TCTL);
@@ -3072,6 +3097,8 @@ static int e1000_open(struct net_device *netdev)
        if (test_bit(__E1000_TESTING, &adapter->state))
                return -EBUSY;
 
+       netif_carrier_off(netdev);
+
        /* allocate transmit descriptors */
        err = e1000e_setup_tx_resources(adapter);
        if (err)
@@ -3128,7 +3155,7 @@ static int e1000_open(struct net_device *netdev)
 
        e1000_irq_enable(adapter);
 
-       netif_tx_start_all_queues(netdev);
+       netif_start_queue(netdev);
 
        /* fire a link status change interrupt to start the watchdog */
        ew32(ICS, E1000_ICS_LSC);
@@ -3262,6 +3289,7 @@ void e1000e_update_stats(struct e1000_adapter *adapter)
 {
        struct e1000_hw *hw = &adapter->hw;
        struct pci_dev *pdev = adapter->pdev;
+       u16 phy_data;
 
        /*
         * Prevent stats update while adapter is being reset, or if the pci
@@ -3281,11 +3309,34 @@ void e1000e_update_stats(struct e1000_adapter *adapter)
        adapter->stats.roc += er32(ROC);
 
        adapter->stats.mpc += er32(MPC);
-       adapter->stats.scc += er32(SCC);
-       adapter->stats.ecol += er32(ECOL);
-       adapter->stats.mcc += er32(MCC);
-       adapter->stats.latecol += er32(LATECOL);
-       adapter->stats.dc += er32(DC);
+       if ((hw->phy.type == e1000_phy_82578) ||
+           (hw->phy.type == e1000_phy_82577)) {
+               e1e_rphy(hw, HV_SCC_UPPER, &phy_data);
+               e1e_rphy(hw, HV_SCC_LOWER, &phy_data);
+               adapter->stats.scc += phy_data;
+
+               e1e_rphy(hw, HV_ECOL_UPPER, &phy_data);
+               e1e_rphy(hw, HV_ECOL_LOWER, &phy_data);
+               adapter->stats.ecol += phy_data;
+
+               e1e_rphy(hw, HV_MCC_UPPER, &phy_data);
+               e1e_rphy(hw, HV_MCC_LOWER, &phy_data);
+               adapter->stats.mcc += phy_data;
+
+               e1e_rphy(hw, HV_LATECOL_UPPER, &phy_data);
+               e1e_rphy(hw, HV_LATECOL_LOWER, &phy_data);
+               adapter->stats.latecol += phy_data;
+
+               e1e_rphy(hw, HV_DC_UPPER, &phy_data);
+               e1e_rphy(hw, HV_DC_LOWER, &phy_data);
+               adapter->stats.dc += phy_data;
+       } else {
+               adapter->stats.scc += er32(SCC);
+               adapter->stats.ecol += er32(ECOL);
+               adapter->stats.mcc += er32(MCC);
+               adapter->stats.latecol += er32(LATECOL);
+               adapter->stats.dc += er32(DC);
+       }
        adapter->stats.xonrxc += er32(XONRXC);
        adapter->stats.xontxc += er32(XONTXC);
        adapter->stats.xoffrxc += er32(XOFFRXC);
@@ -3303,13 +3354,28 @@ void e1000e_update_stats(struct e1000_adapter *adapter)
 
        hw->mac.tx_packet_delta = er32(TPT);
        adapter->stats.tpt += hw->mac.tx_packet_delta;
-       hw->mac.collision_delta = er32(COLC);
+       if ((hw->phy.type == e1000_phy_82578) ||
+           (hw->phy.type == e1000_phy_82577)) {
+               e1e_rphy(hw, HV_COLC_UPPER, &phy_data);
+               e1e_rphy(hw, HV_COLC_LOWER, &phy_data);
+               hw->mac.collision_delta = phy_data;
+       } else {
+               hw->mac.collision_delta = er32(COLC);
+       }
        adapter->stats.colc += hw->mac.collision_delta;
 
        adapter->stats.algnerrc += er32(ALGNERRC);
        adapter->stats.rxerrc += er32(RXERRC);
-       if ((hw->mac.type != e1000_82574) && (hw->mac.type != e1000_82583))
-               adapter->stats.tncrs += er32(TNCRS);
+       if ((hw->phy.type == e1000_phy_82578) ||
+           (hw->phy.type == e1000_phy_82577)) {
+               e1e_rphy(hw, HV_TNCRS_UPPER, &phy_data);
+               e1e_rphy(hw, HV_TNCRS_LOWER, &phy_data);
+               adapter->stats.tncrs += phy_data;
+       } else {
+               if ((hw->mac.type != e1000_82574) &&
+                   (hw->mac.type != e1000_82583))
+                       adapter->stats.tncrs += er32(TNCRS);
+       }
        adapter->stats.cexterr += er32(CEXTERR);
        adapter->stats.tsctc += er32(TSCTC);
        adapter->stats.tsctfc += er32(TSCTFC);
@@ -3598,7 +3664,6 @@ static void e1000_watchdog_task(struct work_struct *work)
                                phy->ops.cfg_on_link_up(hw);
 
                        netif_carrier_on(netdev);
-                       netif_tx_wake_all_queues(netdev);
 
                        if (!test_bit(__E1000_DOWN, &adapter->state))
                                mod_timer(&adapter->phy_info_timer,
@@ -3612,7 +3677,6 @@ static void e1000_watchdog_task(struct work_struct *work)
                        printk(KERN_INFO "e1000e: %s NIC Link is Down\n",
                               adapter->netdev->name);
                        netif_carrier_off(netdev);
-                       netif_tx_stop_all_queues(netdev);
                        if (!test_bit(__E1000_DOWN, &adapter->state))
                                mod_timer(&adapter->phy_info_timer,
                                          round_jiffies(jiffies + 2 * HZ));
@@ -3649,6 +3713,8 @@ link_up:
                         */
                        adapter->tx_timeout_count++;
                        schedule_work(&adapter->reset_task);
+                       /* return immediately since reset is imminent */
+                       return;
                }
        }
 
@@ -3850,7 +3916,7 @@ static int e1000_tx_map(struct e1000_adapter *adapter,
                buffer_info->length = size;
                buffer_info->time_stamp = jiffies;
                buffer_info->next_to_watch = i;
-               buffer_info->dma = map[0] + offset;
+               buffer_info->dma = skb_shinfo(skb)->dma_head + offset;
                count++;
 
                len -= size;
@@ -3881,7 +3947,7 @@ static int e1000_tx_map(struct e1000_adapter *adapter,
                        buffer_info->length = size;
                        buffer_info->time_stamp = jiffies;
                        buffer_info->next_to_watch = i;
-                       buffer_info->dma = map[f + 1] + offset;
+                       buffer_info->dma = map[f] + offset;
 
                        len -= size;
                        offset += size;
@@ -4145,7 +4211,6 @@ static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
        count = e1000_tx_map(adapter, skb, first, max_per_txd, nr_frags, mss);
        if (count) {
                e1000_tx_queue(adapter, tx_flags, count);
-               netdev->trans_start = jiffies;
                /* Make sure there is space in the ring for the next send. */
                e1000_maybe_stop_tx(netdev, MAX_SKB_FRAGS + 2);
 
@@ -4206,27 +4271,17 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
        struct e1000_adapter *adapter = netdev_priv(netdev);
        int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN;
 
-       if ((new_mtu < ETH_ZLEN + ETH_FCS_LEN + VLAN_HLEN) ||
-           (max_frame > MAX_JUMBO_FRAME_SIZE)) {
-               e_err("Invalid MTU setting\n");
+       /* Jumbo frame support */
+       if ((max_frame > ETH_FRAME_LEN + ETH_FCS_LEN) &&
+           !(adapter->flags & FLAG_HAS_JUMBO_FRAMES)) {
+               e_err("Jumbo Frames not supported.\n");
                return -EINVAL;
        }
 
-       /* Jumbo frame size limits */
-       if (max_frame > ETH_FRAME_LEN + ETH_FCS_LEN) {
-               if (!(adapter->flags & FLAG_HAS_JUMBO_FRAMES)) {
-                       e_err("Jumbo Frames not supported.\n");
-                       return -EINVAL;
-               }
-               if (adapter->hw.phy.type == e1000_phy_ife) {
-                       e_err("Jumbo Frames not supported.\n");
-                       return -EINVAL;
-               }
-       }
-
-#define MAX_STD_JUMBO_FRAME_SIZE 9234
-       if (max_frame > MAX_STD_JUMBO_FRAME_SIZE) {
-               e_err("MTU > 9216 not supported.\n");
+       /* Supported frame sizes */
+       if ((new_mtu < ETH_ZLEN + ETH_FCS_LEN + VLAN_HLEN) ||
+           (max_frame > adapter->max_hw_frame_size)) {
+               e_err("Unsupported MTU setting\n");
                return -EINVAL;
        }
 
@@ -4346,6 +4401,81 @@ static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
        }
 }
 
+static int e1000_init_phy_wakeup(struct e1000_adapter *adapter, u32 wufc)
+{
+       struct e1000_hw *hw = &adapter->hw;
+       u32 i, mac_reg;
+       u16 phy_reg;
+       int retval = 0;
+
+       /* copy MAC RARs to PHY RARs */
+       for (i = 0; i < adapter->hw.mac.rar_entry_count; i++) {
+               mac_reg = er32(RAL(i));
+               e1e_wphy(hw, BM_RAR_L(i), (u16)(mac_reg & 0xFFFF));
+               e1e_wphy(hw, BM_RAR_M(i), (u16)((mac_reg >> 16) & 0xFFFF));
+               mac_reg = er32(RAH(i));
+               e1e_wphy(hw, BM_RAR_H(i), (u16)(mac_reg & 0xFFFF));
+               e1e_wphy(hw, BM_RAR_CTRL(i), (u16)((mac_reg >> 16) & 0xFFFF));
+       }
+
+       /* copy MAC MTA to PHY MTA */
+       for (i = 0; i < adapter->hw.mac.mta_reg_count; i++) {
+               mac_reg = E1000_READ_REG_ARRAY(hw, E1000_MTA, i);
+               e1e_wphy(hw, BM_MTA(i), (u16)(mac_reg & 0xFFFF));
+               e1e_wphy(hw, BM_MTA(i) + 1, (u16)((mac_reg >> 16) & 0xFFFF));
+       }
+
+       /* configure PHY Rx Control register */
+       e1e_rphy(&adapter->hw, BM_RCTL, &phy_reg);
+       mac_reg = er32(RCTL);
+       if (mac_reg & E1000_RCTL_UPE)
+               phy_reg |= BM_RCTL_UPE;
+       if (mac_reg & E1000_RCTL_MPE)
+               phy_reg |= BM_RCTL_MPE;
+       phy_reg &= ~(BM_RCTL_MO_MASK);
+       if (mac_reg & E1000_RCTL_MO_3)
+               phy_reg |= (((mac_reg & E1000_RCTL_MO_3) >> E1000_RCTL_MO_SHIFT)
+                               << BM_RCTL_MO_SHIFT);
+       if (mac_reg & E1000_RCTL_BAM)
+               phy_reg |= BM_RCTL_BAM;
+       if (mac_reg & E1000_RCTL_PMCF)
+               phy_reg |= BM_RCTL_PMCF;
+       mac_reg = er32(CTRL);
+       if (mac_reg & E1000_CTRL_RFCE)
+               phy_reg |= BM_RCTL_RFCE;
+       e1e_wphy(&adapter->hw, BM_RCTL, phy_reg);
+
+       /* enable PHY wakeup in MAC register */
+       ew32(WUFC, wufc);
+       ew32(WUC, E1000_WUC_PHY_WAKE | E1000_WUC_PME_EN);
+
+       /* configure and enable PHY wakeup in PHY registers */
+       e1e_wphy(&adapter->hw, BM_WUFC, wufc);
+       e1e_wphy(&adapter->hw, BM_WUC, E1000_WUC_PME_EN);
+
+       /* activate PHY wakeup */
+       retval = hw->phy.ops.acquire_phy(hw);
+       if (retval) {
+               e_err("Could not acquire PHY\n");
+               return retval;
+       }
+       e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT,
+                                (BM_WUC_ENABLE_PAGE << IGP_PAGE_SHIFT));
+       retval = e1000e_read_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, &phy_reg);
+       if (retval) {
+               e_err("Could not read PHY page 769\n");
+               goto out;
+       }
+       phy_reg |= BM_WUC_ENABLE_BIT | BM_WUC_HOST_WU_BIT;
+       retval = e1000e_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, phy_reg);
+       if (retval)
+               e_err("Could not set PHY Host Wakeup bit\n");
+out:
+       hw->phy.ops.release_phy(hw);
+
+       return retval;
+}
+
 static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake)
 {
        struct net_device *netdev = pci_get_drvdata(pdev);
@@ -4388,8 +4518,9 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake)
                #define E1000_CTRL_ADVD3WUC 0x00100000
                /* phy power management enable */
                #define E1000_CTRL_EN_PHY_PWR_MGMT 0x00200000
-               ctrl |= E1000_CTRL_ADVD3WUC |
-                       E1000_CTRL_EN_PHY_PWR_MGMT;
+               ctrl |= E1000_CTRL_ADVD3WUC;
+               if (!(adapter->flags2 & FLAG2_HAS_PHY_WAKEUP))
+                       ctrl |= E1000_CTRL_EN_PHY_PWR_MGMT;
                ew32(CTRL, ctrl);
 
                if (adapter->hw.phy.media_type == e1000_media_type_fiber ||
@@ -4407,8 +4538,17 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake)
                /* Allow time for pending master requests to run */
                e1000e_disable_pcie_master(&adapter->hw);
 
-               ew32(WUC, E1000_WUC_PME_EN);
-               ew32(WUFC, wufc);
+               if ((adapter->flags2 & FLAG2_HAS_PHY_WAKEUP) &&
+                   !(hw->mac.ops.check_mng_mode(hw))) {
+                       /* enable wakeup by the PHY */
+                       retval = e1000_init_phy_wakeup(adapter, wufc);
+                       if (retval)
+                               return retval;
+               } else {
+                       /* enable wakeup by the MAC */
+                       ew32(WUFC, wufc);
+                       ew32(WUC, E1000_WUC_PME_EN);
+               }
        } else {
                ew32(WUC, 0);
                ew32(WUFC, 0);
@@ -4551,8 +4691,37 @@ static int e1000_resume(struct pci_dev *pdev)
        }
 
        e1000e_power_up_phy(adapter);
+
+       /* report the system wakeup cause from S3/S4 */
+       if (adapter->flags2 & FLAG2_HAS_PHY_WAKEUP) {
+               u16 phy_data;
+
+               e1e_rphy(&adapter->hw, BM_WUS, &phy_data);
+               if (phy_data) {
+                       e_info("PHY Wakeup cause - %s\n",
+                               phy_data & E1000_WUS_EX ? "Unicast Packet" :
+                               phy_data & E1000_WUS_MC ? "Multicast Packet" :
+                               phy_data & E1000_WUS_BC ? "Broadcast Packet" :
+                               phy_data & E1000_WUS_MAG ? "Magic Packet" :
+                               phy_data & E1000_WUS_LNKC ? "Link Status "
+                               " Change" : "other");
+               }
+               e1e_wphy(&adapter->hw, BM_WUS, ~0);
+       } else {
+               u32 wus = er32(WUS);
+               if (wus) {
+                       e_info("MAC Wakeup cause - %s\n",
+                               wus & E1000_WUS_EX ? "Unicast Packet" :
+                               wus & E1000_WUS_MC ? "Multicast Packet" :
+                               wus & E1000_WUS_BC ? "Broadcast Packet" :
+                               wus & E1000_WUS_MAG ? "Magic Packet" :
+                               wus & E1000_WUS_LNKC ? "Link Status Change" :
+                               "other");
+               }
+               ew32(WUS, ~0);
+       }
+
        e1000e_reset(adapter);
-       ew32(WUS, ~0);
 
        e1000_init_manageability(adapter);
 
@@ -4842,6 +5011,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
        adapter->flags2 = ei->flags2;
        adapter->hw.adapter = adapter;
        adapter->hw.mac.type = ei->mac;
+       adapter->max_hw_frame_size = ei->max_hw_frame_size;
        adapter->msg_enable = (1 << NETIF_MSG_DRV | NETIF_MSG_PROBE) - 1;
 
        mmio_start = pci_resource_start(pdev, 0);
@@ -4997,6 +5167,8 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
                /* APME bit in EEPROM is mapped to WUC.APME */
                eeprom_data = er32(WUC);
                eeprom_apme_mask = E1000_WUC_APME;
+               if (eeprom_data & E1000_WUC_PHY_WAKE)
+                       adapter->flags2 |= FLAG2_HAS_PHY_WAKEUP;
        } else if (adapter->flags & FLAG_APME_IN_CTRL3) {
                if (adapter->flags & FLAG_APME_CHECK_PORT_B &&
                    (adapter->hw.bus.func == 1))
@@ -5037,15 +5209,14 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
        if (!(adapter->flags & FLAG_HAS_AMT))
                e1000_get_hw_control(adapter);
 
-       /* tell the stack to leave us alone until e1000_open() is called */
-       netif_carrier_off(netdev);
-       netif_tx_stop_all_queues(netdev);
-
        strcpy(netdev->name, "eth%d");
        err = register_netdev(netdev);
        if (err)
                goto err_register;
 
+       /* carrier off reporting is important to ethtool even BEFORE open */
+       netif_carrier_off(netdev);
+
        e1000_print_device_info(adapter);
 
        return 0;
@@ -5199,6 +5370,11 @@ static struct pci_device_id e1000_pci_tbl[] = {
        { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_D_BM_LM), board_ich10lan },
        { PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_D_BM_LF), board_ich10lan },
 
+       { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_M_HV_LM), board_pchlan },
+       { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_M_HV_LC), board_pchlan },
+       { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_D_HV_DM), board_pchlan },
+       { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_D_HV_DC), board_pchlan },
+
        { }     /* terminate list */
 };
 MODULE_DEVICE_TABLE(pci, e1000_pci_tbl);
index e909f96698e8cfb023105a765b00becd6d7e0ae6..1342e0b1815c8e9003c2976ba42dde4593880d70 100644 (file)
@@ -427,6 +427,8 @@ void __devinit e1000e_check_options(struct e1000_adapter *adapter)
                        e1000_validate_option(&crc_stripping, &opt, adapter);
                        if (crc_stripping == OPTION_ENABLED)
                                adapter->flags2 |= FLAG2_CRC_STRIPPING;
+               } else {
+                       adapter->flags2 |= FLAG2_CRC_STRIPPING;
                }
        }
        { /* Kumeran Lock Loss Workaround */
index dc4a9cba6a73dcc34f16590153cd2e8a557fd9c6..e23459cf3d0eecbc64329d40db9de98aa19c7634 100644 (file)
@@ -37,6 +37,9 @@ static s32 e1000_wait_autoneg(struct e1000_hw *hw);
 static u32 e1000_get_phy_addr_for_bm_page(u32 page, u32 reg);
 static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset,
                                          u16 *data, bool read);
+static u32 e1000_get_phy_addr_for_hv_page(u32 page);
+static s32 e1000_access_phy_debug_regs_hv(struct e1000_hw *hw, u32 offset,
+                                          u16 *data, bool read);
 
 /* Cable length tables */
 static const u16 e1000_m88_cable_length_table[] =
@@ -54,6 +57,55 @@ static const u16 e1000_igp_2_cable_length_table[] =
 #define IGP02E1000_CABLE_LENGTH_TABLE_SIZE \
                ARRAY_SIZE(e1000_igp_2_cable_length_table)
 
+#define BM_PHY_REG_PAGE(offset) \
+       ((u16)(((offset) >> PHY_PAGE_SHIFT) & 0xFFFF))
+#define BM_PHY_REG_NUM(offset) \
+       ((u16)(((offset) & MAX_PHY_REG_ADDRESS) |\
+        (((offset) >> (PHY_UPPER_SHIFT - PHY_PAGE_SHIFT)) &\
+               ~MAX_PHY_REG_ADDRESS)))
+
+#define HV_INTC_FC_PAGE_START             768
+#define I82578_ADDR_REG                   29
+#define I82577_ADDR_REG                   16
+#define I82577_CFG_REG                    22
+#define I82577_CFG_ASSERT_CRS_ON_TX       (1 << 15)
+#define I82577_CFG_ENABLE_DOWNSHIFT       (3 << 10) /* auto downshift 100/10 */
+#define I82577_CTRL_REG                   23
+#define I82577_CTRL_DOWNSHIFT_MASK        (7 << 10)
+
+/* 82577 specific PHY registers */
+#define I82577_PHY_CTRL_2            18
+#define I82577_PHY_STATUS_2          26
+#define I82577_PHY_DIAG_STATUS       31
+
+/* I82577 PHY Status 2 */
+#define I82577_PHY_STATUS2_REV_POLARITY   0x0400
+#define I82577_PHY_STATUS2_MDIX           0x0800
+#define I82577_PHY_STATUS2_SPEED_MASK     0x0300
+#define I82577_PHY_STATUS2_SPEED_1000MBPS 0x0200
+
+/* I82577 PHY Control 2 */
+#define I82577_PHY_CTRL2_AUTO_MDIX        0x0400
+#define I82577_PHY_CTRL2_FORCE_MDI_MDIX   0x0200
+
+/* I82577 PHY Diagnostics Status */
+#define I82577_DSTATUS_CABLE_LENGTH       0x03FC
+#define I82577_DSTATUS_CABLE_LENGTH_SHIFT 2
+
+/* BM PHY Copper Specific Control 1 */
+#define BM_CS_CTRL1                       16
+
+/* BM PHY Copper Specific Status */
+#define BM_CS_STATUS                      17
+#define BM_CS_STATUS_LINK_UP              0x0400
+#define BM_CS_STATUS_RESOLVED             0x0800
+#define BM_CS_STATUS_SPEED_MASK           0xC000
+#define BM_CS_STATUS_SPEED_1000           0x8000
+
+#define HV_MUX_DATA_CTRL               PHY_REG(776, 16)
+#define HV_MUX_DATA_CTRL_GEN_TO_MAC    0x0400
+#define HV_MUX_DATA_CTRL_FORCE_SPEED   0x0004
+
 /**
  *  e1000e_check_reset_block_generic - Check if PHY reset is blocked
  *  @hw: pointer to the HW structure
@@ -82,23 +134,48 @@ s32 e1000e_check_reset_block_generic(struct e1000_hw *hw)
 s32 e1000e_get_phy_id(struct e1000_hw *hw)
 {
        struct e1000_phy_info *phy = &hw->phy;
-       s32 ret_val;
+       s32 ret_val = 0;
        u16 phy_id;
+       u16 retry_count = 0;
 
-       ret_val = e1e_rphy(hw, PHY_ID1, &phy_id);
-       if (ret_val)
-               return ret_val;
+       if (!(phy->ops.read_phy_reg))
+               goto out;
 
-       phy->id = (u32)(phy_id << 16);
-       udelay(20);
-       ret_val = e1e_rphy(hw, PHY_ID2, &phy_id);
-       if (ret_val)
-               return ret_val;
+       while (retry_count < 2) {
+               ret_val = e1e_rphy(hw, PHY_ID1, &phy_id);
+               if (ret_val)
+                       goto out;
 
-       phy->id |= (u32)(phy_id & PHY_REVISION_MASK);
-       phy->revision = (u32)(phy_id & ~PHY_REVISION_MASK);
+               phy->id = (u32)(phy_id << 16);
+               udelay(20);
+               ret_val = e1e_rphy(hw, PHY_ID2, &phy_id);
+               if (ret_val)
+                       goto out;
 
-       return 0;
+               phy->id |= (u32)(phy_id & PHY_REVISION_MASK);
+               phy->revision = (u32)(phy_id & ~PHY_REVISION_MASK);
+
+               if (phy->id != 0 && phy->id != PHY_REVISION_MASK)
+                       goto out;
+
+               /*
+                * If the PHY ID is still unknown, we may have an 82577i
+                * without link.  We will try again after setting Slow
+                * MDIC mode. No harm in trying again in this case since
+                * the PHY ID is unknown at this point anyway
+                */
+               ret_val = e1000_set_mdio_slow_mode_hv(hw, true);
+               if (ret_val)
+                       goto out;
+
+               retry_count++;
+       }
+out:
+       /* Revert to MDIO fast mode, if applicable */
+       if (retry_count)
+               ret_val = e1000_set_mdio_slow_mode_hv(hw, false);
+
+       return ret_val;
 }
 
 /**
@@ -409,6 +486,43 @@ s32 e1000e_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data)
        return ret_val;
 }
 
+/**
+ *  e1000_copper_link_setup_82577 - Setup 82577 PHY for copper link
+ *  @hw: pointer to the HW structure
+ *
+ *  Sets up Carrier-sense on Transmit and downshift values.
+ **/
+s32 e1000_copper_link_setup_82577(struct e1000_hw *hw)
+{
+       struct e1000_phy_info *phy = &hw->phy;
+       s32 ret_val;
+       u16 phy_data;
+
+       /* Enable CRS on TX. This must be set for half-duplex operation. */
+       ret_val = phy->ops.read_phy_reg(hw, I82577_CFG_REG, &phy_data);
+       if (ret_val)
+               goto out;
+
+       phy_data |= I82577_CFG_ASSERT_CRS_ON_TX;
+
+       /* Enable downshift */
+       phy_data |= I82577_CFG_ENABLE_DOWNSHIFT;
+
+       ret_val = phy->ops.write_phy_reg(hw, I82577_CFG_REG, phy_data);
+       if (ret_val)
+               goto out;
+
+       /* Set number of link attempts before downshift */
+       ret_val = phy->ops.read_phy_reg(hw, I82577_CTRL_REG, &phy_data);
+       if (ret_val)
+               goto out;
+       phy_data &= ~I82577_CTRL_DOWNSHIFT_MASK;
+       ret_val = phy->ops.write_phy_reg(hw, I82577_CTRL_REG, phy_data);
+
+out:
+       return ret_val;
+}
+
 /**
  *  e1000e_copper_link_setup_m88 - Setup m88 PHY's for copper link
  *  @hw: pointer to the HW structure
@@ -427,8 +541,8 @@ s32 e1000e_copper_link_setup_m88(struct e1000_hw *hw)
        if (ret_val)
                return ret_val;
 
-       /* For newer PHYs this bit is downshift enable */
-       if (phy->type == e1000_phy_m88)
+       /* For BM PHY this bit is downshift enable */
+       if (phy->type != e1000_phy_bm)
                phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
 
        /*
@@ -520,10 +634,27 @@ s32 e1000e_copper_link_setup_m88(struct e1000_hw *hw)
 
        /* Commit the changes. */
        ret_val = e1000e_commit_phy(hw);
-       if (ret_val)
+       if (ret_val) {
                hw_dbg(hw, "Error committing the PHY changes\n");
+               return ret_val;
+       }
 
-       return ret_val;
+       if (phy->type == e1000_phy_82578) {
+               ret_val = phy->ops.read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
+                                           &phy_data);
+               if (ret_val)
+                       return ret_val;
+
+               /* 82578 PHY - set the downshift count to 1x. */
+               phy_data |= I82578_EPSCR_DOWNSHIFT_ENABLE;
+               phy_data &= ~I82578_EPSCR_DOWNSHIFT_COUNTER_MASK;
+               ret_val = phy->ops.write_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL,
+                                            phy_data);
+               if (ret_val)
+                       return ret_val;
+       }
+
+       return 0;
 }
 
 /**
@@ -1251,6 +1382,8 @@ s32 e1000e_check_downshift(struct e1000_hw *hw)
        switch (phy->type) {
        case e1000_phy_m88:
        case e1000_phy_gg82563:
+       case e1000_phy_82578:
+       case e1000_phy_82577:
                offset  = M88E1000_PHY_SPEC_STATUS;
                mask    = M88E1000_PSSR_DOWNSHIFT;
                break;
@@ -1886,6 +2019,12 @@ enum e1000_phy_type e1000e_get_phy_type_from_id(u32 phy_id)
        case BME1000_E_PHY_ID_R2:
                phy_type = e1000_phy_bm;
                break;
+       case I82578_E_PHY_ID:
+               phy_type = e1000_phy_82578;
+               break;
+       case I82577_E_PHY_ID:
+               phy_type = e1000_phy_82577;
+               break;
        default:
                phy_type = e1000_phy_unknown;
                break;
@@ -2181,11 +2320,16 @@ static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset,
                                          u16 *data, bool read)
 {
        s32 ret_val;
-       u16 reg = ((u16)offset) & PHY_REG_MASK;
+       u16 reg = BM_PHY_REG_NUM(offset);
        u16 phy_reg = 0;
        u8  phy_acquired = 1;
 
 
+       /* Gig must be disabled for MDIO accesses to page 800 */
+       if ((hw->mac.type == e1000_pchlan) &&
+          (!(er32(PHY_CTRL) & E1000_PHY_CTRL_GBE_DISABLE)))
+               hw_dbg(hw, "Attempting to access page 800 while gig enabled\n");
+
        ret_val = hw->phy.ops.acquire_phy(hw);
        if (ret_val) {
                phy_acquired = 0;
@@ -2289,3 +2433,524 @@ static s32 e1000_set_d0_lplu_state(struct e1000_hw *hw, bool active)
 
        return 0;
 }
+
+s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw, bool slow)
+{
+       s32 ret_val = 0;
+       u16 data = 0;
+
+       ret_val = hw->phy.ops.acquire_phy(hw);
+       if (ret_val)
+               return ret_val;
+
+       /* Set MDIO mode - page 769, register 16: 0x2580==slow, 0x2180==fast */
+       hw->phy.addr = 1;
+       ret_val = e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT,
+                                        (BM_PORT_CTRL_PAGE << IGP_PAGE_SHIFT));
+       if (ret_val) {
+               hw->phy.ops.release_phy(hw);
+               return ret_val;
+       }
+       ret_val = e1000e_write_phy_reg_mdic(hw, BM_CS_CTRL1,
+                                          (0x2180 | (slow << 10)));
+
+       /* dummy read when reverting to fast mode - throw away result */
+       if (!slow)
+               e1000e_read_phy_reg_mdic(hw, BM_CS_CTRL1, &data);
+
+       hw->phy.ops.release_phy(hw);
+
+       return ret_val;
+}
+
+/**
+ *  e1000_read_phy_reg_hv -  Read HV PHY register
+ *  @hw: pointer to the HW structure
+ *  @offset: register offset to be read
+ *  @data: pointer to the read data
+ *
+ *  Acquires semaphore, if necessary, then reads the PHY register at offset
+ *  and storing the retrieved information in data.  Release any acquired
+ *  semaphore before exiting.
+ **/
+s32 e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data)
+{
+       s32 ret_val;
+       u16 page = BM_PHY_REG_PAGE(offset);
+       u16 reg = BM_PHY_REG_NUM(offset);
+       bool in_slow_mode = false;
+
+       /* Workaround failure in MDIO access while cable is disconnected */
+       if ((hw->phy.type == e1000_phy_82577) &&
+           !(er32(STATUS) & E1000_STATUS_LU)) {
+               ret_val = e1000_set_mdio_slow_mode_hv(hw, true);
+               if (ret_val)
+                       goto out;
+
+               in_slow_mode = true;
+       }
+
+       /* Page 800 works differently than the rest so it has its own func */
+       if (page == BM_WUC_PAGE) {
+               ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset,
+                                                        data, true);
+               goto out;
+       }
+
+       if (page > 0 && page < HV_INTC_FC_PAGE_START) {
+               ret_val = e1000_access_phy_debug_regs_hv(hw, offset,
+                                                        data, true);
+               goto out;
+       }
+
+       ret_val = hw->phy.ops.acquire_phy(hw);
+       if (ret_val)
+               goto out;
+
+       hw->phy.addr = e1000_get_phy_addr_for_hv_page(page);
+
+       if (page == HV_INTC_FC_PAGE_START)
+               page = 0;
+
+       if (reg > MAX_PHY_MULTI_PAGE_REG) {
+               if ((hw->phy.type != e1000_phy_82578) ||
+                   ((reg != I82578_ADDR_REG) &&
+                    (reg != I82578_ADDR_REG + 1))) {
+                       u32 phy_addr = hw->phy.addr;
+
+                       hw->phy.addr = 1;
+
+                       /* Page is shifted left, PHY expects (page x 32) */
+                       ret_val = e1000e_write_phy_reg_mdic(hw,
+                                                    IGP01E1000_PHY_PAGE_SELECT,
+                                                    (page << IGP_PAGE_SHIFT));
+                       if (ret_val) {
+                               hw->phy.ops.release_phy(hw);
+                               goto out;
+                       }
+                       hw->phy.addr = phy_addr;
+               }
+       }
+
+       ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & reg,
+                                         data);
+       hw->phy.ops.release_phy(hw);
+
+out:
+       /* Revert to MDIO fast mode, if applicable */
+       if ((hw->phy.type == e1000_phy_82577) && in_slow_mode)
+               ret_val = e1000_set_mdio_slow_mode_hv(hw, false);
+
+       return ret_val;
+}
+
+/**
+ *  e1000_write_phy_reg_hv - Write HV PHY register
+ *  @hw: pointer to the HW structure
+ *  @offset: register offset to write to
+ *  @data: data to write at register offset
+ *
+ *  Acquires semaphore, if necessary, then writes the data to PHY register
+ *  at the offset.  Release any acquired semaphores before exiting.
+ **/
+s32 e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data)
+{
+       s32 ret_val;
+       u16 page = BM_PHY_REG_PAGE(offset);
+       u16 reg = BM_PHY_REG_NUM(offset);
+       bool in_slow_mode = false;
+
+       /* Workaround failure in MDIO access while cable is disconnected */
+       if ((hw->phy.type == e1000_phy_82577) &&
+           !(er32(STATUS) & E1000_STATUS_LU)) {
+               ret_val = e1000_set_mdio_slow_mode_hv(hw, true);
+               if (ret_val)
+                       goto out;
+
+               in_slow_mode = true;
+       }
+
+       /* Page 800 works differently than the rest so it has its own func */
+       if (page == BM_WUC_PAGE) {
+               ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset,
+                                                        &data, false);
+               goto out;
+       }
+
+       if (page > 0 && page < HV_INTC_FC_PAGE_START) {
+               ret_val = e1000_access_phy_debug_regs_hv(hw, offset,
+                                                        &data, false);
+               goto out;
+       }
+
+       ret_val = hw->phy.ops.acquire_phy(hw);
+       if (ret_val)
+               goto out;
+
+       hw->phy.addr = e1000_get_phy_addr_for_hv_page(page);
+
+       if (page == HV_INTC_FC_PAGE_START)
+               page = 0;
+
+       /*
+        * Workaround MDIO accesses being disabled after entering IEEE Power
+        * Down (whenever bit 11 of the PHY Control register is set)
+        */
+       if ((hw->phy.type == e1000_phy_82578) &&
+           (hw->phy.revision >= 1) &&
+           (hw->phy.addr == 2) &&
+           ((MAX_PHY_REG_ADDRESS & reg) == 0) &&
+           (data & (1 << 11))) {
+               u16 data2 = 0x7EFF;
+               hw->phy.ops.release_phy(hw);
+               ret_val = e1000_access_phy_debug_regs_hv(hw, (1 << 6) | 0x3,
+                                                        &data2, false);
+               if (ret_val)
+                       goto out;
+
+               ret_val = hw->phy.ops.acquire_phy(hw);
+               if (ret_val)
+                       goto out;
+       }
+
+       if (reg > MAX_PHY_MULTI_PAGE_REG) {
+               if ((hw->phy.type != e1000_phy_82578) ||
+                   ((reg != I82578_ADDR_REG) &&
+                    (reg != I82578_ADDR_REG + 1))) {
+                       u32 phy_addr = hw->phy.addr;
+
+                       hw->phy.addr = 1;
+
+                       /* Page is shifted left, PHY expects (page x 32) */
+                       ret_val = e1000e_write_phy_reg_mdic(hw,
+                                                    IGP01E1000_PHY_PAGE_SELECT,
+                                                    (page << IGP_PAGE_SHIFT));
+                       if (ret_val) {
+                               hw->phy.ops.release_phy(hw);
+                               goto out;
+                       }
+                       hw->phy.addr = phy_addr;
+               }
+       }
+
+       ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & reg,
+                                         data);
+       hw->phy.ops.release_phy(hw);
+
+out:
+       /* Revert to MDIO fast mode, if applicable */
+       if ((hw->phy.type == e1000_phy_82577) && in_slow_mode)
+               ret_val = e1000_set_mdio_slow_mode_hv(hw, false);
+
+       return ret_val;
+}
+
+/**
+ *  e1000_get_phy_addr_for_hv_page - Get PHY adrress based on page
+ *  @page: page to be accessed
+ **/
+static u32 e1000_get_phy_addr_for_hv_page(u32 page)
+{
+       u32 phy_addr = 2;
+
+       if (page >= HV_INTC_FC_PAGE_START)
+               phy_addr = 1;
+
+       return phy_addr;
+}
+
+/**
+ *  e1000_access_phy_debug_regs_hv - Read HV PHY vendor specific high registers
+ *  @hw: pointer to the HW structure
+ *  @offset: register offset to be read or written
+ *  @data: pointer to the data to be read or written
+ *  @read: determines if operation is read or written
+ *
+ *  Acquires semaphore, if necessary, then reads the PHY register at offset
+ *  and storing the retreived information in data.  Release any acquired
+ *  semaphores before exiting.  Note that the procedure to read these regs
+ *  uses the address port and data port to read/write.
+ **/
+static s32 e1000_access_phy_debug_regs_hv(struct e1000_hw *hw, u32 offset,
+                                          u16 *data, bool read)
+{
+       s32 ret_val;
+       u32 addr_reg = 0;
+       u32 data_reg = 0;
+       u8  phy_acquired = 1;
+
+       /* This takes care of the difference with desktop vs mobile phy */
+       addr_reg = (hw->phy.type == e1000_phy_82578) ?
+                  I82578_ADDR_REG : I82577_ADDR_REG;
+       data_reg = addr_reg + 1;
+
+       ret_val = hw->phy.ops.acquire_phy(hw);
+       if (ret_val) {
+               hw_dbg(hw, "Could not acquire PHY\n");
+               phy_acquired = 0;
+               goto out;
+       }
+
+       /* All operations in this function are phy address 2 */
+       hw->phy.addr = 2;
+
+       /* masking with 0x3F to remove the page from offset */
+       ret_val = e1000e_write_phy_reg_mdic(hw, addr_reg, (u16)offset & 0x3F);
+       if (ret_val) {
+               hw_dbg(hw, "Could not write PHY the HV address register\n");
+               goto out;
+       }
+
+       /* Read or write the data value next */
+       if (read)
+               ret_val = e1000e_read_phy_reg_mdic(hw, data_reg, data);
+       else
+               ret_val = e1000e_write_phy_reg_mdic(hw, data_reg, *data);
+
+       if (ret_val) {
+               hw_dbg(hw, "Could not read data value from HV data register\n");
+               goto out;
+       }
+
+out:
+       if (phy_acquired == 1)
+               hw->phy.ops.release_phy(hw);
+       return ret_val;
+}
+
+/**
+ *  e1000_link_stall_workaround_hv - Si workaround
+ *  @hw: pointer to the HW structure
+ *
+ *  This function works around a Si bug where the link partner can get
+ *  a link up indication before the PHY does.  If small packets are sent
+ *  by the link partner they can be placed in the packet buffer without
+ *  being properly accounted for by the PHY and will stall preventing
+ *  further packets from being received.  The workaround is to clear the
+ *  packet buffer after the PHY detects link up.
+ **/
+s32 e1000_link_stall_workaround_hv(struct e1000_hw *hw)
+{
+       s32 ret_val = 0;
+       u16 data;
+
+       if (hw->phy.type != e1000_phy_82578)
+               goto out;
+
+       /* check if link is up and at 1Gbps */
+       ret_val = hw->phy.ops.read_phy_reg(hw, BM_CS_STATUS, &data);
+       if (ret_val)
+               goto out;
+
+       data &= BM_CS_STATUS_LINK_UP |
+               BM_CS_STATUS_RESOLVED |
+               BM_CS_STATUS_SPEED_MASK;
+
+       if (data != (BM_CS_STATUS_LINK_UP |
+                    BM_CS_STATUS_RESOLVED |
+                    BM_CS_STATUS_SPEED_1000))
+               goto out;
+
+       mdelay(200);
+
+       /* flush the packets in the fifo buffer */
+       ret_val = hw->phy.ops.write_phy_reg(hw, HV_MUX_DATA_CTRL,
+                                       HV_MUX_DATA_CTRL_GEN_TO_MAC |
+                                       HV_MUX_DATA_CTRL_FORCE_SPEED);
+       if (ret_val)
+               goto out;
+
+       ret_val = hw->phy.ops.write_phy_reg(hw, HV_MUX_DATA_CTRL,
+                                       HV_MUX_DATA_CTRL_GEN_TO_MAC);
+
+out:
+       return ret_val;
+}
+
+/**
+ *  e1000_check_polarity_82577 - Checks the polarity.
+ *  @hw: pointer to the HW structure
+ *
+ *  Success returns 0, Failure returns -E1000_ERR_PHY (-2)
+ *
+ *  Polarity is determined based on the PHY specific status register.
+ **/
+s32 e1000_check_polarity_82577(struct e1000_hw *hw)
+{
+       struct e1000_phy_info *phy = &hw->phy;
+       s32 ret_val;
+       u16 data;
+
+       ret_val = phy->ops.read_phy_reg(hw, I82577_PHY_STATUS_2, &data);
+
+       if (!ret_val)
+               phy->cable_polarity = (data & I82577_PHY_STATUS2_REV_POLARITY)
+                                     ? e1000_rev_polarity_reversed
+                                     : e1000_rev_polarity_normal;
+
+       return ret_val;
+}
+
+/**
+ *  e1000_phy_force_speed_duplex_82577 - Force speed/duplex for I82577 PHY
+ *  @hw: pointer to the HW structure
+ *
+ *  Calls the PHY setup function to force speed and duplex.  Clears the
+ *  auto-crossover to force MDI manually.  Waits for link and returns
+ *  successful if link up is successful, else -E1000_ERR_PHY (-2).
+ **/
+s32 e1000_phy_force_speed_duplex_82577(struct e1000_hw *hw)
+{
+       struct e1000_phy_info *phy = &hw->phy;
+       s32 ret_val;
+       u16 phy_data;
+       bool link;
+
+       ret_val = phy->ops.read_phy_reg(hw, PHY_CONTROL, &phy_data);
+       if (ret_val)
+               goto out;
+
+       e1000e_phy_force_speed_duplex_setup(hw, &phy_data);
+
+       ret_val = phy->ops.write_phy_reg(hw, PHY_CONTROL, phy_data);
+       if (ret_val)
+               goto out;
+
+       /*
+        * Clear Auto-Crossover to force MDI manually.  82577 requires MDI
+        * forced whenever speed and duplex are forced.
+        */
+       ret_val = phy->ops.read_phy_reg(hw, I82577_PHY_CTRL_2, &phy_data);
+       if (ret_val)
+               goto out;
+
+       phy_data &= ~I82577_PHY_CTRL2_AUTO_MDIX;
+       phy_data &= ~I82577_PHY_CTRL2_FORCE_MDI_MDIX;
+
+       ret_val = phy->ops.write_phy_reg(hw, I82577_PHY_CTRL_2, phy_data);
+       if (ret_val)
+               goto out;
+
+       hw_dbg(hw, "I82577_PHY_CTRL_2: %X\n", phy_data);
+
+       udelay(1);
+
+       if (phy->autoneg_wait_to_complete) {
+               hw_dbg(hw, "Waiting for forced speed/duplex link on 82577 phy\n");
+
+               ret_val = e1000e_phy_has_link_generic(hw,
+                                                    PHY_FORCE_LIMIT,
+                                                    100000,
+                                                    &link);
+               if (ret_val)
+                       goto out;
+
+               if (!link)
+                       hw_dbg(hw, "Link taking longer than expected.\n");
+
+               /* Try once more */
+               ret_val = e1000e_phy_has_link_generic(hw,
+                                                    PHY_FORCE_LIMIT,
+                                                    100000,
+                                                    &link);
+               if (ret_val)
+                       goto out;
+       }
+
+out:
+       return ret_val;
+}
+
+/**
+ *  e1000_get_phy_info_82577 - Retrieve I82577 PHY information
+ *  @hw: pointer to the HW structure
+ *
+ *  Read PHY status to determine if link is up.  If link is up, then
+ *  set/determine 10base-T extended distance and polarity correction.  Read
+ *  PHY port status to determine MDI/MDIx and speed.  Based on the speed,
+ *  determine on the cable length, local and remote receiver.
+ **/
+s32 e1000_get_phy_info_82577(struct e1000_hw *hw)
+{
+       struct e1000_phy_info *phy = &hw->phy;
+       s32 ret_val;
+       u16 data;
+       bool link;
+
+       ret_val = e1000e_phy_has_link_generic(hw, 1, 0, &link);
+       if (ret_val)
+               goto out;
+
+       if (!link) {
+               hw_dbg(hw, "Phy info is only valid if link is up\n");
+               ret_val = -E1000_ERR_CONFIG;
+               goto out;
+       }
+
+       phy->polarity_correction = true;
+
+       ret_val = e1000_check_polarity_82577(hw);
+       if (ret_val)
+               goto out;
+
+       ret_val = phy->ops.read_phy_reg(hw, I82577_PHY_STATUS_2, &data);
+       if (ret_val)
+               goto out;
+
+       phy->is_mdix = (data & I82577_PHY_STATUS2_MDIX) ? true : false;
+
+       if ((data & I82577_PHY_STATUS2_SPEED_MASK) ==
+           I82577_PHY_STATUS2_SPEED_1000MBPS) {
+               ret_val = hw->phy.ops.get_cable_length(hw);
+               if (ret_val)
+                       goto out;
+
+               ret_val = phy->ops.read_phy_reg(hw, PHY_1000T_STATUS, &data);
+               if (ret_val)
+                       goto out;
+
+               phy->local_rx = (data & SR_1000T_LOCAL_RX_STATUS)
+                               ? e1000_1000t_rx_status_ok
+                               : e1000_1000t_rx_status_not_ok;
+
+               phy->remote_rx = (data & SR_1000T_REMOTE_RX_STATUS)
+                                ? e1000_1000t_rx_status_ok
+                                : e1000_1000t_rx_status_not_ok;
+       } else {
+               phy->cable_length = E1000_CABLE_LENGTH_UNDEFINED;
+               phy->local_rx = e1000_1000t_rx_status_undefined;
+               phy->remote_rx = e1000_1000t_rx_status_undefined;
+       }
+
+out:
+       return ret_val;
+}
+
+/**
+ *  e1000_get_cable_length_82577 - Determine cable length for 82577 PHY
+ *  @hw: pointer to the HW structure
+ *
+ * Reads the diagnostic status register and verifies result is valid before
+ * placing it in the phy_cable_length field.
+ **/
+s32 e1000_get_cable_length_82577(struct e1000_hw *hw)
+{
+       struct e1000_phy_info *phy = &hw->phy;
+       s32 ret_val;
+       u16 phy_data, length;
+
+       ret_val = phy->ops.read_phy_reg(hw, I82577_PHY_DIAG_STATUS, &phy_data);
+       if (ret_val)
+               goto out;
+
+       length = (phy_data & I82577_DSTATUS_CABLE_LENGTH) >>
+                I82577_DSTATUS_CABLE_LENGTH_SHIFT;
+
+       if (length == E1000_CABLE_LENGTH_UNDEFINED)
+               ret_val = E1000_ERR_PHY;
+
+       phy->cable_length = length;
+
+out:
+       return ret_val;
+}
index b22dab9153f67788f8292ecfe877726cb7a0505d..147c4b088fb3c3467fa3b9027aa887067ccf8114 100644 (file)
@@ -3261,7 +3261,7 @@ static ssize_t ehea_probe_port(struct device *dev,
                               struct device_attribute *attr,
                               const char *buf, size_t count)
 {
-       struct ehea_adapter *adapter = dev->driver_data;
+       struct ehea_adapter *adapter = dev_get_drvdata(dev);
        struct ehea_port *port;
        struct device_node *eth_dn = NULL;
        int i;
@@ -3316,7 +3316,7 @@ static ssize_t ehea_remove_port(struct device *dev,
                                struct device_attribute *attr,
                                const char *buf, size_t count)
 {
-       struct ehea_adapter *adapter = dev->driver_data;
+       struct ehea_adapter *adapter = dev_get_drvdata(dev);
        struct ehea_port *port;
        int i;
        u32 logical_port_id;
@@ -3404,7 +3404,7 @@ static int __devinit ehea_probe_adapter(struct of_device *dev,
 
        adapter->pd = EHEA_PD_ID;
 
-       dev->dev.driver_data = adapter;
+       dev_set_drvdata(&dev->dev, adapter);
 
 
        /* initialize adapter and ports */
@@ -3468,7 +3468,7 @@ out:
 
 static int __devexit ehea_remove(struct of_device *dev)
 {
-       struct ehea_adapter *adapter = dev->dev.driver_data;
+       struct ehea_adapter *adapter = dev_get_drvdata(&dev->dev);
        int i;
 
        for (i = 0; i < EHEA_MAX_PORTS; i++)
index 9080f07da8fe01f23e81a52eef0690151017b47c..8005b602f7768ae1fb98a2dcf9b863a4d96ae3ce 100644 (file)
@@ -661,8 +661,6 @@ static int enic_hard_start_xmit(struct sk_buff *skb, struct net_device *netdev)
        if (vnic_wq_desc_avail(wq) < MAX_SKB_FRAGS + 1)
                netif_stop_queue(netdev);
 
-       netdev->trans_start = jiffies;
-
        spin_unlock_irqrestore(&enic->wq_lock[0], flags);
 
        return NETDEV_TX_OK;
index 5210bb1027cce43d168d5f09d391064af2fac812..19b7dd983944d84add883ee3f0d50abf270e0b80 100644 (file)
@@ -194,6 +194,7 @@ static void __init eql_setup(struct net_device *dev)
 
        dev->type               = ARPHRD_SLIP;
        dev->tx_queue_len       = 5;            /* Hands them off fast */
+       dev->priv_flags        &= ~IFF_XMIT_DST_RELEASE;
 }
 
 static int eql_open(struct net_device *dev)
index 91a9b1a3376407a91c26998a59ede7ea55154fdf..ceb6a9c357adad46d6ba2c897e6da96b909720d6 100644 (file)
@@ -811,7 +811,7 @@ static int ethoc_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
        if (unlikely(skb->len > ETHOC_BUFSIZ)) {
                priv->stats.tx_errors++;
-               return -EMSGSIZE;
+               goto out;
        }
 
        entry = priv->cur_tx % priv->num_tx;
@@ -840,9 +840,9 @@ static int ethoc_start_xmit(struct sk_buff *skb, struct net_device *dev)
        }
 
        dev->trans_start = jiffies;
-       dev_kfree_skb(skb);
-
        spin_unlock_irq(&priv->lock);
+out:
+       dev_kfree_skb(skb);
        return NETDEV_TX_OK;
 }
 
index 1a685a04d4b28212518c2bdc052fffc01e22553d..1e9723281405b6c5e52b15a29652efab8214b243 100644 (file)
@@ -873,7 +873,7 @@ static int ewrk3_queue_pkt (struct sk_buff *skb, struct net_device *dev)
 err_out:
        ENABLE_IRQs;
        spin_unlock_irq (&lp->hw_lock);
-       return 1;
+       return NETDEV_TX_BUSY;
 }
 
 /*
index 682e7f0b558127eb845be5bd60e73e97cafb59cc..0f19b743749bdf8b52783793276c36a247f3f928 100644 (file)
@@ -86,8 +86,7 @@ static unsigned char  fec_mac_default[] = {
 #endif
 #endif /* CONFIG_M5272 */
 
-/* Forward declarations of some structures to support different PHYs
-*/
+/* Forward declarations of some structures to support different PHYs */
 
 typedef struct {
        uint mii_data;
@@ -123,8 +122,7 @@ typedef struct {
 #error "FEC: descriptor ring size constants too large"
 #endif
 
-/* Interrupt events/masks.
-*/
+/* Interrupt events/masks. */
 #define FEC_ENET_HBERR ((uint)0x80000000)      /* Heartbeat error */
 #define FEC_ENET_BABR  ((uint)0x40000000)      /* Babbling receiver */
 #define FEC_ENET_BABT  ((uint)0x20000000)      /* Babbling transmitter */
@@ -165,7 +163,7 @@ typedef struct {
  */
 struct fec_enet_private {
        /* Hardware registers of the FEC device */
-       volatile fec_t  *hwp;
+       void __iomem *hwp;
 
        struct net_device *netdev;
 
@@ -174,16 +172,20 @@ struct fec_enet_private {
        /* The saved address of a sent-in-place packet/buffer, for skfree(). */
        unsigned char *tx_bounce[TX_RING_SIZE];
        struct  sk_buff* tx_skbuff[TX_RING_SIZE];
+       struct  sk_buff* rx_skbuff[RX_RING_SIZE];
        ushort  skb_cur;
        ushort  skb_dirty;
 
-       /* CPM dual port RAM relative addresses.
-       */
+       /* CPM dual port RAM relative addresses */
        dma_addr_t      bd_dma;
-       cbd_t   *rx_bd_base;            /* Address of Rx and Tx buffers. */
-       cbd_t   *tx_bd_base;
-       cbd_t   *cur_rx, *cur_tx;               /* The next free ring entry */
-       cbd_t   *dirty_tx;      /* The ring entries to be free()ed. */
+       /* Address of Rx and Tx buffers */
+       struct bufdesc  *rx_bd_base;
+       struct bufdesc  *tx_bd_base;
+       /* The next free ring entry */
+       struct bufdesc  *cur_rx, *cur_tx; 
+       /* The ring entries to be free()ed */
+       struct bufdesc  *dirty_tx;
+
        uint    tx_full;
        /* hold while accessing the HW like ringbuffer for tx/rx but not MAC */
        spinlock_t hw_lock;
@@ -209,17 +211,13 @@ struct fec_enet_private {
        int     full_duplex;
 };
 
-static int fec_enet_open(struct net_device *dev);
-static int fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev);
 static void fec_enet_mii(struct net_device *dev);
 static irqreturn_t fec_enet_interrupt(int irq, void * dev_id);
 static void fec_enet_tx(struct net_device *dev);
 static void fec_enet_rx(struct net_device *dev);
 static int fec_enet_close(struct net_device *dev);
-static void set_multicast_list(struct net_device *dev);
 static void fec_restart(struct net_device *dev, int duplex);
 static void fec_stop(struct net_device *dev);
-static void fec_set_mac_address(struct net_device *dev);
 
 
 /* MII processing.  We keep this as simple as possible.  Requests are
@@ -241,19 +239,16 @@ static mii_list_t *mii_tail;
 static int     mii_queue(struct net_device *dev, int request,
                                void (*func)(uint, struct net_device *));
 
-/* Make MII read/write commands for the FEC.
-*/
+/* Make MII read/write commands for the FEC */
 #define mk_mii_read(REG)       (0x60020000 | ((REG & 0x1f) << 18))
 #define mk_mii_write(REG, VAL) (0x50020000 | ((REG & 0x1f) << 18) | \
                                                (VAL & 0xffff))
 #define mk_mii_end     0
 
-/* Transmitter timeout.
-*/
-#define TX_TIMEOUT (2*HZ)
+/* Transmitter timeout */
+#define TX_TIMEOUT (2 * HZ)
 
-/* Register definitions for the PHY.
-*/
+/* Register definitions for the PHY */
 
 #define MII_REG_CR          0  /* Control Register                         */
 #define MII_REG_SR          1  /* Status Register                          */
@@ -288,18 +283,14 @@ static int        mii_queue(struct net_device *dev, int request,
 static int
 fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-       struct fec_enet_private *fep;
-       volatile fec_t  *fecp;
-       volatile cbd_t  *bdp;
+       struct fec_enet_private *fep = netdev_priv(dev);
+       struct bufdesc *bdp;
        unsigned short  status;
        unsigned long flags;
 
-       fep = netdev_priv(dev);
-       fecp = (volatile fec_t*)dev->base_addr;
-
        if (!fep->link) {
                /* Link is down or autonegotiation is in progress. */
-               return 1;
+               return NETDEV_TX_BUSY;
        }
 
        spin_lock_irqsave(&fep->hw_lock, flags);
@@ -307,30 +298,27 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
        bdp = fep->cur_tx;
 
        status = bdp->cbd_sc;
-#ifndef final_version
+
        if (status & BD_ENET_TX_READY) {
                /* Ooops.  All transmit buffers are full.  Bail out.
                 * This should not happen, since dev->tbusy should be set.
                 */
                printk("%s: tx queue full!.\n", dev->name);
                spin_unlock_irqrestore(&fep->hw_lock, flags);
-               return 1;
+               return NETDEV_TX_BUSY;
        }
-#endif
 
-       /* Clear all of the status flags.
-        */
+       /* Clear all of the status flags */
        status &= ~BD_ENET_TX_STATS;
 
-       /* Set buffer length and buffer pointer.
-       */
+       /* Set buffer length and buffer pointer */
        bdp->cbd_bufaddr = __pa(skb->data);
        bdp->cbd_datlen = skb->len;
 
        /*
-        *      On some FEC implementations data must be aligned on
-        *      4-byte boundaries. Use bounce buffers to copy data
-        *      and get it aligned. Ugh.
+        * On some FEC implementations data must be aligned on
+        * 4-byte boundaries. Use bounce buffers to copy data
+        * and get it aligned. Ugh.
         */
        if (bdp->cbd_bufaddr & FEC_ALIGNMENT) {
                unsigned int index;
@@ -339,8 +327,7 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
                bdp->cbd_bufaddr = __pa(fep->tx_bounce[index]);
        }
 
-       /* Save skb pointer.
-       */
+       /* Save skb pointer */
        fep->tx_skbuff[fep->skb_cur] = skb;
 
        dev->stats.tx_bytes += skb->len;
@@ -349,13 +336,12 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
        /* Push the data cache so the CPM does not get stale memory
         * data.
         */
-       dma_sync_single(NULL, bdp->cbd_bufaddr,
-                       bdp->cbd_datlen, DMA_TO_DEVICE);
+       bdp->cbd_bufaddr = dma_map_single(&dev->dev, skb->data,
+                       FEC_ENET_TX_FRSIZE, DMA_TO_DEVICE);
 
        /* Send it on its way.  Tell FEC it's ready, interrupt when done,
         * it's the last BD of the frame, and to put the CRC on the end.
         */
-
        status |= (BD_ENET_TX_READY | BD_ENET_TX_INTR
                        | BD_ENET_TX_LAST | BD_ENET_TX_TC);
        bdp->cbd_sc = status;
@@ -363,22 +349,20 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
        dev->trans_start = jiffies;
 
        /* Trigger transmission start */
-       fecp->fec_x_des_active = 0;
+       writel(0, fep->hwp + FEC_X_DES_ACTIVE);
 
-       /* If this was the last BD in the ring, start at the beginning again.
-       */
-       if (status & BD_ENET_TX_WRAP) {
+       /* If this was the last BD in the ring, start at the beginning again. */
+       if (status & BD_ENET_TX_WRAP)
                bdp = fep->tx_bd_base;
-       } else {
+       else
                bdp++;
-       }
 
        if (bdp == fep->dirty_tx) {
                fep->tx_full = 1;
                netif_stop_queue(dev);
        }
 
-       fep->cur_tx = (cbd_t *)bdp;
+       fep->cur_tx = bdp;
 
        spin_unlock_irqrestore(&fep->hw_lock, flags);
 
@@ -390,75 +374,33 @@ fec_timeout(struct net_device *dev)
 {
        struct fec_enet_private *fep = netdev_priv(dev);
 
-       printk("%s: transmit timed out.\n", dev->name);
        dev->stats.tx_errors++;
-#ifndef final_version
-       {
-       int     i;
-       cbd_t   *bdp;
-
-       printk("Ring data dump: cur_tx %lx%s, dirty_tx %lx cur_rx: %lx\n",
-              (unsigned long)fep->cur_tx, fep->tx_full ? " (full)" : "",
-              (unsigned long)fep->dirty_tx,
-              (unsigned long)fep->cur_rx);
-
-       bdp = fep->tx_bd_base;
-       printk(" tx: %u buffers\n",  TX_RING_SIZE);
-       for (i = 0 ; i < TX_RING_SIZE; i++) {
-               printk("  %08x: %04x %04x %08x\n",
-                      (uint) bdp,
-                      bdp->cbd_sc,
-                      bdp->cbd_datlen,
-                      (int) bdp->cbd_bufaddr);
-               bdp++;
-       }
 
-       bdp = fep->rx_bd_base;
-       printk(" rx: %lu buffers\n",  (unsigned long) RX_RING_SIZE);
-       for (i = 0 ; i < RX_RING_SIZE; i++) {
-               printk("  %08x: %04x %04x %08x\n",
-                      (uint) bdp,
-                      bdp->cbd_sc,
-                      bdp->cbd_datlen,
-                      (int) bdp->cbd_bufaddr);
-               bdp++;
-       }
-       }
-#endif
        fec_restart(dev, fep->full_duplex);
        netif_wake_queue(dev);
 }
 
-/* The interrupt handler.
- * This is called from the MPC core interrupt.
- */
 static irqreturn_t
 fec_enet_interrupt(int irq, void * dev_id)
 {
        struct  net_device *dev = dev_id;
-       volatile fec_t  *fecp;
+       struct fec_enet_private *fep = netdev_priv(dev);
        uint    int_events;
        irqreturn_t ret = IRQ_NONE;
 
-       fecp = (volatile fec_t*)dev->base_addr;
-
-       /* Get the interrupt events that caused us to be here.
-       */
        do {
-               int_events = fecp->fec_ievent;
-               fecp->fec_ievent = int_events;
+               int_events = readl(fep->hwp + FEC_IEVENT);
+               writel(int_events, fep->hwp + FEC_IEVENT);
 
-               /* Handle receive event in its own function.
-                */
                if (int_events & FEC_ENET_RXF) {
                        ret = IRQ_HANDLED;
                        fec_enet_rx(dev);
                }
 
                /* Transmit OK, or non-fatal error. Update the buffer
-                  descriptors. FEC handles all errors, we just discover
-                  them as part of the transmit process.
-               */
+                * descriptors. FEC handles all errors, we just discover
+                * them as part of the transmit process.
+                */
                if (int_events & FEC_ENET_TXF) {
                        ret = IRQ_HANDLED;
                        fec_enet_tx(dev);
@@ -479,7 +421,7 @@ static void
 fec_enet_tx(struct net_device *dev)
 {
        struct  fec_enet_private *fep;
-       volatile cbd_t  *bdp;
+       struct bufdesc *bdp;
        unsigned short status;
        struct  sk_buff *skb;
 
@@ -488,7 +430,11 @@ fec_enet_tx(struct net_device *dev)
        bdp = fep->dirty_tx;
 
        while (((status = bdp->cbd_sc) & BD_ENET_TX_READY) == 0) {
-               if (bdp == fep->cur_tx && fep->tx_full == 0) break;
+               if (bdp == fep->cur_tx && fep->tx_full == 0)
+                       break;
+
+               dma_unmap_single(&dev->dev, bdp->cbd_bufaddr, FEC_ENET_TX_FRSIZE, DMA_TO_DEVICE);
+               bdp->cbd_bufaddr = 0;
 
                skb = fep->tx_skbuff[fep->skb_dirty];
                /* Check for errors. */
@@ -510,31 +456,27 @@ fec_enet_tx(struct net_device *dev)
                        dev->stats.tx_packets++;
                }
 
-#ifndef final_version
                if (status & BD_ENET_TX_READY)
                        printk("HEY! Enet xmit interrupt and TX_READY.\n");
-#endif
+
                /* Deferred means some collisions occurred during transmit,
                 * but we eventually sent the packet OK.
                 */
                if (status & BD_ENET_TX_DEF)
                        dev->stats.collisions++;
 
-               /* Free the sk buffer associated with this last transmit.
-                */
+               /* Free the sk buffer associated with this last transmit */
                dev_kfree_skb_any(skb);
                fep->tx_skbuff[fep->skb_dirty] = NULL;
                fep->skb_dirty = (fep->skb_dirty + 1) & TX_RING_MOD_MASK;
 
-               /* Update pointer to next buffer descriptor to be transmitted.
-                */
+               /* Update pointer to next buffer descriptor to be transmitted */
                if (status & BD_ENET_TX_WRAP)
                        bdp = fep->tx_bd_base;
                else
                        bdp++;
 
-               /* Since we have freed up a buffer, the ring is no longer
-                * full.
+               /* Since we have freed up a buffer, the ring is no longer full
                 */
                if (fep->tx_full) {
                        fep->tx_full = 0;
@@ -542,7 +484,7 @@ fec_enet_tx(struct net_device *dev)
                                netif_wake_queue(dev);
                }
        }
-       fep->dirty_tx = (cbd_t *)bdp;
+       fep->dirty_tx = bdp;
        spin_unlock_irq(&fep->hw_lock);
 }
 
@@ -555,9 +497,8 @@ fec_enet_tx(struct net_device *dev)
 static void
 fec_enet_rx(struct net_device *dev)
 {
-       struct  fec_enet_private *fep;
-       volatile fec_t  *fecp;
-       volatile cbd_t *bdp;
+       struct  fec_enet_private *fep = netdev_priv(dev);
+       struct bufdesc *bdp;
        unsigned short status;
        struct  sk_buff *skb;
        ushort  pkt_len;
@@ -567,9 +508,6 @@ fec_enet_rx(struct net_device *dev)
        flush_cache_all();
 #endif
 
-       fep = netdev_priv(dev);
-       fecp = (volatile fec_t*)dev->base_addr;
-
        spin_lock_irq(&fep->hw_lock);
 
        /* First, grab all of the stats for the incoming packet.
@@ -577,143 +515,121 @@ fec_enet_rx(struct net_device *dev)
         */
        bdp = fep->cur_rx;
 
-while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) {
+       while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) {
 
-#ifndef final_version
-       /* Since we have allocated space to hold a complete frame,
-        * the last indicator should be set.
-        */
-       if ((status & BD_ENET_RX_LAST) == 0)
-               printk("FEC ENET: rcv is not +last\n");
-#endif
+               /* Since we have allocated space to hold a complete frame,
+                * the last indicator should be set.
+                */
+               if ((status & BD_ENET_RX_LAST) == 0)
+                       printk("FEC ENET: rcv is not +last\n");
 
-       if (!fep->opened)
-               goto rx_processing_done;
+               if (!fep->opened)
+                       goto rx_processing_done;
 
-       /* Check for errors. */
-       if (status & (BD_ENET_RX_LG | BD_ENET_RX_SH | BD_ENET_RX_NO |
+               /* Check for errors. */
+               if (status & (BD_ENET_RX_LG | BD_ENET_RX_SH | BD_ENET_RX_NO |
                           BD_ENET_RX_CR | BD_ENET_RX_OV)) {
-               dev->stats.rx_errors++;
-               if (status & (BD_ENET_RX_LG | BD_ENET_RX_SH)) {
-               /* Frame too long or too short. */
-                       dev->stats.rx_length_errors++;
+                       dev->stats.rx_errors++;
+                       if (status & (BD_ENET_RX_LG | BD_ENET_RX_SH)) {
+                               /* Frame too long or too short. */
+                               dev->stats.rx_length_errors++;
+                       }
+                       if (status & BD_ENET_RX_NO)     /* Frame alignment */
+                               dev->stats.rx_frame_errors++;
+                       if (status & BD_ENET_RX_CR)     /* CRC Error */
+                               dev->stats.rx_crc_errors++;
+                       if (status & BD_ENET_RX_OV)     /* FIFO overrun */
+                               dev->stats.rx_fifo_errors++;
                }
-               if (status & BD_ENET_RX_NO)     /* Frame alignment */
+
+               /* Report late collisions as a frame error.
+                * On this error, the BD is closed, but we don't know what we
+                * have in the buffer.  So, just drop this frame on the floor.
+                */
+               if (status & BD_ENET_RX_CL) {
+                       dev->stats.rx_errors++;
                        dev->stats.rx_frame_errors++;
-               if (status & BD_ENET_RX_CR)     /* CRC Error */
-                       dev->stats.rx_crc_errors++;
-               if (status & BD_ENET_RX_OV)     /* FIFO overrun */
-                       dev->stats.rx_fifo_errors++;
-       }
+                       goto rx_processing_done;
+               }
 
-       /* Report late collisions as a frame error.
-        * On this error, the BD is closed, but we don't know what we
-        * have in the buffer.  So, just drop this frame on the floor.
-        */
-       if (status & BD_ENET_RX_CL) {
-               dev->stats.rx_errors++;
-               dev->stats.rx_frame_errors++;
-               goto rx_processing_done;
-       }
+               /* Process the incoming frame. */
+               dev->stats.rx_packets++;
+               pkt_len = bdp->cbd_datlen;
+               dev->stats.rx_bytes += pkt_len;
+               data = (__u8*)__va(bdp->cbd_bufaddr);
 
-       /* Process the incoming frame.
-        */
-       dev->stats.rx_packets++;
-       pkt_len = bdp->cbd_datlen;
-       dev->stats.rx_bytes += pkt_len;
-       data = (__u8*)__va(bdp->cbd_bufaddr);
-
-       dma_sync_single(NULL, (unsigned long)__pa(data),
-                       pkt_len - 4, DMA_FROM_DEVICE);
-
-       /* This does 16 byte alignment, exactly what we need.
-        * The packet length includes FCS, but we don't want to
-        * include that when passing upstream as it messes up
-        * bridging applications.
-        */
-       skb = dev_alloc_skb(pkt_len-4);
+               dma_unmap_single(NULL, bdp->cbd_bufaddr, bdp->cbd_datlen,
+                               DMA_FROM_DEVICE);
 
-       if (skb == NULL) {
-               printk("%s: Memory squeeze, dropping packet.\n", dev->name);
-               dev->stats.rx_dropped++;
-       } else {
-               skb_put(skb,pkt_len-4); /* Make room */
-               skb_copy_to_linear_data(skb, data, pkt_len-4);
-               skb->protocol=eth_type_trans(skb,dev);
-               netif_rx(skb);
-       }
-  rx_processing_done:
+               /* This does 16 byte alignment, exactly what we need.
+                * The packet length includes FCS, but we don't want to
+                * include that when passing upstream as it messes up
+                * bridging applications.
+                */
+               skb = dev_alloc_skb(pkt_len - 4 + NET_IP_ALIGN);
 
-       /* Clear the status flags for this buffer.
-       */
-       status &= ~BD_ENET_RX_STATS;
+               if (unlikely(!skb)) {
+                       printk("%s: Memory squeeze, dropping packet.\n",
+                                       dev->name);
+                       dev->stats.rx_dropped++;
+               } else {
+                       skb_reserve(skb, NET_IP_ALIGN);
+                       skb_put(skb, pkt_len - 4);      /* Make room */
+                       skb_copy_to_linear_data(skb, data, pkt_len - 4);
+                       skb->protocol = eth_type_trans(skb, dev);
+                       netif_rx(skb);
+               }
 
-       /* Mark the buffer empty.
-       */
-       status |= BD_ENET_RX_EMPTY;
-       bdp->cbd_sc = status;
+               bdp->cbd_bufaddr = dma_map_single(NULL, data, bdp->cbd_datlen,
+                       DMA_FROM_DEVICE);
+rx_processing_done:
+               /* Clear the status flags for this buffer */
+               status &= ~BD_ENET_RX_STATS;
 
-       /* Update BD pointer to next entry.
-       */
-       if (status & BD_ENET_RX_WRAP)
-               bdp = fep->rx_bd_base;
-       else
-               bdp++;
+               /* Mark the buffer empty */
+               status |= BD_ENET_RX_EMPTY;
+               bdp->cbd_sc = status;
 
-#if 1
-       /* Doing this here will keep the FEC running while we process
-        * incoming frames.  On a heavily loaded network, we should be
-        * able to keep up at the expense of system resources.
-        */
-       fecp->fec_r_des_active = 0;
-#endif
-   } /* while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) */
-       fep->cur_rx = (cbd_t *)bdp;
-
-#if 0
-       /* Doing this here will allow us to process all frames in the
-        * ring before the FEC is allowed to put more there.  On a heavily
-        * loaded network, some frames may be lost.  Unfortunately, this
-        * increases the interrupt overhead since we can potentially work
-        * our way back to the interrupt return only to come right back
-        * here.
-        */
-       fecp->fec_r_des_active = 0;
-#endif
+               /* Update BD pointer to next entry */
+               if (status & BD_ENET_RX_WRAP)
+                       bdp = fep->rx_bd_base;
+               else
+                       bdp++;
+               /* Doing this here will keep the FEC running while we process
+                * incoming frames.  On a heavily loaded network, we should be
+                * able to keep up at the expense of system resources.
+                */
+               writel(0, fep->hwp + FEC_R_DES_ACTIVE);
+       }
+       fep->cur_rx = bdp;
 
        spin_unlock_irq(&fep->hw_lock);
 }
 
-
 /* called from interrupt context */
 static void
 fec_enet_mii(struct net_device *dev)
 {
        struct  fec_enet_private *fep;
-       volatile fec_t  *ep;
        mii_list_t      *mip;
-       uint            mii_reg;
 
        fep = netdev_priv(dev);
        spin_lock_irq(&fep->mii_lock);
 
-       ep = fep->hwp;
-       mii_reg = ep->fec_mii_data;
-
        if ((mip = mii_head) == NULL) {
                printk("MII and no head!\n");
                goto unlock;
        }
 
        if (mip->mii_func != NULL)
-               (*(mip->mii_func))(mii_reg, dev);
+               (*(mip->mii_func))(readl(fep->hwp + FEC_MII_DATA), dev);
 
        mii_head = mip->mii_next;
        mip->mii_next = mii_free;
        mii_free = mip;
 
        if ((mip = mii_head) != NULL)
-               ep->fec_mii_data = mip->mii_regval;
+               writel(mip->mii_regval, fep->hwp + FEC_MII_DATA);
 
 unlock:
        spin_unlock_irq(&fep->mii_lock);
@@ -727,8 +643,7 @@ mii_queue(struct net_device *dev, int regval, void (*func)(uint, struct net_devi
        mii_list_t      *mip;
        int             retval;
 
-       /* Add PHY address to register command.
-       */
+       /* Add PHY address to register command */
        fep = netdev_priv(dev);
        spin_lock_irqsave(&fep->mii_lock, flags);
 
@@ -745,7 +660,7 @@ mii_queue(struct net_device *dev, int regval, void (*func)(uint, struct net_devi
                        mii_tail = mip;
                } else {
                        mii_head = mii_tail = mip;
-                       fep->hwp->fec_mii_data = regval;
+                       writel(regval, fep->hwp + FEC_MII_DATA);
                }
        } else {
                retval = 1;
@@ -1246,11 +1161,8 @@ static void __inline__ fec_phy_ack_intr(void)
 static void __inline__ fec_get_mac(struct net_device *dev)
 {
        struct fec_enet_private *fep = netdev_priv(dev);
-       volatile fec_t *fecp;
        unsigned char *iap, tmpaddr[ETH_ALEN];
 
-       fecp = fep->hwp;
-
        if (FEC_FLASHMAC) {
                /*
                 * Get MAC address from FLASH.
@@ -1264,8 +1176,8 @@ static void __inline__ fec_get_mac(struct net_device *dev)
                    (iap[3] == 0xff) && (iap[4] == 0xff) && (iap[5] == 0xff))
                        iap = fec_mac_default;
        } else {
-               *((unsigned long *) &tmpaddr[0]) = fecp->fec_addr_low;
-               *((unsigned short *) &tmpaddr[4]) = (fecp->fec_addr_high >> 16);
+               *((unsigned long *) &tmpaddr[0]) = readl(fep->hwp + FEC_ADDR_LOW);
+               *((unsigned short *) &tmpaddr[4]) = (readl(fep->hwp + FEC_ADDR_HIGH) >> 16);
                iap = &tmpaddr[0];
        }
 
@@ -1375,11 +1287,6 @@ static void mii_relink(struct work_struct *work)
                fec_restart(dev, duplex);
        } else
                fec_stop(dev);
-
-#if 0
-       enable_irq(fep->mii_irq);
-#endif
-
 }
 
 /* mii_queue_relink is called in interrupt context from mii_link_interrupt */
@@ -1388,12 +1295,12 @@ static void mii_queue_relink(uint mii_reg, struct net_device *dev)
        struct fec_enet_private *fep = netdev_priv(dev);
 
        /*
-       ** We cannot queue phy_task twice in the workqueue.  It
-       ** would cause an endless loop in the workqueue.
-       ** Fortunately, if the last mii_relink entry has not yet been
-       ** executed now, it will do the job for the current interrupt,
-       ** which is just what we want.
-       */
+        * We cannot queue phy_task twice in the workqueue.  It
+        * would cause an endless loop in the workqueue.
+        * Fortunately, if the last mii_relink entry has not yet been
+        * executed now, it will do the job for the current interrupt,
+        * which is just what we want.
+        */
        if (fep->mii_phy_task_queued)
                return;
 
@@ -1424,8 +1331,7 @@ phy_cmd_t const phy_cmd_config[] = {
        { mk_mii_end, }
        };
 
-/* Read remainder of PHY ID.
-*/
+/* Read remainder of PHY ID. */
 static void
 mii_discover_phy3(uint mii_reg, struct net_device *dev)
 {
@@ -1457,17 +1363,14 @@ static void
 mii_discover_phy(uint mii_reg, struct net_device *dev)
 {
        struct fec_enet_private *fep;
-       volatile fec_t *fecp;
        uint phytype;
 
        fep = netdev_priv(dev);
-       fecp = fep->hwp;
 
        if (fep->phy_addr < 32) {
                if ((phytype = (mii_reg & 0xffff)) != 0xffff && phytype != 0) {
 
-                       /* Got first part of ID, now get remainder.
-                       */
+                       /* Got first part of ID, now get remainder */
                        fep->phy_id = phytype << 16;
                        mii_queue(dev, mk_mii_read(MII_REG_PHYIR2),
                                                        mii_discover_phy3);
@@ -1479,15 +1382,15 @@ mii_discover_phy(uint mii_reg, struct net_device *dev)
        } else {
                printk("FEC: No PHY device found.\n");
                /* Disable external MII interface */
-               fecp->fec_mii_speed = fep->phy_speed = 0;
+               writel(0, fep->hwp + FEC_MII_SPEED);
+               fep->phy_speed = 0;
 #ifdef HAVE_mii_link_interrupt
                fec_disable_phy_intr();
 #endif
        }
 }
 
-/* This interrupt occurs when the PHY detects a link change.
-*/
+/* This interrupt occurs when the PHY detects a link change */
 #ifdef HAVE_mii_link_interrupt
 static irqreturn_t
 mii_link_interrupt(int irq, void * dev_id)
@@ -1497,10 +1400,6 @@ mii_link_interrupt(int irq, void * dev_id)
 
        fec_phy_ack_intr();
 
-#if 0
-       disable_irq(fep->mii_irq);  /* disable now, enable later */
-#endif
-
        mii_do_cmd(dev, fep->phy->ack_int);
        mii_do_cmd(dev, phy_cmd_relink);  /* restart and display status */
 
@@ -1508,19 +1407,91 @@ mii_link_interrupt(int irq, void * dev_id)
 }
 #endif
 
+static void fec_enet_free_buffers(struct net_device *dev)
+{
+       struct fec_enet_private *fep = netdev_priv(dev);
+       int i;
+       struct sk_buff *skb;
+       struct bufdesc  *bdp;
+
+       bdp = fep->rx_bd_base;
+       for (i = 0; i < RX_RING_SIZE; i++) {
+               skb = fep->rx_skbuff[i];
+
+               if (bdp->cbd_bufaddr)
+                       dma_unmap_single(&dev->dev, bdp->cbd_bufaddr,
+                                       FEC_ENET_RX_FRSIZE, DMA_FROM_DEVICE);
+               if (skb)
+                       dev_kfree_skb(skb);
+               bdp++;
+       }
+
+       bdp = fep->tx_bd_base;
+       for (i = 0; i < TX_RING_SIZE; i++)
+               kfree(fep->tx_bounce[i]);
+}
+
+static int fec_enet_alloc_buffers(struct net_device *dev)
+{
+       struct fec_enet_private *fep = netdev_priv(dev);
+       int i;
+       struct sk_buff *skb;
+       struct bufdesc  *bdp;
+
+       bdp = fep->rx_bd_base;
+       for (i = 0; i < RX_RING_SIZE; i++) {
+               skb = dev_alloc_skb(FEC_ENET_RX_FRSIZE);
+               if (!skb) {
+                       fec_enet_free_buffers(dev);
+                       return -ENOMEM;
+               }
+               fep->rx_skbuff[i] = skb;
+
+               bdp->cbd_bufaddr = dma_map_single(&dev->dev, skb->data,
+                               FEC_ENET_RX_FRSIZE, DMA_FROM_DEVICE);
+               bdp->cbd_sc = BD_ENET_RX_EMPTY;
+               bdp++;
+       }
+
+       /* Set the last buffer to wrap. */
+       bdp--;
+       bdp->cbd_sc |= BD_SC_WRAP;
+
+       bdp = fep->tx_bd_base;
+       for (i = 0; i < TX_RING_SIZE; i++) {
+               fep->tx_bounce[i] = kmalloc(FEC_ENET_TX_FRSIZE, GFP_KERNEL);
+
+               bdp->cbd_sc = 0;
+               bdp->cbd_bufaddr = 0;
+               bdp++;
+       }
+
+       /* Set the last buffer to wrap. */
+       bdp--;
+       bdp->cbd_sc |= BD_SC_WRAP;
+
+       return 0;
+}
+
 static int
 fec_enet_open(struct net_device *dev)
 {
        struct fec_enet_private *fep = netdev_priv(dev);
+       int ret;
 
        /* I should reset the ring buffers here, but I don't yet know
         * a simple way to do that.
         */
-       fec_set_mac_address(dev);
+
+       ret = fec_enet_alloc_buffers(dev);
+       if (ret)
+               return ret;
 
        fep->sequence_done = 0;
        fep->link = 0;
 
+       fec_restart(dev, 1);
+
        if (fep->phy) {
                mii_do_cmd(dev, fep->phy->ack_int);
                mii_do_cmd(dev, fep->phy->config);
@@ -1537,21 +1508,17 @@ fec_enet_open(struct net_device *dev)
                        schedule();
 
                mii_do_cmd(dev, fep->phy->startup);
-
-               /* Set the initial link state to true. A lot of hardware
-                * based on this device does not implement a PHY interrupt,
-                * so we are never notified of link change.
-                */
-               fep->link = 1;
-       } else {
-               fep->link = 1; /* lets just try it and see */
-               /* no phy,  go full duplex,  it's most likely a hub chip */
-               fec_restart(dev, 1);
        }
 
+       /* Set the initial link state to true. A lot of hardware
+        * based on this device does not implement a PHY interrupt,
+        * so we are never notified of link change.
+        */
+       fep->link = 1;
+
        netif_start_queue(dev);
        fep->opened = 1;
-       return 0;               /* Success */
+       return 0;
 }
 
 static int
@@ -1559,12 +1526,13 @@ fec_enet_close(struct net_device *dev)
 {
        struct fec_enet_private *fep = netdev_priv(dev);
 
-       /* Don't know what to do yet.
-       */
+       /* Don't know what to do yet. */
        fep->opened = 0;
        netif_stop_queue(dev);
        fec_stop(dev);
 
+        fec_enet_free_buffers(dev);
+
        return 0;
 }
 
@@ -1583,87 +1551,102 @@ fec_enet_close(struct net_device *dev)
 
 static void set_multicast_list(struct net_device *dev)
 {
-       struct fec_enet_private *fep;
-       volatile fec_t *ep;
+       struct fec_enet_private *fep = netdev_priv(dev);
        struct dev_mc_list *dmi;
-       unsigned int i, j, bit, data, crc;
+       unsigned int i, j, bit, data, crc, tmp;
        unsigned char hash;
 
-       fep = netdev_priv(dev);
-       ep = fep->hwp;
+       if (dev->flags & IFF_PROMISC) {
+               tmp = readl(fep->hwp + FEC_R_CNTRL);
+               tmp |= 0x8;
+               writel(tmp, fep->hwp + FEC_R_CNTRL);
+               return;
+       }
 
-       if (dev->flags&IFF_PROMISC) {
-               ep->fec_r_cntrl |= 0x0008;
-       } else {
+       tmp = readl(fep->hwp + FEC_R_CNTRL);
+       tmp &= ~0x8;
+       writel(tmp, fep->hwp + FEC_R_CNTRL);
+
+       if (dev->flags & IFF_ALLMULTI) {
+               /* Catch all multicast addresses, so set the
+                * filter to all 1's
+                */
+               writel(0xffffffff, fep->hwp + FEC_GRP_HASH_TABLE_HIGH);
+               writel(0xffffffff, fep->hwp + FEC_GRP_HASH_TABLE_LOW);
 
-               ep->fec_r_cntrl &= ~0x0008;
+               return;
+       }
 
-               if (dev->flags & IFF_ALLMULTI) {
-                       /* Catch all multicast addresses, so set the
-                        * filter to all 1's.
-                        */
-                       ep->fec_grp_hash_table_high = 0xffffffff;
-                       ep->fec_grp_hash_table_low = 0xffffffff;
-               } else {
-                       /* Clear filter and add the addresses in hash register.
-                       */
-                       ep->fec_grp_hash_table_high = 0;
-                       ep->fec_grp_hash_table_low = 0;
-
-                       dmi = dev->mc_list;
-
-                       for (j = 0; j < dev->mc_count; j++, dmi = dmi->next)
-                       {
-                               /* Only support group multicast for now.
-                               */
-                               if (!(dmi->dmi_addr[0] & 1))
-                                       continue;
-
-                               /* calculate crc32 value of mac address
-                               */
-                               crc = 0xffffffff;
-
-                               for (i = 0; i < dmi->dmi_addrlen; i++)
-                               {
-                                       data = dmi->dmi_addr[i];
-                                       for (bit = 0; bit < 8; bit++, data >>= 1)
-                                       {
-                                               crc = (crc >> 1) ^
-                                               (((crc ^ data) & 1) ? CRC32_POLY : 0);
-                                       }
-                               }
-
-                               /* only upper 6 bits (HASH_BITS) are used
-                                  which point to specific bit in he hash registers
-                               */
-                               hash = (crc >> (32 - HASH_BITS)) & 0x3f;
-
-                               if (hash > 31)
-                                       ep->fec_grp_hash_table_high |= 1 << (hash - 32);
-                               else
-                                       ep->fec_grp_hash_table_low |= 1 << hash;
+       /* Clear filter and add the addresses in hash register
+        */
+       writel(0, fep->hwp + FEC_GRP_HASH_TABLE_HIGH);
+       writel(0, fep->hwp + FEC_GRP_HASH_TABLE_LOW);
+
+       dmi = dev->mc_list;
+
+       for (j = 0; j < dev->mc_count; j++, dmi = dmi->next) {
+               /* Only support group multicast for now */
+               if (!(dmi->dmi_addr[0] & 1))
+                       continue;
+
+               /* calculate crc32 value of mac address */
+               crc = 0xffffffff;
+
+               for (i = 0; i < dmi->dmi_addrlen; i++) {
+                       data = dmi->dmi_addr[i];
+                       for (bit = 0; bit < 8; bit++, data >>= 1) {
+                               crc = (crc >> 1) ^
+                               (((crc ^ data) & 1) ? CRC32_POLY : 0);
                        }
                }
+
+               /* only upper 6 bits (HASH_BITS) are used
+                * which point to specific bit in he hash registers
+                */
+               hash = (crc >> (32 - HASH_BITS)) & 0x3f;
+
+               if (hash > 31) {
+                       tmp = readl(fep->hwp + FEC_GRP_HASH_TABLE_HIGH);
+                       tmp |= 1 << (hash - 32);
+                       writel(tmp, fep->hwp + FEC_GRP_HASH_TABLE_HIGH);
+               } else {
+                       tmp = readl(fep->hwp + FEC_GRP_HASH_TABLE_LOW);
+                       tmp |= 1 << hash;
+                       writel(tmp, fep->hwp + FEC_GRP_HASH_TABLE_LOW);
+               }
        }
 }
 
-/* Set a MAC change in hardware.
- */
-static void
-fec_set_mac_address(struct net_device *dev)
+/* Set a MAC change in hardware. */
+static int
+fec_set_mac_address(struct net_device *dev, void *p)
 {
-       volatile fec_t *fecp;
+       struct fec_enet_private *fep = netdev_priv(dev);
+       struct sockaddr *addr = p;
 
-       fecp = ((struct fec_enet_private *)netdev_priv(dev))->hwp;
+       if (!is_valid_ether_addr(addr->sa_data))
+               return -EADDRNOTAVAIL;
 
-       /* Set station address. */
-       fecp->fec_addr_low = dev->dev_addr[3] | (dev->dev_addr[2] << 8) |
-               (dev->dev_addr[1] << 16) | (dev->dev_addr[0] << 24);
-       fecp->fec_addr_high = (dev->dev_addr[5] << 16) |
-               (dev->dev_addr[4] << 24);
+       memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
 
+       writel(dev->dev_addr[3] | (dev->dev_addr[2] << 8) |
+               (dev->dev_addr[1] << 16) | (dev->dev_addr[0] << 24),
+               fep->hwp + FEC_ADDR_LOW);
+       writel((dev->dev_addr[5] << 16) | (dev->dev_addr[4] << 24),
+               fep + FEC_ADDR_HIGH);
+       return 0;
 }
 
+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_validate_addr      = eth_validate_addr,
+       .ndo_tx_timeout         = fec_timeout,
+       .ndo_set_mac_address    = fec_set_mac_address,
+};
+
  /*
   * XXX:  We need to clean up on failure exits here.
   *
@@ -1672,17 +1655,13 @@ fec_set_mac_address(struct net_device *dev)
 int __init fec_enet_init(struct net_device *dev, int index)
 {
        struct fec_enet_private *fep = netdev_priv(dev);
-       unsigned long   mem_addr;
-       volatile cbd_t  *bdp;
-       cbd_t           *cbd_base;
-       volatile fec_t  *fecp;
-       int             i, j;
+       struct bufdesc *cbd_base;
+       int i;
 
-       /* Allocate memory for buffer descriptors.
-       */
-       mem_addr = (unsigned long)dma_alloc_coherent(NULL, PAGE_SIZE,
-                       &fep->bd_dma, GFP_KERNEL);
-       if (mem_addr == 0) {
+       /* Allocate memory for buffer descriptors. */
+       cbd_base = dma_alloc_coherent(NULL, PAGE_SIZE, &fep->bd_dma,
+                       GFP_KERNEL);
+       if (!cbd_base) {
                printk("FEC: allocate descriptor memory failed?\n");
                return -ENOMEM;
        }
@@ -1690,146 +1669,47 @@ int __init fec_enet_init(struct net_device *dev, int index)
        spin_lock_init(&fep->hw_lock);
        spin_lock_init(&fep->mii_lock);
 
-       /* Create an Ethernet device instance.
-       */
-       fecp = (volatile fec_t *)dev->base_addr;
-
        fep->index = index;
-       fep->hwp = fecp;
+       fep->hwp = (void __iomem *)dev->base_addr;
        fep->netdev = dev;
 
-       /* Whack a reset.  We should wait for this.
-       */
-       fecp->fec_ecntrl = 1;
-       udelay(10);
-
        /* Set the Ethernet address */
 #ifdef CONFIG_M5272
        fec_get_mac(dev);
 #else
        {
                unsigned long l;
-               l = fecp->fec_addr_low;
+               l = readl(fep->hwp + FEC_ADDR_LOW);
                dev->dev_addr[0] = (unsigned char)((l & 0xFF000000) >> 24);
                dev->dev_addr[1] = (unsigned char)((l & 0x00FF0000) >> 16);
                dev->dev_addr[2] = (unsigned char)((l & 0x0000FF00) >> 8);
                dev->dev_addr[3] = (unsigned char)((l & 0x000000FF) >> 0);
-               l = fecp->fec_addr_high;
+               l = readl(fep->hwp + FEC_ADDR_HIGH);
                dev->dev_addr[4] = (unsigned char)((l & 0xFF000000) >> 24);
                dev->dev_addr[5] = (unsigned char)((l & 0x00FF0000) >> 16);
        }
 #endif
 
-       cbd_base = (cbd_t *)mem_addr;
-
-       /* Set receive and transmit descriptor base.
-       */
+       /* Set receive and transmit descriptor base. */
        fep->rx_bd_base = cbd_base;
        fep->tx_bd_base = cbd_base + RX_RING_SIZE;
 
-       fep->dirty_tx = fep->cur_tx = fep->tx_bd_base;
-       fep->cur_rx = fep->rx_bd_base;
-
-       fep->skb_cur = fep->skb_dirty = 0;
-
-       /* Initialize the receive buffer descriptors.
-       */
-       bdp = fep->rx_bd_base;
-       for (i=0; i<FEC_ENET_RX_PAGES; i++) {
-
-               /* Allocate a page.
-               */
-               mem_addr = __get_free_page(GFP_KERNEL);
-               /* XXX: missing check for allocation failure */
-
-               /* Initialize the BD for every fragment in the page.
-               */
-               for (j=0; j<FEC_ENET_RX_FRPPG; j++) {
-                       bdp->cbd_sc = BD_ENET_RX_EMPTY;
-                       bdp->cbd_bufaddr = __pa(mem_addr);
-                       mem_addr += FEC_ENET_RX_FRSIZE;
-                       bdp++;
-               }
-       }
-
-       /* Set the last buffer to wrap.
-       */
-       bdp--;
-       bdp->cbd_sc |= BD_SC_WRAP;
-
-       /* ...and the same for transmmit.
-       */
-       bdp = fep->tx_bd_base;
-       for (i=0, j=FEC_ENET_TX_FRPPG; i<TX_RING_SIZE; i++) {
-               if (j >= FEC_ENET_TX_FRPPG) {
-                       mem_addr = __get_free_page(GFP_KERNEL);
-                       j = 1;
-               } else {
-                       mem_addr += FEC_ENET_TX_FRSIZE;
-                       j++;
-               }
-               fep->tx_bounce[i] = (unsigned char *) mem_addr;
-
-               /* Initialize the BD for every fragment in the page.
-               */
-               bdp->cbd_sc = 0;
-               bdp->cbd_bufaddr = 0;
-               bdp++;
-       }
-
-       /* Set the last buffer to wrap.
-       */
-       bdp--;
-       bdp->cbd_sc |= BD_SC_WRAP;
-
-       /* Set receive and transmit descriptor base.
-       */
-       fecp->fec_r_des_start = fep->bd_dma;
-       fecp->fec_x_des_start = (unsigned long)fep->bd_dma + sizeof(cbd_t)
-                               * RX_RING_SIZE;
-
 #ifdef HAVE_mii_link_interrupt
        fec_request_mii_intr(dev);
 #endif
-
-       fecp->fec_grp_hash_table_high = 0;
-       fecp->fec_grp_hash_table_low = 0;
-       fecp->fec_r_buff_size = PKT_MAXBLR_SIZE;
-       fecp->fec_ecntrl = 2;
-       fecp->fec_r_des_active = 0;
-#ifndef CONFIG_M5272
-       fecp->fec_hash_table_high = 0;
-       fecp->fec_hash_table_low = 0;
-#endif
-
-       /* The FEC Ethernet specific entries in the device structure. */
-       dev->open = fec_enet_open;
-       dev->hard_start_xmit = fec_enet_start_xmit;
-       dev->tx_timeout = fec_timeout;
+       /* The FEC Ethernet specific entries in the device structure */
        dev->watchdog_timeo = TX_TIMEOUT;
-       dev->stop = fec_enet_close;
-       dev->set_multicast_list = set_multicast_list;
+       dev->netdev_ops = &fec_netdev_ops;
 
        for (i=0; i<NMII-1; i++)
                mii_cmds[i].mii_next = &mii_cmds[i+1];
        mii_free = mii_cmds;
 
-       /* setup MII interface */
-       fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x04;
-       fecp->fec_x_cntrl = 0x00;
-
-       /*
-        * Set MII speed to 2.5 MHz
-        */
+       /* Set MII speed to 2.5 MHz */
        fep->phy_speed = ((((clk_get_rate(fep->clk) / 2 + 4999999)
                                        / 2500000) / 2) & 0x3F) << 1;
-       fecp->fec_mii_speed = fep->phy_speed;
        fec_restart(dev, 0);
 
-       /* Clear and enable interrupts */
-       fecp->fec_ievent = 0xffc00000;
-       fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII);
-
        /* Queue up command to detect the PHY and initialize the
         * remainder of the interface.
         */
@@ -1847,145 +1727,118 @@ int __init fec_enet_init(struct net_device *dev, int index)
 static void
 fec_restart(struct net_device *dev, int duplex)
 {
-       struct fec_enet_private *fep;
-       volatile cbd_t *bdp;
-       volatile fec_t *fecp;
+       struct fec_enet_private *fep = netdev_priv(dev);
+       struct bufdesc *bdp;
        int i;
 
-       fep = netdev_priv(dev);
-       fecp = fep->hwp;
-
-       /* Whack a reset.  We should wait for this.
-       */
-       fecp->fec_ecntrl = 1;
+       /* Whack a reset.  We should wait for this. */
+       writel(1, fep->hwp + FEC_ECNTRL);
        udelay(10);
 
-       /* Clear any outstanding interrupt.
-       */
-       fecp->fec_ievent = 0xffc00000;
+       /* Clear any outstanding interrupt. */
+       writel(0xffc00000, fep->hwp + FEC_IEVENT);
 
-       /* Set station address.
-       */
-       fec_set_mac_address(dev);
+       /* Reset all multicast. */
+       writel(0, fep->hwp + FEC_GRP_HASH_TABLE_HIGH);
+       writel(0, fep->hwp + FEC_GRP_HASH_TABLE_LOW);
+#ifndef CONFIG_M5272
+       writel(0, fep->hwp + FEC_HASH_TABLE_HIGH);
+       writel(0, fep->hwp + FEC_HASH_TABLE_LOW);
+#endif
 
-       /* Reset all multicast.
-       */
-       fecp->fec_grp_hash_table_high = 0;
-       fecp->fec_grp_hash_table_low = 0;
+       /* Set maximum receive buffer size. */
+       writel(PKT_MAXBLR_SIZE, fep->hwp + FEC_R_BUFF_SIZE);
 
-       /* Set maximum receive buffer size.
-       */
-       fecp->fec_r_buff_size = PKT_MAXBLR_SIZE;
-
-       /* Set receive and transmit descriptor base.
-       */
-       fecp->fec_r_des_start = fep->bd_dma;
-       fecp->fec_x_des_start = (unsigned long)fep->bd_dma + sizeof(cbd_t)
-                               * RX_RING_SIZE;
+       /* Set receive and transmit descriptor base. */
+       writel(fep->bd_dma, fep->hwp + FEC_R_DES_START);
+       writel((unsigned long)fep->bd_dma + sizeof(struct bufdesc) * RX_RING_SIZE,
+                       fep->hwp + FEC_X_DES_START);
 
        fep->dirty_tx = fep->cur_tx = fep->tx_bd_base;
        fep->cur_rx = fep->rx_bd_base;
 
-       /* Reset SKB transmit buffers.
-       */
+       /* Reset SKB transmit buffers. */
        fep->skb_cur = fep->skb_dirty = 0;
-       for (i=0; i<=TX_RING_MOD_MASK; i++) {
-               if (fep->tx_skbuff[i] != NULL) {
+       for (i = 0; i <= TX_RING_MOD_MASK; i++) {
+               if (fep->tx_skbuff[i]) {
                        dev_kfree_skb_any(fep->tx_skbuff[i]);
                        fep->tx_skbuff[i] = NULL;
                }
        }
 
-       /* Initialize the receive buffer descriptors.
-       */
+       /* Initialize the receive buffer descriptors. */
        bdp = fep->rx_bd_base;
-       for (i=0; i<RX_RING_SIZE; i++) {
+       for (i = 0; i < RX_RING_SIZE; i++) {
 
-               /* Initialize the BD for every fragment in the page.
-               */
+               /* Initialize the BD for every fragment in the page. */
                bdp->cbd_sc = BD_ENET_RX_EMPTY;
                bdp++;
        }
 
-       /* Set the last buffer to wrap.
-       */
+       /* Set the last buffer to wrap */
        bdp--;
        bdp->cbd_sc |= BD_SC_WRAP;
 
-       /* ...and the same for transmmit.
-       */
+       /* ...and the same for transmit */
        bdp = fep->tx_bd_base;
-       for (i=0; i<TX_RING_SIZE; i++) {
+       for (i = 0; i < TX_RING_SIZE; i++) {
 
-               /* Initialize the BD for every fragment in the page.
-               */
+               /* Initialize the BD for every fragment in the page. */
                bdp->cbd_sc = 0;
                bdp->cbd_bufaddr = 0;
                bdp++;
        }
 
-       /* Set the last buffer to wrap.
-       */
+       /* Set the last buffer to wrap */
        bdp--;
        bdp->cbd_sc |= BD_SC_WRAP;
 
-       /* Enable MII mode.
-       */
+       /* Enable MII mode */
        if (duplex) {
-               fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x04;/* MII enable */
-               fecp->fec_x_cntrl = 0x04;                 /* FD enable */
+               /* MII enable / FD enable */
+               writel(OPT_FRAME_SIZE | 0x04, fep->hwp + FEC_R_CNTRL);
+               writel(0x04, fep->hwp + FEC_X_CNTRL);
        } else {
-               /* MII enable|No Rcv on Xmit */
-               fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x06;
-               fecp->fec_x_cntrl = 0x00;
+               /* MII enable / No Rcv on Xmit */
+               writel(OPT_FRAME_SIZE | 0x06, fep->hwp + FEC_R_CNTRL);
+               writel(0x0, fep->hwp + FEC_X_CNTRL);
        }
        fep->full_duplex = duplex;
 
-       /* Set MII speed.
-       */
-       fecp->fec_mii_speed = fep->phy_speed;
+       /* Set MII speed */
+       writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED);
 
-       /* And last, enable the transmit and receive processing.
-       */
-       fecp->fec_ecntrl = 2;
-       fecp->fec_r_des_active = 0;
+       /* And last, enable the transmit and receive processing */
+       writel(2, fep->hwp + FEC_ECNTRL);
+       writel(0, fep->hwp + FEC_R_DES_ACTIVE);
 
-       /* Enable interrupts we wish to service.
-       */
-       fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII);
+       /* Enable interrupts we wish to service */
+       writel(FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII,
+                       fep->hwp + FEC_IMASK);
 }
 
 static void
 fec_stop(struct net_device *dev)
 {
-       volatile fec_t *fecp;
-       struct fec_enet_private *fep;
-
-       fep = netdev_priv(dev);
-       fecp = fep->hwp;
+       struct fec_enet_private *fep = netdev_priv(dev);
 
-       /*
-       ** We cannot expect a graceful transmit stop without link !!!
-       */
-       if (fep->link)
-               {
-               fecp->fec_x_cntrl = 0x01;       /* Graceful transmit stop */
+       /* We cannot expect a graceful transmit stop without link !!! */
+       if (fep->link) {
+               writel(1, fep->hwp + FEC_X_CNTRL); /* Graceful transmit stop */
                udelay(10);
-               if (!(fecp->fec_ievent & FEC_ENET_GRA))
+               if (!(readl(fep->hwp + FEC_IEVENT) & FEC_ENET_GRA))
                        printk("fec_stop : Graceful transmit stop did not complete !\n");
-               }
+       }
 
-       /* Whack a reset.  We should wait for this.
-       */
-       fecp->fec_ecntrl = 1;
+       /* Whack a reset.  We should wait for this. */
+       writel(1, fep->hwp + FEC_ECNTRL);
        udelay(10);
 
-       /* Clear outstanding MII command interrupts.
-       */
-       fecp->fec_ievent = FEC_ENET_MII;
+       /* Clear outstanding MII command interrupts. */
+       writel(FEC_ENET_MII, fep->hwp + FEC_IEVENT);
 
-       fecp->fec_imask = FEC_ENET_MII;
-       fecp->fec_mii_speed = fep->phy_speed;
+       writel(FEC_ENET_MII, fep->hwp + FEC_IMASK);
+       writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED);
 }
 
 static int __devinit
index 76c64c92e190980ef5a5d8451412882e410ff722..30b7dd671336b45434bdefff08c137da3ee8bf9a 100644 (file)
  *     registers in the same peripheral device on different models
  *     of the ColdFire!
  */
-typedef struct fec {
-       unsigned long   fec_reserved0;
-       unsigned long   fec_ievent;             /* Interrupt event reg */
-       unsigned long   fec_imask;              /* Interrupt mask reg */
-       unsigned long   fec_reserved1;
-       unsigned long   fec_r_des_active;       /* Receive descriptor reg */
-       unsigned long   fec_x_des_active;       /* Transmit descriptor reg */
-       unsigned long   fec_reserved2[3];
-       unsigned long   fec_ecntrl;             /* Ethernet control reg */
-       unsigned long   fec_reserved3[6];
-       unsigned long   fec_mii_data;           /* MII manage frame reg */
-       unsigned long   fec_mii_speed;          /* MII speed control reg */
-       unsigned long   fec_reserved4[7];
-       unsigned long   fec_mib_ctrlstat;       /* MIB control/status reg */
-       unsigned long   fec_reserved5[7];
-       unsigned long   fec_r_cntrl;            /* Receive control reg */
-       unsigned long   fec_reserved6[15];
-       unsigned long   fec_x_cntrl;            /* Transmit Control reg */
-       unsigned long   fec_reserved7[7];
-       unsigned long   fec_addr_low;           /* Low 32bits MAC address */
-       unsigned long   fec_addr_high;          /* High 16bits MAC address */
-       unsigned long   fec_opd;                /* Opcode + Pause duration */
-       unsigned long   fec_reserved8[10];
-       unsigned long   fec_hash_table_high;    /* High 32bits hash table */
-       unsigned long   fec_hash_table_low;     /* Low 32bits hash table */
-       unsigned long   fec_grp_hash_table_high;/* High 32bits hash table */
-       unsigned long   fec_grp_hash_table_low; /* Low 32bits hash table */
-       unsigned long   fec_reserved9[7];
-       unsigned long   fec_x_wmrk;             /* FIFO transmit water mark */
-       unsigned long   fec_reserved10;
-       unsigned long   fec_r_bound;            /* FIFO receive bound reg */
-       unsigned long   fec_r_fstart;           /* FIFO receive start reg */
-       unsigned long   fec_reserved11[11];
-       unsigned long   fec_r_des_start;        /* Receive descriptor ring */
-       unsigned long   fec_x_des_start;        /* Transmit descriptor ring */
-       unsigned long   fec_r_buff_size;        /* Maximum receive buff size */
-} fec_t;
+#define FEC_IEVENT             0x004 /* Interrupt event reg */
+#define FEC_IMASK              0x008 /* Interrupt mask reg */
+#define FEC_R_DES_ACTIVE       0x010 /* Receive descriptor reg */
+#define FEC_X_DES_ACTIVE       0x014 /* Transmit descriptor reg */
+#define FEC_ECNTRL             0x024 /* Ethernet control reg */
+#define FEC_MII_DATA           0x040 /* MII manage frame reg */
+#define FEC_MII_SPEED          0x044 /* MII speed control reg */
+#define FEC_MIB_CTRLSTAT       0x064 /* MIB control/status reg */
+#define FEC_R_CNTRL            0x084 /* Receive control reg */
+#define FEC_X_CNTRL            0x0c4 /* Transmit Control reg */
+#define FEC_ADDR_LOW           0x0e4 /* Low 32bits MAC address */
+#define FEC_ADDR_HIGH          0x0e8 /* High 16bits MAC address */
+#define FEC_OPD                        0x0ec /* Opcode + Pause duration */
+#define FEC_HASH_TABLE_HIGH    0x118 /* High 32bits hash table */
+#define FEC_HASH_TABLE_LOW     0x11c /* Low 32bits hash table */
+#define FEC_GRP_HASH_TABLE_HIGH        0x120 /* High 32bits hash table */
+#define FEC_GRP_HASH_TABLE_LOW 0x124 /* Low 32bits hash table */
+#define FEC_X_WMRK             0x144 /* FIFO transmit water mark */
+#define FEC_R_BOUND            0x14c /* FIFO receive bound reg */
+#define FEC_R_FSTART           0x150 /* FIFO receive start reg */
+#define FEC_R_DES_START                0x180 /* Receive descriptor ring */
+#define FEC_X_DES_START                0x184 /* Transmit descriptor ring */
+#define FEC_R_BUFF_SIZE                0x188 /* Maximum receive buff size */
 
 #else
 
-/*
- *     Define device register set address map.
- */
-typedef struct fec {
-       unsigned long   fec_ecntrl;             /* Ethernet control reg */
-       unsigned long   fec_ievent;             /* Interrupt even reg */
-       unsigned long   fec_imask;              /* Interrupt mask reg */
-       unsigned long   fec_ivec;               /* Interrupt vec status reg */
-       unsigned long   fec_r_des_active;       /* Receive descriptor reg */
-       unsigned long   fec_x_des_active;       /* Transmit descriptor reg */
-       unsigned long   fec_reserved1[10];
-       unsigned long   fec_mii_data;           /* MII manage frame reg */
-       unsigned long   fec_mii_speed;          /* MII speed control reg */
-       unsigned long   fec_reserved2[17];
-       unsigned long   fec_r_bound;            /* FIFO receive bound reg */
-       unsigned long   fec_r_fstart;           /* FIFO receive start reg */
-       unsigned long   fec_reserved3[4];
-       unsigned long   fec_x_wmrk;             /* FIFO transmit water mark */
-       unsigned long   fec_reserved4;
-       unsigned long   fec_x_fstart;           /* FIFO transmit start reg */
-       unsigned long   fec_reserved5[21];
-       unsigned long   fec_r_cntrl;            /* Receive control reg */
-       unsigned long   fec_max_frm_len;        /* Maximum frame length reg */
-       unsigned long   fec_reserved6[14];
-       unsigned long   fec_x_cntrl;            /* Transmit Control reg */
-       unsigned long   fec_reserved7[158];
-       unsigned long   fec_addr_low;           /* Low 32bits MAC address */
-       unsigned long   fec_addr_high;          /* High 16bits MAC address */
-       unsigned long   fec_grp_hash_table_high;/* High 32bits hash table */
-       unsigned long   fec_grp_hash_table_low; /* Low 32bits hash table */
-       unsigned long   fec_r_des_start;        /* Receive descriptor ring */
-       unsigned long   fec_x_des_start;        /* Transmit descriptor ring */
-       unsigned long   fec_r_buff_size;        /* Maximum receive buff size */
-       unsigned long   reserved8[9];
-       unsigned long   fec_fifo_ram[112];      /* FIFO RAM buffer */
-} fec_t;
+#define FEC_ECNTRL;            0x000 /* Ethernet control reg */
+#define FEC_IEVENT;            0x004 /* Interrupt even reg */
+#define FEC_IMASK;             0x008 /* Interrupt mask reg */
+#define FEC_IVEC;              0x00c /* Interrupt vec status reg */
+#define FEC_R_DES_ACTIVE;      0x010 /* Receive descriptor reg */
+#define FEC_X_DES_ACTIVE;      0x01c /* Transmit descriptor reg */
+#define FEC_MII_DATA           0x040 /* MII manage frame reg */
+#define FEC_MII_SPEED          0x044 /* MII speed control reg */
+#define FEC_R_BOUND            0x08c /* FIFO receive bound reg */
+#define FEC_R_FSTART           0x090 /* FIFO receive start reg */
+#define FEC_X_WMRK             0x0a4 /* FIFO transmit water mark */
+#define FEC_X_FSTART           0x0ac /* FIFO transmit start reg */
+#define FEC_R_CNTRL            0x104 /* Receive control reg */
+#define FEC_MAX_FRM_LEN                0x108 /* Maximum frame length reg */
+#define FEC_X_CNTRL            0x144 /* Transmit Control reg */
+#define FEC_ADDR_LOW           0x3c0 /* Low 32bits MAC address */
+#define FEC_ADDR_HIGH          0x3c4 /* High 16bits MAC address */
+#define FEC_GRP_HASH_TABLE_HIGH        0x3c8 /* High 32bits hash table */
+#define FEC_GRP_HASH_TABLE_LOW 0x3cc /* Low 32bits hash table */
+#define FEC_R_DES_START                0x3d0 /* Receive descriptor ring */
+#define FEC_X_DES_START                0x3d4 /* Transmit descriptor ring */
+#define FEC_R_BUFF_SIZE                0x3d8 /* Maximum receive buff size */
+#define FEC_FIFO_RAM           0x400 /* FIFO RAM buffer */
 
 #endif /* CONFIG_M5272 */
 
@@ -104,17 +77,17 @@ typedef struct fec {
  *     Define the buffer descriptor structure.
  */
 #ifdef CONFIG_ARCH_MXC
-typedef struct bufdesc {
+struct bufdesc {
        unsigned short cbd_datlen;      /* Data length */
        unsigned short cbd_sc;  /* Control and status info */
        unsigned long cbd_bufaddr;      /* Buffer address */
-} cbd_t;
+};
 #else
-typedef struct bufdesc {
+struct bufdesc {
        unsigned short  cbd_sc;                 /* Control and status info */
        unsigned short  cbd_datlen;             /* Data length */
        unsigned long   cbd_bufaddr;            /* Buffer address */
-} cbd_t;
+};
 #endif
 
 /*
index 8bbe7f6179949c30b167d82cb2236394af9332c4..7d443405bbe271e6ea47220775e5d42d4955414c 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/hardirq.h>
 #include <linux/delay.h>
 #include <linux/of_device.h>
+#include <linux/of_mdio.h>
 #include <linux/of_platform.h>
 
 #include <linux/netdevice.h>
 
 #define DRIVER_NAME "mpc52xx-fec"
 
-#define FEC5200_PHYADDR_NONE   (-1)
-#define FEC5200_PHYADDR_7WIRE  (-2)
-
 /* Private driver data structure */
 struct mpc52xx_fec_priv {
+       struct net_device *ndev;
        int duplex;
        int speed;
        int r_irq;
@@ -59,10 +58,11 @@ struct mpc52xx_fec_priv {
        int msg_enable;
 
        /* MDIO link details */
-       int phy_addr;
-       unsigned int phy_speed;
+       unsigned int mdio_speed;
+       struct device_node *phy_node;
        struct phy_device *phydev;
        enum phy_state link;
+       int seven_wire_mode;
 };
 
 
@@ -211,85 +211,25 @@ static void mpc52xx_fec_adjust_link(struct net_device *dev)
                phy_print_status(phydev);
 }
 
-static int mpc52xx_fec_init_phy(struct net_device *dev)
-{
-       struct mpc52xx_fec_priv *priv = netdev_priv(dev);
-       struct phy_device *phydev;
-       char phy_id[BUS_ID_SIZE];
-
-       snprintf(phy_id, sizeof(phy_id), "%x:%02x",
-                       (unsigned int)dev->base_addr, priv->phy_addr);
-
-       priv->link = PHY_DOWN;
-       priv->speed = 0;
-       priv->duplex = -1;
-
-       phydev = phy_connect(dev, phy_id, &mpc52xx_fec_adjust_link, 0, PHY_INTERFACE_MODE_MII);
-       if (IS_ERR(phydev)) {
-               dev_err(&dev->dev, "phy_connect failed\n");
-               return PTR_ERR(phydev);
-       }
-       dev_info(&dev->dev, "attached phy %i to driver %s\n",
-                       phydev->addr, phydev->drv->name);
-
-       priv->phydev = phydev;
-
-       return 0;
-}
-
-static int mpc52xx_fec_phy_start(struct net_device *dev)
-{
-       struct mpc52xx_fec_priv *priv = netdev_priv(dev);
-       int err;
-
-       if (priv->phy_addr < 0)
-               return 0;
-
-       err = mpc52xx_fec_init_phy(dev);
-       if (err) {
-               dev_err(&dev->dev, "mpc52xx_fec_init_phy failed\n");
-               return err;
-       }
-
-       /* reset phy - this also wakes it from PDOWN */
-       phy_write(priv->phydev, MII_BMCR, BMCR_RESET);
-       phy_start(priv->phydev);
-
-       return 0;
-}
-
-static void mpc52xx_fec_phy_stop(struct net_device *dev)
-{
-       struct mpc52xx_fec_priv *priv = netdev_priv(dev);
-
-       if (!priv->phydev)
-               return;
-
-       phy_disconnect(priv->phydev);
-       /* power down phy */
-       phy_stop(priv->phydev);
-       phy_write(priv->phydev, MII_BMCR, BMCR_PDOWN);
-}
-
-static void mpc52xx_fec_phy_hw_init(struct mpc52xx_fec_priv *priv)
-{
-       struct mpc52xx_fec __iomem *fec = priv->fec;
-
-       if (priv->phydev)
-               return;
-
-       out_be32(&fec->mii_speed, priv->phy_speed);
-}
-
 static int mpc52xx_fec_open(struct net_device *dev)
 {
        struct mpc52xx_fec_priv *priv = netdev_priv(dev);
        int err = -EBUSY;
 
+       if (priv->phy_node) {
+               priv->phydev = of_phy_connect(priv->ndev, priv->phy_node,
+                                             mpc52xx_fec_adjust_link, 0, 0);
+               if (!priv->phydev) {
+                       dev_err(&dev->dev, "of_phy_connect failed\n");
+                       return -ENODEV;
+               }
+               phy_start(priv->phydev);
+       }
+
        if (request_irq(dev->irq, &mpc52xx_fec_interrupt, IRQF_SHARED,
                        DRIVER_NAME "_ctrl", dev)) {
                dev_err(&dev->dev, "ctrl interrupt request failed\n");
-               goto out;
+               goto free_phy;
        }
        if (request_irq(priv->r_irq, &mpc52xx_fec_rx_interrupt, 0,
                        DRIVER_NAME "_rx", dev)) {
@@ -311,10 +251,6 @@ static int mpc52xx_fec_open(struct net_device *dev)
                goto free_irqs;
        }
 
-       err = mpc52xx_fec_phy_start(dev);
-       if (err)
-               goto free_skbs;
-
        bcom_enable(priv->rx_dmatsk);
        bcom_enable(priv->tx_dmatsk);
 
@@ -324,16 +260,18 @@ static int mpc52xx_fec_open(struct net_device *dev)
 
        return 0;
 
- free_skbs:
-       mpc52xx_fec_free_rx_buffers(dev, priv->rx_dmatsk);
-
  free_irqs:
        free_irq(priv->t_irq, dev);
  free_2irqs:
        free_irq(priv->r_irq, dev);
  free_ctrl_irq:
        free_irq(dev->irq, dev);
- out:
+ free_phy:
+       if (priv->phydev) {
+               phy_stop(priv->phydev);
+               phy_disconnect(priv->phydev);
+               priv->phydev = NULL;
+       }
 
        return err;
 }
@@ -352,7 +290,12 @@ static int mpc52xx_fec_close(struct net_device *dev)
        free_irq(priv->r_irq, dev);
        free_irq(priv->t_irq, dev);
 
-       mpc52xx_fec_phy_stop(dev);
+       if (priv->phydev) {
+               /* power down phy */
+               phy_stop(priv->phydev);
+               phy_disconnect(priv->phydev);
+               priv->phydev = NULL;
+       }
 
        return 0;
 }
@@ -696,7 +639,7 @@ static void mpc52xx_fec_hw_init(struct net_device *dev)
        /* set phy speed.
         * this can't be done in phy driver, since it needs to be called
         * before fec stuff (even on resume) */
-       mpc52xx_fec_phy_hw_init(priv);
+       out_be32(&fec->mii_speed, priv->mdio_speed);
 }
 
 /**
@@ -732,7 +675,7 @@ static void mpc52xx_fec_start(struct net_device *dev)
        rcntrl = FEC_RX_BUFFER_SIZE << 16;      /* max frame length */
        rcntrl |= FEC_RCNTRL_FCE;
 
-       if (priv->phy_addr != FEC5200_PHYADDR_7WIRE)
+       if (!priv->seven_wire_mode)
                rcntrl |= FEC_RCNTRL_MII_MODE;
 
        if (priv->duplex == DUPLEX_FULL)
@@ -798,8 +741,6 @@ static void mpc52xx_fec_stop(struct net_device *dev)
 
        /* Stop FEC */
        out_be32(&fec->ecntrl, in_be32(&fec->ecntrl) & ~FEC_ECNTRL_ETHER_EN);
-
-       return;
 }
 
 /* reset fec and bestcomm tasks */
@@ -817,9 +758,11 @@ static void mpc52xx_fec_reset(struct net_device *dev)
 
        mpc52xx_fec_hw_init(dev);
 
-       phy_stop(priv->phydev);
-       phy_write(priv->phydev, MII_BMCR, BMCR_RESET);
-       phy_start(priv->phydev);
+       if (priv->phydev) {
+               phy_stop(priv->phydev);
+               phy_write(priv->phydev, MII_BMCR, BMCR_RESET);
+               phy_start(priv->phydev);
+       }
 
        bcom_fec_rx_reset(priv->rx_dmatsk);
        bcom_fec_tx_reset(priv->tx_dmatsk);
@@ -919,8 +862,6 @@ mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match)
        struct net_device *ndev;
        struct mpc52xx_fec_priv *priv = NULL;
        struct resource mem;
-       struct device_node *phy_node;
-       const phandle *phy_handle;
        const u32 *prop;
        int prop_size;
 
@@ -933,6 +874,7 @@ mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match)
                return -ENOMEM;
 
        priv = netdev_priv(ndev);
+       priv->ndev = ndev;
 
        /* Reserve FEC control zone */
        rv = of_address_to_resource(op->node, 0, &mem);
@@ -956,6 +898,7 @@ mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match)
        ndev->ethtool_ops       = &mpc52xx_fec_ethtool_ops;
        ndev->watchdog_timeo    = FEC_WATCHDOG_TIMEOUT;
        ndev->base_addr         = mem.start;
+       SET_NETDEV_DEV(ndev, &op->dev);
 
        spin_lock_init(&priv->lock);
 
@@ -1003,14 +946,9 @@ mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match)
         */
 
        /* Start with safe defaults for link connection */
-       priv->phy_addr = FEC5200_PHYADDR_NONE;
        priv->speed = 100;
        priv->duplex = DUPLEX_HALF;
-       priv->phy_speed = ((mpc52xx_find_ipb_freq(op->node) >> 20) / 5) << 1;
-
-       /* the 7-wire property means don't use MII mode */
-       if (of_find_property(op->node, "fsl,7-wire-mode", NULL))
-               priv->phy_addr = FEC5200_PHYADDR_7WIRE;
+       priv->mdio_speed = ((mpc52xx_find_ipb_freq(op->node) >> 20) / 5) << 1;
 
        /* The current speed preconfigures the speed of the MII link */
        prop = of_get_property(op->node, "current-speed", &prop_size);
@@ -1019,43 +957,23 @@ mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match)
                priv->duplex = prop[1] ? DUPLEX_FULL : DUPLEX_HALF;
        }
 
-       /* If there is a phy handle, setup link to that phy */
-       phy_handle = of_get_property(op->node, "phy-handle", &prop_size);
-       if (phy_handle && (prop_size >= sizeof(phandle))) {
-               phy_node = of_find_node_by_phandle(*phy_handle);
-               prop = of_get_property(phy_node, "reg", &prop_size);
-               if (prop && (prop_size >= sizeof(u32)))
-                       if ((*prop >= 0) && (*prop < PHY_MAX_ADDR))
-                               priv->phy_addr = *prop;
-               of_node_put(phy_node);
+       /* If there is a phy handle, then get the PHY node */
+       priv->phy_node = of_parse_phandle(op->node, "phy-handle", 0);
+
+       /* the 7-wire property means don't use MII mode */
+       if (of_find_property(op->node, "fsl,7-wire-mode", NULL)) {
+               priv->seven_wire_mode = 1;
+               dev_info(&ndev->dev, "using 7-wire PHY mode\n");
        }
 
        /* Hardware init */
        mpc52xx_fec_hw_init(ndev);
-
        mpc52xx_fec_reset_stats(ndev);
 
-       SET_NETDEV_DEV(ndev, &op->dev);
-
-       /* Register the new network device */
        rv = register_netdev(ndev);
        if (rv < 0)
                goto probe_error;
 
-       /* Now report the link setup */
-       switch (priv->phy_addr) {
-        case FEC5200_PHYADDR_NONE:
-               dev_info(&ndev->dev, "Fixed speed MII link: %i%cD\n",
-                        priv->speed, priv->duplex ? 'F' : 'H');
-               break;
-        case FEC5200_PHYADDR_7WIRE:
-               dev_info(&ndev->dev, "using 7-wire PHY mode\n");
-               break;
-        default:
-               dev_info(&ndev->dev, "Using PHY at MDIO address %i\n",
-                        priv->phy_addr);
-       }
-
        /* We're done ! */
        dev_set_drvdata(&op->dev, ndev);
 
@@ -1065,6 +983,10 @@ mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match)
        /* Error handling - free everything that might be allocated */
 probe_error:
 
+       if (priv->phy_node)
+               of_node_put(priv->phy_node);
+       priv->phy_node = NULL;
+
        irq_dispose_mapping(ndev->irq);
 
        if (priv->rx_dmatsk)
@@ -1093,6 +1015,10 @@ mpc52xx_fec_remove(struct of_device *op)
 
        unregister_netdev(ndev);
 
+       if (priv->phy_node)
+               of_node_put(priv->phy_node);
+       priv->phy_node = NULL;
+
        irq_dispose_mapping(ndev->irq);
 
        bcom_fec_rx_release(priv->rx_dmatsk);
index dd9bfa42ac348b3039c56d90dd6cab9f0c61fa50..fec9f245116b7824c2099ccdecf6d4e2b1597b23 100644 (file)
 #include <linux/netdevice.h>
 #include <linux/phy.h>
 #include <linux/of_platform.h>
+#include <linux/of_mdio.h>
 #include <asm/io.h>
 #include <asm/mpc52xx.h>
 #include "fec_mpc52xx.h"
 
 struct mpc52xx_fec_mdio_priv {
        struct mpc52xx_fec __iomem *regs;
+       int mdio_irqs[PHY_MAX_ADDR];
 };
 
 static int mpc52xx_fec_mdio_transfer(struct mii_bus *bus, int phy_id,
@@ -27,7 +29,7 @@ static int mpc52xx_fec_mdio_transfer(struct mii_bus *bus, int phy_id,
 {
        struct mpc52xx_fec_mdio_priv *priv = bus->priv;
        struct mpc52xx_fec __iomem *fec;
-       int tries = 100;
+       int tries = 3;
 
        value |= (phy_id << FEC_MII_DATA_PA_SHIFT) & FEC_MII_DATA_PA_MSK;
        value |= (reg << FEC_MII_DATA_RA_SHIFT) & FEC_MII_DATA_RA_MSK;
@@ -38,7 +40,7 @@ static int mpc52xx_fec_mdio_transfer(struct mii_bus *bus, int phy_id,
 
        /* wait for it to finish, this takes about 23 us on lite5200b */
        while (!(in_be32(&fec->ievent) & FEC_IEVENT_MII) && --tries)
-               udelay(5);
+               msleep(1);
 
        if (!tries)
                return -ETIMEDOUT;
@@ -64,7 +66,6 @@ static int mpc52xx_fec_mdio_probe(struct of_device *of,
 {
        struct device *dev = &of->dev;
        struct device_node *np = of->node;
-       struct device_node *child = NULL;
        struct mii_bus *bus;
        struct mpc52xx_fec_mdio_priv *priv;
        struct resource res = {};
@@ -85,22 +86,7 @@ static int mpc52xx_fec_mdio_probe(struct of_device *of,
        bus->write = mpc52xx_fec_mdio_write;
 
        /* setup irqs */
-       bus->irq = kmalloc(sizeof(bus->irq[0]) * PHY_MAX_ADDR, GFP_KERNEL);
-       if (bus->irq == NULL) {
-               err = -ENOMEM;
-               goto out_free;
-       }
-       for (i=0; i<PHY_MAX_ADDR; i++)
-               bus->irq[i] = PHY_POLL;
-
-       while ((child = of_get_next_child(np, child)) != NULL) {
-               int irq = irq_of_parse_and_map(child, 0);
-               if (irq != NO_IRQ) {
-                       const u32 *id = of_get_property(child, "reg", NULL);
-                       if (id)
-                               bus->irq[*id] = irq;
-               }
-       }
+       bus->irq = priv->mdio_irqs;
 
        /* setup registers */
        err = of_address_to_resource(np, 0, &res);
@@ -122,7 +108,7 @@ static int mpc52xx_fec_mdio_probe(struct of_device *of,
        out_be32(&priv->regs->mii_speed,
                ((mpc52xx_find_ipb_freq(of->node) >> 20) / 5) << 1);
 
-       err = mdiobus_register(bus);
+       err = of_mdiobus_register(bus, np);
        if (err)
                goto out_unmap;
 
index 9f6a68fb7b4573cb5ca5a91e9fb0bd2206927007..b60a3041b64ca981b54dd33fcfd95d4d806b333f 100644 (file)
  * Hardware access:
  */
 
-#define DEV_NEED_TIMERIRQ          0x000001  /* set the timer irq flag in the irq mask */
-#define DEV_NEED_LINKTIMER         0x000002  /* poll link settings. Relies on the timer irq */
-#define DEV_HAS_LARGEDESC          0x000004  /* device supports jumbo frames and needs packet format 2 */
-#define DEV_HAS_HIGH_DMA           0x000008  /* device supports 64bit dma */
-#define DEV_HAS_CHECKSUM           0x000010  /* device supports tx and rx checksum offloads */
-#define DEV_HAS_VLAN               0x000020  /* device supports vlan tagging and striping */
-#define DEV_HAS_MSI                0x000040  /* device supports MSI */
-#define DEV_HAS_MSI_X              0x000080  /* device supports MSI-X */
-#define DEV_HAS_POWER_CNTRL        0x000100  /* device supports power savings */
-#define DEV_HAS_STATISTICS_V1      0x000200  /* device supports hw statistics version 1 */
-#define DEV_HAS_STATISTICS_V2      0x000600  /* device supports hw statistics version 2 */
-#define DEV_HAS_STATISTICS_V3      0x000e00  /* device supports hw statistics version 3 */
-#define DEV_HAS_TEST_EXTENDED      0x001000  /* device supports extended diagnostic test */
-#define DEV_HAS_MGMT_UNIT          0x002000  /* device supports management unit */
-#define DEV_HAS_CORRECT_MACADDR    0x004000  /* device supports correct mac address order */
-#define DEV_HAS_COLLISION_FIX      0x008000  /* device supports tx collision fix */
-#define DEV_HAS_PAUSEFRAME_TX_V1   0x010000  /* device supports tx pause frames version 1 */
-#define DEV_HAS_PAUSEFRAME_TX_V2   0x020000  /* device supports tx pause frames version 2 */
-#define DEV_HAS_PAUSEFRAME_TX_V3   0x040000  /* device supports tx pause frames version 3 */
-#define DEV_NEED_TX_LIMIT          0x080000  /* device needs to limit tx */
-#define DEV_HAS_GEAR_MODE          0x100000  /* device supports gear mode */
+#define DEV_NEED_TIMERIRQ          0x0000001  /* set the timer irq flag in the irq mask */
+#define DEV_NEED_LINKTIMER         0x0000002  /* poll link settings. Relies on the timer irq */
+#define DEV_HAS_LARGEDESC          0x0000004  /* device supports jumbo frames and needs packet format 2 */
+#define DEV_HAS_HIGH_DMA           0x0000008  /* device supports 64bit dma */
+#define DEV_HAS_CHECKSUM           0x0000010  /* device supports tx and rx checksum offloads */
+#define DEV_HAS_VLAN               0x0000020  /* device supports vlan tagging and striping */
+#define DEV_HAS_MSI                0x0000040  /* device supports MSI */
+#define DEV_HAS_MSI_X              0x0000080  /* device supports MSI-X */
+#define DEV_HAS_POWER_CNTRL        0x0000100  /* device supports power savings */
+#define DEV_HAS_STATISTICS_V1      0x0000200  /* device supports hw statistics version 1 */
+#define DEV_HAS_STATISTICS_V2      0x0000600  /* device supports hw statistics version 2 */
+#define DEV_HAS_STATISTICS_V3      0x0000e00  /* device supports hw statistics version 3 */
+#define DEV_HAS_TEST_EXTENDED      0x0001000  /* device supports extended diagnostic test */
+#define DEV_HAS_MGMT_UNIT          0x0002000  /* device supports management unit */
+#define DEV_HAS_CORRECT_MACADDR    0x0004000  /* device supports correct mac address order */
+#define DEV_HAS_COLLISION_FIX      0x0008000  /* device supports tx collision fix */
+#define DEV_HAS_PAUSEFRAME_TX_V1   0x0010000  /* device supports tx pause frames version 1 */
+#define DEV_HAS_PAUSEFRAME_TX_V2   0x0020000  /* device supports tx pause frames version 2 */
+#define DEV_HAS_PAUSEFRAME_TX_V3   0x0040000  /* device supports tx pause frames version 3 */
+#define DEV_NEED_TX_LIMIT          0x0080000  /* device needs to limit tx */
+#define DEV_NEED_TX_LIMIT2         0x0180000  /* device needs to limit tx, expect for some revs */
+#define DEV_HAS_GEAR_MODE          0x0200000  /* device supports gear mode */
+#define DEV_NEED_PHY_INIT_FIX      0x0400000  /* device needs specific phy workaround */
+#define DEV_NEED_LOW_POWER_FIX     0x0800000  /* device needs special power up workaround */
+#define DEV_NEED_MSI_FIX           0x1000000  /* device needs msi workaround */
 
 enum {
        NvRegIrqStatus = 0x000,
@@ -343,6 +347,7 @@ enum {
 #define NVREG_POWERSTATE2_POWERUP_MASK         0x0F15
 #define NVREG_POWERSTATE2_POWERUP_REV_A3       0x0001
 #define NVREG_POWERSTATE2_PHY_RESET            0x0004
+#define NVREG_POWERSTATE2_GATE_CLOCKS          0x0F00
 };
 
 /* Big endian: should work, but is untested */
@@ -1023,6 +1028,23 @@ static int using_multi_irqs(struct net_device *dev)
                return 1;
 }
 
+static void nv_txrx_gate(struct net_device *dev, bool gate)
+{
+       struct fe_priv *np = get_nvpriv(dev);
+       u8 __iomem *base = get_hwbase(dev);
+       u32 powerstate;
+
+       if (!np->mac_in_use &&
+           (np->driver_data & DEV_HAS_POWER_CNTRL)) {
+               powerstate = readl(base + NvRegPowerState2);
+               if (gate)
+                       powerstate |= NVREG_POWERSTATE2_GATE_CLOCKS;
+               else
+                       powerstate &= ~NVREG_POWERSTATE2_GATE_CLOCKS;
+               writel(powerstate, base + NvRegPowerState2);
+       }
+}
+
 static void nv_enable_irq(struct net_device *dev)
 {
        struct fe_priv *np = get_nvpriv(dev);
@@ -1253,14 +1275,7 @@ static int phy_init(struct net_device *dev)
                        }
                }
                if (np->phy_model == PHY_MODEL_REALTEK_8201) {
-                       if (np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_32 ||
-                           np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_33 ||
-                           np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_34 ||
-                           np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_35 ||
-                           np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_36 ||
-                           np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_37 ||
-                           np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_38 ||
-                           np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_39) {
+                       if (np->driver_data & DEV_NEED_PHY_INIT_FIX) {
                                phy_reserved = mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG6, MII_READ);
                                phy_reserved |= PHY_REALTEK_INIT7;
                                if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG6, phy_reserved)) {
@@ -1451,14 +1466,7 @@ static int phy_init(struct net_device *dev)
                        }
                }
                if (np->phy_model == PHY_MODEL_REALTEK_8201) {
-                       if (np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_32 ||
-                           np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_33 ||
-                           np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_34 ||
-                           np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_35 ||
-                           np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_36 ||
-                           np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_37 ||
-                           np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_38 ||
-                           np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_39) {
+                       if (np->driver_data & DEV_NEED_PHY_INIT_FIX) {
                                phy_reserved = mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG6, MII_READ);
                                phy_reserved |= PHY_REALTEK_INIT7;
                                if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG6, phy_reserved)) {
@@ -3403,12 +3411,14 @@ static void nv_linkchange(struct net_device *dev)
                if (!netif_carrier_ok(dev)) {
                        netif_carrier_on(dev);
                        printk(KERN_INFO "%s: link up.\n", dev->name);
+                       nv_txrx_gate(dev, false);
                        nv_start_rx(dev);
                }
        } else {
                if (netif_carrier_ok(dev)) {
                        netif_carrier_off(dev);
                        printk(KERN_INFO "%s: link down.\n", dev->name);
+                       nv_txrx_gate(dev, true);
                        nv_stop_rx(dev);
                }
        }
@@ -5336,6 +5346,7 @@ static int nv_open(struct net_device *dev)
        mii_rw(dev, np->phyaddr, MII_BMCR,
               mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ) & ~BMCR_PDOWN);
 
+       nv_txrx_gate(dev, false);
        /* erase previous misconfiguration */
        if (np->driver_data & DEV_HAS_POWER_CNTRL)
                nv_mac_reset(dev);
@@ -5523,12 +5534,14 @@ static int nv_close(struct net_device *dev)
        nv_drain_rxtx(dev);
 
        if (np->wolenabled || !phy_power_down) {
+               nv_txrx_gate(dev, false);
                writel(NVREG_PFF_ALWAYS|NVREG_PFF_MYADDR, base + NvRegPacketFilterFlags);
                nv_start_rx(dev);
        } else {
                /* power down phy */
                mii_rw(dev, np->phyaddr, MII_BMCR,
                       mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ)|BMCR_PDOWN);
+               nv_txrx_gate(dev, true);
        }
 
        /* FIXME: power down nic */
@@ -5821,8 +5834,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
                /* take phy and nic out of low power mode */
                powerstate = readl(base + NvRegPowerState2);
                powerstate &= ~NVREG_POWERSTATE2_POWERUP_MASK;
-               if ((id->device == PCI_DEVICE_ID_NVIDIA_NVENET_12 ||
-                    id->device == PCI_DEVICE_ID_NVIDIA_NVENET_13) &&
+               if ((id->driver_data & DEV_NEED_LOW_POWER_FIX) &&
                    pci_dev->revision >= 0xA3)
                        powerstate |= NVREG_POWERSTATE2_POWERUP_REV_A3;
                writel(powerstate, base + NvRegPowerState2);
@@ -5878,14 +5890,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
        /* Limit the number of tx's outstanding for hw bug */
        if (id->driver_data & DEV_NEED_TX_LIMIT) {
                np->tx_limit = 1;
-               if ((id->device == PCI_DEVICE_ID_NVIDIA_NVENET_32 ||
-                    id->device == PCI_DEVICE_ID_NVIDIA_NVENET_33 ||
-                    id->device == PCI_DEVICE_ID_NVIDIA_NVENET_34 ||
-                    id->device == PCI_DEVICE_ID_NVIDIA_NVENET_35 ||
-                    id->device == PCI_DEVICE_ID_NVIDIA_NVENET_36 ||
-                    id->device == PCI_DEVICE_ID_NVIDIA_NVENET_37 ||
-                    id->device == PCI_DEVICE_ID_NVIDIA_NVENET_38 ||
-                    id->device == PCI_DEVICE_ID_NVIDIA_NVENET_39) &&
+               if ((id->driver_data & DEV_NEED_TX_LIMIT2) &&
                    pci_dev->revision >= 0xA2)
                        np->tx_limit = 0;
        }
@@ -6135,7 +6140,8 @@ static int nv_resume(struct pci_dev *pdev)
        for (i = 0;i <= np->register_size/sizeof(u32); i++)
                writel(np->saved_config_space[i], base+i*sizeof(u32));
 
-       pci_write_config_dword(pdev, NV_MSI_PRIV_OFFSET, NV_MSI_PRIV_VALUE);
+       if (np->driver_data & DEV_NEED_MSI_FIX)
+               pci_write_config_dword(pdev, NV_MSI_PRIV_OFFSET, NV_MSI_PRIV_VALUE);
 
        /* restore phy state, including autoneg */
        phy_init(dev);
@@ -6184,160 +6190,164 @@ static void nv_shutdown(struct pci_dev *pdev)
 
 static struct pci_device_id pci_tbl[] = {
        {       /* nForce Ethernet Controller */
-               PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_1),
+               PCI_DEVICE(0x10DE, 0x01C3),
                .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER,
        },
        {       /* nForce2 Ethernet Controller */
-               PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_2),
+               PCI_DEVICE(0x10DE, 0x0066),
                .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER,
        },
        {       /* nForce3 Ethernet Controller */
-               PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_3),
+               PCI_DEVICE(0x10DE, 0x00D6),
                .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER,
        },
        {       /* nForce3 Ethernet Controller */
-               PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_4),
+               PCI_DEVICE(0x10DE, 0x0086),
                .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM,
        },
        {       /* nForce3 Ethernet Controller */
-               PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_5),
+               PCI_DEVICE(0x10DE, 0x008C),
                .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM,
        },
        {       /* nForce3 Ethernet Controller */
-               PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_6),
+               PCI_DEVICE(0x10DE, 0x00E6),
                .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM,
        },
        {       /* nForce3 Ethernet Controller */
-               PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_7),
+               PCI_DEVICE(0x10DE, 0x00DF),
                .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM,
        },
        {       /* CK804 Ethernet Controller */
-               PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_8),
+               PCI_DEVICE(0x10DE, 0x0056),
                .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_STATISTICS_V1|DEV_NEED_TX_LIMIT,
        },
        {       /* CK804 Ethernet Controller */
-               PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_9),
+               PCI_DEVICE(0x10DE, 0x0057),
                .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_STATISTICS_V1|DEV_NEED_TX_LIMIT,
        },
        {       /* MCP04 Ethernet Controller */
-               PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_10),
+               PCI_DEVICE(0x10DE, 0x0037),
                .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_STATISTICS_V1|DEV_NEED_TX_LIMIT,
        },
        {       /* MCP04 Ethernet Controller */
-               PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_11),
+               PCI_DEVICE(0x10DE, 0x0038),
                .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_STATISTICS_V1|DEV_NEED_TX_LIMIT,
        },
        {       /* MCP51 Ethernet Controller */
-               PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_12),
-               .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_STATISTICS_V1,
+               PCI_DEVICE(0x10DE, 0x0268),
+               .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_STATISTICS_V1|DEV_NEED_LOW_POWER_FIX,
        },
        {       /* MCP51 Ethernet Controller */
-               PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_13),
-               .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_STATISTICS_V1,
+               PCI_DEVICE(0x10DE, 0x0269),
+               .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_STATISTICS_V1|DEV_NEED_LOW_POWER_FIX,
        },
        {       /* MCP55 Ethernet Controller */
-               PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_14),
-               .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_NEED_TX_LIMIT,
+               PCI_DEVICE(0x10DE, 0x0372),
+               .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_NEED_TX_LIMIT|DEV_NEED_MSI_FIX,
        },
        {       /* MCP55 Ethernet Controller */
-               PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_15),
-               .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_NEED_TX_LIMIT,
+               PCI_DEVICE(0x10DE, 0x0373),
+               .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_NEED_TX_LIMIT|DEV_NEED_MSI_FIX,
        },
        {       /* MCP61 Ethernet Controller */
-               PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_16),
-               .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+               PCI_DEVICE(0x10DE, 0x03E5),
+               .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_MSI_FIX,
        },
        {       /* MCP61 Ethernet Controller */
-               PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_17),
-               .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+               PCI_DEVICE(0x10DE, 0x03E6),
+               .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_MSI_FIX,
        },
        {       /* MCP61 Ethernet Controller */
-               PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_18),
-               .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+               PCI_DEVICE(0x10DE, 0x03EE),
+               .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_MSI_FIX,
        },
        {       /* MCP61 Ethernet Controller */
-               PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_19),
-               .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+               PCI_DEVICE(0x10DE, 0x03EF),
+               .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_MSI_FIX,
        },
        {       /* MCP65 Ethernet Controller */
-               PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_20),
-               .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
+               PCI_DEVICE(0x10DE, 0x0450),
+               .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE|DEV_NEED_MSI_FIX,
        },
        {       /* MCP65 Ethernet Controller */
-               PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_21),
-               .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
+               PCI_DEVICE(0x10DE, 0x0451),
+               .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE|DEV_NEED_MSI_FIX,
        },
        {       /* MCP65 Ethernet Controller */
-               PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_22),
-               .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
+               PCI_DEVICE(0x10DE, 0x0452),
+               .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE|DEV_NEED_MSI_FIX,
        },
        {       /* MCP65 Ethernet Controller */
-               PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_23),
-               .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
+               PCI_DEVICE(0x10DE, 0x0453),
+               .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE|DEV_NEED_MSI_FIX,
        },
        {       /* MCP67 Ethernet Controller */
-               PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_24),
-               .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_GEAR_MODE,
+               PCI_DEVICE(0x10DE, 0x054C),
+               .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_GEAR_MODE|DEV_NEED_MSI_FIX,
        },
        {       /* MCP67 Ethernet Controller */
-               PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_25),
-               .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_GEAR_MODE,
+               PCI_DEVICE(0x10DE, 0x054D),
+               .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_GEAR_MODE|DEV_NEED_MSI_FIX,
        },
        {       /* MCP67 Ethernet Controller */
-               PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_26),
-               .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_GEAR_MODE,
+               PCI_DEVICE(0x10DE, 0x054E),
+               .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_GEAR_MODE|DEV_NEED_MSI_FIX,
        },
        {       /* MCP67 Ethernet Controller */
-               PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_27),
-               .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_GEAR_MODE,
+               PCI_DEVICE(0x10DE, 0x054F),
+               .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_GEAR_MODE|DEV_NEED_MSI_FIX,
        },
        {       /* MCP73 Ethernet Controller */
-               PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_28),
-               .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_HAS_GEAR_MODE,
+               PCI_DEVICE(0x10DE, 0x07DC),
+               .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_HAS_GEAR_MODE|DEV_NEED_MSI_FIX,
        },
        {       /* MCP73 Ethernet Controller */
-               PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_29),
-               .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_HAS_GEAR_MODE,
+               PCI_DEVICE(0x10DE, 0x07DD),
+               .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_HAS_GEAR_MODE|DEV_NEED_MSI_FIX,
        },
        {       /* MCP73 Ethernet Controller */
-               PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_30),
-               .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_HAS_GEAR_MODE,
+               PCI_DEVICE(0x10DE, 0x07DE),
+               .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_HAS_GEAR_MODE|DEV_NEED_MSI_FIX,
        },
        {       /* MCP73 Ethernet Controller */
-               PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_31),
-               .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_HAS_GEAR_MODE,
+               PCI_DEVICE(0x10DE, 0x07DF),
+               .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_HAS_GEAR_MODE|DEV_NEED_MSI_FIX,
        },
        {       /* MCP77 Ethernet Controller */
-               PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_32),
-               .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
+               PCI_DEVICE(0x10DE, 0x0760),
+               .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT2|DEV_HAS_GEAR_MODE|DEV_NEED_PHY_INIT_FIX|DEV_NEED_MSI_FIX,
        },
        {       /* MCP77 Ethernet Controller */
-               PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_33),
-               .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
+               PCI_DEVICE(0x10DE, 0x0761),
+               .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT2|DEV_HAS_GEAR_MODE|DEV_NEED_PHY_INIT_FIX|DEV_NEED_MSI_FIX,
        },
        {       /* MCP77 Ethernet Controller */
-               PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_34),
-               .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
+               PCI_DEVICE(0x10DE, 0x0762),
+               .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT2|DEV_HAS_GEAR_MODE|DEV_NEED_PHY_INIT_FIX|DEV_NEED_MSI_FIX,
        },
        {       /* MCP77 Ethernet Controller */
-               PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_35),
-               .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
+               PCI_DEVICE(0x10DE, 0x0763),
+               .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT2|DEV_HAS_GEAR_MODE|DEV_NEED_PHY_INIT_FIX|DEV_NEED_MSI_FIX,
        },
        {       /* MCP79 Ethernet Controller */
-               PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_36),
-               .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
+               PCI_DEVICE(0x10DE, 0x0AB0),
+               .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT2|DEV_HAS_GEAR_MODE|DEV_NEED_PHY_INIT_FIX|DEV_NEED_MSI_FIX,
        },
        {       /* MCP79 Ethernet Controller */
-               PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_37),
-               .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
+               PCI_DEVICE(0x10DE, 0x0AB1),
+               .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT2|DEV_HAS_GEAR_MODE|DEV_NEED_PHY_INIT_FIX|DEV_NEED_MSI_FIX,
        },
        {       /* MCP79 Ethernet Controller */
-               PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_38),
-               .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
+               PCI_DEVICE(0x10DE, 0x0AB2),
+               .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT2|DEV_HAS_GEAR_MODE|DEV_NEED_PHY_INIT_FIX|DEV_NEED_MSI_FIX,
        },
        {       /* MCP79 Ethernet Controller */
-               PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_39),
-               .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
+               PCI_DEVICE(0x10DE, 0x0AB3),
+               .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT2|DEV_HAS_GEAR_MODE|DEV_NEED_PHY_INIT_FIX|DEV_NEED_MSI_FIX,
+       },
+       {       /* MCP89 Ethernet Controller */
+               PCI_DEVICE(0x10DE, 0x0D7D),
+               .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_HAS_GEAR_MODE|DEV_NEED_PHY_INIT_FIX,
        },
        {0,},
 };
index a9cbc3191a2a1354942e56396e2c39b8e712ec1c..b892c3ad9a742de2957dd5b1a0c14be158d52b8c 100644 (file)
@@ -36,6 +36,8 @@
 #include <linux/fs.h>
 #include <linux/platform_device.h>
 #include <linux/phy.h>
+#include <linux/of.h>
+#include <linux/of_mdio.h>
 #include <linux/of_platform.h>
 #include <linux/of_gpio.h>
 
@@ -752,9 +754,10 @@ static int fs_init_phy(struct net_device *dev)
        fep->oldlink = 0;
        fep->oldspeed = 0;
        fep->oldduplex = -1;
-       if(fep->fpi->bus_id)
-               phydev = phy_connect(dev, fep->fpi->bus_id, &fs_adjust_link, 0,
-                               PHY_INTERFACE_MODE_MII);
+       if(fep->fpi->phy_node)
+               phydev = of_phy_connect(dev, fep->fpi->phy_node,
+                                       &fs_adjust_link, 0,
+                                       PHY_INTERFACE_MODE_MII);
        else {
                printk("No phy bus ID specified in BSP code\n");
                return -EINVAL;
@@ -938,81 +941,6 @@ extern void fs_mii_disconnect(struct net_device *dev);
 
 /**************************************************************************************/
 
-/* handy pointer to the immap */
-void __iomem *fs_enet_immap = NULL;
-
-static int setup_immap(void)
-{
-#ifdef CONFIG_CPM1
-       fs_enet_immap = ioremap(IMAP_ADDR, 0x4000);
-       WARN_ON(!fs_enet_immap);
-#elif defined(CONFIG_CPM2)
-       fs_enet_immap = cpm2_immr;
-#endif
-
-       return 0;
-}
-
-static void cleanup_immap(void)
-{
-#if defined(CONFIG_CPM1)
-       iounmap(fs_enet_immap);
-#endif
-}
-
-/**************************************************************************************/
-
-static int __devinit find_phy(struct device_node *np,
-                              struct fs_platform_info *fpi)
-{
-       struct device_node *phynode, *mdionode;
-       int ret = 0, len, bus_id;
-       const u32 *data;
-
-       data  = of_get_property(np, "fixed-link", NULL);
-       if (data) {
-               snprintf(fpi->bus_id, 16, "%x:%02x", 0, *data);
-               return 0;
-       }
-
-       data = of_get_property(np, "phy-handle", &len);
-       if (!data || len != 4)
-               return -EINVAL;
-
-       phynode = of_find_node_by_phandle(*data);
-       if (!phynode)
-               return -EINVAL;
-
-       data = of_get_property(phynode, "reg", &len);
-       if (!data || len != 4) {
-               ret = -EINVAL;
-               goto out_put_phy;
-       }
-
-       mdionode = of_get_parent(phynode);
-       if (!mdionode) {
-               ret = -EINVAL;
-               goto out_put_phy;
-       }
-
-       bus_id = of_get_gpio(mdionode, 0);
-       if (bus_id < 0) {
-               struct resource res;
-               ret = of_address_to_resource(mdionode, 0, &res);
-               if (ret)
-                       goto out_put_mdio;
-               bus_id = res.start;
-       }
-
-       snprintf(fpi->bus_id, 16, "%x:%02x", bus_id, *data);
-
-out_put_mdio:
-       of_node_put(mdionode);
-out_put_phy:
-       of_node_put(phynode);
-       return ret;
-}
-
 #ifdef CONFIG_FS_ENET_HAS_FEC
 #define IS_FEC(match) ((match)->data == &fs_fec_ops)
 #else
@@ -1062,9 +990,9 @@ static int __devinit fs_enet_probe(struct of_device *ofdev,
        fpi->rx_copybreak = 240;
        fpi->use_napi = 1;
        fpi->napi_weight = 17;
-
-       ret = find_phy(ofdev->node, fpi);
-       if (ret)
+       fpi->phy_node = of_parse_phandle(ofdev->node, "phy-handle", 0);
+       if ((!fpi->phy_node) && (!of_get_property(ofdev->node, "fixed-link",
+                                                 NULL)))
                goto out_free_fpi;
 
        privsize = sizeof(*fep) +
@@ -1136,6 +1064,7 @@ out_cleanup_data:
 out_free_dev:
        free_netdev(ndev);
        dev_set_drvdata(&ofdev->dev, NULL);
+       of_node_put(fpi->phy_node);
 out_free_fpi:
        kfree(fpi);
        return ret;
@@ -1151,7 +1080,7 @@ static int fs_enet_remove(struct of_device *ofdev)
        fep->ops->free_bd(ndev);
        fep->ops->cleanup_data(ndev);
        dev_set_drvdata(fep->dev, NULL);
-
+       of_node_put(fep->fpi->phy_node);
        free_netdev(ndev);
        return 0;
 }
@@ -1191,25 +1120,12 @@ static struct of_platform_driver fs_enet_driver = {
 
 static int __init fs_init(void)
 {
-       int r = setup_immap();
-       if (r != 0)
-               return r;
-
-       r = of_register_platform_driver(&fs_enet_driver);
-       if (r != 0)
-               goto out;
-
-       return 0;
-
-out:
-       cleanup_immap();
-       return r;
+       return of_register_platform_driver(&fs_enet_driver);
 }
 
 static void __exit fs_cleanup(void)
 {
        of_unregister_platform_driver(&fs_enet_driver);
-       cleanup_immap();
 }
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
index 85a4bab7f6308a686df71a5f89bba96385419461..ef01e09781a5f0f6de84d59d0f5f2eca548e8ed2 100644 (file)
@@ -194,9 +194,4 @@ extern const struct fs_ops fs_scc_ops;
 
 /*******************************************************************/
 
-/* handy pointer to the immap */
-extern void __iomem *fs_enet_immap;
-
-/*******************************************************************/
-
 #endif
index 14e575313c89c85c9573a85359368e0e320725a5..ca7bcb8ab3a1060997c6061d098d19baf3fcdda6 100644 (file)
@@ -245,10 +245,6 @@ static void set_multicast_list(struct net_device *dev)
 
 static void restart(struct net_device *dev)
 {
-#ifdef CONFIG_DUET
-       immap_t *immap = fs_enet_immap;
-       u32 cptr;
-#endif
        struct fs_enet_private *fep = netdev_priv(dev);
        fec_t __iomem *fecp = fep->fec.fecp;
        const struct fs_platform_info *fpi = fep->fpi;
@@ -315,36 +311,6 @@ static void restart(struct net_device *dev)
        FW(fecp, ievent, 0xffc0);
        FW(fecp, ivec, (virq_to_hw(fep->interrupt) / 2) << 29);
 
-       /*
-        * adjust to speed (only for DUET & RMII)
-        */
-#ifdef CONFIG_DUET
-       if (fpi->use_rmii) {
-               cptr = in_be32(&immap->im_cpm.cp_cptr);
-               switch (fs_get_fec_index(fpi->fs_no)) {
-               case 0:
-                       cptr |= 0x100;
-                       if (fep->speed == 10)
-                               cptr |= 0x0000010;
-                       else if (fep->speed == 100)
-                               cptr &= ~0x0000010;
-                       break;
-               case 1:
-                       cptr |= 0x80;
-                       if (fep->speed == 10)
-                               cptr |= 0x0000008;
-                       else if (fep->speed == 100)
-                               cptr &= ~0x0000008;
-                       break;
-               default:
-                       BUG();  /* should never happen */
-                       break;
-               }
-               out_be32(&immap->im_cpm.cp_cptr, cptr);
-       }
-#endif
-
-
        FW(fecp, r_cntrl, FEC_RCNTRL_MII_MODE); /* MII enable */
        /*
         * adjust to duplex mode
index 49b6645d7e0cb4bd8cc8bddcd1667ded1b3588af..93b481b0e3c7faf7bec15bae910d090478be4efa 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/mii.h>
 #include <linux/platform_device.h>
 #include <linux/mdio-bitbang.h>
+#include <linux/of_mdio.h>
 #include <linux/of_platform.h>
 
 #include "fs_enet.h"
@@ -149,31 +150,12 @@ static int __devinit fs_mii_bitbang_init(struct mii_bus *bus,
        return 0;
 }
 
-static void __devinit add_phy(struct mii_bus *bus, struct device_node *np)
-{
-       const u32 *data;
-       int len, id, irq;
-
-       data = of_get_property(np, "reg", &len);
-       if (!data || len != 4)
-               return;
-
-       id = *data;
-       bus->phy_mask &= ~(1 << id);
-
-       irq = of_irq_to_resource(np, 0, NULL);
-       if (irq != NO_IRQ)
-               bus->irq[id] = irq;
-}
-
 static int __devinit fs_enet_mdio_probe(struct of_device *ofdev,
                                         const struct of_device_id *match)
 {
-       struct device_node *np = NULL;
        struct mii_bus *new_bus;
        struct bb_info *bitbang;
        int ret = -ENOMEM;
-       int i;
 
        bitbang = kzalloc(sizeof(struct bb_info), GFP_KERNEL);
        if (!bitbang)
@@ -196,17 +178,10 @@ static int __devinit fs_enet_mdio_probe(struct of_device *ofdev,
        if (!new_bus->irq)
                goto out_unmap_regs;
 
-       for (i = 0; i < PHY_MAX_ADDR; i++)
-               new_bus->irq[i] = -1;
-
-       while ((np = of_get_next_child(ofdev->node, np)))
-               if (!strcmp(np->type, "ethernet-phy"))
-                       add_phy(new_bus, np);
-
        new_bus->parent = &ofdev->dev;
        dev_set_drvdata(&ofdev->dev, new_bus);
 
-       ret = mdiobus_register(new_bus);
+       ret = of_mdiobus_register(new_bus, ofdev->node);
        if (ret)
                goto out_free_irqs;
 
index 28077cc1b9498e21932fd174e516cb303df95174..75a09994d6655a7b0e83c619a46de23d03d15ba1 100644 (file)
@@ -54,8 +54,7 @@ static int fs_enet_fec_mii_read(struct mii_bus *bus , int phy_id, int location)
        fec_t __iomem *fecp = fec->fecp;
        int i, ret = -1;
 
-       if ((in_be32(&fecp->fec_r_cntrl) & FEC_RCNTRL_MII_MODE) == 0)
-               BUG();
+       BUG_ON((in_be32(&fecp->fec_r_cntrl) & FEC_RCNTRL_MII_MODE) == 0);
 
        /* Add PHY address to register command.  */
        out_be32(&fecp->fec_mii_data, (phy_id << 23) | mk_mii_read(location));
@@ -79,8 +78,7 @@ static int fs_enet_fec_mii_write(struct mii_bus *bus, int phy_id, int location,
        int i;
 
        /* this must never happen */
-       if ((in_be32(&fecp->fec_r_cntrl) & FEC_RCNTRL_MII_MODE) == 0)
-               BUG();
+       BUG_ON((in_be32(&fecp->fec_r_cntrl) & FEC_RCNTRL_MII_MODE) == 0);
 
        /* Add PHY address to register command.  */
        out_be32(&fecp->fec_mii_data, (phy_id << 23) | mk_mii_write(location, val));
@@ -102,23 +100,6 @@ static int fs_enet_fec_mii_reset(struct mii_bus *bus)
        return 0;
 }
 
-static void __devinit add_phy(struct mii_bus *bus, struct device_node *np)
-{
-       const u32 *data;
-       int len, id, irq;
-
-       data = of_get_property(np, "reg", &len);
-       if (!data || len != 4)
-               return;
-
-       id = *data;
-       bus->phy_mask &= ~(1 << id);
-
-       irq = of_irq_to_resource(np, 0, NULL);
-       if (irq != NO_IRQ)
-               bus->irq[id] = irq;
-}
-
 static int __devinit fs_enet_mdio_probe(struct of_device *ofdev,
                                         const struct of_device_id *match)
 {
@@ -165,17 +146,10 @@ static int __devinit fs_enet_mdio_probe(struct of_device *ofdev,
        if (!new_bus->irq)
                goto out_unmap_regs;
 
-       for (i = 0; i < PHY_MAX_ADDR; i++)
-               new_bus->irq[i] = -1;
-
-       while ((np = of_get_next_child(ofdev->node, np)))
-               if (!strcmp(np->type, "ethernet-phy"))
-                       add_phy(new_bus, np);
-
        new_bus->parent = &ofdev->dev;
        dev_set_drvdata(&ofdev->dev, new_bus);
 
-       ret = mdiobus_register(new_bus);
+       ret = of_mdiobus_register(new_bus, ofdev->node);
        if (ret)
                goto out_free_irqs;
 
index aa1eb88c21fc725196f4ff084b073b41298a4aa3..3af581303ca2b79577d18d0df4d6c64b6d341152 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/mii.h>
 #include <linux/phy.h>
 #include <linux/of.h>
+#include <linux/of_mdio.h>
 #include <linux/of_platform.h>
 
 #include <asm/io.h>
@@ -154,44 +155,6 @@ static int fsl_pq_mdio_reset(struct mii_bus *bus)
        return 0;
 }
 
-/* Allocate an array which provides irq #s for each PHY on the given bus */
-static int *create_irq_map(struct device_node *np)
-{
-       int *irqs;
-       int i;
-       struct device_node *child = NULL;
-
-       irqs = kcalloc(PHY_MAX_ADDR, sizeof(int), GFP_KERNEL);
-
-       if (!irqs)
-               return NULL;
-
-       for (i = 0; i < PHY_MAX_ADDR; i++)
-               irqs[i] = PHY_POLL;
-
-       while ((child = of_get_next_child(np, child)) != NULL) {
-               int irq = irq_of_parse_and_map(child, 0);
-               const u32 *id;
-
-               if (irq == NO_IRQ)
-                       continue;
-
-               id = of_get_property(child, "reg", NULL);
-
-               if (!id)
-                       continue;
-
-               if (*id < PHY_MAX_ADDR && *id >= 0)
-                       irqs[*id] = irq;
-               else
-                       printk(KERN_WARNING "%s: "
-                                       "%d is not a valid PHY address\n",
-                                       np->full_name, *id);
-       }
-
-       return irqs;
-}
-
 void fsl_pq_mdio_bus_name(char *name, struct device_node *np)
 {
        const u32 *addr;
@@ -315,7 +278,7 @@ static int fsl_pq_mdio_probe(struct of_device *ofdev,
 
        new_bus->priv = (void __force *)regs;
 
-       new_bus->irq = create_irq_map(np);
+       new_bus->irq = kcalloc(PHY_MAX_ADDR, sizeof(int), GFP_KERNEL);
 
        if (NULL == new_bus->irq) {
                err = -ENOMEM;
@@ -338,13 +301,17 @@ static int fsl_pq_mdio_probe(struct of_device *ofdev,
                        of_device_is_compatible(np, "ucc_geth_phy")) {
 #ifdef CONFIG_UCC_GETH
                u32 id;
+               static u32 mii_mng_master;
 
                tbipa = &regs->utbipar;
 
                if ((err = get_ucc_id_for_range(addr, addr + size, &id)))
                        goto err_free_irqs;
 
-               ucc_set_qe_mux_mii_mng(id - 1);
+               if (!mii_mng_master) {
+                       mii_mng_master = id;
+                       ucc_set_qe_mux_mii_mng(id - 1);
+               }
 #else
                err = -ENODEV;
                goto err_free_irqs;
@@ -384,15 +351,7 @@ static int fsl_pq_mdio_probe(struct of_device *ofdev,
 
        out_be32(tbipa, tbiaddr);
 
-       /*
-        * The TBIPHY-only buses will find PHYs at every address,
-        * so we mask them all but the TBI
-        */
-       if (of_device_is_compatible(np, "fsl,gianfar-tbi"))
-               new_bus->phy_mask = ~(1 << tbiaddr);
-
-       err = mdiobus_register(new_bus);
-
+       err = of_mdiobus_register(new_bus, np);
        if (err) {
                printk (KERN_ERR "%s: Cannot register as MDIO bus\n",
                                new_bus->name);
@@ -460,10 +419,10 @@ int __init fsl_pq_mdio_init(void)
 {
        return of_register_platform_driver(&fsl_pq_mdio_driver);
 }
+module_init(fsl_pq_mdio_init);
 
 void fsl_pq_mdio_exit(void)
 {
        of_unregister_platform_driver(&fsl_pq_mdio_driver);
 }
-subsys_initcall_sync(fsl_pq_mdio_init);
 module_exit(fsl_pq_mdio_exit);
index a0519184e54ee7d7a30aed189a7ce13e5ab122f1..4ae1d259fced7d6525a6818a1c641db5d1cf3850 100644 (file)
@@ -75,6 +75,7 @@
 #include <linux/if_vlan.h>
 #include <linux/spinlock.h>
 #include <linux/mm.h>
+#include <linux/of_mdio.h>
 #include <linux/of_platform.h>
 #include <linux/ip.h>
 #include <linux/tcp.h>
@@ -168,17 +169,13 @@ static inline int gfar_uses_fcb(struct gfar_private *priv)
 
 static int gfar_of_init(struct net_device *dev)
 {
-       struct device_node *phy, *mdio;
-       const unsigned int *id;
        const char *model;
        const char *ctype;
        const void *mac_addr;
-       const phandle *ph;
        u64 addr, size;
        int err = 0;
        struct gfar_private *priv = netdev_priv(dev);
        struct device_node *np = priv->node;
-       char bus_name[MII_BUS_ID_SIZE];
        const u32 *stash;
        const u32 *stash_len;
        const u32 *stash_idx;
@@ -264,8 +261,8 @@ static int gfar_of_init(struct net_device *dev)
        if (of_get_property(np, "fsl,magic-packet", NULL))
                priv->device_flags |= FSL_GIANFAR_DEV_HAS_MAGIC_PACKET;
 
-       ph = of_get_property(np, "phy-handle", NULL);
-       if (ph == NULL) {
+       priv->phy_node = of_parse_phandle(np, "phy-handle", 0);
+       if (!priv->phy_node) {
                u32 *fixed_link;
 
                fixed_link = (u32 *)of_get_property(np, "fixed-link", NULL);
@@ -273,57 +270,10 @@ static int gfar_of_init(struct net_device *dev)
                        err = -ENODEV;
                        goto err_out;
                }
-
-               snprintf(priv->phy_bus_id, sizeof(priv->phy_bus_id),
-                               PHY_ID_FMT, "0", fixed_link[0]);
-       } else {
-               phy = of_find_node_by_phandle(*ph);
-
-               if (phy == NULL) {
-                       err = -ENODEV;
-                       goto err_out;
-               }
-
-               mdio = of_get_parent(phy);
-
-               id = of_get_property(phy, "reg", NULL);
-
-               of_node_put(phy);
-
-               fsl_pq_mdio_bus_name(bus_name, mdio);
-               of_node_put(mdio);
-               snprintf(priv->phy_bus_id, sizeof(priv->phy_bus_id), "%s:%02x",
-                               bus_name, *id);
        }
 
        /* Find the TBI PHY.  If it's not there, we don't support SGMII */
-       ph = of_get_property(np, "tbi-handle", NULL);
-       if (ph) {
-               struct device_node *tbi = of_find_node_by_phandle(*ph);
-               struct of_device *ofdev;
-               struct mii_bus *bus;
-
-               if (!tbi)
-                       return 0;
-
-               mdio = of_get_parent(tbi);
-               if (!mdio)
-                       return 0;
-
-               ofdev = of_find_device_by_node(mdio);
-
-               of_node_put(mdio);
-
-               id = of_get_property(tbi, "reg", NULL);
-               if (!id)
-                       return 0;
-
-               of_node_put(tbi);
-
-               bus = dev_get_drvdata(&ofdev->dev);
-
-               priv->tbiphy = bus->phy_map[*id];
-       }
+       priv->tbi_node = of_parse_phandle(np, "tbi-handle", 0);
 
        return 0;
 
@@ -529,6 +479,10 @@ static int gfar_probe(struct of_device *ofdev,
 register_fail:
        iounmap(priv->regs);
 regs_fail:
+       if (priv->phy_node)
+               of_node_put(priv->phy_node);
+       if (priv->tbi_node)
+               of_node_put(priv->tbi_node);
        free_netdev(dev);
        return err;
 }
@@ -537,6 +491,11 @@ static int gfar_remove(struct of_device *ofdev)
 {
        struct gfar_private *priv = dev_get_drvdata(&ofdev->dev);
 
+       if (priv->phy_node)
+               of_node_put(priv->phy_node);
+       if (priv->tbi_node)
+               of_node_put(priv->tbi_node);
+
        dev_set_drvdata(&ofdev->dev, NULL);
 
        iounmap(priv->regs);
@@ -690,7 +649,6 @@ static int init_phy(struct net_device *dev)
        uint gigabit_support =
                priv->device_flags & FSL_GIANFAR_DEV_HAS_GIGABIT ?
                SUPPORTED_1000baseT_Full : 0;
-       struct phy_device *phydev;
        phy_interface_t interface;
 
        priv->oldlink = 0;
@@ -699,21 +657,21 @@ static int init_phy(struct net_device *dev)
 
        interface = gfar_get_interface(dev);
 
-       phydev = phy_connect(dev, priv->phy_bus_id, &adjust_link, 0, interface);
+       if (priv->phy_node) {
+               priv->phydev = of_phy_connect(dev, priv->phy_node, &adjust_link,
+                                             0, interface);
+               if (!priv->phydev) {
+                       dev_err(&dev->dev, "error: Could not attach to PHY\n");
+                       return -ENODEV;
+               }
+       }
 
        if (interface == PHY_INTERFACE_MODE_SGMII)
                gfar_configure_serdes(dev);
 
-       if (IS_ERR(phydev)) {
-               printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name);
-               return PTR_ERR(phydev);
-       }
-
        /* Remove any features not supported by the controller */
-       phydev->supported &= (GFAR_SUPPORTED | gigabit_support);
-       phydev->advertising = phydev->supported;
-
-       priv->phydev = phydev;
+       priv->phydev->supported &= (GFAR_SUPPORTED | gigabit_support);
+       priv->phydev->advertising = priv->phydev->supported;
 
        return 0;
 }
@@ -730,10 +688,17 @@ static int init_phy(struct net_device *dev)
 static void gfar_configure_serdes(struct net_device *dev)
 {
        struct gfar_private *priv = netdev_priv(dev);
+       struct phy_device *tbiphy;
 
-       if (!priv->tbiphy) {
-               printk(KERN_WARNING "SGMII mode requires that the device "
-                               "tree specify a tbi-handle\n");
+       if (!priv->tbi_node) {
+               dev_warn(&dev->dev, "error: SGMII mode requires that the "
+                                   "device tree specify a tbi-handle\n");
+               return;
+       }
+
+       tbiphy = of_phy_find_device(priv->tbi_node);
+       if (!tbiphy) {
+               dev_err(&dev->dev, "error: Could not get TBI device\n");
                return;
        }
 
@@ -743,17 +708,17 @@ static void gfar_configure_serdes(struct net_device *dev)
         * everything for us?  Resetting it takes the link down and requires
         * several seconds for it to come back.
         */
-       if (phy_read(priv->tbiphy, MII_BMSR) & BMSR_LSTATUS)
+       if (phy_read(tbiphy, MII_BMSR) & BMSR_LSTATUS)
                return;
 
        /* Single clk mode, mii mode off(for serdes communication) */
-       phy_write(priv->tbiphy, MII_TBICON, TBICON_CLK_SELECT);
+       phy_write(tbiphy, MII_TBICON, TBICON_CLK_SELECT);
 
-       phy_write(priv->tbiphy, MII_ADVERTISE,
+       phy_write(tbiphy, MII_ADVERTISE,
                        ADVERTISE_1000XFULL | ADVERTISE_1000XPAUSE |
                        ADVERTISE_1000XPSE_ASYM);
 
-       phy_write(priv->tbiphy, MII_BMCR, BMCR_ANENABLE |
+       phy_write(tbiphy, MII_BMCR, BMCR_ANENABLE |
                        BMCR_ANRESTART | BMCR_FULLDPLX | BMCR_SPEED1000);
 }
 
@@ -1242,7 +1207,8 @@ static int gfar_enet_open(struct net_device *dev)
 static inline struct txfcb *gfar_add_fcb(struct sk_buff *skb)
 {
        struct txfcb *fcb = (struct txfcb *)skb_push(skb, GMAC_FCB_LEN);
-       cacheable_memzero(fcb, GMAC_FCB_LEN);
+
+       memset(fcb, 0, GMAC_FCB_LEN);
 
        return fcb;
 }
index cf352961ae9b7036748bae75e043af7bd4ce0de6..2cd94338b5d3a8459649f902cab0f72daa18e653 100644 (file)
@@ -779,7 +779,8 @@ struct gfar_private {
        spinlock_t bflock;
 
        phy_interface_t interface;
-       char    phy_bus_id[BUS_ID_SIZE];
+       struct device_node *phy_node;
+       struct device_node *tbi_node;
        u32 device_flags;
        unsigned char rx_csum_enable:1,
                extended_hash:1,
@@ -793,7 +794,6 @@ struct gfar_private {
 
        /* PHY stuff */
        struct phy_device *phydev;
-       struct phy_device *tbiphy;
        struct mii_bus *mii_bus;
        int oldspeed;
        int oldduplex;
index 310ee035067c3ff54002bf322e230bcbe6540493..9d5b62cb30f790de7f198b4d67e7e619b82d7878 100644 (file)
@@ -1163,7 +1163,7 @@ static void hamachi_tx_timeout(struct net_device *dev)
        hmp->rx_ring[RX_RING_SIZE-1].status_n_length |= cpu_to_le32(DescEndRing);
 
        /* Trigger an immediate transmit demand. */
-       dev->trans_start = jiffies;
+       dev->trans_start = jiffies; /* prevent tx timeout */
        hmp->stats.tx_errors++;
 
        /* Restart the chip's Tx/Rx processes . */
@@ -1280,7 +1280,7 @@ static int hamachi_start_xmit(struct sk_buff *skb, struct net_device *dev)
                status=readw(hmp->base + TxStatus);
                if( !(status & 0x0001) || (status & 0x0002))
                        writew(0x0001, hmp->base + TxCmd);
-               return 1;
+               return NETDEV_TX_BUSY;
        }
 
        /* Caution: the write order is important here, set the field
@@ -1364,7 +1364,6 @@ static int hamachi_start_xmit(struct sk_buff *skb, struct net_device *dev)
                hmp->tx_full = 1;
                netif_stop_queue(dev);
        }
-       dev->trans_start = jiffies;
 
        if (hamachi_debug > 4) {
                printk(KERN_DEBUG "%s: Hamachi transmit frame #%d queued in slot %d.\n",
index bb78c11559cd2cd9cb0876cbe2630816b539aea3..5e4b7afd068395b343f5ad267673eed7090e197a 100644 (file)
@@ -777,7 +777,7 @@ static int baycom_send_packet(struct sk_buff *skb, struct net_device *dev)
                return 0;
        }
        if (bc->skb)
-               return -1;
+               return NETDEV_TX_LOCKED;
        /* strip KISS byte */
        if (skb->len >= HDLCDRV_MAXFLEN+1 || skb->len < 3) {
                dev_kfree_skb(skb);
index d509b371a562165bc22cfd086fae186b7130ef2b..5105548ad50c6ad0ccb73efaea382066b0af255b 100644 (file)
@@ -274,7 +274,7 @@ static int bpq_xmit(struct sk_buff *skb, struct net_device *dev)
                if ((newskb = skb_realloc_headroom(skb, AX25_BPQ_HEADER_LEN)) == NULL) {
                        printk(KERN_WARNING "bpqether: out of memory\n");
                        kfree_skb(skb);
-                       return -ENOMEM;
+                       return NETDEV_TX_OK;
                }
 
                if (skb->sk != NULL)
@@ -294,7 +294,7 @@ static int bpq_xmit(struct sk_buff *skb, struct net_device *dev)
        if ((dev = bpq_get_ether_dev(dev)) == NULL) {
                dev->stats.tx_dropped++;
                kfree_skb(skb);
-               return -ENODEV;
+               return NETDEV_TX_OK;
        }
 
        skb->protocol = ax25_type_trans(skb, dev);
index 61de56e45eedb509bc33bca2ed120b4868ab5c7f..d034f8ca63cb9a3b1b5aa18aefd9892e4abd9f1e 100644 (file)
@@ -409,7 +409,7 @@ static int hdlcdrv_send_packet(struct sk_buff *skb, struct net_device *dev)
                return 0;
        }
        if (sm->skb)
-               return -1;
+               return NETDEV_TX_LOCKED;
        netif_stop_queue(dev);
        sm->skb = skb;
        return 0;
index 032c0db4c410b0d516f04f951ba1ed4d48fa5f35..fda2fc83e9a124c66c3f7d3754e8312a36b172f8 100644 (file)
@@ -531,7 +531,7 @@ static int ax_xmit(struct sk_buff *skb, struct net_device *dev)
 
        if (!netif_running(dev))  {
                printk(KERN_ERR "mkiss: %s: xmit call when iface is down\n", dev->name);
-               return 1;
+               return NETDEV_TX_BUSY;
        }
 
        if (netif_queue_stopped(dev)) {
@@ -541,7 +541,7 @@ static int ax_xmit(struct sk_buff *skb, struct net_device *dev)
                 */
                if (time_before(jiffies, dev->trans_start + 20 * HZ)) {
                        /* 20 sec timeout not reached */
-                       return 1;
+                       return NETDEV_TX_BUSY;
                }
 
                printk(KERN_ERR "mkiss: %s: transmit timed out, %s?\n", dev->name,
index de3f49f991a3d61c3f25362414b649c673cf2612..8feda9fe8297d738a77449b85a64259fb58c95dc 100644 (file)
@@ -2864,7 +2864,7 @@ static int __init hp100_eisa_probe (struct device *gendev)
        printk("hp100: %s: EISA adapter found at 0x%x\n", dev->name,
               dev->base_addr);
 #endif
-       gendev->driver_data = dev;
+       dev_set_drvdata(gendev, dev);
        return 0;
  out1:
        free_netdev(dev);
@@ -2873,7 +2873,7 @@ static int __init hp100_eisa_probe (struct device *gendev)
 
 static int __devexit hp100_eisa_remove (struct device *gendev)
 {
-       struct net_device *dev = gendev->driver_data;
+       struct net_device *dev = dev_get_drvdata(gendev);
        cleanup_dev(dev);
        return 0;
 }
index 2e802634d366540d8a54c7ad9633c408c22ac1d5..3e3528ade259d73f072d614f2181fe04c2083940 100644 (file)
@@ -71,6 +71,19 @@ static struct dio_driver hplance_driver = {
        .remove    = __devexit_p(hplance_remove_one),
 };
 
+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_change_mtu         = eth_change_mtu,
+       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_set_mac_address    = eth_mac_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+       .ndo_poll_controller    = lance_poll,
+#endif
+};
+
 /* Find all the HP Lance boards and initialise them... */
 static int __devinit hplance_init_one(struct dio_dev *d,
                                const struct dio_device_id *ent)
@@ -135,13 +148,7 @@ static void __init hplance_init(struct net_device *dev, struct dio_dev *d)
 
         /* Fill the dev fields */
         dev->base_addr = va;
-        dev->open = &hplance_open;
-        dev->stop = &hplance_close;
-#ifdef CONFIG_NET_POLL_CONTROLLER
-        dev->poll_controller = lance_poll;
-#endif
-        dev->hard_start_xmit = &lance_start_xmit;
-        dev->set_multicast_list = &lance_set_multicast;
+        dev->netdev_ops = &hplance_netdev_ops;
         dev->dma = 0;
 
         for (i=0; i<6; i++) {
index 806533c831c7e8ecc43fecf607d81c5342900064..beb84213b6719ba614641e56af5862dd5581ad9e 100644 (file)
@@ -1484,7 +1484,7 @@ static int emac_start_xmit_sg(struct sk_buff *skb, struct net_device *ndev)
  stop_queue:
        netif_stop_queue(ndev);
        DBG2(dev, "stopped TX queue" NL);
-       return 1;
+       return NETDEV_TX_BUSY;
 }
 
 /* Tx lock BHs */
index c25bc0bc0b25ea2031146458ee51cb7715654646..448098d3b39b285c0a5905f2f3b9bf0b470b5507 100644 (file)
@@ -815,7 +815,7 @@ static int ibmlana_close(struct net_device *dev)
 static int ibmlana_tx(struct sk_buff *skb, struct net_device *dev)
 {
        ibmlana_priv *priv = netdev_priv(dev);
-       int retval = 0, tmplen, addr;
+       int tmplen, addr;
        unsigned long flags;
        tda_t tda;
        int baddr;
@@ -824,7 +824,6 @@ static int ibmlana_tx(struct sk_buff *skb, struct net_device *dev)
           the upper layer is in deep desperation and we simply ignore the frame. */
 
        if (priv->txusedcnt >= TXBUFCNT) {
-               retval = -EIO;
                dev->stats.tx_dropped++;
                goto tx_done;
        }
@@ -874,7 +873,7 @@ static int ibmlana_tx(struct sk_buff *skb, struct net_device *dev)
        spin_unlock_irqrestore(&priv->lock, flags);
 tx_done:
        dev_kfree_skb(skb);
-       return retval;
+       return NETDEV_TX_OK;
 }
 
 /* switch receiver mode. */
index 5c6315df86b98ae29c7e8306fd3a803dc45f2ca4..0995c438f286d4fb580828b5a339612a4d0f6ac2 100644 (file)
@@ -1203,6 +1203,20 @@ static unsigned long ibmveth_get_desired_dma(struct vio_dev *vdev)
        return ret;
 }
 
+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_do_ioctl           = ibmveth_ioctl,
+       .ndo_change_mtu         = ibmveth_change_mtu,
+       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_set_mac_address    = eth_mac_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+       .ndo_poll_controller    = ibmveth_poll_controller,
+#endif
+};
+
 static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_id *id)
 {
        int rc, i;
@@ -1241,7 +1255,7 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_
                return -ENOMEM;
 
        adapter = netdev_priv(netdev);
-       dev->dev.driver_data = netdev;
+       dev_set_drvdata(&dev->dev, netdev);
 
        adapter->vdev = dev;
        adapter->netdev = netdev;
@@ -1265,21 +1279,13 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_
        memcpy(&adapter->mac_addr, mac_addr_p, 6);
 
        netdev->irq = dev->irq;
-       netdev->open               = ibmveth_open;
-       netdev->stop               = ibmveth_close;
-       netdev->hard_start_xmit    = ibmveth_start_xmit;
-       netdev->set_multicast_list = ibmveth_set_multicast_list;
-       netdev->do_ioctl           = ibmveth_ioctl;
-       netdev->ethtool_ops           = &netdev_ethtool_ops;
-       netdev->change_mtu         = ibmveth_change_mtu;
+       netdev->netdev_ops = &ibmveth_netdev_ops;
+       netdev->ethtool_ops = &netdev_ethtool_ops;
        SET_NETDEV_DEV(netdev, &dev->dev);
-#ifdef CONFIG_NET_POLL_CONTROLLER
-       netdev->poll_controller = ibmveth_poll_controller;
-#endif
        netdev->features |= NETIF_F_LLTX;
        spin_lock_init(&adapter->stats_lock);
 
-       memcpy(&netdev->dev_addr, &adapter->mac_addr, netdev->addr_len);
+       memcpy(netdev->dev_addr, &adapter->mac_addr, netdev->addr_len);
 
        for(i = 0; i<IbmVethNumBufferPools; i++) {
                struct kobject *kobj = &adapter->rx_buff_pool[i].kobj;
@@ -1335,7 +1341,7 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_
 
 static int __devexit ibmveth_remove(struct vio_dev *dev)
 {
-       struct net_device *netdev = dev->dev.driver_data;
+       struct net_device *netdev = dev_get_drvdata(&dev->dev);
        struct ibmveth_adapter *adapter = netdev_priv(netdev);
        int i;
 
@@ -1368,8 +1374,8 @@ static void ibmveth_proc_unregister_driver(void)
 static int ibmveth_show(struct seq_file *seq, void *v)
 {
        struct ibmveth_adapter *adapter = seq->private;
-       char *current_mac = ((char*) &adapter->netdev->dev_addr);
-       char *firmware_mac = ((char*) &adapter->mac_addr) ;
+       char *current_mac = (char *) adapter->netdev->dev_addr;
+       char *firmware_mac = (char *) &adapter->mac_addr;
 
        seq_printf(seq, "%s %s\n\n", ibmveth_driver_string, ibmveth_driver_version);
 
@@ -1468,8 +1474,8 @@ const char * buf, size_t count)
        struct ibmveth_buff_pool *pool = container_of(kobj,
                                                      struct ibmveth_buff_pool,
                                                      kobj);
-       struct net_device *netdev =
-           container_of(kobj->parent, struct device, kobj)->driver_data;
+       struct net_device *netdev = dev_get_drvdata(
+           container_of(kobj->parent, struct device, kobj));
        struct ibmveth_adapter *adapter = netdev_priv(netdev);
        long value = simple_strtol(buf, NULL, 10);
        long rc;
index 60a263001933a53e48e32d28f7adc7dc8914d437..96713ef0629848dd1d529246a7b8fe1941f43816 100644 (file)
@@ -156,6 +156,7 @@ static void ifb_setup(struct net_device *dev)
 
        dev->flags |= IFF_NOARP;
        dev->flags &= ~IFF_MULTICAST;
+       dev->priv_flags &= ~IFF_XMIT_DST_RELEASE;
        random_ether_addr(dev->dev_addr);
 }
 
index eaf9770503685126dc4b9b74f3d948aa61443019..0f16abab256537f91ec4df794c17136f1be925ef 100644 (file)
@@ -130,6 +130,7 @@ struct e1000_adv_tx_context_desc {
 #define E1000_ADVTXD_MACLEN_SHIFT    9  /* Adv ctxt desc mac len shift */
 #define E1000_ADVTXD_TUCMD_IPV4    0x00000400  /* IP Packet Type: 1=IPv4 */
 #define E1000_ADVTXD_TUCMD_L4T_TCP 0x00000800  /* L4 Packet TYPE of TCP */
+#define E1000_ADVTXD_TUCMD_L4T_SCTP 0x00001000 /* L4 packet TYPE of SCTP */
 /* IPSec Encrypt Enable for ESP */
 #define E1000_ADVTXD_L4LEN_SHIFT     8  /* Adv ctxt L4LEN shift */
 #define E1000_ADVTXD_MSS_SHIFT      16  /* Adv ctxt MSS shift */
index ad2d319d0f8be731579a435de45618beba376b92..3bda3db73f1f01852998741517a4219432eef61c 100644 (file)
 #define E1000_SCTL_DISABLE_SERDES_LOOPBACK 0x0400
 
 /* Receive Checksum Control */
+#define E1000_RXCSUM_IPOFL     0x00000100   /* IPv4 checksum offload */
 #define E1000_RXCSUM_TUOFL     0x00000200   /* TCP / UDP checksum offload */
-#define E1000_RXCSUM_IPPCSE    0x00001000   /* IP payload checksum enable */
+#define E1000_RXCSUM_CRCOFL    0x00000800   /* CRC32 offload enable */
 #define E1000_RXCSUM_PCSD      0x00002000   /* packet checksum disabled */
 
 /* Header split receive */
index 840782fb573659ea85c06cd104611b6217b774e2..ed9058eca45cc80cc8386e1b913e44b0b299975e 100644 (file)
@@ -140,13 +140,13 @@ static s32 igb_poll_for_msg(struct e1000_hw *hw, u16 mbx_id)
        struct e1000_mbx_info *mbx = &hw->mbx;
        int countdown = mbx->timeout;
 
-       if (!mbx->ops.check_for_msg)
+       if (!countdown || !mbx->ops.check_for_msg)
                goto out;
 
        while (mbx->ops.check_for_msg(hw, mbx_id)) {
+               countdown--;
                if (!countdown)
                        break;
-               countdown--;
                udelay(mbx->usec_delay);
        }
 out:
@@ -165,13 +165,13 @@ static s32 igb_poll_for_ack(struct e1000_hw *hw, u16 mbx_id)
        struct e1000_mbx_info *mbx = &hw->mbx;
        int countdown = mbx->timeout;
 
-       if (!mbx->ops.check_for_ack)
+       if (!countdown || !mbx->ops.check_for_ack)
                goto out;
 
        while (mbx->ops.check_for_ack(hw, mbx_id)) {
+               countdown--;
                if (!countdown)
                        break;
-               countdown--;
                udelay(mbx->usec_delay);
        }
 out:
index 3228a862031f87a231d992458def9c93d1e0d54f..ebe4b616db8a472de823928b8de2109930dec153 100644 (file)
@@ -80,7 +80,7 @@ s32  igb_phy_init_script_igp3(struct e1000_hw *hw);
 #define IGP02E1000_PM_D3_LPLU             0x0004 /* For all other states */
 #define IGP01E1000_PLHR_SS_DOWNGRADE      0x8000
 #define IGP01E1000_PSSR_POLARITY_REVERSED 0x0002
-#define IGP01E1000_PSSR_MDIX              0x0008
+#define IGP01E1000_PSSR_MDIX              0x0800
 #define IGP01E1000_PSSR_SPEED_MASK        0xC000
 #define IGP01E1000_PSSR_SPEED_1000MBPS    0xC000
 #define IGP02E1000_PHY_CHANNEL_NUM        4
index 0bd7728fe469bd58c40c91385f609c8a061d3925..6e5924511e40fbda73f5ae298dd1194a80112d25 100644 (file)
@@ -142,6 +142,7 @@ enum {
 #define E1000_SYNQF(_n) (0x055FC + (4 * (_n))) /* SYN Packet Queue Fltr */
 #define E1000_ETQF(_n)  (0x05CB0 + (4 * (_n))) /* EType Queue Fltr */
 
+#define E1000_RQDPC(_n) (0x0C030 + ((_n) * 0x40))
 /* Split and Replication RX Control - RW */
 /*
  * Convenience macros
index 4e8464b9df2e4af277b3d532c59e88612fb062a0..b2c98dea9eed4c01bd0bbfbdf750d1231b53c66e 100644 (file)
@@ -137,11 +137,17 @@ struct igb_buffer {
        };
 };
 
-struct igb_queue_stats {
+struct igb_tx_queue_stats {
        u64 packets;
        u64 bytes;
 };
 
+struct igb_rx_queue_stats {
+       u64 packets;
+       u64 bytes;
+       u64 drops;
+};
+
 struct igb_ring {
        struct igb_adapter *adapter; /* backlink */
        void *desc;                  /* descriptor ring memory */
@@ -167,12 +173,13 @@ struct igb_ring {
        union {
                /* TX */
                struct {
-                       struct igb_queue_stats tx_stats;
+                       struct igb_tx_queue_stats tx_stats;
                        bool detect_tx_hung;
                };
                /* RX */
                struct {
-                       struct igb_queue_stats rx_stats;
+                       struct igb_rx_queue_stats rx_stats;
+                       u64 rx_queue_drops;
                        struct napi_struct napi;
                        int set_itr;
                        struct igb_ring *buddy;
@@ -238,7 +245,6 @@ struct igb_adapter {
        u64 hw_csum_err;
        u64 hw_csum_good;
        u32 alloc_rx_buff_failed;
-       bool rx_csum;
        u32 gorc;
        u64 gorc_old;
        u16 rx_ps_hdr_size;
@@ -286,6 +292,7 @@ struct igb_adapter {
 #define IGB_FLAG_DCA_ENABLED       (1 << 1)
 #define IGB_FLAG_QUAD_PORT_A       (1 << 2)
 #define IGB_FLAG_NEED_CTX_IDX      (1 << 3)
+#define IGB_FLAG_RX_CSUM_DISABLED  (1 << 4)
 
 enum e1000_state_t {
        __IGB_TESTING,
index 27eae49e79c27c068ad31cbafc9fc441fed20f46..9598ac09f4b87942da669029352e502e263aa968 100644 (file)
@@ -64,6 +64,7 @@ static const struct igb_stats igb_gstrings_stats[] = {
        { "rx_crc_errors", IGB_STAT(stats.crcerrs) },
        { "rx_frame_errors", IGB_STAT(net_stats.rx_frame_errors) },
        { "rx_no_buffer_count", IGB_STAT(stats.rnbc) },
+       { "rx_queue_drop_packet_count", IGB_STAT(net_stats.rx_fifo_errors) },
        { "rx_missed_errors", IGB_STAT(stats.mpc) },
        { "tx_aborted_errors", IGB_STAT(stats.ecol) },
        { "tx_carrier_errors", IGB_STAT(stats.tncrs) },
@@ -96,9 +97,10 @@ static const struct igb_stats igb_gstrings_stats[] = {
 };
 
 #define IGB_QUEUE_STATS_LEN \
-       ((((struct igb_adapter *)netdev_priv(netdev))->num_rx_queues + \
-        ((struct igb_adapter *)netdev_priv(netdev))->num_tx_queues) * \
-       (sizeof(struct igb_queue_stats) / sizeof(u64)))
+       (((((struct igb_adapter *)netdev_priv(netdev))->num_rx_queues)* \
+         (sizeof(struct igb_rx_queue_stats) / sizeof(u64))) + \
+        ((((struct igb_adapter *)netdev_priv(netdev))->num_tx_queues) * \
+         (sizeof(struct igb_tx_queue_stats) / sizeof(u64))))
 #define IGB_GLOBAL_STATS_LEN   \
        sizeof(igb_gstrings_stats) / sizeof(struct igb_stats)
 #define IGB_STATS_LEN (IGB_GLOBAL_STATS_LEN + IGB_QUEUE_STATS_LEN)
@@ -275,13 +277,17 @@ static int igb_set_pauseparam(struct net_device *netdev,
 static u32 igb_get_rx_csum(struct net_device *netdev)
 {
        struct igb_adapter *adapter = netdev_priv(netdev);
-       return adapter->rx_csum;
+       return !(adapter->flags & IGB_FLAG_RX_CSUM_DISABLED);
 }
 
 static int igb_set_rx_csum(struct net_device *netdev, u32 data)
 {
        struct igb_adapter *adapter = netdev_priv(netdev);
-       adapter->rx_csum = data;
+
+       if (data)
+               adapter->flags &= ~IGB_FLAG_RX_CSUM_DISABLED;
+       else
+               adapter->flags |= IGB_FLAG_RX_CSUM_DISABLED;
 
        return 0;
 }
@@ -293,10 +299,16 @@ static u32 igb_get_tx_csum(struct net_device *netdev)
 
 static int igb_set_tx_csum(struct net_device *netdev, u32 data)
 {
-       if (data)
+       struct igb_adapter *adapter = netdev_priv(netdev);
+
+       if (data) {
                netdev->features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
-       else
-               netdev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
+               if (adapter->hw.mac.type == e1000_82576)
+                       netdev->features |= NETIF_F_SCTP_CSUM;
+       } else {
+               netdev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
+                                     NETIF_F_SCTP_CSUM);
+       }
 
        return 0;
 }
@@ -1950,7 +1962,8 @@ static void igb_get_ethtool_stats(struct net_device *netdev,
 {
        struct igb_adapter *adapter = netdev_priv(netdev);
        u64 *queue_stat;
-       int stat_count = sizeof(struct igb_queue_stats) / sizeof(u64);
+       int stat_count_tx = sizeof(struct igb_tx_queue_stats) / sizeof(u64);
+       int stat_count_rx = sizeof(struct igb_rx_queue_stats) / sizeof(u64);
        int j;
        int i;
 
@@ -1963,14 +1976,14 @@ static void igb_get_ethtool_stats(struct net_device *netdev,
        for (j = 0; j < adapter->num_tx_queues; j++) {
                int k;
                queue_stat = (u64 *)&adapter->tx_ring[j].tx_stats;
-               for (k = 0; k < stat_count; k++)
+               for (k = 0; k < stat_count_tx; k++)
                        data[i + k] = queue_stat[k];
                i += k;
        }
        for (j = 0; j < adapter->num_rx_queues; j++) {
                int k;
                queue_stat = (u64 *)&adapter->rx_ring[j].rx_stats;
-               for (k = 0; k < stat_count; k++)
+               for (k = 0; k < stat_count_rx; k++)
                        data[i + k] = queue_stat[k];
                i += k;
        }
@@ -2004,6 +2017,8 @@ static void igb_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
                        p += ETH_GSTRING_LEN;
                        sprintf(p, "rx_queue_%u_bytes", i);
                        p += ETH_GSTRING_LEN;
+                       sprintf(p, "rx_queue_%u_drops", i);
+                       p += ETH_GSTRING_LEN;
                }
 /*             BUG_ON(p - data != IGB_STATS_LEN * ETH_GSTRING_LEN); */
                break;
index e25343588fc77466380039a46728ba4bfd8ecd34..ea17319624aa7cc3c2cc51c1ae04044f69e14dba 100644 (file)
@@ -942,6 +942,8 @@ int igb_up(struct igb_adapter *adapter)
        rd32(E1000_ICR);
        igb_irq_enable(adapter);
 
+       netif_tx_start_all_queues(adapter->netdev);
+
        /* Fire a link change interrupt to start the watchdog. */
        wr32(E1000_ICS, E1000_ICS_LSC);
        return 0;
@@ -994,6 +996,11 @@ void igb_down(struct igb_adapter *adapter)
                igb_reset(adapter);
        igb_clean_all_tx_rings(adapter);
        igb_clean_all_rx_rings(adapter);
+#ifdef CONFIG_IGB_DCA
+
+       /* since we reset the hardware DCA settings were cleared */
+       igb_setup_dca(adapter);
+#endif
 }
 
 void igb_reinit_locked(struct igb_adapter *adapter)
@@ -1343,6 +1350,9 @@ static int __devinit igb_probe(struct pci_dev *pdev,
        if (pci_using_dac)
                netdev->features |= NETIF_F_HIGHDMA;
 
+       if (adapter->hw.mac.type == e1000_82576)
+               netdev->features |= NETIF_F_SCTP_CSUM;
+
        adapter->en_mng_pt = igb_enable_mng_pass_thru(&adapter->hw);
 
        /* before reading the NVM, reset the controller to put the device in a
@@ -1390,8 +1400,6 @@ static int __devinit igb_probe(struct pci_dev *pdev,
 
        igb_validate_mdi_setting(hw);
 
-       adapter->rx_csum = 1;
-
        /* Initial Wake on LAN setting If APM wake is enabled in the EEPROM,
         * enable the ACPI Magic Packet filter
         */
@@ -1442,22 +1450,18 @@ static int __devinit igb_probe(struct pci_dev *pdev,
         * driver. */
        igb_get_hw_control(adapter);
 
-       /* tell the stack to leave us alone until igb_open() is called */
-       netif_carrier_off(netdev);
-       netif_tx_stop_all_queues(netdev);
-
        strcpy(netdev->name, "eth%d");
        err = register_netdev(netdev);
        if (err)
                goto err_register;
 
+       /* carrier off reporting is important to ethtool even BEFORE open */
+       netif_carrier_off(netdev);
+
 #ifdef CONFIG_IGB_DCA
        if (dca_add_requester(&pdev->dev) == 0) {
                adapter->flags |= IGB_FLAG_DCA_ENABLED;
                dev_info(&pdev->dev, "DCA enabled\n");
-               /* Always use CB2 mode, difference is masked
-                * in the CB driver. */
-               wr32(E1000_DCA_CTRL, E1000_DCA_CTRL_DCA_MODE_CB2);
                igb_setup_dca(adapter);
        }
 #endif
@@ -1699,6 +1703,8 @@ static int igb_open(struct net_device *netdev)
        if (test_bit(__IGB_TESTING, &adapter->state))
                return -EBUSY;
 
+       netif_carrier_off(netdev);
+
        /* allocate transmit descriptors */
        err = igb_setup_all_tx_resources(adapter);
        if (err)
@@ -2231,29 +2237,24 @@ static void igb_configure_rx(struct igb_adapter *adapter)
                mrqc |= (E1000_MRQC_RSS_FIELD_IPV6_UDP_EX |
                         E1000_MRQC_RSS_FIELD_IPV6_TCP_EX);
 
-
                wr32(E1000_MRQC, mrqc);
-
-               /* Multiqueue and raw packet checksumming are mutually
-                * exclusive.  Note that this not the same as TCP/IP
-                * checksumming, which works fine. */
-               rxcsum = rd32(E1000_RXCSUM);
-               rxcsum |= E1000_RXCSUM_PCSD;
-               wr32(E1000_RXCSUM, rxcsum);
-       } else {
+       } else if (adapter->vfs_allocated_count) {
                /* Enable multi-queue for sr-iov */
-               if (adapter->vfs_allocated_count)
-                       wr32(E1000_MRQC, E1000_MRQC_ENABLE_VMDQ);
-               /* Enable Receive Checksum Offload for TCP and UDP */
-               rxcsum = rd32(E1000_RXCSUM);
-               if (adapter->rx_csum)
-                       rxcsum |= E1000_RXCSUM_TUOFL | E1000_RXCSUM_IPPCSE;
-               else
-                       rxcsum &= ~(E1000_RXCSUM_TUOFL | E1000_RXCSUM_IPPCSE);
-
-               wr32(E1000_RXCSUM, rxcsum);
+               wr32(E1000_MRQC, E1000_MRQC_ENABLE_VMDQ);
        }
 
+       /* Enable Receive Checksum Offload for TCP and UDP */
+       rxcsum = rd32(E1000_RXCSUM);
+       /* Disable raw packet checksumming */
+       rxcsum |= E1000_RXCSUM_PCSD;
+
+       if (adapter->hw.mac.type == e1000_82576)
+               /* Enable Receive Checksum Offload for SCTP */
+               rxcsum |= E1000_RXCSUM_CRCOFL;
+
+       /* Don't need to set TUOFL or IPOFL, they default to 1 */
+       wr32(E1000_RXCSUM, rxcsum);
+
        /* Set the default pool for the PF's first queue */
        igb_configure_vt_default_pool(adapter);
 
@@ -2661,7 +2662,6 @@ static void igb_watchdog_task(struct work_struct *work)
                        }
 
                        netif_carrier_on(netdev);
-                       netif_tx_wake_all_queues(netdev);
 
                        igb_ping_all_vfs(adapter);
 
@@ -2678,7 +2678,6 @@ static void igb_watchdog_task(struct work_struct *work)
                        printk(KERN_INFO "igb: %s NIC Link is Down\n",
                               netdev->name);
                        netif_carrier_off(netdev);
-                       netif_tx_stop_all_queues(netdev);
 
                        igb_ping_all_vfs(adapter);
 
@@ -2712,6 +2711,8 @@ link_up:
                         * (Do the reset outside of interrupt context). */
                        adapter->tx_timeout_count++;
                        schedule_work(&adapter->reset_task);
+                       /* return immediately since reset is imminent */
+                       return;
                }
        }
 
@@ -2895,13 +2896,13 @@ static void igb_set_itr(struct igb_adapter *adapter)
        switch (current_itr) {
        /* counts and packets in update_itr are dependent on these numbers */
        case lowest_latency:
-               new_itr = 70000;
+               new_itr = 56;  /* aka 70,000 ints/sec */
                break;
        case low_latency:
-               new_itr = 20000; /* aka hwitr = ~200 */
+               new_itr = 196; /* aka 20,000 ints/sec */
                break;
        case bulk_latency:
-               new_itr = 4000;
+               new_itr = 980; /* aka 4,000 ints/sec */
                break;
        default:
                break;
@@ -2920,7 +2921,8 @@ set_itr_now:
                 * by adding intermediate steps when interrupt rate is
                 * increasing */
                new_itr = new_itr > adapter->itr ?
-                            min(adapter->itr + (new_itr >> 2), new_itr) :
+                            max((new_itr * adapter->itr) /
+                                (new_itr + (adapter->itr >> 2)), new_itr) :
                             new_itr;
                /* Don't write the value here; it resets the adapter's
                 * internal timer, and causes us to delay far longer than
@@ -2929,7 +2931,7 @@ set_itr_now:
                 * ends up being correct.
                 */
                adapter->itr = new_itr;
-               adapter->rx_ring->itr_val = 1000000000 / (new_itr * 256);
+               adapter->rx_ring->itr_val = new_itr;
                adapter->rx_ring->set_itr = 1;
        }
 
@@ -3068,11 +3070,15 @@ static inline bool igb_tx_csum_adv(struct igb_adapter *adapter,
                                tu_cmd |= E1000_ADVTXD_TUCMD_IPV4;
                                if (ip_hdr(skb)->protocol == IPPROTO_TCP)
                                        tu_cmd |= E1000_ADVTXD_TUCMD_L4T_TCP;
+                               else if (ip_hdr(skb)->protocol == IPPROTO_SCTP)
+                                       tu_cmd |= E1000_ADVTXD_TUCMD_L4T_SCTP;
                                break;
                        case cpu_to_be16(ETH_P_IPV6):
                                /* XXX what about other V6 headers?? */
                                if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP)
                                        tu_cmd |= E1000_ADVTXD_TUCMD_L4T_TCP;
+                               else if (ipv6_hdr(skb)->nexthdr == IPPROTO_SCTP)
+                                       tu_cmd |= E1000_ADVTXD_TUCMD_L4T_SCTP;
                                break;
                        default:
                                if (unlikely(net_ratelimit()))
@@ -3133,8 +3139,7 @@ static inline int igb_tx_map_adv(struct igb_adapter *adapter,
        /* set time_stamp *before* dma to help avoid a possible race */
        buffer_info->time_stamp = jiffies;
        buffer_info->next_to_watch = i;
-       buffer_info->dma = map[count];
-       count++;
+       buffer_info->dma = skb_shinfo(skb)->dma_head;
 
        for (f = 0; f < skb_shinfo(skb)->nr_frags; f++) {
                struct skb_frag_struct *frag;
@@ -3158,7 +3163,7 @@ static inline int igb_tx_map_adv(struct igb_adapter *adapter,
        tx_ring->buffer_info[i].skb = skb;
        tx_ring->buffer_info[first].next_to_watch = i;
 
-       return count;
+       return count + 1;
 }
 
 static inline void igb_tx_queue_adv(struct igb_adapter *adapter,
@@ -3338,7 +3343,6 @@ static int igb_xmit_frame_ring_adv(struct sk_buff *skb,
        if (count) {
                igb_tx_queue_adv(adapter, tx_ring, tx_flags, count,
                                 skb->len, hdr_len);
-               netdev->trans_start = jiffies;
                /* Make sure there is space in the ring for the next send. */
                igb_maybe_stop_tx(netdev, tx_ring, MAX_SKB_FRAGS + 4);
        } else {
@@ -3582,8 +3586,35 @@ void igb_update_stats(struct igb_adapter *adapter)
 
        /* Rx Errors */
 
+       if (hw->mac.type != e1000_82575) {
+               u32 rqdpc_tmp;
+               u64 rqdpc_total = 0;
+               int i;
+               /* Read out drops stats per RX queue.  Notice RQDPC (Receive
+                * Queue Drop Packet Count) stats only gets incremented, if
+                * the DROP_EN but it set (in the SRRCTL register for that
+                * queue).  If DROP_EN bit is NOT set, then the some what
+                * equivalent count is stored in RNBC (not per queue basis).
+                * Also note the drop count is due to lack of available
+                * descriptors.
+                */
+               for (i = 0; i < adapter->num_rx_queues; i++) {
+                       rqdpc_tmp = rd32(E1000_RQDPC(i)) & 0xFFF;
+                       adapter->rx_ring[i].rx_stats.drops += rqdpc_tmp;
+                       rqdpc_total += adapter->rx_ring[i].rx_stats.drops;
+               }
+               adapter->net_stats.rx_fifo_errors = rqdpc_total;
+       }
+
+       /* Note RNBC (Receive No Buffers Count) is an not an exact
+        * drop count as the hardware FIFO might save the day.  Thats
+        * one of the reason for saving it in rx_fifo_errors, as its
+        * potentially not a true drop.
+        */
+       adapter->net_stats.rx_fifo_errors += adapter->stats.rnbc;
+
        /* RLEC on some newer hardware can be incorrect so build
-       * our own version based on RUC and ROC */
+        * our own version based on RUC and ROC */
        adapter->net_stats.rx_errors = adapter->stats.rxerrc +
                adapter->stats.crcerrs + adapter->stats.algnerrc +
                adapter->stats.ruc + adapter->stats.roc +
@@ -3767,11 +3798,15 @@ static void igb_update_tx_dca(struct igb_ring *tx_ring)
 
 static void igb_setup_dca(struct igb_adapter *adapter)
 {
+       struct e1000_hw *hw = &adapter->hw;
        int i;
 
        if (!(adapter->flags & IGB_FLAG_DCA_ENABLED))
                return;
 
+       /* Always use CB2 mode, difference is masked in the CB driver. */
+       wr32(E1000_DCA_CTRL, E1000_DCA_CTRL_DCA_MODE_CB2);
+
        for (i = 0; i < adapter->num_tx_queues; i++) {
                adapter->tx_ring[i].cpu = -1;
                igb_update_tx_dca(&adapter->tx_ring[i]);
@@ -4434,20 +4469,12 @@ static void igb_receive_skb(struct igb_ring *ring, u8 status,
        bool vlan_extracted = (adapter->vlgrp && (status & E1000_RXD_STAT_VP));
 
        skb_record_rx_queue(skb, ring->queue_index);
-       if (skb->ip_summed == CHECKSUM_UNNECESSARY) {
-               if (vlan_extracted)
-                       vlan_gro_receive(&ring->napi, adapter->vlgrp,
-                                        le16_to_cpu(rx_desc->wb.upper.vlan),
-                                        skb);
-               else
-                       napi_gro_receive(&ring->napi, skb);
-       } else {
-               if (vlan_extracted)
-                       vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
-                                         le16_to_cpu(rx_desc->wb.upper.vlan));
-               else
-                       netif_receive_skb(skb);
-       }
+       if (vlan_extracted)
+               vlan_gro_receive(&ring->napi, adapter->vlgrp,
+                                le16_to_cpu(rx_desc->wb.upper.vlan),
+                                skb);
+       else
+               napi_gro_receive(&ring->napi, skb);
 }
 
 static inline void igb_rx_checksum_adv(struct igb_adapter *adapter,
@@ -4456,19 +4483,28 @@ static inline void igb_rx_checksum_adv(struct igb_adapter *adapter,
        skb->ip_summed = CHECKSUM_NONE;
 
        /* Ignore Checksum bit is set or checksum is disabled through ethtool */
-       if ((status_err & E1000_RXD_STAT_IXSM) || !adapter->rx_csum)
+       if ((status_err & E1000_RXD_STAT_IXSM) ||
+           (adapter->flags & IGB_FLAG_RX_CSUM_DISABLED))
                return;
        /* TCP/UDP checksum error bit is set */
        if (status_err &
            (E1000_RXDEXT_STATERR_TCPE | E1000_RXDEXT_STATERR_IPE)) {
+               /*
+                * work around errata with sctp packets where the TCPE aka
+                * L4E bit is set incorrectly on 64 byte (60 byte w/o crc)
+                * packets, (aka let the stack check the crc32c)
+                */
+               if (!((adapter->hw.mac.type == e1000_82576) &&
+                     (skb->len == 60)))
+                       adapter->hw_csum_err++;
                /* let the stack verify checksum errors */
-               adapter->hw_csum_err++;
                return;
        }
        /* It must be a TCP or UDP packet with a valid checksum */
        if (status_err & (E1000_RXD_STAT_TCPCS | E1000_RXD_STAT_UDPCS))
                skb->ip_summed = CHECKSUM_UNNECESSARY;
 
+       dev_dbg(&adapter->pdev->dev, "cksum success: bits %08X\n", status_err);
        adapter->hw_csum_good++;
 }
 
index 1dcaa69053120d26ecd1a30801b685475d9dcfa9..ee17a097d1ca91929f4ab405d6a9b81a02a14498 100644 (file)
@@ -133,6 +133,24 @@ static int igbvf_set_pauseparam(struct net_device *netdev,
        return -EOPNOTSUPP;
 }
 
+static u32 igbvf_get_rx_csum(struct net_device *netdev)
+{
+       struct igbvf_adapter *adapter = netdev_priv(netdev);
+       return !(adapter->flags & IGBVF_FLAG_RX_CSUM_DISABLED);
+}
+
+static int igbvf_set_rx_csum(struct net_device *netdev, u32 data)
+{
+       struct igbvf_adapter *adapter = netdev_priv(netdev);
+
+       if (data)
+               adapter->flags &= ~IGBVF_FLAG_RX_CSUM_DISABLED;
+       else
+               adapter->flags |= IGBVF_FLAG_RX_CSUM_DISABLED;
+
+       return 0;
+}
+
 static u32 igbvf_get_tx_csum(struct net_device *netdev)
 {
        return ((netdev->features & NETIF_F_IP_CSUM) != 0);
@@ -150,8 +168,6 @@ static int igbvf_set_tx_csum(struct net_device *netdev, u32 data)
 static int igbvf_set_tso(struct net_device *netdev, u32 data)
 {
        struct igbvf_adapter *adapter = netdev_priv(netdev);
-       int i;
-       struct net_device *v_netdev;
 
        if (data) {
                netdev->features |= NETIF_F_TSO;
@@ -159,24 +175,10 @@ static int igbvf_set_tso(struct net_device *netdev, u32 data)
        } else {
                netdev->features &= ~NETIF_F_TSO;
                netdev->features &= ~NETIF_F_TSO6;
-               /* disable TSO on all VLANs if they're present */
-               if (!adapter->vlgrp)
-                       goto tso_out;
-               for (i = 0; i < VLAN_GROUP_ARRAY_LEN; i++) {
-                       v_netdev = vlan_group_get_device(adapter->vlgrp, i);
-                       if (!v_netdev)
-                               continue;
-
-                       v_netdev->features &= ~NETIF_F_TSO;
-                       v_netdev->features &= ~NETIF_F_TSO6;
-                       vlan_group_set_device(adapter->vlgrp, i, v_netdev);
-               }
        }
 
-tso_out:
        dev_info(&adapter->pdev->dev, "TSO is %s\n",
                 data ? "Enabled" : "Disabled");
-       adapter->flags |= FLAG_TSO_FORCE;
        return 0;
 }
 
@@ -517,6 +519,8 @@ static const struct ethtool_ops igbvf_ethtool_ops = {
        .set_ringparam          = igbvf_set_ringparam,
        .get_pauseparam         = igbvf_get_pauseparam,
        .set_pauseparam         = igbvf_set_pauseparam,
+       .get_rx_csum            = igbvf_get_rx_csum,
+       .set_rx_csum            = igbvf_set_rx_csum,
        .get_tx_csum            = igbvf_get_tx_csum,
        .set_tx_csum            = igbvf_set_tx_csum,
        .get_sg                 = ethtool_op_get_sg,
index d488733893a6e011dada7b47270c78b3459a26f4..8e9b67ebbf8b49f888112af4fd242733489ec3c7 100644 (file)
@@ -286,11 +286,7 @@ struct igbvf_info {
 };
 
 /* hardware capability, feature, and workaround flags */
-#define FLAG_HAS_HW_VLAN_FILTER           (1 << 0)
-#define FLAG_HAS_JUMBO_FRAMES             (1 << 1)
-#define FLAG_MSI_ENABLED                  (1 << 2)
-#define FLAG_RX_CSUM_ENABLED              (1 << 3)
-#define FLAG_TSO_FORCE                    (1 << 4)
+#define IGBVF_FLAG_RX_CSUM_DISABLED             (1 << 0)
 
 #define IGBVF_RX_DESC_ADV(R, i)     \
        (&((((R).desc))[i].rx_desc))
index b774666ad3cf29a2df5fe62a20b0b8be2e2508e3..22aadb7884fa9ac028a4f1dc60d4aa3014c86c26 100644 (file)
@@ -58,8 +58,7 @@ static void igbvf_reset_interrupt_capability(struct igbvf_adapter *);
 
 static struct igbvf_info igbvf_vf_info = {
        .mac                    = e1000_vfadapt,
-       .flags                  = FLAG_HAS_JUMBO_FRAMES
-                                 | FLAG_RX_CSUM_ENABLED,
+       .flags                  = 0,
        .pba                    = 10,
        .init_ops               = e1000_init_function_pointers_vf,
 };
@@ -107,8 +106,10 @@ static inline void igbvf_rx_checksum_adv(struct igbvf_adapter *adapter,
        skb->ip_summed = CHECKSUM_NONE;
 
        /* Ignore Checksum bit is set or checksum is disabled through ethtool */
-       if ((status_err & E1000_RXD_STAT_IXSM))
+       if ((status_err & E1000_RXD_STAT_IXSM) ||
+           (adapter->flags & IGBVF_FLAG_RX_CSUM_DISABLED))
                return;
+
        /* TCP/UDP checksum error bit is set */
        if (status_err &
            (E1000_RXDEXT_STATERR_TCPE | E1000_RXDEXT_STATERR_IPE)) {
@@ -116,6 +117,7 @@ static inline void igbvf_rx_checksum_adv(struct igbvf_adapter *adapter,
                adapter->hw_csum_err++;
                return;
        }
+
        /* It must be a TCP or UDP packet with a valid checksum */
        if (status_err & (E1000_RXD_STAT_TCPCS | E1000_RXD_STAT_UDPCS))
                skb->ip_summed = CHECKSUM_UNNECESSARY;
@@ -2117,8 +2119,7 @@ static inline int igbvf_tx_map_adv(struct igbvf_adapter *adapter,
        /* set time_stamp *before* dma to help avoid a possible race */
        buffer_info->time_stamp = jiffies;
        buffer_info->next_to_watch = i;
-       buffer_info->dma = map[count];
-       count++;
+       buffer_info->dma = skb_shinfo(skb)->dma_head;
 
        for (f = 0; f < skb_shinfo(skb)->nr_frags; f++) {
                struct skb_frag_struct *frag;
@@ -2142,7 +2143,7 @@ static inline int igbvf_tx_map_adv(struct igbvf_adapter *adapter,
        tx_ring->buffer_info[i].skb = skb;
        tx_ring->buffer_info[first].next_to_watch = i;
 
-       return count;
+       return count + 1;
 }
 
 static inline void igbvf_tx_queue_adv(struct igbvf_adapter *adapter,
@@ -2268,7 +2269,6 @@ static int igbvf_xmit_frame_ring_adv(struct sk_buff *skb,
        if (count) {
                igbvf_tx_queue_adv(adapter, tx_ring, tx_flags, count,
                                   skb->len, hdr_len);
-               netdev->trans_start = jiffies;
                /* Make sure there is space in the ring for the next send. */
                igbvf_maybe_stop_tx(netdev, MAX_SKB_FRAGS + 4);
        } else {
@@ -2351,15 +2351,6 @@ static int igbvf_change_mtu(struct net_device *netdev, int new_mtu)
                return -EINVAL;
        }
 
-       /* Jumbo frame size limits */
-       if (max_frame > ETH_FRAME_LEN + ETH_FCS_LEN) {
-               if (!(adapter->flags & FLAG_HAS_JUMBO_FRAMES)) {
-                       dev_err(&adapter->pdev->dev,
-                               "Jumbo Frames not supported.\n");
-                       return -EINVAL;
-               }
-       }
-
 #define MAX_STD_JUMBO_FRAME_SIZE 9234
        if (max_frame > MAX_STD_JUMBO_FRAME_SIZE) {
                dev_err(&adapter->pdev->dev, "MTU > 9216 not supported.\n");
index c5593f4665a4ea6ffae45c793f4869a5f4c57ec5..e3cfefab670c8b4fb3f4eaf5cc51d243466639a0 100644 (file)
@@ -530,7 +530,7 @@ static void ioc3_tcpudp_checksum(struct sk_buff *skb, uint32_t hwsum, int len)
         *   case where the checksum is right the higher layers will still
         *   drop the packet as appropriate.
         */
-       if (eh->h_proto != ntohs(ETH_P_IP))
+       if (eh->h_proto != htons(ETH_P_IP))
                return;
 
        ih = (struct iphdr *) ((char *)eh + ETH_HLEN);
index e6317557a531e342d516f02ba8daa8bf360b2753..f76384221422ce1ef32005b20d379c0b7b4f8a1f 100644 (file)
@@ -17,6 +17,51 @@ config IRTTY_SIR
 
          If unsure, say Y.
 
+config BFIN_SIR
+       tristate "Blackfin SIR on UART"
+       depends on BLACKFIN && IRDA
+       default n
+       help
+         Say Y here if your want to enable SIR function on Blackfin UART
+         devices.
+
+         To activate this driver you can start irattach like:
+         "irattach irda0 -s"
+
+         Saying M, it will be built as a module named bfin_sir.
+
+         Note that you need to turn off one of the serial drivers for SIR
+         to use that UART.
+
+config BFIN_SIR0
+       bool "Blackfin SIR on UART0"
+       depends on BFIN_SIR && !SERIAL_BFIN_UART0
+
+config BFIN_SIR1
+       bool "Blackfin SIR on UART1"
+       depends on BFIN_SIR && !SERIAL_BFIN_UART1 && (!BF531 && !BF532 && !BF533 && !BF561)
+
+config BFIN_SIR2
+       bool "Blackfin SIR on UART2"
+       depends on BFIN_SIR && !SERIAL_BFIN_UART2 && (BF54x || BF538 || BF539)
+
+config BFIN_SIR3
+       bool "Blackfin SIR on UART3"
+       depends on BFIN_SIR && !SERIAL_BFIN_UART3 && (BF54x)
+
+choice
+       prompt "SIR Mode"
+       depends on BFIN_SIR
+       default SIR_BFIN_DMA
+
+config SIR_BFIN_DMA
+       bool "DMA mode"
+       depends on !DMA_UNCACHED_NONE
+
+config SIR_BFIN_PIO
+       bool "PIO mode"
+endchoice
+
 comment "Dongle support"
 
 config DONGLE
index 5d20fde32a246fd41081594e6559239b60c4bf23..d82e1e3bd8c8f401471f995ab3da4873b2b7b88a 100644 (file)
@@ -21,6 +21,7 @@ obj-$(CONFIG_MCS_FIR)         += mcs7780.o
 obj-$(CONFIG_AU1000_FIR)       += au1k_ir.o
 # SIR drivers
 obj-$(CONFIG_IRTTY_SIR)                += irtty-sir.o  sir-dev.o
+obj-$(CONFIG_BFIN_SIR)         += bfin_sir.o
 # dongle drivers for SIR drivers
 obj-$(CONFIG_ESI_DONGLE)       += esi-sir.o
 obj-$(CONFIG_TEKRAM_DONGLE)    += tekram-sir.o
index 941164076a2b1f675b68b492be4c206549308841..c4361d466597c50963c9a0dc594c6cd3b3e41b7e 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/init.h>
 #include <linux/errno.h>
 #include <linux/netdevice.h>
+#include <linux/etherdevice.h>
 #include <linux/slab.h>
 #include <linux/rtnetlink.h>
 #include <linux/interrupt.h>
@@ -198,6 +199,17 @@ static int au1k_irda_init_iobuf(iobuff_t *io, int size)
        return io->head ? 0 : -ENOMEM;
 }
 
+static const struct net_device_ops au1k_irda_netdev_ops = {
+       .ndo_open               = au1k_irda_start,
+       .ndo_stop               = au1k_irda_stop,
+       .ndo_start_xmit         = au1k_irda_hard_xmit,
+       .ndo_tx_timeout         = au1k_tx_timeout,
+       .ndo_do_ioctl           = au1k_irda_ioctl,
+       .ndo_change_mtu         = eth_change_mtu,
+       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_set_mac_address    = eth_mac_addr,
+};
+
 static int au1k_irda_net_init(struct net_device *dev)
 {
        struct au1k_private *aup = netdev_priv(dev);
@@ -209,11 +221,7 @@ static int au1k_irda_net_init(struct net_device *dev)
        if (err)
                goto out1;
 
-       dev->open = au1k_irda_start;
-       dev->hard_start_xmit = au1k_irda_hard_xmit;
-       dev->stop = au1k_irda_stop;
-       dev->do_ioctl = au1k_irda_ioctl;
-       dev->tx_timeout = au1k_tx_timeout;
+       dev->netdev_ops = &au1k_irda_netdev_ops;
 
        irda_init_max_qos_capabilies(&aup->qos);
 
@@ -504,13 +512,13 @@ static int au1k_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev)
                printk(KERN_DEBUG "%s: tx_full\n", dev->name);
                netif_stop_queue(dev);
                aup->tx_full = 1;
-               return 1;
+               return NETDEV_TX_BUSY;
        }
        else if (((aup->tx_head + 1) & (NUM_IR_DESC - 1)) == aup->tx_tail) {
                printk(KERN_DEBUG "%s: tx_full\n", dev->name);
                netif_stop_queue(dev);
                aup->tx_full = 1;
-               return 1;
+               return NETDEV_TX_BUSY;
        }
 
        pDB = aup->tx_db_inuse[aup->tx_head];
diff --git a/drivers/net/irda/bfin_sir.c b/drivers/net/irda/bfin_sir.c
new file mode 100644 (file)
index 0000000..f3eed6a
--- /dev/null
@@ -0,0 +1,820 @@
+/*
+ * Blackfin Infra-red Driver
+ *
+ * Copyright 2006-2009 Analog Devices Inc.
+ *
+ * Enter bugs at http://blackfin.uclinux.org/
+ *
+ * Licensed under the GPL-2 or later.
+ *
+ */
+#include "bfin_sir.h"
+
+#ifdef CONFIG_SIR_BFIN_DMA
+#define DMA_SIR_RX_XCNT        10
+#define DMA_SIR_RX_YCNT        (PAGE_SIZE / DMA_SIR_RX_XCNT)
+#define DMA_SIR_RX_FLUSH_JIFS  (HZ * 4 / 250)
+#endif
+
+#if ANOMALY_05000447
+static int max_rate = 57600;
+#else
+static int max_rate = 115200;
+#endif
+
+static void turnaround_delay(unsigned long last_jif, int mtt)
+{
+       long ticks;
+
+       mtt = mtt < 10000 ? 10000 : mtt;
+       ticks = 1 + mtt / (USEC_PER_SEC / HZ);
+       schedule_timeout_uninterruptible(ticks);
+}
+
+static void __devinit bfin_sir_init_ports(struct bfin_sir_port *sp, struct platform_device *pdev)
+{
+       int i;
+       struct resource *res;
+
+       for (i = 0; i < pdev->num_resources; i++) {
+               res = &pdev->resource[i];
+               switch (res->flags) {
+               case IORESOURCE_MEM:
+                       sp->membase   = (void __iomem *)res->start;
+                       break;
+               case IORESOURCE_IRQ:
+                       sp->irq = res->start;
+                       break;
+               case IORESOURCE_DMA:
+                       sp->rx_dma_channel = res->start;
+                       sp->tx_dma_channel = res->end;
+                       break;
+               default:
+                       break;
+               }
+       }
+
+       sp->clk = get_sclk();
+#ifdef CONFIG_SIR_BFIN_DMA
+       sp->tx_done        = 1;
+       init_timer(&(sp->rx_dma_timer));
+#endif
+}
+
+static void bfin_sir_stop_tx(struct bfin_sir_port *port)
+{
+#ifdef CONFIG_SIR_BFIN_DMA
+       disable_dma(port->tx_dma_channel);
+#endif
+
+       while (!(SIR_UART_GET_LSR(port) & THRE)) {
+               cpu_relax();
+               continue;
+       }
+
+       SIR_UART_STOP_TX(port);
+}
+
+static void bfin_sir_enable_tx(struct bfin_sir_port *port)
+{
+       SIR_UART_ENABLE_TX(port);
+}
+
+static void bfin_sir_stop_rx(struct bfin_sir_port *port)
+{
+       SIR_UART_STOP_RX(port);
+}
+
+static void bfin_sir_enable_rx(struct bfin_sir_port *port)
+{
+       SIR_UART_ENABLE_RX(port);
+}
+
+static int bfin_sir_set_speed(struct bfin_sir_port *port, int speed)
+{
+       int ret = -EINVAL;
+       unsigned int quot;
+       unsigned short val, lsr, lcr;
+       static int utime;
+       int count = 10;
+
+       lcr = WLS(8);
+
+       switch (speed) {
+       case 9600:
+       case 19200:
+       case 38400:
+       case 57600:
+       case 115200:
+
+               quot = (port->clk + (8 * speed)) / (16 * speed)\
+                                               - ANOMALY_05000230;
+
+               do {
+                       udelay(utime);
+                       lsr = SIR_UART_GET_LSR(port);
+               } while (!(lsr & TEMT) && count--);
+
+               /* The useconds for 1 bits to transmit */
+               utime = 1000000 / speed + 1;
+
+               /* Clear UCEN bit to reset the UART state machine
+                * and control registers
+                */
+               val = SIR_UART_GET_GCTL(port);
+               val &= ~UCEN;
+               SIR_UART_PUT_GCTL(port, val);
+
+               /* Set DLAB in LCR to Access THR RBR IER */
+               SIR_UART_SET_DLAB(port);
+               SSYNC();
+
+               SIR_UART_PUT_DLL(port, quot & 0xFF);
+               SIR_UART_PUT_DLH(port, (quot >> 8) & 0xFF);
+               SSYNC();
+
+               /* Clear DLAB in LCR */
+               SIR_UART_CLEAR_DLAB(port);
+               SSYNC();
+
+               SIR_UART_PUT_LCR(port, lcr);
+
+               val = SIR_UART_GET_GCTL(port);
+               val |= UCEN;
+               SIR_UART_PUT_GCTL(port, val);
+
+               ret = 0;
+               break;
+       default:
+               printk(KERN_WARNING "bfin_sir: Invalid speed %d\n", speed);
+               break;
+       }
+
+       val = SIR_UART_GET_GCTL(port);
+       /* If not add the 'RPOLC', we can't catch the receive interrupt.
+        * It's related with the HW layout and the IR transiver.
+        */
+       val |= IREN | RPOLC;
+       SIR_UART_PUT_GCTL(port, val);
+       return ret;
+}
+
+static int bfin_sir_is_receiving(struct net_device *dev)
+{
+       struct bfin_sir_self *self = netdev_priv(dev);
+       struct bfin_sir_port *port = self->sir_port;
+
+       if (!(SIR_UART_GET_IER(port) & ERBFI))
+               return 0;
+       return self->rx_buff.state != OUTSIDE_FRAME;
+}
+
+#ifdef CONFIG_SIR_BFIN_PIO
+static void bfin_sir_tx_chars(struct net_device *dev)
+{
+       unsigned int chr;
+       struct bfin_sir_self *self = netdev_priv(dev);
+       struct bfin_sir_port *port = self->sir_port;
+
+       if (self->tx_buff.len != 0) {
+               chr = *(self->tx_buff.data);
+               SIR_UART_PUT_CHAR(port, chr);
+               self->tx_buff.data++;
+               self->tx_buff.len--;
+       } else {
+               self->stats.tx_packets++;
+               self->stats.tx_bytes += self->tx_buff.data - self->tx_buff.head;
+               if (self->newspeed) {
+                       bfin_sir_set_speed(port, self->newspeed);
+                       self->speed = self->newspeed;
+                       self->newspeed = 0;
+               }
+               bfin_sir_stop_tx(port);
+               bfin_sir_enable_rx(port);
+               /* I'm hungry! */
+               netif_wake_queue(dev);
+       }
+}
+
+static void bfin_sir_rx_chars(struct net_device *dev)
+{
+       struct bfin_sir_self *self = netdev_priv(dev);
+       struct bfin_sir_port *port = self->sir_port;
+       unsigned char ch;
+
+       SIR_UART_CLEAR_LSR(port);
+       ch = SIR_UART_GET_CHAR(port);
+       async_unwrap_char(dev, &self->stats, &self->rx_buff, ch);
+       dev->last_rx = jiffies;
+}
+
+static irqreturn_t bfin_sir_rx_int(int irq, void *dev_id)
+{
+       struct net_device *dev = dev_id;
+       struct bfin_sir_self *self = netdev_priv(dev);
+       struct bfin_sir_port *port = self->sir_port;
+
+       spin_lock(&self->lock);
+       while ((SIR_UART_GET_LSR(port) & DR))
+               bfin_sir_rx_chars(dev);
+       spin_unlock(&self->lock);
+
+       return IRQ_HANDLED;
+}
+
+static irqreturn_t bfin_sir_tx_int(int irq, void *dev_id)
+{
+       struct net_device *dev = dev_id;
+       struct bfin_sir_self *self = netdev_priv(dev);
+       struct bfin_sir_port *port = self->sir_port;
+
+       spin_lock(&self->lock);
+       if (SIR_UART_GET_LSR(port) & THRE)
+               bfin_sir_tx_chars(dev);
+       spin_unlock(&self->lock);
+
+       return IRQ_HANDLED;
+}
+#endif /* CONFIG_SIR_BFIN_PIO */
+
+#ifdef CONFIG_SIR_BFIN_DMA
+static void bfin_sir_dma_tx_chars(struct net_device *dev)
+{
+       struct bfin_sir_self *self = netdev_priv(dev);
+       struct bfin_sir_port *port = self->sir_port;
+
+       if (!port->tx_done)
+               return;
+       port->tx_done = 0;
+
+       if (self->tx_buff.len == 0) {
+               self->stats.tx_packets++;
+               if (self->newspeed) {
+                       bfin_sir_set_speed(port, self->newspeed);
+                       self->speed = self->newspeed;
+                       self->newspeed = 0;
+               }
+               bfin_sir_enable_rx(port);
+               port->tx_done = 1;
+               netif_wake_queue(dev);
+               return;
+       }
+
+       blackfin_dcache_flush_range((unsigned long)(self->tx_buff.data),
+               (unsigned long)(self->tx_buff.data+self->tx_buff.len));
+       set_dma_config(port->tx_dma_channel,
+               set_bfin_dma_config(DIR_READ, DMA_FLOW_STOP,
+                       INTR_ON_BUF, DIMENSION_LINEAR, DATA_SIZE_8,
+                       DMA_SYNC_RESTART));
+       set_dma_start_addr(port->tx_dma_channel,
+               (unsigned long)(self->tx_buff.data));
+       set_dma_x_count(port->tx_dma_channel, self->tx_buff.len);
+       set_dma_x_modify(port->tx_dma_channel, 1);
+       enable_dma(port->tx_dma_channel);
+}
+
+static irqreturn_t bfin_sir_dma_tx_int(int irq, void *dev_id)
+{
+       struct net_device *dev = dev_id;
+       struct bfin_sir_self *self = netdev_priv(dev);
+       struct bfin_sir_port *port = self->sir_port;
+
+       spin_lock(&self->lock);
+       if (!(get_dma_curr_irqstat(port->tx_dma_channel) & DMA_RUN)) {
+               clear_dma_irqstat(port->tx_dma_channel);
+               bfin_sir_stop_tx(port);
+
+               self->stats.tx_packets++;
+               self->stats.tx_bytes += self->tx_buff.len;
+               self->tx_buff.len = 0;
+               if (self->newspeed) {
+                       bfin_sir_set_speed(port, self->newspeed);
+                       self->speed = self->newspeed;
+                       self->newspeed = 0;
+               }
+               bfin_sir_enable_rx(port);
+               /* I'm hungry! */
+               netif_wake_queue(dev);
+               port->tx_done = 1;
+       }
+       spin_unlock(&self->lock);
+
+       return IRQ_HANDLED;
+}
+
+static void bfin_sir_dma_rx_chars(struct net_device *dev)
+{
+       struct bfin_sir_self *self = netdev_priv(dev);
+       struct bfin_sir_port *port = self->sir_port;
+       int i;
+
+       SIR_UART_CLEAR_LSR(port);
+
+       for (i = port->rx_dma_buf.head; i < port->rx_dma_buf.tail; i++)
+               async_unwrap_char(dev, &self->stats, &self->rx_buff, port->rx_dma_buf.buf[i]);
+}
+
+void bfin_sir_rx_dma_timeout(struct net_device *dev)
+{
+       struct bfin_sir_self *self = netdev_priv(dev);
+       struct bfin_sir_port *port = self->sir_port;
+       int x_pos, pos;
+       unsigned long flags;
+
+       spin_lock_irqsave(&self->lock, flags);
+       x_pos = DMA_SIR_RX_XCNT - get_dma_curr_xcount(port->rx_dma_channel);
+       if (x_pos == DMA_SIR_RX_XCNT)
+               x_pos = 0;
+
+       pos = port->rx_dma_nrows * DMA_SIR_RX_XCNT + x_pos;
+
+       if (pos > port->rx_dma_buf.tail) {
+               port->rx_dma_buf.tail = pos;
+               bfin_sir_dma_rx_chars(dev);
+               port->rx_dma_buf.head = port->rx_dma_buf.tail;
+       }
+       spin_unlock_irqrestore(&self->lock, flags);
+}
+
+static irqreturn_t bfin_sir_dma_rx_int(int irq, void *dev_id)
+{
+       struct net_device *dev = dev_id;
+       struct bfin_sir_self *self = netdev_priv(dev);
+       struct bfin_sir_port *port = self->sir_port;
+       unsigned short irqstat;
+
+       spin_lock(&self->lock);
+
+       port->rx_dma_nrows++;
+       port->rx_dma_buf.tail = DMA_SIR_RX_XCNT * port->rx_dma_nrows;
+       bfin_sir_dma_rx_chars(dev);
+       if (port->rx_dma_nrows >= DMA_SIR_RX_YCNT) {
+               port->rx_dma_nrows = 0;
+               port->rx_dma_buf.tail = 0;
+       }
+       port->rx_dma_buf.head = port->rx_dma_buf.tail;
+
+       irqstat = get_dma_curr_irqstat(port->rx_dma_channel);
+       clear_dma_irqstat(port->rx_dma_channel);
+       spin_unlock(&self->lock);
+
+       mod_timer(&port->rx_dma_timer, jiffies + DMA_SIR_RX_FLUSH_JIFS);
+       return IRQ_HANDLED;
+}
+#endif /* CONFIG_SIR_BFIN_DMA */
+
+static int bfin_sir_startup(struct bfin_sir_port *port, struct net_device *dev)
+{
+#ifdef CONFIG_SIR_BFIN_DMA
+       dma_addr_t dma_handle;
+#endif /* CONFIG_SIR_BFIN_DMA */
+
+       if (request_dma(port->rx_dma_channel, "BFIN_UART_RX") < 0) {
+               dev_warn(&dev->dev, "Unable to attach SIR RX DMA channel\n");
+               return -EBUSY;
+       }
+
+       if (request_dma(port->tx_dma_channel, "BFIN_UART_TX") < 0) {
+               dev_warn(&dev->dev, "Unable to attach SIR TX DMA channel\n");
+               free_dma(port->rx_dma_channel);
+               return -EBUSY;
+       }
+
+#ifdef CONFIG_SIR_BFIN_DMA
+
+       set_dma_callback(port->rx_dma_channel, bfin_sir_dma_rx_int, dev);
+       set_dma_callback(port->tx_dma_channel, bfin_sir_dma_tx_int, dev);
+
+       port->rx_dma_buf.buf = (unsigned char *)dma_alloc_coherent(NULL, PAGE_SIZE, &dma_handle, GFP_DMA);
+       port->rx_dma_buf.head = 0;
+       port->rx_dma_buf.tail = 0;
+       port->rx_dma_nrows = 0;
+
+       set_dma_config(port->rx_dma_channel,
+                               set_bfin_dma_config(DIR_WRITE, DMA_FLOW_AUTO,
+                                                                       INTR_ON_ROW, DIMENSION_2D,
+                                                                       DATA_SIZE_8, DMA_SYNC_RESTART));
+       set_dma_x_count(port->rx_dma_channel, DMA_SIR_RX_XCNT);
+       set_dma_x_modify(port->rx_dma_channel, 1);
+       set_dma_y_count(port->rx_dma_channel, DMA_SIR_RX_YCNT);
+       set_dma_y_modify(port->rx_dma_channel, 1);
+       set_dma_start_addr(port->rx_dma_channel, (unsigned long)port->rx_dma_buf.buf);
+       enable_dma(port->rx_dma_channel);
+
+       port->rx_dma_timer.data = (unsigned long)(dev);
+       port->rx_dma_timer.function = (void *)bfin_sir_rx_dma_timeout;
+
+#else
+
+       if (request_irq(port->irq, bfin_sir_rx_int, IRQF_DISABLED, "BFIN_SIR_RX", dev)) {
+               dev_warn(&dev->dev, "Unable to attach SIR RX interrupt\n");
+               return -EBUSY;
+       }
+
+       if (request_irq(port->irq+1, bfin_sir_tx_int, IRQF_DISABLED, "BFIN_SIR_TX", dev)) {
+               dev_warn(&dev->dev, "Unable to attach SIR TX interrupt\n");
+               free_irq(port->irq, dev);
+               return -EBUSY;
+       }
+#endif
+
+       return 0;
+}
+
+static void bfin_sir_shutdown(struct bfin_sir_port *port, struct net_device *dev)
+{
+       unsigned short val;
+
+       bfin_sir_stop_rx(port);
+       SIR_UART_DISABLE_INTS(port);
+
+       val = SIR_UART_GET_GCTL(port);
+       val &= ~(UCEN | IREN | RPOLC);
+       SIR_UART_PUT_GCTL(port, val);
+
+#ifdef CONFIG_SIR_BFIN_DMA
+       disable_dma(port->tx_dma_channel);
+       disable_dma(port->rx_dma_channel);
+       del_timer(&(port->rx_dma_timer));
+       dma_free_coherent(NULL, PAGE_SIZE, port->rx_dma_buf.buf, 0);
+#else
+       free_irq(port->irq+1, dev);
+       free_irq(port->irq, dev);
+#endif
+       free_dma(port->tx_dma_channel);
+       free_dma(port->rx_dma_channel);
+}
+
+#ifdef CONFIG_PM
+static int bfin_sir_suspend(struct platform_device *pdev, pm_message_t state)
+{
+       struct bfin_sir_port *sir_port;
+       struct net_device *dev;
+       struct bfin_sir_self *self;
+
+       sir_port = platform_get_drvdata(pdev);
+       if (!sir_port)
+               return 0;
+
+       dev = sir_port->dev;
+       self = netdev_priv(dev);
+       if (self->open) {
+               flush_work(&self->work);
+               bfin_sir_shutdown(self->sir_port, dev);
+               netif_device_detach(dev);
+       }
+
+       return 0;
+}
+static int bfin_sir_resume(struct platform_device *pdev)
+{
+       struct bfin_sir_port *sir_port;
+       struct net_device *dev;
+       struct bfin_sir_self *self;
+       struct bfin_sir_port *port;
+
+       sir_port = platform_get_drvdata(pdev);
+       if (!sir_port)
+               return 0;
+
+       dev = sir_port->dev;
+       self = netdev_priv(dev);
+       port = self->sir_port;
+       if (self->open) {
+               if (self->newspeed) {
+                       self->speed = self->newspeed;
+                       self->newspeed = 0;
+               }
+               bfin_sir_startup(port, dev);
+               bfin_sir_set_speed(port, 9600);
+               bfin_sir_enable_rx(port);
+               netif_device_attach(dev);
+       }
+       return 0;
+}
+#else
+#define bfin_sir_suspend   NULL
+#define bfin_sir_resume    NULL
+#endif
+
+static void bfin_sir_send_work(struct work_struct *work)
+{
+       struct bfin_sir_self  *self = container_of(work, struct bfin_sir_self, work);
+       struct net_device *dev = self->sir_port->dev;
+       struct bfin_sir_port *port = self->sir_port;
+       unsigned short val;
+       int tx_cnt = 10;
+
+       while (bfin_sir_is_receiving(dev) && --tx_cnt)
+               turnaround_delay(dev->last_rx, self->mtt);
+
+       bfin_sir_stop_rx(port);
+
+       /* To avoid losting RX interrupt, we reset IR function before
+        * sending data. We also can set the speed, which will
+        * reset all the UART.
+        */
+       val = SIR_UART_GET_GCTL(port);
+       val &= ~(IREN | RPOLC);
+       SIR_UART_PUT_GCTL(port, val);
+       SSYNC();
+       val |= IREN | RPOLC;
+       SIR_UART_PUT_GCTL(port, val);
+       SSYNC();
+       /* bfin_sir_set_speed(port, self->speed); */
+
+#ifdef CONFIG_SIR_BFIN_DMA
+       bfin_sir_dma_tx_chars(dev);
+#endif
+       bfin_sir_enable_tx(port);
+       dev->trans_start = jiffies;
+}
+
+static int bfin_sir_hard_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+       struct bfin_sir_self *self = netdev_priv(dev);
+       int speed = irda_get_next_speed(skb);
+
+       netif_stop_queue(dev);
+
+       self->mtt = irda_get_mtt(skb);
+
+       if (speed != self->speed && speed != -1)
+               self->newspeed = speed;
+
+       self->tx_buff.data = self->tx_buff.head;
+       if (skb->len == 0)
+               self->tx_buff.len = 0;
+       else
+               self->tx_buff.len = async_wrap_skb(skb, self->tx_buff.data, self->tx_buff.truesize);
+
+       schedule_work(&self->work);
+       dev_kfree_skb(skb);
+
+       return 0;
+}
+
+static int bfin_sir_ioctl(struct net_device *dev, struct ifreq *ifreq, int cmd)
+{
+       struct if_irda_req *rq = (struct if_irda_req *)ifreq;
+       struct bfin_sir_self *self = netdev_priv(dev);
+       struct bfin_sir_port *port = self->sir_port;
+       int ret = 0;
+
+       switch (cmd) {
+       case SIOCSBANDWIDTH:
+               if (capable(CAP_NET_ADMIN)) {
+                       if (self->open) {
+                               ret = bfin_sir_set_speed(port, rq->ifr_baudrate);
+                               bfin_sir_enable_rx(port);
+                       } else {
+                               dev_warn(&dev->dev, "SIOCSBANDWIDTH: !netif_running\n");
+                               ret = 0;
+                       }
+               }
+               break;
+
+       case SIOCSMEDIABUSY:
+               ret = -EPERM;
+               if (capable(CAP_NET_ADMIN)) {
+                       irda_device_set_media_busy(dev, TRUE);
+                       ret = 0;
+               }
+               break;
+
+       case SIOCGRECEIVING:
+               rq->ifr_receiving = bfin_sir_is_receiving(dev);
+               break;
+
+       default:
+               ret = -EOPNOTSUPP;
+               break;
+       }
+
+       return ret;
+}
+
+static struct net_device_stats *bfin_sir_stats(struct net_device *dev)
+{
+       struct bfin_sir_self *self = netdev_priv(dev);
+
+       return &self->stats;
+}
+
+static int bfin_sir_open(struct net_device *dev)
+{
+       struct bfin_sir_self *self = netdev_priv(dev);
+       struct bfin_sir_port *port = self->sir_port;
+       int err = -ENOMEM;
+
+       self->newspeed = 0;
+       self->speed = 9600;
+
+       spin_lock_init(&self->lock);
+
+       err = bfin_sir_startup(port, dev);
+       if (err)
+               goto err_startup;
+
+       bfin_sir_set_speed(port, 9600);
+
+       self->irlap = irlap_open(dev, &self->qos, DRIVER_NAME);
+       if (!self->irlap)
+               goto err_irlap;
+
+       INIT_WORK(&self->work, bfin_sir_send_work);
+
+       /*
+        * Now enable the interrupt then start the queue
+        */
+       self->open = 1;
+       bfin_sir_enable_rx(port);
+
+       netif_start_queue(dev);
+
+       return 0;
+
+err_irlap:
+       self->open = 0;
+       bfin_sir_shutdown(port, dev);
+err_startup:
+       return err;
+}
+
+static int bfin_sir_stop(struct net_device *dev)
+{
+       struct bfin_sir_self *self = netdev_priv(dev);
+
+       flush_work(&self->work);
+       bfin_sir_shutdown(self->sir_port, dev);
+
+       if (self->rxskb) {
+               dev_kfree_skb(self->rxskb);
+               self->rxskb = NULL;
+       }
+
+       /* Stop IrLAP */
+       if (self->irlap) {
+               irlap_close(self->irlap);
+               self->irlap = NULL;
+       }
+
+       netif_stop_queue(dev);
+       self->open = 0;
+
+       return 0;
+}
+
+static int bfin_sir_init_iobuf(iobuff_t *io, int size)
+{
+       io->head = kmalloc(size, GFP_KERNEL);
+       if (!io->head)
+               return -ENOMEM;
+       io->truesize = size;
+       io->in_frame = FALSE;
+       io->state    = OUTSIDE_FRAME;
+       io->data     = io->head;
+       return 0;
+}
+
+static int __devinit bfin_sir_probe(struct platform_device *pdev)
+{
+       struct net_device *dev;
+       struct bfin_sir_self *self;
+       unsigned int baudrate_mask;
+       struct bfin_sir_port *sir_port;
+       int err;
+
+       if (pdev->id >= 0 && pdev->id < ARRAY_SIZE(per) && \
+                               per[pdev->id][3] == pdev->id) {
+               err = peripheral_request_list(per[pdev->id], DRIVER_NAME);
+               if (err)
+                       return err;
+       } else {
+               dev_err(&pdev->dev, "Invalid pdev id, please check board file\n");
+               return -ENODEV;
+       }
+
+       err = -ENOMEM;
+       sir_port = kmalloc(sizeof(*sir_port), GFP_KERNEL);
+       if (!sir_port)
+               goto err_mem_0;
+
+       bfin_sir_init_ports(sir_port, pdev);
+
+       dev = alloc_irdadev(sizeof(*self));
+       if (!dev)
+               goto err_mem_1;
+
+       self = netdev_priv(dev);
+       self->dev = &pdev->dev;
+       self->sir_port = sir_port;
+       sir_port->dev = dev;
+
+       err = bfin_sir_init_iobuf(&self->rx_buff, IRDA_SKB_MAX_MTU);
+       if (err)
+               goto err_mem_2;
+       err = bfin_sir_init_iobuf(&self->tx_buff, IRDA_SIR_MAX_FRAME);
+       if (err)
+               goto err_mem_3;
+
+       dev->hard_start_xmit = bfin_sir_hard_xmit;
+       dev->open            = bfin_sir_open;
+       dev->stop            = bfin_sir_stop;
+       dev->do_ioctl        = bfin_sir_ioctl;
+       dev->get_stats       = bfin_sir_stats;
+       dev->irq             = sir_port->irq;
+
+       irda_init_max_qos_capabilies(&self->qos);
+
+       baudrate_mask = IR_9600;
+
+       switch (max_rate) {
+       case 115200:
+               baudrate_mask |= IR_115200;
+       case 57600:
+               baudrate_mask |= IR_57600;
+       case 38400:
+               baudrate_mask |= IR_38400;
+       case 19200:
+               baudrate_mask |= IR_19200;
+       case 9600:
+               break;
+       default:
+               dev_warn(&pdev->dev, "Invalid maximum baud rate, using 9600\n");
+       }
+
+       self->qos.baud_rate.bits &= baudrate_mask;
+
+       self->qos.min_turn_time.bits = 1; /* 10 ms or more */
+
+       irda_qos_bits_to_value(&self->qos);
+
+       err = register_netdev(dev);
+
+       if (err) {
+               kfree(self->tx_buff.head);
+err_mem_3:
+               kfree(self->rx_buff.head);
+err_mem_2:
+               free_netdev(dev);
+err_mem_1:
+               kfree(sir_port);
+err_mem_0:
+               peripheral_free_list(per[pdev->id]);
+       } else
+               platform_set_drvdata(pdev, sir_port);
+
+       return err;
+}
+
+static int __devexit bfin_sir_remove(struct platform_device *pdev)
+{
+       struct bfin_sir_port *sir_port;
+       struct net_device *dev = NULL;
+       struct bfin_sir_self *self;
+
+       sir_port = platform_get_drvdata(pdev);
+       if (!sir_port)
+               return 0;
+       dev = sir_port->dev;
+       self = netdev_priv(dev);
+       unregister_netdev(dev);
+       kfree(self->tx_buff.head);
+       kfree(self->rx_buff.head);
+       free_netdev(dev);
+       kfree(sir_port);
+       platform_set_drvdata(pdev, NULL);
+
+       return 0;
+}
+
+static struct platform_driver bfin_ir_driver = {
+       .probe   = bfin_sir_probe,
+       .remove  = __devexit_p(bfin_sir_remove),
+       .suspend = bfin_sir_suspend,
+       .resume  = bfin_sir_resume,
+       .driver  = {
+               .name = DRIVER_NAME,
+       },
+};
+
+static int __init bfin_sir_init(void)
+{
+       return platform_driver_register(&bfin_ir_driver);
+}
+
+static void __exit bfin_sir_exit(void)
+{
+       platform_driver_unregister(&bfin_ir_driver);
+}
+
+module_init(bfin_sir_init);
+module_exit(bfin_sir_exit);
+
+module_param(max_rate, int, 0);
+MODULE_PARM_DESC(max_rate, "Maximum baud rate (115200, 57600, 38400, 19200, 9600)");
+
+MODULE_AUTHOR("Graf Yang <graf.yang@analog.com>");
+MODULE_DESCRIPTION("Blackfin IrDA driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/irda/bfin_sir.h b/drivers/net/irda/bfin_sir.h
new file mode 100644 (file)
index 0000000..dac71b1
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+ * Blackfin Infra-red Driver
+ *
+ * Copyright 2006-2009 Analog Devices Inc.
+ *
+ * Enter bugs at http://blackfin.uclinux.org/
+ *
+ * Licensed under the GPL-2 or later.
+ *
+ */
+
+#include <linux/serial.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+
+#include <net/irda/irda.h>
+#include <net/irda/wrapper.h>
+#include <net/irda/irda_device.h>
+
+#include <asm/irq.h>
+#include <asm/cacheflush.h>
+#include <asm/dma.h>
+#include <asm/portmux.h>
+
+#ifdef CONFIG_SIR_BFIN_DMA
+struct dma_rx_buf {
+       char *buf;
+       int head;
+       int tail;
+};
+#endif
+
+struct bfin_sir_port {
+       unsigned char __iomem   *membase;
+       unsigned int            irq;
+       unsigned int            lsr;
+       unsigned long           clk;
+       struct net_device       *dev;
+#ifdef CONFIG_SIR_BFIN_DMA
+       int                     tx_done;
+       struct dma_rx_buf       rx_dma_buf;
+       struct timer_list       rx_dma_timer;
+       int                     rx_dma_nrows;
+#endif
+       unsigned int            tx_dma_channel;
+       unsigned int            rx_dma_channel;
+};
+
+struct bfin_sir_port_res {
+       unsigned long   base_addr;
+       int             irq;
+       unsigned int    rx_dma_channel;
+       unsigned int    tx_dma_channel;
+};
+
+struct bfin_sir_self {
+       struct bfin_sir_port    *sir_port;
+       spinlock_t              lock;
+       unsigned int            open;
+       int                     speed;
+       int                     newspeed;
+
+       struct sk_buff          *txskb;
+       struct sk_buff          *rxskb;
+       struct net_device_stats stats;
+       struct device           *dev;
+       struct irlap_cb         *irlap;
+       struct qos_info         qos;
+
+       iobuff_t                tx_buff;
+       iobuff_t                rx_buff;
+
+       struct work_struct      work;
+       int                     mtt;
+};
+
+#define DRIVER_NAME "bfin_sir"
+
+#define SIR_UART_GET_CHAR(port)    bfin_read16((port)->membase + OFFSET_RBR)
+#define SIR_UART_GET_DLL(port)     bfin_read16((port)->membase + OFFSET_DLL)
+#define SIR_UART_GET_DLH(port)     bfin_read16((port)->membase + OFFSET_DLH)
+#define SIR_UART_GET_LCR(port)     bfin_read16((port)->membase + OFFSET_LCR)
+#define SIR_UART_GET_GCTL(port)    bfin_read16((port)->membase + OFFSET_GCTL)
+
+#define SIR_UART_PUT_CHAR(port, v) bfin_write16(((port)->membase + OFFSET_THR), v)
+#define SIR_UART_PUT_DLL(port, v)  bfin_write16(((port)->membase + OFFSET_DLL), v)
+#define SIR_UART_PUT_DLH(port, v)  bfin_write16(((port)->membase + OFFSET_DLH), v)
+#define SIR_UART_PUT_LCR(port, v)  bfin_write16(((port)->membase + OFFSET_LCR), v)
+#define SIR_UART_PUT_GCTL(port, v) bfin_write16(((port)->membase + OFFSET_GCTL), v)
+
+#ifdef CONFIG_BF54x
+#define SIR_UART_GET_LSR(port)     bfin_read16((port)->membase + OFFSET_LSR)
+#define SIR_UART_GET_IER(port)     bfin_read16((port)->membase + OFFSET_IER_SET)
+#define SIR_UART_SET_IER(port, v)  bfin_write16(((port)->membase + OFFSET_IER_SET), v)
+#define SIR_UART_CLEAR_IER(port, v) bfin_write16(((port)->membase + OFFSET_IER_CLEAR), v)
+#define SIR_UART_PUT_LSR(port, v)  bfin_write16(((port)->membase + OFFSET_LSR), v)
+#define SIR_UART_CLEAR_LSR(port)   bfin_write16(((port)->membase + OFFSET_LSR), -1)
+
+#define SIR_UART_SET_DLAB(port)
+#define SIR_UART_CLEAR_DLAB(port)
+
+#define SIR_UART_ENABLE_INTS(port, v) SIR_UART_SET_IER(port, v)
+#define SIR_UART_DISABLE_INTS(port)   SIR_UART_CLEAR_IER(port, 0xF)
+#define SIR_UART_STOP_TX(port)     do { SIR_UART_PUT_LSR(port, TFI); SIR_UART_CLEAR_IER(port, ETBEI); } while (0)
+#define SIR_UART_ENABLE_TX(port)   do { SIR_UART_SET_IER(port, ETBEI); } while (0)
+#define SIR_UART_STOP_RX(port)     do { SIR_UART_CLEAR_IER(port, ERBFI); } while (0)
+#define SIR_UART_ENABLE_RX(port)   do { SIR_UART_SET_IER(port, ERBFI); } while (0)
+#else
+
+#define SIR_UART_GET_IIR(port)     bfin_read16((port)->membase + OFFSET_IIR)
+#define SIR_UART_GET_IER(port)     bfin_read16((port)->membase + OFFSET_IER)
+#define SIR_UART_PUT_IER(port, v)  bfin_write16(((port)->membase + OFFSET_IER), v)
+
+#define SIR_UART_SET_DLAB(port)    do { SIR_UART_PUT_LCR(port, SIR_UART_GET_LCR(port) | DLAB); } while (0)
+#define SIR_UART_CLEAR_DLAB(port)  do { SIR_UART_PUT_LCR(port, SIR_UART_GET_LCR(port) & ~DLAB); } while (0)
+
+#define SIR_UART_ENABLE_INTS(port, v) SIR_UART_PUT_IER(port, v)
+#define SIR_UART_DISABLE_INTS(port)   SIR_UART_PUT_IER(port, 0)
+#define SIR_UART_STOP_TX(port)     do { SIR_UART_PUT_IER(port, SIR_UART_GET_IER(port) & ~ETBEI); } while (0)
+#define SIR_UART_ENABLE_TX(port)   do { SIR_UART_PUT_IER(port, SIR_UART_GET_IER(port) | ETBEI); } while (0)
+#define SIR_UART_STOP_RX(port)     do { SIR_UART_PUT_IER(port, SIR_UART_GET_IER(port) & ~ERBFI); } while (0)
+#define SIR_UART_ENABLE_RX(port)   do { SIR_UART_PUT_IER(port, SIR_UART_GET_IER(port) | ERBFI); } while (0)
+
+static inline unsigned int SIR_UART_GET_LSR(struct bfin_sir_port *port)
+{
+       unsigned int lsr = bfin_read16(port->membase + OFFSET_LSR);
+       port->lsr |= (lsr & (BI|FE|PE|OE));
+       return lsr | port->lsr;
+}
+
+static inline void SIR_UART_CLEAR_LSR(struct bfin_sir_port *port)
+{
+       port->lsr = 0;
+       bfin_read16(port->membase + OFFSET_LSR);
+}
+#endif
+
+static const unsigned short per[][4] = {
+       /* rx pin      tx pin     NULL  uart_number */
+       {P_UART0_RX, P_UART0_TX,    0,    0},
+       {P_UART1_RX, P_UART1_TX,    0,    1},
+       {P_UART2_RX, P_UART2_TX,    0,    2},
+       {P_UART3_RX, P_UART3_TX,    0,    3},
+};
index 6b6548b9fda01717d869c7eb3e0fd7e6ceefbde2..9a0346e751acd33fb47ba34536f8c61e489d49c8 100644 (file)
@@ -994,11 +994,11 @@ toshoboe_hard_xmit (struct sk_buff *skb, struct net_device *dev)
 
   /* change speed pending, wait for its execution */
   if (self->new_speed)
-      return -EBUSY;
+      return NETDEV_TX_BUSY;
 
   /* device stopped (apm) wait for restart */
   if (self->stopped)
-      return -EBUSY;
+      return NETDEV_TX_BUSY;
 
   toshoboe_checkstuck (self);
 
@@ -1049,7 +1049,7 @@ toshoboe_hard_xmit (struct sk_buff *skb, struct net_device *dev)
       if (self->txpending)
         {
          spin_unlock_irqrestore(&self->spinlock, flags);
-          return -EBUSY;
+          return NETDEV_TX_BUSY;
         }
 
       /* If in SIR mode we need to generate a string of XBOFs */
@@ -1105,7 +1105,7 @@ dumpbufs(skb->data,skb->len,'>');
           ,skb->len, self->ring->tx[self->txs].control, self->txpending);
       toshoboe_start_DMA(self, OBOE_CONFIG0H_ENTX);
       spin_unlock_irqrestore(&self->spinlock, flags);
-      return -EBUSY;
+      return NETDEV_TX_BUSY;
     }
 
   if (INB (OBOE_ENABLEH) & OBOE_ENABLEH_SIRON)
index 006ba23110dbb0e9247c1f841dd9fc9c0bb502f9..0c0831c03f64bdad26d61bae3a93e38f2e54055b 100644 (file)
@@ -389,7 +389,6 @@ static int irda_usb_hard_xmit(struct sk_buff *skb, struct net_device *netdev)
        s32 speed;
        s16 xbofs;
        int res, mtt;
-       int     err = 1;        /* Failed */
 
        IRDA_DEBUG(4, "%s() on %s\n", __func__, netdev->name);
 
@@ -430,7 +429,6 @@ static int irda_usb_hard_xmit(struct sk_buff *skb, struct net_device *netdev)
                        irda_usb_change_speed_xbofs(self);
                        netdev->trans_start = jiffies;
                        /* Will netif_wake_queue() in callback */
-                       err = 0;        /* No error */
                        goto drop;
                }
        }
@@ -542,7 +540,7 @@ drop:
        /* Drop silently the skb and exit */
        dev_kfree_skb(skb);
        spin_unlock_irqrestore(&self->lock, flags);
-       return err;             /* Usually 1 */
+       return NETDEV_TX_OK;
 }
 
 /*------------------------------------------------------------------*/
@@ -1859,6 +1857,42 @@ static void irda_usb_disconnect(struct usb_interface *intf)
        IRDA_DEBUG(0, "%s(), USB IrDA Disconnected\n", __func__);
 }
 
+#ifdef CONFIG_PM
+/* USB suspend, so power off the transmitter/receiver */
+static int irda_usb_suspend(struct usb_interface *intf, pm_message_t message)
+{
+       struct irda_usb_cb *self = usb_get_intfdata(intf);
+       int i;
+
+       netif_device_detach(self->netdev);
+
+       if (self->tx_urb != NULL)
+               usb_kill_urb(self->tx_urb);
+       if (self->speed_urb != NULL)
+               usb_kill_urb(self->speed_urb);
+       for (i = 0; i < self->max_rx_urb; i++) {
+               if (self->rx_urb[i] != NULL)
+                       usb_kill_urb(self->rx_urb[i]);
+       }
+       return 0;
+}
+
+/* Coming out of suspend, so reset hardware */
+static int irda_usb_resume(struct usb_interface *intf)
+{
+       struct irda_usb_cb *self = usb_get_intfdata(intf);
+       int i;
+
+       for (i = 0; i < self->max_rx_urb; i++) {
+               if (self->rx_urb[i] != NULL)
+                       usb_submit_urb(self->rx_urb[i], GFP_KERNEL);
+       }
+
+       netif_device_attach(self->netdev);
+       return 0;
+}
+#endif
+
 /*------------------------------------------------------------------*/
 /*
  * USB device callbacks
@@ -1868,6 +1902,10 @@ static struct usb_driver irda_driver = {
        .probe          = irda_usb_probe,
        .disconnect     = irda_usb_disconnect,
        .id_table       = dongles,
+#ifdef CONFIG_PM
+       .suspend        = irda_usb_suspend,
+       .resume         = irda_usb_resume,
+#endif
 };
 
 /************************* MODULE CALLBACKS *************************/
index 9d813bc4502e721890aa59e1fc632ad7a383fbfc..c3e4e2c435baf1547d6e7659860fccc15edd6310 100644 (file)
@@ -156,9 +156,6 @@ static int kingsun_hard_xmit(struct sk_buff *skb, struct net_device *netdev)
        int wraplen;
        int ret = 0;
 
-       if (skb == NULL || netdev == NULL)
-               return -EINVAL;
-
        netif_stop_queue(netdev);
 
        /* the IRDA wrapping routines don't deal with non linear skb */
@@ -197,7 +194,7 @@ static int kingsun_hard_xmit(struct sk_buff *skb, struct net_device *netdev)
        dev_kfree_skb(skb);
        spin_unlock(&kingsun->lock);
 
-       return ret;
+       return NETDEV_TX_OK;
 }
 
 /* Receive callback function */
index b6ffe9715b61d5ef974fb7cf20c402efb848b3ff..d73b8b64fcb91e28496091cb88e056bd0e6bddea 100644 (file)
@@ -391,9 +391,6 @@ static int ks959_hard_xmit(struct sk_buff *skb, struct net_device *netdev)
        unsigned int wraplen;
        int ret = 0;
 
-       if (skb == NULL || netdev == NULL)
-               return -EINVAL;
-
        netif_stop_queue(netdev);
 
        /* the IRDA wrapping routines don't deal with non linear skb */
@@ -428,7 +425,7 @@ static int ks959_hard_xmit(struct sk_buff *skb, struct net_device *netdev)
        dev_kfree_skb(skb);
        spin_unlock(&kingsun->lock);
 
-       return ret;
+       return NETDEV_TX_OK;
 }
 
 /* Receive callback function */
index 64df27f2bfd469cb2568312ddbd5e9ef028280e7..1ef45ec744229d0bc0b84fd030e186ffc4941a67 100644 (file)
@@ -304,9 +304,6 @@ static int ksdazzle_hard_xmit(struct sk_buff *skb, struct net_device *netdev)
        unsigned int wraplen;
        int ret = 0;
 
-       if (skb == NULL || netdev == NULL)
-               return -EINVAL;
-
        netif_stop_queue(netdev);
 
        /* the IRDA wrapping routines don't deal with non linear skb */
@@ -341,7 +338,7 @@ static int ksdazzle_hard_xmit(struct sk_buff *skb, struct net_device *netdev)
        dev_kfree_skb(skb);
        spin_unlock(&kingsun->lock);
 
-       return ret;
+       return NETDEV_TX_OK;
 }
 
 /* Receive callback function */
index fac504d0cfd86d46f84ad94a880bc689bf122676..f4df1001983cb170426ef799735d93aa81874ca1 100644 (file)
@@ -824,10 +824,6 @@ static int mcs_hard_xmit(struct sk_buff *skb, struct net_device *ndev)
        int wraplen;
        int ret = 0;
 
-
-       if (skb == NULL || ndev == NULL)
-               return -EINVAL;
-
        netif_stop_queue(ndev);
        mcs = netdev_priv(ndev);
 
@@ -870,7 +866,7 @@ static int mcs_hard_xmit(struct sk_buff *skb, struct net_device *ndev)
 
        dev_kfree_skb(skb);
        spin_unlock_irqrestore(&mcs->lock, flags);
-       return ret;
+       return NETDEV_TX_OK;
 }
 
 static const struct net_device_ops mcs_netdev_ops = {
index e775338b525f7b96459594f1ea66418d30dcf47e..3376a4f39e0a1eb02b6287a9355159c3aca7fc0f 100644 (file)
@@ -14,6 +14,7 @@
  */
 #include <linux/module.h>
 #include <linux/netdevice.h>
+#include <linux/etherdevice.h>
 #include <linux/platform_device.h>
 #include <linux/clk.h>
 
@@ -797,6 +798,16 @@ static int pxa_irda_init_iobuf(iobuff_t *io, int size)
        return io->head ? 0 : -ENOMEM;
 }
 
+static const struct net_device_ops pxa_irda_netdev_ops = {
+       .ndo_open               = pxa_irda_start,
+       .ndo_stop               = pxa_irda_stop,
+       .ndo_start_xmit         = pxa_irda_hard_xmit,
+       .ndo_do_ioctl           = pxa_irda_ioctl,
+       .ndo_change_mtu         = eth_change_mtu,
+       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_set_mac_address    = eth_mac_addr,
+};
+
 static int pxa_irda_probe(struct platform_device *pdev)
 {
        struct net_device *dev;
@@ -845,10 +856,7 @@ static int pxa_irda_probe(struct platform_device *pdev)
        if (err)
                goto err_startup;
 
-       dev->hard_start_xmit    = pxa_irda_hard_xmit;
-       dev->open               = pxa_irda_start;
-       dev->stop               = pxa_irda_stop;
-       dev->do_ioctl           = pxa_irda_ioctl;
+       dev->netdev_ops = &pxa_irda_netdev_ops;
 
        irda_init_max_qos_capabilies(&si->qos);
 
index 7a2b003954cacd71bd09389478ead376a6ec097a..2aeb2e6aec1bb583e6867d4716f85f5eec3bfa83 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/init.h>
 #include <linux/errno.h>
 #include <linux/netdevice.h>
+#include <linux/etherdevice.h>
 #include <linux/slab.h>
 #include <linux/rtnetlink.h>
 #include <linux/interrupt.h>
@@ -875,6 +876,16 @@ static int sa1100_irda_init_iobuf(iobuff_t *io, int size)
        return io->head ? 0 : -ENOMEM;
 }
 
+static const struct net_device_ops sa1100_irda_netdev_ops = {
+       .ndo_open               = sa1100_irda_start,
+       .ndo_stop               = sa1100_irda_stop,
+       .ndo_start_xmit         = sa1100_irda_hard_xmit,
+       .ndo_do_ioctl           = sa1100_irda_ioctl,
+       .ndo_change_mtu         = eth_change_mtu,
+       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_set_mac_address    = eth_mac_addr,
+};
+
 static int sa1100_irda_probe(struct platform_device *pdev)
 {
        struct net_device *dev;
@@ -913,11 +924,8 @@ static int sa1100_irda_probe(struct platform_device *pdev)
        if (err)
                goto err_mem_5;
 
-       dev->hard_start_xmit    = sa1100_irda_hard_xmit;
-       dev->open               = sa1100_irda_start;
-       dev->stop               = sa1100_irda_stop;
-       dev->do_ioctl           = sa1100_irda_ioctl;
-       dev->irq                = IRQ_Ser2ICP;
+       dev->netdev_ops = &sa1100_irda_netdev_ops;
+       dev->irq        = IRQ_Ser2ICP;
 
        irda_init_max_qos_capabilies(&si->qos);
 
index d940809762eca2bafa6c2966e4fc1b717b863d20..fd0796c3db3cf7889a21ff72d8ffc49b38b919d1 100644 (file)
@@ -607,7 +607,7 @@ static int sirdev_hard_xmit(struct sk_buff *skb, struct net_device *ndev)
                                 * stopped so the network layer will retry after the
                                 * fsm completes and wakes the queue.
                                 */
-                                return 1;
+                                return NETDEV_TX_BUSY;
                        }
                        else if (unlikely(err)) {
                                /* other fatal error - forget the speed change and
index 59d79807b4d506e4bdca343b8cab1e6fa771d478..d0797adb5f8e7b1eec689fd0e69ae4d1c9ccec37 100644 (file)
@@ -2124,7 +2124,7 @@ static void smsc_ircc_sir_wait_hw_transmitter_finish(struct smsc_ircc_cb *self)
        while (count-- > 0 && !(inb(iobase + UART_LSR) & UART_LSR_TEMT))
                udelay(1);
 
-       if (count == 0)
+       if (count < 0)
                IRDA_DEBUG(0, "%s(): stuck transmitter\n", __func__);
 }
 
index cb793c2bade2bd5a525e97ef7a5a216c84e18720..e44215cb18823ccaaf959f8ea82a3b442b6e306d 100644 (file)
@@ -1021,6 +1021,16 @@ static const struct ethtool_ops ops = {
        .get_link = veth_get_link,
 };
 
+static const struct net_device_ops veth_netdev_ops = {
+       .ndo_open               = veth_open,
+       .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_mac_address    = NULL,
+       .ndo_validate_addr      = eth_validate_addr,
+};
+
 static struct net_device *veth_probe_one(int vlan,
                struct vio_dev *vio_dev)
 {
@@ -1067,12 +1077,7 @@ static struct net_device *veth_probe_one(int vlan,
 
        memcpy(&port->mac_addr, mac_addr, ETH_ALEN);
 
-       dev->open = veth_open;
-       dev->hard_start_xmit = veth_start_xmit;
-       dev->stop = veth_close;
-       dev->change_mtu = veth_change_mtu;
-       dev->set_mac_address = NULL;
-       dev->set_multicast_list = veth_set_multicast_list;
+       dev->netdev_ops = &veth_netdev_ops;
        SET_ETHTOOL_OPS(dev, &ops);
 
        SET_NETDEV_DEV(dev, vdev);
index 11dcda0f453e9655a32fdde9e4222db67bd18aa2..ff67a84e68026daf7d72aa36faf3cb68dcd1508c 100644 (file)
@@ -192,7 +192,7 @@ ixgb_identify_xpak_vendor(struct ixgb_hw *hw)
                vendor_name[i] = ixgb_read_phy_reg(hw,
                                                   MDIO_PMA_PMD_XPAK_VENDOR_NAME
                                                   + i, IXGB_PHY_ADDRESS,
-                                                  MDIO_PMA_PMD_DID);
+                                                  MDIO_MMD_PMAPMD);
        }
 
        /* Determine the actual vendor */
@@ -1225,15 +1225,15 @@ ixgb_optics_reset(struct ixgb_hw *hw)
                u16 mdio_reg;
 
                ixgb_write_phy_reg(hw,
-                                       MDIO_PMA_PMD_CR1,
-                                       IXGB_PHY_ADDRESS,
-                                       MDIO_PMA_PMD_DID,
-                                       MDIO_PMA_PMD_CR1_RESET);
-
-               mdio_reg = ixgb_read_phy_reg( hw,
-                                               MDIO_PMA_PMD_CR1,
-                                               IXGB_PHY_ADDRESS,
-                                               MDIO_PMA_PMD_DID);
+                                  MDIO_CTRL1,
+                                  IXGB_PHY_ADDRESS,
+                                  MDIO_MMD_PMAPMD,
+                                  MDIO_CTRL1_RESET);
+
+               mdio_reg = ixgb_read_phy_reg(hw,
+                                            MDIO_CTRL1,
+                                            IXGB_PHY_ADDRESS,
+                                            MDIO_MMD_PMAPMD);
        }
 
        return;
index 831fe0c58b2b87027469c0ba2b1ee4badc87986b..af6ca3aab5adc5d16a96d2aa57a96b27074bdeff 100644 (file)
@@ -29,6 +29,8 @@
 #ifndef _IXGB_HW_H_
 #define _IXGB_HW_H_
 
+#include <linux/mdio.h>
+
 #include "ixgb_osdep.h"
 
 /* Enums */
@@ -507,18 +509,6 @@ typedef enum {
 /* Definitions for the optics devices on the MDIO bus. */
 #define IXGB_PHY_ADDRESS             0x0       /* Single PHY, multiple "Devices" */
 
-/* Standard five-bit Device IDs.  See IEEE 802.3ae, clause 45 */
-#define MDIO_PMA_PMD_DID        0x01
-#define MDIO_WIS_DID            0x02
-#define MDIO_PCS_DID            0x03
-#define MDIO_XGXS_DID           0x04
-
-/* Standard PMA/PMD registers and bit definitions. */
-/* Note: This is a very limited set of definitions,      */
-/* only implemented features are defined.                */
-#define MDIO_PMA_PMD_CR1        0x0000
-#define MDIO_PMA_PMD_CR1_RESET  0x8000
-
 #define MDIO_PMA_PMD_XPAK_VENDOR_NAME       0x803A     /* XPAK/XENPAK devices only */
 
 /* Vendor-specific MDIO registers */
index 4a0826b8f6f2bda1498f72fe5d9314ec33f07210..9c897cf86b9f629c5a690aba85c27724ef42f006 100644 (file)
@@ -266,6 +266,8 @@ ixgb_up(struct ixgb_adapter *adapter)
        napi_enable(&adapter->napi);
        ixgb_irq_enable(adapter);
 
+       netif_wake_queue(netdev);
+
        mod_timer(&adapter->watchdog_timer, jiffies);
 
        return 0;
@@ -471,10 +473,8 @@ ixgb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        if (err)
                goto err_register;
 
-       /* we're going to reset, so assume we have no link for now */
-
+       /* carrier off reporting is important to ethtool even BEFORE open */
        netif_carrier_off(netdev);
-       netif_stop_queue(netdev);
 
        DPRINTK(PROBE, INFO, "Intel(R) PRO/10GbE Network Connection\n");
        ixgb_check_options(adapter);
@@ -592,6 +592,8 @@ ixgb_open(struct net_device *netdev)
        if (err)
                goto err_setup_tx;
 
+       netif_carrier_off(netdev);
+
        /* allocate receive descriptors */
 
        err = ixgb_setup_rx_resources(adapter);
@@ -602,6 +604,8 @@ ixgb_open(struct net_device *netdev)
        if (err)
                goto err_up;
 
+       netif_start_queue(netdev);
+
        return 0;
 
 err_up:
@@ -1116,7 +1120,6 @@ ixgb_watchdog(unsigned long data)
                        adapter->link_speed = 10000;
                        adapter->link_duplex = FULL_DUPLEX;
                        netif_carrier_on(netdev);
-                       netif_wake_queue(netdev);
                }
        } else {
                if (netif_carrier_ok(netdev)) {
@@ -1125,8 +1128,6 @@ ixgb_watchdog(unsigned long data)
                        printk(KERN_INFO "ixgb: %s NIC Link is Down\n",
                               netdev->name);
                        netif_carrier_off(netdev);
-                       netif_stop_queue(netdev);
-
                }
        }
 
@@ -1139,6 +1140,8 @@ ixgb_watchdog(unsigned long data)
                         * to get done, so reset controller to flush Tx.
                         * (Do the reset outside of interrupt context). */
                        schedule_work(&adapter->tx_timeout_task);
+                       /* return immediately since reset is imminent */
+                       return;
                }
        }
 
@@ -1297,7 +1300,7 @@ ixgb_tx_map(struct ixgb_adapter *adapter, struct sk_buff *skb,
                buffer_info->length = size;
                WARN_ON(buffer_info->dma != 0);
                buffer_info->time_stamp = jiffies;
-               buffer_info->dma = map[0] + offset;
+               buffer_info->dma = skb_shinfo(skb)->dma_head + offset;
                        pci_map_single(adapter->pdev,
                                skb->data + offset,
                                size,
@@ -1337,7 +1340,7 @@ ixgb_tx_map(struct ixgb_adapter *adapter, struct sk_buff *skb,
 
                        buffer_info->length = size;
                        buffer_info->time_stamp = jiffies;
-                       buffer_info->dma = map[f + 1] + offset;
+                       buffer_info->dma = map[f] + offset;
                        buffer_info->next_to_watch = 0;
 
                        len -= size;
@@ -1485,7 +1488,6 @@ ixgb_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 
        if (count) {
                ixgb_tx_queue(adapter, count, vlan_id, tx_flags);
-               netdev->trans_start = jiffies;
                /* Make sure there is space in the ring for the next send. */
                ixgb_maybe_stop_tx(netdev, &adapter->tx_ring, DESC_NEEDED);
 
index d92e72bd627a08e91d8f4131fcda8d30ac762155..371a6be4d965b5a5cf0a852a9af8d71c0c614e7c 100644 (file)
@@ -40,7 +40,7 @@
 #include <linux/sched.h>
 
 #undef ASSERT
-#define ASSERT(x)      if (!(x)) BUG()
+#define ASSERT(x)      BUG_ON(!(x))
 #define MSGOUT(S, A, B)        printk(KERN_DEBUG S "\n", A, B)
 
 #ifdef DBG
index b3f8208ec7bec21288df1c5b548d895af6ec3b40..21b41f42b61cf1237bc25e88c06444b52c5f7649 100644 (file)
@@ -37,3 +37,5 @@ ixgbe-objs := ixgbe_main.o ixgbe_common.o ixgbe_ethtool.o \
 
 ixgbe-$(CONFIG_IXGBE_DCB) +=  ixgbe_dcb.o ixgbe_dcb_82598.o \
                               ixgbe_dcb_82599.o ixgbe_dcb_nl.o
+
+ixgbe-$(CONFIG_FCOE:m=y) += ixgbe_fcoe.o
index c26433d14605d9fd74fafc996f69065cbca75524..cd22323cfd2276009b15bf0254bdcfbbafce00e5 100644 (file)
 #include "ixgbe_type.h"
 #include "ixgbe_common.h"
 #include "ixgbe_dcb.h"
+#if defined(CONFIG_FCOE) || defined(CONFIG_FCOE_MODULE)
+#define IXGBE_FCOE
+#include "ixgbe_fcoe.h"
+#endif /* CONFIG_FCOE or CONFIG_FCOE_MODULE */
 #ifdef CONFIG_IXGBE_DCA
 #include <linux/dca.h>
 #endif
@@ -71,6 +75,8 @@
 #define IXGBE_RXBUFFER_128   128    /* Used for packet split */
 #define IXGBE_RXBUFFER_256   256    /* Used for packet split */
 #define IXGBE_RXBUFFER_2048  2048
+#define IXGBE_RXBUFFER_4096  4096
+#define IXGBE_RXBUFFER_8192  8192
 #define IXGBE_MAX_RXBUFFER   16384  /* largest size for a single descriptor */
 
 #define IXGBE_RX_HDR_SIZE IXGBE_RXBUFFER_256
@@ -84,6 +90,8 @@
 #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_VLAN_MASK       0xffff0000
 #define IXGBE_TX_FLAGS_VLAN_PRIO_MASK   0x0000e000
 #define IXGBE_TX_FLAGS_VLAN_SHIFT      16
@@ -113,17 +121,18 @@ struct ixgbe_queue_stats {
 
 struct ixgbe_ring {
        void *desc;                     /* descriptor ring memory */
-       dma_addr_t dma;                 /* phys. address of descriptor ring */
-       unsigned int size;              /* length in bytes */
-       unsigned int count;             /* amount of descriptors */
-       unsigned int next_to_use;
-       unsigned int next_to_clean;
-
-       int queue_index; /* needed for multiqueue queue management */
        union {
                struct ixgbe_tx_buffer *tx_buffer_info;
                struct ixgbe_rx_buffer *rx_buffer_info;
        };
+       u8 atr_sample_rate;
+       u8 atr_count;
+       u16 count;                      /* amount of descriptors */
+       u16 rx_buf_len;
+       u16 next_to_use;
+       u16 next_to_clean;
+
+       u8 queue_index; /* needed for multiqueue queue management */
 
        u16 head;
        u16 tail;
@@ -131,22 +140,24 @@ struct ixgbe_ring {
        unsigned int total_bytes;
        unsigned int total_packets;
 
-       u16 reg_idx; /* holds the special value that gets the hardware register
-                     * offset associated with this ring, which is different
-                     * for DCB and RSS modes */
-
 #ifdef CONFIG_IXGBE_DCA
        /* cpu for tx queue */
        int cpu;
 #endif
-       struct ixgbe_queue_stats stats;
-       u64 v_idx; /* maps directly to the index for this ring in the hardware
-                   * vector array, can also be used for finding the bit in EICR
-                   * and friends that represents the vector for this ring */
 
+       u16 work_limit;                 /* max work per interrupt */
+       u16 reg_idx;                    /* holds the special value that gets
+                                        * the hardware register offset
+                                        * associated with this ring, which is
+                                        * different for DCB and RSS modes
+                                        */
 
-       u16 work_limit;                /* max work per interrupt */
-       u16 rx_buf_len;
+       struct ixgbe_queue_stats stats;
+       unsigned long reinit_state;
+       u64 rsc_count;                  /* stat for coalesced packets */
+
+       unsigned int size;              /* length in bytes */
+       dma_addr_t dma;                 /* phys. address of descriptor ring */
 };
 
 enum ixgbe_ring_f_enum {
@@ -154,6 +165,10 @@ enum ixgbe_ring_f_enum {
        RING_F_DCB,
        RING_F_VMDQ,
        RING_F_RSS,
+       RING_F_FDIR,
+#ifdef IXGBE_FCOE
+       RING_F_FCOE,
+#endif /* IXGBE_FCOE */
 
        RING_F_ARRAY_SIZE      /* must be last in enum set */
 };
@@ -161,6 +176,10 @@ enum ixgbe_ring_f_enum {
 #define IXGBE_MAX_DCB_INDICES   8
 #define IXGBE_MAX_RSS_INDICES  16
 #define IXGBE_MAX_VMDQ_INDICES 16
+#define IXGBE_MAX_FDIR_INDICES 64
+#ifdef IXGBE_FCOE
+#define IXGBE_MAX_FCOE_INDICES  8
+#endif /* IXGBE_FCOE */
 struct ixgbe_ring_feature {
        int indices;
        int mask;
@@ -178,6 +197,9 @@ struct ixgbe_ring_feature {
  */
 struct ixgbe_q_vector {
        struct ixgbe_adapter *adapter;
+       unsigned int v_idx; /* index of q_vector within array, also used for
+                            * finding the bit in EICR and friends that
+                            * represents the vector for this ring */
        struct napi_struct napi;
        DECLARE_BITMAP(rxr_idx, MAX_RX_QUEUES); /* Rx ring indices */
        DECLARE_BITMAP(txr_idx, MAX_TX_QUEUES); /* Tx ring indices */
@@ -207,7 +229,15 @@ struct ixgbe_q_vector {
 #define IXGBE_TX_CTXTDESC_ADV(R, i)        \
        (&(((struct ixgbe_adv_tx_context_desc *)((R).desc))[i]))
 
+#define IXGBE_GET_DESC(R, i, type)     (&(((struct type *)((R).desc))[i]))
+#define IXGBE_TX_DESC(R, i)    IXGBE_GET_DESC(R, i, ixgbe_legacy_tx_desc)
+#define IXGBE_RX_DESC(R, i)    IXGBE_GET_DESC(R, i, ixgbe_legacy_rx_desc)
+
 #define IXGBE_MAX_JUMBO_FRAME_SIZE        16128
+#ifdef IXGBE_FCOE
+/* Use 3K as the baby jumbo frame size for FCoE */
+#define IXGBE_FCOE_JUMBO_FRAME_SIZE       3072
+#endif /* IXGBE_FCOE */
 
 #define OTHER_VECTOR 1
 #define NON_Q_VECTORS (OTHER_VECTOR)
@@ -229,11 +259,12 @@ struct ixgbe_adapter {
        struct vlan_group *vlgrp;
        u16 bd_number;
        struct work_struct reset_task;
-       struct ixgbe_q_vector q_vector[MAX_MSIX_Q_VECTORS];
+       struct ixgbe_q_vector *q_vector[MAX_MSIX_Q_VECTORS];
        char name[MAX_MSIX_COUNT][IFNAMSIZ + 9];
        struct ixgbe_dcb_config dcb_cfg;
        struct ixgbe_dcb_config temp_dcb_cfg;
        u8 dcb_set_bitmap;
+       enum ixgbe_fc_mode last_lfc_mode;
 
        /* Interrupt Throttle Rate */
        u32 itr_setting;
@@ -294,7 +325,13 @@ struct ixgbe_adapter {
 #define IXGBE_FLAG_IN_WATCHDOG_TASK             (u32)(1 << 23)
 #define IXGBE_FLAG_IN_SFP_LINK_TASK             (u32)(1 << 24)
 #define IXGBE_FLAG_IN_SFP_MOD_TASK              (u32)(1 << 25)
+#define IXGBE_FLAG_FDIR_HASH_CAPABLE            (u32)(1 << 26)
+#define IXGBE_FLAG_FDIR_PERFECT_CAPABLE         (u32)(1 << 27)
+#define IXGBE_FLAG_FCOE_ENABLED                 (u32)(1 << 29)
 
+       u32 flags2;
+#define IXGBE_FLAG2_RSC_CAPABLE                 (u32)(1)
+#define IXGBE_FLAG2_RSC_ENABLED                 (u32)(1 << 1)
 /* default to trying for four seconds */
 #define IXGBE_TRY_LINK_TIMEOUT (4 * HZ)
 
@@ -303,6 +340,10 @@ struct ixgbe_adapter {
        struct pci_dev *pdev;
        struct net_device_stats net_stats;
 
+       u32 test_icr;
+       struct ixgbe_ring test_tx_ring;
+       struct ixgbe_ring test_rx_ring;
+
        /* structs defined in ixgbe_hw.h */
        struct ixgbe_hw hw;
        u16 msg_enable;
@@ -325,6 +366,14 @@ struct ixgbe_adapter {
        struct timer_list sfp_timer;
        struct work_struct multispeed_fiber_task;
        struct work_struct sfp_config_module_task;
+       u32 fdir_pballoc;
+       u32 atr_sample_rate;
+       spinlock_t fdir_perfect_lock;
+       struct work_struct fdir_reinit_task;
+#ifdef IXGBE_FCOE
+       struct ixgbe_fcoe fcoe;
+#endif /* IXGBE_FCOE */
+       u64 rsc_count;
        u32 wol;
        u16 eeprom_version;
 };
@@ -333,6 +382,7 @@ enum ixbge_state_t {
        __IXGBE_TESTING,
        __IXGBE_RESETTING,
        __IXGBE_DOWN,
+       __IXGBE_FDIR_INIT_DONE,
        __IXGBE_SFP_MODULE_NOT_FOUND
 };
 
@@ -363,10 +413,77 @@ extern int ixgbe_setup_tx_resources(struct ixgbe_adapter *, struct ixgbe_ring *)
 extern void ixgbe_free_rx_resources(struct ixgbe_adapter *, struct ixgbe_ring *);
 extern void ixgbe_free_tx_resources(struct ixgbe_adapter *, struct ixgbe_ring *);
 extern void ixgbe_update_stats(struct ixgbe_adapter *adapter);
-extern void ixgbe_reset_interrupt_capability(struct ixgbe_adapter *adapter);
 extern int ixgbe_init_interrupt_scheme(struct ixgbe_adapter *adapter);
-void ixgbe_napi_add_all(struct ixgbe_adapter *adapter);
-void ixgbe_napi_del_all(struct ixgbe_adapter *adapter);
-extern void ixgbe_write_eitr(struct ixgbe_adapter *, int, u32);
+extern void ixgbe_clear_interrupt_scheme(struct ixgbe_adapter *adapter);
+extern void ixgbe_write_eitr(struct ixgbe_q_vector *);
+extern int ethtool_ioctl(struct ifreq *ifr);
+extern s32 ixgbe_reinit_fdir_tables_82599(struct ixgbe_hw *hw);
+extern s32 ixgbe_init_fdir_signature_82599(struct ixgbe_hw *hw, u32 pballoc);
+extern s32 ixgbe_init_fdir_perfect_82599(struct ixgbe_hw *hw, u32 pballoc);
+extern s32 ixgbe_fdir_add_signature_filter_82599(struct ixgbe_hw *hw,
+                                                 struct ixgbe_atr_input *input,
+                                                 u8 queue);
+extern s32 ixgbe_fdir_add_perfect_filter_82599(struct ixgbe_hw *hw,
+                                               struct ixgbe_atr_input *input,
+                                               u16 soft_id,
+                                               u8 queue);
+extern u16 ixgbe_atr_compute_hash_82599(struct ixgbe_atr_input *input, u32 key);
+extern s32 ixgbe_atr_set_vlan_id_82599(struct ixgbe_atr_input *input,
+                                       u16 vlan_id);
+extern s32 ixgbe_atr_set_src_ipv4_82599(struct ixgbe_atr_input *input,
+                                        u32 src_addr);
+extern s32 ixgbe_atr_set_dst_ipv4_82599(struct ixgbe_atr_input *input,
+                                        u32 dst_addr);
+extern s32 ixgbe_atr_set_src_ipv6_82599(struct ixgbe_atr_input *input,
+                                        u32 src_addr_1, u32 src_addr_2,
+                                        u32 src_addr_3, u32 src_addr_4);
+extern s32 ixgbe_atr_set_dst_ipv6_82599(struct ixgbe_atr_input *input,
+                                        u32 dst_addr_1, u32 dst_addr_2,
+                                        u32 dst_addr_3, u32 dst_addr_4);
+extern s32 ixgbe_atr_set_src_port_82599(struct ixgbe_atr_input *input,
+                                        u16 src_port);
+extern s32 ixgbe_atr_set_dst_port_82599(struct ixgbe_atr_input *input,
+                                        u16 dst_port);
+extern s32 ixgbe_atr_set_flex_byte_82599(struct ixgbe_atr_input *input,
+                                         u16 flex_byte);
+extern s32 ixgbe_atr_set_vm_pool_82599(struct ixgbe_atr_input *input,
+                                       u8 vm_pool);
+extern s32 ixgbe_atr_set_l4type_82599(struct ixgbe_atr_input *input,
+                                      u8 l4type);
+extern s32 ixgbe_atr_get_vlan_id_82599(struct ixgbe_atr_input *input,
+                                       u16 *vlan_id);
+extern s32 ixgbe_atr_get_src_ipv4_82599(struct ixgbe_atr_input *input,
+                                        u32 *src_addr);
+extern s32 ixgbe_atr_get_dst_ipv4_82599(struct ixgbe_atr_input *input,
+                                        u32 *dst_addr);
+extern s32 ixgbe_atr_get_src_ipv6_82599(struct ixgbe_atr_input *input,
+                                        u32 *src_addr_1, u32 *src_addr_2,
+                                        u32 *src_addr_3, u32 *src_addr_4);
+extern s32 ixgbe_atr_get_dst_ipv6_82599(struct ixgbe_atr_input *input,
+                                        u32 *dst_addr_1, u32 *dst_addr_2,
+                                        u32 *dst_addr_3, u32 *dst_addr_4);
+extern s32 ixgbe_atr_get_src_port_82599(struct ixgbe_atr_input *input,
+                                        u16 *src_port);
+extern s32 ixgbe_atr_get_dst_port_82599(struct ixgbe_atr_input *input,
+                                        u16 *dst_port);
+extern s32 ixgbe_atr_get_flex_byte_82599(struct ixgbe_atr_input *input,
+                                         u16 *flex_byte);
+extern s32 ixgbe_atr_get_vm_pool_82599(struct ixgbe_atr_input *input,
+                                       u8 *vm_pool);
+extern s32 ixgbe_atr_get_l4type_82599(struct ixgbe_atr_input *input,
+                                      u8 *l4type);
+#ifdef IXGBE_FCOE
+extern void ixgbe_configure_fcoe(struct ixgbe_adapter *adapter);
+extern int ixgbe_fso(struct ixgbe_adapter *adapter,
+                     struct ixgbe_ring *tx_ring, struct sk_buff *skb,
+                     u32 tx_flags, u8 *hdr_len);
+extern void ixgbe_cleanup_fcoe(struct ixgbe_adapter *adapter);
+extern int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter,
+                          union ixgbe_adv_rx_desc *rx_desc,
+                          struct sk_buff *skb);
+extern int ixgbe_fcoe_ddp_get(struct net_device *netdev, u16 xid,
+                              struct scatterlist *sgl, unsigned int sgc);
+extern int ixgbe_fcoe_ddp_put(struct net_device *netdev, u16 xid);
+#endif /* IXGBE_FCOE */
 
 #endif /* _IXGBE_H_ */
index 4791238c3f6e9fdec240ee755817947636eff5dc..b9923047ce11469a2e5fb82369d7b00ec4845e24 100644 (file)
@@ -73,20 +73,51 @@ static u16 ixgbe_get_pcie_msix_count_82598(struct ixgbe_hw *hw)
 /**
  */
 static s32 ixgbe_get_invariants_82598(struct ixgbe_hw *hw)
+{
+       struct ixgbe_mac_info *mac = &hw->mac;
+
+       /* Call PHY identify routine to get the phy type */
+       ixgbe_identify_phy_generic(hw);
+
+       mac->mcft_size = IXGBE_82598_MC_TBL_SIZE;
+       mac->vft_size = IXGBE_82598_VFT_TBL_SIZE;
+       mac->num_rar_entries = IXGBE_82598_RAR_ENTRIES;
+       mac->max_rx_queues = IXGBE_82598_MAX_RX_QUEUES;
+       mac->max_tx_queues = IXGBE_82598_MAX_TX_QUEUES;
+       mac->max_msix_vectors = ixgbe_get_pcie_msix_count_82598(hw);
+
+       return 0;
+}
+
+/**
+ *  ixgbe_init_phy_ops_82598 - PHY/SFP specific init
+ *  @hw: pointer to hardware structure
+ *
+ *  Initialize any function pointers that were not able to be
+ *  set during get_invariants because the PHY/SFP type was
+ *  not known.  Perform the SFP init if necessary.
+ *
+ **/
+s32 ixgbe_init_phy_ops_82598(struct ixgbe_hw *hw)
 {
        struct ixgbe_mac_info *mac = &hw->mac;
        struct ixgbe_phy_info *phy = &hw->phy;
        s32 ret_val = 0;
        u16 list_offset, data_offset;
 
-       /* Set the bus information prior to PHY identification */
-       mac->ops.get_bus_info(hw);
+       /* Identify the PHY */
+       phy->ops.identify(hw);
 
-       /* Call PHY identify routine to get the phy type */
-       ixgbe_identify_phy_generic(hw);
+       /* Overwrite the link function pointers if copper PHY */
+       if (mac->ops.get_media_type(hw) == ixgbe_media_type_copper) {
+               mac->ops.setup_link = &ixgbe_setup_copper_link_82598;
+               mac->ops.setup_link_speed =
+                                    &ixgbe_setup_copper_link_speed_82598;
+               mac->ops.get_link_capabilities =
+                                 &ixgbe_get_copper_link_capabilities_82598;
+       }
 
-       /* PHY Init */
-       switch (phy->type) {
+       switch (hw->phy.type) {
        case ixgbe_phy_tn:
                phy->ops.check_link = &ixgbe_check_phy_link_tnx;
                phy->ops.get_firmware_version =
@@ -106,8 +137,8 @@ static s32 ixgbe_get_invariants_82598(struct ixgbe_hw *hw)
 
                /* Check to see if SFP+ module is supported */
                ret_val = ixgbe_get_sfp_init_sequence_offsets(hw,
-                                                             &list_offset,
-                                                             &data_offset);
+                                                           &list_offset,
+                                                           &data_offset);
                if (ret_val != 0) {
                        ret_val = IXGBE_ERR_SFP_NOT_SUPPORTED;
                        goto out;
@@ -117,21 +148,6 @@ static s32 ixgbe_get_invariants_82598(struct ixgbe_hw *hw)
                break;
        }
 
-       if (mac->ops.get_media_type(hw) == ixgbe_media_type_copper) {
-               mac->ops.setup_link = &ixgbe_setup_copper_link_82598;
-               mac->ops.setup_link_speed =
-                                    &ixgbe_setup_copper_link_speed_82598;
-               mac->ops.get_link_capabilities =
-                                    &ixgbe_get_copper_link_capabilities_82598;
-       }
-
-       mac->mcft_size = IXGBE_82598_MC_TBL_SIZE;
-       mac->vft_size = IXGBE_82598_VFT_TBL_SIZE;
-       mac->num_rar_entries = IXGBE_82598_RAR_ENTRIES;
-       mac->max_rx_queues = IXGBE_82598_MAX_RX_QUEUES;
-       mac->max_tx_queues = IXGBE_82598_MAX_TX_QUEUES;
-       mac->max_msix_vectors = ixgbe_get_pcie_msix_count_82598(hw);
-
 out:
        return ret_val;
 }
@@ -149,12 +165,19 @@ static s32 ixgbe_get_link_capabilities_82598(struct ixgbe_hw *hw,
                                              bool *autoneg)
 {
        s32 status = 0;
+       u32 autoc = 0;
 
        /*
         * Determine link capabilities based on the stored value of AUTOC,
-        * which represents EEPROM defaults.
+        * which represents EEPROM defaults.  If AUTOC value has not been
+        * stored, use the current register value.
         */
-       switch (hw->mac.orig_autoc & IXGBE_AUTOC_LMS_MASK) {
+       if (hw->mac.orig_link_settings_stored)
+               autoc = hw->mac.orig_autoc;
+       else
+               autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+
+       switch (autoc & IXGBE_AUTOC_LMS_MASK) {
        case IXGBE_AUTOC_LMS_1G_LINK_NO_AN:
                *speed = IXGBE_LINK_SPEED_1GB_FULL;
                *autoneg = false;
@@ -173,9 +196,9 @@ static s32 ixgbe_get_link_capabilities_82598(struct ixgbe_hw *hw,
        case IXGBE_AUTOC_LMS_KX4_AN:
        case IXGBE_AUTOC_LMS_KX4_AN_1G_AN:
                *speed = IXGBE_LINK_SPEED_UNKNOWN;
-               if (hw->mac.orig_autoc & IXGBE_AUTOC_KX4_SUPP)
+               if (autoc & IXGBE_AUTOC_KX4_SUPP)
                        *speed |= IXGBE_LINK_SPEED_10GB_FULL;
-               if (hw->mac.orig_autoc & IXGBE_AUTOC_KX_SUPP)
+               if (autoc & IXGBE_AUTOC_KX_SUPP)
                        *speed |= IXGBE_LINK_SPEED_1GB_FULL;
                *autoneg = true;
                break;
@@ -206,14 +229,13 @@ static s32 ixgbe_get_copper_link_capabilities_82598(struct ixgbe_hw *hw,
        *speed = 0;
        *autoneg = true;
 
-       status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_SPEED_ABILITY,
-                                     IXGBE_MDIO_PMA_PMD_DEV_TYPE,
+       status = hw->phy.ops.read_reg(hw, MDIO_SPEED, MDIO_MMD_PMAPMD,
                                      &speed_ability);
 
        if (status == 0) {
-               if (speed_ability & IXGBE_MDIO_PHY_SPEED_10G)
+               if (speed_ability & MDIO_SPEED_10G)
                    *speed |= IXGBE_LINK_SPEED_10GB_FULL;
-               if (speed_ability & IXGBE_MDIO_PHY_SPEED_1G)
+               if (speed_ability & MDIO_PMA_SPEED_1000)
                    *speed |= IXGBE_LINK_SPEED_1GB_FULL;
        }
 
@@ -271,6 +293,17 @@ static s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw, s32 packetbuf_num)
        u32 rmcs_reg;
        u32 reg;
 
+#ifdef CONFIG_DCB
+       if (hw->fc.requested_mode == ixgbe_fc_pfc)
+               goto out;
+
+#endif /* CONFIG_DCB */
+       /* Negotiate the fc mode to use */
+       ret_val = ixgbe_fc_autoneg(hw);
+       if (ret_val)
+               goto out;
+
+       /* Disable any previous flow control settings */
        fctrl_reg = IXGBE_READ_REG(hw, IXGBE_FCTRL);
        fctrl_reg &= ~(IXGBE_FCTRL_RFCE | IXGBE_FCTRL_RPFCE);
 
@@ -282,14 +315,20 @@ static s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw, s32 packetbuf_num)
         * 0: Flow control is completely disabled
         * 1: Rx flow control is enabled (we can receive pause frames,
         *    but not send pause frames).
-        * 2:  Tx flow control is enabled (we can send pause frames but
+        * 2: Tx flow control is enabled (we can send pause frames but
         *     we do not support receiving pause frames).
         * 3: Both Rx and Tx flow control (symmetric) are enabled.
         * other: Invalid.
+#ifdef CONFIG_DCB
+        * 4: Priority Flow Control is enabled.
+#endif
         */
        switch (hw->fc.current_mode) {
        case ixgbe_fc_none:
-               /* Flow control completely disabled by software override. */
+               /*
+                * Flow control is disabled by software override or autoneg.
+                * The code below will actually disable it in the HW.
+                */
                break;
        case ixgbe_fc_rx_pause:
                /*
@@ -314,6 +353,11 @@ static s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw, s32 packetbuf_num)
                fctrl_reg |= IXGBE_FCTRL_RFCE;
                rmcs_reg |= IXGBE_RMCS_TFCE_802_3X;
                break;
+#ifdef CONFIG_DCB
+       case ixgbe_fc_pfc:
+               goto out;
+               break;
+#endif /* CONFIG_DCB */
        default:
                hw_dbg(hw, "Flow control param set incorrectly\n");
                ret_val = -IXGBE_ERR_CONFIG;
@@ -321,7 +365,8 @@ static s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw, s32 packetbuf_num)
                break;
        }
 
-       /* Enable 802.3x based flow control settings. */
+       /* Set 802.3x based flow control settings. */
+       fctrl_reg |= IXGBE_FCTRL_DPF;
        IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl_reg);
        IXGBE_WRITE_REG(hw, IXGBE_RMCS, rmcs_reg);
 
@@ -340,7 +385,7 @@ static s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw, s32 packetbuf_num)
        }
 
        /* Configure pause time (2 TCs per register) */
-       reg = IXGBE_READ_REG(hw, IXGBE_FCTTV(packetbuf_num));
+       reg = IXGBE_READ_REG(hw, IXGBE_FCTTV(packetbuf_num / 2));
        if ((packetbuf_num & 1) == 0)
                reg = (reg & 0xFFFF0000) | hw->fc.pause_time;
        else
@@ -353,77 +398,6 @@ out:
        return ret_val;
 }
 
-/**
- *  ixgbe_setup_fc_82598 - Configure flow control settings
- *  @hw: pointer to hardware structure
- *  @packetbuf_num: packet buffer number (0-7)
- *
- *  Configures the flow control settings based on SW configuration.  This
- *  function is used for 802.3x flow control configuration only.
- **/
-static s32 ixgbe_setup_fc_82598(struct ixgbe_hw *hw, s32 packetbuf_num)
-{
-       s32 ret_val = 0;
-       ixgbe_link_speed speed;
-       bool link_up;
-
-       /* Validate the packetbuf configuration */
-       if (packetbuf_num < 0 || packetbuf_num > 7) {
-               hw_dbg(hw, "Invalid packet buffer number [%d], expected range is"
-                         " 0-7\n", packetbuf_num);
-               ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
-               goto out;
-       }
-
-       /*
-        * Validate the water mark configuration.  Zero water marks are invalid
-        * because it causes the controller to just blast out fc packets.
-        */
-       if (!hw->fc.low_water || !hw->fc.high_water || !hw->fc.pause_time) {
-               hw_dbg(hw, "Invalid water mark configuration\n");
-               ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
-               goto out;
-       }
-
-       /*
-        * Validate the requested mode.  Strict IEEE mode does not allow
-        * ixgbe_fc_rx_pause because it will cause testing anomalies.
-        */
-       if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) {
-               hw_dbg(hw, "ixgbe_fc_rx_pause not valid in strict IEEE mode\n");
-               ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
-               goto out;
-       }
-
-       /*
-        * 10gig parts do not have a word in the EEPROM to determine the
-        * default flow control setting, so we explicitly set it to full.
-        */
-       if (hw->fc.requested_mode == ixgbe_fc_default)
-               hw->fc.requested_mode = ixgbe_fc_full;
-
-       /*
-        * Save off the requested flow control mode for use later.  Depending
-        * on the link partner's capabilities, we may or may not use this mode.
-        */
-
-       hw->fc.current_mode = hw->fc.requested_mode;
-
-       /* Decide whether to use autoneg or not. */
-       hw->mac.ops.check_link(hw, &speed, &link_up, false);
-       if (!hw->fc.disable_fc_autoneg && hw->phy.multispeed_fiber &&
-           (speed == IXGBE_LINK_SPEED_1GB_FULL))
-               ret_val = ixgbe_fc_autoneg(hw);
-
-       if (ret_val)
-               goto out;
-
-       ret_val = ixgbe_fc_enable_82598(hw, packetbuf_num);
-
-out:
-       return ret_val;
-}
-
 /**
  *  ixgbe_setup_mac_link_82598 - Configures MAC link settings
  *  @hw: pointer to hardware structure
@@ -463,13 +437,6 @@ static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw)
                }
        }
 
-       /*
-        * We want to save off the original Flow Control configuration just in
-        * case we get disconnected and then reconnected into a different hub
-        * or switch with different Flow Control capabilities.
-        */
-       ixgbe_setup_fc_82598(hw, 0);
-
        /* Add delay to filter out noises during initial link setup */
        msleep(50);
 
@@ -500,9 +467,9 @@ static s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw,
         * clear indicates active; set indicates inactive.
         */
        if (hw->phy.type == ixgbe_phy_nl) {
-               hw->phy.ops.read_reg(hw, 0xC79F, IXGBE_TWINAX_DEV, &link_reg);
-               hw->phy.ops.read_reg(hw, 0xC79F, IXGBE_TWINAX_DEV, &link_reg);
-               hw->phy.ops.read_reg(hw, 0xC00C, IXGBE_TWINAX_DEV,
+               hw->phy.ops.read_reg(hw, 0xC79F, MDIO_MMD_PMAPMD, &link_reg);
+               hw->phy.ops.read_reg(hw, 0xC79F, MDIO_MMD_PMAPMD, &link_reg);
+               hw->phy.ops.read_reg(hw, 0xC00C, MDIO_MMD_PMAPMD,
                                     &adapt_comp_reg);
                if (link_up_wait_to_complete) {
                        for (i = 0; i < IXGBE_LINK_UP_TIME; i++) {
@@ -515,10 +482,10 @@ static s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw,
                                }
                                msleep(100);
                                hw->phy.ops.read_reg(hw, 0xC79F,
-                                                    IXGBE_TWINAX_DEV,
+                                                    MDIO_MMD_PMAPMD,
                                                     &link_reg);
                                hw->phy.ops.read_reg(hw, 0xC00C,
-                                                    IXGBE_TWINAX_DEV,
+                                                    MDIO_MMD_PMAPMD,
                                                     &adapt_comp_reg);
                        }
                } else {
@@ -556,6 +523,11 @@ static s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw,
        else
                *speed = IXGBE_LINK_SPEED_1GB_FULL;
 
+       /* if link is down, zero out the current_mode */
+       if (*link_up == false) {
+               hw->fc.current_mode = ixgbe_fc_none;
+               hw->fc.fc_was_autonegged = false;
+       }
 out:
        return 0;
 }
@@ -673,6 +645,7 @@ static s32 ixgbe_setup_copper_link_speed_82598(struct ixgbe_hw *hw,
 static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw)
 {
        s32 status = 0;
+       s32 phy_status = 0;
        u32 ctrl;
        u32 gheccr;
        u32 i;
@@ -716,14 +689,27 @@ static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw)
        }
 
        /* Reset PHY */
-       if (hw->phy.reset_disable == false)
+       if (hw->phy.reset_disable == false) {
+               /* PHY ops must be identified and initialized prior to reset */
+
+               /* Init PHY and function pointers, perform SFP setup */
+               phy_status = hw->phy.ops.init(hw);
+               if (phy_status == IXGBE_ERR_SFP_NOT_SUPPORTED)
+                       goto reset_hw_out;
+               else if (phy_status == IXGBE_ERR_SFP_NOT_PRESENT)
+                       goto no_phy_reset;
+
+
                hw->phy.ops.reset(hw);
+       }
 
+no_phy_reset:
        /*
         * Prevent the PCI-E bus from from hanging by disabling PCI-E master
         * access and verify no pending requests before reset
         */
-       if (ixgbe_disable_pcie_master(hw) != 0) {
+       status = ixgbe_disable_pcie_master(hw);
+       if (status != 0) {
                status = IXGBE_ERR_MASTER_REQUESTS_PENDING;
                hw_dbg(hw, "PCI-E Master disable polling has failed.\n");
        }
@@ -767,9 +753,19 @@ static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw)
                IXGBE_WRITE_REG(hw, IXGBE_AUTOC, hw->mac.orig_autoc);
        }
 
+       /*
+        * Store MAC address from RAR0, clear receive address registers, and
+        * clear the multicast table
+        */
+       hw->mac.ops.init_rx_addrs(hw);
+
        /* Store the permanent mac address */
        hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr);
 
+reset_hw_out:
+       if (phy_status)
+               status = phy_status;
+
        return status;
 }
 
@@ -954,14 +950,14 @@ static s32 ixgbe_read_i2c_eeprom_82598(struct ixgbe_hw *hw, u8 byte_offset,
                sfp_addr = (sfp_addr | IXGBE_I2C_EEPROM_READ_MASK);
                hw->phy.ops.write_reg(hw,
                                      IXGBE_MDIO_PMA_PMD_SDA_SCL_ADDR,
-                                     IXGBE_MDIO_PMA_PMD_DEV_TYPE,
+                                     MDIO_MMD_PMAPMD,
                                      sfp_addr);
 
                /* Poll status */
                for (i = 0; i < 100; i++) {
                        hw->phy.ops.read_reg(hw,
                                             IXGBE_MDIO_PMA_PMD_SDA_SCL_STAT,
-                                            IXGBE_MDIO_PMA_PMD_DEV_TYPE,
+                                            MDIO_MMD_PMAPMD,
                                             &sfp_stat);
                        sfp_stat = sfp_stat & IXGBE_I2C_EEPROM_STATUS_MASK;
                        if (sfp_stat != IXGBE_I2C_EEPROM_STATUS_IN_PROGRESS)
@@ -977,7 +973,7 @@ static s32 ixgbe_read_i2c_eeprom_82598(struct ixgbe_hw *hw, u8 byte_offset,
 
                /* Read data */
                hw->phy.ops.read_reg(hw, IXGBE_MDIO_PMA_PMD_SDA_SCL_DATA,
-                                    IXGBE_MDIO_PMA_PMD_DEV_TYPE, &sfp_data);
+                                    MDIO_MMD_PMAPMD, &sfp_data);
 
                *eeprom_data = (u8)(sfp_data >> 8);
        } else {
@@ -998,35 +994,56 @@ out:
 static u32 ixgbe_get_supported_physical_layer_82598(struct ixgbe_hw *hw)
 {
        u32 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
+       u32 autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+       u32 pma_pmd_10g = autoc & IXGBE_AUTOC_10G_PMA_PMD_MASK;
+       u32 pma_pmd_1g = autoc & IXGBE_AUTOC_1G_PMA_PMD_MASK;
+       u16 ext_ability = 0;
+
+       hw->phy.ops.identify(hw);
+
+       /* Copper PHY must be checked before AUTOC LMS to determine correct
+        * physical layer because 10GBase-T PHYs use LMS = KX4/KX */
+       if (hw->phy.type == ixgbe_phy_tn ||
+           hw->phy.type == ixgbe_phy_cu_unknown) {
+               hw->phy.ops.read_reg(hw, MDIO_PMA_EXTABLE, MDIO_MMD_PMAPMD,
+                                    &ext_ability);
+               if (ext_ability & MDIO_PMA_EXTABLE_10GBT)
+                       physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_T;
+               if (ext_ability & MDIO_PMA_EXTABLE_1000BT)
+                       physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T;
+               if (ext_ability & MDIO_PMA_EXTABLE_100BTX)
+                       physical_layer |= IXGBE_PHYSICAL_LAYER_100BASE_TX;
+               goto out;
+       }
 
-       switch (hw->device_id) {
-       case IXGBE_DEV_ID_82598:
-               /* Default device ID is mezzanine card KX/KX4 */
-               physical_layer = (IXGBE_PHYSICAL_LAYER_10GBASE_KX4 |
-                                 IXGBE_PHYSICAL_LAYER_1000BASE_KX);
-               break;
-       case IXGBE_DEV_ID_82598_BX:
-               physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_BX;
-       case IXGBE_DEV_ID_82598EB_CX4:
-       case IXGBE_DEV_ID_82598_CX4_DUAL_PORT:
-               physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_CX4;
-               break;
-       case IXGBE_DEV_ID_82598_DA_DUAL_PORT:
-               physical_layer = IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU;
+       switch (autoc & IXGBE_AUTOC_LMS_MASK) {
+       case IXGBE_AUTOC_LMS_1G_AN:
+       case IXGBE_AUTOC_LMS_1G_LINK_NO_AN:
+               if (pma_pmd_1g == IXGBE_AUTOC_1G_KX)
+                       physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_KX;
+               else
+                       physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_BX;
                break;
-       case IXGBE_DEV_ID_82598AF_DUAL_PORT:
-       case IXGBE_DEV_ID_82598AF_SINGLE_PORT:
-       case IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM:
-               physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR;
+       case IXGBE_AUTOC_LMS_10G_LINK_NO_AN:
+               if (pma_pmd_10g == IXGBE_AUTOC_10G_CX4)
+                       physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_CX4;
+               else if (pma_pmd_10g == IXGBE_AUTOC_10G_KX4)
+                       physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_KX4;
+               else /* XAUI */
+                       physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
                break;
-       case IXGBE_DEV_ID_82598EB_XF_LR:
-               physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR;
+       case IXGBE_AUTOC_LMS_KX4_AN:
+       case IXGBE_AUTOC_LMS_KX4_AN_1G_AN:
+               if (autoc & IXGBE_AUTOC_KX_SUPP)
+                       physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_KX;
+               if (autoc & IXGBE_AUTOC_KX4_SUPP)
+                       physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_KX4;
                break;
-       case IXGBE_DEV_ID_82598AT:
-               physical_layer = (IXGBE_PHYSICAL_LAYER_10GBASE_T |
-                                 IXGBE_PHYSICAL_LAYER_1000BASE_T);
+       default:
                break;
-       case IXGBE_DEV_ID_82598EB_SFP_LOM:
+       }
+
+       if (hw->phy.type == ixgbe_phy_nl) {
                hw->phy.ops.identify_sfp(hw);
 
                switch (hw->phy.sfp_type) {
@@ -1043,13 +1060,25 @@ static u32 ixgbe_get_supported_physical_layer_82598(struct ixgbe_hw *hw)
                        physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
                        break;
                }
-               break;
+       }
 
+       switch (hw->device_id) {
+       case IXGBE_DEV_ID_82598_DA_DUAL_PORT:
+               physical_layer = IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU;
+               break;
+       case IXGBE_DEV_ID_82598AF_DUAL_PORT:
+       case IXGBE_DEV_ID_82598AF_SINGLE_PORT:
+       case IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM:
+               physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR;
+               break;
+       case IXGBE_DEV_ID_82598EB_XF_LR:
+               physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR;
+               break;
        default:
-               physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
                break;
        }
 
+out:
        return physical_layer;
 }
 
@@ -1086,7 +1115,7 @@ static struct ixgbe_mac_operations mac_ops_82598 = {
        .disable_mc             = &ixgbe_disable_mc_generic,
        .clear_vfta             = &ixgbe_clear_vfta_82598,
        .set_vfta               = &ixgbe_set_vfta_82598,
-       .setup_fc               = &ixgbe_setup_fc_82598,
+       .fc_enable              = &ixgbe_fc_enable_82598,
 };
 
 static struct ixgbe_eeprom_operations eeprom_ops_82598 = {
@@ -1099,6 +1128,7 @@ static struct ixgbe_eeprom_operations eeprom_ops_82598 = {
 static struct ixgbe_phy_operations phy_ops_82598 = {
        .identify               = &ixgbe_identify_phy_generic,
        .identify_sfp           = &ixgbe_identify_sfp_module_generic,
+       .init                   = &ixgbe_init_phy_ops_82598,
        .reset                  = &ixgbe_reset_phy_generic,
        .read_reg               = &ixgbe_read_phy_reg_generic,
        .write_reg              = &ixgbe_write_phy_reg_generic,
index 29771fbaa42d2a20e7af615d24c515aa77a9581a..1984cab7d48b8ab9009f076094971986a58135a2 100644 (file)
@@ -71,10 +71,10 @@ s32 ixgbe_clear_vfta_82599(struct ixgbe_hw *hw);
 s32 ixgbe_init_uta_tables_82599(struct ixgbe_hw *hw);
 s32 ixgbe_read_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 *val);
 s32 ixgbe_write_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 val);
-s32 ixgbe_start_hw_rev_0_82599(struct ixgbe_hw *hw);
 s32 ixgbe_identify_phy_82599(struct ixgbe_hw *hw);
 s32 ixgbe_start_hw_82599(struct ixgbe_hw *hw);
 u32 ixgbe_get_supported_physical_layer_82599(struct ixgbe_hw *hw);
+static s32 ixgbe_verify_fw_version_82599(struct ixgbe_hw *hw);
 
 void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw)
 {
@@ -100,22 +100,36 @@ s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw)
 
        if (hw->phy.sfp_type != ixgbe_sfp_type_unknown) {
                ixgbe_init_mac_link_ops_82599(hw);
+
+               hw->phy.ops.reset = NULL;
+
                ret_val = ixgbe_get_sfp_init_sequence_offsets(hw, &list_offset,
                                                              &data_offset);
 
                if (ret_val != 0)
                        goto setup_sfp_out;
 
+               /* PHY config will finish before releasing the semaphore */
+               ret_val = ixgbe_acquire_swfw_sync(hw, IXGBE_GSSR_MAC_CSR_SM);
+               if (ret_val != 0) {
+                       ret_val = IXGBE_ERR_SWFW_SYNC;
+                       goto setup_sfp_out;
+               }
+
                hw->eeprom.ops.read(hw, ++data_offset, &data_value);
                while (data_value != 0xffff) {
                        IXGBE_WRITE_REG(hw, IXGBE_CORECTL, data_value);
                        IXGBE_WRITE_FLUSH(hw);
                        hw->eeprom.ops.read(hw, ++data_offset, &data_value);
                }
-               /* Now restart DSP */
-               IXGBE_WRITE_REG(hw, IXGBE_CORECTL, 0x00000102);
-               IXGBE_WRITE_REG(hw, IXGBE_CORECTL, 0x00000b1d);
-               IXGBE_WRITE_FLUSH(hw);
+               /* Now restart DSP by setting Restart_AN */
+               IXGBE_WRITE_REG(hw, IXGBE_AUTOC,
+                   (IXGBE_READ_REG(hw, IXGBE_AUTOC) | IXGBE_AUTOC_AN_RESTART));
+
+               /* Release the semaphore */
+               ixgbe_release_swfw_sync(hw, IXGBE_GSSR_MAC_CSR_SM);
+               /* Delay obtaining semaphore again to allow FW access */
+               msleep(hw->eeprom.semaphore_delay);
        }
 
 setup_sfp_out:
@@ -146,51 +160,60 @@ u32 ixgbe_get_pcie_msix_count_82599(struct ixgbe_hw *hw)
 static s32 ixgbe_get_invariants_82599(struct ixgbe_hw *hw)
 {
        struct ixgbe_mac_info *mac = &hw->mac;
-       struct ixgbe_phy_info *phy = &hw->phy;
-       s32 ret_val;
 
-       /* Set the bus information prior to PHY identification */
-       mac->ops.get_bus_info(hw);
+       ixgbe_init_mac_link_ops_82599(hw);
+
+       mac->mcft_size = IXGBE_82599_MC_TBL_SIZE;
+       mac->vft_size = IXGBE_82599_VFT_TBL_SIZE;
+       mac->num_rar_entries = IXGBE_82599_RAR_ENTRIES;
+       mac->max_rx_queues = IXGBE_82599_MAX_RX_QUEUES;
+       mac->max_tx_queues = IXGBE_82599_MAX_TX_QUEUES;
+       mac->max_msix_vectors = ixgbe_get_pcie_msix_count_82599(hw);
 
-       /* Call PHY identify routine to get the Cu or SFI phy type */
-       ret_val = phy->ops.identify(hw);
+       return 0;
+}
+
+/**
+ *  ixgbe_init_phy_ops_82599 - PHY/SFP specific init
+ *  @hw: pointer to hardware structure
+ *
+ *  Initialize any function pointers that were not able to be
+ *  set during get_invariants because the PHY/SFP type was
+ *  not known.  Perform the SFP init if necessary.
+ *
+ **/
+s32 ixgbe_init_phy_ops_82599(struct ixgbe_hw *hw)
+{
+       struct ixgbe_mac_info *mac = &hw->mac;
+       struct ixgbe_phy_info *phy = &hw->phy;
+       s32 ret_val = 0;
 
-       if (ret_val == IXGBE_ERR_SFP_NOT_SUPPORTED)
-               goto get_invariants_out;
+       /* Identify the PHY or SFP module */
+       ret_val = phy->ops.identify(hw);
 
+       /* Setup function pointers based on detected SFP module and speeds */
        ixgbe_init_mac_link_ops_82599(hw);
 
-       /* Setup SFP module if there is one present. */
-       ret_val = mac->ops.setup_sfp(hw);
-
        /* If copper media, overwrite with copper function pointers */
        if (mac->ops.get_media_type(hw) == ixgbe_media_type_copper) {
                mac->ops.setup_link = &ixgbe_setup_copper_link_82599;
                mac->ops.setup_link_speed =
-                                 &ixgbe_setup_copper_link_speed_82599;
+                                    &ixgbe_setup_copper_link_speed_82599;
                mac->ops.get_link_capabilities =
                                  &ixgbe_get_copper_link_capabilities_82599;
        }
 
-       /* PHY Init */
+       /* Set necessary function pointers based on phy type */
        switch (hw->phy.type) {
        case ixgbe_phy_tn:
                phy->ops.check_link = &ixgbe_check_phy_link_tnx;
                phy->ops.get_firmware_version =
-                                 &ixgbe_get_phy_firmware_version_tnx;
+                            &ixgbe_get_phy_firmware_version_tnx;
                break;
        default:
                break;
        }
 
-       mac->mcft_size = IXGBE_82599_MC_TBL_SIZE;
-       mac->vft_size = IXGBE_82599_VFT_TBL_SIZE;
-       mac->num_rar_entries = IXGBE_82599_RAR_ENTRIES;
-       mac->max_rx_queues = IXGBE_82599_MAX_RX_QUEUES;
-       mac->max_tx_queues = IXGBE_82599_MAX_TX_QUEUES;
-       mac->max_msix_vectors = ixgbe_get_pcie_msix_count_82599(hw);
-
-get_invariants_out:
        return ret_val;
 }
 
@@ -207,8 +230,19 @@ s32 ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw,
                                       bool *negotiation)
 {
        s32 status = 0;
+       u32 autoc = 0;
+
+       /*
+        * Determine link capabilities based on the stored value of AUTOC,
+        * which represents EEPROM defaults.  If AUTOC value has not been
+        * stored, use the current register value.
+        */
+       if (hw->mac.orig_link_settings_stored)
+               autoc = hw->mac.orig_autoc;
+       else
+               autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
 
-       switch (hw->mac.orig_autoc & IXGBE_AUTOC_LMS_MASK) {
+       switch (autoc & IXGBE_AUTOC_LMS_MASK) {
        case IXGBE_AUTOC_LMS_1G_LINK_NO_AN:
                *speed = IXGBE_LINK_SPEED_1GB_FULL;
                *negotiation = false;
@@ -232,22 +266,22 @@ s32 ixgbe_get_link_capabilities_82599(struct ixgbe_hw *hw,
        case IXGBE_AUTOC_LMS_KX4_KX_KR:
        case IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN:
                *speed = IXGBE_LINK_SPEED_UNKNOWN;
-               if (hw->mac.orig_autoc & IXGBE_AUTOC_KR_SUPP)
+               if (autoc & IXGBE_AUTOC_KR_SUPP)
                        *speed |= IXGBE_LINK_SPEED_10GB_FULL;
-               if (hw->mac.orig_autoc & IXGBE_AUTOC_KX4_SUPP)
+               if (autoc & IXGBE_AUTOC_KX4_SUPP)
                        *speed |= IXGBE_LINK_SPEED_10GB_FULL;
-               if (hw->mac.orig_autoc & IXGBE_AUTOC_KX_SUPP)
+               if (autoc & IXGBE_AUTOC_KX_SUPP)
                        *speed |= IXGBE_LINK_SPEED_1GB_FULL;
                *negotiation = true;
                break;
 
        case IXGBE_AUTOC_LMS_KX4_KX_KR_SGMII:
                *speed = IXGBE_LINK_SPEED_100_FULL;
-               if (hw->mac.orig_autoc & IXGBE_AUTOC_KR_SUPP)
+               if (autoc & IXGBE_AUTOC_KR_SUPP)
                        *speed |= IXGBE_LINK_SPEED_10GB_FULL;
-               if (hw->mac.orig_autoc & IXGBE_AUTOC_KX4_SUPP)
+               if (autoc & IXGBE_AUTOC_KX4_SUPP)
                        *speed |= IXGBE_LINK_SPEED_10GB_FULL;
-               if (hw->mac.orig_autoc & IXGBE_AUTOC_KX_SUPP)
+               if (autoc & IXGBE_AUTOC_KX_SUPP)
                        *speed |= IXGBE_LINK_SPEED_1GB_FULL;
                *negotiation = true;
                break;
@@ -291,14 +325,13 @@ static s32 ixgbe_get_copper_link_capabilities_82599(struct ixgbe_hw *hw,
        *speed = 0;
        *autoneg = true;
 
-       status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_SPEED_ABILITY,
-                                     IXGBE_MDIO_PMA_PMD_DEV_TYPE,
+       status = hw->phy.ops.read_reg(hw, MDIO_SPEED, MDIO_MMD_PMAPMD,
                                      &speed_ability);
 
        if (status == 0) {
-               if (speed_ability & IXGBE_MDIO_PHY_SPEED_10G)
+               if (speed_ability & MDIO_SPEED_10G)
                    *speed |= IXGBE_LINK_SPEED_10GB_FULL;
-               if (speed_ability & IXGBE_MDIO_PHY_SPEED_1G)
+               if (speed_ability & MDIO_PMA_SPEED_1000)
                    *speed |= IXGBE_LINK_SPEED_1GB_FULL;
        }
 
@@ -323,8 +356,8 @@ enum ixgbe_media_type ixgbe_get_media_type_82599(struct ixgbe_hw *hw)
        }
 
        switch (hw->device_id) {
-       case IXGBE_DEV_ID_82599:
        case IXGBE_DEV_ID_82599_KX4:
+       case IXGBE_DEV_ID_82599_XAUI_LOM:
                /* Default device ID is mezzanine card KX/KX4 */
                media_type = ixgbe_media_type_backplane;
                break;
@@ -380,9 +413,6 @@ s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw)
                }
        }
 
-       /* Set up flow control */
-       status = ixgbe_setup_fc_generic(hw, 0);
-
        /* Add delay to filter out noises during initial link setup */
        msleep(50);
 
@@ -428,11 +458,31 @@ s32 ixgbe_setup_mac_link_speed_multispeed_fiber(struct ixgbe_hw *hw,
        u32 esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP);
        bool link_up = false;
        bool negotiation;
+       int i;
 
        /* Mask off requested but non-supported speeds */
        hw->mac.ops.get_link_capabilities(hw, &phy_link_speed, &negotiation);
        speed &= phy_link_speed;
 
+        /* Set autoneg_advertised value based on input link speed */
+       hw->phy.autoneg_advertised = 0;
+
+       if (speed & IXGBE_LINK_SPEED_10GB_FULL)
+               hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_10GB_FULL;
+
+       if (speed & IXGBE_LINK_SPEED_1GB_FULL)
+               hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_1GB_FULL;
+
+       /*
+        * When the driver changes the link speeds that it can support,
+        * it sets autotry_restart to true to indicate that we need to
+        * initiate a new autotry session with the link partner.  To do
+        * so, we set the speed then disable and re-enable the tx laser, to
+        * alert the link partner that it also needs to restart autotry on its
+        * end.  This is consistent with true clause 37 autoneg, which also
+        * involves a loss of signal.
+        */
+
        /*
         * Try each speed one by one, highest priority first.  We do this in
         * software because 10gb fiber doesn't support speed autonegotiation.
@@ -441,21 +491,52 @@ s32 ixgbe_setup_mac_link_speed_multispeed_fiber(struct ixgbe_hw *hw,
                speedcnt++;
                highest_link_speed = IXGBE_LINK_SPEED_10GB_FULL;
 
-               /* Set hardware SDP's */
+               /* If we already have link at this speed, just jump out */
+               hw->mac.ops.check_link(hw, &phy_link_speed, &link_up, false);
+
+               if ((phy_link_speed == IXGBE_LINK_SPEED_10GB_FULL) && link_up)
+                       goto out;
+
+               /* Set the module link speed */
                esdp_reg |= (IXGBE_ESDP_SDP5_DIR | IXGBE_ESDP_SDP5);
                IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
 
-               ixgbe_setup_mac_link_speed_82599(hw,
-                                                IXGBE_LINK_SPEED_10GB_FULL,
-                                                autoneg,
-                                                autoneg_wait_to_complete);
-
-               msleep(50);
+               /* Allow module to change analog characteristics (1G->10G) */
+               msleep(40);
 
-               /* If we have link, just jump out */
-               hw->mac.ops.check_link(hw, &phy_link_speed, &link_up, false);
-               if (link_up)
+               status = ixgbe_setup_mac_link_speed_82599(hw,
+                                                    IXGBE_LINK_SPEED_10GB_FULL,
+                                                    autoneg,
+                                                    autoneg_wait_to_complete);
+               if (status != 0)
                        goto out;
+
+               /* Flap the tx laser if it has not already been done */
+               if (hw->mac.autotry_restart) {
+                       /* Disable tx laser; allow 100us to go dark per spec */
+                       esdp_reg |= IXGBE_ESDP_SDP3;
+                       IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
+                       udelay(100);
+
+                       /* Enable tx laser; allow 2ms to light up per spec */
+                       esdp_reg &= ~IXGBE_ESDP_SDP3;
+                       IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
+                       msleep(2);
+
+                       hw->mac.autotry_restart = false;
+               }
+
+               /* The controller may take up to 500ms at 10g to acquire link */
+               for (i = 0; i < 5; i++) {
+                       /* Wait for the link partner to also set speed */
+                       msleep(100);
+
+                       /* If we have link, just jump out */
+                       hw->mac.ops.check_link(hw, &phy_link_speed,
+                                              &link_up, false);
+                       if (link_up)
+                               goto out;
+               }
        }
 
        if (speed & IXGBE_LINK_SPEED_1GB_FULL) {
@@ -463,16 +544,44 @@ s32 ixgbe_setup_mac_link_speed_multispeed_fiber(struct ixgbe_hw *hw,
                if (highest_link_speed == IXGBE_LINK_SPEED_UNKNOWN)
                        highest_link_speed = IXGBE_LINK_SPEED_1GB_FULL;
 
-               /* Set hardware SDP's */
+               /* If we already have link at this speed, just jump out */
+               hw->mac.ops.check_link(hw, &phy_link_speed, &link_up, false);
+
+               if ((phy_link_speed == IXGBE_LINK_SPEED_1GB_FULL) && link_up)
+                       goto out;
+
+               /* Set the module link speed */
                esdp_reg &= ~IXGBE_ESDP_SDP5;
                esdp_reg |= IXGBE_ESDP_SDP5_DIR;
                IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
 
-               ixgbe_setup_mac_link_speed_82599(
-                       hw, IXGBE_LINK_SPEED_1GB_FULL, autoneg,
-                       autoneg_wait_to_complete);
+               /* Allow module to change analog characteristics (10G->1G) */
+               msleep(40);
 
-               msleep(50);
+               status = ixgbe_setup_mac_link_speed_82599(hw,
+                                                     IXGBE_LINK_SPEED_1GB_FULL,
+                                                     autoneg,
+                                                     autoneg_wait_to_complete);
+               if (status != 0)
+                       goto out;
+
+               /* Flap the tx laser if it has not already been done */
+               if (hw->mac.autotry_restart) {
+                       /* Disable tx laser; allow 100us to go dark per spec */
+                       esdp_reg |= IXGBE_ESDP_SDP3;
+                       IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
+                       udelay(100);
+
+                       /* Enable tx laser; allow 2ms to light up per spec */
+                       esdp_reg &= ~IXGBE_ESDP_SDP3;
+                       IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp_reg);
+                       msleep(2);
+
+                       hw->mac.autotry_restart = false;
+               }
+
+               /* Wait for the link partner to also set speed */
+               msleep(100);
 
                /* If we have link, just jump out */
                hw->mac.ops.check_link(hw, &phy_link_speed, &link_up, false);
@@ -538,6 +647,11 @@ s32 ixgbe_check_mac_link_82599(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
        else
                *speed = IXGBE_LINK_SPEED_100_FULL;
 
+       /* if link is down, zero out the current_mode */
+       if (*link_up == false) {
+               hw->fc.current_mode = ixgbe_fc_none;
+               hw->fc.fc_was_autonegged = false;
+       }
 
        return 0;
 }
@@ -558,6 +672,8 @@ s32 ixgbe_setup_mac_link_speed_82599(struct ixgbe_hw *hw,
        s32 status = 0;
        u32 autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
        u32 autoc2 = IXGBE_READ_REG(hw, IXGBE_AUTOC2);
+       u32 start_autoc = autoc;
+       u32 orig_autoc = 0;
        u32 link_mode = autoc & IXGBE_AUTOC_LMS_MASK;
        u32 pma_pmd_1g = autoc & IXGBE_AUTOC_1G_PMA_PMD_MASK;
        u32 pma_pmd_10g_serial = autoc2 & IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_MASK;
@@ -571,15 +687,25 @@ s32 ixgbe_setup_mac_link_speed_82599(struct ixgbe_hw *hw,
 
        if (speed == IXGBE_LINK_SPEED_UNKNOWN) {
                status = IXGBE_ERR_LINK_SETUP;
-       } else if (link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR ||
-                  link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN ||
-                  link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR_SGMII) {
+               goto out;
+       }
+
+       /* Use stored value (EEPROM defaults) of AUTOC to find KR/KX4 support*/
+       if (hw->mac.orig_link_settings_stored)
+               orig_autoc = hw->mac.orig_autoc;
+       else
+               orig_autoc = autoc;
+
+
+       if (link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR ||
+           link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN ||
+           link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR_SGMII) {
                /* Set KX4/KX/KR support according to speed requested */
                autoc &= ~(IXGBE_AUTOC_KX4_KX_SUPP_MASK | IXGBE_AUTOC_KR_SUPP);
                if (speed & IXGBE_LINK_SPEED_10GB_FULL)
-                       if (hw->mac.orig_autoc & IXGBE_AUTOC_KX4_SUPP)
+                       if (orig_autoc & IXGBE_AUTOC_KX4_SUPP)
                                autoc |= IXGBE_AUTOC_KX4_SUPP;
-                       if (hw->mac.orig_autoc & IXGBE_AUTOC_KR_SUPP)
+                       if (orig_autoc & IXGBE_AUTOC_KR_SUPP)
                                autoc |= IXGBE_AUTOC_KR_SUPP;
                if (speed & IXGBE_LINK_SPEED_1GB_FULL)
                        autoc |= IXGBE_AUTOC_KX_SUPP;
@@ -605,7 +731,7 @@ s32 ixgbe_setup_mac_link_speed_82599(struct ixgbe_hw *hw,
                }
        }
 
-       if (status == 0) {
+       if (autoc != start_autoc) {
                /* Restart link */
                autoc |= IXGBE_AUTOC_AN_RESTART;
                IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc);
@@ -632,13 +758,11 @@ s32 ixgbe_setup_mac_link_speed_82599(struct ixgbe_hw *hw,
                        }
                }
 
-               /* Set up flow control */
-               status = ixgbe_setup_fc_generic(hw, 0);
-
                /* Add delay to filter out noises during initial link setup */
                msleep(50);
        }
 
+out:
        return status;
 }
 
@@ -705,14 +829,30 @@ s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw)
        /* Call adapter stop to disable tx/rx and clear interrupts */
        hw->mac.ops.stop_adapter(hw);
 
+       /* PHY ops must be identified and initialized prior to reset */
+
+       /* Init PHY and function pointers, perform SFP setup */
+       status = hw->phy.ops.init(hw);
+
+       if (status == IXGBE_ERR_SFP_NOT_SUPPORTED)
+               goto reset_hw_out;
+
+       /* Setup SFP module if there is one present. */
+       if (hw->phy.sfp_setup_needed) {
+               status = hw->mac.ops.setup_sfp(hw);
+               hw->phy.sfp_setup_needed = false;
+       }
+
        /* Reset PHY */
-       hw->phy.ops.reset(hw);
+       if (hw->phy.reset_disable == false && hw->phy.ops.reset != NULL)
+               hw->phy.ops.reset(hw);
 
        /*
         * Prevent the PCI-E bus from from hanging by disabling PCI-E master
         * access and verify no pending requests before reset
         */
-       if (ixgbe_disable_pcie_master(hw) != 0) {
+       status = ixgbe_disable_pcie_master(hw);
+       if (status != 0) {
                status = IXGBE_ERR_MASTER_REQUESTS_PENDING;
                hw_dbg(hw, "PCI-E Master disable polling has failed.\n");
        }
@@ -770,9 +910,30 @@ s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw)
                }
        }
 
+       /*
+        * Store MAC address from RAR0, clear receive address registers, and
+        * clear the multicast table.  Also reset num_rar_entries to 128,
+        * since we modify this value when programming the SAN MAC address.
+        */
+       hw->mac.num_rar_entries = 128;
+       hw->mac.ops.init_rx_addrs(hw);
+
        /* Store the permanent mac address */
        hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr);
 
+       /* Store the permanent SAN mac address */
+       hw->mac.ops.get_san_mac_addr(hw, hw->mac.san_addr);
+
+       /* Add the SAN MAC address to the RAR only if it's a valid address */
+       if (ixgbe_validate_mac_addr(hw->mac.san_addr) == 0) {
+               hw->mac.ops.set_rar(hw, hw->mac.num_rar_entries - 1,
+                                   hw->mac.san_addr, 0, IXGBE_RAH_AV);
+
+               /* Reserve the last RAR for the SAN MAC address */
+               hw->mac.num_rar_entries--;
+       }
+
+reset_hw_out:
        return status;
 }
 
@@ -1004,165 +1165,1144 @@ s32 ixgbe_init_uta_tables_82599(struct ixgbe_hw *hw)
 }
 
 /**
- *  ixgbe_read_analog_reg8_82599 - Reads 8 bit Omer analog register
+ *  ixgbe_reinit_fdir_tables_82599 - Reinitialize Flow Director tables.
  *  @hw: pointer to hardware structure
- *  @reg: analog register to read
- *  @val: read value
- *
- *  Performs read operation to Omer analog register specified.
  **/
-s32 ixgbe_read_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 *val)
+s32 ixgbe_reinit_fdir_tables_82599(struct ixgbe_hw *hw)
 {
-       u32  core_ctl;
+       int i;
+       u32 fdirctrl = IXGBE_READ_REG(hw, IXGBE_FDIRCTRL);
+       fdirctrl &= ~IXGBE_FDIRCTRL_INIT_DONE;
 
-       IXGBE_WRITE_REG(hw, IXGBE_CORECTL, IXGBE_CORECTL_WRITE_CMD |
-                       (reg << 8));
+       /*
+        * Before starting reinitialization process,
+        * FDIRCMD.CMD must be zero.
+        */
+       for (i = 0; i < IXGBE_FDIRCMD_CMD_POLL; i++) {
+               if (!(IXGBE_READ_REG(hw, IXGBE_FDIRCMD) &
+                     IXGBE_FDIRCMD_CMD_MASK))
+                       break;
+               udelay(10);
+       }
+       if (i >= IXGBE_FDIRCMD_CMD_POLL) {
+               hw_dbg(hw ,"Flow Director previous command isn't complete, "
+                      "aborting table re-initialization. \n");
+               return IXGBE_ERR_FDIR_REINIT_FAILED;
+       }
+
+       IXGBE_WRITE_REG(hw, IXGBE_FDIRFREE, 0);
+       IXGBE_WRITE_FLUSH(hw);
+       /*
+        * 82599 adapters flow director init flow cannot be restarted,
+        * Workaround 82599 silicon errata by performing the following steps
+        * before re-writing the FDIRCTRL control register with the same value.
+        * - write 1 to bit 8 of FDIRCMD register &
+        * - write 0 to bit 8 of FDIRCMD register
+        */
+       IXGBE_WRITE_REG(hw, IXGBE_FDIRCMD,
+                       (IXGBE_READ_REG(hw, IXGBE_FDIRCMD) |
+                        IXGBE_FDIRCMD_CLEARHT));
+       IXGBE_WRITE_FLUSH(hw);
+       IXGBE_WRITE_REG(hw, IXGBE_FDIRCMD,
+                       (IXGBE_READ_REG(hw, IXGBE_FDIRCMD) &
+                        ~IXGBE_FDIRCMD_CLEARHT));
+       IXGBE_WRITE_FLUSH(hw);
+       /*
+        * Clear FDIR Hash register to clear any leftover hashes
+        * waiting to be programmed.
+        */
+       IXGBE_WRITE_REG(hw, IXGBE_FDIRHASH, 0x00);
        IXGBE_WRITE_FLUSH(hw);
-       udelay(10);
-       core_ctl = IXGBE_READ_REG(hw, IXGBE_CORECTL);
-       *val = (u8)core_ctl;
 
-       return 0;
-}
+       IXGBE_WRITE_REG(hw, IXGBE_FDIRCTRL, fdirctrl);
+       IXGBE_WRITE_FLUSH(hw);
 
-/**
- *  ixgbe_write_analog_reg8_82599 - Writes 8 bit Omer analog register
- *  @hw: pointer to hardware structure
- *  @reg: atlas register to write
- *  @val: value to write
- *
- *  Performs write operation to Omer analog register specified.
- **/
-s32 ixgbe_write_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 val)
-{
-       u32  core_ctl;
+       /* Poll init-done after we write FDIRCTRL register */
+       for (i = 0; i < IXGBE_FDIR_INIT_DONE_POLL; i++) {
+               if (IXGBE_READ_REG(hw, IXGBE_FDIRCTRL) &
+                                  IXGBE_FDIRCTRL_INIT_DONE)
+                       break;
+               udelay(10);
+       }
+       if (i >= IXGBE_FDIR_INIT_DONE_POLL) {
+               hw_dbg(hw, "Flow Director Signature poll time exceeded!\n");
+               return IXGBE_ERR_FDIR_REINIT_FAILED;
+       }
 
-       core_ctl = (reg << 8) | val;
-       IXGBE_WRITE_REG(hw, IXGBE_CORECTL, core_ctl);
-       IXGBE_WRITE_FLUSH(hw);
-       udelay(10);
+       /* Clear FDIR statistics registers (read to clear) */
+       IXGBE_READ_REG(hw, IXGBE_FDIRUSTAT);
+       IXGBE_READ_REG(hw, IXGBE_FDIRFSTAT);
+       IXGBE_READ_REG(hw, IXGBE_FDIRMATCH);
+       IXGBE_READ_REG(hw, IXGBE_FDIRMISS);
+       IXGBE_READ_REG(hw, IXGBE_FDIRLEN);
 
        return 0;
 }
 
 /**
- *  ixgbe_start_hw_82599 - Prepare hardware for Tx/Rx
+ *  ixgbe_init_fdir_signature_82599 - Initialize Flow Director signature filters
  *  @hw: pointer to hardware structure
- *
- *  Starts the hardware using the generic start_hw function.
- *  Then performs device-specific:
- *  Clears the rate limiter registers.
+ *  @pballoc: which mode to allocate filters with
  **/
-s32 ixgbe_start_hw_82599(struct ixgbe_hw *hw)
+s32 ixgbe_init_fdir_signature_82599(struct ixgbe_hw *hw, u32 pballoc)
 {
-       u32 q_num;
+       u32 fdirctrl = 0;
+       u32 pbsize;
+       int i;
+
+       /*
+        * Before enabling Flow Director, the Rx Packet Buffer size
+        * must be reduced.  The new value is the current size minus
+        * flow director memory usage size.
+        */
+       pbsize = (1 << (IXGBE_FDIR_PBALLOC_SIZE_SHIFT + pballoc));
+       IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(0),
+           (IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(0)) - pbsize));
 
-       ixgbe_start_hw_generic(hw);
+       /*
+        * The defaults in the HW for RX PB 1-7 are not zero and so should be
+        * intialized to zero for non DCB mode otherwise actual total RX PB
+        * would be bigger than programmed and filter space would run into
+        * the PB 0 region.
+        */
+       for (i = 1; i < 8; i++)
+               IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), 0);
 
-       /* Clear the rate limiters */
-       for (q_num = 0; q_num < hw->mac.max_tx_queues; q_num++) {
-               IXGBE_WRITE_REG(hw, IXGBE_RTTDQSEL, q_num);
-               IXGBE_WRITE_REG(hw, IXGBE_RTTBCNRC, 0);
-       }
+       /* Send interrupt when 64 filters are left */
+       fdirctrl |= 4 << IXGBE_FDIRCTRL_FULL_THRESH_SHIFT;
+
+       /* Set the maximum length per hash bucket to 0xA filters */
+       fdirctrl |= 0xA << IXGBE_FDIRCTRL_MAX_LENGTH_SHIFT;
+
+       switch (pballoc) {
+       case IXGBE_FDIR_PBALLOC_64K:
+               /* 8k - 1 signature filters */
+               fdirctrl |= IXGBE_FDIRCTRL_PBALLOC_64K;
+               break;
+       case IXGBE_FDIR_PBALLOC_128K:
+               /* 16k - 1 signature filters */
+               fdirctrl |= IXGBE_FDIRCTRL_PBALLOC_128K;
+               break;
+       case IXGBE_FDIR_PBALLOC_256K:
+               /* 32k - 1 signature filters */
+               fdirctrl |= IXGBE_FDIRCTRL_PBALLOC_256K;
+               break;
+       default:
+               /* bad value */
+               return IXGBE_ERR_CONFIG;
+       };
+
+       /* Move the flexible bytes to use the ethertype - shift 6 words */
+       fdirctrl |= (0x6 << IXGBE_FDIRCTRL_FLEX_SHIFT);
+
+       fdirctrl |= IXGBE_FDIRCTRL_REPORT_STATUS;
+
+       /* Prime the keys for hashing */
+       IXGBE_WRITE_REG(hw, IXGBE_FDIRHKEY,
+                       htonl(IXGBE_ATR_BUCKET_HASH_KEY));
+       IXGBE_WRITE_REG(hw, IXGBE_FDIRSKEY,
+                       htonl(IXGBE_ATR_SIGNATURE_HASH_KEY));
+
+       /*
+        * Poll init-done after we write the register.  Estimated times:
+        *      10G: PBALLOC = 11b, timing is 60us
+        *       1G: PBALLOC = 11b, timing is 600us
+        *     100M: PBALLOC = 11b, timing is 6ms
+        *
+        *     Multiple these timings by 4 if under full Rx load
+        *
+        * So we'll poll for IXGBE_FDIR_INIT_DONE_POLL times, sleeping for
+        * 1 msec per poll time.  If we're at line rate and drop to 100M, then
+        * this might not finish in our poll time, but we can live with that
+        * for now.
+        */
+       IXGBE_WRITE_REG(hw, IXGBE_FDIRCTRL, fdirctrl);
        IXGBE_WRITE_FLUSH(hw);
+       for (i = 0; i < IXGBE_FDIR_INIT_DONE_POLL; i++) {
+               if (IXGBE_READ_REG(hw, IXGBE_FDIRCTRL) &
+                                  IXGBE_FDIRCTRL_INIT_DONE)
+                       break;
+               msleep(1);
+       }
+       if (i >= IXGBE_FDIR_INIT_DONE_POLL)
+               hw_dbg(hw, "Flow Director Signature poll time exceeded!\n");
 
        return 0;
 }
 
 /**
- *  ixgbe_identify_phy_82599 - Get physical layer module
+ *  ixgbe_init_fdir_perfect_82599 - Initialize Flow Director perfect filters
  *  @hw: pointer to hardware structure
- *
- *  Determines the physical layer module found on the current adapter.
+ *  @pballoc: which mode to allocate filters with
  **/
-s32 ixgbe_identify_phy_82599(struct ixgbe_hw *hw)
+s32 ixgbe_init_fdir_perfect_82599(struct ixgbe_hw *hw, u32 pballoc)
 {
-       s32 status = IXGBE_ERR_PHY_ADDR_INVALID;
-       status = ixgbe_identify_phy_generic(hw);
-       if (status != 0)
-               status = ixgbe_identify_sfp_module_generic(hw);
-       return status;
-}
+       u32 fdirctrl = 0;
+       u32 pbsize;
+       int i;
 
-/**
- *  ixgbe_get_supported_physical_layer_82599 - Returns physical layer type
- *  @hw: pointer to hardware structure
- *
- *  Determines physical layer capabilities of the current configuration.
- **/
-u32 ixgbe_get_supported_physical_layer_82599(struct ixgbe_hw *hw)
-{
-       u32 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
-       u8 comp_codes_10g = 0;
+       /*
+        * Before enabling Flow Director, the Rx Packet Buffer size
+        * must be reduced.  The new value is the current size minus
+        * flow director memory usage size.
+        */
+       pbsize = (1 << (IXGBE_FDIR_PBALLOC_SIZE_SHIFT + pballoc));
+       IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(0),
+           (IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(0)) - pbsize));
 
-       switch (hw->device_id) {
-       case IXGBE_DEV_ID_82599:
-       case IXGBE_DEV_ID_82599_KX4:
-               /* Default device ID is mezzanine card KX/KX4 */
-               physical_layer = (IXGBE_PHYSICAL_LAYER_10GBASE_KX4 |
-                                 IXGBE_PHYSICAL_LAYER_1000BASE_KX);
-               break;
-       case IXGBE_DEV_ID_82599_SFP:
-               hw->phy.ops.identify_sfp(hw);
+       /*
+        * The defaults in the HW for RX PB 1-7 are not zero and so should be
+        * intialized to zero for non DCB mode otherwise actual total RX PB
+        * would be bigger than programmed and filter space would run into
+        * the PB 0 region.
+        */
+       for (i = 1; i < 8; i++)
+               IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), 0);
 
-               switch (hw->phy.sfp_type) {
-               case ixgbe_sfp_type_da_cu:
-               case ixgbe_sfp_type_da_cu_core0:
-               case ixgbe_sfp_type_da_cu_core1:
-                       physical_layer = IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU;
-                       break;
-               case ixgbe_sfp_type_sr:
-                       physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR;
-                       break;
-               case ixgbe_sfp_type_lr:
-                       physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR;
-                       break;
-               case ixgbe_sfp_type_srlr_core0:
-               case ixgbe_sfp_type_srlr_core1:
-                       hw->phy.ops.read_i2c_eeprom(hw,
-                                                   IXGBE_SFF_10GBE_COMP_CODES,
-                                                   &comp_codes_10g);
-                       if (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)
-                               physical_layer =
-                                               IXGBE_PHYSICAL_LAYER_10GBASE_SR;
-                       else if (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE)
-                               physical_layer =
-                                               IXGBE_PHYSICAL_LAYER_10GBASE_LR;
-                       else
-                               physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
-               default:
-                       physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
-                       break;
-               }
+       /* Send interrupt when 64 filters are left */
+       fdirctrl |= 4 << IXGBE_FDIRCTRL_FULL_THRESH_SHIFT;
+
+       switch (pballoc) {
+       case IXGBE_FDIR_PBALLOC_64K:
+               /* 2k - 1 perfect filters */
+               fdirctrl |= IXGBE_FDIRCTRL_PBALLOC_64K;
                break;
-       default:
-               physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
+       case IXGBE_FDIR_PBALLOC_128K:
+               /* 4k - 1 perfect filters */
+               fdirctrl |= IXGBE_FDIRCTRL_PBALLOC_128K;
+               break;
+       case IXGBE_FDIR_PBALLOC_256K:
+               /* 8k - 1 perfect filters */
+               fdirctrl |= IXGBE_FDIRCTRL_PBALLOC_256K;
                break;
+       default:
+               /* bad value */
+               return IXGBE_ERR_CONFIG;
+       };
+
+       /* Turn perfect match filtering on */
+       fdirctrl |= IXGBE_FDIRCTRL_PERFECT_MATCH;
+       fdirctrl |= IXGBE_FDIRCTRL_REPORT_STATUS;
+
+       /* Move the flexible bytes to use the ethertype - shift 6 words */
+       fdirctrl |= (0x6 << IXGBE_FDIRCTRL_FLEX_SHIFT);
+
+       /* Prime the keys for hashing */
+       IXGBE_WRITE_REG(hw, IXGBE_FDIRHKEY,
+                       htonl(IXGBE_ATR_BUCKET_HASH_KEY));
+       IXGBE_WRITE_REG(hw, IXGBE_FDIRSKEY,
+                       htonl(IXGBE_ATR_SIGNATURE_HASH_KEY));
+
+       /*
+        * Poll init-done after we write the register.  Estimated times:
+        *      10G: PBALLOC = 11b, timing is 60us
+        *       1G: PBALLOC = 11b, timing is 600us
+        *     100M: PBALLOC = 11b, timing is 6ms
+        *
+        *     Multiple these timings by 4 if under full Rx load
+        *
+        * So we'll poll for IXGBE_FDIR_INIT_DONE_POLL times, sleeping for
+        * 1 msec per poll time.  If we're at line rate and drop to 100M, then
+        * this might not finish in our poll time, but we can live with that
+        * for now.
+        */
+
+       /* Set the maximum length per hash bucket to 0xA filters */
+       fdirctrl |= (0xA << IXGBE_FDIRCTRL_MAX_LENGTH_SHIFT);
+
+       IXGBE_WRITE_REG(hw, IXGBE_FDIRCTRL, fdirctrl);
+       IXGBE_WRITE_FLUSH(hw);
+       for (i = 0; i < IXGBE_FDIR_INIT_DONE_POLL; i++) {
+               if (IXGBE_READ_REG(hw, IXGBE_FDIRCTRL) &
+                                  IXGBE_FDIRCTRL_INIT_DONE)
+                       break;
+               msleep(1);
        }
+       if (i >= IXGBE_FDIR_INIT_DONE_POLL)
+               hw_dbg(hw, "Flow Director Perfect poll time exceeded!\n");
 
-       return physical_layer;
+       return 0;
 }
 
+
 /**
- *  ixgbe_enable_rx_dma_82599 - Enable the Rx DMA unit on 82599
- *  @hw: pointer to hardware structure
- *  @regval: register value to write to RXCTRL
- *
- *  Enables the Rx DMA unit for 82599
+ *  ixgbe_atr_compute_hash_82599 - Compute the hashes for SW ATR
+ *  @stream: input bitstream to compute the hash on
+ *  @key: 32-bit hash key
  **/
-s32 ixgbe_enable_rx_dma_82599(struct ixgbe_hw *hw, u32 regval)
+u16 ixgbe_atr_compute_hash_82599(struct ixgbe_atr_input *atr_input, u32 key)
 {
-#define IXGBE_MAX_SECRX_POLL 30
-       int i;
-       int secrxreg;
+       /*
+        * The algorithm is as follows:
+        *    Hash[15:0] = Sum { S[n] x K[n+16] }, n = 0...350
+        *    where Sum {A[n]}, n = 0...n is bitwise XOR of A[0], A[1]...A[n]
+        *    and A[n] x B[n] is bitwise AND between same length strings
+        *
+        *    K[n] is 16 bits, defined as:
+        *       for n modulo 32 >= 15, K[n] = K[n % 32 : (n % 32) - 15]
+        *       for n modulo 32 < 15, K[n] =
+        *             K[(n % 32:0) | (31:31 - (14 - (n % 32)))]
+        *
+        *    S[n] is 16 bits, defined as:
+        *       for n >= 15, S[n] = S[n:n - 15]
+        *       for n < 15, S[n] = S[(n:0) | (350:350 - (14 - n))]
+        *
+        *    To simplify for programming, the algorithm is implemented
+        *    in software this way:
+        *
+        *    Key[31:0], Stream[335:0]
+        *
+        *    tmp_key[11 * 32 - 1:0] = 11{Key[31:0] = key concatenated 11 times
+        *    int_key[350:0] = tmp_key[351:1]
+        *    int_stream[365:0] = Stream[14:0] | Stream[335:0] | Stream[335:321]
+        *
+        *    hash[15:0] = 0;
+        *    for (i = 0; i < 351; i++) {
+        *        if (int_key[i])
+        *            hash ^= int_stream[(i + 15):i];
+        *    }
+        */
+
+       union {
+               u64    fill[6];
+               u32    key[11];
+               u8     key_stream[44];
+       } tmp_key;
+
+       u8   *stream = (u8 *)atr_input;
+       u8   int_key[44];      /* upper-most bit unused */
+       u8   hash_str[46];     /* upper-most 2 bits unused */
+       u16  hash_result = 0;
+       int  i, j, k, h;
 
        /*
-        * Workaround for 82599 silicon errata when enabling the Rx datapath.
-        * If traffic is incoming before we enable the Rx unit, it could hang
-        * the Rx DMA unit.  Therefore, make sure the security engine is
-        * completely disabled prior to enabling the Rx unit.
+        * Initialize the fill member to prevent warnings
+        * on some compilers
         */
-       secrxreg = IXGBE_READ_REG(hw, IXGBE_SECRXCTRL);
+        tmp_key.fill[0] = 0;
+
+       /* First load the temporary key stream */
+       for (i = 0; i < 6; i++) {
+               u64 fillkey = ((u64)key << 32) | key;
+               tmp_key.fill[i] = fillkey;
+       }
+
+       /*
+        * Set the interim key for the hashing.  Bit 352 is unused, so we must
+        * shift and compensate when building the key.
+        */
+
+       int_key[0] = tmp_key.key_stream[0] >> 1;
+       for (i = 1, j = 0; i < 44; i++) {
+               unsigned int this_key = tmp_key.key_stream[j] << 7;
+               j++;
+               int_key[i] = (u8)(this_key | (tmp_key.key_stream[j] >> 1));
+       }
+
+       /*
+        * Set the interim bit string for the hashing.  Bits 368 and 367 are
+        * unused, so shift and compensate when building the string.
+        */
+       hash_str[0] = (stream[40] & 0x7f) >> 1;
+       for (i = 1, j = 40; i < 46; i++) {
+               unsigned int this_str = stream[j] << 7;
+               j++;
+               if (j > 41)
+                       j = 0;
+               hash_str[i] = (u8)(this_str | (stream[j] >> 1));
+       }
+
+       /*
+        * Now compute the hash.  i is the index into hash_str, j is into our
+        * key stream, k is counting the number of bits, and h interates within
+        * each byte.
+        */
+       for (i = 45, j = 43, k = 0; k < 351 && i >= 2 && j >= 0; i--, j--) {
+               for (h = 0; h < 8 && k < 351; h++, k++) {
+                       if (int_key[j] & (1 << h)) {
+                               /*
+                                * Key bit is set, XOR in the current 16-bit
+                                * string.  Example of processing:
+                                *    h = 0,
+                                *      tmp = (hash_str[i - 2] & 0 << 16) |
+                                *            (hash_str[i - 1] & 0xff << 8) |
+                                *            (hash_str[i] & 0xff >> 0)
+                                *      So tmp = hash_str[15 + k:k], since the
+                                *      i + 2 clause rolls off the 16-bit value
+                                *    h = 7,
+                                *      tmp = (hash_str[i - 2] & 0x7f << 9) |
+                                *            (hash_str[i - 1] & 0xff << 1) |
+                                *            (hash_str[i] & 0x80 >> 7)
+                                */
+                               int tmp = (hash_str[i] >> h);
+                               tmp |= (hash_str[i - 1] << (8 - h));
+                               tmp |= (int)(hash_str[i - 2] & ((1 << h) - 1))
+                                            << (16 - h);
+                               hash_result ^= (u16)tmp;
+                       }
+               }
+       }
+
+       return hash_result;
+}
+
+/**
+ *  ixgbe_atr_set_vlan_id_82599 - Sets the VLAN id in the ATR input stream
+ *  @input: input stream to modify
+ *  @vlan: the VLAN id to load
+ **/
+s32 ixgbe_atr_set_vlan_id_82599(struct ixgbe_atr_input *input, u16 vlan)
+{
+       input->byte_stream[IXGBE_ATR_VLAN_OFFSET + 1] = vlan >> 8;
+       input->byte_stream[IXGBE_ATR_VLAN_OFFSET] = vlan & 0xff;
+
+       return 0;
+}
+
+/**
+ *  ixgbe_atr_set_src_ipv4_82599 - Sets the source IPv4 address
+ *  @input: input stream to modify
+ *  @src_addr: the IP address to load
+ **/
+s32 ixgbe_atr_set_src_ipv4_82599(struct ixgbe_atr_input *input, u32 src_addr)
+{
+       input->byte_stream[IXGBE_ATR_SRC_IPV4_OFFSET + 3] = src_addr >> 24;
+       input->byte_stream[IXGBE_ATR_SRC_IPV4_OFFSET + 2] =
+                                                      (src_addr >> 16) & 0xff;
+       input->byte_stream[IXGBE_ATR_SRC_IPV4_OFFSET + 1] =
+                                                       (src_addr >> 8) & 0xff;
+       input->byte_stream[IXGBE_ATR_SRC_IPV4_OFFSET] = src_addr & 0xff;
+
+       return 0;
+}
+
+/**
+ *  ixgbe_atr_set_dst_ipv4_82599 - Sets the destination IPv4 address
+ *  @input: input stream to modify
+ *  @dst_addr: the IP address to load
+ **/
+s32 ixgbe_atr_set_dst_ipv4_82599(struct ixgbe_atr_input *input, u32 dst_addr)
+{
+       input->byte_stream[IXGBE_ATR_DST_IPV4_OFFSET + 3] = dst_addr >> 24;
+       input->byte_stream[IXGBE_ATR_DST_IPV4_OFFSET + 2] =
+                                                      (dst_addr >> 16) & 0xff;
+       input->byte_stream[IXGBE_ATR_DST_IPV4_OFFSET + 1] =
+                                                       (dst_addr >> 8) & 0xff;
+       input->byte_stream[IXGBE_ATR_DST_IPV4_OFFSET] = dst_addr & 0xff;
+
+       return 0;
+}
+
+/**
+ *  ixgbe_atr_set_src_ipv6_82599 - Sets the source IPv6 address
+ *  @input: input stream to modify
+ *  @src_addr_1: the first 4 bytes of the IP address to load
+ *  @src_addr_2: the second 4 bytes of the IP address to load
+ *  @src_addr_3: the third 4 bytes of the IP address to load
+ *  @src_addr_4: the fourth 4 bytes of the IP address to load
+ **/
+s32 ixgbe_atr_set_src_ipv6_82599(struct ixgbe_atr_input *input,
+                                 u32 src_addr_1, u32 src_addr_2,
+                                 u32 src_addr_3, u32 src_addr_4)
+{
+       input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET] = src_addr_4 & 0xff;
+       input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 1] =
+                                                      (src_addr_4 >> 8) & 0xff;
+       input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 2] =
+                                                     (src_addr_4 >> 16) & 0xff;
+       input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 3] = src_addr_4 >> 24;
+
+       input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 4] = src_addr_3 & 0xff;
+       input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 5] =
+                                                      (src_addr_3 >> 8) & 0xff;
+       input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 6] =
+                                                     (src_addr_3 >> 16) & 0xff;
+       input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 7] = src_addr_3 >> 24;
+
+       input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 8] = src_addr_2 & 0xff;
+       input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 9] =
+                                                      (src_addr_2 >> 8) & 0xff;
+       input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 10] =
+                                                     (src_addr_2 >> 16) & 0xff;
+       input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 11] = src_addr_2 >> 24;
+
+       input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 12] = src_addr_1 & 0xff;
+       input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 13] =
+                                                      (src_addr_1 >> 8) & 0xff;
+       input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 14] =
+                                                     (src_addr_1 >> 16) & 0xff;
+       input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 15] = src_addr_1 >> 24;
+
+       return 0;
+}
+
+/**
+ *  ixgbe_atr_set_dst_ipv6_82599 - Sets the destination IPv6 address
+ *  @input: input stream to modify
+ *  @dst_addr_1: the first 4 bytes of the IP address to load
+ *  @dst_addr_2: the second 4 bytes of the IP address to load
+ *  @dst_addr_3: the third 4 bytes of the IP address to load
+ *  @dst_addr_4: the fourth 4 bytes of the IP address to load
+ **/
+s32 ixgbe_atr_set_dst_ipv6_82599(struct ixgbe_atr_input *input,
+                                 u32 dst_addr_1, u32 dst_addr_2,
+                                 u32 dst_addr_3, u32 dst_addr_4)
+{
+       input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET] = dst_addr_4 & 0xff;
+       input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 1] =
+                                                      (dst_addr_4 >> 8) & 0xff;
+       input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 2] =
+                                                     (dst_addr_4 >> 16) & 0xff;
+       input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 3] = dst_addr_4 >> 24;
+
+       input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 4] = dst_addr_3 & 0xff;
+       input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 5] =
+                                                      (dst_addr_3 >> 8) & 0xff;
+       input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 6] =
+                                                     (dst_addr_3 >> 16) & 0xff;
+       input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 7] = dst_addr_3 >> 24;
+
+       input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 8] = dst_addr_2 & 0xff;
+       input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 9] =
+                                                      (dst_addr_2 >> 8) & 0xff;
+       input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 10] =
+                                                     (dst_addr_2 >> 16) & 0xff;
+       input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 11] = dst_addr_2 >> 24;
+
+       input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 12] = dst_addr_1 & 0xff;
+       input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 13] =
+                                                      (dst_addr_1 >> 8) & 0xff;
+       input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 14] =
+                                                     (dst_addr_1 >> 16) & 0xff;
+       input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 15] = dst_addr_1 >> 24;
+
+       return 0;
+}
+
+/**
+ *  ixgbe_atr_set_src_port_82599 - Sets the source port
+ *  @input: input stream to modify
+ *  @src_port: the source port to load
+ **/
+s32 ixgbe_atr_set_src_port_82599(struct ixgbe_atr_input *input, u16 src_port)
+{
+       input->byte_stream[IXGBE_ATR_SRC_PORT_OFFSET + 1] = src_port >> 8;
+       input->byte_stream[IXGBE_ATR_SRC_PORT_OFFSET] = src_port & 0xff;
+
+       return 0;
+}
+
+/**
+ *  ixgbe_atr_set_dst_port_82599 - Sets the destination port
+ *  @input: input stream to modify
+ *  @dst_port: the destination port to load
+ **/
+s32 ixgbe_atr_set_dst_port_82599(struct ixgbe_atr_input *input, u16 dst_port)
+{
+       input->byte_stream[IXGBE_ATR_DST_PORT_OFFSET + 1] = dst_port >> 8;
+       input->byte_stream[IXGBE_ATR_DST_PORT_OFFSET] = dst_port & 0xff;
+
+       return 0;
+}
+
+/**
+ *  ixgbe_atr_set_flex_byte_82599 - Sets the flexible bytes
+ *  @input: input stream to modify
+ *  @flex_bytes: the flexible bytes to load
+ **/
+s32 ixgbe_atr_set_flex_byte_82599(struct ixgbe_atr_input *input, u16 flex_byte)
+{
+       input->byte_stream[IXGBE_ATR_FLEX_BYTE_OFFSET + 1] = flex_byte >> 8;
+       input->byte_stream[IXGBE_ATR_FLEX_BYTE_OFFSET] = flex_byte & 0xff;
+
+       return 0;
+}
+
+/**
+ *  ixgbe_atr_set_vm_pool_82599 - Sets the Virtual Machine pool
+ *  @input: input stream to modify
+ *  @vm_pool: the Virtual Machine pool to load
+ **/
+s32 ixgbe_atr_set_vm_pool_82599(struct ixgbe_atr_input *input, u8 vm_pool)
+{
+       input->byte_stream[IXGBE_ATR_VM_POOL_OFFSET] = vm_pool;
+
+       return 0;
+}
+
+/**
+ *  ixgbe_atr_set_l4type_82599 - Sets the layer 4 packet type
+ *  @input: input stream to modify
+ *  @l4type: the layer 4 type value to load
+ **/
+s32 ixgbe_atr_set_l4type_82599(struct ixgbe_atr_input *input, u8 l4type)
+{
+       input->byte_stream[IXGBE_ATR_L4TYPE_OFFSET] = l4type;
+
+       return 0;
+}
+
+/**
+ *  ixgbe_atr_get_vlan_id_82599 - Gets the VLAN id from the ATR input stream
+ *  @input: input stream to search
+ *  @vlan: the VLAN id to load
+ **/
+s32 ixgbe_atr_get_vlan_id_82599(struct ixgbe_atr_input *input, u16 *vlan)
+{
+       *vlan = input->byte_stream[IXGBE_ATR_VLAN_OFFSET];
+       *vlan |= input->byte_stream[IXGBE_ATR_VLAN_OFFSET + 1] << 8;
+
+       return 0;
+}
+
+/**
+ *  ixgbe_atr_get_src_ipv4_82599 - Gets the source IPv4 address
+ *  @input: input stream to search
+ *  @src_addr: the IP address to load
+ **/
+s32 ixgbe_atr_get_src_ipv4_82599(struct ixgbe_atr_input *input, u32 *src_addr)
+{
+       *src_addr = input->byte_stream[IXGBE_ATR_SRC_IPV4_OFFSET];
+       *src_addr |= input->byte_stream[IXGBE_ATR_SRC_IPV4_OFFSET + 1] << 8;
+       *src_addr |= input->byte_stream[IXGBE_ATR_SRC_IPV4_OFFSET + 2] << 16;
+       *src_addr |= input->byte_stream[IXGBE_ATR_SRC_IPV4_OFFSET + 3] << 24;
+
+       return 0;
+}
+
+/**
+ *  ixgbe_atr_get_dst_ipv4_82599 - Gets the destination IPv4 address
+ *  @input: input stream to search
+ *  @dst_addr: the IP address to load
+ **/
+s32 ixgbe_atr_get_dst_ipv4_82599(struct ixgbe_atr_input *input, u32 *dst_addr)
+{
+       *dst_addr = input->byte_stream[IXGBE_ATR_DST_IPV4_OFFSET];
+       *dst_addr |= input->byte_stream[IXGBE_ATR_DST_IPV4_OFFSET + 1] << 8;
+       *dst_addr |= input->byte_stream[IXGBE_ATR_DST_IPV4_OFFSET + 2] << 16;
+       *dst_addr |= input->byte_stream[IXGBE_ATR_DST_IPV4_OFFSET + 3] << 24;
+
+       return 0;
+}
+
+/**
+ *  ixgbe_atr_get_src_ipv6_82599 - Gets the source IPv6 address
+ *  @input: input stream to search
+ *  @src_addr_1: the first 4 bytes of the IP address to load
+ *  @src_addr_2: the second 4 bytes of the IP address to load
+ *  @src_addr_3: the third 4 bytes of the IP address to load
+ *  @src_addr_4: the fourth 4 bytes of the IP address to load
+ **/
+s32 ixgbe_atr_get_src_ipv6_82599(struct ixgbe_atr_input *input,
+                                 u32 *src_addr_1, u32 *src_addr_2,
+                                 u32 *src_addr_3, u32 *src_addr_4)
+{
+       *src_addr_1 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 12];
+       *src_addr_1 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 13] << 8;
+       *src_addr_1 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 14] << 16;
+       *src_addr_1 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 15] << 24;
+
+       *src_addr_2 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 8];
+       *src_addr_2 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 9] << 8;
+       *src_addr_2 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 10] << 16;
+       *src_addr_2 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 11] << 24;
+
+       *src_addr_3 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 4];
+       *src_addr_3 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 5] << 8;
+       *src_addr_3 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 6] << 16;
+       *src_addr_3 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 7] << 24;
+
+       *src_addr_4 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET];
+       *src_addr_4 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 1] << 8;
+       *src_addr_4 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 2] << 16;
+       *src_addr_4 = input->byte_stream[IXGBE_ATR_SRC_IPV6_OFFSET + 3] << 24;
+
+       return 0;
+}
+
+/**
+ *  ixgbe_atr_get_dst_ipv6_82599 - Gets the destination IPv6 address
+ *  @input: input stream to search
+ *  @dst_addr_1: the first 4 bytes of the IP address to load
+ *  @dst_addr_2: the second 4 bytes of the IP address to load
+ *  @dst_addr_3: the third 4 bytes of the IP address to load
+ *  @dst_addr_4: the fourth 4 bytes of the IP address to load
+ **/
+s32 ixgbe_atr_get_dst_ipv6_82599(struct ixgbe_atr_input *input,
+                                 u32 *dst_addr_1, u32 *dst_addr_2,
+                                 u32 *dst_addr_3, u32 *dst_addr_4)
+{
+       *dst_addr_1 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 12];
+       *dst_addr_1 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 13] << 8;
+       *dst_addr_1 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 14] << 16;
+       *dst_addr_1 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 15] << 24;
+
+       *dst_addr_2 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 8];
+       *dst_addr_2 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 9] << 8;
+       *dst_addr_2 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 10] << 16;
+       *dst_addr_2 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 11] << 24;
+
+       *dst_addr_3 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 4];
+       *dst_addr_3 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 5] << 8;
+       *dst_addr_3 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 6] << 16;
+       *dst_addr_3 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 7] << 24;
+
+       *dst_addr_4 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET];
+       *dst_addr_4 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 1] << 8;
+       *dst_addr_4 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 2] << 16;
+       *dst_addr_4 = input->byte_stream[IXGBE_ATR_DST_IPV6_OFFSET + 3] << 24;
+
+       return 0;
+}
+
+/**
+ *  ixgbe_atr_get_src_port_82599 - Gets the source port
+ *  @input: input stream to modify
+ *  @src_port: the source port to load
+ *
+ *  Even though the input is given in big-endian, the FDIRPORT registers
+ *  expect the ports to be programmed in little-endian.  Hence the need to swap
+ *  endianness when retrieving the data.  This can be confusing since the
+ *  internal hash engine expects it to be big-endian.
+ **/
+s32 ixgbe_atr_get_src_port_82599(struct ixgbe_atr_input *input, u16 *src_port)
+{
+       *src_port = input->byte_stream[IXGBE_ATR_SRC_PORT_OFFSET] << 8;
+       *src_port |= input->byte_stream[IXGBE_ATR_SRC_PORT_OFFSET + 1];
+
+       return 0;
+}
+
+/**
+ *  ixgbe_atr_get_dst_port_82599 - Gets the destination port
+ *  @input: input stream to modify
+ *  @dst_port: the destination port to load
+ *
+ *  Even though the input is given in big-endian, the FDIRPORT registers
+ *  expect the ports to be programmed in little-endian.  Hence the need to swap
+ *  endianness when retrieving the data.  This can be confusing since the
+ *  internal hash engine expects it to be big-endian.
+ **/
+s32 ixgbe_atr_get_dst_port_82599(struct ixgbe_atr_input *input, u16 *dst_port)
+{
+       *dst_port = input->byte_stream[IXGBE_ATR_DST_PORT_OFFSET] << 8;
+       *dst_port |= input->byte_stream[IXGBE_ATR_DST_PORT_OFFSET + 1];
+
+       return 0;
+}
+
+/**
+ *  ixgbe_atr_get_flex_byte_82599 - Gets the flexible bytes
+ *  @input: input stream to modify
+ *  @flex_bytes: the flexible bytes to load
+ **/
+s32 ixgbe_atr_get_flex_byte_82599(struct ixgbe_atr_input *input, u16 *flex_byte)
+{
+       *flex_byte = input->byte_stream[IXGBE_ATR_FLEX_BYTE_OFFSET];
+       *flex_byte |= input->byte_stream[IXGBE_ATR_FLEX_BYTE_OFFSET + 1] << 8;
+
+       return 0;
+}
+
+/**
+ *  ixgbe_atr_get_vm_pool_82599 - Gets the Virtual Machine pool
+ *  @input: input stream to modify
+ *  @vm_pool: the Virtual Machine pool to load
+ **/
+s32 ixgbe_atr_get_vm_pool_82599(struct ixgbe_atr_input *input, u8 *vm_pool)
+{
+       *vm_pool = input->byte_stream[IXGBE_ATR_VM_POOL_OFFSET];
+
+       return 0;
+}
+
+/**
+ *  ixgbe_atr_get_l4type_82599 - Gets the layer 4 packet type
+ *  @input: input stream to modify
+ *  @l4type: the layer 4 type value to load
+ **/
+s32 ixgbe_atr_get_l4type_82599(struct ixgbe_atr_input *input, u8 *l4type)
+{
+       *l4type = input->byte_stream[IXGBE_ATR_L4TYPE_OFFSET];
+
+       return 0;
+}
+
+/**
+ *  ixgbe_atr_add_signature_filter_82599 - Adds a signature hash filter
+ *  @hw: pointer to hardware structure
+ *  @stream: input bitstream
+ *  @queue: queue index to direct traffic to
+ **/
+s32 ixgbe_fdir_add_signature_filter_82599(struct ixgbe_hw *hw,
+                                          struct ixgbe_atr_input *input,
+                                          u8 queue)
+{
+       u64  fdirhashcmd;
+       u64  fdircmd;
+       u32  fdirhash;
+       u16  bucket_hash, sig_hash;
+       u8   l4type;
+
+       bucket_hash = ixgbe_atr_compute_hash_82599(input,
+                                                  IXGBE_ATR_BUCKET_HASH_KEY);
+
+       /* bucket_hash is only 15 bits */
+       bucket_hash &= IXGBE_ATR_HASH_MASK;
+
+       sig_hash = ixgbe_atr_compute_hash_82599(input,
+                                               IXGBE_ATR_SIGNATURE_HASH_KEY);
+
+       /* Get the l4type in order to program FDIRCMD properly */
+       /* lowest 2 bits are FDIRCMD.L4TYPE, third lowest bit is FDIRCMD.IPV6 */
+       ixgbe_atr_get_l4type_82599(input, &l4type);
+
+       /*
+        * The lower 32-bits of fdirhashcmd is for FDIRHASH, the upper 32-bits
+        * is for FDIRCMD.  Then do a 64-bit register write from FDIRHASH.
+        */
+       fdirhash = sig_hash << IXGBE_FDIRHASH_SIG_SW_INDEX_SHIFT | bucket_hash;
+
+       fdircmd = (IXGBE_FDIRCMD_CMD_ADD_FLOW | IXGBE_FDIRCMD_FILTER_UPDATE |
+                  IXGBE_FDIRCMD_LAST | IXGBE_FDIRCMD_QUEUE_EN);
+
+       switch (l4type & IXGBE_ATR_L4TYPE_MASK) {
+       case IXGBE_ATR_L4TYPE_TCP:
+               fdircmd |= IXGBE_FDIRCMD_L4TYPE_TCP;
+               break;
+       case IXGBE_ATR_L4TYPE_UDP:
+               fdircmd |= IXGBE_FDIRCMD_L4TYPE_UDP;
+               break;
+       case IXGBE_ATR_L4TYPE_SCTP:
+               fdircmd |= IXGBE_FDIRCMD_L4TYPE_SCTP;
+               break;
+       default:
+               hw_dbg(hw, "Error on l4type input\n");
+               return IXGBE_ERR_CONFIG;
+       }
+
+       if (l4type & IXGBE_ATR_L4TYPE_IPV6_MASK)
+               fdircmd |= IXGBE_FDIRCMD_IPV6;
+
+       fdircmd |= ((u64)queue << IXGBE_FDIRCMD_RX_QUEUE_SHIFT);
+       fdirhashcmd = ((fdircmd << 32) | fdirhash);
+
+       IXGBE_WRITE_REG64(hw, IXGBE_FDIRHASH, fdirhashcmd);
+
+       return 0;
+}
+
+/**
+ *  ixgbe_fdir_add_perfect_filter_82599 - Adds a perfect filter
+ *  @hw: pointer to hardware structure
+ *  @input: input bitstream
+ *  @queue: queue index to direct traffic to
+ *
+ *  Note that the caller to this function must lock before calling, since the
+ *  hardware writes must be protected from one another.
+ **/
+s32 ixgbe_fdir_add_perfect_filter_82599(struct ixgbe_hw *hw,
+                                        struct ixgbe_atr_input *input,
+                                        u16 soft_id,
+                                        u8 queue)
+{
+       u32 fdircmd = 0;
+       u32 fdirhash;
+       u32 src_ipv4, dst_ipv4;
+       u32 src_ipv6_1, src_ipv6_2, src_ipv6_3, src_ipv6_4;
+       u16 src_port, dst_port, vlan_id, flex_bytes;
+       u16 bucket_hash;
+       u8  l4type;
+
+       /* Get our input values */
+       ixgbe_atr_get_l4type_82599(input, &l4type);
+
+       /*
+        * Check l4type formatting, and bail out before we touch the hardware
+        * if there's a configuration issue
+        */
+       switch (l4type & IXGBE_ATR_L4TYPE_MASK) {
+       case IXGBE_ATR_L4TYPE_TCP:
+               fdircmd |= IXGBE_FDIRCMD_L4TYPE_TCP;
+               break;
+       case IXGBE_ATR_L4TYPE_UDP:
+               fdircmd |= IXGBE_FDIRCMD_L4TYPE_UDP;
+               break;
+       case IXGBE_ATR_L4TYPE_SCTP:
+               fdircmd |= IXGBE_FDIRCMD_L4TYPE_SCTP;
+               break;
+       default:
+               hw_dbg(hw, "Error on l4type input\n");
+               return IXGBE_ERR_CONFIG;
+       }
+
+       bucket_hash = ixgbe_atr_compute_hash_82599(input,
+                                                  IXGBE_ATR_BUCKET_HASH_KEY);
+
+       /* bucket_hash is only 15 bits */
+       bucket_hash &= IXGBE_ATR_HASH_MASK;
+
+       ixgbe_atr_get_vlan_id_82599(input, &vlan_id);
+       ixgbe_atr_get_src_port_82599(input, &src_port);
+       ixgbe_atr_get_dst_port_82599(input, &dst_port);
+       ixgbe_atr_get_flex_byte_82599(input, &flex_bytes);
+
+       fdirhash = soft_id << IXGBE_FDIRHASH_SIG_SW_INDEX_SHIFT | bucket_hash;
+
+       /* Now figure out if we're IPv4 or IPv6 */
+       if (l4type & IXGBE_ATR_L4TYPE_IPV6_MASK) {
+               /* IPv6 */
+               ixgbe_atr_get_src_ipv6_82599(input, &src_ipv6_1, &src_ipv6_2,
+                                            &src_ipv6_3, &src_ipv6_4);
+
+               IXGBE_WRITE_REG(hw, IXGBE_FDIRSIPv6(0), src_ipv6_1);
+               IXGBE_WRITE_REG(hw, IXGBE_FDIRSIPv6(1), src_ipv6_2);
+               IXGBE_WRITE_REG(hw, IXGBE_FDIRSIPv6(2), src_ipv6_3);
+               /* The last 4 bytes is the same register as IPv4 */
+               IXGBE_WRITE_REG(hw, IXGBE_FDIRIPSA, src_ipv6_4);
+
+               fdircmd |= IXGBE_FDIRCMD_IPV6;
+               fdircmd |= IXGBE_FDIRCMD_IPv6DMATCH;
+       } else {
+               /* IPv4 */
+               ixgbe_atr_get_src_ipv4_82599(input, &src_ipv4);
+               IXGBE_WRITE_REG(hw, IXGBE_FDIRIPSA, src_ipv4);
+
+       }
+
+       ixgbe_atr_get_dst_ipv4_82599(input, &dst_ipv4);
+       IXGBE_WRITE_REG(hw, IXGBE_FDIRIPDA, dst_ipv4);
+
+       IXGBE_WRITE_REG(hw, IXGBE_FDIRVLAN, (vlan_id |
+                                   (flex_bytes << IXGBE_FDIRVLAN_FLEX_SHIFT)));
+       IXGBE_WRITE_REG(hw, IXGBE_FDIRPORT, (src_port |
+                              (dst_port << IXGBE_FDIRPORT_DESTINATION_SHIFT)));
+
+       fdircmd |= IXGBE_FDIRCMD_CMD_ADD_FLOW;
+       fdircmd |= IXGBE_FDIRCMD_FILTER_UPDATE;
+       fdircmd |= IXGBE_FDIRCMD_LAST;
+       fdircmd |= IXGBE_FDIRCMD_QUEUE_EN;
+       fdircmd |= queue << IXGBE_FDIRCMD_RX_QUEUE_SHIFT;
+
+       IXGBE_WRITE_REG(hw, IXGBE_FDIRHASH, fdirhash);
+       IXGBE_WRITE_REG(hw, IXGBE_FDIRCMD, fdircmd);
+
+       return 0;
+}
+/**
+ *  ixgbe_read_analog_reg8_82599 - Reads 8 bit Omer analog register
+ *  @hw: pointer to hardware structure
+ *  @reg: analog register to read
+ *  @val: read value
+ *
+ *  Performs read operation to Omer analog register specified.
+ **/
+s32 ixgbe_read_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 *val)
+{
+       u32  core_ctl;
+
+       IXGBE_WRITE_REG(hw, IXGBE_CORECTL, IXGBE_CORECTL_WRITE_CMD |
+                       (reg << 8));
+       IXGBE_WRITE_FLUSH(hw);
+       udelay(10);
+       core_ctl = IXGBE_READ_REG(hw, IXGBE_CORECTL);
+       *val = (u8)core_ctl;
+
+       return 0;
+}
+
+/**
+ *  ixgbe_write_analog_reg8_82599 - Writes 8 bit Omer analog register
+ *  @hw: pointer to hardware structure
+ *  @reg: atlas register to write
+ *  @val: value to write
+ *
+ *  Performs write operation to Omer analog register specified.
+ **/
+s32 ixgbe_write_analog_reg8_82599(struct ixgbe_hw *hw, u32 reg, u8 val)
+{
+       u32  core_ctl;
+
+       core_ctl = (reg << 8) | val;
+       IXGBE_WRITE_REG(hw, IXGBE_CORECTL, core_ctl);
+       IXGBE_WRITE_FLUSH(hw);
+       udelay(10);
+
+       return 0;
+}
+
+/**
+ *  ixgbe_start_hw_82599 - Prepare hardware for Tx/Rx
+ *  @hw: pointer to hardware structure
+ *
+ *  Starts the hardware using the generic start_hw function.
+ *  Then performs device-specific:
+ *  Clears the rate limiter registers.
+ **/
+s32 ixgbe_start_hw_82599(struct ixgbe_hw *hw)
+{
+       u32 q_num;
+       s32 ret_val;
+
+       ret_val = ixgbe_start_hw_generic(hw);
+
+       /* Clear the rate limiters */
+       for (q_num = 0; q_num < hw->mac.max_tx_queues; q_num++) {
+               IXGBE_WRITE_REG(hw, IXGBE_RTTDQSEL, q_num);
+               IXGBE_WRITE_REG(hw, IXGBE_RTTBCNRC, 0);
+       }
+       IXGBE_WRITE_FLUSH(hw);
+
+       /* We need to run link autotry after the driver loads */
+       hw->mac.autotry_restart = true;
+
+       if (ret_val == 0)
+               ret_val = ixgbe_verify_fw_version_82599(hw);
+
+       return ret_val;
+}
+
+/**
+ *  ixgbe_identify_phy_82599 - Get physical layer module
+ *  @hw: pointer to hardware structure
+ *
+ *  Determines the physical layer module found on the current adapter.
+ **/
+s32 ixgbe_identify_phy_82599(struct ixgbe_hw *hw)
+{
+       s32 status = IXGBE_ERR_PHY_ADDR_INVALID;
+       status = ixgbe_identify_phy_generic(hw);
+       if (status != 0)
+               status = ixgbe_identify_sfp_module_generic(hw);
+       return status;
+}
+
+/**
+ *  ixgbe_get_supported_physical_layer_82599 - Returns physical layer type
+ *  @hw: pointer to hardware structure
+ *
+ *  Determines physical layer capabilities of the current configuration.
+ **/
+u32 ixgbe_get_supported_physical_layer_82599(struct ixgbe_hw *hw)
+{
+       u32 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN;
+       u32 autoc = IXGBE_READ_REG(hw, IXGBE_AUTOC);
+       u32 autoc2 = IXGBE_READ_REG(hw, IXGBE_AUTOC2);
+       u32 pma_pmd_10g_serial = autoc2 & IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_MASK;
+       u32 pma_pmd_10g_parallel = autoc & IXGBE_AUTOC_10G_PMA_PMD_MASK;
+       u32 pma_pmd_1g = autoc & IXGBE_AUTOC_1G_PMA_PMD_MASK;
+       u16 ext_ability = 0;
+       u8 comp_codes_10g = 0;
+
+       hw->phy.ops.identify(hw);
+
+       if (hw->phy.type == ixgbe_phy_tn ||
+           hw->phy.type == ixgbe_phy_cu_unknown) {
+               hw->phy.ops.read_reg(hw, MDIO_PMA_EXTABLE, MDIO_MMD_PMAPMD,
+                                    &ext_ability);
+               if (ext_ability & MDIO_PMA_EXTABLE_10GBT)
+                       physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_T;
+               if (ext_ability & MDIO_PMA_EXTABLE_1000BT)
+                       physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_T;
+               if (ext_ability & MDIO_PMA_EXTABLE_100BTX)
+                       physical_layer |= IXGBE_PHYSICAL_LAYER_100BASE_TX;
+               goto out;
+       }
+
+       switch (autoc & IXGBE_AUTOC_LMS_MASK) {
+       case IXGBE_AUTOC_LMS_1G_AN:
+       case IXGBE_AUTOC_LMS_1G_LINK_NO_AN:
+               if (pma_pmd_1g == IXGBE_AUTOC_1G_KX_BX) {
+                       physical_layer = IXGBE_PHYSICAL_LAYER_1000BASE_KX |
+                           IXGBE_PHYSICAL_LAYER_1000BASE_BX;
+                       goto out;
+               } else
+                       /* SFI mode so read SFP module */
+                       goto sfp_check;
+               break;
+       case IXGBE_AUTOC_LMS_10G_LINK_NO_AN:
+               if (pma_pmd_10g_parallel == IXGBE_AUTOC_10G_CX4)
+                       physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_CX4;
+               else if (pma_pmd_10g_parallel == IXGBE_AUTOC_10G_KX4)
+                       physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_KX4;
+               else if (pma_pmd_10g_parallel == IXGBE_AUTOC_10G_XAUI)
+                       physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_XAUI;
+               goto out;
+               break;
+       case IXGBE_AUTOC_LMS_10G_SERIAL:
+               if (pma_pmd_10g_serial == IXGBE_AUTOC2_10G_KR) {
+                       physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_KR;
+                       goto out;
+               } else if (pma_pmd_10g_serial == IXGBE_AUTOC2_10G_SFI)
+                       goto sfp_check;
+               break;
+       case IXGBE_AUTOC_LMS_KX4_KX_KR:
+       case IXGBE_AUTOC_LMS_KX4_KX_KR_1G_AN:
+               if (autoc & IXGBE_AUTOC_KX_SUPP)
+                       physical_layer |= IXGBE_PHYSICAL_LAYER_1000BASE_KX;
+               if (autoc & IXGBE_AUTOC_KX4_SUPP)
+                       physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_KX4;
+               if (autoc & IXGBE_AUTOC_KR_SUPP)
+                       physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_KR;
+               goto out;
+               break;
+       default:
+               goto out;
+               break;
+       }
+
+sfp_check:
+       /* SFP check must be done last since DA modules are sometimes used to
+        * test KR mode -  we need to id KR mode correctly before SFP module.
+        * Call identify_sfp because the pluggable module may have changed */
+       hw->phy.ops.identify_sfp(hw);
+       if (hw->phy.sfp_type == ixgbe_sfp_type_not_present)
+               goto out;
+
+       switch (hw->phy.type) {
+       case ixgbe_phy_tw_tyco:
+       case ixgbe_phy_tw_unknown:
+               physical_layer = IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU;
+               break;
+       case ixgbe_phy_sfp_avago:
+       case ixgbe_phy_sfp_ftl:
+       case ixgbe_phy_sfp_intel:
+       case ixgbe_phy_sfp_unknown:
+               hw->phy.ops.read_i2c_eeprom(hw,
+                     IXGBE_SFF_10GBE_COMP_CODES, &comp_codes_10g);
+               if (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)
+                       physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR;
+               else if (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE)
+                       physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR;
+               break;
+       default:
+               break;
+       }
+
+out:
+       return physical_layer;
+}
+
+/**
+ *  ixgbe_enable_rx_dma_82599 - Enable the Rx DMA unit on 82599
+ *  @hw: pointer to hardware structure
+ *  @regval: register value to write to RXCTRL
+ *
+ *  Enables the Rx DMA unit for 82599
+ **/
+s32 ixgbe_enable_rx_dma_82599(struct ixgbe_hw *hw, u32 regval)
+{
+#define IXGBE_MAX_SECRX_POLL 30
+       int i;
+       int secrxreg;
+
+       /*
+        * Workaround for 82599 silicon errata when enabling the Rx datapath.
+        * If traffic is incoming before we enable the Rx unit, it could hang
+        * the Rx DMA unit.  Therefore, make sure the security engine is
+        * completely disabled prior to enabling the Rx unit.
+        */
+       secrxreg = IXGBE_READ_REG(hw, IXGBE_SECRXCTRL);
        secrxreg |= IXGBE_SECRXCTRL_RX_DIS;
        IXGBE_WRITE_REG(hw, IXGBE_SECRXCTRL, secrxreg);
        for (i = 0; i < IXGBE_MAX_SECRX_POLL; i++) {
@@ -1187,6 +2327,138 @@ s32 ixgbe_enable_rx_dma_82599(struct ixgbe_hw *hw, u32 regval)
        return 0;
 }
 
+/**
+ *  ixgbe_get_device_caps_82599 - Get additional device capabilities
+ *  @hw: pointer to hardware structure
+ *  @device_caps: the EEPROM word with the extra device capabilities
+ *
+ *  This function will read the EEPROM location for the device capabilities,
+ *  and return the word through device_caps.
+ **/
+s32 ixgbe_get_device_caps_82599(struct ixgbe_hw *hw, u16 *device_caps)
+{
+       hw->eeprom.ops.read(hw, IXGBE_DEVICE_CAPS, device_caps);
+
+       return 0;
+}
+
+/**
+ *  ixgbe_get_san_mac_addr_offset_82599 - SAN MAC address offset for 82599
+ *  @hw: pointer to hardware structure
+ *  @san_mac_offset: SAN MAC address offset
+ *
+ *  This function will read the EEPROM location for the SAN MAC address
+ *  pointer, and returns the value at that location.  This is used in both
+ *  get and set mac_addr routines.
+ **/
+s32 ixgbe_get_san_mac_addr_offset_82599(struct ixgbe_hw *hw,
+                                        u16 *san_mac_offset)
+{
+       /*
+        * First read the EEPROM pointer to see if the MAC addresses are
+        * available.
+        */
+       hw->eeprom.ops.read(hw, IXGBE_SAN_MAC_ADDR_PTR, san_mac_offset);
+
+       return 0;
+}
+
+/**
+ *  ixgbe_get_san_mac_addr_82599 - SAN MAC address retrieval for 82599
+ *  @hw: pointer to hardware structure
+ *  @san_mac_addr: SAN MAC address
+ *
+ *  Reads the SAN MAC address from the EEPROM, if it's available.  This is
+ *  per-port, so set_lan_id() must be called before reading the addresses.
+ *  set_lan_id() is called by identify_sfp(), but this cannot be relied
+ *  upon for non-SFP connections, so we must call it here.
+ **/
+s32 ixgbe_get_san_mac_addr_82599(struct ixgbe_hw *hw, u8 *san_mac_addr)
+{
+       u16 san_mac_data, san_mac_offset;
+       u8 i;
+
+       /*
+        * First read the EEPROM pointer to see if the MAC addresses are
+        * available.  If they're not, no point in calling set_lan_id() here.
+        */
+       ixgbe_get_san_mac_addr_offset_82599(hw, &san_mac_offset);
+
+       if ((san_mac_offset == 0) || (san_mac_offset == 0xFFFF)) {
+               /*
+                * No addresses available in this EEPROM.  It's not an
+                * error though, so just wipe the local address and return.
+                */
+               for (i = 0; i < 6; i++)
+                       san_mac_addr[i] = 0xFF;
+
+               goto san_mac_addr_out;
+       }
+
+       /* make sure we know which port we need to program */
+       hw->mac.ops.set_lan_id(hw);
+       /* apply the port offset to the address offset */
+       (hw->bus.func) ? (san_mac_offset += IXGBE_SAN_MAC_ADDR_PORT1_OFFSET) :
+                        (san_mac_offset += IXGBE_SAN_MAC_ADDR_PORT0_OFFSET);
+       for (i = 0; i < 3; i++) {
+               hw->eeprom.ops.read(hw, san_mac_offset, &san_mac_data);
+               san_mac_addr[i * 2] = (u8)(san_mac_data);
+               san_mac_addr[i * 2 + 1] = (u8)(san_mac_data >> 8);
+               san_mac_offset++;
+       }
+
+san_mac_addr_out:
+       return 0;
+}
+
+/**
+ *  ixgbe_verify_fw_version_82599 - verify fw version for 82599
+ *  @hw: pointer to hardware structure
+ *
+ *  Verifies that installed the firmware version is 0.6 or higher
+ *  for SFI devices. All 82599 SFI devices should have version 0.6 or higher.
+ *
+ *  Returns IXGBE_ERR_EEPROM_VERSION if the FW is not present or
+ *  if the FW version is not supported.
+ **/
+static s32 ixgbe_verify_fw_version_82599(struct ixgbe_hw *hw)
+{
+       s32 status = IXGBE_ERR_EEPROM_VERSION;
+       u16 fw_offset, fw_ptp_cfg_offset;
+       u16 fw_version = 0;
+
+       /* firmware check is only necessary for SFI devices */
+       if (hw->phy.media_type != ixgbe_media_type_fiber) {
+               status = 0;
+               goto fw_version_out;
+       }
+
+       /* get the offset to the Firmware Module block */
+       hw->eeprom.ops.read(hw, IXGBE_FW_PTR, &fw_offset);
+
+       if ((fw_offset == 0) || (fw_offset == 0xFFFF))
+               goto fw_version_out;
+
+       /* get the offset to the Pass Through Patch Configuration block */
+       hw->eeprom.ops.read(hw, (fw_offset +
+                                IXGBE_FW_PASSTHROUGH_PATCH_CONFIG_PTR),
+                                &fw_ptp_cfg_offset);
+
+       if ((fw_ptp_cfg_offset == 0) || (fw_ptp_cfg_offset == 0xFFFF))
+               goto fw_version_out;
+
+       /* get the firmware version */
+       hw->eeprom.ops.read(hw, (fw_ptp_cfg_offset +
+                                IXGBE_FW_PATCH_VERSION_4),
+                                &fw_version);
+
+       if (fw_version > 0x5)
+               status = 0;
+
+fw_version_out:
+       return status;
+}
+
 static struct ixgbe_mac_operations mac_ops_82599 = {
        .init_hw                = &ixgbe_init_hw_generic,
        .reset_hw               = &ixgbe_reset_hw_82599,
@@ -1196,6 +2468,8 @@ static struct ixgbe_mac_operations mac_ops_82599 = {
        .get_supported_physical_layer = &ixgbe_get_supported_physical_layer_82599,
        .enable_rx_dma          = &ixgbe_enable_rx_dma_82599,
        .get_mac_addr           = &ixgbe_get_mac_addr_generic,
+       .get_san_mac_addr       = &ixgbe_get_san_mac_addr_82599,
+       .get_device_caps        = &ixgbe_get_device_caps_82599,
        .stop_adapter           = &ixgbe_stop_adapter_generic,
        .get_bus_info           = &ixgbe_get_bus_info_generic,
        .set_lan_id             = &ixgbe_set_lan_id_multi_port_pcie,
@@ -1220,7 +2494,7 @@ static struct ixgbe_mac_operations mac_ops_82599 = {
        .disable_mc             = &ixgbe_disable_mc_generic,
        .clear_vfta             = &ixgbe_clear_vfta_82599,
        .set_vfta               = &ixgbe_set_vfta_82599,
-       .setup_fc               = &ixgbe_setup_fc_generic,
+       .fc_enable               = &ixgbe_fc_enable_generic,
        .init_uta_tables        = &ixgbe_init_uta_tables_82599,
        .setup_sfp              = &ixgbe_setup_sfp_modules_82599,
 };
@@ -1236,6 +2510,7 @@ static struct ixgbe_eeprom_operations eeprom_ops_82599 = {
 static struct ixgbe_phy_operations phy_ops_82599 = {
        .identify               = &ixgbe_identify_phy_82599,
        .identify_sfp           = &ixgbe_identify_sfp_module_generic,
+       .init                   = &ixgbe_init_phy_ops_82599,
        .reset                  = &ixgbe_reset_phy_generic,
        .read_reg               = &ixgbe_read_phy_reg_generic,
        .write_reg              = &ixgbe_write_phy_reg_generic,
index 186a65069b3329e0d9525b08072a6fce8e1a7518..96a185953777fe741c07a2db9c473e278d612f43 100644 (file)
@@ -28,6 +28,8 @@
 #include <linux/pci.h>
 #include <linux/delay.h>
 #include <linux/sched.h>
+#include <linux/list.h>
+#include <linux/netdevice.h>
 
 #include "ixgbe.h"
 #include "ixgbe_common.h"
@@ -71,12 +73,6 @@ s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw)
        /* Identify the PHY */
        hw->phy.ops.identify(hw);
 
-       /*
-        * Store MAC address from RAR0, clear receive address registers, and
-        * clear the multicast table
-        */
-       hw->mac.ops.init_rx_addrs(hw);
-
        /* Clear the VLAN filter table */
        hw->mac.ops.clear_vfta(hw);
 
@@ -89,6 +85,9 @@ s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw)
        IXGBE_WRITE_REG(hw, IXGBE_CTRL_EXT, ctrl_ext);
        IXGBE_WRITE_FLUSH(hw);
 
+       /* Setup flow control */
+       ixgbe_setup_fc(hw, 0);
+
        /* Clear adapter stopped flag */
        hw->adapter_stopped = false;
 
@@ -107,13 +106,17 @@ s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw)
  **/
 s32 ixgbe_init_hw_generic(struct ixgbe_hw *hw)
 {
+       s32 status;
+
        /* Reset the hardware */
-       hw->mac.ops.reset_hw(hw);
+       status = hw->mac.ops.reset_hw(hw);
 
-       /* Start the HW */
-       hw->mac.ops.start_hw(hw);
+       if (status == 0) {
+               /* Start the HW */
+               status = hw->mac.ops.start_hw(hw);
+       }
 
-       return 0;
+       return status;
 }
 
 /**
@@ -1362,15 +1365,14 @@ static void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq)
  *  Drivers using secondary unicast addresses must set user_set_promisc when
  *  manually putting the device into promiscuous mode.
  **/
-s32 ixgbe_update_uc_addr_list_generic(struct ixgbe_hw *hw, u8 *addr_list,
-                              u32 addr_count, ixgbe_mc_addr_itr next)
+s32 ixgbe_update_uc_addr_list_generic(struct ixgbe_hw *hw,
+                                     struct list_head *uc_list)
 {
-       u8 *addr;
        u32 i;
        u32 old_promisc_setting = hw->addr_ctrl.overflow_promisc;
        u32 uc_addr_in_use;
        u32 fctrl;
-       u32 vmdq;
+       struct netdev_hw_addr *ha;
 
        /*
         * Clear accounting of old secondary address list,
@@ -1388,10 +1390,9 @@ s32 ixgbe_update_uc_addr_list_generic(struct ixgbe_hw *hw, u8 *addr_list,
        }
 
        /* Add the new addresses */
-       for (i = 0; i < addr_count; i++) {
+       list_for_each_entry(ha, uc_list, list) {
                hw_dbg(hw, " Adding the secondary addresses:\n");
-               addr = next(hw, &addr_list, &vmdq);
-               ixgbe_add_uc_addr(hw, addr, vmdq);
+               ixgbe_add_uc_addr(hw, ha->addr, 0);
        }
 
        if (hw->addr_ctrl.overflow_promisc) {
@@ -1583,19 +1584,30 @@ s32 ixgbe_disable_mc_generic(struct ixgbe_hw *hw)
 }
 
 /**
- *  ixgbe_fc_enable - Enable flow control
+ *  ixgbe_fc_enable_generic - Enable flow control
  *  @hw: pointer to hardware structure
  *  @packetbuf_num: packet buffer number (0-7)
  *
  *  Enable flow control according to the current settings.
  **/
-s32 ixgbe_fc_enable(struct ixgbe_hw *hw, s32 packetbuf_num)
+s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw, s32 packetbuf_num)
 {
        s32 ret_val = 0;
-       u32 mflcn_reg;
-       u32 fccfg_reg;
+       u32 mflcn_reg, fccfg_reg;
        u32 reg;
+       u32 rx_pba_size;
 
+#ifdef CONFIG_DCB
+       if (hw->fc.requested_mode == ixgbe_fc_pfc)
+               goto out;
+
+#endif /* CONFIG_DCB */
+       /* Negotiate the fc mode to use */
+       ret_val = ixgbe_fc_autoneg(hw);
+       if (ret_val)
+               goto out;
+
+       /* Disable any previous flow control settings */
        mflcn_reg = IXGBE_READ_REG(hw, IXGBE_MFLCN);
        mflcn_reg &= ~(IXGBE_MFLCN_RFCE | IXGBE_MFLCN_RPFCE);
 
@@ -1615,7 +1627,10 @@ s32 ixgbe_fc_enable(struct ixgbe_hw *hw, s32 packetbuf_num)
         */
        switch (hw->fc.current_mode) {
        case ixgbe_fc_none:
-               /* Flow control completely disabled by software override. */
+               /*
+                * Flow control is disabled by software override or autoneg.
+                * The code below will actually disable it in the HW.
+                */
                break;
        case ixgbe_fc_rx_pause:
                /*
@@ -1644,7 +1659,7 @@ s32 ixgbe_fc_enable(struct ixgbe_hw *hw, s32 packetbuf_num)
        case ixgbe_fc_pfc:
                goto out;
                break;
-#endif
+#endif /* CONFIG_DCB */
        default:
                hw_dbg(hw, "Flow control param set incorrectly\n");
                ret_val = -IXGBE_ERR_CONFIG;
@@ -1652,25 +1667,48 @@ s32 ixgbe_fc_enable(struct ixgbe_hw *hw, s32 packetbuf_num)
                break;
        }
 
-       /* Enable 802.3x based flow control settings. */
+       /* Set 802.3x based flow control settings. */
+       mflcn_reg |= IXGBE_MFLCN_DPF;
        IXGBE_WRITE_REG(hw, IXGBE_MFLCN, mflcn_reg);
        IXGBE_WRITE_REG(hw, IXGBE_FCCFG, fccfg_reg);
 
-       /* Set up and enable Rx high/low water mark thresholds, enable XON. */
-       if (hw->fc.current_mode & ixgbe_fc_tx_pause) {
-               if (hw->fc.send_xon)
-                       IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(packetbuf_num),
-                                       (hw->fc.low_water | IXGBE_FCRTL_XONE));
-               else
-                       IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(packetbuf_num),
-                                       hw->fc.low_water);
+       reg = IXGBE_READ_REG(hw, IXGBE_MTQC);
+       /* Thresholds are different for link flow control when in DCB mode */
+       if (reg & IXGBE_MTQC_RT_ENA) {
+               rx_pba_size = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(packetbuf_num));
+
+               /* Always disable XON for LFC when in DCB mode */
+               reg = (rx_pba_size >> 5) & 0xFFE0;
+               IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(packetbuf_num), reg);
+
+               reg = (rx_pba_size >> 2) & 0xFFE0;
+               if (hw->fc.current_mode & ixgbe_fc_tx_pause)
+                       reg |= IXGBE_FCRTH_FCEN;
+               IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(packetbuf_num), reg);
+       } else {
+               /*
+                * Set up and enable Rx high/low water mark thresholds,
+                * enable XON.
+                */
+               if (hw->fc.current_mode & ixgbe_fc_tx_pause) {
+                       if (hw->fc.send_xon) {
+                               IXGBE_WRITE_REG(hw,
+                                             IXGBE_FCRTL_82599(packetbuf_num),
+                                             (hw->fc.low_water |
+                                             IXGBE_FCRTL_XONE));
+                       } else {
+                               IXGBE_WRITE_REG(hw,
+                                             IXGBE_FCRTL_82599(packetbuf_num),
+                                             hw->fc.low_water);
+                       }
 
-               IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(packetbuf_num),
-                               (hw->fc.high_water | IXGBE_FCRTH_FCEN));
+                       IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(packetbuf_num),
+                                      (hw->fc.high_water | IXGBE_FCRTH_FCEN));
+               }
        }
 
        /* Configure pause time (2 TCs per register) */
-       reg = IXGBE_READ_REG(hw, IXGBE_FCTTV(packetbuf_num));
+       reg = IXGBE_READ_REG(hw, IXGBE_FCTTV(packetbuf_num / 2));
        if ((packetbuf_num & 1) == 0)
                reg = (reg & 0xFFFF0000) | hw->fc.pause_time;
        else
@@ -1687,100 +1725,41 @@ out:
  *  ixgbe_fc_autoneg - Configure flow control
  *  @hw: pointer to hardware structure
  *
- *  Negotiates flow control capabilities with link partner using autoneg and
- *  applies the results.
+ *  Compares our advertised flow control capabilities to those advertised by
+ *  our link partner, and determines the proper flow control mode to use.
  **/
 s32 ixgbe_fc_autoneg(struct ixgbe_hw *hw)
 {
        s32 ret_val = 0;
-       u32 i, reg, pcs_anadv_reg, pcs_lpab_reg;
-
-       reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA);
+       ixgbe_link_speed speed;
+       u32 pcs_anadv_reg, pcs_lpab_reg, linkstat;
+       bool link_up;
 
        /*
-        * The possible values of fc.current_mode are:
-        * 0:  Flow control is completely disabled
-        * 1:  Rx flow control is enabled (we can receive pause frames,
-        *     but not send pause frames).
-        * 2:  Tx flow control is enabled (we can send pause frames but
-        *     we do not support receiving pause frames).
-        * 3:  Both Rx and Tx flow control (symmetric) are enabled.
-        * 4:  Priority Flow Control is enabled.
-        * other: Invalid.
+        * AN should have completed when the cable was plugged in.
+        * Look for reasons to bail out.  Bail out if:
+        * - FC autoneg is disabled, or if
+        * - we don't have multispeed fiber, or if
+        * - we're not running at 1G, or if
+        * - link is not up, or if
+        * - link is up but AN did not complete, or if
+        * - link is up and AN completed but timed out
+        *
+        * Since we're being called from an LSC, link is already know to be up.
+        * So use link_up_wait_to_complete=false.
         */
-       switch (hw->fc.current_mode) {
-       case ixgbe_fc_none:
-               /* Flow control completely disabled by software override. */
-               reg &= ~(IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE);
-               break;
-       case ixgbe_fc_rx_pause:
-               /*
-                * Rx Flow control is enabled and Tx Flow control is
-                * disabled by software override. Since there really
-                * isn't a way to advertise that we are capable of RX
-                * Pause ONLY, we will advertise that we support both
-                * symmetric and asymmetric Rx PAUSE.  Later, we will
-                * disable the adapter's ability to send PAUSE frames.
-                */
-               reg |= (IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE);
-               break;
-       case ixgbe_fc_tx_pause:
-               /*
-                * Tx Flow control is enabled, and Rx Flow control is
-                * disabled by software override.
-                */
-               reg |= (IXGBE_PCS1GANA_ASM_PAUSE);
-               reg &= ~(IXGBE_PCS1GANA_SYM_PAUSE);
-               break;
-       case ixgbe_fc_full:
-               /* Flow control (both Rx and Tx) is enabled by SW override. */
-               reg |= (IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE);
-               break;
-#ifdef CONFIG_DCB
-       case ixgbe_fc_pfc:
-               goto out;
-               break;
-#endif
-       default:
-               hw_dbg(hw, "Flow control param set incorrectly\n");
-               ret_val = -IXGBE_ERR_CONFIG;
-               goto out;
-               break;
-       }
-
-       IXGBE_WRITE_REG(hw, IXGBE_PCS1GANA, reg);
-       reg = IXGBE_READ_REG(hw, IXGBE_PCS1GLCTL);
-
-       /* Set PCS register for autoneg */
-       /* Enable and restart autoneg */
-       reg |= IXGBE_PCS1GLCTL_AN_ENABLE | IXGBE_PCS1GLCTL_AN_RESTART;
-
-       /* Disable AN timeout */
-       if (hw->fc.strict_ieee)
-               reg &= ~IXGBE_PCS1GLCTL_AN_1G_TIMEOUT_EN;
-
-       hw_dbg(hw, "Configuring Autoneg; PCS_LCTL = 0x%08X\n", reg);
-       IXGBE_WRITE_REG(hw, IXGBE_PCS1GLCTL, reg);
-
-       /* See if autonegotiation has succeeded */
-       hw->mac.autoneg_succeeded = 0;
-       for (i = 0; i < FIBER_LINK_UP_LIMIT; i++) {
-               msleep(10);
-               reg = IXGBE_READ_REG(hw, IXGBE_PCS1GLSTA);
-               if ((reg & (IXGBE_PCS1GLSTA_LINK_OK |
-                    IXGBE_PCS1GLSTA_AN_COMPLETE)) ==
-                   (IXGBE_PCS1GLSTA_LINK_OK |
-                    IXGBE_PCS1GLSTA_AN_COMPLETE)) {
-                       if (!(reg & IXGBE_PCS1GLSTA_AN_TIMED_OUT))
-                               hw->mac.autoneg_succeeded = 1;
-                       break;
-               }
-       }
-
-       if (!hw->mac.autoneg_succeeded) {
-               /* Autoneg failed to achieve a link, so we turn fc off */
-               hw->fc.current_mode = ixgbe_fc_none;
-               hw_dbg(hw, "Flow Control = NONE.\n");
+       hw->mac.ops.check_link(hw, &speed, &link_up, false);
+       linkstat = IXGBE_READ_REG(hw, IXGBE_PCS1GLSTA);
+
+       if (hw->fc.disable_fc_autoneg ||
+           !hw->phy.multispeed_fiber ||
+           (speed != IXGBE_LINK_SPEED_1GB_FULL) ||
+           !link_up ||
+           ((linkstat & IXGBE_PCS1GLSTA_AN_COMPLETE) == 0) ||
+           ((linkstat & IXGBE_PCS1GLSTA_AN_TIMED_OUT) == 1)) {
+               hw->fc.fc_was_autonegged = false;
+               hw->fc.current_mode = hw->fc.requested_mode;
+               hw_dbg(hw, "Autoneg FC was skipped.\n");
                goto out;
        }
 
@@ -1823,21 +1802,23 @@ s32 ixgbe_fc_autoneg(struct ixgbe_hw *hw)
                hw_dbg(hw, "Flow Control = NONE.\n");
        }
 
+       /* Record that current_mode is the result of a successful autoneg */
+       hw->fc.fc_was_autonegged = true;
+
 out:
        return ret_val;
 }
 
 /**
- *  ixgbe_setup_fc_generic - Set up flow control
+ *  ixgbe_setup_fc - Set up flow control
  *  @hw: pointer to hardware structure
  *
- *  Sets up flow control.
+ *  Called at init time to set up flow control.
  **/
-s32 ixgbe_setup_fc_generic(struct ixgbe_hw *hw, s32 packetbuf_num)
+s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num)
 {
        s32 ret_val = 0;
-       ixgbe_link_speed speed;
-       bool link_up;
+       u32 reg;
 
 #ifdef CONFIG_DCB
        if (hw->fc.requested_mode == ixgbe_fc_pfc) {
@@ -1866,7 +1847,7 @@ s32 ixgbe_setup_fc_generic(struct ixgbe_hw *hw, s32 packetbuf_num)
 
        /*
         * Validate the requested mode.  Strict IEEE mode does not allow
-        * ixgbe_fc_rx_pause because it will cause testing anomalies.
+        * ixgbe_fc_rx_pause because it will cause us to fail at UNH.
         */
        if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) {
                hw_dbg(hw, "ixgbe_fc_rx_pause not valid in strict "
@@ -1883,21 +1864,77 @@ s32 ixgbe_setup_fc_generic(struct ixgbe_hw *hw, s32 packetbuf_num)
                hw->fc.requested_mode = ixgbe_fc_full;
 
        /*
-        * Save off the requested flow control mode for use later.  Depending
-        * on the link partner's capabilities, we may or may not use this mode.
+        * Set up the 1G flow control advertisement registers so the HW will be
+        * able to do fc autoneg once the cable is plugged in.  If we end up
+        * using 10g instead, this is harmless.
         */
-       hw->fc.current_mode = hw->fc.requested_mode;
-
-       /* Decide whether to use autoneg or not. */
-       hw->mac.ops.check_link(hw, &speed, &link_up, false);
-       if (!hw->fc.disable_fc_autoneg && hw->phy.multispeed_fiber &&
-           (speed == IXGBE_LINK_SPEED_1GB_FULL))
-               ret_val = ixgbe_fc_autoneg(hw);
+       reg = IXGBE_READ_REG(hw, IXGBE_PCS1GANA);
 
-       if (ret_val)
+       /*
+        * The possible values of fc.requested_mode are:
+        * 0: Flow control is completely disabled
+        * 1: Rx flow control is enabled (we can receive pause frames,
+        *    but not send pause frames).
+        * 2: Tx flow control is enabled (we can send pause frames but
+        *    we do not support receiving pause frames).
+        * 3: Both Rx and Tx flow control (symmetric) are enabled.
+#ifdef CONFIG_DCB
+        * 4: Priority Flow Control is enabled.
+#endif
+        * other: Invalid.
+        */
+       switch (hw->fc.requested_mode) {
+       case ixgbe_fc_none:
+               /* Flow control completely disabled by software override. */
+               reg &= ~(IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE);
+               break;
+       case ixgbe_fc_rx_pause:
+               /*
+                * Rx Flow control is enabled and Tx Flow control is
+                * disabled by software override. Since there really
+                * isn't a way to advertise that we are capable of RX
+                * Pause ONLY, we will advertise that we support both
+                * symmetric and asymmetric Rx PAUSE.  Later, we will
+                * disable the adapter's ability to send PAUSE frames.
+                */
+               reg |= (IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE);
+               break;
+       case ixgbe_fc_tx_pause:
+               /*
+                * Tx Flow control is enabled, and Rx Flow control is
+                * disabled by software override.
+                */
+               reg |= (IXGBE_PCS1GANA_ASM_PAUSE);
+               reg &= ~(IXGBE_PCS1GANA_SYM_PAUSE);
+               break;
+       case ixgbe_fc_full:
+               /* Flow control (both Rx and Tx) is enabled by SW override. */
+               reg |= (IXGBE_PCS1GANA_SYM_PAUSE | IXGBE_PCS1GANA_ASM_PAUSE);
+               break;
+#ifdef CONFIG_DCB
+       case ixgbe_fc_pfc:
+               goto out;
+               break;
+#endif /* CONFIG_DCB */
+       default:
+               hw_dbg(hw, "Flow control param set incorrectly\n");
+               ret_val = -IXGBE_ERR_CONFIG;
                goto out;
+               break;
+       }
 
-       ret_val = ixgbe_fc_enable(hw, packetbuf_num);
+       IXGBE_WRITE_REG(hw, IXGBE_PCS1GANA, reg);
+       reg = IXGBE_READ_REG(hw, IXGBE_PCS1GLCTL);
+
+       /* Enable and restart autoneg to inform the link partner */
+       reg |= IXGBE_PCS1GLCTL_AN_ENABLE | IXGBE_PCS1GLCTL_AN_RESTART;
+
+       /* Disable AN timeout */
+       if (hw->fc.strict_ieee)
+               reg &= ~IXGBE_PCS1GLCTL_AN_1G_TIMEOUT_EN;
+
+       IXGBE_WRITE_REG(hw, IXGBE_PCS1GLCTL, reg);
+       hw_dbg(hw, "Set up FC; PCS1GLCTL = 0x%08X\n", reg);
 
 out:
        return ret_val;
@@ -2044,6 +2081,7 @@ s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index)
        hw->mac.ops.check_link(hw, &speed, &link_up, false);
 
        if (!link_up) {
+               autoc_reg |= IXGBE_AUTOC_AN_RESTART;
                autoc_reg |= IXGBE_AUTOC_FLU;
                IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
                msleep(10);
index dd260890ad0aa37f1bc3abdf36401dc94b2ab1c6..0d34d4d8244c7fffc6d18323c45e4b134313a7e0 100644 (file)
@@ -59,13 +59,13 @@ s32 ixgbe_init_rx_addrs_generic(struct ixgbe_hw *hw);
 s32 ixgbe_update_mc_addr_list_generic(struct ixgbe_hw *hw, u8 *mc_addr_list,
                                       u32 mc_addr_count,
                                       ixgbe_mc_addr_itr func);
-s32 ixgbe_update_uc_addr_list_generic(struct ixgbe_hw *hw, u8 *addr_list,
-                                      u32 addr_count, ixgbe_mc_addr_itr func);
+s32 ixgbe_update_uc_addr_list_generic(struct ixgbe_hw *hw,
+                                     struct list_head *uc_list);
 s32 ixgbe_enable_mc_generic(struct ixgbe_hw *hw);
 s32 ixgbe_disable_mc_generic(struct ixgbe_hw *hw);
 s32 ixgbe_enable_rx_dma_generic(struct ixgbe_hw *hw, u32 regval);
-s32 ixgbe_setup_fc_generic(struct ixgbe_hw *hw, s32 packetbuf_num);
-s32 ixgbe_fc_enable(struct ixgbe_hw *hw, s32 packtetbuf_num);
+s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num);
+s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw, s32 packtetbuf_num);
 s32 ixgbe_fc_autoneg(struct ixgbe_hw *hw);
 
 s32 ixgbe_validate_mac_addr(u8 *mac_addr);
index 62206273d88806921669f38f4ca3a911f4df5d31..f30263898ebca85cc9613d32a311e916ce33a6f8 100644 (file)
@@ -294,6 +294,9 @@ s32 ixgbe_dcb_config_pfc_82598(struct ixgbe_hw *hw,
        u32 reg, rx_pba_size;
        u8  i;
 
+       if (!dcb_config->pfc_mode_enable)
+               goto out;
+
        /* Enable Transmit Priority Flow Control */
        reg = IXGBE_READ_REG(hw, IXGBE_RMCS);
        reg &= ~IXGBE_RMCS_TFCE_802_3X;
@@ -341,6 +344,7 @@ s32 ixgbe_dcb_config_pfc_82598(struct ixgbe_hw *hw,
        /* Configure flow control refresh threshold value */
        IXGBE_WRITE_REG(hw, IXGBE_FCRTV, 0x3400);
 
+out:
        return 0;
 }
 
index f4417fc3b0fded18b6980d92e472ccebb7701fc6..589f62c7062a8612da5423350a5332ff14c0807b 100644 (file)
@@ -295,7 +295,7 @@ s32 ixgbe_dcb_config_pfc_82599(struct ixgbe_hw *hw,
        /* If PFC is disabled globally then fall back to LFC. */
        if (!dcb_config->pfc_mode_enable) {
                for (i = 0; i < MAX_TRAFFIC_CLASS; i++)
-                       hw->mac.ops.setup_fc(hw, i);
+                       hw->mac.ops.fc_enable(hw, i);
                goto out;
        }
 
index bd0a0c2769520fd3b3f7186dfc7a539a00397d2d..d56890f5c9d53f736c1ba58c5c1d73f5e2c131d2 100644 (file)
 
 #include "ixgbe.h"
 #include <linux/dcbnl.h>
+#include "ixgbe_dcb_82598.h"
+#include "ixgbe_dcb_82599.h"
 
 /* Callbacks for DCB netlink in the kernel */
 #define BIT_DCB_MODE   0x01
 #define BIT_PFC                0x02
 #define BIT_PG_RX      0x04
 #define BIT_PG_TX      0x08
-#define BIT_BCN         0x10
+#define BIT_RESETLINK   0x40
 #define BIT_LINKSPEED   0x80
 
+/* Responses for the DCB_C_SET_ALL command */
+#define DCB_HW_CHG_RST  0  /* DCB configuration changed with reset */
+#define DCB_NO_HW_CHG   1  /* DCB configuration did not change */
+#define DCB_HW_CHG      2  /* DCB configuration changed, no reset */
+
 int ixgbe_copy_dcb_cfg(struct ixgbe_dcb_config *src_dcb_cfg,
                        struct ixgbe_dcb_config *dst_dcb_cfg, int tc_max)
 {
@@ -124,15 +131,12 @@ static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state)
 
                if (netif_running(netdev))
                        netdev->netdev_ops->ndo_stop(netdev);
-               ixgbe_reset_interrupt_capability(adapter);
-               ixgbe_napi_del_all(adapter);
-               INIT_LIST_HEAD(&netdev->napi_list);
-               kfree(adapter->tx_ring);
-               kfree(adapter->rx_ring);
-               adapter->tx_ring = NULL;
-               adapter->rx_ring = NULL;
+               ixgbe_clear_interrupt_scheme(adapter);
 
-               adapter->hw.fc.requested_mode = ixgbe_fc_pfc;
+               if (adapter->hw.mac.type == ixgbe_mac_82598EB) {
+                       adapter->last_lfc_mode = adapter->hw.fc.current_mode;
+                       adapter->hw.fc.requested_mode = ixgbe_fc_none;
+               }
                adapter->flags &= ~IXGBE_FLAG_RSS_ENABLED;
                adapter->flags |= IXGBE_FLAG_DCB_ENABLED;
                ixgbe_init_interrupt_scheme(adapter);
@@ -141,17 +145,13 @@ static u8 ixgbe_dcbnl_set_state(struct net_device *netdev, u8 state)
        } else {
                /* Turn off DCB */
                if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
-                       adapter->hw.fc.requested_mode = ixgbe_fc_default;
                        if (netif_running(netdev))
                                netdev->netdev_ops->ndo_stop(netdev);
-                       ixgbe_reset_interrupt_capability(adapter);
-                       ixgbe_napi_del_all(adapter);
-                       INIT_LIST_HEAD(&netdev->napi_list);
-                       kfree(adapter->tx_ring);
-                       kfree(adapter->rx_ring);
-                       adapter->tx_ring = NULL;
-                       adapter->rx_ring = NULL;
+                       ixgbe_clear_interrupt_scheme(adapter);
 
+                       adapter->hw.fc.requested_mode = adapter->last_lfc_mode;
+                       adapter->temp_dcb_cfg.pfc_mode_enable = false;
+                       adapter->dcb_cfg.pfc_mode_enable = false;
                        adapter->flags &= ~IXGBE_FLAG_DCB_ENABLED;
                        adapter->flags |= IXGBE_FLAG_RSS_ENABLED;
                        ixgbe_init_interrupt_scheme(adapter);
@@ -167,10 +167,15 @@ static void ixgbe_dcbnl_get_perm_hw_addr(struct net_device *netdev,
                                         u8 *perm_addr)
 {
        struct ixgbe_adapter *adapter = netdev_priv(netdev);
-       int i;
+       int i, j;
 
        for (i = 0; i < netdev->addr_len; i++)
                perm_addr[i] = adapter->hw.mac.perm_addr[i];
+
+       if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
+               for (j = 0; j < netdev->addr_len; j++, i++)
+                       perm_addr[i] = adapter->hw.mac.san_addr[j];
+       }
 }
 
 static void ixgbe_dcbnl_set_pg_tc_cfg_tx(struct net_device *netdev, int tc,
@@ -197,8 +202,10 @@ static void ixgbe_dcbnl_set_pg_tc_cfg_tx(struct net_device *netdev, int tc,
            (adapter->temp_dcb_cfg.tc_config[tc].path[0].bwg_percent !=
             adapter->dcb_cfg.tc_config[tc].path[0].bwg_percent) ||
            (adapter->temp_dcb_cfg.tc_config[tc].path[0].up_to_tc_bitmap !=
-            adapter->dcb_cfg.tc_config[tc].path[0].up_to_tc_bitmap))
+            adapter->dcb_cfg.tc_config[tc].path[0].up_to_tc_bitmap)) {
                adapter->dcb_set_bitmap |= BIT_PG_TX;
+               adapter->dcb_set_bitmap |= BIT_RESETLINK;
+       }
 }
 
 static void ixgbe_dcbnl_set_pg_bwg_cfg_tx(struct net_device *netdev, int bwg_id,
@@ -209,8 +216,10 @@ static void ixgbe_dcbnl_set_pg_bwg_cfg_tx(struct net_device *netdev, int bwg_id,
        adapter->temp_dcb_cfg.bw_percentage[0][bwg_id] = bw_pct;
 
        if (adapter->temp_dcb_cfg.bw_percentage[0][bwg_id] !=
-           adapter->dcb_cfg.bw_percentage[0][bwg_id])
+           adapter->dcb_cfg.bw_percentage[0][bwg_id]) {
                adapter->dcb_set_bitmap |= BIT_PG_RX;
+               adapter->dcb_set_bitmap |= BIT_RESETLINK;
+       }
 }
 
 static void ixgbe_dcbnl_set_pg_tc_cfg_rx(struct net_device *netdev, int tc,
@@ -237,8 +246,10 @@ static void ixgbe_dcbnl_set_pg_tc_cfg_rx(struct net_device *netdev, int tc,
            (adapter->temp_dcb_cfg.tc_config[tc].path[1].bwg_percent !=
             adapter->dcb_cfg.tc_config[tc].path[1].bwg_percent) ||
            (adapter->temp_dcb_cfg.tc_config[tc].path[1].up_to_tc_bitmap !=
-            adapter->dcb_cfg.tc_config[tc].path[1].up_to_tc_bitmap))
+            adapter->dcb_cfg.tc_config[tc].path[1].up_to_tc_bitmap)) {
                adapter->dcb_set_bitmap |= BIT_PG_RX;
+               adapter->dcb_set_bitmap |= BIT_RESETLINK;
+       }
 }
 
 static void ixgbe_dcbnl_set_pg_bwg_cfg_rx(struct net_device *netdev, int bwg_id,
@@ -249,8 +260,10 @@ static void ixgbe_dcbnl_set_pg_bwg_cfg_rx(struct net_device *netdev, int bwg_id,
        adapter->temp_dcb_cfg.bw_percentage[1][bwg_id] = bw_pct;
 
        if (adapter->temp_dcb_cfg.bw_percentage[1][bwg_id] !=
-           adapter->dcb_cfg.bw_percentage[1][bwg_id])
+           adapter->dcb_cfg.bw_percentage[1][bwg_id]) {
                adapter->dcb_set_bitmap |= BIT_PG_RX;
+               adapter->dcb_set_bitmap |= BIT_RESETLINK;
+       }
 }
 
 static void ixgbe_dcbnl_get_pg_tc_cfg_tx(struct net_device *netdev, int tc,
@@ -319,28 +332,60 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev)
        struct ixgbe_adapter *adapter = netdev_priv(netdev);
        int ret;
 
-       adapter->dcb_set_bitmap &= ~BIT_BCN;    /* no set for BCN */
        if (!adapter->dcb_set_bitmap)
-               return 1;
+               return DCB_NO_HW_CHG;
 
-       while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state))
-               msleep(1);
+       /*
+        * Only take down the adapter if the configuration change
+        * requires a reset.
+        */
+       if (adapter->dcb_set_bitmap & BIT_RESETLINK) {
+               while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state))
+                       msleep(1);
 
-       if (netif_running(netdev))
-               ixgbe_down(adapter);
+               if (netif_running(netdev))
+                       ixgbe_down(adapter);
+       }
 
        ret = ixgbe_copy_dcb_cfg(&adapter->temp_dcb_cfg, &adapter->dcb_cfg,
                                 adapter->ring_feature[RING_F_DCB].indices);
        if (ret) {
-               clear_bit(__IXGBE_RESETTING, &adapter->state);
-               return ret;
+               if (adapter->dcb_set_bitmap & BIT_RESETLINK)
+                       clear_bit(__IXGBE_RESETTING, &adapter->state);
+               return DCB_NO_HW_CHG;
+       }
+
+       if (adapter->dcb_cfg.pfc_mode_enable) {
+               if ((adapter->hw.mac.type != ixgbe_mac_82598EB) &&
+                       (adapter->hw.fc.current_mode != ixgbe_fc_pfc))
+                       adapter->last_lfc_mode = adapter->hw.fc.current_mode;
+               adapter->hw.fc.requested_mode = ixgbe_fc_pfc;
+       } else {
+               if (adapter->hw.mac.type != ixgbe_mac_82598EB)
+                       adapter->hw.fc.requested_mode = adapter->last_lfc_mode;
+               else
+                       adapter->hw.fc.requested_mode = ixgbe_fc_none;
        }
 
-       if (netif_running(netdev))
-               ixgbe_up(adapter);
+       if (adapter->dcb_set_bitmap & BIT_RESETLINK) {
+               if (netif_running(netdev))
+                       ixgbe_up(adapter);
+               ret = DCB_HW_CHG_RST;
+       } else if (adapter->dcb_set_bitmap & BIT_PFC) {
+               if (adapter->hw.mac.type == ixgbe_mac_82598EB)
+                       ixgbe_dcb_config_pfc_82598(&adapter->hw,
+                                                  &adapter->dcb_cfg);
+               else if (adapter->hw.mac.type == ixgbe_mac_82599EB)
+                       ixgbe_dcb_config_pfc_82599(&adapter->hw,
+                                                  &adapter->dcb_cfg);
+               ret = DCB_HW_CHG;
+       }
+       if (adapter->dcb_cfg.pfc_mode_enable)
+               adapter->hw.fc.current_mode = ixgbe_fc_pfc;
 
+       if (adapter->dcb_set_bitmap & BIT_RESETLINK)
+               clear_bit(__IXGBE_RESETTING, &adapter->state);
        adapter->dcb_set_bitmap = 0x00;
-       clear_bit(__IXGBE_RESETTING, &adapter->state);
        return ret;
 }
 
@@ -416,11 +461,17 @@ static u8 ixgbe_dcbnl_getpfcstate(struct net_device *netdev)
 {
        struct ixgbe_adapter *adapter = netdev_priv(netdev);
 
-       return !!(adapter->flags & IXGBE_FLAG_DCB_ENABLED);
+       return adapter->dcb_cfg.pfc_mode_enable;
 }
 
 static void ixgbe_dcbnl_setpfcstate(struct net_device *netdev, u8 state)
 {
+       struct ixgbe_adapter *adapter = netdev_priv(netdev);
+
+       adapter->temp_dcb_cfg.pfc_mode_enable = state;
+       if (adapter->temp_dcb_cfg.pfc_mode_enable !=
+               adapter->dcb_cfg.pfc_mode_enable)
+               adapter->dcb_set_bitmap |= BIT_PFC;
        return;
 }
 
index f0a20facc6509d7f06a6e60804a03e65666826c2..86f4f3e36f27fc8d3ff0cccd734d8d691694bbd3 100644 (file)
@@ -67,6 +67,9 @@ static struct ixgbe_stats ixgbe_gstrings_stats[] = {
        {"rx_over_errors", IXGBE_STAT(net_stats.rx_over_errors)},
        {"rx_crc_errors", IXGBE_STAT(net_stats.rx_crc_errors)},
        {"rx_frame_errors", IXGBE_STAT(net_stats.rx_frame_errors)},
+       {"hw_rsc_count", IXGBE_STAT(rsc_count)},
+       {"fdir_match", IXGBE_STAT(stats.fdirmatch)},
+       {"fdir_miss", IXGBE_STAT(stats.fdirmiss)},
        {"rx_fifo_errors", IXGBE_STAT(net_stats.rx_fifo_errors)},
        {"rx_missed_errors", IXGBE_STAT(net_stats.rx_missed_errors)},
        {"tx_aborted_errors", IXGBE_STAT(net_stats.tx_aborted_errors)},
@@ -90,6 +93,14 @@ static struct ixgbe_stats ixgbe_gstrings_stats[] = {
        {"alloc_rx_page_failed", IXGBE_STAT(alloc_rx_page_failed)},
        {"alloc_rx_buff_failed", IXGBE_STAT(alloc_rx_buff_failed)},
        {"rx_no_dma_resources", IXGBE_STAT(hw_rx_no_dma_resources)},
+#ifdef IXGBE_FCOE
+       {"fcoe_bad_fccrc", IXGBE_STAT(stats.fccrc)},
+       {"rx_fcoe_dropped", IXGBE_STAT(stats.fcoerpdc)},
+       {"rx_fcoe_packets", IXGBE_STAT(stats.fcoeprc)},
+       {"rx_fcoe_dwords", IXGBE_STAT(stats.fcoedwrc)},
+       {"tx_fcoe_packets", IXGBE_STAT(stats.fcoeptc)},
+       {"tx_fcoe_dwords", IXGBE_STAT(stats.fcoedwtc)},
+#endif /* IXGBE_FCOE */
 };
 
 #define IXGBE_QUEUE_STATS_LEN \
@@ -109,6 +120,13 @@ static struct ixgbe_stats ixgbe_gstrings_stats[] = {
                          IXGBE_PB_STATS_LEN + \
                          IXGBE_QUEUE_STATS_LEN)
 
+static const char ixgbe_gstrings_test[][ETH_GSTRING_LEN] = {
+       "Register test  (offline)", "Eeprom test    (offline)",
+       "Interrupt test (offline)", "Loopback test  (offline)",
+       "Link test   (on/offline)"
+};
+#define IXGBE_TEST_LEN sizeof(ixgbe_gstrings_test) / ETH_GSTRING_LEN
+
 static int ixgbe_get_settings(struct net_device *netdev,
                               struct ethtool_cmd *ecmd)
 {
@@ -120,11 +138,12 @@ static int ixgbe_get_settings(struct net_device *netdev,
        ecmd->supported = SUPPORTED_10000baseT_Full;
        ecmd->autoneg = AUTONEG_ENABLE;
        ecmd->transceiver = XCVR_EXTERNAL;
-       if (hw->phy.media_type == ixgbe_media_type_copper) {
+       if ((hw->phy.media_type == ixgbe_media_type_copper) ||
+           (hw->mac.type == ixgbe_mac_82599EB)) {
                ecmd->supported |= (SUPPORTED_1000baseT_Full |
-                                   SUPPORTED_TP | SUPPORTED_Autoneg);
+                                   SUPPORTED_Autoneg);
 
-               ecmd->advertising = (ADVERTISED_TP | ADVERTISED_Autoneg);
+               ecmd->advertising = ADVERTISED_Autoneg;
                if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL)
                        ecmd->advertising |= ADVERTISED_10000baseT_Full;
                if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL)
@@ -139,7 +158,15 @@ static int ixgbe_get_settings(struct net_device *netdev,
                        ecmd->advertising |= (ADVERTISED_10000baseT_Full |
                                              ADVERTISED_1000baseT_Full);
 
-               ecmd->port = PORT_TP;
+               if (hw->phy.media_type == ixgbe_media_type_copper) {
+                       ecmd->supported |= SUPPORTED_TP;
+                       ecmd->advertising |= ADVERTISED_TP;
+                       ecmd->port = PORT_TP;
+               } else {
+                       ecmd->supported |= SUPPORTED_FIBRE;
+                       ecmd->advertising |= ADVERTISED_FIBRE;
+                       ecmd->port = PORT_FIBRE;
+               }
        } else if (hw->phy.media_type == ixgbe_media_type_backplane) {
                /* Set as FIBRE until SERDES defined in kernel */
                switch (hw->device_id) {
@@ -187,16 +214,10 @@ static int ixgbe_set_settings(struct net_device *netdev,
        struct ixgbe_adapter *adapter = netdev_priv(netdev);
        struct ixgbe_hw *hw = &adapter->hw;
        u32 advertised, old;
-       s32 err;
+       s32 err = 0;
 
-       switch (hw->phy.media_type) {
-       case ixgbe_media_type_fiber:
-               if ((ecmd->autoneg == AUTONEG_ENABLE) ||
-                   (ecmd->speed + ecmd->duplex != SPEED_10000 + DUPLEX_FULL))
-                       return -EINVAL;
-               /* in this case we currently only support 10Gb/FULL */
-               break;
-       case ixgbe_media_type_copper:
+       if ((hw->phy.media_type == ixgbe_media_type_copper) ||
+           (hw->mac.type == ixgbe_mac_82599EB)) {
                /* 10000/copper and 1000/copper must autoneg
                 * this function does not support any duplex forcing, but can
                 * limit the advertising of the adapter to only 10000 or 1000 */
@@ -212,20 +233,23 @@ static int ixgbe_set_settings(struct net_device *netdev,
                        advertised |= IXGBE_LINK_SPEED_1GB_FULL;
 
                if (old == advertised)
-                       break;
+                       return err;
                /* this sets the link speed and restarts auto-neg */
+               hw->mac.autotry_restart = true;
                err = hw->mac.ops.setup_link_speed(hw, advertised, true, true);
                if (err) {
                        DPRINTK(PROBE, INFO,
                                "setup link failed with code %d\n", err);
                        hw->mac.ops.setup_link_speed(hw, old, true, true);
                }
-               break;
-       default:
-               break;
+       } else {
+               /* in this case we currently only support 10Gb/FULL */
+               if ((ecmd->autoneg == AUTONEG_ENABLE) ||
+                   (ecmd->speed + ecmd->duplex != SPEED_10000 + DUPLEX_FULL))
+                       return -EINVAL;
        }
 
-       return 0;
+       return err;
 }
 
 static void ixgbe_get_pauseparam(struct net_device *netdev,
@@ -245,6 +269,13 @@ static void ixgbe_get_pauseparam(struct net_device *netdev,
        else
                pause->autoneg = 1;
 
+#ifdef CONFIG_DCB
+       if (hw->fc.current_mode == ixgbe_fc_pfc) {
+               pause->rx_pause = 0;
+               pause->tx_pause = 0;
+       }
+
+#endif
        if (hw->fc.current_mode == ixgbe_fc_rx_pause) {
                pause->rx_pause = 1;
        } else if (hw->fc.current_mode == ixgbe_fc_tx_pause) {
@@ -260,24 +291,46 @@ static int ixgbe_set_pauseparam(struct net_device *netdev,
 {
        struct ixgbe_adapter *adapter = netdev_priv(netdev);
        struct ixgbe_hw *hw = &adapter->hw;
+       struct ixgbe_fc_info fc;
+
+#ifdef CONFIG_DCB
+       if (adapter->dcb_cfg.pfc_mode_enable ||
+               ((hw->mac.type == ixgbe_mac_82598EB) &&
+               (adapter->flags & IXGBE_FLAG_DCB_ENABLED)))
+               return -EINVAL;
+
+#endif
+
+       fc = hw->fc;
 
        if (pause->autoneg != AUTONEG_ENABLE)
-               hw->fc.disable_fc_autoneg = true;
+               fc.disable_fc_autoneg = true;
        else
-               hw->fc.disable_fc_autoneg = false;
+               fc.disable_fc_autoneg = false;
 
        if (pause->rx_pause && pause->tx_pause)
-               hw->fc.requested_mode = ixgbe_fc_full;
+               fc.requested_mode = ixgbe_fc_full;
        else if (pause->rx_pause && !pause->tx_pause)
-               hw->fc.requested_mode = ixgbe_fc_rx_pause;
+               fc.requested_mode = ixgbe_fc_rx_pause;
        else if (!pause->rx_pause && pause->tx_pause)
-               hw->fc.requested_mode = ixgbe_fc_tx_pause;
+               fc.requested_mode = ixgbe_fc_tx_pause;
        else if (!pause->rx_pause && !pause->tx_pause)
-               hw->fc.requested_mode = ixgbe_fc_none;
+               fc.requested_mode = ixgbe_fc_none;
        else
                return -EINVAL;
 
-       hw->mac.ops.setup_fc(hw, 0);
+#ifdef CONFIG_DCB
+       adapter->last_lfc_mode = fc.requested_mode;
+#endif
+
+       /* if the thing changed then we'll update and use new autoneg */
+       if (memcmp(&fc, &hw->fc, sizeof(struct ixgbe_fc_info))) {
+               hw->fc = fc;
+               if (netif_running(netdev))
+                       ixgbe_reinit_locked(adapter);
+               else
+                       ixgbe_reset(adapter);
+       }
 
        return 0;
 }
@@ -311,10 +364,17 @@ static u32 ixgbe_get_tx_csum(struct net_device *netdev)
 
 static int ixgbe_set_tx_csum(struct net_device *netdev, u32 data)
 {
-       if (data)
+       struct ixgbe_adapter *adapter = netdev_priv(netdev);
+
+       if (data) {
                netdev->features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
-       else
+               if (adapter->hw.mac.type == ixgbe_mac_82599EB)
+                       netdev->features |= NETIF_F_SCTP_CSUM;
+       } else {
                netdev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
+               if (adapter->hw.mac.type == ixgbe_mac_82599EB)
+                       netdev->features &= ~NETIF_F_SCTP_CSUM;
+       }
 
        return 0;
 }
@@ -710,6 +770,7 @@ static void ixgbe_get_drvinfo(struct net_device *netdev,
        strncpy(drvinfo->fw_version, firmware_version, 32);
        strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32);
        drvinfo->n_stats = IXGBE_STATS_LEN;
+       drvinfo->testinfo_len = IXGBE_TEST_LEN;
        drvinfo->regdump_len = ixgbe_get_regs_len(netdev);
 }
 
@@ -781,7 +842,6 @@ static int ixgbe_set_ringparam(struct net_device *netdev,
                                }
                                goto err_setup;
                        }
-                       temp_tx_ring[i].v_idx = adapter->tx_ring[i].v_idx;
                }
                need_update = true;
        }
@@ -811,7 +871,6 @@ static int ixgbe_set_ringparam(struct net_device *netdev,
                                }
                                goto err_setup;
                        }
-                       temp_rx_ring[i].v_idx = adapter->rx_ring[i].v_idx;
                }
                need_update = true;
        }
@@ -851,6 +910,8 @@ err_setup:
 static int ixgbe_get_sset_count(struct net_device *netdev, int sset)
 {
        switch (sset) {
+       case ETH_SS_TEST:
+               return IXGBE_TEST_LEN;
        case ETH_SS_STATS:
                return IXGBE_STATS_LEN;
        default:
@@ -905,6 +966,10 @@ static void ixgbe_get_strings(struct net_device *netdev, u32 stringset,
        int i;
 
        switch (stringset) {
+       case ETH_SS_TEST:
+               memcpy(data, *ixgbe_gstrings_test,
+                      IXGBE_TEST_LEN * ETH_GSTRING_LEN);
+               break;
        case ETH_SS_STATS:
                for (i = 0; i < IXGBE_GLOBAL_STATS_LEN; i++) {
                        memcpy(p, ixgbe_gstrings_stats[i].stat_string,
@@ -942,6 +1007,815 @@ static void ixgbe_get_strings(struct net_device *netdev, u32 stringset,
        }
 }
 
+static int ixgbe_link_test(struct ixgbe_adapter *adapter, u64 *data)
+{
+       struct ixgbe_hw *hw = &adapter->hw;
+       bool link_up;
+       u32 link_speed = 0;
+       *data = 0;
+
+       hw->mac.ops.check_link(hw, &link_speed, &link_up, true);
+       if (link_up)
+               return *data;
+       else
+               *data = 1;
+       return *data;
+}
+
+/* ethtool register test data */
+struct ixgbe_reg_test {
+       u16 reg;
+       u8  array_len;
+       u8  test_type;
+       u32 mask;
+       u32 write;
+};
+
+/* In the hardware, registers are laid out either singly, in arrays
+ * spaced 0x40 bytes apart, or in contiguous tables.  We assume
+ * most tests take place on arrays or single registers (handled
+ * as a single-element array) and special-case the tables.
+ * Table tests are always pattern tests.
+ *
+ * We also make provision for some required setup steps by specifying
+ * registers to be written without any read-back testing.
+ */
+
+#define PATTERN_TEST   1
+#define SET_READ_TEST  2
+#define WRITE_NO_TEST  3
+#define TABLE32_TEST   4
+#define TABLE64_TEST_LO        5
+#define TABLE64_TEST_HI        6
+
+/* default 82599 register test */
+static struct ixgbe_reg_test reg_test_82599[] = {
+       { IXGBE_FCRTL_82599(0), 1, PATTERN_TEST, 0x8007FFF0, 0x8007FFF0 },
+       { IXGBE_FCRTH_82599(0), 1, PATTERN_TEST, 0x8007FFF0, 0x8007FFF0 },
+       { IXGBE_PFCTOP, 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
+       { IXGBE_VLNCTRL, 1, PATTERN_TEST, 0x00000000, 0x00000000 },
+       { IXGBE_RDBAL(0), 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFF80 },
+       { IXGBE_RDBAH(0), 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
+       { IXGBE_RDLEN(0), 4, PATTERN_TEST, 0x000FFF80, 0x000FFFFF },
+       { IXGBE_RXDCTL(0), 4, WRITE_NO_TEST, 0, IXGBE_RXDCTL_ENABLE },
+       { IXGBE_RDT(0), 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
+       { IXGBE_RXDCTL(0), 4, WRITE_NO_TEST, 0, 0 },
+       { IXGBE_FCRTH(0), 1, PATTERN_TEST, 0x8007FFF0, 0x8007FFF0 },
+       { IXGBE_FCTTV(0), 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
+       { IXGBE_TDBAL(0), 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
+       { IXGBE_TDBAH(0), 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
+       { IXGBE_TDLEN(0), 4, PATTERN_TEST, 0x000FFF80, 0x000FFF80 },
+       { IXGBE_RXCTRL, 1, SET_READ_TEST, 0x00000001, 0x00000001 },
+       { IXGBE_RAL(0), 16, TABLE64_TEST_LO, 0xFFFFFFFF, 0xFFFFFFFF },
+       { IXGBE_RAL(0), 16, TABLE64_TEST_HI, 0x8001FFFF, 0x800CFFFF },
+       { IXGBE_MTA(0), 128, TABLE32_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
+       { 0, 0, 0, 0 }
+};
+
+/* default 82598 register test */
+static struct ixgbe_reg_test reg_test_82598[] = {
+       { IXGBE_FCRTL(0), 1, PATTERN_TEST, 0x8007FFF0, 0x8007FFF0 },
+       { IXGBE_FCRTH(0), 1, PATTERN_TEST, 0x8007FFF0, 0x8007FFF0 },
+       { IXGBE_PFCTOP, 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
+       { IXGBE_VLNCTRL, 1, PATTERN_TEST, 0x00000000, 0x00000000 },
+       { IXGBE_RDBAL(0), 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
+       { IXGBE_RDBAH(0), 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
+       { IXGBE_RDLEN(0), 4, PATTERN_TEST, 0x000FFF80, 0x000FFFFF },
+       /* Enable all four RX queues before testing. */
+       { IXGBE_RXDCTL(0), 4, WRITE_NO_TEST, 0, IXGBE_RXDCTL_ENABLE },
+       /* RDH is read-only for 82598, only test RDT. */
+       { IXGBE_RDT(0), 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
+       { IXGBE_RXDCTL(0), 4, WRITE_NO_TEST, 0, 0 },
+       { IXGBE_FCRTH(0), 1, PATTERN_TEST, 0x8007FFF0, 0x8007FFF0 },
+       { IXGBE_FCTTV(0), 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
+       { IXGBE_TIPG, 1, PATTERN_TEST, 0x000000FF, 0x000000FF },
+       { IXGBE_TDBAL(0), 4, PATTERN_TEST, 0xFFFFFF80, 0xFFFFFFFF },
+       { IXGBE_TDBAH(0), 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
+       { IXGBE_TDLEN(0), 4, PATTERN_TEST, 0x000FFF80, 0x000FFFFF },
+       { IXGBE_RXCTRL, 1, SET_READ_TEST, 0x00000003, 0x00000003 },
+       { IXGBE_DTXCTL, 1, SET_READ_TEST, 0x00000005, 0x00000005 },
+       { IXGBE_RAL(0), 16, TABLE64_TEST_LO, 0xFFFFFFFF, 0xFFFFFFFF },
+       { IXGBE_RAL(0), 16, TABLE64_TEST_HI, 0x800CFFFF, 0x800CFFFF },
+       { IXGBE_MTA(0), 128, TABLE32_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
+       { 0, 0, 0, 0 }
+};
+
+#define REG_PATTERN_TEST(R, M, W)                                             \
+{                                                                             \
+       u32 pat, val, before;                                                 \
+       const u32 _test[] = {0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF}; \
+       for (pat = 0; pat < ARRAY_SIZE(_test); pat++) {                       \
+               before = readl(adapter->hw.hw_addr + R);                      \
+               writel((_test[pat] & W), (adapter->hw.hw_addr + R));          \
+               val = readl(adapter->hw.hw_addr + R);                         \
+               if (val != (_test[pat] & W & M)) {                            \
+                       DPRINTK(DRV, ERR, "pattern test reg %04X failed: got "\
+                                         "0x%08X expected 0x%08X\n",         \
+                               R, val, (_test[pat] & W & M));                \
+                       *data = R;                                            \
+                       writel(before, adapter->hw.hw_addr + R);              \
+                       return 1;                                             \
+               }                                                             \
+               writel(before, adapter->hw.hw_addr + R);                      \
+       }                                                                     \
+}
+
+#define REG_SET_AND_CHECK(R, M, W)                                            \
+{                                                                             \
+       u32 val, before;                                                      \
+       before = readl(adapter->hw.hw_addr + R);                              \
+       writel((W & M), (adapter->hw.hw_addr + R));                           \
+       val = readl(adapter->hw.hw_addr + R);                                 \
+       if ((W & M) != (val & M)) {                                           \
+               DPRINTK(DRV, ERR, "set/check reg %04X test failed: got 0x%08X "\
+                                "expected 0x%08X\n", R, (val & M), (W & M)); \
+               *data = R;                                                    \
+               writel(before, (adapter->hw.hw_addr + R));                    \
+               return 1;                                                     \
+       }                                                                     \
+       writel(before, (adapter->hw.hw_addr + R));                            \
+}
+
+static int ixgbe_reg_test(struct ixgbe_adapter *adapter, u64 *data)
+{
+       struct ixgbe_reg_test *test;
+       u32 value, before, after;
+       u32 i, toggle;
+
+       if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
+               toggle = 0x7FFFF30F;
+               test = reg_test_82599;
+       } else {
+               toggle = 0x7FFFF3FF;
+               test = reg_test_82598;
+       }
+
+       /*
+        * Because the status register is such a special case,
+        * we handle it separately from the rest of the register
+        * tests.  Some bits are read-only, some toggle, and some
+        * are writeable on newer MACs.
+        */
+       before = IXGBE_READ_REG(&adapter->hw, IXGBE_STATUS);
+       value = (IXGBE_READ_REG(&adapter->hw, IXGBE_STATUS) & toggle);
+       IXGBE_WRITE_REG(&adapter->hw, IXGBE_STATUS, toggle);
+       after = IXGBE_READ_REG(&adapter->hw, IXGBE_STATUS) & toggle;
+       if (value != after) {
+               DPRINTK(DRV, ERR, "failed STATUS register test got: "
+                       "0x%08X expected: 0x%08X\n", after, value);
+               *data = 1;
+               return 1;
+       }
+       /* restore previous status */
+       IXGBE_WRITE_REG(&adapter->hw, IXGBE_STATUS, before);
+
+       /*
+        * Perform the remainder of the register test, looping through
+        * the test table until we either fail or reach the null entry.
+        */
+       while (test->reg) {
+               for (i = 0; i < test->array_len; i++) {
+                       switch (test->test_type) {
+                       case PATTERN_TEST:
+                               REG_PATTERN_TEST(test->reg + (i * 0x40),
+                                               test->mask,
+                                               test->write);
+                               break;
+                       case SET_READ_TEST:
+                               REG_SET_AND_CHECK(test->reg + (i * 0x40),
+                                               test->mask,
+                                               test->write);
+                               break;
+                       case WRITE_NO_TEST:
+                               writel(test->write,
+                                      (adapter->hw.hw_addr + test->reg)
+                                      + (i * 0x40));
+                               break;
+                       case TABLE32_TEST:
+                               REG_PATTERN_TEST(test->reg + (i * 4),
+                                               test->mask,
+                                               test->write);
+                               break;
+                       case TABLE64_TEST_LO:
+                               REG_PATTERN_TEST(test->reg + (i * 8),
+                                               test->mask,
+                                               test->write);
+                               break;
+                       case TABLE64_TEST_HI:
+                               REG_PATTERN_TEST((test->reg + 4) + (i * 8),
+                                               test->mask,
+                                               test->write);
+                               break;
+                       }
+               }
+               test++;
+       }
+
+       *data = 0;
+       return 0;
+}
+
+static int ixgbe_eeprom_test(struct ixgbe_adapter *adapter, u64 *data)
+{
+       struct ixgbe_hw *hw = &adapter->hw;
+       if (hw->eeprom.ops.validate_checksum(hw, NULL))
+               *data = 1;
+       else
+               *data = 0;
+       return *data;
+}
+
+static irqreturn_t ixgbe_test_intr(int irq, void *data)
+{
+       struct net_device *netdev = (struct net_device *) data;
+       struct ixgbe_adapter *adapter = netdev_priv(netdev);
+
+       adapter->test_icr |= IXGBE_READ_REG(&adapter->hw, IXGBE_EICR);
+
+       return IRQ_HANDLED;
+}
+
+static int ixgbe_intr_test(struct ixgbe_adapter *adapter, u64 *data)
+{
+       struct net_device *netdev = adapter->netdev;
+       u32 mask, i = 0, shared_int = true;
+       u32 irq = adapter->pdev->irq;
+
+       *data = 0;
+
+       /* Hook up test interrupt handler just for this test */
+       if (adapter->msix_entries) {
+               /* NOTE: we don't test MSI-X interrupts here, yet */
+               return 0;
+       } else if (adapter->flags & IXGBE_FLAG_MSI_ENABLED) {
+               shared_int = false;
+               if (request_irq(irq, &ixgbe_test_intr, 0, netdev->name,
+                               netdev)) {
+                       *data = 1;
+                       return -1;
+               }
+       } else if (!request_irq(irq, &ixgbe_test_intr, IRQF_PROBE_SHARED,
+                               netdev->name, netdev)) {
+               shared_int = false;
+       } else if (request_irq(irq, &ixgbe_test_intr, IRQF_SHARED,
+                              netdev->name, netdev)) {
+               *data = 1;
+               return -1;
+       }
+       DPRINTK(HW, INFO, "testing %s interrupt\n",
+               (shared_int ? "shared" : "unshared"));
+
+       /* Disable all the interrupts */
+       IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, 0xFFFFFFFF);
+       msleep(10);
+
+       /* Test each interrupt */
+       for (; i < 10; i++) {
+               /* Interrupt to test */
+               mask = 1 << i;
+
+               if (!shared_int) {
+                       /*
+                        * Disable the interrupts to be reported in
+                        * the cause register and then force the same
+                        * interrupt and see if one gets posted.  If
+                        * an interrupt was posted to the bus, the
+                        * test failed.
+                        */
+                       adapter->test_icr = 0;
+                       IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC,
+                                       ~mask & 0x00007FFF);
+                       IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS,
+                                       ~mask & 0x00007FFF);
+                       msleep(10);
+
+                       if (adapter->test_icr & mask) {
+                               *data = 3;
+                               break;
+                       }
+               }
+
+               /*
+                * Enable the interrupt to be reported in the cause
+                * register and then force the same interrupt and see
+                * if one gets posted.  If an interrupt was not posted
+                * to the bus, the test failed.
+                */
+               adapter->test_icr = 0;
+               IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, mask);
+               IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS, mask);
+               msleep(10);
+
+               if (!(adapter->test_icr &mask)) {
+                       *data = 4;
+                       break;
+               }
+
+               if (!shared_int) {
+                       /*
+                        * Disable the other interrupts to be reported in
+                        * the cause register and then force the other
+                        * interrupts and see if any get posted.  If
+                        * an interrupt was posted to the bus, the
+                        * test failed.
+                        */
+                       adapter->test_icr = 0;
+                       IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC,
+                                       ~mask & 0x00007FFF);
+                       IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS,
+                                       ~mask & 0x00007FFF);
+                       msleep(10);
+
+                       if (adapter->test_icr) {
+                               *data = 5;
+                               break;
+                       }
+               }
+       }
+
+       /* Disable all the interrupts */
+       IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, 0xFFFFFFFF);
+       msleep(10);
+
+       /* Unhook test interrupt handler */
+       free_irq(irq, netdev);
+
+       return *data;
+}
+
+static void ixgbe_free_desc_rings(struct ixgbe_adapter *adapter)
+{
+       struct ixgbe_ring *tx_ring = &adapter->test_tx_ring;
+       struct ixgbe_ring *rx_ring = &adapter->test_rx_ring;
+       struct ixgbe_hw *hw = &adapter->hw;
+       struct pci_dev *pdev = adapter->pdev;
+       u32 reg_ctl;
+       int i;
+
+       /* shut down the DMA engines now so they can be reinitialized later */
+
+       /* first Rx */
+       reg_ctl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
+       reg_ctl &= ~IXGBE_RXCTRL_RXEN;
+       IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, reg_ctl);
+       reg_ctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(0));
+       reg_ctl &= ~IXGBE_RXDCTL_ENABLE;
+       IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(0), reg_ctl);
+
+       /* now Tx */
+       reg_ctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(0));
+       reg_ctl &= ~IXGBE_TXDCTL_ENABLE;
+       IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(0), reg_ctl);
+       if (hw->mac.type == ixgbe_mac_82599EB) {
+               reg_ctl = IXGBE_READ_REG(hw, IXGBE_DMATXCTL);
+               reg_ctl &= ~IXGBE_DMATXCTL_TE;
+               IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, reg_ctl);
+       }
+
+       ixgbe_reset(adapter);
+
+       if (tx_ring->desc && tx_ring->tx_buffer_info) {
+               for (i = 0; i < tx_ring->count; i++) {
+                       struct ixgbe_tx_buffer *buf =
+                                       &(tx_ring->tx_buffer_info[i]);
+                       if (buf->dma)
+                               pci_unmap_single(pdev, buf->dma, buf->length,
+                                                PCI_DMA_TODEVICE);
+                       if (buf->skb)
+                               dev_kfree_skb(buf->skb);
+               }
+       }
+
+       if (rx_ring->desc && rx_ring->rx_buffer_info) {
+               for (i = 0; i < rx_ring->count; i++) {
+                       struct ixgbe_rx_buffer *buf =
+                                       &(rx_ring->rx_buffer_info[i]);
+                       if (buf->dma)
+                               pci_unmap_single(pdev, buf->dma,
+                                                IXGBE_RXBUFFER_2048,
+                                                PCI_DMA_FROMDEVICE);
+                       if (buf->skb)
+                               dev_kfree_skb(buf->skb);
+               }
+       }
+
+       if (tx_ring->desc) {
+               pci_free_consistent(pdev, tx_ring->size, tx_ring->desc,
+                                   tx_ring->dma);
+               tx_ring->desc = NULL;
+       }
+       if (rx_ring->desc) {
+               pci_free_consistent(pdev, rx_ring->size, rx_ring->desc,
+                                   rx_ring->dma);
+               rx_ring->desc = NULL;
+       }
+
+       kfree(tx_ring->tx_buffer_info);
+       tx_ring->tx_buffer_info = NULL;
+       kfree(rx_ring->rx_buffer_info);
+       rx_ring->rx_buffer_info = NULL;
+
+       return;
+}
+
+static int ixgbe_setup_desc_rings(struct ixgbe_adapter *adapter)
+{
+       struct ixgbe_ring *tx_ring = &adapter->test_tx_ring;
+       struct ixgbe_ring *rx_ring = &adapter->test_rx_ring;
+       struct pci_dev *pdev = adapter->pdev;
+       u32 rctl, reg_data;
+       int i, ret_val;
+
+       /* Setup Tx descriptor ring and Tx buffers */
+
+       if (!tx_ring->count)
+               tx_ring->count = IXGBE_DEFAULT_TXD;
+
+       tx_ring->tx_buffer_info = kcalloc(tx_ring->count,
+                                         sizeof(struct ixgbe_tx_buffer),
+                                         GFP_KERNEL);
+       if (!(tx_ring->tx_buffer_info)) {
+               ret_val = 1;
+               goto err_nomem;
+       }
+
+       tx_ring->size = tx_ring->count * sizeof(struct ixgbe_legacy_tx_desc);
+       tx_ring->size = ALIGN(tx_ring->size, 4096);
+       if (!(tx_ring->desc = pci_alloc_consistent(pdev, tx_ring->size,
+                                                  &tx_ring->dma))) {
+               ret_val = 2;
+               goto err_nomem;
+       }
+       tx_ring->next_to_use = tx_ring->next_to_clean = 0;
+
+       IXGBE_WRITE_REG(&adapter->hw, IXGBE_TDBAL(0),
+                       ((u64) tx_ring->dma & 0x00000000FFFFFFFF));
+       IXGBE_WRITE_REG(&adapter->hw, IXGBE_TDBAH(0),
+                       ((u64) tx_ring->dma >> 32));
+       IXGBE_WRITE_REG(&adapter->hw, IXGBE_TDLEN(0),
+                       tx_ring->count * sizeof(struct ixgbe_legacy_tx_desc));
+       IXGBE_WRITE_REG(&adapter->hw, IXGBE_TDH(0), 0);
+       IXGBE_WRITE_REG(&adapter->hw, IXGBE_TDT(0), 0);
+
+       reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_HLREG0);
+       reg_data |= IXGBE_HLREG0_TXPADEN;
+       IXGBE_WRITE_REG(&adapter->hw, IXGBE_HLREG0, reg_data);
+
+       if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
+               reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_DMATXCTL);
+               reg_data |= IXGBE_DMATXCTL_TE;
+               IXGBE_WRITE_REG(&adapter->hw, IXGBE_DMATXCTL, reg_data);
+       }
+       reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_TXDCTL(0));
+       reg_data |= IXGBE_TXDCTL_ENABLE;
+       IXGBE_WRITE_REG(&adapter->hw, IXGBE_TXDCTL(0), reg_data);
+
+       for (i = 0; i < tx_ring->count; i++) {
+               struct ixgbe_legacy_tx_desc *desc = IXGBE_TX_DESC(*tx_ring, i);
+               struct sk_buff *skb;
+               unsigned int size = 1024;
+
+               skb = alloc_skb(size, GFP_KERNEL);
+               if (!skb) {
+                       ret_val = 3;
+                       goto err_nomem;
+               }
+               skb_put(skb, size);
+               tx_ring->tx_buffer_info[i].skb = skb;
+               tx_ring->tx_buffer_info[i].length = skb->len;
+               tx_ring->tx_buffer_info[i].dma =
+                       pci_map_single(pdev, skb->data, skb->len,
+                                       PCI_DMA_TODEVICE);
+               desc->buffer_addr = cpu_to_le64(tx_ring->tx_buffer_info[i].dma);
+               desc->lower.data = cpu_to_le32(skb->len);
+               desc->lower.data |= cpu_to_le32(IXGBE_TXD_CMD_EOP |
+                                               IXGBE_TXD_CMD_IFCS |
+                                               IXGBE_TXD_CMD_RS);
+               desc->upper.data = 0;
+       }
+
+       /* Setup Rx Descriptor ring and Rx buffers */
+
+       if (!rx_ring->count)
+               rx_ring->count = IXGBE_DEFAULT_RXD;
+
+       rx_ring->rx_buffer_info = kcalloc(rx_ring->count,
+                                         sizeof(struct ixgbe_rx_buffer),
+                                         GFP_KERNEL);
+       if (!(rx_ring->rx_buffer_info)) {
+               ret_val = 4;
+               goto err_nomem;
+       }
+
+       rx_ring->size = rx_ring->count * sizeof(struct ixgbe_legacy_rx_desc);
+       rx_ring->size = ALIGN(rx_ring->size, 4096);
+       if (!(rx_ring->desc = pci_alloc_consistent(pdev, rx_ring->size,
+                                                  &rx_ring->dma))) {
+               ret_val = 5;
+               goto err_nomem;
+       }
+       rx_ring->next_to_use = rx_ring->next_to_clean = 0;
+
+       rctl = IXGBE_READ_REG(&adapter->hw, IXGBE_RXCTRL);
+       IXGBE_WRITE_REG(&adapter->hw, IXGBE_RXCTRL, rctl & ~IXGBE_RXCTRL_RXEN);
+       IXGBE_WRITE_REG(&adapter->hw, IXGBE_RDBAL(0),
+                       ((u64)rx_ring->dma & 0xFFFFFFFF));
+       IXGBE_WRITE_REG(&adapter->hw, IXGBE_RDBAH(0),
+                       ((u64) rx_ring->dma >> 32));
+       IXGBE_WRITE_REG(&adapter->hw, IXGBE_RDLEN(0), rx_ring->size);
+       IXGBE_WRITE_REG(&adapter->hw, IXGBE_RDH(0), 0);
+       IXGBE_WRITE_REG(&adapter->hw, IXGBE_RDT(0), 0);
+
+       reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_FCTRL);
+       reg_data |= IXGBE_FCTRL_BAM | IXGBE_FCTRL_SBP | IXGBE_FCTRL_MPE;
+       IXGBE_WRITE_REG(&adapter->hw, IXGBE_FCTRL, reg_data);
+
+       reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_HLREG0);
+       reg_data &= ~IXGBE_HLREG0_LPBK;
+       IXGBE_WRITE_REG(&adapter->hw, IXGBE_HLREG0, reg_data);
+
+       reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_RDRXCTL);
+#define IXGBE_RDRXCTL_RDMTS_MASK    0x00000003 /* Receive Descriptor Minimum
+                                                  Threshold Size mask */
+       reg_data &= ~IXGBE_RDRXCTL_RDMTS_MASK;
+       IXGBE_WRITE_REG(&adapter->hw, IXGBE_RDRXCTL, reg_data);
+
+       reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_MCSTCTRL);
+#define IXGBE_MCSTCTRL_MO_MASK      0x00000003 /* Multicast Offset mask */
+       reg_data &= ~IXGBE_MCSTCTRL_MO_MASK;
+       reg_data |= adapter->hw.mac.mc_filter_type;
+       IXGBE_WRITE_REG(&adapter->hw, IXGBE_MCSTCTRL, reg_data);
+
+       reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_RXDCTL(0));
+       reg_data |= IXGBE_RXDCTL_ENABLE;
+       IXGBE_WRITE_REG(&adapter->hw, IXGBE_RXDCTL(0), reg_data);
+       if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
+               int j = adapter->rx_ring[0].reg_idx;
+               u32 k;
+               for (k = 0; k < 10; k++) {
+                       if (IXGBE_READ_REG(&adapter->hw,
+                                          IXGBE_RXDCTL(j)) & IXGBE_RXDCTL_ENABLE)
+                               break;
+                       else
+                               msleep(1);
+               }
+       }
+
+       rctl |= IXGBE_RXCTRL_RXEN | IXGBE_RXCTRL_DMBYPS;
+       IXGBE_WRITE_REG(&adapter->hw, IXGBE_RXCTRL, rctl);
+
+       for (i = 0; i < rx_ring->count; i++) {
+               struct ixgbe_legacy_rx_desc *rx_desc =
+                                       IXGBE_RX_DESC(*rx_ring, i);
+               struct sk_buff *skb;
+
+               skb = alloc_skb(IXGBE_RXBUFFER_2048 + NET_IP_ALIGN, GFP_KERNEL);
+               if (!skb) {
+                       ret_val = 6;
+                       goto err_nomem;
+               }
+               skb_reserve(skb, NET_IP_ALIGN);
+               rx_ring->rx_buffer_info[i].skb = skb;
+               rx_ring->rx_buffer_info[i].dma =
+                       pci_map_single(pdev, skb->data, IXGBE_RXBUFFER_2048,
+                                      PCI_DMA_FROMDEVICE);
+               rx_desc->buffer_addr =
+                               cpu_to_le64(rx_ring->rx_buffer_info[i].dma);
+               memset(skb->data, 0x00, skb->len);
+       }
+
+       return 0;
+
+err_nomem:
+       ixgbe_free_desc_rings(adapter);
+       return ret_val;
+}
+
+static int ixgbe_setup_loopback_test(struct ixgbe_adapter *adapter)
+{
+       struct ixgbe_hw *hw = &adapter->hw;
+       u32 reg_data;
+
+       /* right now we only support MAC loopback in the driver */
+
+       /* Setup MAC loopback */
+       reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_HLREG0);
+       reg_data |= IXGBE_HLREG0_LPBK;
+       IXGBE_WRITE_REG(&adapter->hw, IXGBE_HLREG0, reg_data);
+
+       reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_AUTOC);
+       reg_data &= ~IXGBE_AUTOC_LMS_MASK;
+       reg_data |= IXGBE_AUTOC_LMS_10G_LINK_NO_AN | IXGBE_AUTOC_FLU;
+       IXGBE_WRITE_REG(&adapter->hw, IXGBE_AUTOC, reg_data);
+
+       /* Disable Atlas Tx lanes; re-enabled in reset path */
+       if (hw->mac.type == ixgbe_mac_82598EB) {
+               u8 atlas;
+
+               hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_LPBK, &atlas);
+               atlas |= IXGBE_ATLAS_PDN_TX_REG_EN;
+               hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_LPBK, atlas);
+
+               hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_10G, &atlas);
+               atlas |= IXGBE_ATLAS_PDN_TX_10G_QL_ALL;
+               hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_10G, atlas);
+
+               hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_1G, &atlas);
+               atlas |= IXGBE_ATLAS_PDN_TX_1G_QL_ALL;
+               hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_1G, atlas);
+
+               hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_AN, &atlas);
+               atlas |= IXGBE_ATLAS_PDN_TX_AN_QL_ALL;
+               hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_AN, atlas);
+       }
+
+       return 0;
+}
+
+static void ixgbe_loopback_cleanup(struct ixgbe_adapter *adapter)
+{
+       u32 reg_data;
+
+       reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_HLREG0);
+       reg_data &= ~IXGBE_HLREG0_LPBK;
+       IXGBE_WRITE_REG(&adapter->hw, IXGBE_HLREG0, reg_data);
+}
+
+static void ixgbe_create_lbtest_frame(struct sk_buff *skb,
+                                      unsigned int frame_size)
+{
+       memset(skb->data, 0xFF, frame_size);
+       frame_size &= ~1;
+       memset(&skb->data[frame_size / 2], 0xAA, frame_size / 2 - 1);
+       memset(&skb->data[frame_size / 2 + 10], 0xBE, 1);
+       memset(&skb->data[frame_size / 2 + 12], 0xAF, 1);
+}
+
+static int ixgbe_check_lbtest_frame(struct sk_buff *skb,
+                                    unsigned int frame_size)
+{
+       frame_size &= ~1;
+       if (*(skb->data + 3) == 0xFF) {
+               if ((*(skb->data + frame_size / 2 + 10) == 0xBE) &&
+                   (*(skb->data + frame_size / 2 + 12) == 0xAF)) {
+                       return 0;
+               }
+       }
+       return 13;
+}
+
+static int ixgbe_run_loopback_test(struct ixgbe_adapter *adapter)
+{
+       struct ixgbe_ring *tx_ring = &adapter->test_tx_ring;
+       struct ixgbe_ring *rx_ring = &adapter->test_rx_ring;
+       struct pci_dev *pdev = adapter->pdev;
+       int i, j, k, l, lc, good_cnt, ret_val = 0;
+       unsigned long time;
+
+       IXGBE_WRITE_REG(&adapter->hw, IXGBE_RDT(0), rx_ring->count - 1);
+
+       /*
+        * Calculate the loop count based on the largest descriptor ring
+        * The idea is to wrap the largest ring a number of times using 64
+        * send/receive pairs during each loop
+        */
+
+       if (rx_ring->count <= tx_ring->count)
+               lc = ((tx_ring->count / 64) * 2) + 1;
+       else
+               lc = ((rx_ring->count / 64) * 2) + 1;
+
+       k = l = 0;
+       for (j = 0; j <= lc; j++) {
+               for (i = 0; i < 64; i++) {
+                       ixgbe_create_lbtest_frame(
+                                       tx_ring->tx_buffer_info[k].skb,
+                                       1024);
+                       pci_dma_sync_single_for_device(pdev,
+                               tx_ring->tx_buffer_info[k].dma,
+                               tx_ring->tx_buffer_info[k].length,
+                               PCI_DMA_TODEVICE);
+                       if (unlikely(++k == tx_ring->count))
+                               k = 0;
+               }
+               IXGBE_WRITE_REG(&adapter->hw, IXGBE_TDT(0), k);
+               msleep(200);
+               /* set the start time for the receive */
+               time = jiffies;
+               good_cnt = 0;
+               do {
+                       /* receive the sent packets */
+                       pci_dma_sync_single_for_cpu(pdev,
+                                       rx_ring->rx_buffer_info[l].dma,
+                                       IXGBE_RXBUFFER_2048,
+                                       PCI_DMA_FROMDEVICE);
+                       ret_val = ixgbe_check_lbtest_frame(
+                                       rx_ring->rx_buffer_info[l].skb, 1024);
+                       if (!ret_val)
+                               good_cnt++;
+                       if (++l == rx_ring->count)
+                               l = 0;
+                       /*
+                        * time + 20 msecs (200 msecs on 2.4) is more than
+                        * enough time to complete the receives, if it's
+                        * exceeded, break and error off
+                        */
+               } while (good_cnt < 64 && jiffies < (time + 20));
+               if (good_cnt != 64) {
+                       /* ret_val is the same as mis-compare */
+                       ret_val = 13;
+                       break;
+               }
+               if (jiffies >= (time + 20)) {
+                       /* Error code for time out error */
+                       ret_val = 14;
+                       break;
+               }
+       }
+
+       return ret_val;
+}
+
+static int ixgbe_loopback_test(struct ixgbe_adapter *adapter, u64 *data)
+{
+       *data = ixgbe_setup_desc_rings(adapter);
+       if (*data)
+               goto out;
+       *data = ixgbe_setup_loopback_test(adapter);
+       if (*data)
+               goto err_loopback;
+       *data = ixgbe_run_loopback_test(adapter);
+       ixgbe_loopback_cleanup(adapter);
+
+err_loopback:
+       ixgbe_free_desc_rings(adapter);
+out:
+       return *data;
+}
+
+static void ixgbe_diag_test(struct net_device *netdev,
+                            struct ethtool_test *eth_test, u64 *data)
+{
+       struct ixgbe_adapter *adapter = netdev_priv(netdev);
+       bool if_running = netif_running(netdev);
+
+       set_bit(__IXGBE_TESTING, &adapter->state);
+       if (eth_test->flags == ETH_TEST_FL_OFFLINE) {
+               /* Offline tests */
+
+               DPRINTK(HW, INFO, "offline testing starting\n");
+
+               /* Link test performed before hardware reset so autoneg doesn't
+                * interfere with test result */
+               if (ixgbe_link_test(adapter, &data[4]))
+                       eth_test->flags |= ETH_TEST_FL_FAILED;
+
+               if (if_running)
+                       /* indicate we're in test mode */
+                       dev_close(netdev);
+               else
+                       ixgbe_reset(adapter);
+
+               DPRINTK(HW, INFO, "register testing starting\n");
+               if (ixgbe_reg_test(adapter, &data[0]))
+                       eth_test->flags |= ETH_TEST_FL_FAILED;
+
+               ixgbe_reset(adapter);
+               DPRINTK(HW, INFO, "eeprom testing starting\n");
+               if (ixgbe_eeprom_test(adapter, &data[1]))
+                       eth_test->flags |= ETH_TEST_FL_FAILED;
+
+               ixgbe_reset(adapter);
+               DPRINTK(HW, INFO, "interrupt testing starting\n");
+               if (ixgbe_intr_test(adapter, &data[2]))
+                       eth_test->flags |= ETH_TEST_FL_FAILED;
+
+               ixgbe_reset(adapter);
+               DPRINTK(HW, INFO, "loopback testing starting\n");
+               if (ixgbe_loopback_test(adapter, &data[3]))
+                       eth_test->flags |= ETH_TEST_FL_FAILED;
+
+               ixgbe_reset(adapter);
+
+               clear_bit(__IXGBE_TESTING, &adapter->state);
+               if (if_running)
+                       dev_open(netdev);
+       } else {
+               DPRINTK(HW, INFO, "online testing starting\n");
+               /* Online tests */
+               if (ixgbe_link_test(adapter, &data[4]))
+                       eth_test->flags |= ETH_TEST_FL_FAILED;
+
+               /* Online tests aren't run; pass by default */
+               data[0] = 0;
+               data[1] = 0;
+               data[2] = 0;
+               data[3] = 0;
+
+               clear_bit(__IXGBE_TESTING, &adapter->state);
+       }
+       msleep_interruptible(4 * 1000);
+}
 
 static int ixgbe_wol_exclusion(struct ixgbe_adapter *adapter,
                                struct ethtool_wolinfo *wol)
@@ -1106,20 +1980,40 @@ static int ixgbe_set_coalesce(struct net_device *netdev,
        }
 
        for (i = 0; i < adapter->num_msix_vectors - NON_Q_VECTORS; i++) {
-               struct ixgbe_q_vector *q_vector = &adapter->q_vector[i];
+               struct ixgbe_q_vector *q_vector = adapter->q_vector[i];
                if (q_vector->txr_count && !q_vector->rxr_count)
                        /* tx vector gets half the rate */
                        q_vector->eitr = (adapter->eitr_param >> 1);
                else
                        /* rx only or mixed */
                        q_vector->eitr = adapter->eitr_param;
-               ixgbe_write_eitr(adapter, i,
-                                EITR_INTS_PER_SEC_TO_REG(q_vector->eitr));
+               ixgbe_write_eitr(q_vector);
        }
 
        return 0;
 }
 
+static int ixgbe_set_flags(struct net_device *netdev, u32 data)
+{
+       struct ixgbe_adapter *adapter = netdev_priv(netdev);
+
+       ethtool_op_set_flags(netdev, data);
+
+       if (!(adapter->flags & IXGBE_FLAG2_RSC_CAPABLE))
+               return 0;
+
+       /* if state changes we need to update adapter->flags and reset */
+       if ((!!(data & ETH_FLAG_LRO)) != 
+           (!!(adapter->flags & IXGBE_FLAG2_RSC_ENABLED))) {
+               adapter->flags ^= IXGBE_FLAG2_RSC_ENABLED;
+               if (netif_running(netdev))
+                       ixgbe_reinit_locked(adapter);
+               else
+                       ixgbe_reset(adapter);
+       }
+       return 0;
+
+}
 
 static const struct ethtool_ops ixgbe_ethtool_ops = {
        .get_settings           = ixgbe_get_settings,
@@ -1147,6 +2041,7 @@ static const struct ethtool_ops ixgbe_ethtool_ops = {
        .set_msglevel           = ixgbe_set_msglevel,
        .get_tso                = ethtool_op_get_tso,
        .set_tso                = ixgbe_set_tso,
+       .self_test              = ixgbe_diag_test,
        .get_strings            = ixgbe_get_strings,
        .phys_id                = ixgbe_phys_id,
        .get_sset_count         = ixgbe_get_sset_count,
@@ -1154,7 +2049,7 @@ static const struct ethtool_ops ixgbe_ethtool_ops = {
        .get_coalesce           = ixgbe_get_coalesce,
        .set_coalesce           = ixgbe_set_coalesce,
        .get_flags              = ethtool_op_get_flags,
-       .set_flags              = ethtool_op_set_flags,
+       .set_flags              = ixgbe_set_flags,
 };
 
 void ixgbe_set_ethtool_ops(struct net_device *netdev)
diff --git a/drivers/net/ixgbe/ixgbe_fcoe.c b/drivers/net/ixgbe/ixgbe_fcoe.c
new file mode 100644 (file)
index 0000000..3c3bf1f
--- /dev/null
@@ -0,0 +1,556 @@
+/*******************************************************************************
+
+  Intel 10 Gigabit PCI Express Linux driver
+  Copyright(c) 1999 - 2009 Intel Corporation.
+
+  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.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+  Contact Information:
+  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+
+*******************************************************************************/
+
+
+#include "ixgbe.h"
+#include <linux/if_ether.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_device.h>
+#include <scsi/fc/fc_fs.h>
+#include <scsi/fc/fc_fcoe.h>
+#include <scsi/libfc.h>
+#include <scsi/libfcoe.h>
+
+/**
+ * ixgbe_rx_is_fcoe - check the rx desc for incoming pkt type
+ * @rx_desc: advanced rx descriptor
+ *
+ * Returns : true if it is FCoE pkt
+ */
+static inline bool ixgbe_rx_is_fcoe(union ixgbe_adv_rx_desc *rx_desc)
+{
+       u16 p;
+
+       p = le16_to_cpu(rx_desc->wb.lower.lo_dword.hs_rss.pkt_info);
+       if (p & IXGBE_RXDADV_PKTTYPE_ETQF) {
+               p &= IXGBE_RXDADV_PKTTYPE_ETQF_MASK;
+               p >>= IXGBE_RXDADV_PKTTYPE_ETQF_SHIFT;
+               return p == IXGBE_ETQF_FILTER_FCOE;
+       }
+       return false;
+}
+
+/**
+ * ixgbe_fcoe_clear_ddp - clear the given ddp context
+ * @ddp - ptr to the ixgbe_fcoe_ddp
+ *
+ * Returns : none
+ *
+ */
+static inline void ixgbe_fcoe_clear_ddp(struct ixgbe_fcoe_ddp *ddp)
+{
+       ddp->len = 0;
+       ddp->err = 0;
+       ddp->udl = NULL;
+       ddp->udp = 0UL;
+       ddp->sgl = NULL;
+       ddp->sgc = 0;
+}
+
+/**
+ * ixgbe_fcoe_ddp_put - free the ddp context for a given xid
+ * @netdev: the corresponding net_device
+ * @xid: the xid that corresponding ddp will be freed
+ *
+ * This is the implementation of net_device_ops.ndo_fcoe_ddp_done
+ * and it is expected to be called by ULD, i.e., FCP layer of libfc
+ * to release the corresponding ddp context when the I/O is done.
+ *
+ * Returns : data length already ddp-ed in bytes
+ */
+int ixgbe_fcoe_ddp_put(struct net_device *netdev, u16 xid)
+{
+       int len = 0;
+       struct ixgbe_fcoe *fcoe;
+       struct ixgbe_adapter *adapter;
+       struct ixgbe_fcoe_ddp *ddp;
+
+       if (!netdev)
+               goto out_ddp_put;
+
+       if (xid >= IXGBE_FCOE_DDP_MAX)
+               goto out_ddp_put;
+
+       adapter = netdev_priv(netdev);
+       fcoe = &adapter->fcoe;
+       ddp = &fcoe->ddp[xid];
+       if (!ddp->udl)
+               goto out_ddp_put;
+
+       len = ddp->len;
+       /* if there an error, force to invalidate ddp context */
+       if (ddp->err) {
+               spin_lock_bh(&fcoe->lock);
+               IXGBE_WRITE_REG(&adapter->hw, IXGBE_FCFLT, 0);
+               IXGBE_WRITE_REG(&adapter->hw, IXGBE_FCFLTRW,
+                               (xid | IXGBE_FCFLTRW_WE));
+               IXGBE_WRITE_REG(&adapter->hw, IXGBE_FCBUFF, 0);
+               IXGBE_WRITE_REG(&adapter->hw, IXGBE_FCDMARW,
+                               (xid | IXGBE_FCDMARW_WE));
+               spin_unlock_bh(&fcoe->lock);
+       }
+       if (ddp->sgl)
+               pci_unmap_sg(adapter->pdev, ddp->sgl, ddp->sgc,
+                            DMA_FROM_DEVICE);
+       pci_pool_free(fcoe->pool, ddp->udl, ddp->udp);
+       ixgbe_fcoe_clear_ddp(ddp);
+
+out_ddp_put:
+       return len;
+}
+
+/**
+ * ixgbe_fcoe_ddp_get - called to set up ddp context
+ * @netdev: the corresponding net_device
+ * @xid: the exchange id requesting ddp
+ * @sgl: the scatter-gather list for this request
+ * @sgc: the number of scatter-gather items
+ *
+ * This is the implementation of net_device_ops.ndo_fcoe_ddp_setup
+ * and is expected to be called from ULD, e.g., FCP layer of libfc
+ * to set up ddp for the corresponding xid of the given sglist for
+ * the corresponding I/O.
+ *
+ * Returns : 1 for success and 0 for no ddp
+ */
+int ixgbe_fcoe_ddp_get(struct net_device *netdev, u16 xid,
+                      struct scatterlist *sgl, unsigned int sgc)
+{
+       struct ixgbe_adapter *adapter;
+       struct ixgbe_hw *hw;
+       struct ixgbe_fcoe *fcoe;
+       struct ixgbe_fcoe_ddp *ddp;
+       struct scatterlist *sg;
+       unsigned int i, j, dmacount;
+       unsigned int len;
+       static const unsigned int bufflen = 4096;
+       unsigned int firstoff = 0;
+       unsigned int lastsize;
+       unsigned int thisoff = 0;
+       unsigned int thislen = 0;
+       u32 fcbuff, fcdmarw, fcfltrw;
+       dma_addr_t addr;
+
+       if (!netdev || !sgl)
+               return 0;
+
+       adapter = netdev_priv(netdev);
+       if (xid >= IXGBE_FCOE_DDP_MAX) {
+               DPRINTK(DRV, WARNING, "xid=0x%x out-of-range\n", xid);
+               return 0;
+       }
+
+       fcoe = &adapter->fcoe;
+       if (!fcoe->pool) {
+               DPRINTK(DRV, WARNING, "xid=0x%x no ddp pool for fcoe\n", xid);
+               return 0;
+       }
+
+       ddp = &fcoe->ddp[xid];
+       if (ddp->sgl) {
+               DPRINTK(DRV, ERR, "xid 0x%x w/ non-null sgl=%p nents=%d\n",
+                       xid, ddp->sgl, ddp->sgc);
+               return 0;
+       }
+       ixgbe_fcoe_clear_ddp(ddp);
+
+       /* setup dma from scsi command sgl */
+       dmacount = pci_map_sg(adapter->pdev, sgl, sgc, DMA_FROM_DEVICE);
+       if (dmacount == 0) {
+               DPRINTK(DRV, ERR, "xid 0x%x DMA map error\n", xid);
+               return 0;
+       }
+
+       /* alloc the udl from our ddp pool */
+       ddp->udl = pci_pool_alloc(fcoe->pool, GFP_KERNEL, &ddp->udp);
+       if (!ddp->udl) {
+               DPRINTK(DRV, ERR, "failed allocated ddp context\n");
+               goto out_noddp_unmap;
+       }
+       ddp->sgl = sgl;
+       ddp->sgc = sgc;
+
+       j = 0;
+       for_each_sg(sgl, sg, dmacount, i) {
+               addr = sg_dma_address(sg);
+               len = sg_dma_len(sg);
+               while (len) {
+                       /* get the offset of length of current buffer */
+                       thisoff = addr & ((dma_addr_t)bufflen - 1);
+                       thislen = min((bufflen - thisoff), len);
+                       /*
+                        * all but the 1st buffer (j == 0)
+                        * must be aligned on bufflen
+                        */
+                       if ((j != 0) && (thisoff))
+                               goto out_noddp_free;
+                       /*
+                        * all but the last buffer
+                        * ((i == (dmacount - 1)) && (thislen == len))
+                        * must end at bufflen
+                        */
+                       if (((i != (dmacount - 1)) || (thislen != len))
+                           && ((thislen + thisoff) != bufflen))
+                               goto out_noddp_free;
+
+                       ddp->udl[j] = (u64)(addr - thisoff);
+                       /* only the first buffer may have none-zero offset */
+                       if (j == 0)
+                               firstoff = thisoff;
+                       len -= thislen;
+                       addr += thislen;
+                       j++;
+                       /* max number of buffers allowed in one DDP context */
+                       if (j > IXGBE_BUFFCNT_MAX) {
+                               DPRINTK(DRV, ERR, "xid=%x:%d,%d,%d:addr=%llx "
+                                       "not enough descriptors\n",
+                                       xid, i, j, dmacount, (u64)addr);
+                               goto out_noddp_free;
+                       }
+               }
+       }
+       /* only the last buffer may have non-full bufflen */
+       lastsize = thisoff + thislen;
+
+       fcbuff = (IXGBE_FCBUFF_4KB << IXGBE_FCBUFF_BUFFSIZE_SHIFT);
+       fcbuff |= (j << IXGBE_FCBUFF_BUFFCNT_SHIFT);
+       fcbuff |= (firstoff << IXGBE_FCBUFF_OFFSET_SHIFT);
+       fcbuff |= (IXGBE_FCBUFF_VALID);
+
+       fcdmarw = xid;
+       fcdmarw |= IXGBE_FCDMARW_WE;
+       fcdmarw |= (lastsize << IXGBE_FCDMARW_LASTSIZE_SHIFT);
+
+       fcfltrw = xid;
+       fcfltrw |= IXGBE_FCFLTRW_WE;
+
+       /* program DMA context */
+       hw = &adapter->hw;
+       spin_lock_bh(&fcoe->lock);
+       IXGBE_WRITE_REG(hw, IXGBE_FCPTRL, ddp->udp & DMA_32BIT_MASK);
+       IXGBE_WRITE_REG(hw, IXGBE_FCPTRH, (u64)ddp->udp >> 32);
+       IXGBE_WRITE_REG(hw, IXGBE_FCBUFF, fcbuff);
+       IXGBE_WRITE_REG(hw, IXGBE_FCDMARW, fcdmarw);
+       /* program filter context */
+       IXGBE_WRITE_REG(hw, IXGBE_FCPARAM, 0);
+       IXGBE_WRITE_REG(hw, IXGBE_FCFLT, IXGBE_FCFLT_VALID);
+       IXGBE_WRITE_REG(hw, IXGBE_FCFLTRW, fcfltrw);
+       spin_unlock_bh(&fcoe->lock);
+
+       return 1;
+
+out_noddp_free:
+       pci_pool_free(fcoe->pool, ddp->udl, ddp->udp);
+       ixgbe_fcoe_clear_ddp(ddp);
+
+out_noddp_unmap:
+       pci_unmap_sg(adapter->pdev, sgl, sgc, DMA_FROM_DEVICE);
+       return 0;
+}
+
+/**
+ * ixgbe_fcoe_ddp - check ddp status and mark it done
+ * @adapter: ixgbe adapter
+ * @rx_desc: advanced rx descriptor
+ * @skb: the skb holding the received data
+ *
+ * This checks ddp status.
+ *
+ * Returns : < 0 indicates an error or not a FCiE ddp, 0 indicates
+ * not passing the skb to ULD, > 0 indicates is the length of data
+ * being ddped.
+ */
+int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter,
+                  union ixgbe_adv_rx_desc *rx_desc,
+                  struct sk_buff *skb)
+{
+       u16 xid;
+       u32 sterr, fceofe, fcerr, fcstat;
+       int rc = -EINVAL;
+       struct ixgbe_fcoe *fcoe;
+       struct ixgbe_fcoe_ddp *ddp;
+       struct fc_frame_header *fh;
+
+       if (!ixgbe_rx_is_fcoe(rx_desc))
+               goto ddp_out;
+
+       skb->ip_summed = CHECKSUM_UNNECESSARY;
+       sterr = le32_to_cpu(rx_desc->wb.upper.status_error);
+       fcerr = (sterr & IXGBE_RXDADV_ERR_FCERR);
+       fceofe = (sterr & IXGBE_RXDADV_ERR_FCEOFE);
+       if (fcerr == IXGBE_FCERR_BADCRC)
+               skb->ip_summed = CHECKSUM_NONE;
+
+       skb_reset_network_header(skb);
+       skb_set_transport_header(skb, skb_network_offset(skb) +
+                                sizeof(struct fcoe_hdr));
+       fh = (struct fc_frame_header *)skb_transport_header(skb);
+       xid =  be16_to_cpu(fh->fh_ox_id);
+       if (xid >= IXGBE_FCOE_DDP_MAX)
+               goto ddp_out;
+
+       fcoe = &adapter->fcoe;
+       ddp = &fcoe->ddp[xid];
+       if (!ddp->udl)
+               goto ddp_out;
+
+       ddp->err = (fcerr | fceofe);
+       if (ddp->err)
+               goto ddp_out;
+
+       fcstat = (sterr & IXGBE_RXDADV_STAT_FCSTAT);
+       if (fcstat) {
+               /* update length of DDPed data */
+               ddp->len = le32_to_cpu(rx_desc->wb.lower.hi_dword.rss);
+               /* unmap the sg list when FCP_RSP is received */
+               if (fcstat == IXGBE_RXDADV_STAT_FCSTAT_FCPRSP) {
+                       pci_unmap_sg(adapter->pdev, ddp->sgl,
+                                    ddp->sgc, DMA_FROM_DEVICE);
+                       ddp->sgl = NULL;
+                       ddp->sgc = 0;
+               }
+               /* return 0 to bypass going to ULD for DDPed data */
+               if (fcstat == IXGBE_RXDADV_STAT_FCSTAT_DDP)
+                       rc = 0;
+               else
+                       rc = ddp->len;
+       }
+
+ddp_out:
+       return rc;
+}
+
+/**
+ * ixgbe_fso - ixgbe FCoE Sequence Offload (FSO)
+ * @adapter: ixgbe adapter
+ * @tx_ring: tx desc ring
+ * @skb: associated skb
+ * @tx_flags: tx flags
+ * @hdr_len: hdr_len to be returned
+ *
+ * This sets up large send offload for FCoE
+ *
+ * Returns : 0 indicates no FSO, > 0 for FSO, < 0 for error
+ */
+int ixgbe_fso(struct ixgbe_adapter *adapter,
+              struct ixgbe_ring *tx_ring, struct sk_buff *skb,
+              u32 tx_flags, u8 *hdr_len)
+{
+       u8 sof, eof;
+       u32 vlan_macip_lens;
+       u32 fcoe_sof_eof;
+       u32 type_tucmd;
+       u32 mss_l4len_idx;
+       int mss = 0;
+       unsigned int i;
+       struct ixgbe_tx_buffer *tx_buffer_info;
+       struct ixgbe_adv_tx_context_desc *context_desc;
+       struct fc_frame_header *fh;
+
+       if (skb_is_gso(skb) && (skb_shinfo(skb)->gso_type != SKB_GSO_FCOE)) {
+               DPRINTK(DRV, ERR, "Wrong gso type %d:expecting SKB_GSO_FCOE\n",
+                       skb_shinfo(skb)->gso_type);
+               return -EINVAL;
+       }
+
+       /* resets the header to point fcoe/fc */
+       skb_set_network_header(skb, skb->mac_len);
+       skb_set_transport_header(skb, skb->mac_len +
+                                sizeof(struct fcoe_hdr));
+
+       /* sets up SOF and ORIS */
+       fcoe_sof_eof = 0;
+       sof = ((struct fcoe_hdr *)skb_network_header(skb))->fcoe_sof;
+       switch (sof) {
+       case FC_SOF_I2:
+               fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_ORIS;
+               break;
+       case FC_SOF_I3:
+               fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_SOF;
+               fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_ORIS;
+               break;
+       case FC_SOF_N2:
+               break;
+       case FC_SOF_N3:
+               fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_SOF;
+               break;
+       default:
+               DPRINTK(DRV, WARNING, "unknown sof = 0x%x\n", sof);
+               return -EINVAL;
+       }
+
+       /* the first byte of the last dword is EOF */
+       skb_copy_bits(skb, skb->len - 4, &eof, 1);
+       /* sets up EOF and ORIE */
+       switch (eof) {
+       case FC_EOF_N:
+               fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_EOF_N;
+               break;
+       case FC_EOF_T:
+               /* lso needs ORIE */
+               if (skb_is_gso(skb)) {
+                       fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_EOF_N;
+                       fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_ORIE;
+               } else {
+                       fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_EOF_T;
+               }
+               break;
+       case FC_EOF_NI:
+               fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_EOF_NI;
+               break;
+       case FC_EOF_A:
+               fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_EOF_A;
+               break;
+       default:
+               DPRINTK(DRV, WARNING, "unknown eof = 0x%x\n", eof);
+               return -EINVAL;
+       }
+
+       /* sets up PARINC indicating data offset */
+       fh = (struct fc_frame_header *)skb_transport_header(skb);
+       if (fh->fh_f_ctl[2] & FC_FC_REL_OFF)
+               fcoe_sof_eof |= IXGBE_ADVTXD_FCOEF_PARINC;
+
+       /* hdr_len includes fc_hdr if FCoE lso is enabled */
+       *hdr_len = sizeof(struct fcoe_crc_eof);
+       if (skb_is_gso(skb))
+               *hdr_len += (skb_transport_offset(skb) +
+                            sizeof(struct fc_frame_header));
+       /* vlan_macip_lens: HEADLEN, MACLEN, VLAN tag */
+       vlan_macip_lens = (skb_transport_offset(skb) +
+                         sizeof(struct fc_frame_header));
+       vlan_macip_lens |= ((skb_transport_offset(skb) - 4)
+                          << IXGBE_ADVTXD_MACLEN_SHIFT);
+       vlan_macip_lens |= (tx_flags & IXGBE_TX_FLAGS_VLAN_MASK);
+
+       /* type_tycmd and mss: set TUCMD.FCoE to enable offload */
+       type_tucmd = IXGBE_TXD_CMD_DEXT | IXGBE_ADVTXD_DTYP_CTXT |
+                    IXGBE_ADVTXT_TUCMD_FCOE;
+       if (skb_is_gso(skb))
+               mss = skb_shinfo(skb)->gso_size;
+       /* mss_l4len_id: use 1 for FSO as TSO, no need for L4LEN */
+       mss_l4len_idx = (mss << IXGBE_ADVTXD_MSS_SHIFT) |
+                       (1 << IXGBE_ADVTXD_IDX_SHIFT);
+
+       /* write context desc */
+       i = tx_ring->next_to_use;
+       context_desc = IXGBE_TX_CTXTDESC_ADV(*tx_ring, i);
+       context_desc->vlan_macip_lens   = cpu_to_le32(vlan_macip_lens);
+       context_desc->seqnum_seed       = cpu_to_le32(fcoe_sof_eof);
+       context_desc->type_tucmd_mlhl   = cpu_to_le32(type_tucmd);
+       context_desc->mss_l4len_idx     = cpu_to_le32(mss_l4len_idx);
+
+       tx_buffer_info = &tx_ring->tx_buffer_info[i];
+       tx_buffer_info->time_stamp = jiffies;
+       tx_buffer_info->next_to_watch = i;
+
+       i++;
+       if (i == tx_ring->count)
+               i = 0;
+       tx_ring->next_to_use = i;
+
+       return skb_is_gso(skb);
+}
+
+/**
+ * ixgbe_configure_fcoe - configures registers for fcoe at start
+ * @adapter: ptr to ixgbe adapter
+ *
+ * This sets up FCoE related registers
+ *
+ * Returns : none
+ */
+void ixgbe_configure_fcoe(struct ixgbe_adapter *adapter)
+{
+       int i, fcoe_q, fcoe_i;
+       struct ixgbe_hw *hw = &adapter->hw;
+       struct ixgbe_fcoe *fcoe = &adapter->fcoe;
+       struct ixgbe_ring_feature *f = &adapter->ring_feature[RING_F_FCOE];
+
+       /* create the pool for ddp if not created yet */
+       if (!fcoe->pool) {
+               /* allocate ddp pool */
+               fcoe->pool = pci_pool_create("ixgbe_fcoe_ddp",
+                                            adapter->pdev, IXGBE_FCPTR_MAX,
+                                            IXGBE_FCPTR_ALIGN, PAGE_SIZE);
+               if (!fcoe->pool)
+                       DPRINTK(DRV, ERR,
+                               "failed to allocated FCoE DDP pool\n");
+
+               spin_lock_init(&fcoe->lock);
+       }
+
+       /* Enable L2 eth type filter for FCoE */
+       IXGBE_WRITE_REG(hw, IXGBE_ETQF(IXGBE_ETQF_FILTER_FCOE),
+                       (ETH_P_FCOE | IXGBE_ETQF_FCOE | IXGBE_ETQF_FILTER_EN));
+       if (adapter->ring_feature[RING_F_FCOE].indices) {
+               /* Use multiple rx queues for FCoE by redirection table */
+               for (i = 0; i < IXGBE_FCRETA_SIZE; i++) {
+                       fcoe_i = f->mask + i % f->indices;
+                       fcoe_i &= IXGBE_FCRETA_ENTRY_MASK;
+                       fcoe_q = adapter->rx_ring[fcoe_i].reg_idx;
+                       IXGBE_WRITE_REG(hw, IXGBE_FCRETA(i), fcoe_q);
+               }
+               IXGBE_WRITE_REG(hw, IXGBE_FCRECTL, IXGBE_FCRECTL_ENA);
+               IXGBE_WRITE_REG(hw, IXGBE_ETQS(IXGBE_ETQF_FILTER_FCOE), 0);
+       } else  {
+               /* Use single rx queue for FCoE */
+               fcoe_i = f->mask;
+               fcoe_q = adapter->rx_ring[fcoe_i].reg_idx;
+               IXGBE_WRITE_REG(hw, IXGBE_FCRECTL, 0);
+               IXGBE_WRITE_REG(hw, IXGBE_ETQS(IXGBE_ETQF_FILTER_FCOE),
+                               IXGBE_ETQS_QUEUE_EN |
+                               (fcoe_q << IXGBE_ETQS_RX_QUEUE_SHIFT));
+       }
+
+       IXGBE_WRITE_REG(hw, IXGBE_FCRXCTRL,
+                       IXGBE_FCRXCTRL_FCOELLI |
+                       IXGBE_FCRXCTRL_FCCRCBO |
+                       (FC_FCOE_VER << IXGBE_FCRXCTRL_FCOEVER_SHIFT));
+}
+
+/**
+ * ixgbe_cleanup_fcoe - release all fcoe ddp context resources
+ * @adapter : ixgbe adapter
+ *
+ * Cleans up outstanding ddp context resources
+ *
+ * Returns : none
+ */
+void ixgbe_cleanup_fcoe(struct ixgbe_adapter *adapter)
+{
+       int i;
+       struct ixgbe_fcoe *fcoe = &adapter->fcoe;
+
+       /* release ddp resource */
+       if (fcoe->pool) {
+               for (i = 0; i < IXGBE_FCOE_DDP_MAX; i++)
+                       ixgbe_fcoe_ddp_put(adapter->netdev, i);
+               pci_pool_destroy(fcoe->pool);
+               fcoe->pool = NULL;
+       }
+}
diff --git a/drivers/net/ixgbe/ixgbe_fcoe.h b/drivers/net/ixgbe/ixgbe_fcoe.h
new file mode 100644 (file)
index 0000000..c5b5002
--- /dev/null
@@ -0,0 +1,67 @@
+/*******************************************************************************
+
+  Intel 10 Gigabit PCI Express Linux driver
+  Copyright(c) 1999 - 2009 Intel Corporation.
+
+  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.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+  Contact Information:
+  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
+  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+
+*******************************************************************************/
+
+#ifndef _IXGBE_FCOE_H
+#define _IXGBE_FCOE_H
+
+#include <scsi/fc/fc_fs.h>
+#include <scsi/fc/fc_fcoe.h>
+
+/* shift bits within STAT fo FCSTAT */
+#define IXGBE_RXDADV_FCSTAT_SHIFT      4
+
+/* ddp user buffer */
+#define IXGBE_BUFFCNT_MAX      256     /* 8 bits bufcnt */
+#define IXGBE_FCPTR_ALIGN      16
+#define IXGBE_FCPTR_MAX        (IXGBE_BUFFCNT_MAX * sizeof(dma_addr_t))
+#define IXGBE_FCBUFF_4KB       0x0
+#define IXGBE_FCBUFF_8KB       0x1
+#define IXGBE_FCBUFF_16KB      0x2
+#define IXGBE_FCBUFF_64KB      0x3
+#define IXGBE_FCBUFF_MAX       65536   /* 64KB max */
+#define IXGBE_FCBUFF_MIN       4096    /* 4KB min */
+#define IXGBE_FCOE_DDP_MAX     512     /* 9 bits xid */
+
+/* fcerr */
+#define IXGBE_FCERR_BADCRC       0x00100000
+
+struct ixgbe_fcoe_ddp {
+       int len;
+       u32 err;
+       unsigned int sgc;
+       struct scatterlist *sgl;
+       dma_addr_t udp;
+       u64 *udl;
+};
+
+struct ixgbe_fcoe {
+       spinlock_t lock;
+       struct pci_pool *pool;
+       struct ixgbe_fcoe_ddp ddp[IXGBE_FCOE_DDP_MAX];
+};
+
+#endif /* _IXGBE_FCOE_H */
index 07e778d3e5d22e51010b070abc8c9af816f37ac0..a551a96ce6765a1ed8eb84f1a466abaca938a479 100644 (file)
@@ -39,6 +39,7 @@
 #include <net/ip6_checksum.h>
 #include <linux/ethtool.h>
 #include <linux/if_vlan.h>
+#include <scsi/fc/fc_fcoe.h>
 
 #include "ixgbe.h"
 #include "ixgbe_common.h"
@@ -47,7 +48,7 @@ char ixgbe_driver_name[] = "ixgbe";
 static const char ixgbe_driver_string[] =
                               "Intel(R) 10 Gigabit PCI Express Network Driver";
 
-#define DRV_VERSION "2.0.8-k2"
+#define DRV_VERSION "2.0.34-k2"
 const char ixgbe_driver_version[] = DRV_VERSION;
 static char ixgbe_copyright[] = "Copyright (c) 1999-2009 Intel Corporation.";
 
@@ -89,6 +90,8 @@ static struct pci_device_id ixgbe_pci_tbl[] = {
         board_82598 },
        {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_KX4),
         board_82599 },
+       {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_XAUI_LOM),
+        board_82599 },
        {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_SFP),
         board_82599 },
 
@@ -183,6 +186,22 @@ static void ixgbe_set_ivar(struct ixgbe_adapter *adapter, s8 direction,
        }
 }
 
+static inline void ixgbe_irq_rearm_queues(struct ixgbe_adapter *adapter,
+                                          u64 qmask)
+{
+       u32 mask;
+
+       if (adapter->hw.mac.type == ixgbe_mac_82598EB) {
+               mask = (IXGBE_EIMS_RTX_QUEUE & qmask);
+               IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS, mask);
+       } else {
+               mask = (qmask & 0xFFFFFFFF);
+               IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS_EX(0), mask);
+               mask = (qmask >> 32);
+               IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS_EX(1), mask);
+       }
+}
+
 static void ixgbe_unmap_and_free_tx_resource(struct ixgbe_adapter *adapter,
                                              struct ixgbe_tx_buffer
                                              *tx_buffer_info)
@@ -245,14 +264,13 @@ static void ixgbe_tx_timeout(struct net_device *netdev);
 
 /**
  * ixgbe_clean_tx_irq - Reclaim resources after transmit completes
- * @adapter: board private structure
+ * @q_vector: structure containing interrupt and ring information
  * @tx_ring: tx ring to clean
- *
- * returns true if transmit work is done
  **/
-static bool ixgbe_clean_tx_irq(struct ixgbe_adapter *adapter,
+static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector,
                                struct ixgbe_ring *tx_ring)
 {
+       struct ixgbe_adapter *adapter = q_vector->adapter;
        struct net_device *netdev = adapter->netdev;
        union ixgbe_adv_tx_desc *tx_desc, *eop_desc;
        struct ixgbe_tx_buffer *tx_buffer_info;
@@ -275,12 +293,24 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_adapter *adapter,
 
                        if (cleaned && skb) {
                                unsigned int segs, bytecount;
+                               unsigned int hlen = skb_headlen(skb);
 
                                /* gso_segs is currently only valid for tcp */
                                segs = skb_shinfo(skb)->gso_segs ?: 1;
+#ifdef IXGBE_FCOE
+                               /* adjust for FCoE Sequence Offload */
+                               if ((adapter->flags & IXGBE_FLAG_FCOE_ENABLED)
+                                   && (skb->protocol == htons(ETH_P_FCOE)) &&
+                                   skb_is_gso(skb)) {
+                                       hlen = skb_transport_offset(skb) +
+                                               sizeof(struct fc_frame_header) +
+                                               sizeof(struct fcoe_crc_eof);
+                                       segs = DIV_ROUND_UP(skb->len - hlen,
+                                               skb_shinfo(skb)->gso_size);
+                               }
+#endif /* IXGBE_FCOE */
                                /* multiply data chunks by size of headers */
-                               bytecount = ((segs - 1) * skb_headlen(skb)) +
-                                           skb->len;
+                               bytecount = ((segs - 1) * hlen) + skb->len;
                                total_packets += segs;
                                total_bytes += bytecount;
                        }
@@ -327,7 +357,7 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_adapter *adapter,
 
        /* re-arm the interrupt */
        if (count >= tx_ring->work_limit)
-               IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS, tx_ring->v_idx);
+               ixgbe_irq_rearm_queues(adapter, ((u64)1 << q_vector->v_idx));
 
        tx_ring->total_bytes += total_bytes;
        tx_ring->total_packets += total_packets;
@@ -398,6 +428,9 @@ static void ixgbe_setup_dca(struct ixgbe_adapter *adapter)
        if (!(adapter->flags & IXGBE_FLAG_DCA_ENABLED))
                return;
 
+       /* always use CB2 mode, difference is masked in the CB driver */
+       IXGBE_WRITE_REG(&adapter->hw, IXGBE_DCA_CTRL, 2);
+
        for (i = 0; i < adapter->num_tx_queues; i++) {
                adapter->tx_ring[i].cpu = -1;
                ixgbe_update_tx_dca(adapter, &adapter->tx_ring[i]);
@@ -419,9 +452,6 @@ static int __ixgbe_notify_dca(struct device *dev, void *data)
                /* if we're already enabled, don't do it again */
                if (adapter->flags & IXGBE_FLAG_DCA_ENABLED)
                        break;
-               /* Always use CB2 mode, difference is masked
-                * in the CB driver. */
-               IXGBE_WRITE_REG(&adapter->hw, IXGBE_DCA_CTRL, 2);
                if (dca_add_requester(dev) == 0) {
                        adapter->flags |= IXGBE_FLAG_DCA_ENABLED;
                        ixgbe_setup_dca(adapter);
@@ -451,6 +481,7 @@ static int __ixgbe_notify_dca(struct device *dev, void *data)
  **/
 static void ixgbe_receive_skb(struct ixgbe_q_vector *q_vector,
                               struct sk_buff *skb, u8 status,
+                              struct ixgbe_ring *ring,
                               union ixgbe_adv_rx_desc *rx_desc)
 {
        struct ixgbe_adapter *adapter = q_vector->adapter;
@@ -458,24 +489,17 @@ static void ixgbe_receive_skb(struct ixgbe_q_vector *q_vector,
        bool is_vlan = (status & IXGBE_RXD_STAT_VP);
        u16 tag = le16_to_cpu(rx_desc->wb.upper.vlan);
 
-       skb_record_rx_queue(skb, q_vector - &adapter->q_vector[0]);
-       if (skb->ip_summed == CHECKSUM_UNNECESSARY) {
+       skb_record_rx_queue(skb, ring->queue_index);
+       if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL)) {
                if (adapter->vlgrp && is_vlan && (tag != 0))
                        vlan_gro_receive(napi, adapter->vlgrp, tag, skb);
                else
                        napi_gro_receive(napi, skb);
        } else {
-               if (!(adapter->flags & IXGBE_FLAG_IN_NETPOLL)) {
-                       if (adapter->vlgrp && is_vlan && (tag != 0))
-                               vlan_hwaccel_receive_skb(skb, adapter->vlgrp, tag);
-                       else
-                               netif_receive_skb(skb);
-               } else {
-                       if (adapter->vlgrp && is_vlan && (tag != 0))
-                               vlan_hwaccel_rx(skb, adapter->vlgrp, tag);
-                       else
-                               netif_rx(skb);
-               }
+               if (adapter->vlgrp && is_vlan && (tag != 0))
+                       vlan_hwaccel_rx(skb, adapter->vlgrp, tag);
+               else
+                       netif_rx(skb);
        }
 }
 
@@ -622,6 +646,40 @@ static inline u16 ixgbe_get_pkt_info(union ixgbe_adv_rx_desc *rx_desc)
        return rx_desc->wb.lower.lo_dword.hs_rss.pkt_info;
 }
 
+static inline u32 ixgbe_get_rsc_count(union ixgbe_adv_rx_desc *rx_desc)
+{
+       return (le32_to_cpu(rx_desc->wb.lower.lo_dword.data) &
+               IXGBE_RXDADV_RSCCNT_MASK) >>
+               IXGBE_RXDADV_RSCCNT_SHIFT;
+}
+
+/**
+ * ixgbe_transform_rsc_queue - change rsc queue into a full packet
+ * @skb: pointer to the last skb in the rsc queue
+ *
+ * This function changes a queue full of hw rsc buffers into a completed
+ * packet.  It uses the ->prev pointers to find the first packet and then
+ * turns it into the frag list owner.
+ **/
+static inline struct sk_buff *ixgbe_transform_rsc_queue(struct sk_buff *skb)
+{
+       unsigned int frag_list_size = 0;
+
+       while (skb->prev) {
+               struct sk_buff *prev = skb->prev;
+               frag_list_size += skb->len;
+               skb->prev = NULL;
+               skb = prev;
+       }
+
+       skb_shinfo(skb)->frag_list = skb->next;
+       skb->next = NULL;
+       skb->len += frag_list_size;
+       skb->data_len += frag_list_size;
+       skb->truesize += frag_list_size;
+       return skb;
+}
+
 static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
                                struct ixgbe_ring *rx_ring,
                                int *work_done, int work_to_do)
@@ -631,12 +689,15 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
        union ixgbe_adv_rx_desc *rx_desc, *next_rxd;
        struct ixgbe_rx_buffer *rx_buffer_info, *next_buffer;
        struct sk_buff *skb;
-       unsigned int i;
+       unsigned int i, rsc_count = 0;
        u32 len, staterr;
        u16 hdr_info;
        bool cleaned = false;
        int cleaned_count = 0;
        unsigned int total_rx_bytes = 0, total_rx_packets = 0;
+#ifdef IXGBE_FCOE
+       int ddp_bytes = 0;
+#endif /* IXGBE_FCOE */
 
        i = rx_ring->next_to_clean;
        rx_desc = IXGBE_RX_DESC_ADV(*rx_ring, i);
@@ -667,7 +728,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
                prefetch(skb->data - NET_IP_ALIGN);
                rx_buffer_info->skb = NULL;
 
-               if (len && !skb_shinfo(skb)->nr_frags) {
+               if (rx_buffer_info->dma) {
                        pci_unmap_single(pdev, rx_buffer_info->dma,
                                         rx_ring->rx_buf_len,
                                         PCI_DMA_FROMDEVICE);
@@ -697,20 +758,38 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
                i++;
                if (i == rx_ring->count)
                        i = 0;
-               next_buffer = &rx_ring->rx_buffer_info[i];
 
                next_rxd = IXGBE_RX_DESC_ADV(*rx_ring, i);
                prefetch(next_rxd);
-
                cleaned_count++;
+
+               if (adapter->flags & IXGBE_FLAG2_RSC_CAPABLE)
+                       rsc_count = ixgbe_get_rsc_count(rx_desc);
+
+               if (rsc_count) {
+                       u32 nextp = (staterr & IXGBE_RXDADV_NEXTP_MASK) >>
+                                    IXGBE_RXDADV_NEXTP_SHIFT;
+                       next_buffer = &rx_ring->rx_buffer_info[nextp];
+                       rx_ring->rsc_count += (rsc_count - 1);
+               } else {
+                       next_buffer = &rx_ring->rx_buffer_info[i];
+               }
+
                if (staterr & IXGBE_RXD_STAT_EOP) {
+                       if (skb->prev)
+                               skb = ixgbe_transform_rsc_queue(skb);
                        rx_ring->stats.packets++;
                        rx_ring->stats.bytes += skb->len;
                } else {
-                       rx_buffer_info->skb = next_buffer->skb;
-                       rx_buffer_info->dma = next_buffer->dma;
-                       next_buffer->skb = skb;
-                       next_buffer->dma = 0;
+                       if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) {
+                               rx_buffer_info->skb = next_buffer->skb;
+                               rx_buffer_info->dma = next_buffer->dma;
+                               next_buffer->skb = skb;
+                               next_buffer->dma = 0;
+                       } else {
+                               skb->next = next_buffer->skb;
+                               skb->next->prev = skb;
+                       }
                        adapter->non_eop_descs++;
                        goto next_desc;
                }
@@ -727,7 +806,15 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
                total_rx_packets++;
 
                skb->protocol = eth_type_trans(skb, adapter->netdev);
-               ixgbe_receive_skb(q_vector, skb, staterr, rx_desc);
+#ifdef IXGBE_FCOE
+               /* if ddp, not passing to ULD unless for FCP_RSP or error */
+               if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) {
+                       ddp_bytes = ixgbe_fcoe_ddp(adapter, rx_desc, skb);
+                       if (!ddp_bytes)
+                               goto next_desc;
+               }
+#endif /* IXGBE_FCOE */
+               ixgbe_receive_skb(q_vector, skb, staterr, rx_ring, rx_desc);
 
 next_desc:
                rx_desc->wb.upper.status_error = 0;
@@ -740,7 +827,7 @@ next_desc:
 
                /* use prefetched values */
                rx_desc = next_rxd;
-               rx_buffer_info = next_buffer;
+               rx_buffer_info = &rx_ring->rx_buffer_info[i];
 
                staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
        }
@@ -751,6 +838,21 @@ next_desc:
        if (cleaned_count)
                ixgbe_alloc_rx_buffers(adapter, rx_ring, cleaned_count);
 
+#ifdef IXGBE_FCOE
+       /* include DDPed FCoE data */
+       if (ddp_bytes > 0) {
+               unsigned int mss;
+
+               mss = adapter->netdev->mtu - sizeof(struct fcoe_hdr) -
+                       sizeof(struct fc_frame_header) -
+                       sizeof(struct fcoe_crc_eof);
+               if (mss > 512)
+                       mss &= ~511;
+               total_rx_bytes += ddp_bytes;
+               total_rx_packets += DIV_ROUND_UP(ddp_bytes, mss);
+       }
+#endif /* IXGBE_FCOE */
+
        rx_ring->total_packets += total_rx_packets;
        rx_ring->total_bytes += total_rx_bytes;
        adapter->net_stats.rx_bytes += total_rx_bytes;
@@ -780,7 +882,7 @@ static void ixgbe_configure_msix(struct ixgbe_adapter *adapter)
         * corresponding register.
         */
        for (v_idx = 0; v_idx < q_vectors; v_idx++) {
-               q_vector = &adapter->q_vector[v_idx];
+               q_vector = adapter->q_vector[v_idx];
                /* XXX for_each_bit(...) */
                r_idx = find_first_bit(q_vector->rxr_idx,
                                       adapter->num_rx_queues);
@@ -810,12 +912,7 @@ static void ixgbe_configure_msix(struct ixgbe_adapter *adapter)
                        /* rx only */
                        q_vector->eitr = adapter->eitr_param;
 
-               /*
-                * since this is initial set up don't need to call
-                * ixgbe_write_eitr helper
-                */
-               IXGBE_WRITE_REG(&adapter->hw, IXGBE_EITR(v_idx),
-                               EITR_INTS_PER_SEC_TO_REG(q_vector->eitr));
+               ixgbe_write_eitr(q_vector);
        }
 
        if (adapter->hw.mac.type == ixgbe_mac_82598EB)
@@ -900,17 +997,19 @@ update_itr_done:
 
 /**
  * ixgbe_write_eitr - write EITR register in hardware specific way
- * @adapter: pointer to adapter struct
- * @v_idx: vector index into q_vector array
- * @itr_reg: new value to be written in *register* format, not ints/s
+ * @q_vector: structure containing interrupt and ring information
  *
  * This function is made to be called by ethtool and by the driver
  * when it needs to update EITR registers at runtime.  Hardware
  * specific quirks/differences are taken care of here.
  */
-void ixgbe_write_eitr(struct ixgbe_adapter *adapter, int v_idx, u32 itr_reg)
+void ixgbe_write_eitr(struct ixgbe_q_vector *q_vector)
 {
+       struct ixgbe_adapter *adapter = q_vector->adapter;
        struct ixgbe_hw *hw = &adapter->hw;
+       int v_idx = q_vector->v_idx;
+       u32 itr_reg = EITR_INTS_PER_SEC_TO_REG(q_vector->eitr);
+
        if (adapter->hw.mac.type == ixgbe_mac_82598EB) {
                /* must write high and low 16 bits to reset counter */
                itr_reg |= (itr_reg << 16);
@@ -929,8 +1028,7 @@ static void ixgbe_set_itr_msix(struct ixgbe_q_vector *q_vector)
        struct ixgbe_adapter *adapter = q_vector->adapter;
        u32 new_itr;
        u8 current_itr, ret_itr;
-       int i, r_idx, v_idx = ((void *)q_vector - (void *)(adapter->q_vector)) /
-                              sizeof(struct ixgbe_q_vector);
+       int i, r_idx;
        struct ixgbe_ring *rx_ring, *tx_ring;
 
        r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues);
@@ -980,14 +1078,13 @@ static void ixgbe_set_itr_msix(struct ixgbe_q_vector *q_vector)
        }
 
        if (new_itr != q_vector->eitr) {
-               u32 itr_reg;
+               /* do an exponential smoothing */
+               new_itr = ((q_vector->eitr * 90)/100) + ((new_itr * 10)/100);
 
                /* save the algorithm value here, not the smoothed one */
                q_vector->eitr = new_itr;
-               /* do an exponential smoothing */
-               new_itr = ((q_vector->eitr * 90)/100) + ((new_itr * 10)/100);
-               itr_reg = EITR_INTS_PER_SEC_TO_REG(new_itr);
-               ixgbe_write_eitr(adapter, v_idx, itr_reg);
+
+               ixgbe_write_eitr(q_vector);
        }
 
        return;
@@ -1058,14 +1155,64 @@ static irqreturn_t ixgbe_msix_lsc(int irq, void *data)
        if (hw->mac.type == ixgbe_mac_82598EB)
                ixgbe_check_fan_failure(adapter, eicr);
 
-       if (hw->mac.type == ixgbe_mac_82599EB)
+       if (hw->mac.type == ixgbe_mac_82599EB) {
                ixgbe_check_sfp_event(adapter, eicr);
+
+               /* Handle Flow Director Full threshold interrupt */
+               if (eicr & IXGBE_EICR_FLOW_DIR) {
+                       int i;
+                       IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_FLOW_DIR);
+                       /* Disable transmits before FDIR Re-initialization */
+                       netif_tx_stop_all_queues(netdev);
+                       for (i = 0; i < adapter->num_tx_queues; i++) {
+                               struct ixgbe_ring *tx_ring =
+                                                          &adapter->tx_ring[i];
+                               if (test_and_clear_bit(__IXGBE_FDIR_INIT_DONE,
+                                                      &tx_ring->reinit_state))
+                                       schedule_work(&adapter->fdir_reinit_task);
+                       }
+               }
+       }
        if (!test_bit(__IXGBE_DOWN, &adapter->state))
                IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMS_OTHER);
 
        return IRQ_HANDLED;
 }
 
+static inline void ixgbe_irq_enable_queues(struct ixgbe_adapter *adapter,
+                                          u64 qmask)
+{
+       u32 mask;
+
+       if (adapter->hw.mac.type == ixgbe_mac_82598EB) {
+               mask = (IXGBE_EIMS_RTX_QUEUE & qmask);
+               IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, mask);
+       } else {
+               mask = (qmask & 0xFFFFFFFF);
+               IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS_EX(0), mask);
+               mask = (qmask >> 32);
+               IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS_EX(1), mask);
+       }
+       /* skip the flush */
+}
+
+static inline void ixgbe_irq_disable_queues(struct ixgbe_adapter *adapter,
+                                            u64 qmask)
+{
+       u32 mask;
+
+       if (adapter->hw.mac.type == ixgbe_mac_82598EB) {
+               mask = (IXGBE_EIMS_RTX_QUEUE & qmask);
+               IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, mask);
+       } else {
+               mask = (qmask & 0xFFFFFFFF);
+               IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC_EX(0), mask);
+               mask = (qmask >> 32);
+               IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC_EX(1), mask);
+       }
+       /* skip the flush */
+}
+
 static irqreturn_t ixgbe_msix_clean_tx(int irq, void *data)
 {
        struct ixgbe_q_vector *q_vector = data;
@@ -1079,17 +1226,16 @@ static irqreturn_t ixgbe_msix_clean_tx(int irq, void *data)
        r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues);
        for (i = 0; i < q_vector->txr_count; i++) {
                tx_ring = &(adapter->tx_ring[r_idx]);
-#ifdef CONFIG_IXGBE_DCA
-               if (adapter->flags & IXGBE_FLAG_DCA_ENABLED)
-                       ixgbe_update_tx_dca(adapter, tx_ring);
-#endif
                tx_ring->total_bytes = 0;
                tx_ring->total_packets = 0;
-               ixgbe_clean_tx_irq(adapter, tx_ring);
                r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues,
                                      r_idx + 1);
        }
 
+       /* disable interrupts on this vector only */
+       ixgbe_irq_disable_queues(adapter, ((u64)1 << q_vector->v_idx));
+       napi_schedule(&q_vector->napi);
+
        return IRQ_HANDLED;
 }
 
@@ -1121,7 +1267,7 @@ static irqreturn_t ixgbe_msix_clean_rx(int irq, void *data)
        r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
        rx_ring = &(adapter->rx_ring[r_idx]);
        /* disable interrupts on this vector only */
-       IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, rx_ring->v_idx);
+       ixgbe_irq_disable_queues(adapter, ((u64)1 << q_vector->v_idx));
        napi_schedule(&q_vector->napi);
 
        return IRQ_HANDLED;
@@ -1129,8 +1275,36 @@ static irqreturn_t ixgbe_msix_clean_rx(int irq, void *data)
 
 static irqreturn_t ixgbe_msix_clean_many(int irq, void *data)
 {
-       ixgbe_msix_clean_rx(irq, data);
-       ixgbe_msix_clean_tx(irq, data);
+       struct ixgbe_q_vector *q_vector = data;
+       struct ixgbe_adapter  *adapter = q_vector->adapter;
+       struct ixgbe_ring  *ring;
+       int r_idx;
+       int i;
+
+       if (!q_vector->txr_count && !q_vector->rxr_count)
+               return IRQ_HANDLED;
+
+       r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues);
+       for (i = 0; i < q_vector->txr_count; i++) {
+               ring = &(adapter->tx_ring[r_idx]);
+               ring->total_bytes = 0;
+               ring->total_packets = 0;
+               r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues,
+                                     r_idx + 1);
+       }
+
+       r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
+       for (i = 0; i < q_vector->rxr_count; i++) {
+               ring = &(adapter->rx_ring[r_idx]);
+               ring->total_bytes = 0;
+               ring->total_packets = 0;
+               r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues,
+                                     r_idx + 1);
+       }
+
+       /* disable interrupts on this vector only */
+       ixgbe_irq_disable_queues(adapter, ((u64)1 << q_vector->v_idx));
+       napi_schedule(&q_vector->napi);
 
        return IRQ_HANDLED;
 }
@@ -1167,29 +1341,42 @@ static int ixgbe_clean_rxonly(struct napi_struct *napi, int budget)
                if (adapter->itr_setting & 1)
                        ixgbe_set_itr_msix(q_vector);
                if (!test_bit(__IXGBE_DOWN, &adapter->state))
-                       IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, rx_ring->v_idx);
+                       ixgbe_irq_enable_queues(adapter,
+                                               ((u64)1 << q_vector->v_idx));
        }
 
        return work_done;
 }
 
 /**
- * ixgbe_clean_rxonly_many - msix (aka one shot) rx clean routine
+ * ixgbe_clean_rxtx_many - msix (aka one shot) rx clean routine
  * @napi: napi struct with our devices info in it
  * @budget: amount of work driver is allowed to do this pass, in packets
  *
  * This function will clean more than one rx queue associated with a
  * q_vector.
  **/
-static int ixgbe_clean_rxonly_many(struct napi_struct *napi, int budget)
+static int ixgbe_clean_rxtx_many(struct napi_struct *napi, int budget)
 {
        struct ixgbe_q_vector *q_vector =
                               container_of(napi, struct ixgbe_q_vector, napi);
        struct ixgbe_adapter *adapter = q_vector->adapter;
-       struct ixgbe_ring *rx_ring = NULL;
+       struct ixgbe_ring *ring = NULL;
        int work_done = 0, i;
        long r_idx;
-       u16 enable_mask = 0;
+       bool tx_clean_complete = true;
+
+       r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues);
+       for (i = 0; i < q_vector->txr_count; i++) {
+               ring = &(adapter->tx_ring[r_idx]);
+#ifdef CONFIG_IXGBE_DCA
+               if (adapter->flags & IXGBE_FLAG_DCA_ENABLED)
+                       ixgbe_update_tx_dca(adapter, ring);
+#endif
+               tx_clean_complete &= ixgbe_clean_tx_irq(q_vector, ring);
+               r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues,
+                                     r_idx + 1);
+       }
 
        /* attempt to distribute budget to each queue fairly, but don't allow
         * the budget to go below 1 because we'll exit polling */
@@ -1197,47 +1384,87 @@ static int ixgbe_clean_rxonly_many(struct napi_struct *napi, int budget)
        budget = max(budget, 1);
        r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
        for (i = 0; i < q_vector->rxr_count; i++) {
-               rx_ring = &(adapter->rx_ring[r_idx]);
+               ring = &(adapter->rx_ring[r_idx]);
 #ifdef CONFIG_IXGBE_DCA
                if (adapter->flags & IXGBE_FLAG_DCA_ENABLED)
-                       ixgbe_update_rx_dca(adapter, rx_ring);
+                       ixgbe_update_rx_dca(adapter, ring);
 #endif
-               ixgbe_clean_rx_irq(q_vector, rx_ring, &work_done, budget);
-               enable_mask |= rx_ring->v_idx;
+               ixgbe_clean_rx_irq(q_vector, ring, &work_done, budget);
                r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues,
                                      r_idx + 1);
        }
 
        r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues);
-       rx_ring = &(adapter->rx_ring[r_idx]);
+       ring = &(adapter->rx_ring[r_idx]);
        /* If all Rx work done, exit the polling mode */
        if (work_done < budget) {
                napi_complete(napi);
                if (adapter->itr_setting & 1)
                        ixgbe_set_itr_msix(q_vector);
                if (!test_bit(__IXGBE_DOWN, &adapter->state))
-                       IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, enable_mask);
+                       ixgbe_irq_enable_queues(adapter,
+                                               ((u64)1 << q_vector->v_idx));
                return 0;
        }
 
        return work_done;
 }
+
+/**
+ * ixgbe_clean_txonly - msix (aka one shot) tx clean routine
+ * @napi: napi struct with our devices info in it
+ * @budget: amount of work driver is allowed to do this pass, in packets
+ *
+ * This function is optimized for cleaning one queue only on a single
+ * q_vector!!!
+ **/
+static int ixgbe_clean_txonly(struct napi_struct *napi, int budget)
+{
+       struct ixgbe_q_vector *q_vector =
+                              container_of(napi, struct ixgbe_q_vector, napi);
+       struct ixgbe_adapter *adapter = q_vector->adapter;
+       struct ixgbe_ring *tx_ring = NULL;
+       int work_done = 0;
+       long r_idx;
+
+       r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues);
+       tx_ring = &(adapter->tx_ring[r_idx]);
+#ifdef CONFIG_IXGBE_DCA
+       if (adapter->flags & IXGBE_FLAG_DCA_ENABLED)
+               ixgbe_update_tx_dca(adapter, tx_ring);
+#endif
+
+       if (!ixgbe_clean_tx_irq(q_vector, tx_ring))
+               work_done = budget;
+
+       /* If all Rx work done, exit the polling mode */
+       if (work_done < budget) {
+               napi_complete(napi);
+               if (adapter->itr_setting & 1)
+                       ixgbe_set_itr_msix(q_vector);
+               if (!test_bit(__IXGBE_DOWN, &adapter->state))
+                       ixgbe_irq_enable_queues(adapter, ((u64)1 << q_vector->v_idx));
+       }
+
+       return work_done;
+}
+
 static inline void map_vector_to_rxq(struct ixgbe_adapter *a, int v_idx,
                                      int r_idx)
 {
-       a->q_vector[v_idx].adapter = a;
-       set_bit(r_idx, a->q_vector[v_idx].rxr_idx);
-       a->q_vector[v_idx].rxr_count++;
-       a->rx_ring[r_idx].v_idx = 1 << v_idx;
+       struct ixgbe_q_vector *q_vector = a->q_vector[v_idx];
+
+       set_bit(r_idx, q_vector->rxr_idx);
+       q_vector->rxr_count++;
 }
 
 static inline void map_vector_to_txq(struct ixgbe_adapter *a, int v_idx,
-                                     int r_idx)
+                                     int t_idx)
 {
-       a->q_vector[v_idx].adapter = a;
-       set_bit(r_idx, a->q_vector[v_idx].txr_idx);
-       a->q_vector[v_idx].txr_count++;
-       a->tx_ring[r_idx].v_idx = 1 << v_idx;
+       struct ixgbe_q_vector *q_vector = a->q_vector[v_idx];
+
+       set_bit(t_idx, q_vector->txr_idx);
+       q_vector->txr_count++;
 }
 
 /**
@@ -1333,7 +1560,7 @@ static int ixgbe_request_msix_irqs(struct ixgbe_adapter *adapter)
                          (!(_v)->txr_count) ? &ixgbe_msix_clean_rx : \
                          &ixgbe_msix_clean_many)
        for (vector = 0; vector < q_vectors; vector++) {
-               handler = SET_HANDLER(&adapter->q_vector[vector]);
+               handler = SET_HANDLER(adapter->q_vector[vector]);
 
                if(handler == &ixgbe_msix_clean_rx) {
                        sprintf(adapter->name[vector], "%s-%s-%d",
@@ -1349,7 +1576,7 @@ static int ixgbe_request_msix_irqs(struct ixgbe_adapter *adapter)
 
                err = request_irq(adapter->msix_entries[vector].vector,
                                  handler, 0, adapter->name[vector],
-                                 &(adapter->q_vector[vector]));
+                                 adapter->q_vector[vector]);
                if (err) {
                        DPRINTK(PROBE, ERR,
                                "request_irq failed for MSIX interrupt "
@@ -1372,7 +1599,7 @@ static int ixgbe_request_msix_irqs(struct ixgbe_adapter *adapter)
 free_queue_irqs:
        for (i = vector - 1; i >= 0; i--)
                free_irq(adapter->msix_entries[--vector].vector,
-                        &(adapter->q_vector[i]));
+                        adapter->q_vector[i]);
        adapter->flags &= ~IXGBE_FLAG_MSIX_ENABLED;
        pci_disable_msix(adapter->pdev);
        kfree(adapter->msix_entries);
@@ -1383,7 +1610,7 @@ out:
 
 static void ixgbe_set_itr(struct ixgbe_adapter *adapter)
 {
-       struct ixgbe_q_vector *q_vector = adapter->q_vector;
+       struct ixgbe_q_vector *q_vector = adapter->q_vector[0];
        u8 current_itr;
        u32 new_itr = q_vector->eitr;
        struct ixgbe_ring *rx_ring = &adapter->rx_ring[0];
@@ -1416,14 +1643,13 @@ static void ixgbe_set_itr(struct ixgbe_adapter *adapter)
        }
 
        if (new_itr != q_vector->eitr) {
-               u32 itr_reg;
+               /* do an exponential smoothing */
+               new_itr = ((q_vector->eitr * 90)/100) + ((new_itr * 10)/100);
 
                /* save the algorithm value here, not the smoothed one */
                q_vector->eitr = new_itr;
-               /* do an exponential smoothing */
-               new_itr = ((q_vector->eitr * 90)/100) + ((new_itr * 10)/100);
-               itr_reg = EITR_INTS_PER_SEC_TO_REG(new_itr);
-               ixgbe_write_eitr(adapter, 0, itr_reg);
+
+               ixgbe_write_eitr(q_vector);
        }
 
        return;
@@ -1436,7 +1662,8 @@ static void ixgbe_set_itr(struct ixgbe_adapter *adapter)
 static inline void ixgbe_irq_enable(struct ixgbe_adapter *adapter)
 {
        u32 mask;
-       mask = IXGBE_EIMS_ENABLE_MASK;
+
+       mask = (IXGBE_EIMS_ENABLE_MASK & ~IXGBE_EIMS_RTX_QUEUE);
        if (adapter->flags & IXGBE_FLAG_FAN_FAIL_CAPABLE)
                mask |= IXGBE_EIMS_GPI_SDP1;
        if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
@@ -1444,16 +1671,12 @@ static inline void ixgbe_irq_enable(struct ixgbe_adapter *adapter)
                mask |= IXGBE_EIMS_GPI_SDP1;
                mask |= IXGBE_EIMS_GPI_SDP2;
        }
+       if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE ||
+           adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)
+               mask |= IXGBE_EIMS_FLOW_DIR;
 
        IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, mask);
-       if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
-               /* enable the rest of the queue vectors */
-               IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS_EX(1),
-                               (IXGBE_EIMS_RTX_QUEUE << 16));
-               IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS_EX(2),
-                               ((IXGBE_EIMS_RTX_QUEUE << 16) |
-                                 IXGBE_EIMS_RTX_QUEUE));
-       }
+       ixgbe_irq_enable_queues(adapter, ~0);
        IXGBE_WRITE_FLUSH(&adapter->hw);
 }
 
@@ -1467,6 +1690,7 @@ static irqreturn_t ixgbe_intr(int irq, void *data)
        struct net_device *netdev = data;
        struct ixgbe_adapter *adapter = netdev_priv(netdev);
        struct ixgbe_hw *hw = &adapter->hw;
+       struct ixgbe_q_vector *q_vector = adapter->q_vector[0];
        u32 eicr;
 
        /*
@@ -1494,13 +1718,13 @@ static irqreturn_t ixgbe_intr(int irq, void *data)
 
        ixgbe_check_fan_failure(adapter, eicr);
 
-       if (napi_schedule_prep(&adapter->q_vector[0].napi)) {
+       if (napi_schedule_prep(&(q_vector->napi))) {
                adapter->tx_ring[0].total_packets = 0;
                adapter->tx_ring[0].total_bytes = 0;
                adapter->rx_ring[0].total_packets = 0;
                adapter->rx_ring[0].total_bytes = 0;
                /* would disable interrupts here but EIAM disabled it */
-               __napi_schedule(&adapter->q_vector[0].napi);
+               __napi_schedule(&(q_vector->napi));
        }
 
        return IRQ_HANDLED;
@@ -1511,7 +1735,7 @@ static inline void ixgbe_reset_q_vectors(struct ixgbe_adapter *adapter)
        int i, q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
 
        for (i = 0; i < q_vectors; i++) {
-               struct ixgbe_q_vector *q_vector = &adapter->q_vector[i];
+               struct ixgbe_q_vector *q_vector = adapter->q_vector[i];
                bitmap_zero(q_vector->rxr_idx, MAX_RX_QUEUES);
                bitmap_zero(q_vector->txr_idx, MAX_TX_QUEUES);
                q_vector->rxr_count = 0;
@@ -1562,7 +1786,7 @@ static void ixgbe_free_irq(struct ixgbe_adapter *adapter)
                i--;
                for (; i >= 0; i--) {
                        free_irq(adapter->msix_entries[i].vector,
-                                &(adapter->q_vector[i]));
+                                adapter->q_vector[i]);
                }
 
                ixgbe_reset_q_vectors(adapter);
@@ -1577,10 +1801,12 @@ static void ixgbe_free_irq(struct ixgbe_adapter *adapter)
  **/
 static inline void ixgbe_irq_disable(struct ixgbe_adapter *adapter)
 {
-       IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, ~0);
-       if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
+       if (adapter->hw.mac.type == ixgbe_mac_82598EB) {
+               IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, ~0);
+       } else {
+               IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, 0xFFFF0000);
+               IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC_EX(0), ~0);
                IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC_EX(1), ~0);
-               IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC_EX(2), ~0);
        }
        IXGBE_WRITE_FLUSH(&adapter->hw);
        if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
@@ -1592,18 +1818,6 @@ static inline void ixgbe_irq_disable(struct ixgbe_adapter *adapter)
        }
 }
 
-static inline void ixgbe_irq_enable_queues(struct ixgbe_adapter *adapter)
-{
-       u32 mask = IXGBE_EIMS_RTX_QUEUE;
-       IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, mask);
-       if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
-               IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS_EX(1), mask << 16);
-               IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS_EX(2),
-                               (mask << 16 | mask));
-       }
-       /* skip the flush */
-}
-
 /**
  * ixgbe_configure_msi_and_legacy - Initialize PIN (INTA...) and MSI interrupts
  *
@@ -1673,11 +1887,34 @@ static void ixgbe_configure_srrctl(struct ixgbe_adapter *adapter, int index)
        u32 srrctl;
        int queue0 = 0;
        unsigned long mask;
+       struct ixgbe_ring_feature *feature = adapter->ring_feature;
 
        if (adapter->hw.mac.type == ixgbe_mac_82599EB) {
-               queue0 = index;
+               if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
+                       int dcb_i = feature[RING_F_DCB].indices;
+                       if (dcb_i == 8)
+                               queue0 = index >> 4;
+                       else if (dcb_i == 4)
+                               queue0 = index >> 5;
+                       else
+                               dev_err(&adapter->pdev->dev, "Invalid DCB "
+                                       "configuration\n");
+#ifdef IXGBE_FCOE
+                       if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) {
+                               struct ixgbe_ring_feature *f;
+
+                               rx_ring = &adapter->rx_ring[queue0];
+                               f = &adapter->ring_feature[RING_F_FCOE];
+                               if ((queue0 == 0) && (index > rx_ring->reg_idx))
+                                       queue0 = f->mask + index -
+                                                rx_ring->reg_idx - 1;
+                       }
+#endif /* IXGBE_FCOE */
+               } else {
+                       queue0 = index;
+               }
        } else {
-               mask = (unsigned long) adapter->ring_feature[RING_F_RSS].mask;
+               mask = (unsigned long) feature[RING_F_RSS].mask;
                queue0 = index & mask;
                index = index & mask;
        }
@@ -1689,33 +1926,55 @@ static void ixgbe_configure_srrctl(struct ixgbe_adapter *adapter, int index)
        srrctl &= ~IXGBE_SRRCTL_BSIZEHDR_MASK;
        srrctl &= ~IXGBE_SRRCTL_BSIZEPKT_MASK;
 
+       srrctl |= (IXGBE_RX_HDR_SIZE << IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT) &
+                 IXGBE_SRRCTL_BSIZEHDR_MASK;
+
        if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) {
-               u16 bufsz = IXGBE_RXBUFFER_2048;
-               /* grow the amount we can receive on large page machines */
-               if (bufsz < (PAGE_SIZE / 2))
-                       bufsz = (PAGE_SIZE / 2);
-               /* cap the bufsz at our largest descriptor size */
-               bufsz = min((u16)IXGBE_MAX_RXBUFFER, bufsz);
-
-               srrctl |= bufsz >> IXGBE_SRRCTL_BSIZEPKT_SHIFT;
+#if (PAGE_SIZE / 2) > IXGBE_MAX_RXBUFFER
+               srrctl |= IXGBE_MAX_RXBUFFER >> IXGBE_SRRCTL_BSIZEPKT_SHIFT;
+#else
+               srrctl |= (PAGE_SIZE / 2) >> IXGBE_SRRCTL_BSIZEPKT_SHIFT;
+#endif
                srrctl |= IXGBE_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS;
-               srrctl |= ((IXGBE_RX_HDR_SIZE <<
-                           IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT) &
-                          IXGBE_SRRCTL_BSIZEHDR_MASK);
        } else {
+               srrctl |= ALIGN(rx_ring->rx_buf_len, 1024) >>
+                         IXGBE_SRRCTL_BSIZEPKT_SHIFT;
                srrctl |= IXGBE_SRRCTL_DESCTYPE_ADV_ONEBUF;
-
-               if (rx_ring->rx_buf_len == MAXIMUM_ETHERNET_VLAN_SIZE)
-                       srrctl |= IXGBE_RXBUFFER_2048 >>
-                                 IXGBE_SRRCTL_BSIZEPKT_SHIFT;
-               else
-                       srrctl |= rx_ring->rx_buf_len >>
-                                 IXGBE_SRRCTL_BSIZEPKT_SHIFT;
        }
 
        IXGBE_WRITE_REG(&adapter->hw, IXGBE_SRRCTL(index), srrctl);
 }
 
+static u32 ixgbe_setup_mrqc(struct ixgbe_adapter *adapter)
+{
+       u32 mrqc = 0;
+       int mask;
+
+       if (!(adapter->hw.mac.type == ixgbe_mac_82599EB))
+               return mrqc;
+
+       mask = adapter->flags & (IXGBE_FLAG_RSS_ENABLED
+#ifdef CONFIG_IXGBE_DCB
+                                | IXGBE_FLAG_DCB_ENABLED
+#endif
+                               );
+
+       switch (mask) {
+       case (IXGBE_FLAG_RSS_ENABLED):
+               mrqc = IXGBE_MRQC_RSSEN;
+               break;
+#ifdef CONFIG_IXGBE_DCB
+       case (IXGBE_FLAG_DCB_ENABLED):
+               mrqc = IXGBE_MRQC_RT8TCEN;
+               break;
+#endif /* CONFIG_IXGBE_DCB */
+       default:
+               break;
+       }
+
+       return mrqc;
+}
+
 /**
  * ixgbe_configure_rx - Configure 8259x Receive Unit after Reset
  * @adapter: board private structure
@@ -1736,11 +1995,17 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
        u32 fctrl, hlreg0;
        u32 reta = 0, mrqc = 0;
        u32 rdrxctl;
+       u32 rscctrl;
        int rx_buf_len;
 
        /* Decide whether to use packet split mode or not */
        adapter->flags |= IXGBE_FLAG_RX_PS_ENABLED;
 
+#ifdef IXGBE_FCOE
+       if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED)
+               adapter->flags &= ~IXGBE_FLAG_RX_PS_ENABLED;
+#endif /* IXGBE_FCOE */
+
        /* Set the RX buffer length according to the mode */
        if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) {
                rx_buf_len = IXGBE_RX_HDR_SIZE;
@@ -1749,11 +2014,13 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
                        u32 psrtype = IXGBE_PSRTYPE_TCPHDR |
                                      IXGBE_PSRTYPE_UDPHDR |
                                      IXGBE_PSRTYPE_IPV4HDR |
-                                     IXGBE_PSRTYPE_IPV6HDR;
+                                     IXGBE_PSRTYPE_IPV6HDR |
+                                     IXGBE_PSRTYPE_L2HDR;
                        IXGBE_WRITE_REG(hw, IXGBE_PSRTYPE(0), psrtype);
                }
        } else {
-               if (netdev->mtu <= ETH_DATA_LEN)
+               if (!(adapter->flags & IXGBE_FLAG2_RSC_ENABLED) &&
+                   (netdev->mtu <= ETH_DATA_LEN))
                        rx_buf_len = MAXIMUM_ETHERNET_VLAN_SIZE;
                else
                        rx_buf_len = ALIGN(max_frame, 1024);
@@ -1770,6 +2037,10 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
                hlreg0 &= ~IXGBE_HLREG0_JUMBOEN;
        else
                hlreg0 |= IXGBE_HLREG0_JUMBOEN;
+#ifdef IXGBE_FCOE
+       if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED)
+               hlreg0 |= IXGBE_HLREG0_JUMBOEN;
+#endif
        IXGBE_WRITE_REG(hw, IXGBE_HLREG0, hlreg0);
 
        rdlen = adapter->rx_ring[0].count * sizeof(union ixgbe_adv_rx_desc);
@@ -1777,8 +2048,10 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
        rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
        IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, rxctrl & ~IXGBE_RXCTRL_RXEN);
 
-       /* Setup the HW Rx Head and Tail Descriptor Pointers and
-        * the Base and Length of the Rx Descriptor Ring */
+       /*
+        * Setup the HW Rx Head and Tail Descriptor Pointers and
+        * the Base and Length of the Rx Descriptor Ring
+        */
        for (i = 0; i < adapter->num_rx_queues; i++) {
                rdba = adapter->rx_ring[i].dma;
                j = adapter->rx_ring[i].reg_idx;
@@ -1791,6 +2064,17 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
                adapter->rx_ring[i].tail = IXGBE_RDT(j);
                adapter->rx_ring[i].rx_buf_len = rx_buf_len;
 
+#ifdef IXGBE_FCOE
+               if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) {
+                       struct ixgbe_ring_feature *f;
+                       f = &adapter->ring_feature[RING_F_FCOE];
+                       if ((rx_buf_len < IXGBE_FCOE_JUMBO_FRAME_SIZE) &&
+                           (i >= f->mask) && (i < f->mask + f->indices))
+                               adapter->rx_ring[i].rx_buf_len =
+                                       IXGBE_FCOE_JUMBO_FRAME_SIZE;
+               }
+
+#endif /* IXGBE_FCOE */
                ixgbe_configure_srrctl(adapter, j);
        }
 
@@ -1811,23 +2095,8 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
        }
 
        /* Program MRQC for the distribution of queues */
-       if (hw->mac.type == ixgbe_mac_82599EB) {
-               int mask = adapter->flags & (
-                               IXGBE_FLAG_RSS_ENABLED
-                               | IXGBE_FLAG_DCB_ENABLED
-                               );
+       mrqc = ixgbe_setup_mrqc(adapter);
 
-               switch (mask) {
-               case (IXGBE_FLAG_RSS_ENABLED):
-                       mrqc = IXGBE_MRQC_RSSEN;
-                       break;
-               case (IXGBE_FLAG_DCB_ENABLED):
-                       mrqc = IXGBE_MRQC_RT8TCEN;
-                       break;
-               default:
-                       break;
-               }
-       }
        if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) {
                /* Fill out redirection table */
                for (i = 0, j = 0; i < 128; i++, j++) {
@@ -1875,8 +2144,45 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
        if (hw->mac.type == ixgbe_mac_82599EB) {
                rdrxctl = IXGBE_READ_REG(hw, IXGBE_RDRXCTL);
                rdrxctl |= IXGBE_RDRXCTL_CRCSTRIP;
+               rdrxctl &= ~IXGBE_RDRXCTL_RSCFRSTSIZE;
                IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, rdrxctl);
        }
+
+       if (adapter->flags & IXGBE_FLAG2_RSC_ENABLED) {
+               /* Enable 82599 HW-RSC */
+               for (i = 0; i < adapter->num_rx_queues; i++) {
+                       j = adapter->rx_ring[i].reg_idx;
+                       rscctrl = IXGBE_READ_REG(hw, IXGBE_RSCCTL(j));
+                       rscctrl |= IXGBE_RSCCTL_RSCEN;
+                       /*
+                        * we must limit the number of descriptors so that the
+                        * total size of max desc * buf_len is not greater
+                        * than 65535
+                        */
+                       if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) {
+#if (MAX_SKB_FRAGS > 16)
+                               rscctrl |= IXGBE_RSCCTL_MAXDESC_16;
+#elif (MAX_SKB_FRAGS > 8)
+                               rscctrl |= IXGBE_RSCCTL_MAXDESC_8;
+#elif (MAX_SKB_FRAGS > 4)
+                               rscctrl |= IXGBE_RSCCTL_MAXDESC_4;
+#else
+                               rscctrl |= IXGBE_RSCCTL_MAXDESC_1;
+#endif
+                       } else {
+                               if (rx_buf_len < IXGBE_RXBUFFER_4096)
+                                       rscctrl |= IXGBE_RSCCTL_MAXDESC_16;
+                               else if (rx_buf_len < IXGBE_RXBUFFER_8192)
+                                       rscctrl |= IXGBE_RSCCTL_MAXDESC_8;
+                               else
+                                       rscctrl |= IXGBE_RSCCTL_MAXDESC_4;
+                       }
+                       IXGBE_WRITE_REG(hw, IXGBE_RSCCTL(j), rscctrl);
+               }
+               /* Disable RSC for ACK packets */
+               IXGBE_WRITE_REG(hw, IXGBE_RSCDBU,
+                  (IXGBE_RSCDBU_RSCACKDIS | IXGBE_READ_REG(hw, IXGBE_RSCDBU)));
+       }
 }
 
 static void ixgbe_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
@@ -2015,11 +2321,7 @@ static void ixgbe_set_rx_mode(struct net_device *netdev)
        IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl);
 
        /* reprogram secondary unicast list */
-       addr_count = netdev->uc_count;
-       if (addr_count)
-               addr_list = netdev->uc_list->dmi_addr;
-       hw->mac.ops.update_uc_addr_list(hw, addr_list, addr_count,
-                                         ixgbe_addr_list_itr);
+       hw->mac.ops.update_uc_addr_list(hw, &netdev->uc_list);
 
        /* reprogram multicast list */
        addr_count = netdev->mc_count;
@@ -2041,13 +2343,16 @@ static void ixgbe_napi_enable_all(struct ixgbe_adapter *adapter)
 
        for (q_idx = 0; q_idx < q_vectors; q_idx++) {
                struct napi_struct *napi;
-               q_vector = &adapter->q_vector[q_idx];
-               if (!q_vector->rxr_count)
-                       continue;
+               q_vector = adapter->q_vector[q_idx];
                napi = &q_vector->napi;
-               if ((adapter->flags & IXGBE_FLAG_MSIX_ENABLED) &&
-                   (q_vector->rxr_count > 1))
-                       napi->poll = &ixgbe_clean_rxonly_many;
+               if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
+                       if (!q_vector->rxr_count || !q_vector->txr_count) {
+                               if (q_vector->txr_count == 1)
+                                       napi->poll = &ixgbe_clean_txonly;
+                               else if (q_vector->rxr_count == 1)
+                                       napi->poll = &ixgbe_clean_rxonly;
+                       }
+               }
 
                napi_enable(napi);
        }
@@ -2064,9 +2369,7 @@ static void ixgbe_napi_disable_all(struct ixgbe_adapter *adapter)
                q_vectors = 1;
 
        for (q_idx = 0; q_idx < q_vectors; q_idx++) {
-               q_vector = &adapter->q_vector[q_idx];
-               if (!q_vector->rxr_count)
-                       continue;
+               q_vector = adapter->q_vector[q_idx];
                napi_disable(&q_vector->napi);
        }
 }
@@ -2124,6 +2427,7 @@ static void ixgbe_configure_dcb(struct ixgbe_adapter *adapter)
 static void ixgbe_configure(struct ixgbe_adapter *adapter)
 {
        struct net_device *netdev = adapter->netdev;
+       struct ixgbe_hw *hw = &adapter->hw;
        int i;
 
        ixgbe_set_rx_mode(netdev);
@@ -2140,6 +2444,20 @@ static void ixgbe_configure(struct ixgbe_adapter *adapter)
        netif_set_gso_max_size(netdev, 65536);
 #endif
 
+#ifdef IXGBE_FCOE
+       if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED)
+               ixgbe_configure_fcoe(adapter);
+
+#endif /* IXGBE_FCOE */
+       if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) {
+               for (i = 0; i < adapter->num_tx_queues; i++)
+                       adapter->tx_ring[i].atr_sample_rate =
+                                                      adapter->atr_sample_rate;
+               ixgbe_init_fdir_signature_82599(hw, adapter->fdir_pballoc);
+       } else if (adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE) {
+               ixgbe_init_fdir_perfect_82599(hw, adapter->fdir_pballoc);
+       }
+
        ixgbe_configure_tx(adapter);
        ixgbe_configure_rx(adapter);
        for (i = 0; i < adapter->num_rx_queues; i++)
@@ -2294,6 +2612,13 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
                IXGBE_WRITE_REG(hw, IXGBE_GPIE, gpie);
        }
 
+#ifdef IXGBE_FCOE
+       /* adjust max frame to be able to do baby jumbo for FCoE */
+       if ((adapter->flags & IXGBE_FLAG_FCOE_ENABLED) &&
+           (max_frame < IXGBE_FCOE_JUMBO_FRAME_SIZE))
+               max_frame = IXGBE_FCOE_JUMBO_FRAME_SIZE;
+
+#endif /* IXGBE_FCOE */
        mhadd = IXGBE_READ_REG(hw, IXGBE_MHADD);
        if (max_frame != (mhadd >> IXGBE_MHADD_MFS_SHIFT)) {
                mhadd &= ~IXGBE_MHADD_MFS_MASK;
@@ -2356,6 +2681,17 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
 
        ixgbe_irq_enable(adapter);
 
+       /*
+        * If this adapter has a fan, check to see if we had a failure
+        * before we enabled the interrupt.
+        */
+       if (adapter->flags & IXGBE_FLAG_FAN_FAIL_CAPABLE) {
+               u32 esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
+               if (esdp & IXGBE_ESDP_SDP1)
+                       DPRINTK(DRV, CRIT,
+                               "Fan has stopped, replace the adapter\n");
+       }
+
        /*
         * For hot-pluggable SFP+ devices, a new SFP+ module may have
         * arrived before interrupts were enabled.  We need to kick off
@@ -2378,6 +2714,10 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
                        DPRINTK(PROBE, ERR, "link_config FAILED %d\n", err);
        }
 
+       for (i = 0; i < adapter->num_tx_queues; i++)
+               set_bit(__IXGBE_FDIR_INIT_DONE,
+                       &(adapter->tx_ring[i].reinit_state));
+
        /* enable transmits */
        netif_tx_start_all_queues(netdev);
 
@@ -2404,20 +2744,37 @@ int ixgbe_up(struct ixgbe_adapter *adapter)
        /* hardware has been reset, we need to reload some things */
        ixgbe_configure(adapter);
 
-       ixgbe_napi_add_all(adapter);
-
        return ixgbe_up_complete(adapter);
 }
 
 void ixgbe_reset(struct ixgbe_adapter *adapter)
 {
        struct ixgbe_hw *hw = &adapter->hw;
-       if (hw->mac.ops.init_hw(hw))
-               dev_err(&adapter->pdev->dev, "Hardware Error\n");
+       int err;
+
+       err = hw->mac.ops.init_hw(hw);
+       switch (err) {
+       case 0:
+       case IXGBE_ERR_SFP_NOT_PRESENT:
+               break;
+       case IXGBE_ERR_MASTER_REQUESTS_PENDING:
+               dev_err(&adapter->pdev->dev, "master disable timed out\n");
+               break;
+       case IXGBE_ERR_EEPROM_VERSION:
+               /* We are running on a pre-production device, log a warning */
+               dev_warn(&adapter->pdev->dev, "This device is a pre-production "
+                        "adapter/LOM.  Please be aware there may be issues "
+                        "associated with your hardware.  If you are "
+                        "experiencing problems please contact your Intel or "
+                        "hardware representative who provided you with this "
+                        "hardware.\n");
+               break;
+       default:
+               dev_err(&adapter->pdev->dev, "Hardware Error: %d\n", err);
+       }
 
        /* reprogram the RAR[0] in case user changed it. */
        hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV);
-
 }
 
 /**
@@ -2445,8 +2802,13 @@ static void ixgbe_clean_rx_ring(struct ixgbe_adapter *adapter,
                        rx_buffer_info->dma = 0;
                }
                if (rx_buffer_info->skb) {
-                       dev_kfree_skb(rx_buffer_info->skb);
+                       struct sk_buff *skb = rx_buffer_info->skb;
                        rx_buffer_info->skb = NULL;
+                       do {
+                               struct sk_buff *this = skb;
+                               skb = skb->prev;
+                               dev_kfree_skb(this);
+                       } while (skb);
                }
                if (!rx_buffer_info->page)
                        continue;
@@ -2560,6 +2922,10 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
        del_timer_sync(&adapter->watchdog_timer);
        cancel_work_sync(&adapter->watchdog_task);
 
+       if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE ||
+           adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)
+               cancel_work_sync(&adapter->fdir_reinit_task);
+
        /* disable transmits in the hardware now that interrupts are off */
        for (i = 0; i < adapter->num_tx_queues; i++) {
                j = adapter->tx_ring[i].reg_idx;
@@ -2575,13 +2941,6 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
 
        netif_carrier_off(netdev);
 
-#ifdef CONFIG_IXGBE_DCA
-       if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) {
-               adapter->flags &= ~IXGBE_FLAG_DCA_ENABLED;
-               dca_remove_requester(&adapter->pdev->dev);
-       }
-
-#endif
        if (!pci_channel_offline(adapter->pdev))
                ixgbe_reset(adapter);
        ixgbe_clean_all_tx_rings(adapter);
@@ -2589,13 +2948,7 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
 
 #ifdef CONFIG_IXGBE_DCA
        /* since we reset the hardware DCA settings were cleared */
-       if (dca_add_requester(&adapter->pdev->dev) == 0) {
-               adapter->flags |= IXGBE_FLAG_DCA_ENABLED;
-               /* always use CB2 mode, difference is masked
-                * in the CB driver */
-               IXGBE_WRITE_REG(hw, IXGBE_DCA_CTRL, 2);
-               ixgbe_setup_dca(adapter);
-       }
+       ixgbe_setup_dca(adapter);
 #endif
 }
 
@@ -2620,7 +2973,7 @@ static int ixgbe_poll(struct napi_struct *napi, int budget)
        }
 #endif
 
-       tx_clean_complete = ixgbe_clean_tx_irq(adapter, adapter->tx_ring);
+       tx_clean_complete = ixgbe_clean_tx_irq(q_vector, adapter->tx_ring);
        ixgbe_clean_rx_irq(q_vector, adapter->rx_ring, &work_done, budget);
 
        if (!tx_clean_complete)
@@ -2632,7 +2985,7 @@ static int ixgbe_poll(struct napi_struct *napi, int budget)
                if (adapter->itr_setting & 1)
                        ixgbe_set_itr(adapter);
                if (!test_bit(__IXGBE_DOWN, &adapter->state))
-                       ixgbe_irq_enable_queues(adapter);
+                       ixgbe_irq_enable_queues(adapter, IXGBE_EIMS_RTX_QUEUE);
        }
        return work_done;
 }
@@ -2668,17 +3021,15 @@ static void ixgbe_reset_task(struct work_struct *work)
 static inline bool ixgbe_set_dcb_queues(struct ixgbe_adapter *adapter)
 {
        bool ret = false;
+       struct ixgbe_ring_feature *f = &adapter->ring_feature[RING_F_DCB];
 
-       if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
-               adapter->ring_feature[RING_F_DCB].mask = 0x7 << 3;
-               adapter->num_rx_queues =
-                                     adapter->ring_feature[RING_F_DCB].indices;
-               adapter->num_tx_queues =
-                                     adapter->ring_feature[RING_F_DCB].indices;
-               ret = true;
-       } else {
-               ret = false;
-       }
+       if (!(adapter->flags & IXGBE_FLAG_DCB_ENABLED))
+               return ret;
+
+       f->mask = 0x7 << 3;
+       adapter->num_rx_queues = f->indices;
+       adapter->num_tx_queues = f->indices;
+       ret = true;
 
        return ret;
 }
@@ -2695,13 +3046,12 @@ static inline bool ixgbe_set_dcb_queues(struct ixgbe_adapter *adapter)
 static inline bool ixgbe_set_rss_queues(struct ixgbe_adapter *adapter)
 {
        bool ret = false;
+       struct ixgbe_ring_feature *f = &adapter->ring_feature[RING_F_RSS];
 
        if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) {
-               adapter->ring_feature[RING_F_RSS].mask = 0xF;
-               adapter->num_rx_queues =
-                                     adapter->ring_feature[RING_F_RSS].indices;
-               adapter->num_tx_queues =
-                                     adapter->ring_feature[RING_F_RSS].indices;
+               f->mask = 0xF;
+               adapter->num_rx_queues = f->indices;
+               adapter->num_tx_queues = f->indices;
                ret = true;
        } else {
                ret = false;
@@ -2710,6 +3060,79 @@ static inline bool ixgbe_set_rss_queues(struct ixgbe_adapter *adapter)
        return ret;
 }
 
+/**
+ * ixgbe_set_fdir_queues: Allocate queues for Flow Director
+ * @adapter: board private structure to initialize
+ *
+ * Flow Director is an advanced Rx filter, attempting to get Rx flows back
+ * to the original CPU that initiated the Tx session.  This runs in addition
+ * to RSS, so if a packet doesn't match an FDIR filter, we can still spread the
+ * Rx load across CPUs using RSS.
+ *
+ **/
+static bool inline ixgbe_set_fdir_queues(struct ixgbe_adapter *adapter)
+{
+       bool ret = false;
+       struct ixgbe_ring_feature *f_fdir = &adapter->ring_feature[RING_F_FDIR];
+
+       f_fdir->indices = min((int)num_online_cpus(), f_fdir->indices);
+       f_fdir->mask = 0;
+
+       /* Flow Director must have RSS enabled */
+       if (adapter->flags & IXGBE_FLAG_RSS_ENABLED &&
+           ((adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE ||
+            (adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)))) {
+               adapter->num_tx_queues = f_fdir->indices;
+               adapter->num_rx_queues = f_fdir->indices;
+               ret = true;
+       } else {
+               adapter->flags &= ~IXGBE_FLAG_FDIR_HASH_CAPABLE;
+               adapter->flags &= ~IXGBE_FLAG_FDIR_PERFECT_CAPABLE;
+       }
+       return ret;
+}
+
+#ifdef IXGBE_FCOE
+/**
+ * ixgbe_set_fcoe_queues: Allocate queues for Fiber Channel over Ethernet (FCoE)
+ * @adapter: board private structure to initialize
+ *
+ * FCoE RX FCRETA can use up to 8 rx queues for up to 8 different exchanges.
+ * The ring feature mask is not used as a mask for FCoE, as it can take any 8
+ * rx queues out of the max number of rx queues, instead, it is used as the
+ * index of the first rx queue used by FCoE.
+ *
+ **/
+static inline bool ixgbe_set_fcoe_queues(struct ixgbe_adapter *adapter)
+{
+       bool ret = false;
+       struct ixgbe_ring_feature *f = &adapter->ring_feature[RING_F_FCOE];
+
+       f->indices = min((int)num_online_cpus(), f->indices);
+       if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) {
+#ifdef CONFIG_IXGBE_DCB
+               if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
+                       DPRINTK(PROBE, INFO, "FCOE enabled with DCB \n");
+                       ixgbe_set_dcb_queues(adapter);
+               }
+#endif
+               if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) {
+                       DPRINTK(PROBE, INFO, "FCOE enabled with RSS \n");
+                       ixgbe_set_rss_queues(adapter);
+               }
+               /* adding FCoE rx rings to the end */
+               f->mask = adapter->num_rx_queues;
+               adapter->num_rx_queues += f->indices;
+               if (adapter->num_tx_queues == 0)
+                       adapter->num_tx_queues = f->indices;
+
+               ret = true;
+       }
+
+       return ret;
+}
+
+#endif /* IXGBE_FCOE */
 /*
  * ixgbe_set_num_queues: Allocate queues for device, feature dependant
  * @adapter: board private structure to initialize
@@ -2723,11 +3146,19 @@ static inline bool ixgbe_set_rss_queues(struct ixgbe_adapter *adapter)
  **/
 static void ixgbe_set_num_queues(struct ixgbe_adapter *adapter)
 {
+#ifdef IXGBE_FCOE
+       if (ixgbe_set_fcoe_queues(adapter))
+               goto done;
+
+#endif /* IXGBE_FCOE */
 #ifdef CONFIG_IXGBE_DCB
        if (ixgbe_set_dcb_queues(adapter))
                goto done;
 
 #endif
+       if (ixgbe_set_fdir_queues(adapter))
+               goto done;
+
        if (ixgbe_set_rss_queues(adapter))
                goto done;
 
@@ -2778,9 +3209,6 @@ static void ixgbe_acquire_msix_vectors(struct ixgbe_adapter *adapter,
                adapter->flags &= ~IXGBE_FLAG_MSIX_ENABLED;
                kfree(adapter->msix_entries);
                adapter->msix_entries = NULL;
-               adapter->flags &= ~IXGBE_FLAG_DCB_ENABLED;
-               adapter->flags &= ~IXGBE_FLAG_RSS_ENABLED;
-               ixgbe_set_num_queues(adapter);
        } else {
                adapter->flags |= IXGBE_FLAG_MSIX_ENABLED; /* Woot! */
                /*
@@ -2901,6 +3329,64 @@ static inline bool ixgbe_cache_ring_dcb(struct ixgbe_adapter *adapter)
 }
 #endif
 
+/**
+ * ixgbe_cache_ring_fdir - Descriptor ring to register mapping for Flow Director
+ * @adapter: board private structure to initialize
+ *
+ * Cache the descriptor ring offsets for Flow Director to the assigned rings.
+ *
+ **/
+static bool inline ixgbe_cache_ring_fdir(struct ixgbe_adapter *adapter)
+{
+       int i;
+       bool ret = false;
+
+       if (adapter->flags & IXGBE_FLAG_RSS_ENABLED &&
+           ((adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE) ||
+            (adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE))) {
+               for (i = 0; i < adapter->num_rx_queues; i++)
+                       adapter->rx_ring[i].reg_idx = i;
+               for (i = 0; i < adapter->num_tx_queues; i++)
+                       adapter->tx_ring[i].reg_idx = i;
+               ret = true;
+       }
+
+       return ret;
+}
+
+#ifdef IXGBE_FCOE
+/**
+ * ixgbe_cache_ring_fcoe - Descriptor ring to register mapping for the FCoE
+ * @adapter: board private structure to initialize
+ *
+ * Cache the descriptor ring offsets for FCoE mode to the assigned rings.
+ *
+ */
+static inline bool ixgbe_cache_ring_fcoe(struct ixgbe_adapter *adapter)
+{
+       int i, fcoe_i = 0;
+       bool ret = false;
+       struct ixgbe_ring_feature *f = &adapter->ring_feature[RING_F_FCOE];
+
+       if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) {
+#ifdef CONFIG_IXGBE_DCB
+               if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
+                       ixgbe_cache_ring_dcb(adapter);
+                       fcoe_i = adapter->rx_ring[0].reg_idx + 1;
+               }
+#endif /* CONFIG_IXGBE_DCB */
+               if (adapter->flags & IXGBE_FLAG_RSS_ENABLED) {
+                       ixgbe_cache_ring_rss(adapter);
+                       fcoe_i = f->mask;
+               }
+               for (i = 0; i < f->indices; i++, fcoe_i++)
+                       adapter->rx_ring[f->mask + i].reg_idx = fcoe_i;
+               ret = true;
+       }
+       return ret;
+}
+
+#endif /* IXGBE_FCOE */
 /**
  * ixgbe_cache_ring_register - Descriptor ring to register mapping
  * @adapter: board private structure to initialize
@@ -2918,11 +3404,19 @@ static void ixgbe_cache_ring_register(struct ixgbe_adapter *adapter)
        adapter->rx_ring[0].reg_idx = 0;
        adapter->tx_ring[0].reg_idx = 0;
 
+#ifdef IXGBE_FCOE
+       if (ixgbe_cache_ring_fcoe(adapter))
+               return;
+
+#endif /* IXGBE_FCOE */
 #ifdef CONFIG_IXGBE_DCB
        if (ixgbe_cache_ring_dcb(adapter))
                return;
 
 #endif
+       if (ixgbe_cache_ring_fdir(adapter))
+               return;
+
        if (ixgbe_cache_ring_rss(adapter))
                return;
 }
@@ -3004,31 +3498,23 @@ static int ixgbe_set_interrupt_capability(struct ixgbe_adapter *adapter)
         * mean we disable MSI-X capabilities of the adapter. */
        adapter->msix_entries = kcalloc(v_budget,
                                        sizeof(struct msix_entry), GFP_KERNEL);
-       if (!adapter->msix_entries) {
-               adapter->flags &= ~IXGBE_FLAG_DCB_ENABLED;
-               adapter->flags &= ~IXGBE_FLAG_RSS_ENABLED;
-               ixgbe_set_num_queues(adapter);
-               kfree(adapter->tx_ring);
-               kfree(adapter->rx_ring);
-               err = ixgbe_alloc_queues(adapter);
-               if (err) {
-                       DPRINTK(PROBE, ERR, "Unable to allocate memory "
-                               "for queues\n");
-                       goto out;
-               }
+       if (adapter->msix_entries) {
+               for (vector = 0; vector < v_budget; vector++)
+                       adapter->msix_entries[vector].entry = vector;
 
-               goto try_msi;
-       }
+               ixgbe_acquire_msix_vectors(adapter, v_budget);
 
-       for (vector = 0; vector < v_budget; vector++)
-               adapter->msix_entries[vector].entry = vector;
-
-       ixgbe_acquire_msix_vectors(adapter, v_budget);
+               if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED)
+                       goto out;
+       }
 
-       if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED)
-               goto out;
+       adapter->flags &= ~IXGBE_FLAG_DCB_ENABLED;
+       adapter->flags &= ~IXGBE_FLAG_RSS_ENABLED;
+       adapter->flags &= ~IXGBE_FLAG_FDIR_HASH_CAPABLE;
+       adapter->flags &= ~IXGBE_FLAG_FDIR_PERFECT_CAPABLE;
+       adapter->atr_sample_rate = 0;
+       ixgbe_set_num_queues(adapter);
 
-try_msi:
        err = pci_enable_msi(adapter->pdev);
        if (!err) {
                adapter->flags |= IXGBE_FLAG_MSI_ENABLED;
@@ -3043,6 +3529,79 @@ out:
        return err;
 }
 
+/**
+ * ixgbe_alloc_q_vectors - Allocate memory for interrupt vectors
+ * @adapter: board private structure to initialize
+ *
+ * We allocate one q_vector per queue interrupt.  If allocation fails we
+ * return -ENOMEM.
+ **/
+static int ixgbe_alloc_q_vectors(struct ixgbe_adapter *adapter)
+{
+       int q_idx, num_q_vectors;
+       struct ixgbe_q_vector *q_vector;
+       int napi_vectors;
+       int (*poll)(struct napi_struct *, int);
+
+       if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
+               num_q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
+               napi_vectors = adapter->num_rx_queues;
+               poll = &ixgbe_clean_rxtx_many;
+       } else {
+               num_q_vectors = 1;
+               napi_vectors = 1;
+               poll = &ixgbe_poll;
+       }
+
+       for (q_idx = 0; q_idx < num_q_vectors; q_idx++) {
+               q_vector = kzalloc(sizeof(struct ixgbe_q_vector), GFP_KERNEL);
+               if (!q_vector)
+                       goto err_out;
+               q_vector->adapter = adapter;
+               q_vector->eitr = adapter->eitr_param;
+               q_vector->v_idx = q_idx;
+               netif_napi_add(adapter->netdev, &q_vector->napi, (*poll), 64);
+               adapter->q_vector[q_idx] = q_vector;
+       }
+
+       return 0;
+
+err_out:
+       while (q_idx) {
+               q_idx--;
+               q_vector = adapter->q_vector[q_idx];
+               netif_napi_del(&q_vector->napi);
+               kfree(q_vector);
+               adapter->q_vector[q_idx] = NULL;
+       }
+       return -ENOMEM;
+}
+
+/**
+ * ixgbe_free_q_vectors - Free memory allocated for interrupt vectors
+ * @adapter: board private structure to initialize
+ *
+ * This function frees the memory allocated to the q_vectors.  In addition if
+ * NAPI is enabled it will delete any references to the NAPI struct prior
+ * to freeing the q_vector.
+ **/
+static void ixgbe_free_q_vectors(struct ixgbe_adapter *adapter)
+{
+       int q_idx, num_q_vectors;
+
+       if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED)
+               num_q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
+       else
+               num_q_vectors = 1;
+
+       for (q_idx = 0; q_idx < num_q_vectors; q_idx++) {
+               struct ixgbe_q_vector *q_vector = adapter->q_vector[q_idx];
+               adapter->q_vector[q_idx] = NULL;
+               netif_napi_del(&q_vector->napi);
+               kfree(q_vector);
+       }
+}
+
 void ixgbe_reset_interrupt_capability(struct ixgbe_adapter *adapter)
 {
        if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
@@ -3074,18 +3633,25 @@ int ixgbe_init_interrupt_scheme(struct ixgbe_adapter *adapter)
        /* Number of supported queues */
        ixgbe_set_num_queues(adapter);
 
-       err = ixgbe_alloc_queues(adapter);
-       if (err) {
-               DPRINTK(PROBE, ERR, "Unable to allocate memory for queues\n");
-               goto err_alloc_queues;
-       }
-
        err = ixgbe_set_interrupt_capability(adapter);
        if (err) {
                DPRINTK(PROBE, ERR, "Unable to setup interrupt capabilities\n");
                goto err_set_interrupt;
        }
 
+       err = ixgbe_alloc_q_vectors(adapter);
+       if (err) {
+               DPRINTK(PROBE, ERR, "Unable to allocate memory for queue "
+                       "vectors\n");
+               goto err_alloc_q_vectors;
+       }
+
+       err = ixgbe_alloc_queues(adapter);
+       if (err) {
+               DPRINTK(PROBE, ERR, "Unable to allocate memory for queues\n");
+               goto err_alloc_queues;
+       }
+
        DPRINTK(DRV, INFO, "Multiqueue %s: Rx Queue count = %u, "
                "Tx Queue count = %u\n",
                (adapter->num_rx_queues > 1) ? "Enabled" :
@@ -3095,11 +3661,30 @@ int ixgbe_init_interrupt_scheme(struct ixgbe_adapter *adapter)
 
        return 0;
 
+err_alloc_queues:
+       ixgbe_free_q_vectors(adapter);
+err_alloc_q_vectors:
+       ixgbe_reset_interrupt_capability(adapter);
 err_set_interrupt:
+       return err;
+}
+
+/**
+ * ixgbe_clear_interrupt_scheme - Clear the current interrupt scheme settings
+ * @adapter: board private structure to clear interrupt scheme on
+ *
+ * We go through and clear interrupt specific resources and reset the structure
+ * to pre-load conditions
+ **/
+void ixgbe_clear_interrupt_scheme(struct ixgbe_adapter *adapter)
+{
        kfree(adapter->tx_ring);
        kfree(adapter->rx_ring);
-err_alloc_queues:
-       return err;
+       adapter->tx_ring = NULL;
+       adapter->rx_ring = NULL;
+
+       ixgbe_free_q_vectors(adapter);
+       ixgbe_reset_interrupt_capability(adapter);
 }
 
 /**
@@ -3185,10 +3770,24 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter)
        adapter->ring_feature[RING_F_RSS].indices = rss;
        adapter->flags |= IXGBE_FLAG_RSS_ENABLED;
        adapter->ring_feature[RING_F_DCB].indices = IXGBE_MAX_DCB_INDICES;
-       if (hw->mac.type == ixgbe_mac_82598EB)
+       if (hw->mac.type == ixgbe_mac_82598EB) {
+               if (hw->device_id == IXGBE_DEV_ID_82598AT)
+                       adapter->flags |= IXGBE_FLAG_FAN_FAIL_CAPABLE;
                adapter->max_msix_q_vectors = MAX_MSIX_Q_VECTORS_82598;
-       else if (hw->mac.type == ixgbe_mac_82599EB)
+       } else if (hw->mac.type == ixgbe_mac_82599EB) {
                adapter->max_msix_q_vectors = MAX_MSIX_Q_VECTORS_82599;
+               adapter->flags |= IXGBE_FLAG2_RSC_CAPABLE;
+               adapter->flags |= IXGBE_FLAG2_RSC_ENABLED;
+               adapter->flags |= IXGBE_FLAG_FDIR_HASH_CAPABLE;
+               adapter->ring_feature[RING_F_FDIR].indices =
+                                                        IXGBE_MAX_FDIR_INDICES;
+               adapter->atr_sample_rate = 20;
+               adapter->fdir_pballoc = 0;
+#ifdef IXGBE_FCOE
+               adapter->flags |= IXGBE_FLAG_FCOE_ENABLED;
+               adapter->ring_feature[RING_F_FCOE].indices = IXGBE_FCRETA_SIZE;
+#endif /* IXGBE_FCOE */
+       }
 
 #ifdef CONFIG_IXGBE_DCB
        /* Configure DCB traffic classes */
@@ -3203,6 +3802,7 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter)
        adapter->dcb_cfg.bw_percentage[DCB_TX_CONFIG][0] = 100;
        adapter->dcb_cfg.bw_percentage[DCB_RX_CONFIG][0] = 100;
        adapter->dcb_cfg.rx_pba_cfg = pba_equal;
+       adapter->dcb_cfg.pfc_mode_enable = false;
        adapter->dcb_cfg.round_robin_enable = false;
        adapter->dcb_set_bitmap = 0x00;
        ixgbe_copy_dcb_cfg(&adapter->dcb_cfg, &adapter->temp_dcb_cfg,
@@ -3213,6 +3813,9 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter)
        /* default flow control settings */
        hw->fc.requested_mode = ixgbe_fc_full;
        hw->fc.current_mode = ixgbe_fc_full;    /* init for ethtool output */
+#ifdef CONFIG_DCB
+       adapter->last_lfc_mode = hw->fc.current_mode;
+#endif
        hw->fc.high_water = IXGBE_DEFAULT_FCRTH;
        hw->fc.low_water = IXGBE_DEFAULT_FCRTL;
        hw->fc.pause_time = IXGBE_DEFAULT_FCPAUSE;
@@ -3503,6 +4106,8 @@ static int ixgbe_open(struct net_device *netdev)
        if (test_bit(__IXGBE_TESTING, &adapter->state))
                return -EBUSY;
 
+       netif_carrier_off(netdev);
+
        /* allocate transmit descriptors */
        err = ixgbe_setup_all_tx_resources(adapter);
        if (err)
@@ -3515,8 +4120,6 @@ static int ixgbe_open(struct net_device *netdev)
 
        ixgbe_configure(adapter);
 
-       ixgbe_napi_add_all(adapter);
-
        err = ixgbe_request_irq(adapter);
        if (err)
                goto err_req_irq;
@@ -3568,55 +4171,6 @@ static int ixgbe_close(struct net_device *netdev)
        return 0;
 }
 
-/**
- * ixgbe_napi_add_all - prep napi structs for use
- * @adapter: private struct
- *
- * helper function to napi_add each possible q_vector->napi
- */
-void ixgbe_napi_add_all(struct ixgbe_adapter *adapter)
-{
-       int q_idx, q_vectors;
-       struct net_device *netdev = adapter->netdev;
-       int (*poll)(struct napi_struct *, int);
-
-       /* check if we already have our netdev->napi_list populated */
-       if (&netdev->napi_list != netdev->napi_list.next)
-               return;
-
-       if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
-               poll = &ixgbe_clean_rxonly;
-               /* Only enable as many vectors as we have rx queues. */
-               q_vectors = adapter->num_rx_queues;
-       } else {
-               poll = &ixgbe_poll;
-               /* only one q_vector for legacy modes */
-               q_vectors = 1;
-       }
-
-       for (q_idx = 0; q_idx < q_vectors; q_idx++) {
-               struct ixgbe_q_vector *q_vector = &adapter->q_vector[q_idx];
-               netif_napi_add(adapter->netdev, &q_vector->napi, (*poll), 64);
-       }
-}
-
-void ixgbe_napi_del_all(struct ixgbe_adapter *adapter)
-{
-       int q_idx;
-       int q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
-
-       /* legacy and MSI only use one vector */
-       if (!(adapter->flags & IXGBE_FLAG_MSIX_ENABLED))
-               q_vectors = 1;
-
-       for (q_idx = 0; q_idx < q_vectors; q_idx++) {
-               struct ixgbe_q_vector *q_vector = &adapter->q_vector[q_idx];
-               if (!q_vector->rxr_count)
-                       continue;
-               netif_napi_del(&q_vector->napi);
-       }
-}
-
 #ifdef CONFIG_PM
 static int ixgbe_resume(struct pci_dev *pdev)
 {
@@ -3626,7 +4180,8 @@ static int ixgbe_resume(struct pci_dev *pdev)
 
        pci_set_power_state(pdev, PCI_D0);
        pci_restore_state(pdev);
-       err = pci_enable_device(pdev);
+
+       err = pci_enable_device_mem(pdev);
        if (err) {
                printk(KERN_ERR "ixgbe: Cannot enable PCI device from "
                                "suspend\n");
@@ -3634,8 +4189,7 @@ static int ixgbe_resume(struct pci_dev *pdev)
        }
        pci_set_master(pdev);
 
-       pci_enable_wake(pdev, PCI_D3hot, 0);
-       pci_enable_wake(pdev, PCI_D3cold, 0);
+       pci_wake_from_d3(pdev, false);
 
        err = ixgbe_init_interrupt_scheme(adapter);
        if (err) {
@@ -3679,11 +4233,7 @@ static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake)
                ixgbe_free_all_tx_resources(adapter);
                ixgbe_free_all_rx_resources(adapter);
        }
-       ixgbe_reset_interrupt_capability(adapter);
-       ixgbe_napi_del_all(adapter);
-       INIT_LIST_HEAD(&netdev->napi_list);
-       kfree(adapter->tx_ring);
-       kfree(adapter->rx_ring);
+       ixgbe_clear_interrupt_scheme(adapter);
 
 #ifdef CONFIG_PM
        retval = pci_save_state(pdev);
@@ -3711,13 +4261,10 @@ static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake)
                IXGBE_WRITE_REG(hw, IXGBE_WUFC, 0);
        }
 
-       if (wufc && hw->mac.type == ixgbe_mac_82599EB) {
-               pci_enable_wake(pdev, PCI_D3hot, 1);
-               pci_enable_wake(pdev, PCI_D3cold, 1);
-       } else {
-               pci_enable_wake(pdev, PCI_D3hot, 0);
-               pci_enable_wake(pdev, PCI_D3cold, 0);
-       }
+       if (wufc && hw->mac.type == ixgbe_mac_82599EB)
+               pci_wake_from_d3(pdev, true);
+       else
+               pci_wake_from_d3(pdev, false);
 
        *enable_wake = !!wufc;
 
@@ -3772,9 +4319,13 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter)
        u32 i, missed_rx = 0, mpc, bprc, lxon, lxoff, xon_off_tot;
 
        if (hw->mac.type == ixgbe_mac_82599EB) {
+               u64 rsc_count = 0;
                for (i = 0; i < 16; i++)
                        adapter->hw_rx_no_dma_resources +=
                                             IXGBE_READ_REG(hw, IXGBE_QPRDC(i));
+               for (i = 0; i < adapter->num_rx_queues; i++)
+                       rsc_count += adapter->rx_ring[i].rsc_count;
+               adapter->rsc_count = rsc_count;
        }
 
        adapter->stats.crcerrs += IXGBE_READ_REG(hw, IXGBE_CRCERRS);
@@ -3821,6 +4372,16 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter)
                IXGBE_READ_REG(hw, IXGBE_TORH); /* to clear */
                adapter->stats.lxonrxc += IXGBE_READ_REG(hw, IXGBE_LXONRXCNT);
                adapter->stats.lxoffrxc += IXGBE_READ_REG(hw, IXGBE_LXOFFRXCNT);
+               adapter->stats.fdirmatch += IXGBE_READ_REG(hw, IXGBE_FDIRMATCH);
+               adapter->stats.fdirmiss += IXGBE_READ_REG(hw, IXGBE_FDIRMISS);
+#ifdef IXGBE_FCOE
+               adapter->stats.fccrc += IXGBE_READ_REG(hw, IXGBE_FCCRC);
+               adapter->stats.fcoerpdc += IXGBE_READ_REG(hw, IXGBE_FCOERPDC);
+               adapter->stats.fcoeprc += IXGBE_READ_REG(hw, IXGBE_FCOEPRC);
+               adapter->stats.fcoeptc += IXGBE_READ_REG(hw, IXGBE_FCOEPTC);
+               adapter->stats.fcoedwrc += IXGBE_READ_REG(hw, IXGBE_FCOEDWRC);
+               adapter->stats.fcoedwtc += IXGBE_READ_REG(hw, IXGBE_FCOEDWTC);
+#endif /* IXGBE_FCOE */
        } else {
                adapter->stats.lxonrxc += IXGBE_READ_REG(hw, IXGBE_LXONRXC);
                adapter->stats.lxoffrxc += IXGBE_READ_REG(hw, IXGBE_LXOFFRXC);
@@ -3888,64 +4449,43 @@ static void ixgbe_watchdog(unsigned long data)
 {
        struct ixgbe_adapter *adapter = (struct ixgbe_adapter *)data;
        struct ixgbe_hw *hw = &adapter->hw;
+       u64 eics = 0;
+       int i;
 
-       /* Do the watchdog outside of interrupt context due to the lovely
-        * delays that some of the newer hardware requires */
-       if (!test_bit(__IXGBE_DOWN, &adapter->state)) {
-               u64 eics = 0;
-               int i;
+       /*
+        *  Do the watchdog outside of interrupt context due to the lovely
+        * delays that some of the newer hardware requires
+        */
 
-               for (i = 0; i < adapter->num_msix_vectors - NON_Q_VECTORS; i++)
-                       eics |= (1 << i);
+       if (test_bit(__IXGBE_DOWN, &adapter->state))
+               goto watchdog_short_circuit;
 
-               /* Cause software interrupt to ensure rx rings are cleaned */
-               switch (hw->mac.type) {
-               case ixgbe_mac_82598EB:
-                       if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
-                               IXGBE_WRITE_REG(hw, IXGBE_EICS, (u32)eics);
-                       } else {
-                               /*
-                                * for legacy and MSI interrupts don't set any
-                                * bits that are enabled for EIAM, because this
-                                * operation would set *both* EIMS and EICS for
-                                * any bit in EIAM
-                                */
-                               IXGBE_WRITE_REG(hw, IXGBE_EICS,
-                                    (IXGBE_EICS_TCP_TIMER | IXGBE_EICS_OTHER));
-                       }
-                       break;
-               case ixgbe_mac_82599EB:
-                       if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
-                               /*
-                                * EICS(0..15) first 0-15 q vectors
-                                * EICS[1] (16..31) q vectors 16-31
-                                * EICS[2] (0..31) q vectors 32-63
-                                */
-                               IXGBE_WRITE_REG(hw, IXGBE_EICS,
-                                               (u32)(eics & 0xFFFF));
-                               IXGBE_WRITE_REG(hw, IXGBE_EICS_EX(1),
-                                               (u32)(eics & 0xFFFF0000));
-                               IXGBE_WRITE_REG(hw, IXGBE_EICS_EX(2),
-                                               (u32)(eics >> 32));
-                       } else {
-                               /*
-                                * for legacy and MSI interrupts don't set any
-                                * bits that are enabled for EIAM, because this
-                                * operation would set *both* EIMS and EICS for
-                                * any bit in EIAM
-                                */
-                               IXGBE_WRITE_REG(hw, IXGBE_EICS,
-                                    (IXGBE_EICS_TCP_TIMER | IXGBE_EICS_OTHER));
-                       }
-                       break;
-               default:
-                       break;
-               }
-               /* Reset the timer */
-               mod_timer(&adapter->watchdog_timer,
-                         round_jiffies(jiffies + 2 * HZ));
+       if (!(adapter->flags & IXGBE_FLAG_MSIX_ENABLED)) {
+               /*
+                * for legacy and MSI interrupts don't set any bits
+                * that are enabled for EIAM, because this operation
+                * would set *both* EIMS and EICS for any bit in EIAM
+                */
+               IXGBE_WRITE_REG(hw, IXGBE_EICS,
+                       (IXGBE_EICS_TCP_TIMER | IXGBE_EICS_OTHER));
+               goto watchdog_reschedule;
        }
 
+       /* get one bit for every active tx/rx interrupt vector */
+       for (i = 0; i < adapter->num_msix_vectors - NON_Q_VECTORS; i++) {
+               struct ixgbe_q_vector *qv = adapter->q_vector[i];
+               if (qv->rxr_count || qv->txr_count)
+                       eics |= ((u64)1 << i);
+       }
+
+       /* Cause software interrupt to ensure rx rings are cleaned */
+       ixgbe_irq_rearm_queues(adapter, eics);
+
+watchdog_reschedule:
+       /* Reset the timer */
+       mod_timer(&adapter->watchdog_timer, round_jiffies(jiffies + 2 * HZ));
+
+watchdog_short_circuit:
        schedule_work(&adapter->watchdog_task);
 }
 
@@ -3998,6 +4538,30 @@ static void ixgbe_sfp_config_module_task(struct work_struct *work)
        adapter->flags &= ~IXGBE_FLAG_IN_SFP_MOD_TASK;
 }
 
+/**
+ * ixgbe_fdir_reinit_task - worker thread to reinit FDIR filter table
+ * @work: pointer to work_struct containing our data
+ **/
+static void ixgbe_fdir_reinit_task(struct work_struct *work)
+{
+       struct ixgbe_adapter *adapter = container_of(work,
+                                                    struct ixgbe_adapter,
+                                                    fdir_reinit_task);
+       struct ixgbe_hw *hw = &adapter->hw;
+       int i;
+
+       if (ixgbe_reinit_fdir_tables_82599(hw) == 0) {
+               for (i = 0; i < adapter->num_tx_queues; i++)
+                       set_bit(__IXGBE_FDIR_INIT_DONE,
+                               &(adapter->tx_ring[i].reinit_state));
+       } else {
+               DPRINTK(PROBE, ERR, "failed to finish FDIR re-initialization, "
+                       "ignored adding FDIR ATR filters \n");
+       }
+       /* Done FDIR Re-initialization, enable transmits */
+       netif_tx_start_all_queues(adapter->netdev);
+}
+
 /**
  * ixgbe_watchdog_task - worker thread to bring link up
  * @work: pointer to work_struct containing our data
@@ -4011,16 +4575,32 @@ static void ixgbe_watchdog_task(struct work_struct *work)
        struct ixgbe_hw *hw = &adapter->hw;
        u32 link_speed = adapter->link_speed;
        bool link_up = adapter->link_up;
+       int i;
+       struct ixgbe_ring *tx_ring;
+       int some_tx_pending = 0;
 
        adapter->flags |= IXGBE_FLAG_IN_WATCHDOG_TASK;
 
        if (adapter->flags & IXGBE_FLAG_NEED_LINK_UPDATE) {
                hw->mac.ops.check_link(hw, &link_speed, &link_up, false);
+               if (link_up) {
+#ifdef CONFIG_DCB
+                       if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
+                               for (i = 0; i < MAX_TRAFFIC_CLASS; i++)
+                                       hw->mac.ops.fc_enable(hw, i);
+                       } else {
+                               hw->mac.ops.fc_enable(hw, 0);
+                       }
+#else
+                       hw->mac.ops.fc_enable(hw, 0);
+#endif
+               }
+
                if (link_up ||
                    time_after(jiffies, (adapter->link_check_timeout +
                                         IXGBE_TRY_LINK_TIMEOUT))) {
-                       IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMC_LSC);
                        adapter->flags &= ~IXGBE_FLAG_NEED_LINK_UPDATE;
+                       IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMC_LSC);
                }
                adapter->link_up = link_up;
                adapter->link_speed = link_speed;
@@ -4068,6 +4648,25 @@ static void ixgbe_watchdog_task(struct work_struct *work)
                }
        }
 
+       if (!netif_carrier_ok(netdev)) {
+               for (i = 0; i < adapter->num_tx_queues; i++) {
+                       tx_ring = &adapter->tx_ring[i];
+                       if (tx_ring->next_to_use != tx_ring->next_to_clean) {
+                               some_tx_pending = 1;
+                               break;
+                       }
+               }
+
+               if (some_tx_pending) {
+                       /* We've lost link, so the controller stops DMA,
+                        * but we've got queued Tx work that's never going
+                        * to get done, so reset controller to flush Tx.
+                        * (Do the reset outside of interrupt context).
+                        */
+                        schedule_work(&adapter->reset_task);
+               }
+       }
+
        ixgbe_update_stats(adapter);
        adapter->flags &= ~IXGBE_FLAG_IN_WATCHDOG_TASK;
 }
@@ -4196,12 +4795,18 @@ static bool ixgbe_tx_csum(struct ixgbe_adapter *adapter,
                                if (ip_hdr(skb)->protocol == IPPROTO_TCP)
                                        type_tucmd_mlhl |=
                                                IXGBE_ADVTXD_TUCMD_L4T_TCP;
+                               else if (ip_hdr(skb)->protocol == IPPROTO_SCTP)
+                                       type_tucmd_mlhl |=
+                                               IXGBE_ADVTXD_TUCMD_L4T_SCTP;
                                break;
                        case cpu_to_be16(ETH_P_IPV6):
                                /* XXX what about other V6 headers?? */
                                if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP)
                                        type_tucmd_mlhl |=
                                                IXGBE_ADVTXD_TUCMD_L4T_TCP;
+                               else if (ipv6_hdr(skb)->nexthdr == IPPROTO_SCTP)
+                                       type_tucmd_mlhl |=
+                                               IXGBE_ADVTXD_TUCMD_L4T_SCTP;
                                break;
                        default:
                                if (unlikely(net_ratelimit())) {
@@ -4234,10 +4839,12 @@ static bool ixgbe_tx_csum(struct ixgbe_adapter *adapter,
 
 static int ixgbe_tx_map(struct ixgbe_adapter *adapter,
                         struct ixgbe_ring *tx_ring,
-                        struct sk_buff *skb, unsigned int first)
+                        struct sk_buff *skb, u32 tx_flags,
+                        unsigned int first)
 {
        struct ixgbe_tx_buffer *tx_buffer_info;
-       unsigned int len = skb_headlen(skb);
+       unsigned int len;
+       unsigned int total = skb->len;
        unsigned int offset = 0, size, count = 0, i;
        unsigned int nr_frags = skb_shinfo(skb)->nr_frags;
        unsigned int f;
@@ -4252,16 +4859,22 @@ static int ixgbe_tx_map(struct ixgbe_adapter *adapter,
 
        map = skb_shinfo(skb)->dma_maps;
 
+       if (tx_flags & IXGBE_TX_FLAGS_FCOE)
+               /* excluding fcoe_crc_eof for FCoE */
+               total -= sizeof(struct fcoe_crc_eof);
+
+       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->dma = map[0] + offset;
+               tx_buffer_info->dma = skb_shinfo(skb)->dma_head + offset;
                tx_buffer_info->time_stamp = jiffies;
                tx_buffer_info->next_to_watch = i;
 
                len -= size;
+               total -= size;
                offset += size;
                count++;
 
@@ -4276,7 +4889,7 @@ static int ixgbe_tx_map(struct ixgbe_adapter *adapter,
                struct skb_frag_struct *frag;
 
                frag = &skb_shinfo(skb)->frags[f];
-               len = frag->size;
+               len = min((unsigned int)frag->size, total);
                offset = 0;
 
                while (len) {
@@ -4288,14 +4901,17 @@ static int ixgbe_tx_map(struct ixgbe_adapter *adapter,
                        size = min(len, (uint)IXGBE_MAX_DATA_PER_TXD);
 
                        tx_buffer_info->length = size;
-                       tx_buffer_info->dma = map[f + 1] + offset;
+                       tx_buffer_info->dma = map[f] + offset;
                        tx_buffer_info->time_stamp = jiffies;
                        tx_buffer_info->next_to_watch = i;
 
                        len -= size;
+                       total -= size;
                        offset += size;
                        count++;
                }
+               if (total == 0)
+                       break;
        }
 
        tx_ring->tx_buffer_info[i].skb = skb;
@@ -4337,6 +4953,13 @@ static void ixgbe_tx_queue(struct ixgbe_adapter *adapter,
                olinfo_status |= IXGBE_TXD_POPTS_TXSM <<
                                 IXGBE_ADVTXD_POPTS_SHIFT;
 
+       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;
+       }
+
        olinfo_status |= ((paylen - hdr_len) << IXGBE_ADVTXD_PAYLEN_SHIFT);
 
        i = tx_ring->next_to_use;
@@ -4366,6 +4989,58 @@ static void ixgbe_tx_queue(struct ixgbe_adapter *adapter,
        writel(i, adapter->hw.hw_addr + tx_ring->tail);
 }
 
+static void ixgbe_atr(struct ixgbe_adapter *adapter, struct sk_buff *skb,
+                     int queue, u32 tx_flags)
+{
+       /* Right now, we support IPv4 only */
+       struct ixgbe_atr_input atr_input;
+       struct tcphdr *th;
+       struct udphdr *uh;
+       struct iphdr *iph = ip_hdr(skb);
+       struct ethhdr *eth = (struct ethhdr *)skb->data;
+       u16 vlan_id, src_port, dst_port, flex_bytes;
+       u32 src_ipv4_addr, dst_ipv4_addr;
+       u8 l4type = 0;
+
+       /* check if we're UDP or TCP */
+       if (iph->protocol == IPPROTO_TCP) {
+               th = tcp_hdr(skb);
+               src_port = th->source;
+               dst_port = th->dest;
+               l4type |= IXGBE_ATR_L4TYPE_TCP;
+               /* l4type IPv4 type is 0, no need to assign */
+       } else if(iph->protocol == IPPROTO_UDP) {
+               uh = udp_hdr(skb);
+               src_port = uh->source;
+               dst_port = uh->dest;
+               l4type |= IXGBE_ATR_L4TYPE_UDP;
+               /* l4type IPv4 type is 0, no need to assign */
+       } else {
+               /* Unsupported L4 header, just bail here */
+               return;
+       }
+
+       memset(&atr_input, 0, sizeof(struct ixgbe_atr_input));
+
+       vlan_id = (tx_flags & IXGBE_TX_FLAGS_VLAN_MASK) >>
+                  IXGBE_TX_FLAGS_VLAN_SHIFT;
+       src_ipv4_addr = iph->saddr;
+       dst_ipv4_addr = iph->daddr;
+       flex_bytes = eth->h_proto;
+
+       ixgbe_atr_set_vlan_id_82599(&atr_input, vlan_id);
+       ixgbe_atr_set_src_port_82599(&atr_input, dst_port);
+       ixgbe_atr_set_dst_port_82599(&atr_input, src_port);
+       ixgbe_atr_set_flex_byte_82599(&atr_input, flex_bytes);
+       ixgbe_atr_set_l4type_82599(&atr_input, l4type);
+       /* src and dst are inverted, think how the receiver sees them */
+       ixgbe_atr_set_src_ipv4_82599(&atr_input, dst_ipv4_addr);
+       ixgbe_atr_set_dst_ipv4_82599(&atr_input, src_ipv4_addr);
+
+       /* This assumes the Rx queue and Tx queue are bound to the same CPU */
+       ixgbe_fdir_add_signature_filter_82599(&adapter->hw, &atr_input, queue);
+}
+
 static int __ixgbe_maybe_stop_tx(struct net_device *netdev,
                                  struct ixgbe_ring *tx_ring, int size)
 {
@@ -4400,6 +5075,9 @@ static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb)
 {
        struct ixgbe_adapter *adapter = netdev_priv(dev);
 
+       if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE)
+               return smp_processor_id();
+
        if (adapter->flags & IXGBE_FLAG_DCB_ENABLED)
                return 0;  /* All traffic should default to class 0 */
 
@@ -4433,10 +5111,16 @@ static int ixgbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
                tx_flags <<= IXGBE_TX_FLAGS_VLAN_SHIFT;
                tx_flags |= IXGBE_TX_FLAGS_VLAN;
        }
-       /* three things can cause us to need a context descriptor */
+
+       if ((adapter->flags & IXGBE_FLAG_FCOE_ENABLED) &&
+           (skb->protocol == htons(ETH_P_FCOE)))
+               tx_flags |= IXGBE_TX_FLAGS_FCOE;
+
+       /* four things can cause us to need a context descriptor */
        if (skb_is_gso(skb) ||
            (skb->ip_summed == CHECKSUM_PARTIAL) ||
-           (tx_flags & IXGBE_TX_FLAGS_VLAN))
+           (tx_flags & IXGBE_TX_FLAGS_VLAN) ||
+           (tx_flags & IXGBE_TX_FLAGS_FCOE))
                count++;
 
        count += TXD_USE_COUNT(skb_headlen(skb));
@@ -4448,27 +5132,49 @@ static int ixgbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
                return NETDEV_TX_BUSY;
        }
 
-       if (skb->protocol == htons(ETH_P_IP))
-               tx_flags |= IXGBE_TX_FLAGS_IPV4;
        first = tx_ring->next_to_use;
-       tso = ixgbe_tso(adapter, tx_ring, skb, tx_flags, &hdr_len);
-       if (tso < 0) {
-               dev_kfree_skb_any(skb);
-               return NETDEV_TX_OK;
-       }
-
-       if (tso)
-               tx_flags |= IXGBE_TX_FLAGS_TSO;
-       else if (ixgbe_tx_csum(adapter, tx_ring, skb, tx_flags) &&
-                (skb->ip_summed == CHECKSUM_PARTIAL))
-               tx_flags |= IXGBE_TX_FLAGS_CSUM;
+       if (tx_flags & IXGBE_TX_FLAGS_FCOE) {
+#ifdef IXGBE_FCOE
+               /* setup tx offload for FCoE */
+               tso = ixgbe_fso(adapter, tx_ring, skb, tx_flags, &hdr_len);
+               if (tso < 0) {
+                       dev_kfree_skb_any(skb);
+                       return NETDEV_TX_OK;
+               }
+               if (tso)
+                       tx_flags |= IXGBE_TX_FLAGS_FSO;
+#endif /* IXGBE_FCOE */
+       } else {
+               if (skb->protocol == htons(ETH_P_IP))
+                       tx_flags |= IXGBE_TX_FLAGS_IPV4;
+               tso = ixgbe_tso(adapter, tx_ring, skb, tx_flags, &hdr_len);
+               if (tso < 0) {
+                       dev_kfree_skb_any(skb);
+                       return NETDEV_TX_OK;
+               }
 
-       count = ixgbe_tx_map(adapter, tx_ring, skb, first);
+               if (tso)
+                       tx_flags |= IXGBE_TX_FLAGS_TSO;
+               else if (ixgbe_tx_csum(adapter, tx_ring, skb, tx_flags) &&
+                        (skb->ip_summed == CHECKSUM_PARTIAL))
+                       tx_flags |= IXGBE_TX_FLAGS_CSUM;
+       }
 
+       count = ixgbe_tx_map(adapter, tx_ring, skb, tx_flags, first);
        if (count) {
+               /* add the ATR filter if ATR is on */
+               if (tx_ring->atr_sample_rate) {
+                       ++tx_ring->atr_count;
+                       if ((tx_ring->atr_count >= tx_ring->atr_sample_rate) &&
+                            test_bit(__IXGBE_FDIR_INIT_DONE,
+                                      &tx_ring->reinit_state)) {
+                               ixgbe_atr(adapter, skb, tx_ring->queue_index,
+                                         tx_flags);
+                               tx_ring->atr_count = 0;
+                       }
+               }
                ixgbe_tx_queue(adapter, tx_ring, tx_flags, count, skb->len,
                               hdr_len);
-               netdev->trans_start = jiffies;
                ixgbe_maybe_stop_tx(netdev, tx_ring, DESC_NEEDED);
 
        } else {
@@ -4519,6 +5225,82 @@ static int ixgbe_set_mac(struct net_device *netdev, void *p)
        return 0;
 }
 
+static int
+ixgbe_mdio_read(struct net_device *netdev, int prtad, int devad, u16 addr)
+{
+       struct ixgbe_adapter *adapter = netdev_priv(netdev);
+       struct ixgbe_hw *hw = &adapter->hw;
+       u16 value;
+       int rc;
+
+       if (prtad != hw->phy.mdio.prtad)
+               return -EINVAL;
+       rc = hw->phy.ops.read_reg(hw, addr, devad, &value);
+       if (!rc)
+               rc = value;
+       return rc;
+}
+
+static int ixgbe_mdio_write(struct net_device *netdev, int prtad, int devad,
+                           u16 addr, u16 value)
+{
+       struct ixgbe_adapter *adapter = netdev_priv(netdev);
+       struct ixgbe_hw *hw = &adapter->hw;
+
+       if (prtad != hw->phy.mdio.prtad)
+               return -EINVAL;
+       return hw->phy.ops.write_reg(hw, addr, devad, value);
+}
+
+static int ixgbe_ioctl(struct net_device *netdev, struct ifreq *req, int cmd)
+{
+       struct ixgbe_adapter *adapter = netdev_priv(netdev);
+
+       return mdio_mii_ioctl(&adapter->hw.phy.mdio, if_mii(req), cmd);
+}
+
+/**
+ * ixgbe_add_sanmac_netdev - Add the SAN MAC address to the corresponding
+ * netdev->dev_addr_list
+ * @netdev: network interface device structure
+ *
+ * Returns non-zero on failure
+ **/
+static int ixgbe_add_sanmac_netdev(struct net_device *dev)
+{
+       int err = 0;
+       struct ixgbe_adapter *adapter = netdev_priv(dev);
+       struct ixgbe_mac_info *mac = &adapter->hw.mac;
+
+       if (is_valid_ether_addr(mac->san_addr)) {
+               rtnl_lock();
+               err = dev_addr_add(dev, mac->san_addr, NETDEV_HW_ADDR_T_SAN);
+               rtnl_unlock();
+       }
+       return err;
+}
+
+/**
+ * ixgbe_del_sanmac_netdev - Removes the SAN MAC address to the corresponding
+ * netdev->dev_addr_list
+ * @netdev: network interface device structure
+ *
+ * Returns non-zero on failure
+ **/
+static int ixgbe_del_sanmac_netdev(struct net_device *dev)
+{
+       int err = 0;
+       struct ixgbe_adapter *adapter = netdev_priv(dev);
+       struct ixgbe_mac_info *mac = &adapter->hw.mac;
+
+       if (is_valid_ether_addr(mac->san_addr)) {
+               rtnl_lock();
+               err = dev_addr_del(dev, mac->san_addr, NETDEV_HW_ADDR_T_SAN);
+               rtnl_unlock();
+       }
+       return err;
+}
+
 #ifdef CONFIG_NET_POLL_CONTROLLER
 /*
  * Polling 'interrupt' - used by things like netconsole to send skbs
@@ -4552,9 +5334,14 @@ static const struct net_device_ops ixgbe_netdev_ops = {
        .ndo_vlan_rx_register   = ixgbe_vlan_rx_register,
        .ndo_vlan_rx_add_vid    = ixgbe_vlan_rx_add_vid,
        .ndo_vlan_rx_kill_vid   = ixgbe_vlan_rx_kill_vid,
+       .ndo_do_ioctl           = ixgbe_ioctl,
 #ifdef CONFIG_NET_POLL_CONTROLLER
        .ndo_poll_controller    = ixgbe_netpoll,
 #endif
+#ifdef IXGBE_FCOE
+       .ndo_fcoe_ddp_setup = ixgbe_fcoe_ddp_get,
+       .ndo_fcoe_ddp_done = ixgbe_fcoe_ddp_put,
+#endif /* IXGBE_FCOE */
 };
 
 /**
@@ -4577,9 +5364,12 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
        const struct ixgbe_info *ii = ixgbe_info_tbl[ent->driver_data];
        static int cards_found;
        int i, err, pci_using_dac;
+#ifdef IXGBE_FCOE
+       u16 device_caps;
+#endif
        u32 part_num, eec;
 
-       err = pci_enable_device(pdev);
+       err = pci_enable_device_mem(pdev);
        if (err)
                return err;
 
@@ -4599,9 +5389,11 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
                pci_using_dac = 0;
        }
 
-       err = pci_request_regions(pdev, ixgbe_driver_name);
+       err = pci_request_selected_regions(pdev, pci_select_bars(pdev,
+                                          IORESOURCE_MEM), ixgbe_driver_name);
        if (err) {
-               dev_err(&pdev->dev, "pci_request_regions failed 0x%x\n", err);
+               dev_err(&pdev->dev,
+                       "pci_request_selected_regions failed 0x%x\n", err);
                goto err_pci_reg;
        }
 
@@ -4665,6 +5457,13 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
        /* PHY */
        memcpy(&hw->phy.ops, ii->phy_ops, sizeof(hw->phy.ops));
        hw->phy.sfp_type = ixgbe_sfp_type_unknown;
+       /* ixgbe_identify_phy_generic will set prtad and mmds properly */
+       hw->phy.mdio.prtad = MDIO_PRTAD_NONE;
+       hw->phy.mdio.mmds = 0;
+       hw->phy.mdio.mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22;
+       hw->phy.mdio.dev = netdev;
+       hw->phy.mdio.mdio_read = ixgbe_mdio_read;
+       hw->phy.mdio.mdio_write = ixgbe_mdio_write;
 
        /* set up this timer and work struct before calling get_invariants
         * which might start the timer
@@ -4682,29 +5481,42 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
        INIT_WORK(&adapter->sfp_config_module_task,
                  ixgbe_sfp_config_module_task);
 
-       err = ii->get_invariants(hw);
-       if (err == IXGBE_ERR_SFP_NOT_PRESENT) {
-               /* start a kernel thread to watch for a module to arrive */
-               set_bit(__IXGBE_SFP_MODULE_NOT_FOUND, &adapter->state);
-               mod_timer(&adapter->sfp_timer,
-                         round_jiffies(jiffies + (2 * HZ)));
-               err = 0;
-       } else if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) {
-               DPRINTK(PROBE, ERR, "failed to load because an "
-                       "unsupported SFP+ module type was detected.\n");
-               goto err_hw_init;
-       } else if (err) {
-               goto err_hw_init;
-       }
+       ii->get_invariants(hw);
 
        /* setup the private structure */
        err = ixgbe_sw_init(adapter);
        if (err)
                goto err_sw_init;
 
+       /*
+        * If there is a fan on this device and it has failed log the
+        * failure.
+        */
+       if (adapter->flags & IXGBE_FLAG_FAN_FAIL_CAPABLE) {
+               u32 esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
+               if (esdp & IXGBE_ESDP_SDP1)
+                       DPRINTK(PROBE, CRIT,
+                               "Fan has stopped, replace the adapter\n");
+       }
+
        /* reset_hw fills in the perm_addr as well */
        err = hw->mac.ops.reset_hw(hw);
-       if (err) {
+       if (err == IXGBE_ERR_SFP_NOT_PRESENT &&
+           hw->mac.type == ixgbe_mac_82598EB) {
+               /*
+                * Start a kernel thread to watch for a module to arrive.
+                * Only do this for 82598, since 82599 will generate
+                * interrupts on module arrival.
+                */
+               set_bit(__IXGBE_SFP_MODULE_NOT_FOUND, &adapter->state);
+               mod_timer(&adapter->sfp_timer,
+                         round_jiffies(jiffies + (2 * HZ)));
+               err = 0;
+       } else if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) {
+               dev_err(&adapter->pdev->dev, "failed to load because an "
+                       "unsupported SFP+ module type was detected.\n");
+               goto err_sw_init;
+       } else if (err) {
                dev_err(&adapter->pdev->dev, "HW Init failed: %d\n", err);
                goto err_sw_init;
        }
@@ -4720,6 +5532,9 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
        netdev->features |= NETIF_F_TSO6;
        netdev->features |= NETIF_F_GRO;
 
+       if (adapter->hw.mac.type == ixgbe_mac_82599EB)
+               netdev->features |= NETIF_F_SCTP_CSUM;
+
        netdev->vlan_features |= NETIF_F_TSO;
        netdev->vlan_features |= NETIF_F_TSO6;
        netdev->vlan_features |= NETIF_F_IP_CSUM;
@@ -4732,9 +5547,32 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
        netdev->dcbnl_ops = &dcbnl_ops;
 #endif
 
+#ifdef IXGBE_FCOE
+       if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) {
+               if (hw->mac.ops.get_device_caps) {
+                       hw->mac.ops.get_device_caps(hw, &device_caps);
+                       if (!(device_caps & IXGBE_DEVICE_CAPS_FCOE_OFFLOADS)) {
+                               netdev->features |= NETIF_F_FCOE_CRC;
+                               netdev->features |= NETIF_F_FSO;
+                               netdev->fcoe_ddp_xid = IXGBE_FCOE_DDP_MAX - 1;
+                               DPRINTK(DRV, INFO, "FCoE enabled, "
+                                       "disabling Flow Director\n");
+                               adapter->flags &= ~IXGBE_FLAG_FDIR_HASH_CAPABLE;
+                               adapter->flags &=
+                                       ~IXGBE_FLAG_FDIR_PERFECT_CAPABLE;
+                               adapter->atr_sample_rate = 0;
+                       } else {
+                               adapter->flags &= ~IXGBE_FLAG_FCOE_ENABLED;
+                       }
+               }
+       }
+#endif /* IXGBE_FCOE */
        if (pci_using_dac)
                netdev->features |= NETIF_F_HIGHDMA;
 
+       if (adapter->flags & IXGBE_FLAG2_RSC_ENABLED)
+               netdev->features |= NETIF_F_LRO;
+
        /* make sure the EEPROM is good */
        if (hw->eeprom.ops.validate_checksum(hw, NULL) < 0) {
                dev_err(&pdev->dev, "The EEPROM Checksum Is Not Valid\n");
@@ -4766,6 +5604,9 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
        case IXGBE_DEV_ID_82599_KX4:
                adapter->wol = (IXGBE_WUFC_MAG | IXGBE_WUFC_EX |
                                IXGBE_WUFC_MC | IXGBE_WUFC_BC);
+               /* Enable ACPI wakeup in GRC */
+               IXGBE_WRITE_REG(hw, IXGBE_GRC,
+                            (IXGBE_READ_REG(hw, IXGBE_GRC) & ~IXGBE_GRC_APME));
                break;
        default:
                adapter->wol = 0;
@@ -4774,6 +5615,9 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
        device_init_wakeup(&adapter->pdev->dev, true);
        device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
 
+       /* pick up the PCI bus settings for reporting later */
+       hw->mac.ops.get_bus_info(hw);
+
        /* print bus type/speed/width info */
        dev_info(&pdev->dev, "(PCI Express:%s:%s) %pM\n",
                ((hw->bus.speed == ixgbe_bus_speed_5000) ? "5.0Gb/s":
@@ -4805,24 +5649,37 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
        hw->eeprom.ops.read(hw, 0x29, &adapter->eeprom_version);
 
        /* reset the hardware with the new settings */
-       hw->mac.ops.start_hw(hw);
-
-       netif_carrier_off(netdev);
+       err = hw->mac.ops.start_hw(hw);
 
+       if (err == IXGBE_ERR_EEPROM_VERSION) {
+               /* We are running on a pre-production device, log a warning */
+               dev_warn(&pdev->dev, "This device is a pre-production "
+                        "adapter/LOM.  Please be aware there may be issues "
+                        "associated with your hardware.  If you are "
+                        "experiencing problems please contact your Intel or "
+                        "hardware representative who provided you with this "
+                        "hardware.\n");
+       }
        strcpy(netdev->name, "eth%d");
        err = register_netdev(netdev);
        if (err)
                goto err_register;
 
+       /* carrier off reporting is important to ethtool even BEFORE open */
+       netif_carrier_off(netdev);
+
+       if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE ||
+           adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)
+               INIT_WORK(&adapter->fdir_reinit_task, ixgbe_fdir_reinit_task);
+
 #ifdef CONFIG_IXGBE_DCA
        if (dca_add_requester(&pdev->dev) == 0) {
                adapter->flags |= IXGBE_FLAG_DCA_ENABLED;
-               /* always use CB2 mode, difference is masked
-                * in the CB driver */
-               IXGBE_WRITE_REG(hw, IXGBE_DCA_CTRL, 2);
                ixgbe_setup_dca(adapter);
        }
 #endif
+       /* add san mac addr to netdev */
+       ixgbe_add_sanmac_netdev(netdev);
 
        dev_info(&pdev->dev, "Intel(R) 10 Gigabit Network Connection\n");
        cards_found++;
@@ -4830,9 +5687,8 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
 
 err_register:
        ixgbe_release_hw_control(adapter);
-err_hw_init:
+       ixgbe_clear_interrupt_scheme(adapter);
 err_sw_init:
-       ixgbe_reset_interrupt_capability(adapter);
 err_eeprom:
        clear_bit(__IXGBE_SFP_MODULE_NOT_FOUND, &adapter->state);
        del_timer_sync(&adapter->sfp_timer);
@@ -4843,7 +5699,8 @@ err_eeprom:
 err_ioremap:
        free_netdev(netdev);
 err_alloc_etherdev:
-       pci_release_regions(pdev);
+       pci_release_selected_regions(pdev, pci_select_bars(pdev,
+                                    IORESOURCE_MEM));
 err_pci_reg:
 err_dma:
        pci_disable_device(pdev);
@@ -4877,6 +5734,9 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev)
        cancel_work_sync(&adapter->sfp_task);
        cancel_work_sync(&adapter->multispeed_fiber_task);
        cancel_work_sync(&adapter->sfp_config_module_task);
+       if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE ||
+           adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)
+               cancel_work_sync(&adapter->fdir_reinit_task);
        flush_scheduled_work();
 
 #ifdef CONFIG_IXGBE_DCA
@@ -4887,19 +5747,27 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev)
        }
 
 #endif
+#ifdef IXGBE_FCOE
+       if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED)
+               ixgbe_cleanup_fcoe(adapter);
+
+#endif /* IXGBE_FCOE */
+
+       /* remove the added san mac */
+       ixgbe_del_sanmac_netdev(netdev);
+
        if (netdev->reg_state == NETREG_REGISTERED)
                unregister_netdev(netdev);
 
-       ixgbe_reset_interrupt_capability(adapter);
+       ixgbe_clear_interrupt_scheme(adapter);
 
        ixgbe_release_hw_control(adapter);
 
        iounmap(adapter->hw.hw_addr);
-       pci_release_regions(pdev);
+       pci_release_selected_regions(pdev, pci_select_bars(pdev,
+                                    IORESOURCE_MEM));
 
        DPRINTK(PROBE, INFO, "complete\n");
-       kfree(adapter->tx_ring);
-       kfree(adapter->rx_ring);
 
        free_netdev(netdev);
 
@@ -4927,6 +5795,9 @@ static pci_ers_result_t ixgbe_io_error_detected(struct pci_dev *pdev,
 
        netif_device_detach(netdev);
 
+       if (state == pci_channel_io_perm_failure)
+               return PCI_ERS_RESULT_DISCONNECT;
+
        if (netif_running(netdev))
                ixgbe_down(adapter);
        pci_disable_device(pdev);
@@ -4948,7 +5819,7 @@ static pci_ers_result_t ixgbe_io_slot_reset(struct pci_dev *pdev)
        pci_ers_result_t result;
        int err;
 
-       if (pci_enable_device(pdev)) {
+       if (pci_enable_device_mem(pdev)) {
                DPRINTK(PROBE, ERR,
                        "Cannot re-enable PCI device after reset.\n");
                result = PCI_ERS_RESULT_DISCONNECT;
@@ -4956,8 +5827,7 @@ static pci_ers_result_t ixgbe_io_slot_reset(struct pci_dev *pdev)
                pci_set_master(pdev);
                pci_restore_state(pdev);
 
-               pci_enable_wake(pdev, PCI_D3hot, 0);
-               pci_enable_wake(pdev, PCI_D3cold, 0);
+               pci_wake_from_d3(pdev, false);
 
                ixgbe_reset(adapter);
                IXGBE_WRITE_REG(&adapter->hw, IXGBE_WUS, ~0);
index 14e9606aa3b30a42b734b5f5982cd0842a1370c1..453e966762f0e3a6f8f14c603ccbb031849ab5de 100644 (file)
@@ -44,7 +44,6 @@ static void ixgbe_lower_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl);
 static s32 ixgbe_set_i2c_data(struct ixgbe_hw *hw, u32 *i2cctl, bool data);
 static bool ixgbe_get_i2c_data(u32 *i2cctl);
 static void ixgbe_i2c_bus_clear(struct ixgbe_hw *hw);
-static bool ixgbe_validate_phy_addr(struct ixgbe_hw *hw, u32 phy_addr);
 static enum ixgbe_phy_type ixgbe_get_phy_type_from_id(u32 phy_id);
 static s32 ixgbe_get_phy_id(struct ixgbe_hw *hw);
 
@@ -61,8 +60,7 @@ s32 ixgbe_identify_phy_generic(struct ixgbe_hw *hw)
 
        if (hw->phy.type == ixgbe_phy_unknown) {
                for (phy_addr = 0; phy_addr < IXGBE_MAX_PHY_ADDR; phy_addr++) {
-                       if (ixgbe_validate_phy_addr(hw, phy_addr)) {
-                               hw->phy.addr = phy_addr;
+                       if (mdio45_probe(&hw->phy.mdio, phy_addr) == 0) {
                                ixgbe_get_phy_id(hw);
                                hw->phy.type =
                                        ixgbe_get_phy_type_from_id(hw->phy.id);
@@ -77,26 +75,6 @@ s32 ixgbe_identify_phy_generic(struct ixgbe_hw *hw)
        return status;
 }
 
-/**
- *  ixgbe_validate_phy_addr - Determines phy address is valid
- *  @hw: pointer to hardware structure
- *
- **/
-static bool ixgbe_validate_phy_addr(struct ixgbe_hw *hw, u32 phy_addr)
-{
-       u16 phy_id = 0;
-       bool valid = false;
-
-       hw->phy.addr = phy_addr;
-       hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_ID_HIGH,
-                            IXGBE_MDIO_PMA_PMD_DEV_TYPE, &phy_id);
-
-       if (phy_id != 0xFFFF && phy_id != 0x0)
-               valid = true;
-
-       return valid;
-}
-
 /**
  *  ixgbe_get_phy_id - Get the phy type
  *  @hw: pointer to hardware structure
@@ -108,14 +86,12 @@ static s32 ixgbe_get_phy_id(struct ixgbe_hw *hw)
        u16 phy_id_high = 0;
        u16 phy_id_low = 0;
 
-       status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_ID_HIGH,
-                                     IXGBE_MDIO_PMA_PMD_DEV_TYPE,
+       status = hw->phy.ops.read_reg(hw, MDIO_DEVID1, MDIO_MMD_PMAPMD,
                                      &phy_id_high);
 
        if (status == 0) {
                hw->phy.id = (u32)(phy_id_high << 16);
-               status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_ID_LOW,
-                                             IXGBE_MDIO_PMA_PMD_DEV_TYPE,
+               status = hw->phy.ops.read_reg(hw, MDIO_DEVID2, MDIO_MMD_PMAPMD,
                                              &phy_id_low);
                hw->phy.id |= (u32)(phy_id_low & IXGBE_PHY_REVISION_MASK);
                hw->phy.revision = (u32)(phy_id_low & ~IXGBE_PHY_REVISION_MASK);
@@ -160,9 +136,8 @@ s32 ixgbe_reset_phy_generic(struct ixgbe_hw *hw)
         * Perform soft PHY reset to the PHY_XS.
         * This will cause a soft reset to the PHY
         */
-       return hw->phy.ops.write_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL,
-                                    IXGBE_MDIO_PHY_XS_DEV_TYPE,
-                                    IXGBE_MDIO_PHY_XS_RESET);
+       return hw->phy.ops.write_reg(hw, MDIO_CTRL1, MDIO_MMD_PHYXS,
+                                    MDIO_CTRL1_RESET);
 }
 
 /**
@@ -192,7 +167,7 @@ s32 ixgbe_read_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr,
                /* Setup and write the address cycle command */
                command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT)  |
                           (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
-                          (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) |
+                          (hw->phy.mdio.prtad << IXGBE_MSCA_PHY_ADDR_SHIFT) |
                           (IXGBE_MSCA_ADDR_CYCLE | IXGBE_MSCA_MDI_COMMAND));
 
                IXGBE_WRITE_REG(hw, IXGBE_MSCA, command);
@@ -223,7 +198,8 @@ s32 ixgbe_read_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr,
                         */
                        command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT)  |
                                   (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
-                                  (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) |
+                                  (hw->phy.mdio.prtad <<
+                                   IXGBE_MSCA_PHY_ADDR_SHIFT) |
                                   (IXGBE_MSCA_READ | IXGBE_MSCA_MDI_COMMAND));
 
                        IXGBE_WRITE_REG(hw, IXGBE_MSCA, command);
@@ -292,7 +268,7 @@ s32 ixgbe_write_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr,
                /* Setup and write the address cycle command */
                command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT)  |
                           (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
-                          (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) |
+                          (hw->phy.mdio.prtad << IXGBE_MSCA_PHY_ADDR_SHIFT) |
                           (IXGBE_MSCA_ADDR_CYCLE | IXGBE_MSCA_MDI_COMMAND));
 
                IXGBE_WRITE_REG(hw, IXGBE_MSCA, command);
@@ -323,7 +299,8 @@ s32 ixgbe_write_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr,
                         */
                        command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT)  |
                                   (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) |
-                                  (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) |
+                                  (hw->phy.mdio.prtad <<
+                                   IXGBE_MSCA_PHY_ADDR_SHIFT) |
                                   (IXGBE_MSCA_WRITE | IXGBE_MSCA_MDI_COMMAND));
 
                        IXGBE_WRITE_REG(hw, IXGBE_MSCA, command);
@@ -365,7 +342,7 @@ s32 ixgbe_setup_phy_link_generic(struct ixgbe_hw *hw)
        s32 status = IXGBE_NOT_IMPLEMENTED;
        u32 time_out;
        u32 max_time_out = 10;
-       u16 autoneg_reg = IXGBE_MII_AUTONEG_REG;
+       u16 autoneg_reg;
 
        /*
         * Set advertisement settings in PHY based on autoneg_advertised
@@ -373,36 +350,31 @@ s32 ixgbe_setup_phy_link_generic(struct ixgbe_hw *hw)
         * tnx devices cannot be "forced" to a autoneg 10G and fail.  But can
         * for a 1G.
         */
-       hw->phy.ops.read_reg(hw, IXGBE_MII_SPEED_SELECTION_REG,
-                            IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &autoneg_reg);
+       hw->phy.ops.read_reg(hw, MDIO_AN_ADVERTISE, MDIO_MMD_AN, &autoneg_reg);
 
        if (hw->phy.autoneg_advertised == IXGBE_LINK_SPEED_1GB_FULL)
-               autoneg_reg &= 0xEFFF; /* 0 in bit 12 is 1G operation */
+               autoneg_reg &= ~MDIO_AN_10GBT_CTRL_ADV10G;
        else
-               autoneg_reg |= 0x1000; /* 1 in bit 12 is 10G/1G operation */
+               autoneg_reg |= MDIO_AN_10GBT_CTRL_ADV10G;
 
-       hw->phy.ops.write_reg(hw, IXGBE_MII_SPEED_SELECTION_REG,
-                             IXGBE_MDIO_AUTO_NEG_DEV_TYPE, autoneg_reg);
+       hw->phy.ops.write_reg(hw, MDIO_AN_ADVERTISE, MDIO_MMD_AN, autoneg_reg);
 
        /* Restart PHY autonegotiation and wait for completion */
-       hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_CONTROL,
-                            IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &autoneg_reg);
+       hw->phy.ops.read_reg(hw, MDIO_CTRL1, MDIO_MMD_AN, &autoneg_reg);
 
-       autoneg_reg |= IXGBE_MII_RESTART;
+       autoneg_reg |= MDIO_AN_CTRL1_RESTART;
 
-       hw->phy.ops.write_reg(hw, IXGBE_MDIO_AUTO_NEG_CONTROL,
-                             IXGBE_MDIO_AUTO_NEG_DEV_TYPE, autoneg_reg);
+       hw->phy.ops.write_reg(hw, MDIO_CTRL1, MDIO_MMD_AN, autoneg_reg);
 
        /* Wait for autonegotiation to finish */
        for (time_out = 0; time_out < max_time_out; time_out++) {
                udelay(10);
                /* Restart PHY autonegotiation and wait for completion */
-               status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS,
-                                             IXGBE_MDIO_AUTO_NEG_DEV_TYPE,
+               status = hw->phy.ops.read_reg(hw, MDIO_STAT1, MDIO_MMD_AN,
                                              &autoneg_reg);
 
-               autoneg_reg &= IXGBE_MII_AUTONEG_COMPLETE;
-               if (autoneg_reg == IXGBE_MII_AUTONEG_COMPLETE) {
+               autoneg_reg &= MDIO_AN_STAT1_COMPLETE;
+               if (autoneg_reg == MDIO_AN_STAT1_COMPLETE) {
                        status = 0;
                        break;
                }
@@ -457,23 +429,21 @@ s32 ixgbe_reset_phy_nl(struct ixgbe_hw *hw)
        s32 ret_val = 0;
        u32 i;
 
-       hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL,
-                            IXGBE_MDIO_PHY_XS_DEV_TYPE, &phy_data);
+       hw->phy.ops.read_reg(hw, MDIO_CTRL1, MDIO_MMD_PHYXS, &phy_data);
 
        /* reset the PHY and poll for completion */
-       hw->phy.ops.write_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL,
-                             IXGBE_MDIO_PHY_XS_DEV_TYPE,
-                             (phy_data | IXGBE_MDIO_PHY_XS_RESET));
+       hw->phy.ops.write_reg(hw, MDIO_CTRL1, MDIO_MMD_PHYXS,
+                             (phy_data | MDIO_CTRL1_RESET));
 
        for (i = 0; i < 100; i++) {
-               hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL,
-                                    IXGBE_MDIO_PHY_XS_DEV_TYPE, &phy_data);
-               if ((phy_data & IXGBE_MDIO_PHY_XS_RESET) == 0)
+               hw->phy.ops.read_reg(hw, MDIO_CTRL1, MDIO_MMD_PHYXS,
+                                    &phy_data);
+               if ((phy_data & MDIO_CTRL1_RESET) == 0)
                        break;
                msleep(10);
        }
 
-       if ((phy_data & IXGBE_MDIO_PHY_XS_RESET) != 0) {
+       if ((phy_data & MDIO_CTRL1_RESET) != 0) {
                hw_dbg(hw, "PHY reset did not complete.\n");
                ret_val = IXGBE_ERR_PHY;
                goto out;
@@ -509,7 +479,7 @@ s32 ixgbe_reset_phy_nl(struct ixgbe_hw *hw)
                        for (i = 0; i < edata; i++) {
                                hw->eeprom.ops.read(hw, data_offset, &eword);
                                hw->phy.ops.write_reg(hw, phy_offset,
-                                                     IXGBE_TWINAX_DEV, eword);
+                                                     MDIO_MMD_PMAPMD, eword);
                                hw_dbg(hw, "Wrote %4.4x to %4.4x\n", eword,
                                       phy_offset);
                                data_offset++;
@@ -552,18 +522,30 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
 {
        s32 status = IXGBE_ERR_PHY_ADDR_INVALID;
        u32 vendor_oui = 0;
+       enum ixgbe_sfp_type stored_sfp_type = hw->phy.sfp_type;
        u8 identifier = 0;
        u8 comp_codes_1g = 0;
        u8 comp_codes_10g = 0;
        u8 oui_bytes[3] = {0, 0, 0};
-       u8 transmission_media = 0;
+       u8 cable_tech = 0;
        u16 enforce_sfp = 0;
 
+       if (hw->mac.ops.get_media_type(hw) != ixgbe_media_type_fiber) {
+               hw->phy.sfp_type = ixgbe_sfp_type_not_present;
+               status = IXGBE_ERR_SFP_NOT_PRESENT;
+               goto out;
+       }
+
        status = hw->phy.ops.read_i2c_eeprom(hw, IXGBE_SFF_IDENTIFIER,
                                             &identifier);
 
-       if (status == IXGBE_ERR_SFP_NOT_PRESENT) {
+       if (status == IXGBE_ERR_SFP_NOT_PRESENT || status == IXGBE_ERR_I2C) {
+               status = IXGBE_ERR_SFP_NOT_PRESENT;
                hw->phy.sfp_type = ixgbe_sfp_type_not_present;
+               if (hw->phy.type != ixgbe_phy_nl) {
+                       hw->phy.id = 0;
+                       hw->phy.type = ixgbe_phy_unknown;
+               }
                goto out;
        }
 
@@ -572,8 +554,8 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
                                            &comp_codes_1g);
                hw->phy.ops.read_i2c_eeprom(hw, IXGBE_SFF_10GBE_COMP_CODES,
                                            &comp_codes_10g);
-               hw->phy.ops.read_i2c_eeprom(hw, IXGBE_SFF_TRANSMISSION_MEDIA,
-                                           &transmission_media);
+               hw->phy.ops.read_i2c_eeprom(hw, IXGBE_SFF_CABLE_TECHNOLOGY,
+                                           &cable_tech);
 
                /* ID Module
                 * =========
@@ -586,7 +568,7 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
                 * 6    SFP_SR/LR_CORE1 - 82599-specific
                 */
                if (hw->mac.type == ixgbe_mac_82598EB) {
-                       if (transmission_media & IXGBE_SFF_TWIN_AX_CAPABLE)
+                       if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE)
                                hw->phy.sfp_type = ixgbe_sfp_type_da_cu;
                        else if (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)
                                hw->phy.sfp_type = ixgbe_sfp_type_sr;
@@ -595,7 +577,7 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
                        else
                                hw->phy.sfp_type = ixgbe_sfp_type_unknown;
                } else if (hw->mac.type == ixgbe_mac_82599EB) {
-                       if (transmission_media & IXGBE_SFF_TWIN_AX_CAPABLE)
+                       if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE)
                                if (hw->bus.lan_id == 0)
                                        hw->phy.sfp_type =
                                                     ixgbe_sfp_type_da_cu_core0;
@@ -620,8 +602,19 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
                                hw->phy.sfp_type = ixgbe_sfp_type_unknown;
                }
 
+               if (hw->phy.sfp_type != stored_sfp_type)
+                       hw->phy.sfp_setup_needed = true;
+
+               /* Determine if the SFP+ PHY is dual speed or not. */
+               hw->phy.multispeed_fiber = false;
+               if (((comp_codes_1g & IXGBE_SFF_1GBASESX_CAPABLE) &&
+                  (comp_codes_10g & IXGBE_SFF_10GBASESR_CAPABLE)) ||
+                  ((comp_codes_1g & IXGBE_SFF_1GBASELX_CAPABLE) &&
+                  (comp_codes_10g & IXGBE_SFF_10GBASELR_CAPABLE)))
+                       hw->phy.multispeed_fiber = true;
+
                /* Determine PHY vendor */
-               if (hw->phy.type == ixgbe_phy_unknown) {
+               if (hw->phy.type != ixgbe_phy_nl) {
                        hw->phy.id = identifier;
                        hw->phy.ops.read_i2c_eeprom(hw,
                                                    IXGBE_SFF_VENDOR_OUI_BYTE0,
@@ -640,8 +633,7 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
 
                        switch (vendor_oui) {
                        case IXGBE_SFF_VENDOR_OUI_TYCO:
-                               if (transmission_media &
-                                   IXGBE_SFF_TWIN_AX_CAPABLE)
+                               if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE)
                                        hw->phy.type = ixgbe_phy_tw_tyco;
                                break;
                        case IXGBE_SFF_VENDOR_OUI_FTL:
@@ -654,31 +646,42 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
                                hw->phy.type = ixgbe_phy_sfp_intel;
                                break;
                        default:
-                               if (transmission_media &
-                                   IXGBE_SFF_TWIN_AX_CAPABLE)
+                               if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE)
                                        hw->phy.type = ixgbe_phy_tw_unknown;
                                else
                                        hw->phy.type = ixgbe_phy_sfp_unknown;
                                break;
                        }
                }
-               if (hw->mac.type == ixgbe_mac_82598EB ||
-                   (hw->phy.sfp_type != ixgbe_sfp_type_sr &&
-                    hw->phy.sfp_type != ixgbe_sfp_type_lr &&
-                    hw->phy.sfp_type != ixgbe_sfp_type_srlr_core0 &&
-                    hw->phy.sfp_type != ixgbe_sfp_type_srlr_core1)) {
+
+               /* All passive DA cables are supported */
+               if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE) {
+                       status = 0;
+                       goto out;
+               }
+
+               /* 1G SFP modules are not supported */
+               if (comp_codes_10g == 0) {
+                       hw->phy.type = ixgbe_phy_sfp_unsupported;
+                       status = IXGBE_ERR_SFP_NOT_SUPPORTED;
+                       goto out;
+               }
+
+               /* Anything else 82598-based is supported */
+               if (hw->mac.type == ixgbe_mac_82598EB) {
                        status = 0;
                        goto out;
                }
 
-               hw->eeprom.ops.read(hw, IXGBE_PHY_ENFORCE_INTEL_SFP_OFFSET,
-                                   &enforce_sfp);
-               if (!(enforce_sfp & IXGBE_PHY_ALLOW_ANY_SFP)) {
+               /* This is guaranteed to be 82599, no need to check for NULL */
+               hw->mac.ops.get_device_caps(hw, &enforce_sfp);
+               if (!(enforce_sfp & IXGBE_DEVICE_CAPS_ALLOW_ANY_SFP)) {
                        /* Make sure we're a supported PHY type */
                        if (hw->phy.type == ixgbe_phy_sfp_intel) {
                                status = 0;
                        } else {
                                hw_dbg(hw, "SFP+ module not supported\n");
+                               hw->phy.type = ixgbe_phy_sfp_unsupported;
                                status = IXGBE_ERR_SFP_NOT_SUPPORTED;
                        }
                } else {
@@ -1279,7 +1282,7 @@ s32 ixgbe_check_phy_link_tnx(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
                udelay(10);
                status = hw->phy.ops.read_reg(hw,
                                        IXGBE_MDIO_VENDOR_SPECIFIC_1_STATUS,
-                                       IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
+                                       MDIO_MMD_VEND1,
                                        &phy_data);
                phy_link = phy_data &
                           IXGBE_MDIO_VENDOR_SPECIFIC_1_LINK_STATUS;
@@ -1307,8 +1310,7 @@ s32 ixgbe_get_phy_firmware_version_tnx(struct ixgbe_hw *hw,
 {
        s32 status = 0;
 
-       status = hw->phy.ops.read_reg(hw, TNX_FW_REV,
-                                     IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE,
+       status = hw->phy.ops.read_reg(hw, TNX_FW_REV, MDIO_MMD_VEND1,
                                      firmware_version);
 
        return status;
index cc5f1b3287e18c4e8c28a058f2f1fe895e635f5f..9b700f5bf1ed5e5859b7a90f11bf9c5dc9966b2f 100644 (file)
 #define IXGBE_SFF_VENDOR_OUI_BYTE2   0x27
 #define IXGBE_SFF_1GBE_COMP_CODES    0x6
 #define IXGBE_SFF_10GBE_COMP_CODES   0x3
-#define IXGBE_SFF_TRANSMISSION_MEDIA 0x9
+#define IXGBE_SFF_CABLE_TECHNOLOGY   0x8
 
 /* Bitmasks */
-#define IXGBE_SFF_TWIN_AX_CAPABLE            0x80
+#define IXGBE_SFF_DA_PASSIVE_CABLE           0x4
 #define IXGBE_SFF_1GBASESX_CAPABLE           0x1
+#define IXGBE_SFF_1GBASELX_CAPABLE           0x2
 #define IXGBE_SFF_10GBASESR_CAPABLE          0x10
 #define IXGBE_SFF_10GBASELR_CAPABLE          0x20
 #define IXGBE_I2C_EEPROM_READ_MASK           0x100
index 030ff0a9ea6757079e75f020679f42360d1b76d9..fa87309dc0877b39447138232c2f44c74d2282d4 100644 (file)
@@ -29,6 +29,8 @@
 #define _IXGBE_TYPE_H_
 
 #include <linux/types.h>
+#include <linux/mdio.h>
+#include <linux/list.h>
 
 /* Vendor ID */
 #define IXGBE_INTEL_VENDOR_ID   0x8086
@@ -45,9 +47,9 @@
 #define IXGBE_DEV_ID_82598_DA_DUAL_PORT  0x10F1
 #define IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM      0x10E1
 #define IXGBE_DEV_ID_82598EB_XF_LR       0x10F4
-#define IXGBE_DEV_ID_82599               0x10D8
 #define IXGBE_DEV_ID_82599_KX4           0x10F7
 #define IXGBE_DEV_ID_82599_SFP           0x10FB
+#define IXGBE_DEV_ID_82599_XAUI_LOM      0x10FC
 
 /* General Registers */
 #define IXGBE_CTRL      0x00000
 #define IXGBE_RETA(_i)  (0x05C00 + ((_i) * 4))  /* 32 of these (0-31) */
 #define IXGBE_RSSRK(_i) (0x05C80 + ((_i) * 4))  /* 10 of these (0-9) */
 
+/* Flow Director registers */
+#define IXGBE_FDIRCTRL  0x0EE00
+#define IXGBE_FDIRHKEY  0x0EE68
+#define IXGBE_FDIRSKEY  0x0EE6C
+#define IXGBE_FDIRDIP4M 0x0EE3C
+#define IXGBE_FDIRSIP4M 0x0EE40
+#define IXGBE_FDIRTCPM  0x0EE44
+#define IXGBE_FDIRUDPM  0x0EE48
+#define IXGBE_FDIRIP6M  0x0EE74
+#define IXGBE_FDIRM     0x0EE70
+
+/* Flow Director Stats registers */
+#define IXGBE_FDIRFREE  0x0EE38
+#define IXGBE_FDIRLEN   0x0EE4C
+#define IXGBE_FDIRUSTAT 0x0EE50
+#define IXGBE_FDIRFSTAT 0x0EE54
+#define IXGBE_FDIRMATCH 0x0EE58
+#define IXGBE_FDIRMISS  0x0EE5C
+
+/* Flow Director Programming registers */
+#define IXGBE_FDIRSIPv6(_i) (0x0EE0C + ((_i) * 4)) /* 3 of these (0-2) */
+#define IXGBE_FDIRIPSA      0x0EE18
+#define IXGBE_FDIRIPDA      0x0EE1C
+#define IXGBE_FDIRPORT      0x0EE20
+#define IXGBE_FDIRVLAN      0x0EE24
+#define IXGBE_FDIRHASH      0x0EE28
+#define IXGBE_FDIRCMD       0x0EE2C
+
 /* Transmit DMA registers */
 #define IXGBE_TDBAL(_i) (0x06000 + ((_i) * 0x40)) /* 32 of these (0-31)*/
 #define IXGBE_TDBAH(_i) (0x06004 + ((_i) * 0x40))
 
 #define IXGBE_SECTXCTRL_STORE_FORWARD_ENABLE    0x4
 
+/* HW RSC registers */
+#define IXGBE_RSCCTL(_i) (((_i) < 64) ? (0x0102C + ((_i) * 0x40)) : \
+                          (0x0D02C + ((_i - 64) * 0x40)))
+#define IXGBE_RSCDBU      0x03028
+#define IXGBE_RSCCTL_RSCEN          0x01
+#define IXGBE_RSCCTL_MAXDESC_1      0x00
+#define IXGBE_RSCCTL_MAXDESC_4      0x04
+#define IXGBE_RSCCTL_MAXDESC_8      0x08
+#define IXGBE_RSCCTL_MAXDESC_16     0x0C
+#define IXGBE_RXDADV_RSCCNT_SHIFT     17
+#define IXGBE_GPIE_RSC_DELAY_SHIFT    11
+#define IXGBE_RXDADV_RSCCNT_MASK    0x001E0000
+#define IXGBE_RSCDBU_RSCACKDIS      0x00000080
+#define IXGBE_RDRXCTL_RSCFRSTSIZE   0x003E0000
+
 /* DCB registers */
 #define IXGBE_RTRPCS      0x02430
 #define IXGBE_RTTDCS      0x04900
 #define IXGBE_RTTDTECC_NO_BCN   0x00000100
 #define IXGBE_RTTBCNRC    0x04984
 
+/* FCoE registers */
+#define IXGBE_FCPTRL    0x02410 /* FC User Desc. PTR Low */
+#define IXGBE_FCPTRH    0x02414 /* FC USer Desc. PTR High */
+#define IXGBE_FCBUFF    0x02418 /* FC Buffer Control */
+#define IXGBE_FCDMARW   0x02420 /* FC Receive DMA RW */
+#define IXGBE_FCINVST0  0x03FC0 /* FC Invalid DMA Context Status Reg 0 */
+#define IXGBE_FCINVST(_i)       (IXGBE_FCINVST0 + ((_i) * 4))
+#define IXGBE_FCBUFF_VALID      (1 << 0)   /* DMA Context Valid */
+#define IXGBE_FCBUFF_BUFFSIZE   (3 << 3)   /* User Buffer Size */
+#define IXGBE_FCBUFF_WRCONTX    (1 << 7)   /* 0: Initiator, 1: Target */
+#define IXGBE_FCBUFF_BUFFCNT    0x0000ff00 /* Number of User Buffers */
+#define IXGBE_FCBUFF_OFFSET     0xffff0000 /* User Buffer Offset */
+#define IXGBE_FCBUFF_BUFFSIZE_SHIFT  3
+#define IXGBE_FCBUFF_BUFFCNT_SHIFT   8
+#define IXGBE_FCBUFF_OFFSET_SHIFT    16
+#define IXGBE_FCDMARW_WE        (1 << 14)   /* Write enable */
+#define IXGBE_FCDMARW_RE        (1 << 15)   /* Read enable */
+#define IXGBE_FCDMARW_FCOESEL   0x000001ff  /* FC X_ID: 11 bits */
+#define IXGBE_FCDMARW_LASTSIZE  0xffff0000  /* Last User Buffer Size */
+#define IXGBE_FCDMARW_LASTSIZE_SHIFT 16
+
+/* FCoE SOF/EOF */
+#define IXGBE_TEOFF     0x04A94 /* Tx FC EOF */
+#define IXGBE_TSOFF     0x04A98 /* Tx FC SOF */
+#define IXGBE_REOFF     0x05158 /* Rx FC EOF */
+#define IXGBE_RSOFF     0x051F8 /* Rx FC SOF */
+/* FCoE Filter Context Registers */
+#define IXGBE_FCFLT     0x05108 /* FC FLT Context */
+#define IXGBE_FCFLTRW   0x05110 /* FC Filter RW Control */
+#define IXGBE_FCPARAM   0x051d8 /* FC Offset Parameter */
+#define IXGBE_FCFLT_VALID       (1 << 0)   /* Filter Context Valid */
+#define IXGBE_FCFLT_FIRST       (1 << 1)   /* Filter First */
+#define IXGBE_FCFLT_SEQID       0x00ff0000 /* Sequence ID */
+#define IXGBE_FCFLT_SEQCNT      0xff000000 /* Sequence Count */
+#define IXGBE_FCFLTRW_RVALDT    (1 << 13)  /* Fast Re-Validation */
+#define IXGBE_FCFLTRW_WE        (1 << 14)  /* Write Enable */
+#define IXGBE_FCFLTRW_RE        (1 << 15)  /* Read Enable */
+/* FCoE Receive Control */
+#define IXGBE_FCRXCTRL  0x05100 /* FC Receive Control */
+#define IXGBE_FCRXCTRL_FCOELLI  (1 << 0)   /* Low latency interrupt */
+#define IXGBE_FCRXCTRL_SAVBAD   (1 << 1)   /* Save Bad Frames */
+#define IXGBE_FCRXCTRL_FRSTRDH  (1 << 2)   /* EN 1st Read Header */
+#define IXGBE_FCRXCTRL_LASTSEQH (1 << 3)   /* EN Last Header in Seq */
+#define IXGBE_FCRXCTRL_ALLH     (1 << 4)   /* EN All Headers */
+#define IXGBE_FCRXCTRL_FRSTSEQH (1 << 5)   /* EN 1st Seq. Header */
+#define IXGBE_FCRXCTRL_ICRC     (1 << 6)   /* Ignore Bad FC CRC */
+#define IXGBE_FCRXCTRL_FCCRCBO  (1 << 7)   /* FC CRC Byte Ordering */
+#define IXGBE_FCRXCTRL_FCOEVER  0x00000f00 /* FCoE Version: 4 bits */
+#define IXGBE_FCRXCTRL_FCOEVER_SHIFT 8
+/* FCoE Redirection */
+#define IXGBE_FCRECTL   0x0ED00 /* FC Redirection Control */
+#define IXGBE_FCRETA0   0x0ED10 /* FC Redirection Table 0 */
+#define IXGBE_FCRETA(_i)        (IXGBE_FCRETA0 + ((_i) * 4)) /* FCoE Redir */
+#define IXGBE_FCRECTL_ENA       0x1        /* FCoE Redir Table Enable */
+#define IXGBE_FCRETA_SIZE       8          /* Max entries in FCRETA */
+#define IXGBE_FCRETA_ENTRY_MASK 0x0000007f /* 7 bits for the queue index */
+
 /* Stats registers */
 #define IXGBE_CRCERRS   0x04000
 #define IXGBE_ILLERRC   0x04004
 #define IXGBE_QPRDC(_i) (0x01430 + ((_i) * 0x40)) /* 16 of these */
 #define IXGBE_QBTC_L(_i) (0x08700 + ((_i) * 0x8)) /* 16 of these */
 #define IXGBE_QBTC_H(_i) (0x08704 + ((_i) * 0x8)) /* 16 of these */
+#define IXGBE_FCCRC     0x05118 /* Count of Good Eth CRC w/ Bad FC CRC */
+#define IXGBE_FCOERPDC  0x0241C /* FCoE Rx Packets Dropped Count */
+#define IXGBE_FCLAST    0x02424 /* FCoE Last Error Count */
+#define IXGBE_FCOEPRC   0x02428 /* Number of FCoE Packets Received */
+#define IXGBE_FCOEDWRC  0x0242C /* Number of FCoE DWords Received */
+#define IXGBE_FCOEPTC   0x08784 /* Number of FCoE Packets Transmitted */
+#define IXGBE_FCOEDWTC  0x08788 /* Number of FCoE DWords Transmitted */
 
 /* Management */
 #define IXGBE_MAVTV(_i) (0x05010 + ((_i) * 4)) /* 8 of these (0-7) */
 /* Omer bit masks */
 #define IXGBE_CORECTL_WRITE_CMD         0x00010000
 
-/* Device Type definitions for new protocol MDIO commands */
-#define IXGBE_MDIO_PMA_PMD_DEV_TYPE               0x1
-#define IXGBE_MDIO_PCS_DEV_TYPE                   0x3
-#define IXGBE_MDIO_PHY_XS_DEV_TYPE                0x4
-#define IXGBE_MDIO_AUTO_NEG_DEV_TYPE              0x7
-#define IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE     0x1E   /* Device 30 */
-#define IXGBE_TWINAX_DEV                          1
+/* MDIO definitions */
 
 #define IXGBE_MDIO_COMMAND_TIMEOUT     100 /* PHY Timeout for 1 GB mode */
 
 #define IXGBE_MDIO_VENDOR_SPECIFIC_1_10G_SPEED    0x0018
 #define IXGBE_MDIO_VENDOR_SPECIFIC_1_1G_SPEED     0x0010
 
-#define IXGBE_MDIO_AUTO_NEG_CONTROL    0x0 /* AUTO_NEG Control Reg */
-#define IXGBE_MDIO_AUTO_NEG_STATUS     0x1 /* AUTO_NEG Status Reg */
-#define IXGBE_MDIO_PHY_XS_CONTROL      0x0 /* PHY_XS Control Reg */
-#define IXGBE_MDIO_PHY_XS_RESET        0x8000 /* PHY_XS Reset */
-#define IXGBE_MDIO_PHY_ID_HIGH         0x2 /* PHY ID High Reg*/
-#define IXGBE_MDIO_PHY_ID_LOW          0x3 /* PHY ID Low Reg*/
-#define IXGBE_MDIO_PHY_SPEED_ABILITY   0x4 /* Speed Ability Reg */
-#define IXGBE_MDIO_PHY_SPEED_10G       0x0001 /* 10G capable */
-#define IXGBE_MDIO_PHY_SPEED_1G        0x0010 /* 1G capable */
-#define IXGBE_MDIO_PHY_EXT_ABILITY        0xB /* Ext Ability Reg */
-#define IXGBE_MDIO_PHY_10GBASET_ABILITY   0x0004 /* 10GBaseT capable */
-#define IXGBE_MDIO_PHY_1000BASET_ABILITY  0x0020 /* 1000BaseT capable */
-
 #define IXGBE_MDIO_PMA_PMD_SDA_SCL_ADDR     0xC30A /* PHY_XS SDA/SCL Addr Reg */
 #define IXGBE_MDIO_PMA_PMD_SDA_SCL_DATA     0xC30B /* PHY_XS SDA/SCL Data Reg */
 #define IXGBE_MDIO_PMA_PMD_SDA_SCL_STAT     0xC30C /* PHY_XS SDA/SCL Status Reg */
 
-/* MII clause 22/28 definitions */
-#define IXGBE_MDIO_PHY_LOW_POWER_MODE  0x0800
-
-#define IXGBE_MII_SPEED_SELECTION_REG  0x10
-#define IXGBE_MII_RESTART              0x200
-#define IXGBE_MII_AUTONEG_COMPLETE     0x20
-#define IXGBE_MII_AUTONEG_REG          0x0
-
 #define IXGBE_PHY_REVISION_MASK        0xFFFFFFF0
 #define IXGBE_MAX_PHY_ADDR             32
 
 #define IXGBE_CONTROL_NL         0x000F
 #define IXGBE_CONTROL_EOL_NL     0x0FFF
 #define IXGBE_CONTROL_SOL_NL     0x0000
-#define IXGBE_PHY_ENFORCE_INTEL_SFP_OFFSET 0x002C
-#define IXGBE_PHY_ALLOW_ANY_SFP            0x1
 
 /* General purpose Interrupt Enable */
 #define IXGBE_SDP0_GPIEN         0x00000001 /* SDP0 */
 #define IXGBE_VT_CTL_DIS_DEFPL  0x20000000 /* disable default pool */
 #define IXGBE_VT_CTL_REPLEN     0x40000000 /* replication enabled */
 #define IXGBE_VT_CTL_VT_ENABLE  0x00000001  /* Enable VT Mode */
+#define IXGBE_VT_CTL_POOL_SHIFT 7
+#define IXGBE_VT_CTL_POOL_MASK  (0x3F << IXGBE_VT_CTL_POOL_SHIFT)
 
 /* VMOLR bitmasks */
 #define IXGBE_VMOLR_AUPE        0x01000000 /* accept untagged packets */
 
 /* Interrupt Vector Allocation Registers */
 #define IXGBE_IVAR_REG_NUM      25
+#define IXGBE_IVAR_REG_NUM_82599       64
 #define IXGBE_IVAR_TXRX_ENTRY   96
 #define IXGBE_IVAR_RX_ENTRY     64
 #define IXGBE_IVAR_RX_QUEUE(_i)    (0 + (_i))
 
 /* ETYPE Queue Filter/Select Bit Masks */
 #define IXGBE_MAX_ETQF_FILTERS  8
+#define IXGBE_ETQF_FCOE         0x08000000 /* bit 27 */
 #define IXGBE_ETQF_BCN          0x10000000 /* bit 28 */
 #define IXGBE_ETQF_1588         0x40000000 /* bit 30 */
 #define IXGBE_ETQF_FILTER_EN    0x80000000 /* bit 31 */
  */
 #define IXGBE_ETQF_FILTER_EAPOL          0
 #define IXGBE_ETQF_FILTER_BCN            1
+#define IXGBE_ETQF_FILTER_FCOE           2
 #define IXGBE_ETQF_FILTER_1588           3
 /* VLAN Control Bit Masks */
 #define IXGBE_VLNCTRL_VET       0x0000FFFF  /* bits 0-15 */
 #define IXGBE_STATUS_LAN_ID_1   0x00000004 /* LAN ID 1 */
 
 /* ESDP Bit Masks */
-#define IXGBE_ESDP_SDP0 0x00000001
-#define IXGBE_ESDP_SDP1 0x00000002
+#define IXGBE_ESDP_SDP0 0x00000001 /* SDP0 Data Value */
+#define IXGBE_ESDP_SDP1 0x00000002 /* SDP1 Data Value */
+#define IXGBE_ESDP_SDP2 0x00000004 /* SDP2 Data Value */
+#define IXGBE_ESDP_SDP3 0x00000008 /* SDP3 Data Value */
 #define IXGBE_ESDP_SDP4 0x00000010 /* SDP4 Data Value */
 #define IXGBE_ESDP_SDP5 0x00000020 /* SDP5 Data Value */
 #define IXGBE_ESDP_SDP6 0x00000040 /* SDP6 Data Value */
 #define IXGBE_LINK_UP_TIME      90 /* 9.0 Seconds */
 #define IXGBE_AUTO_NEG_TIME     45 /* 4.5 Seconds */
 
-#define FIBER_LINK_UP_LIMIT     50
-
 /* PCS1GLSTA Bit Masks */
 #define IXGBE_PCS1GLSTA_LINK_OK         1
 #define IXGBE_PCS1GLSTA_SYNK_OK         0x10
 #define IXGBE_FW_PTR            0x0F
 #define IXGBE_PBANUM0_PTR       0x15
 #define IXGBE_PBANUM1_PTR       0x16
+#define IXGBE_DEVICE_CAPS       0x2C
+#define IXGBE_SAN_MAC_ADDR_PTR  0x28
 #define IXGBE_PCIE_MSIX_82599_CAPS  0x72
 #define IXGBE_PCIE_MSIX_82598_CAPS  0x62
 
 #define IXGBE_EERD_ATTEMPTS 100000
 #endif
 
+#define IXGBE_SAN_MAC_ADDR_PORT0_OFFSET  0x0
+#define IXGBE_SAN_MAC_ADDR_PORT1_OFFSET  0x3
+#define IXGBE_DEVICE_CAPS_ALLOW_ANY_SFP  0x1
+#define IXGBE_DEVICE_CAPS_FCOE_OFFLOADS  0x2
+#define IXGBE_FW_PASSTHROUGH_PATCH_CONFIG_PTR   0x4
+#define IXGBE_FW_PATCH_VERSION_4   0x7
+
 /* PCI Bus Info */
 #define IXGBE_PCI_LINK_STATUS     0xB2
 #define IXGBE_PCI_LINK_WIDTH      0x3F0
 #define IXGBE_MTQC_RT_ENA       0x1 /* DCB Enable */
 #define IXGBE_MTQC_VT_ENA       0x2 /* VMDQ2 Enable */
 #define IXGBE_MTQC_64Q_1PB      0x0 /* 64 queues 1 pack buffer */
-#define IXGBE_MTQC_64VF         0x8 /* 2 TX Queues per pool w/64VF's */
+#define IXGBE_MTQC_32VF         0x8 /* 4 TX Queues per pool w/32VF's */
+#define IXGBE_MTQC_64VF         0x4 /* 2 TX Queues per pool w/64VF's */
 #define IXGBE_MTQC_8TC_8TQ      0xC /* 8 TC if RT_ENA or 8 TQ if VT_ENA */
 
 /* Receive Descriptor bit definitions */
 #define IXGBE_RXD_ERR_IPE       0x80    /* IP Checksum Error */
 #define IXGBE_RXDADV_ERR_MASK           0xfff00000 /* RDESC.ERRORS mask */
 #define IXGBE_RXDADV_ERR_SHIFT          20         /* RDESC.ERRORS shift */
+#define IXGBE_RXDADV_ERR_FCEOFE         0x80000000 /* FCoEFe/IPE */
+#define IXGBE_RXDADV_ERR_FCERR          0x00700000 /* FCERR/FDIRERR */
+#define IXGBE_RXDADV_ERR_FDIR_LEN       0x00100000 /* FDIR Length error */
+#define IXGBE_RXDADV_ERR_FDIR_DROP      0x00200000 /* FDIR Drop error */
+#define IXGBE_RXDADV_ERR_FDIR_COLL      0x00400000 /* FDIR Collision error */
 #define IXGBE_RXDADV_ERR_HBO    0x00800000 /*Header Buffer Overflow */
 #define IXGBE_RXDADV_ERR_CE     0x01000000 /* CRC Error */
 #define IXGBE_RXDADV_ERR_LE     0x02000000 /* Length Error */
 #define IXGBE_RXDADV_STAT_FLM           IXGBE_RXD_STAT_FLM /* FDir Match */
 #define IXGBE_RXDADV_STAT_VP            IXGBE_RXD_STAT_VP  /* IEEE VLAN Pkt */
 #define IXGBE_RXDADV_STAT_MASK          0x000fffff /* Stat/NEXTP: bit 0-19 */
+#define IXGBE_RXDADV_STAT_FCEOFS        0x00000040 /* FCoE EOF/SOF Stat */
+#define IXGBE_RXDADV_STAT_FCSTAT        0x00000030 /* FCoE Pkt Stat */
+#define IXGBE_RXDADV_STAT_FCSTAT_NOMTCH 0x00000000 /* 00: No Ctxt Match */
+#define IXGBE_RXDADV_STAT_FCSTAT_NODDP  0x00000010 /* 01: Ctxt w/o DDP */
+#define IXGBE_RXDADV_STAT_FCSTAT_FCPRSP 0x00000020 /* 10: Recv. FCP_RSP */
+#define IXGBE_RXDADV_STAT_FCSTAT_DDP    0x00000030 /* 11: Ctxt w/ DDP */
 
 /* PSRTYPE bit definitions */
 #define IXGBE_PSRTYPE_TCPHDR    0x00000010
 #define IXGBE_PSRTYPE_UDPHDR    0x00000020
 #define IXGBE_PSRTYPE_IPV4HDR   0x00000100
 #define IXGBE_PSRTYPE_IPV6HDR   0x00000200
+#define IXGBE_PSRTYPE_L2HDR     0x00001000
 
 /* SRRCTL bit definitions */
 #define IXGBE_SRRCTL_BSIZEPKT_SHIFT     10     /* so many KBs */
 
 #endif
 
+enum ixgbe_fdir_pballoc_type {
+       IXGBE_FDIR_PBALLOC_64K = 0,
+       IXGBE_FDIR_PBALLOC_128K,
+       IXGBE_FDIR_PBALLOC_256K,
+};
+#define IXGBE_FDIR_PBALLOC_SIZE_SHIFT           16
+
+/* Flow Director register values */
+#define IXGBE_FDIRCTRL_PBALLOC_64K              0x00000001
+#define IXGBE_FDIRCTRL_PBALLOC_128K             0x00000002
+#define IXGBE_FDIRCTRL_PBALLOC_256K             0x00000003
+#define IXGBE_FDIRCTRL_INIT_DONE                0x00000008
+#define IXGBE_FDIRCTRL_PERFECT_MATCH            0x00000010
+#define IXGBE_FDIRCTRL_REPORT_STATUS            0x00000020
+#define IXGBE_FDIRCTRL_REPORT_STATUS_ALWAYS     0x00000080
+#define IXGBE_FDIRCTRL_DROP_Q_SHIFT             8
+#define IXGBE_FDIRCTRL_FLEX_SHIFT               16
+#define IXGBE_FDIRCTRL_SEARCHLIM                0x00800000
+#define IXGBE_FDIRCTRL_MAX_LENGTH_SHIFT         24
+#define IXGBE_FDIRCTRL_FULL_THRESH_MASK         0xF0000000
+#define IXGBE_FDIRCTRL_FULL_THRESH_SHIFT        28
+
+#define IXGBE_FDIRTCPM_DPORTM_SHIFT             16
+#define IXGBE_FDIRUDPM_DPORTM_SHIFT             16
+#define IXGBE_FDIRIP6M_DIPM_SHIFT               16
+#define IXGBE_FDIRM_VLANID                      0x00000001
+#define IXGBE_FDIRM_VLANP                       0x00000002
+#define IXGBE_FDIRM_POOL                        0x00000004
+#define IXGBE_FDIRM_L3P                         0x00000008
+#define IXGBE_FDIRM_L4P                         0x00000010
+#define IXGBE_FDIRM_FLEX                        0x00000020
+#define IXGBE_FDIRM_DIPv6                       0x00000040
+
+#define IXGBE_FDIRFREE_FREE_MASK                0xFFFF
+#define IXGBE_FDIRFREE_FREE_SHIFT               0
+#define IXGBE_FDIRFREE_COLL_MASK                0x7FFF0000
+#define IXGBE_FDIRFREE_COLL_SHIFT               16
+#define IXGBE_FDIRLEN_MAXLEN_MASK               0x3F
+#define IXGBE_FDIRLEN_MAXLEN_SHIFT              0
+#define IXGBE_FDIRLEN_MAXHASH_MASK              0x7FFF0000
+#define IXGBE_FDIRLEN_MAXHASH_SHIFT             16
+#define IXGBE_FDIRUSTAT_ADD_MASK                0xFFFF
+#define IXGBE_FDIRUSTAT_ADD_SHIFT               0
+#define IXGBE_FDIRUSTAT_REMOVE_MASK             0xFFFF0000
+#define IXGBE_FDIRUSTAT_REMOVE_SHIFT            16
+#define IXGBE_FDIRFSTAT_FADD_MASK               0x00FF
+#define IXGBE_FDIRFSTAT_FADD_SHIFT              0
+#define IXGBE_FDIRFSTAT_FREMOVE_MASK            0xFF00
+#define IXGBE_FDIRFSTAT_FREMOVE_SHIFT           8
+#define IXGBE_FDIRPORT_DESTINATION_SHIFT        16
+#define IXGBE_FDIRVLAN_FLEX_SHIFT               16
+#define IXGBE_FDIRHASH_BUCKET_VALID_SHIFT       15
+#define IXGBE_FDIRHASH_SIG_SW_INDEX_SHIFT       16
+
+#define IXGBE_FDIRCMD_CMD_MASK                  0x00000003
+#define IXGBE_FDIRCMD_CMD_ADD_FLOW              0x00000001
+#define IXGBE_FDIRCMD_CMD_REMOVE_FLOW           0x00000002
+#define IXGBE_FDIRCMD_CMD_QUERY_REM_FILT        0x00000003
+#define IXGBE_FDIRCMD_CMD_QUERY_REM_HASH        0x00000007
+#define IXGBE_FDIRCMD_FILTER_UPDATE             0x00000008
+#define IXGBE_FDIRCMD_IPv6DMATCH                0x00000010
+#define IXGBE_FDIRCMD_L4TYPE_UDP                0x00000020
+#define IXGBE_FDIRCMD_L4TYPE_TCP                0x00000040
+#define IXGBE_FDIRCMD_L4TYPE_SCTP               0x00000060
+#define IXGBE_FDIRCMD_IPV6                      0x00000080
+#define IXGBE_FDIRCMD_CLEARHT                   0x00000100
+#define IXGBE_FDIRCMD_DROP                      0x00000200
+#define IXGBE_FDIRCMD_INT                       0x00000400
+#define IXGBE_FDIRCMD_LAST                      0x00000800
+#define IXGBE_FDIRCMD_COLLISION                 0x00001000
+#define IXGBE_FDIRCMD_QUEUE_EN                  0x00008000
+#define IXGBE_FDIRCMD_RX_QUEUE_SHIFT            16
+#define IXGBE_FDIRCMD_VT_POOL_SHIFT             24
+#define IXGBE_FDIR_INIT_DONE_POLL               10
+#define IXGBE_FDIRCMD_CMD_POLL                  10
+
 /* Transmit Descriptor - Legacy */
 struct ixgbe_legacy_tx_desc {
        u64 buffer_addr;       /* Address of the descriptor's data buffer */
@@ -1836,6 +2019,16 @@ struct ixgbe_adv_tx_context_desc {
 #define IXGBE_ADVTXD_POPTS_IPSEC      0x00000400 /* IPSec offload request */
 #define IXGBE_ADVTXD_TUCMD_IPSEC_TYPE_ESP 0x00002000 /* IPSec Type ESP */
 #define IXGBE_ADVTXD_TUCMD_IPSEC_ENCRYPT_EN 0x00004000/* ESP Encrypt Enable */
+#define IXGBE_ADVTXT_TUCMD_FCOE      0x00008000       /* FCoE Frame Type */
+#define IXGBE_ADVTXD_FCOEF_EOF_MASK  (0x3 << 10)      /* FC EOF index */
+#define IXGBE_ADVTXD_FCOEF_SOF       ((1 << 2) << 10) /* FC SOF index */
+#define IXGBE_ADVTXD_FCOEF_PARINC    ((1 << 3) << 10) /* Rel_Off in F_CTL */
+#define IXGBE_ADVTXD_FCOEF_ORIE      ((1 << 4) << 10) /* Orientation: End */
+#define IXGBE_ADVTXD_FCOEF_ORIS      ((1 << 5) << 10) /* Orientation: Start */
+#define IXGBE_ADVTXD_FCOEF_EOF_N     (0x0 << 10)      /* 00: EOFn */
+#define IXGBE_ADVTXD_FCOEF_EOF_T     (0x1 << 10)      /* 01: EOFt */
+#define IXGBE_ADVTXD_FCOEF_EOF_NI    (0x2 << 10)      /* 10: EOFni */
+#define IXGBE_ADVTXD_FCOEF_EOF_A     (0x3 << 10)      /* 11: EOFa */
 #define IXGBE_ADVTXD_L4LEN_SHIFT     8  /* Adv ctxt L4LEN shift */
 #define IXGBE_ADVTXD_MSS_SHIFT       16  /* Adv ctxt MSS shift */
 
@@ -1861,7 +2054,7 @@ typedef u32 ixgbe_physical_layer;
 #define IXGBE_PHYSICAL_LAYER_UNKNOWN      0
 #define IXGBE_PHYSICAL_LAYER_10GBASE_T    0x0001
 #define IXGBE_PHYSICAL_LAYER_1000BASE_T   0x0002
-#define IXGBE_PHYSICAL_LAYER_100BASE_T    0x0004
+#define IXGBE_PHYSICAL_LAYER_100BASE_TX   0x0004
 #define IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU  0x0008
 #define IXGBE_PHYSICAL_LAYER_10GBASE_LR   0x0010
 #define IXGBE_PHYSICAL_LAYER_10GBASE_LRM  0x0020
@@ -1870,6 +2063,47 @@ typedef u32 ixgbe_physical_layer;
 #define IXGBE_PHYSICAL_LAYER_10GBASE_CX4  0x0100
 #define IXGBE_PHYSICAL_LAYER_1000BASE_KX  0x0200
 #define IXGBE_PHYSICAL_LAYER_1000BASE_BX  0x0400
+#define IXGBE_PHYSICAL_LAYER_10GBASE_KR   0x0800
+#define IXGBE_PHYSICAL_LAYER_10GBASE_XAUI 0x1000
+
+/* Software ATR hash keys */
+#define IXGBE_ATR_BUCKET_HASH_KEY    0xE214AD3D
+#define IXGBE_ATR_SIGNATURE_HASH_KEY 0x14364D17
+
+/* Software ATR input stream offsets and masks */
+#define IXGBE_ATR_VLAN_OFFSET       0
+#define IXGBE_ATR_SRC_IPV6_OFFSET   2
+#define IXGBE_ATR_SRC_IPV4_OFFSET  14
+#define IXGBE_ATR_DST_IPV6_OFFSET  18
+#define IXGBE_ATR_DST_IPV4_OFFSET  30
+#define IXGBE_ATR_SRC_PORT_OFFSET  34
+#define IXGBE_ATR_DST_PORT_OFFSET  36
+#define IXGBE_ATR_FLEX_BYTE_OFFSET 38
+#define IXGBE_ATR_VM_POOL_OFFSET   40
+#define IXGBE_ATR_L4TYPE_OFFSET    41
+
+#define IXGBE_ATR_L4TYPE_MASK      0x3
+#define IXGBE_ATR_L4TYPE_IPV6_MASK 0x4
+#define IXGBE_ATR_L4TYPE_UDP       0x1
+#define IXGBE_ATR_L4TYPE_TCP       0x2
+#define IXGBE_ATR_L4TYPE_SCTP      0x3
+#define IXGBE_ATR_HASH_MASK     0x7fff
+
+/* Flow Director ATR input struct. */
+struct ixgbe_atr_input {
+       /* Byte layout in order, all values with MSB first:
+        *
+        * vlan_id    - 2 bytes
+        * src_ip     - 16 bytes
+        * dst_ip     - 16 bytes
+        * src_port   - 2 bytes
+        * dst_port   - 2 bytes
+        * flex_bytes - 2 bytes
+        * vm_pool    - 1 byte
+        * l4type     - 1 byte
+        */
+       u8 byte_stream[42];
+};
 
 enum ixgbe_eeprom_type {
        ixgbe_eeprom_uninitialized = 0,
@@ -1897,6 +2131,7 @@ enum ixgbe_phy_type {
        ixgbe_phy_sfp_ftl,
        ixgbe_phy_sfp_unknown,
        ixgbe_phy_sfp_intel,
+       ixgbe_phy_sfp_unsupported,
        ixgbe_phy_generic
 };
 
@@ -2005,7 +2240,8 @@ struct ixgbe_fc_info {
        u16 pause_time; /* Flow Control Pause timer */
        bool send_xon; /* Flow control send XON */
        bool strict_ieee; /* Strict IEEE mode */
-       bool disable_fc_autoneg; /* Turn off autoneg FC mode */
+       bool disable_fc_autoneg; /* Do not autonegotiate FC */
+       bool fc_was_autonegged; /* Is current_mode the result of autonegging? */
        enum ixgbe_fc_mode current_mode; /* FC mode in effect */
        enum ixgbe_fc_mode requested_mode; /* FC mode requested by caller */
 };
@@ -2075,6 +2311,12 @@ struct ixgbe_hw_stats {
        u64 fdirfstat_fremove;
        u64 fdirmatch;
        u64 fdirmiss;
+       u64 fccrc;
+       u64 fcoerpdc;
+       u64 fcoeprc;
+       u64 fcoeptc;
+       u64 fcoedwrc;
+       u64 fcoedwtc;
 };
 
 /* forward declaration */
@@ -2101,6 +2343,8 @@ struct ixgbe_mac_operations {
        enum ixgbe_media_type (*get_media_type)(struct ixgbe_hw *);
        u32 (*get_supported_physical_layer)(struct ixgbe_hw *);
        s32 (*get_mac_addr)(struct ixgbe_hw *, u8 *);
+       s32 (*get_san_mac_addr)(struct ixgbe_hw *, u8 *);
+       s32 (*get_device_caps)(struct ixgbe_hw *, u16 *);
        s32 (*stop_adapter)(struct ixgbe_hw *);
        s32 (*get_bus_info)(struct ixgbe_hw *);
        void (*set_lan_id)(struct ixgbe_hw *);
@@ -2129,8 +2373,7 @@ struct ixgbe_mac_operations {
        s32 (*set_vmdq)(struct ixgbe_hw *, u32, u32);
        s32 (*clear_vmdq)(struct ixgbe_hw *, u32, u32);
        s32 (*init_rx_addrs)(struct ixgbe_hw *);
-       s32 (*update_uc_addr_list)(struct ixgbe_hw *, u8 *, u32,
-                                  ixgbe_mc_addr_itr);
+       s32 (*update_uc_addr_list)(struct ixgbe_hw *, struct list_head *);
        s32 (*update_mc_addr_list)(struct ixgbe_hw *, u8 *, u32,
                                   ixgbe_mc_addr_itr);
        s32 (*enable_mc)(struct ixgbe_hw *);
@@ -2140,12 +2383,13 @@ struct ixgbe_mac_operations {
        s32 (*init_uta_tables)(struct ixgbe_hw *);
 
        /* Flow Control */
-       s32 (*setup_fc)(struct ixgbe_hw *, s32);
+       s32 (*fc_enable)(struct ixgbe_hw *, s32);
 };
 
 struct ixgbe_phy_operations {
        s32 (*identify)(struct ixgbe_hw *);
        s32 (*identify_sfp)(struct ixgbe_hw *);
+       s32 (*init)(struct ixgbe_hw *);
        s32 (*reset)(struct ixgbe_hw *);
        s32 (*read_reg)(struct ixgbe_hw *, u32, u32, u16 *);
        s32 (*write_reg)(struct ixgbe_hw *, u32, u32, u16);
@@ -2173,6 +2417,7 @@ struct ixgbe_mac_info {
        enum ixgbe_mac_type             type;
        u8                              addr[IXGBE_ETH_LENGTH_OF_ADDRESS];
        u8                              perm_addr[IXGBE_ETH_LENGTH_OF_ADDRESS];
+       u8                              san_addr[IXGBE_ETH_LENGTH_OF_ADDRESS];
        s32                             mc_filter_type;
        u32                             mcft_size;
        u32                             vft_size;
@@ -2185,14 +2430,16 @@ struct ixgbe_mac_info {
        bool                            orig_link_settings_stored;
        bool                            autoneg;
        bool                            autoneg_succeeded;
+       bool                            autotry_restart;
 };
 
 struct ixgbe_phy_info {
        struct ixgbe_phy_operations     ops;
+       struct mdio_if_info             mdio;
        enum ixgbe_phy_type             type;
-       u32                             addr;
        u32                             id;
        enum ixgbe_sfp_type             sfp_type;
+       bool                            sfp_setup_needed;
        u32                             revision;
        enum ixgbe_media_type           media_type;
        bool                            reset_disable;
@@ -2249,6 +2496,8 @@ struct ixgbe_info {
 #define IXGBE_ERR_SFP_NOT_SUPPORTED             -19
 #define IXGBE_ERR_SFP_NOT_PRESENT               -20
 #define IXGBE_ERR_SFP_NO_INIT_SEQ_PRESENT       -21
+#define IXGBE_ERR_FDIR_REINIT_FAILED            -23
+#define IXGBE_ERR_EEPROM_VERSION                -24
 #define IXGBE_NOT_IMPLEMENTED                   0x7FFFFFFF
 
 #endif /* _IXGBE_TYPE_H_ */
index d3bf2f017cc27f0507b393a07761b198a15cd123..2a0174b62e964d613102e0ef14e32828b3b91c34 100644 (file)
@@ -270,6 +270,18 @@ static int ixpdev_close(struct net_device *dev)
        return 0;
 }
 
+static const struct net_device_ops ixpdev_netdev_ops = {
+       .ndo_open               = ixpdev_open,
+       .ndo_stop               = ixpdev_close,
+       .ndo_start_xmit         = ixpdev_xmit,
+       .ndo_change_mtu         = eth_change_mtu,
+       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_set_mac_address    = eth_mac_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+       .ndo_poll_controller    = ixpdev_poll_controller,
+#endif
+};
+
 struct net_device *ixpdev_alloc(int channel, int sizeof_priv)
 {
        struct net_device *dev;
@@ -279,12 +291,7 @@ struct net_device *ixpdev_alloc(int channel, int sizeof_priv)
        if (dev == NULL)
                return NULL;
 
-       dev->hard_start_xmit = ixpdev_xmit;
-       dev->open = ixpdev_open;
-       dev->stop = ixpdev_close;
-#ifdef CONFIG_NET_POLL_CONTROLLER
-       dev->poll_controller = ixpdev_poll_controller;
-#endif
+       dev->netdev_ops = &ixpdev_netdev_ops;
 
        dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM;
 
index 14248cfc3dfd165d74d2656d8a56431460478538..d12106b47bf2a6cbd9130c9f5840a4322108f5d2 100644 (file)
@@ -96,6 +96,18 @@ static int jazzsonic_close(struct net_device* dev)
        return err;
 }
 
+static const struct net_device_ops sonic_netdev_ops = {
+       .ndo_open               = jazzsonic_open,
+       .ndo_stop               = jazzsonic_close,
+       .ndo_start_xmit         = sonic_send_packet,
+       .ndo_get_stats          = sonic_get_stats,
+       .ndo_set_multicast_list = sonic_multicast_list,
+       .ndo_tx_timeout         = sonic_tx_timeout,
+       .ndo_change_mtu         = eth_change_mtu,
+       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_set_mac_address    = eth_mac_addr,
+};
+
 static int __init sonic_probe1(struct net_device *dev)
 {
        static unsigned version_printed;
@@ -179,12 +191,7 @@ static int __init sonic_probe1(struct net_device *dev)
        lp->rra_laddr = lp->rda_laddr + (SIZEOF_SONIC_RD * SONIC_NUM_RDS
                             * SONIC_BUS_SCALE(lp->dma_bitmode));
 
-       dev->open = jazzsonic_open;
-       dev->stop = jazzsonic_close;
-       dev->hard_start_xmit = sonic_send_packet;
-       dev->get_stats = sonic_get_stats;
-       dev->set_multicast_list = &sonic_multicast_list;
-       dev->tx_timeout = sonic_tx_timeout;
+       dev->netdev_ops = &sonic_netdev_ops;
        dev->watchdog_timeo = TX_TIMEOUT;
 
        /*
index 621a7c0c46ba7360e314878e1bd7d5a924673132..1e3c63d67b9177b8d22ffd55663529d3aa1ff976 100644 (file)
@@ -1939,7 +1939,6 @@ jme_start_xmit(struct sk_buff *skb, struct net_device *netdev)
                                TXCS_SELECT_QUEUE0 |
                                TXCS_QUEUE0S |
                                TXCS_ENABLE);
-       netdev->trans_start = jiffies;
 
        tx_dbg(jme, "xmit: %d+%d@%lu\n", idx,
                        skb_shinfo(skb)->nr_frags + 2,
index 38d6649a29c42a491139b2cb882d3a68421c0fc3..b4cf602c32b079a71e495518ce57653f760d6122 100644 (file)
@@ -133,6 +133,7 @@ struct korina_private {
        int dma_halt_cnt;
        int dma_run_cnt;
        struct napi_struct napi;
+       struct timer_list media_check_timer;
        struct mii_if_info mii_if;
        struct net_device *dev;
        int phy_addr;
@@ -664,6 +665,15 @@ static void korina_check_media(struct net_device *dev, unsigned int init_media)
                                                &lp->eth_regs->ethmac2);
 }
 
+static void korina_poll_media(unsigned long data)
+{
+       struct net_device *dev = (struct net_device *) data;
+       struct korina_private *lp = netdev_priv(dev);
+
+       korina_check_media(dev, 0);
+       mod_timer(&lp->media_check_timer, jiffies + HZ);
+}
+
 static void korina_set_carrier(struct mii_if_info *mii)
 {
        if (mii->force_media) {
@@ -1034,6 +1044,7 @@ static int korina_open(struct net_device *dev)
                    dev->name, lp->und_irq);
                goto err_free_ovr_irq;
        }
+       mod_timer(&lp->media_check_timer, jiffies + 1);
 out:
        return ret;
 
@@ -1053,6 +1064,8 @@ static int korina_close(struct net_device *dev)
        struct korina_private *lp = netdev_priv(dev);
        u32 tmp;
 
+       del_timer(&lp->media_check_timer);
+
        /* Disable interrupts */
        disable_irq(lp->rx_irq);
        disable_irq(lp->tx_irq);
@@ -1081,6 +1094,21 @@ static int korina_close(struct net_device *dev)
        return 0;
 }
 
+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_tx_timeout         = korina_tx_timeout,
+       .ndo_do_ioctl           = korina_ioctl,
+       .ndo_change_mtu         = eth_change_mtu,
+       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_set_mac_address    = eth_mac_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+       .ndo_poll_controller    = korina_poll_controller,
+#endif
+};
+
 static int korina_probe(struct platform_device *pdev)
 {
        struct korina_device *bif = platform_get_drvdata(pdev);
@@ -1149,17 +1177,9 @@ static int korina_probe(struct platform_device *pdev)
        dev->irq = lp->rx_irq;
        lp->dev = dev;
 
-       dev->open = korina_open;
-       dev->stop = korina_close;
-       dev->hard_start_xmit = korina_send_packet;
-       dev->set_multicast_list = &korina_multicast_list;
+       dev->netdev_ops = &korina_netdev_ops;
        dev->ethtool_ops = &netdev_ethtool_ops;
-       dev->tx_timeout = korina_tx_timeout;
        dev->watchdog_timeo = TX_TIMEOUT;
-       dev->do_ioctl = &korina_ioctl;
-#ifdef CONFIG_NET_POLL_CONTROLLER
-       dev->poll_controller = korina_poll_controller;
-#endif
        netif_napi_add(dev, &lp->napi, korina_poll, 64);
 
        lp->phy_addr = (((lp->rx_irq == 0x2c? 1:0) << 8) | 0x05);
@@ -1176,6 +1196,7 @@ static int korina_probe(struct platform_device *pdev)
                        ": cannot register net device %d\n", rc);
                goto probe_err_register;
        }
+       setup_timer(&lp->media_check_timer, korina_poll_media, (unsigned long) dev);
 out:
        return rc;
 
diff --git a/drivers/net/ks8842.c b/drivers/net/ks8842.c
new file mode 100644 (file)
index 0000000..39b0aea
--- /dev/null
@@ -0,0 +1,732 @@
+/*
+ * ks8842_main.c timberdale KS8842 ethernet driver
+ * Copyright (c) 2009 Intel Corporation
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* Supports:
+ * The Micrel KS8842 behind the timberdale FPGA
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+
+#define DRV_NAME "ks8842"
+
+/* Timberdale specific Registers */
+#define REG_TIMB_RST   0x1c
+
+/* KS8842 registers */
+
+#define REG_SELECT_BANK 0x0e
+
+/* bank 0 registers */
+#define REG_QRFCR      0x04
+
+/* bank 2 registers */
+#define REG_MARL       0x00
+#define REG_MARM       0x02
+#define REG_MARH       0x04
+
+/* bank 3 registers */
+#define REG_GRR                0x06
+
+/* bank 16 registers */
+#define REG_TXCR       0x00
+#define REG_TXSR       0x02
+#define REG_RXCR       0x04
+#define REG_TXMIR      0x08
+#define REG_RXMIR      0x0A
+
+/* bank 17 registers */
+#define REG_TXQCR      0x00
+#define REG_RXQCR      0x02
+#define REG_TXFDPR     0x04
+#define REG_RXFDPR     0x06
+#define REG_QMU_DATA_LO 0x08
+#define REG_QMU_DATA_HI 0x0A
+
+/* bank 18 registers */
+#define REG_IER                0x00
+#define IRQ_LINK_CHANGE        0x8000
+#define IRQ_TX         0x4000
+#define IRQ_RX         0x2000
+#define IRQ_RX_OVERRUN 0x0800
+#define IRQ_TX_STOPPED 0x0200
+#define IRQ_RX_STOPPED 0x0100
+#define IRQ_RX_ERROR   0x0080
+#define ENABLED_IRQS   (IRQ_LINK_CHANGE | IRQ_TX | IRQ_RX | IRQ_RX_STOPPED | \
+               IRQ_TX_STOPPED | IRQ_RX_OVERRUN | IRQ_RX_ERROR)
+#define REG_ISR                0x02
+#define REG_RXSR       0x04
+#define RXSR_VALID     0x8000
+#define RXSR_BROADCAST 0x80
+#define RXSR_MULTICAST 0x40
+#define RXSR_UNICAST   0x20
+#define RXSR_FRAMETYPE 0x08
+#define RXSR_TOO_LONG  0x04
+#define RXSR_RUNT      0x02
+#define RXSR_CRC_ERROR 0x01
+#define RXSR_ERROR     (RXSR_TOO_LONG | RXSR_RUNT | RXSR_CRC_ERROR)
+
+/* bank 32 registers */
+#define REG_SW_ID_AND_ENABLE   0x00
+#define REG_SGCR1              0x02
+#define REG_SGCR2              0x04
+#define REG_SGCR3              0x06
+
+/* bank 39 registers */
+#define REG_MACAR1             0x00
+#define REG_MACAR2             0x02
+#define REG_MACAR3             0x04
+
+/* bank 45 registers */
+#define REG_P1MBCR             0x00
+#define REG_P1MBSR             0x02
+
+/* bank 46 registers */
+#define REG_P2MBCR             0x00
+#define REG_P2MBSR             0x02
+
+/* bank 48 registers */
+#define REG_P1CR2              0x02
+
+/* bank 49 registers */
+#define REG_P1CR4              0x02
+#define REG_P1SR               0x04
+
+struct ks8842_adapter {
+       void __iomem    *hw_addr;
+       int             irq;
+       struct tasklet_struct   tasklet;
+       spinlock_t      lock; /* spinlock to be interrupt safe */
+       struct platform_device *pdev;
+};
+
+static inline void ks8842_select_bank(struct ks8842_adapter *adapter, u16 bank)
+{
+       iowrite16(bank, adapter->hw_addr + REG_SELECT_BANK);
+}
+
+static inline void ks8842_write8(struct ks8842_adapter *adapter, u16 bank,
+       u8 value, int offset)
+{
+       ks8842_select_bank(adapter, bank);
+       iowrite8(value, adapter->hw_addr + offset);
+}
+
+static inline void ks8842_write16(struct ks8842_adapter *adapter, u16 bank,
+       u16 value, int offset)
+{
+       ks8842_select_bank(adapter, bank);
+       iowrite16(value, adapter->hw_addr + offset);
+}
+
+static inline void ks8842_enable_bits(struct ks8842_adapter *adapter, u16 bank,
+       u16 bits, int offset)
+{
+       u16 reg;
+       ks8842_select_bank(adapter, bank);
+       reg = ioread16(adapter->hw_addr + offset);
+       reg |= bits;
+       iowrite16(reg, adapter->hw_addr + offset);
+}
+
+static inline void ks8842_clear_bits(struct ks8842_adapter *adapter, u16 bank,
+       u16 bits, int offset)
+{
+       u16 reg;
+       ks8842_select_bank(adapter, bank);
+       reg = ioread16(adapter->hw_addr + offset);
+       reg &= ~bits;
+       iowrite16(reg, adapter->hw_addr + offset);
+}
+
+static inline void ks8842_write32(struct ks8842_adapter *adapter, u16 bank,
+       u32 value, int offset)
+{
+       ks8842_select_bank(adapter, bank);
+       iowrite32(value, adapter->hw_addr + offset);
+}
+
+static inline u8 ks8842_read8(struct ks8842_adapter *adapter, u16 bank,
+       int offset)
+{
+       ks8842_select_bank(adapter, bank);
+       return ioread8(adapter->hw_addr + offset);
+}
+
+static inline u16 ks8842_read16(struct ks8842_adapter *adapter, u16 bank,
+       int offset)
+{
+       ks8842_select_bank(adapter, bank);
+       return ioread16(adapter->hw_addr + offset);
+}
+
+static inline u32 ks8842_read32(struct ks8842_adapter *adapter, u16 bank,
+       int offset)
+{
+       ks8842_select_bank(adapter, bank);
+       return ioread32(adapter->hw_addr + offset);
+}
+
+static void ks8842_reset(struct ks8842_adapter *adapter)
+{
+       /* The KS8842 goes haywire when doing softare reset
+        * a work around in the timberdale IP is implemented to
+        * do a hardware reset instead
+       ks8842_write16(adapter, 3, 1, REG_GRR);
+       msleep(10);
+       iowrite16(0, adapter->hw_addr + REG_GRR);
+       */
+       iowrite16(32, adapter->hw_addr + REG_SELECT_BANK);
+       iowrite32(0x1, adapter->hw_addr + REG_TIMB_RST);
+       msleep(20);
+}
+
+static void ks8842_update_link_status(struct net_device *netdev,
+       struct ks8842_adapter *adapter)
+{
+       /* check the status of the link */
+       if (ks8842_read16(adapter, 45, REG_P1MBSR) & 0x4) {
+               netif_carrier_on(netdev);
+               netif_wake_queue(netdev);
+       } else {
+               netif_stop_queue(netdev);
+               netif_carrier_off(netdev);
+       }
+}
+
+static void ks8842_enable_tx(struct ks8842_adapter *adapter)
+{
+       ks8842_enable_bits(adapter, 16, 0x01, REG_TXCR);
+}
+
+static void ks8842_disable_tx(struct ks8842_adapter *adapter)
+{
+       ks8842_clear_bits(adapter, 16, 0x01, REG_TXCR);
+}
+
+static void ks8842_enable_rx(struct ks8842_adapter *adapter)
+{
+       ks8842_enable_bits(adapter, 16, 0x01, REG_RXCR);
+}
+
+static void ks8842_disable_rx(struct ks8842_adapter *adapter)
+{
+       ks8842_clear_bits(adapter, 16, 0x01, REG_RXCR);
+}
+
+static void ks8842_reset_hw(struct ks8842_adapter *adapter)
+{
+       /* reset the HW */
+       ks8842_reset(adapter);
+
+       /* Enable QMU Transmit flow control / transmit padding / Transmit CRC */
+       ks8842_write16(adapter, 16, 0x000E, REG_TXCR);
+
+       /* enable the receiver, uni + multi + broadcast + flow ctrl
+               + crc strip */
+       ks8842_write16(adapter, 16, 0x8 | 0x20 | 0x40 | 0x80 | 0x400,
+               REG_RXCR);
+
+       /* TX frame pointer autoincrement */
+       ks8842_write16(adapter, 17, 0x4000, REG_TXFDPR);
+
+       /* RX frame pointer autoincrement */
+       ks8842_write16(adapter, 17, 0x4000, REG_RXFDPR);
+
+       /* RX 2 kb high watermark */
+       ks8842_write16(adapter, 0, 0x1000, REG_QRFCR);
+
+       /* aggresive back off in half duplex */
+       ks8842_enable_bits(adapter, 32, 1 << 8, REG_SGCR1);
+
+       /* enable no excessive collison drop */
+       ks8842_enable_bits(adapter, 32, 1 << 3, REG_SGCR2);
+
+       /* Enable port 1 force flow control / back pressure / transmit / recv */
+       ks8842_write16(adapter, 48, 0x1E07, REG_P1CR2);
+
+       /* restart port auto-negotiation */
+       ks8842_enable_bits(adapter, 49, 1 << 13, REG_P1CR4);
+       /* only advertise 10Mbps */
+       ks8842_clear_bits(adapter, 49, 3 << 2, REG_P1CR4);
+
+       /* Enable the transmitter */
+       ks8842_enable_tx(adapter);
+
+       /* Enable the receiver */
+       ks8842_enable_rx(adapter);
+
+       /* clear all interrupts */
+       ks8842_write16(adapter, 18, 0xffff, REG_ISR);
+
+       /* enable interrupts */
+       ks8842_write16(adapter, 18, ENABLED_IRQS, REG_IER);
+
+       /* enable the switch */
+       ks8842_write16(adapter, 32, 0x1, REG_SW_ID_AND_ENABLE);
+}
+
+static void ks8842_read_mac_addr(struct ks8842_adapter *adapter, u8 *dest)
+{
+       int i;
+       u16 mac;
+
+       for (i = 0; i < ETH_ALEN; i++)
+               dest[ETH_ALEN - i - 1] = ks8842_read8(adapter, 2, REG_MARL + i);
+
+       /* make sure the switch port uses the same MAC as the QMU */
+       mac = ks8842_read16(adapter, 2, REG_MARL);
+       ks8842_write16(adapter, 39, mac, REG_MACAR1);
+       mac = ks8842_read16(adapter, 2, REG_MARM);
+       ks8842_write16(adapter, 39, mac, REG_MACAR2);
+       mac = ks8842_read16(adapter, 2, REG_MARH);
+       ks8842_write16(adapter, 39, mac, REG_MACAR3);
+}
+
+static inline u16 ks8842_tx_fifo_space(struct ks8842_adapter *adapter)
+{
+       return ks8842_read16(adapter, 16, REG_TXMIR) & 0x1fff;
+}
+
+static int ks8842_tx_frame(struct sk_buff *skb, struct net_device *netdev)
+{
+       struct ks8842_adapter *adapter = netdev_priv(netdev);
+       int len = skb->len;
+       u32 *ptr = (u32 *)skb->data;
+       u32 ctrl;
+
+       dev_dbg(&adapter->pdev->dev,
+               "%s: len %u head %p data %p tail %p end %p\n",
+               __func__, skb->len, skb->head, skb->data,
+               skb_tail_pointer(skb), skb_end_pointer(skb));
+
+       /* check FIFO buffer space, we need space for CRC and command bits */
+       if (ks8842_tx_fifo_space(adapter) < len + 8)
+               return NETDEV_TX_BUSY;
+
+       /* the control word, enable IRQ, port 1 and the length */
+       ctrl = 0x8000 | 0x100 | (len << 16);
+       ks8842_write32(adapter, 17, ctrl, REG_QMU_DATA_LO);
+
+       netdev->stats.tx_bytes += len;
+
+       /* copy buffer */
+       while (len > 0) {
+               iowrite32(*ptr, adapter->hw_addr + REG_QMU_DATA_LO);
+               len -= sizeof(u32);
+               ptr++;
+       }
+
+       /* enqueue packet */
+       ks8842_write16(adapter, 17, 1, REG_TXQCR);
+
+       dev_kfree_skb(skb);
+
+       return NETDEV_TX_OK;
+}
+
+static void ks8842_rx_frame(struct net_device *netdev,
+       struct ks8842_adapter *adapter)
+{
+       u32 status = ks8842_read32(adapter, 17, REG_QMU_DATA_LO);
+       int len = (status >> 16) & 0x7ff;
+
+       status &= 0xffff;
+
+       dev_dbg(&adapter->pdev->dev, "%s - rx_data: status: %x\n",
+               __func__, status);
+
+       /* check the status */
+       if ((status & RXSR_VALID) && !(status & RXSR_ERROR)) {
+               struct sk_buff *skb = netdev_alloc_skb(netdev, len + 2);
+
+               dev_dbg(&adapter->pdev->dev, "%s, got package, len: %d\n",
+                       __func__, len);
+               if (skb) {
+                       u32 *data;
+
+                       netdev->stats.rx_packets++;
+                       netdev->stats.rx_bytes += len;
+                       if (status & RXSR_MULTICAST)
+                               netdev->stats.multicast++;
+
+                       /* Align socket buffer in 4-byte boundary for
+                                better performance. */
+                       skb_reserve(skb, 2);
+                       data = (u32 *)skb_put(skb, len);
+
+                       ks8842_select_bank(adapter, 17);
+                       while (len > 0) {
+                               *data++ = ioread32(adapter->hw_addr +
+                                       REG_QMU_DATA_LO);
+                               len -= sizeof(u32);
+                       }
+
+                       skb->protocol = eth_type_trans(skb, netdev);
+                       netif_rx(skb);
+               } else
+                       netdev->stats.rx_dropped++;
+       } else {
+               dev_dbg(&adapter->pdev->dev, "RX error, status: %x\n", status);
+               netdev->stats.rx_errors++;
+               if (status & RXSR_TOO_LONG)
+                       netdev->stats.rx_length_errors++;
+               if (status & RXSR_CRC_ERROR)
+                       netdev->stats.rx_crc_errors++;
+               if (status & RXSR_RUNT)
+                       netdev->stats.rx_frame_errors++;
+       }
+
+       /* set high watermark to 3K */
+       ks8842_clear_bits(adapter, 0, 1 << 12, REG_QRFCR);
+
+       /* release the frame */
+       ks8842_write16(adapter, 17, 0x01, REG_RXQCR);
+
+       /* set high watermark to 2K */
+       ks8842_enable_bits(adapter, 0, 1 << 12, REG_QRFCR);
+}
+
+void ks8842_handle_rx(struct net_device *netdev, struct ks8842_adapter *adapter)
+{
+       u16 rx_data = ks8842_read16(adapter, 16, REG_RXMIR) & 0x1fff;
+       dev_dbg(&adapter->pdev->dev, "%s Entry - rx_data: %d\n",
+               __func__, rx_data);
+       while (rx_data) {
+               ks8842_rx_frame(netdev, adapter);
+               rx_data = ks8842_read16(adapter, 16, REG_RXMIR) & 0x1fff;
+       }
+}
+
+void ks8842_handle_tx(struct net_device *netdev, struct ks8842_adapter *adapter)
+{
+       u16 sr = ks8842_read16(adapter, 16, REG_TXSR);
+       dev_dbg(&adapter->pdev->dev, "%s - entry, sr: %x\n", __func__, sr);
+       netdev->stats.tx_packets++;
+       if (netif_queue_stopped(netdev))
+               netif_wake_queue(netdev);
+}
+
+void ks8842_handle_rx_overrun(struct net_device *netdev,
+       struct ks8842_adapter *adapter)
+{
+       dev_dbg(&adapter->pdev->dev, "%s: entry\n", __func__);
+       netdev->stats.rx_errors++;
+       netdev->stats.rx_fifo_errors++;
+}
+
+void ks8842_tasklet(unsigned long arg)
+{
+       struct net_device *netdev = (struct net_device *)arg;
+       struct ks8842_adapter *adapter = netdev_priv(netdev);
+       u16 isr;
+       unsigned long flags;
+       u16 entry_bank;
+
+       /* read current bank to be able to set it back */
+       spin_lock_irqsave(&adapter->lock, flags);
+       entry_bank = ioread16(adapter->hw_addr + REG_SELECT_BANK);
+       spin_unlock_irqrestore(&adapter->lock, flags);
+
+       isr = ks8842_read16(adapter, 18, REG_ISR);
+       dev_dbg(&adapter->pdev->dev, "%s - ISR: 0x%x\n", __func__, isr);
+
+       /* Ack */
+       ks8842_write16(adapter, 18, isr, REG_ISR);
+
+       if (!netif_running(netdev))
+               return;
+
+       if (isr & IRQ_LINK_CHANGE)
+               ks8842_update_link_status(netdev, adapter);
+
+       if (isr & (IRQ_RX | IRQ_RX_ERROR))
+               ks8842_handle_rx(netdev, adapter);
+
+       if (isr & IRQ_TX)
+               ks8842_handle_tx(netdev, adapter);
+
+       if (isr & IRQ_RX_OVERRUN)
+               ks8842_handle_rx_overrun(netdev, adapter);
+
+       if (isr & IRQ_TX_STOPPED) {
+               ks8842_disable_tx(adapter);
+               ks8842_enable_tx(adapter);
+       }
+
+       if (isr & IRQ_RX_STOPPED) {
+               ks8842_disable_rx(adapter);
+               ks8842_enable_rx(adapter);
+       }
+
+       /* re-enable interrupts, put back the bank selection register */
+       spin_lock_irqsave(&adapter->lock, flags);
+       ks8842_write16(adapter, 18, ENABLED_IRQS, REG_IER);
+       iowrite16(entry_bank, adapter->hw_addr + REG_SELECT_BANK);
+       spin_unlock_irqrestore(&adapter->lock, flags);
+}
+
+static irqreturn_t ks8842_irq(int irq, void *devid)
+{
+       struct ks8842_adapter *adapter = devid;
+       u16 isr;
+       u16 entry_bank = ioread16(adapter->hw_addr + REG_SELECT_BANK);
+       irqreturn_t ret = IRQ_NONE;
+
+       isr = ks8842_read16(adapter, 18, REG_ISR);
+       dev_dbg(&adapter->pdev->dev, "%s - ISR: 0x%x\n", __func__, isr);
+
+       if (isr) {
+               /* disable IRQ */
+               ks8842_write16(adapter, 18, 0x00, REG_IER);
+
+               /* schedule tasklet */
+               tasklet_schedule(&adapter->tasklet);
+
+               ret = IRQ_HANDLED;
+       }
+
+       iowrite16(entry_bank, adapter->hw_addr + REG_SELECT_BANK);
+
+       return ret;
+}
+
+
+/* Netdevice operations */
+
+static int ks8842_open(struct net_device *netdev)
+{
+       struct ks8842_adapter *adapter = netdev_priv(netdev);
+       int err;
+
+       dev_dbg(&adapter->pdev->dev, "%s - entry\n", __func__);
+
+       /* reset the HW */
+       ks8842_reset_hw(adapter);
+
+       ks8842_update_link_status(netdev, adapter);
+
+       err = request_irq(adapter->irq, ks8842_irq, IRQF_SHARED, DRV_NAME,
+               adapter);
+       if (err) {
+               printk(KERN_ERR "Failed to request IRQ: %d: %d\n",
+                       adapter->irq, err);
+               return err;
+       }
+
+       return 0;
+}
+
+static int ks8842_close(struct net_device *netdev)
+{
+       struct ks8842_adapter *adapter = netdev_priv(netdev);
+
+       dev_dbg(&adapter->pdev->dev, "%s - entry\n", __func__);
+
+       /* free the irq */
+       free_irq(adapter->irq, adapter);
+
+       /* disable the switch */
+       ks8842_write16(adapter, 32, 0x0, REG_SW_ID_AND_ENABLE);
+
+       return 0;
+}
+
+static int ks8842_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
+{
+       int ret;
+       struct ks8842_adapter *adapter = netdev_priv(netdev);
+
+       dev_dbg(&adapter->pdev->dev, "%s: entry\n", __func__);
+
+       ret = ks8842_tx_frame(skb, netdev);
+
+       if (ks8842_tx_fifo_space(adapter) <  netdev->mtu + 8)
+               netif_stop_queue(netdev);
+
+       return ret;
+}
+
+static int ks8842_set_mac(struct net_device *netdev, void *p)
+{
+       struct ks8842_adapter *adapter = netdev_priv(netdev);
+       unsigned long flags;
+       struct sockaddr *addr = p;
+       char *mac = (u8 *)addr->sa_data;
+       int i;
+
+       dev_dbg(&adapter->pdev->dev, "%s: entry\n", __func__);
+
+       if (!is_valid_ether_addr(addr->sa_data))
+               return -EADDRNOTAVAIL;
+
+       memcpy(netdev->dev_addr, mac, netdev->addr_len);
+
+       spin_lock_irqsave(&adapter->lock, flags);
+       for (i = 0; i < ETH_ALEN; i++) {
+               ks8842_write8(adapter, 2, mac[ETH_ALEN - i - 1], REG_MARL + i);
+               ks8842_write8(adapter, 39, mac[ETH_ALEN - i - 1],
+                       REG_MACAR1 + i);
+       }
+       spin_unlock_irqrestore(&adapter->lock, flags);
+       return 0;
+}
+
+static void ks8842_tx_timeout(struct net_device *netdev)
+{
+       struct ks8842_adapter *adapter = netdev_priv(netdev);
+       unsigned long flags;
+
+       dev_dbg(&adapter->pdev->dev, "%s: entry\n", __func__);
+
+       spin_lock_irqsave(&adapter->lock, flags);
+       /* disable interrupts */
+       ks8842_write16(adapter, 18, 0, REG_IER);
+       ks8842_write16(adapter, 18, 0xFFFF, REG_ISR);
+       spin_unlock_irqrestore(&adapter->lock, flags);
+
+       ks8842_reset_hw(adapter);
+
+       ks8842_update_link_status(netdev, adapter);
+}
+
+static const struct net_device_ops ks8842_netdev_ops = {
+       .ndo_open               = ks8842_open,
+       .ndo_stop               = ks8842_close,
+       .ndo_start_xmit         = ks8842_xmit_frame,
+       .ndo_set_mac_address    = ks8842_set_mac,
+       .ndo_tx_timeout         = ks8842_tx_timeout,
+       .ndo_validate_addr      = eth_validate_addr
+};
+
+static struct ethtool_ops ks8842_ethtool_ops = {
+       .get_link               = ethtool_op_get_link,
+};
+
+static int __devinit ks8842_probe(struct platform_device *pdev)
+{
+       int err = -ENOMEM;
+       struct resource *iomem;
+       struct net_device *netdev;
+       struct ks8842_adapter *adapter;
+       u16 id;
+
+       iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!request_mem_region(iomem->start, resource_size(iomem), DRV_NAME))
+               goto err_mem_region;
+
+       netdev = alloc_etherdev(sizeof(struct ks8842_adapter));
+       if (!netdev)
+               goto err_alloc_etherdev;
+
+       SET_NETDEV_DEV(netdev, &pdev->dev);
+
+       adapter = netdev_priv(netdev);
+       adapter->hw_addr = ioremap(iomem->start, resource_size(iomem));
+       if (!adapter->hw_addr)
+               goto err_ioremap;
+
+       adapter->irq = platform_get_irq(pdev, 0);
+       if (adapter->irq < 0) {
+               err = adapter->irq;
+               goto err_get_irq;
+       }
+
+       adapter->pdev = pdev;
+
+       tasklet_init(&adapter->tasklet, ks8842_tasklet, (unsigned long)netdev);
+       spin_lock_init(&adapter->lock);
+
+       netdev->netdev_ops = &ks8842_netdev_ops;
+       netdev->ethtool_ops = &ks8842_ethtool_ops;
+
+       ks8842_read_mac_addr(adapter, netdev->dev_addr);
+
+       id = ks8842_read16(adapter, 32, REG_SW_ID_AND_ENABLE);
+
+       strcpy(netdev->name, "eth%d");
+       err = register_netdev(netdev);
+       if (err)
+               goto err_register;
+
+       platform_set_drvdata(pdev, netdev);
+
+       printk(KERN_INFO DRV_NAME
+               " Found chip, family: 0x%x, id: 0x%x, rev: 0x%x\n",
+               (id >> 8) & 0xff, (id >> 4) & 0xf, (id >> 1) & 0x7);
+
+       return 0;
+
+err_register:
+err_get_irq:
+       iounmap(adapter->hw_addr);
+err_ioremap:
+       free_netdev(netdev);
+err_alloc_etherdev:
+       release_mem_region(iomem->start, resource_size(iomem));
+err_mem_region:
+       return err;
+}
+
+static int __devexit ks8842_remove(struct platform_device *pdev)
+{
+       struct net_device *netdev = platform_get_drvdata(pdev);
+       struct ks8842_adapter *adapter = netdev_priv(netdev);
+       struct resource *iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+       unregister_netdev(netdev);
+       tasklet_kill(&adapter->tasklet);
+       iounmap(adapter->hw_addr);
+       free_netdev(netdev);
+       release_mem_region(iomem->start, resource_size(iomem));
+       platform_set_drvdata(pdev, NULL);
+       return 0;
+}
+
+
+static struct platform_driver ks8842_platform_driver = {
+       .driver = {
+               .name   = DRV_NAME,
+               .owner  = THIS_MODULE,
+       },
+       .probe          = ks8842_probe,
+       .remove         = ks8842_remove,
+};
+
+static int __init ks8842_init(void)
+{
+       return platform_driver_register(&ks8842_platform_driver);
+}
+
+static void __exit ks8842_exit(void)
+{
+       platform_driver_unregister(&ks8842_platform_driver);
+}
+
+module_init(ks8842_init);
+module_exit(ks8842_exit);
+
+MODULE_DESCRIPTION("Timberdale KS8842 ethernet driver");
+MODULE_AUTHOR("Mocean Laboratories <info@mocean-labs.com>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:ks8842");
+
index efbae4b8398e5b6cbdf8da59db85f83e18fd7212..a0c578585a50fe9f2a609ea7d6b406357f0b035b 100644 (file)
@@ -161,12 +161,12 @@ lan_init_chip(struct parisc_device *dev)
 
        if (!dev->irq) {
                printk(KERN_ERR "%s: IRQ not found for i82596 at 0x%lx\n",
-                       __FILE__, dev->hpa.start);
+                       __FILE__, (unsigned long)dev->hpa.start);
                return -ENODEV;
        }
 
-       printk(KERN_INFO "Found i82596 at 0x%lx, IRQ %d\n", dev->hpa.start,
-                       dev->irq);
+       printk(KERN_INFO "Found i82596 at 0x%lx, IRQ %d\n",
+                       (unsigned long)dev->hpa.start, dev->irq);
 
        netdevice = alloc_etherdev(sizeof(struct i596_private));
        if (!netdevice)
index 7415f517491d73a6bfb7817e7f07c14f842a1923..070fa4500871eb57e73a4b3526b3053cfb5f8104 100644 (file)
@@ -1036,6 +1036,19 @@ static void print_eth(unsigned char *add, char *str)
        printk(KERN_DEBUG "i596 0x%p, %pM --> %pM %02X%02X, %s\n",
               add, add + 6, add, add[12], add[13], str);
 }
+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_tx_timeout         = i596_tx_timeout,
+       .ndo_change_mtu         = eth_change_mtu,
+       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_set_mac_address    = eth_mac_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+       .ndo_poll_controller    = i596_poll_controller,
+#endif
+};
 
 static int __devinit i82596_probe(struct net_device *dev)
 {
@@ -1062,16 +1075,8 @@ static int __devinit i82596_probe(struct net_device *dev)
                return -ENOMEM;
        }
 
-       /* The 82596-specific entries in the device structure. */
-       dev->open = i596_open;
-       dev->stop = i596_close;
-       dev->hard_start_xmit = i596_start_xmit;
-       dev->set_multicast_list = set_multicast_list;
-       dev->tx_timeout = i596_tx_timeout;
+       dev->netdev_ops = &i596_netdev_ops;
        dev->watchdog_timeo = TX_TIMEOUT;
-#ifdef CONFIG_NET_POLL_CONTROLLER
-       dev->poll_controller = i596_poll_controller;
-#endif
 
        memset(dma, 0, sizeof(struct i596_dma));
        lp->dma = dma;
index 789b6cb744b284ee08d4c749ab9fa210dc34170e..f28c23343009f26869bcaa8f13f1a0dc85ad54b7 100644 (file)
@@ -370,7 +370,7 @@ static int __ei_start_xmit(struct sk_buff *skb, struct net_device *dev)
                spin_unlock(&ei_local->page_lock);
                enable_irq_lockdep_irqrestore(dev->irq, &flags);
                dev->stats.tx_errors++;
-               return 1;
+               return NETDEV_TX_BUSY;
        }
 
        /*
diff --git a/drivers/net/ll_temac.h b/drivers/net/ll_temac.h
new file mode 100644 (file)
index 0000000..1af66a1
--- /dev/null
@@ -0,0 +1,374 @@
+
+#ifndef XILINX_LL_TEMAC_H
+#define XILINX_LL_TEMAC_H
+
+#include <linux/netdevice.h>
+#include <linux/of.h>
+#include <linux/spinlock.h>
+#include <asm/dcr.h>
+#include <asm/dcr-regs.h>
+
+/* packet size info */
+#define XTE_HDR_SIZE                   14      /* size of Ethernet header */
+#define XTE_TRL_SIZE                   4       /* size of Ethernet trailer (FCS) */
+#define XTE_JUMBO_MTU                  9000
+#define XTE_MAX_JUMBO_FRAME_SIZE       (XTE_JUMBO_MTU + XTE_HDR_SIZE + XTE_TRL_SIZE)
+
+/*  Configuration options */
+
+/*  Accept all incoming packets.
+ *  This option defaults to disabled (cleared) */
+#define XTE_OPTION_PROMISC                      (1 << 0)
+/*  Jumbo frame support for Tx & Rx.
+ *  This option defaults to disabled (cleared) */
+#define XTE_OPTION_JUMBO                        (1 << 1)
+/*  VLAN Rx & Tx frame support.
+ *  This option defaults to disabled (cleared) */
+#define XTE_OPTION_VLAN                         (1 << 2)
+/*  Enable recognition of flow control frames on Rx
+ *  This option defaults to enabled (set) */
+#define XTE_OPTION_FLOW_CONTROL                 (1 << 4)
+/*  Strip FCS and PAD from incoming frames.
+ *  Note: PAD from VLAN frames is not stripped.
+ *  This option defaults to disabled (set) */
+#define XTE_OPTION_FCS_STRIP                    (1 << 5)
+/*  Generate FCS field and add PAD automatically for outgoing frames.
+ *  This option defaults to enabled (set) */
+#define XTE_OPTION_FCS_INSERT                   (1 << 6)
+/*  Enable Length/Type error checking for incoming frames. When this option is
+set, the MAC will filter frames that have a mismatched type/length field
+and if XTE_OPTION_REPORT_RXERR is set, the user is notified when these
+types of frames are encountered. When this option is cleared, the MAC will
+allow these types of frames to be received.
+This option defaults to enabled (set) */
+#define XTE_OPTION_LENTYPE_ERR                  (1 << 7)
+/*  Enable the transmitter.
+ *  This option defaults to enabled (set) */
+#define XTE_OPTION_TXEN                         (1 << 11)
+/*  Enable the receiver
+*   This option defaults to enabled (set) */
+#define XTE_OPTION_RXEN                         (1 << 12)
+
+/*  Default options set when device is initialized or reset */
+#define XTE_OPTION_DEFAULTS                     \
+       (XTE_OPTION_TXEN |                          \
+        XTE_OPTION_FLOW_CONTROL |                  \
+        XTE_OPTION_RXEN)
+
+/* XPS_LL_TEMAC SDMA registers definition */
+
+#define TX_NXTDESC_PTR      0x00            /* r */
+#define TX_CURBUF_ADDR      0x01            /* r */
+#define TX_CURBUF_LENGTH    0x02            /* r */
+#define TX_CURDESC_PTR      0x03            /* rw */
+#define TX_TAILDESC_PTR     0x04            /* rw */
+#define TX_CHNL_CTRL        0x05            /* rw */
+/*
+ 0:7      24:31       IRQTimeout
+ 8:15     16:23       IRQCount
+ 16:20    11:15       Reserved
+ 21       10          0
+ 22       9           UseIntOnEnd
+ 23       8           LdIRQCnt
+ 24       7           IRQEn
+ 25:28    3:6         Reserved
+ 29       2           IrqErrEn
+ 30       1           IrqDlyEn
+ 31       0           IrqCoalEn
+*/
+#define CHNL_CTRL_IRQ_IOE       (1 << 9)
+#define CHNL_CTRL_IRQ_EN        (1 << 7)
+#define CHNL_CTRL_IRQ_ERR_EN    (1 << 2)
+#define CHNL_CTRL_IRQ_DLY_EN    (1 << 1)
+#define CHNL_CTRL_IRQ_COAL_EN   (1 << 0)
+#define TX_IRQ_REG          0x06            /* rw */
+/*
+  0:7      24:31       DltTmrValue
+ 8:15     16:23       ClscCntrValue
+ 16:17    14:15       Reserved
+ 18:21    10:13       ClscCnt
+ 22:23    8:9         DlyCnt
+ 24:28    3::7        Reserved
+ 29       2           ErrIrq
+ 30       1           DlyIrq
+ 31       0           CoalIrq
+ */
+#define TX_CHNL_STS         0x07            /* r */
+/*
+   0:9      22:31   Reserved
+ 10       21      TailPErr
+ 11       20      CmpErr
+ 12       19      AddrErr
+ 13       18      NxtPErr
+ 14       17      CurPErr
+ 15       16      BsyWr
+ 16:23    8:15    Reserved
+ 24       7       Error
+ 25       6       IOE
+ 26       5       SOE
+ 27       4       Cmplt
+ 28       3       SOP
+ 29       2       EOP
+ 30       1       EngBusy
+ 31       0       Reserved
+*/
+
+#define RX_NXTDESC_PTR      0x08            /* r */
+#define RX_CURBUF_ADDR      0x09            /* r */
+#define RX_CURBUF_LENGTH    0x0a            /* r */
+#define RX_CURDESC_PTR      0x0b            /* rw */
+#define RX_TAILDESC_PTR     0x0c            /* rw */
+#define RX_CHNL_CTRL        0x0d            /* rw */
+/*
+ 0:7      24:31       IRQTimeout
+ 8:15     16:23       IRQCount
+ 16:20    11:15       Reserved
+ 21       10          0
+ 22       9           UseIntOnEnd
+ 23       8           LdIRQCnt
+ 24       7           IRQEn
+ 25:28    3:6         Reserved
+ 29       2           IrqErrEn
+ 30       1           IrqDlyEn
+ 31       0           IrqCoalEn
+ */
+#define RX_IRQ_REG          0x0e            /* rw */
+#define IRQ_COAL        (1 << 0)
+#define IRQ_DLY         (1 << 1)
+#define IRQ_ERR         (1 << 2)
+#define IRQ_DMAERR      (1 << 7)            /* this is not documented ??? */
+/*
+ 0:7      24:31       DltTmrValue
+ 8:15     16:23       ClscCntrValue
+ 16:17    14:15       Reserved
+ 18:21    10:13       ClscCnt
+ 22:23    8:9         DlyCnt
+ 24:28    3::7        Reserved
+*/
+#define RX_CHNL_STS         0x0f        /* r */
+#define CHNL_STS_ENGBUSY    (1 << 1)
+#define CHNL_STS_EOP        (1 << 2)
+#define CHNL_STS_SOP        (1 << 3)
+#define CHNL_STS_CMPLT      (1 << 4)
+#define CHNL_STS_SOE        (1 << 5)
+#define CHNL_STS_IOE        (1 << 6)
+#define CHNL_STS_ERR        (1 << 7)
+
+#define CHNL_STS_BSYWR      (1 << 16)
+#define CHNL_STS_CURPERR    (1 << 17)
+#define CHNL_STS_NXTPERR    (1 << 18)
+#define CHNL_STS_ADDRERR    (1 << 19)
+#define CHNL_STS_CMPERR     (1 << 20)
+#define CHNL_STS_TAILERR    (1 << 21)
+/*
+ 0:9      22:31   Reserved
+ 10       21      TailPErr
+ 11       20      CmpErr
+ 12       19      AddrErr
+ 13       18      NxtPErr
+ 14       17      CurPErr
+ 15       16      BsyWr
+ 16:23    8:15    Reserved
+ 24       7       Error
+ 25       6       IOE
+ 26       5       SOE
+ 27       4       Cmplt
+ 28       3       SOP
+ 29       2       EOP
+ 30       1       EngBusy
+ 31       0       Reserved
+*/
+
+#define DMA_CONTROL_REG             0x10            /* rw */
+#define DMA_CONTROL_RST                 (1 << 0)
+#define DMA_TAIL_ENABLE                 (1 << 2)
+
+/* XPS_LL_TEMAC direct registers definition */
+
+#define XTE_RAF0_OFFSET              0x00
+#define RAF0_RST                        (1 << 0)
+#define RAF0_MCSTREJ                    (1 << 1)
+#define RAF0_BCSTREJ                    (1 << 2)
+#define XTE_TPF0_OFFSET              0x04
+#define XTE_IFGP0_OFFSET             0x08
+#define XTE_ISR0_OFFSET              0x0c
+#define ISR0_HARDACSCMPLT               (1 << 0)
+#define ISR0_AUTONEG                    (1 << 1)
+#define ISR0_RXCMPLT                    (1 << 2)
+#define ISR0_RXREJ                      (1 << 3)
+#define ISR0_RXFIFOOVR                  (1 << 4)
+#define ISR0_TXCMPLT                    (1 << 5)
+#define ISR0_RXDCMLCK                   (1 << 6)
+
+#define XTE_IPR0_OFFSET              0x10
+#define XTE_IER0_OFFSET              0x14
+
+#define XTE_MSW0_OFFSET              0x20
+#define XTE_LSW0_OFFSET              0x24
+#define XTE_CTL0_OFFSET              0x28
+#define XTE_RDY0_OFFSET              0x2c
+
+#define XTE_RSE_MIIM_RR_MASK      0x0002
+#define XTE_RSE_MIIM_WR_MASK      0x0004
+#define XTE_RSE_CFG_RR_MASK       0x0020
+#define XTE_RSE_CFG_WR_MASK       0x0040
+#define XTE_RDY0_HARD_ACS_RDY_MASK  (0x10000)
+
+/* XPS_LL_TEMAC indirect registers offset definition */
+
+#define        XTE_RXC0_OFFSET                 0x00000200 /* Rx configuration word 0 */
+#define        XTE_RXC1_OFFSET                 0x00000240 /* Rx configuration word 1 */
+#define XTE_RXC1_RXRST_MASK            (1 << 31)  /* Receiver reset */
+#define XTE_RXC1_RXJMBO_MASK           (1 << 30)  /* Jumbo frame enable */
+#define XTE_RXC1_RXFCS_MASK            (1 << 29)  /* FCS not stripped */
+#define XTE_RXC1_RXEN_MASK             (1 << 28)  /* Receiver enable */
+#define XTE_RXC1_RXVLAN_MASK           (1 << 27)  /* VLAN enable */
+#define XTE_RXC1_RXHD_MASK             (1 << 26)  /* Half duplex */
+#define XTE_RXC1_RXLT_MASK             (1 << 25)  /* Length/type check disable */
+
+#define XTE_TXC_OFFSET                 0x00000280 /*  Tx configuration */
+#define XTE_TXC_TXRST_MASK             (1 << 31)  /* Transmitter reset */
+#define XTE_TXC_TXJMBO_MASK            (1 << 30)  /* Jumbo frame enable */
+#define XTE_TXC_TXFCS_MASK             (1 << 29)  /* Generate FCS */
+#define XTE_TXC_TXEN_MASK              (1 << 28)  /* Transmitter enable */
+#define XTE_TXC_TXVLAN_MASK            (1 << 27)  /* VLAN enable */
+#define XTE_TXC_TXHD_MASK              (1 << 26)  /* Half duplex */
+
+#define XTE_FCC_OFFSET                 0x000002C0 /* Flow control config */
+#define XTE_FCC_RXFLO_MASK             (1 << 29)  /* Rx flow control enable */
+#define XTE_FCC_TXFLO_MASK             (1 << 30)  /* Tx flow control enable */
+
+#define XTE_EMCFG_OFFSET               0x00000300 /* EMAC configuration */
+#define XTE_EMCFG_LINKSPD_MASK         0xC0000000 /* Link speed */
+#define XTE_EMCFG_HOSTEN_MASK          (1 << 26)  /* Host interface enable */
+#define XTE_EMCFG_LINKSPD_10           0x00000000 /* 10 Mbit LINKSPD_MASK */
+#define XTE_EMCFG_LINKSPD_100          (1 << 30)  /* 100 Mbit LINKSPD_MASK */
+#define XTE_EMCFG_LINKSPD_1000         (1 << 31)  /* 1000 Mbit LINKSPD_MASK */
+
+#define XTE_GMIC_OFFSET                        0x00000320 /* RGMII/SGMII config */
+#define XTE_MC_OFFSET                  0x00000340 /* MDIO configuration */
+#define XTE_UAW0_OFFSET                        0x00000380 /* Unicast address word 0 */
+#define XTE_UAW1_OFFSET                        0x00000384 /* Unicast address word 1 */
+
+#define XTE_MAW0_OFFSET                        0x00000388 /* Multicast addr word 0 */
+#define XTE_MAW1_OFFSET                        0x0000038C /* Multicast addr word 1 */
+#define XTE_AFM_OFFSET                 0x00000390 /* Promiscuous mode */
+#define XTE_AFM_EPPRM_MASK             (1 << 31)  /* Promiscuous mode enable */
+
+/* Interrupt Request status */
+#define XTE_TIS_OFFSET                 0x000003A0
+#define TIS_FRIS                       (1 << 0)
+#define TIS_MRIS                       (1 << 1)
+#define TIS_MWIS                       (1 << 2)
+#define TIS_ARIS                       (1 << 3)
+#define TIS_AWIS                       (1 << 4)
+#define TIS_CRIS                       (1 << 5)
+#define TIS_CWIS                       (1 << 6)
+
+#define XTE_TIE_OFFSET                 0x000003A4 /* Interrupt enable */
+
+/**  MII Mamagement Control register (MGTCR) */
+#define XTE_MGTDR_OFFSET               0x000003B0 /* MII data */
+#define XTE_MIIMAI_OFFSET              0x000003B4 /* MII control */
+
+#define CNTLREG_WRITE_ENABLE_MASK   0x8000
+#define CNTLREG_EMAC1SEL_MASK       0x0400
+#define CNTLREG_ADDRESSCODE_MASK    0x03ff
+
+/* CDMAC descriptor status bit definitions */
+
+#define STS_CTRL_APP0_ERR         (1 << 31)
+#define STS_CTRL_APP0_IRQONEND    (1 << 30)
+/* undoccumented */
+#define STS_CTRL_APP0_STOPONEND   (1 << 29)
+#define STS_CTRL_APP0_CMPLT       (1 << 28)
+#define STS_CTRL_APP0_SOP         (1 << 27)
+#define STS_CTRL_APP0_EOP         (1 << 26)
+#define STS_CTRL_APP0_ENGBUSY     (1 << 25)
+/* undocumented */
+#define STS_CTRL_APP0_ENGRST      (1 << 24)
+
+#define TX_CONTROL_CALC_CSUM_MASK   1
+
+#define XTE_ALIGN       32
+#define BUFFER_ALIGN(adr) ((XTE_ALIGN - ((u32) adr)) % XTE_ALIGN)
+
+#define MULTICAST_CAM_TABLE_NUM 4
+
+/* TX/RX CURDESC_PTR points to first descriptor */
+/* TX/RX TAILDESC_PTR points to last descriptor in linked list */
+
+/**
+ * struct cdmac_bd - LocalLink buffer descriptor format
+ *
+ * app0 bits:
+ *     0    Error
+ *     1    IrqOnEnd    generate an interrupt at completion of DMA  op
+ *     2    reserved
+ *     3    completed   Current descriptor completed
+ *     4    SOP         TX - marks first desc/ RX marks first desct
+ *     5    EOP         TX marks last desc/RX marks last desc
+ *     6    EngBusy     DMA is processing
+ *     7    reserved
+ *     8:31 application specific
+ */
+struct cdmac_bd {
+       u32 next;       /* Physical address of next buffer descriptor */
+       u32 phys;
+       u32 len;
+       u32 app0;
+       u32 app1;       /* TX start << 16 | insert */
+       u32 app2;       /* TX csum */
+       u32 app3;
+       u32 app4;       /* skb for TX length for RX */
+};
+
+struct temac_local {
+       struct net_device *ndev;
+       struct device *dev;
+
+       /* Connection to PHY device */
+       struct phy_device *phy_dev;     /* Pointer to PHY device */
+       struct device_node *phy_node;
+
+       /* MDIO bus data */
+       struct mii_bus *mii_bus;        /* MII bus reference */
+       int mdio_irqs[PHY_MAX_ADDR];    /* IRQs table for MDIO bus */
+
+       /* IO registers and IRQs */
+       void __iomem *regs;
+       dcr_host_t sdma_dcrs;
+       int tx_irq;
+       int rx_irq;
+       int emac_num;
+
+       struct sk_buff **rx_skb;
+       spinlock_t rx_lock;
+       struct mutex indirect_mutex;
+       u32 options;                    /* Current options word */
+       int last_link;
+
+       /* Buffer descriptors */
+       struct cdmac_bd *tx_bd_v;
+       dma_addr_t tx_bd_p;
+       struct cdmac_bd *rx_bd_v;
+       dma_addr_t rx_bd_p;
+       int tx_bd_ci;
+       int tx_bd_next;
+       int tx_bd_tail;
+       int rx_bd_ci;
+};
+
+/* xilinx_temac.c */
+u32 temac_ior(struct temac_local *lp, int offset);
+void temac_iow(struct temac_local *lp, int offset, u32 value);
+int temac_indirect_busywait(struct temac_local *lp);
+u32 temac_indirect_in32(struct temac_local *lp, int reg);
+void temac_indirect_out32(struct temac_local *lp, int reg, u32 value);
+
+
+/* xilinx_temac_mdio.c */
+int temac_mdio_setup(struct temac_local *lp, struct device_node *np);
+void temac_mdio_teardown(struct temac_local *lp);
+
+#endif /* XILINX_LL_TEMAC_H */
diff --git a/drivers/net/ll_temac_main.c b/drivers/net/ll_temac_main.c
new file mode 100644 (file)
index 0000000..96e7248
--- /dev/null
@@ -0,0 +1,969 @@
+/*
+ * Driver for Xilinx TEMAC Ethernet device
+ *
+ * Copyright (c) 2008 Nissin Systems Co., Ltd.,  Yoshio Kashiwagi
+ * Copyright (c) 2005-2008 DLA Systems,  David H. Lynch Jr. <dhlii@dlasys.net>
+ * Copyright (c) 2008-2009 Secret Lab Technologies Ltd.
+ *
+ * This is a driver for the Xilinx ll_temac ipcore which is often used
+ * in the Virtex and Spartan series of chips.
+ *
+ * Notes:
+ * - The ll_temac hardware uses indirect access for many of the TEMAC
+ *   registers, include the MDIO bus.  However, indirect access to MDIO
+ *   registers take considerably more clock cycles than to TEMAC registers.
+ *   MDIO accesses are long, so threads doing them should probably sleep
+ *   rather than busywait.  However, since only one indirect access can be
+ *   in progress at any given time, that means that *all* indirect accesses
+ *   could end up sleeping (to wait for an MDIO access to complete).
+ *   Fortunately none of the indirect accesses are on the 'hot' path for tx
+ *   or rx, so this should be okay.
+ *
+ * TODO:
+ * - Fix driver to work on more than just Virtex5.  Right now the driver
+ *   assumes that the locallink DMA registers are accessed via DCR
+ *   instructions.
+ * - Factor out locallink DMA code into separate driver
+ * - Fix multicast assignment.
+ * - Fix support for hardware checksumming.
+ * - Testing.  Lots and lots of testing.
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/etherdevice.h>
+#include <linux/init.h>
+#include <linux/mii.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/netdevice.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_mdio.h>
+#include <linux/of_platform.h>
+#include <linux/skbuff.h>
+#include <linux/spinlock.h>
+#include <linux/tcp.h>      /* needed for sizeof(tcphdr) */
+#include <linux/udp.h>      /* needed for sizeof(udphdr) */
+#include <linux/phy.h>
+#include <linux/in.h>
+#include <linux/io.h>
+#include <linux/ip.h>
+
+#include "ll_temac.h"
+
+#define TX_BD_NUM   64
+#define RX_BD_NUM   128
+
+/* ---------------------------------------------------------------------
+ * Low level register access functions
+ */
+
+u32 temac_ior(struct temac_local *lp, int offset)
+{
+       return in_be32((u32 *)(lp->regs + offset));
+}
+
+void temac_iow(struct temac_local *lp, int offset, u32 value)
+{
+       out_be32((u32 *) (lp->regs + offset), value);
+}
+
+int temac_indirect_busywait(struct temac_local *lp)
+{
+       long end = jiffies + 2;
+
+       while (!(temac_ior(lp, XTE_RDY0_OFFSET) & XTE_RDY0_HARD_ACS_RDY_MASK)) {
+               if (end - jiffies <= 0) {
+                       WARN_ON(1);
+                       return -ETIMEDOUT;
+               }
+               msleep(1);
+       }
+       return 0;
+}
+
+/**
+ * temac_indirect_in32
+ *
+ * lp->indirect_mutex must be held when calling this function
+ */
+u32 temac_indirect_in32(struct temac_local *lp, int reg)
+{
+       u32 val;
+
+       if (temac_indirect_busywait(lp))
+               return -ETIMEDOUT;
+       temac_iow(lp, XTE_CTL0_OFFSET, reg);
+       if (temac_indirect_busywait(lp))
+               return -ETIMEDOUT;
+       val = temac_ior(lp, XTE_LSW0_OFFSET);
+
+       return val;
+}
+
+/**
+ * temac_indirect_out32
+ *
+ * lp->indirect_mutex must be held when calling this function
+ */
+void temac_indirect_out32(struct temac_local *lp, int reg, u32 value)
+{
+       if (temac_indirect_busywait(lp))
+               return;
+       temac_iow(lp, XTE_LSW0_OFFSET, value);
+       temac_iow(lp, XTE_CTL0_OFFSET, CNTLREG_WRITE_ENABLE_MASK | reg);
+}
+
+static u32 temac_dma_in32(struct temac_local *lp, int reg)
+{
+       return dcr_read(lp->sdma_dcrs, reg);
+}
+
+static void temac_dma_out32(struct temac_local *lp, int reg, u32 value)
+{
+       dcr_write(lp->sdma_dcrs, reg, value);
+}
+
+/**
+ * temac_dma_bd_init - Setup buffer descriptor rings
+ */
+static int temac_dma_bd_init(struct net_device *ndev)
+{
+       struct temac_local *lp = netdev_priv(ndev);
+       struct sk_buff *skb;
+       int i;
+
+       lp->rx_skb = kzalloc(sizeof(struct sk_buff)*RX_BD_NUM, GFP_KERNEL);
+       /* allocate the tx and rx ring buffer descriptors. */
+       /* returns a virtual addres and a physical address. */
+       lp->tx_bd_v = dma_alloc_coherent(ndev->dev.parent,
+                                        sizeof(*lp->tx_bd_v) * TX_BD_NUM,
+                                        &lp->tx_bd_p, GFP_KERNEL);
+       lp->rx_bd_v = dma_alloc_coherent(ndev->dev.parent,
+                                        sizeof(*lp->rx_bd_v) * RX_BD_NUM,
+                                        &lp->rx_bd_p, GFP_KERNEL);
+
+       memset(lp->tx_bd_v, 0, sizeof(*lp->tx_bd_v) * TX_BD_NUM);
+       for (i = 0; i < TX_BD_NUM; i++) {
+               lp->tx_bd_v[i].next = lp->tx_bd_p +
+                               sizeof(*lp->tx_bd_v) * ((i + 1) % TX_BD_NUM);
+       }
+
+       memset(lp->rx_bd_v, 0, sizeof(*lp->rx_bd_v) * RX_BD_NUM);
+       for (i = 0; i < RX_BD_NUM; i++) {
+               lp->rx_bd_v[i].next = lp->rx_bd_p +
+                               sizeof(*lp->rx_bd_v) * ((i + 1) % RX_BD_NUM);
+
+               skb = alloc_skb(XTE_MAX_JUMBO_FRAME_SIZE
+                               + XTE_ALIGN, GFP_ATOMIC);
+               if (skb == 0) {
+                       dev_err(&ndev->dev, "alloc_skb error %d\n", i);
+                       return -1;
+               }
+               lp->rx_skb[i] = skb;
+               skb_reserve(skb,  BUFFER_ALIGN(skb->data));
+               /* returns physical address of skb->data */
+               lp->rx_bd_v[i].phys = dma_map_single(ndev->dev.parent,
+                                                    skb->data,
+                                                    XTE_MAX_JUMBO_FRAME_SIZE,
+                                                    DMA_FROM_DEVICE);
+               lp->rx_bd_v[i].len = XTE_MAX_JUMBO_FRAME_SIZE;
+               lp->rx_bd_v[i].app0 = STS_CTRL_APP0_IRQONEND;
+       }
+
+       temac_dma_out32(lp, TX_CHNL_CTRL, 0x10220400 |
+                                         CHNL_CTRL_IRQ_EN |
+                                         CHNL_CTRL_IRQ_DLY_EN |
+                                         CHNL_CTRL_IRQ_COAL_EN);
+       /* 0x10220483 */
+       /* 0x00100483 */
+       temac_dma_out32(lp, RX_CHNL_CTRL, 0xff010000 |
+                                         CHNL_CTRL_IRQ_EN |
+                                         CHNL_CTRL_IRQ_DLY_EN |
+                                         CHNL_CTRL_IRQ_COAL_EN |
+                                         CHNL_CTRL_IRQ_IOE);
+       /* 0xff010283 */
+
+       temac_dma_out32(lp, RX_CURDESC_PTR,  lp->rx_bd_p);
+       temac_dma_out32(lp, RX_TAILDESC_PTR,
+                      lp->rx_bd_p + (sizeof(*lp->rx_bd_v) * (RX_BD_NUM - 1)));
+       temac_dma_out32(lp, TX_CURDESC_PTR, lp->tx_bd_p);
+
+       return 0;
+}
+
+/* ---------------------------------------------------------------------
+ * net_device_ops
+ */
+
+static int temac_set_mac_address(struct net_device *ndev, void *address)
+{
+       struct temac_local *lp = netdev_priv(ndev);
+
+       if (address)
+               memcpy(ndev->dev_addr, address, ETH_ALEN);
+
+       if (!is_valid_ether_addr(ndev->dev_addr))
+               random_ether_addr(ndev->dev_addr);
+
+       /* set up unicast MAC address filter set its mac address */
+       mutex_lock(&lp->indirect_mutex);
+       temac_indirect_out32(lp, XTE_UAW0_OFFSET,
+                            (ndev->dev_addr[0]) |
+                            (ndev->dev_addr[1] << 8) |
+                            (ndev->dev_addr[2] << 16) |
+                            (ndev->dev_addr[3] << 24));
+       /* There are reserved bits in EUAW1
+        * so don't affect them Set MAC bits [47:32] in EUAW1 */
+       temac_indirect_out32(lp, XTE_UAW1_OFFSET,
+                            (ndev->dev_addr[4] & 0x000000ff) |
+                            (ndev->dev_addr[5] << 8));
+       mutex_unlock(&lp->indirect_mutex);
+
+       return 0;
+}
+
+static void temac_set_multicast_list(struct net_device *ndev)
+{
+       struct temac_local *lp = netdev_priv(ndev);
+       u32 multi_addr_msw, multi_addr_lsw, val;
+       int i;
+
+       mutex_lock(&lp->indirect_mutex);
+       if (ndev->flags & (IFF_ALLMULTI | IFF_PROMISC)
+                       || ndev->mc_count > MULTICAST_CAM_TABLE_NUM) {
+               /*
+                *      We must make the kernel realise we had to move
+                *      into promisc mode or we start all out war on
+                *      the cable. If it was a promisc request the
+                *      flag is already set. If not we assert it.
+                */
+               ndev->flags |= IFF_PROMISC;
+               temac_indirect_out32(lp, XTE_AFM_OFFSET, XTE_AFM_EPPRM_MASK);
+               dev_info(&ndev->dev, "Promiscuous mode enabled.\n");
+       } else if (ndev->mc_count) {
+               struct dev_mc_list *mclist = ndev->mc_list;
+               for (i = 0; mclist && i < ndev->mc_count; i++) {
+
+                       if (i >= MULTICAST_CAM_TABLE_NUM)
+                               break;
+                       multi_addr_msw = ((mclist->dmi_addr[3] << 24) |
+                                         (mclist->dmi_addr[2] << 16) |
+                                         (mclist->dmi_addr[1] << 8) |
+                                         (mclist->dmi_addr[0]));
+                       temac_indirect_out32(lp, XTE_MAW0_OFFSET,
+                                            multi_addr_msw);
+                       multi_addr_lsw = ((mclist->dmi_addr[5] << 8) |
+                                         (mclist->dmi_addr[4]) | (i << 16));
+                       temac_indirect_out32(lp, XTE_MAW1_OFFSET,
+                                            multi_addr_lsw);
+                       mclist = mclist->next;
+               }
+       } else {
+               val = temac_indirect_in32(lp, XTE_AFM_OFFSET);
+               temac_indirect_out32(lp, XTE_AFM_OFFSET,
+                                    val & ~XTE_AFM_EPPRM_MASK);
+               temac_indirect_out32(lp, XTE_MAW0_OFFSET, 0);
+               temac_indirect_out32(lp, XTE_MAW1_OFFSET, 0);
+               dev_info(&ndev->dev, "Promiscuous mode disabled.\n");
+       }
+       mutex_unlock(&lp->indirect_mutex);
+}
+
+struct temac_option {
+       int flg;
+       u32 opt;
+       u32 reg;
+       u32 m_or;
+       u32 m_and;
+} temac_options[] = {
+       /* Turn on jumbo packet support for both Rx and Tx */
+       {
+               .opt = XTE_OPTION_JUMBO,
+               .reg = XTE_TXC_OFFSET,
+               .m_or = XTE_TXC_TXJMBO_MASK,
+       },
+       {
+               .opt = XTE_OPTION_JUMBO,
+               .reg = XTE_RXC1_OFFSET,
+               .m_or =XTE_RXC1_RXJMBO_MASK,
+       },
+       /* Turn on VLAN packet support for both Rx and Tx */
+       {
+               .opt = XTE_OPTION_VLAN,
+               .reg = XTE_TXC_OFFSET,
+               .m_or =XTE_TXC_TXVLAN_MASK,
+       },
+       {
+               .opt = XTE_OPTION_VLAN,
+               .reg = XTE_RXC1_OFFSET,
+               .m_or =XTE_RXC1_RXVLAN_MASK,
+       },
+       /* Turn on FCS stripping on receive packets */
+       {
+               .opt = XTE_OPTION_FCS_STRIP,
+               .reg = XTE_RXC1_OFFSET,
+               .m_or =XTE_RXC1_RXFCS_MASK,
+       },
+       /* Turn on FCS insertion on transmit packets */
+       {
+               .opt = XTE_OPTION_FCS_INSERT,
+               .reg = XTE_TXC_OFFSET,
+               .m_or =XTE_TXC_TXFCS_MASK,
+       },
+       /* Turn on length/type field checking on receive packets */
+       {
+               .opt = XTE_OPTION_LENTYPE_ERR,
+               .reg = XTE_RXC1_OFFSET,
+               .m_or =XTE_RXC1_RXLT_MASK,
+       },
+       /* Turn on flow control */
+       {
+               .opt = XTE_OPTION_FLOW_CONTROL,
+               .reg = XTE_FCC_OFFSET,
+               .m_or =XTE_FCC_RXFLO_MASK,
+       },
+       /* Turn on flow control */
+       {
+               .opt = XTE_OPTION_FLOW_CONTROL,
+               .reg = XTE_FCC_OFFSET,
+               .m_or =XTE_FCC_TXFLO_MASK,
+       },
+       /* Turn on promiscuous frame filtering (all frames are received ) */
+       {
+               .opt = XTE_OPTION_PROMISC,
+               .reg = XTE_AFM_OFFSET,
+               .m_or =XTE_AFM_EPPRM_MASK,
+       },
+       /* Enable transmitter if not already enabled */
+       {
+               .opt = XTE_OPTION_TXEN,
+               .reg = XTE_TXC_OFFSET,
+               .m_or =XTE_TXC_TXEN_MASK,
+       },
+       /* Enable receiver? */
+       {
+               .opt = XTE_OPTION_RXEN,
+               .reg = XTE_RXC1_OFFSET,
+               .m_or =XTE_RXC1_RXEN_MASK,
+       },
+       {}
+};
+
+/**
+ * temac_setoptions
+ */
+static u32 temac_setoptions(struct net_device *ndev, u32 options)
+{
+       struct temac_local *lp = netdev_priv(ndev);
+       struct temac_option *tp = &temac_options[0];
+       int reg;
+
+       mutex_lock(&lp->indirect_mutex);
+       while (tp->opt) {
+               reg = temac_indirect_in32(lp, tp->reg) & ~tp->m_or;
+               if (options & tp->opt)
+                       reg |= tp->m_or;
+               temac_indirect_out32(lp, tp->reg, reg);
+               tp++;
+       }
+       lp->options |= options;
+       mutex_unlock(&lp->indirect_mutex);
+
+       return (0);
+}
+
+/* Initilize temac */
+static void temac_device_reset(struct net_device *ndev)
+{
+       struct temac_local *lp = netdev_priv(ndev);
+       u32 timeout;
+       u32 val;
+
+       /* Perform a software reset */
+
+       /* 0x300 host enable bit ? */
+       /* reset PHY through control register ?:1 */
+
+       dev_dbg(&ndev->dev, "%s()\n", __func__);
+
+       mutex_lock(&lp->indirect_mutex);
+       /* Reset the receiver and wait for it to finish reset */
+       temac_indirect_out32(lp, XTE_RXC1_OFFSET, XTE_RXC1_RXRST_MASK);
+       timeout = 1000;
+       while (temac_indirect_in32(lp, XTE_RXC1_OFFSET) & XTE_RXC1_RXRST_MASK) {
+               udelay(1);
+               if (--timeout == 0) {
+                       dev_err(&ndev->dev,
+                               "temac_device_reset RX reset timeout!!\n");
+                       break;
+               }
+       }
+
+       /* Reset the transmitter and wait for it to finish reset */
+       temac_indirect_out32(lp, XTE_TXC_OFFSET, XTE_TXC_TXRST_MASK);
+       timeout = 1000;
+       while (temac_indirect_in32(lp, XTE_TXC_OFFSET) & XTE_TXC_TXRST_MASK) {
+               udelay(1);
+               if (--timeout == 0) {
+                       dev_err(&ndev->dev,
+                               "temac_device_reset TX reset timeout!!\n");
+                       break;
+               }
+       }
+
+       /* Disable the receiver */
+       val = temac_indirect_in32(lp, XTE_RXC1_OFFSET);
+       temac_indirect_out32(lp, XTE_RXC1_OFFSET, val & ~XTE_RXC1_RXEN_MASK);
+
+       /* Reset Local Link (DMA) */
+       temac_dma_out32(lp, DMA_CONTROL_REG, DMA_CONTROL_RST);
+       timeout = 1000;
+       while (temac_dma_in32(lp, DMA_CONTROL_REG) & DMA_CONTROL_RST) {
+               udelay(1);
+               if (--timeout == 0) {
+                       dev_err(&ndev->dev,
+                               "temac_device_reset DMA reset timeout!!\n");
+                       break;
+               }
+       }
+       temac_dma_out32(lp, DMA_CONTROL_REG, DMA_TAIL_ENABLE);
+
+       temac_dma_bd_init(ndev);
+
+       temac_indirect_out32(lp, XTE_RXC0_OFFSET, 0);
+       temac_indirect_out32(lp, XTE_RXC1_OFFSET, 0);
+       temac_indirect_out32(lp, XTE_TXC_OFFSET, 0);
+       temac_indirect_out32(lp, XTE_FCC_OFFSET, XTE_FCC_RXFLO_MASK);
+
+       mutex_unlock(&lp->indirect_mutex);
+
+       /* Sync default options with HW
+        * but leave receiver and transmitter disabled.  */
+       temac_setoptions(ndev,
+                        lp->options & ~(XTE_OPTION_TXEN | XTE_OPTION_RXEN));
+
+       temac_set_mac_address(ndev, NULL);
+
+       /* Set address filter table */
+       temac_set_multicast_list(ndev);
+       if (temac_setoptions(ndev, lp->options))
+               dev_err(&ndev->dev, "Error setting TEMAC options\n");
+
+       /* Init Driver variable */
+       ndev->trans_start = 0;
+}
+
+void temac_adjust_link(struct net_device *ndev)
+{
+       struct temac_local *lp = netdev_priv(ndev);
+       struct phy_device *phy = lp->phy_dev;
+       u32 mii_speed;
+       int link_state;
+
+       /* hash together the state values to decide if something has changed */
+       link_state = phy->speed | (phy->duplex << 1) | phy->link;
+
+       mutex_lock(&lp->indirect_mutex);
+       if (lp->last_link != link_state) {
+               mii_speed = temac_indirect_in32(lp, XTE_EMCFG_OFFSET);
+               mii_speed &= ~XTE_EMCFG_LINKSPD_MASK;
+
+               switch (phy->speed) {
+               case SPEED_1000: mii_speed |= XTE_EMCFG_LINKSPD_1000; break;
+               case SPEED_100: mii_speed |= XTE_EMCFG_LINKSPD_100; break;
+               case SPEED_10: mii_speed |= XTE_EMCFG_LINKSPD_10; break;
+               }
+
+               /* Write new speed setting out to TEMAC */
+               temac_indirect_out32(lp, XTE_EMCFG_OFFSET, mii_speed);
+               lp->last_link = link_state;
+               phy_print_status(phy);
+       }
+       mutex_unlock(&lp->indirect_mutex);
+}
+
+static void temac_start_xmit_done(struct net_device *ndev)
+{
+       struct temac_local *lp = netdev_priv(ndev);
+       struct cdmac_bd *cur_p;
+       unsigned int stat = 0;
+
+       cur_p = &lp->tx_bd_v[lp->tx_bd_ci];
+       stat = cur_p->app0;
+
+       while (stat & STS_CTRL_APP0_CMPLT) {
+               dma_unmap_single(ndev->dev.parent, cur_p->phys, cur_p->len,
+                                DMA_TO_DEVICE);
+               if (cur_p->app4)
+                       dev_kfree_skb_irq((struct sk_buff *)cur_p->app4);
+               cur_p->app0 = 0;
+
+               ndev->stats.tx_packets++;
+               ndev->stats.tx_bytes += cur_p->len;
+
+               lp->tx_bd_ci++;
+               if (lp->tx_bd_ci >= TX_BD_NUM)
+                       lp->tx_bd_ci = 0;
+
+               cur_p = &lp->tx_bd_v[lp->tx_bd_ci];
+               stat = cur_p->app0;
+       }
+
+       netif_wake_queue(ndev);
+}
+
+static int temac_start_xmit(struct sk_buff *skb, struct net_device *ndev)
+{
+       struct temac_local *lp = netdev_priv(ndev);
+       struct cdmac_bd *cur_p;
+       dma_addr_t start_p, tail_p;
+       int ii;
+       unsigned long num_frag;
+       skb_frag_t *frag;
+
+       num_frag = skb_shinfo(skb)->nr_frags;
+       frag = &skb_shinfo(skb)->frags[0];
+       start_p = lp->tx_bd_p + sizeof(*lp->tx_bd_v) * lp->tx_bd_tail;
+       cur_p = &lp->tx_bd_v[lp->tx_bd_tail];
+
+       if (cur_p->app0 & STS_CTRL_APP0_CMPLT) {
+               if (!netif_queue_stopped(ndev)) {
+                       netif_stop_queue(ndev);
+                       return NETDEV_TX_BUSY;
+               }
+               return NETDEV_TX_BUSY;
+       }
+
+       cur_p->app0 = 0;
+       if (skb->ip_summed == CHECKSUM_PARTIAL) {
+               const struct iphdr *ip = ip_hdr(skb);
+               int length = 0, start = 0, insert = 0;
+
+               switch (ip->protocol) {
+               case IPPROTO_TCP:
+                       start = sizeof(struct iphdr) + ETH_HLEN;
+                       insert = sizeof(struct iphdr) + ETH_HLEN + 16;
+                       length = ip->tot_len - sizeof(struct iphdr);
+                       break;
+               case IPPROTO_UDP:
+                       start = sizeof(struct iphdr) + ETH_HLEN;
+                       insert = sizeof(struct iphdr) + ETH_HLEN + 6;
+                       length = ip->tot_len - sizeof(struct iphdr);
+                       break;
+               default:
+                       break;
+               }
+               cur_p->app1 = ((start << 16) | insert);
+               cur_p->app2 = csum_tcpudp_magic(ip->saddr, ip->daddr,
+                                               length, ip->protocol, 0);
+               skb->data[insert] = 0;
+               skb->data[insert + 1] = 0;
+       }
+       cur_p->app0 |= STS_CTRL_APP0_SOP;
+       cur_p->len = skb_headlen(skb);
+       cur_p->phys = dma_map_single(ndev->dev.parent, skb->data, skb->len,
+                                    DMA_TO_DEVICE);
+       cur_p->app4 = (unsigned long)skb;
+
+       for (ii = 0; ii < num_frag; ii++) {
+               lp->tx_bd_tail++;
+               if (lp->tx_bd_tail >= TX_BD_NUM)
+                       lp->tx_bd_tail = 0;
+
+               cur_p = &lp->tx_bd_v[lp->tx_bd_tail];
+               cur_p->phys = dma_map_single(ndev->dev.parent,
+                                            (void *)page_address(frag->page) +
+                                                 frag->page_offset,
+                                            frag->size, DMA_TO_DEVICE);
+               cur_p->len = frag->size;
+               cur_p->app0 = 0;
+               frag++;
+       }
+       cur_p->app0 |= STS_CTRL_APP0_EOP;
+
+       tail_p = lp->tx_bd_p + sizeof(*lp->tx_bd_v) * lp->tx_bd_tail;
+       lp->tx_bd_tail++;
+       if (lp->tx_bd_tail >= TX_BD_NUM)
+               lp->tx_bd_tail = 0;
+
+       /* Kick off the transfer */
+       temac_dma_out32(lp, TX_TAILDESC_PTR, tail_p); /* DMA start */
+
+       return 0;
+}
+
+
+static void ll_temac_recv(struct net_device *ndev)
+{
+       struct temac_local *lp = netdev_priv(ndev);
+       struct sk_buff *skb, *new_skb;
+       unsigned int bdstat;
+       struct cdmac_bd *cur_p;
+       dma_addr_t tail_p;
+       int length;
+       unsigned long skb_vaddr;
+       unsigned long flags;
+
+       spin_lock_irqsave(&lp->rx_lock, flags);
+
+       tail_p = lp->rx_bd_p + sizeof(*lp->rx_bd_v) * lp->rx_bd_ci;
+       cur_p = &lp->rx_bd_v[lp->rx_bd_ci];
+
+       bdstat = cur_p->app0;
+       while ((bdstat & STS_CTRL_APP0_CMPLT)) {
+
+               skb = lp->rx_skb[lp->rx_bd_ci];
+               length = cur_p->app4;
+
+               skb_vaddr = virt_to_bus(skb->data);
+               dma_unmap_single(ndev->dev.parent, skb_vaddr, length,
+                                DMA_FROM_DEVICE);
+
+               skb_put(skb, length);
+               skb->dev = ndev;
+               skb->protocol = eth_type_trans(skb, ndev);
+               skb->ip_summed = CHECKSUM_NONE;
+
+               netif_rx(skb);
+
+               ndev->stats.rx_packets++;
+               ndev->stats.rx_bytes += length;
+
+               new_skb = alloc_skb(XTE_MAX_JUMBO_FRAME_SIZE + XTE_ALIGN,
+                               GFP_ATOMIC);
+               if (new_skb == 0) {
+                       dev_err(&ndev->dev, "no memory for new sk_buff\n");
+                       spin_unlock_irqrestore(&lp->rx_lock, flags);
+                       return;
+               }
+
+               skb_reserve(new_skb, BUFFER_ALIGN(new_skb->data));
+
+               cur_p->app0 = STS_CTRL_APP0_IRQONEND;
+               cur_p->phys = dma_map_single(ndev->dev.parent, new_skb->data,
+                                            XTE_MAX_JUMBO_FRAME_SIZE,
+                                            DMA_FROM_DEVICE);
+               cur_p->len = XTE_MAX_JUMBO_FRAME_SIZE;
+               lp->rx_skb[lp->rx_bd_ci] = new_skb;
+
+               lp->rx_bd_ci++;
+               if (lp->rx_bd_ci >= RX_BD_NUM)
+                       lp->rx_bd_ci = 0;
+
+               cur_p = &lp->rx_bd_v[lp->rx_bd_ci];
+               bdstat = cur_p->app0;
+       }
+       temac_dma_out32(lp, RX_TAILDESC_PTR, tail_p);
+
+       spin_unlock_irqrestore(&lp->rx_lock, flags);
+}
+
+static irqreturn_t ll_temac_tx_irq(int irq, void *_ndev)
+{
+       struct net_device *ndev = _ndev;
+       struct temac_local *lp = netdev_priv(ndev);
+       unsigned int status;
+
+       status = temac_dma_in32(lp, TX_IRQ_REG);
+       temac_dma_out32(lp, TX_IRQ_REG, status);
+
+       if (status & (IRQ_COAL | IRQ_DLY))
+               temac_start_xmit_done(lp->ndev);
+       if (status & 0x080)
+               dev_err(&ndev->dev, "DMA error 0x%x\n", status);
+
+       return IRQ_HANDLED;
+}
+
+static irqreturn_t ll_temac_rx_irq(int irq, void *_ndev)
+{
+       struct net_device *ndev = _ndev;
+       struct temac_local *lp = netdev_priv(ndev);
+       unsigned int status;
+
+       /* Read and clear the status registers */
+       status = temac_dma_in32(lp, RX_IRQ_REG);
+       temac_dma_out32(lp, RX_IRQ_REG, status);
+
+       if (status & (IRQ_COAL | IRQ_DLY))
+               ll_temac_recv(lp->ndev);
+
+       return IRQ_HANDLED;
+}
+
+static int temac_open(struct net_device *ndev)
+{
+       struct temac_local *lp = netdev_priv(ndev);
+       int rc;
+
+       dev_dbg(&ndev->dev, "temac_open()\n");
+
+       if (lp->phy_node) {
+               lp->phy_dev = of_phy_connect(lp->ndev, lp->phy_node,
+                                            temac_adjust_link, 0, 0);
+               if (!lp->phy_dev) {
+                       dev_err(lp->dev, "of_phy_connect() failed\n");
+                       return -ENODEV;
+               }
+
+               phy_start(lp->phy_dev);
+       }
+
+       rc = request_irq(lp->tx_irq, ll_temac_tx_irq, 0, ndev->name, ndev);
+       if (rc)
+               goto err_tx_irq;
+       rc = request_irq(lp->rx_irq, ll_temac_rx_irq, 0, ndev->name, ndev);
+       if (rc)
+               goto err_rx_irq;
+
+       temac_device_reset(ndev);
+       return 0;
+
+ err_rx_irq:
+       free_irq(lp->tx_irq, ndev);
+ err_tx_irq:
+       if (lp->phy_dev)
+               phy_disconnect(lp->phy_dev);
+       lp->phy_dev = NULL;
+       dev_err(lp->dev, "request_irq() failed\n");
+       return rc;
+}
+
+static int temac_stop(struct net_device *ndev)
+{
+       struct temac_local *lp = netdev_priv(ndev);
+
+       dev_dbg(&ndev->dev, "temac_close()\n");
+
+       free_irq(lp->tx_irq, ndev);
+       free_irq(lp->rx_irq, ndev);
+
+       if (lp->phy_dev)
+               phy_disconnect(lp->phy_dev);
+       lp->phy_dev = NULL;
+
+       return 0;
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void
+temac_poll_controller(struct net_device *ndev)
+{
+       struct temac_local *lp = netdev_priv(ndev);
+
+       disable_irq(lp->tx_irq);
+       disable_irq(lp->rx_irq);
+
+       ll_temac_rx_irq(lp->tx_irq, lp);
+       ll_temac_tx_irq(lp->rx_irq, lp);
+
+       enable_irq(lp->tx_irq);
+       enable_irq(lp->rx_irq);
+}
+#endif
+
+static const struct net_device_ops temac_netdev_ops = {
+       .ndo_open = temac_open,
+       .ndo_stop = temac_stop,
+       .ndo_start_xmit = temac_start_xmit,
+       .ndo_set_mac_address = temac_set_mac_address,
+       //.ndo_set_multicast_list = temac_set_multicast_list,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+       .ndo_poll_controller = temac_poll_controller,
+#endif
+};
+
+/* ---------------------------------------------------------------------
+ * SYSFS device attributes
+ */
+static ssize_t temac_show_llink_regs(struct device *dev,
+                                    struct device_attribute *attr, char *buf)
+{
+       struct net_device *ndev = dev_get_drvdata(dev);
+       struct temac_local *lp = netdev_priv(ndev);
+       int i, len = 0;
+
+       for (i = 0; i < 0x11; i++)
+               len += sprintf(buf + len, "%.8x%s", temac_dma_in32(lp, i),
+                              (i % 8) == 7 ? "\n" : " ");
+       len += sprintf(buf + len, "\n");
+
+       return len;
+}
+
+static DEVICE_ATTR(llink_regs, 0440, temac_show_llink_regs, NULL);
+
+static struct attribute *temac_device_attrs[] = {
+       &dev_attr_llink_regs.attr,
+       NULL,
+};
+
+static const struct attribute_group temac_attr_group = {
+       .attrs = temac_device_attrs,
+};
+
+static int __init
+temac_of_probe(struct of_device *op, const struct of_device_id *match)
+{
+       struct device_node *np;
+       struct temac_local *lp;
+       struct net_device *ndev;
+       const void *addr;
+       int size, rc = 0;
+       unsigned int dcrs;
+
+       /* Init network device structure */
+       ndev = alloc_etherdev(sizeof(*lp));
+       if (!ndev) {
+               dev_err(&op->dev, "could not allocate device.\n");
+               return -ENOMEM;
+       }
+       ether_setup(ndev);
+       dev_set_drvdata(&op->dev, ndev);
+       SET_NETDEV_DEV(ndev, &op->dev);
+       ndev->flags &= ~IFF_MULTICAST;  /* clear multicast */
+       ndev->features = NETIF_F_SG | NETIF_F_FRAGLIST;
+       ndev->netdev_ops = &temac_netdev_ops;
+#if 0
+       ndev->features |= NETIF_F_IP_CSUM; /* Can checksum TCP/UDP over IPv4. */
+       ndev->features |= NETIF_F_HW_CSUM; /* Can checksum all the packets. */
+       ndev->features |= NETIF_F_IPV6_CSUM; /* Can checksum IPV6 TCP/UDP */
+       ndev->features |= NETIF_F_HIGHDMA; /* Can DMA to high memory. */
+       ndev->features |= NETIF_F_HW_VLAN_TX; /* Transmit VLAN hw accel */
+       ndev->features |= NETIF_F_HW_VLAN_RX; /* Receive VLAN hw acceleration */
+       ndev->features |= NETIF_F_HW_VLAN_FILTER; /* Receive VLAN filtering */
+       ndev->features |= NETIF_F_VLAN_CHALLENGED; /* cannot handle VLAN pkts */
+       ndev->features |= NETIF_F_GSO; /* Enable software GSO. */
+       ndev->features |= NETIF_F_MULTI_QUEUE; /* Has multiple TX/RX queues */
+       ndev->features |= NETIF_F_LRO; /* large receive offload */
+#endif
+
+       /* setup temac private info structure */
+       lp = netdev_priv(ndev);
+       lp->ndev = ndev;
+       lp->dev = &op->dev;
+       lp->options = XTE_OPTION_DEFAULTS;
+       spin_lock_init(&lp->rx_lock);
+       mutex_init(&lp->indirect_mutex);
+
+       /* map device registers */
+       lp->regs = of_iomap(op->node, 0);
+       if (!lp->regs) {
+               dev_err(&op->dev, "could not map temac regs.\n");
+               goto nodev;
+       }
+
+       /* Find the DMA node, map the DMA registers, and decode the DMA IRQs */
+       np = of_parse_phandle(op->node, "llink-connected", 0);
+       if (!np) {
+               dev_err(&op->dev, "could not find DMA node\n");
+               goto nodev;
+       }
+
+       dcrs = dcr_resource_start(np, 0);
+       if (dcrs == 0) {
+               dev_err(&op->dev, "could not get DMA register address\n");
+               goto nodev;;
+       }
+       lp->sdma_dcrs = dcr_map(np, dcrs, dcr_resource_len(np, 0));
+       dev_dbg(&op->dev, "DCR base: %x\n", dcrs);
+
+       lp->rx_irq = irq_of_parse_and_map(np, 0);
+       lp->tx_irq = irq_of_parse_and_map(np, 1);
+       if (!lp->rx_irq || !lp->tx_irq) {
+               dev_err(&op->dev, "could not determine irqs\n");
+               rc = -ENOMEM;
+               goto nodev;
+       }
+
+       of_node_put(np); /* Finished with the DMA node; drop the reference */
+
+       /* Retrieve the MAC address */
+       addr = of_get_property(op->node, "local-mac-address", &size);
+       if ((!addr) || (size != 6)) {
+               dev_err(&op->dev, "could not find MAC address\n");
+               rc = -ENODEV;
+               goto nodev;
+       }
+       temac_set_mac_address(ndev, (void *)addr);
+
+       rc = temac_mdio_setup(lp, op->node);
+       if (rc)
+               dev_warn(&op->dev, "error registering MDIO bus\n");
+
+       lp->phy_node = of_parse_phandle(op->node, "phy-handle", 0);
+       if (lp->phy_node)
+               dev_dbg(lp->dev, "using PHY node %s (%p)\n", np->full_name, np);
+
+       /* Add the device attributes */
+       rc = sysfs_create_group(&lp->dev->kobj, &temac_attr_group);
+       if (rc) {
+               dev_err(lp->dev, "Error creating sysfs files\n");
+               goto nodev;
+       }
+
+       rc = register_netdev(lp->ndev);
+       if (rc) {
+               dev_err(lp->dev, "register_netdev() error (%i)\n", rc);
+               goto err_register_ndev;
+       }
+
+       return 0;
+
+ err_register_ndev:
+       sysfs_remove_group(&lp->dev->kobj, &temac_attr_group);
+ nodev:
+       free_netdev(ndev);
+       ndev = NULL;
+       return rc;
+}
+
+static int __devexit temac_of_remove(struct of_device *op)
+{
+       struct net_device *ndev = dev_get_drvdata(&op->dev);
+       struct temac_local *lp = netdev_priv(ndev);
+
+       temac_mdio_teardown(lp);
+       unregister_netdev(ndev);
+       sysfs_remove_group(&lp->dev->kobj, &temac_attr_group);
+       if (lp->phy_node)
+               of_node_put(lp->phy_node);
+       lp->phy_node = NULL;
+       dev_set_drvdata(&op->dev, NULL);
+       free_netdev(ndev);
+       return 0;
+}
+
+static struct of_device_id temac_of_match[] __devinitdata = {
+       { .compatible = "xlnx,xps-ll-temac-1.01.b", },
+       {},
+};
+MODULE_DEVICE_TABLE(of, temac_of_match);
+
+static struct of_platform_driver temac_of_driver = {
+       .match_table = temac_of_match,
+       .probe = temac_of_probe,
+       .remove = __devexit_p(temac_of_remove),
+       .driver = {
+               .owner = THIS_MODULE,
+               .name = "xilinx_temac",
+       },
+};
+
+static int __init temac_init(void)
+{
+       return of_register_platform_driver(&temac_of_driver);
+}
+module_init(temac_init);
+
+static void __exit temac_exit(void)
+{
+       of_unregister_platform_driver(&temac_of_driver);
+}
+module_exit(temac_exit);
+
+MODULE_DESCRIPTION("Xilinx LL_TEMAC Ethernet driver");
+MODULE_AUTHOR("Yoshio Kashiwagi");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/ll_temac_mdio.c b/drivers/net/ll_temac_mdio.c
new file mode 100644 (file)
index 0000000..da0e462
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ * MDIO bus driver for the Xilinx TEMAC device
+ *
+ * Copyright (c) 2009 Secret Lab Technologies, Ltd.
+ */
+
+#include <linux/io.h>
+#include <linux/netdevice.h>
+#include <linux/mutex.h>
+#include <linux/phy.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_mdio.h>
+
+#include "ll_temac.h"
+
+/* ---------------------------------------------------------------------
+ * MDIO Bus functions
+ */
+static int temac_mdio_read(struct mii_bus *bus, int phy_id, int reg)
+{
+       struct temac_local *lp = bus->priv;
+       u32 rc;
+
+       /* Write the PHY address to the MIIM Access Initiator register.
+        * When the transfer completes, the PHY register value will appear
+        * in the LSW0 register */
+       mutex_lock(&lp->indirect_mutex);
+       temac_iow(lp, XTE_LSW0_OFFSET, (phy_id << 5) | reg);
+       rc = temac_indirect_in32(lp, XTE_MIIMAI_OFFSET);
+       mutex_unlock(&lp->indirect_mutex);
+
+       dev_dbg(lp->dev, "temac_mdio_read(phy_id=%i, reg=%x) == %x\n",
+               phy_id, reg, rc);
+
+       return rc;
+}
+
+static int temac_mdio_write(struct mii_bus *bus, int phy_id, int reg, u16 val)
+{
+       struct temac_local *lp = bus->priv;
+
+       dev_dbg(lp->dev, "temac_mdio_write(phy_id=%i, reg=%x, val=%x)\n",
+               phy_id, reg, val);
+
+       /* First write the desired value into the write data register
+        * and then write the address into the access initiator register
+        */
+       mutex_lock(&lp->indirect_mutex);
+       temac_indirect_out32(lp, XTE_MGTDR_OFFSET, val);
+       temac_indirect_out32(lp, XTE_MIIMAI_OFFSET, (phy_id << 5) | reg);
+       mutex_unlock(&lp->indirect_mutex);
+
+       return 0;
+}
+
+int temac_mdio_setup(struct temac_local *lp, struct device_node *np)
+{
+       struct mii_bus *bus;
+       const u32 *bus_hz;
+       int clk_div;
+       int rc, size;
+       struct resource res;
+
+       /* Calculate a reasonable divisor for the clock rate */
+       clk_div = 0x3f; /* worst-case default setting */
+       bus_hz = of_get_property(np, "clock-frequency", &size);
+       if (bus_hz && size >= sizeof(*bus_hz)) {
+               clk_div = (*bus_hz) / (2500 * 1000 * 2) - 1;
+               if (clk_div < 1)
+                       clk_div = 1;
+               if (clk_div > 0x3f)
+                       clk_div = 0x3f;
+       }
+
+       /* Enable the MDIO bus by asserting the enable bit and writing
+        * in the clock config */
+       mutex_lock(&lp->indirect_mutex);
+       temac_indirect_out32(lp, XTE_MC_OFFSET, 1 << 6 | clk_div);
+       mutex_unlock(&lp->indirect_mutex);
+
+       bus = mdiobus_alloc();
+       if (!bus)
+               return -ENOMEM;
+
+       of_address_to_resource(np, 0, &res);
+       snprintf(bus->id, MII_BUS_ID_SIZE, "%.8llx",
+                (unsigned long long)res.start);
+       bus->priv = lp;
+       bus->name = "Xilinx TEMAC MDIO";
+       bus->read = temac_mdio_read;
+       bus->write = temac_mdio_write;
+       bus->parent = lp->dev;
+       bus->irq = lp->mdio_irqs; /* preallocated IRQ table */
+
+       lp->mii_bus = bus;
+
+       rc = of_mdiobus_register(bus, np);
+       if (rc)
+               goto err_register;
+
+       mutex_lock(&lp->indirect_mutex);
+       dev_dbg(lp->dev, "MDIO bus registered;  MC:%x\n",
+               temac_indirect_in32(lp, XTE_MC_OFFSET));
+       mutex_unlock(&lp->indirect_mutex);
+       return 0;
+
+ err_register:
+       mdiobus_free(bus);
+       return rc;
+}
+
+void temac_mdio_teardown(struct temac_local *lp)
+{
+       mdiobus_unregister(lp->mii_bus);
+       kfree(lp->mii_bus->irq);
+       mdiobus_free(lp->mii_bus);
+       lp->mii_bus = NULL;
+}
+
index b7d438a367f36c15c495f1ff51ebb5b984cad5dc..da472c687481ab23ce0e6a9d0afa9c8733fd4ab8 100644 (file)
@@ -62,6 +62,7 @@
 struct pcpu_lstats {
        unsigned long packets;
        unsigned long bytes;
+       unsigned long drops;
 };
 
 /*
@@ -71,18 +72,22 @@ struct pcpu_lstats {
 static int loopback_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        struct pcpu_lstats *pcpu_lstats, *lb_stats;
+       int len;
 
        skb_orphan(skb);
 
-       skb->protocol = eth_type_trans(skb,dev);
+       skb->protocol = eth_type_trans(skb, dev);
 
        /* it's OK to use per_cpu_ptr() because BHs are off */
        pcpu_lstats = dev->ml_priv;
        lb_stats = per_cpu_ptr(pcpu_lstats, smp_processor_id());
-       lb_stats->bytes += skb->len;
-       lb_stats->packets++;
 
-       netif_rx(skb);
+       len = skb->len;
+       if (likely(netif_rx(skb) == NET_RX_SUCCESS)) {
+               lb_stats->bytes += len;
+               lb_stats->packets++;
+       } else
+               lb_stats->drops++;
 
        return 0;
 }
@@ -93,6 +98,7 @@ static struct net_device_stats *loopback_get_stats(struct net_device *dev)
        struct net_device_stats *stats = &dev->stats;
        unsigned long bytes = 0;
        unsigned long packets = 0;
+       unsigned long drops = 0;
        int i;
 
        pcpu_lstats = dev->ml_priv;
@@ -102,11 +108,14 @@ static struct net_device_stats *loopback_get_stats(struct net_device *dev)
                lb_stats = per_cpu_ptr(pcpu_lstats, i);
                bytes   += lb_stats->bytes;
                packets += lb_stats->packets;
+               drops   += lb_stats->drops;
        }
        stats->rx_packets = packets;
        stats->tx_packets = packets;
-       stats->rx_bytes = bytes;
-       stats->tx_bytes = bytes;
+       stats->rx_dropped = drops;
+       stats->rx_errors  = drops;
+       stats->rx_bytes   = bytes;
+       stats->tx_bytes   = bytes;
        return stats;
 }
 
@@ -161,6 +170,7 @@ static void loopback_setup(struct net_device *dev)
        dev->tx_queue_len       = 0;
        dev->type               = ARPHRD_LOOPBACK;      /* 0x0001*/
        dev->flags              = IFF_LOOPBACK;
+       dev->priv_flags        &= ~IFF_XMIT_DST_RELEASE;
        dev->features           = NETIF_F_SG | NETIF_F_FRAGLIST
                | NETIF_F_TSO
                | NETIF_F_NO_CSUM
index 22e74a0e03619a7aab64f68fd7d5ff4189620fe3..f8fa0c3f0f6408d5761f17f402372f0e9a49a8ee 100644 (file)
@@ -620,19 +620,12 @@ static int __init mac8390_initdev(struct net_device * dev, struct nubus_dev * nd
 
        /* Good, done, now spit out some messages */
        printk(KERN_INFO "%s: %s in slot %X (type %s)\n",
-                  dev->name, ndev->board->name, ndev->board->slot, cardname[type]);
-       printk(KERN_INFO "MAC ");
-       {
-               int i;
-               for (i = 0; i < 6; i++) {
-                       printk("%2.2x", dev->dev_addr[i]);
-                       if (i < 5)
-                               printk(":");
-               }
-       }
-       printk(" IRQ %d, %d KB shared memory at %#lx,  %d-bit access.\n",
-                  dev->irq, (int)((dev->mem_end - dev->mem_start)/0x1000) * 4,
-                  dev->mem_start, access_bitmode?32:16);
+              dev->name, ndev->board->name, ndev->board->slot, cardname[type]);
+       printk(KERN_INFO
+              "MAC %pM IRQ %d, %d KB shared memory at %#lx, %d-bit access.\n",
+              dev->dev_addr, dev->irq,
+              (unsigned int)(dev->mem_end - dev->mem_start) >> 10,
+              dev->mem_start, access_bitmode ? 32 : 16);
        return 0;
 }
 
index 384e072de2e7945ed490d710b530c4354dfa172b..dab45339d3a876eee8fd0a326f6b2dca9350d868 100644 (file)
@@ -73,8 +73,6 @@ static char *version =
    or override something. */
 #include <linux/module.h>
 
-#define PRINTK(x) printk x
-
 /*
   Sources:
 
@@ -402,7 +400,7 @@ net_send_packet(struct sk_buff *skb, struct net_device *dev)
                /* Gasp!  It hasn't.  But that shouldn't happen since
                   we're waiting for TxOk, so return 1 and requeue this packet. */
                local_irq_restore(flags);
-               return 1;
+               return NETDEV_TX_BUSY;
        }
 
        /* Write the contents of the packet */
index e82aee41d77ed3c590bdc0ebe7f20f624c941a85..5b5c25368d1e559e9f2dbbb71013f13efa293ce7 100644 (file)
@@ -599,6 +599,21 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id)
        return IRQ_HANDLED;
 }
 
+#ifdef CONFIG_NET_POLL_CONTROLLER
+/*
+ * Polling receive - used by netconsole and other diagnostic tools
+ * to allow network i/o with interrupts disabled.
+ */
+static void macb_poll_controller(struct net_device *dev)
+{
+       unsigned long flags;
+
+       local_irq_save(flags);
+       macb_interrupt(dev->irq, dev);
+       local_irq_restore(flags);
+}
+#endif
+
 static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        struct macb *bp = netdev_priv(dev);
@@ -630,7 +645,7 @@ static int macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
                        "BUG! Tx Ring full when queue awake!\n");
                dev_dbg(&bp->pdev->dev, "tx_head = %u, tx_tail = %u\n",
                        bp->tx_head, bp->tx_tail);
-               return 1;
+               return NETDEV_TX_BUSY;
        }
 
        entry = bp->tx_head;
@@ -1094,6 +1109,9 @@ static const struct net_device_ops macb_netdev_ops = {
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_change_mtu         = eth_change_mtu,
        .ndo_set_mac_address    = eth_mac_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+       .ndo_poll_controller    = macb_poll_controller,
+#endif
 };
 
 static int __init macb_probe(struct platform_device *pdev)
index feebbd92aff2d3202d8e877cf31a6c6f13117140..1427755c224d982c0c26807da94a04baa20f4478 100644 (file)
@@ -94,6 +94,16 @@ static void __mace_set_address(struct net_device *dev, void *addr);
  */
 static unsigned char *dummy_buf;
 
+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_mac_address    = mace_set_address,
+       .ndo_change_mtu         = eth_change_mtu,
+       .ndo_validate_addr      = eth_validate_addr,
+};
+
 static int __devinit mace_probe(struct macio_dev *mdev, const struct of_device_id *match)
 {
        struct device_node *mace = macio_get_of_node(mdev);
@@ -207,11 +217,7 @@ static int __devinit mace_probe(struct macio_dev *mdev, const struct of_device_i
                }
        }
 
-       dev->open = mace_open;
-       dev->stop = mace_close;
-       dev->hard_start_xmit = mace_xmit_start;
-       dev->set_multicast_list = mace_set_multicast;
-       dev->set_mac_address = mace_set_address;
+       dev->netdev_ops = &mace_netdev_ops;
 
        /*
         * Most of what is below could be moved to mace_open()
@@ -541,7 +547,7 @@ static int mace_xmit_start(struct sk_buff *skb, struct net_device *dev)
        netif_stop_queue(dev);
        mp->tx_fullup = 1;
        spin_unlock_irqrestore(&mp->lock, flags);
-       return 1;               /* can't take it at the moment */
+       return NETDEV_TX_BUSY;          /* can't take it at the moment */
     }
     spin_unlock_irqrestore(&mp->lock, flags);
 
index 274e99bb63ac28857b568e339a46088065ecf6e2..44f3c2896f2086cf92510b42761cb4b9b08a2eee 100644 (file)
@@ -180,6 +180,17 @@ static void mace_dma_off(struct net_device *dev)
        psc_write_word(PSC_ENETWR_CMD + PSC_SET1, 0x1100);
 }
 
+static const struct net_device_ops mace_netdev_ops = {
+       .ndo_open               = mace_open,
+       .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_mac_address    = mace_set_address,
+       .ndo_change_mtu         = eth_change_mtu,
+       .ndo_validate_addr      = eth_validate_addr,
+};
+
 /*
  * Not really much of a probe. The hardware table tells us if this
  * model of Macintrash has a MACE (AV macintoshes)
@@ -240,13 +251,8 @@ static int __devinit mace_probe(struct platform_device *pdev)
                return -ENODEV;
        }
 
-       dev->open               = mace_open;
-       dev->stop               = mace_close;
-       dev->hard_start_xmit    = mace_xmit_start;
-       dev->tx_timeout         = mace_tx_timeout;
+       dev->netdev_ops         = &mace_netdev_ops;
        dev->watchdog_timeo     = TX_TIMEOUT;
-       dev->set_multicast_list = mace_set_multicast;
-       dev->set_mac_address    = mace_set_address;
 
        printk(KERN_INFO "%s: 68K MACE, hardware address %pM\n",
               dev->name, dev->dev_addr);
index 214a8cf2b7089bc63de02506ea0a873313f60569..99eed9f37c8417b0661b411db364571fb581f530 100644 (file)
@@ -232,7 +232,7 @@ static int macvlan_open(struct net_device *dev)
        if (macvlan_addr_busy(vlan->port, dev->dev_addr))
                goto out;
 
-       err = dev_unicast_add(lowerdev, dev->dev_addr, ETH_ALEN);
+       err = dev_unicast_add(lowerdev, dev->dev_addr);
        if (err < 0)
                goto out;
        if (dev->flags & IFF_ALLMULTI) {
@@ -244,7 +244,7 @@ static int macvlan_open(struct net_device *dev)
        return 0;
 
 del_unicast:
-       dev_unicast_delete(lowerdev, dev->dev_addr, ETH_ALEN);
+       dev_unicast_delete(lowerdev, dev->dev_addr);
 out:
        return err;
 }
@@ -258,7 +258,7 @@ static int macvlan_stop(struct net_device *dev)
        if (dev->flags & IFF_ALLMULTI)
                dev_set_allmulti(lowerdev, -1);
 
-       dev_unicast_delete(lowerdev, dev->dev_addr, ETH_ALEN);
+       dev_unicast_delete(lowerdev, dev->dev_addr);
 
        macvlan_hash_del(vlan);
        return 0;
@@ -282,10 +282,11 @@ static int macvlan_set_mac_address(struct net_device *dev, void *p)
                if (macvlan_addr_busy(vlan->port, addr->sa_data))
                        return -EBUSY;
 
-               if ((err = dev_unicast_add(lowerdev, addr->sa_data, ETH_ALEN)))
+               err = dev_unicast_add(lowerdev, addr->sa_data);
+               if (err)
                        return err;
 
-               dev_unicast_delete(lowerdev, dev->dev_addr, ETH_ALEN);
+               dev_unicast_delete(lowerdev, dev->dev_addr);
 
                macvlan_hash_change_addr(vlan, addr->sa_data);
        }
@@ -358,6 +359,7 @@ static int macvlan_init(struct net_device *dev)
                                  (lowerdev->state & MACVLAN_STATE_MASK);
        dev->features           = lowerdev->features & MACVLAN_FEATURES;
        dev->iflink             = lowerdev->ifindex;
+       dev->hard_header_len    = lowerdev->hard_header_len;
 
        macvlan_set_lockdep_class(dev);
 
@@ -374,36 +376,20 @@ static void macvlan_ethtool_get_drvinfo(struct net_device *dev,
 static u32 macvlan_ethtool_get_rx_csum(struct net_device *dev)
 {
        const struct macvlan_dev *vlan = netdev_priv(dev);
-       struct net_device *lowerdev = vlan->lowerdev;
-
-       if (lowerdev->ethtool_ops == NULL ||
-           lowerdev->ethtool_ops->get_rx_csum == NULL)
-               return 0;
-       return lowerdev->ethtool_ops->get_rx_csum(lowerdev);
+       return dev_ethtool_get_rx_csum(vlan->lowerdev);
 }
 
 static int macvlan_ethtool_get_settings(struct net_device *dev,
                                        struct ethtool_cmd *cmd)
 {
        const struct macvlan_dev *vlan = netdev_priv(dev);
-       struct net_device *lowerdev = vlan->lowerdev;
-
-       if (!lowerdev->ethtool_ops ||
-           !lowerdev->ethtool_ops->get_settings)
-               return -EOPNOTSUPP;
-
-       return lowerdev->ethtool_ops->get_settings(lowerdev, cmd);
+       return dev_ethtool_get_settings(vlan->lowerdev, cmd);
 }
 
 static u32 macvlan_ethtool_get_flags(struct net_device *dev)
 {
        const struct macvlan_dev *vlan = netdev_priv(dev);
-       struct net_device *lowerdev = vlan->lowerdev;
-
-       if (!lowerdev->ethtool_ops ||
-           !lowerdev->ethtool_ops->get_flags)
-               return 0;
-       return lowerdev->ethtool_ops->get_flags(lowerdev);
+       return dev_ethtool_get_flags(vlan->lowerdev);
 }
 
 static const struct ethtool_ops macvlan_ethtool_ops = {
@@ -430,6 +416,7 @@ static void macvlan_setup(struct net_device *dev)
 {
        ether_setup(dev);
 
+       dev->priv_flags        &= ~IFF_XMIT_DST_RELEASE;
        dev->netdev_ops         = &macvlan_netdev_ops;
        dev->destructor         = free_netdev;
        dev->header_ops         = &macvlan_hard_header_ops,
diff --git a/drivers/net/mdio.c b/drivers/net/mdio.c
new file mode 100644 (file)
index 0000000..dc45e98
--- /dev/null
@@ -0,0 +1,431 @@
+/*
+ * mdio.c: Generic support for MDIO-compatible transceivers
+ * Copyright 2006-2009 Solarflare Communications 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, incorporated herein by reference.
+ */
+
+#include <linux/kernel.h>
+#include <linux/capability.h>
+#include <linux/errno.h>
+#include <linux/ethtool.h>
+#include <linux/mdio.h>
+#include <linux/module.h>
+
+/**
+ * mdio45_probe - probe for an MDIO (clause 45) device
+ * @mdio: MDIO interface
+ * @prtad: Expected PHY address
+ *
+ * This sets @prtad and @mmds in the MDIO interface if successful.
+ * Returns 0 on success, negative on error.
+ */
+int mdio45_probe(struct mdio_if_info *mdio, int prtad)
+{
+       int mmd, stat2, devs1, devs2;
+
+       /* Assume PHY must have at least one of PMA/PMD, WIS, PCS, PHY
+        * XS or DTE XS; give up if none is present. */
+       for (mmd = 1; mmd <= 5; mmd++) {
+               /* Is this MMD present? */
+               stat2 = mdio->mdio_read(mdio->dev, prtad, mmd, MDIO_STAT2);
+               if (stat2 < 0 ||
+                   (stat2 & MDIO_STAT2_DEVPRST) != MDIO_STAT2_DEVPRST_VAL)
+                       continue;
+
+               /* It should tell us about all the other MMDs */
+               devs1 = mdio->mdio_read(mdio->dev, prtad, mmd, MDIO_DEVS1);
+               devs2 = mdio->mdio_read(mdio->dev, prtad, mmd, MDIO_DEVS2);
+               if (devs1 < 0 || devs2 < 0)
+                       continue;
+
+               mdio->prtad = prtad;
+               mdio->mmds = devs1 | (devs2 << 16);
+               return 0;
+       }
+
+       return -ENODEV;
+}
+EXPORT_SYMBOL(mdio45_probe);
+
+/**
+ * mdio_set_flag - set or clear flag in an MDIO register
+ * @mdio: MDIO interface
+ * @prtad: PHY address
+ * @devad: MMD address
+ * @addr: Register address
+ * @mask: Mask for flag (single bit set)
+ * @sense: New value of flag
+ *
+ * This debounces changes: it does not write the register if the flag
+ * already has the proper value.  Returns 0 on success, negative on error.
+ */
+int mdio_set_flag(const struct mdio_if_info *mdio,
+                 int prtad, int devad, u16 addr, int mask,
+                 bool sense)
+{
+       int old_val = mdio->mdio_read(mdio->dev, prtad, devad, addr);
+       int new_val;
+
+       if (old_val < 0)
+               return old_val;
+       if (sense)
+               new_val = old_val | mask;
+       else
+               new_val = old_val & ~mask;
+       if (old_val == new_val)
+               return 0;
+       return mdio->mdio_write(mdio->dev, prtad, devad, addr, new_val);
+}
+EXPORT_SYMBOL(mdio_set_flag);
+
+/**
+ * mdio_link_ok - is link status up/OK
+ * @mdio: MDIO interface
+ * @mmd_mask: Mask for MMDs to check
+ *
+ * Returns 1 if the PHY reports link status up/OK, 0 otherwise.
+ * @mmd_mask is normally @mdio->mmds, but if loopback is enabled
+ * the MMDs being bypassed should be excluded from the mask.
+ */
+int mdio45_links_ok(const struct mdio_if_info *mdio, u32 mmd_mask)
+{
+       int devad, reg;
+
+       if (!mmd_mask) {
+               /* Use absence of XGMII faults in lieu of link state */
+               reg = mdio->mdio_read(mdio->dev, mdio->prtad,
+                                     MDIO_MMD_PHYXS, MDIO_STAT2);
+               return reg >= 0 && !(reg & MDIO_STAT2_RXFAULT);
+       }
+
+       for (devad = 0; mmd_mask; devad++) {
+               if (mmd_mask & (1 << devad)) {
+                       mmd_mask &= ~(1 << devad);
+
+                       /* Read twice because link state is latched and a
+                        * read moves the current state into the register */
+                       mdio->mdio_read(mdio->dev, mdio->prtad,
+                                       devad, MDIO_STAT1);
+                       reg = mdio->mdio_read(mdio->dev, mdio->prtad,
+                                             devad, MDIO_STAT1);
+                       if (reg < 0 || !(reg & MDIO_STAT1_LSTATUS))
+                               return false;
+               }
+       }
+
+       return true;
+}
+EXPORT_SYMBOL(mdio45_links_ok);
+
+/**
+ * mdio45_nway_restart - restart auto-negotiation for this interface
+ * @mdio: MDIO interface
+ *
+ * Returns 0 on success, negative on error.
+ */
+int mdio45_nway_restart(const struct mdio_if_info *mdio)
+{
+       if (!(mdio->mmds & MDIO_DEVS_AN))
+               return -EOPNOTSUPP;
+
+       mdio_set_flag(mdio, mdio->prtad, MDIO_MMD_AN, MDIO_CTRL1,
+                     MDIO_AN_CTRL1_RESTART, true);
+       return 0;
+}
+EXPORT_SYMBOL(mdio45_nway_restart);
+
+static u32 mdio45_get_an(const struct mdio_if_info *mdio, u16 addr)
+{
+       u32 result = 0;
+       int reg;
+
+       reg = mdio->mdio_read(mdio->dev, mdio->prtad, MDIO_MMD_AN, addr);
+       if (reg & ADVERTISE_10HALF)
+               result |= ADVERTISED_10baseT_Half;
+       if (reg & ADVERTISE_10FULL)
+               result |= ADVERTISED_10baseT_Full;
+       if (reg & ADVERTISE_100HALF)
+               result |= ADVERTISED_100baseT_Half;
+       if (reg & ADVERTISE_100FULL)
+               result |= ADVERTISED_100baseT_Full;
+       return result;
+}
+
+/**
+ * mdio45_ethtool_gset_npage - get settings for ETHTOOL_GSET
+ * @mdio: MDIO interface
+ * @ecmd: Ethtool request structure
+ * @npage_adv: Modes currently advertised on next pages
+ * @npage_lpa: Modes advertised by link partner on next pages
+ *
+ * Since the CSRs for auto-negotiation using next pages are not fully
+ * standardised, this function does not attempt to decode them.  The
+ * caller must pass them in.
+ */
+void mdio45_ethtool_gset_npage(const struct mdio_if_info *mdio,
+                              struct ethtool_cmd *ecmd,
+                              u32 npage_adv, u32 npage_lpa)
+{
+       int reg;
+
+       ecmd->transceiver = XCVR_INTERNAL;
+       ecmd->phy_address = mdio->prtad;
+       ecmd->mdio_support =
+               mdio->mode_support & (MDIO_SUPPORTS_C45 | MDIO_SUPPORTS_C22);
+
+       reg = mdio->mdio_read(mdio->dev, mdio->prtad, MDIO_MMD_PMAPMD,
+                             MDIO_CTRL2);
+       switch (reg & MDIO_PMA_CTRL2_TYPE) {
+       case MDIO_PMA_CTRL2_10GBT:
+       case MDIO_PMA_CTRL2_1000BT:
+       case MDIO_PMA_CTRL2_100BTX:
+       case MDIO_PMA_CTRL2_10BT:
+               ecmd->port = PORT_TP;
+               ecmd->supported = SUPPORTED_TP;
+               reg = mdio->mdio_read(mdio->dev, mdio->prtad, MDIO_MMD_PMAPMD,
+                                     MDIO_SPEED);
+               if (reg & MDIO_SPEED_10G)
+                       ecmd->supported |= SUPPORTED_10000baseT_Full;
+               if (reg & MDIO_PMA_SPEED_1000)
+                       ecmd->supported |= (SUPPORTED_1000baseT_Full |
+                                           SUPPORTED_1000baseT_Half);
+               if (reg & MDIO_PMA_SPEED_100)
+                       ecmd->supported |= (SUPPORTED_100baseT_Full |
+                                           SUPPORTED_100baseT_Half);
+               if (reg & MDIO_PMA_SPEED_10)
+                       ecmd->supported |= (SUPPORTED_10baseT_Full |
+                                           SUPPORTED_10baseT_Half);
+               ecmd->advertising = ADVERTISED_TP;
+               break;
+
+       case MDIO_PMA_CTRL2_10GBCX4:
+               ecmd->port = PORT_OTHER;
+               ecmd->supported = 0;
+               ecmd->advertising = 0;
+               break;
+
+       case MDIO_PMA_CTRL2_10GBKX4:
+       case MDIO_PMA_CTRL2_10GBKR:
+       case MDIO_PMA_CTRL2_1000BKX:
+               ecmd->port = PORT_OTHER;
+               ecmd->supported = SUPPORTED_Backplane;
+               reg = mdio->mdio_read(mdio->dev, mdio->prtad, MDIO_MMD_PMAPMD,
+                                     MDIO_PMA_EXTABLE);
+               if (reg & MDIO_PMA_EXTABLE_10GBKX4)
+                       ecmd->supported |= SUPPORTED_10000baseKX4_Full;
+               if (reg & MDIO_PMA_EXTABLE_10GBKR)
+                       ecmd->supported |= SUPPORTED_10000baseKR_Full;
+               if (reg & MDIO_PMA_EXTABLE_1000BKX)
+                       ecmd->supported |= SUPPORTED_1000baseKX_Full;
+               reg = mdio->mdio_read(mdio->dev, mdio->prtad, MDIO_MMD_PMAPMD,
+                                     MDIO_PMA_10GBR_FECABLE);
+               if (reg & MDIO_PMA_10GBR_FECABLE_ABLE)
+                       ecmd->supported |= SUPPORTED_10000baseR_FEC;
+               ecmd->advertising = ADVERTISED_Backplane;
+               break;
+
+       /* All the other defined modes are flavours of optical */
+       default:
+               ecmd->port = PORT_FIBRE;
+               ecmd->supported = SUPPORTED_FIBRE;
+               ecmd->advertising = ADVERTISED_FIBRE;
+               break;
+       }
+
+       if (mdio->mmds & MDIO_DEVS_AN) {
+               ecmd->supported |= SUPPORTED_Autoneg;
+               reg = mdio->mdio_read(mdio->dev, mdio->prtad, MDIO_MMD_AN,
+                                     MDIO_CTRL1);
+               if (reg & MDIO_AN_CTRL1_ENABLE) {
+                       ecmd->autoneg = AUTONEG_ENABLE;
+                       ecmd->advertising |=
+                               ADVERTISED_Autoneg |
+                               mdio45_get_an(mdio, MDIO_AN_ADVERTISE) |
+                               npage_adv;
+               } else {
+                       ecmd->autoneg = AUTONEG_DISABLE;
+               }
+       } else {
+               ecmd->autoneg = AUTONEG_DISABLE;
+       }
+
+       if (ecmd->autoneg) {
+               u32 modes = 0;
+               int an_stat = mdio->mdio_read(mdio->dev, mdio->prtad,
+                                             MDIO_MMD_AN, MDIO_STAT1);
+
+               /* If AN is complete and successful, report best common
+                * mode, otherwise report best advertised mode. */
+               if (an_stat & MDIO_AN_STAT1_COMPLETE) {
+                       ecmd->lp_advertising =
+                               mdio45_get_an(mdio, MDIO_AN_LPA) | npage_lpa;
+                       if (an_stat & MDIO_AN_STAT1_LPABLE)
+                               ecmd->lp_advertising |= ADVERTISED_Autoneg;
+                       modes = ecmd->advertising & ecmd->lp_advertising;
+               }
+               if ((modes & ~ADVERTISED_Autoneg) == 0)
+                       modes = ecmd->advertising;
+
+               if (modes & (ADVERTISED_10000baseT_Full |
+                            ADVERTISED_10000baseKX4_Full |
+                            ADVERTISED_10000baseKR_Full)) {
+                       ecmd->speed = SPEED_10000;
+                       ecmd->duplex = DUPLEX_FULL;
+               } else if (modes & (ADVERTISED_1000baseT_Full |
+                                   ADVERTISED_1000baseT_Half |
+                                   ADVERTISED_1000baseKX_Full)) {
+                       ecmd->speed = SPEED_1000;
+                       ecmd->duplex = !(modes & ADVERTISED_1000baseT_Half);
+               } else if (modes & (ADVERTISED_100baseT_Full |
+                                   ADVERTISED_100baseT_Half)) {
+                       ecmd->speed = SPEED_100;
+                       ecmd->duplex = !!(modes & ADVERTISED_100baseT_Full);
+               } else {
+                       ecmd->speed = SPEED_10;
+                       ecmd->duplex = !!(modes & ADVERTISED_10baseT_Full);
+               }
+       } else {
+               /* Report forced settings */
+               reg = mdio->mdio_read(mdio->dev, mdio->prtad, MDIO_MMD_PMAPMD,
+                                     MDIO_CTRL1);
+               ecmd->speed = (((reg & MDIO_PMA_CTRL1_SPEED1000) ? 100 : 1) *
+                              ((reg & MDIO_PMA_CTRL1_SPEED100) ? 100 : 10));
+               ecmd->duplex = (reg & MDIO_CTRL1_FULLDPLX ||
+                               ecmd->speed == SPEED_10000);
+       }
+
+       /* 10GBASE-T MDI/MDI-X */
+       if (ecmd->port == PORT_TP && ecmd->speed == SPEED_10000) {
+               switch (mdio->mdio_read(mdio->dev, mdio->prtad, MDIO_MMD_PMAPMD,
+                                       MDIO_PMA_10GBT_SWAPPOL)) {
+               case MDIO_PMA_10GBT_SWAPPOL_ABNX | MDIO_PMA_10GBT_SWAPPOL_CDNX:
+                       ecmd->eth_tp_mdix = ETH_TP_MDI;
+                       break;
+               case 0:
+                       ecmd->eth_tp_mdix = ETH_TP_MDI_X;
+                       break;
+               default:
+                       /* It's complicated... */
+                       ecmd->eth_tp_mdix = ETH_TP_MDI_INVALID;
+                       break;
+               }
+       }
+}
+EXPORT_SYMBOL(mdio45_ethtool_gset_npage);
+
+/**
+ * mdio45_ethtool_spauseparam_an - set auto-negotiated pause parameters
+ * @mdio: MDIO interface
+ * @ecmd: Ethtool request structure
+ *
+ * This function assumes that the PHY has an auto-negotiation MMD.  It
+ * will enable and disable advertising of flow control as appropriate.
+ */
+void mdio45_ethtool_spauseparam_an(const struct mdio_if_info *mdio,
+                                  const struct ethtool_pauseparam *ecmd)
+{
+       int adv, old_adv;
+
+       WARN_ON(!(mdio->mmds & MDIO_DEVS_AN));
+
+       old_adv = mdio->mdio_read(mdio->dev, mdio->prtad, MDIO_MMD_AN,
+                                 MDIO_AN_ADVERTISE);
+       adv = old_adv & ~(ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM);
+       if (ecmd->autoneg)
+               adv |= mii_advertise_flowctrl(
+                       (ecmd->rx_pause ? FLOW_CTRL_RX : 0) |
+                       (ecmd->tx_pause ? FLOW_CTRL_TX : 0));
+       if (adv != old_adv) {
+               mdio->mdio_write(mdio->dev, mdio->prtad, MDIO_MMD_AN,
+                                MDIO_AN_ADVERTISE, adv);
+               mdio45_nway_restart(mdio);
+       }
+}
+EXPORT_SYMBOL(mdio45_ethtool_spauseparam_an);
+
+/**
+ * mdio_mii_ioctl - MII ioctl interface for MDIO (clause 22 or 45) PHYs
+ * @mdio: MDIO interface
+ * @mii_data: MII ioctl data structure
+ * @cmd: MII ioctl command
+ *
+ * Returns 0 on success, negative on error.
+ */
+int mdio_mii_ioctl(const struct mdio_if_info *mdio,
+                  struct mii_ioctl_data *mii_data, int cmd)
+{
+       int prtad, devad;
+       u16 addr = mii_data->reg_num;
+
+       /* Validate/convert cmd to one of SIOC{G,S}MIIREG */
+       switch (cmd) {
+       case SIOCGMIIPHY:
+               if (mdio->prtad == MDIO_PRTAD_NONE)
+                       return -EOPNOTSUPP;
+               mii_data->phy_id = mdio->prtad;
+               cmd = SIOCGMIIREG;
+               break;
+       case SIOCGMIIREG:
+               break;
+       case SIOCSMIIREG:
+               if (!capable(CAP_NET_ADMIN))
+                       return -EPERM;
+               break;
+       default:
+               return -EOPNOTSUPP;
+       }
+
+       /* Validate/convert phy_id */
+       if ((mdio->mode_support & MDIO_SUPPORTS_C45) &&
+           mdio_phy_id_is_c45(mii_data->phy_id)) {
+               prtad = mdio_phy_id_prtad(mii_data->phy_id);
+               devad = mdio_phy_id_devad(mii_data->phy_id);
+       } else if ((mdio->mode_support & MDIO_SUPPORTS_C22) &&
+                  mii_data->phy_id < 0x20) {
+               prtad = mii_data->phy_id;
+               devad = MDIO_DEVAD_NONE;
+               addr &= 0x1f;
+       } else if ((mdio->mode_support & MDIO_EMULATE_C22) &&
+                  mdio->prtad != MDIO_PRTAD_NONE &&
+                  mii_data->phy_id == mdio->prtad) {
+               /* Remap commonly-used MII registers. */
+               prtad = mdio->prtad;
+               switch (addr) {
+               case MII_BMCR:
+               case MII_BMSR:
+               case MII_PHYSID1:
+               case MII_PHYSID2:
+                       devad = __ffs(mdio->mmds);
+                       break;
+               case MII_ADVERTISE:
+               case MII_LPA:
+                       if (!(mdio->mmds & MDIO_DEVS_AN))
+                               return -EINVAL;
+                       devad = MDIO_MMD_AN;
+                       if (addr == MII_ADVERTISE)
+                               addr = MDIO_AN_ADVERTISE;
+                       else
+                               addr = MDIO_AN_LPA;
+                       break;
+               default:
+                       return -EINVAL;
+               }
+       } else {
+               return -EINVAL;
+       }
+
+       if (cmd == SIOCGMIIREG) {
+               int rc = mdio->mdio_read(mdio->dev, prtad, devad, addr);
+               if (rc < 0)
+                       return rc;
+               mii_data->val_out = rc;
+               return 0;
+       } else {
+               return mdio->mdio_write(mdio->dev, prtad, devad, addr,
+                                       mii_data->val_in);
+       }
+}
+EXPORT_SYMBOL(mdio_mii_ioctl);
index dbd3436912b8cf847517b0dd8e44ea3c88af8577..5d04d94f2a2164bab6a8eac4c01705601a7cd24c 100644 (file)
@@ -770,9 +770,17 @@ static int meth_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
        }
 }
 
-/*
- * Return statistics to the caller
- */
+static const struct net_device_ops meth_netdev_ops = {
+       .ndo_open               = meth_open,
+       .ndo_stop               = meth_release,
+       .ndo_start_xmit         = meth_tx,
+       .ndo_do_ioctl           = meth_ioctl,
+       .ndo_tx_timeout         = meth_tx_timeout,
+       .ndo_change_mtu         = eth_change_mtu,
+       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_set_mac_address    = eth_mac_addr,
+};
+
 /*
  * The init function.
  */
@@ -786,16 +794,10 @@ static int __init meth_probe(struct platform_device *pdev)
        if (!dev)
                return -ENOMEM;
 
-       dev->open            = meth_open;
-       dev->stop            = meth_release;
-       dev->hard_start_xmit = meth_tx;
-       dev->do_ioctl        = meth_ioctl;
-#ifdef HAVE_TX_TIMEOUT
-       dev->tx_timeout      = meth_tx_timeout;
-       dev->watchdog_timeo  = timeout;
-#endif
-       dev->irq             = MACE_ETHERNET_IRQ;
-       dev->base_addr       = (unsigned long)&mace->eth;
+       dev->netdev_ops         = &meth_netdev_ops;
+       dev->watchdog_timeo     = timeout;
+       dev->irq                = MACE_ETHERNET_IRQ;
+       dev->base_addr          = (unsigned long)&mace->eth;
        memcpy(dev->dev_addr, o2meth_eaddr, 6);
 
        priv = netdev_priv(dev);
index 92056051f2691cd3fe94fa82603cc2a9849511f9..d81a5d22a3a9f0dd88514753ce62649255691380 100644 (file)
 #include <linux/module.h>
 #include <linux/netdevice.h>
 #include <linux/ethtool.h>
-#include <linux/mii.h>
+#include <linux/mdio.h>
+
+static u32 mii_get_an(struct mii_if_info *mii, u16 addr)
+{
+       u32 result = 0;
+       int advert;
+
+       advert = mii->mdio_read(mii->dev, mii->phy_id, addr);
+       if (advert & LPA_LPACK)
+               result |= ADVERTISED_Autoneg;
+       if (advert & ADVERTISE_10HALF)
+               result |= ADVERTISED_10baseT_Half;
+       if (advert & ADVERTISE_10FULL)
+               result |= ADVERTISED_10baseT_Full;
+       if (advert & ADVERTISE_100HALF)
+               result |= ADVERTISED_100baseT_Half;
+       if (advert & ADVERTISE_100FULL)
+               result |= ADVERTISED_100baseT_Full;
+
+       return result;
+}
 
 /**
  * mii_ethtool_gset - get settings that are specified in @ecmd
@@ -43,8 +63,8 @@
 int mii_ethtool_gset(struct mii_if_info *mii, struct ethtool_cmd *ecmd)
 {
        struct net_device *dev = mii->dev;
-       u32 advert, bmcr, lpa, nego;
-       u32 advert2 = 0, bmcr2 = 0, lpa2 = 0;
+       u16 bmcr, bmsr, ctrl1000 = 0, stat1000 = 0;
+       u32 nego;
 
        ecmd->supported =
            (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full |
@@ -62,50 +82,51 @@ int mii_ethtool_gset(struct mii_if_info *mii, struct ethtool_cmd *ecmd)
 
        /* this isn't fully supported at higher layers */
        ecmd->phy_address = mii->phy_id;
+       ecmd->mdio_support = MDIO_SUPPORTS_C22;
 
        ecmd->advertising = ADVERTISED_TP | ADVERTISED_MII;
-       advert = mii->mdio_read(dev, mii->phy_id, MII_ADVERTISE);
-       if (mii->supports_gmii)
-               advert2 = mii->mdio_read(dev, mii->phy_id, MII_CTRL1000);
-
-       if (advert & ADVERTISE_10HALF)
-               ecmd->advertising |= ADVERTISED_10baseT_Half;
-       if (advert & ADVERTISE_10FULL)
-               ecmd->advertising |= ADVERTISED_10baseT_Full;
-       if (advert & ADVERTISE_100HALF)
-               ecmd->advertising |= ADVERTISED_100baseT_Half;
-       if (advert & ADVERTISE_100FULL)
-               ecmd->advertising |= ADVERTISED_100baseT_Full;
-       if (advert2 & ADVERTISE_1000HALF)
-               ecmd->advertising |= ADVERTISED_1000baseT_Half;
-       if (advert2 & ADVERTISE_1000FULL)
-               ecmd->advertising |= ADVERTISED_1000baseT_Full;
 
        bmcr = mii->mdio_read(dev, mii->phy_id, MII_BMCR);
-       lpa = mii->mdio_read(dev, mii->phy_id, MII_LPA);
+       bmsr = mii->mdio_read(dev, mii->phy_id, MII_BMSR);
        if (mii->supports_gmii) {
-               bmcr2 = mii->mdio_read(dev, mii->phy_id, MII_CTRL1000);
-               lpa2 = mii->mdio_read(dev, mii->phy_id, MII_STAT1000);
+               ctrl1000 = mii->mdio_read(dev, mii->phy_id, MII_CTRL1000);
+               stat1000 = mii->mdio_read(dev, mii->phy_id, MII_STAT1000);
        }
        if (bmcr & BMCR_ANENABLE) {
                ecmd->advertising |= ADVERTISED_Autoneg;
                ecmd->autoneg = AUTONEG_ENABLE;
 
-               nego = mii_nway_result(advert & lpa);
-               if ((bmcr2 & (ADVERTISE_1000HALF | ADVERTISE_1000FULL)) &
-                   (lpa2 >> 2))
+               ecmd->advertising |= mii_get_an(mii, MII_ADVERTISE);
+               if (ctrl1000 & ADVERTISE_1000HALF)
+                       ecmd->advertising |= ADVERTISED_1000baseT_Half;
+               if (ctrl1000 & ADVERTISE_1000FULL)
+                       ecmd->advertising |= ADVERTISED_1000baseT_Full;
+
+               if (bmsr & BMSR_ANEGCOMPLETE) {
+                       ecmd->lp_advertising = mii_get_an(mii, MII_LPA);
+                       if (stat1000 & LPA_1000HALF)
+                               ecmd->lp_advertising |=
+                                       ADVERTISED_1000baseT_Half;
+                       if (stat1000 & LPA_1000FULL)
+                               ecmd->lp_advertising |=
+                                       ADVERTISED_1000baseT_Full;
+               } else {
+                       ecmd->lp_advertising = 0;
+               }
+
+               nego = ecmd->advertising & ecmd->lp_advertising;
+
+               if (nego & (ADVERTISED_1000baseT_Full |
+                           ADVERTISED_1000baseT_Half)) {
                        ecmd->speed = SPEED_1000;
-               else if (nego == LPA_100FULL || nego == LPA_100HALF)
+                       ecmd->duplex = !!(nego & ADVERTISED_1000baseT_Full);
+               } else if (nego & (ADVERTISED_100baseT_Full |
+                                  ADVERTISED_100baseT_Half)) {
                        ecmd->speed = SPEED_100;
-               else
-                       ecmd->speed = SPEED_10;
-               if ((lpa2 & LPA_1000FULL) || nego == LPA_100FULL ||
-                   nego == LPA_10FULL) {
-                       ecmd->duplex = DUPLEX_FULL;
-                       mii->full_duplex = 1;
+                       ecmd->duplex = !!(nego & ADVERTISED_100baseT_Full);
                } else {
-                       ecmd->duplex = DUPLEX_HALF;
-                       mii->full_duplex = 0;
+                       ecmd->speed = SPEED_10;
+                       ecmd->duplex = !!(nego & ADVERTISED_10baseT_Full);
                }
        } else {
                ecmd->autoneg = AUTONEG_DISABLE;
@@ -116,6 +137,8 @@ int mii_ethtool_gset(struct mii_if_info *mii, struct ethtool_cmd *ecmd)
                ecmd->duplex = (bmcr & BMCR_FULLDPLX) ? DUPLEX_FULL : DUPLEX_HALF;
        }
 
+       mii->full_duplex = ecmd->duplex;
+
        /* ignore maxtxpkt, maxrxpkt for now */
 
        return 0;
index 664835b822fba31ed7d3d8cd15ce20172887dc36..b3b9a147d09a3c9cf23906d6034049240bf20919 100644 (file)
@@ -237,6 +237,16 @@ static void mipsnet_set_mclist(struct net_device *dev)
 {
 }
 
+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_change_mtu         = eth_change_mtu,
+       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_set_mac_address    = eth_mac_addr,
+};
+
 static int __init mipsnet_probe(struct platform_device *dev)
 {
        struct net_device *netdev;
@@ -250,10 +260,7 @@ static int __init mipsnet_probe(struct platform_device *dev)
 
        platform_set_drvdata(dev, netdev);
 
-       netdev->open                    = mipsnet_open;
-       netdev->stop                    = mipsnet_close;
-       netdev->hard_start_xmit         = mipsnet_xmit;
-       netdev->set_multicast_list      = mipsnet_set_mclist;
+       netdev->netdev_ops = &mipsnet_netdev_ops;
 
        /*
         * TODO: probe for these or load them from PARAM
index 21040a0d81fe18991e1eb0b01f0cfe25815ee4e6..1fd068e1d93054ad7e9d72feade1e053d9939673 100644 (file)
@@ -5,5 +5,5 @@ mlx4_core-y :=  alloc.o catas.o cmd.o cq.o eq.o fw.o icm.o intf.o main.o mcg.o \
 
 obj-$(CONFIG_MLX4_EN)               += mlx4_en.o
 
-mlx4_en-y :=   en_main.o en_tx.o en_rx.o en_params.o en_port.o en_cq.o \
+mlx4_en-y :=   en_main.o en_tx.o en_rx.o en_ethtool.o en_port.o en_cq.o \
                en_resources.o en_netdev.o
index a276125b709bf5deb4b2e26af10d01aa30dd4052..21786ad4455e25de27c3fe9c45122d37d5d5cbd6 100644 (file)
@@ -89,6 +89,9 @@ int mlx4_en_activate_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq)
        *cq->mcq.arm_db    = 0;
        memset(cq->buf, 0, cq->buf_size);
 
+       if (!cq->is_tx)
+               cq->size = priv->rx_ring[cq->ring].actual_size;
+
        err = mlx4_cq_alloc(mdev->dev, cq->size, &cq->wqres.mtt, &mdev->priv_uar,
                            cq->wqres.db.dma, &cq->mcq, cq->vector, cq->is_tx);
        if (err)
diff --git a/drivers/net/mlx4/en_ethtool.c b/drivers/net/mlx4/en_ethtool.c
new file mode 100644 (file)
index 0000000..091f990
--- /dev/null
@@ -0,0 +1,426 @@
+/*
+ * Copyright (c) 2007 Mellanox Technologies. All rights reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses.  You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the
+ * OpenIB.org BSD license below:
+ *
+ *     Redistribution and use in source and binary forms, with or
+ *     without modification, are permitted provided that the following
+ *     conditions are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the following
+ *        disclaimer in the documentation and/or other materials
+ *        provided with the distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/ethtool.h>
+#include <linux/netdevice.h>
+
+#include "mlx4_en.h"
+#include "en_port.h"
+
+
+static void mlx4_en_update_lro_stats(struct mlx4_en_priv *priv)
+{
+       int i;
+
+       priv->port_stats.lro_aggregated = 0;
+       priv->port_stats.lro_flushed = 0;
+       priv->port_stats.lro_no_desc = 0;
+
+       for (i = 0; i < priv->rx_ring_num; i++) {
+               priv->port_stats.lro_aggregated += priv->rx_ring[i].lro.stats.aggregated;
+               priv->port_stats.lro_flushed += priv->rx_ring[i].lro.stats.flushed;
+               priv->port_stats.lro_no_desc += priv->rx_ring[i].lro.stats.no_desc;
+       }
+}
+
+static void
+mlx4_en_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo)
+{
+       struct mlx4_en_priv *priv = netdev_priv(dev);
+       struct mlx4_en_dev *mdev = priv->mdev;
+
+       sprintf(drvinfo->driver, DRV_NAME " (%s)", mdev->dev->board_id);
+       strncpy(drvinfo->version, DRV_VERSION " (" DRV_RELDATE ")", 32);
+       sprintf(drvinfo->fw_version, "%d.%d.%d",
+               (u16) (mdev->dev->caps.fw_ver >> 32),
+               (u16) ((mdev->dev->caps.fw_ver >> 16) & 0xffff),
+               (u16) (mdev->dev->caps.fw_ver & 0xffff));
+       strncpy(drvinfo->bus_info, pci_name(mdev->dev->pdev), 32);
+       drvinfo->n_stats = 0;
+       drvinfo->regdump_len = 0;
+       drvinfo->eedump_len = 0;
+}
+
+static u32 mlx4_en_get_tso(struct net_device *dev)
+{
+       return (dev->features & NETIF_F_TSO) != 0;
+}
+
+static int mlx4_en_set_tso(struct net_device *dev, u32 data)
+{
+       struct mlx4_en_priv *priv = netdev_priv(dev);
+
+       if (data) {
+               if (!priv->mdev->LSO_support)
+                       return -EPERM;
+               dev->features |= (NETIF_F_TSO | NETIF_F_TSO6);
+       } else
+               dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6);
+       return 0;
+}
+
+static u32 mlx4_en_get_rx_csum(struct net_device *dev)
+{
+       struct mlx4_en_priv *priv = netdev_priv(dev);
+       return priv->rx_csum;
+}
+
+static int mlx4_en_set_rx_csum(struct net_device *dev, u32 data)
+{
+       struct mlx4_en_priv *priv = netdev_priv(dev);
+       priv->rx_csum = (data != 0);
+       return 0;
+}
+
+static const char main_strings[][ETH_GSTRING_LEN] = {
+       "rx_packets", "tx_packets", "rx_bytes", "tx_bytes", "rx_errors",
+       "tx_errors", "rx_dropped", "tx_dropped", "multicast", "collisions",
+       "rx_length_errors", "rx_over_errors", "rx_crc_errors",
+       "rx_frame_errors", "rx_fifo_errors", "rx_missed_errors",
+       "tx_aborted_errors", "tx_carrier_errors", "tx_fifo_errors",
+       "tx_heartbeat_errors", "tx_window_errors",
+
+       /* port statistics */
+       "lro_aggregated", "lro_flushed", "lro_no_desc", "tso_packets",
+       "queue_stopped", "wake_queue", "tx_timeout", "rx_alloc_failed",
+       "rx_csum_good", "rx_csum_none", "tx_chksum_offload",
+
+       /* packet statistics */
+       "broadcast", "rx_prio_0", "rx_prio_1", "rx_prio_2", "rx_prio_3",
+       "rx_prio_4", "rx_prio_5", "rx_prio_6", "rx_prio_7", "tx_prio_0",
+       "tx_prio_1", "tx_prio_2", "tx_prio_3", "tx_prio_4", "tx_prio_5",
+       "tx_prio_6", "tx_prio_7",
+};
+#define NUM_MAIN_STATS 21
+#define NUM_ALL_STATS  (NUM_MAIN_STATS + NUM_PORT_STATS + NUM_PKT_STATS + NUM_PERF_STATS)
+
+static u32 mlx4_en_get_msglevel(struct net_device *dev)
+{
+       return ((struct mlx4_en_priv *) netdev_priv(dev))->msg_enable;
+}
+
+static void mlx4_en_set_msglevel(struct net_device *dev, u32 val)
+{
+       ((struct mlx4_en_priv *) netdev_priv(dev))->msg_enable = val;
+}
+
+static void mlx4_en_get_wol(struct net_device *netdev,
+                           struct ethtool_wolinfo *wol)
+{
+       wol->supported = 0;
+       wol->wolopts = 0;
+
+       return;
+}
+
+static int mlx4_en_get_sset_count(struct net_device *dev, int sset)
+{
+       struct mlx4_en_priv *priv = netdev_priv(dev);
+
+       if (sset != ETH_SS_STATS)
+               return -EOPNOTSUPP;
+
+       return NUM_ALL_STATS + (priv->tx_ring_num + priv->rx_ring_num) * 2;
+}
+
+static void mlx4_en_get_ethtool_stats(struct net_device *dev,
+               struct ethtool_stats *stats, uint64_t *data)
+{
+       struct mlx4_en_priv *priv = netdev_priv(dev);
+       int index = 0;
+       int i;
+
+       spin_lock_bh(&priv->stats_lock);
+
+       mlx4_en_update_lro_stats(priv);
+
+       for (i = 0; i < NUM_MAIN_STATS; i++)
+               data[index++] = ((unsigned long *) &priv->stats)[i];
+       for (i = 0; i < NUM_PORT_STATS; i++)
+               data[index++] = ((unsigned long *) &priv->port_stats)[i];
+       for (i = 0; i < priv->tx_ring_num; i++) {
+               data[index++] = priv->tx_ring[i].packets;
+               data[index++] = priv->tx_ring[i].bytes;
+       }
+       for (i = 0; i < priv->rx_ring_num; i++) {
+               data[index++] = priv->rx_ring[i].packets;
+               data[index++] = priv->rx_ring[i].bytes;
+       }
+       for (i = 0; i < NUM_PKT_STATS; i++)
+               data[index++] = ((unsigned long *) &priv->pkstats)[i];
+       spin_unlock_bh(&priv->stats_lock);
+
+}
+
+static void mlx4_en_get_strings(struct net_device *dev,
+                               uint32_t stringset, uint8_t *data)
+{
+       struct mlx4_en_priv *priv = netdev_priv(dev);
+       int index = 0;
+       int i;
+
+       if (stringset != ETH_SS_STATS)
+               return;
+
+       /* Add main counters */
+       for (i = 0; i < NUM_MAIN_STATS; i++)
+               strcpy(data + (index++) * ETH_GSTRING_LEN, main_strings[i]);
+       for (i = 0; i < NUM_PORT_STATS; i++)
+               strcpy(data + (index++) * ETH_GSTRING_LEN,
+                       main_strings[i + NUM_MAIN_STATS]);
+       for (i = 0; i < priv->tx_ring_num; i++) {
+               sprintf(data + (index++) * ETH_GSTRING_LEN,
+                       "tx%d_packets", i);
+               sprintf(data + (index++) * ETH_GSTRING_LEN,
+                       "tx%d_bytes", i);
+       }
+       for (i = 0; i < priv->rx_ring_num; i++) {
+               sprintf(data + (index++) * ETH_GSTRING_LEN,
+                       "rx%d_packets", i);
+               sprintf(data + (index++) * ETH_GSTRING_LEN,
+                       "rx%d_bytes", i);
+       }
+       for (i = 0; i < NUM_PKT_STATS; i++)
+               strcpy(data + (index++) * ETH_GSTRING_LEN,
+                       main_strings[i + NUM_MAIN_STATS + NUM_PORT_STATS]);
+}
+
+static int mlx4_en_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+       cmd->autoneg = AUTONEG_DISABLE;
+       cmd->supported = SUPPORTED_10000baseT_Full;
+       cmd->advertising = SUPPORTED_10000baseT_Full;
+       if (netif_carrier_ok(dev)) {
+               cmd->speed = SPEED_10000;
+               cmd->duplex = DUPLEX_FULL;
+       } else {
+               cmd->speed = -1;
+               cmd->duplex = -1;
+       }
+       return 0;
+}
+
+static int mlx4_en_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+       if ((cmd->autoneg == AUTONEG_ENABLE) ||
+           (cmd->speed != SPEED_10000) || (cmd->duplex != DUPLEX_FULL))
+               return -EINVAL;
+
+       /* Nothing to change */
+       return 0;
+}
+
+static int mlx4_en_get_coalesce(struct net_device *dev,
+                             struct ethtool_coalesce *coal)
+{
+       struct mlx4_en_priv *priv = netdev_priv(dev);
+
+       coal->tx_coalesce_usecs = 0;
+       coal->tx_max_coalesced_frames = 0;
+       coal->rx_coalesce_usecs = priv->rx_usecs;
+       coal->rx_max_coalesced_frames = priv->rx_frames;
+
+       coal->pkt_rate_low = priv->pkt_rate_low;
+       coal->rx_coalesce_usecs_low = priv->rx_usecs_low;
+       coal->pkt_rate_high = priv->pkt_rate_high;
+       coal->rx_coalesce_usecs_high = priv->rx_usecs_high;
+       coal->rate_sample_interval = priv->sample_interval;
+       coal->use_adaptive_rx_coalesce = priv->adaptive_rx_coal;
+       return 0;
+}
+
+static int mlx4_en_set_coalesce(struct net_device *dev,
+                             struct ethtool_coalesce *coal)
+{
+       struct mlx4_en_priv *priv = netdev_priv(dev);
+       int err, i;
+
+       priv->rx_frames = (coal->rx_max_coalesced_frames ==
+                          MLX4_EN_AUTO_CONF) ?
+                               MLX4_EN_RX_COAL_TARGET :
+                               coal->rx_max_coalesced_frames;
+       priv->rx_usecs = (coal->rx_coalesce_usecs ==
+                         MLX4_EN_AUTO_CONF) ?
+                               MLX4_EN_RX_COAL_TIME :
+                               coal->rx_coalesce_usecs;
+
+       /* Set adaptive coalescing params */
+       priv->pkt_rate_low = coal->pkt_rate_low;
+       priv->rx_usecs_low = coal->rx_coalesce_usecs_low;
+       priv->pkt_rate_high = coal->pkt_rate_high;
+       priv->rx_usecs_high = coal->rx_coalesce_usecs_high;
+       priv->sample_interval = coal->rate_sample_interval;
+       priv->adaptive_rx_coal = coal->use_adaptive_rx_coalesce;
+       priv->last_moder_time = MLX4_EN_AUTO_CONF;
+       if (priv->adaptive_rx_coal)
+               return 0;
+
+       for (i = 0; i < priv->rx_ring_num; i++) {
+               priv->rx_cq[i].moder_cnt = priv->rx_frames;
+               priv->rx_cq[i].moder_time = priv->rx_usecs;
+               err = mlx4_en_set_cq_moder(priv, &priv->rx_cq[i]);
+               if (err)
+                       return err;
+       }
+       return 0;
+}
+
+static int mlx4_en_set_pauseparam(struct net_device *dev,
+                               struct ethtool_pauseparam *pause)
+{
+       struct mlx4_en_priv *priv = netdev_priv(dev);
+       struct mlx4_en_dev *mdev = priv->mdev;
+       int err;
+
+       priv->prof->tx_pause = pause->tx_pause != 0;
+       priv->prof->rx_pause = pause->rx_pause != 0;
+       err = mlx4_SET_PORT_general(mdev->dev, priv->port,
+                                   priv->rx_skb_size + ETH_FCS_LEN,
+                                   priv->prof->tx_pause,
+                                   priv->prof->tx_ppp,
+                                   priv->prof->rx_pause,
+                                   priv->prof->rx_ppp);
+       if (err)
+               en_err(priv, "Failed setting pause params\n");
+
+       return err;
+}
+
+static void mlx4_en_get_pauseparam(struct net_device *dev,
+                                struct ethtool_pauseparam *pause)
+{
+       struct mlx4_en_priv *priv = netdev_priv(dev);
+
+       pause->tx_pause = priv->prof->tx_pause;
+       pause->rx_pause = priv->prof->rx_pause;
+}
+
+static int mlx4_en_set_ringparam(struct net_device *dev,
+                                struct ethtool_ringparam *param)
+{
+       struct mlx4_en_priv *priv = netdev_priv(dev);
+       struct mlx4_en_dev *mdev = priv->mdev;
+       u32 rx_size, tx_size;
+       int port_up = 0;
+       int err = 0;
+
+       if (param->rx_jumbo_pending || param->rx_mini_pending)
+               return -EINVAL;
+
+       rx_size = roundup_pow_of_two(param->rx_pending);
+       rx_size = max_t(u32, rx_size, MLX4_EN_MIN_RX_SIZE);
+       rx_size = min_t(u32, rx_size, MLX4_EN_MAX_RX_SIZE);
+       tx_size = roundup_pow_of_two(param->tx_pending);
+       tx_size = max_t(u32, tx_size, MLX4_EN_MIN_TX_SIZE);
+       tx_size = min_t(u32, tx_size, MLX4_EN_MAX_TX_SIZE);
+
+       if (rx_size == priv->prof->rx_ring_size &&
+           tx_size == priv->prof->tx_ring_size)
+               return 0;
+
+       mutex_lock(&mdev->state_lock);
+       if (priv->port_up) {
+               port_up = 1;
+               mlx4_en_stop_port(dev);
+       }
+
+       mlx4_en_free_resources(priv);
+
+       priv->prof->tx_ring_size = tx_size;
+       priv->prof->rx_ring_size = rx_size;
+
+       err = mlx4_en_alloc_resources(priv);
+       if (err) {
+               en_err(priv, "Failed reallocating port resources\n");
+               goto out;
+       }
+       if (port_up) {
+               err = mlx4_en_start_port(dev);
+               if (err)
+                       en_err(priv, "Failed starting port\n");
+       }
+
+out:
+       mutex_unlock(&mdev->state_lock);
+       return err;
+}
+
+static void mlx4_en_get_ringparam(struct net_device *dev,
+                                 struct ethtool_ringparam *param)
+{
+       struct mlx4_en_priv *priv = netdev_priv(dev);
+       struct mlx4_en_dev *mdev = priv->mdev;
+
+       memset(param, 0, sizeof(*param));
+       param->rx_max_pending = MLX4_EN_MAX_RX_SIZE;
+       param->tx_max_pending = MLX4_EN_MAX_TX_SIZE;
+       param->rx_pending = mdev->profile.prof[priv->port].rx_ring_size;
+       param->tx_pending = mdev->profile.prof[priv->port].tx_ring_size;
+}
+
+const struct ethtool_ops mlx4_en_ethtool_ops = {
+       .get_drvinfo = mlx4_en_get_drvinfo,
+       .get_settings = mlx4_en_get_settings,
+       .set_settings = mlx4_en_set_settings,
+#ifdef NETIF_F_TSO
+       .get_tso = mlx4_en_get_tso,
+       .set_tso = mlx4_en_set_tso,
+#endif
+       .get_sg = ethtool_op_get_sg,
+       .set_sg = ethtool_op_set_sg,
+       .get_link = ethtool_op_get_link,
+       .get_rx_csum = mlx4_en_get_rx_csum,
+       .set_rx_csum = mlx4_en_set_rx_csum,
+       .get_tx_csum = ethtool_op_get_tx_csum,
+       .set_tx_csum = ethtool_op_set_tx_ipv6_csum,
+       .get_strings = mlx4_en_get_strings,
+       .get_sset_count = mlx4_en_get_sset_count,
+       .get_ethtool_stats = mlx4_en_get_ethtool_stats,
+       .get_wol = mlx4_en_get_wol,
+       .get_msglevel = mlx4_en_get_msglevel,
+       .set_msglevel = mlx4_en_set_msglevel,
+       .get_coalesce = mlx4_en_get_coalesce,
+       .set_coalesce = mlx4_en_set_coalesce,
+       .get_pauseparam = mlx4_en_get_pauseparam,
+       .set_pauseparam = mlx4_en_set_pauseparam,
+       .get_ringparam = mlx4_en_get_ringparam,
+       .set_ringparam = mlx4_en_set_ringparam,
+       .get_flags = ethtool_op_get_flags,
+       .set_flags = ethtool_op_set_flags,
+};
+
+
+
+
+
index 510633fd57f613906660f848b879b03d72fccd5c..9ed4a158f895cedaf7e4fc441e7361944523d117 100644 (file)
@@ -51,6 +51,55 @@ static const char mlx4_en_version[] =
        DRV_NAME ": Mellanox ConnectX HCA Ethernet driver v"
        DRV_VERSION " (" DRV_RELDATE ")\n";
 
+#define MLX4_EN_PARM_INT(X, def_val, desc) \
+       static unsigned int X = def_val;\
+       module_param(X , uint, 0444); \
+       MODULE_PARM_DESC(X, desc);
+
+
+/*
+ * Device scope module parameters
+ */
+
+
+/* Use a XOR rathern than Toeplitz hash function for RSS */
+MLX4_EN_PARM_INT(rss_xor, 0, "Use XOR hash function for RSS");
+
+/* RSS hash type mask - default to <saddr, daddr, sport, dport> */
+MLX4_EN_PARM_INT(rss_mask, 0xf, "RSS hash type bitmask");
+
+/* Number of LRO sessions per Rx ring (rounded up to a power of two) */
+MLX4_EN_PARM_INT(num_lro, MLX4_EN_MAX_LRO_DESCRIPTORS,
+                "Number of LRO sessions per ring or disabled (0)");
+
+/* Priority pausing */
+MLX4_EN_PARM_INT(pfctx, 0, "Priority based Flow Control policy on TX[7:0]."
+                          " Per priority bit mask");
+MLX4_EN_PARM_INT(pfcrx, 0, "Priority based Flow Control policy on RX[7:0]."
+                          " Per priority bit mask");
+
+static int mlx4_en_get_profile(struct mlx4_en_dev *mdev)
+{
+       struct mlx4_en_profile *params = &mdev->profile;
+       int i;
+
+       params->rss_xor = (rss_xor != 0);
+       params->rss_mask = rss_mask & 0x1f;
+       params->num_lro = min_t(int, num_lro , MLX4_EN_MAX_LRO_DESCRIPTORS);
+       for (i = 1; i <= MLX4_MAX_PORTS; i++) {
+               params->prof[i].rx_pause = 1;
+               params->prof[i].rx_ppp = pfcrx;
+               params->prof[i].tx_pause = 1;
+               params->prof[i].tx_ppp = pfctx;
+               params->prof[i].tx_ring_size = MLX4_EN_DEF_TX_RING_SIZE;
+               params->prof[i].rx_ring_size = MLX4_EN_DEF_RX_RING_SIZE;
+               params->prof[i].tx_ring_num = MLX4_EN_NUM_TX_RINGS +
+                       (!!pfcrx) * MLX4_EN_NUM_PPP_RINGS;
+       }
+
+       return 0;
+}
+
 static void mlx4_en_event(struct mlx4_dev *dev, void *endev_ptr,
                          enum mlx4_dev_event event, int port)
 {
@@ -194,28 +243,11 @@ static void *mlx4_en_add(struct mlx4_dev *dev)
        /* Create a netdev for each port */
        mlx4_foreach_port(i, dev, MLX4_PORT_TYPE_ETH) {
                mlx4_info(mdev, "Activating port:%d\n", i);
-               if (mlx4_en_init_netdev(mdev, i, &mdev->profile.prof[i])) {
+               if (mlx4_en_init_netdev(mdev, i, &mdev->profile.prof[i]))
                        mdev->pndev[i] = NULL;
-                       goto err_free_netdev;
-               }
        }
        return mdev;
 
-
-err_free_netdev:
-       mlx4_foreach_port(i, dev, MLX4_PORT_TYPE_ETH) {
-               if (mdev->pndev[i])
-                       mlx4_en_destroy_netdev(mdev->pndev[i]);
-       }
-
-       mutex_lock(&mdev->state_lock);
-       mdev->device_up = false;
-       mutex_unlock(&mdev->state_lock);
-       flush_workqueue(mdev->workqueue);
-
-       /* Stop event queue before we drop down to release shared SW state */
-       destroy_workqueue(mdev->workqueue);
-
 err_mr:
        mlx4_mr_free(dev, &mdev->mr);
 err_uar:
index e8eeef0c9c9ace85ccb9696cb81ee5fd1c94e452..e02bafdd368204a1831439ff595d110a6d3313a1 100644 (file)
@@ -51,14 +51,14 @@ static void mlx4_en_vlan_rx_register(struct net_device *dev, struct vlan_group *
        struct mlx4_en_dev *mdev = priv->mdev;
        int err;
 
-       mlx4_dbg(HW, priv, "Registering VLAN group:%p\n", grp);
+       en_dbg(HW, priv, "Registering VLAN group:%p\n", grp);
        priv->vlgrp = grp;
 
        mutex_lock(&mdev->state_lock);
        if (mdev->device_up && priv->port_up) {
                err = mlx4_SET_VLAN_FLTR(mdev->dev, priv->port, grp);
                if (err)
-                       mlx4_err(mdev, "Failed configuring VLAN filter\n");
+                       en_err(priv, "Failed configuring VLAN filter\n");
        }
        mutex_unlock(&mdev->state_lock);
 }
@@ -72,15 +72,15 @@ static void mlx4_en_vlan_rx_add_vid(struct net_device *dev, unsigned short vid)
        if (!priv->vlgrp)
                return;
 
-       mlx4_dbg(HW, priv, "adding VLAN:%d (vlgrp entry:%p)\n",
-                vid, vlan_group_get_device(priv->vlgrp, vid));
+       en_dbg(HW, priv, "adding VLAN:%d (vlgrp entry:%p)\n",
+              vid, vlan_group_get_device(priv->vlgrp, vid));
 
        /* Add VID to port VLAN filter */
        mutex_lock(&mdev->state_lock);
        if (mdev->device_up && priv->port_up) {
                err = mlx4_SET_VLAN_FLTR(mdev->dev, priv->port, priv->vlgrp);
                if (err)
-                       mlx4_err(mdev, "Failed configuring VLAN filter\n");
+                       en_err(priv, "Failed configuring VLAN filter\n");
        }
        mutex_unlock(&mdev->state_lock);
 }
@@ -94,9 +94,8 @@ static void mlx4_en_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
        if (!priv->vlgrp)
                return;
 
-       mlx4_dbg(HW, priv, "Killing VID:%d (vlgrp:%p vlgrp "
-                "entry:%p)\n", vid, priv->vlgrp,
-                vlan_group_get_device(priv->vlgrp, vid));
+       en_dbg(HW, priv, "Killing VID:%d (vlgrp:%p vlgrp entry:%p)\n",
+              vid, priv->vlgrp, vlan_group_get_device(priv->vlgrp, vid));
        vlan_group_set_device(priv->vlgrp, vid, NULL);
 
        /* Remove VID from port VLAN filter */
@@ -104,7 +103,7 @@ static void mlx4_en_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
        if (mdev->device_up && priv->port_up) {
                err = mlx4_SET_VLAN_FLTR(mdev->dev, priv->port, priv->vlgrp);
                if (err)
-                       mlx4_err(mdev, "Failed configuring VLAN filter\n");
+                       en_err(priv, "Failed configuring VLAN filter\n");
        }
        mutex_unlock(&mdev->state_lock);
 }
@@ -150,9 +149,10 @@ static void mlx4_en_do_set_mac(struct work_struct *work)
                err = mlx4_register_mac(mdev->dev, priv->port,
                                        priv->mac, &priv->mac_index);
                if (err)
-                       mlx4_err(mdev, "Failed changing HW MAC address\n");
+                       en_err(priv, "Failed changing HW MAC address\n");
        } else
-               mlx4_dbg(HW, priv, "Port is down, exiting...\n");
+               en_dbg(HW, priv, "Port is down while "
+                                "registering mac, exiting...\n");
 
        mutex_unlock(&mdev->state_lock);
 }
@@ -174,7 +174,6 @@ static void mlx4_en_clear_list(struct net_device *dev)
 static void mlx4_en_cache_mclist(struct net_device *dev)
 {
        struct mlx4_en_priv *priv = netdev_priv(dev);
-       struct mlx4_en_dev *mdev = priv->mdev;
        struct dev_mc_list *mclist;
        struct dev_mc_list *tmp;
        struct dev_mc_list *plist = NULL;
@@ -182,7 +181,7 @@ static void mlx4_en_cache_mclist(struct net_device *dev)
        for (mclist = dev->mc_list; mclist; mclist = mclist->next) {
                tmp = kmalloc(sizeof(struct dev_mc_list), GFP_ATOMIC);
                if (!tmp) {
-                       mlx4_err(mdev, "failed to allocate multicast list\n");
+                       en_err(priv, "failed to allocate multicast list\n");
                        mlx4_en_clear_list(dev);
                        return;
                }
@@ -219,13 +218,13 @@ static void mlx4_en_do_set_multicast(struct work_struct *work)
 
        mutex_lock(&mdev->state_lock);
        if (!mdev->device_up) {
-               mlx4_dbg(HW, priv, "Card is not up, ignoring "
-                                  "multicast change.\n");
+               en_dbg(HW, priv, "Card is not up, "
+                                "ignoring multicast change.\n");
                goto out;
        }
        if (!priv->port_up) {
-               mlx4_dbg(HW, priv, "Port is down, ignoring "
-                                  "multicast change.\n");
+               en_dbg(HW, priv, "Port is down, "
+                                "ignoring  multicast change.\n");
                goto out;
        }
 
@@ -236,29 +235,27 @@ static void mlx4_en_do_set_multicast(struct work_struct *work)
        if (dev->flags & IFF_PROMISC) {
                if (!(priv->flags & MLX4_EN_FLAG_PROMISC)) {
                        if (netif_msg_rx_status(priv))
-                               mlx4_warn(mdev, "Port:%d entering promiscuous mode\n",
-                                         priv->port);
+                               en_warn(priv, "Entering promiscuous mode\n");
                        priv->flags |= MLX4_EN_FLAG_PROMISC;
 
                        /* Enable promiscouos mode */
                        err = mlx4_SET_PORT_qpn_calc(mdev->dev, priv->port,
                                                     priv->base_qpn, 1);
                        if (err)
-                               mlx4_err(mdev, "Failed enabling "
-                                        "promiscous mode\n");
+                               en_err(priv, "Failed enabling "
+                                            "promiscous mode\n");
 
                        /* Disable port multicast filter (unconditionally) */
                        err = mlx4_SET_MCAST_FLTR(mdev->dev, priv->port, 0,
                                                  0, MLX4_MCAST_DISABLE);
                        if (err)
-                               mlx4_err(mdev, "Failed disabling "
-                                        "multicast filter\n");
+                               en_err(priv, "Failed disabling "
+                                            "multicast filter\n");
 
                        /* Disable port VLAN filter */
                        err = mlx4_SET_VLAN_FLTR(mdev->dev, priv->port, NULL);
                        if (err)
-                               mlx4_err(mdev, "Failed disabling "
-                                        "VLAN filter\n");
+                               en_err(priv, "Failed disabling VLAN filter\n");
                }
                goto out;
        }
@@ -269,20 +266,19 @@ static void mlx4_en_do_set_multicast(struct work_struct *work)
 
        if (priv->flags & MLX4_EN_FLAG_PROMISC) {
                if (netif_msg_rx_status(priv))
-                       mlx4_warn(mdev, "Port:%d leaving promiscuous mode\n",
-                                 priv->port);
+                       en_warn(priv, "Leaving promiscuous mode\n");
                priv->flags &= ~MLX4_EN_FLAG_PROMISC;
 
                /* Disable promiscouos mode */
                err = mlx4_SET_PORT_qpn_calc(mdev->dev, priv->port,
                                             priv->base_qpn, 0);
                if (err)
-                       mlx4_err(mdev, "Failed disabling promiscous mode\n");
+                       en_err(priv, "Failed disabling promiscous mode\n");
 
                /* Enable port VLAN filter */
                err = mlx4_SET_VLAN_FLTR(mdev->dev, priv->port, priv->vlgrp);
                if (err)
-                       mlx4_err(mdev, "Failed enabling VLAN filter\n");
+                       en_err(priv, "Failed enabling VLAN filter\n");
        }
 
        /* Enable/disable the multicast filter according to IFF_ALLMULTI */
@@ -290,12 +286,12 @@ static void mlx4_en_do_set_multicast(struct work_struct *work)
                err = mlx4_SET_MCAST_FLTR(mdev->dev, priv->port, 0,
                                          0, MLX4_MCAST_DISABLE);
                if (err)
-                       mlx4_err(mdev, "Failed disabling multicast filter\n");
+                       en_err(priv, "Failed disabling multicast filter\n");
        } else {
                err = mlx4_SET_MCAST_FLTR(mdev->dev, priv->port, 0,
                                          0, MLX4_MCAST_DISABLE);
                if (err)
-                       mlx4_err(mdev, "Failed disabling multicast filter\n");
+                       en_err(priv, "Failed disabling multicast filter\n");
 
                /* Flush mcast filter and init it with broadcast address */
                mlx4_SET_MCAST_FLTR(mdev->dev, priv->port, ETH_BCAST,
@@ -314,7 +310,7 @@ static void mlx4_en_do_set_multicast(struct work_struct *work)
                err = mlx4_SET_MCAST_FLTR(mdev->dev, priv->port, 0,
                                          0, MLX4_MCAST_ENABLE);
                if (err)
-                       mlx4_err(mdev, "Failed enabling multicast filter\n");
+                       en_err(priv, "Failed enabling multicast filter\n");
 
                mlx4_en_clear_list(dev);
        }
@@ -346,10 +342,10 @@ static void mlx4_en_tx_timeout(struct net_device *dev)
        struct mlx4_en_dev *mdev = priv->mdev;
 
        if (netif_msg_timer(priv))
-               mlx4_warn(mdev, "Tx timeout called on port:%d\n", priv->port);
+               en_warn(priv, "Tx timeout called on port:%d\n", priv->port);
 
        priv->port_stats.tx_timeout++;
-       mlx4_dbg(DRV, priv, "Scheduling watchdog\n");
+       en_dbg(DRV, priv, "Scheduling watchdog\n");
        queue_work(mdev->workqueue, &priv->watchdog_task);
 }
 
@@ -376,10 +372,10 @@ static void mlx4_en_set_default_moderation(struct mlx4_en_priv *priv)
         *   satisfy our coelsing target.
         * - moder_time is set to a fixed value.
         */
-       priv->rx_frames = MLX4_EN_RX_COAL_TARGET / priv->dev->mtu + 1;
+       priv->rx_frames = MLX4_EN_RX_COAL_TARGET;
        priv->rx_usecs = MLX4_EN_RX_COAL_TIME;
-       mlx4_dbg(INTR, priv, "Default coalesing params for mtu:%d - "
-                            "rx_frames:%d rx_usecs:%d\n",
+       en_dbg(INTR, priv, "Default coalesing params for mtu:%d - "
+                          "rx_frames:%d rx_usecs:%d\n",
                 priv->dev->mtu, priv->rx_frames, priv->rx_usecs);
 
        /* Setup cq moderation params */
@@ -412,7 +408,6 @@ static void mlx4_en_set_default_moderation(struct mlx4_en_priv *priv)
 static void mlx4_en_auto_moderation(struct mlx4_en_priv *priv)
 {
        unsigned long period = (unsigned long) (jiffies - priv->last_moder_jiffies);
-       struct mlx4_en_dev *mdev = priv->mdev;
        struct mlx4_en_cq *cq;
        unsigned long packets;
        unsigned long rate;
@@ -472,11 +467,11 @@ static void mlx4_en_auto_moderation(struct mlx4_en_priv *priv)
                moder_time = priv->rx_usecs;
        }
 
-       mlx4_dbg(INTR, priv, "tx rate:%lu rx_rate:%lu\n",
-                tx_pkt_diff * HZ / period, rx_pkt_diff * HZ / period);
+       en_dbg(INTR, priv, "tx rate:%lu rx_rate:%lu\n",
+              tx_pkt_diff * HZ / period, rx_pkt_diff * HZ / period);
 
-       mlx4_dbg(INTR, priv, "Rx moder_time changed from:%d to %d period:%lu "
-                "[jiff] packets:%lu avg_pkt_size:%lu rate:%lu [p/s])\n",
+       en_dbg(INTR, priv, "Rx moder_time changed from:%d to %d period:%lu "
+              "[jiff] packets:%lu avg_pkt_size:%lu rate:%lu [p/s])\n",
                 priv->last_moder_time, moder_time, period, packets,
                 avg_pkt_size, rate);
 
@@ -487,8 +482,7 @@ static void mlx4_en_auto_moderation(struct mlx4_en_priv *priv)
                        cq->moder_time = moder_time;
                        err = mlx4_en_set_cq_moder(priv, cq);
                        if (err) {
-                               mlx4_err(mdev, "Failed modifying moderation for cq:%d "
-                                        "on port:%d\n", i, priv->port);
+                               en_err(priv, "Failed modifying moderation for cq:%d\n", i);
                                break;
                        }
                }
@@ -511,8 +505,7 @@ static void mlx4_en_do_get_stats(struct work_struct *work)
 
        err = mlx4_en_DUMP_ETH_STATS(mdev, priv->port, 0);
        if (err)
-               mlx4_dbg(HW, priv, "Could not update stats for "
-                                  "port:%d\n", priv->port);
+               en_dbg(HW, priv, "Could not update stats \n");
 
        mutex_lock(&mdev->state_lock);
        if (mdev->device_up) {
@@ -536,12 +529,10 @@ static void mlx4_en_linkstate(struct work_struct *work)
         * report to system log */
        if (priv->last_link_state != linkstate) {
                if (linkstate == MLX4_DEV_EVENT_PORT_DOWN) {
-                       if (netif_msg_link(priv))
-                               mlx4_info(mdev, "Port %d - link down\n", priv->port);
+                       en_dbg(LINK, priv, "Link Down\n");
                        netif_carrier_off(priv->dev);
                } else {
-                       if (netif_msg_link(priv))
-                               mlx4_info(mdev, "Port %d - link up\n", priv->port);
+                       en_dbg(LINK, priv, "Link Up\n");
                        netif_carrier_on(priv->dev);
                }
        }
@@ -556,58 +547,53 @@ int mlx4_en_start_port(struct net_device *dev)
        struct mlx4_en_dev *mdev = priv->mdev;
        struct mlx4_en_cq *cq;
        struct mlx4_en_tx_ring *tx_ring;
-       struct mlx4_en_rx_ring *rx_ring;
        int rx_index = 0;
        int tx_index = 0;
-       u16 stride;
        int err = 0;
        int i;
        int j;
 
        if (priv->port_up) {
-               mlx4_dbg(DRV, priv, "start port called while port already up\n");
+               en_dbg(DRV, priv, "start port called while port already up\n");
                return 0;
        }
 
        /* Calculate Rx buf size */
        dev->mtu = min(dev->mtu, priv->max_mtu);
        mlx4_en_calc_rx_buf(dev);
-       mlx4_dbg(DRV, priv, "Rx buf size:%d\n", priv->rx_skb_size);
-       stride = roundup_pow_of_two(sizeof(struct mlx4_en_rx_desc) +
-                                   DS_SIZE * priv->num_frags);
+       en_dbg(DRV, priv, "Rx buf size:%d\n", priv->rx_skb_size);
+
        /* Configure rx cq's and rings */
+       err = mlx4_en_activate_rx_rings(priv);
+       if (err) {
+               en_err(priv, "Failed to activate RX rings\n");
+               return err;
+       }
        for (i = 0; i < priv->rx_ring_num; i++) {
                cq = &priv->rx_cq[i];
-               rx_ring = &priv->rx_ring[i];
 
                err = mlx4_en_activate_cq(priv, cq);
                if (err) {
-                       mlx4_err(mdev, "Failed activating Rx CQ\n");
+                       en_err(priv, "Failed activating Rx CQ\n");
                        goto cq_err;
                }
                for (j = 0; j < cq->size; j++)
                        cq->buf[j].owner_sr_opcode = MLX4_CQE_OWNER_MASK;
                err = mlx4_en_set_cq_moder(priv, cq);
                if (err) {
-                       mlx4_err(mdev, "Failed setting cq moderation parameters");
+                       en_err(priv, "Failed setting cq moderation parameters");
                        mlx4_en_deactivate_cq(priv, cq);
                        goto cq_err;
                }
                mlx4_en_arm_cq(priv, cq);
-
+               priv->rx_ring[i].cqn = cq->mcq.cqn;
                ++rx_index;
        }
 
-       err = mlx4_en_activate_rx_rings(priv);
-       if (err) {
-               mlx4_err(mdev, "Failed to activate RX rings\n");
-               goto cq_err;
-       }
-
        err = mlx4_en_config_rss_steer(priv);
        if (err) {
-               mlx4_err(mdev, "Failed configuring rss steering\n");
-               goto rx_err;
+               en_err(priv, "Failed configuring rss steering\n");
+               goto cq_err;
        }
 
        /* Configure tx cq's and rings */
@@ -616,16 +602,16 @@ int mlx4_en_start_port(struct net_device *dev)
                cq = &priv->tx_cq[i];
                err = mlx4_en_activate_cq(priv, cq);
                if (err) {
-                       mlx4_err(mdev, "Failed allocating Tx CQ\n");
+                       en_err(priv, "Failed allocating Tx CQ\n");
                        goto tx_err;
                }
                err = mlx4_en_set_cq_moder(priv, cq);
                if (err) {
-                       mlx4_err(mdev, "Failed setting cq moderation parameters");
+                       en_err(priv, "Failed setting cq moderation parameters");
                        mlx4_en_deactivate_cq(priv, cq);
                        goto tx_err;
                }
-               mlx4_dbg(DRV, priv, "Resetting index of collapsed CQ:%d to -1\n", i);
+               en_dbg(DRV, priv, "Resetting index of collapsed CQ:%d to -1\n", i);
                cq->buf->wqe_index = cpu_to_be16(0xffff);
 
                /* Configure ring */
@@ -633,7 +619,7 @@ int mlx4_en_start_port(struct net_device *dev)
                err = mlx4_en_activate_tx_ring(priv, tx_ring, cq->mcq.cqn,
                                               priv->rx_ring[0].srq.srqn);
                if (err) {
-                       mlx4_err(mdev, "Failed allocating Tx ring\n");
+                       en_err(priv, "Failed allocating Tx ring\n");
                        mlx4_en_deactivate_cq(priv, cq);
                        goto tx_err;
                }
@@ -651,30 +637,30 @@ int mlx4_en_start_port(struct net_device *dev)
                                    priv->prof->rx_pause,
                                    priv->prof->rx_ppp);
        if (err) {
-               mlx4_err(mdev, "Failed setting port general configurations"
-                              " for port %d, with error %d\n", priv->port, err);
+               en_err(priv, "Failed setting port general configurations "
+                            "for port %d, with error %d\n", priv->port, err);
                goto tx_err;
        }
        /* Set default qp number */
        err = mlx4_SET_PORT_qpn_calc(mdev->dev, priv->port, priv->base_qpn, 0);
        if (err) {
-               mlx4_err(mdev, "Failed setting default qp numbers\n");
+               en_err(priv, "Failed setting default qp numbers\n");
                goto tx_err;
        }
        /* Set port mac number */
-       mlx4_dbg(DRV, priv, "Setting mac for port %d\n", priv->port);
+       en_dbg(DRV, priv, "Setting mac for port %d\n", priv->port);
        err = mlx4_register_mac(mdev->dev, priv->port,
                                priv->mac, &priv->mac_index);
        if (err) {
-               mlx4_err(mdev, "Failed setting port mac\n");
+               en_err(priv, "Failed setting port mac\n");
                goto tx_err;
        }
 
        /* Init port */
-       mlx4_dbg(HW, priv, "Initializing port\n");
+       en_dbg(HW, priv, "Initializing port\n");
        err = mlx4_INIT_PORT(mdev->dev, priv->port);
        if (err) {
-               mlx4_err(mdev, "Failed Initializing port\n");
+               en_err(priv, "Failed Initializing port\n");
                goto mac_err;
        }
 
@@ -694,12 +680,11 @@ tx_err:
        }
 
        mlx4_en_release_rss_steer(priv);
-rx_err:
-       for (i = 0; i < priv->rx_ring_num; i++)
-               mlx4_en_deactivate_rx_ring(priv, &priv->rx_ring[i]);
 cq_err:
        while (rx_index--)
                mlx4_en_deactivate_cq(priv, &priv->rx_cq[rx_index]);
+       for (i = 0; i < priv->rx_ring_num; i++)
+               mlx4_en_deactivate_rx_ring(priv, &priv->rx_ring[i]);
 
        return err; /* need to close devices */
 }
@@ -712,8 +697,7 @@ void mlx4_en_stop_port(struct net_device *dev)
        int i;
 
        if (!priv->port_up) {
-               mlx4_dbg(DRV, priv, "stop port (%d) called while port already down\n",
-                        priv->port);
+               en_dbg(DRV, priv, "stop port called while port already down\n");
                return;
        }
        netif_stop_queue(dev);
@@ -758,13 +742,13 @@ static void mlx4_en_restart(struct work_struct *work)
        struct mlx4_en_dev *mdev = priv->mdev;
        struct net_device *dev = priv->dev;
 
-       mlx4_dbg(DRV, priv, "Watchdog task called for port %d\n", priv->port);
+       en_dbg(DRV, priv, "Watchdog task called for port %d\n", priv->port);
 
        mutex_lock(&mdev->state_lock);
        if (priv->port_up) {
                mlx4_en_stop_port(dev);
                if (mlx4_en_start_port(dev))
-                       mlx4_err(mdev, "Failed restarting port %d\n", priv->port);
+                       en_err(priv, "Failed restarting port %d\n", priv->port);
        }
        mutex_unlock(&mdev->state_lock);
 }
@@ -780,14 +764,14 @@ static int mlx4_en_open(struct net_device *dev)
        mutex_lock(&mdev->state_lock);
 
        if (!mdev->device_up) {
-               mlx4_err(mdev, "Cannot open - device down/disabled\n");
+               en_err(priv, "Cannot open - device down/disabled\n");
                err = -EBUSY;
                goto out;
        }
 
        /* Reset HW statistics and performance counters */
        if (mlx4_en_DUMP_ETH_STATS(mdev, priv->port, 1))
-               mlx4_dbg(HW, priv, "Failed dumping statistics\n");
+               en_dbg(HW, priv, "Failed dumping statistics\n");
 
        memset(&priv->stats, 0, sizeof(priv->stats));
        memset(&priv->pstats, 0, sizeof(priv->pstats));
@@ -804,7 +788,7 @@ static int mlx4_en_open(struct net_device *dev)
        mlx4_en_set_default_moderation(priv);
        err = mlx4_en_start_port(dev);
        if (err)
-               mlx4_err(mdev, "Failed starting port:%d\n", priv->port);
+               en_err(priv, "Failed starting port:%d\n", priv->port);
 
 out:
        mutex_unlock(&mdev->state_lock);
@@ -817,8 +801,7 @@ static int mlx4_en_close(struct net_device *dev)
        struct mlx4_en_priv *priv = netdev_priv(dev);
        struct mlx4_en_dev *mdev = priv->mdev;
 
-       if (netif_msg_ifdown(priv))
-               mlx4_info(mdev, "Close called for port:%d\n", priv->port);
+       en_dbg(IFDOWN, priv, "Close port called\n");
 
        mutex_lock(&mdev->state_lock);
 
@@ -850,7 +833,6 @@ void mlx4_en_free_resources(struct mlx4_en_priv *priv)
 
 int mlx4_en_alloc_resources(struct mlx4_en_priv *priv)
 {
-       struct mlx4_en_dev *mdev = priv->mdev;
        struct mlx4_en_port_profile *prof = priv->prof;
        int i;
 
@@ -879,7 +861,7 @@ int mlx4_en_alloc_resources(struct mlx4_en_priv *priv)
        return 0;
 
 err:
-       mlx4_err(mdev, "Failed to allocate NIC resources\n");
+       en_err(priv, "Failed to allocate NIC resources\n");
        return -ENOMEM;
 }
 
@@ -889,7 +871,7 @@ void mlx4_en_destroy_netdev(struct net_device *dev)
        struct mlx4_en_priv *priv = netdev_priv(dev);
        struct mlx4_en_dev *mdev = priv->mdev;
 
-       mlx4_dbg(DRV, priv, "Destroying netdev on port:%d\n", priv->port);
+       en_dbg(DRV, priv, "Destroying netdev on port:%d\n", priv->port);
 
        /* Unregister device - this will close the port if it was up */
        if (priv->registered)
@@ -918,11 +900,11 @@ static int mlx4_en_change_mtu(struct net_device *dev, int new_mtu)
        struct mlx4_en_dev *mdev = priv->mdev;
        int err = 0;
 
-       mlx4_dbg(DRV, priv, "Change MTU called - current:%d new:%d\n",
+       en_dbg(DRV, priv, "Change MTU called - current:%d new:%d\n",
                 dev->mtu, new_mtu);
 
        if ((new_mtu < MLX4_EN_MIN_MTU) || (new_mtu > priv->max_mtu)) {
-               mlx4_err(mdev, "Bad MTU size:%d.\n", new_mtu);
+               en_err(priv, "Bad MTU size:%d.\n", new_mtu);
                return -EPERM;
        }
        dev->mtu = new_mtu;
@@ -932,13 +914,13 @@ static int mlx4_en_change_mtu(struct net_device *dev, int new_mtu)
                if (!mdev->device_up) {
                        /* NIC is probably restarting - let watchdog task reset
                         * the port */
-                       mlx4_dbg(DRV, priv, "Change MTU called with card down!?\n");
+                       en_dbg(DRV, priv, "Change MTU called with card down!?\n");
                } else {
                        mlx4_en_stop_port(dev);
                        mlx4_en_set_default_moderation(priv);
                        err = mlx4_en_start_port(dev);
                        if (err) {
-                               mlx4_err(mdev, "Failed restarting port:%d\n",
+                               en_err(priv, "Failed restarting port:%d\n",
                                         priv->port);
                                queue_work(mdev->workqueue, &priv->watchdog_task);
                        }
@@ -952,6 +934,7 @@ static const struct net_device_ops mlx4_netdev_ops = {
        .ndo_open               = mlx4_en_open,
        .ndo_stop               = mlx4_en_close,
        .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_mac_address    = mlx4_en_set_mac,
@@ -974,7 +957,7 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
        int i;
        int err;
 
-       dev = alloc_etherdev(sizeof(struct mlx4_en_priv));
+       dev = alloc_etherdev_mq(sizeof(struct mlx4_en_priv), prof->tx_ring_num);
        if (dev == NULL) {
                mlx4_err(mdev, "Net device allocation failed\n");
                return -ENOMEM;
@@ -1012,7 +995,7 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
        priv->max_mtu = mdev->dev->caps.eth_mtu_cap[priv->port];
        priv->mac = mdev->dev->caps.def_mac[priv->port];
        if (ILLEGAL_MAC(priv->mac)) {
-               mlx4_err(mdev, "Port: %d, invalid mac burned: 0x%llx, quiting\n",
+               en_err(priv, "Port: %d, invalid mac burned: 0x%llx, quiting\n",
                         priv->port, priv->mac);
                err = -EINVAL;
                goto out;
@@ -1031,19 +1014,17 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
        err = mlx4_alloc_hwq_res(mdev->dev, &priv->res,
                                MLX4_EN_PAGE_SIZE, MLX4_EN_PAGE_SIZE);
        if (err) {
-               mlx4_err(mdev, "Failed to allocate page for rx qps\n");
+               en_err(priv, "Failed to allocate page for rx qps\n");
                goto out;
        }
        priv->allocated = 1;
 
-       /* Populate Tx priority mappings */
-       mlx4_en_set_prio_map(priv, priv->tx_prio_map, prof->tx_ring_num);
-
        /*
         * Initialize netdev entry points
         */
        dev->netdev_ops = &mlx4_netdev_ops;
        dev->watchdog_timeo = MLX4_EN_WATCHDOG_TIMEOUT;
+       dev->real_num_tx_queues = MLX4_EN_NUM_TX_RINGS;
 
        SET_ETHTOOL_OPS(dev, &mlx4_en_ethtool_ops);
 
@@ -1057,7 +1038,9 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
         * Set driver features
         */
        dev->features |= NETIF_F_SG;
+       dev->vlan_features |= NETIF_F_SG;
        dev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
+       dev->vlan_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
        dev->features |= NETIF_F_HIGHDMA;
        dev->features |= NETIF_F_HW_VLAN_TX |
                         NETIF_F_HW_VLAN_RX |
@@ -1067,6 +1050,8 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
        if (mdev->LSO_support) {
                dev->features |= NETIF_F_TSO;
                dev->features |= NETIF_F_TSO6;
+               dev->vlan_features |= NETIF_F_TSO;
+               dev->vlan_features |= NETIF_F_TSO6;
        }
 
        mdev->pndev[port] = dev;
@@ -1074,9 +1059,13 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
        netif_carrier_off(dev);
        err = register_netdev(dev);
        if (err) {
-               mlx4_err(mdev, "Netdev registration failed\n");
+               en_err(priv, "Netdev registration failed for port %d\n", port);
                goto out;
        }
+
+       en_warn(priv, "Using %d TX rings\n", prof->tx_ring_num);
+       en_warn(priv, "Using %d RX rings\n", prof->rx_ring_num);
+
        priv->registered = 1;
        queue_delayed_work(mdev->workqueue, &priv->stats_task, STATS_DELAY);
        return 0;
diff --git a/drivers/net/mlx4/en_params.c b/drivers/net/mlx4/en_params.c
deleted file mode 100644 (file)
index c1bd040..0000000
+++ /dev/null
@@ -1,485 +0,0 @@
-/*
- * Copyright (c) 2007 Mellanox Technologies. All rights reserved.
- *
- * This software is available to you under a choice of one of two
- * licenses.  You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the
- * OpenIB.org BSD license below:
- *
- *     Redistribution and use in source and binary forms, with or
- *     without modification, are permitted provided that the following
- *     conditions are met:
- *
- *      - Redistributions of source code must retain the above
- *        copyright notice, this list of conditions and the following
- *        disclaimer.
- *
- *      - Redistributions in binary form must reproduce the above
- *        copyright notice, this list of conditions and the following
- *        disclaimer in the documentation and/or other materials
- *        provided with the distribution.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/ethtool.h>
-#include <linux/netdevice.h>
-
-#include "mlx4_en.h"
-#include "en_port.h"
-
-#define MLX4_EN_PARM_INT(X, def_val, desc) \
-       static unsigned int X = def_val;\
-       module_param(X , uint, 0444); \
-       MODULE_PARM_DESC(X, desc);
-
-
-/*
- * Device scope module parameters
- */
-
-
-/* Use a XOR rathern than Toeplitz hash function for RSS */
-MLX4_EN_PARM_INT(rss_xor, 0, "Use XOR hash function for RSS");
-
-/* RSS hash type mask - default to <saddr, daddr, sport, dport> */
-MLX4_EN_PARM_INT(rss_mask, 0xf, "RSS hash type bitmask");
-
-/* Number of LRO sessions per Rx ring (rounded up to a power of two) */
-MLX4_EN_PARM_INT(num_lro, MLX4_EN_MAX_LRO_DESCRIPTORS,
-                "Number of LRO sessions per ring or disabled (0)");
-
-/* Priority pausing */
-MLX4_EN_PARM_INT(pfctx, 0, "Priority based Flow Control policy on TX[7:0]."
-                          " Per priority bit mask");
-MLX4_EN_PARM_INT(pfcrx, 0, "Priority based Flow Control policy on RX[7:0]."
-                          " Per priority bit mask");
-
-int mlx4_en_get_profile(struct mlx4_en_dev *mdev)
-{
-       struct mlx4_en_profile *params = &mdev->profile;
-       int i;
-
-       params->rss_xor = (rss_xor != 0);
-       params->rss_mask = rss_mask & 0x1f;
-       params->num_lro = min_t(int, num_lro , MLX4_EN_MAX_LRO_DESCRIPTORS);
-       for (i = 1; i <= MLX4_MAX_PORTS; i++) {
-               params->prof[i].rx_pause = 1;
-               params->prof[i].rx_ppp = pfcrx;
-               params->prof[i].tx_pause = 1;
-               params->prof[i].tx_ppp = pfctx;
-               params->prof[i].tx_ring_size = MLX4_EN_DEF_TX_RING_SIZE;
-               params->prof[i].rx_ring_size = MLX4_EN_DEF_RX_RING_SIZE;
-       }
-       if (pfcrx || pfctx) {
-               params->prof[1].tx_ring_num = MLX4_EN_TX_RING_NUM;
-               params->prof[2].tx_ring_num = MLX4_EN_TX_RING_NUM;
-       } else {
-               params->prof[1].tx_ring_num = 1;
-               params->prof[2].tx_ring_num = 1;
-       }
-
-       return 0;
-}
-
-
-/*
- * Ethtool support
- */
-
-static void mlx4_en_update_lro_stats(struct mlx4_en_priv *priv)
-{
-       int i;
-
-       priv->port_stats.lro_aggregated = 0;
-       priv->port_stats.lro_flushed = 0;
-       priv->port_stats.lro_no_desc = 0;
-
-       for (i = 0; i < priv->rx_ring_num; i++) {
-               priv->port_stats.lro_aggregated += priv->rx_ring[i].lro.stats.aggregated;
-               priv->port_stats.lro_flushed += priv->rx_ring[i].lro.stats.flushed;
-               priv->port_stats.lro_no_desc += priv->rx_ring[i].lro.stats.no_desc;
-       }
-}
-
-static void
-mlx4_en_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo)
-{
-       struct mlx4_en_priv *priv = netdev_priv(dev);
-       struct mlx4_en_dev *mdev = priv->mdev;
-
-       sprintf(drvinfo->driver, DRV_NAME " (%s)", mdev->dev->board_id);
-       strncpy(drvinfo->version, DRV_VERSION " (" DRV_RELDATE ")", 32);
-       sprintf(drvinfo->fw_version, "%d.%d.%d",
-               (u16) (mdev->dev->caps.fw_ver >> 32),
-               (u16) ((mdev->dev->caps.fw_ver >> 16) & 0xffff),
-               (u16) (mdev->dev->caps.fw_ver & 0xffff));
-       strncpy(drvinfo->bus_info, pci_name(mdev->dev->pdev), 32);
-       drvinfo->n_stats = 0;
-       drvinfo->regdump_len = 0;
-       drvinfo->eedump_len = 0;
-}
-
-static u32 mlx4_en_get_tso(struct net_device *dev)
-{
-       return (dev->features & NETIF_F_TSO) != 0;
-}
-
-static int mlx4_en_set_tso(struct net_device *dev, u32 data)
-{
-       struct mlx4_en_priv *priv = netdev_priv(dev);
-
-       if (data) {
-               if (!priv->mdev->LSO_support)
-                       return -EPERM;
-               dev->features |= (NETIF_F_TSO | NETIF_F_TSO6);
-       } else
-               dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6);
-       return 0;
-}
-
-static u32 mlx4_en_get_rx_csum(struct net_device *dev)
-{
-       struct mlx4_en_priv *priv = netdev_priv(dev);
-       return priv->rx_csum;
-}
-
-static int mlx4_en_set_rx_csum(struct net_device *dev, u32 data)
-{
-       struct mlx4_en_priv *priv = netdev_priv(dev);
-       priv->rx_csum = (data != 0);
-       return 0;
-}
-
-static const char main_strings[][ETH_GSTRING_LEN] = {
-       "rx_packets", "tx_packets", "rx_bytes", "tx_bytes", "rx_errors",
-       "tx_errors", "rx_dropped", "tx_dropped", "multicast", "collisions",
-       "rx_length_errors", "rx_over_errors", "rx_crc_errors",
-       "rx_frame_errors", "rx_fifo_errors", "rx_missed_errors",
-       "tx_aborted_errors", "tx_carrier_errors", "tx_fifo_errors",
-       "tx_heartbeat_errors", "tx_window_errors",
-
-       /* port statistics */
-       "lro_aggregated", "lro_flushed", "lro_no_desc", "tso_packets",
-       "queue_stopped", "wake_queue", "tx_timeout", "rx_alloc_failed",
-       "rx_csum_good", "rx_csum_none", "tx_chksum_offload",
-
-       /* packet statistics */
-       "broadcast", "rx_prio_0", "rx_prio_1", "rx_prio_2", "rx_prio_3",
-       "rx_prio_4", "rx_prio_5", "rx_prio_6", "rx_prio_7", "tx_prio_0",
-       "tx_prio_1", "tx_prio_2", "tx_prio_3", "tx_prio_4", "tx_prio_5",
-       "tx_prio_6", "tx_prio_7",
-};
-#define NUM_MAIN_STATS 21
-#define NUM_ALL_STATS  (NUM_MAIN_STATS + NUM_PORT_STATS + NUM_PKT_STATS + NUM_PERF_STATS)
-
-static u32 mlx4_en_get_msglevel(struct net_device *dev)
-{
-       return ((struct mlx4_en_priv *) netdev_priv(dev))->msg_enable;
-}
-
-static void mlx4_en_set_msglevel(struct net_device *dev, u32 val)
-{
-       ((struct mlx4_en_priv *) netdev_priv(dev))->msg_enable = val;
-}
-
-static void mlx4_en_get_wol(struct net_device *netdev,
-                           struct ethtool_wolinfo *wol)
-{
-       wol->supported = 0;
-       wol->wolopts = 0;
-
-       return;
-}
-
-static int mlx4_en_get_sset_count(struct net_device *dev, int sset)
-{
-       struct mlx4_en_priv *priv = netdev_priv(dev);
-
-       if (sset != ETH_SS_STATS)
-               return -EOPNOTSUPP;
-
-       return NUM_ALL_STATS + (priv->tx_ring_num + priv->rx_ring_num) * 2;
-}
-
-static void mlx4_en_get_ethtool_stats(struct net_device *dev,
-               struct ethtool_stats *stats, uint64_t *data)
-{
-       struct mlx4_en_priv *priv = netdev_priv(dev);
-       int index = 0;
-       int i;
-
-       spin_lock_bh(&priv->stats_lock);
-
-       mlx4_en_update_lro_stats(priv);
-
-       for (i = 0; i < NUM_MAIN_STATS; i++)
-               data[index++] = ((unsigned long *) &priv->stats)[i];
-       for (i = 0; i < NUM_PORT_STATS; i++)
-               data[index++] = ((unsigned long *) &priv->port_stats)[i];
-       for (i = 0; i < priv->tx_ring_num; i++) {
-               data[index++] = priv->tx_ring[i].packets;
-               data[index++] = priv->tx_ring[i].bytes;
-       }
-       for (i = 0; i < priv->rx_ring_num; i++) {
-               data[index++] = priv->rx_ring[i].packets;
-               data[index++] = priv->rx_ring[i].bytes;
-       }
-       for (i = 0; i < NUM_PKT_STATS; i++)
-               data[index++] = ((unsigned long *) &priv->pkstats)[i];
-       spin_unlock_bh(&priv->stats_lock);
-
-}
-
-static void mlx4_en_get_strings(struct net_device *dev,
-                               uint32_t stringset, uint8_t *data)
-{
-       struct mlx4_en_priv *priv = netdev_priv(dev);
-       int index = 0;
-       int i;
-
-       if (stringset != ETH_SS_STATS)
-               return;
-
-       /* Add main counters */
-       for (i = 0; i < NUM_MAIN_STATS; i++)
-               strcpy(data + (index++) * ETH_GSTRING_LEN, main_strings[i]);
-       for (i = 0; i < NUM_PORT_STATS; i++)
-               strcpy(data + (index++) * ETH_GSTRING_LEN,
-                       main_strings[i + NUM_MAIN_STATS]);
-       for (i = 0; i < priv->tx_ring_num; i++) {
-               sprintf(data + (index++) * ETH_GSTRING_LEN,
-                       "tx%d_packets", i);
-               sprintf(data + (index++) * ETH_GSTRING_LEN,
-                       "tx%d_bytes", i);
-       }
-       for (i = 0; i < priv->rx_ring_num; i++) {
-               sprintf(data + (index++) * ETH_GSTRING_LEN,
-                       "rx%d_packets", i);
-               sprintf(data + (index++) * ETH_GSTRING_LEN,
-                       "rx%d_bytes", i);
-       }
-       for (i = 0; i < NUM_PKT_STATS; i++)
-               strcpy(data + (index++) * ETH_GSTRING_LEN,
-                       main_strings[i + NUM_MAIN_STATS + NUM_PORT_STATS]);
-}
-
-static int mlx4_en_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
-{
-       cmd->autoneg = AUTONEG_DISABLE;
-       cmd->supported = SUPPORTED_10000baseT_Full;
-       cmd->advertising = SUPPORTED_10000baseT_Full;
-       if (netif_carrier_ok(dev)) {
-               cmd->speed = SPEED_10000;
-               cmd->duplex = DUPLEX_FULL;
-       } else {
-               cmd->speed = -1;
-               cmd->duplex = -1;
-       }
-       return 0;
-}
-
-static int mlx4_en_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
-{
-       if ((cmd->autoneg == AUTONEG_ENABLE) ||
-           (cmd->speed != SPEED_10000) || (cmd->duplex != DUPLEX_FULL))
-               return -EINVAL;
-
-       /* Nothing to change */
-       return 0;
-}
-
-static int mlx4_en_get_coalesce(struct net_device *dev,
-                             struct ethtool_coalesce *coal)
-{
-       struct mlx4_en_priv *priv = netdev_priv(dev);
-
-       coal->tx_coalesce_usecs = 0;
-       coal->tx_max_coalesced_frames = 0;
-       coal->rx_coalesce_usecs = priv->rx_usecs;
-       coal->rx_max_coalesced_frames = priv->rx_frames;
-
-       coal->pkt_rate_low = priv->pkt_rate_low;
-       coal->rx_coalesce_usecs_low = priv->rx_usecs_low;
-       coal->pkt_rate_high = priv->pkt_rate_high;
-       coal->rx_coalesce_usecs_high = priv->rx_usecs_high;
-       coal->rate_sample_interval = priv->sample_interval;
-       coal->use_adaptive_rx_coalesce = priv->adaptive_rx_coal;
-       return 0;
-}
-
-static int mlx4_en_set_coalesce(struct net_device *dev,
-                             struct ethtool_coalesce *coal)
-{
-       struct mlx4_en_priv *priv = netdev_priv(dev);
-       int err, i;
-
-       priv->rx_frames = (coal->rx_max_coalesced_frames ==
-                          MLX4_EN_AUTO_CONF) ?
-                               MLX4_EN_RX_COAL_TARGET /
-                               priv->dev->mtu + 1 :
-                               coal->rx_max_coalesced_frames;
-       priv->rx_usecs = (coal->rx_coalesce_usecs ==
-                         MLX4_EN_AUTO_CONF) ?
-                               MLX4_EN_RX_COAL_TIME :
-                               coal->rx_coalesce_usecs;
-
-       /* Set adaptive coalescing params */
-       priv->pkt_rate_low = coal->pkt_rate_low;
-       priv->rx_usecs_low = coal->rx_coalesce_usecs_low;
-       priv->pkt_rate_high = coal->pkt_rate_high;
-       priv->rx_usecs_high = coal->rx_coalesce_usecs_high;
-       priv->sample_interval = coal->rate_sample_interval;
-       priv->adaptive_rx_coal = coal->use_adaptive_rx_coalesce;
-       priv->last_moder_time = MLX4_EN_AUTO_CONF;
-       if (priv->adaptive_rx_coal)
-               return 0;
-
-       for (i = 0; i < priv->rx_ring_num; i++) {
-               priv->rx_cq[i].moder_cnt = priv->rx_frames;
-               priv->rx_cq[i].moder_time = priv->rx_usecs;
-               err = mlx4_en_set_cq_moder(priv, &priv->rx_cq[i]);
-               if (err)
-                       return err;
-       }
-       return 0;
-}
-
-static int mlx4_en_set_pauseparam(struct net_device *dev,
-                               struct ethtool_pauseparam *pause)
-{
-       struct mlx4_en_priv *priv = netdev_priv(dev);
-       struct mlx4_en_dev *mdev = priv->mdev;
-       int err;
-
-       priv->prof->tx_pause = pause->tx_pause != 0;
-       priv->prof->rx_pause = pause->rx_pause != 0;
-       err = mlx4_SET_PORT_general(mdev->dev, priv->port,
-                                   priv->rx_skb_size + ETH_FCS_LEN,
-                                   priv->prof->tx_pause,
-                                   priv->prof->tx_ppp,
-                                   priv->prof->rx_pause,
-                                   priv->prof->rx_ppp);
-       if (err)
-               mlx4_err(mdev, "Failed setting pause params to\n");
-
-       return err;
-}
-
-static void mlx4_en_get_pauseparam(struct net_device *dev,
-                                struct ethtool_pauseparam *pause)
-{
-       struct mlx4_en_priv *priv = netdev_priv(dev);
-
-       pause->tx_pause = priv->prof->tx_pause;
-       pause->rx_pause = priv->prof->rx_pause;
-}
-
-static int mlx4_en_set_ringparam(struct net_device *dev,
-                                struct ethtool_ringparam *param)
-{
-       struct mlx4_en_priv *priv = netdev_priv(dev);
-       struct mlx4_en_dev *mdev = priv->mdev;
-       u32 rx_size, tx_size;
-       int port_up = 0;
-       int err = 0;
-
-       if (param->rx_jumbo_pending || param->rx_mini_pending)
-               return -EINVAL;
-
-       rx_size = roundup_pow_of_two(param->rx_pending);
-       rx_size = max_t(u32, rx_size, MLX4_EN_MIN_RX_SIZE);
-       rx_size = min_t(u32, rx_size, MLX4_EN_MAX_RX_SIZE);
-       tx_size = roundup_pow_of_two(param->tx_pending);
-       tx_size = max_t(u32, tx_size, MLX4_EN_MIN_TX_SIZE);
-       tx_size = min_t(u32, tx_size, MLX4_EN_MAX_TX_SIZE);
-
-       if (rx_size == priv->prof->rx_ring_size &&
-           tx_size == priv->prof->tx_ring_size)
-               return 0;
-
-       mutex_lock(&mdev->state_lock);
-       if (priv->port_up) {
-               port_up = 1;
-               mlx4_en_stop_port(dev);
-       }
-
-       mlx4_en_free_resources(priv);
-
-       priv->prof->tx_ring_size = tx_size;
-       priv->prof->rx_ring_size = rx_size;
-
-       err = mlx4_en_alloc_resources(priv);
-       if (err) {
-               mlx4_err(mdev, "Failed reallocating port resources\n");
-               goto out;
-       }
-       if (port_up) {
-               err = mlx4_en_start_port(dev);
-               if (err)
-                       mlx4_err(mdev, "Failed starting port\n");
-       }
-
-out:
-       mutex_unlock(&mdev->state_lock);
-       return err;
-}
-
-static void mlx4_en_get_ringparam(struct net_device *dev,
-                                 struct ethtool_ringparam *param)
-{
-       struct mlx4_en_priv *priv = netdev_priv(dev);
-       struct mlx4_en_dev *mdev = priv->mdev;
-
-       memset(param, 0, sizeof(*param));
-       param->rx_max_pending = MLX4_EN_MAX_RX_SIZE;
-       param->tx_max_pending = MLX4_EN_MAX_TX_SIZE;
-       param->rx_pending = mdev->profile.prof[priv->port].rx_ring_size;
-       param->tx_pending = mdev->profile.prof[priv->port].tx_ring_size;
-}
-
-const struct ethtool_ops mlx4_en_ethtool_ops = {
-       .get_drvinfo = mlx4_en_get_drvinfo,
-       .get_settings = mlx4_en_get_settings,
-       .set_settings = mlx4_en_set_settings,
-#ifdef NETIF_F_TSO
-       .get_tso = mlx4_en_get_tso,
-       .set_tso = mlx4_en_set_tso,
-#endif
-       .get_sg = ethtool_op_get_sg,
-       .set_sg = ethtool_op_set_sg,
-       .get_link = ethtool_op_get_link,
-       .get_rx_csum = mlx4_en_get_rx_csum,
-       .set_rx_csum = mlx4_en_set_rx_csum,
-       .get_tx_csum = ethtool_op_get_tx_csum,
-       .set_tx_csum = ethtool_op_set_tx_ipv6_csum,
-       .get_strings = mlx4_en_get_strings,
-       .get_sset_count = mlx4_en_get_sset_count,
-       .get_ethtool_stats = mlx4_en_get_ethtool_stats,
-       .get_wol = mlx4_en_get_wol,
-       .get_msglevel = mlx4_en_get_msglevel,
-       .set_msglevel = mlx4_en_set_msglevel,
-       .get_coalesce = mlx4_en_get_coalesce,
-       .set_coalesce = mlx4_en_set_coalesce,
-       .get_pauseparam = mlx4_en_get_pauseparam,
-       .set_pauseparam = mlx4_en_set_pauseparam,
-       .get_ringparam = mlx4_en_get_ringparam,
-       .set_ringparam = mlx4_en_set_ringparam,
-       .get_flags = ethtool_op_get_flags,
-       .set_flags = ethtool_op_set_flags,
-};
-
-
-
-
-
index 9ee873e872b34a2c02db98ab59e3b5c3f2616b13..5a14899c1e255d7e9cc802f46f57eb7619f68c56 100644 (file)
@@ -114,8 +114,8 @@ static int mlx4_en_init_allocator(struct mlx4_en_priv *priv,
                        goto out;
 
                page_alloc->offset = priv->frag_info[i].frag_align;
-               mlx4_dbg(DRV, priv, "Initialized allocator:%d with page:%p\n",
-                        i, page_alloc->page);
+               en_dbg(DRV, priv, "Initialized allocator:%d with page:%p\n",
+                      i, page_alloc->page);
        }
        return 0;
 
@@ -136,8 +136,8 @@ static void mlx4_en_destroy_allocator(struct mlx4_en_priv *priv,
 
        for (i = 0; i < priv->num_frags; i++) {
                page_alloc = &ring->page_alloc[i];
-               mlx4_dbg(DRV, priv, "Freeing allocator:%d count:%d\n",
-                        i, page_count(page_alloc->page));
+               en_dbg(DRV, priv, "Freeing allocator:%d count:%d\n",
+                      i, page_count(page_alloc->page));
 
                put_page(page_alloc->page);
                page_alloc->page = NULL;
@@ -202,12 +202,34 @@ static inline void mlx4_en_update_rx_prod_db(struct mlx4_en_rx_ring *ring)
        *ring->wqres.db.db = cpu_to_be32(ring->prod & 0xffff);
 }
 
-static int mlx4_en_fill_rx_buffers(struct mlx4_en_priv *priv)
+static void mlx4_en_free_rx_desc(struct mlx4_en_priv *priv,
+                                struct mlx4_en_rx_ring *ring,
+                                int index)
 {
        struct mlx4_en_dev *mdev = priv->mdev;
+       struct skb_frag_struct *skb_frags;
+       struct mlx4_en_rx_desc *rx_desc = ring->buf + (index << ring->log_stride);
+       dma_addr_t dma;
+       int nr;
+
+       skb_frags = ring->rx_info + (index << priv->log_rx_info);
+       for (nr = 0; nr < priv->num_frags; nr++) {
+               en_dbg(DRV, priv, "Freeing fragment:%d\n", nr);
+               dma = be64_to_cpu(rx_desc->data[nr].addr);
+
+               en_dbg(DRV, priv, "Unmaping buffer at dma:0x%llx\n", (u64) dma);
+               pci_unmap_single(mdev->pdev, dma, skb_frags[nr].size,
+                                PCI_DMA_FROMDEVICE);
+               put_page(skb_frags[nr].page);
+       }
+}
+
+static int mlx4_en_fill_rx_buffers(struct mlx4_en_priv *priv)
+{
        struct mlx4_en_rx_ring *ring;
        int ring_ind;
        int buf_ind;
+       int new_size;
 
        for (buf_ind = 0; buf_ind < priv->prof->rx_ring_size; buf_ind++) {
                for (ring_ind = 0; ring_ind < priv->rx_ring_num; ring_ind++) {
@@ -216,22 +238,34 @@ static int mlx4_en_fill_rx_buffers(struct mlx4_en_priv *priv)
                        if (mlx4_en_prepare_rx_desc(priv, ring,
                                                    ring->actual_size)) {
                                if (ring->actual_size < MLX4_EN_MIN_RX_SIZE) {
-                                       mlx4_err(mdev, "Failed to allocate "
-                                                      "enough rx buffers\n");
+                                       en_err(priv, "Failed to allocate "
+                                                    "enough rx buffers\n");
                                        return -ENOMEM;
                                } else {
-                                       if (netif_msg_rx_err(priv))
-                                               mlx4_warn(mdev,
-                                                         "Only %d buffers allocated\n",
-                                                         ring->actual_size);
-                                       goto out;
+                                       new_size = rounddown_pow_of_two(ring->actual_size);
+                                       en_warn(priv, "Only %d buffers allocated "
+                                                     "reducing ring size to %d",
+                                               ring->actual_size, new_size);
+                                       goto reduce_rings;
                                }
                        }
                        ring->actual_size++;
                        ring->prod++;
                }
        }
-out:
+       return 0;
+
+reduce_rings:
+       for (ring_ind = 0; ring_ind < priv->rx_ring_num; ring_ind++) {
+               ring = &priv->rx_ring[ring_ind];
+               while (ring->actual_size > new_size) {
+                       ring->actual_size--;
+                       ring->prod--;
+                       mlx4_en_free_rx_desc(priv, ring, ring->actual_size);
+               }
+               ring->size_mask = ring->actual_size - 1;
+       }
+
        return 0;
 }
 
@@ -247,15 +281,14 @@ static int mlx4_en_fill_rx_buf(struct net_device *dev,
                                              ring->size_mask);
                if (err) {
                        if (netif_msg_rx_err(priv))
-                               mlx4_warn(priv->mdev,
-                                         "Failed preparing rx descriptor\n");
+                               en_warn(priv, "Failed preparing rx descriptor\n");
                        priv->port_stats.rx_alloc_failed++;
                        break;
                }
                ++num;
                ++ring->prod;
        }
-       if ((u32) (ring->prod - ring->cons) == ring->size)
+       if ((u32) (ring->prod - ring->cons) == ring->actual_size)
                ring->full = 1;
 
        return num;
@@ -264,33 +297,17 @@ static int mlx4_en_fill_rx_buf(struct net_device *dev,
 static void mlx4_en_free_rx_buf(struct mlx4_en_priv *priv,
                                struct mlx4_en_rx_ring *ring)
 {
-       struct mlx4_en_dev *mdev = priv->mdev;
-       struct skb_frag_struct *skb_frags;
-       struct mlx4_en_rx_desc *rx_desc;
-       dma_addr_t dma;
        int index;
-       int nr;
 
-       mlx4_dbg(DRV, priv, "Freeing Rx buf - cons:%d prod:%d\n",
-                       ring->cons, ring->prod);
+       en_dbg(DRV, priv, "Freeing Rx buf - cons:%d prod:%d\n",
+              ring->cons, ring->prod);
 
        /* Unmap and free Rx buffers */
-       BUG_ON((u32) (ring->prod - ring->cons) > ring->size);
+       BUG_ON((u32) (ring->prod - ring->cons) > ring->actual_size);
        while (ring->cons != ring->prod) {
                index = ring->cons & ring->size_mask;
-               rx_desc = ring->buf + (index << ring->log_stride);
-               skb_frags = ring->rx_info + (index << priv->log_rx_info);
-               mlx4_dbg(DRV, priv, "Processing descriptor:%d\n", index);
-
-               for (nr = 0; nr < priv->num_frags; nr++) {
-                       mlx4_dbg(DRV, priv, "Freeing fragment:%d\n", nr);
-                       dma = be64_to_cpu(rx_desc->data[nr].addr);
-
-                       mlx4_dbg(DRV, priv, "Unmaping buffer at dma:0x%llx\n", (u64) dma);
-                       pci_unmap_single(mdev->pdev, dma, skb_frags[nr].size,
-                                        PCI_DMA_FROMDEVICE);
-                       put_page(skb_frags[nr].page);
-               }
+               en_dbg(DRV, priv, "Processing descriptor:%d\n", index);
+               mlx4_en_free_rx_desc(priv, ring, index);
                ++ring->cons;
        }
 }
@@ -354,10 +371,10 @@ int mlx4_en_create_rx_ring(struct mlx4_en_priv *priv,
                                        sizeof(struct skb_frag_struct));
        ring->rx_info = vmalloc(tmp);
        if (!ring->rx_info) {
-               mlx4_err(mdev, "Failed allocating rx_info ring\n");
+               en_err(priv, "Failed allocating rx_info ring\n");
                return -ENOMEM;
        }
-       mlx4_dbg(DRV, priv, "Allocated rx_info ring at addr:%p size:%d\n",
+       en_dbg(DRV, priv, "Allocated rx_info ring at addr:%p size:%d\n",
                 ring->rx_info, tmp);
 
        err = mlx4_alloc_hwq_res(mdev->dev, &ring->wqres,
@@ -367,7 +384,7 @@ int mlx4_en_create_rx_ring(struct mlx4_en_priv *priv,
 
        err = mlx4_en_map_buffer(&ring->wqres.buf);
        if (err) {
-               mlx4_err(mdev, "Failed to map RX buffer\n");
+               en_err(priv, "Failed to map RX buffer\n");
                goto err_hwq;
        }
        ring->buf = ring->wqres.buf.direct.buf;
@@ -385,7 +402,7 @@ int mlx4_en_create_rx_ring(struct mlx4_en_priv *priv,
                                    sizeof(struct net_lro_desc),
                                    GFP_KERNEL);
        if (!ring->lro.lro_arr) {
-               mlx4_err(mdev, "Failed to allocate lro array\n");
+               en_err(priv, "Failed to allocate lro array\n");
                goto err_map;
        }
        ring->lro.get_frag_header = mlx4_en_get_frag_header;
@@ -436,7 +453,7 @@ int mlx4_en_activate_rx_rings(struct mlx4_en_priv *priv)
                /* Initialize page allocators */
                err = mlx4_en_init_allocator(priv, ring);
                if (err) {
-                       mlx4_err(mdev, "Failed initializing ring allocator\n");
+                       en_err(priv, "Failed initializing ring allocator\n");
                        ring_ind--;
                        goto err_allocator;
                }
@@ -454,7 +471,7 @@ int mlx4_en_activate_rx_rings(struct mlx4_en_priv *priv)
                mlx4_en_update_rx_prod_db(ring);
 
                /* Configure SRQ representing the ring */
-               ring->srq.max    = ring->size;
+               ring->srq.max    = ring->actual_size;
                ring->srq.max_gs = max_gs;
                ring->srq.wqe_shift = ilog2(ring->stride);
 
@@ -467,7 +484,7 @@ int mlx4_en_activate_rx_rings(struct mlx4_en_priv *priv)
                err = mlx4_srq_alloc(mdev->dev, mdev->priv_pdn, &ring->wqres.mtt,
                                     ring->wqres.db.dma, &ring->srq);
                if (err){
-                       mlx4_err(mdev, "Failed to allocate srq\n");
+                       en_err(priv, "Failed to allocate srq\n");
                        ring_ind--;
                        goto err_srq;
                }
@@ -582,7 +599,7 @@ static struct sk_buff *mlx4_en_rx_skb(struct mlx4_en_priv *priv,
 
        skb = dev_alloc_skb(SMALL_PACKET_SIZE + NET_IP_ALIGN);
        if (!skb) {
-               mlx4_dbg(RX_ERR, priv, "Failed allocating skb\n");
+               en_dbg(RX_ERR, priv, "Failed allocating skb\n");
                return NULL;
        }
        skb->dev = priv->dev;
@@ -661,7 +678,6 @@ static void mlx4_en_copy_desc(struct mlx4_en_priv *priv,
 int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int budget)
 {
        struct mlx4_en_priv *priv = netdev_priv(dev);
-       struct mlx4_en_dev *mdev = priv->mdev;
        struct mlx4_cqe *cqe;
        struct mlx4_en_rx_ring *ring = &priv->rx_ring[cq->ring];
        struct skb_frag_struct *skb_frags;
@@ -698,14 +714,14 @@ int mlx4_en_process_rx_cq(struct net_device *dev, struct mlx4_en_cq *cq, int bud
                /* Drop packet on bad receive or bad checksum */
                if (unlikely((cqe->owner_sr_opcode & MLX4_CQE_OPCODE_MASK) ==
                                                MLX4_CQE_OPCODE_ERROR)) {
-                       mlx4_err(mdev, "CQE completed in error - vendor "
+                       en_err(priv, "CQE completed in error - vendor "
                                  "syndrom:%d syndrom:%d\n",
                                  ((struct mlx4_err_cqe *) cqe)->vendor_err_syndrome,
                                  ((struct mlx4_err_cqe *) cqe)->syndrome);
                        goto next;
                }
                if (unlikely(cqe->badfcs_enc & MLX4_CQE_BAD_FCS)) {
-                       mlx4_dbg(RX_ERR, priv, "Accepted frame with bad FCS\n");
+                       en_dbg(RX_ERR, priv, "Accepted frame with bad FCS\n");
                        goto next;
                }
 
@@ -855,7 +871,7 @@ static int mlx4_en_last_alloc_offset(struct mlx4_en_priv *priv, u16 stride, u16
        u16 res = MLX4_EN_ALLOC_SIZE % stride;
        u16 offset = MLX4_EN_ALLOC_SIZE - stride - res + align;
 
-       mlx4_dbg(DRV, priv, "Calculated last offset for stride:%d align:%d "
+       en_dbg(DRV, priv, "Calculated last offset for stride:%d align:%d "
                            "res:%d offset:%d\n", stride, align, res, offset);
        return offset;
 }
@@ -900,10 +916,10 @@ void mlx4_en_calc_rx_buf(struct net_device *dev)
        priv->rx_skb_size = eff_mtu;
        priv->log_rx_info = ROUNDUP_LOG2(i * sizeof(struct skb_frag_struct));
 
-       mlx4_dbg(DRV, priv, "Rx buffer scatter-list (effective-mtu:%d "
+       en_dbg(DRV, priv, "Rx buffer scatter-list (effective-mtu:%d "
                  "num_frags:%d):\n", eff_mtu, priv->num_frags);
        for (i = 0; i < priv->num_frags; i++) {
-               mlx4_dbg(DRV, priv, "  frag:%d - size:%d prefix:%d align:%d "
+               en_dbg(DRV, priv, "  frag:%d - size:%d prefix:%d align:%d "
                                "stride:%d last_offset:%d\n", i,
                                priv->frag_info[i].frag_size,
                                priv->frag_info[i].frag_prefix_size,
@@ -923,12 +939,12 @@ void mlx4_en_set_default_rss_map(struct mlx4_en_priv *priv,
        int i;
 
        rss_map->size = roundup_pow_of_two(num_entries);
-       mlx4_dbg(DRV, priv, "Setting default RSS map of %d entires\n",
-                rss_map->size);
+       en_dbg(DRV, priv, "Setting default RSS map of %d entires\n",
+              rss_map->size);
 
        for (i = 0; i < rss_map->size; i++) {
                rss_map->map[i] = i % num_rings;
-               mlx4_dbg(DRV, priv, "Entry %d ---> ring %d\n", i, rss_map->map[i]);
+               en_dbg(DRV, priv, "Entry %d ---> ring %d\n", i, rss_map->map[i]);
        }
 }
 
@@ -943,13 +959,13 @@ static int mlx4_en_config_rss_qp(struct mlx4_en_priv *priv,
 
        context = kmalloc(sizeof *context , GFP_KERNEL);
        if (!context) {
-               mlx4_err(mdev, "Failed to allocate qp context\n");
+               en_err(priv, "Failed to allocate qp context\n");
                return -ENOMEM;
        }
 
        err = mlx4_qp_alloc(mdev->dev, qpn, qp);
        if (err) {
-               mlx4_err(mdev, "Failed to allocate qp #%d\n", qpn);
+               en_err(priv, "Failed to allocate qp #%x\n", qpn);
                goto out;
        }
        qp->event = mlx4_en_sqp_event;
@@ -981,12 +997,11 @@ int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv)
        int err = 0;
        int good_qps = 0;
 
-       mlx4_dbg(DRV, priv, "Configuring rss steering for port %u\n", priv->port);
+       en_dbg(DRV, priv, "Configuring rss steering\n");
        err = mlx4_qp_reserve_range(mdev->dev, rss_map->size,
                                    rss_map->size, &rss_map->base_qpn);
        if (err) {
-               mlx4_err(mdev, "Failed reserving %d qps for port %u\n",
-                        rss_map->size, priv->port);
+               en_err(priv, "Failed reserving %d qps\n", rss_map->size);
                return err;
        }
 
@@ -1006,13 +1021,13 @@ int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv)
        /* Configure RSS indirection qp */
        err = mlx4_qp_reserve_range(mdev->dev, 1, 1, &priv->base_qpn);
        if (err) {
-               mlx4_err(mdev, "Failed to reserve range for RSS "
-                              "indirection qp\n");
+               en_err(priv, "Failed to reserve range for RSS "
+                            "indirection qp\n");
                goto rss_err;
        }
        err = mlx4_qp_alloc(mdev->dev, priv->base_qpn, &rss_map->indir_qp);
        if (err) {
-               mlx4_err(mdev, "Failed to allocate RSS indirection QP\n");
+               en_err(priv, "Failed to allocate RSS indirection QP\n");
                goto reserve_err;
        }
        rss_map->indir_qp.event = mlx4_en_sqp_event;
index e5c98a98ad3788c2c273c645bad8ccee545a1679..5dc7466ad035e9eb9607b514d674349e2fc89f5f 100644 (file)
@@ -68,15 +68,15 @@ int mlx4_en_create_tx_ring(struct mlx4_en_priv *priv,
        tmp = size * sizeof(struct mlx4_en_tx_info);
        ring->tx_info = vmalloc(tmp);
        if (!ring->tx_info) {
-               mlx4_err(mdev, "Failed allocating tx_info ring\n");
+               en_err(priv, "Failed allocating tx_info ring\n");
                return -ENOMEM;
        }
-       mlx4_dbg(DRV, priv, "Allocated tx_info ring at addr:%p size:%d\n",
+       en_dbg(DRV, priv, "Allocated tx_info ring at addr:%p size:%d\n",
                 ring->tx_info, tmp);
 
        ring->bounce_buf = kmalloc(MAX_DESC_SIZE, GFP_KERNEL);
        if (!ring->bounce_buf) {
-               mlx4_err(mdev, "Failed allocating bounce buffer\n");
+               en_err(priv, "Failed allocating bounce buffer\n");
                err = -ENOMEM;
                goto err_tx;
        }
@@ -85,31 +85,31 @@ int mlx4_en_create_tx_ring(struct mlx4_en_priv *priv,
        err = mlx4_alloc_hwq_res(mdev->dev, &ring->wqres, ring->buf_size,
                                 2 * PAGE_SIZE);
        if (err) {
-               mlx4_err(mdev, "Failed allocating hwq resources\n");
+               en_err(priv, "Failed allocating hwq resources\n");
                goto err_bounce;
        }
 
        err = mlx4_en_map_buffer(&ring->wqres.buf);
        if (err) {
-               mlx4_err(mdev, "Failed to map TX buffer\n");
+               en_err(priv, "Failed to map TX buffer\n");
                goto err_hwq_res;
        }
 
        ring->buf = ring->wqres.buf.direct.buf;
 
-       mlx4_dbg(DRV, priv, "Allocated TX ring (addr:%p) - buf:%p size:%d "
-                "buf_size:%d dma:%llx\n", ring, ring->buf, ring->size,
-                ring->buf_size, (unsigned long long) ring->wqres.buf.direct.map);
+       en_dbg(DRV, priv, "Allocated TX ring (addr:%p) - buf:%p size:%d "
+              "buf_size:%d dma:%llx\n", ring, ring->buf, ring->size,
+              ring->buf_size, (unsigned long long) ring->wqres.buf.direct.map);
 
        err = mlx4_qp_reserve_range(mdev->dev, 1, 1, &ring->qpn);
        if (err) {
-               mlx4_err(mdev, "Failed reserving qp for tx ring.\n");
+               en_err(priv, "Failed reserving qp for tx ring.\n");
                goto err_map;
        }
 
        err = mlx4_qp_alloc(mdev->dev, ring->qpn, &ring->qp);
        if (err) {
-               mlx4_err(mdev, "Failed allocating qp %d\n", ring->qpn);
+               en_err(priv, "Failed allocating qp %d\n", ring->qpn);
                goto err_reserve;
        }
        ring->qp.event = mlx4_en_sqp_event;
@@ -135,7 +135,7 @@ void mlx4_en_destroy_tx_ring(struct mlx4_en_priv *priv,
                             struct mlx4_en_tx_ring *ring)
 {
        struct mlx4_en_dev *mdev = priv->mdev;
-       mlx4_dbg(DRV, priv, "Destroying tx ring, qpn: %d\n", ring->qpn);
+       en_dbg(DRV, priv, "Destroying tx ring, qpn: %d\n", ring->qpn);
 
        mlx4_qp_remove(mdev->dev, &ring->qp);
        mlx4_qp_free(mdev->dev, &ring->qp);
@@ -274,12 +274,12 @@ int mlx4_en_free_tx_buf(struct net_device *dev, struct mlx4_en_tx_ring *ring)
 
        /* Skip last polled descriptor */
        ring->cons += ring->last_nr_txbb;
-       mlx4_dbg(DRV, priv, "Freeing Tx buf - cons:0x%x prod:0x%x\n",
+       en_dbg(DRV, priv, "Freeing Tx buf - cons:0x%x prod:0x%x\n",
                 ring->cons, ring->prod);
 
        if ((u32) (ring->prod - ring->cons) > ring->size) {
                if (netif_msg_tx_err(priv))
-                       mlx4_warn(priv->mdev, "Tx consumer passed producer!\n");
+                       en_warn(priv, "Tx consumer passed producer!\n");
                return 0;
        }
 
@@ -292,39 +292,11 @@ int mlx4_en_free_tx_buf(struct net_device *dev, struct mlx4_en_tx_ring *ring)
        }
 
        if (cnt)
-               mlx4_dbg(DRV, priv, "Freed %d uncompleted tx descriptors\n", cnt);
+               en_dbg(DRV, priv, "Freed %d uncompleted tx descriptors\n", cnt);
 
        return cnt;
 }
 
-void mlx4_en_set_prio_map(struct mlx4_en_priv *priv, u16 *prio_map, u32 ring_num)
-{
-       int block = 8 / ring_num;
-       int extra = 8 - (block * ring_num);
-       int num = 0;
-       u16 ring = 1;
-       int prio;
-
-       if (ring_num == 1) {
-               for (prio = 0; prio < 8; prio++)
-                       prio_map[prio] = 0;
-               return;
-       }
-
-       for (prio = 0; prio < 8; prio++) {
-               if (extra && (num == block + 1)) {
-                       ring++;
-                       num = 0;
-                       extra--;
-               } else if (!extra && (num == block)) {
-                       ring++;
-                       num = 0;
-               }
-               prio_map[prio] = ring;
-               mlx4_dbg(DRV, priv, " prio:%d --> ring:%d\n", prio, ring);
-               num++;
-       }
-}
 
 static void mlx4_en_process_tx_cq(struct net_device *dev, struct mlx4_en_cq *cq)
 {
@@ -386,18 +358,8 @@ static void mlx4_en_process_tx_cq(struct net_device *dev, struct mlx4_en_cq *cq)
        if (unlikely(ring->blocked)) {
                if ((u32) (ring->prod - ring->cons) <=
                     ring->size - HEADROOM - MAX_DESC_TXBBS) {
-
-                       /* TODO: support multiqueue netdevs. Currently, we block
-                        * when *any* ring is full. Note that:
-                        * - 2 Tx rings can unblock at the same time and call
-                        *   netif_wake_queue(), which is OK since this
-                        *   operation is idempotent.
-                        * - We might wake the queue just after another ring
-                        *   stopped it. This is no big deal because the next
-                        *   transmission on that ring would stop the queue.
-                        */
                        ring->blocked = 0;
-                       netif_wake_queue(dev);
+                       netif_tx_wake_queue(netdev_get_tx_queue(dev, cq->ring));
                        priv->port_stats.wake_queue++;
                }
        }
@@ -539,7 +501,6 @@ static int get_real_size(struct sk_buff *skb, struct net_device *dev,
                         int *lso_header_size)
 {
        struct mlx4_en_priv *priv = netdev_priv(dev);
-       struct mlx4_en_dev *mdev = priv->mdev;
        int real_size;
 
        if (skb_is_gso(skb)) {
@@ -553,14 +514,14 @@ static int get_real_size(struct sk_buff *skb, struct net_device *dev,
                                real_size += DS_SIZE;
                        else {
                                if (netif_msg_tx_err(priv))
-                                       mlx4_warn(mdev, "Non-linear headers\n");
+                                       en_warn(priv, "Non-linear headers\n");
                                dev_kfree_skb_any(skb);
                                return 0;
                        }
                }
                if (unlikely(*lso_header_size > MAX_LSO_HDR_SIZE)) {
                        if (netif_msg_tx_err(priv))
-                               mlx4_warn(mdev, "LSO header size too big\n");
+                               en_warn(priv, "LSO header size too big\n");
                        dev_kfree_skb_any(skb);
                        return 0;
                }
@@ -617,21 +578,20 @@ static void build_inline_wqe(struct mlx4_en_tx_desc *tx_desc, struct sk_buff *sk
        tx_desc->ctrl.fence_size = (real_size / 16) & 0x3f;
 }
 
-static int get_vlan_info(struct mlx4_en_priv *priv, struct sk_buff *skb,
-                        u16 *vlan_tag)
+u16 mlx4_en_select_queue(struct net_device *dev, struct sk_buff *skb)
 {
-       int tx_ind;
+       struct mlx4_en_priv *priv = netdev_priv(dev);
+       u16 vlan_tag = 0;
 
-       /* Obtain VLAN information if present */
-       if (priv->vlgrp && vlan_tx_tag_present(skb)) {
-               *vlan_tag = vlan_tx_tag_get(skb);
-               /* Set the Tx ring to use according to vlan priority */
-               tx_ind = priv->tx_prio_map[*vlan_tag >> 13];
-       } else {
-               *vlan_tag = 0;
-               tx_ind = 0;
+       /* If we support per priority flow control and the packet contains
+        * a vlan tag, send the packet to the TX ring assigned to that priority
+        */
+       if (priv->prof->rx_ppp && priv->vlgrp && vlan_tx_tag_present(skb)) {
+               vlan_tag = vlan_tx_tag_get(skb);
+               return MLX4_EN_NUM_TX_RINGS + (vlan_tag >> 13);
        }
-       return tx_ind;
+
+       return skb_tx_hash(dev, skb);
 }
 
 int mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
@@ -651,7 +611,7 @@ int mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
        dma_addr_t dma;
        u32 index;
        __be32 op_own;
-       u16 vlan_tag;
+       u16 vlan_tag = 0;
        int i;
        int lso_header_size;
        void *fragptr;
@@ -669,20 +629,21 @@ int mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
        nr_txbb = desc_size / TXBB_SIZE;
        if (unlikely(nr_txbb > MAX_DESC_TXBBS)) {
                if (netif_msg_tx_err(priv))
-                       mlx4_warn(mdev, "Oversized header or SG list\n");
+                       en_warn(priv, "Oversized header or SG list\n");
                dev_kfree_skb_any(skb);
                return NETDEV_TX_OK;
        }
 
-       tx_ind = get_vlan_info(priv, skb, &vlan_tag);
+       tx_ind = skb->queue_mapping;
        ring = &priv->tx_ring[tx_ind];
+       if (priv->vlgrp && vlan_tx_tag_present(skb))
+               vlan_tag = vlan_tx_tag_get(skb);
 
        /* Check available TXBBs And 2K spare for prefetch */
        if (unlikely(((int)(ring->prod - ring->cons)) >
                     ring->size - HEADROOM - MAX_DESC_TXBBS)) {
-               /* every full Tx ring stops queue.
-                * TODO: implement multi-queue support (per-queue stop) */
-               netif_stop_queue(dev);
+               /* every full Tx ring stops queue */
+               netif_tx_stop_queue(netdev_get_tx_queue(dev, tx_ind));
                ring->blocked = 1;
                priv->port_stats.queue_stopped++;
 
@@ -695,7 +656,7 @@ int mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
        /* Now that we know what Tx ring to use */
        if (unlikely(!priv->port_up)) {
                if (netif_msg_tx_err(priv))
-                       mlx4_warn(mdev, "xmit: port down!\n");
+                       en_warn(priv, "xmit: port down!\n");
                dev_kfree_skb_any(skb);
                return NETDEV_TX_OK;
        }
@@ -819,7 +780,6 @@ int mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev)
        /* Ring doorbell! */
        wmb();
        writel(ring->doorbell_qpn, mdev->uar_map + MLX4_SEND_DOORBELL);
-       dev->trans_start = jiffies;
 
        /* Poll CQ here */
        mlx4_en_xmit_poll(priv, tx_ind);
index ce064e324200ab58de0836a2f6fc4bcff40e3715..b9ceddde46c0adf5f7e9602235bef02cd534babf 100644 (file)
@@ -625,8 +625,10 @@ int mlx4_init_eq_table(struct mlx4_dev *dev)
                err = mlx4_create_eq(dev, dev->caps.num_cqs + MLX4_NUM_SPARE_EQE,
                                     (dev->flags & MLX4_FLAG_MSI_X) ? i : 0,
                                     &priv->eq_table.eq[i]);
-               if (err)
+               if (err) {
+                       --i;
                        goto err_out_unmap;
+               }
        }
 
        err = mlx4_create_eq(dev, MLX4_NUM_ASYNC_EQE + MLX4_NUM_SPARE_EQE,
index ef840abbcd39a9a2ffc98f2fab865a885381e7c9..d43a9e4c2aeae13ba527022a7ef6f9d15187d568 100644 (file)
 #include "en_port.h"
 
 #define DRV_NAME       "mlx4_en"
-#define DRV_VERSION    "1.4.0"
-#define DRV_RELDATE    "Sep 2008"
+#define DRV_VERSION    "1.4.1.1"
+#define DRV_RELDATE    "June 2009"
 
 
 #define MLX4_EN_MSG_LEVEL      (NETIF_MSG_LINK | NETIF_MSG_IFDOWN)
 
-#define mlx4_dbg(mlevel, priv, format, arg...) \
-       if (NETIF_MSG_##mlevel & priv->msg_enable) \
-       printk(KERN_DEBUG "%s %s: " format , DRV_NAME ,\
-               (dev_name(&priv->mdev->pdev->dev)) , ## arg)
+#define en_print(level, priv, format, arg...)                  \
+       {                                                       \
+       if ((priv)->registered)                                 \
+               printk(level "%s: %s: " format, DRV_NAME,       \
+                       (priv->dev)->name, ## arg);             \
+       else                                                    \
+               printk(level "%s: %s: Port %d: " format,        \
+                       DRV_NAME, dev_name(&priv->mdev->pdev->dev), \
+                       (priv)->port, ## arg);                  \
+       }
+
+#define en_dbg(mlevel, priv, format, arg...)                   \
+       {                                                       \
+       if (NETIF_MSG_##mlevel & priv->msg_enable)              \
+               en_print(KERN_DEBUG, priv, format, ## arg)      \
+       }
+#define en_warn(priv, format, arg...)                          \
+       en_print(KERN_WARNING, priv, format, ## arg)
+#define en_err(priv, format, arg...)                           \
+       en_print(KERN_ERR, priv, format, ## arg)
 
 #define mlx4_err(mdev, format, arg...) \
        printk(KERN_ERR "%s %s: " format , DRV_NAME ,\
-               (dev_name(&mdev->pdev->dev)) , ## arg)
+               dev_name(&mdev->pdev->dev) , ## arg)
 #define mlx4_info(mdev, format, arg...) \
        printk(KERN_INFO "%s %s: " format , DRV_NAME ,\
-               (dev_name(&mdev->pdev->dev)) , ## arg)
+               dev_name(&mdev->pdev->dev) , ## arg)
 #define mlx4_warn(mdev, format, arg...) \
        printk(KERN_WARNING "%s %s: " format , DRV_NAME ,\
-               (dev_name(&mdev->pdev->dev)) , ## arg)
+               dev_name(&mdev->pdev->dev) , ## arg)
 
 /*
  * Device constants
@@ -123,12 +139,14 @@ enum {
 #define MLX4_EN_MIN_RX_SIZE    (MLX4_EN_ALLOC_SIZE / SMP_CACHE_BYTES)
 #define MLX4_EN_MIN_TX_SIZE    (4096 / TXBB_SIZE)
 
-#define MLX4_EN_TX_RING_NUM            9
-#define MLX4_EN_DEF_TX_RING_SIZE       1024
+#define MLX4_EN_SMALL_PKT_SIZE         64
+#define MLX4_EN_NUM_TX_RINGS           8
+#define MLX4_EN_NUM_PPP_RINGS          8
+#define MLX4_EN_DEF_TX_RING_SIZE       512
 #define MLX4_EN_DEF_RX_RING_SIZE       1024
 
-/* Target number of bytes to coalesce with interrupt moderation */
-#define MLX4_EN_RX_COAL_TARGET 0x20000
+/* Target number of packets to coalesce with interrupt moderation */
+#define MLX4_EN_RX_COAL_TARGET 44
 #define MLX4_EN_RX_COAL_TIME   0x10
 
 #define MLX4_EN_TX_COAL_PKTS   5
@@ -462,7 +480,6 @@ struct mlx4_en_priv {
        int base_qpn;
 
        struct mlx4_en_rss_map rss_map;
-       u16 tx_prio_map[8];
        u32 flags;
 #define MLX4_EN_FLAG_PROMISC   0x1
        u32 tx_ring_num;
@@ -500,8 +517,6 @@ void mlx4_en_stop_port(struct net_device *dev);
 void mlx4_en_free_resources(struct mlx4_en_priv *priv);
 int mlx4_en_alloc_resources(struct mlx4_en_priv *priv);
 
-int mlx4_en_get_profile(struct mlx4_en_dev *mdev);
-
 int mlx4_en_create_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq,
                      int entries, int ring, enum cq_type mode);
 void mlx4_en_destroy_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq);
@@ -512,6 +527,7 @@ int mlx4_en_arm_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq);
 
 void mlx4_en_poll_tx_cq(unsigned long data);
 void mlx4_en_tx_irq(struct mlx4_cq *mcq);
+u16 mlx4_en_select_queue(struct net_device *dev, struct sk_buff *skb);
 int mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev);
 
 int mlx4_en_create_tx_ring(struct mlx4_en_priv *priv, struct mlx4_en_tx_ring *ring,
@@ -546,7 +562,6 @@ void mlx4_en_calc_rx_buf(struct net_device *dev);
 void mlx4_en_set_default_rss_map(struct mlx4_en_priv *priv,
                                 struct mlx4_en_rss_map *rss_map,
                                 int num_entries, int num_rings);
-void mlx4_en_set_prio_map(struct mlx4_en_priv *priv, u16 *prio_map, u32 ring_num);
 int mlx4_en_config_rss_steer(struct mlx4_en_priv *priv);
 void mlx4_en_release_rss_steer(struct mlx4_en_priv *priv);
 int mlx4_en_free_tx_buf(struct net_device *dev, struct mlx4_en_tx_ring *ring);
index 3b8973d19933d7bf2b2aa4f418ce13bc1aeca860..5887e4764d220a7019439d98892b21d87039a2d3 100644 (file)
@@ -402,7 +402,8 @@ static int mlx4_write_mtt_chunk(struct mlx4_dev *dev, struct mlx4_mtt *mtt,
        for (i = 0; i < npages; ++i)
                mtts[i] = cpu_to_be64(page_list[i] | MLX4_MTT_FLAG_PRESENT);
 
-       dma_sync_single(&dev->pdev->dev, dma_handle, npages * sizeof (u64), DMA_TO_DEVICE);
+       dma_sync_single_for_cpu(&dev->pdev->dev, dma_handle,
+                               npages * sizeof (u64), DMA_TO_DEVICE);
 
        return 0;
 }
@@ -549,8 +550,8 @@ int mlx4_map_phys_fmr(struct mlx4_dev *dev, struct mlx4_fmr *fmr, u64 *page_list
        for (i = 0; i < npages; ++i)
                fmr->mtts[i] = cpu_to_be64(page_list[i] | MLX4_MTT_FLAG_PRESENT);
 
-       dma_sync_single(&dev->pdev->dev, fmr->dma_handle,
-                       npages * sizeof(u64), DMA_TO_DEVICE);
+       dma_sync_single_for_cpu(&dev->pdev->dev, fmr->dma_handle,
+                               npages * sizeof(u64), DMA_TO_DEVICE);
 
        fmr->mpt->key    = cpu_to_be32(key);
        fmr->mpt->lkey   = cpu_to_be32(key);
index 6bb5af35eda6aa03cd0a672cb30e201d4e8b40a6..b4e18a58cb1bcaf2e4bb0fb379bd7758726c7cd2 100644 (file)
@@ -55,6 +55,7 @@
 #include <linux/types.h>
 #include <linux/inet_lro.h>
 #include <asm/system.h>
+#include <linux/list.h>
 
 static char mv643xx_eth_driver_name[] = "mv643xx_eth";
 static char mv643xx_eth_driver_version[] = "1.4";
@@ -88,7 +89,24 @@ static char mv643xx_eth_driver_version[] = "1.4";
 #define MAC_ADDR_LOW                   0x0014
 #define MAC_ADDR_HIGH                  0x0018
 #define SDMA_CONFIG                    0x001c
+#define  TX_BURST_SIZE_16_64BIT                0x01000000
+#define  TX_BURST_SIZE_4_64BIT         0x00800000
+#define  BLM_TX_NO_SWAP                        0x00000020
+#define  BLM_RX_NO_SWAP                        0x00000010
+#define  RX_BURST_SIZE_16_64BIT                0x00000008
+#define  RX_BURST_SIZE_4_64BIT         0x00000004
 #define PORT_SERIAL_CONTROL            0x003c
+#define  SET_MII_SPEED_TO_100          0x01000000
+#define  SET_GMII_SPEED_TO_1000                0x00800000
+#define  SET_FULL_DUPLEX_MODE          0x00200000
+#define  MAX_RX_PACKET_9700BYTE                0x000a0000
+#define  DISABLE_AUTO_NEG_SPEED_GMII   0x00002000
+#define  DO_NOT_FORCE_LINK_FAIL                0x00000400
+#define  SERIAL_PORT_CONTROL_RESERVED  0x00000200
+#define  DISABLE_AUTO_NEG_FOR_FLOW_CTRL        0x00000008
+#define  DISABLE_AUTO_NEG_FOR_DUPLEX   0x00000004
+#define  FORCE_LINK_PASS               0x00000002
+#define  SERIAL_PORT_ENABLE            0x00000001
 #define PORT_STATUS                    0x0044
 #define  TX_FIFO_EMPTY                 0x00000400
 #define  TX_IN_PROGRESS                        0x00000080
@@ -106,7 +124,9 @@ static char mv643xx_eth_driver_version[] = "1.4";
 #define TX_BW_BURST                    0x005c
 #define INT_CAUSE                      0x0060
 #define  INT_TX_END                    0x07f80000
+#define  INT_TX_END_0                  0x00080000
 #define  INT_RX                                0x000003fc
+#define  INT_RX_0                      0x00000004
 #define  INT_EXT                       0x00000002
 #define INT_CAUSE_EXT                  0x0064
 #define  INT_EXT_LINK_PHY              0x00110000
@@ -135,15 +155,8 @@ static char mv643xx_eth_driver_version[] = "1.4";
 
 
 /*
- * SDMA configuration register.
+ * SDMA configuration register default value.
  */
-#define RX_BURST_SIZE_4_64BIT          (2 << 1)
-#define RX_BURST_SIZE_16_64BIT         (4 << 1)
-#define BLM_RX_NO_SWAP                 (1 << 4)
-#define BLM_TX_NO_SWAP                 (1 << 5)
-#define TX_BURST_SIZE_4_64BIT          (2 << 22)
-#define TX_BURST_SIZE_16_64BIT         (4 << 22)
-
 #if defined(__BIG_ENDIAN)
 #define PORT_SDMA_CONFIG_DEFAULT_VALUE         \
                (RX_BURST_SIZE_4_64BIT  |       \
@@ -160,22 +173,11 @@ static char mv643xx_eth_driver_version[] = "1.4";
 
 
 /*
- * Port serial control register.
+ * Misc definitions.
  */
-#define SET_MII_SPEED_TO_100                   (1 << 24)
-#define SET_GMII_SPEED_TO_1000                 (1 << 23)
-#define SET_FULL_DUPLEX_MODE                   (1 << 21)
-#define MAX_RX_PACKET_9700BYTE                 (5 << 17)
-#define DISABLE_AUTO_NEG_SPEED_GMII            (1 << 13)
-#define DO_NOT_FORCE_LINK_FAIL                 (1 << 10)
-#define SERIAL_PORT_CONTROL_RESERVED           (1 << 9)
-#define DISABLE_AUTO_NEG_FOR_FLOW_CTRL         (1 << 3)
-#define DISABLE_AUTO_NEG_FOR_DUPLEX            (1 << 2)
-#define FORCE_LINK_PASS                                (1 << 1)
-#define SERIAL_PORT_ENABLE                     (1 << 0)
-
-#define DEFAULT_RX_QUEUE_SIZE          128
-#define DEFAULT_TX_QUEUE_SIZE          256
+#define DEFAULT_RX_QUEUE_SIZE  128
+#define DEFAULT_TX_QUEUE_SIZE  256
+#define SKB_DMA_REALIGN                ((PAGE_SIZE - NET_SKB_PAD) % SMP_CACHE_BYTES)
 
 
 /*
@@ -393,6 +395,7 @@ struct mv643xx_eth_private {
        struct work_struct tx_timeout_task;
 
        struct napi_struct napi;
+       u32 int_mask;
        u8 oom;
        u8 work_link;
        u8 work_tx;
@@ -651,23 +654,20 @@ static int rxq_refill(struct rx_queue *rxq, int budget)
        refilled = 0;
        while (refilled < budget && rxq->rx_desc_count < rxq->rx_ring_size) {
                struct sk_buff *skb;
-               int unaligned;
                int rx;
                struct rx_desc *rx_desc;
 
                skb = __skb_dequeue(&mp->rx_recycle);
                if (skb == NULL)
-                       skb = dev_alloc_skb(mp->skb_size +
-                                           dma_get_cache_alignment() - 1);
+                       skb = dev_alloc_skb(mp->skb_size);
 
                if (skb == NULL) {
                        mp->oom = 1;
                        goto oom;
                }
 
-               unaligned = (u32)skb->data & (dma_get_cache_alignment() - 1);
-               if (unaligned)
-                       skb_reserve(skb, dma_get_cache_alignment() - unaligned);
+               if (SKB_DMA_REALIGN)
+                       skb_reserve(skb, SKB_DMA_REALIGN);
 
                refilled++;
                rxq->rx_desc_count++;
@@ -969,8 +969,7 @@ static int txq_reclaim(struct tx_queue *txq, int budget, int force)
                if (skb != NULL) {
                        if (skb_queue_len(&mp->rx_recycle) <
                                        mp->rx_ring_size &&
-                           skb_recycle_check(skb, mp->skb_size +
-                                       dma_get_cache_alignment() - 1))
+                           skb_recycle_check(skb, mp->skb_size))
                                __skb_queue_head(&mp->rx_recycle, skb);
                        else
                                dev_kfree_skb(skb);
@@ -1723,20 +1722,20 @@ static void uc_addr_set(struct mv643xx_eth_private *mp, unsigned char *addr)
 
 static u32 uc_addr_filter_mask(struct net_device *dev)
 {
-       struct dev_addr_list *uc_ptr;
+       struct netdev_hw_addr *ha;
        u32 nibbles;
 
        if (dev->flags & IFF_PROMISC)
                return 0;
 
        nibbles = 1 << (dev->dev_addr[5] & 0x0f);
-       for (uc_ptr = dev->uc_list; uc_ptr != NULL; uc_ptr = uc_ptr->next) {
-               if (memcmp(dev->dev_addr, uc_ptr->da_addr, 5))
+       list_for_each_entry(ha, &dev->uc_list, list) {
+               if (memcmp(dev->dev_addr, ha->addr, 5))
                        return 0;
-               if ((dev->dev_addr[5] ^ uc_ptr->da_addr[5]) & 0xf0)
+               if ((dev->dev_addr[5] ^ ha->addr[5]) & 0xf0)
                        return 0;
 
-               nibbles |= 1 << (uc_ptr->da_addr[5] & 0x0f);
+               nibbles |= 1 << (ha->addr[5] & 0x0f);
        }
 
        return nibbles;
@@ -1810,7 +1809,6 @@ static void mv643xx_eth_program_multicast_filter(struct net_device *dev)
        if (dev->flags & (IFF_PROMISC | IFF_ALLMULTI)) {
                int port_num;
                u32 accept;
-               int i;
 
 oom:
                port_num = mp->port_num;
@@ -2067,15 +2065,16 @@ static int mv643xx_eth_collect_events(struct mv643xx_eth_private *mp)
        u32 int_cause;
        u32 int_cause_ext;
 
-       int_cause = rdlp(mp, INT_CAUSE) & (INT_TX_END | INT_RX | INT_EXT);
+       int_cause = rdlp(mp, INT_CAUSE) & mp->int_mask;
        if (int_cause == 0)
                return 0;
 
        int_cause_ext = 0;
-       if (int_cause & INT_EXT)
+       if (int_cause & INT_EXT) {
+               int_cause &= ~INT_EXT;
                int_cause_ext = rdlp(mp, INT_CAUSE_EXT);
+       }
 
-       int_cause &= INT_TX_END | INT_RX;
        if (int_cause) {
                wrlp(mp, INT_CAUSE, ~int_cause);
                mp->work_tx_end |= ((int_cause & INT_TX_END) >> 19) &
@@ -2182,6 +2181,7 @@ static int mv643xx_eth_poll(struct napi_struct *napi, int budget)
                if (mp->work_link) {
                        mp->work_link = 0;
                        handle_link_event(mp);
+                       work_done++;
                        continue;
                }
 
@@ -2220,7 +2220,7 @@ static int mv643xx_eth_poll(struct napi_struct *napi, int budget)
                if (mp->oom)
                        mod_timer(&mp->rx_oom, jiffies + (HZ / 10));
                napi_complete(napi);
-               wrlp(mp, INT_MASK, INT_TX_END | INT_RX | INT_EXT);
+               wrlp(mp, INT_MASK, mp->int_mask);
        }
 
        return work_done;
@@ -2341,6 +2341,14 @@ static void mv643xx_eth_recalc_skb_size(struct mv643xx_eth_private *mp)
         * size field are ignored by the hardware.
         */
        mp->skb_size = (skb_size + 7) & ~7;
+
+       /*
+        * If NET_SKB_PAD is smaller than a cache line,
+        * netdev_alloc_skb() will cause skb->data to be misaligned
+        * to a cache line boundary.  If this is the case, include
+        * some extra space to allow re-aligning the data area.
+        */
+       mp->skb_size += SKB_DMA_REALIGN;
 }
 
 static int mv643xx_eth_open(struct net_device *dev)
@@ -2366,6 +2374,8 @@ static int mv643xx_eth_open(struct net_device *dev)
 
        skb_queue_head_init(&mp->rx_recycle);
 
+       mp->int_mask = INT_EXT;
+
        for (i = 0; i < mp->rxq_count; i++) {
                err = rxq_init(mp, i);
                if (err) {
@@ -2375,6 +2385,7 @@ static int mv643xx_eth_open(struct net_device *dev)
                }
 
                rxq_refill(mp->rxq + i, INT_MAX);
+               mp->int_mask |= INT_RX_0 << i;
        }
 
        if (mp->oom) {
@@ -2389,12 +2400,13 @@ static int mv643xx_eth_open(struct net_device *dev)
                                txq_deinit(mp->txq + i);
                        goto out_free;
                }
+               mp->int_mask |= INT_TX_END_0 << i;
        }
 
        port_start(mp);
 
        wrlp(mp, INT_MASK_EXT, INT_EXT_LINK_PHY | INT_EXT_TX);
-       wrlp(mp, INT_MASK, INT_TX_END | INT_RX | INT_EXT);
+       wrlp(mp, INT_MASK, mp->int_mask);
 
        return 0;
 
@@ -2538,7 +2550,7 @@ static void mv643xx_eth_netpoll(struct net_device *dev)
 
        mv643xx_eth_irq(dev->irq, dev);
 
-       wrlp(mp, INT_MASK, INT_TX_END | INT_RX | INT_EXT);
+       wrlp(mp, INT_MASK, mp->int_mask);
 }
 #endif
 
index 435e5a847c43c972cc24e9c5ab179191c113dc43..93c709d63e2f5abc9f91d2cefacf2651057e7708 100644 (file)
@@ -57,6 +57,17 @@ typedef void (*writerap_t)(void *, unsigned short);
 typedef void (*writerdp_t)(void *, unsigned short);
 typedef unsigned short (*readrdp_t)(void *);
 
+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_tx_timeout         = lance_tx_timeout,
+       .ndo_change_mtu         = eth_change_mtu,
+       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_set_mac_address    = eth_mac_addr,
+};
+
 /* Initialise the one and only on-board 7990 */
 struct net_device * __init mvme147lance_probe(int unit)
 {
@@ -81,11 +92,7 @@ struct net_device * __init mvme147lance_probe(int unit)
 
        /* Fill the dev fields */
        dev->base_addr = (unsigned long)MVME147_LANCE_BASE;
-       dev->open = &m147lance_open;
-       dev->stop = &m147lance_close;
-       dev->hard_start_xmit = &lance_start_xmit;
-       dev->set_multicast_list = &lance_set_multicast;
-       dev->tx_timeout = &lance_tx_timeout;
+       dev->netdev_ops = &lance_netdev_ops;
        dev->dma = 0;
 
        addr=(u_long *)ETHERNET_ADDRESS;
index f2c4a665e93f3d89cf1e0dcaf679f92f3aac681a..1f6e36ea669edad675f99a01f3e1678525ae984e 100644 (file)
@@ -75,7 +75,7 @@
 #include "myri10ge_mcp.h"
 #include "myri10ge_mcp_gen_header.h"
 
-#define MYRI10GE_VERSION_STR "1.4.4-1.401"
+#define MYRI10GE_VERSION_STR "1.5.0-1.418"
 
 MODULE_DESCRIPTION("Myricom 10G driver (10GbE)");
 MODULE_AUTHOR("Maintainer: help@myri.com");
@@ -255,6 +255,7 @@ struct myri10ge_priv {
        u32 read_write_dma;
        u32 link_changes;
        u32 msg_enable;
+       unsigned int board_number;
 };
 
 static char *myri10ge_fw_unaligned = "myri10ge_ethp_z8e.dat";
@@ -266,6 +267,13 @@ static char *myri10ge_fw_name = NULL;
 module_param(myri10ge_fw_name, charp, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(myri10ge_fw_name, "Firmware image name");
 
+#define MYRI10GE_MAX_BOARDS 8
+static char *myri10ge_fw_names[MYRI10GE_MAX_BOARDS] =
+    {[0 ... (MYRI10GE_MAX_BOARDS - 1)] = NULL };
+module_param_array_named(myri10ge_fw_names, myri10ge_fw_names, charp, NULL,
+                        0444);
+MODULE_PARM_DESC(myri10ge_fw_name, "Firmware image names per board");
+
 static int myri10ge_ecrc_enable = 1;
 module_param(myri10ge_ecrc_enable, int, S_IRUGO);
 MODULE_PARM_DESC(myri10ge_ecrc_enable, "Enable Extended CRC on PCI-E");
@@ -319,10 +327,6 @@ static int myri10ge_debug = -1;    /* defaults above */
 module_param(myri10ge_debug, int, 0);
 MODULE_PARM_DESC(myri10ge_debug, "Debug level (0=none,...,16=all)");
 
-static int myri10ge_lro = 1;
-module_param(myri10ge_lro, int, S_IRUGO);
-MODULE_PARM_DESC(myri10ge_lro, "Enable large receive offload");
-
 static int myri10ge_lro_max_pkts = MYRI10GE_LRO_MAX_PKTS;
 module_param(myri10ge_lro_max_pkts, int, S_IRUGO);
 MODULE_PARM_DESC(myri10ge_lro_max_pkts,
@@ -361,6 +365,8 @@ static inline void put_be32(__be32 val, __be32 __iomem * p)
        __raw_writel((__force __u32) val, (__force void __iomem *)p);
 }
 
+static struct net_device_stats *myri10ge_get_stats(struct net_device *dev);
+
 static int
 myri10ge_send_cmd(struct myri10ge_priv *mgp, u32 cmd,
                  struct myri10ge_cmd *data, int atomic)
@@ -1290,7 +1296,7 @@ myri10ge_rx_done(struct myri10ge_slice_state *ss, struct myri10ge_rx_buf *rx,
                remainder -= MYRI10GE_ALLOC_SIZE;
        }
 
-       if (mgp->csum_flag && myri10ge_lro) {
+       if (dev->features & NETIF_F_LRO) {
                rx_frags[0].page_offset += MXGEFW_PAD;
                rx_frags[0].size -= MXGEFW_PAD;
                len -= MXGEFW_PAD;
@@ -1412,6 +1418,7 @@ myri10ge_clean_rx_done(struct myri10ge_slice_state *ss, int budget)
 {
        struct myri10ge_rx_done *rx_done = &ss->rx_done;
        struct myri10ge_priv *mgp = ss->mgp;
+       struct net_device *netdev = mgp->dev;
        unsigned long rx_bytes = 0;
        unsigned long rx_packets = 0;
        unsigned long rx_ok;
@@ -1445,7 +1452,7 @@ myri10ge_clean_rx_done(struct myri10ge_slice_state *ss, int budget)
        ss->stats.rx_packets += rx_packets;
        ss->stats.rx_bytes += rx_bytes;
 
-       if (myri10ge_lro)
+       if (netdev->features & NETIF_F_LRO)
                lro_flush_all(&rx_done->lro_mgr);
 
        /* restock receive rings if needed */
@@ -1686,7 +1693,7 @@ myri10ge_get_ringparam(struct net_device *netdev,
        ring->rx_mini_max_pending = mgp->ss[0].rx_small.mask + 1;
        ring->rx_max_pending = mgp->ss[0].rx_big.mask + 1;
        ring->rx_jumbo_max_pending = 0;
-       ring->tx_max_pending = mgp->ss[0].rx_small.mask + 1;
+       ring->tx_max_pending = mgp->ss[0].tx.mask + 1;
        ring->rx_mini_pending = ring->rx_mini_max_pending;
        ring->rx_pending = ring->rx_max_pending;
        ring->rx_jumbo_pending = ring->rx_jumbo_max_pending;
@@ -1706,12 +1713,17 @@ static u32 myri10ge_get_rx_csum(struct net_device *netdev)
 static int myri10ge_set_rx_csum(struct net_device *netdev, u32 csum_enabled)
 {
        struct myri10ge_priv *mgp = netdev_priv(netdev);
+       int err = 0;
 
        if (csum_enabled)
                mgp->csum_flag = MXGEFW_FLAGS_CKSUM;
-       else
+       else {
+               u32 flags = ethtool_op_get_flags(netdev);
+               err = ethtool_op_set_flags(netdev, (flags & ~ETH_FLAG_LRO));
                mgp->csum_flag = 0;
-       return 0;
+
+       }
+       return err;
 }
 
 static int myri10ge_set_tso(struct net_device *netdev, u32 tso_enabled)
@@ -1803,6 +1815,8 @@ myri10ge_get_ethtool_stats(struct net_device *netdev,
        int slice;
        int i;
 
+       /* force stats update */
+       (void)myri10ge_get_stats(netdev);
        for (i = 0; i < MYRI10GE_NET_STATS_LEN; i++)
                data[i] = ((unsigned long *)&mgp->stats)[i];
 
@@ -1892,7 +1906,9 @@ static const struct ethtool_ops myri10ge_ethtool_ops = {
        .get_sset_count = myri10ge_get_sset_count,
        .get_ethtool_stats = myri10ge_get_ethtool_stats,
        .set_msglevel = myri10ge_set_msglevel,
-       .get_msglevel = myri10ge_get_msglevel
+       .get_msglevel = myri10ge_get_msglevel,
+       .get_flags = ethtool_op_get_flags,
+       .set_flags = ethtool_op_set_flags
 };
 
 static int myri10ge_allocate_rings(struct myri10ge_slice_state *ss)
@@ -2671,7 +2687,7 @@ again:
                /* we are out of transmit resources */
                tx->stop_queue++;
                netif_tx_stop_queue(netdev_queue);
-               return 1;
+               return NETDEV_TX_BUSY;
        }
 
        /* Setup checksum offloading, if needed */
@@ -2876,7 +2892,6 @@ again:
                tx->stop_queue++;
                netif_tx_stop_queue(netdev_queue);
        }
-       dev->trans_start = jiffies;
        return 0;
 
 abort_linearize:
@@ -2969,6 +2984,7 @@ static struct net_device_stats *myri10ge_get_stats(struct net_device *dev)
        struct net_device_stats *stats = &mgp->stats;
        int i;
 
+       spin_lock(&mgp->stats_lock);
        memset(stats, 0, sizeof(*stats));
        for (i = 0; i < mgp->num_slices; i++) {
                slice_stats = &mgp->ss[i].stats;
@@ -2979,6 +2995,7 @@ static struct net_device_stats *myri10ge_get_stats(struct net_device *dev)
                stats->rx_dropped += slice_stats->rx_dropped;
                stats->tx_dropped += slice_stats->tx_dropped;
        }
+       spin_unlock(&mgp->stats_lock);
        return stats;
 }
 
@@ -3253,6 +3270,8 @@ abort:
 
 static void myri10ge_select_firmware(struct myri10ge_priv *mgp)
 {
+       int overridden = 0;
+
        if (myri10ge_force_firmware == 0) {
                int link_width, exp_cap;
                u16 lnk;
@@ -3286,10 +3305,18 @@ static void myri10ge_select_firmware(struct myri10ge_priv *mgp)
                }
        }
        if (myri10ge_fw_name != NULL) {
-               dev_info(&mgp->pdev->dev, "overriding firmware to %s\n",
-                        myri10ge_fw_name);
+               overridden = 1;
                mgp->fw_name = myri10ge_fw_name;
        }
+       if (mgp->board_number < MYRI10GE_MAX_BOARDS &&
+           myri10ge_fw_names[mgp->board_number] != NULL &&
+           strlen(myri10ge_fw_names[mgp->board_number])) {
+               mgp->fw_name = myri10ge_fw_names[mgp->board_number];
+               overridden = 1;
+       }
+       if (overridden)
+               dev_info(&mgp->pdev->dev, "overriding firmware to %s\n",
+                        mgp->fw_name);
 }
 
 #ifdef CONFIG_PM
@@ -3754,6 +3781,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        int status = -ENXIO;
        int dac_enabled;
        unsigned hdr_offset, ss_offset;
+       static int board_number;
 
        netdev = alloc_etherdev_mq(sizeof(*mgp), MYRI10GE_MAX_SLICES);
        if (netdev == NULL) {
@@ -3770,6 +3798,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        mgp->pause = myri10ge_flow_control;
        mgp->intr_coal_delay = myri10ge_intr_coal_delay;
        mgp->msg_enable = netif_msg_init(myri10ge_debug, MYRI10GE_MSG_DEFAULT);
+       mgp->board_number = board_number;
        init_waitqueue_head(&mgp->down_wq);
 
        if (pci_enable_device(pdev)) {
@@ -3884,6 +3913,13 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        if (dac_enabled)
                netdev->features |= NETIF_F_HIGHDMA;
+       netdev->features |= NETIF_F_LRO;
+
+       netdev->vlan_features |= mgp->features;
+       if (mgp->fw_ver_tiny < 37)
+               netdev->vlan_features &= ~NETIF_F_TSO6;
+       if (mgp->fw_ver_tiny < 32)
+               netdev->vlan_features &= ~NETIF_F_TSO;
 
        /* make sure we can get an irq, and that MSI can be
         * setup (if available).  Also ensure netdev->irq
@@ -3902,6 +3938,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        setup_timer(&mgp->watchdog_timer, myri10ge_watchdog_timer,
                    (unsigned long)mgp);
 
+       spin_lock_init(&mgp->stats_lock);
        SET_ETHTOOL_OPS(netdev, &myri10ge_ethtool_ops);
        INIT_WORK(&mgp->watchdog_work, myri10ge_watchdog);
        status = register_netdev(netdev);
@@ -3919,6 +3956,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                         netdev->irq, mgp->tx_boundary, mgp->fw_name,
                         (mgp->wc_enabled ? "Enabled" : "Disabled"));
 
+       board_number++;
        return 0;
 
 abort_with_state:
@@ -4008,6 +4046,8 @@ static struct pci_device_id myri10ge_pci_tbl[] = {
        {0},
 };
 
+MODULE_DEVICE_TABLE(pci, myri10ge_pci_tbl);
+
 static struct pci_driver myri10ge_driver = {
        .name = "myri10ge",
        .probe = myri10ge_probe,
index 9a802adba9a328e5047843fc8ba8e5ca31abe9a8..5f0758bda6b3ea0572aaed03454dfb2b8ce0d117 100644 (file)
@@ -640,7 +640,7 @@ static int myri_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
        if (!TX_BUFFS_AVAIL(head, tail)) {
                DTX(("no buffs available, returning 1\n"));
-               return 1;
+               return NETDEV_TX_BUSY;
        }
 
        spin_lock_irqsave(&mp->irq_lock, flags);
index 7d83896b8c2614a1289a10526e5875f0fb388f3c..3fcebb70151c82fbbab06026f2dc636f3baff7d9 100644 (file)
@@ -374,7 +374,7 @@ static int __devinit ne2k_pci_init_one (struct pci_dev *pdev,
        dev->ethtool_ops = &ne2k_pci_ethtool_ops;
        NS8390_init(dev, 0);
 
-       memcpy(dev->dev_addr, SA_prom, 6);
+       memcpy(dev->dev_addr, SA_prom, dev->addr_len);
        memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
 
        i = register_netdev(dev);
index 6a843f7350ab10982506df13116b9b5c48d02b40..a00bbfb9aed0f5d7f9131082edda777d3d146b2f 100644 (file)
@@ -104,7 +104,7 @@ static int __init ne3210_eisa_probe (struct device *device)
        }
 
        SET_NETDEV_DEV(dev, device);
-       device->driver_data = dev;
+       dev_set_drvdata(device, dev);
        ioaddr = edev->base_addr;
 
        if (!request_region(ioaddr, NE3210_IO_EXTENT, DRV_NAME)) {
@@ -225,7 +225,7 @@ static int __init ne3210_eisa_probe (struct device *device)
 
 static int __devexit ne3210_eisa_remove (struct device *device)
 {
-       struct net_device  *dev    = device->driver_data;
+       struct net_device  *dev    = dev_get_drvdata(device);
        unsigned long       ioaddr = to_eisa_device (device)->base_addr;
 
        unregister_netdev (dev);
index 1861d5bbd96ba01764a8ab6462a5ae1aaf5422c8..946366dcc99221e4b98c44efcbbcc1a60a1a6490 100644 (file)
@@ -301,6 +301,17 @@ netx_eth_phy_write(struct net_device *ndev, int phy_id, int reg, int value)
        while (readl(NETX_MIIMU) & MIIMU_SNRDY);
 }
 
+static const struct net_device_ops netx_eth_netdev_ops = {
+       .ndo_open               = netx_eth_open,
+       .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_change_mtu         = eth_change_mtu,
+       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_set_mac_address    = eth_mac_addr,
+};
+
 static int netx_eth_enable(struct net_device *ndev)
 {
        struct netx_eth_priv *priv = netdev_priv(ndev);
@@ -309,12 +320,8 @@ static int netx_eth_enable(struct net_device *ndev)
 
        ether_setup(ndev);
 
-       ndev->open = netx_eth_open;
-       ndev->stop = netx_eth_close;
-       ndev->hard_start_xmit = netx_eth_hard_start_xmit;
-       ndev->tx_timeout = netx_eth_timeout;
+       ndev->netdev_ops = &netx_eth_netdev_ops;
        ndev->watchdog_timeo = msecs_to_jiffies(5000);
-       ndev->set_multicast_list = netx_eth_set_multicast_list;
 
        priv->msg_enable       = NETIF_MSG_LINK;
        priv->mii.phy_id_mask  = 0x1f;
index c40815169f35bee6b0b3ac188e74d001984ab425..ab11c2b3f0fe0ab2ddb42dc7f430a7a6311d5251 100644 (file)
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/types.h>
-#include <linux/compiler.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-#include <linux/init.h>
 #include <linux/ioport.h>
 #include <linux/pci.h>
 #include <linux/netdevice.h>
 #include <linux/in.h>
 #include <linux/tcp.h>
 #include <linux/skbuff.h>
+#include <linux/firmware.h>
 
 #include <linux/ethtool.h>
 #include <linux/mii.h>
-#include <linux/interrupt.h>
 #include <linux/timer.h>
 
-#include <linux/mm.h>
-#include <linux/mman.h>
 #include <linux/vmalloc.h>
 
-#include <asm/system.h>
 #include <asm/io.h>
 #include <asm/byteorder.h>
-#include <asm/uaccess.h>
-#include <asm/pgtable.h>
 
 #include "netxen_nic_hw.h"
 
        (sizeof(struct netxen_rx_buffer) * rds_ring->num_desc)
 #define STATUS_DESC_RINGSIZE(sds_ring) \
        (sizeof(struct status_desc) * (sds_ring)->num_desc)
-#define TX_BUFF_RINGSIZE(adapter)      \
-       (sizeof(struct netxen_cmd_buffer) * adapter->num_txd)
-#define TX_DESC_RINGSIZE(adapter)      \
-       (sizeof(struct cmd_desc_type0) * adapter->num_txd)
+#define TX_BUFF_RINGSIZE(tx_ring)      \
+       (sizeof(struct netxen_cmd_buffer) * tx_ring->num_desc)
+#define TX_DESC_RINGSIZE(tx_ring)      \
+       (sizeof(struct cmd_desc_type0) * tx_ring->num_desc)
 
 #define find_diff_among(a,b,range) ((a)<(b)?((b)-(a)):((b)+(range)-(a)))
 
 #define NX_P3_A2               0x30
 #define NX_P3_B0               0x40
 #define NX_P3_B1               0x41
+#define NX_P3_B2               0x42
 
 #define NX_IS_REVISION_P2(REVISION)     (REVISION <= NX_P2_C1)
 #define NX_IS_REVISION_P3(REVISION)     (REVISION >= NX_P3_A0)
 #define MAX_RCV_DESCRIPTORS_10G                4096
 #define MAX_JUMBO_RCV_DESCRIPTORS      1024
 #define MAX_LRO_RCV_DESCRIPTORS                8
-#define MAX_RCVSTATUS_DESCRIPTORS      MAX_RCV_DESCRIPTORS
-#define MAX_JUMBO_RCV_DESC     MAX_JUMBO_RCV_DESCRIPTORS
-#define MAX_RCV_DESC           MAX_RCV_DESCRIPTORS
-#define MAX_RCVSTATUS_DESC     MAX_RCV_DESCRIPTORS
-#define MAX_EPG_DESCRIPTORS    (MAX_CMD_DESCRIPTORS * 8)
-#define NUM_RCV_DESC           (MAX_RCV_DESC + MAX_JUMBO_RCV_DESCRIPTORS + \
-                                MAX_LRO_RCV_DESCRIPTORS)
-#define MIN_TX_COUNT   4096
-#define MIN_RX_COUNT   4096
 #define NETXEN_CTX_SIGNATURE   0xdee0
+#define NETXEN_CTX_SIGNATURE_V2        0x0002dee0
+#define NETXEN_CTX_RESET       0xbad0
 #define NETXEN_RCV_PRODUCER(ringid)    (ringid)
-#define MAX_FRAME_SIZE 0x10000 /* 64K MAX size for LSO */
 
 #define PHAN_PEG_RCV_INITIALIZED       0xff01
 #define PHAN_PEG_RCV_START_INITIALIZE  0xff00
@@ -253,12 +237,19 @@ typedef u32 netxen_ctx_msg;
 #define netxen_set_msg_opcode(config_word, val)        \
        ((config_word) &= ~(0xf<<28), (config_word) |= (val & 0xf) << 28)
 
-struct netxen_rcv_context {
-       __le64 rcv_ring_addr;
-       __le32 rcv_ring_size;
+struct netxen_rcv_ring {
+       __le64 addr;
+       __le32 size;
        __le32 rsrvd;
 };
 
+struct netxen_sts_ring {
+       __le64 addr;
+       __le32 size;
+       __le16 msi_index;
+       __le16 rsvd;
+} ;
+
 struct netxen_ring_ctx {
 
        /* one command ring */
@@ -268,13 +259,18 @@ struct netxen_ring_ctx {
        __le32 rsrvd;
 
        /* three receive rings */
-       struct netxen_rcv_context rcv_ctx[3];
+       struct netxen_rcv_ring rcv_rings[NUM_RCV_DESC_RINGS];
 
-       /* one status ring */
        __le64 sts_ring_addr;
        __le32 sts_ring_size;
 
        __le32 ctx_id;
+
+       __le64 rsrvd_2[3];
+       __le32 sts_ring_count;
+       __le32 rsrvd_3;
+       struct netxen_sts_ring sts_rings[NUM_STS_DESC_RINGS];
+
 } __attribute__ ((aligned(64)));
 
 /*
@@ -373,6 +369,7 @@ struct rcv_desc {
 /* opcode field in status_desc */
 #define NETXEN_NIC_RXPKT_DESC  0x04
 #define NETXEN_OLD_RXPKT_DESC  0x3f
+#define NETXEN_NIC_RESPONSE_DESC 0x05
 
 /* for status field in status_desc */
 #define STATUS_NEED_CKSUM      (1)
@@ -382,13 +379,11 @@ struct rcv_desc {
 #define STATUS_OWNER_HOST      (0x1ULL << 56)
 #define STATUS_OWNER_PHANTOM   (0x2ULL << 56)
 
-/* Note: sizeof(status_desc) should always be a mutliple of 2 */
-
-#define netxen_get_sts_desc_lro_cnt(status_desc)       \
-       ((status_desc)->lro & 0x7F)
-#define netxen_get_sts_desc_lro_last_frag(status_desc) \
-       (((status_desc)->lro & 0x80) >> 7)
-
+/* Status descriptor:
+   0-3 port, 4-7 status, 8-11 type, 12-27 total_length
+   28-43 reference_handle, 44-47 protocol, 48-52 pkt_offset
+   53-55 desc_cnt, 56-57 owner, 58-63 opcode
+ */
 #define netxen_get_sts_port(sts_data)  \
        ((sts_data) & 0x0F)
 #define netxen_get_sts_status(sts_data)        \
@@ -403,41 +398,15 @@ struct rcv_desc {
        (((sts_data) >> 44) & 0x0F)
 #define netxen_get_sts_pkt_offset(sts_data)    \
        (((sts_data) >> 48) & 0x1F)
+#define netxen_get_sts_desc_cnt(sts_data)      \
+       (((sts_data) >> 53) & 0x7)
 #define netxen_get_sts_opcode(sts_data)        \
        (((sts_data) >> 58) & 0x03F)
 
 struct status_desc {
-       /* Bit pattern: 0-3 port, 4-7 status, 8-11 type, 12-27 total_length
-          28-43 reference_handle, 44-47 protocol, 48-52 pkt_offset
-          53-55 desc_cnt, 56-57 owner, 58-63 opcode
-        */
-       __le64 status_desc_data;
-       union {
-               struct {
-                       __le32 hash_value;
-                       u8 hash_type;
-                       u8 msg_type;
-                       u8 unused;
-                       union {
-                               /* Bit pattern: 0-6 lro_count indicates frag
-                                * sequence, 7 last_frag indicates last frag
-                                */
-                               u8 lro;
-
-                               /* chained buffers */
-                               u8 nr_frags;
-                       };
-               };
-               struct {
-                       __le16 frag_handles[4];
-               };
-       };
+       __le64 status_desc_data[2];
 } __attribute__ ((aligned(16)));
 
-enum {
-       NETXEN_RCV_PEG_0 = 0,
-       NETXEN_RCV_PEG_1
-};
 /* The version of the main data structure */
 #define        NETXEN_BDINFO_VERSION 1
 
@@ -447,85 +416,35 @@ enum {
 /* Max number of Gig ports on a Phantom board */
 #define NETXEN_MAX_PORTS 4
 
-typedef enum {
-       NETXEN_BRDTYPE_P1_BD = 0x0000,
-       NETXEN_BRDTYPE_P1_SB = 0x0001,
-       NETXEN_BRDTYPE_P1_SMAX = 0x0002,
-       NETXEN_BRDTYPE_P1_SOCK = 0x0003,
-
-       NETXEN_BRDTYPE_P2_SOCK_31 = 0x0008,
-       NETXEN_BRDTYPE_P2_SOCK_35 = 0x0009,
-       NETXEN_BRDTYPE_P2_SB35_4G = 0x000a,
-       NETXEN_BRDTYPE_P2_SB31_10G = 0x000b,
-       NETXEN_BRDTYPE_P2_SB31_2G = 0x000c,
-
-       NETXEN_BRDTYPE_P2_SB31_10G_IMEZ = 0x000d,
-       NETXEN_BRDTYPE_P2_SB31_10G_HMEZ = 0x000e,
-       NETXEN_BRDTYPE_P2_SB31_10G_CX4 = 0x000f,
-
-       NETXEN_BRDTYPE_P3_REF_QG = 0x0021,
-       NETXEN_BRDTYPE_P3_HMEZ = 0x0022,
-       NETXEN_BRDTYPE_P3_10G_CX4_LP = 0x0023,
-       NETXEN_BRDTYPE_P3_4_GB = 0x0024,
-       NETXEN_BRDTYPE_P3_IMEZ = 0x0025,
-       NETXEN_BRDTYPE_P3_10G_SFP_PLUS = 0x0026,
-       NETXEN_BRDTYPE_P3_10000_BASE_T = 0x0027,
-       NETXEN_BRDTYPE_P3_XG_LOM = 0x0028,
-       NETXEN_BRDTYPE_P3_4_GB_MM = 0x0029,
-       NETXEN_BRDTYPE_P3_10G_SFP_CT = 0x002a,
-       NETXEN_BRDTYPE_P3_10G_SFP_QT = 0x002b,
-       NETXEN_BRDTYPE_P3_10G_CX4 = 0x0031,
-       NETXEN_BRDTYPE_P3_10G_XFP = 0x0032,
-       NETXEN_BRDTYPE_P3_10G_TP = 0x0080
-
-} netxen_brdtype_t;
-
-typedef enum {
-       NETXEN_BRDMFG_INVENTEC = 1
-} netxen_brdmfg;
-
-typedef enum {
-       MEM_ORG_128Mbx4 = 0x0,  /* DDR1 only */
-       MEM_ORG_128Mbx8 = 0x1,  /* DDR1 only */
-       MEM_ORG_128Mbx16 = 0x2, /* DDR1 only */
-       MEM_ORG_256Mbx4 = 0x3,
-       MEM_ORG_256Mbx8 = 0x4,
-       MEM_ORG_256Mbx16 = 0x5,
-       MEM_ORG_512Mbx4 = 0x6,
-       MEM_ORG_512Mbx8 = 0x7,
-       MEM_ORG_512Mbx16 = 0x8,
-       MEM_ORG_1Gbx4 = 0x9,
-       MEM_ORG_1Gbx8 = 0xa,
-       MEM_ORG_1Gbx16 = 0xb,
-       MEM_ORG_2Gbx4 = 0xc,
-       MEM_ORG_2Gbx8 = 0xd,
-       MEM_ORG_2Gbx16 = 0xe,
-       MEM_ORG_128Mbx32 = 0x10002,     /* GDDR only */
-       MEM_ORG_256Mbx32 = 0x10005      /* GDDR only */
-} netxen_mn_mem_org_t;
-
-typedef enum {
-       MEM_ORG_512Kx36 = 0x0,
-       MEM_ORG_1Mx36 = 0x1,
-       MEM_ORG_2Mx36 = 0x2
-} netxen_sn_mem_org_t;
-
-typedef enum {
-       MEM_DEPTH_4MB = 0x1,
-       MEM_DEPTH_8MB = 0x2,
-       MEM_DEPTH_16MB = 0x3,
-       MEM_DEPTH_32MB = 0x4,
-       MEM_DEPTH_64MB = 0x5,
-       MEM_DEPTH_128MB = 0x6,
-       MEM_DEPTH_256MB = 0x7,
-       MEM_DEPTH_512MB = 0x8,
-       MEM_DEPTH_1GB = 0x9,
-       MEM_DEPTH_2GB = 0xa,
-       MEM_DEPTH_4GB = 0xb,
-       MEM_DEPTH_8GB = 0xc,
-       MEM_DEPTH_16GB = 0xd,
-       MEM_DEPTH_32GB = 0xe
-} netxen_mem_depth_t;
+#define NETXEN_BRDTYPE_P1_BD           0x0000
+#define NETXEN_BRDTYPE_P1_SB           0x0001
+#define NETXEN_BRDTYPE_P1_SMAX         0x0002
+#define NETXEN_BRDTYPE_P1_SOCK         0x0003
+
+#define NETXEN_BRDTYPE_P2_SOCK_31      0x0008
+#define NETXEN_BRDTYPE_P2_SOCK_35      0x0009
+#define NETXEN_BRDTYPE_P2_SB35_4G      0x000a
+#define NETXEN_BRDTYPE_P2_SB31_10G     0x000b
+#define NETXEN_BRDTYPE_P2_SB31_2G      0x000c
+
+#define NETXEN_BRDTYPE_P2_SB31_10G_IMEZ                0x000d
+#define NETXEN_BRDTYPE_P2_SB31_10G_HMEZ                0x000e
+#define NETXEN_BRDTYPE_P2_SB31_10G_CX4         0x000f
+
+#define NETXEN_BRDTYPE_P3_REF_QG       0x0021
+#define NETXEN_BRDTYPE_P3_HMEZ         0x0022
+#define NETXEN_BRDTYPE_P3_10G_CX4_LP   0x0023
+#define NETXEN_BRDTYPE_P3_4_GB         0x0024
+#define NETXEN_BRDTYPE_P3_IMEZ         0x0025
+#define NETXEN_BRDTYPE_P3_10G_SFP_PLUS 0x0026
+#define NETXEN_BRDTYPE_P3_10000_BASE_T 0x0027
+#define NETXEN_BRDTYPE_P3_XG_LOM       0x0028
+#define NETXEN_BRDTYPE_P3_4_GB_MM      0x0029
+#define NETXEN_BRDTYPE_P3_10G_SFP_CT   0x002a
+#define NETXEN_BRDTYPE_P3_10G_SFP_QT   0x002b
+#define NETXEN_BRDTYPE_P3_10G_CX4      0x0031
+#define NETXEN_BRDTYPE_P3_10G_XFP      0x0032
+#define NETXEN_BRDTYPE_P3_10G_TP       0x0080
 
 struct netxen_board_info {
        u32 header_version;
@@ -676,17 +595,15 @@ struct netxen_new_user_info {
 #define PRIMARY_IMAGE_BAD      0xffffffff
 
 /* Flash memory map */
-typedef enum {
-       NETXEN_CRBINIT_START = 0,       /* Crbinit section */
-       NETXEN_BRDCFG_START = 0x4000,   /* board config */
-       NETXEN_INITCODE_START = 0x6000, /* pegtune code */
-       NETXEN_BOOTLD_START = 0x10000,  /* bootld */
-       NETXEN_IMAGE_START = 0x43000,   /* compressed image */
-       NETXEN_SECONDARY_START = 0x200000,      /* backup images */
-       NETXEN_PXE_START = 0x3E0000,    /* user defined region */
-       NETXEN_USER_START = 0x3E8000,   /* User defined region for new boards */
-       NETXEN_FIXED_START = 0x3F0000   /* backup of crbinit */
-} netxen_flash_map_t;
+#define NETXEN_CRBINIT_START   0       /* crbinit section */
+#define NETXEN_BRDCFG_START    0x4000  /* board config */
+#define NETXEN_INITCODE_START  0x6000  /* pegtune code */
+#define NETXEN_BOOTLD_START    0x10000 /* bootld */
+#define NETXEN_IMAGE_START     0x43000 /* compressed image */
+#define NETXEN_SECONDARY_START 0x200000        /* backup images */
+#define NETXEN_PXE_START       0x3E0000        /* PXE boot rom */
+#define NETXEN_USER_START      0x3E8000        /* Firmare info */
+#define NETXEN_FIXED_START     0x3F0000        /* backup of crbinit */
 
 #define NX_FW_VERSION_OFFSET   (NETXEN_USER_START+0x408)
 #define NX_FW_SIZE_OFFSET      (NETXEN_USER_START+0x40c)
@@ -708,21 +625,8 @@ typedef enum {
 #define NETXEN_FLASH_SECONDARY_SIZE    (NETXEN_USER_START-NETXEN_SECONDARY_START)
 #define NETXEN_NUM_PRIMARY_SECTORS     (0x20)
 #define NETXEN_NUM_CONFIG_SECTORS      (1)
-#define PFX "NetXen: "
 extern char netxen_nic_driver_name[];
 
-/* Note: Make sure to not call this before adapter->port is valid */
-#if !defined(NETXEN_DEBUG)
-#define DPRINTK(klevel, fmt, args...)  do { \
-       } while (0)
-#else
-#define DPRINTK(klevel, fmt, args...)  do { \
-       printk(KERN_##klevel PFX "%s: %s: " fmt, __func__,\
-               (adapter != NULL && adapter->netdev != NULL) ? \
-               adapter->netdev->name : NULL, \
-               ## args); } while(0)
-#endif
-
 /* Number of status descriptors to handle per interrupt */
 #define MAX_STATUS_HANDLE      (64)
 
@@ -732,7 +636,7 @@ extern char netxen_nic_driver_name[];
  */
 struct netxen_skb_frag {
        u64 dma;
-       ulong length;
+       u64 length;
 };
 
 #define _netxen_set_bits(config_word, start, bits, val)        {\
@@ -793,34 +697,24 @@ struct netxen_hardware_context {
 
        u8 cut_through;
        u8 revision_id;
+       u8 pci_func;
+       u8 linkup;
        u16 port_type;
-       int board_type;
-       u32 linkup;
-       /* Address of cmd ring in Phantom */
-       struct cmd_desc_type0 *cmd_desc_head;
-       dma_addr_t cmd_desc_phys_addr;
-       struct netxen_adapter *adapter;
-       int pci_func;
+       u16 board_type;
 };
 
 #define MINIMUM_ETHERNET_FRAME_SIZE    64      /* With FCS */
 #define ETHERNET_FCS_SIZE              4
 
 struct netxen_adapter_stats {
-       u64  rcvdbadskb;
        u64  xmitcalled;
-       u64  xmitedframes;
        u64  xmitfinished;
-       u64  badskblen;
-       u64  nocmddescriptor;
-       u64  polled;
        u64  rxdropped;
        u64  txdropped;
        u64  csummed;
        u64  no_rcv;
        u64  rxbytes;
        u64  txbytes;
-       u64  ints;
 };
 
 /*
@@ -852,14 +746,25 @@ struct nx_host_sds_ring {
        struct napi_struct napi;
        struct list_head free_list[NUM_RCV_DESC_RINGS];
 
-       u16 clean_tx;
-       u16 post_rxd;
        int irq;
 
        dma_addr_t phys_addr;
        char name[IFNAMSIZ+4];
 };
 
+struct nx_host_tx_ring {
+       u32 producer;
+       __le32 *hw_consumer;
+       u32 sw_consumer;
+       u32 crb_cmd_producer;
+       u32 crb_cmd_consumer;
+       u32 num_desc;
+
+       struct netxen_cmd_buffer *cmd_buf_arr;
+       struct cmd_desc_type0 *desc_head;
+       dma_addr_t phys_addr;
+};
+
 /*
  * Receive context. There is one such structure per instance of the
  * receive processing. Any state information that is relevant to
@@ -871,8 +776,11 @@ struct netxen_recv_context {
        u16 context_id;
        u16 virt_port;
 
-       struct nx_host_rds_ring rds_rings[NUM_RCV_DESC_RINGS];
-       struct nx_host_sds_ring sds_rings[NUM_STS_DESC_RINGS];
+       struct nx_host_rds_ring *rds_rings;
+       struct nx_host_sds_ring *sds_rings;
+
+       struct netxen_ring_ctx *hwctx;
+       dma_addr_t phys_addr;
 };
 
 /* New HW context creation */
@@ -1111,8 +1019,8 @@ typedef struct {
 #define NETXEN_MAC_DEL 2
 
 typedef struct nx_mac_list_s {
-       struct nx_mac_list_s *next;
-       uint8_t mac_addr[MAX_ADDR_LEN];
+       struct list_head list;
+       uint8_t mac_addr[ETH_ALEN+2];
 } nx_mac_list_t;
 
 /*
@@ -1154,31 +1062,118 @@ typedef struct {
 
 #define NX_MAC_EVENT           0x1
 
-enum {
-       NX_NIC_H2C_OPCODE_START = 0,
-       NX_NIC_H2C_OPCODE_CONFIG_RSS,
-       NX_NIC_H2C_OPCODE_CONFIG_RSS_TBL,
-       NX_NIC_H2C_OPCODE_CONFIG_INTR_COALESCE,
-       NX_NIC_H2C_OPCODE_CONFIG_LED,
-       NX_NIC_H2C_OPCODE_CONFIG_PROMISCUOUS,
-       NX_NIC_H2C_OPCODE_CONFIG_L2_MAC,
-       NX_NIC_H2C_OPCODE_LRO_REQUEST,
-       NX_NIC_H2C_OPCODE_GET_SNMP_STATS,
-       NX_NIC_H2C_OPCODE_PROXY_START_REQUEST,
-       NX_NIC_H2C_OPCODE_PROXY_STOP_REQUEST,
-       NX_NIC_H2C_OPCODE_PROXY_SET_MTU,
-       NX_NIC_H2C_OPCODE_PROXY_SET_VPORT_MISS_MODE,
-       NX_H2P_OPCODE_GET_FINGER_PRINT_REQUEST,
-       NX_H2P_OPCODE_INSTALL_LICENSE_REQUEST,
-       NX_H2P_OPCODE_GET_LICENSE_CAPABILITY_REQUEST,
-       NX_NIC_H2C_OPCODE_GET_NET_STATS,
-       NX_NIC_H2C_OPCODE_LAST
-};
+/*
+ * Driver --> Firmware
+ */
+#define NX_NIC_H2C_OPCODE_START                                0
+#define NX_NIC_H2C_OPCODE_CONFIG_RSS                   1
+#define NX_NIC_H2C_OPCODE_CONFIG_RSS_TBL               2
+#define NX_NIC_H2C_OPCODE_CONFIG_INTR_COALESCE         3
+#define NX_NIC_H2C_OPCODE_CONFIG_LED                   4
+#define NX_NIC_H2C_OPCODE_CONFIG_PROMISCUOUS           5
+#define NX_NIC_H2C_OPCODE_CONFIG_L2_MAC                        6
+#define NX_NIC_H2C_OPCODE_LRO_REQUEST                  7
+#define NX_NIC_H2C_OPCODE_GET_SNMP_STATS               8
+#define NX_NIC_H2C_OPCODE_PROXY_START_REQUEST          9
+#define NX_NIC_H2C_OPCODE_PROXY_STOP_REQUEST           10
+#define NX_NIC_H2C_OPCODE_PROXY_SET_MTU                        11
+#define NX_NIC_H2C_OPCODE_PROXY_SET_VPORT_MISS_MODE    12
+#define NX_NIC_H2C_OPCODE_GET_FINGER_PRINT_REQUEST     13
+#define NX_NIC_H2C_OPCODE_INSTALL_LICENSE_REQUEST      14
+#define NX_NIC_H2C_OPCODE_GET_LICENSE_CAPABILITY_REQUEST       15
+#define NX_NIC_H2C_OPCODE_GET_NET_STATS                        16
+#define NX_NIC_H2C_OPCODE_PROXY_UPDATE_P2V             17
+#define NX_NIC_H2C_OPCODE_CONFIG_IPADDR                        18
+#define NX_NIC_H2C_OPCODE_CONFIG_LOOPBACK              19
+#define NX_NIC_H2C_OPCODE_PROXY_STOP_DONE              20
+#define NX_NIC_H2C_OPCODE_GET_LINKEVENT                        21
+#define NX_NIC_C2C_OPCODE                              22
+#define NX_NIC_H2C_OPCODE_LAST                         23
+
+/*
+ * Firmware --> Driver
+ */
+
+#define NX_NIC_C2H_OPCODE_START                                128
+#define NX_NIC_C2H_OPCODE_CONFIG_RSS_RESPONSE          129
+#define NX_NIC_C2H_OPCODE_CONFIG_RSS_TBL_RESPONSE      130
+#define NX_NIC_C2H_OPCODE_CONFIG_MAC_RESPONSE          131
+#define NX_NIC_C2H_OPCODE_CONFIG_PROMISCUOUS_RESPONSE  132
+#define NX_NIC_C2H_OPCODE_CONFIG_L2_MAC_RESPONSE       133
+#define NX_NIC_C2H_OPCODE_LRO_DELETE_RESPONSE          134
+#define NX_NIC_C2H_OPCODE_LRO_ADD_FAILURE_RESPONSE     135
+#define NX_NIC_C2H_OPCODE_GET_SNMP_STATS               136
+#define NX_NIC_C2H_OPCODE_GET_FINGER_PRINT_REPLY       137
+#define NX_NIC_C2H_OPCODE_INSTALL_LICENSE_REPLY                138
+#define NX_NIC_C2H_OPCODE_GET_LICENSE_CAPABILITIES_REPLY 139
+#define NX_NIC_C2H_OPCODE_GET_NET_STATS_RESPONSE       140
+#define NX_NIC_C2H_OPCODE_GET_LINKEVENT_RESPONSE       141
+#define NX_NIC_C2H_OPCODE_LAST                         142
 
 #define VPORT_MISS_MODE_DROP           0 /* drop all unmatched */
 #define VPORT_MISS_MODE_ACCEPT_ALL     1 /* accept all packets */
 #define VPORT_MISS_MODE_ACCEPT_MULTI   2 /* accept unmatched multicast */
 
+#define NX_FW_CAPABILITY_LINK_NOTIFICATION     (1 << 5)
+#define NX_FW_CAPABILITY_SWITCHING             (1 << 6)
+
+/* module types */
+#define LINKEVENT_MODULE_NOT_PRESENT                   1
+#define LINKEVENT_MODULE_OPTICAL_UNKNOWN               2
+#define LINKEVENT_MODULE_OPTICAL_SRLR                  3
+#define LINKEVENT_MODULE_OPTICAL_LRM                   4
+#define LINKEVENT_MODULE_OPTICAL_SFP_1G                        5
+#define LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLE      6
+#define LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLELEN   7
+#define LINKEVENT_MODULE_TWINAX                                8
+
+#define LINKSPEED_10GBPS       10000
+#define LINKSPEED_1GBPS                1000
+#define LINKSPEED_100MBPS      100
+#define LINKSPEED_10MBPS       10
+
+#define LINKSPEED_ENCODED_10MBPS       0
+#define LINKSPEED_ENCODED_100MBPS      1
+#define LINKSPEED_ENCODED_1GBPS                2
+
+#define LINKEVENT_AUTONEG_DISABLED     0
+#define LINKEVENT_AUTONEG_ENABLED      1
+
+#define LINKEVENT_HALF_DUPLEX          0
+#define LINKEVENT_FULL_DUPLEX          1
+
+#define LINKEVENT_LINKSPEED_MBPS       0
+#define LINKEVENT_LINKSPEED_ENCODED    1
+
+/* firmware response header:
+ *     63:58 - message type
+ *     57:56 - owner
+ *     55:53 - desc count
+ *     52:48 - reserved
+ *     47:40 - completion id
+ *     39:32 - opcode
+ *     31:16 - error code
+ *     15:00 - reserved
+ */
+#define netxen_get_nic_msgtype(msg_hdr)        \
+       ((msg_hdr >> 58) & 0x3F)
+#define netxen_get_nic_msg_compid(msg_hdr)     \
+       ((msg_hdr >> 40) & 0xFF)
+#define netxen_get_nic_msg_opcode(msg_hdr)     \
+       ((msg_hdr >> 32) & 0xFF)
+#define netxen_get_nic_msg_errcode(msg_hdr)    \
+       ((msg_hdr >> 16) & 0xFFFF)
+
+typedef struct {
+       union {
+               struct {
+                       u64 hdr;
+                       u64 body[7];
+               };
+               u64 words[8];
+       };
+} nx_fw_msg_t;
+
 typedef struct {
        __le64 qhdr;
        __le64 req_hdr;
@@ -1218,99 +1213,96 @@ struct netxen_adapter {
 
        struct net_device *netdev;
        struct pci_dev *pdev;
-       int pci_using_dac;
-       struct net_device_stats net_stats;
-       int mtu;
-       int portnum;
-       u8 physical_port;
-       u16 tx_context_id;
-
-       uint8_t         mc_enabled;
-       uint8_t         max_mc_count;
-       nx_mac_list_t   *mac_list;
-
-       struct netxen_legacy_intr_set legacy_intr;
-
-       struct work_struct watchdog_task;
-       struct timer_list watchdog_timer;
-       struct work_struct  tx_timeout_task;
+       struct list_head mac_list;
 
        u32 curr_window;
        u32 crb_win;
        rwlock_t adapter_lock;
 
-       u32 cmd_producer;
-       __le32 *cmd_consumer;
-       u32 last_cmd_consumer;
-       u32 crb_addr_cmd_producer;
-       u32 crb_addr_cmd_consumer;
        spinlock_t tx_clean_lock;
 
-       u32 num_txd;
-       u32 num_rxd;
-       u32 num_jumbo_rxd;
-       u32 num_lro_rxd;
+       u16 num_txd;
+       u16 num_rxd;
+       u16 num_jumbo_rxd;
+       u16 num_lro_rxd;
+
+       u8 max_rds_rings;
+       u8 max_sds_rings;
+       u8 driver_mismatch;
+       u8 msix_supported;
+       u8 rx_csum;
+       u8 pci_using_dac;
+       u8 portnum;
+       u8 physical_port;
+
+       u8 mc_enabled;
+       u8 max_mc_count;
+       u8 rss_supported;
+       u8 resv2;
+       u32 resv3;
+
+       u8 has_link_events;
+       u8 resv1;
+       u16 tx_context_id;
+       u16 mtu;
+       u16 is_up;
 
-       int max_rds_rings;
-       int max_sds_rings;
+       u16 link_speed;
+       u16 link_duplex;
+       u16 link_autoneg;
+       u16 module_type;
 
+       u32 capabilities;
        u32 flags;
        u32 irq;
-       int driver_mismatch;
        u32 temp;
 
-       u32 fw_major;
-       u32 fw_version;
-
-       int msix_supported;
-       struct msix_entry msix_entries[MSIX_ENTRIES_PER_ADAPTER];
+       u32 msi_tgt_status;
+       u32 resv4;
 
        struct netxen_adapter_stats stats;
 
-       u16 link_speed;
-       u16 link_duplex;
-       u16 state;
-       u16 link_autoneg;
-       int rx_csum;
-
-       struct netxen_cmd_buffer *cmd_buf_arr;  /* Command buffers for xmit */
-
-       /*
-        * Receive instances. These can be either one per port,
-        * or one per peg, etc.
-        */
        struct netxen_recv_context recv_ctx;
+       struct nx_host_tx_ring *tx_ring;
 
-       int is_up;
-       struct netxen_dummy_dma dummy_dma;
-       nx_nic_intr_coalesce_t coal;
-
-       /* Context interface shared between card and host */
-       struct netxen_ring_ctx *ctx_desc;
-       dma_addr_t ctx_desc_phys_addr;
-       int intr_scheme;
-       int msi_mode;
        int (*enable_phy_interrupts) (struct netxen_adapter *);
        int (*disable_phy_interrupts) (struct netxen_adapter *);
-       int (*macaddr_set) (struct netxen_adapter *, netxen_ethernet_macaddr_t);
+       int (*macaddr_set) (struct netxen_adapter *, u8 *);
        int (*set_mtu) (struct netxen_adapter *, int);
        int (*set_promisc) (struct netxen_adapter *, u32);
+       void (*set_multi) (struct net_device *);
        int (*phy_read) (struct netxen_adapter *, long reg, u32 *);
        int (*phy_write) (struct netxen_adapter *, long reg, u32 val);
        int (*init_port) (struct netxen_adapter *, int);
        int (*stop_port) (struct netxen_adapter *);
 
-       int (*hw_read_wx)(struct netxen_adapter *, ulong, void *, int);
-       int (*hw_write_wx)(struct netxen_adapter *, ulong, void *, int);
+       u32 (*hw_read_wx)(struct netxen_adapter *, ulong);
+       int (*hw_write_wx)(struct netxen_adapter *, ulong, u32);
        int (*pci_mem_read)(struct netxen_adapter *, u64, void *, int);
        int (*pci_mem_write)(struct netxen_adapter *, u64, void *, int);
        int (*pci_write_immediate)(struct netxen_adapter *, u64, u32);
        u32 (*pci_read_immediate)(struct netxen_adapter *, u64);
-       void (*pci_write_normalize)(struct netxen_adapter *, u64, u32);
-       u32 (*pci_read_normalize)(struct netxen_adapter *, u64);
        unsigned long (*pci_set_window)(struct netxen_adapter *,
                        unsigned long long);
-};                             /* netxen_adapter structure */
+
+       struct netxen_legacy_intr_set legacy_intr;
+
+       struct msix_entry msix_entries[MSIX_ENTRIES_PER_ADAPTER];
+
+       struct netxen_dummy_dma dummy_dma;
+
+       struct work_struct watchdog_task;
+       struct timer_list watchdog_timer;
+       struct work_struct  tx_timeout_task;
+
+       struct net_device_stats net_stats;
+
+       nx_nic_intr_coalesce_t coal;
+
+       u32 fw_major;
+       u32 fw_version;
+       const struct firmware *fw;
+};
 
 /*
  * NetXen dma watchdog control structure
@@ -1330,46 +1322,6 @@ struct netxen_adapter {
 #define netxen_get_dma_watchdog_disabled(config_word) \
        (((config_word) >> 1) & 0x1)
 
-/* Max number of xmit producer threads that can run simultaneously */
-#define        MAX_XMIT_PRODUCERS              16
-
-#define PCI_OFFSET_FIRST_RANGE(adapter, off)    \
-       ((adapter)->ahw.pci_base0 + (off))
-#define PCI_OFFSET_SECOND_RANGE(adapter, off)   \
-       ((adapter)->ahw.pci_base1 + (off) - SECOND_PAGE_GROUP_START)
-#define PCI_OFFSET_THIRD_RANGE(adapter, off)    \
-       ((adapter)->ahw.pci_base2 + (off) - THIRD_PAGE_GROUP_START)
-
-static inline void __iomem *pci_base_offset(struct netxen_adapter *adapter,
-                                           unsigned long off)
-{
-       if ((off < FIRST_PAGE_GROUP_END) && (off >= FIRST_PAGE_GROUP_START)) {
-               return (adapter->ahw.pci_base0 + off);
-       } else if ((off < SECOND_PAGE_GROUP_END) &&
-                  (off >= SECOND_PAGE_GROUP_START)) {
-               return (adapter->ahw.pci_base1 + off - SECOND_PAGE_GROUP_START);
-       } else if ((off < THIRD_PAGE_GROUP_END) &&
-                  (off >= THIRD_PAGE_GROUP_START)) {
-               return (adapter->ahw.pci_base2 + off - THIRD_PAGE_GROUP_START);
-       }
-       return NULL;
-}
-
-static inline void __iomem *pci_base(struct netxen_adapter *adapter,
-                                    unsigned long off)
-{
-       if ((off < FIRST_PAGE_GROUP_END) && (off >= FIRST_PAGE_GROUP_START)) {
-               return adapter->ahw.pci_base0;
-       } else if ((off < SECOND_PAGE_GROUP_END) &&
-                  (off >= SECOND_PAGE_GROUP_START)) {
-               return adapter->ahw.pci_base1;
-       } else if ((off < THIRD_PAGE_GROUP_END) &&
-                  (off >= THIRD_PAGE_GROUP_START)) {
-               return adapter->ahw.pci_base2;
-       }
-       return NULL;
-}
-
 int netxen_niu_xgbe_enable_phy_interrupts(struct netxen_adapter *adapter);
 int netxen_niu_gbe_enable_phy_interrupts(struct netxen_adapter *adapter);
 int netxen_niu_xgbe_disable_phy_interrupts(struct netxen_adapter *adapter);
@@ -1382,21 +1334,22 @@ int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter,
 /* Functions available from netxen_nic_hw.c */
 int netxen_nic_set_mtu_xgb(struct netxen_adapter *adapter, int new_mtu);
 int netxen_nic_set_mtu_gb(struct netxen_adapter *adapter, int new_mtu);
-void netxen_nic_reg_write(struct netxen_adapter *adapter, u64 off, u32 val);
-int netxen_nic_reg_read(struct netxen_adapter *adapter, u64 off);
-void netxen_nic_write_w0(struct netxen_adapter *adapter, u32 index, u32 value);
-void netxen_nic_read_w0(struct netxen_adapter *adapter, u32 index, u32 *value);
-void netxen_nic_write_w1(struct netxen_adapter *adapter, u32 index, u32 value);
-void netxen_nic_read_w1(struct netxen_adapter *adapter, u32 index, u32 *value);
+
+int netxen_p2_nic_set_mac_addr(struct netxen_adapter *adapter, u8 *addr);
+int netxen_p3_nic_set_mac_addr(struct netxen_adapter *adapter, u8 *addr);
+
+#define NXRD32(adapter, off) \
+       (adapter->hw_read_wx(adapter, off))
+#define NXWR32(adapter, off, val) \
+       (adapter->hw_write_wx(adapter, off, val))
 
 int netxen_nic_get_board_info(struct netxen_adapter *adapter);
 void netxen_nic_get_firmware_info(struct netxen_adapter *adapter);
 int netxen_nic_wol_supported(struct netxen_adapter *adapter);
 
-int netxen_nic_hw_read_wx_128M(struct netxen_adapter *adapter,
-               ulong off, void *data, int len);
+u32 netxen_nic_hw_read_wx_128M(struct netxen_adapter *adapter, ulong off);
 int netxen_nic_hw_write_wx_128M(struct netxen_adapter *adapter,
-               ulong off, void *data, int len);
+               ulong off, u32 data);
 int netxen_nic_pci_mem_read_128M(struct netxen_adapter *adapter,
                u64 off, void *data, int size);
 int netxen_nic_pci_mem_write_128M(struct netxen_adapter *adapter,
@@ -1412,16 +1365,13 @@ unsigned long netxen_nic_pci_set_window_128M(struct netxen_adapter *adapter,
 void netxen_nic_pci_change_crbwindow_128M(struct netxen_adapter *adapter,
                u32 wndw);
 
-int netxen_nic_hw_read_wx_2M(struct netxen_adapter *adapter,
-               ulong off, void *data, int len);
+u32 netxen_nic_hw_read_wx_2M(struct netxen_adapter *adapter, ulong off);
 int netxen_nic_hw_write_wx_2M(struct netxen_adapter *adapter,
-               ulong off, void *data, int len);
+               ulong off, u32 data);
 int netxen_nic_pci_mem_read_2M(struct netxen_adapter *adapter,
                u64 off, void *data, int size);
 int netxen_nic_pci_mem_write_2M(struct netxen_adapter *adapter,
                u64 off, void *data, int size);
-void netxen_crb_writelit_adapter(struct netxen_adapter *adapter,
-                                unsigned long off, int data);
 int netxen_nic_pci_write_immediate_2M(struct netxen_adapter *adapter,
                u64 off, u32 data);
 u32 netxen_nic_pci_read_immediate_2M(struct netxen_adapter *adapter, u64 off);
@@ -1435,8 +1385,9 @@ unsigned long netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter,
 void netxen_free_adapter_offload(struct netxen_adapter *adapter);
 int netxen_initialize_adapter_offload(struct netxen_adapter *adapter);
 int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val);
-int netxen_receive_peg_ready(struct netxen_adapter *adapter);
 int netxen_load_firmware(struct netxen_adapter *adapter);
+void netxen_request_firmware(struct netxen_adapter *adapter);
+void netxen_release_firmware(struct netxen_adapter *adapter);
 int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose);
 
 int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp);
@@ -1475,6 +1426,8 @@ void netxen_p3_free_mac_list(struct netxen_adapter *adapter);
 int netxen_p3_nic_set_promisc(struct netxen_adapter *adapter, u32);
 int netxen_config_intr_coalesce(struct netxen_adapter *adapter);
 int netxen_config_rss(struct netxen_adapter *adapter, int enable);
+int netxen_linkevent_request(struct netxen_adapter *adapter, int enable);
+void netxen_advert_link_change(struct netxen_adapter *adapter, int linkup);
 
 int nx_fw_cmd_set_mtu(struct netxen_adapter *adapter, int mtu);
 int netxen_nic_change_mtu(struct net_device *netdev, int new_mtu);
@@ -1483,7 +1436,7 @@ int netxen_nic_set_mac(struct net_device *netdev, void *p);
 struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev);
 
 void netxen_nic_update_cmd_producer(struct netxen_adapter *adapter,
-               uint32_t crb_producer);
+               struct nx_host_tx_ring *tx_ring, uint32_t crb_producer);
 
 /*
  * NetXen Board information
@@ -1491,7 +1444,7 @@ void netxen_nic_update_cmd_producer(struct netxen_adapter *adapter,
 
 #define NETXEN_MAX_SHORT_NAME 32
 struct netxen_brdinfo {
-       netxen_brdtype_t brdtype;       /* type of board */
+       int brdtype;    /* type of board */
        long ports;             /* max no of physical ports */
        char short_name[NETXEN_MAX_SHORT_NAME];
 };
@@ -1541,17 +1494,15 @@ dma_watchdog_shutdown_request(struct netxen_adapter *adapter)
        u32 ctrl;
 
        /* check if already inactive */
-       if (adapter->hw_read_wx(adapter,
-           NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL), &ctrl, 4))
-               printk(KERN_ERR "failed to read dma watchdog status\n");
+       ctrl = adapter->hw_read_wx(adapter,
+                       NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL));
 
        if (netxen_get_dma_watchdog_enabled(ctrl) == 0)
                return 1;
 
        /* Send the disable request */
        netxen_set_dma_watchdog_disable_req(ctrl);
-       netxen_crb_writelit_adapter(adapter,
-               NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL), ctrl);
+       NXWR32(adapter, NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL), ctrl);
 
        return 0;
 }
@@ -1561,9 +1512,8 @@ dma_watchdog_shutdown_poll_result(struct netxen_adapter *adapter)
 {
        u32 ctrl;
 
-       if (adapter->hw_read_wx(adapter,
-           NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL), &ctrl, 4))
-               printk(KERN_ERR "failed to read dma watchdog status\n");
+       ctrl = adapter->hw_read_wx(adapter,
+                       NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL));
 
        return (netxen_get_dma_watchdog_enabled(ctrl) == 0);
 }
@@ -1573,9 +1523,8 @@ dma_watchdog_wakeup(struct netxen_adapter *adapter)
 {
        u32 ctrl;
 
-       if (adapter->hw_read_wx(adapter,
-               NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL), &ctrl, 4))
-               printk(KERN_ERR "failed to read dma watchdog status\n");
+       ctrl = adapter->hw_read_wx(adapter,
+                       NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL));
 
        if (netxen_get_dma_watchdog_enabled(ctrl))
                return 1;
@@ -1583,8 +1532,7 @@ dma_watchdog_wakeup(struct netxen_adapter *adapter)
        /* send the wakeup request */
        netxen_set_dma_watchdog_enable_req(ctrl);
 
-       netxen_crb_writelit_adapter(adapter,
-               NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL), ctrl);
+       NXWR32(adapter, NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL), ctrl);
 
        return 0;
 }
index 9234473bc08a752bfb06a45d740e30d198e9f091..4754f5cffad078ce53436b26330b6a0623ee4749 100644 (file)
@@ -41,8 +41,7 @@ netxen_api_lock(struct netxen_adapter *adapter)
 
        for (;;) {
                /* Acquire PCIE HW semaphore5 */
-               netxen_nic_read_w0(adapter,
-                       NETXEN_PCIE_REG(PCIE_SEM5_LOCK), &done);
+               done = NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM5_LOCK));
 
                if (done == 1)
                        break;
@@ -56,7 +55,7 @@ netxen_api_lock(struct netxen_adapter *adapter)
        }
 
 #if 0
-       netxen_nic_write_w1(adapter,
+       NXWR32(adapter,
                NETXEN_API_LOCK_ID, NX_OS_API_LOCK_DRIVER);
 #endif
        return 0;
@@ -65,11 +64,8 @@ netxen_api_lock(struct netxen_adapter *adapter)
 static int
 netxen_api_unlock(struct netxen_adapter *adapter)
 {
-       u32 val;
-
        /* Release PCIE HW semaphore5 */
-       netxen_nic_read_w0(adapter,
-               NETXEN_PCIE_REG(PCIE_SEM5_UNLOCK), &val);
+       NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM5_UNLOCK));
        return 0;
 }
 
@@ -86,7 +82,7 @@ netxen_poll_rsp(struct netxen_adapter *adapter)
                if (++timeout > NX_OS_CRB_RETRY_COUNT)
                        return NX_CDRP_RSP_TIMEOUT;
 
-               netxen_nic_read_w1(adapter, NX_CDRP_CRB_OFFSET, &rsp);
+               rsp = NXRD32(adapter, NX_CDRP_CRB_OFFSET);
        } while (!NX_CDRP_IS_RSP(rsp));
 
        return rsp;
@@ -106,16 +102,15 @@ netxen_issue_cmd(struct netxen_adapter *adapter,
        if (netxen_api_lock(adapter))
                return NX_RCODE_TIMEOUT;
 
-       netxen_nic_write_w1(adapter, NX_SIGN_CRB_OFFSET, signature);
+       NXWR32(adapter, NX_SIGN_CRB_OFFSET, signature);
 
-       netxen_nic_write_w1(adapter, NX_ARG1_CRB_OFFSET, arg1);
+       NXWR32(adapter, NX_ARG1_CRB_OFFSET, arg1);
 
-       netxen_nic_write_w1(adapter, NX_ARG2_CRB_OFFSET, arg2);
+       NXWR32(adapter, NX_ARG2_CRB_OFFSET, arg2);
 
-       netxen_nic_write_w1(adapter, NX_ARG3_CRB_OFFSET, arg3);
+       NXWR32(adapter, NX_ARG3_CRB_OFFSET, arg3);
 
-       netxen_nic_write_w1(adapter, NX_CDRP_CRB_OFFSET,
-                       NX_CDRP_FORM_CMD(cmd));
+       NXWR32(adapter, NX_CDRP_CRB_OFFSET, NX_CDRP_FORM_CMD(cmd));
 
        rsp = netxen_poll_rsp(adapter);
 
@@ -125,7 +120,7 @@ netxen_issue_cmd(struct netxen_adapter *adapter,
 
                rcode = NX_RCODE_TIMEOUT;
        } else if (rsp == NX_CDRP_RSP_FAIL) {
-               netxen_nic_read_w1(adapter, NX_ARG1_CRB_OFFSET, &rcode);
+               rcode = NXRD32(adapter, NX_ARG1_CRB_OFFSET);
 
                printk(KERN_ERR "%s: failed card response code:0x%x\n",
                                netxen_nic_driver_name, rcode);
@@ -328,6 +323,8 @@ nx_fw_cmd_create_tx_ctx(struct netxen_adapter *adapter)
        int     err = 0;
        u64     offset, phys_addr;
        dma_addr_t      rq_phys_addr, rsp_phys_addr;
+       struct nx_host_tx_ring *tx_ring = adapter->tx_ring;
+       struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
 
        rq_size = SIZEOF_HOSTRQ_TX(nx_hostrq_tx_ctx_t);
        rq_addr = pci_alloc_consistent(adapter->pdev,
@@ -362,15 +359,13 @@ nx_fw_cmd_create_tx_ctx(struct netxen_adapter *adapter)
 
        prq->dummy_dma_addr = cpu_to_le64(adapter->dummy_dma.phys_addr);
 
-       offset = adapter->ctx_desc_phys_addr+sizeof(struct netxen_ring_ctx);
+       offset = recv_ctx->phys_addr + sizeof(struct netxen_ring_ctx);
        prq->cmd_cons_dma_addr = cpu_to_le64(offset);
 
        prq_cds = &prq->cds_ring;
 
-       prq_cds->host_phys_addr =
-               cpu_to_le64(adapter->ahw.cmd_desc_phys_addr);
-
-       prq_cds->ring_size = cpu_to_le32(adapter->num_txd);
+       prq_cds->host_phys_addr = cpu_to_le64(tx_ring->phys_addr);
+       prq_cds->ring_size = cpu_to_le32(tx_ring->num_desc);
 
        phys_addr = rq_phys_addr;
        err = netxen_issue_cmd(adapter,
@@ -383,8 +378,7 @@ nx_fw_cmd_create_tx_ctx(struct netxen_adapter *adapter)
 
        if (err == NX_RCODE_SUCCESS) {
                temp = le32_to_cpu(prsp->cds_ring.host_producer_crb);
-               adapter->crb_addr_cmd_producer =
-                       NETXEN_NIC_REG(temp - 0x200);
+               tx_ring->crb_cmd_producer = NETXEN_NIC_REG(temp - 0x200);
 #if 0
                adapter->tx_state =
                        le32_to_cpu(prsp->host_ctx_state);
@@ -448,7 +442,19 @@ static struct netxen_recv_crb recv_crb_registers[] = {
                        NETXEN_NIC_REG(0x120)
                },
                /* crb_sts_consumer: */
-               NETXEN_NIC_REG(0x138),
+               {
+                       NETXEN_NIC_REG(0x138),
+                       NETXEN_NIC_REG_2(0x000),
+                       NETXEN_NIC_REG_2(0x004),
+                       NETXEN_NIC_REG_2(0x008),
+               },
+               /* sw_int_mask */
+               {
+                       CRB_SW_INT_MASK_0,
+                       NETXEN_NIC_REG_2(0x044),
+                       NETXEN_NIC_REG_2(0x048),
+                       NETXEN_NIC_REG_2(0x04c),
+               },
        },
        /* Instance 1 */
        {
@@ -461,7 +467,19 @@ static struct netxen_recv_crb recv_crb_registers[] = {
                        NETXEN_NIC_REG(0x164)
                },
                /* crb_sts_consumer: */
-               NETXEN_NIC_REG(0x17c),
+               {
+                       NETXEN_NIC_REG(0x17c),
+                       NETXEN_NIC_REG_2(0x020),
+                       NETXEN_NIC_REG_2(0x024),
+                       NETXEN_NIC_REG_2(0x028),
+               },
+               /* sw_int_mask */
+               {
+                       CRB_SW_INT_MASK_1,
+                       NETXEN_NIC_REG_2(0x064),
+                       NETXEN_NIC_REG_2(0x068),
+                       NETXEN_NIC_REG_2(0x06c),
+               },
        },
        /* Instance 2 */
        {
@@ -474,7 +492,19 @@ static struct netxen_recv_crb recv_crb_registers[] = {
                        NETXEN_NIC_REG(0x208)
                },
                /* crb_sts_consumer: */
-               NETXEN_NIC_REG(0x220),
+               {
+                       NETXEN_NIC_REG(0x220),
+                       NETXEN_NIC_REG_2(0x03c),
+                       NETXEN_NIC_REG_2(0x03c),
+                       NETXEN_NIC_REG_2(0x03c),
+               },
+               /* sw_int_mask */
+               {
+                       CRB_SW_INT_MASK_2,
+                       NETXEN_NIC_REG_2(0x03c),
+                       NETXEN_NIC_REG_2(0x03c),
+                       NETXEN_NIC_REG_2(0x03c),
+               },
        },
        /* Instance 3 */
        {
@@ -487,7 +517,19 @@ static struct netxen_recv_crb recv_crb_registers[] = {
                        NETXEN_NIC_REG(0x24c)
                },
                /* crb_sts_consumer: */
-               NETXEN_NIC_REG(0x264),
+               {
+                       NETXEN_NIC_REG(0x264),
+                       NETXEN_NIC_REG_2(0x03c),
+                       NETXEN_NIC_REG_2(0x03c),
+                       NETXEN_NIC_REG_2(0x03c),
+               },
+               /* sw_int_mask */
+               {
+                       CRB_SW_INT_MASK_3,
+                       NETXEN_NIC_REG_2(0x03c),
+                       NETXEN_NIC_REG_2(0x03c),
+                       NETXEN_NIC_REG_2(0x03c),
+               },
        },
 };
 
@@ -497,84 +539,91 @@ netxen_init_old_ctx(struct netxen_adapter *adapter)
        struct netxen_recv_context *recv_ctx;
        struct nx_host_rds_ring *rds_ring;
        struct nx_host_sds_ring *sds_ring;
+       struct nx_host_tx_ring *tx_ring;
        int ring;
-       int func_id = adapter->portnum;
-
-       adapter->ctx_desc->cmd_ring_addr =
-               cpu_to_le64(adapter->ahw.cmd_desc_phys_addr);
-       adapter->ctx_desc->cmd_ring_size =
-               cpu_to_le32(adapter->num_txd);
+       int port = adapter->portnum;
+       struct netxen_ring_ctx *hwctx;
+       u32 signature;
 
+       tx_ring = adapter->tx_ring;
        recv_ctx = &adapter->recv_ctx;
+       hwctx = recv_ctx->hwctx;
+
+       hwctx->cmd_ring_addr = cpu_to_le64(tx_ring->phys_addr);
+       hwctx->cmd_ring_size = cpu_to_le32(tx_ring->num_desc);
+
 
        for (ring = 0; ring < adapter->max_rds_rings; ring++) {
                rds_ring = &recv_ctx->rds_rings[ring];
 
-               adapter->ctx_desc->rcv_ctx[ring].rcv_ring_addr =
+               hwctx->rcv_rings[ring].addr =
                        cpu_to_le64(rds_ring->phys_addr);
-               adapter->ctx_desc->rcv_ctx[ring].rcv_ring_size =
+               hwctx->rcv_rings[ring].size =
                        cpu_to_le32(rds_ring->num_desc);
        }
-       sds_ring = &recv_ctx->sds_rings[0];
-       adapter->ctx_desc->sts_ring_addr = cpu_to_le64(sds_ring->phys_addr);
-       adapter->ctx_desc->sts_ring_size = cpu_to_le32(sds_ring->num_desc);
-
-       adapter->pci_write_normalize(adapter, CRB_CTX_ADDR_REG_LO(func_id),
-                       lower32(adapter->ctx_desc_phys_addr));
-       adapter->pci_write_normalize(adapter, CRB_CTX_ADDR_REG_HI(func_id),
-                       upper32(adapter->ctx_desc_phys_addr));
-       adapter->pci_write_normalize(adapter, CRB_CTX_SIGNATURE_REG(func_id),
-                       NETXEN_CTX_SIGNATURE | func_id);
+
+       for (ring = 0; ring < adapter->max_sds_rings; ring++) {
+               sds_ring = &recv_ctx->sds_rings[ring];
+
+               if (ring == 0) {
+                       hwctx->sts_ring_addr = cpu_to_le64(sds_ring->phys_addr);
+                       hwctx->sts_ring_size = cpu_to_le32(sds_ring->num_desc);
+               }
+               hwctx->sts_rings[ring].addr = cpu_to_le64(sds_ring->phys_addr);
+               hwctx->sts_rings[ring].size = cpu_to_le32(sds_ring->num_desc);
+               hwctx->sts_rings[ring].msi_index = cpu_to_le16(ring);
+       }
+       hwctx->sts_ring_count = cpu_to_le32(adapter->max_sds_rings);
+
+       signature = (adapter->max_sds_rings > 1) ?
+               NETXEN_CTX_SIGNATURE_V2 : NETXEN_CTX_SIGNATURE;
+
+       NXWR32(adapter, CRB_CTX_ADDR_REG_LO(port),
+                       lower32(recv_ctx->phys_addr));
+       NXWR32(adapter, CRB_CTX_ADDR_REG_HI(port),
+                       upper32(recv_ctx->phys_addr));
+       NXWR32(adapter, CRB_CTX_SIGNATURE_REG(port),
+                       signature | port);
        return 0;
 }
 
-static uint32_t sw_int_mask[4] = {
-       CRB_SW_INT_MASK_0, CRB_SW_INT_MASK_1,
-       CRB_SW_INT_MASK_2, CRB_SW_INT_MASK_3
-};
-
 int netxen_alloc_hw_resources(struct netxen_adapter *adapter)
 {
-       struct netxen_hardware_context *hw = &adapter->ahw;
-       u32 state = 0;
        void *addr;
        int err = 0;
        int ring;
        struct netxen_recv_context *recv_ctx;
        struct nx_host_rds_ring *rds_ring;
        struct nx_host_sds_ring *sds_ring;
+       struct nx_host_tx_ring *tx_ring;
 
        struct pci_dev *pdev = adapter->pdev;
        struct net_device *netdev = adapter->netdev;
+       int port = adapter->portnum;
 
-       err = netxen_receive_peg_ready(adapter);
-       if (err) {
-               printk(KERN_ERR "Rcv Peg initialization not complete:%x.\n",
-                               state);
-               return err;
-       }
+       recv_ctx = &adapter->recv_ctx;
+       tx_ring = adapter->tx_ring;
 
        addr = pci_alloc_consistent(pdev,
                        sizeof(struct netxen_ring_ctx) + sizeof(uint32_t),
-                       &adapter->ctx_desc_phys_addr);
-
+                       &recv_ctx->phys_addr);
        if (addr == NULL) {
                dev_err(&pdev->dev, "failed to allocate hw context\n");
                return -ENOMEM;
        }
+
        memset(addr, 0, sizeof(struct netxen_ring_ctx));
-       adapter->ctx_desc = (struct netxen_ring_ctx *)addr;
-       adapter->ctx_desc->ctx_id = cpu_to_le32(adapter->portnum);
-       adapter->ctx_desc->cmd_consumer_offset =
-               cpu_to_le64(adapter->ctx_desc_phys_addr +
+       recv_ctx->hwctx = (struct netxen_ring_ctx *)addr;
+       recv_ctx->hwctx->ctx_id = cpu_to_le32(port);
+       recv_ctx->hwctx->cmd_consumer_offset =
+               cpu_to_le64(recv_ctx->phys_addr +
                        sizeof(struct netxen_ring_ctx));
-       adapter->cmd_consumer =
+       tx_ring->hw_consumer =
                (__le32 *)(((char *)addr) + sizeof(struct netxen_ring_ctx));
 
        /* cmd desc ring */
-       addr = pci_alloc_consistent(pdev,
-                       TX_DESC_RINGSIZE(adapter),
-                       &hw->cmd_desc_phys_addr);
+       addr = pci_alloc_consistent(pdev, TX_DESC_RINGSIZE(tx_ring),
+                       &tx_ring->phys_addr);
 
        if (addr == NULL) {
                dev_err(&pdev->dev, "%s: failed to allocate tx desc ring\n",
@@ -582,9 +631,7 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter)
                return -ENOMEM;
        }
 
-       hw->cmd_desc_head = (struct cmd_desc_type0 *)addr;
-
-       recv_ctx = &adapter->recv_ctx;
+       tx_ring->desc_head = (struct cmd_desc_type0 *)addr;
 
        for (ring = 0; ring < adapter->max_rds_rings; ring++) {
                rds_ring = &recv_ctx->rds_rings[ring];
@@ -602,8 +649,7 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter)
 
                if (adapter->fw_major < 4)
                        rds_ring->crb_rcv_producer =
-                               recv_crb_registers[adapter->portnum].
-                               crb_rcv_producer[ring];
+                               recv_crb_registers[port].crb_rcv_producer[ring];
        }
 
        for (ring = 0; ring < adapter->max_sds_rings; ring++) {
@@ -620,13 +666,16 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter)
                        goto err_out_free;
                }
                sds_ring->desc_head = (struct status_desc *)addr;
+
+               sds_ring->crb_sts_consumer =
+                       recv_crb_registers[port].crb_sts_consumer[ring];
+
+               sds_ring->crb_intr_mask =
+                       recv_crb_registers[port].sw_int_mask[ring];
        }
 
 
        if (adapter->fw_major >= 4) {
-               adapter->intr_scheme = INTR_SCHEME_PERPORT;
-               adapter->msi_mode = MSI_MODE_MULTIFUNC;
-
                err = nx_fw_cmd_create_rx_ctx(adapter);
                if (err)
                        goto err_out_free;
@@ -634,23 +683,11 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter)
                if (err)
                        goto err_out_free;
        } else {
-               sds_ring = &recv_ctx->sds_rings[0];
-               sds_ring->crb_sts_consumer =
-                       recv_crb_registers[adapter->portnum].crb_sts_consumer;
-
-               adapter->intr_scheme = adapter->pci_read_normalize(adapter,
-                               CRB_NIC_CAPABILITIES_FW);
-               adapter->msi_mode = adapter->pci_read_normalize(adapter,
-                               CRB_NIC_MSI_MODE_FW);
-               recv_ctx->sds_rings[0].crb_intr_mask =
-                               sw_int_mask[adapter->portnum];
-
                err = netxen_init_old_ctx(adapter);
                if (err) {
                        netxen_free_hw_resources(adapter);
                        return err;
                }
-
        }
 
        return 0;
@@ -665,32 +702,40 @@ void netxen_free_hw_resources(struct netxen_adapter *adapter)
        struct netxen_recv_context *recv_ctx;
        struct nx_host_rds_ring *rds_ring;
        struct nx_host_sds_ring *sds_ring;
+       struct nx_host_tx_ring *tx_ring;
        int ring;
 
+       int port = adapter->portnum;
+
        if (adapter->fw_major >= 4) {
                nx_fw_cmd_destroy_tx_ctx(adapter);
                nx_fw_cmd_destroy_rx_ctx(adapter);
+       } else {
+               netxen_api_lock(adapter);
+               NXWR32(adapter, CRB_CTX_SIGNATURE_REG(port),
+                               NETXEN_CTX_RESET | port);
+               netxen_api_unlock(adapter);
        }
 
-       if (adapter->ctx_desc != NULL) {
+       recv_ctx = &adapter->recv_ctx;
+
+       if (recv_ctx->hwctx != NULL) {
                pci_free_consistent(adapter->pdev,
                                sizeof(struct netxen_ring_ctx) +
                                sizeof(uint32_t),
-                               adapter->ctx_desc,
-                               adapter->ctx_desc_phys_addr);
-               adapter->ctx_desc = NULL;
+                               recv_ctx->hwctx,
+                               recv_ctx->phys_addr);
+               recv_ctx->hwctx = NULL;
        }
 
-       if (adapter->ahw.cmd_desc_head != NULL) {
+       tx_ring = adapter->tx_ring;
+       if (tx_ring->desc_head != NULL) {
                pci_free_consistent(adapter->pdev,
-                               sizeof(struct cmd_desc_type0) *
-                               adapter->num_txd,
-                               adapter->ahw.cmd_desc_head,
-                               adapter->ahw.cmd_desc_phys_addr);
-               adapter->ahw.cmd_desc_head = NULL;
+                               TX_DESC_RINGSIZE(tx_ring),
+                               tx_ring->desc_head, tx_ring->phys_addr);
+               tx_ring->desc_head = NULL;
        }
 
-       recv_ctx = &adapter->recv_ctx;
        for (ring = 0; ring < adapter->max_rds_rings; ring++) {
                rds_ring = &recv_ctx->rds_rings[ring];
 
index a677ff8951844e3451a6f5d6b93d67aa38322796..e16ea46c24b89bf89a685b260b45e01261823755 100644 (file)
@@ -30,7 +30,6 @@
 
 #include <linux/types.h>
 #include <linux/delay.h>
-#include <asm/uaccess.h>
 #include <linux/pci.h>
 #include <asm/io.h>
 #include <linux/netdevice.h>
@@ -53,13 +52,9 @@ struct netxen_nic_stats {
 #define NETXEN_NIC_INVALID_DATA 0xDEADBEEF
 
 static const struct netxen_nic_stats netxen_nic_gstrings_stats[] = {
-       {"rcvd_bad_skb", NETXEN_NIC_STAT(stats.rcvdbadskb)},
        {"xmit_called", NETXEN_NIC_STAT(stats.xmitcalled)},
-       {"xmited_frames", NETXEN_NIC_STAT(stats.xmitedframes)},
        {"xmit_finished", NETXEN_NIC_STAT(stats.xmitfinished)},
-       {"bad_skb_len", NETXEN_NIC_STAT(stats.badskblen)},
-       {"no_cmd_desc", NETXEN_NIC_STAT(stats.nocmddescriptor)},
-       {"polled", NETXEN_NIC_STAT(stats.polled)},
+       {"rx_dropped", NETXEN_NIC_STAT(stats.rxdropped)},
        {"tx_dropped", NETXEN_NIC_STAT(stats.txdropped)},
        {"csummed", NETXEN_NIC_STAT(stats.csummed)},
        {"no_rcv", NETXEN_NIC_STAT(stats.no_rcv)},
@@ -97,12 +92,9 @@ netxen_nic_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo)
        strncpy(drvinfo->driver, netxen_nic_driver_name, 32);
        strncpy(drvinfo->version, NETXEN_NIC_LINUX_VERSIONID, 32);
        write_lock_irqsave(&adapter->adapter_lock, flags);
-       fw_major = adapter->pci_read_normalize(adapter,
-                                       NETXEN_FW_VERSION_MAJOR);
-       fw_minor = adapter->pci_read_normalize(adapter,
-                                       NETXEN_FW_VERSION_MINOR);
-       fw_build = adapter->pci_read_normalize(adapter,
-                                       NETXEN_FW_VERSION_SUB);
+       fw_major = NXRD32(adapter, NETXEN_FW_VERSION_MAJOR);
+       fw_minor = NXRD32(adapter, NETXEN_FW_VERSION_MINOR);
+       fw_build = NXRD32(adapter, NETXEN_FW_VERSION_SUB);
        write_unlock_irqrestore(&adapter->adapter_lock, flags);
        sprintf(drvinfo->fw_version, "%d.%d.%d", fw_major, fw_minor, fw_build);
 
@@ -115,6 +107,7 @@ static int
 netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 {
        struct netxen_adapter *adapter = netdev_priv(dev);
+       int check_sfp_module = 0;
 
        /* read which mode */
        if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
@@ -139,7 +132,7 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
        } else if (adapter->ahw.port_type == NETXEN_NIC_XGBE) {
                u32 val;
 
-               adapter->hw_read_wx(adapter, NETXEN_PORT_MODE_ADDR, &val, 4);
+               val = NXRD32(adapter, NETXEN_PORT_MODE_ADDR);
                if (val == NETXEN_PORT_MODE_802_3_AP) {
                        ecmd->supported = SUPPORTED_1000baseT_Full;
                        ecmd->advertising = ADVERTISED_1000baseT_Full;
@@ -148,13 +141,19 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
                        ecmd->advertising = ADVERTISED_10000baseT_Full;
                }
 
+               if (netif_running(dev) && adapter->has_link_events) {
+                       ecmd->speed = adapter->link_speed;
+                       ecmd->autoneg = adapter->link_autoneg;
+                       ecmd->duplex = adapter->link_duplex;
+                       goto skip;
+               }
+
                ecmd->port = PORT_TP;
 
                if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
                        u16 pcifn = adapter->ahw.pci_func;
 
-                       adapter->hw_read_wx(adapter,
-                               P3_LINK_SPEED_REG(pcifn), &val, 4);
+                       val = NXRD32(adapter, P3_LINK_SPEED_REG(pcifn));
                        ecmd->speed = P3_LINK_SPEED_MHZ *
                                        P3_LINK_SPEED_VAL(pcifn, val);
                } else
@@ -165,10 +164,11 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
        } else
                return -EIO;
 
+skip:
        ecmd->phy_address = adapter->physical_port;
        ecmd->transceiver = XCVR_EXTERNAL;
 
-       switch ((netxen_brdtype_t)adapter->ahw.board_type) {
+       switch (adapter->ahw.board_type) {
        case NETXEN_BRDTYPE_P2_SB35_4G:
        case NETXEN_BRDTYPE_P2_SB31_2G:
        case NETXEN_BRDTYPE_P3_REF_QG:
@@ -195,7 +195,7 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
        case NETXEN_BRDTYPE_P3_HMEZ:
                ecmd->supported |= SUPPORTED_MII;
                ecmd->advertising |= ADVERTISED_MII;
-               ecmd->port = PORT_FIBRE;
+               ecmd->port = PORT_MII;
                ecmd->autoneg = AUTONEG_DISABLE;
                break;
        case NETXEN_BRDTYPE_P3_10G_SFP_PLUS:
@@ -203,6 +203,8 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
        case NETXEN_BRDTYPE_P3_10G_SFP_QT:
                ecmd->advertising |= ADVERTISED_TP;
                ecmd->supported |= SUPPORTED_TP;
+               check_sfp_module = netif_running(dev) &&
+                       adapter->has_link_events;
        case NETXEN_BRDTYPE_P2_SB31_10G:
        case NETXEN_BRDTYPE_P3_10G_XFP:
                ecmd->supported |= SUPPORTED_FIBRE;
@@ -217,6 +219,8 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
                        ecmd->advertising |=
                                (ADVERTISED_FIBRE | ADVERTISED_TP);
                        ecmd->port = PORT_FIBRE;
+                       check_sfp_module = netif_running(dev) &&
+                               adapter->has_link_events;
                } else {
                        ecmd->autoneg = AUTONEG_ENABLE;
                        ecmd->supported |= (SUPPORTED_TP |SUPPORTED_Autoneg);
@@ -227,10 +231,28 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
                break;
        default:
                printk(KERN_ERR "netxen-nic: Unsupported board model %d\n",
-                      (netxen_brdtype_t)adapter->ahw.board_type);
+                               adapter->ahw.board_type);
                return -EIO;
        }
 
+       if (check_sfp_module) {
+               switch (adapter->module_type) {
+               case LINKEVENT_MODULE_OPTICAL_UNKNOWN:
+               case LINKEVENT_MODULE_OPTICAL_SRLR:
+               case LINKEVENT_MODULE_OPTICAL_LRM:
+               case LINKEVENT_MODULE_OPTICAL_SFP_1G:
+                       ecmd->port = PORT_FIBRE;
+                       break;
+               case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLE:
+               case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLELEN:
+               case LINKEVENT_MODULE_TWINAX:
+                       ecmd->port = PORT_TP;
+                       break;
+               default:
+                       ecmd->port = -1;
+               }
+       }
+
        return 0;
 }
 
@@ -398,12 +420,11 @@ netxen_nic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)
        regs->version = (1 << 24) | (adapter->ahw.revision_id << 16) |
            (adapter->pdev)->device;
        /* which mode */
-       adapter->hw_read_wx(adapter, NETXEN_NIU_MODE, &regs_buff[0], 4);
+       regs_buff[0] = NXRD32(adapter, NETXEN_NIU_MODE);
        mode = regs_buff[0];
 
        /* Common registers to all the modes */
-       adapter->hw_read_wx(adapter,
-                       NETXEN_NIU_STRAP_VALUE_SAVE_HIGHER, &regs_buff[2], 4);
+       regs_buff[2] = NXRD32(adapter, NETXEN_NIU_STRAP_VALUE_SAVE_HIGHER);
        /* GB/XGB Mode */
        mode = (mode / 2) - 1;
        window = 0;
@@ -414,9 +435,8 @@ netxen_nic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)
                                window = adapter->physical_port *
                                        NETXEN_NIC_PORT_WINDOW;
 
-                       adapter->hw_read_wx(adapter,
-                               niu_registers[mode].reg[i - 3] + window,
-                               &regs_buff[i], 4);
+                       regs_buff[i] = NXRD32(adapter,
+                               niu_registers[mode].reg[i - 3] + window);
                }
 
        }
@@ -440,7 +460,7 @@ static u32 netxen_nic_test_link(struct net_device *dev)
                        return !val;
                }
        } else if (adapter->ahw.port_type == NETXEN_NIC_XGBE) {
-               val = adapter->pci_read_normalize(adapter, CRB_XG_STATE);
+               val = NXRD32(adapter, CRB_XG_STATE);
                return (val == XG_LINK_UP) ? 0 : 1;
        }
        return -EIO;
@@ -504,10 +524,9 @@ netxen_nic_get_pauseparam(struct net_device *dev,
                if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS))
                        return;
                /* get flow control settings */
-               netxen_nic_read_w0(adapter,NETXEN_NIU_GB_MAC_CONFIG_0(port),
-                               &val);
+               val = NXRD32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port));
                pause->rx_pause = netxen_gb_get_rx_flowctl(val);
-               netxen_nic_read_w0(adapter, NETXEN_NIU_GB_PAUSE_CTL, &val);
+               val = NXRD32(adapter, NETXEN_NIU_GB_PAUSE_CTL);
                switch (port) {
                        case 0:
                                pause->tx_pause = !(netxen_gb_get_gb0_mask(val));
@@ -527,7 +546,7 @@ netxen_nic_get_pauseparam(struct net_device *dev,
                if ((port < 0) || (port > NETXEN_NIU_MAX_XG_PORTS))
                        return;
                pause->rx_pause = 1;
-               netxen_nic_read_w0(adapter, NETXEN_NIU_XG_PAUSE_CTL, &val);
+               val = NXRD32(adapter, NETXEN_NIU_XG_PAUSE_CTL);
                if (port == 0)
                        pause->tx_pause = !(netxen_xg_get_xg0_mask(val));
                else
@@ -550,18 +569,17 @@ netxen_nic_set_pauseparam(struct net_device *dev,
                if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS))
                        return -EIO;
                /* set flow control */
-               netxen_nic_read_w0(adapter,
-                                       NETXEN_NIU_GB_MAC_CONFIG_0(port), &val);
+               val = NXRD32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port));
 
                if (pause->rx_pause)
                        netxen_gb_rx_flowctl(val);
                else
                        netxen_gb_unset_rx_flowctl(val);
 
-               netxen_nic_write_w0(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
+               NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
                                val);
                /* set autoneg */
-               netxen_nic_read_w0(adapter, NETXEN_NIU_GB_PAUSE_CTL, &val);
+               val = NXRD32(adapter, NETXEN_NIU_GB_PAUSE_CTL);
                switch (port) {
                        case 0:
                                if (pause->tx_pause)
@@ -589,11 +607,11 @@ netxen_nic_set_pauseparam(struct net_device *dev,
                                        netxen_gb_set_gb3_mask(val);
                                break;
                }
-               netxen_nic_write_w0(adapter, NETXEN_NIU_GB_PAUSE_CTL, val);
+               NXWR32(adapter, NETXEN_NIU_GB_PAUSE_CTL, val);
        } else if (adapter->ahw.port_type == NETXEN_NIC_XGBE) {
                if ((port < 0) || (port > NETXEN_NIU_MAX_XG_PORTS))
                        return -EIO;
-               netxen_nic_read_w0(adapter, NETXEN_NIU_XG_PAUSE_CTL, &val);
+               val = NXRD32(adapter, NETXEN_NIU_XG_PAUSE_CTL);
                if (port == 0) {
                        if (pause->tx_pause)
                                netxen_xg_unset_xg0_mask(val);
@@ -605,7 +623,7 @@ netxen_nic_set_pauseparam(struct net_device *dev,
                        else
                                netxen_xg_set_xg1_mask(val);
                }
-               netxen_nic_write_w0(adapter, NETXEN_NIU_XG_PAUSE_CTL, val);
+               NXWR32(adapter, NETXEN_NIU_XG_PAUSE_CTL, val);
        } else {
                printk(KERN_ERR "%s: Unknown board type: %x\n",
                                netxen_nic_driver_name,
@@ -619,14 +637,14 @@ static int netxen_nic_reg_test(struct net_device *dev)
        struct netxen_adapter *adapter = netdev_priv(dev);
        u32 data_read, data_written;
 
-       netxen_nic_read_w0(adapter, NETXEN_PCIX_PH_REG(0), &data_read);
+       data_read = NXRD32(adapter, NETXEN_PCIX_PH_REG(0));
        if ((data_read & 0xffff) != PHAN_VENDOR_ID)
        return 1;
 
        data_written = (u32)0xa5a5a5a5;
 
-       netxen_nic_reg_write(adapter, CRB_SCRATCHPAD_TEST, data_written);
-       data_read = adapter->pci_read_normalize(adapter, CRB_SCRATCHPAD_TEST);
+       NXWR32(adapter, CRB_SCRATCHPAD_TEST, data_written);
+       data_read = NXRD32(adapter, CRB_SCRATCHPAD_TEST);
        if (data_written != data_read)
                return 1;
 
@@ -743,11 +761,11 @@ netxen_nic_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
        if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
                return;
 
-       wol_cfg = netxen_nic_reg_read(adapter, NETXEN_WOL_CONFIG_NV);
+       wol_cfg = NXRD32(adapter, NETXEN_WOL_CONFIG_NV);
        if (wol_cfg & (1UL << adapter->portnum))
                wol->supported |= WAKE_MAGIC;
 
-       wol_cfg = netxen_nic_reg_read(adapter, NETXEN_WOL_CONFIG);
+       wol_cfg = NXRD32(adapter, NETXEN_WOL_CONFIG);
        if (wol_cfg & (1UL << adapter->portnum))
                wol->wolopts |= WAKE_MAGIC;
 }
@@ -764,16 +782,16 @@ netxen_nic_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
        if (wol->wolopts & ~WAKE_MAGIC)
                return -EOPNOTSUPP;
 
-       wol_cfg = netxen_nic_reg_read(adapter, NETXEN_WOL_CONFIG_NV);
+       wol_cfg = NXRD32(adapter, NETXEN_WOL_CONFIG_NV);
        if (!(wol_cfg & (1 << adapter->portnum)))
                return -EOPNOTSUPP;
 
-       wol_cfg = netxen_nic_reg_read(adapter, NETXEN_WOL_CONFIG);
+       wol_cfg = NXRD32(adapter, NETXEN_WOL_CONFIG);
        if (wol->wolopts & WAKE_MAGIC)
                wol_cfg |= 1UL << adapter->portnum;
        else
                wol_cfg &= ~(1UL << adapter->portnum);
-       netxen_nic_reg_write(adapter, NETXEN_WOL_CONFIG, wol_cfg);
+       NXWR32(adapter, NETXEN_WOL_CONFIG, wol_cfg);
 
        return 0;
 }
index 016c62129c766c2cf9ef9415c381fa7eacacbac5..7f0ddbfa7b2839299efce81963180e78b5a825d9 100644 (file)
 #ifndef __NETXEN_NIC_HDR_H_
 #define __NETXEN_NIC_HDR_H_
 
-#include <linux/module.h>
 #include <linux/kernel.h>
-#include <linux/spinlock.h>
-#include <asm/irq.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/pci.h>
 #include <linux/types.h>
-#include <asm/uaccess.h>
-#include <asm/string.h>                /* for memset */
 
 /*
  * The basic unit of access when reading/writing control registers.
index 5026811c04ced0a1d1d4effe7dc033c47d083dba..42ffb825ebf1aa011aa431cfcf28d94d64e0f936 100644 (file)
@@ -32,7 +32,6 @@
 #include "netxen_nic_hw.h"
 #include "netxen_nic_phan_reg.h"
 
-#include <linux/firmware.h>
 #include <net/ip.h>
 
 #define MASK(n) ((1ULL<<(n))-1)
 #define CRB_HI(off)    ((crb_hub_agt[CRB_BLK(off)] << 20) | ((off) & 0xf0000))
 #define CRB_INDIRECT_2M        (0x1e0000UL)
 
+#ifndef readq
+static inline u64 readq(void __iomem *addr)
+{
+       return readl(addr) | (((u64) readl(addr + 4)) << 32LL);
+}
+#endif
+
+#ifndef writeq
+static inline void writeq(u64 val, void __iomem *addr)
+{
+       writel(((u32) (val)), (addr));
+       writel(((u32) (val >> 32)), (addr + 4));
+}
+#endif
+
+#define ADDR_IN_RANGE(addr, low, high) \
+       (((addr) < (high)) && ((addr) >= (low)))
+
+#define PCI_OFFSET_FIRST_RANGE(adapter, off)    \
+       ((adapter)->ahw.pci_base0 + (off))
+#define PCI_OFFSET_SECOND_RANGE(adapter, off)   \
+       ((adapter)->ahw.pci_base1 + (off) - SECOND_PAGE_GROUP_START)
+#define PCI_OFFSET_THIRD_RANGE(adapter, off)    \
+       ((adapter)->ahw.pci_base2 + (off) - THIRD_PAGE_GROUP_START)
+
+static void __iomem *pci_base_offset(struct netxen_adapter *adapter,
+                                           unsigned long off)
+{
+       if (ADDR_IN_RANGE(off, FIRST_PAGE_GROUP_START, FIRST_PAGE_GROUP_END))
+               return PCI_OFFSET_FIRST_RANGE(adapter, off);
+
+       if (ADDR_IN_RANGE(off, SECOND_PAGE_GROUP_START, SECOND_PAGE_GROUP_END))
+               return PCI_OFFSET_SECOND_RANGE(adapter, off);
+
+       if (ADDR_IN_RANGE(off, THIRD_PAGE_GROUP_START, THIRD_PAGE_GROUP_END))
+               return PCI_OFFSET_THIRD_RANGE(adapter, off);
+
+       return NULL;
+}
+
 #define CRB_WIN_LOCK_TIMEOUT 100000000
-static crb_128M_2M_block_map_t crb_128M_2M_map[64] = {
+static crb_128M_2M_block_map_t
+crb_128M_2M_map[64] __cacheline_aligned_in_smp = {
     {{{0, 0,         0,         0} } },                /* 0: PCI */
     {{{1, 0x0100000, 0x0102000, 0x120000},     /* 1: PCIE */
          {1, 0x0110000, 0x0120000, 0x130000},
@@ -279,39 +319,8 @@ static unsigned crb_hub_agt[64] =
 
 /*  PCI Windowing for DDR regions.  */
 
-#define ADDR_IN_RANGE(addr, low, high) \
-       (((addr) <= (high)) && ((addr) >= (low)))
-
 #define NETXEN_WINDOW_ONE      0x2000000 /*CRB Window: bit 25 of CRB address */
 
-#define NETXEN_NIC_ZERO_PAUSE_ADDR     0ULL
-#define NETXEN_NIC_UNIT_PAUSE_ADDR     0x200ULL
-#define NETXEN_NIC_EPG_PAUSE_ADDR1     0x2200010000c28001ULL
-#define NETXEN_NIC_EPG_PAUSE_ADDR2     0x0100088866554433ULL
-
-#define NETXEN_NIC_WINDOW_MARGIN 0x100000
-
-int netxen_nic_set_mac(struct net_device *netdev, void *p)
-{
-       struct netxen_adapter *adapter = netdev_priv(netdev);
-       struct sockaddr *addr = p;
-
-       if (netif_running(netdev))
-               return -EBUSY;
-
-       if (!is_valid_ether_addr(addr->sa_data))
-               return -EADDRNOTAVAIL;
-
-       memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
-
-       /* For P3, MAC addr is not set in NIU */
-       if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
-               if (adapter->macaddr_set)
-                       adapter->macaddr_set(adapter, addr->sa_data);
-
-       return 0;
-}
-
 #define NETXEN_UNICAST_ADDR(port, index) \
        (NETXEN_UNICAST_ADDR_BASE+(port*32)+(index*8))
 #define NETXEN_MCAST_ADDR(port, index) \
@@ -331,22 +340,20 @@ netxen_nic_enable_mcast_filter(struct netxen_adapter *adapter)
        if (adapter->mc_enabled)
                return 0;
 
-       adapter->hw_read_wx(adapter, NETXEN_MAC_ADDR_CNTL_REG, &val, 4);
+       val = NXRD32(adapter, NETXEN_MAC_ADDR_CNTL_REG);
        val |= (1UL << (28+port));
-       adapter->hw_write_wx(adapter, NETXEN_MAC_ADDR_CNTL_REG, &val, 4);
+       NXWR32(adapter, NETXEN_MAC_ADDR_CNTL_REG, val);
 
        /* add broadcast addr to filter */
        val = 0xffffff;
-       netxen_crb_writelit_adapter(adapter, NETXEN_UNICAST_ADDR(port, 0), val);
-       netxen_crb_writelit_adapter(adapter,
-                       NETXEN_UNICAST_ADDR(port, 0)+4, val);
+       NXWR32(adapter, NETXEN_UNICAST_ADDR(port, 0), val);
+       NXWR32(adapter, NETXEN_UNICAST_ADDR(port, 0)+4, val);
 
        /* add station addr to filter */
        val = MAC_HI(addr);
-       netxen_crb_writelit_adapter(adapter, NETXEN_UNICAST_ADDR(port, 1), val);
+       NXWR32(adapter, NETXEN_UNICAST_ADDR(port, 1), val);
        val = MAC_LO(addr);
-       netxen_crb_writelit_adapter(adapter,
-                       NETXEN_UNICAST_ADDR(port, 1)+4, val);
+       NXWR32(adapter, NETXEN_UNICAST_ADDR(port, 1)+4, val);
 
        adapter->mc_enabled = 1;
        return 0;
@@ -362,18 +369,17 @@ netxen_nic_disable_mcast_filter(struct netxen_adapter *adapter)
        if (!adapter->mc_enabled)
                return 0;
 
-       adapter->hw_read_wx(adapter, NETXEN_MAC_ADDR_CNTL_REG, &val, 4);
+       val = NXRD32(adapter, NETXEN_MAC_ADDR_CNTL_REG);
        val &= ~(1UL << (28+port));
-       adapter->hw_write_wx(adapter, NETXEN_MAC_ADDR_CNTL_REG, &val, 4);
+       NXWR32(adapter, NETXEN_MAC_ADDR_CNTL_REG, val);
 
        val = MAC_HI(addr);
-       netxen_crb_writelit_adapter(adapter, NETXEN_UNICAST_ADDR(port, 0), val);
+       NXWR32(adapter, NETXEN_UNICAST_ADDR(port, 0), val);
        val = MAC_LO(addr);
-       netxen_crb_writelit_adapter(adapter,
-                       NETXEN_UNICAST_ADDR(port, 0)+4, val);
+       NXWR32(adapter, NETXEN_UNICAST_ADDR(port, 0)+4, val);
 
-       netxen_crb_writelit_adapter(adapter, NETXEN_UNICAST_ADDR(port, 1), 0);
-       netxen_crb_writelit_adapter(adapter, NETXEN_UNICAST_ADDR(port, 1)+4, 0);
+       NXWR32(adapter, NETXEN_UNICAST_ADDR(port, 1), 0);
+       NXWR32(adapter, NETXEN_UNICAST_ADDR(port, 1)+4, 0);
 
        adapter->mc_enabled = 0;
        return 0;
@@ -389,10 +395,8 @@ netxen_nic_set_mcast_addr(struct netxen_adapter *adapter,
        lo = MAC_LO(addr);
        hi = MAC_HI(addr);
 
-       netxen_crb_writelit_adapter(adapter,
-                       NETXEN_MCAST_ADDR(port, index), hi);
-       netxen_crb_writelit_adapter(adapter,
-                       NETXEN_MCAST_ADDR(port, index)+4, lo);
+       NXWR32(adapter, NETXEN_MCAST_ADDR(port, index), hi);
+       NXWR32(adapter, NETXEN_MCAST_ADDR(port, index)+4, lo);
 
        return 0;
 }
@@ -445,100 +449,58 @@ void netxen_p2_nic_set_multi(struct net_device *netdev)
                netxen_nic_set_mcast_addr(adapter, index, null_addr);
 }
 
-static int nx_p3_nic_add_mac(struct netxen_adapter *adapter,
-               u8 *addr, nx_mac_list_t **add_list, nx_mac_list_t **del_list)
-{
-       nx_mac_list_t *cur, *prev;
-
-       /* if in del_list, move it to adapter->mac_list */
-       for (cur = *del_list, prev = NULL; cur;) {
-               if (memcmp(addr, cur->mac_addr, ETH_ALEN) == 0) {
-                       if (prev == NULL)
-                               *del_list = cur->next;
-                       else
-                               prev->next = cur->next;
-                       cur->next = adapter->mac_list;
-                       adapter->mac_list = cur;
-                       return 0;
-               }
-               prev = cur;
-               cur = cur->next;
-       }
-
-       /* make sure to add each mac address only once */
-       for (cur = adapter->mac_list; cur; cur = cur->next) {
-               if (memcmp(addr, cur->mac_addr, ETH_ALEN) == 0)
-                       return 0;
-       }
-       /* not in del_list, create new entry and add to add_list */
-       cur = kmalloc(sizeof(*cur), in_atomic()? GFP_ATOMIC : GFP_KERNEL);
-       if (cur == NULL) {
-               printk(KERN_ERR "%s: cannot allocate memory. MAC filtering may"
-                               "not work properly from now.\n", __func__);
-               return -1;
-       }
-
-       memcpy(cur->mac_addr, addr, ETH_ALEN);
-       cur->next = *add_list;
-       *add_list = cur;
-       return 0;
-}
-
 static int
 netxen_send_cmd_descs(struct netxen_adapter *adapter,
-               struct cmd_desc_type0 *cmd_desc_arr, int nr_elements)
+               struct cmd_desc_type0 *cmd_desc_arr, int nr_desc)
 {
-       uint32_t i, producer;
+       u32 i, producer, consumer;
        struct netxen_cmd_buffer *pbuf;
        struct cmd_desc_type0 *cmd_desc;
-
-       if (nr_elements > MAX_PENDING_DESC_BLOCK_SIZE || nr_elements == 0) {
-               printk(KERN_WARNING "%s: Too many command descriptors in a "
-                             "request\n", __func__);
-               return -EINVAL;
-       }
+       struct nx_host_tx_ring *tx_ring;
 
        i = 0;
 
+       tx_ring = adapter->tx_ring;
        netif_tx_lock_bh(adapter->netdev);
 
-       producer = adapter->cmd_producer;
+       producer = tx_ring->producer;
+       consumer = tx_ring->sw_consumer;
+
+       if (nr_desc >= find_diff_among(producer, consumer, tx_ring->num_desc)) {
+               netif_tx_unlock_bh(adapter->netdev);
+               return -EBUSY;
+       }
+
        do {
                cmd_desc = &cmd_desc_arr[i];
 
-               pbuf = &adapter->cmd_buf_arr[producer];
+               pbuf = &tx_ring->cmd_buf_arr[producer];
                pbuf->skb = NULL;
                pbuf->frag_count = 0;
 
-               /* adapter->ahw.cmd_desc_head[producer] = *cmd_desc; */
-               memcpy(&adapter->ahw.cmd_desc_head[producer],
+               memcpy(&tx_ring->desc_head[producer],
                        &cmd_desc_arr[i], sizeof(struct cmd_desc_type0));
 
-               producer = get_next_index(producer,
-                               adapter->num_txd);
+               producer = get_next_index(producer, tx_ring->num_desc);
                i++;
 
-       } while (i != nr_elements);
-
-       adapter->cmd_producer = producer;
+       } while (i != nr_desc);
 
-       /* write producer index to start the xmit */
+       tx_ring->producer = producer;
 
-       netxen_nic_update_cmd_producer(adapter, adapter->cmd_producer);
+       netxen_nic_update_cmd_producer(adapter, tx_ring, producer);
 
        netif_tx_unlock_bh(adapter->netdev);
 
        return 0;
 }
 
-static int nx_p3_sre_macaddr_change(struct net_device *dev,
-               u8 *addr, unsigned op)
+static int
+nx_p3_sre_macaddr_change(struct netxen_adapter *adapter, u8 *addr, unsigned op)
 {
-       struct netxen_adapter *adapter = netdev_priv(dev);
        nx_nic_req_t req;
        nx_mac_req_t *mac_req;
        u64 word;
-       int rv;
 
        memset(&req, 0, sizeof(nx_nic_req_t));
        req.qhdr = cpu_to_le64(NX_NIC_REQUEST << 23);
@@ -550,28 +512,51 @@ static int nx_p3_sre_macaddr_change(struct net_device *dev,
        mac_req->op = op;
        memcpy(mac_req->mac_addr, addr, 6);
 
-       rv = netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
-       if (rv != 0) {
-               printk(KERN_ERR "ERROR. Could not send mac update\n");
-               return rv;
+       return netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
+}
+
+static int nx_p3_nic_add_mac(struct netxen_adapter *adapter,
+               u8 *addr, struct list_head *del_list)
+{
+       struct list_head *head;
+       nx_mac_list_t *cur;
+
+       /* look up if already exists */
+       list_for_each(head, del_list) {
+               cur = list_entry(head, nx_mac_list_t, list);
+
+               if (memcmp(addr, cur->mac_addr, ETH_ALEN) == 0) {
+                       list_move_tail(head, &adapter->mac_list);
+                       return 0;
+               }
        }
 
-       return 0;
+       cur = kzalloc(sizeof(nx_mac_list_t), GFP_ATOMIC);
+       if (cur == NULL) {
+               printk(KERN_ERR "%s: failed to add mac address filter\n",
+                               adapter->netdev->name);
+               return -ENOMEM;
+       }
+       memcpy(cur->mac_addr, addr, ETH_ALEN);
+       list_add_tail(&cur->list, &adapter->mac_list);
+       return nx_p3_sre_macaddr_change(adapter,
+                               cur->mac_addr, NETXEN_MAC_ADD);
 }
 
 void netxen_p3_nic_set_multi(struct net_device *netdev)
 {
        struct netxen_adapter *adapter = netdev_priv(netdev);
-       nx_mac_list_t *cur, *next, *del_list, *add_list = NULL;
        struct dev_mc_list *mc_ptr;
        u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
        u32 mode = VPORT_MISS_MODE_DROP;
+       LIST_HEAD(del_list);
+       struct list_head *head;
+       nx_mac_list_t *cur;
 
-       del_list = adapter->mac_list;
-       adapter->mac_list = NULL;
+       list_splice_tail_init(&adapter->mac_list, &del_list);
 
-       nx_p3_nic_add_mac(adapter, netdev->dev_addr, &add_list, &del_list);
-       nx_p3_nic_add_mac(adapter, bcast_addr, &add_list, &del_list);
+       nx_p3_nic_add_mac(adapter, netdev->dev_addr, &del_list);
+       nx_p3_nic_add_mac(adapter, bcast_addr, &del_list);
 
        if (netdev->flags & IFF_PROMISC) {
                mode = VPORT_MISS_MODE_ACCEPT_ALL;
@@ -587,25 +572,20 @@ void netxen_p3_nic_set_multi(struct net_device *netdev)
        if (netdev->mc_count > 0) {
                for (mc_ptr = netdev->mc_list; mc_ptr;
                     mc_ptr = mc_ptr->next) {
-                       nx_p3_nic_add_mac(adapter, mc_ptr->dmi_addr,
-                                         &add_list, &del_list);
+                       nx_p3_nic_add_mac(adapter, mc_ptr->dmi_addr, &del_list);
                }
        }
 
 send_fw_cmd:
        adapter->set_promisc(adapter, mode);
-       for (cur = del_list; cur;) {
-               nx_p3_sre_macaddr_change(netdev, cur->mac_addr, NETXEN_MAC_DEL);
-               next = cur->next;
+       head = &del_list;
+       while (!list_empty(head)) {
+               cur = list_entry(head->next, nx_mac_list_t, list);
+
+               nx_p3_sre_macaddr_change(adapter,
+                               cur->mac_addr, NETXEN_MAC_DEL);
+               list_del(&cur->list);
                kfree(cur);
-               cur = next;
-       }
-       for (cur = add_list; cur;) {
-               nx_p3_sre_macaddr_change(netdev, cur->mac_addr, NETXEN_MAC_ADD);
-               next = cur->next;
-               cur->next = adapter->mac_list;
-               adapter->mac_list = cur;
-               cur = next;
        }
 }
 
@@ -630,17 +610,25 @@ int netxen_p3_nic_set_promisc(struct netxen_adapter *adapter, u32 mode)
 
 void netxen_p3_free_mac_list(struct netxen_adapter *adapter)
 {
-       nx_mac_list_t *cur, *next;
-
-       cur = adapter->mac_list;
-
-       while (cur) {
-               next = cur->next;
+       nx_mac_list_t *cur;
+       struct list_head *head = &adapter->mac_list;
+
+       while (!list_empty(head)) {
+               cur = list_entry(head->next, nx_mac_list_t, list);
+               nx_p3_sre_macaddr_change(adapter,
+                               cur->mac_addr, NETXEN_MAC_DEL);
+               list_del(&cur->list);
                kfree(cur);
-               cur = next;
        }
 }
 
+int netxen_p3_nic_set_mac_addr(struct netxen_adapter *adapter, u8 *addr)
+{
+       /* assuming caller has already copied new addr to netdev */
+       netxen_p3_nic_set_multi(adapter->netdev);
+       return 0;
+}
+
 #define        NETXEN_CONFIG_INTR_COALESCE     3
 
 /*
@@ -717,6 +705,28 @@ int netxen_config_rss(struct netxen_adapter *adapter, int enable)
        return rv;
 }
 
+int netxen_linkevent_request(struct netxen_adapter *adapter, int enable)
+{
+       nx_nic_req_t req;
+       u64 word;
+       int rv;
+
+       memset(&req, 0, sizeof(nx_nic_req_t));
+       req.qhdr = cpu_to_le64(NX_HOST_REQUEST << 23);
+
+       word = NX_NIC_H2C_OPCODE_GET_LINKEVENT | ((u64)adapter->portnum << 16);
+       req.req_hdr = cpu_to_le64(word);
+       req.words[0] = cpu_to_le64(enable | (enable << 8));
+
+       rv = netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
+       if (rv != 0) {
+               printk(KERN_ERR "%s: could not configure link notification\n",
+                               adapter->netdev->name);
+       }
+
+       return rv;
+}
+
 /*
  * netxen_nic_change_mtu - Change the Maximum Transfer Unit
  * @returns 0 on success, negative on failure
@@ -812,8 +822,8 @@ int netxen_p3_get_mac_addr(struct netxen_adapter *adapter, __le64 *mac)
        crbaddr = CRB_MAC_BLOCK_START +
                (4 * ((pci_func/2) * 3)) + (4 * (pci_func & 1));
 
-       adapter->hw_read_wx(adapter, crbaddr, &mac_lo, 4);
-       adapter->hw_read_wx(adapter, crbaddr+4, &mac_hi, 4);
+       mac_lo = NXRD32(adapter, crbaddr);
+       mac_hi = NXRD32(adapter, crbaddr+4);
 
        if (pci_func & 1)
                *mac = le64_to_cpu((mac_lo >> 16) | ((u64)mac_hi << 16));
@@ -831,8 +841,7 @@ static int crb_win_lock(struct netxen_adapter *adapter)
 
        while (!done) {
                /* acquire semaphore3 from PCI HW block */
-               adapter->hw_read_wx(adapter,
-                               NETXEN_PCIE_REG(PCIE_SEM7_LOCK), &done, 4);
+               done = NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM7_LOCK));
                if (done == 1)
                        break;
                if (timeout >= CRB_WIN_LOCK_TIMEOUT)
@@ -840,8 +849,7 @@ static int crb_win_lock(struct netxen_adapter *adapter)
                timeout++;
                udelay(1);
        }
-       netxen_crb_writelit_adapter(adapter,
-                       NETXEN_CRB_WIN_LOCK_ID, adapter->portnum);
+       NXWR32(adapter, NETXEN_CRB_WIN_LOCK_ID, adapter->portnum);
        return 0;
 }
 
@@ -849,8 +857,7 @@ static void crb_win_unlock(struct netxen_adapter *adapter)
 {
        int val;
 
-       adapter->hw_read_wx(adapter,
-                       NETXEN_PCIE_REG(PCIE_SEM7_UNLOCK), &val, 4);
+       val = NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM7_UNLOCK));
 }
 
 /*
@@ -907,17 +914,15 @@ netxen_nic_pci_change_crbwindow_128M(struct netxen_adapter *adapter, u32 wndw)
  * In: 'off' is offset from base in 128M pci map
  */
 static int
-netxen_nic_pci_get_crb_addr_2M(struct netxen_adapter *adapter,
-               ulong *off, int len)
+netxen_nic_pci_get_crb_addr_2M(struct netxen_adapter *adapter, ulong *off)
 {
-       unsigned long end = *off + len;
        crb_128M_2M_sub_block_map_t *m;
 
 
        if (*off >= NETXEN_CRB_MAX)
                return -1;
 
-       if (*off >= NETXEN_PCI_CAMQM && (end <= NETXEN_PCI_CAMQM_2M_END)) {
+       if (*off >= NETXEN_PCI_CAMQM && (*off < NETXEN_PCI_CAMQM_2M_END)) {
                *off = (*off - NETXEN_PCI_CAMQM) + NETXEN_PCI_CAMQM_2M_BASE +
                        (ulong)adapter->ahw.pci_base0;
                return 0;
@@ -927,14 +932,13 @@ netxen_nic_pci_get_crb_addr_2M(struct netxen_adapter *adapter,
                return -1;
 
        *off -= NETXEN_PCI_CRBSPACE;
-       end = *off + len;
 
        /*
         * Try direct map
         */
        m = &crb_128M_2M_map[CRB_BLK(*off)].sub_block[CRB_SUBBLK(*off)];
 
-       if (m->valid && (m->start_128M <= *off) && (m->end_128M >= end)) {
+       if (m->valid && (m->start_128M <= *off) && (m->end_128M > *off)) {
                *off = *off + m->start_2M - m->start_128M +
                        (ulong)adapter->ahw.pci_base0;
                return 0;
@@ -972,214 +976,11 @@ netxen_nic_pci_set_crbwindow_2M(struct netxen_adapter *adapter, ulong *off)
                (ulong)adapter->ahw.pci_base0;
 }
 
-static int
-netxen_do_load_firmware(struct netxen_adapter *adapter, const char *fwname,
-               const struct firmware *fw)
-{
-       u64 *ptr64;
-       u32 i, flashaddr, size;
-       struct pci_dev *pdev = adapter->pdev;
-
-       if (fw)
-               dev_info(&pdev->dev, "loading firmware from file %s\n", fwname);
-       else
-               dev_info(&pdev->dev, "loading firmware from flash\n");
-
-       if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
-               adapter->pci_write_normalize(adapter,
-                               NETXEN_ROMUSB_GLB_CAS_RST, 1);
-
-       if (fw) {
-               __le64 data;
-
-               size = (NETXEN_IMAGE_START - NETXEN_BOOTLD_START) / 8;
-
-               ptr64 = (u64 *)&fw->data[NETXEN_BOOTLD_START];
-               flashaddr = NETXEN_BOOTLD_START;
-
-               for (i = 0; i < size; i++) {
-                       data = cpu_to_le64(ptr64[i]);
-                       adapter->pci_mem_write(adapter, flashaddr, &data, 8);
-                       flashaddr += 8;
-               }
-
-               size = *(u32 *)&fw->data[NX_FW_SIZE_OFFSET];
-               size = (__force u32)cpu_to_le32(size) / 8;
-
-               ptr64 = (u64 *)&fw->data[NETXEN_IMAGE_START];
-               flashaddr = NETXEN_IMAGE_START;
-
-               for (i = 0; i < size; i++) {
-                       data = cpu_to_le64(ptr64[i]);
-
-                       if (adapter->pci_mem_write(adapter,
-                                               flashaddr, &data, 8))
-                               return -EIO;
-
-                       flashaddr += 8;
-               }
-       } else {
-               u32 data;
-
-               size = (NETXEN_IMAGE_START - NETXEN_BOOTLD_START) / 4;
-               flashaddr = NETXEN_BOOTLD_START;
-
-               for (i = 0; i < size; i++) {
-                       if (netxen_rom_fast_read(adapter,
-                                       flashaddr, (int *)&data) != 0)
-                               return -EIO;
-
-                       if (adapter->pci_mem_write(adapter,
-                                               flashaddr, &data, 4))
-                               return -EIO;
-
-                       flashaddr += 4;
-               }
-       }
-       msleep(1);
-
-       if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
-               adapter->pci_write_normalize(adapter,
-                               NETXEN_ROMUSB_GLB_SW_RESET, 0x80001d);
-       else {
-               adapter->pci_write_normalize(adapter,
-                               NETXEN_ROMUSB_GLB_CHIP_CLK_CTRL, 0x3fff);
-               adapter->pci_write_normalize(adapter,
-                               NETXEN_ROMUSB_GLB_CAS_RST, 0);
-       }
-
-       return 0;
-}
-
-static int
-netxen_validate_firmware(struct netxen_adapter *adapter, const char *fwname,
-               const struct firmware *fw)
-{
-       __le32 val;
-       u32 major, minor, build, ver, min_ver, bios;
-       struct pci_dev *pdev = adapter->pdev;
-
-       if (fw->size < NX_FW_MIN_SIZE)
-               return -EINVAL;
-
-       val = cpu_to_le32(*(u32 *)&fw->data[NX_FW_MAGIC_OFFSET]);
-       if ((__force u32)val != NETXEN_BDINFO_MAGIC)
-               return -EINVAL;
-
-       val = cpu_to_le32(*(u32 *)&fw->data[NX_FW_VERSION_OFFSET]);
-       major = (__force u32)val & 0xff;
-       minor = ((__force u32)val >> 8) & 0xff;
-       build = (__force u32)val >> 16;
-
-       if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
-               min_ver = NETXEN_VERSION_CODE(4, 0, 216);
-       else
-               min_ver = NETXEN_VERSION_CODE(3, 4, 216);
-
-       ver = NETXEN_VERSION_CODE(major, minor, build);
-
-       if ((major > _NETXEN_NIC_LINUX_MAJOR) || (ver < min_ver)) {
-               dev_err(&pdev->dev,
-                               "%s: firmware version %d.%d.%d unsupported\n",
-                               fwname, major, minor, build);
-               return -EINVAL;
-       }
-
-       val = cpu_to_le32(*(u32 *)&fw->data[NX_BIOS_VERSION_OFFSET]);
-       netxen_rom_fast_read(adapter, NX_BIOS_VERSION_OFFSET, (int *)&bios);
-       if ((__force u32)val != bios) {
-               dev_err(&pdev->dev, "%s: firmware bios is incompatible\n",
-                               fwname);
-               return -EINVAL;
-       }
-
-       /* check if flashed firmware is newer */
-       if (netxen_rom_fast_read(adapter,
-                       NX_FW_VERSION_OFFSET, (int *)&val))
-               return -EIO;
-       major = (__force u32)val & 0xff;
-       minor = ((__force u32)val >> 8) & 0xff;
-       build = (__force u32)val >> 16;
-       if (NETXEN_VERSION_CODE(major, minor, build) > ver)
-               return -EINVAL;
-
-       netxen_nic_reg_write(adapter, NETXEN_CAM_RAM(0x1fc),
-                       NETXEN_BDINFO_MAGIC);
-       return 0;
-}
-
-static char *fw_name[] = { "nxromimg.bin", "nx3fwct.bin", "nx3fwmn.bin" };
-
-int netxen_load_firmware(struct netxen_adapter *adapter)
-{
-       u32 capability, flashed_ver;
-       const struct firmware *fw;
-       int fw_type;
-       struct pci_dev *pdev = adapter->pdev;
-       int rc = 0;
-
-       if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
-               fw_type = NX_P2_MN_ROMIMAGE;
-               goto request_fw;
-       } else {
-               fw_type = NX_P3_CT_ROMIMAGE;
-               goto request_fw;
-       }
-
-request_mn:
-       capability = 0;
-
-       netxen_rom_fast_read(adapter,
-                       NX_FW_VERSION_OFFSET, (int *)&flashed_ver);
-       if (flashed_ver >= NETXEN_VERSION_CODE(4, 0, 220)) {
-               adapter->hw_read_wx(adapter,
-                               NX_PEG_TUNE_CAPABILITY, &capability, 4);
-               if (capability & NX_PEG_TUNE_MN_PRESENT) {
-                       fw_type = NX_P3_MN_ROMIMAGE;
-                       goto request_fw;
-               }
-       }
-
-request_fw:
-       rc = request_firmware(&fw, fw_name[fw_type], &pdev->dev);
-       if (rc != 0) {
-               if (fw_type == NX_P3_CT_ROMIMAGE) {
-                       msleep(1);
-                       goto request_mn;
-               }
-
-               fw = NULL;
-               goto load_fw;
-       }
-
-       rc = netxen_validate_firmware(adapter, fw_name[fw_type], fw);
-       if (rc != 0) {
-               release_firmware(fw);
-
-               if (fw_type == NX_P3_CT_ROMIMAGE) {
-                       msleep(1);
-                       goto request_mn;
-               }
-
-               fw = NULL;
-       }
-
-load_fw:
-       rc = netxen_do_load_firmware(adapter, fw_name[fw_type], fw);
-
-       if (fw)
-               release_firmware(fw);
-       return rc;
-}
-
 int
-netxen_nic_hw_write_wx_128M(struct netxen_adapter *adapter,
-               ulong off, void *data, int len)
+netxen_nic_hw_write_wx_128M(struct netxen_adapter *adapter, ulong off, u32 data)
 {
        void __iomem *addr;
 
-       BUG_ON(len != 4);
-
        if (ADDR_IN_WINDOW1(off)) {
                addr = NETXEN_CRB_NORMALIZE(adapter, off);
        } else {                /* Window 0 */
@@ -1192,7 +993,7 @@ netxen_nic_hw_write_wx_128M(struct netxen_adapter *adapter,
                return 1;
        }
 
-       writel(*(u32 *) data, addr);
+       writel(data, addr);
 
        if (!ADDR_IN_WINDOW1(off))
                netxen_nic_pci_change_crbwindow_128M(adapter, 1);
@@ -1200,13 +1001,11 @@ netxen_nic_hw_write_wx_128M(struct netxen_adapter *adapter,
        return 0;
 }
 
-int
-netxen_nic_hw_read_wx_128M(struct netxen_adapter *adapter,
-               ulong off, void *data, int len)
+u32
+netxen_nic_hw_read_wx_128M(struct netxen_adapter *adapter, ulong off)
 {
        void __iomem *addr;
-
-       BUG_ON(len != 4);
+       u32 data;
 
        if (ADDR_IN_WINDOW1(off)) {     /* Window 1 */
                addr = NETXEN_CRB_NORMALIZE(adapter, off);
@@ -1220,24 +1019,21 @@ netxen_nic_hw_read_wx_128M(struct netxen_adapter *adapter,
                return 1;
        }
 
-       *(u32 *)data = readl(addr);
+       data = readl(addr);
 
        if (!ADDR_IN_WINDOW1(off))
                netxen_nic_pci_change_crbwindow_128M(adapter, 1);
 
-       return 0;
+       return data;
 }
 
 int
-netxen_nic_hw_write_wx_2M(struct netxen_adapter *adapter,
-               ulong off, void *data, int len)
+netxen_nic_hw_write_wx_2M(struct netxen_adapter *adapter, ulong off, u32 data)
 {
        unsigned long flags = 0;
        int rv;
 
-       BUG_ON(len != 4);
-
-       rv = netxen_nic_pci_get_crb_addr_2M(adapter, &off, len);
+       rv = netxen_nic_pci_get_crb_addr_2M(adapter, &off);
 
        if (rv == -1) {
                printk(KERN_ERR "%s: invalid offset: 0x%016lx\n",
@@ -1250,26 +1046,24 @@ netxen_nic_hw_write_wx_2M(struct netxen_adapter *adapter,
                write_lock_irqsave(&adapter->adapter_lock, flags);
                crb_win_lock(adapter);
                netxen_nic_pci_set_crbwindow_2M(adapter, &off);
-               writel(*(uint32_t *)data, (void __iomem *)off);
+               writel(data, (void __iomem *)off);
                crb_win_unlock(adapter);
                write_unlock_irqrestore(&adapter->adapter_lock, flags);
        } else
-               writel(*(uint32_t *)data, (void __iomem *)off);
+               writel(data, (void __iomem *)off);
 
 
        return 0;
 }
 
-int
-netxen_nic_hw_read_wx_2M(struct netxen_adapter *adapter,
-               ulong off, void *data, int len)
+u32
+netxen_nic_hw_read_wx_2M(struct netxen_adapter *adapter, ulong off)
 {
        unsigned long flags = 0;
        int rv;
+       u32 data;
 
-       BUG_ON(len != 4);
-
-       rv = netxen_nic_pci_get_crb_addr_2M(adapter, &off, len);
+       rv = netxen_nic_pci_get_crb_addr_2M(adapter, &off);
 
        if (rv == -1) {
                printk(KERN_ERR "%s: invalid offset: 0x%016lx\n",
@@ -1282,47 +1076,13 @@ netxen_nic_hw_read_wx_2M(struct netxen_adapter *adapter,
                write_lock_irqsave(&adapter->adapter_lock, flags);
                crb_win_lock(adapter);
                netxen_nic_pci_set_crbwindow_2M(adapter, &off);
-               *(uint32_t *)data = readl((void __iomem *)off);
+               data = readl((void __iomem *)off);
                crb_win_unlock(adapter);
                write_unlock_irqrestore(&adapter->adapter_lock, flags);
        } else
-               *(uint32_t *)data = readl((void __iomem *)off);
-
-       return 0;
-}
+               data = readl((void __iomem *)off);
 
-void netxen_nic_reg_write(struct netxen_adapter *adapter, u64 off, u32 val)
-{
-       adapter->hw_write_wx(adapter, off, &val, 4);
-}
-
-int netxen_nic_reg_read(struct netxen_adapter *adapter, u64 off)
-{
-       int val;
-       adapter->hw_read_wx(adapter, off, &val, 4);
-       return val;
-}
-
-/* Change the window to 0, write and change back to window 1. */
-void netxen_nic_write_w0(struct netxen_adapter *adapter, u32 index, u32 value)
-{
-       adapter->hw_write_wx(adapter, index, &value, 4);
-}
-
-/* Change the window to 0, read and change back to window 1. */
-void netxen_nic_read_w0(struct netxen_adapter *adapter, u32 index, u32 *value)
-{
-       adapter->hw_read_wx(adapter, index, value, 4);
-}
-
-void netxen_nic_write_w1(struct netxen_adapter *adapter, u32 index, u32 value)
-{
-       adapter->hw_write_wx(adapter, index, &value, 4);
-}
-
-void netxen_nic_read_w1(struct netxen_adapter *adapter, u32 index, u32 *value)
-{
-       adapter->hw_read_wx(adapter, index, value, 4);
+       return data;
 }
 
 /*
@@ -1425,17 +1185,6 @@ u32 netxen_nic_pci_read_immediate_128M(struct netxen_adapter *adapter, u64 off)
        return readl((void __iomem *)(pci_base_offset(adapter, off)));
 }
 
-void netxen_nic_pci_write_normalize_128M(struct netxen_adapter *adapter,
-               u64 off, u32 data)
-{
-       writel(data, NETXEN_CRB_NORMALIZE(adapter, off));
-}
-
-u32 netxen_nic_pci_read_normalize_128M(struct netxen_adapter *adapter, u64 off)
-{
-       return readl(NETXEN_CRB_NORMALIZE(adapter, off));
-}
-
 unsigned long
 netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter,
                unsigned long long addr)
@@ -1447,12 +1196,10 @@ netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter,
                /* DDR network side */
                window = MN_WIN(addr);
                adapter->ahw.ddr_mn_window = window;
-               adapter->hw_write_wx(adapter,
-                               adapter->ahw.mn_win_crb | NETXEN_PCI_CRBSPACE,
-                               &window, 4);
-               adapter->hw_read_wx(adapter,
-                               adapter->ahw.mn_win_crb | NETXEN_PCI_CRBSPACE,
-                               &win_read, 4);
+               NXWR32(adapter, adapter->ahw.mn_win_crb | NETXEN_PCI_CRBSPACE,
+                               window);
+               win_read = NXRD32(adapter,
+                               adapter->ahw.mn_win_crb | NETXEN_PCI_CRBSPACE);
                if ((win_read << 17) != window) {
                        printk(KERN_INFO "Written MNwin (0x%x) != "
                                "Read MNwin (0x%x)\n", window, win_read);
@@ -1467,12 +1214,10 @@ netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter,
 
                window = OCM_WIN(addr);
                adapter->ahw.ddr_mn_window = window;
-               adapter->hw_write_wx(adapter,
-                               adapter->ahw.mn_win_crb | NETXEN_PCI_CRBSPACE,
-                               &window, 4);
-               adapter->hw_read_wx(adapter,
-                               adapter->ahw.mn_win_crb | NETXEN_PCI_CRBSPACE,
-                               &win_read, 4);
+               NXWR32(adapter, adapter->ahw.mn_win_crb | NETXEN_PCI_CRBSPACE,
+                               window);
+               win_read = NXRD32(adapter,
+                               adapter->ahw.mn_win_crb | NETXEN_PCI_CRBSPACE);
                if ((win_read >> 7) != window) {
                        printk(KERN_INFO "%s: Written OCMwin (0x%x) != "
                                        "Read OCMwin (0x%x)\n",
@@ -1485,12 +1230,10 @@ netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter,
                /* QDR network side */
                window = MS_WIN(addr);
                adapter->ahw.qdr_sn_window = window;
-               adapter->hw_write_wx(adapter,
-                               adapter->ahw.ms_win_crb | NETXEN_PCI_CRBSPACE,
-                               &window, 4);
-               adapter->hw_read_wx(adapter,
-                               adapter->ahw.ms_win_crb | NETXEN_PCI_CRBSPACE,
-                               &win_read, 4);
+               NXWR32(adapter, adapter->ahw.ms_win_crb | NETXEN_PCI_CRBSPACE,
+                               window);
+               win_read = NXRD32(adapter,
+                               adapter->ahw.ms_win_crb | NETXEN_PCI_CRBSPACE);
                if (win_read != window) {
                        printk(KERN_INFO "%s: Written MSwin (0x%x) != "
                                        "Read MSwin (0x%x)\n",
@@ -1936,27 +1679,20 @@ netxen_nic_pci_mem_write_2M(struct netxen_adapter *adapter,
 
        for (i = 0; i < loop; i++) {
                temp = off8 + (i << 3);
-               adapter->hw_write_wx(adapter,
-                               mem_crb+MIU_TEST_AGT_ADDR_LO, &temp, 4);
+               NXWR32(adapter, mem_crb+MIU_TEST_AGT_ADDR_LO, temp);
                temp = 0;
-               adapter->hw_write_wx(adapter,
-                               mem_crb+MIU_TEST_AGT_ADDR_HI, &temp, 4);
+               NXWR32(adapter, mem_crb+MIU_TEST_AGT_ADDR_HI, temp);
                temp = word[i] & 0xffffffff;
-               adapter->hw_write_wx(adapter,
-                               mem_crb+MIU_TEST_AGT_WRDATA_LO, &temp, 4);
+               NXWR32(adapter, mem_crb+MIU_TEST_AGT_WRDATA_LO, temp);
                temp = (word[i] >> 32) & 0xffffffff;
-               adapter->hw_write_wx(adapter,
-                               mem_crb+MIU_TEST_AGT_WRDATA_HI, &temp, 4);
+               NXWR32(adapter, mem_crb+MIU_TEST_AGT_WRDATA_HI, temp);
                temp = MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE;
-               adapter->hw_write_wx(adapter,
-                               mem_crb+MIU_TEST_AGT_CTRL, &temp, 4);
+               NXWR32(adapter, mem_crb+MIU_TEST_AGT_CTRL, temp);
                temp = MIU_TA_CTL_START | MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE;
-               adapter->hw_write_wx(adapter,
-                               mem_crb+MIU_TEST_AGT_CTRL, &temp, 4);
+               NXWR32(adapter, mem_crb+MIU_TEST_AGT_CTRL, temp);
 
                for (j = 0; j < MAX_CTL_CHECK; j++) {
-                       adapter->hw_read_wx(adapter,
-                                       mem_crb + MIU_TEST_AGT_CTRL, &temp, 4);
+                       temp = NXRD32(adapter, mem_crb + MIU_TEST_AGT_CTRL);
                        if ((temp & MIU_TA_CTL_BUSY) == 0)
                                break;
                }
@@ -2013,21 +1749,16 @@ netxen_nic_pci_mem_read_2M(struct netxen_adapter *adapter,
 
        for (i = 0; i < loop; i++) {
                temp = off8 + (i << 3);
-               adapter->hw_write_wx(adapter,
-                               mem_crb + MIU_TEST_AGT_ADDR_LO, &temp, 4);
+               NXWR32(adapter, mem_crb + MIU_TEST_AGT_ADDR_LO, temp);
                temp = 0;
-               adapter->hw_write_wx(adapter,
-                               mem_crb + MIU_TEST_AGT_ADDR_HI, &temp, 4);
+               NXWR32(adapter, mem_crb + MIU_TEST_AGT_ADDR_HI, temp);
                temp = MIU_TA_CTL_ENABLE;
-               adapter->hw_write_wx(adapter,
-                               mem_crb + MIU_TEST_AGT_CTRL, &temp, 4);
+               NXWR32(adapter, mem_crb + MIU_TEST_AGT_CTRL, temp);
                temp = MIU_TA_CTL_START | MIU_TA_CTL_ENABLE;
-               adapter->hw_write_wx(adapter,
-                               mem_crb + MIU_TEST_AGT_CTRL, &temp, 4);
+               NXWR32(adapter, mem_crb + MIU_TEST_AGT_CTRL, temp);
 
                for (j = 0; j < MAX_CTL_CHECK; j++) {
-                       adapter->hw_read_wx(adapter,
-                                       mem_crb + MIU_TEST_AGT_CTRL, &temp, 4);
+                       temp = NXRD32(adapter, mem_crb + MIU_TEST_AGT_CTRL);
                        if ((temp & MIU_TA_CTL_BUSY) == 0)
                                break;
                }
@@ -2042,8 +1773,8 @@ netxen_nic_pci_mem_read_2M(struct netxen_adapter *adapter,
                start = off0[i] >> 2;
                end   = (off0[i] + sz[i] - 1) >> 2;
                for (k = start; k <= end; k++) {
-                       adapter->hw_read_wx(adapter,
-                               mem_crb + MIU_TEST_AGT_RDDATA(k), &temp, 4);
+                       temp = NXRD32(adapter,
+                               mem_crb + MIU_TEST_AGT_RDDATA(k));
                        word[i] |= ((uint64_t)temp << (32 * k));
                }
        }
@@ -2086,29 +1817,14 @@ netxen_nic_pci_mem_read_2M(struct netxen_adapter *adapter,
 int netxen_nic_pci_write_immediate_2M(struct netxen_adapter *adapter,
                u64 off, u32 data)
 {
-       adapter->hw_write_wx(adapter, off, &data, 4);
+       NXWR32(adapter, off, data);
 
        return 0;
 }
 
 u32 netxen_nic_pci_read_immediate_2M(struct netxen_adapter *adapter, u64 off)
 {
-       u32 temp;
-       adapter->hw_read_wx(adapter, off, &temp, 4);
-       return temp;
-}
-
-void netxen_nic_pci_write_normalize_2M(struct netxen_adapter *adapter,
-               u64 off, u32 data)
-{
-       adapter->hw_write_wx(adapter, off, &data, 4);
-}
-
-u32 netxen_nic_pci_read_normalize_2M(struct netxen_adapter *adapter, u64 off)
-{
-       u32 temp;
-       adapter->hw_read_wx(adapter, off, &temp, 4);
-       return temp;
+       return NXRD32(adapter, off);
 }
 
 int netxen_nic_get_board_info(struct netxen_adapter *adapter)
@@ -2142,13 +1858,12 @@ int netxen_nic_get_board_info(struct netxen_adapter *adapter)
        adapter->ahw.board_type = board_type;
 
        if (board_type == NETXEN_BRDTYPE_P3_4_GB_MM) {
-               u32 gpio = netxen_nic_reg_read(adapter,
-                               NETXEN_ROMUSB_GLB_PAD_GPIO_I);
+               u32 gpio = NXRD32(adapter, NETXEN_ROMUSB_GLB_PAD_GPIO_I);
                if ((gpio & 0x8000) == 0)
                        board_type = NETXEN_BRDTYPE_P3_10G_TP;
        }
 
-       switch ((netxen_brdtype_t)board_type) {
+       switch (board_type) {
        case NETXEN_BRDTYPE_P2_SB35_4G:
                adapter->ahw.port_type = NETXEN_NIC_GBE;
                break;
@@ -2195,8 +1910,7 @@ int netxen_nic_get_board_info(struct netxen_adapter *adapter)
 int netxen_nic_set_mtu_gb(struct netxen_adapter *adapter, int new_mtu)
 {
        new_mtu += MTU_FUDGE_FACTOR;
-       netxen_nic_write_w0(adapter,
-               NETXEN_NIU_GB_MAX_FRAME_SIZE(adapter->physical_port),
+       NXWR32(adapter, NETXEN_NIU_GB_MAX_FRAME_SIZE(adapter->physical_port),
                new_mtu);
        return 0;
 }
@@ -2205,21 +1919,12 @@ int netxen_nic_set_mtu_xgb(struct netxen_adapter *adapter, int new_mtu)
 {
        new_mtu += MTU_FUDGE_FACTOR;
        if (adapter->physical_port == 0)
-               netxen_nic_write_w0(adapter, NETXEN_NIU_XGE_MAX_FRAME_SIZE,
-                               new_mtu);
+               NXWR32(adapter, NETXEN_NIU_XGE_MAX_FRAME_SIZE, new_mtu);
        else
-               netxen_nic_write_w0(adapter, NETXEN_NIU_XG1_MAX_FRAME_SIZE,
-                               new_mtu);
+               NXWR32(adapter, NETXEN_NIU_XG1_MAX_FRAME_SIZE, new_mtu);
        return 0;
 }
 
-void
-netxen_crb_writelit_adapter(struct netxen_adapter *adapter,
-               unsigned long off, int data)
-{
-       adapter->hw_write_wx(adapter, off, &data, 4);
-}
-
 void netxen_nic_set_link_parameters(struct netxen_adapter *adapter)
 {
        __u32 status;
@@ -2234,8 +1939,7 @@ void netxen_nic_set_link_parameters(struct netxen_adapter *adapter)
        }
 
        if (adapter->ahw.port_type == NETXEN_NIC_GBE) {
-               adapter->hw_read_wx(adapter,
-                               NETXEN_PORT_MODE_ADDR, &port_mode, 4);
+               port_mode = NXRD32(adapter, NETXEN_PORT_MODE_ADDR);
                if (port_mode == NETXEN_PORT_MODE_802_3_AP) {
                        adapter->link_speed   = SPEED_1000;
                        adapter->link_duplex  = DUPLEX_FULL;
@@ -2312,9 +2016,9 @@ void netxen_nic_get_firmware_info(struct netxen_adapter *adapter)
                addr += sizeof(u32);
        }
 
-       adapter->hw_read_wx(adapter, NETXEN_FW_VERSION_MAJOR, &fw_major, 4);
-       adapter->hw_read_wx(adapter, NETXEN_FW_VERSION_MINOR, &fw_minor, 4);
-       adapter->hw_read_wx(adapter, NETXEN_FW_VERSION_SUB, &fw_build, 4);
+       fw_major = NXRD32(adapter, NETXEN_FW_VERSION_MAJOR);
+       fw_minor = NXRD32(adapter, NETXEN_FW_VERSION_MINOR);
+       fw_build = NXRD32(adapter, NETXEN_FW_VERSION_SUB);
 
        adapter->fw_major = fw_major;
        adapter->fw_version = NETXEN_VERSION_CODE(fw_major, fw_minor, fw_build);
@@ -2337,8 +2041,7 @@ void netxen_nic_get_firmware_info(struct netxen_adapter *adapter)
                        fw_major, fw_minor, fw_build);
 
        if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
-               adapter->hw_read_wx(adapter,
-                               NETXEN_MIU_MN_CONTROL, &i, 4);
+               i = NXRD32(adapter, NETXEN_MIU_MN_CONTROL);
                adapter->ahw.cut_through = (i & 0x4) ? 1 : 0;
                dev_info(&pdev->dev, "firmware running in %s mode\n",
                adapter->ahw.cut_through ? "cut-through" : "legacy");
@@ -2353,9 +2056,9 @@ netxen_nic_wol_supported(struct netxen_adapter *adapter)
        if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
                return 0;
 
-       wol_cfg = netxen_nic_reg_read(adapter, NETXEN_WOL_CONFIG_NV);
+       wol_cfg = NXRD32(adapter, NETXEN_WOL_CONFIG_NV);
        if (wol_cfg & (1UL << adapter->portnum)) {
-               wol_cfg = netxen_nic_reg_read(adapter, NETXEN_WOL_CONFIG);
+               wol_cfg = NXRD32(adapter, NETXEN_WOL_CONFIG);
                if (wol_cfg & (1 << adapter->portnum))
                        return 1;
        }
index 04b47a7993cd67da7269dcbcd7c50853d9d784a0..d4e8333397818bf0ce6fba286643422ba2d112aa 100644 (file)
 /* Hardware memory size of 128 meg */
 #define NETXEN_MEMADDR_MAX (128 * 1024 * 1024)
 
-#ifndef readq
-static inline u64 readq(void __iomem * addr)
-{
-       return readl(addr) | (((u64) readl(addr + 4)) << 32LL);
-}
-#endif
-
-#ifndef writeq
-static inline void writeq(u64 val, void __iomem * addr)
-{
-       writel(((u32) (val)), (addr));
-       writel(((u32) (val >> 32)), (addr + 4));
-}
-#endif
-
 struct netxen_adapter;
 
 #define NETXEN_PCI_MAPSIZE_BYTES  (NETXEN_PCI_MAPSIZE << 20)
 
-struct netxen_port;
 void netxen_nic_set_link_parameters(struct netxen_adapter *adapter);
 
-typedef u8 netxen_ethernet_macaddr_t[6];
-
 /* Nibble or Byte mode for phy interface (GbE mode only) */
-typedef enum {
-       NETXEN_NIU_10_100_MB = 0,
-       NETXEN_NIU_1000_MB
-} netxen_niu_gbe_ifmode_t;
 
 #define _netxen_crb_get_bit(var, bit)  ((var >> bit) & 0x1)
 
@@ -222,30 +200,28 @@ typedef enum {
 /*
  * PHY-Specific MII control/status registers.
  */
-typedef enum {
-       NETXEN_NIU_GB_MII_MGMT_ADDR_CONTROL = 0,
-       NETXEN_NIU_GB_MII_MGMT_ADDR_STATUS = 1,
-       NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_ID_0 = 2,
-       NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_ID_1 = 3,
-       NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG = 4,
-       NETXEN_NIU_GB_MII_MGMT_ADDR_LNKPART = 5,
-       NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG_MORE = 6,
-       NETXEN_NIU_GB_MII_MGMT_ADDR_NEXTPAGE_XMIT = 7,
-       NETXEN_NIU_GB_MII_MGMT_ADDR_LNKPART_NEXTPAGE = 8,
-       NETXEN_NIU_GB_MII_MGMT_ADDR_1000BT_CONTROL = 9,
-       NETXEN_NIU_GB_MII_MGMT_ADDR_1000BT_STATUS = 10,
-       NETXEN_NIU_GB_MII_MGMT_ADDR_EXTENDED_STATUS = 15,
-       NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_CONTROL = 16,
-       NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS = 17,
-       NETXEN_NIU_GB_MII_MGMT_ADDR_INT_ENABLE = 18,
-       NETXEN_NIU_GB_MII_MGMT_ADDR_INT_STATUS = 19,
-       NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_CONTROL_MORE = 20,
-       NETXEN_NIU_GB_MII_MGMT_ADDR_RECV_ERROR_COUNT = 21,
-       NETXEN_NIU_GB_MII_MGMT_ADDR_LED_CONTROL = 24,
-       NETXEN_NIU_GB_MII_MGMT_ADDR_LED_OVERRIDE = 25,
-       NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_CONTROL_MORE_YET = 26,
-       NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS_MORE = 27
-} netxen_niu_phy_register_t;
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_CONTROL            0
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_STATUS             1
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_ID_0           2
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_ID_1           3
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG            4
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_LNKPART            5
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG_MORE       6
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_NEXTPAGE_XMIT      7
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_LNKPART_NEXTPAGE   8
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_1000BT_CONTROL     9
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_1000BT_STATUS      10
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_EXTENDED_STATUS    15
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_CONTROL                16
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS         17
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_INT_ENABLE         18
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_INT_STATUS         19
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_CONTROL_MORE   20
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_RECV_ERROR_COUNT   21
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_LED_CONTROL                24
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_LED_OVERRIDE       25
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_CONTROL_MORE_YET       26
+#define NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS_MORE    27
 
 /*
  * PHY-Specific Status Register (reg 17).
@@ -417,14 +393,6 @@ int netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter,
 int netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter,
                                       u32 mode);
 
-/* set the MAC address for a given MAC */
-int netxen_niu_macaddr_set(struct netxen_adapter *adapter,
-                          netxen_ethernet_macaddr_t addr);
-
-/* XG version */
-int netxen_niu_xg_macaddr_set(struct netxen_adapter *adapter,
-                             netxen_ethernet_macaddr_t addr);
-
 /* Generic enable for GbE ports. Will detect the speed of the link. */
 int netxen_niu_gbe_init_port(struct netxen_adapter *adapter, int port);
 
index 0759c35f16ac6005416b8986f74f548b1221cbd4..6f77ad58e3b3d00752861b9626a95493041cbf22 100644 (file)
@@ -108,42 +108,6 @@ static void crb_addr_transform_setup(void)
        crb_addr_transform(I2C0);
 }
 
-int netxen_init_firmware(struct netxen_adapter *adapter)
-{
-       u32 state = 0, loops = 0, err = 0;
-
-       /* Window 1 call */
-       state = adapter->pci_read_normalize(adapter, CRB_CMDPEG_STATE);
-
-       if (state == PHAN_INITIALIZE_ACK)
-               return 0;
-
-       while (state != PHAN_INITIALIZE_COMPLETE && loops < 2000) {
-               msleep(1);
-               /* Window 1 call */
-               state = adapter->pci_read_normalize(adapter, CRB_CMDPEG_STATE);
-
-               loops++;
-       }
-       if (loops >= 2000) {
-               printk(KERN_ERR "Cmd Peg initialization not complete:%x.\n",
-                      state);
-               err = -EIO;
-               return err;
-       }
-       /* Window 1 call */
-       adapter->pci_write_normalize(adapter,
-                       CRB_NIC_CAPABILITIES_HOST, INTR_SCHEME_PERPORT);
-       adapter->pci_write_normalize(adapter,
-                       CRB_NIC_MSI_MODE_HOST, MSI_MODE_MULTIFUNC);
-       adapter->pci_write_normalize(adapter,
-                       CRB_MPORT_MODE, MPORT_MULTI_FUNCTION_MODE);
-       adapter->pci_write_normalize(adapter,
-                       CRB_CMDPEG_STATE, PHAN_INITIALIZE_ACK);
-
-       return err;
-}
-
 void netxen_release_rx_buffers(struct netxen_adapter *adapter)
 {
        struct netxen_recv_context *recv_ctx;
@@ -173,9 +137,10 @@ void netxen_release_tx_buffers(struct netxen_adapter *adapter)
        struct netxen_cmd_buffer *cmd_buf;
        struct netxen_skb_frag *buffrag;
        int i, j;
+       struct nx_host_tx_ring *tx_ring = adapter->tx_ring;
 
-       cmd_buf = adapter->cmd_buf_arr;
-       for (i = 0; i < adapter->num_txd; i++) {
+       cmd_buf = tx_ring->cmd_buf_arr;
+       for (i = 0; i < tx_ring->num_desc; i++) {
                buffrag = cmd_buf->frag_array;
                if (buffrag->dma) {
                        pci_unmap_single(adapter->pdev, buffrag->dma,
@@ -203,20 +168,27 @@ void netxen_free_sw_resources(struct netxen_adapter *adapter)
 {
        struct netxen_recv_context *recv_ctx;
        struct nx_host_rds_ring *rds_ring;
+       struct nx_host_tx_ring *tx_ring;
        int ring;
 
        recv_ctx = &adapter->recv_ctx;
+
+       if (recv_ctx->rds_rings == NULL)
+               goto skip_rds;
+
        for (ring = 0; ring < adapter->max_rds_rings; ring++) {
                rds_ring = &recv_ctx->rds_rings[ring];
-               if (rds_ring->rx_buf_arr) {
-                       vfree(rds_ring->rx_buf_arr);
-                       rds_ring->rx_buf_arr = NULL;
-               }
+               vfree(rds_ring->rx_buf_arr);
+               rds_ring->rx_buf_arr = NULL;
        }
+       kfree(recv_ctx->rds_rings);
 
-       if (adapter->cmd_buf_arr)
-               vfree(adapter->cmd_buf_arr);
-       return;
+skip_rds:
+       if (adapter->tx_ring == NULL)
+               return;
+
+       tx_ring = adapter->tx_ring;
+       vfree(tx_ring->cmd_buf_arr);
 }
 
 int netxen_alloc_sw_resources(struct netxen_adapter *adapter)
@@ -224,23 +196,45 @@ int netxen_alloc_sw_resources(struct netxen_adapter *adapter)
        struct netxen_recv_context *recv_ctx;
        struct nx_host_rds_ring *rds_ring;
        struct nx_host_sds_ring *sds_ring;
+       struct nx_host_tx_ring *tx_ring;
        struct netxen_rx_buffer *rx_buf;
-       int ring, i, num_rx_bufs;
+       int ring, i, size;
 
        struct netxen_cmd_buffer *cmd_buf_arr;
        struct net_device *netdev = adapter->netdev;
+       struct pci_dev *pdev = adapter->pdev;
 
-       cmd_buf_arr =
-               (struct netxen_cmd_buffer *)vmalloc(TX_BUFF_RINGSIZE(adapter));
+       size = sizeof(struct nx_host_tx_ring);
+       tx_ring = kzalloc(size, GFP_KERNEL);
+       if (tx_ring == NULL) {
+               dev_err(&pdev->dev, "%s: failed to allocate tx ring struct\n",
+                      netdev->name);
+               return -ENOMEM;
+       }
+       adapter->tx_ring = tx_ring;
+
+       tx_ring->num_desc = adapter->num_txd;
+
+       cmd_buf_arr = vmalloc(TX_BUFF_RINGSIZE(tx_ring));
        if (cmd_buf_arr == NULL) {
-               printk(KERN_ERR "%s: Failed to allocate cmd buffer ring\n",
+               dev_err(&pdev->dev, "%s: failed to allocate cmd buffer ring\n",
                       netdev->name);
                return -ENOMEM;
        }
-       memset(cmd_buf_arr, 0, TX_BUFF_RINGSIZE(adapter));
-       adapter->cmd_buf_arr = cmd_buf_arr;
+       memset(cmd_buf_arr, 0, TX_BUFF_RINGSIZE(tx_ring));
+       tx_ring->cmd_buf_arr = cmd_buf_arr;
 
        recv_ctx = &adapter->recv_ctx;
+
+       size = adapter->max_rds_rings * sizeof (struct nx_host_rds_ring);
+       rds_ring = kzalloc(size, GFP_KERNEL);
+       if (rds_ring == NULL) {
+               dev_err(&pdev->dev, "%s: failed to allocate rds ring struct\n",
+                      netdev->name);
+               return -ENOMEM;
+       }
+       recv_ctx->rds_rings = rds_ring;
+
        for (ring = 0; ring < adapter->max_rds_rings; ring++) {
                rds_ring = &recv_ctx->rds_rings[ring];
                switch (ring) {
@@ -292,9 +286,8 @@ int netxen_alloc_sw_resources(struct netxen_adapter *adapter)
                 * Now go through all of them, set reference handles
                 * and put them in the queues.
                 */
-               num_rx_bufs = rds_ring->num_desc;
                rx_buf = rds_ring->rx_buf_arr;
-               for (i = 0; i < num_rx_bufs; i++) {
+               for (i = 0; i < rds_ring->num_desc; i++) {
                        list_add_tail(&rx_buf->list,
                                        &rds_ring->free_list);
                        rx_buf->ref_handle = i;
@@ -307,8 +300,6 @@ int netxen_alloc_sw_resources(struct netxen_adapter *adapter)
        for (ring = 0; ring < adapter->max_sds_rings; ring++) {
                sds_ring = &recv_ctx->sds_rings[ring];
                sds_ring->irq = adapter->msix_entries[ring].vector;
-               sds_ring->clean_tx = (ring == 0);
-               sds_ring->post_rxd = (ring == 0);
                sds_ring->adapter = adapter;
                sds_ring->num_desc = adapter->num_rxd;
 
@@ -325,13 +316,15 @@ err_out:
 
 void netxen_initialize_adapter_ops(struct netxen_adapter *adapter)
 {
+       adapter->macaddr_set = netxen_p2_nic_set_mac_addr;
+       adapter->set_multi = netxen_p2_nic_set_multi;
+
        switch (adapter->ahw.port_type) {
        case NETXEN_NIC_GBE:
                adapter->enable_phy_interrupts =
                    netxen_niu_gbe_enable_phy_interrupts;
                adapter->disable_phy_interrupts =
                    netxen_niu_gbe_disable_phy_interrupts;
-               adapter->macaddr_set = netxen_niu_macaddr_set;
                adapter->set_mtu = netxen_nic_set_mtu_gb;
                adapter->set_promisc = netxen_niu_set_promiscuous_mode;
                adapter->phy_read = netxen_niu_gbe_phy_read;
@@ -345,7 +338,6 @@ void netxen_initialize_adapter_ops(struct netxen_adapter *adapter)
                    netxen_niu_xgbe_enable_phy_interrupts;
                adapter->disable_phy_interrupts =
                    netxen_niu_xgbe_disable_phy_interrupts;
-               adapter->macaddr_set = netxen_niu_xg_macaddr_set;
                adapter->set_mtu = netxen_nic_set_mtu_xgb;
                adapter->init_port = netxen_niu_xg_init_port;
                adapter->set_promisc = netxen_niu_xg_set_promiscuous_mode;
@@ -359,6 +351,8 @@ void netxen_initialize_adapter_ops(struct netxen_adapter *adapter)
        if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
                adapter->set_mtu = nx_fw_cmd_set_mtu;
                adapter->set_promisc = netxen_p3_nic_set_promisc;
+               adapter->macaddr_set = netxen_p3_nic_set_mac_addr;
+               adapter->set_multi = netxen_p3_nic_set_multi;
        }
 }
 
@@ -400,8 +394,7 @@ static int rom_lock(struct netxen_adapter *adapter)
 
        while (!done) {
                /* acquire semaphore2 from PCI HW block */
-               netxen_nic_read_w0(adapter, NETXEN_PCIE_REG(PCIE_SEM2_LOCK),
-                                  &done);
+               done = NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM2_LOCK));
                if (done == 1)
                        break;
                if (timeout >= rom_lock_timeout)
@@ -418,7 +411,7 @@ static int rom_lock(struct netxen_adapter *adapter)
                                cpu_relax();    /*This a nop instr on i386 */
                }
        }
-       netxen_nic_reg_write(adapter, NETXEN_ROM_LOCK_ID, ROM_LOCK_DRIVER);
+       NXWR32(adapter, NETXEN_ROM_LOCK_ID, ROM_LOCK_DRIVER);
        return 0;
 }
 
@@ -430,7 +423,7 @@ static int netxen_wait_rom_done(struct netxen_adapter *adapter)
        cond_resched();
 
        while (done == 0) {
-               done = netxen_nic_reg_read(adapter, NETXEN_ROMUSB_GLB_STATUS);
+               done = NXRD32(adapter, NETXEN_ROMUSB_GLB_STATUS);
                done &= 2;
                timeout++;
                if (timeout >= rom_max_timeout) {
@@ -443,30 +436,28 @@ static int netxen_wait_rom_done(struct netxen_adapter *adapter)
 
 static void netxen_rom_unlock(struct netxen_adapter *adapter)
 {
-       u32 val;
-
        /* release semaphore2 */
-       netxen_nic_read_w0(adapter, NETXEN_PCIE_REG(PCIE_SEM2_UNLOCK), &val);
+       NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM2_UNLOCK));
 
 }
 
 static int do_rom_fast_read(struct netxen_adapter *adapter,
                            int addr, int *valp)
 {
-       netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ADDRESS, addr);
-       netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
-       netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 3);
-       netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_INSTR_OPCODE, 0xb);
+       NXWR32(adapter, NETXEN_ROMUSB_ROM_ADDRESS, addr);
+       NXWR32(adapter, NETXEN_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
+       NXWR32(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 3);
+       NXWR32(adapter, NETXEN_ROMUSB_ROM_INSTR_OPCODE, 0xb);
        if (netxen_wait_rom_done(adapter)) {
                printk("Error waiting for rom done\n");
                return -EIO;
        }
        /* reset abyte_cnt and dummy_byte_cnt */
-       netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 0);
+       NXWR32(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 0);
        udelay(10);
-       netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
+       NXWR32(adapter, NETXEN_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
 
-       *valp = netxen_nic_reg_read(adapter, NETXEN_ROMUSB_ROM_RDATA);
+       *valp = NXRD32(adapter, NETXEN_ROMUSB_ROM_RDATA);
        return 0;
 }
 
@@ -530,8 +521,7 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose)
 
        /* resetall */
        rom_lock(adapter);
-       netxen_crb_writelit_adapter(adapter, NETXEN_ROMUSB_GLB_SW_RESET,
-                                   0xffffffff);
+       NXWR32(adapter, NETXEN_ROMUSB_GLB_SW_RESET, 0xffffffff);
        netxen_rom_unlock(adapter);
 
        if (verbose) {
@@ -655,7 +645,7 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose)
                        }
                }
 
-               adapter->hw_write_wx(adapter, off, &buf[i].data, 4);
+               NXWR32(adapter, off, buf[i].data);
 
                msleep(init_delay);
        }
@@ -665,36 +655,230 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose)
 
        /* unreset_net_cache */
        if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
-               adapter->hw_read_wx(adapter,
-                               NETXEN_ROMUSB_GLB_SW_RESET, &val, 4);
-               netxen_crb_writelit_adapter(adapter,
-                               NETXEN_ROMUSB_GLB_SW_RESET, (val & 0xffffff0f));
+               val = NXRD32(adapter, NETXEN_ROMUSB_GLB_SW_RESET);
+               NXWR32(adapter, NETXEN_ROMUSB_GLB_SW_RESET, (val & 0xffffff0f));
        }
 
        /* p2dn replyCount */
-       netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_D + 0xec, 0x1e);
+       NXWR32(adapter, NETXEN_CRB_PEG_NET_D + 0xec, 0x1e);
        /* disable_peg_cache 0 */
-       netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_D + 0x4c, 8);
+       NXWR32(adapter, NETXEN_CRB_PEG_NET_D + 0x4c, 8);
        /* disable_peg_cache 1 */
-       netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_I + 0x4c, 8);
+       NXWR32(adapter, NETXEN_CRB_PEG_NET_I + 0x4c, 8);
 
        /* peg_clr_all */
 
        /* peg_clr 0 */
-       netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_0 + 0x8, 0);
-       netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_0 + 0xc, 0);
+       NXWR32(adapter, NETXEN_CRB_PEG_NET_0 + 0x8, 0);
+       NXWR32(adapter, NETXEN_CRB_PEG_NET_0 + 0xc, 0);
        /* peg_clr 1 */
-       netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_1 + 0x8, 0);
-       netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_1 + 0xc, 0);
+       NXWR32(adapter, NETXEN_CRB_PEG_NET_1 + 0x8, 0);
+       NXWR32(adapter, NETXEN_CRB_PEG_NET_1 + 0xc, 0);
        /* peg_clr 2 */
-       netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_2 + 0x8, 0);
-       netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_2 + 0xc, 0);
+       NXWR32(adapter, NETXEN_CRB_PEG_NET_2 + 0x8, 0);
+       NXWR32(adapter, NETXEN_CRB_PEG_NET_2 + 0xc, 0);
        /* peg_clr 3 */
-       netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_3 + 0x8, 0);
-       netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_3 + 0xc, 0);
+       NXWR32(adapter, NETXEN_CRB_PEG_NET_3 + 0x8, 0);
+       NXWR32(adapter, NETXEN_CRB_PEG_NET_3 + 0xc, 0);
+       return 0;
+}
+
+int
+netxen_load_firmware(struct netxen_adapter *adapter)
+{
+       u64 *ptr64;
+       u32 i, flashaddr, size;
+       const struct firmware *fw = adapter->fw;
+
+       if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
+               NXWR32(adapter, NETXEN_ROMUSB_GLB_CAS_RST, 1);
+
+       if (fw) {
+               __le64 data;
+
+               size = (NETXEN_IMAGE_START - NETXEN_BOOTLD_START) / 8;
+
+               ptr64 = (u64 *)&fw->data[NETXEN_BOOTLD_START];
+               flashaddr = NETXEN_BOOTLD_START;
+
+               for (i = 0; i < size; i++) {
+                       data = cpu_to_le64(ptr64[i]);
+                       adapter->pci_mem_write(adapter, flashaddr, &data, 8);
+                       flashaddr += 8;
+               }
+
+               size = *(u32 *)&fw->data[NX_FW_SIZE_OFFSET];
+               size = (__force u32)cpu_to_le32(size) / 8;
+
+               ptr64 = (u64 *)&fw->data[NETXEN_IMAGE_START];
+               flashaddr = NETXEN_IMAGE_START;
+
+               for (i = 0; i < size; i++) {
+                       data = cpu_to_le64(ptr64[i]);
+
+                       if (adapter->pci_mem_write(adapter,
+                                               flashaddr, &data, 8))
+                               return -EIO;
+
+                       flashaddr += 8;
+               }
+       } else {
+               u32 data;
+
+               size = (NETXEN_IMAGE_START - NETXEN_BOOTLD_START) / 4;
+               flashaddr = NETXEN_BOOTLD_START;
+
+               for (i = 0; i < size; i++) {
+                       if (netxen_rom_fast_read(adapter,
+                                       flashaddr, (int *)&data) != 0)
+                               return -EIO;
+
+                       if (adapter->pci_mem_write(adapter,
+                                               flashaddr, &data, 4))
+                               return -EIO;
+
+                       flashaddr += 4;
+               }
+       }
+       msleep(1);
+
+       if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
+               NXWR32(adapter, NETXEN_ROMUSB_GLB_SW_RESET, 0x80001d);
+       else {
+               NXWR32(adapter, NETXEN_ROMUSB_GLB_CHIP_CLK_CTRL, 0x3fff);
+               NXWR32(adapter, NETXEN_ROMUSB_GLB_CAS_RST, 0);
+       }
+
+       return 0;
+}
+
+static int
+netxen_validate_firmware(struct netxen_adapter *adapter, const char *fwname)
+{
+       __le32 val;
+       u32 major, minor, build, ver, min_ver, bios;
+       struct pci_dev *pdev = adapter->pdev;
+       const struct firmware *fw = adapter->fw;
+
+       if (fw->size < NX_FW_MIN_SIZE)
+               return -EINVAL;
+
+       val = cpu_to_le32(*(u32 *)&fw->data[NX_FW_MAGIC_OFFSET]);
+       if ((__force u32)val != NETXEN_BDINFO_MAGIC)
+               return -EINVAL;
+
+       val = cpu_to_le32(*(u32 *)&fw->data[NX_FW_VERSION_OFFSET]);
+       major = (__force u32)val & 0xff;
+       minor = ((__force u32)val >> 8) & 0xff;
+       build = (__force u32)val >> 16;
+
+       if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
+               min_ver = NETXEN_VERSION_CODE(4, 0, 216);
+       else
+               min_ver = NETXEN_VERSION_CODE(3, 4, 216);
+
+       ver = NETXEN_VERSION_CODE(major, minor, build);
+
+       if ((major > _NETXEN_NIC_LINUX_MAJOR) || (ver < min_ver)) {
+               dev_err(&pdev->dev,
+                               "%s: firmware version %d.%d.%d unsupported\n",
+                               fwname, major, minor, build);
+               return -EINVAL;
+       }
+
+       val = cpu_to_le32(*(u32 *)&fw->data[NX_BIOS_VERSION_OFFSET]);
+       netxen_rom_fast_read(adapter, NX_BIOS_VERSION_OFFSET, (int *)&bios);
+       if ((__force u32)val != bios) {
+               dev_err(&pdev->dev, "%s: firmware bios is incompatible\n",
+                               fwname);
+               return -EINVAL;
+       }
+
+       /* check if flashed firmware is newer */
+       if (netxen_rom_fast_read(adapter,
+                       NX_FW_VERSION_OFFSET, (int *)&val))
+               return -EIO;
+       major = (__force u32)val & 0xff;
+       minor = ((__force u32)val >> 8) & 0xff;
+       build = (__force u32)val >> 16;
+       if (NETXEN_VERSION_CODE(major, minor, build) > ver)
+               return -EINVAL;
+
+       NXWR32(adapter, NETXEN_CAM_RAM(0x1fc), NETXEN_BDINFO_MAGIC);
        return 0;
 }
 
+static char *fw_name[] = { "nxromimg.bin", "nx3fwct.bin", "nx3fwmn.bin" };
+
+void netxen_request_firmware(struct netxen_adapter *adapter)
+{
+       u32 capability, flashed_ver;
+       int fw_type;
+       struct pci_dev *pdev = adapter->pdev;
+       int rc = 0;
+
+       if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
+               fw_type = NX_P2_MN_ROMIMAGE;
+               goto request_fw;
+       } else {
+               fw_type = NX_P3_CT_ROMIMAGE;
+               goto request_fw;
+       }
+
+request_mn:
+       capability = 0;
+
+       netxen_rom_fast_read(adapter,
+                       NX_FW_VERSION_OFFSET, (int *)&flashed_ver);
+       if (flashed_ver >= NETXEN_VERSION_CODE(4, 0, 220)) {
+               capability = NXRD32(adapter, NX_PEG_TUNE_CAPABILITY);
+               if (capability & NX_PEG_TUNE_MN_PRESENT) {
+                       fw_type = NX_P3_MN_ROMIMAGE;
+                       goto request_fw;
+               }
+       }
+
+request_fw:
+       rc = request_firmware(&adapter->fw, fw_name[fw_type], &pdev->dev);
+       if (rc != 0) {
+               if (fw_type == NX_P3_CT_ROMIMAGE) {
+                       msleep(1);
+                       goto request_mn;
+               }
+
+               adapter->fw = NULL;
+               goto done;
+       }
+
+       rc = netxen_validate_firmware(adapter, fw_name[fw_type]);
+       if (rc != 0) {
+               release_firmware(adapter->fw);
+
+               if (fw_type == NX_P3_CT_ROMIMAGE) {
+                       msleep(1);
+                       goto request_mn;
+               }
+
+               adapter->fw = NULL;
+               goto done;
+       }
+
+done:
+       if (adapter->fw)
+               dev_info(&pdev->dev, "loading firmware from file %s\n",
+                               fw_name[fw_type]);
+       else
+               dev_info(&pdev->dev, "loading firmware from flash\n");
+}
+
+
+void
+netxen_release_firmware(struct netxen_adapter *adapter)
+{
+       if (adapter->fw)
+               release_firmware(adapter->fw);
+}
+
 int netxen_initialize_adapter_offload(struct netxen_adapter *adapter)
 {
        uint64_t addr;
@@ -715,12 +899,12 @@ int netxen_initialize_adapter_offload(struct netxen_adapter *adapter)
        hi = (addr >> 32) & 0xffffffff;
        lo = addr & 0xffffffff;
 
-       adapter->pci_write_normalize(adapter, CRB_HOST_DUMMY_BUF_ADDR_HI, hi);
-       adapter->pci_write_normalize(adapter, CRB_HOST_DUMMY_BUF_ADDR_LO, lo);
+       NXWR32(adapter, CRB_HOST_DUMMY_BUF_ADDR_HI, hi);
+       NXWR32(adapter, CRB_HOST_DUMMY_BUF_ADDR_LO, lo);
 
        if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
                uint32_t temp = 0;
-               adapter->hw_write_wx(adapter, CRB_HOST_DUMMY_BUF, &temp, 4);
+               NXWR32(adapter, CRB_HOST_DUMMY_BUF, temp);
        }
 
        return 0;
@@ -762,8 +946,7 @@ int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val)
 
        if (!pegtune_val) {
                do {
-                       val = adapter->pci_read_normalize(adapter,
-                                       CRB_CMDPEG_STATE);
+                       val = NXRD32(adapter, CRB_CMDPEG_STATE);
 
                        if (val == PHAN_INITIALIZE_COMPLETE ||
                                val == PHAN_INITIALIZE_ACK)
@@ -774,7 +957,7 @@ int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val)
                } while (--retries);
 
                if (!retries) {
-                       pegtune_val = adapter->pci_read_normalize(adapter,
+                       pegtune_val = NXRD32(adapter,
                                        NETXEN_ROMUSB_GLB_PEGTUNE_DONE);
                        printk(KERN_WARNING "netxen_phantom_init: init failed, "
                                        "pegtune_val=%x\n", pegtune_val);
@@ -785,13 +968,14 @@ int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val)
        return 0;
 }
 
-int netxen_receive_peg_ready(struct netxen_adapter *adapter)
+static int
+netxen_receive_peg_ready(struct netxen_adapter *adapter)
 {
        u32 val = 0;
        int retries = 2000;
 
        do {
-               val = adapter->pci_read_normalize(adapter, CRB_RCVPEG_STATE);
+               val = NXRD32(adapter, CRB_RCVPEG_STATE);
 
                if (val == PHAN_PEG_RCV_INITIALIZED)
                        return 0;
@@ -809,6 +993,93 @@ int netxen_receive_peg_ready(struct netxen_adapter *adapter)
        return 0;
 }
 
+int netxen_init_firmware(struct netxen_adapter *adapter)
+{
+       int err;
+
+       err = netxen_receive_peg_ready(adapter);
+       if (err)
+               return err;
+
+       NXWR32(adapter, CRB_NIC_CAPABILITIES_HOST, INTR_SCHEME_PERPORT);
+       NXWR32(adapter, CRB_NIC_MSI_MODE_HOST, MSI_MODE_MULTIFUNC);
+       NXWR32(adapter, CRB_MPORT_MODE, MPORT_MULTI_FUNCTION_MODE);
+       NXWR32(adapter, CRB_CMDPEG_STATE, PHAN_INITIALIZE_ACK);
+
+       if (adapter->fw_version >= NETXEN_VERSION_CODE(4, 0, 222)) {
+               adapter->capabilities = NXRD32(adapter, CRB_FW_CAPABILITIES_1);
+       }
+
+       return err;
+}
+
+static void
+netxen_handle_linkevent(struct netxen_adapter *adapter, nx_fw_msg_t *msg)
+{
+       u32 cable_OUI;
+       u16 cable_len;
+       u16 link_speed;
+       u8  link_status, module, duplex, autoneg;
+       struct net_device *netdev = adapter->netdev;
+
+       adapter->has_link_events = 1;
+
+       cable_OUI = msg->body[1] & 0xffffffff;
+       cable_len = (msg->body[1] >> 32) & 0xffff;
+       link_speed = (msg->body[1] >> 48) & 0xffff;
+
+       link_status = msg->body[2] & 0xff;
+       duplex = (msg->body[2] >> 16) & 0xff;
+       autoneg = (msg->body[2] >> 24) & 0xff;
+
+       module = (msg->body[2] >> 8) & 0xff;
+       if (module == LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLE) {
+               printk(KERN_INFO "%s: unsupported cable: OUI 0x%x, length %d\n",
+                               netdev->name, cable_OUI, cable_len);
+       } else if (module == LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLELEN) {
+               printk(KERN_INFO "%s: unsupported cable length %d\n",
+                               netdev->name, cable_len);
+       }
+
+       netxen_advert_link_change(adapter, link_status);
+
+       /* update link parameters */
+       if (duplex == LINKEVENT_FULL_DUPLEX)
+               adapter->link_duplex = DUPLEX_FULL;
+       else
+               adapter->link_duplex = DUPLEX_HALF;
+       adapter->module_type = module;
+       adapter->link_autoneg = autoneg;
+       adapter->link_speed = link_speed;
+}
+
+static void
+netxen_handle_fw_message(int desc_cnt, int index,
+               struct nx_host_sds_ring *sds_ring)
+{
+       nx_fw_msg_t msg;
+       struct status_desc *desc;
+       int i = 0, opcode;
+
+       while (desc_cnt > 0 && i < 8) {
+               desc = &sds_ring->desc_head[index];
+               msg.words[i++] = le64_to_cpu(desc->status_desc_data[0]);
+               msg.words[i++] = le64_to_cpu(desc->status_desc_data[1]);
+
+               index = get_next_index(index, sds_ring->num_desc);
+               desc_cnt--;
+       }
+
+       opcode = netxen_get_nic_msg_opcode(msg.body[0]);
+       switch (opcode) {
+       case NX_NIC_C2H_OPCODE_GET_LINKEVENT_RESPONSE:
+               netxen_handle_linkevent(sds_ring->adapter, &msg);
+               break;
+       default:
+               break;
+       }
+}
+
 static int
 netxen_alloc_rx_skb(struct netxen_adapter *adapter,
                struct nx_host_rds_ring *rds_ring,
@@ -874,7 +1145,8 @@ no_skb:
 
 static struct netxen_rx_buffer *
 netxen_process_rcv(struct netxen_adapter *adapter,
-               int ring, int index, int length, int cksum, int pkt_offset)
+               int ring, int index, int length, int cksum, int pkt_offset,
+               struct nx_host_sds_ring *sds_ring)
 {
        struct net_device *netdev = adapter->netdev;
        struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
@@ -902,7 +1174,7 @@ netxen_process_rcv(struct netxen_adapter *adapter,
 
        skb->protocol = eth_type_trans(skb, netdev);
 
-       netif_receive_skb(skb);
+       napi_gro_receive(&sds_ring->napi, skb);
 
        adapter->stats.no_rcv++;
        adapter->stats.rxbytes += length;
@@ -927,35 +1199,53 @@ netxen_process_rcv_ring(struct nx_host_sds_ring *sds_ring, int max)
 
        int count = 0;
        u64 sts_data;
-       int opcode, ring, index, length, cksum, pkt_offset;
+       int opcode, ring, index, length, cksum, pkt_offset, desc_cnt;
 
        while (count < max) {
                desc = &sds_ring->desc_head[consumer];
-               sts_data = le64_to_cpu(desc->status_desc_data);
+               sts_data = le64_to_cpu(desc->status_desc_data[0]);
 
                if (!(sts_data & STATUS_OWNER_HOST))
                        break;
 
+               desc_cnt = netxen_get_sts_desc_cnt(sts_data);
                ring   = netxen_get_sts_type(sts_data);
+
                if (ring > RCV_RING_JUMBO)
-                       continue;
+                       goto skip;
 
                opcode = netxen_get_sts_opcode(sts_data);
 
+               switch (opcode) {
+               case NETXEN_NIC_RXPKT_DESC:
+               case NETXEN_OLD_RXPKT_DESC:
+                       break;
+               case NETXEN_NIC_RESPONSE_DESC:
+                       netxen_handle_fw_message(desc_cnt, consumer, sds_ring);
+               default:
+                       goto skip;
+               }
+
+               WARN_ON(desc_cnt > 1);
+
                index  = netxen_get_sts_refhandle(sts_data);
                length = netxen_get_sts_totallength(sts_data);
                cksum  = netxen_get_sts_status(sts_data);
                pkt_offset = netxen_get_sts_pkt_offset(sts_data);
 
                rxbuf = netxen_process_rcv(adapter, ring, index,
-                               length, cksum, pkt_offset);
+                               length, cksum, pkt_offset, sds_ring);
 
                if (rxbuf)
                        list_add_tail(&rxbuf->list, &sds_ring->free_list[ring]);
 
-               desc->status_desc_data = cpu_to_le64(STATUS_OWNER_PHANTOM);
-
-               consumer = get_next_index(consumer, sds_ring->num_desc);
+skip:
+               for (; desc_cnt > 0; desc_cnt--) {
+                       desc = &sds_ring->desc_head[consumer];
+                       desc->status_desc_data[0] =
+                               cpu_to_le64(STATUS_OWNER_PHANTOM);
+                       consumer = get_next_index(consumer, sds_ring->num_desc);
+               }
                count++;
        }
 
@@ -980,8 +1270,7 @@ netxen_process_rcv_ring(struct nx_host_sds_ring *sds_ring, int max)
 
        if (count) {
                sds_ring->consumer = consumer;
-               adapter->pci_write_normalize(adapter,
-                               sds_ring->crb_sts_consumer, consumer);
+               NXWR32(adapter, sds_ring->crb_sts_consumer, consumer);
        }
 
        return count;
@@ -990,23 +1279,24 @@ netxen_process_rcv_ring(struct nx_host_sds_ring *sds_ring, int max)
 /* Process Command status ring */
 int netxen_process_cmd_ring(struct netxen_adapter *adapter)
 {
-       u32 last_consumer, consumer;
+       u32 sw_consumer, hw_consumer;
        int count = 0, i;
        struct netxen_cmd_buffer *buffer;
        struct pci_dev *pdev = adapter->pdev;
        struct net_device *netdev = adapter->netdev;
        struct netxen_skb_frag *frag;
        int done = 0;
+       struct nx_host_tx_ring *tx_ring = adapter->tx_ring;
 
        if (!spin_trylock(&adapter->tx_clean_lock))
                return 1;
 
-       last_consumer = adapter->last_cmd_consumer;
-       barrier(); /* cmd_consumer can change underneath */
-       consumer = le32_to_cpu(*(adapter->cmd_consumer));
+       sw_consumer = tx_ring->sw_consumer;
+       barrier(); /* hw_consumer can change underneath */
+       hw_consumer = le32_to_cpu(*(tx_ring->hw_consumer));
 
-       while (last_consumer != consumer) {
-               buffer = &adapter->cmd_buf_arr[last_consumer];
+       while (sw_consumer != hw_consumer) {
+               buffer = &tx_ring->cmd_buf_arr[sw_consumer];
                if (buffer->skb) {
                        frag = &buffer->frag_array[0];
                        pci_unmap_single(pdev, frag->dma, frag->length,
@@ -1024,16 +1314,16 @@ int netxen_process_cmd_ring(struct netxen_adapter *adapter)
                        buffer->skb = NULL;
                }
 
-               last_consumer = get_next_index(last_consumer,
-                                              adapter->num_txd);
+               sw_consumer = get_next_index(sw_consumer, tx_ring->num_desc);
                if (++count >= MAX_STATUS_HANDLE)
                        break;
        }
 
-       if (count) {
-               adapter->last_cmd_consumer = last_consumer;
+       tx_ring->sw_consumer = sw_consumer;
+
+       if (count && netif_running(netdev)) {
                smp_mb();
-               if (netif_queue_stopped(netdev) && netif_running(netdev)) {
+               if (netif_queue_stopped(netdev) && netif_carrier_ok(netdev)) {
                        netif_tx_lock(netdev);
                        netif_wake_queue(netdev);
                        smp_mb();
@@ -1053,9 +1343,9 @@ int netxen_process_cmd_ring(struct netxen_adapter *adapter)
         * There is still a possible race condition and the host could miss an
         * interrupt. The card has to take care of this.
         */
-       barrier(); /* cmd_consumer can change underneath */
-       consumer = le32_to_cpu(*(adapter->cmd_consumer));
-       done = (last_consumer == consumer);
+       barrier(); /* hw_consumer can change underneath */
+       hw_consumer = le32_to_cpu(*(tx_ring->hw_consumer));
+       done = (sw_consumer == hw_consumer);
        spin_unlock(&adapter->tx_clean_lock);
 
        return (done);
@@ -1099,8 +1389,7 @@ netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ringid,
 
        if (count) {
                rds_ring->producer = producer;
-               adapter->pci_write_normalize(adapter,
-                               rds_ring->crb_rcv_producer,
+               NXWR32(adapter, rds_ring->crb_rcv_producer,
                                (producer-1) & (rds_ring->num_desc-1));
 
                if (adapter->fw_major < 4) {
@@ -1160,10 +1449,8 @@ netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter,
 
        if (count) {
                rds_ring->producer = producer;
-               adapter->pci_write_normalize(adapter,
-                       rds_ring->crb_rcv_producer,
+               NXWR32(adapter, rds_ring->crb_rcv_producer,
                                (producer - 1) & (rds_ring->num_desc - 1));
-                       wmb();
        }
        spin_unlock(&rds_ring->lock);
 }
index aef77289bd34d0577b7824a609170c537850c6e9..98737ef72936a34cef220d06cdfb30be0d941424 100644 (file)
@@ -29,7 +29,7 @@
  */
 
 #include <linux/vmalloc.h>
-#include <linux/highmem.h>
+#include <linux/interrupt.h>
 #include "netxen_nic_hw.h"
 
 #include "netxen_nic.h"
@@ -107,10 +107,9 @@ static uint32_t crb_cmd_producer[4] = {
 
 void
 netxen_nic_update_cmd_producer(struct netxen_adapter *adapter,
-               uint32_t crb_producer)
+               struct nx_host_tx_ring *tx_ring, u32 producer)
 {
-       adapter->pci_write_normalize(adapter,
-                       adapter->crb_addr_cmd_producer, crb_producer);
+       NXWR32(adapter, tx_ring->crb_cmd_producer, producer);
 }
 
 static uint32_t crb_cmd_consumer[4] = {
@@ -120,10 +119,9 @@ static uint32_t crb_cmd_consumer[4] = {
 
 static inline void
 netxen_nic_update_cmd_consumer(struct netxen_adapter *adapter,
-               u32 crb_consumer)
+               struct nx_host_tx_ring *tx_ring, u32 consumer)
 {
-       adapter->pci_write_normalize(adapter,
-                       adapter->crb_addr_cmd_consumer, crb_consumer);
+       NXWR32(adapter, tx_ring->crb_cmd_consumer, consumer);
 }
 
 static uint32_t msi_tgt_status[8] = {
@@ -139,37 +137,54 @@ static inline void netxen_nic_disable_int(struct nx_host_sds_ring *sds_ring)
 {
        struct netxen_adapter *adapter = sds_ring->adapter;
 
-       adapter->pci_write_normalize(adapter, sds_ring->crb_intr_mask, 0);
+       NXWR32(adapter, sds_ring->crb_intr_mask, 0);
 }
 
 static inline void netxen_nic_enable_int(struct nx_host_sds_ring *sds_ring)
 {
        struct netxen_adapter *adapter = sds_ring->adapter;
 
-       adapter->pci_write_normalize(adapter, sds_ring->crb_intr_mask, 0x1);
+       NXWR32(adapter, sds_ring->crb_intr_mask, 0x1);
 
        if (!NETXEN_IS_MSI_FAMILY(adapter))
                adapter->pci_write_immediate(adapter,
                                adapter->legacy_intr.tgt_mask_reg, 0xfbff);
 }
 
+static int
+netxen_alloc_sds_rings(struct netxen_recv_context *recv_ctx, int count)
+{
+       int size = sizeof(struct nx_host_sds_ring) * count;
+
+       recv_ctx->sds_rings = kzalloc(size, GFP_KERNEL);
+
+       return (recv_ctx->sds_rings == NULL);
+}
+
 static void
+netxen_free_sds_rings(struct netxen_recv_context *recv_ctx)
+{
+       if (recv_ctx->sds_rings != NULL)
+               kfree(recv_ctx->sds_rings);
+}
+
+static int
 netxen_napi_add(struct netxen_adapter *adapter, struct net_device *netdev)
 {
        int ring;
        struct nx_host_sds_ring *sds_ring;
        struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
 
-       if (adapter->flags & NETXEN_NIC_MSIX_ENABLED)
-               adapter->max_sds_rings = (num_online_cpus() >= 4) ? 4 : 2;
-       else
-               adapter->max_sds_rings = 1;
+       if (netxen_alloc_sds_rings(recv_ctx, adapter->max_sds_rings))
+               return 1;
 
        for (ring = 0; ring < adapter->max_sds_rings; ring++) {
                sds_ring = &recv_ctx->sds_rings[ring];
                netif_napi_add(netdev, &sds_ring->napi,
                                netxen_nic_poll, NETXEN_NETDEV_WEIGHT);
        }
+
+       return 0;
 }
 
 static void
@@ -195,8 +210,9 @@ netxen_napi_disable(struct netxen_adapter *adapter)
 
        for (ring = 0; ring < adapter->max_sds_rings; ring++) {
                sds_ring = &recv_ctx->sds_rings[ring];
-               netxen_nic_disable_int(sds_ring);
                napi_disable(&sds_ring->napi);
+               netxen_nic_disable_int(sds_ring);
+               synchronize_irq(sds_ring->irq);
        }
 }
 
@@ -240,7 +256,7 @@ nx_update_dma_mask(struct netxen_adapter *adapter)
 
        change = 0;
 
-       shift = netxen_nic_reg_read(adapter, CRB_DMA_SHIFT);
+       shift = NXRD32(adapter, CRB_DMA_SHIFT);
        if (shift >= 32)
                return 0;
 
@@ -268,10 +284,21 @@ static void netxen_check_options(struct netxen_adapter *adapter)
        else if (adapter->ahw.port_type == NETXEN_NIC_GBE)
                adapter->num_rxd = MAX_RCV_DESCRIPTORS_1G;
 
-       if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
+       adapter->msix_supported = 0;
+       if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
                adapter->msix_supported = !!use_msi_x;
-       else
-               adapter->msix_supported = 0;
+               adapter->rss_supported = !!use_msi_x;
+       } else if (adapter->fw_version >= NETXEN_VERSION_CODE(3, 4, 336)) {
+               switch (adapter->ahw.board_type) {
+               case NETXEN_BRDTYPE_P2_SB31_10G:
+               case NETXEN_BRDTYPE_P2_SB31_10G_CX4:
+                       adapter->msix_supported = !!use_msi_x;
+                       adapter->rss_supported = !!use_msi_x;
+                       break;
+               default:
+                       break;
+               }
+       }
 
        adapter->num_txd = MAX_CMD_DESCRIPTORS_HOST;
        adapter->num_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS;
@@ -287,43 +314,34 @@ netxen_check_hw_init(struct netxen_adapter *adapter, int first_boot)
 
        if (first_boot == 0x55555555) {
                /* This is the first boot after power up */
-               adapter->pci_write_normalize(adapter,
-                       NETXEN_CAM_RAM(0x1fc), NETXEN_BDINFO_MAGIC);
+               NXWR32(adapter, NETXEN_CAM_RAM(0x1fc), NETXEN_BDINFO_MAGIC);
 
                if (!NX_IS_REVISION_P2(adapter->ahw.revision_id))
                        return 0;
 
                /* PCI bus master workaround */
-               adapter->hw_read_wx(adapter,
-                       NETXEN_PCIE_REG(0x4), &first_boot, 4);
+               first_boot = NXRD32(adapter, NETXEN_PCIE_REG(0x4));
                if (!(first_boot & 0x4)) {
                        first_boot |= 0x4;
-                       adapter->hw_write_wx(adapter,
-                               NETXEN_PCIE_REG(0x4), &first_boot, 4);
-                       adapter->hw_read_wx(adapter,
-                               NETXEN_PCIE_REG(0x4), &first_boot, 4);
+                       NXWR32(adapter, NETXEN_PCIE_REG(0x4), first_boot);
+                       first_boot = NXRD32(adapter, NETXEN_PCIE_REG(0x4));
                }
 
                /* This is the first boot after power up */
-               adapter->hw_read_wx(adapter,
-                       NETXEN_ROMUSB_GLB_SW_RESET, &first_boot, 4);
+               first_boot = NXRD32(adapter, NETXEN_ROMUSB_GLB_SW_RESET);
                if (first_boot != 0x80000f) {
                        /* clear the register for future unloads/loads */
-                       adapter->pci_write_normalize(adapter,
-                                       NETXEN_CAM_RAM(0x1fc), 0);
+                       NXWR32(adapter, NETXEN_CAM_RAM(0x1fc), 0);
                        return -EIO;
                }
 
                /* Start P2 boot loader */
-               val = adapter->pci_read_normalize(adapter,
-                               NETXEN_ROMUSB_GLB_PEGTUNE_DONE);
-               adapter->pci_write_normalize(adapter,
-                               NETXEN_ROMUSB_GLB_PEGTUNE_DONE, val | 0x1);
+               val = NXRD32(adapter, NETXEN_ROMUSB_GLB_PEGTUNE_DONE);
+               NXWR32(adapter, NETXEN_ROMUSB_GLB_PEGTUNE_DONE, val | 0x1);
                timeout = 0;
                do {
                        msleep(1);
-                       val = adapter->pci_read_normalize(adapter,
-                                       NETXEN_CAM_RAM(0x1fc));
+                       val = NXRD32(adapter, NETXEN_CAM_RAM(0x1fc));
 
                        if (++timeout > 5000)
                                return -EIO;
@@ -342,24 +360,19 @@ static void netxen_set_port_mode(struct netxen_adapter *adapter)
                (val == NETXEN_BRDTYPE_P3_XG_LOM)) {
                if (port_mode == NETXEN_PORT_MODE_802_3_AP) {
                        data = NETXEN_PORT_MODE_802_3_AP;
-                       adapter->hw_write_wx(adapter,
-                               NETXEN_PORT_MODE_ADDR, &data, 4);
+                       NXWR32(adapter, NETXEN_PORT_MODE_ADDR, data);
                } else if (port_mode == NETXEN_PORT_MODE_XG) {
                        data = NETXEN_PORT_MODE_XG;
-                       adapter->hw_write_wx(adapter,
-                               NETXEN_PORT_MODE_ADDR, &data, 4);
+                       NXWR32(adapter, NETXEN_PORT_MODE_ADDR, data);
                } else if (port_mode == NETXEN_PORT_MODE_AUTO_NEG_1G) {
                        data = NETXEN_PORT_MODE_AUTO_NEG_1G;
-                       adapter->hw_write_wx(adapter,
-                               NETXEN_PORT_MODE_ADDR, &data, 4);
+                       NXWR32(adapter, NETXEN_PORT_MODE_ADDR, data);
                } else if (port_mode == NETXEN_PORT_MODE_AUTO_NEG_XG) {
                        data = NETXEN_PORT_MODE_AUTO_NEG_XG;
-                       adapter->hw_write_wx(adapter,
-                               NETXEN_PORT_MODE_ADDR, &data, 4);
+                       NXWR32(adapter, NETXEN_PORT_MODE_ADDR, data);
                } else {
                        data = NETXEN_PORT_MODE_AUTO_NEG;
-                       adapter->hw_write_wx(adapter,
-                               NETXEN_PORT_MODE_ADDR, &data, 4);
+                       NXWR32(adapter, NETXEN_PORT_MODE_ADDR, data);
                }
 
                if ((wol_port_mode != NETXEN_PORT_MODE_802_3_AP) &&
@@ -368,8 +381,7 @@ static void netxen_set_port_mode(struct netxen_adapter *adapter)
                        (wol_port_mode != NETXEN_PORT_MODE_AUTO_NEG_XG)) {
                        wol_port_mode = NETXEN_PORT_MODE_AUTO_NEG;
                }
-               adapter->hw_write_wx(adapter, NETXEN_WOL_PORT_MODE,
-                       &wol_port_mode, 4);
+               NXWR32(adapter, NETXEN_WOL_PORT_MODE, wol_port_mode);
        }
 }
 
@@ -389,11 +401,11 @@ static void netxen_set_msix_bit(struct pci_dev *pdev, int enable)
        }
 }
 
-static void netxen_init_msix_entries(struct netxen_adapter *adapter)
+static void netxen_init_msix_entries(struct netxen_adapter *adapter, int count)
 {
        int i;
 
-       for (i = 0; i < MSIX_ENTRIES_PER_ADAPTER; i++)
+       for (i = 0; i < count; i++)
                adapter->msix_entries[i].entry = i;
 }
 
@@ -424,20 +436,38 @@ netxen_read_mac_addr(struct netxen_adapter *adapter)
 
        if (!is_valid_ether_addr(netdev->perm_addr))
                dev_warn(&pdev->dev, "Bad MAC address %pM.\n", netdev->dev_addr);
-       else
-               adapter->macaddr_set(adapter, netdev->dev_addr);
 
        return 0;
 }
 
+int netxen_nic_set_mac(struct net_device *netdev, void *p)
+{
+       struct netxen_adapter *adapter = netdev_priv(netdev);
+       struct sockaddr *addr = p;
+
+       if (!is_valid_ether_addr(addr->sa_data))
+               return -EINVAL;
+
+       if (netif_running(netdev)) {
+               netif_device_detach(netdev);
+               netxen_napi_disable(adapter);
+       }
+
+       memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
+       adapter->macaddr_set(adapter, addr->sa_data);
+
+       if (netif_running(netdev)) {
+               netif_device_attach(netdev);
+               netxen_napi_enable(adapter);
+       }
+       return 0;
+}
+
 static void netxen_set_multicast_list(struct net_device *dev)
 {
        struct netxen_adapter *adapter = netdev_priv(dev);
 
-       if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
-               netxen_p3_nic_set_multi(dev);
-       else
-               netxen_p2_nic_set_multi(dev);
+       adapter->set_multi(dev);
 }
 
 static const struct net_device_ops netxen_netdev_ops = {
@@ -460,10 +490,17 @@ netxen_setup_intr(struct netxen_adapter *adapter)
 {
        struct netxen_legacy_intr_set *legacy_intrp;
        struct pci_dev *pdev = adapter->pdev;
+       int err, num_msix;
+
+       if (adapter->rss_supported) {
+               num_msix = (num_online_cpus() >= MSIX_ENTRIES_PER_ADAPTER) ?
+                       MSIX_ENTRIES_PER_ADAPTER : 2;
+       } else
+               num_msix = 1;
+
+       adapter->max_sds_rings = 1;
 
        adapter->flags &= ~(NETXEN_NIC_MSI_ENABLED | NETXEN_NIC_MSIX_ENABLED);
-       adapter->intr_scheme = -1;
-       adapter->msi_mode = -1;
 
        if (adapter->ahw.revision_id >= NX_P3_B0)
                legacy_intrp = &legacy_intr[adapter->ahw.pci_func];
@@ -478,24 +515,36 @@ netxen_setup_intr(struct netxen_adapter *adapter)
 
        if (adapter->msix_supported) {
 
-               netxen_init_msix_entries(adapter);
-               if (pci_enable_msix(pdev, adapter->msix_entries,
-                                       MSIX_ENTRIES_PER_ADAPTER))
-                       goto request_msi;
+               netxen_init_msix_entries(adapter, num_msix);
+               err = pci_enable_msix(pdev, adapter->msix_entries, num_msix);
+               if (err == 0) {
+                       adapter->flags |= NETXEN_NIC_MSIX_ENABLED;
+                       netxen_set_msix_bit(pdev, 1);
 
-               adapter->flags |= NETXEN_NIC_MSIX_ENABLED;
-               netxen_set_msix_bit(pdev, 1);
-               dev_info(&pdev->dev, "using msi-x interrupts\n");
+                       if (adapter->rss_supported)
+                               adapter->max_sds_rings = num_msix;
 
-       } else {
-request_msi:
-               if (use_msi && !pci_enable_msi(pdev)) {
-                       adapter->flags |= NETXEN_NIC_MSI_ENABLED;
-                       dev_info(&pdev->dev, "using msi interrupts\n");
-               } else
-                       dev_info(&pdev->dev, "using legacy interrupts\n");
+                       dev_info(&pdev->dev, "using msi-x interrupts\n");
+                       return;
+               }
+
+               if (err > 0)
+                       pci_disable_msix(pdev);
+
+               /* fall through for msi */
+       }
+
+       if (use_msi && !pci_enable_msi(pdev)) {
+               adapter->flags |= NETXEN_NIC_MSI_ENABLED;
+               adapter->msi_tgt_status =
+                       msi_tgt_status[adapter->ahw.pci_func];
+               dev_info(&pdev->dev, "using msi interrupts\n");
                adapter->msix_entries[0].vector = pdev->irq;
+               return;
        }
+
+       dev_info(&pdev->dev, "using legacy interrupts\n");
+       adapter->msix_entries[0].vector = pdev->irq;
 }
 
 static void
@@ -552,8 +601,6 @@ netxen_setup_pci_map(struct netxen_adapter *adapter)
        adapter->hw_read_wx = netxen_nic_hw_read_wx_128M;
        adapter->pci_read_immediate = netxen_nic_pci_read_immediate_128M;
        adapter->pci_write_immediate = netxen_nic_pci_write_immediate_128M;
-       adapter->pci_read_normalize = netxen_nic_pci_read_normalize_128M;
-       adapter->pci_write_normalize = netxen_nic_pci_write_normalize_128M;
        adapter->pci_set_window = netxen_nic_pci_set_window_128M;
        adapter->pci_mem_read = netxen_nic_pci_mem_read_128M;
        adapter->pci_mem_write = netxen_nic_pci_mem_write_128M;
@@ -575,9 +622,6 @@ netxen_setup_pci_map(struct netxen_adapter *adapter)
                adapter->pci_read_immediate = netxen_nic_pci_read_immediate_2M;
                adapter->pci_write_immediate =
                        netxen_nic_pci_write_immediate_2M;
-               adapter->pci_read_normalize = netxen_nic_pci_read_normalize_2M;
-               adapter->pci_write_normalize =
-                       netxen_nic_pci_write_normalize_2M;
                adapter->pci_set_window = netxen_nic_pci_set_window_2M;
                adapter->pci_mem_read = netxen_nic_pci_mem_read_2M;
                adapter->pci_mem_write = netxen_nic_pci_mem_write_2M;
@@ -643,25 +687,22 @@ err_out:
 }
 
 static int
-netxen_start_firmware(struct netxen_adapter *adapter)
+netxen_start_firmware(struct netxen_adapter *adapter, int request_fw)
 {
        int val, err, first_boot;
        struct pci_dev *pdev = adapter->pdev;
 
        int first_driver = 0;
-       if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
-               if (adapter->ahw.pci_func == 0)
-                       first_driver = 1;
-       } else {
-               if (adapter->portnum == 0)
-                       first_driver = 1;
-       }
+
+       if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
+               first_driver = (adapter->portnum == 0);
+       else
+               first_driver = (adapter->ahw.pci_func == 0);
 
        if (!first_driver)
                return 0;
 
-       first_boot = adapter->pci_read_normalize(adapter,
-                       NETXEN_CAM_RAM(0x1fc));
+       first_boot = NXRD32(adapter, NETXEN_CAM_RAM(0x1fc));
 
        err = netxen_check_hw_init(adapter, first_boot);
        if (err) {
@@ -669,14 +710,16 @@ netxen_start_firmware(struct netxen_adapter *adapter)
                return err;
        }
 
+       if (request_fw)
+               netxen_request_firmware(adapter);
+
        if (first_boot != 0x55555555) {
-               adapter->pci_write_normalize(adapter,
-                                       CRB_CMDPEG_STATE, 0);
+               NXWR32(adapter, CRB_CMDPEG_STATE, 0);
                netxen_pinit_from_rom(adapter, 0);
                msleep(1);
        }
 
-       netxen_nic_reg_write(adapter, CRB_DMA_SHIFT, 0x55555555);
+       NXWR32(adapter, CRB_DMA_SHIFT, 0x55555555);
        if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
                netxen_set_port_mode(adapter);
 
@@ -688,8 +731,7 @@ netxen_start_firmware(struct netxen_adapter *adapter)
                val = 0x7654;
                if (adapter->ahw.port_type == NETXEN_NIC_XGBE)
                        val |= 0x0f000000;
-               netxen_crb_writelit_adapter(adapter,
-                               NETXEN_MAC_ADDR_CNTL_REG, val);
+               NXWR32(adapter, NETXEN_MAC_ADDR_CNTL_REG, val);
 
        }
 
@@ -703,7 +745,7 @@ netxen_start_firmware(struct netxen_adapter *adapter)
        val = (_NETXEN_NIC_LINUX_MAJOR << 16)
                | ((_NETXEN_NIC_LINUX_MINOR << 8))
                | (_NETXEN_NIC_LINUX_SUBVERSION);
-       adapter->pci_write_normalize(adapter, CRB_DRIVER_VERSION, val);
+       NXWR32(adapter, CRB_DRIVER_VERSION, val);
 
        /* Handshake with the card before we register the devices. */
        err = netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE);
@@ -726,15 +768,6 @@ netxen_nic_request_irq(struct netxen_adapter *adapter)
        struct net_device *netdev = adapter->netdev;
        struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
 
-       if ((adapter->msi_mode != MSI_MODE_MULTIFUNC) ||
-               (adapter->intr_scheme != INTR_SCHEME_PERPORT)) {
-               printk(KERN_ERR "%s: Firmware interrupt scheme is "
-                               "incompatible with driver\n",
-                               netdev->name);
-               adapter->driver_mismatch = 1;
-               return -EINVAL;
-       }
-
        if (adapter->flags & NETXEN_NIC_MSIX_ENABLED)
                handler = netxen_msix_intr;
        else if (adapter->flags & NETXEN_NIC_MSI_ENABLED)
@@ -747,7 +780,7 @@ netxen_nic_request_irq(struct netxen_adapter *adapter)
 
        for (ring = 0; ring < adapter->max_sds_rings; ring++) {
                sds_ring = &recv_ctx->sds_rings[ring];
-               sprintf(sds_ring->name, "%16s[%d]", netdev->name, ring);
+               sprintf(sds_ring->name, "%s[%d]", netdev->name, ring);
                err = request_irq(sds_ring->irq, handler,
                                  flags, sds_ring->name, sds_ring);
                if (err)
@@ -782,22 +815,26 @@ netxen_nic_up(struct netxen_adapter *adapter, struct net_device *netdev)
                                netxen_nic_driver_name, adapter->portnum);
                return err;
        }
-       adapter->macaddr_set(adapter, netdev->dev_addr);
-
-       netxen_nic_set_link_parameters(adapter);
+       if (NX_IS_REVISION_P2(adapter->ahw.revision_id))
+               adapter->macaddr_set(adapter, netdev->dev_addr);
 
-       netxen_set_multicast_list(netdev);
-       if (adapter->set_mtu)
-               adapter->set_mtu(adapter, netdev->mtu);
+       adapter->set_multi(netdev);
+       adapter->set_mtu(adapter, netdev->mtu);
 
        adapter->ahw.linkup = 0;
-       mod_timer(&adapter->watchdog_timer, jiffies);
 
        netxen_napi_enable(adapter);
 
        if (adapter->max_sds_rings > 1)
                netxen_config_rss(adapter, 1);
 
+       if (adapter->capabilities & NX_FW_CAPABILITY_LINK_NOTIFICATION)
+               netxen_linkevent_request(adapter, 1);
+       else
+               netxen_nic_set_link_parameters(adapter);
+
+       mod_timer(&adapter->watchdog_timer, jiffies);
+
        return 0;
 }
 
@@ -806,11 +843,15 @@ netxen_nic_down(struct netxen_adapter *adapter, struct net_device *netdev)
 {
        netif_carrier_off(netdev);
        netif_stop_queue(netdev);
-       netxen_napi_disable(adapter);
 
        if (adapter->stop_port)
                adapter->stop_port(adapter);
 
+       if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
+               netxen_p3_free_mac_list(adapter);
+
+       netxen_napi_disable(adapter);
+
        netxen_release_tx_buffers(adapter);
 
        FLUSH_SCHEDULED_WORK();
@@ -825,6 +866,7 @@ netxen_nic_attach(struct netxen_adapter *adapter)
        struct pci_dev *pdev = adapter->pdev;
        int err, ring;
        struct nx_host_rds_ring *rds_ring;
+       struct nx_host_tx_ring *tx_ring;
 
        err = netxen_init_firmware(adapter);
        if (err != 0) {
@@ -854,13 +896,12 @@ netxen_nic_attach(struct netxen_adapter *adapter)
        }
 
        if (adapter->fw_major < 4) {
-               adapter->crb_addr_cmd_producer =
-                       crb_cmd_producer[adapter->portnum];
-               adapter->crb_addr_cmd_consumer =
-                       crb_cmd_consumer[adapter->portnum];
+               tx_ring = adapter->tx_ring;
+               tx_ring->crb_cmd_producer = crb_cmd_producer[adapter->portnum];
+               tx_ring->crb_cmd_consumer = crb_cmd_consumer[adapter->portnum];
 
-               netxen_nic_update_cmd_producer(adapter, 0);
-               netxen_nic_update_cmd_consumer(adapter, 0);
+               netxen_nic_update_cmd_producer(adapter, tx_ring, 0);
+               netxen_nic_update_cmd_consumer(adapter, tx_ring, 0);
        }
 
        for (ring = 0; ring < adapter->max_rds_rings; ring++) {
@@ -889,10 +930,9 @@ err_out_free_sw:
 static void
 netxen_nic_detach(struct netxen_adapter *adapter)
 {
-       netxen_nic_free_irq(adapter);
-
        netxen_release_rx_buffers(adapter);
        netxen_free_hw_resources(adapter);
+       netxen_nic_free_irq(adapter);
        netxen_free_sw_resources(adapter);
 
        adapter->is_up = 0;
@@ -957,6 +997,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        rwlock_init(&adapter->adapter_lock);
        spin_lock_init(&adapter->tx_clean_lock);
+       INIT_LIST_HEAD(&adapter->mac_list);
 
        err = netxen_setup_pci_map(adapter);
        if (err)
@@ -979,6 +1020,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        SET_ETHTOOL_OPS(netdev, &netxen_nic_ethtool_ops);
 
        netdev->features |= (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO);
+       netdev->features |= (NETIF_F_GRO);
        netdev->vlan_features |= (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO);
 
        if (NX_IS_REVISION_P3(revision_id)) {
@@ -1011,7 +1053,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                break;
        }
 
-       err = netxen_start_firmware(adapter);
+       err = netxen_start_firmware(adapter, 1);
        if (err)
                goto err_out_iounmap;
 
@@ -1024,8 +1066,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
         */
        adapter->physical_port = adapter->portnum;
        if (adapter->fw_major < 4) {
-               i = adapter->pci_read_normalize(adapter,
-                               CRB_V2P(adapter->portnum));
+               i = NXRD32(adapter, CRB_V2P(adapter->portnum));
                if (i != 0x55555555)
                        adapter->physical_port = i;
        }
@@ -1036,10 +1077,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        netdev->irq = adapter->msix_entries[0].vector;
 
-       netxen_napi_add(adapter, netdev);
-
-       err = netxen_receive_peg_ready(adapter);
-       if (err)
+       if (netxen_napi_add(adapter, netdev))
                goto err_out_disable_msi;
 
        init_timer(&adapter->watchdog_timer);
@@ -1113,18 +1151,18 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev)
 
        if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) {
                netxen_nic_detach(adapter);
-
-               if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
-                       netxen_p3_free_mac_list(adapter);
        }
 
        if (adapter->portnum == 0)
                netxen_free_adapter_offload(adapter);
 
        netxen_teardown_intr(adapter);
+       netxen_free_sds_rings(&adapter->recv_ctx);
 
        netxen_cleanup_pci_map(adapter);
 
+       netxen_release_firmware(adapter);
+
        pci_release_regions(pdev);
        pci_disable_device(pdev);
        pci_set_drvdata(pdev, NULL);
@@ -1176,7 +1214,7 @@ netxen_nic_resume(struct pci_dev *pdev)
 
        adapter->curr_window = 255;
 
-       err = netxen_start_firmware(adapter);
+       err = netxen_start_firmware(adapter, 0);
        if (err) {
                dev_err(&pdev->dev, "failed to start firmware\n");
                return err;
@@ -1315,7 +1353,7 @@ static int
 netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 {
        struct netxen_adapter *adapter = netdev_priv(netdev);
-       struct netxen_hardware_context *hw = &adapter->ahw;
+       struct nx_host_tx_ring *tx_ring = adapter->tx_ring;
        unsigned int first_seg_len = skb->len - skb->data_len;
        struct netxen_cmd_buffer *pbuf;
        struct netxen_skb_frag *buffrag;
@@ -1326,28 +1364,26 @@ netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 
        u32 producer, consumer;
        int frag_count, no_of_desc;
-       u32 num_txd = adapter->num_txd;
+       u32 num_txd = tx_ring->num_desc;
        bool is_tso = false;
 
        frag_count = skb_shinfo(skb)->nr_frags + 1;
 
-       /* There 4 fragments per descriptor */
+       /* 4 fragments per cmd des */
        no_of_desc = (frag_count + 3) >> 2;
 
-       producer = adapter->cmd_producer;
+       producer = tx_ring->producer;
        smp_mb();
-       consumer = adapter->last_cmd_consumer;
-       if ((no_of_desc+2) > find_diff_among(producer, consumer, num_txd)) {
+       consumer = tx_ring->sw_consumer;
+       if ((no_of_desc+2) >= find_diff_among(producer, consumer, num_txd)) {
                netif_stop_queue(netdev);
                smp_mb();
                return NETDEV_TX_BUSY;
        }
 
-       /* Copy the descriptors into the hardware    */
-       hwdesc = &hw->cmd_desc_head[producer];
+       hwdesc = &tx_ring->desc_head[producer];
        netxen_clear_cmddesc((u64 *)hwdesc);
-       /* Take skb->data itself */
-       pbuf = &adapter->cmd_buf_arr[producer];
+       pbuf = &tx_ring->cmd_buf_arr[producer];
 
        is_tso = netxen_tso_check(netdev, hwdesc, skb);
 
@@ -1376,9 +1412,9 @@ netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
                if ((i & 0x3) == 0) {
                        k = 0;
                        producer = get_next_index(producer, num_txd);
-                       hwdesc = &hw->cmd_desc_head[producer];
+                       hwdesc = &tx_ring->desc_head[producer];
                        netxen_clear_cmddesc((u64 *)hwdesc);
-                       pbuf = &adapter->cmd_buf_arr[producer];
+                       pbuf = &tx_ring->cmd_buf_arr[producer];
                        pbuf->skb = NULL;
                }
                frag = &skb_shinfo(skb)->frags[i - 1];
@@ -1430,8 +1466,8 @@ netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
                        more_hdr = 0;
                }
                /* copy the MAC/IP/TCP headers to the cmd descriptor list */
-               hwdesc = &hw->cmd_desc_head[producer];
-               pbuf = &adapter->cmd_buf_arr[producer];
+               hwdesc = &tx_ring->desc_head[producer];
+               pbuf = &tx_ring->cmd_buf_arr[producer];
                pbuf->skb = NULL;
 
                /* copy the first 64 bytes */
@@ -1440,8 +1476,8 @@ netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
                producer = get_next_index(producer, num_txd);
 
                if (more_hdr) {
-                       hwdesc = &hw->cmd_desc_head[producer];
-                       pbuf = &adapter->cmd_buf_arr[producer];
+                       hwdesc = &tx_ring->desc_head[producer];
+                       pbuf = &tx_ring->cmd_buf_arr[producer];
                        pbuf->skb = NULL;
                        /* copy the next 64 bytes - should be enough except
                         * for pathological case
@@ -1454,13 +1490,12 @@ netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
                }
        }
 
-       adapter->cmd_producer = producer;
+       tx_ring->producer = producer;
        adapter->stats.txbytes += skb->len;
 
-       netxen_nic_update_cmd_producer(adapter, adapter->cmd_producer);
+       netxen_nic_update_cmd_producer(adapter, tx_ring, producer);
 
        adapter->stats.xmitcalled++;
-       netdev->trans_start = jiffies;
 
        return NETDEV_TX_OK;
 
@@ -1476,7 +1511,7 @@ static int netxen_nic_check_temp(struct netxen_adapter *adapter)
        uint32_t temp, temp_state, temp_val;
        int rv = 0;
 
-       temp = adapter->pci_read_normalize(adapter, CRB_TEMP_STATE);
+       temp = NXRD32(adapter, CRB_TEMP_STATE);
 
        temp_state = nx_get_temp_state(temp);
        temp_val = nx_get_temp_val(temp);
@@ -1510,26 +1545,9 @@ static int netxen_nic_check_temp(struct netxen_adapter *adapter)
        return rv;
 }
 
-static void netxen_nic_handle_phy_intr(struct netxen_adapter *adapter)
+void netxen_advert_link_change(struct netxen_adapter *adapter, int linkup)
 {
        struct net_device *netdev = adapter->netdev;
-       u32 val, port, linkup;
-
-       port = adapter->physical_port;
-
-       if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
-               val = adapter->pci_read_normalize(adapter, CRB_XG_STATE_P3);
-               val = XG_LINK_STATE_P3(adapter->ahw.pci_func, val);
-               linkup = (val == XG_LINK_UP_P3);
-       } else {
-               val = adapter->pci_read_normalize(adapter, CRB_XG_STATE);
-               if (adapter->ahw.port_type == NETXEN_NIC_GBE)
-                       linkup = (val >> port) & 1;
-               else {
-                       val = (val >> port*8) & 0xff;
-                       linkup = (val == XG_LINK_UP);
-               }
-       }
 
        if (adapter->ahw.linkup && !linkup) {
                printk(KERN_INFO "%s: %s NIC Link is down\n",
@@ -1540,7 +1558,9 @@ static void netxen_nic_handle_phy_intr(struct netxen_adapter *adapter)
                        netif_stop_queue(netdev);
                }
 
-               netxen_nic_set_link_parameters(adapter);
+               if (!adapter->has_link_events)
+                       netxen_nic_set_link_parameters(adapter);
+
        } else if (!adapter->ahw.linkup && linkup) {
                printk(KERN_INFO "%s: %s NIC Link is up\n",
                       netxen_nic_driver_name, netdev->name);
@@ -1550,8 +1570,32 @@ static void netxen_nic_handle_phy_intr(struct netxen_adapter *adapter)
                        netif_wake_queue(netdev);
                }
 
-               netxen_nic_set_link_parameters(adapter);
+               if (!adapter->has_link_events)
+                       netxen_nic_set_link_parameters(adapter);
+       }
+}
+
+static void netxen_nic_handle_phy_intr(struct netxen_adapter *adapter)
+{
+       u32 val, port, linkup;
+
+       port = adapter->physical_port;
+
+       if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
+               val = NXRD32(adapter, CRB_XG_STATE_P3);
+               val = XG_LINK_STATE_P3(adapter->ahw.pci_func, val);
+               linkup = (val == XG_LINK_UP_P3);
+       } else {
+               val = NXRD32(adapter, CRB_XG_STATE);
+               if (adapter->ahw.port_type == NETXEN_NIC_GBE)
+                       linkup = (val >> port) & 1;
+               else {
+                       val = (val >> port*8) & 0xff;
+                       linkup = (val == XG_LINK_UP);
+               }
        }
+
+       netxen_advert_link_change(adapter, linkup);
 }
 
 static void netxen_watchdog(unsigned long v)
@@ -1569,7 +1613,8 @@ void netxen_watchdog_task(struct work_struct *work)
        if ((adapter->portnum  == 0) && netxen_nic_check_temp(adapter))
                return;
 
-       netxen_nic_handle_phy_intr(adapter);
+       if (!adapter->has_link_events)
+               netxen_nic_handle_phy_intr(adapter);
 
        if (netif_running(adapter->netdev))
                mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ);
@@ -1598,10 +1643,6 @@ static void netxen_tx_timeout_task(struct work_struct *work)
        netif_wake_queue(adapter->netdev);
 }
 
-/*
- * netxen_nic_get_stats - Get System Network Statistics
- * @netdev: network interface device structure
- */
 struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev)
 {
        struct netxen_adapter *adapter = netdev_priv(netdev);
@@ -1609,22 +1650,11 @@ struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev)
 
        memset(stats, 0, sizeof(*stats));
 
-       /* total packets received   */
        stats->rx_packets = adapter->stats.no_rcv;
-       /* total packets transmitted    */
-       stats->tx_packets = adapter->stats.xmitedframes +
-               adapter->stats.xmitfinished;
-       /* total bytes received     */
+       stats->tx_packets = adapter->stats.xmitfinished;
        stats->rx_bytes = adapter->stats.rxbytes;
-       /* total bytes transmitted  */
        stats->tx_bytes = adapter->stats.txbytes;
-       /* bad packets received     */
-       stats->rx_errors = adapter->stats.rcvdbadskb;
-       /* packet transmit problems */
-       stats->tx_errors = adapter->stats.nocmddescriptor;
-       /* no space in linux buffers    */
        stats->rx_dropped = adapter->stats.rxdropped;
-       /* no space available in linux  */
        stats->tx_dropped = adapter->stats.txdropped;
 
        return stats;
@@ -1651,15 +1681,14 @@ static irqreturn_t netxen_intr(int irq, void *data)
        } else {
                unsigned long our_int = 0;
 
-               our_int = adapter->pci_read_normalize(adapter, CRB_INT_VECTOR);
+               our_int = NXRD32(adapter, CRB_INT_VECTOR);
 
                /* not our interrupt */
                if (!test_and_clear_bit((7 + adapter->portnum), &our_int))
                        return IRQ_NONE;
 
                /* claim interrupt */
-               adapter->pci_write_normalize(adapter,
-                               CRB_INT_VECTOR, (our_int & 0xffffffff));
+               NXWR32(adapter, CRB_INT_VECTOR, (our_int & 0xffffffff));
        }
 
        /* clear interrupt */
@@ -1685,7 +1714,7 @@ static irqreturn_t netxen_msi_intr(int irq, void *data)
 
        /* clear interrupt */
        adapter->pci_write_immediate(adapter,
-                       msi_tgt_status[adapter->ahw.pci_func], 0xffffffff);
+                       adapter->msi_tgt_status, 0xffffffff);
 
        napi_schedule(&sds_ring->napi);
        return IRQ_HANDLED;
index d85203203d4d2afb5c9f3cfc888d0c5b1419776b..5941c79be723309b3057b8356eef59e5c883befc 100644 (file)
@@ -43,8 +43,7 @@ static int phy_lock(struct netxen_adapter *adapter)
        int done = 0, timeout = 0;
 
        while (!done) {
-               done = netxen_nic_reg_read(adapter,
-                               NETXEN_PCIE_REG(PCIE_SEM3_LOCK));
+               done = NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM3_LOCK));
                if (done == 1)
                        break;
                if (timeout >= phy_lock_timeout) {
@@ -59,8 +58,7 @@ static int phy_lock(struct netxen_adapter *adapter)
                }
        }
 
-       netxen_crb_writelit_adapter(adapter,
-                       NETXEN_PHY_LOCK_ID, PHY_LOCK_DRIVER);
+       NXWR32(adapter, NETXEN_PHY_LOCK_ID, PHY_LOCK_DRIVER);
        return 0;
 }
 
@@ -105,9 +103,7 @@ int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long reg,
         * so it cannot be in reset
         */
 
-       if (adapter->hw_read_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0),
-                                 &mac_cfg0, 4))
-               return -EIO;
+       mac_cfg0 = NXRD32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0));
        if (netxen_gb_get_soft_reset(mac_cfg0)) {
                __u32 temp;
                temp = 0;
@@ -115,9 +111,7 @@ int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long reg,
                netxen_gb_rx_reset_pb(temp);
                netxen_gb_tx_reset_mac(temp);
                netxen_gb_rx_reset_mac(temp);
-               if (adapter->hw_write_wx(adapter,
-                                          NETXEN_NIU_GB_MAC_CONFIG_0(0),
-                                          &temp, 4))
+               if (NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0), temp))
                        return -EIO;
                restore = 1;
        }
@@ -125,43 +119,32 @@ int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long reg,
        address = 0;
        netxen_gb_mii_mgmt_reg_addr(address, reg);
        netxen_gb_mii_mgmt_phy_addr(address, phy);
-       if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_ADDR(0),
-                                  &address, 4))
+       if (NXWR32(adapter, NETXEN_NIU_GB_MII_MGMT_ADDR(0), address))
                return -EIO;
        command = 0;            /* turn off any prior activity */
-       if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0),
-                                  &command, 4))
+       if (NXWR32(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0), command))
                return -EIO;
        /* send read command */
        netxen_gb_mii_mgmt_set_read_cycle(command);
-       if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0),
-                                  &command, 4))
+       if (NXWR32(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0), command))
                return -EIO;
 
        status = 0;
        do {
-               if (adapter->hw_read_wx(adapter,
-                                         NETXEN_NIU_GB_MII_MGMT_INDICATE(0),
-                                         &status, 4))
-                       return -EIO;
+               status = NXRD32(adapter, NETXEN_NIU_GB_MII_MGMT_INDICATE(0));
                timeout++;
        } while ((netxen_get_gb_mii_mgmt_busy(status)
                  || netxen_get_gb_mii_mgmt_notvalid(status))
                 && (timeout++ < NETXEN_NIU_PHY_WAITMAX));
 
        if (timeout < NETXEN_NIU_PHY_WAITMAX) {
-               if (adapter->hw_read_wx(adapter,
-                                         NETXEN_NIU_GB_MII_MGMT_STATUS(0),
-                                         readval, 4))
-                       return -EIO;
+               *readval = NXRD32(adapter, NETXEN_NIU_GB_MII_MGMT_STATUS(0));
                result = 0;
        } else
                result = -1;
 
        if (restore)
-               if (adapter->hw_write_wx(adapter,
-                                          NETXEN_NIU_GB_MAC_CONFIG_0(0),
-                                          &mac_cfg0, 4))
+               if (NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0), mac_cfg0))
                        return -EIO;
        phy_unlock(adapter);
        return result;
@@ -197,9 +180,7 @@ int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter, long reg,
         * cannot be in reset
         */
 
-       if (adapter->hw_read_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0),
-                                 &mac_cfg0, 4))
-               return -EIO;
+       mac_cfg0 = NXRD32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0));
        if (netxen_gb_get_soft_reset(mac_cfg0)) {
                __u32 temp;
                temp = 0;
@@ -208,35 +189,27 @@ int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter, long reg,
                netxen_gb_tx_reset_mac(temp);
                netxen_gb_rx_reset_mac(temp);
 
-               if (adapter->hw_write_wx(adapter,
-                                          NETXEN_NIU_GB_MAC_CONFIG_0(0),
-                                          &temp, 4))
+               if (NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0), temp))
                        return -EIO;
                restore = 1;
        }
 
        command = 0;            /* turn off any prior activity */
-       if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0),
-                                  &command, 4))
+       if (NXWR32(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0), command))
                return -EIO;
 
        address = 0;
        netxen_gb_mii_mgmt_reg_addr(address, reg);
        netxen_gb_mii_mgmt_phy_addr(address, phy);
-       if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_ADDR(0),
-                                  &address, 4))
+       if (NXWR32(adapter, NETXEN_NIU_GB_MII_MGMT_ADDR(0), address))
                return -EIO;
 
-       if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_CTRL(0),
-                                  &val, 4))
+       if (NXWR32(adapter, NETXEN_NIU_GB_MII_MGMT_CTRL(0), val))
                return -EIO;
 
        status = 0;
        do {
-               if (adapter->hw_read_wx(adapter,
-                                         NETXEN_NIU_GB_MII_MGMT_INDICATE(0),
-                                         &status, 4))
-                       return -EIO;
+               status = NXRD32(adapter, NETXEN_NIU_GB_MII_MGMT_INDICATE(0));
                timeout++;
        } while ((netxen_get_gb_mii_mgmt_busy(status))
                 && (timeout++ < NETXEN_NIU_PHY_WAITMAX));
@@ -248,9 +221,7 @@ int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter, long reg,
 
        /* restore the state of port 0 MAC in case we tampered with it */
        if (restore)
-               if (adapter->hw_write_wx(adapter,
-                                          NETXEN_NIU_GB_MAC_CONFIG_0(0),
-                                          &mac_cfg0, 4))
+               if (NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0), mac_cfg0))
                        return -EIO;
 
        return result;
@@ -258,7 +229,7 @@ int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter, long reg,
 
 int netxen_niu_xgbe_enable_phy_interrupts(struct netxen_adapter *adapter)
 {
-       netxen_crb_writelit_adapter(adapter, NETXEN_NIU_INT_MASK, 0x3f);
+       NXWR32(adapter, NETXEN_NIU_INT_MASK, 0x3f);
        return 0;
 }
 
@@ -281,7 +252,7 @@ int netxen_niu_gbe_enable_phy_interrupts(struct netxen_adapter *adapter)
 
 int netxen_niu_xgbe_disable_phy_interrupts(struct netxen_adapter *adapter)
 {
-       netxen_crb_writelit_adapter(adapter, NETXEN_NIU_INT_MASK, 0x7f);
+       NXWR32(adapter, NETXEN_NIU_INT_MASK, 0x7f);
        return 0;
 }
 
@@ -315,36 +286,27 @@ static int netxen_niu_gbe_clear_phy_interrupts(struct netxen_adapter *adapter)
 static void netxen_niu_gbe_set_mii_mode(struct netxen_adapter *adapter,
                                        int port, long enable)
 {
-       netxen_crb_writelit_adapter(adapter, NETXEN_NIU_MODE, 0x2);
-       netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
-                                   0x80000000);
-       netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
-                                   0x0000f0025);
-       netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_1(port),
-                                   0xf1ff);
-       netxen_crb_writelit_adapter(adapter,
-                                   NETXEN_NIU_GB0_GMII_MODE + (port << 3), 0);
-       netxen_crb_writelit_adapter(adapter,
-                                   NETXEN_NIU_GB0_MII_MODE + (port << 3), 1);
-       netxen_crb_writelit_adapter(adapter,
-                                   (NETXEN_NIU_GB0_HALF_DUPLEX + port * 4), 0);
-       netxen_crb_writelit_adapter(adapter,
-                                   NETXEN_NIU_GB_MII_MGMT_CONFIG(port), 0x7);
+       NXWR32(adapter, NETXEN_NIU_MODE, 0x2);
+       NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), 0x80000000);
+       NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), 0x0000f0025);
+       NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_1(port), 0xf1ff);
+       NXWR32(adapter, NETXEN_NIU_GB0_GMII_MODE + (port << 3), 0);
+       NXWR32(adapter, NETXEN_NIU_GB0_MII_MODE + (port << 3), 1);
+       NXWR32(adapter, (NETXEN_NIU_GB0_HALF_DUPLEX + port * 4), 0);
+       NXWR32(adapter, NETXEN_NIU_GB_MII_MGMT_CONFIG(port), 0x7);
 
        if (enable) {
                /*
                 * Do NOT enable flow control until a suitable solution for
                 *  shutting down pause frames is found.
                 */
-               netxen_crb_writelit_adapter(adapter,
-                                           NETXEN_NIU_GB_MAC_CONFIG_0(port),
-                                           0x5);
+               NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), 0x5);
        }
 
        if (netxen_niu_gbe_enable_phy_interrupts(adapter))
-               printk(KERN_ERR PFX "ERROR enabling PHY interrupts\n");
+               printk(KERN_ERR "ERROR enabling PHY interrupts\n");
        if (netxen_niu_gbe_clear_phy_interrupts(adapter))
-               printk(KERN_ERR PFX "ERROR clearing PHY interrupts\n");
+               printk(KERN_ERR "ERROR clearing PHY interrupts\n");
 }
 
 /*
@@ -353,36 +315,27 @@ static void netxen_niu_gbe_set_mii_mode(struct netxen_adapter *adapter,
 static void netxen_niu_gbe_set_gmii_mode(struct netxen_adapter *adapter,
                                         int port, long enable)
 {
-       netxen_crb_writelit_adapter(adapter, NETXEN_NIU_MODE, 0x2);
-       netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
-                                   0x80000000);
-       netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
-                                   0x0000f0025);
-       netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB_MAC_CONFIG_1(port),
-                                   0xf2ff);
-       netxen_crb_writelit_adapter(adapter,
-                                   NETXEN_NIU_GB0_MII_MODE + (port << 3), 0);
-       netxen_crb_writelit_adapter(adapter,
-                                   NETXEN_NIU_GB0_GMII_MODE + (port << 3), 1);
-       netxen_crb_writelit_adapter(adapter,
-                                   (NETXEN_NIU_GB0_HALF_DUPLEX + port * 4), 0);
-       netxen_crb_writelit_adapter(adapter,
-                                   NETXEN_NIU_GB_MII_MGMT_CONFIG(port), 0x7);
+       NXWR32(adapter, NETXEN_NIU_MODE, 0x2);
+       NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), 0x80000000);
+       NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), 0x0000f0025);
+       NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_1(port), 0xf2ff);
+       NXWR32(adapter, NETXEN_NIU_GB0_MII_MODE + (port << 3), 0);
+       NXWR32(adapter, NETXEN_NIU_GB0_GMII_MODE + (port << 3), 1);
+       NXWR32(adapter, (NETXEN_NIU_GB0_HALF_DUPLEX + port * 4), 0);
+       NXWR32(adapter, NETXEN_NIU_GB_MII_MGMT_CONFIG(port), 0x7);
 
        if (enable) {
                /*
                 * Do NOT enable flow control until a suitable solution for
                 *  shutting down pause frames is found.
                 */
-               netxen_crb_writelit_adapter(adapter,
-                                           NETXEN_NIU_GB_MAC_CONFIG_0(port),
-                                           0x5);
+               NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), 0x5);
        }
 
        if (netxen_niu_gbe_enable_phy_interrupts(adapter))
-               printk(KERN_ERR PFX "ERROR enabling PHY interrupts\n");
+               printk(KERN_ERR "ERROR enabling PHY interrupts\n");
        if (netxen_niu_gbe_clear_phy_interrupts(adapter))
-               printk(KERN_ERR PFX "ERROR clearing PHY interrupts\n");
+               printk(KERN_ERR "ERROR clearing PHY interrupts\n");
 }
 
 int netxen_niu_gbe_init_port(struct netxen_adapter *adapter, int port)
@@ -416,25 +369,20 @@ int netxen_niu_gbe_init_port(struct netxen_adapter *adapter, int port)
                         * plugged in.
                         */
 
-                       netxen_crb_writelit_adapter(adapter,
-                                                   NETXEN_NIU_GB_MAC_CONFIG_0
-                                                   (port),
+                       NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
                                                    NETXEN_GB_MAC_SOFT_RESET);
-                       netxen_crb_writelit_adapter(adapter,
-                                                   NETXEN_NIU_GB_MAC_CONFIG_0
-                                                   (port),
-                                                   NETXEN_GB_MAC_RESET_PROT_BLK
-                                                   | NETXEN_GB_MAC_ENABLE_TX_RX
-                                                   |
-                                                   NETXEN_GB_MAC_PAUSED_FRMS);
+                       NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
+                                           NETXEN_GB_MAC_RESET_PROT_BLK |
+                                           NETXEN_GB_MAC_ENABLE_TX_RX |
+                                           NETXEN_GB_MAC_PAUSED_FRMS);
                        if (netxen_niu_gbe_clear_phy_interrupts(adapter))
-                               printk(KERN_ERR PFX
+                               printk(KERN_ERR
                                       "ERROR clearing PHY interrupts\n");
                        if (netxen_niu_gbe_enable_phy_interrupts(adapter))
-                               printk(KERN_ERR PFX
+                               printk(KERN_ERR
                                       "ERROR enabling PHY interrupts\n");
                        if (netxen_niu_gbe_clear_phy_interrupts(adapter))
-                               printk(KERN_ERR PFX
+                               printk(KERN_ERR
                                       "ERROR clearing PHY interrupts\n");
                        result = -1;
                }
@@ -447,88 +395,10 @@ int netxen_niu_gbe_init_port(struct netxen_adapter *adapter, int port)
 int netxen_niu_xg_init_port(struct netxen_adapter *adapter, int port)
 {
        if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
-               netxen_crb_writelit_adapter(adapter,
-                       NETXEN_NIU_XGE_CONFIG_1+(0x10000*port), 0x1447);
-               netxen_crb_writelit_adapter(adapter,
-                       NETXEN_NIU_XGE_CONFIG_0+(0x10000*port), 0x5);
-       }
-
-       return 0;
-}
-
-/*
- * Return the current station MAC address.
- * Note that the passed-in value must already be in network byte order.
- */
-static int netxen_niu_macaddr_get(struct netxen_adapter *adapter,
-                                 netxen_ethernet_macaddr_t * addr)
-{
-       u32 stationhigh;
-       u32 stationlow;
-       int phy = adapter->physical_port;
-       u8 val[8];
-
-       if (addr == NULL)
-               return -EINVAL;
-       if ((phy < 0) || (phy > 3))
-               return -EINVAL;
-
-       if (adapter->hw_read_wx(adapter, NETXEN_NIU_GB_STATION_ADDR_0(phy),
-                                 &stationhigh, 4))
-               return -EIO;
-       if (adapter->hw_read_wx(adapter, NETXEN_NIU_GB_STATION_ADDR_1(phy),
-                                 &stationlow, 4))
-               return -EIO;
-       ((__le32 *)val)[1] = cpu_to_le32(stationhigh);
-       ((__le32 *)val)[0] = cpu_to_le32(stationlow);
-
-       memcpy(addr, val + 2, 6);
-
-       return 0;
-}
-
-/*
- * Set the station MAC address.
- * Note that the passed-in value must already be in network byte order.
- */
-int netxen_niu_macaddr_set(struct netxen_adapter *adapter,
-                          netxen_ethernet_macaddr_t addr)
-{
-       u8 temp[4];
-       u32 val;
-       int phy = adapter->physical_port;
-       unsigned char mac_addr[6];
-       int i;
-
-       if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
-               return 0;
-
-       for (i = 0; i < 10; i++) {
-               temp[0] = temp[1] = 0;
-               memcpy(temp + 2, addr, 2);
-               val = le32_to_cpu(*(__le32 *)temp);
-               if (adapter->hw_write_wx(adapter,
-                               NETXEN_NIU_GB_STATION_ADDR_1(phy), &val, 4))
-                       return -EIO;
-
-               memcpy(temp, ((u8 *) addr) + 2, sizeof(__le32));
-               val = le32_to_cpu(*(__le32 *)temp);
-               if (adapter->hw_write_wx(adapter,
-                               NETXEN_NIU_GB_STATION_ADDR_0(phy), &val, 4))
-                       return -2;
-
-               netxen_niu_macaddr_get(adapter,
-                                      (netxen_ethernet_macaddr_t *) mac_addr);
-               if (memcmp(mac_addr, addr, 6) == 0)
-                       break;
+               NXWR32(adapter, NETXEN_NIU_XGE_CONFIG_1+(0x10000*port), 0x1447);
+               NXWR32(adapter, NETXEN_NIU_XGE_CONFIG_0+(0x10000*port), 0x5);
        }
 
-       if (i == 10) {
-               printk(KERN_ERR "%s: cannot set Mac addr for %s\n",
-                      netxen_nic_driver_name, adapter->netdev->name);
-               printk(KERN_ERR "MAC address set: %pM.\n", addr);
-               printk(KERN_ERR "MAC address get: %pM.\n", mac_addr);
-       }
        return 0;
 }
 
@@ -545,8 +415,7 @@ int netxen_niu_disable_gbe_port(struct netxen_adapter *adapter)
                return -EINVAL;
        mac_cfg0 = 0;
        netxen_gb_soft_reset(mac_cfg0);
-       if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port),
-                                  &mac_cfg0, 4))
+       if (NXWR32(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), mac_cfg0))
                return -EIO;
        return 0;
 }
@@ -564,8 +433,8 @@ int netxen_niu_disable_xg_port(struct netxen_adapter *adapter)
                return -EINVAL;
 
        mac_cfg = 0;
-       if (adapter->hw_write_wx(adapter,
-               NETXEN_NIU_XGE_CONFIG_0 + (0x10000 * port), &mac_cfg, 4))
+       if (NXWR32(adapter,
+                       NETXEN_NIU_XGE_CONFIG_0 + (0x10000 * port), mac_cfg))
                return -EIO;
        return 0;
 }
@@ -581,9 +450,7 @@ int netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter,
                return -EINVAL;
 
        /* save previous contents */
-       if (adapter->hw_read_wx(adapter, NETXEN_NIU_GB_DROP_WRONGADDR,
-                                 &reg, 4))
-               return -EIO;
+       reg = NXRD32(adapter, NETXEN_NIU_GB_DROP_WRONGADDR);
        if (mode == NETXEN_NIU_PROMISC_MODE) {
                switch (port) {
                case 0:
@@ -619,67 +486,11 @@ int netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter,
                        return -EIO;
                }
        }
-       if (adapter->hw_write_wx(adapter, NETXEN_NIU_GB_DROP_WRONGADDR,
-                                  &reg, 4))
+       if (NXWR32(adapter, NETXEN_NIU_GB_DROP_WRONGADDR, reg))
                return -EIO;
        return 0;
 }
 
-/*
- * Set the MAC address for an XG port
- * Note that the passed-in value must already be in network byte order.
- */
-int netxen_niu_xg_macaddr_set(struct netxen_adapter *adapter,
-                             netxen_ethernet_macaddr_t addr)
-{
-       int phy = adapter->physical_port;
-       u8 temp[4];
-       u32 val;
-
-       if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
-               return 0;
-
-       if ((phy < 0) || (phy > NETXEN_NIU_MAX_XG_PORTS))
-               return -EIO;
-
-       temp[0] = temp[1] = 0;
-       switch (phy) {
-       case 0:
-           memcpy(temp + 2, addr, 2);
-           val = le32_to_cpu(*(__le32 *)temp);
-           if (adapter->hw_write_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_1,
-                               &val, 4))
-               return -EIO;
-
-           memcpy(&temp, ((u8 *) addr) + 2, sizeof(__le32));
-           val = le32_to_cpu(*(__le32 *)temp);
-           if (adapter->hw_write_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_HI,
-                               &val, 4))
-               return -EIO;
-           break;
-
-       case 1:
-           memcpy(temp + 2, addr, 2);
-           val = le32_to_cpu(*(__le32 *)temp);
-           if (adapter->hw_write_wx(adapter, NETXEN_NIU_XG1_STATION_ADDR_0_1,
-                               &val, 4))
-               return -EIO;
-
-           memcpy(&temp, ((u8 *) addr) + 2, sizeof(__le32));
-           val = le32_to_cpu(*(__le32 *)temp);
-           if (adapter->hw_write_wx(adapter, NETXEN_NIU_XG1_STATION_ADDR_0_HI,
-                               &val, 4))
-               return -EIO;
-           break;
-
-       default:
-           printk(KERN_ERR "Unknown port %d\n", phy);
-           break;
-       }
-
-       return 0;
-}
-
 int netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter,
                u32 mode)
 {
@@ -689,9 +500,7 @@ int netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter,
        if (port > NETXEN_NIU_MAX_XG_PORTS)
                return -EINVAL;
 
-       if (adapter->hw_read_wx(adapter,
-               NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port), &reg, 4))
-                       return -EIO;
+       reg = NXRD32(adapter, NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port));
        if (mode == NETXEN_NIU_PROMISC_MODE)
                reg = (reg | 0x2000UL);
        else
@@ -702,8 +511,40 @@ int netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter,
        else
                reg = (reg & ~0x1000UL);
 
-       netxen_crb_writelit_adapter(adapter,
-               NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port), reg);
+       NXWR32(adapter, NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port), reg);
+
+       return 0;
+}
+
+int netxen_p2_nic_set_mac_addr(struct netxen_adapter *adapter, u8 *addr)
+{
+       u32 mac_hi, mac_lo;
+       u32 reg_hi, reg_lo;
+
+       u8 phy = adapter->physical_port;
+       u8 phy_count = (adapter->ahw.port_type == NETXEN_NIC_XGBE) ?
+               NETXEN_NIU_MAX_XG_PORTS : NETXEN_NIU_MAX_GBE_PORTS;
+
+       if (phy >= phy_count)
+               return -EINVAL;
+
+       mac_lo = ((u32)addr[0] << 16) | ((u32)addr[1] << 24);
+       mac_hi = addr[2] | ((u32)addr[3] << 8) |
+               ((u32)addr[4] << 16) | ((u32)addr[5] << 24);
+
+       if (adapter->ahw.port_type == NETXEN_NIC_XGBE) {
+               reg_lo = NETXEN_NIU_XGE_STATION_ADDR_0_1 + (0x10000 * phy);
+               reg_hi = NETXEN_NIU_XGE_STATION_ADDR_0_HI + (0x10000 * phy);
+       } else {
+               reg_lo = NETXEN_NIU_GB_STATION_ADDR_1(phy);
+               reg_hi = NETXEN_NIU_GB_STATION_ADDR_0(phy);
+       }
+
+       /* write twice to flush */
+       if (NXWR32(adapter, reg_lo, mac_lo) || NXWR32(adapter, reg_hi, mac_hi))
+               return -EIO;
+       if (NXWR32(adapter, reg_lo, mac_lo) || NXWR32(adapter, reg_hi, mac_hi))
+               return -EIO;
 
        return 0;
 }
index 50183335e43afcf47ce6b5fa41177f0b9d2a77d2..b73a62ca74f8b835a9dfe184195f0356ac5afb4d 100644 (file)
  */
 #define NIC_CRB_BASE               NETXEN_CAM_RAM(0x200)
 #define NETXEN_NIC_REG(X)             (NIC_CRB_BASE+(X))
+#define NIC_CRB_BASE_2             NETXEN_CAM_RAM(0x700)
+#define NETXEN_NIC_REG_2(X)         (NIC_CRB_BASE_2+(X))
 
 #define CRB_PHAN_CNTRL_LO_OFFSET    NETXEN_NIC_REG(0x00)
 #define CRB_PHAN_CNTRL_HI_OFFSET    NETXEN_NIC_REG(0x04)
 #define CRB_CMD_PRODUCER_OFFSET     NETXEN_NIC_REG(0x08)
 #define CRB_CMD_CONSUMER_OFFSET     NETXEN_NIC_REG(0x0c)
-#define CRB_PAUSE_ADDR_LO           NETXEN_NIC_REG(0x10)       /* C0 EPG BUG  */
+#define CRB_PAUSE_ADDR_LO           NETXEN_NIC_REG(0x10)
 #define CRB_PAUSE_ADDR_HI           NETXEN_NIC_REG(0x14)
 #define NX_CDRP_CRB_OFFSET          NETXEN_NIC_REG(0x18)
 #define NX_ARG1_CRB_OFFSET          NETXEN_NIC_REG(0x1c)
 #define NX_ARG2_CRB_OFFSET          NETXEN_NIC_REG(0x20)
 #define NX_ARG3_CRB_OFFSET          NETXEN_NIC_REG(0x24)
 #define NX_SIGN_CRB_OFFSET          NETXEN_NIC_REG(0x28)
-#define CRB_CMD_INTR_LOOP           NETXEN_NIC_REG(0x20)       /* 4 regs for perf */
+#define CRB_CMD_INTR_LOOP           NETXEN_NIC_REG(0x20)
 #define CRB_CMD_DMA_LOOP            NETXEN_NIC_REG(0x24)
 #define CRB_RCV_INTR_LOOP           NETXEN_NIC_REG(0x28)
 #define CRB_RCV_DMA_LOOP            NETXEN_NIC_REG(0x2c)
-#define CRB_ENABLE_TX_INTR          NETXEN_NIC_REG(0x30)       /* phantom init status */
+#define CRB_ENABLE_TX_INTR          NETXEN_NIC_REG(0x30)
 #define CRB_MMAP_ADDR_3             NETXEN_NIC_REG(0x34)
 #define CRB_CMDPEG_CMDRING          NETXEN_NIC_REG(0x38)
 #define CRB_HOST_DUMMY_BUF_ADDR_HI  NETXEN_NIC_REG(0x3c)
@@ -65,7 +67,7 @@
 #define CRB_MMAP_SIZE_1             NETXEN_NIC_REG(0x58)
 #define CRB_MMAP_SIZE_2             NETXEN_NIC_REG(0x5c)
 #define CRB_MMAP_SIZE_3             NETXEN_NIC_REG(0x60)
-#define CRB_GLOBAL_INT_COAL         NETXEN_NIC_REG(0x64)       /* interrupt coalescing */
+#define CRB_GLOBAL_INT_COAL         NETXEN_NIC_REG(0x64)
 #define CRB_INT_COAL_MODE           NETXEN_NIC_REG(0x68)
 #define CRB_MAX_RCV_BUFS            NETXEN_NIC_REG(0x6c)
 #define CRB_TX_INT_THRESHOLD        NETXEN_NIC_REG(0x70)
 #define CRB_AGENT_TX_TYPE           NETXEN_NIC_REG(0xa0)
 #define CRB_AGENT_TX_ADDR           NETXEN_NIC_REG(0xa4)
 #define CRB_AGENT_TX_MSS            NETXEN_NIC_REG(0xa8)
-#define CRB_TX_STATE                NETXEN_NIC_REG(0xac)       /* Debug -performance */
+#define CRB_TX_STATE                NETXEN_NIC_REG(0xac)
 #define CRB_TX_COUNT                NETXEN_NIC_REG(0xb0)
 #define CRB_RX_STATE                NETXEN_NIC_REG(0xb4)
 #define CRB_RX_PERF_DEBUG_1         NETXEN_NIC_REG(0xb8)
-#define CRB_RX_LRO_CONTROL          NETXEN_NIC_REG(0xbc)       /* LRO On/OFF */
+#define CRB_RX_LRO_CONTROL          NETXEN_NIC_REG(0xbc)
 #define CRB_RX_LRO_START_NUM        NETXEN_NIC_REG(0xc0)
-#define CRB_MPORT_MODE              NETXEN_NIC_REG(0xc4)       /* Multiport Mode */
+#define CRB_MPORT_MODE              NETXEN_NIC_REG(0xc4)
 #define CRB_CMD_RING_SIZE           NETXEN_NIC_REG(0xc8)
 #define CRB_DMA_SHIFT               NETXEN_NIC_REG(0xcc)
 #define CRB_INT_VECTOR              NETXEN_NIC_REG(0xd4)
 #define CRB_CMD_CONSUMER_OFFSET_1   NETXEN_NIC_REG(0x1b0)
 #define CRB_CMD_PRODUCER_OFFSET_2   NETXEN_NIC_REG(0x1b8)
 #define CRB_CMD_CONSUMER_OFFSET_2   NETXEN_NIC_REG(0x1bc)
-
-// 1c0 to 1cc used for signature reg
 #define CRB_CMD_PRODUCER_OFFSET_3   NETXEN_NIC_REG(0x1d0)
 #define CRB_CMD_CONSUMER_OFFSET_3   NETXEN_NIC_REG(0x1d4)
 #define CRB_TEMP_STATE              NETXEN_NIC_REG(0x1b4)
 #define CRB_V2P_2                  NETXEN_NIC_REG(0x298)
 #define CRB_V2P_3                  NETXEN_NIC_REG(0x29c)
 #define CRB_V2P(port)              (CRB_V2P_0+((port)*4))
-#define CRB_DRIVER_VERSION         NETXEN_NIC_REG(0x2a0)
-/* sw int status/mask registers */
+#define CRB_DRIVER_VERSION        NETXEN_NIC_REG(0x2a0)
 #define CRB_SW_INT_MASK_0         NETXEN_NIC_REG(0x1d8)
 #define CRB_SW_INT_MASK_1         NETXEN_NIC_REG(0x1e0)
 #define CRB_SW_INT_MASK_2         NETXEN_NIC_REG(0x1e4)
 #define CRB_SW_INT_MASK_3         NETXEN_NIC_REG(0x1e8)
 
+#define CRB_FW_CAPABILITIES_1      NETXEN_CAM_RAM(0x128)
 #define CRB_MAC_BLOCK_START        NETXEN_CAM_RAM(0x1c0)
 
 /*
 #define CRB_NIC_CAPABILITIES_HOST      NETXEN_NIC_REG(0x1a8)
 #define CRB_NIC_CAPABILITIES_FW                NETXEN_NIC_REG(0x1dc)
 #define CRB_NIC_MSI_MODE_HOST          NETXEN_NIC_REG(0x270)
-#define CRB_NIC_MSI_MODE_FW                    NETXEN_NIC_REG(0x274)
+#define CRB_NIC_MSI_MODE_FW            NETXEN_NIC_REG(0x274)
 
 #define INTR_SCHEME_PERPORT            0x1
 #define MSI_MODE_MULTIFUNC             0x1
 
 struct netxen_recv_crb {
        u32 crb_rcv_producer[NUM_RCV_DESC_RINGS];
-       u32 crb_sts_consumer;
+       u32 crb_sts_consumer[NUM_STS_DESC_RINGS];
+       u32 sw_int_mask[NUM_STS_DESC_RINGS];
 };
 
 /*
index 6474f02bf78391c758445bd6f24a1f10e3f85fc0..1f10ed603e20bc4ee7943346020b557d3415229a 100644 (file)
@@ -1165,7 +1165,7 @@ static int ni65_send_packet(struct sk_buff *skb, struct net_device *dev)
 
        if (test_and_set_bit(0, (void*)&p->lock)) {
                printk(KERN_ERR "%s: Queue was locked.\n", dev->name);
-               return 1;
+               return NETDEV_TX_BUSY;
        }
 
        {
index 2b1745328cf78a90aa20cd05d1fb1a74598544ff..fa61a12c5e1546dc73e1f5394cc18598ef33906a 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/log2.h>
 #include <linux/jiffies.h>
 #include <linux/crc32.h>
+#include <linux/list.h>
 
 #include <linux/io.h>
 
@@ -1317,7 +1318,7 @@ static int bcm8704_reset(struct niu *np)
 
        err = mdio_read(np, np->phy_addr,
                        BCM8704_PHYXS_DEV_ADDR, MII_BMCR);
-       if (err < 0)
+       if (err < 0 || err == 0xffff)
                return err;
        err |= BMCR_RESET;
        err = mdio_write(np, np->phy_addr, BCM8704_PHYXS_DEV_ADDR,
@@ -2042,7 +2043,7 @@ static int link_status_10g_bcm8706(struct niu *np, int *link_up_p)
 
        err = mdio_read(np, np->phy_addr, BCM8704_PMA_PMD_DEV_ADDR,
                        BCM8704_PMD_RCV_SIGDET);
-       if (err < 0)
+       if (err < 0 || err == 0xffff)
                goto out;
        if (!(err & PMD_RCV_SIGDET_GLOBAL)) {
                err = 0;
@@ -2083,8 +2084,6 @@ static int link_status_10g_bcm8706(struct niu *np, int *link_up_p)
 
 out:
        *link_up_p = link_up;
-       if (np->flags & NIU_FLAGS_HOTPLUG_PHY)
-               err = 0;
        return err;
 }
 
@@ -2220,10 +2219,17 @@ static int link_status_10g_hotplug(struct niu *np, int *link_up_p)
                if (phy_present != phy_present_prev) {
                        /* state change */
                        if (phy_present) {
+                               /* A NEM was just plugged in */
                                np->flags |= NIU_FLAGS_HOTPLUG_PHY_PRESENT;
                                if (np->phy_ops->xcvr_init)
                                        err = np->phy_ops->xcvr_init(np);
                                if (err) {
+                                       err = mdio_read(np, np->phy_addr,
+                                               BCM8704_PHYXS_DEV_ADDR, MII_BMCR);
+                                       if (err == 0xffff) {
+                                               /* No mdio, back-to-back XAUI */
+                                               goto out;
+                                       }
                                        /* debounce */
                                        np->flags &= ~NIU_FLAGS_HOTPLUG_PHY_PRESENT;
                                }
@@ -2234,13 +2240,21 @@ static int link_status_10g_hotplug(struct niu *np, int *link_up_p)
                                        np->dev->name);
                        }
                }
-               if (np->flags & NIU_FLAGS_HOTPLUG_PHY_PRESENT)
+out:
+               if (np->flags & NIU_FLAGS_HOTPLUG_PHY_PRESENT) {
                        err = link_status_10g_bcm8706(np, link_up_p);
+                       if (err == 0xffff) {
+                               /* No mdio, back-to-back XAUI: it is C10NEM */
+                               *link_up_p = 1;
+                               np->link_config.active_speed = SPEED_10000;
+                               np->link_config.active_duplex = DUPLEX_FULL;
+                       }
+               }
        }
 
        spin_unlock_irqrestore(&np->lock, flags);
 
-       return err;
+       return 0;
 }
 
 static int niu_link_status(struct niu *np, int *link_up_p)
@@ -2312,6 +2326,12 @@ static const struct niu_phy_ops phy_ops_10g_fiber_hotplug = {
        .link_status            = link_status_10g_hotplug,
 };
 
+static const struct niu_phy_ops phy_ops_niu_10g_hotplug = {
+       .serdes_init            = serdes_init_niu_10g_fiber,
+       .xcvr_init              = xcvr_init_10g_bcm8706,
+       .link_status            = link_status_10g_hotplug,
+};
+
 static const struct niu_phy_ops phy_ops_10g_copper = {
        .serdes_init            = serdes_init_10g,
        .link_status            = link_status_10g, /* XXX */
@@ -2358,6 +2378,11 @@ static const struct niu_phy_template phy_template_10g_fiber_hotplug = {
        .phy_addr_base  = 8,
 };
 
+static const struct niu_phy_template phy_template_niu_10g_hotplug = {
+       .ops            = &phy_ops_niu_10g_hotplug,
+       .phy_addr_base  = 8,
+};
+
 static const struct niu_phy_template phy_template_10g_copper = {
        .ops            = &phy_ops_10g_copper,
        .phy_addr_base  = 10,
@@ -2542,8 +2567,16 @@ static int niu_determine_phy_disposition(struct niu *np)
                case NIU_FLAGS_10G | NIU_FLAGS_FIBER:
                        /* 10G Fiber */
                default:
-                       tp = &phy_template_niu_10g_fiber;
-                       phy_addr_off += np->port;
+                       if (np->flags & NIU_FLAGS_HOTPLUG_PHY) {
+                               tp = &phy_template_niu_10g_hotplug;
+                               if (np->port == 0)
+                                       phy_addr_off = 8;
+                               if (np->port == 1)
+                                       phy_addr_off = 12;
+                       } else {
+                               tp = &phy_template_niu_10g_fiber;
+                               phy_addr_off += np->port;
+                       }
                        break;
                }
        } else {
@@ -2630,11 +2663,11 @@ static int niu_init_link(struct niu *np)
                msleep(200);
        }
        err = niu_serdes_init(np);
-       if (err)
+       if (err && !(np->flags & NIU_FLAGS_HOTPLUG_PHY))
                return err;
        msleep(200);
        err = niu_xcvr_init(np);
-       if (!err)
+       if (!err || (np->flags & NIU_FLAGS_HOTPLUG_PHY))
                niu_link_status(np, &ignore);
        return 0;
 }
@@ -6330,6 +6363,7 @@ static void niu_set_rx_mode(struct net_device *dev)
        struct niu *np = netdev_priv(dev);
        int i, alt_cnt, err;
        struct dev_addr_list *addr;
+       struct netdev_hw_addr *ha;
        unsigned long flags;
        u16 hash[16] = { 0, };
 
@@ -6351,9 +6385,8 @@ static void niu_set_rx_mode(struct net_device *dev)
        if (alt_cnt) {
                int index = 0;
 
-               for (addr = dev->uc_list; addr; addr = addr->next) {
-                       err = niu_set_alt_mac(np, index,
-                                             addr->da_addr);
+               list_for_each_entry(ha, &dev->uc_list, list) {
+                       err = niu_set_alt_mac(np, index, ha->addr);
                        if (err)
                                printk(KERN_WARNING PFX "%s: Error %d "
                                       "adding alt mac %d\n",
@@ -6745,8 +6778,6 @@ static int niu_start_xmit(struct sk_buff *skb, struct net_device *dev)
                        netif_tx_wake_queue(txq);
        }
 
-       dev->trans_start = jiffies;
-
 out:
        return NETDEV_TX_OK;
 
@@ -9346,6 +9377,11 @@ static int __devinit niu_get_of_props(struct niu *np)
        if (model)
                strcpy(np->vpd.model, model);
 
+       if (of_find_property(dp, "hot-swappable-phy", &prop_len)) {
+               np->flags |= (NIU_FLAGS_10G | NIU_FLAGS_FIBER |
+                       NIU_FLAGS_HOTPLUG_PHY);
+       }
+
        return 0;
 #else
        return -EINVAL;
index d531614a90b551135de193fb34800a0f7b7a2d60..1576ac07216ec9bb7a65576336945804a4353168 100644 (file)
@@ -1097,7 +1097,7 @@ again:
        if (unlikely(dev->CFG_cache & CFG_LNKSTS)) {
                netif_stop_queue(ndev);
                if (unlikely(dev->CFG_cache & CFG_LNKSTS))
-                       return 1;
+                       return NETDEV_TX_BUSY;
                netif_start_queue(ndev);
        }
 
@@ -1115,7 +1115,7 @@ again:
                        netif_start_queue(ndev);
                        goto again;
                }
-               return 1;
+               return NETDEV_TX_BUSY;
        }
 
        if (free_idx == dev->tx_intr_idx) {
@@ -1204,9 +1204,7 @@ again:
        if (stopped && (dev->tx_done_idx != tx_done_idx) && start_tx_okay(dev))
                netif_start_queue(ndev);
 
-       /* set the transmit start time to catch transmit timeouts */
-       ndev->trans_start = jiffies;
-       return 0;
+       return NETDEV_TX_OK;
 }
 
 static void ns83820_update_stats(struct ns83820 *dev)
@@ -1626,7 +1624,7 @@ static void ns83820_tx_watch(unsigned long data)
                );
 #endif
 
-       if (time_after(jiffies, ndev->trans_start + 1*HZ) &&
+       if (time_after(jiffies, dev_trans_start(ndev) + 1*HZ) &&
            dev->tx_done_idx != dev->tx_free_idx) {
                printk(KERN_DEBUG "%s: ns83820_tx_watch: %u %u %d\n",
                        ndev->name,
index 5eeb5a87b7387ede885f565ea9409da99a704865..c254a7f5b9f5bf6344f1318011bba5f817d677ac 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/dmaengine.h>
 #include <linux/delay.h>
 #include <linux/netdevice.h>
+#include <linux/of_mdio.h>
 #include <linux/etherdevice.h>
 #include <asm/dma-mapping.h>
 #include <linux/in.h>
@@ -1086,34 +1087,17 @@ static int pasemi_mac_phy_init(struct net_device *dev)
        struct pasemi_mac *mac = netdev_priv(dev);
        struct device_node *dn, *phy_dn;
        struct phy_device *phydev;
-       unsigned int phy_id;
-       const phandle *ph;
-       const unsigned int *prop;
-       struct resource r;
-       int ret;
 
        dn = pci_device_to_OF_node(mac->pdev);
-       ph = of_get_property(dn, "phy-handle", NULL);
-       if (!ph)
-               return -ENODEV;
-       phy_dn = of_find_node_by_phandle(*ph);
-
-       prop = of_get_property(phy_dn, "reg", NULL);
-       ret = of_address_to_resource(phy_dn->parent, 0, &r);
-       if (ret)
-               goto err;
-
-       phy_id = *prop;
-       snprintf(mac->phy_id, sizeof(mac->phy_id), "%x:%02x",
-                (int)r.start, phy_id);
-
+       phy_dn = of_parse_phandle(dn, "phy-handle", 0);
        of_node_put(phy_dn);
 
        mac->link = 0;
        mac->speed = 0;
        mac->duplex = -1;
 
-       phydev = phy_connect(dev, mac->phy_id, &pasemi_adjust_link, 0, PHY_INTERFACE_MODE_SGMII);
+       phydev = of_phy_connect(dev, phy_dn, &pasemi_adjust_link, 0,
+                               PHY_INTERFACE_MODE_SGMII);
 
        if (IS_ERR(phydev)) {
                printk(KERN_ERR "%s: Could not attach to phy\n", dev->name);
@@ -1123,10 +1107,6 @@ static int pasemi_mac_phy_init(struct net_device *dev)
        mac->phydev = phydev;
 
        return 0;
-
-err:
-       of_node_put(phy_dn);
-       return -ENODEV;
 }
 
 
@@ -1735,12 +1715,25 @@ out:
        return ret;
 }
 
+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_mac_address    = pasemi_mac_set_mac_addr,
+       .ndo_change_mtu         = pasemi_mac_change_mtu,
+       .ndo_validate_addr      = eth_validate_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+       .ndo_poll_controller    = pasemi_mac_netpoll,
+#endif
+};
+
 static int __devinit
 pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
        struct net_device *dev;
        struct pasemi_mac *mac;
-       int err;
+       int err, ret;
 
        err = pci_enable_device(pdev);
        if (err)
@@ -1798,12 +1791,13 @@ pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        }
        memcpy(dev->dev_addr, mac->mac_addr, sizeof(mac->mac_addr));
 
-       mac->dma_if = mac_to_intf(mac);
-       if (mac->dma_if < 0) {
+       ret = mac_to_intf(mac);
+       if (ret < 0) {
                dev_err(&mac->pdev->dev, "Can't map DMA interface\n");
                err = -ENODEV;
                goto out;
        }
+       mac->dma_if = ret;
 
        switch (pdev->device) {
        case 0xa005:
@@ -1817,19 +1811,11 @@ pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                goto out;
        }
 
-       dev->open = pasemi_mac_open;
-       dev->stop = pasemi_mac_close;
-       dev->hard_start_xmit = pasemi_mac_start_tx;
-       dev->set_multicast_list = pasemi_mac_set_rx_mode;
-       dev->set_mac_address = pasemi_mac_set_mac_addr;
+       dev->netdev_ops = &pasemi_netdev_ops;
        dev->mtu = PE_DEF_MTU;
        /* 1500 MTU + ETH_HLEN + VLAN_HLEN + 2 64B cachelines */
        mac->bufsz = dev->mtu + ETH_HLEN + ETH_FCS_LEN + LOCAL_SKB_ALIGN + 128;
-#ifdef CONFIG_NET_POLL_CONTROLLER
-       dev->poll_controller = pasemi_mac_netpoll;
-#endif
 
-       dev->change_mtu = pasemi_mac_change_mtu;
        dev->ethtool_ops = &pasemi_mac_ethtool_ops;
 
        if (err)
index 1a115ec60b531d4bf407f406716fc8ccf9ac72f0..e2f4efa8ad46a5d79384a2afd6e441a1552f02a0 100644 (file)
@@ -100,7 +100,6 @@ struct pasemi_mac {
        int     duplex;
 
        unsigned int    msg_enable;
-       char    phy_id[BUS_ID_SIZE];
 };
 
 /* Software status descriptor (ring_info) */
index c95fd72c3bb96886a9862d27533ef20d650e32be..8c1f6988f398bdbc42305fb1aed09fffb9db97ed 100644 (file)
@@ -728,6 +728,17 @@ err_out:
        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)
@@ -769,13 +780,7 @@ static int __devinit netdrv_init_one (struct pci_dev *pdev,
                ((u16 *) (dev->dev_addr))[i] =
                    le16_to_cpu (read_eeprom (ioaddr, i + 7, addr_len));
 
-       /* The Rtl8139-specific entries in the device structure. */
-       dev->open = netdrv_open;
-       dev->hard_start_xmit = netdrv_start_xmit;
-       dev->stop = netdrv_close;
-       dev->set_multicast_list = netdrv_set_rx_mode;
-       dev->do_ioctl = netdrv_ioctl;
-       dev->tx_timeout = netdrv_tx_timeout;
+       dev->netdev_ops = &netdrv_netdev_ops;
        dev->watchdog_timeo = TX_TIMEOUT;
 
        dev->irq = pdev->irq;
index 8f3872b8985d10fd72c51498c1cd987166fcb49b..f35c609ba020c8fff9ea082c37362056bec9ff4c 100644 (file)
@@ -1195,7 +1195,7 @@ static int el3_close(struct net_device *dev)
 
 static struct pcmcia_device_id tc574_ids[] = {
        PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0574),
-       PCMCIA_MFC_DEVICE_CIS_MANF_CARD(0, 0x0101, 0x0556, "3CCFEM556.cis"),
+       PCMCIA_MFC_DEVICE_CIS_MANF_CARD(0, 0x0101, 0x0556, "cis/3CCFEM556.cis"),
        PCMCIA_DEVICE_NULL,
 };
 MODULE_DEVICE_TABLE(pcmcia, tc574_ids);
index cdf661a6092c8b7f697886c22b1983473ac07bec..ec7cf5ac4f0595275551e3addecf16747be79c92 100644 (file)
@@ -967,8 +967,8 @@ static struct pcmcia_device_id tc589_ids[] = {
        PCMCIA_MFC_DEVICE_PROD_ID1(0, "Motorola MARQUIS", 0xf03e4e77),
        PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0589),
        PCMCIA_DEVICE_PROD_ID12("Farallon", "ENet", 0x58d93fc4, 0x992c2202),
-       PCMCIA_MFC_DEVICE_CIS_MANF_CARD(0, 0x0101, 0x0035, "3CXEM556.cis"),
-       PCMCIA_MFC_DEVICE_CIS_MANF_CARD(0, 0x0101, 0x003d, "3CXEM556.cis"),
+       PCMCIA_MFC_DEVICE_CIS_MANF_CARD(0, 0x0101, 0x0035, "cis/3CXEM556.cis"),
+       PCMCIA_MFC_DEVICE_CIS_MANF_CARD(0, 0x0101, 0x003d, "cis/3CXEM556.cis"),
        PCMCIA_DEVICE_NULL,
 };
 MODULE_DEVICE_TABLE(pcmcia, tc589_ids);
index 15b8fe61695bed13cfdcadd3d38cae59d420b9b5..0e38d80fd25594768f9b9412c453c376a8310b4f 100644 (file)
@@ -1130,7 +1130,7 @@ static int axnet_start_xmit(struct sk_buff *skb, struct net_device *dev)
                outb_p(ENISR_ALL, e8390_base + EN0_IMR);
                spin_unlock_irqrestore(&ei_local->page_lock, flags);
                dev->stats.tx_errors++;
-               return 1;
+               return NETDEV_TX_BUSY;
        }
 
        /*
index 81e6660a433ad9dcd892d3aebf5d3a885ce5e334..479d5b4943713ad376b847f9872d06f2b0f7f2e0 100644 (file)
@@ -877,7 +877,7 @@ static int fjn_start_xmit(struct sk_buff *skb, struct net_device *dev)
        if (length > ETH_FRAME_LEN) {
            printk(KERN_NOTICE "%s: Attempting to send a large packet"
                   " (%d bytes).\n", dev->name, length);
-           return 1;
+           return NETDEV_TX_BUSY;
        }
 
        DEBUG(4, "%s: Transmitting a packet of length %lu.\n",
index 48dbb35747d8aefa4f04ee098e1f8dd37b022ed7..37e05d3ab893b7c8c74478b01bc2e7e0bf4053f1 100644 (file)
@@ -1388,7 +1388,7 @@ static int smc_start_xmit(struct sk_buff *skb, struct net_device *dev)
        dev->stats.tx_aborted_errors++;
        printk(KERN_DEBUG "%s: Internal error -- sent packet while busy.\n",
               dev->name);
-       return 1;
+       return NETDEV_TX_BUSY;
     }
     smc->saved_skb = skb;
 
index a3685c0d22fc3a2fd26a072019386395862586f5..ef37d22c7e1d4dcaf264ee09a96b333d6334ee5f 100644 (file)
@@ -1399,7 +1399,7 @@ do_start_xmit(struct sk_buff *skb, struct net_device *dev)
     DEBUG(2 + (okay ? 2 : 0), "%s: avail. tx space=%u%s\n",
          dev->name, freespace, okay ? " (okay)":" (not enough)");
     if (!okay) { /* not enough space */
-       return 1;  /* upper layer may decide to requeue this packet */
+       return NETDEV_TX_BUSY;  /* upper layer may decide to requeue this packet */
     }
     /* send the packet */
     PutWord(XIRCREG_EDP, (u_short)pktlen);
index 80124fac65fa83682a7b256db5dd11039fb7d445..1c35e1d637a0e30aecd6f3369a0f89cdbf34b972 100644 (file)
@@ -1227,7 +1227,6 @@ static void pcnet32_rx_entry(struct net_device *dev,
                dev->stats.rx_dropped++;
                return;
        }
-       skb->dev = dev;
        if (!rx_in_place) {
                skb_reserve(skb, NET_IP_ALIGN);
                skb_put(skb, pkt_len);  /* Make room */
@@ -1406,7 +1405,7 @@ static int pcnet32_poll(struct napi_struct *napi, int budget)
 
                /* Set interrupt enable. */
                lp->a.write_csr(ioaddr, CSR0, CSR0_INTEN);
-               mmiowb();
+
                spin_unlock_irqrestore(&lp->lock, flags);
        }
        return work_done;
@@ -2598,7 +2597,7 @@ pcnet32_interrupt(int irq, void *dev_id)
                        val = lp->a.read_csr(ioaddr, CSR3);
                        val |= 0x5f00;
                        lp->a.write_csr(ioaddr, CSR3, val);
-                       mmiowb();
+
                        __napi_schedule(&lp->napi);
                        break;
                }
index 7a3ec9d39a9a62952a5f598c9dd03794a3a58529..dd6f54d1b49539a39fb2b18bfd19d2a5e10f3746 100644 (file)
@@ -243,6 +243,7 @@ static int m88e1111_config_init(struct phy_device *phydev)
 
                temp &= ~(MII_M1111_HWCFG_MODE_MASK);
                temp |= MII_M1111_HWCFG_MODE_SGMII_NO_CLK;
+               temp |= MII_M1111_HWCFG_FIBER_COPPER_AUTO;
 
                err = phy_write(phydev, MII_M1111_PHY_EXT_SR, temp);
                if (err < 0)
index b754020cbe75c731c1da255082fe382a59e1bf72..bd4e8d72dc08fa7e5a14822ef9d577cabdf3a185 100644 (file)
@@ -113,7 +113,6 @@ int mdiobus_register(struct mii_bus *bus)
                bus->reset(bus);
 
        for (i = 0; i < PHY_MAX_ADDR; i++) {
-               bus->phy_map[i] = NULL;
                if ((bus->phy_mask & (1 << i)) == 0) {
                        struct phy_device *phydev;
 
@@ -150,6 +149,7 @@ void mdiobus_unregister(struct mii_bus *bus)
        for (i = 0; i < PHY_MAX_ADDR; i++) {
                if (bus->phy_map[i])
                        device_unregister(&bus->phy_map[i]->dev);
+               bus->phy_map[i] = NULL;
        }
 }
 EXPORT_SYMBOL(mdiobus_unregister);
@@ -188,35 +188,12 @@ struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr)
        if (IS_ERR(phydev) || phydev == NULL)
                return phydev;
 
-       /* There's a PHY at this address
-        * We need to set:
-        * 1) IRQ
-        * 2) bus_id
-        * 3) parent
-        * 4) bus
-        * 5) mii_bus
-        * And, we need to register it */
-
-       phydev->irq = bus->irq != NULL ? bus->irq[addr] : PHY_POLL;
-
-       phydev->dev.parent = bus->parent;
-       phydev->dev.bus = &mdio_bus_type;
-       dev_set_name(&phydev->dev, PHY_ID_FMT, bus->id, addr);
-
-       phydev->bus = bus;
-
-       /* Run all of the fixups for this PHY */
-       phy_scan_fixups(phydev);
-
-       err = device_register(&phydev->dev);
+       err = phy_device_register(phydev);
        if (err) {
-               printk(KERN_ERR "phy %d failed to register\n", addr);
                phy_device_free(phydev);
-               phydev = NULL;
+               return NULL;
        }
 
-       bus->phy_map[addr] = phydev;
-
        return phydev;
 }
 EXPORT_SYMBOL(mdiobus_scan);
index 0a06e4fd37d9b16e37a9e54e901cd659d7044163..a2ece89622d64ceb82c99bf55199e9765d7d661c 100644 (file)
@@ -39,20 +39,21 @@ MODULE_DESCRIPTION("PHY library");
 MODULE_AUTHOR("Andy Fleming");
 MODULE_LICENSE("GPL");
 
-static struct phy_driver genphy_driver;
-extern int mdio_bus_init(void);
-extern void mdio_bus_exit(void);
-
 void phy_device_free(struct phy_device *phydev)
 {
        kfree(phydev);
 }
+EXPORT_SYMBOL(phy_device_free);
 
 static void phy_device_release(struct device *dev)
 {
        phy_device_free(to_phy_device(dev));
 }
 
+static struct phy_driver genphy_driver;
+extern int mdio_bus_init(void);
+extern void mdio_bus_exit(void);
+
 static LIST_HEAD(phy_fixup_list);
 static DEFINE_MUTEX(phy_fixup_lock);
 
@@ -166,6 +167,10 @@ struct phy_device* phy_device_create(struct mii_bus *bus, int addr, int phy_id)
        dev->addr = addr;
        dev->phy_id = phy_id;
        dev->bus = bus;
+       dev->dev.parent = bus->parent;
+       dev->dev.bus = &mdio_bus_type;
+       dev->irq = bus->irq != NULL ? bus->irq[addr] : PHY_POLL;
+       dev_set_name(&dev->dev, PHY_ID_FMT, bus->id, addr);
 
        dev->state = PHY_DOWN;
 
@@ -235,6 +240,38 @@ struct phy_device * get_phy_device(struct mii_bus *bus, int addr)
 
        return dev;
 }
+EXPORT_SYMBOL(get_phy_device);
+
+/**
+ * phy_device_register - Register the phy device on the MDIO bus
+ * @phy_device: phy_device structure to be added to the MDIO bus
+ */
+int phy_device_register(struct phy_device *phydev)
+{
+       int err;
+
+       /* Don't register a phy if one is already registered at this
+        * address */
+       if (phydev->bus->phy_map[phydev->addr])
+               return -EINVAL;
+       phydev->bus->phy_map[phydev->addr] = phydev;
+
+       /* Run all of the fixups for this PHY */
+       phy_scan_fixups(phydev);
+
+       err = device_register(&phydev->dev);
+       if (err) {
+               pr_err("phy %d failed to register\n", phydev->addr);
+               goto out;
+       }
+
+       return 0;
+
+ out:
+       phydev->bus->phy_map[phydev->addr] = NULL;
+       return err;
+}
+EXPORT_SYMBOL(phy_device_register);
 
 /**
  * phy_prepare_link - prepares the PHY layer to monitor link status
@@ -254,6 +291,33 @@ void phy_prepare_link(struct phy_device *phydev,
        phydev->adjust_link = handler;
 }
 
+/**
+ * phy_connect_direct - connect an ethernet device to a specific phy_device
+ * @dev: the network device to connect
+ * @phydev: the pointer to the phy device
+ * @handler: callback function for state change notifications
+ * @flags: PHY device's dev_flags
+ * @interface: PHY device's interface
+ */
+int phy_connect_direct(struct net_device *dev, struct phy_device *phydev,
+                      void (*handler)(struct net_device *), u32 flags,
+                      phy_interface_t interface)
+{
+       int rc;
+
+       rc = phy_attach_direct(dev, phydev, flags, interface);
+       if (rc)
+               return rc;
+
+       phy_prepare_link(phydev, handler);
+       phy_start_machine(phydev, NULL);
+       if (phydev->irq > 0)
+               phy_start_interrupts(phydev);
+
+       return 0;
+}
+EXPORT_SYMBOL(phy_connect_direct);
+
 /**
  * phy_connect - connect an ethernet device to a PHY device
  * @dev: the network device to connect
@@ -275,18 +339,21 @@ struct phy_device * phy_connect(struct net_device *dev, const char *bus_id,
                phy_interface_t interface)
 {
        struct phy_device *phydev;
+       struct device *d;
+       int rc;
 
-       phydev = phy_attach(dev, bus_id, flags, interface);
-
-       if (IS_ERR(phydev))
-               return phydev;
-
-       phy_prepare_link(phydev, handler);
-
-       phy_start_machine(phydev, NULL);
+       /* Search the list of PHY devices on the mdio bus for the
+        * PHY with the requested name */
+       d = bus_find_device_by_name(&mdio_bus_type, NULL, bus_id);
+       if (!d) {
+               pr_err("PHY %s not found\n", bus_id);
+               return ERR_PTR(-ENODEV);
+       }
+       phydev = to_phy_device(d);
 
-       if (phydev->irq > 0)
-               phy_start_interrupts(phydev);
+       rc = phy_connect_direct(dev, phydev, handler, flags, interface);
+       if (rc)
+               return ERR_PTR(rc);
 
        return phydev;
 }
@@ -310,9 +377,9 @@ void phy_disconnect(struct phy_device *phydev)
 EXPORT_SYMBOL(phy_disconnect);
 
 /**
- * phy_attach - attach a network device to a particular PHY device
+ * phy_attach_direct - attach a network device to a given PHY device pointer
  * @dev: network device to attach
- * @bus_id: PHY device to attach
+ * @phydev: Pointer to phy_device to attach
  * @flags: PHY device's dev_flags
  * @interface: PHY device's interface
  *
@@ -323,22 +390,10 @@ EXPORT_SYMBOL(phy_disconnect);
  *     the attaching device, and given a callback for link status
  *     change.  The phy_device is returned to the attaching driver.
  */
-struct phy_device *phy_attach(struct net_device *dev,
-               const char *bus_id, u32 flags, phy_interface_t interface)
+int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
+                     u32 flags, phy_interface_t interface)
 {
-       struct bus_type *bus = &mdio_bus_type;
-       struct phy_device *phydev;
-       struct device *d;
-
-       /* Search the list of PHY devices on the mdio bus for the
-        * PHY with the requested name */
-       d = bus_find_device_by_name(bus, NULL, bus_id);
-       if (d) {
-               phydev = to_phy_device(d);
-       } else {
-               printk(KERN_ERR "%s not found\n", bus_id);
-               return ERR_PTR(-ENODEV);
-       }
+       struct device *d = &phydev->dev;
 
        /* Assume that if there is no driver, that it doesn't
         * exist, and we should use the genphy driver. */
@@ -351,13 +406,12 @@ struct phy_device *phy_attach(struct net_device *dev,
                        err = device_bind_driver(d);
 
                if (err)
-                       return ERR_PTR(err);
+                       return err;
        }
 
        if (phydev->attached_dev) {
-               printk(KERN_ERR "%s: %s already attached\n",
-                               dev->name, bus_id);
-               return ERR_PTR(-EBUSY);
+               dev_err(&dev->dev, "PHY already attached\n");
+               return -EBUSY;
        }
 
        phydev->attached_dev = dev;
@@ -375,14 +429,49 @@ struct phy_device *phy_attach(struct net_device *dev,
                err = phy_scan_fixups(phydev);
 
                if (err < 0)
-                       return ERR_PTR(err);
+                       return err;
 
                err = phydev->drv->config_init(phydev);
 
                if (err < 0)
-                       return ERR_PTR(err);
+                       return err;
        }
 
+       return 0;
+}
+EXPORT_SYMBOL(phy_attach_direct);
+
+/**
+ * phy_attach - attach a network device to a particular PHY device
+ * @dev: network device to attach
+ * @bus_id: Bus ID of PHY device to attach
+ * @flags: PHY device's dev_flags
+ * @interface: PHY device's interface
+ *
+ * Description: Same as phy_attach_direct() except that a PHY bus_id
+ *     string is passed instead of a pointer to a struct phy_device.
+ */
+struct phy_device *phy_attach(struct net_device *dev,
+               const char *bus_id, u32 flags, phy_interface_t interface)
+{
+       struct bus_type *bus = &mdio_bus_type;
+       struct phy_device *phydev;
+       struct device *d;
+       int rc;
+
+       /* Search the list of PHY devices on the mdio bus for the
+        * PHY with the requested name */
+       d = bus_find_device_by_name(bus, NULL, bus_id);
+       if (!d) {
+               pr_err("PHY %s not found\n", bus_id);
+               return ERR_PTR(-ENODEV);
+       }
+       phydev = to_phy_device(d);
+
+       rc = phy_attach_direct(dev, phydev, flags, interface);
+       if (rc)
+               return ERR_PTR(rc);
+
        return phydev;
 }
 EXPORT_SYMBOL(phy_attach);
index 0be0f0b164f3cf6833701ecbf26369293d07fe3e..7a62f781fef2b83fdfe55dc0cad944cb5a2d7c8b 100644 (file)
@@ -955,12 +955,12 @@ plip_tx_packet(struct sk_buff *skb, struct net_device *dev)
        struct plip_local *snd = &nl->snd_data;
 
        if (netif_queue_stopped(dev))
-               return 1;
+               return NETDEV_TX_BUSY;
 
        /* We may need to grab the bus */
        if (!nl->port_owner) {
                if (parport_claim(nl->pardev))
-                       return 1;
+                       return NETDEV_TX_BUSY;
                nl->port_owner = 1;
        }
 
@@ -969,7 +969,7 @@ plip_tx_packet(struct sk_buff *skb, struct net_device *dev)
        if (skb->len > dev->mtu + dev->hard_header_len) {
                printk(KERN_WARNING "%s: packet too big, %d.\n", dev->name, (int)skb->len);
                netif_start_queue (dev);
-               return 1;
+               return NETDEV_TX_BUSY;
        }
 
        if (net_debug > 2)
index 8ee91421db12133634a922d2d8d70c933e22c248..639d11bc444e8a07a88c50beaddf9f867f126aee 100644 (file)
@@ -1054,6 +1054,7 @@ static void ppp_setup(struct net_device *dev)
        dev->type = ARPHRD_PPP;
        dev->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST;
        dev->features |= NETIF_F_NETNS_LOCAL;
+       dev->priv_flags &= ~IFF_XMIT_DST_RELEASE;
 }
 
 /*
index 5b07dd8e5c04e6b274e303b837c8243b31ba47dc..e7935d09c896786083606cc23d962a6504aed9a5 100644 (file)
@@ -433,8 +433,7 @@ static void pppol2tp_recv_dequeue_skb(struct pppol2tp_session *session, struct s
                 *   to the inner packet either
                 */
                secpath_reset(skb);
-               dst_release(skb->dst);
-               skb->dst = NULL;
+               skb_dst_drop(skb);
                nf_reset(skb);
 
                po = pppox_sk(session_sock);
@@ -976,7 +975,7 @@ static int pppol2tp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msgh
        /* Calculate UDP checksum if configured to do so */
        if (sk_tun->sk_no_check == UDP_CSUM_NOXMIT)
                skb->ip_summed = CHECKSUM_NONE;
-       else if (!(skb->dst->dev->features & NETIF_F_V4_CSUM)) {
+       else if (!(skb_dst(skb)->dev->features & NETIF_F_V4_CSUM)) {
                skb->ip_summed = CHECKSUM_COMPLETE;
                csum = skb_checksum(skb, 0, udp_len, 0);
                uh->check = csum_tcpudp_magic(inet->saddr, inet->daddr,
@@ -1172,14 +1171,14 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
        nf_reset(skb);
 
        /* Get routing info from the tunnel socket */
-       dst_release(skb->dst);
-       skb->dst = dst_clone(__sk_dst_get(sk_tun));
+       skb_dst_drop(skb);
+       skb_dst_set(skb, dst_clone(__sk_dst_get(sk_tun)));
        pppol2tp_skb_set_owner_w(skb, sk_tun);
 
        /* Calculate UDP checksum if configured to do so */
        if (sk_tun->sk_no_check == UDP_CSUM_NOXMIT)
                skb->ip_summed = CHECKSUM_NONE;
-       else if (!(skb->dst->dev->features & NETIF_F_V4_CSUM)) {
+       else if (!(skb_dst(skb)->dev->features & NETIF_F_V4_CSUM)) {
                skb->ip_summed = CHECKSUM_COMPLETE;
                csum = skb_checksum(skb, 0, udp_len, 0);
                uh->check = csum_tcpudp_magic(inet->saddr, inet->daddr,
@@ -1238,8 +1237,7 @@ static void pppol2tp_tunnel_closeall(struct pppol2tp_tunnel *tunnel)
        struct pppol2tp_session *session;
        struct sock *sk;
 
-       if (tunnel == NULL)
-               BUG();
+       BUG_ON(tunnel == NULL);
 
        PRINTK(tunnel->debug, PPPOL2TP_MSG_CONTROL, KERN_INFO,
               "%s: closing all sessions...\n", tunnel->name);
index cadc32c94c1e64da93b48ca26fb7ce448be88ef6..8a823ecc99a90568d55cdd10fd30c72cddb92906 100644 (file)
@@ -2617,7 +2617,6 @@ static int ql3xxx_send(struct sk_buff *skb, struct net_device *ndev)
                            &port_regs->CommonRegs.reqQProducerIndex,
                            qdev->req_producer_index);
 
-       ndev->trans_start = jiffies;
        if (netif_msg_tx_queued(qdev))
                printk(KERN_DEBUG PFX "%s: tx queued, slot %d, len %d\n",
                       ndev->name, qdev->req_producer_index, skb->len);
index fcb159e4df54e75231a17bcd48c115c778fa242a..156e02e8905ddc0b3ddc00bbdef4110bdb6ad165 100644 (file)
@@ -27,6 +27,8 @@
                           "%s: " fmt, __func__, ##args);  \
        } while (0)
 
+#define WQ_ADDR_ALIGN  0x3     /* 4 byte alignment */
+
 #define QLGE_VENDOR_ID    0x1077
 #define QLGE_DEVICE_ID_8012    0x8012
 #define QLGE_DEVICE_ID_8000    0x8000
 
 #define NUM_SMALL_BUFFERS   512
 #define NUM_LARGE_BUFFERS   512
+#define DB_PAGE_SIZE 4096
+
+/* Calculate the number of (4k) pages required to
+ * contain a buffer queue of the given length.
+ */
+#define MAX_DB_PAGES_PER_BQ(x) \
+               (((x * sizeof(u64)) / DB_PAGE_SIZE) + \
+               (((x * sizeof(u64)) % DB_PAGE_SIZE) ? 1 : 0))
 
+#define RX_RING_SHADOW_SPACE   (sizeof(u64) + \
+               MAX_DB_PAGES_PER_BQ(NUM_SMALL_BUFFERS) * sizeof(u64) + \
+               MAX_DB_PAGES_PER_BQ(NUM_LARGE_BUFFERS) * sizeof(u64))
 #define SMALL_BUFFER_SIZE 256
 #define LARGE_BUFFER_SIZE      PAGE_SIZE
 #define MAX_SPLIT_SIZE 1023
@@ -50,7 +63,7 @@
 #define MAX_INTER_FRAME_WAIT 10        /* 10 usec max interframe-wait for coalescing */
 #define DFLT_INTER_FRAME_WAIT (MAX_INTER_FRAME_WAIT/2)
 #define UDELAY_COUNT 3
-#define UDELAY_DELAY 10
+#define UDELAY_DELAY 100
 
 
 #define TX_DESC_PER_IOCB 8
 #define TX_DESC_PER_OAL 0
 #endif
 
-#define DB_PAGE_SIZE 4096
+/* MPI test register definitions. This register
+ * is used for determining alternate NIC function's
+ * PCI->func number.
+ */
+enum {
+       MPI_TEST_FUNC_PORT_CFG = 0x1002,
+       MPI_TEST_NIC1_FUNC_SHIFT = 1,
+       MPI_TEST_NIC2_FUNC_SHIFT = 5,
+       MPI_TEST_NIC_FUNC_MASK = 0x00000007,
+};
 
 /*
  * Processor Address Register (PROC_ADDR) bit definitions.
@@ -1430,7 +1452,10 @@ struct ql_adapter {
 
        /* Hardware information */
        u32 chip_rev_id;
+       u32 fw_rev_id;
        u32 func;               /* PCI function for this adapter */
+       u32 alt_func;           /* PCI function for alternate adapter */
+       u32 port;               /* Port number this adapter */
 
        spinlock_t adapter_lock;
        spinlock_t hw_lock;
@@ -1580,6 +1605,8 @@ void ql_mpi_idc_work(struct work_struct *work);
 void ql_mpi_port_cfg_work(struct work_struct *work);
 int ql_mb_get_fw_state(struct ql_adapter *qdev);
 int ql_cam_route_initialize(struct ql_adapter *qdev);
+int ql_read_mpi_reg(struct ql_adapter *qdev, u32 reg, u32 *data);
+int ql_mb_about_fw(struct ql_adapter *qdev);
 
 #if 1
 #define QL_ALL_DUMP
index 913b2a5fafc9fea160fb90bf0c18d1fd2f6e4447..37c99fe79770fc78de8c6a9cec9c15a743f50bef 100644 (file)
@@ -293,7 +293,10 @@ static void ql_get_drvinfo(struct net_device *ndev,
        struct ql_adapter *qdev = netdev_priv(ndev);
        strncpy(drvinfo->driver, qlge_driver_name, 32);
        strncpy(drvinfo->version, qlge_driver_version, 32);
-       strncpy(drvinfo->fw_version, "N/A", 32);
+       snprintf(drvinfo->fw_version, 32, "v%d.%d.%d",
+                (qdev->fw_rev_id & 0x00ff0000) >> 16,
+                (qdev->fw_rev_id & 0x0000ff00) >> 8,
+                (qdev->fw_rev_id & 0x000000ff));
        strncpy(drvinfo->bus_info, pci_name(qdev->pdev), 32);
        drvinfo->n_stats = 0;
        drvinfo->testinfo_len = 0;
@@ -401,6 +404,7 @@ const struct ethtool_ops qlge_ethtool_ops = {
        .get_rx_csum = ql_get_rx_csum,
        .set_rx_csum = ql_set_rx_csum,
        .get_tx_csum = ethtool_op_get_tx_csum,
+       .set_tx_csum = ethtool_op_set_tx_csum,
        .get_sg = ethtool_op_get_sg,
        .set_sg = ethtool_op_set_sg,
        .get_tso = ethtool_op_get_tso,
index 1fd5ecb24425c4b9c44db951368abbcc14a08249..90d1f76c0e8b074729047d5d7aed9440b8d8315f 100644 (file)
@@ -675,11 +675,12 @@ static int ql_get_8000_flash_params(struct ql_adapter *qdev)
        int status;
        __le32 *p = (__le32 *)&qdev->flash;
        u32 offset;
+       u8 mac_addr[6];
 
        /* Get flash offset for function and adjust
         * for dword access.
         */
-       if (!qdev->func)
+       if (!qdev->port)
                offset = FUNC0_FLASH_OFFSET / sizeof(u32);
        else
                offset = FUNC1_FLASH_OFFSET / sizeof(u32);
@@ -705,14 +706,26 @@ static int ql_get_8000_flash_params(struct ql_adapter *qdev)
                goto exit;
        }
 
-       if (!is_valid_ether_addr(qdev->flash.flash_params_8000.mac_addr)) {
+       /* Extract either manufacturer or BOFM modified
+        * MAC address.
+        */
+       if (qdev->flash.flash_params_8000.data_type1 == 2)
+               memcpy(mac_addr,
+                       qdev->flash.flash_params_8000.mac_addr1,
+                       qdev->ndev->addr_len);
+       else
+               memcpy(mac_addr,
+                       qdev->flash.flash_params_8000.mac_addr,
+                       qdev->ndev->addr_len);
+
+       if (!is_valid_ether_addr(mac_addr)) {
                QPRINTK(qdev, IFUP, ERR, "Invalid MAC address.\n");
                status = -EINVAL;
                goto exit;
        }
 
        memcpy(qdev->ndev->dev_addr,
-               qdev->flash.flash_params_8000.mac_addr,
+               mac_addr,
                qdev->ndev->addr_len);
 
 exit:
@@ -731,7 +744,7 @@ static int ql_get_8012_flash_params(struct ql_adapter *qdev)
        /* Second function's parameters follow the first
         * function's.
         */
-       if (qdev->func)
+       if (qdev->port)
                offset = size;
 
        if (ql_sem_spinlock(qdev, SEM_FLASH_MASK))
@@ -837,6 +850,13 @@ exit:
 static int ql_8000_port_initialize(struct ql_adapter *qdev)
 {
        int status;
+       /*
+        * Get MPI firmware version for driver banner
+        * and ethool info.
+        */
+       status = ql_mb_about_fw(qdev);
+       if (status)
+               goto exit;
        status = ql_mb_get_fw_state(qdev);
        if (status)
                goto exit;
@@ -1518,6 +1538,22 @@ static void ql_process_mac_rx_intr(struct ql_adapter *qdev,
                return;
        }
 
+       /* Frame error, so drop the packet. */
+       if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_ERR_MASK) {
+               QPRINTK(qdev, DRV, ERR, "Receive error, flags2 = 0x%x\n",
+                                       ib_mac_rsp->flags2);
+               dev_kfree_skb_any(skb);
+               return;
+       }
+
+       /* The max framesize filter on this chip is set higher than
+        * MTU since FCoE uses 2k frames.
+        */
+       if (skb->len > ndev->mtu + ETH_HLEN) {
+               dev_kfree_skb_any(skb);
+               return;
+       }
+
        prefetch(skb->data);
        skb->dev = ndev;
        if (ib_mac_rsp->flags1 & IB_MAC_IOCB_RSP_M_MASK) {
@@ -1540,7 +1576,6 @@ static void ql_process_mac_rx_intr(struct ql_adapter *qdev,
         * csum or frame errors.
         */
        if (qdev->rx_csum &&
-               !(ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_ERR_MASK) &&
                !(ib_mac_rsp->flags1 & IB_MAC_CSUM_ERR_MASK)) {
                /* TCP frame. */
                if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_T) {
@@ -2108,7 +2143,6 @@ static int qlge_send(struct sk_buff *skb, struct net_device *ndev)
        wmb();
 
        ql_write_db_reg(tx_ring->prod_idx, tx_ring->prod_idx_db_reg);
-       ndev->trans_start = jiffies;
        QPRINTK(qdev, TX_QUEUED, DEBUG, "tx queued, slot %d, len %d\n",
                tx_ring->prod_idx, skb->len);
 
@@ -2203,7 +2237,7 @@ static int ql_alloc_tx_resources(struct ql_adapter *qdev,
                                 &tx_ring->wq_base_dma);
 
        if ((tx_ring->wq_base == NULL)
-           || tx_ring->wq_base_dma & (tx_ring->wq_size - 1)) {
+               || tx_ring->wq_base_dma & WQ_ADDR_ALIGN) {
                QPRINTK(qdev, IFUP, ERR, "tx_ring alloc failed.\n");
                return -ENOMEM;
        }
@@ -2518,14 +2552,16 @@ static int ql_start_rx_ring(struct ql_adapter *qdev, struct rx_ring *rx_ring)
 {
        struct cqicb *cqicb = &rx_ring->cqicb;
        void *shadow_reg = qdev->rx_ring_shadow_reg_area +
-           (rx_ring->cq_id * sizeof(u64) * 4);
+               (rx_ring->cq_id * RX_RING_SHADOW_SPACE);
        u64 shadow_reg_dma = qdev->rx_ring_shadow_reg_dma +
-           (rx_ring->cq_id * sizeof(u64) * 4);
+               (rx_ring->cq_id * RX_RING_SHADOW_SPACE);
        void __iomem *doorbell_area =
            qdev->doorbell_area + (DB_PAGE_SIZE * (128 + rx_ring->cq_id));
        int err = 0;
        u16 bq_len;
        u64 tmp;
+       __le64 *base_indirect_ptr;
+       int page_entries;
 
        /* Set up the shadow registers for this ring. */
        rx_ring->prod_idx_sh_reg = shadow_reg;
@@ -2534,8 +2570,8 @@ static int ql_start_rx_ring(struct ql_adapter *qdev, struct rx_ring *rx_ring)
        shadow_reg_dma += sizeof(u64);
        rx_ring->lbq_base_indirect = shadow_reg;
        rx_ring->lbq_base_indirect_dma = shadow_reg_dma;
-       shadow_reg += sizeof(u64);
-       shadow_reg_dma += sizeof(u64);
+       shadow_reg += (sizeof(u64) * MAX_DB_PAGES_PER_BQ(rx_ring->lbq_len));
+       shadow_reg_dma += (sizeof(u64) * MAX_DB_PAGES_PER_BQ(rx_ring->lbq_len));
        rx_ring->sbq_base_indirect = shadow_reg;
        rx_ring->sbq_base_indirect_dma = shadow_reg_dma;
 
@@ -2572,7 +2608,14 @@ static int ql_start_rx_ring(struct ql_adapter *qdev, struct rx_ring *rx_ring)
        if (rx_ring->lbq_len) {
                cqicb->flags |= FLAGS_LL;       /* Load lbq values */
                tmp = (u64)rx_ring->lbq_base_dma;;
-               *((__le64 *) rx_ring->lbq_base_indirect) = cpu_to_le64(tmp);
+               base_indirect_ptr = (__le64 *) rx_ring->lbq_base_indirect;
+               page_entries = 0;
+               do {
+                       *base_indirect_ptr = cpu_to_le64(tmp);
+                       tmp += DB_PAGE_SIZE;
+                       base_indirect_ptr++;
+                       page_entries++;
+               } while (page_entries < MAX_DB_PAGES_PER_BQ(rx_ring->lbq_len));
                cqicb->lbq_addr =
                    cpu_to_le64(rx_ring->lbq_base_indirect_dma);
                bq_len = (rx_ring->lbq_buf_size == 65536) ? 0 :
@@ -2589,7 +2632,14 @@ static int ql_start_rx_ring(struct ql_adapter *qdev, struct rx_ring *rx_ring)
        if (rx_ring->sbq_len) {
                cqicb->flags |= FLAGS_LS;       /* Load sbq values */
                tmp = (u64)rx_ring->sbq_base_dma;;
-               *((__le64 *) rx_ring->sbq_base_indirect) = cpu_to_le64(tmp);
+               base_indirect_ptr = (__le64 *) rx_ring->sbq_base_indirect;
+               page_entries = 0;
+               do {
+                       *base_indirect_ptr = cpu_to_le64(tmp);
+                       tmp += DB_PAGE_SIZE;
+                       base_indirect_ptr++;
+                       page_entries++;
+               } while (page_entries < MAX_DB_PAGES_PER_BQ(rx_ring->sbq_len));
                cqicb->sbq_addr =
                    cpu_to_le64(rx_ring->sbq_base_indirect_dma);
                cqicb->sbq_buf_size =
@@ -3186,9 +3236,10 @@ static void ql_display_dev_info(struct net_device *ndev)
        struct ql_adapter *qdev = (struct ql_adapter *)netdev_priv(ndev);
 
        QPRINTK(qdev, PROBE, INFO,
-               "Function #%d, NIC Roll %d, NIC Rev = %d, "
+               "Function #%d, Port %d, NIC Roll %d, NIC Rev = %d, "
                "XG Roll = %d, XG Rev = %d.\n",
                qdev->func,
+               qdev->port,
                qdev->chip_rev_id & 0x0000000f,
                qdev->chip_rev_id >> 4 & 0x0000000f,
                qdev->chip_rev_id >> 8 & 0x0000000f,
@@ -3264,7 +3315,6 @@ static int ql_adapter_up(struct ql_adapter *qdev)
        err = ql_adapter_initialize(qdev);
        if (err) {
                QPRINTK(qdev, IFUP, INFO, "Unable to initialize adapter.\n");
-               spin_unlock(&qdev->hw_lock);
                goto err_init;
        }
        set_bit(QL_ADAPTER_UP, &qdev->flags);
@@ -3361,7 +3411,6 @@ static int ql_configure_rings(struct ql_adapter *qdev)
         * completion handler rx_rings.
         */
        qdev->rx_ring_count = qdev->tx_ring_count + qdev->rss_ring_count + 1;
-       netif_set_gso_max_size(qdev->ndev, 65536);
 
        for (i = 0; i < qdev->tx_ring_count; i++) {
                tx_ring = &qdev->tx_ring[i];
@@ -3644,12 +3693,53 @@ static struct nic_operations qla8000_nic_ops = {
        .port_initialize        = ql_8000_port_initialize,
 };
 
+/* Find the pcie function number for the other NIC
+ * on this chip.  Since both NIC functions share a
+ * common firmware we have the lowest enabled function
+ * do any common work.  Examples would be resetting
+ * after a fatal firmware error, or doing a firmware
+ * coredump.
+ */
+static int ql_get_alt_pcie_func(struct ql_adapter *qdev)
+{
+       int status = 0;
+       u32 temp;
+       u32 nic_func1, nic_func2;
+
+       status = ql_read_mpi_reg(qdev, MPI_TEST_FUNC_PORT_CFG,
+                       &temp);
+       if (status)
+               return status;
+
+       nic_func1 = ((temp >> MPI_TEST_NIC1_FUNC_SHIFT) &
+                       MPI_TEST_NIC_FUNC_MASK);
+       nic_func2 = ((temp >> MPI_TEST_NIC2_FUNC_SHIFT) &
+                       MPI_TEST_NIC_FUNC_MASK);
+
+       if (qdev->func == nic_func1)
+               qdev->alt_func = nic_func2;
+       else if (qdev->func == nic_func2)
+               qdev->alt_func = nic_func1;
+       else
+               status = -EIO;
+
+       return status;
+}
 
-static void ql_get_board_info(struct ql_adapter *qdev)
+static int ql_get_board_info(struct ql_adapter *qdev)
 {
+       int status;
        qdev->func =
            (ql_read32(qdev, STS) & STS_FUNC_ID_MASK) >> STS_FUNC_ID_SHIFT;
-       if (qdev->func) {
+       if (qdev->func > 3)
+               return -EIO;
+
+       status = ql_get_alt_pcie_func(qdev);
+       if (status)
+               return status;
+
+       qdev->port = (qdev->func < qdev->alt_func) ? 0 : 1;
+       if (qdev->port) {
                qdev->xg_sem_mask = SEM_XGMAC1_MASK;
                qdev->port_link_up = STS_PL1;
                qdev->port_init = STS_PI1;
@@ -3668,6 +3758,7 @@ static void ql_get_board_info(struct ql_adapter *qdev)
                qdev->nic_ops = &qla8012_nic_ops;
        else if (qdev->device_id == QLGE_DEVICE_ID_8000)
                qdev->nic_ops = &qla8000_nic_ops;
+       return status;
 }
 
 static void ql_release_all(struct pci_dev *pdev)
@@ -3762,7 +3853,12 @@ static int __devinit ql_init_device(struct pci_dev *pdev,
 
        qdev->ndev = ndev;
        qdev->pdev = pdev;
-       ql_get_board_info(qdev);
+       err = ql_get_board_info(qdev);
+       if (err) {
+               dev_err(&pdev->dev, "Register access failed.\n");
+               err = -EIO;
+               goto err_out;
+       }
        qdev->msg_enable = netif_msg_init(debug, default_msg);
        spin_lock_init(&qdev->hw_lock);
        spin_lock_init(&qdev->stats_lock);
index ac9493f6c1a149f1c5ccbc07f020f656256b8060..71afbf8b9c50c23d9c36acbc788dcda20d7e5336 100644 (file)
@@ -90,14 +90,14 @@ static int ql_get_mb_sts(struct ql_adapter *qdev, struct mbox_params *mbcp)
  */
 static int ql_wait_mbx_cmd_cmplt(struct ql_adapter *qdev)
 {
-       int count = 50; /* TODO: arbitrary for now. */
+       int count = 100;
        u32 value;
 
        do {
                value = ql_read32(qdev, STS);
                if (value & STS_PI)
                        return 0;
-               udelay(UDELAY_DELAY); /* 10us */
+               mdelay(UDELAY_DELAY); /* 100ms */
        } while (--count);
        return -ETIMEDOUT;
 }
@@ -453,6 +453,13 @@ static int ql_mpi_handler(struct ql_adapter *qdev, struct mbox_params *mbcp)
        }
 end:
        ql_write32(qdev, CSR, CSR_CMD_CLR_R2PCI_INT);
+       /* Restore the original mailbox count to
+        * what the caller asked for.  This can get
+        * changed when a mailbox command is waiting
+        * for a response and an AEN arrives and
+        * is handled.
+        * */
+       mbcp->out_count = orig_count;
        return status;
 }
 
@@ -540,6 +547,40 @@ end:
        return status;
 }
 
+
+/* Get MPI firmware version. This will be used for
+ * driver banner and for ethtool info.
+ * Returns zero on success.
+ */
+int ql_mb_about_fw(struct ql_adapter *qdev)
+{
+       struct mbox_params mbc;
+       struct mbox_params *mbcp = &mbc;
+       int status = 0;
+
+       memset(mbcp, 0, sizeof(struct mbox_params));
+
+       mbcp->in_count = 1;
+       mbcp->out_count = 3;
+
+       mbcp->mbox_in[0] = MB_CMD_ABOUT_FW;
+
+       status = ql_mailbox_command(qdev, mbcp);
+       if (status)
+               return status;
+
+       if (mbcp->mbox_out[0] != MB_CMD_STS_GOOD) {
+               QPRINTK(qdev, DRV, ERR,
+                       "Failed about firmware command\n");
+               status = -EIO;
+       }
+
+       /* Store the firmware version */
+       qdev->fw_rev_id = mbcp->mbox_out[1];
+
+       return status;
+}
+
 /* Get functional state for MPI firmware.
  * Returns zero on success.
  */
@@ -754,7 +795,6 @@ void ql_mpi_port_cfg_work(struct work_struct *work)
 {
        struct ql_adapter *qdev =
            container_of(work, struct ql_adapter, mpi_port_cfg_work.work);
-       struct net_device *ndev = qdev->ndev;
        int status;
 
        status = ql_mb_get_port_cfg(qdev);
@@ -764,9 +804,7 @@ void ql_mpi_port_cfg_work(struct work_struct *work)
                goto err;
        }
 
-       if (ndev->mtu <= 2500)
-               goto end;
-       else if (qdev->link_config & CFG_JUMBO_FRAME_SIZE &&
+       if (qdev->link_config & CFG_JUMBO_FRAME_SIZE &&
                        qdev->max_frame_size ==
                        CFG_DEFAULT_MAX_FRAME_SIZE)
                goto end;
@@ -831,13 +869,19 @@ void ql_mpi_work(struct work_struct *work)
            container_of(work, struct ql_adapter, mpi_work.work);
        struct mbox_params mbc;
        struct mbox_params *mbcp = &mbc;
+       int err = 0;
 
        mutex_lock(&qdev->mpi_mutex);
 
        while (ql_read32(qdev, STS) & STS_PI) {
                memset(mbcp, 0, sizeof(struct mbox_params));
                mbcp->out_count = 1;
-               ql_mpi_handler(qdev, mbcp);
+               /* Don't continue if an async event
+                * did not complete properly.
+                */
+               err = ql_mpi_handler(qdev, mbcp);
+               if (err)
+                       break;
        }
 
        mutex_unlock(&qdev->mpi_mutex);
index 6f97b47d74a6931c83294644640d724fd21207de..ed63d23a645233f9da9a6e88abb51632fdf5f98d 100644 (file)
@@ -49,8 +49,8 @@
 #include <asm/processor.h>
 
 #define DRV_NAME       "r6040"
-#define DRV_VERSION    "0.22"
-#define DRV_RELDATE    "25Mar2009"
+#define DRV_VERSION    "0.23"
+#define DRV_RELDATE    "05May2009"
 
 /* PHY CHIP Address */
 #define PHY1_ADDR      1       /* For MAC1 */
@@ -401,6 +401,9 @@ static void r6040_init_mac_regs(struct net_device *dev)
         * we may got called by r6040_tx_timeout which has left
         * some unsent tx buffers */
        iowrite16(0x01, ioaddr + MTPR);
+
+       /* Check media */
+       mii_check_media(&lp->mii_if, 1, 1);
 }
 
 static void r6040_tx_timeout(struct net_device *dev)
@@ -528,6 +531,8 @@ static int r6040_phy_mode_chk(struct net_device *dev)
                        phy_dat = 0x0000;
        }
 
+       mii_check_media(&lp->mii_if, 0, 1);
+
        return phy_dat;
 };
 
@@ -742,6 +747,14 @@ static int r6040_up(struct net_device *dev)
        struct r6040_private *lp = netdev_priv(dev);
        void __iomem *ioaddr = lp->base;
        int ret;
+       u16 val;
+
+       /* Check presence of a second PHY */
+       val = r6040_phy_read(ioaddr, lp->phy_addr, 2);
+       if (val == 0xFFFF) {
+               printk(KERN_ERR DRV_NAME " no second PHY attached\n");
+               return -EIO;
+       }
 
        /* Initialise and alloc RX/TX buffers */
        r6040_init_txbufs(dev);
@@ -802,7 +815,6 @@ static void r6040_timer(unsigned long data)
                lp->phy_mode = phy_mode;
                lp->mcr0 = (lp->mcr0 & 0x7fff) | phy_mode;
                iowrite16(lp->mcr0, ioaddr);
-               printk(KERN_INFO "Link Change %x \n", ioread16(ioaddr));
        }
 
        /* Timer active again */
index 3b19e0ce290fa4b6ba5f53a0b33c23b30ef098f8..35196faa084e87f797bdb33c2ce150590279d560 100644 (file)
@@ -93,6 +93,7 @@ static const int multicast_filter_limit = 32;
 #define RTL_R32(reg)           ((unsigned long) readl (ioaddr + (reg)))
 
 enum mac_version {
+       RTL_GIGA_MAC_NONE   = 0x00,
        RTL_GIGA_MAC_VER_01 = 0x01, // 8169
        RTL_GIGA_MAC_VER_02 = 0x02, // 8169S
        RTL_GIGA_MAC_VER_03 = 0x03, // 8110S
@@ -478,7 +479,6 @@ struct rtl8169_private {
        u16 intr_event;
        u16 napi_event;
        u16 intr_mask;
-       int phy_auto_nego_reg;
        int phy_1000_ctrl_reg;
 #ifdef CONFIG_R8169_VLAN
        struct vlan_group *vlgrp;
@@ -843,76 +843,81 @@ static int rtl8169_set_speed_xmii(struct net_device *dev,
 {
        struct rtl8169_private *tp = netdev_priv(dev);
        void __iomem *ioaddr = tp->mmio_addr;
-       int auto_nego, giga_ctrl;
-
-       auto_nego = mdio_read(ioaddr, MII_ADVERTISE);
-       auto_nego &= ~(ADVERTISE_10HALF | ADVERTISE_10FULL |
-                      ADVERTISE_100HALF | ADVERTISE_100FULL);
-       giga_ctrl = mdio_read(ioaddr, MII_CTRL1000);
-       giga_ctrl &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF);
+       int giga_ctrl, bmcr;
 
        if (autoneg == AUTONEG_ENABLE) {
+               int auto_nego;
+
+               auto_nego = mdio_read(ioaddr, MII_ADVERTISE);
                auto_nego |= (ADVERTISE_10HALF | ADVERTISE_10FULL |
                              ADVERTISE_100HALF | ADVERTISE_100FULL);
-               giga_ctrl |= ADVERTISE_1000FULL | ADVERTISE_1000HALF;
-       } else {
-               if (speed == SPEED_10)
-                       auto_nego |= ADVERTISE_10HALF | ADVERTISE_10FULL;
-               else if (speed == SPEED_100)
-                       auto_nego |= ADVERTISE_100HALF | ADVERTISE_100FULL;
-               else if (speed == SPEED_1000)
-                       giga_ctrl |= ADVERTISE_1000FULL | ADVERTISE_1000HALF;
-
-               if (duplex == DUPLEX_HALF)
-                       auto_nego &= ~(ADVERTISE_10FULL | ADVERTISE_100FULL);
-
-               if (duplex == DUPLEX_FULL)
-                       auto_nego &= ~(ADVERTISE_10HALF | ADVERTISE_100HALF);
+               auto_nego |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
 
-               /* This tweak comes straight from Realtek's driver. */
-               if ((speed == SPEED_100) && (duplex == DUPLEX_HALF) &&
-                   ((tp->mac_version == RTL_GIGA_MAC_VER_13) ||
-                    (tp->mac_version == RTL_GIGA_MAC_VER_16))) {
-                       auto_nego = ADVERTISE_100HALF | ADVERTISE_CSMA;
-               }
-       }
+               giga_ctrl = mdio_read(ioaddr, MII_CTRL1000);
+               giga_ctrl &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF);
 
-       /* The 8100e/8101e/8102e do Fast Ethernet only. */
-       if ((tp->mac_version == RTL_GIGA_MAC_VER_07) ||
-           (tp->mac_version == RTL_GIGA_MAC_VER_08) ||
-           (tp->mac_version == RTL_GIGA_MAC_VER_09) ||
-           (tp->mac_version == RTL_GIGA_MAC_VER_10) ||
-           (tp->mac_version == RTL_GIGA_MAC_VER_13) ||
-           (tp->mac_version == RTL_GIGA_MAC_VER_14) ||
-           (tp->mac_version == RTL_GIGA_MAC_VER_15) ||
-           (tp->mac_version == RTL_GIGA_MAC_VER_16)) {
-               if ((giga_ctrl & (ADVERTISE_1000FULL | ADVERTISE_1000HALF)) &&
-                   netif_msg_link(tp)) {
+               /* The 8100e/8101e/8102e do Fast Ethernet only. */
+               if ((tp->mac_version != RTL_GIGA_MAC_VER_07) &&
+                   (tp->mac_version != RTL_GIGA_MAC_VER_08) &&
+                   (tp->mac_version != RTL_GIGA_MAC_VER_09) &&
+                   (tp->mac_version != RTL_GIGA_MAC_VER_10) &&
+                   (tp->mac_version != RTL_GIGA_MAC_VER_13) &&
+                   (tp->mac_version != RTL_GIGA_MAC_VER_14) &&
+                   (tp->mac_version != RTL_GIGA_MAC_VER_15) &&
+                   (tp->mac_version != RTL_GIGA_MAC_VER_16)) {
+                       giga_ctrl |= ADVERTISE_1000FULL | ADVERTISE_1000HALF;
+               } else if (netif_msg_link(tp)) {
                        printk(KERN_INFO "%s: PHY does not support 1000Mbps.\n",
                               dev->name);
                }
-               giga_ctrl &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF);
-       }
 
-       auto_nego |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
+               bmcr = BMCR_ANENABLE | BMCR_ANRESTART;
+
+               if ((tp->mac_version == RTL_GIGA_MAC_VER_11) ||
+                   (tp->mac_version == RTL_GIGA_MAC_VER_12) ||
+                   (tp->mac_version >= RTL_GIGA_MAC_VER_17)) {
+                       /*
+                        * Wake up the PHY.
+                        * Vendor specific (0x1f) and reserved (0x0e) MII
+                        * registers.
+                        */
+                       mdio_write(ioaddr, 0x1f, 0x0000);
+                       mdio_write(ioaddr, 0x0e, 0x0000);
+               }
+
+               mdio_write(ioaddr, MII_ADVERTISE, auto_nego);
+               mdio_write(ioaddr, MII_CTRL1000, giga_ctrl);
+       } else {
+               giga_ctrl = 0;
+
+               if (speed == SPEED_10)
+                       bmcr = 0;
+               else if (speed == SPEED_100)
+                       bmcr = BMCR_SPEED100;
+               else
+                       return -EINVAL;
+
+               if (duplex == DUPLEX_FULL)
+                       bmcr |= BMCR_FULLDPLX;
 
-       if ((tp->mac_version == RTL_GIGA_MAC_VER_11) ||
-           (tp->mac_version == RTL_GIGA_MAC_VER_12) ||
-           (tp->mac_version >= RTL_GIGA_MAC_VER_17)) {
-               /*
-                * Wake up the PHY.
-                * Vendor specific (0x1f) and reserved (0x0e) MII registers.
-                */
                mdio_write(ioaddr, 0x1f, 0x0000);
-               mdio_write(ioaddr, 0x0e, 0x0000);
        }
 
-       tp->phy_auto_nego_reg = auto_nego;
        tp->phy_1000_ctrl_reg = giga_ctrl;
 
-       mdio_write(ioaddr, MII_ADVERTISE, auto_nego);
-       mdio_write(ioaddr, MII_CTRL1000, giga_ctrl);
-       mdio_write(ioaddr, MII_BMCR, BMCR_ANENABLE | BMCR_ANRESTART);
+       mdio_write(ioaddr, MII_BMCR, bmcr);
+
+       if ((tp->mac_version == RTL_GIGA_MAC_VER_02) ||
+           (tp->mac_version == RTL_GIGA_MAC_VER_03)) {
+               if ((speed == SPEED_100) && (autoneg != AUTONEG_ENABLE)) {
+                       mdio_write(ioaddr, 0x17, 0x2138);
+                       mdio_write(ioaddr, 0x0e, 0x0260);
+               } else {
+                       mdio_write(ioaddr, 0x17, 0x2108);
+                       mdio_write(ioaddr, 0x0e, 0x0000);
+               }
+       }
+
        return 0;
 }
 
@@ -1295,7 +1300,8 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp,
                { 0xfc800000, 0x00800000,       RTL_GIGA_MAC_VER_02 },
                { 0xfc800000, 0x00000000,       RTL_GIGA_MAC_VER_01 },
 
-               { 0x00000000, 0x00000000,       RTL_GIGA_MAC_VER_01 }   /* Catch-all */
+               /* Catch-all */
+               { 0x00000000, 0x00000000,       RTL_GIGA_MAC_NONE   }
        }, *p = mac_info;
        u32 reg;
 
@@ -1303,12 +1309,6 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp,
        while ((reg & p->mask) != p->val)
                p++;
        tp->mac_version = p->mac_version;
-
-       if (p->mask == 0x00000000) {
-               struct pci_dev *pdev = tp->pci_dev;
-
-               dev_info(&pdev->dev, "unknown MAC (%08x)\n", reg);
-       }
 }
 
 static void rtl8169_print_mac_version(struct rtl8169_private *tp)
@@ -1884,6 +1884,7 @@ static const struct rtl_cfg_info {
        u16 intr_event;
        u16 napi_event;
        unsigned features;
+       u8 default_ver;
 } rtl_cfg_infos [] = {
        [RTL_CFG_0] = {
                .hw_start       = rtl_hw_start_8169,
@@ -1892,7 +1893,8 @@ static const struct rtl_cfg_info {
                .intr_event     = SYSErr | LinkChg | RxOverflow |
                                  RxFIFOOver | TxErr | TxOK | RxOK | RxErr,
                .napi_event     = RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow,
-               .features       = RTL_FEATURE_GMII
+               .features       = RTL_FEATURE_GMII,
+               .default_ver    = RTL_GIGA_MAC_VER_01,
        },
        [RTL_CFG_1] = {
                .hw_start       = rtl_hw_start_8168,
@@ -1901,7 +1903,8 @@ static const struct rtl_cfg_info {
                .intr_event     = SYSErr | LinkChg | RxOverflow |
                                  TxErr | TxOK | RxOK | RxErr,
                .napi_event     = TxErr | TxOK | RxOK | RxOverflow,
-               .features       = RTL_FEATURE_GMII | RTL_FEATURE_MSI
+               .features       = RTL_FEATURE_GMII | RTL_FEATURE_MSI,
+               .default_ver    = RTL_GIGA_MAC_VER_11,
        },
        [RTL_CFG_2] = {
                .hw_start       = rtl_hw_start_8101,
@@ -1910,7 +1913,8 @@ static const struct rtl_cfg_info {
                .intr_event     = SYSErr | LinkChg | RxOverflow | PCSTimeout |
                                  RxFIFOOver | TxErr | TxOK | RxOK | RxErr,
                .napi_event     = RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow,
-               .features       = RTL_FEATURE_MSI
+               .features       = RTL_FEATURE_MSI,
+               .default_ver    = RTL_GIGA_MAC_VER_13,
        }
 };
 
@@ -2091,6 +2095,15 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        /* Identify chip attached to board */
        rtl8169_get_mac_version(tp, ioaddr);
 
+       /* Use appropriate default if unknown */
+       if (tp->mac_version == RTL_GIGA_MAC_NONE) {
+               if (netif_msg_probe(tp)) {
+                       dev_notice(&pdev->dev,
+                                  "unknown MAC, using family default\n");
+               }
+               tp->mac_version = cfg->default_ver;
+       }
+
        rtl8169_print_mac_version(tp);
 
        for (i = 0; i < ARRAY_SIZE(rtl_chip_info); i++) {
@@ -2098,13 +2111,9 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
                        break;
        }
        if (i == ARRAY_SIZE(rtl_chip_info)) {
-               /* Unknown chip: assume array element #0, original RTL-8169 */
-               if (netif_msg_probe(tp)) {
-                       dev_printk(KERN_DEBUG, &pdev->dev,
-                               "unknown chip version, assuming %s\n",
-                               rtl_chip_info[0].name);
-               }
-               i = 0;
+               dev_err(&pdev->dev,
+                       "driver bug, MAC version not found in rtl_chip_info\n");
+               goto err_out_msi_5;
        }
        tp->chipset = i;
 
@@ -3269,8 +3278,6 @@ static int rtl8169_start_xmit(struct sk_buff *skb, struct net_device *dev)
        status = opts1 | len | (RingEnd * !((entry + 1) % NUM_TX_DESC));
        txd->opts1 = cpu_to_le32(status);
 
-       dev->trans_start = jiffies;
-
        tp->cur_tx += frags + 1;
 
        smp_wmb();
@@ -3371,7 +3378,7 @@ static void rtl8169_tx_interrupt(struct net_device *dev,
                rtl8169_unmap_tx_skb(tp->pci_dev, tx_skb, tp->TxDescArray + entry);
 
                if (status & LastFrag) {
-                       dev_kfree_skb_irq(tx_skb->skb);
+                       dev_kfree_skb(tx_skb->skb);
                        tx_skb->skb = NULL;
                }
                dirty_tx++;
@@ -3802,16 +3809,13 @@ static struct net_device_stats *rtl8169_get_stats(struct net_device *dev)
        return &dev->stats;
 }
 
-#ifdef CONFIG_PM
-
-static int rtl8169_suspend(struct pci_dev *pdev, pm_message_t state)
+static void rtl8169_net_suspend(struct net_device *dev)
 {
-       struct net_device *dev = pci_get_drvdata(pdev);
        struct rtl8169_private *tp = netdev_priv(dev);
        void __iomem *ioaddr = tp->mmio_addr;
 
        if (!netif_running(dev))
-               goto out_pci_suspend;
+               return;
 
        netif_device_detach(dev);
        netif_stop_queue(dev);
@@ -3823,24 +3827,25 @@ static int rtl8169_suspend(struct pci_dev *pdev, pm_message_t state)
        rtl8169_rx_missed(dev, ioaddr);
 
        spin_unlock_irq(&tp->lock);
+}
 
-out_pci_suspend:
-       pci_save_state(pdev);
-       pci_enable_wake(pdev, pci_choose_state(pdev, state),
-               (tp->features & RTL_FEATURE_WOL) ? 1 : 0);
-       pci_set_power_state(pdev, pci_choose_state(pdev, state));
+#ifdef CONFIG_PM
+
+static int rtl8169_suspend(struct device *device)
+{
+       struct pci_dev *pdev = to_pci_dev(device);
+       struct net_device *dev = pci_get_drvdata(pdev);
+
+       rtl8169_net_suspend(dev);
 
        return 0;
 }
 
-static int rtl8169_resume(struct pci_dev *pdev)
+static int rtl8169_resume(struct device *device)
 {
+       struct pci_dev *pdev = to_pci_dev(device);
        struct net_device *dev = pci_get_drvdata(pdev);
 
-       pci_set_power_state(pdev, PCI_D0);
-       pci_restore_state(pdev);
-       pci_enable_wake(pdev, PCI_D0, 0);
-
        if (!netif_running(dev))
                goto out;
 
@@ -3851,23 +3856,42 @@ out:
        return 0;
 }
 
+static struct dev_pm_ops rtl8169_pm_ops = {
+       .suspend = rtl8169_suspend,
+       .resume = rtl8169_resume,
+       .freeze = rtl8169_suspend,
+       .thaw = rtl8169_resume,
+       .poweroff = rtl8169_suspend,
+       .restore = rtl8169_resume,
+};
+
+#define RTL8169_PM_OPS (&rtl8169_pm_ops)
+
+#else /* !CONFIG_PM */
+
+#define RTL8169_PM_OPS NULL
+
+#endif /* !CONFIG_PM */
+
 static void rtl_shutdown(struct pci_dev *pdev)
 {
-       rtl8169_suspend(pdev, PMSG_SUSPEND);
-}
+       struct net_device *dev = pci_get_drvdata(pdev);
+
+       rtl8169_net_suspend(dev);
 
-#endif /* CONFIG_PM */
+       if (system_state == SYSTEM_POWER_OFF) {
+               pci_wake_from_d3(pdev, true);
+               pci_set_power_state(pdev, PCI_D3hot);
+       }
+}
 
 static struct pci_driver rtl8169_pci_driver = {
        .name           = MODULENAME,
        .id_table       = rtl8169_pci_tbl,
        .probe          = rtl8169_init_one,
        .remove         = __devexit_p(rtl8169_remove_one),
-#ifdef CONFIG_PM
-       .suspend        = rtl8169_suspend,
-       .resume         = rtl8169_resume,
        .shutdown       = rtl_shutdown,
-#endif
+       .driver.pm      = RTL8169_PM_OPS,
 };
 
 static int __init rtl8169_init_module(void)
index ec59e29807a67ad94a79ded9d2487856ae436ec9..8702e7acdee648565112494e1095b5668f5e76f7 100644 (file)
@@ -428,6 +428,15 @@ static const struct ethtool_ops rionet_ethtool_ops = {
        .get_link = ethtool_op_get_link,
 };
 
+static const struct net_device_ops rionet_netdev_ops = {
+       .ndo_open               = rionet_open,
+       .ndo_stop               = rionet_close,
+       .ndo_start_xmit         = rionet_start_xmit,
+       .ndo_change_mtu         = eth_change_mtu,
+       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_set_mac_address    = eth_mac_addr,
+};
+
 static int rionet_setup_netdev(struct rio_mport *mport)
 {
        int rc = 0;
@@ -466,10 +475,7 @@ static int rionet_setup_netdev(struct rio_mport *mport)
        ndev->dev_addr[4] = device_id >> 8;
        ndev->dev_addr[5] = device_id & 0xff;
 
-       /* Fill in the driver function table */
-       ndev->open = &rionet_open;
-       ndev->hard_start_xmit = &rionet_start_xmit;
-       ndev->stop = &rionet_close;
+       ndev->netdev_ops = &rionet_netdev_ops;
        ndev->mtu = RIO_MAX_MSG_SIZE - 14;
        ndev->features = NETIF_F_LLTX;
        SET_ETHTOOL_OPS(ndev, &rionet_ethtool_ops);
index d890829a9acc61f678e06c273a031976603f010f..81dbcbb910f4099c0644c9222ed773f8be3df9c9 100644 (file)
@@ -1425,7 +1425,7 @@ static int rr_start_xmit(struct sk_buff *skb, struct net_device *dev)
                if (!(new_skb = dev_alloc_skb(len + 8))) {
                        dev_kfree_skb(skb);
                        netif_wake_queue(dev);
-                       return -EBUSY;
+                       return NETDEV_TX_OK;
                }
                skb_reserve(new_skb, 8);
                skb_put(new_skb, len);
index f8274f8941ea4cb383938bf7e01febdbaad51da5..416669fd68c6bcbaf42b4ebc4962195713f1d459 100644 (file)
@@ -271,11 +271,6 @@ struct XENA_dev_config {
        u64 mdio_control;
 #define MDIO_MMD_INDX_ADDR(val)                vBIT(val, 0, 16)
 #define MDIO_MMD_DEV_ADDR(val)         vBIT(val, 19, 5)
-#define MDIO_MMD_PMA_DEV_ADDR          0x1
-#define MDIO_MMD_PMD_DEV_ADDR          0x1
-#define MDIO_MMD_WIS_DEV_ADDR          0x2
-#define MDIO_MMD_PCS_DEV_ADDR          0x3
-#define MDIO_MMD_PHYXS_DEV_ADDR                0x4
 #define MDIO_MMS_PRT_ADDR(val)         vBIT(val, 27, 5)
 #define MDIO_CTRL_START_TRANS(val)     vBIT(val, 56, 4)
 #define MDIO_OP(val)                   vBIT(val, 60, 2)
index 1a4979f27fb5af83e82c31ad448f4a63774b67e4..458daa06ed41ebafb0f327be81c289cf1a6e62f5 100644 (file)
@@ -63,6 +63,7 @@
 #include <linux/kernel.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
+#include <linux/mdio.h>
 #include <linux/skbuff.h>
 #include <linux/init.h>
 #include <linux/delay.h>
@@ -1763,7 +1764,7 @@ static int init_nic(struct s2io_nic *nic)
                 * by then we return error.
                 */
                time = 0;
-               while (TRUE) {
+               while (true) {
                        val64 = readq(&bar0->rti_command_mem);
                        if (!(val64 & RTI_CMD_MEM_STROBE_NEW_CMD))
                                break;
@@ -2136,7 +2137,7 @@ static int verify_pcc_quiescent(struct s2io_nic *sp, int flag)
 
        herc = (sp->device_type == XFRAME_II_DEVICE);
 
-       if (flag == FALSE) {
+       if (flag == false) {
                if ((!herc && (sp->pdev->revision >= 4)) || herc) {
                        if (!(val64 & ADAPTER_STATUS_RMAC_PCC_IDLE))
                                ret = 1;
@@ -3328,9 +3329,9 @@ static void s2io_updt_xpak_counter(struct net_device *dev)
        struct stat_block *stat_info = sp->mac_control.stats_info;
 
        /* Check the communication with the MDIO slave */
-       addr = 0x0000;
+       addr = MDIO_CTRL1;
        val64 = 0x0;
-       val64 = s2io_mdio_read(MDIO_MMD_PMA_DEV_ADDR, addr, dev);
+       val64 = s2io_mdio_read(MDIO_MMD_PMAPMD, addr, dev);
        if((val64 == 0xFFFF) || (val64 == 0x0000))
        {
                DBG_PRINT(ERR_DBG, "ERR: MDIO slave access failed - "
@@ -3338,24 +3339,24 @@ static void s2io_updt_xpak_counter(struct net_device *dev)
                return;
        }
 
-       /* Check for the expecte value of 2040 at PMA address 0x0000 */
-       if(val64 != 0x2040)
+       /* Check for the expected value of control reg 1 */
+       if(val64 != MDIO_CTRL1_SPEED10G)
        {
                DBG_PRINT(ERR_DBG, "Incorrect value at PMA address 0x0000 - ");
-               DBG_PRINT(ERR_DBG, "Returned: %llx- Expected: 0x2040\n",
-                         (unsigned long long)val64);
+               DBG_PRINT(ERR_DBG, "Returned: %llx- Expected: 0x%x\n",
+                         (unsigned long long)val64, MDIO_CTRL1_SPEED10G);
                return;
        }
 
        /* Loading the DOM register to MDIO register */
        addr = 0xA100;
-       s2io_mdio_write(MDIO_MMD_PMA_DEV_ADDR, addr, val16, dev);
-       val64 = s2io_mdio_read(MDIO_MMD_PMA_DEV_ADDR, addr, dev);
+       s2io_mdio_write(MDIO_MMD_PMAPMD, addr, val16, dev);
+       val64 = s2io_mdio_read(MDIO_MMD_PMAPMD, addr, dev);
 
        /* Reading the Alarm flags */
        addr = 0xA070;
        val64 = 0x0;
-       val64 = s2io_mdio_read(MDIO_MMD_PMA_DEV_ADDR, addr, dev);
+       val64 = s2io_mdio_read(MDIO_MMD_PMAPMD, addr, dev);
 
        flag = CHECKBIT(val64, 0x7);
        type = 1;
@@ -3387,7 +3388,7 @@ static void s2io_updt_xpak_counter(struct net_device *dev)
        /* Reading the Warning flags */
        addr = 0xA074;
        val64 = 0x0;
-       val64 = s2io_mdio_read(MDIO_MMD_PMA_DEV_ADDR, addr, dev);
+       val64 = s2io_mdio_read(MDIO_MMD_PMAPMD, addr, dev);
 
        if(CHECKBIT(val64, 0x7))
                stat_info->xpak_stat.warn_transceiver_temp_high++;
@@ -3586,7 +3587,7 @@ static void s2io_reset(struct s2io_nic * sp)
                writeq(val64, &bar0->pcc_err_reg);
        }
 
-       sp->device_enabled_once = FALSE;
+       sp->device_enabled_once = false;
 }
 
 /**
@@ -4298,7 +4299,6 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
                s2io_stop_tx_queue(sp, fifo->fifo_no);
        }
        mac_control->stats_info->sw_stat.mem_allocated += skb->truesize;
-       dev->trans_start = jiffies;
        spin_unlock_irqrestore(&fifo->tx_lock, flags);
 
        if (sp->config.intr_type == MSI_X)
@@ -5572,10 +5572,10 @@ static void s2io_ethtool_getpause_data(struct net_device *dev,
 
        val64 = readq(&bar0->rmac_pause_cfg);
        if (val64 & RMAC_PAUSE_GEN_ENABLE)
-               ep->tx_pause = TRUE;
+               ep->tx_pause = true;
        if (val64 & RMAC_PAUSE_RX_ENABLE)
-               ep->rx_pause = TRUE;
-       ep->autoneg = FALSE;
+               ep->rx_pause = true;
+       ep->autoneg = false;
 }
 
 /**
@@ -6806,7 +6806,7 @@ static void s2io_set_link(struct work_struct *work)
                                        val64 |= ADAPTER_LED_ON;
                                        writeq(val64, &bar0->adapter_control);
                                }
-                               nic->device_enabled_once = TRUE;
+                               nic->device_enabled_once = true;
                        } else {
                                DBG_PRINT(ERR_DBG, "%s: Error: ", dev->name);
                                DBG_PRINT(ERR_DBG, "device is not Quiescent\n");
@@ -7754,7 +7754,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
        struct s2io_nic *sp;
        struct net_device *dev;
        int i, j, ret;
-       int dma_flag = FALSE;
+       int dma_flag = false;
        u32 mac_up, mac_down;
        u64 val64 = 0, tmp64 = 0;
        struct XENA_dev_config __iomem *bar0 = NULL;
@@ -7777,7 +7777,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
 
        if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
                DBG_PRINT(INIT_DBG, "s2io_init_nic: Using 64bit DMA\n");
-               dma_flag = TRUE;
+               dma_flag = true;
                if (pci_set_consistent_dma_mask
                    (pdev, DMA_BIT_MASK(64))) {
                        DBG_PRINT(ERR_DBG,
@@ -7818,7 +7818,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
        sp->dev = dev;
        sp->pdev = pdev;
        sp->high_dma_flag = dma_flag;
-       sp->device_enabled_once = FALSE;
+       sp->device_enabled_once = false;
        if (rx_ring_mode == 1)
                sp->rxd_mode = RXD_MODE_1;
        if (rx_ring_mode == 2)
@@ -7964,7 +7964,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
        dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
 
        dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
-       if (sp->high_dma_flag == TRUE)
+       if (sp->high_dma_flag == true)
                dev->features |= NETIF_F_HIGHDMA;
        dev->features |= NETIF_F_TSO;
        dev->features |= NETIF_F_TSO6;
index 55cb943f23f86c8f35a77bd58cae27727dc0dd8e..d5c5be6c07b9520d57b9eb15fc4510cf98bc607e 100644 (file)
 #define vBIT(val, loc, sz)     (((u64)val) << (64-loc-sz))
 #define INV(d)  ((d&0xff)<<24) | (((d>>8)&0xff)<<16) | (((d>>16)&0xff)<<8)| ((d>>24)&0xff)
 
-#ifndef BOOL
-#define BOOL    int
-#endif
-
-#ifndef TRUE
-#define TRUE    1
-#define FALSE   0
-#endif
-
 #undef SUCCESS
 #define SUCCESS 0
 #define FAILURE -1
index ce7551e17ba780e4c1aa5be39b6cc49be2792a8e..d8c9cf1b901d7f8c5780ffff4b61490fcfd65c54 100644 (file)
@@ -2084,7 +2084,7 @@ static int sbmac_start_tx(struct sk_buff *skb, struct net_device *dev)
                netif_stop_queue(dev);
                spin_unlock_irqrestore(&sc->sbm_lock, flags);
 
-               return 1;
+               return NETDEV_TX_BUSY;
        }
 
        dev->trans_start = jiffies;
@@ -2271,6 +2271,21 @@ static int sb1250_change_mtu(struct net_device *_dev, int new_mtu)
        return 0;
 }
 
+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_tx_timeout         = sbmac_tx_timeout,
+       .ndo_do_ioctl           = sbmac_mii_ioctl,
+       .ndo_change_mtu         = sb1250_change_mtu,
+       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_set_mac_address    = eth_mac_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+       .ndo_poll_controller    = sbmac_netpoll,
+#endif
+};
+
 /**********************************************************************
  *  SBMAC_INIT(dev)
  *
@@ -2285,7 +2300,7 @@ static int sb1250_change_mtu(struct net_device *_dev, int new_mtu)
 
 static int sbmac_init(struct platform_device *pldev, long long base)
 {
-       struct net_device *dev = pldev->dev.driver_data;
+       struct net_device *dev = dev_get_drvdata(&pldev->dev);
        int idx = pldev->id;
        struct sbmac_softc *sc = netdev_priv(dev);
        unsigned char *eaddr;
@@ -2327,21 +2342,11 @@ static int sbmac_init(struct platform_device *pldev, long long base)
 
        spin_lock_init(&(sc->sbm_lock));
 
-       dev->open               = sbmac_open;
-       dev->hard_start_xmit    = sbmac_start_tx;
-       dev->stop               = sbmac_close;
-       dev->set_multicast_list = sbmac_set_rx_mode;
-       dev->do_ioctl           = sbmac_mii_ioctl;
-       dev->tx_timeout         = sbmac_tx_timeout;
-       dev->watchdog_timeo     = TX_TIMEOUT;
+       dev->netdev_ops = &sbmac_netdev_ops;
+       dev->watchdog_timeo = TX_TIMEOUT;
 
        netif_napi_add(dev, &sc->napi, sbmac_poll, 16);
 
-       dev->change_mtu         = sb1250_change_mtu;
-#ifdef CONFIG_NET_POLL_CONTROLLER
-       dev->poll_controller = sbmac_netpoll;
-#endif
-
        dev->irq                = UNIT_INT(idx);
 
        /* This is needed for PASS2 for Rx H/W checksum feature */
@@ -2726,7 +2731,7 @@ static int __init sbmac_probe(struct platform_device *pldev)
                goto out_unmap;
        }
 
-       pldev->dev.driver_data = dev;
+       dev_set_drvdata(&pldev->dev, dev);
        SET_NETDEV_DEV(dev, &pldev->dev);
 
        sc = netdev_priv(dev);
@@ -2751,7 +2756,7 @@ out_out:
 
 static int __exit sbmac_remove(struct platform_device *pldev)
 {
-       struct net_device *dev = pldev->dev.driver_data;
+       struct net_device *dev = dev_get_drvdata(&pldev->dev);
        struct sbmac_softc *sc = netdev_priv(dev);
 
        unregister_netdev(dev);
index 12a82966b5779f2db7f115ac7f967afc4baff8e2..260aafaac2359e6b67c2f28e3d59dbc8089bf555 100644 (file)
@@ -1,7 +1,7 @@
 config SFC
        tristate "Solarflare Solarstorm SFC4000 support"
        depends on PCI && INET
-       select MII
+       select MDIO
        select CRC32
        select I2C
        select I2C_ALGOBIT
index 5182ac5a1034c2d0ccb3cce336446b0f02e04089..4a4c74c891b755c99692df94c7758aa99ab9008e 100644 (file)
@@ -172,7 +172,6 @@ static const u8 sfe4002_lm87_regs[] = {
 static struct i2c_board_info sfe4002_hwmon_info = {
        I2C_BOARD_INFO("lm87", 0x2e),
        .platform_data  = &sfe4002_lm87_channel,
-       .irq            = -1,
 };
 
 /****************************************************************************/
@@ -247,7 +246,6 @@ static const u8 sfn4112f_lm87_regs[] = {
 static struct i2c_board_info sfn4112f_hwmon_info = {
        I2C_BOARD_INFO("lm87", 0x2e),
        .platform_data  = &sfn4112f_lm87_channel,
-       .irq            = -1,
 };
 
 #define SFN4112F_ACT_LED       0
index 7269a426051c01f0671dc80fc41e204eb55aaf72..343e8da1fa30a3f9786fbe3cacdd636d9d6bbdb5 100644 (file)
@@ -49,16 +49,6 @@ static struct workqueue_struct *reset_workqueue;
  *
  *************************************************************************/
 
-/*
- * Enable large receive offload (LRO) aka soft segment reassembly (SSR)
- *
- * This sets the default for new devices.  It can be controlled later
- * using ethtool.
- */
-static int lro = true;
-module_param(lro, int, 0644);
-MODULE_PARM_DESC(lro, "Large receive offload acceleration");
-
 /*
  * Use separate channels for TX and RX events
  *
@@ -894,9 +884,9 @@ static int efx_wanted_rx_queues(void)
        int count;
        int cpu;
 
-       if (!alloc_cpumask_var(&core_mask, GFP_KERNEL)) {
+       if (unlikely(!alloc_cpumask_var(&core_mask, GFP_KERNEL))) {
                printk(KERN_WARNING
-                      "efx.c: allocation failure, irq balancing hobbled\n");
+                      "sfc: RSS disabled due to allocation failure\n");
                return 1;
        }
 
@@ -1300,10 +1290,16 @@ out_requeue:
 static int efx_ioctl(struct net_device *net_dev, struct ifreq *ifr, int cmd)
 {
        struct efx_nic *efx = netdev_priv(net_dev);
+       struct mii_ioctl_data *data = if_mii(ifr);
 
        EFX_ASSERT_RESET_SERIALISED(efx);
 
-       return generic_mii_ioctl(&efx->mii, if_mii(ifr), cmd, NULL);
+       /* Convert phy_id from older PRTAD/DEVAD format */
+       if ((cmd == SIOCGMIIREG || cmd == SIOCSMIIREG) &&
+           (data->phy_id & 0xfc00) == 0x0400)
+               data->phy_id ^= MDIO_PHY_ID_C45 | 0x0400;
+
+       return mdio_mii_ioctl(&efx->mdio, data, cmd);
 }
 
 /**************************************************************************
@@ -1945,7 +1941,7 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type,
        mutex_init(&efx->mac_lock);
        efx->mac_op = &efx_dummy_mac_operations;
        efx->phy_op = &efx_dummy_phy_operations;
-       efx->mii.dev = net_dev;
+       efx->mdio.dev = net_dev;
        INIT_WORK(&efx->phy_work, efx_phy_work);
        INIT_WORK(&efx->mac_work, efx_mac_work);
        atomic_set(&efx->netif_stop_count, 1);
@@ -2161,9 +2157,8 @@ static int __devinit efx_pci_probe(struct pci_dev *pci_dev,
        if (!net_dev)
                return -ENOMEM;
        net_dev->features |= (NETIF_F_IP_CSUM | NETIF_F_SG |
-                             NETIF_F_HIGHDMA | NETIF_F_TSO);
-       if (lro)
-               net_dev->features |= NETIF_F_GRO;
+                             NETIF_F_HIGHDMA | NETIF_F_TSO |
+                             NETIF_F_GRO);
        /* Mask for features that also apply to VLAN devices */
        net_dev->vlan_features |= (NETIF_F_ALL_CSUM | NETIF_F_SG |
                                   NETIF_F_HIGHDMA | NETIF_F_TSO);
index 64309f4e8b190e440307a4da29b47753cf794416..997ea2a3d53f144269efaccd6999b90870184596 100644 (file)
@@ -10,6 +10,7 @@
 
 #include <linux/netdevice.h>
 #include <linux/ethtool.h>
+#include <linux/mdio.h>
 #include <linux/rtnetlink.h>
 #include "net_driver.h"
 #include "workarounds.h"
@@ -345,8 +346,8 @@ static int efx_ethtool_fill_self_tests(struct efx_nic *efx,
        unsigned int n = 0, i;
        enum efx_loopback_mode mode;
 
-       efx_fill_test(n++, strings, data, &tests->mii,
-                     "core", 0, "mii", NULL);
+       efx_fill_test(n++, strings, data, &tests->mdio,
+                     "core", 0, "mdio", NULL);
        efx_fill_test(n++, strings, data, &tests->nvram,
                      "core", 0, "nvram", NULL);
        efx_fill_test(n++, strings, data, &tests->interrupt,
@@ -529,14 +530,7 @@ static int efx_ethtool_nway_reset(struct net_device *net_dev)
 {
        struct efx_nic *efx = netdev_priv(net_dev);
 
-       if (efx->phy_op->mmds & DEV_PRESENT_BIT(MDIO_MMD_AN)) {
-               mdio_clause45_set_flag(efx, efx->mii.phy_id, MDIO_MMD_AN,
-                                      MDIO_MMDREG_CTRL1,
-                                      __ffs(BMCR_ANRESTART), true);
-               return 0;
-       }
-
-       return -EOPNOTSUPP;
+       return mdio45_nway_restart(&efx->mdio);
 }
 
 static u32 efx_ethtool_get_link(struct net_device *net_dev)
@@ -689,7 +683,7 @@ static int efx_ethtool_set_pauseparam(struct net_device *net_dev,
                return -EINVAL;
        }
 
-       if (!(efx->phy_op->mmds & DEV_PRESENT_BIT(MDIO_MMD_AN)) &&
+       if (!(efx->phy_op->mmds & MDIO_DEVS_AN) &&
            (wanted_fc & EFX_FC_AUTO)) {
                EFX_LOG(efx, "PHY does not support flow control "
                        "autonegotiation\n");
@@ -717,7 +711,8 @@ static int efx_ethtool_set_pauseparam(struct net_device *net_dev,
        mutex_lock(&efx->mac_lock);
 
        efx->wanted_fc = wanted_fc;
-       mdio_clause45_set_pause(efx);
+       if (efx->phy_op->mmds & MDIO_DEVS_AN)
+               mdio45_ethtool_spauseparam_an(&efx->mdio, pause);
        __efx_reconfigure_port(efx);
 
        mutex_unlock(&efx->mac_lock);
index 466a8abb005379d2698b48093e4ed6ab6f0378cd..c049364aec46356d271ce6f52fe1ec36555d61ad 100644 (file)
@@ -2063,26 +2063,6 @@ int falcon_dma_stats(struct efx_nic *efx, unsigned int done_offset)
  **************************************************************************
  */
 
-/* Use the top bit of the MII PHY id to indicate the PHY type
- * (1G/10G), with the remaining bits as the actual PHY id.
- *
- * This allows us to avoid leaking information from the mii_if_info
- * structure into other data structures.
- */
-#define FALCON_PHY_ID_ID_WIDTH  EFX_WIDTH(MD_PRT_DEV_ADR)
-#define FALCON_PHY_ID_ID_MASK   ((1 << FALCON_PHY_ID_ID_WIDTH) - 1)
-#define FALCON_PHY_ID_WIDTH     (FALCON_PHY_ID_ID_WIDTH + 1)
-#define FALCON_PHY_ID_MASK      ((1 << FALCON_PHY_ID_WIDTH) - 1)
-#define FALCON_PHY_ID_10G       (1 << (FALCON_PHY_ID_WIDTH - 1))
-
-
-/* Packing the clause 45 port and device fields into a single value */
-#define MD_PRT_ADR_COMP_LBN   (MD_PRT_ADR_LBN - MD_DEV_ADR_LBN)
-#define MD_PRT_ADR_COMP_WIDTH  MD_PRT_ADR_WIDTH
-#define MD_DEV_ADR_COMP_LBN    0
-#define MD_DEV_ADR_COMP_WIDTH  MD_DEV_ADR_WIDTH
-
-
 /* Wait for GMII access to complete */
 static int falcon_gmii_wait(struct efx_nic *efx)
 {
@@ -2108,49 +2088,29 @@ static int falcon_gmii_wait(struct efx_nic *efx)
        return -ETIMEDOUT;
 }
 
-/* Writes a GMII register of a PHY connected to Falcon using MDIO. */
-static void falcon_mdio_write(struct net_device *net_dev, int phy_id,
-                             int addr, int value)
+/* Write an MDIO register of a PHY connected to Falcon. */
+static int falcon_mdio_write(struct net_device *net_dev,
+                            int prtad, int devad, u16 addr, u16 value)
 {
        struct efx_nic *efx = netdev_priv(net_dev);
-       unsigned int phy_id2 = phy_id & FALCON_PHY_ID_ID_MASK;
        efx_oword_t reg;
+       int rc;
 
-       /* The 'generic' prt/dev packing in mdio_10g.h is conveniently
-        * chosen so that the only current user, Falcon, can take the
-        * packed value and use them directly.
-        * Fail to build if this assumption is broken.
-        */
-       BUILD_BUG_ON(FALCON_PHY_ID_10G != MDIO45_XPRT_ID_IS10G);
-       BUILD_BUG_ON(FALCON_PHY_ID_ID_WIDTH != MDIO45_PRT_DEV_WIDTH);
-       BUILD_BUG_ON(MD_PRT_ADR_COMP_LBN != MDIO45_PRT_ID_COMP_LBN);
-       BUILD_BUG_ON(MD_DEV_ADR_COMP_LBN != MDIO45_DEV_ID_COMP_LBN);
-
-       if (phy_id2 == PHY_ADDR_INVALID)
-               return;
-
-       /* See falcon_mdio_read for an explanation. */
-       if (!(phy_id & FALCON_PHY_ID_10G)) {
-               int mmd = ffs(efx->phy_op->mmds) - 1;
-               EFX_TRACE(efx, "Fixing erroneous clause22 write\n");
-               phy_id2 = mdio_clause45_pack(phy_id2, mmd)
-                       & FALCON_PHY_ID_ID_MASK;
-       }
-
-       EFX_REGDUMP(efx, "writing GMII %d register %02x with %04x\n", phy_id,
-                   addr, value);
+       EFX_REGDUMP(efx, "writing MDIO %d register %d.%d with 0x%04x\n",
+                   prtad, devad, addr, value);
 
        spin_lock_bh(&efx->phy_lock);
 
-       /* Check MII not currently being accessed */
-       if (falcon_gmii_wait(efx) != 0)
+       /* Check MDIO not currently being accessed */
+       rc = falcon_gmii_wait(efx);
+       if (rc)
                goto out;
 
        /* Write the address/ID register */
        EFX_POPULATE_OWORD_1(reg, MD_PHY_ADR, addr);
        falcon_write(efx, &reg, MD_PHY_ADR_REG_KER);
 
-       EFX_POPULATE_OWORD_1(reg, MD_PRT_DEV_ADR, phy_id2);
+       EFX_POPULATE_OWORD_2(reg, MD_PRT_ADR, prtad, MD_DEV_ADR, devad);
        falcon_write(efx, &reg, MD_ID_REG_KER);
 
        /* Write data */
@@ -2163,7 +2123,8 @@ static void falcon_mdio_write(struct net_device *net_dev, int phy_id,
        falcon_write(efx, &reg, MD_CS_REG_KER);
 
        /* Wait for data to be written */
-       if (falcon_gmii_wait(efx) != 0) {
+       rc = falcon_gmii_wait(efx);
+       if (rc) {
                /* Abort the write operation */
                EFX_POPULATE_OWORD_2(reg,
                                     MD_WRC, 0,
@@ -2174,45 +2135,28 @@ static void falcon_mdio_write(struct net_device *net_dev, int phy_id,
 
  out:
        spin_unlock_bh(&efx->phy_lock);
+       return rc;
 }
 
-/* Reads a GMII register from a PHY connected to Falcon.  If no value
- * could be read, -1 will be returned. */
-static int falcon_mdio_read(struct net_device *net_dev, int phy_id, int addr)
+/* Read an MDIO register of a PHY connected to Falcon. */
+static int falcon_mdio_read(struct net_device *net_dev,
+                           int prtad, int devad, u16 addr)
 {
        struct efx_nic *efx = netdev_priv(net_dev);
-       unsigned int phy_addr = phy_id & FALCON_PHY_ID_ID_MASK;
        efx_oword_t reg;
-       int value = -1;
-
-       if (phy_addr == PHY_ADDR_INVALID)
-               return -1;
-
-       /* Our PHY code knows whether it needs to talk clause 22(1G) or 45(10G)
-        * but the generic Linux code does not make any distinction or have
-        * any state for this.
-        * We spot the case where someone tried to talk 22 to a 45 PHY and
-        * redirect the request to the lowest numbered MMD as a clause45
-        * request. This is enough to allow simple queries like id and link
-        * state to succeed. TODO: We may need to do more in future.
-        */
-       if (!(phy_id & FALCON_PHY_ID_10G)) {
-               int mmd = ffs(efx->phy_op->mmds) - 1;
-               EFX_TRACE(efx, "Fixing erroneous clause22 read\n");
-               phy_addr = mdio_clause45_pack(phy_addr, mmd)
-                       & FALCON_PHY_ID_ID_MASK;
-       }
+       int rc;
 
        spin_lock_bh(&efx->phy_lock);
 
-       /* Check MII not currently being accessed */
-       if (falcon_gmii_wait(efx) != 0)
+       /* Check MDIO not currently being accessed */
+       rc = falcon_gmii_wait(efx);
+       if (rc)
                goto out;
 
        EFX_POPULATE_OWORD_1(reg, MD_PHY_ADR, addr);
        falcon_write(efx, &reg, MD_PHY_ADR_REG_KER);
 
-       EFX_POPULATE_OWORD_1(reg, MD_PRT_DEV_ADR, phy_addr);
+       EFX_POPULATE_OWORD_2(reg, MD_PRT_ADR, prtad, MD_DEV_ADR, devad);
        falcon_write(efx, &reg, MD_ID_REG_KER);
 
        /* Request data to be read */
@@ -2220,12 +2164,12 @@ static int falcon_mdio_read(struct net_device *net_dev, int phy_id, int addr)
        falcon_write(efx, &reg, MD_CS_REG_KER);
 
        /* Wait for data to become available */
-       value = falcon_gmii_wait(efx);
-       if (value == 0) {
+       rc = falcon_gmii_wait(efx);
+       if (rc == 0) {
                falcon_read(efx, &reg, MD_RXD_REG_KER);
-               value = EFX_OWORD_FIELD(reg, MD_RXD);
-               EFX_REGDUMP(efx, "read from GMII %d register %02x, got %04x\n",
-                           phy_id, addr, value);
+               rc = EFX_OWORD_FIELD(reg, MD_RXD);
+               EFX_REGDUMP(efx, "read from MDIO %d register %d.%d, got %04x\n",
+                           prtad, devad, addr, rc);
        } else {
                /* Abort the read operation */
                EFX_POPULATE_OWORD_2(reg,
@@ -2233,22 +2177,13 @@ static int falcon_mdio_read(struct net_device *net_dev, int phy_id, int addr)
                                     MD_GC, 1);
                falcon_write(efx, &reg, MD_CS_REG_KER);
 
-               EFX_LOG(efx, "read from GMII 0x%x register %02x, got "
-                       "error %d\n", phy_id, addr, value);
+               EFX_LOG(efx, "read from MDIO %d register %d.%d, got error %d\n",
+                       prtad, devad, addr, rc);
        }
 
  out:
        spin_unlock_bh(&efx->phy_lock);
-
-       return value;
-}
-
-static void falcon_init_mdio(struct mii_if_info *gmii)
-{
-       gmii->mdio_read = falcon_mdio_read;
-       gmii->mdio_write = falcon_mdio_write;
-       gmii->phy_id_mask = FALCON_PHY_ID_MASK;
-       gmii->reg_num_mask = ((1 << EFX_WIDTH(MD_PHY_ADR)) - 1);
+       return rc;
 }
 
 static int falcon_probe_phy(struct efx_nic *efx)
@@ -2342,9 +2277,11 @@ int falcon_probe_port(struct efx_nic *efx)
        if (rc)
                return rc;
 
-       /* Set up GMII structure for PHY */
-       efx->mii.supports_gmii = true;
-       falcon_init_mdio(&efx->mii);
+       /* Set up MDIO structure for PHY */
+       efx->mdio.mmds = efx->phy_op->mmds;
+       efx->mdio.mode_support = MDIO_SUPPORTS_C45 | MDIO_EMULATE_C22;
+       efx->mdio.mdio_read = falcon_mdio_read;
+       efx->mdio.mdio_write = falcon_mdio_write;
 
        /* Hardware flow ctrl. FalconA RX FIFO too small for pause generation */
        if (falcon_rev(efx) >= FALCON_REV_B0)
@@ -2761,7 +2698,7 @@ static int falcon_probe_nvconfig(struct efx_nic *efx)
        if (rc == -EINVAL) {
                EFX_ERR(efx, "NVRAM is invalid therefore using defaults\n");
                efx->phy_type = PHY_TYPE_NONE;
-               efx->mii.phy_id = PHY_ADDR_INVALID;
+               efx->mdio.prtad = MDIO_PRTAD_NONE;
                board_rev = 0;
                rc = 0;
        } else if (rc) {
@@ -2771,7 +2708,7 @@ static int falcon_probe_nvconfig(struct efx_nic *efx)
                struct falcon_nvconfig_board_v3 *v3 = &nvconfig->board_v3;
 
                efx->phy_type = v2->port0_phy_type;
-               efx->mii.phy_id = v2->port0_phy_addr;
+               efx->mdio.prtad = v2->port0_phy_addr;
                board_rev = le16_to_cpu(v2->board_revision);
 
                if (le16_to_cpu(nvconfig->board_struct_ver) >= 3) {
@@ -2793,7 +2730,7 @@ static int falcon_probe_nvconfig(struct efx_nic *efx)
        /* Read the MAC addresses */
        memcpy(efx->mac_address, nvconfig->mac_address[0], ETH_ALEN);
 
-       EFX_LOG(efx, "PHY is %d phy_id %d\n", efx->phy_type, efx->mii.phy_id);
+       EFX_LOG(efx, "PHY is %d phy_id %d\n", efx->phy_type, efx->mdio.prtad);
 
        efx_set_board_info(efx, board_rev);
 
index bda8d5bb72e49476a26d92cb8a7692ef519814b7..375e2a5961ec6c214bcc270389ef66da59a7be8d 100644 (file)
 #define MD_PRT_ADR_WIDTH 5
 #define MD_DEV_ADR_LBN 6
 #define MD_DEV_ADR_WIDTH 5
-/* Used for writing both at once */
-#define MD_PRT_DEV_ADR_LBN 6
-#define MD_PRT_DEV_ADR_WIDTH 10
 
 /* PHY management status & mask register (DWORD read only) */
 #define MD_STAT_REG_KER 0xc50
index 5a03713685acda98fe958ad5c1f50e7d93a8d3dc..2b3269c03263e1b93231af89b97a52e818e94a06 100644 (file)
@@ -133,7 +133,7 @@ bool falcon_xaui_link_ok(struct efx_nic *efx)
        /* If the link is up, then check the phy side of the xaui link */
        if (efx->link_up && link_ok)
                if (efx->phy_op->mmds & (1 << MDIO_MMD_PHYXS))
-                       link_ok = mdio_clause45_phyxgxs_lane_sync(efx);
+                       link_ok = efx_mdio_phyxgxs_lane_sync(efx);
 
        return link_ok;
 }
index 9f5ec3eb3418c4b797b6a1a626af87b1addcd66b..6c33459f9ea9ddbd4c0938284f341ff1657b1812 100644 (file)
@@ -17,7 +17,7 @@
 #include "boards.h"
 #include "workarounds.h"
 
-unsigned mdio_id_oui(u32 id)
+unsigned efx_mdio_id_oui(u32 id)
 {
        unsigned oui = 0;
        int i;
@@ -32,52 +32,45 @@ unsigned mdio_id_oui(u32 id)
        return oui;
 }
 
-int mdio_clause45_reset_mmd(struct efx_nic *port, int mmd,
+int efx_mdio_reset_mmd(struct efx_nic *port, int mmd,
                            int spins, int spintime)
 {
        u32 ctrl;
-       int phy_id = port->mii.phy_id;
 
        /* Catch callers passing values in the wrong units (or just silly) */
        EFX_BUG_ON_PARANOID(spins * spintime >= 5000);
 
-       mdio_clause45_write(port, phy_id, mmd, MDIO_MMDREG_CTRL1,
-                           (1 << MDIO_MMDREG_CTRL1_RESET_LBN));
+       efx_mdio_write(port, mmd, MDIO_CTRL1, MDIO_CTRL1_RESET);
        /* Wait for the reset bit to clear. */
        do {
                msleep(spintime);
-               ctrl = mdio_clause45_read(port, phy_id, mmd, MDIO_MMDREG_CTRL1);
+               ctrl = efx_mdio_read(port, mmd, MDIO_CTRL1);
                spins--;
 
-       } while (spins && (ctrl & (1 << MDIO_MMDREG_CTRL1_RESET_LBN)));
+       } while (spins && (ctrl & MDIO_CTRL1_RESET));
 
        return spins ? spins : -ETIMEDOUT;
 }
 
-static int mdio_clause45_check_mmd(struct efx_nic *efx, int mmd,
-                                  int fault_fatal)
+static int efx_mdio_check_mmd(struct efx_nic *efx, int mmd, int fault_fatal)
 {
        int status;
-       int phy_id = efx->mii.phy_id;
 
        if (LOOPBACK_INTERNAL(efx))
                return 0;
 
        if (mmd != MDIO_MMD_AN) {
                /* Read MMD STATUS2 to check it is responding. */
-               status = mdio_clause45_read(efx, phy_id, mmd,
-                                           MDIO_MMDREG_STAT2);
-               if (((status >> MDIO_MMDREG_STAT2_PRESENT_LBN) &
-                    ((1 << MDIO_MMDREG_STAT2_PRESENT_WIDTH) - 1)) !=
-                   MDIO_MMDREG_STAT2_PRESENT_VAL) {
+               status = efx_mdio_read(efx, mmd, MDIO_STAT2);
+               if ((status & MDIO_STAT2_DEVPRST) != MDIO_STAT2_DEVPRST_VAL) {
                        EFX_ERR(efx, "PHY MMD %d not responding.\n", mmd);
                        return -EIO;
                }
        }
 
        /* Read MMD STATUS 1 to check for fault. */
-       status = mdio_clause45_read(efx, phy_id, mmd, MDIO_MMDREG_STAT1);
-       if ((status & (1 << MDIO_MMDREG_STAT1_FAULT_LBN)) != 0) {
+       status = efx_mdio_read(efx, mmd, MDIO_STAT1);
+       if (status & MDIO_STAT1_FAULT) {
                if (fault_fatal) {
                        EFX_ERR(efx, "PHY MMD %d reporting fatal"
                                " fault: status %x\n", mmd, status);
@@ -94,8 +87,7 @@ static int mdio_clause45_check_mmd(struct efx_nic *efx, int mmd,
 #define MDIO45_RESET_TIME      1000 /* ms */
 #define MDIO45_RESET_ITERS     100
 
-int mdio_clause45_wait_reset_mmds(struct efx_nic *efx,
-                                 unsigned int mmd_mask)
+int efx_mdio_wait_reset_mmds(struct efx_nic *efx, unsigned int mmd_mask)
 {
        const int spintime = MDIO45_RESET_TIME / MDIO45_RESET_ITERS;
        int tries = MDIO45_RESET_ITERS;
@@ -109,16 +101,13 @@ int mdio_clause45_wait_reset_mmds(struct efx_nic *efx,
                in_reset = 0;
                while (mask) {
                        if (mask & 1) {
-                               stat = mdio_clause45_read(efx,
-                                                         efx->mii.phy_id,
-                                                         mmd,
-                                                         MDIO_MMDREG_CTRL1);
+                               stat = efx_mdio_read(efx, mmd, MDIO_CTRL1);
                                if (stat < 0) {
                                        EFX_ERR(efx, "failed to read status of"
                                                " MMD %d\n", mmd);
                                        return -EIO;
                                }
-                               if (stat & (1 << MDIO_MMDREG_CTRL1_RESET_LBN))
+                               if (stat & MDIO_CTRL1_RESET)
                                        in_reset |= (1 << mmd);
                        }
                        mask = mask >> 1;
@@ -137,28 +126,26 @@ int mdio_clause45_wait_reset_mmds(struct efx_nic *efx,
        return rc;
 }
 
-int mdio_clause45_check_mmds(struct efx_nic *efx,
-                            unsigned int mmd_mask, unsigned int fatal_mask)
+int efx_mdio_check_mmds(struct efx_nic *efx,
+                       unsigned int mmd_mask, unsigned int fatal_mask)
 {
-       int mmd = 0, probe_mmd, devs0, devs1;
+       int mmd = 0, probe_mmd, devs1, devs2;
        u32 devices;
 
        /* Historically we have probed the PHYXS to find out what devices are
         * present,but that doesn't work so well if the PHYXS isn't expected
         * to exist, if so just find the first item in the list supplied. */
-       probe_mmd = (mmd_mask & MDIO_MMDREG_DEVS_PHYXS) ? MDIO_MMD_PHYXS :
+       probe_mmd = (mmd_mask & MDIO_DEVS_PHYXS) ? MDIO_MMD_PHYXS :
            __ffs(mmd_mask);
 
        /* Check all the expected MMDs are present */
-       devs0 = mdio_clause45_read(efx, efx->mii.phy_id,
-                                  probe_mmd, MDIO_MMDREG_DEVS0);
-       devs1 = mdio_clause45_read(efx, efx->mii.phy_id,
-                                  probe_mmd, MDIO_MMDREG_DEVS1);
-       if (devs0 < 0 || devs1 < 0) {
+       devs1 = efx_mdio_read(efx, probe_mmd, MDIO_DEVS1);
+       devs2 = efx_mdio_read(efx, probe_mmd, MDIO_DEVS2);
+       if (devs1 < 0 || devs2 < 0) {
                EFX_ERR(efx, "failed to read devices present\n");
                return -EIO;
        }
-       devices = devs0 | (devs1 << 16);
+       devices = devs1 | (devs2 << 16);
        if ((devices & mmd_mask) != mmd_mask) {
                EFX_ERR(efx, "required MMDs not present: got %x, "
                        "wanted %x\n", devices, mmd_mask);
@@ -170,7 +157,7 @@ int mdio_clause45_check_mmds(struct efx_nic *efx,
        while (mmd_mask) {
                if (mmd_mask & 1) {
                        int fault_fatal = fatal_mask & 1;
-                       if (mdio_clause45_check_mmd(efx, mmd, fault_fatal))
+                       if (efx_mdio_check_mmd(efx, mmd, fault_fatal))
                                return -EIO;
                }
                mmd_mask = mmd_mask >> 1;
@@ -181,13 +168,8 @@ int mdio_clause45_check_mmds(struct efx_nic *efx,
        return 0;
 }
 
-bool mdio_clause45_links_ok(struct efx_nic *efx, unsigned int mmd_mask)
+bool efx_mdio_links_ok(struct efx_nic *efx, unsigned int mmd_mask)
 {
-       int phy_id = efx->mii.phy_id;
-       u32 reg;
-       bool ok = true;
-       int mmd = 0;
-
        /* If the port is in loopback, then we should only consider a subset
         * of mmd's */
        if (LOOPBACK_INTERNAL(efx))
@@ -197,241 +179,75 @@ bool mdio_clause45_links_ok(struct efx_nic *efx, unsigned int mmd_mask)
        else if (efx_phy_mode_disabled(efx->phy_mode))
                return false;
        else if (efx->loopback_mode == LOOPBACK_PHYXS)
-               mmd_mask &= ~(MDIO_MMDREG_DEVS_PHYXS |
-                             MDIO_MMDREG_DEVS_PCS |
-                             MDIO_MMDREG_DEVS_PMAPMD |
-                             MDIO_MMDREG_DEVS_AN);
+               mmd_mask &= ~(MDIO_DEVS_PHYXS |
+                             MDIO_DEVS_PCS |
+                             MDIO_DEVS_PMAPMD |
+                             MDIO_DEVS_AN);
        else if (efx->loopback_mode == LOOPBACK_PCS)
-               mmd_mask &= ~(MDIO_MMDREG_DEVS_PCS |
-                             MDIO_MMDREG_DEVS_PMAPMD |
-                             MDIO_MMDREG_DEVS_AN);
+               mmd_mask &= ~(MDIO_DEVS_PCS |
+                             MDIO_DEVS_PMAPMD |
+                             MDIO_DEVS_AN);
        else if (efx->loopback_mode == LOOPBACK_PMAPMD)
-               mmd_mask &= ~(MDIO_MMDREG_DEVS_PMAPMD |
-                             MDIO_MMDREG_DEVS_AN);
-
-       if (!mmd_mask) {
-               /* Use presence of XGMII faults in leui of link state */
-               reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PHYXS,
-                                        MDIO_PHYXS_STATUS2);
-               return !(reg & (1 << MDIO_PHYXS_STATUS2_RX_FAULT_LBN));
-       }
+               mmd_mask &= ~(MDIO_DEVS_PMAPMD |
+                             MDIO_DEVS_AN);
 
-       while (mmd_mask) {
-               if (mmd_mask & 1) {
-                       /* Double reads because link state is latched, and a
-                        * read moves the current state into the register */
-                       reg = mdio_clause45_read(efx, phy_id,
-                                                mmd, MDIO_MMDREG_STAT1);
-                       reg = mdio_clause45_read(efx, phy_id,
-                                                mmd, MDIO_MMDREG_STAT1);
-                       ok = ok && (reg & (1 << MDIO_MMDREG_STAT1_LINK_LBN));
-               }
-               mmd_mask = (mmd_mask >> 1);
-               mmd++;
-       }
-       return ok;
+       return mdio45_links_ok(&efx->mdio, mmd_mask);
 }
 
-void mdio_clause45_transmit_disable(struct efx_nic *efx)
+void efx_mdio_transmit_disable(struct efx_nic *efx)
 {
-       mdio_clause45_set_flag(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD,
-                              MDIO_MMDREG_TXDIS, MDIO_MMDREG_TXDIS_GLOBAL_LBN,
-                              efx->phy_mode & PHY_MODE_TX_DISABLED);
+       efx_mdio_set_flag(efx, MDIO_MMD_PMAPMD,
+                         MDIO_PMA_TXDIS, MDIO_PMD_TXDIS_GLOBAL,
+                         efx->phy_mode & PHY_MODE_TX_DISABLED);
 }
 
-void mdio_clause45_phy_reconfigure(struct efx_nic *efx)
+void efx_mdio_phy_reconfigure(struct efx_nic *efx)
 {
-       int phy_id = efx->mii.phy_id;
-
-       mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_PMAPMD,
-                              MDIO_MMDREG_CTRL1, MDIO_PMAPMD_CTRL1_LBACK_LBN,
-                              efx->loopback_mode == LOOPBACK_PMAPMD);
-       mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_PCS,
-                              MDIO_MMDREG_CTRL1, MDIO_MMDREG_CTRL1_LBACK_LBN,
-                              efx->loopback_mode == LOOPBACK_PCS);
-       mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_PHYXS,
-                              MDIO_MMDREG_CTRL1, MDIO_MMDREG_CTRL1_LBACK_LBN,
-                              efx->loopback_mode == LOOPBACK_NETWORK);
+       efx_mdio_set_flag(efx, MDIO_MMD_PMAPMD,
+                         MDIO_CTRL1, MDIO_PMA_CTRL1_LOOPBACK,
+                         efx->loopback_mode == LOOPBACK_PMAPMD);
+       efx_mdio_set_flag(efx, MDIO_MMD_PCS,
+                         MDIO_CTRL1, MDIO_PCS_CTRL1_LOOPBACK,
+                         efx->loopback_mode == LOOPBACK_PCS);
+       efx_mdio_set_flag(efx, MDIO_MMD_PHYXS,
+                         MDIO_CTRL1, MDIO_PHYXS_CTRL1_LOOPBACK,
+                         efx->loopback_mode == LOOPBACK_NETWORK);
 }
 
-static void mdio_clause45_set_mmd_lpower(struct efx_nic *efx,
-                                        int lpower, int mmd)
+static void efx_mdio_set_mmd_lpower(struct efx_nic *efx,
+                                   int lpower, int mmd)
 {
-       int phy = efx->mii.phy_id;
-       int stat = mdio_clause45_read(efx, phy, mmd, MDIO_MMDREG_STAT1);
+       int stat = efx_mdio_read(efx, mmd, MDIO_STAT1);
 
        EFX_TRACE(efx, "Setting low power mode for MMD %d to %d\n",
                  mmd, lpower);
 
-       if (stat & (1 << MDIO_MMDREG_STAT1_LPABLE_LBN)) {
-               mdio_clause45_set_flag(efx, phy, mmd, MDIO_MMDREG_CTRL1,
-                                      MDIO_MMDREG_CTRL1_LPOWER_LBN, lpower);
+       if (stat & MDIO_STAT1_LPOWERABLE) {
+               efx_mdio_set_flag(efx, mmd, MDIO_CTRL1,
+                                 MDIO_CTRL1_LPOWER, lpower);
        }
 }
 
-void mdio_clause45_set_mmds_lpower(struct efx_nic *efx,
-                                  int low_power, unsigned int mmd_mask)
+void efx_mdio_set_mmds_lpower(struct efx_nic *efx,
+                             int low_power, unsigned int mmd_mask)
 {
        int mmd = 0;
-       mmd_mask &= ~MDIO_MMDREG_DEVS_AN;
+       mmd_mask &= ~MDIO_DEVS_AN;
        while (mmd_mask) {
                if (mmd_mask & 1)
-                       mdio_clause45_set_mmd_lpower(efx, low_power, mmd);
+                       efx_mdio_set_mmd_lpower(efx, low_power, mmd);
                mmd_mask = (mmd_mask >> 1);
                mmd++;
        }
 }
 
-static u32 mdio_clause45_get_an(struct efx_nic *efx, u16 addr)
-{
-       int phy_id = efx->mii.phy_id;
-       u32 result = 0;
-       int reg;
-
-       reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN, addr);
-       if (reg & ADVERTISE_10HALF)
-               result |= ADVERTISED_10baseT_Half;
-       if (reg & ADVERTISE_10FULL)
-               result |= ADVERTISED_10baseT_Full;
-       if (reg & ADVERTISE_100HALF)
-               result |= ADVERTISED_100baseT_Half;
-       if (reg & ADVERTISE_100FULL)
-               result |= ADVERTISED_100baseT_Full;
-       return result;
-}
-
-/**
- * mdio_clause45_get_settings - Read (some of) the PHY settings over MDIO.
- * @efx:               Efx NIC
- * @ecmd:              Buffer for settings
- *
- * On return the 'port', 'speed', 'supported' and 'advertising' fields of
- * ecmd have been filled out.
- */
-void mdio_clause45_get_settings(struct efx_nic *efx,
-                               struct ethtool_cmd *ecmd)
-{
-       mdio_clause45_get_settings_ext(efx, ecmd, 0, 0);
-}
-
-/**
- * mdio_clause45_get_settings_ext - Read (some of) the PHY settings over MDIO.
- * @efx:               Efx NIC
- * @ecmd:              Buffer for settings
- * @xnp:               Advertised Extended Next Page state
- * @xnp_lpa:           Link Partner's advertised XNP state
- *
- * On return the 'port', 'speed', 'supported' and 'advertising' fields of
- * ecmd have been filled out.
- */
-void mdio_clause45_get_settings_ext(struct efx_nic *efx,
-                                   struct ethtool_cmd *ecmd,
-                                   u32 npage_adv, u32 npage_lpa)
-{
-       int phy_id = efx->mii.phy_id;
-       int reg;
-
-       ecmd->transceiver = XCVR_INTERNAL;
-       ecmd->phy_address = phy_id;
-
-       reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
-                                MDIO_MMDREG_CTRL2);
-       switch (reg & MDIO_PMAPMD_CTRL2_TYPE_MASK) {
-       case MDIO_PMAPMD_CTRL2_10G_BT:
-       case MDIO_PMAPMD_CTRL2_1G_BT:
-       case MDIO_PMAPMD_CTRL2_100_BT:
-       case MDIO_PMAPMD_CTRL2_10_BT:
-               ecmd->port = PORT_TP;
-               ecmd->supported = SUPPORTED_TP;
-               reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
-                                        MDIO_MMDREG_SPEED);
-               if (reg & (1 << MDIO_MMDREG_SPEED_10G_LBN))
-                       ecmd->supported |= SUPPORTED_10000baseT_Full;
-               if (reg & (1 << MDIO_MMDREG_SPEED_1000M_LBN))
-                       ecmd->supported |= (SUPPORTED_1000baseT_Full |
-                                           SUPPORTED_1000baseT_Half);
-               if (reg & (1 << MDIO_MMDREG_SPEED_100M_LBN))
-                       ecmd->supported |= (SUPPORTED_100baseT_Full |
-                                           SUPPORTED_100baseT_Half);
-               if (reg & (1 << MDIO_MMDREG_SPEED_10M_LBN))
-                       ecmd->supported |= (SUPPORTED_10baseT_Full |
-                                           SUPPORTED_10baseT_Half);
-               ecmd->advertising = ADVERTISED_TP;
-               break;
-
-       /* We represent CX4 as fibre in the absence of anything better */
-       case MDIO_PMAPMD_CTRL2_10G_CX4:
-       /* All the other defined modes are flavours of optical */
-       default:
-               ecmd->port = PORT_FIBRE;
-               ecmd->supported = SUPPORTED_FIBRE;
-               ecmd->advertising = ADVERTISED_FIBRE;
-               break;
-       }
-
-       if (efx->phy_op->mmds & DEV_PRESENT_BIT(MDIO_MMD_AN)) {
-               ecmd->supported |= SUPPORTED_Autoneg;
-               reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
-                                        MDIO_MMDREG_CTRL1);
-               if (reg & BMCR_ANENABLE) {
-                       ecmd->autoneg = AUTONEG_ENABLE;
-                       ecmd->advertising |=
-                               ADVERTISED_Autoneg |
-                               mdio_clause45_get_an(efx, MDIO_AN_ADVERTISE) |
-                               npage_adv;
-               } else
-                       ecmd->autoneg = AUTONEG_DISABLE;
-       } else
-               ecmd->autoneg = AUTONEG_DISABLE;
-
-       if (ecmd->autoneg) {
-               /* If AN is complete, report best common mode,
-                * otherwise report best advertised mode. */
-               u32 modes = 0;
-               if (mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
-                                      MDIO_MMDREG_STAT1) &
-                   (1 << MDIO_AN_STATUS_AN_DONE_LBN))
-                       modes = (ecmd->advertising &
-                                (mdio_clause45_get_an(efx, MDIO_AN_LPA) |
-                                 npage_lpa));
-               if (modes == 0)
-                       modes = ecmd->advertising;
-
-               if (modes & ADVERTISED_10000baseT_Full) {
-                       ecmd->speed = SPEED_10000;
-                       ecmd->duplex = DUPLEX_FULL;
-               } else if (modes & (ADVERTISED_1000baseT_Full |
-                                   ADVERTISED_1000baseT_Half)) {
-                       ecmd->speed = SPEED_1000;
-                       ecmd->duplex = !!(modes & ADVERTISED_1000baseT_Full);
-               } else if (modes & (ADVERTISED_100baseT_Full |
-                                   ADVERTISED_100baseT_Half)) {
-                       ecmd->speed = SPEED_100;
-                       ecmd->duplex = !!(modes & ADVERTISED_100baseT_Full);
-               } else {
-                       ecmd->speed = SPEED_10;
-                       ecmd->duplex = !!(modes & ADVERTISED_10baseT_Full);
-               }
-       } else {
-               /* Report forced settings */
-               reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
-                                        MDIO_MMDREG_CTRL1);
-               ecmd->speed = (((reg & BMCR_SPEED1000) ? 100 : 1) *
-                              ((reg & BMCR_SPEED100) ? 100 : 10));
-               ecmd->duplex = (reg & BMCR_FULLDPLX ||
-                               ecmd->speed == SPEED_10000);
-       }
-}
-
 /**
- * mdio_clause45_set_settings - Set (some of) the PHY settings over MDIO.
+ * efx_mdio_set_settings - Set (some of) the PHY settings over MDIO.
  * @efx:               Efx NIC
  * @ecmd:              New settings
  */
-int mdio_clause45_set_settings(struct efx_nic *efx,
-                              struct ethtool_cmd *ecmd)
+int efx_mdio_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
 {
-       int phy_id = efx->mii.phy_id;
        struct ethtool_cmd prev;
        u32 required;
        int reg;
@@ -488,95 +304,48 @@ int mdio_clause45_set_settings(struct efx_nic *efx,
                else if (ecmd->advertising & (ADVERTISED_1000baseT_Half |
                                              ADVERTISED_1000baseT_Full))
                        reg |= ADVERTISE_NPAGE;
-               reg |= efx_fc_advertise(efx->wanted_fc);
-               mdio_clause45_write(efx, phy_id, MDIO_MMD_AN,
-                                   MDIO_AN_ADVERTISE, reg);
+               reg |= mii_advertise_flowctrl(efx->wanted_fc);
+               efx_mdio_write(efx, MDIO_MMD_AN, MDIO_AN_ADVERTISE, reg);
 
                /* Set up the (extended) next page if necessary */
                if (efx->phy_op->set_npage_adv)
                        efx->phy_op->set_npage_adv(efx, ecmd->advertising);
 
                /* Enable and restart AN */
-               reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
-                                        MDIO_MMDREG_CTRL1);
-               reg |= BMCR_ANENABLE;
+               reg = efx_mdio_read(efx, MDIO_MMD_AN, MDIO_CTRL1);
+               reg |= MDIO_AN_CTRL1_ENABLE;
                if (!(EFX_WORKAROUND_15195(efx) &&
                      LOOPBACK_MASK(efx) & efx->phy_op->loopbacks))
-                       reg |= BMCR_ANRESTART;
+                       reg |= MDIO_AN_CTRL1_RESTART;
                if (xnp)
-                       reg |= 1 << MDIO_AN_CTRL_XNP_LBN;
+                       reg |= MDIO_AN_CTRL1_XNP;
                else
-                       reg &= ~(1 << MDIO_AN_CTRL_XNP_LBN);
-               mdio_clause45_write(efx, phy_id, MDIO_MMD_AN,
-                                   MDIO_MMDREG_CTRL1, reg);
+                       reg &= ~MDIO_AN_CTRL1_XNP;
+               efx_mdio_write(efx, MDIO_MMD_AN, MDIO_CTRL1, reg);
        } else {
                /* Disable AN */
-               mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_AN,
-                                      MDIO_MMDREG_CTRL1,
-                                      __ffs(BMCR_ANENABLE), false);
+               efx_mdio_set_flag(efx, MDIO_MMD_AN, MDIO_CTRL1,
+                                 MDIO_AN_CTRL1_ENABLE, false);
 
                /* Set the basic control bits */
-               reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
-                                        MDIO_MMDREG_CTRL1);
-               reg &= ~(BMCR_SPEED1000 | BMCR_SPEED100 | BMCR_FULLDPLX |
-                        0x003c);
+               reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD, MDIO_CTRL1);
+               reg &= ~(MDIO_CTRL1_SPEEDSEL | MDIO_CTRL1_FULLDPLX);
                if (ecmd->speed == SPEED_100)
-                       reg |= BMCR_SPEED100;
+                       reg |= MDIO_PMA_CTRL1_SPEED100;
                if (ecmd->duplex)
-                       reg |= BMCR_FULLDPLX;
-               mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD,
-                                   MDIO_MMDREG_CTRL1, reg);
+                       reg |= MDIO_CTRL1_FULLDPLX;
+               efx_mdio_write(efx, MDIO_MMD_PMAPMD, MDIO_CTRL1, reg);
        }
 
        return 0;
 }
 
-void mdio_clause45_set_pause(struct efx_nic *efx)
-{
-       int phy_id = efx->mii.phy_id;
-       int reg;
-
-       if (efx->phy_op->mmds & DEV_PRESENT_BIT(MDIO_MMD_AN)) {
-               /* Set pause capability advertising */
-               reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
-                                        MDIO_AN_ADVERTISE);
-               reg &= ~(ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM);
-               reg |= efx_fc_advertise(efx->wanted_fc);
-               mdio_clause45_write(efx, phy_id, MDIO_MMD_AN,
-                                   MDIO_AN_ADVERTISE, reg);
-
-               /* Restart auto-negotiation */
-               reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
-                                        MDIO_MMDREG_CTRL1);
-               if (reg & BMCR_ANENABLE) {
-                       reg |= BMCR_ANRESTART;
-                       mdio_clause45_write(efx, phy_id, MDIO_MMD_AN,
-                                           MDIO_MMDREG_CTRL1, reg);
-               }
-       }
-}
-
-enum efx_fc_type mdio_clause45_get_pause(struct efx_nic *efx)
+enum efx_fc_type efx_mdio_get_pause(struct efx_nic *efx)
 {
-       int phy_id = efx->mii.phy_id;
        int lpa;
 
-       if (!(efx->phy_op->mmds & DEV_PRESENT_BIT(MDIO_MMD_AN)))
+       if (!(efx->phy_op->mmds & MDIO_DEVS_AN))
                return efx->wanted_fc;
-       lpa = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN, MDIO_AN_LPA);
+       lpa = efx_mdio_read(efx, MDIO_MMD_AN, MDIO_AN_LPA);
        return efx_fc_resolve(efx->wanted_fc, lpa);
 }
-
-void mdio_clause45_set_flag(struct efx_nic *efx, u8 prt, u8 dev,
-                           u16 addr, int bit, bool sense)
-{
-       int old_val = mdio_clause45_read(efx, prt, dev, addr);
-       int new_val;
-
-       if (sense)
-               new_val = old_val | (1 << bit);
-       else
-               new_val = old_val & ~(1 << bit);
-       if (old_val != new_val)
-               mdio_clause45_write(efx, prt, dev, addr, new_val);
-}
index 7014d2279c20f633977808647839681cfdfe7244..6b14421a74446ee18708cea3c02520af4e657944 100644 (file)
 #ifndef EFX_MDIO_10G_H
 #define EFX_MDIO_10G_H
 
+#include <linux/mdio.h>
+
 /*
- * Definitions needed for doing 10G MDIO as specified in clause 45
- * MDIO, which do not appear in Linux yet. Also some helper functions.
+ * Helper functions for doing 10G MDIO as specified in IEEE 802.3 clause 45.
  */
 
 #include "efx.h"
 #include "boards.h"
 
-/* Numbering of the MDIO Manageable Devices (MMDs) */
-/* Physical Medium Attachment/ Physical Medium Dependent sublayer */
-#define MDIO_MMD_PMAPMD        (1)
-/* WAN Interface Sublayer */
-#define MDIO_MMD_WIS   (2)
-/* Physical Coding Sublayer */
-#define MDIO_MMD_PCS   (3)
-/* PHY Extender Sublayer */
-#define MDIO_MMD_PHYXS (4)
-/* Extender Sublayer */
-#define MDIO_MMD_DTEXS (5)
-/* Transmission convergence */
-#define MDIO_MMD_TC    (6)
-/* Auto negotiation */
-#define MDIO_MMD_AN    (7)
-/* Clause 22 extension */
-#define MDIO_MMD_C22EXT        29
-
-/* Generic register locations */
-#define MDIO_MMDREG_CTRL1      (0)
-#define MDIO_MMDREG_STAT1      (1)
-#define MDIO_MMDREG_IDHI       (2)
-#define MDIO_MMDREG_IDLOW      (3)
-#define MDIO_MMDREG_SPEED      (4)
-#define MDIO_MMDREG_DEVS0      (5)
-#define MDIO_MMDREG_DEVS1      (6)
-#define MDIO_MMDREG_CTRL2      (7)
-#define MDIO_MMDREG_STAT2      (8)
-#define MDIO_MMDREG_TXDIS      (9)
-
-/* Bits in MMDREG_CTRL1 */
-/* Reset */
-#define MDIO_MMDREG_CTRL1_RESET_LBN    (15)
-#define MDIO_MMDREG_CTRL1_RESET_WIDTH  (1)
-/* Loopback */
-/* Loopback bit for WIS, PCS, PHYSX and DTEXS */
-#define MDIO_MMDREG_CTRL1_LBACK_LBN    (14)
-#define MDIO_MMDREG_CTRL1_LBACK_WIDTH  (1)
-/* Low power */
-#define MDIO_MMDREG_CTRL1_LPOWER_LBN   (11)
-#define MDIO_MMDREG_CTRL1_LPOWER_WIDTH (1)
-
-/* Bits in MMDREG_STAT1 */
-#define MDIO_MMDREG_STAT1_FAULT_LBN    (7)
-#define MDIO_MMDREG_STAT1_FAULT_WIDTH  (1)
-/* Link state */
-#define MDIO_MMDREG_STAT1_LINK_LBN     (2)
-#define MDIO_MMDREG_STAT1_LINK_WIDTH   (1)
-/* Low power ability */
-#define MDIO_MMDREG_STAT1_LPABLE_LBN   (1)
-#define MDIO_MMDREG_STAT1_LPABLE_WIDTH (1)
-
-/* Bits in combined ID regs */
-static inline unsigned mdio_id_rev(u32 id) { return id & 0xf; }
-static inline unsigned mdio_id_model(u32 id) { return (id >> 4) & 0x3f; }
-extern unsigned mdio_id_oui(u32 id);
-
-/* Bits in MMDREG_DEVS0/1. Someone thoughtfully layed things out
- * so the 'bit present' bit number of an MMD is the number of
- * that MMD */
-#define DEV_PRESENT_BIT(_b) (1 << _b)
-
-#define MDIO_MMDREG_DEVS_PHYXS DEV_PRESENT_BIT(MDIO_MMD_PHYXS)
-#define MDIO_MMDREG_DEVS_PCS   DEV_PRESENT_BIT(MDIO_MMD_PCS)
-#define MDIO_MMDREG_DEVS_PMAPMD        DEV_PRESENT_BIT(MDIO_MMD_PMAPMD)
-#define MDIO_MMDREG_DEVS_AN    DEV_PRESENT_BIT(MDIO_MMD_AN)
-#define MDIO_MMDREG_DEVS_C22EXT        DEV_PRESENT_BIT(MDIO_MMD_C22EXT)
-
-/* Bits in MMDREG_SPEED */
-#define MDIO_MMDREG_SPEED_10G_LBN      0
-#define MDIO_MMDREG_SPEED_10G_WIDTH    1
-#define MDIO_MMDREG_SPEED_1000M_LBN    4
-#define MDIO_MMDREG_SPEED_1000M_WIDTH  1
-#define MDIO_MMDREG_SPEED_100M_LBN     5
-#define MDIO_MMDREG_SPEED_100M_WIDTH   1
-#define MDIO_MMDREG_SPEED_10M_LBN      6
-#define MDIO_MMDREG_SPEED_10M_WIDTH    1
-
-/* Bits in MMDREG_STAT2 */
-#define MDIO_MMDREG_STAT2_PRESENT_VAL  (2)
-#define MDIO_MMDREG_STAT2_PRESENT_LBN  (14)
-#define MDIO_MMDREG_STAT2_PRESENT_WIDTH (2)
-
-/* Bits in MMDREG_TXDIS */
-#define MDIO_MMDREG_TXDIS_GLOBAL_LBN    (0)
-#define MDIO_MMDREG_TXDIS_GLOBAL_WIDTH  (1)
-
-/* MMD-specific bits, ordered by MMD, then register */
-#define MDIO_PMAPMD_CTRL1_LBACK_LBN    (0)
-#define MDIO_PMAPMD_CTRL1_LBACK_WIDTH  (1)
-
-/* PMA type (4 bits) */
-#define MDIO_PMAPMD_CTRL2_10G_CX4      (0x0)
-#define MDIO_PMAPMD_CTRL2_10G_EW       (0x1)
-#define MDIO_PMAPMD_CTRL2_10G_LW       (0x2)
-#define MDIO_PMAPMD_CTRL2_10G_SW       (0x3)
-#define MDIO_PMAPMD_CTRL2_10G_LX4      (0x4)
-#define MDIO_PMAPMD_CTRL2_10G_ER       (0x5)
-#define MDIO_PMAPMD_CTRL2_10G_LR       (0x6)
-#define MDIO_PMAPMD_CTRL2_10G_SR       (0x7)
-/* Reserved */
-#define MDIO_PMAPMD_CTRL2_10G_BT       (0x9)
-/* Reserved */
-/* Reserved */
-#define MDIO_PMAPMD_CTRL2_1G_BT                (0xc)
-/* Reserved */
-#define MDIO_PMAPMD_CTRL2_100_BT       (0xe)
-#define MDIO_PMAPMD_CTRL2_10_BT                (0xf)
-#define MDIO_PMAPMD_CTRL2_TYPE_MASK    (0xf)
-
-/* PMA 10GBT registers */
-#define MDIO_PMAPMD_10GBT_TXPWR                (131)
-#define MDIO_PMAPMD_10GBT_TXPWR_SHORT_LBN (0)
-#define MDIO_PMAPMD_10GBT_TXPWR_SHORT_WIDTH (1)
-
-/* PHY XGXS Status 2 */
-#define MDIO_PHYXS_STATUS2              (8)
-#define MDIO_PHYXS_STATUS2_RX_FAULT_LBN 10
-
-/* PHY XGXS lane state */
-#define MDIO_PHYXS_LANE_STATE          (0x18)
-#define MDIO_PHYXS_LANE_ALIGNED_LBN    (12)
-
-/* AN registers */
-#define MDIO_AN_CTRL_XNP_LBN           13
-#define MDIO_AN_STATUS                 (1)
-#define MDIO_AN_STATUS_XNP_LBN         (7)
-#define MDIO_AN_STATUS_PAGE_LBN                (6)
-#define MDIO_AN_STATUS_AN_DONE_LBN     (5)
-#define MDIO_AN_STATUS_LP_AN_CAP_LBN   (0)
-
-#define MDIO_AN_ADVERTISE              16
-#define MDIO_AN_ADVERTISE_XNP_LBN      12
-#define MDIO_AN_LPA                    19
-#define MDIO_AN_XNP                    22
-#define MDIO_AN_LPA_XNP                        25
-
-#define MDIO_AN_10GBT_CTRL             32
-#define MDIO_AN_10GBT_CTRL_ADV_10G_LBN 12
-#define MDIO_AN_10GBT_STATUS           (33)
-#define MDIO_AN_10GBT_STATUS_MS_FLT_LBN (15) /* MASTER/SLAVE config fault */
-#define MDIO_AN_10GBT_STATUS_MS_LBN     (14) /* MASTER/SLAVE config */
-#define MDIO_AN_10GBT_STATUS_LOC_OK_LBN (13) /* Local OK */
-#define MDIO_AN_10GBT_STATUS_REM_OK_LBN (12) /* Remote OK */
-#define MDIO_AN_10GBT_STATUS_LP_10G_LBN (11) /* Link partner is 10GBT capable */
-#define MDIO_AN_10GBT_STATUS_LP_LTA_LBN (10) /* LP loop timing ability */
-#define MDIO_AN_10GBT_STATUS_LP_TRR_LBN (9)  /* LP Training Reset Request */
-
+static inline unsigned efx_mdio_id_rev(u32 id) { return id & 0xf; }
+static inline unsigned efx_mdio_id_model(u32 id) { return (id >> 4) & 0x3f; }
+extern unsigned efx_mdio_id_oui(u32 id);
 
-/* Packing of the prt and dev arguments of clause 45 style MDIO into a
- * single int so they can be passed into the mdio_read/write functions
- * that currently exist. Note that as Falcon is the only current user,
- * the packed form is chosen to match what Falcon needs to write into
- * a register. This is checked at compile-time so do not change it. If
- * your target chip needs things layed out differently you will need
- * to unpack the arguments in your chip-specific mdio functions.
- */
- /* These are defined by the standard. */
-#define MDIO45_PRT_ID_WIDTH  (5)
-#define MDIO45_DEV_ID_WIDTH  (5)
-
-/* The prt ID is just packed in immediately to the left of the dev ID */
-#define MDIO45_PRT_DEV_WIDTH (MDIO45_PRT_ID_WIDTH + MDIO45_DEV_ID_WIDTH)
-
-#define MDIO45_PRT_ID_MASK   ((1 << MDIO45_PRT_DEV_WIDTH) - 1)
-/* This is the prt + dev extended by 1 bit to hold the 'is clause 45' flag. */
-#define MDIO45_XPRT_ID_WIDTH   (MDIO45_PRT_DEV_WIDTH + 1)
-#define MDIO45_XPRT_ID_MASK   ((1 << MDIO45_XPRT_ID_WIDTH) - 1)
-#define MDIO45_XPRT_ID_IS10G   (1 << (MDIO45_XPRT_ID_WIDTH - 1))
-
-
-#define MDIO45_PRT_ID_COMP_LBN   MDIO45_DEV_ID_WIDTH
-#define MDIO45_PRT_ID_COMP_WIDTH  MDIO45_PRT_ID_WIDTH
-#define MDIO45_DEV_ID_COMP_LBN    0
-#define MDIO45_DEV_ID_COMP_WIDTH  MDIO45_DEV_ID_WIDTH
-
-/* Compose port and device into a phy_id */
-static inline int mdio_clause45_pack(u8 prt, u8 dev)
-{
-       efx_dword_t phy_id;
-       EFX_POPULATE_DWORD_2(phy_id, MDIO45_PRT_ID_COMP, prt,
-                            MDIO45_DEV_ID_COMP, dev);
-       return MDIO45_XPRT_ID_IS10G | EFX_DWORD_VAL(phy_id);
-}
-
-static inline void mdio_clause45_unpack(u32 val, u8 *prt, u8 *dev)
+static inline int efx_mdio_read(struct efx_nic *efx, int devad, int addr)
 {
-       efx_dword_t phy_id;
-       EFX_POPULATE_DWORD_1(phy_id, EFX_DWORD_0, val);
-       *prt = EFX_DWORD_FIELD(phy_id, MDIO45_PRT_ID_COMP);
-       *dev = EFX_DWORD_FIELD(phy_id, MDIO45_DEV_ID_COMP);
+       return efx->mdio.mdio_read(efx->net_dev, efx->mdio.prtad, devad, addr);
 }
 
-static inline int mdio_clause45_read(struct efx_nic *efx,
-                                    u8 prt, u8 dev, u16 addr)
+static inline void
+efx_mdio_write(struct efx_nic *efx, int devad, int addr, int value)
 {
-       return efx->mii.mdio_read(efx->net_dev,
-                                 mdio_clause45_pack(prt, dev), addr);
+       efx->mdio.mdio_write(efx->net_dev, efx->mdio.prtad, devad, addr, value);
 }
 
-static inline void mdio_clause45_write(struct efx_nic *efx,
-                                      u8 prt, u8 dev, u16 addr, int value)
+static inline u32 efx_mdio_read_id(struct efx_nic *efx, int mmd)
 {
-       efx->mii.mdio_write(efx->net_dev,
-                           mdio_clause45_pack(prt, dev), addr, value);
-}
-
-
-static inline u32 mdio_clause45_read_id(struct efx_nic *efx, int mmd)
-{
-       int phy_id = efx->mii.phy_id;
-       u16 id_low = mdio_clause45_read(efx, phy_id, mmd, MDIO_MMDREG_IDLOW);
-       u16 id_hi = mdio_clause45_read(efx, phy_id, mmd, MDIO_MMDREG_IDHI);
+       u16 id_low = efx_mdio_read(efx, mmd, MDIO_DEVID2);
+       u16 id_hi = efx_mdio_read(efx, mmd, MDIO_DEVID1);
        return (id_hi << 16) | (id_low);
 }
 
-static inline bool mdio_clause45_phyxgxs_lane_sync(struct efx_nic *efx)
+static inline bool efx_mdio_phyxgxs_lane_sync(struct efx_nic *efx)
 {
        int i, lane_status;
        bool sync;
 
        for (i = 0; i < 2; ++i)
-               lane_status = mdio_clause45_read(efx, efx->mii.phy_id,
-                                                MDIO_MMD_PHYXS,
-                                                MDIO_PHYXS_LANE_STATE);
+               lane_status = efx_mdio_read(efx, MDIO_MMD_PHYXS,
+                                           MDIO_PHYXS_LNSTAT);
 
-       sync = !!(lane_status & (1 << MDIO_PHYXS_LANE_ALIGNED_LBN));
+       sync = !!(lane_status & MDIO_PHYXS_LNSTAT_ALIGN);
        if (!sync)
                EFX_LOG(efx, "XGXS lane status: %x\n", lane_status);
        return sync;
 }
 
-extern const char *mdio_clause45_mmd_name(int mmd);
+extern const char *efx_mdio_mmd_name(int mmd);
 
 /*
  * Reset a specific MMD and wait for reset to clear.
@@ -258,54 +64,44 @@ extern const char *mdio_clause45_mmd_name(int mmd);
  *
  * This function will sleep
  */
-extern int mdio_clause45_reset_mmd(struct efx_nic *efx, int mmd,
-                                  int spins, int spintime);
+extern int efx_mdio_reset_mmd(struct efx_nic *efx, int mmd,
+                             int spins, int spintime);
 
-/* As mdio_clause45_check_mmd but for multiple MMDs */
-int mdio_clause45_check_mmds(struct efx_nic *efx,
-                            unsigned int mmd_mask, unsigned int fatal_mask);
+/* As efx_mdio_check_mmd but for multiple MMDs */
+int efx_mdio_check_mmds(struct efx_nic *efx,
+                       unsigned int mmd_mask, unsigned int fatal_mask);
 
 /* Check the link status of specified mmds in bit mask */
-extern bool mdio_clause45_links_ok(struct efx_nic *efx,
-                                  unsigned int mmd_mask);
+extern bool efx_mdio_links_ok(struct efx_nic *efx, unsigned int mmd_mask);
 
 /* Generic transmit disable support though PMAPMD */
-extern void mdio_clause45_transmit_disable(struct efx_nic *efx);
+extern void efx_mdio_transmit_disable(struct efx_nic *efx);
 
 /* Generic part of reconfigure: set/clear loopback bits */
-extern void mdio_clause45_phy_reconfigure(struct efx_nic *efx);
+extern void efx_mdio_phy_reconfigure(struct efx_nic *efx);
 
 /* Set the power state of the specified MMDs */
-extern void mdio_clause45_set_mmds_lpower(struct efx_nic *efx,
-                                         int low_power, unsigned int mmd_mask);
-
-/* Read (some of) the PHY settings over MDIO */
-extern void mdio_clause45_get_settings(struct efx_nic *efx,
-                                      struct ethtool_cmd *ecmd);
-
-/* Read (some of) the PHY settings over MDIO */
-extern void
-mdio_clause45_get_settings_ext(struct efx_nic *efx, struct ethtool_cmd *ecmd,
-                              u32 xnp, u32 xnp_lpa);
+extern void efx_mdio_set_mmds_lpower(struct efx_nic *efx,
+                                    int low_power, unsigned int mmd_mask);
 
 /* Set (some of) the PHY settings over MDIO */
-extern int mdio_clause45_set_settings(struct efx_nic *efx,
-                                     struct ethtool_cmd *ecmd);
-
-/* Set pause parameters to be advertised through AN (if available) */
-extern void mdio_clause45_set_pause(struct efx_nic *efx);
+extern int efx_mdio_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd);
 
 /* Get pause parameters from AN if available (otherwise return
  * requested pause parameters)
  */
-enum efx_fc_type mdio_clause45_get_pause(struct efx_nic *efx);
+enum efx_fc_type efx_mdio_get_pause(struct efx_nic *efx);
 
 /* Wait for specified MMDs to exit reset within a timeout */
-extern int mdio_clause45_wait_reset_mmds(struct efx_nic *efx,
-                                        unsigned int mmd_mask);
+extern int efx_mdio_wait_reset_mmds(struct efx_nic *efx,
+                                   unsigned int mmd_mask);
 
 /* Set or clear flag, debouncing */
-extern void mdio_clause45_set_flag(struct efx_nic *efx, u8 prt, u8 dev,
-                                  u16 addr, int bit, bool sense);
+static inline void
+efx_mdio_set_flag(struct efx_nic *efx, int devad, int addr,
+                 int mask, bool state)
+{
+       mdio_set_flag(&efx->mdio, efx->mdio.prtad, devad, addr, mask, state);
+}
 
 #endif /* EFX_MDIO_10G_H */
index e169e5dcd1e63cc2f0f39cfb11d2975271b2f8f3..5eabede9ac184597c0a70968714b8b2b8166b0ab 100644 (file)
@@ -19,7 +19,7 @@
 #include <linux/ethtool.h>
 #include <linux/if_vlan.h>
 #include <linux/timer.h>
-#include <linux/mii.h>
+#include <linux/mdio.h>
 #include <linux/list.h>
 #include <linux/pci.h>
 #include <linux/device.h>
@@ -458,8 +458,6 @@ enum phy_type {
        PHY_TYPE_MAX    /* Insert any new items before this */
 };
 
-#define PHY_ADDR_INVALID 0xff
-
 #define EFX_IS10G(efx) ((efx)->link_speed == 10000)
 
 enum nic_state {
@@ -497,8 +495,8 @@ struct efx_nic;
 
 /* Pseudo bit-mask flow control field */
 enum efx_fc_type {
-       EFX_FC_RX = 1,
-       EFX_FC_TX = 2,
+       EFX_FC_RX = FLOW_CTRL_RX,
+       EFX_FC_TX = FLOW_CTRL_TX,
        EFX_FC_AUTO = 4,
 };
 
@@ -508,33 +506,15 @@ enum efx_mac_type {
        EFX_XMAC = 2,
 };
 
-static inline unsigned int efx_fc_advertise(enum efx_fc_type wanted_fc)
-{
-       unsigned int adv = 0;
-       if (wanted_fc & EFX_FC_RX)
-               adv = ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
-       if (wanted_fc & EFX_FC_TX)
-               adv ^= ADVERTISE_PAUSE_ASYM;
-       return adv;
-}
-
 static inline enum efx_fc_type efx_fc_resolve(enum efx_fc_type wanted_fc,
                                              unsigned int lpa)
 {
-       unsigned int adv = efx_fc_advertise(wanted_fc);
+       BUILD_BUG_ON(EFX_FC_AUTO & (EFX_FC_RX | EFX_FC_TX));
 
        if (!(wanted_fc & EFX_FC_AUTO))
                return wanted_fc;
 
-       if (adv & lpa & ADVERTISE_PAUSE_CAP)
-               return EFX_FC_RX | EFX_FC_TX;
-       if (adv & lpa & ADVERTISE_PAUSE_ASYM) {
-               if (adv & ADVERTISE_PAUSE_CAP)
-                       return EFX_FC_RX;
-               if (lpa & ADVERTISE_PAUSE_CAP)
-                       return EFX_FC_TX;
-       }
-       return 0;
+       return mii_resolve_flowctrl_fdx(mii_advertise_flowctrl(wanted_fc), lpa);
 }
 
 /**
@@ -758,7 +738,7 @@ union efx_multicast_hash {
  * @phy_lock: PHY access lock
  * @phy_op: PHY interface
  * @phy_data: PHY private data (including PHY-specific stats)
- * @mii: PHY interface
+ * @mdio: PHY MDIO interface
  * @phy_mode: PHY operating mode. Serialised by @mac_lock.
  * @mac_up: MAC link state
  * @link_up: Link status
@@ -845,7 +825,7 @@ struct efx_nic {
        struct work_struct phy_work;
        struct efx_phy_operations *phy_op;
        void *phy_data;
-       struct mii_if_info mii;
+       struct mdio_if_info mdio;
        enum efx_phy_mode phy_mode;
 
        bool mac_up;
index 66d7fe3db3e6e74cc6c2c137226121828bb5577d..01f9432c31ef9f2c02ec3df3dce4159c2fda1bb4 100644 (file)
@@ -450,17 +450,27 @@ static void efx_rx_packet_lro(struct efx_channel *channel,
 
        /* Pass the skb/page into the LRO engine */
        if (rx_buf->page) {
-               struct napi_gro_fraginfo info;
+               struct sk_buff *skb = napi_get_frags(napi);
 
-               info.frags[0].page = rx_buf->page;
-               info.frags[0].page_offset = efx_rx_buf_offset(rx_buf);
-               info.frags[0].size = rx_buf->len;
-               info.nr_frags = 1;
-               info.ip_summed = CHECKSUM_UNNECESSARY;
-               info.len = rx_buf->len;
+               if (!skb) {
+                       put_page(rx_buf->page);
+                       goto out;
+               }
+
+               skb_shinfo(skb)->frags[0].page = rx_buf->page;
+               skb_shinfo(skb)->frags[0].page_offset =
+                       efx_rx_buf_offset(rx_buf);
+               skb_shinfo(skb)->frags[0].size = rx_buf->len;
+               skb_shinfo(skb)->nr_frags = 1;
+
+               skb->len = rx_buf->len;
+               skb->data_len = rx_buf->len;
+               skb->truesize += rx_buf->len;
+               skb->ip_summed = CHECKSUM_UNNECESSARY;
 
-               napi_gro_frags(napi, &info);
+               napi_gro_frags(napi);
 
+out:
                EFX_BUG_ON_PARANOID(rx_buf->skb);
                rx_buf->page = NULL;
        } else {
index 0a598084c5133a64cdb4dd4bb342b2fedc976b66..b67ccca3fc1a07920c9d7a3e6cecc9f3653eebe9 100644 (file)
@@ -80,39 +80,38 @@ struct efx_loopback_state {
  *
  **************************************************************************/
 
-static int efx_test_mii(struct efx_nic *efx, struct efx_self_tests *tests)
+static int efx_test_mdio(struct efx_nic *efx, struct efx_self_tests *tests)
 {
        int rc = 0;
+       int devad = __ffs(efx->mdio.mmds);
        u16 physid1, physid2;
-       struct mii_if_info *mii = &efx->mii;
-       struct net_device *net_dev = efx->net_dev;
 
        if (efx->phy_type == PHY_TYPE_NONE)
                return 0;
 
        mutex_lock(&efx->mac_lock);
-       tests->mii = -1;
+       tests->mdio = -1;
 
-       physid1 = mii->mdio_read(net_dev, mii->phy_id, MII_PHYSID1);
-       physid2 = mii->mdio_read(net_dev, mii->phy_id, MII_PHYSID2);
+       physid1 = efx_mdio_read(efx, devad, MDIO_DEVID1);
+       physid2 = efx_mdio_read(efx, devad, MDIO_DEVID2);
 
        if ((physid1 == 0x0000) || (physid1 == 0xffff) ||
            (physid2 == 0x0000) || (physid2 == 0xffff)) {
-               EFX_ERR(efx, "no MII PHY present with ID %d\n",
-                       mii->phy_id);
+               EFX_ERR(efx, "no MDIO PHY present with ID %d\n",
+                       efx->mdio.prtad);
                rc = -EINVAL;
                goto out;
        }
 
        if (EFX_IS10G(efx)) {
-               rc = mdio_clause45_check_mmds(efx, efx->phy_op->mmds, 0);
+               rc = efx_mdio_check_mmds(efx, efx->phy_op->mmds, 0);
                if (rc)
                        goto out;
        }
 
 out:
        mutex_unlock(&efx->mac_lock);
-       tests->mii = rc ? -1 : 1;
+       tests->mdio = rc ? -1 : 1;
        return rc;
 }
 
@@ -439,6 +438,7 @@ static int efx_begin_loopback(struct efx_tx_queue *tx_queue)
                        kfree_skb(skb);
                        return -EPIPE;
                }
+               efx->net_dev->trans_start = jiffies;
        }
 
        return 0;
@@ -673,7 +673,7 @@ int efx_selftest(struct efx_nic *efx, struct efx_self_tests *tests,
        /* Online (i.e. non-disruptive) testing
         * This checks interrupt generation, event delivery and PHY presence. */
 
-       rc = efx_test_mii(efx, tests);
+       rc = efx_test_mdio(efx, tests);
        if (rc && !rc_test)
                rc_test = rc;
 
index 39451cf938cfe7bd1448553fa9b0fb13e8b33f89..f6feee04c96ba925ea187284cd6fffab812872ed 100644 (file)
@@ -32,7 +32,7 @@ struct efx_loopback_self_tests {
  */
 struct efx_self_tests {
        /* online tests */
-       int mii;
+       int mdio;
        int nvram;
        int interrupt;
        int eventq_dma[EFX_MAX_CHANNELS];
index 4eac5da81e5aeab2816222235be680cc6d3607ac..cee00ad49b5725e86c0f5b60cf6f995f5b8717b7 100644 (file)
@@ -296,7 +296,6 @@ static int sfe4001_check_hw(struct efx_nic *efx)
 
 static struct i2c_board_info sfe4001_hwmon_info = {
        I2C_BOARD_INFO("max6647", 0x4e),
-       .irq            = -1,
 };
 
 /* This board uses an I2C expander to provider power to the PHY, which needs to
@@ -389,12 +388,10 @@ static void sfn4111t_fini(struct efx_nic *efx)
 
 static struct i2c_board_info sfn4111t_a0_hwmon_info = {
        I2C_BOARD_INFO("max6647", 0x4e),
-       .irq            = -1,
 };
 
 static struct i2c_board_info sfn4111t_r5_hwmon_info = {
        I2C_BOARD_INFO("max6646", 0x4d),
-       .irq            = -1,
 };
 
 int sfn4111t_init(struct efx_nic *efx)
index e61dc4d4741c973d59ce4c33c7d332eb0a5fa6fa..f4d509015f754d0a26245a8e90333a2514dcdf0d 100644 (file)
  * clause 22 extension MMD, but since it doesn't have all the generic
  * MMD registers it is pointless to include it here.
  */
-#define TENXPRESS_REQUIRED_DEVS (MDIO_MMDREG_DEVS_PMAPMD       | \
-                                MDIO_MMDREG_DEVS_PCS           | \
-                                MDIO_MMDREG_DEVS_PHYXS         | \
-                                MDIO_MMDREG_DEVS_AN)
+#define TENXPRESS_REQUIRED_DEVS (MDIO_DEVS_PMAPMD      | \
+                                MDIO_DEVS_PCS          | \
+                                MDIO_DEVS_PHYXS        | \
+                                MDIO_DEVS_AN)
 
 #define SFX7101_LOOPBACKS ((1 << LOOPBACK_PHYXS) |     \
                           (1 << LOOPBACK_PCS) |        \
  */
 #define MAX_BAD_LP_TRIES       (5)
 
-/* LASI Control */
-#define PMA_PMD_LASI_CTRL      36866
-#define PMA_PMD_LASI_STATUS    36869
-#define PMA_PMD_LS_ALARM_LBN   0
-#define PMA_PMD_LS_ALARM_WIDTH 1
-#define PMA_PMD_TX_ALARM_LBN   1
-#define PMA_PMD_TX_ALARM_WIDTH 1
-#define PMA_PMD_RX_ALARM_LBN   2
-#define PMA_PMD_RX_ALARM_WIDTH 1
-#define PMA_PMD_AN_ALARM_LBN   3
-#define PMA_PMD_AN_ALARM_WIDTH 1
-
 /* Extended control register */
 #define PMA_PMD_XCONTROL_REG   49152
 #define PMA_PMD_EXT_GMII_EN_LBN        1
@@ -75,6 +63,7 @@
 
 /* extended status register */
 #define PMA_PMD_XSTATUS_REG    49153
+#define PMA_PMD_XSTAT_MDIX_LBN 14
 #define PMA_PMD_XSTAT_FLP_LBN   (12)
 
 /* LED control register */
 #define LOOPBACK_NEAR_LBN   (8)
 #define LOOPBACK_NEAR_WIDTH (1)
 
-#define PCS_10GBASET_STAT1       32
-#define PCS_10GBASET_BLKLK_LBN   0
-#define PCS_10GBASET_BLKLK_WIDTH 1
-
 /* Boot status register */
 #define PCS_BOOT_STATUS_REG            53248
 #define PCS_BOOT_FATAL_ERROR_LBN       0
@@ -206,10 +191,8 @@ static ssize_t show_phy_short_reach(struct device *dev,
        struct efx_nic *efx = pci_get_drvdata(to_pci_dev(dev));
        int reg;
 
-       reg = mdio_clause45_read(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD,
-                                MDIO_PMAPMD_10GBT_TXPWR);
-       return sprintf(buf, "%d\n",
-                      !!(reg & (1 << MDIO_PMAPMD_10GBT_TXPWR_SHORT_LBN)));
+       reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD, MDIO_PMA_10GBT_TXPWR);
+       return sprintf(buf, "%d\n", !!(reg & MDIO_PMA_10GBT_TXPWR_SHORT));
 }
 
 static ssize_t set_phy_short_reach(struct device *dev,
@@ -219,10 +202,9 @@ static ssize_t set_phy_short_reach(struct device *dev,
        struct efx_nic *efx = pci_get_drvdata(to_pci_dev(dev));
 
        rtnl_lock();
-       mdio_clause45_set_flag(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD,
-                              MDIO_PMAPMD_10GBT_TXPWR,
-                              MDIO_PMAPMD_10GBT_TXPWR_SHORT_LBN,
-                              count != 0 && *buf != '0');
+       efx_mdio_set_flag(efx, MDIO_MMD_PMAPMD, MDIO_PMA_10GBT_TXPWR,
+                         MDIO_PMA_10GBT_TXPWR_SHORT,
+                         count != 0 && *buf != '0');
        efx_reconfigure_port(efx);
        rtnl_unlock();
 
@@ -238,9 +220,8 @@ int sft9001_wait_boot(struct efx_nic *efx)
        int boot_stat;
 
        for (;;) {
-               boot_stat = mdio_clause45_read(efx, efx->mii.phy_id,
-                                              MDIO_MMD_PCS,
-                                              PCS_BOOT_STATUS_REG);
+               boot_stat = efx_mdio_read(efx, MDIO_MMD_PCS,
+                                         PCS_BOOT_STATUS_REG);
                if (boot_stat >= 0) {
                        EFX_LOG(efx, "PHY boot status = %#x\n", boot_stat);
                        switch (boot_stat &
@@ -286,38 +267,32 @@ int sft9001_wait_boot(struct efx_nic *efx)
 
 static int tenxpress_init(struct efx_nic *efx)
 {
-       int phy_id = efx->mii.phy_id;
        int reg;
 
        if (efx->phy_type == PHY_TYPE_SFX7101) {
                /* Enable 312.5 MHz clock */
-               mdio_clause45_write(efx, phy_id,
-                                   MDIO_MMD_PCS, PCS_TEST_SELECT_REG,
-                                   1 << CLK312_EN_LBN);
+               efx_mdio_write(efx, MDIO_MMD_PCS, PCS_TEST_SELECT_REG,
+                              1 << CLK312_EN_LBN);
        } else {
                /* Enable 312.5 MHz clock and GMII */
-               reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
-                                        PMA_PMD_XCONTROL_REG);
+               reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG);
                reg |= ((1 << PMA_PMD_EXT_GMII_EN_LBN) |
                        (1 << PMA_PMD_EXT_CLK_OUT_LBN) |
                        (1 << PMA_PMD_EXT_CLK312_LBN) |
                        (1 << PMA_PMD_EXT_ROBUST_LBN));
 
-               mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD,
-                                   PMA_PMD_XCONTROL_REG, reg);
-               mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_C22EXT,
-                                      GPHY_XCONTROL_REG, GPHY_ISOLATE_LBN,
-                                      false);
+               efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG, reg);
+               efx_mdio_set_flag(efx, MDIO_MMD_C22EXT,
+                             GPHY_XCONTROL_REG, 1 << GPHY_ISOLATE_LBN,
+                             false);
        }
 
        /* Set the LEDs up as: Green = Link, Amber = Link/Act, Red = Off */
        if (efx->phy_type == PHY_TYPE_SFX7101) {
-               mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_PMAPMD,
-                                      PMA_PMD_LED_CTRL_REG,
-                                      PMA_PMA_LED_ACTIVITY_LBN,
-                                      true);
-               mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD,
-                                   PMA_PMD_LED_OVERR_REG, PMA_PMD_LED_DEFAULT);
+               efx_mdio_set_flag(efx, MDIO_MMD_PMAPMD, PMA_PMD_LED_CTRL_REG,
+                                 1 << PMA_PMA_LED_ACTIVITY_LBN, true);
+               efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_LED_OVERR_REG,
+                              PMA_PMD_LED_DEFAULT);
        }
 
        return 0;
@@ -337,22 +312,19 @@ static int tenxpress_phy_init(struct efx_nic *efx)
        if (!(efx->phy_mode & PHY_MODE_SPECIAL)) {
                if (efx->phy_type == PHY_TYPE_SFT9001A) {
                        int reg;
-                       reg = mdio_clause45_read(efx, efx->mii.phy_id,
-                                                MDIO_MMD_PMAPMD,
-                                                PMA_PMD_XCONTROL_REG);
+                       reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD,
+                                           PMA_PMD_XCONTROL_REG);
                        reg |= (1 << PMA_PMD_EXT_SSR_LBN);
-                       mdio_clause45_write(efx, efx->mii.phy_id,
-                                           MDIO_MMD_PMAPMD,
-                                           PMA_PMD_XCONTROL_REG, reg);
+                       efx_mdio_write(efx, MDIO_MMD_PMAPMD,
+                                      PMA_PMD_XCONTROL_REG, reg);
                        mdelay(200);
                }
 
-               rc = mdio_clause45_wait_reset_mmds(efx,
-                                                  TENXPRESS_REQUIRED_DEVS);
+               rc = efx_mdio_wait_reset_mmds(efx, TENXPRESS_REQUIRED_DEVS);
                if (rc < 0)
                        goto fail;
 
-               rc = mdio_clause45_check_mmds(efx, TENXPRESS_REQUIRED_DEVS, 0);
+               rc = efx_mdio_check_mmds(efx, TENXPRESS_REQUIRED_DEVS, 0);
                if (rc < 0)
                        goto fail;
        }
@@ -360,7 +332,6 @@ static int tenxpress_phy_init(struct efx_nic *efx)
        rc = tenxpress_init(efx);
        if (rc < 0)
                goto fail;
-       mdio_clause45_set_pause(efx);
 
        if (efx->phy_type == PHY_TYPE_SFT9001B) {
                rc = device_create_file(&efx->pci_dev->dev,
@@ -395,17 +366,14 @@ static int tenxpress_special_reset(struct efx_nic *efx)
        efx_stats_disable(efx);
 
        /* Initiate reset */
-       reg = mdio_clause45_read(efx, efx->mii.phy_id,
-                                MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG);
+       reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG);
        reg |= (1 << PMA_PMD_EXT_SSR_LBN);
-       mdio_clause45_write(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD,
-                           PMA_PMD_XCONTROL_REG, reg);
+       efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG, reg);
 
        mdelay(200);
 
        /* Wait for the blocks to come out of reset */
-       rc = mdio_clause45_wait_reset_mmds(efx,
-                                          TENXPRESS_REQUIRED_DEVS);
+       rc = efx_mdio_wait_reset_mmds(efx, TENXPRESS_REQUIRED_DEVS);
        if (rc < 0)
                goto out;
 
@@ -424,7 +392,6 @@ out:
 static void sfx7101_check_bad_lp(struct efx_nic *efx, bool link_ok)
 {
        struct tenxpress_phy_data *pd = efx->phy_data;
-       int phy_id = efx->mii.phy_id;
        bool bad_lp;
        int reg;
 
@@ -432,11 +399,10 @@ static void sfx7101_check_bad_lp(struct efx_nic *efx, bool link_ok)
                bad_lp = false;
        } else {
                /* Check that AN has started but not completed. */
-               reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
-                                        MDIO_AN_STATUS);
-               if (!(reg & (1 << MDIO_AN_STATUS_LP_AN_CAP_LBN)))
+               reg = efx_mdio_read(efx, MDIO_MMD_AN, MDIO_STAT1);
+               if (!(reg & MDIO_AN_STAT1_LPABLE))
                        return; /* LP status is unknown */
-               bad_lp = !(reg & (1 << MDIO_AN_STATUS_AN_DONE_LBN));
+               bad_lp = !(reg & MDIO_AN_STAT1_COMPLETE);
                if (bad_lp)
                        pd->bad_lp_tries++;
        }
@@ -448,8 +414,8 @@ static void sfx7101_check_bad_lp(struct efx_nic *efx, bool link_ok)
        /* Use the RX (red) LED as an error indicator once we've seen AN
         * failure several times in a row, and also log a message. */
        if (!bad_lp || pd->bad_lp_tries == MAX_BAD_LP_TRIES) {
-               reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
-                                        PMA_PMD_LED_OVERR_REG);
+               reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD,
+                                   PMA_PMD_LED_OVERR_REG);
                reg &= ~(PMA_PMD_LED_MASK << PMA_PMD_LED_RX_LBN);
                if (!bad_lp) {
                        reg |= PMA_PMD_LED_OFF << PMA_PMD_LED_RX_LBN;
@@ -460,23 +426,22 @@ static void sfx7101_check_bad_lp(struct efx_nic *efx, bool link_ok)
                                " supports 10GBASE-T ONLY, so no link can"
                                " be established\n");
                }
-               mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD,
-                                   PMA_PMD_LED_OVERR_REG, reg);
+               efx_mdio_write(efx, MDIO_MMD_PMAPMD,
+                              PMA_PMD_LED_OVERR_REG, reg);
                pd->bad_lp_tries = bad_lp;
        }
 }
 
 static bool sfx7101_link_ok(struct efx_nic *efx)
 {
-       return mdio_clause45_links_ok(efx,
-                                     MDIO_MMDREG_DEVS_PMAPMD |
-                                     MDIO_MMDREG_DEVS_PCS |
-                                     MDIO_MMDREG_DEVS_PHYXS);
+       return efx_mdio_links_ok(efx,
+                                MDIO_DEVS_PMAPMD |
+                                MDIO_DEVS_PCS |
+                                MDIO_DEVS_PHYXS);
 }
 
 static bool sft9001_link_ok(struct efx_nic *efx, struct ethtool_cmd *ecmd)
 {
-       int phy_id = efx->mii.phy_id;
        u32 reg;
 
        if (efx_phy_mode_disabled(efx->phy_mode))
@@ -484,50 +449,43 @@ static bool sft9001_link_ok(struct efx_nic *efx, struct ethtool_cmd *ecmd)
        else if (efx->loopback_mode == LOOPBACK_GPHY)
                return true;
        else if (efx->loopback_mode)
-               return mdio_clause45_links_ok(efx,
-                                             MDIO_MMDREG_DEVS_PMAPMD |
-                                             MDIO_MMDREG_DEVS_PHYXS);
+               return efx_mdio_links_ok(efx,
+                                        MDIO_DEVS_PMAPMD |
+                                        MDIO_DEVS_PHYXS);
 
        /* We must use the same definition of link state as LASI,
         * otherwise we can miss a link state transition
         */
        if (ecmd->speed == 10000) {
-               reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PCS,
-                                        PCS_10GBASET_STAT1);
-               return reg & (1 << PCS_10GBASET_BLKLK_LBN);
+               reg = efx_mdio_read(efx, MDIO_MMD_PCS, MDIO_PCS_10GBRT_STAT1);
+               return reg & MDIO_PCS_10GBRT_STAT1_BLKLK;
        } else {
-               reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_C22EXT,
-                                        C22EXT_STATUS_REG);
+               reg = efx_mdio_read(efx, MDIO_MMD_C22EXT, C22EXT_STATUS_REG);
                return reg & (1 << C22EXT_STATUS_LINK_LBN);
        }
 }
 
 static void tenxpress_ext_loopback(struct efx_nic *efx)
 {
-       int phy_id = efx->mii.phy_id;
-
-       mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_PHYXS,
-                              PHYXS_TEST1, LOOPBACK_NEAR_LBN,
-                              efx->loopback_mode == LOOPBACK_PHYXS);
+       efx_mdio_set_flag(efx, MDIO_MMD_PHYXS, PHYXS_TEST1,
+                         1 << LOOPBACK_NEAR_LBN,
+                         efx->loopback_mode == LOOPBACK_PHYXS);
        if (efx->phy_type != PHY_TYPE_SFX7101)
-               mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_C22EXT,
-                                      GPHY_XCONTROL_REG,
-                                      GPHY_LOOPBACK_NEAR_LBN,
-                                      efx->loopback_mode == LOOPBACK_GPHY);
+               efx_mdio_set_flag(efx, MDIO_MMD_C22EXT, GPHY_XCONTROL_REG,
+                                 1 << GPHY_LOOPBACK_NEAR_LBN,
+                                 efx->loopback_mode == LOOPBACK_GPHY);
 }
 
 static void tenxpress_low_power(struct efx_nic *efx)
 {
-       int phy_id = efx->mii.phy_id;
-
        if (efx->phy_type == PHY_TYPE_SFX7101)
-               mdio_clause45_set_mmds_lpower(
+               efx_mdio_set_mmds_lpower(
                        efx, !!(efx->phy_mode & PHY_MODE_LOW_POWER),
                        TENXPRESS_REQUIRED_DEVS);
        else
-               mdio_clause45_set_flag(
-                       efx, phy_id, MDIO_MMD_PMAPMD,
-                       PMA_PMD_XCONTROL_REG, PMA_PMD_EXT_LPOWER_LBN,
+               efx_mdio_set_flag(
+                       efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG,
+                       1 << PMA_PMD_EXT_LPOWER_LBN,
                        !!(efx->phy_mode & PHY_MODE_LOW_POWER));
 }
 
@@ -568,8 +526,8 @@ static void tenxpress_phy_reconfigure(struct efx_nic *efx)
                WARN_ON(rc);
        }
 
-       mdio_clause45_transmit_disable(efx);
-       mdio_clause45_phy_reconfigure(efx);
+       efx_mdio_transmit_disable(efx);
+       efx_mdio_phy_reconfigure(efx);
        tenxpress_ext_loopback(efx);
 
        phy_data->loopback_mode = efx->loopback_mode;
@@ -585,7 +543,7 @@ static void tenxpress_phy_reconfigure(struct efx_nic *efx)
                efx->link_fd = ecmd.duplex == DUPLEX_FULL;
                efx->link_up = sft9001_link_ok(efx, &ecmd);
        }
-       efx->link_fc = mdio_clause45_get_pause(efx);
+       efx->link_fc = efx_mdio_get_pause(efx);
 }
 
 /* Poll PHY for interrupt */
@@ -599,7 +557,7 @@ static void tenxpress_phy_poll(struct efx_nic *efx)
                if (link_ok != efx->link_up) {
                        change = true;
                } else {
-                       unsigned int link_fc = mdio_clause45_get_pause(efx);
+                       unsigned int link_fc = efx_mdio_get_pause(efx);
                        if (link_fc != efx->link_fc)
                                change = true;
                }
@@ -609,10 +567,9 @@ static void tenxpress_phy_poll(struct efx_nic *efx)
                if (link_ok != efx->link_up)
                        change = true;
        } else {
-               u32 status = mdio_clause45_read(efx, efx->mii.phy_id,
-                                               MDIO_MMD_PMAPMD,
-                                               PMA_PMD_LASI_STATUS);
-               if (status & (1 << PMA_PMD_LS_ALARM_LBN))
+               int status = efx_mdio_read(efx, MDIO_MMD_PMAPMD,
+                                          MDIO_PMA_LASI_STAT);
+               if (status & MDIO_PMA_LASI_LSALARM)
                        change = true;
        }
 
@@ -634,8 +591,7 @@ static void tenxpress_phy_fini(struct efx_nic *efx)
        if (efx->phy_type == PHY_TYPE_SFX7101) {
                /* Power down the LNPGA */
                reg = (1 << PMA_PMD_LNPGA_POWERDOWN_LBN);
-               mdio_clause45_write(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD,
-                                   PMA_PMD_XCONTROL_REG, reg);
+               efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG, reg);
 
                /* Waiting here ensures that the board fini, which can turn
                 * off the power to the PHY, won't get run until the LNPGA
@@ -661,8 +617,7 @@ void tenxpress_phy_blink(struct efx_nic *efx, bool blink)
        else
                reg = PMA_PMD_LED_DEFAULT;
 
-       mdio_clause45_write(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD,
-                           PMA_PMD_LED_OVERR_REG, reg);
+       efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_LED_OVERR_REG, reg);
 }
 
 static const char *const sfx7101_test_names[] = {
@@ -698,7 +653,6 @@ static const char *const sft9001_test_names[] = {
 static int sft9001_run_tests(struct efx_nic *efx, int *results, unsigned flags)
 {
        struct ethtool_cmd ecmd;
-       int phy_id = efx->mii.phy_id;
        int rc = 0, rc2, i, ctrl_reg, res_reg;
 
        if (flags & ETH_TEST_FL_OFFLINE)
@@ -717,11 +671,10 @@ static int sft9001_run_tests(struct efx_nic *efx, int *results, unsigned flags)
                 * must reset the PHY to resume normal service. */
                ctrl_reg |= (1 << CDIAG_CTRL_BRK_LINK_LBN);
        }
-       mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD,
-                           PMA_PMD_CDIAG_CTRL_REG, ctrl_reg);
+       efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_CDIAG_CTRL_REG,
+                      ctrl_reg);
        i = 0;
-       while (mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
-                                 PMA_PMD_CDIAG_CTRL_REG) &
+       while (efx_mdio_read(efx, MDIO_MMD_PMAPMD, PMA_PMD_CDIAG_CTRL_REG) &
               (1 << CDIAG_CTRL_IN_PROG_LBN)) {
                if (++i == 50) {
                        rc = -ETIMEDOUT;
@@ -729,15 +682,13 @@ static int sft9001_run_tests(struct efx_nic *efx, int *results, unsigned flags)
                }
                msleep(100);
        }
-       res_reg = mdio_clause45_read(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD,
-                                    PMA_PMD_CDIAG_RES_REG);
+       res_reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD, PMA_PMD_CDIAG_RES_REG);
        for (i = 0; i < 4; i++) {
                int pair_res =
                        (res_reg >> (CDIAG_RES_A_LBN - i * CDIAG_RES_WIDTH))
                        & ((1 << CDIAG_RES_WIDTH) - 1);
-               int len_reg = mdio_clause45_read(efx, efx->mii.phy_id,
-                                                MDIO_MMD_PMAPMD,
-                                                PMA_PMD_CDIAG_LEN_REG + i);
+               int len_reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD,
+                                           PMA_PMD_CDIAG_LEN_REG + i);
                if (pair_res == CDIAG_RES_OK)
                        results[1 + i] = 1;
                else if (pair_res == CDIAG_RES_INVALID)
@@ -769,36 +720,39 @@ out:
 static void
 tenxpress_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
 {
-       int phy_id = efx->mii.phy_id;
        u32 adv = 0, lpa = 0;
        int reg;
 
        if (efx->phy_type != PHY_TYPE_SFX7101) {
-               reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_C22EXT,
-                                        C22EXT_MSTSLV_CTRL);
+               reg = efx_mdio_read(efx, MDIO_MMD_C22EXT, C22EXT_MSTSLV_CTRL);
                if (reg & (1 << C22EXT_MSTSLV_CTRL_ADV_1000_FD_LBN))
                        adv |= ADVERTISED_1000baseT_Full;
-               reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_C22EXT,
-                                        C22EXT_MSTSLV_STATUS);
+               reg = efx_mdio_read(efx, MDIO_MMD_C22EXT, C22EXT_MSTSLV_STATUS);
                if (reg & (1 << C22EXT_MSTSLV_STATUS_LP_1000_HD_LBN))
                        lpa |= ADVERTISED_1000baseT_Half;
                if (reg & (1 << C22EXT_MSTSLV_STATUS_LP_1000_FD_LBN))
                        lpa |= ADVERTISED_1000baseT_Full;
        }
-       reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
-                                MDIO_AN_10GBT_CTRL);
-       if (reg & (1 << MDIO_AN_10GBT_CTRL_ADV_10G_LBN))
+       reg = efx_mdio_read(efx, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL);
+       if (reg & MDIO_AN_10GBT_CTRL_ADV10G)
                adv |= ADVERTISED_10000baseT_Full;
-       reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_AN,
-                                MDIO_AN_10GBT_STATUS);
-       if (reg & (1 << MDIO_AN_10GBT_STATUS_LP_10G_LBN))
+       reg = efx_mdio_read(efx, MDIO_MMD_AN, MDIO_AN_10GBT_STAT);
+       if (reg & MDIO_AN_10GBT_STAT_LP10G)
                lpa |= ADVERTISED_10000baseT_Full;
 
-       mdio_clause45_get_settings_ext(efx, ecmd, adv, lpa);
+       mdio45_ethtool_gset_npage(&efx->mdio, ecmd, adv, lpa);
 
-       if (efx->phy_type != PHY_TYPE_SFX7101)
+       if (efx->phy_type != PHY_TYPE_SFX7101) {
                ecmd->supported |= (SUPPORTED_100baseT_Full |
                                    SUPPORTED_1000baseT_Full);
+               if (ecmd->speed != SPEED_10000) {
+                       ecmd->eth_tp_mdix =
+                               (efx_mdio_read(efx, MDIO_MMD_PMAPMD,
+                                              PMA_PMD_XSTATUS_REG) &
+                                (1 << PMA_PMD_XSTAT_MDIX_LBN))
+                               ? ETH_TP_MDI_X : ETH_TP_MDI;
+               }
+       }
 
        /* In loopback, the PHY automatically brings up the correct interface,
         * but doesn't advertise the correct speed. So override it */
@@ -813,29 +767,24 @@ static int tenxpress_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
        if (!ecmd->autoneg)
                return -EINVAL;
 
-       return mdio_clause45_set_settings(efx, ecmd);
+       return efx_mdio_set_settings(efx, ecmd);
 }
 
 static void sfx7101_set_npage_adv(struct efx_nic *efx, u32 advertising)
 {
-       mdio_clause45_set_flag(efx, efx->mii.phy_id, MDIO_MMD_AN,
-                              MDIO_AN_10GBT_CTRL,
-                              MDIO_AN_10GBT_CTRL_ADV_10G_LBN,
-                              advertising & ADVERTISED_10000baseT_Full);
+       efx_mdio_set_flag(efx, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL,
+                         MDIO_AN_10GBT_CTRL_ADV10G,
+                         advertising & ADVERTISED_10000baseT_Full);
 }
 
 static void sft9001_set_npage_adv(struct efx_nic *efx, u32 advertising)
 {
-       int phy_id = efx->mii.phy_id;
-
-       mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_C22EXT,
-                              C22EXT_MSTSLV_CTRL,
-                              C22EXT_MSTSLV_CTRL_ADV_1000_FD_LBN,
-                              advertising & ADVERTISED_1000baseT_Full);
-       mdio_clause45_set_flag(efx, phy_id, MDIO_MMD_AN,
-                              MDIO_AN_10GBT_CTRL,
-                              MDIO_AN_10GBT_CTRL_ADV_10G_LBN,
-                              advertising & ADVERTISED_10000baseT_Full);
+       efx_mdio_set_flag(efx, MDIO_MMD_C22EXT, C22EXT_MSTSLV_CTRL,
+                         1 << C22EXT_MSTSLV_CTRL_ADV_1000_FD_LBN,
+                         advertising & ADVERTISED_1000baseT_Full);
+       efx_mdio_set_flag(efx, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL,
+                         MDIO_AN_10GBT_CTRL_ADV10G,
+                         advertising & ADVERTISED_10000baseT_Full);
 }
 
 struct efx_phy_operations falcon_sfx7101_phy_ops = {
index d6681edb7014d799e92ab3978abe2e38c6fd664a..14a14788566c6a4962413eb105f8da6739ea8e77 100644 (file)
@@ -360,13 +360,6 @@ inline int efx_xmit(struct efx_nic *efx,
 
        /* Map fragments for DMA and add to TX queue */
        rc = efx_enqueue_skb(tx_queue, skb);
-       if (unlikely(rc != NETDEV_TX_OK))
-               goto out;
-
-       /* Update last TX timer */
-       efx->net_dev->trans_start = jiffies;
-
- out:
        return rc;
 }
 
diff --git a/drivers/net/sfc/xenpack.h b/drivers/net/sfc/xenpack.h
deleted file mode 100644 (file)
index b0d1f22..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/****************************************************************************
- * Driver for Solarflare Solarstorm network controllers and boards
- * Copyright 2006 Solarflare Communications 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, incorporated herein by reference.
- */
-
-#ifndef EFX_XENPACK_H
-#define EFX_XENPACK_H
-
-/* Exported functions from Xenpack standard PHY control */
-
-#include "mdio_10g.h"
-
-/****************************************************************************/
-/* XENPACK MDIO register extensions */
-#define MDIO_XP_LASI_RX_CTRL   (0x9000)
-#define MDIO_XP_LASI_TX_CTRL   (0x9001)
-#define MDIO_XP_LASI_CTRL      (0x9002)
-#define MDIO_XP_LASI_RX_STAT   (0x9003)
-#define MDIO_XP_LASI_TX_STAT   (0x9004)
-#define MDIO_XP_LASI_STAT      (0x9005)
-
-/* Control/Status bits */
-#define XP_LASI_LS_ALARM       (1 << 0)
-#define XP_LASI_TX_ALARM       (1 << 1)
-#define XP_LASI_RX_ALARM       (1 << 2)
-/* These two are Quake vendor extensions to the standard XENPACK defines */
-#define XP_LASI_LS_INTB                (1 << 3)
-#define XP_LASI_TEST           (1 << 7)
-
-/* Enable LASI interrupts for PHY */
-static inline void xenpack_enable_lasi_irqs(struct efx_nic *efx)
-{
-       int reg;
-       int phy_id = efx->mii.phy_id;
-       /* Read to clear LASI status register */
-       reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PMAPMD,
-                                MDIO_XP_LASI_STAT);
-
-       mdio_clause45_write(efx, phy_id, MDIO_MMD_PMAPMD,
-                           MDIO_XP_LASI_CTRL, XP_LASI_LS_ALARM);
-}
-
-/* Read the LASI interrupt status to clear the interrupt. */
-static inline int xenpack_clear_lasi_irqs(struct efx_nic *efx)
-{
-       /* Read to clear link status alarm */
-       return mdio_clause45_read(efx, efx->mii.phy_id,
-                                 MDIO_MMD_PMAPMD, MDIO_XP_LASI_STAT);
-}
-
-/* Turn off LASI interrupts */
-static inline void xenpack_disable_lasi_irqs(struct efx_nic *efx)
-{
-       mdio_clause45_write(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD,
-                           MDIO_XP_LASI_CTRL, 0);
-}
-
-#endif /* EFX_XENPACK_H */
index bb1ef77d5f56e5b7fcf72533f4bc66db00cdb8ae..bb2e6afd08294fbe63f3571ce87121324b7e1f4f 100644 (file)
 #include <linux/delay.h>
 #include "efx.h"
 #include "mdio_10g.h"
-#include "xenpack.h"
 #include "phy.h"
 #include "falcon.h"
 
-#define XFP_REQUIRED_DEVS (MDIO_MMDREG_DEVS_PCS |      \
-                          MDIO_MMDREG_DEVS_PMAPMD |    \
-                          MDIO_MMDREG_DEVS_PHYXS)
+#define XFP_REQUIRED_DEVS (MDIO_DEVS_PCS |     \
+                          MDIO_DEVS_PMAPMD |   \
+                          MDIO_DEVS_PHYXS)
 
 #define XFP_LOOPBACKS ((1 << LOOPBACK_PCS) |           \
                       (1 << LOOPBACK_PMAPMD) |         \
@@ -49,8 +48,7 @@
 void xfp_set_led(struct efx_nic *p, int led, int mode)
 {
        int addr = MDIO_QUAKE_LED0_REG + led;
-       mdio_clause45_write(p, p->mii.phy_id, MDIO_MMD_PMAPMD, addr,
-                           mode);
+       efx_mdio_write(p, MDIO_MMD_PMAPMD, addr, mode);
 }
 
 struct xfp_phy_data {
@@ -63,14 +61,12 @@ struct xfp_phy_data {
 static int qt2025c_wait_reset(struct efx_nic *efx)
 {
        unsigned long timeout = jiffies + 10 * HZ;
-       int phy_id = efx->mii.phy_id;
        int reg, old_counter = 0;
 
        /* Wait for firmware heartbeat to start */
        for (;;) {
                int counter;
-               reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PCS,
-                                        PCS_FW_HEARTBEAT_REG);
+               reg = efx_mdio_read(efx, MDIO_MMD_PCS, PCS_FW_HEARTBEAT_REG);
                if (reg < 0)
                        return reg;
                counter = ((reg >> PCS_FW_HEARTB_LBN) &
@@ -86,8 +82,7 @@ static int qt2025c_wait_reset(struct efx_nic *efx)
 
        /* Wait for firmware status to look good */
        for (;;) {
-               reg = mdio_clause45_read(efx, phy_id, MDIO_MMD_PCS,
-                                        PCS_UC8051_STATUS_REG);
+               reg = efx_mdio_read(efx, MDIO_MMD_PCS, PCS_UC8051_STATUS_REG);
                if (reg < 0)
                        return reg;
                if ((reg &
@@ -109,9 +104,9 @@ static int xfp_reset_phy(struct efx_nic *efx)
 {
        int rc;
 
-       rc = mdio_clause45_reset_mmd(efx, MDIO_MMD_PHYXS,
-                                    XFP_MAX_RESET_TIME / XFP_RESET_WAIT,
-                                    XFP_RESET_WAIT);
+       rc = efx_mdio_reset_mmd(efx, MDIO_MMD_PHYXS,
+                               XFP_MAX_RESET_TIME / XFP_RESET_WAIT,
+                               XFP_RESET_WAIT);
        if (rc < 0)
                goto fail;
 
@@ -126,8 +121,7 @@ static int xfp_reset_phy(struct efx_nic *efx)
 
        /* Check that all the MMDs we expect are present and responding. We
         * expect faults on some if the link is down, but not on the PHY XS */
-       rc = mdio_clause45_check_mmds(efx, XFP_REQUIRED_DEVS,
-                                     MDIO_MMDREG_DEVS_PHYXS);
+       rc = efx_mdio_check_mmds(efx, XFP_REQUIRED_DEVS, MDIO_DEVS_PHYXS);
        if (rc < 0)
                goto fail;
 
@@ -143,7 +137,7 @@ static int xfp_reset_phy(struct efx_nic *efx)
 static int xfp_phy_init(struct efx_nic *efx)
 {
        struct xfp_phy_data *phy_data;
-       u32 devid = mdio_clause45_read_id(efx, MDIO_MMD_PHYXS);
+       u32 devid = efx_mdio_read_id(efx, MDIO_MMD_PHYXS);
        int rc;
 
        phy_data = kzalloc(sizeof(struct xfp_phy_data), GFP_KERNEL);
@@ -152,8 +146,8 @@ static int xfp_phy_init(struct efx_nic *efx)
        efx->phy_data = phy_data;
 
        EFX_INFO(efx, "PHY ID reg %x (OUI %06x model %02x revision %x)\n",
-                devid, mdio_id_oui(devid), mdio_id_model(devid),
-                mdio_id_rev(devid));
+                devid, efx_mdio_id_oui(devid), efx_mdio_id_model(devid),
+                efx_mdio_id_rev(devid));
 
        phy_data->phy_mode = efx->phy_mode;
 
@@ -174,12 +168,13 @@ static int xfp_phy_init(struct efx_nic *efx)
 
 static void xfp_phy_clear_interrupt(struct efx_nic *efx)
 {
-       xenpack_clear_lasi_irqs(efx);
+       /* Read to clear link status alarm */
+       efx_mdio_read(efx, MDIO_MMD_PMAPMD, MDIO_PMA_LASI_STAT);
 }
 
 static int xfp_link_ok(struct efx_nic *efx)
 {
-       return mdio_clause45_links_ok(efx, XFP_REQUIRED_DEVS);
+       return efx_mdio_links_ok(efx, XFP_REQUIRED_DEVS);
 }
 
 static void xfp_phy_poll(struct efx_nic *efx)
@@ -200,9 +195,9 @@ static void xfp_phy_reconfigure(struct efx_nic *efx)
                 * or optical transceivers, varying somewhat between
                 * firmware versions.  Only 'static mode' appears to
                 * cover everything. */
-               mdio_clause45_set_flag(
-                       efx, efx->mii.phy_id, MDIO_MMD_PMAPMD,
-                       PMA_PMD_FTX_CTRL2_REG, PMA_PMD_FTX_STATIC_LBN,
+               mdio_set_flag(
+                       &efx->mdio, efx->mdio.prtad, MDIO_MMD_PMAPMD,
+                       PMA_PMD_FTX_CTRL2_REG, 1 << PMA_PMD_FTX_STATIC_LBN,
                        efx->phy_mode & PHY_MODE_TX_DISABLED ||
                        efx->phy_mode & PHY_MODE_LOW_POWER ||
                        efx->loopback_mode == LOOPBACK_PCS ||
@@ -213,10 +208,10 @@ static void xfp_phy_reconfigure(struct efx_nic *efx)
                    (phy_data->phy_mode & PHY_MODE_TX_DISABLED))
                        xfp_reset_phy(efx);
 
-               mdio_clause45_transmit_disable(efx);
+               efx_mdio_transmit_disable(efx);
        }
 
-       mdio_clause45_phy_reconfigure(efx);
+       efx_mdio_phy_reconfigure(efx);
 
        phy_data->phy_mode = efx->phy_mode;
        efx->link_up = xfp_link_ok(efx);
@@ -225,6 +220,10 @@ static void xfp_phy_reconfigure(struct efx_nic *efx)
        efx->link_fc = efx->wanted_fc;
 }
 
+static void xfp_phy_get_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
+{
+       mdio45_ethtool_gset(&efx->mdio, ecmd);
+}
 
 static void xfp_phy_fini(struct efx_nic *efx)
 {
@@ -243,8 +242,8 @@ struct efx_phy_operations falcon_xfp_phy_ops = {
        .poll            = xfp_phy_poll,
        .fini            = xfp_phy_fini,
        .clear_interrupt = xfp_phy_clear_interrupt,
-       .get_settings    = mdio_clause45_get_settings,
-       .set_settings    = mdio_clause45_set_settings,
+       .get_settings    = xfp_phy_get_settings,
+       .set_settings    = efx_mdio_set_settings,
        .mmds            = XFP_REQUIRED_DEVS,
        .loopbacks       = XFP_LOOPBACKS,
 };
index 97d68560067dd6e6a3da4be85c48b0e7fd5eacfe..5fb88ca6dd7f9be0189225bbe60ad3c1d0fe8172 100644 (file)
@@ -709,6 +709,17 @@ static inline void setup_rx_ring(struct net_device *dev,
        dma_sync_desc_dev(dev, &buf[i]);
 }
 
+static const struct net_device_ops sgiseeq_netdev_ops = {
+       .ndo_open               = sgiseeq_open,
+       .ndo_stop               = sgiseeq_close,
+       .ndo_start_xmit         = sgiseeq_start_xmit,
+       .ndo_tx_timeout         = timeout,
+       .ndo_set_multicast_list = sgiseeq_set_multicast,
+       .ndo_set_mac_address    = sgiseeq_set_mac_address,
+       .ndo_change_mtu         = eth_change_mtu,
+       .ndo_validate_addr      = eth_validate_addr,
+};
+
 static int __init sgiseeq_probe(struct platform_device *pdev)
 {
        struct sgiseeq_platform_data *pd = pdev->dev.platform_data;
@@ -775,13 +786,8 @@ static int __init sgiseeq_probe(struct platform_device *pdev)
                              SEEQ_CTRL_SFLAG | SEEQ_CTRL_ESHORT |
                              SEEQ_CTRL_ENCARR;
 
-       dev->open               = sgiseeq_open;
-       dev->stop               = sgiseeq_close;
-       dev->hard_start_xmit    = sgiseeq_start_xmit;
-       dev->tx_timeout         = timeout;
+       dev->netdev_ops         = &sgiseeq_netdev_ops;
        dev->watchdog_timeo     = (200 * HZ) / 1000;
-       dev->set_multicast_list = sgiseeq_set_multicast;
-       dev->set_mac_address    = sgiseeq_set_mac_address;
        dev->irq                = irq;
 
        if (register_netdev(dev)) {
index 3ab28bb00c12296095f56bd72ca35dd3a318c1da..341882f959f3c9eb12de2cb5afa4b422062c5636 100644 (file)
@@ -2,7 +2,7 @@
  *  SuperH Ethernet device driver
  *
  *  Copyright (C) 2006-2008 Nobuhiro Iwamatsu
- *  Copyright (C) 2008 Renesas Solutions Corp.
+ *  Copyright (C) 2008-2009 Renesas Solutions Corp.
  *
  *  This program is free software; you can redistribute it and/or modify it
  *  under the terms and conditions of the GNU General Public License,
 
 #include "sh_eth.h"
 
+/* There is CPU dependent code */
+#if defined(CONFIG_CPU_SUBTYPE_SH7724)
+#define SH_ETH_RESET_DEFAULT   1
+static void sh_eth_set_duplex(struct net_device *ndev)
+{
+       struct sh_eth_private *mdp = netdev_priv(ndev);
+       u32 ioaddr = ndev->base_addr;
+
+       if (mdp->duplex) /* Full */
+               ctrl_outl(ctrl_inl(ioaddr + ECMR) | ECMR_DM, ioaddr + ECMR);
+       else            /* Half */
+               ctrl_outl(ctrl_inl(ioaddr + ECMR) & ~ECMR_DM, ioaddr + ECMR);
+}
+
+static void sh_eth_set_rate(struct net_device *ndev)
+{
+       struct sh_eth_private *mdp = netdev_priv(ndev);
+       u32 ioaddr = ndev->base_addr;
+
+       switch (mdp->speed) {
+       case 10: /* 10BASE */
+               ctrl_outl(ctrl_inl(ioaddr + ECMR) & ~ECMR_RTM, ioaddr + ECMR);
+               break;
+       case 100:/* 100BASE */
+               ctrl_outl(ctrl_inl(ioaddr + ECMR) | ECMR_RTM, ioaddr + ECMR);
+               break;
+       default:
+               break;
+       }
+}
+
+/* SH7724 */
+static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
+       .set_duplex     = sh_eth_set_duplex,
+       .set_rate       = sh_eth_set_rate,
+
+       .ecsr_value     = ECSR_PSRTO | ECSR_LCHNG | ECSR_ICD,
+       .ecsipr_value   = ECSIPR_PSRTOIP | ECSIPR_LCHNGIP | ECSIPR_ICDIP,
+       .eesipr_value   = DMAC_M_RFRMER | DMAC_M_ECI | 0x01ff009f,
+
+       .tx_check       = EESR_FTC | EESR_CND | EESR_DLC | EESR_CD | EESR_RTO,
+       .eesr_err_check = EESR_TWB | EESR_TABT | EESR_RABT | EESR_RDE |
+                         EESR_RFRMER | EESR_TFE | EESR_TDE | EESR_ECI,
+       .tx_error_check = EESR_TWB | EESR_TABT | EESR_TDE | EESR_TFE,
+
+       .apr            = 1,
+       .mpr            = 1,
+       .tpauser        = 1,
+       .hw_swap        = 1,
+};
+
+#elif defined(CONFIG_CPU_SUBTYPE_SH7763)
+#define SH_ETH_HAS_TSU 1
+static void sh_eth_chip_reset(struct net_device *ndev)
+{
+       /* reset device */
+       ctrl_outl(ARSTR_ARSTR, ARSTR);
+       mdelay(1);
+}
+
+static void sh_eth_reset(struct net_device *ndev)
+{
+       u32 ioaddr = ndev->base_addr;
+       int cnt = 100;
+
+       ctrl_outl(EDSR_ENALL, ioaddr + EDSR);
+       ctrl_outl(ctrl_inl(ioaddr + EDMR) | EDMR_SRST, ioaddr + EDMR);
+       while (cnt > 0) {
+               if (!(ctrl_inl(ioaddr + EDMR) & 0x3))
+                       break;
+               mdelay(1);
+               cnt--;
+       }
+       if (cnt < 0)
+               printk(KERN_ERR "Device reset fail\n");
+
+       /* Table Init */
+       ctrl_outl(0x0, ioaddr + TDLAR);
+       ctrl_outl(0x0, ioaddr + TDFAR);
+       ctrl_outl(0x0, ioaddr + TDFXR);
+       ctrl_outl(0x0, ioaddr + TDFFR);
+       ctrl_outl(0x0, ioaddr + RDLAR);
+       ctrl_outl(0x0, ioaddr + RDFAR);
+       ctrl_outl(0x0, ioaddr + RDFXR);
+       ctrl_outl(0x0, ioaddr + RDFFR);
+}
+
+static void sh_eth_set_duplex(struct net_device *ndev)
+{
+       struct sh_eth_private *mdp = netdev_priv(ndev);
+       u32 ioaddr = ndev->base_addr;
+
+       if (mdp->duplex) /* Full */
+               ctrl_outl(ctrl_inl(ioaddr + ECMR) | ECMR_DM, ioaddr + ECMR);
+       else            /* Half */
+               ctrl_outl(ctrl_inl(ioaddr + ECMR) & ~ECMR_DM, ioaddr + ECMR);
+}
+
+static void sh_eth_set_rate(struct net_device *ndev)
+{
+       struct sh_eth_private *mdp = netdev_priv(ndev);
+       u32 ioaddr = ndev->base_addr;
+
+       switch (mdp->speed) {
+       case 10: /* 10BASE */
+               ctrl_outl(GECMR_10, ioaddr + GECMR);
+               break;
+       case 100:/* 100BASE */
+               ctrl_outl(GECMR_100, ioaddr + GECMR);
+               break;
+       case 1000: /* 1000BASE */
+               ctrl_outl(GECMR_1000, ioaddr + GECMR);
+               break;
+       default:
+               break;
+       }
+}
+
+/* sh7763 */
+static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
+       .chip_reset     = sh_eth_chip_reset,
+       .set_duplex     = sh_eth_set_duplex,
+       .set_rate       = sh_eth_set_rate,
+
+       .ecsr_value     = ECSR_ICD | ECSR_MPD,
+       .ecsipr_value   = ECSIPR_LCHNGIP | ECSIPR_ICDIP | ECSIPR_MPDIP,
+       .eesipr_value   = DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff,
+
+       .tx_check       = EESR_TC1 | EESR_FTC,
+       .eesr_err_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT | \
+                         EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE | \
+                         EESR_ECI,
+       .tx_error_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_TDE | \
+                         EESR_TFE,
+
+       .apr            = 1,
+       .mpr            = 1,
+       .tpauser        = 1,
+       .bculr          = 1,
+       .hw_swap        = 1,
+       .rpadir         = 1,
+       .no_trimd       = 1,
+       .no_ade         = 1,
+};
+
+#elif defined(CONFIG_CPU_SUBTYPE_SH7619)
+#define SH_ETH_RESET_DEFAULT   1
+static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
+       .eesipr_value   = DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff,
+
+       .apr            = 1,
+       .mpr            = 1,
+       .tpauser        = 1,
+       .hw_swap        = 1,
+};
+#elif defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712)
+#define SH_ETH_RESET_DEFAULT   1
+#define SH_ETH_HAS_TSU 1
+static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
+       .eesipr_value   = DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff,
+};
+#endif
+
+static void sh_eth_set_default_cpu_data(struct sh_eth_cpu_data *cd)
+{
+       if (!cd->ecsr_value)
+               cd->ecsr_value = DEFAULT_ECSR_INIT;
+
+       if (!cd->ecsipr_value)
+               cd->ecsipr_value = DEFAULT_ECSIPR_INIT;
+
+       if (!cd->fcftr_value)
+               cd->fcftr_value = DEFAULT_FIFO_F_D_RFF | \
+                                 DEFAULT_FIFO_F_D_RFD;
+
+       if (!cd->fdr_value)
+               cd->fdr_value = DEFAULT_FDR_INIT;
+
+       if (!cd->rmcr_value)
+               cd->rmcr_value = DEFAULT_RMCR_VALUE;
+
+       if (!cd->tx_check)
+               cd->tx_check = DEFAULT_TX_CHECK;
+
+       if (!cd->eesr_err_check)
+               cd->eesr_err_check = DEFAULT_EESR_ERR_CHECK;
+
+       if (!cd->tx_error_check)
+               cd->tx_error_check = DEFAULT_TX_ERROR_CHECK;
+}
+
+#if defined(SH_ETH_RESET_DEFAULT)
+/* Chip Reset */
+static void sh_eth_reset(struct net_device *ndev)
+{
+       u32 ioaddr = ndev->base_addr;
+
+       ctrl_outl(ctrl_inl(ioaddr + EDMR) | EDMR_SRST, ioaddr + EDMR);
+       mdelay(3);
+       ctrl_outl(ctrl_inl(ioaddr + EDMR) & ~EDMR_SRST, ioaddr + EDMR);
+}
+#endif
+
+#if defined(CONFIG_CPU_SH4)
+static void sh_eth_set_receive_align(struct sk_buff *skb)
+{
+       int reserve;
+
+       reserve = SH4_SKB_RX_ALIGN - ((u32)skb->data & (SH4_SKB_RX_ALIGN - 1));
+       if (reserve)
+               skb_reserve(skb, reserve);
+}
+#else
+static void sh_eth_set_receive_align(struct sk_buff *skb)
+{
+       skb_reserve(skb, SH2_SH3_SKB_RX_ALIGN);
+}
+#endif
+
+
 /* CPU <-> EDMAC endian convert */
 static inline __u32 cpu_to_edmac(struct sh_eth_private *mdp, u32 x)
 {
@@ -165,41 +385,6 @@ static struct mdiobb_ops bb_ops = {
        .get_mdio_data = sh_get_mdio,
 };
 
-/* Chip Reset */
-static void sh_eth_reset(struct net_device *ndev)
-{
-       u32 ioaddr = ndev->base_addr;
-
-#if defined(CONFIG_CPU_SUBTYPE_SH7763)
-       int cnt = 100;
-
-       ctrl_outl(EDSR_ENALL, ioaddr + EDSR);
-       ctrl_outl(ctrl_inl(ioaddr + EDMR) | EDMR_SRST, ioaddr + EDMR);
-       while (cnt > 0) {
-               if (!(ctrl_inl(ioaddr + EDMR) & 0x3))
-                       break;
-               mdelay(1);
-               cnt--;
-       }
-       if (cnt < 0)
-               printk(KERN_ERR "Device reset fail\n");
-
-       /* Table Init */
-       ctrl_outl(0x0, ioaddr + TDLAR);
-       ctrl_outl(0x0, ioaddr + TDFAR);
-       ctrl_outl(0x0, ioaddr + TDFXR);
-       ctrl_outl(0x0, ioaddr + TDFFR);
-       ctrl_outl(0x0, ioaddr + RDLAR);
-       ctrl_outl(0x0, ioaddr + RDFAR);
-       ctrl_outl(0x0, ioaddr + RDFXR);
-       ctrl_outl(0x0, ioaddr + RDFFR);
-#else
-       ctrl_outl(ctrl_inl(ioaddr + EDMR) | EDMR_SRST, ioaddr + EDMR);
-       mdelay(3);
-       ctrl_outl(ctrl_inl(ioaddr + EDMR) & ~EDMR_SRST, ioaddr + EDMR);
-#endif
-}
-
 /* free skb and descriptor buffer */
 static void sh_eth_ring_free(struct net_device *ndev)
 {
@@ -228,7 +413,7 @@ static void sh_eth_ring_free(struct net_device *ndev)
 /* format skb and descriptor buffer */
 static void sh_eth_ring_format(struct net_device *ndev)
 {
-       u32 ioaddr = ndev->base_addr, reserve = 0;
+       u32 ioaddr = ndev->base_addr;
        struct sh_eth_private *mdp = netdev_priv(ndev);
        int i;
        struct sk_buff *skb;
@@ -250,37 +435,27 @@ static void sh_eth_ring_format(struct net_device *ndev)
                mdp->rx_skbuff[i] = skb;
                if (skb == NULL)
                        break;
+               dma_map_single(&ndev->dev, skb->tail, mdp->rx_buf_sz,
+                               DMA_FROM_DEVICE);
                skb->dev = ndev; /* Mark as being used by this device. */
-#if defined(CONFIG_CPU_SUBTYPE_SH7763)
-               reserve = SH7763_SKB_ALIGN
-                       - ((uint32_t)skb->data & (SH7763_SKB_ALIGN-1));
-               if (reserve)
-                       skb_reserve(skb, reserve);
-#else
-               skb_reserve(skb, RX_OFFSET);
-#endif
+               sh_eth_set_receive_align(skb);
+
                /* RX descriptor */
                rxdesc = &mdp->rx_ring[i];
-               rxdesc->addr = (u32)skb->data & ~0x3UL;
+               rxdesc->addr = virt_to_phys(PTR_ALIGN(skb->data, 4));
                rxdesc->status = cpu_to_edmac(mdp, RD_RACT | RD_RFP);
 
                /* The size of the buffer is 16 byte boundary. */
-               rxdesc->buffer_length = (mdp->rx_buf_sz + 16) & ~0x0F;
+               rxdesc->buffer_length = ALIGN(mdp->rx_buf_sz, 16);
                /* Rx descriptor address set */
                if (i == 0) {
-                       ctrl_outl((u32)rxdesc, ioaddr + RDLAR);
+                       ctrl_outl(mdp->rx_desc_dma, ioaddr + RDLAR);
 #if defined(CONFIG_CPU_SUBTYPE_SH7763)
-                       ctrl_outl((u32)rxdesc, ioaddr + RDFAR);
+                       ctrl_outl(mdp->rx_desc_dma, ioaddr + RDFAR);
 #endif
                }
        }
 
-       /* Rx descriptor address set */
-#if defined(CONFIG_CPU_SUBTYPE_SH7763)
-       ctrl_outl((u32)rxdesc, ioaddr + RDFXR);
-       ctrl_outl(0x1, ioaddr + RDFFR);
-#endif
-
        mdp->dirty_rx = (u32) (i - RX_RING_SIZE);
 
        /* Mark the last entry as wrapping the ring. */
@@ -296,19 +471,13 @@ static void sh_eth_ring_format(struct net_device *ndev)
                txdesc->buffer_length = 0;
                if (i == 0) {
                        /* Tx descriptor address set */
-                       ctrl_outl((u32)txdesc, ioaddr + TDLAR);
+                       ctrl_outl(mdp->tx_desc_dma, ioaddr + TDLAR);
 #if defined(CONFIG_CPU_SUBTYPE_SH7763)
-                       ctrl_outl((u32)txdesc, ioaddr + TDFAR);
+                       ctrl_outl(mdp->tx_desc_dma, ioaddr + TDFAR);
 #endif
                }
        }
 
-       /* Tx descriptor address set */
-#if defined(CONFIG_CPU_SUBTYPE_SH7763)
-       ctrl_outl((u32)txdesc, ioaddr + TDFXR);
-       ctrl_outl(0x1, ioaddr + TDFFR);
-#endif
-
        txdesc->status |= cpu_to_edmac(mdp, TD_TDLE);
 }
 
@@ -331,7 +500,7 @@ static int sh_eth_ring_init(struct net_device *ndev)
        mdp->rx_skbuff = kmalloc(sizeof(*mdp->rx_skbuff) * RX_RING_SIZE,
                                GFP_KERNEL);
        if (!mdp->rx_skbuff) {
-               printk(KERN_ERR "%s: Cannot allocate Rx skb\n", ndev->name);
+               dev_err(&ndev->dev, "Cannot allocate Rx skb\n");
                ret = -ENOMEM;
                return ret;
        }
@@ -339,7 +508,7 @@ static int sh_eth_ring_init(struct net_device *ndev)
        mdp->tx_skbuff = kmalloc(sizeof(*mdp->tx_skbuff) * TX_RING_SIZE,
                                GFP_KERNEL);
        if (!mdp->tx_skbuff) {
-               printk(KERN_ERR "%s: Cannot allocate Tx skb\n", ndev->name);
+               dev_err(&ndev->dev, "Cannot allocate Tx skb\n");
                ret = -ENOMEM;
                goto skb_ring_free;
        }
@@ -350,8 +519,8 @@ static int sh_eth_ring_init(struct net_device *ndev)
                        GFP_KERNEL);
 
        if (!mdp->rx_ring) {
-               printk(KERN_ERR "%s: Cannot allocate Rx Ring (size %d bytes)\n",
-                       ndev->name, rx_ringsize);
+               dev_err(&ndev->dev, "Cannot allocate Rx Ring (size %d bytes)\n",
+                       rx_ringsize);
                ret = -ENOMEM;
                goto desc_ring_free;
        }
@@ -363,8 +532,8 @@ static int sh_eth_ring_init(struct net_device *ndev)
        mdp->tx_ring = dma_alloc_coherent(NULL, tx_ringsize, &mdp->tx_desc_dma,
                        GFP_KERNEL);
        if (!mdp->tx_ring) {
-               printk(KERN_ERR "%s: Cannot allocate Tx Ring (size %d bytes)\n",
-                       ndev->name, tx_ringsize);
+               dev_err(&ndev->dev, "Cannot allocate Tx Ring (size %d bytes)\n",
+                       tx_ringsize);
                ret = -ENOMEM;
                goto desc_ring_free;
        }
@@ -394,44 +563,43 @@ static int sh_eth_dev_init(struct net_device *ndev)
 
        /* Descriptor format */
        sh_eth_ring_format(ndev);
-       ctrl_outl(RPADIR_INIT, ioaddr + RPADIR);
+       if (mdp->cd->rpadir)
+               ctrl_outl(mdp->cd->rpadir_value, ioaddr + RPADIR);
 
        /* all sh_eth int mask */
        ctrl_outl(0, ioaddr + EESIPR);
 
-#if defined(CONFIG_CPU_SUBTYPE_SH7763)
-       ctrl_outl(EDMR_EL, ioaddr + EDMR);
-#else
-       ctrl_outl(0, ioaddr + EDMR);    /* Endian change */
+#if defined(__LITTLE_ENDIAN__)
+       if (mdp->cd->hw_swap)
+               ctrl_outl(EDMR_EL, ioaddr + EDMR);
+       else
 #endif
+               ctrl_outl(0, ioaddr + EDMR);
 
        /* FIFO size set */
-       ctrl_outl((FIFO_SIZE_T | FIFO_SIZE_R), ioaddr + FDR);
+       ctrl_outl(mdp->cd->fdr_value, ioaddr + FDR);
        ctrl_outl(0, ioaddr + TFTR);
 
        /* Frame recv control */
-       ctrl_outl(0, ioaddr + RMCR);
+       ctrl_outl(mdp->cd->rmcr_value, ioaddr + RMCR);
 
        rx_int_var = mdp->rx_int_var = DESC_I_RINT8 | DESC_I_RINT5;
        tx_int_var = mdp->tx_int_var = DESC_I_TINT2;
        ctrl_outl(rx_int_var | tx_int_var, ioaddr + TRSCER);
 
-#if defined(CONFIG_CPU_SUBTYPE_SH7763)
-       /* Burst sycle set */
-       ctrl_outl(0x800, ioaddr + BCULR);
-#endif
+       if (mdp->cd->bculr)
+               ctrl_outl(0x800, ioaddr + BCULR);       /* Burst sycle set */
 
-       ctrl_outl((FIFO_F_D_RFF | FIFO_F_D_RFD), ioaddr + FCFTR);
+       ctrl_outl(mdp->cd->fcftr_value, ioaddr + FCFTR);
 
-#if !defined(CONFIG_CPU_SUBTYPE_SH7763)
-       ctrl_outl(0, ioaddr + TRIMD);
-#endif
+       if (!mdp->cd->no_trimd)
+               ctrl_outl(0, ioaddr + TRIMD);
 
        /* Recv frame limit set register */
        ctrl_outl(RFLR_VALUE, ioaddr + RFLR);
 
        ctrl_outl(ctrl_inl(ioaddr + EESR), ioaddr + EESR);
-       ctrl_outl((DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff), ioaddr + EESIPR);
+       ctrl_outl(mdp->cd->eesipr_value, ioaddr + EESIPR);
 
        /* PAUSE Prohibition */
        val = (ctrl_inl(ioaddr + ECMR) & ECMR_DM) |
@@ -439,24 +607,25 @@ static int sh_eth_dev_init(struct net_device *ndev)
 
        ctrl_outl(val, ioaddr + ECMR);
 
+       if (mdp->cd->set_rate)
+               mdp->cd->set_rate(ndev);
+
        /* E-MAC Status Register clear */
-       ctrl_outl(ECSR_INIT, ioaddr + ECSR);
+       ctrl_outl(mdp->cd->ecsr_value, ioaddr + ECSR);
 
        /* E-MAC Interrupt Enable register */
-       ctrl_outl(ECSIPR_INIT, ioaddr + ECSIPR);
+       ctrl_outl(mdp->cd->ecsipr_value, ioaddr + ECSIPR);
 
        /* Set MAC address */
        update_mac_address(ndev);
 
        /* mask reset */
-#if defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7763)
-       ctrl_outl(APR_AP, ioaddr + APR);
-       ctrl_outl(MPR_MP, ioaddr + MPR);
-       ctrl_outl(TPAUSER_UNLIMITED, ioaddr + TPAUSER);
-#endif
-#if defined(CONFIG_CPU_SUBTYPE_SH7710)
-       ctrl_outl(BCFR_UNLIMITED, ioaddr + BCFR);
-#endif
+       if (mdp->cd->apr)
+               ctrl_outl(APR_AP, ioaddr + APR);
+       if (mdp->cd->mpr)
+               ctrl_outl(MPR_MP, ioaddr + MPR);
+       if (mdp->cd->tpauser)
+               ctrl_outl(TPAUSER_UNLIMITED, ioaddr + TPAUSER);
 
        /* Setting the Rx mode will start the Rx process. */
        ctrl_outl(EDRRR_R, ioaddr + EDRRR);
@@ -505,7 +674,7 @@ static int sh_eth_rx(struct net_device *ndev)
        int boguscnt = (mdp->dirty_rx + RX_RING_SIZE) - mdp->cur_rx;
        struct sk_buff *skb;
        u16 pkt_len = 0;
-       u32 desc_status, reserve = 0;
+       u32 desc_status;
 
        rxdesc = &mdp->rx_ring[entry];
        while (!(rxdesc->status & cpu_to_edmac(mdp, RD_RACT))) {
@@ -534,7 +703,10 @@ static int sh_eth_rx(struct net_device *ndev)
                        if (desc_status & RD_RFS10)
                                mdp->stats.rx_over_errors++;
                } else {
-                       swaps((char *)(rxdesc->addr & ~0x3), pkt_len + 2);
+                       if (!mdp->cd->hw_swap)
+                               sh_eth_soft_swap(
+                                       phys_to_virt(ALIGN(rxdesc->addr, 4)),
+                                       pkt_len + 2);
                        skb = mdp->rx_skbuff[entry];
                        mdp->rx_skbuff[entry] = NULL;
                        skb_put(skb, pkt_len);
@@ -545,6 +717,7 @@ static int sh_eth_rx(struct net_device *ndev)
                }
                rxdesc->status |= cpu_to_edmac(mdp, RD_RACT);
                entry = (++mdp->cur_rx) % RX_RING_SIZE;
+               rxdesc = &mdp->rx_ring[entry];
        }
 
        /* Refill the Rx ring buffers. */
@@ -552,24 +725,20 @@ static int sh_eth_rx(struct net_device *ndev)
                entry = mdp->dirty_rx % RX_RING_SIZE;
                rxdesc = &mdp->rx_ring[entry];
                /* The size of the buffer is 16 byte boundary. */
-               rxdesc->buffer_length = (mdp->rx_buf_sz + 16) & ~0x0F;
+               rxdesc->buffer_length = ALIGN(mdp->rx_buf_sz, 16);
 
                if (mdp->rx_skbuff[entry] == NULL) {
                        skb = dev_alloc_skb(mdp->rx_buf_sz);
                        mdp->rx_skbuff[entry] = skb;
                        if (skb == NULL)
                                break;  /* Better luck next round. */
+                       dma_map_single(&ndev->dev, skb->tail, mdp->rx_buf_sz,
+                                       DMA_FROM_DEVICE);
                        skb->dev = ndev;
-#if defined(CONFIG_CPU_SUBTYPE_SH7763)
-                       reserve = SH7763_SKB_ALIGN
-                               - ((uint32_t)skb->data & (SH7763_SKB_ALIGN-1));
-                       if (reserve)
-                               skb_reserve(skb, reserve);
-#else
-                       skb_reserve(skb, RX_OFFSET);
-#endif
+                       sh_eth_set_receive_align(skb);
+
                        skb->ip_summed = CHECKSUM_NONE;
-                       rxdesc->addr = (u32)skb->data & ~0x3UL;
+                       rxdesc->addr = virt_to_phys(PTR_ALIGN(skb->data, 4));
                }
                if (entry >= RX_RING_SIZE - 1)
                        rxdesc->status |=
@@ -593,6 +762,8 @@ static void sh_eth_error(struct net_device *ndev, int intr_status)
        struct sh_eth_private *mdp = netdev_priv(ndev);
        u32 ioaddr = ndev->base_addr;
        u32 felic_stat;
+       u32 link_stat;
+       u32 mask;
 
        if (intr_status & EESR_ECI) {
                felic_stat = ctrl_inl(ioaddr + ECSR);
@@ -601,7 +772,14 @@ static void sh_eth_error(struct net_device *ndev, int intr_status)
                        mdp->stats.tx_carrier_errors++;
                if (felic_stat & ECSR_LCHNG) {
                        /* Link Changed */
-                       u32 link_stat = (ctrl_inl(ioaddr + PSR));
+                       if (mdp->cd->no_psr) {
+                               if (mdp->link == PHY_DOWN)
+                                       link_stat = 0;
+                               else
+                                       link_stat = PHY_ST_LINK;
+                       } else {
+                               link_stat = (ctrl_inl(ioaddr + PSR));
+                       }
                        if (!(link_stat & PHY_ST_LINK)) {
                                /* Link Down : disable tx and rx */
                                ctrl_outl(ctrl_inl(ioaddr + ECMR) &
@@ -633,17 +811,15 @@ static void sh_eth_error(struct net_device *ndev, int intr_status)
                if (intr_status & EESR_RFRMER) {
                        /* Receive Frame Overflow int */
                        mdp->stats.rx_frame_errors++;
-                       printk(KERN_ERR "Receive Frame Overflow\n");
+                       dev_err(&ndev->dev, "Receive Frame Overflow\n");
                }
        }
-#if !defined(CONFIG_CPU_SUBTYPE_SH7763)
-       if (intr_status & EESR_ADE) {
-               if (intr_status & EESR_TDE) {
-                       if (intr_status & EESR_TFE)
-                               mdp->stats.tx_fifo_errors++;
-               }
+
+       if (!mdp->cd->no_ade) {
+               if (intr_status & EESR_ADE && intr_status & EESR_TDE &&
+                   intr_status & EESR_TFE)
+                       mdp->stats.tx_fifo_errors++;
        }
-#endif
 
        if (intr_status & EESR_RDE) {
                /* Receive Descriptor Empty int */
@@ -651,24 +827,24 @@ static void sh_eth_error(struct net_device *ndev, int intr_status)
 
                if (ctrl_inl(ioaddr + EDRRR) ^ EDRRR_R)
                        ctrl_outl(EDRRR_R, ioaddr + EDRRR);
-               printk(KERN_ERR "Receive Descriptor Empty\n");
+               dev_err(&ndev->dev, "Receive Descriptor Empty\n");
        }
        if (intr_status & EESR_RFE) {
                /* Receive FIFO Overflow int */
                mdp->stats.rx_fifo_errors++;
-               printk(KERN_ERR "Receive FIFO Overflow\n");
+               dev_err(&ndev->dev, "Receive FIFO Overflow\n");
        }
-       if (intr_status & (EESR_TWB | EESR_TABT |
-#if !defined(CONFIG_CPU_SUBTYPE_SH7763)
-                       EESR_ADE |
-#endif
-                       EESR_TDE | EESR_TFE)) {
+
+       mask = EESR_TWB | EESR_TABT | EESR_ADE | EESR_TDE | EESR_TFE;
+       if (mdp->cd->no_ade)
+               mask &= ~EESR_ADE;
+       if (intr_status & mask) {
                /* Tx error */
                u32 edtrr = ctrl_inl(ndev->base_addr + EDTRR);
                /* dmesg */
-               printk(KERN_ERR "%s:TX error. status=%8.8x cur_tx=%8.8x ",
-                               ndev->name, intr_status, mdp->cur_tx);
-               printk(KERN_ERR "dirty_tx=%8.8x state=%8.8x EDTRR=%8.8x.\n",
+               dev_err(&ndev->dev, "TX error. status=%8.8x cur_tx=%8.8x ",
+                               intr_status, mdp->cur_tx);
+               dev_err(&ndev->dev, "dirty_tx=%8.8x state=%8.8x EDTRR=%8.8x.\n",
                                mdp->dirty_tx, (u32) ndev->state, edtrr);
                /* dirty buffer free */
                sh_eth_txfree(ndev);
@@ -687,6 +863,7 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev)
 {
        struct net_device *ndev = netdev;
        struct sh_eth_private *mdp = netdev_priv(ndev);
+       struct sh_eth_cpu_data *cd = mdp->cd;
        irqreturn_t ret = IRQ_NONE;
        u32 ioaddr, boguscnt = RX_RING_SIZE;
        u32 intr_status = 0;
@@ -699,7 +876,7 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev)
        /* Clear interrupt */
        if (intr_status & (EESR_FRC | EESR_RMAF | EESR_RRF |
                        EESR_RTLF | EESR_RTSF | EESR_PRE | EESR_CERF |
-                       TX_CHECK | EESR_ERR_CHECK)) {
+                       cd->tx_check | cd->eesr_err_check)) {
                ctrl_outl(intr_status, ioaddr + EESR);
                ret = IRQ_HANDLED;
        } else
@@ -716,12 +893,12 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev)
        }
 
        /* Tx Check */
-       if (intr_status & TX_CHECK) {
+       if (intr_status & cd->tx_check) {
                sh_eth_txfree(ndev);
                netif_wake_queue(ndev);
        }
 
-       if (intr_status & EESR_ERR_CHECK)
+       if (intr_status & cd->eesr_err_check)
                sh_eth_error(ndev, intr_status);
 
        if (--boguscnt < 0) {
@@ -756,32 +933,15 @@ static void sh_eth_adjust_link(struct net_device *ndev)
                if (phydev->duplex != mdp->duplex) {
                        new_state = 1;
                        mdp->duplex = phydev->duplex;
-#if defined(CONFIG_CPU_SUBTYPE_SH7763)
-                       if (mdp->duplex) { /*  FULL */
-                               ctrl_outl(ctrl_inl(ioaddr + ECMR) | ECMR_DM,
-                                               ioaddr + ECMR);
-                       } else {        /* Half */
-                               ctrl_outl(ctrl_inl(ioaddr + ECMR) & ~ECMR_DM,
-                                               ioaddr + ECMR);
-                       }
-#endif
+                       if (mdp->cd->set_duplex)
+                               mdp->cd->set_duplex(ndev);
                }
 
                if (phydev->speed != mdp->speed) {
                        new_state = 1;
                        mdp->speed = phydev->speed;
-#if defined(CONFIG_CPU_SUBTYPE_SH7763)
-                       switch (mdp->speed) {
-                       case 10: /* 10BASE */
-                               ctrl_outl(GECMR_10, ioaddr + GECMR); break;
-                       case 100:/* 100BASE */
-                               ctrl_outl(GECMR_100, ioaddr + GECMR); break;
-                       case 1000: /* 1000BASE */
-                               ctrl_outl(GECMR_1000, ioaddr + GECMR); break;
-                       default:
-                               break;
-                       }
-#endif
+                       if (mdp->cd->set_rate)
+                               mdp->cd->set_rate(ndev);
                }
                if (mdp->link == PHY_DOWN) {
                        ctrl_outl((ctrl_inl(ioaddr + ECMR) & ~ECMR_TXF)
@@ -804,7 +964,7 @@ static void sh_eth_adjust_link(struct net_device *ndev)
 static int sh_eth_phy_init(struct net_device *ndev)
 {
        struct sh_eth_private *mdp = netdev_priv(ndev);
-       char phy_id[BUS_ID_SIZE];
+       char phy_id[MII_BUS_ID_SIZE + 3];
        struct phy_device *phydev = NULL;
 
        snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT,
@@ -821,8 +981,9 @@ static int sh_eth_phy_init(struct net_device *ndev)
                dev_err(&ndev->dev, "phy_connect failed\n");
                return PTR_ERR(phydev);
        }
+
        dev_info(&ndev->dev, "attached phy %i to driver %s\n",
-       phydev->addr, phydev->drv->name);
+               phydev->addr, phydev->drv->name);
 
        mdp->phydev = phydev;
 
@@ -860,7 +1021,7 @@ static int sh_eth_open(struct net_device *ndev)
 #endif
                                ndev->name, ndev);
        if (ret) {
-               printk(KERN_ERR "Can not assign IRQ number to %s\n", CARDNAME);
+               dev_err(&ndev->dev, "Can not assign IRQ number\n");
                return ret;
        }
 
@@ -947,7 +1108,7 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev)
                if (!sh_eth_txfree(ndev)) {
                        netif_stop_queue(ndev);
                        spin_unlock_irqrestore(&mdp->lock, flags);
-                       return 1;
+                       return NETDEV_TX_BUSY;
                }
        }
        spin_unlock_irqrestore(&mdp->lock, flags);
@@ -955,9 +1116,11 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev)
        entry = mdp->cur_tx % TX_RING_SIZE;
        mdp->tx_skbuff[entry] = skb;
        txdesc = &mdp->tx_ring[entry];
-       txdesc->addr = (u32)(skb->data);
+       txdesc->addr = virt_to_phys(skb->data);
        /* soft swap. */
-       swaps((char *)(txdesc->addr & ~0x3), skb->len + 2);
+       if (!mdp->cd->hw_swap)
+               sh_eth_soft_swap(phys_to_virt(ALIGN(txdesc->addr, 4)),
+                                skb->len + 2);
        /* write back */
        __flush_purge_region(skb->data, skb->len);
        if (skb->len < ETHERSMALL)
@@ -1059,7 +1222,7 @@ static int sh_eth_do_ioctl(struct net_device *ndev, struct ifreq *rq,
        return phy_mii_ioctl(phydev, if_mii(rq), cmd);
 }
 
-
+#if defined(SH_ETH_HAS_TSU)
 /* Multicast reception directions set */
 static void sh_eth_set_multicast_list(struct net_device *ndev)
 {
@@ -1104,6 +1267,7 @@ static void sh_eth_tsu_init(u32 ioaddr)
        ctrl_outl(0, ioaddr + TSU_POST3);       /* Disable CAM entry [16-23] */
        ctrl_outl(0, ioaddr + TSU_POST4);       /* Disable CAM entry [24-31] */
 }
+#endif /* SH_ETH_HAS_TSU */
 
 /* MDIO bus release function */
 static int sh_mdio_release(struct net_device *ndev)
@@ -1193,7 +1357,9 @@ static const struct net_device_ops sh_eth_netdev_ops = {
        .ndo_stop               = sh_eth_close,
        .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,
+#endif
        .ndo_tx_timeout         = sh_eth_tx_timeout,
        .ndo_do_ioctl           = sh_eth_do_ioctl,
        .ndo_validate_addr      = eth_validate_addr,
@@ -1219,7 +1385,7 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
 
        ndev = alloc_etherdev(sizeof(struct sh_eth_private));
        if (!ndev) {
-               printk(KERN_ERR "%s: could not allocate device.\n", CARDNAME);
+               dev_err(&pdev->dev, "Could not allocate device.\n");
                ret = -ENOMEM;
                goto out;
        }
@@ -1252,6 +1418,10 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
        /* EDMAC endian */
        mdp->edmac_endian = pd->edmac_endian;
 
+       /* set cpu data */
+       mdp->cd = &sh_eth_my_cpu_data;
+       sh_eth_set_default_cpu_data(mdp->cd);
+
        /* set function */
        ndev->netdev_ops = &sh_eth_netdev_ops;
        ndev->watchdog_timeo = TX_TIMEOUT;
@@ -1264,13 +1434,10 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
 
        /* First device only init */
        if (!devno) {
-#if defined(ARSTR)
-               /* reset device */
-               ctrl_outl(ARSTR_ARSTR, ARSTR);
-               mdelay(1);
-#endif
+               if (mdp->cd->chip_reset)
+                       mdp->cd->chip_reset(ndev);
 
-#if defined(SH_TSU_ADDR)
+#if defined(SH_ETH_HAS_TSU)
                /* TSU init (Init only)*/
                sh_eth_tsu_init(SH_TSU_ADDR);
 #endif
@@ -1287,8 +1454,8 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
                goto out_unregister;
 
        /* pritnt device infomation */
-       printk(KERN_INFO "%s: %s at 0x%x, ",
-              ndev->name, CARDNAME, (u32) ndev->base_addr);
+       pr_info("Base address at 0x%x, ",
+              (u32)ndev->base_addr);
 
        for (i = 0; i < 5; i++)
                printk("%02X:", ndev->dev_addr[i]);
index 1537e13e623d5e650056de4453a4a3d9c8c5e25e..9afe5b4c855d4f15429eccb7cca36f09e468fe83 100644 (file)
@@ -2,7 +2,7 @@
  *  SuperH Ethernet device driver
  *
  *  Copyright (C) 2006-2008 Nobuhiro Iwamatsu
- *  Copyright (C) 2008 Renesas Solutions Corp.
+ *  Copyright (C) 2008-2009 Renesas Solutions Corp.
  *
  *  This program is free software; you can redistribute it and/or modify it
  *  under the terms and conditions of the GNU General Public License,
 #define ETHERSMALL             60
 #define PKT_BUF_SZ             1538
 
-#ifdef CONFIG_CPU_SUBTYPE_SH7763
+#if defined(CONFIG_CPU_SUBTYPE_SH7763)
+/* This CPU register maps is very difference by other SH4 CPU */
 
-#define SH7763_SKB_ALIGN 32
 /* Chip Base Address */
 # define SH_TSU_ADDR   0xFEE01800
-# define ARSTR                 SH_TSU_ADDR
+# define ARSTR         SH_TSU_ADDR
 
 /* Chip Registers */
 /* E-DMAC */
 # define FWNLCR1         0xB0
 # define FWALCR1         0x40
 
-#else /* CONFIG_CPU_SUBTYPE_SH7763 */
-# define RX_OFFSET 2   /* skb offset */
+#elif defined(CONFIG_CPU_SH4)  /* #if defined(CONFIG_CPU_SUBTYPE_SH7763) */
+/* EtherC */
+#define ECMR           0x100
+#define RFLR           0x108
+#define ECSR           0x110
+#define ECSIPR         0x118
+#define PIR            0x120
+#define PSR            0x128
+#define RDMLR          0x140
+#define IPGR           0x150
+#define APR            0x154
+#define MPR            0x158
+#define TPAUSER                0x164
+#define RFCF           0x160
+#define TPAUSECR       0x168
+#define BCFRR          0x16c
+#define MAHR           0x1c0
+#define MALR           0x1c8
+#define TROCR          0x1d0
+#define CDCR           0x1d4
+#define LCCR           0x1d8
+#define CNDCR          0x1dc
+#define CEFCR          0x1e4
+#define FRECR          0x1e8
+#define TSFRCR         0x1ec
+#define TLFRCR         0x1f0
+#define RFCR           0x1f4
+#define MAFCR          0x1f8
+#define RTRATE         0x1fc
+
+/* E-DMAC */
+#define EDMR           0x000
+#define EDTRR          0x008
+#define EDRRR          0x010
+#define TDLAR          0x018
+#define RDLAR          0x020
+#define EESR           0x028
+#define EESIPR         0x030
+#define TRSCER         0x038
+#define RMFCR          0x040
+#define TFTR           0x048
+#define FDR            0x050
+#define RMCR           0x058
+#define TFUCR          0x064
+#define RFOCR          0x068
+#define FCFTR          0x070
+#define RPADIR         0x078
+#define TRIMD          0x07c
+#define RBWAR          0x0c8
+#define RDFAR          0x0cc
+#define TBRAR          0x0d4
+#define TDFAR          0x0d8
+#else /* #elif defined(CONFIG_CPU_SH4) */
+/* This section is SH3 or SH2 */
 #ifndef CONFIG_CPU_SUBTYPE_SH7619
 /* Chip base address */
 # define SH_TSU_ADDR  0xA7000804
 
 #endif /* CONFIG_CPU_SUBTYPE_SH7763 */
 
+/* There are avoid compile error... */
+#if !defined(BCULR)
+#define BCULR  0x0fc
+#endif
+#if !defined(TRIMD)
+#define TRIMD  0x0fc
+#endif
+#if !defined(APR)
+#define APR    0x0fc
+#endif
+#if !defined(MPR)
+#define MPR    0x0fc
+#endif
+#if !defined(TPAUSER)
+#define TPAUSER        0x0fc
+#endif
+
+/* Driver's parameters */
+#if defined(CONFIG_CPU_SH4)
+#define SH4_SKB_RX_ALIGN       32
+#else
+#define SH2_SH3_SKB_RX_ALIGN   2
+#endif
+
 /*
  * Register's bits
  */
@@ -261,11 +337,10 @@ enum GECMR_BIT {
 
 /* EDMR */
 enum DMAC_M_BIT {
+       EDMR_EL = 0x40, /* Litte endian */
        EDMR_DL1 = 0x20, EDMR_DL0 = 0x10,
 #ifdef CONFIG_CPU_SUBTYPE_SH7763
-       EDMR_SRST       = 0x03,
-       EMDR_DESC_R     = 0x30, /* Descriptor reserve size */
-       EDMR_EL         = 0x40, /* Litte endian */
+       EDMR_SRST = 0x03,
 #else /* CONFIG_CPU_SUBTYPE_SH7763 */
        EDMR_SRST = 0x01,
 #endif
@@ -307,47 +382,43 @@ enum PHY_STATUS_BIT { PHY_ST_LINK = 0x01, };
 
 /* EESR */
 enum EESR_BIT {
-#ifndef CONFIG_CPU_SUBTYPE_SH7763
-       EESR_TWB  = 0x40000000,
-#else
-       EESR_TWB  = 0xC0000000,
-       EESR_TC1  = 0x20000000,
-       EESR_TUC  = 0x10000000,
-       EESR_ROC  = 0x80000000,
-#endif
-       EESR_TABT = 0x04000000,
-       EESR_RABT = 0x02000000, EESR_RFRMER = 0x01000000,
-#ifndef CONFIG_CPU_SUBTYPE_SH7763
-       EESR_ADE  = 0x00800000,
-#endif
-       EESR_ECI  = 0x00400000,
-       EESR_FTC  = 0x00200000, EESR_TDE  = 0x00100000,
-       EESR_TFE  = 0x00080000, EESR_FRC  = 0x00040000,
-       EESR_RDE  = 0x00020000, EESR_RFE  = 0x00010000,
-#ifndef CONFIG_CPU_SUBTYPE_SH7763
-       EESR_CND  = 0x00000800,
-#endif
-       EESR_DLC  = 0x00000400,
-       EESR_CD   = 0x00000200, EESR_RTO  = 0x00000100,
-       EESR_RMAF = 0x00000080, EESR_CEEF = 0x00000040,
-       EESR_CELF = 0x00000020, EESR_RRF  = 0x00000010,
-       EESR_RTLF = 0x00000008, EESR_RTSF = 0x00000004,
-       EESR_PRE  = 0x00000002, EESR_CERF = 0x00000001,
-};
-
-
-#ifdef CONFIG_CPU_SUBTYPE_SH7763
-# define TX_CHECK (EESR_TC1 | EESR_FTC)
-# define EESR_ERR_CHECK        (EESR_TWB | EESR_TABT | EESR_RABT | EESR_RDE \
-               | EESR_RFRMER | EESR_TFE | EESR_TDE | EESR_ECI)
-# define TX_ERROR_CEHCK (EESR_TWB | EESR_TABT | EESR_TDE | EESR_TFE)
-
-#else
-# define TX_CHECK (EESR_FTC | EESR_CND | EESR_DLC | EESR_CD | EESR_RTO)
-# define EESR_ERR_CHECK        (EESR_TWB | EESR_TABT | EESR_RABT | EESR_RDE \
-               | EESR_RFRMER | EESR_ADE | EESR_TFE | EESR_TDE | EESR_ECI)
-# define TX_ERROR_CEHCK (EESR_TWB | EESR_TABT | EESR_ADE | EESR_TDE | EESR_TFE)
-#endif
+       EESR_TWB1       = 0x80000000,
+       EESR_TWB        = 0x40000000,   /* same as TWB0 */
+       EESR_TC1        = 0x20000000,
+       EESR_TUC        = 0x10000000,
+       EESR_ROC        = 0x08000000,
+       EESR_TABT       = 0x04000000,
+       EESR_RABT       = 0x02000000,
+       EESR_RFRMER     = 0x01000000,   /* same as RFCOF */
+       EESR_ADE        = 0x00800000,
+       EESR_ECI        = 0x00400000,
+       EESR_FTC        = 0x00200000,   /* same as TC or TC0 */
+       EESR_TDE        = 0x00100000,
+       EESR_TFE        = 0x00080000,   /* same as TFUF */
+       EESR_FRC        = 0x00040000,   /* same as FR */
+       EESR_RDE        = 0x00020000,
+       EESR_RFE        = 0x00010000,
+       EESR_CND        = 0x00000800,
+       EESR_DLC        = 0x00000400,
+       EESR_CD         = 0x00000200,
+       EESR_RTO        = 0x00000100,
+       EESR_RMAF       = 0x00000080,
+       EESR_CEEF       = 0x00000040,
+       EESR_CELF       = 0x00000020,
+       EESR_RRF        = 0x00000010,
+       EESR_RTLF       = 0x00000008,
+       EESR_RTSF       = 0x00000004,
+       EESR_PRE        = 0x00000002,
+       EESR_CERF       = 0x00000001,
+};
+
+#define DEFAULT_TX_CHECK       (EESR_FTC | EESR_CND | EESR_DLC | EESR_CD | \
+                                EESR_RTO)
+#define DEFAULT_EESR_ERR_CHECK (EESR_TWB | EESR_TABT | EESR_RABT | \
+                                EESR_RDE | EESR_RFRMER | EESR_ADE | \
+                                EESR_TFE | EESR_TDE | EESR_ECI)
+#define DEFAULT_TX_ERROR_CHECK (EESR_TWB | EESR_TABT | EESR_ADE | EESR_TDE | \
+                                EESR_TFE)
 
 /* EESIPR */
 enum DMAC_IM_BIT {
@@ -386,12 +457,8 @@ enum FCFTR_BIT {
        FCFTR_RFF0 = 0x00010000, FCFTR_RFD2 = 0x00000004,
        FCFTR_RFD1 = 0x00000002, FCFTR_RFD0 = 0x00000001,
 };
-#define FIFO_F_D_RFF   (FCFTR_RFF2|FCFTR_RFF1|FCFTR_RFF0)
-#ifndef CONFIG_CPU_SUBTYPE_SH7619
-#define FIFO_F_D_RFD   (FCFTR_RFD2|FCFTR_RFD1|FCFTR_RFD0)
-#else
-#define FIFO_F_D_RFD   (FCFTR_RFD0)
-#endif
+#define DEFAULT_FIFO_F_D_RFF   (FCFTR_RFF2 | FCFTR_RFF1 | FCFTR_RFF0)
+#define DEFAULT_FIFO_F_D_RFD   (FCFTR_RFD2 | FCFTR_RFD1 | FCFTR_RFD0)
 
 /* Transfer descriptor bit */
 enum TD_STS_BIT {
@@ -404,60 +471,38 @@ enum TD_STS_BIT {
 #define TD_TFP (TD_TFP1|TD_TFP0)
 
 /* RMCR */
-enum RECV_RST_BIT { RMCR_RST = 0x01, };
+#define DEFAULT_RMCR_VALUE     0x00000000
+
 /* ECMR */
 enum FELIC_MODE_BIT {
-#ifdef CONFIG_CPU_SUBTYPE_SH7763
        ECMR_TRCCM = 0x04000000, ECMR_RCSC = 0x00800000,
        ECMR_DPAD = 0x00200000, ECMR_RZPF = 0x00100000,
-#endif
        ECMR_ZPF = 0x00080000, ECMR_PFR = 0x00040000, ECMR_RXF = 0x00020000,
        ECMR_TXF = 0x00010000, ECMR_MCT = 0x00002000, ECMR_PRCEF = 0x00001000,
        ECMR_PMDE = 0x00000200, ECMR_RE = 0x00000040, ECMR_TE = 0x00000020,
-       ECMR_ILB = 0x00000008, ECMR_ELB = 0x00000004, ECMR_DM = 0x00000002,
-       ECMR_PRM = 0x00000001,
+       ECMR_RTM = 0x00000010, ECMR_ILB = 0x00000008, ECMR_ELB = 0x00000004,
+       ECMR_DM = 0x00000002, ECMR_PRM = 0x00000001,
 };
 
-#ifdef CONFIG_CPU_SUBTYPE_SH7763
-#define ECMR_CHG_DM    (ECMR_TRCCM | ECMR_RZPF | ECMR_ZPF |\
-                       ECMR_PFR | ECMR_RXF | ECMR_TXF | ECMR_MCT)
-#elif CONFIG_CPU_SUBTYPE_SH7619
-#define ECMR_CHG_DM    (ECMR_ZPF | ECMR_PFR | ECMR_RXF | ECMR_TXF)
-#else
-#define ECMR_CHG_DM    (ECMR_ZPF | ECMR_PFR | ECMR_RXF | ECMR_TXF | ECMR_MCT)
-#endif
-
 /* ECSR */
 enum ECSR_STATUS_BIT {
-#ifndef CONFIG_CPU_SUBTYPE_SH7763
        ECSR_BRCRX = 0x20, ECSR_PSRTO = 0x10,
-#endif
        ECSR_LCHNG = 0x04,
        ECSR_MPD = 0x02, ECSR_ICD = 0x01,
 };
 
-#ifdef CONFIG_CPU_SUBTYPE_SH7763
-# define ECSR_INIT (ECSR_ICD | ECSIPR_MPDIP)
-#else
-# define ECSR_INIT (ECSR_BRCRX | ECSR_PSRTO | \
-                       ECSR_LCHNG | ECSR_ICD | ECSIPR_MPDIP)
-#endif
+#define DEFAULT_ECSR_INIT      (ECSR_BRCRX | ECSR_PSRTO | ECSR_LCHNG | \
+                                ECSR_ICD | ECSIPR_MPDIP)
 
 /* ECSIPR */
 enum ECSIPR_STATUS_MASK_BIT {
-#ifndef CONFIG_CPU_SUBTYPE_SH7763
        ECSIPR_BRCRXIP = 0x20, ECSIPR_PSRTOIP = 0x10,
-#endif
        ECSIPR_LCHNGIP = 0x04,
        ECSIPR_MPDIP = 0x02, ECSIPR_ICDIP = 0x01,
 };
 
-#ifdef CONFIG_CPU_SUBTYPE_SH7763
-# define ECSIPR_INIT (ECSIPR_LCHNGIP | ECSIPR_ICDIP | ECSIPR_MPDIP)
-#else
-# define ECSIPR_INIT (ECSIPR_BRCRXIP | ECSIPR_PSRTOIP | ECSIPR_LCHNGIP | \
-                               ECSIPR_ICDIP | ECSIPR_MPDIP)
-#endif
+#define DEFAULT_ECSIPR_INIT    (ECSIPR_BRCRXIP | ECSIPR_PSRTOIP | \
+                                ECSIPR_LCHNGIP | ECSIPR_ICDIP | ECSIPR_MPDIP)
 
 /* APR */
 enum APR_BIT {
@@ -483,23 +528,12 @@ enum RPADIR_BIT {
        RPADIR_PADR = 0x0003f,
 };
 
-#if defined(CONFIG_CPU_SUBTYPE_SH7763)
-# define RPADIR_INIT (0x00)
-#else
-# define RPADIR_INIT (RPADIR_PADS1)
-#endif
-
 /* RFLR */
 #define RFLR_VALUE 0x1000
 
 /* FDR */
-enum FIFO_SIZE_BIT {
-#ifndef CONFIG_CPU_SUBTYPE_SH7619
-       FIFO_SIZE_T = 0x00000700, FIFO_SIZE_R = 0x00000007,
-#else
-       FIFO_SIZE_T = 0x00000100, FIFO_SIZE_R = 0x00000001,
-#endif
-};
+#define DEFAULT_FDR_INIT       0x00000707
+
 enum phy_offsets {
        PHY_CTRL = 0, PHY_STAT = 1, PHY_IDT1 = 2, PHY_IDT2 = 3,
        PHY_ANA = 4, PHY_ANL = 5, PHY_ANE = 6,
@@ -633,7 +667,43 @@ struct sh_eth_rxdesc {
        u32 pad0;               /* padding data */
 } __attribute__((aligned(2), packed));
 
+/* This structure is used by each CPU dependency handling. */
+struct sh_eth_cpu_data {
+       /* optional functions */
+       void (*chip_reset)(struct net_device *ndev);
+       void (*set_duplex)(struct net_device *ndev);
+       void (*set_rate)(struct net_device *ndev);
+
+       /* mandatory initialize value */
+       unsigned long eesipr_value;
+
+       /* optional initialize value */
+       unsigned long ecsr_value;
+       unsigned long ecsipr_value;
+       unsigned long fdr_value;
+       unsigned long fcftr_value;
+       unsigned long rpadir_value;
+       unsigned long rmcr_value;
+
+       /* interrupt checking mask */
+       unsigned long tx_check;
+       unsigned long eesr_err_check;
+       unsigned long tx_error_check;
+
+       /* hardware features */
+       unsigned no_psr:1;              /* EtherC DO NOT have PSR */
+       unsigned apr:1;                 /* EtherC have APR */
+       unsigned mpr:1;                 /* EtherC have MPR */
+       unsigned tpauser:1;             /* EtherC have TPAUSER */
+       unsigned bculr:1;               /* EtherC have BCULR */
+       unsigned hw_swap:1;             /* E-DMAC have DE bit in EDMR */
+       unsigned rpadir:1;              /* E-DMAC have RPADIR */
+       unsigned no_trimd:1;            /* E-DMAC DO NOT have TRIMD */
+       unsigned no_ade:1;      /* E-DMAC DO NOT have ADE bit in EESR */
+};
+
 struct sh_eth_private {
+       struct sh_eth_cpu_data *cd;
        dma_addr_t rx_desc_dma;
        dma_addr_t tx_desc_dma;
        struct sh_eth_rxdesc *rx_ring;
@@ -661,11 +731,7 @@ struct sh_eth_private {
        struct net_device_stats tsu_stats;      /* TSU forward status */
 };
 
-#ifdef CONFIG_CPU_SUBTYPE_SH7763
-/* SH7763 has endian control register */
-#define swaps(x, y)
-#else
-static void swaps(char *src, int len)
+static inline void sh_eth_soft_swap(char *src, int len)
 {
 #ifdef __LITTLE_ENDIAN__
        u32 *p = (u32 *)src;
@@ -676,5 +742,5 @@ static void swaps(char *src, int len)
                *p = swab32(*p);
 #endif
 }
-#endif /* CONFIG_CPU_SUBTYPE_SH7763 */
-#endif
+
+#endif /* #ifndef __SH_ETH_H__ */
index 55ccd51d247efc3fa20cddd6616ddc8607637e17..e2247669a4951ffdc385a149b248b4d8c18d5ee8 100644 (file)
@@ -47,7 +47,7 @@
 #define PHY_ID_ANY             0x1f
 #define MII_REG_ANY            0x1f
 
-#define DRV_VERSION            "1.2"
+#define DRV_VERSION            "1.3"
 #define DRV_NAME               "sis190"
 #define SIS190_DRIVER_NAME     DRV_NAME " Gigabit Ethernet driver " DRV_VERSION
 #define PFX DRV_NAME ": "
@@ -317,6 +317,7 @@ static struct mii_chip_info {
         unsigned int type;
        u32 feature;
 } mii_chip_table[] = {
+       { "Atheros PHY",          { 0x004d, 0xd010 }, LAN, 0 },
        { "Atheros PHY AR8012",   { 0x004d, 0xd020 }, LAN, 0 },
        { "Broadcom PHY BCM5461", { 0x0020, 0x60c0 }, LAN, F_PHY_BCM5461 },
        { "Broadcom PHY AC131",   { 0x0143, 0xbc70 }, LAN, 0 },
@@ -347,7 +348,7 @@ static struct {
        u32 msg_enable;
 } debug = { -1 };
 
-MODULE_DESCRIPTION("SiS sis190 Gigabit Ethernet driver");
+MODULE_DESCRIPTION("SiS sis190/191 Gigabit Ethernet driver");
 module_param(rx_copybreak, int, 0);
 MODULE_PARM_DESC(rx_copybreak, "Copy breakpoint for copy-only-tiny-frames");
 module_param_named(debug, debug.msg_enable, int, 0);
@@ -539,8 +540,8 @@ static bool sis190_try_rx_copy(struct sis190_private *tp,
        if (!skb)
                goto out;
 
-       pci_dma_sync_single_for_device(tp->pci_dev, addr, pkt_size,
-                                      PCI_DMA_FROMDEVICE);
+       pci_dma_sync_single_for_cpu(tp->pci_dev, addr, tp->rx_buf_sz,
+                               PCI_DMA_FROMDEVICE);
        skb_reserve(skb, 2);
        skb_copy_to_linear_data(skb, sk_buff[0]->data, pkt_size);
        *sk_buff = skb;
@@ -942,9 +943,9 @@ static void sis190_phy_task(struct work_struct *work)
                        u32 ctl;
                        const char *msg;
                } reg31[] = {
-                       { LPA_1000XFULL | LPA_SLCT, 0x07000c00 | 0x00001000,
+                       { LPA_1000FULL, 0x07000c00 | 0x00001000,
                                "1000 Mbps Full Duplex" },
-                       { LPA_1000XHALF | LPA_SLCT, 0x07000c00,
+                       { LPA_1000HALF, 0x07000c00,
                                "1000 Mbps Half Duplex" },
                        { LPA_100FULL, 0x04000800 | 0x00001000,
                                "100 Mbps Full Duplex" },
@@ -955,22 +956,35 @@ static void sis190_phy_task(struct work_struct *work)
                        { LPA_10HALF, 0x04000400,
                                "10 Mbps Half Duplex" },
                        { 0, 0x04000400, "unknown" }
-               }, *p;
-               u16 adv;
+               }, *p = NULL;
+               u16 adv, autoexp, gigadv, gigrec;
 
                val = mdio_read(ioaddr, phy_id, 0x1f);
                net_link(tp, KERN_INFO "%s: mii ext = %04x.\n", dev->name, val);
 
                val = mdio_read(ioaddr, phy_id, MII_LPA);
                adv = mdio_read(ioaddr, phy_id, MII_ADVERTISE);
-               net_link(tp, KERN_INFO "%s: mii lpa = %04x adv = %04x.\n",
-                        dev->name, val, adv);
-
-               val &= adv;
+               autoexp = mdio_read(ioaddr, phy_id, MII_EXPANSION);
+               net_link(tp, KERN_INFO "%s: mii lpa=%04x adv=%04x exp=%04x.\n",
+                        dev->name, val, adv, autoexp);
+
+               if (val & LPA_NPAGE && autoexp & EXPANSION_NWAY) {
+                       /* check for gigabit speed */
+                       gigadv = mdio_read(ioaddr, phy_id, MII_CTRL1000);
+                       gigrec = mdio_read(ioaddr, phy_id, MII_STAT1000);
+                       val = (gigadv & (gigrec >> 2));
+                       if (val & ADVERTISE_1000FULL)
+                               p = reg31;
+                       else if (val & ADVERTISE_1000HALF)
+                               p = reg31 + 1;
+               }
+               if (!p) {
+                       val &= adv;
 
-               for (p = reg31; p->val; p++) {
-                       if ((val & p->val) == p->val)
-                               break;
+                       for (p = reg31; p->val; p++) {
+                               if ((val & p->val) == p->val)
+                                       break;
+                       }
                }
 
                p->ctl |= SIS_R32(StationControl) & ~0x0f001c00;
@@ -1204,8 +1218,6 @@ static int sis190_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
        SIS_W32(TxControl, 0x1a00 | CmdReset | CmdTxEnb);
 
-       dev->trans_start = jiffies;
-
        dirty_tx = tp->dirty_tx;
        if ((tp->cur_tx - NUM_TX_DESC) == dirty_tx) {
                netif_stop_queue(dev);
@@ -1315,12 +1327,15 @@ static void sis190_init_phy(struct net_device *dev, struct sis190_private *tp,
                        ((mii_status & (BMSR_100FULL | BMSR_100HALF)) ?
                                LAN : HOME) : p->type;
                tp->features |= p->feature;
-       } else
+               net_probe(tp, KERN_INFO "%s: %s transceiver at address %d.\n",
+                       pci_name(tp->pci_dev), p->name, phy_id);
+       } else {
                phy->type = UNKNOWN;
-
-       net_probe(tp, KERN_INFO "%s: %s transceiver at address %d.\n",
-                 pci_name(tp->pci_dev),
-                 (phy->type == UNKNOWN) ? "Unknown PHY" : p->name, phy_id);
+               net_probe(tp, KERN_INFO
+                       "%s: unknown PHY 0x%x:0x%x transceiver at address %d\n",
+                       pci_name(tp->pci_dev),
+                       phy->id[0], (phy->id[1] & 0xfff0), phy_id);
+       }
 }
 
 static void sis190_mii_probe_88e1111_fixup(struct sis190_private *tp)
index 2d4617b3e2087c9a7bcc9bf33a83f3e00bbf77cb..a9a897bb42d57f0342a7ee0405c06d005b51046d 100644 (file)
@@ -1584,7 +1584,7 @@ sis900_start_xmit(struct sk_buff *skb, struct net_device *net_dev)
        /* Don't transmit data before the complete of auto-negotiation */
        if(!sis_priv->autong_complete){
                netif_stop_queue(net_dev);
-               return 1;
+               return NETDEV_TX_BUSY;
        }
 
        spin_lock_irqsave(&sis_priv->lock, flags);
index e14aec0a73337ee4e832284155cd8c9d313935b9..088fe26484e70a681818bc01c163d27d5638639d 100644 (file)
@@ -159,12 +159,6 @@ MODULE_AUTHOR("Mirko Lindner <mlindner@syskonnect.de>");
 
 static int num_boards; /* total number of adapters configured */
 
-#ifdef DRIVERDEBUG
-#define PRINTK(s, args...) printk(s, ## args)
-#else
-#define PRINTK(s, args...)
-#endif                         // DRIVERDEBUG
-
 static const struct net_device_ops skfp_netdev_ops = {
        .ndo_open               = skfp_open,
        .ndo_stop               = skfp_close,
@@ -213,7 +207,7 @@ static int skfp_init_one(struct pci_dev *pdev,
        void __iomem *mem;
        int err;
 
-       PRINTK(KERN_INFO "entering skfp_init_one\n");
+       pr_debug(KERN_INFO "entering skfp_init_one\n");
 
        if (num_boards == 0) 
                printk("%s\n", boot_msg);
@@ -389,7 +383,7 @@ static  int skfp_driver_init(struct net_device *dev)
        skfddi_priv *bp = &smc->os;
        int err = -EIO;
 
-       PRINTK(KERN_INFO "entering skfp_driver_init\n");
+       pr_debug(KERN_INFO "entering skfp_driver_init\n");
 
        // set the io address in private structures
        bp->base_addr = dev->base_addr;
@@ -409,7 +403,7 @@ static  int skfp_driver_init(struct net_device *dev)
 
        // Determine the required size of the 'shared' memory area.
        bp->SharedMemSize = mac_drv_check_space();
-       PRINTK(KERN_INFO "Memory for HWM: %ld\n", bp->SharedMemSize);
+       pr_debug(KERN_INFO "Memory for HWM: %ld\n", bp->SharedMemSize);
        if (bp->SharedMemSize > 0) {
                bp->SharedMemSize += 16;        // for descriptor alignment
 
@@ -433,13 +427,13 @@ static  int skfp_driver_init(struct net_device *dev)
 
        card_stop(smc);         // Reset adapter.
 
-       PRINTK(KERN_INFO "mac_drv_init()..\n");
+       pr_debug(KERN_INFO "mac_drv_init()..\n");
        if (mac_drv_init(smc) != 0) {
-               PRINTK(KERN_INFO "mac_drv_init() failed.\n");
+               pr_debug(KERN_INFO "mac_drv_init() failed.\n");
                goto fail;
        }
        read_address(smc, NULL);
-       PRINTK(KERN_INFO "HW-Addr: %02x %02x %02x %02x %02x %02x\n",
+       pr_debug(KERN_INFO "HW-Addr: %02x %02x %02x %02x %02x %02x\n",
               smc->hw.fddi_canon_addr.a[0],
               smc->hw.fddi_canon_addr.a[1],
               smc->hw.fddi_canon_addr.a[2],
@@ -495,7 +489,7 @@ static int skfp_open(struct net_device *dev)
        struct s_smc *smc = netdev_priv(dev);
        int err;
 
-       PRINTK(KERN_INFO "entering skfp_open\n");
+       pr_debug(KERN_INFO "entering skfp_open\n");
        /* Register IRQ - support shared interrupts by passing device ptr */
        err = request_irq(dev->irq, skfp_interrupt, IRQF_SHARED,
                          dev->name, dev);
@@ -868,12 +862,12 @@ static void skfp_ctl_set_multicast_list_wo_lock(struct net_device *dev)
        /* Enable promiscuous mode, if necessary */
        if (dev->flags & IFF_PROMISC) {
                mac_drv_rx_mode(smc, RX_ENABLE_PROMISC);
-               PRINTK(KERN_INFO "PROMISCUOUS MODE ENABLED\n");
+               pr_debug(KERN_INFO "PROMISCUOUS MODE ENABLED\n");
        }
        /* Else, update multicast address table */
        else {
                mac_drv_rx_mode(smc, RX_DISABLE_PROMISC);
-               PRINTK(KERN_INFO "PROMISCUOUS MODE DISABLED\n");
+               pr_debug(KERN_INFO "PROMISCUOUS MODE DISABLED\n");
 
                // Reset all MC addresses
                mac_clear_multicast(smc);
@@ -881,7 +875,7 @@ static void skfp_ctl_set_multicast_list_wo_lock(struct net_device *dev)
 
                if (dev->flags & IFF_ALLMULTI) {
                        mac_drv_rx_mode(smc, RX_ENABLE_ALLMULTI);
-                       PRINTK(KERN_INFO "ENABLE ALL MC ADDRESSES\n");
+                       pr_debug(KERN_INFO "ENABLE ALL MC ADDRESSES\n");
                } else if (dev->mc_count > 0) {
                        if (dev->mc_count <= FPMAX_MULTICAST) {
                                /* use exact filtering */
@@ -894,12 +888,12 @@ static void skfp_ctl_set_multicast_list_wo_lock(struct net_device *dev)
                                                          (struct fddi_addr *)dmi->dmi_addr, 
                                                          1);
 
-                                       PRINTK(KERN_INFO "ENABLE MC ADDRESS:");
-                                       PRINTK(" %02x %02x %02x ",
+                                       pr_debug(KERN_INFO "ENABLE MC ADDRESS:");
+                                       pr_debug(" %02x %02x %02x ",
                                               dmi->dmi_addr[0],
                                               dmi->dmi_addr[1],
                                               dmi->dmi_addr[2]);
-                                       PRINTK("%02x %02x %02x\n",
+                                       pr_debug("%02x %02x %02x\n",
                                               dmi->dmi_addr[3],
                                               dmi->dmi_addr[4],
                                               dmi->dmi_addr[5]);
@@ -909,11 +903,11 @@ static void skfp_ctl_set_multicast_list_wo_lock(struct net_device *dev)
                        } else {        // more MC addresses than HW supports
 
                                mac_drv_rx_mode(smc, RX_ENABLE_ALLMULTI);
-                               PRINTK(KERN_INFO "ENABLE ALL MC ADDRESSES\n");
+                               pr_debug(KERN_INFO "ENABLE ALL MC ADDRESSES\n");
                        }
                } else {        // no MC addresses
 
-                       PRINTK(KERN_INFO "DISABLE ALL MC ADDRESSES\n");
+                       pr_debug(KERN_INFO "DISABLE ALL MC ADDRESSES\n");
                }
 
                /* Update adapter filters */
@@ -1067,7 +1061,7 @@ static int skfp_send_pkt(struct sk_buff *skb, struct net_device *dev)
        struct s_smc *smc = netdev_priv(dev);
        skfddi_priv *bp = &smc->os;
 
-       PRINTK(KERN_INFO "skfp_send_pkt\n");
+       pr_debug(KERN_INFO "skfp_send_pkt\n");
 
        /*
         * Verify that incoming transmit request is OK
@@ -1088,7 +1082,7 @@ static int skfp_send_pkt(struct sk_buff *skb, struct net_device *dev)
        if (bp->QueueSkb == 0) {        // return with tbusy set: queue full
 
                netif_stop_queue(dev);
-               return 1;
+               return NETDEV_TX_BUSY;
        }
        bp->QueueSkb--;
        skb_queue_tail(&bp->SendSkbQueue, skb);
@@ -1137,13 +1131,13 @@ static void send_queued_packets(struct s_smc *smc)
 
        int frame_status;       // HWM tx frame status.
 
-       PRINTK(KERN_INFO "send queued packets\n");
+       pr_debug(KERN_INFO "send queued packets\n");
        for (;;) {
                // send first buffer from queue
                skb = skb_dequeue(&bp->SendSkbQueue);
 
                if (!skb) {
-                       PRINTK(KERN_INFO "queue empty\n");
+                       pr_debug(KERN_INFO "queue empty\n");
                        return;
                }               // queue empty !
 
@@ -1174,11 +1168,11 @@ static void send_queued_packets(struct s_smc *smc)
 
                        if ((frame_status & RING_DOWN) != 0) {
                                // Ring is down.
-                               PRINTK("Tx attempt while ring down.\n");
+                               pr_debug("Tx attempt while ring down.\n");
                        } else if ((frame_status & OUT_OF_TXD) != 0) {
-                               PRINTK("%s: out of TXDs.\n", bp->dev->name);
+                               pr_debug("%s: out of TXDs.\n", bp->dev->name);
                        } else {
-                               PRINTK("%s: out of transmit resources",
+                               pr_debug("%s: out of transmit resources",
                                        bp->dev->name);
                        }
 
@@ -1255,7 +1249,7 @@ static void CheckSourceAddress(unsigned char *frame, unsigned char *hw_addr)
 static void ResetAdapter(struct s_smc *smc)
 {
 
-       PRINTK(KERN_INFO "[fddi: ResetAdapter]\n");
+       pr_debug(KERN_INFO "[fddi: ResetAdapter]\n");
 
        // Stop the adapter.
 
@@ -1301,7 +1295,7 @@ void llc_restart_tx(struct s_smc *smc)
 {
        skfddi_priv *bp = &smc->os;
 
-       PRINTK(KERN_INFO "[llc_restart_tx]\n");
+       pr_debug(KERN_INFO "[llc_restart_tx]\n");
 
        // Try to send queued packets
        spin_unlock(&bp->DriverLock);
@@ -1331,7 +1325,7 @@ void *mac_drv_get_space(struct s_smc *smc, unsigned int size)
 {
        void *virt;
 
-       PRINTK(KERN_INFO "mac_drv_get_space (%d bytes), ", size);
+       pr_debug(KERN_INFO "mac_drv_get_space (%d bytes), ", size);
        virt = (void *) (smc->os.SharedMemAddr + smc->os.SharedMemHeap);
 
        if ((smc->os.SharedMemHeap + size) > smc->os.SharedMemSize) {
@@ -1340,9 +1334,9 @@ void *mac_drv_get_space(struct s_smc *smc, unsigned int size)
        }
        smc->os.SharedMemHeap += size;  // Move heap pointer.
 
-       PRINTK(KERN_INFO "mac_drv_get_space end\n");
-       PRINTK(KERN_INFO "virt addr: %lx\n", (ulong) virt);
-       PRINTK(KERN_INFO "bus  addr: %lx\n", (ulong)
+       pr_debug(KERN_INFO "mac_drv_get_space end\n");
+       pr_debug(KERN_INFO "virt addr: %lx\n", (ulong) virt);
+       pr_debug(KERN_INFO "bus  addr: %lx\n", (ulong)
               (smc->os.SharedMemDMA +
                ((char *) virt - (char *)smc->os.SharedMemAddr)));
        return (virt);
@@ -1372,7 +1366,7 @@ void *mac_drv_get_desc_mem(struct s_smc *smc, unsigned int size)
 
        char *virt;
 
-       PRINTK(KERN_INFO "mac_drv_get_desc_mem\n");
+       pr_debug(KERN_INFO "mac_drv_get_desc_mem\n");
 
        // Descriptor memory must be aligned on 16-byte boundary.
 
@@ -1381,8 +1375,8 @@ void *mac_drv_get_desc_mem(struct s_smc *smc, unsigned int size)
        size = (u_int) (16 - (((unsigned long) virt) & 15UL));
        size = size % 16;
 
-       PRINTK("Allocate %u bytes alignment gap ", size);
-       PRINTK("for descriptor memory.\n");
+       pr_debug("Allocate %u bytes alignment gap ", size);
+       pr_debug("for descriptor memory.\n");
 
        if (!mac_drv_get_space(smc, size)) {
                printk("fddi: Unable to align descriptor memory.\n");
@@ -1516,11 +1510,11 @@ void mac_drv_tx_complete(struct s_smc *smc, volatile struct s_smt_fp_txd *txd)
 {
        struct sk_buff *skb;
 
-       PRINTK(KERN_INFO "entering mac_drv_tx_complete\n");
+       pr_debug(KERN_INFO "entering mac_drv_tx_complete\n");
        // Check if this TxD points to a skb
 
        if (!(skb = txd->txd_os.skb)) {
-               PRINTK("TXD with no skb assigned.\n");
+               pr_debug("TXD with no skb assigned.\n");
                return;
        }
        txd->txd_os.skb = NULL;
@@ -1536,7 +1530,7 @@ void mac_drv_tx_complete(struct s_smc *smc, volatile struct s_smt_fp_txd *txd)
        // free the skb
        dev_kfree_skb_irq(skb);
 
-       PRINTK(KERN_INFO "leaving mac_drv_tx_complete\n");
+       pr_debug(KERN_INFO "leaving mac_drv_tx_complete\n");
 }                              // mac_drv_tx_complete
 
 
@@ -1603,7 +1597,7 @@ void mac_drv_rx_complete(struct s_smc *smc, volatile struct s_smt_fp_rxd *rxd,
        unsigned short ri;
        u_int RifLength;
 
-       PRINTK(KERN_INFO "entering mac_drv_rx_complete (len=%d)\n", len);
+       pr_debug(KERN_INFO "entering mac_drv_rx_complete (len=%d)\n", len);
        if (frag_count != 1) {  // This is not allowed to happen.
 
                printk("fddi: Multi-fragment receive!\n");
@@ -1612,7 +1606,7 @@ void mac_drv_rx_complete(struct s_smc *smc, volatile struct s_smt_fp_rxd *rxd,
        }
        skb = rxd->rxd_os.skb;
        if (!skb) {
-               PRINTK(KERN_INFO "No skb in rxd\n");
+               pr_debug(KERN_INFO "No skb in rxd\n");
                smc->os.MacStat.gen.rx_errors++;
                goto RequeueRxd;
        }
@@ -1642,7 +1636,7 @@ void mac_drv_rx_complete(struct s_smc *smc, volatile struct s_smt_fp_rxd *rxd,
        else {
                int n;
 // goos: RIF removal has still to be tested
-               PRINTK(KERN_INFO "RIF found\n");
+               pr_debug(KERN_INFO "RIF found\n");
                // Get RIF length from Routing Control (RC) field.
                cp = virt + FDDI_MAC_HDR_LEN;   // Point behind MAC header.
 
@@ -1687,7 +1681,7 @@ void mac_drv_rx_complete(struct s_smc *smc, volatile struct s_smt_fp_rxd *rxd,
        return;
 
       RequeueRxd:
-       PRINTK(KERN_INFO "Rx: re-queue RXD.\n");
+       pr_debug(KERN_INFO "Rx: re-queue RXD.\n");
        mac_drv_requeue_rxd(smc, rxd, frag_count);
        smc->os.MacStat.gen.rx_errors++;        // Count receive packets
                                                // not indicated.
@@ -1736,7 +1730,7 @@ void mac_drv_requeue_rxd(struct s_smc *smc, volatile struct s_smt_fp_rxd *rxd,
                skb = src_rxd->rxd_os.skb;
                if (skb == NULL) {      // this should not happen
 
-                       PRINTK("Requeue with no skb in rxd!\n");
+                       pr_debug("Requeue with no skb in rxd!\n");
                        skb = alloc_skb(MaxFrameSize + 3, GFP_ATOMIC);
                        if (skb) {
                                // we got a skb
@@ -1751,7 +1745,7 @@ void mac_drv_requeue_rxd(struct s_smc *smc, volatile struct s_smt_fp_rxd *rxd,
                                rxd->rxd_os.dma_addr = b_addr;
                        } else {
                                // no skb available, use local buffer
-                               PRINTK("Queueing invalid buffer!\n");
+                               pr_debug("Queueing invalid buffer!\n");
                                rxd->rxd_os.skb = NULL;
                                v_addr = smc->os.LocalRxBuffer;
                                b_addr = smc->os.LocalRxBufferDMA;
@@ -1798,7 +1792,7 @@ void mac_drv_fill_rxd(struct s_smc *smc)
        struct sk_buff *skb;
        volatile struct s_smt_fp_rxd *rxd;
 
-       PRINTK(KERN_INFO "entering mac_drv_fill_rxd\n");
+       pr_debug(KERN_INFO "entering mac_drv_fill_rxd\n");
 
        // Walk through the list of free receive buffers, passing receive
        // buffers to the HWM as long as RXDs are available.
@@ -1806,7 +1800,7 @@ void mac_drv_fill_rxd(struct s_smc *smc)
        MaxFrameSize = smc->os.MaxFrameSize;
        // Check if there is any RXD left.
        while (HWM_GET_RX_FREE(smc) > 0) {
-               PRINTK(KERN_INFO ".\n");
+               pr_debug(KERN_INFO ".\n");
 
                rxd = HWM_GET_CURR_RXD(smc);
                skb = alloc_skb(MaxFrameSize + 3, GFP_ATOMIC);
@@ -1826,7 +1820,7 @@ void mac_drv_fill_rxd(struct s_smc *smc)
                        // keep the receiver running in hope of better times.
                        // Multiple descriptors may point to this local buffer,
                        // so data in it must be considered invalid.
-                       PRINTK("Queueing invalid buffer!\n");
+                       pr_debug("Queueing invalid buffer!\n");
                        v_addr = smc->os.LocalRxBuffer;
                        b_addr = smc->os.LocalRxBufferDMA;
                }
@@ -1837,7 +1831,7 @@ void mac_drv_fill_rxd(struct s_smc *smc)
                hwm_rx_frag(smc, v_addr, b_addr, MaxFrameSize,
                            FIRST_FRAG | LAST_FRAG);
        }
-       PRINTK(KERN_INFO "leaving mac_drv_fill_rxd\n");
+       pr_debug(KERN_INFO "leaving mac_drv_fill_rxd\n");
 }                              // mac_drv_fill_rxd
 
 
@@ -1863,7 +1857,7 @@ void mac_drv_clear_rxd(struct s_smc *smc, volatile struct s_smt_fp_rxd *rxd,
 
        struct sk_buff *skb;
 
-       PRINTK("entering mac_drv_clear_rxd\n");
+       pr_debug("entering mac_drv_clear_rxd\n");
 
        if (frag_count != 1)    // This is not allowed to happen.
 
@@ -1919,19 +1913,19 @@ int mac_drv_rx_init(struct s_smc *smc, int len, int fc,
 {
        struct sk_buff *skb;
 
-       PRINTK("entering mac_drv_rx_init(len=%d)\n", len);
+       pr_debug("entering mac_drv_rx_init(len=%d)\n", len);
 
        // "Received" a SMT or NSA frame of the local SMT.
 
        if (len != la_len || len < FDDI_MAC_HDR_LEN || !look_ahead) {
-               PRINTK("fddi: Discard invalid local SMT frame\n");
-               PRINTK("  len=%d, la_len=%d, (ULONG) look_ahead=%08lXh.\n",
+               pr_debug("fddi: Discard invalid local SMT frame\n");
+               pr_debug("  len=%d, la_len=%d, (ULONG) look_ahead=%08lXh.\n",
                       len, la_len, (unsigned long) look_ahead);
                return (0);
        }
        skb = alloc_skb(len + 3, GFP_ATOMIC);
        if (!skb) {
-               PRINTK("fddi: Local SMT: skb memory exhausted.\n");
+               pr_debug("fddi: Local SMT: skb memory exhausted.\n");
                return (0);
        }
        skb_reserve(skb, 3);
@@ -1981,40 +1975,40 @@ void smt_timer_poll(struct s_smc *smc)
  ************************/
 void ring_status_indication(struct s_smc *smc, u_long status)
 {
-       PRINTK("ring_status_indication( ");
+       pr_debug("ring_status_indication( ");
        if (status & RS_RES15)
-               PRINTK("RS_RES15 ");
+               pr_debug("RS_RES15 ");
        if (status & RS_HARDERROR)
-               PRINTK("RS_HARDERROR ");
+               pr_debug("RS_HARDERROR ");
        if (status & RS_SOFTERROR)
-               PRINTK("RS_SOFTERROR ");
+               pr_debug("RS_SOFTERROR ");
        if (status & RS_BEACON)
-               PRINTK("RS_BEACON ");
+               pr_debug("RS_BEACON ");
        if (status & RS_PATHTEST)
-               PRINTK("RS_PATHTEST ");
+               pr_debug("RS_PATHTEST ");
        if (status & RS_SELFTEST)
-               PRINTK("RS_SELFTEST ");
+               pr_debug("RS_SELFTEST ");
        if (status & RS_RES9)
-               PRINTK("RS_RES9 ");
+               pr_debug("RS_RES9 ");
        if (status & RS_DISCONNECT)
-               PRINTK("RS_DISCONNECT ");
+               pr_debug("RS_DISCONNECT ");
        if (status & RS_RES7)
-               PRINTK("RS_RES7 ");
+               pr_debug("RS_RES7 ");
        if (status & RS_DUPADDR)
-               PRINTK("RS_DUPADDR ");
+               pr_debug("RS_DUPADDR ");
        if (status & RS_NORINGOP)
-               PRINTK("RS_NORINGOP ");
+               pr_debug("RS_NORINGOP ");
        if (status & RS_VERSION)
-               PRINTK("RS_VERSION ");
+               pr_debug("RS_VERSION ");
        if (status & RS_STUCKBYPASSS)
-               PRINTK("RS_STUCKBYPASSS ");
+               pr_debug("RS_STUCKBYPASSS ");
        if (status & RS_EVENT)
-               PRINTK("RS_EVENT ");
+               pr_debug("RS_EVENT ");
        if (status & RS_RINGOPCHANGE)
-               PRINTK("RS_RINGOPCHANGE ");
+               pr_debug("RS_RINGOPCHANGE ");
        if (status & RS_RES0)
-               PRINTK("RS_RES0 ");
-       PRINTK("]\n");
+               pr_debug("RS_RES0 ");
+       pr_debug("]\n");
 }                              // ring_status_indication
 
 
@@ -2057,17 +2051,17 @@ void smt_stat_counter(struct s_smc *smc, int stat)
 {
 //      BOOLEAN RingIsUp ;
 
-       PRINTK(KERN_INFO "smt_stat_counter\n");
+       pr_debug(KERN_INFO "smt_stat_counter\n");
        switch (stat) {
        case 0:
-               PRINTK(KERN_INFO "Ring operational change.\n");
+               pr_debug(KERN_INFO "Ring operational change.\n");
                break;
        case 1:
-               PRINTK(KERN_INFO "Receive fifo overflow.\n");
+               pr_debug(KERN_INFO "Receive fifo overflow.\n");
                smc->os.MacStat.gen.rx_errors++;
                break;
        default:
-               PRINTK(KERN_INFO "Unknown status (%d).\n", stat);
+               pr_debug(KERN_INFO "Unknown status (%d).\n", stat);
                break;
        }
 }                              // smt_stat_counter
@@ -2123,10 +2117,10 @@ void cfm_state_change(struct s_smc *smc, int c_state)
                s = "SC11_C_WRAP_S";
                break;
        default:
-               PRINTK(KERN_INFO "cfm_state_change: unknown %d\n", c_state);
+               pr_debug(KERN_INFO "cfm_state_change: unknown %d\n", c_state);
                return;
        }
-       PRINTK(KERN_INFO "cfm_state_change: %s\n", s);
+       pr_debug(KERN_INFO "cfm_state_change: %s\n", s);
 #endif                         // DRIVERDEBUG
 }                              // cfm_state_change
 
@@ -2181,7 +2175,7 @@ void ecm_state_change(struct s_smc *smc, int e_state)
                s = "unknown";
                break;
        }
-       PRINTK(KERN_INFO "ecm_state_change: %s\n", s);
+       pr_debug(KERN_INFO "ecm_state_change: %s\n", s);
 #endif                         //DRIVERDEBUG
 }                              // ecm_state_change
 
@@ -2236,7 +2230,7 @@ void rmt_state_change(struct s_smc *smc, int r_state)
                s = "unknown";
                break;
        }
-       PRINTK(KERN_INFO "[rmt_state_change: %s]\n", s);
+       pr_debug(KERN_INFO "[rmt_state_change: %s]\n", s);
 #endif                         // DRIVERDEBUG
 }                              // rmt_state_change
 
@@ -2256,7 +2250,7 @@ void rmt_state_change(struct s_smc *smc, int r_state)
  ************************/
 void drv_reset_indication(struct s_smc *smc)
 {
-       PRINTK(KERN_INFO "entering drv_reset_indication\n");
+       pr_debug(KERN_INFO "entering drv_reset_indication\n");
 
        smc->os.ResetRequested = TRUE;  // Set flag.
 
index c11cdd08ec5701ea2b4b9fe3dca92b1727ca2b69..60d502eef4fc36868d6fac2099f14ec852855497 100644 (file)
@@ -2837,8 +2837,6 @@ static int skge_xmit_frame(struct sk_buff *skb, struct net_device *dev)
                netif_stop_queue(dev);
        }
 
-       dev->trans_start = jiffies;
-
        return NETDEV_TX_OK;
 }
 
index a2ff9cb1e7ac55e4f4a80311d11326268345e87c..6b5946fe8ae2224720ab319aab6c415574e4382b 100644 (file)
@@ -1690,7 +1690,6 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
 
        sky2_put_idx(hw, txqaddr[sky2->port], sky2->tx_prod);
 
-       dev->trans_start = jiffies;
        return NETDEV_TX_OK;
 
 mapping_unwind:
index 8d36d40649eff2701e5faac99531dc6407435413..c791ef76c1d6341c755e159da7473ab2b1544ab3 100644 (file)
@@ -370,7 +370,7 @@ static int __init ultramca_probe(struct device *gen_dev)
 
        outb(reg4, ioaddr + 4);
 
-       gen_dev->driver_data = dev;
+       dev_set_drvdata(gen_dev, dev);
 
        /* The 8390 isn't at the base address, so fake the offset
         */
@@ -531,7 +531,7 @@ static int ultramca_close_card(struct net_device *dev)
 static int ultramca_remove(struct device *gen_dev)
 {
        struct mca_device *mca_dev = to_mca_device(gen_dev);
-       struct net_device *dev = (struct net_device *)gen_dev->driver_data;
+       struct net_device *dev = dev_get_drvdata(gen_dev);
 
        if (dev) {
                /* NB: ultra_close_card() does free_irq */
index 293610334a778b2ca81c4af52a2b8e391d13b204..bc4976ac871281f716800249710448e9f81b628c 100644 (file)
@@ -1774,6 +1774,20 @@ static int __devinit smc911x_findirq(struct net_device *dev)
        return probe_irq_off(cookie);
 }
 
+static const struct net_device_ops smc911x_netdev_ops = {
+       .ndo_open               = smc911x_open,
+       .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_change_mtu         = eth_change_mtu,
+       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_set_mac_address    = eth_mac_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+       .ndo_poll_controller    = smc911x_poll_controller,
+#endif
+};
+
 /*
  * Function: smc911x_probe(unsigned long ioaddr)
  *
@@ -1940,16 +1954,9 @@ static int __devinit smc911x_probe(struct net_device *dev)
        /* Fill in the fields of the device structure with ethernet values. */
        ether_setup(dev);
 
-       dev->open = smc911x_open;
-       dev->stop = smc911x_close;
-       dev->hard_start_xmit = smc911x_hard_start_xmit;
-       dev->tx_timeout = smc911x_timeout;
+       dev->netdev_ops = &smc911x_netdev_ops;
        dev->watchdog_timeo = msecs_to_jiffies(watchdog);
-       dev->set_multicast_list = smc911x_set_multicast_list;
        dev->ethtool_ops = &smc911x_ethtool_ops;
-#ifdef CONFIG_NET_POLL_CONTROLLER
-       dev->poll_controller = smc911x_poll_controller;
-#endif
 
        INIT_WORK(&lp->phy_configure, smc911x_phy_configure);
        lp->mii.phy_id_mask = 0x1f;
index 9a7973a541168b0f675080cd5a44feb7a2bacbe5..e02471b2f2b5c483e9238b2e2c783e843edefa74 100644 (file)
@@ -503,7 +503,7 @@ static int smc_wait_to_send_packet( struct sk_buff * skb, struct net_device * de
                /* THIS SHOULD NEVER HAPPEN. */
                dev->stats.tx_aborted_errors++;
                printk(CARDNAME": Bad Craziness - sent packet while busy.\n" );
-               return 1;
+               return NETDEV_TX_BUSY;
        }
        lp->saved_skb = skb;
 
index eb7db032a780eac55990782c69fc25dfac0cf8ee..b60639bd181b998738185a5d6ceaa1f6059339ad 100644 (file)
@@ -47,6 +47,7 @@
 #include <linux/bitops.h>
 #include <linux/irq.h>
 #include <linux/io.h>
+#include <linux/swab.h>
 #include <linux/phy.h>
 #include <linux/smsc911x.h>
 #include "smsc911x.h"
@@ -175,6 +176,12 @@ static inline void
 smsc911x_tx_writefifo(struct smsc911x_data *pdata, unsigned int *buf,
                      unsigned int wordcount)
 {
+       if (pdata->config.flags & SMSC911X_SWAP_FIFO) {
+               while (wordcount--)
+                       smsc911x_reg_write(pdata, TX_DATA_FIFO, swab32(*buf++));
+               return;
+       }
+
        if (pdata->config.flags & SMSC911X_USE_32BIT) {
                writesl(pdata->ioaddr + TX_DATA_FIFO, buf, wordcount);
                return;
@@ -194,6 +201,12 @@ static inline void
 smsc911x_rx_readfifo(struct smsc911x_data *pdata, unsigned int *buf,
                     unsigned int wordcount)
 {
+       if (pdata->config.flags & SMSC911X_SWAP_FIFO) {
+               while (wordcount--)
+                       *buf++ = swab32(smsc911x_reg_read(pdata, RX_DATA_FIFO));
+               return;
+       }
+
        if (pdata->config.flags & SMSC911X_USE_32BIT) {
                readsl(pdata->ioaddr + RX_DATA_FIFO, buf, wordcount);
                return;
@@ -1963,7 +1976,7 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev)
                retval = -ENODEV;
                goto out_0;
        }
-       res_size = res->end - res->start;
+       res_size = res->end - res->start + 1;
 
        irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
        if (!irq_res) {
@@ -2096,12 +2109,58 @@ out_0:
        return retval;
 }
 
+#ifdef CONFIG_PM
+/* This implementation assumes the devices remains powered on its VDDVARIO
+ * pins during suspend. */
+
+static int smsc911x_suspend(struct platform_device *pdev, pm_message_t state)
+{
+       struct net_device *dev = platform_get_drvdata(pdev);
+       struct smsc911x_data *pdata = netdev_priv(dev);
+
+       /* enable wake on LAN, energy detection and the external PME
+        * signal. */
+       smsc911x_reg_write(pdata, PMT_CTRL,
+               PMT_CTRL_PM_MODE_D1_ | PMT_CTRL_WOL_EN_ |
+               PMT_CTRL_ED_EN_ | PMT_CTRL_PME_EN_);
+
+       return 0;
+}
+
+static int smsc911x_resume(struct platform_device *pdev)
+{
+       struct net_device *dev = platform_get_drvdata(pdev);
+       struct smsc911x_data *pdata = netdev_priv(dev);
+       unsigned int to = 100;
+
+       /* Note 3.11 from the datasheet:
+        *      "When the LAN9220 is in a power saving state, a write of any
+        *       data to the BYTE_TEST register will wake-up the device."
+        */
+       smsc911x_reg_write(pdata, BYTE_TEST, 0);
+
+       /* poll the READY bit in PMT_CTRL. Any other access to the device is
+        * forbidden while this bit isn't set. Try for 100ms and return -EIO
+        * if it failed. */
+       while (!(smsc911x_reg_read(pdata, PMT_CTRL) & PMT_CTRL_READY_) && --to)
+               udelay(1000);
+
+       return (to == 0) ? -EIO : 0;
+}
+
+#else
+#define smsc911x_suspend       NULL
+#define smsc911x_resume                NULL
+#endif
+
 static struct platform_driver smsc911x_driver = {
        .probe = smsc911x_drv_probe,
-       .remove = smsc911x_drv_remove,
+       .remove = __devexit_p(smsc911x_drv_remove),
        .driver = {
                .name = SMSC_CHIPNAME,
        },
+       .suspend = smsc911x_suspend,
+       .resume = smsc911x_resume,
 };
 
 /* Entry point for loading the module */
index 211e805c122350a2707e90858321d8a8fd4a5a60..e4255d82938063dd73dfb7521064fe2d4e920892 100644 (file)
@@ -223,7 +223,7 @@ static int sonic_send_packet(struct sk_buff *skb, struct net_device *dev)
        if (!laddr) {
                printk(KERN_ERR "%s: failed to map tx DMA buffer.\n", dev->name);
                dev_kfree_skb(skb);
-               return 1;
+               return NETDEV_TX_BUSY
        }
 
        sonic_tda_put(dev, entry, SONIC_TD_STATUS, 0);       /* clear status */
index fcb943fca4f128716312257bbbb6e26a1cebc40e..838cce8b8fff3969286408536ad92b06f36e6063 100644 (file)
@@ -1236,7 +1236,7 @@ static int start_tx(struct sk_buff *skb, struct net_device *dev)
         */
        if ((np->cur_tx - np->dirty_tx) + skb_num_frags(skb) * 2 > TX_RING_SIZE) {
                netif_stop_queue(dev);
-               return 1;
+               return NETDEV_TX_BUSY;
        }
 
 #if defined(ZEROCOPY) && defined(HAS_BROKEN_FIRMWARE)
index a39c0b9ba8b6e57fa3f0efc279eff04e3f6a1e17..7bb27426dbd669e7d43e770e00885937861aaa86 100644 (file)
@@ -1023,7 +1023,7 @@ static int sun3_82586_send_packet(struct sk_buff *skb, struct net_device *dev)
 #if(NUM_XMIT_BUFFS > 1)
        if(test_and_set_bit(0,(void *) &p->lock)) {
                printk("%s: Queue was locked\n",dev->name);
-               return 1;
+               return NETDEV_TX_BUSY;
        }
        else
 #endif
index e5beb299cbd0192fe3925c9ff7a15aa2c62cb0a3..534dfe3eef6ffdeabd173a1dbd00d0c20ae01a9f 100644 (file)
@@ -294,6 +294,16 @@ out:
        return ERR_PTR(err);
 }
 
+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_mac_address    = NULL,
+       .ndo_change_mtu         = eth_change_mtu,
+       .ndo_validate_addr      = eth_validate_addr,
+};
+
 static int __init lance_probe( struct net_device *dev)
 {
        unsigned long ioaddr;
@@ -397,12 +407,7 @@ static int __init lance_probe( struct net_device *dev)
        if (did_version++ == 0)
                printk( version );
 
-       /* The LANCE-specific entries in the device structure. */
-       dev->open = &lance_open;
-       dev->hard_start_xmit = &lance_start_xmit;
-       dev->stop = &lance_close;
-       dev->set_multicast_list = &set_multicast_list;
-       dev->set_mac_address = NULL;
+       dev->netdev_ops = &lance_netdev_ops;
 //     KLUDGE -- REMOVE ME
        set_bit(__LINK_STATE_PRESENT, &dev->state);
 
@@ -521,7 +526,7 @@ static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev )
        if (netif_queue_stopped(dev)) {
                int tickssofar = jiffies - dev->trans_start;
                if (tickssofar < 20)
-                       return( 1 );
+                       return NETDEV_TX_BUSY;
 
                DPRINTK( 1, ( "%s: transmit timed out, status %04x, resetting.\n",
                                          dev->name, DREG ));
@@ -572,7 +577,7 @@ static int lance_start_xmit( struct sk_buff *skb, struct net_device *dev )
        if (test_and_set_bit( 0, (void*)&lp->lock ) != 0) {
                printk( "%s: tx queue lock!.\n", dev->name);
                /* don't clear dev->tbusy flag. */
-               return 1;
+               return NETDEV_TX_BUSY;
        }
 
        AREG = CSR0;
index c399b1955c1eec016a037e67059f57d2f3f8eebc..545f81b34ad7ee7ba8e055e90135437e98bdc87b 100644 (file)
@@ -369,7 +369,6 @@ struct netdev_private {
        struct sk_buff* tx_skbuff[TX_RING_SIZE];
         dma_addr_t tx_ring_dma;
         dma_addr_t rx_ring_dma;
-       struct net_device_stats stats;
        struct timer_list timer;                /* Media monitoring timer. */
        /* Frequently used values: keep some adjacent for cache effect. */
        spinlock_t lock;
@@ -975,7 +974,7 @@ static void tx_timeout(struct net_device *dev)
        dev->if_port = 0;
 
        dev->trans_start = jiffies;
-       np->stats.tx_errors++;
+       dev->stats.tx_errors++;
        if (np->cur_tx - np->dirty_tx < TX_QUEUE_LEN - 4) {
                netif_wake_queue(dev);
        }
@@ -1123,7 +1122,7 @@ reset_tx (struct net_device *dev)
                        else
                                dev_kfree_skb (skb);
                        np->tx_skbuff[i] = NULL;
-                       np->stats.tx_dropped++;
+                       dev->stats.tx_dropped++;
                }
        }
        np->cur_tx = np->dirty_tx = 0;
@@ -1181,15 +1180,15 @@ static irqreturn_t intr_handler(int irq, void *dev_instance)
                                        if (netif_msg_tx_err(np))
                                                printk("%s: Transmit error status %4.4x.\n",
                                                           dev->name, tx_status);
-                                       np->stats.tx_errors++;
+                                       dev->stats.tx_errors++;
                                        if (tx_status & 0x10)
-                                               np->stats.tx_fifo_errors++;
+                                               dev->stats.tx_fifo_errors++;
                                        if (tx_status & 0x08)
-                                               np->stats.collisions++;
+                                               dev->stats.collisions++;
                                        if (tx_status & 0x04)
-                                               np->stats.tx_fifo_errors++;
+                                               dev->stats.tx_fifo_errors++;
                                        if (tx_status & 0x02)
-                                               np->stats.tx_window_errors++;
+                                               dev->stats.tx_window_errors++;
 
                                        /*
                                        ** This reset has been verified on
@@ -1313,11 +1312,15 @@ static void rx_poll(unsigned long data)
                        if (netif_msg_rx_err(np))
                                printk(KERN_DEBUG "  netdev_rx() Rx error was %8.8x.\n",
                                           frame_status);
-                       np->stats.rx_errors++;
-                       if (frame_status & 0x00100000) np->stats.rx_length_errors++;
-                       if (frame_status & 0x00010000) np->stats.rx_fifo_errors++;
-                       if (frame_status & 0x00060000) np->stats.rx_frame_errors++;
-                       if (frame_status & 0x00080000) np->stats.rx_crc_errors++;
+                       dev->stats.rx_errors++;
+                       if (frame_status & 0x00100000)
+                               dev->stats.rx_length_errors++;
+                       if (frame_status & 0x00010000)
+                               dev->stats.rx_fifo_errors++;
+                       if (frame_status & 0x00060000)
+                               dev->stats.rx_frame_errors++;
+                       if (frame_status & 0x00080000)
+                               dev->stats.rx_crc_errors++;
                        if (frame_status & 0x00100000) {
                                printk(KERN_WARNING "%s: Oversized Ethernet frame,"
                                           " status %8.8x.\n",
@@ -1485,22 +1488,22 @@ static struct net_device_stats *get_stats(struct net_device *dev)
           the vulnerability window is very small and statistics are
           non-critical. */
        /* The chip only need report frame silently dropped. */
-       np->stats.rx_missed_errors      += ioread8(ioaddr + RxMissed);
-       np->stats.tx_packets += ioread16(ioaddr + TxFramesOK);
-       np->stats.rx_packets += ioread16(ioaddr + RxFramesOK);
-       np->stats.collisions += ioread8(ioaddr + StatsLateColl);
-       np->stats.collisions += ioread8(ioaddr + StatsMultiColl);
-       np->stats.collisions += ioread8(ioaddr + StatsOneColl);
-       np->stats.tx_carrier_errors += ioread8(ioaddr + StatsCarrierError);
+       dev->stats.rx_missed_errors     += ioread8(ioaddr + RxMissed);
+       dev->stats.tx_packets += ioread16(ioaddr + TxFramesOK);
+       dev->stats.rx_packets += ioread16(ioaddr + RxFramesOK);
+       dev->stats.collisions += ioread8(ioaddr + StatsLateColl);
+       dev->stats.collisions += ioread8(ioaddr + StatsMultiColl);
+       dev->stats.collisions += ioread8(ioaddr + StatsOneColl);
+       dev->stats.tx_carrier_errors += ioread8(ioaddr + StatsCarrierError);
        ioread8(ioaddr + StatsTxDefer);
        for (i = StatsTxDefer; i <= StatsMcastRx; i++)
                ioread8(ioaddr + i);
-       np->stats.tx_bytes += ioread16(ioaddr + TxOctetsLow);
-       np->stats.tx_bytes += ioread16(ioaddr + TxOctetsHigh) << 16;
-       np->stats.rx_bytes += ioread16(ioaddr + RxOctetsLow);
-       np->stats.rx_bytes += ioread16(ioaddr + RxOctetsHigh) << 16;
+       dev->stats.tx_bytes += ioread16(ioaddr + TxOctetsLow);
+       dev->stats.tx_bytes += ioread16(ioaddr + TxOctetsHigh) << 16;
+       dev->stats.rx_bytes += ioread16(ioaddr + RxOctetsLow);
+       dev->stats.rx_bytes += ioread16(ioaddr + RxOctetsHigh) << 16;
 
-       return &np->stats;
+       return &dev->stats;
 }
 
 static void set_rx_mode(struct net_device *dev)
index 4e9bd380a5c2ea2b50661627e439da2a9bc2712e..4ef729198e10b6630692fef18b2a47cb88bc10b6 100644 (file)
@@ -2275,7 +2275,7 @@ static int happy_meal_start_xmit(struct sk_buff *skb, struct net_device *dev)
                spin_unlock_irq(&hp->happy_lock);
                printk(KERN_ERR "%s: BUG! Tx Ring full when queue awake!\n",
                       dev->name);
-               return 1;
+               return NETDEV_TX_BUSY;
        }
 
        entry = hp->tx_new;
index 0ce2db6ce2bf17b546b0c82be39db5ac84305344..d737f6b8f876900a8c772d45beb8ea977de5546a 100644 (file)
@@ -688,14 +688,11 @@ static void tc_handle_link_change(struct net_device *dev)
 
        if (status_change && netif_msg_link(lp)) {
                phy_print_status(phydev);
-#ifdef DEBUG
-               printk(KERN_DEBUG
-                      "%s: MII BMCR %04x BMSR %04x LPA %04x\n",
-                      dev->name,
-                      phy_read(phydev, MII_BMCR),
-                      phy_read(phydev, MII_BMSR),
-                      phy_read(phydev, MII_LPA));
-#endif
+               pr_debug("%s: MII BMCR %04x BMSR %04x LPA %04x\n",
+                        dev->name,
+                        phy_read(phydev, MII_BMCR),
+                        phy_read(phydev, MII_BMSR),
+                        phy_read(phydev, MII_LPA));
        }
 }
 
index 7f4a9683ba1e4962ebcf08025cce066383ec0e0d..3c2679cd196bdd7da13ab94e4dfb085cc4e57a62 100644 (file)
@@ -948,8 +948,7 @@ static void print_rxfd(struct rxf_desc *rxfd);
 
 static void bdx_rxdb_destroy(struct rxdb *db)
 {
-       if (db)
-               vfree(db);
+       vfree(db);
 }
 
 static struct rxdb *bdx_rxdb_create(int nelem)
@@ -1482,10 +1481,8 @@ static void bdx_tx_db_close(struct txdb *d)
 {
        BDX_ASSERT(d == NULL);
 
-       if (d->start) {
-               vfree(d->start);
-               d->start = NULL;
-       }
+       vfree(d->start);
+       d->start = NULL;
 }
 
 /*************************************************************************
@@ -1718,8 +1715,9 @@ static int bdx_tx_transmit(struct sk_buff *skb, struct net_device *ndev)
        WRITE_REG(priv, f->m.reg_WPTR, f->m.wptr & TXF_WPTR_WR_PTR);
 
 #endif
-       ndev->trans_start = jiffies;
-
+#ifdef BDX_LLTX
+       ndev->trans_start = jiffies; /* NETIF_F_LLTX driver :( */
+#endif
        priv->net_stats.tx_packets++;
        priv->net_stats.tx_bytes += skb->len;
 
index 201be425643a6fb7acb8801bbbb718897c9a6431..46a3f86125be7659e4f35700a6ee209914febcea 100644 (file)
@@ -68,8 +68,8 @@
 
 #define DRV_MODULE_NAME                "tg3"
 #define PFX DRV_MODULE_NAME    ": "
-#define DRV_MODULE_VERSION     "3.98"
-#define DRV_MODULE_RELDATE     "February 25, 2009"
+#define DRV_MODULE_VERSION     "3.99"
+#define DRV_MODULE_RELDATE     "April 20, 2009"
 
 #define TG3_DEF_MAC_MODE       0
 #define TG3_DEF_RX_MODE                0
@@ -1950,7 +1950,8 @@ static void tg3_frob_aux_power(struct tg3 *tp)
                                     GRC_LCLCTRL_GPIO_OUTPUT0 |
                                     GRC_LCLCTRL_GPIO_OUTPUT1),
                                    100);
-               } else if (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5761) {
+               } else if (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5761 ||
+                          tp->pdev->device == TG3PCI_DEVICE_TIGON3_5761S) {
                        /* The 5761 non-e device swaps GPIO 0 and GPIO 2. */
                        u32 grc_local_ctrl = GRC_LCLCTRL_GPIO_OE0 |
                                             GRC_LCLCTRL_GPIO_OE1 |
@@ -2455,8 +2456,6 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
                }
        }
 
-       __tg3_set_mac_addr(tp, 0);
-
        if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
                u32 val;
 
@@ -4656,6 +4655,7 @@ static int tg3_poll(struct napi_struct *napi, int budget)
                         * so we must read it before checking for more work.
                         */
                        tp->last_tag = sblk->status_tag;
+                       tp->last_irq_tag = tp->last_tag;
                        rmb();
                } else
                        sblk->status &= ~SD_STATUS_UPDATED;
@@ -4811,7 +4811,7 @@ static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id)
         * Reading the PCI State register will confirm whether the
         * interrupt is ours and will flush the status block.
         */
-       if (unlikely(sblk->status_tag == tp->last_tag)) {
+       if (unlikely(sblk->status_tag == tp->last_irq_tag)) {
                if ((tp->tg3_flags & TG3_FLAG_CHIP_RESETTING) ||
                    (tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) {
                        handled = 0;
@@ -4831,18 +4831,22 @@ static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id)
         * excessive spurious interrupts can be worse in some cases.
         */
        tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001);
+
+       /*
+        * In a shared interrupt configuration, sometimes other devices'
+        * interrupts will scream.  We record the current status tag here
+        * so that the above check can report that the screaming interrupts
+        * are unhandled.  Eventually they will be silenced.
+        */
+       tp->last_irq_tag = sblk->status_tag;
+
        if (tg3_irq_sync(tp))
                goto out;
-       if (napi_schedule_prep(&tp->napi)) {
-               prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]);
-               /* Update last_tag to mark that this status has been
-                * seen. Because interrupt may be shared, we may be
-                * racing with tg3_poll(), so only update last_tag
-                * if tg3_poll() is not scheduled.
-                */
-               tp->last_tag = sblk->status_tag;
-               __napi_schedule(&tp->napi);
-       }
+
+       prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]);
+
+       napi_schedule(&tp->napi);
+
 out:
        return IRQ_RETVAL(handled);
 }
@@ -5017,7 +5021,7 @@ static int tigon3_dma_hwbug_workaround(struct tg3 *tp, struct sk_buff *skb,
                /* New SKB is guaranteed to be linear. */
                entry = *start;
                ret = skb_dma_map(&tp->pdev->dev, new_skb, DMA_TO_DEVICE);
-               new_addr = skb_shinfo(new_skb)->dma_maps[0];
+               new_addr = skb_shinfo(new_skb)->dma_head;
 
                /* Make sure new skb does not cross any 4G boundaries.
                 * Drop the packet if it does.
@@ -5151,7 +5155,7 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
        sp = skb_shinfo(skb);
 
-       mapping = sp->dma_maps[0];
+       mapping = sp->dma_head;
 
        tp->tx_buffers[entry].skb = skb;
 
@@ -5169,7 +5173,7 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
                        skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
 
                        len = frag->size;
-                       mapping = sp->dma_maps[i + 1];
+                       mapping = sp->dma_maps[i];
                        tp->tx_buffers[entry].skb = NULL;
 
                        tg3_set_txd(tp, entry, mapping, len,
@@ -5190,9 +5194,7 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
        }
 
 out_unlock:
-       mmiowb();
-
-       dev->trans_start = jiffies;
+       mmiowb();
 
        return NETDEV_TX_OK;
 }
@@ -5329,7 +5331,7 @@ static int tg3_start_xmit_dma_bug(struct sk_buff *skb, struct net_device *dev)
 
        sp = skb_shinfo(skb);
 
-       mapping = sp->dma_maps[0];
+       mapping = sp->dma_head;
 
        tp->tx_buffers[entry].skb = skb;
 
@@ -5354,7 +5356,7 @@ static int tg3_start_xmit_dma_bug(struct sk_buff *skb, struct net_device *dev)
                        skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
 
                        len = frag->size;
-                       mapping = sp->dma_maps[i + 1];
+                       mapping = sp->dma_maps[i];
 
                        tp->tx_buffers[entry].skb = NULL;
 
@@ -5403,9 +5405,7 @@ static int tg3_start_xmit_dma_bug(struct sk_buff *skb, struct net_device *dev)
        }
 
 out_unlock:
-       mmiowb();
-
-       dev->trans_start = jiffies;
+       mmiowb();
 
        return NETDEV_TX_OK;
 }
@@ -6156,6 +6156,7 @@ static int tg3_chip_reset(struct tg3 *tp)
                tp->hw_status->status_tag = 0;
        }
        tp->last_tag = 0;
+       tp->last_irq_tag = 0;
        smp_mb();
        synchronize_irq(tp->pdev->irq);
 
@@ -6350,6 +6351,8 @@ static int tg3_halt(struct tg3 *tp, int kind, int silent)
        tg3_abort_hw(tp, silent);
        err = tg3_chip_reset(tp);
 
+       __tg3_set_mac_addr(tp, 0);
+
        tg3_write_sig_legacy(tp, kind);
        tg3_write_sig_post_reset(tp, kind);
 
@@ -6711,6 +6714,13 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
                tw32(TG3_CPMU_HST_ACC, val);
        }
 
+       if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780) {
+               val = tr32(PCIE_PWR_MGMT_THRESH) & ~PCIE_PWR_MGMT_L1_THRESH_MSK;
+               val |= PCIE_PWR_MGMT_EXT_ASPM_TMR_EN |
+                      PCIE_PWR_MGMT_L1_THRESH_4MS;
+               tw32(PCIE_PWR_MGMT_THRESH, val);
+       }
+
        /* This works around an issue with Athlon chipsets on
         * B3 tigon3 silicon.  This bit has no effect on any
         * other revision.  But do not set this on PCI Express
@@ -7138,7 +7148,6 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
        udelay(100);
 
        tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0);
-       tp->last_tag = 0;
 
        if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) {
                tw32_f(DMAC_MODE, DMAC_MODE_ENABLE);
@@ -8539,6 +8548,9 @@ static int tg3_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
        u32 i, offset, len, b_offset, b_count;
        __be32 val;
 
+       if (tp->tg3_flags3 & TG3_FLG3_NO_NVRAM)
+               return -EINVAL;
+
        if (tp->link_config.phy_is_low_power)
                return -EAGAIN;
 
@@ -8604,7 +8616,8 @@ static int tg3_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
        if (tp->link_config.phy_is_low_power)
                return -EAGAIN;
 
-       if (eeprom->magic != TG3_EEPROM_MAGIC)
+       if ((tp->tg3_flags3 & TG3_FLG3_NO_NVRAM) ||
+           eeprom->magic != TG3_EEPROM_MAGIC)
                return -EINVAL;
 
        offset = eeprom->offset;
@@ -9201,6 +9214,9 @@ static int tg3_test_nvram(struct tg3 *tp)
        __be32 *buf;
        int i, j, k, err = 0, size;
 
+       if (tp->tg3_flags3 & TG3_FLG3_NO_NVRAM)
+               return 0;
+
        if (tg3_nvram_read(tp, 0, &magic) != 0)
                return -EIO;
 
@@ -10183,7 +10199,8 @@ static void __devinit tg3_get_nvram_size(struct tg3 *tp)
 {
        u32 val;
 
-       if (tg3_nvram_read(tp, 0, &val) != 0)
+       if ((tp->tg3_flags3 & TG3_FLG3_NO_NVRAM) ||
+           tg3_nvram_read(tp, 0, &val) != 0)
                return;
 
        /* Selfboot format */
@@ -10565,6 +10582,7 @@ static void __devinit tg3_get_57780_nvram_info(struct tg3 *tp)
                }
                break;
        default:
+               tp->tg3_flags3 |= TG3_FLG3_NO_NVRAM;
                return;
        }
 
@@ -11365,7 +11383,8 @@ static void __devinit tg3_read_partno(struct tg3 *tp)
        unsigned int i;
        u32 magic;
 
-       if (tg3_nvram_read(tp, 0x0, &magic))
+       if ((tp->tg3_flags3 & TG3_FLG3_NO_NVRAM) ||
+           tg3_nvram_read(tp, 0x0, &magic))
                goto out_not_found;
 
        if (magic == TG3_EEPROM_MAGIC) {
@@ -11457,6 +11476,15 @@ static void __devinit tg3_read_partno(struct tg3 *tp)
 out_not_found:
        if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
                strcpy(tp->board_part_number, "BCM95906");
+       else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 &&
+                tp->pdev->device == TG3PCI_DEVICE_TIGON3_57780)
+               strcpy(tp->board_part_number, "BCM57780");
+       else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 &&
+                tp->pdev->device == TG3PCI_DEVICE_TIGON3_57760)
+               strcpy(tp->board_part_number, "BCM57760");
+       else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 &&
+                tp->pdev->device == TG3PCI_DEVICE_TIGON3_57790)
+               strcpy(tp->board_part_number, "BCM57790");
        else
                strcpy(tp->board_part_number, "none");
 }
@@ -11667,6 +11695,14 @@ static void __devinit tg3_read_fw_ver(struct tg3 *tp)
 {
        u32 val;
 
+       if (tp->tg3_flags3 & TG3_FLG3_NO_NVRAM) {
+               tp->fw_ver[0] = 's';
+               tp->fw_ver[1] = 'b';
+               tp->fw_ver[2] = '\0';
+
+               return;
+       }
+
        if (tg3_nvram_read(tp, 0, &val))
                return;
 
@@ -11952,7 +11988,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
                                tp->tg3_flags2 &= ~TG3_FLG2_HW_TSO_2;
                        if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
                            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
-                           GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780)
+                           tp->pci_chip_rev_id == CHIPREV_ID_57780_A0 ||
+                           tp->pci_chip_rev_id == CHIPREV_ID_57780_A1)
                                tp->tg3_flags3 |= TG3_FLG3_CLKREQ_BUG;
                }
        } else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785) {
@@ -12144,7 +12181,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
            GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780)
                tp->grc_local_ctrl |= GRC_LCLCTRL_GPIO_UART_SEL;
 
-       if (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5761) {
+       if (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5761 ||
+           tp->pdev->device == TG3PCI_DEVICE_TIGON3_5761S) {
                /* Turn off the debug UART. */
                tp->grc_local_ctrl |= GRC_LCLCTRL_GPIO_UART_SEL;
                if (tp->tg3_flags2 & TG3_FLG2_IS_NIC)
@@ -12454,7 +12492,8 @@ static int __devinit tg3_get_device_address(struct tg3 *tp)
        }
        if (!addr_ok) {
                /* Next, try NVRAM. */
-               if (!tg3_nvram_read_be32(tp, mac_offset + 0, &hi) &&
+               if (!(tp->tg3_flags3 & TG3_FLG3_NO_NVRAM) &&
+                   !tg3_nvram_read_be32(tp, mac_offset + 0, &hi) &&
                    !tg3_nvram_read_be32(tp, mac_offset + 4, &lo)) {
                        memcpy(&dev->dev_addr[0], ((char *)&hi) + 2, 2);
                        memcpy(&dev->dev_addr[2], (char *)&lo, sizeof(lo));
index cb4c62abdd2142c9295fc170f8463a79c8358d18..b3347c41a1a3df0652b119cb3626407f2b71306d 100644 (file)
@@ -95,6 +95,8 @@
 #define  CHIPREV_ID_5752_A1             0x6001
 #define  CHIPREV_ID_5714_A2             0x9002
 #define  CHIPREV_ID_5906_A1             0xc001
+#define  CHIPREV_ID_57780_A0            0x57780000
+#define  CHIPREV_ID_57780_A1            0x57780001
 #define  GET_ASIC_REV(CHIP_REV_ID)     ((CHIP_REV_ID) >> 12)
 #define   ASIC_REV_5700                         0x07
 #define   ASIC_REV_5701                         0x00
 
 #define PCIE_PWR_MGMT_THRESH           0x00007d28
 #define PCIE_PWR_MGMT_L1_THRESH_MSK     0x0000ff00
+#define PCIE_PWR_MGMT_L1_THRESH_4MS     0x0000ff00
+#define PCIE_PWR_MGMT_EXT_ASPM_TMR_EN   0x01000000
 
 
 /* OTP bit definitions */
@@ -2501,6 +2505,7 @@ struct tg3 {
        struct tg3_hw_status            *hw_status;
        dma_addr_t                      status_mapping;
        u32                             last_tag;
+       u32                             last_irq_tag;
 
        u32                             msg_enable;
 
@@ -2635,6 +2640,7 @@ struct tg3 {
 #define TG3_FLG3_CLKREQ_BUG            0x00000800
 #define TG3_FLG3_PHY_ENABLE_APD                0x00001000
 #define TG3_FLG3_5755_PLUS             0x00002000
+#define TG3_FLG3_NO_NVRAM              0x00004000
 
        struct timer_list               timer;
        u16                             timer_counter;
index aa6964922d5e20b54be7d5c6238b2ca72312a8f3..384cb5e28397924536bdbf79fa43ffbf8bb30b55 100644 (file)
@@ -1111,7 +1111,7 @@ static int TLan_StartTx( struct sk_buff *skb, struct net_device *dev )
                          dev->name, priv->txHead, priv->txTail );
                netif_stop_queue(dev);
                priv->txBusyCount++;
-               return 1;
+               return NETDEV_TX_BUSY;
        }
 
        tail_list->forward = 0;
index 0337b9d673f46d45bbbbf083545ba4a76d5d0fbb..b40b6de2d086fc8a8d761c30e9fb74e99062b4e4 100644 (file)
@@ -1243,7 +1243,7 @@ static int xl_xmit(struct sk_buff *skb, struct net_device *dev)
                return 0;
        } else {
                spin_unlock_irqrestore(&xl_priv->xl_lock,flags) ; 
-               return 1;
+               return NETDEV_TX_BUSY;
        }
 
 }
index 46a2cc92d97988ab605a9c6209a81737bd424dd8..b3715efdce562ee13acb5ac860191c0c07637260 100644 (file)
@@ -1187,7 +1187,7 @@ static int streamer_xmit(struct sk_buff *skb, struct net_device *dev)
        } else {
                netif_stop_queue(dev);
                spin_unlock_irqrestore(&streamer_priv->streamer_lock,flags);
-               return 1;
+               return NETDEV_TX_BUSY;
        }
 }
 
index 2d819fc85589609b42debab889e29ab00ade265d..451b54136ede04a82d1db929a136c440647a3799 100644 (file)
@@ -1055,7 +1055,7 @@ static int olympic_xmit(struct sk_buff *skb, struct net_device *dev)
                return 0;
        } else {
                spin_unlock_irqrestore(&olympic_priv->olympic_lock,flags);
-               return 1;
+               return NETDEV_TX_BUSY;
        } 
 
 }
index a91d9c55d78e94b28718c8dfdc83b62521d2a0d6..54ad4ed0337406d9ef46ed3e8a2a4397c8449db0 100644 (file)
@@ -4601,7 +4601,7 @@ static int smctr_send_packet(struct sk_buff *skb, struct net_device *dev)
         netif_stop_queue(dev);
 
         if(tp->QueueSkb == 0)
-                return (1);     /* Return with tbusy set: queue full */
+                return NETDEV_TX_BUSY;     /* Return with tbusy set: queue full */
 
         tp->QueueSkb--;
         skb_queue_tail(&tp->SendSkbQueue, skb);
index b11bb72dc7abae085326c605351cd92f52c6f70d..a2eab72b507a6473c4d72d43c2bdc8f3e68bf3a8 100644 (file)
@@ -633,7 +633,7 @@ static int tms380tr_hardware_send_packet(struct sk_buff *skb, struct net_device
                if (tms380tr_debug > 0)
                        printk(KERN_DEBUG "%s: No free TPL\n", dev->name);
                spin_unlock_irqrestore(&tp->lock, flags);
-               return 1;
+               return NETDEV_TX_BUSY;
        }
 
        dmabuf = 0;
index d913405bc39335f480f382d2c408b7d211889b5d..1cc8cf4425d18a576e5c8829a1bbfb0461bb0f18 100644 (file)
@@ -27,6 +27,18 @@ config DE2104X
          To compile this driver as a module, choose M here. The module will
          be called de2104x.
 
+config DE2104X_DSL
+       int "Descriptor Skip Length in 32 bit longwords"
+       depends on DE2104X
+       range 0 31
+       default 0
+       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
+         cache coherence, an example is PowerMac 5500. Otherwise 0 is safe.
+         Default is 0, and range is 0 to 31.
+
 config TULIP
        tristate "DECchip Tulip (dc2114x) PCI support"
        depends on PCI
index d4c5ecc51f779e975eff00a72413a46ae4c171b2..81f054dbb88ddb2712bc6d60921f857c3920a05e 100644 (file)
@@ -82,6 +82,13 @@ MODULE_PARM_DESC (rx_copybreak, "de2104x Breakpoint at which Rx packets are copi
                                 NETIF_MSG_RX_ERR       | \
                                 NETIF_MSG_TX_ERR)
 
+/* Descriptor skip length in 32 bit longwords. */
+#ifndef CONFIG_DE2104X_DSL
+#define DSL                    0
+#else
+#define DSL                    CONFIG_DE2104X_DSL
+#endif
+
 #define DE_RX_RING_SIZE                64
 #define DE_TX_RING_SIZE                64
 #define DE_RING_BYTES          \
@@ -153,6 +160,7 @@ enum {
        CmdReset                = (1 << 0),
        CacheAlign16            = 0x00008000,
        BurstLen4               = 0x00000400,
+       DescSkipLen             = (DSL << 2),
 
        /* Rx/TxPoll bits */
        NormalTxPoll            = (1 << 0),
@@ -246,7 +254,7 @@ static const u32 de_intr_mask =
  * Set the programmable burst length to 4 longwords for all:
  * DMA errors result without these values. Cache align 16 long.
  */
-static const u32 de_bus_mode = CacheAlign16 | BurstLen4;
+static const u32 de_bus_mode = CacheAlign16 | BurstLen4 | DescSkipLen;
 
 struct de_srom_media_block {
        u8                      opts;
@@ -266,6 +274,9 @@ struct de_desc {
        __le32                  opts2;
        __le32                  addr1;
        __le32                  addr2;
+#if DSL
+       __le32                  skip[DSL];
+#endif
 };
 
 struct media_info {
@@ -601,7 +612,7 @@ static int de_start_xmit (struct sk_buff *skb, struct net_device *dev)
        if (tx_free == 0) {
                netif_stop_queue(dev);
                spin_unlock_irq(&de->lock);
-               return 1;
+               return NETDEV_TX_BUSY;
        }
        tx_free--;
 
index f9491bd787d1ac06c0032a2524b5cc52b31c7f60..eb72d2e9ab3d1366f2347969d35ba31efc16630b 100644 (file)
@@ -1099,7 +1099,7 @@ de4x5_hw_init(struct net_device *dev, u_long iobase, struct device *gendev)
     struct pci_dev *pdev = NULL;
     int i, status=0;
 
-    gendev->driver_data = dev;
+    dev_set_drvdata(gendev, dev);
 
     /* Ensure we're not sleeping */
     if (lp->bus == EISA) {
@@ -1461,12 +1461,12 @@ de4x5_queue_pkt(struct sk_buff *skb, struct net_device *dev)
 {
     struct de4x5_private *lp = netdev_priv(dev);
     u_long iobase = dev->base_addr;
-    int status = 0;
+    int status = NETDEV_TX_OK;
     u_long flags = 0;
 
     netif_stop_queue(dev);
     if (!lp->tx_enable) {                   /* Cannot send for now */
-       return -1;
+       return NETDEV_TX_LOCKED;
     }
 
     /*
@@ -1480,7 +1480,7 @@ de4x5_queue_pkt(struct sk_buff *skb, struct net_device *dev)
 
     /* Test if cache is already locked - requeue skb if so */
     if (test_and_set_bit(0, (void *)&lp->cache.lock) && !lp->interrupt)
-       return -1;
+       return NETDEV_TX_LOCKED;
 
     /* Transmit descriptor ring full or stale skb */
     if (netif_queue_stopped(dev) || (u_long) lp->tx_skb[lp->tx_new] > 1) {
@@ -2094,7 +2094,7 @@ static int __devexit de4x5_eisa_remove (struct device *device)
        struct net_device *dev;
        u_long iobase;
 
-       dev = device->driver_data;
+       dev = dev_get_drvdata(device);
        iobase = dev->base_addr;
 
        unregister_netdev (dev);
@@ -2338,7 +2338,7 @@ static void __devexit de4x5_pci_remove (struct pci_dev *pdev)
        struct net_device *dev;
        u_long iobase;
 
-       dev = pdev->dev.driver_data;
+       dev = dev_get_drvdata(&pdev->dev);
        iobase = dev->base_addr;
 
        unregister_netdev (dev);
index f2e669974c787e0270a403f85235e0e4375dc0b4..8e78f003f08f6c559f8d1ce12493ef4b9095b58c 100644 (file)
@@ -686,7 +686,7 @@ static int dmfe_start_xmit(struct sk_buff *skb, struct DEVICE *dev)
                spin_unlock_irqrestore(&db->lock, flags);
                printk(KERN_ERR DRV_NAME ": No Tx resource %ld\n",
                       db->tx_queue_cnt);
-               return 1;
+               return NETDEV_TX_BUSY;
        }
 
        /* Disable NIC interrupt */
index 8761a5a5bd79bdc620d3af577202a9b6e688239e..9277ce8febe4c60deb659b25add3385800975fe4 100644 (file)
@@ -591,7 +591,7 @@ static int uli526x_start_xmit(struct sk_buff *skb, struct net_device *dev)
        if (db->tx_packet_cnt >= TX_FREE_DESC_CNT) {
                spin_unlock_irqrestore(&db->lock, flags);
                printk(KERN_ERR DRV_NAME ": No Tx resource %ld\n", db->tx_packet_cnt);
-               return 1;
+               return NETDEV_TX_BUSY;
        }
 
        /* Disable NIC interrupt */
index 264e61404f345a8d36d9ee2cdabf2df4ec2a99f9..842b1a2c40d4abed18d9d241c8759f1daaaae8be 100644 (file)
@@ -1601,8 +1601,7 @@ static int w840_suspend (struct pci_dev *pdev, pm_message_t state)
 
                /* no more hardware accesses behind this line. */
 
-               BUG_ON(np->csr6);
-               if (ioread32(ioaddr + IntrEnable)) BUG();
+               BUG_ON(np->csr6 || ioread32(ioaddr + IntrEnable));
 
                /* pci_power_off(pdev, -1); */
 
index 735bf41c654ab459a6bf556bbf6d8242b8117797..811d3517fce0c99895b4738df64a60d934f86fcf 100644 (file)
@@ -540,31 +540,38 @@ static inline struct sk_buff *tun_alloc_skb(struct tun_struct *tun,
 
 /* Get packet from user space buffer */
 static __inline__ ssize_t tun_get_user(struct tun_struct *tun,
-                                      struct iovec *iv, size_t count,
+                                      const struct iovec *iv, size_t count,
                                       int noblock)
 {
        struct tun_pi pi = { 0, cpu_to_be16(ETH_P_IP) };
        struct sk_buff *skb;
        size_t len = count, align = 0;
        struct virtio_net_hdr gso = { 0 };
+       int offset = 0;
 
        if (!(tun->flags & TUN_NO_PI)) {
                if ((len -= sizeof(pi)) > count)
                        return -EINVAL;
 
-               if(memcpy_fromiovec((void *)&pi, iv, sizeof(pi)))
+               if (memcpy_fromiovecend((void *)&pi, iv, 0, sizeof(pi)))
                        return -EFAULT;
+               offset += sizeof(pi);
        }
 
        if (tun->flags & TUN_VNET_HDR) {
                if ((len -= sizeof(gso)) > count)
                        return -EINVAL;
 
-               if (memcpy_fromiovec((void *)&gso, iv, sizeof(gso)))
+               if (memcpy_fromiovecend((void *)&gso, iv, offset, sizeof(gso)))
                        return -EFAULT;
 
+               if ((gso.flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) &&
+                   gso.csum_start + gso.csum_offset + 2 > gso.hdr_len)
+                       gso.hdr_len = gso.csum_start + gso.csum_offset + 2;
+
                if (gso.hdr_len > len)
                        return -EINVAL;
+               offset += sizeof(gso);
        }
 
        if ((tun->flags & TUN_TYPE_MASK) == TUN_TAP_DEV) {
@@ -581,7 +588,7 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun,
                return PTR_ERR(skb);
        }
 
-       if (skb_copy_datagram_from_iovec(skb, 0, iv, len)) {
+       if (skb_copy_datagram_from_iovec(skb, 0, iv, offset, len)) {
                tun->dev->stats.rx_dropped++;
                kfree_skb(skb);
                return -EFAULT;
@@ -673,7 +680,7 @@ static ssize_t tun_chr_aio_write(struct kiocb *iocb, const struct iovec *iv,
 
        DBG(KERN_INFO "%s: tun_chr_write %ld\n", tun->dev->name, count);
 
-       result = tun_get_user(tun, (struct iovec *)iv, iov_length(iv, count),
+       result = tun_get_user(tun, iv, iov_length(iv, count),
                              file->f_flags & O_NONBLOCK);
 
        tun_put(tun);
@@ -683,7 +690,7 @@ static ssize_t tun_chr_aio_write(struct kiocb *iocb, const struct iovec *iv,
 /* Put packet to the user space buffer */
 static __inline__ ssize_t tun_put_user(struct tun_struct *tun,
                                       struct sk_buff *skb,
-                                      struct iovec *iv, int len)
+                                      const struct iovec *iv, int len)
 {
        struct tun_pi pi = { 0, skb->protocol };
        ssize_t total = 0;
@@ -697,7 +704,7 @@ static __inline__ ssize_t tun_put_user(struct tun_struct *tun,
                        pi.flags |= TUN_PKT_STRIP;
                }
 
-               if (memcpy_toiovec(iv, (void *) &pi, sizeof(pi)))
+               if (memcpy_toiovecend(iv, (void *) &pi, 0, sizeof(pi)))
                        return -EFAULT;
                total += sizeof(pi);
        }
@@ -730,14 +737,15 @@ static __inline__ ssize_t tun_put_user(struct tun_struct *tun,
                        gso.csum_offset = skb->csum_offset;
                } /* else everything is zero */
 
-               if (unlikely(memcpy_toiovec(iv, (void *)&gso, sizeof(gso))))
+               if (unlikely(memcpy_toiovecend(iv, (void *)&gso, total,
+                                              sizeof(gso))))
                        return -EFAULT;
                total += sizeof(gso);
        }
 
        len = min_t(int, skb->len, len);
 
-       skb_copy_datagram_iovec(skb, 0, iv, len);
+       skb_copy_datagram_const_iovec(skb, 0, iv, total, len);
        total += len;
 
        tun->dev->stats.tx_packets++;
@@ -792,7 +800,7 @@ static ssize_t tun_chr_aio_read(struct kiocb *iocb, const struct iovec *iv,
                }
                netif_wake_queue(tun->dev);
 
-               ret = tun_put_user(tun, skb, (struct iovec *) iv, len);
+               ret = tun_put_user(tun, skb, iv, len);
                kfree_skb(skb);
                break;
        }
@@ -840,12 +848,12 @@ static void tun_sock_write_space(struct sock *sk)
        if (!sock_writeable(sk))
                return;
 
-       if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
-               wake_up_interruptible_sync(sk->sk_sleep);
-
        if (!test_and_clear_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags))
                return;
 
+       if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
+               wake_up_interruptible_sync(sk->sk_sleep);
+
        tun = container_of(sk, struct tun_sock, sk)->tun;
        kill_fasync(&tun->fasync, SIGIO, POLL_OUT);
 }
@@ -861,6 +869,52 @@ static struct proto tun_proto = {
        .obj_size       = sizeof(struct tun_sock),
 };
 
+static int tun_flags(struct tun_struct *tun)
+{
+       int flags = 0;
+
+       if (tun->flags & TUN_TUN_DEV)
+               flags |= IFF_TUN;
+       else
+               flags |= IFF_TAP;
+
+       if (tun->flags & TUN_NO_PI)
+               flags |= IFF_NO_PI;
+
+       if (tun->flags & TUN_ONE_QUEUE)
+               flags |= IFF_ONE_QUEUE;
+
+       if (tun->flags & TUN_VNET_HDR)
+               flags |= IFF_VNET_HDR;
+
+       return flags;
+}
+
+static ssize_t tun_show_flags(struct device *dev, struct device_attribute *attr,
+                             char *buf)
+{
+       struct tun_struct *tun = netdev_priv(to_net_dev(dev));
+       return sprintf(buf, "0x%x\n", tun_flags(tun));
+}
+
+static ssize_t tun_show_owner(struct device *dev, struct device_attribute *attr,
+                             char *buf)
+{
+       struct tun_struct *tun = netdev_priv(to_net_dev(dev));
+       return sprintf(buf, "%d\n", tun->owner);
+}
+
+static ssize_t tun_show_group(struct device *dev, struct device_attribute *attr,
+                             char *buf)
+{
+       struct tun_struct *tun = netdev_priv(to_net_dev(dev));
+       return sprintf(buf, "%d\n", tun->group);
+}
+
+static DEVICE_ATTR(tun_flags, 0444, tun_show_flags, NULL);
+static DEVICE_ATTR(owner, 0444, tun_show_owner, NULL);
+static DEVICE_ATTR(group, 0444, tun_show_group, NULL);
+
 static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
 {
        struct sock *sk;
@@ -870,6 +924,8 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
 
        dev = __dev_get_by_name(net, ifr->ifr_name);
        if (dev) {
+               if (ifr->ifr_flags & IFF_TUN_EXCL)
+                       return -EBUSY;
                if ((ifr->ifr_flags & IFF_TUN) && dev->netdev_ops == &tun_netdev_ops)
                        tun = netdev_priv(dev);
                else if ((ifr->ifr_flags & IFF_TAP) && dev->netdev_ops == &tap_netdev_ops)
@@ -944,6 +1000,11 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
                if (err < 0)
                        goto err_free_sk;
 
+               if (device_create_file(&tun->dev->dev, &dev_attr_tun_flags) ||
+                   device_create_file(&tun->dev->dev, &dev_attr_owner) ||
+                   device_create_file(&tun->dev->dev, &dev_attr_group))
+                       printk(KERN_ERR "Failed to create tun sysfs files\n");
+
                sk->sk_destruct = tun_sock_destruct;
 
                err = tun_attach(tun, file);
@@ -996,21 +1057,7 @@ static int tun_get_iff(struct net *net, struct file *file, struct ifreq *ifr)
 
        strcpy(ifr->ifr_name, tun->dev->name);
 
-       ifr->ifr_flags = 0;
-
-       if (ifr->ifr_flags & TUN_TUN_DEV)
-               ifr->ifr_flags |= IFF_TUN;
-       else
-               ifr->ifr_flags |= IFF_TAP;
-
-       if (tun->flags & TUN_NO_PI)
-               ifr->ifr_flags |= IFF_NO_PI;
-
-       if (tun->flags & TUN_ONE_QUEUE)
-               ifr->ifr_flags |= IFF_ONE_QUEUE;
-
-       if (tun->flags & TUN_VNET_HDR)
-               ifr->ifr_flags |= IFF_VNET_HDR;
+       ifr->ifr_flags = tun_flags(tun);
 
        tun_put(tun);
        return 0;
@@ -1275,21 +1322,22 @@ static int tun_chr_open(struct inode *inode, struct file * file)
 static int tun_chr_close(struct inode *inode, struct file *file)
 {
        struct tun_file *tfile = file->private_data;
-       struct tun_struct *tun = __tun_get(tfile);
+       struct tun_struct *tun;
 
 
+       rtnl_lock();
+       tun = __tun_get(tfile);
        if (tun) {
                DBG(KERN_INFO "%s: tun_chr_close\n", tun->dev->name);
 
-               rtnl_lock();
                __tun_detach(tun);
 
                /* If desireable, unregister the netdevice. */
                if (!(tun->flags & TUN_PERSIST))
                        unregister_netdevice(tun->dev);
 
-               rtnl_unlock();
        }
+       rtnl_unlock();
 
        tun = tfile->tun;
        if (tun)
index 44f8392da11729522a5e809e13f3a782ee03df71..e2f2e91cfdd2f523094e94ad79c95e96f3466f75 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006-2007 Freescale Semicondutor, Inc. All rights reserved.
+ * Copyright (C) 2006-2009 Freescale Semicondutor, Inc. All rights reserved.
  *
  * Author: Shlomi Gridish <gridish@freescale.com>
  *        Li Yang <leoli@freescale.com>
@@ -27,6 +27,7 @@
 #include <linux/mii.h>
 #include <linux/phy.h>
 #include <linux/workqueue.h>
+#include <linux/of_mdio.h>
 #include <linux/of_platform.h>
 
 #include <asm/uaccess.h>
@@ -64,6 +65,8 @@
 
 static DEFINE_SPINLOCK(ugeth_lock);
 
+static void uec_configure_serdes(struct net_device *dev);
+
 static struct {
        u32 msg_enable;
 } debug = { -1 };
@@ -270,7 +273,7 @@ static int fill_init_enet_entries(struct ucc_geth_private *ugeth,
                                  u8 num_entries,
                                  u32 thread_size,
                                  u32 thread_alignment,
-                                 enum qe_risc_allocation risc,
+                                 unsigned int risc,
                                  int skip_page_for_first_entry)
 {
        u32 init_enet_offset;
@@ -307,7 +310,7 @@ static int fill_init_enet_entries(struct ucc_geth_private *ugeth,
 static int return_init_enet_entries(struct ucc_geth_private *ugeth,
                                    u32 *p_start,
                                    u8 num_entries,
-                                   enum qe_risc_allocation risc,
+                                   unsigned int risc,
                                    int skip_page_for_first_entry)
 {
        u32 init_enet_offset;
@@ -342,7 +345,7 @@ static int dump_init_enet_entries(struct ucc_geth_private *ugeth,
                                  u32 __iomem *p_start,
                                  u8 num_entries,
                                  u32 thread_size,
-                                 enum qe_risc_allocation risc,
+                                 unsigned int risc,
                                  int skip_page_for_first_entry)
 {
        u32 init_enet_offset;
@@ -1409,6 +1412,9 @@ static int adjust_enet_interface(struct ucc_geth_private *ugeth)
            (ugeth->phy_interface == PHY_INTERFACE_MODE_RTBI)) {
                upsmr |= UCC_GETH_UPSMR_TBIM;
        }
+       if ((ugeth->phy_interface == PHY_INTERFACE_MODE_SGMII))
+               upsmr |= UCC_GETH_UPSMR_SGMM;
+
        out_be32(&uf_regs->upsmr, upsmr);
 
        /* Disable autonegotiation in tbi mode, because by default it
@@ -1543,14 +1549,19 @@ static int init_phy(struct net_device *dev)
        priv->oldspeed = 0;
        priv->oldduplex = -1;
 
-       phydev = phy_connect(dev, ug_info->phy_bus_id, &adjust_link, 0,
-                            priv->phy_interface);
+       if (!ug_info->phy_node)
+               return 0;
 
-       if (IS_ERR(phydev)) {
+       phydev = of_phy_connect(dev, ug_info->phy_node, &adjust_link, 0,
+                               priv->phy_interface);
+       if (!phydev) {
                printk("%s: Could not attach to PHY\n", dev->name);
-               return PTR_ERR(phydev);
+               return -ENODEV;
        }
 
+       if (priv->phy_interface == PHY_INTERFACE_MODE_SGMII)
+               uec_configure_serdes(dev);
+
        phydev->supported &= (ADVERTISED_10baseT_Half |
                                 ADVERTISED_10baseT_Full |
                                 ADVERTISED_100baseT_Half |
@@ -1566,7 +1577,41 @@ static int init_phy(struct net_device *dev)
        return 0;
 }
 
+/* Initialize TBI PHY interface for communicating with the
+ * SERDES lynx PHY on the chip.  We communicate with this PHY
+ * through the MDIO bus on each controller, treating it as a
+ * "normal" PHY at the address found in the UTBIPA register.  We assume
+ * that the UTBIPA register is valid.  Either the MDIO bus code will set
+ * it to a value that doesn't conflict with other PHYs on the bus, or the
+ * value doesn't matter, as there are no other PHYs on the bus.
+ */
+static void uec_configure_serdes(struct net_device *dev)
+{
+       struct ucc_geth_private *ugeth = netdev_priv(dev);
 
+       if (!ugeth->tbiphy) {
+               printk(KERN_WARNING "SGMII mode requires that the device "
+                       "tree specify a tbi-handle\n");
+       return;
+       }
+
+       /*
+        * If the link is already up, we must already be ok, and don't need to
+        * configure and reset the TBI<->SerDes link.  Maybe U-Boot configured
+        * everything for us?  Resetting it takes the link down and requires
+        * several seconds for it to come back.
+        */
+       if (phy_read(ugeth->tbiphy, ENET_TBI_MII_SR) & TBISR_LSTATUS)
+               return;
+
+       /* Single clk mode, mii mode off(for serdes communication) */
+       phy_write(ugeth->tbiphy, ENET_TBI_MII_ANA, TBIANA_SETTINGS);
+
+       phy_write(ugeth->tbiphy, ENET_TBI_MII_TBICON, TBICON_CLK_SELECT);
+
+       phy_write(ugeth->tbiphy, ENET_TBI_MII_CR, TBICR_SETTINGS);
+
+}
 
 static int ugeth_graceful_stop_tx(struct ucc_geth_private *ugeth)
 {
@@ -2135,6 +2180,14 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth)
                return -ENOMEM;
        }
 
+       /* read the number of risc engines, update the riscTx and riscRx
+        * if there are 4 riscs in QE
+        */
+       if (qe_get_num_of_risc() == 4) {
+               ug_info->riscTx = QE_RISC_ALLOCATION_FOUR_RISCS;
+               ug_info->riscRx = QE_RISC_ALLOCATION_FOUR_RISCS;
+       }
+
        ugeth->ug_regs = ioremap(uf_info->regs, sizeof(*ugeth->ug_regs));
        if (!ugeth->ug_regs) {
                if (netif_msg_probe(ugeth))
@@ -3217,7 +3270,7 @@ static int ucc_geth_tx(struct net_device *dev, u8 txQ)
                dev->stats.tx_packets++;
 
                /* Free the sk buffer associated with this TxBD */
-               dev_kfree_skb_irq(ugeth->
+               dev_kfree_skb(ugeth->
                                  tx_skbuff[txQ][ugeth->skb_dirtytx[txQ]]);
                ugeth->tx_skbuff[txQ][ugeth->skb_dirtytx[txQ]] = NULL;
                ugeth->skb_dirtytx[txQ] =
@@ -3251,9 +3304,15 @@ static int ucc_geth_poll(struct napi_struct *napi, int budget)
        for (i = 0; i < ug_info->numQueuesRx; i++)
                howmany += ucc_geth_rx(ugeth, i, budget - howmany);
 
+       /* Tx event processing */
+       spin_lock(&ugeth->lock);
+       for (i = 0; i < ug_info->numQueuesTx; i++)
+               ucc_geth_tx(ugeth->ndev, i);
+       spin_unlock(&ugeth->lock);
+
        if (howmany < budget) {
                napi_complete(napi);
-               setbits32(ugeth->uccf->p_uccm, UCCE_RX_EVENTS);
+               setbits32(ugeth->uccf->p_uccm, UCCE_RX_EVENTS | UCCE_TX_EVENTS);
        }
 
        return howmany;
@@ -3267,8 +3326,6 @@ static irqreturn_t ucc_geth_irq_handler(int irq, void *info)
        struct ucc_geth_info *ug_info;
        register u32 ucce;
        register u32 uccm;
-       register u32 tx_mask;
-       u8 i;
 
        ugeth_vdbg("%s: IN", __func__);
 
@@ -3282,27 +3339,14 @@ static irqreturn_t ucc_geth_irq_handler(int irq, void *info)
        out_be32(uccf->p_ucce, ucce);
 
        /* check for receive events that require processing */
-       if (ucce & UCCE_RX_EVENTS) {
+       if (ucce & (UCCE_RX_EVENTS | UCCE_TX_EVENTS)) {
                if (napi_schedule_prep(&ugeth->napi)) {
-                       uccm &= ~UCCE_RX_EVENTS;
+                       uccm &= ~(UCCE_RX_EVENTS | UCCE_TX_EVENTS);
                        out_be32(uccf->p_uccm, uccm);
                        __napi_schedule(&ugeth->napi);
                }
        }
 
-       /* Tx event processing */
-       if (ucce & UCCE_TX_EVENTS) {
-               spin_lock(&ugeth->lock);
-               tx_mask = UCC_GETH_UCCE_TXB0;
-               for (i = 0; i < ug_info->numQueuesTx; i++) {
-                       if (ucce & tx_mask)
-                               ucc_geth_tx(dev, i);
-                       ucce &= ~tx_mask;
-                       tx_mask <<= 1;
-               }
-               spin_unlock(&ugeth->lock);
-       }
-
        /* Errors and other events */
        if (ucce & UCCE_OTHER) {
                if (ucce & UCC_GETH_UCCE_BSY)
@@ -3331,6 +3375,37 @@ static void ucc_netpoll(struct net_device *dev)
 }
 #endif /* CONFIG_NET_POLL_CONTROLLER */
 
+static int ucc_geth_set_mac_addr(struct net_device *dev, void *p)
+{
+       struct ucc_geth_private *ugeth = netdev_priv(dev);
+       struct sockaddr *addr = p;
+
+       if (!is_valid_ether_addr(addr->sa_data))
+               return -EADDRNOTAVAIL;
+
+       memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
+
+       /*
+        * If device is not running, we will set mac addr register
+        * when opening the device.
+        */
+       if (!netif_running(dev))
+               return 0;
+
+       spin_lock_irq(&ugeth->lock);
+       init_mac_station_addr_regs(dev->dev_addr[0],
+                                  dev->dev_addr[1],
+                                  dev->dev_addr[2],
+                                  dev->dev_addr[3],
+                                  dev->dev_addr[4],
+                                  dev->dev_addr[5],
+                                  &ugeth->ug_regs->macstnaddr1,
+                                  &ugeth->ug_regs->macstnaddr2);
+       spin_unlock_irq(&ugeth->lock);
+
+       return 0;
+}
+
 /* Called when something needs to use the ethernet device */
 /* Returns 0 for success. */
 static int ucc_geth_open(struct net_device *dev)
@@ -3498,6 +3573,8 @@ static phy_interface_t to_phy_interface(const char *phy_connection_type)
                return PHY_INTERFACE_MODE_RGMII_RXID;
        if (strcasecmp(phy_connection_type, "rtbi") == 0)
                return PHY_INTERFACE_MODE_RTBI;
+       if (strcasecmp(phy_connection_type, "sgmii") == 0)
+               return PHY_INTERFACE_MODE_SGMII;
 
        return PHY_INTERFACE_MODE_MII;
 }
@@ -3507,7 +3584,7 @@ static const struct net_device_ops ucc_geth_netdev_ops = {
        .ndo_stop               = ucc_geth_close,
        .ndo_start_xmit         = ucc_geth_start_xmit,
        .ndo_validate_addr      = eth_validate_addr,
-       .ndo_set_mac_address    = eth_mac_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_tx_timeout         = ucc_geth_timeout,
@@ -3520,14 +3597,12 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
 {
        struct device *device = &ofdev->dev;
        struct device_node *np = ofdev->node;
-       struct device_node *mdio;
        struct net_device *dev = NULL;
        struct ucc_geth_private *ugeth = NULL;
        struct ucc_geth_info *ug_info;
        struct resource res;
        struct device_node *phy;
        int err, ucc_num, max_speed = 0;
-       const phandle *ph;
        const u32 *fixed_link;
        const unsigned int *prop;
        const char *sprop;
@@ -3544,6 +3619,7 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
                PHY_INTERFACE_MODE_RMII, PHY_INTERFACE_MODE_RGMII,
                PHY_INTERFACE_MODE_GMII, PHY_INTERFACE_MODE_RGMII,
                PHY_INTERFACE_MODE_TBI, PHY_INTERFACE_MODE_RTBI,
+               PHY_INTERFACE_MODE_SGMII,
        };
 
        ugeth_vdbg("%s: IN", __func__);
@@ -3627,40 +3703,13 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
        ug_info->uf_info.irq = irq_of_parse_and_map(np, 0);
        fixed_link = of_get_property(np, "fixed-link", NULL);
        if (fixed_link) {
-               snprintf(ug_info->phy_bus_id, sizeof(ug_info->phy_bus_id),
-                        PHY_ID_FMT, "0", fixed_link[0]);
                phy = NULL;
        } else {
-               char bus_name[MII_BUS_ID_SIZE];
-
-               ph = of_get_property(np, "phy-handle", NULL);
-               phy = of_find_node_by_phandle(*ph);
-
+               phy = of_parse_phandle(np, "phy-handle", 0);
                if (phy == NULL)
                        return -ENODEV;
-
-               /* set the PHY address */
-               prop = of_get_property(phy, "reg", NULL);
-               if (prop == NULL)
-                       return -1;
-
-               /* Set the bus id */
-               mdio = of_get_parent(phy);
-
-               if (mdio == NULL)
-                       return -ENODEV;
-
-               err = of_address_to_resource(mdio, 0, &res);
-
-               if (err) {
-                       of_node_put(mdio);
-                       return err;
-               }
-               fsl_pq_mdio_bus_name(bus_name, mdio);
-               of_node_put(mdio);
-               snprintf(ug_info->phy_bus_id, sizeof(ug_info->phy_bus_id),
-                       "%s:%02x", bus_name, *prop);
        }
+       ug_info->phy_node = phy;
 
        /* get the phy interface type, or default to MII */
        prop = of_get_property(np, "phy-connection-type", NULL);
@@ -3686,6 +3735,7 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
                case PHY_INTERFACE_MODE_RGMII_TXID:
                case PHY_INTERFACE_MODE_TBI:
                case PHY_INTERFACE_MODE_RTBI:
+               case PHY_INTERFACE_MODE_SGMII:
                        max_speed = SPEED_1000;
                        break;
                default:
@@ -3702,7 +3752,15 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
                ug_info->uf_info.utfet = UCC_GETH_UTFET_GIGA_INIT;
                ug_info->uf_info.utftt = UCC_GETH_UTFTT_GIGA_INIT;
                ug_info->numThreadsTx = UCC_GETH_NUM_OF_THREADS_4;
-               ug_info->numThreadsRx = UCC_GETH_NUM_OF_THREADS_4;
+
+               /* If QE's snum number is 46 which means we need to support
+                * 4 UECs at 1000Base-T simultaneously, we need to allocate
+                * more Threads to Rx.
+                */
+               if (qe_get_num_of_snums() == 46)
+                       ug_info->numThreadsRx = UCC_GETH_NUM_OF_THREADS_6;
+               else
+                       ug_info->numThreadsRx = UCC_GETH_NUM_OF_THREADS_4;
        }
 
        if (netif_msg_probe(&debug))
@@ -3735,7 +3793,7 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
        dev->netdev_ops = &ucc_geth_netdev_ops;
        dev->watchdog_timeo = TX_TIMEOUT;
        INIT_WORK(&ugeth->timeout_work, ucc_geth_timeout_work);
-       netif_napi_add(dev, &ugeth->napi, ucc_geth_poll, UCC_GETH_DEV_WEIGHT);
+       netif_napi_add(dev, &ugeth->napi, ucc_geth_poll, 64);
        dev->mtu = 1500;
 
        ugeth->msg_enable = netif_msg_init(debug.msg_enable, UGETH_MSG_DEFAULT);
@@ -3760,6 +3818,37 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
        ugeth->ndev = dev;
        ugeth->node = np;
 
+       /* Find the TBI PHY.  If it's not there, we don't support SGMII */
+       ph = of_get_property(np, "tbi-handle", NULL);
+       if (ph) {
+               struct device_node *tbi = of_find_node_by_phandle(*ph);
+               struct of_device *ofdev;
+               struct mii_bus *bus;
+               const unsigned int *id;
+
+               if (!tbi)
+                       return 0;
+
+               mdio = of_get_parent(tbi);
+               if (!mdio)
+                       return 0;
+
+               ofdev = of_find_device_by_node(mdio);
+
+               of_node_put(mdio);
+
+               id = of_get_property(tbi, "reg", NULL);
+               if (!id)
+                       return 0;
+               of_node_put(tbi);
+
+               bus = dev_get_drvdata(&ofdev->dev);
+               if (!bus)
+                       return 0;
+
+               ugeth->tbiphy = bus->phy_map[*id];
+       }
+
        return 0;
 }
 
index 2f8ee7c87efe944e6e788e861ee407ce97018a59..5beba4c145325bde47b553dfad20f59f6d256069 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) Freescale Semicondutor, Inc. 2006. All rights reserved.
+ * Copyright (C) Freescale Semicondutor, Inc. 2006-2009. All rights reserved.
  *
  * Author: Shlomi Gridish <gridish@freescale.com>
  *
@@ -193,6 +193,31 @@ struct ucc_geth {
 #define        ENET_TBI_MII_JD         0x10    /* Jitter diagnostics */
 #define        ENET_TBI_MII_TBICON     0x11    /* TBI control */
 
+/* TBI MDIO register bit fields*/
+#define TBISR_LSTATUS          0x0004
+#define TBICON_CLK_SELECT       0x0020
+#define TBIANA_ASYMMETRIC_PAUSE 0x0100
+#define TBIANA_SYMMETRIC_PAUSE  0x0080
+#define TBIANA_HALF_DUPLEX      0x0040
+#define TBIANA_FULL_DUPLEX      0x0020
+#define TBICR_PHY_RESET         0x8000
+#define TBICR_ANEG_ENABLE       0x1000
+#define TBICR_RESTART_ANEG      0x0200
+#define TBICR_FULL_DUPLEX       0x0100
+#define TBICR_SPEED1_SET        0x0040
+
+#define TBIANA_SETTINGS ( \
+               TBIANA_ASYMMETRIC_PAUSE \
+               | TBIANA_SYMMETRIC_PAUSE \
+               | TBIANA_FULL_DUPLEX \
+               )
+#define TBICR_SETTINGS ( \
+               TBICR_PHY_RESET \
+               | TBICR_ANEG_ENABLE \
+               | TBICR_FULL_DUPLEX \
+               | TBICR_SPEED1_SET \
+               )
+
 /* UCC GETH MACCFG1 (MAC Configuration 1 Register) */
 #define MACCFG1_FLOW_RX                         0x00000020     /* Flow Control
                                                                   Rx */
@@ -852,7 +877,6 @@ struct ucc_geth_hardware_statistics {
 /* Driver definitions */
 #define TX_BD_RING_LEN                          0x10
 #define RX_BD_RING_LEN                          0x10
-#define UCC_GETH_DEV_WEIGHT                     TX_BD_RING_LEN
 
 #define TX_RING_MOD_MASK(size)                  (size-1)
 #define RX_RING_MOD_MASK(size)                  (size-1)
@@ -1100,7 +1124,7 @@ struct ucc_geth_info {
        u32 eventRegMask;
        u16 pausePeriod;
        u16 extensionField;
-       char phy_bus_id[BUS_ID_SIZE];
+       struct device_node *phy_node;
        u8 weightfactor[NUM_TX_QUEUES];
        u8 interruptcoalescingmaxvalue[NUM_RX_QUEUES];
        u8 l2qt[UCC_GETH_VLAN_PRIORITY_MAX];
@@ -1120,8 +1144,8 @@ struct ucc_geth_info {
        enum ucc_geth_maccfg2_pad_and_crc_mode padAndCrc;
        enum ucc_geth_num_of_threads numThreadsTx;
        enum ucc_geth_num_of_threads numThreadsRx;
-       enum qe_risc_allocation riscTx;
-       enum qe_risc_allocation riscRx;
+       unsigned int riscTx;
+       unsigned int riscRx;
 };
 
 /* structure representing UCC GETH */
@@ -1189,6 +1213,7 @@ struct ucc_geth_private {
 
        struct ugeth_mii_info *mii_info;
        struct phy_device *phydev;
+       struct phy_device *tbiphy;
        phy_interface_t phy_interface;
        int max_speed;
        uint32_t msg_enable;
index dfc6cf765fbdf77e5081679c9a2ac2d14e8d99a0..3717569828bf360f16a8bc6b8138c6965269bddd 100644 (file)
@@ -359,4 +359,12 @@ config USB_HSO
          To compile this driver as a module, choose M here: the
          module will be called hso.
 
+config USB_NET_INT51X1
+       tristate "Intellon PLC based usb adapter"
+       depends on USB_USBNET
+       help
+         Choose this option if you're using a 14Mb USB-based PLC
+         (Powerline Communications) solution with an Intellon
+         INT51x1/INT5200 chip, like the "devolo dLan duo".
+
 endmenu
index c8aef62cf2b74a90f332068be027bbe5a7eaf92d..b870b0b1cbe0a1280ad7900a05c148417ff7729f 100644 (file)
@@ -20,4 +20,5 @@ obj-$(CONFIG_USB_NET_CDC_SUBSET)      += cdc_subset.o
 obj-$(CONFIG_USB_NET_ZAURUS)   += zaurus.o
 obj-$(CONFIG_USB_NET_MCS7830)  += mcs7830.o
 obj-$(CONFIG_USB_USBNET)       += usbnet.o
+obj-$(CONFIG_USB_NET_INT51X1)  += int51x1.o
 
index 55e8ecc3a9e5d5bd6eb88038530ccada469bb2c6..01fd528306ec1c87c74e930f6effe6201b519171 100644 (file)
@@ -25,7 +25,6 @@
 #include <linux/init.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
-#include <linux/ctype.h>
 #include <linux/ethtool.h>
 #include <linux/workqueue.h>
 #include <linux/mii.h>
@@ -389,36 +388,6 @@ static void cdc_status(struct usbnet *dev, struct urb *urb)
        }
 }
 
-static u8 nibble(unsigned char c)
-{
-       if (likely(isdigit(c)))
-               return c - '0';
-       c = toupper(c);
-       if (likely(isxdigit(c)))
-               return 10 + c - 'A';
-       return 0;
-}
-
-static inline int
-get_ethernet_addr(struct usbnet *dev, struct usb_cdc_ether_desc *e)
-{
-       int             tmp, i;
-       unsigned char   buf [13];
-
-       tmp = usb_string(dev->udev, e->iMACAddress, buf, sizeof buf);
-       if (tmp != 12) {
-               dev_dbg(&dev->udev->dev,
-                       "bad MAC string %d fetch, %d\n", e->iMACAddress, tmp);
-               if (tmp >= 0)
-                       tmp = -EINVAL;
-               return tmp;
-       }
-       for (i = tmp = 0; i < 6; i++, tmp += 2)
-               dev->net->dev_addr [i] =
-                       (nibble(buf [tmp]) << 4) + nibble(buf [tmp + 1]);
-       return 0;
-}
-
 static int cdc_bind(struct usbnet *dev, struct usb_interface *intf)
 {
        int                             status;
@@ -428,7 +397,7 @@ static int cdc_bind(struct usbnet *dev, struct usb_interface *intf)
        if (status < 0)
                return status;
 
-       status = get_ethernet_addr(dev, info->ether);
+       status = usbnet_get_ethernet_addr(dev, info->ether->iMACAddress);
        if (status < 0) {
                usb_set_intfdata(info->data, NULL);
                usb_driver_release_interface(driver_of(intf), info->data);
index 6fc4f82b0bebdd4d1fb7688675a680511d2a7f99..7ae82446b93aed59f3dd646f5df5767ab3feb74f 100644 (file)
@@ -497,10 +497,10 @@ static int dm9601_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
        int len;
 
        /* format:
-          b0: rx status
-          b1: packet length (incl crc) low
-          b2: packet length (incl crc) high
-          b3..n-4: packet data
+          b1: rx status
+          b2: packet length (incl crc) low
+          b3: packet length (incl crc) high
+          b4..n-4: packet data
           bn-3..bn: ethernet crc
         */
 
@@ -533,8 +533,8 @@ static struct sk_buff *dm9601_tx_fixup(struct usbnet *dev, struct sk_buff *skb,
        int len;
 
        /* format:
-          b0: packet length low
-          b1: packet length high
+          b1: packet length low
+          b2: packet length high
           b3..n: packet data
        */
 
index f84b78d94c400f0533a34a1a568b9e6507f0a1f0..f8c6d7ea72646ceb24fe1ccf480f80fffb5c7767 100644 (file)
@@ -482,7 +482,7 @@ static ssize_t hso_sysfs_show_porttype(struct device *dev,
                                       struct device_attribute *attr,
                                       char *buf)
 {
-       struct hso_device *hso_dev = dev->driver_data;
+       struct hso_device *hso_dev = dev_get_drvdata(dev);
        char *port_name;
 
        if (!hso_dev)
@@ -816,7 +816,7 @@ static int hso_net_start_xmit(struct sk_buff *skb, struct net_device *net)
        }
        dev_kfree_skb(skb);
        /* we're done */
-       return result;
+       return NETDEV_TX_OK;
 }
 
 static void hso_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *info)
@@ -899,15 +899,14 @@ static void packetizeRx(struct hso_net *odev, unsigned char *ip_pkt,
                                        continue;
                                }
                                /* Allocate an sk_buff */
-                               odev->skb_rx_buf = dev_alloc_skb(frame_len);
+                               odev->skb_rx_buf = netdev_alloc_skb(odev->net,
+                                                                   frame_len);
                                if (!odev->skb_rx_buf) {
                                        /* We got no receive buffer. */
                                        D1("could not allocate memory");
                                        odev->rx_parse_state = WAIT_SYNC;
                                        return;
                                }
-                               /* Here's where it came from */
-                               odev->skb_rx_buf->dev = odev->net;
 
                                /* Copy what we got so far. make room for iphdr
                                 * after tail. */
@@ -2313,7 +2312,7 @@ static int hso_serial_common_create(struct hso_serial *serial, int num_urbs,
        serial->parent->dev = tty_register_device(tty_drv, minor,
                                        &serial->parent->interface->dev);
        dev = serial->parent->dev;
-       dev->driver_data = serial->parent;
+       dev_set_drvdata(dev, serial->parent);
        i = device_create_file(dev, &dev_attr_hsotype);
 
        /* fill in specific data for later use */
@@ -2481,10 +2480,10 @@ static int add_net_device(struct hso_device *hso_dev)
        return 0;
 }
 
-static int hso_radio_toggle(void *data, enum rfkill_state state)
+static int hso_rfkill_set_block(void *data, bool blocked)
 {
        struct hso_device *hso_dev = data;
-       int enabled = (state == RFKILL_STATE_ON);
+       int enabled = !blocked;
        int rv;
 
        mutex_lock(&hso_dev->mutex);
@@ -2498,6 +2497,10 @@ static int hso_radio_toggle(void *data, enum rfkill_state state)
        return rv;
 }
 
+static const struct rfkill_ops hso_rfkill_ops = {
+       .set_block = hso_rfkill_set_block,
+};
+
 /* Creates and sets up everything for rfkill */
 static void hso_create_rfkill(struct hso_device *hso_dev,
                             struct usb_interface *interface)
@@ -2506,29 +2509,25 @@ static void hso_create_rfkill(struct hso_device *hso_dev,
        struct device *dev = &hso_net->net->dev;
        char *rfkn;
 
-       hso_net->rfkill = rfkill_allocate(&interface_to_usbdev(interface)->dev,
-                                RFKILL_TYPE_WWAN);
-       if (!hso_net->rfkill) {
-               dev_err(dev, "%s - Out of memory\n", __func__);
-               return;
-       }
        rfkn = kzalloc(20, GFP_KERNEL);
-       if (!rfkn) {
-               rfkill_free(hso_net->rfkill);
-               hso_net->rfkill = NULL;
+       if (!rfkn)
                dev_err(dev, "%s - Out of memory\n", __func__);
-               return;
-       }
+
        snprintf(rfkn, 20, "hso-%d",
                 interface->altsetting->desc.bInterfaceNumber);
-       hso_net->rfkill->name = rfkn;
-       hso_net->rfkill->state = RFKILL_STATE_ON;
-       hso_net->rfkill->data = hso_dev;
-       hso_net->rfkill->toggle_radio = hso_radio_toggle;
+
+       hso_net->rfkill = rfkill_alloc(rfkn,
+                                      &interface_to_usbdev(interface)->dev,
+                                      RFKILL_TYPE_WWAN,
+                                      &hso_rfkill_ops, hso_dev);
+       if (!hso_net->rfkill) {
+               dev_err(dev, "%s - Out of memory\n", __func__);
+               kfree(rfkn);
+               return;
+       }
        if (rfkill_register(hso_net->rfkill) < 0) {
+               rfkill_destroy(hso_net->rfkill);
                kfree(rfkn);
-               hso_net->rfkill->name = NULL;
-               rfkill_free(hso_net->rfkill);
                hso_net->rfkill = NULL;
                dev_err(dev, "%s - Failed to register rfkill\n", __func__);
                return;
@@ -3165,8 +3164,10 @@ static void hso_free_interface(struct usb_interface *interface)
                        hso_stop_net_device(network_table[i]);
                        cancel_work_sync(&network_table[i]->async_put_intf);
                        cancel_work_sync(&network_table[i]->async_get_intf);
-                       if (rfk)
+                       if (rfk) {
                                rfkill_unregister(rfk);
+                               rfkill_destroy(rfk);
+                       }
                        hso_free_net_device(network_table[i]);
                }
        }
diff --git a/drivers/net/usb/int51x1.c b/drivers/net/usb/int51x1.c
new file mode 100644 (file)
index 0000000..55cf708
--- /dev/null
@@ -0,0 +1,253 @@
+/*
+ * Copyright (c) 2009 Peter Holik
+ *
+ * Intellon usb PLC (Powerline Communications) usb net driver
+ *
+ * http://www.tandel.be/downloads/INT51X1_Datasheet.pdf
+ *
+ * Based on the work of Jan 'RedBully' Seiffert
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or.
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/module.h>
+#include <linux/ctype.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/mii.h>
+#include <linux/usb.h>
+#include <linux/usb/usbnet.h>
+
+#define INT51X1_VENDOR_ID      0x09e1
+#define INT51X1_PRODUCT_ID     0x5121
+
+#define INT51X1_HEADER_SIZE    2       /* 2 byte header */
+
+#define PACKET_TYPE_PROMISCUOUS                (1 << 0)
+#define PACKET_TYPE_ALL_MULTICAST      (1 << 1) /* no filter */
+#define PACKET_TYPE_DIRECTED           (1 << 2)
+#define PACKET_TYPE_BROADCAST          (1 << 3)
+#define PACKET_TYPE_MULTICAST          (1 << 4) /* filtered */
+
+#define SET_ETHERNET_PACKET_FILTER     0x43
+
+static int int51x1_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
+{
+       int len;
+
+       if (!(pskb_may_pull(skb, INT51X1_HEADER_SIZE))) {
+               deverr(dev, "unexpected tiny rx frame");
+               return 0;
+       }
+
+       len = le16_to_cpu(*(__le16 *)&skb->data[skb->len - 2]);
+
+       skb_trim(skb, len);
+
+       return 1;
+}
+
+static struct sk_buff *int51x1_tx_fixup(struct usbnet *dev,
+               struct sk_buff *skb, gfp_t flags)
+{
+       int pack_len = skb->len;
+       int pack_with_header_len = pack_len + INT51X1_HEADER_SIZE;
+       int headroom = skb_headroom(skb);
+       int tailroom = skb_tailroom(skb);
+       int need_tail = 0;
+       __le16 *len;
+
+       /* if packet and our header is smaler than 64 pad to 64 (+ ZLP) */
+       if ((pack_with_header_len) < dev->maxpacket)
+               need_tail = dev->maxpacket - pack_with_header_len + 1;
+       /*
+        * usbnet would send a ZLP if packetlength mod urbsize == 0 for us,
+        * but we need to know ourself, because this would add to the length
+        * we send down to the device...
+        */
+       else if (!(pack_with_header_len % dev->maxpacket))
+               need_tail = 1;
+
+       if (!skb_cloned(skb) &&
+                       (headroom + tailroom >= need_tail + INT51X1_HEADER_SIZE)) {
+               if (headroom < INT51X1_HEADER_SIZE || tailroom < need_tail) {
+                       skb->data = memmove(skb->head + INT51X1_HEADER_SIZE,
+                                       skb->data, skb->len);
+                       skb_set_tail_pointer(skb, skb->len);
+               }
+       } else {
+               struct sk_buff *skb2;
+
+               skb2 = skb_copy_expand(skb,
+                               INT51X1_HEADER_SIZE,
+                               need_tail,
+                               flags);
+               dev_kfree_skb_any(skb);
+               if (!skb2)
+                       return NULL;
+               skb = skb2;
+       }
+
+       pack_len += need_tail;
+       pack_len &= 0x07ff;
+
+       len = (__le16 *) __skb_push(skb, INT51X1_HEADER_SIZE);
+       *len = cpu_to_le16(pack_len);
+
+       if(need_tail)
+               memset(__skb_put(skb, need_tail), 0, need_tail);
+
+       return skb;
+}
+
+static void int51x1_async_cmd_callback(struct urb *urb)
+{
+       struct usb_ctrlrequest *req = (struct usb_ctrlrequest *)urb->context;
+       int status = urb->status;
+
+       if (status < 0)
+               dev_warn(&urb->dev->dev, "async callback failed with %d\n", status);
+
+       kfree(req);
+       usb_free_urb(urb);
+}
+
+static void int51x1_set_multicast(struct net_device *netdev)
+{
+       struct usb_ctrlrequest *req;
+       int status;
+       struct urb *urb;
+       struct usbnet *dev = netdev_priv(netdev);
+       u16 filter = PACKET_TYPE_DIRECTED | PACKET_TYPE_BROADCAST;
+
+       if (netdev->flags & IFF_PROMISC) {
+               /* do not expect to see traffic of other PLCs */
+               filter |= PACKET_TYPE_PROMISCUOUS;
+               devinfo(dev, "promiscuous mode enabled");
+       } else if (netdev->mc_count ||
+                 (netdev->flags & IFF_ALLMULTI)) {
+               filter |= PACKET_TYPE_ALL_MULTICAST;
+               devdbg(dev, "receive all multicast enabled");
+       } else {
+               /* ~PROMISCUOUS, ~MULTICAST */
+               devdbg(dev, "receive own packets only");
+       }
+
+       urb = usb_alloc_urb(0, GFP_ATOMIC);
+       if (!urb) {
+               devwarn(dev, "Error allocating URB");
+               return;
+       }
+
+       req = kmalloc(sizeof(*req), GFP_ATOMIC);
+       if (!req) {
+               devwarn(dev, "Error allocating control msg");
+               goto out;
+       }
+
+       req->bRequestType = USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
+       req->bRequest = SET_ETHERNET_PACKET_FILTER;
+       req->wValue = cpu_to_le16(filter);
+       req->wIndex = 0;
+       req->wLength = 0;
+
+       usb_fill_control_urb(urb, dev->udev, usb_sndctrlpipe(dev->udev, 0),
+               (void *)req, NULL, 0,
+               int51x1_async_cmd_callback,
+               (void *)req);
+
+       status = usb_submit_urb(urb, GFP_ATOMIC);
+       if (status < 0) {
+               devwarn(dev, "Error submitting control msg, sts=%d", status);
+               goto out1;
+       }
+       return;
+out1:
+       kfree(req);
+out:
+       usb_free_urb(urb);
+}
+
+static const struct net_device_ops int51x1_netdev_ops = {
+       .ndo_open               = usbnet_open,
+       .ndo_stop               = usbnet_stop,
+       .ndo_start_xmit         = usbnet_start_xmit,
+       .ndo_tx_timeout         = usbnet_tx_timeout,
+       .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,
+};
+
+static int int51x1_bind(struct usbnet *dev, struct usb_interface *intf)
+{
+       int status = usbnet_get_ethernet_addr(dev, 3);
+
+       if (status)
+               return status;
+
+       dev->net->hard_header_len += INT51X1_HEADER_SIZE;
+       dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len;
+       dev->net->netdev_ops = &int51x1_netdev_ops;
+
+       return usbnet_get_endpoints(dev, intf);
+}
+
+static const struct driver_info int51x1_info = {
+       .description = "Intellon usb powerline adapter",
+       .bind        = int51x1_bind,
+       .rx_fixup    = int51x1_rx_fixup,
+       .tx_fixup    = int51x1_tx_fixup,
+       .in          = 1,
+       .out         = 2,
+       .flags       = FLAG_ETHER,
+};
+
+static const struct usb_device_id products[] = {
+       {
+       USB_DEVICE(INT51X1_VENDOR_ID, INT51X1_PRODUCT_ID),
+               .driver_info = (unsigned long) &int51x1_info,
+       },
+       {},
+};
+MODULE_DEVICE_TABLE(usb, products);
+
+static struct usb_driver int51x1_driver = {
+       .name       = "int51x1",
+       .id_table   = products,
+       .probe      = usbnet_probe,
+       .disconnect = usbnet_disconnect,
+       .suspend    = usbnet_suspend,
+       .resume     = usbnet_resume,
+};
+
+static int __init int51x1_init(void)
+{
+       return usb_register(&int51x1_driver);
+}
+module_init(int51x1_init);
+
+static void __exit int51x1_exit(void)
+{
+       usb_deregister(&int51x1_driver);
+}
+module_exit(int51x1_exit);
+
+MODULE_AUTHOR("Peter Holik");
+MODULE_DESCRIPTION("Intellon usb powerline adapter");
+MODULE_LICENSE("GPL");
index 3d0d0b0b37c53d71be8396e3a2a2965bcaf01edd..e0131478971829902dd2f8e836f7b17d0d74aeda 100644 (file)
@@ -31,7 +31,6 @@
  ****************************************************************/
 
 /* TODO:
- * Fix in_interrupt() problem
  * Develop test procedures for USB net interfaces
  * Run test procedures
  * Fix bugs from previous two steps
@@ -606,14 +605,30 @@ static void kaweth_usb_receive(struct urb *urb)
 
        struct sk_buff *skb;
 
-       if(unlikely(status == -ECONNRESET || status == -ESHUTDOWN))
-       /* we are killed - set a flag and wake the disconnect handler */
-       {
+       if (unlikely(status == -EPIPE)) {
+               kaweth->stats.rx_errors++;
                kaweth->end = 1;
                wake_up(&kaweth->term_wait);
+               dbg("Status was -EPIPE.");
                return;
        }
-
+       if (unlikely(status == -ECONNRESET || status == -ESHUTDOWN)) {
+               /* we are killed - set a flag and wake the disconnect handler */
+               kaweth->end = 1;
+               wake_up(&kaweth->term_wait);
+               dbg("Status was -ECONNRESET or -ESHUTDOWN.");
+               return;
+       }
+       if (unlikely(status == -EPROTO || status == -ETIME ||
+                    status == -EILSEQ)) {
+               kaweth->stats.rx_errors++;
+               dbg("Status was -EPROTO, -ETIME, or -EILSEQ.");
+               return;
+       }
+       if (unlikely(status == -EOVERFLOW)) {
+               kaweth->stats.rx_errors++;
+               dbg("Status was -EOVERFLOW.");
+       }
        spin_lock(&kaweth->device_lock);
        if (IS_BLOCKED(kaweth->status)) {
                spin_unlock(&kaweth->device_lock);
@@ -883,13 +898,16 @@ static void kaweth_set_rx_mode(struct net_device *net)
  ****************************************************************/
 static void kaweth_async_set_rx_mode(struct kaweth_device *kaweth)
 {
+       int result;
        __u16 packet_filter_bitmap = kaweth->packet_filter_bitmap;
+
        kaweth->packet_filter_bitmap = 0;
        if (packet_filter_bitmap == 0)
                return;
 
-       {
-       int result;
+       if (in_interrupt())
+               return;
+
        result = kaweth_control(kaweth,
                                usb_sndctrlpipe(kaweth->dev, 0),
                                KAWETH_COMMAND_SET_PACKET_FILTER,
@@ -906,7 +924,6 @@ static void kaweth_async_set_rx_mode(struct kaweth_device *kaweth)
        else {
                dbg("Set Rx mode to %d", packet_filter_bitmap);
        }
-       }
 }
 
 /****************************************************************
index f9fb454ffa8bab25db07ce78f50e30c4fbbc3e80..fcc6fa0905d1cbbf1416e9736ec62ddd86f9450d 100644 (file)
@@ -221,7 +221,8 @@ static void ctrl_callback(struct urb *urb)
        case -ENOENT:
                break;
        default:
-               dev_warn(&urb->dev->dev, "ctrl urb status %d\n", status);
+               if (printk_ratelimit())
+                       dev_warn(&urb->dev->dev, "ctrl urb status %d\n", status);
        }
        dev = urb->context;
        clear_bit(RX_REG_SET, &dev->flags);
@@ -442,10 +443,12 @@ static void read_bulk_callback(struct urb *urb)
        case -ENOENT:
                return; /* the urb is in unlink state */
        case -ETIME:
-               dev_warn(&urb->dev->dev, "may be reset is needed?..\n");
+               if (printk_ratelimit())
+                       dev_warn(&urb->dev->dev, "may be reset is needed?..\n");
                goto goon;
        default:
-               dev_warn(&urb->dev->dev, "Rx status %d\n", status);
+               if (printk_ratelimit())
+                       dev_warn(&urb->dev->dev, "Rx status %d\n", status);
                goto goon;
        }
 
index 5a7283372b53d09c9c4d39d6332fef471fde1875..89a91f8c22dea051009a1a2c513f28fa9a9b600f 100644 (file)
@@ -1134,7 +1134,7 @@ static int smsc95xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
                        if (skb->len == size) {
                                if (pdata->use_rx_csum)
                                        smsc95xx_rx_csum_offload(skb);
-
+                               skb_trim(skb, skb->len - 4); /* remove fcs */
                                skb->truesize = size + sizeof(struct sk_buff);
 
                                return 1;
@@ -1152,7 +1152,7 @@ static int smsc95xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
 
                        if (pdata->use_rx_csum)
                                smsc95xx_rx_csum_offload(ax_skb);
-
+                       skb_trim(ax_skb, ax_skb->len - 4); /* remove fcs */
                        ax_skb->truesize = size + sizeof(struct sk_buff);
 
                        usbnet_skb_return(dev, ax_skb);
index 47f68cfa7e21344b6ebcb426023f032af43a9f28..22c0585a03198f75ea73b3974d394fc984a4ecc1 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/init.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
+#include <linux/ctype.h>
 #include <linux/ethtool.h>
 #include <linux/workqueue.h>
 #include <linux/mii.h>
@@ -156,6 +157,36 @@ int usbnet_get_endpoints(struct usbnet *dev, struct usb_interface *intf)
 }
 EXPORT_SYMBOL_GPL(usbnet_get_endpoints);
 
+static u8 nibble(unsigned char c)
+{
+       if (likely(isdigit(c)))
+               return c - '0';
+       c = toupper(c);
+       if (likely(isxdigit(c)))
+               return 10 + c - 'A';
+       return 0;
+}
+
+int usbnet_get_ethernet_addr(struct usbnet *dev, int iMACAddress)
+{
+       int             tmp, i;
+       unsigned char   buf [13];
+
+       tmp = usb_string(dev->udev, iMACAddress, buf, sizeof buf);
+       if (tmp != 12) {
+               dev_dbg(&dev->udev->dev,
+                       "bad MAC string %d fetch, %d\n", iMACAddress, tmp);
+               if (tmp >= 0)
+                       tmp = -EINVAL;
+               return tmp;
+       }
+       for (i = tmp = 0; i < 6; i++, tmp += 2)
+               dev->net->dev_addr [i] =
+                       (nibble(buf [tmp]) << 4) + nibble(buf [tmp + 1]);
+       return 0;
+}
+EXPORT_SYMBOL_GPL(usbnet_get_ethernet_addr);
+
 static void intr_complete (struct urb *urb);
 
 static int init_status (struct usbnet *dev, struct usb_interface *intf)
@@ -1185,12 +1216,6 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
 #endif
 
        net->netdev_ops = &usbnet_netdev_ops;
-#ifdef CONFIG_COMPAT_NET_DEV_OPS
-       net->hard_start_xmit = usbnet_start_xmit;
-       net->open = usbnet_open;
-       net->stop = usbnet_stop;
-       net->tx_timeout = usbnet_tx_timeout;
-#endif
        net->watchdog_timeo = TX_TIMEOUT_JIFFIES;
        net->ethtool_ops = &usbnet_ethtool_ops;
 
index 8e56fcf0a0e34eada5e2be3d9339e6a2c30364b8..87197dd9c78847b1eec6497ea331df660841bf83 100644 (file)
@@ -176,8 +176,6 @@ static int veth_xmit(struct sk_buff *skb, struct net_device *dev)
        if (dev->features & NETIF_F_NO_CSUM)
                skb->ip_summed = rcv_priv->ip_summed;
 
-       dst_release(skb->dst);
-       skb->dst = NULL;
        skb->mark = 0;
        secpath_reset(skb);
        nf_reset(skb);
index 45daba726b665fd753a1338244536595a00099f6..d3489a3c4c03b28907035181134c20ccb44b9233 100644 (file)
@@ -388,7 +388,6 @@ struct rhine_private {
        long pioaddr;
        struct net_device *dev;
        struct napi_struct napi;
-       struct net_device_stats stats;
        spinlock_t lock;
 
        /* Frequently used values: keep some adjacent for cache effect. */
@@ -1209,7 +1208,7 @@ static void rhine_tx_timeout(struct net_device *dev)
        enable_irq(rp->pdev->irq);
 
        dev->trans_start = jiffies;
-       rp->stats.tx_errors++;
+       dev->stats.tx_errors++;
        netif_wake_queue(dev);
 }
 
@@ -1237,7 +1236,7 @@ static int rhine_start_tx(struct sk_buff *skb, struct net_device *dev)
                        /* packet too long, drop it */
                        dev_kfree_skb(skb);
                        rp->tx_skbuff[entry] = NULL;
-                       rp->stats.tx_dropped++;
+                       dev->stats.tx_dropped++;
                        return 0;
                }
 
@@ -1378,29 +1377,33 @@ static void rhine_tx(struct net_device *dev)
                                printk(KERN_DEBUG "%s: Transmit error, "
                                       "Tx status %8.8x.\n",
                                       dev->name, txstatus);
-                       rp->stats.tx_errors++;
-                       if (txstatus & 0x0400) rp->stats.tx_carrier_errors++;
-                       if (txstatus & 0x0200) rp->stats.tx_window_errors++;
-                       if (txstatus & 0x0100) rp->stats.tx_aborted_errors++;
-                       if (txstatus & 0x0080) rp->stats.tx_heartbeat_errors++;
+                       dev->stats.tx_errors++;
+                       if (txstatus & 0x0400)
+                               dev->stats.tx_carrier_errors++;
+                       if (txstatus & 0x0200)
+                               dev->stats.tx_window_errors++;
+                       if (txstatus & 0x0100)
+                               dev->stats.tx_aborted_errors++;
+                       if (txstatus & 0x0080)
+                               dev->stats.tx_heartbeat_errors++;
                        if (((rp->quirks & rqRhineI) && txstatus & 0x0002) ||
                            (txstatus & 0x0800) || (txstatus & 0x1000)) {
-                               rp->stats.tx_fifo_errors++;
+                               dev->stats.tx_fifo_errors++;
                                rp->tx_ring[entry].tx_status = cpu_to_le32(DescOwn);
                                break; /* Keep the skb - we try again */
                        }
                        /* Transmitter restarted in 'abnormal' handler. */
                } else {
                        if (rp->quirks & rqRhineI)
-                               rp->stats.collisions += (txstatus >> 3) & 0x0F;
+                               dev->stats.collisions += (txstatus >> 3) & 0x0F;
                        else
-                               rp->stats.collisions += txstatus & 0x0F;
+                               dev->stats.collisions += txstatus & 0x0F;
                        if (debug > 6)
                                printk(KERN_DEBUG "collisions: %1.1x:%1.1x\n",
                                       (txstatus >> 3) & 0xF,
                                       txstatus & 0xF);
-                       rp->stats.tx_bytes += rp->tx_skbuff[entry]->len;
-                       rp->stats.tx_packets++;
+                       dev->stats.tx_bytes += rp->tx_skbuff[entry]->len;
+                       dev->stats.tx_packets++;
                }
                /* Free the original skb. */
                if (rp->tx_skbuff_dma[entry]) {
@@ -1455,21 +1458,24 @@ static int rhine_rx(struct net_device *dev, int limit)
                                printk(KERN_WARNING "%s: Oversized Ethernet "
                                       "frame %p vs %p.\n", dev->name,
                                       rp->rx_head_desc, &rp->rx_ring[entry]);
-                               rp->stats.rx_length_errors++;
+                               dev->stats.rx_length_errors++;
                        } else if (desc_status & RxErr) {
                                /* There was a error. */
                                if (debug > 2)
                                        printk(KERN_DEBUG "rhine_rx() Rx "
                                               "error was %8.8x.\n",
                                               desc_status);
-                               rp->stats.rx_errors++;
-                               if (desc_status & 0x0030) rp->stats.rx_length_errors++;
-                               if (desc_status & 0x0048) rp->stats.rx_fifo_errors++;
-                               if (desc_status & 0x0004) rp->stats.rx_frame_errors++;
+                               dev->stats.rx_errors++;
+                               if (desc_status & 0x0030)
+                                       dev->stats.rx_length_errors++;
+                               if (desc_status & 0x0048)
+                                       dev->stats.rx_fifo_errors++;
+                               if (desc_status & 0x0004)
+                                       dev->stats.rx_frame_errors++;
                                if (desc_status & 0x0002) {
                                        /* this can also be updated outside the interrupt handler */
                                        spin_lock(&rp->lock);
-                                       rp->stats.rx_crc_errors++;
+                                       dev->stats.rx_crc_errors++;
                                        spin_unlock(&rp->lock);
                                }
                        }
@@ -1513,8 +1519,8 @@ static int rhine_rx(struct net_device *dev, int limit)
                        }
                        skb->protocol = eth_type_trans(skb, dev);
                        netif_receive_skb(skb);
-                       rp->stats.rx_bytes += pkt_len;
-                       rp->stats.rx_packets++;
+                       dev->stats.rx_bytes += pkt_len;
+                       dev->stats.rx_packets++;
                }
                entry = (++rp->cur_rx) % RX_RING_SIZE;
                rp->rx_head_desc = &rp->rx_ring[entry];
@@ -1599,8 +1605,8 @@ static void rhine_error(struct net_device *dev, int intr_status)
        if (intr_status & IntrLinkChange)
                rhine_check_media(dev, 0);
        if (intr_status & IntrStatsMax) {
-               rp->stats.rx_crc_errors += ioread16(ioaddr + RxCRCErrs);
-               rp->stats.rx_missed_errors += ioread16(ioaddr + RxMissed);
+               dev->stats.rx_crc_errors += ioread16(ioaddr + RxCRCErrs);
+               dev->stats.rx_missed_errors += ioread16(ioaddr + RxMissed);
                clear_tally_counters(ioaddr);
        }
        if (intr_status & IntrTxAborted) {
@@ -1654,12 +1660,12 @@ static struct net_device_stats *rhine_get_stats(struct net_device *dev)
        unsigned long flags;
 
        spin_lock_irqsave(&rp->lock, flags);
-       rp->stats.rx_crc_errors += ioread16(ioaddr + RxCRCErrs);
-       rp->stats.rx_missed_errors += ioread16(ioaddr + RxMissed);
+       dev->stats.rx_crc_errors += ioread16(ioaddr + RxCRCErrs);
+       dev->stats.rx_missed_errors += ioread16(ioaddr + RxMissed);
        clear_tally_counters(ioaddr);
        spin_unlock_irqrestore(&rp->lock, flags);
 
-       return &rp->stats;
+       return &dev->stats;
 }
 
 static void rhine_set_rx_mode(struct net_device *dev)
index 754a4b182c1d86b3cf36512d9d795419cbc3c2d0..e2a7725e567eb0c64b68f6c25d3de6de1e5139be 100644 (file)
@@ -1385,7 +1385,7 @@ static void velocity_free_td_ring(struct velocity_info *vptr)
 
 static int velocity_rx_srv(struct velocity_info *vptr, int status)
 {
-       struct net_device_stats *stats = &vptr->stats;
+       struct net_device_stats *stats = &vptr->dev->stats;
        int rd_curr = vptr->rx.curr;
        int works = 0;
 
@@ -1519,7 +1519,7 @@ static inline void velocity_iph_realign(struct velocity_info *vptr,
 static int velocity_receive_frame(struct velocity_info *vptr, int idx)
 {
        void (*pci_action)(struct pci_dev *, dma_addr_t, size_t, int);
-       struct net_device_stats *stats = &vptr->stats;
+       struct net_device_stats *stats = &vptr->dev->stats;
        struct velocity_rd_info *rd_info = &(vptr->rx.info[idx]);
        struct rx_desc *rd = &(vptr->rx.ring[idx]);
        int pkt_len = le16_to_cpu(rd->rdesc0.len) & 0x3fff;
@@ -1532,7 +1532,7 @@ static int velocity_receive_frame(struct velocity_info *vptr, int idx)
        }
 
        if (rd->rdesc0.RSR & RSR_MAR)
-               vptr->stats.multicast++;
+               stats->multicast++;
 
        skb = rd_info->skb;
 
@@ -1634,7 +1634,7 @@ static int velocity_tx_srv(struct velocity_info *vptr, u32 status)
        int idx;
        int works = 0;
        struct velocity_td_info *tdinfo;
-       struct net_device_stats *stats = &vptr->stats;
+       struct net_device_stats *stats = &vptr->dev->stats;
 
        for (qnum = 0; qnum < vptr->tx.numq; qnum++) {
                for (idx = vptr->tx.tail[qnum]; vptr->tx.used[qnum] > 0;
@@ -2324,22 +2324,22 @@ static struct net_device_stats *velocity_get_stats(struct net_device *dev)
 
        /* If the hardware is down, don't touch MII */
        if(!netif_running(dev))
-               return &vptr->stats;
+               return &dev->stats;
 
        spin_lock_irq(&vptr->lock);
        velocity_update_hw_mibs(vptr);
        spin_unlock_irq(&vptr->lock);
 
-       vptr->stats.rx_packets = vptr->mib_counter[HW_MIB_ifRxAllPkts];
-       vptr->stats.rx_errors = vptr->mib_counter[HW_MIB_ifRxErrorPkts];
-       vptr->stats.rx_length_errors = vptr->mib_counter[HW_MIB_ifInRangeLengthErrors];
+       dev->stats.rx_packets = vptr->mib_counter[HW_MIB_ifRxAllPkts];
+       dev->stats.rx_errors = vptr->mib_counter[HW_MIB_ifRxErrorPkts];
+       dev->stats.rx_length_errors = vptr->mib_counter[HW_MIB_ifInRangeLengthErrors];
 
 //  unsigned long   rx_dropped;     /* no space in linux buffers    */
-       vptr->stats.collisions = vptr->mib_counter[HW_MIB_ifTxEtherCollisions];
+       dev->stats.collisions = vptr->mib_counter[HW_MIB_ifTxEtherCollisions];
        /* detailed rx_errors: */
 //  unsigned long   rx_length_errors;
 //  unsigned long   rx_over_errors;     /* receiver ring buff overflow  */
-       vptr->stats.rx_crc_errors = vptr->mib_counter[HW_MIB_ifRxPktCRCE];
+       dev->stats.rx_crc_errors = vptr->mib_counter[HW_MIB_ifRxPktCRCE];
 //  unsigned long   rx_frame_errors;    /* recv'd frame alignment error */
 //  unsigned long   rx_fifo_errors;     /* recv'r fifo overrun      */
 //  unsigned long   rx_missed_errors;   /* receiver missed packet   */
@@ -2347,7 +2347,7 @@ static struct net_device_stats *velocity_get_stats(struct net_device *dev)
        /* detailed tx_errors */
 //  unsigned long   tx_fifo_errors;
 
-       return &vptr->stats;
+       return &dev->stats;
 }
 
 
index ea43e1832afba07d389861b05ef3b2f6102f4595..4cd3f6c9737974889c516db4fb42cdc507a34b99 100644 (file)
@@ -1503,7 +1503,6 @@ struct velocity_info {
 
        struct pci_dev *pdev;
        struct net_device *dev;
-       struct net_device_stats stats;
 
        struct vlan_group    *vlgrp;
        u8 ip_addr[4];
index 7fa620ddeb2170ea7b3393ea6b5cfdbf9adfb2e8..52198f6797a48a88a76bfee8cc4f6cfe64925ea8 100644 (file)
@@ -283,10 +283,11 @@ static void try_fill_recv_maxbufs(struct virtnet_info *vi)
        for (;;) {
                struct virtio_net_hdr *hdr;
 
-               skb = netdev_alloc_skb(vi->dev, MAX_PACKET_LEN);
+               skb = netdev_alloc_skb(vi->dev, MAX_PACKET_LEN + NET_IP_ALIGN);
                if (unlikely(!skb))
                        break;
 
+               skb_reserve(skb, NET_IP_ALIGN);
                skb_put(skb, MAX_PACKET_LEN);
 
                hdr = skb_vnet_hdr(skb);
@@ -470,7 +471,7 @@ static int xmit_skb(struct virtnet_info *vi, struct sk_buff *skb)
        }
 
        if (skb_is_gso(skb)) {
-               hdr->hdr_len = skb_transport_header(skb) - skb->data;
+               hdr->hdr_len = skb_headlen(skb);
                hdr->gso_size = skb_shinfo(skb)->gso_size;
                if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4)
                        hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV4;
@@ -622,12 +623,9 @@ static bool virtnet_send_command(struct virtnet_info *vi, u8 class, u8 cmd,
        unsigned int tmp;
        int i;
 
-       if (!virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ)) {
-               BUG();  /* Caller should know better */
-               return false;
-       }
-
-       BUG_ON(out + in > VIRTNET_SEND_COMMAND_SG_MAX);
+       /* Caller should know better */
+       BUG_ON(!virtio_has_feature(vi->vdev, VIRTIO_NET_F_CTRL_VQ) ||
+               (out + in > VIRTNET_SEND_COMMAND_SG_MAX));
 
        out++; /* Add header */
        in++; /* Add return status */
@@ -642,8 +640,7 @@ static bool virtnet_send_command(struct virtnet_info *vi, u8 class, u8 cmd,
                sg_set_buf(&sg[i + 1], sg_virt(s), s->length);
        sg_set_buf(&sg[out + in - 1], &status, sizeof(status));
 
-       if (vi->cvq->vq_ops->add_buf(vi->cvq, sg, out, in, vi) != 0)
-               BUG();
+       BUG_ON(vi->cvq->vq_ops->add_buf(vi->cvq, sg, out, in, vi));
 
        vi->cvq->vq_ops->kick(vi->cvq);
 
@@ -684,6 +681,7 @@ static void virtnet_set_rx_mode(struct net_device *dev)
        u8 promisc, allmulti;
        struct virtio_net_ctrl_mac *mac_data;
        struct dev_addr_list *addr;
+       struct netdev_hw_addr *ha;
        void *buf;
        int i;
 
@@ -722,9 +720,9 @@ static void virtnet_set_rx_mode(struct net_device *dev)
 
        /* Store the unicast list and count in the front of the buffer */
        mac_data->entries = dev->uc_count;
-       addr = dev->uc_list;
-       for (i = 0; i < dev->uc_count; i++, addr = addr->next)
-               memcpy(&mac_data->macs[i][0], addr->da_addr, ETH_ALEN);
+       i = 0;
+       list_for_each_entry(ha, &dev->uc_list, list)
+               memcpy(&mac_data->macs[i++][0], ha->addr, ETH_ALEN);
 
        sg_set_buf(&sg[0], mac_data,
                   sizeof(mac_data->entries) + (dev->uc_count * ETH_ALEN));
index 6b41c884a3372ce6a30b3c1203c816633f02df95..26cde573af430cfa3e66de4fccf5a324f73e333a 100644 (file)
@@ -1884,17 +1884,13 @@ void __vxge_hw_mempool_destroy(struct vxge_hw_mempool *mempool)
                                mempool->memblock_size, dma_object);
        }
 
-       if (mempool->items_arr)
-               vfree(mempool->items_arr);
+       vfree(mempool->items_arr);
 
-       if (mempool->memblocks_dma_arr)
-               vfree(mempool->memblocks_dma_arr);
+       vfree(mempool->memblocks_dma_arr);
 
-       if (mempool->memblocks_priv_arr)
-               vfree(mempool->memblocks_priv_arr);
+       vfree(mempool->memblocks_priv_arr);
 
-       if (mempool->memblocks_arr)
-               vfree(mempool->memblocks_arr);
+       vfree(mempool->memblocks_arr);
 
        vfree(mempool);
 }
index b7f08f3e524b512331a570de319a1578ea97a88a..6c838b3e063a6fc6905e1eb6b429d0472b12a2e9 100644 (file)
@@ -677,7 +677,7 @@ vxge_xmit_compl(struct __vxge_hw_fifo *fifo_hw, void *dtr,
        return VXGE_HW_OK;
 }
 
-/* select a vpath to trasmit the packet */
+/* select a vpath to transmit the packet */
 static u32 vxge_get_vpath_no(struct vxgedev *vdev, struct sk_buff *skb,
        int *do_lock)
 {
@@ -992,7 +992,9 @@ vxge_xmit(struct sk_buff *skb, struct net_device *dev)
                                        VXGE_HW_FIFO_TXD_TX_CKO_UDP_EN);
 
        vxge_hw_fifo_txdl_post(fifo_hw, dtr);
-       dev->trans_start = jiffies;
+#ifdef NETIF_F_LLTX
+       dev->trans_start = jiffies; /* NETIF_F_LLTX driver :( */
+#endif
        spin_unlock_irqrestore(&fifo->tx_lock, flags);
 
        VXGE_COMPLETE_VPATH_TX(fifo);
index c2eeac4125f328d07cc993ed5125541b77d891d4..370f55cbbad71947eb7cac983ec9b0985331f953 100644 (file)
@@ -1923,7 +1923,7 @@ enum vxge_hw_status __vxge_hw_vpath_alarm_process(
        if (vpath == NULL) {
                alarm_event = VXGE_HW_SET_LEVEL(VXGE_HW_EVENT_UNKNOWN,
                        alarm_event);
-               goto out;
+               goto out2;
        }
 
        hldev = vpath->hldev;
@@ -2161,7 +2161,7 @@ enum vxge_hw_status __vxge_hw_vpath_alarm_process(
        }
 out:
        hldev->stats.sw_dev_err_stats.vpath_alarms++;
-
+out2:
        if ((alarm_event == VXGE_HW_EVENT_ALARM_CLEARED) ||
                (alarm_event == VXGE_HW_EVENT_UNKNOWN))
                return VXGE_HW_OK;
index 35dea3bea95dfe91490a39274e938753ae729147..f525f9fe74db8cb6cf44d2f64945972be258bf9b 100644 (file)
@@ -615,7 +615,7 @@ static int cycx_netdevice_hard_start_xmit(struct sk_buff *skb,
                case WAN_DISCONNECTED:
                        if (cycx_x25_chan_connect(dev)) {
                                netif_stop_queue(dev);
-                               return -EBUSY;
+                               return NETDEV_TX_BUSY;
                        }
                        /* fall thru */
                case WAN_CONNECTED:
@@ -624,7 +624,7 @@ static int cycx_netdevice_hard_start_xmit(struct sk_buff *skb,
                        netif_stop_queue(dev);
 
                        if (cycx_x25_chan_send(dev, skb))
-                               return -EBUSY;
+                               return NETDEV_TX_BUSY;
 
                        break;
                default:
@@ -656,7 +656,7 @@ static int cycx_netdevice_hard_start_xmit(struct sk_buff *skb,
                if (cycx_x25_chan_send(dev, skb)) {
                        /* prepare for future retransmissions */
                        skb_push(skb, 1);
-                       return -EBUSY;
+                       return NETDEV_TX_BUSY;
                }
        }
 
index e8d155c3e59f5bdf53bc6a2f3e426d99bac6c407..2fa275a58f9d7f618b8a7d0e5398cda3c38c51c6 100644 (file)
@@ -205,15 +205,15 @@ static int dlci_transmit(struct sk_buff *skb, struct net_device *dev)
        {
                case DLCI_RET_OK:
                        dev->stats.tx_packets++;
-                       ret = 0;
+                       ret = NETDEV_TX_OK;
                        break;
                        case DLCI_RET_ERR:
                        dev->stats.tx_errors++;
-                       ret = 0;
+                       ret = NETDEV_TX_OK;
                        break;
                        case DLCI_RET_DROP:
                        dev->stats.tx_dropped++;
-                       ret = 1;
+                       ret = NETDEV_TX_BUSY;
                        break;
        }
        /* Alan Cox recommends always returning 0, and always freeing the packet */
index 800530101093a10901ee16956bf75040a6ec971a..bfa0161a02d32001f8f22d5f6beb2b9c5d2a2c93 100644 (file)
@@ -1054,6 +1054,7 @@ static void pvc_setup(struct net_device *dev)
        dev->flags = IFF_POINTOPOINT;
        dev->hard_header_len = 10;
        dev->addr_len = 2;
+       dev->priv_flags &= ~IFF_XMIT_DST_RELEASE;
 }
 
 static const struct net_device_ops pvc_ops = {
index a6dc317083d32c66ed027d440a295931125be25a..bb719b6114cb264fea47523f5e8ccab070101351 100644 (file)
@@ -732,8 +732,8 @@ static int hss_hdlc_poll(struct napi_struct *napi, int budget)
                dma_unmap_single(&dev->dev, desc->data,
                                 RX_SIZE, DMA_FROM_DEVICE);
 #else
-               dma_sync_single(&dev->dev, desc->data,
-                               RX_SIZE, DMA_FROM_DEVICE);
+               dma_sync_single_for_cpu(&dev->dev, desc->data,
+                                       RX_SIZE, DMA_FROM_DEVICE);
                memcpy_swab32((u32 *)skb->data, (u32 *)port->rx_buff_tab[n],
                              ALIGN(desc->pkt_len, 4) / 4);
 #endif
index c23fde0c0344cc6893c2d912d9cebfa10ba7e9f6..79dabc557bd395b58fdf137efe7a79d65b2df956 100644 (file)
@@ -225,6 +225,7 @@ static char rcsid[] =
 #include <linux/skbuff.h>
 #include <linux/if_arp.h>
 #include <linux/netdevice.h>
+#include <linux/etherdevice.h>
 #include <linux/spinlock.h>
 #include <linux/if.h>
 #include <net/arp.h>
@@ -3246,6 +3247,16 @@ static inline void show_version(void)
                rcsvers, rcsdate, __DATE__, __TIME__);
 }                              /* show_version */
 
+static const struct net_device_ops cpc_netdev_ops = {
+       .ndo_open               = cpc_open,
+       .ndo_stop               = cpc_close,
+       .ndo_tx_timeout         = cpc_tx_timeout,
+       .ndo_set_mac_address    = NULL,
+       .ndo_change_mtu         = cpc_change_mtu,
+       .ndo_do_ioctl           = cpc_ioctl,
+       .ndo_validate_addr      = eth_validate_addr,
+};
+
 static void cpc_init_card(pc300_t * card)
 {
        int i, devcount = 0;
@@ -3357,18 +3368,11 @@ static void cpc_init_card(pc300_t * card)
                dev->mem_start = card->hw.ramphys;
                dev->mem_end = card->hw.ramphys + card->hw.ramsize - 1;
                dev->irq = card->hw.irq;
-               dev->init = NULL;
                dev->tx_queue_len = PC300_TX_QUEUE_LEN;
                dev->mtu = PC300_DEF_MTU;
 
-               dev->open = cpc_open;
-               dev->stop = cpc_close;
-               dev->tx_timeout = cpc_tx_timeout;
+               dev->netdev_ops = &cpc_netdev_ops;
                dev->watchdog_timeo = PC300_TX_TIMEOUT;
-               dev->set_multicast_list = NULL;
-               dev->set_mac_address = NULL;
-               dev->change_mtu = cpc_change_mtu;
-               dev->do_ioctl = cpc_ioctl;
 
                if (register_hdlc_device(dev) == 0) {
                        printk("%s: Cyclades-PC300/", dev->name);
index f4211fe0f445138af27ebe3fbf8f2dc7ef6c2371..3fb9dbc88a1aaa277ba631f4c09a19026cdce11d 100644 (file)
@@ -469,7 +469,7 @@ sbni_start_xmit( struct sk_buff  *skb,  struct net_device  *dev )
                }
        }
 
-       return  1;
+       return NETDEV_TX_BUSY;
 }
 
 #else  /* CONFIG_SBNI_MULTILINE */
index 8130b79a8a996594209188f79c19512011fa0d08..e4ad7b6b52eb2077d5f8e3c30b6c4d98ee253407 100644 (file)
@@ -283,7 +283,7 @@ static int wanxl_xmit(struct sk_buff *skb, struct net_device *dev)
 #endif
                netif_stop_queue(dev);
                spin_unlock_irq(&port->lock);
-               return 1;       /* request packet to be queued */
+               return NETDEV_TX_BUSY;       /* request packet to be queued */
        }
 
 #ifdef DEBUG_PKT
index b3cadb626fe0af97b2861ad195d6be1a183c7164..07308686dbcf69f8fd9a90a2c05cef8641d5d9cf 100644 (file)
@@ -292,8 +292,6 @@ void i2400m_report_tlv_system_state(struct i2400m *i2400m,
 
        d_fnstart(3, dev, "(i2400m %p ss %p [%u])\n", i2400m, ss, i2400m_state);
 
-       if (unlikely(i2400m->ready == 0))       /* act if up */
-               goto out;
        if (i2400m->state != i2400m_state) {
                i2400m->state = i2400m_state;
                wake_up_all(&i2400m->state_wq);
@@ -341,7 +339,6 @@ void i2400m_report_tlv_system_state(struct i2400m *i2400m,
                i2400m->bus_reset(i2400m, I2400M_RT_WARM);
                break;
        };
-out:
        d_fnend(3, dev, "(i2400m %p ss %p [%u]) = void\n",
                i2400m, ss, i2400m_state);
 }
@@ -372,8 +369,6 @@ void i2400m_report_tlv_media_status(struct i2400m *i2400m,
 
        d_fnstart(3, dev, "(i2400m %p ms %p [%u])\n", i2400m, ms, status);
 
-       if (unlikely(i2400m->ready == 0))       /* act if up */
-               goto out;
        switch (status) {
        case I2400M_MEDIA_STATUS_LINK_UP:
                netif_carrier_on(net_dev);
@@ -393,14 +388,59 @@ void i2400m_report_tlv_media_status(struct i2400m *i2400m,
                dev_err(dev, "HW BUG? unknown media status %u\n",
                        status);
        };
-out:
        d_fnend(3, dev, "(i2400m %p ms %p [%u]) = void\n",
                i2400m, ms, status);
 }
 
 
 /*
- * Parse a 'state report' and extract carrier on/off information
+ * Process a TLV from a 'state report'
+ *
+ * @i2400m: device descriptor
+ * @tlv: pointer to the TLV header; it has been already validated for
+ *     consistent size.
+ * @tag: for error messages
+ *
+ * Act on the TLVs from a 'state report'.
+ */
+static
+void i2400m_report_state_parse_tlv(struct i2400m *i2400m,
+                                  const struct i2400m_tlv_hdr *tlv,
+                                  const char *tag)
+{
+       struct device *dev = i2400m_dev(i2400m);
+       const struct i2400m_tlv_media_status *ms;
+       const struct i2400m_tlv_system_state *ss;
+       const struct i2400m_tlv_rf_switches_status *rfss;
+
+       if (0 == i2400m_tlv_match(tlv, I2400M_TLV_SYSTEM_STATE, sizeof(*ss))) {
+               ss = container_of(tlv, typeof(*ss), hdr);
+               d_printf(2, dev, "%s: system state TLV "
+                        "found (0x%04x), state 0x%08x\n",
+                        tag, I2400M_TLV_SYSTEM_STATE,
+                        le32_to_cpu(ss->state));
+               i2400m_report_tlv_system_state(i2400m, ss);
+       }
+       if (0 == i2400m_tlv_match(tlv, I2400M_TLV_RF_STATUS, sizeof(*rfss))) {
+               rfss = container_of(tlv, typeof(*rfss), hdr);
+               d_printf(2, dev, "%s: RF status TLV "
+                        "found (0x%04x), sw 0x%02x hw 0x%02x\n",
+                        tag, I2400M_TLV_RF_STATUS,
+                        le32_to_cpu(rfss->sw_rf_switch),
+                        le32_to_cpu(rfss->hw_rf_switch));
+               i2400m_report_tlv_rf_switches_status(i2400m, rfss);
+       }
+       if (0 == i2400m_tlv_match(tlv, I2400M_TLV_MEDIA_STATUS, sizeof(*ms))) {
+               ms = container_of(tlv, typeof(*ms), hdr);
+               d_printf(2, dev, "%s: Media Status TLV: %u\n",
+                        tag, le32_to_cpu(ms->media_status));
+               i2400m_report_tlv_media_status(i2400m, ms);
+       }
+}
+
+
+/*
+ * Parse a 'state report' and extract information
  *
  * @i2400m: device descriptor
  * @l3l4_hdr: pointer to message; it has been already validated for
@@ -409,13 +449,7 @@ out:
  *        declaration is assumed to be congruent with @size (as in
  *        sizeof(*l3l4_hdr) + l3l4_hdr->length == size)
  *
- * Extract from the report state the system state TLV and infer from
- * there if we have a carrier or not. Update our local state and tell
- * netdev.
- *
- * When setting the carrier, it's fine to set OFF twice (for example),
- * as netif_carrier_off() will not generate two OFF events (just on
- * the transitions).
+ * Walk over the TLVs in a report state and act on them.
  */
 static
 void i2400m_report_state_hook(struct i2400m *i2400m,
@@ -424,9 +458,6 @@ void i2400m_report_state_hook(struct i2400m *i2400m,
 {
        struct device *dev = i2400m_dev(i2400m);
        const struct i2400m_tlv_hdr *tlv;
-       const struct i2400m_tlv_system_state *ss;
-       const struct i2400m_tlv_rf_switches_status *rfss;
-       const struct i2400m_tlv_media_status *ms;
        size_t tlv_size = le16_to_cpu(l3l4_hdr->length);
 
        d_fnstart(4, dev, "(i2400m %p, l3l4_hdr %p, size %zu, %s)\n",
@@ -434,34 +465,8 @@ void i2400m_report_state_hook(struct i2400m *i2400m,
        tlv = NULL;
 
        while ((tlv = i2400m_tlv_buffer_walk(i2400m, &l3l4_hdr->pl,
-                                            tlv_size, tlv))) {
-               if (0 == i2400m_tlv_match(tlv, I2400M_TLV_SYSTEM_STATE,
-                                         sizeof(*ss))) {
-                       ss = container_of(tlv, typeof(*ss), hdr);
-                       d_printf(2, dev, "%s: system state TLV "
-                                "found (0x%04x), state 0x%08x\n",
-                                tag, I2400M_TLV_SYSTEM_STATE,
-                                le32_to_cpu(ss->state));
-                       i2400m_report_tlv_system_state(i2400m, ss);
-               }
-               if (0 == i2400m_tlv_match(tlv, I2400M_TLV_RF_STATUS,
-                                         sizeof(*rfss))) {
-                       rfss = container_of(tlv, typeof(*rfss), hdr);
-                       d_printf(2, dev, "%s: RF status TLV "
-                                "found (0x%04x), sw 0x%02x hw 0x%02x\n",
-                                tag, I2400M_TLV_RF_STATUS,
-                                le32_to_cpu(rfss->sw_rf_switch),
-                                le32_to_cpu(rfss->hw_rf_switch));
-                       i2400m_report_tlv_rf_switches_status(i2400m, rfss);
-               }
-               if (0 == i2400m_tlv_match(tlv, I2400M_TLV_MEDIA_STATUS,
-                                         sizeof(*ms))) {
-                       ms = container_of(tlv, typeof(*ms), hdr);
-                       d_printf(2, dev, "%s: Media Status TLV: %u\n",
-                                tag, le32_to_cpu(ms->media_status));
-                       i2400m_report_tlv_media_status(i2400m, ms);
-               }
-       }
+                                            tlv_size, tlv)))
+               i2400m_report_state_parse_tlv(i2400m, tlv, tag);
        d_fnend(4, dev, "(i2400m %p, l3l4_hdr %p, size %zu, %s) = void\n",
                i2400m, l3l4_hdr, size, tag);
 }
@@ -500,8 +505,15 @@ void i2400m_report_hook(struct i2400m *i2400m,
         * it. */
        case I2400M_MT_REPORT_POWERSAVE_READY:  /* zzzzz */
                if (l3l4_hdr->status == cpu_to_le16(I2400M_MS_DONE_OK)) {
-                       d_printf(1, dev, "ready for powersave, requesting\n");
-                       i2400m_cmd_enter_powersave(i2400m);
+                       if (i2400m_power_save_disabled)
+                               d_printf(1, dev, "ready for powersave, "
+                                        "not requesting (disabled by module "
+                                        "parameter)\n");
+                       else {
+                               d_printf(1, dev, "ready for powersave, "
+                                        "requesting\n");
+                               i2400m_cmd_enter_powersave(i2400m);
+                       }
                }
                break;
        };
@@ -683,8 +695,9 @@ struct sk_buff *i2400m_msg_to_dev(struct i2400m *i2400m,
        d_fnstart(3, dev, "(i2400m %p buf %p len %zu)\n",
                  i2400m, buf, buf_len);
 
+       rmb();          /* Make sure we see what i2400m_dev_reset_handle() */
        if (i2400m->boot_mode)
-               return ERR_PTR(-ENODEV);
+               return ERR_PTR(-EL3RST);
 
        msg_l3l4_hdr = buf;
        /* Check msg & payload consistency */
@@ -721,6 +734,8 @@ struct sk_buff *i2400m_msg_to_dev(struct i2400m *i2400m,
                ack_timeout = HZ;
        };
 
+       if (unlikely(i2400m->trace_msg_from_user))
+               wimax_msg(&i2400m->wimax_dev, "echo", buf, buf_len, GFP_KERNEL);
        /* The RX path in rx.c will put any response for this message
         * in i2400m->ack_skb and wake us up. If we cancel the wait,
         * we need to change the value of i2400m->ack_skb to something
@@ -755,6 +770,9 @@ struct sk_buff *i2400m_msg_to_dev(struct i2400m *i2400m,
        ack_l3l4_hdr = wimax_msg_data_len(ack_skb, &ack_len);
 
        /* Check the ack and deliver it if it is ok */
+       if (unlikely(i2400m->trace_msg_from_user))
+               wimax_msg(&i2400m->wimax_dev, "echo",
+                         ack_l3l4_hdr, ack_len, GFP_KERNEL);
        result = i2400m_msg_size_check(i2400m, ack_l3l4_hdr, ack_len);
        if (result < 0) {
                dev_err(dev, "HW BUG? reply to message 0x%04x: %d\n",
@@ -1379,16 +1397,16 @@ error:
  *
  * @i2400m: device descriptor
  *
- * Gracefully stops the device, moving it to the lowest power
- * consumption state possible.
+ * Release resources acquired during the running of the device; in
+ * theory, should also tell the device to go to sleep, switch off the
+ * radio, all that, but at this point, in most cases (driver
+ * disconnection, reset handling) we can't even talk to the device.
  */
 void i2400m_dev_shutdown(struct i2400m *i2400m)
 {
-       int result = -ENODEV;
        struct device *dev = i2400m_dev(i2400m);
 
        d_fnstart(3, dev, "(i2400m %p)\n", i2400m);
-       result = i2400m->bus_reset(i2400m, I2400M_RT_WARM);
-       d_fnend(3, dev, "(i2400m %p) = void [%d]\n", i2400m, result);
+       d_fnend(3, dev, "(i2400m %p) = void\n", i2400m);
        return;
 }
index 07a54bad237b3aefc999208425a515b634a7d337..304f0443ca4bc7e739b7ad567557686c77987d8d 100644 (file)
@@ -62,6 +62,7 @@
  *   unregister_netdev()
  */
 #include "i2400m.h"
+#include <linux/etherdevice.h>
 #include <linux/wimax/i2400m.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
@@ -81,6 +82,14 @@ module_param_named(rx_reorder_disabled, i2400m_rx_reorder_disabled, int, 0644);
 MODULE_PARM_DESC(rx_reorder_disabled,
                 "If true, RX reordering will be disabled.");
 
+int i2400m_power_save_disabled;        /* 0 (power saving enabled) by default */
+module_param_named(power_save_disabled, i2400m_power_save_disabled, int, 0644);
+MODULE_PARM_DESC(power_save_disabled,
+                "If true, the driver will not tell the device to enter "
+                "power saving mode when it reports it is ready for it. "
+                "False by default (so the device is told to do power "
+                "saving).");
+
 /**
  * i2400m_queue_work - schedule work on a i2400m's queue
  *
@@ -171,7 +180,6 @@ int i2400m_schedule_work(struct i2400m *i2400m,
        int result;
        struct i2400m_work *iw;
 
-       BUG_ON(i2400m->work_queue == NULL);
        result = -ENOMEM;
        iw = kzalloc(sizeof(*iw), gfp_flags);
        if (iw == NULL)
@@ -234,9 +242,6 @@ int i2400m_op_msg_from_user(struct wimax_dev *wimax_dev,
        result = PTR_ERR(ack_skb);
        if (IS_ERR(ack_skb))
                goto error_msg_to_dev;
-       if (unlikely(i2400m->trace_msg_from_user))
-               wimax_msg(&i2400m->wimax_dev, "trace",
-                         msg_buf, msg_len, GFP_KERNEL);
        result = wimax_msg_send(&i2400m->wimax_dev, ack_skb);
 error_msg_to_dev:
        d_fnend(4, dev, "(wimax_dev %p [i2400m %p] msg_buf %p msg_len %zu "
@@ -379,6 +384,11 @@ error:
  * Uploads firmware and brings up all the resources needed to be able
  * to communicate with the device.
  *
+ * The workqueue has to be setup early, at least before RX handling
+ * (it's only real user for now) so it can process reports as they
+ * arrive. We also want to destroy it if we retry, to make sure it is
+ * flushed...easier like this.
+ *
  * TX needs to be setup before the bus-specific code (otherwise on
  * shutdown, the bus-tx code could try to access it).
  */
@@ -389,7 +399,7 @@ int __i2400m_dev_start(struct i2400m *i2400m, enum i2400m_bri flags)
        struct wimax_dev *wimax_dev = &i2400m->wimax_dev;
        struct net_device *net_dev = wimax_dev->net_dev;
        struct device *dev = i2400m_dev(i2400m);
-       int times = 3;
+       int times = i2400m->bus_bm_retries;
 
        d_fnstart(3, dev, "(i2400m %p)\n", i2400m);
 retry:
@@ -404,15 +414,15 @@ retry:
        result = i2400m_rx_setup(i2400m);
        if (result < 0)
                goto error_rx_setup;
-       result = i2400m->bus_dev_start(i2400m);
-       if (result < 0)
-               goto error_bus_dev_start;
        i2400m->work_queue = create_singlethread_workqueue(wimax_dev->name);
        if (i2400m->work_queue == NULL) {
                result = -ENOMEM;
                dev_err(dev, "cannot create workqueue\n");
                goto error_create_workqueue;
        }
+       result = i2400m->bus_dev_start(i2400m);
+       if (result < 0)
+               goto error_bus_dev_start;
        result = i2400m_firmware_check(i2400m); /* fw versions ok? */
        if (result < 0)
                goto error_fw_check;
@@ -434,17 +444,17 @@ retry:
 error_dev_initialize:
 error_check_mac_addr:
 error_fw_check:
-       destroy_workqueue(i2400m->work_queue);
-error_create_workqueue:
        i2400m->bus_dev_stop(i2400m);
 error_bus_dev_start:
+       destroy_workqueue(i2400m->work_queue);
+error_create_workqueue:
        i2400m_rx_release(i2400m);
 error_rx_setup:
        i2400m_tx_release(i2400m);
 error_tx_setup:
 error_bootstrap:
-       if (result == -ERESTARTSYS && times-- > 0) {
-               flags = I2400M_BRI_SOFT;
+       if (result == -EL3RST && times-- > 0) {
+               flags = I2400M_BRI_SOFT|I2400M_BRI_MAC_REINIT;
                goto retry;
        }
        d_fnend(3, dev, "(net_dev %p [i2400m %p]) = %d\n",
@@ -473,7 +483,9 @@ int i2400m_dev_start(struct i2400m *i2400m, enum i2400m_bri bm_flags)
  *
  * Returns: 0 if ok, < 0 errno code on error.
  *
- * Releases all the resources allocated to communicate with the device.
+ * Releases all the resources allocated to communicate with the
+ * device. Note we cannot destroy the workqueue earlier as until RX is
+ * fully destroyed, it could still try to schedule jobs.
  */
 static
 void __i2400m_dev_stop(struct i2400m *i2400m)
@@ -485,8 +497,8 @@ void __i2400m_dev_stop(struct i2400m *i2400m)
        wimax_state_change(wimax_dev, __WIMAX_ST_QUIESCING);
        i2400m_dev_shutdown(i2400m);
        i2400m->ready = 0;
-       destroy_workqueue(i2400m->work_queue);
        i2400m->bus_dev_stop(i2400m);
+       destroy_workqueue(i2400m->work_queue);
        i2400m_rx_release(i2400m);
        i2400m_tx_release(i2400m);
        wimax_state_change(wimax_dev, WIMAX_ST_DOWN);
@@ -548,7 +560,7 @@ void __i2400m_dev_reset_handle(struct work_struct *ws)
                 * i2400m_dev_stop() [we are shutting down anyway, so
                 * ignore it] or we are resetting somewhere else. */
                dev_err(dev, "device rebooted\n");
-               i2400m_msg_to_dev_cancel_wait(i2400m, -ERESTARTSYS);
+               i2400m_msg_to_dev_cancel_wait(i2400m, -EL3RST);
                complete(&i2400m->msg_completion);
                goto out;
        }
@@ -598,6 +610,8 @@ out:
  */
 int i2400m_dev_reset_handle(struct i2400m *i2400m)
 {
+       i2400m->boot_mode = 1;
+       wmb();          /* Make sure i2400m_msg_to_dev() sees boot_mode */
        return i2400m_schedule_work(i2400m, __i2400m_dev_reset_handle,
                                    GFP_ATOMIC);
 }
@@ -650,6 +664,7 @@ int i2400m_setup(struct i2400m *i2400m, enum i2400m_bri bm_flags)
        result = i2400m_read_mac_addr(i2400m);
        if (result < 0)
                goto error_read_mac_addr;
+       random_ether_addr(i2400m->src_mac_addr);
 
        result = register_netdev(net_dev);      /* Okey dokey, bring it up */
        if (result < 0) {
index 675c6ce810c01dbf0f39ddc65b16edc9d0882771..e81750e54452b5d7b4384fb20c15fcead8e17332 100644 (file)
@@ -397,7 +397,7 @@ static int i2400m_download_chunk(struct i2400m *i2400m, const void *chunk,
                                 unsigned int direct, unsigned int do_csum)
 {
        int ret;
-       size_t chunk_len = ALIGN(__chunk_len, I2400M_PL_PAD);
+       size_t chunk_len = ALIGN(__chunk_len, I2400M_PL_ALIGN);
        struct device *dev = i2400m_dev(i2400m);
        struct {
                struct i2400m_bootrom_header cmd;
@@ -532,14 +532,14 @@ int i2400m_dnload_finalize(struct i2400m *i2400m,
        cmd = (void *) bcf + offset;
        if (i2400m->sboot == 0) {
                struct i2400m_bootrom_header jump_ack;
-               d_printf(3, dev, "unsecure boot, jumping to 0x%08x\n",
+               d_printf(1, dev, "unsecure boot, jumping to 0x%08x\n",
                        le32_to_cpu(cmd->target_addr));
                i2400m_brh_set_opcode(cmd, I2400M_BRH_JUMP);
                cmd->data_size = 0;
                ret = i2400m_bm_cmd(i2400m, cmd, sizeof(*cmd),
                                    &jump_ack, sizeof(jump_ack), 0);
        } else {
-               d_printf(3, dev, "secure boot, jumping to 0x%08x\n",
+               d_printf(1, dev, "secure boot, jumping to 0x%08x\n",
                         le32_to_cpu(cmd->target_addr));
                cmd_buf = i2400m->bm_cmd_buf;
                memcpy(&cmd_buf->cmd, cmd, sizeof(*cmd));
@@ -696,8 +696,7 @@ error_dev_gone:
        return result;
 
 error_timeout:
-       dev_err(dev, "Timed out waiting for reboot ack, resetting\n");
-       i2400m->bus_reset(i2400m, I2400M_RT_BUS);
+       dev_err(dev, "Timed out waiting for reboot ack\n");
        result = -ETIMEDOUT;
        goto exit_timeout;
 }
@@ -770,40 +769,21 @@ error_read_mac:
 static
 int i2400m_dnload_init_nonsigned(struct i2400m *i2400m)
 {
-#define POKE(a, d) {                                   \
-       .address = cpu_to_le32(a),              \
-       .data = cpu_to_le32(d)          \
-}
-       static const struct {
-               __le32 address;
-               __le32 data;
-       } i2400m_pokes[] = {
-               POKE(0x081A58, 0xA7810230),
-               POKE(0x080040, 0x00000000),
-               POKE(0x080048, 0x00000082),
-               POKE(0x08004C, 0x0000081F),
-               POKE(0x080054, 0x00000085),
-               POKE(0x080058, 0x00000180),
-               POKE(0x08005C, 0x00000018),
-               POKE(0x080060, 0x00000010),
-               POKE(0x080574, 0x00000001),
-               POKE(0x080550, 0x00000005),
-               POKE(0xAE0000, 0x00000000),
-       };
-#undef POKE
-       unsigned i;
-       int ret;
+       unsigned i = 0;
+       int ret = 0;
        struct device *dev = i2400m_dev(i2400m);
-
-       dev_warn(dev, "WARNING!!! non-signed boot UNTESTED PATH!\n");
-
        d_fnstart(5, dev, "(i2400m %p)\n", i2400m);
-       for (i = 0; i < ARRAY_SIZE(i2400m_pokes); i++) {
-               ret = i2400m_download_chunk(i2400m, &i2400m_pokes[i].data,
-                                           sizeof(i2400m_pokes[i].data),
-                                           i2400m_pokes[i].address, 1, 1);
-               if (ret < 0)
-                       break;
+       if (i2400m->bus_bm_pokes_table) {
+               while (i2400m->bus_bm_pokes_table[i].address) {
+                       ret = i2400m_download_chunk(
+                               i2400m,
+                               &i2400m->bus_bm_pokes_table[i].data,
+                               sizeof(i2400m->bus_bm_pokes_table[i].data),
+                               i2400m->bus_bm_pokes_table[i].address, 1, 1);
+                       if (ret < 0)
+                               break;
+                       i++;
+               }
        }
        d_fnend(5, dev, "(i2400m %p) = %d\n", i2400m, ret);
        return ret;
@@ -980,11 +960,12 @@ int i2400m_fw_dnload(struct i2400m *i2400m, const struct i2400m_bcf_hdr *bcf,
 {
        int ret = 0;
        struct device *dev = i2400m_dev(i2400m);
-       int count = I2400M_BOOT_RETRIES;
+       int count = i2400m->bus_bm_retries;
 
        d_fnstart(5, dev, "(i2400m %p bcf %p size %zu)\n",
                  i2400m, bcf, bcf_size);
        i2400m->boot_mode = 1;
+       wmb();          /* Make sure other readers see it */
 hw_reboot:
        if (count-- == 0) {
                ret = -ERESTARTSYS;
@@ -1033,6 +1014,7 @@ hw_reboot:
        d_printf(2, dev, "fw %s successfully uploaded\n",
                 i2400m->fw_name);
        i2400m->boot_mode = 0;
+       wmb();          /* Make sure i2400m_msg_to_dev() sees boot_mode */
 error_dnload_finalize:
 error_dnload_bcf:
 error_dnload_init:
index 08c2fb739234c0110782336b30d8155240aa327a..9c4e3189f7b5c48feb4cf4ac564141febe6b18c0 100644 (file)
@@ -78,6 +78,8 @@ enum {
        /* The number of ticks to wait for the device to signal that
         * it is ready */
        I2400MS_INIT_SLEEP_INTERVAL = 10,
+       /* How long to wait for the device to settle after reset */
+       I2400MS_SETTLE_TIME = 40,
 };
 
 
@@ -105,6 +107,10 @@ struct i2400ms {
        char tx_wq_name[32];
 
        struct dentry *debugfs_dentry;
+
+       wait_queue_head_t bm_wfa_wq;
+       int bm_wait_result;
+       size_t bm_ack_size;
 };
 
 
@@ -129,4 +135,7 @@ extern ssize_t i2400ms_bus_bm_cmd_send(struct i2400m *,
 extern ssize_t i2400ms_bus_bm_wait_for_ack(struct i2400m *,
                                           struct i2400m_bootrom_header *,
                                           size_t);
+extern void i2400ms_bus_bm_release(struct i2400m *);
+extern int i2400ms_bus_bm_setup(struct i2400m *);
+
 #endif /* #ifndef __I2400M_SDIO_H__ */
index 3ae2df38b59a7cc0bb4ceff1ba2e1700c11ec646..1fe5da4cf0a02d918942e0f19f7a36aaf9ef1264 100644 (file)
 enum {
        /* Firmware uploading */
        I2400M_BOOT_RETRIES = 3,
+       I3200_BOOT_RETRIES = 3,
        /* Size of the Boot Mode Command buffer */
        I2400M_BM_CMD_BUF_SIZE = 16 * 1024,
        I2400M_BM_ACK_BUF_SIZE = 256,
 };
 
+/**
+ * struct i2400m_poke_table - Hardware poke table for the Intel 2400m
+ *
+ * This structure will be used to create a device specific poke table
+ * to put the device in a consistant state at boot time.
+ *
+ * @address: The device address to poke
+ *
+ * @data: The data value to poke to the device address
+ *
+ */
+struct i2400m_poke_table{
+       __le32 address;
+       __le32 data;
+};
+
+#define I2400M_FW_POKE(a, d) {         \
+       .address = cpu_to_le32(a),      \
+       .data = cpu_to_le32(d)          \
+}
+
 
 /**
  * i2400m_reset_type - methods to reset a device
@@ -224,6 +246,17 @@ struct i2400m_roq;
  *     process, so it cannot rely on common infrastructure being laid
  *     out.
  *
+ * @bus_bm_retries: [fill] How many times shall a firmware upload /
+ *     device initialization be retried? Different models of the same
+ *     device might need different values, hence it is set by the
+ *     bus-specific driver. Note this value is used in two places,
+ *     i2400m_fw_dnload() and __i2400m_dev_start(); they won't become
+ *     multiplicative (__i2400m_dev_start() calling N times
+ *     i2400m_fw_dnload() and this trying N times to download the
+ *     firmware), as if __i2400m_dev_start() only retries if the
+ *     firmware crashed while initializing the device (not in a
+ *     general case).
+ *
  * @bus_bm_cmd_send: [fill] Function called to send a boot-mode
  *     command. Flags are defined in 'enum i2400m_bm_cmd_flags'. This
  *     is synchronous and has to return 0 if ok or < 0 errno code in
@@ -252,6 +285,12 @@ struct i2400m_roq;
  *     address provided in boot mode is kind of broken and needs to
  *     be re-read later on.
  *
+ * @bus_bm_pokes_table: [fill/optional] A table of device addresses
+ *     and values that will be poked at device init time to move the
+ *     device to the correct state for the type of boot/firmware being
+ *     used.  This table MUST be terminated with (0x000000,
+ *     0x00000000) or bad things will happen.
+ *
  *
  * @wimax_dev: WiMAX generic device for linkage into the kernel WiMAX
  *     stack. Due to the way a net_device is allocated, we need to
@@ -323,6 +362,10 @@ struct i2400m_roq;
  *     delivered. Then the driver can release them to the host. See
  *     drivers/net/i2400m/rx.c for details.
  *
+ * @src_mac_addr: MAC address used to make ethernet packets be coming
+ *     from. This is generated at i2400m_setup() time and used during
+ *     the life cycle of the instance. See i2400m_fake_eth_header().
+ *
  * @init_mutex: Mutex used for serializing the device bringup
  *     sequence; this way if the device reboots in the middle, we
  *     don't try to do a bringup again while we are tearing down the
@@ -395,6 +438,8 @@ struct i2400m {
 
        size_t bus_tx_block_size;
        size_t bus_pl_size_max;
+       unsigned bus_bm_retries;
+
        int (*bus_dev_start)(struct i2400m *);
        void (*bus_dev_stop)(struct i2400m *);
        void (*bus_tx_kick)(struct i2400m *);
@@ -406,6 +451,7 @@ struct i2400m {
                                       struct i2400m_bootrom_header *, size_t);
        const char **bus_fw_names;
        unsigned bus_bm_mac_addr_impaired:1;
+       const struct i2400m_poke_table *bus_bm_pokes_table;
 
        spinlock_t tx_lock;             /* protect TX state */
        void *tx_buf;
@@ -421,6 +467,7 @@ struct i2400m {
        unsigned rx_pl_num, rx_pl_max, rx_pl_min,
                rx_num, rx_size_acc, rx_size_min, rx_size_max;
        struct i2400m_roq *rx_roq;      /* not under rx_lock! */
+       u8 src_mac_addr[ETH_HLEN];
 
        struct mutex msg_mutex;         /* serialize command execution */
        struct completion msg_completion;
@@ -704,6 +751,7 @@ static const __le32 i2400m_SBOOT_BARKER[4] = {
        cpu_to_le32(I2400M_SBOOT_BARKER)
 };
 
+extern int i2400m_power_save_disabled;
 
 /*
  * Utility functions
index 6b1fe7a81f25f4a2a0314fe6c30c721092e4a788..9653f478b382f166fa469a752a0057a8d87183c5 100644 (file)
@@ -404,10 +404,12 @@ static
 void i2400m_rx_fake_eth_header(struct net_device *net_dev,
                               void *_eth_hdr, __be16 protocol)
 {
+       struct i2400m *i2400m = net_dev_to_i2400m(net_dev);
        struct ethhdr *eth_hdr = _eth_hdr;
 
        memcpy(eth_hdr->h_dest, net_dev->dev_addr, sizeof(eth_hdr->h_dest));
-       memset(eth_hdr->h_source, 0, sizeof(eth_hdr->h_dest));
+       memcpy(eth_hdr->h_source, i2400m->src_mac_addr,
+              sizeof(eth_hdr->h_source));
        eth_hdr->h_proto = protocol;
 }
 
index 487ec58cea46563ccf7c561f2c83fc1890545f21..43927b5d7ad6158a959b06f305e008b56bb306b5 100644 (file)
@@ -54,8 +54,10 @@ int i2400m_radio_is(struct i2400m *i2400m, enum wimax_rf_state state)
                /* state == WIMAX_RF_ON */
                return i2400m->state != I2400M_SS_RF_OFF
                        && i2400m->state != I2400M_SS_RF_SHUTDOWN;
-       else
+       else {
                BUG();
+               return -EINVAL; /* shut gcc warnings on certain arches */
+       }
 }
 
 
index f9fc389023224e2f70880192ae765d78488ce84d..07c32e68909f93c33ceb08fd58d332c848193fa9 100644 (file)
@@ -177,7 +177,8 @@ void i2400m_report_hook_work(struct work_struct *ws)
        struct i2400m_work *iw =
                container_of(ws, struct i2400m_work, ws);
        struct i2400m_report_hook_args *args = (void *) iw->pl;
-       i2400m_report_hook(iw->i2400m, args->l3l4_hdr, args->size);
+       if (iw->i2400m->ready)
+               i2400m_report_hook(iw->i2400m, args->l3l4_hdr, args->size);
        kfree_skb(args->skb_rx);
        i2400m_put(iw->i2400m);
        kfree(iw);
@@ -309,6 +310,9 @@ void i2400m_rx_ctl(struct i2400m *i2400m, struct sk_buff *skb_rx,
                skb_get(skb_rx);
                i2400m_queue_work(i2400m, i2400m_report_hook_work,
                                  GFP_KERNEL, &args, sizeof(args));
+               if (unlikely(i2400m->trace_msg_from_user))
+                       wimax_msg(&i2400m->wimax_dev, "echo",
+                                 l3l4_hdr, size, GFP_KERNEL);
                result = wimax_msg(&i2400m->wimax_dev, NULL, l3l4_hdr, size,
                                   GFP_KERNEL);
                if (result < 0)
@@ -1144,7 +1148,7 @@ int i2400m_rx(struct i2400m *i2400m, struct sk_buff *skb)
        num_pls = le16_to_cpu(msg_hdr->num_pls);
        pl_itr = sizeof(*msg_hdr) +     /* Check payload descriptor(s) */
                num_pls * sizeof(msg_hdr->pld[0]);
-       pl_itr = ALIGN(pl_itr, I2400M_PL_PAD);
+       pl_itr = ALIGN(pl_itr, I2400M_PL_ALIGN);
        if (pl_itr > skb->len) {        /* got all the payload descriptors? */
                dev_err(dev, "RX: HW BUG? message too short (%u bytes) for "
                        "%u payload descriptors (%zu each, total %zu)\n",
@@ -1162,7 +1166,7 @@ int i2400m_rx(struct i2400m *i2400m, struct sk_buff *skb)
                single_last = num_pls == 1 || i == num_pls - 1;
                i2400m_rx_payload(i2400m, skb, single_last, &msg_hdr->pld[i],
                                  skb->data + pl_itr);
-               pl_itr += ALIGN(pl_size, I2400M_PL_PAD);
+               pl_itr += ALIGN(pl_size, I2400M_PL_ALIGN);
                cond_resched();         /* Don't monopolize */
        }
        kfree_skb(skb);
index 3487205d8f505b198d3b41ec516341985530d304..7d6ec0f475f83b17d483b311cb1baef656bcefb9 100644 (file)
  * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
  *  - SDIO rehash for changes in the bus-driver model
  *
+ * Dirk Brandewie <dirk.j.brandewie@intel.com>
+ *  - Make it IRQ based, not polling
+ *
  * THE PROCEDURE
  *
  * See fw.c for the generic description of this procedure.
  *
  * This file implements only the SDIO specifics. It boils down to how
  * to send a command and waiting for an acknowledgement from the
- * device. We do polled reads.
+ * device.
+ *
+ * All this code is sequential -- all i2400ms_bus_bm_*() functions are
+ * executed in the same thread, except i2400ms_bm_irq() [on its own by
+ * the SDIO driver]. This makes it possible to avoid locking.
  *
  * COMMAND EXECUTION
  *
- * THe generic firmware upload code will call i2400m_bus_bm_cmd_send()
+ * The generic firmware upload code will call i2400m_bus_bm_cmd_send()
  * to send commands.
  *
  * The SDIO devices expects things in 256 byte blocks, so it will pad
  *
  * ACK RECEPTION
  *
- * This works in polling mode -- the fw loader says when to wait for
- * data and for that it calls i2400ms_bus_bm_wait_for_ack().
+ * This works in IRQ mode -- the fw loader says when to wait for data
+ * and for that it calls i2400ms_bus_bm_wait_for_ack().
  *
- * This will poll the device for data until it is received. We need to
- * receive at least as much bytes as where asked for (although it'll
- * always be a multiple of 256 bytes).
+ * This checks if there is any data available (RX size > 0); if not,
+ * waits for the IRQ handler to notify about it. Once there is data,
+ * it is read and passed to the caller. Doing it this way we don't
+ * need much coordination/locking, and it makes it much more difficult
+ * for an interrupt to be lost and the wait_for_ack() function getting
+ * stuck even when data is pending.
  */
 #include <linux/mmc/sdio_func.h>
 #include "i2400m-sdio.h"
@@ -78,6 +88,7 @@
 #define D_SUBMODULE fw
 #include "sdio-debug-levels.h"
 
+
 /*
  * Send a boot-mode command to the SDIO function
  *
@@ -139,7 +150,7 @@ error_too_big:
 
 
 /*
- * Read an ack from the device's boot-mode (polling)
+ * Read an ack from the device's boot-mode
  *
  * @i2400m:
  * @_ack: pointer to where to store the read data
@@ -150,75 +161,49 @@ error_too_big:
  * The ACK for a BM command is always at least sizeof(*ack) bytes, so
  * check for that. We don't need to check for device reboots
  *
- * NOTE: We do an artificial timeout of 1 sec over the SDIO timeout;
- *     this way we have control over it...there is no way that I know
- *     of setting an SDIO transaction timeout.
  */
 ssize_t i2400ms_bus_bm_wait_for_ack(struct i2400m *i2400m,
                                    struct i2400m_bootrom_header *ack,
                                    size_t ack_size)
 {
-       int result;
-       ssize_t rx_size;
-       u64 timeout;
+       ssize_t result;
        struct i2400ms *i2400ms = container_of(i2400m, struct i2400ms, i2400m);
        struct sdio_func *func = i2400ms->func;
        struct device *dev = &func->dev;
+       int size;
 
        BUG_ON(sizeof(*ack) > ack_size);
 
        d_fnstart(5, dev, "(i2400m %p ack %p size %zu)\n",
                  i2400m, ack, ack_size);
 
-       timeout = get_jiffies_64() + 2 * HZ;
-       sdio_claim_host(func);
-       while (1) {
-               if (time_after64(get_jiffies_64(), timeout)) {
-                       rx_size = -ETIMEDOUT;
-                       dev_err(dev, "timeout waiting for ack data\n");
-                       goto error_timedout;
-               }
+       spin_lock(&i2400m->rx_lock);
+       i2400ms->bm_ack_size = -EINPROGRESS;
+       spin_unlock(&i2400m->rx_lock);
 
-               /* Find the RX size, check if it fits or not -- it if
-                * doesn't fit, fail, as we have no way to dispose of
-                * the extra data. */
-               rx_size = __i2400ms_rx_get_size(i2400ms);
-               if (rx_size < 0)
-                       goto error_rx_get_size;
-               result = -ENOSPC;               /* Check it fits */
-               if (rx_size < sizeof(*ack)) {
-                       rx_size = -EIO;
-                       dev_err(dev, "HW BUG? received is too small (%zu vs "
-                               "%zu needed)\n", sizeof(*ack), rx_size);
-                       goto error_too_small;
-               }
-               if (rx_size > I2400M_BM_ACK_BUF_SIZE) {
-                       dev_err(dev, "SW BUG? BM_ACK_BUF is too small (%u vs "
-                               "%zu needed)\n", I2400M_BM_ACK_BUF_SIZE,
-                               rx_size);
-                       goto error_too_small;
-               }
+       result = wait_event_timeout(i2400ms->bm_wfa_wq,
+                                   i2400ms->bm_ack_size != -EINPROGRESS,
+                                   2 * HZ);
+       if (result == 0) {
+               result = -ETIMEDOUT;
+               dev_err(dev, "BM: error waiting for an ack\n");
+               goto error_timeout;
+       }
 
-               /* Read it */
-               result = sdio_memcpy_fromio(func, i2400m->bm_ack_buf,
-                                           I2400MS_DATA_ADDR, rx_size);
-               if (result == -ETIMEDOUT || result == -ETIME)
-                       continue;
-               if (result < 0) {
-                       dev_err(dev, "BM SDIO receive (%zu B) failed: %d\n",
-                               rx_size, result);
-                       goto error_read;
-               } else
-                       break;
+       spin_lock(&i2400m->rx_lock);
+       result = i2400ms->bm_ack_size;
+       BUG_ON(result == -EINPROGRESS);
+       if (result < 0)        /* so we exit when rx_release() is called */
+               dev_err(dev, "BM: %s failed: %zd\n", __func__, result);
+       else {
+               size = min(ack_size, i2400ms->bm_ack_size);
+               memcpy(ack, i2400m->bm_ack_buf, size);
        }
-       rx_size = min((ssize_t)ack_size, rx_size);
-       memcpy(ack, i2400m->bm_ack_buf, rx_size);
-error_read:
-error_too_small:
-error_rx_get_size:
-error_timedout:
-       sdio_release_host(func);
-       d_fnend(5, dev, "(i2400m %p ack %p size %zu) = %ld\n",
-               i2400m, ack, ack_size, (long) rx_size);
-       return rx_size;
+       i2400ms->bm_ack_size = -EINPROGRESS;
+       spin_unlock(&i2400m->rx_lock);
+
+error_timeout:
+       d_fnend(5, dev, "(i2400m %p ack %p size %zu) = %zd\n",
+               i2400m, ack, ack_size, result);
+       return result;
 }
index a3008b904f7ddc02395c33f2bf53a52f4b5ac4df..321beadf6e475d2fa8758dcdde1972195559abe8 100644 (file)
 #define D_SUBMODULE rx
 #include "sdio-debug-levels.h"
 
+static const __le32 i2400m_ACK_BARKER[4] = {
+       __constant_cpu_to_le32(I2400M_ACK_BARKER),
+       __constant_cpu_to_le32(I2400M_ACK_BARKER),
+       __constant_cpu_to_le32(I2400M_ACK_BARKER),
+       __constant_cpu_to_le32(I2400M_ACK_BARKER)
+};
+
 
 /*
  * Read and return the amount of bytes available for RX
@@ -131,25 +138,35 @@ void i2400ms_rx(struct i2400ms *i2400ms)
                ret = rx_size;
                goto error_get_size;
        }
+
        ret = -ENOMEM;
        skb = alloc_skb(rx_size, GFP_ATOMIC);
        if (NULL == skb) {
                dev_err(dev, "RX: unable to alloc skb\n");
                goto error_alloc_skb;
        }
-
        ret = sdio_memcpy_fromio(func, skb->data,
                                 I2400MS_DATA_ADDR, rx_size);
        if (ret < 0) {
                dev_err(dev, "RX: SDIO data read failed: %d\n", ret);
                goto error_memcpy_fromio;
        }
-       /* Check if device has reset */
-       if (!memcmp(skb->data, i2400m_NBOOT_BARKER,
-                   sizeof(i2400m_NBOOT_BARKER))
-           || !memcmp(skb->data, i2400m_SBOOT_BARKER,
-                      sizeof(i2400m_SBOOT_BARKER))) {
+
+       rmb();  /* make sure we get boot_mode from dev_reset_handle */
+       if (i2400m->boot_mode == 1) {
+               spin_lock(&i2400m->rx_lock);
+               i2400ms->bm_ack_size = rx_size;
+               spin_unlock(&i2400m->rx_lock);
+               memcpy(i2400m->bm_ack_buf, skb->data, rx_size);
+               wake_up(&i2400ms->bm_wfa_wq);
+               dev_err(dev, "RX: SDIO boot mode message\n");
+               kfree_skb(skb);
+       } else if (unlikely(!memcmp(skb->data, i2400m_NBOOT_BARKER,
+                                   sizeof(i2400m_NBOOT_BARKER))
+                           || !memcmp(skb->data, i2400m_SBOOT_BARKER,
+                                      sizeof(i2400m_SBOOT_BARKER)))) {
                ret = i2400m_dev_reset_handle(i2400m);
+               dev_err(dev, "RX: SDIO reboot barker\n");
                kfree_skb(skb);
        } else {
                skb_put(skb, rx_size);
@@ -179,7 +196,6 @@ void i2400ms_irq(struct sdio_func *func)
 {
        int ret;
        struct i2400ms *i2400ms = sdio_get_drvdata(func);
-       struct i2400m *i2400m = &i2400ms->i2400m;
        struct device *dev = &func->dev;
        int val;
 
@@ -194,10 +210,7 @@ void i2400ms_irq(struct sdio_func *func)
                goto error_no_irq;
        }
        sdio_writeb(func, 1, I2400MS_INTR_CLEAR_ADDR, &ret);
-       if (WARN_ON(i2400m->boot_mode != 0))
-               dev_err(dev, "RX: SW BUG? boot mode and IRQ is up?\n");
-       else
-               i2400ms_rx(i2400ms);
+       i2400ms_rx(i2400ms);
 error_no_irq:
        d_fnend(6, dev, "(i2400ms %p) = void\n", i2400ms);
        return;
@@ -214,8 +227,15 @@ int i2400ms_rx_setup(struct i2400ms *i2400ms)
        int result;
        struct sdio_func *func = i2400ms->func;
        struct device *dev = &func->dev;
+       struct i2400m *i2400m = &i2400ms->i2400m;
 
        d_fnstart(5, dev, "(i2400ms %p)\n", i2400ms);
+
+       init_waitqueue_head(&i2400ms->bm_wfa_wq);
+       spin_lock(&i2400m->rx_lock);
+       i2400ms->bm_wait_result = -EINPROGRESS;
+       spin_unlock(&i2400m->rx_lock);
+
        sdio_claim_host(func);
        result = sdio_claim_irq(func, i2400ms_irq);
        if (result < 0) {
@@ -245,8 +265,13 @@ void i2400ms_rx_release(struct i2400ms *i2400ms)
        int result;
        struct sdio_func *func = i2400ms->func;
        struct device *dev = &func->dev;
+       struct i2400m *i2400m = &i2400ms->i2400m;
 
        d_fnstart(5, dev, "(i2400ms %p)\n", i2400ms);
+       spin_lock(&i2400m->rx_lock);
+       i2400ms->bm_ack_size = -EINTR;
+       spin_unlock(&i2400m->rx_lock);
+       wake_up_all(&i2400ms->bm_wfa_wq);
        sdio_claim_host(func);
        sdio_writeb(func, 0, I2400MS_INTR_ENABLE_ADDR, &result);
        sdio_release_irq(func);
index 5ac5e76701cd8d3761764c1424d78f1b51a828e9..2538825d1c662580d8211937937e6ec6084cfd1d 100644 (file)
@@ -78,6 +78,14 @@ static const char *i2400ms_bus_fw_names[] = {
 };
 
 
+static const struct i2400m_poke_table i2400ms_pokes[] = {
+       I2400M_FW_POKE(0x6BE260, 0x00000088),
+       I2400M_FW_POKE(0x080550, 0x00000005),
+       I2400M_FW_POKE(0xAE0000, 0x00000000),
+       I2400M_FW_POKE(0x000000, 0x00000000), /* MUST be 0 terminated or bad
+                                              * things will happen */
+};
+
 /*
  * Enable the SDIO function
  *
@@ -148,19 +156,14 @@ int i2400ms_bus_dev_start(struct i2400m *i2400m)
 
        d_fnstart(3, dev, "(i2400m %p)\n", i2400m);
        msleep(200);
-       result = i2400ms_rx_setup(i2400ms);
-       if (result < 0)
-               goto error_rx_setup;
        result = i2400ms_tx_setup(i2400ms);
        if (result < 0)
                goto error_tx_setup;
        d_fnend(3, dev, "(i2400m %p) = %d\n", i2400m, result);
        return result;
 
-       i2400ms_tx_release(i2400ms);
 error_tx_setup:
-       i2400ms_rx_release(i2400ms);
-error_rx_setup:
+       i2400ms_tx_release(i2400ms);
        d_fnend(3, dev, "(i2400m %p) = void\n", i2400m);
        return result;
 }
@@ -174,7 +177,6 @@ void i2400ms_bus_dev_stop(struct i2400m *i2400m)
        struct device *dev = &func->dev;
 
        d_fnstart(3, dev, "(i2400m %p)\n", i2400m);
-       i2400ms_rx_release(i2400ms);
        i2400ms_tx_release(i2400ms);
        d_fnend(3, dev, "(i2400m %p) = void\n", i2400m);
 }
@@ -255,7 +257,7 @@ error_kzalloc:
 static
 int i2400ms_bus_reset(struct i2400m *i2400m, enum i2400m_reset_type rt)
 {
-       int result;
+       int result = 0;
        struct i2400ms *i2400ms =
                container_of(i2400m, struct i2400ms, i2400m);
        struct device *dev = i2400m_dev(i2400m);
@@ -280,8 +282,25 @@ int i2400ms_bus_reset(struct i2400m *i2400m, enum i2400m_reset_type rt)
                                               sizeof(i2400m_COLD_BOOT_BARKER));
        else if (rt == I2400M_RT_BUS) {
 do_bus_reset:
-               dev_err(dev, "FIXME: SDIO bus reset not implemented\n");
-               result = rt == I2400M_RT_WARM ? -ENODEV : -ENOSYS;
+               /* call netif_tx_disable() before sending IOE disable,
+                * so that all the tx from network layer are stopped
+                * while IOE is being reset. Make sure it is called
+                * only after register_netdev() was issued.
+                */
+               if (i2400m->wimax_dev.net_dev->reg_state == NETREG_REGISTERED)
+                       netif_tx_disable(i2400m->wimax_dev.net_dev);
+
+               i2400ms_rx_release(i2400ms);
+               sdio_claim_host(i2400ms->func);
+               sdio_disable_func(i2400ms->func);
+               sdio_release_host(i2400ms->func);
+
+               /* Wait for the device to settle */
+               msleep(40);
+
+               result = i2400ms_enable_function(i2400ms->func);
+               if (result >= 0)
+                       i2400ms_rx_setup(i2400ms);
        } else
                BUG();
        if (result < 0 && rt != I2400M_RT_BUS) {
@@ -404,24 +423,32 @@ int i2400ms_probe(struct sdio_func *func,
        i2400m->bus_dev_stop = i2400ms_bus_dev_stop;
        i2400m->bus_tx_kick = i2400ms_bus_tx_kick;
        i2400m->bus_reset = i2400ms_bus_reset;
+       /* The iwmc3200-wimax sometimes requires the driver to try
+        * hard when we paint it into a corner. */
+       i2400m->bus_bm_retries = I3200_BOOT_RETRIES;
        i2400m->bus_bm_cmd_send = i2400ms_bus_bm_cmd_send;
        i2400m->bus_bm_wait_for_ack = i2400ms_bus_bm_wait_for_ack;
        i2400m->bus_fw_names = i2400ms_bus_fw_names;
        i2400m->bus_bm_mac_addr_impaired = 1;
-
-       result = i2400ms_enable_function(i2400ms->func);
-       if (result < 0) {
-               dev_err(dev, "Cannot enable SDIO function: %d\n", result);
-               goto error_func_enable;
-       }
+       i2400m->bus_bm_pokes_table = &i2400ms_pokes[0];
 
        sdio_claim_host(func);
        result = sdio_set_block_size(func, I2400MS_BLK_SIZE);
+       sdio_release_host(func);
        if (result < 0) {
                dev_err(dev, "Failed to set block size: %d\n", result);
                goto error_set_blk_size;
        }
-       sdio_release_host(func);
+
+       result = i2400ms_enable_function(i2400ms->func);
+       if (result < 0) {
+               dev_err(dev, "Cannot enable SDIO function: %d\n", result);
+               goto error_func_enable;
+       }
+
+       result = i2400ms_rx_setup(i2400ms);
+       if (result < 0)
+               goto error_rx_setup;
 
        result = i2400m_setup(i2400m, I2400M_BRI_NO_REBOOT);
        if (result < 0) {
@@ -440,12 +467,14 @@ int i2400ms_probe(struct sdio_func *func,
 error_debugfs_add:
        i2400m_release(i2400m);
 error_setup:
-       sdio_set_drvdata(func, NULL);
+       i2400ms_rx_release(i2400ms);
+error_rx_setup:
        sdio_claim_host(func);
-error_set_blk_size:
        sdio_disable_func(func);
        sdio_release_host(func);
 error_func_enable:
+error_set_blk_size:
+       sdio_set_drvdata(func, NULL);
        free_netdev(net_dev);
 error_alloc_netdev:
        return result;
@@ -462,6 +491,7 @@ void i2400ms_remove(struct sdio_func *func)
 
        d_fnstart(3, dev, "SDIO func %p\n", func);
        debugfs_remove_recursive(i2400ms->debugfs_dentry);
+       i2400ms_rx_release(i2400ms);
        i2400m_release(i2400m);
        sdio_set_drvdata(func, NULL);
        sdio_claim_host(func);
index 613a88ffd651e03725d333feb5d77baa5cdd13e7..fa16ccf8e26a40bf5795c635c030f9713dd50fe6 100644 (file)
@@ -277,6 +277,48 @@ enum {
 
 #define TAIL_FULL ((void *)~(unsigned long)NULL)
 
+/*
+ * Calculate how much tail room is available
+ *
+ * Note the trick here. This path is ONLY caleed for Case A (see
+ * i2400m_tx_fifo_push() below), where we have:
+ *
+ *       Case A
+ * N  ___________
+ *   | tail room |
+ *   |           |
+ *   |<-  IN   ->|
+ *   |           |
+ *   |   data    |
+ *   |           |
+ *   |<-  OUT  ->|
+ *   |           |
+ *   | head room |
+ * 0  -----------
+ *
+ * When calculating the tail_room, tx_in might get to be zero if
+ * i2400m->tx_in is right at the end of the buffer (really full
+ * buffer) if there is no head room. In this case, tail_room would be
+ * I2400M_TX_BUF_SIZE, although it is actually zero. Hence the final
+ * mod (%) operation. However, when doing this kind of optimization,
+ * i2400m->tx_in being zero would fail, so we treat is an a special
+ * case.
+ */
+static inline
+size_t __i2400m_tx_tail_room(struct i2400m *i2400m)
+{
+       size_t tail_room;
+       size_t tx_in;
+
+       if (unlikely(i2400m->tx_in) == 0)
+               return I2400M_TX_BUF_SIZE;
+       tx_in = i2400m->tx_in % I2400M_TX_BUF_SIZE;
+       tail_room = I2400M_TX_BUF_SIZE - tx_in;
+       tail_room %= I2400M_TX_BUF_SIZE;
+       return tail_room;
+}
+
+
 /*
  * Allocate @size bytes in the TX fifo, return a pointer to it
  *
@@ -338,7 +380,7 @@ void *i2400m_tx_fifo_push(struct i2400m *i2400m, size_t size, size_t padding)
                return NULL;
        }
        /* Is there space at the tail? */
-       tail_room = I2400M_TX_BUF_SIZE - i2400m->tx_in % I2400M_TX_BUF_SIZE;
+       tail_room = __i2400m_tx_tail_room(i2400m);
        if (tail_room < needed_size) {
                if (i2400m->tx_out % I2400M_TX_BUF_SIZE
                    < i2400m->tx_in % I2400M_TX_BUF_SIZE) {
@@ -367,17 +409,29 @@ void *i2400m_tx_fifo_push(struct i2400m *i2400m, size_t size, size_t padding)
  * (I2400M_PL_PAD for the payloads, I2400M_TX_PLD_SIZE for the
  * header).
  *
+ * Tail room can get to be zero if a message was opened when there was
+ * space only for a header. _tx_close() will mark it as to-skip (as it
+ * will have no payloads) and there will be no more space to flush, so
+ * nothing has to be done here. This is probably cheaper than ensuring
+ * in _tx_new() that there is some space for payloads...as we could
+ * always possibly hit the same problem if the payload wouldn't fit.
+ *
  * Note:
  *
  *     Assumes i2400m->tx_lock is taken, and we use that as a barrier
+ *
+ *     This path is only taken for Case A FIFO situations [see
+ *     i2400m_tx_fifo_push()]
  */
 static
 void i2400m_tx_skip_tail(struct i2400m *i2400m)
 {
        struct device *dev = i2400m_dev(i2400m);
        size_t tx_in = i2400m->tx_in % I2400M_TX_BUF_SIZE;
-       size_t tail_room = I2400M_TX_BUF_SIZE - tx_in;
+       size_t tail_room = __i2400m_tx_tail_room(i2400m);
        struct i2400m_msg_hdr *msg = i2400m->tx_buf + tx_in;
+       if (unlikely(tail_room == 0))
+               return;
        BUG_ON(tail_room < sizeof(*msg));
        msg->size = tail_room | I2400M_TX_SKIP;
        d_printf(2, dev, "skip tail: skipping %zu bytes @%zu\n",
@@ -474,10 +528,18 @@ void i2400m_tx_close(struct i2400m *i2400m)
        struct i2400m_msg_hdr *tx_msg_moved;
        size_t aligned_size, padding, hdr_size;
        void *pad_buf;
+       unsigned num_pls;
 
        if (tx_msg->size & I2400M_TX_SKIP)      /* a skipper? nothing to do */
                goto out;
-
+       num_pls = le16_to_cpu(tx_msg->num_pls);
+       /* We can get this situation when a new message was started
+        * and there was no space to add payloads before hitting the
+        tail (and taking padding into consideration). */
+       if (num_pls == 0) {
+               tx_msg->size |= I2400M_TX_SKIP;
+               goto out;
+       }
        /* Relocate the message header
         *
         * Find the current header size, align it to 16 and if we need
@@ -491,7 +553,7 @@ void i2400m_tx_close(struct i2400m *i2400m)
         */
        hdr_size = sizeof(*tx_msg)
                + le16_to_cpu(tx_msg->num_pls) * sizeof(tx_msg->pld[0]);
-       hdr_size = ALIGN(hdr_size, I2400M_PL_PAD);
+       hdr_size = ALIGN(hdr_size, I2400M_PL_ALIGN);
        tx_msg->offset = I2400M_TX_PLD_SIZE - hdr_size;
        tx_msg_moved = (void *) tx_msg + tx_msg->offset;
        memmove(tx_msg_moved, tx_msg, hdr_size);
@@ -574,7 +636,7 @@ int i2400m_tx(struct i2400m *i2400m, const void *buf, size_t buf_len,
 
        d_fnstart(3, dev, "(i2400m %p skb %p [%zu bytes] pt %u)\n",
                  i2400m, buf, buf_len, pl_type);
-       padded_len = ALIGN(buf_len, I2400M_PL_PAD);
+       padded_len = ALIGN(buf_len, I2400M_PL_ALIGN);
        d_printf(5, dev, "padded_len %zd buf_len %zd\n", padded_len, buf_len);
        /* If there is no current TX message, create one; if the
         * current one is out of payload slots or we have a singleton,
@@ -591,6 +653,8 @@ try_new:
                i2400m_tx_close(i2400m);
                i2400m_tx_new(i2400m);
        }
+       if (i2400m->tx_msg == NULL)
+               goto error_tx_new;
        if (i2400m->tx_msg->size + padded_len > I2400M_TX_BUF_SIZE / 2) {
                d_printf(2, dev, "TX: message too big, going new\n");
                i2400m_tx_close(i2400m);
@@ -773,7 +837,6 @@ void i2400m_tx_msg_sent(struct i2400m *i2400m)
        n = i2400m->tx_out / I2400M_TX_BUF_SIZE;
        i2400m->tx_out %= I2400M_TX_BUF_SIZE;
        i2400m->tx_in -= n * I2400M_TX_BUF_SIZE;
-       netif_start_queue(i2400m->wimax_dev.net_dev);
        spin_unlock_irqrestore(&i2400m->tx_lock, flags);
        d_fnend(3, dev, "(i2400m %p) = void\n", i2400m);
 }
index 17851321b7fd0ea7bd1e7815577ba5654de149ce..cfdaf69da9d1bbc2ed98ca99848d77228c53f52e 100644 (file)
@@ -254,8 +254,10 @@ do_bus_reset:
                        dev_err(dev, "USB reset failed (%d), giving up!\n",
                                result);
                }
-       } else
+       } else {
+               result = -EINVAL;       /* shut gcc up in certain arches */
                BUG();
+       }
        if (result < 0
            && result != -EINVAL        /* device is gone */
            && rt != I2400M_RT_BUS) {
@@ -399,6 +401,7 @@ int i2400mu_probe(struct usb_interface *iface,
        i2400m->bus_dev_stop = i2400mu_bus_dev_stop;
        i2400m->bus_tx_kick = i2400mu_bus_tx_kick;
        i2400m->bus_reset = i2400mu_bus_reset;
+       i2400m->bus_bm_retries = I2400M_BOOT_RETRIES;
        i2400m->bus_bm_cmd_send = i2400mu_bus_bm_cmd_send;
        i2400m->bus_bm_wait_for_ack = i2400mu_bus_bm_wait_for_ack;
        i2400m->bus_fw_names = i2400mu_bus_fw_names;
index 3359497012aa468f32654388558887fb298e8f4c..5bc00db21b24f6e28f576613ab9dc6f22b95b3d6 100644 (file)
@@ -146,14 +146,14 @@ config LIBERTAS_CS
          A driver for Marvell Libertas 8385 CompactFlash devices.
 
 config LIBERTAS_SDIO
-       tristate "Marvell Libertas 8385 and 8686 SDIO 802.11b/g cards"
+       tristate "Marvell Libertas 8385/8686/8688 SDIO 802.11b/g cards"
        depends on LIBERTAS && MMC
        ---help---
-         A driver for Marvell Libertas 8385 and 8686 SDIO devices.
+         A driver for Marvell Libertas 8385/8686/8688 SDIO devices.
 
 config LIBERTAS_SPI
        tristate "Marvell Libertas 8686 SPI 802.11b/g cards"
-       depends on LIBERTAS && SPI && GENERIC_GPIO
+       depends on LIBERTAS && SPI
        ---help---
          A driver for Marvell Libertas 8686 SPI devices.
 
@@ -333,6 +333,7 @@ config USB_ZD1201
 config USB_NET_RNDIS_WLAN
        tristate "Wireless RNDIS USB support"
        depends on USB && WLAN_80211 && EXPERIMENTAL
+       depends on CFG80211
        select USB_USBNET
        select USB_NET_CDCETHER
        select USB_NET_RNDIS_HOST
@@ -434,6 +435,13 @@ config RTL8187
 
          Thanks to Realtek for their support!
 
+# If possible, automatically enable LEDs for RTL8187.
+
+config RTL8187_LEDS
+       bool
+       depends on RTL8187 && MAC80211_LEDS && (LEDS_CLASS = y || LEDS_CLASS = RTL8187)
+       default y
+
 config ADM8211
        tristate "ADMtek ADM8211 support"
        depends on MAC80211 && PCI && WLAN_80211 && EXPERIMENTAL
@@ -484,9 +492,7 @@ config MWL8K
          will be called mwl8k.  If unsure, say N.
 
 source "drivers/net/wireless/p54/Kconfig"
-source "drivers/net/wireless/ath5k/Kconfig"
-source "drivers/net/wireless/ath9k/Kconfig"
-source "drivers/net/wireless/ar9170/Kconfig"
+source "drivers/net/wireless/ath/Kconfig"
 source "drivers/net/wireless/ipw2x00/Kconfig"
 source "drivers/net/wireless/iwlwifi/Kconfig"
 source "drivers/net/wireless/hostap/Kconfig"
@@ -495,5 +501,7 @@ source "drivers/net/wireless/b43legacy/Kconfig"
 source "drivers/net/wireless/zd1211rw/Kconfig"
 source "drivers/net/wireless/rt2x00/Kconfig"
 source "drivers/net/wireless/orinoco/Kconfig"
+source "drivers/net/wireless/wl12xx/Kconfig"
+source "drivers/net/wireless/iwmc3200wifi/Kconfig"
 
 endmenu
index 50e7fba7f0ea95b1922a6bcf3938420295d83ad7..7a4647e78fd39c5c1d4bcd5afa8bf433d3649e5f 100644 (file)
@@ -55,8 +55,10 @@ obj-$(CONFIG_RT2X00) += rt2x00/
 
 obj-$(CONFIG_P54_COMMON)       += p54/
 
-obj-$(CONFIG_ATH5K)    += ath5k/
-obj-$(CONFIG_ATH9K)    += ath9k/
-obj-$(CONFIG_AR9170_USB)       += ar9170/
+obj-$(CONFIG_ATH_COMMON)       += ath/
 
 obj-$(CONFIG_MAC80211_HWSIM)   += mac80211_hwsim.o
+
+obj-$(CONFIG_WL12XX)   += wl12xx/
+
+obj-$(CONFIG_IWM)      += iwmc3200wifi/
index f7182179501800e31e23ba4f3db5562d87a843bc..2b9e379994a180294690d0f06735f864a27e045f 100644 (file)
@@ -1311,18 +1311,20 @@ static int adm8211_config(struct ieee80211_hw *dev, u32 changed)
        return 0;
 }
 
-static int adm8211_config_interface(struct ieee80211_hw *dev,
-                                   struct ieee80211_vif *vif,
-                                   struct ieee80211_if_conf *conf)
+static void adm8211_bss_info_changed(struct ieee80211_hw *dev,
+                                    struct ieee80211_vif *vif,
+                                    struct ieee80211_bss_conf *conf,
+                                    u32 changes)
 {
        struct adm8211_priv *priv = dev->priv;
 
+       if (!(changes & BSS_CHANGED_BSSID))
+               return;
+
        if (memcmp(conf->bssid, priv->bssid, ETH_ALEN)) {
                adm8211_set_bssid(dev, conf->bssid);
                memcpy(priv->bssid, conf->bssid, ETH_ALEN);
        }
-
-       return 0;
 }
 
 static void adm8211_configure_filter(struct ieee80211_hw *dev,
@@ -1753,7 +1755,7 @@ static const struct ieee80211_ops adm8211_ops = {
        .add_interface          = adm8211_add_interface,
        .remove_interface       = adm8211_remove_interface,
        .config                 = adm8211_config,
-       .config_interface       = adm8211_config_interface,
+       .bss_info_changed       = adm8211_bss_info_changed,
        .configure_filter       = adm8211_configure_filter,
        .get_stats              = adm8211_get_stats,
        .get_tx_stats           = adm8211_get_tx_stats,
index 9eabf4d1f2e7cd021f5041576776aeb1a658a905..c70604f0329edf19e8577d1c4342e5655f020b69 100644 (file)
@@ -1935,7 +1935,7 @@ static int mpi_start_xmit(struct sk_buff *skb, struct net_device *dev) {
                netif_stop_queue (dev);
                if (npacks > MAXTXQ) {
                        dev->stats.tx_fifo_errors++;
-                       return 1;
+                       return NETDEV_TX_BUSY;
                }
                skb_queue_tail (&ai->txq, skb);
                return 0;
@@ -2139,7 +2139,7 @@ static int airo_start_xmit(struct sk_buff *skb, struct net_device *dev) {
 
                if (i == MAX_FIDS / 2) {
                        dev->stats.tx_fifo_errors++;
-                       return 1;
+                       return NETDEV_TX_BUSY;
                }
        }
        /* check min length*/
@@ -2193,7 +2193,8 @@ static int airo_start_xmit11(struct sk_buff *skb, struct net_device *dev) {
        if (test_bit(FLAG_MPI, &priv->flags)) {
                /* Not implemented yet for MPI350 */
                netif_stop_queue(dev);
-               return -ENETDOWN;
+               dev_kfree_skb_any(skb);
+               return NETDEV_TX_OK;
        }
 
        if ( skb == NULL ) {
@@ -2210,7 +2211,7 @@ static int airo_start_xmit11(struct sk_buff *skb, struct net_device *dev) {
 
                if (i == MAX_FIDS) {
                        dev->stats.tx_fifo_errors++;
-                       return 1;
+                       return NETDEV_TX_BUSY;
                }
        }
        /* check min length*/
diff --git a/drivers/net/wireless/ar9170/Kconfig b/drivers/net/wireless/ar9170/Kconfig
deleted file mode 100644 (file)
index de4281f..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-config AR9170_USB
-       tristate "Atheros AR9170 802.11n USB support"
-       depends on USB && MAC80211 && WLAN_80211 && EXPERIMENTAL
-       select FW_LOADER
-       help
-         This is a driver for the Atheros "otus" 802.11n USB devices.
-
-         These devices require additional firmware (2 files).
-         For now, these files can be downloaded from here:
-         http://wireless.kernel.org/en/users/Drivers/ar9170
-
-         If you choose to build a module, it'll be called ar9170usb.
-
-config AR9170_LEDS
-       bool
-       depends on AR9170_USB && MAC80211_LEDS && (LEDS_CLASS = y || LEDS_CLASS = AR9170_USB)
-       default y
diff --git a/drivers/net/wireless/ar9170/Makefile b/drivers/net/wireless/ar9170/Makefile
deleted file mode 100644 (file)
index 8d91c7e..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-ar9170usb-objs := usb.o main.o cmd.o mac.o phy.o led.o
-
-obj-$(CONFIG_AR9170_USB) += ar9170usb.o
diff --git a/drivers/net/wireless/ar9170/ar9170.h b/drivers/net/wireless/ar9170/ar9170.h
deleted file mode 100644 (file)
index f4fb2e9..0000000
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * Atheros AR9170 driver
- *
- * Driver specific definitions
- *
- * Copyright 2008, 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 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; see the file COPYING.  If not, see
- * http://www.gnu.org/licenses/.
- *
- * This file incorporates work covered by the following copyright and
- * permission notice:
- *    Copyright (c) 2007-2008 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 __AR9170_H
-#define __AR9170_H
-
-#include <linux/completion.h>
-#include <linux/spinlock.h>
-#include <net/wireless.h>
-#include <net/mac80211.h>
-#ifdef CONFIG_AR9170_LEDS
-#include <linux/leds.h>
-#endif /* CONFIG_AR9170_LEDS */
-#include "eeprom.h"
-#include "hw.h"
-
-#define PAYLOAD_MAX    (AR9170_MAX_CMD_LEN/4 - 1)
-
-enum ar9170_bw {
-       AR9170_BW_20,
-       AR9170_BW_40_BELOW,
-       AR9170_BW_40_ABOVE,
-
-       __AR9170_NUM_BW,
-};
-
-enum ar9170_rf_init_mode {
-       AR9170_RFI_NONE,
-       AR9170_RFI_WARM,
-       AR9170_RFI_COLD,
-};
-
-#define AR9170_MAX_RX_BUFFER_SIZE              8192
-
-#ifdef CONFIG_AR9170_LEDS
-struct ar9170;
-
-struct ar9170_led {
-       struct ar9170 *ar;
-       struct led_classdev l;
-       char name[32];
-       unsigned int toggled;
-       bool registered;
-};
-
-#endif /* CONFIG_AR9170_LEDS */
-
-enum ar9170_device_state {
-       AR9170_UNKNOWN_STATE,
-       AR9170_STOPPED,
-       AR9170_IDLE,
-       AR9170_STARTED,
-       AR9170_ASSOCIATED,
-};
-
-struct ar9170 {
-       struct ieee80211_hw *hw;
-       struct mutex mutex;
-       enum ar9170_device_state state;
-
-       int (*open)(struct ar9170 *);
-       void (*stop)(struct ar9170 *);
-       int (*tx)(struct ar9170 *, struct sk_buff *, bool, unsigned int);
-       int (*exec_cmd)(struct ar9170 *, enum ar9170_cmd, u32 ,
-                       void *, u32 , void *);
-       void (*callback_cmd)(struct ar9170 *, u32 , void *);
-
-       /* interface mode settings */
-       struct ieee80211_vif *vif;
-       u8 mac_addr[ETH_ALEN];
-       u8 bssid[ETH_ALEN];
-
-       /* beaconing */
-       struct sk_buff *beacon;
-       struct work_struct beacon_work;
-
-       /* cryptographic engine */
-       u64 usedkeys;
-       bool rx_software_decryption;
-       bool disable_offload;
-
-       /* filter settings */
-       struct work_struct filter_config_work;
-       u64 cur_mc_hash, want_mc_hash;
-       u32 cur_filter, want_filter;
-       unsigned int filter_changed;
-       bool sniffer_enabled;
-
-       /* PHY */
-       struct ieee80211_channel *channel;
-       int noise[4];
-
-       /* power calibration data */
-       u8 power_5G_leg[4];
-       u8 power_2G_cck[4];
-       u8 power_2G_ofdm[4];
-       u8 power_5G_ht20[8];
-       u8 power_5G_ht40[8];
-       u8 power_2G_ht20[8];
-       u8 power_2G_ht40[8];
-
-#ifdef CONFIG_AR9170_LEDS
-       struct delayed_work led_work;
-       struct ar9170_led leds[AR9170_NUM_LEDS];
-#endif /* CONFIG_AR9170_LEDS */
-
-       /* qos queue settings */
-       spinlock_t tx_stats_lock;
-       struct ieee80211_tx_queue_stats tx_stats[5];
-       struct ieee80211_tx_queue_params edcf[5];
-
-       spinlock_t cmdlock;
-       __le32 cmdbuf[PAYLOAD_MAX + 1];
-
-       /* MAC statistics */
-       struct ieee80211_low_level_stats stats;
-
-       /* EEPROM */
-       struct ar9170_eeprom eeprom;
-
-       /* global tx status for unregistered Stations. */
-       struct sk_buff_head global_tx_status;
-       struct sk_buff_head global_tx_status_waste;
-       struct delayed_work tx_status_janitor;
-};
-
-struct ar9170_sta_info {
-       struct sk_buff_head tx_status[__AR9170_NUM_TXQ];
-};
-
-#define IS_STARTED(a)          (a->state >= AR9170_STARTED)
-#define IS_ACCEPTING_CMD(a)    (a->state >= AR9170_IDLE)
-
-#define AR9170_FILTER_CHANGED_PROMISC          BIT(0)
-#define AR9170_FILTER_CHANGED_MULTICAST                BIT(1)
-#define AR9170_FILTER_CHANGED_FRAMEFILTER      BIT(2)
-
-/* exported interface */
-void *ar9170_alloc(size_t priv_size);
-int ar9170_register(struct ar9170 *ar, struct device *pdev);
-void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb);
-void ar9170_unregister(struct ar9170 *ar);
-void ar9170_handle_tx_status(struct ar9170 *ar, struct sk_buff *skb,
-                            bool update_statistics, u16 tx_status);
-
-/* MAC */
-int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
-int ar9170_init_mac(struct ar9170 *ar);
-int ar9170_set_qos(struct ar9170 *ar);
-int ar9170_update_multicast(struct ar9170 *ar);
-int ar9170_update_frame_filter(struct ar9170 *ar);
-int ar9170_set_operating_mode(struct ar9170 *ar);
-int ar9170_set_beacon_timers(struct ar9170 *ar);
-int ar9170_set_hwretry_limit(struct ar9170 *ar, u32 max_retry);
-int ar9170_update_beacon(struct ar9170 *ar);
-void ar9170_new_beacon(struct work_struct *work);
-int ar9170_upload_key(struct ar9170 *ar, u8 id, const u8 *mac, u8 ktype,
-                     u8 keyidx, u8 *keydata, int keylen);
-int ar9170_disable_key(struct ar9170 *ar, u8 id);
-
-/* LEDs */
-#ifdef CONFIG_AR9170_LEDS
-int ar9170_register_leds(struct ar9170 *ar);
-void ar9170_unregister_leds(struct ar9170 *ar);
-#endif /* CONFIG_AR9170_LEDS */
-int ar9170_init_leds(struct ar9170 *ar);
-int ar9170_set_leds_state(struct ar9170 *ar, u32 led_state);
-
-/* PHY / RF */
-int ar9170_init_phy(struct ar9170 *ar, enum ieee80211_band band);
-int ar9170_init_rf(struct ar9170 *ar);
-int ar9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
-                      enum ar9170_rf_init_mode rfi, enum ar9170_bw bw);
-
-#endif /* __AR9170_H */
diff --git a/drivers/net/wireless/ar9170/cmd.c b/drivers/net/wireless/ar9170/cmd.c
deleted file mode 100644 (file)
index f57a620..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Atheros AR9170 driver
- *
- * Basic HW register/memory/command access functions
- *
- * Copyright 2008, 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 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; see the file COPYING.  If not, see
- * http://www.gnu.org/licenses/.
- *
- * This file incorporates work covered by the following copyright and
- * permission notice:
- *    Copyright (c) 2007-2008 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 "ar9170.h"
-#include "cmd.h"
-
-int ar9170_write_mem(struct ar9170 *ar, const __le32 *data, size_t len)
-{
-       int err;
-
-       if (unlikely(!IS_ACCEPTING_CMD(ar)))
-               return 0;
-
-       err = ar->exec_cmd(ar, AR9170_CMD_WMEM, len, (u8 *) data, 0, NULL);
-       if (err)
-               printk(KERN_DEBUG "%s: writing memory failed\n",
-                      wiphy_name(ar->hw->wiphy));
-       return err;
-}
-
-int ar9170_write_reg(struct ar9170 *ar, const u32 reg, const u32 val)
-{
-       __le32 buf[2] = {
-               cpu_to_le32(reg),
-               cpu_to_le32(val),
-       };
-       int err;
-
-       if (unlikely(!IS_ACCEPTING_CMD(ar)))
-               return 0;
-
-       err = ar->exec_cmd(ar, AR9170_CMD_WREG, sizeof(buf),
-                          (u8 *) buf, 0, NULL);
-       if (err)
-               printk(KERN_DEBUG "%s: writing reg %#x (val %#x) failed\n",
-                      wiphy_name(ar->hw->wiphy), reg, val);
-       return err;
-}
-
-static int ar9170_read_mreg(struct ar9170 *ar, int nregs,
-                           const u32 *regs, u32 *out)
-{
-       int i, err;
-       __le32 *offs, *res;
-
-       if (unlikely(!IS_ACCEPTING_CMD(ar)))
-               return 0;
-
-       /* abuse "out" for the register offsets, must be same length */
-       offs = (__le32 *)out;
-       for (i = 0; i < nregs; i++)
-               offs[i] = cpu_to_le32(regs[i]);
-
-       /* also use the same buffer for the input */
-       res = (__le32 *)out;
-
-       err = ar->exec_cmd(ar, AR9170_CMD_RREG,
-                          4 * nregs, (u8 *)offs,
-                          4 * nregs, (u8 *)res);
-       if (err)
-               return err;
-
-       /* convert result to cpu endian */
-       for (i = 0; i < nregs; i++)
-               out[i] = le32_to_cpu(res[i]);
-
-       return 0;
-}
-
-int ar9170_read_reg(struct ar9170 *ar, u32 reg, u32 *val)
-{
-       return ar9170_read_mreg(ar, 1, &reg, val);
-}
-
-int ar9170_echo_test(struct ar9170 *ar, u32 v)
-{
-       __le32 echobuf = cpu_to_le32(v);
-       __le32 echores;
-       int err;
-
-       if (unlikely(!IS_ACCEPTING_CMD(ar)))
-               return -ENODEV;
-
-       err = ar->exec_cmd(ar, AR9170_CMD_ECHO,
-                          4, (u8 *)&echobuf,
-                          4, (u8 *)&echores);
-       if (err)
-               return err;
-
-       if (echobuf != echores)
-               return -EINVAL;
-
-       return 0;
-}
diff --git a/drivers/net/wireless/ar9170/cmd.h b/drivers/net/wireless/ar9170/cmd.h
deleted file mode 100644 (file)
index a4f0e50..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Atheros AR9170 driver
- *
- * Basic HW register/memory/command access functions
- *
- * Copyright 2008, 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 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; see the file COPYING.  If not, see
- * http://www.gnu.org/licenses/.
- *
- * This file incorporates work covered by the following copyright and
- * permission notice:
- *    Copyright (c) 2007-2008 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 __CMD_H
-#define __CMD_H
-
-#include "ar9170.h"
-
-/* basic HW access */
-int ar9170_write_mem(struct ar9170 *ar, const __le32 *data, size_t len);
-int ar9170_write_reg(struct ar9170 *ar, const u32 reg, const u32 val);
-int ar9170_read_reg(struct ar9170 *ar, u32 reg, u32 *val);
-int ar9170_echo_test(struct ar9170 *ar, u32 v);
-
-/*
- * Macros to facilitate writing multiple registers in a single
- * write-combining USB command. Note that when the first group
- * fails the whole thing will fail without any others attempted,
- * but you won't know which write in the group failed.
- */
-#define ar9170_regwrite_begin(ar)                                      \
-do {                                                                   \
-       int __nreg = 0, __err = 0;                                      \
-       struct ar9170 *__ar = ar;
-
-#define ar9170_regwrite(r, v) do {                                     \
-       __ar->cmdbuf[2 * __nreg + 1] = cpu_to_le32(r);                  \
-       __ar->cmdbuf[2 * __nreg + 2] = cpu_to_le32(v);                  \
-       __nreg++;                                                       \
-       if ((__nreg >= PAYLOAD_MAX/2)) {                                \
-               if (IS_ACCEPTING_CMD(__ar))                             \
-                       __err = ar->exec_cmd(__ar, AR9170_CMD_WREG,     \
-                                            8 * __nreg,                \
-                                            (u8 *) &__ar->cmdbuf[1],   \
-                                            0, NULL);                  \
-               __nreg = 0;                                             \
-               if (__err)                                              \
-                       goto __regwrite_out;                            \
-       }                                                               \
-} while (0)
-
-#define ar9170_regwrite_finish()                                       \
-__regwrite_out :                                                       \
-       if (__nreg) {                                                   \
-               if (IS_ACCEPTING_CMD(__ar))                             \
-                       __err = ar->exec_cmd(__ar, AR9170_CMD_WREG,     \
-                                            8 * __nreg,                \
-                                            (u8 *) &__ar->cmdbuf[1],   \
-                                            0, NULL);                  \
-               __nreg = 0;                                             \
-       }
-
-#define ar9170_regwrite_result()                                       \
-       __err;                                                          \
-} while (0);
-
-#endif /* __CMD_H */
diff --git a/drivers/net/wireless/ar9170/eeprom.h b/drivers/net/wireless/ar9170/eeprom.h
deleted file mode 100644 (file)
index d2c8cc8..0000000
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Atheros AR9170 driver
- *
- * EEPROM layout
- *
- * Copyright 2008, 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 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; see the file COPYING.  If not, see
- * http://www.gnu.org/licenses/.
- *
- * This file incorporates work covered by the following copyright and
- * permission notice:
- *    Copyright (c) 2007-2008 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 __AR9170_EEPROM_H
-#define __AR9170_EEPROM_H
-
-#define AR5416_MAX_CHAINS              2
-#define AR5416_MODAL_SPURS             5
-
-struct ar9170_eeprom_modal {
-       __le32  antCtrlChain[AR5416_MAX_CHAINS];
-       __le32  antCtrlCommon;
-       s8      antennaGainCh[AR5416_MAX_CHAINS];
-       u8      switchSettling;
-       u8      txRxAttenCh[AR5416_MAX_CHAINS];
-       u8      rxTxMarginCh[AR5416_MAX_CHAINS];
-       s8      adcDesiredSize;
-       s8      pgaDesiredSize;
-       u8      xlnaGainCh[AR5416_MAX_CHAINS];
-       u8      txEndToXpaOff;
-       u8      txEndToRxOn;
-       u8      txFrameToXpaOn;
-       u8      thresh62;
-       s8      noiseFloorThreshCh[AR5416_MAX_CHAINS];
-       u8      xpdGain;
-       u8      xpd;
-       s8      iqCalICh[AR5416_MAX_CHAINS];
-       s8      iqCalQCh[AR5416_MAX_CHAINS];
-       u8      pdGainOverlap;
-       u8      ob;
-       u8      db;
-       u8      xpaBiasLvl;
-       u8      pwrDecreaseFor2Chain;
-       u8      pwrDecreaseFor3Chain;
-       u8      txFrameToDataStart;
-       u8      txFrameToPaOn;
-       u8      ht40PowerIncForPdadc;
-       u8      bswAtten[AR5416_MAX_CHAINS];
-       u8      bswMargin[AR5416_MAX_CHAINS];
-       u8      swSettleHt40;
-       u8      reserved[22];
-       struct spur_channel {
-               __le16 spurChan;
-               u8      spurRangeLow;
-               u8      spurRangeHigh;
-       } __packed spur_channels[AR5416_MODAL_SPURS];
-} __packed;
-
-#define AR5416_NUM_PD_GAINS            4
-#define AR5416_PD_GAIN_ICEPTS          5
-
-struct ar9170_calibration_data_per_freq {
-       u8      pwr_pdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
-       u8      vpd_pdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
-} __packed;
-
-#define AR5416_NUM_5G_CAL_PIERS                8
-#define AR5416_NUM_2G_CAL_PIERS                4
-
-#define AR5416_NUM_5G_TARGET_PWRS      8
-#define AR5416_NUM_2G_CCK_TARGET_PWRS  3
-#define AR5416_NUM_2G_OFDM_TARGET_PWRS 4
-#define AR5416_MAX_NUM_TGT_PWRS                8
-
-struct ar9170_calibration_target_power_legacy {
-       u8      freq;
-       u8      power[4];
-} __packed;
-
-struct ar9170_calibration_target_power_ht {
-       u8      freq;
-       u8      power[8];
-} __packed;
-
-#define AR5416_NUM_CTLS                        24
-
-struct ar9170_calctl_edges {
-       u8      channel;
-#define AR9170_CALCTL_EDGE_FLAGS       0xC0
-       u8      power_flags;
-} __packed;
-
-#define AR5416_NUM_BAND_EDGES          8
-
-struct ar9170_calctl_data {
-       struct ar9170_calctl_edges
-               control_edges[AR5416_MAX_CHAINS][AR5416_NUM_BAND_EDGES];
-} __packed;
-
-
-struct ar9170_eeprom {
-       __le16  length;
-       __le16  checksum;
-       __le16  version;
-       u8      operating_flags;
-#define AR9170_OPFLAG_5GHZ             1
-#define AR9170_OPFLAG_2GHZ             2
-       u8      misc;
-       __le16  reg_domain[2];
-       u8      mac_address[6];
-       u8      rx_mask;
-       u8      tx_mask;
-       __le16  rf_silent;
-       __le16  bluetooth_options;
-       __le16  device_capabilities;
-       __le32  build_number;
-       u8      deviceType;
-       u8      reserved[33];
-
-       u8      customer_data[64];
-
-       struct ar9170_eeprom_modal
-               modal_header[2];
-
-       u8      cal_freq_pier_5G[AR5416_NUM_5G_CAL_PIERS];
-       u8      cal_freq_pier_2G[AR5416_NUM_2G_CAL_PIERS];
-
-       struct ar9170_calibration_data_per_freq
-               cal_pier_data_5G[AR5416_MAX_CHAINS][AR5416_NUM_5G_CAL_PIERS],
-               cal_pier_data_2G[AR5416_MAX_CHAINS][AR5416_NUM_2G_CAL_PIERS];
-
-       /* power calibration data */
-       struct ar9170_calibration_target_power_legacy
-               cal_tgt_pwr_5G[AR5416_NUM_5G_TARGET_PWRS];
-       struct ar9170_calibration_target_power_ht
-               cal_tgt_pwr_5G_ht20[AR5416_NUM_5G_TARGET_PWRS],
-               cal_tgt_pwr_5G_ht40[AR5416_NUM_5G_TARGET_PWRS];
-
-       struct ar9170_calibration_target_power_legacy
-               cal_tgt_pwr_2G_cck[AR5416_NUM_2G_CCK_TARGET_PWRS],
-               cal_tgt_pwr_2G_ofdm[AR5416_NUM_2G_OFDM_TARGET_PWRS];
-       struct ar9170_calibration_target_power_ht
-               cal_tgt_pwr_2G_ht20[AR5416_NUM_2G_OFDM_TARGET_PWRS],
-               cal_tgt_pwr_2G_ht40[AR5416_NUM_2G_OFDM_TARGET_PWRS];
-
-       /* conformance testing limits */
-       u8      ctl_index[AR5416_NUM_CTLS];
-       struct ar9170_calctl_data
-               ctl_data[AR5416_NUM_CTLS];
-
-       u8      pad;
-       __le16  subsystem_id;
-} __packed;
-
-#endif /* __AR9170_EEPROM_H */
diff --git a/drivers/net/wireless/ar9170/hw.h b/drivers/net/wireless/ar9170/hw.h
deleted file mode 100644 (file)
index 53e250a..0000000
+++ /dev/null
@@ -1,417 +0,0 @@
-/*
- * Atheros AR9170 driver
- *
- * Hardware-specific definitions
- *
- * Copyright 2008, 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 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; see the file COPYING.  If not, see
- * http://www.gnu.org/licenses/.
- *
- * This file incorporates work covered by the following copyright and
- * permission notice:
- *    Copyright (c) 2007-2008 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 __AR9170_HW_H
-#define __AR9170_HW_H
-
-#define AR9170_MAX_CMD_LEN     64
-
-enum ar9170_cmd {
-       AR9170_CMD_RREG         = 0x00,
-       AR9170_CMD_WREG         = 0x01,
-       AR9170_CMD_RMEM         = 0x02,
-       AR9170_CMD_WMEM         = 0x03,
-       AR9170_CMD_BITAND       = 0x04,
-       AR9170_CMD_BITOR        = 0x05,
-       AR9170_CMD_EKEY         = 0x28,
-       AR9170_CMD_DKEY         = 0x29,
-       AR9170_CMD_FREQUENCY    = 0x30,
-       AR9170_CMD_RF_INIT      = 0x31,
-       AR9170_CMD_SYNTH        = 0x32,
-       AR9170_CMD_FREQ_START   = 0x33,
-       AR9170_CMD_ECHO         = 0x80,
-       AR9170_CMD_TALLY        = 0x81,
-       AR9170_CMD_TALLY_APD    = 0x82,
-       AR9170_CMD_CONFIG       = 0x83,
-       AR9170_CMD_RESET        = 0x90,
-       AR9170_CMD_DKRESET      = 0x91,
-       AR9170_CMD_DKTX_STATUS  = 0x92,
-       AR9170_CMD_FDC          = 0xA0,
-       AR9170_CMD_WREEPROM     = 0xB0,
-       AR9170_CMD_WFLASH       = 0xB0,
-       AR9170_CMD_FLASH_ERASE  = 0xB1,
-       AR9170_CMD_FLASH_PROG   = 0xB2,
-       AR9170_CMD_FLASH_CHKSUM = 0xB3,
-       AR9170_CMD_FLASH_READ   = 0xB4,
-       AR9170_CMD_FW_DL_INIT   = 0xB5,
-       AR9170_CMD_MEM_WREEPROM = 0xBB,
-};
-
-/* endpoints */
-#define AR9170_EP_TX                           1
-#define AR9170_EP_RX                           2
-#define AR9170_EP_IRQ                          3
-#define AR9170_EP_CMD                          4
-
-#define AR9170_EEPROM_START                    0x1600
-
-#define AR9170_GPIO_REG_BASE                   0x1d0100
-#define AR9170_GPIO_REG_PORT_TYPE              AR9170_GPIO_REG_BASE
-#define AR9170_GPIO_REG_DATA                   (AR9170_GPIO_REG_BASE + 4)
-#define AR9170_NUM_LEDS                                2
-
-
-#define AR9170_USB_REG_BASE                    0x1e1000
-#define AR9170_USB_REG_DMA_CTL                 (AR9170_USB_REG_BASE + 0x108)
-#define                AR9170_DMA_CTL_ENABLE_TO_DEVICE         0x1
-#define                AR9170_DMA_CTL_ENABLE_FROM_DEVICE       0x2
-#define                AR9170_DMA_CTL_HIGH_SPEED               0x4
-#define                AR9170_DMA_CTL_PACKET_MODE              0x8
-
-#define AR9170_USB_REG_MAX_AGG_UPLOAD          (AR9170_USB_REG_BASE + 0x110)
-#define AR9170_USB_REG_UPLOAD_TIME_CTL         (AR9170_USB_REG_BASE + 0x114)
-
-
-
-#define AR9170_MAC_REG_BASE                    0x1c3000
-
-#define AR9170_MAC_REG_TSF_L                   (AR9170_MAC_REG_BASE + 0x514)
-#define AR9170_MAC_REG_TSF_H                   (AR9170_MAC_REG_BASE + 0x518)
-
-#define AR9170_MAC_REG_ATIM_WINDOW             (AR9170_MAC_REG_BASE + 0x51C)
-#define AR9170_MAC_REG_BCN_PERIOD              (AR9170_MAC_REG_BASE + 0x520)
-#define AR9170_MAC_REG_PRETBTT                 (AR9170_MAC_REG_BASE + 0x524)
-
-#define AR9170_MAC_REG_MAC_ADDR_L              (AR9170_MAC_REG_BASE + 0x610)
-#define AR9170_MAC_REG_MAC_ADDR_H              (AR9170_MAC_REG_BASE + 0x614)
-#define AR9170_MAC_REG_BSSID_L                 (AR9170_MAC_REG_BASE + 0x618)
-#define AR9170_MAC_REG_BSSID_H                 (AR9170_MAC_REG_BASE + 0x61c)
-
-#define AR9170_MAC_REG_GROUP_HASH_TBL_L                (AR9170_MAC_REG_BASE + 0x624)
-#define AR9170_MAC_REG_GROUP_HASH_TBL_H                (AR9170_MAC_REG_BASE + 0x628)
-
-#define AR9170_MAC_REG_RX_TIMEOUT              (AR9170_MAC_REG_BASE + 0x62C)
-
-#define AR9170_MAC_REG_BASIC_RATE              (AR9170_MAC_REG_BASE + 0x630)
-#define AR9170_MAC_REG_MANDATORY_RATE          (AR9170_MAC_REG_BASE + 0x634)
-#define AR9170_MAC_REG_RTS_CTS_RATE            (AR9170_MAC_REG_BASE + 0x638)
-#define AR9170_MAC_REG_BACKOFF_PROTECT         (AR9170_MAC_REG_BASE + 0x63c)
-#define AR9170_MAC_REG_RX_THRESHOLD            (AR9170_MAC_REG_BASE + 0x640)
-#define AR9170_MAC_REG_RX_PE_DELAY             (AR9170_MAC_REG_BASE + 0x64C)
-
-#define AR9170_MAC_REG_DYNAMIC_SIFS_ACK                (AR9170_MAC_REG_BASE + 0x658)
-#define AR9170_MAC_REG_SNIFFER                 (AR9170_MAC_REG_BASE + 0x674)
-#define                AR9170_MAC_REG_SNIFFER_ENABLE_PROMISC   BIT(0)
-#define                AR9170_MAC_REG_SNIFFER_DEFAULTS         0x02000000
-#define AR9170_MAC_REG_ENCRYPTION              (AR9170_MAC_REG_BASE + 0x678)
-#define                AR9170_MAC_REG_ENCRYPTION_RX_SOFTWARE   BIT(3)
-#define                AR9170_MAC_REG_ENCRYPTION_DEFAULTS      0x70
-
-#define AR9170_MAC_REG_MISC_680                        (AR9170_MAC_REG_BASE + 0x680)
-#define AR9170_MAC_REG_TX_UNDERRUN             (AR9170_MAC_REG_BASE + 0x688)
-
-#define AR9170_MAC_REG_FRAMETYPE_FILTER                (AR9170_MAC_REG_BASE + 0x68c)
-#define                AR9170_MAC_REG_FTF_ASSOC_REQ            BIT(0)
-#define                AR9170_MAC_REG_FTF_ASSOC_RESP           BIT(1)
-#define                AR9170_MAC_REG_FTF_REASSOC_REQ          BIT(2)
-#define                AR9170_MAC_REG_FTF_REASSOC_RESP         BIT(3)
-#define                AR9170_MAC_REG_FTF_PRB_REQ              BIT(4)
-#define                AR9170_MAC_REG_FTF_PRB_RESP             BIT(5)
-#define                AR9170_MAC_REG_FTF_BIT6                 BIT(6)
-#define                AR9170_MAC_REG_FTF_BIT7                 BIT(7)
-#define                AR9170_MAC_REG_FTF_BEACON               BIT(8)
-#define                AR9170_MAC_REG_FTF_ATIM                 BIT(9)
-#define                AR9170_MAC_REG_FTF_DEASSOC              BIT(10)
-#define                AR9170_MAC_REG_FTF_AUTH                 BIT(11)
-#define                AR9170_MAC_REG_FTF_DEAUTH               BIT(12)
-#define                AR9170_MAC_REG_FTF_BIT13                BIT(13)
-#define                AR9170_MAC_REG_FTF_BIT14                BIT(14)
-#define                AR9170_MAC_REG_FTF_BIT15                BIT(15)
-#define                AR9170_MAC_REG_FTF_BAR                  BIT(24)
-#define                AR9170_MAC_REG_FTF_BIT25                BIT(25)
-#define                AR9170_MAC_REG_FTF_PSPOLL               BIT(26)
-#define                AR9170_MAC_REG_FTF_RTS                  BIT(27)
-#define                AR9170_MAC_REG_FTF_CTS                  BIT(28)
-#define                AR9170_MAC_REG_FTF_ACK                  BIT(29)
-#define                AR9170_MAC_REG_FTF_CFE                  BIT(30)
-#define                AR9170_MAC_REG_FTF_CFE_ACK              BIT(31)
-#define                AR9170_MAC_REG_FTF_DEFAULTS             0x0500ffff
-#define                AR9170_MAC_REG_FTF_MONITOR              0xfd00ffff
-
-#define AR9170_MAC_REG_RX_TOTAL                        (AR9170_MAC_REG_BASE + 0x6A0)
-#define AR9170_MAC_REG_RX_CRC32                        (AR9170_MAC_REG_BASE + 0x6A4)
-#define AR9170_MAC_REG_RX_CRC16                        (AR9170_MAC_REG_BASE + 0x6A8)
-#define AR9170_MAC_REG_RX_ERR_DECRYPTION_UNI   (AR9170_MAC_REG_BASE + 0x6AC)
-#define AR9170_MAC_REG_RX_OVERRUN              (AR9170_MAC_REG_BASE + 0x6B0)
-#define AR9170_MAC_REG_RX_ERR_DECRYPTION_MUL   (AR9170_MAC_REG_BASE + 0x6BC)
-#define AR9170_MAC_REG_TX_RETRY                        (AR9170_MAC_REG_BASE + 0x6CC)
-#define AR9170_MAC_REG_TX_TOTAL                        (AR9170_MAC_REG_BASE + 0x6F4)
-
-
-#define AR9170_MAC_REG_ACK_EXTENSION           (AR9170_MAC_REG_BASE + 0x690)
-#define AR9170_MAC_REG_EIFS_AND_SIFS           (AR9170_MAC_REG_BASE + 0x698)
-
-#define AR9170_MAC_REG_SLOT_TIME               (AR9170_MAC_REG_BASE + 0x6F0)
-
-#define AR9170_MAC_REG_POWERMANAGEMENT         (AR9170_MAC_REG_BASE + 0x700)
-#define                AR9170_MAC_REG_POWERMGT_IBSS            0xe0
-#define                AR9170_MAC_REG_POWERMGT_AP              0xa1
-#define                AR9170_MAC_REG_POWERMGT_STA             0x2
-#define                AR9170_MAC_REG_POWERMGT_AP_WDS          0x3
-#define                AR9170_MAC_REG_POWERMGT_DEFAULTS        (0xf << 24)
-
-#define AR9170_MAC_REG_ROLL_CALL_TBL_L         (AR9170_MAC_REG_BASE + 0x704)
-#define AR9170_MAC_REG_ROLL_CALL_TBL_H         (AR9170_MAC_REG_BASE + 0x708)
-
-#define AR9170_MAC_REG_AC0_CW                  (AR9170_MAC_REG_BASE + 0xB00)
-#define AR9170_MAC_REG_AC1_CW                  (AR9170_MAC_REG_BASE + 0xB04)
-#define AR9170_MAC_REG_AC2_CW                  (AR9170_MAC_REG_BASE + 0xB08)
-#define AR9170_MAC_REG_AC3_CW                  (AR9170_MAC_REG_BASE + 0xB0C)
-#define AR9170_MAC_REG_AC4_CW                  (AR9170_MAC_REG_BASE + 0xB10)
-#define AR9170_MAC_REG_AC1_AC0_AIFS            (AR9170_MAC_REG_BASE + 0xB14)
-#define AR9170_MAC_REG_AC3_AC2_AIFS            (AR9170_MAC_REG_BASE + 0xB18)
-
-#define AR9170_MAC_REG_RETRY_MAX               (AR9170_MAC_REG_BASE + 0xB28)
-
-#define AR9170_MAC_REG_FCS_SELECT              (AR9170_MAC_REG_BASE + 0xBB0)
-#define                AR9170_MAC_FCS_SWFCS            0x1
-#define                AR9170_MAC_FCS_FIFO_PROT        0x4
-
-
-#define AR9170_MAC_REG_TXOP_NOT_ENOUGH_IND     (AR9170_MAC_REG_BASE + 0xB30)
-
-#define AR9170_MAC_REG_AC1_AC0_TXOP            (AR9170_MAC_REG_BASE + 0xB44)
-#define AR9170_MAC_REG_AC3_AC2_TXOP            (AR9170_MAC_REG_BASE + 0xB48)
-
-#define AR9170_MAC_REG_ACK_TABLE               (AR9170_MAC_REG_BASE + 0xC00)
-#define AR9170_MAC_REG_AMPDU_RX_THRESH         (AR9170_MAC_REG_BASE + 0xC50)
-
-#define AR9170_MAC_REG_TXRX_MPI                        (AR9170_MAC_REG_BASE + 0xD7C)
-#define                AR9170_MAC_TXRX_MPI_TX_MPI_MASK 0x0000000f
-#define                AR9170_MAC_TXRX_MPI_TX_TO_MASK  0x0000fff0
-#define                AR9170_MAC_TXRX_MPI_RX_MPI_MASK 0x000f0000
-#define                AR9170_MAC_TXRX_MPI_RX_TO_MASK  0xfff00000
-
-#define AR9170_MAC_REG_BCN_ADDR                        (AR9170_MAC_REG_BASE + 0xD84)
-#define AR9170_MAC_REG_BCN_LENGTH              (AR9170_MAC_REG_BASE + 0xD88)
-#define AR9170_MAC_REG_BCN_PLCP                        (AR9170_MAC_REG_BASE + 0xD90)
-#define AR9170_MAC_REG_BCN_CTRL                        (AR9170_MAC_REG_BASE + 0xD94)
-#define AR9170_MAC_REG_BCN_HT1                 (AR9170_MAC_REG_BASE + 0xDA0)
-#define AR9170_MAC_REG_BCN_HT2                 (AR9170_MAC_REG_BASE + 0xDA4)
-
-
-#define AR9170_PWR_REG_BASE                    0x1D4000
-
-#define AR9170_PWR_REG_CLOCK_SEL               (AR9170_PWR_REG_BASE + 0x008)
-#define                AR9170_PWR_CLK_AHB_40MHZ        0
-#define                AR9170_PWR_CLK_AHB_20_22MHZ     1
-#define                AR9170_PWR_CLK_AHB_40_44MHZ     2
-#define                AR9170_PWR_CLK_AHB_80_88MHZ     3
-#define                AR9170_PWR_CLK_DAC_160_INV_DLY  0x70
-
-
-/* put beacon here in memory */
-#define AR9170_BEACON_BUFFER_ADDRESS           0x117900
-
-
-struct ar9170_tx_control {
-       __le16 length;
-       __le16 mac_control;
-       __le32 phy_control;
-       u8 frame_data[0];
-} __packed;
-
-/* these are either-or */
-#define AR9170_TX_MAC_PROT_RTS                 0x0001
-#define AR9170_TX_MAC_PROT_CTS                 0x0002
-
-#define AR9170_TX_MAC_NO_ACK                   0x0004
-/* if unset, MAC will only do SIFS space before frame */
-#define AR9170_TX_MAC_BACKOFF                  0x0008
-#define AR9170_TX_MAC_BURST                    0x0010
-#define AR9170_TX_MAC_AGGR                     0x0020
-
-/* encryption is a two-bit field */
-#define AR9170_TX_MAC_ENCR_NONE                        0x0000
-#define AR9170_TX_MAC_ENCR_RC4                 0x0040
-#define AR9170_TX_MAC_ENCR_CENC                        0x0080
-#define AR9170_TX_MAC_ENCR_AES                 0x00c0
-
-#define AR9170_TX_MAC_MMIC                     0x0100
-#define AR9170_TX_MAC_HW_DURATION              0x0200
-#define AR9170_TX_MAC_QOS_SHIFT                        10
-#define AR9170_TX_MAC_QOS_MASK                 (3 << AR9170_TX_MAC_QOS_SHIFT)
-#define AR9170_TX_MAC_AGGR_QOS_BIT1            0x0400
-#define AR9170_TX_MAC_AGGR_QOS_BIT2            0x0800
-#define AR9170_TX_MAC_DISABLE_TXOP             0x1000
-#define AR9170_TX_MAC_TXOP_RIFS                        0x2000
-#define AR9170_TX_MAC_IMM_AMPDU                        0x4000
-#define AR9170_TX_MAC_RATE_PROBE               0x8000
-
-/* either-or */
-#define AR9170_TX_PHY_MOD_CCK                  0x00000000
-#define AR9170_TX_PHY_MOD_OFDM                 0x00000001
-#define AR9170_TX_PHY_MOD_HT                   0x00000002
-
-/* depends on modulation */
-#define AR9170_TX_PHY_SHORT_PREAMBLE           0x00000004
-#define AR9170_TX_PHY_GREENFIELD               0x00000004
-
-#define AR9170_TX_PHY_BW_SHIFT                 3
-#define AR9170_TX_PHY_BW_MASK                  (3 << AR9170_TX_PHY_BW_SHIFT)
-#define AR9170_TX_PHY_BW_20MHZ                 0
-#define AR9170_TX_PHY_BW_40MHZ                 2
-#define AR9170_TX_PHY_BW_40MHZ_DUP             3
-
-#define AR9170_TX_PHY_TX_HEAVY_CLIP_SHIFT      6
-#define AR9170_TX_PHY_TX_HEAVY_CLIP_MASK       (7 << AR9170_TX_PHY_TX_HEAVY_CLIP_SHIFT)
-
-#define AR9170_TX_PHY_TX_PWR_SHIFT             9
-#define AR9170_TX_PHY_TX_PWR_MASK              (0x3f << AR9170_TX_PHY_TX_PWR_SHIFT)
-
-/* not part of the hw-spec */
-#define AR9170_TX_PHY_QOS_SHIFT                        25
-#define AR9170_TX_PHY_QOS_MASK                 (3 << AR9170_TX_PHY_QOS_SHIFT)
-
-#define AR9170_TX_PHY_TXCHAIN_SHIFT            15
-#define AR9170_TX_PHY_TXCHAIN_MASK             (7 << AR9170_TX_PHY_TXCHAIN_SHIFT)
-#define AR9170_TX_PHY_TXCHAIN_1                        1
-/* use for cck, ofdm 6/9/12/18/24 and HT if capable */
-#define AR9170_TX_PHY_TXCHAIN_2                        5
-
-#define AR9170_TX_PHY_MCS_SHIFT                        18
-#define AR9170_TX_PHY_MCS_MASK                 (0x7f << AR9170_TX_PHY_MCS_SHIFT)
-
-#define AR9170_TX_PHY_SHORT_GI                 0x80000000
-
-struct ar9170_rx_head {
-       u8 plcp[12];
-} __packed;
-
-struct ar9170_rx_tail {
-       union {
-               struct {
-                       u8 rssi_ant0, rssi_ant1, rssi_ant2,
-                          rssi_ant0x, rssi_ant1x, rssi_ant2x,
-                          rssi_combined;
-               } __packed;
-               u8 rssi[7];
-       } __packed;
-
-       u8 evm_stream0[6], evm_stream1[6];
-       u8 phy_err;
-       u8 SAidx, DAidx;
-       u8 error;
-       u8 status;
-} __packed;
-
-#define AR9170_ENC_ALG_NONE                    0x0
-#define AR9170_ENC_ALG_WEP64                   0x1
-#define AR9170_ENC_ALG_TKIP                    0x2
-#define AR9170_ENC_ALG_AESCCMP                 0x4
-#define AR9170_ENC_ALG_WEP128                  0x5
-#define AR9170_ENC_ALG_WEP256                  0x6
-#define AR9170_ENC_ALG_CENC                    0x7
-
-#define AR9170_RX_ENC_SOFTWARE                 0x8
-
-static inline u8 ar9170_get_decrypt_type(struct ar9170_rx_tail *t)
-{
-       return (t->SAidx & 0xc0) >> 4 |
-              (t->DAidx & 0xc0) >> 6;
-}
-
-#define AR9170_RX_STATUS_MODULATION_MASK       0x03
-#define AR9170_RX_STATUS_MODULATION_CCK                0x00
-#define AR9170_RX_STATUS_MODULATION_OFDM       0x01
-#define AR9170_RX_STATUS_MODULATION_HT         0x02
-#define AR9170_RX_STATUS_MODULATION_DUPOFDM    0x03
-
-/* depends on modulation */
-#define AR9170_RX_STATUS_SHORT_PREAMBLE                0x08
-#define AR9170_RX_STATUS_GREENFIELD            0x08
-
-#define AR9170_RX_STATUS_MPDU_MASK             0x30
-#define AR9170_RX_STATUS_MPDU_SINGLE           0x00
-#define AR9170_RX_STATUS_MPDU_FIRST            0x10
-#define AR9170_RX_STATUS_MPDU_MIDDLE           0x20
-#define AR9170_RX_STATUS_MPDU_LAST             0x30
-
-
-#define AR9170_RX_ERROR_RXTO                   0x01
-#define AR9170_RX_ERROR_OVERRUN                        0x02
-#define AR9170_RX_ERROR_DECRYPT                        0x04
-#define AR9170_RX_ERROR_FCS                    0x08
-#define AR9170_RX_ERROR_WRONG_RA               0x10
-#define AR9170_RX_ERROR_PLCP                   0x20
-#define AR9170_RX_ERROR_MMIC                   0x40
-
-struct ar9170_cmd_tx_status {
-       __le16 unkn;
-       u8 dst[ETH_ALEN];
-       __le32 rate;
-       __le16 status;
-} __packed;
-
-#define AR9170_TX_STATUS_COMPLETE              0x00
-#define AR9170_TX_STATUS_RETRY                 0x01
-#define AR9170_TX_STATUS_FAILED                        0x02
-
-struct ar9170_cmd_ba_failed_count {
-       __le16 failed;
-       __le16 rate;
-} __packed;
-
-struct ar9170_cmd_response {
-       u8 flag;
-       u8 type;
-
-       union {
-               struct ar9170_cmd_tx_status             tx_status;
-               struct ar9170_cmd_ba_failed_count       ba_fail_cnt;
-               u8 data[0];
-       };
-} __packed;
-
-/* QoS */
-
-/* mac80211 queue to HW/FW map */
-static const u8 ar9170_qos_hwmap[4] = { 3, 2, 0, 1 };
-
-/* HW/FW queue to mac80211 map */
-static const u8 ar9170_qos_mac80211map[4] = { 2, 3, 1, 0 };
-
-enum ar9170_txq {
-       AR9170_TXQ_BE,
-       AR9170_TXQ_BK,
-       AR9170_TXQ_VI,
-       AR9170_TXQ_VO,
-
-       __AR9170_NUM_TXQ,
-};
-
-#endif /* __AR9170_HW_H */
diff --git a/drivers/net/wireless/ar9170/led.c b/drivers/net/wireless/ar9170/led.c
deleted file mode 100644 (file)
index 341cead..0000000
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Atheros AR9170 driver
- *
- * LED handling
- *
- * Copyright 2008, 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 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; see the file COPYING.  If not, see
- * http://www.gnu.org/licenses/.
- *
- * This file incorporates work covered by the following copyright and
- * permission notice:
- *    Copyright (c) 2007-2008 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 "ar9170.h"
-#include "cmd.h"
-
-int ar9170_set_leds_state(struct ar9170 *ar, u32 led_state)
-{
-       return ar9170_write_reg(ar, AR9170_GPIO_REG_DATA, led_state);
-}
-
-int ar9170_init_leds(struct ar9170 *ar)
-{
-       int err;
-
-       /* disable LEDs */
-       /* GPIO [0/1 mode: output, 2/3: input] */
-       err = ar9170_write_reg(ar, AR9170_GPIO_REG_PORT_TYPE, 3);
-       if (err)
-               goto out;
-
-       /* GPIO 0/1 value: off */
-       err = ar9170_set_leds_state(ar, 0);
-
-out:
-       return err;
-}
-
-#ifdef CONFIG_AR9170_LEDS
-static void ar9170_update_leds(struct work_struct *work)
-{
-       struct ar9170 *ar = container_of(work, struct ar9170, led_work.work);
-       int i, tmp, blink_delay = 1000;
-       u32 led_val = 0;
-       bool rerun = false;
-
-       if (unlikely(!IS_ACCEPTING_CMD(ar)))
-               return ;
-
-       mutex_lock(&ar->mutex);
-       for (i = 0; i < AR9170_NUM_LEDS; i++)
-               if (ar->leds[i].toggled) {
-                       led_val |= 1 << i;
-
-                       tmp = 70 + 200 / (ar->leds[i].toggled);
-                       if (tmp < blink_delay)
-                               blink_delay = tmp;
-
-                       if (ar->leds[i].toggled > 1)
-                               ar->leds[i].toggled = 0;
-
-                       rerun = true;
-               }
-
-       ar9170_set_leds_state(ar, led_val);
-       mutex_unlock(&ar->mutex);
-
-       if (rerun)
-               queue_delayed_work(ar->hw->workqueue, &ar->led_work,
-                                  msecs_to_jiffies(blink_delay));
-}
-
-static void ar9170_led_brightness_set(struct led_classdev *led,
-                                     enum led_brightness brightness)
-{
-       struct ar9170_led *arl = container_of(led, struct ar9170_led, l);
-       struct ar9170 *ar = arl->ar;
-
-       arl->toggled++;
-
-       if (likely(IS_ACCEPTING_CMD(ar) && brightness))
-               queue_delayed_work(ar->hw->workqueue, &ar->led_work, HZ/10);
-}
-
-static int ar9170_register_led(struct ar9170 *ar, int i, char *name,
-                              char *trigger)
-{
-       int err;
-
-       snprintf(ar->leds[i].name, sizeof(ar->leds[i].name),
-                "ar9170-%s::%s", wiphy_name(ar->hw->wiphy), name);
-
-       ar->leds[i].ar = ar;
-       ar->leds[i].l.name = ar->leds[i].name;
-       ar->leds[i].l.brightness_set = ar9170_led_brightness_set;
-       ar->leds[i].l.brightness = 0;
-       ar->leds[i].l.default_trigger = trigger;
-
-       err = led_classdev_register(wiphy_dev(ar->hw->wiphy),
-                                   &ar->leds[i].l);
-       if (err)
-               printk(KERN_ERR "%s: failed to register %s LED (%d).\n",
-                      wiphy_name(ar->hw->wiphy), ar->leds[i].name, err);
-       else
-               ar->leds[i].registered = true;
-
-       return err;
-}
-
-void ar9170_unregister_leds(struct ar9170 *ar)
-{
-       int i;
-
-       cancel_delayed_work_sync(&ar->led_work);
-
-       for (i = 0; i < AR9170_NUM_LEDS; i++)
-               if (ar->leds[i].registered) {
-                       led_classdev_unregister(&ar->leds[i].l);
-                       ar->leds[i].registered = false;
-               }
-}
-
-int ar9170_register_leds(struct ar9170 *ar)
-{
-       int err;
-
-       INIT_DELAYED_WORK(&ar->led_work, ar9170_update_leds);
-
-       err = ar9170_register_led(ar, 0, "tx",
-                                 ieee80211_get_tx_led_name(ar->hw));
-       if (err)
-               goto fail;
-
-       err = ar9170_register_led(ar, 1, "assoc",
-                                ieee80211_get_assoc_led_name(ar->hw));
-       if (err)
-               goto fail;
-
-       return 0;
-
-fail:
-       ar9170_unregister_leds(ar);
-       return err;
-}
-
-#endif /* CONFIG_AR9170_LEDS */
diff --git a/drivers/net/wireless/ar9170/mac.c b/drivers/net/wireless/ar9170/mac.c
deleted file mode 100644 (file)
index c8fa307..0000000
+++ /dev/null
@@ -1,452 +0,0 @@
-/*
- * Atheros AR9170 driver
- *
- * MAC programming
- *
- * Copyright 2008, 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 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; see the file COPYING.  If not, see
- * http://www.gnu.org/licenses/.
- *
- * This file incorporates work covered by the following copyright and
- * permission notice:
- *    Copyright (c) 2007-2008 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 "ar9170.h"
-#include "cmd.h"
-
-int ar9170_set_qos(struct ar9170 *ar)
-{
-       ar9170_regwrite_begin(ar);
-
-       ar9170_regwrite(AR9170_MAC_REG_AC0_CW, ar->edcf[0].cw_min |
-                       (ar->edcf[0].cw_max << 16));
-       ar9170_regwrite(AR9170_MAC_REG_AC1_CW, ar->edcf[1].cw_min |
-                       (ar->edcf[1].cw_max << 16));
-       ar9170_regwrite(AR9170_MAC_REG_AC2_CW, ar->edcf[2].cw_min |
-                       (ar->edcf[2].cw_max << 16));
-       ar9170_regwrite(AR9170_MAC_REG_AC3_CW, ar->edcf[3].cw_min |
-                       (ar->edcf[3].cw_max << 16));
-       ar9170_regwrite(AR9170_MAC_REG_AC4_CW, ar->edcf[4].cw_min |
-                       (ar->edcf[4].cw_max << 16));
-
-       ar9170_regwrite(AR9170_MAC_REG_AC1_AC0_AIFS,
-                       ((ar->edcf[0].aifs * 9 + 10)) |
-                       ((ar->edcf[1].aifs * 9 + 10) << 12) |
-                       ((ar->edcf[2].aifs * 9 + 10) << 24));
-       ar9170_regwrite(AR9170_MAC_REG_AC3_AC2_AIFS,
-                       ((ar->edcf[2].aifs * 9 + 10) >> 8) |
-                       ((ar->edcf[3].aifs * 9 + 10) << 4) |
-                       ((ar->edcf[4].aifs * 9 + 10) << 16));
-
-       ar9170_regwrite(AR9170_MAC_REG_AC1_AC0_TXOP,
-                       ar->edcf[0].txop | ar->edcf[1].txop << 16);
-       ar9170_regwrite(AR9170_MAC_REG_AC3_AC2_TXOP,
-                       ar->edcf[1].txop | ar->edcf[3].txop << 16);
-
-       ar9170_regwrite_finish();
-
-       return ar9170_regwrite_result();
-}
-
-int ar9170_init_mac(struct ar9170 *ar)
-{
-       ar9170_regwrite_begin(ar);
-
-       ar9170_regwrite(AR9170_MAC_REG_ACK_EXTENSION, 0x40);
-
-       ar9170_regwrite(AR9170_MAC_REG_RETRY_MAX, 0);
-
-       /* enable MMIC */
-       ar9170_regwrite(AR9170_MAC_REG_SNIFFER,
-                       AR9170_MAC_REG_SNIFFER_DEFAULTS);
-
-       ar9170_regwrite(AR9170_MAC_REG_RX_THRESHOLD, 0xc1f80);
-
-       ar9170_regwrite(AR9170_MAC_REG_RX_PE_DELAY, 0x70);
-       ar9170_regwrite(AR9170_MAC_REG_EIFS_AND_SIFS, 0xa144000);
-       ar9170_regwrite(AR9170_MAC_REG_SLOT_TIME, 9 << 10);
-
-       /* CF-END mode */
-       ar9170_regwrite(0x1c3b2c, 0x19000000);
-
-       /* NAV protects ACK only (in TXOP) */
-       ar9170_regwrite(0x1c3b38, 0x201);
-
-       /* Set Beacon PHY CTRL's TPC to 0x7, TA1=1 */
-       /* OTUS set AM to 0x1 */
-       ar9170_regwrite(AR9170_MAC_REG_BCN_HT1, 0x8000170);
-
-       ar9170_regwrite(AR9170_MAC_REG_BACKOFF_PROTECT, 0x105);
-
-       /* AGG test code*/
-       /* Aggregation MAX number and timeout */
-       ar9170_regwrite(0x1c3b9c, 0x10000a);
-
-       ar9170_regwrite(AR9170_MAC_REG_FRAMETYPE_FILTER,
-                       AR9170_MAC_REG_FTF_DEFAULTS);
-
-       /* Enable deaggregator, response in sniffer mode */
-       ar9170_regwrite(0x1c3c40, 0x1 | 1<<30);
-
-       /* rate sets */
-       ar9170_regwrite(AR9170_MAC_REG_BASIC_RATE, 0x150f);
-       ar9170_regwrite(AR9170_MAC_REG_MANDATORY_RATE, 0x150f);
-       ar9170_regwrite(AR9170_MAC_REG_RTS_CTS_RATE, 0x10b01bb);
-
-       /* MIMO response control */
-       ar9170_regwrite(0x1c3694, 0x4003C1E);/* bit 26~28  otus-AM */
-
-       /* switch MAC to OTUS interface */
-       ar9170_regwrite(0x1c3600, 0x3);
-
-       ar9170_regwrite(AR9170_MAC_REG_AMPDU_RX_THRESH, 0xffff);
-
-       /* set PHY register read timeout (??) */
-       ar9170_regwrite(AR9170_MAC_REG_MISC_680, 0xf00008);
-
-       /* Disable Rx TimeOut, workaround for BB. */
-       ar9170_regwrite(AR9170_MAC_REG_RX_TIMEOUT, 0x0);
-
-       /* Set CPU clock frequency to 88/80MHz */
-       ar9170_regwrite(AR9170_PWR_REG_CLOCK_SEL,
-                       AR9170_PWR_CLK_AHB_80_88MHZ |
-                       AR9170_PWR_CLK_DAC_160_INV_DLY);
-
-       /* Set WLAN DMA interrupt mode: generate int per packet */
-       ar9170_regwrite(AR9170_MAC_REG_TXRX_MPI, 0x110011);
-
-       ar9170_regwrite(AR9170_MAC_REG_FCS_SELECT,
-                       AR9170_MAC_FCS_FIFO_PROT);
-
-       /* Disables the CF_END frame, undocumented register */
-       ar9170_regwrite(AR9170_MAC_REG_TXOP_NOT_ENOUGH_IND,
-                       0x141E0F48);
-
-       ar9170_regwrite_finish();
-
-       return ar9170_regwrite_result();
-}
-
-static int ar9170_set_mac_reg(struct ar9170 *ar, const u32 reg, const u8 *mac)
-{
-       static const u8 zero[ETH_ALEN] = { 0 };
-
-       if (!mac)
-               mac = zero;
-
-       ar9170_regwrite_begin(ar);
-
-       ar9170_regwrite(reg,
-                       (mac[3] << 24) | (mac[2] << 16) |
-                       (mac[1] << 8) | mac[0]);
-
-       ar9170_regwrite(reg + 4, (mac[5] << 8) | mac[4]);
-
-       ar9170_regwrite_finish();
-
-       return ar9170_regwrite_result();
-}
-
-int ar9170_update_multicast(struct ar9170 *ar)
-{
-       int err;
-
-       ar9170_regwrite_begin(ar);
-       ar9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_H,
-               ar->want_mc_hash >> 32);
-       ar9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_L,
-               ar->want_mc_hash);
-
-       ar9170_regwrite_finish();
-       err = ar9170_regwrite_result();
-
-       if (err)
-               return err;
-
-       ar->cur_mc_hash = ar->want_mc_hash;
-
-       return 0;
-}
-
-int ar9170_update_frame_filter(struct ar9170 *ar)
-{
-       int err;
-
-       err = ar9170_write_reg(ar, AR9170_MAC_REG_FRAMETYPE_FILTER,
-                              ar->want_filter);
-
-       if (err)
-               return err;
-
-       ar->cur_filter = ar->want_filter;
-
-       return 0;
-}
-
-static int ar9170_set_promiscouous(struct ar9170 *ar)
-{
-       u32 encr_mode, sniffer;
-       int err;
-
-       err = ar9170_read_reg(ar, AR9170_MAC_REG_SNIFFER, &sniffer);
-       if (err)
-               return err;
-
-       err = ar9170_read_reg(ar, AR9170_MAC_REG_ENCRYPTION, &encr_mode);
-       if (err)
-               return err;
-
-       if (ar->sniffer_enabled) {
-               sniffer |= AR9170_MAC_REG_SNIFFER_ENABLE_PROMISC;
-
-               /*
-                * Rx decryption works in place.
-                *
-                * If we don't disable it, the hardware will render all
-                * encrypted frames which are encrypted with an unknown
-                * key useless.
-                */
-
-               encr_mode |= AR9170_MAC_REG_ENCRYPTION_RX_SOFTWARE;
-               ar->sniffer_enabled = true;
-       } else {
-               sniffer &= ~AR9170_MAC_REG_SNIFFER_ENABLE_PROMISC;
-
-               if (ar->rx_software_decryption)
-                       encr_mode |= AR9170_MAC_REG_ENCRYPTION_RX_SOFTWARE;
-               else
-                       encr_mode &= ~AR9170_MAC_REG_ENCRYPTION_RX_SOFTWARE;
-       }
-
-       ar9170_regwrite_begin(ar);
-       ar9170_regwrite(AR9170_MAC_REG_ENCRYPTION, encr_mode);
-       ar9170_regwrite(AR9170_MAC_REG_SNIFFER, sniffer);
-       ar9170_regwrite_finish();
-
-       return ar9170_regwrite_result();
-}
-
-int ar9170_set_operating_mode(struct ar9170 *ar)
-{
-       u32 pm_mode = AR9170_MAC_REG_POWERMGT_DEFAULTS;
-       u8 *mac_addr, *bssid;
-       int err;
-
-       if (ar->vif) {
-               mac_addr = ar->mac_addr;
-               bssid = ar->bssid;
-
-               switch (ar->vif->type) {
-               case NL80211_IFTYPE_MESH_POINT:
-               case NL80211_IFTYPE_ADHOC:
-                       pm_mode |= AR9170_MAC_REG_POWERMGT_IBSS;
-                       break;
-/*             case NL80211_IFTYPE_AP:
-                       pm_mode |= AR9170_MAC_REG_POWERMGT_AP;
-                       break;*/
-               case NL80211_IFTYPE_WDS:
-                       pm_mode |= AR9170_MAC_REG_POWERMGT_AP_WDS;
-                       break;
-               case NL80211_IFTYPE_MONITOR:
-                       ar->sniffer_enabled = true;
-                       ar->rx_software_decryption = true;
-                       break;
-               default:
-                       pm_mode |= AR9170_MAC_REG_POWERMGT_STA;
-                       break;
-               }
-       } else {
-               mac_addr = NULL;
-               bssid = NULL;
-       }
-
-       err = ar9170_set_mac_reg(ar, AR9170_MAC_REG_MAC_ADDR_L, mac_addr);
-       if (err)
-               return err;
-
-       err = ar9170_set_mac_reg(ar, AR9170_MAC_REG_BSSID_L, bssid);
-       if (err)
-               return err;
-
-       err = ar9170_set_promiscouous(ar);
-       if (err)
-               return err;
-
-       ar9170_regwrite_begin(ar);
-
-       ar9170_regwrite(AR9170_MAC_REG_POWERMANAGEMENT, pm_mode);
-       ar9170_regwrite_finish();
-
-       return ar9170_regwrite_result();
-}
-
-int ar9170_set_hwretry_limit(struct ar9170 *ar, unsigned int max_retry)
-{
-       u32 tmp = min_t(u32, 0x33333, max_retry * 0x11111);
-
-       return ar9170_write_reg(ar, AR9170_MAC_REG_RETRY_MAX, tmp);
-}
-
-int ar9170_set_beacon_timers(struct ar9170 *ar)
-{
-       u32 v = 0;
-       u32 pretbtt = 0;
-
-       v |= ar->hw->conf.beacon_int;
-
-       if (ar->vif) {
-               switch (ar->vif->type) {
-               case NL80211_IFTYPE_MESH_POINT:
-               case NL80211_IFTYPE_ADHOC:
-                       v |= BIT(25);
-                       break;
-               case NL80211_IFTYPE_AP:
-                       v |= BIT(24);
-                       pretbtt = (ar->hw->conf.beacon_int - 6) << 16;
-                       break;
-               default:
-                       break;
-               }
-
-               v |= ar->vif->bss_conf.dtim_period << 16;
-       }
-
-       ar9170_regwrite_begin(ar);
-
-       ar9170_regwrite(AR9170_MAC_REG_PRETBTT, pretbtt);
-       ar9170_regwrite(AR9170_MAC_REG_BCN_PERIOD, v);
-       ar9170_regwrite_finish();
-       return ar9170_regwrite_result();
-}
-
-int ar9170_update_beacon(struct ar9170 *ar)
-{
-       struct sk_buff *skb;
-       __le32 *data, *old = NULL;
-       u32 word;
-       int i;
-
-       skb = ieee80211_beacon_get(ar->hw, ar->vif);
-       if (!skb)
-               return -ENOMEM;
-
-       data = (__le32 *)skb->data;
-       if (ar->beacon)
-               old = (__le32 *)ar->beacon->data;
-
-       ar9170_regwrite_begin(ar);
-       for (i = 0; i < DIV_ROUND_UP(skb->len, 4); i++) {
-               /*
-                * XXX: This accesses beyond skb data for up
-                *      to the last 3 bytes!!
-                */
-
-               if (old && (data[i] == old[i]))
-                       continue;
-
-               word = le32_to_cpu(data[i]);
-               ar9170_regwrite(AR9170_BEACON_BUFFER_ADDRESS + 4 * i, word);
-       }
-
-       /* XXX: use skb->cb info */
-       if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ)
-               ar9170_regwrite(AR9170_MAC_REG_BCN_PLCP,
-                               ((skb->len + 4) << (3+16)) + 0x0400);
-       else
-               ar9170_regwrite(AR9170_MAC_REG_BCN_PLCP,
-                               ((skb->len + 4) << (3+16)) + 0x0400);
-
-       ar9170_regwrite(AR9170_MAC_REG_BCN_LENGTH, skb->len + 4);
-       ar9170_regwrite(AR9170_MAC_REG_BCN_ADDR, AR9170_BEACON_BUFFER_ADDRESS);
-       ar9170_regwrite(AR9170_MAC_REG_BCN_CTRL, 1);
-
-       ar9170_regwrite_finish();
-
-       dev_kfree_skb(ar->beacon);
-       ar->beacon = skb;
-
-       return ar9170_regwrite_result();
-}
-
-void ar9170_new_beacon(struct work_struct *work)
-{
-       struct ar9170 *ar = container_of(work, struct ar9170,
-                                        beacon_work);
-       struct sk_buff *skb;
-
-       if (unlikely(!IS_STARTED(ar)))
-               return ;
-
-       mutex_lock(&ar->mutex);
-
-       if (!ar->vif)
-               goto out;
-
-       ar9170_update_beacon(ar);
-
-       rcu_read_lock();
-       while ((skb = ieee80211_get_buffered_bc(ar->hw, ar->vif)))
-               ar9170_op_tx(ar->hw, skb);
-
-       rcu_read_unlock();
-
- out:
-       mutex_unlock(&ar->mutex);
-}
-
-int ar9170_upload_key(struct ar9170 *ar, u8 id, const u8 *mac, u8 ktype,
-                     u8 keyidx, u8 *keydata, int keylen)
-{
-       __le32 vals[7];
-       static const u8 bcast[ETH_ALEN] =
-               { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
-       u8 dummy;
-
-       mac = mac ? : bcast;
-
-       vals[0] = cpu_to_le32((keyidx << 16) + id);
-       vals[1] = cpu_to_le32(mac[1] << 24 | mac[0] << 16 | ktype);
-       vals[2] = cpu_to_le32(mac[5] << 24 | mac[4] << 16 |
-                             mac[3] << 8 | mac[2]);
-       memset(&vals[3], 0, 16);
-       if (keydata)
-               memcpy(&vals[3], keydata, keylen);
-
-       return ar->exec_cmd(ar, AR9170_CMD_EKEY,
-                           sizeof(vals), (u8 *)vals,
-                           1, &dummy);
-}
-
-int ar9170_disable_key(struct ar9170 *ar, u8 id)
-{
-       __le32 val = cpu_to_le32(id);
-       u8 dummy;
-
-       return ar->exec_cmd(ar, AR9170_CMD_EKEY,
-                           sizeof(val), (u8 *)&val,
-                           1, &dummy);
-}
diff --git a/drivers/net/wireless/ar9170/main.c b/drivers/net/wireless/ar9170/main.c
deleted file mode 100644 (file)
index 5996ff9..0000000
+++ /dev/null
@@ -1,1671 +0,0 @@
-/*
- * Atheros AR9170 driver
- *
- * mac80211 interaction code
- *
- * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
- * Copyright 2009, Christian Lamparter <chunkeey@web.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.
- *
- * 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; see the file COPYING.  If not, see
- * http://www.gnu.org/licenses/.
- *
- * This file incorporates work covered by the following copyright and
- * permission notice:
- *    Copyright (c) 2007-2008 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/init.h>
-#include <linux/module.h>
-#include <linux/etherdevice.h>
-#include <net/mac80211.h>
-#include "ar9170.h"
-#include "hw.h"
-#include "cmd.h"
-
-static int modparam_nohwcrypt;
-module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
-MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
-
-#define RATE(_bitrate, _hw_rate, _txpidx, _flags) {    \
-       .bitrate        = (_bitrate),                   \
-       .flags          = (_flags),                     \
-       .hw_value       = (_hw_rate) | (_txpidx) << 4,  \
-}
-
-static struct ieee80211_rate __ar9170_ratetable[] = {
-       RATE(10, 0, 0, 0),
-       RATE(20, 1, 1, IEEE80211_RATE_SHORT_PREAMBLE),
-       RATE(55, 2, 2, IEEE80211_RATE_SHORT_PREAMBLE),
-       RATE(110, 3, 3, IEEE80211_RATE_SHORT_PREAMBLE),
-       RATE(60, 0xb, 0, 0),
-       RATE(90, 0xf, 0, 0),
-       RATE(120, 0xa, 0, 0),
-       RATE(180, 0xe, 0, 0),
-       RATE(240, 0x9, 0, 0),
-       RATE(360, 0xd, 1, 0),
-       RATE(480, 0x8, 2, 0),
-       RATE(540, 0xc, 3, 0),
-};
-#undef RATE
-
-#define ar9170_g_ratetable     (__ar9170_ratetable + 0)
-#define ar9170_g_ratetable_size        12
-#define ar9170_a_ratetable     (__ar9170_ratetable + 4)
-#define ar9170_a_ratetable_size        8
-
-/*
- * NB: The hw_value is used as an index into the ar9170_phy_freq_params
- *     array in phy.c so that we don't have to do frequency lookups!
- */
-#define CHAN(_freq, _idx) {            \
-       .center_freq    = (_freq),      \
-       .hw_value       = (_idx),       \
-       .max_power      = 18, /* XXX */ \
-}
-
-static struct ieee80211_channel ar9170_2ghz_chantable[] = {
-       CHAN(2412,  0),
-       CHAN(2417,  1),
-       CHAN(2422,  2),
-       CHAN(2427,  3),
-       CHAN(2432,  4),
-       CHAN(2437,  5),
-       CHAN(2442,  6),
-       CHAN(2447,  7),
-       CHAN(2452,  8),
-       CHAN(2457,  9),
-       CHAN(2462, 10),
-       CHAN(2467, 11),
-       CHAN(2472, 12),
-       CHAN(2484, 13),
-};
-
-static struct ieee80211_channel ar9170_5ghz_chantable[] = {
-       CHAN(4920, 14),
-       CHAN(4940, 15),
-       CHAN(4960, 16),
-       CHAN(4980, 17),
-       CHAN(5040, 18),
-       CHAN(5060, 19),
-       CHAN(5080, 20),
-       CHAN(5180, 21),
-       CHAN(5200, 22),
-       CHAN(5220, 23),
-       CHAN(5240, 24),
-       CHAN(5260, 25),
-       CHAN(5280, 26),
-       CHAN(5300, 27),
-       CHAN(5320, 28),
-       CHAN(5500, 29),
-       CHAN(5520, 30),
-       CHAN(5540, 31),
-       CHAN(5560, 32),
-       CHAN(5580, 33),
-       CHAN(5600, 34),
-       CHAN(5620, 35),
-       CHAN(5640, 36),
-       CHAN(5660, 37),
-       CHAN(5680, 38),
-       CHAN(5700, 39),
-       CHAN(5745, 40),
-       CHAN(5765, 41),
-       CHAN(5785, 42),
-       CHAN(5805, 43),
-       CHAN(5825, 44),
-       CHAN(5170, 45),
-       CHAN(5190, 46),
-       CHAN(5210, 47),
-       CHAN(5230, 48),
-};
-#undef CHAN
-
-static struct ieee80211_supported_band ar9170_band_2GHz = {
-       .channels       = ar9170_2ghz_chantable,
-       .n_channels     = ARRAY_SIZE(ar9170_2ghz_chantable),
-       .bitrates       = ar9170_g_ratetable,
-       .n_bitrates     = ar9170_g_ratetable_size,
-};
-
-#ifdef AR9170_QUEUE_DEBUG
-/*
- * In case some wants works with AR9170's crazy tx_status queueing techniques.
- * He might need this rather useful probing function.
- *
- * NOTE: caller must hold the queue's spinlock!
- */
-
-static void ar9170_print_txheader(struct ar9170 *ar, struct sk_buff *skb)
-{
-       struct ar9170_tx_control *txc = (void *) skb->data;
-       struct ieee80211_hdr *hdr = (void *)txc->frame_data;
-
-       printk(KERN_DEBUG "%s: => FRAME [skb:%p, queue:%d, DA:[%pM] "
-                         "mac_control:%04x, phy_control:%08x]\n",
-              wiphy_name(ar->hw->wiphy), skb, skb_get_queue_mapping(skb),
-              ieee80211_get_DA(hdr), le16_to_cpu(txc->mac_control),
-              le32_to_cpu(txc->phy_control));
-}
-
-static void ar9170_dump_station_tx_status_queue(struct ar9170 *ar,
-                                               struct sk_buff_head *queue)
-{
-       struct sk_buff *skb;
-       int i = 0;
-
-       printk(KERN_DEBUG "---[ cut here ]---\n");
-       printk(KERN_DEBUG "%s: %d entries in tx_status queue.\n",
-              wiphy_name(ar->hw->wiphy), skb_queue_len(queue));
-
-       skb_queue_walk(queue, skb) {
-               struct ar9170_tx_control *txc = (void *) skb->data;
-               struct ieee80211_hdr *hdr = (void *)txc->frame_data;
-
-               printk(KERN_DEBUG "index:%d => \n", i);
-               ar9170_print_txheader(ar, skb);
-       }
-       printk(KERN_DEBUG "---[ end ]---\n");
-}
-#endif /* AR9170_QUEUE_DEBUG */
-
-static struct ieee80211_supported_band ar9170_band_5GHz = {
-       .channels       = ar9170_5ghz_chantable,
-       .n_channels     = ARRAY_SIZE(ar9170_5ghz_chantable),
-       .bitrates       = ar9170_a_ratetable,
-       .n_bitrates     = ar9170_a_ratetable_size,
-};
-
-void ar9170_handle_tx_status(struct ar9170 *ar, struct sk_buff *skb,
-                            bool valid_status, u16 tx_status)
-{
-       struct ieee80211_tx_info *txinfo;
-       unsigned int retries = 0, queue = skb_get_queue_mapping(skb);
-       unsigned long flags;
-
-       spin_lock_irqsave(&ar->tx_stats_lock, flags);
-       ar->tx_stats[queue].len--;
-       if (ieee80211_queue_stopped(ar->hw, queue))
-               ieee80211_wake_queue(ar->hw, queue);
-       spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
-
-       txinfo = IEEE80211_SKB_CB(skb);
-       ieee80211_tx_info_clear_status(txinfo);
-
-       switch (tx_status) {
-       case AR9170_TX_STATUS_RETRY:
-               retries = 2;
-       case AR9170_TX_STATUS_COMPLETE:
-               txinfo->flags |= IEEE80211_TX_STAT_ACK;
-               break;
-
-       case AR9170_TX_STATUS_FAILED:
-               retries = ar->hw->conf.long_frame_max_tx_count;
-               break;
-
-       default:
-               printk(KERN_ERR "%s: invalid tx_status response (%x).\n",
-                      wiphy_name(ar->hw->wiphy), tx_status);
-               break;
-       }
-
-       if (valid_status)
-               txinfo->status.rates[0].count = retries + 1;
-
-       skb_pull(skb, sizeof(struct ar9170_tx_control));
-       ieee80211_tx_status_irqsafe(ar->hw, skb);
-}
-
-static struct sk_buff *ar9170_find_skb_in_queue(struct ar9170 *ar,
-                                               const u8 *mac,
-                                               const u32 queue,
-                                               struct sk_buff_head *q)
-{
-       unsigned long flags;
-       struct sk_buff *skb;
-
-       spin_lock_irqsave(&q->lock, flags);
-       skb_queue_walk(q, skb) {
-               struct ar9170_tx_control *txc = (void *) skb->data;
-               struct ieee80211_hdr *hdr = (void *) txc->frame_data;
-               u32 txc_queue = (le32_to_cpu(txc->phy_control) &
-                               AR9170_TX_PHY_QOS_MASK) >>
-                               AR9170_TX_PHY_QOS_SHIFT;
-
-               if  ((queue != txc_queue) ||
-                    (compare_ether_addr(ieee80211_get_DA(hdr), mac)))
-                       continue;
-
-               __skb_unlink(skb, q);
-               spin_unlock_irqrestore(&q->lock, flags);
-               return skb;
-       }
-       spin_unlock_irqrestore(&q->lock, flags);
-       return NULL;
-}
-
-static struct sk_buff *ar9170_find_queued_skb(struct ar9170 *ar, const u8 *mac,
-                                             const u32 queue)
-{
-       struct ieee80211_sta *sta;
-       struct sk_buff *skb;
-
-       /*
-        * Unfortunately, the firmware does not tell to which (queued) frame
-        * this transmission status report belongs to.
-        *
-        * So we have to make risky guesses - with the scarce information
-        * the firmware provided (-> destination MAC, and phy_control) -
-        * and hope that we picked the right one...
-        */
-       rcu_read_lock();
-       sta = ieee80211_find_sta(ar->hw, mac);
-
-       if (likely(sta)) {
-               struct ar9170_sta_info *sta_priv = (void *) sta->drv_priv;
-               skb = skb_dequeue(&sta_priv->tx_status[queue]);
-               rcu_read_unlock();
-               if (likely(skb))
-                       return skb;
-       } else
-               rcu_read_unlock();
-
-       /* scan the waste queue for candidates */
-       skb = ar9170_find_skb_in_queue(ar, mac, queue,
-                                      &ar->global_tx_status_waste);
-       if (!skb) {
-               /* so it still _must_ be in the global list. */
-               skb = ar9170_find_skb_in_queue(ar, mac, queue,
-                                              &ar->global_tx_status);
-       }
-
-#ifdef AR9170_QUEUE_DEBUG
-       if (unlikely((!skb) && net_ratelimit())) {
-               printk(KERN_ERR "%s: ESS:[%pM] does not have any "
-                               "outstanding frames in this queue (%d).\n",
-                               wiphy_name(ar->hw->wiphy), mac, queue);
-       }
-#endif /* AR9170_QUEUE_DEBUG */
-       return skb;
-}
-
-/*
- * This worker tries to keep the global tx_status queue empty.
- * So we can guarantee that incoming tx_status reports for
- * unregistered stations are always synced with the actual
- * frame - which we think - belongs to.
- */
-
-static void ar9170_tx_status_janitor(struct work_struct *work)
-{
-       struct ar9170 *ar = container_of(work, struct ar9170,
-                                        tx_status_janitor.work);
-       struct sk_buff *skb;
-
-       if (unlikely(!IS_STARTED(ar)))
-               return ;
-
-       mutex_lock(&ar->mutex);
-       /* recycle the garbage back to mac80211... one by one. */
-       while ((skb = skb_dequeue(&ar->global_tx_status_waste))) {
-#ifdef AR9170_QUEUE_DEBUG
-               printk(KERN_DEBUG "%s: dispose queued frame =>\n",
-                      wiphy_name(ar->hw->wiphy));
-               ar9170_print_txheader(ar, skb);
-#endif /* AR9170_QUEUE_DEBUG */
-               ar9170_handle_tx_status(ar, skb, false,
-                                       AR9170_TX_STATUS_FAILED);
-       }
-
-       while ((skb = skb_dequeue(&ar->global_tx_status))) {
-#ifdef AR9170_QUEUE_DEBUG
-               printk(KERN_DEBUG "%s: moving frame into waste queue =>\n",
-                      wiphy_name(ar->hw->wiphy));
-
-               ar9170_print_txheader(ar, skb);
-#endif /* AR9170_QUEUE_DEBUG */
-               skb_queue_tail(&ar->global_tx_status_waste, skb);
-       }
-
-       /* recall the janitor in 100ms - if there's garbage in the can. */
-       if (skb_queue_len(&ar->global_tx_status_waste) > 0)
-               queue_delayed_work(ar->hw->workqueue, &ar->tx_status_janitor,
-                                  msecs_to_jiffies(100));
-
-       mutex_unlock(&ar->mutex);
-}
-
-static void ar9170_handle_command_response(struct ar9170 *ar,
-                                          void *buf, u32 len)
-{
-       struct ar9170_cmd_response *cmd = (void *) buf;
-
-       if ((cmd->type & 0xc0) != 0xc0) {
-               ar->callback_cmd(ar, len, buf);
-               return;
-       }
-
-       /* hardware event handlers */
-       switch (cmd->type) {
-       case 0xc1: {
-               /*
-                * TX status notification:
-                * bytes: 0c c1 XX YY M1 M2 M3 M4 M5 M6 R4 R3 R2 R1 S2 S1
-                *
-                * XX always 81
-                * YY always 00
-                * M1-M6 is the MAC address
-                * R1-R4 is the transmit rate
-                * S1-S2 is the transmit status
-                */
-
-               struct sk_buff *skb;
-               u32 queue = (le32_to_cpu(cmd->tx_status.rate) &
-                           AR9170_TX_PHY_QOS_MASK) >> AR9170_TX_PHY_QOS_SHIFT;
-
-               skb = ar9170_find_queued_skb(ar, cmd->tx_status.dst, queue);
-               if (unlikely(!skb))
-                       return ;
-
-               ar9170_handle_tx_status(ar, skb, true,
-                                       le16_to_cpu(cmd->tx_status.status));
-               break;
-               }
-
-       case 0xc0:
-               /*
-                * pre-TBTT event
-                */
-               if (ar->vif && ar->vif->type == NL80211_IFTYPE_AP)
-                       queue_work(ar->hw->workqueue, &ar->beacon_work);
-               break;
-
-       case 0xc2:
-               /*
-                * (IBSS) beacon send notification
-                * bytes: 04 c2 XX YY B4 B3 B2 B1
-                *
-                * XX always 80
-                * YY always 00
-                * B1-B4 "should" be the number of send out beacons.
-                */
-               break;
-
-       case 0xc3:
-               /* End of Atim Window */
-               break;
-
-       case 0xc4:
-       case 0xc5:
-               /* BlockACK events */
-               break;
-
-       case 0xc6:
-               /* Watchdog Interrupt */
-               break;
-
-       case 0xc9:
-               /* retransmission issue / SIFS/EIFS collision ?! */
-               break;
-
-       default:
-               printk(KERN_INFO "received unhandled event %x\n", cmd->type);
-               print_hex_dump_bytes("dump:", DUMP_PREFIX_NONE, buf, len);
-               break;
-       }
-}
-
-/*
- * If the frame alignment is right (or the kernel has
- * CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS), and there
- * is only a single MPDU in the USB frame, then we can
- * submit to mac80211 the SKB directly. However, since
- * there may be multiple packets in one SKB in stream
- * mode, and we need to observe the proper ordering,
- * this is non-trivial.
- */
-static void ar9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len)
-{
-       struct sk_buff *skb;
-       struct ar9170_rx_head *head = (void *)buf;
-       struct ar9170_rx_tail *tail;
-       struct ieee80211_rx_status status;
-       int mpdu_len, i;
-       u8 error, antennas = 0, decrypt;
-       __le16 fc;
-       int reserved;
-
-       if (unlikely(!IS_STARTED(ar)))
-               return ;
-
-       /* Received MPDU */
-       mpdu_len = len;
-       mpdu_len -= sizeof(struct ar9170_rx_head);
-       mpdu_len -= sizeof(struct ar9170_rx_tail);
-       BUILD_BUG_ON(sizeof(struct ar9170_rx_head) != 12);
-       BUILD_BUG_ON(sizeof(struct ar9170_rx_tail) != 24);
-
-       if (mpdu_len <= FCS_LEN)
-               return;
-
-       tail = (void *)(buf + sizeof(struct ar9170_rx_head) + mpdu_len);
-
-       for (i = 0; i < 3; i++)
-               if (tail->rssi[i] != 0x80)
-                       antennas |= BIT(i);
-
-       /* post-process RSSI */
-       for (i = 0; i < 7; i++)
-               if (tail->rssi[i] & 0x80)
-                       tail->rssi[i] = ((tail->rssi[i] & 0x7f) + 1) & 0x7f;
-
-       memset(&status, 0, sizeof(status));
-
-       status.band = ar->channel->band;
-       status.freq = ar->channel->center_freq;
-       status.signal = ar->noise[0] + tail->rssi_combined;
-       status.noise = ar->noise[0];
-       status.antenna = antennas;
-
-       switch (tail->status & AR9170_RX_STATUS_MODULATION_MASK) {
-       case AR9170_RX_STATUS_MODULATION_CCK:
-               if (tail->status & AR9170_RX_STATUS_SHORT_PREAMBLE)
-                       status.flag |= RX_FLAG_SHORTPRE;
-               switch (head->plcp[0]) {
-               case 0x0a:
-                       status.rate_idx = 0;
-                       break;
-               case 0x14:
-                       status.rate_idx = 1;
-                       break;
-               case 0x37:
-                       status.rate_idx = 2;
-                       break;
-               case 0x6e:
-                       status.rate_idx = 3;
-                       break;
-               default:
-                       if ((!ar->sniffer_enabled) && (net_ratelimit()))
-                               printk(KERN_ERR "%s: invalid plcp cck rate "
-                                      "(%x).\n", wiphy_name(ar->hw->wiphy),
-                                      head->plcp[0]);
-                       return;
-               }
-               break;
-       case AR9170_RX_STATUS_MODULATION_OFDM:
-               switch (head->plcp[0] & 0xF) {
-               case 0xB:
-                       status.rate_idx = 0;
-                       break;
-               case 0xF:
-                       status.rate_idx = 1;
-                       break;
-               case 0xA:
-                       status.rate_idx = 2;
-                       break;
-               case 0xE:
-                       status.rate_idx = 3;
-                       break;
-               case 0x9:
-                       status.rate_idx = 4;
-                       break;
-               case 0xD:
-                       status.rate_idx = 5;
-                       break;
-               case 0x8:
-                       status.rate_idx = 6;
-                       break;
-               case 0xC:
-                       status.rate_idx = 7;
-                       break;
-               default:
-                       if ((!ar->sniffer_enabled) && (net_ratelimit()))
-                               printk(KERN_ERR "%s: invalid plcp ofdm rate "
-                                      "(%x).\n", wiphy_name(ar->hw->wiphy),
-                                      head->plcp[0]);
-                       return;
-               }
-               if (status.band == IEEE80211_BAND_2GHZ)
-                       status.rate_idx += 4;
-               break;
-       case AR9170_RX_STATUS_MODULATION_HT:
-       case AR9170_RX_STATUS_MODULATION_DUPOFDM:
-               /* XXX */
-
-               if (net_ratelimit())
-                       printk(KERN_ERR "%s: invalid modulation\n",
-                              wiphy_name(ar->hw->wiphy));
-               return;
-       }
-
-       error = tail->error;
-
-       if (error & AR9170_RX_ERROR_MMIC) {
-               status.flag |= RX_FLAG_MMIC_ERROR;
-               error &= ~AR9170_RX_ERROR_MMIC;
-       }
-
-       if (error & AR9170_RX_ERROR_PLCP) {
-               status.flag |= RX_FLAG_FAILED_PLCP_CRC;
-               error &= ~AR9170_RX_ERROR_PLCP;
-       }
-
-       if (error & AR9170_RX_ERROR_FCS) {
-               status.flag |= RX_FLAG_FAILED_FCS_CRC;
-               error &= ~AR9170_RX_ERROR_FCS;
-       }
-
-       decrypt = ar9170_get_decrypt_type(tail);
-       if (!(decrypt & AR9170_RX_ENC_SOFTWARE) &&
-           decrypt != AR9170_ENC_ALG_NONE)
-               status.flag |= RX_FLAG_DECRYPTED;
-
-       /* ignore wrong RA errors */
-       error &= ~AR9170_RX_ERROR_WRONG_RA;
-
-       if (error & AR9170_RX_ERROR_DECRYPT) {
-               error &= ~AR9170_RX_ERROR_DECRYPT;
-
-               /*
-                * Rx decryption is done in place,
-                * the original data is lost anyway.
-                */
-               return ;
-       }
-
-       /* drop any other error frames */
-       if ((error) && (net_ratelimit())) {
-               printk(KERN_DEBUG "%s: errors: %#x\n",
-                      wiphy_name(ar->hw->wiphy), error);
-               return;
-       }
-
-       buf += sizeof(struct ar9170_rx_head);
-       fc = *(__le16 *)buf;
-
-       if (ieee80211_is_data_qos(fc) ^ ieee80211_has_a4(fc))
-               reserved = 32 + 2;
-       else
-               reserved = 32;
-
-       skb = dev_alloc_skb(mpdu_len + reserved);
-       if (!skb)
-               return;
-
-       skb_reserve(skb, reserved);
-       memcpy(skb_put(skb, mpdu_len), buf, mpdu_len);
-       ieee80211_rx_irqsafe(ar->hw, skb, &status);
-}
-
-void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb)
-{
-       unsigned int i, tlen, resplen;
-       u8 *tbuf, *respbuf;
-
-       tbuf = skb->data;
-       tlen = skb->len;
-
-       while (tlen >= 4) {
-               int clen = tbuf[1] << 8 | tbuf[0];
-               int wlen = (clen + 3) & ~3;
-
-               /*
-                * parse stream (if any)
-                */
-               if (tbuf[2] != 0 || tbuf[3] != 0x4e) {
-                       printk(KERN_ERR "%s: missing tag!\n",
-                              wiphy_name(ar->hw->wiphy));
-                       return ;
-               }
-               if (wlen > tlen - 4) {
-                       printk(KERN_ERR "%s: invalid RX (%d, %d, %d)\n",
-                              wiphy_name(ar->hw->wiphy), clen, wlen, tlen);
-                       print_hex_dump(KERN_DEBUG, "data: ",
-                                      DUMP_PREFIX_OFFSET,
-                                      16, 1, tbuf, tlen, true);
-                       return ;
-               }
-               resplen = clen;
-               respbuf = tbuf + 4;
-               tbuf += wlen + 4;
-               tlen -= wlen + 4;
-
-               i = 0;
-
-               /* weird thing, but this is the same in the original driver */
-               while (resplen > 2 && i < 12 &&
-                      respbuf[0] == 0xff && respbuf[1] == 0xff) {
-                       i += 2;
-                       resplen -= 2;
-                       respbuf += 2;
-               }
-
-               if (resplen < 4)
-                       continue;
-
-               /* found the 6 * 0xffff marker? */
-               if (i == 12)
-                       ar9170_handle_command_response(ar, respbuf, resplen);
-               else
-                       ar9170_handle_mpdu(ar, respbuf, resplen);
-       }
-
-       if (tlen)
-               printk(KERN_ERR "%s: buffer remains!\n",
-                      wiphy_name(ar->hw->wiphy));
-}
-
-#define AR9170_FILL_QUEUE(queue, ai_fs, cwmin, cwmax, _txop)           \
-do {                                                                   \
-       queue.aifs = ai_fs;                                             \
-       queue.cw_min = cwmin;                                           \
-       queue.cw_max = cwmax;                                           \
-       queue.txop = _txop;                                             \
-} while (0)
-
-static int ar9170_op_start(struct ieee80211_hw *hw)
-{
-       struct ar9170 *ar = hw->priv;
-       int err, i;
-
-       mutex_lock(&ar->mutex);
-
-       /* reinitialize queues statistics */
-       memset(&ar->tx_stats, 0, sizeof(ar->tx_stats));
-       for (i = 0; i < ARRAY_SIZE(ar->tx_stats); i++)
-               ar->tx_stats[i].limit = 8;
-
-       /* reset QoS defaults */
-       AR9170_FILL_QUEUE(ar->edcf[0], 3, 15, 1023,  0); /* BEST EFFORT*/
-       AR9170_FILL_QUEUE(ar->edcf[1], 7, 15, 1023,  0); /* BACKGROUND */
-       AR9170_FILL_QUEUE(ar->edcf[2], 2, 7,    15, 94); /* VIDEO */
-       AR9170_FILL_QUEUE(ar->edcf[3], 2, 3,     7, 47); /* VOICE */
-       AR9170_FILL_QUEUE(ar->edcf[4], 2, 3,     7,  0); /* SPECIAL */
-
-       err = ar->open(ar);
-       if (err)
-               goto out;
-
-       err = ar9170_init_mac(ar);
-       if (err)
-               goto out;
-
-       err = ar9170_set_qos(ar);
-       if (err)
-               goto out;
-
-       err = ar9170_init_phy(ar, IEEE80211_BAND_2GHZ);
-       if (err)
-               goto out;
-
-       err = ar9170_init_rf(ar);
-       if (err)
-               goto out;
-
-       /* start DMA */
-       err = ar9170_write_reg(ar, 0x1c3d30, 0x100);
-       if (err)
-               goto out;
-
-       ar->state = AR9170_STARTED;
-
-out:
-       mutex_unlock(&ar->mutex);
-       return err;
-}
-
-static void ar9170_op_stop(struct ieee80211_hw *hw)
-{
-       struct ar9170 *ar = hw->priv;
-
-       if (IS_STARTED(ar))
-               ar->state = AR9170_IDLE;
-
-       mutex_lock(&ar->mutex);
-
-       cancel_delayed_work_sync(&ar->tx_status_janitor);
-       cancel_work_sync(&ar->filter_config_work);
-       cancel_work_sync(&ar->beacon_work);
-       skb_queue_purge(&ar->global_tx_status_waste);
-       skb_queue_purge(&ar->global_tx_status);
-
-       if (IS_ACCEPTING_CMD(ar)) {
-               ar9170_set_leds_state(ar, 0);
-
-               /* stop DMA */
-               ar9170_write_reg(ar, 0x1c3d30, 0);
-               ar->stop(ar);
-       }
-
-       mutex_unlock(&ar->mutex);
-}
-
-int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
-{
-       struct ar9170 *ar = hw->priv;
-       struct ieee80211_hdr *hdr;
-       struct ar9170_tx_control *txc;
-       struct ieee80211_tx_info *info;
-       struct ieee80211_rate *rate = NULL;
-       struct ieee80211_tx_rate *txrate;
-       unsigned int queue = skb_get_queue_mapping(skb);
-       unsigned long flags = 0;
-       struct ar9170_sta_info *sta_info = NULL;
-       u32 power, chains;
-       u16 keytype = 0;
-       u16 len, icv = 0;
-       int err;
-       bool tx_status;
-
-       if (unlikely(!IS_STARTED(ar)))
-               goto err_free;
-
-       hdr = (void *)skb->data;
-       info = IEEE80211_SKB_CB(skb);
-       len = skb->len;
-
-       spin_lock_irqsave(&ar->tx_stats_lock, flags);
-       if (ar->tx_stats[queue].limit < ar->tx_stats[queue].len) {
-               spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
-               return NETDEV_TX_OK;
-       }
-
-       ar->tx_stats[queue].len++;
-       ar->tx_stats[queue].count++;
-       if (ar->tx_stats[queue].limit == ar->tx_stats[queue].len)
-               ieee80211_stop_queue(hw, queue);
-
-       spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
-
-       txc = (void *)skb_push(skb, sizeof(*txc));
-
-       tx_status = (((info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) != 0) ||
-                   ((info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) != 0));
-
-       if (info->control.hw_key) {
-               icv = info->control.hw_key->icv_len;
-
-               switch (info->control.hw_key->alg) {
-               case ALG_WEP:
-                       keytype = AR9170_TX_MAC_ENCR_RC4;
-                       break;
-               case ALG_TKIP:
-                       keytype = AR9170_TX_MAC_ENCR_RC4;
-                       break;
-               case ALG_CCMP:
-                       keytype = AR9170_TX_MAC_ENCR_AES;
-                       break;
-               default:
-                       WARN_ON(1);
-                       goto err_dequeue;
-               }
-       }
-
-       /* Length */
-       txc->length = cpu_to_le16(len + icv + 4);
-
-       txc->mac_control = cpu_to_le16(AR9170_TX_MAC_HW_DURATION |
-                                      AR9170_TX_MAC_BACKOFF);
-       txc->mac_control |= cpu_to_le16(ar9170_qos_hwmap[queue] <<
-                                       AR9170_TX_MAC_QOS_SHIFT);
-       txc->mac_control |= cpu_to_le16(keytype);
-       txc->phy_control = cpu_to_le32(0);
-
-       if (info->flags & IEEE80211_TX_CTL_NO_ACK)
-               txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_NO_ACK);
-
-       if (info->flags & IEEE80211_TX_CTL_AMPDU)
-               txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_AGGR);
-
-       txrate = &info->control.rates[0];
-
-       if (txrate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
-               txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_PROT_CTS);
-       else if (txrate->flags & IEEE80211_TX_RC_USE_RTS_CTS)
-               txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_PROT_RTS);
-
-       if (txrate->flags & IEEE80211_TX_RC_GREEN_FIELD)
-               txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_GREENFIELD);
-
-       if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
-               txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_SHORT_PREAMBLE);
-
-       if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
-               txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_BW_40MHZ);
-       /* this works because 40 MHz is 2 and dup is 3 */
-       if (txrate->flags & IEEE80211_TX_RC_DUP_DATA)
-               txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_BW_40MHZ_DUP);
-
-       if (txrate->flags & IEEE80211_TX_RC_SHORT_GI)
-               txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_SHORT_GI);
-
-       if (txrate->flags & IEEE80211_TX_RC_MCS) {
-               u32 r = txrate->idx;
-               u8 *txpower;
-
-               r <<= AR9170_TX_PHY_MCS_SHIFT;
-               if (WARN_ON(r & ~AR9170_TX_PHY_MCS_MASK))
-                       goto err_dequeue;
-               txc->phy_control |= cpu_to_le32(r & AR9170_TX_PHY_MCS_MASK);
-               txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_MOD_HT);
-
-               if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) {
-                       if (info->band == IEEE80211_BAND_5GHZ)
-                               txpower = ar->power_5G_ht40;
-                       else
-                               txpower = ar->power_2G_ht40;
-               } else {
-                       if (info->band == IEEE80211_BAND_5GHZ)
-                               txpower = ar->power_5G_ht20;
-                       else
-                               txpower = ar->power_2G_ht20;
-               }
-
-               power = txpower[(txrate->idx) & 7];
-       } else {
-               u8 *txpower;
-               u32 mod;
-               u32 phyrate;
-               u8 idx = txrate->idx;
-
-               if (info->band != IEEE80211_BAND_2GHZ) {
-                       idx += 4;
-                       txpower = ar->power_5G_leg;
-                       mod = AR9170_TX_PHY_MOD_OFDM;
-               } else {
-                       if (idx < 4) {
-                               txpower = ar->power_2G_cck;
-                               mod = AR9170_TX_PHY_MOD_CCK;
-                       } else {
-                               mod = AR9170_TX_PHY_MOD_OFDM;
-                               txpower = ar->power_2G_ofdm;
-                       }
-               }
-
-               rate = &__ar9170_ratetable[idx];
-
-               phyrate = rate->hw_value & 0xF;
-               power = txpower[(rate->hw_value & 0x30) >> 4];
-               phyrate <<= AR9170_TX_PHY_MCS_SHIFT;
-
-               txc->phy_control |= cpu_to_le32(mod);
-               txc->phy_control |= cpu_to_le32(phyrate);
-       }
-
-       power <<= AR9170_TX_PHY_TX_PWR_SHIFT;
-       power &= AR9170_TX_PHY_TX_PWR_MASK;
-       txc->phy_control |= cpu_to_le32(power);
-
-       /* set TX chains */
-       if (ar->eeprom.tx_mask == 1) {
-               chains = AR9170_TX_PHY_TXCHAIN_1;
-       } else {
-               chains = AR9170_TX_PHY_TXCHAIN_2;
-
-               /* >= 36M legacy OFDM - use only one chain */
-               if (rate && rate->bitrate >= 360)
-                       chains = AR9170_TX_PHY_TXCHAIN_1;
-       }
-       txc->phy_control |= cpu_to_le32(chains << AR9170_TX_PHY_TXCHAIN_SHIFT);
-
-       if (tx_status) {
-               txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_RATE_PROBE);
-               /*
-                * WARNING:
-                * Putting the QoS queue bits into an unexplored territory is
-                * certainly not elegant.
-                *
-                * In my defense: This idea provides a reasonable way to
-                * smuggle valuable information to the tx_status callback.
-                * Also, the idea behind this bit-abuse came straight from
-                * the original driver code.
-                */
-
-               txc->phy_control |=
-                       cpu_to_le32(queue << AR9170_TX_PHY_QOS_SHIFT);
-
-               if (info->control.sta) {
-                       sta_info = (void *) info->control.sta->drv_priv;
-                       skb_queue_tail(&sta_info->tx_status[queue], skb);
-               } else {
-                       skb_queue_tail(&ar->global_tx_status, skb);
-
-                       queue_delayed_work(ar->hw->workqueue,
-                                          &ar->tx_status_janitor,
-                                          msecs_to_jiffies(100));
-               }
-       }
-
-       err = ar->tx(ar, skb, tx_status, 0);
-       if (unlikely(tx_status && err)) {
-               if (info->control.sta)
-                       skb_unlink(skb, &sta_info->tx_status[queue]);
-               else
-                       skb_unlink(skb, &ar->global_tx_status);
-       }
-
-       return NETDEV_TX_OK;
-
-err_dequeue:
-       spin_lock_irqsave(&ar->tx_stats_lock, flags);
-       ar->tx_stats[queue].len--;
-       ar->tx_stats[queue].count--;
-       spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
-
-err_free:
-       dev_kfree_skb(skb);
-       return NETDEV_TX_OK;
-}
-
-static int ar9170_op_add_interface(struct ieee80211_hw *hw,
-                                  struct ieee80211_if_init_conf *conf)
-{
-       struct ar9170 *ar = hw->priv;
-       int err = 0;
-
-       mutex_lock(&ar->mutex);
-
-       if (ar->vif) {
-               err = -EBUSY;
-               goto unlock;
-       }
-
-       ar->vif = conf->vif;
-       memcpy(ar->mac_addr, conf->mac_addr, ETH_ALEN);
-
-       if (modparam_nohwcrypt || (ar->vif->type != NL80211_IFTYPE_STATION)) {
-               ar->rx_software_decryption = true;
-               ar->disable_offload = true;
-       }
-
-       ar->cur_filter = 0;
-       ar->want_filter = AR9170_MAC_REG_FTF_DEFAULTS;
-       err = ar9170_update_frame_filter(ar);
-       if (err)
-               goto unlock;
-
-       err = ar9170_set_operating_mode(ar);
-
-unlock:
-       mutex_unlock(&ar->mutex);
-       return err;
-}
-
-static void ar9170_op_remove_interface(struct ieee80211_hw *hw,
-                                      struct ieee80211_if_init_conf *conf)
-{
-       struct ar9170 *ar = hw->priv;
-
-       mutex_lock(&ar->mutex);
-       ar->vif = NULL;
-       ar->want_filter = 0;
-       ar9170_update_frame_filter(ar);
-       ar9170_set_beacon_timers(ar);
-       dev_kfree_skb(ar->beacon);
-       ar->beacon = NULL;
-       ar->sniffer_enabled = false;
-       ar->rx_software_decryption = false;
-       ar9170_set_operating_mode(ar);
-       mutex_unlock(&ar->mutex);
-}
-
-static int ar9170_op_config(struct ieee80211_hw *hw, u32 changed)
-{
-       struct ar9170 *ar = hw->priv;
-       int err = 0;
-
-       mutex_lock(&ar->mutex);
-
-       if (changed & IEEE80211_CONF_CHANGE_RADIO_ENABLED) {
-               /* TODO */
-               err = 0;
-       }
-
-       if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) {
-               /* TODO */
-               err = 0;
-       }
-
-       if (changed & IEEE80211_CONF_CHANGE_PS) {
-               /* TODO */
-               err = 0;
-       }
-
-       if (changed & IEEE80211_CONF_CHANGE_POWER) {
-               /* TODO */
-               err = 0;
-       }
-
-       if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) {
-               /*
-                * is it long_frame_max_tx_count or short_frame_max_tx_count?
-                */
-
-               err = ar9170_set_hwretry_limit(ar,
-                       ar->hw->conf.long_frame_max_tx_count);
-               if (err)
-                       goto out;
-       }
-
-       if (changed & IEEE80211_CONF_CHANGE_BEACON_INTERVAL) {
-               err = ar9170_set_beacon_timers(ar);
-               if (err)
-                       goto out;
-       }
-
-       if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
-               err = ar9170_set_channel(ar, hw->conf.channel,
-                                        AR9170_RFI_NONE, AR9170_BW_20);
-               if (err)
-                       goto out;
-               /* adjust slot time for 5 GHz */
-               if (hw->conf.channel->band == IEEE80211_BAND_5GHZ)
-                       err = ar9170_write_reg(ar, AR9170_MAC_REG_SLOT_TIME,
-                                              9 << 10);
-       }
-
-out:
-       mutex_unlock(&ar->mutex);
-       return err;
-}
-
-static int ar9170_op_config_interface(struct ieee80211_hw *hw,
-                                     struct ieee80211_vif *vif,
-                                     struct ieee80211_if_conf *conf)
-{
-       struct ar9170 *ar = hw->priv;
-       int err = 0;
-
-       mutex_lock(&ar->mutex);
-
-       if (conf->changed & IEEE80211_IFCC_BSSID) {
-               memcpy(ar->bssid, conf->bssid, ETH_ALEN);
-               err = ar9170_set_operating_mode(ar);
-       }
-
-       if (conf->changed & IEEE80211_IFCC_BEACON) {
-               err = ar9170_update_beacon(ar);
-
-               if (err)
-                       goto out;
-               err = ar9170_set_beacon_timers(ar);
-       }
-
-out:
-       mutex_unlock(&ar->mutex);
-       return err;
-}
-
-static void ar9170_set_filters(struct work_struct *work)
-{
-       struct ar9170 *ar = container_of(work, struct ar9170,
-                                        filter_config_work);
-       int err;
-
-       mutex_lock(&ar->mutex);
-       if (unlikely(!IS_STARTED(ar)))
-               goto unlock;
-
-       if (ar->filter_changed & AR9170_FILTER_CHANGED_PROMISC) {
-               err = ar9170_set_operating_mode(ar);
-               if (err)
-                       goto unlock;
-       }
-
-       if (ar->filter_changed & AR9170_FILTER_CHANGED_MULTICAST) {
-               err = ar9170_update_multicast(ar);
-               if (err)
-                       goto unlock;
-       }
-
-       if (ar->filter_changed & AR9170_FILTER_CHANGED_FRAMEFILTER)
-               err = ar9170_update_frame_filter(ar);
-
-unlock:
-       mutex_unlock(&ar->mutex);
-}
-
-static void ar9170_op_configure_filter(struct ieee80211_hw *hw,
-                                      unsigned int changed_flags,
-                                      unsigned int *new_flags,
-                                      int mc_count, struct dev_mc_list *mclist)
-{
-       struct ar9170 *ar = hw->priv;
-
-       /* mask supported flags */
-       *new_flags &= FIF_ALLMULTI | FIF_CONTROL | FIF_BCN_PRBRESP_PROMISC |
-                     FIF_PROMISC_IN_BSS;
-
-       /*
-        * We can support more by setting the sniffer bit and
-        * then checking the error flags, later.
-        */
-
-       if (changed_flags & FIF_ALLMULTI) {
-               if (*new_flags & FIF_ALLMULTI) {
-                       ar->want_mc_hash = ~0ULL;
-               } else {
-                       u64 mchash;
-                       int i;
-
-                       /* always get broadcast frames */
-                       mchash = 1ULL << (0xff>>2);
-
-                       for (i = 0; i < mc_count; i++) {
-                               if (WARN_ON(!mclist))
-                                       break;
-                               mchash |= 1ULL << (mclist->dmi_addr[5] >> 2);
-                               mclist = mclist->next;
-                       }
-               ar->want_mc_hash = mchash;
-               }
-               ar->filter_changed |= AR9170_FILTER_CHANGED_MULTICAST;
-       }
-
-       if (changed_flags & FIF_CONTROL) {
-               u32 filter = AR9170_MAC_REG_FTF_PSPOLL |
-                            AR9170_MAC_REG_FTF_RTS |
-                            AR9170_MAC_REG_FTF_CTS |
-                            AR9170_MAC_REG_FTF_ACK |
-                            AR9170_MAC_REG_FTF_CFE |
-                            AR9170_MAC_REG_FTF_CFE_ACK;
-
-               if (*new_flags & FIF_CONTROL)
-                       ar->want_filter = ar->cur_filter | filter;
-               else
-                       ar->want_filter = ar->cur_filter & ~filter;
-
-               ar->filter_changed |= AR9170_FILTER_CHANGED_FRAMEFILTER;
-       }
-
-       if (changed_flags & FIF_PROMISC_IN_BSS) {
-               ar->sniffer_enabled = ((*new_flags) & FIF_PROMISC_IN_BSS) != 0;
-               ar->filter_changed |= AR9170_FILTER_CHANGED_PROMISC;
-       }
-
-       if (likely(IS_STARTED(ar)))
-               queue_work(ar->hw->workqueue, &ar->filter_config_work);
-}
-
-static void ar9170_op_bss_info_changed(struct ieee80211_hw *hw,
-                                      struct ieee80211_vif *vif,
-                                      struct ieee80211_bss_conf *bss_conf,
-                                      u32 changed)
-{
-       struct ar9170 *ar = hw->priv;
-       int err = 0;
-
-       mutex_lock(&ar->mutex);
-
-       ar9170_regwrite_begin(ar);
-
-       if (changed & BSS_CHANGED_ASSOC) {
-               ar->state = bss_conf->assoc ? AR9170_ASSOCIATED : ar->state;
-
-#ifndef CONFIG_AR9170_LEDS
-               /* enable assoc LED. */
-               err = ar9170_set_leds_state(ar, bss_conf->assoc ? 2 : 0);
-#endif /* CONFIG_AR9170_LEDS */
-       }
-
-       if (changed & BSS_CHANGED_HT) {
-               /* TODO */
-               err = 0;
-       }
-
-       if (changed & BSS_CHANGED_ERP_SLOT) {
-               u32 slottime = 20;
-
-               if (bss_conf->use_short_slot)
-                       slottime = 9;
-
-               ar9170_regwrite(AR9170_MAC_REG_SLOT_TIME, slottime << 10);
-       }
-
-       if (changed & BSS_CHANGED_BASIC_RATES) {
-               u32 cck, ofdm;
-
-               if (hw->conf.channel->band == IEEE80211_BAND_5GHZ) {
-                       ofdm = bss_conf->basic_rates;
-                       cck = 0;
-               } else {
-                       /* four cck rates */
-                       cck = bss_conf->basic_rates & 0xf;
-                       ofdm = bss_conf->basic_rates >> 4;
-               }
-               ar9170_regwrite(AR9170_MAC_REG_BASIC_RATE,
-                               ofdm << 8 | cck);
-       }
-
-       ar9170_regwrite_finish();
-       err = ar9170_regwrite_result();
-       mutex_unlock(&ar->mutex);
-}
-
-static u64 ar9170_op_get_tsf(struct ieee80211_hw *hw)
-{
-       struct ar9170 *ar = hw->priv;
-       int err;
-       u32 tsf_low;
-       u32 tsf_high;
-       u64 tsf;
-
-       mutex_lock(&ar->mutex);
-       err = ar9170_read_reg(ar, AR9170_MAC_REG_TSF_L, &tsf_low);
-       if (!err)
-               err = ar9170_read_reg(ar, AR9170_MAC_REG_TSF_H, &tsf_high);
-       mutex_unlock(&ar->mutex);
-
-       if (WARN_ON(err))
-               return 0;
-
-       tsf = tsf_high;
-       tsf = (tsf << 32) | tsf_low;
-       return tsf;
-}
-
-static int ar9170_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
-                         struct ieee80211_vif *vif, struct ieee80211_sta *sta,
-                         struct ieee80211_key_conf *key)
-{
-       struct ar9170 *ar = hw->priv;
-       int err = 0, i;
-       u8 ktype;
-
-       if ((!ar->vif) || (ar->disable_offload))
-               return -EOPNOTSUPP;
-
-       switch (key->alg) {
-       case ALG_WEP:
-               if (key->keylen == LEN_WEP40)
-                       ktype = AR9170_ENC_ALG_WEP64;
-               else
-                       ktype = AR9170_ENC_ALG_WEP128;
-               break;
-       case ALG_TKIP:
-               ktype = AR9170_ENC_ALG_TKIP;
-               break;
-       case ALG_CCMP:
-               ktype = AR9170_ENC_ALG_AESCCMP;
-               break;
-       default:
-               return -EOPNOTSUPP;
-       }
-
-       mutex_lock(&ar->mutex);
-       if (cmd == SET_KEY) {
-               if (unlikely(!IS_STARTED(ar))) {
-                       err = -EOPNOTSUPP;
-                       goto out;
-               }
-
-               /* group keys need all-zeroes address */
-               if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
-                       sta = NULL;
-
-               if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
-                       for (i = 0; i < 64; i++)
-                               if (!(ar->usedkeys & BIT(i)))
-                                       break;
-                       if (i == 64) {
-                               ar->rx_software_decryption = true;
-                               ar9170_set_operating_mode(ar);
-                               err = -ENOSPC;
-                               goto out;
-                       }
-               } else {
-                       i = 64 + key->keyidx;
-               }
-
-               key->hw_key_idx = i;
-
-               err = ar9170_upload_key(ar, i, sta ? sta->addr : NULL, ktype, 0,
-                                       key->key, min_t(u8, 16, key->keylen));
-               if (err)
-                       goto out;
-
-               if (key->alg == ALG_TKIP) {
-                       err = ar9170_upload_key(ar, i, sta ? sta->addr : NULL,
-                                               ktype, 1, key->key + 16, 16);
-                       if (err)
-                               goto out;
-
-                       /*
-                        * hardware is not capable generating the MMIC
-                        * for fragmented frames!
-                        */
-                       key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
-               }
-
-               if (i < 64)
-                       ar->usedkeys |= BIT(i);
-
-               key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
-       } else {
-               if (unlikely(!IS_STARTED(ar))) {
-                       /* The device is gone... together with the key ;-) */
-                       err = 0;
-                       goto out;
-               }
-
-               err = ar9170_disable_key(ar, key->hw_key_idx);
-               if (err)
-                       goto out;
-
-               if (key->hw_key_idx < 64) {
-                       ar->usedkeys &= ~BIT(key->hw_key_idx);
-               } else {
-                       err = ar9170_upload_key(ar, key->hw_key_idx, NULL,
-                                               AR9170_ENC_ALG_NONE, 0,
-                                               NULL, 0);
-                       if (err)
-                               goto out;
-
-                       if (key->alg == ALG_TKIP) {
-                               err = ar9170_upload_key(ar, key->hw_key_idx,
-                                                       NULL,
-                                                       AR9170_ENC_ALG_NONE, 1,
-                                                       NULL, 0);
-                               if (err)
-                                       goto out;
-                       }
-
-               }
-       }
-
-       ar9170_regwrite_begin(ar);
-       ar9170_regwrite(AR9170_MAC_REG_ROLL_CALL_TBL_L, ar->usedkeys);
-       ar9170_regwrite(AR9170_MAC_REG_ROLL_CALL_TBL_H, ar->usedkeys >> 32);
-       ar9170_regwrite_finish();
-       err = ar9170_regwrite_result();
-
-out:
-       mutex_unlock(&ar->mutex);
-
-       return err;
-}
-
-static void ar9170_sta_notify(struct ieee80211_hw *hw,
-                             struct ieee80211_vif *vif,
-                             enum sta_notify_cmd cmd,
-                             struct ieee80211_sta *sta)
-{
-       struct ar9170 *ar = hw->priv;
-       struct ar9170_sta_info *info = (void *) sta->drv_priv;
-       struct sk_buff *skb;
-       unsigned int i;
-
-       switch (cmd) {
-       case STA_NOTIFY_ADD:
-               for (i = 0; i < ar->hw->queues; i++)
-                       skb_queue_head_init(&info->tx_status[i]);
-               break;
-
-       case STA_NOTIFY_REMOVE:
-
-               /*
-                * transfer all outstanding frames that need a tx_status
-                * reports to the global tx_status queue
-                */
-
-               for (i = 0; i < ar->hw->queues; i++) {
-                       while ((skb = skb_dequeue(&info->tx_status[i]))) {
-#ifdef AR9170_QUEUE_DEBUG
-                               printk(KERN_DEBUG "%s: queueing frame in "
-                                         "global tx_status queue =>\n",
-                                      wiphy_name(ar->hw->wiphy));
-
-                               ar9170_print_txheader(ar, skb);
-#endif /* AR9170_QUEUE_DEBUG */
-                               skb_queue_tail(&ar->global_tx_status, skb);
-                       }
-               }
-               queue_delayed_work(ar->hw->workqueue, &ar->tx_status_janitor,
-                                  msecs_to_jiffies(100));
-               break;
-
-       default:
-               break;
-       }
-}
-
-static int ar9170_get_stats(struct ieee80211_hw *hw,
-                           struct ieee80211_low_level_stats *stats)
-{
-       struct ar9170 *ar = hw->priv;
-       u32 val;
-       int err;
-
-       mutex_lock(&ar->mutex);
-       err = ar9170_read_reg(ar, AR9170_MAC_REG_TX_RETRY, &val);
-       ar->stats.dot11ACKFailureCount += val;
-
-       memcpy(stats, &ar->stats, sizeof(*stats));
-       mutex_unlock(&ar->mutex);
-
-       return 0;
-}
-
-static int ar9170_get_tx_stats(struct ieee80211_hw *hw,
-                              struct ieee80211_tx_queue_stats *tx_stats)
-{
-       struct ar9170 *ar = hw->priv;
-
-       spin_lock_bh(&ar->tx_stats_lock);
-       memcpy(tx_stats, ar->tx_stats, sizeof(tx_stats[0]) * hw->queues);
-       spin_unlock_bh(&ar->tx_stats_lock);
-
-       return 0;
-}
-
-static int ar9170_conf_tx(struct ieee80211_hw *hw, u16 queue,
-                         const struct ieee80211_tx_queue_params *param)
-{
-       struct ar9170 *ar = hw->priv;
-       int ret;
-
-       mutex_lock(&ar->mutex);
-       if ((param) && !(queue > ar->hw->queues)) {
-               memcpy(&ar->edcf[ar9170_qos_hwmap[queue]],
-                      param, sizeof(*param));
-
-               ret = ar9170_set_qos(ar);
-       } else
-               ret = -EINVAL;
-
-       mutex_unlock(&ar->mutex);
-       return ret;
-}
-
-static const struct ieee80211_ops ar9170_ops = {
-       .start                  = ar9170_op_start,
-       .stop                   = ar9170_op_stop,
-       .tx                     = ar9170_op_tx,
-       .add_interface          = ar9170_op_add_interface,
-       .remove_interface       = ar9170_op_remove_interface,
-       .config                 = ar9170_op_config,
-       .config_interface       = ar9170_op_config_interface,
-       .configure_filter       = ar9170_op_configure_filter,
-       .conf_tx                = ar9170_conf_tx,
-       .bss_info_changed       = ar9170_op_bss_info_changed,
-       .get_tsf                = ar9170_op_get_tsf,
-       .set_key                = ar9170_set_key,
-       .sta_notify             = ar9170_sta_notify,
-       .get_stats              = ar9170_get_stats,
-       .get_tx_stats           = ar9170_get_tx_stats,
-};
-
-void *ar9170_alloc(size_t priv_size)
-{
-       struct ieee80211_hw *hw;
-       struct ar9170 *ar;
-       int i;
-
-       hw = ieee80211_alloc_hw(priv_size, &ar9170_ops);
-       if (!hw)
-               return ERR_PTR(-ENOMEM);
-
-       ar = hw->priv;
-       ar->hw = hw;
-
-       mutex_init(&ar->mutex);
-       spin_lock_init(&ar->cmdlock);
-       spin_lock_init(&ar->tx_stats_lock);
-       skb_queue_head_init(&ar->global_tx_status);
-       skb_queue_head_init(&ar->global_tx_status_waste);
-       INIT_WORK(&ar->filter_config_work, ar9170_set_filters);
-       INIT_WORK(&ar->beacon_work, ar9170_new_beacon);
-       INIT_DELAYED_WORK(&ar->tx_status_janitor, ar9170_tx_status_janitor);
-
-       /* all hw supports 2.4 GHz, so set channel to 1 by default */
-       ar->channel = &ar9170_2ghz_chantable[0];
-
-       /* first part of wiphy init */
-       ar->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
-                                        BIT(NL80211_IFTYPE_WDS) |
-                                        BIT(NL80211_IFTYPE_ADHOC);
-       ar->hw->flags |= IEEE80211_HW_RX_INCLUDES_FCS |
-                        IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
-                        IEEE80211_HW_SIGNAL_DBM |
-                        IEEE80211_HW_NOISE_DBM;
-
-       ar->hw->queues = __AR9170_NUM_TXQ;
-       ar->hw->extra_tx_headroom = 8;
-       ar->hw->sta_data_size = sizeof(struct ar9170_sta_info);
-
-       ar->hw->max_rates = 1;
-       ar->hw->max_rate_tries = 3;
-
-       for (i = 0; i < ARRAY_SIZE(ar->noise); i++)
-               ar->noise[i] = -95; /* ATH_DEFAULT_NOISE_FLOOR */
-
-       return ar;
-}
-
-static int ar9170_read_eeprom(struct ar9170 *ar)
-{
-#define RW     8       /* number of words to read at once */
-#define RB     (sizeof(u32) * RW)
-       DECLARE_MAC_BUF(mbuf);
-       u8 *eeprom = (void *)&ar->eeprom;
-       u8 *addr = ar->eeprom.mac_address;
-       __le32 offsets[RW];
-       int i, j, err, bands = 0;
-
-       BUILD_BUG_ON(sizeof(ar->eeprom) & 3);
-
-       BUILD_BUG_ON(RB > AR9170_MAX_CMD_LEN - 4);
-#ifndef __CHECKER__
-       /* don't want to handle trailing remains */
-       BUILD_BUG_ON(sizeof(ar->eeprom) % RB);
-#endif
-
-       for (i = 0; i < sizeof(ar->eeprom)/RB; i++) {
-               for (j = 0; j < RW; j++)
-                       offsets[j] = cpu_to_le32(AR9170_EEPROM_START +
-                                                RB * i + 4 * j);
-
-               err = ar->exec_cmd(ar, AR9170_CMD_RREG,
-                                  RB, (u8 *) &offsets,
-                                  RB, eeprom + RB * i);
-               if (err)
-                       return err;
-       }
-
-#undef RW
-#undef RB
-
-       if (ar->eeprom.length == cpu_to_le16(0xFFFF))
-               return -ENODATA;
-
-       if (ar->eeprom.operating_flags & AR9170_OPFLAG_2GHZ) {
-               ar->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &ar9170_band_2GHz;
-               bands++;
-       }
-       if (ar->eeprom.operating_flags & AR9170_OPFLAG_5GHZ) {
-               ar->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &ar9170_band_5GHz;
-               bands++;
-       }
-       /*
-        * I measured this, a bandswitch takes roughly
-        * 135 ms and a frequency switch about 80.
-        *
-        * FIXME: measure these values again once EEPROM settings
-        *        are used, that will influence them!
-        */
-       if (bands == 2)
-               ar->hw->channel_change_time = 135 * 1000;
-       else
-               ar->hw->channel_change_time = 80 * 1000;
-
-       /* second part of wiphy init */
-       SET_IEEE80211_PERM_ADDR(ar->hw, addr);
-
-       return bands ? 0 : -EINVAL;
-}
-
-int ar9170_register(struct ar9170 *ar, struct device *pdev)
-{
-       int err;
-
-       /* try to read EEPROM, init MAC addr */
-       err = ar9170_read_eeprom(ar);
-       if (err)
-               goto err_out;
-
-       err = ieee80211_register_hw(ar->hw);
-       if (err)
-               goto err_out;
-
-       err = ar9170_init_leds(ar);
-       if (err)
-               goto err_unreg;
-
-#ifdef CONFIG_AR9170_LEDS
-       err = ar9170_register_leds(ar);
-       if (err)
-               goto err_unreg;
-#endif /* CONFIG_AR9170_LEDS */
-
-       dev_info(pdev, "Atheros AR9170 is registered as '%s'\n",
-                wiphy_name(ar->hw->wiphy));
-
-       return err;
-
-err_unreg:
-       ieee80211_unregister_hw(ar->hw);
-
-err_out:
-       return err;
-}
-
-void ar9170_unregister(struct ar9170 *ar)
-{
-#ifdef CONFIG_AR9170_LEDS
-       ar9170_unregister_leds(ar);
-#endif /* CONFIG_AR9170_LEDS */
-
-       ieee80211_unregister_hw(ar->hw);
-       mutex_destroy(&ar->mutex);
-}
diff --git a/drivers/net/wireless/ar9170/phy.c b/drivers/net/wireless/ar9170/phy.c
deleted file mode 100644 (file)
index 6ce2075..0000000
+++ /dev/null
@@ -1,1240 +0,0 @@
-/*
- * Atheros AR9170 driver
- *
- * PHY and RF code
- *
- * Copyright 2008, 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 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; see the file COPYING.  If not, see
- * http://www.gnu.org/licenses/.
- *
- * This file incorporates work covered by the following copyright and
- * permission notice:
- *    Copyright (c) 2007-2008 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/bitrev.h>
-#include "ar9170.h"
-#include "cmd.h"
-
-static int ar9170_init_power_cal(struct ar9170 *ar)
-{
-       ar9170_regwrite_begin(ar);
-
-       ar9170_regwrite(0x1bc000 + 0x993c, 0x7f);
-       ar9170_regwrite(0x1bc000 + 0x9934, 0x3f3f3f3f);
-       ar9170_regwrite(0x1bc000 + 0x9938, 0x3f3f3f3f);
-       ar9170_regwrite(0x1bc000 + 0xa234, 0x3f3f3f3f);
-       ar9170_regwrite(0x1bc000 + 0xa238, 0x3f3f3f3f);
-       ar9170_regwrite(0x1bc000 + 0xa38c, 0x3f3f3f3f);
-       ar9170_regwrite(0x1bc000 + 0xa390, 0x3f3f3f3f);
-       ar9170_regwrite(0x1bc000 + 0xa3cc, 0x3f3f3f3f);
-       ar9170_regwrite(0x1bc000 + 0xa3d0, 0x3f3f3f3f);
-       ar9170_regwrite(0x1bc000 + 0xa3d4, 0x3f3f3f3f);
-
-       ar9170_regwrite_finish();
-       return ar9170_regwrite_result();
-}
-
-struct ar9170_phy_init {
-       u32 reg, _5ghz_20, _5ghz_40, _2ghz_40, _2ghz_20;
-};
-
-static struct ar9170_phy_init ar5416_phy_init[] = {
-       { 0x1c5800, 0x00000007, 0x00000007, 0x00000007, 0x00000007, },
-       { 0x1c5804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, },
-       { 0x1c5808, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c580c, 0xad848e19, 0xad848e19, 0xad848e19, 0xad848e19, },
-       { 0x1c5810, 0x7d14e000, 0x7d14e000, 0x7d14e000, 0x7d14e000, },
-       { 0x1c5814, 0x9c0a9f6b, 0x9c0a9f6b, 0x9c0a9f6b, 0x9c0a9f6b, },
-       { 0x1c5818, 0x00000090, 0x00000090, 0x00000090, 0x00000090, },
-       { 0x1c581c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c5820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, },
-       { 0x1c5824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, },
-       { 0x1c5828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, },
-       { 0x1c582c, 0x0000a000, 0x0000a000, 0x0000a000, 0x0000a000, },
-       { 0x1c5830, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c5834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, },
-       { 0x1c5838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, },
-       { 0x1c583c, 0x00200400, 0x00200400, 0x00200400, 0x00200400, },
-       { 0x1c5840, 0x206a002e, 0x206a002e, 0x206a002e, 0x206a002e, },
-       { 0x1c5844, 0x1372161e, 0x13721c1e, 0x13721c24, 0x137216a4, },
-       { 0x1c5848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, },
-       { 0x1c584c, 0x1284233c, 0x1284233c, 0x1284233c, 0x1284233c, },
-       { 0x1c5850, 0x6c48b4e4, 0x6c48b4e4, 0x6c48b0e4, 0x6c48b0e4, },
-       { 0x1c5854, 0x00000859, 0x00000859, 0x00000859, 0x00000859, },
-       { 0x1c5858, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, },
-       { 0x1c585c, 0x31395c5e, 0x31395c5e, 0x31395c5e, 0x31395c5e, },
-       { 0x1c5860, 0x0004dd10, 0x0004dd10, 0x0004dd20, 0x0004dd20, },
-       { 0x1c5868, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190, },
-       { 0x1c586c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, },
-       { 0x1c5900, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c5904, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c5908, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c590c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c5914, 0x000007d0, 0x000007d0, 0x00000898, 0x00000898, },
-       { 0x1c5918, 0x00000118, 0x00000230, 0x00000268, 0x00000134, },
-       { 0x1c591c, 0x10000fff, 0x10000fff, 0x10000fff, 0x10000fff, },
-       { 0x1c5920, 0x0510081c, 0x0510081c, 0x0510001c, 0x0510001c, },
-       { 0x1c5924, 0xd0058a15, 0xd0058a15, 0xd0058a15, 0xd0058a15, },
-       { 0x1c5928, 0x00000001, 0x00000001, 0x00000001, 0x00000001, },
-       { 0x1c592c, 0x00000004, 0x00000004, 0x00000004, 0x00000004, },
-       { 0x1c5934, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
-       { 0x1c5938, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
-       { 0x1c593c, 0x0000007f, 0x0000007f, 0x0000007f, 0x0000007f, },
-       { 0x1c5944, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020, },
-       { 0x1c5948, 0x9280b212, 0x9280b212, 0x9280b212, 0x9280b212, },
-       { 0x1c594c, 0x00020028, 0x00020028, 0x00020028, 0x00020028, },
-       { 0x1c5954, 0x5d50e188, 0x5d50e188, 0x5d50e188, 0x5d50e188, },
-       { 0x1c5958, 0x00081fff, 0x00081fff, 0x00081fff, 0x00081fff, },
-       { 0x1c5960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, },
-       { 0x1c5964, 0x00001120, 0x00001120, 0x00001120, 0x00001120, },
-       { 0x1c5970, 0x190fb515, 0x190fb515, 0x190fb515, 0x190fb515, },
-       { 0x1c5974, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c5978, 0x00000001, 0x00000001, 0x00000001, 0x00000001, },
-       { 0x1c597c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c5980, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c5984, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c5988, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c598c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c5990, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c5994, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c5998, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c599c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c59a0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c59a4, 0x00000007, 0x00000007, 0x00000007, 0x00000007, },
-       { 0x1c59a8, 0x001fff00, 0x001fff00, 0x001fff00, 0x001fff00, },
-       { 0x1c59ac, 0x006f00c4, 0x006f00c4, 0x006f00c4, 0x006f00c4, },
-       { 0x1c59b0, 0x03051000, 0x03051000, 0x03051000, 0x03051000, },
-       { 0x1c59b4, 0x00000820, 0x00000820, 0x00000820, 0x00000820, },
-       { 0x1c59c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, },
-       { 0x1c59c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, },
-       { 0x1c59c8, 0x60f6532c, 0x60f6532c, 0x60f6532c, 0x60f6532c, },
-       { 0x1c59cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, },
-       { 0x1c59d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, },
-       { 0x1c59d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c59d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c59dc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c59e0, 0x00000200, 0x00000200, 0x00000200, 0x00000200, },
-       { 0x1c59e4, 0x64646464, 0x64646464, 0x64646464, 0x64646464, },
-       { 0x1c59e8, 0x3c787878, 0x3c787878, 0x3c787878, 0x3c787878, },
-       { 0x1c59ec, 0x000000aa, 0x000000aa, 0x000000aa, 0x000000aa, },
-       { 0x1c59f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c59fc, 0x00001042, 0x00001042, 0x00001042, 0x00001042, },
-       { 0x1c5a00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c5a04, 0x00000040, 0x00000040, 0x00000040, 0x00000040, },
-       { 0x1c5a08, 0x00000080, 0x00000080, 0x00000080, 0x00000080, },
-       { 0x1c5a0c, 0x000001a1, 0x000001a1, 0x00000141, 0x00000141, },
-       { 0x1c5a10, 0x000001e1, 0x000001e1, 0x00000181, 0x00000181, },
-       { 0x1c5a14, 0x00000021, 0x00000021, 0x000001c1, 0x000001c1, },
-       { 0x1c5a18, 0x00000061, 0x00000061, 0x00000001, 0x00000001, },
-       { 0x1c5a1c, 0x00000168, 0x00000168, 0x00000041, 0x00000041, },
-       { 0x1c5a20, 0x000001a8, 0x000001a8, 0x000001a8, 0x000001a8, },
-       { 0x1c5a24, 0x000001e8, 0x000001e8, 0x000001e8, 0x000001e8, },
-       { 0x1c5a28, 0x00000028, 0x00000028, 0x00000028, 0x00000028, },
-       { 0x1c5a2c, 0x00000068, 0x00000068, 0x00000068, 0x00000068, },
-       { 0x1c5a30, 0x00000189, 0x00000189, 0x000000a8, 0x000000a8, },
-       { 0x1c5a34, 0x000001c9, 0x000001c9, 0x00000169, 0x00000169, },
-       { 0x1c5a38, 0x00000009, 0x00000009, 0x000001a9, 0x000001a9, },
-       { 0x1c5a3c, 0x00000049, 0x00000049, 0x000001e9, 0x000001e9, },
-       { 0x1c5a40, 0x00000089, 0x00000089, 0x00000029, 0x00000029, },
-       { 0x1c5a44, 0x00000170, 0x00000170, 0x00000069, 0x00000069, },
-       { 0x1c5a48, 0x000001b0, 0x000001b0, 0x00000190, 0x00000190, },
-       { 0x1c5a4c, 0x000001f0, 0x000001f0, 0x000001d0, 0x000001d0, },
-       { 0x1c5a50, 0x00000030, 0x00000030, 0x00000010, 0x00000010, },
-       { 0x1c5a54, 0x00000070, 0x00000070, 0x00000050, 0x00000050, },
-       { 0x1c5a58, 0x00000191, 0x00000191, 0x00000090, 0x00000090, },
-       { 0x1c5a5c, 0x000001d1, 0x000001d1, 0x00000151, 0x00000151, },
-       { 0x1c5a60, 0x00000011, 0x00000011, 0x00000191, 0x00000191, },
-       { 0x1c5a64, 0x00000051, 0x00000051, 0x000001d1, 0x000001d1, },
-       { 0x1c5a68, 0x00000091, 0x00000091, 0x00000011, 0x00000011, },
-       { 0x1c5a6c, 0x000001b8, 0x000001b8, 0x00000051, 0x00000051, },
-       { 0x1c5a70, 0x000001f8, 0x000001f8, 0x00000198, 0x00000198, },
-       { 0x1c5a74, 0x00000038, 0x00000038, 0x000001d8, 0x000001d8, },
-       { 0x1c5a78, 0x00000078, 0x00000078, 0x00000018, 0x00000018, },
-       { 0x1c5a7c, 0x00000199, 0x00000199, 0x00000058, 0x00000058, },
-       { 0x1c5a80, 0x000001d9, 0x000001d9, 0x00000098, 0x00000098, },
-       { 0x1c5a84, 0x00000019, 0x00000019, 0x00000159, 0x00000159, },
-       { 0x1c5a88, 0x00000059, 0x00000059, 0x00000199, 0x00000199, },
-       { 0x1c5a8c, 0x00000099, 0x00000099, 0x000001d9, 0x000001d9, },
-       { 0x1c5a90, 0x000000d9, 0x000000d9, 0x00000019, 0x00000019, },
-       { 0x1c5a94, 0x000000f9, 0x000000f9, 0x00000059, 0x00000059, },
-       { 0x1c5a98, 0x000000f9, 0x000000f9, 0x00000099, 0x00000099, },
-       { 0x1c5a9c, 0x000000f9, 0x000000f9, 0x000000d9, 0x000000d9, },
-       { 0x1c5aa0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-       { 0x1c5aa4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-       { 0x1c5aa8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-       { 0x1c5aac, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-       { 0x1c5ab0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-       { 0x1c5ab4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-       { 0x1c5ab8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-       { 0x1c5abc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-       { 0x1c5ac0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-       { 0x1c5ac4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-       { 0x1c5ac8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-       { 0x1c5acc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-       { 0x1c5ad0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-       { 0x1c5ad4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-       { 0x1c5ad8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-       { 0x1c5adc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-       { 0x1c5ae0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-       { 0x1c5ae4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-       { 0x1c5ae8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-       { 0x1c5aec, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-       { 0x1c5af0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-       { 0x1c5af4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-       { 0x1c5af8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-       { 0x1c5afc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-       { 0x1c5b00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c5b04, 0x00000001, 0x00000001, 0x00000001, 0x00000001, },
-       { 0x1c5b08, 0x00000002, 0x00000002, 0x00000002, 0x00000002, },
-       { 0x1c5b0c, 0x00000003, 0x00000003, 0x00000003, 0x00000003, },
-       { 0x1c5b10, 0x00000004, 0x00000004, 0x00000004, 0x00000004, },
-       { 0x1c5b14, 0x00000005, 0x00000005, 0x00000005, 0x00000005, },
-       { 0x1c5b18, 0x00000008, 0x00000008, 0x00000008, 0x00000008, },
-       { 0x1c5b1c, 0x00000009, 0x00000009, 0x00000009, 0x00000009, },
-       { 0x1c5b20, 0x0000000a, 0x0000000a, 0x0000000a, 0x0000000a, },
-       { 0x1c5b24, 0x0000000b, 0x0000000b, 0x0000000b, 0x0000000b, },
-       { 0x1c5b28, 0x0000000c, 0x0000000c, 0x0000000c, 0x0000000c, },
-       { 0x1c5b2c, 0x0000000d, 0x0000000d, 0x0000000d, 0x0000000d, },
-       { 0x1c5b30, 0x00000010, 0x00000010, 0x00000010, 0x00000010, },
-       { 0x1c5b34, 0x00000011, 0x00000011, 0x00000011, 0x00000011, },
-       { 0x1c5b38, 0x00000012, 0x00000012, 0x00000012, 0x00000012, },
-       { 0x1c5b3c, 0x00000013, 0x00000013, 0x00000013, 0x00000013, },
-       { 0x1c5b40, 0x00000014, 0x00000014, 0x00000014, 0x00000014, },
-       { 0x1c5b44, 0x00000015, 0x00000015, 0x00000015, 0x00000015, },
-       { 0x1c5b48, 0x00000018, 0x00000018, 0x00000018, 0x00000018, },
-       { 0x1c5b4c, 0x00000019, 0x00000019, 0x00000019, 0x00000019, },
-       { 0x1c5b50, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a, },
-       { 0x1c5b54, 0x0000001b, 0x0000001b, 0x0000001b, 0x0000001b, },
-       { 0x1c5b58, 0x0000001c, 0x0000001c, 0x0000001c, 0x0000001c, },
-       { 0x1c5b5c, 0x0000001d, 0x0000001d, 0x0000001d, 0x0000001d, },
-       { 0x1c5b60, 0x00000020, 0x00000020, 0x00000020, 0x00000020, },
-       { 0x1c5b64, 0x00000021, 0x00000021, 0x00000021, 0x00000021, },
-       { 0x1c5b68, 0x00000022, 0x00000022, 0x00000022, 0x00000022, },
-       { 0x1c5b6c, 0x00000023, 0x00000023, 0x00000023, 0x00000023, },
-       { 0x1c5b70, 0x00000024, 0x00000024, 0x00000024, 0x00000024, },
-       { 0x1c5b74, 0x00000025, 0x00000025, 0x00000025, 0x00000025, },
-       { 0x1c5b78, 0x00000028, 0x00000028, 0x00000028, 0x00000028, },
-       { 0x1c5b7c, 0x00000029, 0x00000029, 0x00000029, 0x00000029, },
-       { 0x1c5b80, 0x0000002a, 0x0000002a, 0x0000002a, 0x0000002a, },
-       { 0x1c5b84, 0x0000002b, 0x0000002b, 0x0000002b, 0x0000002b, },
-       { 0x1c5b88, 0x0000002c, 0x0000002c, 0x0000002c, 0x0000002c, },
-       { 0x1c5b8c, 0x0000002d, 0x0000002d, 0x0000002d, 0x0000002d, },
-       { 0x1c5b90, 0x00000030, 0x00000030, 0x00000030, 0x00000030, },
-       { 0x1c5b94, 0x00000031, 0x00000031, 0x00000031, 0x00000031, },
-       { 0x1c5b98, 0x00000032, 0x00000032, 0x00000032, 0x00000032, },
-       { 0x1c5b9c, 0x00000033, 0x00000033, 0x00000033, 0x00000033, },
-       { 0x1c5ba0, 0x00000034, 0x00000034, 0x00000034, 0x00000034, },
-       { 0x1c5ba4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
-       { 0x1c5ba8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
-       { 0x1c5bac, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
-       { 0x1c5bb0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
-       { 0x1c5bb4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
-       { 0x1c5bb8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
-       { 0x1c5bbc, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
-       { 0x1c5bc0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
-       { 0x1c5bc4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
-       { 0x1c5bc8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
-       { 0x1c5bcc, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
-       { 0x1c5bd0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
-       { 0x1c5bd4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
-       { 0x1c5bd8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
-       { 0x1c5bdc, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
-       { 0x1c5be0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
-       { 0x1c5be4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
-       { 0x1c5be8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
-       { 0x1c5bec, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
-       { 0x1c5bf0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
-       { 0x1c5bf4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
-       { 0x1c5bf8, 0x00000010, 0x00000010, 0x00000010, 0x00000010, },
-       { 0x1c5bfc, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a, },
-       { 0x1c5c00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c5c0c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c5c10, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c5c14, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c5c18, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c5c1c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c5c20, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c5c24, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c5c28, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c5c2c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c5c30, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c5c34, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c5c38, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c5c3c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c5cf0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c5cf4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c5cf8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c5cfc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c6200, 0x00000008, 0x00000008, 0x0000000e, 0x0000000e, },
-       { 0x1c6204, 0x00000440, 0x00000440, 0x00000440, 0x00000440, },
-       { 0x1c6208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, },
-       { 0x1c620c, 0x012e8160, 0x012e8160, 0x012a8160, 0x012a8160, },
-       { 0x1c6210, 0x40806333, 0x40806333, 0x40806333, 0x40806333, },
-       { 0x1c6214, 0x00106c10, 0x00106c10, 0x00106c10, 0x00106c10, },
-       { 0x1c6218, 0x009c4060, 0x009c4060, 0x009c4060, 0x009c4060, },
-       { 0x1c621c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, },
-       { 0x1c6220, 0x018830c6, 0x018830c6, 0x018830c6, 0x018830c6, },
-       { 0x1c6224, 0x00000400, 0x00000400, 0x00000400, 0x00000400, },
-       { 0x1c6228, 0x000009b5, 0x000009b5, 0x000009b5, 0x000009b5, },
-       { 0x1c622c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c6230, 0x00000108, 0x00000210, 0x00000210, 0x00000108, },
-       { 0x1c6234, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
-       { 0x1c6238, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
-       { 0x1c623c, 0x13c889af, 0x13c889af, 0x13c889af, 0x13c889af, },
-       { 0x1c6240, 0x38490a20, 0x38490a20, 0x38490a20, 0x38490a20, },
-       { 0x1c6244, 0x00007bb6, 0x00007bb6, 0x00007bb6, 0x00007bb6, },
-       { 0x1c6248, 0x0fff3ffc, 0x0fff3ffc, 0x0fff3ffc, 0x0fff3ffc, },
-       { 0x1c624c, 0x00000001, 0x00000001, 0x00000001, 0x00000001, },
-       { 0x1c6250, 0x0000a000, 0x0000a000, 0x0000a000, 0x0000a000, },
-       { 0x1c6254, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c6258, 0x0cc75380, 0x0cc75380, 0x0cc75380, 0x0cc75380, },
-       { 0x1c625c, 0x0f0f0f01, 0x0f0f0f01, 0x0f0f0f01, 0x0f0f0f01, },
-       { 0x1c6260, 0xdfa91f01, 0xdfa91f01, 0xdfa91f01, 0xdfa91f01, },
-       { 0x1c6264, 0x00418a11, 0x00418a11, 0x00418a11, 0x00418a11, },
-       { 0x1c6268, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c626c, 0x09249126, 0x09249126, 0x09249126, 0x09249126, },
-       { 0x1c6274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, },
-       { 0x1c6278, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, },
-       { 0x1c627c, 0x051701ce, 0x051701ce, 0x051701ce, 0x051701ce, },
-       { 0x1c6300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, },
-       { 0x1c6304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, },
-       { 0x1c6308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, },
-       { 0x1c630c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, },
-       { 0x1c6310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, },
-       { 0x1c6314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, },
-       { 0x1c6318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, },
-       { 0x1c631c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, },
-       { 0x1c6320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, },
-       { 0x1c6324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, },
-       { 0x1c6328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, },
-       { 0x1c632c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c6330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c6334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c6338, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c633c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c6340, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c6344, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c6348, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, },
-       { 0x1c634c, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, },
-       { 0x1c6350, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, },
-       { 0x1c6354, 0x0003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff, },
-       { 0x1c6358, 0x79a8aa1f, 0x79a8aa1f, 0x79a8aa1f, 0x79a8aa1f, },
-       { 0x1c6388, 0x08000000, 0x08000000, 0x08000000, 0x08000000, },
-       { 0x1c638c, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
-       { 0x1c6390, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
-       { 0x1c6394, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, },
-       { 0x1c6398, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce, },
-       { 0x1c639c, 0x00000007, 0x00000007, 0x00000007, 0x00000007, },
-       { 0x1c63a0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c63a4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c63a8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c63ac, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c63b0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c63b4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c63b8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c63bc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c63c0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c63c4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c63c8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c63cc, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
-       { 0x1c63d0, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
-       { 0x1c63d4, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
-       { 0x1c63d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-       { 0x1c63dc, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, },
-       { 0x1c63e0, 0x000000c0, 0x000000c0, 0x000000c0, 0x000000c0, },
-       { 0x1c6848, 0x00180a65, 0x00180a65, 0x00180a68, 0x00180a68, },
-       { 0x1c6920, 0x0510001c, 0x0510001c, 0x0510001c, 0x0510001c, },
-       { 0x1c6960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, },
-       { 0x1c720c, 0x012e8160, 0x012e8160, 0x012a8160, 0x012a8160, },
-       { 0x1c726c, 0x09249126, 0x09249126, 0x09249126, 0x09249126, },
-       { 0x1c7848, 0x00180a65, 0x00180a65, 0x00180a68, 0x00180a68, },
-       { 0x1c7920, 0x0510001c, 0x0510001c, 0x0510001c, 0x0510001c, },
-       { 0x1c7960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, },
-       { 0x1c820c, 0x012e8160, 0x012e8160, 0x012a8160, 0x012a8160, },
-       { 0x1c826c, 0x09249126, 0x09249126, 0x09249126, 0x09249126, },
-/*     { 0x1c8864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, }, */
-       { 0x1c8864, 0x0001c600, 0x0001c600, 0x0001c600, 0x0001c600, },
-       { 0x1c895c, 0x004b6a8e, 0x004b6a8e, 0x004b6a8e, 0x004b6a8e, },
-       { 0x1c8968, 0x000003ce, 0x000003ce, 0x000003ce, 0x000003ce, },
-       { 0x1c89bc, 0x00181400, 0x00181400, 0x00181400, 0x00181400, },
-       { 0x1c9270, 0x00820820, 0x00820820, 0x00820820, 0x00820820, },
-       { 0x1c935c, 0x066c420f, 0x066c420f, 0x066c420f, 0x066c420f, },
-       { 0x1c9360, 0x0f282207, 0x0f282207, 0x0f282207, 0x0f282207, },
-       { 0x1c9364, 0x17601685, 0x17601685, 0x17601685, 0x17601685, },
-       { 0x1c9368, 0x1f801104, 0x1f801104, 0x1f801104, 0x1f801104, },
-       { 0x1c936c, 0x37a00c03, 0x37a00c03, 0x37a00c03, 0x37a00c03, },
-       { 0x1c9370, 0x3fc40883, 0x3fc40883, 0x3fc40883, 0x3fc40883, },
-       { 0x1c9374, 0x57c00803, 0x57c00803, 0x57c00803, 0x57c00803, },
-       { 0x1c9378, 0x5fd80682, 0x5fd80682, 0x5fd80682, 0x5fd80682, },
-       { 0x1c937c, 0x7fe00482, 0x7fe00482, 0x7fe00482, 0x7fe00482, },
-       { 0x1c9380, 0x7f3c7bba, 0x7f3c7bba, 0x7f3c7bba, 0x7f3c7bba, },
-       { 0x1c9384, 0xf3307ff0, 0xf3307ff0, 0xf3307ff0, 0xf3307ff0, }
-};
-
-int ar9170_init_phy(struct ar9170 *ar, enum ieee80211_band band)
-{
-       int i, err;
-       u32 val;
-       bool is_2ghz = band == IEEE80211_BAND_2GHZ;
-       bool is_40mhz = false; /* XXX: for now */
-
-       ar9170_regwrite_begin(ar);
-
-       for (i = 0; i < ARRAY_SIZE(ar5416_phy_init); i++) {
-               if (is_40mhz) {
-                       if (is_2ghz)
-                               val = ar5416_phy_init[i]._2ghz_40;
-                       else
-                               val = ar5416_phy_init[i]._5ghz_40;
-               } else {
-                       if (is_2ghz)
-                               val = ar5416_phy_init[i]._2ghz_20;
-                       else
-                               val = ar5416_phy_init[i]._5ghz_20;
-               }
-
-               ar9170_regwrite(ar5416_phy_init[i].reg, val);
-       }
-
-       ar9170_regwrite_finish();
-       err = ar9170_regwrite_result();
-       if (err)
-               return err;
-
-       /* XXX: use EEPROM data here! */
-
-       err = ar9170_init_power_cal(ar);
-       if (err)
-               return err;
-
-       /* XXX: remove magic! */
-       if (is_2ghz)
-               err = ar9170_write_reg(ar, 0x1d4014, 0x5163);
-       else
-               err = ar9170_write_reg(ar, 0x1d4014, 0x5143);
-
-       return err;
-}
-
-struct ar9170_rf_init {
-       u32 reg, _5ghz, _2ghz;
-};
-
-static struct ar9170_rf_init ar9170_rf_init[] = {
-     /* bank 0 */
-     { 0x1c58b0,  0x1e5795e5,  0x1e5795e5},
-     { 0x1c58e0,  0x02008020,  0x02008020},
-     /* bank 1 */
-     { 0x1c58b0,  0x02108421,  0x02108421},
-     { 0x1c58ec,  0x00000008,  0x00000008},
-     /* bank 2 */
-     { 0x1c58b0,  0x0e73ff17,  0x0e73ff17},
-     { 0x1c58e0,  0x00000420,  0x00000420},
-     /* bank 3 */
-     { 0x1c58f0,  0x01400018,  0x01c00018},
-     /* bank 4 */
-     { 0x1c58b0,  0x000001a1,  0x000001a1},
-     { 0x1c58e8,  0x00000001,  0x00000001},
-     /* bank 5 */
-     { 0x1c58b0,  0x00000013,  0x00000013},
-     { 0x1c58e4,  0x00000002,  0x00000002},
-     /* bank 6 */
-     { 0x1c58b0,  0x00000000,  0x00000000},
-     { 0x1c58b0,  0x00000000,  0x00000000},
-     { 0x1c58b0,  0x00000000,  0x00000000},
-     { 0x1c58b0,  0x00000000,  0x00000000},
-     { 0x1c58b0,  0x00000000,  0x00000000},
-     { 0x1c58b0,  0x00004000,  0x00004000},
-     { 0x1c58b0,  0x00006c00,  0x00006c00},
-     { 0x1c58b0,  0x00002c00,  0x00002c00},
-     { 0x1c58b0,  0x00004800,  0x00004800},
-     { 0x1c58b0,  0x00004000,  0x00004000},
-     { 0x1c58b0,  0x00006000,  0x00006000},
-     { 0x1c58b0,  0x00001000,  0x00001000},
-     { 0x1c58b0,  0x00004000,  0x00004000},
-     { 0x1c58b0,  0x00007c00,  0x00007c00},
-     { 0x1c58b0,  0x00007c00,  0x00007c00},
-     { 0x1c58b0,  0x00007c00,  0x00007c00},
-     { 0x1c58b0,  0x00007c00,  0x00007c00},
-     { 0x1c58b0,  0x00007c00,  0x00007c00},
-     { 0x1c58b0,  0x00087c00,  0x00087c00},
-     { 0x1c58b0,  0x00007c00,  0x00007c00},
-     { 0x1c58b0,  0x00005400,  0x00005400},
-     { 0x1c58b0,  0x00000c00,  0x00000c00},
-     { 0x1c58b0,  0x00001800,  0x00001800},
-     { 0x1c58b0,  0x00007c00,  0x00007c00},
-     { 0x1c58b0,  0x00006c00,  0x00006c00},
-     { 0x1c58b0,  0x00006c00,  0x00006c00},
-     { 0x1c58b0,  0x00007c00,  0x00007c00},
-     { 0x1c58b0,  0x00002c00,  0x00002c00},
-     { 0x1c58b0,  0x00003c00,  0x00003c00},
-     { 0x1c58b0,  0x00003800,  0x00003800},
-     { 0x1c58b0,  0x00001c00,  0x00001c00},
-     { 0x1c58b0,  0x00000800,  0x00000800},
-     { 0x1c58b0,  0x00000408,  0x00000408},
-     { 0x1c58b0,  0x00004c15,  0x00004c15},
-     { 0x1c58b0,  0x00004188,  0x00004188},
-     { 0x1c58b0,  0x0000201e,  0x0000201e},
-     { 0x1c58b0,  0x00010408,  0x00010408},
-     { 0x1c58b0,  0x00000801,  0x00000801},
-     { 0x1c58b0,  0x00000c08,  0x00000c08},
-     { 0x1c58b0,  0x0000181e,  0x0000181e},
-     { 0x1c58b0,  0x00001016,  0x00001016},
-     { 0x1c58b0,  0x00002800,  0x00002800},
-     { 0x1c58b0,  0x00004010,  0x00004010},
-     { 0x1c58b0,  0x0000081c,  0x0000081c},
-     { 0x1c58b0,  0x00000115,  0x00000115},
-     { 0x1c58b0,  0x00000015,  0x00000015},
-     { 0x1c58b0,  0x00000066,  0x00000066},
-     { 0x1c58b0,  0x0000001c,  0x0000001c},
-     { 0x1c58b0,  0x00000000,  0x00000000},
-     { 0x1c58b0,  0x00000004,  0x00000004},
-     { 0x1c58b0,  0x00000015,  0x00000015},
-     { 0x1c58b0,  0x0000001f,  0x0000001f},
-     { 0x1c58e0,  0x00000000,  0x00000400},
-     /* bank 7 */
-     { 0x1c58b0,  0x000000a0,  0x000000a0},
-     { 0x1c58b0,  0x00000000,  0x00000000},
-     { 0x1c58b0,  0x00000040,  0x00000040},
-     { 0x1c58f0,  0x0000001c,  0x0000001c},
-};
-
-static int ar9170_init_rf_banks_0_7(struct ar9170 *ar, bool band5ghz)
-{
-       int err, i;
-
-       ar9170_regwrite_begin(ar);
-
-       for (i = 0; i < ARRAY_SIZE(ar9170_rf_init); i++)
-               ar9170_regwrite(ar9170_rf_init[i].reg,
-                               band5ghz ? ar9170_rf_init[i]._5ghz
-                                        : ar9170_rf_init[i]._2ghz);
-
-       ar9170_regwrite_finish();
-       err = ar9170_regwrite_result();
-       if (err)
-               printk(KERN_ERR "%s: rf init failed\n",
-                      wiphy_name(ar->hw->wiphy));
-       return err;
-}
-
-static int ar9170_init_rf_bank4_pwr(struct ar9170 *ar, bool band5ghz,
-                                   u32 freq, enum ar9170_bw bw)
-{
-       int err;
-       u32 d0, d1, td0, td1, fd0, fd1;
-       u8 chansel;
-       u8 refsel0 = 1, refsel1 = 0;
-       u8 lf_synth = 0;
-
-       switch (bw) {
-       case AR9170_BW_40_ABOVE:
-               freq += 10;
-               break;
-       case AR9170_BW_40_BELOW:
-               freq -= 10;
-               break;
-       case AR9170_BW_20:
-               break;
-       case __AR9170_NUM_BW:
-               BUG();
-       }
-
-       if (band5ghz) {
-               if (freq % 10) {
-                       chansel = (freq - 4800) / 5;
-               } else {
-                       chansel = ((freq - 4800) / 10) * 2;
-                       refsel0 = 0;
-                       refsel1 = 1;
-               }
-               chansel = byte_rev_table[chansel];
-       } else {
-               if (freq == 2484) {
-                       chansel = 10 + (freq - 2274) / 5;
-                       lf_synth = 1;
-               } else
-                       chansel = 16 + (freq - 2272) / 5;
-               chansel *= 4;
-               chansel = byte_rev_table[chansel];
-       }
-
-       d1 =    chansel;
-       d0 =    0x21 |
-               refsel0 << 3 |
-               refsel1 << 2 |
-               lf_synth << 1;
-       td0 =   d0 & 0x1f;
-       td1 =   d1 & 0x1f;
-       fd0 =   td1 << 5 | td0;
-
-       td0 =   (d0 >> 5) & 0x7;
-       td1 =   (d1 >> 5) & 0x7;
-       fd1 =   td1 << 5 | td0;
-
-       ar9170_regwrite_begin(ar);
-
-       ar9170_regwrite(0x1c58b0, fd0);
-       ar9170_regwrite(0x1c58e8, fd1);
-
-       ar9170_regwrite_finish();
-       err = ar9170_regwrite_result();
-       if (err)
-               return err;
-
-       msleep(10);
-
-       return 0;
-}
-
-struct ar9170_phy_freq_params {
-       u8 coeff_exp;
-       u16 coeff_man;
-       u8 coeff_exp_shgi;
-       u16 coeff_man_shgi;
-};
-
-struct ar9170_phy_freq_entry {
-       u16 freq;
-       struct ar9170_phy_freq_params params[__AR9170_NUM_BW];
-};
-
-/* NB: must be in sync with channel tables in main! */
-static const struct ar9170_phy_freq_entry ar9170_phy_freq_params[] = {
-/*
- *     freq,
- *             20MHz,
- *             40MHz (below),
- *             40Mhz (above),
- */
-       { 2412, {
-               { 3, 21737, 3, 19563, },
-               { 3, 21827, 3, 19644, },
-               { 3, 21647, 3, 19482, },
-       } },
-       { 2417, {
-               { 3, 21692, 3, 19523, },
-               { 3, 21782, 3, 19604, },
-               { 3, 21602, 3, 19442, },
-       } },
-       { 2422, {
-               { 3, 21647, 3, 19482, },
-               { 3, 21737, 3, 19563, },
-               { 3, 21558, 3, 19402, },
-       } },
-       { 2427, {
-               { 3, 21602, 3, 19442, },
-               { 3, 21692, 3, 19523, },
-               { 3, 21514, 3, 19362, },
-       } },
-       { 2432, {
-               { 3, 21558, 3, 19402, },
-               { 3, 21647, 3, 19482, },
-               { 3, 21470, 3, 19323, },
-       } },
-       { 2437, {
-               { 3, 21514, 3, 19362, },
-               { 3, 21602, 3, 19442, },
-               { 3, 21426, 3, 19283, },
-       } },
-       { 2442, {
-               { 3, 21470, 3, 19323, },
-               { 3, 21558, 3, 19402, },
-               { 3, 21382, 3, 19244, },
-       } },
-       { 2447, {
-               { 3, 21426, 3, 19283, },
-               { 3, 21514, 3, 19362, },
-               { 3, 21339, 3, 19205, },
-       } },
-       { 2452, {
-               { 3, 21382, 3, 19244, },
-               { 3, 21470, 3, 19323, },
-               { 3, 21295, 3, 19166, },
-       } },
-       { 2457, {
-               { 3, 21339, 3, 19205, },
-               { 3, 21426, 3, 19283, },
-               { 3, 21252, 3, 19127, },
-       } },
-       { 2462, {
-               { 3, 21295, 3, 19166, },
-               { 3, 21382, 3, 19244, },
-               { 3, 21209, 3, 19088, },
-       } },
-       { 2467, {
-               { 3, 21252, 3, 19127, },
-               { 3, 21339, 3, 19205, },
-               { 3, 21166, 3, 19050, },
-       } },
-       { 2472, {
-               { 3, 21209, 3, 19088, },
-               { 3, 21295, 3, 19166, },
-               { 3, 21124, 3, 19011, },
-       } },
-       { 2484, {
-               { 3, 21107, 3, 18996, },
-               { 3, 21192, 3, 19073, },
-               { 3, 21022, 3, 18920, },
-       } },
-       { 4920, {
-               { 4, 21313, 4, 19181, },
-               { 4, 21356, 4, 19220, },
-               { 4, 21269, 4, 19142, },
-       } },
-       { 4940, {
-               { 4, 21226, 4, 19104, },
-               { 4, 21269, 4, 19142, },
-               { 4, 21183, 4, 19065, },
-       } },
-       { 4960, {
-               { 4, 21141, 4, 19027, },
-               { 4, 21183, 4, 19065, },
-               { 4, 21098, 4, 18988, },
-       } },
-       { 4980, {
-               { 4, 21056, 4, 18950, },
-               { 4, 21098, 4, 18988, },
-               { 4, 21014, 4, 18912, },
-       } },
-       { 5040, {
-               { 4, 20805, 4, 18725, },
-               { 4, 20846, 4, 18762, },
-               { 4, 20764, 4, 18687, },
-       } },
-       { 5060, {
-               { 4, 20723, 4, 18651, },
-               { 4, 20764, 4, 18687, },
-               { 4, 20682, 4, 18614, },
-       } },
-       { 5080, {
-               { 4, 20641, 4, 18577, },
-               { 4, 20682, 4, 18614, },
-               { 4, 20601, 4, 18541, },
-       } },
-       { 5180, {
-               { 4, 20243, 4, 18219, },
-               { 4, 20282, 4, 18254, },
-               { 4, 20204, 4, 18183, },
-       } },
-       { 5200, {
-               { 4, 20165, 4, 18148, },
-               { 4, 20204, 4, 18183, },
-               { 4, 20126, 4, 18114, },
-       } },
-       { 5220, {
-               { 4, 20088, 4, 18079, },
-               { 4, 20126, 4, 18114, },
-               { 4, 20049, 4, 18044, },
-       } },
-       { 5240, {
-               { 4, 20011, 4, 18010, },
-               { 4, 20049, 4, 18044, },
-               { 4, 19973, 4, 17976, },
-       } },
-       { 5260, {
-               { 4, 19935, 4, 17941, },
-               { 4, 19973, 4, 17976, },
-               { 4, 19897, 4, 17907, },
-       } },
-       { 5280, {
-               { 4, 19859, 4, 17873, },
-               { 4, 19897, 4, 17907, },
-               { 4, 19822, 4, 17840, },
-       } },
-       { 5300, {
-               { 4, 19784, 4, 17806, },
-               { 4, 19822, 4, 17840, },
-               { 4, 19747, 4, 17772, },
-       } },
-       { 5320, {
-               { 4, 19710, 4, 17739, },
-               { 4, 19747, 4, 17772, },
-               { 4, 19673, 4, 17706, },
-       } },
-       { 5500, {
-               { 4, 19065, 4, 17159, },
-               { 4, 19100, 4, 17190, },
-               { 4, 19030, 4, 17127, },
-       } },
-       { 5520, {
-               { 4, 18996, 4, 17096, },
-               { 4, 19030, 4, 17127, },
-               { 4, 18962, 4, 17065, },
-       } },
-       { 5540, {
-               { 4, 18927, 4, 17035, },
-               { 4, 18962, 4, 17065, },
-               { 4, 18893, 4, 17004, },
-       } },
-       { 5560, {
-               { 4, 18859, 4, 16973, },
-               { 4, 18893, 4, 17004, },
-               { 4, 18825, 4, 16943, },
-       } },
-       { 5580, {
-               { 4, 18792, 4, 16913, },
-               { 4, 18825, 4, 16943, },
-               { 4, 18758, 4, 16882, },
-       } },
-       { 5600, {
-               { 4, 18725, 4, 16852, },
-               { 4, 18758, 4, 16882, },
-               { 4, 18691, 4, 16822, },
-       } },
-       { 5620, {
-               { 4, 18658, 4, 16792, },
-               { 4, 18691, 4, 16822, },
-               { 4, 18625, 4, 16762, },
-       } },
-       { 5640, {
-               { 4, 18592, 4, 16733, },
-               { 4, 18625, 4, 16762, },
-               { 4, 18559, 4, 16703, },
-       } },
-       { 5660, {
-               { 4, 18526, 4, 16673, },
-               { 4, 18559, 4, 16703, },
-               { 4, 18493, 4, 16644, },
-       } },
-       { 5680, {
-               { 4, 18461, 4, 16615, },
-               { 4, 18493, 4, 16644, },
-               { 4, 18428, 4, 16586, },
-       } },
-       { 5700, {
-               { 4, 18396, 4, 16556, },
-               { 4, 18428, 4, 16586, },
-               { 4, 18364, 4, 16527, },
-       } },
-       { 5745, {
-               { 4, 18252, 4, 16427, },
-               { 4, 18284, 4, 16455, },
-               { 4, 18220, 4, 16398, },
-       } },
-       { 5765, {
-               { 4, 18189, 5, 32740, },
-               { 4, 18220, 4, 16398, },
-               { 4, 18157, 5, 32683, },
-       } },
-       { 5785, {
-               { 4, 18126, 5, 32626, },
-               { 4, 18157, 5, 32683, },
-               { 4, 18094, 5, 32570, },
-       } },
-       { 5805, {
-               { 4, 18063, 5, 32514, },
-               { 4, 18094, 5, 32570, },
-               { 4, 18032, 5, 32458, },
-       } },
-       { 5825, {
-               { 4, 18001, 5, 32402, },
-               { 4, 18032, 5, 32458, },
-               { 4, 17970, 5, 32347, },
-       } },
-       { 5170, {
-               { 4, 20282, 4, 18254, },
-               { 4, 20321, 4, 18289, },
-               { 4, 20243, 4, 18219, },
-       } },
-       { 5190, {
-               { 4, 20204, 4, 18183, },
-               { 4, 20243, 4, 18219, },
-               { 4, 20165, 4, 18148, },
-       } },
-       { 5210, {
-               { 4, 20126, 4, 18114, },
-               { 4, 20165, 4, 18148, },
-               { 4, 20088, 4, 18079, },
-       } },
-       { 5230, {
-               { 4, 20049, 4, 18044, },
-               { 4, 20088, 4, 18079, },
-               { 4, 20011, 4, 18010, },
-       } },
-};
-
-static const struct ar9170_phy_freq_params *
-ar9170_get_hw_dyn_params(struct ieee80211_channel *channel,
-                        enum ar9170_bw bw)
-{
-       unsigned int chanidx = 0;
-       u16 freq = 2412;
-
-       if (channel) {
-               chanidx = channel->hw_value;
-               freq = channel->center_freq;
-       }
-
-       BUG_ON(chanidx >= ARRAY_SIZE(ar9170_phy_freq_params));
-
-       BUILD_BUG_ON(__AR9170_NUM_BW != 3);
-
-       WARN_ON(ar9170_phy_freq_params[chanidx].freq != freq);
-
-       return &ar9170_phy_freq_params[chanidx].params[bw];
-}
-
-
-int ar9170_init_rf(struct ar9170 *ar)
-{
-       const struct ar9170_phy_freq_params *freqpar;
-       __le32 cmd[7];
-       int err;
-
-       err = ar9170_init_rf_banks_0_7(ar, false);
-       if (err)
-               return err;
-
-       err = ar9170_init_rf_bank4_pwr(ar, false, 2412, AR9170_BW_20);
-       if (err)
-               return err;
-
-       freqpar = ar9170_get_hw_dyn_params(NULL, AR9170_BW_20);
-
-       cmd[0] = cpu_to_le32(2412 * 1000);
-       cmd[1] = cpu_to_le32(0);
-       cmd[2] = cpu_to_le32(1);
-       cmd[3] = cpu_to_le32(freqpar->coeff_exp);
-       cmd[4] = cpu_to_le32(freqpar->coeff_man);
-       cmd[5] = cpu_to_le32(freqpar->coeff_exp_shgi);
-       cmd[6] = cpu_to_le32(freqpar->coeff_man_shgi);
-
-       /* RF_INIT echoes the command back to us */
-       err = ar->exec_cmd(ar, AR9170_CMD_RF_INIT,
-                          sizeof(cmd), (u8 *)cmd,
-                          sizeof(cmd), (u8 *)cmd);
-       if (err)
-               return err;
-
-       msleep(1000);
-
-       return ar9170_echo_test(ar, 0xaabbccdd);
-}
-
-static int ar9170_find_freq_idx(int nfreqs, u8 *freqs, u8 f)
-{
-       int idx = nfreqs - 2;
-
-       while (idx >= 0) {
-               if (f >= freqs[idx])
-                       return idx;
-               idx--;
-       }
-
-       return 0;
-}
-
-static s32 ar9170_interpolate_s32(s32 x, s32 x1, s32 y1, s32 x2, s32 y2)
-{
-       /* nothing to interpolate, it's horizontal */
-       if (y2 == y1)
-               return y1;
-
-       /* check if we hit one of the edges */
-       if (x == x1)
-               return y1;
-       if (x == x2)
-               return y2;
-
-       /* x1 == x2 is bad, hopefully == x */
-       if (x2 == x1)
-               return y1;
-
-       return y1 + (((y2 - y1) * (x - x1)) / (x2 - x1));
-}
-
-static u8 ar9170_interpolate_u8(u8 x, u8 x1, u8 y1, u8 x2, u8 y2)
-{
-#define SHIFT          8
-       s32 y;
-
-       y = ar9170_interpolate_s32(x << SHIFT,
-                                  x1 << SHIFT, y1 << SHIFT,
-                                  x2 << SHIFT, y2 << SHIFT);
-
-       /*
-        * XXX: unwrap this expression
-        *      Isn't it just DIV_ROUND_UP(y, 1<<SHIFT)?
-        *      Can we rely on the compiler to optimise away the div?
-        */
-       return (y >> SHIFT) + ((y & (1<<(SHIFT-1))) >> (SHIFT - 1));
-#undef SHIFT
-}
-
-static int ar9170_set_power_cal(struct ar9170 *ar, u32 freq, enum ar9170_bw bw)
-{
-       struct ar9170_calibration_target_power_legacy *ctpl;
-       struct ar9170_calibration_target_power_ht *ctph;
-       u8 *ctpres;
-       int ntargets;
-       int idx, i, n;
-       u8 ackpower, ackchains, f;
-       u8 pwr_freqs[AR5416_MAX_NUM_TGT_PWRS];
-
-       if (freq < 3000)
-               f = freq - 2300;
-       else
-               f = (freq - 4800)/5;
-
-       /*
-        * cycle through the various modes
-        *
-        * legacy modes first: 5G, 2G CCK, 2G OFDM
-        */
-       for (i = 0; i < 3; i++) {
-               switch (i) {
-               case 0: /* 5 GHz legacy */
-                       ctpl = &ar->eeprom.cal_tgt_pwr_5G[0];
-                       ntargets = AR5416_NUM_5G_TARGET_PWRS;
-                       ctpres = ar->power_5G_leg;
-                       break;
-               case 1: /* 2.4 GHz CCK */
-                       ctpl = &ar->eeprom.cal_tgt_pwr_2G_cck[0];
-                       ntargets = AR5416_NUM_2G_CCK_TARGET_PWRS;
-                       ctpres = ar->power_2G_cck;
-                       break;
-               case 2: /* 2.4 GHz OFDM */
-                       ctpl = &ar->eeprom.cal_tgt_pwr_2G_ofdm[0];
-                       ntargets = AR5416_NUM_2G_OFDM_TARGET_PWRS;
-                       ctpres = ar->power_2G_ofdm;
-                       break;
-               default:
-                       BUG();
-               }
-
-               for (n = 0; n < ntargets; n++) {
-                       if (ctpl[n].freq == 0xff)
-                               break;
-                       pwr_freqs[n] = ctpl[n].freq;
-               }
-               ntargets = n;
-               idx = ar9170_find_freq_idx(ntargets, pwr_freqs, f);
-               for (n = 0; n < 4; n++)
-                       ctpres[n] = ar9170_interpolate_u8(
-                                       f,
-                                       ctpl[idx + 0].freq,
-                                       ctpl[idx + 0].power[n],
-                                       ctpl[idx + 1].freq,
-                                       ctpl[idx + 1].power[n]);
-       }
-
-       /*
-        * HT modes now: 5G HT20, 5G HT40, 2G CCK, 2G OFDM, 2G HT20, 2G HT40
-        */
-       for (i = 0; i < 4; i++) {
-               switch (i) {
-               case 0: /* 5 GHz HT 20 */
-                       ctph = &ar->eeprom.cal_tgt_pwr_5G_ht20[0];
-                       ntargets = AR5416_NUM_5G_TARGET_PWRS;
-                       ctpres = ar->power_5G_ht20;
-                       break;
-               case 1: /* 5 GHz HT 40 */
-                       ctph = &ar->eeprom.cal_tgt_pwr_5G_ht40[0];
-                       ntargets = AR5416_NUM_5G_TARGET_PWRS;
-                       ctpres = ar->power_5G_ht40;
-                       break;
-               case 2: /* 2.4 GHz HT 20 */
-                       ctph = &ar->eeprom.cal_tgt_pwr_2G_ht20[0];
-                       ntargets = AR5416_NUM_2G_OFDM_TARGET_PWRS;
-                       ctpres = ar->power_2G_ht20;
-                       break;
-               case 3: /* 2.4 GHz HT 40 */
-                       ctph = &ar->eeprom.cal_tgt_pwr_2G_ht40[0];
-                       ntargets = AR5416_NUM_2G_OFDM_TARGET_PWRS;
-                       ctpres = ar->power_2G_ht40;
-                       break;
-               default:
-                       BUG();
-               }
-
-               for (n = 0; n < ntargets; n++) {
-                       if (ctph[n].freq == 0xff)
-                               break;
-                       pwr_freqs[n] = ctph[n].freq;
-               }
-               ntargets = n;
-               idx = ar9170_find_freq_idx(ntargets, pwr_freqs, f);
-               for (n = 0; n < 8; n++)
-                       ctpres[n] = ar9170_interpolate_u8(
-                                       f,
-                                       ctph[idx + 0].freq,
-                                       ctph[idx + 0].power[n],
-                                       ctph[idx + 1].freq,
-                                       ctph[idx + 1].power[n]);
-       }
-
-       /* set ACK/CTS TX power */
-       ar9170_regwrite_begin(ar);
-
-       if (ar->eeprom.tx_mask != 1)
-               ackchains = AR9170_TX_PHY_TXCHAIN_2;
-       else
-               ackchains = AR9170_TX_PHY_TXCHAIN_1;
-
-       if (freq < 3000)
-               ackpower = ar->power_2G_ofdm[0] & 0x3f;
-       else
-               ackpower = ar->power_5G_leg[0] & 0x3f;
-
-       ar9170_regwrite(0x1c3694, ackpower << 20 | ackchains << 26);
-       ar9170_regwrite(0x1c3bb4, ackpower << 5 | ackchains << 11 |
-                                 ackpower << 21 | ackchains << 27);
-
-       ar9170_regwrite_finish();
-       return ar9170_regwrite_result();
-}
-
-static int ar9170_calc_noise_dbm(u32 raw_noise)
-{
-       if (raw_noise & 0x100)
-               return ~((raw_noise & 0x0ff) >> 1);
-       else
-               return (raw_noise & 0xff) >> 1;
-}
-
-int ar9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
-                      enum ar9170_rf_init_mode rfi, enum ar9170_bw bw)
-{
-       const struct ar9170_phy_freq_params *freqpar;
-       u32 cmd, tmp, offs;
-       __le32 vals[8];
-       int i, err;
-       bool bandswitch;
-
-       /* clear BB heavy clip enable */
-       err = ar9170_write_reg(ar, 0x1c59e0, 0x200);
-       if (err)
-               return err;
-
-       /* may be NULL at first setup */
-       if (ar->channel)
-               bandswitch = ar->channel->band != channel->band;
-       else
-               bandswitch = true;
-
-       /* HW workaround */
-       if (!ar->hw->wiphy->bands[IEEE80211_BAND_5GHZ] &&
-           channel->center_freq <= 2417)
-               bandswitch = true;
-
-       err = ar->exec_cmd(ar, AR9170_CMD_FREQ_START, 0, NULL, 0, NULL);
-       if (err)
-               return err;
-
-       if (rfi != AR9170_RFI_NONE || bandswitch) {
-               u32 val = 0x400;
-
-               if (rfi == AR9170_RFI_COLD)
-                       val = 0x800;
-
-               /* warm/cold reset BB/ADDA */
-               err = ar9170_write_reg(ar, 0x1d4004, val);
-               if (err)
-                       return err;
-
-               err = ar9170_write_reg(ar, 0x1d4004, 0x0);
-               if (err)
-                       return err;
-
-               err = ar9170_init_phy(ar, channel->band);
-               if (err)
-                       return err;
-
-               err = ar9170_init_rf_banks_0_7(ar,
-                       channel->band == IEEE80211_BAND_5GHZ);
-               if (err)
-                       return err;
-
-               cmd = AR9170_CMD_RF_INIT;
-       } else {
-               cmd = AR9170_CMD_FREQUENCY;
-       }
-
-       err = ar9170_init_rf_bank4_pwr(ar,
-               channel->band == IEEE80211_BAND_5GHZ,
-               channel->center_freq, bw);
-       if (err)
-               return err;
-
-       switch (bw) {
-       case AR9170_BW_20:
-               tmp = 0x240;
-               offs = 0;
-               break;
-       case AR9170_BW_40_BELOW:
-               tmp = 0x2c4;
-               offs = 3;
-               break;
-       case AR9170_BW_40_ABOVE:
-               tmp = 0x2d4;
-               offs = 1;
-               break;
-       default:
-               BUG();
-               return -ENOSYS;
-       }
-
-       if (0 /* 2 streams capable */)
-               tmp |= 0x100;
-
-       err = ar9170_write_reg(ar, 0x1c5804, tmp);
-       if (err)
-               return err;
-
-       err = ar9170_set_power_cal(ar, channel->center_freq, bw);
-       if (err)
-               return err;
-
-       freqpar = ar9170_get_hw_dyn_params(channel, bw);
-
-       vals[0] = cpu_to_le32(channel->center_freq * 1000);
-       vals[1] = cpu_to_le32(bw == AR9170_BW_20 ? 0 : 1);
-       vals[2] = cpu_to_le32(offs << 2 | 1);
-       vals[3] = cpu_to_le32(freqpar->coeff_exp);
-       vals[4] = cpu_to_le32(freqpar->coeff_man);
-       vals[5] = cpu_to_le32(freqpar->coeff_exp_shgi);
-       vals[6] = cpu_to_le32(freqpar->coeff_man_shgi);
-       vals[7] = cpu_to_le32(1000);
-
-       err = ar->exec_cmd(ar, cmd, sizeof(vals), (u8 *)vals,
-                          sizeof(vals), (u8 *)vals);
-       if (err)
-               return err;
-
-       for (i = 0; i < 2; i++) {
-               ar->noise[i] = ar9170_calc_noise_dbm(
-                               (le32_to_cpu(vals[2 + i]) >> 19) & 0x1ff);
-
-               ar->noise[i + 2] = ar9170_calc_noise_dbm(
-                                   (le32_to_cpu(vals[5 + i]) >> 23) & 0x1ff);
-       }
-
-       ar->channel = channel;
-       return 0;
-}
diff --git a/drivers/net/wireless/ar9170/usb.c b/drivers/net/wireless/ar9170/usb.c
deleted file mode 100644 (file)
index fddda47..0000000
+++ /dev/null
@@ -1,822 +0,0 @@
-/*
- * Atheros AR9170 driver
- *
- * USB - frontend
- *
- * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
- * Copyright 2009, Christian Lamparter <chunkeey@web.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.
- *
- * 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; see the file COPYING.  If not, see
- * http://www.gnu.org/licenses/.
- *
- * This file incorporates work covered by the following copyright and
- * permission notice:
- *    Copyright (c) 2007-2008 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/module.h>
-#include <linux/usb.h>
-#include <linux/firmware.h>
-#include <linux/etherdevice.h>
-#include <net/mac80211.h>
-#include "ar9170.h"
-#include "cmd.h"
-#include "hw.h"
-#include "usb.h"
-
-MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
-MODULE_AUTHOR("Christian Lamparter <chunkeey@web.de>");
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Atheros AR9170 802.11n USB wireless");
-MODULE_FIRMWARE("ar9170-1.fw");
-MODULE_FIRMWARE("ar9170-2.fw");
-
-static struct usb_device_id ar9170_usb_ids[] = {
-       /* Atheros 9170 */
-       { USB_DEVICE(0x0cf3, 0x9170) },
-       /* Atheros TG121N */
-       { USB_DEVICE(0x0cf3, 0x1001) },
-       /* Cace Airpcap NX */
-       { USB_DEVICE(0xcace, 0x0300) },
-       /* D-Link DWA 160A */
-       { USB_DEVICE(0x07d1, 0x3c10) },
-       /* Netgear WNDA3100 */
-       { USB_DEVICE(0x0846, 0x9010) },
-       /* Netgear WN111 v2 */
-       { USB_DEVICE(0x0846, 0x9001) },
-       /* Zydas ZD1221 */
-       { USB_DEVICE(0x0ace, 0x1221) },
-       /* ZyXEL NWD271N */
-       { USB_DEVICE(0x0586, 0x3417) },
-       /* Z-Com UB81 BG */
-       { USB_DEVICE(0x0cde, 0x0023) },
-       /* Z-Com UB82 ABG */
-       { USB_DEVICE(0x0cde, 0x0026) },
-       /* Arcadyan WN7512 */
-       { USB_DEVICE(0x083a, 0xf522) },
-       /* Planex GWUS300 */
-       { USB_DEVICE(0x2019, 0x5304) },
-       /* IO-Data WNGDNUS2 */
-       { USB_DEVICE(0x04bb, 0x093f) },
-
-       /* terminate */
-       {}
-};
-MODULE_DEVICE_TABLE(usb, ar9170_usb_ids);
-
-static void ar9170_usb_tx_urb_complete_free(struct urb *urb)
-{
-       struct sk_buff *skb = urb->context;
-       struct ar9170_usb *aru = (struct ar9170_usb *)
-             usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
-
-       if (!aru) {
-               dev_kfree_skb_irq(skb);
-               return ;
-       }
-
-       ar9170_handle_tx_status(&aru->common, skb, false,
-                               AR9170_TX_STATUS_COMPLETE);
-}
-
-static void ar9170_usb_tx_urb_complete(struct urb *urb)
-{
-}
-
-static void ar9170_usb_irq_completed(struct urb *urb)
-{
-       struct ar9170_usb *aru = urb->context;
-
-       switch (urb->status) {
-       /* everything is fine */
-       case 0:
-               break;
-
-       /* disconnect */
-       case -ENOENT:
-       case -ECONNRESET:
-       case -ENODEV:
-       case -ESHUTDOWN:
-               goto free;
-
-       default:
-               goto resubmit;
-       }
-
-       print_hex_dump_bytes("ar9170 irq: ", DUMP_PREFIX_OFFSET,
-                            urb->transfer_buffer, urb->actual_length);
-
-resubmit:
-       usb_anchor_urb(urb, &aru->rx_submitted);
-       if (usb_submit_urb(urb, GFP_ATOMIC)) {
-               usb_unanchor_urb(urb);
-               goto free;
-       }
-
-       return;
-
-free:
-       usb_buffer_free(aru->udev, 64, urb->transfer_buffer, urb->transfer_dma);
-}
-
-static void ar9170_usb_rx_completed(struct urb *urb)
-{
-       struct sk_buff *skb = urb->context;
-       struct ar9170_usb *aru = (struct ar9170_usb *)
-               usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
-       int err;
-
-       if (!aru)
-               goto free;
-
-       switch (urb->status) {
-       /* everything is fine */
-       case 0:
-               break;
-
-       /* disconnect */
-       case -ENOENT:
-       case -ECONNRESET:
-       case -ENODEV:
-       case -ESHUTDOWN:
-               goto free;
-
-       default:
-               goto resubmit;
-       }
-
-       skb_put(skb, urb->actual_length);
-       ar9170_rx(&aru->common, skb);
-
-resubmit:
-       skb_reset_tail_pointer(skb);
-       skb_trim(skb, 0);
-
-       usb_anchor_urb(urb, &aru->rx_submitted);
-       err = usb_submit_urb(urb, GFP_ATOMIC);
-       if (err) {
-               usb_unanchor_urb(urb);
-               dev_kfree_skb_irq(skb);
-       }
-
-       return ;
-
-free:
-       dev_kfree_skb_irq(skb);
-       return;
-}
-
-static int ar9170_usb_prep_rx_urb(struct ar9170_usb *aru,
-                                 struct urb *urb, gfp_t gfp)
-{
-       struct sk_buff *skb;
-
-       skb = __dev_alloc_skb(AR9170_MAX_RX_BUFFER_SIZE + 32, gfp);
-       if (!skb)
-               return -ENOMEM;
-
-       /* reserve some space for mac80211's radiotap */
-       skb_reserve(skb, 32);
-
-       usb_fill_bulk_urb(urb, aru->udev,
-                         usb_rcvbulkpipe(aru->udev, AR9170_EP_RX),
-                         skb->data, min(skb_tailroom(skb),
-                         AR9170_MAX_RX_BUFFER_SIZE),
-                         ar9170_usb_rx_completed, skb);
-
-       return 0;
-}
-
-static int ar9170_usb_alloc_rx_irq_urb(struct ar9170_usb *aru)
-{
-       struct urb *urb = NULL;
-       void *ibuf;
-       int err = -ENOMEM;
-
-       /* initialize interrupt endpoint */
-       urb = usb_alloc_urb(0, GFP_KERNEL);
-       if (!urb)
-               goto out;
-
-       ibuf = usb_buffer_alloc(aru->udev, 64, GFP_KERNEL, &urb->transfer_dma);
-       if (!ibuf)
-               goto out;
-
-       usb_fill_int_urb(urb, aru->udev,
-                        usb_rcvintpipe(aru->udev, AR9170_EP_IRQ), ibuf,
-                        64, ar9170_usb_irq_completed, aru, 1);
-       urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
-
-       usb_anchor_urb(urb, &aru->rx_submitted);
-       err = usb_submit_urb(urb, GFP_KERNEL);
-       if (err) {
-               usb_unanchor_urb(urb);
-               usb_buffer_free(aru->udev, 64, urb->transfer_buffer,
-                               urb->transfer_dma);
-       }
-
-out:
-       usb_free_urb(urb);
-       return err;
-}
-
-static int ar9170_usb_alloc_rx_bulk_urbs(struct ar9170_usb *aru)
-{
-       struct urb *urb;
-       int i;
-       int err = -EINVAL;
-
-       for (i = 0; i < AR9170_NUM_RX_URBS; i++) {
-               err = -ENOMEM;
-               urb = usb_alloc_urb(0, GFP_KERNEL);
-               if (!urb)
-                       goto err_out;
-
-               err = ar9170_usb_prep_rx_urb(aru, urb, GFP_KERNEL);
-               if (err) {
-                       usb_free_urb(urb);
-                       goto err_out;
-               }
-
-               usb_anchor_urb(urb, &aru->rx_submitted);
-               err = usb_submit_urb(urb, GFP_KERNEL);
-               if (err) {
-                       usb_unanchor_urb(urb);
-                       dev_kfree_skb_any((void *) urb->transfer_buffer);
-                       usb_free_urb(urb);
-                       goto err_out;
-               }
-               usb_free_urb(urb);
-       }
-
-       /* the device now waiting for a firmware. */
-       aru->common.state = AR9170_IDLE;
-       return 0;
-
-err_out:
-
-       usb_kill_anchored_urbs(&aru->rx_submitted);
-       return err;
-}
-
-static void ar9170_usb_cancel_urbs(struct ar9170_usb *aru)
-{
-       int ret;
-
-       aru->common.state = AR9170_UNKNOWN_STATE;
-
-       usb_unlink_anchored_urbs(&aru->tx_submitted);
-
-       /* give the LED OFF command and the deauth frame a chance to air. */
-       ret = usb_wait_anchor_empty_timeout(&aru->tx_submitted,
-                                           msecs_to_jiffies(100));
-       if (ret == 0)
-               dev_err(&aru->udev->dev, "kill pending tx urbs.\n");
-       usb_poison_anchored_urbs(&aru->tx_submitted);
-
-       usb_poison_anchored_urbs(&aru->rx_submitted);
-}
-
-static int ar9170_usb_exec_cmd(struct ar9170 *ar, enum ar9170_cmd cmd,
-                              unsigned int plen, void *payload,
-                              unsigned int outlen, void *out)
-{
-       struct ar9170_usb *aru = (void *) ar;
-       struct urb *urb = NULL;
-       unsigned long flags;
-       int err = -ENOMEM;
-
-       if (unlikely(!IS_ACCEPTING_CMD(ar)))
-               return -EPERM;
-
-       if (WARN_ON(plen > AR9170_MAX_CMD_LEN - 4))
-               return -EINVAL;
-
-       urb = usb_alloc_urb(0, GFP_ATOMIC);
-       if (unlikely(!urb))
-               goto err_free;
-
-       ar->cmdbuf[0] = cpu_to_le32(plen);
-       ar->cmdbuf[0] |= cpu_to_le32(cmd << 8);
-       /* writing multiple regs fills this buffer already */
-       if (plen && payload != (u8 *)(&ar->cmdbuf[1]))
-               memcpy(&ar->cmdbuf[1], payload, plen);
-
-       spin_lock_irqsave(&aru->common.cmdlock, flags);
-       aru->readbuf = (u8 *)out;
-       aru->readlen = outlen;
-       spin_unlock_irqrestore(&aru->common.cmdlock, flags);
-
-       usb_fill_int_urb(urb, aru->udev,
-                        usb_sndbulkpipe(aru->udev, AR9170_EP_CMD),
-                        aru->common.cmdbuf, plen + 4,
-                        ar9170_usb_tx_urb_complete, NULL, 1);
-
-       usb_anchor_urb(urb, &aru->tx_submitted);
-       err = usb_submit_urb(urb, GFP_ATOMIC);
-       if (err) {
-               usb_unanchor_urb(urb);
-               usb_free_urb(urb);
-               goto err_unbuf;
-       }
-       usb_free_urb(urb);
-
-       err = wait_for_completion_timeout(&aru->cmd_wait, HZ);
-       if (err == 0) {
-               err = -ETIMEDOUT;
-               goto err_unbuf;
-       }
-
-       if (outlen >= 0 && aru->readlen != outlen) {
-               err = -EMSGSIZE;
-               goto err_unbuf;
-       }
-
-       return 0;
-
-err_unbuf:
-       /* Maybe the device was removed in the second we were waiting? */
-       if (IS_STARTED(ar)) {
-               dev_err(&aru->udev->dev, "no command feedback "
-                                        "received (%d).\n", err);
-
-               /* provide some maybe useful debug information */
-               print_hex_dump_bytes("ar9170 cmd: ", DUMP_PREFIX_NONE,
-                                    aru->common.cmdbuf, plen + 4);
-               dump_stack();
-       }
-
-       /* invalidate to avoid completing the next prematurely */
-       spin_lock_irqsave(&aru->common.cmdlock, flags);
-       aru->readbuf = NULL;
-       aru->readlen = 0;
-       spin_unlock_irqrestore(&aru->common.cmdlock, flags);
-
-err_free:
-
-       return err;
-}
-
-static int ar9170_usb_tx(struct ar9170 *ar, struct sk_buff *skb,
-                        bool txstatus_needed, unsigned int extra_len)
-{
-       struct ar9170_usb *aru = (struct ar9170_usb *) ar;
-       struct urb *urb;
-       int err;
-
-       if (unlikely(!IS_STARTED(ar))) {
-               /* Seriously, what were you drink... err... thinking!? */
-               return -EPERM;
-       }
-
-       urb = usb_alloc_urb(0, GFP_ATOMIC);
-       if (unlikely(!urb))
-               return -ENOMEM;
-
-       usb_fill_bulk_urb(urb, aru->udev,
-                         usb_sndbulkpipe(aru->udev, AR9170_EP_TX),
-                         skb->data, skb->len + extra_len, (txstatus_needed ?
-                         ar9170_usb_tx_urb_complete :
-                         ar9170_usb_tx_urb_complete_free), skb);
-       urb->transfer_flags |= URB_ZERO_PACKET;
-
-       usb_anchor_urb(urb, &aru->tx_submitted);
-       err = usb_submit_urb(urb, GFP_ATOMIC);
-       if (unlikely(err))
-               usb_unanchor_urb(urb);
-
-       usb_free_urb(urb);
-       return err;
-}
-
-static void ar9170_usb_callback_cmd(struct ar9170 *ar, u32 len , void *buffer)
-{
-       struct ar9170_usb *aru = (void *) ar;
-       unsigned long flags;
-       u32 in, out;
-
-       if (!buffer)
-               return ;
-
-       in = le32_to_cpup((__le32 *)buffer);
-       out = le32_to_cpu(ar->cmdbuf[0]);
-
-       /* mask off length byte */
-       out &= ~0xFF;
-
-       if (aru->readlen >= 0) {
-               /* add expected length */
-               out |= aru->readlen;
-       } else {
-               /* add obtained length */
-               out |= in & 0xFF;
-       }
-
-       /*
-        * Some commands (e.g: AR9170_CMD_FREQUENCY) have a variable response
-        * length and we cannot predict the correct length in advance.
-        * So we only check if we provided enough space for the data.
-        */
-       if (unlikely(out < in)) {
-               dev_warn(&aru->udev->dev, "received invalid command response "
-                                         "got %d bytes, instead of %d bytes "
-                                         "and the resp length is %d bytes\n",
-                        in, out, len);
-               print_hex_dump_bytes("ar9170 invalid resp: ",
-                                    DUMP_PREFIX_OFFSET, buffer, len);
-               /*
-                * Do not complete, then the command times out,
-                * and we get a stack trace from there.
-                */
-               return ;
-       }
-
-       spin_lock_irqsave(&aru->common.cmdlock, flags);
-       if (aru->readbuf && len > 0) {
-               memcpy(aru->readbuf, buffer + 4, len - 4);
-               aru->readbuf = NULL;
-       }
-       complete(&aru->cmd_wait);
-       spin_unlock_irqrestore(&aru->common.cmdlock, flags);
-}
-
-static int ar9170_usb_upload(struct ar9170_usb *aru, const void *data,
-                            size_t len, u32 addr, bool complete)
-{
-       int transfer, err;
-       u8 *buf = kmalloc(4096, GFP_KERNEL);
-
-       if (!buf)
-               return -ENOMEM;
-
-       while (len) {
-               transfer = min_t(int, len, 4096);
-               memcpy(buf, data, transfer);
-
-               err = usb_control_msg(aru->udev, usb_sndctrlpipe(aru->udev, 0),
-                                     0x30 /* FW DL */, 0x40 | USB_DIR_OUT,
-                                     addr >> 8, 0, buf, transfer, 1000);
-
-               if (err < 0) {
-                       kfree(buf);
-                       return err;
-               }
-
-               len -= transfer;
-               data += transfer;
-               addr += transfer;
-       }
-       kfree(buf);
-
-       if (complete) {
-               err = usb_control_msg(aru->udev, usb_sndctrlpipe(aru->udev, 0),
-                                     0x31 /* FW DL COMPLETE */,
-                                     0x40 | USB_DIR_OUT, 0, 0, NULL, 0, 5000);
-       }
-
-       return 0;
-}
-
-static int ar9170_usb_request_firmware(struct ar9170_usb *aru)
-{
-       int err = 0;
-
-       err = request_firmware(&aru->init_values, "ar9170-1.fw",
-                              &aru->udev->dev);
-       if (err) {
-               dev_err(&aru->udev->dev, "file with init values not found.\n");
-               return err;
-       }
-
-       err = request_firmware(&aru->firmware, "ar9170-2.fw", &aru->udev->dev);
-       if (err) {
-               release_firmware(aru->init_values);
-               dev_err(&aru->udev->dev, "firmware file not found.\n");
-               return err;
-       }
-
-       return err;
-}
-
-static int ar9170_usb_reset(struct ar9170_usb *aru)
-{
-       int ret, lock = (aru->intf->condition != USB_INTERFACE_BINDING);
-
-       if (lock) {
-               ret = usb_lock_device_for_reset(aru->udev, aru->intf);
-               if (ret < 0) {
-                       dev_err(&aru->udev->dev, "unable to lock device "
-                               "for reset (%d).\n", ret);
-                       return ret;
-               }
-       }
-
-       ret = usb_reset_device(aru->udev);
-       if (lock)
-               usb_unlock_device(aru->udev);
-
-       /* let it rest - for a second - */
-       msleep(1000);
-
-       return ret;
-}
-
-static int ar9170_usb_upload_firmware(struct ar9170_usb *aru)
-{
-       int err;
-
-       /* First, upload initial values to device RAM */
-       err = ar9170_usb_upload(aru, aru->init_values->data,
-                               aru->init_values->size, 0x102800, false);
-       if (err) {
-               dev_err(&aru->udev->dev, "firmware part 1 "
-                       "upload failed (%d).\n", err);
-               return err;
-       }
-
-       /* Then, upload the firmware itself and start it */
-       return ar9170_usb_upload(aru, aru->firmware->data, aru->firmware->size,
-                               0x200000, true);
-}
-
-static int ar9170_usb_init_transport(struct ar9170_usb *aru)
-{
-       struct ar9170 *ar = (void *) &aru->common;
-       int err;
-
-       ar9170_regwrite_begin(ar);
-
-       /* Set USB Rx stream mode MAX packet number to 2 */
-       ar9170_regwrite(AR9170_USB_REG_MAX_AGG_UPLOAD, 0x4);
-
-       /* Set USB Rx stream mode timeout to 10us */
-       ar9170_regwrite(AR9170_USB_REG_UPLOAD_TIME_CTL, 0x80);
-
-       ar9170_regwrite_finish();
-
-       err = ar9170_regwrite_result();
-       if (err)
-               dev_err(&aru->udev->dev, "USB setup failed (%d).\n", err);
-
-       return err;
-}
-
-static void ar9170_usb_stop(struct ar9170 *ar)
-{
-       struct ar9170_usb *aru = (void *) ar;
-       int ret;
-
-       if (IS_ACCEPTING_CMD(ar))
-               aru->common.state = AR9170_STOPPED;
-
-       /* lets wait a while until the tx - queues are dried out */
-       ret = usb_wait_anchor_empty_timeout(&aru->tx_submitted,
-                                           msecs_to_jiffies(1000));
-       if (ret == 0)
-               dev_err(&aru->udev->dev, "kill pending tx urbs.\n");
-
-       usb_poison_anchored_urbs(&aru->tx_submitted);
-
-       /*
-        * Note:
-        * So far we freed all tx urbs, but we won't dare to touch any rx urbs.
-        * Else we would end up with a unresponsive device...
-        */
-}
-
-static int ar9170_usb_open(struct ar9170 *ar)
-{
-       struct ar9170_usb *aru = (void *) ar;
-       int err;
-
-       usb_unpoison_anchored_urbs(&aru->tx_submitted);
-       err = ar9170_usb_init_transport(aru);
-       if (err) {
-               usb_poison_anchored_urbs(&aru->tx_submitted);
-               return err;
-       }
-
-       aru->common.state = AR9170_IDLE;
-       return 0;
-}
-
-static int ar9170_usb_init_device(struct ar9170_usb *aru)
-{
-       int err;
-
-       err = ar9170_usb_alloc_rx_irq_urb(aru);
-       if (err)
-               goto err_out;
-
-       err = ar9170_usb_alloc_rx_bulk_urbs(aru);
-       if (err)
-               goto err_unrx;
-
-       err = ar9170_usb_upload_firmware(aru);
-       if (err) {
-               err = ar9170_echo_test(&aru->common, 0x60d43110);
-               if (err) {
-                       /* force user invention, by disabling the device */
-                       err = usb_driver_set_configuration(aru->udev, -1);
-                       dev_err(&aru->udev->dev, "device is in a bad state. "
-                                                "please reconnect it!\n");
-                       goto err_unrx;
-               }
-       }
-
-       return 0;
-
-err_unrx:
-       ar9170_usb_cancel_urbs(aru);
-
-err_out:
-       return err;
-}
-
-static int ar9170_usb_probe(struct usb_interface *intf,
-                       const struct usb_device_id *id)
-{
-       struct ar9170_usb *aru;
-       struct ar9170 *ar;
-       struct usb_device *udev;
-       int err;
-
-       aru = ar9170_alloc(sizeof(*aru));
-       if (IS_ERR(aru)) {
-               err = PTR_ERR(aru);
-               goto out;
-       }
-
-       udev = interface_to_usbdev(intf);
-       usb_get_dev(udev);
-       aru->udev = udev;
-       aru->intf = intf;
-       ar = &aru->common;
-
-       usb_set_intfdata(intf, aru);
-       SET_IEEE80211_DEV(ar->hw, &udev->dev);
-
-       init_usb_anchor(&aru->rx_submitted);
-       init_usb_anchor(&aru->tx_submitted);
-       init_completion(&aru->cmd_wait);
-
-       aru->common.stop = ar9170_usb_stop;
-       aru->common.open = ar9170_usb_open;
-       aru->common.tx = ar9170_usb_tx;
-       aru->common.exec_cmd = ar9170_usb_exec_cmd;
-       aru->common.callback_cmd = ar9170_usb_callback_cmd;
-
-       err = ar9170_usb_reset(aru);
-       if (err)
-               goto err_freehw;
-
-       err = ar9170_usb_request_firmware(aru);
-       if (err)
-               goto err_freehw;
-
-       err = ar9170_usb_init_device(aru);
-       if (err)
-               goto err_freefw;
-
-       err = ar9170_usb_open(ar);
-       if (err)
-               goto err_unrx;
-
-       err = ar9170_register(ar, &udev->dev);
-
-       ar9170_usb_stop(ar);
-       if (err)
-               goto err_unrx;
-
-       return 0;
-
-err_unrx:
-       ar9170_usb_cancel_urbs(aru);
-
-err_freefw:
-       release_firmware(aru->init_values);
-       release_firmware(aru->firmware);
-
-err_freehw:
-       usb_set_intfdata(intf, NULL);
-       usb_put_dev(udev);
-       ieee80211_free_hw(ar->hw);
-out:
-       return err;
-}
-
-static void ar9170_usb_disconnect(struct usb_interface *intf)
-{
-       struct ar9170_usb *aru = usb_get_intfdata(intf);
-
-       if (!aru)
-               return;
-
-       aru->common.state = AR9170_IDLE;
-       ar9170_unregister(&aru->common);
-       ar9170_usb_cancel_urbs(aru);
-
-       release_firmware(aru->init_values);
-       release_firmware(aru->firmware);
-
-       usb_put_dev(aru->udev);
-       usb_set_intfdata(intf, NULL);
-       ieee80211_free_hw(aru->common.hw);
-}
-
-#ifdef CONFIG_PM
-static int ar9170_suspend(struct usb_interface *intf,
-                         pm_message_t  message)
-{
-       struct ar9170_usb *aru = usb_get_intfdata(intf);
-
-       if (!aru)
-               return -ENODEV;
-
-       aru->common.state = AR9170_IDLE;
-       ar9170_usb_cancel_urbs(aru);
-
-       return 0;
-}
-
-static int ar9170_resume(struct usb_interface *intf)
-{
-       struct ar9170_usb *aru = usb_get_intfdata(intf);
-       int err;
-
-       if (!aru)
-               return -ENODEV;
-
-       usb_unpoison_anchored_urbs(&aru->rx_submitted);
-       usb_unpoison_anchored_urbs(&aru->tx_submitted);
-
-       /*
-        * FIXME: firmware upload will fail on resume.
-        * but this is better than a hang!
-        */
-
-       err = ar9170_usb_init_device(aru);
-       if (err)
-               goto err_unrx;
-
-       err = ar9170_usb_open(&aru->common);
-       if (err)
-               goto err_unrx;
-
-       return 0;
-
-err_unrx:
-       aru->common.state = AR9170_IDLE;
-       ar9170_usb_cancel_urbs(aru);
-
-       return err;
-}
-#endif /* CONFIG_PM */
-
-static struct usb_driver ar9170_driver = {
-       .name = "ar9170usb",
-       .probe = ar9170_usb_probe,
-       .disconnect = ar9170_usb_disconnect,
-       .id_table = ar9170_usb_ids,
-       .soft_unbind = 1,
-#ifdef CONFIG_PM
-       .suspend = ar9170_suspend,
-       .resume = ar9170_resume,
-#endif /* CONFIG_PM */
-};
-
-static int __init ar9170_init(void)
-{
-       return usb_register(&ar9170_driver);
-}
-
-static void __exit ar9170_exit(void)
-{
-       usb_deregister(&ar9170_driver);
-}
-
-module_init(ar9170_init);
-module_exit(ar9170_exit);
diff --git a/drivers/net/wireless/ar9170/usb.h b/drivers/net/wireless/ar9170/usb.h
deleted file mode 100644 (file)
index f585292..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Atheros AR9170 USB driver
- *
- * Driver specific definitions
- *
- * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
- * Copyright 2009, Christian Lamparter <chunkeey@web.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.
- *
- * 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; see the file COPYING.  If not, see
- * http://www.gnu.org/licenses/.
- *
- * This file incorporates work covered by the following copyright and
- * permission notice:
- *    Copyright (c) 2007-2008 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 __USB_H
-#define __USB_H
-
-#include <linux/usb.h>
-#include <linux/completion.h>
-#include <linux/spinlock.h>
-#include <linux/leds.h>
-#include <net/wireless.h>
-#include <net/mac80211.h>
-#include <linux/firmware.h>
-#include "eeprom.h"
-#include "hw.h"
-#include "ar9170.h"
-
-#define AR9170_NUM_RX_URBS                     16
-
-struct firmware;
-
-struct ar9170_usb {
-       struct ar9170 common;
-       struct usb_device *udev;
-       struct usb_interface *intf;
-
-       struct usb_anchor rx_submitted;
-       struct usb_anchor tx_submitted;
-
-       spinlock_t cmdlock;
-       struct completion cmd_wait;
-       int readlen;
-       u8 *readbuf;
-
-       const struct firmware *init_values;
-       const struct firmware *firmware;
-};
-
-#endif /* __USB_H */
index a54a67c425c8f7e02e401b255fb2d2ef3123846f..d84caf198a23ed0f2d4057f6bab603915fbed586 100644 (file)
@@ -1199,7 +1199,7 @@ bad_end:
        arlan_process_interrupt(dev);
        netif_stop_queue (dev);
        ARLAN_DEBUG_EXIT("arlan_tx");
-       return 1;
+       return NETDEV_TX_BUSY;
 }
 
 
index 8d93ca4651b9fad66e2cd7c890aa757cf0c27d2e..4efbdbe6d6bf511c75816350aabc038a239830cd 100644 (file)
@@ -1965,13 +1965,18 @@ static int at76_config(struct ieee80211_hw *hw, u32 changed)
        return 0;
 }
 
-static int at76_config_interface(struct ieee80211_hw *hw,
-                                struct ieee80211_vif *vif,
-                                struct ieee80211_if_conf *conf)
+static void at76_bss_info_changed(struct ieee80211_hw *hw,
+                                 struct ieee80211_vif *vif,
+                                 struct ieee80211_bss_conf *conf,
+                                 u32 changed)
 {
        struct at76_priv *priv = hw->priv;
 
        at76_dbg(DBG_MAC80211, "%s():", __func__);
+
+       if (!(changed & BSS_CHANGED_BSSID))
+               return;
+
        at76_dbg_dump(DBG_MAC80211, conf->bssid, ETH_ALEN, "bssid:");
 
        mutex_lock(&priv->mtx);
@@ -1983,8 +1988,6 @@ static int at76_config_interface(struct ieee80211_hw *hw,
                at76_join(priv);
 
        mutex_unlock(&priv->mtx);
-
-       return 0;
 }
 
 /* must be atomic */
@@ -2076,7 +2079,7 @@ static const struct ieee80211_ops at76_ops = {
        .add_interface = at76_add_interface,
        .remove_interface = at76_remove_interface,
        .config = at76_config,
-       .config_interface = at76_config_interface,
+       .bss_info_changed = at76_bss_info_changed,
        .configure_filter = at76_configure_filter,
        .start = at76_mac80211_start,
        .stop = at76_mac80211_stop,
@@ -2250,6 +2253,7 @@ static int at76_init_new_device(struct at76_priv *priv,
 
        /* mac80211 initialisation */
        priv->hw->wiphy->max_scan_ssids = 1;
+       priv->hw->wiphy->max_scan_ie_len = 0;
        priv->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
        priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &at76_supported_band;
        priv->hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
@@ -2311,8 +2315,7 @@ static void at76_delete_device(struct at76_priv *priv)
 
        del_timer_sync(&ledtrig_tx_timer);
 
-       if (priv->rx_skb)
-               kfree_skb(priv->rx_skb);
+       kfree_skb(priv->rx_skb);
 
        usb_put_dev(priv->udev);
 
diff --git a/drivers/net/wireless/ath/Kconfig b/drivers/net/wireless/ath/Kconfig
new file mode 100644 (file)
index 0000000..d26e7b4
--- /dev/null
@@ -0,0 +1,8 @@
+config ATH_COMMON
+       tristate "Atheros Wireless Cards"
+       depends on ATH5K || ATH9K || AR9170_USB
+
+source "drivers/net/wireless/ath/ath5k/Kconfig"
+source "drivers/net/wireless/ath/ath9k/Kconfig"
+source "drivers/net/wireless/ath/ar9170/Kconfig"
+
diff --git a/drivers/net/wireless/ath/Makefile b/drivers/net/wireless/ath/Makefile
new file mode 100644 (file)
index 0000000..4bb0132
--- /dev/null
@@ -0,0 +1,6 @@
+obj-$(CONFIG_ATH5K)            += ath5k/
+obj-$(CONFIG_ATH9K)            += ath9k/
+obj-$(CONFIG_AR9170_USB)        += ar9170/
+
+obj-$(CONFIG_ATH_COMMON)       += ath.o
+ath-objs               := main.o regd.o
diff --git a/drivers/net/wireless/ath/ar9170/Kconfig b/drivers/net/wireless/ath/ar9170/Kconfig
new file mode 100644 (file)
index 0000000..b99e326
--- /dev/null
@@ -0,0 +1,18 @@
+config AR9170_USB
+       tristate "Atheros AR9170 802.11n USB support"
+       depends on USB && MAC80211 && WLAN_80211 && EXPERIMENTAL
+       select FW_LOADER
+       select ATH_COMMON
+       help
+         This is a driver for the Atheros "otus" 802.11n USB devices.
+
+         These devices require additional firmware (2 files).
+         For now, these files can be downloaded from here:
+         http://wireless.kernel.org/en/users/Drivers/ar9170
+
+         If you choose to build a module, it'll be called ar9170usb.
+
+config AR9170_LEDS
+       bool
+       depends on AR9170_USB && MAC80211_LEDS && (LEDS_CLASS = y || LEDS_CLASS = AR9170_USB)
+       default y
diff --git a/drivers/net/wireless/ath/ar9170/Makefile b/drivers/net/wireless/ath/ar9170/Makefile
new file mode 100644 (file)
index 0000000..8d91c7e
--- /dev/null
@@ -0,0 +1,3 @@
+ar9170usb-objs := usb.o main.o cmd.o mac.o phy.o led.o
+
+obj-$(CONFIG_AR9170_USB) += ar9170usb.o
diff --git a/drivers/net/wireless/ath/ar9170/ar9170.h b/drivers/net/wireless/ath/ar9170/ar9170.h
new file mode 100644 (file)
index 0000000..bb97981
--- /dev/null
@@ -0,0 +1,257 @@
+/*
+ * Atheros AR9170 driver
+ *
+ * Driver specific definitions
+ *
+ * Copyright 2008, 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 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; see the file COPYING.  If not, see
+ * http://www.gnu.org/licenses/.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ *    Copyright (c) 2007-2008 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 __AR9170_H
+#define __AR9170_H
+
+#include <linux/completion.h>
+#include <linux/spinlock.h>
+#include <net/cfg80211.h>
+#include <net/mac80211.h>
+#ifdef CONFIG_AR9170_LEDS
+#include <linux/leds.h>
+#endif /* CONFIG_AR9170_LEDS */
+#include "eeprom.h"
+#include "hw.h"
+
+#include "../regd.h"
+
+#define PAYLOAD_MAX    (AR9170_MAX_CMD_LEN/4 - 1)
+
+enum ar9170_bw {
+       AR9170_BW_20,
+       AR9170_BW_40_BELOW,
+       AR9170_BW_40_ABOVE,
+
+       __AR9170_NUM_BW,
+};
+
+static inline enum ar9170_bw nl80211_to_ar9170(enum nl80211_channel_type type)
+{
+       switch (type) {
+       case NL80211_CHAN_NO_HT:
+       case NL80211_CHAN_HT20:
+               return AR9170_BW_20;
+       case NL80211_CHAN_HT40MINUS:
+               return AR9170_BW_40_BELOW;
+       case NL80211_CHAN_HT40PLUS:
+               return AR9170_BW_40_ABOVE;
+       default:
+               BUG();
+       }
+}
+
+enum ar9170_rf_init_mode {
+       AR9170_RFI_NONE,
+       AR9170_RFI_WARM,
+       AR9170_RFI_COLD,
+};
+
+#define AR9170_MAX_RX_BUFFER_SIZE              8192
+
+#ifdef CONFIG_AR9170_LEDS
+struct ar9170;
+
+struct ar9170_led {
+       struct ar9170 *ar;
+       struct led_classdev l;
+       char name[32];
+       unsigned int toggled;
+       bool last_state;
+       bool registered;
+};
+
+#endif /* CONFIG_AR9170_LEDS */
+
+enum ar9170_device_state {
+       AR9170_UNKNOWN_STATE,
+       AR9170_STOPPED,
+       AR9170_IDLE,
+       AR9170_STARTED,
+};
+
+struct ar9170_rxstream_mpdu_merge {
+       struct ar9170_rx_head plcp;
+       bool has_plcp;
+};
+
+#define AR9170_QUEUE_TIMEOUT           64
+#define AR9170_TX_TIMEOUT              8
+#define AR9170_JANITOR_DELAY           128
+#define AR9170_TX_INVALID_RATE         0xffffffff
+
+struct ar9170 {
+       struct ieee80211_hw *hw;
+       struct mutex mutex;
+       enum ar9170_device_state state;
+       unsigned long bad_hw_nagger;
+
+       int (*open)(struct ar9170 *);
+       void (*stop)(struct ar9170 *);
+       int (*tx)(struct ar9170 *, struct sk_buff *);
+       int (*exec_cmd)(struct ar9170 *, enum ar9170_cmd, u32 ,
+                       void *, u32 , void *);
+       void (*callback_cmd)(struct ar9170 *, u32 , void *);
+       int (*flush)(struct ar9170 *);
+
+       /* interface mode settings */
+       struct ieee80211_vif *vif;
+       u8 mac_addr[ETH_ALEN];
+       u8 bssid[ETH_ALEN];
+
+       /* beaconing */
+       struct sk_buff *beacon;
+       struct work_struct beacon_work;
+
+       /* cryptographic engine */
+       u64 usedkeys;
+       bool rx_software_decryption;
+       bool disable_offload;
+
+       /* filter settings */
+       struct work_struct filter_config_work;
+       u64 cur_mc_hash, want_mc_hash;
+       u32 cur_filter, want_filter;
+       unsigned long filter_changed;
+       unsigned int filter_state;
+       bool sniffer_enabled;
+
+       /* PHY */
+       struct ieee80211_channel *channel;
+       int noise[4];
+
+       /* power calibration data */
+       u8 power_5G_leg[4];
+       u8 power_2G_cck[4];
+       u8 power_2G_ofdm[4];
+       u8 power_5G_ht20[8];
+       u8 power_5G_ht40[8];
+       u8 power_2G_ht20[8];
+       u8 power_2G_ht40[8];
+
+#ifdef CONFIG_AR9170_LEDS
+       struct delayed_work led_work;
+       struct ar9170_led leds[AR9170_NUM_LEDS];
+#endif /* CONFIG_AR9170_LEDS */
+
+       /* qos queue settings */
+       spinlock_t tx_stats_lock;
+       struct ieee80211_tx_queue_stats tx_stats[5];
+       struct ieee80211_tx_queue_params edcf[5];
+
+       spinlock_t cmdlock;
+       __le32 cmdbuf[PAYLOAD_MAX + 1];
+
+       /* MAC statistics */
+       struct ieee80211_low_level_stats stats;
+
+       /* EEPROM */
+       struct ar9170_eeprom eeprom;
+       struct ath_regulatory regulatory;
+
+       /* tx queues - as seen by hw - */
+       struct sk_buff_head tx_pending[__AR9170_NUM_TXQ];
+       struct sk_buff_head tx_status[__AR9170_NUM_TXQ];
+       struct delayed_work tx_janitor;
+
+       /* rxstream mpdu merge */
+       struct ar9170_rxstream_mpdu_merge rx_mpdu;
+       struct sk_buff *rx_failover;
+       int rx_failover_missing;
+};
+
+struct ar9170_sta_info {
+};
+
+#define AR9170_TX_FLAG_WAIT_FOR_ACK    BIT(0)
+#define AR9170_TX_FLAG_NO_ACK          BIT(1)
+#define AR9170_TX_FLAG_BLOCK_ACK       BIT(2)
+
+struct ar9170_tx_info {
+       unsigned long timeout;
+       unsigned int flags;
+};
+
+#define IS_STARTED(a)          (((struct ar9170 *)a)->state >= AR9170_STARTED)
+#define IS_ACCEPTING_CMD(a)    (((struct ar9170 *)a)->state >= AR9170_IDLE)
+
+#define AR9170_FILTER_CHANGED_MODE             BIT(0)
+#define AR9170_FILTER_CHANGED_MULTICAST                BIT(1)
+#define AR9170_FILTER_CHANGED_FRAMEFILTER      BIT(2)
+
+/* exported interface */
+void *ar9170_alloc(size_t priv_size);
+int ar9170_register(struct ar9170 *ar, struct device *pdev);
+void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb);
+void ar9170_unregister(struct ar9170 *ar);
+void ar9170_tx_callback(struct ar9170 *ar, struct sk_buff *skb);
+void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len);
+int ar9170_nag_limiter(struct ar9170 *ar);
+
+/* MAC */
+int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
+int ar9170_init_mac(struct ar9170 *ar);
+int ar9170_set_qos(struct ar9170 *ar);
+int ar9170_update_multicast(struct ar9170 *ar);
+int ar9170_update_frame_filter(struct ar9170 *ar);
+int ar9170_set_operating_mode(struct ar9170 *ar);
+int ar9170_set_beacon_timers(struct ar9170 *ar);
+int ar9170_set_dyn_sifs_ack(struct ar9170 *ar);
+int ar9170_set_slot_time(struct ar9170 *ar);
+int ar9170_set_basic_rates(struct ar9170 *ar);
+int ar9170_set_hwretry_limit(struct ar9170 *ar, u32 max_retry);
+int ar9170_update_beacon(struct ar9170 *ar);
+void ar9170_new_beacon(struct work_struct *work);
+int ar9170_upload_key(struct ar9170 *ar, u8 id, const u8 *mac, u8 ktype,
+                     u8 keyidx, u8 *keydata, int keylen);
+int ar9170_disable_key(struct ar9170 *ar, u8 id);
+
+/* LEDs */
+#ifdef CONFIG_AR9170_LEDS
+int ar9170_register_leds(struct ar9170 *ar);
+void ar9170_unregister_leds(struct ar9170 *ar);
+#endif /* CONFIG_AR9170_LEDS */
+int ar9170_init_leds(struct ar9170 *ar);
+int ar9170_set_leds_state(struct ar9170 *ar, u32 led_state);
+
+/* PHY / RF */
+int ar9170_init_phy(struct ar9170 *ar, enum ieee80211_band band);
+int ar9170_init_rf(struct ar9170 *ar);
+int ar9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
+                      enum ar9170_rf_init_mode rfi, enum ar9170_bw bw);
+
+#endif /* __AR9170_H */
diff --git a/drivers/net/wireless/ath/ar9170/cmd.c b/drivers/net/wireless/ath/ar9170/cmd.c
new file mode 100644 (file)
index 0000000..f57a620
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ * Atheros AR9170 driver
+ *
+ * Basic HW register/memory/command access functions
+ *
+ * Copyright 2008, 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 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; see the file COPYING.  If not, see
+ * http://www.gnu.org/licenses/.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ *    Copyright (c) 2007-2008 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 "ar9170.h"
+#include "cmd.h"
+
+int ar9170_write_mem(struct ar9170 *ar, const __le32 *data, size_t len)
+{
+       int err;
+
+       if (unlikely(!IS_ACCEPTING_CMD(ar)))
+               return 0;
+
+       err = ar->exec_cmd(ar, AR9170_CMD_WMEM, len, (u8 *) data, 0, NULL);
+       if (err)
+               printk(KERN_DEBUG "%s: writing memory failed\n",
+                      wiphy_name(ar->hw->wiphy));
+       return err;
+}
+
+int ar9170_write_reg(struct ar9170 *ar, const u32 reg, const u32 val)
+{
+       __le32 buf[2] = {
+               cpu_to_le32(reg),
+               cpu_to_le32(val),
+       };
+       int err;
+
+       if (unlikely(!IS_ACCEPTING_CMD(ar)))
+               return 0;
+
+       err = ar->exec_cmd(ar, AR9170_CMD_WREG, sizeof(buf),
+                          (u8 *) buf, 0, NULL);
+       if (err)
+               printk(KERN_DEBUG "%s: writing reg %#x (val %#x) failed\n",
+                      wiphy_name(ar->hw->wiphy), reg, val);
+       return err;
+}
+
+static int ar9170_read_mreg(struct ar9170 *ar, int nregs,
+                           const u32 *regs, u32 *out)
+{
+       int i, err;
+       __le32 *offs, *res;
+
+       if (unlikely(!IS_ACCEPTING_CMD(ar)))
+               return 0;
+
+       /* abuse "out" for the register offsets, must be same length */
+       offs = (__le32 *)out;
+       for (i = 0; i < nregs; i++)
+               offs[i] = cpu_to_le32(regs[i]);
+
+       /* also use the same buffer for the input */
+       res = (__le32 *)out;
+
+       err = ar->exec_cmd(ar, AR9170_CMD_RREG,
+                          4 * nregs, (u8 *)offs,
+                          4 * nregs, (u8 *)res);
+       if (err)
+               return err;
+
+       /* convert result to cpu endian */
+       for (i = 0; i < nregs; i++)
+               out[i] = le32_to_cpu(res[i]);
+
+       return 0;
+}
+
+int ar9170_read_reg(struct ar9170 *ar, u32 reg, u32 *val)
+{
+       return ar9170_read_mreg(ar, 1, &reg, val);
+}
+
+int ar9170_echo_test(struct ar9170 *ar, u32 v)
+{
+       __le32 echobuf = cpu_to_le32(v);
+       __le32 echores;
+       int err;
+
+       if (unlikely(!IS_ACCEPTING_CMD(ar)))
+               return -ENODEV;
+
+       err = ar->exec_cmd(ar, AR9170_CMD_ECHO,
+                          4, (u8 *)&echobuf,
+                          4, (u8 *)&echores);
+       if (err)
+               return err;
+
+       if (echobuf != echores)
+               return -EINVAL;
+
+       return 0;
+}
diff --git a/drivers/net/wireless/ath/ar9170/cmd.h b/drivers/net/wireless/ath/ar9170/cmd.h
new file mode 100644 (file)
index 0000000..a4f0e50
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * Atheros AR9170 driver
+ *
+ * Basic HW register/memory/command access functions
+ *
+ * Copyright 2008, 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 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; see the file COPYING.  If not, see
+ * http://www.gnu.org/licenses/.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ *    Copyright (c) 2007-2008 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 __CMD_H
+#define __CMD_H
+
+#include "ar9170.h"
+
+/* basic HW access */
+int ar9170_write_mem(struct ar9170 *ar, const __le32 *data, size_t len);
+int ar9170_write_reg(struct ar9170 *ar, const u32 reg, const u32 val);
+int ar9170_read_reg(struct ar9170 *ar, u32 reg, u32 *val);
+int ar9170_echo_test(struct ar9170 *ar, u32 v);
+
+/*
+ * Macros to facilitate writing multiple registers in a single
+ * write-combining USB command. Note that when the first group
+ * fails the whole thing will fail without any others attempted,
+ * but you won't know which write in the group failed.
+ */
+#define ar9170_regwrite_begin(ar)                                      \
+do {                                                                   \
+       int __nreg = 0, __err = 0;                                      \
+       struct ar9170 *__ar = ar;
+
+#define ar9170_regwrite(r, v) do {                                     \
+       __ar->cmdbuf[2 * __nreg + 1] = cpu_to_le32(r);                  \
+       __ar->cmdbuf[2 * __nreg + 2] = cpu_to_le32(v);                  \
+       __nreg++;                                                       \
+       if ((__nreg >= PAYLOAD_MAX/2)) {                                \
+               if (IS_ACCEPTING_CMD(__ar))                             \
+                       __err = ar->exec_cmd(__ar, AR9170_CMD_WREG,     \
+                                            8 * __nreg,                \
+                                            (u8 *) &__ar->cmdbuf[1],   \
+                                            0, NULL);                  \
+               __nreg = 0;                                             \
+               if (__err)                                              \
+                       goto __regwrite_out;                            \
+       }                                                               \
+} while (0)
+
+#define ar9170_regwrite_finish()                                       \
+__regwrite_out :                                                       \
+       if (__nreg) {                                                   \
+               if (IS_ACCEPTING_CMD(__ar))                             \
+                       __err = ar->exec_cmd(__ar, AR9170_CMD_WREG,     \
+                                            8 * __nreg,                \
+                                            (u8 *) &__ar->cmdbuf[1],   \
+                                            0, NULL);                  \
+               __nreg = 0;                                             \
+       }
+
+#define ar9170_regwrite_result()                                       \
+       __err;                                                          \
+} while (0);
+
+#endif /* __CMD_H */
diff --git a/drivers/net/wireless/ath/ar9170/eeprom.h b/drivers/net/wireless/ath/ar9170/eeprom.h
new file mode 100644 (file)
index 0000000..d2c8cc8
--- /dev/null
@@ -0,0 +1,179 @@
+/*
+ * Atheros AR9170 driver
+ *
+ * EEPROM layout
+ *
+ * Copyright 2008, 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 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; see the file COPYING.  If not, see
+ * http://www.gnu.org/licenses/.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ *    Copyright (c) 2007-2008 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 __AR9170_EEPROM_H
+#define __AR9170_EEPROM_H
+
+#define AR5416_MAX_CHAINS              2
+#define AR5416_MODAL_SPURS             5
+
+struct ar9170_eeprom_modal {
+       __le32  antCtrlChain[AR5416_MAX_CHAINS];
+       __le32  antCtrlCommon;
+       s8      antennaGainCh[AR5416_MAX_CHAINS];
+       u8      switchSettling;
+       u8      txRxAttenCh[AR5416_MAX_CHAINS];
+       u8      rxTxMarginCh[AR5416_MAX_CHAINS];
+       s8      adcDesiredSize;
+       s8      pgaDesiredSize;
+       u8      xlnaGainCh[AR5416_MAX_CHAINS];
+       u8      txEndToXpaOff;
+       u8      txEndToRxOn;
+       u8      txFrameToXpaOn;
+       u8      thresh62;
+       s8      noiseFloorThreshCh[AR5416_MAX_CHAINS];
+       u8      xpdGain;
+       u8      xpd;
+       s8      iqCalICh[AR5416_MAX_CHAINS];
+       s8      iqCalQCh[AR5416_MAX_CHAINS];
+       u8      pdGainOverlap;
+       u8      ob;
+       u8      db;
+       u8      xpaBiasLvl;
+       u8      pwrDecreaseFor2Chain;
+       u8      pwrDecreaseFor3Chain;
+       u8      txFrameToDataStart;
+       u8      txFrameToPaOn;
+       u8      ht40PowerIncForPdadc;
+       u8      bswAtten[AR5416_MAX_CHAINS];
+       u8      bswMargin[AR5416_MAX_CHAINS];
+       u8      swSettleHt40;
+       u8      reserved[22];
+       struct spur_channel {
+               __le16 spurChan;
+               u8      spurRangeLow;
+               u8      spurRangeHigh;
+       } __packed spur_channels[AR5416_MODAL_SPURS];
+} __packed;
+
+#define AR5416_NUM_PD_GAINS            4
+#define AR5416_PD_GAIN_ICEPTS          5
+
+struct ar9170_calibration_data_per_freq {
+       u8      pwr_pdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
+       u8      vpd_pdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
+} __packed;
+
+#define AR5416_NUM_5G_CAL_PIERS                8
+#define AR5416_NUM_2G_CAL_PIERS                4
+
+#define AR5416_NUM_5G_TARGET_PWRS      8
+#define AR5416_NUM_2G_CCK_TARGET_PWRS  3
+#define AR5416_NUM_2G_OFDM_TARGET_PWRS 4
+#define AR5416_MAX_NUM_TGT_PWRS                8
+
+struct ar9170_calibration_target_power_legacy {
+       u8      freq;
+       u8      power[4];
+} __packed;
+
+struct ar9170_calibration_target_power_ht {
+       u8      freq;
+       u8      power[8];
+} __packed;
+
+#define AR5416_NUM_CTLS                        24
+
+struct ar9170_calctl_edges {
+       u8      channel;
+#define AR9170_CALCTL_EDGE_FLAGS       0xC0
+       u8      power_flags;
+} __packed;
+
+#define AR5416_NUM_BAND_EDGES          8
+
+struct ar9170_calctl_data {
+       struct ar9170_calctl_edges
+               control_edges[AR5416_MAX_CHAINS][AR5416_NUM_BAND_EDGES];
+} __packed;
+
+
+struct ar9170_eeprom {
+       __le16  length;
+       __le16  checksum;
+       __le16  version;
+       u8      operating_flags;
+#define AR9170_OPFLAG_5GHZ             1
+#define AR9170_OPFLAG_2GHZ             2
+       u8      misc;
+       __le16  reg_domain[2];
+       u8      mac_address[6];
+       u8      rx_mask;
+       u8      tx_mask;
+       __le16  rf_silent;
+       __le16  bluetooth_options;
+       __le16  device_capabilities;
+       __le32  build_number;
+       u8      deviceType;
+       u8      reserved[33];
+
+       u8      customer_data[64];
+
+       struct ar9170_eeprom_modal
+               modal_header[2];
+
+       u8      cal_freq_pier_5G[AR5416_NUM_5G_CAL_PIERS];
+       u8      cal_freq_pier_2G[AR5416_NUM_2G_CAL_PIERS];
+
+       struct ar9170_calibration_data_per_freq
+               cal_pier_data_5G[AR5416_MAX_CHAINS][AR5416_NUM_5G_CAL_PIERS],
+               cal_pier_data_2G[AR5416_MAX_CHAINS][AR5416_NUM_2G_CAL_PIERS];
+
+       /* power calibration data */
+       struct ar9170_calibration_target_power_legacy
+               cal_tgt_pwr_5G[AR5416_NUM_5G_TARGET_PWRS];
+       struct ar9170_calibration_target_power_ht
+               cal_tgt_pwr_5G_ht20[AR5416_NUM_5G_TARGET_PWRS],
+               cal_tgt_pwr_5G_ht40[AR5416_NUM_5G_TARGET_PWRS];
+
+       struct ar9170_calibration_target_power_legacy
+               cal_tgt_pwr_2G_cck[AR5416_NUM_2G_CCK_TARGET_PWRS],
+               cal_tgt_pwr_2G_ofdm[AR5416_NUM_2G_OFDM_TARGET_PWRS];
+       struct ar9170_calibration_target_power_ht
+               cal_tgt_pwr_2G_ht20[AR5416_NUM_2G_OFDM_TARGET_PWRS],
+               cal_tgt_pwr_2G_ht40[AR5416_NUM_2G_OFDM_TARGET_PWRS];
+
+       /* conformance testing limits */
+       u8      ctl_index[AR5416_NUM_CTLS];
+       struct ar9170_calctl_data
+               ctl_data[AR5416_NUM_CTLS];
+
+       u8      pad;
+       __le16  subsystem_id;
+} __packed;
+
+#endif /* __AR9170_EEPROM_H */
diff --git a/drivers/net/wireless/ath/ar9170/hw.h b/drivers/net/wireless/ath/ar9170/hw.h
new file mode 100644 (file)
index 0000000..6cbfb2f
--- /dev/null
@@ -0,0 +1,426 @@
+/*
+ * Atheros AR9170 driver
+ *
+ * Hardware-specific definitions
+ *
+ * Copyright 2008, 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 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; see the file COPYING.  If not, see
+ * http://www.gnu.org/licenses/.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ *    Copyright (c) 2007-2008 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 __AR9170_HW_H
+#define __AR9170_HW_H
+
+#define AR9170_MAX_CMD_LEN     64
+
+enum ar9170_cmd {
+       AR9170_CMD_RREG         = 0x00,
+       AR9170_CMD_WREG         = 0x01,
+       AR9170_CMD_RMEM         = 0x02,
+       AR9170_CMD_WMEM         = 0x03,
+       AR9170_CMD_BITAND       = 0x04,
+       AR9170_CMD_BITOR        = 0x05,
+       AR9170_CMD_EKEY         = 0x28,
+       AR9170_CMD_DKEY         = 0x29,
+       AR9170_CMD_FREQUENCY    = 0x30,
+       AR9170_CMD_RF_INIT      = 0x31,
+       AR9170_CMD_SYNTH        = 0x32,
+       AR9170_CMD_FREQ_START   = 0x33,
+       AR9170_CMD_ECHO         = 0x80,
+       AR9170_CMD_TALLY        = 0x81,
+       AR9170_CMD_TALLY_APD    = 0x82,
+       AR9170_CMD_CONFIG       = 0x83,
+       AR9170_CMD_RESET        = 0x90,
+       AR9170_CMD_DKRESET      = 0x91,
+       AR9170_CMD_DKTX_STATUS  = 0x92,
+       AR9170_CMD_FDC          = 0xA0,
+       AR9170_CMD_WREEPROM     = 0xB0,
+       AR9170_CMD_WFLASH       = 0xB0,
+       AR9170_CMD_FLASH_ERASE  = 0xB1,
+       AR9170_CMD_FLASH_PROG   = 0xB2,
+       AR9170_CMD_FLASH_CHKSUM = 0xB3,
+       AR9170_CMD_FLASH_READ   = 0xB4,
+       AR9170_CMD_FW_DL_INIT   = 0xB5,
+       AR9170_CMD_MEM_WREEPROM = 0xBB,
+};
+
+/* endpoints */
+#define AR9170_EP_TX                           1
+#define AR9170_EP_RX                           2
+#define AR9170_EP_IRQ                          3
+#define AR9170_EP_CMD                          4
+
+#define AR9170_EEPROM_START                    0x1600
+
+#define AR9170_GPIO_REG_BASE                   0x1d0100
+#define AR9170_GPIO_REG_PORT_TYPE              AR9170_GPIO_REG_BASE
+#define AR9170_GPIO_REG_DATA                   (AR9170_GPIO_REG_BASE + 4)
+#define AR9170_NUM_LEDS                                2
+
+
+#define AR9170_USB_REG_BASE                    0x1e1000
+#define AR9170_USB_REG_DMA_CTL                 (AR9170_USB_REG_BASE + 0x108)
+#define                AR9170_DMA_CTL_ENABLE_TO_DEVICE         0x1
+#define                AR9170_DMA_CTL_ENABLE_FROM_DEVICE       0x2
+#define                AR9170_DMA_CTL_HIGH_SPEED               0x4
+#define                AR9170_DMA_CTL_PACKET_MODE              0x8
+
+#define AR9170_USB_REG_MAX_AGG_UPLOAD          (AR9170_USB_REG_BASE + 0x110)
+#define AR9170_USB_REG_UPLOAD_TIME_CTL         (AR9170_USB_REG_BASE + 0x114)
+
+
+
+#define AR9170_MAC_REG_BASE                    0x1c3000
+
+#define AR9170_MAC_REG_TSF_L                   (AR9170_MAC_REG_BASE + 0x514)
+#define AR9170_MAC_REG_TSF_H                   (AR9170_MAC_REG_BASE + 0x518)
+
+#define AR9170_MAC_REG_ATIM_WINDOW             (AR9170_MAC_REG_BASE + 0x51C)
+#define AR9170_MAC_REG_BCN_PERIOD              (AR9170_MAC_REG_BASE + 0x520)
+#define AR9170_MAC_REG_PRETBTT                 (AR9170_MAC_REG_BASE + 0x524)
+
+#define AR9170_MAC_REG_MAC_ADDR_L              (AR9170_MAC_REG_BASE + 0x610)
+#define AR9170_MAC_REG_MAC_ADDR_H              (AR9170_MAC_REG_BASE + 0x614)
+#define AR9170_MAC_REG_BSSID_L                 (AR9170_MAC_REG_BASE + 0x618)
+#define AR9170_MAC_REG_BSSID_H                 (AR9170_MAC_REG_BASE + 0x61c)
+
+#define AR9170_MAC_REG_GROUP_HASH_TBL_L                (AR9170_MAC_REG_BASE + 0x624)
+#define AR9170_MAC_REG_GROUP_HASH_TBL_H                (AR9170_MAC_REG_BASE + 0x628)
+
+#define AR9170_MAC_REG_RX_TIMEOUT              (AR9170_MAC_REG_BASE + 0x62C)
+
+#define AR9170_MAC_REG_BASIC_RATE              (AR9170_MAC_REG_BASE + 0x630)
+#define AR9170_MAC_REG_MANDATORY_RATE          (AR9170_MAC_REG_BASE + 0x634)
+#define AR9170_MAC_REG_RTS_CTS_RATE            (AR9170_MAC_REG_BASE + 0x638)
+#define AR9170_MAC_REG_BACKOFF_PROTECT         (AR9170_MAC_REG_BASE + 0x63c)
+#define AR9170_MAC_REG_RX_THRESHOLD            (AR9170_MAC_REG_BASE + 0x640)
+#define AR9170_MAC_REG_RX_PE_DELAY             (AR9170_MAC_REG_BASE + 0x64C)
+
+#define AR9170_MAC_REG_DYNAMIC_SIFS_ACK                (AR9170_MAC_REG_BASE + 0x658)
+#define AR9170_MAC_REG_SNIFFER                 (AR9170_MAC_REG_BASE + 0x674)
+#define                AR9170_MAC_REG_SNIFFER_ENABLE_PROMISC   BIT(0)
+#define                AR9170_MAC_REG_SNIFFER_DEFAULTS         0x02000000
+#define AR9170_MAC_REG_ENCRYPTION              (AR9170_MAC_REG_BASE + 0x678)
+#define                AR9170_MAC_REG_ENCRYPTION_RX_SOFTWARE   BIT(3)
+#define                AR9170_MAC_REG_ENCRYPTION_DEFAULTS      0x70
+
+#define AR9170_MAC_REG_MISC_680                        (AR9170_MAC_REG_BASE + 0x680)
+#define AR9170_MAC_REG_TX_UNDERRUN             (AR9170_MAC_REG_BASE + 0x688)
+
+#define AR9170_MAC_REG_FRAMETYPE_FILTER                (AR9170_MAC_REG_BASE + 0x68c)
+#define                AR9170_MAC_REG_FTF_ASSOC_REQ            BIT(0)
+#define                AR9170_MAC_REG_FTF_ASSOC_RESP           BIT(1)
+#define                AR9170_MAC_REG_FTF_REASSOC_REQ          BIT(2)
+#define                AR9170_MAC_REG_FTF_REASSOC_RESP         BIT(3)
+#define                AR9170_MAC_REG_FTF_PRB_REQ              BIT(4)
+#define                AR9170_MAC_REG_FTF_PRB_RESP             BIT(5)
+#define                AR9170_MAC_REG_FTF_BIT6                 BIT(6)
+#define                AR9170_MAC_REG_FTF_BIT7                 BIT(7)
+#define                AR9170_MAC_REG_FTF_BEACON               BIT(8)
+#define                AR9170_MAC_REG_FTF_ATIM                 BIT(9)
+#define                AR9170_MAC_REG_FTF_DEASSOC              BIT(10)
+#define                AR9170_MAC_REG_FTF_AUTH                 BIT(11)
+#define                AR9170_MAC_REG_FTF_DEAUTH               BIT(12)
+#define                AR9170_MAC_REG_FTF_BIT13                BIT(13)
+#define                AR9170_MAC_REG_FTF_BIT14                BIT(14)
+#define                AR9170_MAC_REG_FTF_BIT15                BIT(15)
+#define                AR9170_MAC_REG_FTF_BAR                  BIT(24)
+#define                AR9170_MAC_REG_FTF_BIT25                BIT(25)
+#define                AR9170_MAC_REG_FTF_PSPOLL               BIT(26)
+#define                AR9170_MAC_REG_FTF_RTS                  BIT(27)
+#define                AR9170_MAC_REG_FTF_CTS                  BIT(28)
+#define                AR9170_MAC_REG_FTF_ACK                  BIT(29)
+#define                AR9170_MAC_REG_FTF_CFE                  BIT(30)
+#define                AR9170_MAC_REG_FTF_CFE_ACK              BIT(31)
+#define                AR9170_MAC_REG_FTF_DEFAULTS             0x0500ffff
+#define                AR9170_MAC_REG_FTF_MONITOR              0xfd00ffff
+
+#define AR9170_MAC_REG_RX_TOTAL                        (AR9170_MAC_REG_BASE + 0x6A0)
+#define AR9170_MAC_REG_RX_CRC32                        (AR9170_MAC_REG_BASE + 0x6A4)
+#define AR9170_MAC_REG_RX_CRC16                        (AR9170_MAC_REG_BASE + 0x6A8)
+#define AR9170_MAC_REG_RX_ERR_DECRYPTION_UNI   (AR9170_MAC_REG_BASE + 0x6AC)
+#define AR9170_MAC_REG_RX_OVERRUN              (AR9170_MAC_REG_BASE + 0x6B0)
+#define AR9170_MAC_REG_RX_ERR_DECRYPTION_MUL   (AR9170_MAC_REG_BASE + 0x6BC)
+#define AR9170_MAC_REG_TX_RETRY                        (AR9170_MAC_REG_BASE + 0x6CC)
+#define AR9170_MAC_REG_TX_TOTAL                        (AR9170_MAC_REG_BASE + 0x6F4)
+
+
+#define AR9170_MAC_REG_ACK_EXTENSION           (AR9170_MAC_REG_BASE + 0x690)
+#define AR9170_MAC_REG_EIFS_AND_SIFS           (AR9170_MAC_REG_BASE + 0x698)
+
+#define AR9170_MAC_REG_SLOT_TIME               (AR9170_MAC_REG_BASE + 0x6F0)
+
+#define AR9170_MAC_REG_POWERMANAGEMENT         (AR9170_MAC_REG_BASE + 0x700)
+#define                AR9170_MAC_REG_POWERMGT_IBSS            0xe0
+#define                AR9170_MAC_REG_POWERMGT_AP              0xa1
+#define                AR9170_MAC_REG_POWERMGT_STA             0x2
+#define                AR9170_MAC_REG_POWERMGT_AP_WDS          0x3
+#define                AR9170_MAC_REG_POWERMGT_DEFAULTS        (0xf << 24)
+
+#define AR9170_MAC_REG_ROLL_CALL_TBL_L         (AR9170_MAC_REG_BASE + 0x704)
+#define AR9170_MAC_REG_ROLL_CALL_TBL_H         (AR9170_MAC_REG_BASE + 0x708)
+
+#define AR9170_MAC_REG_AC0_CW                  (AR9170_MAC_REG_BASE + 0xB00)
+#define AR9170_MAC_REG_AC1_CW                  (AR9170_MAC_REG_BASE + 0xB04)
+#define AR9170_MAC_REG_AC2_CW                  (AR9170_MAC_REG_BASE + 0xB08)
+#define AR9170_MAC_REG_AC3_CW                  (AR9170_MAC_REG_BASE + 0xB0C)
+#define AR9170_MAC_REG_AC4_CW                  (AR9170_MAC_REG_BASE + 0xB10)
+#define AR9170_MAC_REG_AC1_AC0_AIFS            (AR9170_MAC_REG_BASE + 0xB14)
+#define AR9170_MAC_REG_AC3_AC2_AIFS            (AR9170_MAC_REG_BASE + 0xB18)
+
+#define AR9170_MAC_REG_RETRY_MAX               (AR9170_MAC_REG_BASE + 0xB28)
+
+#define AR9170_MAC_REG_FCS_SELECT              (AR9170_MAC_REG_BASE + 0xBB0)
+#define                AR9170_MAC_FCS_SWFCS            0x1
+#define                AR9170_MAC_FCS_FIFO_PROT        0x4
+
+
+#define AR9170_MAC_REG_TXOP_NOT_ENOUGH_IND     (AR9170_MAC_REG_BASE + 0xB30)
+
+#define AR9170_MAC_REG_AC1_AC0_TXOP            (AR9170_MAC_REG_BASE + 0xB44)
+#define AR9170_MAC_REG_AC3_AC2_TXOP            (AR9170_MAC_REG_BASE + 0xB48)
+
+#define AR9170_MAC_REG_AMPDU_FACTOR            (AR9170_MAC_REG_BASE + 0xB9C)
+#define AR9170_MAC_REG_AMPDU_DENSITY           (AR9170_MAC_REG_BASE + 0xBA0)
+
+#define AR9170_MAC_REG_ACK_TABLE               (AR9170_MAC_REG_BASE + 0xC00)
+#define AR9170_MAC_REG_AMPDU_RX_THRESH         (AR9170_MAC_REG_BASE + 0xC50)
+
+#define AR9170_MAC_REG_TXRX_MPI                        (AR9170_MAC_REG_BASE + 0xD7C)
+#define                AR9170_MAC_TXRX_MPI_TX_MPI_MASK 0x0000000f
+#define                AR9170_MAC_TXRX_MPI_TX_TO_MASK  0x0000fff0
+#define                AR9170_MAC_TXRX_MPI_RX_MPI_MASK 0x000f0000
+#define                AR9170_MAC_TXRX_MPI_RX_TO_MASK  0xfff00000
+
+#define AR9170_MAC_REG_BCN_ADDR                        (AR9170_MAC_REG_BASE + 0xD84)
+#define AR9170_MAC_REG_BCN_LENGTH              (AR9170_MAC_REG_BASE + 0xD88)
+#define AR9170_MAC_REG_BCN_PLCP                        (AR9170_MAC_REG_BASE + 0xD90)
+#define AR9170_MAC_REG_BCN_CTRL                        (AR9170_MAC_REG_BASE + 0xD94)
+#define AR9170_MAC_REG_BCN_HT1                 (AR9170_MAC_REG_BASE + 0xDA0)
+#define AR9170_MAC_REG_BCN_HT2                 (AR9170_MAC_REG_BASE + 0xDA4)
+
+
+#define AR9170_PWR_REG_BASE                    0x1D4000
+
+#define AR9170_PWR_REG_CLOCK_SEL               (AR9170_PWR_REG_BASE + 0x008)
+#define                AR9170_PWR_CLK_AHB_40MHZ        0
+#define                AR9170_PWR_CLK_AHB_20_22MHZ     1
+#define                AR9170_PWR_CLK_AHB_40_44MHZ     2
+#define                AR9170_PWR_CLK_AHB_80_88MHZ     3
+#define                AR9170_PWR_CLK_DAC_160_INV_DLY  0x70
+
+
+/* put beacon here in memory */
+#define AR9170_BEACON_BUFFER_ADDRESS           0x117900
+
+
+struct ar9170_tx_control {
+       __le16 length;
+       __le16 mac_control;
+       __le32 phy_control;
+       u8 frame_data[0];
+} __packed;
+
+/* these are either-or */
+#define AR9170_TX_MAC_PROT_RTS                 0x0001
+#define AR9170_TX_MAC_PROT_CTS                 0x0002
+
+#define AR9170_TX_MAC_NO_ACK                   0x0004
+/* if unset, MAC will only do SIFS space before frame */
+#define AR9170_TX_MAC_BACKOFF                  0x0008
+#define AR9170_TX_MAC_BURST                    0x0010
+#define AR9170_TX_MAC_AGGR                     0x0020
+
+/* encryption is a two-bit field */
+#define AR9170_TX_MAC_ENCR_NONE                        0x0000
+#define AR9170_TX_MAC_ENCR_RC4                 0x0040
+#define AR9170_TX_MAC_ENCR_CENC                        0x0080
+#define AR9170_TX_MAC_ENCR_AES                 0x00c0
+
+#define AR9170_TX_MAC_MMIC                     0x0100
+#define AR9170_TX_MAC_HW_DURATION              0x0200
+#define AR9170_TX_MAC_QOS_SHIFT                        10
+#define AR9170_TX_MAC_QOS_MASK                 (3 << AR9170_TX_MAC_QOS_SHIFT)
+#define AR9170_TX_MAC_AGGR_QOS_BIT1            0x0400
+#define AR9170_TX_MAC_AGGR_QOS_BIT2            0x0800
+#define AR9170_TX_MAC_DISABLE_TXOP             0x1000
+#define AR9170_TX_MAC_TXOP_RIFS                        0x2000
+#define AR9170_TX_MAC_IMM_AMPDU                        0x4000
+#define AR9170_TX_MAC_RATE_PROBE               0x8000
+
+/* either-or */
+#define AR9170_TX_PHY_MOD_CCK                  0x00000000
+#define AR9170_TX_PHY_MOD_OFDM                 0x00000001
+#define AR9170_TX_PHY_MOD_HT                   0x00000002
+
+/* depends on modulation */
+#define AR9170_TX_PHY_SHORT_PREAMBLE           0x00000004
+#define AR9170_TX_PHY_GREENFIELD               0x00000004
+
+#define AR9170_TX_PHY_BW_SHIFT                 3
+#define AR9170_TX_PHY_BW_MASK                  (3 << AR9170_TX_PHY_BW_SHIFT)
+#define AR9170_TX_PHY_BW_20MHZ                 0
+#define AR9170_TX_PHY_BW_40MHZ                 2
+#define AR9170_TX_PHY_BW_40MHZ_DUP             3
+
+#define AR9170_TX_PHY_TX_HEAVY_CLIP_SHIFT      6
+#define AR9170_TX_PHY_TX_HEAVY_CLIP_MASK       (7 << AR9170_TX_PHY_TX_HEAVY_CLIP_SHIFT)
+
+#define AR9170_TX_PHY_TX_PWR_SHIFT             9
+#define AR9170_TX_PHY_TX_PWR_MASK              (0x3f << AR9170_TX_PHY_TX_PWR_SHIFT)
+
+/* not part of the hw-spec */
+#define AR9170_TX_PHY_QOS_SHIFT                        25
+#define AR9170_TX_PHY_QOS_MASK                 (3 << AR9170_TX_PHY_QOS_SHIFT)
+
+#define AR9170_TX_PHY_TXCHAIN_SHIFT            15
+#define AR9170_TX_PHY_TXCHAIN_MASK             (7 << AR9170_TX_PHY_TXCHAIN_SHIFT)
+#define AR9170_TX_PHY_TXCHAIN_1                        1
+/* use for cck, ofdm 6/9/12/18/24 and HT if capable */
+#define AR9170_TX_PHY_TXCHAIN_2                        5
+
+#define AR9170_TX_PHY_MCS_SHIFT                        18
+#define AR9170_TX_PHY_MCS_MASK                 (0x7f << AR9170_TX_PHY_MCS_SHIFT)
+
+#define AR9170_TX_PHY_SHORT_GI                 0x80000000
+
+struct ar9170_rx_head {
+       u8 plcp[12];
+} __packed;
+
+struct ar9170_rx_phystatus {
+       union {
+               struct {
+                       u8 rssi_ant0, rssi_ant1, rssi_ant2,
+                          rssi_ant0x, rssi_ant1x, rssi_ant2x,
+                          rssi_combined;
+               } __packed;
+               u8 rssi[7];
+       } __packed;
+
+       u8 evm_stream0[6], evm_stream1[6];
+       u8 phy_err;
+} __packed;
+
+struct ar9170_rx_macstatus {
+       u8 SAidx, DAidx;
+       u8 error;
+       u8 status;
+} __packed;
+
+#define AR9170_ENC_ALG_NONE                    0x0
+#define AR9170_ENC_ALG_WEP64                   0x1
+#define AR9170_ENC_ALG_TKIP                    0x2
+#define AR9170_ENC_ALG_AESCCMP                 0x4
+#define AR9170_ENC_ALG_WEP128                  0x5
+#define AR9170_ENC_ALG_WEP256                  0x6
+#define AR9170_ENC_ALG_CENC                    0x7
+
+#define AR9170_RX_ENC_SOFTWARE                 0x8
+
+static inline u8 ar9170_get_decrypt_type(struct ar9170_rx_macstatus *t)
+{
+       return (t->SAidx & 0xc0) >> 4 |
+              (t->DAidx & 0xc0) >> 6;
+}
+
+#define AR9170_RX_STATUS_MODULATION_MASK       0x03
+#define AR9170_RX_STATUS_MODULATION_CCK                0x00
+#define AR9170_RX_STATUS_MODULATION_OFDM       0x01
+#define AR9170_RX_STATUS_MODULATION_HT         0x02
+#define AR9170_RX_STATUS_MODULATION_DUPOFDM    0x03
+
+/* depends on modulation */
+#define AR9170_RX_STATUS_SHORT_PREAMBLE                0x08
+#define AR9170_RX_STATUS_GREENFIELD            0x08
+
+#define AR9170_RX_STATUS_MPDU_MASK             0x30
+#define AR9170_RX_STATUS_MPDU_SINGLE           0x00
+#define AR9170_RX_STATUS_MPDU_FIRST            0x20
+#define AR9170_RX_STATUS_MPDU_MIDDLE           0x30
+#define AR9170_RX_STATUS_MPDU_LAST             0x10
+
+#define AR9170_RX_ERROR_RXTO                   0x01
+#define AR9170_RX_ERROR_OVERRUN                        0x02
+#define AR9170_RX_ERROR_DECRYPT                        0x04
+#define AR9170_RX_ERROR_FCS                    0x08
+#define AR9170_RX_ERROR_WRONG_RA               0x10
+#define AR9170_RX_ERROR_PLCP                   0x20
+#define AR9170_RX_ERROR_MMIC                   0x40
+#define AR9170_RX_ERROR_FATAL                  0x80
+
+struct ar9170_cmd_tx_status {
+       u8 dst[ETH_ALEN];
+       __le32 rate;
+       __le16 status;
+} __packed;
+
+#define AR9170_TX_STATUS_COMPLETE              0x00
+#define AR9170_TX_STATUS_RETRY                 0x01
+#define AR9170_TX_STATUS_FAILED                        0x02
+
+struct ar9170_cmd_ba_failed_count {
+       __le16 failed;
+       __le16 rate;
+} __packed;
+
+struct ar9170_cmd_response {
+       u8 flag;
+       u8 type;
+       __le16 padding;
+
+       union {
+               struct ar9170_cmd_tx_status             tx_status;
+               struct ar9170_cmd_ba_failed_count       ba_fail_cnt;
+               u8 data[0];
+       };
+} __packed;
+
+/* QoS */
+
+/* mac80211 queue to HW/FW map */
+static const u8 ar9170_qos_hwmap[4] = { 3, 2, 0, 1 };
+
+/* HW/FW queue to mac80211 map */
+static const u8 ar9170_qos_mac80211map[4] = { 2, 3, 1, 0 };
+
+enum ar9170_txq {
+       AR9170_TXQ_BE,
+       AR9170_TXQ_BK,
+       AR9170_TXQ_VI,
+       AR9170_TXQ_VO,
+
+       __AR9170_NUM_TXQ,
+};
+
+#define AR9170_TXQ_DEPTH       32
+#define AR9170_TX_MAX_PENDING  128
+
+#endif /* __AR9170_HW_H */
diff --git a/drivers/net/wireless/ath/ar9170/led.c b/drivers/net/wireless/ath/ar9170/led.c
new file mode 100644 (file)
index 0000000..63fda6c
--- /dev/null
@@ -0,0 +1,178 @@
+/*
+ * Atheros AR9170 driver
+ *
+ * LED handling
+ *
+ * Copyright 2008, 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 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; see the file COPYING.  If not, see
+ * http://www.gnu.org/licenses/.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ *    Copyright (c) 2007-2008 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 "ar9170.h"
+#include "cmd.h"
+
+int ar9170_set_leds_state(struct ar9170 *ar, u32 led_state)
+{
+       return ar9170_write_reg(ar, AR9170_GPIO_REG_DATA, led_state);
+}
+
+int ar9170_init_leds(struct ar9170 *ar)
+{
+       int err;
+
+       /* disable LEDs */
+       /* GPIO [0/1 mode: output, 2/3: input] */
+       err = ar9170_write_reg(ar, AR9170_GPIO_REG_PORT_TYPE, 3);
+       if (err)
+               goto out;
+
+       /* GPIO 0/1 value: off */
+       err = ar9170_set_leds_state(ar, 0);
+
+out:
+       return err;
+}
+
+#ifdef CONFIG_AR9170_LEDS
+static void ar9170_update_leds(struct work_struct *work)
+{
+       struct ar9170 *ar = container_of(work, struct ar9170, led_work.work);
+       int i, tmp, blink_delay = 1000;
+       u32 led_val = 0;
+       bool rerun = false;
+
+       if (unlikely(!IS_ACCEPTING_CMD(ar)))
+               return ;
+
+       mutex_lock(&ar->mutex);
+       for (i = 0; i < AR9170_NUM_LEDS; i++)
+               if (ar->leds[i].registered && ar->leds[i].toggled) {
+                       led_val |= 1 << i;
+
+                       tmp = 70 + 200 / (ar->leds[i].toggled);
+                       if (tmp < blink_delay)
+                               blink_delay = tmp;
+
+                       if (ar->leds[i].toggled > 1)
+                               ar->leds[i].toggled = 0;
+
+                       rerun = true;
+               }
+
+       ar9170_set_leds_state(ar, led_val);
+       mutex_unlock(&ar->mutex);
+
+       if (rerun)
+               queue_delayed_work(ar->hw->workqueue, &ar->led_work,
+                                  msecs_to_jiffies(blink_delay));
+}
+
+static void ar9170_led_brightness_set(struct led_classdev *led,
+                                     enum led_brightness brightness)
+{
+       struct ar9170_led *arl = container_of(led, struct ar9170_led, l);
+       struct ar9170 *ar = arl->ar;
+
+       if (unlikely(!arl->registered))
+               return ;
+
+       if (arl->last_state != !!brightness) {
+               arl->toggled++;
+               arl->last_state = !!brightness;
+       }
+
+       if (likely(IS_ACCEPTING_CMD(ar) && arl->toggled))
+               queue_delayed_work(ar->hw->workqueue, &ar->led_work, HZ/10);
+}
+
+static int ar9170_register_led(struct ar9170 *ar, int i, char *name,
+                              char *trigger)
+{
+       int err;
+
+       snprintf(ar->leds[i].name, sizeof(ar->leds[i].name),
+                "ar9170-%s::%s", wiphy_name(ar->hw->wiphy), name);
+
+       ar->leds[i].ar = ar;
+       ar->leds[i].l.name = ar->leds[i].name;
+       ar->leds[i].l.brightness_set = ar9170_led_brightness_set;
+       ar->leds[i].l.brightness = 0;
+       ar->leds[i].l.default_trigger = trigger;
+
+       err = led_classdev_register(wiphy_dev(ar->hw->wiphy),
+                                   &ar->leds[i].l);
+       if (err)
+               printk(KERN_ERR "%s: failed to register %s LED (%d).\n",
+                      wiphy_name(ar->hw->wiphy), ar->leds[i].name, err);
+       else
+               ar->leds[i].registered = true;
+
+       return err;
+}
+
+void ar9170_unregister_leds(struct ar9170 *ar)
+{
+       int i;
+
+       for (i = 0; i < AR9170_NUM_LEDS; i++)
+               if (ar->leds[i].registered) {
+                       led_classdev_unregister(&ar->leds[i].l);
+                       ar->leds[i].registered = false;
+                       ar->leds[i].toggled = 0;
+               }
+
+       cancel_delayed_work_sync(&ar->led_work);
+}
+
+int ar9170_register_leds(struct ar9170 *ar)
+{
+       int err;
+
+       INIT_DELAYED_WORK(&ar->led_work, ar9170_update_leds);
+
+       err = ar9170_register_led(ar, 0, "tx",
+                                 ieee80211_get_tx_led_name(ar->hw));
+       if (err)
+               goto fail;
+
+       err = ar9170_register_led(ar, 1, "assoc",
+                                ieee80211_get_assoc_led_name(ar->hw));
+       if (err)
+               goto fail;
+
+       return 0;
+
+fail:
+       ar9170_unregister_leds(ar);
+       return err;
+}
+
+#endif /* CONFIG_AR9170_LEDS */
diff --git a/drivers/net/wireless/ath/ar9170/mac.c b/drivers/net/wireless/ath/ar9170/mac.c
new file mode 100644 (file)
index 0000000..d9f1f46
--- /dev/null
@@ -0,0 +1,524 @@
+/*
+ * Atheros AR9170 driver
+ *
+ * MAC programming
+ *
+ * Copyright 2008, 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 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; see the file COPYING.  If not, see
+ * http://www.gnu.org/licenses/.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ *    Copyright (c) 2007-2008 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 "ar9170.h"
+#include "cmd.h"
+
+int ar9170_set_dyn_sifs_ack(struct ar9170 *ar)
+{
+       u32 val;
+
+       if (conf_is_ht40(&ar->hw->conf))
+               val = 0x010a;
+       else {
+               if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ)
+                       val = 0x105;
+               else
+                       val = 0x104;
+       }
+
+       return ar9170_write_reg(ar, AR9170_MAC_REG_DYNAMIC_SIFS_ACK, val);
+}
+
+int ar9170_set_slot_time(struct ar9170 *ar)
+{
+       u32 slottime = 20;
+
+       if (!ar->vif)
+               return 0;
+
+       if ((ar->hw->conf.channel->band == IEEE80211_BAND_5GHZ) ||
+           ar->vif->bss_conf.use_short_slot)
+               slottime = 9;
+
+       return ar9170_write_reg(ar, AR9170_MAC_REG_SLOT_TIME, slottime << 10);
+}
+
+int ar9170_set_basic_rates(struct ar9170 *ar)
+{
+       u8 cck, ofdm;
+
+       if (!ar->vif)
+               return 0;
+
+       ofdm = ar->vif->bss_conf.basic_rates >> 4;
+
+       /* FIXME: is still necessary? */
+       if (ar->hw->conf.channel->band == IEEE80211_BAND_5GHZ)
+               cck = 0;
+       else
+               cck = ar->vif->bss_conf.basic_rates & 0xf;
+
+       return ar9170_write_reg(ar, AR9170_MAC_REG_BASIC_RATE,
+                               ofdm << 8 | cck);
+}
+
+int ar9170_set_qos(struct ar9170 *ar)
+{
+       ar9170_regwrite_begin(ar);
+
+       ar9170_regwrite(AR9170_MAC_REG_AC0_CW, ar->edcf[0].cw_min |
+                       (ar->edcf[0].cw_max << 16));
+       ar9170_regwrite(AR9170_MAC_REG_AC1_CW, ar->edcf[1].cw_min |
+                       (ar->edcf[1].cw_max << 16));
+       ar9170_regwrite(AR9170_MAC_REG_AC2_CW, ar->edcf[2].cw_min |
+                       (ar->edcf[2].cw_max << 16));
+       ar9170_regwrite(AR9170_MAC_REG_AC3_CW, ar->edcf[3].cw_min |
+                       (ar->edcf[3].cw_max << 16));
+       ar9170_regwrite(AR9170_MAC_REG_AC4_CW, ar->edcf[4].cw_min |
+                       (ar->edcf[4].cw_max << 16));
+
+       ar9170_regwrite(AR9170_MAC_REG_AC1_AC0_AIFS,
+                       ((ar->edcf[0].aifs * 9 + 10)) |
+                       ((ar->edcf[1].aifs * 9 + 10) << 12) |
+                       ((ar->edcf[2].aifs * 9 + 10) << 24));
+       ar9170_regwrite(AR9170_MAC_REG_AC3_AC2_AIFS,
+                       ((ar->edcf[2].aifs * 9 + 10) >> 8) |
+                       ((ar->edcf[3].aifs * 9 + 10) << 4) |
+                       ((ar->edcf[4].aifs * 9 + 10) << 16));
+
+       ar9170_regwrite(AR9170_MAC_REG_AC1_AC0_TXOP,
+                       ar->edcf[0].txop | ar->edcf[1].txop << 16);
+       ar9170_regwrite(AR9170_MAC_REG_AC3_AC2_TXOP,
+                       ar->edcf[1].txop | ar->edcf[3].txop << 16);
+
+       ar9170_regwrite_finish();
+
+       return ar9170_regwrite_result();
+}
+
+static int ar9170_set_ampdu_density(struct ar9170 *ar, u8 mpdudensity)
+{
+       u32 val;
+
+       /* don't allow AMPDU density > 8us */
+       if (mpdudensity > 6)
+               return -EINVAL;
+
+       /* Watch out! Otus uses slightly different density values. */
+       val = 0x140a00 | (mpdudensity ? (mpdudensity + 1) : 0);
+
+       ar9170_regwrite_begin(ar);
+       ar9170_regwrite(AR9170_MAC_REG_AMPDU_DENSITY, val);
+       ar9170_regwrite_finish();
+
+       return ar9170_regwrite_result();
+}
+
+int ar9170_init_mac(struct ar9170 *ar)
+{
+       ar9170_regwrite_begin(ar);
+
+       ar9170_regwrite(AR9170_MAC_REG_ACK_EXTENSION, 0x40);
+
+       ar9170_regwrite(AR9170_MAC_REG_RETRY_MAX, 0);
+
+       /* enable MMIC */
+       ar9170_regwrite(AR9170_MAC_REG_SNIFFER,
+                       AR9170_MAC_REG_SNIFFER_DEFAULTS);
+
+       ar9170_regwrite(AR9170_MAC_REG_RX_THRESHOLD, 0xc1f80);
+
+       ar9170_regwrite(AR9170_MAC_REG_RX_PE_DELAY, 0x70);
+       ar9170_regwrite(AR9170_MAC_REG_EIFS_AND_SIFS, 0xa144000);
+       ar9170_regwrite(AR9170_MAC_REG_SLOT_TIME, 9 << 10);
+
+       /* CF-END mode */
+       ar9170_regwrite(0x1c3b2c, 0x19000000);
+
+       /* NAV protects ACK only (in TXOP) */
+       ar9170_regwrite(0x1c3b38, 0x201);
+
+       /* Set Beacon PHY CTRL's TPC to 0x7, TA1=1 */
+       /* OTUS set AM to 0x1 */
+       ar9170_regwrite(AR9170_MAC_REG_BCN_HT1, 0x8000170);
+
+       ar9170_regwrite(AR9170_MAC_REG_BACKOFF_PROTECT, 0x105);
+
+       /* AGG test code*/
+       /* Aggregation MAX number and timeout */
+       ar9170_regwrite(0x1c3b9c, 0x10000a);
+
+       ar9170_regwrite(AR9170_MAC_REG_FRAMETYPE_FILTER,
+                       AR9170_MAC_REG_FTF_DEFAULTS);
+
+       /* Enable deaggregator, response in sniffer mode */
+       ar9170_regwrite(0x1c3c40, 0x1 | 1<<30);
+
+       /* rate sets */
+       ar9170_regwrite(AR9170_MAC_REG_BASIC_RATE, 0x150f);
+       ar9170_regwrite(AR9170_MAC_REG_MANDATORY_RATE, 0x150f);
+       ar9170_regwrite(AR9170_MAC_REG_RTS_CTS_RATE, 0x10b01bb);
+
+       /* MIMO response control */
+       ar9170_regwrite(0x1c3694, 0x4003C1E);/* bit 26~28  otus-AM */
+
+       /* switch MAC to OTUS interface */
+       ar9170_regwrite(0x1c3600, 0x3);
+
+       ar9170_regwrite(AR9170_MAC_REG_AMPDU_RX_THRESH, 0xffff);
+
+       /* set PHY register read timeout (??) */
+       ar9170_regwrite(AR9170_MAC_REG_MISC_680, 0xf00008);
+
+       /* Disable Rx TimeOut, workaround for BB. */
+       ar9170_regwrite(AR9170_MAC_REG_RX_TIMEOUT, 0x0);
+
+       /* Set CPU clock frequency to 88/80MHz */
+       ar9170_regwrite(AR9170_PWR_REG_CLOCK_SEL,
+                       AR9170_PWR_CLK_AHB_80_88MHZ |
+                       AR9170_PWR_CLK_DAC_160_INV_DLY);
+
+       /* Set WLAN DMA interrupt mode: generate int per packet */
+       ar9170_regwrite(AR9170_MAC_REG_TXRX_MPI, 0x110011);
+
+       ar9170_regwrite(AR9170_MAC_REG_FCS_SELECT,
+                       AR9170_MAC_FCS_FIFO_PROT);
+
+       /* Disables the CF_END frame, undocumented register */
+       ar9170_regwrite(AR9170_MAC_REG_TXOP_NOT_ENOUGH_IND,
+                       0x141E0F48);
+
+       ar9170_regwrite_finish();
+
+       return ar9170_regwrite_result();
+}
+
+static int ar9170_set_mac_reg(struct ar9170 *ar, const u32 reg, const u8 *mac)
+{
+       static const u8 zero[ETH_ALEN] = { 0 };
+
+       if (!mac)
+               mac = zero;
+
+       ar9170_regwrite_begin(ar);
+
+       ar9170_regwrite(reg,
+                       (mac[3] << 24) | (mac[2] << 16) |
+                       (mac[1] << 8) | mac[0]);
+
+       ar9170_regwrite(reg + 4, (mac[5] << 8) | mac[4]);
+
+       ar9170_regwrite_finish();
+
+       return ar9170_regwrite_result();
+}
+
+int ar9170_update_multicast(struct ar9170 *ar)
+{
+       int err;
+
+       ar9170_regwrite_begin(ar);
+       ar9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_H,
+               ar->want_mc_hash >> 32);
+       ar9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_L,
+               ar->want_mc_hash);
+
+       ar9170_regwrite_finish();
+       err = ar9170_regwrite_result();
+
+       if (err)
+               return err;
+
+       ar->cur_mc_hash = ar->want_mc_hash;
+
+       return 0;
+}
+
+int ar9170_update_frame_filter(struct ar9170 *ar)
+{
+       int err;
+
+       err = ar9170_write_reg(ar, AR9170_MAC_REG_FRAMETYPE_FILTER,
+                              ar->want_filter);
+
+       if (err)
+               return err;
+
+       ar->cur_filter = ar->want_filter;
+
+       return 0;
+}
+
+static int ar9170_set_promiscouous(struct ar9170 *ar)
+{
+       u32 encr_mode, sniffer;
+       int err;
+
+       err = ar9170_read_reg(ar, AR9170_MAC_REG_SNIFFER, &sniffer);
+       if (err)
+               return err;
+
+       err = ar9170_read_reg(ar, AR9170_MAC_REG_ENCRYPTION, &encr_mode);
+       if (err)
+               return err;
+
+       if (ar->sniffer_enabled) {
+               sniffer |= AR9170_MAC_REG_SNIFFER_ENABLE_PROMISC;
+
+               /*
+                * Rx decryption works in place.
+                *
+                * If we don't disable it, the hardware will render all
+                * encrypted frames which are encrypted with an unknown
+                * key useless.
+                */
+
+               encr_mode |= AR9170_MAC_REG_ENCRYPTION_RX_SOFTWARE;
+               ar->sniffer_enabled = true;
+       } else {
+               sniffer &= ~AR9170_MAC_REG_SNIFFER_ENABLE_PROMISC;
+
+               if (ar->rx_software_decryption)
+                       encr_mode |= AR9170_MAC_REG_ENCRYPTION_RX_SOFTWARE;
+               else
+                       encr_mode &= ~AR9170_MAC_REG_ENCRYPTION_RX_SOFTWARE;
+       }
+
+       ar9170_regwrite_begin(ar);
+       ar9170_regwrite(AR9170_MAC_REG_ENCRYPTION, encr_mode);
+       ar9170_regwrite(AR9170_MAC_REG_SNIFFER, sniffer);
+       ar9170_regwrite_finish();
+
+       return ar9170_regwrite_result();
+}
+
+int ar9170_set_operating_mode(struct ar9170 *ar)
+{
+       u32 pm_mode = AR9170_MAC_REG_POWERMGT_DEFAULTS;
+       u8 *mac_addr, *bssid;
+       int err;
+
+       if (ar->vif) {
+               mac_addr = ar->mac_addr;
+               bssid = ar->bssid;
+
+               switch (ar->vif->type) {
+               case NL80211_IFTYPE_MESH_POINT:
+               case NL80211_IFTYPE_ADHOC:
+                       pm_mode |= AR9170_MAC_REG_POWERMGT_IBSS;
+                       break;
+               case NL80211_IFTYPE_AP:
+                       pm_mode |= AR9170_MAC_REG_POWERMGT_AP;
+                       break;
+               case NL80211_IFTYPE_WDS:
+                       pm_mode |= AR9170_MAC_REG_POWERMGT_AP_WDS;
+                       break;
+               case NL80211_IFTYPE_MONITOR:
+                       ar->sniffer_enabled = true;
+                       ar->rx_software_decryption = true;
+                       break;
+               default:
+                       pm_mode |= AR9170_MAC_REG_POWERMGT_STA;
+                       break;
+               }
+       } else {
+               mac_addr = NULL;
+               bssid = NULL;
+       }
+
+       err = ar9170_set_mac_reg(ar, AR9170_MAC_REG_MAC_ADDR_L, mac_addr);
+       if (err)
+               return err;
+
+       err = ar9170_set_mac_reg(ar, AR9170_MAC_REG_BSSID_L, bssid);
+       if (err)
+               return err;
+
+       err = ar9170_set_promiscouous(ar);
+       if (err)
+               return err;
+
+       /* set AMPDU density to 8us. */
+       err = ar9170_set_ampdu_density(ar, 6);
+       if (err)
+               return err;
+
+       ar9170_regwrite_begin(ar);
+
+       ar9170_regwrite(AR9170_MAC_REG_POWERMANAGEMENT, pm_mode);
+       ar9170_regwrite_finish();
+
+       return ar9170_regwrite_result();
+}
+
+int ar9170_set_hwretry_limit(struct ar9170 *ar, unsigned int max_retry)
+{
+       u32 tmp = min_t(u32, 0x33333, max_retry * 0x11111);
+
+       return ar9170_write_reg(ar, AR9170_MAC_REG_RETRY_MAX, tmp);
+}
+
+int ar9170_set_beacon_timers(struct ar9170 *ar)
+{
+       u32 v = 0;
+       u32 pretbtt = 0;
+
+       if (ar->vif) {
+               v |= ar->vif->bss_conf.beacon_int;
+
+               switch (ar->vif->type) {
+               case NL80211_IFTYPE_MESH_POINT:
+               case NL80211_IFTYPE_ADHOC:
+                       v |= BIT(25);
+                       break;
+               case NL80211_IFTYPE_AP:
+                       v |= BIT(24);
+                       pretbtt = (ar->vif->bss_conf.beacon_int - 6) << 16;
+                       break;
+               default:
+                       break;
+               }
+
+               v |= ar->vif->bss_conf.dtim_period << 16;
+       }
+
+       ar9170_regwrite_begin(ar);
+
+       ar9170_regwrite(AR9170_MAC_REG_PRETBTT, pretbtt);
+       ar9170_regwrite(AR9170_MAC_REG_BCN_PERIOD, v);
+       ar9170_regwrite_finish();
+       return ar9170_regwrite_result();
+}
+
+int ar9170_update_beacon(struct ar9170 *ar)
+{
+       struct sk_buff *skb;
+       __le32 *data, *old = NULL;
+       u32 word;
+       int i;
+
+       skb = ieee80211_beacon_get(ar->hw, ar->vif);
+       if (!skb)
+               return -ENOMEM;
+
+       data = (__le32 *)skb->data;
+       if (ar->beacon)
+               old = (__le32 *)ar->beacon->data;
+
+       ar9170_regwrite_begin(ar);
+       for (i = 0; i < DIV_ROUND_UP(skb->len, 4); i++) {
+               /*
+                * XXX: This accesses beyond skb data for up
+                *      to the last 3 bytes!!
+                */
+
+               if (old && (data[i] == old[i]))
+                       continue;
+
+               word = le32_to_cpu(data[i]);
+               ar9170_regwrite(AR9170_BEACON_BUFFER_ADDRESS + 4 * i, word);
+       }
+
+       /* XXX: use skb->cb info */
+       if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ)
+               ar9170_regwrite(AR9170_MAC_REG_BCN_PLCP,
+                               ((skb->len + 4) << (3 + 16)) + 0x0400);
+       else
+               ar9170_regwrite(AR9170_MAC_REG_BCN_PLCP,
+                               ((skb->len + 4) << 16) + 0x001b);
+
+       ar9170_regwrite(AR9170_MAC_REG_BCN_LENGTH, skb->len + 4);
+       ar9170_regwrite(AR9170_MAC_REG_BCN_ADDR, AR9170_BEACON_BUFFER_ADDRESS);
+       ar9170_regwrite(AR9170_MAC_REG_BCN_CTRL, 1);
+
+       ar9170_regwrite_finish();
+
+       dev_kfree_skb(ar->beacon);
+       ar->beacon = skb;
+
+       return ar9170_regwrite_result();
+}
+
+void ar9170_new_beacon(struct work_struct *work)
+{
+       struct ar9170 *ar = container_of(work, struct ar9170,
+                                        beacon_work);
+       struct sk_buff *skb;
+
+       if (unlikely(!IS_STARTED(ar)))
+               return ;
+
+       mutex_lock(&ar->mutex);
+
+       if (!ar->vif)
+               goto out;
+
+       ar9170_update_beacon(ar);
+
+       rcu_read_lock();
+       while ((skb = ieee80211_get_buffered_bc(ar->hw, ar->vif)))
+               ar9170_op_tx(ar->hw, skb);
+
+       rcu_read_unlock();
+
+ out:
+       mutex_unlock(&ar->mutex);
+}
+
+int ar9170_upload_key(struct ar9170 *ar, u8 id, const u8 *mac, u8 ktype,
+                     u8 keyidx, u8 *keydata, int keylen)
+{
+       __le32 vals[7];
+       static const u8 bcast[ETH_ALEN] =
+               { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+       u8 dummy;
+
+       mac = mac ? : bcast;
+
+       vals[0] = cpu_to_le32((keyidx << 16) + id);
+       vals[1] = cpu_to_le32(mac[1] << 24 | mac[0] << 16 | ktype);
+       vals[2] = cpu_to_le32(mac[5] << 24 | mac[4] << 16 |
+                             mac[3] << 8 | mac[2]);
+       memset(&vals[3], 0, 16);
+       if (keydata)
+               memcpy(&vals[3], keydata, keylen);
+
+       return ar->exec_cmd(ar, AR9170_CMD_EKEY,
+                           sizeof(vals), (u8 *)vals,
+                           1, &dummy);
+}
+
+int ar9170_disable_key(struct ar9170 *ar, u8 id)
+{
+       __le32 val = cpu_to_le32(id);
+       u8 dummy;
+
+       return ar->exec_cmd(ar, AR9170_CMD_EKEY,
+                           sizeof(val), (u8 *)&val,
+                           1, &dummy);
+}
diff --git a/drivers/net/wireless/ath/ar9170/main.c b/drivers/net/wireless/ath/ar9170/main.c
new file mode 100644 (file)
index 0000000..9d38cf6
--- /dev/null
@@ -0,0 +1,2210 @@
+/*
+ * Atheros AR9170 driver
+ *
+ * mac80211 interaction code
+ *
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
+ * Copyright 2009, Christian Lamparter <chunkeey@web.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.
+ *
+ * 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; see the file COPYING.  If not, see
+ * http://www.gnu.org/licenses/.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ *    Copyright (c) 2007-2008 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/init.h>
+#include <linux/module.h>
+#include <linux/etherdevice.h>
+#include <net/mac80211.h>
+#include "ar9170.h"
+#include "hw.h"
+#include "cmd.h"
+
+static int modparam_nohwcrypt;
+module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
+MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
+
+#define RATE(_bitrate, _hw_rate, _txpidx, _flags) {    \
+       .bitrate        = (_bitrate),                   \
+       .flags          = (_flags),                     \
+       .hw_value       = (_hw_rate) | (_txpidx) << 4,  \
+}
+
+static struct ieee80211_rate __ar9170_ratetable[] = {
+       RATE(10, 0, 0, 0),
+       RATE(20, 1, 1, IEEE80211_RATE_SHORT_PREAMBLE),
+       RATE(55, 2, 2, IEEE80211_RATE_SHORT_PREAMBLE),
+       RATE(110, 3, 3, IEEE80211_RATE_SHORT_PREAMBLE),
+       RATE(60, 0xb, 0, 0),
+       RATE(90, 0xf, 0, 0),
+       RATE(120, 0xa, 0, 0),
+       RATE(180, 0xe, 0, 0),
+       RATE(240, 0x9, 0, 0),
+       RATE(360, 0xd, 1, 0),
+       RATE(480, 0x8, 2, 0),
+       RATE(540, 0xc, 3, 0),
+};
+#undef RATE
+
+#define ar9170_g_ratetable     (__ar9170_ratetable + 0)
+#define ar9170_g_ratetable_size        12
+#define ar9170_a_ratetable     (__ar9170_ratetable + 4)
+#define ar9170_a_ratetable_size        8
+
+/*
+ * NB: The hw_value is used as an index into the ar9170_phy_freq_params
+ *     array in phy.c so that we don't have to do frequency lookups!
+ */
+#define CHAN(_freq, _idx) {            \
+       .center_freq    = (_freq),      \
+       .hw_value       = (_idx),       \
+       .max_power      = 18, /* XXX */ \
+}
+
+static struct ieee80211_channel ar9170_2ghz_chantable[] = {
+       CHAN(2412,  0),
+       CHAN(2417,  1),
+       CHAN(2422,  2),
+       CHAN(2427,  3),
+       CHAN(2432,  4),
+       CHAN(2437,  5),
+       CHAN(2442,  6),
+       CHAN(2447,  7),
+       CHAN(2452,  8),
+       CHAN(2457,  9),
+       CHAN(2462, 10),
+       CHAN(2467, 11),
+       CHAN(2472, 12),
+       CHAN(2484, 13),
+};
+
+static struct ieee80211_channel ar9170_5ghz_chantable[] = {
+       CHAN(4920, 14),
+       CHAN(4940, 15),
+       CHAN(4960, 16),
+       CHAN(4980, 17),
+       CHAN(5040, 18),
+       CHAN(5060, 19),
+       CHAN(5080, 20),
+       CHAN(5180, 21),
+       CHAN(5200, 22),
+       CHAN(5220, 23),
+       CHAN(5240, 24),
+       CHAN(5260, 25),
+       CHAN(5280, 26),
+       CHAN(5300, 27),
+       CHAN(5320, 28),
+       CHAN(5500, 29),
+       CHAN(5520, 30),
+       CHAN(5540, 31),
+       CHAN(5560, 32),
+       CHAN(5580, 33),
+       CHAN(5600, 34),
+       CHAN(5620, 35),
+       CHAN(5640, 36),
+       CHAN(5660, 37),
+       CHAN(5680, 38),
+       CHAN(5700, 39),
+       CHAN(5745, 40),
+       CHAN(5765, 41),
+       CHAN(5785, 42),
+       CHAN(5805, 43),
+       CHAN(5825, 44),
+       CHAN(5170, 45),
+       CHAN(5190, 46),
+       CHAN(5210, 47),
+       CHAN(5230, 48),
+};
+#undef CHAN
+
+#define AR9170_HT_CAP                                                  \
+{                                                                      \
+       .ht_supported   = true,                                         \
+       .cap            = IEEE80211_HT_CAP_MAX_AMSDU |                  \
+                         IEEE80211_HT_CAP_SUP_WIDTH_20_40 |            \
+                         IEEE80211_HT_CAP_SGI_40 |                     \
+                         IEEE80211_HT_CAP_DSSSCCK40 |                  \
+                         IEEE80211_HT_CAP_SM_PS,                       \
+       .ampdu_factor   = 3,                                            \
+       .ampdu_density  = 6,                                            \
+       .mcs            = {                                             \
+               .rx_mask = { 0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0, },     \
+       },                                                              \
+}
+
+static struct ieee80211_supported_band ar9170_band_2GHz = {
+       .channels       = ar9170_2ghz_chantable,
+       .n_channels     = ARRAY_SIZE(ar9170_2ghz_chantable),
+       .bitrates       = ar9170_g_ratetable,
+       .n_bitrates     = ar9170_g_ratetable_size,
+       .ht_cap         = AR9170_HT_CAP,
+};
+
+static struct ieee80211_supported_band ar9170_band_5GHz = {
+       .channels       = ar9170_5ghz_chantable,
+       .n_channels     = ARRAY_SIZE(ar9170_5ghz_chantable),
+       .bitrates       = ar9170_a_ratetable,
+       .n_bitrates     = ar9170_a_ratetable_size,
+       .ht_cap         = AR9170_HT_CAP,
+};
+
+static void ar9170_tx(struct ar9170 *ar);
+
+#ifdef AR9170_QUEUE_DEBUG
+static void ar9170_print_txheader(struct ar9170 *ar, struct sk_buff *skb)
+{
+       struct ar9170_tx_control *txc = (void *) skb->data;
+       struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb);
+       struct ar9170_tx_info *arinfo = (void *) txinfo->rate_driver_data;
+       struct ieee80211_hdr *hdr = (void *) txc->frame_data;
+
+       printk(KERN_DEBUG "%s: => FRAME [skb:%p, q:%d, DA:[%pM] flags:%x "
+                         "mac_ctrl:%04x, phy_ctrl:%08x, timeout:[%d ms]]\n",
+              wiphy_name(ar->hw->wiphy), skb, skb_get_queue_mapping(skb),
+              ieee80211_get_DA(hdr), arinfo->flags,
+              le16_to_cpu(txc->mac_control), le32_to_cpu(txc->phy_control),
+              jiffies_to_msecs(arinfo->timeout - jiffies));
+}
+
+static void __ar9170_dump_txqueue(struct ar9170 *ar,
+                               struct sk_buff_head *queue)
+{
+       struct sk_buff *skb;
+       int i = 0;
+
+       printk(KERN_DEBUG "---[ cut here ]---\n");
+       printk(KERN_DEBUG "%s: %d entries in queue.\n",
+              wiphy_name(ar->hw->wiphy), skb_queue_len(queue));
+
+       skb_queue_walk(queue, skb) {
+               printk(KERN_DEBUG "index:%d => \n", i++);
+               ar9170_print_txheader(ar, skb);
+       }
+       if (i != skb_queue_len(queue))
+               printk(KERN_DEBUG "WARNING: queue frame counter "
+                      "mismatch %d != %d\n", skb_queue_len(queue), i);
+       printk(KERN_DEBUG "---[ end ]---\n");
+}
+
+static void ar9170_dump_txqueue(struct ar9170 *ar,
+                               struct sk_buff_head *queue)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&queue->lock, flags);
+       __ar9170_dump_txqueue(ar, queue);
+       spin_unlock_irqrestore(&queue->lock, flags);
+}
+
+static void __ar9170_dump_txstats(struct ar9170 *ar)
+{
+       int i;
+
+       printk(KERN_DEBUG "%s: QoS queue stats\n",
+              wiphy_name(ar->hw->wiphy));
+
+       for (i = 0; i < __AR9170_NUM_TXQ; i++)
+               printk(KERN_DEBUG "%s: queue:%d limit:%d len:%d waitack:%d\n",
+                      wiphy_name(ar->hw->wiphy), i, ar->tx_stats[i].limit,
+                      ar->tx_stats[i].len, skb_queue_len(&ar->tx_status[i]));
+}
+
+static void ar9170_dump_txstats(struct ar9170 *ar)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&ar->tx_stats_lock, flags);
+       __ar9170_dump_txstats(ar);
+       spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
+}
+#endif /* AR9170_QUEUE_DEBUG */
+
+/* caller must guarantee exclusive access for _bin_ queue. */
+static void ar9170_recycle_expired(struct ar9170 *ar,
+                                  struct sk_buff_head *queue,
+                                  struct sk_buff_head *bin)
+{
+       struct sk_buff *skb, *old = NULL;
+       unsigned long flags;
+
+       spin_lock_irqsave(&queue->lock, flags);
+       while ((skb = skb_peek(queue))) {
+               struct ieee80211_tx_info *txinfo;
+               struct ar9170_tx_info *arinfo;
+
+               txinfo = IEEE80211_SKB_CB(skb);
+               arinfo = (void *) txinfo->rate_driver_data;
+
+               if (time_is_before_jiffies(arinfo->timeout)) {
+#ifdef AR9170_QUEUE_DEBUG
+                       printk(KERN_DEBUG "%s: [%ld > %ld] frame expired => "
+                              "recycle \n", wiphy_name(ar->hw->wiphy),
+                              jiffies, arinfo->timeout);
+                       ar9170_print_txheader(ar, skb);
+#endif /* AR9170_QUEUE_DEBUG */
+                       __skb_unlink(skb, queue);
+                       __skb_queue_tail(bin, skb);
+               } else {
+                       break;
+               }
+
+               if (unlikely(old == skb)) {
+                       /* bail out - queue is shot. */
+
+                       WARN_ON(1);
+                       break;
+               }
+               old = skb;
+       }
+       spin_unlock_irqrestore(&queue->lock, flags);
+}
+
+static void ar9170_tx_status(struct ar9170 *ar, struct sk_buff *skb,
+                                   u16 tx_status)
+{
+       struct ieee80211_tx_info *txinfo;
+       unsigned int retries = 0;
+
+       txinfo = IEEE80211_SKB_CB(skb);
+       ieee80211_tx_info_clear_status(txinfo);
+
+       switch (tx_status) {
+       case AR9170_TX_STATUS_RETRY:
+               retries = 2;
+       case AR9170_TX_STATUS_COMPLETE:
+               txinfo->flags |= IEEE80211_TX_STAT_ACK;
+               break;
+
+       case AR9170_TX_STATUS_FAILED:
+               retries = ar->hw->conf.long_frame_max_tx_count;
+               break;
+
+       default:
+               printk(KERN_ERR "%s: invalid tx_status response (%x).\n",
+                      wiphy_name(ar->hw->wiphy), tx_status);
+               break;
+       }
+
+       txinfo->status.rates[0].count = retries + 1;
+       skb_pull(skb, sizeof(struct ar9170_tx_control));
+       ieee80211_tx_status_irqsafe(ar->hw, skb);
+}
+
+void ar9170_tx_callback(struct ar9170 *ar, struct sk_buff *skb)
+{
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+       struct ar9170_tx_info *arinfo = (void *) info->rate_driver_data;
+       unsigned int queue = skb_get_queue_mapping(skb);
+       unsigned long flags;
+
+       spin_lock_irqsave(&ar->tx_stats_lock, flags);
+       ar->tx_stats[queue].len--;
+
+       if (skb_queue_empty(&ar->tx_pending[queue])) {
+#ifdef AR9170_QUEUE_STOP_DEBUG
+               printk(KERN_DEBUG "%s: wake queue %d\n",
+                      wiphy_name(ar->hw->wiphy), queue);
+               __ar9170_dump_txstats(ar);
+#endif /* AR9170_QUEUE_STOP_DEBUG */
+               ieee80211_wake_queue(ar->hw, queue);
+       }
+       spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
+
+       if (arinfo->flags & AR9170_TX_FLAG_BLOCK_ACK) {
+               dev_kfree_skb_any(skb);
+       } else if (arinfo->flags & AR9170_TX_FLAG_WAIT_FOR_ACK) {
+               arinfo->timeout = jiffies +
+                                 msecs_to_jiffies(AR9170_TX_TIMEOUT);
+
+               skb_queue_tail(&ar->tx_status[queue], skb);
+       } else if (arinfo->flags & AR9170_TX_FLAG_NO_ACK) {
+               ar9170_tx_status(ar, skb, AR9170_TX_STATUS_FAILED);
+       } else {
+#ifdef AR9170_QUEUE_DEBUG
+               printk(KERN_DEBUG "%s: unsupported frame flags!\n",
+                      wiphy_name(ar->hw->wiphy));
+               ar9170_print_txheader(ar, skb);
+#endif /* AR9170_QUEUE_DEBUG */
+               dev_kfree_skb_any(skb);
+       }
+
+       if (!ar->tx_stats[queue].len &&
+           !skb_queue_empty(&ar->tx_pending[queue])) {
+               ar9170_tx(ar);
+       }
+}
+
+static struct sk_buff *ar9170_get_queued_skb(struct ar9170 *ar,
+                                            const u8 *mac,
+                                            struct sk_buff_head *queue,
+                                            const u32 rate)
+{
+       unsigned long flags;
+       struct sk_buff *skb;
+
+       /*
+        * Unfortunately, the firmware does not tell to which (queued) frame
+        * this transmission status report belongs to.
+        *
+        * So we have to make risky guesses - with the scarce information
+        * the firmware provided (-> destination MAC, and phy_control) -
+        * and hope that we picked the right one...
+        */
+
+       spin_lock_irqsave(&queue->lock, flags);
+       skb_queue_walk(queue, skb) {
+               struct ar9170_tx_control *txc = (void *) skb->data;
+               struct ieee80211_hdr *hdr = (void *) txc->frame_data;
+               u32 r;
+
+               if (mac && compare_ether_addr(ieee80211_get_DA(hdr), mac)) {
+#ifdef AR9170_QUEUE_DEBUG
+                       printk(KERN_DEBUG "%s: skip frame => DA %pM != %pM\n",
+                              wiphy_name(ar->hw->wiphy), mac,
+                              ieee80211_get_DA(hdr));
+                       ar9170_print_txheader(ar, skb);
+#endif /* AR9170_QUEUE_DEBUG */
+                       continue;
+               }
+
+               r = (le32_to_cpu(txc->phy_control) & AR9170_TX_PHY_MCS_MASK) >>
+                   AR9170_TX_PHY_MCS_SHIFT;
+
+               if ((rate != AR9170_TX_INVALID_RATE) && (r != rate)) {
+#ifdef AR9170_QUEUE_DEBUG
+                       printk(KERN_DEBUG "%s: skip frame => rate %d != %d\n",
+                              wiphy_name(ar->hw->wiphy), rate, r);
+                       ar9170_print_txheader(ar, skb);
+#endif /* AR9170_QUEUE_DEBUG */
+                       continue;
+               }
+
+               __skb_unlink(skb, queue);
+               spin_unlock_irqrestore(&queue->lock, flags);
+               return skb;
+       }
+
+#ifdef AR9170_QUEUE_DEBUG
+       printk(KERN_ERR "%s: ESS:[%pM] does not have any "
+                       "outstanding frames in queue.\n",
+                       wiphy_name(ar->hw->wiphy), mac);
+       __ar9170_dump_txqueue(ar, queue);
+#endif /* AR9170_QUEUE_DEBUG */
+       spin_unlock_irqrestore(&queue->lock, flags);
+
+       return NULL;
+}
+
+/*
+ * This worker tries to keeps an maintain tx_status queues.
+ * So we can guarantee that incoming tx_status reports are
+ * actually for a pending frame.
+ */
+
+static void ar9170_tx_janitor(struct work_struct *work)
+{
+       struct ar9170 *ar = container_of(work, struct ar9170,
+                                        tx_janitor.work);
+       struct sk_buff_head waste;
+       unsigned int i;
+       bool resched = false;
+
+       if (unlikely(!IS_STARTED(ar)))
+               return ;
+
+       skb_queue_head_init(&waste);
+
+       for (i = 0; i < __AR9170_NUM_TXQ; i++) {
+#ifdef AR9170_QUEUE_DEBUG
+               printk(KERN_DEBUG "%s: garbage collector scans queue:%d\n",
+                      wiphy_name(ar->hw->wiphy), i);
+               ar9170_dump_txqueue(ar, &ar->tx_pending[i]);
+               ar9170_dump_txqueue(ar, &ar->tx_status[i]);
+#endif /* AR9170_QUEUE_DEBUG */
+
+               ar9170_recycle_expired(ar, &ar->tx_status[i], &waste);
+               ar9170_recycle_expired(ar, &ar->tx_pending[i], &waste);
+               skb_queue_purge(&waste);
+
+               if (!skb_queue_empty(&ar->tx_status[i]) ||
+                   !skb_queue_empty(&ar->tx_pending[i]))
+                       resched = true;
+       }
+
+       if (resched)
+               queue_delayed_work(ar->hw->workqueue,
+                                  &ar->tx_janitor,
+                                  msecs_to_jiffies(AR9170_JANITOR_DELAY));
+}
+
+void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len)
+{
+       struct ar9170_cmd_response *cmd = (void *) buf;
+
+       if ((cmd->type & 0xc0) != 0xc0) {
+               ar->callback_cmd(ar, len, buf);
+               return;
+       }
+
+       /* hardware event handlers */
+       switch (cmd->type) {
+       case 0xc1: {
+               /*
+                * TX status notification:
+                * bytes: 0c c1 XX YY M1 M2 M3 M4 M5 M6 R4 R3 R2 R1 S2 S1
+                *
+                * XX always 81
+                * YY always 00
+                * M1-M6 is the MAC address
+                * R1-R4 is the transmit rate
+                * S1-S2 is the transmit status
+                */
+
+               struct sk_buff *skb;
+               u32 phy = le32_to_cpu(cmd->tx_status.rate);
+               u32 q = (phy & AR9170_TX_PHY_QOS_MASK) >>
+                       AR9170_TX_PHY_QOS_SHIFT;
+#ifdef AR9170_QUEUE_DEBUG
+               printk(KERN_DEBUG "%s: recv tx_status for %pM, p:%08x, q:%d\n",
+                      wiphy_name(ar->hw->wiphy), cmd->tx_status.dst, phy, q);
+#endif /* AR9170_QUEUE_DEBUG */
+
+               skb = ar9170_get_queued_skb(ar, cmd->tx_status.dst,
+                                           &ar->tx_status[q],
+                                           AR9170_TX_INVALID_RATE);
+               if (unlikely(!skb))
+                       return ;
+
+               ar9170_tx_status(ar, skb, le16_to_cpu(cmd->tx_status.status));
+               break;
+               }
+
+       case 0xc0:
+               /*
+                * pre-TBTT event
+                */
+               if (ar->vif && ar->vif->type == NL80211_IFTYPE_AP)
+                       queue_work(ar->hw->workqueue, &ar->beacon_work);
+               break;
+
+       case 0xc2:
+               /*
+                * (IBSS) beacon send notification
+                * bytes: 04 c2 XX YY B4 B3 B2 B1
+                *
+                * XX always 80
+                * YY always 00
+                * B1-B4 "should" be the number of send out beacons.
+                */
+               break;
+
+       case 0xc3:
+               /* End of Atim Window */
+               break;
+
+       case 0xc4:
+       case 0xc5:
+               /* BlockACK events */
+               break;
+
+       case 0xc6:
+               /* Watchdog Interrupt */
+               break;
+
+       case 0xc9:
+               /* retransmission issue / SIFS/EIFS collision ?! */
+               break;
+
+       /* firmware debug */
+       case 0xca:
+               printk(KERN_DEBUG "ar9170 FW: %.*s\n", len - 4, (char *)buf + 4);
+               break;
+       case 0xcb:
+               len -= 4;
+
+               switch (len) {
+               case 1:
+                       printk(KERN_DEBUG "ar9170 FW: u8: %#.2x\n",
+                               *((char *)buf + 4));
+                       break;
+               case 2:
+                       printk(KERN_DEBUG "ar9170 FW: u8: %#.4x\n",
+                               le16_to_cpup((__le16 *)((char *)buf + 4)));
+                       break;
+               case 4:
+                       printk(KERN_DEBUG "ar9170 FW: u8: %#.8x\n",
+                               le32_to_cpup((__le32 *)((char *)buf + 4)));
+                       break;
+               case 8:
+                       printk(KERN_DEBUG "ar9170 FW: u8: %#.16lx\n",
+                               (unsigned long)le64_to_cpup(
+                                               (__le64 *)((char *)buf + 4)));
+                       break;
+               }
+               break;
+       case 0xcc:
+               print_hex_dump_bytes("ar9170 FW:", DUMP_PREFIX_NONE,
+                                    (char *)buf + 4, len - 4);
+               break;
+
+       default:
+               printk(KERN_INFO "received unhandled event %x\n", cmd->type);
+               print_hex_dump_bytes("dump:", DUMP_PREFIX_NONE, buf, len);
+               break;
+       }
+}
+
+static void ar9170_rx_reset_rx_mpdu(struct ar9170 *ar)
+{
+       memset(&ar->rx_mpdu.plcp, 0, sizeof(struct ar9170_rx_head));
+       ar->rx_mpdu.has_plcp = false;
+}
+
+int ar9170_nag_limiter(struct ar9170 *ar)
+{
+       bool print_message;
+
+       /*
+        * we expect all sorts of errors in promiscuous mode.
+        * don't bother with it, it's OK!
+        */
+       if (ar->sniffer_enabled)
+               return false;
+
+       /*
+        * only go for frequent errors! The hardware tends to
+        * do some stupid thing once in a while under load, in
+        * noisy environments or just for fun!
+        */
+       if (time_before(jiffies, ar->bad_hw_nagger) && net_ratelimit())
+               print_message = true;
+       else
+               print_message = false;
+
+       /* reset threshold for "once in a while" */
+       ar->bad_hw_nagger = jiffies + HZ / 4;
+       return print_message;
+}
+
+static int ar9170_rx_mac_status(struct ar9170 *ar,
+                               struct ar9170_rx_head *head,
+                               struct ar9170_rx_macstatus *mac,
+                               struct ieee80211_rx_status *status)
+{
+       u8 error, decrypt;
+
+       BUILD_BUG_ON(sizeof(struct ar9170_rx_head) != 12);
+       BUILD_BUG_ON(sizeof(struct ar9170_rx_macstatus) != 4);
+
+       error = mac->error;
+       if (error & AR9170_RX_ERROR_MMIC) {
+               status->flag |= RX_FLAG_MMIC_ERROR;
+               error &= ~AR9170_RX_ERROR_MMIC;
+       }
+
+       if (error & AR9170_RX_ERROR_PLCP) {
+               status->flag |= RX_FLAG_FAILED_PLCP_CRC;
+               error &= ~AR9170_RX_ERROR_PLCP;
+
+               if (!(ar->filter_state & FIF_PLCPFAIL))
+                       return -EINVAL;
+       }
+
+       if (error & AR9170_RX_ERROR_FCS) {
+               status->flag |= RX_FLAG_FAILED_FCS_CRC;
+               error &= ~AR9170_RX_ERROR_FCS;
+
+               if (!(ar->filter_state & FIF_FCSFAIL))
+                       return -EINVAL;
+       }
+
+       decrypt = ar9170_get_decrypt_type(mac);
+       if (!(decrypt & AR9170_RX_ENC_SOFTWARE) &&
+           decrypt != AR9170_ENC_ALG_NONE)
+               status->flag |= RX_FLAG_DECRYPTED;
+
+       /* ignore wrong RA errors */
+       error &= ~AR9170_RX_ERROR_WRONG_RA;
+
+       if (error & AR9170_RX_ERROR_DECRYPT) {
+               error &= ~AR9170_RX_ERROR_DECRYPT;
+               /*
+                * Rx decryption is done in place,
+                * the original data is lost anyway.
+                */
+
+               return -EINVAL;
+       }
+
+       /* drop any other error frames */
+       if (unlikely(error)) {
+               /* TODO: update netdevice's RX dropped/errors statistics */
+
+               if (ar9170_nag_limiter(ar))
+                       printk(KERN_DEBUG "%s: received frame with "
+                              "suspicious error code (%#x).\n",
+                              wiphy_name(ar->hw->wiphy), error);
+
+               return -EINVAL;
+       }
+
+       status->band = ar->channel->band;
+       status->freq = ar->channel->center_freq;
+
+       switch (mac->status & AR9170_RX_STATUS_MODULATION_MASK) {
+       case AR9170_RX_STATUS_MODULATION_CCK:
+               if (mac->status & AR9170_RX_STATUS_SHORT_PREAMBLE)
+                       status->flag |= RX_FLAG_SHORTPRE;
+               switch (head->plcp[0]) {
+               case 0x0a:
+                       status->rate_idx = 0;
+                       break;
+               case 0x14:
+                       status->rate_idx = 1;
+                       break;
+               case 0x37:
+                       status->rate_idx = 2;
+                       break;
+               case 0x6e:
+                       status->rate_idx = 3;
+                       break;
+               default:
+                       if (ar9170_nag_limiter(ar))
+                               printk(KERN_ERR "%s: invalid plcp cck rate "
+                                      "(%x).\n", wiphy_name(ar->hw->wiphy),
+                                      head->plcp[0]);
+                       return -EINVAL;
+               }
+               break;
+
+       case AR9170_RX_STATUS_MODULATION_OFDM:
+               switch (head->plcp[0] & 0xf) {
+               case 0xb:
+                       status->rate_idx = 0;
+                       break;
+               case 0xf:
+                       status->rate_idx = 1;
+                       break;
+               case 0xa:
+                       status->rate_idx = 2;
+                       break;
+               case 0xe:
+                       status->rate_idx = 3;
+                       break;
+               case 0x9:
+                       status->rate_idx = 4;
+                       break;
+               case 0xd:
+                       status->rate_idx = 5;
+                       break;
+               case 0x8:
+                       status->rate_idx = 6;
+                       break;
+               case 0xc:
+                       status->rate_idx = 7;
+                       break;
+               default:
+                       if (ar9170_nag_limiter(ar))
+                               printk(KERN_ERR "%s: invalid plcp ofdm rate "
+                                      "(%x).\n", wiphy_name(ar->hw->wiphy),
+                                      head->plcp[0]);
+                       return -EINVAL;
+               }
+               if (status->band == IEEE80211_BAND_2GHZ)
+                       status->rate_idx += 4;
+               break;
+
+       case AR9170_RX_STATUS_MODULATION_HT:
+               if (head->plcp[3] & 0x80)
+                       status->flag |= RX_FLAG_40MHZ;
+               if (head->plcp[6] & 0x80)
+                       status->flag |= RX_FLAG_SHORT_GI;
+
+               status->rate_idx = clamp(0, 75, head->plcp[6] & 0x7f);
+               status->flag |= RX_FLAG_HT;
+               break;
+
+       case AR9170_RX_STATUS_MODULATION_DUPOFDM:
+               /* XXX */
+               if (ar9170_nag_limiter(ar))
+                       printk(KERN_ERR "%s: invalid modulation\n",
+                              wiphy_name(ar->hw->wiphy));
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static void ar9170_rx_phy_status(struct ar9170 *ar,
+                                struct ar9170_rx_phystatus *phy,
+                                struct ieee80211_rx_status *status)
+{
+       int i;
+
+       BUILD_BUG_ON(sizeof(struct ar9170_rx_phystatus) != 20);
+
+       for (i = 0; i < 3; i++)
+               if (phy->rssi[i] != 0x80)
+                       status->antenna |= BIT(i);
+
+       /* post-process RSSI */
+       for (i = 0; i < 7; i++)
+               if (phy->rssi[i] & 0x80)
+                       phy->rssi[i] = ((phy->rssi[i] & 0x7f) + 1) & 0x7f;
+
+       /* TODO: we could do something with phy_errors */
+       status->signal = ar->noise[0] + phy->rssi_combined;
+       status->noise = ar->noise[0];
+}
+
+static struct sk_buff *ar9170_rx_copy_data(u8 *buf, int len)
+{
+       struct sk_buff *skb;
+       int reserved = 0;
+       struct ieee80211_hdr *hdr = (void *) buf;
+
+       if (ieee80211_is_data_qos(hdr->frame_control)) {
+               u8 *qc = ieee80211_get_qos_ctl(hdr);
+               reserved += NET_IP_ALIGN;
+
+               if (*qc & IEEE80211_QOS_CONTROL_A_MSDU_PRESENT)
+                       reserved += NET_IP_ALIGN;
+       }
+
+       if (ieee80211_has_a4(hdr->frame_control))
+               reserved += NET_IP_ALIGN;
+
+       reserved = 32 + (reserved & NET_IP_ALIGN);
+
+       skb = dev_alloc_skb(len + reserved);
+       if (likely(skb)) {
+               skb_reserve(skb, reserved);
+               memcpy(skb_put(skb, len), buf, len);
+       }
+
+       return skb;
+}
+
+/*
+ * If the frame alignment is right (or the kernel has
+ * CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS), and there
+ * is only a single MPDU in the USB frame, then we could
+ * submit to mac80211 the SKB directly. However, since
+ * there may be multiple packets in one SKB in stream
+ * mode, and we need to observe the proper ordering,
+ * this is non-trivial.
+ */
+
+static void ar9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len)
+{
+       struct ar9170_rx_head *head;
+       struct ar9170_rx_macstatus *mac;
+       struct ar9170_rx_phystatus *phy = NULL;
+       struct ieee80211_rx_status status;
+       struct sk_buff *skb;
+       int mpdu_len;
+
+       if (unlikely(!IS_STARTED(ar) || len < (sizeof(*mac))))
+               return ;
+
+       /* Received MPDU */
+       mpdu_len = len - sizeof(*mac);
+
+       mac = (void *)(buf + mpdu_len);
+       if (unlikely(mac->error & AR9170_RX_ERROR_FATAL)) {
+               /* this frame is too damaged and can't be used - drop it */
+
+               return ;
+       }
+
+       switch (mac->status & AR9170_RX_STATUS_MPDU_MASK) {
+       case AR9170_RX_STATUS_MPDU_FIRST:
+               /* first mpdu packet has the plcp header */
+               if (likely(mpdu_len >= sizeof(struct ar9170_rx_head))) {
+                       head = (void *) buf;
+                       memcpy(&ar->rx_mpdu.plcp, (void *) buf,
+                              sizeof(struct ar9170_rx_head));
+
+                       mpdu_len -= sizeof(struct ar9170_rx_head);
+                       buf += sizeof(struct ar9170_rx_head);
+                       ar->rx_mpdu.has_plcp = true;
+               } else {
+                       if (ar9170_nag_limiter(ar))
+                               printk(KERN_ERR "%s: plcp info is clipped.\n",
+                                      wiphy_name(ar->hw->wiphy));
+                       return ;
+               }
+               break;
+
+       case AR9170_RX_STATUS_MPDU_LAST:
+               /* last mpdu has a extra tail with phy status information */
+
+               if (likely(mpdu_len >= sizeof(struct ar9170_rx_phystatus))) {
+                       mpdu_len -= sizeof(struct ar9170_rx_phystatus);
+                       phy = (void *)(buf + mpdu_len);
+               } else {
+                       if (ar9170_nag_limiter(ar))
+                               printk(KERN_ERR "%s: frame tail is clipped.\n",
+                                      wiphy_name(ar->hw->wiphy));
+                       return ;
+               }
+
+       case AR9170_RX_STATUS_MPDU_MIDDLE:
+               /* middle mpdus are just data */
+               if (unlikely(!ar->rx_mpdu.has_plcp)) {
+                       if (!ar9170_nag_limiter(ar))
+                               return ;
+
+                       printk(KERN_ERR "%s: rx stream did not start "
+                                       "with a first_mpdu frame tag.\n",
+                              wiphy_name(ar->hw->wiphy));
+
+                       return ;
+               }
+
+               head = &ar->rx_mpdu.plcp;
+               break;
+
+       case AR9170_RX_STATUS_MPDU_SINGLE:
+               /* single mpdu - has plcp (head) and phy status (tail) */
+               head = (void *) buf;
+
+               mpdu_len -= sizeof(struct ar9170_rx_head);
+               mpdu_len -= sizeof(struct ar9170_rx_phystatus);
+
+               buf += sizeof(struct ar9170_rx_head);
+               phy = (void *)(buf + mpdu_len);
+               break;
+
+       default:
+               BUG_ON(1);
+               break;
+       }
+
+       if (unlikely(mpdu_len < FCS_LEN))
+               return ;
+
+       memset(&status, 0, sizeof(status));
+       if (unlikely(ar9170_rx_mac_status(ar, head, mac, &status)))
+               return ;
+
+       if (phy)
+               ar9170_rx_phy_status(ar, phy, &status);
+
+       skb = ar9170_rx_copy_data(buf, mpdu_len);
+       if (likely(skb))
+               ieee80211_rx_irqsafe(ar->hw, skb, &status);
+}
+
+void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb)
+{
+       unsigned int i, tlen, resplen, wlen = 0, clen = 0;
+       u8 *tbuf, *respbuf;
+
+       tbuf = skb->data;
+       tlen = skb->len;
+
+       while (tlen >= 4) {
+               clen = tbuf[1] << 8 | tbuf[0];
+               wlen = ALIGN(clen, 4);
+
+               /* check if this is stream has a valid tag.*/
+               if (tbuf[2] != 0 || tbuf[3] != 0x4e) {
+                       /*
+                        * TODO: handle the highly unlikely event that the
+                        * corrupted stream has the TAG at the right position.
+                        */
+
+                       /* check if the frame can be repaired. */
+                       if (!ar->rx_failover_missing) {
+                               /* this is no "short read". */
+                               if (ar9170_nag_limiter(ar)) {
+                                       printk(KERN_ERR "%s: missing tag!\n",
+                                              wiphy_name(ar->hw->wiphy));
+                                       goto err_telluser;
+                               } else
+                                       goto err_silent;
+                       }
+
+                       if (ar->rx_failover_missing > tlen) {
+                               if (ar9170_nag_limiter(ar)) {
+                                       printk(KERN_ERR "%s: possible multi "
+                                              "stream corruption!\n",
+                                              wiphy_name(ar->hw->wiphy));
+                                       goto err_telluser;
+                               } else
+                                       goto err_silent;
+                       }
+
+                       memcpy(skb_put(ar->rx_failover, tlen), tbuf, tlen);
+                       ar->rx_failover_missing -= tlen;
+
+                       if (ar->rx_failover_missing <= 0) {
+                               /*
+                                * nested ar9170_rx call!
+                                * termination is guranteed, even when the
+                                * combined frame also have a element with
+                                * a bad tag.
+                                */
+
+                               ar->rx_failover_missing = 0;
+                               ar9170_rx(ar, ar->rx_failover);
+
+                               skb_reset_tail_pointer(ar->rx_failover);
+                               skb_trim(ar->rx_failover, 0);
+                       }
+
+                       return ;
+               }
+
+               /* check if stream is clipped */
+               if (wlen > tlen - 4) {
+                       if (ar->rx_failover_missing) {
+                               /* TODO: handle double stream corruption. */
+                               if (ar9170_nag_limiter(ar)) {
+                                       printk(KERN_ERR "%s: double rx stream "
+                                              "corruption!\n",
+                                               wiphy_name(ar->hw->wiphy));
+                                       goto err_telluser;
+                               } else
+                                       goto err_silent;
+                       }
+
+                       /*
+                        * save incomplete data set.
+                        * the firmware will resend the missing bits when
+                        * the rx - descriptor comes round again.
+                        */
+
+                       memcpy(skb_put(ar->rx_failover, tlen), tbuf, tlen);
+                       ar->rx_failover_missing = clen - tlen;
+                       return ;
+               }
+               resplen = clen;
+               respbuf = tbuf + 4;
+               tbuf += wlen + 4;
+               tlen -= wlen + 4;
+
+               i = 0;
+
+               /* weird thing, but this is the same in the original driver */
+               while (resplen > 2 && i < 12 &&
+                      respbuf[0] == 0xff && respbuf[1] == 0xff) {
+                       i += 2;
+                       resplen -= 2;
+                       respbuf += 2;
+               }
+
+               if (resplen < 4)
+                       continue;
+
+               /* found the 6 * 0xffff marker? */
+               if (i == 12)
+                       ar9170_handle_command_response(ar, respbuf, resplen);
+               else
+                       ar9170_handle_mpdu(ar, respbuf, clen);
+       }
+
+       if (tlen) {
+               if (net_ratelimit())
+                       printk(KERN_ERR "%s: %d bytes of unprocessed "
+                                       "data left in rx stream!\n",
+                              wiphy_name(ar->hw->wiphy), tlen);
+
+               goto err_telluser;
+       }
+
+       return ;
+
+err_telluser:
+       printk(KERN_ERR "%s: damaged RX stream data [want:%d, "
+                       "data:%d, rx:%d, pending:%d ]\n",
+              wiphy_name(ar->hw->wiphy), clen, wlen, tlen,
+              ar->rx_failover_missing);
+
+       if (ar->rx_failover_missing)
+               print_hex_dump_bytes("rxbuf:", DUMP_PREFIX_OFFSET,
+                                    ar->rx_failover->data,
+                                    ar->rx_failover->len);
+
+       print_hex_dump_bytes("stream:", DUMP_PREFIX_OFFSET,
+                            skb->data, skb->len);
+
+       printk(KERN_ERR "%s: please check your hardware and cables, if "
+                       "you see this message frequently.\n",
+              wiphy_name(ar->hw->wiphy));
+
+err_silent:
+       if (ar->rx_failover_missing) {
+               skb_reset_tail_pointer(ar->rx_failover);
+               skb_trim(ar->rx_failover, 0);
+               ar->rx_failover_missing = 0;
+       }
+}
+
+#define AR9170_FILL_QUEUE(queue, ai_fs, cwmin, cwmax, _txop)           \
+do {                                                                   \
+       queue.aifs = ai_fs;                                             \
+       queue.cw_min = cwmin;                                           \
+       queue.cw_max = cwmax;                                           \
+       queue.txop = _txop;                                             \
+} while (0)
+
+static int ar9170_op_start(struct ieee80211_hw *hw)
+{
+       struct ar9170 *ar = hw->priv;
+       int err, i;
+
+       mutex_lock(&ar->mutex);
+
+       ar->filter_changed = 0;
+
+       /* reinitialize queues statistics */
+       memset(&ar->tx_stats, 0, sizeof(ar->tx_stats));
+       for (i = 0; i < __AR9170_NUM_TXQ; i++)
+               ar->tx_stats[i].limit = AR9170_TXQ_DEPTH;
+
+       /* reset QoS defaults */
+       AR9170_FILL_QUEUE(ar->edcf[0], 3, 15, 1023,  0); /* BEST EFFORT*/
+       AR9170_FILL_QUEUE(ar->edcf[1], 7, 15, 1023,  0); /* BACKGROUND */
+       AR9170_FILL_QUEUE(ar->edcf[2], 2, 7,    15, 94); /* VIDEO */
+       AR9170_FILL_QUEUE(ar->edcf[3], 2, 3,     7, 47); /* VOICE */
+       AR9170_FILL_QUEUE(ar->edcf[4], 2, 3,     7,  0); /* SPECIAL */
+
+       ar->bad_hw_nagger = jiffies;
+
+       err = ar->open(ar);
+       if (err)
+               goto out;
+
+       err = ar9170_init_mac(ar);
+       if (err)
+               goto out;
+
+       err = ar9170_set_qos(ar);
+       if (err)
+               goto out;
+
+       err = ar9170_init_phy(ar, IEEE80211_BAND_2GHZ);
+       if (err)
+               goto out;
+
+       err = ar9170_init_rf(ar);
+       if (err)
+               goto out;
+
+       /* start DMA */
+       err = ar9170_write_reg(ar, 0x1c3d30, 0x100);
+       if (err)
+               goto out;
+
+       ar->state = AR9170_STARTED;
+
+out:
+       mutex_unlock(&ar->mutex);
+       return err;
+}
+
+static void ar9170_op_stop(struct ieee80211_hw *hw)
+{
+       struct ar9170 *ar = hw->priv;
+       unsigned int i;
+
+       if (IS_STARTED(ar))
+               ar->state = AR9170_IDLE;
+
+       flush_workqueue(ar->hw->workqueue);
+
+       cancel_delayed_work_sync(&ar->tx_janitor);
+       cancel_work_sync(&ar->filter_config_work);
+       cancel_work_sync(&ar->beacon_work);
+       mutex_lock(&ar->mutex);
+
+       if (IS_ACCEPTING_CMD(ar)) {
+               ar9170_set_leds_state(ar, 0);
+
+               /* stop DMA */
+               ar9170_write_reg(ar, 0x1c3d30, 0);
+               ar->stop(ar);
+       }
+
+       for (i = 0; i < __AR9170_NUM_TXQ; i++) {
+               skb_queue_purge(&ar->tx_pending[i]);
+               skb_queue_purge(&ar->tx_status[i]);
+       }
+       mutex_unlock(&ar->mutex);
+}
+
+static int ar9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb)
+{
+       struct ieee80211_hdr *hdr;
+       struct ar9170_tx_control *txc;
+       struct ieee80211_tx_info *info;
+       struct ieee80211_tx_rate *txrate;
+       struct ar9170_tx_info *arinfo;
+       unsigned int queue = skb_get_queue_mapping(skb);
+       u16 keytype = 0;
+       u16 len, icv = 0;
+
+       BUILD_BUG_ON(sizeof(*arinfo) > sizeof(info->rate_driver_data));
+
+       hdr = (void *)skb->data;
+       info = IEEE80211_SKB_CB(skb);
+       len = skb->len;
+
+       txc = (void *)skb_push(skb, sizeof(*txc));
+
+       if (info->control.hw_key) {
+               icv = info->control.hw_key->icv_len;
+
+               switch (info->control.hw_key->alg) {
+               case ALG_WEP:
+                       keytype = AR9170_TX_MAC_ENCR_RC4;
+                       break;
+               case ALG_TKIP:
+                       keytype = AR9170_TX_MAC_ENCR_RC4;
+                       break;
+               case ALG_CCMP:
+                       keytype = AR9170_TX_MAC_ENCR_AES;
+                       break;
+               default:
+                       WARN_ON(1);
+                       goto err_out;
+               }
+       }
+
+       /* Length */
+       txc->length = cpu_to_le16(len + icv + 4);
+
+       txc->mac_control = cpu_to_le16(AR9170_TX_MAC_HW_DURATION |
+                                      AR9170_TX_MAC_BACKOFF);
+       txc->mac_control |= cpu_to_le16(ar9170_qos_hwmap[queue] <<
+                                       AR9170_TX_MAC_QOS_SHIFT);
+       txc->mac_control |= cpu_to_le16(keytype);
+       txc->phy_control = cpu_to_le32(0);
+
+       if (info->flags & IEEE80211_TX_CTL_NO_ACK)
+               txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_NO_ACK);
+
+       txrate = &info->control.rates[0];
+       if (txrate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
+               txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_PROT_CTS);
+       else if (txrate->flags & IEEE80211_TX_RC_USE_RTS_CTS)
+               txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_PROT_RTS);
+
+       arinfo = (void *)info->rate_driver_data;
+       arinfo->timeout = jiffies + msecs_to_jiffies(AR9170_QUEUE_TIMEOUT);
+
+       if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) &&
+            (is_valid_ether_addr(ieee80211_get_DA(hdr)))) {
+               if (info->flags & IEEE80211_TX_CTL_AMPDU) {
+                       if (unlikely(!info->control.sta))
+                               goto err_out;
+
+                       txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_AGGR);
+                       arinfo->flags = AR9170_TX_FLAG_BLOCK_ACK;
+                       goto out;
+               }
+
+               txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_RATE_PROBE);
+               /*
+                * WARNING:
+                * Putting the QoS queue bits into an unexplored territory is
+                * certainly not elegant.
+                *
+                * In my defense: This idea provides a reasonable way to
+                * smuggle valuable information to the tx_status callback.
+                * Also, the idea behind this bit-abuse came straight from
+                * the original driver code.
+                */
+
+               txc->phy_control |=
+                       cpu_to_le32(queue << AR9170_TX_PHY_QOS_SHIFT);
+               arinfo->flags = AR9170_TX_FLAG_WAIT_FOR_ACK;
+       } else {
+               arinfo->flags = AR9170_TX_FLAG_NO_ACK;
+       }
+
+out:
+       return 0;
+
+err_out:
+       skb_pull(skb, sizeof(*txc));
+       return -EINVAL;
+}
+
+static void ar9170_tx_prepare_phy(struct ar9170 *ar, struct sk_buff *skb)
+{
+       struct ar9170_tx_control *txc;
+       struct ieee80211_tx_info *info;
+       struct ieee80211_rate *rate = NULL;
+       struct ieee80211_tx_rate *txrate;
+       u32 power, chains;
+
+       txc = (void *) skb->data;
+       info = IEEE80211_SKB_CB(skb);
+       txrate = &info->control.rates[0];
+
+       if (txrate->flags & IEEE80211_TX_RC_GREEN_FIELD)
+               txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_GREENFIELD);
+
+       if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
+               txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_SHORT_PREAMBLE);
+
+       if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
+               txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_BW_40MHZ);
+       /* this works because 40 MHz is 2 and dup is 3 */
+       if (txrate->flags & IEEE80211_TX_RC_DUP_DATA)
+               txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_BW_40MHZ_DUP);
+
+       if (txrate->flags & IEEE80211_TX_RC_SHORT_GI)
+               txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_SHORT_GI);
+
+       if (txrate->flags & IEEE80211_TX_RC_MCS) {
+               u32 r = txrate->idx;
+               u8 *txpower;
+
+               /* heavy clip control */
+               txc->phy_control |= cpu_to_le32((r & 0x7) << 7);
+
+               r <<= AR9170_TX_PHY_MCS_SHIFT;
+               BUG_ON(r & ~AR9170_TX_PHY_MCS_MASK);
+
+               txc->phy_control |= cpu_to_le32(r & AR9170_TX_PHY_MCS_MASK);
+               txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_MOD_HT);
+
+               if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) {
+                       if (info->band == IEEE80211_BAND_5GHZ)
+                               txpower = ar->power_5G_ht40;
+                       else
+                               txpower = ar->power_2G_ht40;
+               } else {
+                       if (info->band == IEEE80211_BAND_5GHZ)
+                               txpower = ar->power_5G_ht20;
+                       else
+                               txpower = ar->power_2G_ht20;
+               }
+
+               power = txpower[(txrate->idx) & 7];
+       } else {
+               u8 *txpower;
+               u32 mod;
+               u32 phyrate;
+               u8 idx = txrate->idx;
+
+               if (info->band != IEEE80211_BAND_2GHZ) {
+                       idx += 4;
+                       txpower = ar->power_5G_leg;
+                       mod = AR9170_TX_PHY_MOD_OFDM;
+               } else {
+                       if (idx < 4) {
+                               txpower = ar->power_2G_cck;
+                               mod = AR9170_TX_PHY_MOD_CCK;
+                       } else {
+                               mod = AR9170_TX_PHY_MOD_OFDM;
+                               txpower = ar->power_2G_ofdm;
+                       }
+               }
+
+               rate = &__ar9170_ratetable[idx];
+
+               phyrate = rate->hw_value & 0xF;
+               power = txpower[(rate->hw_value & 0x30) >> 4];
+               phyrate <<= AR9170_TX_PHY_MCS_SHIFT;
+
+               txc->phy_control |= cpu_to_le32(mod);
+               txc->phy_control |= cpu_to_le32(phyrate);
+       }
+
+       power <<= AR9170_TX_PHY_TX_PWR_SHIFT;
+       power &= AR9170_TX_PHY_TX_PWR_MASK;
+       txc->phy_control |= cpu_to_le32(power);
+
+       /* set TX chains */
+       if (ar->eeprom.tx_mask == 1) {
+               chains = AR9170_TX_PHY_TXCHAIN_1;
+       } else {
+               chains = AR9170_TX_PHY_TXCHAIN_2;
+
+               /* >= 36M legacy OFDM - use only one chain */
+               if (rate && rate->bitrate >= 360)
+                       chains = AR9170_TX_PHY_TXCHAIN_1;
+       }
+       txc->phy_control |= cpu_to_le32(chains << AR9170_TX_PHY_TXCHAIN_SHIFT);
+}
+
+static void ar9170_tx(struct ar9170 *ar)
+{
+       struct sk_buff *skb;
+       unsigned long flags;
+       struct ieee80211_tx_info *info;
+       struct ar9170_tx_info *arinfo;
+       unsigned int i, frames, frames_failed, remaining_space;
+       int err;
+       bool schedule_garbagecollector = false;
+
+       BUILD_BUG_ON(sizeof(*arinfo) > sizeof(info->rate_driver_data));
+
+       if (unlikely(!IS_STARTED(ar)))
+               return ;
+
+       remaining_space = AR9170_TX_MAX_PENDING;
+
+       for (i = 0; i < __AR9170_NUM_TXQ; i++) {
+               spin_lock_irqsave(&ar->tx_stats_lock, flags);
+               if (ar->tx_stats[i].len >= ar->tx_stats[i].limit) {
+#ifdef AR9170_QUEUE_DEBUG
+                       printk(KERN_DEBUG "%s: queue %d full\n",
+                              wiphy_name(ar->hw->wiphy), i);
+
+                       __ar9170_dump_txstats(ar);
+                       printk(KERN_DEBUG "stuck frames: ===> \n");
+                       ar9170_dump_txqueue(ar, &ar->tx_pending[i]);
+                       ar9170_dump_txqueue(ar, &ar->tx_status[i]);
+#endif /* AR9170_QUEUE_DEBUG */
+                       ieee80211_stop_queue(ar->hw, i);
+                       spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
+                       continue;
+               }
+
+               frames = min(ar->tx_stats[i].limit - ar->tx_stats[i].len,
+                            skb_queue_len(&ar->tx_pending[i]));
+
+               if (remaining_space < frames) {
+#ifdef AR9170_QUEUE_DEBUG
+                       printk(KERN_DEBUG "%s: tx quota reached queue:%d, "
+                              "remaining slots:%d, needed:%d\n",
+                              wiphy_name(ar->hw->wiphy), i, remaining_space,
+                              frames);
+
+                       ar9170_dump_txstats(ar);
+#endif /* AR9170_QUEUE_DEBUG */
+                       frames = remaining_space;
+               }
+
+               ar->tx_stats[i].len += frames;
+               ar->tx_stats[i].count += frames;
+               spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
+
+               if (!frames)
+                       continue;
+
+               frames_failed = 0;
+               while (frames) {
+                       skb = skb_dequeue(&ar->tx_pending[i]);
+                       if (unlikely(!skb)) {
+                               frames_failed += frames;
+                               frames = 0;
+                               break;
+                       }
+
+                       info = IEEE80211_SKB_CB(skb);
+                       arinfo = (void *) info->rate_driver_data;
+
+                       /* TODO: cancel stuck frames */
+                       arinfo->timeout = jiffies +
+                                         msecs_to_jiffies(AR9170_TX_TIMEOUT);
+
+#ifdef AR9170_QUEUE_DEBUG
+                       printk(KERN_DEBUG "%s: send frame q:%d =>\n",
+                              wiphy_name(ar->hw->wiphy), i);
+                       ar9170_print_txheader(ar, skb);
+#endif /* AR9170_QUEUE_DEBUG */
+
+                       err = ar->tx(ar, skb);
+                       if (unlikely(err)) {
+                               frames_failed++;
+                               dev_kfree_skb_any(skb);
+                       } else {
+                               remaining_space--;
+                               schedule_garbagecollector = true;
+                       }
+
+                       frames--;
+               }
+
+#ifdef AR9170_QUEUE_DEBUG
+               printk(KERN_DEBUG "%s: ar9170_tx report for queue %d\n",
+                      wiphy_name(ar->hw->wiphy), i);
+
+               printk(KERN_DEBUG "%s: unprocessed pending frames left:\n",
+                      wiphy_name(ar->hw->wiphy));
+               ar9170_dump_txqueue(ar, &ar->tx_pending[i]);
+#endif /* AR9170_QUEUE_DEBUG */
+
+               if (unlikely(frames_failed)) {
+#ifdef AR9170_QUEUE_DEBUG
+                       printk(KERN_DEBUG "%s: frames failed =>\n",
+                              wiphy_name(ar->hw->wiphy), frames_failed);
+#endif /* AR9170_QUEUE_DEBUG */
+
+                       spin_lock_irqsave(&ar->tx_stats_lock, flags);
+                       ar->tx_stats[i].len -= frames_failed;
+                       ar->tx_stats[i].count -= frames_failed;
+                       ieee80211_wake_queue(ar->hw, i);
+                       spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
+               }
+       }
+
+       if (schedule_garbagecollector)
+               queue_delayed_work(ar->hw->workqueue,
+                                  &ar->tx_janitor,
+                                  msecs_to_jiffies(AR9170_JANITOR_DELAY));
+}
+
+int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
+{
+       struct ar9170 *ar = hw->priv;
+       struct ieee80211_tx_info *info;
+
+       if (unlikely(!IS_STARTED(ar)))
+               goto err_free;
+
+       if (unlikely(ar9170_tx_prepare(ar, skb)))
+               goto err_free;
+
+       info = IEEE80211_SKB_CB(skb);
+       if (info->flags & IEEE80211_TX_CTL_AMPDU) {
+               /* drop frame, we do not allow TX A-MPDU aggregation yet. */
+               goto err_free;
+       } else {
+               unsigned int queue = skb_get_queue_mapping(skb);
+
+               ar9170_tx_prepare_phy(ar, skb);
+               skb_queue_tail(&ar->tx_pending[queue], skb);
+       }
+
+       ar9170_tx(ar);
+       return NETDEV_TX_OK;
+
+err_free:
+       dev_kfree_skb_any(skb);
+       return NETDEV_TX_OK;
+}
+
+static int ar9170_op_add_interface(struct ieee80211_hw *hw,
+                                  struct ieee80211_if_init_conf *conf)
+{
+       struct ar9170 *ar = hw->priv;
+       int err = 0;
+
+       mutex_lock(&ar->mutex);
+
+       if (ar->vif) {
+               err = -EBUSY;
+               goto unlock;
+       }
+
+       ar->vif = conf->vif;
+       memcpy(ar->mac_addr, conf->mac_addr, ETH_ALEN);
+
+       if (modparam_nohwcrypt || (ar->vif->type != NL80211_IFTYPE_STATION)) {
+               ar->rx_software_decryption = true;
+               ar->disable_offload = true;
+       }
+
+       ar->cur_filter = 0;
+       ar->want_filter = AR9170_MAC_REG_FTF_DEFAULTS;
+       err = ar9170_update_frame_filter(ar);
+       if (err)
+               goto unlock;
+
+       err = ar9170_set_operating_mode(ar);
+
+unlock:
+       mutex_unlock(&ar->mutex);
+       return err;
+}
+
+static void ar9170_op_remove_interface(struct ieee80211_hw *hw,
+                                      struct ieee80211_if_init_conf *conf)
+{
+       struct ar9170 *ar = hw->priv;
+
+       mutex_lock(&ar->mutex);
+       ar->vif = NULL;
+       ar->want_filter = 0;
+       ar9170_update_frame_filter(ar);
+       ar9170_set_beacon_timers(ar);
+       dev_kfree_skb(ar->beacon);
+       ar->beacon = NULL;
+       ar->sniffer_enabled = false;
+       ar->rx_software_decryption = false;
+       ar9170_set_operating_mode(ar);
+       mutex_unlock(&ar->mutex);
+}
+
+static int ar9170_op_config(struct ieee80211_hw *hw, u32 changed)
+{
+       struct ar9170 *ar = hw->priv;
+       int err = 0;
+
+       mutex_lock(&ar->mutex);
+
+       if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) {
+               /* TODO */
+               err = 0;
+       }
+
+       if (changed & IEEE80211_CONF_CHANGE_PS) {
+               /* TODO */
+               err = 0;
+       }
+
+       if (changed & IEEE80211_CONF_CHANGE_POWER) {
+               /* TODO */
+               err = 0;
+       }
+
+       if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) {
+               /*
+                * is it long_frame_max_tx_count or short_frame_max_tx_count?
+                */
+
+               err = ar9170_set_hwretry_limit(ar,
+                       ar->hw->conf.long_frame_max_tx_count);
+               if (err)
+                       goto out;
+       }
+
+       if (changed & BSS_CHANGED_BEACON_INT) {
+               err = ar9170_set_beacon_timers(ar);
+               if (err)
+                       goto out;
+       }
+
+       if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
+
+               /* adjust slot time for 5 GHz */
+               err = ar9170_set_slot_time(ar);
+               if (err)
+                       goto out;
+
+               err = ar9170_set_dyn_sifs_ack(ar);
+               if (err)
+                       goto out;
+
+               err = ar9170_set_channel(ar, hw->conf.channel,
+                               AR9170_RFI_NONE,
+                               nl80211_to_ar9170(hw->conf.channel_type));
+               if (err)
+                       goto out;
+       }
+
+out:
+       mutex_unlock(&ar->mutex);
+       return err;
+}
+
+static void ar9170_set_filters(struct work_struct *work)
+{
+       struct ar9170 *ar = container_of(work, struct ar9170,
+                                        filter_config_work);
+       int err;
+
+       if (unlikely(!IS_STARTED(ar)))
+               return ;
+
+       mutex_lock(&ar->mutex);
+       if (test_and_clear_bit(AR9170_FILTER_CHANGED_MODE,
+                              &ar->filter_changed)) {
+               err = ar9170_set_operating_mode(ar);
+               if (err)
+                       goto unlock;
+       }
+
+       if (test_and_clear_bit(AR9170_FILTER_CHANGED_MULTICAST,
+                              &ar->filter_changed)) {
+               err = ar9170_update_multicast(ar);
+               if (err)
+                       goto unlock;
+       }
+
+       if (test_and_clear_bit(AR9170_FILTER_CHANGED_FRAMEFILTER,
+                              &ar->filter_changed)) {
+               err = ar9170_update_frame_filter(ar);
+               if (err)
+                       goto unlock;
+       }
+
+unlock:
+       mutex_unlock(&ar->mutex);
+}
+
+static void ar9170_op_configure_filter(struct ieee80211_hw *hw,
+                                      unsigned int changed_flags,
+                                      unsigned int *new_flags,
+                                      int mc_count, struct dev_mc_list *mclist)
+{
+       struct ar9170 *ar = hw->priv;
+
+       /* mask supported flags */
+       *new_flags &= FIF_ALLMULTI | FIF_CONTROL | FIF_BCN_PRBRESP_PROMISC |
+                     FIF_PROMISC_IN_BSS | FIF_FCSFAIL | FIF_PLCPFAIL;
+       ar->filter_state = *new_flags;
+       /*
+        * We can support more by setting the sniffer bit and
+        * then checking the error flags, later.
+        */
+
+       if (changed_flags & FIF_ALLMULTI) {
+               if (*new_flags & FIF_ALLMULTI) {
+                       ar->want_mc_hash = ~0ULL;
+               } else {
+                       u64 mchash;
+                       int i;
+
+                       /* always get broadcast frames */
+                       mchash = 1ULL << (0xff >> 2);
+
+                       for (i = 0; i < mc_count; i++) {
+                               if (WARN_ON(!mclist))
+                                       break;
+                               mchash |= 1ULL << (mclist->dmi_addr[5] >> 2);
+                               mclist = mclist->next;
+                       }
+               ar->want_mc_hash = mchash;
+               }
+               set_bit(AR9170_FILTER_CHANGED_MULTICAST, &ar->filter_changed);
+       }
+
+       if (changed_flags & FIF_CONTROL) {
+               u32 filter = AR9170_MAC_REG_FTF_PSPOLL |
+                            AR9170_MAC_REG_FTF_RTS |
+                            AR9170_MAC_REG_FTF_CTS |
+                            AR9170_MAC_REG_FTF_ACK |
+                            AR9170_MAC_REG_FTF_CFE |
+                            AR9170_MAC_REG_FTF_CFE_ACK;
+
+               if (*new_flags & FIF_CONTROL)
+                       ar->want_filter = ar->cur_filter | filter;
+               else
+                       ar->want_filter = ar->cur_filter & ~filter;
+
+               set_bit(AR9170_FILTER_CHANGED_FRAMEFILTER,
+                       &ar->filter_changed);
+       }
+
+       if (changed_flags & FIF_PROMISC_IN_BSS) {
+               ar->sniffer_enabled = ((*new_flags) & FIF_PROMISC_IN_BSS) != 0;
+               set_bit(AR9170_FILTER_CHANGED_MODE,
+                       &ar->filter_changed);
+       }
+
+       if (likely(IS_STARTED(ar)))
+               queue_work(ar->hw->workqueue, &ar->filter_config_work);
+}
+
+static void ar9170_op_bss_info_changed(struct ieee80211_hw *hw,
+                                      struct ieee80211_vif *vif,
+                                      struct ieee80211_bss_conf *bss_conf,
+                                      u32 changed)
+{
+       struct ar9170 *ar = hw->priv;
+       int err = 0;
+
+       mutex_lock(&ar->mutex);
+
+       if (changed & BSS_CHANGED_BSSID) {
+               memcpy(ar->bssid, bss_conf->bssid, ETH_ALEN);
+               err = ar9170_set_operating_mode(ar);
+               if (err)
+                       goto out;
+       }
+
+       if (changed & (BSS_CHANGED_BEACON | BSS_CHANGED_BEACON_ENABLED)) {
+               err = ar9170_update_beacon(ar);
+               if (err)
+                       goto out;
+
+               err = ar9170_set_beacon_timers(ar);
+               if (err)
+                       goto out;
+       }
+
+       if (changed & BSS_CHANGED_ASSOC) {
+#ifndef CONFIG_AR9170_LEDS
+               /* enable assoc LED. */
+               err = ar9170_set_leds_state(ar, bss_conf->assoc ? 2 : 0);
+#endif /* CONFIG_AR9170_LEDS */
+       }
+
+       if (changed & BSS_CHANGED_BEACON_INT) {
+               err = ar9170_set_beacon_timers(ar);
+               if (err)
+                       goto out;
+       }
+
+       if (changed & BSS_CHANGED_HT) {
+               /* TODO */
+               err = 0;
+       }
+
+       if (changed & BSS_CHANGED_ERP_SLOT) {
+               err = ar9170_set_slot_time(ar);
+               if (err)
+                       goto out;
+       }
+
+       if (changed & BSS_CHANGED_BASIC_RATES) {
+               err = ar9170_set_basic_rates(ar);
+               if (err)
+                       goto out;
+       }
+
+out:
+       mutex_unlock(&ar->mutex);
+}
+
+static u64 ar9170_op_get_tsf(struct ieee80211_hw *hw)
+{
+       struct ar9170 *ar = hw->priv;
+       int err;
+       u32 tsf_low;
+       u32 tsf_high;
+       u64 tsf;
+
+       mutex_lock(&ar->mutex);
+       err = ar9170_read_reg(ar, AR9170_MAC_REG_TSF_L, &tsf_low);
+       if (!err)
+               err = ar9170_read_reg(ar, AR9170_MAC_REG_TSF_H, &tsf_high);
+       mutex_unlock(&ar->mutex);
+
+       if (WARN_ON(err))
+               return 0;
+
+       tsf = tsf_high;
+       tsf = (tsf << 32) | tsf_low;
+       return tsf;
+}
+
+static int ar9170_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
+                         struct ieee80211_vif *vif, struct ieee80211_sta *sta,
+                         struct ieee80211_key_conf *key)
+{
+       struct ar9170 *ar = hw->priv;
+       int err = 0, i;
+       u8 ktype;
+
+       if ((!ar->vif) || (ar->disable_offload))
+               return -EOPNOTSUPP;
+
+       switch (key->alg) {
+       case ALG_WEP:
+               if (key->keylen == WLAN_KEY_LEN_WEP40)
+                       ktype = AR9170_ENC_ALG_WEP64;
+               else
+                       ktype = AR9170_ENC_ALG_WEP128;
+               break;
+       case ALG_TKIP:
+               ktype = AR9170_ENC_ALG_TKIP;
+               break;
+       case ALG_CCMP:
+               ktype = AR9170_ENC_ALG_AESCCMP;
+               break;
+       default:
+               return -EOPNOTSUPP;
+       }
+
+       mutex_lock(&ar->mutex);
+       if (cmd == SET_KEY) {
+               if (unlikely(!IS_STARTED(ar))) {
+                       err = -EOPNOTSUPP;
+                       goto out;
+               }
+
+               /* group keys need all-zeroes address */
+               if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
+                       sta = NULL;
+
+               if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
+                       for (i = 0; i < 64; i++)
+                               if (!(ar->usedkeys & BIT(i)))
+                                       break;
+                       if (i == 64) {
+                               ar->rx_software_decryption = true;
+                               ar9170_set_operating_mode(ar);
+                               err = -ENOSPC;
+                               goto out;
+                       }
+               } else {
+                       i = 64 + key->keyidx;
+               }
+
+               key->hw_key_idx = i;
+
+               err = ar9170_upload_key(ar, i, sta ? sta->addr : NULL, ktype, 0,
+                                       key->key, min_t(u8, 16, key->keylen));
+               if (err)
+                       goto out;
+
+               if (key->alg == ALG_TKIP) {
+                       err = ar9170_upload_key(ar, i, sta ? sta->addr : NULL,
+                                               ktype, 1, key->key + 16, 16);
+                       if (err)
+                               goto out;
+
+                       /*
+                        * hardware is not capable generating the MMIC
+                        * for fragmented frames!
+                        */
+                       key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
+               }
+
+               if (i < 64)
+                       ar->usedkeys |= BIT(i);
+
+               key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
+       } else {
+               if (unlikely(!IS_STARTED(ar))) {
+                       /* The device is gone... together with the key ;-) */
+                       err = 0;
+                       goto out;
+               }
+
+               err = ar9170_disable_key(ar, key->hw_key_idx);
+               if (err)
+                       goto out;
+
+               if (key->hw_key_idx < 64) {
+                       ar->usedkeys &= ~BIT(key->hw_key_idx);
+               } else {
+                       err = ar9170_upload_key(ar, key->hw_key_idx, NULL,
+                                               AR9170_ENC_ALG_NONE, 0,
+                                               NULL, 0);
+                       if (err)
+                               goto out;
+
+                       if (key->alg == ALG_TKIP) {
+                               err = ar9170_upload_key(ar, key->hw_key_idx,
+                                                       NULL,
+                                                       AR9170_ENC_ALG_NONE, 1,
+                                                       NULL, 0);
+                               if (err)
+                                       goto out;
+                       }
+
+               }
+       }
+
+       ar9170_regwrite_begin(ar);
+       ar9170_regwrite(AR9170_MAC_REG_ROLL_CALL_TBL_L, ar->usedkeys);
+       ar9170_regwrite(AR9170_MAC_REG_ROLL_CALL_TBL_H, ar->usedkeys >> 32);
+       ar9170_regwrite_finish();
+       err = ar9170_regwrite_result();
+
+out:
+       mutex_unlock(&ar->mutex);
+
+       return err;
+}
+
+static void ar9170_sta_notify(struct ieee80211_hw *hw,
+                             struct ieee80211_vif *vif,
+                             enum sta_notify_cmd cmd,
+                             struct ieee80211_sta *sta)
+{
+}
+
+static int ar9170_get_stats(struct ieee80211_hw *hw,
+                           struct ieee80211_low_level_stats *stats)
+{
+       struct ar9170 *ar = hw->priv;
+       u32 val;
+       int err;
+
+       mutex_lock(&ar->mutex);
+       err = ar9170_read_reg(ar, AR9170_MAC_REG_TX_RETRY, &val);
+       ar->stats.dot11ACKFailureCount += val;
+
+       memcpy(stats, &ar->stats, sizeof(*stats));
+       mutex_unlock(&ar->mutex);
+
+       return 0;
+}
+
+static int ar9170_get_tx_stats(struct ieee80211_hw *hw,
+                              struct ieee80211_tx_queue_stats *tx_stats)
+{
+       struct ar9170 *ar = hw->priv;
+
+       spin_lock_bh(&ar->tx_stats_lock);
+       memcpy(tx_stats, ar->tx_stats, sizeof(tx_stats[0]) * hw->queues);
+       spin_unlock_bh(&ar->tx_stats_lock);
+
+       return 0;
+}
+
+static int ar9170_conf_tx(struct ieee80211_hw *hw, u16 queue,
+                         const struct ieee80211_tx_queue_params *param)
+{
+       struct ar9170 *ar = hw->priv;
+       int ret;
+
+       mutex_lock(&ar->mutex);
+       if ((param) && !(queue > __AR9170_NUM_TXQ)) {
+               memcpy(&ar->edcf[ar9170_qos_hwmap[queue]],
+                      param, sizeof(*param));
+
+               ret = ar9170_set_qos(ar);
+       } else
+               ret = -EINVAL;
+
+       mutex_unlock(&ar->mutex);
+       return ret;
+}
+
+static int ar9170_ampdu_action(struct ieee80211_hw *hw,
+                              enum ieee80211_ampdu_mlme_action action,
+                              struct ieee80211_sta *sta, u16 tid, u16 *ssn)
+{
+       switch (action) {
+       case IEEE80211_AMPDU_RX_START:
+       case IEEE80211_AMPDU_RX_STOP:
+               /*
+                * Something goes wrong -- RX locks up
+                * after a while of receiving aggregated
+                * frames -- not enabling for now.
+                */
+               return -EOPNOTSUPP;
+       default:
+               return -EOPNOTSUPP;
+       }
+}
+
+static const struct ieee80211_ops ar9170_ops = {
+       .start                  = ar9170_op_start,
+       .stop                   = ar9170_op_stop,
+       .tx                     = ar9170_op_tx,
+       .add_interface          = ar9170_op_add_interface,
+       .remove_interface       = ar9170_op_remove_interface,
+       .config                 = ar9170_op_config,
+       .configure_filter       = ar9170_op_configure_filter,
+       .conf_tx                = ar9170_conf_tx,
+       .bss_info_changed       = ar9170_op_bss_info_changed,
+       .get_tsf                = ar9170_op_get_tsf,
+       .set_key                = ar9170_set_key,
+       .sta_notify             = ar9170_sta_notify,
+       .get_stats              = ar9170_get_stats,
+       .get_tx_stats           = ar9170_get_tx_stats,
+       .ampdu_action           = ar9170_ampdu_action,
+};
+
+void *ar9170_alloc(size_t priv_size)
+{
+       struct ieee80211_hw *hw;
+       struct ar9170 *ar;
+       struct sk_buff *skb;
+       int i;
+
+       /*
+        * this buffer is used for rx stream reconstruction.
+        * Under heavy load this device (or the transport layer?)
+        * tends to split the streams into seperate rx descriptors.
+        */
+
+       skb = __dev_alloc_skb(AR9170_MAX_RX_BUFFER_SIZE, GFP_KERNEL);
+       if (!skb)
+               goto err_nomem;
+
+       hw = ieee80211_alloc_hw(priv_size, &ar9170_ops);
+       if (!hw)
+               goto err_nomem;
+
+       ar = hw->priv;
+       ar->hw = hw;
+       ar->rx_failover = skb;
+
+       mutex_init(&ar->mutex);
+       spin_lock_init(&ar->cmdlock);
+       spin_lock_init(&ar->tx_stats_lock);
+       for (i = 0; i < __AR9170_NUM_TXQ; i++) {
+               skb_queue_head_init(&ar->tx_status[i]);
+               skb_queue_head_init(&ar->tx_pending[i]);
+       }
+       ar9170_rx_reset_rx_mpdu(ar);
+       INIT_WORK(&ar->filter_config_work, ar9170_set_filters);
+       INIT_WORK(&ar->beacon_work, ar9170_new_beacon);
+       INIT_DELAYED_WORK(&ar->tx_janitor, ar9170_tx_janitor);
+
+       /* all hw supports 2.4 GHz, so set channel to 1 by default */
+       ar->channel = &ar9170_2ghz_chantable[0];
+
+       /* first part of wiphy init */
+       ar->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
+                                        BIT(NL80211_IFTYPE_WDS) |
+                                        BIT(NL80211_IFTYPE_ADHOC);
+       ar->hw->flags |= IEEE80211_HW_RX_INCLUDES_FCS |
+                        IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
+                        IEEE80211_HW_SIGNAL_DBM |
+                        IEEE80211_HW_NOISE_DBM;
+
+       ar->hw->queues = __AR9170_NUM_TXQ;
+       ar->hw->extra_tx_headroom = 8;
+       ar->hw->sta_data_size = sizeof(struct ar9170_sta_info);
+
+       ar->hw->max_rates = 1;
+       ar->hw->max_rate_tries = 3;
+
+       for (i = 0; i < ARRAY_SIZE(ar->noise); i++)
+               ar->noise[i] = -95; /* ATH_DEFAULT_NOISE_FLOOR */
+
+       return ar;
+
+err_nomem:
+       kfree_skb(skb);
+       return ERR_PTR(-ENOMEM);
+}
+
+static int ar9170_read_eeprom(struct ar9170 *ar)
+{
+#define RW     8       /* number of words to read at once */
+#define RB     (sizeof(u32) * RW)
+       DECLARE_MAC_BUF(mbuf);
+       u8 *eeprom = (void *)&ar->eeprom;
+       u8 *addr = ar->eeprom.mac_address;
+       __le32 offsets[RW];
+       int i, j, err, bands = 0;
+
+       BUILD_BUG_ON(sizeof(ar->eeprom) & 3);
+
+       BUILD_BUG_ON(RB > AR9170_MAX_CMD_LEN - 4);
+#ifndef __CHECKER__
+       /* don't want to handle trailing remains */
+       BUILD_BUG_ON(sizeof(ar->eeprom) % RB);
+#endif
+
+       for (i = 0; i < sizeof(ar->eeprom)/RB; i++) {
+               for (j = 0; j < RW; j++)
+                       offsets[j] = cpu_to_le32(AR9170_EEPROM_START +
+                                                RB * i + 4 * j);
+
+               err = ar->exec_cmd(ar, AR9170_CMD_RREG,
+                                  RB, (u8 *) &offsets,
+                                  RB, eeprom + RB * i);
+               if (err)
+                       return err;
+       }
+
+#undef RW
+#undef RB
+
+       if (ar->eeprom.length == cpu_to_le16(0xFFFF))
+               return -ENODATA;
+
+       if (ar->eeprom.operating_flags & AR9170_OPFLAG_2GHZ) {
+               ar->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &ar9170_band_2GHz;
+               bands++;
+       }
+       if (ar->eeprom.operating_flags & AR9170_OPFLAG_5GHZ) {
+               ar->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &ar9170_band_5GHz;
+               bands++;
+       }
+       /*
+        * I measured this, a bandswitch takes roughly
+        * 135 ms and a frequency switch about 80.
+        *
+        * FIXME: measure these values again once EEPROM settings
+        *        are used, that will influence them!
+        */
+       if (bands == 2)
+               ar->hw->channel_change_time = 135 * 1000;
+       else
+               ar->hw->channel_change_time = 80 * 1000;
+
+       ar->regulatory.current_rd = le16_to_cpu(ar->eeprom.reg_domain[0]);
+       ar->regulatory.current_rd_ext = le16_to_cpu(ar->eeprom.reg_domain[1]);
+
+       /* second part of wiphy init */
+       SET_IEEE80211_PERM_ADDR(ar->hw, addr);
+
+       return bands ? 0 : -EINVAL;
+}
+
+static int ar9170_reg_notifier(struct wiphy *wiphy,
+                       struct regulatory_request *request)
+{
+       struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
+       struct ar9170 *ar = hw->priv;
+
+       return ath_reg_notifier_apply(wiphy, request, &ar->regulatory);
+}
+
+int ar9170_register(struct ar9170 *ar, struct device *pdev)
+{
+       int err;
+
+       /* try to read EEPROM, init MAC addr */
+       err = ar9170_read_eeprom(ar);
+       if (err)
+               goto err_out;
+
+       err = ath_regd_init(&ar->regulatory, ar->hw->wiphy,
+                           ar9170_reg_notifier);
+       if (err)
+               goto err_out;
+
+       err = ieee80211_register_hw(ar->hw);
+       if (err)
+               goto err_out;
+
+       if (!ath_is_world_regd(&ar->regulatory))
+               regulatory_hint(ar->hw->wiphy, ar->regulatory.alpha2);
+
+       err = ar9170_init_leds(ar);
+       if (err)
+               goto err_unreg;
+
+#ifdef CONFIG_AR9170_LEDS
+       err = ar9170_register_leds(ar);
+       if (err)
+               goto err_unreg;
+#endif /* CONFIG_AR9170_LEDS */
+
+       dev_info(pdev, "Atheros AR9170 is registered as '%s'\n",
+                wiphy_name(ar->hw->wiphy));
+
+       return err;
+
+err_unreg:
+       ieee80211_unregister_hw(ar->hw);
+
+err_out:
+       return err;
+}
+
+void ar9170_unregister(struct ar9170 *ar)
+{
+#ifdef CONFIG_AR9170_LEDS
+       ar9170_unregister_leds(ar);
+#endif /* CONFIG_AR9170_LEDS */
+
+       kfree_skb(ar->rx_failover);
+       ieee80211_unregister_hw(ar->hw);
+       mutex_destroy(&ar->mutex);
+}
diff --git a/drivers/net/wireless/ath/ar9170/phy.c b/drivers/net/wireless/ath/ar9170/phy.c
new file mode 100644 (file)
index 0000000..df86f70
--- /dev/null
@@ -0,0 +1,1240 @@
+/*
+ * Atheros AR9170 driver
+ *
+ * PHY and RF code
+ *
+ * Copyright 2008, 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 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; see the file COPYING.  If not, see
+ * http://www.gnu.org/licenses/.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ *    Copyright (c) 2007-2008 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/bitrev.h>
+#include "ar9170.h"
+#include "cmd.h"
+
+static int ar9170_init_power_cal(struct ar9170 *ar)
+{
+       ar9170_regwrite_begin(ar);
+
+       ar9170_regwrite(0x1bc000 + 0x993c, 0x7f);
+       ar9170_regwrite(0x1bc000 + 0x9934, 0x3f3f3f3f);
+       ar9170_regwrite(0x1bc000 + 0x9938, 0x3f3f3f3f);
+       ar9170_regwrite(0x1bc000 + 0xa234, 0x3f3f3f3f);
+       ar9170_regwrite(0x1bc000 + 0xa238, 0x3f3f3f3f);
+       ar9170_regwrite(0x1bc000 + 0xa38c, 0x3f3f3f3f);
+       ar9170_regwrite(0x1bc000 + 0xa390, 0x3f3f3f3f);
+       ar9170_regwrite(0x1bc000 + 0xa3cc, 0x3f3f3f3f);
+       ar9170_regwrite(0x1bc000 + 0xa3d0, 0x3f3f3f3f);
+       ar9170_regwrite(0x1bc000 + 0xa3d4, 0x3f3f3f3f);
+
+       ar9170_regwrite_finish();
+       return ar9170_regwrite_result();
+}
+
+struct ar9170_phy_init {
+       u32 reg, _5ghz_20, _5ghz_40, _2ghz_40, _2ghz_20;
+};
+
+static struct ar9170_phy_init ar5416_phy_init[] = {
+       { 0x1c5800, 0x00000007, 0x00000007, 0x00000007, 0x00000007, },
+       { 0x1c5804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, },
+       { 0x1c5808, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c580c, 0xad848e19, 0xad848e19, 0xad848e19, 0xad848e19, },
+       { 0x1c5810, 0x7d14e000, 0x7d14e000, 0x7d14e000, 0x7d14e000, },
+       { 0x1c5814, 0x9c0a9f6b, 0x9c0a9f6b, 0x9c0a9f6b, 0x9c0a9f6b, },
+       { 0x1c5818, 0x00000090, 0x00000090, 0x00000090, 0x00000090, },
+       { 0x1c581c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c5820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, },
+       { 0x1c5824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, },
+       { 0x1c5828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, },
+       { 0x1c582c, 0x0000a000, 0x0000a000, 0x0000a000, 0x0000a000, },
+       { 0x1c5830, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c5834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, },
+       { 0x1c5838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, },
+       { 0x1c583c, 0x00200400, 0x00200400, 0x00200400, 0x00200400, },
+       { 0x1c5840, 0x206a002e, 0x206a002e, 0x206a002e, 0x206a002e, },
+       { 0x1c5844, 0x1372161e, 0x13721c1e, 0x13721c24, 0x137216a4, },
+       { 0x1c5848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, },
+       { 0x1c584c, 0x1284233c, 0x1284233c, 0x1284233c, 0x1284233c, },
+       { 0x1c5850, 0x6c48b4e4, 0x6c48b4e4, 0x6c48b0e4, 0x6c48b0e4, },
+       { 0x1c5854, 0x00000859, 0x00000859, 0x00000859, 0x00000859, },
+       { 0x1c5858, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, },
+       { 0x1c585c, 0x31395c5e, 0x31395c5e, 0x31395c5e, 0x31395c5e, },
+       { 0x1c5860, 0x0004dd10, 0x0004dd10, 0x0004dd20, 0x0004dd20, },
+       { 0x1c5868, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190, },
+       { 0x1c586c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, },
+       { 0x1c5900, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c5904, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c5908, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c590c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c5914, 0x000007d0, 0x000007d0, 0x00000898, 0x00000898, },
+       { 0x1c5918, 0x00000118, 0x00000230, 0x00000268, 0x00000134, },
+       { 0x1c591c, 0x10000fff, 0x10000fff, 0x10000fff, 0x10000fff, },
+       { 0x1c5920, 0x0510081c, 0x0510081c, 0x0510001c, 0x0510001c, },
+       { 0x1c5924, 0xd0058a15, 0xd0058a15, 0xd0058a15, 0xd0058a15, },
+       { 0x1c5928, 0x00000001, 0x00000001, 0x00000001, 0x00000001, },
+       { 0x1c592c, 0x00000004, 0x00000004, 0x00000004, 0x00000004, },
+       { 0x1c5934, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
+       { 0x1c5938, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
+       { 0x1c593c, 0x0000007f, 0x0000007f, 0x0000007f, 0x0000007f, },
+       { 0x1c5944, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020, },
+       { 0x1c5948, 0x9280b212, 0x9280b212, 0x9280b212, 0x9280b212, },
+       { 0x1c594c, 0x00020028, 0x00020028, 0x00020028, 0x00020028, },
+       { 0x1c5954, 0x5d50e188, 0x5d50e188, 0x5d50e188, 0x5d50e188, },
+       { 0x1c5958, 0x00081fff, 0x00081fff, 0x00081fff, 0x00081fff, },
+       { 0x1c5960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, },
+       { 0x1c5964, 0x00001120, 0x00001120, 0x00001120, 0x00001120, },
+       { 0x1c5970, 0x190fb515, 0x190fb515, 0x190fb515, 0x190fb515, },
+       { 0x1c5974, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c5978, 0x00000001, 0x00000001, 0x00000001, 0x00000001, },
+       { 0x1c597c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c5980, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c5984, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c5988, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c598c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c5990, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c5994, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c5998, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c599c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c59a0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c59a4, 0x00000007, 0x00000007, 0x00000007, 0x00000007, },
+       { 0x1c59a8, 0x001fff00, 0x001fff00, 0x001fff00, 0x001fff00, },
+       { 0x1c59ac, 0x006f00c4, 0x006f00c4, 0x006f00c4, 0x006f00c4, },
+       { 0x1c59b0, 0x03051000, 0x03051000, 0x03051000, 0x03051000, },
+       { 0x1c59b4, 0x00000820, 0x00000820, 0x00000820, 0x00000820, },
+       { 0x1c59c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, },
+       { 0x1c59c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, },
+       { 0x1c59c8, 0x60f6532c, 0x60f6532c, 0x60f6532c, 0x60f6532c, },
+       { 0x1c59cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, },
+       { 0x1c59d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, },
+       { 0x1c59d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c59d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c59dc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c59e0, 0x00000200, 0x00000200, 0x00000200, 0x00000200, },
+       { 0x1c59e4, 0x64646464, 0x64646464, 0x64646464, 0x64646464, },
+       { 0x1c59e8, 0x3c787878, 0x3c787878, 0x3c787878, 0x3c787878, },
+       { 0x1c59ec, 0x000000aa, 0x000000aa, 0x000000aa, 0x000000aa, },
+       { 0x1c59f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c59fc, 0x00001042, 0x00001042, 0x00001042, 0x00001042, },
+       { 0x1c5a00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c5a04, 0x00000040, 0x00000040, 0x00000040, 0x00000040, },
+       { 0x1c5a08, 0x00000080, 0x00000080, 0x00000080, 0x00000080, },
+       { 0x1c5a0c, 0x000001a1, 0x000001a1, 0x00000141, 0x00000141, },
+       { 0x1c5a10, 0x000001e1, 0x000001e1, 0x00000181, 0x00000181, },
+       { 0x1c5a14, 0x00000021, 0x00000021, 0x000001c1, 0x000001c1, },
+       { 0x1c5a18, 0x00000061, 0x00000061, 0x00000001, 0x00000001, },
+       { 0x1c5a1c, 0x00000168, 0x00000168, 0x00000041, 0x00000041, },
+       { 0x1c5a20, 0x000001a8, 0x000001a8, 0x000001a8, 0x000001a8, },
+       { 0x1c5a24, 0x000001e8, 0x000001e8, 0x000001e8, 0x000001e8, },
+       { 0x1c5a28, 0x00000028, 0x00000028, 0x00000028, 0x00000028, },
+       { 0x1c5a2c, 0x00000068, 0x00000068, 0x00000068, 0x00000068, },
+       { 0x1c5a30, 0x00000189, 0x00000189, 0x000000a8, 0x000000a8, },
+       { 0x1c5a34, 0x000001c9, 0x000001c9, 0x00000169, 0x00000169, },
+       { 0x1c5a38, 0x00000009, 0x00000009, 0x000001a9, 0x000001a9, },
+       { 0x1c5a3c, 0x00000049, 0x00000049, 0x000001e9, 0x000001e9, },
+       { 0x1c5a40, 0x00000089, 0x00000089, 0x00000029, 0x00000029, },
+       { 0x1c5a44, 0x00000170, 0x00000170, 0x00000069, 0x00000069, },
+       { 0x1c5a48, 0x000001b0, 0x000001b0, 0x00000190, 0x00000190, },
+       { 0x1c5a4c, 0x000001f0, 0x000001f0, 0x000001d0, 0x000001d0, },
+       { 0x1c5a50, 0x00000030, 0x00000030, 0x00000010, 0x00000010, },
+       { 0x1c5a54, 0x00000070, 0x00000070, 0x00000050, 0x00000050, },
+       { 0x1c5a58, 0x00000191, 0x00000191, 0x00000090, 0x00000090, },
+       { 0x1c5a5c, 0x000001d1, 0x000001d1, 0x00000151, 0x00000151, },
+       { 0x1c5a60, 0x00000011, 0x00000011, 0x00000191, 0x00000191, },
+       { 0x1c5a64, 0x00000051, 0x00000051, 0x000001d1, 0x000001d1, },
+       { 0x1c5a68, 0x00000091, 0x00000091, 0x00000011, 0x00000011, },
+       { 0x1c5a6c, 0x000001b8, 0x000001b8, 0x00000051, 0x00000051, },
+       { 0x1c5a70, 0x000001f8, 0x000001f8, 0x00000198, 0x00000198, },
+       { 0x1c5a74, 0x00000038, 0x00000038, 0x000001d8, 0x000001d8, },
+       { 0x1c5a78, 0x00000078, 0x00000078, 0x00000018, 0x00000018, },
+       { 0x1c5a7c, 0x00000199, 0x00000199, 0x00000058, 0x00000058, },
+       { 0x1c5a80, 0x000001d9, 0x000001d9, 0x00000098, 0x00000098, },
+       { 0x1c5a84, 0x00000019, 0x00000019, 0x00000159, 0x00000159, },
+       { 0x1c5a88, 0x00000059, 0x00000059, 0x00000199, 0x00000199, },
+       { 0x1c5a8c, 0x00000099, 0x00000099, 0x000001d9, 0x000001d9, },
+       { 0x1c5a90, 0x000000d9, 0x000000d9, 0x00000019, 0x00000019, },
+       { 0x1c5a94, 0x000000f9, 0x000000f9, 0x00000059, 0x00000059, },
+       { 0x1c5a98, 0x000000f9, 0x000000f9, 0x00000099, 0x00000099, },
+       { 0x1c5a9c, 0x000000f9, 0x000000f9, 0x000000d9, 0x000000d9, },
+       { 0x1c5aa0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+       { 0x1c5aa4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+       { 0x1c5aa8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+       { 0x1c5aac, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+       { 0x1c5ab0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+       { 0x1c5ab4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+       { 0x1c5ab8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+       { 0x1c5abc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+       { 0x1c5ac0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+       { 0x1c5ac4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+       { 0x1c5ac8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+       { 0x1c5acc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+       { 0x1c5ad0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+       { 0x1c5ad4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+       { 0x1c5ad8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+       { 0x1c5adc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+       { 0x1c5ae0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+       { 0x1c5ae4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+       { 0x1c5ae8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+       { 0x1c5aec, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+       { 0x1c5af0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+       { 0x1c5af4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+       { 0x1c5af8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+       { 0x1c5afc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
+       { 0x1c5b00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c5b04, 0x00000001, 0x00000001, 0x00000001, 0x00000001, },
+       { 0x1c5b08, 0x00000002, 0x00000002, 0x00000002, 0x00000002, },
+       { 0x1c5b0c, 0x00000003, 0x00000003, 0x00000003, 0x00000003, },
+       { 0x1c5b10, 0x00000004, 0x00000004, 0x00000004, 0x00000004, },
+       { 0x1c5b14, 0x00000005, 0x00000005, 0x00000005, 0x00000005, },
+       { 0x1c5b18, 0x00000008, 0x00000008, 0x00000008, 0x00000008, },
+       { 0x1c5b1c, 0x00000009, 0x00000009, 0x00000009, 0x00000009, },
+       { 0x1c5b20, 0x0000000a, 0x0000000a, 0x0000000a, 0x0000000a, },
+       { 0x1c5b24, 0x0000000b, 0x0000000b, 0x0000000b, 0x0000000b, },
+       { 0x1c5b28, 0x0000000c, 0x0000000c, 0x0000000c, 0x0000000c, },
+       { 0x1c5b2c, 0x0000000d, 0x0000000d, 0x0000000d, 0x0000000d, },
+       { 0x1c5b30, 0x00000010, 0x00000010, 0x00000010, 0x00000010, },
+       { 0x1c5b34, 0x00000011, 0x00000011, 0x00000011, 0x00000011, },
+       { 0x1c5b38, 0x00000012, 0x00000012, 0x00000012, 0x00000012, },
+       { 0x1c5b3c, 0x00000013, 0x00000013, 0x00000013, 0x00000013, },
+       { 0x1c5b40, 0x00000014, 0x00000014, 0x00000014, 0x00000014, },
+       { 0x1c5b44, 0x00000015, 0x00000015, 0x00000015, 0x00000015, },
+       { 0x1c5b48, 0x00000018, 0x00000018, 0x00000018, 0x00000018, },
+       { 0x1c5b4c, 0x00000019, 0x00000019, 0x00000019, 0x00000019, },
+       { 0x1c5b50, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a, },
+       { 0x1c5b54, 0x0000001b, 0x0000001b, 0x0000001b, 0x0000001b, },
+       { 0x1c5b58, 0x0000001c, 0x0000001c, 0x0000001c, 0x0000001c, },
+       { 0x1c5b5c, 0x0000001d, 0x0000001d, 0x0000001d, 0x0000001d, },
+       { 0x1c5b60, 0x00000020, 0x00000020, 0x00000020, 0x00000020, },
+       { 0x1c5b64, 0x00000021, 0x00000021, 0x00000021, 0x00000021, },
+       { 0x1c5b68, 0x00000022, 0x00000022, 0x00000022, 0x00000022, },
+       { 0x1c5b6c, 0x00000023, 0x00000023, 0x00000023, 0x00000023, },
+       { 0x1c5b70, 0x00000024, 0x00000024, 0x00000024, 0x00000024, },
+       { 0x1c5b74, 0x00000025, 0x00000025, 0x00000025, 0x00000025, },
+       { 0x1c5b78, 0x00000028, 0x00000028, 0x00000028, 0x00000028, },
+       { 0x1c5b7c, 0x00000029, 0x00000029, 0x00000029, 0x00000029, },
+       { 0x1c5b80, 0x0000002a, 0x0000002a, 0x0000002a, 0x0000002a, },
+       { 0x1c5b84, 0x0000002b, 0x0000002b, 0x0000002b, 0x0000002b, },
+       { 0x1c5b88, 0x0000002c, 0x0000002c, 0x0000002c, 0x0000002c, },
+       { 0x1c5b8c, 0x0000002d, 0x0000002d, 0x0000002d, 0x0000002d, },
+       { 0x1c5b90, 0x00000030, 0x00000030, 0x00000030, 0x00000030, },
+       { 0x1c5b94, 0x00000031, 0x00000031, 0x00000031, 0x00000031, },
+       { 0x1c5b98, 0x00000032, 0x00000032, 0x00000032, 0x00000032, },
+       { 0x1c5b9c, 0x00000033, 0x00000033, 0x00000033, 0x00000033, },
+       { 0x1c5ba0, 0x00000034, 0x00000034, 0x00000034, 0x00000034, },
+       { 0x1c5ba4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+       { 0x1c5ba8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+       { 0x1c5bac, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+       { 0x1c5bb0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+       { 0x1c5bb4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+       { 0x1c5bb8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+       { 0x1c5bbc, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+       { 0x1c5bc0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+       { 0x1c5bc4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+       { 0x1c5bc8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+       { 0x1c5bcc, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+       { 0x1c5bd0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+       { 0x1c5bd4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+       { 0x1c5bd8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+       { 0x1c5bdc, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+       { 0x1c5be0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+       { 0x1c5be4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+       { 0x1c5be8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+       { 0x1c5bec, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+       { 0x1c5bf0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+       { 0x1c5bf4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
+       { 0x1c5bf8, 0x00000010, 0x00000010, 0x00000010, 0x00000010, },
+       { 0x1c5bfc, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a, },
+       { 0x1c5c00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c5c0c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c5c10, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c5c14, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c5c18, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c5c1c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c5c20, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c5c24, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c5c28, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c5c2c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c5c30, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c5c34, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c5c38, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c5c3c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c5cf0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c5cf4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c5cf8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c5cfc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c6200, 0x00000008, 0x00000008, 0x0000000e, 0x0000000e, },
+       { 0x1c6204, 0x00000440, 0x00000440, 0x00000440, 0x00000440, },
+       { 0x1c6208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, },
+       { 0x1c620c, 0x012e8160, 0x012e8160, 0x012a8160, 0x012a8160, },
+       { 0x1c6210, 0x40806333, 0x40806333, 0x40806333, 0x40806333, },
+       { 0x1c6214, 0x00106c10, 0x00106c10, 0x00106c10, 0x00106c10, },
+       { 0x1c6218, 0x009c4060, 0x009c4060, 0x009c4060, 0x009c4060, },
+       { 0x1c621c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, },
+       { 0x1c6220, 0x018830c6, 0x018830c6, 0x018830c6, 0x018830c6, },
+       { 0x1c6224, 0x00000400, 0x00000400, 0x00000400, 0x00000400, },
+       { 0x1c6228, 0x000009b5, 0x000009b5, 0x000009b5, 0x000009b5, },
+       { 0x1c622c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c6230, 0x00000108, 0x00000210, 0x00000210, 0x00000108, },
+       { 0x1c6234, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
+       { 0x1c6238, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
+       { 0x1c623c, 0x13c889af, 0x13c889af, 0x13c889af, 0x13c889af, },
+       { 0x1c6240, 0x38490a20, 0x38490a20, 0x38490a20, 0x38490a20, },
+       { 0x1c6244, 0x00007bb6, 0x00007bb6, 0x00007bb6, 0x00007bb6, },
+       { 0x1c6248, 0x0fff3ffc, 0x0fff3ffc, 0x0fff3ffc, 0x0fff3ffc, },
+       { 0x1c624c, 0x00000001, 0x00000001, 0x00000001, 0x00000001, },
+       { 0x1c6250, 0x0000a000, 0x0000a000, 0x0000a000, 0x0000a000, },
+       { 0x1c6254, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c6258, 0x0cc75380, 0x0cc75380, 0x0cc75380, 0x0cc75380, },
+       { 0x1c625c, 0x0f0f0f01, 0x0f0f0f01, 0x0f0f0f01, 0x0f0f0f01, },
+       { 0x1c6260, 0xdfa91f01, 0xdfa91f01, 0xdfa91f01, 0xdfa91f01, },
+       { 0x1c6264, 0x00418a11, 0x00418a11, 0x00418a11, 0x00418a11, },
+       { 0x1c6268, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c626c, 0x09249126, 0x09249126, 0x09249126, 0x09249126, },
+       { 0x1c6274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, },
+       { 0x1c6278, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, },
+       { 0x1c627c, 0x051701ce, 0x051701ce, 0x051701ce, 0x051701ce, },
+       { 0x1c6300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, },
+       { 0x1c6304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, },
+       { 0x1c6308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, },
+       { 0x1c630c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, },
+       { 0x1c6310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, },
+       { 0x1c6314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, },
+       { 0x1c6318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, },
+       { 0x1c631c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, },
+       { 0x1c6320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, },
+       { 0x1c6324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, },
+       { 0x1c6328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, },
+       { 0x1c632c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c6330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c6334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c6338, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c633c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c6340, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c6344, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c6348, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, },
+       { 0x1c634c, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, },
+       { 0x1c6350, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, },
+       { 0x1c6354, 0x0003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff, },
+       { 0x1c6358, 0x79a8aa1f, 0x79a8aa1f, 0x79a8aa1f, 0x79a8aa1f, },
+       { 0x1c6388, 0x08000000, 0x08000000, 0x08000000, 0x08000000, },
+       { 0x1c638c, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
+       { 0x1c6390, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
+       { 0x1c6394, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, },
+       { 0x1c6398, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce, },
+       { 0x1c639c, 0x00000007, 0x00000007, 0x00000007, 0x00000007, },
+       { 0x1c63a0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c63a4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c63a8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c63ac, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c63b0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c63b4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c63b8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c63bc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c63c0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c63c4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c63c8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c63cc, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
+       { 0x1c63d0, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
+       { 0x1c63d4, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
+       { 0x1c63d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
+       { 0x1c63dc, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, },
+       { 0x1c63e0, 0x000000c0, 0x000000c0, 0x000000c0, 0x000000c0, },
+       { 0x1c6848, 0x00180a65, 0x00180a65, 0x00180a68, 0x00180a68, },
+       { 0x1c6920, 0x0510001c, 0x0510001c, 0x0510001c, 0x0510001c, },
+       { 0x1c6960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, },
+       { 0x1c720c, 0x012e8160, 0x012e8160, 0x012a8160, 0x012a8160, },
+       { 0x1c726c, 0x09249126, 0x09249126, 0x09249126, 0x09249126, },
+       { 0x1c7848, 0x00180a65, 0x00180a65, 0x00180a68, 0x00180a68, },
+       { 0x1c7920, 0x0510001c, 0x0510001c, 0x0510001c, 0x0510001c, },
+       { 0x1c7960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, },
+       { 0x1c820c, 0x012e8160, 0x012e8160, 0x012a8160, 0x012a8160, },
+       { 0x1c826c, 0x09249126, 0x09249126, 0x09249126, 0x09249126, },
+/*     { 0x1c8864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, }, */
+       { 0x1c8864, 0x0001c600, 0x0001c600, 0x0001c600, 0x0001c600, },
+       { 0x1c895c, 0x004b6a8e, 0x004b6a8e, 0x004b6a8e, 0x004b6a8e, },
+       { 0x1c8968, 0x000003ce, 0x000003ce, 0x000003ce, 0x000003ce, },
+       { 0x1c89bc, 0x00181400, 0x00181400, 0x00181400, 0x00181400, },
+       { 0x1c9270, 0x00820820, 0x00820820, 0x00820820, 0x00820820, },
+       { 0x1c935c, 0x066c420f, 0x066c420f, 0x066c420f, 0x066c420f, },
+       { 0x1c9360, 0x0f282207, 0x0f282207, 0x0f282207, 0x0f282207, },
+       { 0x1c9364, 0x17601685, 0x17601685, 0x17601685, 0x17601685, },
+       { 0x1c9368, 0x1f801104, 0x1f801104, 0x1f801104, 0x1f801104, },
+       { 0x1c936c, 0x37a00c03, 0x37a00c03, 0x37a00c03, 0x37a00c03, },
+       { 0x1c9370, 0x3fc40883, 0x3fc40883, 0x3fc40883, 0x3fc40883, },
+       { 0x1c9374, 0x57c00803, 0x57c00803, 0x57c00803, 0x57c00803, },
+       { 0x1c9378, 0x5fd80682, 0x5fd80682, 0x5fd80682, 0x5fd80682, },
+       { 0x1c937c, 0x7fe00482, 0x7fe00482, 0x7fe00482, 0x7fe00482, },
+       { 0x1c9380, 0x7f3c7bba, 0x7f3c7bba, 0x7f3c7bba, 0x7f3c7bba, },
+       { 0x1c9384, 0xf3307ff0, 0xf3307ff0, 0xf3307ff0, 0xf3307ff0, }
+};
+
+int ar9170_init_phy(struct ar9170 *ar, enum ieee80211_band band)
+{
+       int i, err;
+       u32 val;
+       bool is_2ghz = band == IEEE80211_BAND_2GHZ;
+       bool is_40mhz = conf_is_ht40(&ar->hw->conf);
+
+       ar9170_regwrite_begin(ar);
+
+       for (i = 0; i < ARRAY_SIZE(ar5416_phy_init); i++) {
+               if (is_40mhz) {
+                       if (is_2ghz)
+                               val = ar5416_phy_init[i]._2ghz_40;
+                       else
+                               val = ar5416_phy_init[i]._5ghz_40;
+               } else {
+                       if (is_2ghz)
+                               val = ar5416_phy_init[i]._2ghz_20;
+                       else
+                               val = ar5416_phy_init[i]._5ghz_20;
+               }
+
+               ar9170_regwrite(ar5416_phy_init[i].reg, val);
+       }
+
+       ar9170_regwrite_finish();
+       err = ar9170_regwrite_result();
+       if (err)
+               return err;
+
+       /* XXX: use EEPROM data here! */
+
+       err = ar9170_init_power_cal(ar);
+       if (err)
+               return err;
+
+       /* XXX: remove magic! */
+       if (is_2ghz)
+               err = ar9170_write_reg(ar, 0x1d4014, 0x5163);
+       else
+               err = ar9170_write_reg(ar, 0x1d4014, 0x5143);
+
+       return err;
+}
+
+struct ar9170_rf_init {
+       u32 reg, _5ghz, _2ghz;
+};
+
+static struct ar9170_rf_init ar9170_rf_init[] = {
+     /* bank 0 */
+     { 0x1c58b0,  0x1e5795e5,  0x1e5795e5},
+     { 0x1c58e0,  0x02008020,  0x02008020},
+     /* bank 1 */
+     { 0x1c58b0,  0x02108421,  0x02108421},
+     { 0x1c58ec,  0x00000008,  0x00000008},
+     /* bank 2 */
+     { 0x1c58b0,  0x0e73ff17,  0x0e73ff17},
+     { 0x1c58e0,  0x00000420,  0x00000420},
+     /* bank 3 */
+     { 0x1c58f0,  0x01400018,  0x01c00018},
+     /* bank 4 */
+     { 0x1c58b0,  0x000001a1,  0x000001a1},
+     { 0x1c58e8,  0x00000001,  0x00000001},
+     /* bank 5 */
+     { 0x1c58b0,  0x00000013,  0x00000013},
+     { 0x1c58e4,  0x00000002,  0x00000002},
+     /* bank 6 */
+     { 0x1c58b0,  0x00000000,  0x00000000},
+     { 0x1c58b0,  0x00000000,  0x00000000},
+     { 0x1c58b0,  0x00000000,  0x00000000},
+     { 0x1c58b0,  0x00000000,  0x00000000},
+     { 0x1c58b0,  0x00000000,  0x00000000},
+     { 0x1c58b0,  0x00004000,  0x00004000},
+     { 0x1c58b0,  0x00006c00,  0x00006c00},
+     { 0x1c58b0,  0x00002c00,  0x00002c00},
+     { 0x1c58b0,  0x00004800,  0x00004800},
+     { 0x1c58b0,  0x00004000,  0x00004000},
+     { 0x1c58b0,  0x00006000,  0x00006000},
+     { 0x1c58b0,  0x00001000,  0x00001000},
+     { 0x1c58b0,  0x00004000,  0x00004000},
+     { 0x1c58b0,  0x00007c00,  0x00007c00},
+     { 0x1c58b0,  0x00007c00,  0x00007c00},
+     { 0x1c58b0,  0x00007c00,  0x00007c00},
+     { 0x1c58b0,  0x00007c00,  0x00007c00},
+     { 0x1c58b0,  0x00007c00,  0x00007c00},
+     { 0x1c58b0,  0x00087c00,  0x00087c00},
+     { 0x1c58b0,  0x00007c00,  0x00007c00},
+     { 0x1c58b0,  0x00005400,  0x00005400},
+     { 0x1c58b0,  0x00000c00,  0x00000c00},
+     { 0x1c58b0,  0x00001800,  0x00001800},
+     { 0x1c58b0,  0x00007c00,  0x00007c00},
+     { 0x1c58b0,  0x00006c00,  0x00006c00},
+     { 0x1c58b0,  0x00006c00,  0x00006c00},
+     { 0x1c58b0,  0x00007c00,  0x00007c00},
+     { 0x1c58b0,  0x00002c00,  0x00002c00},
+     { 0x1c58b0,  0x00003c00,  0x00003c00},
+     { 0x1c58b0,  0x00003800,  0x00003800},
+     { 0x1c58b0,  0x00001c00,  0x00001c00},
+     { 0x1c58b0,  0x00000800,  0x00000800},
+     { 0x1c58b0,  0x00000408,  0x00000408},
+     { 0x1c58b0,  0x00004c15,  0x00004c15},
+     { 0x1c58b0,  0x00004188,  0x00004188},
+     { 0x1c58b0,  0x0000201e,  0x0000201e},
+     { 0x1c58b0,  0x00010408,  0x00010408},
+     { 0x1c58b0,  0x00000801,  0x00000801},
+     { 0x1c58b0,  0x00000c08,  0x00000c08},
+     { 0x1c58b0,  0x0000181e,  0x0000181e},
+     { 0x1c58b0,  0x00001016,  0x00001016},
+     { 0x1c58b0,  0x00002800,  0x00002800},
+     { 0x1c58b0,  0x00004010,  0x00004010},
+     { 0x1c58b0,  0x0000081c,  0x0000081c},
+     { 0x1c58b0,  0x00000115,  0x00000115},
+     { 0x1c58b0,  0x00000015,  0x00000015},
+     { 0x1c58b0,  0x00000066,  0x00000066},
+     { 0x1c58b0,  0x0000001c,  0x0000001c},
+     { 0x1c58b0,  0x00000000,  0x00000000},
+     { 0x1c58b0,  0x00000004,  0x00000004},
+     { 0x1c58b0,  0x00000015,  0x00000015},
+     { 0x1c58b0,  0x0000001f,  0x0000001f},
+     { 0x1c58e0,  0x00000000,  0x00000400},
+     /* bank 7 */
+     { 0x1c58b0,  0x000000a0,  0x000000a0},
+     { 0x1c58b0,  0x00000000,  0x00000000},
+     { 0x1c58b0,  0x00000040,  0x00000040},
+     { 0x1c58f0,  0x0000001c,  0x0000001c},
+};
+
+static int ar9170_init_rf_banks_0_7(struct ar9170 *ar, bool band5ghz)
+{
+       int err, i;
+
+       ar9170_regwrite_begin(ar);
+
+       for (i = 0; i < ARRAY_SIZE(ar9170_rf_init); i++)
+               ar9170_regwrite(ar9170_rf_init[i].reg,
+                               band5ghz ? ar9170_rf_init[i]._5ghz
+                                        : ar9170_rf_init[i]._2ghz);
+
+       ar9170_regwrite_finish();
+       err = ar9170_regwrite_result();
+       if (err)
+               printk(KERN_ERR "%s: rf init failed\n",
+                      wiphy_name(ar->hw->wiphy));
+       return err;
+}
+
+static int ar9170_init_rf_bank4_pwr(struct ar9170 *ar, bool band5ghz,
+                                   u32 freq, enum ar9170_bw bw)
+{
+       int err;
+       u32 d0, d1, td0, td1, fd0, fd1;
+       u8 chansel;
+       u8 refsel0 = 1, refsel1 = 0;
+       u8 lf_synth = 0;
+
+       switch (bw) {
+       case AR9170_BW_40_ABOVE:
+               freq += 10;
+               break;
+       case AR9170_BW_40_BELOW:
+               freq -= 10;
+               break;
+       case AR9170_BW_20:
+               break;
+       case __AR9170_NUM_BW:
+               BUG();
+       }
+
+       if (band5ghz) {
+               if (freq % 10) {
+                       chansel = (freq - 4800) / 5;
+               } else {
+                       chansel = ((freq - 4800) / 10) * 2;
+                       refsel0 = 0;
+                       refsel1 = 1;
+               }
+               chansel = byte_rev_table[chansel];
+       } else {
+               if (freq == 2484) {
+                       chansel = 10 + (freq - 2274) / 5;
+                       lf_synth = 1;
+               } else
+                       chansel = 16 + (freq - 2272) / 5;
+               chansel *= 4;
+               chansel = byte_rev_table[chansel];
+       }
+
+       d1 =    chansel;
+       d0 =    0x21 |
+               refsel0 << 3 |
+               refsel1 << 2 |
+               lf_synth << 1;
+       td0 =   d0 & 0x1f;
+       td1 =   d1 & 0x1f;
+       fd0 =   td1 << 5 | td0;
+
+       td0 =   (d0 >> 5) & 0x7;
+       td1 =   (d1 >> 5) & 0x7;
+       fd1 =   td1 << 5 | td0;
+
+       ar9170_regwrite_begin(ar);
+
+       ar9170_regwrite(0x1c58b0, fd0);
+       ar9170_regwrite(0x1c58e8, fd1);
+
+       ar9170_regwrite_finish();
+       err = ar9170_regwrite_result();
+       if (err)
+               return err;
+
+       msleep(10);
+
+       return 0;
+}
+
+struct ar9170_phy_freq_params {
+       u8 coeff_exp;
+       u16 coeff_man;
+       u8 coeff_exp_shgi;
+       u16 coeff_man_shgi;
+};
+
+struct ar9170_phy_freq_entry {
+       u16 freq;
+       struct ar9170_phy_freq_params params[__AR9170_NUM_BW];
+};
+
+/* NB: must be in sync with channel tables in main! */
+static const struct ar9170_phy_freq_entry ar9170_phy_freq_params[] = {
+/*
+ *     freq,
+ *             20MHz,
+ *             40MHz (below),
+ *             40Mhz (above),
+ */
+       { 2412, {
+               { 3, 21737, 3, 19563, },
+               { 3, 21827, 3, 19644, },
+               { 3, 21647, 3, 19482, },
+       } },
+       { 2417, {
+               { 3, 21692, 3, 19523, },
+               { 3, 21782, 3, 19604, },
+               { 3, 21602, 3, 19442, },
+       } },
+       { 2422, {
+               { 3, 21647, 3, 19482, },
+               { 3, 21737, 3, 19563, },
+               { 3, 21558, 3, 19402, },
+       } },
+       { 2427, {
+               { 3, 21602, 3, 19442, },
+               { 3, 21692, 3, 19523, },
+               { 3, 21514, 3, 19362, },
+       } },
+       { 2432, {
+               { 3, 21558, 3, 19402, },
+               { 3, 21647, 3, 19482, },
+               { 3, 21470, 3, 19323, },
+       } },
+       { 2437, {
+               { 3, 21514, 3, 19362, },
+               { 3, 21602, 3, 19442, },
+               { 3, 21426, 3, 19283, },
+       } },
+       { 2442, {
+               { 3, 21470, 3, 19323, },
+               { 3, 21558, 3, 19402, },
+               { 3, 21382, 3, 19244, },
+       } },
+       { 2447, {
+               { 3, 21426, 3, 19283, },
+               { 3, 21514, 3, 19362, },
+               { 3, 21339, 3, 19205, },
+       } },
+       { 2452, {
+               { 3, 21382, 3, 19244, },
+               { 3, 21470, 3, 19323, },
+               { 3, 21295, 3, 19166, },
+       } },
+       { 2457, {
+               { 3, 21339, 3, 19205, },
+               { 3, 21426, 3, 19283, },
+               { 3, 21252, 3, 19127, },
+       } },
+       { 2462, {
+               { 3, 21295, 3, 19166, },
+               { 3, 21382, 3, 19244, },
+               { 3, 21209, 3, 19088, },
+       } },
+       { 2467, {
+               { 3, 21252, 3, 19127, },
+               { 3, 21339, 3, 19205, },
+               { 3, 21166, 3, 19050, },
+       } },
+       { 2472, {
+               { 3, 21209, 3, 19088, },
+               { 3, 21295, 3, 19166, },
+               { 3, 21124, 3, 19011, },
+       } },
+       { 2484, {
+               { 3, 21107, 3, 18996, },
+               { 3, 21192, 3, 19073, },
+               { 3, 21022, 3, 18920, },
+       } },
+       { 4920, {
+               { 4, 21313, 4, 19181, },
+               { 4, 21356, 4, 19220, },
+               { 4, 21269, 4, 19142, },
+       } },
+       { 4940, {
+               { 4, 21226, 4, 19104, },
+               { 4, 21269, 4, 19142, },
+               { 4, 21183, 4, 19065, },
+       } },
+       { 4960, {
+               { 4, 21141, 4, 19027, },
+               { 4, 21183, 4, 19065, },
+               { 4, 21098, 4, 18988, },
+       } },
+       { 4980, {
+               { 4, 21056, 4, 18950, },
+               { 4, 21098, 4, 18988, },
+               { 4, 21014, 4, 18912, },
+       } },
+       { 5040, {
+               { 4, 20805, 4, 18725, },
+               { 4, 20846, 4, 18762, },
+               { 4, 20764, 4, 18687, },
+       } },
+       { 5060, {
+               { 4, 20723, 4, 18651, },
+               { 4, 20764, 4, 18687, },
+               { 4, 20682, 4, 18614, },
+       } },
+       { 5080, {
+               { 4, 20641, 4, 18577, },
+               { 4, 20682, 4, 18614, },
+               { 4, 20601, 4, 18541, },
+       } },
+       { 5180, {
+               { 4, 20243, 4, 18219, },
+               { 4, 20282, 4, 18254, },
+               { 4, 20204, 4, 18183, },
+       } },
+       { 5200, {
+               { 4, 20165, 4, 18148, },
+               { 4, 20204, 4, 18183, },
+               { 4, 20126, 4, 18114, },
+       } },
+       { 5220, {
+               { 4, 20088, 4, 18079, },
+               { 4, 20126, 4, 18114, },
+               { 4, 20049, 4, 18044, },
+       } },
+       { 5240, {
+               { 4, 20011, 4, 18010, },
+               { 4, 20049, 4, 18044, },
+               { 4, 19973, 4, 17976, },
+       } },
+       { 5260, {
+               { 4, 19935, 4, 17941, },
+               { 4, 19973, 4, 17976, },
+               { 4, 19897, 4, 17907, },
+       } },
+       { 5280, {
+               { 4, 19859, 4, 17873, },
+               { 4, 19897, 4, 17907, },
+               { 4, 19822, 4, 17840, },
+       } },
+       { 5300, {
+               { 4, 19784, 4, 17806, },
+               { 4, 19822, 4, 17840, },
+               { 4, 19747, 4, 17772, },
+       } },
+       { 5320, {
+               { 4, 19710, 4, 17739, },
+               { 4, 19747, 4, 17772, },
+               { 4, 19673, 4, 17706, },
+       } },
+       { 5500, {
+               { 4, 19065, 4, 17159, },
+               { 4, 19100, 4, 17190, },
+               { 4, 19030, 4, 17127, },
+       } },
+       { 5520, {
+               { 4, 18996, 4, 17096, },
+               { 4, 19030, 4, 17127, },
+               { 4, 18962, 4, 17065, },
+       } },
+       { 5540, {
+               { 4, 18927, 4, 17035, },
+               { 4, 18962, 4, 17065, },
+               { 4, 18893, 4, 17004, },
+       } },
+       { 5560, {
+               { 4, 18859, 4, 16973, },
+               { 4, 18893, 4, 17004, },
+               { 4, 18825, 4, 16943, },
+       } },
+       { 5580, {
+               { 4, 18792, 4, 16913, },
+               { 4, 18825, 4, 16943, },
+               { 4, 18758, 4, 16882, },
+       } },
+       { 5600, {
+               { 4, 18725, 4, 16852, },
+               { 4, 18758, 4, 16882, },
+               { 4, 18691, 4, 16822, },
+       } },
+       { 5620, {
+               { 4, 18658, 4, 16792, },
+               { 4, 18691, 4, 16822, },
+               { 4, 18625, 4, 16762, },
+       } },
+       { 5640, {
+               { 4, 18592, 4, 16733, },
+               { 4, 18625, 4, 16762, },
+               { 4, 18559, 4, 16703, },
+       } },
+       { 5660, {
+               { 4, 18526, 4, 16673, },
+               { 4, 18559, 4, 16703, },
+               { 4, 18493, 4, 16644, },
+       } },
+       { 5680, {
+               { 4, 18461, 4, 16615, },
+               { 4, 18493, 4, 16644, },
+               { 4, 18428, 4, 16586, },
+       } },
+       { 5700, {
+               { 4, 18396, 4, 16556, },
+               { 4, 18428, 4, 16586, },
+               { 4, 18364, 4, 16527, },
+       } },
+       { 5745, {
+               { 4, 18252, 4, 16427, },
+               { 4, 18284, 4, 16455, },
+               { 4, 18220, 4, 16398, },
+       } },
+       { 5765, {
+               { 4, 18189, 5, 32740, },
+               { 4, 18220, 4, 16398, },
+               { 4, 18157, 5, 32683, },
+       } },
+       { 5785, {
+               { 4, 18126, 5, 32626, },
+               { 4, 18157, 5, 32683, },
+               { 4, 18094, 5, 32570, },
+       } },
+       { 5805, {
+               { 4, 18063, 5, 32514, },
+               { 4, 18094, 5, 32570, },
+               { 4, 18032, 5, 32458, },
+       } },
+       { 5825, {
+               { 4, 18001, 5, 32402, },
+               { 4, 18032, 5, 32458, },
+               { 4, 17970, 5, 32347, },
+       } },
+       { 5170, {
+               { 4, 20282, 4, 18254, },
+               { 4, 20321, 4, 18289, },
+               { 4, 20243, 4, 18219, },
+       } },
+       { 5190, {
+               { 4, 20204, 4, 18183, },
+               { 4, 20243, 4, 18219, },
+               { 4, 20165, 4, 18148, },
+       } },
+       { 5210, {
+               { 4, 20126, 4, 18114, },
+               { 4, 20165, 4, 18148, },
+               { 4, 20088, 4, 18079, },
+       } },
+       { 5230, {
+               { 4, 20049, 4, 18044, },
+               { 4, 20088, 4, 18079, },
+               { 4, 20011, 4, 18010, },
+       } },
+};
+
+static const struct ar9170_phy_freq_params *
+ar9170_get_hw_dyn_params(struct ieee80211_channel *channel,
+                        enum ar9170_bw bw)
+{
+       unsigned int chanidx = 0;
+       u16 freq = 2412;
+
+       if (channel) {
+               chanidx = channel->hw_value;
+               freq = channel->center_freq;
+       }
+
+       BUG_ON(chanidx >= ARRAY_SIZE(ar9170_phy_freq_params));
+
+       BUILD_BUG_ON(__AR9170_NUM_BW != 3);
+
+       WARN_ON(ar9170_phy_freq_params[chanidx].freq != freq);
+
+       return &ar9170_phy_freq_params[chanidx].params[bw];
+}
+
+
+int ar9170_init_rf(struct ar9170 *ar)
+{
+       const struct ar9170_phy_freq_params *freqpar;
+       __le32 cmd[7];
+       int err;
+
+       err = ar9170_init_rf_banks_0_7(ar, false);
+       if (err)
+               return err;
+
+       err = ar9170_init_rf_bank4_pwr(ar, false, 2412, AR9170_BW_20);
+       if (err)
+               return err;
+
+       freqpar = ar9170_get_hw_dyn_params(NULL, AR9170_BW_20);
+
+       cmd[0] = cpu_to_le32(2412 * 1000);
+       cmd[1] = cpu_to_le32(0);
+       cmd[2] = cpu_to_le32(1);
+       cmd[3] = cpu_to_le32(freqpar->coeff_exp);
+       cmd[4] = cpu_to_le32(freqpar->coeff_man);
+       cmd[5] = cpu_to_le32(freqpar->coeff_exp_shgi);
+       cmd[6] = cpu_to_le32(freqpar->coeff_man_shgi);
+
+       /* RF_INIT echoes the command back to us */
+       err = ar->exec_cmd(ar, AR9170_CMD_RF_INIT,
+                          sizeof(cmd), (u8 *)cmd,
+                          sizeof(cmd), (u8 *)cmd);
+       if (err)
+               return err;
+
+       msleep(1000);
+
+       return ar9170_echo_test(ar, 0xaabbccdd);
+}
+
+static int ar9170_find_freq_idx(int nfreqs, u8 *freqs, u8 f)
+{
+       int idx = nfreqs - 2;
+
+       while (idx >= 0) {
+               if (f >= freqs[idx])
+                       return idx;
+               idx--;
+       }
+
+       return 0;
+}
+
+static s32 ar9170_interpolate_s32(s32 x, s32 x1, s32 y1, s32 x2, s32 y2)
+{
+       /* nothing to interpolate, it's horizontal */
+       if (y2 == y1)
+               return y1;
+
+       /* check if we hit one of the edges */
+       if (x == x1)
+               return y1;
+       if (x == x2)
+               return y2;
+
+       /* x1 == x2 is bad, hopefully == x */
+       if (x2 == x1)
+               return y1;
+
+       return y1 + (((y2 - y1) * (x - x1)) / (x2 - x1));
+}
+
+static u8 ar9170_interpolate_u8(u8 x, u8 x1, u8 y1, u8 x2, u8 y2)
+{
+#define SHIFT          8
+       s32 y;
+
+       y = ar9170_interpolate_s32(x << SHIFT,
+                                  x1 << SHIFT, y1 << SHIFT,
+                                  x2 << SHIFT, y2 << SHIFT);
+
+       /*
+        * XXX: unwrap this expression
+        *      Isn't it just DIV_ROUND_UP(y, 1<<SHIFT)?
+        *      Can we rely on the compiler to optimise away the div?
+        */
+       return (y >> SHIFT) + ((y & (1<<(SHIFT-1))) >> (SHIFT - 1));
+#undef SHIFT
+}
+
+static int ar9170_set_power_cal(struct ar9170 *ar, u32 freq, enum ar9170_bw bw)
+{
+       struct ar9170_calibration_target_power_legacy *ctpl;
+       struct ar9170_calibration_target_power_ht *ctph;
+       u8 *ctpres;
+       int ntargets;
+       int idx, i, n;
+       u8 ackpower, ackchains, f;
+       u8 pwr_freqs[AR5416_MAX_NUM_TGT_PWRS];
+
+       if (freq < 3000)
+               f = freq - 2300;
+       else
+               f = (freq - 4800)/5;
+
+       /*
+        * cycle through the various modes
+        *
+        * legacy modes first: 5G, 2G CCK, 2G OFDM
+        */
+       for (i = 0; i < 3; i++) {
+               switch (i) {
+               case 0: /* 5 GHz legacy */
+                       ctpl = &ar->eeprom.cal_tgt_pwr_5G[0];
+                       ntargets = AR5416_NUM_5G_TARGET_PWRS;
+                       ctpres = ar->power_5G_leg;
+                       break;
+               case 1: /* 2.4 GHz CCK */
+                       ctpl = &ar->eeprom.cal_tgt_pwr_2G_cck[0];
+                       ntargets = AR5416_NUM_2G_CCK_TARGET_PWRS;
+                       ctpres = ar->power_2G_cck;
+                       break;
+               case 2: /* 2.4 GHz OFDM */
+                       ctpl = &ar->eeprom.cal_tgt_pwr_2G_ofdm[0];
+                       ntargets = AR5416_NUM_2G_OFDM_TARGET_PWRS;
+                       ctpres = ar->power_2G_ofdm;
+                       break;
+               default:
+                       BUG();
+               }
+
+               for (n = 0; n < ntargets; n++) {
+                       if (ctpl[n].freq == 0xff)
+                               break;
+                       pwr_freqs[n] = ctpl[n].freq;
+               }
+               ntargets = n;
+               idx = ar9170_find_freq_idx(ntargets, pwr_freqs, f);
+               for (n = 0; n < 4; n++)
+                       ctpres[n] = ar9170_interpolate_u8(
+                                       f,
+                                       ctpl[idx + 0].freq,
+                                       ctpl[idx + 0].power[n],
+                                       ctpl[idx + 1].freq,
+                                       ctpl[idx + 1].power[n]);
+       }
+
+       /*
+        * HT modes now: 5G HT20, 5G HT40, 2G CCK, 2G OFDM, 2G HT20, 2G HT40
+        */
+       for (i = 0; i < 4; i++) {
+               switch (i) {
+               case 0: /* 5 GHz HT 20 */
+                       ctph = &ar->eeprom.cal_tgt_pwr_5G_ht20[0];
+                       ntargets = AR5416_NUM_5G_TARGET_PWRS;
+                       ctpres = ar->power_5G_ht20;
+                       break;
+               case 1: /* 5 GHz HT 40 */
+                       ctph = &ar->eeprom.cal_tgt_pwr_5G_ht40[0];
+                       ntargets = AR5416_NUM_5G_TARGET_PWRS;
+                       ctpres = ar->power_5G_ht40;
+                       break;
+               case 2: /* 2.4 GHz HT 20 */
+                       ctph = &ar->eeprom.cal_tgt_pwr_2G_ht20[0];
+                       ntargets = AR5416_NUM_2G_OFDM_TARGET_PWRS;
+                       ctpres = ar->power_2G_ht20;
+                       break;
+               case 3: /* 2.4 GHz HT 40 */
+                       ctph = &ar->eeprom.cal_tgt_pwr_2G_ht40[0];
+                       ntargets = AR5416_NUM_2G_OFDM_TARGET_PWRS;
+                       ctpres = ar->power_2G_ht40;
+                       break;
+               default:
+                       BUG();
+               }
+
+               for (n = 0; n < ntargets; n++) {
+                       if (ctph[n].freq == 0xff)
+                               break;
+                       pwr_freqs[n] = ctph[n].freq;
+               }
+               ntargets = n;
+               idx = ar9170_find_freq_idx(ntargets, pwr_freqs, f);
+               for (n = 0; n < 8; n++)
+                       ctpres[n] = ar9170_interpolate_u8(
+                                       f,
+                                       ctph[idx + 0].freq,
+                                       ctph[idx + 0].power[n],
+                                       ctph[idx + 1].freq,
+                                       ctph[idx + 1].power[n]);
+       }
+
+       /* set ACK/CTS TX power */
+       ar9170_regwrite_begin(ar);
+
+       if (ar->eeprom.tx_mask != 1)
+               ackchains = AR9170_TX_PHY_TXCHAIN_2;
+       else
+               ackchains = AR9170_TX_PHY_TXCHAIN_1;
+
+       if (freq < 3000)
+               ackpower = ar->power_2G_ofdm[0] & 0x3f;
+       else
+               ackpower = ar->power_5G_leg[0] & 0x3f;
+
+       ar9170_regwrite(0x1c3694, ackpower << 20 | ackchains << 26);
+       ar9170_regwrite(0x1c3bb4, ackpower << 5 | ackchains << 11 |
+                                 ackpower << 21 | ackchains << 27);
+
+       ar9170_regwrite_finish();
+       return ar9170_regwrite_result();
+}
+
+static int ar9170_calc_noise_dbm(u32 raw_noise)
+{
+       if (raw_noise & 0x100)
+               return ~((raw_noise & 0x0ff) >> 1);
+       else
+               return (raw_noise & 0xff) >> 1;
+}
+
+int ar9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
+                      enum ar9170_rf_init_mode rfi, enum ar9170_bw bw)
+{
+       const struct ar9170_phy_freq_params *freqpar;
+       u32 cmd, tmp, offs;
+       __le32 vals[8];
+       int i, err;
+       bool bandswitch;
+
+       /* clear BB heavy clip enable */
+       err = ar9170_write_reg(ar, 0x1c59e0, 0x200);
+       if (err)
+               return err;
+
+       /* may be NULL at first setup */
+       if (ar->channel)
+               bandswitch = ar->channel->band != channel->band;
+       else
+               bandswitch = true;
+
+       /* HW workaround */
+       if (!ar->hw->wiphy->bands[IEEE80211_BAND_5GHZ] &&
+           channel->center_freq <= 2417)
+               bandswitch = true;
+
+       err = ar->exec_cmd(ar, AR9170_CMD_FREQ_START, 0, NULL, 0, NULL);
+       if (err)
+               return err;
+
+       if (rfi != AR9170_RFI_NONE || bandswitch) {
+               u32 val = 0x400;
+
+               if (rfi == AR9170_RFI_COLD)
+                       val = 0x800;
+
+               /* warm/cold reset BB/ADDA */
+               err = ar9170_write_reg(ar, 0x1d4004, val);
+               if (err)
+                       return err;
+
+               err = ar9170_write_reg(ar, 0x1d4004, 0x0);
+               if (err)
+                       return err;
+
+               err = ar9170_init_phy(ar, channel->band);
+               if (err)
+                       return err;
+
+               err = ar9170_init_rf_banks_0_7(ar,
+                       channel->band == IEEE80211_BAND_5GHZ);
+               if (err)
+                       return err;
+
+               cmd = AR9170_CMD_RF_INIT;
+       } else {
+               cmd = AR9170_CMD_FREQUENCY;
+       }
+
+       err = ar9170_init_rf_bank4_pwr(ar,
+               channel->band == IEEE80211_BAND_5GHZ,
+               channel->center_freq, bw);
+       if (err)
+               return err;
+
+       switch (bw) {
+       case AR9170_BW_20:
+               tmp = 0x240;
+               offs = 0;
+               break;
+       case AR9170_BW_40_BELOW:
+               tmp = 0x2c4;
+               offs = 3;
+               break;
+       case AR9170_BW_40_ABOVE:
+               tmp = 0x2d4;
+               offs = 1;
+               break;
+       default:
+               BUG();
+               return -ENOSYS;
+       }
+
+       if (ar->eeprom.tx_mask != 1)
+               tmp |= 0x100;
+
+       err = ar9170_write_reg(ar, 0x1c5804, tmp);
+       if (err)
+               return err;
+
+       err = ar9170_set_power_cal(ar, channel->center_freq, bw);
+       if (err)
+               return err;
+
+       freqpar = ar9170_get_hw_dyn_params(channel, bw);
+
+       vals[0] = cpu_to_le32(channel->center_freq * 1000);
+       vals[1] = cpu_to_le32(conf_is_ht40(&ar->hw->conf));
+       vals[2] = cpu_to_le32(offs << 2 | 1);
+       vals[3] = cpu_to_le32(freqpar->coeff_exp);
+       vals[4] = cpu_to_le32(freqpar->coeff_man);
+       vals[5] = cpu_to_le32(freqpar->coeff_exp_shgi);
+       vals[6] = cpu_to_le32(freqpar->coeff_man_shgi);
+       vals[7] = cpu_to_le32(1000);
+
+       err = ar->exec_cmd(ar, cmd, sizeof(vals), (u8 *)vals,
+                          sizeof(vals), (u8 *)vals);
+       if (err)
+               return err;
+
+       for (i = 0; i < 2; i++) {
+               ar->noise[i] = ar9170_calc_noise_dbm(
+                               (le32_to_cpu(vals[2 + i]) >> 19) & 0x1ff);
+
+               ar->noise[i + 2] = ar9170_calc_noise_dbm(
+                                   (le32_to_cpu(vals[5 + i]) >> 23) & 0x1ff);
+       }
+
+       ar->channel = channel;
+       return 0;
+}
diff --git a/drivers/net/wireless/ath/ar9170/usb.c b/drivers/net/wireless/ath/ar9170/usb.c
new file mode 100644 (file)
index 0000000..754b1f8
--- /dev/null
@@ -0,0 +1,929 @@
+/*
+ * Atheros AR9170 driver
+ *
+ * USB - frontend
+ *
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
+ * Copyright 2009, Christian Lamparter <chunkeey@web.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.
+ *
+ * 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; see the file COPYING.  If not, see
+ * http://www.gnu.org/licenses/.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ *    Copyright (c) 2007-2008 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/module.h>
+#include <linux/usb.h>
+#include <linux/firmware.h>
+#include <linux/etherdevice.h>
+#include <net/mac80211.h>
+#include "ar9170.h"
+#include "cmd.h"
+#include "hw.h"
+#include "usb.h"
+
+MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
+MODULE_AUTHOR("Christian Lamparter <chunkeey@web.de>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Atheros AR9170 802.11n USB wireless");
+MODULE_FIRMWARE("ar9170.fw");
+MODULE_FIRMWARE("ar9170-1.fw");
+MODULE_FIRMWARE("ar9170-2.fw");
+
+enum ar9170_requirements {
+       AR9170_REQ_FW1_ONLY = 1,
+};
+
+static struct usb_device_id ar9170_usb_ids[] = {
+       /* Atheros 9170 */
+       { USB_DEVICE(0x0cf3, 0x9170) },
+       /* Atheros TG121N */
+       { USB_DEVICE(0x0cf3, 0x1001) },
+       /* Cace Airpcap NX */
+       { USB_DEVICE(0xcace, 0x0300) },
+       /* D-Link DWA 160A */
+       { USB_DEVICE(0x07d1, 0x3c10) },
+       /* Netgear WNDA3100 */
+       { USB_DEVICE(0x0846, 0x9010) },
+       /* Netgear WN111 v2 */
+       { USB_DEVICE(0x0846, 0x9001) },
+       /* Zydas ZD1221 */
+       { USB_DEVICE(0x0ace, 0x1221) },
+       /* ZyXEL NWD271N */
+       { USB_DEVICE(0x0586, 0x3417) },
+       /* Z-Com UB81 BG */
+       { USB_DEVICE(0x0cde, 0x0023) },
+       /* Z-Com UB82 ABG */
+       { USB_DEVICE(0x0cde, 0x0026) },
+       /* Arcadyan WN7512 */
+       { USB_DEVICE(0x083a, 0xf522) },
+       /* Planex GWUS300 */
+       { USB_DEVICE(0x2019, 0x5304) },
+       /* IO-Data WNGDNUS2 */
+       { USB_DEVICE(0x04bb, 0x093f) },
+       /* AVM FRITZ!WLAN USB Stick N */
+       { USB_DEVICE(0x057C, 0x8401) },
+       /* AVM FRITZ!WLAN USB Stick N 2.4 */
+       { USB_DEVICE(0x057C, 0x8402), .driver_info = AR9170_REQ_FW1_ONLY },
+
+       /* terminate */
+       {}
+};
+MODULE_DEVICE_TABLE(usb, ar9170_usb_ids);
+
+static void ar9170_usb_submit_urb(struct ar9170_usb *aru)
+{
+       struct urb *urb;
+       unsigned long flags;
+       int err;
+
+       if (unlikely(!IS_STARTED(&aru->common)))
+               return ;
+
+       spin_lock_irqsave(&aru->tx_urb_lock, flags);
+       if (aru->tx_submitted_urbs >= AR9170_NUM_TX_URBS) {
+               spin_unlock_irqrestore(&aru->tx_urb_lock, flags);
+               return ;
+       }
+       aru->tx_submitted_urbs++;
+
+       urb = usb_get_from_anchor(&aru->tx_pending);
+       if (!urb) {
+               aru->tx_submitted_urbs--;
+               spin_unlock_irqrestore(&aru->tx_urb_lock, flags);
+
+               return ;
+       }
+       spin_unlock_irqrestore(&aru->tx_urb_lock, flags);
+
+       aru->tx_pending_urbs--;
+       usb_anchor_urb(urb, &aru->tx_submitted);
+
+       err = usb_submit_urb(urb, GFP_ATOMIC);
+       if (unlikely(err)) {
+               if (ar9170_nag_limiter(&aru->common))
+                       dev_err(&aru->udev->dev, "submit_urb failed (%d).\n",
+                               err);
+
+               usb_unanchor_urb(urb);
+               aru->tx_submitted_urbs--;
+               ar9170_tx_callback(&aru->common, urb->context);
+       }
+
+       usb_free_urb(urb);
+}
+
+static void ar9170_usb_tx_urb_complete_frame(struct urb *urb)
+{
+       struct sk_buff *skb = urb->context;
+       struct ar9170_usb *aru = (struct ar9170_usb *)
+             usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
+
+       if (unlikely(!aru)) {
+               dev_kfree_skb_irq(skb);
+               return ;
+       }
+
+       aru->tx_submitted_urbs--;
+
+       ar9170_tx_callback(&aru->common, skb);
+
+       ar9170_usb_submit_urb(aru);
+}
+
+static void ar9170_usb_tx_urb_complete(struct urb *urb)
+{
+}
+
+static void ar9170_usb_irq_completed(struct urb *urb)
+{
+       struct ar9170_usb *aru = urb->context;
+
+       switch (urb->status) {
+       /* everything is fine */
+       case 0:
+               break;
+
+       /* disconnect */
+       case -ENOENT:
+       case -ECONNRESET:
+       case -ENODEV:
+       case -ESHUTDOWN:
+               goto free;
+
+       default:
+               goto resubmit;
+       }
+
+       ar9170_handle_command_response(&aru->common, urb->transfer_buffer,
+                                      urb->actual_length);
+
+resubmit:
+       usb_anchor_urb(urb, &aru->rx_submitted);
+       if (usb_submit_urb(urb, GFP_ATOMIC)) {
+               usb_unanchor_urb(urb);
+               goto free;
+       }
+
+       return;
+
+free:
+       usb_buffer_free(aru->udev, 64, urb->transfer_buffer, urb->transfer_dma);
+}
+
+static void ar9170_usb_rx_completed(struct urb *urb)
+{
+       struct sk_buff *skb = urb->context;
+       struct ar9170_usb *aru = (struct ar9170_usb *)
+               usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
+       int err;
+
+       if (!aru)
+               goto free;
+
+       switch (urb->status) {
+       /* everything is fine */
+       case 0:
+               break;
+
+       /* disconnect */
+       case -ENOENT:
+       case -ECONNRESET:
+       case -ENODEV:
+       case -ESHUTDOWN:
+               goto free;
+
+       default:
+               goto resubmit;
+       }
+
+       skb_put(skb, urb->actual_length);
+       ar9170_rx(&aru->common, skb);
+
+resubmit:
+       skb_reset_tail_pointer(skb);
+       skb_trim(skb, 0);
+
+       usb_anchor_urb(urb, &aru->rx_submitted);
+       err = usb_submit_urb(urb, GFP_ATOMIC);
+       if (unlikely(err)) {
+               usb_unanchor_urb(urb);
+               goto free;
+       }
+
+       return ;
+
+free:
+       dev_kfree_skb_irq(skb);
+}
+
+static int ar9170_usb_prep_rx_urb(struct ar9170_usb *aru,
+                                 struct urb *urb, gfp_t gfp)
+{
+       struct sk_buff *skb;
+
+       skb = __dev_alloc_skb(AR9170_MAX_RX_BUFFER_SIZE + 32, gfp);
+       if (!skb)
+               return -ENOMEM;
+
+       /* reserve some space for mac80211's radiotap */
+       skb_reserve(skb, 32);
+
+       usb_fill_bulk_urb(urb, aru->udev,
+                         usb_rcvbulkpipe(aru->udev, AR9170_EP_RX),
+                         skb->data, min(skb_tailroom(skb),
+                         AR9170_MAX_RX_BUFFER_SIZE),
+                         ar9170_usb_rx_completed, skb);
+
+       return 0;
+}
+
+static int ar9170_usb_alloc_rx_irq_urb(struct ar9170_usb *aru)
+{
+       struct urb *urb = NULL;
+       void *ibuf;
+       int err = -ENOMEM;
+
+       /* initialize interrupt endpoint */
+       urb = usb_alloc_urb(0, GFP_KERNEL);
+       if (!urb)
+               goto out;
+
+       ibuf = usb_buffer_alloc(aru->udev, 64, GFP_KERNEL, &urb->transfer_dma);
+       if (!ibuf)
+               goto out;
+
+       usb_fill_int_urb(urb, aru->udev,
+                        usb_rcvintpipe(aru->udev, AR9170_EP_IRQ), ibuf,
+                        64, ar9170_usb_irq_completed, aru, 1);
+       urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+
+       usb_anchor_urb(urb, &aru->rx_submitted);
+       err = usb_submit_urb(urb, GFP_KERNEL);
+       if (err) {
+               usb_unanchor_urb(urb);
+               usb_buffer_free(aru->udev, 64, urb->transfer_buffer,
+                               urb->transfer_dma);
+       }
+
+out:
+       usb_free_urb(urb);
+       return err;
+}
+
+static int ar9170_usb_alloc_rx_bulk_urbs(struct ar9170_usb *aru)
+{
+       struct urb *urb;
+       int i;
+       int err = -EINVAL;
+
+       for (i = 0; i < AR9170_NUM_RX_URBS; i++) {
+               err = -ENOMEM;
+               urb = usb_alloc_urb(0, GFP_KERNEL);
+               if (!urb)
+                       goto err_out;
+
+               err = ar9170_usb_prep_rx_urb(aru, urb, GFP_KERNEL);
+               if (err) {
+                       usb_free_urb(urb);
+                       goto err_out;
+               }
+
+               usb_anchor_urb(urb, &aru->rx_submitted);
+               err = usb_submit_urb(urb, GFP_KERNEL);
+               if (err) {
+                       usb_unanchor_urb(urb);
+                       dev_kfree_skb_any((void *) urb->transfer_buffer);
+                       usb_free_urb(urb);
+                       goto err_out;
+               }
+               usb_free_urb(urb);
+       }
+
+       /* the device now waiting for a firmware. */
+       aru->common.state = AR9170_IDLE;
+       return 0;
+
+err_out:
+
+       usb_kill_anchored_urbs(&aru->rx_submitted);
+       return err;
+}
+
+static int ar9170_usb_flush(struct ar9170 *ar)
+{
+       struct ar9170_usb *aru = (void *) ar;
+       struct urb *urb;
+       int ret, err = 0;
+
+       if (IS_STARTED(ar))
+               aru->common.state = AR9170_IDLE;
+
+       usb_wait_anchor_empty_timeout(&aru->tx_pending,
+                                           msecs_to_jiffies(800));
+       while ((urb = usb_get_from_anchor(&aru->tx_pending))) {
+               ar9170_tx_callback(&aru->common, (void *) urb->context);
+               usb_free_urb(urb);
+       }
+
+       /* lets wait a while until the tx - queues are dried out */
+       ret = usb_wait_anchor_empty_timeout(&aru->tx_submitted,
+                                           msecs_to_jiffies(100));
+       if (ret == 0)
+               err = -ETIMEDOUT;
+
+       usb_kill_anchored_urbs(&aru->tx_submitted);
+
+       if (IS_ACCEPTING_CMD(ar))
+               aru->common.state = AR9170_STARTED;
+
+       return err;
+}
+
+static void ar9170_usb_cancel_urbs(struct ar9170_usb *aru)
+{
+       int err;
+
+       aru->common.state = AR9170_UNKNOWN_STATE;
+
+       err = ar9170_usb_flush(&aru->common);
+       if (err)
+               dev_err(&aru->udev->dev, "stuck tx urbs!\n");
+
+       usb_poison_anchored_urbs(&aru->tx_submitted);
+       usb_poison_anchored_urbs(&aru->rx_submitted);
+}
+
+static int ar9170_usb_exec_cmd(struct ar9170 *ar, enum ar9170_cmd cmd,
+                              unsigned int plen, void *payload,
+                              unsigned int outlen, void *out)
+{
+       struct ar9170_usb *aru = (void *) ar;
+       struct urb *urb = NULL;
+       unsigned long flags;
+       int err = -ENOMEM;
+
+       if (unlikely(!IS_ACCEPTING_CMD(ar)))
+               return -EPERM;
+
+       if (WARN_ON(plen > AR9170_MAX_CMD_LEN - 4))
+               return -EINVAL;
+
+       urb = usb_alloc_urb(0, GFP_ATOMIC);
+       if (unlikely(!urb))
+               goto err_free;
+
+       ar->cmdbuf[0] = cpu_to_le32(plen);
+       ar->cmdbuf[0] |= cpu_to_le32(cmd << 8);
+       /* writing multiple regs fills this buffer already */
+       if (plen && payload != (u8 *)(&ar->cmdbuf[1]))
+               memcpy(&ar->cmdbuf[1], payload, plen);
+
+       spin_lock_irqsave(&aru->common.cmdlock, flags);
+       aru->readbuf = (u8 *)out;
+       aru->readlen = outlen;
+       spin_unlock_irqrestore(&aru->common.cmdlock, flags);
+
+       usb_fill_int_urb(urb, aru->udev,
+                        usb_sndbulkpipe(aru->udev, AR9170_EP_CMD),
+                        aru->common.cmdbuf, plen + 4,
+                        ar9170_usb_tx_urb_complete, NULL, 1);
+
+       usb_anchor_urb(urb, &aru->tx_submitted);
+       err = usb_submit_urb(urb, GFP_ATOMIC);
+       if (unlikely(err)) {
+               usb_unanchor_urb(urb);
+               usb_free_urb(urb);
+               goto err_unbuf;
+       }
+       usb_free_urb(urb);
+
+       err = wait_for_completion_timeout(&aru->cmd_wait, HZ);
+       if (err == 0) {
+               err = -ETIMEDOUT;
+               goto err_unbuf;
+       }
+
+       if (aru->readlen != outlen) {
+               err = -EMSGSIZE;
+               goto err_unbuf;
+       }
+
+       return 0;
+
+err_unbuf:
+       /* Maybe the device was removed in the second we were waiting? */
+       if (IS_STARTED(ar)) {
+               dev_err(&aru->udev->dev, "no command feedback "
+                                        "received (%d).\n", err);
+
+               /* provide some maybe useful debug information */
+               print_hex_dump_bytes("ar9170 cmd: ", DUMP_PREFIX_NONE,
+                                    aru->common.cmdbuf, plen + 4);
+               dump_stack();
+       }
+
+       /* invalidate to avoid completing the next prematurely */
+       spin_lock_irqsave(&aru->common.cmdlock, flags);
+       aru->readbuf = NULL;
+       aru->readlen = 0;
+       spin_unlock_irqrestore(&aru->common.cmdlock, flags);
+
+err_free:
+
+       return err;
+}
+
+static int ar9170_usb_tx(struct ar9170 *ar, struct sk_buff *skb)
+{
+       struct ar9170_usb *aru = (struct ar9170_usb *) ar;
+       struct urb *urb;
+
+       if (unlikely(!IS_STARTED(ar))) {
+               /* Seriously, what were you drink... err... thinking!? */
+               return -EPERM;
+       }
+
+       urb = usb_alloc_urb(0, GFP_ATOMIC);
+       if (unlikely(!urb))
+               return -ENOMEM;
+
+       usb_fill_bulk_urb(urb, aru->udev,
+                         usb_sndbulkpipe(aru->udev, AR9170_EP_TX),
+                         skb->data, skb->len,
+                         ar9170_usb_tx_urb_complete_frame, skb);
+       urb->transfer_flags |= URB_ZERO_PACKET;
+
+       usb_anchor_urb(urb, &aru->tx_pending);
+       aru->tx_pending_urbs++;
+
+       usb_free_urb(urb);
+
+       ar9170_usb_submit_urb(aru);
+       return 0;
+}
+
+static void ar9170_usb_callback_cmd(struct ar9170 *ar, u32 len , void *buffer)
+{
+       struct ar9170_usb *aru = (void *) ar;
+       unsigned long flags;
+       u32 in, out;
+
+       if (unlikely(!buffer))
+               return ;
+
+       in = le32_to_cpup((__le32 *)buffer);
+       out = le32_to_cpu(ar->cmdbuf[0]);
+
+       /* mask off length byte */
+       out &= ~0xFF;
+
+       if (aru->readlen >= 0) {
+               /* add expected length */
+               out |= aru->readlen;
+       } else {
+               /* add obtained length */
+               out |= in & 0xFF;
+       }
+
+       /*
+        * Some commands (e.g: AR9170_CMD_FREQUENCY) have a variable response
+        * length and we cannot predict the correct length in advance.
+        * So we only check if we provided enough space for the data.
+        */
+       if (unlikely(out < in)) {
+               dev_warn(&aru->udev->dev, "received invalid command response "
+                                         "got %d bytes, instead of %d bytes "
+                                         "and the resp length is %d bytes\n",
+                        in, out, len);
+               print_hex_dump_bytes("ar9170 invalid resp: ",
+                                    DUMP_PREFIX_OFFSET, buffer, len);
+               /*
+                * Do not complete, then the command times out,
+                * and we get a stack trace from there.
+                */
+               return ;
+       }
+
+       spin_lock_irqsave(&aru->common.cmdlock, flags);
+       if (aru->readbuf && len > 0) {
+               memcpy(aru->readbuf, buffer + 4, len - 4);
+               aru->readbuf = NULL;
+       }
+       complete(&aru->cmd_wait);
+       spin_unlock_irqrestore(&aru->common.cmdlock, flags);
+}
+
+static int ar9170_usb_upload(struct ar9170_usb *aru, const void *data,
+                            size_t len, u32 addr, bool complete)
+{
+       int transfer, err;
+       u8 *buf = kmalloc(4096, GFP_KERNEL);
+
+       if (!buf)
+               return -ENOMEM;
+
+       while (len) {
+               transfer = min_t(int, len, 4096);
+               memcpy(buf, data, transfer);
+
+               err = usb_control_msg(aru->udev, usb_sndctrlpipe(aru->udev, 0),
+                                     0x30 /* FW DL */, 0x40 | USB_DIR_OUT,
+                                     addr >> 8, 0, buf, transfer, 1000);
+
+               if (err < 0) {
+                       kfree(buf);
+                       return err;
+               }
+
+               len -= transfer;
+               data += transfer;
+               addr += transfer;
+       }
+       kfree(buf);
+
+       if (complete) {
+               err = usb_control_msg(aru->udev, usb_sndctrlpipe(aru->udev, 0),
+                                     0x31 /* FW DL COMPLETE */,
+                                     0x40 | USB_DIR_OUT, 0, 0, NULL, 0, 5000);
+       }
+
+       return 0;
+}
+
+static int ar9170_usb_request_firmware(struct ar9170_usb *aru)
+{
+       int err = 0;
+
+       err = request_firmware(&aru->firmware, "ar9170.fw",
+                              &aru->udev->dev);
+       if (!err) {
+               aru->init_values = NULL;
+               return 0;
+       }
+
+       if (aru->req_one_stage_fw) {
+               dev_err(&aru->udev->dev, "ar9170.fw firmware file "
+                       "not found and is required for this device\n");
+               return -EINVAL;
+       }
+
+       dev_err(&aru->udev->dev, "ar9170.fw firmware file "
+               "not found, trying old firmware...\n");
+
+       err = request_firmware(&aru->init_values, "ar9170-1.fw",
+                              &aru->udev->dev);
+
+       err = request_firmware(&aru->firmware, "ar9170-2.fw", &aru->udev->dev);
+       if (err) {
+               release_firmware(aru->init_values);
+               dev_err(&aru->udev->dev, "file with init values not found.\n");
+               return err;
+       }
+
+       return err;
+}
+
+static int ar9170_usb_reset(struct ar9170_usb *aru)
+{
+       int ret, lock = (aru->intf->condition != USB_INTERFACE_BINDING);
+
+       if (lock) {
+               ret = usb_lock_device_for_reset(aru->udev, aru->intf);
+               if (ret < 0) {
+                       dev_err(&aru->udev->dev, "unable to lock device "
+                               "for reset (%d).\n", ret);
+                       return ret;
+               }
+       }
+
+       ret = usb_reset_device(aru->udev);
+       if (lock)
+               usb_unlock_device(aru->udev);
+
+       /* let it rest - for a second - */
+       msleep(1000);
+
+       return ret;
+}
+
+static int ar9170_usb_upload_firmware(struct ar9170_usb *aru)
+{
+       int err;
+
+       if (!aru->init_values)
+               goto upload_fw_start;
+
+       /* First, upload initial values to device RAM */
+       err = ar9170_usb_upload(aru, aru->init_values->data,
+                               aru->init_values->size, 0x102800, false);
+       if (err) {
+               dev_err(&aru->udev->dev, "firmware part 1 "
+                       "upload failed (%d).\n", err);
+               return err;
+       }
+
+upload_fw_start:
+
+       /* Then, upload the firmware itself and start it */
+       return ar9170_usb_upload(aru, aru->firmware->data, aru->firmware->size,
+                               0x200000, true);
+}
+
+static int ar9170_usb_init_transport(struct ar9170_usb *aru)
+{
+       struct ar9170 *ar = (void *) &aru->common;
+       int err;
+
+       ar9170_regwrite_begin(ar);
+
+       /* Set USB Rx stream mode MAX packet number to 2 */
+       ar9170_regwrite(AR9170_USB_REG_MAX_AGG_UPLOAD, 0x4);
+
+       /* Set USB Rx stream mode timeout to 10us */
+       ar9170_regwrite(AR9170_USB_REG_UPLOAD_TIME_CTL, 0x80);
+
+       ar9170_regwrite_finish();
+
+       err = ar9170_regwrite_result();
+       if (err)
+               dev_err(&aru->udev->dev, "USB setup failed (%d).\n", err);
+
+       return err;
+}
+
+static void ar9170_usb_stop(struct ar9170 *ar)
+{
+       struct ar9170_usb *aru = (void *) ar;
+       int ret;
+
+       if (IS_ACCEPTING_CMD(ar))
+               aru->common.state = AR9170_STOPPED;
+
+       ret = ar9170_usb_flush(ar);
+       if (ret)
+               dev_err(&aru->udev->dev, "kill pending tx urbs.\n");
+
+       usb_poison_anchored_urbs(&aru->tx_submitted);
+
+       /*
+        * Note:
+        * So far we freed all tx urbs, but we won't dare to touch any rx urbs.
+        * Else we would end up with a unresponsive device...
+        */
+}
+
+static int ar9170_usb_open(struct ar9170 *ar)
+{
+       struct ar9170_usb *aru = (void *) ar;
+       int err;
+
+       usb_unpoison_anchored_urbs(&aru->tx_submitted);
+       err = ar9170_usb_init_transport(aru);
+       if (err) {
+               usb_poison_anchored_urbs(&aru->tx_submitted);
+               return err;
+       }
+
+       aru->common.state = AR9170_IDLE;
+       return 0;
+}
+
+static int ar9170_usb_init_device(struct ar9170_usb *aru)
+{
+       int err;
+
+       err = ar9170_usb_alloc_rx_irq_urb(aru);
+       if (err)
+               goto err_out;
+
+       err = ar9170_usb_alloc_rx_bulk_urbs(aru);
+       if (err)
+               goto err_unrx;
+
+       err = ar9170_usb_upload_firmware(aru);
+       if (err) {
+               err = ar9170_echo_test(&aru->common, 0x60d43110);
+               if (err) {
+                       /* force user invention, by disabling the device */
+                       err = usb_driver_set_configuration(aru->udev, -1);
+                       dev_err(&aru->udev->dev, "device is in a bad state. "
+                                                "please reconnect it!\n");
+                       goto err_unrx;
+               }
+       }
+
+       return 0;
+
+err_unrx:
+       ar9170_usb_cancel_urbs(aru);
+
+err_out:
+       return err;
+}
+
+static bool ar9170_requires_one_stage(const struct usb_device_id *id)
+{
+       if (!id->driver_info)
+               return false;
+       if (id->driver_info == AR9170_REQ_FW1_ONLY)
+               return true;
+       return false;
+}
+
+static int ar9170_usb_probe(struct usb_interface *intf,
+                       const struct usb_device_id *id)
+{
+       struct ar9170_usb *aru;
+       struct ar9170 *ar;
+       struct usb_device *udev;
+       int err;
+
+       aru = ar9170_alloc(sizeof(*aru));
+       if (IS_ERR(aru)) {
+               err = PTR_ERR(aru);
+               goto out;
+       }
+
+       udev = interface_to_usbdev(intf);
+       usb_get_dev(udev);
+       aru->udev = udev;
+       aru->intf = intf;
+       ar = &aru->common;
+
+       aru->req_one_stage_fw = ar9170_requires_one_stage(id);
+
+       usb_set_intfdata(intf, aru);
+       SET_IEEE80211_DEV(ar->hw, &udev->dev);
+
+       init_usb_anchor(&aru->rx_submitted);
+       init_usb_anchor(&aru->tx_pending);
+       init_usb_anchor(&aru->tx_submitted);
+       init_completion(&aru->cmd_wait);
+       spin_lock_init(&aru->tx_urb_lock);
+
+       aru->tx_pending_urbs = 0;
+       aru->tx_submitted_urbs = 0;
+
+       aru->common.stop = ar9170_usb_stop;
+       aru->common.flush = ar9170_usb_flush;
+       aru->common.open = ar9170_usb_open;
+       aru->common.tx = ar9170_usb_tx;
+       aru->common.exec_cmd = ar9170_usb_exec_cmd;
+       aru->common.callback_cmd = ar9170_usb_callback_cmd;
+
+#ifdef CONFIG_PM
+       udev->reset_resume = 1;
+#endif /* CONFIG_PM */
+       err = ar9170_usb_reset(aru);
+       if (err)
+               goto err_freehw;
+
+       err = ar9170_usb_request_firmware(aru);
+       if (err)
+               goto err_freehw;
+
+       err = ar9170_usb_init_device(aru);
+       if (err)
+               goto err_freefw;
+
+       err = ar9170_usb_open(ar);
+       if (err)
+               goto err_unrx;
+
+       err = ar9170_register(ar, &udev->dev);
+
+       ar9170_usb_stop(ar);
+       if (err)
+               goto err_unrx;
+
+       return 0;
+
+err_unrx:
+       ar9170_usb_cancel_urbs(aru);
+
+err_freefw:
+       release_firmware(aru->init_values);
+       release_firmware(aru->firmware);
+
+err_freehw:
+       usb_set_intfdata(intf, NULL);
+       usb_put_dev(udev);
+       ieee80211_free_hw(ar->hw);
+out:
+       return err;
+}
+
+static void ar9170_usb_disconnect(struct usb_interface *intf)
+{
+       struct ar9170_usb *aru = usb_get_intfdata(intf);
+
+       if (!aru)
+               return;
+
+       aru->common.state = AR9170_IDLE;
+       ar9170_unregister(&aru->common);
+       ar9170_usb_cancel_urbs(aru);
+
+       release_firmware(aru->init_values);
+       release_firmware(aru->firmware);
+
+       usb_put_dev(aru->udev);
+       usb_set_intfdata(intf, NULL);
+       ieee80211_free_hw(aru->common.hw);
+}
+
+#ifdef CONFIG_PM
+static int ar9170_suspend(struct usb_interface *intf,
+                         pm_message_t  message)
+{
+       struct ar9170_usb *aru = usb_get_intfdata(intf);
+
+       if (!aru)
+               return -ENODEV;
+
+       aru->common.state = AR9170_IDLE;
+       ar9170_usb_cancel_urbs(aru);
+
+       return 0;
+}
+
+static int ar9170_resume(struct usb_interface *intf)
+{
+       struct ar9170_usb *aru = usb_get_intfdata(intf);
+       int err;
+
+       if (!aru)
+               return -ENODEV;
+
+       usb_unpoison_anchored_urbs(&aru->rx_submitted);
+       usb_unpoison_anchored_urbs(&aru->tx_submitted);
+
+       err = ar9170_usb_init_device(aru);
+       if (err)
+               goto err_unrx;
+
+       err = ar9170_usb_open(&aru->common);
+       if (err)
+               goto err_unrx;
+
+       return 0;
+
+err_unrx:
+       aru->common.state = AR9170_IDLE;
+       ar9170_usb_cancel_urbs(aru);
+
+       return err;
+}
+#endif /* CONFIG_PM */
+
+static struct usb_driver ar9170_driver = {
+       .name = "ar9170usb",
+       .probe = ar9170_usb_probe,
+       .disconnect = ar9170_usb_disconnect,
+       .id_table = ar9170_usb_ids,
+       .soft_unbind = 1,
+#ifdef CONFIG_PM
+       .suspend = ar9170_suspend,
+       .resume = ar9170_resume,
+       .reset_resume = ar9170_resume,
+#endif /* CONFIG_PM */
+};
+
+static int __init ar9170_init(void)
+{
+       return usb_register(&ar9170_driver);
+}
+
+static void __exit ar9170_exit(void)
+{
+       usb_deregister(&ar9170_driver);
+}
+
+module_init(ar9170_init);
+module_exit(ar9170_exit);
diff --git a/drivers/net/wireless/ath/ar9170/usb.h b/drivers/net/wireless/ath/ar9170/usb.h
new file mode 100644 (file)
index 0000000..d098f4d
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Atheros AR9170 USB driver
+ *
+ * Driver specific definitions
+ *
+ * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
+ * Copyright 2009, Christian Lamparter <chunkeey@web.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.
+ *
+ * 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; see the file COPYING.  If not, see
+ * http://www.gnu.org/licenses/.
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ *    Copyright (c) 2007-2008 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 __USB_H
+#define __USB_H
+
+#include <linux/usb.h>
+#include <linux/completion.h>
+#include <linux/spinlock.h>
+#include <linux/leds.h>
+#include <net/cfg80211.h>
+#include <net/mac80211.h>
+#include <linux/firmware.h>
+#include "eeprom.h"
+#include "hw.h"
+#include "ar9170.h"
+
+#define AR9170_NUM_RX_URBS                     16
+#define AR9170_NUM_TX_URBS                     8
+
+struct firmware;
+
+struct ar9170_usb {
+       struct ar9170 common;
+       struct usb_device *udev;
+       struct usb_interface *intf;
+
+       struct usb_anchor rx_submitted;
+       struct usb_anchor tx_pending;
+       struct usb_anchor tx_submitted;
+
+       bool req_one_stage_fw;
+
+       spinlock_t tx_urb_lock;
+       unsigned int tx_submitted_urbs;
+       unsigned int tx_pending_urbs;
+
+       struct completion cmd_wait;
+       int readlen;
+       u8 *readbuf;
+
+       const struct firmware *init_values;
+       const struct firmware *firmware;
+};
+
+#endif /* __USB_H */
diff --git a/drivers/net/wireless/ath/ath5k/Kconfig b/drivers/net/wireless/ath/ath5k/Kconfig
new file mode 100644 (file)
index 0000000..509b6f9
--- /dev/null
@@ -0,0 +1,41 @@
+config ATH5K
+       tristate "Atheros 5xxx wireless cards support"
+       depends on PCI && MAC80211 && WLAN_80211 && EXPERIMENTAL
+       select ATH_COMMON
+       select MAC80211_LEDS
+       select LEDS_CLASS
+       select NEW_LEDS
+       ---help---
+         This module adds support for wireless adapters based on
+         Atheros 5xxx chipset.
+
+         Currently the following chip versions are supported:
+
+         MAC: AR5211 AR5212
+         PHY: RF5111/2111 RF5112/2112 RF5413/2413
+
+         This driver uses the kernel's mac80211 subsystem.
+
+         If you choose to build a module, it'll be called ath5k. Say M if
+         unsure.
+
+config ATH5K_DEBUG
+       bool "Atheros 5xxx debugging"
+       depends on ATH5K
+       ---help---
+         Atheros 5xxx debugging messages.
+
+         Say Y, if and you will get debug options for ath5k.
+         To use this, you need to mount debugfs:
+
+         mkdir /debug/
+         mount -t debugfs debug /debug/
+
+         You will get access to files under:
+         /debug/ath5k/phy0/
+
+         To enable debug, pass the debug level to the debug module
+         parameter. For example:
+
+         modprobe ath5k debug=0x00000400
+
diff --git a/drivers/net/wireless/ath/ath5k/Makefile b/drivers/net/wireless/ath/ath5k/Makefile
new file mode 100644 (file)
index 0000000..090dc6d
--- /dev/null
@@ -0,0 +1,16 @@
+ath5k-y                                += caps.o
+ath5k-y                                += initvals.o
+ath5k-y                                += eeprom.o
+ath5k-y                                += gpio.o
+ath5k-y                                += desc.o
+ath5k-y                                += dma.o
+ath5k-y                                += qcu.o
+ath5k-y                                += pcu.o
+ath5k-y                                += phy.o
+ath5k-y                                += reset.o
+ath5k-y                                += attach.o
+ath5k-y                                += base.o
+ath5k-y                                += led.o
+ath5k-y                                += rfkill.o
+ath5k-$(CONFIG_ATH5K_DEBUG)    += debug.o
+obj-$(CONFIG_ATH5K)            += ath5k.o
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
new file mode 100644 (file)
index 0000000..6358233
--- /dev/null
@@ -0,0 +1,1379 @@
+/*
+ * Copyright (c) 2004-2007 Reyk Floeter <reyk@openbsd.org>
+ * Copyright (c) 2006-2007 Nick Kossifidis <mickflemm@gmail.com>
+ *
+ * Permission to use, copy, modify, and 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 _ATH5K_H
+#define _ATH5K_H
+
+/* TODO: Clean up channel debuging -doesn't work anyway- and start
+ * working on reg. control code using all available eeprom information
+ * -rev. engineering needed- */
+#define CHAN_DEBUG     0
+
+#include <linux/io.h>
+#include <linux/types.h>
+#include <net/mac80211.h>
+
+#include "../regd.h"
+
+/* RX/TX descriptor hw structs
+ * TODO: Driver part should only see sw structs */
+#include "desc.h"
+
+/* EEPROM structs/offsets
+ * TODO: Make a more generic struct (eg. add more stuff to ath5k_capabilities)
+ * and clean up common bits, then introduce set/get functions in eeprom.c */
+#include "eeprom.h"
+
+/* PCI IDs */
+#define PCI_DEVICE_ID_ATHEROS_AR5210           0x0007 /* AR5210 */
+#define PCI_DEVICE_ID_ATHEROS_AR5311           0x0011 /* AR5311 */
+#define PCI_DEVICE_ID_ATHEROS_AR5211           0x0012 /* AR5211 */
+#define PCI_DEVICE_ID_ATHEROS_AR5212           0x0013 /* AR5212 */
+#define PCI_DEVICE_ID_3COM_3CRDAG675           0x0013 /* 3CRDAG675 (Atheros AR5212) */
+#define PCI_DEVICE_ID_3COM_2_3CRPAG175                 0x0013 /* 3CRPAG175 (Atheros AR5212) */
+#define PCI_DEVICE_ID_ATHEROS_AR5210_AP        0x0207 /* AR5210 (Early) */
+#define PCI_DEVICE_ID_ATHEROS_AR5212_IBM       0x1014 /* AR5212 (IBM MiniPCI) */
+#define PCI_DEVICE_ID_ATHEROS_AR5210_DEFAULT   0x1107 /* AR5210 (no eeprom) */
+#define PCI_DEVICE_ID_ATHEROS_AR5212_DEFAULT   0x1113 /* AR5212 (no eeprom) */
+#define PCI_DEVICE_ID_ATHEROS_AR5211_DEFAULT   0x1112 /* AR5211 (no eeprom) */
+#define PCI_DEVICE_ID_ATHEROS_AR5212_FPGA      0xf013 /* AR5212 (emulation board) */
+#define PCI_DEVICE_ID_ATHEROS_AR5211_LEGACY    0xff12 /* AR5211 (emulation board) */
+#define PCI_DEVICE_ID_ATHEROS_AR5211_FPGA11B   0xf11b /* AR5211 (emulation board) */
+#define PCI_DEVICE_ID_ATHEROS_AR5312_REV2      0x0052 /* AR5312 WMAC (AP31) */
+#define PCI_DEVICE_ID_ATHEROS_AR5312_REV7      0x0057 /* AR5312 WMAC (AP30-040) */
+#define PCI_DEVICE_ID_ATHEROS_AR5312_REV8      0x0058 /* AR5312 WMAC (AP43-030) */
+#define PCI_DEVICE_ID_ATHEROS_AR5212_0014      0x0014 /* AR5212 compatible */
+#define PCI_DEVICE_ID_ATHEROS_AR5212_0015      0x0015 /* AR5212 compatible */
+#define PCI_DEVICE_ID_ATHEROS_AR5212_0016      0x0016 /* AR5212 compatible */
+#define PCI_DEVICE_ID_ATHEROS_AR5212_0017      0x0017 /* AR5212 compatible */
+#define PCI_DEVICE_ID_ATHEROS_AR5212_0018      0x0018 /* AR5212 compatible */
+#define PCI_DEVICE_ID_ATHEROS_AR5212_0019      0x0019 /* AR5212 compatible */
+#define PCI_DEVICE_ID_ATHEROS_AR2413           0x001a /* AR2413 (Griffin-lite) */
+#define PCI_DEVICE_ID_ATHEROS_AR5413           0x001b /* AR5413 (Eagle) */
+#define PCI_DEVICE_ID_ATHEROS_AR5424           0x001c /* AR5424 (Condor PCI-E) */
+#define PCI_DEVICE_ID_ATHEROS_AR5416           0x0023 /* AR5416 */
+#define PCI_DEVICE_ID_ATHEROS_AR5418           0x0024 /* AR5418 */
+
+/****************************\
+  GENERIC DRIVER DEFINITIONS
+\****************************/
+
+#define ATH5K_PRINTF(fmt, ...)   printk("%s: " fmt, __func__, ##__VA_ARGS__)
+
+#define ATH5K_PRINTK(_sc, _level, _fmt, ...) \
+       printk(_level "ath5k %s: " _fmt, \
+               ((_sc) && (_sc)->hw) ? wiphy_name((_sc)->hw->wiphy) : "", \
+               ##__VA_ARGS__)
+
+#define ATH5K_PRINTK_LIMIT(_sc, _level, _fmt, ...) do { \
+       if (net_ratelimit()) \
+               ATH5K_PRINTK(_sc, _level, _fmt, ##__VA_ARGS__); \
+       } while (0)
+
+#define ATH5K_INFO(_sc, _fmt, ...) \
+       ATH5K_PRINTK(_sc, KERN_INFO, _fmt, ##__VA_ARGS__)
+
+#define ATH5K_WARN(_sc, _fmt, ...) \
+       ATH5K_PRINTK_LIMIT(_sc, KERN_WARNING, _fmt, ##__VA_ARGS__)
+
+#define ATH5K_ERR(_sc, _fmt, ...) \
+       ATH5K_PRINTK_LIMIT(_sc, KERN_ERR, _fmt, ##__VA_ARGS__)
+
+/*
+ * AR5K REGISTER ACCESS
+ */
+
+/* Some macros to read/write fields */
+
+/* First shift, then mask */
+#define AR5K_REG_SM(_val, _flags)                                      \
+       (((_val) << _flags##_S) & (_flags))
+
+/* First mask, then shift */
+#define AR5K_REG_MS(_val, _flags)                                      \
+       (((_val) & (_flags)) >> _flags##_S)
+
+/* Some registers can hold multiple values of interest. For this
+ * reason when we want to write to these registers we must first
+ * retrieve the values which we do not want to clear (lets call this
+ * old_data) and then set the register with this and our new_value:
+ * ( old_data | new_value) */
+#define AR5K_REG_WRITE_BITS(ah, _reg, _flags, _val)                    \
+       ath5k_hw_reg_write(ah, (ath5k_hw_reg_read(ah, _reg) & ~(_flags)) | \
+           (((_val) << _flags##_S) & (_flags)), _reg)
+
+#define AR5K_REG_MASKED_BITS(ah, _reg, _flags, _mask)                  \
+       ath5k_hw_reg_write(ah, (ath5k_hw_reg_read(ah, _reg) &           \
+                       (_mask)) | (_flags), _reg)
+
+#define AR5K_REG_ENABLE_BITS(ah, _reg, _flags)                         \
+       ath5k_hw_reg_write(ah, ath5k_hw_reg_read(ah, _reg) | (_flags), _reg)
+
+#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_REG_WRITE_Q(ah, _reg, _queue)                             \
+       ath5k_hw_reg_write(ah, (1 << _queue), _reg)
+
+#define AR5K_Q_ENABLE_BITS(_reg, _queue) do {                          \
+       _reg |= 1 << _queue;                                            \
+} while (0)
+
+#define AR5K_Q_DISABLE_BITS(_reg, _queue) do {                         \
+       _reg &= ~(1 << _queue);                                         \
+} while (0)
+
+/* Used while writing initvals */
+#define AR5K_REG_WAIT(_i) do {                                         \
+       if (_i % 64)                                                    \
+               udelay(1);                                              \
+} while (0)
+
+/* Register dumps are done per operation mode */
+#define AR5K_INI_RFGAIN_5GHZ           0
+#define AR5K_INI_RFGAIN_2GHZ           1
+
+/* TODO: Clean this up */
+#define AR5K_INI_VAL_11A               0
+#define AR5K_INI_VAL_11A_TURBO         1
+#define AR5K_INI_VAL_11B               2
+#define AR5K_INI_VAL_11G               3
+#define AR5K_INI_VAL_11G_TURBO         4
+#define AR5K_INI_VAL_XR                        0
+#define AR5K_INI_VAL_MAX               5
+
+/* Used for BSSID etc manipulation */
+#define AR5K_LOW_ID(_a)(                               \
+(_a)[0] | (_a)[1] << 8 | (_a)[2] << 16 | (_a)[3] << 24 \
+)
+
+#define AR5K_HIGH_ID(_a)       ((_a)[4] | (_a)[5] << 8)
+
+/*
+ * Some tuneable values (these should be changeable by the user)
+ * TODO: Make use of them and add more options OR use debug/configfs
+ */
+#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_LEN / 64) + 1)
+#define AR5K_TUNE_REGISTER_TIMEOUT             20000
+/* Register for RSSI threshold has a mask of 0xff, so 255 seems to
+ * be the max value. */
+#define AR5K_TUNE_RSSI_THRES                   129
+/* This must be set when setting the RSSI threshold otherwise it can
+ * prevent a reset. If AR5K_RSSI_THR is read after writing to it
+ * the BMISS_THRES will be seen as 0, seems harware doesn't keep
+ * track of it. Max value depends on harware. For AR5210 this is just 7.
+ * For AR5211+ this seems to be up to 255. */
+#define AR5K_TUNE_BMISS_THRES                  7
+#define AR5K_TUNE_REGISTER_DWELL_TIME          20000
+#define AR5K_TUNE_BEACON_INTERVAL              100
+#define AR5K_TUNE_AIFS                         2
+#define AR5K_TUNE_AIFS_11B                     2
+#define AR5K_TUNE_AIFS_XR                      0
+#define AR5K_TUNE_CWMIN                                15
+#define AR5K_TUNE_CWMIN_11B                    31
+#define AR5K_TUNE_CWMIN_XR                     3
+#define AR5K_TUNE_CWMAX                                1023
+#define AR5K_TUNE_CWMAX_11B                    1023
+#define AR5K_TUNE_CWMAX_XR                     7
+#define AR5K_TUNE_NOISE_FLOOR                  -72
+#define AR5K_TUNE_MAX_TXPOWER                  63
+#define AR5K_TUNE_DEFAULT_TXPOWER              25
+#define AR5K_TUNE_TPC_TXPOWER                  false
+#define AR5K_TUNE_HWTXTRIES                    4
+
+#define AR5K_INIT_CARR_SENSE_EN                        1
+
+/*Swap RX/TX Descriptor for big endian archs*/
+#if defined(__BIG_ENDIAN)
+#define AR5K_INIT_CFG  (               \
+       AR5K_CFG_SWTD | AR5K_CFG_SWRD   \
+)
+#else
+#define AR5K_INIT_CFG  0x00000000
+#endif
+
+/* Initial values */
+#define        AR5K_INIT_CYCRSSI_THR1                  2
+#define AR5K_INIT_TX_LATENCY                   502
+#define AR5K_INIT_USEC                         39
+#define AR5K_INIT_USEC_TURBO                   79
+#define AR5K_INIT_USEC_32                      31
+#define AR5K_INIT_SLOT_TIME                    396
+#define AR5K_INIT_SLOT_TIME_TURBO              480
+#define AR5K_INIT_ACK_CTS_TIMEOUT              1024
+#define AR5K_INIT_ACK_CTS_TIMEOUT_TURBO                0x08000800
+#define AR5K_INIT_PROG_IFS                     920
+#define AR5K_INIT_PROG_IFS_TURBO               960
+#define AR5K_INIT_EIFS                         3440
+#define AR5K_INIT_EIFS_TURBO                   6880
+#define AR5K_INIT_SIFS                         560
+#define AR5K_INIT_SIFS_TURBO                   480
+#define AR5K_INIT_SH_RETRY                     10
+#define AR5K_INIT_LG_RETRY                     AR5K_INIT_SH_RETRY
+#define AR5K_INIT_SSH_RETRY                    32
+#define AR5K_INIT_SLG_RETRY                    AR5K_INIT_SSH_RETRY
+#define AR5K_INIT_TX_RETRY                     10
+
+#define AR5K_INIT_TRANSMIT_LATENCY             (                       \
+       (AR5K_INIT_TX_LATENCY << 14) | (AR5K_INIT_USEC_32 << 7) |       \
+       (AR5K_INIT_USEC)                                                \
+)
+#define AR5K_INIT_TRANSMIT_LATENCY_TURBO       (                       \
+       (AR5K_INIT_TX_LATENCY << 14) | (AR5K_INIT_USEC_32 << 7) |       \
+       (AR5K_INIT_USEC_TURBO)                                          \
+)
+#define AR5K_INIT_PROTO_TIME_CNTRL             (                       \
+       (AR5K_INIT_CARR_SENSE_EN << 26) | (AR5K_INIT_EIFS << 12) |      \
+       (AR5K_INIT_PROG_IFS)                                            \
+)
+#define AR5K_INIT_PROTO_TIME_CNTRL_TURBO       (                       \
+       (AR5K_INIT_CARR_SENSE_EN << 26) | (AR5K_INIT_EIFS_TURBO << 12) | \
+       (AR5K_INIT_PROG_IFS_TURBO)                                      \
+)
+
+/* token to use for aifs, cwmin, cwmax in MadWiFi */
+#define        AR5K_TXQ_USEDEFAULT     ((u32) -1)
+
+/* GENERIC CHIPSET DEFINITIONS */
+
+/* MAC Chips */
+enum ath5k_version {
+       AR5K_AR5210     = 0,
+       AR5K_AR5211     = 1,
+       AR5K_AR5212     = 2,
+};
+
+/* PHY Chips */
+enum ath5k_radio {
+       AR5K_RF5110     = 0,
+       AR5K_RF5111     = 1,
+       AR5K_RF5112     = 2,
+       AR5K_RF2413     = 3,
+       AR5K_RF5413     = 4,
+       AR5K_RF2316     = 5,
+       AR5K_RF2317     = 6,
+       AR5K_RF2425     = 7,
+};
+
+/*
+ * 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 */
+#define AR5K_SREV_AR5311       0x10 /* Maui 1 */
+#define AR5K_SREV_AR5311A      0x20 /* Maui 2 */
+#define AR5K_SREV_AR5311B      0x30 /* Spirit */
+#define AR5K_SREV_AR5211       0x40 /* Oahu */
+#define AR5K_SREV_AR5212       0x50 /* Venice */
+#define AR5K_SREV_AR5213       0x55 /* ??? */
+#define AR5K_SREV_AR5213A      0x59 /* Hainan */
+#define AR5K_SREV_AR2413       0x78 /* Griffin lite */
+#define AR5K_SREV_AR2414       0x70 /* Griffin */
+#define AR5K_SREV_AR5424       0x90 /* Condor */
+#define AR5K_SREV_AR5413       0xa4 /* Eagle lite */
+#define AR5K_SREV_AR5414       0xa0 /* Eagle */
+#define AR5K_SREV_AR2415       0xb0 /* Talon */
+#define AR5K_SREV_AR5416       0xc0 /* PCI-E */
+#define AR5K_SREV_AR5418       0xca /* PCI-E */
+#define AR5K_SREV_AR2425       0xe0 /* Swan */
+#define AR5K_SREV_AR2417       0xf0 /* Nala */
+
+#define AR5K_SREV_RAD_5110     0x00
+#define AR5K_SREV_RAD_5111     0x10
+#define AR5K_SREV_RAD_5111A    0x15
+#define AR5K_SREV_RAD_2111     0x20
+#define AR5K_SREV_RAD_5112     0x30
+#define AR5K_SREV_RAD_5112A    0x35
+#define        AR5K_SREV_RAD_5112B     0x36
+#define AR5K_SREV_RAD_2112     0x40
+#define AR5K_SREV_RAD_2112A    0x45
+#define        AR5K_SREV_RAD_2112B     0x46
+#define AR5K_SREV_RAD_2413     0x50
+#define AR5K_SREV_RAD_5413     0x60
+#define AR5K_SREV_RAD_2316     0x70 /* Cobra SoC */
+#define AR5K_SREV_RAD_2317     0x80
+#define AR5K_SREV_RAD_5424     0xa0 /* Mostly same as 5413 */
+#define AR5K_SREV_RAD_2425     0xa2
+#define AR5K_SREV_RAD_5133     0xc0
+
+#define AR5K_SREV_PHY_5211     0x30
+#define AR5K_SREV_PHY_5212     0x41
+#define        AR5K_SREV_PHY_5212A     0x42
+#define AR5K_SREV_PHY_5212B    0x43
+#define AR5K_SREV_PHY_2413     0x45
+#define AR5K_SREV_PHY_5413     0x61
+#define AR5K_SREV_PHY_2425     0x70
+
+/* IEEE defs */
+#define IEEE80211_MAX_LEN       2500
+
+/* TODO add support to mac80211 for vendor-specific rates and modes */
+
+/*
+ * Some of this information is based on Documentation from:
+ *
+ * http://madwifi.org/wiki/ChipsetFeatures/SuperAG
+ *
+ * Modulation for Atheros' eXtended Range - range enhancing extension that is
+ * supposed to double the distance an Atheros client device can keep a
+ * connection with an Atheros access point. This is achieved by increasing
+ * the receiver sensitivity up to, -105dBm, which is about 20dB above what
+ * the 802.11 specifications demand. In addition, new (proprietary) data rates
+ * are introduced: 3, 2, 1, 0.5 and 0.25 MBit/s.
+ *
+ * Please note that can you either use XR or TURBO but you cannot use both,
+ * they are exclusive.
+ *
+ */
+#define MODULATION_XR          0x00000200
+/*
+ * Modulation for Atheros' Turbo G and Turbo A, its supposed to provide a
+ * throughput transmission speed up to 40Mbit/s-60Mbit/s at a 108Mbit/s
+ * signaling rate achieved through the bonding of two 54Mbit/s 802.11g
+ * channels. To use this feature your Access Point must also suport it.
+ * There is also a distinction between "static" and "dynamic" turbo modes:
+ *
+ * - Static: is the dumb version: devices set to this mode stick to it until
+ *     the mode is turned off.
+ * - Dynamic: is the intelligent version, the network decides itself if it
+ *     is ok to use turbo. As soon as traffic is detected on adjacent channels
+ *     (which would get used in turbo mode), or when a non-turbo station joins
+ *     the network, turbo mode won't be used until the situation changes again.
+ *     Dynamic mode is achieved by Atheros' Adaptive Radio (AR) feature which
+ *     monitors the used radio band in order to decide whether turbo mode may
+ *     be used or not.
+ *
+ * This article claims Super G sticks to bonding of channels 5 and 6 for
+ * USA:
+ *
+ * http://www.pcworld.com/article/id,113428-page,1/article.html
+ *
+ * The channel bonding seems to be driver specific though. In addition to
+ * deciding what channels will be used, these "Turbo" modes are accomplished
+ * by also enabling the following features:
+ *
+ * - Bursting: allows multiple frames to be sent at once, rather than pausing
+ *     after each frame. Bursting is a standards-compliant feature that can be
+ *     used with any Access Point.
+ * - Fast frames: increases the amount of information that can be sent per
+ *     frame, also resulting in a reduction of transmission overhead. It is a
+ *     proprietary feature that needs to be supported by the Access Point.
+ * - Compression: data frames are compressed in real time using a Lempel Ziv
+ *     algorithm. This is done transparently. Once this feature is enabled,
+ *     compression and decompression takes place inside the chipset, without
+ *     putting additional load on the host CPU.
+ *
+ */
+#define MODULATION_TURBO       0x00000080
+
+enum ath5k_driver_mode {
+       AR5K_MODE_11A           =       0,
+       AR5K_MODE_11A_TURBO     =       1,
+       AR5K_MODE_11B           =       2,
+       AR5K_MODE_11G           =       3,
+       AR5K_MODE_11G_TURBO     =       4,
+       AR5K_MODE_XR            =       0,
+       AR5K_MODE_MAX           =       5
+};
+
+enum ath5k_ant_mode {
+       AR5K_ANTMODE_DEFAULT    = 0,    /* default antenna setup */
+       AR5K_ANTMODE_FIXED_A    = 1,    /* only antenna A is present */
+       AR5K_ANTMODE_FIXED_B    = 2,    /* only antenna B is present */
+       AR5K_ANTMODE_SINGLE_AP  = 3,    /* sta locked on a single ap */
+       AR5K_ANTMODE_SECTOR_AP  = 4,    /* AP with tx antenna set on tx desc */
+       AR5K_ANTMODE_SECTOR_STA = 5,    /* STA with tx antenna set on tx desc */
+       AR5K_ANTMODE_DEBUG      = 6,    /* Debug mode -A -> Rx, B-> Tx- */
+       AR5K_ANTMODE_MAX,
+};
+
+
+/****************\
+  TX DEFINITIONS
+\****************/
+
+/*
+ * TX Status descriptor
+ */
+struct ath5k_tx_status {
+       u16     ts_seqnum;
+       u16     ts_tstamp;
+       u8      ts_status;
+       u8      ts_rate[4];
+       u8      ts_retry[4];
+       u8      ts_final_idx;
+       s8      ts_rssi;
+       u8      ts_shortretry;
+       u8      ts_longretry;
+       u8      ts_virtcol;
+       u8      ts_antenna;
+};
+
+#define AR5K_TXSTAT_ALTRATE    0x80
+#define AR5K_TXERR_XRETRY      0x01
+#define AR5K_TXERR_FILT                0x02
+#define AR5K_TXERR_FIFO                0x04
+
+/**
+ * enum ath5k_tx_queue - Queue types used to classify tx queues.
+ * @AR5K_TX_QUEUE_INACTIVE: q is unused -- see ath5k_hw_release_tx_queue
+ * @AR5K_TX_QUEUE_DATA: A normal data queue
+ * @AR5K_TX_QUEUE_XR_DATA: An XR-data queue
+ * @AR5K_TX_QUEUE_BEACON: The beacon queue
+ * @AR5K_TX_QUEUE_CAB: The after-beacon queue
+ * @AR5K_TX_QUEUE_UAPSD: Unscheduled Automatic Power Save Delivery queue
+ */
+enum ath5k_tx_queue {
+       AR5K_TX_QUEUE_INACTIVE = 0,
+       AR5K_TX_QUEUE_DATA,
+       AR5K_TX_QUEUE_XR_DATA,
+       AR5K_TX_QUEUE_BEACON,
+       AR5K_TX_QUEUE_CAB,
+       AR5K_TX_QUEUE_UAPSD,
+};
+
+#define        AR5K_NUM_TX_QUEUES              10
+#define        AR5K_NUM_TX_QUEUES_NOQCU        2
+
+/*
+ * Queue syb-types to classify normal data queues.
+ * These are the 4 Access Categories as defined in
+ * WME spec. 0 is the lowest priority and 4 is the
+ * highest. Normal data that hasn't been classified
+ * goes to the Best Effort AC.
+ */
+enum ath5k_tx_queue_subtype {
+       AR5K_WME_AC_BK = 0,     /*Background traffic*/
+       AR5K_WME_AC_BE,         /*Best-effort (normal) traffic)*/
+       AR5K_WME_AC_VI,         /*Video traffic*/
+       AR5K_WME_AC_VO,         /*Voice traffic*/
+};
+
+/*
+ * Queue ID numbers as returned by the hw functions, each number
+ * represents a hw queue. If hw does not support hw queues
+ * (eg 5210) all data goes in one queue. These match
+ * d80211 definitions (net80211/MadWiFi don't use them).
+ */
+enum ath5k_tx_queue_id {
+       AR5K_TX_QUEUE_ID_NOQCU_DATA     = 0,
+       AR5K_TX_QUEUE_ID_NOQCU_BEACON   = 1,
+       AR5K_TX_QUEUE_ID_DATA_MIN       = 0, /*IEEE80211_TX_QUEUE_DATA0*/
+       AR5K_TX_QUEUE_ID_DATA_MAX       = 4, /*IEEE80211_TX_QUEUE_DATA4*/
+       AR5K_TX_QUEUE_ID_DATA_SVP       = 5, /*IEEE80211_TX_QUEUE_SVP - Spectralink Voice Protocol*/
+       AR5K_TX_QUEUE_ID_CAB            = 6, /*IEEE80211_TX_QUEUE_AFTER_BEACON*/
+       AR5K_TX_QUEUE_ID_BEACON         = 7, /*IEEE80211_TX_QUEUE_BEACON*/
+       AR5K_TX_QUEUE_ID_UAPSD          = 8,
+       AR5K_TX_QUEUE_ID_XR_DATA        = 9,
+};
+
+/*
+ * Flags to set hw queue's parameters...
+ */
+#define AR5K_TXQ_FLAG_TXOKINT_ENABLE           0x0001  /* Enable TXOK interrupt */
+#define AR5K_TXQ_FLAG_TXERRINT_ENABLE          0x0002  /* Enable TXERR interrupt */
+#define AR5K_TXQ_FLAG_TXEOLINT_ENABLE          0x0004  /* Enable TXEOL interrupt -not used- */
+#define AR5K_TXQ_FLAG_TXDESCINT_ENABLE         0x0008  /* Enable TXDESC interrupt -not used- */
+#define AR5K_TXQ_FLAG_TXURNINT_ENABLE          0x0010  /* Enable TXURN interrupt */
+#define AR5K_TXQ_FLAG_CBRORNINT_ENABLE         0x0020  /* Enable CBRORN interrupt */
+#define AR5K_TXQ_FLAG_CBRURNINT_ENABLE         0x0040  /* Enable CBRURN interrupt */
+#define AR5K_TXQ_FLAG_QTRIGINT_ENABLE          0x0080  /* Enable QTRIG interrupt */
+#define AR5K_TXQ_FLAG_TXNOFRMINT_ENABLE                0x0100  /* Enable TXNOFRM interrupt */
+#define AR5K_TXQ_FLAG_BACKOFF_DISABLE          0x0200  /* Disable random post-backoff */
+#define AR5K_TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE        0x0300  /* Enable ready time expiry policy (?)*/
+#define AR5K_TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE        0x0800  /* Enable backoff while bursting */
+#define AR5K_TXQ_FLAG_POST_FR_BKOFF_DIS                0x1000  /* Disable backoff while bursting */
+#define AR5K_TXQ_FLAG_COMPRESSION_ENABLE       0x2000  /* Enable hw compression -not implemented-*/
+
+/*
+ * A struct to hold tx queue's parameters
+ */
+struct ath5k_txq_info {
+       enum ath5k_tx_queue tqi_type;
+       enum ath5k_tx_queue_subtype tqi_subtype;
+       u16     tqi_flags;      /* Tx queue flags (see above) */
+       u32     tqi_aifs;       /* Arbitrated Interframe Space */
+       s32     tqi_cw_min;     /* Minimum Contention Window */
+       s32     tqi_cw_max;     /* Maximum Contention Window */
+       u32     tqi_cbr_period; /* Constant bit rate period */
+       u32     tqi_cbr_overflow_limit;
+       u32     tqi_burst_time;
+       u32     tqi_ready_time; /* Not used */
+};
+
+/*
+ * Transmit packet types.
+ * used on tx control descriptor
+ * TODO: Use them inside base.c corectly
+ */
+enum ath5k_pkt_type {
+       AR5K_PKT_TYPE_NORMAL            = 0,
+       AR5K_PKT_TYPE_ATIM              = 1,
+       AR5K_PKT_TYPE_PSPOLL            = 2,
+       AR5K_PKT_TYPE_BEACON            = 3,
+       AR5K_PKT_TYPE_PROBE_RESP        = 4,
+       AR5K_PKT_TYPE_PIFS              = 5,
+};
+
+/*
+ * TX power and TPC settings
+ */
+#define AR5K_TXPOWER_OFDM(_r, _v)      (                       \
+       ((0 & 1) << ((_v) + 6)) |                               \
+       (((ah->ah_txpower.txp_rates_power_table[(_r)]) & 0x3f) << (_v)) \
+)
+
+#define AR5K_TXPOWER_CCK(_r, _v)       (                       \
+       (ah->ah_txpower.txp_rates_power_table[(_r)] & 0x3f) << (_v)     \
+)
+
+/*
+ * DMA size definitions (2^n+2)
+ */
+enum ath5k_dmasize {
+       AR5K_DMASIZE_4B = 0,
+       AR5K_DMASIZE_8B,
+       AR5K_DMASIZE_16B,
+       AR5K_DMASIZE_32B,
+       AR5K_DMASIZE_64B,
+       AR5K_DMASIZE_128B,
+       AR5K_DMASIZE_256B,
+       AR5K_DMASIZE_512B
+};
+
+
+/****************\
+  RX DEFINITIONS
+\****************/
+
+/*
+ * RX Status descriptor
+ */
+struct ath5k_rx_status {
+       u16     rs_datalen;
+       u16     rs_tstamp;
+       u8      rs_status;
+       u8      rs_phyerr;
+       s8      rs_rssi;
+       u8      rs_keyix;
+       u8      rs_rate;
+       u8      rs_antenna;
+       u8      rs_more;
+};
+
+#define AR5K_RXERR_CRC         0x01
+#define AR5K_RXERR_PHY         0x02
+#define AR5K_RXERR_FIFO                0x04
+#define AR5K_RXERR_DECRYPT     0x08
+#define AR5K_RXERR_MIC         0x10
+#define AR5K_RXKEYIX_INVALID   ((u8) - 1)
+#define AR5K_TXKEYIX_INVALID   ((u32) - 1)
+
+
+/**************************\
+ BEACON TIMERS DEFINITIONS
+\**************************/
+
+#define AR5K_BEACON_PERIOD     0x0000ffff
+#define AR5K_BEACON_ENA                0x00800000 /*enable beacon xmit*/
+#define AR5K_BEACON_RESET_TSF  0x01000000 /*force a TSF reset*/
+
+#if 0
+/**
+ * struct ath5k_beacon_state - Per-station beacon timer state.
+ * @bs_interval: in TU's, can also include the above flags
+ * @bs_cfp_max_duration: if non-zero hw is setup to coexist with a
+ *     Point Coordination Function capable AP
+ */
+struct ath5k_beacon_state {
+       u32     bs_next_beacon;
+       u32     bs_next_dtim;
+       u32     bs_interval;
+       u8      bs_dtim_period;
+       u8      bs_cfp_period;
+       u16     bs_cfp_max_duration;
+       u16     bs_cfp_du_remain;
+       u16     bs_tim_offset;
+       u16     bs_sleep_duration;
+       u16     bs_bmiss_threshold;
+       u32     bs_cfp_next;
+};
+#endif
+
+
+/*
+ * TSF to TU conversion:
+ *
+ * TSF is a 64bit value in usec (microseconds).
+ * TU is a 32bit value and defined by IEEE802.11 (page 6) as "A measurement of
+ * time equal to 1024 usec", so it's roughly milliseconds (usec / 1024).
+ */
+#define TSF_TO_TU(_tsf) (u32)((_tsf) >> 10)
+
+
+/*******************************\
+  GAIN OPTIMIZATION DEFINITIONS
+\*******************************/
+
+enum ath5k_rfgain {
+       AR5K_RFGAIN_INACTIVE = 0,
+       AR5K_RFGAIN_ACTIVE,
+       AR5K_RFGAIN_READ_REQUESTED,
+       AR5K_RFGAIN_NEED_CHANGE,
+};
+
+struct ath5k_gain {
+       u8                      g_step_idx;
+       u8                      g_current;
+       u8                      g_target;
+       u8                      g_low;
+       u8                      g_high;
+       u8                      g_f_corr;
+       u8                      g_state;
+};
+
+/********************\
+  COMMON DEFINITIONS
+\********************/
+
+#define AR5K_SLOT_TIME_9       396
+#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_TURBO   0x0010  /* Turbo Channel */
+#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_T       (CHANNEL_5GHZ|CHANNEL_OFDM|CHANNEL_TURBO)
+#define        CHANNEL_TG      (CHANNEL_2GHZ|CHANNEL_OFDM|CHANNEL_TURBO)
+#define        CHANNEL_108A    CHANNEL_T
+#define        CHANNEL_108G    CHANNEL_TG
+#define        CHANNEL_X       (CHANNEL_5GHZ|CHANNEL_OFDM|CHANNEL_XR)
+
+#define        CHANNEL_ALL     (CHANNEL_OFDM|CHANNEL_CCK|CHANNEL_2GHZ|CHANNEL_5GHZ| \
+               CHANNEL_TURBO)
+
+#define        CHANNEL_ALL_NOTURBO     (CHANNEL_ALL & ~CHANNEL_TURBO)
+#define CHANNEL_MODES          CHANNEL_ALL
+
+/*
+ * Used internaly for 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.
+ * TODO: Clean up
+ */
+struct ath5k_athchan_2ghz {
+       u32     a2_flags;
+       u16     a2_athchan;
+};
+
+
+/******************\
+  RATE DEFINITIONS
+\******************/
+
+/**
+ * Seems the ar5xxx harware supports up to 32 rates, indexed by 1-32.
+ *
+ * The rate code is used to get the RX rate or set the TX rate on the
+ * hardware descriptors. It is also used for internal modulation control
+ * and settings.
+ *
+ * This is the hardware rate map we are aware of:
+ *
+ * rate_code   0x01    0x02    0x03    0x04    0x05    0x06    0x07    0x08
+ * rate_kbps   3000    1000    ?       ?       ?       2000    500     48000
+ *
+ * rate_code   0x09    0x0A    0x0B    0x0C    0x0D    0x0E    0x0F    0x10
+ * rate_kbps   24000   12000   6000    54000   36000   18000   9000    ?
+ *
+ * rate_code   17      18      19      20      21      22      23      24
+ * rate_kbps   ?       ?       ?       ?       ?       ?       ?       11000
+ *
+ * rate_code   25      26      27      28      29      30      31      32
+ * rate_kbps   5500    2000    1000    11000S  5500S   2000S   ?       ?
+ *
+ * "S" indicates CCK rates with short preamble.
+ *
+ * AR5211 has different rate codes for CCK (802.11B) rates. It only uses the
+ * lowest 4 bits, so they are the same as below with a 0xF mask.
+ * (0xB, 0xA, 0x9 and 0x8 for 1M, 2M, 5.5M and 11M).
+ * We handle this in ath5k_setup_bands().
+ */
+#define AR5K_MAX_RATES 32
+
+/* B */
+#define ATH5K_RATE_CODE_1M     0x1B
+#define ATH5K_RATE_CODE_2M     0x1A
+#define ATH5K_RATE_CODE_5_5M   0x19
+#define ATH5K_RATE_CODE_11M    0x18
+/* A and G */
+#define ATH5K_RATE_CODE_6M     0x0B
+#define ATH5K_RATE_CODE_9M     0x0F
+#define ATH5K_RATE_CODE_12M    0x0A
+#define ATH5K_RATE_CODE_18M    0x0E
+#define ATH5K_RATE_CODE_24M    0x09
+#define ATH5K_RATE_CODE_36M    0x0D
+#define ATH5K_RATE_CODE_48M    0x08
+#define ATH5K_RATE_CODE_54M    0x0C
+/* XR */
+#define ATH5K_RATE_CODE_XR_500K        0x07
+#define ATH5K_RATE_CODE_XR_1M  0x02
+#define ATH5K_RATE_CODE_XR_2M  0x06
+#define ATH5K_RATE_CODE_XR_3M  0x01
+
+/* adding this flag to rate_code enables short preamble */
+#define AR5K_SET_SHORT_PREAMBLE 0x04
+
+/*
+ * Crypto definitions
+ */
+
+#define AR5K_KEYCACHE_SIZE     8
+
+/***********************\
+ HW RELATED DEFINITIONS
+\***********************/
+
+/*
+ * Misc definitions
+ */
+#define        AR5K_RSSI_EP_MULTIPLIER (1<<7)
+
+#define AR5K_ASSERT_ENTRY(_e, _s) do {         \
+       if (_e >= _s)                           \
+               return (false);                 \
+} while (0)
+
+/*
+ * Hardware interrupt abstraction
+ */
+
+/**
+ * enum ath5k_int - Hardware interrupt masks helpers
+ *
+ * @AR5K_INT_RX: mask to identify received frame interrupts, of type
+ *     AR5K_ISR_RXOK or AR5K_ISR_RXERR
+ * @AR5K_INT_RXDESC: Request RX descriptor/Read RX descriptor (?)
+ * @AR5K_INT_RXNOFRM: No frame received (?)
+ * @AR5K_INT_RXEOL: received End Of List for VEOL (Virtual End Of List). The
+ *     Queue Control Unit (QCU) signals an EOL interrupt only if a descriptor's
+ *     LinkPtr is NULL. For more details, refer to:
+ *     http://www.freepatentsonline.com/20030225739.html
+ * @AR5K_INT_RXORN: Indicates we got RX overrun (eg. no more descriptors).
+ *     Note that Rx overrun is not always fatal, on some chips we can continue
+ *     operation without reseting the card, that's why int_fatal is not
+ *     common for all chips.
+ * @AR5K_INT_TX: mask to identify received frame interrupts, of type
+ *     AR5K_ISR_TXOK or AR5K_ISR_TXERR
+ * @AR5K_INT_TXDESC: Request TX descriptor/Read TX status descriptor (?)
+ * @AR5K_INT_TXURN: received when we should increase the TX trigger threshold
+ *     We currently do increments on interrupt by
+ *     (AR5K_TUNE_MAX_TX_FIFO_THRES - current_trigger_level) / 2
+ * @AR5K_INT_MIB: Indicates the Management Information Base counters should be
+ *     checked. We should do this with ath5k_hw_update_mib_counters() but
+ *     it seems we should also then do some noise immunity work.
+ * @AR5K_INT_RXPHY: RX PHY Error
+ * @AR5K_INT_RXKCM: RX Key cache miss
+ * @AR5K_INT_SWBA: SoftWare Beacon Alert - indicates its time to send a
+ *     beacon that must be handled in software. The alternative is if you
+ *     have VEOL support, in that case you let the hardware deal with things.
+ * @AR5K_INT_BMISS: If in STA mode this indicates we have stopped seeing
+ *     beacons from the AP have associated with, we should probably try to
+ *     reassociate. When in IBSS mode this might mean we have not received
+ *     any beacons from any local stations. Note that every station in an
+ *     IBSS schedules to send beacons at the Target Beacon Transmission Time
+ *     (TBTT) with a random backoff.
+ * @AR5K_INT_BNR: Beacon Not Ready interrupt - ??
+ * @AR5K_INT_GPIO: GPIO interrupt is used for RF Kill, disabled for now
+ *     until properly handled
+ * @AR5K_INT_FATAL: Fatal errors were encountered, typically caused by DMA
+ *     errors. These types of errors we can enable seem to be of type
+ *     AR5K_SIMR2_MCABT, AR5K_SIMR2_SSERR and AR5K_SIMR2_DPERR.
+ * @AR5K_INT_GLOBAL: Used to clear and set the IER
+ * @AR5K_INT_NOCARD: signals the card has been removed
+ * @AR5K_INT_COMMON: common interrupts shared amogst MACs with the same
+ *     bit value
+ *
+ * These are mapped to take advantage of some common bits
+ * between the MACs, to be able to set intr properties
+ * easier. Some of them are not used yet inside hw.c. Most map
+ * to the respective hw interrupt value as they are common amogst different
+ * MACs.
+ */
+enum ath5k_int {
+       AR5K_INT_RXOK   = 0x00000001,
+       AR5K_INT_RXDESC = 0x00000002,
+       AR5K_INT_RXERR  = 0x00000004,
+       AR5K_INT_RXNOFRM = 0x00000008,
+       AR5K_INT_RXEOL  = 0x00000010,
+       AR5K_INT_RXORN  = 0x00000020,
+       AR5K_INT_TXOK   = 0x00000040,
+       AR5K_INT_TXDESC = 0x00000080,
+       AR5K_INT_TXERR  = 0x00000100,
+       AR5K_INT_TXNOFRM = 0x00000200,
+       AR5K_INT_TXEOL  = 0x00000400,
+       AR5K_INT_TXURN  = 0x00000800,
+       AR5K_INT_MIB    = 0x00001000,
+       AR5K_INT_SWI    = 0x00002000,
+       AR5K_INT_RXPHY  = 0x00004000,
+       AR5K_INT_RXKCM  = 0x00008000,
+       AR5K_INT_SWBA   = 0x00010000,
+       AR5K_INT_BRSSI  = 0x00020000,
+       AR5K_INT_BMISS  = 0x00040000,
+       AR5K_INT_FATAL  = 0x00080000, /* Non common */
+       AR5K_INT_BNR    = 0x00100000, /* Non common */
+       AR5K_INT_TIM    = 0x00200000, /* Non common */
+       AR5K_INT_DTIM   = 0x00400000, /* Non common */
+       AR5K_INT_DTIM_SYNC =    0x00800000, /* Non common */
+       AR5K_INT_GPIO   =       0x01000000,
+       AR5K_INT_BCN_TIMEOUT =  0x02000000, /* Non common */
+       AR5K_INT_CAB_TIMEOUT =  0x04000000, /* Non common */
+       AR5K_INT_RX_DOPPLER =   0x08000000, /* Non common */
+       AR5K_INT_QCBRORN =      0x10000000, /* Non common */
+       AR5K_INT_QCBRURN =      0x20000000, /* Non common */
+       AR5K_INT_QTRIG  =       0x40000000, /* Non common */
+       AR5K_INT_GLOBAL =       0x80000000,
+
+       AR5K_INT_COMMON  = AR5K_INT_RXOK
+               | AR5K_INT_RXDESC
+               | AR5K_INT_RXERR
+               | AR5K_INT_RXNOFRM
+               | AR5K_INT_RXEOL
+               | AR5K_INT_RXORN
+               | AR5K_INT_TXOK
+               | AR5K_INT_TXDESC
+               | AR5K_INT_TXERR
+               | AR5K_INT_TXNOFRM
+               | AR5K_INT_TXEOL
+               | AR5K_INT_TXURN
+               | AR5K_INT_MIB
+               | AR5K_INT_SWI
+               | AR5K_INT_RXPHY
+               | AR5K_INT_RXKCM
+               | AR5K_INT_SWBA
+               | AR5K_INT_BRSSI
+               | AR5K_INT_BMISS
+               | AR5K_INT_GPIO
+               | AR5K_INT_GLOBAL,
+
+       AR5K_INT_NOCARD = 0xffffffff
+};
+
+/*
+ * Power management
+ */
+enum ath5k_power_mode {
+       AR5K_PM_UNDEFINED = 0,
+       AR5K_PM_AUTO,
+       AR5K_PM_AWAKE,
+       AR5K_PM_FULL_SLEEP,
+       AR5K_PM_NETWORK_SLEEP,
+};
+
+/*
+ * These match net80211 definitions (not used in
+ * mac80211).
+ * TODO: Clean this up
+ */
+#define AR5K_LED_INIT  0 /*IEEE80211_S_INIT*/
+#define AR5K_LED_SCAN  1 /*IEEE80211_S_SCAN*/
+#define AR5K_LED_AUTH  2 /*IEEE80211_S_AUTH*/
+#define AR5K_LED_ASSOC 3 /*IEEE80211_S_ASSOC*/
+#define AR5K_LED_RUN   4 /*IEEE80211_S_RUN*/
+
+/* GPIO-controlled software LED */
+#define AR5K_SOFTLED_PIN       0
+#define AR5K_SOFTLED_ON                0
+#define AR5K_SOFTLED_OFF       1
+
+/*
+ * Chipset capabilities -see ath5k_hw_get_capability-
+ * get_capability function is not yet fully implemented
+ * in ath5k so most of these don't work yet...
+ * TODO: Implement these & merge with _TUNE_ stuff above
+ */
+enum ath5k_capability_type {
+       AR5K_CAP_REG_DMN                = 0,    /* Used to get current reg. domain id */
+       AR5K_CAP_TKIP_MIC               = 2,    /* Can handle TKIP MIC in hardware */
+       AR5K_CAP_TKIP_SPLIT             = 3,    /* TKIP uses split keys */
+       AR5K_CAP_PHYCOUNTERS            = 4,    /* PHY error counters */
+       AR5K_CAP_DIVERSITY              = 5,    /* Supports fast diversity */
+       AR5K_CAP_NUM_TXQUEUES           = 6,    /* Used to get max number of hw txqueues */
+       AR5K_CAP_VEOL                   = 7,    /* Supports virtual EOL */
+       AR5K_CAP_COMPRESSION            = 8,    /* Supports compression */
+       AR5K_CAP_BURST                  = 9,    /* Supports packet bursting */
+       AR5K_CAP_FASTFRAME              = 10,   /* Supports fast frames */
+       AR5K_CAP_TXPOW                  = 11,   /* Used to get global tx power limit */
+       AR5K_CAP_TPC                    = 12,   /* Can do per-packet tx power control (needed for 802.11a) */
+       AR5K_CAP_BSSIDMASK              = 13,   /* Supports bssid mask */
+       AR5K_CAP_MCAST_KEYSRCH          = 14,   /* Supports multicast key search */
+       AR5K_CAP_TSF_ADJUST             = 15,   /* Supports beacon tsf adjust */
+       AR5K_CAP_XR                     = 16,   /* Supports XR mode */
+       AR5K_CAP_WME_TKIPMIC            = 17,   /* Supports TKIP MIC when using WMM */
+       AR5K_CAP_CHAN_HALFRATE          = 18,   /* Supports half rate channels */
+       AR5K_CAP_CHAN_QUARTERRATE       = 19,   /* Supports quarter rate channels */
+       AR5K_CAP_RFSILENT               = 20,   /* Supports RFsilent */
+};
+
+
+/* XXX: we *may* move cap_range stuff to struct wiphy */
+struct ath5k_capabilities {
+       /*
+        * Supported PHY modes
+        * (ie. CHANNEL_A, CHANNEL_B, ...)
+        */
+       DECLARE_BITMAP(cap_mode, AR5K_MODE_MAX);
+
+       /*
+        * Frequency range (without regulation restrictions)
+        */
+       struct {
+               u16     range_2ghz_min;
+               u16     range_2ghz_max;
+               u16     range_5ghz_min;
+               u16     range_5ghz_max;
+       } cap_range;
+
+       /*
+        * Values stored in the EEPROM (some of them...)
+        */
+       struct ath5k_eeprom_info        cap_eeprom;
+
+       /*
+        * Queue information
+        */
+       struct {
+               u8      q_tx_num;
+       } cap_queues;
+};
+
+
+/***************************************\
+  HARDWARE ABSTRACTION LAYER STRUCTURE
+\***************************************/
+
+/*
+ * Misc defines
+ */
+
+#define AR5K_MAX_GPIO          10
+#define AR5K_MAX_RF_BANKS      8
+
+/* TODO: Clean up and merge with ath5k_softc */
+struct ath5k_hw {
+       u32                     ah_magic;
+
+       struct ath5k_softc      *ah_sc;
+       void __iomem            *ah_iobase;
+
+       enum ath5k_int          ah_imr;
+
+       enum nl80211_iftype     ah_op_mode;
+       enum ath5k_power_mode   ah_power_mode;
+       struct ieee80211_channel ah_current_channel;
+       bool                    ah_turbo;
+       bool                    ah_calibration;
+       bool                    ah_running;
+       bool                    ah_single_chip;
+       bool                    ah_combined_mic;
+
+       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;
+
+       enum ath5k_version      ah_version;
+       enum ath5k_radio        ah_radio;
+       u32                     ah_phy;
+
+       bool                    ah_5ghz;
+       bool                    ah_2ghz;
+
+#define ah_modes               ah_capabilities.cap_mode
+#define ah_ee_version          ah_capabilities.cap_eeprom.ee_version
+
+       u32                     ah_atim_window;
+       u32                     ah_aifs;
+       u32                     ah_cw_min;
+       u32                     ah_cw_max;
+       bool                    ah_software_retry;
+       u32                     ah_limit_tx_retries;
+
+       /* Antenna Control */
+       u32                     ah_ant_ctl[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX];
+       u8                      ah_ant_mode;
+       u8                      ah_tx_ant;
+       u8                      ah_def_ant;
+
+       u8                      ah_sta_id[ETH_ALEN];
+
+       /* Current BSSID we are trying to assoc to / create.
+        * This is passed by mac80211 on config_interface() and cached here for
+        * use in resets */
+       u8                      ah_bssid[ETH_ALEN];
+       u8                      ah_bssid_mask[ETH_ALEN];
+
+       u32                     ah_gpio[AR5K_MAX_GPIO];
+       int                     ah_gpio_npins;
+
+       struct ath_regulatory   ah_regulatory;
+       struct ath5k_capabilities ah_capabilities;
+
+       struct ath5k_txq_info   ah_txq[AR5K_NUM_TX_QUEUES];
+       u32                     ah_txq_status;
+       u32                     ah_txq_imr_txok;
+       u32                     ah_txq_imr_txerr;
+       u32                     ah_txq_imr_txurn;
+       u32                     ah_txq_imr_txdesc;
+       u32                     ah_txq_imr_txeol;
+       u32                     ah_txq_imr_cbrorn;
+       u32                     ah_txq_imr_cbrurn;
+       u32                     ah_txq_imr_qtrig;
+       u32                     ah_txq_imr_nofrm;
+       u32                     ah_txq_isr;
+       u32                     *ah_rf_banks;
+       size_t                  ah_rf_banks_size;
+       size_t                  ah_rf_regs_count;
+       struct ath5k_gain       ah_gain;
+       u8                      ah_offset[AR5K_MAX_RF_BANKS];
+
+
+       struct {
+               /* Temporary tables used for interpolation */
+               u8              tmpL[AR5K_EEPROM_N_PD_GAINS]
+                                       [AR5K_EEPROM_POWER_TABLE_SIZE];
+               u8              tmpR[AR5K_EEPROM_N_PD_GAINS]
+                                       [AR5K_EEPROM_POWER_TABLE_SIZE];
+               u8              txp_pd_table[AR5K_EEPROM_POWER_TABLE_SIZE * 2];
+               u16             txp_rates_power_table[AR5K_MAX_RATES];
+               u8              txp_min_idx;
+               bool            txp_tpc;
+               /* Values in 0.25dB units */
+               s16             txp_min_pwr;
+               s16             txp_max_pwr;
+               /* Values in 0.5dB units */
+               s16             txp_offset;
+               s16             txp_ofdm;
+               s16             txp_cck_ofdm_gainf_delta;
+               /* Value in dB units */
+               s16             txp_cck_ofdm_pwr_delta;
+       } ah_txpower;
+
+       struct {
+               bool            r_enabled;
+               int             r_last_alert;
+               struct ieee80211_channel r_last_channel;
+       } ah_radar;
+
+       /* noise floor from last periodic calibration */
+       s32                     ah_noise_floor;
+
+       /*
+        * Function pointers
+        */
+       int (*ah_setup_rx_desc)(struct ath5k_hw *ah, struct ath5k_desc *desc,
+                               u32 size, unsigned int flags);
+       int (*ah_setup_tx_desc)(struct ath5k_hw *, struct ath5k_desc *,
+               unsigned int, unsigned int, enum ath5k_pkt_type, unsigned int,
+               unsigned int, unsigned int, unsigned int, unsigned int,
+               unsigned int, unsigned int, unsigned int);
+       int (*ah_setup_mrr_tx_desc)(struct ath5k_hw *, struct ath5k_desc *,
+               unsigned int, unsigned int, unsigned int, unsigned int,
+               unsigned int, unsigned int);
+       int (*ah_proc_tx_desc)(struct ath5k_hw *, struct ath5k_desc *,
+               struct ath5k_tx_status *);
+       int (*ah_proc_rx_desc)(struct ath5k_hw *, struct ath5k_desc *,
+               struct ath5k_rx_status *);
+};
+
+/*
+ * Prototypes
+ */
+
+/* Attach/Detach Functions */
+extern struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version);
+extern void ath5k_hw_detach(struct ath5k_hw *ah);
+
+/* LED functions */
+extern int ath5k_init_leds(struct ath5k_softc *sc);
+extern void ath5k_led_enable(struct ath5k_softc *sc);
+extern void ath5k_led_off(struct ath5k_softc *sc);
+extern void ath5k_unregister_leds(struct ath5k_softc *sc);
+
+/* Reset Functions */
+extern int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial);
+extern int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, struct ieee80211_channel *channel, bool change_channel);
+/* Power management functions */
+extern int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode, bool set_chip, u16 sleep_duration);
+
+/* DMA Related Functions */
+extern void ath5k_hw_start_rx_dma(struct ath5k_hw *ah);
+extern int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah);
+extern u32 ath5k_hw_get_rxdp(struct ath5k_hw *ah);
+extern void ath5k_hw_set_rxdp(struct ath5k_hw *ah, u32 phys_addr);
+extern int ath5k_hw_start_tx_dma(struct ath5k_hw *ah, unsigned int queue);
+extern int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue);
+extern u32 ath5k_hw_get_txdp(struct ath5k_hw *ah, unsigned int queue);
+extern int ath5k_hw_set_txdp(struct ath5k_hw *ah, unsigned int queue,
+                               u32 phys_addr);
+extern int ath5k_hw_update_tx_triglevel(struct ath5k_hw *ah, bool increase);
+/* Interrupt handling */
+extern bool ath5k_hw_is_intr_pending(struct ath5k_hw *ah);
+extern int ath5k_hw_get_isr(struct ath5k_hw *ah, enum ath5k_int *interrupt_mask);
+extern enum ath5k_int ath5k_hw_set_imr(struct ath5k_hw *ah, enum
+ath5k_int new_mask);
+extern void ath5k_hw_update_mib_counters(struct ath5k_hw *ah, struct ieee80211_low_level_stats *stats);
+
+/* EEPROM access functions */
+extern int ath5k_eeprom_init(struct ath5k_hw *ah);
+extern void ath5k_eeprom_detach(struct ath5k_hw *ah);
+extern int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac);
+extern bool ath5k_eeprom_is_hb63(struct ath5k_hw *ah);
+
+/* Protocol Control Unit Functions */
+extern int ath5k_hw_set_opmode(struct ath5k_hw *ah);
+/* BSSID Functions */
+extern void ath5k_hw_get_lladdr(struct ath5k_hw *ah, u8 *mac);
+extern int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac);
+extern void ath5k_hw_set_associd(struct ath5k_hw *ah, const u8 *bssid, u16 assoc_id);
+extern int ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask);
+/* Receive start/stop functions */
+extern void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah);
+extern void ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah);
+/* RX Filter functions */
+extern void ath5k_hw_set_mcast_filter(struct ath5k_hw *ah, u32 filter0, u32 filter1);
+extern int ath5k_hw_set_mcast_filter_idx(struct ath5k_hw *ah, u32 index);
+extern int ath5k_hw_clear_mcast_filter_idx(struct ath5k_hw *ah, u32 index);
+extern u32 ath5k_hw_get_rx_filter(struct ath5k_hw *ah);
+extern void ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter);
+/* Beacon control functions */
+extern u32 ath5k_hw_get_tsf32(struct ath5k_hw *ah);
+extern u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah);
+extern void ath5k_hw_set_tsf64(struct ath5k_hw *ah, u64 tsf64);
+extern void ath5k_hw_reset_tsf(struct ath5k_hw *ah);
+extern void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval);
+#if 0
+extern int ath5k_hw_set_beacon_timers(struct ath5k_hw *ah, const struct ath5k_beacon_state *state);
+extern void ath5k_hw_reset_beacon(struct ath5k_hw *ah);
+extern int ath5k_hw_beaconq_finish(struct ath5k_hw *ah, unsigned long phys_addr);
+#endif
+/* ACK bit rate */
+void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high);
+/* ACK/CTS Timeouts */
+extern int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout);
+extern unsigned int ath5k_hw_get_ack_timeout(struct ath5k_hw *ah);
+extern int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout);
+extern unsigned int ath5k_hw_get_cts_timeout(struct ath5k_hw *ah);
+/* Key table (WEP) functions */
+extern int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry);
+extern int ath5k_hw_is_key_valid(struct ath5k_hw *ah, u16 entry);
+extern int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry, const struct ieee80211_key_conf *key, const u8 *mac);
+extern int ath5k_hw_set_key_lladdr(struct ath5k_hw *ah, u16 entry, const u8 *mac);
+
+/* Queue Control Unit, DFS Control Unit Functions */
+extern int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue, struct ath5k_txq_info *queue_info);
+extern int ath5k_hw_set_tx_queueprops(struct ath5k_hw *ah, int queue,
+                               const struct ath5k_txq_info *queue_info);
+extern int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah,
+                               enum ath5k_tx_queue queue_type,
+                               struct ath5k_txq_info *queue_info);
+extern u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue);
+extern void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue);
+extern int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue);
+extern unsigned int ath5k_hw_get_slot_time(struct ath5k_hw *ah);
+extern int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time);
+
+/* Hardware Descriptor Functions */
+extern int ath5k_hw_init_desc_functions(struct ath5k_hw *ah);
+
+/* GPIO Functions */
+extern void ath5k_hw_set_ledstate(struct ath5k_hw *ah, unsigned int state);
+extern int ath5k_hw_set_gpio_input(struct ath5k_hw *ah, u32 gpio);
+extern int ath5k_hw_set_gpio_output(struct ath5k_hw *ah, u32 gpio);
+extern u32 ath5k_hw_get_gpio(struct ath5k_hw *ah, u32 gpio);
+extern int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val);
+extern void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio, u32 interrupt_level);
+
+/* rfkill Functions */
+extern void ath5k_rfkill_hw_start(struct ath5k_hw *ah);
+extern void ath5k_rfkill_hw_stop(struct ath5k_hw *ah);
+
+/* Misc functions */
+int ath5k_hw_set_capabilities(struct ath5k_hw *ah);
+extern int ath5k_hw_get_capability(struct ath5k_hw *ah, enum ath5k_capability_type cap_type, u32 capability, u32 *result);
+extern int ath5k_hw_enable_pspoll(struct ath5k_hw *ah, u8 *bssid, u16 assoc_id);
+extern int ath5k_hw_disable_pspoll(struct ath5k_hw *ah);
+
+/* Initial register settings functions */
+extern int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel);
+
+/* Initialize RF */
+extern int ath5k_hw_rfregs_init(struct ath5k_hw *ah,
+                               struct ieee80211_channel *channel,
+                               unsigned int mode);
+extern int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq);
+extern enum ath5k_rfgain ath5k_hw_gainf_calibrate(struct ath5k_hw *ah);
+extern int ath5k_hw_rfgain_opt_init(struct ath5k_hw *ah);
+/* PHY/RF channel functions */
+extern bool ath5k_channel_ok(struct ath5k_hw *ah, u16 freq, unsigned int flags);
+extern int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel);
+/* PHY calibration */
+extern int ath5k_hw_phy_calibrate(struct ath5k_hw *ah, struct ieee80211_channel *channel);
+extern int ath5k_hw_noise_floor_calibration(struct ath5k_hw *ah, short freq);
+/* Spur mitigation */
+bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah,
+                               struct ieee80211_channel *channel);
+void ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah,
+                               struct ieee80211_channel *channel);
+/* Misc PHY functions */
+extern u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan);
+extern int ath5k_hw_phy_disable(struct ath5k_hw *ah);
+/* Antenna control */
+extern void ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode);
+extern void ath5k_hw_set_def_antenna(struct ath5k_hw *ah, u8 ant);
+extern unsigned int ath5k_hw_get_def_antenna(struct ath5k_hw *ah);
+/* TX power setup */
+extern int ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, u8 ee_mode, u8 txpower);
+extern int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower);
+
+/*
+ * Functions used internaly
+ */
+
+/*
+ * Translate usec to hw clock units
+ * TODO: Half/quarter rate
+ */
+static inline unsigned int ath5k_hw_htoclock(unsigned int usec, bool turbo)
+{
+       return turbo ? (usec * 80) : (usec * 40);
+}
+
+/*
+ * Translate hw clock units to usec
+ * TODO: Half/quarter rate
+ */
+static inline unsigned int ath5k_hw_clocktoh(unsigned int clock, bool turbo)
+{
+       return turbo ? (clock / 80) : (clock / 40);
+}
+
+/*
+ * Read from a register
+ */
+static inline u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg)
+{
+       return ioread32(ah->ah_iobase + reg);
+}
+
+/*
+ * Write to a register
+ */
+static inline void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg)
+{
+       iowrite32(val, ah->ah_iobase + reg);
+}
+
+#if defined(_ATH5K_RESET) || defined(_ATH5K_PHY)
+/*
+ * Check if a register write has been completed
+ */
+static int ath5k_hw_register_timeout(struct ath5k_hw *ah, u32 reg, u32 flag,
+               u32 val, bool is_set)
+{
+       int i;
+       u32 data;
+
+       for (i = AR5K_TUNE_REGISTER_TIMEOUT; i > 0; i--) {
+               data = ath5k_hw_reg_read(ah, reg);
+               if (is_set && (data & flag))
+                       break;
+               else if ((data & flag) == val)
+                       break;
+               udelay(15);
+       }
+
+       return (i <= 0) ? -EAGAIN : 0;
+}
+#endif
+
+static inline u32 ath5k_hw_bitswap(u32 val, unsigned int bits)
+{
+       u32 retval = 0, bit, i;
+
+       for (i = 0; i < bits; i++) {
+               bit = (val >> i) & 1;
+               retval = (retval << 1) | bit;
+       }
+
+       return retval;
+}
+
+static inline int ath5k_pad_size(int hdrlen)
+{
+       return (hdrlen < 24) ? 0 : hdrlen & 3;
+}
+
+#endif
diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c
new file mode 100644 (file)
index 0000000..c41ef58
--- /dev/null
@@ -0,0 +1,347 @@
+/*
+ * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
+ * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
+ *
+ * Permission to use, copy, modify, and 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.
+ *
+ */
+
+/*************************************\
+* Attach/Detach Functions and helpers *
+\*************************************/
+
+#include <linux/pci.h>
+#include "ath5k.h"
+#include "reg.h"
+#include "debug.h"
+#include "base.h"
+
+/**
+ * ath5k_hw_post - Power On Self Test helper function
+ *
+ * @ah: The &struct ath5k_hw
+ */
+static int ath5k_hw_post(struct ath5k_hw *ah)
+{
+
+       static const u32 static_pattern[4] = {
+               0x55555555,     0xaaaaaaaa,
+               0x66666666,     0x99999999
+       };
+       static const u16 regs[2] = { AR5K_STA_ID0, AR5K_PHY(8) };
+       int i, c;
+       u16 cur_reg;
+       u32 var_pattern;
+       u32 init_val;
+       u32 cur_val;
+
+       for (c = 0; c < 2; c++) {
+
+               cur_reg = regs[c];
+
+               /* Save previous value */
+               init_val = ath5k_hw_reg_read(ah, cur_reg);
+
+               for (i = 0; i < 256; i++) {
+                       var_pattern = i << 16 | i;
+                       ath5k_hw_reg_write(ah, var_pattern, cur_reg);
+                       cur_val = ath5k_hw_reg_read(ah, cur_reg);
+
+                       if (cur_val != var_pattern) {
+                               ATH5K_ERR(ah->ah_sc, "POST Failed !!!\n");
+                               return -EAGAIN;
+                       }
+
+                       /* Found on ndiswrapper dumps */
+                       var_pattern = 0x0039080f;
+                       ath5k_hw_reg_write(ah, var_pattern, cur_reg);
+               }
+
+               for (i = 0; i < 4; i++) {
+                       var_pattern = static_pattern[i];
+                       ath5k_hw_reg_write(ah, var_pattern, cur_reg);
+                       cur_val = ath5k_hw_reg_read(ah, cur_reg);
+
+                       if (cur_val != var_pattern) {
+                               ATH5K_ERR(ah->ah_sc, "POST Failed !!!\n");
+                               return -EAGAIN;
+                       }
+
+                       /* Found on ndiswrapper dumps */
+                       var_pattern = 0x003b080f;
+                       ath5k_hw_reg_write(ah, var_pattern, cur_reg);
+               }
+
+               /* Restore previous value */
+               ath5k_hw_reg_write(ah, init_val, cur_reg);
+
+       }
+
+       return 0;
+
+}
+
+/**
+ * ath5k_hw_attach - Check if hw is supported and init the needed structs
+ *
+ * @sc: The &struct ath5k_softc we got from the driver's attach function
+ * @mac_version: The mac version id (check out ath5k.h) based on pci id
+ *
+ * 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,
+ * -ENODEV if the device is not supported or prints an error msg if something
+ * else went wrong.
+ */
+struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
+{
+       struct ath5k_hw *ah;
+       struct pci_dev *pdev = sc->pdev;
+       int ret;
+       u32 srev;
+
+       /*If we passed the test malloc a ath5k_hw struct*/
+       ah = kzalloc(sizeof(struct ath5k_hw), GFP_KERNEL);
+       if (ah == NULL) {
+               ret = -ENOMEM;
+               ATH5K_ERR(sc, "out of memory\n");
+               goto err;
+       }
+
+       ah->ah_sc = sc;
+       ah->ah_iobase = sc->iobase;
+
+       /*
+        * HW information
+        */
+       ah->ah_op_mode = NL80211_IFTYPE_STATION;
+       ah->ah_radar.r_enabled = AR5K_TUNE_RADAR_ALERT;
+       ah->ah_turbo = false;
+       ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER;
+       ah->ah_imr = 0;
+       ah->ah_atim_window = 0;
+       ah->ah_aifs = AR5K_TUNE_AIFS;
+       ah->ah_cw_min = AR5K_TUNE_CWMIN;
+       ah->ah_limit_tx_retries = AR5K_INIT_TX_RETRY;
+       ah->ah_software_retry = false;
+
+       /*
+        * Set the mac version based on the pci id
+        */
+       ah->ah_version = mac_version;
+
+       /*Fill the ath5k_hw struct with the needed functions*/
+       ret = ath5k_hw_init_desc_functions(ah);
+       if (ret)
+               goto err_free;
+
+       /* Bring device out of sleep and reset it's units */
+       ret = ath5k_hw_nic_wakeup(ah, CHANNEL_B, true);
+       if (ret)
+               goto err_free;
+
+       /* Get MAC, PHY and RADIO revisions */
+       srev = ath5k_hw_reg_read(ah, AR5K_SREV);
+       ah->ah_mac_srev = srev;
+       ah->ah_mac_version = AR5K_REG_MS(srev, AR5K_SREV_VER);
+       ah->ah_mac_revision = AR5K_REG_MS(srev, AR5K_SREV_REV);
+       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);
+
+       /* Try to identify radio chip based on it's srev */
+       switch (ah->ah_radio_5ghz_revision & 0xf0) {
+       case AR5K_SREV_RAD_5111:
+               ah->ah_radio = AR5K_RF5111;
+               ah->ah_single_chip = false;
+               ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah,
+                                                       CHANNEL_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);
+               break;
+       case AR5K_SREV_RAD_2413:
+               ah->ah_radio = AR5K_RF2413;
+               ah->ah_single_chip = true;
+               break;
+       case AR5K_SREV_RAD_5413:
+               ah->ah_radio = AR5K_RF5413;
+               ah->ah_single_chip = true;
+               break;
+       case AR5K_SREV_RAD_2316:
+               ah->ah_radio = AR5K_RF2316;
+               ah->ah_single_chip = true;
+               break;
+       case AR5K_SREV_RAD_2317:
+               ah->ah_radio = AR5K_RF2317;
+               ah->ah_single_chip = true;
+               break;
+       case AR5K_SREV_RAD_5424:
+               if (ah->ah_mac_version == AR5K_SREV_AR2425 ||
+               ah->ah_mac_version == AR5K_SREV_AR2417){
+                       ah->ah_radio = AR5K_RF2425;
+                       ah->ah_single_chip = true;
+               } else {
+                       ah->ah_radio = AR5K_RF5413;
+                       ah->ah_single_chip = true;
+               }
+               break;
+       default:
+               /* Identify radio based on mac/phy srev */
+               if (ah->ah_version == AR5K_AR5210) {
+                       ah->ah_radio = AR5K_RF5110;
+                       ah->ah_single_chip = false;
+               } else if (ah->ah_version == AR5K_AR5211) {
+                       ah->ah_radio = AR5K_RF5111;
+                       ah->ah_single_chip = false;
+                       ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah,
+                                                               CHANNEL_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) {
+                       ah->ah_radio = AR5K_RF2425;
+                       ah->ah_single_chip = true;
+                       ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2425;
+               } else if (srev == AR5K_SREV_AR5213A &&
+               ah->ah_phy_revision == AR5K_SREV_PHY_5212B) {
+                       ah->ah_radio = AR5K_RF5112;
+                       ah->ah_single_chip = false;
+                       ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_5112B;
+               } else if (ah->ah_mac_version == (AR5K_SREV_AR2415 >> 4)) {
+                       ah->ah_radio = AR5K_RF2316;
+                       ah->ah_single_chip = true;
+                       ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2316;
+               } else if (ah->ah_mac_version == (AR5K_SREV_AR5414 >> 4) ||
+               ah->ah_phy_revision == AR5K_SREV_PHY_5413) {
+                       ah->ah_radio = AR5K_RF5413;
+                       ah->ah_single_chip = true;
+                       ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_5413;
+               } else if (ah->ah_mac_version == (AR5K_SREV_AR2414 >> 4) ||
+               ah->ah_phy_revision == AR5K_SREV_PHY_2413) {
+                       ah->ah_radio = AR5K_RF2413;
+                       ah->ah_single_chip = true;
+                       ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2413;
+               } else {
+                       ATH5K_ERR(sc, "Couldn't identify radio revision.\n");
+                       ret = -ENODEV;
+                       goto err_free;
+               }
+       }
+
+
+       /* Return on unsuported chips (unsupported eeprom etc) */
+       if ((srev >= AR5K_SREV_AR5416) &&
+       (srev < AR5K_SREV_AR2425)) {
+               ATH5K_ERR(sc, "Device not yet supported.\n");
+               ret = -ENODEV;
+               goto err_free;
+       }
+
+       /*
+        * Write PCI-E power save settings
+        */
+       if ((ah->ah_version == AR5K_AR5212) && (pdev->is_pcie)) {
+               ath5k_hw_reg_write(ah, 0x9248fc00, AR5K_PCIE_SERDES);
+               ath5k_hw_reg_write(ah, 0x24924924, AR5K_PCIE_SERDES);
+               /* Shut off RX when elecidle is asserted */
+               ath5k_hw_reg_write(ah, 0x28000039, AR5K_PCIE_SERDES);
+               ath5k_hw_reg_write(ah, 0x53160824, AR5K_PCIE_SERDES);
+               /* TODO: EEPROM work */
+               ath5k_hw_reg_write(ah, 0xe5980579, AR5K_PCIE_SERDES);
+               /* Shut off PLL and CLKREQ active in L1 */
+               ath5k_hw_reg_write(ah, 0x001defff, AR5K_PCIE_SERDES);
+               /* Preserce other settings */
+               ath5k_hw_reg_write(ah, 0x1aaabe40, AR5K_PCIE_SERDES);
+               ath5k_hw_reg_write(ah, 0xbe105554, AR5K_PCIE_SERDES);
+               ath5k_hw_reg_write(ah, 0x000e3007, AR5K_PCIE_SERDES);
+               /* Reset SERDES to load new settings */
+               ath5k_hw_reg_write(ah, 0x00000000, AR5K_PCIE_SERDES_RESET);
+               mdelay(1);
+       }
+
+       /*
+        * POST
+        */
+       ret = ath5k_hw_post(ah);
+       if (ret)
+               goto err_free;
+
+       /* Enable pci core retry fix on Hainan (5213A) and later chips */
+       if (srev >= AR5K_SREV_AR5213A)
+               ath5k_hw_reg_write(ah, AR5K_PCICFG_RETRY_FIX, AR5K_PCICFG);
+
+       /*
+        * Get card capabilities, calibration values etc
+        * TODO: EEPROM work
+        */
+       ret = ath5k_eeprom_init(ah);
+       if (ret) {
+               ATH5K_ERR(sc, "unable to init EEPROM\n");
+               goto err_free;
+       }
+
+       /* Get misc capabilities */
+       ret = ath5k_hw_set_capabilities(ah);
+       if (ret) {
+               ATH5K_ERR(sc, "unable to get device capabilities: 0x%04x\n",
+                       sc->pdev->device);
+               goto err_free;
+       }
+
+       if (srev >= AR5K_SREV_AR2414) {
+               ah->ah_combined_mic = true;
+               AR5K_REG_ENABLE_BITS(ah, AR5K_MISC_MODE,
+                       AR5K_MISC_MODE_COMBINED_MIC);
+       }
+
+       /* MAC address is cleared until add_interface */
+       ath5k_hw_set_lladdr(ah, (u8[ETH_ALEN]){});
+
+       /* Set BSSID to bcast address: ff:ff:ff:ff:ff:ff for now */
+       memset(ah->ah_bssid, 0xff, ETH_ALEN);
+       ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
+       ath5k_hw_set_opmode(ah);
+
+       ath5k_hw_rfgain_opt_init(ah);
+
+       return ah;
+err_free:
+       kfree(ah);
+err:
+       return ERR_PTR(ret);
+}
+
+/**
+ * ath5k_hw_detach - Free the ath5k_hw struct
+ *
+ * @ah: The &struct ath5k_hw
+ */
+void ath5k_hw_detach(struct ath5k_hw *ah)
+{
+       ATH5K_TRACE(ah->ah_sc);
+
+       __set_bit(ATH_STAT_INVALID, ah->ah_sc->status);
+
+       if (ah->ah_rf_banks != NULL)
+               kfree(ah->ah_rf_banks);
+
+       ath5k_eeprom_detach(ah);
+
+       /* assume interrupts are down */
+       kfree(ah);
+}
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
new file mode 100644 (file)
index 0000000..55f7de0
--- /dev/null
@@ -0,0 +1,3176 @@
+/*-
+ * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
+ * Copyright (c) 2004-2005 Atheros Communications, Inc.
+ * Copyright (c) 2006 Devicescape Software, Inc.
+ * Copyright (c) 2007 Jiri Slaby <jirislaby@gmail.com>
+ * Copyright (c) 2007 Luis R. Rodriguez <mcgrof@winlab.rutgers.edu>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ *    redistribution must be conditioned upon including a substantially
+ *    similar Disclaimer requirement for further binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/hardirq.h>
+#include <linux/if.h>
+#include <linux/io.h>
+#include <linux/netdevice.h>
+#include <linux/cache.h>
+#include <linux/pci.h>
+#include <linux/ethtool.h>
+#include <linux/uaccess.h>
+
+#include <net/ieee80211_radiotap.h>
+
+#include <asm/unaligned.h>
+
+#include "base.h"
+#include "reg.h"
+#include "debug.h"
+
+static int ath5k_calinterval = 10; /* Calibrate PHY every 10 secs (TODO: Fixme) */
+static int modparam_nohwcrypt;
+module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
+MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
+
+static int modparam_all_channels;
+module_param_named(all_channels, modparam_all_channels, bool, S_IRUGO);
+MODULE_PARM_DESC(all_channels, "Expose all channels the device can use.");
+
+
+/******************\
+* Internal defines *
+\******************/
+
+/* Module info */
+MODULE_AUTHOR("Jiri Slaby");
+MODULE_AUTHOR("Nick Kossifidis");
+MODULE_DESCRIPTION("Support for 5xxx series of Atheros 802.11 wireless LAN cards.");
+MODULE_SUPPORTED_DEVICE("Atheros 5xxx WLAN cards");
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_VERSION("0.6.0 (EXPERIMENTAL)");
+
+
+/* Known PCI ids */
+static const struct pci_device_id ath5k_pci_id_table[] = {
+       { PCI_VDEVICE(ATHEROS, 0x0207), .driver_data = AR5K_AR5210 }, /* 5210 early */
+       { PCI_VDEVICE(ATHEROS, 0x0007), .driver_data = AR5K_AR5210 }, /* 5210 */
+       { PCI_VDEVICE(ATHEROS, 0x0011), .driver_data = AR5K_AR5211 }, /* 5311 - this is on AHB bus !*/
+       { PCI_VDEVICE(ATHEROS, 0x0012), .driver_data = AR5K_AR5211 }, /* 5211 */
+       { PCI_VDEVICE(ATHEROS, 0x0013), .driver_data = AR5K_AR5212 }, /* 5212 */
+       { PCI_VDEVICE(3COM_2,  0x0013), .driver_data = AR5K_AR5212 }, /* 3com 5212 */
+       { PCI_VDEVICE(3COM,    0x0013), .driver_data = AR5K_AR5212 }, /* 3com 3CRDAG675 5212 */
+       { PCI_VDEVICE(ATHEROS, 0x1014), .driver_data = AR5K_AR5212 }, /* IBM minipci 5212 */
+       { PCI_VDEVICE(ATHEROS, 0x0014), .driver_data = AR5K_AR5212 }, /* 5212 combatible */
+       { PCI_VDEVICE(ATHEROS, 0x0015), .driver_data = AR5K_AR5212 }, /* 5212 combatible */
+       { PCI_VDEVICE(ATHEROS, 0x0016), .driver_data = AR5K_AR5212 }, /* 5212 combatible */
+       { PCI_VDEVICE(ATHEROS, 0x0017), .driver_data = AR5K_AR5212 }, /* 5212 combatible */
+       { PCI_VDEVICE(ATHEROS, 0x0018), .driver_data = AR5K_AR5212 }, /* 5212 combatible */
+       { PCI_VDEVICE(ATHEROS, 0x0019), .driver_data = AR5K_AR5212 }, /* 5212 combatible */
+       { PCI_VDEVICE(ATHEROS, 0x001a), .driver_data = AR5K_AR5212 }, /* 2413 Griffin-lite */
+       { PCI_VDEVICE(ATHEROS, 0x001b), .driver_data = AR5K_AR5212 }, /* 5413 Eagle */
+       { PCI_VDEVICE(ATHEROS, 0x001c), .driver_data = AR5K_AR5212 }, /* PCI-E cards */
+       { PCI_VDEVICE(ATHEROS, 0x001d), .driver_data = AR5K_AR5212 }, /* 2417 Nala */
+       { 0 }
+};
+MODULE_DEVICE_TABLE(pci, ath5k_pci_id_table);
+
+/* Known SREVs */
+static const struct ath5k_srev_name srev_names[] = {
+       { "5210",       AR5K_VERSION_MAC,       AR5K_SREV_AR5210 },
+       { "5311",       AR5K_VERSION_MAC,       AR5K_SREV_AR5311 },
+       { "5311A",      AR5K_VERSION_MAC,       AR5K_SREV_AR5311A },
+       { "5311B",      AR5K_VERSION_MAC,       AR5K_SREV_AR5311B },
+       { "5211",       AR5K_VERSION_MAC,       AR5K_SREV_AR5211 },
+       { "5212",       AR5K_VERSION_MAC,       AR5K_SREV_AR5212 },
+       { "5213",       AR5K_VERSION_MAC,       AR5K_SREV_AR5213 },
+       { "5213A",      AR5K_VERSION_MAC,       AR5K_SREV_AR5213A },
+       { "2413",       AR5K_VERSION_MAC,       AR5K_SREV_AR2413 },
+       { "2414",       AR5K_VERSION_MAC,       AR5K_SREV_AR2414 },
+       { "5424",       AR5K_VERSION_MAC,       AR5K_SREV_AR5424 },
+       { "5413",       AR5K_VERSION_MAC,       AR5K_SREV_AR5413 },
+       { "5414",       AR5K_VERSION_MAC,       AR5K_SREV_AR5414 },
+       { "2415",       AR5K_VERSION_MAC,       AR5K_SREV_AR2415 },
+       { "5416",       AR5K_VERSION_MAC,       AR5K_SREV_AR5416 },
+       { "5418",       AR5K_VERSION_MAC,       AR5K_SREV_AR5418 },
+       { "2425",       AR5K_VERSION_MAC,       AR5K_SREV_AR2425 },
+       { "2417",       AR5K_VERSION_MAC,       AR5K_SREV_AR2417 },
+       { "xxxxx",      AR5K_VERSION_MAC,       AR5K_SREV_UNKNOWN },
+       { "5110",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_5110 },
+       { "5111",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_5111 },
+       { "5111A",      AR5K_VERSION_RAD,       AR5K_SREV_RAD_5111A },
+       { "2111",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_2111 },
+       { "5112",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_5112 },
+       { "5112A",      AR5K_VERSION_RAD,       AR5K_SREV_RAD_5112A },
+       { "5112B",      AR5K_VERSION_RAD,       AR5K_SREV_RAD_5112B },
+       { "2112",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_2112 },
+       { "2112A",      AR5K_VERSION_RAD,       AR5K_SREV_RAD_2112A },
+       { "2112B",      AR5K_VERSION_RAD,       AR5K_SREV_RAD_2112B },
+       { "2413",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_2413 },
+       { "5413",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_5413 },
+       { "2316",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_2316 },
+       { "2317",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_2317 },
+       { "5424",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_5424 },
+       { "5133",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_5133 },
+       { "xxxxx",      AR5K_VERSION_RAD,       AR5K_SREV_UNKNOWN },
+};
+
+static const struct ieee80211_rate ath5k_rates[] = {
+       { .bitrate = 10,
+         .hw_value = ATH5K_RATE_CODE_1M, },
+       { .bitrate = 20,
+         .hw_value = ATH5K_RATE_CODE_2M,
+         .hw_value_short = ATH5K_RATE_CODE_2M | AR5K_SET_SHORT_PREAMBLE,
+         .flags = IEEE80211_RATE_SHORT_PREAMBLE },
+       { .bitrate = 55,
+         .hw_value = ATH5K_RATE_CODE_5_5M,
+         .hw_value_short = ATH5K_RATE_CODE_5_5M | AR5K_SET_SHORT_PREAMBLE,
+         .flags = IEEE80211_RATE_SHORT_PREAMBLE },
+       { .bitrate = 110,
+         .hw_value = ATH5K_RATE_CODE_11M,
+         .hw_value_short = ATH5K_RATE_CODE_11M | AR5K_SET_SHORT_PREAMBLE,
+         .flags = IEEE80211_RATE_SHORT_PREAMBLE },
+       { .bitrate = 60,
+         .hw_value = ATH5K_RATE_CODE_6M,
+         .flags = 0 },
+       { .bitrate = 90,
+         .hw_value = ATH5K_RATE_CODE_9M,
+         .flags = 0 },
+       { .bitrate = 120,
+         .hw_value = ATH5K_RATE_CODE_12M,
+         .flags = 0 },
+       { .bitrate = 180,
+         .hw_value = ATH5K_RATE_CODE_18M,
+         .flags = 0 },
+       { .bitrate = 240,
+         .hw_value = ATH5K_RATE_CODE_24M,
+         .flags = 0 },
+       { .bitrate = 360,
+         .hw_value = ATH5K_RATE_CODE_36M,
+         .flags = 0 },
+       { .bitrate = 480,
+         .hw_value = ATH5K_RATE_CODE_48M,
+         .flags = 0 },
+       { .bitrate = 540,
+         .hw_value = ATH5K_RATE_CODE_54M,
+         .flags = 0 },
+       /* XR missing */
+};
+
+/*
+ * Prototypes - PCI stack related functions
+ */
+static int __devinit   ath5k_pci_probe(struct pci_dev *pdev,
+                               const struct pci_device_id *id);
+static void __devexit  ath5k_pci_remove(struct pci_dev *pdev);
+#ifdef CONFIG_PM
+static int             ath5k_pci_suspend(struct pci_dev *pdev,
+                                       pm_message_t state);
+static int             ath5k_pci_resume(struct pci_dev *pdev);
+#else
+#define ath5k_pci_suspend NULL
+#define ath5k_pci_resume NULL
+#endif /* CONFIG_PM */
+
+static struct pci_driver ath5k_pci_driver = {
+       .name           = KBUILD_MODNAME,
+       .id_table       = ath5k_pci_id_table,
+       .probe          = ath5k_pci_probe,
+       .remove         = __devexit_p(ath5k_pci_remove),
+       .suspend        = ath5k_pci_suspend,
+       .resume         = ath5k_pci_resume,
+};
+
+
+
+/*
+ * Prototypes - MAC 802.11 stack related functions
+ */
+static int ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
+static int ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan);
+static int ath5k_reset_wake(struct ath5k_softc *sc);
+static int ath5k_start(struct ieee80211_hw *hw);
+static void ath5k_stop(struct ieee80211_hw *hw);
+static int ath5k_add_interface(struct ieee80211_hw *hw,
+               struct ieee80211_if_init_conf *conf);
+static void ath5k_remove_interface(struct ieee80211_hw *hw,
+               struct ieee80211_if_init_conf *conf);
+static int ath5k_config(struct ieee80211_hw *hw, u32 changed);
+static void ath5k_configure_filter(struct ieee80211_hw *hw,
+               unsigned int changed_flags,
+               unsigned int *new_flags,
+               int mc_count, struct dev_mc_list *mclist);
+static int ath5k_set_key(struct ieee80211_hw *hw,
+               enum set_key_cmd cmd,
+               struct ieee80211_vif *vif, struct ieee80211_sta *sta,
+               struct ieee80211_key_conf *key);
+static int ath5k_get_stats(struct ieee80211_hw *hw,
+               struct ieee80211_low_level_stats *stats);
+static int ath5k_get_tx_stats(struct ieee80211_hw *hw,
+               struct ieee80211_tx_queue_stats *stats);
+static u64 ath5k_get_tsf(struct ieee80211_hw *hw);
+static void ath5k_set_tsf(struct ieee80211_hw *hw, u64 tsf);
+static void ath5k_reset_tsf(struct ieee80211_hw *hw);
+static int ath5k_beacon_update(struct ieee80211_hw *hw,
+               struct ieee80211_vif *vif);
+static void ath5k_bss_info_changed(struct ieee80211_hw *hw,
+               struct ieee80211_vif *vif,
+               struct ieee80211_bss_conf *bss_conf,
+               u32 changes);
+
+static const struct ieee80211_ops ath5k_hw_ops = {
+       .tx             = ath5k_tx,
+       .start          = ath5k_start,
+       .stop           = ath5k_stop,
+       .add_interface  = ath5k_add_interface,
+       .remove_interface = ath5k_remove_interface,
+       .config         = ath5k_config,
+       .configure_filter = ath5k_configure_filter,
+       .set_key        = ath5k_set_key,
+       .get_stats      = ath5k_get_stats,
+       .conf_tx        = NULL,
+       .get_tx_stats   = ath5k_get_tx_stats,
+       .get_tsf        = ath5k_get_tsf,
+       .set_tsf        = ath5k_set_tsf,
+       .reset_tsf      = ath5k_reset_tsf,
+       .bss_info_changed = ath5k_bss_info_changed,
+};
+
+/*
+ * Prototypes - Internal functions
+ */
+/* Attach detach */
+static int     ath5k_attach(struct pci_dev *pdev,
+                       struct ieee80211_hw *hw);
+static void    ath5k_detach(struct pci_dev *pdev,
+                       struct ieee80211_hw *hw);
+/* Channel/mode setup */
+static inline short ath5k_ieee2mhz(short chan);
+static unsigned int ath5k_copy_channels(struct ath5k_hw *ah,
+                               struct ieee80211_channel *channels,
+                               unsigned int mode,
+                               unsigned int max);
+static int     ath5k_setup_bands(struct ieee80211_hw *hw);
+static int     ath5k_chan_set(struct ath5k_softc *sc,
+                               struct ieee80211_channel *chan);
+static void    ath5k_setcurmode(struct ath5k_softc *sc,
+                               unsigned int mode);
+static void    ath5k_mode_setup(struct ath5k_softc *sc);
+
+/* Descriptor setup */
+static int     ath5k_desc_alloc(struct ath5k_softc *sc,
+                               struct pci_dev *pdev);
+static void    ath5k_desc_free(struct ath5k_softc *sc,
+                               struct pci_dev *pdev);
+/* Buffers setup */
+static int     ath5k_rxbuf_setup(struct ath5k_softc *sc,
+                               struct ath5k_buf *bf);
+static int     ath5k_txbuf_setup(struct ath5k_softc *sc,
+                               struct ath5k_buf *bf);
+static inline void ath5k_txbuf_free(struct ath5k_softc *sc,
+                               struct ath5k_buf *bf)
+{
+       BUG_ON(!bf);
+       if (!bf->skb)
+               return;
+       pci_unmap_single(sc->pdev, bf->skbaddr, bf->skb->len,
+                       PCI_DMA_TODEVICE);
+       dev_kfree_skb_any(bf->skb);
+       bf->skb = NULL;
+}
+
+static inline void ath5k_rxbuf_free(struct ath5k_softc *sc,
+                               struct ath5k_buf *bf)
+{
+       BUG_ON(!bf);
+       if (!bf->skb)
+               return;
+       pci_unmap_single(sc->pdev, bf->skbaddr, sc->rxbufsize,
+                       PCI_DMA_FROMDEVICE);
+       dev_kfree_skb_any(bf->skb);
+       bf->skb = NULL;
+}
+
+
+/* Queues setup */
+static struct  ath5k_txq *ath5k_txq_setup(struct ath5k_softc *sc,
+                               int qtype, int subtype);
+static int     ath5k_beaconq_setup(struct ath5k_hw *ah);
+static int     ath5k_beaconq_config(struct ath5k_softc *sc);
+static void    ath5k_txq_drainq(struct ath5k_softc *sc,
+                               struct ath5k_txq *txq);
+static void    ath5k_txq_cleanup(struct ath5k_softc *sc);
+static void    ath5k_txq_release(struct ath5k_softc *sc);
+/* Rx handling */
+static int     ath5k_rx_start(struct ath5k_softc *sc);
+static void    ath5k_rx_stop(struct ath5k_softc *sc);
+static unsigned int ath5k_rx_decrypted(struct ath5k_softc *sc,
+                                       struct ath5k_desc *ds,
+                                       struct sk_buff *skb,
+                                       struct ath5k_rx_status *rs);
+static void    ath5k_tasklet_rx(unsigned long data);
+/* Tx handling */
+static void    ath5k_tx_processq(struct ath5k_softc *sc,
+                               struct ath5k_txq *txq);
+static void    ath5k_tasklet_tx(unsigned long data);
+/* Beacon handling */
+static int     ath5k_beacon_setup(struct ath5k_softc *sc,
+                                       struct ath5k_buf *bf);
+static void    ath5k_beacon_send(struct ath5k_softc *sc);
+static void    ath5k_beacon_config(struct ath5k_softc *sc);
+static void    ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf);
+static void    ath5k_tasklet_beacon(unsigned long data);
+
+static inline u64 ath5k_extend_tsf(struct ath5k_hw *ah, u32 rstamp)
+{
+       u64 tsf = ath5k_hw_get_tsf64(ah);
+
+       if ((tsf & 0x7fff) < rstamp)
+               tsf -= 0x8000;
+
+       return (tsf & ~0x7fff) | rstamp;
+}
+
+/* Interrupt handling */
+static int     ath5k_init(struct ath5k_softc *sc);
+static int     ath5k_stop_locked(struct ath5k_softc *sc);
+static int     ath5k_stop_hw(struct ath5k_softc *sc);
+static irqreturn_t ath5k_intr(int irq, void *dev_id);
+static void    ath5k_tasklet_reset(unsigned long data);
+
+static void    ath5k_calibrate(unsigned long data);
+
+/*
+ * Module init/exit functions
+ */
+static int __init
+init_ath5k_pci(void)
+{
+       int ret;
+
+       ath5k_debug_init();
+
+       ret = pci_register_driver(&ath5k_pci_driver);
+       if (ret) {
+               printk(KERN_ERR "ath5k_pci: can't register pci driver\n");
+               return ret;
+       }
+
+       return 0;
+}
+
+static void __exit
+exit_ath5k_pci(void)
+{
+       pci_unregister_driver(&ath5k_pci_driver);
+
+       ath5k_debug_finish();
+}
+
+module_init(init_ath5k_pci);
+module_exit(exit_ath5k_pci);
+
+
+/********************\
+* PCI Initialization *
+\********************/
+
+static const char *
+ath5k_chip_name(enum ath5k_srev_type type, u_int16_t val)
+{
+       const char *name = "xxxxx";
+       unsigned int i;
+
+       for (i = 0; i < ARRAY_SIZE(srev_names); i++) {
+               if (srev_names[i].sr_type != type)
+                       continue;
+
+               if ((val & 0xf0) == srev_names[i].sr_val)
+                       name = srev_names[i].sr_name;
+
+               if ((val & 0xff) == srev_names[i].sr_val) {
+                       name = srev_names[i].sr_name;
+                       break;
+               }
+       }
+
+       return name;
+}
+
+static int __devinit
+ath5k_pci_probe(struct pci_dev *pdev,
+               const struct pci_device_id *id)
+{
+       void __iomem *mem;
+       struct ath5k_softc *sc;
+       struct ieee80211_hw *hw;
+       int ret;
+       u8 csz;
+
+       ret = pci_enable_device(pdev);
+       if (ret) {
+               dev_err(&pdev->dev, "can't enable device\n");
+               goto err;
+       }
+
+       /* XXX 32-bit addressing only */
+       ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+       if (ret) {
+               dev_err(&pdev->dev, "32-bit DMA not available\n");
+               goto err_dis;
+       }
+
+       /*
+        * Cache line size is used to size and align various
+        * structures used to communicate with the hardware.
+        */
+       pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &csz);
+       if (csz == 0) {
+               /*
+                * Linux 2.4.18 (at least) writes the cache line size
+                * register as a 16-bit wide register which is wrong.
+                * We must have this setup properly for rx buffer
+                * DMA to work so force a reasonable value here if it
+                * comes up zero.
+                */
+               csz = L1_CACHE_BYTES / sizeof(u32);
+               pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz);
+       }
+       /*
+        * The default setting of latency timer yields poor results,
+        * set it to the value used by other systems.  It may be worth
+        * tweaking this setting more.
+        */
+       pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xa8);
+
+       /* Enable bus mastering */
+       pci_set_master(pdev);
+
+       /*
+        * Disable the RETRY_TIMEOUT register (0x41) to keep
+        * PCI Tx retries from interfering with C3 CPU state.
+        */
+       pci_write_config_byte(pdev, 0x41, 0);
+
+       ret = pci_request_region(pdev, 0, "ath5k");
+       if (ret) {
+               dev_err(&pdev->dev, "cannot reserve PCI memory region\n");
+               goto err_dis;
+       }
+
+       mem = pci_iomap(pdev, 0, 0);
+       if (!mem) {
+               dev_err(&pdev->dev, "cannot remap PCI memory region\n") ;
+               ret = -EIO;
+               goto err_reg;
+       }
+
+       /*
+        * Allocate hw (mac80211 main struct)
+        * and hw->priv (driver private data)
+        */
+       hw = ieee80211_alloc_hw(sizeof(*sc), &ath5k_hw_ops);
+       if (hw == NULL) {
+               dev_err(&pdev->dev, "cannot allocate ieee80211_hw\n");
+               ret = -ENOMEM;
+               goto err_map;
+       }
+
+       dev_info(&pdev->dev, "registered as '%s'\n", wiphy_name(hw->wiphy));
+
+       /* Initialize driver private data */
+       SET_IEEE80211_DEV(hw, &pdev->dev);
+       hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
+                   IEEE80211_HW_SIGNAL_DBM |
+                   IEEE80211_HW_NOISE_DBM;
+
+       hw->wiphy->interface_modes =
+               BIT(NL80211_IFTYPE_AP) |
+               BIT(NL80211_IFTYPE_STATION) |
+               BIT(NL80211_IFTYPE_ADHOC) |
+               BIT(NL80211_IFTYPE_MESH_POINT);
+
+       hw->extra_tx_headroom = 2;
+       hw->channel_change_time = 5000;
+       sc = hw->priv;
+       sc->hw = hw;
+       sc->pdev = pdev;
+
+       ath5k_debug_init_device(sc);
+
+       /*
+        * Mark the device as detached to avoid processing
+        * interrupts until setup is complete.
+        */
+       __set_bit(ATH_STAT_INVALID, sc->status);
+
+       sc->iobase = mem; /* So we can unmap it on detach */
+       sc->cachelsz = csz * sizeof(u32); /* convert to bytes */
+       sc->opmode = NL80211_IFTYPE_STATION;
+       mutex_init(&sc->lock);
+       spin_lock_init(&sc->rxbuflock);
+       spin_lock_init(&sc->txbuflock);
+       spin_lock_init(&sc->block);
+
+       /* Set private data */
+       pci_set_drvdata(pdev, hw);
+
+       /* Setup interrupt handler */
+       ret = request_irq(pdev->irq, ath5k_intr, IRQF_SHARED, "ath", sc);
+       if (ret) {
+               ATH5K_ERR(sc, "request_irq failed\n");
+               goto err_free;
+       }
+
+       /* Initialize device */
+       sc->ah = ath5k_hw_attach(sc, id->driver_data);
+       if (IS_ERR(sc->ah)) {
+               ret = PTR_ERR(sc->ah);
+               goto err_irq;
+       }
+
+       /* set up multi-rate retry capabilities */
+       if (sc->ah->ah_version == AR5K_AR5212) {
+               hw->max_rates = 4;
+               hw->max_rate_tries = 11;
+       }
+
+       /* Finish private driver data initialization */
+       ret = ath5k_attach(pdev, hw);
+       if (ret)
+               goto err_ah;
+
+       ATH5K_INFO(sc, "Atheros AR%s chip found (MAC: 0x%x, PHY: 0x%x)\n",
+                       ath5k_chip_name(AR5K_VERSION_MAC, sc->ah->ah_mac_srev),
+                                       sc->ah->ah_mac_srev,
+                                       sc->ah->ah_phy_revision);
+
+       if (!sc->ah->ah_single_chip) {
+               /* Single chip radio (!RF5111) */
+               if (sc->ah->ah_radio_5ghz_revision &&
+                       !sc->ah->ah_radio_2ghz_revision) {
+                       /* No 5GHz support -> report 2GHz radio */
+                       if (!test_bit(AR5K_MODE_11A,
+                               sc->ah->ah_capabilities.cap_mode)) {
+                               ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n",
+                                       ath5k_chip_name(AR5K_VERSION_RAD,
+                                               sc->ah->ah_radio_5ghz_revision),
+                                               sc->ah->ah_radio_5ghz_revision);
+                       /* No 2GHz support (5110 and some
+                        * 5Ghz only cards) -> report 5Ghz radio */
+                       } else if (!test_bit(AR5K_MODE_11B,
+                               sc->ah->ah_capabilities.cap_mode)) {
+                               ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n",
+                                       ath5k_chip_name(AR5K_VERSION_RAD,
+                                               sc->ah->ah_radio_5ghz_revision),
+                                               sc->ah->ah_radio_5ghz_revision);
+                       /* Multiband radio */
+                       } else {
+                               ATH5K_INFO(sc, "RF%s multiband radio found"
+                                       " (0x%x)\n",
+                                       ath5k_chip_name(AR5K_VERSION_RAD,
+                                               sc->ah->ah_radio_5ghz_revision),
+                                               sc->ah->ah_radio_5ghz_revision);
+                       }
+               }
+               /* Multi chip radio (RF5111 - RF2111) ->
+                * report both 2GHz/5GHz radios */
+               else if (sc->ah->ah_radio_5ghz_revision &&
+                               sc->ah->ah_radio_2ghz_revision){
+                       ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n",
+                               ath5k_chip_name(AR5K_VERSION_RAD,
+                                       sc->ah->ah_radio_5ghz_revision),
+                                       sc->ah->ah_radio_5ghz_revision);
+                       ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n",
+                               ath5k_chip_name(AR5K_VERSION_RAD,
+                                       sc->ah->ah_radio_2ghz_revision),
+                                       sc->ah->ah_radio_2ghz_revision);
+               }
+       }
+
+
+       /* ready to process interrupts */
+       __clear_bit(ATH_STAT_INVALID, sc->status);
+
+       return 0;
+err_ah:
+       ath5k_hw_detach(sc->ah);
+err_irq:
+       free_irq(pdev->irq, sc);
+err_free:
+       ieee80211_free_hw(hw);
+err_map:
+       pci_iounmap(pdev, mem);
+err_reg:
+       pci_release_region(pdev, 0);
+err_dis:
+       pci_disable_device(pdev);
+err:
+       return ret;
+}
+
+static void __devexit
+ath5k_pci_remove(struct pci_dev *pdev)
+{
+       struct ieee80211_hw *hw = pci_get_drvdata(pdev);
+       struct ath5k_softc *sc = hw->priv;
+
+       ath5k_debug_finish_device(sc);
+       ath5k_detach(pdev, hw);
+       ath5k_hw_detach(sc->ah);
+       free_irq(pdev->irq, sc);
+       pci_iounmap(pdev, sc->iobase);
+       pci_release_region(pdev, 0);
+       pci_disable_device(pdev);
+       ieee80211_free_hw(hw);
+}
+
+#ifdef CONFIG_PM
+static int
+ath5k_pci_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+       struct ieee80211_hw *hw = pci_get_drvdata(pdev);
+       struct ath5k_softc *sc = hw->priv;
+
+       ath5k_led_off(sc);
+
+       free_irq(pdev->irq, sc);
+       pci_save_state(pdev);
+       pci_disable_device(pdev);
+       pci_set_power_state(pdev, PCI_D3hot);
+
+       return 0;
+}
+
+static int
+ath5k_pci_resume(struct pci_dev *pdev)
+{
+       struct ieee80211_hw *hw = pci_get_drvdata(pdev);
+       struct ath5k_softc *sc = hw->priv;
+       int err;
+
+       pci_restore_state(pdev);
+
+       err = pci_enable_device(pdev);
+       if (err)
+               return err;
+
+       err = request_irq(pdev->irq, ath5k_intr, IRQF_SHARED, "ath", sc);
+       if (err) {
+               ATH5K_ERR(sc, "request_irq failed\n");
+               goto err_no_irq;
+       }
+
+       ath5k_led_enable(sc);
+       return 0;
+
+err_no_irq:
+       pci_disable_device(pdev);
+       return err;
+}
+#endif /* CONFIG_PM */
+
+
+/***********************\
+* Driver Initialization *
+\***********************/
+
+static int ath5k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request)
+{
+       struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
+       struct ath5k_softc *sc = hw->priv;
+       struct ath_regulatory *reg = &sc->ah->ah_regulatory;
+
+       return ath_reg_notifier_apply(wiphy, request, reg);
+}
+
+static int
+ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
+{
+       struct ath5k_softc *sc = hw->priv;
+       struct ath5k_hw *ah = sc->ah;
+       u8 mac[ETH_ALEN] = {};
+       int ret;
+
+       ATH5K_DBG(sc, ATH5K_DEBUG_ANY, "devid 0x%x\n", pdev->device);
+
+       /*
+        * Check if the MAC has multi-rate retry support.
+        * We do this by trying to setup a fake extended
+        * descriptor.  MAC's that don't have support will
+        * return false w/o doing anything.  MAC's that do
+        * support it will return true w/o doing anything.
+        */
+       ret = ah->ah_setup_mrr_tx_desc(ah, NULL, 0, 0, 0, 0, 0, 0);
+       if (ret < 0)
+               goto err;
+       if (ret > 0)
+               __set_bit(ATH_STAT_MRRETRY, sc->status);
+
+       /*
+        * Collect the channel list.  The 802.11 layer
+        * is resposible for filtering this list based
+        * on settings like the phy mode and regulatory
+        * domain restrictions.
+        */
+       ret = ath5k_setup_bands(hw);
+       if (ret) {
+               ATH5K_ERR(sc, "can't get channels\n");
+               goto err;
+       }
+
+       /* NB: setup here so ath5k_rate_update is happy */
+       if (test_bit(AR5K_MODE_11A, ah->ah_modes))
+               ath5k_setcurmode(sc, AR5K_MODE_11A);
+       else
+               ath5k_setcurmode(sc, AR5K_MODE_11B);
+
+       /*
+        * Allocate tx+rx descriptors and populate the lists.
+        */
+       ret = ath5k_desc_alloc(sc, pdev);
+       if (ret) {
+               ATH5K_ERR(sc, "can't allocate descriptors\n");
+               goto err;
+       }
+
+       /*
+        * Allocate hardware transmit queues: one queue for
+        * beacon frames and one data queue for each QoS
+        * priority.  Note that hw functions handle reseting
+        * these queues at the needed time.
+        */
+       ret = ath5k_beaconq_setup(ah);
+       if (ret < 0) {
+               ATH5K_ERR(sc, "can't setup a beacon xmit queue\n");
+               goto err_desc;
+       }
+       sc->bhalq = ret;
+
+       sc->txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_BK);
+       if (IS_ERR(sc->txq)) {
+               ATH5K_ERR(sc, "can't setup xmit queue\n");
+               ret = PTR_ERR(sc->txq);
+               goto err_bhal;
+       }
+
+       tasklet_init(&sc->rxtq, ath5k_tasklet_rx, (unsigned long)sc);
+       tasklet_init(&sc->txtq, ath5k_tasklet_tx, (unsigned long)sc);
+       tasklet_init(&sc->restq, ath5k_tasklet_reset, (unsigned long)sc);
+       tasklet_init(&sc->beacontq, ath5k_tasklet_beacon, (unsigned long)sc);
+       setup_timer(&sc->calib_tim, ath5k_calibrate, (unsigned long)sc);
+
+       ret = ath5k_eeprom_read_mac(ah, mac);
+       if (ret) {
+               ATH5K_ERR(sc, "unable to read address from EEPROM: 0x%04x\n",
+                       sc->pdev->device);
+               goto err_queues;
+       }
+
+       SET_IEEE80211_PERM_ADDR(hw, mac);
+       /* All MAC address bits matter for ACKs */
+       memset(sc->bssidmask, 0xff, ETH_ALEN);
+       ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask);
+
+       ah->ah_regulatory.current_rd =
+               ah->ah_capabilities.cap_eeprom.ee_regdomain;
+       ret = ath_regd_init(&ah->ah_regulatory, hw->wiphy, ath5k_reg_notifier);
+       if (ret) {
+               ATH5K_ERR(sc, "can't initialize regulatory system\n");
+               goto err_queues;
+       }
+
+       ret = ieee80211_register_hw(hw);
+       if (ret) {
+               ATH5K_ERR(sc, "can't register ieee80211 hw\n");
+               goto err_queues;
+       }
+
+       if (!ath_is_world_regd(&sc->ah->ah_regulatory))
+               regulatory_hint(hw->wiphy, sc->ah->ah_regulatory.alpha2);
+
+       ath5k_init_leds(sc);
+
+       return 0;
+err_queues:
+       ath5k_txq_release(sc);
+err_bhal:
+       ath5k_hw_release_tx_queue(ah, sc->bhalq);
+err_desc:
+       ath5k_desc_free(sc, pdev);
+err:
+       return ret;
+}
+
+static void
+ath5k_detach(struct pci_dev *pdev, struct ieee80211_hw *hw)
+{
+       struct ath5k_softc *sc = hw->priv;
+
+       /*
+        * NB: the order of these is important:
+        * o call the 802.11 layer before detaching ath5k_hw to
+        *   insure callbacks into the driver to delete global
+        *   key cache entries can be handled
+        * o reclaim the tx queue data structures after calling
+        *   the 802.11 layer as we'll get called back to reclaim
+        *   node state and potentially want to use them
+        * o to cleanup the tx queues the hal is called, so detach
+        *   it last
+        * XXX: ??? detach ath5k_hw ???
+        * Other than that, it's straightforward...
+        */
+       ieee80211_unregister_hw(hw);
+       ath5k_desc_free(sc, pdev);
+       ath5k_txq_release(sc);
+       ath5k_hw_release_tx_queue(sc->ah, sc->bhalq);
+       ath5k_unregister_leds(sc);
+
+       /*
+        * NB: can't reclaim these until after ieee80211_ifdetach
+        * returns because we'll get called back to reclaim node
+        * state and potentially want to use them.
+        */
+}
+
+
+
+
+/********************\
+* Channel/mode setup *
+\********************/
+
+/*
+ * Convert IEEE channel number to MHz frequency.
+ */
+static inline short
+ath5k_ieee2mhz(short chan)
+{
+       if (chan <= 14 || chan >= 27)
+               return ieee80211chan2mhz(chan);
+       else
+               return 2212 + chan * 20;
+}
+
+/*
+ * Returns true for the channel numbers used without all_channels modparam.
+ */
+static bool ath5k_is_standard_channel(short chan)
+{
+       return ((chan <= 14) ||
+               /* UNII 1,2 */
+               ((chan & 3) == 0 && chan >= 36 && chan <= 64) ||
+               /* midband */
+               ((chan & 3) == 0 && chan >= 100 && chan <= 140) ||
+               /* UNII-3 */
+               ((chan & 3) == 1 && chan >= 149 && chan <= 165));
+}
+
+static unsigned int
+ath5k_copy_channels(struct ath5k_hw *ah,
+               struct ieee80211_channel *channels,
+               unsigned int mode,
+               unsigned int max)
+{
+       unsigned int i, count, size, chfreq, freq, ch;
+
+       if (!test_bit(mode, ah->ah_modes))
+               return 0;
+
+       switch (mode) {
+       case AR5K_MODE_11A:
+       case AR5K_MODE_11A_TURBO:
+               /* 1..220, but 2GHz frequencies are filtered by check_channel */
+               size = 220 ;
+               chfreq = CHANNEL_5GHZ;
+               break;
+       case AR5K_MODE_11B:
+       case AR5K_MODE_11G:
+       case AR5K_MODE_11G_TURBO:
+               size = 26;
+               chfreq = CHANNEL_2GHZ;
+               break;
+       default:
+               ATH5K_WARN(ah->ah_sc, "bad mode, not copying channels\n");
+               return 0;
+       }
+
+       for (i = 0, count = 0; i < size && max > 0; i++) {
+               ch = i + 1 ;
+               freq = ath5k_ieee2mhz(ch);
+
+               /* Check if channel is supported by the chipset */
+               if (!ath5k_channel_ok(ah, freq, chfreq))
+                       continue;
+
+               if (!modparam_all_channels && !ath5k_is_standard_channel(ch))
+                       continue;
+
+               /* Write channel info and increment counter */
+               channels[count].center_freq = freq;
+               channels[count].band = (chfreq == CHANNEL_2GHZ) ?
+                       IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
+               switch (mode) {
+               case AR5K_MODE_11A:
+               case AR5K_MODE_11G:
+                       channels[count].hw_value = chfreq | CHANNEL_OFDM;
+                       break;
+               case AR5K_MODE_11A_TURBO:
+               case AR5K_MODE_11G_TURBO:
+                       channels[count].hw_value = chfreq |
+                               CHANNEL_OFDM | CHANNEL_TURBO;
+                       break;
+               case AR5K_MODE_11B:
+                       channels[count].hw_value = CHANNEL_B;
+               }
+
+               count++;
+               max--;
+       }
+
+       return count;
+}
+
+static void
+ath5k_setup_rate_idx(struct ath5k_softc *sc, struct ieee80211_supported_band *b)
+{
+       u8 i;
+
+       for (i = 0; i < AR5K_MAX_RATES; i++)
+               sc->rate_idx[b->band][i] = -1;
+
+       for (i = 0; i < b->n_bitrates; i++) {
+               sc->rate_idx[b->band][b->bitrates[i].hw_value] = i;
+               if (b->bitrates[i].hw_value_short)
+                       sc->rate_idx[b->band][b->bitrates[i].hw_value_short] = i;
+       }
+}
+
+static int
+ath5k_setup_bands(struct ieee80211_hw *hw)
+{
+       struct ath5k_softc *sc = hw->priv;
+       struct ath5k_hw *ah = sc->ah;
+       struct ieee80211_supported_band *sband;
+       int max_c, count_c = 0;
+       int i;
+
+       BUILD_BUG_ON(ARRAY_SIZE(sc->sbands) < IEEE80211_NUM_BANDS);
+       max_c = ARRAY_SIZE(sc->channels);
+
+       /* 2GHz band */
+       sband = &sc->sbands[IEEE80211_BAND_2GHZ];
+       sband->band = IEEE80211_BAND_2GHZ;
+       sband->bitrates = &sc->rates[IEEE80211_BAND_2GHZ][0];
+
+       if (test_bit(AR5K_MODE_11G, sc->ah->ah_capabilities.cap_mode)) {
+               /* G mode */
+               memcpy(sband->bitrates, &ath5k_rates[0],
+                      sizeof(struct ieee80211_rate) * 12);
+               sband->n_bitrates = 12;
+
+               sband->channels = sc->channels;
+               sband->n_channels = ath5k_copy_channels(ah, sband->channels,
+                                       AR5K_MODE_11G, max_c);
+
+               hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband;
+               count_c = sband->n_channels;
+               max_c -= count_c;
+       } else if (test_bit(AR5K_MODE_11B, sc->ah->ah_capabilities.cap_mode)) {
+               /* B mode */
+               memcpy(sband->bitrates, &ath5k_rates[0],
+                      sizeof(struct ieee80211_rate) * 4);
+               sband->n_bitrates = 4;
+
+               /* 5211 only supports B rates and uses 4bit rate codes
+                * (e.g normally we have 0x1B for 1M, but on 5211 we have 0x0B)
+                * fix them up here:
+                */
+               if (ah->ah_version == AR5K_AR5211) {
+                       for (i = 0; i < 4; i++) {
+                               sband->bitrates[i].hw_value =
+                                       sband->bitrates[i].hw_value & 0xF;
+                               sband->bitrates[i].hw_value_short =
+                                       sband->bitrates[i].hw_value_short & 0xF;
+                       }
+               }
+
+               sband->channels = sc->channels;
+               sband->n_channels = ath5k_copy_channels(ah, sband->channels,
+                                       AR5K_MODE_11B, max_c);
+
+               hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband;
+               count_c = sband->n_channels;
+               max_c -= count_c;
+       }
+       ath5k_setup_rate_idx(sc, sband);
+
+       /* 5GHz band, A mode */
+       if (test_bit(AR5K_MODE_11A, sc->ah->ah_capabilities.cap_mode)) {
+               sband = &sc->sbands[IEEE80211_BAND_5GHZ];
+               sband->band = IEEE80211_BAND_5GHZ;
+               sband->bitrates = &sc->rates[IEEE80211_BAND_5GHZ][0];
+
+               memcpy(sband->bitrates, &ath5k_rates[4],
+                      sizeof(struct ieee80211_rate) * 8);
+               sband->n_bitrates = 8;
+
+               sband->channels = &sc->channels[count_c];
+               sband->n_channels = ath5k_copy_channels(ah, sband->channels,
+                                       AR5K_MODE_11A, max_c);
+
+               hw->wiphy->bands[IEEE80211_BAND_5GHZ] = sband;
+       }
+       ath5k_setup_rate_idx(sc, sband);
+
+       ath5k_debug_dump_bands(sc);
+
+       return 0;
+}
+
+/*
+ * Set/change channels.  If the channel is really being changed,
+ * it's done by reseting the chip.  To accomplish this we must
+ * first cleanup any pending DMA, then restart stuff after a la
+ * ath5k_init.
+ *
+ * Called with sc->lock.
+ */
+static int
+ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan)
+{
+       ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "(%u MHz) -> (%u MHz)\n",
+               sc->curchan->center_freq, chan->center_freq);
+
+       if (chan->center_freq != sc->curchan->center_freq ||
+               chan->hw_value != sc->curchan->hw_value) {
+
+               /*
+                * To switch channels clear any pending DMA operations;
+                * wait long enough for the RX fifo to drain, reset the
+                * hardware at the new frequency, and then re-enable
+                * the relevant bits of the h/w.
+                */
+               return ath5k_reset(sc, chan);
+       }
+
+       return 0;
+}
+
+static void
+ath5k_setcurmode(struct ath5k_softc *sc, unsigned int mode)
+{
+       sc->curmode = mode;
+
+       if (mode == AR5K_MODE_11A) {
+               sc->curband = &sc->sbands[IEEE80211_BAND_5GHZ];
+       } else {
+               sc->curband = &sc->sbands[IEEE80211_BAND_2GHZ];
+       }
+}
+
+static void
+ath5k_mode_setup(struct ath5k_softc *sc)
+{
+       struct ath5k_hw *ah = sc->ah;
+       u32 rfilt;
+
+       /* configure rx filter */
+       rfilt = sc->filter_flags;
+       ath5k_hw_set_rx_filter(ah, rfilt);
+
+       if (ath5k_hw_hasbssidmask(ah))
+               ath5k_hw_set_bssid_mask(ah, sc->bssidmask);
+
+       /* configure operational mode */
+       ath5k_hw_set_opmode(ah);
+
+       ath5k_hw_set_mcast_filter(ah, 0, 0);
+       ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "RX filter 0x%x\n", rfilt);
+}
+
+static inline int
+ath5k_hw_to_driver_rix(struct ath5k_softc *sc, int hw_rix)
+{
+       int rix;
+
+       /* return base rate on errors */
+       if (WARN(hw_rix < 0 || hw_rix >= AR5K_MAX_RATES,
+                       "hw_rix out of bounds: %x\n", hw_rix))
+               return 0;
+
+       rix = sc->rate_idx[sc->curband->band][hw_rix];
+       if (WARN(rix < 0, "invalid hw_rix: %x\n", hw_rix))
+               rix = 0;
+
+       return rix;
+}
+
+/***************\
+* Buffers setup *
+\***************/
+
+static
+struct sk_buff *ath5k_rx_skb_alloc(struct ath5k_softc *sc, dma_addr_t *skb_addr)
+{
+       struct sk_buff *skb;
+       unsigned int off;
+
+       /*
+        * Allocate buffer with headroom_needed space for the
+        * fake physical layer header at the start.
+        */
+       skb = dev_alloc_skb(sc->rxbufsize + sc->cachelsz - 1);
+
+       if (!skb) {
+               ATH5K_ERR(sc, "can't alloc skbuff of size %u\n",
+                               sc->rxbufsize + sc->cachelsz - 1);
+               return NULL;
+       }
+       /*
+        * Cache-line-align.  This is important (for the
+        * 5210 at least) as not doing so causes bogus data
+        * in rx'd frames.
+        */
+       off = ((unsigned long)skb->data) % sc->cachelsz;
+       if (off != 0)
+               skb_reserve(skb, sc->cachelsz - off);
+
+       *skb_addr = pci_map_single(sc->pdev,
+               skb->data, sc->rxbufsize, PCI_DMA_FROMDEVICE);
+       if (unlikely(pci_dma_mapping_error(sc->pdev, *skb_addr))) {
+               ATH5K_ERR(sc, "%s: DMA mapping failed\n", __func__);
+               dev_kfree_skb(skb);
+               return NULL;
+       }
+       return skb;
+}
+
+static int
+ath5k_rxbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
+{
+       struct ath5k_hw *ah = sc->ah;
+       struct sk_buff *skb = bf->skb;
+       struct ath5k_desc *ds;
+
+       if (!skb) {
+               skb = ath5k_rx_skb_alloc(sc, &bf->skbaddr);
+               if (!skb)
+                       return -ENOMEM;
+               bf->skb = skb;
+       }
+
+       /*
+        * Setup descriptors.  For receive we always terminate
+        * the descriptor list with a self-linked entry so we'll
+        * not get overrun under high load (as can happen with a
+        * 5212 when ANI processing enables PHY error frames).
+        *
+        * To insure the last descriptor is self-linked we create
+        * each descriptor as self-linked and add it to the end.  As
+        * each additional descriptor is added the previous self-linked
+        * entry is ``fixed'' naturally.  This should be safe even
+        * if DMA is happening.  When processing RX interrupts we
+        * never remove/process the last, self-linked, entry on the
+        * descriptor list.  This insures the hardware always has
+        * someplace to write a new frame.
+        */
+       ds = bf->desc;
+       ds->ds_link = bf->daddr;        /* link to self */
+       ds->ds_data = bf->skbaddr;
+       ah->ah_setup_rx_desc(ah, ds,
+               skb_tailroom(skb),      /* buffer size */
+               0);
+
+       if (sc->rxlink != NULL)
+               *sc->rxlink = bf->daddr;
+       sc->rxlink = &ds->ds_link;
+       return 0;
+}
+
+static int
+ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
+{
+       struct ath5k_hw *ah = sc->ah;
+       struct ath5k_txq *txq = sc->txq;
+       struct ath5k_desc *ds = bf->desc;
+       struct sk_buff *skb = bf->skb;
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+       unsigned int pktlen, flags, keyidx = AR5K_TXKEYIX_INVALID;
+       struct ieee80211_rate *rate;
+       unsigned int mrr_rate[3], mrr_tries[3];
+       int i, ret;
+       u16 hw_rate;
+       u16 cts_rate = 0;
+       u16 duration = 0;
+       u8 rc_flags;
+
+       flags = AR5K_TXDESC_INTREQ | AR5K_TXDESC_CLRDMASK;
+
+       /* XXX endianness */
+       bf->skbaddr = pci_map_single(sc->pdev, skb->data, skb->len,
+                       PCI_DMA_TODEVICE);
+
+       rate = ieee80211_get_tx_rate(sc->hw, info);
+
+       if (info->flags & IEEE80211_TX_CTL_NO_ACK)
+               flags |= AR5K_TXDESC_NOACK;
+
+       rc_flags = info->control.rates[0].flags;
+       hw_rate = (rc_flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) ?
+               rate->hw_value_short : rate->hw_value;
+
+       pktlen = skb->len;
+
+       /* FIXME: If we are in g mode and rate is a CCK rate
+        * subtract ah->ah_txpower.txp_cck_ofdm_pwr_delta
+        * from tx power (value is in dB units already) */
+       if (info->control.hw_key) {
+               keyidx = info->control.hw_key->hw_key_idx;
+               pktlen += info->control.hw_key->icv_len;
+       }
+       if (rc_flags & IEEE80211_TX_RC_USE_RTS_CTS) {
+               flags |= AR5K_TXDESC_RTSENA;
+               cts_rate = ieee80211_get_rts_cts_rate(sc->hw, info)->hw_value;
+               duration = le16_to_cpu(ieee80211_rts_duration(sc->hw,
+                       sc->vif, pktlen, info));
+       }
+       if (rc_flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
+               flags |= AR5K_TXDESC_CTSENA;
+               cts_rate = ieee80211_get_rts_cts_rate(sc->hw, info)->hw_value;
+               duration = le16_to_cpu(ieee80211_ctstoself_duration(sc->hw,
+                       sc->vif, pktlen, info));
+       }
+       ret = ah->ah_setup_tx_desc(ah, ds, pktlen,
+               ieee80211_get_hdrlen_from_skb(skb), AR5K_PKT_TYPE_NORMAL,
+               (sc->power_level * 2),
+               hw_rate,
+               info->control.rates[0].count, keyidx, ah->ah_tx_ant, flags,
+               cts_rate, duration);
+       if (ret)
+               goto err_unmap;
+
+       memset(mrr_rate, 0, sizeof(mrr_rate));
+       memset(mrr_tries, 0, sizeof(mrr_tries));
+       for (i = 0; i < 3; i++) {
+               rate = ieee80211_get_alt_retry_rate(sc->hw, info, i);
+               if (!rate)
+                       break;
+
+               mrr_rate[i] = rate->hw_value;
+               mrr_tries[i] = info->control.rates[i + 1].count;
+       }
+
+       ah->ah_setup_mrr_tx_desc(ah, ds,
+               mrr_rate[0], mrr_tries[0],
+               mrr_rate[1], mrr_tries[1],
+               mrr_rate[2], mrr_tries[2]);
+
+       ds->ds_link = 0;
+       ds->ds_data = bf->skbaddr;
+
+       spin_lock_bh(&txq->lock);
+       list_add_tail(&bf->list, &txq->q);
+       sc->tx_stats[txq->qnum].len++;
+       if (txq->link == NULL) /* is this first packet? */
+               ath5k_hw_set_txdp(ah, txq->qnum, bf->daddr);
+       else /* no, so only link it */
+               *txq->link = bf->daddr;
+
+       txq->link = &ds->ds_link;
+       ath5k_hw_start_tx_dma(ah, txq->qnum);
+       mmiowb();
+       spin_unlock_bh(&txq->lock);
+
+       return 0;
+err_unmap:
+       pci_unmap_single(sc->pdev, bf->skbaddr, skb->len, PCI_DMA_TODEVICE);
+       return ret;
+}
+
+/*******************\
+* Descriptors setup *
+\*******************/
+
+static int
+ath5k_desc_alloc(struct ath5k_softc *sc, struct pci_dev *pdev)
+{
+       struct ath5k_desc *ds;
+       struct ath5k_buf *bf;
+       dma_addr_t da;
+       unsigned int i;
+       int ret;
+
+       /* allocate descriptors */
+       sc->desc_len = sizeof(struct ath5k_desc) *
+                       (ATH_TXBUF + ATH_RXBUF + ATH_BCBUF + 1);
+       sc->desc = pci_alloc_consistent(pdev, sc->desc_len, &sc->desc_daddr);
+       if (sc->desc == NULL) {
+               ATH5K_ERR(sc, "can't allocate descriptors\n");
+               ret = -ENOMEM;
+               goto err;
+       }
+       ds = sc->desc;
+       da = sc->desc_daddr;
+       ATH5K_DBG(sc, ATH5K_DEBUG_ANY, "DMA map: %p (%zu) -> %llx\n",
+               ds, sc->desc_len, (unsigned long long)sc->desc_daddr);
+
+       bf = kcalloc(1 + ATH_TXBUF + ATH_RXBUF + ATH_BCBUF,
+                       sizeof(struct ath5k_buf), GFP_KERNEL);
+       if (bf == NULL) {
+               ATH5K_ERR(sc, "can't allocate bufptr\n");
+               ret = -ENOMEM;
+               goto err_free;
+       }
+       sc->bufptr = bf;
+
+       INIT_LIST_HEAD(&sc->rxbuf);
+       for (i = 0; i < ATH_RXBUF; i++, bf++, ds++, da += sizeof(*ds)) {
+               bf->desc = ds;
+               bf->daddr = da;
+               list_add_tail(&bf->list, &sc->rxbuf);
+       }
+
+       INIT_LIST_HEAD(&sc->txbuf);
+       sc->txbuf_len = ATH_TXBUF;
+       for (i = 0; i < ATH_TXBUF; i++, bf++, ds++,
+                       da += sizeof(*ds)) {
+               bf->desc = ds;
+               bf->daddr = da;
+               list_add_tail(&bf->list, &sc->txbuf);
+       }
+
+       /* beacon buffer */
+       bf->desc = ds;
+       bf->daddr = da;
+       sc->bbuf = bf;
+
+       return 0;
+err_free:
+       pci_free_consistent(pdev, sc->desc_len, sc->desc, sc->desc_daddr);
+err:
+       sc->desc = NULL;
+       return ret;
+}
+
+static void
+ath5k_desc_free(struct ath5k_softc *sc, struct pci_dev *pdev)
+{
+       struct ath5k_buf *bf;
+
+       ath5k_txbuf_free(sc, sc->bbuf);
+       list_for_each_entry(bf, &sc->txbuf, list)
+               ath5k_txbuf_free(sc, bf);
+       list_for_each_entry(bf, &sc->rxbuf, list)
+               ath5k_rxbuf_free(sc, bf);
+
+       /* Free memory associated with all descriptors */
+       pci_free_consistent(pdev, sc->desc_len, sc->desc, sc->desc_daddr);
+
+       kfree(sc->bufptr);
+       sc->bufptr = NULL;
+}
+
+
+
+
+
+/**************\
+* Queues setup *
+\**************/
+
+static struct ath5k_txq *
+ath5k_txq_setup(struct ath5k_softc *sc,
+               int qtype, int subtype)
+{
+       struct ath5k_hw *ah = sc->ah;
+       struct ath5k_txq *txq;
+       struct ath5k_txq_info qi = {
+               .tqi_subtype = subtype,
+               .tqi_aifs = AR5K_TXQ_USEDEFAULT,
+               .tqi_cw_min = AR5K_TXQ_USEDEFAULT,
+               .tqi_cw_max = AR5K_TXQ_USEDEFAULT
+       };
+       int qnum;
+
+       /*
+        * Enable interrupts only for EOL and DESC conditions.
+        * We mark tx descriptors to receive a DESC interrupt
+        * when a tx queue gets deep; otherwise waiting for the
+        * EOL to reap descriptors.  Note that this is done to
+        * reduce interrupt load and this only defers reaping
+        * descriptors, never transmitting frames.  Aside from
+        * reducing interrupts this also permits more concurrency.
+        * The only potential downside is if the tx queue backs
+        * up in which case the top half of the kernel may backup
+        * due to a lack of tx descriptors.
+        */
+       qi.tqi_flags = AR5K_TXQ_FLAG_TXEOLINT_ENABLE |
+                               AR5K_TXQ_FLAG_TXDESCINT_ENABLE;
+       qnum = ath5k_hw_setup_tx_queue(ah, qtype, &qi);
+       if (qnum < 0) {
+               /*
+                * NB: don't print a message, this happens
+                * normally on parts with too few tx queues
+                */
+               return ERR_PTR(qnum);
+       }
+       if (qnum >= ARRAY_SIZE(sc->txqs)) {
+               ATH5K_ERR(sc, "hw qnum %u out of range, max %tu!\n",
+                       qnum, ARRAY_SIZE(sc->txqs));
+               ath5k_hw_release_tx_queue(ah, qnum);
+               return ERR_PTR(-EINVAL);
+       }
+       txq = &sc->txqs[qnum];
+       if (!txq->setup) {
+               txq->qnum = qnum;
+               txq->link = NULL;
+               INIT_LIST_HEAD(&txq->q);
+               spin_lock_init(&txq->lock);
+               txq->setup = true;
+       }
+       return &sc->txqs[qnum];
+}
+
+static int
+ath5k_beaconq_setup(struct ath5k_hw *ah)
+{
+       struct ath5k_txq_info qi = {
+               .tqi_aifs = AR5K_TXQ_USEDEFAULT,
+               .tqi_cw_min = AR5K_TXQ_USEDEFAULT,
+               .tqi_cw_max = AR5K_TXQ_USEDEFAULT,
+               /* NB: for dynamic turbo, don't enable any other interrupts */
+               .tqi_flags = AR5K_TXQ_FLAG_TXDESCINT_ENABLE
+       };
+
+       return ath5k_hw_setup_tx_queue(ah, AR5K_TX_QUEUE_BEACON, &qi);
+}
+
+static int
+ath5k_beaconq_config(struct ath5k_softc *sc)
+{
+       struct ath5k_hw *ah = sc->ah;
+       struct ath5k_txq_info qi;
+       int ret;
+
+       ret = ath5k_hw_get_tx_queueprops(ah, sc->bhalq, &qi);
+       if (ret)
+               return ret;
+       if (sc->opmode == NL80211_IFTYPE_AP ||
+               sc->opmode == NL80211_IFTYPE_MESH_POINT) {
+               /*
+                * Always burst out beacon and CAB traffic
+                * (aifs = cwmin = cwmax = 0)
+                */
+               qi.tqi_aifs = 0;
+               qi.tqi_cw_min = 0;
+               qi.tqi_cw_max = 0;
+       } else if (sc->opmode == NL80211_IFTYPE_ADHOC) {
+               /*
+                * Adhoc mode; backoff between 0 and (2 * cw_min).
+                */
+               qi.tqi_aifs = 0;
+               qi.tqi_cw_min = 0;
+               qi.tqi_cw_max = 2 * ah->ah_cw_min;
+       }
+
+       ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
+               "beacon queueprops tqi_aifs:%d tqi_cw_min:%d tqi_cw_max:%d\n",
+               qi.tqi_aifs, qi.tqi_cw_min, qi.tqi_cw_max);
+
+       ret = ath5k_hw_set_tx_queueprops(ah, sc->bhalq, &qi);
+       if (ret) {
+               ATH5K_ERR(sc, "%s: unable to update parameters for beacon "
+                       "hardware queue!\n", __func__);
+               return ret;
+       }
+
+       return ath5k_hw_reset_tx_queue(ah, sc->bhalq); /* push to h/w */;
+}
+
+static void
+ath5k_txq_drainq(struct ath5k_softc *sc, struct ath5k_txq *txq)
+{
+       struct ath5k_buf *bf, *bf0;
+
+       /*
+        * NB: this assumes output has been stopped and
+        *     we do not need to block ath5k_tx_tasklet
+        */
+       spin_lock_bh(&txq->lock);
+       list_for_each_entry_safe(bf, bf0, &txq->q, list) {
+               ath5k_debug_printtxbuf(sc, bf);
+
+               ath5k_txbuf_free(sc, bf);
+
+               spin_lock_bh(&sc->txbuflock);
+               sc->tx_stats[txq->qnum].len--;
+               list_move_tail(&bf->list, &sc->txbuf);
+               sc->txbuf_len++;
+               spin_unlock_bh(&sc->txbuflock);
+       }
+       txq->link = NULL;
+       spin_unlock_bh(&txq->lock);
+}
+
+/*
+ * Drain the transmit queues and reclaim resources.
+ */
+static void
+ath5k_txq_cleanup(struct ath5k_softc *sc)
+{
+       struct ath5k_hw *ah = sc->ah;
+       unsigned int i;
+
+       /* XXX return value */
+       if (likely(!test_bit(ATH_STAT_INVALID, sc->status))) {
+               /* don't touch the hardware if marked invalid */
+               ath5k_hw_stop_tx_dma(ah, sc->bhalq);
+               ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "beacon queue %x\n",
+                       ath5k_hw_get_txdp(ah, sc->bhalq));
+               for (i = 0; i < ARRAY_SIZE(sc->txqs); i++)
+                       if (sc->txqs[i].setup) {
+                               ath5k_hw_stop_tx_dma(ah, sc->txqs[i].qnum);
+                               ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "txq [%u] %x, "
+                                       "link %p\n",
+                                       sc->txqs[i].qnum,
+                                       ath5k_hw_get_txdp(ah,
+                                                       sc->txqs[i].qnum),
+                                       sc->txqs[i].link);
+                       }
+       }
+       ieee80211_wake_queues(sc->hw); /* XXX move to callers */
+
+       for (i = 0; i < ARRAY_SIZE(sc->txqs); i++)
+               if (sc->txqs[i].setup)
+                       ath5k_txq_drainq(sc, &sc->txqs[i]);
+}
+
+static void
+ath5k_txq_release(struct ath5k_softc *sc)
+{
+       struct ath5k_txq *txq = sc->txqs;
+       unsigned int i;
+
+       for (i = 0; i < ARRAY_SIZE(sc->txqs); i++, txq++)
+               if (txq->setup) {
+                       ath5k_hw_release_tx_queue(sc->ah, txq->qnum);
+                       txq->setup = false;
+               }
+}
+
+
+
+
+/*************\
+* RX Handling *
+\*************/
+
+/*
+ * Enable the receive h/w following a reset.
+ */
+static int
+ath5k_rx_start(struct ath5k_softc *sc)
+{
+       struct ath5k_hw *ah = sc->ah;
+       struct ath5k_buf *bf;
+       int ret;
+
+       sc->rxbufsize = roundup(IEEE80211_MAX_LEN, sc->cachelsz);
+
+       ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "cachelsz %u rxbufsize %u\n",
+               sc->cachelsz, sc->rxbufsize);
+
+       spin_lock_bh(&sc->rxbuflock);
+       sc->rxlink = NULL;
+       list_for_each_entry(bf, &sc->rxbuf, list) {
+               ret = ath5k_rxbuf_setup(sc, bf);
+               if (ret != 0) {
+                       spin_unlock_bh(&sc->rxbuflock);
+                       goto err;
+               }
+       }
+       bf = list_first_entry(&sc->rxbuf, struct ath5k_buf, list);
+       ath5k_hw_set_rxdp(ah, bf->daddr);
+       spin_unlock_bh(&sc->rxbuflock);
+
+       ath5k_hw_start_rx_dma(ah);      /* enable recv descriptors */
+       ath5k_mode_setup(sc);           /* set filters, etc. */
+       ath5k_hw_start_rx_pcu(ah);      /* re-enable PCU/DMA engine */
+
+       return 0;
+err:
+       return ret;
+}
+
+/*
+ * Disable the receive h/w in preparation for a reset.
+ */
+static void
+ath5k_rx_stop(struct ath5k_softc *sc)
+{
+       struct ath5k_hw *ah = sc->ah;
+
+       ath5k_hw_stop_rx_pcu(ah);       /* disable PCU */
+       ath5k_hw_set_rx_filter(ah, 0);  /* clear recv filter */
+       ath5k_hw_stop_rx_dma(ah);       /* disable DMA engine */
+
+       ath5k_debug_printrxbuffs(sc, ah);
+
+       sc->rxlink = NULL;              /* just in case */
+}
+
+static unsigned int
+ath5k_rx_decrypted(struct ath5k_softc *sc, struct ath5k_desc *ds,
+               struct sk_buff *skb, struct ath5k_rx_status *rs)
+{
+       struct ieee80211_hdr *hdr = (void *)skb->data;
+       unsigned int keyix, hlen;
+
+       if (!(rs->rs_status & AR5K_RXERR_DECRYPT) &&
+                       rs->rs_keyix != AR5K_RXKEYIX_INVALID)
+               return RX_FLAG_DECRYPTED;
+
+       /* Apparently when a default key is used to decrypt the packet
+          the hw does not set the index used to decrypt.  In such cases
+          get the index from the packet. */
+       hlen = ieee80211_hdrlen(hdr->frame_control);
+       if (ieee80211_has_protected(hdr->frame_control) &&
+           !(rs->rs_status & AR5K_RXERR_DECRYPT) &&
+           skb->len >= hlen + 4) {
+               keyix = skb->data[hlen + 3] >> 6;
+
+               if (test_bit(keyix, sc->keymap))
+                       return RX_FLAG_DECRYPTED;
+       }
+
+       return 0;
+}
+
+
+static void
+ath5k_check_ibss_tsf(struct ath5k_softc *sc, struct sk_buff *skb,
+                    struct ieee80211_rx_status *rxs)
+{
+       u64 tsf, bc_tstamp;
+       u32 hw_tu;
+       struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
+
+       if (ieee80211_is_beacon(mgmt->frame_control) &&
+           le16_to_cpu(mgmt->u.beacon.capab_info) & WLAN_CAPABILITY_IBSS &&
+           memcmp(mgmt->bssid, sc->ah->ah_bssid, ETH_ALEN) == 0) {
+               /*
+                * Received an IBSS beacon with the same BSSID. Hardware *must*
+                * have updated the local TSF. We have to work around various
+                * hardware bugs, though...
+                */
+               tsf = ath5k_hw_get_tsf64(sc->ah);
+               bc_tstamp = le64_to_cpu(mgmt->u.beacon.timestamp);
+               hw_tu = TSF_TO_TU(tsf);
+
+               ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON,
+                       "beacon %llx mactime %llx (diff %lld) tsf now %llx\n",
+                       (unsigned long long)bc_tstamp,
+                       (unsigned long long)rxs->mactime,
+                       (unsigned long long)(rxs->mactime - bc_tstamp),
+                       (unsigned long long)tsf);
+
+               /*
+                * Sometimes the HW will give us a wrong tstamp in the rx
+                * status, causing the timestamp extension to go wrong.
+                * (This seems to happen especially with beacon frames bigger
+                * than 78 byte (incl. FCS))
+                * But we know that the receive timestamp must be later than the
+                * timestamp of the beacon since HW must have synced to that.
+                *
+                * NOTE: here we assume mactime to be after the frame was
+                * received, not like mac80211 which defines it at the start.
+                */
+               if (bc_tstamp > rxs->mactime) {
+                       ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON,
+                               "fixing mactime from %llx to %llx\n",
+                               (unsigned long long)rxs->mactime,
+                               (unsigned long long)tsf);
+                       rxs->mactime = tsf;
+               }
+
+               /*
+                * Local TSF might have moved higher than our beacon timers,
+                * in that case we have to update them to continue sending
+                * beacons. This also takes care of synchronizing beacon sending
+                * times with other stations.
+                */
+               if (hw_tu >= sc->nexttbtt)
+                       ath5k_beacon_update_timers(sc, bc_tstamp);
+       }
+}
+
+static void
+ath5k_tasklet_rx(unsigned long data)
+{
+       struct ieee80211_rx_status rxs = {};
+       struct ath5k_rx_status rs = {};
+       struct sk_buff *skb, *next_skb;
+       dma_addr_t next_skb_addr;
+       struct ath5k_softc *sc = (void *)data;
+       struct ath5k_buf *bf;
+       struct ath5k_desc *ds;
+       int ret;
+       int hdrlen;
+       int padsize;
+
+       spin_lock(&sc->rxbuflock);
+       if (list_empty(&sc->rxbuf)) {
+               ATH5K_WARN(sc, "empty rx buf pool\n");
+               goto unlock;
+       }
+       do {
+               rxs.flag = 0;
+
+               bf = list_first_entry(&sc->rxbuf, struct ath5k_buf, list);
+               BUG_ON(bf->skb == NULL);
+               skb = bf->skb;
+               ds = bf->desc;
+
+               /* bail if HW is still using self-linked descriptor */
+               if (ath5k_hw_get_rxdp(sc->ah) == bf->daddr)
+                       break;
+
+               ret = sc->ah->ah_proc_rx_desc(sc->ah, ds, &rs);
+               if (unlikely(ret == -EINPROGRESS))
+                       break;
+               else if (unlikely(ret)) {
+                       ATH5K_ERR(sc, "error in processing rx descriptor\n");
+                       spin_unlock(&sc->rxbuflock);
+                       return;
+               }
+
+               if (unlikely(rs.rs_more)) {
+                       ATH5K_WARN(sc, "unsupported jumbo\n");
+                       goto next;
+               }
+
+               if (unlikely(rs.rs_status)) {
+                       if (rs.rs_status & AR5K_RXERR_PHY)
+                               goto next;
+                       if (rs.rs_status & AR5K_RXERR_DECRYPT) {
+                               /*
+                                * Decrypt error.  If the error occurred
+                                * because there was no hardware key, then
+                                * let the frame through so the upper layers
+                                * can process it.  This is necessary for 5210
+                                * parts which have no way to setup a ``clear''
+                                * key cache entry.
+                                *
+                                * XXX do key cache faulting
+                                */
+                               if (rs.rs_keyix == AR5K_RXKEYIX_INVALID &&
+                                   !(rs.rs_status & AR5K_RXERR_CRC))
+                                       goto accept;
+                       }
+                       if (rs.rs_status & AR5K_RXERR_MIC) {
+                               rxs.flag |= RX_FLAG_MMIC_ERROR;
+                               goto accept;
+                       }
+
+                       /* let crypto-error packets fall through in MNTR */
+                       if ((rs.rs_status &
+                               ~(AR5K_RXERR_DECRYPT|AR5K_RXERR_MIC)) ||
+                                       sc->opmode != NL80211_IFTYPE_MONITOR)
+                               goto next;
+               }
+accept:
+               next_skb = ath5k_rx_skb_alloc(sc, &next_skb_addr);
+
+               /*
+                * If we can't replace bf->skb with a new skb under memory
+                * pressure, just skip this packet
+                */
+               if (!next_skb)
+                       goto next;
+
+               pci_unmap_single(sc->pdev, bf->skbaddr, sc->rxbufsize,
+                               PCI_DMA_FROMDEVICE);
+               skb_put(skb, rs.rs_datalen);
+
+               /* The MAC header is padded to have 32-bit boundary if the
+                * packet payload is non-zero. The general calculation for
+                * padsize would take into account odd header lengths:
+                * padsize = (4 - hdrlen % 4) % 4; However, since only
+                * even-length headers are used, padding can only be 0 or 2
+                * bytes and we can optimize this a bit. In addition, we must
+                * not try to remove padding from short control frames that do
+                * not have payload. */
+               hdrlen = ieee80211_get_hdrlen_from_skb(skb);
+               padsize = ath5k_pad_size(hdrlen);
+               if (padsize) {
+                       memmove(skb->data + padsize, skb->data, hdrlen);
+                       skb_pull(skb, padsize);
+               }
+
+               /*
+                * always extend the mac timestamp, since this information is
+                * also needed for proper IBSS merging.
+                *
+                * XXX: it might be too late to do it here, since rs_tstamp is
+                * 15bit only. that means TSF extension has to be done within
+                * 32768usec (about 32ms). it might be necessary to move this to
+                * the interrupt handler, like it is done in madwifi.
+                *
+                * Unfortunately we don't know when the hardware takes the rx
+                * timestamp (beginning of phy frame, data frame, end of rx?).
+                * The only thing we know is that it is hardware specific...
+                * On AR5213 it seems the rx timestamp is at the end of the
+                * frame, but i'm not sure.
+                *
+                * NOTE: mac80211 defines mactime at the beginning of the first
+                * data symbol. Since we don't have any time references it's
+                * impossible to comply to that. This affects IBSS merge only
+                * right now, so it's not too bad...
+                */
+               rxs.mactime = ath5k_extend_tsf(sc->ah, rs.rs_tstamp);
+               rxs.flag |= RX_FLAG_TSFT;
+
+               rxs.freq = sc->curchan->center_freq;
+               rxs.band = sc->curband->band;
+
+               rxs.noise = sc->ah->ah_noise_floor;
+               rxs.signal = rxs.noise + rs.rs_rssi;
+
+               /* An rssi of 35 indicates you should be able use
+                * 54 Mbps reliably. A more elaborate scheme can be used
+                * here but it requires a map of SNR/throughput for each
+                * possible mode used */
+               rxs.qual = rs.rs_rssi * 100 / 35;
+
+               /* rssi can be more than 35 though, anything above that
+                * should be considered at 100% */
+               if (rxs.qual > 100)
+                       rxs.qual = 100;
+
+               rxs.antenna = rs.rs_antenna;
+               rxs.rate_idx = ath5k_hw_to_driver_rix(sc, rs.rs_rate);
+               rxs.flag |= ath5k_rx_decrypted(sc, ds, skb, &rs);
+
+               if (rxs.rate_idx >= 0 && rs.rs_rate ==
+                   sc->curband->bitrates[rxs.rate_idx].hw_value_short)
+                       rxs.flag |= RX_FLAG_SHORTPRE;
+
+               ath5k_debug_dump_skb(sc, skb, "RX  ", 0);
+
+               /* check beacons in IBSS mode */
+               if (sc->opmode == NL80211_IFTYPE_ADHOC)
+                       ath5k_check_ibss_tsf(sc, skb, &rxs);
+
+               __ieee80211_rx(sc->hw, skb, &rxs);
+
+               bf->skb = next_skb;
+               bf->skbaddr = next_skb_addr;
+next:
+               list_move_tail(&bf->list, &sc->rxbuf);
+       } while (ath5k_rxbuf_setup(sc, bf) == 0);
+unlock:
+       spin_unlock(&sc->rxbuflock);
+}
+
+
+
+
+/*************\
+* TX Handling *
+\*************/
+
+static void
+ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq)
+{
+       struct ath5k_tx_status ts = {};
+       struct ath5k_buf *bf, *bf0;
+       struct ath5k_desc *ds;
+       struct sk_buff *skb;
+       struct ieee80211_tx_info *info;
+       int i, ret;
+
+       spin_lock(&txq->lock);
+       list_for_each_entry_safe(bf, bf0, &txq->q, list) {
+               ds = bf->desc;
+
+               ret = sc->ah->ah_proc_tx_desc(sc->ah, ds, &ts);
+               if (unlikely(ret == -EINPROGRESS))
+                       break;
+               else if (unlikely(ret)) {
+                       ATH5K_ERR(sc, "error %d while processing queue %u\n",
+                               ret, txq->qnum);
+                       break;
+               }
+
+               skb = bf->skb;
+               info = IEEE80211_SKB_CB(skb);
+               bf->skb = NULL;
+
+               pci_unmap_single(sc->pdev, bf->skbaddr, skb->len,
+                               PCI_DMA_TODEVICE);
+
+               ieee80211_tx_info_clear_status(info);
+               for (i = 0; i < 4; i++) {
+                       struct ieee80211_tx_rate *r =
+                               &info->status.rates[i];
+
+                       if (ts.ts_rate[i]) {
+                               r->idx = ath5k_hw_to_driver_rix(sc, ts.ts_rate[i]);
+                               r->count = ts.ts_retry[i];
+                       } else {
+                               r->idx = -1;
+                               r->count = 0;
+                       }
+               }
+
+               /* count the successful attempt as well */
+               info->status.rates[ts.ts_final_idx].count++;
+
+               if (unlikely(ts.ts_status)) {
+                       sc->ll_stats.dot11ACKFailureCount++;
+                       if (ts.ts_status & AR5K_TXERR_FILT)
+                               info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
+               } else {
+                       info->flags |= IEEE80211_TX_STAT_ACK;
+                       info->status.ack_signal = ts.ts_rssi;
+               }
+
+               ieee80211_tx_status(sc->hw, skb);
+               sc->tx_stats[txq->qnum].count++;
+
+               spin_lock(&sc->txbuflock);
+               sc->tx_stats[txq->qnum].len--;
+               list_move_tail(&bf->list, &sc->txbuf);
+               sc->txbuf_len++;
+               spin_unlock(&sc->txbuflock);
+       }
+       if (likely(list_empty(&txq->q)))
+               txq->link = NULL;
+       spin_unlock(&txq->lock);
+       if (sc->txbuf_len > ATH_TXBUF / 5)
+               ieee80211_wake_queues(sc->hw);
+}
+
+static void
+ath5k_tasklet_tx(unsigned long data)
+{
+       struct ath5k_softc *sc = (void *)data;
+
+       ath5k_tx_processq(sc, sc->txq);
+}
+
+
+/*****************\
+* Beacon handling *
+\*****************/
+
+/*
+ * Setup the beacon frame for transmit.
+ */
+static int
+ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
+{
+       struct sk_buff *skb = bf->skb;
+       struct  ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+       struct ath5k_hw *ah = sc->ah;
+       struct ath5k_desc *ds;
+       int ret = 0;
+       u8 antenna;
+       u32 flags;
+
+       bf->skbaddr = pci_map_single(sc->pdev, skb->data, skb->len,
+                       PCI_DMA_TODEVICE);
+       ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, "skb %p [data %p len %u] "
+                       "skbaddr %llx\n", skb, skb->data, skb->len,
+                       (unsigned long long)bf->skbaddr);
+       if (pci_dma_mapping_error(sc->pdev, bf->skbaddr)) {
+               ATH5K_ERR(sc, "beacon DMA mapping failed\n");
+               return -EIO;
+       }
+
+       ds = bf->desc;
+       antenna = ah->ah_tx_ant;
+
+       flags = AR5K_TXDESC_NOACK;
+       if (sc->opmode == NL80211_IFTYPE_ADHOC && ath5k_hw_hasveol(ah)) {
+               ds->ds_link = bf->daddr;        /* self-linked */
+               flags |= AR5K_TXDESC_VEOL;
+       } else
+               ds->ds_link = 0;
+
+       /*
+        * If we use multiple antennas on AP and use
+        * the Sectored AP scenario, switch antenna every
+        * 4 beacons to make sure everybody hears our AP.
+        * When a client tries to associate, hw will keep
+        * track of the tx antenna to be used for this client
+        * automaticaly, based on ACKed packets.
+        *
+        * Note: AP still listens and transmits RTS on the
+        * default antenna which is supposed to be an omni.
+        *
+        * Note2: On sectored scenarios it's possible to have
+        * multiple antennas (1omni -the default- and 14 sectors)
+        * so if we choose to actually support this mode we need
+        * to allow user to set how many antennas we have and tweak
+        * the code below to send beacons on all of them.
+        */
+       if (ah->ah_ant_mode == AR5K_ANTMODE_SECTOR_AP)
+               antenna = sc->bsent & 4 ? 2 : 1;
+
+
+       /* FIXME: If we are in g mode and rate is a CCK rate
+        * subtract ah->ah_txpower.txp_cck_ofdm_pwr_delta
+        * from tx power (value is in dB units already) */
+       ds->ds_data = bf->skbaddr;
+       ret = ah->ah_setup_tx_desc(ah, ds, skb->len,
+                       ieee80211_get_hdrlen_from_skb(skb),
+                       AR5K_PKT_TYPE_BEACON, (sc->power_level * 2),
+                       ieee80211_get_tx_rate(sc->hw, info)->hw_value,
+                       1, AR5K_TXKEYIX_INVALID,
+                       antenna, flags, 0, 0);
+       if (ret)
+               goto err_unmap;
+
+       return 0;
+err_unmap:
+       pci_unmap_single(sc->pdev, bf->skbaddr, skb->len, PCI_DMA_TODEVICE);
+       return ret;
+}
+
+static void ath5k_beacon_disable(struct ath5k_softc *sc)
+{
+       sc->imask &= ~(AR5K_INT_BMISS | AR5K_INT_SWBA);
+       ath5k_hw_set_imr(sc->ah, sc->imask);
+       ath5k_hw_stop_tx_dma(sc->ah, sc->bhalq);
+}
+
+/*
+ * Transmit a beacon frame at SWBA.  Dynamic updates to the
+ * frame contents are done as needed and the slot time is
+ * also adjusted based on current state.
+ *
+ * This is called from software irq context (beacontq or restq
+ * tasklets) or user context from ath5k_beacon_config.
+ */
+static void
+ath5k_beacon_send(struct ath5k_softc *sc)
+{
+       struct ath5k_buf *bf = sc->bbuf;
+       struct ath5k_hw *ah = sc->ah;
+
+       ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON, "in beacon_send\n");
+
+       if (unlikely(bf->skb == NULL || sc->opmode == NL80211_IFTYPE_STATION ||
+                       sc->opmode == NL80211_IFTYPE_MONITOR)) {
+               ATH5K_WARN(sc, "bf=%p bf_skb=%p\n", bf, bf ? bf->skb : NULL);
+               return;
+       }
+       /*
+        * Check if the previous beacon has gone out.  If
+        * not don't don't try to post another, skip this
+        * period and wait for the next.  Missed beacons
+        * indicate a problem and should not occur.  If we
+        * miss too many consecutive beacons reset the device.
+        */
+       if (unlikely(ath5k_hw_num_tx_pending(ah, sc->bhalq) != 0)) {
+               sc->bmisscount++;
+               ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
+                       "missed %u consecutive beacons\n", sc->bmisscount);
+               if (sc->bmisscount > 10) {      /* NB: 10 is a guess */
+                       ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
+                               "stuck beacon time (%u missed)\n",
+                               sc->bmisscount);
+                       tasklet_schedule(&sc->restq);
+               }
+               return;
+       }
+       if (unlikely(sc->bmisscount != 0)) {
+               ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
+                       "resume beacon xmit after %u misses\n",
+                       sc->bmisscount);
+               sc->bmisscount = 0;
+       }
+
+       /*
+        * Stop any current dma and put the new frame on the queue.
+        * This should never fail since we check above that no frames
+        * are still pending on the queue.
+        */
+       if (unlikely(ath5k_hw_stop_tx_dma(ah, sc->bhalq))) {
+               ATH5K_WARN(sc, "beacon queue %u didn't start/stop ?\n", sc->bhalq);
+               /* NB: hw still stops DMA, so proceed */
+       }
+
+       /* refresh the beacon for AP mode */
+       if (sc->opmode == NL80211_IFTYPE_AP)
+               ath5k_beacon_update(sc->hw, sc->vif);
+
+       ath5k_hw_set_txdp(ah, sc->bhalq, bf->daddr);
+       ath5k_hw_start_tx_dma(ah, sc->bhalq);
+       ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, "TXDP[%u] = %llx (%p)\n",
+               sc->bhalq, (unsigned long long)bf->daddr, bf->desc);
+
+       sc->bsent++;
+}
+
+
+/**
+ * ath5k_beacon_update_timers - update beacon timers
+ *
+ * @sc: struct ath5k_softc pointer we are operating on
+ * @bc_tsf: the timestamp of the beacon. 0 to reset the TSF. -1 to perform a
+ *          beacon timer update based on the current HW TSF.
+ *
+ * Calculate the next target beacon transmit time (TBTT) based on the timestamp
+ * of a received beacon or the current local hardware TSF and write it to the
+ * beacon timer registers.
+ *
+ * This is called in a variety of situations, e.g. when a beacon is received,
+ * when a TSF update has been detected, but also when an new IBSS is created or
+ * when we otherwise know we have to update the timers, but we keep it in this
+ * function to have it all together in one place.
+ */
+static void
+ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf)
+{
+       struct ath5k_hw *ah = sc->ah;
+       u32 nexttbtt, intval, hw_tu, bc_tu;
+       u64 hw_tsf;
+
+       intval = sc->bintval & AR5K_BEACON_PERIOD;
+       if (WARN_ON(!intval))
+               return;
+
+       /* beacon TSF converted to TU */
+       bc_tu = TSF_TO_TU(bc_tsf);
+
+       /* current TSF converted to TU */
+       hw_tsf = ath5k_hw_get_tsf64(ah);
+       hw_tu = TSF_TO_TU(hw_tsf);
+
+#define FUDGE 3
+       /* we use FUDGE to make sure the next TBTT is ahead of the current TU */
+       if (bc_tsf == -1) {
+               /*
+                * no beacons received, called internally.
+                * just need to refresh timers based on HW TSF.
+                */
+               nexttbtt = roundup(hw_tu + FUDGE, intval);
+       } else if (bc_tsf == 0) {
+               /*
+                * no beacon received, probably called by ath5k_reset_tsf().
+                * reset TSF to start with 0.
+                */
+               nexttbtt = intval;
+               intval |= AR5K_BEACON_RESET_TSF;
+       } else if (bc_tsf > hw_tsf) {
+               /*
+                * beacon received, SW merge happend but HW TSF not yet updated.
+                * not possible to reconfigure timers yet, but next time we
+                * receive a beacon with the same BSSID, the hardware will
+                * automatically update the TSF and then we need to reconfigure
+                * the timers.
+                */
+               ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON,
+                       "need to wait for HW TSF sync\n");
+               return;
+       } else {
+               /*
+                * most important case for beacon synchronization between STA.
+                *
+                * beacon received and HW TSF has been already updated by HW.
+                * update next TBTT based on the TSF of the beacon, but make
+                * sure it is ahead of our local TSF timer.
+                */
+               nexttbtt = bc_tu + roundup(hw_tu + FUDGE - bc_tu, intval);
+       }
+#undef FUDGE
+
+       sc->nexttbtt = nexttbtt;
+
+       intval |= AR5K_BEACON_ENA;
+       ath5k_hw_init_beacon(ah, nexttbtt, intval);
+
+       /*
+        * debugging output last in order to preserve the time critical aspect
+        * of this function
+        */
+       if (bc_tsf == -1)
+               ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON,
+                       "reconfigured timers based on HW TSF\n");
+       else if (bc_tsf == 0)
+               ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON,
+                       "reset HW TSF and timers\n");
+       else
+               ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON,
+                       "updated timers based on beacon TSF\n");
+
+       ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON,
+                         "bc_tsf %llx hw_tsf %llx bc_tu %u hw_tu %u nexttbtt %u\n",
+                         (unsigned long long) bc_tsf,
+                         (unsigned long long) hw_tsf, bc_tu, hw_tu, nexttbtt);
+       ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON, "intval %u %s %s\n",
+               intval & AR5K_BEACON_PERIOD,
+               intval & AR5K_BEACON_ENA ? "AR5K_BEACON_ENA" : "",
+               intval & AR5K_BEACON_RESET_TSF ? "AR5K_BEACON_RESET_TSF" : "");
+}
+
+
+/**
+ * ath5k_beacon_config - Configure the beacon queues and interrupts
+ *
+ * @sc: struct ath5k_softc pointer we are operating on
+ *
+ * In IBSS mode we use a self-linked tx descriptor if possible. We enable SWBA
+ * interrupts to detect TSF updates only.
+ */
+static void
+ath5k_beacon_config(struct ath5k_softc *sc)
+{
+       struct ath5k_hw *ah = sc->ah;
+       unsigned long flags;
+
+       ath5k_hw_set_imr(ah, 0);
+       sc->bmisscount = 0;
+       sc->imask &= ~(AR5K_INT_BMISS | AR5K_INT_SWBA);
+
+       if (sc->opmode == NL80211_IFTYPE_ADHOC ||
+                       sc->opmode == NL80211_IFTYPE_MESH_POINT ||
+                       sc->opmode == NL80211_IFTYPE_AP) {
+               /*
+                * In IBSS mode we use a self-linked tx descriptor and let the
+                * hardware send the beacons automatically. We have to load it
+                * only once here.
+                * We use the SWBA interrupt only to keep track of the beacon
+                * timers in order to detect automatic TSF updates.
+                */
+               ath5k_beaconq_config(sc);
+
+               sc->imask |= AR5K_INT_SWBA;
+
+               if (sc->opmode == NL80211_IFTYPE_ADHOC) {
+                       if (ath5k_hw_hasveol(ah)) {
+                               spin_lock_irqsave(&sc->block, flags);
+                               ath5k_beacon_send(sc);
+                               spin_unlock_irqrestore(&sc->block, flags);
+                       }
+               } else
+                       ath5k_beacon_update_timers(sc, -1);
+       }
+
+       ath5k_hw_set_imr(ah, sc->imask);
+}
+
+static void ath5k_tasklet_beacon(unsigned long data)
+{
+       struct ath5k_softc *sc = (struct ath5k_softc *) data;
+
+       /*
+        * Software beacon alert--time to send a beacon.
+        *
+        * In IBSS mode we use this interrupt just to
+        * keep track of the next TBTT (target beacon
+        * transmission time) in order to detect wether
+        * automatic TSF updates happened.
+        */
+       if (sc->opmode == NL80211_IFTYPE_ADHOC) {
+               /* XXX: only if VEOL suppported */
+               u64 tsf = ath5k_hw_get_tsf64(sc->ah);
+               sc->nexttbtt += sc->bintval;
+               ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
+                               "SWBA nexttbtt: %x hw_tu: %x "
+                               "TSF: %llx\n",
+                               sc->nexttbtt,
+                               TSF_TO_TU(tsf),
+                               (unsigned long long) tsf);
+       } else {
+               spin_lock(&sc->block);
+               ath5k_beacon_send(sc);
+               spin_unlock(&sc->block);
+       }
+}
+
+
+/********************\
+* Interrupt handling *
+\********************/
+
+static int
+ath5k_init(struct ath5k_softc *sc)
+{
+       struct ath5k_hw *ah = sc->ah;
+       int ret, i;
+
+       mutex_lock(&sc->lock);
+
+       ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "mode %d\n", sc->opmode);
+
+       /*
+        * Stop anything previously setup.  This is safe
+        * no matter this is the first time through or not.
+        */
+       ath5k_stop_locked(sc);
+
+       /*
+        * The basic interface to setting the hardware in a good
+        * state is ``reset''.  On return the hardware is known to
+        * be powered up and with interrupts disabled.  This must
+        * be followed by initialization of the appropriate bits
+        * and then setup of the interrupt mask.
+        */
+       sc->curchan = sc->hw->conf.channel;
+       sc->curband = &sc->sbands[sc->curchan->band];
+       sc->imask = AR5K_INT_RXOK | AR5K_INT_RXERR | AR5K_INT_RXEOL |
+               AR5K_INT_RXORN | AR5K_INT_TXDESC | AR5K_INT_TXEOL |
+               AR5K_INT_FATAL | AR5K_INT_GLOBAL;
+       ret = ath5k_reset(sc, NULL);
+       if (ret)
+               goto done;
+
+       ath5k_rfkill_hw_start(ah);
+
+       /*
+        * Reset the key cache since some parts do not reset the
+        * contents on initial power up or resume from suspend.
+        */
+       for (i = 0; i < AR5K_KEYTABLE_SIZE; i++)
+               ath5k_hw_reset_key(ah, i);
+
+       /* Set ack to be sent at low bit-rates */
+       ath5k_hw_set_ack_bitrate_high(ah, false);
+
+       mod_timer(&sc->calib_tim, round_jiffies(jiffies +
+                       msecs_to_jiffies(ath5k_calinterval * 1000)));
+
+       ret = 0;
+done:
+       mmiowb();
+       mutex_unlock(&sc->lock);
+       return ret;
+}
+
+static int
+ath5k_stop_locked(struct ath5k_softc *sc)
+{
+       struct ath5k_hw *ah = sc->ah;
+
+       ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "invalid %u\n",
+                       test_bit(ATH_STAT_INVALID, sc->status));
+
+       /*
+        * Shutdown the hardware and driver:
+        *    stop output from above
+        *    disable interrupts
+        *    turn off timers
+        *    turn off the radio
+        *    clear transmit machinery
+        *    clear receive machinery
+        *    drain and release tx queues
+        *    reclaim beacon resources
+        *    power down hardware
+        *
+        * Note that some of this work is not possible if the
+        * hardware is gone (invalid).
+        */
+       ieee80211_stop_queues(sc->hw);
+
+       if (!test_bit(ATH_STAT_INVALID, sc->status)) {
+               ath5k_led_off(sc);
+               ath5k_hw_set_imr(ah, 0);
+               synchronize_irq(sc->pdev->irq);
+       }
+       ath5k_txq_cleanup(sc);
+       if (!test_bit(ATH_STAT_INVALID, sc->status)) {
+               ath5k_rx_stop(sc);
+               ath5k_hw_phy_disable(ah);
+       } else
+               sc->rxlink = NULL;
+
+       return 0;
+}
+
+/*
+ * Stop the device, grabbing the top-level lock to protect
+ * against concurrent entry through ath5k_init (which can happen
+ * if another thread does a system call and the thread doing the
+ * stop is preempted).
+ */
+static int
+ath5k_stop_hw(struct ath5k_softc *sc)
+{
+       int ret;
+
+       mutex_lock(&sc->lock);
+       ret = ath5k_stop_locked(sc);
+       if (ret == 0 && !test_bit(ATH_STAT_INVALID, sc->status)) {
+               /*
+                * Set the chip in full sleep mode.  Note that we are
+                * careful to do this only when bringing the interface
+                * completely to a stop.  When the chip is in this state
+                * it must be carefully woken up or references to
+                * registers in the PCI clock domain may freeze the bus
+                * (and system).  This varies by chip and is mostly an
+                * issue with newer parts that go to sleep more quickly.
+                */
+               if (sc->ah->ah_mac_srev >= 0x78) {
+                       /*
+                        * XXX
+                        * don't put newer MAC revisions > 7.8 to sleep because
+                        * of the above mentioned problems
+                        */
+                       ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "mac version > 7.8, "
+                               "not putting device to sleep\n");
+               } else {
+                       ATH5K_DBG(sc, ATH5K_DEBUG_RESET,
+                               "putting device to full sleep\n");
+                       ath5k_hw_set_power(sc->ah, AR5K_PM_FULL_SLEEP, true, 0);
+               }
+       }
+       ath5k_txbuf_free(sc, sc->bbuf);
+
+       mmiowb();
+       mutex_unlock(&sc->lock);
+
+       del_timer_sync(&sc->calib_tim);
+       tasklet_kill(&sc->rxtq);
+       tasklet_kill(&sc->txtq);
+       tasklet_kill(&sc->restq);
+       tasklet_kill(&sc->beacontq);
+
+       ath5k_rfkill_hw_stop(sc->ah);
+
+       return ret;
+}
+
+static irqreturn_t
+ath5k_intr(int irq, void *dev_id)
+{
+       struct ath5k_softc *sc = dev_id;
+       struct ath5k_hw *ah = sc->ah;
+       enum ath5k_int status;
+       unsigned int counter = 1000;
+
+       if (unlikely(test_bit(ATH_STAT_INVALID, sc->status) ||
+                               !ath5k_hw_is_intr_pending(ah)))
+               return IRQ_NONE;
+
+       do {
+               ath5k_hw_get_isr(ah, &status);          /* NB: clears IRQ too */
+               ATH5K_DBG(sc, ATH5K_DEBUG_INTR, "status 0x%x/0x%x\n",
+                               status, sc->imask);
+               if (unlikely(status & AR5K_INT_FATAL)) {
+                       /*
+                        * Fatal errors are unrecoverable.
+                        * Typically these are caused by DMA errors.
+                        */
+                       tasklet_schedule(&sc->restq);
+               } else if (unlikely(status & AR5K_INT_RXORN)) {
+                       tasklet_schedule(&sc->restq);
+               } else {
+                       if (status & AR5K_INT_SWBA) {
+                               tasklet_hi_schedule(&sc->beacontq);
+                       }
+                       if (status & AR5K_INT_RXEOL) {
+                               /*
+                               * NB: the hardware should re-read the link when
+                               *     RXE bit is written, but it doesn't work at
+                               *     least on older hardware revs.
+                               */
+                               sc->rxlink = NULL;
+                       }
+                       if (status & AR5K_INT_TXURN) {
+                               /* bump tx trigger level */
+                               ath5k_hw_update_tx_triglevel(ah, true);
+                       }
+                       if (status & (AR5K_INT_RXOK | AR5K_INT_RXERR))
+                               tasklet_schedule(&sc->rxtq);
+                       if (status & (AR5K_INT_TXOK | AR5K_INT_TXDESC
+                                       | AR5K_INT_TXERR | AR5K_INT_TXEOL))
+                               tasklet_schedule(&sc->txtq);
+                       if (status & AR5K_INT_BMISS) {
+                               /* TODO */
+                       }
+                       if (status & AR5K_INT_MIB) {
+                               /*
+                                * These stats are also used for ANI i think
+                                * so how about updating them more often ?
+                                */
+                               ath5k_hw_update_mib_counters(ah, &sc->ll_stats);
+                       }
+                       if (status & AR5K_INT_GPIO)
+                               tasklet_schedule(&sc->rf_kill.toggleq);
+
+               }
+       } while (ath5k_hw_is_intr_pending(ah) && --counter > 0);
+
+       if (unlikely(!counter))
+               ATH5K_WARN(sc, "too many interrupts, giving up for now\n");
+
+       return IRQ_HANDLED;
+}
+
+static void
+ath5k_tasklet_reset(unsigned long data)
+{
+       struct ath5k_softc *sc = (void *)data;
+
+       ath5k_reset_wake(sc);
+}
+
+/*
+ * Periodically recalibrate the PHY to account
+ * for temperature/environment changes.
+ */
+static void
+ath5k_calibrate(unsigned long data)
+{
+       struct ath5k_softc *sc = (void *)data;
+       struct ath5k_hw *ah = sc->ah;
+
+       ATH5K_DBG(sc, ATH5K_DEBUG_CALIBRATE, "channel %u/%x\n",
+               ieee80211_frequency_to_channel(sc->curchan->center_freq),
+               sc->curchan->hw_value);
+
+       if (ath5k_hw_gainf_calibrate(ah) == AR5K_RFGAIN_NEED_CHANGE) {
+               /*
+                * Rfgain is out of bounds, reset the chip
+                * to load new gain values.
+                */
+               ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "calibration, resetting\n");
+               ath5k_reset_wake(sc);
+       }
+       if (ath5k_hw_phy_calibrate(ah, sc->curchan))
+               ATH5K_ERR(sc, "calibration of channel %u failed\n",
+                       ieee80211_frequency_to_channel(
+                               sc->curchan->center_freq));
+
+       mod_timer(&sc->calib_tim, round_jiffies(jiffies +
+                       msecs_to_jiffies(ath5k_calinterval * 1000)));
+}
+
+
+/********************\
+* Mac80211 functions *
+\********************/
+
+static int
+ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
+{
+       struct ath5k_softc *sc = hw->priv;
+       struct ath5k_buf *bf;
+       unsigned long flags;
+       int hdrlen;
+       int padsize;
+
+       ath5k_debug_dump_skb(sc, skb, "TX  ", 1);
+
+       if (sc->opmode == NL80211_IFTYPE_MONITOR)
+               ATH5K_DBG(sc, ATH5K_DEBUG_XMIT, "tx in monitor (scan?)\n");
+
+       /*
+        * the hardware expects the header padded to 4 byte boundaries
+        * if this is not the case we add the padding after the header
+        */
+       hdrlen = ieee80211_get_hdrlen_from_skb(skb);
+       padsize = ath5k_pad_size(hdrlen);
+       if (padsize) {
+
+               if (skb_headroom(skb) < padsize) {
+                       ATH5K_ERR(sc, "tx hdrlen not %%4: %d not enough"
+                                 " headroom to pad %d\n", hdrlen, padsize);
+                       goto drop_packet;
+               }
+               skb_push(skb, padsize);
+               memmove(skb->data, skb->data+padsize, hdrlen);
+       }
+
+       spin_lock_irqsave(&sc->txbuflock, flags);
+       if (list_empty(&sc->txbuf)) {
+               ATH5K_ERR(sc, "no further txbuf available, dropping packet\n");
+               spin_unlock_irqrestore(&sc->txbuflock, flags);
+               ieee80211_stop_queue(hw, skb_get_queue_mapping(skb));
+               goto drop_packet;
+       }
+       bf = list_first_entry(&sc->txbuf, struct ath5k_buf, list);
+       list_del(&bf->list);
+       sc->txbuf_len--;
+       if (list_empty(&sc->txbuf))
+               ieee80211_stop_queues(hw);
+       spin_unlock_irqrestore(&sc->txbuflock, flags);
+
+       bf->skb = skb;
+
+       if (ath5k_txbuf_setup(sc, bf)) {
+               bf->skb = NULL;
+               spin_lock_irqsave(&sc->txbuflock, flags);
+               list_add_tail(&bf->list, &sc->txbuf);
+               sc->txbuf_len++;
+               spin_unlock_irqrestore(&sc->txbuflock, flags);
+               goto drop_packet;
+       }
+       return NETDEV_TX_OK;
+
+drop_packet:
+       dev_kfree_skb_any(skb);
+       return NETDEV_TX_OK;
+}
+
+/*
+ * Reset the hardware.  If chan is not NULL, then also pause rx/tx
+ * and change to the given channel.
+ */
+static int
+ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan)
+{
+       struct ath5k_hw *ah = sc->ah;
+       int ret;
+
+       ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "resetting\n");
+
+       if (chan) {
+               ath5k_hw_set_imr(ah, 0);
+               ath5k_txq_cleanup(sc);
+               ath5k_rx_stop(sc);
+
+               sc->curchan = chan;
+               sc->curband = &sc->sbands[chan->band];
+       }
+       ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, true);
+       if (ret) {
+               ATH5K_ERR(sc, "can't reset hardware (%d)\n", ret);
+               goto err;
+       }
+
+       ret = ath5k_rx_start(sc);
+       if (ret) {
+               ATH5K_ERR(sc, "can't start recv logic\n");
+               goto err;
+       }
+
+       /*
+        * Change channels and update the h/w rate map if we're switching;
+        * e.g. 11a to 11b/g.
+        *
+        * We may be doing a reset in response to an ioctl that changes the
+        * channel so update any state that might change as a result.
+        *
+        * XXX needed?
+        */
+/*     ath5k_chan_change(sc, c); */
+
+       ath5k_beacon_config(sc);
+       /* intrs are enabled by ath5k_beacon_config */
+
+       return 0;
+err:
+       return ret;
+}
+
+static int
+ath5k_reset_wake(struct ath5k_softc *sc)
+{
+       int ret;
+
+       ret = ath5k_reset(sc, sc->curchan);
+       if (!ret)
+               ieee80211_wake_queues(sc->hw);
+
+       return ret;
+}
+
+static int ath5k_start(struct ieee80211_hw *hw)
+{
+       return ath5k_init(hw->priv);
+}
+
+static void ath5k_stop(struct ieee80211_hw *hw)
+{
+       ath5k_stop_hw(hw->priv);
+}
+
+static int ath5k_add_interface(struct ieee80211_hw *hw,
+               struct ieee80211_if_init_conf *conf)
+{
+       struct ath5k_softc *sc = hw->priv;
+       int ret;
+
+       mutex_lock(&sc->lock);
+       if (sc->vif) {
+               ret = 0;
+               goto end;
+       }
+
+       sc->vif = conf->vif;
+
+       switch (conf->type) {
+       case NL80211_IFTYPE_AP:
+       case NL80211_IFTYPE_STATION:
+       case NL80211_IFTYPE_ADHOC:
+       case NL80211_IFTYPE_MESH_POINT:
+       case NL80211_IFTYPE_MONITOR:
+               sc->opmode = conf->type;
+               break;
+       default:
+               ret = -EOPNOTSUPP;
+               goto end;
+       }
+
+       /* Set to a reasonable value. Note that this will
+        * be set to mac80211's value at ath5k_config(). */
+       sc->bintval = 1000;
+       ath5k_hw_set_lladdr(sc->ah, conf->mac_addr);
+
+       ret = 0;
+end:
+       mutex_unlock(&sc->lock);
+       return ret;
+}
+
+static void
+ath5k_remove_interface(struct ieee80211_hw *hw,
+                       struct ieee80211_if_init_conf *conf)
+{
+       struct ath5k_softc *sc = hw->priv;
+       u8 mac[ETH_ALEN] = {};
+
+       mutex_lock(&sc->lock);
+       if (sc->vif != conf->vif)
+               goto end;
+
+       ath5k_hw_set_lladdr(sc->ah, mac);
+       ath5k_beacon_disable(sc);
+       sc->vif = NULL;
+end:
+       mutex_unlock(&sc->lock);
+}
+
+/*
+ * TODO: Phy disable/diversity etc
+ */
+static int
+ath5k_config(struct ieee80211_hw *hw, u32 changed)
+{
+       struct ath5k_softc *sc = hw->priv;
+       struct ath5k_hw *ah = sc->ah;
+       struct ieee80211_conf *conf = &hw->conf;
+       int ret = 0;
+
+       mutex_lock(&sc->lock);
+
+       ret = ath5k_chan_set(sc, conf->channel);
+       if (ret < 0)
+               goto unlock;
+
+       if ((changed & IEEE80211_CONF_CHANGE_POWER) &&
+       (sc->power_level != conf->power_level)) {
+               sc->power_level = conf->power_level;
+
+               /* Half dB steps */
+               ath5k_hw_set_txpower_limit(ah, (conf->power_level * 2));
+       }
+
+       /* TODO:
+        * 1) Move this on config_interface and handle each case
+        * separately eg. when we have only one STA vif, use
+        * AR5K_ANTMODE_SINGLE_AP
+        *
+        * 2) Allow the user to change antenna mode eg. when only
+        * one antenna is present
+        *
+        * 3) Allow the user to set default/tx antenna when possible
+        *
+        * 4) Default mode should handle 90% of the cases, together
+        * with fixed a/b and single AP modes we should be able to
+        * handle 99%. Sectored modes are extreme cases and i still
+        * haven't found a usage for them. If we decide to support them,
+        * then we must allow the user to set how many tx antennas we
+        * have available
+        */
+       ath5k_hw_set_antenna_mode(ah, AR5K_ANTMODE_DEFAULT);
+
+unlock:
+       mutex_unlock(&sc->lock);
+       return ret;
+}
+
+#define SUPPORTED_FIF_FLAGS \
+       FIF_PROMISC_IN_BSS |  FIF_ALLMULTI | FIF_FCSFAIL | \
+       FIF_PLCPFAIL | FIF_CONTROL | FIF_OTHER_BSS | \
+       FIF_BCN_PRBRESP_PROMISC
+/*
+ * o always accept unicast, broadcast, and multicast traffic
+ * o multicast traffic for all BSSIDs will be enabled if mac80211
+ *   says it should be
+ * o maintain current state of phy ofdm or phy cck error reception.
+ *   If the hardware detects any of these type of errors then
+ *   ath5k_hw_get_rx_filter() will pass to us the respective
+ *   hardware filters to be able to receive these type of frames.
+ * o probe request frames are accepted only when operating in
+ *   hostap, adhoc, or monitor modes
+ * o enable promiscuous mode according to the interface state
+ * o accept beacons:
+ *   - when operating in adhoc mode so the 802.11 layer creates
+ *     node table entries for peers,
+ *   - when operating in station mode for collecting rssi data when
+ *     the station is otherwise quiet, or
+ *   - when scanning
+ */
+static void ath5k_configure_filter(struct ieee80211_hw *hw,
+               unsigned int changed_flags,
+               unsigned int *new_flags,
+               int mc_count, struct dev_mc_list *mclist)
+{
+       struct ath5k_softc *sc = hw->priv;
+       struct ath5k_hw *ah = sc->ah;
+       u32 mfilt[2], val, rfilt;
+       u8 pos;
+       int i;
+
+       mfilt[0] = 0;
+       mfilt[1] = 0;
+
+       /* Only deal with supported flags */
+       changed_flags &= SUPPORTED_FIF_FLAGS;
+       *new_flags &= SUPPORTED_FIF_FLAGS;
+
+       /* If HW detects any phy or radar errors, leave those filters on.
+        * Also, always enable Unicast, Broadcasts and Multicast
+        * XXX: move unicast, bssid broadcasts and multicast to mac80211 */
+       rfilt = (ath5k_hw_get_rx_filter(ah) & (AR5K_RX_FILTER_PHYERR)) |
+               (AR5K_RX_FILTER_UCAST | AR5K_RX_FILTER_BCAST |
+               AR5K_RX_FILTER_MCAST);
+
+       if (changed_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS)) {
+               if (*new_flags & FIF_PROMISC_IN_BSS) {
+                       rfilt |= AR5K_RX_FILTER_PROM;
+                       __set_bit(ATH_STAT_PROMISC, sc->status);
+               } else {
+                       __clear_bit(ATH_STAT_PROMISC, sc->status);
+               }
+       }
+
+       /* Note, AR5K_RX_FILTER_MCAST is already enabled */
+       if (*new_flags & FIF_ALLMULTI) {
+               mfilt[0] =  ~0;
+               mfilt[1] =  ~0;
+       } else {
+               for (i = 0; i < mc_count; i++) {
+                       if (!mclist)
+                               break;
+                       /* calculate XOR of eight 6-bit values */
+                       val = get_unaligned_le32(mclist->dmi_addr + 0);
+                       pos = (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val;
+                       val = get_unaligned_le32(mclist->dmi_addr + 3);
+                       pos ^= (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val;
+                       pos &= 0x3f;
+                       mfilt[pos / 32] |= (1 << (pos % 32));
+                       /* XXX: we might be able to just do this instead,
+                       * but not sure, needs testing, if we do use this we'd
+                       * neet to inform below to not reset the mcast */
+                       /* ath5k_hw_set_mcast_filterindex(ah,
+                        *      mclist->dmi_addr[5]); */
+                       mclist = mclist->next;
+               }
+       }
+
+       /* This is the best we can do */
+       if (*new_flags & (FIF_FCSFAIL | FIF_PLCPFAIL))
+               rfilt |= AR5K_RX_FILTER_PHYERR;
+
+       /* FIF_BCN_PRBRESP_PROMISC really means to enable beacons
+       * and probes for any BSSID, this needs testing */
+       if (*new_flags & FIF_BCN_PRBRESP_PROMISC)
+               rfilt |= AR5K_RX_FILTER_BEACON | AR5K_RX_FILTER_PROBEREQ;
+
+       /* FIF_CONTROL doc says that if FIF_PROMISC_IN_BSS is not
+        * set we should only pass on control frames for this
+        * station. This needs testing. I believe right now this
+        * enables *all* control frames, which is OK.. but
+        * but we should see if we can improve on granularity */
+       if (*new_flags & FIF_CONTROL)
+               rfilt |= AR5K_RX_FILTER_CONTROL;
+
+       /* Additional settings per mode -- this is per ath5k */
+
+       /* XXX move these to mac80211, and add a beacon IFF flag to mac80211 */
+
+       if (sc->opmode == NL80211_IFTYPE_MONITOR)
+               rfilt |= AR5K_RX_FILTER_CONTROL | AR5K_RX_FILTER_BEACON |
+                       AR5K_RX_FILTER_PROBEREQ | AR5K_RX_FILTER_PROM;
+       if (sc->opmode != NL80211_IFTYPE_STATION)
+               rfilt |= AR5K_RX_FILTER_PROBEREQ;
+       if (sc->opmode != NL80211_IFTYPE_AP &&
+               sc->opmode != NL80211_IFTYPE_MESH_POINT &&
+               test_bit(ATH_STAT_PROMISC, sc->status))
+               rfilt |= AR5K_RX_FILTER_PROM;
+       if ((sc->opmode == NL80211_IFTYPE_STATION && sc->assoc) ||
+               sc->opmode == NL80211_IFTYPE_ADHOC ||
+               sc->opmode == NL80211_IFTYPE_AP)
+               rfilt |= AR5K_RX_FILTER_BEACON;
+       if (sc->opmode == NL80211_IFTYPE_MESH_POINT)
+               rfilt |= AR5K_RX_FILTER_CONTROL | AR5K_RX_FILTER_BEACON |
+                       AR5K_RX_FILTER_PROBEREQ | AR5K_RX_FILTER_PROM;
+
+       /* Set filters */
+       ath5k_hw_set_rx_filter(ah, rfilt);
+
+       /* Set multicast bits */
+       ath5k_hw_set_mcast_filter(ah, mfilt[0], mfilt[1]);
+       /* Set the cached hw filter flags, this will alter actually
+        * be set in HW */
+       sc->filter_flags = rfilt;
+}
+
+static int
+ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
+             struct ieee80211_vif *vif, struct ieee80211_sta *sta,
+             struct ieee80211_key_conf *key)
+{
+       struct ath5k_softc *sc = hw->priv;
+       int ret = 0;
+
+       if (modparam_nohwcrypt)
+               return -EOPNOTSUPP;
+
+       switch (key->alg) {
+       case ALG_WEP:
+       case ALG_TKIP:
+               break;
+       case ALG_CCMP:
+               return -EOPNOTSUPP;
+       default:
+               WARN_ON(1);
+               return -EINVAL;
+       }
+
+       mutex_lock(&sc->lock);
+
+       switch (cmd) {
+       case SET_KEY:
+               ret = ath5k_hw_set_key(sc->ah, key->keyidx, key,
+                                      sta ? sta->addr : NULL);
+               if (ret) {
+                       ATH5K_ERR(sc, "can't set the key\n");
+                       goto unlock;
+               }
+               __set_bit(key->keyidx, sc->keymap);
+               key->hw_key_idx = key->keyidx;
+               key->flags |= (IEEE80211_KEY_FLAG_GENERATE_IV |
+                              IEEE80211_KEY_FLAG_GENERATE_MMIC);
+               break;
+       case DISABLE_KEY:
+               ath5k_hw_reset_key(sc->ah, key->keyidx);
+               __clear_bit(key->keyidx, sc->keymap);
+               break;
+       default:
+               ret = -EINVAL;
+               goto unlock;
+       }
+
+unlock:
+       mmiowb();
+       mutex_unlock(&sc->lock);
+       return ret;
+}
+
+static int
+ath5k_get_stats(struct ieee80211_hw *hw,
+               struct ieee80211_low_level_stats *stats)
+{
+       struct ath5k_softc *sc = hw->priv;
+       struct ath5k_hw *ah = sc->ah;
+
+       /* Force update */
+       ath5k_hw_update_mib_counters(ah, &sc->ll_stats);
+
+       memcpy(stats, &sc->ll_stats, sizeof(sc->ll_stats));
+
+       return 0;
+}
+
+static int
+ath5k_get_tx_stats(struct ieee80211_hw *hw,
+               struct ieee80211_tx_queue_stats *stats)
+{
+       struct ath5k_softc *sc = hw->priv;
+
+       memcpy(stats, &sc->tx_stats, sizeof(sc->tx_stats));
+
+       return 0;
+}
+
+static u64
+ath5k_get_tsf(struct ieee80211_hw *hw)
+{
+       struct ath5k_softc *sc = hw->priv;
+
+       return ath5k_hw_get_tsf64(sc->ah);
+}
+
+static void
+ath5k_set_tsf(struct ieee80211_hw *hw, u64 tsf)
+{
+       struct ath5k_softc *sc = hw->priv;
+
+       ath5k_hw_set_tsf64(sc->ah, tsf);
+}
+
+static void
+ath5k_reset_tsf(struct ieee80211_hw *hw)
+{
+       struct ath5k_softc *sc = hw->priv;
+
+       /*
+        * in IBSS mode we need to update the beacon timers too.
+        * this will also reset the TSF if we call it with 0
+        */
+       if (sc->opmode == NL80211_IFTYPE_ADHOC)
+               ath5k_beacon_update_timers(sc, 0);
+       else
+               ath5k_hw_reset_tsf(sc->ah);
+}
+
+/*
+ * Updates the beacon that is sent by ath5k_beacon_send.  For adhoc,
+ * this is called only once at config_bss time, for AP we do it every
+ * SWBA interrupt so that the TIM will reflect buffered frames.
+ *
+ * Called with the beacon lock.
+ */
+static int
+ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
+{
+       int ret;
+       struct ath5k_softc *sc = hw->priv;
+       struct sk_buff *skb;
+
+       if (WARN_ON(!vif)) {
+               ret = -EINVAL;
+               goto out;
+       }
+
+       skb = ieee80211_beacon_get(hw, vif);
+
+       if (!skb) {
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       ath5k_debug_dump_skb(sc, skb, "BC  ", 1);
+
+       ath5k_txbuf_free(sc, sc->bbuf);
+       sc->bbuf->skb = skb;
+       ret = ath5k_beacon_setup(sc, sc->bbuf);
+       if (ret)
+               sc->bbuf->skb = NULL;
+out:
+       return ret;
+}
+
+/*
+ *  Update the beacon and reconfigure the beacon queues.
+ */
+static void
+ath5k_beacon_reconfig(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
+{
+       int ret;
+       unsigned long flags;
+       struct ath5k_softc *sc = hw->priv;
+
+       spin_lock_irqsave(&sc->block, flags);
+       ret = ath5k_beacon_update(hw, vif);
+       spin_unlock_irqrestore(&sc->block, flags);
+       if (ret == 0) {
+               ath5k_beacon_config(sc);
+               mmiowb();
+       }
+}
+
+static void
+set_beacon_filter(struct ieee80211_hw *hw, bool enable)
+{
+       struct ath5k_softc *sc = hw->priv;
+       struct ath5k_hw *ah = sc->ah;
+       u32 rfilt;
+       rfilt = ath5k_hw_get_rx_filter(ah);
+       if (enable)
+               rfilt |= AR5K_RX_FILTER_BEACON;
+       else
+               rfilt &= ~AR5K_RX_FILTER_BEACON;
+       ath5k_hw_set_rx_filter(ah, rfilt);
+       sc->filter_flags = rfilt;
+}
+
+static void ath5k_bss_info_changed(struct ieee80211_hw *hw,
+                                   struct ieee80211_vif *vif,
+                                   struct ieee80211_bss_conf *bss_conf,
+                                   u32 changes)
+{
+       struct ath5k_softc *sc = hw->priv;
+       struct ath5k_hw *ah = sc->ah;
+
+       mutex_lock(&sc->lock);
+       if (WARN_ON(sc->vif != vif))
+               goto unlock;
+
+       if (changes & BSS_CHANGED_BSSID) {
+               /* Cache for later use during resets */
+               memcpy(ah->ah_bssid, bss_conf->bssid, ETH_ALEN);
+               /* XXX: assoc id is set to 0 for now, mac80211 doesn't have
+                * a clean way of letting us retrieve this yet. */
+               ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
+               mmiowb();
+       }
+
+       if (changes & BSS_CHANGED_BEACON_INT)
+               sc->bintval = bss_conf->beacon_int;
+
+       if (changes & BSS_CHANGED_ASSOC) {
+               sc->assoc = bss_conf->assoc;
+               if (sc->opmode == NL80211_IFTYPE_STATION)
+                       set_beacon_filter(hw, sc->assoc);
+       }
+
+       if (changes & BSS_CHANGED_BEACON &&
+           (vif->type == NL80211_IFTYPE_ADHOC ||
+            vif->type == NL80211_IFTYPE_MESH_POINT ||
+            vif->type == NL80211_IFTYPE_AP)) {
+               ath5k_beacon_reconfig(hw, vif);
+       }
+
+ unlock:
+       mutex_unlock(&sc->lock);
+}
diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h
new file mode 100644 (file)
index 0000000..f9b7f2f
--- /dev/null
@@ -0,0 +1,201 @@
+/*-
+ * Copyright (c) 2002-2007 Sam Leffler, Errno Consulting
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ *    redistribution must be conditioned upon including a substantially
+ *    similar Disclaimer requirement for further binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+/*
+ * Defintions for the Atheros Wireless LAN controller driver.
+ */
+#ifndef _DEV_ATH_ATHVAR_H
+#define _DEV_ATH_ATHVAR_H
+
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/wireless.h>
+#include <linux/if_ether.h>
+#include <linux/leds.h>
+#include <linux/rfkill.h>
+
+#include "ath5k.h"
+#include "debug.h"
+
+#define        ATH_RXBUF       40              /* number of RX buffers */
+#define        ATH_TXBUF       200             /* number of TX buffers */
+#define ATH_BCBUF      1               /* number of beacon buffers */
+
+struct ath5k_buf {
+       struct list_head        list;
+       struct ath5k_desc       *desc;  /* virtual addr of desc */
+       dma_addr_t              daddr;  /* physical addr of desc */
+       struct sk_buff          *skb;   /* skbuff for buf */
+       dma_addr_t              skbaddr;/* physical addr of skb data */
+};
+
+/*
+ * Data transmit queue state.  One of these exists for each
+ * hardware transmit queue.  Packets sent to us from above
+ * are assigned to queues based on their priority.  Not all
+ * devices support a complete set of hardware transmit queues.
+ * For those devices the array sc_ac2q will map multiple
+ * priorities to fewer hardware queues (typically all to one
+ * hardware queue).
+ */
+struct ath5k_txq {
+       unsigned int            qnum;   /* hardware q number */
+       u32                     *link;  /* link ptr in last TX desc */
+       struct list_head        q;      /* transmit queue */
+       spinlock_t              lock;   /* lock on q and link */
+       bool                    setup;
+};
+
+#define ATH5K_LED_MAX_NAME_LEN 31
+
+/*
+ * State for LED triggers
+ */
+struct ath5k_led
+{
+       char name[ATH5K_LED_MAX_NAME_LEN + 1];  /* name of the LED in sysfs */
+       struct ath5k_softc *sc;                 /* driver state */
+       struct led_classdev led_dev;            /* led classdev */
+};
+
+/* Rfkill */
+struct ath5k_rfkill {
+       /* GPIO PIN for rfkill */
+       u16 gpio;
+       /* polarity of rfkill GPIO PIN */
+       bool polarity;
+       /* RFKILL toggle tasklet */
+       struct tasklet_struct toggleq;
+};
+
+#if CHAN_DEBUG
+#define ATH_CHAN_MAX   (26+26+26+200+200)
+#else
+#define ATH_CHAN_MAX   (14+14+14+252+20)
+#endif
+
+/* Software Carrier, keeps track of the driver state
+ * associated with an instance of a device */
+struct ath5k_softc {
+       struct pci_dev          *pdev;          /* for dma mapping */
+       void __iomem            *iobase;        /* address of the device */
+       struct mutex            lock;           /* dev-level lock */
+       /* FIXME: how many does it really need? */
+       struct ieee80211_tx_queue_stats tx_stats[16];
+       struct ieee80211_low_level_stats ll_stats;
+       struct ieee80211_hw     *hw;            /* IEEE 802.11 common */
+       struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
+       struct ieee80211_channel channels[ATH_CHAN_MAX];
+       struct ieee80211_rate   rates[IEEE80211_NUM_BANDS][AR5K_MAX_RATES];
+       s8                      rate_idx[IEEE80211_NUM_BANDS][AR5K_MAX_RATES];
+       enum nl80211_iftype     opmode;
+       struct ath5k_hw         *ah;            /* Atheros HW */
+
+       struct ieee80211_supported_band         *curband;
+
+#ifdef CONFIG_ATH5K_DEBUG
+       struct ath5k_dbg_info   debug;          /* debug info */
+#endif /* CONFIG_ATH5K_DEBUG */
+
+       struct ath5k_buf        *bufptr;        /* allocated buffer ptr */
+       struct ath5k_desc       *desc;          /* TX/RX descriptors */
+       dma_addr_t              desc_daddr;     /* DMA (physical) address */
+       size_t                  desc_len;       /* size of TX/RX descriptors */
+       u16                     cachelsz;       /* cache line size */
+
+       DECLARE_BITMAP(status, 5);
+#define ATH_STAT_INVALID       0               /* disable hardware accesses */
+#define ATH_STAT_MRRETRY       1               /* multi-rate retry support */
+#define ATH_STAT_PROMISC       2
+#define ATH_STAT_LEDSOFT       3               /* enable LED gpio status */
+#define ATH_STAT_STARTED       4               /* opened & irqs enabled */
+
+       unsigned int            filter_flags;   /* HW flags, AR5K_RX_FILTER_* */
+       unsigned int            curmode;        /* current phy mode */
+       struct ieee80211_channel *curchan;      /* current h/w channel */
+
+       struct ieee80211_vif *vif;
+
+       enum ath5k_int          imask;          /* interrupt mask copy */
+
+       DECLARE_BITMAP(keymap, AR5K_KEYCACHE_SIZE); /* key use bit map */
+
+       u8                      bssidmask[ETH_ALEN];
+
+       unsigned int            led_pin,        /* GPIO pin for driving LED */
+                               led_on;         /* pin setting for LED on */
+
+       struct tasklet_struct   restq;          /* reset tasklet */
+
+       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 */
+       struct tasklet_struct   rxtq;           /* rx intr tasklet */
+       struct ath5k_led        rx_led;         /* rx led */
+
+       struct list_head        txbuf;          /* transmit buffer */
+       spinlock_t              txbuflock;
+       unsigned int            txbuf_len;      /* buf count in txbuf list */
+       struct ath5k_txq        txqs[2];        /* beacon and tx */
+
+       struct ath5k_txq        *txq;           /* beacon and tx*/
+       struct tasklet_struct   txtq;           /* tx intr tasklet */
+       struct ath5k_led        tx_led;         /* tx led */
+
+       struct ath5k_rfkill     rf_kill;
+
+       spinlock_t              block;          /* protects beacon */
+       struct tasklet_struct   beacontq;       /* beacon intr tasklet */
+       struct ath5k_buf        *bbuf;          /* beacon buffer */
+       unsigned int            bhalq,          /* SW q for outgoing beacons */
+                               bmisscount,     /* missed beacon transmits */
+                               bintval,        /* beacon interval in TU */
+                               bsent;
+       unsigned int            nexttbtt;       /* next beacon time in TU */
+
+       struct timer_list       calib_tim;      /* calibration timer */
+       int                     power_level;    /* Requested tx power in dbm */
+       bool                    assoc;          /* assocate state */
+};
+
+#define ath5k_hw_hasbssidmask(_ah) \
+       (ath5k_hw_get_capability(_ah, AR5K_CAP_BSSIDMASK, 0, NULL) == 0)
+#define ath5k_hw_hasveol(_ah) \
+       (ath5k_hw_get_capability(_ah, AR5K_CAP_VEOL, 0, NULL) == 0)
+
+#endif
diff --git a/drivers/net/wireless/ath/ath5k/caps.c b/drivers/net/wireless/ath/ath5k/caps.c
new file mode 100644 (file)
index 0000000..367a6c7
--- /dev/null
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
+ * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
+ * Copyright (c) 2007-2008 Jiri Slaby <jirislaby@gmail.com>
+ *
+ * Permission to use, copy, modify, and 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.
+ *
+ */
+
+/**************\
+* Capabilities *
+\**************/
+
+#include "ath5k.h"
+#include "reg.h"
+#include "debug.h"
+#include "base.h"
+
+/*
+ * Fill the capabilities struct
+ * TODO: Merge this with EEPROM code when we are done with it
+ */
+int ath5k_hw_set_capabilities(struct ath5k_hw *ah)
+{
+       u16 ee_header;
+
+       ATH5K_TRACE(ah->ah_sc);
+       /* Capabilities stored in the EEPROM */
+       ee_header = ah->ah_capabilities.cap_eeprom.ee_header;
+
+       if (ah->ah_version == AR5K_AR5210) {
+               /*
+                * Set radio capabilities
+                * (The AR5110 only supports the middle 5GHz band)
+                */
+               ah->ah_capabilities.cap_range.range_5ghz_min = 5120;
+               ah->ah_capabilities.cap_range.range_5ghz_max = 5430;
+               ah->ah_capabilities.cap_range.range_2ghz_min = 0;
+               ah->ah_capabilities.cap_range.range_2ghz_max = 0;
+
+               /* Set supported modes */
+               __set_bit(AR5K_MODE_11A, ah->ah_capabilities.cap_mode);
+               __set_bit(AR5K_MODE_11A_TURBO, ah->ah_capabilities.cap_mode);
+       } else {
+               /*
+                * XXX The tranceiver supports frequencies from 4920 to 6100GHz
+                * XXX and from 2312 to 2732GHz. There are problems with the
+                * XXX current ieee80211 implementation because the IEEE
+                * XXX channel mapping does not support negative channel
+                * XXX numbers (2312MHz is channel -19). Of course, this
+                * XXX doesn't matter because these channels are out of range
+                * XXX but some regulation domains like MKK (Japan) will
+                * XXX support frequencies somewhere around 4.8GHz.
+                */
+
+               /*
+                * Set radio capabilities
+                */
+
+               if (AR5K_EEPROM_HDR_11A(ee_header)) {
+                       /* 4920 */
+                       ah->ah_capabilities.cap_range.range_5ghz_min = 5005;
+                       ah->ah_capabilities.cap_range.range_5ghz_max = 6100;
+
+                       /* Set supported modes */
+                       __set_bit(AR5K_MODE_11A,
+                                       ah->ah_capabilities.cap_mode);
+                       __set_bit(AR5K_MODE_11A_TURBO,
+                                       ah->ah_capabilities.cap_mode);
+                       if (ah->ah_version == AR5K_AR5212)
+                               __set_bit(AR5K_MODE_11G_TURBO,
+                                               ah->ah_capabilities.cap_mode);
+               }
+
+               /* Enable  802.11b if a 2GHz capable radio (2111/5112) is
+                * connected */
+               if (AR5K_EEPROM_HDR_11B(ee_header) ||
+                   (AR5K_EEPROM_HDR_11G(ee_header) &&
+                    ah->ah_version != AR5K_AR5211)) {
+                       /* 2312 */
+                       ah->ah_capabilities.cap_range.range_2ghz_min = 2412;
+                       ah->ah_capabilities.cap_range.range_2ghz_max = 2732;
+
+                       if (AR5K_EEPROM_HDR_11B(ee_header))
+                               __set_bit(AR5K_MODE_11B,
+                                               ah->ah_capabilities.cap_mode);
+
+                       if (AR5K_EEPROM_HDR_11G(ee_header) &&
+                           ah->ah_version != AR5K_AR5211)
+                               __set_bit(AR5K_MODE_11G,
+                                               ah->ah_capabilities.cap_mode);
+               }
+       }
+
+       /* GPIO */
+       ah->ah_gpio_npins = AR5K_NUM_GPIO;
+
+       /* Set number of supported TX queues */
+       if (ah->ah_version == AR5K_AR5210)
+               ah->ah_capabilities.cap_queues.q_tx_num =
+                       AR5K_NUM_TX_QUEUES_NOQCU;
+       else
+               ah->ah_capabilities.cap_queues.q_tx_num = AR5K_NUM_TX_QUEUES;
+
+       return 0;
+}
+
+/* Main function used by the driver part to check caps */
+int ath5k_hw_get_capability(struct ath5k_hw *ah,
+               enum ath5k_capability_type cap_type,
+               u32 capability, u32 *result)
+{
+       ATH5K_TRACE(ah->ah_sc);
+
+       switch (cap_type) {
+       case AR5K_CAP_NUM_TXQUEUES:
+               if (result) {
+                       if (ah->ah_version == AR5K_AR5210)
+                               *result = AR5K_NUM_TX_QUEUES_NOQCU;
+                       else
+                               *result = AR5K_NUM_TX_QUEUES;
+                       goto yes;
+               }
+       case AR5K_CAP_VEOL:
+               goto yes;
+       case AR5K_CAP_COMPRESSION:
+               if (ah->ah_version == AR5K_AR5212)
+                       goto yes;
+               else
+                       goto no;
+       case AR5K_CAP_BURST:
+               goto yes;
+       case AR5K_CAP_TPC:
+               goto yes;
+       case AR5K_CAP_BSSIDMASK:
+               if (ah->ah_version == AR5K_AR5212)
+                       goto yes;
+               else
+                       goto no;
+       case AR5K_CAP_XR:
+               if (ah->ah_version == AR5K_AR5212)
+                       goto yes;
+               else
+                       goto no;
+       default:
+               goto no;
+       }
+
+no:
+       return -EINVAL;
+yes:
+       return 0;
+}
+
+/*
+ * TODO: Following functions should be part of a new function
+ * set_capability
+ */
+
+int ath5k_hw_enable_pspoll(struct ath5k_hw *ah, u8 *bssid,
+               u16 assoc_id)
+{
+       ATH5K_TRACE(ah->ah_sc);
+
+       if (ah->ah_version == AR5K_AR5210) {
+               AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1,
+                       AR5K_STA_ID1_NO_PSPOLL | AR5K_STA_ID1_DEFAULT_ANTENNA);
+               return 0;
+       }
+
+       return -EIO;
+}
+
+int ath5k_hw_disable_pspoll(struct ath5k_hw *ah)
+{
+       ATH5K_TRACE(ah->ah_sc);
+
+       if (ah->ah_version == AR5K_AR5210) {
+               AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1,
+                       AR5K_STA_ID1_NO_PSPOLL | AR5K_STA_ID1_DEFAULT_ANTENNA);
+               return 0;
+       }
+
+       return -EIO;
+}
diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c
new file mode 100644 (file)
index 0000000..4904a07
--- /dev/null
@@ -0,0 +1,538 @@
+/*
+ * Copyright (c) 2007-2008 Bruno Randolf <bruno@thinktube.com>
+ *
+ *  This file is free software: you may copy, redistribute 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 file 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, see <http://www.gnu.org/licenses/>.
+ *
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ *
+ * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
+ * Copyright (c) 2004-2005 Atheros Communications, Inc.
+ * Copyright (c) 2006 Devicescape Software, Inc.
+ * Copyright (c) 2007 Jiri Slaby <jirislaby@gmail.com>
+ * Copyright (c) 2007 Luis R. Rodriguez <mcgrof@winlab.rutgers.edu>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ *    redistribution must be conditioned upon including a substantially
+ *    similar Disclaimer requirement for further binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include "base.h"
+#include "debug.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"
+
+static struct dentry *ath5k_global_debugfs;
+
+static int ath5k_debugfs_open(struct inode *inode, struct file *file)
+{
+       file->private_data = inode->i_private;
+       return 0;
+}
+
+
+/* debugfs: registers */
+
+struct reg {
+       const char *name;
+       int addr;
+};
+
+#define REG_STRUCT_INIT(r) { #r, r }
+
+/* just a few random registers, might want to add more */
+static const struct reg regs[] = {
+       REG_STRUCT_INIT(AR5K_CR),
+       REG_STRUCT_INIT(AR5K_RXDP),
+       REG_STRUCT_INIT(AR5K_CFG),
+       REG_STRUCT_INIT(AR5K_IER),
+       REG_STRUCT_INIT(AR5K_BCR),
+       REG_STRUCT_INIT(AR5K_RTSD0),
+       REG_STRUCT_INIT(AR5K_RTSD1),
+       REG_STRUCT_INIT(AR5K_TXCFG),
+       REG_STRUCT_INIT(AR5K_RXCFG),
+       REG_STRUCT_INIT(AR5K_RXJLA),
+       REG_STRUCT_INIT(AR5K_MIBC),
+       REG_STRUCT_INIT(AR5K_TOPS),
+       REG_STRUCT_INIT(AR5K_RXNOFRM),
+       REG_STRUCT_INIT(AR5K_TXNOFRM),
+       REG_STRUCT_INIT(AR5K_RPGTO),
+       REG_STRUCT_INIT(AR5K_RFCNT),
+       REG_STRUCT_INIT(AR5K_MISC),
+       REG_STRUCT_INIT(AR5K_QCUDCU_CLKGT),
+       REG_STRUCT_INIT(AR5K_ISR),
+       REG_STRUCT_INIT(AR5K_PISR),
+       REG_STRUCT_INIT(AR5K_SISR0),
+       REG_STRUCT_INIT(AR5K_SISR1),
+       REG_STRUCT_INIT(AR5K_SISR2),
+       REG_STRUCT_INIT(AR5K_SISR3),
+       REG_STRUCT_INIT(AR5K_SISR4),
+       REG_STRUCT_INIT(AR5K_IMR),
+       REG_STRUCT_INIT(AR5K_PIMR),
+       REG_STRUCT_INIT(AR5K_SIMR0),
+       REG_STRUCT_INIT(AR5K_SIMR1),
+       REG_STRUCT_INIT(AR5K_SIMR2),
+       REG_STRUCT_INIT(AR5K_SIMR3),
+       REG_STRUCT_INIT(AR5K_SIMR4),
+       REG_STRUCT_INIT(AR5K_DCM_ADDR),
+       REG_STRUCT_INIT(AR5K_DCCFG),
+       REG_STRUCT_INIT(AR5K_CCFG),
+       REG_STRUCT_INIT(AR5K_CPC0),
+       REG_STRUCT_INIT(AR5K_CPC1),
+       REG_STRUCT_INIT(AR5K_CPC2),
+       REG_STRUCT_INIT(AR5K_CPC3),
+       REG_STRUCT_INIT(AR5K_CPCOVF),
+       REG_STRUCT_INIT(AR5K_RESET_CTL),
+       REG_STRUCT_INIT(AR5K_SLEEP_CTL),
+       REG_STRUCT_INIT(AR5K_INTPEND),
+       REG_STRUCT_INIT(AR5K_SFR),
+       REG_STRUCT_INIT(AR5K_PCICFG),
+       REG_STRUCT_INIT(AR5K_GPIOCR),
+       REG_STRUCT_INIT(AR5K_GPIODO),
+       REG_STRUCT_INIT(AR5K_SREV),
+};
+
+static void *reg_start(struct seq_file *seq, loff_t *pos)
+{
+       return *pos < ARRAY_SIZE(regs) ? (void *)&regs[*pos] : NULL;
+}
+
+static void reg_stop(struct seq_file *seq, void *p)
+{
+       /* nothing to do */
+}
+
+static void *reg_next(struct seq_file *seq, void *p, loff_t *pos)
+{
+       ++*pos;
+       return *pos < ARRAY_SIZE(regs) ? (void *)&regs[*pos] : NULL;
+}
+
+static int reg_show(struct seq_file *seq, void *p)
+{
+       struct ath5k_softc *sc = seq->private;
+       struct reg *r = p;
+       seq_printf(seq, "%-25s0x%08x\n", r->name,
+               ath5k_hw_reg_read(sc->ah, r->addr));
+       return 0;
+}
+
+static const struct seq_operations register_seq_ops = {
+       .start = reg_start,
+       .next  = reg_next,
+       .stop  = reg_stop,
+       .show  = reg_show
+};
+
+static int open_file_registers(struct inode *inode, struct file *file)
+{
+       struct seq_file *s;
+       int res;
+       res = seq_open(file, &register_seq_ops);
+       if (res == 0) {
+               s = file->private_data;
+               s->private = inode->i_private;
+       }
+       return res;
+}
+
+static const struct file_operations fops_registers = {
+       .open = open_file_registers,
+       .read    = seq_read,
+       .llseek  = seq_lseek,
+       .release = seq_release,
+       .owner = THIS_MODULE,
+};
+
+
+/* debugfs: beacons */
+
+static ssize_t read_file_beacon(struct file *file, char __user *user_buf,
+                                  size_t count, loff_t *ppos)
+{
+       struct ath5k_softc *sc = file->private_data;
+       struct ath5k_hw *ah = sc->ah;
+       char buf[500];
+       unsigned int len = 0;
+       unsigned int v;
+       u64 tsf;
+
+       v = ath5k_hw_reg_read(sc->ah, AR5K_BEACON);
+       len += snprintf(buf+len, sizeof(buf)-len,
+               "%-24s0x%08x\tintval: %d\tTIM: 0x%x\n",
+               "AR5K_BEACON", v, v & AR5K_BEACON_PERIOD,
+               (v & AR5K_BEACON_TIM) >> AR5K_BEACON_TIM_S);
+
+       len += snprintf(buf+len, sizeof(buf)-len, "%-24s0x%08x\n",
+               "AR5K_LAST_TSTP", ath5k_hw_reg_read(sc->ah, AR5K_LAST_TSTP));
+
+       len += snprintf(buf+len, sizeof(buf)-len, "%-24s0x%08x\n\n",
+               "AR5K_BEACON_CNT", ath5k_hw_reg_read(sc->ah, AR5K_BEACON_CNT));
+
+       v = ath5k_hw_reg_read(sc->ah, AR5K_TIMER0);
+       len += snprintf(buf+len, sizeof(buf)-len, "%-24s0x%08x\tTU: %08x\n",
+               "AR5K_TIMER0 (TBTT)", v, v);
+
+       v = ath5k_hw_reg_read(sc->ah, AR5K_TIMER1);
+       len += snprintf(buf+len, sizeof(buf)-len, "%-24s0x%08x\tTU: %08x\n",
+               "AR5K_TIMER1 (DMA)", v, v >> 3);
+
+       v = ath5k_hw_reg_read(sc->ah, AR5K_TIMER2);
+       len += snprintf(buf+len, sizeof(buf)-len, "%-24s0x%08x\tTU: %08x\n",
+               "AR5K_TIMER2 (SWBA)", v, v >> 3);
+
+       v = ath5k_hw_reg_read(sc->ah, AR5K_TIMER3);
+       len += snprintf(buf+len, sizeof(buf)-len, "%-24s0x%08x\tTU: %08x\n",
+               "AR5K_TIMER3 (ATIM)", v, v);
+
+       tsf = ath5k_hw_get_tsf64(sc->ah);
+       len += snprintf(buf+len, sizeof(buf)-len,
+               "TSF\t\t0x%016llx\tTU: %08x\n",
+               (unsigned long long)tsf, TSF_TO_TU(tsf));
+
+       return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static ssize_t write_file_beacon(struct file *file,
+                                const char __user *userbuf,
+                                size_t count, loff_t *ppos)
+{
+       struct ath5k_softc *sc = file->private_data;
+       struct ath5k_hw *ah = sc->ah;
+       char buf[20];
+
+       if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
+               return -EFAULT;
+
+       if (strncmp(buf, "disable", 7) == 0) {
+               AR5K_REG_DISABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE);
+               printk(KERN_INFO "debugfs disable beacons\n");
+       } else if (strncmp(buf, "enable", 6) == 0) {
+               AR5K_REG_ENABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE);
+               printk(KERN_INFO "debugfs enable beacons\n");
+       }
+       return count;
+}
+
+static const struct file_operations fops_beacon = {
+       .read = read_file_beacon,
+       .write = write_file_beacon,
+       .open = ath5k_debugfs_open,
+       .owner = THIS_MODULE,
+};
+
+
+/* debugfs: reset */
+
+static ssize_t write_file_reset(struct file *file,
+                                const char __user *userbuf,
+                                size_t count, loff_t *ppos)
+{
+       struct ath5k_softc *sc = file->private_data;
+       tasklet_schedule(&sc->restq);
+       return count;
+}
+
+static const struct file_operations fops_reset = {
+       .write = write_file_reset,
+       .open = ath5k_debugfs_open,
+       .owner = THIS_MODULE,
+};
+
+
+/* debugfs: debug level */
+
+static const struct {
+       enum ath5k_debug_level level;
+       const char *name;
+       const char *desc;
+} dbg_info[] = {
+       { ATH5K_DEBUG_RESET,    "reset",        "reset and initialization" },
+       { ATH5K_DEBUG_INTR,     "intr",         "interrupt handling" },
+       { ATH5K_DEBUG_MODE,     "mode",         "mode init/setup" },
+       { ATH5K_DEBUG_XMIT,     "xmit",         "basic xmit operation" },
+       { ATH5K_DEBUG_BEACON,   "beacon",       "beacon handling" },
+       { ATH5K_DEBUG_CALIBRATE, "calib",       "periodic calibration" },
+       { ATH5K_DEBUG_TXPOWER,  "txpower",      "transmit power setting" },
+       { ATH5K_DEBUG_LED,      "led",          "LED management" },
+       { ATH5K_DEBUG_DUMP_RX,  "dumprx",       "print received skb content" },
+       { ATH5K_DEBUG_DUMP_TX,  "dumptx",       "print transmit skb content" },
+       { ATH5K_DEBUG_DUMPBANDS, "dumpbands",   "dump bands" },
+       { ATH5K_DEBUG_TRACE,    "trace",        "trace function calls" },
+       { ATH5K_DEBUG_ANY,      "all",          "show all debug levels" },
+};
+
+static ssize_t read_file_debug(struct file *file, char __user *user_buf,
+                                  size_t count, loff_t *ppos)
+{
+       struct ath5k_softc *sc = file->private_data;
+       char buf[700];
+       unsigned int len = 0;
+       unsigned int i;
+
+       len += snprintf(buf+len, sizeof(buf)-len,
+               "DEBUG LEVEL: 0x%08x\n\n", sc->debug.level);
+
+       for (i = 0; i < ARRAY_SIZE(dbg_info) - 1; i++) {
+               len += snprintf(buf+len, sizeof(buf)-len,
+                       "%10s %c 0x%08x - %s\n", dbg_info[i].name,
+                       sc->debug.level & dbg_info[i].level ? '+' : ' ',
+                       dbg_info[i].level, dbg_info[i].desc);
+       }
+       len += snprintf(buf+len, sizeof(buf)-len,
+               "%10s %c 0x%08x - %s\n", dbg_info[i].name,
+               sc->debug.level == dbg_info[i].level ? '+' : ' ',
+               dbg_info[i].level, dbg_info[i].desc);
+
+       return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static ssize_t write_file_debug(struct file *file,
+                                const char __user *userbuf,
+                                size_t count, loff_t *ppos)
+{
+       struct ath5k_softc *sc = file->private_data;
+       unsigned int i;
+       char buf[20];
+
+       if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
+               return -EFAULT;
+
+       for (i = 0; i < ARRAY_SIZE(dbg_info); i++) {
+               if (strncmp(buf, dbg_info[i].name,
+                                       strlen(dbg_info[i].name)) == 0) {
+                       sc->debug.level ^= dbg_info[i].level; /* toggle bit */
+                       break;
+               }
+       }
+       return count;
+}
+
+static const struct file_operations fops_debug = {
+       .read = read_file_debug,
+       .write = write_file_debug,
+       .open = ath5k_debugfs_open,
+       .owner = THIS_MODULE,
+};
+
+
+/* init */
+
+void
+ath5k_debug_init(void)
+{
+       ath5k_global_debugfs = debugfs_create_dir("ath5k", NULL);
+}
+
+void
+ath5k_debug_init_device(struct ath5k_softc *sc)
+{
+       sc->debug.level = ath5k_debug;
+
+       sc->debug.debugfs_phydir = debugfs_create_dir(wiphy_name(sc->hw->wiphy),
+                               ath5k_global_debugfs);
+
+       sc->debug.debugfs_debug = debugfs_create_file("debug", S_IWUSR | S_IRUGO,
+                               sc->debug.debugfs_phydir, sc, &fops_debug);
+
+       sc->debug.debugfs_registers = debugfs_create_file("registers", S_IRUGO,
+                               sc->debug.debugfs_phydir, sc, &fops_registers);
+
+       sc->debug.debugfs_beacon = debugfs_create_file("beacon", S_IWUSR | S_IRUGO,
+                               sc->debug.debugfs_phydir, sc, &fops_beacon);
+
+       sc->debug.debugfs_reset = debugfs_create_file("reset", S_IWUSR,
+                               sc->debug.debugfs_phydir, sc, &fops_reset);
+}
+
+void
+ath5k_debug_finish(void)
+{
+       debugfs_remove(ath5k_global_debugfs);
+}
+
+void
+ath5k_debug_finish_device(struct ath5k_softc *sc)
+{
+       debugfs_remove(sc->debug.debugfs_debug);
+       debugfs_remove(sc->debug.debugfs_registers);
+       debugfs_remove(sc->debug.debugfs_beacon);
+       debugfs_remove(sc->debug.debugfs_reset);
+       debugfs_remove(sc->debug.debugfs_phydir);
+}
+
+
+/* functions used in other places */
+
+void
+ath5k_debug_dump_bands(struct ath5k_softc *sc)
+{
+       unsigned int b, i;
+
+       if (likely(!(sc->debug.level & ATH5K_DEBUG_DUMPBANDS)))
+               return;
+
+       BUG_ON(!sc->sbands);
+
+       for (b = 0; b < IEEE80211_NUM_BANDS; b++) {
+               struct ieee80211_supported_band *band = &sc->sbands[b];
+               char bname[6];
+               switch (band->band) {
+               case IEEE80211_BAND_2GHZ:
+                       strcpy(bname, "2 GHz");
+                       break;
+               case IEEE80211_BAND_5GHZ:
+                       strcpy(bname, "5 GHz");
+                       break;
+               default:
+                       printk(KERN_DEBUG "Band not supported: %d\n",
+                               band->band);
+                       return;
+               }
+               printk(KERN_DEBUG "Band %s: channels %d, rates %d\n", bname,
+                               band->n_channels, band->n_bitrates);
+               printk(KERN_DEBUG " channels:\n");
+               for (i = 0; i < band->n_channels; i++)
+                       printk(KERN_DEBUG "  %3d %d %.4x %.4x\n",
+                                       ieee80211_frequency_to_channel(
+                                               band->channels[i].center_freq),
+                                       band->channels[i].center_freq,
+                                       band->channels[i].hw_value,
+                                       band->channels[i].flags);
+               printk(KERN_DEBUG " rates:\n");
+               for (i = 0; i < band->n_bitrates; i++)
+                       printk(KERN_DEBUG "  %4d %.4x %.4x %.4x\n",
+                                       band->bitrates[i].bitrate,
+                                       band->bitrates[i].hw_value,
+                                       band->bitrates[i].flags,
+                                       band->bitrates[i].hw_value_short);
+       }
+}
+
+static inline void
+ath5k_debug_printrxbuf(struct ath5k_buf *bf, int done,
+                      struct ath5k_rx_status *rs)
+{
+       struct ath5k_desc *ds = bf->desc;
+       struct ath5k_hw_all_rx_desc *rd = &ds->ud.ds_rx;
+
+       printk(KERN_DEBUG "R (%p %llx) %08x %08x %08x %08x %08x %08x %c\n",
+               ds, (unsigned long long)bf->daddr,
+               ds->ds_link, ds->ds_data,
+               rd->rx_ctl.rx_control_0, rd->rx_ctl.rx_control_1,
+               rd->u.rx_stat.rx_status_0, rd->u.rx_stat.rx_status_0,
+               !done ? ' ' : (rs->rs_status == 0) ? '*' : '!');
+}
+
+void
+ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah)
+{
+       struct ath5k_desc *ds;
+       struct ath5k_buf *bf;
+       struct ath5k_rx_status rs = {};
+       int status;
+
+       if (likely(!(sc->debug.level & ATH5K_DEBUG_RESET)))
+               return;
+
+       printk(KERN_DEBUG "rx queue %x, link %p\n",
+               ath5k_hw_get_rxdp(ah), sc->rxlink);
+
+       spin_lock_bh(&sc->rxbuflock);
+       list_for_each_entry(bf, &sc->rxbuf, list) {
+               ds = bf->desc;
+               status = ah->ah_proc_rx_desc(ah, ds, &rs);
+               if (!status)
+                       ath5k_debug_printrxbuf(bf, status == 0, &rs);
+       }
+       spin_unlock_bh(&sc->rxbuflock);
+}
+
+void
+ath5k_debug_dump_skb(struct ath5k_softc *sc,
+                       struct sk_buff *skb, const char *prefix, int tx)
+{
+       char buf[16];
+
+       if (likely(!((tx && (sc->debug.level & ATH5K_DEBUG_DUMP_TX)) ||
+                    (!tx && (sc->debug.level & ATH5K_DEBUG_DUMP_RX)))))
+               return;
+
+       snprintf(buf, sizeof(buf), "%s %s", wiphy_name(sc->hw->wiphy), prefix);
+
+       print_hex_dump_bytes(buf, DUMP_PREFIX_NONE, skb->data,
+               min(200U, skb->len));
+
+       printk(KERN_DEBUG "\n");
+}
+
+void
+ath5k_debug_printtxbuf(struct ath5k_softc *sc, struct ath5k_buf *bf)
+{
+       struct ath5k_desc *ds = bf->desc;
+       struct ath5k_hw_5212_tx_desc *td = &ds->ud.ds_tx5212;
+       struct ath5k_tx_status ts = {};
+       int done;
+
+       if (likely(!(sc->debug.level & ATH5K_DEBUG_RESET)))
+               return;
+
+       done = sc->ah->ah_proc_tx_desc(sc->ah, bf->desc, &ts);
+
+       printk(KERN_DEBUG "T (%p %llx) %08x %08x %08x %08x %08x %08x %08x "
+               "%08x %c\n", ds, (unsigned long long)bf->daddr, ds->ds_link,
+               ds->ds_data, td->tx_ctl.tx_control_0, td->tx_ctl.tx_control_1,
+               td->tx_ctl.tx_control_2, td->tx_ctl.tx_control_3,
+               td->tx_stat.tx_status_0, td->tx_stat.tx_status_1,
+               done ? ' ' : (ts.ts_status == 0) ? '*' : '!');
+}
+
+#endif /* ifdef CONFIG_ATH5K_DEBUG */
diff --git a/drivers/net/wireless/ath/ath5k/debug.h b/drivers/net/wireless/ath/ath5k/debug.h
new file mode 100644 (file)
index 0000000..66f69f0
--- /dev/null
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2007 Bruno Randolf <bruno@thinktube.com>
+ *
+ *  This file is free software: you may copy, redistribute 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 file 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, see <http://www.gnu.org/licenses/>.
+ *
+ *
+ * This file incorporates work covered by the following copyright and
+ * permission notice:
+ *
+ * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
+ * Copyright (c) 2004-2005 Atheros Communications, Inc.
+ * Copyright (c) 2006 Devicescape Software, Inc.
+ * Copyright (c) 2007 Jiri Slaby <jirislaby@gmail.com>
+ * Copyright (c) 2007 Luis R. Rodriguez <mcgrof@winlab.rutgers.edu>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ *    redistribution must be conditioned upon including a substantially
+ *    similar Disclaimer requirement for further binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#ifndef _ATH5K_DEBUG_H
+#define _ATH5K_DEBUG_H
+
+struct ath5k_softc;
+struct ath5k_hw;
+struct sk_buff;
+struct ath5k_buf;
+
+struct ath5k_dbg_info {
+       unsigned int            level;          /* debug level */
+       /* debugfs entries */
+       struct dentry           *debugfs_phydir;
+       struct dentry           *debugfs_debug;
+       struct dentry           *debugfs_registers;
+       struct dentry           *debugfs_beacon;
+       struct dentry           *debugfs_reset;
+};
+
+/**
+ * enum ath5k_debug_level - ath5k debug level
+ *
+ * @ATH5K_DEBUG_RESET: reset processing
+ * @ATH5K_DEBUG_INTR: interrupt handling
+ * @ATH5K_DEBUG_MODE: mode init/setup
+ * @ATH5K_DEBUG_XMIT: basic xmit operation
+ * @ATH5K_DEBUG_BEACON: beacon handling
+ * @ATH5K_DEBUG_CALIBRATE: periodic calibration
+ * @ATH5K_DEBUG_TXPOWER: transmit power setting
+ * @ATH5K_DEBUG_LED: led management
+ * @ATH5K_DEBUG_DUMP_RX: print received skb content
+ * @ATH5K_DEBUG_DUMP_TX: print transmit skb content
+ * @ATH5K_DEBUG_DUMPBANDS: dump bands
+ * @ATH5K_DEBUG_TRACE: trace function calls
+ * @ATH5K_DEBUG_ANY: show at any debug level
+ *
+ * The debug level is used to control the amount and type of debugging output
+ * we want to see. The debug level is given in calls to ATH5K_DBG to specify
+ * where the message should appear, and the user can control the debugging
+ * messages he wants to see, either by the module parameter 'debug' on module
+ * load, or dynamically by using debugfs 'ath5k/phyX/debug'. these levels can
+ * be combined together by bitwise OR.
+ */
+enum ath5k_debug_level {
+       ATH5K_DEBUG_RESET       = 0x00000001,
+       ATH5K_DEBUG_INTR        = 0x00000002,
+       ATH5K_DEBUG_MODE        = 0x00000004,
+       ATH5K_DEBUG_XMIT        = 0x00000008,
+       ATH5K_DEBUG_BEACON      = 0x00000010,
+       ATH5K_DEBUG_CALIBRATE   = 0x00000020,
+       ATH5K_DEBUG_TXPOWER     = 0x00000040,
+       ATH5K_DEBUG_LED         = 0x00000080,
+       ATH5K_DEBUG_DUMP_RX     = 0x00000100,
+       ATH5K_DEBUG_DUMP_TX     = 0x00000200,
+       ATH5K_DEBUG_DUMPBANDS   = 0x00000400,
+       ATH5K_DEBUG_TRACE       = 0x00001000,
+       ATH5K_DEBUG_ANY         = 0xffffffff
+};
+
+#ifdef CONFIG_ATH5K_DEBUG
+
+#define ATH5K_TRACE(_sc) do { \
+       if (unlikely((_sc)->debug.level & ATH5K_DEBUG_TRACE)) \
+               printk(KERN_DEBUG "ath5k trace %s:%d\n", __func__, __LINE__); \
+       } while (0)
+
+#define ATH5K_DBG(_sc, _m, _fmt, ...) do { \
+       if (unlikely((_sc)->debug.level & (_m) && net_ratelimit())) \
+               ATH5K_PRINTK(_sc, KERN_DEBUG, "(%s:%d): " _fmt, \
+                       __func__, __LINE__, ##__VA_ARGS__); \
+       } while (0)
+
+#define ATH5K_DBG_UNLIMIT(_sc, _m, _fmt, ...) do { \
+       if (unlikely((_sc)->debug.level & (_m))) \
+               ATH5K_PRINTK(_sc, KERN_DEBUG, "(%s:%d): " _fmt, \
+                       __func__, __LINE__, ##__VA_ARGS__); \
+       } while (0)
+
+void
+ath5k_debug_init(void);
+
+void
+ath5k_debug_init_device(struct ath5k_softc *sc);
+
+void
+ath5k_debug_finish(void);
+
+void
+ath5k_debug_finish_device(struct ath5k_softc *sc);
+
+void
+ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah);
+
+void
+ath5k_debug_dump_bands(struct ath5k_softc *sc);
+
+void
+ath5k_debug_dump_skb(struct ath5k_softc *sc,
+                       struct sk_buff *skb, const char *prefix, int tx);
+
+void
+ath5k_debug_printtxbuf(struct ath5k_softc *sc, struct ath5k_buf *bf);
+
+#else /* no debugging */
+
+#include <linux/compiler.h>
+
+#define ATH5K_TRACE(_sc) typecheck(struct ath5k_softc *, (_sc))
+
+static inline void __attribute__ ((format (printf, 3, 4)))
+ATH5K_DBG(struct ath5k_softc *sc, unsigned int m, const char *fmt, ...) {}
+
+static inline void __attribute__ ((format (printf, 3, 4)))
+ATH5K_DBG_UNLIMIT(struct ath5k_softc *sc, unsigned int m, const char *fmt, ...)
+{}
+
+static inline void
+ath5k_debug_init(void) {}
+
+static inline void
+ath5k_debug_init_device(struct ath5k_softc *sc) {}
+
+static inline void
+ath5k_debug_finish(void) {}
+
+static inline void
+ath5k_debug_finish_device(struct ath5k_softc *sc) {}
+
+static inline void
+ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah) {}
+
+static inline void
+ath5k_debug_dump_bands(struct ath5k_softc *sc) {}
+
+static inline void
+ath5k_debug_dump_skb(struct ath5k_softc *sc,
+                       struct sk_buff *skb, const char *prefix, int tx) {}
+
+static inline void
+ath5k_debug_printtxbuf(struct ath5k_softc *sc, struct ath5k_buf *bf) {}
+
+#endif /* ifdef CONFIG_ATH5K_DEBUG */
+
+#endif /* ifndef _ATH5K_DEBUG_H */
diff --git a/drivers/net/wireless/ath/ath5k/desc.c b/drivers/net/wireless/ath/ath5k/desc.c
new file mode 100644 (file)
index 0000000..dc30a2b
--- /dev/null
@@ -0,0 +1,696 @@
+/*
+ * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
+ * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
+ * Copyright (c) 2007-2008 Pavel Roskin <proski@gnu.org>
+ *
+ * Permission to use, copy, modify, and 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.
+ *
+ */
+
+/******************************\
+ Hardware Descriptor Functions
+\******************************/
+
+#include "ath5k.h"
+#include "reg.h"
+#include "debug.h"
+#include "base.h"
+
+/*
+ * TX Descriptors
+ */
+
+/*
+ * Initialize the 2-word tx control descriptor on 5210/5211
+ */
+static int
+ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
+       unsigned int pkt_len, unsigned int hdr_len, enum ath5k_pkt_type type,
+       unsigned int tx_power, unsigned int tx_rate0, unsigned int tx_tries0,
+       unsigned int key_index, unsigned int antenna_mode, unsigned int flags,
+       unsigned int rtscts_rate, unsigned int rtscts_duration)
+{
+       u32 frame_type;
+       struct ath5k_hw_2w_tx_ctl *tx_ctl;
+       unsigned int frame_len;
+
+       tx_ctl = &desc->ud.ds_tx5210.tx_ctl;
+
+       /*
+        * Validate input
+        * - Zero retries don't make sense.
+        * - A zero rate will put the HW into a mode where it continously sends
+        *   noise on the channel, so it is important to avoid this.
+        */
+       if (unlikely(tx_tries0 == 0)) {
+               ATH5K_ERR(ah->ah_sc, "zero retries\n");
+               WARN_ON(1);
+               return -EINVAL;
+       }
+       if (unlikely(tx_rate0 == 0)) {
+               ATH5K_ERR(ah->ah_sc, "zero rate\n");
+               WARN_ON(1);
+               return -EINVAL;
+       }
+
+       /* Clear descriptor */
+       memset(&desc->ud.ds_tx5210, 0, sizeof(struct ath5k_hw_5210_tx_desc));
+
+       /* Setup control descriptor */
+
+       /* Verify and set frame length */
+
+       /* remove padding we might have added before */
+       frame_len = pkt_len - ath5k_pad_size(hdr_len) + FCS_LEN;
+
+       if (frame_len & ~AR5K_2W_TX_DESC_CTL0_FRAME_LEN)
+               return -EINVAL;
+
+       tx_ctl->tx_control_0 = frame_len & AR5K_2W_TX_DESC_CTL0_FRAME_LEN;
+
+       /* Verify and set buffer length */
+
+       /* NB: beacon's BufLen must be a multiple of 4 bytes */
+       if (type == AR5K_PKT_TYPE_BEACON)
+               pkt_len = roundup(pkt_len, 4);
+
+       if (pkt_len & ~AR5K_2W_TX_DESC_CTL1_BUF_LEN)
+               return -EINVAL;
+
+       tx_ctl->tx_control_1 = pkt_len & AR5K_2W_TX_DESC_CTL1_BUF_LEN;
+
+       /*
+        * Verify and set header length
+        * XXX: I only found that on 5210 code, does it work on 5211 ?
+        */
+       if (ah->ah_version == AR5K_AR5210) {
+               if (hdr_len & ~AR5K_2W_TX_DESC_CTL0_HEADER_LEN)
+                       return -EINVAL;
+               tx_ctl->tx_control_0 |=
+                       AR5K_REG_SM(hdr_len, AR5K_2W_TX_DESC_CTL0_HEADER_LEN);
+       }
+
+       /*Diferences between 5210-5211*/
+       if (ah->ah_version == AR5K_AR5210) {
+               switch (type) {
+               case AR5K_PKT_TYPE_BEACON:
+               case AR5K_PKT_TYPE_PROBE_RESP:
+                       frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_NO_DELAY;
+               case AR5K_PKT_TYPE_PIFS:
+                       frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_PIFS;
+               default:
+                       frame_type = type /*<< 2 ?*/;
+               }
+
+               tx_ctl->tx_control_0 |=
+               AR5K_REG_SM(frame_type, AR5K_2W_TX_DESC_CTL0_FRAME_TYPE) |
+               AR5K_REG_SM(tx_rate0, AR5K_2W_TX_DESC_CTL0_XMIT_RATE);
+
+       } else {
+               tx_ctl->tx_control_0 |=
+                       AR5K_REG_SM(tx_rate0, AR5K_2W_TX_DESC_CTL0_XMIT_RATE) |
+                       AR5K_REG_SM(antenna_mode,
+                               AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT);
+               tx_ctl->tx_control_1 |=
+                       AR5K_REG_SM(type, AR5K_2W_TX_DESC_CTL1_FRAME_TYPE);
+       }
+#define _TX_FLAGS(_c, _flag)                                   \
+       if (flags & AR5K_TXDESC_##_flag) {                      \
+               tx_ctl->tx_control_##_c |=                      \
+                       AR5K_2W_TX_DESC_CTL##_c##_##_flag;      \
+       }
+
+       _TX_FLAGS(0, CLRDMASK);
+       _TX_FLAGS(0, VEOL);
+       _TX_FLAGS(0, INTREQ);
+       _TX_FLAGS(0, RTSENA);
+       _TX_FLAGS(1, NOACK);
+
+#undef _TX_FLAGS
+
+       /*
+        * WEP crap
+        */
+       if (key_index != AR5K_TXKEYIX_INVALID) {
+               tx_ctl->tx_control_0 |=
+                       AR5K_2W_TX_DESC_CTL0_ENCRYPT_KEY_VALID;
+               tx_ctl->tx_control_1 |=
+                       AR5K_REG_SM(key_index,
+                       AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX);
+       }
+
+       /*
+        * RTS/CTS Duration [5210 ?]
+        */
+       if ((ah->ah_version == AR5K_AR5210) &&
+                       (flags & (AR5K_TXDESC_RTSENA | AR5K_TXDESC_CTSENA)))
+               tx_ctl->tx_control_1 |= rtscts_duration &
+                               AR5K_2W_TX_DESC_CTL1_RTS_DURATION;
+
+       return 0;
+}
+
+/*
+ * Initialize the 4-word tx control descriptor on 5212
+ */
+static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah,
+       struct ath5k_desc *desc, unsigned int pkt_len, unsigned int hdr_len,
+       enum ath5k_pkt_type type, unsigned int tx_power, unsigned int tx_rate0,
+       unsigned int tx_tries0, unsigned int key_index,
+       unsigned int antenna_mode, unsigned int flags,
+       unsigned int rtscts_rate,
+       unsigned int rtscts_duration)
+{
+       struct ath5k_hw_4w_tx_ctl *tx_ctl;
+       unsigned int frame_len;
+
+       ATH5K_TRACE(ah->ah_sc);
+       tx_ctl = &desc->ud.ds_tx5212.tx_ctl;
+
+       /*
+        * Validate input
+        * - Zero retries don't make sense.
+        * - A zero rate will put the HW into a mode where it continously sends
+        *   noise on the channel, so it is important to avoid this.
+        */
+       if (unlikely(tx_tries0 == 0)) {
+               ATH5K_ERR(ah->ah_sc, "zero retries\n");
+               WARN_ON(1);
+               return -EINVAL;
+       }
+       if (unlikely(tx_rate0 == 0)) {
+               ATH5K_ERR(ah->ah_sc, "zero rate\n");
+               WARN_ON(1);
+               return -EINVAL;
+       }
+
+       tx_power += ah->ah_txpower.txp_offset;
+       if (tx_power > AR5K_TUNE_MAX_TXPOWER)
+               tx_power = AR5K_TUNE_MAX_TXPOWER;
+
+       /* Clear descriptor */
+       memset(&desc->ud.ds_tx5212, 0, sizeof(struct ath5k_hw_5212_tx_desc));
+
+       /* Setup control descriptor */
+
+       /* Verify and set frame length */
+
+       /* remove padding we might have added before */
+       frame_len = pkt_len - ath5k_pad_size(hdr_len) + FCS_LEN;
+
+       if (frame_len & ~AR5K_4W_TX_DESC_CTL0_FRAME_LEN)
+               return -EINVAL;
+
+       tx_ctl->tx_control_0 = frame_len & AR5K_4W_TX_DESC_CTL0_FRAME_LEN;
+
+       /* Verify and set buffer length */
+
+       /* NB: beacon's BufLen must be a multiple of 4 bytes */
+       if (type == AR5K_PKT_TYPE_BEACON)
+               pkt_len = roundup(pkt_len, 4);
+
+       if (pkt_len & ~AR5K_4W_TX_DESC_CTL1_BUF_LEN)
+               return -EINVAL;
+
+       tx_ctl->tx_control_1 = pkt_len & AR5K_4W_TX_DESC_CTL1_BUF_LEN;
+
+       tx_ctl->tx_control_0 |=
+               AR5K_REG_SM(tx_power, AR5K_4W_TX_DESC_CTL0_XMIT_POWER) |
+               AR5K_REG_SM(antenna_mode, AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT);
+       tx_ctl->tx_control_1 |= AR5K_REG_SM(type,
+                                       AR5K_4W_TX_DESC_CTL1_FRAME_TYPE);
+       tx_ctl->tx_control_2 = AR5K_REG_SM(tx_tries0 + AR5K_TUNE_HWTXTRIES,
+                                       AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0);
+       tx_ctl->tx_control_3 = tx_rate0 & AR5K_4W_TX_DESC_CTL3_XMIT_RATE0;
+
+#define _TX_FLAGS(_c, _flag)                                   \
+       if (flags & AR5K_TXDESC_##_flag) {                      \
+               tx_ctl->tx_control_##_c |=                      \
+                       AR5K_4W_TX_DESC_CTL##_c##_##_flag;      \
+       }
+
+       _TX_FLAGS(0, CLRDMASK);
+       _TX_FLAGS(0, VEOL);
+       _TX_FLAGS(0, INTREQ);
+       _TX_FLAGS(0, RTSENA);
+       _TX_FLAGS(0, CTSENA);
+       _TX_FLAGS(1, NOACK);
+
+#undef _TX_FLAGS
+
+       /*
+        * WEP crap
+        */
+       if (key_index != AR5K_TXKEYIX_INVALID) {
+               tx_ctl->tx_control_0 |= AR5K_4W_TX_DESC_CTL0_ENCRYPT_KEY_VALID;
+               tx_ctl->tx_control_1 |= AR5K_REG_SM(key_index,
+                               AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX);
+       }
+
+       /*
+        * RTS/CTS
+        */
+       if (flags & (AR5K_TXDESC_RTSENA | AR5K_TXDESC_CTSENA)) {
+               if ((flags & AR5K_TXDESC_RTSENA) &&
+                               (flags & AR5K_TXDESC_CTSENA))
+                       return -EINVAL;
+               tx_ctl->tx_control_2 |= rtscts_duration &
+                               AR5K_4W_TX_DESC_CTL2_RTS_DURATION;
+               tx_ctl->tx_control_3 |= AR5K_REG_SM(rtscts_rate,
+                               AR5K_4W_TX_DESC_CTL3_RTS_CTS_RATE);
+       }
+
+       return 0;
+}
+
+/*
+ * Initialize a 4-word multi rate retry tx control descriptor on 5212
+ */
+static int
+ath5k_hw_setup_mrr_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
+       unsigned int tx_rate1, u_int tx_tries1, u_int tx_rate2,
+       u_int tx_tries2, unsigned int tx_rate3, u_int tx_tries3)
+{
+       struct ath5k_hw_4w_tx_ctl *tx_ctl;
+
+       /*
+        * Rates can be 0 as long as the retry count is 0 too.
+        * A zero rate and nonzero retry count will put the HW into a mode where
+        * it continously sends noise on the channel, so it is important to
+        * avoid this.
+        */
+       if (unlikely((tx_rate1 == 0 && tx_tries1 != 0) ||
+                    (tx_rate2 == 0 && tx_tries2 != 0) ||
+                    (tx_rate3 == 0 && tx_tries3 != 0))) {
+               ATH5K_ERR(ah->ah_sc, "zero rate\n");
+               WARN_ON(1);
+               return -EINVAL;
+       }
+
+       if (ah->ah_version == AR5K_AR5212) {
+               tx_ctl = &desc->ud.ds_tx5212.tx_ctl;
+
+#define _XTX_TRIES(_n)                                                 \
+       if (tx_tries##_n) {                                             \
+               tx_ctl->tx_control_2 |=                                 \
+                   AR5K_REG_SM(tx_tries##_n,                           \
+                   AR5K_4W_TX_DESC_CTL2_XMIT_TRIES##_n);               \
+               tx_ctl->tx_control_3 |=                                 \
+                   AR5K_REG_SM(tx_rate##_n,                            \
+                   AR5K_4W_TX_DESC_CTL3_XMIT_RATE##_n);                \
+       }
+
+               _XTX_TRIES(1);
+               _XTX_TRIES(2);
+               _XTX_TRIES(3);
+
+#undef _XTX_TRIES
+
+               return 1;
+       }
+
+       return 0;
+}
+
+/* no mrr support for cards older than 5212 */
+static int
+ath5k_hw_setup_no_mrr(struct ath5k_hw *ah, struct ath5k_desc *desc,
+       unsigned int tx_rate1, u_int tx_tries1, u_int tx_rate2,
+       u_int tx_tries2, unsigned int tx_rate3, u_int tx_tries3)
+{
+       return 0;
+}
+
+/*
+ * Proccess the tx status descriptor on 5210/5211
+ */
+static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *ah,
+               struct ath5k_desc *desc, struct ath5k_tx_status *ts)
+{
+       struct ath5k_hw_2w_tx_ctl *tx_ctl;
+       struct ath5k_hw_tx_status *tx_status;
+
+       ATH5K_TRACE(ah->ah_sc);
+
+       tx_ctl = &desc->ud.ds_tx5210.tx_ctl;
+       tx_status = &desc->ud.ds_tx5210.tx_stat;
+
+       /* No frame has been send or error */
+       if (unlikely((tx_status->tx_status_1 & AR5K_DESC_TX_STATUS1_DONE) == 0))
+               return -EINPROGRESS;
+
+       /*
+        * Get descriptor status
+        */
+       ts->ts_tstamp = AR5K_REG_MS(tx_status->tx_status_0,
+               AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP);
+       ts->ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0,
+               AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT);
+       ts->ts_longretry = AR5K_REG_MS(tx_status->tx_status_0,
+               AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT);
+       /*TODO: ts->ts_virtcol + test*/
+       ts->ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1,
+               AR5K_DESC_TX_STATUS1_SEQ_NUM);
+       ts->ts_rssi = AR5K_REG_MS(tx_status->tx_status_1,
+               AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH);
+       ts->ts_antenna = 1;
+       ts->ts_status = 0;
+       ts->ts_rate[0] = AR5K_REG_MS(tx_ctl->tx_control_0,
+               AR5K_2W_TX_DESC_CTL0_XMIT_RATE);
+       ts->ts_retry[0] = ts->ts_longretry;
+       ts->ts_final_idx = 0;
+
+       if (!(tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) {
+               if (tx_status->tx_status_0 &
+                               AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES)
+                       ts->ts_status |= AR5K_TXERR_XRETRY;
+
+               if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN)
+                       ts->ts_status |= AR5K_TXERR_FIFO;
+
+               if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FILTERED)
+                       ts->ts_status |= AR5K_TXERR_FILT;
+       }
+
+       return 0;
+}
+
+/*
+ * Proccess a tx status descriptor on 5212
+ */
+static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah,
+               struct ath5k_desc *desc, struct ath5k_tx_status *ts)
+{
+       struct ath5k_hw_4w_tx_ctl *tx_ctl;
+       struct ath5k_hw_tx_status *tx_status;
+
+       ATH5K_TRACE(ah->ah_sc);
+
+       tx_ctl = &desc->ud.ds_tx5212.tx_ctl;
+       tx_status = &desc->ud.ds_tx5212.tx_stat;
+
+       /* No frame has been send or error */
+       if (unlikely(!(tx_status->tx_status_1 & AR5K_DESC_TX_STATUS1_DONE)))
+               return -EINPROGRESS;
+
+       /*
+        * Get descriptor status
+        */
+       ts->ts_tstamp = AR5K_REG_MS(tx_status->tx_status_0,
+               AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP);
+       ts->ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0,
+               AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT);
+       ts->ts_longretry = AR5K_REG_MS(tx_status->tx_status_0,
+               AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT);
+       ts->ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1,
+               AR5K_DESC_TX_STATUS1_SEQ_NUM);
+       ts->ts_rssi = AR5K_REG_MS(tx_status->tx_status_1,
+               AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH);
+       ts->ts_antenna = (tx_status->tx_status_1 &
+               AR5K_DESC_TX_STATUS1_XMIT_ANTENNA) ? 2 : 1;
+       ts->ts_status = 0;
+
+       ts->ts_final_idx = AR5K_REG_MS(tx_status->tx_status_1,
+                       AR5K_DESC_TX_STATUS1_FINAL_TS_INDEX);
+
+       /* The longretry counter has the number of un-acked retries
+        * for the final rate. To get the total number of retries
+        * we have to add the retry counters for the other rates
+        * as well
+        */
+       ts->ts_retry[ts->ts_final_idx] = ts->ts_longretry;
+       switch (ts->ts_final_idx) {
+       case 3:
+               ts->ts_rate[3] = AR5K_REG_MS(tx_ctl->tx_control_3,
+                       AR5K_4W_TX_DESC_CTL3_XMIT_RATE3);
+
+               ts->ts_retry[2] = AR5K_REG_MS(tx_ctl->tx_control_2,
+                       AR5K_4W_TX_DESC_CTL2_XMIT_TRIES2);
+               ts->ts_longretry += ts->ts_retry[2];
+               /* fall through */
+       case 2:
+               ts->ts_rate[2] = AR5K_REG_MS(tx_ctl->tx_control_3,
+                       AR5K_4W_TX_DESC_CTL3_XMIT_RATE2);
+
+               ts->ts_retry[1] = AR5K_REG_MS(tx_ctl->tx_control_2,
+                       AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1);
+               ts->ts_longretry += ts->ts_retry[1];
+               /* fall through */
+       case 1:
+               ts->ts_rate[1] = AR5K_REG_MS(tx_ctl->tx_control_3,
+                       AR5K_4W_TX_DESC_CTL3_XMIT_RATE1);
+
+               ts->ts_retry[0] = AR5K_REG_MS(tx_ctl->tx_control_2,
+                       AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1);
+               ts->ts_longretry += ts->ts_retry[0];
+               /* fall through */
+       case 0:
+               ts->ts_rate[0] = tx_ctl->tx_control_3 &
+                       AR5K_4W_TX_DESC_CTL3_XMIT_RATE0;
+               break;
+       }
+
+       /* TX error */
+       if (!(tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) {
+               if (tx_status->tx_status_0 &
+                               AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES)
+                       ts->ts_status |= AR5K_TXERR_XRETRY;
+
+               if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN)
+                       ts->ts_status |= AR5K_TXERR_FIFO;
+
+               if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FILTERED)
+                       ts->ts_status |= AR5K_TXERR_FILT;
+       }
+
+       return 0;
+}
+
+/*
+ * RX Descriptors
+ */
+
+/*
+ * Initialize an rx control descriptor
+ */
+static int ath5k_hw_setup_rx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
+                       u32 size, unsigned int flags)
+{
+       struct ath5k_hw_rx_ctl *rx_ctl;
+
+       ATH5K_TRACE(ah->ah_sc);
+       rx_ctl = &desc->ud.ds_rx.rx_ctl;
+
+       /*
+        * Clear the descriptor
+        * If we don't clean the status descriptor,
+        * while scanning we get too many results,
+        * most of them virtual, after some secs
+        * of scanning system hangs. M.F.
+       */
+       memset(&desc->ud.ds_rx, 0, sizeof(struct ath5k_hw_all_rx_desc));
+
+       /* Setup descriptor */
+       rx_ctl->rx_control_1 = size & AR5K_DESC_RX_CTL1_BUF_LEN;
+       if (unlikely(rx_ctl->rx_control_1 != size))
+               return -EINVAL;
+
+       if (flags & AR5K_RXDESC_INTREQ)
+               rx_ctl->rx_control_1 |= AR5K_DESC_RX_CTL1_INTREQ;
+
+       return 0;
+}
+
+/*
+ * Proccess the rx status descriptor on 5210/5211
+ */
+static int ath5k_hw_proc_5210_rx_status(struct ath5k_hw *ah,
+               struct ath5k_desc *desc, struct ath5k_rx_status *rs)
+{
+       struct ath5k_hw_rx_status *rx_status;
+
+       rx_status = &desc->ud.ds_rx.u.rx_stat;
+
+       /* No frame received / not ready */
+       if (unlikely(!(rx_status->rx_status_1 &
+       AR5K_5210_RX_DESC_STATUS1_DONE)))
+               return -EINPROGRESS;
+
+       /*
+        * Frame receive status
+        */
+       rs->rs_datalen = rx_status->rx_status_0 &
+               AR5K_5210_RX_DESC_STATUS0_DATA_LEN;
+       rs->rs_rssi = AR5K_REG_MS(rx_status->rx_status_0,
+               AR5K_5210_RX_DESC_STATUS0_RECEIVE_SIGNAL);
+       rs->rs_rate = AR5K_REG_MS(rx_status->rx_status_0,
+               AR5K_5210_RX_DESC_STATUS0_RECEIVE_RATE);
+       rs->rs_antenna = AR5K_REG_MS(rx_status->rx_status_0,
+               AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANTENNA);
+       rs->rs_more = !!(rx_status->rx_status_0 &
+               AR5K_5210_RX_DESC_STATUS0_MORE);
+       /* TODO: this timestamp is 13 bit, later on we assume 15 bit */
+       rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1,
+               AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP);
+       rs->rs_status = 0;
+       rs->rs_phyerr = 0;
+
+       /*
+        * Key table status
+        */
+       if (rx_status->rx_status_1 & AR5K_5210_RX_DESC_STATUS1_KEY_INDEX_VALID)
+               rs->rs_keyix = AR5K_REG_MS(rx_status->rx_status_1,
+                       AR5K_5210_RX_DESC_STATUS1_KEY_INDEX);
+       else
+               rs->rs_keyix = AR5K_RXKEYIX_INVALID;
+
+       /*
+        * Receive/descriptor errors
+        */
+       if (!(rx_status->rx_status_1 &
+       AR5K_5210_RX_DESC_STATUS1_FRAME_RECEIVE_OK)) {
+               if (rx_status->rx_status_1 &
+                               AR5K_5210_RX_DESC_STATUS1_CRC_ERROR)
+                       rs->rs_status |= AR5K_RXERR_CRC;
+
+               if (rx_status->rx_status_1 &
+                               AR5K_5210_RX_DESC_STATUS1_FIFO_OVERRUN)
+                       rs->rs_status |= AR5K_RXERR_FIFO;
+
+               if (rx_status->rx_status_1 &
+                               AR5K_5210_RX_DESC_STATUS1_PHY_ERROR) {
+                       rs->rs_status |= AR5K_RXERR_PHY;
+                       rs->rs_phyerr |= AR5K_REG_MS(rx_status->rx_status_1,
+                               AR5K_5210_RX_DESC_STATUS1_PHY_ERROR);
+               }
+
+               if (rx_status->rx_status_1 &
+                               AR5K_5210_RX_DESC_STATUS1_DECRYPT_CRC_ERROR)
+                       rs->rs_status |= AR5K_RXERR_DECRYPT;
+       }
+
+       return 0;
+}
+
+/*
+ * Proccess the rx status descriptor on 5212
+ */
+static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah,
+               struct ath5k_desc *desc, struct ath5k_rx_status *rs)
+{
+       struct ath5k_hw_rx_status *rx_status;
+       struct ath5k_hw_rx_error *rx_err;
+
+       ATH5K_TRACE(ah->ah_sc);
+       rx_status = &desc->ud.ds_rx.u.rx_stat;
+
+       /* Overlay on error */
+       rx_err = &desc->ud.ds_rx.u.rx_err;
+
+       /* No frame received / not ready */
+       if (unlikely(!(rx_status->rx_status_1 &
+       AR5K_5212_RX_DESC_STATUS1_DONE)))
+               return -EINPROGRESS;
+
+       /*
+        * Frame receive status
+        */
+       rs->rs_datalen = rx_status->rx_status_0 &
+               AR5K_5212_RX_DESC_STATUS0_DATA_LEN;
+       rs->rs_rssi = AR5K_REG_MS(rx_status->rx_status_0,
+               AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL);
+       rs->rs_rate = AR5K_REG_MS(rx_status->rx_status_0,
+               AR5K_5212_RX_DESC_STATUS0_RECEIVE_RATE);
+       rs->rs_antenna = AR5K_REG_MS(rx_status->rx_status_0,
+               AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA);
+       rs->rs_more = !!(rx_status->rx_status_0 &
+               AR5K_5212_RX_DESC_STATUS0_MORE);
+       rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1,
+               AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP);
+       rs->rs_status = 0;
+       rs->rs_phyerr = 0;
+
+       /*
+        * Key table status
+        */
+       if (rx_status->rx_status_1 & AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_VALID)
+               rs->rs_keyix = AR5K_REG_MS(rx_status->rx_status_1,
+                               AR5K_5212_RX_DESC_STATUS1_KEY_INDEX);
+       else
+               rs->rs_keyix = AR5K_RXKEYIX_INVALID;
+
+       /*
+        * Receive/descriptor errors
+        */
+       if (!(rx_status->rx_status_1 &
+       AR5K_5212_RX_DESC_STATUS1_FRAME_RECEIVE_OK)) {
+               if (rx_status->rx_status_1 &
+                               AR5K_5212_RX_DESC_STATUS1_CRC_ERROR)
+                       rs->rs_status |= AR5K_RXERR_CRC;
+
+               if (rx_status->rx_status_1 &
+                               AR5K_5212_RX_DESC_STATUS1_PHY_ERROR) {
+                       rs->rs_status |= AR5K_RXERR_PHY;
+                       rs->rs_phyerr |= AR5K_REG_MS(rx_err->rx_error_1,
+                                          AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE);
+               }
+
+               if (rx_status->rx_status_1 &
+                               AR5K_5212_RX_DESC_STATUS1_DECRYPT_CRC_ERROR)
+                       rs->rs_status |= AR5K_RXERR_DECRYPT;
+
+               if (rx_status->rx_status_1 &
+                               AR5K_5212_RX_DESC_STATUS1_MIC_ERROR)
+                       rs->rs_status |= AR5K_RXERR_MIC;
+       }
+
+       return 0;
+}
+
+/*
+ * Init function pointers inside ath5k_hw struct
+ */
+int ath5k_hw_init_desc_functions(struct ath5k_hw *ah)
+{
+
+       if (ah->ah_version != AR5K_AR5210 &&
+               ah->ah_version != AR5K_AR5211 &&
+               ah->ah_version != AR5K_AR5212)
+                       return -ENOTSUPP;
+
+       /* XXX: What is this magic value and where is it used ? */
+       if (ah->ah_version == AR5K_AR5212)
+               ah->ah_magic = AR5K_EEPROM_MAGIC_5212;
+       else if (ah->ah_version == AR5K_AR5211)
+               ah->ah_magic = AR5K_EEPROM_MAGIC_5211;
+
+       if (ah->ah_version == AR5K_AR5212) {
+               ah->ah_setup_rx_desc = ath5k_hw_setup_rx_desc;
+               ah->ah_setup_tx_desc = ath5k_hw_setup_4word_tx_desc;
+               ah->ah_setup_mrr_tx_desc = ath5k_hw_setup_mrr_tx_desc;
+               ah->ah_proc_tx_desc = ath5k_hw_proc_4word_tx_status;
+       } else {
+               ah->ah_setup_rx_desc = ath5k_hw_setup_rx_desc;
+               ah->ah_setup_tx_desc = ath5k_hw_setup_2word_tx_desc;
+               ah->ah_setup_mrr_tx_desc = ath5k_hw_setup_no_mrr;
+               ah->ah_proc_tx_desc = ath5k_hw_proc_2word_tx_status;
+       }
+
+       if (ah->ah_version == AR5K_AR5212)
+               ah->ah_proc_rx_desc = ath5k_hw_proc_5212_rx_status;
+       else if (ah->ah_version <= AR5K_AR5211)
+               ah->ah_proc_rx_desc = ath5k_hw_proc_5210_rx_status;
+
+       return 0;
+}
+
diff --git a/drivers/net/wireless/ath/ath5k/desc.h b/drivers/net/wireless/ath/ath5k/desc.h
new file mode 100644 (file)
index 0000000..56158c8
--- /dev/null
@@ -0,0 +1,332 @@
+/*
+ * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
+ * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
+ *
+ * Permission to use, copy, modify, and 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 RX/TX descriptor structures
+ * (rX: reserved fields possibily used by future versions of the ar5k chipset)
+ */
+
+/*
+ * common hardware RX control descriptor
+ */
+struct ath5k_hw_rx_ctl {
+       u32     rx_control_0; /* RX control word 0 */
+       u32     rx_control_1; /* RX control word 1 */
+} __packed;
+
+/* RX control word 0 field/sflags */
+#define AR5K_DESC_RX_CTL0                      0x00000000
+
+/* RX control word 1 fields/flags */
+#define AR5K_DESC_RX_CTL1_BUF_LEN              0x00000fff
+#define AR5K_DESC_RX_CTL1_INTREQ               0x00002000
+
+/*
+ * common hardware RX status descriptor
+ * 5210/11 and 5212 differ only in the flags defined below
+ */
+struct ath5k_hw_rx_status {
+       u32     rx_status_0; /* RX status word 0 */
+       u32     rx_status_1; /* RX status word 1 */
+} __packed;
+
+/* 5210/5211 */
+/* RX status word 0 fields/flags */
+#define AR5K_5210_RX_DESC_STATUS0_DATA_LEN             0x00000fff
+#define AR5K_5210_RX_DESC_STATUS0_MORE                 0x00001000
+#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_RATE         0x00078000
+#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_RATE_S       15
+#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_SIGNAL       0x07f80000
+#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_SIGNAL_S     19
+#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANTENNA      0x38000000
+#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANTENNA_S    27
+
+/* RX status word 1 fields/flags */
+#define AR5K_5210_RX_DESC_STATUS1_DONE                 0x00000001
+#define AR5K_5210_RX_DESC_STATUS1_FRAME_RECEIVE_OK     0x00000002
+#define AR5K_5210_RX_DESC_STATUS1_CRC_ERROR            0x00000004
+#define AR5K_5210_RX_DESC_STATUS1_FIFO_OVERRUN         0x00000008
+#define AR5K_5210_RX_DESC_STATUS1_DECRYPT_CRC_ERROR    0x00000010
+#define AR5K_5210_RX_DESC_STATUS1_PHY_ERROR            0x000000e0
+#define AR5K_5210_RX_DESC_STATUS1_PHY_ERROR_S          5
+#define AR5K_5210_RX_DESC_STATUS1_KEY_INDEX_VALID      0x00000100
+#define AR5K_5210_RX_DESC_STATUS1_KEY_INDEX            0x00007e00
+#define AR5K_5210_RX_DESC_STATUS1_KEY_INDEX_S          9
+#define AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP    0x0fff8000
+#define AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP_S  15
+#define AR5K_5210_RX_DESC_STATUS1_KEY_CACHE_MISS       0x10000000
+
+/* 5212 */
+/* RX status word 0 fields/flags */
+#define AR5K_5212_RX_DESC_STATUS0_DATA_LEN             0x00000fff
+#define AR5K_5212_RX_DESC_STATUS0_MORE                 0x00001000
+#define AR5K_5212_RX_DESC_STATUS0_DECOMP_CRC_ERROR     0x00002000
+#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_RATE         0x000f8000
+#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_RATE_S       15
+#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL       0x0ff00000
+#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL_S     20
+#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA      0xf0000000
+#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA_S    28
+
+/* RX status word 1 fields/flags */
+#define AR5K_5212_RX_DESC_STATUS1_DONE                 0x00000001
+#define AR5K_5212_RX_DESC_STATUS1_FRAME_RECEIVE_OK     0x00000002
+#define AR5K_5212_RX_DESC_STATUS1_CRC_ERROR            0x00000004
+#define AR5K_5212_RX_DESC_STATUS1_DECRYPT_CRC_ERROR    0x00000008
+#define AR5K_5212_RX_DESC_STATUS1_PHY_ERROR            0x00000010
+#define AR5K_5212_RX_DESC_STATUS1_MIC_ERROR            0x00000020
+#define AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_VALID      0x00000100
+#define AR5K_5212_RX_DESC_STATUS1_KEY_INDEX            0x0000fe00
+#define AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_S          9
+#define AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP    0x7fff0000
+#define AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP_S  16
+#define AR5K_5212_RX_DESC_STATUS1_KEY_CACHE_MISS       0x80000000
+
+/*
+ * common hardware RX error descriptor
+ */
+struct ath5k_hw_rx_error {
+       u32     rx_error_0; /* RX status word 0 */
+       u32     rx_error_1; /* RX status word 1 */
+} __packed;
+
+/* RX error word 0 fields/flags */
+#define AR5K_RX_DESC_ERROR0                    0x00000000
+
+/* RX error word 1 fields/flags */
+#define AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE     0x0000ff00
+#define AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE_S   8
+
+/* PHY Error codes */
+#define AR5K_DESC_RX_PHY_ERROR_NONE            0x00
+#define AR5K_DESC_RX_PHY_ERROR_TIMING          0x20
+#define AR5K_DESC_RX_PHY_ERROR_PARITY          0x40
+#define AR5K_DESC_RX_PHY_ERROR_RATE            0x60
+#define AR5K_DESC_RX_PHY_ERROR_LENGTH          0x80
+#define AR5K_DESC_RX_PHY_ERROR_64QAM           0xa0
+#define AR5K_DESC_RX_PHY_ERROR_SERVICE         0xc0
+#define AR5K_DESC_RX_PHY_ERROR_TRANSMITOVR     0xe0
+
+/*
+ * 5210/5211 hardware 2-word TX control descriptor
+ */
+struct ath5k_hw_2w_tx_ctl {
+       u32     tx_control_0; /* TX control word 0 */
+       u32     tx_control_1; /* TX control word 1 */
+} __packed;
+
+/* TX control word 0 fields/flags */
+#define AR5K_2W_TX_DESC_CTL0_FRAME_LEN         0x00000fff
+#define AR5K_2W_TX_DESC_CTL0_HEADER_LEN                0x0003f000 /*[5210 ?]*/
+#define AR5K_2W_TX_DESC_CTL0_HEADER_LEN_S      12
+#define AR5K_2W_TX_DESC_CTL0_XMIT_RATE         0x003c0000
+#define AR5K_2W_TX_DESC_CTL0_XMIT_RATE_S       18
+#define AR5K_2W_TX_DESC_CTL0_RTSENA            0x00400000
+#define AR5K_2W_TX_DESC_CTL0_CLRDMASK          0x01000000
+#define AR5K_2W_TX_DESC_CTL0_LONG_PACKET       0x00800000 /*[5210]*/
+#define AR5K_2W_TX_DESC_CTL0_VEOL              0x00800000 /*[5211]*/
+#define AR5K_2W_TX_DESC_CTL0_FRAME_TYPE                0x1c000000 /*[5210]*/
+#define AR5K_2W_TX_DESC_CTL0_FRAME_TYPE_S      26
+#define AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_5210        0x02000000
+#define AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_5211        0x1e000000
+
+#define AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT                     \
+               (ah->ah_version == AR5K_AR5210 ?                \
+               AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_5210 :       \
+               AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_5211)
+
+#define AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_S   25
+#define AR5K_2W_TX_DESC_CTL0_INTREQ            0x20000000
+#define AR5K_2W_TX_DESC_CTL0_ENCRYPT_KEY_VALID 0x40000000
+
+/* TX control word 1 fields/flags */
+#define AR5K_2W_TX_DESC_CTL1_BUF_LEN           0x00000fff
+#define AR5K_2W_TX_DESC_CTL1_MORE              0x00001000
+#define AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX_5210    0x0007e000
+#define AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX_5211    0x000fe000
+
+#define AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX                         \
+                       (ah->ah_version == AR5K_AR5210 ?                \
+                       AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX_5210 :   \
+                       AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX_5211)
+
+#define AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX_S       13
+#define AR5K_2W_TX_DESC_CTL1_FRAME_TYPE                0x00700000 /*[5211]*/
+#define AR5K_2W_TX_DESC_CTL1_FRAME_TYPE_S      20
+#define AR5K_2W_TX_DESC_CTL1_NOACK             0x00800000 /*[5211]*/
+#define AR5K_2W_TX_DESC_CTL1_RTS_DURATION      0xfff80000 /*[5210 ?]*/
+
+/* Frame types */
+#define AR5K_AR5210_TX_DESC_FRAME_TYPE_NORMAL   0x00
+#define AR5K_AR5210_TX_DESC_FRAME_TYPE_ATIM     0x04
+#define AR5K_AR5210_TX_DESC_FRAME_TYPE_PSPOLL   0x08
+#define AR5K_AR5210_TX_DESC_FRAME_TYPE_NO_DELAY 0x0c
+#define AR5K_AR5210_TX_DESC_FRAME_TYPE_PIFS     0x10
+
+/*
+ * 5212 hardware 4-word TX control descriptor
+ */
+struct ath5k_hw_4w_tx_ctl {
+       u32     tx_control_0; /* TX control word 0 */
+
+#define AR5K_4W_TX_DESC_CTL0_FRAME_LEN         0x00000fff
+#define AR5K_4W_TX_DESC_CTL0_XMIT_POWER                0x003f0000
+#define AR5K_4W_TX_DESC_CTL0_XMIT_POWER_S      16
+#define AR5K_4W_TX_DESC_CTL0_RTSENA            0x00400000
+#define AR5K_4W_TX_DESC_CTL0_VEOL              0x00800000
+#define AR5K_4W_TX_DESC_CTL0_CLRDMASK          0x01000000
+#define AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT     0x1e000000
+#define AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT_S   25
+#define AR5K_4W_TX_DESC_CTL0_INTREQ            0x20000000
+#define AR5K_4W_TX_DESC_CTL0_ENCRYPT_KEY_VALID 0x40000000
+#define AR5K_4W_TX_DESC_CTL0_CTSENA            0x80000000
+
+       u32     tx_control_1; /* TX control word 1 */
+
+#define AR5K_4W_TX_DESC_CTL1_BUF_LEN           0x00000fff
+#define AR5K_4W_TX_DESC_CTL1_MORE              0x00001000
+#define AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX 0x000fe000
+#define AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX_S       13
+#define AR5K_4W_TX_DESC_CTL1_FRAME_TYPE                0x00f00000
+#define AR5K_4W_TX_DESC_CTL1_FRAME_TYPE_S      20
+#define AR5K_4W_TX_DESC_CTL1_NOACK             0x01000000
+#define AR5K_4W_TX_DESC_CTL1_COMP_PROC         0x06000000
+#define AR5K_4W_TX_DESC_CTL1_COMP_PROC_S       25
+#define AR5K_4W_TX_DESC_CTL1_COMP_IV_LEN       0x18000000
+#define AR5K_4W_TX_DESC_CTL1_COMP_IV_LEN_S     27
+#define AR5K_4W_TX_DESC_CTL1_COMP_ICV_LEN      0x60000000
+#define AR5K_4W_TX_DESC_CTL1_COMP_ICV_LEN_S    29
+
+       u32     tx_control_2; /* TX control word 2 */
+
+#define AR5K_4W_TX_DESC_CTL2_RTS_DURATION              0x00007fff
+#define AR5K_4W_TX_DESC_CTL2_DURATION_UPDATE_ENABLE    0x00008000
+#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0               0x000f0000
+#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0_S             16
+#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1               0x00f00000
+#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1_S             20
+#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES2               0x0f000000
+#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES2_S             24
+#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES3               0xf0000000
+#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES3_S             28
+
+       u32     tx_control_3; /* TX control word 3 */
+
+#define AR5K_4W_TX_DESC_CTL3_XMIT_RATE0                0x0000001f
+#define AR5K_4W_TX_DESC_CTL3_XMIT_RATE1                0x000003e0
+#define AR5K_4W_TX_DESC_CTL3_XMIT_RATE1_S      5
+#define AR5K_4W_TX_DESC_CTL3_XMIT_RATE2                0x00007c00
+#define AR5K_4W_TX_DESC_CTL3_XMIT_RATE2_S      10
+#define AR5K_4W_TX_DESC_CTL3_XMIT_RATE3                0x000f8000
+#define AR5K_4W_TX_DESC_CTL3_XMIT_RATE3_S      15
+#define AR5K_4W_TX_DESC_CTL3_RTS_CTS_RATE      0x01f00000
+#define AR5K_4W_TX_DESC_CTL3_RTS_CTS_RATE_S    20
+} __packed;
+
+/*
+ * Common TX status descriptor
+ */
+struct ath5k_hw_tx_status {
+       u32     tx_status_0; /* TX status word 0 */
+       u32     tx_status_1; /* TX status word 1 */
+} __packed;
+
+/* TX status word 0 fields/flags */
+#define AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK     0x00000001
+#define AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES 0x00000002
+#define AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN     0x00000004
+#define AR5K_DESC_TX_STATUS0_FILTERED          0x00000008
+/*???
+#define AR5K_DESC_TX_STATUS0_RTS_FAIL_COUNT    0x000000f0
+#define AR5K_DESC_TX_STATUS0_RTS_FAIL_COUNT_S  4
+*/
+#define AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT 0x000000f0
+#define AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT_S       4
+/*???
+#define AR5K_DESC_TX_STATUS0_DATA_FAIL_COUNT   0x00000f00
+#define AR5K_DESC_TX_STATUS0_DATA_FAIL_COUNT_S 8
+*/
+#define AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT  0x00000f00
+#define AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT_S        8
+#define AR5K_DESC_TX_STATUS0_VIRT_COLL_COUNT   0x0000f000
+#define AR5K_DESC_TX_STATUS0_VIRT_COLL_COUNT_S 12
+#define AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP    0xffff0000
+#define AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP_S  16
+
+/* TX status word 1 fields/flags */
+#define AR5K_DESC_TX_STATUS1_DONE              0x00000001
+#define AR5K_DESC_TX_STATUS1_SEQ_NUM           0x00001ffe
+#define AR5K_DESC_TX_STATUS1_SEQ_NUM_S         1
+#define AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH  0x001fe000
+#define AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH_S        13
+#define AR5K_DESC_TX_STATUS1_FINAL_TS_INDEX    0x00600000
+#define AR5K_DESC_TX_STATUS1_FINAL_TS_INDEX_S  21
+#define AR5K_DESC_TX_STATUS1_COMP_SUCCESS      0x00800000
+#define AR5K_DESC_TX_STATUS1_XMIT_ANTENNA      0x01000000
+
+/*
+ * 5210/5211 hardware TX descriptor
+ */
+struct ath5k_hw_5210_tx_desc {
+       struct ath5k_hw_2w_tx_ctl       tx_ctl;
+       struct ath5k_hw_tx_status       tx_stat;
+} __packed;
+
+/*
+ * 5212 hardware TX descriptor
+ */
+struct ath5k_hw_5212_tx_desc {
+       struct ath5k_hw_4w_tx_ctl       tx_ctl;
+       struct ath5k_hw_tx_status       tx_stat;
+} __packed;
+
+/*
+ * common hardware RX descriptor
+ */
+struct ath5k_hw_all_rx_desc {
+       struct ath5k_hw_rx_ctl                  rx_ctl;
+       union {
+               struct ath5k_hw_rx_status       rx_stat;
+               struct ath5k_hw_rx_error        rx_err;
+       } u;
+} __packed;
+
+/*
+ * Atheros hardware descriptor
+ * This is read and written to by the hardware
+ */
+struct ath5k_desc {
+       u32     ds_link;        /* physical address of the next descriptor */
+       u32     ds_data;        /* physical address of data buffer (skb) */
+
+       union {
+               struct ath5k_hw_5210_tx_desc    ds_tx5210;
+               struct ath5k_hw_5212_tx_desc    ds_tx5212;
+               struct ath5k_hw_all_rx_desc     ds_rx;
+       } ud;
+} __packed;
+
+#define AR5K_RXDESC_INTREQ     0x0020
+
+#define AR5K_TXDESC_CLRDMASK   0x0001
+#define AR5K_TXDESC_NOACK      0x0002  /*[5211+]*/
+#define AR5K_TXDESC_RTSENA     0x0004
+#define AR5K_TXDESC_CTSENA     0x0008
+#define AR5K_TXDESC_INTREQ     0x0010
+#define AR5K_TXDESC_VEOL       0x0020  /*[5211+]*/
+
diff --git a/drivers/net/wireless/ath/ath5k/dma.c b/drivers/net/wireless/ath/ath5k/dma.c
new file mode 100644 (file)
index 0000000..941b511
--- /dev/null
@@ -0,0 +1,703 @@
+/*
+ * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
+ * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
+ *
+ * Permission to use, copy, modify, and 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.
+ *
+ */
+
+/*************************************\
+* DMA and interrupt masking functions *
+\*************************************/
+
+/*
+ * dma.c - DMA and interrupt masking functions
+ *
+ * Here we setup descriptor pointers (rxdp/txdp) start/stop dma engine and
+ * handle queue setup for 5210 chipset (rest are handled on qcu.c).
+ * Also we setup interrupt mask register (IMR) and read the various iterrupt
+ * status registers (ISR).
+ *
+ * TODO: Handle SISR on 5211+ and introduce a function to return the queue
+ * number that resulted the interrupt.
+ */
+
+#include "ath5k.h"
+#include "reg.h"
+#include "debug.h"
+#include "base.h"
+
+/*********\
+* Receive *
+\*********/
+
+/**
+ * ath5k_hw_start_rx_dma - Start DMA receive
+ *
+ * @ah:        The &struct ath5k_hw
+ */
+void ath5k_hw_start_rx_dma(struct ath5k_hw *ah)
+{
+       ATH5K_TRACE(ah->ah_sc);
+       ath5k_hw_reg_write(ah, AR5K_CR_RXE, AR5K_CR);
+       ath5k_hw_reg_read(ah, AR5K_CR);
+}
+
+/**
+ * ath5k_hw_stop_rx_dma - Stop DMA receive
+ *
+ * @ah:        The &struct ath5k_hw
+ */
+int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah)
+{
+       unsigned int i;
+
+       ATH5K_TRACE(ah->ah_sc);
+       ath5k_hw_reg_write(ah, AR5K_CR_RXD, AR5K_CR);
+
+       /*
+        * It may take some time to disable the DMA receive unit
+        */
+       for (i = 1000; i > 0 &&
+                       (ath5k_hw_reg_read(ah, AR5K_CR) & AR5K_CR_RXE) != 0;
+                       i--)
+               udelay(10);
+
+       return i ? 0 : -EBUSY;
+}
+
+/**
+ * ath5k_hw_get_rxdp - Get RX Descriptor's address
+ *
+ * @ah: The &struct ath5k_hw
+ */
+u32 ath5k_hw_get_rxdp(struct ath5k_hw *ah)
+{
+       return ath5k_hw_reg_read(ah, AR5K_RXDP);
+}
+
+/**
+ * ath5k_hw_set_rxdp - Set RX Descriptor's address
+ *
+ * @ah: The &struct ath5k_hw
+ * @phys_addr: RX descriptor address
+ *
+ * XXX: Should we check if rx is enabled before setting rxdp ?
+ */
+void ath5k_hw_set_rxdp(struct ath5k_hw *ah, u32 phys_addr)
+{
+       ATH5K_TRACE(ah->ah_sc);
+
+       ath5k_hw_reg_write(ah, phys_addr, AR5K_RXDP);
+}
+
+
+/**********\
+* Transmit *
+\**********/
+
+/**
+ * ath5k_hw_start_tx_dma - Start DMA transmit for a specific queue
+ *
+ * @ah: The &struct ath5k_hw
+ * @queue: The hw queue number
+ *
+ * Start DMA transmit for a specific queue and since 5210 doesn't have
+ * QCU/DCU, set up queue parameters for 5210 here based on queue type (one
+ * queue for normal data and one queue for beacons). For queue setup
+ * on newer chips check out qcu.c. Returns -EINVAL if queue number is out
+ * of range or if queue is already disabled.
+ *
+ * NOTE: Must be called after setting up tx control descriptor for that
+ * queue (see below).
+ */
+int ath5k_hw_start_tx_dma(struct ath5k_hw *ah, unsigned int queue)
+{
+       u32 tx_queue;
+
+       ATH5K_TRACE(ah->ah_sc);
+       AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
+
+       /* Return if queue is declared inactive */
+       if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
+               return -EIO;
+
+       if (ah->ah_version == AR5K_AR5210) {
+               tx_queue = ath5k_hw_reg_read(ah, AR5K_CR);
+
+               /*
+                * Set the queue by type on 5210
+                */
+               switch (ah->ah_txq[queue].tqi_type) {
+               case AR5K_TX_QUEUE_DATA:
+                       tx_queue |= AR5K_CR_TXE0 & ~AR5K_CR_TXD0;
+                       break;
+               case AR5K_TX_QUEUE_BEACON:
+                       tx_queue |= AR5K_CR_TXE1 & ~AR5K_CR_TXD1;
+                       ath5k_hw_reg_write(ah, AR5K_BCR_TQ1V | AR5K_BCR_BDMAE,
+                                       AR5K_BSR);
+                       break;
+               case AR5K_TX_QUEUE_CAB:
+                       tx_queue |= AR5K_CR_TXE1 & ~AR5K_CR_TXD1;
+                       ath5k_hw_reg_write(ah, AR5K_BCR_TQ1FV | AR5K_BCR_TQ1V |
+                               AR5K_BCR_BDMAE, AR5K_BSR);
+                       break;
+               default:
+                       return -EINVAL;
+               }
+               /* Start queue */
+               ath5k_hw_reg_write(ah, tx_queue, AR5K_CR);
+               ath5k_hw_reg_read(ah, AR5K_CR);
+       } else {
+               /* Return if queue is disabled */
+               if (AR5K_REG_READ_Q(ah, AR5K_QCU_TXD, queue))
+                       return -EIO;
+
+               /* Start queue */
+               AR5K_REG_WRITE_Q(ah, AR5K_QCU_TXE, queue);
+       }
+
+       return 0;
+}
+
+/**
+ * ath5k_hw_stop_tx_dma - Stop DMA transmit on a specific queue
+ *
+ * @ah: The &struct ath5k_hw
+ * @queue: The hw queue number
+ *
+ * Stop DMA transmit on a specific hw queue and drain queue so we don't
+ * have any pending frames. Returns -EBUSY if we still have pending frames,
+ * -EINVAL if queue number is out of range.
+ *
+ */
+int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue)
+{
+       unsigned int i = 40;
+       u32 tx_queue, pending;
+
+       ATH5K_TRACE(ah->ah_sc);
+       AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
+
+       /* Return if queue is declared inactive */
+       if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
+               return -EIO;
+
+       if (ah->ah_version == AR5K_AR5210) {
+               tx_queue = ath5k_hw_reg_read(ah, AR5K_CR);
+
+               /*
+                * Set by queue type
+                */
+               switch (ah->ah_txq[queue].tqi_type) {
+               case AR5K_TX_QUEUE_DATA:
+                       tx_queue |= AR5K_CR_TXD0 & ~AR5K_CR_TXE0;
+                       break;
+               case AR5K_TX_QUEUE_BEACON:
+               case AR5K_TX_QUEUE_CAB:
+                       /* XXX Fix me... */
+                       tx_queue |= AR5K_CR_TXD1 & ~AR5K_CR_TXD1;
+                       ath5k_hw_reg_write(ah, 0, AR5K_BSR);
+                       break;
+               default:
+                       return -EINVAL;
+               }
+
+               /* Stop queue */
+               ath5k_hw_reg_write(ah, tx_queue, AR5K_CR);
+               ath5k_hw_reg_read(ah, AR5K_CR);
+       } else {
+               /*
+                * Schedule TX disable and wait until queue is empty
+                */
+               AR5K_REG_WRITE_Q(ah, AR5K_QCU_TXD, queue);
+
+               /*Check for pending frames*/
+               do {
+                       pending = ath5k_hw_reg_read(ah,
+                               AR5K_QUEUE_STATUS(queue)) &
+                               AR5K_QCU_STS_FRMPENDCNT;
+                       udelay(100);
+               } while (--i && pending);
+
+               /* For 2413+ order PCU to drop packets using
+                * QUIET mechanism */
+               if (ah->ah_mac_version >= (AR5K_SREV_AR2414 >> 4) &&
+               pending){
+                       /* Set periodicity and duration */
+                       ath5k_hw_reg_write(ah,
+                               AR5K_REG_SM(100, AR5K_QUIET_CTL2_QT_PER)|
+                               AR5K_REG_SM(10, AR5K_QUIET_CTL2_QT_DUR),
+                               AR5K_QUIET_CTL2);
+
+                       /* Enable quiet period for current TSF */
+                       ath5k_hw_reg_write(ah,
+                               AR5K_QUIET_CTL1_QT_EN |
+                               AR5K_REG_SM(ath5k_hw_reg_read(ah,
+                                               AR5K_TSF_L32_5211) >> 10,
+                                               AR5K_QUIET_CTL1_NEXT_QT_TSF),
+                               AR5K_QUIET_CTL1);
+
+                       /* Force channel idle high */
+                       AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW_5211,
+                                       AR5K_DIAG_SW_CHANEL_IDLE_HIGH);
+
+                       /* Wait a while and disable mechanism */
+                       udelay(200);
+                       AR5K_REG_DISABLE_BITS(ah, AR5K_QUIET_CTL1,
+                                               AR5K_QUIET_CTL1_QT_EN);
+
+                       /* Re-check for pending frames */
+                       i = 40;
+                       do {
+                               pending = ath5k_hw_reg_read(ah,
+                                       AR5K_QUEUE_STATUS(queue)) &
+                                       AR5K_QCU_STS_FRMPENDCNT;
+                               udelay(100);
+                       } while (--i && pending);
+
+                       AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW_5211,
+                                       AR5K_DIAG_SW_CHANEL_IDLE_HIGH);
+               }
+
+               /* Clear register */
+               ath5k_hw_reg_write(ah, 0, AR5K_QCU_TXD);
+               if (pending)
+                       return -EBUSY;
+       }
+
+       /* TODO: Check for success on 5210 else return error */
+       return 0;
+}
+
+/**
+ * ath5k_hw_get_txdp - Get TX Descriptor's address for a specific queue
+ *
+ * @ah: The &struct ath5k_hw
+ * @queue: The hw queue number
+ *
+ * Get TX descriptor's address for a specific queue. For 5210 we ignore
+ * the queue number and use tx queue type since we only have 2 queues.
+ * We use TXDP0 for normal data queue and TXDP1 for beacon queue.
+ * For newer chips with QCU/DCU we just read the corresponding TXDP register.
+ *
+ * XXX: Is TXDP read and clear ?
+ */
+u32 ath5k_hw_get_txdp(struct ath5k_hw *ah, unsigned int queue)
+{
+       u16 tx_reg;
+
+       ATH5K_TRACE(ah->ah_sc);
+       AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
+
+       /*
+        * Get the transmit queue descriptor pointer from the selected queue
+        */
+       /*5210 doesn't have QCU*/
+       if (ah->ah_version == AR5K_AR5210) {
+               switch (ah->ah_txq[queue].tqi_type) {
+               case AR5K_TX_QUEUE_DATA:
+                       tx_reg = AR5K_NOQCU_TXDP0;
+                       break;
+               case AR5K_TX_QUEUE_BEACON:
+               case AR5K_TX_QUEUE_CAB:
+                       tx_reg = AR5K_NOQCU_TXDP1;
+                       break;
+               default:
+                       return 0xffffffff;
+               }
+       } else {
+               tx_reg = AR5K_QUEUE_TXDP(queue);
+       }
+
+       return ath5k_hw_reg_read(ah, tx_reg);
+}
+
+/**
+ * ath5k_hw_set_txdp - Set TX Descriptor's address for a specific queue
+ *
+ * @ah: The &struct ath5k_hw
+ * @queue: The hw queue number
+ *
+ * Set TX descriptor's address for a specific queue. For 5210 we ignore
+ * the queue number and we use tx queue type since we only have 2 queues
+ * so as above we use TXDP0 for normal data queue and TXDP1 for beacon queue.
+ * For newer chips with QCU/DCU we just set the corresponding TXDP register.
+ * Returns -EINVAL if queue type is invalid for 5210 and -EIO if queue is still
+ * active.
+ */
+int ath5k_hw_set_txdp(struct ath5k_hw *ah, unsigned int queue, u32 phys_addr)
+{
+       u16 tx_reg;
+
+       ATH5K_TRACE(ah->ah_sc);
+       AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
+
+       /*
+        * Set the transmit queue descriptor pointer register by type
+        * on 5210
+        */
+       if (ah->ah_version == AR5K_AR5210) {
+               switch (ah->ah_txq[queue].tqi_type) {
+               case AR5K_TX_QUEUE_DATA:
+                       tx_reg = AR5K_NOQCU_TXDP0;
+                       break;
+               case AR5K_TX_QUEUE_BEACON:
+               case AR5K_TX_QUEUE_CAB:
+                       tx_reg = AR5K_NOQCU_TXDP1;
+                       break;
+               default:
+                       return -EINVAL;
+               }
+       } else {
+               /*
+                * Set the transmit queue descriptor pointer for
+                * the selected queue on QCU for 5211+
+                * (this won't work if the queue is still active)
+                */
+               if (AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, queue))
+                       return -EIO;
+
+               tx_reg = AR5K_QUEUE_TXDP(queue);
+       }
+
+       /* Set descriptor pointer */
+       ath5k_hw_reg_write(ah, phys_addr, tx_reg);
+
+       return 0;
+}
+
+/**
+ * ath5k_hw_update_tx_triglevel - Update tx trigger level
+ *
+ * @ah: The &struct ath5k_hw
+ * @increase: Flag to force increase of trigger level
+ *
+ * This function increases/decreases the tx trigger level for the tx fifo
+ * buffer (aka FIFO threshold) that is used to indicate when PCU flushes
+ * the buffer and transmits it's data. Lowering this results sending small
+ * frames more quickly but can lead to tx underruns, raising it a lot can
+ * result other problems (i think bmiss is related). Right now we start with
+ * the lowest possible (64Bytes) and if we get tx underrun we increase it using
+ * the increase flag. Returns -EIO if we have have reached maximum/minimum.
+ *
+ * XXX: Link this with tx DMA size ?
+ * XXX: Use it to save interrupts ?
+ * TODO: Needs testing, i think it's related to bmiss...
+ */
+int ath5k_hw_update_tx_triglevel(struct ath5k_hw *ah, bool increase)
+{
+       u32 trigger_level, imr;
+       int ret = -EIO;
+
+       ATH5K_TRACE(ah->ah_sc);
+
+       /*
+        * Disable interrupts by setting the mask
+        */
+       imr = ath5k_hw_set_imr(ah, ah->ah_imr & ~AR5K_INT_GLOBAL);
+
+       trigger_level = AR5K_REG_MS(ath5k_hw_reg_read(ah, AR5K_TXCFG),
+                       AR5K_TXCFG_TXFULL);
+
+       if (!increase) {
+               if (--trigger_level < AR5K_TUNE_MIN_TX_FIFO_THRES)
+                       goto done;
+       } else
+               trigger_level +=
+                       ((AR5K_TUNE_MAX_TX_FIFO_THRES - trigger_level) / 2);
+
+       /*
+        * Update trigger level on success
+        */
+       if (ah->ah_version == AR5K_AR5210)
+               ath5k_hw_reg_write(ah, trigger_level, AR5K_TRIG_LVL);
+       else
+               AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG,
+                               AR5K_TXCFG_TXFULL, trigger_level);
+
+       ret = 0;
+
+done:
+       /*
+        * Restore interrupt mask
+        */
+       ath5k_hw_set_imr(ah, imr);
+
+       return ret;
+}
+
+/*******************\
+* Interrupt masking *
+\*******************/
+
+/**
+ * ath5k_hw_is_intr_pending - Check if we have pending interrupts
+ *
+ * @ah: The &struct ath5k_hw
+ *
+ * Check if we have pending interrupts to process. Returns 1 if we
+ * have pending interrupts and 0 if we haven't.
+ */
+bool ath5k_hw_is_intr_pending(struct ath5k_hw *ah)
+{
+       ATH5K_TRACE(ah->ah_sc);
+       return ath5k_hw_reg_read(ah, AR5K_INTPEND) == 1 ? 1 : 0;
+}
+
+/**
+ * ath5k_hw_get_isr - Get interrupt status
+ *
+ * @ah: The @struct ath5k_hw
+ * @interrupt_mask: Driver's interrupt mask used to filter out
+ * interrupts in sw.
+ *
+ * This function is used inside our interrupt handler to determine the reason
+ * for the interrupt by reading Primary Interrupt Status Register. Returns an
+ * abstract interrupt status mask which is mostly ISR with some uncommon bits
+ * being mapped on some standard non hw-specific positions
+ * (check out &ath5k_int).
+ *
+ * NOTE: We use read-and-clear register, so after this function is called ISR
+ * is zeroed.
+ */
+int ath5k_hw_get_isr(struct ath5k_hw *ah, enum ath5k_int *interrupt_mask)
+{
+       u32 data;
+
+       ATH5K_TRACE(ah->ah_sc);
+
+       /*
+        * Read interrupt status from the Interrupt Status register
+        * on 5210
+        */
+       if (ah->ah_version == AR5K_AR5210) {
+               data = ath5k_hw_reg_read(ah, AR5K_ISR);
+               if (unlikely(data == AR5K_INT_NOCARD)) {
+                       *interrupt_mask = data;
+                       return -ENODEV;
+               }
+       } else {
+               /*
+                * Read interrupt status from Interrupt
+                * Status Register shadow copy (Read And Clear)
+                *
+                * Note: PISR/SISR Not available on 5210
+                */
+               data = ath5k_hw_reg_read(ah, AR5K_RAC_PISR);
+               if (unlikely(data == AR5K_INT_NOCARD)) {
+                       *interrupt_mask = data;
+                       return -ENODEV;
+               }
+       }
+
+       /*
+        * Get abstract interrupt mask (driver-compatible)
+        */
+       *interrupt_mask = (data & AR5K_INT_COMMON) & ah->ah_imr;
+
+       if (ah->ah_version != AR5K_AR5210) {
+               u32 sisr2 = ath5k_hw_reg_read(ah, AR5K_RAC_SISR2);
+
+               /*HIU = Host Interface Unit (PCI etc)*/
+               if (unlikely(data & (AR5K_ISR_HIUERR)))
+                       *interrupt_mask |= AR5K_INT_FATAL;
+
+               /*Beacon Not Ready*/
+               if (unlikely(data & (AR5K_ISR_BNR)))
+                       *interrupt_mask |= AR5K_INT_BNR;
+
+               if (unlikely(sisr2 & (AR5K_SISR2_SSERR |
+                                       AR5K_SISR2_DPERR |
+                                       AR5K_SISR2_MCABT)))
+                       *interrupt_mask |= AR5K_INT_FATAL;
+
+               if (data & AR5K_ISR_TIM)
+                       *interrupt_mask |= AR5K_INT_TIM;
+
+               if (data & AR5K_ISR_BCNMISC) {
+                       if (sisr2 & AR5K_SISR2_TIM)
+                               *interrupt_mask |= AR5K_INT_TIM;
+                       if (sisr2 & AR5K_SISR2_DTIM)
+                               *interrupt_mask |= AR5K_INT_DTIM;
+                       if (sisr2 & AR5K_SISR2_DTIM_SYNC)
+                               *interrupt_mask |= AR5K_INT_DTIM_SYNC;
+                       if (sisr2 & AR5K_SISR2_BCN_TIMEOUT)
+                               *interrupt_mask |= AR5K_INT_BCN_TIMEOUT;
+                       if (sisr2 & AR5K_SISR2_CAB_TIMEOUT)
+                               *interrupt_mask |= AR5K_INT_CAB_TIMEOUT;
+               }
+
+               if (data & AR5K_ISR_RXDOPPLER)
+                       *interrupt_mask |= AR5K_INT_RX_DOPPLER;
+               if (data & AR5K_ISR_QCBRORN) {
+                       *interrupt_mask |= AR5K_INT_QCBRORN;
+                       ah->ah_txq_isr |= AR5K_REG_MS(
+                                       ath5k_hw_reg_read(ah, AR5K_RAC_SISR3),
+                                       AR5K_SISR3_QCBRORN);
+               }
+               if (data & AR5K_ISR_QCBRURN) {
+                       *interrupt_mask |= AR5K_INT_QCBRURN;
+                       ah->ah_txq_isr |= AR5K_REG_MS(
+                                       ath5k_hw_reg_read(ah, AR5K_RAC_SISR3),
+                                       AR5K_SISR3_QCBRURN);
+               }
+               if (data & AR5K_ISR_QTRIG) {
+                       *interrupt_mask |= AR5K_INT_QTRIG;
+                       ah->ah_txq_isr |= AR5K_REG_MS(
+                                       ath5k_hw_reg_read(ah, AR5K_RAC_SISR4),
+                                       AR5K_SISR4_QTRIG);
+               }
+
+               if (data & AR5K_ISR_TXOK)
+                       ah->ah_txq_isr |= AR5K_REG_MS(
+                                       ath5k_hw_reg_read(ah, AR5K_RAC_SISR0),
+                                       AR5K_SISR0_QCU_TXOK);
+
+               if (data & AR5K_ISR_TXDESC)
+                       ah->ah_txq_isr |= AR5K_REG_MS(
+                                       ath5k_hw_reg_read(ah, AR5K_RAC_SISR0),
+                                       AR5K_SISR0_QCU_TXDESC);
+
+               if (data & AR5K_ISR_TXERR)
+                       ah->ah_txq_isr |= AR5K_REG_MS(
+                                       ath5k_hw_reg_read(ah, AR5K_RAC_SISR1),
+                                       AR5K_SISR1_QCU_TXERR);
+
+               if (data & AR5K_ISR_TXEOL)
+                       ah->ah_txq_isr |= AR5K_REG_MS(
+                                       ath5k_hw_reg_read(ah, AR5K_RAC_SISR1),
+                                       AR5K_SISR1_QCU_TXEOL);
+
+               if (data & AR5K_ISR_TXURN)
+                       ah->ah_txq_isr |= AR5K_REG_MS(
+                                       ath5k_hw_reg_read(ah, AR5K_RAC_SISR2),
+                                       AR5K_SISR2_QCU_TXURN);
+       } else {
+               if (unlikely(data & (AR5K_ISR_SSERR | AR5K_ISR_MCABT
+                               | AR5K_ISR_HIUERR | AR5K_ISR_DPERR)))
+                       *interrupt_mask |= AR5K_INT_FATAL;
+
+               /*
+                * XXX: BMISS interrupts may occur after association.
+                * I found this on 5210 code but it needs testing. If this is
+                * true we should disable them before assoc and re-enable them
+                * after a successful assoc + some jiffies.
+                       interrupt_mask &= ~AR5K_INT_BMISS;
+                */
+       }
+
+       /*
+        * In case we didn't handle anything,
+        * print the register value.
+        */
+       if (unlikely(*interrupt_mask == 0 && net_ratelimit()))
+               ATH5K_PRINTF("ISR: 0x%08x IMR: 0x%08x\n", data, ah->ah_imr);
+
+       return 0;
+}
+
+/**
+ * ath5k_hw_set_imr - Set interrupt mask
+ *
+ * @ah: The &struct ath5k_hw
+ * @new_mask: The new interrupt mask to be set
+ *
+ * Set the interrupt mask in hw to save interrupts. We do that by mapping
+ * ath5k_int bits to hw-specific bits to remove abstraction and writing
+ * Interrupt Mask Register.
+ */
+enum ath5k_int ath5k_hw_set_imr(struct ath5k_hw *ah, enum ath5k_int new_mask)
+{
+       enum ath5k_int old_mask, int_mask;
+
+       old_mask = ah->ah_imr;
+
+       /*
+        * Disable card interrupts to prevent any race conditions
+        * (they will be re-enabled afterwards if AR5K_INT GLOBAL
+        * is set again on the new mask).
+        */
+       if (old_mask & AR5K_INT_GLOBAL) {
+               ath5k_hw_reg_write(ah, AR5K_IER_DISABLE, AR5K_IER);
+               ath5k_hw_reg_read(ah, AR5K_IER);
+       }
+
+       /*
+        * Add additional, chipset-dependent interrupt mask flags
+        * and write them to the IMR (interrupt mask register).
+        */
+       int_mask = new_mask & AR5K_INT_COMMON;
+
+       if (ah->ah_version != AR5K_AR5210) {
+               /* Preserve per queue TXURN interrupt mask */
+               u32 simr2 = ath5k_hw_reg_read(ah, AR5K_SIMR2)
+                               & AR5K_SIMR2_QCU_TXURN;
+
+               if (new_mask & AR5K_INT_FATAL) {
+                       int_mask |= AR5K_IMR_HIUERR;
+                       simr2 |= (AR5K_SIMR2_MCABT | AR5K_SIMR2_SSERR
+                               | AR5K_SIMR2_DPERR);
+               }
+
+               /*Beacon Not Ready*/
+               if (new_mask & AR5K_INT_BNR)
+                       int_mask |= AR5K_INT_BNR;
+
+               if (new_mask & AR5K_INT_TIM)
+                       int_mask |= AR5K_IMR_TIM;
+
+               if (new_mask & AR5K_INT_TIM)
+                       simr2 |= AR5K_SISR2_TIM;
+               if (new_mask & AR5K_INT_DTIM)
+                       simr2 |= AR5K_SISR2_DTIM;
+               if (new_mask & AR5K_INT_DTIM_SYNC)
+                       simr2 |= AR5K_SISR2_DTIM_SYNC;
+               if (new_mask & AR5K_INT_BCN_TIMEOUT)
+                       simr2 |= AR5K_SISR2_BCN_TIMEOUT;
+               if (new_mask & AR5K_INT_CAB_TIMEOUT)
+                       simr2 |= AR5K_SISR2_CAB_TIMEOUT;
+
+               if (new_mask & AR5K_INT_RX_DOPPLER)
+                       int_mask |= AR5K_IMR_RXDOPPLER;
+
+               /* Note: Per queue interrupt masks
+                * are set via reset_tx_queue (qcu.c) */
+               ath5k_hw_reg_write(ah, int_mask, AR5K_PIMR);
+               ath5k_hw_reg_write(ah, simr2, AR5K_SIMR2);
+
+       } else {
+               if (new_mask & AR5K_INT_FATAL)
+                       int_mask |= (AR5K_IMR_SSERR | AR5K_IMR_MCABT
+                               | AR5K_IMR_HIUERR | AR5K_IMR_DPERR);
+
+               ath5k_hw_reg_write(ah, int_mask, AR5K_IMR);
+       }
+
+       /* If RXNOFRM interrupt is masked disable it
+        * by setting AR5K_RXNOFRM to zero */
+       if (!(new_mask & AR5K_INT_RXNOFRM))
+               ath5k_hw_reg_write(ah, 0, AR5K_RXNOFRM);
+
+       /* Store new interrupt mask */
+       ah->ah_imr = new_mask;
+
+       /* ..re-enable interrupts if AR5K_INT_GLOBAL is set */
+       if (new_mask & AR5K_INT_GLOBAL) {
+               ath5k_hw_reg_write(ah, AR5K_IER_ENABLE, AR5K_IER);
+               ath5k_hw_reg_read(ah, AR5K_IER);
+       }
+
+       return old_mask;
+}
+
diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c
new file mode 100644 (file)
index 0000000..c56b494
--- /dev/null
@@ -0,0 +1,1802 @@
+/*
+ * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
+ * Copyright (c) 2006-2009 Nick Kossifidis <mickflemm@gmail.com>
+ * Copyright (c) 2008-2009 Felix Fietkau <nbd@openwrt.org>
+ *
+ * Permission to use, copy, modify, and 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.
+ *
+ */
+
+/*************************************\
+* EEPROM access functions and helpers *
+\*************************************/
+
+#include "ath5k.h"
+#include "reg.h"
+#include "debug.h"
+#include "base.h"
+
+/*
+ * Read from eeprom
+ */
+static int ath5k_hw_eeprom_read(struct ath5k_hw *ah, u32 offset, u16 *data)
+{
+       u32 status, timeout;
+
+       ATH5K_TRACE(ah->ah_sc);
+       /*
+        * Initialize EEPROM access
+        */
+       if (ah->ah_version == AR5K_AR5210) {
+               AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, AR5K_PCICFG_EEAE);
+               (void)ath5k_hw_reg_read(ah, AR5K_EEPROM_BASE + (4 * offset));
+       } else {
+               ath5k_hw_reg_write(ah, offset, AR5K_EEPROM_BASE);
+               AR5K_REG_ENABLE_BITS(ah, AR5K_EEPROM_CMD,
+                               AR5K_EEPROM_CMD_READ);
+       }
+
+       for (timeout = AR5K_TUNE_REGISTER_TIMEOUT; timeout > 0; timeout--) {
+               status = ath5k_hw_reg_read(ah, AR5K_EEPROM_STATUS);
+               if (status & AR5K_EEPROM_STAT_RDDONE) {
+                       if (status & AR5K_EEPROM_STAT_RDERR)
+                               return -EIO;
+                       *data = (u16)(ath5k_hw_reg_read(ah, AR5K_EEPROM_DATA) &
+                                       0xffff);
+                       return 0;
+               }
+               udelay(15);
+       }
+
+       return -ETIMEDOUT;
+}
+
+/*
+ * Translate binary channel representation in EEPROM to frequency
+ */
+static u16 ath5k_eeprom_bin2freq(struct ath5k_eeprom_info *ee, u16 bin,
+                                 unsigned int mode)
+{
+       u16 val;
+
+       if (bin == AR5K_EEPROM_CHANNEL_DIS)
+               return bin;
+
+       if (mode == AR5K_EEPROM_MODE_11A) {
+               if (ee->ee_version > AR5K_EEPROM_VERSION_3_2)
+                       val = (5 * bin) + 4800;
+               else
+                       val = bin > 62 ? (10 * 62) + (5 * (bin - 62)) + 5100 :
+                               (bin * 10) + 5100;
+       } else {
+               if (ee->ee_version > AR5K_EEPROM_VERSION_3_2)
+                       val = bin + 2300;
+               else
+                       val = bin + 2400;
+       }
+
+       return val;
+}
+
+/*
+ * Initialize eeprom & capabilities structs
+ */
+static int
+ath5k_eeprom_init_header(struct ath5k_hw *ah)
+{
+       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+       int ret;
+       u16 val;
+
+       /*
+        * Read values from EEPROM and store them in the capability structure
+        */
+       AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MAGIC, ee_magic);
+       AR5K_EEPROM_READ_HDR(AR5K_EEPROM_PROTECT, ee_protect);
+       AR5K_EEPROM_READ_HDR(AR5K_EEPROM_REG_DOMAIN, ee_regdomain);
+       AR5K_EEPROM_READ_HDR(AR5K_EEPROM_VERSION, ee_version);
+       AR5K_EEPROM_READ_HDR(AR5K_EEPROM_HDR, ee_header);
+
+       /* Return if we have an old EEPROM */
+       if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_0)
+               return 0;
+
+#ifdef notyet
+       /*
+        * Validate the checksum of the EEPROM date. There are some
+        * devices with invalid EEPROMs.
+        */
+       for (cksum = 0, offset = 0; offset < AR5K_EEPROM_INFO_MAX; offset++) {
+               AR5K_EEPROM_READ(AR5K_EEPROM_INFO(offset), val);
+               cksum ^= val;
+       }
+       if (cksum != AR5K_EEPROM_INFO_CKSUM) {
+               ATH5K_ERR(ah->ah_sc, "Invalid EEPROM checksum 0x%04x\n", cksum);
+               return -EIO;
+       }
+#endif
+
+       AR5K_EEPROM_READ_HDR(AR5K_EEPROM_ANT_GAIN(ah->ah_ee_version),
+           ee_ant_gain);
+
+       if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) {
+               AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC0, ee_misc0);
+               AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC1, ee_misc1);
+
+               /* XXX: Don't know which versions include these two */
+               AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC2, ee_misc2);
+
+               if (ee->ee_version >= AR5K_EEPROM_VERSION_4_3)
+                       AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC3, ee_misc3);
+
+               if (ee->ee_version >= AR5K_EEPROM_VERSION_5_0) {
+                       AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC4, ee_misc4);
+                       AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC5, ee_misc5);
+                       AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC6, ee_misc6);
+               }
+       }
+
+       if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_3) {
+               AR5K_EEPROM_READ(AR5K_EEPROM_OBDB0_2GHZ, val);
+               ee->ee_ob[AR5K_EEPROM_MODE_11B][0] = val & 0x7;
+               ee->ee_db[AR5K_EEPROM_MODE_11B][0] = (val >> 3) & 0x7;
+
+               AR5K_EEPROM_READ(AR5K_EEPROM_OBDB1_2GHZ, val);
+               ee->ee_ob[AR5K_EEPROM_MODE_11G][0] = val & 0x7;
+               ee->ee_db[AR5K_EEPROM_MODE_11G][0] = (val >> 3) & 0x7;
+       }
+
+       AR5K_EEPROM_READ(AR5K_EEPROM_IS_HB63, val);
+
+       if ((ah->ah_mac_version == (AR5K_SREV_AR2425 >> 4)) && val)
+               ee->ee_is_hb63 = true;
+       else
+               ee->ee_is_hb63 = false;
+
+       AR5K_EEPROM_READ(AR5K_EEPROM_RFKILL, val);
+       ee->ee_rfkill_pin = (u8) AR5K_REG_MS(val, AR5K_EEPROM_RFKILL_GPIO_SEL);
+       ee->ee_rfkill_pol = val & AR5K_EEPROM_RFKILL_POLARITY ? true : false;
+
+       return 0;
+}
+
+
+/*
+ * Read antenna infos from eeprom
+ */
+static int ath5k_eeprom_read_ants(struct ath5k_hw *ah, u32 *offset,
+               unsigned int mode)
+{
+       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+       u32 o = *offset;
+       u16 val;
+       int ret, i = 0;
+
+       AR5K_EEPROM_READ(o++, val);
+       ee->ee_switch_settling[mode]    = (val >> 8) & 0x7f;
+       ee->ee_atn_tx_rx[mode]          = (val >> 2) & 0x3f;
+       ee->ee_ant_control[mode][i]     = (val << 4) & 0x3f;
+
+       AR5K_EEPROM_READ(o++, val);
+       ee->ee_ant_control[mode][i++]   |= (val >> 12) & 0xf;
+       ee->ee_ant_control[mode][i++]   = (val >> 6) & 0x3f;
+       ee->ee_ant_control[mode][i++]   = val & 0x3f;
+
+       AR5K_EEPROM_READ(o++, val);
+       ee->ee_ant_control[mode][i++]   = (val >> 10) & 0x3f;
+       ee->ee_ant_control[mode][i++]   = (val >> 4) & 0x3f;
+       ee->ee_ant_control[mode][i]     = (val << 2) & 0x3f;
+
+       AR5K_EEPROM_READ(o++, val);
+       ee->ee_ant_control[mode][i++]   |= (val >> 14) & 0x3;
+       ee->ee_ant_control[mode][i++]   = (val >> 8) & 0x3f;
+       ee->ee_ant_control[mode][i++]   = (val >> 2) & 0x3f;
+       ee->ee_ant_control[mode][i]     = (val << 4) & 0x3f;
+
+       AR5K_EEPROM_READ(o++, val);
+       ee->ee_ant_control[mode][i++]   |= (val >> 12) & 0xf;
+       ee->ee_ant_control[mode][i++]   = (val >> 6) & 0x3f;
+       ee->ee_ant_control[mode][i++]   = val & 0x3f;
+
+       /* Get antenna switch tables */
+       ah->ah_ant_ctl[mode][AR5K_ANT_CTL] =
+           (ee->ee_ant_control[mode][0] << 4);
+       ah->ah_ant_ctl[mode][AR5K_ANT_SWTABLE_A] =
+            ee->ee_ant_control[mode][1]        |
+           (ee->ee_ant_control[mode][2] << 6)  |
+           (ee->ee_ant_control[mode][3] << 12) |
+           (ee->ee_ant_control[mode][4] << 18) |
+           (ee->ee_ant_control[mode][5] << 24);
+       ah->ah_ant_ctl[mode][AR5K_ANT_SWTABLE_B] =
+            ee->ee_ant_control[mode][6]        |
+           (ee->ee_ant_control[mode][7] << 6)  |
+           (ee->ee_ant_control[mode][8] << 12) |
+           (ee->ee_ant_control[mode][9] << 18) |
+           (ee->ee_ant_control[mode][10] << 24);
+
+       /* return new offset */
+       *offset = o;
+
+       return 0;
+}
+
+/*
+ * Read supported modes and some mode-specific calibration data
+ * from eeprom
+ */
+static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset,
+               unsigned int mode)
+{
+       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+       u32 o = *offset;
+       u16 val;
+       int ret;
+
+       ee->ee_n_piers[mode] = 0;
+       AR5K_EEPROM_READ(o++, val);
+       ee->ee_adc_desired_size[mode]   = (s8)((val >> 8) & 0xff);
+       switch(mode) {
+       case AR5K_EEPROM_MODE_11A:
+               ee->ee_ob[mode][3]      = (val >> 5) & 0x7;
+               ee->ee_db[mode][3]      = (val >> 2) & 0x7;
+               ee->ee_ob[mode][2]      = (val << 1) & 0x7;
+
+               AR5K_EEPROM_READ(o++, val);
+               ee->ee_ob[mode][2]      |= (val >> 15) & 0x1;
+               ee->ee_db[mode][2]      = (val >> 12) & 0x7;
+               ee->ee_ob[mode][1]      = (val >> 9) & 0x7;
+               ee->ee_db[mode][1]      = (val >> 6) & 0x7;
+               ee->ee_ob[mode][0]      = (val >> 3) & 0x7;
+               ee->ee_db[mode][0]      = val & 0x7;
+               break;
+       case AR5K_EEPROM_MODE_11G:
+       case AR5K_EEPROM_MODE_11B:
+               ee->ee_ob[mode][1]      = (val >> 4) & 0x7;
+               ee->ee_db[mode][1]      = val & 0x7;
+               break;
+       }
+
+       AR5K_EEPROM_READ(o++, val);
+       ee->ee_tx_end2xlna_enable[mode] = (val >> 8) & 0xff;
+       ee->ee_thr_62[mode]             = val & 0xff;
+
+       if (ah->ah_ee_version <= AR5K_EEPROM_VERSION_3_2)
+               ee->ee_thr_62[mode] = mode == AR5K_EEPROM_MODE_11A ? 15 : 28;
+
+       AR5K_EEPROM_READ(o++, val);
+       ee->ee_tx_end2xpa_disable[mode] = (val >> 8) & 0xff;
+       ee->ee_tx_frm2xpa_enable[mode]  = val & 0xff;
+
+       AR5K_EEPROM_READ(o++, val);
+       ee->ee_pga_desired_size[mode]   = (val >> 8) & 0xff;
+
+       if ((val & 0xff) & 0x80)
+               ee->ee_noise_floor_thr[mode] = -((((val & 0xff) ^ 0xff)) + 1);
+       else
+               ee->ee_noise_floor_thr[mode] = val & 0xff;
+
+       if (ah->ah_ee_version <= AR5K_EEPROM_VERSION_3_2)
+               ee->ee_noise_floor_thr[mode] =
+                   mode == AR5K_EEPROM_MODE_11A ? -54 : -1;
+
+       AR5K_EEPROM_READ(o++, val);
+       ee->ee_xlna_gain[mode]          = (val >> 5) & 0xff;
+       ee->ee_x_gain[mode]             = (val >> 1) & 0xf;
+       ee->ee_xpd[mode]                = val & 0x1;
+
+       if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0)
+               ee->ee_fixed_bias[mode] = (val >> 13) & 0x1;
+
+       if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_3_3) {
+               AR5K_EEPROM_READ(o++, val);
+               ee->ee_false_detect[mode] = (val >> 6) & 0x7f;
+
+               if (mode == AR5K_EEPROM_MODE_11A)
+                       ee->ee_xr_power[mode] = val & 0x3f;
+               else {
+                       ee->ee_ob[mode][0] = val & 0x7;
+                       ee->ee_db[mode][0] = (val >> 3) & 0x7;
+               }
+       }
+
+       if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_4) {
+               ee->ee_i_gain[mode] = AR5K_EEPROM_I_GAIN;
+               ee->ee_cck_ofdm_power_delta = AR5K_EEPROM_CCK_OFDM_DELTA;
+       } else {
+               ee->ee_i_gain[mode] = (val >> 13) & 0x7;
+
+               AR5K_EEPROM_READ(o++, val);
+               ee->ee_i_gain[mode] |= (val << 3) & 0x38;
+
+               if (mode == AR5K_EEPROM_MODE_11G) {
+                       ee->ee_cck_ofdm_power_delta = (val >> 3) & 0xff;
+                       if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_6)
+                               ee->ee_scaled_cck_delta = (val >> 11) & 0x1f;
+               }
+       }
+
+       if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0 &&
+                       mode == AR5K_EEPROM_MODE_11A) {
+               ee->ee_i_cal[mode] = (val >> 8) & 0x3f;
+               ee->ee_q_cal[mode] = (val >> 3) & 0x1f;
+       }
+
+       if (ah->ah_ee_version < AR5K_EEPROM_VERSION_4_0)
+               goto done;
+
+       /* Note: >= v5 have bg freq piers on another location
+        * so these freq piers are ignored for >= v5 (should be 0xff
+        * anyway) */
+       switch(mode) {
+       case AR5K_EEPROM_MODE_11A:
+               if (ah->ah_ee_version < AR5K_EEPROM_VERSION_4_1)
+                       break;
+
+               AR5K_EEPROM_READ(o++, val);
+               ee->ee_margin_tx_rx[mode] = val & 0x3f;
+               break;
+       case AR5K_EEPROM_MODE_11B:
+               AR5K_EEPROM_READ(o++, val);
+
+               ee->ee_pwr_cal_b[0].freq =
+                       ath5k_eeprom_bin2freq(ee, val & 0xff, mode);
+               if (ee->ee_pwr_cal_b[0].freq != AR5K_EEPROM_CHANNEL_DIS)
+                       ee->ee_n_piers[mode]++;
+
+               ee->ee_pwr_cal_b[1].freq =
+                       ath5k_eeprom_bin2freq(ee, (val >> 8) & 0xff, mode);
+               if (ee->ee_pwr_cal_b[1].freq != AR5K_EEPROM_CHANNEL_DIS)
+                       ee->ee_n_piers[mode]++;
+
+               AR5K_EEPROM_READ(o++, val);
+               ee->ee_pwr_cal_b[2].freq =
+                       ath5k_eeprom_bin2freq(ee, val & 0xff, mode);
+               if (ee->ee_pwr_cal_b[2].freq != AR5K_EEPROM_CHANNEL_DIS)
+                       ee->ee_n_piers[mode]++;
+
+               if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1)
+                       ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f;
+               break;
+       case AR5K_EEPROM_MODE_11G:
+               AR5K_EEPROM_READ(o++, val);
+
+               ee->ee_pwr_cal_g[0].freq =
+                       ath5k_eeprom_bin2freq(ee, val & 0xff, mode);
+               if (ee->ee_pwr_cal_g[0].freq != AR5K_EEPROM_CHANNEL_DIS)
+                       ee->ee_n_piers[mode]++;
+
+               ee->ee_pwr_cal_g[1].freq =
+                       ath5k_eeprom_bin2freq(ee, (val >> 8) & 0xff, mode);
+               if (ee->ee_pwr_cal_g[1].freq != AR5K_EEPROM_CHANNEL_DIS)
+                       ee->ee_n_piers[mode]++;
+
+               AR5K_EEPROM_READ(o++, val);
+               ee->ee_turbo_max_power[mode] = val & 0x7f;
+               ee->ee_xr_power[mode] = (val >> 7) & 0x3f;
+
+               AR5K_EEPROM_READ(o++, val);
+               ee->ee_pwr_cal_g[2].freq =
+                       ath5k_eeprom_bin2freq(ee, val & 0xff, mode);
+               if (ee->ee_pwr_cal_g[2].freq != AR5K_EEPROM_CHANNEL_DIS)
+                       ee->ee_n_piers[mode]++;
+
+               if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1)
+                       ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f;
+
+               AR5K_EEPROM_READ(o++, val);
+               ee->ee_i_cal[mode] = (val >> 8) & 0x3f;
+               ee->ee_q_cal[mode] = (val >> 3) & 0x1f;
+
+               if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_2) {
+                       AR5K_EEPROM_READ(o++, val);
+                       ee->ee_cck_ofdm_gain_delta = val & 0xff;
+               }
+               break;
+       }
+
+done:
+       /* return new offset */
+       *offset = o;
+
+       return 0;
+}
+
+/*
+ * Read turbo mode information on newer EEPROM versions
+ */
+static int
+ath5k_eeprom_read_turbo_modes(struct ath5k_hw *ah,
+                             u32 *offset, unsigned int mode)
+{
+       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+       u32 o = *offset;
+       u16 val;
+       int ret;
+
+       if (ee->ee_version < AR5K_EEPROM_VERSION_5_0)
+               return 0;
+
+       switch (mode){
+       case AR5K_EEPROM_MODE_11A:
+               ee->ee_switch_settling_turbo[mode] = (val >> 6) & 0x7f;
+
+               ee->ee_atn_tx_rx_turbo[mode] = (val >> 13) & 0x7;
+               AR5K_EEPROM_READ(o++, val);
+               ee->ee_atn_tx_rx_turbo[mode] |= (val & 0x7) << 3;
+               ee->ee_margin_tx_rx_turbo[mode] = (val >> 3) & 0x3f;
+
+               ee->ee_adc_desired_size_turbo[mode] = (val >> 9) & 0x7f;
+               AR5K_EEPROM_READ(o++, val);
+               ee->ee_adc_desired_size_turbo[mode] |= (val & 0x1) << 7;
+               ee->ee_pga_desired_size_turbo[mode] = (val >> 1) & 0xff;
+
+               if (AR5K_EEPROM_EEMAP(ee->ee_misc0) >=2)
+                       ee->ee_pd_gain_overlap = (val >> 9) & 0xf;
+               break;
+       case AR5K_EEPROM_MODE_11G:
+               ee->ee_switch_settling_turbo[mode] = (val >> 8) & 0x7f;
+
+               ee->ee_atn_tx_rx_turbo[mode] = (val >> 15) & 0x7;
+               AR5K_EEPROM_READ(o++, val);
+               ee->ee_atn_tx_rx_turbo[mode] |= (val & 0x1f) << 1;
+               ee->ee_margin_tx_rx_turbo[mode] = (val >> 5) & 0x3f;
+
+               ee->ee_adc_desired_size_turbo[mode] = (val >> 11) & 0x7f;
+               AR5K_EEPROM_READ(o++, val);
+               ee->ee_adc_desired_size_turbo[mode] |= (val & 0x7) << 5;
+               ee->ee_pga_desired_size_turbo[mode] = (val >> 3) & 0xff;
+               break;
+       }
+
+       /* return new offset */
+       *offset = o;
+
+       return 0;
+}
+
+/* Read mode-specific data (except power calibration data) */
+static int
+ath5k_eeprom_init_modes(struct ath5k_hw *ah)
+{
+       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+       u32 mode_offset[3];
+       unsigned int mode;
+       u32 offset;
+       int ret;
+
+       /*
+        * Get values for all modes
+        */
+       mode_offset[AR5K_EEPROM_MODE_11A] = AR5K_EEPROM_MODES_11A(ah->ah_ee_version);
+       mode_offset[AR5K_EEPROM_MODE_11B] = AR5K_EEPROM_MODES_11B(ah->ah_ee_version);
+       mode_offset[AR5K_EEPROM_MODE_11G] = AR5K_EEPROM_MODES_11G(ah->ah_ee_version);
+
+       ee->ee_turbo_max_power[AR5K_EEPROM_MODE_11A] =
+               AR5K_EEPROM_HDR_T_5GHZ_DBM(ee->ee_header);
+
+       for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G; mode++) {
+               offset = mode_offset[mode];
+
+               ret = ath5k_eeprom_read_ants(ah, &offset, mode);
+               if (ret)
+                       return ret;
+
+               ret = ath5k_eeprom_read_modes(ah, &offset, mode);
+               if (ret)
+                       return ret;
+
+               ret = ath5k_eeprom_read_turbo_modes(ah, &offset, mode);
+               if (ret)
+                       return ret;
+       }
+
+       /* override for older eeprom versions for better performance */
+       if (ah->ah_ee_version <= AR5K_EEPROM_VERSION_3_2) {
+               ee->ee_thr_62[AR5K_EEPROM_MODE_11A] = 15;
+               ee->ee_thr_62[AR5K_EEPROM_MODE_11B] = 28;
+               ee->ee_thr_62[AR5K_EEPROM_MODE_11G] = 28;
+       }
+
+       return 0;
+}
+
+/* Read the frequency piers for each mode (mostly used on newer eeproms with 0xff
+ * frequency mask) */
+static inline int
+ath5k_eeprom_read_freq_list(struct ath5k_hw *ah, int *offset, int max,
+                       struct ath5k_chan_pcal_info *pc, unsigned int mode)
+{
+       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+       int o = *offset;
+       int i = 0;
+       u8 freq1, freq2;
+       int ret;
+       u16 val;
+
+       ee->ee_n_piers[mode] = 0;
+       while(i < max) {
+               AR5K_EEPROM_READ(o++, val);
+
+               freq1 = val & 0xff;
+               if (!freq1)
+                       break;
+
+               pc[i++].freq = ath5k_eeprom_bin2freq(ee,
+                               freq1, mode);
+               ee->ee_n_piers[mode]++;
+
+               freq2 = (val >> 8) & 0xff;
+               if (!freq2)
+                       break;
+
+               pc[i++].freq = ath5k_eeprom_bin2freq(ee,
+                               freq2, mode);
+               ee->ee_n_piers[mode]++;
+       }
+
+       /* return new offset */
+       *offset = o;
+
+       return 0;
+}
+
+/* Read frequency piers for 802.11a */
+static int
+ath5k_eeprom_init_11a_pcal_freq(struct ath5k_hw *ah, int offset)
+{
+       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+       struct ath5k_chan_pcal_info *pcal = ee->ee_pwr_cal_a;
+       int i, ret;
+       u16 val;
+       u8 mask;
+
+       if (ee->ee_version >= AR5K_EEPROM_VERSION_3_3) {
+               ath5k_eeprom_read_freq_list(ah, &offset,
+                       AR5K_EEPROM_N_5GHZ_CHAN, pcal,
+                       AR5K_EEPROM_MODE_11A);
+       } else {
+               mask = AR5K_EEPROM_FREQ_M(ah->ah_ee_version);
+
+               AR5K_EEPROM_READ(offset++, val);
+               pcal[0].freq  = (val >> 9) & mask;
+               pcal[1].freq  = (val >> 2) & mask;
+               pcal[2].freq  = (val << 5) & mask;
+
+               AR5K_EEPROM_READ(offset++, val);
+               pcal[2].freq |= (val >> 11) & 0x1f;
+               pcal[3].freq  = (val >> 4) & mask;
+               pcal[4].freq  = (val << 3) & mask;
+
+               AR5K_EEPROM_READ(offset++, val);
+               pcal[4].freq |= (val >> 13) & 0x7;
+               pcal[5].freq  = (val >> 6) & mask;
+               pcal[6].freq  = (val << 1) & mask;
+
+               AR5K_EEPROM_READ(offset++, val);
+               pcal[6].freq |= (val >> 15) & 0x1;
+               pcal[7].freq  = (val >> 8) & mask;
+               pcal[8].freq  = (val >> 1) & mask;
+               pcal[9].freq  = (val << 6) & mask;
+
+               AR5K_EEPROM_READ(offset++, val);
+               pcal[9].freq |= (val >> 10) & 0x3f;
+
+               /* Fixed number of piers */
+               ee->ee_n_piers[AR5K_EEPROM_MODE_11A] = 10;
+
+               for (i = 0; i < AR5K_EEPROM_N_5GHZ_CHAN; i++) {
+                       pcal[i].freq = ath5k_eeprom_bin2freq(ee,
+                               pcal[i].freq, AR5K_EEPROM_MODE_11A);
+               }
+       }
+
+       return 0;
+}
+
+/* Read frequency piers for 802.11bg on eeprom versions >= 5 and eemap >= 2 */
+static inline int
+ath5k_eeprom_init_11bg_2413(struct ath5k_hw *ah, unsigned int mode, int offset)
+{
+       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+       struct ath5k_chan_pcal_info *pcal;
+
+       switch(mode) {
+       case AR5K_EEPROM_MODE_11B:
+               pcal = ee->ee_pwr_cal_b;
+               break;
+       case AR5K_EEPROM_MODE_11G:
+               pcal = ee->ee_pwr_cal_g;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       ath5k_eeprom_read_freq_list(ah, &offset,
+               AR5K_EEPROM_N_2GHZ_CHAN_2413, pcal,
+               mode);
+
+       return 0;
+}
+
+/*
+ * Read power calibration for RF5111 chips
+ *
+ * For RF5111 we have an XPD -eXternal Power Detector- curve
+ * for each calibrated channel. Each curve has 0,5dB Power steps
+ * on x axis and PCDAC steps (offsets) on y axis and looks like an
+ * exponential function. To recreate the curve we read 11 points
+ * here and interpolate later.
+ */
+
+/* Used to match PCDAC steps with power values on RF5111 chips
+ * (eeprom versions < 4). For RF5111 we have 11 pre-defined PCDAC
+ * steps that match with the power values we read from eeprom. On
+ * older eeprom versions (< 3.2) these steps are equaly spaced at
+ * 10% of the pcdac curve -until the curve reaches it's maximum-
+ * (11 steps from 0 to 100%) but on newer eeprom versions (>= 3.2)
+ * these 11 steps are spaced in a different way. This function returns
+ * the pcdac steps based on eeprom version and curve min/max so that we
+ * can have pcdac/pwr points.
+ */
+static inline void
+ath5k_get_pcdac_intercepts(struct ath5k_hw *ah, u8 min, u8 max, u8 *vp)
+{
+       static const u16 intercepts3[] =
+               { 0, 5, 10, 20, 30, 50, 70, 85, 90, 95, 100 };
+       static const u16 intercepts3_2[] =
+               { 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 };
+       const u16 *ip;
+       int i;
+
+       if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_3_2)
+               ip = intercepts3_2;
+       else
+               ip = intercepts3;
+
+       for (i = 0; i < ARRAY_SIZE(intercepts3); i++)
+               vp[i] = (ip[i] * max + (100 - ip[i]) * min) / 100;
+}
+
+/* Convert RF5111 specific data to generic raw data
+ * used by interpolation code */
+static int
+ath5k_eeprom_convert_pcal_info_5111(struct ath5k_hw *ah, int mode,
+                               struct ath5k_chan_pcal_info *chinfo)
+{
+       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+       struct ath5k_chan_pcal_info_rf5111 *pcinfo;
+       struct ath5k_pdgain_info *pd;
+       u8 pier, point, idx;
+       u8 *pdgain_idx = ee->ee_pdc_to_idx[mode];
+
+       /* Fill raw data for each calibration pier */
+       for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) {
+
+               pcinfo = &chinfo[pier].rf5111_info;
+
+               /* Allocate pd_curves for this cal pier */
+               chinfo[pier].pd_curves =
+                       kcalloc(AR5K_EEPROM_N_PD_CURVES,
+                               sizeof(struct ath5k_pdgain_info),
+                               GFP_KERNEL);
+
+               if (!chinfo[pier].pd_curves)
+                       return -ENOMEM;
+
+               /* Only one curve for RF5111
+                * find out which one and place
+                * in in pd_curves.
+                * Note: ee_x_gain is reversed here */
+               for (idx = 0; idx < AR5K_EEPROM_N_PD_CURVES; idx++) {
+
+                       if (!((ee->ee_x_gain[mode] >> idx) & 0x1)) {
+                               pdgain_idx[0] = idx;
+                               break;
+                       }
+               }
+
+               ee->ee_pd_gains[mode] = 1;
+
+               pd = &chinfo[pier].pd_curves[idx];
+
+               pd->pd_points = AR5K_EEPROM_N_PWR_POINTS_5111;
+
+               /* Allocate pd points for this curve */
+               pd->pd_step = kcalloc(AR5K_EEPROM_N_PWR_POINTS_5111,
+                                       sizeof(u8), GFP_KERNEL);
+               if (!pd->pd_step)
+                       return -ENOMEM;
+
+               pd->pd_pwr = kcalloc(AR5K_EEPROM_N_PWR_POINTS_5111,
+                                       sizeof(s16), GFP_KERNEL);
+               if (!pd->pd_pwr)
+                       return -ENOMEM;
+
+               /* Fill raw dataset
+                * (convert power to 0.25dB units
+                * for RF5112 combatibility) */
+               for (point = 0; point < pd->pd_points; point++) {
+
+                       /* Absolute values */
+                       pd->pd_pwr[point] = 2 * pcinfo->pwr[point];
+
+                       /* Already sorted */
+                       pd->pd_step[point] = pcinfo->pcdac[point];
+               }
+
+               /* Set min/max pwr */
+               chinfo[pier].min_pwr = pd->pd_pwr[0];
+               chinfo[pier].max_pwr = pd->pd_pwr[10];
+
+       }
+
+       return 0;
+}
+
+/* Parse EEPROM data */
+static int
+ath5k_eeprom_read_pcal_info_5111(struct ath5k_hw *ah, int mode)
+{
+       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+       struct ath5k_chan_pcal_info *pcal;
+       int offset, ret;
+       int i;
+       u16 val;
+
+       offset = AR5K_EEPROM_GROUPS_START(ee->ee_version);
+       switch(mode) {
+       case AR5K_EEPROM_MODE_11A:
+               if (!AR5K_EEPROM_HDR_11A(ee->ee_header))
+                       return 0;
+
+               ret = ath5k_eeprom_init_11a_pcal_freq(ah,
+                       offset + AR5K_EEPROM_GROUP1_OFFSET);
+               if (ret < 0)
+                       return ret;
+
+               offset += AR5K_EEPROM_GROUP2_OFFSET;
+               pcal = ee->ee_pwr_cal_a;
+               break;
+       case AR5K_EEPROM_MODE_11B:
+               if (!AR5K_EEPROM_HDR_11B(ee->ee_header) &&
+                   !AR5K_EEPROM_HDR_11G(ee->ee_header))
+                       return 0;
+
+               pcal = ee->ee_pwr_cal_b;
+               offset += AR5K_EEPROM_GROUP3_OFFSET;
+
+               /* fixed piers */
+               pcal[0].freq = 2412;
+               pcal[1].freq = 2447;
+               pcal[2].freq = 2484;
+               ee->ee_n_piers[mode] = 3;
+               break;
+       case AR5K_EEPROM_MODE_11G:
+               if (!AR5K_EEPROM_HDR_11G(ee->ee_header))
+                       return 0;
+
+               pcal = ee->ee_pwr_cal_g;
+               offset += AR5K_EEPROM_GROUP4_OFFSET;
+
+               /* fixed piers */
+               pcal[0].freq = 2312;
+               pcal[1].freq = 2412;
+               pcal[2].freq = 2484;
+               ee->ee_n_piers[mode] = 3;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       for (i = 0; i < ee->ee_n_piers[mode]; i++) {
+               struct ath5k_chan_pcal_info_rf5111 *cdata =
+                       &pcal[i].rf5111_info;
+
+               AR5K_EEPROM_READ(offset++, val);
+               cdata->pcdac_max = ((val >> 10) & AR5K_EEPROM_PCDAC_M);
+               cdata->pcdac_min = ((val >> 4) & AR5K_EEPROM_PCDAC_M);
+               cdata->pwr[0] = ((val << 2) & AR5K_EEPROM_POWER_M);
+
+               AR5K_EEPROM_READ(offset++, val);
+               cdata->pwr[0] |= ((val >> 14) & 0x3);
+               cdata->pwr[1] = ((val >> 8) & AR5K_EEPROM_POWER_M);
+               cdata->pwr[2] = ((val >> 2) & AR5K_EEPROM_POWER_M);
+               cdata->pwr[3] = ((val << 4) & AR5K_EEPROM_POWER_M);
+
+               AR5K_EEPROM_READ(offset++, val);
+               cdata->pwr[3] |= ((val >> 12) & 0xf);
+               cdata->pwr[4] = ((val >> 6) & AR5K_EEPROM_POWER_M);
+               cdata->pwr[5] = (val  & AR5K_EEPROM_POWER_M);
+
+               AR5K_EEPROM_READ(offset++, val);
+               cdata->pwr[6] = ((val >> 10) & AR5K_EEPROM_POWER_M);
+               cdata->pwr[7] = ((val >> 4) & AR5K_EEPROM_POWER_M);
+               cdata->pwr[8] = ((val << 2) & AR5K_EEPROM_POWER_M);
+
+               AR5K_EEPROM_READ(offset++, val);
+               cdata->pwr[8] |= ((val >> 14) & 0x3);
+               cdata->pwr[9] = ((val >> 8) & AR5K_EEPROM_POWER_M);
+               cdata->pwr[10] = ((val >> 2) & AR5K_EEPROM_POWER_M);
+
+               ath5k_get_pcdac_intercepts(ah, cdata->pcdac_min,
+                       cdata->pcdac_max, cdata->pcdac);
+       }
+
+       return ath5k_eeprom_convert_pcal_info_5111(ah, mode, pcal);
+}
+
+
+/*
+ * Read power calibration for RF5112 chips
+ *
+ * For RF5112 we have 4 XPD -eXternal Power Detector- curves
+ * for each calibrated channel on 0, -6, -12 and -18dbm but we only
+ * use the higher (3) and the lower (0) curves. Each curve has 0.5dB
+ * power steps on x axis and PCDAC steps on y axis and looks like a
+ * linear function. To recreate the curve and pass the power values
+ * on hw, we read 4 points for xpd 0 (lower gain -> max power)
+ * and 3 points for xpd 3 (higher gain -> lower power) here and
+ * interpolate later.
+ *
+ * Note: Many vendors just use xpd 0 so xpd 3 is zeroed.
+ */
+
+/* Convert RF5112 specific data to generic raw data
+ * used by interpolation code */
+static int
+ath5k_eeprom_convert_pcal_info_5112(struct ath5k_hw *ah, int mode,
+                               struct ath5k_chan_pcal_info *chinfo)
+{
+       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+       struct ath5k_chan_pcal_info_rf5112 *pcinfo;
+       u8 *pdgain_idx = ee->ee_pdc_to_idx[mode];
+       unsigned int pier, pdg, point;
+
+       /* Fill raw data for each calibration pier */
+       for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) {
+
+               pcinfo = &chinfo[pier].rf5112_info;
+
+               /* Allocate pd_curves for this cal pier */
+               chinfo[pier].pd_curves =
+                               kcalloc(AR5K_EEPROM_N_PD_CURVES,
+                                       sizeof(struct ath5k_pdgain_info),
+                                       GFP_KERNEL);
+
+               if (!chinfo[pier].pd_curves)
+                       return -ENOMEM;
+
+               /* Fill pd_curves */
+               for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) {
+
+                       u8 idx = pdgain_idx[pdg];
+                       struct ath5k_pdgain_info *pd =
+                                       &chinfo[pier].pd_curves[idx];
+
+                       /* Lowest gain curve (max power) */
+                       if (pdg == 0) {
+                               /* One more point for better accuracy */
+                               pd->pd_points = AR5K_EEPROM_N_XPD0_POINTS;
+
+                               /* Allocate pd points for this curve */
+                               pd->pd_step = kcalloc(pd->pd_points,
+                                               sizeof(u8), GFP_KERNEL);
+
+                               if (!pd->pd_step)
+                                       return -ENOMEM;
+
+                               pd->pd_pwr = kcalloc(pd->pd_points,
+                                               sizeof(s16), GFP_KERNEL);
+
+                               if (!pd->pd_pwr)
+                                       return -ENOMEM;
+
+
+                               /* Fill raw dataset
+                                * (all power levels are in 0.25dB units) */
+                               pd->pd_step[0] = pcinfo->pcdac_x0[0];
+                               pd->pd_pwr[0] = pcinfo->pwr_x0[0];
+
+                               for (point = 1; point < pd->pd_points;
+                               point++) {
+                                       /* Absolute values */
+                                       pd->pd_pwr[point] =
+                                               pcinfo->pwr_x0[point];
+
+                                       /* Deltas */
+                                       pd->pd_step[point] =
+                                               pd->pd_step[point - 1] +
+                                               pcinfo->pcdac_x0[point];
+                               }
+
+                               /* Set min power for this frequency */
+                               chinfo[pier].min_pwr = pd->pd_pwr[0];
+
+                       /* Highest gain curve (min power) */
+                       } else if (pdg == 1) {
+
+                               pd->pd_points = AR5K_EEPROM_N_XPD3_POINTS;
+
+                               /* Allocate pd points for this curve */
+                               pd->pd_step = kcalloc(pd->pd_points,
+                                               sizeof(u8), GFP_KERNEL);
+
+                               if (!pd->pd_step)
+                                       return -ENOMEM;
+
+                               pd->pd_pwr = kcalloc(pd->pd_points,
+                                               sizeof(s16), GFP_KERNEL);
+
+                               if (!pd->pd_pwr)
+                                       return -ENOMEM;
+
+                               /* Fill raw dataset
+                                * (all power levels are in 0.25dB units) */
+                               for (point = 0; point < pd->pd_points;
+                               point++) {
+                                       /* Absolute values */
+                                       pd->pd_pwr[point] =
+                                               pcinfo->pwr_x3[point];
+
+                                       /* Fixed points */
+                                       pd->pd_step[point] =
+                                               pcinfo->pcdac_x3[point];
+                               }
+
+                               /* Since we have a higher gain curve
+                                * override min power */
+                               chinfo[pier].min_pwr = pd->pd_pwr[0];
+                       }
+               }
+       }
+
+       return 0;
+}
+
+/* Parse EEPROM data */
+static int
+ath5k_eeprom_read_pcal_info_5112(struct ath5k_hw *ah, int mode)
+{
+       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+       struct ath5k_chan_pcal_info_rf5112 *chan_pcal_info;
+       struct ath5k_chan_pcal_info *gen_chan_info;
+       u8 *pdgain_idx = ee->ee_pdc_to_idx[mode];
+       u32 offset;
+       u8 i, c;
+       u16 val;
+       int ret;
+       u8 pd_gains = 0;
+
+       /* Count how many curves we have and
+        * identify them (which one of the 4
+        * available curves we have on each count).
+        * Curves are stored from lower (x0) to
+        * higher (x3) gain */
+       for (i = 0; i < AR5K_EEPROM_N_PD_CURVES; i++) {
+               /* ee_x_gain[mode] is x gain mask */
+               if ((ee->ee_x_gain[mode] >> i) & 0x1)
+                       pdgain_idx[pd_gains++] = i;
+       }
+       ee->ee_pd_gains[mode] = pd_gains;
+
+       if (pd_gains == 0 || pd_gains > 2)
+               return -EINVAL;
+
+       switch (mode) {
+       case AR5K_EEPROM_MODE_11A:
+               /*
+                * Read 5GHz EEPROM channels
+                */
+               offset = AR5K_EEPROM_GROUPS_START(ee->ee_version);
+               ath5k_eeprom_init_11a_pcal_freq(ah, offset);
+
+               offset += AR5K_EEPROM_GROUP2_OFFSET;
+               gen_chan_info = ee->ee_pwr_cal_a;
+               break;
+       case AR5K_EEPROM_MODE_11B:
+               offset = AR5K_EEPROM_GROUPS_START(ee->ee_version);
+               if (AR5K_EEPROM_HDR_11A(ee->ee_header))
+                       offset += AR5K_EEPROM_GROUP3_OFFSET;
+
+               /* NB: frequency piers parsed during mode init */
+               gen_chan_info = ee->ee_pwr_cal_b;
+               break;
+       case AR5K_EEPROM_MODE_11G:
+               offset = AR5K_EEPROM_GROUPS_START(ee->ee_version);
+               if (AR5K_EEPROM_HDR_11A(ee->ee_header))
+                       offset += AR5K_EEPROM_GROUP4_OFFSET;
+               else if (AR5K_EEPROM_HDR_11B(ee->ee_header))
+                       offset += AR5K_EEPROM_GROUP2_OFFSET;
+
+               /* NB: frequency piers parsed during mode init */
+               gen_chan_info = ee->ee_pwr_cal_g;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       for (i = 0; i < ee->ee_n_piers[mode]; i++) {
+               chan_pcal_info = &gen_chan_info[i].rf5112_info;
+
+               /* Power values in quarter dB
+                * for the lower xpd gain curve
+                * (0 dBm -> higher output power) */
+               for (c = 0; c < AR5K_EEPROM_N_XPD0_POINTS; c++) {
+                       AR5K_EEPROM_READ(offset++, val);
+                       chan_pcal_info->pwr_x0[c] = (s8) (val & 0xff);
+                       chan_pcal_info->pwr_x0[++c] = (s8) ((val >> 8) & 0xff);
+               }
+
+               /* PCDAC steps
+                * corresponding to the above power
+                * measurements */
+               AR5K_EEPROM_READ(offset++, val);
+               chan_pcal_info->pcdac_x0[1] = (val & 0x1f);
+               chan_pcal_info->pcdac_x0[2] = ((val >> 5) & 0x1f);
+               chan_pcal_info->pcdac_x0[3] = ((val >> 10) & 0x1f);
+
+               /* Power values in quarter dB
+                * for the higher xpd gain curve
+                * (18 dBm -> lower output power) */
+               AR5K_EEPROM_READ(offset++, val);
+               chan_pcal_info->pwr_x3[0] = (s8) (val & 0xff);
+               chan_pcal_info->pwr_x3[1] = (s8) ((val >> 8) & 0xff);
+
+               AR5K_EEPROM_READ(offset++, val);
+               chan_pcal_info->pwr_x3[2] = (val & 0xff);
+
+               /* PCDAC steps
+                * corresponding to the above power
+                * measurements (fixed) */
+               chan_pcal_info->pcdac_x3[0] = 20;
+               chan_pcal_info->pcdac_x3[1] = 35;
+               chan_pcal_info->pcdac_x3[2] = 63;
+
+               if (ee->ee_version >= AR5K_EEPROM_VERSION_4_3) {
+                       chan_pcal_info->pcdac_x0[0] = ((val >> 8) & 0x3f);
+
+                       /* Last xpd0 power level is also channel maximum */
+                       gen_chan_info[i].max_pwr = chan_pcal_info->pwr_x0[3];
+               } else {
+                       chan_pcal_info->pcdac_x0[0] = 1;
+                       gen_chan_info[i].max_pwr = (s8) ((val >> 8) & 0xff);
+               }
+
+       }
+
+       return ath5k_eeprom_convert_pcal_info_5112(ah, mode, gen_chan_info);
+}
+
+
+/*
+ * Read power calibration for RF2413 chips
+ *
+ * For RF2413 we have a Power to PDDAC table (Power Detector)
+ * instead of a PCDAC and 4 pd gain curves for each calibrated channel.
+ * Each curve has power on x axis in 0.5 db steps and PDDADC steps on y
+ * axis and looks like an exponential function like the RF5111 curve.
+ *
+ * To recreate the curves we read here the points and interpolate
+ * later. Note that in most cases only 2 (higher and lower) curves are
+ * used (like RF5112) but vendors have the oportunity to include all
+ * 4 curves on eeprom. The final curve (higher power) has an extra
+ * point for better accuracy like RF5112.
+ */
+
+/* For RF2413 power calibration data doesn't start on a fixed location and
+ * if a mode is not supported, it's section is missing -not zeroed-.
+ * So we need to calculate the starting offset for each section by using
+ * these two functions */
+
+/* Return the size of each section based on the mode and the number of pd
+ * gains available (maximum 4). */
+static inline unsigned int
+ath5k_pdgains_size_2413(struct ath5k_eeprom_info *ee, unsigned int mode)
+{
+       static const unsigned int pdgains_size[] = { 4, 6, 9, 12 };
+       unsigned int sz;
+
+       sz = pdgains_size[ee->ee_pd_gains[mode] - 1];
+       sz *= ee->ee_n_piers[mode];
+
+       return sz;
+}
+
+/* Return the starting offset for a section based on the modes supported
+ * and each section's size. */
+static unsigned int
+ath5k_cal_data_offset_2413(struct ath5k_eeprom_info *ee, int mode)
+{
+       u32 offset = AR5K_EEPROM_CAL_DATA_START(ee->ee_misc4);
+
+       switch(mode) {
+       case AR5K_EEPROM_MODE_11G:
+               if (AR5K_EEPROM_HDR_11B(ee->ee_header))
+                       offset += ath5k_pdgains_size_2413(ee,
+                                       AR5K_EEPROM_MODE_11B) +
+                                       AR5K_EEPROM_N_2GHZ_CHAN_2413 / 2;
+               /* fall through */
+       case AR5K_EEPROM_MODE_11B:
+               if (AR5K_EEPROM_HDR_11A(ee->ee_header))
+                       offset += ath5k_pdgains_size_2413(ee,
+                                       AR5K_EEPROM_MODE_11A) +
+                                       AR5K_EEPROM_N_5GHZ_CHAN / 2;
+               /* fall through */
+       case AR5K_EEPROM_MODE_11A:
+               break;
+       default:
+               break;
+       }
+
+       return offset;
+}
+
+/* Convert RF2413 specific data to generic raw data
+ * used by interpolation code */
+static int
+ath5k_eeprom_convert_pcal_info_2413(struct ath5k_hw *ah, int mode,
+                               struct ath5k_chan_pcal_info *chinfo)
+{
+       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+       struct ath5k_chan_pcal_info_rf2413 *pcinfo;
+       u8 *pdgain_idx = ee->ee_pdc_to_idx[mode];
+       unsigned int pier, pdg, point;
+
+       /* Fill raw data for each calibration pier */
+       for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) {
+
+               pcinfo = &chinfo[pier].rf2413_info;
+
+               /* Allocate pd_curves for this cal pier */
+               chinfo[pier].pd_curves =
+                               kcalloc(AR5K_EEPROM_N_PD_CURVES,
+                                       sizeof(struct ath5k_pdgain_info),
+                                       GFP_KERNEL);
+
+               if (!chinfo[pier].pd_curves)
+                       return -ENOMEM;
+
+               /* Fill pd_curves */
+               for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) {
+
+                       u8 idx = pdgain_idx[pdg];
+                       struct ath5k_pdgain_info *pd =
+                                       &chinfo[pier].pd_curves[idx];
+
+                       /* One more point for the highest power
+                        * curve (lowest gain) */
+                       if (pdg == ee->ee_pd_gains[mode] - 1)
+                               pd->pd_points = AR5K_EEPROM_N_PD_POINTS;
+                       else
+                               pd->pd_points = AR5K_EEPROM_N_PD_POINTS - 1;
+
+                       /* Allocate pd points for this curve */
+                       pd->pd_step = kcalloc(pd->pd_points,
+                                       sizeof(u8), GFP_KERNEL);
+
+                       if (!pd->pd_step)
+                               return -ENOMEM;
+
+                       pd->pd_pwr = kcalloc(pd->pd_points,
+                                       sizeof(s16), GFP_KERNEL);
+
+                       if (!pd->pd_pwr)
+                               return -ENOMEM;
+
+                       /* Fill raw dataset
+                        * convert all pwr levels to
+                        * quarter dB for RF5112 combatibility */
+                       pd->pd_step[0] = pcinfo->pddac_i[pdg];
+                       pd->pd_pwr[0] = 4 * pcinfo->pwr_i[pdg];
+
+                       for (point = 1; point < pd->pd_points; point++) {
+
+                               pd->pd_pwr[point] = pd->pd_pwr[point - 1] +
+                                       2 * pcinfo->pwr[pdg][point - 1];
+
+                               pd->pd_step[point] = pd->pd_step[point - 1] +
+                                               pcinfo->pddac[pdg][point - 1];
+
+                       }
+
+                       /* Highest gain curve -> min power */
+                       if (pdg == 0)
+                               chinfo[pier].min_pwr = pd->pd_pwr[0];
+
+                       /* Lowest gain curve -> max power */
+                       if (pdg == ee->ee_pd_gains[mode] - 1)
+                               chinfo[pier].max_pwr =
+                                       pd->pd_pwr[pd->pd_points - 1];
+               }
+       }
+
+       return 0;
+}
+
+/* Parse EEPROM data */
+static int
+ath5k_eeprom_read_pcal_info_2413(struct ath5k_hw *ah, int mode)
+{
+       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+       struct ath5k_chan_pcal_info_rf2413 *pcinfo;
+       struct ath5k_chan_pcal_info *chinfo;
+       u8 *pdgain_idx = ee->ee_pdc_to_idx[mode];
+       u32 offset;
+       int idx, i, ret;
+       u16 val;
+       u8 pd_gains = 0;
+
+       /* Count how many curves we have and
+        * identify them (which one of the 4
+        * available curves we have on each count).
+        * Curves are stored from higher to
+        * lower gain so we go backwards */
+       for (idx = AR5K_EEPROM_N_PD_CURVES - 1; idx >= 0; idx--) {
+               /* ee_x_gain[mode] is x gain mask */
+               if ((ee->ee_x_gain[mode] >> idx) & 0x1)
+                       pdgain_idx[pd_gains++] = idx;
+
+       }
+       ee->ee_pd_gains[mode] = pd_gains;
+
+       if (pd_gains == 0)
+               return -EINVAL;
+
+       offset = ath5k_cal_data_offset_2413(ee, mode);
+       switch (mode) {
+       case AR5K_EEPROM_MODE_11A:
+               if (!AR5K_EEPROM_HDR_11A(ee->ee_header))
+                       return 0;
+
+               ath5k_eeprom_init_11a_pcal_freq(ah, offset);
+               offset += AR5K_EEPROM_N_5GHZ_CHAN / 2;
+               chinfo = ee->ee_pwr_cal_a;
+               break;
+       case AR5K_EEPROM_MODE_11B:
+               if (!AR5K_EEPROM_HDR_11B(ee->ee_header))
+                       return 0;
+
+               ath5k_eeprom_init_11bg_2413(ah, mode, offset);
+               offset += AR5K_EEPROM_N_2GHZ_CHAN_2413 / 2;
+               chinfo = ee->ee_pwr_cal_b;
+               break;
+       case AR5K_EEPROM_MODE_11G:
+               if (!AR5K_EEPROM_HDR_11G(ee->ee_header))
+                       return 0;
+
+               ath5k_eeprom_init_11bg_2413(ah, mode, offset);
+               offset += AR5K_EEPROM_N_2GHZ_CHAN_2413 / 2;
+               chinfo = ee->ee_pwr_cal_g;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       for (i = 0; i < ee->ee_n_piers[mode]; i++) {
+               pcinfo = &chinfo[i].rf2413_info;
+
+               /*
+                * Read pwr_i, pddac_i and the first
+                * 2 pd points (pwr, pddac)
+                */
+               AR5K_EEPROM_READ(offset++, val);
+               pcinfo->pwr_i[0] = val & 0x1f;
+               pcinfo->pddac_i[0] = (val >> 5) & 0x7f;
+               pcinfo->pwr[0][0] = (val >> 12) & 0xf;
+
+               AR5K_EEPROM_READ(offset++, val);
+               pcinfo->pddac[0][0] = val & 0x3f;
+               pcinfo->pwr[0][1] = (val >> 6) & 0xf;
+               pcinfo->pddac[0][1] = (val >> 10) & 0x3f;
+
+               AR5K_EEPROM_READ(offset++, val);
+               pcinfo->pwr[0][2] = val & 0xf;
+               pcinfo->pddac[0][2] = (val >> 4) & 0x3f;
+
+               pcinfo->pwr[0][3] = 0;
+               pcinfo->pddac[0][3] = 0;
+
+               if (pd_gains > 1) {
+                       /*
+                        * Pd gain 0 is not the last pd gain
+                        * so it only has 2 pd points.
+                        * Continue wih pd gain 1.
+                        */
+                       pcinfo->pwr_i[1] = (val >> 10) & 0x1f;
+
+                       pcinfo->pddac_i[1] = (val >> 15) & 0x1;
+                       AR5K_EEPROM_READ(offset++, val);
+                       pcinfo->pddac_i[1] |= (val & 0x3F) << 1;
+
+                       pcinfo->pwr[1][0] = (val >> 6) & 0xf;
+                       pcinfo->pddac[1][0] = (val >> 10) & 0x3f;
+
+                       AR5K_EEPROM_READ(offset++, val);
+                       pcinfo->pwr[1][1] = val & 0xf;
+                       pcinfo->pddac[1][1] = (val >> 4) & 0x3f;
+                       pcinfo->pwr[1][2] = (val >> 10) & 0xf;
+
+                       pcinfo->pddac[1][2] = (val >> 14) & 0x3;
+                       AR5K_EEPROM_READ(offset++, val);
+                       pcinfo->pddac[1][2] |= (val & 0xF) << 2;
+
+                       pcinfo->pwr[1][3] = 0;
+                       pcinfo->pddac[1][3] = 0;
+               } else if (pd_gains == 1) {
+                       /*
+                        * Pd gain 0 is the last one so
+                        * read the extra point.
+                        */
+                       pcinfo->pwr[0][3] = (val >> 10) & 0xf;
+
+                       pcinfo->pddac[0][3] = (val >> 14) & 0x3;
+                       AR5K_EEPROM_READ(offset++, val);
+                       pcinfo->pddac[0][3] |= (val & 0xF) << 2;
+               }
+
+               /*
+                * Proceed with the other pd_gains
+                * as above.
+                */
+               if (pd_gains > 2) {
+                       pcinfo->pwr_i[2] = (val >> 4) & 0x1f;
+                       pcinfo->pddac_i[2] = (val >> 9) & 0x7f;
+
+                       AR5K_EEPROM_READ(offset++, val);
+                       pcinfo->pwr[2][0] = (val >> 0) & 0xf;
+                       pcinfo->pddac[2][0] = (val >> 4) & 0x3f;
+                       pcinfo->pwr[2][1] = (val >> 10) & 0xf;
+
+                       pcinfo->pddac[2][1] = (val >> 14) & 0x3;
+                       AR5K_EEPROM_READ(offset++, val);
+                       pcinfo->pddac[2][1] |= (val & 0xF) << 2;
+
+                       pcinfo->pwr[2][2] = (val >> 4) & 0xf;
+                       pcinfo->pddac[2][2] = (val >> 8) & 0x3f;
+
+                       pcinfo->pwr[2][3] = 0;
+                       pcinfo->pddac[2][3] = 0;
+               } else if (pd_gains == 2) {
+                       pcinfo->pwr[1][3] = (val >> 4) & 0xf;
+                       pcinfo->pddac[1][3] = (val >> 8) & 0x3f;
+               }
+
+               if (pd_gains > 3) {
+                       pcinfo->pwr_i[3] = (val >> 14) & 0x3;
+                       AR5K_EEPROM_READ(offset++, val);
+                       pcinfo->pwr_i[3] |= ((val >> 0) & 0x7) << 2;
+
+                       pcinfo->pddac_i[3] = (val >> 3) & 0x7f;
+                       pcinfo->pwr[3][0] = (val >> 10) & 0xf;
+                       pcinfo->pddac[3][0] = (val >> 14) & 0x3;
+
+                       AR5K_EEPROM_READ(offset++, val);
+                       pcinfo->pddac[3][0] |= (val & 0xF) << 2;
+                       pcinfo->pwr[3][1] = (val >> 4) & 0xf;
+                       pcinfo->pddac[3][1] = (val >> 8) & 0x3f;
+
+                       pcinfo->pwr[3][2] = (val >> 14) & 0x3;
+                       AR5K_EEPROM_READ(offset++, val);
+                       pcinfo->pwr[3][2] |= ((val >> 0) & 0x3) << 2;
+
+                       pcinfo->pddac[3][2] = (val >> 2) & 0x3f;
+                       pcinfo->pwr[3][3] = (val >> 8) & 0xf;
+
+                       pcinfo->pddac[3][3] = (val >> 12) & 0xF;
+                       AR5K_EEPROM_READ(offset++, val);
+                       pcinfo->pddac[3][3] |= ((val >> 0) & 0x3) << 4;
+               } else if (pd_gains == 3) {
+                       pcinfo->pwr[2][3] = (val >> 14) & 0x3;
+                       AR5K_EEPROM_READ(offset++, val);
+                       pcinfo->pwr[2][3] |= ((val >> 0) & 0x3) << 2;
+
+                       pcinfo->pddac[2][3] = (val >> 2) & 0x3f;
+               }
+       }
+
+       return ath5k_eeprom_convert_pcal_info_2413(ah, mode, chinfo);
+}
+
+
+/*
+ * Read per rate target power (this is the maximum tx power
+ * supported by the card). This info is used when setting
+ * tx power, no matter the channel.
+ *
+ * This also works for v5 EEPROMs.
+ */
+static int
+ath5k_eeprom_read_target_rate_pwr_info(struct ath5k_hw *ah, unsigned int mode)
+{
+       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+       struct ath5k_rate_pcal_info *rate_pcal_info;
+       u8 *rate_target_pwr_num;
+       u32 offset;
+       u16 val;
+       int ret, i;
+
+       offset = AR5K_EEPROM_TARGET_PWRSTART(ee->ee_misc1);
+       rate_target_pwr_num = &ee->ee_rate_target_pwr_num[mode];
+       switch (mode) {
+       case AR5K_EEPROM_MODE_11A:
+               offset += AR5K_EEPROM_TARGET_PWR_OFF_11A(ee->ee_version);
+               rate_pcal_info = ee->ee_rate_tpwr_a;
+               ee->ee_rate_target_pwr_num[mode] = AR5K_EEPROM_N_5GHZ_CHAN;
+               break;
+       case AR5K_EEPROM_MODE_11B:
+               offset += AR5K_EEPROM_TARGET_PWR_OFF_11B(ee->ee_version);
+               rate_pcal_info = ee->ee_rate_tpwr_b;
+               ee->ee_rate_target_pwr_num[mode] = 2; /* 3rd is g mode's 1st */
+               break;
+       case AR5K_EEPROM_MODE_11G:
+               offset += AR5K_EEPROM_TARGET_PWR_OFF_11G(ee->ee_version);
+               rate_pcal_info = ee->ee_rate_tpwr_g;
+               ee->ee_rate_target_pwr_num[mode] = AR5K_EEPROM_N_2GHZ_CHAN;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       /* Different freq mask for older eeproms (<= v3.2) */
+       if (ee->ee_version <= AR5K_EEPROM_VERSION_3_2) {
+               for (i = 0; i < (*rate_target_pwr_num); i++) {
+                       AR5K_EEPROM_READ(offset++, val);
+                       rate_pcal_info[i].freq =
+                           ath5k_eeprom_bin2freq(ee, (val >> 9) & 0x7f, mode);
+
+                       rate_pcal_info[i].target_power_6to24 = ((val >> 3) & 0x3f);
+                       rate_pcal_info[i].target_power_36 = (val << 3) & 0x3f;
+
+                       AR5K_EEPROM_READ(offset++, val);
+
+                       if (rate_pcal_info[i].freq == AR5K_EEPROM_CHANNEL_DIS ||
+                           val == 0) {
+                               (*rate_target_pwr_num) = i;
+                               break;
+                       }
+
+                       rate_pcal_info[i].target_power_36 |= ((val >> 13) & 0x7);
+                       rate_pcal_info[i].target_power_48 = ((val >> 7) & 0x3f);
+                       rate_pcal_info[i].target_power_54 = ((val >> 1) & 0x3f);
+               }
+       } else {
+               for (i = 0; i < (*rate_target_pwr_num); i++) {
+                       AR5K_EEPROM_READ(offset++, val);
+                       rate_pcal_info[i].freq =
+                           ath5k_eeprom_bin2freq(ee, (val >> 8) & 0xff, mode);
+
+                       rate_pcal_info[i].target_power_6to24 = ((val >> 2) & 0x3f);
+                       rate_pcal_info[i].target_power_36 = (val << 4) & 0x3f;
+
+                       AR5K_EEPROM_READ(offset++, val);
+
+                       if (rate_pcal_info[i].freq == AR5K_EEPROM_CHANNEL_DIS ||
+                           val == 0) {
+                               (*rate_target_pwr_num) = i;
+                               break;
+                       }
+
+                       rate_pcal_info[i].target_power_36 |= (val >> 12) & 0xf;
+                       rate_pcal_info[i].target_power_48 = ((val >> 6) & 0x3f);
+                       rate_pcal_info[i].target_power_54 = (val & 0x3f);
+               }
+       }
+
+       return 0;
+}
+
+/*
+ * Read per channel calibration info from EEPROM
+ *
+ * This info is used to calibrate the baseband power table. Imagine
+ * that for each channel there is a power curve that's hw specific
+ * (depends on amplifier etc) and we try to "correct" this curve using
+ * offests we pass on to phy chip (baseband -> before amplifier) so that
+ * it can use accurate power values when setting tx power (takes amplifier's
+ * performance on each channel into account).
+ *
+ * EEPROM provides us with the offsets for some pre-calibrated channels
+ * and we have to interpolate to create the full table for these channels and
+ * also the table for any channel.
+ */
+static int
+ath5k_eeprom_read_pcal_info(struct ath5k_hw *ah)
+{
+       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+       int (*read_pcal)(struct ath5k_hw *hw, int mode);
+       int mode;
+       int err;
+
+       if ((ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) &&
+                       (AR5K_EEPROM_EEMAP(ee->ee_misc0) == 1))
+               read_pcal = ath5k_eeprom_read_pcal_info_5112;
+       else if ((ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_0) &&
+                       (AR5K_EEPROM_EEMAP(ee->ee_misc0) == 2))
+               read_pcal = ath5k_eeprom_read_pcal_info_2413;
+       else
+               read_pcal = ath5k_eeprom_read_pcal_info_5111;
+
+
+       for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G;
+       mode++) {
+               err = read_pcal(ah, mode);
+               if (err)
+                       return err;
+
+               err = ath5k_eeprom_read_target_rate_pwr_info(ah, mode);
+               if (err < 0)
+                       return err;
+       }
+
+       return 0;
+}
+
+static int
+ath5k_eeprom_free_pcal_info(struct ath5k_hw *ah, int mode)
+{
+       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+       struct ath5k_chan_pcal_info *chinfo;
+       u8 pier, pdg;
+
+       switch (mode) {
+       case AR5K_EEPROM_MODE_11A:
+               if (!AR5K_EEPROM_HDR_11A(ee->ee_header))
+                       return 0;
+               chinfo = ee->ee_pwr_cal_a;
+               break;
+       case AR5K_EEPROM_MODE_11B:
+               if (!AR5K_EEPROM_HDR_11B(ee->ee_header))
+                       return 0;
+               chinfo = ee->ee_pwr_cal_b;
+               break;
+       case AR5K_EEPROM_MODE_11G:
+               if (!AR5K_EEPROM_HDR_11G(ee->ee_header))
+                       return 0;
+               chinfo = ee->ee_pwr_cal_g;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) {
+               if (!chinfo[pier].pd_curves)
+                       continue;
+
+               for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) {
+                       struct ath5k_pdgain_info *pd =
+                                       &chinfo[pier].pd_curves[pdg];
+
+                       if (pd != NULL) {
+                               kfree(pd->pd_step);
+                               kfree(pd->pd_pwr);
+                       }
+               }
+
+               kfree(chinfo[pier].pd_curves);
+       }
+
+       return 0;
+}
+
+void
+ath5k_eeprom_detach(struct ath5k_hw *ah)
+{
+       u8 mode;
+
+       for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G; mode++)
+               ath5k_eeprom_free_pcal_info(ah, mode);
+}
+
+/* Read conformance test limits used for regulatory control */
+static int
+ath5k_eeprom_read_ctl_info(struct ath5k_hw *ah)
+{
+       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+       struct ath5k_edge_power *rep;
+       unsigned int fmask, pmask;
+       unsigned int ctl_mode;
+       int ret, i, j;
+       u32 offset;
+       u16 val;
+
+       pmask = AR5K_EEPROM_POWER_M;
+       fmask = AR5K_EEPROM_FREQ_M(ee->ee_version);
+       offset = AR5K_EEPROM_CTL(ee->ee_version);
+       ee->ee_ctls = AR5K_EEPROM_N_CTLS(ee->ee_version);
+       for (i = 0; i < ee->ee_ctls; i += 2) {
+               AR5K_EEPROM_READ(offset++, val);
+               ee->ee_ctl[i] = (val >> 8) & 0xff;
+               ee->ee_ctl[i + 1] = val & 0xff;
+       }
+
+       offset = AR5K_EEPROM_GROUP8_OFFSET;
+       if (ee->ee_version >= AR5K_EEPROM_VERSION_4_0)
+               offset += AR5K_EEPROM_TARGET_PWRSTART(ee->ee_misc1) -
+                       AR5K_EEPROM_GROUP5_OFFSET;
+       else
+               offset += AR5K_EEPROM_GROUPS_START(ee->ee_version);
+
+       rep = ee->ee_ctl_pwr;
+       for(i = 0; i < ee->ee_ctls; i++) {
+               switch(ee->ee_ctl[i] & AR5K_CTL_MODE_M) {
+               case AR5K_CTL_11A:
+               case AR5K_CTL_TURBO:
+                       ctl_mode = AR5K_EEPROM_MODE_11A;
+                       break;
+               default:
+                       ctl_mode = AR5K_EEPROM_MODE_11G;
+                       break;
+               }
+               if (ee->ee_ctl[i] == 0) {
+                       if (ee->ee_version >= AR5K_EEPROM_VERSION_3_3)
+                               offset += 8;
+                       else
+                               offset += 7;
+                       rep += AR5K_EEPROM_N_EDGES;
+                       continue;
+               }
+               if (ee->ee_version >= AR5K_EEPROM_VERSION_3_3) {
+                       for (j = 0; j < AR5K_EEPROM_N_EDGES; j += 2) {
+                               AR5K_EEPROM_READ(offset++, val);
+                               rep[j].freq = (val >> 8) & fmask;
+                               rep[j + 1].freq = val & fmask;
+                       }
+                       for (j = 0; j < AR5K_EEPROM_N_EDGES; j += 2) {
+                               AR5K_EEPROM_READ(offset++, val);
+                               rep[j].edge = (val >> 8) & pmask;
+                               rep[j].flag = (val >> 14) & 1;
+                               rep[j + 1].edge = val & pmask;
+                               rep[j + 1].flag = (val >> 6) & 1;
+                       }
+               } else {
+                       AR5K_EEPROM_READ(offset++, val);
+                       rep[0].freq = (val >> 9) & fmask;
+                       rep[1].freq = (val >> 2) & fmask;
+                       rep[2].freq = (val << 5) & fmask;
+
+                       AR5K_EEPROM_READ(offset++, val);
+                       rep[2].freq |= (val >> 11) & 0x1f;
+                       rep[3].freq = (val >> 4) & fmask;
+                       rep[4].freq = (val << 3) & fmask;
+
+                       AR5K_EEPROM_READ(offset++, val);
+                       rep[4].freq |= (val >> 13) & 0x7;
+                       rep[5].freq = (val >> 6) & fmask;
+                       rep[6].freq = (val << 1) & fmask;
+
+                       AR5K_EEPROM_READ(offset++, val);
+                       rep[6].freq |= (val >> 15) & 0x1;
+                       rep[7].freq = (val >> 8) & fmask;
+
+                       rep[0].edge = (val >> 2) & pmask;
+                       rep[1].edge = (val << 4) & pmask;
+
+                       AR5K_EEPROM_READ(offset++, val);
+                       rep[1].edge |= (val >> 12) & 0xf;
+                       rep[2].edge = (val >> 6) & pmask;
+                       rep[3].edge = val & pmask;
+
+                       AR5K_EEPROM_READ(offset++, val);
+                       rep[4].edge = (val >> 10) & pmask;
+                       rep[5].edge = (val >> 4) & pmask;
+                       rep[6].edge = (val << 2) & pmask;
+
+                       AR5K_EEPROM_READ(offset++, val);
+                       rep[6].edge |= (val >> 14) & 0x3;
+                       rep[7].edge = (val >> 8) & pmask;
+               }
+               for (j = 0; j < AR5K_EEPROM_N_EDGES; j++) {
+                       rep[j].freq = ath5k_eeprom_bin2freq(ee,
+                               rep[j].freq, ctl_mode);
+               }
+               rep += AR5K_EEPROM_N_EDGES;
+       }
+
+       return 0;
+}
+
+static int
+ath5k_eeprom_read_spur_chans(struct ath5k_hw *ah)
+{
+       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+       u32 offset;
+       u16 val;
+       int ret = 0, i;
+
+       offset = AR5K_EEPROM_CTL(ee->ee_version) +
+                               AR5K_EEPROM_N_CTLS(ee->ee_version);
+
+       if (ee->ee_version < AR5K_EEPROM_VERSION_5_3) {
+               /* No spur info for 5GHz */
+               ee->ee_spur_chans[0][0] = AR5K_EEPROM_NO_SPUR;
+               /* 2 channels for 2GHz (2464/2420) */
+               ee->ee_spur_chans[0][1] = AR5K_EEPROM_5413_SPUR_CHAN_1;
+               ee->ee_spur_chans[1][1] = AR5K_EEPROM_5413_SPUR_CHAN_2;
+               ee->ee_spur_chans[2][1] = AR5K_EEPROM_NO_SPUR;
+       } else if (ee->ee_version >= AR5K_EEPROM_VERSION_5_3) {
+               for (i = 0; i < AR5K_EEPROM_N_SPUR_CHANS; i++) {
+                       AR5K_EEPROM_READ(offset, val);
+                       ee->ee_spur_chans[i][0] = val;
+                       AR5K_EEPROM_READ(offset + AR5K_EEPROM_N_SPUR_CHANS,
+                                                                       val);
+                       ee->ee_spur_chans[i][1] = val;
+                       offset++;
+               }
+       }
+
+       return ret;
+}
+
+/*
+ * Initialize eeprom data structure
+ */
+int
+ath5k_eeprom_init(struct ath5k_hw *ah)
+{
+       int err;
+
+       err = ath5k_eeprom_init_header(ah);
+       if (err < 0)
+               return err;
+
+       err = ath5k_eeprom_init_modes(ah);
+       if (err < 0)
+               return err;
+
+       err = ath5k_eeprom_read_pcal_info(ah);
+       if (err < 0)
+               return err;
+
+       err = ath5k_eeprom_read_ctl_info(ah);
+       if (err < 0)
+               return err;
+
+       err = ath5k_eeprom_read_spur_chans(ah);
+       if (err < 0)
+               return err;
+
+       return 0;
+}
+
+/*
+ * Read the MAC address from eeprom
+ */
+int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac)
+{
+       u8 mac_d[ETH_ALEN] = {};
+       u32 total, offset;
+       u16 data;
+       int octet, ret;
+
+       ret = ath5k_hw_eeprom_read(ah, 0x20, &data);
+       if (ret)
+               return ret;
+
+       for (offset = 0x1f, octet = 0, total = 0; offset >= 0x1d; offset--) {
+               ret = ath5k_hw_eeprom_read(ah, offset, &data);
+               if (ret)
+                       return ret;
+
+               total += data;
+               mac_d[octet + 1] = data & 0xff;
+               mac_d[octet] = data >> 8;
+               octet += 2;
+       }
+
+       if (!total || total == 3 * 0xffff)
+               return -EINVAL;
+
+       memcpy(mac, mac_d, ETH_ALEN);
+
+       return 0;
+}
diff --git a/drivers/net/wireless/ath/ath5k/eeprom.h b/drivers/net/wireless/ath/ath5k/eeprom.h
new file mode 100644 (file)
index 0000000..64be73a
--- /dev/null
@@ -0,0 +1,467 @@
+/*
+ * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
+ * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
+ *
+ * Permission to use, copy, modify, and 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 ar5xxx EEPROM data offsets (set these on AR5K_EEPROM_BASE)
+ */
+#define AR5K_EEPROM_MAGIC              0x003d  /* EEPROM Magic number */
+#define AR5K_EEPROM_MAGIC_VALUE                0x5aa5  /* Default - found on EEPROM */
+#define AR5K_EEPROM_MAGIC_5212         0x0000145c /* 5212 */
+#define AR5K_EEPROM_MAGIC_5211         0x0000145b /* 5211 */
+#define AR5K_EEPROM_MAGIC_5210         0x0000145a /* 5210 */
+
+#define        AR5K_EEPROM_IS_HB63             0x000b  /* Talon detect */
+
+#define AR5K_EEPROM_RFKILL             0x0f
+#define AR5K_EEPROM_RFKILL_GPIO_SEL    0x0000001c
+#define AR5K_EEPROM_RFKILL_GPIO_SEL_S  2
+#define AR5K_EEPROM_RFKILL_POLARITY    0x00000002
+#define AR5K_EEPROM_RFKILL_POLARITY_S  1
+
+#define AR5K_EEPROM_REG_DOMAIN         0x00bf  /* EEPROM regdom */
+#define AR5K_EEPROM_CHECKSUM           0x00c0  /* EEPROM checksum */
+#define AR5K_EEPROM_INFO_BASE          0x00c0  /* EEPROM header */
+#define AR5K_EEPROM_INFO_MAX           (0x400 - AR5K_EEPROM_INFO_BASE)
+#define AR5K_EEPROM_INFO_CKSUM         0xffff
+#define AR5K_EEPROM_INFO(_n)           (AR5K_EEPROM_INFO_BASE + (_n))
+
+#define AR5K_EEPROM_VERSION            AR5K_EEPROM_INFO(1)     /* EEPROM Version */
+#define AR5K_EEPROM_VERSION_3_0                0x3000  /* No idea what's going on before this version */
+#define AR5K_EEPROM_VERSION_3_1                0x3001  /* ob/db values for 2Ghz (ar5211_rfregs) */
+#define AR5K_EEPROM_VERSION_3_2                0x3002  /* different frequency representation (eeprom_bin2freq) */
+#define AR5K_EEPROM_VERSION_3_3                0x3003  /* offsets changed, has 32 CTLs (see below) and ee_false_detect (eeprom_read_modes) */
+#define AR5K_EEPROM_VERSION_3_4                0x3004  /* has ee_i_gain, ee_cck_ofdm_power_delta (eeprom_read_modes) */
+#define AR5K_EEPROM_VERSION_4_0                0x4000  /* has ee_misc, ee_cal_pier, ee_turbo_max_power and ee_xr_power (eeprom_init) */
+#define AR5K_EEPROM_VERSION_4_1                0x4001  /* has ee_margin_tx_rx (eeprom_init) */
+#define AR5K_EEPROM_VERSION_4_2                0x4002  /* has ee_cck_ofdm_gain_delta (eeprom_init) */
+#define AR5K_EEPROM_VERSION_4_3                0x4003  /* power calibration changes */
+#define AR5K_EEPROM_VERSION_4_4                0x4004
+#define AR5K_EEPROM_VERSION_4_5                0x4005
+#define AR5K_EEPROM_VERSION_4_6                0x4006  /* has ee_scaled_cck_delta */
+#define AR5K_EEPROM_VERSION_4_7                0x3007  /* 4007 ? */
+#define AR5K_EEPROM_VERSION_4_9                0x4009  /* EAR futureproofing */
+#define AR5K_EEPROM_VERSION_5_0                0x5000  /* Has 2413 PDADC calibration etc */
+#define AR5K_EEPROM_VERSION_5_1                0x5001  /* Has capability values */
+#define AR5K_EEPROM_VERSION_5_3                0x5003  /* Has spur mitigation tables */
+
+#define AR5K_EEPROM_MODE_11A           0
+#define AR5K_EEPROM_MODE_11B           1
+#define AR5K_EEPROM_MODE_11G           2
+
+#define AR5K_EEPROM_HDR                        AR5K_EEPROM_INFO(2)     /* Header that contains the device caps */
+#define AR5K_EEPROM_HDR_11A(_v)                (((_v) >> AR5K_EEPROM_MODE_11A) & 0x1)
+#define AR5K_EEPROM_HDR_11B(_v)                (((_v) >> AR5K_EEPROM_MODE_11B) & 0x1)
+#define AR5K_EEPROM_HDR_11G(_v)                (((_v) >> AR5K_EEPROM_MODE_11G) & 0x1)
+#define AR5K_EEPROM_HDR_T_2GHZ_DIS(_v) (((_v) >> 3) & 0x1)     /* Disable turbo for 2Ghz (?) */
+#define AR5K_EEPROM_HDR_T_5GHZ_DBM(_v) (((_v) >> 4) & 0x7f)    /* Max turbo power for a/XR mode (eeprom_init) */
+#define AR5K_EEPROM_HDR_DEVICE(_v)     (((_v) >> 11) & 0x7)
+#define AR5K_EEPROM_HDR_RFKILL(_v)     (((_v) >> 14) & 0x1)    /* Device has RFKill support */
+#define AR5K_EEPROM_HDR_T_5GHZ_DIS(_v) (((_v) >> 15) & 0x1)    /* Disable turbo for 5Ghz */
+
+/* Newer EEPROMs are using a different offset */
+#define AR5K_EEPROM_OFF(_v, _v3_0, _v3_3) \
+       (((_v) >= AR5K_EEPROM_VERSION_3_3) ? _v3_3 : _v3_0)
+
+#define AR5K_EEPROM_ANT_GAIN(_v)       AR5K_EEPROM_OFF(_v, 0x00c4, 0x00c3)
+#define AR5K_EEPROM_ANT_GAIN_5GHZ(_v)  ((s8)(((_v) >> 8) & 0xff))
+#define AR5K_EEPROM_ANT_GAIN_2GHZ(_v)  ((s8)((_v) & 0xff))
+
+/* Misc values available since EEPROM 4.0 */
+#define AR5K_EEPROM_MISC0              AR5K_EEPROM_INFO(4)
+#define AR5K_EEPROM_EARSTART(_v)       ((_v) & 0xfff)
+#define AR5K_EEPROM_HDR_XR2_DIS(_v)    (((_v) >> 12) & 0x1)
+#define AR5K_EEPROM_HDR_XR5_DIS(_v)    (((_v) >> 13) & 0x1)
+#define AR5K_EEPROM_EEMAP(_v)          (((_v) >> 14) & 0x3)
+
+#define AR5K_EEPROM_MISC1                      AR5K_EEPROM_INFO(5)
+#define AR5K_EEPROM_TARGET_PWRSTART(_v)                ((_v) & 0xfff)
+#define AR5K_EEPROM_HAS32KHZCRYSTAL(_v)                (((_v) >> 14) & 0x1)
+#define AR5K_EEPROM_HAS32KHZCRYSTAL_OLD(_v)    (((_v) >> 15) & 0x1)
+
+#define AR5K_EEPROM_MISC2                      AR5K_EEPROM_INFO(6)
+#define AR5K_EEPROM_EEP_FILE_VERSION(_v)       (((_v) >> 8) & 0xff)
+#define AR5K_EEPROM_EAR_FILE_VERSION(_v)       ((_v) & 0xff)
+
+#define AR5K_EEPROM_MISC3              AR5K_EEPROM_INFO(7)
+#define AR5K_EEPROM_ART_BUILD_NUM(_v)  (((_v) >> 10) & 0x3f)
+#define AR5K_EEPROM_EAR_FILE_ID(_v)    ((_v) & 0xff)
+
+#define AR5K_EEPROM_MISC4              AR5K_EEPROM_INFO(8)
+#define AR5K_EEPROM_CAL_DATA_START(_v) (((_v) >> 4) & 0xfff)
+#define AR5K_EEPROM_MASK_R0(_v)                (((_v) >> 2) & 0x3)
+#define AR5K_EEPROM_MASK_R1(_v)                ((_v) & 0x3)
+
+#define AR5K_EEPROM_MISC5              AR5K_EEPROM_INFO(9)
+#define AR5K_EEPROM_COMP_DIS(_v)       ((_v) & 0x1)
+#define AR5K_EEPROM_AES_DIS(_v)                (((_v) >> 1) & 0x1)
+#define AR5K_EEPROM_FF_DIS(_v)         (((_v) >> 2) & 0x1)
+#define AR5K_EEPROM_BURST_DIS(_v)      (((_v) >> 3) & 0x1)
+#define AR5K_EEPROM_MAX_QCU(_v)                (((_v) >> 4) & 0xf)
+#define AR5K_EEPROM_HEAVY_CLIP_EN(_v)  (((_v) >> 8) & 0x1)
+#define AR5K_EEPROM_KEY_CACHE_SIZE(_v) (((_v) >> 12) & 0xf)
+
+#define AR5K_EEPROM_MISC6              AR5K_EEPROM_INFO(10)
+#define AR5K_EEPROM_TX_CHAIN_DIS       ((_v) & 0x8)
+#define AR5K_EEPROM_RX_CHAIN_DIS       (((_v) >> 3) & 0x8)
+#define AR5K_EEPROM_FCC_MID_EN         (((_v) >> 6) & 0x1)
+#define AR5K_EEPROM_JAP_U1EVEN_EN      (((_v) >> 7) & 0x1)
+#define AR5K_EEPROM_JAP_U2_EN          (((_v) >> 8) & 0x1)
+#define AR5K_EEPROM_JAP_U1ODD_EN       (((_v) >> 9) & 0x1)
+#define AR5K_EEPROM_JAP_11A_NEW_EN     (((_v) >> 10) & 0x1)
+
+/* calibration settings */
+#define AR5K_EEPROM_MODES_11A(_v)      AR5K_EEPROM_OFF(_v, 0x00c5, 0x00d4)
+#define AR5K_EEPROM_MODES_11B(_v)      AR5K_EEPROM_OFF(_v, 0x00d0, 0x00f2)
+#define AR5K_EEPROM_MODES_11G(_v)      AR5K_EEPROM_OFF(_v, 0x00da, 0x010d)
+#define AR5K_EEPROM_CTL(_v)            AR5K_EEPROM_OFF(_v, 0x00e4, 0x0128)     /* Conformance test limits */
+#define AR5K_EEPROM_GROUPS_START(_v)   AR5K_EEPROM_OFF(_v, 0x0100, 0x0150)     /* Start of Groups */
+#define AR5K_EEPROM_GROUP1_OFFSET      0x0
+#define AR5K_EEPROM_GROUP2_OFFSET      0x5
+#define AR5K_EEPROM_GROUP3_OFFSET      0x37
+#define AR5K_EEPROM_GROUP4_OFFSET      0x46
+#define AR5K_EEPROM_GROUP5_OFFSET      0x55
+#define AR5K_EEPROM_GROUP6_OFFSET      0x65
+#define AR5K_EEPROM_GROUP7_OFFSET      0x69
+#define AR5K_EEPROM_GROUP8_OFFSET      0x6f
+
+#define AR5K_EEPROM_TARGET_PWR_OFF_11A(_v)     AR5K_EEPROM_OFF(_v, AR5K_EEPROM_GROUPS_START(_v) + \
+                                                               AR5K_EEPROM_GROUP5_OFFSET, 0x0000)
+#define AR5K_EEPROM_TARGET_PWR_OFF_11B(_v)     AR5K_EEPROM_OFF(_v, AR5K_EEPROM_GROUPS_START(_v) + \
+                                                               AR5K_EEPROM_GROUP6_OFFSET, 0x0010)
+#define AR5K_EEPROM_TARGET_PWR_OFF_11G(_v)     AR5K_EEPROM_OFF(_v, AR5K_EEPROM_GROUPS_START(_v) + \
+                                                               AR5K_EEPROM_GROUP7_OFFSET, 0x0014)
+
+/* [3.1 - 3.3] */
+#define AR5K_EEPROM_OBDB0_2GHZ         0x00ec
+#define AR5K_EEPROM_OBDB1_2GHZ         0x00ed
+
+#define AR5K_EEPROM_PROTECT            0x003f  /* EEPROM protect status */
+#define AR5K_EEPROM_PROTECT_RD_0_31    0x0001  /* Read protection bit for offsets 0x0 - 0x1f */
+#define AR5K_EEPROM_PROTECT_WR_0_31    0x0002  /* Write protection bit for offsets 0x0 - 0x1f */
+#define AR5K_EEPROM_PROTECT_RD_32_63   0x0004  /* 0x20 - 0x3f */
+#define AR5K_EEPROM_PROTECT_WR_32_63   0x0008
+#define AR5K_EEPROM_PROTECT_RD_64_127  0x0010  /* 0x40 - 0x7f */
+#define AR5K_EEPROM_PROTECT_WR_64_127  0x0020
+#define AR5K_EEPROM_PROTECT_RD_128_191 0x0040  /* 0x80 - 0xbf (regdom) */
+#define AR5K_EEPROM_PROTECT_WR_128_191 0x0080
+#define AR5K_EEPROM_PROTECT_RD_192_207 0x0100  /* 0xc0 - 0xcf */
+#define AR5K_EEPROM_PROTECT_WR_192_207 0x0200
+#define AR5K_EEPROM_PROTECT_RD_208_223 0x0400  /* 0xd0 - 0xdf */
+#define AR5K_EEPROM_PROTECT_WR_208_223 0x0800
+#define AR5K_EEPROM_PROTECT_RD_224_239 0x1000  /* 0xe0 - 0xef */
+#define AR5K_EEPROM_PROTECT_WR_224_239 0x2000
+#define AR5K_EEPROM_PROTECT_RD_240_255 0x4000  /* 0xf0 - 0xff */
+#define AR5K_EEPROM_PROTECT_WR_240_255 0x8000
+
+/* Some EEPROM defines */
+#define AR5K_EEPROM_EEP_SCALE          100
+#define AR5K_EEPROM_EEP_DELTA          10
+#define AR5K_EEPROM_N_MODES            3
+#define AR5K_EEPROM_N_5GHZ_CHAN                10
+#define AR5K_EEPROM_N_2GHZ_CHAN                3
+#define AR5K_EEPROM_N_2GHZ_CHAN_2413   4
+#define        AR5K_EEPROM_N_2GHZ_CHAN_MAX     4
+#define AR5K_EEPROM_MAX_CHAN           10
+#define AR5K_EEPROM_N_PWR_POINTS_5111  11
+#define AR5K_EEPROM_N_PCDAC            11
+#define AR5K_EEPROM_N_PHASE_CAL                5
+#define AR5K_EEPROM_N_TEST_FREQ                8
+#define AR5K_EEPROM_N_EDGES            8
+#define AR5K_EEPROM_N_INTERCEPTS       11
+#define AR5K_EEPROM_FREQ_M(_v)         AR5K_EEPROM_OFF(_v, 0x7f, 0xff)
+#define AR5K_EEPROM_PCDAC_M            0x3f
+#define AR5K_EEPROM_PCDAC_START                1
+#define AR5K_EEPROM_PCDAC_STOP         63
+#define AR5K_EEPROM_PCDAC_STEP         1
+#define AR5K_EEPROM_NON_EDGE_M         0x40
+#define AR5K_EEPROM_CHANNEL_POWER      8
+#define AR5K_EEPROM_N_OBDB             4
+#define AR5K_EEPROM_OBDB_DIS           0xffff
+#define AR5K_EEPROM_CHANNEL_DIS                0xff
+#define AR5K_EEPROM_SCALE_OC_DELTA(_x) (((_x) * 2) / 10)
+#define AR5K_EEPROM_N_CTLS(_v)         AR5K_EEPROM_OFF(_v, 16, 32)
+#define AR5K_EEPROM_MAX_CTLS           32
+#define AR5K_EEPROM_N_PD_CURVES                4
+#define AR5K_EEPROM_N_XPD0_POINTS      4
+#define AR5K_EEPROM_N_XPD3_POINTS      3
+#define AR5K_EEPROM_N_PD_GAINS         4
+#define AR5K_EEPROM_N_PD_POINTS                5
+#define AR5K_EEPROM_N_INTERCEPT_10_2GHZ        35
+#define AR5K_EEPROM_N_INTERCEPT_10_5GHZ        55
+#define AR5K_EEPROM_POWER_M            0x3f
+#define AR5K_EEPROM_POWER_MIN          0
+#define AR5K_EEPROM_POWER_MAX          3150
+#define AR5K_EEPROM_POWER_STEP         50
+#define AR5K_EEPROM_POWER_TABLE_SIZE   64
+#define AR5K_EEPROM_N_POWER_LOC_11B    4
+#define AR5K_EEPROM_N_POWER_LOC_11G    6
+#define AR5K_EEPROM_I_GAIN             10
+#define AR5K_EEPROM_CCK_OFDM_DELTA     15
+#define AR5K_EEPROM_N_IQ_CAL           2
+/* 5GHz/2GHz */
+enum ath5k_eeprom_freq_bands{
+       AR5K_EEPROM_BAND_5GHZ = 0,
+       AR5K_EEPROM_BAND_2GHZ = 1,
+       AR5K_EEPROM_N_FREQ_BANDS,
+};
+/* Spur chans per freq band */
+#define        AR5K_EEPROM_N_SPUR_CHANS        5
+/* fbin value for chan 2464 x2 */
+#define        AR5K_EEPROM_5413_SPUR_CHAN_1    1640
+/* fbin value for chan 2420 x2 */
+#define        AR5K_EEPROM_5413_SPUR_CHAN_2    1200
+#define        AR5K_EEPROM_SPUR_CHAN_MASK      0x3FFF
+#define        AR5K_EEPROM_NO_SPUR             0x8000
+#define        AR5K_SPUR_CHAN_WIDTH                    87
+#define        AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz       3125
+#define        AR5K_SPUR_SYMBOL_WIDTH_TURBO_100Hz      6250
+
+#define AR5K_EEPROM_READ(_o, _v) do {                  \
+       ret = ath5k_hw_eeprom_read(ah, (_o), &(_v));    \
+       if (ret)                                        \
+               return ret;                             \
+} while (0)
+
+#define AR5K_EEPROM_READ_HDR(_o, _v)                                   \
+       AR5K_EEPROM_READ(_o, ah->ah_capabilities.cap_eeprom._v);        \
+
+enum ath5k_ant_table {
+       AR5K_ANT_CTL            = 0,    /* Idle switch table settings */
+       AR5K_ANT_SWTABLE_A      = 1,    /* Switch table for antenna A */
+       AR5K_ANT_SWTABLE_B      = 2,    /* Switch table for antenna B */
+       AR5K_ANT_MAX,
+};
+
+enum ath5k_ctl_mode {
+       AR5K_CTL_11A = 0,
+       AR5K_CTL_11B = 1,
+       AR5K_CTL_11G = 2,
+       AR5K_CTL_TURBO = 3,
+       AR5K_CTL_TURBOG = 4,
+       AR5K_CTL_2GHT20 = 5,
+       AR5K_CTL_5GHT20 = 6,
+       AR5K_CTL_2GHT40 = 7,
+       AR5K_CTL_5GHT40 = 8,
+       AR5K_CTL_MODE_M = 15,
+};
+
+/* Default CTL ids for the 3 main reg domains.
+ * Atheros only uses these by default but vendors
+ * can have up to 32 different CTLs for different
+ * scenarios. Note that theese values are ORed with
+ * the mode id (above) so we can have up to 24 CTL
+ * datasets out of these 3 main regdomains. That leaves
+ * 8 ids that can be used by vendors and since 0x20 is
+ * missing from HAL sources i guess this is the set of
+ * custom CTLs vendors can use. */
+#define        AR5K_CTL_FCC    0x10
+#define        AR5K_CTL_CUSTOM 0x20
+#define        AR5K_CTL_ETSI   0x30
+#define        AR5K_CTL_MKK    0x40
+
+/* Indicates a CTL with only mode set and
+ * no reg domain mapping, such CTLs are used
+ * for world roaming domains or simply when
+ * a reg domain is not set */
+#define        AR5K_CTL_NO_REGDOMAIN   0xf0
+
+/* Indicates an empty (invalid) CTL */
+#define AR5K_CTL_NO_CTL                0xff
+
+/* Per channel calibration data, used for power table setup */
+struct ath5k_chan_pcal_info_rf5111 {
+       /* Power levels in half dbm units
+        * for one power curve. */
+       u8 pwr[AR5K_EEPROM_N_PWR_POINTS_5111];
+       /* PCDAC table steps
+        * for the above values */
+       u8 pcdac[AR5K_EEPROM_N_PWR_POINTS_5111];
+       /* Starting PCDAC step */
+       u8 pcdac_min;
+       /* Final PCDAC step */
+       u8 pcdac_max;
+};
+
+struct ath5k_chan_pcal_info_rf5112 {
+       /* Power levels in quarter dBm units
+        * for lower (0) and higher (3)
+        * level curves in 0.25dB units */
+       s8 pwr_x0[AR5K_EEPROM_N_XPD0_POINTS];
+       s8 pwr_x3[AR5K_EEPROM_N_XPD3_POINTS];
+       /* PCDAC table steps
+        * for the above values */
+       u8 pcdac_x0[AR5K_EEPROM_N_XPD0_POINTS];
+       u8 pcdac_x3[AR5K_EEPROM_N_XPD3_POINTS];
+};
+
+struct ath5k_chan_pcal_info_rf2413 {
+       /* Starting pwr/pddac values */
+       s8 pwr_i[AR5K_EEPROM_N_PD_GAINS];
+       u8 pddac_i[AR5K_EEPROM_N_PD_GAINS];
+       /* (pwr,pddac) points
+        * power levels in 0.5dB units */
+       s8 pwr[AR5K_EEPROM_N_PD_GAINS]
+               [AR5K_EEPROM_N_PD_POINTS];
+       u8 pddac[AR5K_EEPROM_N_PD_GAINS]
+               [AR5K_EEPROM_N_PD_POINTS];
+};
+
+enum ath5k_powertable_type {
+       AR5K_PWRTABLE_PWR_TO_PCDAC = 0,
+       AR5K_PWRTABLE_LINEAR_PCDAC = 1,
+       AR5K_PWRTABLE_PWR_TO_PDADC = 2,
+};
+
+struct ath5k_pdgain_info {
+       u8 pd_points;
+       u8 *pd_step;
+       /* Power values are in
+        * 0.25dB units */
+       s16 *pd_pwr;
+};
+
+struct ath5k_chan_pcal_info {
+       /* Frequency */
+       u16     freq;
+       /* Tx power boundaries */
+       s16     max_pwr;
+       s16     min_pwr;
+       union {
+               struct ath5k_chan_pcal_info_rf5111 rf5111_info;
+               struct ath5k_chan_pcal_info_rf5112 rf5112_info;
+               struct ath5k_chan_pcal_info_rf2413 rf2413_info;
+       };
+       /* Raw values used by phy code
+        * Curves are stored in order from lower
+        * gain to higher gain (max txpower -> min txpower) */
+       struct ath5k_pdgain_info *pd_curves;
+};
+
+/* Per rate calibration data for each mode,
+ * used for rate power table setup.
+ * Note: Values in 0.5dB units */
+struct ath5k_rate_pcal_info {
+       u16     freq; /* Frequency */
+       /* Power level for 6-24Mbit/s rates or
+        * 1Mb rate */
+       u16     target_power_6to24;
+       /* Power level for 36Mbit rate or
+        * 2Mb rate */
+       u16     target_power_36;
+       /* Power level for 48Mbit rate or
+        * 5.5Mbit rate */
+       u16     target_power_48;
+       /* Power level for 54Mbit rate or
+        * 11Mbit rate */
+       u16     target_power_54;
+};
+
+/* Power edges for conformance test limits */
+struct ath5k_edge_power {
+       u16 freq;
+       u16 edge; /* in half dBm */
+       bool flag;
+};
+
+/* EEPROM calibration data */
+struct ath5k_eeprom_info {
+
+       /* Header information */
+       u16     ee_magic;
+       u16     ee_protect;
+       u16     ee_regdomain;
+       u16     ee_version;
+       u16     ee_header;
+       u16     ee_ant_gain;
+       u8      ee_rfkill_pin;
+       bool    ee_rfkill_pol;
+       bool    ee_is_hb63;
+       u16     ee_misc0;
+       u16     ee_misc1;
+       u16     ee_misc2;
+       u16     ee_misc3;
+       u16     ee_misc4;
+       u16     ee_misc5;
+       u16     ee_misc6;
+       u16     ee_cck_ofdm_gain_delta;
+       u16     ee_cck_ofdm_power_delta;
+       u16     ee_scaled_cck_delta;
+
+       /* RF Calibration settings (reset, rfregs) */
+       u16     ee_i_cal[AR5K_EEPROM_N_MODES];
+       u16     ee_q_cal[AR5K_EEPROM_N_MODES];
+       u16     ee_fixed_bias[AR5K_EEPROM_N_MODES];
+       u16     ee_turbo_max_power[AR5K_EEPROM_N_MODES];
+       u16     ee_xr_power[AR5K_EEPROM_N_MODES];
+       u16     ee_switch_settling[AR5K_EEPROM_N_MODES];
+       u16     ee_atn_tx_rx[AR5K_EEPROM_N_MODES];
+       u16     ee_ant_control[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_PCDAC];
+       u16     ee_ob[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_OBDB];
+       u16     ee_db[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_OBDB];
+       u16     ee_tx_end2xlna_enable[AR5K_EEPROM_N_MODES];
+       u16     ee_tx_end2xpa_disable[AR5K_EEPROM_N_MODES];
+       u16     ee_tx_frm2xpa_enable[AR5K_EEPROM_N_MODES];
+       u16     ee_thr_62[AR5K_EEPROM_N_MODES];
+       u16     ee_xlna_gain[AR5K_EEPROM_N_MODES];
+       u16     ee_xpd[AR5K_EEPROM_N_MODES];
+       u16     ee_x_gain[AR5K_EEPROM_N_MODES];
+       u16     ee_i_gain[AR5K_EEPROM_N_MODES];
+       u16     ee_margin_tx_rx[AR5K_EEPROM_N_MODES];
+       u16     ee_switch_settling_turbo[AR5K_EEPROM_N_MODES];
+       u16     ee_margin_tx_rx_turbo[AR5K_EEPROM_N_MODES];
+       u16     ee_atn_tx_rx_turbo[AR5K_EEPROM_N_MODES];
+
+       /* Power calibration data */
+       u16     ee_false_detect[AR5K_EEPROM_N_MODES];
+
+       /* Number of pd gain curves per mode */
+       u8      ee_pd_gains[AR5K_EEPROM_N_MODES];
+       /* Back mapping pdcurve number -> pdcurve index in pd->pd_curves */
+       u8      ee_pdc_to_idx[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_PD_GAINS];
+
+       u8      ee_n_piers[AR5K_EEPROM_N_MODES];
+       struct ath5k_chan_pcal_info     ee_pwr_cal_a[AR5K_EEPROM_N_5GHZ_CHAN];
+       struct ath5k_chan_pcal_info     ee_pwr_cal_b[AR5K_EEPROM_N_2GHZ_CHAN_MAX];
+       struct ath5k_chan_pcal_info     ee_pwr_cal_g[AR5K_EEPROM_N_2GHZ_CHAN_MAX];
+
+       /* Per rate target power levels */
+       u8      ee_rate_target_pwr_num[AR5K_EEPROM_N_MODES];
+       struct ath5k_rate_pcal_info     ee_rate_tpwr_a[AR5K_EEPROM_N_5GHZ_CHAN];
+       struct ath5k_rate_pcal_info     ee_rate_tpwr_b[AR5K_EEPROM_N_2GHZ_CHAN_MAX];
+       struct ath5k_rate_pcal_info     ee_rate_tpwr_g[AR5K_EEPROM_N_2GHZ_CHAN_MAX];
+
+       /* Conformance test limits (Unused) */
+       u8      ee_ctls;
+       u8      ee_ctl[AR5K_EEPROM_MAX_CTLS];
+       struct ath5k_edge_power ee_ctl_pwr[AR5K_EEPROM_N_EDGES * AR5K_EEPROM_MAX_CTLS];
+
+       /* Noise Floor Calibration settings */
+       s16     ee_noise_floor_thr[AR5K_EEPROM_N_MODES];
+       s8      ee_adc_desired_size[AR5K_EEPROM_N_MODES];
+       s8      ee_pga_desired_size[AR5K_EEPROM_N_MODES];
+       s8      ee_adc_desired_size_turbo[AR5K_EEPROM_N_MODES];
+       s8      ee_pga_desired_size_turbo[AR5K_EEPROM_N_MODES];
+       s8      ee_pd_gain_overlap;
+
+       /* Spur mitigation data (fbin values for spur channels) */
+       u16     ee_spur_chans[AR5K_EEPROM_N_SPUR_CHANS][AR5K_EEPROM_N_FREQ_BANDS];
+
+       /* Antenna raw switch tables */
+       u32     ee_antenna[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX];
+};
+
diff --git a/drivers/net/wireless/ath/ath5k/gpio.c b/drivers/net/wireless/ath/ath5k/gpio.c
new file mode 100644 (file)
index 0000000..64a27e7
--- /dev/null
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
+ * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
+ *
+ * Permission to use, copy, modify, and 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.
+ *
+ */
+
+/****************\
+  GPIO Functions
+\****************/
+
+#include "ath5k.h"
+#include "reg.h"
+#include "debug.h"
+#include "base.h"
+
+/*
+ * Set led state
+ */
+void ath5k_hw_set_ledstate(struct ath5k_hw *ah, unsigned int state)
+{
+       u32 led;
+       /*5210 has different led mode handling*/
+       u32 led_5210;
+
+       ATH5K_TRACE(ah->ah_sc);
+
+       /*Reset led status*/
+       if (ah->ah_version != AR5K_AR5210)
+               AR5K_REG_DISABLE_BITS(ah, AR5K_PCICFG,
+                       AR5K_PCICFG_LEDMODE |  AR5K_PCICFG_LED);
+       else
+               AR5K_REG_DISABLE_BITS(ah, AR5K_PCICFG, AR5K_PCICFG_LED);
+
+       /*
+        * Some blinking values, define at your wish
+        */
+       switch (state) {
+       case AR5K_LED_SCAN:
+       case AR5K_LED_AUTH:
+               led = AR5K_PCICFG_LEDMODE_PROP | AR5K_PCICFG_LED_PEND;
+               led_5210 = AR5K_PCICFG_LED_PEND | AR5K_PCICFG_LED_BCTL;
+               break;
+
+       case AR5K_LED_INIT:
+               led = AR5K_PCICFG_LEDMODE_PROP | AR5K_PCICFG_LED_NONE;
+               led_5210 = AR5K_PCICFG_LED_PEND;
+               break;
+
+       case AR5K_LED_ASSOC:
+       case AR5K_LED_RUN:
+               led = AR5K_PCICFG_LEDMODE_PROP | AR5K_PCICFG_LED_ASSOC;
+               led_5210 = AR5K_PCICFG_LED_ASSOC;
+               break;
+
+       default:
+               led = AR5K_PCICFG_LEDMODE_PROM | AR5K_PCICFG_LED_NONE;
+               led_5210 = AR5K_PCICFG_LED_PEND;
+               break;
+       }
+
+       /*Write new status to the register*/
+       if (ah->ah_version != AR5K_AR5210)
+               AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, led);
+       else
+               AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, led_5210);
+}
+
+/*
+ * Set GPIO inputs
+ */
+int ath5k_hw_set_gpio_input(struct ath5k_hw *ah, u32 gpio)
+{
+       ATH5K_TRACE(ah->ah_sc);
+       if (gpio >= AR5K_NUM_GPIO)
+               return -EINVAL;
+
+       ath5k_hw_reg_write(ah,
+               (ath5k_hw_reg_read(ah, AR5K_GPIOCR) & ~AR5K_GPIOCR_OUT(gpio))
+               | AR5K_GPIOCR_IN(gpio), AR5K_GPIOCR);
+
+       return 0;
+}
+
+/*
+ * Set GPIO outputs
+ */
+int ath5k_hw_set_gpio_output(struct ath5k_hw *ah, u32 gpio)
+{
+       ATH5K_TRACE(ah->ah_sc);
+       if (gpio >= AR5K_NUM_GPIO)
+               return -EINVAL;
+
+       ath5k_hw_reg_write(ah,
+               (ath5k_hw_reg_read(ah, AR5K_GPIOCR) & ~AR5K_GPIOCR_OUT(gpio))
+               | AR5K_GPIOCR_OUT(gpio), AR5K_GPIOCR);
+
+       return 0;
+}
+
+/*
+ * Get GPIO state
+ */
+u32 ath5k_hw_get_gpio(struct ath5k_hw *ah, u32 gpio)
+{
+       ATH5K_TRACE(ah->ah_sc);
+       if (gpio >= AR5K_NUM_GPIO)
+               return 0xffffffff;
+
+       /* GPIO input magic */
+       return ((ath5k_hw_reg_read(ah, AR5K_GPIODI) & AR5K_GPIODI_M) >> gpio) &
+               0x1;
+}
+
+/*
+ * Set GPIO state
+ */
+int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val)
+{
+       u32 data;
+       ATH5K_TRACE(ah->ah_sc);
+
+       if (gpio >= AR5K_NUM_GPIO)
+               return -EINVAL;
+
+       /* GPIO output magic */
+       data = ath5k_hw_reg_read(ah, AR5K_GPIODO);
+
+       data &= ~(1 << gpio);
+       data |= (val & 1) << gpio;
+
+       ath5k_hw_reg_write(ah, data, AR5K_GPIODO);
+
+       return 0;
+}
+
+/*
+ * Initialize the GPIO interrupt (RFKill switch)
+ */
+void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio,
+               u32 interrupt_level)
+{
+       u32 data;
+
+       ATH5K_TRACE(ah->ah_sc);
+       if (gpio >= AR5K_NUM_GPIO)
+               return;
+
+       /*
+        * Set the GPIO interrupt
+        */
+       data = (ath5k_hw_reg_read(ah, AR5K_GPIOCR) &
+               ~(AR5K_GPIOCR_INT_SEL(gpio) | AR5K_GPIOCR_INT_SELH |
+               AR5K_GPIOCR_INT_ENA | AR5K_GPIOCR_OUT(gpio))) |
+               (AR5K_GPIOCR_INT_SEL(gpio) | AR5K_GPIOCR_INT_ENA);
+
+       ath5k_hw_reg_write(ah, interrupt_level ? data :
+               (data | AR5K_GPIOCR_INT_SELH), AR5K_GPIOCR);
+
+       ah->ah_imr |= AR5K_IMR_GPIO;
+
+       /* Enable GPIO interrupts */
+       AR5K_REG_ENABLE_BITS(ah, AR5K_PIMR, AR5K_IMR_GPIO);
+}
+
diff --git a/drivers/net/wireless/ath/ath5k/initvals.c b/drivers/net/wireless/ath/ath5k/initvals.c
new file mode 100644 (file)
index 0000000..18eb519
--- /dev/null
@@ -0,0 +1,1555 @@
+/*
+ * Initial register settings functions
+ *
+ * Copyright (c) 2004-2007 Reyk Floeter <reyk@openbsd.org>
+ * Copyright (c) 2006-2009 Nick Kossifidis <mickflemm@gmail.com>
+ * Copyright (c) 2007-2008 Jiri Slaby <jirislaby@gmail.com>
+ *
+ * Permission to use, copy, modify, and 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 "ath5k.h"
+#include "reg.h"
+#include "debug.h"
+#include "base.h"
+
+/*
+ * Mode-independent initial register writes
+ */
+
+struct ath5k_ini {
+       u16     ini_register;
+       u32     ini_value;
+
+       enum {
+               AR5K_INI_WRITE = 0,     /* Default */
+               AR5K_INI_READ = 1,      /* Cleared on read */
+       } ini_mode;
+};
+
+/*
+ * Mode specific initial register values
+ */
+
+struct ath5k_ini_mode {
+       u16     mode_register;
+       u32     mode_value[5];
+};
+
+/* Initial register settings for AR5210 */
+static const struct ath5k_ini ar5210_ini[] = {
+       /* PCU and MAC registers */
+       { AR5K_NOQCU_TXDP0,     0 },
+       { AR5K_NOQCU_TXDP1,     0 },
+       { AR5K_RXDP,            0 },
+       { AR5K_CR,              0 },
+       { AR5K_ISR,             0, AR5K_INI_READ },
+       { AR5K_IMR,             0 },
+       { AR5K_IER,             AR5K_IER_DISABLE },
+       { AR5K_BSR,             0, AR5K_INI_READ },
+       { AR5K_TXCFG,           AR5K_DMASIZE_128B },
+       { AR5K_RXCFG,           AR5K_DMASIZE_128B },
+       { AR5K_CFG,             AR5K_INIT_CFG },
+       { AR5K_TOPS,            8 },
+       { AR5K_RXNOFRM,         8 },
+       { AR5K_RPGTO,           0 },
+       { AR5K_TXNOFRM,         0 },
+       { AR5K_SFR,             0 },
+       { AR5K_MIBC,            0 },
+       { AR5K_MISC,            0 },
+       { AR5K_RX_FILTER_5210,  0 },
+       { AR5K_MCAST_FILTER0_5210, 0 },
+       { AR5K_MCAST_FILTER1_5210, 0 },
+       { AR5K_TX_MASK0,        0 },
+       { AR5K_TX_MASK1,        0 },
+       { AR5K_CLR_TMASK,       0 },
+       { AR5K_TRIG_LVL,        AR5K_TUNE_MIN_TX_FIFO_THRES },
+       { AR5K_DIAG_SW_5210,    0 },
+       { AR5K_RSSI_THR,        AR5K_TUNE_RSSI_THRES },
+       { AR5K_TSF_L32_5210,    0 },
+       { AR5K_TIMER0_5210,     0 },
+       { AR5K_TIMER1_5210,     0xffffffff },
+       { AR5K_TIMER2_5210,     0xffffffff },
+       { AR5K_TIMER3_5210,     1 },
+       { AR5K_CFP_DUR_5210,    0 },
+       { AR5K_CFP_PERIOD_5210, 0 },
+       /* PHY registers */
+       { AR5K_PHY(0),  0x00000047 },
+       { AR5K_PHY_AGC, 0x00000000 },
+       { AR5K_PHY(3),  0x09848ea6 },
+       { AR5K_PHY(4),  0x3d32e000 },
+       { AR5K_PHY(5),  0x0000076b },
+       { AR5K_PHY_ACT, AR5K_PHY_ACT_DISABLE },
+       { AR5K_PHY(8),  0x02020200 },
+       { AR5K_PHY(9),  0x00000e0e },
+       { AR5K_PHY(10), 0x0a020201 },
+       { AR5K_PHY(11), 0x00036ffc },
+       { AR5K_PHY(12), 0x00000000 },
+       { AR5K_PHY(13), 0x00000e0e },
+       { AR5K_PHY(14), 0x00000007 },
+       { AR5K_PHY(15), 0x00020100 },
+       { AR5K_PHY(16), 0x89630000 },
+       { AR5K_PHY(17), 0x1372169c },
+       { AR5K_PHY(18), 0x0018b633 },
+       { AR5K_PHY(19), 0x1284613c },
+       { AR5K_PHY(20), 0x0de8b8e0 },
+       { AR5K_PHY(21), 0x00074859 },
+       { AR5K_PHY(22), 0x7e80beba },
+       { AR5K_PHY(23), 0x313a665e },
+       { AR5K_PHY_AGCCTL, 0x00001d08 },
+       { AR5K_PHY(25), 0x0001ce00 },
+       { AR5K_PHY(26), 0x409a4190 },
+       { AR5K_PHY(28), 0x0000000f },
+       { AR5K_PHY(29), 0x00000080 },
+       { AR5K_PHY(30), 0x00000004 },
+       { AR5K_PHY(31), 0x00000018 },   /* 0x987c */
+       { AR5K_PHY(64), 0x00000000 },   /* 0x9900 */
+       { AR5K_PHY(65), 0x00000000 },
+       { AR5K_PHY(66), 0x00000000 },
+       { AR5K_PHY(67), 0x00800000 },
+       { AR5K_PHY(68), 0x00000003 },
+       /* BB gain table (64bytes) */
+       { AR5K_BB_GAIN(0), 0x00000000 },
+       { AR5K_BB_GAIN(1), 0x00000020 },
+       { AR5K_BB_GAIN(2), 0x00000010 },
+       { AR5K_BB_GAIN(3), 0x00000030 },
+       { AR5K_BB_GAIN(4), 0x00000008 },
+       { AR5K_BB_GAIN(5), 0x00000028 },
+       { AR5K_BB_GAIN(6), 0x00000028 },
+       { AR5K_BB_GAIN(7), 0x00000004 },
+       { AR5K_BB_GAIN(8), 0x00000024 },
+       { AR5K_BB_GAIN(9), 0x00000014 },
+       { AR5K_BB_GAIN(10), 0x00000034 },
+       { AR5K_BB_GAIN(11), 0x0000000c },
+       { AR5K_BB_GAIN(12), 0x0000002c },
+       { AR5K_BB_GAIN(13), 0x00000002 },
+       { AR5K_BB_GAIN(14), 0x00000022 },
+       { AR5K_BB_GAIN(15), 0x00000012 },
+       { AR5K_BB_GAIN(16), 0x00000032 },
+       { AR5K_BB_GAIN(17), 0x0000000a },
+       { AR5K_BB_GAIN(18), 0x0000002a },
+       { AR5K_BB_GAIN(19), 0x00000001 },
+       { AR5K_BB_GAIN(20), 0x00000021 },
+       { AR5K_BB_GAIN(21), 0x00000011 },
+       { AR5K_BB_GAIN(22), 0x00000031 },
+       { AR5K_BB_GAIN(23), 0x00000009 },
+       { AR5K_BB_GAIN(24), 0x00000029 },
+       { AR5K_BB_GAIN(25), 0x00000005 },
+       { AR5K_BB_GAIN(26), 0x00000025 },
+       { AR5K_BB_GAIN(27), 0x00000015 },
+       { AR5K_BB_GAIN(28), 0x00000035 },
+       { AR5K_BB_GAIN(29), 0x0000000d },
+       { AR5K_BB_GAIN(30), 0x0000002d },
+       { AR5K_BB_GAIN(31), 0x00000003 },
+       { AR5K_BB_GAIN(32), 0x00000023 },
+       { AR5K_BB_GAIN(33), 0x00000013 },
+       { AR5K_BB_GAIN(34), 0x00000033 },
+       { AR5K_BB_GAIN(35), 0x0000000b },
+       { AR5K_BB_GAIN(36), 0x0000002b },
+       { AR5K_BB_GAIN(37), 0x00000007 },
+       { AR5K_BB_GAIN(38), 0x00000027 },
+       { AR5K_BB_GAIN(39), 0x00000017 },
+       { AR5K_BB_GAIN(40), 0x00000037 },
+       { AR5K_BB_GAIN(41), 0x0000000f },
+       { AR5K_BB_GAIN(42), 0x0000002f },
+       { AR5K_BB_GAIN(43), 0x0000002f },
+       { AR5K_BB_GAIN(44), 0x0000002f },
+       { AR5K_BB_GAIN(45), 0x0000002f },
+       { AR5K_BB_GAIN(46), 0x0000002f },
+       { AR5K_BB_GAIN(47), 0x0000002f },
+       { AR5K_BB_GAIN(48), 0x0000002f },
+       { AR5K_BB_GAIN(49), 0x0000002f },
+       { AR5K_BB_GAIN(50), 0x0000002f },
+       { AR5K_BB_GAIN(51), 0x0000002f },
+       { AR5K_BB_GAIN(52), 0x0000002f },
+       { AR5K_BB_GAIN(53), 0x0000002f },
+       { AR5K_BB_GAIN(54), 0x0000002f },
+       { AR5K_BB_GAIN(55), 0x0000002f },
+       { AR5K_BB_GAIN(56), 0x0000002f },
+       { AR5K_BB_GAIN(57), 0x0000002f },
+       { AR5K_BB_GAIN(58), 0x0000002f },
+       { AR5K_BB_GAIN(59), 0x0000002f },
+       { AR5K_BB_GAIN(60), 0x0000002f },
+       { AR5K_BB_GAIN(61), 0x0000002f },
+       { AR5K_BB_GAIN(62), 0x0000002f },
+       { AR5K_BB_GAIN(63), 0x0000002f },
+       /* 5110 RF gain table (64btes) */
+       { AR5K_RF_GAIN(0), 0x0000001d },
+       { AR5K_RF_GAIN(1), 0x0000005d },
+       { AR5K_RF_GAIN(2), 0x0000009d },
+       { AR5K_RF_GAIN(3), 0x000000dd },
+       { AR5K_RF_GAIN(4), 0x0000011d },
+       { AR5K_RF_GAIN(5), 0x00000021 },
+       { AR5K_RF_GAIN(6), 0x00000061 },
+       { AR5K_RF_GAIN(7), 0x000000a1 },
+       { AR5K_RF_GAIN(8), 0x000000e1 },
+       { AR5K_RF_GAIN(9), 0x00000031 },
+       { AR5K_RF_GAIN(10), 0x00000071 },
+       { AR5K_RF_GAIN(11), 0x000000b1 },
+       { AR5K_RF_GAIN(12), 0x0000001c },
+       { AR5K_RF_GAIN(13), 0x0000005c },
+       { AR5K_RF_GAIN(14), 0x00000029 },
+       { AR5K_RF_GAIN(15), 0x00000069 },
+       { AR5K_RF_GAIN(16), 0x000000a9 },
+       { AR5K_RF_GAIN(17), 0x00000020 },
+       { AR5K_RF_GAIN(18), 0x00000019 },
+       { AR5K_RF_GAIN(19), 0x00000059 },
+       { AR5K_RF_GAIN(20), 0x00000099 },
+       { AR5K_RF_GAIN(21), 0x00000030 },
+       { AR5K_RF_GAIN(22), 0x00000005 },
+       { AR5K_RF_GAIN(23), 0x00000025 },
+       { AR5K_RF_GAIN(24), 0x00000065 },
+       { AR5K_RF_GAIN(25), 0x000000a5 },
+       { AR5K_RF_GAIN(26), 0x00000028 },
+       { AR5K_RF_GAIN(27), 0x00000068 },
+       { AR5K_RF_GAIN(28), 0x0000001f },
+       { AR5K_RF_GAIN(29), 0x0000001e },
+       { AR5K_RF_GAIN(30), 0x00000018 },
+       { AR5K_RF_GAIN(31), 0x00000058 },
+       { AR5K_RF_GAIN(32), 0x00000098 },
+       { AR5K_RF_GAIN(33), 0x00000003 },
+       { AR5K_RF_GAIN(34), 0x00000004 },
+       { AR5K_RF_GAIN(35), 0x00000044 },
+       { AR5K_RF_GAIN(36), 0x00000084 },
+       { AR5K_RF_GAIN(37), 0x00000013 },
+       { AR5K_RF_GAIN(38), 0x00000012 },
+       { AR5K_RF_GAIN(39), 0x00000052 },
+       { AR5K_RF_GAIN(40), 0x00000092 },
+       { AR5K_RF_GAIN(41), 0x000000d2 },
+       { AR5K_RF_GAIN(42), 0x0000002b },
+       { AR5K_RF_GAIN(43), 0x0000002a },
+       { AR5K_RF_GAIN(44), 0x0000006a },
+       { AR5K_RF_GAIN(45), 0x000000aa },
+       { AR5K_RF_GAIN(46), 0x0000001b },
+       { AR5K_RF_GAIN(47), 0x0000001a },
+       { AR5K_RF_GAIN(48), 0x0000005a },
+       { AR5K_RF_GAIN(49), 0x0000009a },
+       { AR5K_RF_GAIN(50), 0x000000da },
+       { AR5K_RF_GAIN(51), 0x00000006 },
+       { AR5K_RF_GAIN(52), 0x00000006 },
+       { AR5K_RF_GAIN(53), 0x00000006 },
+       { AR5K_RF_GAIN(54), 0x00000006 },
+       { AR5K_RF_GAIN(55), 0x00000006 },
+       { AR5K_RF_GAIN(56), 0x00000006 },
+       { AR5K_RF_GAIN(57), 0x00000006 },
+       { AR5K_RF_GAIN(58), 0x00000006 },
+       { AR5K_RF_GAIN(59), 0x00000006 },
+       { AR5K_RF_GAIN(60), 0x00000006 },
+       { AR5K_RF_GAIN(61), 0x00000006 },
+       { AR5K_RF_GAIN(62), 0x00000006 },
+       { AR5K_RF_GAIN(63), 0x00000006 },
+       /* PHY activation */
+       { AR5K_PHY(53), 0x00000020 },
+       { AR5K_PHY(51), 0x00000004 },
+       { AR5K_PHY(50), 0x00060106 },
+       { AR5K_PHY(39), 0x0000006d },
+       { AR5K_PHY(48), 0x00000000 },
+       { AR5K_PHY(52), 0x00000014 },
+       { AR5K_PHY_ACT, AR5K_PHY_ACT_ENABLE },
+};
+
+/* Initial register settings for AR5211 */
+static const struct ath5k_ini ar5211_ini[] = {
+       { AR5K_RXDP,            0x00000000 },
+       { AR5K_RTSD0,           0x84849c9c },
+       { AR5K_RTSD1,           0x7c7c7c7c },
+       { AR5K_RXCFG,           0x00000005 },
+       { AR5K_MIBC,            0x00000000 },
+       { AR5K_TOPS,            0x00000008 },
+       { AR5K_RXNOFRM,         0x00000008 },
+       { AR5K_TXNOFRM,         0x00000010 },
+       { AR5K_RPGTO,           0x00000000 },
+       { AR5K_RFCNT,           0x0000001f },
+       { AR5K_QUEUE_TXDP(0),   0x00000000 },
+       { AR5K_QUEUE_TXDP(1),   0x00000000 },
+       { AR5K_QUEUE_TXDP(2),   0x00000000 },
+       { AR5K_QUEUE_TXDP(3),   0x00000000 },
+       { AR5K_QUEUE_TXDP(4),   0x00000000 },
+       { AR5K_QUEUE_TXDP(5),   0x00000000 },
+       { AR5K_QUEUE_TXDP(6),   0x00000000 },
+       { AR5K_QUEUE_TXDP(7),   0x00000000 },
+       { AR5K_QUEUE_TXDP(8),   0x00000000 },
+       { AR5K_QUEUE_TXDP(9),   0x00000000 },
+       { AR5K_DCU_FP,          0x00000000 },
+       { AR5K_STA_ID1,         0x00000000 },
+       { AR5K_BSS_ID0,         0x00000000 },
+       { AR5K_BSS_ID1,         0x00000000 },
+       { AR5K_RSSI_THR,        0x00000000 },
+       { AR5K_CFP_PERIOD_5211, 0x00000000 },
+       { AR5K_TIMER0_5211,     0x00000030 },
+       { AR5K_TIMER1_5211,     0x0007ffff },
+       { AR5K_TIMER2_5211,     0x01ffffff },
+       { AR5K_TIMER3_5211,     0x00000031 },
+       { AR5K_CFP_DUR_5211,    0x00000000 },
+       { AR5K_RX_FILTER_5211,  0x00000000 },
+       { AR5K_MCAST_FILTER0_5211, 0x00000000 },
+       { AR5K_MCAST_FILTER1_5211, 0x00000002 },
+       { AR5K_DIAG_SW_5211,    0x00000000 },
+       { AR5K_ADDAC_TEST,      0x00000000 },
+       { AR5K_DEFAULT_ANTENNA, 0x00000000 },
+       /* PHY registers */
+       { AR5K_PHY_AGC, 0x00000000 },
+       { AR5K_PHY(3),  0x2d849093 },
+       { AR5K_PHY(4),  0x7d32e000 },
+       { AR5K_PHY(5),  0x00000f6b },
+       { AR5K_PHY_ACT, 0x00000000 },
+       { AR5K_PHY(11), 0x00026ffe },
+       { AR5K_PHY(12), 0x00000000 },
+       { AR5K_PHY(15), 0x00020100 },
+       { AR5K_PHY(16), 0x206a017a },
+       { AR5K_PHY(19), 0x1284613c },
+       { AR5K_PHY(21), 0x00000859 },
+       { AR5K_PHY(26), 0x409a4190 },   /* 0x9868 */
+       { AR5K_PHY(27), 0x050cb081 },
+       { AR5K_PHY(28), 0x0000000f },
+       { AR5K_PHY(29), 0x00000080 },
+       { AR5K_PHY(30), 0x0000000c },
+       { AR5K_PHY(64), 0x00000000 },
+       { AR5K_PHY(65), 0x00000000 },
+       { AR5K_PHY(66), 0x00000000 },
+       { AR5K_PHY(67), 0x00800000 },
+       { AR5K_PHY(68), 0x00000001 },
+       { AR5K_PHY(71), 0x0000092a },
+       { AR5K_PHY_IQ,  0x00000000 },
+       { AR5K_PHY(73), 0x00058a05 },
+       { AR5K_PHY(74), 0x00000001 },
+       { AR5K_PHY(75), 0x00000000 },
+       { AR5K_PHY_PAPD_PROBE, 0x00000000 },
+       { AR5K_PHY(77), 0x00000000 },   /* 0x9934 */
+       { AR5K_PHY(78), 0x00000000 },   /* 0x9938 */
+       { AR5K_PHY(79), 0x0000003f },   /* 0x993c */
+       { AR5K_PHY(80), 0x00000004 },
+       { AR5K_PHY(82), 0x00000000 },
+       { AR5K_PHY(83), 0x00000000 },
+       { AR5K_PHY(84), 0x00000000 },
+       { AR5K_PHY_RADAR, 0x5d50f14c },
+       { AR5K_PHY(86), 0x00000018 },
+       { AR5K_PHY(87), 0x004b6a8e },
+       /* Initial Power table (32bytes)
+        * common on all cards/modes.
+        * Note: Table is rewritten during
+        * txpower setup later using calibration
+        * data etc. so next write is non-common */
+       { AR5K_PHY_PCDAC_TXPOWER(1), 0x06ff05ff },
+       { AR5K_PHY_PCDAC_TXPOWER(2), 0x07ff07ff },
+       { AR5K_PHY_PCDAC_TXPOWER(3), 0x08ff08ff },
+       { AR5K_PHY_PCDAC_TXPOWER(4), 0x09ff09ff },
+       { AR5K_PHY_PCDAC_TXPOWER(5), 0x0aff0aff },
+       { AR5K_PHY_PCDAC_TXPOWER(6), 0x0bff0bff },
+       { AR5K_PHY_PCDAC_TXPOWER(7), 0x0cff0cff },
+       { AR5K_PHY_PCDAC_TXPOWER(8), 0x0dff0dff },
+       { AR5K_PHY_PCDAC_TXPOWER(9), 0x0fff0eff },
+       { AR5K_PHY_PCDAC_TXPOWER(10), 0x12ff12ff },
+       { AR5K_PHY_PCDAC_TXPOWER(11), 0x14ff13ff },
+       { AR5K_PHY_PCDAC_TXPOWER(12), 0x16ff15ff },
+       { AR5K_PHY_PCDAC_TXPOWER(13), 0x19ff17ff },
+       { AR5K_PHY_PCDAC_TXPOWER(14), 0x1bff1aff },
+       { AR5K_PHY_PCDAC_TXPOWER(15), 0x1eff1dff },
+       { AR5K_PHY_PCDAC_TXPOWER(16), 0x23ff20ff },
+       { AR5K_PHY_PCDAC_TXPOWER(17), 0x27ff25ff },
+       { AR5K_PHY_PCDAC_TXPOWER(18), 0x2cff29ff },
+       { AR5K_PHY_PCDAC_TXPOWER(19), 0x31ff2fff },
+       { AR5K_PHY_PCDAC_TXPOWER(20), 0x37ff34ff },
+       { AR5K_PHY_PCDAC_TXPOWER(21), 0x3aff3aff },
+       { AR5K_PHY_PCDAC_TXPOWER(22), 0x3aff3aff },
+       { AR5K_PHY_PCDAC_TXPOWER(23), 0x3aff3aff },
+       { AR5K_PHY_PCDAC_TXPOWER(24), 0x3aff3aff },
+       { AR5K_PHY_PCDAC_TXPOWER(25), 0x3aff3aff },
+       { AR5K_PHY_PCDAC_TXPOWER(26), 0x3aff3aff },
+       { AR5K_PHY_PCDAC_TXPOWER(27), 0x3aff3aff },
+       { AR5K_PHY_PCDAC_TXPOWER(28), 0x3aff3aff },
+       { AR5K_PHY_PCDAC_TXPOWER(29), 0x3aff3aff },
+       { AR5K_PHY_PCDAC_TXPOWER(30), 0x3aff3aff },
+       { AR5K_PHY_PCDAC_TXPOWER(31), 0x3aff3aff },
+       { AR5K_PHY_CCKTXCTL, 0x00000000 },
+       { AR5K_PHY(642), 0x503e4646 },
+       { AR5K_PHY_GAIN_2GHZ, 0x6480416c },
+       { AR5K_PHY(644), 0x0199a003 },
+       { AR5K_PHY(645), 0x044cd610 },
+       { AR5K_PHY(646), 0x13800040 },
+       { AR5K_PHY(647), 0x1be00060 },
+       { AR5K_PHY(648), 0x0c53800a },
+       { AR5K_PHY(649), 0x0014df3b },
+       { AR5K_PHY(650), 0x000001b5 },
+       { AR5K_PHY(651), 0x00000020 },
+};
+
+/* Initial mode-specific settings for AR5211
+ * 5211 supports OFDM-only g (draft g) but we
+ * need to test it !
+ */
+static const struct ath5k_ini_mode ar5211_ini_mode[] = {
+       { AR5K_TXCFG,
+       /*        a         aTurbo        b       g (OFDM)    */
+          { 0x00000015, 0x00000015, 0x0000001d, 0x00000015 } },
+       { AR5K_QUEUE_DFS_LOCAL_IFS(0),
+          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
+       { AR5K_QUEUE_DFS_LOCAL_IFS(1),
+          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
+       { AR5K_QUEUE_DFS_LOCAL_IFS(2),
+          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
+       { AR5K_QUEUE_DFS_LOCAL_IFS(3),
+          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
+       { AR5K_QUEUE_DFS_LOCAL_IFS(4),
+          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
+       { AR5K_QUEUE_DFS_LOCAL_IFS(5),
+          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
+       { AR5K_QUEUE_DFS_LOCAL_IFS(6),
+          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
+       { AR5K_QUEUE_DFS_LOCAL_IFS(7),
+          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
+       { AR5K_QUEUE_DFS_LOCAL_IFS(8),
+          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
+       { AR5K_QUEUE_DFS_LOCAL_IFS(9),
+          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
+       { AR5K_DCU_GBL_IFS_SLOT,
+          { 0x00000168, 0x000001e0, 0x000001b8, 0x00000168 } },
+       { AR5K_DCU_GBL_IFS_SIFS,
+          { 0x00000230, 0x000001e0, 0x000000b0, 0x00000230 } },
+       { AR5K_DCU_GBL_IFS_EIFS,
+          { 0x00000d98, 0x00001180, 0x00001f48, 0x00000d98 } },
+       { AR5K_DCU_GBL_IFS_MISC,
+          { 0x0000a0e0, 0x00014068, 0x00005880, 0x0000a0e0 } },
+       { AR5K_TIME_OUT,
+          { 0x04000400, 0x08000800, 0x20003000, 0x04000400 } },
+       { AR5K_USEC_5211,
+          { 0x0e8d8fa7, 0x0e8d8fcf, 0x01608f95, 0x0e8d8fa7 } },
+       { AR5K_PHY_TURBO,
+          { 0x00000000, 0x00000003, 0x00000000, 0x00000000 } },
+       { AR5K_PHY(8),
+          { 0x02020200, 0x02020200, 0x02010200, 0x02020200 } },
+       { AR5K_PHY(9),
+          { 0x00000e0e, 0x00000e0e, 0x00000707, 0x00000e0e } },
+       { AR5K_PHY(10),
+          { 0x0a020001, 0x0a020001, 0x05010000, 0x0a020001 } },
+       { AR5K_PHY(13),
+          { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
+       { AR5K_PHY(14),
+          { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b } },
+       { AR5K_PHY(17),
+          { 0x1372169c, 0x137216a5, 0x137216a8, 0x1372169c } },
+       { AR5K_PHY(18),
+          { 0x0018ba67, 0x0018ba67, 0x0018ba69, 0x0018ba69 } },
+       { AR5K_PHY(20),
+          { 0x0c28b4e0, 0x0c28b4e0, 0x0c28b4e0, 0x0c28b4e0 } },
+       { AR5K_PHY_SIG,
+          { 0x7e800d2e, 0x7e800d2e, 0x7ec00d2e, 0x7e800d2e } },
+       { AR5K_PHY_AGCCOARSE,
+          { 0x31375d5e, 0x31375d5e, 0x313a5d5e, 0x31375d5e } },
+       { AR5K_PHY_AGCCTL,
+          { 0x0000bd10, 0x0000bd10, 0x0000bd38, 0x0000bd10 } },
+       { AR5K_PHY_NF,
+          { 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 } },
+       { AR5K_PHY_RX_DELAY,
+          { 0x00002710, 0x00002710, 0x0000157c, 0x00002710 } },
+       { AR5K_PHY(70),
+          { 0x00000190, 0x00000190, 0x00000084, 0x00000190 } },
+       { AR5K_PHY_FRAME_CTL_5211,
+          { 0x6fe01020, 0x6fe01020, 0x6fe00920, 0x6fe01020 } },
+       { AR5K_PHY_PCDAC_TXPOWER_BASE,
+          { 0x05ff14ff, 0x05ff14ff, 0x05ff14ff, 0x05ff19ff } },
+       { AR5K_RF_BUFFER_CONTROL_4,
+          { 0x00000010, 0x00000014, 0x00000010, 0x00000010 } },
+};
+
+/* Initial register settings for AR5212 */
+static const struct ath5k_ini ar5212_ini_common_start[] = {
+       { AR5K_RXDP,            0x00000000 },
+       { AR5K_RXCFG,           0x00000005 },
+       { AR5K_MIBC,            0x00000000 },
+       { AR5K_TOPS,            0x00000008 },
+       { AR5K_RXNOFRM,         0x00000008 },
+       { AR5K_TXNOFRM,         0x00000010 },
+       { AR5K_RPGTO,           0x00000000 },
+       { AR5K_RFCNT,           0x0000001f },
+       { AR5K_QUEUE_TXDP(0),   0x00000000 },
+       { AR5K_QUEUE_TXDP(1),   0x00000000 },
+       { AR5K_QUEUE_TXDP(2),   0x00000000 },
+       { AR5K_QUEUE_TXDP(3),   0x00000000 },
+       { AR5K_QUEUE_TXDP(4),   0x00000000 },
+       { AR5K_QUEUE_TXDP(5),   0x00000000 },
+       { AR5K_QUEUE_TXDP(6),   0x00000000 },
+       { AR5K_QUEUE_TXDP(7),   0x00000000 },
+       { AR5K_QUEUE_TXDP(8),   0x00000000 },
+       { AR5K_QUEUE_TXDP(9),   0x00000000 },
+       { AR5K_DCU_FP,          0x00000000 },
+       { AR5K_DCU_TXP,         0x00000000 },
+       /* Tx filter table 0 (32 entries) */
+       { AR5K_DCU_TX_FILTER_0(0),  0x00000000 }, /* DCU 0 */
+       { AR5K_DCU_TX_FILTER_0(1),  0x00000000 },
+       { AR5K_DCU_TX_FILTER_0(2),  0x00000000 },
+       { AR5K_DCU_TX_FILTER_0(3),  0x00000000 },
+       { AR5K_DCU_TX_FILTER_0(4),  0x00000000 }, /* DCU 1 */
+       { AR5K_DCU_TX_FILTER_0(5),  0x00000000 },
+       { AR5K_DCU_TX_FILTER_0(6),  0x00000000 },
+       { AR5K_DCU_TX_FILTER_0(7),  0x00000000 },
+       { AR5K_DCU_TX_FILTER_0(8),  0x00000000 }, /* DCU 2 */
+       { AR5K_DCU_TX_FILTER_0(9),  0x00000000 },
+       { AR5K_DCU_TX_FILTER_0(10), 0x00000000 },
+       { AR5K_DCU_TX_FILTER_0(11), 0x00000000 },
+       { AR5K_DCU_TX_FILTER_0(12), 0x00000000 }, /* DCU 3 */
+       { AR5K_DCU_TX_FILTER_0(13), 0x00000000 },
+       { AR5K_DCU_TX_FILTER_0(14), 0x00000000 },
+       { AR5K_DCU_TX_FILTER_0(15), 0x00000000 },
+       { AR5K_DCU_TX_FILTER_0(16), 0x00000000 }, /* DCU 4 */
+       { AR5K_DCU_TX_FILTER_0(17), 0x00000000 },
+       { AR5K_DCU_TX_FILTER_0(18), 0x00000000 },
+       { AR5K_DCU_TX_FILTER_0(19), 0x00000000 },
+       { AR5K_DCU_TX_FILTER_0(20), 0x00000000 }, /* DCU 5 */
+       { AR5K_DCU_TX_FILTER_0(21), 0x00000000 },
+       { AR5K_DCU_TX_FILTER_0(22), 0x00000000 },
+       { AR5K_DCU_TX_FILTER_0(23), 0x00000000 },
+       { AR5K_DCU_TX_FILTER_0(24), 0x00000000 }, /* DCU 6 */
+       { AR5K_DCU_TX_FILTER_0(25), 0x00000000 },
+       { AR5K_DCU_TX_FILTER_0(26), 0x00000000 },
+       { AR5K_DCU_TX_FILTER_0(27), 0x00000000 },
+       { AR5K_DCU_TX_FILTER_0(28), 0x00000000 }, /* DCU 7 */
+       { AR5K_DCU_TX_FILTER_0(29), 0x00000000 },
+       { AR5K_DCU_TX_FILTER_0(30), 0x00000000 },
+       { AR5K_DCU_TX_FILTER_0(31), 0x00000000 },
+       /* Tx filter table 1 (16 entries) */
+       { AR5K_DCU_TX_FILTER_1(0),  0x00000000 },
+       { AR5K_DCU_TX_FILTER_1(1),  0x00000000 },
+       { AR5K_DCU_TX_FILTER_1(2),  0x00000000 },
+       { AR5K_DCU_TX_FILTER_1(3),  0x00000000 },
+       { AR5K_DCU_TX_FILTER_1(4),  0x00000000 },
+       { AR5K_DCU_TX_FILTER_1(5),  0x00000000 },
+       { AR5K_DCU_TX_FILTER_1(6),  0x00000000 },
+       { AR5K_DCU_TX_FILTER_1(7),  0x00000000 },
+       { AR5K_DCU_TX_FILTER_1(8),  0x00000000 },
+       { AR5K_DCU_TX_FILTER_1(9),  0x00000000 },
+       { AR5K_DCU_TX_FILTER_1(10), 0x00000000 },
+       { AR5K_DCU_TX_FILTER_1(11), 0x00000000 },
+       { AR5K_DCU_TX_FILTER_1(12), 0x00000000 },
+       { AR5K_DCU_TX_FILTER_1(13), 0x00000000 },
+       { AR5K_DCU_TX_FILTER_1(14), 0x00000000 },
+       { AR5K_DCU_TX_FILTER_1(15), 0x00000000 },
+       { AR5K_DCU_TX_FILTER_CLR, 0x00000000 },
+       { AR5K_DCU_TX_FILTER_SET, 0x00000000 },
+       { AR5K_STA_ID1,         0x00000000 },
+       { AR5K_BSS_ID0,         0x00000000 },
+       { AR5K_BSS_ID1,         0x00000000 },
+       { AR5K_BEACON_5211,     0x00000000 },
+       { AR5K_CFP_PERIOD_5211, 0x00000000 },
+       { AR5K_TIMER0_5211,     0x00000030 },
+       { AR5K_TIMER1_5211,     0x0007ffff },
+       { AR5K_TIMER2_5211,     0x01ffffff },
+       { AR5K_TIMER3_5211,     0x00000031 },
+       { AR5K_CFP_DUR_5211,    0x00000000 },
+       { AR5K_RX_FILTER_5211,  0x00000000 },
+       { AR5K_DIAG_SW_5211,    0x00000000 },
+       { AR5K_ADDAC_TEST,      0x00000000 },
+       { AR5K_DEFAULT_ANTENNA, 0x00000000 },
+       { AR5K_FRAME_CTL_QOSM,  0x000fc78f },
+       { AR5K_XRMODE,          0x2a82301a },
+       { AR5K_XRDELAY,         0x05dc01e0 },
+       { AR5K_XRTIMEOUT,       0x1f402710 },
+       { AR5K_XRCHIRP,         0x01f40000 },
+       { AR5K_XRSTOMP,         0x00001e1c },
+       { AR5K_SLEEP0,          0x0002aaaa },
+       { AR5K_SLEEP1,          0x02005555 },
+       { AR5K_SLEEP2,          0x00000000 },
+       { AR5K_BSS_IDM0,        0xffffffff },
+       { AR5K_BSS_IDM1,        0x0000ffff },
+       { AR5K_TXPC,            0x00000000 },
+       { AR5K_PROFCNT_TX,      0x00000000 },
+       { AR5K_PROFCNT_RX,      0x00000000 },
+       { AR5K_PROFCNT_RXCLR,   0x00000000 },
+       { AR5K_PROFCNT_CYCLE,   0x00000000 },
+       { AR5K_QUIET_CTL1,      0x00000088 },
+       /* Initial rate duration table (32 entries )*/
+       { AR5K_RATE_DUR(0),     0x00000000 },
+       { AR5K_RATE_DUR(1),     0x0000008c },
+       { AR5K_RATE_DUR(2),     0x000000e4 },
+       { AR5K_RATE_DUR(3),     0x000002d5 },
+       { AR5K_RATE_DUR(4),     0x00000000 },
+       { AR5K_RATE_DUR(5),     0x00000000 },
+       { AR5K_RATE_DUR(6),     0x000000a0 },
+       { AR5K_RATE_DUR(7),     0x000001c9 },
+       { AR5K_RATE_DUR(8),     0x0000002c },
+       { AR5K_RATE_DUR(9),     0x0000002c },
+       { AR5K_RATE_DUR(10),    0x00000030 },
+       { AR5K_RATE_DUR(11),    0x0000003c },
+       { AR5K_RATE_DUR(12),    0x0000002c },
+       { AR5K_RATE_DUR(13),    0x0000002c },
+       { AR5K_RATE_DUR(14),    0x00000030 },
+       { AR5K_RATE_DUR(15),    0x0000003c },
+       { AR5K_RATE_DUR(16),    0x00000000 },
+       { AR5K_RATE_DUR(17),    0x00000000 },
+       { AR5K_RATE_DUR(18),    0x00000000 },
+       { AR5K_RATE_DUR(19),    0x00000000 },
+       { AR5K_RATE_DUR(20),    0x00000000 },
+       { AR5K_RATE_DUR(21),    0x00000000 },
+       { AR5K_RATE_DUR(22),    0x00000000 },
+       { AR5K_RATE_DUR(23),    0x00000000 },
+       { AR5K_RATE_DUR(24),    0x000000d5 },
+       { AR5K_RATE_DUR(25),    0x000000df },
+       { AR5K_RATE_DUR(26),    0x00000102 },
+       { AR5K_RATE_DUR(27),    0x0000013a },
+       { AR5K_RATE_DUR(28),    0x00000075 },
+       { AR5K_RATE_DUR(29),    0x0000007f },
+       { AR5K_RATE_DUR(30),    0x000000a2 },
+       { AR5K_RATE_DUR(31),    0x00000000 },
+       { AR5K_QUIET_CTL2,      0x00010002 },
+       { AR5K_TSF_PARM,        0x00000001 },
+       { AR5K_QOS_NOACK,       0x000000c0 },
+       { AR5K_PHY_ERR_FIL,     0x00000000 },
+       { AR5K_XRLAT_TX,        0x00000168 },
+       { AR5K_ACKSIFS,         0x00000000 },
+       /* Rate -> db table
+        * notice ...03<-02<-01<-00 ! */
+       { AR5K_RATE2DB(0),      0x03020100 },
+       { AR5K_RATE2DB(1),      0x07060504 },
+       { AR5K_RATE2DB(2),      0x0b0a0908 },
+       { AR5K_RATE2DB(3),      0x0f0e0d0c },
+       { AR5K_RATE2DB(4),      0x13121110 },
+       { AR5K_RATE2DB(5),      0x17161514 },
+       { AR5K_RATE2DB(6),      0x1b1a1918 },
+       { AR5K_RATE2DB(7),      0x1f1e1d1c },
+       /* Db -> Rate table */
+       { AR5K_DB2RATE(0),      0x03020100 },
+       { AR5K_DB2RATE(1),      0x07060504 },
+       { AR5K_DB2RATE(2),      0x0b0a0908 },
+       { AR5K_DB2RATE(3),      0x0f0e0d0c },
+       { AR5K_DB2RATE(4),      0x13121110 },
+       { AR5K_DB2RATE(5),      0x17161514 },
+       { AR5K_DB2RATE(6),      0x1b1a1918 },
+       { AR5K_DB2RATE(7),      0x1f1e1d1c },
+       /* PHY registers (Common settings
+        * for all chips/modes) */
+       { AR5K_PHY(3),          0xad848e19 },
+       { AR5K_PHY(4),          0x7d28e000 },
+       { AR5K_PHY_TIMING_3,    0x9c0a9f6b },
+       { AR5K_PHY_ACT,         0x00000000 },
+       { AR5K_PHY(16),         0x206a017a },
+       { AR5K_PHY(21),         0x00000859 },
+       { AR5K_PHY_BIN_MASK_1,  0x00000000 },
+       { AR5K_PHY_BIN_MASK_2,  0x00000000 },
+       { AR5K_PHY_BIN_MASK_3,  0x00000000 },
+       { AR5K_PHY_BIN_MASK_CTL, 0x00800000 },
+       { AR5K_PHY_ANT_CTL,     0x00000001 },
+       /*{ AR5K_PHY(71), 0x0000092a },*/ /* Old value */
+       { AR5K_PHY_MAX_RX_LEN,  0x00000c80 },
+       { AR5K_PHY_IQ,          0x05100000 },
+       { AR5K_PHY_WARM_RESET,  0x00000001 },
+       { AR5K_PHY_CTL,         0x00000004 },
+       { AR5K_PHY_TXPOWER_RATE1, 0x1e1f2022 },
+       { AR5K_PHY_TXPOWER_RATE2, 0x0a0b0c0d },
+       { AR5K_PHY_TXPOWER_RATE_MAX, 0x0000003f },
+       { AR5K_PHY(82),         0x9280b212 },
+       { AR5K_PHY_RADAR,       0x5d50e188 },
+       /*{ AR5K_PHY(86), 0x000000ff },*/
+       { AR5K_PHY(87),         0x004b6a8e },
+       { AR5K_PHY_NFTHRES,     0x000003ce },
+       { AR5K_PHY_RESTART,     0x192fb515 },
+       { AR5K_PHY(94),         0x00000001 },
+       { AR5K_PHY_RFBUS_REQ,   0x00000000 },
+       /*{ AR5K_PHY(644), 0x0080a333 },*/ /* Old value */
+       /*{ AR5K_PHY(645), 0x00206c10 },*/ /* Old value */
+       { AR5K_PHY(644),        0x00806333 },
+       { AR5K_PHY(645),        0x00106c10 },
+       { AR5K_PHY(646),        0x009c4060 },
+       /* { AR5K_PHY(647), 0x1483800a }, */
+       /* { AR5K_PHY(648), 0x01831061 }, */ /* Old value */
+       { AR5K_PHY(648),        0x018830c6 },
+       { AR5K_PHY(649),        0x00000400 },
+       /*{ AR5K_PHY(650), 0x000001b5 },*/
+       { AR5K_PHY(651),        0x00000000 },
+       { AR5K_PHY_TXPOWER_RATE3, 0x20202020 },
+       { AR5K_PHY_TXPOWER_RATE4, 0x20202020 },
+       /*{ AR5K_PHY(655), 0x13c889af },*/
+       { AR5K_PHY(656),        0x38490a20 },
+       { AR5K_PHY(657),        0x00007bb6 },
+       { AR5K_PHY(658),        0x0fff3ffc },
+};
+
+/* Initial mode-specific settings for AR5212 (Written before ar5212_ini) */
+static const struct ath5k_ini_mode ar5212_ini_mode_start[] = {
+       { AR5K_QUEUE_DFS_LOCAL_IFS(0),
+       /*      a/XR       aTurbo         b        g (DYN)     gTurbo     */
+          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+       { AR5K_QUEUE_DFS_LOCAL_IFS(1),
+          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+       { AR5K_QUEUE_DFS_LOCAL_IFS(2),
+          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+       { AR5K_QUEUE_DFS_LOCAL_IFS(3),
+          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+       { AR5K_QUEUE_DFS_LOCAL_IFS(4),
+          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+       { AR5K_QUEUE_DFS_LOCAL_IFS(5),
+          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+       { AR5K_QUEUE_DFS_LOCAL_IFS(6),
+          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+       { AR5K_QUEUE_DFS_LOCAL_IFS(7),
+          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+       { AR5K_QUEUE_DFS_LOCAL_IFS(8),
+          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+       { AR5K_QUEUE_DFS_LOCAL_IFS(9),
+          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
+       { AR5K_DCU_GBL_IFS_SIFS,
+          { 0x00000230, 0x000001e0, 0x000000b0, 0x00000160, 0x000001e0 } },
+       { AR5K_DCU_GBL_IFS_SLOT,
+          { 0x00000168, 0x000001e0, 0x000001b8, 0x0000018c, 0x000001e0 } },
+       { AR5K_DCU_GBL_IFS_EIFS,
+          { 0x00000e60, 0x00001180, 0x00001f1c, 0x00003e38, 0x00001180 } },
+       { AR5K_DCU_GBL_IFS_MISC,
+          { 0x0000a0e0, 0x00014068, 0x00005880, 0x0000b0e0, 0x00014068 } },
+       { AR5K_TIME_OUT,
+          { 0x03e803e8, 0x06e006e0, 0x04200420, 0x08400840, 0x06e006e0 } },
+       { AR5K_PHY_TURBO,
+          { 0x00000000, 0x00000003, 0x00000000, 0x00000000, 0x00000003 } },
+       { AR5K_PHY(8),
+          { 0x02020200, 0x02020200, 0x02010200, 0x02020200, 0x02020200 } },
+       { AR5K_PHY_RF_CTL2,
+          { 0x00000e0e, 0x00000e0e, 0x00000707, 0x00000e0e, 0x00000e0e } },
+       { AR5K_PHY_SETTLING,
+          { 0x1372161c, 0x13721c25, 0x13721722, 0x137216a2, 0x13721c25 } },
+       { AR5K_PHY_AGCCTL,
+          { 0x00009d10, 0x00009d10, 0x00009d18, 0x00009d18, 0x00009d10 } },
+       { AR5K_PHY_NF,
+          { 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 } },
+       { AR5K_PHY_WEAK_OFDM_HIGH_THR,
+          { 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190 } },
+       { AR5K_PHY(70),
+          { 0x000001b8, 0x000001b8, 0x00000084, 0x00000108, 0x000001b8 } },
+       { AR5K_PHY_OFDM_SELFCORR,
+          { 0x10058a05, 0x10058a05, 0x10058a05, 0x10058a05, 0x10058a05 } },
+       { 0xa230,
+          { 0x00000000, 0x00000000, 0x00000000, 0x00000108, 0x00000000 } },
+};
+
+/* Initial mode-specific settings for AR5212 + RF5111 (Written after ar5212_ini) */
+static const struct ath5k_ini_mode rf5111_ini_mode_end[] = {
+       { AR5K_TXCFG,
+       /*      a/XR       aTurbo         b        g (DYN)     gTurbo     */
+          { 0x00008015, 0x00008015, 0x00008015, 0x00008015, 0x00008015 } },
+       { AR5K_USEC_5211,
+          { 0x128d8fa7, 0x09880fcf, 0x04e00f95, 0x12e00fab, 0x09880fcf } },
+       { AR5K_PHY_RF_CTL3,
+          { 0x0a020001, 0x0a020001, 0x05010100, 0x0a020001, 0x0a020001 } },
+       { AR5K_PHY_RF_CTL4,
+          { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
+       { AR5K_PHY_PA_CTL,
+          { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b, 0x0000000b } },
+       { AR5K_PHY_GAIN,
+          { 0x0018da5a, 0x0018da5a, 0x0018ca69, 0x0018ca69, 0x0018ca69 } },
+       { AR5K_PHY_DESIRED_SIZE,
+          { 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0 } },
+       { AR5K_PHY_SIG,
+          { 0x7e800d2e, 0x7e800d2e, 0x7ee84d2e, 0x7ee84d2e, 0x7e800d2e } },
+       { AR5K_PHY_AGCCOARSE,
+          { 0x3137665e, 0x3137665e, 0x3137665e, 0x3137665e, 0x3137615e } },
+       { AR5K_PHY_WEAK_OFDM_LOW_THR,
+          { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb080, 0x050cb080 } },
+       { AR5K_PHY_RX_DELAY,
+          { 0x00002710, 0x00002710, 0x0000157c, 0x00002af8, 0x00002710 } },
+       { AR5K_PHY_FRAME_CTL_5211,
+          { 0xf7b81020, 0xf7b81020, 0xf7b80d20, 0xf7b81020, 0xf7b81020 } },
+       { AR5K_PHY_GAIN_2GHZ,
+          { 0x642c416a, 0x642c416a, 0x6440416a, 0x6440416a, 0x6440416a } },
+       { AR5K_PHY_CCK_RX_CTL_4,
+          { 0x1883800a, 0x1883800a, 0x1873800a, 0x1883800a, 0x1883800a } },
+};
+
+static const struct ath5k_ini rf5111_ini_common_end[] = {
+       { AR5K_DCU_FP,          0x00000000 },
+       { AR5K_PHY_AGC,         0x00000000 },
+       { AR5K_PHY_ADC_CTL,     0x00022ffe },
+       { 0x983c,               0x00020100 },
+       { AR5K_PHY_GAIN_OFFSET, 0x1284613c },
+       { AR5K_PHY_PAPD_PROBE,  0x00004883 },
+       { 0x9940,               0x00000004 },
+       { 0x9958,               0x000000ff },
+       { 0x9974,               0x00000000 },
+       { AR5K_PHY_SPENDING,    0x00000018 },
+       { AR5K_PHY_CCKTXCTL,    0x00000000 },
+       { AR5K_PHY_CCK_CROSSCORR, 0xd03e6788 },
+       { AR5K_PHY_DAG_CCK_CTL, 0x000001b5 },
+       { 0xa23c,               0x13c889af },
+};
+
+/* Initial mode-specific settings for AR5212 + RF5112 (Written after ar5212_ini) */
+static const struct ath5k_ini_mode rf5112_ini_mode_end[] = {
+       { AR5K_TXCFG,
+       /*      a/XR       aTurbo         b        g (DYN)     gTurbo     */
+          { 0x00008015, 0x00008015, 0x00008015, 0x00008015, 0x00008015 } },
+       { AR5K_USEC_5211,
+          { 0x128d93a7, 0x098813cf, 0x04e01395, 0x12e013ab, 0x098813cf } },
+       { AR5K_PHY_RF_CTL3,
+          { 0x0a020001, 0x0a020001, 0x05020100, 0x0a020001, 0x0a020001 } },
+       { AR5K_PHY_RF_CTL4,
+          { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
+       { AR5K_PHY_PA_CTL,
+          { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b, 0x0000000b } },
+       { AR5K_PHY_GAIN,
+          { 0x0018da6d, 0x0018da6d, 0x0018ca75, 0x0018ca75, 0x0018ca75 } },
+       { AR5K_PHY_DESIRED_SIZE,
+          { 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0 } },
+       { AR5K_PHY_SIG,
+          { 0x7e800d2e, 0x7e800d2e, 0x7ee80d2e, 0x7ee80d2e, 0x7e800d2e } },
+       { AR5K_PHY_AGCCOARSE,
+          { 0x3137665e, 0x3137665e, 0x3137665e, 0x3137665e, 0x3137665e } },
+       { AR5K_PHY_WEAK_OFDM_LOW_THR,
+          { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 } },
+       { AR5K_PHY_RX_DELAY,
+          { 0x000007d0, 0x000007d0, 0x0000044c, 0x00000898, 0x000007d0 } },
+       { AR5K_PHY_FRAME_CTL_5211,
+          { 0xf7b81020, 0xf7b81020, 0xf7b80d10, 0xf7b81010, 0xf7b81010 } },
+       { AR5K_PHY_CCKTXCTL,
+          { 0x00000000, 0x00000000, 0x00000008, 0x00000008, 0x00000008 } },
+       { AR5K_PHY_CCK_CROSSCORR,
+          { 0xd6be6788, 0xd6be6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } },
+       { AR5K_PHY_GAIN_2GHZ,
+          { 0x642c0140, 0x642c0140, 0x6442c160, 0x6442c160, 0x6442c160 } },
+       { AR5K_PHY_CCK_RX_CTL_4,
+          { 0x1883800a, 0x1883800a, 0x1873800a, 0x1883800a, 0x1883800a } },
+};
+
+static const struct ath5k_ini rf5112_ini_common_end[] = {
+       { AR5K_DCU_FP,          0x00000000 },
+       { AR5K_PHY_AGC,         0x00000000 },
+       { AR5K_PHY_ADC_CTL,     0x00022ffe },
+       { 0x983c,               0x00020100 },
+       { AR5K_PHY_GAIN_OFFSET, 0x1284613c },
+       { AR5K_PHY_PAPD_PROBE,  0x00004882 },
+       { 0x9940,               0x00000004 },
+       { 0x9958,               0x000000ff },
+       { 0x9974,               0x00000000 },
+       { AR5K_PHY_DAG_CCK_CTL, 0x000001b5 },
+       { 0xa23c,               0x13c889af },
+};
+
+/* Initial mode-specific settings for RF5413/5414 (Written after ar5212_ini) */
+static const struct ath5k_ini_mode rf5413_ini_mode_end[] = {
+       { AR5K_TXCFG,
+       /*      a/XR       aTurbo         b        g (DYN)     gTurbo     */
+          { 0x00000015, 0x00000015, 0x00000015, 0x00000015, 0x00000015 } },
+       { AR5K_USEC_5211,
+          { 0x128d93a7, 0x098813cf, 0x04e01395, 0x12e013ab, 0x098813cf } },
+       { AR5K_PHY_RF_CTL3,
+          { 0x0a020001, 0x0a020001, 0x05020100, 0x0a020001, 0x0a020001 } },
+       { AR5K_PHY_RF_CTL4,
+          { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
+       { AR5K_PHY_PA_CTL,
+          { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b, 0x0000000b } },
+       { AR5K_PHY_GAIN,
+          { 0x0018fa61, 0x0018fa61, 0x001a1a63, 0x001a1a63, 0x001a1a63 } },
+       { AR5K_PHY_DESIRED_SIZE,
+          { 0x0c98b4e0, 0x0c98b4e0, 0x0c98b0da, 0x0c98b0da, 0x0c98b0da } },
+       { AR5K_PHY_SIG,
+          { 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e } },
+       { AR5K_PHY_AGCCOARSE,
+          { 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e } },
+       { AR5K_PHY_WEAK_OFDM_LOW_THR,
+          { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 } },
+       { AR5K_PHY_RX_DELAY,
+          { 0x000007d0, 0x000007d0, 0x0000044c, 0x00000898, 0x000007d0 } },
+       { AR5K_PHY_FRAME_CTL_5211,
+          { 0xf7b81000, 0xf7b81000, 0xf7b80d00, 0xf7b81000, 0xf7b81000 } },
+       { AR5K_PHY_CCKTXCTL,
+          { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { AR5K_PHY_CCK_CROSSCORR,
+          { 0xd6be6788, 0xd6be6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } },
+       { AR5K_PHY_GAIN_2GHZ,
+          { 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 } },
+       { AR5K_PHY_CCK_RX_CTL_4,
+          { 0x1883800a, 0x1883800a, 0x1863800a, 0x1883800a, 0x1883800a } },
+       { 0xa300,
+          { 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000 } },
+       { 0xa304,
+          { 0x30032602, 0x30032602, 0x30032602, 0x30032602, 0x30032602 } },
+       { 0xa308,
+          { 0x48073e06, 0x48073e06, 0x48073e06, 0x48073e06, 0x48073e06 } },
+       { 0xa30c,
+          { 0x560b4c0a, 0x560b4c0a, 0x560b4c0a, 0x560b4c0a, 0x560b4c0a } },
+       { 0xa310,
+          { 0x641a600f, 0x641a600f, 0x641a600f, 0x641a600f, 0x641a600f } },
+       { 0xa314,
+          { 0x784f6e1b, 0x784f6e1b, 0x784f6e1b, 0x784f6e1b, 0x784f6e1b } },
+       { 0xa318,
+          { 0x868f7c5a, 0x868f7c5a, 0x868f7c5a, 0x868f7c5a, 0x868f7c5a } },
+       { 0xa31c,
+          { 0x90cf865b, 0x90cf865b, 0x8ecf865b, 0x8ecf865b, 0x8ecf865b } },
+       { 0xa320,
+          { 0x9d4f970f, 0x9d4f970f, 0x9b4f970f, 0x9b4f970f, 0x9b4f970f } },
+       { 0xa324,
+          { 0xa7cfa38f, 0xa7cfa38f, 0xa3cf9f8f, 0xa3cf9f8f, 0xa3cf9f8f } },
+       { 0xa328,
+          { 0xb55faf1f, 0xb55faf1f, 0xb35faf1f, 0xb35faf1f, 0xb35faf1f } },
+       { 0xa32c,
+          { 0xbddfb99f, 0xbddfb99f, 0xbbdfb99f, 0xbbdfb99f, 0xbbdfb99f } },
+       { 0xa330,
+          { 0xcb7fc53f, 0xcb7fc53f, 0xcb7fc73f, 0xcb7fc73f, 0xcb7fc73f } },
+       { 0xa334,
+          { 0xd5ffd1bf, 0xd5ffd1bf, 0xd3ffd1bf, 0xd3ffd1bf, 0xd3ffd1bf } },
+};
+
+static const struct ath5k_ini rf5413_ini_common_end[] = {
+       { AR5K_DCU_FP,          0x000003e0 },
+       { AR5K_5414_CBCFG,      0x00000010 },
+       { AR5K_SEQ_MASK,        0x0000000f },
+       { 0x809c,               0x00000000 },
+       { 0x80a0,               0x00000000 },
+       { AR5K_MIC_QOS_CTL,     0x00000000 },
+       { AR5K_MIC_QOS_SEL,     0x00000000 },
+       { AR5K_MISC_MODE,       0x00000000 },
+       { AR5K_OFDM_FIL_CNT,    0x00000000 },
+       { AR5K_CCK_FIL_CNT,     0x00000000 },
+       { AR5K_PHYERR_CNT1,     0x00000000 },
+       { AR5K_PHYERR_CNT1_MASK, 0x00000000 },
+       { AR5K_PHYERR_CNT2,     0x00000000 },
+       { AR5K_PHYERR_CNT2_MASK, 0x00000000 },
+       { AR5K_TSF_THRES,       0x00000000 },
+       { 0x8140,               0x800003f9 },
+       { 0x8144,               0x00000000 },
+       { AR5K_PHY_AGC,         0x00000000 },
+       { AR5K_PHY_ADC_CTL,     0x0000a000 },
+       { 0x983c,               0x00200400 },
+       { AR5K_PHY_GAIN_OFFSET, 0x1284233c },
+       { AR5K_PHY_SCR,         0x0000001f },
+       { AR5K_PHY_SLMT,        0x00000080 },
+       { AR5K_PHY_SCAL,        0x0000000e },
+       { 0x9958,               0x00081fff },
+       { AR5K_PHY_TIMING_7,    0x00000000 },
+       { AR5K_PHY_TIMING_8,    0x02800000 },
+       { AR5K_PHY_TIMING_11,   0x00000000 },
+       { AR5K_PHY_HEAVY_CLIP_ENABLE, 0x00000000 },
+       { 0x99e4,               0xaaaaaaaa },
+       { 0x99e8,               0x3c466478 },
+       { 0x99ec,               0x000000aa },
+       { AR5K_PHY_SCLOCK,      0x0000000c },
+       { AR5K_PHY_SDELAY,      0x000000ff },
+       { AR5K_PHY_SPENDING,    0x00000014 },
+       { AR5K_PHY_DAG_CCK_CTL, 0x000009b5 },
+       { 0xa23c,               0x93c889af },
+       { AR5K_PHY_FAST_ADC,    0x00000001 },
+       { 0xa250,               0x0000a000 },
+       { AR5K_PHY_BLUETOOTH,   0x00000000 },
+       { AR5K_PHY_TPC_RG1,     0x0cc75380 },
+       { 0xa25c,               0x0f0f0f01 },
+       { 0xa260,               0x5f690f01 },
+       { 0xa264,               0x00418a11 },
+       { 0xa268,               0x00000000 },
+       { AR5K_PHY_TPC_RG5,     0x0c30c16a },
+       { 0xa270, 0x00820820 },
+       { 0xa274, 0x081b7caa },
+       { 0xa278, 0x1ce739ce },
+       { 0xa27c, 0x051701ce },
+       { 0xa338, 0x00000000 },
+       { 0xa33c, 0x00000000 },
+       { 0xa340, 0x00000000 },
+       { 0xa344, 0x00000000 },
+       { 0xa348, 0x3fffffff },
+       { 0xa34c, 0x3fffffff },
+       { 0xa350, 0x3fffffff },
+       { 0xa354, 0x0003ffff },
+       { 0xa358, 0x79a8aa1f },
+       { 0xa35c, 0x066c420f },
+       { 0xa360, 0x0f282207 },
+       { 0xa364, 0x17601685 },
+       { 0xa368, 0x1f801104 },
+       { 0xa36c, 0x37a00c03 },
+       { 0xa370, 0x3fc40883 },
+       { 0xa374, 0x57c00803 },
+       { 0xa378, 0x5fd80682 },
+       { 0xa37c, 0x7fe00482 },
+       { 0xa380, 0x7f3c7bba },
+       { 0xa384, 0xf3307ff0 },
+};
+
+/* Initial mode-specific settings for RF2413/2414 (Written after ar5212_ini) */
+/* XXX: a mode ? */
+static const struct ath5k_ini_mode rf2413_ini_mode_end[] = {
+       { AR5K_TXCFG,
+       /*      a/XR       aTurbo         b        g (DYN)     gTurbo     */
+          { 0x00000015, 0x00000015, 0x00000015, 0x00000015, 0x00000015 } },
+       { AR5K_USEC_5211,
+          { 0x128d93a7, 0x098813cf, 0x04e01395, 0x12e013ab, 0x098813cf } },
+       { AR5K_PHY_RF_CTL3,
+          { 0x0a020001, 0x0a020001, 0x05020000, 0x0a020001, 0x0a020001 } },
+       { AR5K_PHY_RF_CTL4,
+          { 0x00000e00, 0x00000e00, 0x00000e00, 0x00000e00, 0x00000e00 } },
+       { AR5K_PHY_PA_CTL,
+          { 0x00000002, 0x00000002, 0x0000000a, 0x0000000a, 0x0000000a } },
+       { AR5K_PHY_GAIN,
+          { 0x0018da6d, 0x0018da6d, 0x001a6a64, 0x001a6a64, 0x001a6a64 } },
+       { AR5K_PHY_DESIRED_SIZE,
+          { 0x0de8b4e0, 0x0de8b4e0, 0x0de8b0da, 0x0c98b0da, 0x0de8b0da } },
+       { AR5K_PHY_SIG,
+          { 0x7e800d2e, 0x7e800d2e, 0x7ee80d2e, 0x7ec80d2e, 0x7e800d2e } },
+       { AR5K_PHY_AGCCOARSE,
+          { 0x3137665e, 0x3137665e, 0x3137665e, 0x3139605e, 0x3137665e } },
+       { AR5K_PHY_WEAK_OFDM_LOW_THR,
+          { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 } },
+       { AR5K_PHY_RX_DELAY,
+          { 0x000007d0, 0x000007d0, 0x0000044c, 0x00000898, 0x000007d0 } },
+       { AR5K_PHY_FRAME_CTL_5211,
+          { 0xf7b81000, 0xf7b81000, 0xf7b80d00, 0xf7b81000, 0xf7b81000 } },
+       { AR5K_PHY_CCKTXCTL,
+          { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { AR5K_PHY_CCK_CROSSCORR,
+          { 0xd6be6788, 0xd6be6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } },
+       { AR5K_PHY_GAIN_2GHZ,
+          { 0x002c0140, 0x002c0140, 0x0042c140, 0x0042c140, 0x0042c140 } },
+       { AR5K_PHY_CCK_RX_CTL_4,
+          { 0x1883800a, 0x1883800a, 0x1863800a, 0x1883800a, 0x1883800a } },
+};
+
+static const struct ath5k_ini rf2413_ini_common_end[] = {
+       { AR5K_DCU_FP,          0x000003e0 },
+       { AR5K_SEQ_MASK,        0x0000000f },
+       { AR5K_MIC_QOS_CTL,     0x00000000 },
+       { AR5K_MIC_QOS_SEL,     0x00000000 },
+       { AR5K_MISC_MODE,       0x00000000 },
+       { AR5K_OFDM_FIL_CNT,    0x00000000 },
+       { AR5K_CCK_FIL_CNT,     0x00000000 },
+       { AR5K_PHYERR_CNT1,     0x00000000 },
+       { AR5K_PHYERR_CNT1_MASK, 0x00000000 },
+       { AR5K_PHYERR_CNT2,     0x00000000 },
+       { AR5K_PHYERR_CNT2_MASK, 0x00000000 },
+       { AR5K_TSF_THRES,       0x00000000 },
+       { 0x8140,               0x800000a8 },
+       { 0x8144,               0x00000000 },
+       { AR5K_PHY_AGC,         0x00000000 },
+       { AR5K_PHY_ADC_CTL,     0x0000a000 },
+       { 0x983c,               0x00200400 },
+       { AR5K_PHY_GAIN_OFFSET, 0x1284233c },
+       { AR5K_PHY_SCR,         0x0000001f },
+       { AR5K_PHY_SLMT,        0x00000080 },
+       { AR5K_PHY_SCAL,        0x0000000e },
+       { 0x9958,               0x000000ff },
+       { AR5K_PHY_TIMING_7,    0x00000000 },
+       { AR5K_PHY_TIMING_8,    0x02800000 },
+       { AR5K_PHY_TIMING_11,   0x00000000 },
+       { AR5K_PHY_HEAVY_CLIP_ENABLE, 0x00000000 },
+       { 0x99e4,               0xaaaaaaaa },
+       { 0x99e8,               0x3c466478 },
+       { 0x99ec,               0x000000aa },
+       { AR5K_PHY_SCLOCK,      0x0000000c },
+       { AR5K_PHY_SDELAY,      0x000000ff },
+       { AR5K_PHY_SPENDING,    0x00000014 },
+       { AR5K_PHY_DAG_CCK_CTL, 0x000009b5 },
+       { 0xa23c,               0x93c889af },
+       { AR5K_PHY_FAST_ADC,    0x00000001 },
+       { 0xa250,               0x0000a000 },
+       { AR5K_PHY_BLUETOOTH,   0x00000000 },
+       { AR5K_PHY_TPC_RG1,     0x0cc75380 },
+       { 0xa25c,               0x0f0f0f01 },
+       { 0xa260,               0x5f690f01 },
+       { 0xa264,               0x00418a11 },
+       { 0xa268,               0x00000000 },
+       { AR5K_PHY_TPC_RG5,     0x0c30c16a },
+       { 0xa270, 0x00820820 },
+       { 0xa274, 0x001b7caa },
+       { 0xa278, 0x1ce739ce },
+       { 0xa27c, 0x051701ce },
+       { 0xa300, 0x18010000 },
+       { 0xa304, 0x30032602 },
+       { 0xa308, 0x48073e06 },
+       { 0xa30c, 0x560b4c0a },
+       { 0xa310, 0x641a600f },
+       { 0xa314, 0x784f6e1b },
+       { 0xa318, 0x868f7c5a },
+       { 0xa31c, 0x8ecf865b },
+       { 0xa320, 0x9d4f970f },
+       { 0xa324, 0xa5cfa18f },
+       { 0xa328, 0xb55faf1f },
+       { 0xa32c, 0xbddfb99f },
+       { 0xa330, 0xcd7fc73f },
+       { 0xa334, 0xd5ffd1bf },
+       { 0xa338, 0x00000000 },
+       { 0xa33c, 0x00000000 },
+       { 0xa340, 0x00000000 },
+       { 0xa344, 0x00000000 },
+       { 0xa348, 0x3fffffff },
+       { 0xa34c, 0x3fffffff },
+       { 0xa350, 0x3fffffff },
+       { 0xa354, 0x0003ffff },
+       { 0xa358, 0x79a8aa1f },
+       { 0xa35c, 0x066c420f },
+       { 0xa360, 0x0f282207 },
+       { 0xa364, 0x17601685 },
+       { 0xa368, 0x1f801104 },
+       { 0xa36c, 0x37a00c03 },
+       { 0xa370, 0x3fc40883 },
+       { 0xa374, 0x57c00803 },
+       { 0xa378, 0x5fd80682 },
+       { 0xa37c, 0x7fe00482 },
+       { 0xa380, 0x7f3c7bba },
+       { 0xa384, 0xf3307ff0 },
+};
+
+/* Initial mode-specific settings for RF2425 (Written after ar5212_ini) */
+/* XXX: a mode ? */
+static const struct ath5k_ini_mode rf2425_ini_mode_end[] = {
+       { AR5K_TXCFG,
+       /*      a/XR       aTurbo         b        g (DYN)     gTurbo     */
+          { 0x00000015, 0x00000015, 0x00000015, 0x00000015, 0x00000015 } },
+       { AR5K_USEC_5211,
+          { 0x128d93a7, 0x098813cf, 0x04e01395, 0x12e013ab, 0x098813cf } },
+       { AR5K_PHY_TURBO,
+          { 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000001 } },
+       { AR5K_PHY_RF_CTL3,
+          { 0x0a020001, 0x0a020001, 0x05020100, 0x0a020001, 0x0a020001 } },
+       { AR5K_PHY_RF_CTL4,
+          { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
+       { AR5K_PHY_PA_CTL,
+          { 0x00000003, 0x00000003, 0x0000000b, 0x0000000b, 0x0000000b } },
+       { AR5K_PHY_SETTLING,
+          { 0x1372161c, 0x13721c25, 0x13721722, 0x13721422, 0x13721c25 } },
+       { AR5K_PHY_GAIN,
+          { 0x0018fa61, 0x0018fa61, 0x00199a65, 0x00199a65, 0x00199a65 } },
+       { AR5K_PHY_DESIRED_SIZE,
+          { 0x0c98b4e0, 0x0c98b4e0, 0x0c98b0da, 0x0c98b0da, 0x0c98b0da } },
+       { AR5K_PHY_SIG,
+          { 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e } },
+       { AR5K_PHY_AGCCOARSE,
+          { 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e } },
+       { AR5K_PHY_WEAK_OFDM_LOW_THR,
+          { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 } },
+       { AR5K_PHY_RX_DELAY,
+          { 0x000007d0, 0x000007d0, 0x0000044c, 0x00000898, 0x000007d0 } },
+       { AR5K_PHY_FRAME_CTL_5211,
+          { 0xf7b81000, 0xf7b81000, 0xf7b80d00, 0xf7b81000, 0xf7b81000 } },
+       { AR5K_PHY_CCKTXCTL,
+          { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { AR5K_PHY_CCK_CROSSCORR,
+          { 0xd6be6788, 0xd6be6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } },
+       { AR5K_PHY_GAIN_2GHZ,
+          { 0x00000140, 0x00000140, 0x0052c140, 0x0052c140, 0x0052c140 } },
+       { AR5K_PHY_CCK_RX_CTL_4,
+          { 0x1883800a, 0x1883800a, 0x1863800a, 0x1883800a, 0x1883800a } },
+       { 0xa324,
+          { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
+       { 0xa328,
+          { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
+       { 0xa32c,
+          { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
+       { 0xa330,
+          { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
+       { 0xa334,
+          { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
+};
+
+static const struct ath5k_ini rf2425_ini_common_end[] = {
+       { AR5K_DCU_FP,          0x000003e0 },
+       { AR5K_SEQ_MASK,        0x0000000f },
+       { 0x809c,               0x00000000 },
+       { 0x80a0,               0x00000000 },
+       { AR5K_MIC_QOS_CTL,     0x00000000 },
+       { AR5K_MIC_QOS_SEL,     0x00000000 },
+       { AR5K_MISC_MODE,       0x00000000 },
+       { AR5K_OFDM_FIL_CNT,    0x00000000 },
+       { AR5K_CCK_FIL_CNT,     0x00000000 },
+       { AR5K_PHYERR_CNT1,     0x00000000 },
+       { AR5K_PHYERR_CNT1_MASK, 0x00000000 },
+       { AR5K_PHYERR_CNT2,     0x00000000 },
+       { AR5K_PHYERR_CNT2_MASK, 0x00000000 },
+       { AR5K_TSF_THRES,       0x00000000 },
+       { 0x8140,               0x800003f9 },
+       { 0x8144,               0x00000000 },
+       { AR5K_PHY_AGC,         0x00000000 },
+       { AR5K_PHY_ADC_CTL,     0x0000a000 },
+       { 0x983c,               0x00200400 },
+       { AR5K_PHY_GAIN_OFFSET, 0x1284233c },
+       { AR5K_PHY_SCR,         0x0000001f },
+       { AR5K_PHY_SLMT,        0x00000080 },
+       { AR5K_PHY_SCAL,        0x0000000e },
+       { 0x9958,               0x00081fff },
+       { AR5K_PHY_TIMING_7,    0x00000000 },
+       { AR5K_PHY_TIMING_8,    0x02800000 },
+       { AR5K_PHY_TIMING_11,   0x00000000 },
+       { 0x99dc,               0xfebadbe8 },
+       { AR5K_PHY_HEAVY_CLIP_ENABLE, 0x00000000 },
+       { 0x99e4,               0xaaaaaaaa },
+       { 0x99e8,               0x3c466478 },
+       { 0x99ec,               0x000000aa },
+       { AR5K_PHY_SCLOCK,      0x0000000c },
+       { AR5K_PHY_SDELAY,      0x000000ff },
+       { AR5K_PHY_SPENDING,    0x00000014 },
+       { AR5K_PHY_DAG_CCK_CTL, 0x000009b5 },
+       { AR5K_PHY_TXPOWER_RATE3, 0x20202020 },
+       { AR5K_PHY_TXPOWER_RATE4, 0x20202020 },
+       { 0xa23c,               0x93c889af },
+       { AR5K_PHY_FAST_ADC,    0x00000001 },
+       { 0xa250,               0x0000a000 },
+       { AR5K_PHY_BLUETOOTH,   0x00000000 },
+       { AR5K_PHY_TPC_RG1,     0x0cc75380 },
+       { 0xa25c,               0x0f0f0f01 },
+       { 0xa260,               0x5f690f01 },
+       { 0xa264,               0x00418a11 },
+       { 0xa268,               0x00000000 },
+       { AR5K_PHY_TPC_RG5,     0x0c30c166 },
+       { 0xa270, 0x00820820 },
+       { 0xa274, 0x081a3caa },
+       { 0xa278, 0x1ce739ce },
+       { 0xa27c, 0x051701ce },
+       { 0xa300, 0x16010000 },
+       { 0xa304, 0x2c032402 },
+       { 0xa308, 0x48433e42 },
+       { 0xa30c, 0x5a0f500b },
+       { 0xa310, 0x6c4b624a },
+       { 0xa314, 0x7e8b748a },
+       { 0xa318, 0x96cf8ccb },
+       { 0xa31c, 0xa34f9d0f },
+       { 0xa320, 0xa7cfa58f },
+       { 0xa348, 0x3fffffff },
+       { 0xa34c, 0x3fffffff },
+       { 0xa350, 0x3fffffff },
+       { 0xa354, 0x0003ffff },
+       { 0xa358, 0x79a8aa1f },
+       { 0xa35c, 0x066c420f },
+       { 0xa360, 0x0f282207 },
+       { 0xa364, 0x17601685 },
+       { 0xa368, 0x1f801104 },
+       { 0xa36c, 0x37a00c03 },
+       { 0xa370, 0x3fc40883 },
+       { 0xa374, 0x57c00803 },
+       { 0xa378, 0x5fd80682 },
+       { 0xa37c, 0x7fe00482 },
+       { 0xa380, 0x7f3c7bba },
+       { 0xa384, 0xf3307ff0 },
+};
+
+/*
+ * Initial BaseBand Gain settings for RF5111/5112 (AR5210 comes with
+ * RF5110 only so initial BB Gain settings are included in AR5K_AR5210_INI)
+ */
+
+/* RF5111 Initial BaseBand Gain settings */
+static const struct ath5k_ini rf5111_ini_bbgain[] = {
+       { AR5K_BB_GAIN(0), 0x00000000 },
+       { AR5K_BB_GAIN(1), 0x00000020 },
+       { AR5K_BB_GAIN(2), 0x00000010 },
+       { AR5K_BB_GAIN(3), 0x00000030 },
+       { AR5K_BB_GAIN(4), 0x00000008 },
+       { AR5K_BB_GAIN(5), 0x00000028 },
+       { AR5K_BB_GAIN(6), 0x00000004 },
+       { AR5K_BB_GAIN(7), 0x00000024 },
+       { AR5K_BB_GAIN(8), 0x00000014 },
+       { AR5K_BB_GAIN(9), 0x00000034 },
+       { AR5K_BB_GAIN(10), 0x0000000c },
+       { AR5K_BB_GAIN(11), 0x0000002c },
+       { AR5K_BB_GAIN(12), 0x00000002 },
+       { AR5K_BB_GAIN(13), 0x00000022 },
+       { AR5K_BB_GAIN(14), 0x00000012 },
+       { AR5K_BB_GAIN(15), 0x00000032 },
+       { AR5K_BB_GAIN(16), 0x0000000a },
+       { AR5K_BB_GAIN(17), 0x0000002a },
+       { AR5K_BB_GAIN(18), 0x00000006 },
+       { AR5K_BB_GAIN(19), 0x00000026 },
+       { AR5K_BB_GAIN(20), 0x00000016 },
+       { AR5K_BB_GAIN(21), 0x00000036 },
+       { AR5K_BB_GAIN(22), 0x0000000e },
+       { AR5K_BB_GAIN(23), 0x0000002e },
+       { AR5K_BB_GAIN(24), 0x00000001 },
+       { AR5K_BB_GAIN(25), 0x00000021 },
+       { AR5K_BB_GAIN(26), 0x00000011 },
+       { AR5K_BB_GAIN(27), 0x00000031 },
+       { AR5K_BB_GAIN(28), 0x00000009 },
+       { AR5K_BB_GAIN(29), 0x00000029 },
+       { AR5K_BB_GAIN(30), 0x00000005 },
+       { AR5K_BB_GAIN(31), 0x00000025 },
+       { AR5K_BB_GAIN(32), 0x00000015 },
+       { AR5K_BB_GAIN(33), 0x00000035 },
+       { AR5K_BB_GAIN(34), 0x0000000d },
+       { AR5K_BB_GAIN(35), 0x0000002d },
+       { AR5K_BB_GAIN(36), 0x00000003 },
+       { AR5K_BB_GAIN(37), 0x00000023 },
+       { AR5K_BB_GAIN(38), 0x00000013 },
+       { AR5K_BB_GAIN(39), 0x00000033 },
+       { AR5K_BB_GAIN(40), 0x0000000b },
+       { AR5K_BB_GAIN(41), 0x0000002b },
+       { AR5K_BB_GAIN(42), 0x0000002b },
+       { AR5K_BB_GAIN(43), 0x0000002b },
+       { AR5K_BB_GAIN(44), 0x0000002b },
+       { AR5K_BB_GAIN(45), 0x0000002b },
+       { AR5K_BB_GAIN(46), 0x0000002b },
+       { AR5K_BB_GAIN(47), 0x0000002b },
+       { AR5K_BB_GAIN(48), 0x0000002b },
+       { AR5K_BB_GAIN(49), 0x0000002b },
+       { AR5K_BB_GAIN(50), 0x0000002b },
+       { AR5K_BB_GAIN(51), 0x0000002b },
+       { AR5K_BB_GAIN(52), 0x0000002b },
+       { AR5K_BB_GAIN(53), 0x0000002b },
+       { AR5K_BB_GAIN(54), 0x0000002b },
+       { AR5K_BB_GAIN(55), 0x0000002b },
+       { AR5K_BB_GAIN(56), 0x0000002b },
+       { AR5K_BB_GAIN(57), 0x0000002b },
+       { AR5K_BB_GAIN(58), 0x0000002b },
+       { AR5K_BB_GAIN(59), 0x0000002b },
+       { AR5K_BB_GAIN(60), 0x0000002b },
+       { AR5K_BB_GAIN(61), 0x0000002b },
+       { AR5K_BB_GAIN(62), 0x00000002 },
+       { AR5K_BB_GAIN(63), 0x00000016 },
+};
+
+/* RF5112 Initial BaseBand Gain settings (Same for RF5413/5414+) */
+static const struct ath5k_ini rf5112_ini_bbgain[] = {
+       { AR5K_BB_GAIN(0), 0x00000000 },
+       { AR5K_BB_GAIN(1), 0x00000001 },
+       { AR5K_BB_GAIN(2), 0x00000002 },
+       { AR5K_BB_GAIN(3), 0x00000003 },
+       { AR5K_BB_GAIN(4), 0x00000004 },
+       { AR5K_BB_GAIN(5), 0x00000005 },
+       { AR5K_BB_GAIN(6), 0x00000008 },
+       { AR5K_BB_GAIN(7), 0x00000009 },
+       { AR5K_BB_GAIN(8), 0x0000000a },
+       { AR5K_BB_GAIN(9), 0x0000000b },
+       { AR5K_BB_GAIN(10), 0x0000000c },
+       { AR5K_BB_GAIN(11), 0x0000000d },
+       { AR5K_BB_GAIN(12), 0x00000010 },
+       { AR5K_BB_GAIN(13), 0x00000011 },
+       { AR5K_BB_GAIN(14), 0x00000012 },
+       { AR5K_BB_GAIN(15), 0x00000013 },
+       { AR5K_BB_GAIN(16), 0x00000014 },
+       { AR5K_BB_GAIN(17), 0x00000015 },
+       { AR5K_BB_GAIN(18), 0x00000018 },
+       { AR5K_BB_GAIN(19), 0x00000019 },
+       { AR5K_BB_GAIN(20), 0x0000001a },
+       { AR5K_BB_GAIN(21), 0x0000001b },
+       { AR5K_BB_GAIN(22), 0x0000001c },
+       { AR5K_BB_GAIN(23), 0x0000001d },
+       { AR5K_BB_GAIN(24), 0x00000020 },
+       { AR5K_BB_GAIN(25), 0x00000021 },
+       { AR5K_BB_GAIN(26), 0x00000022 },
+       { AR5K_BB_GAIN(27), 0x00000023 },
+       { AR5K_BB_GAIN(28), 0x00000024 },
+       { AR5K_BB_GAIN(29), 0x00000025 },
+       { AR5K_BB_GAIN(30), 0x00000028 },
+       { AR5K_BB_GAIN(31), 0x00000029 },
+       { AR5K_BB_GAIN(32), 0x0000002a },
+       { AR5K_BB_GAIN(33), 0x0000002b },
+       { AR5K_BB_GAIN(34), 0x0000002c },
+       { AR5K_BB_GAIN(35), 0x0000002d },
+       { AR5K_BB_GAIN(36), 0x00000030 },
+       { AR5K_BB_GAIN(37), 0x00000031 },
+       { AR5K_BB_GAIN(38), 0x00000032 },
+       { AR5K_BB_GAIN(39), 0x00000033 },
+       { AR5K_BB_GAIN(40), 0x00000034 },
+       { AR5K_BB_GAIN(41), 0x00000035 },
+       { AR5K_BB_GAIN(42), 0x00000035 },
+       { AR5K_BB_GAIN(43), 0x00000035 },
+       { AR5K_BB_GAIN(44), 0x00000035 },
+       { AR5K_BB_GAIN(45), 0x00000035 },
+       { AR5K_BB_GAIN(46), 0x00000035 },
+       { AR5K_BB_GAIN(47), 0x00000035 },
+       { AR5K_BB_GAIN(48), 0x00000035 },
+       { AR5K_BB_GAIN(49), 0x00000035 },
+       { AR5K_BB_GAIN(50), 0x00000035 },
+       { AR5K_BB_GAIN(51), 0x00000035 },
+       { AR5K_BB_GAIN(52), 0x00000035 },
+       { AR5K_BB_GAIN(53), 0x00000035 },
+       { AR5K_BB_GAIN(54), 0x00000035 },
+       { AR5K_BB_GAIN(55), 0x00000035 },
+       { AR5K_BB_GAIN(56), 0x00000035 },
+       { AR5K_BB_GAIN(57), 0x00000035 },
+       { AR5K_BB_GAIN(58), 0x00000035 },
+       { AR5K_BB_GAIN(59), 0x00000035 },
+       { AR5K_BB_GAIN(60), 0x00000035 },
+       { AR5K_BB_GAIN(61), 0x00000035 },
+       { AR5K_BB_GAIN(62), 0x00000010 },
+       { AR5K_BB_GAIN(63), 0x0000001a },
+};
+
+
+/*
+ * Write initial register dump
+ */
+static void ath5k_hw_ini_registers(struct ath5k_hw *ah, unsigned int size,
+               const struct ath5k_ini *ini_regs, bool change_channel)
+{
+       unsigned int i;
+
+       /* Write initial registers */
+       for (i = 0; i < size; i++) {
+               /* On channel change there is
+                * no need to mess with PCU */
+               if (change_channel &&
+                               ini_regs[i].ini_register >= AR5K_PCU_MIN &&
+                               ini_regs[i].ini_register <= AR5K_PCU_MAX)
+                       continue;
+
+               switch (ini_regs[i].ini_mode) {
+               case AR5K_INI_READ:
+                       /* Cleared on read */
+                       ath5k_hw_reg_read(ah, ini_regs[i].ini_register);
+                       break;
+               case AR5K_INI_WRITE:
+               default:
+                       AR5K_REG_WAIT(i);
+                       ath5k_hw_reg_write(ah, ini_regs[i].ini_value,
+                                       ini_regs[i].ini_register);
+               }
+       }
+}
+
+static void ath5k_hw_ini_mode_registers(struct ath5k_hw *ah,
+               unsigned int size, const struct ath5k_ini_mode *ini_mode,
+               u8 mode)
+{
+       unsigned int i;
+
+       for (i = 0; i < size; i++) {
+               AR5K_REG_WAIT(i);
+               ath5k_hw_reg_write(ah, ini_mode[i].mode_value[mode],
+                       (u32)ini_mode[i].mode_register);
+       }
+
+}
+
+int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel)
+{
+       /*
+        * Write initial register settings
+        */
+
+       /* For AR5212 and combatible */
+       if (ah->ah_version == AR5K_AR5212) {
+
+               /* First set of mode-specific settings */
+               ath5k_hw_ini_mode_registers(ah,
+                       ARRAY_SIZE(ar5212_ini_mode_start),
+                       ar5212_ini_mode_start, mode);
+
+               /*
+                * Write initial settings common for all modes
+                */
+               ath5k_hw_ini_registers(ah, ARRAY_SIZE(ar5212_ini_common_start),
+                               ar5212_ini_common_start, change_channel);
+
+               /* Second set of mode-specific settings */
+               switch (ah->ah_radio) {
+               case AR5K_RF5111:
+
+                       ath5k_hw_ini_mode_registers(ah,
+                                       ARRAY_SIZE(rf5111_ini_mode_end),
+                                       rf5111_ini_mode_end, mode);
+
+                       ath5k_hw_ini_registers(ah,
+                                       ARRAY_SIZE(rf5111_ini_common_end),
+                                       rf5111_ini_common_end, change_channel);
+
+                       /* Baseband gain table */
+                       ath5k_hw_ini_registers(ah,
+                                       ARRAY_SIZE(rf5111_ini_bbgain),
+                                       rf5111_ini_bbgain, change_channel);
+
+                       break;
+               case AR5K_RF5112:
+
+                       ath5k_hw_ini_mode_registers(ah,
+                                       ARRAY_SIZE(rf5112_ini_mode_end),
+                                       rf5112_ini_mode_end, mode);
+
+                       ath5k_hw_ini_registers(ah,
+                                       ARRAY_SIZE(rf5112_ini_common_end),
+                                       rf5112_ini_common_end, change_channel);
+
+                       ath5k_hw_ini_registers(ah,
+                                       ARRAY_SIZE(rf5112_ini_bbgain),
+                                       rf5112_ini_bbgain, change_channel);
+
+                       break;
+               case AR5K_RF5413:
+
+                       ath5k_hw_ini_mode_registers(ah,
+                                       ARRAY_SIZE(rf5413_ini_mode_end),
+                                       rf5413_ini_mode_end, mode);
+
+                       ath5k_hw_ini_registers(ah,
+                                       ARRAY_SIZE(rf5413_ini_common_end),
+                                       rf5413_ini_common_end, change_channel);
+
+                       ath5k_hw_ini_registers(ah,
+                                       ARRAY_SIZE(rf5112_ini_bbgain),
+                                       rf5112_ini_bbgain, change_channel);
+
+                       break;
+               case AR5K_RF2316:
+               case AR5K_RF2413:
+
+                       ath5k_hw_ini_mode_registers(ah,
+                                       ARRAY_SIZE(rf2413_ini_mode_end),
+                                       rf2413_ini_mode_end, mode);
+
+                       ath5k_hw_ini_registers(ah,
+                                       ARRAY_SIZE(rf2413_ini_common_end),
+                                       rf2413_ini_common_end, change_channel);
+
+                       /* Override settings from rf2413_ini_common_end */
+                       if (ah->ah_radio == AR5K_RF2316) {
+                               ath5k_hw_reg_write(ah, 0x00004000,
+                                                       AR5K_PHY_AGC);
+                               ath5k_hw_reg_write(ah, 0x081b7caa,
+                                                       0xa274);
+                       }
+
+                       ath5k_hw_ini_registers(ah,
+                                       ARRAY_SIZE(rf5112_ini_bbgain),
+                                       rf5112_ini_bbgain, change_channel);
+                       break;
+               case AR5K_RF2317:
+               case AR5K_RF2425:
+
+                       ath5k_hw_ini_mode_registers(ah,
+                                       ARRAY_SIZE(rf2425_ini_mode_end),
+                                       rf2425_ini_mode_end, mode);
+
+                       ath5k_hw_ini_registers(ah,
+                                       ARRAY_SIZE(rf2425_ini_common_end),
+                                       rf2425_ini_common_end, change_channel);
+
+                       ath5k_hw_ini_registers(ah,
+                                       ARRAY_SIZE(rf5112_ini_bbgain),
+                                       rf5112_ini_bbgain, change_channel);
+                       break;
+               default:
+                       return -EINVAL;
+
+               }
+
+       /* For AR5211 */
+       } else if (ah->ah_version == AR5K_AR5211) {
+
+               /* AR5K_MODE_11B */
+               if (mode > 2) {
+                       ATH5K_ERR(ah->ah_sc,
+                               "unsupported channel mode: %d\n", mode);
+                       return -EINVAL;
+               }
+
+               /* Mode-specific settings */
+               ath5k_hw_ini_mode_registers(ah, ARRAY_SIZE(ar5211_ini_mode),
+                               ar5211_ini_mode, mode);
+
+               /*
+                * Write initial settings common for all modes
+                */
+               ath5k_hw_ini_registers(ah, ARRAY_SIZE(ar5211_ini),
+                               ar5211_ini, change_channel);
+
+               /* AR5211 only comes with 5111 */
+
+               /* Baseband gain table */
+               ath5k_hw_ini_registers(ah, ARRAY_SIZE(rf5111_ini_bbgain),
+                               rf5111_ini_bbgain, change_channel);
+       /* For AR5210 (for mode settings check out ath5k_hw_reset_tx_queue) */
+       } else if (ah->ah_version == AR5K_AR5210) {
+               ath5k_hw_ini_registers(ah, ARRAY_SIZE(ar5210_ini),
+                               ar5210_ini, change_channel);
+       }
+
+       return 0;
+}
diff --git a/drivers/net/wireless/ath/ath5k/led.c b/drivers/net/wireless/ath/ath5k/led.c
new file mode 100644 (file)
index 0000000..876725f
--- /dev/null
@@ -0,0 +1,180 @@
+/*
+ * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
+ * Copyright (c) 2004-2005 Atheros Communications, Inc.
+ * Copyright (c) 2007 Jiri Slaby <jirislaby@gmail.com>
+ * Copyright (c) 2009 Bob Copeland <me@bobcopeland.com>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ *    redistribution must be conditioned upon including a substantially
+ *    similar Disclaimer requirement for further binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+#include <linux/pci.h>
+#include "ath5k.h"
+#include "base.h"
+
+#define ATH_SDEVICE(subv,subd) \
+       .vendor = PCI_ANY_ID, .device = PCI_ANY_ID, \
+       .subvendor = (subv), .subdevice = (subd)
+
+#define ATH_LED(pin,polarity) .driver_data = (((pin) << 8) | (polarity))
+#define ATH_PIN(data) ((data) >> 8)
+#define ATH_POLARITY(data) ((data) & 0xff)
+
+/* Devices we match on for LED config info (typically laptops) */
+static const struct pci_device_id ath5k_led_devices[] = {
+       /* AR5211 */
+       { PCI_VDEVICE(ATHEROS, PCI_DEVICE_ID_ATHEROS_AR5211), ATH_LED(0, 0) },
+       /* HP Compaq nc6xx, nc4000, nx6000 */
+       { ATH_SDEVICE(PCI_VENDOR_ID_COMPAQ, PCI_ANY_ID), ATH_LED(1, 1) },
+       /* Acer Aspire One A150 (maximlevitsky@gmail.com) */
+       { ATH_SDEVICE(PCI_VENDOR_ID_FOXCONN, 0xe008), ATH_LED(3, 0) },
+       /* Acer Ferrari 5000 (russ.dill@gmail.com) */
+       { ATH_SDEVICE(PCI_VENDOR_ID_AMBIT, 0x0422), ATH_LED(1, 1) },
+       /* E-machines E510 (tuliom@gmail.com) */
+       { ATH_SDEVICE(PCI_VENDOR_ID_AMBIT, 0x0428), ATH_LED(3, 0) },
+       /* Acer Extensa 5620z (nekoreeve@gmail.com) */
+       { ATH_SDEVICE(PCI_VENDOR_ID_QMI, 0x0105), ATH_LED(3, 0) },
+       /* Fukato Datacask Jupiter 1014a (mrb74@gmx.at) */
+       { ATH_SDEVICE(PCI_VENDOR_ID_AZWAVE, 0x1026), ATH_LED(3, 0) },
+       /* IBM ThinkPad AR5BXB6 (legovini@spiro.fisica.unipd.it) */
+       { ATH_SDEVICE(PCI_VENDOR_ID_IBM, 0x058a), ATH_LED(1, 0) },
+       /* IBM-specific AR5212 (all others) */
+       { PCI_VDEVICE(ATHEROS, PCI_DEVICE_ID_ATHEROS_AR5212_IBM), ATH_LED(0, 0) },
+       { }
+};
+
+void ath5k_led_enable(struct ath5k_softc *sc)
+{
+       if (test_bit(ATH_STAT_LEDSOFT, sc->status)) {
+               ath5k_hw_set_gpio_output(sc->ah, sc->led_pin);
+               ath5k_led_off(sc);
+       }
+}
+
+static void ath5k_led_on(struct ath5k_softc *sc)
+{
+       if (!test_bit(ATH_STAT_LEDSOFT, sc->status))
+               return;
+       ath5k_hw_set_gpio(sc->ah, sc->led_pin, sc->led_on);
+}
+
+void ath5k_led_off(struct ath5k_softc *sc)
+{
+       if (!test_bit(ATH_STAT_LEDSOFT, sc->status))
+               return;
+       ath5k_hw_set_gpio(sc->ah, sc->led_pin, !sc->led_on);
+}
+
+static void
+ath5k_led_brightness_set(struct led_classdev *led_dev,
+       enum led_brightness brightness)
+{
+       struct ath5k_led *led = container_of(led_dev, struct ath5k_led,
+               led_dev);
+
+       if (brightness == LED_OFF)
+               ath5k_led_off(led->sc);
+       else
+               ath5k_led_on(led->sc);
+}
+
+static int
+ath5k_register_led(struct ath5k_softc *sc, struct ath5k_led *led,
+                  const char *name, char *trigger)
+{
+       int err;
+
+       led->sc = sc;
+       strncpy(led->name, name, sizeof(led->name));
+       led->led_dev.name = led->name;
+       led->led_dev.default_trigger = trigger;
+       led->led_dev.brightness_set = ath5k_led_brightness_set;
+
+       err = led_classdev_register(&sc->pdev->dev, &led->led_dev);
+       if (err) {
+               ATH5K_WARN(sc, "could not register LED %s\n", name);
+               led->sc = NULL;
+       }
+       return err;
+}
+
+static void
+ath5k_unregister_led(struct ath5k_led *led)
+{
+       if (!led->sc)
+               return;
+       led_classdev_unregister(&led->led_dev);
+       ath5k_led_off(led->sc);
+       led->sc = NULL;
+}
+
+void ath5k_unregister_leds(struct ath5k_softc *sc)
+{
+       ath5k_unregister_led(&sc->rx_led);
+       ath5k_unregister_led(&sc->tx_led);
+}
+
+int ath5k_init_leds(struct ath5k_softc *sc)
+{
+       int ret = 0;
+       struct ieee80211_hw *hw = sc->hw;
+       struct pci_dev *pdev = sc->pdev;
+       char name[ATH5K_LED_MAX_NAME_LEN + 1];
+       const struct pci_device_id *match;
+
+       match = pci_match_id(&ath5k_led_devices[0], pdev);
+       if (match) {
+               __set_bit(ATH_STAT_LEDSOFT, sc->status);
+               sc->led_pin = ATH_PIN(match->driver_data);
+               sc->led_on = ATH_POLARITY(match->driver_data);
+       }
+
+       if (!test_bit(ATH_STAT_LEDSOFT, sc->status))
+               goto out;
+
+       ath5k_led_enable(sc);
+
+       snprintf(name, sizeof(name), "ath5k-%s::rx", wiphy_name(hw->wiphy));
+       ret = ath5k_register_led(sc, &sc->rx_led, name,
+               ieee80211_get_rx_led_name(hw));
+       if (ret)
+               goto out;
+
+       snprintf(name, sizeof(name), "ath5k-%s::tx", wiphy_name(hw->wiphy));
+       ret = ath5k_register_led(sc, &sc->tx_led, name,
+               ieee80211_get_tx_led_name(hw));
+out:
+       return ret;
+}
+
diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c
new file mode 100644 (file)
index 0000000..ec35503
--- /dev/null
@@ -0,0 +1,1174 @@
+/*
+ * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
+ * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
+ * Copyright (c) 2007-2008 Matthew W. S. Bell  <mentor@madwifi.org>
+ * Copyright (c) 2007-2008 Luis Rodriguez <mcgrof@winlab.rutgers.edu>
+ * Copyright (c) 2007-2008 Pavel Roskin <proski@gnu.org>
+ * Copyright (c) 2007-2008 Jiri Slaby <jirislaby@gmail.com>
+ *
+ * Permission to use, copy, modify, and 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 Control Unit Functions *
+\*********************************/
+
+#include "ath5k.h"
+#include "reg.h"
+#include "debug.h"
+#include "base.h"
+
+/*******************\
+* Generic functions *
+\*******************/
+
+/**
+ * ath5k_hw_set_opmode - Set PCU operating mode
+ *
+ * @ah: The &struct ath5k_hw
+ *
+ * Initialize PCU for the various operating modes (AP/STA etc)
+ *
+ * NOTE: ah->ah_op_mode must be set before calling this.
+ */
+int ath5k_hw_set_opmode(struct ath5k_hw *ah)
+{
+       u32 pcu_reg, beacon_reg, low_id, high_id;
+
+
+       /* Preserve rest settings */
+       pcu_reg = ath5k_hw_reg_read(ah, AR5K_STA_ID1) & 0xffff0000;
+       pcu_reg &= ~(AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_AP
+                       | AR5K_STA_ID1_KEYSRCH_MODE
+                       | (ah->ah_version == AR5K_AR5210 ?
+                       (AR5K_STA_ID1_PWR_SV | AR5K_STA_ID1_NO_PSPOLL) : 0));
+
+       beacon_reg = 0;
+
+       ATH5K_TRACE(ah->ah_sc);
+
+       switch (ah->ah_op_mode) {
+       case NL80211_IFTYPE_ADHOC:
+               pcu_reg |= AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_KEYSRCH_MODE;
+               beacon_reg |= AR5K_BCR_ADHOC;
+               if (ah->ah_version == AR5K_AR5210)
+                       pcu_reg |= AR5K_STA_ID1_NO_PSPOLL;
+               else
+                       AR5K_REG_ENABLE_BITS(ah, AR5K_CFG, AR5K_CFG_IBSS);
+               break;
+
+       case NL80211_IFTYPE_AP:
+       case NL80211_IFTYPE_MESH_POINT:
+               pcu_reg |= AR5K_STA_ID1_AP | AR5K_STA_ID1_KEYSRCH_MODE;
+               beacon_reg |= AR5K_BCR_AP;
+               if (ah->ah_version == AR5K_AR5210)
+                       pcu_reg |= AR5K_STA_ID1_NO_PSPOLL;
+               else
+                       AR5K_REG_DISABLE_BITS(ah, AR5K_CFG, AR5K_CFG_IBSS);
+               break;
+
+       case NL80211_IFTYPE_STATION:
+               pcu_reg |= AR5K_STA_ID1_KEYSRCH_MODE
+                       | (ah->ah_version == AR5K_AR5210 ?
+                               AR5K_STA_ID1_PWR_SV : 0);
+       case NL80211_IFTYPE_MONITOR:
+               pcu_reg |= AR5K_STA_ID1_KEYSRCH_MODE
+                       | (ah->ah_version == AR5K_AR5210 ?
+                               AR5K_STA_ID1_NO_PSPOLL : 0);
+               break;
+
+       default:
+               return -EINVAL;
+       }
+
+       /*
+        * Set PCU registers
+        */
+       low_id = AR5K_LOW_ID(ah->ah_sta_id);
+       high_id = AR5K_HIGH_ID(ah->ah_sta_id);
+       ath5k_hw_reg_write(ah, low_id, AR5K_STA_ID0);
+       ath5k_hw_reg_write(ah, pcu_reg | high_id, AR5K_STA_ID1);
+
+       /*
+        * Set Beacon Control Register on 5210
+        */
+       if (ah->ah_version == AR5K_AR5210)
+               ath5k_hw_reg_write(ah, beacon_reg, AR5K_BCR);
+
+       return 0;
+}
+
+/**
+ * ath5k_hw_update - Update mib counters (mac layer statistics)
+ *
+ * @ah: The &struct ath5k_hw
+ * @stats: The &struct ieee80211_low_level_stats we use to track
+ * statistics on the driver
+ *
+ * Reads MIB counters from PCU and updates sw statistics. Must be
+ * called after a MIB interrupt.
+ */
+void ath5k_hw_update_mib_counters(struct ath5k_hw *ah,
+               struct ieee80211_low_level_stats  *stats)
+{
+       ATH5K_TRACE(ah->ah_sc);
+
+       /* Read-And-Clear */
+       stats->dot11ACKFailureCount += ath5k_hw_reg_read(ah, AR5K_ACK_FAIL);
+       stats->dot11RTSFailureCount += ath5k_hw_reg_read(ah, AR5K_RTS_FAIL);
+       stats->dot11RTSSuccessCount += ath5k_hw_reg_read(ah, AR5K_RTS_OK);
+       stats->dot11FCSErrorCount += ath5k_hw_reg_read(ah, AR5K_FCS_FAIL);
+
+       /* XXX: Should we use this to track beacon count ?
+        * -we read it anyway to clear the register */
+       ath5k_hw_reg_read(ah, AR5K_BEACON_CNT);
+
+       /* Reset profile count registers on 5212*/
+       if (ah->ah_version == AR5K_AR5212) {
+               ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_TX);
+               ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_RX);
+               ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_RXCLR);
+               ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_CYCLE);
+       }
+
+       /* TODO: Handle ANI stats */
+}
+
+/**
+ * ath5k_hw_set_ack_bitrate - set bitrate for ACKs
+ *
+ * @ah: The &struct ath5k_hw
+ * @high: Flag to determine if we want to use high transmition rate
+ * for ACKs or not
+ *
+ * If high flag is set, we tell hw to use a set of control rates based on
+ * the current transmition rate (check out control_rates array inside reset.c).
+ * If not hw just uses the lowest rate available for the current modulation
+ * scheme being used (1Mbit for CCK and 6Mbits for OFDM).
+ */
+void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high)
+{
+       if (ah->ah_version != AR5K_AR5212)
+               return;
+       else {
+               u32 val = AR5K_STA_ID1_BASE_RATE_11B | AR5K_STA_ID1_ACKCTS_6MB;
+               if (high)
+                       AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1, val);
+               else
+                       AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, val);
+       }
+}
+
+
+/******************\
+* ACK/CTS Timeouts *
+\******************/
+
+/**
+ * ath5k_hw_het_ack_timeout - Get ACK timeout from PCU in usec
+ *
+ * @ah: The &struct ath5k_hw
+ */
+unsigned int ath5k_hw_get_ack_timeout(struct ath5k_hw *ah)
+{
+       ATH5K_TRACE(ah->ah_sc);
+
+       return ath5k_hw_clocktoh(AR5K_REG_MS(ath5k_hw_reg_read(ah,
+                       AR5K_TIME_OUT), AR5K_TIME_OUT_ACK), ah->ah_turbo);
+}
+
+/**
+ * ath5k_hw_set_ack_timeout - Set ACK timeout on PCU
+ *
+ * @ah: The &struct ath5k_hw
+ * @timeout: Timeout in usec
+ */
+int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout)
+{
+       ATH5K_TRACE(ah->ah_sc);
+       if (ath5k_hw_clocktoh(AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_ACK),
+                       ah->ah_turbo) <= timeout)
+               return -EINVAL;
+
+       AR5K_REG_WRITE_BITS(ah, AR5K_TIME_OUT, AR5K_TIME_OUT_ACK,
+               ath5k_hw_htoclock(timeout, ah->ah_turbo));
+
+       return 0;
+}
+
+/**
+ * ath5k_hw_get_cts_timeout - Get CTS timeout from PCU in usec
+ *
+ * @ah: The &struct ath5k_hw
+ */
+unsigned int ath5k_hw_get_cts_timeout(struct ath5k_hw *ah)
+{
+       ATH5K_TRACE(ah->ah_sc);
+       return ath5k_hw_clocktoh(AR5K_REG_MS(ath5k_hw_reg_read(ah,
+                       AR5K_TIME_OUT), AR5K_TIME_OUT_CTS), ah->ah_turbo);
+}
+
+/**
+ * ath5k_hw_set_cts_timeout - Set CTS timeout on PCU
+ *
+ * @ah: The &struct ath5k_hw
+ * @timeout: Timeout in usec
+ */
+int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout)
+{
+       ATH5K_TRACE(ah->ah_sc);
+       if (ath5k_hw_clocktoh(AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_CTS),
+                       ah->ah_turbo) <= timeout)
+               return -EINVAL;
+
+       AR5K_REG_WRITE_BITS(ah, AR5K_TIME_OUT, AR5K_TIME_OUT_CTS,
+                       ath5k_hw_htoclock(timeout, ah->ah_turbo));
+
+       return 0;
+}
+
+
+/****************\
+* BSSID handling *
+\****************/
+
+/**
+ * ath5k_hw_get_lladdr - Get station id
+ *
+ * @ah: The &struct ath5k_hw
+ * @mac: The card's mac address
+ *
+ * Initialize ah->ah_sta_id using the mac address provided
+ * (just a memcpy).
+ *
+ * TODO: Remove it once we merge ath5k_softc and ath5k_hw
+ */
+void ath5k_hw_get_lladdr(struct ath5k_hw *ah, u8 *mac)
+{
+       ATH5K_TRACE(ah->ah_sc);
+       memcpy(mac, ah->ah_sta_id, ETH_ALEN);
+}
+
+/**
+ * ath5k_hw_set_lladdr - Set station id
+ *
+ * @ah: The &struct ath5k_hw
+ * @mac: The card's mac address
+ *
+ * Set station id on hw using the provided mac address
+ */
+int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac)
+{
+       u32 low_id, high_id;
+       u32 pcu_reg;
+
+       ATH5K_TRACE(ah->ah_sc);
+       /* Set new station ID */
+       memcpy(ah->ah_sta_id, mac, ETH_ALEN);
+
+       pcu_reg = ath5k_hw_reg_read(ah, AR5K_STA_ID1) & 0xffff0000;
+
+       low_id = AR5K_LOW_ID(mac);
+       high_id = AR5K_HIGH_ID(mac);
+
+       ath5k_hw_reg_write(ah, low_id, AR5K_STA_ID0);
+       ath5k_hw_reg_write(ah, pcu_reg | high_id, AR5K_STA_ID1);
+
+       return 0;
+}
+
+/**
+ * ath5k_hw_set_associd - Set BSSID for association
+ *
+ * @ah: The &struct ath5k_hw
+ * @bssid: BSSID
+ * @assoc_id: Assoc id
+ *
+ * Sets the BSSID which trigers the "SME Join" operation
+ */
+void ath5k_hw_set_associd(struct ath5k_hw *ah, const u8 *bssid, u16 assoc_id)
+{
+       u32 low_id, high_id;
+       u16 tim_offset = 0;
+
+       /*
+        * Set simple BSSID mask on 5212
+        */
+       if (ah->ah_version == AR5K_AR5212) {
+               ath5k_hw_reg_write(ah, AR5K_LOW_ID(ah->ah_bssid_mask),
+                                                       AR5K_BSS_IDM0);
+               ath5k_hw_reg_write(ah, AR5K_HIGH_ID(ah->ah_bssid_mask),
+                                                       AR5K_BSS_IDM1);
+       }
+
+       /*
+        * Set BSSID which triggers the "SME Join" operation
+        */
+       low_id = AR5K_LOW_ID(bssid);
+       high_id = AR5K_HIGH_ID(bssid);
+       ath5k_hw_reg_write(ah, low_id, AR5K_BSS_ID0);
+       ath5k_hw_reg_write(ah, high_id | ((assoc_id & 0x3fff) <<
+                               AR5K_BSS_ID1_AID_S), AR5K_BSS_ID1);
+
+       if (assoc_id == 0) {
+               ath5k_hw_disable_pspoll(ah);
+               return;
+       }
+
+       AR5K_REG_WRITE_BITS(ah, AR5K_BEACON, AR5K_BEACON_TIM,
+                       tim_offset ? tim_offset + 4 : 0);
+
+       ath5k_hw_enable_pspoll(ah, NULL, 0);
+}
+
+/**
+ * ath5k_hw_set_bssid_mask - filter out bssids we listen
+ *
+ * @ah: the &struct ath5k_hw
+ * @mask: the bssid_mask, a u8 array of size ETH_ALEN
+ *
+ * BSSID masking is a method used by AR5212 and newer hardware to inform PCU
+ * which bits of the interface's MAC address should be looked at when trying
+ * to decide which packets to ACK. In station mode and AP mode with a single
+ * BSS every bit matters since we lock to only one BSS. In AP mode with
+ * multiple BSSes (virtual interfaces) not every bit matters because hw must
+ * accept frames for all BSSes and so we tweak some bits of our mac address
+ * in order to have multiple BSSes.
+ *
+ * NOTE: This is a simple filter and does *not* filter out all
+ * relevant frames. Some frames that are not for us might get ACKed from us
+ * by PCU because they just match the mask.
+ *
+ * When handling multiple BSSes you can get the BSSID mask by computing the
+ * set of  ~ ( MAC XOR BSSID ) for all bssids we handle.
+ *
+ * When you do this you are essentially computing the common bits of all your
+ * BSSes. Later it is assumed the harware will "and" (&) the BSSID mask with
+ * the MAC address to obtain the relevant bits and compare the result with
+ * (frame's BSSID & mask) to see if they match.
+ */
+/*
+ * Simple example: on your card you have have two BSSes you have created with
+ * BSSID-01 and BSSID-02. Lets assume BSSID-01 will not use the MAC address.
+ * There is another BSSID-03 but you are not part of it. For simplicity's sake,
+ * assuming only 4 bits for a mac address and for BSSIDs you can then have:
+ *
+ *                  \
+ * MAC:                0001 |
+ * BSSID-01:   0100 | --> Belongs to us
+ * BSSID-02:   1001 |
+ *                  /
+ * -------------------
+ * BSSID-03:   0110  | --> External
+ * -------------------
+ *
+ * Our bssid_mask would then be:
+ *
+ *             On loop iteration for BSSID-01:
+ *             ~(0001 ^ 0100)  -> ~(0101)
+ *                             ->   1010
+ *             bssid_mask      =    1010
+ *
+ *             On loop iteration for BSSID-02:
+ *             bssid_mask &= ~(0001   ^   1001)
+ *             bssid_mask =   (1010)  & ~(0001 ^ 1001)
+ *             bssid_mask =   (1010)  & ~(1001)
+ *             bssid_mask =   (1010)  &  (0110)
+ *             bssid_mask =   0010
+ *
+ * A bssid_mask of 0010 means "only pay attention to the second least
+ * significant bit". This is because its the only bit common
+ * amongst the MAC and all BSSIDs we support. To findout what the real
+ * common bit is we can simply "&" the bssid_mask now with any BSSID we have
+ * or our MAC address (we assume the hardware uses the MAC address).
+ *
+ * Now, suppose there's an incoming frame for BSSID-03:
+ *
+ * IFRAME-01:  0110
+ *
+ * An easy eye-inspeciton of this already should tell you that this frame
+ * will not pass our check. This is beacuse the bssid_mask tells the
+ * hardware to only look at the second least significant bit and the
+ * common bit amongst the MAC and BSSIDs is 0, this frame has the 2nd LSB
+ * as 1, which does not match 0.
+ *
+ * So with IFRAME-01 we *assume* the hardware will do:
+ *
+ *     allow = (IFRAME-01 & bssid_mask) == (bssid_mask & MAC) ? 1 : 0;
+ *  --> allow = (0110 & 0010) == (0010 & 0001) ? 1 : 0;
+ *  --> allow = (0010) == 0000 ? 1 : 0;
+ *  --> allow = 0
+ *
+ *  Lets now test a frame that should work:
+ *
+ * IFRAME-02:  0001 (we should allow)
+ *
+ *     allow = (0001 & 1010) == 1010
+ *
+ *     allow = (IFRAME-02 & bssid_mask) == (bssid_mask & MAC) ? 1 : 0;
+ *  --> allow = (0001 & 0010) ==  (0010 & 0001) ? 1 :0;
+ *  --> allow = (0010) == (0010)
+ *  --> allow = 1
+ *
+ * Other examples:
+ *
+ * IFRAME-03:  0100 --> allowed
+ * IFRAME-04:  1001 --> allowed
+ * IFRAME-05:  1101 --> allowed but its not for us!!!
+ *
+ */
+int ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask)
+{
+       u32 low_id, high_id;
+       ATH5K_TRACE(ah->ah_sc);
+
+       /* Cache bssid mask so that we can restore it
+        * on reset */
+       memcpy(ah->ah_bssid_mask, mask, ETH_ALEN);
+       if (ah->ah_version == AR5K_AR5212) {
+               low_id = AR5K_LOW_ID(mask);
+               high_id = AR5K_HIGH_ID(mask);
+
+               ath5k_hw_reg_write(ah, low_id, AR5K_BSS_IDM0);
+               ath5k_hw_reg_write(ah, high_id, AR5K_BSS_IDM1);
+
+               return 0;
+       }
+
+       return -EIO;
+}
+
+
+/************\
+* RX Control *
+\************/
+
+/**
+ * ath5k_hw_start_rx_pcu - Start RX engine
+ *
+ * @ah: The &struct ath5k_hw
+ *
+ * Starts RX engine on PCU so that hw can process RXed frames
+ * (ACK etc).
+ *
+ * NOTE: RX DMA should be already enabled using ath5k_hw_start_rx_dma
+ * TODO: Init ANI here
+ */
+void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah)
+{
+       ATH5K_TRACE(ah->ah_sc);
+       AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX);
+}
+
+/**
+ * at5k_hw_stop_rx_pcu - Stop RX engine
+ *
+ * @ah: The &struct ath5k_hw
+ *
+ * Stops RX engine on PCU
+ *
+ * TODO: Detach ANI here
+ */
+void ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah)
+{
+       ATH5K_TRACE(ah->ah_sc);
+       AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX);
+}
+
+/*
+ * Set multicast filter
+ */
+void ath5k_hw_set_mcast_filter(struct ath5k_hw *ah, u32 filter0, u32 filter1)
+{
+       ATH5K_TRACE(ah->ah_sc);
+       /* Set the multicat filter */
+       ath5k_hw_reg_write(ah, filter0, AR5K_MCAST_FILTER0);
+       ath5k_hw_reg_write(ah, filter1, AR5K_MCAST_FILTER1);
+}
+
+/*
+ * Set multicast filter by index
+ */
+int ath5k_hw_set_mcast_filter_idx(struct ath5k_hw *ah, u32 index)
+{
+
+       ATH5K_TRACE(ah->ah_sc);
+       if (index >= 64)
+               return -EINVAL;
+       else if (index >= 32)
+               AR5K_REG_ENABLE_BITS(ah, AR5K_MCAST_FILTER1,
+                               (1 << (index - 32)));
+       else
+               AR5K_REG_ENABLE_BITS(ah, AR5K_MCAST_FILTER0, (1 << index));
+
+       return 0;
+}
+
+/*
+ * Clear Multicast filter by index
+ */
+int ath5k_hw_clear_mcast_filter_idx(struct ath5k_hw *ah, u32 index)
+{
+
+       ATH5K_TRACE(ah->ah_sc);
+       if (index >= 64)
+               return -EINVAL;
+       else if (index >= 32)
+               AR5K_REG_DISABLE_BITS(ah, AR5K_MCAST_FILTER1,
+                               (1 << (index - 32)));
+       else
+               AR5K_REG_DISABLE_BITS(ah, AR5K_MCAST_FILTER0, (1 << index));
+
+       return 0;
+}
+
+/**
+ * ath5k_hw_get_rx_filter - Get current rx filter
+ *
+ * @ah: The &struct ath5k_hw
+ *
+ * Returns the RX filter by reading rx filter and
+ * phy error filter registers. RX filter is used
+ * to set the allowed frame types that PCU will accept
+ * and pass to the driver. For a list of frame types
+ * check out reg.h.
+ */
+u32 ath5k_hw_get_rx_filter(struct ath5k_hw *ah)
+{
+       u32 data, filter = 0;
+
+       ATH5K_TRACE(ah->ah_sc);
+       filter = ath5k_hw_reg_read(ah, AR5K_RX_FILTER);
+
+       /*Radar detection for 5212*/
+       if (ah->ah_version == AR5K_AR5212) {
+               data = ath5k_hw_reg_read(ah, AR5K_PHY_ERR_FIL);
+
+               if (data & AR5K_PHY_ERR_FIL_RADAR)
+                       filter |= AR5K_RX_FILTER_RADARERR;
+               if (data & (AR5K_PHY_ERR_FIL_OFDM | AR5K_PHY_ERR_FIL_CCK))
+                       filter |= AR5K_RX_FILTER_PHYERR;
+       }
+
+       return filter;
+}
+
+/**
+ * ath5k_hw_set_rx_filter - Set rx filter
+ *
+ * @ah: The &struct ath5k_hw
+ * @filter: RX filter mask (see reg.h)
+ *
+ * Sets RX filter register and also handles PHY error filter
+ * register on 5212 and newer chips so that we have proper PHY
+ * error reporting.
+ */
+void ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter)
+{
+       u32 data = 0;
+
+       ATH5K_TRACE(ah->ah_sc);
+
+       /* Set PHY error filter register on 5212*/
+       if (ah->ah_version == AR5K_AR5212) {
+               if (filter & AR5K_RX_FILTER_RADARERR)
+                       data |= AR5K_PHY_ERR_FIL_RADAR;
+               if (filter & AR5K_RX_FILTER_PHYERR)
+                       data |= AR5K_PHY_ERR_FIL_OFDM | AR5K_PHY_ERR_FIL_CCK;
+       }
+
+       /*
+        * The AR5210 uses promiscous mode to detect radar activity
+        */
+       if (ah->ah_version == AR5K_AR5210 &&
+                       (filter & AR5K_RX_FILTER_RADARERR)) {
+               filter &= ~AR5K_RX_FILTER_RADARERR;
+               filter |= AR5K_RX_FILTER_PROM;
+       }
+
+       /*Zero length DMA (phy error reporting) */
+       if (data)
+               AR5K_REG_ENABLE_BITS(ah, AR5K_RXCFG, AR5K_RXCFG_ZLFDMA);
+       else
+               AR5K_REG_DISABLE_BITS(ah, AR5K_RXCFG, AR5K_RXCFG_ZLFDMA);
+
+       /*Write RX Filter register*/
+       ath5k_hw_reg_write(ah, filter & 0xff, AR5K_RX_FILTER);
+
+       /*Write PHY error filter register on 5212*/
+       if (ah->ah_version == AR5K_AR5212)
+               ath5k_hw_reg_write(ah, data, AR5K_PHY_ERR_FIL);
+
+}
+
+
+/****************\
+* Beacon control *
+\****************/
+
+/**
+ * ath5k_hw_get_tsf32 - Get a 32bit TSF
+ *
+ * @ah: The &struct ath5k_hw
+ *
+ * Returns lower 32 bits of current TSF
+ */
+u32 ath5k_hw_get_tsf32(struct ath5k_hw *ah)
+{
+       ATH5K_TRACE(ah->ah_sc);
+       return ath5k_hw_reg_read(ah, AR5K_TSF_L32);
+}
+
+/**
+ * ath5k_hw_get_tsf64 - Get the full 64bit TSF
+ *
+ * @ah: The &struct ath5k_hw
+ *
+ * Returns the current TSF
+ */
+u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah)
+{
+       u64 tsf = ath5k_hw_reg_read(ah, AR5K_TSF_U32);
+       ATH5K_TRACE(ah->ah_sc);
+
+       return ath5k_hw_reg_read(ah, AR5K_TSF_L32) | (tsf << 32);
+}
+
+/**
+ * ath5k_hw_set_tsf64 - Set a new 64bit TSF
+ *
+ * @ah: The &struct ath5k_hw
+ * @tsf64: The new 64bit TSF
+ *
+ * Sets the new TSF
+ */
+void ath5k_hw_set_tsf64(struct ath5k_hw *ah, u64 tsf64)
+{
+       ATH5K_TRACE(ah->ah_sc);
+
+       ath5k_hw_reg_write(ah, tsf64 & 0xffffffff, AR5K_TSF_L32);
+       ath5k_hw_reg_write(ah, (tsf64 >> 32) & 0xffffffff, AR5K_TSF_U32);
+}
+
+/**
+ * ath5k_hw_reset_tsf - Force a TSF reset
+ *
+ * @ah: The &struct ath5k_hw
+ *
+ * Forces a TSF reset on PCU
+ */
+void ath5k_hw_reset_tsf(struct ath5k_hw *ah)
+{
+       u32 val;
+
+       ATH5K_TRACE(ah->ah_sc);
+
+       val = ath5k_hw_reg_read(ah, AR5K_BEACON) | AR5K_BEACON_RESET_TSF;
+
+       /*
+        * Each write to the RESET_TSF bit toggles a hardware internal
+        * signal to reset TSF, but if left high it will cause a TSF reset
+        * on the next chip reset as well.  Thus we always write the value
+        * twice to clear the signal.
+        */
+       ath5k_hw_reg_write(ah, val, AR5K_BEACON);
+       ath5k_hw_reg_write(ah, val, AR5K_BEACON);
+}
+
+/*
+ * Initialize beacon timers
+ */
+void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval)
+{
+       u32 timer1, timer2, timer3;
+
+       ATH5K_TRACE(ah->ah_sc);
+       /*
+        * Set the additional timers by mode
+        */
+       switch (ah->ah_op_mode) {
+       case NL80211_IFTYPE_MONITOR:
+       case NL80211_IFTYPE_STATION:
+               /* In STA mode timer1 is used as next wakeup
+                * timer and timer2 as next CFP duration start
+                * timer. Both in 1/8TUs. */
+               /* TODO: PCF handling */
+               if (ah->ah_version == AR5K_AR5210) {
+                       timer1 = 0xffffffff;
+                       timer2 = 0xffffffff;
+               } else {
+                       timer1 = 0x0000ffff;
+                       timer2 = 0x0007ffff;
+               }
+               /* Mark associated AP as PCF incapable for now */
+               AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, AR5K_STA_ID1_PCF);
+               break;
+       case NL80211_IFTYPE_ADHOC:
+               AR5K_REG_ENABLE_BITS(ah, AR5K_TXCFG, AR5K_TXCFG_ADHOC_BCN_ATIM);
+       default:
+               /* On non-STA modes timer1 is used as next DMA
+                * beacon alert (DBA) timer and timer2 as next
+                * software beacon alert. Both in 1/8TUs. */
+               timer1 = (next_beacon - AR5K_TUNE_DMA_BEACON_RESP) << 3;
+               timer2 = (next_beacon - AR5K_TUNE_SW_BEACON_RESP) << 3;
+               break;
+       }
+
+       /* Timer3 marks the end of our ATIM window
+        * a zero length window is not allowed because
+        * we 'll get no beacons */
+       timer3 = next_beacon + (ah->ah_atim_window ? ah->ah_atim_window : 1);
+
+       /*
+        * Set the beacon register and enable all timers.
+        */
+       /* When in AP mode zero timer0 to start TSF */
+       if (ah->ah_op_mode == NL80211_IFTYPE_AP)
+               ath5k_hw_reg_write(ah, 0, AR5K_TIMER0);
+
+       ath5k_hw_reg_write(ah, next_beacon, AR5K_TIMER0);
+       ath5k_hw_reg_write(ah, timer1, AR5K_TIMER1);
+       ath5k_hw_reg_write(ah, timer2, AR5K_TIMER2);
+       ath5k_hw_reg_write(ah, timer3, AR5K_TIMER3);
+
+       /* Force a TSF reset if requested and enable beacons */
+       if (interval & AR5K_BEACON_RESET_TSF)
+               ath5k_hw_reset_tsf(ah);
+
+       ath5k_hw_reg_write(ah, interval & (AR5K_BEACON_PERIOD |
+                                       AR5K_BEACON_ENABLE),
+                                               AR5K_BEACON);
+
+       /* Flush any pending BMISS interrupts on ISR by
+        * performing a clear-on-write operation on PISR
+        * register for the BMISS bit (writing a bit on
+        * ISR togles a reset for that bit and leaves
+        * the rest bits intact) */
+       if (ah->ah_version == AR5K_AR5210)
+               ath5k_hw_reg_write(ah, AR5K_ISR_BMISS, AR5K_ISR);
+       else
+               ath5k_hw_reg_write(ah, AR5K_ISR_BMISS, AR5K_PISR);
+
+       /* TODO: Set enchanced sleep registers on AR5212
+        * based on vif->bss_conf params, until then
+        * disable power save reporting.*/
+       AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, AR5K_STA_ID1_PWR_SV);
+
+}
+
+#if 0
+/*
+ * Set beacon timers
+ */
+int ath5k_hw_set_beacon_timers(struct ath5k_hw *ah,
+               const struct ath5k_beacon_state *state)
+{
+       u32 cfp_period, next_cfp, dtim, interval, next_beacon;
+
+       /*
+        * TODO: should be changed through *state
+        * review struct ath5k_beacon_state struct
+        *
+        * XXX: These are used for cfp period bellow, are they
+        * ok ? Is it O.K. for tsf here to be 0 or should we use
+        * get_tsf ?
+        */
+       u32 dtim_count = 0; /* XXX */
+       u32 cfp_count = 0; /* XXX */
+       u32 tsf = 0; /* XXX */
+
+       ATH5K_TRACE(ah->ah_sc);
+       /* Return on an invalid beacon state */
+       if (state->bs_interval < 1)
+               return -EINVAL;
+
+       interval = state->bs_interval;
+       dtim = state->bs_dtim_period;
+
+       /*
+        * PCF support?
+        */
+       if (state->bs_cfp_period > 0) {
+               /*
+                * Enable PCF mode and set the CFP
+                * (Contention Free Period) and timer registers
+                */
+               cfp_period = state->bs_cfp_period * state->bs_dtim_period *
+                       state->bs_interval;
+               next_cfp = (cfp_count * state->bs_dtim_period + dtim_count) *
+                       state->bs_interval;
+
+               AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1,
+                               AR5K_STA_ID1_DEFAULT_ANTENNA |
+                               AR5K_STA_ID1_PCF);
+               ath5k_hw_reg_write(ah, cfp_period, AR5K_CFP_PERIOD);
+               ath5k_hw_reg_write(ah, state->bs_cfp_max_duration,
+                               AR5K_CFP_DUR);
+               ath5k_hw_reg_write(ah, (tsf + (next_cfp == 0 ? cfp_period :
+                                               next_cfp)) << 3, AR5K_TIMER2);
+       } else {
+               /* Disable PCF mode */
+               AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1,
+                               AR5K_STA_ID1_DEFAULT_ANTENNA |
+                               AR5K_STA_ID1_PCF);
+       }
+
+       /*
+        * Enable the beacon timer register
+        */
+       ath5k_hw_reg_write(ah, state->bs_next_beacon, AR5K_TIMER0);
+
+       /*
+        * Start the beacon timers
+        */
+       ath5k_hw_reg_write(ah, (ath5k_hw_reg_read(ah, AR5K_BEACON) &
+               ~(AR5K_BEACON_PERIOD | AR5K_BEACON_TIM)) |
+               AR5K_REG_SM(state->bs_tim_offset ? state->bs_tim_offset + 4 : 0,
+               AR5K_BEACON_TIM) | AR5K_REG_SM(state->bs_interval,
+               AR5K_BEACON_PERIOD), AR5K_BEACON);
+
+       /*
+        * Write new beacon miss threshold, if it appears to be valid
+        * XXX: Figure out right values for min <= bs_bmiss_threshold <= max
+        * and return if its not in range. We can test this by reading value and
+        * setting value to a largest value and seeing which values register.
+        */
+
+       AR5K_REG_WRITE_BITS(ah, AR5K_RSSI_THR, AR5K_RSSI_THR_BMISS,
+                       state->bs_bmiss_threshold);
+
+       /*
+        * Set sleep control register
+        * XXX: Didn't find this in 5210 code but since this register
+        * exists also in ar5k's 5210 headers i leave it as common code.
+        */
+       AR5K_REG_WRITE_BITS(ah, AR5K_SLEEP_CTL, AR5K_SLEEP_CTL_SLDUR,
+                       (state->bs_sleep_duration - 3) << 3);
+
+       /*
+        * Set enhanced sleep registers on 5212
+        */
+       if (ah->ah_version == AR5K_AR5212) {
+               if (state->bs_sleep_duration > state->bs_interval &&
+                               roundup(state->bs_sleep_duration, interval) ==
+                               state->bs_sleep_duration)
+                       interval = state->bs_sleep_duration;
+
+               if (state->bs_sleep_duration > dtim && (dtim == 0 ||
+                               roundup(state->bs_sleep_duration, dtim) ==
+                               state->bs_sleep_duration))
+                       dtim = state->bs_sleep_duration;
+
+               if (interval > dtim)
+                       return -EINVAL;
+
+               next_beacon = interval == dtim ? state->bs_next_dtim :
+                       state->bs_next_beacon;
+
+               ath5k_hw_reg_write(ah,
+                       AR5K_REG_SM((state->bs_next_dtim - 3) << 3,
+                       AR5K_SLEEP0_NEXT_DTIM) |
+                       AR5K_REG_SM(10, AR5K_SLEEP0_CABTO) |
+                       AR5K_SLEEP0_ENH_SLEEP_EN |
+                       AR5K_SLEEP0_ASSUME_DTIM, AR5K_SLEEP0);
+
+               ath5k_hw_reg_write(ah, AR5K_REG_SM((next_beacon - 3) << 3,
+                       AR5K_SLEEP1_NEXT_TIM) |
+                       AR5K_REG_SM(10, AR5K_SLEEP1_BEACON_TO), AR5K_SLEEP1);
+
+               ath5k_hw_reg_write(ah,
+                       AR5K_REG_SM(interval, AR5K_SLEEP2_TIM_PER) |
+                       AR5K_REG_SM(dtim, AR5K_SLEEP2_DTIM_PER), AR5K_SLEEP2);
+       }
+
+       return 0;
+}
+
+/*
+ * Reset beacon timers
+ */
+void ath5k_hw_reset_beacon(struct ath5k_hw *ah)
+{
+       ATH5K_TRACE(ah->ah_sc);
+       /*
+        * Disable beacon timer
+        */
+       ath5k_hw_reg_write(ah, 0, AR5K_TIMER0);
+
+       /*
+        * Disable some beacon register values
+        */
+       AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1,
+                       AR5K_STA_ID1_DEFAULT_ANTENNA | AR5K_STA_ID1_PCF);
+       ath5k_hw_reg_write(ah, AR5K_BEACON_PERIOD, AR5K_BEACON);
+}
+
+/*
+ * Wait for beacon queue to finish
+ */
+int ath5k_hw_beaconq_finish(struct ath5k_hw *ah, unsigned long phys_addr)
+{
+       unsigned int i;
+       int ret;
+
+       ATH5K_TRACE(ah->ah_sc);
+
+       /* 5210 doesn't have QCU*/
+       if (ah->ah_version == AR5K_AR5210) {
+               /*
+                * Wait for beaconn queue to finish by checking
+                * Control Register and Beacon Status Register.
+                */
+               for (i = AR5K_TUNE_BEACON_INTERVAL / 2; i > 0; i--) {
+                       if (!(ath5k_hw_reg_read(ah, AR5K_BSR) & AR5K_BSR_TXQ1F)
+                                       ||
+                           !(ath5k_hw_reg_read(ah, AR5K_CR) & AR5K_BSR_TXQ1F))
+                               break;
+                       udelay(10);
+               }
+
+               /* Timeout... */
+               if (i <= 0) {
+                       /*
+                        * Re-schedule the beacon queue
+                        */
+                       ath5k_hw_reg_write(ah, phys_addr, AR5K_NOQCU_TXDP1);
+                       ath5k_hw_reg_write(ah, AR5K_BCR_TQ1V | AR5K_BCR_BDMAE,
+                                       AR5K_BCR);
+
+                       return -EIO;
+               }
+               ret = 0;
+       } else {
+       /*5211/5212*/
+               ret = ath5k_hw_register_timeout(ah,
+                       AR5K_QUEUE_STATUS(AR5K_TX_QUEUE_ID_BEACON),
+                       AR5K_QCU_STS_FRMPENDCNT, 0, false);
+
+               if (AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, AR5K_TX_QUEUE_ID_BEACON))
+                       return -EIO;
+       }
+
+       return ret;
+}
+#endif
+
+
+/*********************\
+* Key table functions *
+\*********************/
+
+/*
+ * Reset a key entry on the table
+ */
+int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry)
+{
+       unsigned int i, type;
+       u16 micentry = entry + AR5K_KEYTABLE_MIC_OFFSET;
+
+       ATH5K_TRACE(ah->ah_sc);
+       AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE);
+
+       type = ath5k_hw_reg_read(ah, AR5K_KEYTABLE_TYPE(entry));
+
+       for (i = 0; i < AR5K_KEYCACHE_SIZE; i++)
+               ath5k_hw_reg_write(ah, 0, AR5K_KEYTABLE_OFF(entry, i));
+
+       /* Reset associated MIC entry if TKIP
+        * is enabled located at offset (entry + 64) */
+       if (type == AR5K_KEYTABLE_TYPE_TKIP) {
+               AR5K_ASSERT_ENTRY(micentry, AR5K_KEYTABLE_SIZE);
+               for (i = 0; i < AR5K_KEYCACHE_SIZE / 2 ; i++)
+                       ath5k_hw_reg_write(ah, 0,
+                               AR5K_KEYTABLE_OFF(micentry, i));
+       }
+
+       /*
+        * Set NULL encryption on AR5212+
+        *
+        * Note: AR5K_KEYTABLE_TYPE -> AR5K_KEYTABLE_OFF(entry, 5)
+        *       AR5K_KEYTABLE_TYPE_NULL -> 0x00000007
+        *
+        * Note2: Windows driver (ndiswrapper) sets this to
+        *        0x00000714 instead of 0x00000007
+        */
+       if (ah->ah_version >= AR5K_AR5211) {
+               ath5k_hw_reg_write(ah, AR5K_KEYTABLE_TYPE_NULL,
+                               AR5K_KEYTABLE_TYPE(entry));
+
+               if (type == AR5K_KEYTABLE_TYPE_TKIP) {
+                       ath5k_hw_reg_write(ah, AR5K_KEYTABLE_TYPE_NULL,
+                               AR5K_KEYTABLE_TYPE(micentry));
+               }
+       }
+
+       return 0;
+}
+
+/*
+ * Check if a table entry is valid
+ */
+int ath5k_hw_is_key_valid(struct ath5k_hw *ah, u16 entry)
+{
+       ATH5K_TRACE(ah->ah_sc);
+       AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE);
+
+       /* Check the validation flag at the end of the entry */
+       return ath5k_hw_reg_read(ah, AR5K_KEYTABLE_MAC1(entry)) &
+               AR5K_KEYTABLE_VALID;
+}
+
+static
+int ath5k_keycache_type(const struct ieee80211_key_conf *key)
+{
+       switch (key->alg) {
+       case ALG_TKIP:
+               return AR5K_KEYTABLE_TYPE_TKIP;
+       case ALG_CCMP:
+               return AR5K_KEYTABLE_TYPE_CCM;
+       case ALG_WEP:
+               if (key->keylen == WLAN_KEY_LEN_WEP40)
+                       return AR5K_KEYTABLE_TYPE_40;
+               else if (key->keylen == WLAN_KEY_LEN_WEP104)
+                       return AR5K_KEYTABLE_TYPE_104;
+               return -EINVAL;
+       default:
+               return -EINVAL;
+       }
+       return -EINVAL;
+}
+
+/*
+ * Set a key entry on the table
+ */
+int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry,
+               const struct ieee80211_key_conf *key, const u8 *mac)
+{
+       unsigned int i;
+       int keylen;
+       __le32 key_v[5] = {};
+       __le32 key0 = 0, key1 = 0;
+       __le32 *rxmic, *txmic;
+       int keytype;
+       u16 micentry = entry + AR5K_KEYTABLE_MIC_OFFSET;
+       bool is_tkip;
+       const u8 *key_ptr;
+
+       ATH5K_TRACE(ah->ah_sc);
+
+       is_tkip = (key->alg == ALG_TKIP);
+
+       /*
+        * key->keylen comes in from mac80211 in bytes.
+        * TKIP is 128 bit + 128 bit mic
+        */
+       keylen = (is_tkip) ? (128 / 8) : key->keylen;
+
+       if (entry > AR5K_KEYTABLE_SIZE ||
+               (is_tkip && micentry > AR5K_KEYTABLE_SIZE))
+               return -EOPNOTSUPP;
+
+       if (unlikely(keylen > 16))
+               return -EOPNOTSUPP;
+
+       keytype = ath5k_keycache_type(key);
+       if (keytype < 0)
+               return keytype;
+
+       /*
+        * each key block is 6 bytes wide, written as pairs of
+        * alternating 32 and 16 bit le values.
+        */
+       key_ptr = key->key;
+       for (i = 0; keylen >= 6; keylen -= 6) {
+               memcpy(&key_v[i], key_ptr, 6);
+               i += 2;
+               key_ptr += 6;
+       }
+       if (keylen)
+               memcpy(&key_v[i], key_ptr, keylen);
+
+       /* intentionally corrupt key until mic is installed */
+       if (is_tkip) {
+               key0 = key_v[0] = ~key_v[0];
+               key1 = key_v[1] = ~key_v[1];
+       }
+
+       for (i = 0; i < ARRAY_SIZE(key_v); i++)
+               ath5k_hw_reg_write(ah, le32_to_cpu(key_v[i]),
+                               AR5K_KEYTABLE_OFF(entry, i));
+
+       ath5k_hw_reg_write(ah, keytype, AR5K_KEYTABLE_TYPE(entry));
+
+       if (is_tkip) {
+               /* Install rx/tx MIC */
+               rxmic = (__le32 *) &key->key[16];
+               txmic = (__le32 *) &key->key[24];
+
+               if (ah->ah_combined_mic) {
+                       key_v[0] = rxmic[0];
+                       key_v[1] = cpu_to_le32(le32_to_cpu(txmic[0]) >> 16);
+                       key_v[2] = rxmic[1];
+                       key_v[3] = cpu_to_le32(le32_to_cpu(txmic[0]) & 0xffff);
+                       key_v[4] = txmic[1];
+               } else {
+                       key_v[0] = rxmic[0];
+                       key_v[1] = 0;
+                       key_v[2] = rxmic[1];
+                       key_v[3] = 0;
+                       key_v[4] = 0;
+               }
+               for (i = 0; i < ARRAY_SIZE(key_v); i++)
+                       ath5k_hw_reg_write(ah, le32_to_cpu(key_v[i]),
+                               AR5K_KEYTABLE_OFF(micentry, i));
+
+               ath5k_hw_reg_write(ah, AR5K_KEYTABLE_TYPE_NULL,
+                       AR5K_KEYTABLE_TYPE(micentry));
+               ath5k_hw_reg_write(ah, 0, AR5K_KEYTABLE_MAC0(micentry));
+               ath5k_hw_reg_write(ah, 0, AR5K_KEYTABLE_MAC1(micentry));
+
+               /* restore first 2 words of key */
+               ath5k_hw_reg_write(ah, le32_to_cpu(~key0),
+                       AR5K_KEYTABLE_OFF(entry, 0));
+               ath5k_hw_reg_write(ah, le32_to_cpu(~key1),
+                       AR5K_KEYTABLE_OFF(entry, 1));
+       }
+
+       return ath5k_hw_set_key_lladdr(ah, entry, mac);
+}
+
+int ath5k_hw_set_key_lladdr(struct ath5k_hw *ah, u16 entry, const u8 *mac)
+{
+       u32 low_id, high_id;
+
+       ATH5K_TRACE(ah->ah_sc);
+        /* Invalid entry (key table overflow) */
+       AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE);
+
+       /* MAC may be NULL if it's a broadcast key. In this case no need to
+        * to compute AR5K_LOW_ID and AR5K_HIGH_ID as we already know it. */
+       if (!mac) {
+               low_id = 0xffffffff;
+               high_id = 0xffff | AR5K_KEYTABLE_VALID;
+       } else {
+               low_id = AR5K_LOW_ID(mac);
+               high_id = AR5K_HIGH_ID(mac) | AR5K_KEYTABLE_VALID;
+       }
+
+       ath5k_hw_reg_write(ah, low_id, AR5K_KEYTABLE_MAC0(entry));
+       ath5k_hw_reg_write(ah, high_id, AR5K_KEYTABLE_MAC1(entry));
+
+       return 0;
+}
+
diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c
new file mode 100644 (file)
index 0000000..a876ca8
--- /dev/null
@@ -0,0 +1,3044 @@
+/*
+ * PHY functions
+ *
+ * Copyright (c) 2004-2007 Reyk Floeter <reyk@openbsd.org>
+ * Copyright (c) 2006-2009 Nick Kossifidis <mickflemm@gmail.com>
+ * Copyright (c) 2007-2008 Jiri Slaby <jirislaby@gmail.com>
+ * Copyright (c) 2008-2009 Felix Fietkau <nbd@openwrt.org>
+ *
+ * Permission to use, copy, modify, and 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.
+ *
+ */
+
+#define _ATH5K_PHY
+
+#include <linux/delay.h>
+
+#include "ath5k.h"
+#include "reg.h"
+#include "base.h"
+#include "rfbuffer.h"
+#include "rfgain.h"
+
+/*
+ * Used to modify RF Banks before writing them to AR5K_RF_BUFFER
+ */
+static unsigned int ath5k_hw_rfb_op(struct ath5k_hw *ah,
+                                       const struct ath5k_rf_reg *rf_regs,
+                                       u32 val, u8 reg_id, bool set)
+{
+       const struct ath5k_rf_reg *rfreg = NULL;
+       u8 offset, bank, num_bits, col, position;
+       u16 entry;
+       u32 mask, data, last_bit, bits_shifted, first_bit;
+       u32 *rfb;
+       s32 bits_left;
+       int i;
+
+       data = 0;
+       rfb = ah->ah_rf_banks;
+
+       for (i = 0; i < ah->ah_rf_regs_count; i++) {
+               if (rf_regs[i].index == reg_id) {
+                       rfreg = &rf_regs[i];
+                       break;
+               }
+       }
+
+       if (rfb == NULL || rfreg == NULL) {
+               ATH5K_PRINTF("Rf register not found!\n");
+               /* should not happen */
+               return 0;
+       }
+
+       bank = rfreg->bank;
+       num_bits = rfreg->field.len;
+       first_bit = rfreg->field.pos;
+       col = rfreg->field.col;
+
+       /* first_bit is an offset from bank's
+        * start. Since we have all banks on
+        * the same array, we use this offset
+        * to mark each bank's start */
+       offset = ah->ah_offset[bank];
+
+       /* Boundary check */
+       if (!(col <= 3 && num_bits <= 32 && first_bit + num_bits <= 319)) {
+               ATH5K_PRINTF("invalid values at offset %u\n", offset);
+               return 0;
+       }
+
+       entry = ((first_bit - 1) / 8) + offset;
+       position = (first_bit - 1) % 8;
+
+       if (set)
+               data = ath5k_hw_bitswap(val, num_bits);
+
+       for (bits_shifted = 0, bits_left = num_bits; bits_left > 0;
+       position = 0, entry++) {
+
+               last_bit = (position + bits_left > 8) ? 8 :
+                                       position + bits_left;
+
+               mask = (((1 << last_bit) - 1) ^ ((1 << position) - 1)) <<
+                                                               (col * 8);
+
+               if (set) {
+                       rfb[entry] &= ~mask;
+                       rfb[entry] |= ((data << position) << (col * 8)) & mask;
+                       data >>= (8 - position);
+               } else {
+                       data |= (((rfb[entry] & mask) >> (col * 8)) >> position)
+                               << bits_shifted;
+                       bits_shifted += last_bit - position;
+               }
+
+               bits_left -= 8 - position;
+       }
+
+       data = set ? 1 : ath5k_hw_bitswap(data, num_bits);
+
+       return data;
+}
+
+/**********************\
+* RF Gain optimization *
+\**********************/
+
+/*
+ * This code is used to optimize rf gain on different environments
+ * (temprature mostly) based on feedback from a power detector.
+ *
+ * It's only used on RF5111 and RF5112, later RF chips seem to have
+ * auto adjustment on hw -notice they have a much smaller BANK 7 and
+ * no gain optimization ladder-.
+ *
+ * For more infos check out this patent doc
+ * http://www.freepatentsonline.com/7400691.html
+ *
+ * This paper describes power drops as seen on the receiver due to
+ * probe packets
+ * http://www.cnri.dit.ie/publications/ICT08%20-%20Practical%20Issues
+ * %20of%20Power%20Control.pdf
+ *
+ * And this is the MadWiFi bug entry related to the above
+ * http://madwifi-project.org/ticket/1659
+ * with various measurements and diagrams
+ *
+ * TODO: Deal with power drops due to probes by setting an apropriate
+ * tx power on the probe packets ! Make this part of the calibration process.
+ */
+
+/* Initialize ah_gain durring attach */
+int ath5k_hw_rfgain_opt_init(struct ath5k_hw *ah)
+{
+       /* Initialize the gain optimization values */
+       switch (ah->ah_radio) {
+       case AR5K_RF5111:
+               ah->ah_gain.g_step_idx = rfgain_opt_5111.go_default;
+               ah->ah_gain.g_low = 20;
+               ah->ah_gain.g_high = 35;
+               ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
+               break;
+       case AR5K_RF5112:
+               ah->ah_gain.g_step_idx = rfgain_opt_5112.go_default;
+               ah->ah_gain.g_low = 20;
+               ah->ah_gain.g_high = 85;
+               ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+/* Schedule a gain probe check on the next transmited packet.
+ * That means our next packet is going to be sent with lower
+ * tx power and a Peak to Average Power Detector (PAPD) will try
+ * to measure the gain.
+ *
+ * XXX:  How about forcing a tx packet (bypassing PCU arbitrator etc)
+ * just after we enable the probe so that we don't mess with
+ * standard traffic ? Maybe it's time to use sw interrupts and
+ * a probe tasklet !!!
+ */
+static void ath5k_hw_request_rfgain_probe(struct ath5k_hw *ah)
+{
+
+       /* Skip if gain calibration is inactive or
+        * we already handle a probe request */
+       if (ah->ah_gain.g_state != AR5K_RFGAIN_ACTIVE)
+               return;
+
+       /* Send the packet with 2dB below max power as
+        * patent doc suggest */
+       ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txpower.txp_ofdm - 4,
+                       AR5K_PHY_PAPD_PROBE_TXPOWER) |
+                       AR5K_PHY_PAPD_PROBE_TX_NEXT, AR5K_PHY_PAPD_PROBE);
+
+       ah->ah_gain.g_state = AR5K_RFGAIN_READ_REQUESTED;
+
+}
+
+/* Calculate gain_F measurement correction
+ * based on the current step for RF5112 rev. 2 */
+static u32 ath5k_hw_rf_gainf_corr(struct ath5k_hw *ah)
+{
+       u32 mix, step;
+       u32 *rf;
+       const struct ath5k_gain_opt *go;
+       const struct ath5k_gain_opt_step *g_step;
+       const struct ath5k_rf_reg *rf_regs;
+
+       /* Only RF5112 Rev. 2 supports it */
+       if ((ah->ah_radio != AR5K_RF5112) ||
+       (ah->ah_radio_5ghz_revision <= AR5K_SREV_RAD_5112A))
+               return 0;
+
+       go = &rfgain_opt_5112;
+       rf_regs = rf_regs_5112a;
+       ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5112a);
+
+       g_step = &go->go_step[ah->ah_gain.g_step_idx];
+
+       if (ah->ah_rf_banks == NULL)
+               return 0;
+
+       rf = ah->ah_rf_banks;
+       ah->ah_gain.g_f_corr = 0;
+
+       /* No VGA (Variable Gain Amplifier) override, skip */
+       if (ath5k_hw_rfb_op(ah, rf_regs, 0, AR5K_RF_MIXVGA_OVR, false) != 1)
+               return 0;
+
+       /* Mix gain stepping */
+       step = ath5k_hw_rfb_op(ah, rf_regs, 0, AR5K_RF_MIXGAIN_STEP, false);
+
+       /* Mix gain override */
+       mix = g_step->gos_param[0];
+
+       switch (mix) {
+       case 3:
+               ah->ah_gain.g_f_corr = step * 2;
+               break;
+       case 2:
+               ah->ah_gain.g_f_corr = (step - 5) * 2;
+               break;
+       case 1:
+               ah->ah_gain.g_f_corr = step;
+               break;
+       default:
+               ah->ah_gain.g_f_corr = 0;
+               break;
+       }
+
+       return ah->ah_gain.g_f_corr;
+}
+
+/* Check if current gain_F measurement is in the range of our
+ * power detector windows. If we get a measurement outside range
+ * we know it's not accurate (detectors can't measure anything outside
+ * their detection window) so we must ignore it */
+static bool ath5k_hw_rf_check_gainf_readback(struct ath5k_hw *ah)
+{
+       const struct ath5k_rf_reg *rf_regs;
+       u32 step, mix_ovr, level[4];
+       u32 *rf;
+
+       if (ah->ah_rf_banks == NULL)
+               return false;
+
+       rf = ah->ah_rf_banks;
+
+       if (ah->ah_radio == AR5K_RF5111) {
+
+               rf_regs = rf_regs_5111;
+               ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5111);
+
+               step = ath5k_hw_rfb_op(ah, rf_regs, 0, AR5K_RF_RFGAIN_STEP,
+                       false);
+
+               level[0] = 0;
+               level[1] = (step == 63) ? 50 : step + 4;
+               level[2] = (step != 63) ? 64 : level[0];
+               level[3] = level[2] + 50 ;
+
+               ah->ah_gain.g_high = level[3] -
+                       (step == 63 ? AR5K_GAIN_DYN_ADJUST_HI_MARGIN : -5);
+               ah->ah_gain.g_low = level[0] +
+                       (step == 63 ? AR5K_GAIN_DYN_ADJUST_LO_MARGIN : 0);
+       } else {
+
+               rf_regs = rf_regs_5112;
+               ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5112);
+
+               mix_ovr = ath5k_hw_rfb_op(ah, rf_regs, 0, AR5K_RF_MIXVGA_OVR,
+                       false);
+
+               level[0] = level[2] = 0;
+
+               if (mix_ovr == 1) {
+                       level[1] = level[3] = 83;
+               } else {
+                       level[1] = level[3] = 107;
+                       ah->ah_gain.g_high = 55;
+               }
+       }
+
+       return (ah->ah_gain.g_current >= level[0] &&
+                       ah->ah_gain.g_current <= level[1]) ||
+               (ah->ah_gain.g_current >= level[2] &&
+                       ah->ah_gain.g_current <= level[3]);
+}
+
+/* Perform gain_F adjustment by choosing the right set
+ * of parameters from rf gain optimization ladder */
+static s8 ath5k_hw_rf_gainf_adjust(struct ath5k_hw *ah)
+{
+       const struct ath5k_gain_opt *go;
+       const struct ath5k_gain_opt_step *g_step;
+       int ret = 0;
+
+       switch (ah->ah_radio) {
+       case AR5K_RF5111:
+               go = &rfgain_opt_5111;
+               break;
+       case AR5K_RF5112:
+               go = &rfgain_opt_5112;
+               break;
+       default:
+               return 0;
+       }
+
+       g_step = &go->go_step[ah->ah_gain.g_step_idx];
+
+       if (ah->ah_gain.g_current >= ah->ah_gain.g_high) {
+
+               /* Reached maximum */
+               if (ah->ah_gain.g_step_idx == 0)
+                       return -1;
+
+               for (ah->ah_gain.g_target = ah->ah_gain.g_current;
+                               ah->ah_gain.g_target >=  ah->ah_gain.g_high &&
+                               ah->ah_gain.g_step_idx > 0;
+                               g_step = &go->go_step[ah->ah_gain.g_step_idx])
+                       ah->ah_gain.g_target -= 2 *
+                           (go->go_step[--(ah->ah_gain.g_step_idx)].gos_gain -
+                           g_step->gos_gain);
+
+               ret = 1;
+               goto done;
+       }
+
+       if (ah->ah_gain.g_current <= ah->ah_gain.g_low) {
+
+               /* Reached minimum */
+               if (ah->ah_gain.g_step_idx == (go->go_steps_count - 1))
+                       return -2;
+
+               for (ah->ah_gain.g_target = ah->ah_gain.g_current;
+                               ah->ah_gain.g_target <= ah->ah_gain.g_low &&
+                               ah->ah_gain.g_step_idx < go->go_steps_count-1;
+                               g_step = &go->go_step[ah->ah_gain.g_step_idx])
+                       ah->ah_gain.g_target -= 2 *
+                           (go->go_step[++ah->ah_gain.g_step_idx].gos_gain -
+                           g_step->gos_gain);
+
+               ret = 2;
+               goto done;
+       }
+
+done:
+       ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_CALIBRATE,
+               "ret %d, gain step %u, current gain %u, target gain %u\n",
+               ret, ah->ah_gain.g_step_idx, ah->ah_gain.g_current,
+               ah->ah_gain.g_target);
+
+       return ret;
+}
+
+/* Main callback for thermal rf gain calibration engine
+ * Check for a new gain reading and schedule an adjustment
+ * if needed.
+ *
+ * TODO: Use sw interrupt to schedule reset if gain_F needs
+ * adjustment */
+enum ath5k_rfgain ath5k_hw_gainf_calibrate(struct ath5k_hw *ah)
+{
+       u32 data, type;
+       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+
+       ATH5K_TRACE(ah->ah_sc);
+
+       if (ah->ah_rf_banks == NULL ||
+       ah->ah_gain.g_state == AR5K_RFGAIN_INACTIVE)
+               return AR5K_RFGAIN_INACTIVE;
+
+       /* No check requested, either engine is inactive
+        * or an adjustment is already requested */
+       if (ah->ah_gain.g_state != AR5K_RFGAIN_READ_REQUESTED)
+               goto done;
+
+       /* Read the PAPD (Peak to Average Power Detector)
+        * register */
+       data = ath5k_hw_reg_read(ah, AR5K_PHY_PAPD_PROBE);
+
+       /* No probe is scheduled, read gain_F measurement */
+       if (!(data & AR5K_PHY_PAPD_PROBE_TX_NEXT)) {
+               ah->ah_gain.g_current = data >> AR5K_PHY_PAPD_PROBE_GAINF_S;
+               type = AR5K_REG_MS(data, AR5K_PHY_PAPD_PROBE_TYPE);
+
+               /* If tx packet is CCK correct the gain_F measurement
+                * by cck ofdm gain delta */
+               if (type == AR5K_PHY_PAPD_PROBE_TYPE_CCK) {
+                       if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A)
+                               ah->ah_gain.g_current +=
+                                       ee->ee_cck_ofdm_gain_delta;
+                       else
+                               ah->ah_gain.g_current +=
+                                       AR5K_GAIN_CCK_PROBE_CORR;
+               }
+
+               /* Further correct gain_F measurement for
+                * RF5112A radios */
+               if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A) {
+                       ath5k_hw_rf_gainf_corr(ah);
+                       ah->ah_gain.g_current =
+                               ah->ah_gain.g_current >= ah->ah_gain.g_f_corr ?
+                               (ah->ah_gain.g_current-ah->ah_gain.g_f_corr) :
+                               0;
+               }
+
+               /* Check if measurement is ok and if we need
+                * to adjust gain, schedule a gain adjustment,
+                * else switch back to the acive state */
+               if (ath5k_hw_rf_check_gainf_readback(ah) &&
+               AR5K_GAIN_CHECK_ADJUST(&ah->ah_gain) &&
+               ath5k_hw_rf_gainf_adjust(ah)) {
+                       ah->ah_gain.g_state = AR5K_RFGAIN_NEED_CHANGE;
+               } else {
+                       ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
+               }
+       }
+
+done:
+       return ah->ah_gain.g_state;
+}
+
+/* Write initial rf gain table to set the RF sensitivity
+ * this one works on all RF chips and has nothing to do
+ * with gain_F calibration */
+int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq)
+{
+       const struct ath5k_ini_rfgain *ath5k_rfg;
+       unsigned int i, size;
+
+       switch (ah->ah_radio) {
+       case AR5K_RF5111:
+               ath5k_rfg = rfgain_5111;
+               size = ARRAY_SIZE(rfgain_5111);
+               break;
+       case AR5K_RF5112:
+               ath5k_rfg = rfgain_5112;
+               size = ARRAY_SIZE(rfgain_5112);
+               break;
+       case AR5K_RF2413:
+               ath5k_rfg = rfgain_2413;
+               size = ARRAY_SIZE(rfgain_2413);
+               break;
+       case AR5K_RF2316:
+               ath5k_rfg = rfgain_2316;
+               size = ARRAY_SIZE(rfgain_2316);
+               break;
+       case AR5K_RF5413:
+               ath5k_rfg = rfgain_5413;
+               size = ARRAY_SIZE(rfgain_5413);
+               break;
+       case AR5K_RF2317:
+       case AR5K_RF2425:
+               ath5k_rfg = rfgain_2425;
+               size = ARRAY_SIZE(rfgain_2425);
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       switch (freq) {
+       case AR5K_INI_RFGAIN_2GHZ:
+       case AR5K_INI_RFGAIN_5GHZ:
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       for (i = 0; i < size; i++) {
+               AR5K_REG_WAIT(i);
+               ath5k_hw_reg_write(ah, ath5k_rfg[i].rfg_value[freq],
+                       (u32)ath5k_rfg[i].rfg_register);
+       }
+
+       return 0;
+}
+
+
+
+/********************\
+* RF Registers setup *
+\********************/
+
+
+/*
+ * Setup RF registers by writing rf buffer on hw
+ */
+int ath5k_hw_rfregs_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
+               unsigned int mode)
+{
+       const struct ath5k_rf_reg *rf_regs;
+       const struct ath5k_ini_rfbuffer *ini_rfb;
+       const struct ath5k_gain_opt *go = NULL;
+       const struct ath5k_gain_opt_step *g_step;
+       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+       u8 ee_mode = 0;
+       u32 *rfb;
+       int i, obdb = -1, bank = -1;
+
+       switch (ah->ah_radio) {
+       case AR5K_RF5111:
+               rf_regs = rf_regs_5111;
+               ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5111);
+               ini_rfb = rfb_5111;
+               ah->ah_rf_banks_size = ARRAY_SIZE(rfb_5111);
+               go = &rfgain_opt_5111;
+               break;
+       case AR5K_RF5112:
+               if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A) {
+                       rf_regs = rf_regs_5112a;
+                       ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5112a);
+                       ini_rfb = rfb_5112a;
+                       ah->ah_rf_banks_size = ARRAY_SIZE(rfb_5112a);
+               } else {
+                       rf_regs = rf_regs_5112;
+                       ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5112);
+                       ini_rfb = rfb_5112;
+                       ah->ah_rf_banks_size = ARRAY_SIZE(rfb_5112);
+               }
+               go = &rfgain_opt_5112;
+               break;
+       case AR5K_RF2413:
+               rf_regs = rf_regs_2413;
+               ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_2413);
+               ini_rfb = rfb_2413;
+               ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2413);
+               break;
+       case AR5K_RF2316:
+               rf_regs = rf_regs_2316;
+               ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_2316);
+               ini_rfb = rfb_2316;
+               ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2316);
+               break;
+       case AR5K_RF5413:
+               rf_regs = rf_regs_5413;
+               ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5413);
+               ini_rfb = rfb_5413;
+               ah->ah_rf_banks_size = ARRAY_SIZE(rfb_5413);
+               break;
+       case AR5K_RF2317:
+               rf_regs = rf_regs_2425;
+               ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_2425);
+               ini_rfb = rfb_2317;
+               ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2317);
+               break;
+       case AR5K_RF2425:
+               rf_regs = rf_regs_2425;
+               ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_2425);
+               if (ah->ah_mac_srev < AR5K_SREV_AR2417) {
+                       ini_rfb = rfb_2425;
+                       ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2425);
+               } else {
+                       ini_rfb = rfb_2417;
+                       ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2417);
+               }
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       /* If it's the first time we set rf buffer, allocate
+        * ah->ah_rf_banks based on ah->ah_rf_banks_size
+        * we set above */
+       if (ah->ah_rf_banks == NULL) {
+               ah->ah_rf_banks = kmalloc(sizeof(u32) * ah->ah_rf_banks_size,
+                                                               GFP_KERNEL);
+               if (ah->ah_rf_banks == NULL) {
+                       ATH5K_ERR(ah->ah_sc, "out of memory\n");
+                       return -ENOMEM;
+               }
+       }
+
+       /* Copy values to modify them */
+       rfb = ah->ah_rf_banks;
+
+       for (i = 0; i < ah->ah_rf_banks_size; i++) {
+               if (ini_rfb[i].rfb_bank >= AR5K_MAX_RF_BANKS) {
+                       ATH5K_ERR(ah->ah_sc, "invalid bank\n");
+                       return -EINVAL;
+               }
+
+               /* Bank changed, write down the offset */
+               if (bank != ini_rfb[i].rfb_bank) {
+                       bank = ini_rfb[i].rfb_bank;
+                       ah->ah_offset[bank] = i;
+               }
+
+               rfb[i] = ini_rfb[i].rfb_mode_data[mode];
+       }
+
+       /* Set Output and Driver bias current (OB/DB) */
+       if (channel->hw_value & CHANNEL_2GHZ) {
+
+               if (channel->hw_value & CHANNEL_CCK)
+                       ee_mode = AR5K_EEPROM_MODE_11B;
+               else
+                       ee_mode = AR5K_EEPROM_MODE_11G;
+
+               /* For RF511X/RF211X combination we
+                * use b_OB and b_DB parameters stored
+                * in eeprom on ee->ee_ob[ee_mode][0]
+                *
+                * For all other chips we use OB/DB for 2Ghz
+                * stored in the b/g modal section just like
+                * 802.11a on ee->ee_ob[ee_mode][1] */
+               if ((ah->ah_radio == AR5K_RF5111) ||
+               (ah->ah_radio == AR5K_RF5112))
+                       obdb = 0;
+               else
+                       obdb = 1;
+
+               ath5k_hw_rfb_op(ah, rf_regs, ee->ee_ob[ee_mode][obdb],
+                                               AR5K_RF_OB_2GHZ, true);
+
+               ath5k_hw_rfb_op(ah, rf_regs, ee->ee_db[ee_mode][obdb],
+                                               AR5K_RF_DB_2GHZ, true);
+
+       /* RF5111 always needs OB/DB for 5GHz, even if we use 2GHz */
+       } else if ((channel->hw_value & CHANNEL_5GHZ) ||
+                       (ah->ah_radio == AR5K_RF5111)) {
+
+               /* For 11a, Turbo and XR we need to choose
+                * OB/DB based on frequency range */
+               ee_mode = AR5K_EEPROM_MODE_11A;
+               obdb =   channel->center_freq >= 5725 ? 3 :
+                       (channel->center_freq >= 5500 ? 2 :
+                       (channel->center_freq >= 5260 ? 1 :
+                        (channel->center_freq > 4000 ? 0 : -1)));
+
+               if (obdb < 0)
+                       return -EINVAL;
+
+               ath5k_hw_rfb_op(ah, rf_regs, ee->ee_ob[ee_mode][obdb],
+                                               AR5K_RF_OB_5GHZ, true);
+
+               ath5k_hw_rfb_op(ah, rf_regs, ee->ee_db[ee_mode][obdb],
+                                               AR5K_RF_DB_5GHZ, true);
+       }
+
+       g_step = &go->go_step[ah->ah_gain.g_step_idx];
+
+       /* Bank Modifications (chip-specific) */
+       if (ah->ah_radio == AR5K_RF5111) {
+
+               /* Set gain_F settings according to current step */
+               if (channel->hw_value & CHANNEL_OFDM) {
+
+                       AR5K_REG_WRITE_BITS(ah, AR5K_PHY_FRAME_CTL,
+                                       AR5K_PHY_FRAME_CTL_TX_CLIP,
+                                       g_step->gos_param[0]);
+
+                       ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[1],
+                                                       AR5K_RF_PWD_90, true);
+
+                       ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[2],
+                                                       AR5K_RF_PWD_84, true);
+
+                       ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[3],
+                                               AR5K_RF_RFGAIN_SEL, true);
+
+                       /* We programmed gain_F parameters, switch back
+                        * to active state */
+                       ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
+
+               }
+
+               /* Bank 6/7 setup */
+
+               ath5k_hw_rfb_op(ah, rf_regs, !ee->ee_xpd[ee_mode],
+                                               AR5K_RF_PWD_XPD, true);
+
+               ath5k_hw_rfb_op(ah, rf_regs, ee->ee_x_gain[ee_mode],
+                                               AR5K_RF_XPD_GAIN, true);
+
+               ath5k_hw_rfb_op(ah, rf_regs, ee->ee_i_gain[ee_mode],
+                                               AR5K_RF_GAIN_I, true);
+
+               ath5k_hw_rfb_op(ah, rf_regs, ee->ee_xpd[ee_mode],
+                                               AR5K_RF_PLO_SEL, true);
+
+               /* TODO: Half/quarter channel support */
+       }
+
+       if (ah->ah_radio == AR5K_RF5112) {
+
+               /* Set gain_F settings according to current step */
+               if (channel->hw_value & CHANNEL_OFDM) {
+
+                       ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[0],
+                                               AR5K_RF_MIXGAIN_OVR, true);
+
+                       ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[1],
+                                               AR5K_RF_PWD_138, true);
+
+                       ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[2],
+                                               AR5K_RF_PWD_137, true);
+
+                       ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[3],
+                                               AR5K_RF_PWD_136, true);
+
+                       ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[4],
+                                               AR5K_RF_PWD_132, true);
+
+                       ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[5],
+                                               AR5K_RF_PWD_131, true);
+
+                       ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[6],
+                                               AR5K_RF_PWD_130, true);
+
+                       /* We programmed gain_F parameters, switch back
+                        * to active state */
+                       ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
+               }
+
+               /* Bank 6/7 setup */
+
+               ath5k_hw_rfb_op(ah, rf_regs, ee->ee_xpd[ee_mode],
+                                               AR5K_RF_XPD_SEL, true);
+
+               if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5112A) {
+                       /* Rev. 1 supports only one xpd */
+                       ath5k_hw_rfb_op(ah, rf_regs,
+                                               ee->ee_x_gain[ee_mode],
+                                               AR5K_RF_XPD_GAIN, true);
+
+               } else {
+                       /* TODO: Set high and low gain bits */
+                       ath5k_hw_rfb_op(ah, rf_regs,
+                                               ee->ee_x_gain[ee_mode],
+                                               AR5K_RF_PD_GAIN_LO, true);
+                       ath5k_hw_rfb_op(ah, rf_regs,
+                                               ee->ee_x_gain[ee_mode],
+                                               AR5K_RF_PD_GAIN_HI, true);
+
+                       /* Lower synth voltage on Rev 2 */
+                       ath5k_hw_rfb_op(ah, rf_regs, 2,
+                                       AR5K_RF_HIGH_VC_CP, true);
+
+                       ath5k_hw_rfb_op(ah, rf_regs, 2,
+                                       AR5K_RF_MID_VC_CP, true);
+
+                       ath5k_hw_rfb_op(ah, rf_regs, 2,
+                                       AR5K_RF_LOW_VC_CP, true);
+
+                       ath5k_hw_rfb_op(ah, rf_regs, 2,
+                                       AR5K_RF_PUSH_UP, true);
+
+                       /* Decrease power consumption on 5213+ BaseBand */
+                       if (ah->ah_phy_revision >= AR5K_SREV_PHY_5212A) {
+                               ath5k_hw_rfb_op(ah, rf_regs, 1,
+                                               AR5K_RF_PAD2GND, true);
+
+                               ath5k_hw_rfb_op(ah, rf_regs, 1,
+                                               AR5K_RF_XB2_LVL, true);
+
+                               ath5k_hw_rfb_op(ah, rf_regs, 1,
+                                               AR5K_RF_XB5_LVL, true);
+
+                               ath5k_hw_rfb_op(ah, rf_regs, 1,
+                                               AR5K_RF_PWD_167, true);
+
+                               ath5k_hw_rfb_op(ah, rf_regs, 1,
+                                               AR5K_RF_PWD_166, true);
+                       }
+               }
+
+               ath5k_hw_rfb_op(ah, rf_regs, ee->ee_i_gain[ee_mode],
+                                               AR5K_RF_GAIN_I, true);
+
+               /* TODO: Half/quarter channel support */
+
+       }
+
+       if (ah->ah_radio == AR5K_RF5413 &&
+       channel->hw_value & CHANNEL_2GHZ) {
+
+               ath5k_hw_rfb_op(ah, rf_regs, 1, AR5K_RF_DERBY_CHAN_SEL_MODE,
+                                                                       true);
+
+               /* Set optimum value for early revisions (on pci-e chips) */
+               if (ah->ah_mac_srev >= AR5K_SREV_AR5424 &&
+               ah->ah_mac_srev < AR5K_SREV_AR5413)
+                       ath5k_hw_rfb_op(ah, rf_regs, ath5k_hw_bitswap(6, 3),
+                                               AR5K_RF_PWD_ICLOBUF_2G, true);
+
+       }
+
+       /* Write RF banks on hw */
+       for (i = 0; i < ah->ah_rf_banks_size; i++) {
+               AR5K_REG_WAIT(i);
+               ath5k_hw_reg_write(ah, rfb[i], ini_rfb[i].rfb_ctrl_register);
+       }
+
+       return 0;
+}
+
+
+/**************************\
+  PHY/RF channel functions
+\**************************/
+
+/*
+ * Check if a channel is supported
+ */
+bool ath5k_channel_ok(struct ath5k_hw *ah, u16 freq, unsigned int flags)
+{
+       /* Check if the channel is in our supported range */
+       if (flags & CHANNEL_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)
+               if ((freq >= ah->ah_capabilities.cap_range.range_5ghz_min) &&
+                   (freq <= ah->ah_capabilities.cap_range.range_5ghz_max))
+                       return true;
+
+       return false;
+}
+
+/*
+ * Convertion needed for RF5110
+ */
+static u32 ath5k_hw_rf5110_chan2athchan(struct ieee80211_channel *channel)
+{
+       u32 athchan;
+
+       /*
+        * Convert IEEE channel/MHz to an internal channel value used
+        * by the AR5210 chipset. This has not been verified with
+        * newer chipsets like the AR5212A who have a completely
+        * different RF/PHY part.
+        */
+       athchan = (ath5k_hw_bitswap(
+                       (ieee80211_frequency_to_channel(
+                               channel->center_freq) - 24) / 2, 5)
+                               << 1) | (1 << 6) | 0x1;
+       return athchan;
+}
+
+/*
+ * Set channel on RF5110
+ */
+static int ath5k_hw_rf5110_channel(struct ath5k_hw *ah,
+               struct ieee80211_channel *channel)
+{
+       u32 data;
+
+       /*
+        * Set the channel and wait
+        */
+       data = ath5k_hw_rf5110_chan2athchan(channel);
+       ath5k_hw_reg_write(ah, data, AR5K_RF_BUFFER);
+       ath5k_hw_reg_write(ah, 0, AR5K_RF_BUFFER_CONTROL_0);
+       mdelay(1);
+
+       return 0;
+}
+
+/*
+ * Convertion needed for 5111
+ */
+static int ath5k_hw_rf5111_chan2athchan(unsigned int ieee,
+               struct ath5k_athchan_2ghz *athchan)
+{
+       int channel;
+
+       /* Cast this value to catch negative channel numbers (>= -19) */
+       channel = (int)ieee;
+
+       /*
+        * Map 2GHz IEEE channel to 5GHz Atheros channel
+        */
+       if (channel <= 13) {
+               athchan->a2_athchan = 115 + channel;
+               athchan->a2_flags = 0x46;
+       } else if (channel == 14) {
+               athchan->a2_athchan = 124;
+               athchan->a2_flags = 0x44;
+       } else if (channel >= 15 && channel <= 26) {
+               athchan->a2_athchan = ((channel - 14) * 4) + 132;
+               athchan->a2_flags = 0x46;
+       } else
+               return -EINVAL;
+
+       return 0;
+}
+
+/*
+ * Set channel on 5111
+ */
+static int ath5k_hw_rf5111_channel(struct ath5k_hw *ah,
+               struct ieee80211_channel *channel)
+{
+       struct ath5k_athchan_2ghz ath5k_channel_2ghz;
+       unsigned int ath5k_channel =
+               ieee80211_frequency_to_channel(channel->center_freq);
+       u32 data0, data1, clock;
+       int ret;
+
+       /*
+        * Set the channel on the RF5111 radio
+        */
+       data0 = data1 = 0;
+
+       if (channel->hw_value & CHANNEL_2GHZ) {
+               /* Map 2GHz channel to 5GHz Atheros channel ID */
+               ret = ath5k_hw_rf5111_chan2athchan(
+                       ieee80211_frequency_to_channel(channel->center_freq),
+                       &ath5k_channel_2ghz);
+               if (ret)
+                       return ret;
+
+               ath5k_channel = ath5k_channel_2ghz.a2_athchan;
+               data0 = ((ath5k_hw_bitswap(ath5k_channel_2ghz.a2_flags, 8) & 0xff)
+                   << 5) | (1 << 4);
+       }
+
+       if (ath5k_channel < 145 || !(ath5k_channel & 1)) {
+               clock = 1;
+               data1 = ((ath5k_hw_bitswap(ath5k_channel - 24, 8) & 0xff) << 2) |
+                       (clock << 1) | (1 << 10) | 1;
+       } else {
+               clock = 0;
+               data1 = ((ath5k_hw_bitswap((ath5k_channel - 24) / 2, 8) & 0xff)
+                       << 2) | (clock << 1) | (1 << 10) | 1;
+       }
+
+       ath5k_hw_reg_write(ah, (data1 & 0xff) | ((data0 & 0xff) << 8),
+                       AR5K_RF_BUFFER);
+       ath5k_hw_reg_write(ah, ((data1 >> 8) & 0xff) | (data0 & 0xff00),
+                       AR5K_RF_BUFFER_CONTROL_3);
+
+       return 0;
+}
+
+/*
+ * Set channel on 5112 and newer
+ */
+static int ath5k_hw_rf5112_channel(struct ath5k_hw *ah,
+               struct ieee80211_channel *channel)
+{
+       u32 data, data0, data1, data2;
+       u16 c;
+
+       data = data0 = data1 = data2 = 0;
+       c = channel->center_freq;
+
+       if (c < 4800) {
+               if (!((c - 2224) % 5)) {
+                       data0 = ((2 * (c - 704)) - 3040) / 10;
+                       data1 = 1;
+               } else if (!((c - 2192) % 5)) {
+                       data0 = ((2 * (c - 672)) - 3040) / 10;
+                       data1 = 0;
+               } else
+                       return -EINVAL;
+
+               data0 = ath5k_hw_bitswap((data0 << 2) & 0xff, 8);
+       } else if ((c - (c % 5)) != 2 || c > 5435) {
+               if (!(c % 20) && c >= 5120) {
+                       data0 = ath5k_hw_bitswap(((c - 4800) / 20 << 2), 8);
+                       data2 = ath5k_hw_bitswap(3, 2);
+               } else if (!(c % 10)) {
+                       data0 = ath5k_hw_bitswap(((c - 4800) / 10 << 1), 8);
+                       data2 = ath5k_hw_bitswap(2, 2);
+               } else if (!(c % 5)) {
+                       data0 = ath5k_hw_bitswap((c - 4800) / 5, 8);
+                       data2 = ath5k_hw_bitswap(1, 2);
+               } else
+                       return -EINVAL;
+       } else {
+               data0 = ath5k_hw_bitswap((10 * (c - 2) - 4800) / 25 + 1, 8);
+               data2 = ath5k_hw_bitswap(0, 2);
+       }
+
+       data = (data0 << 4) | (data1 << 1) | (data2 << 2) | 0x1001;
+
+       ath5k_hw_reg_write(ah, data & 0xff, AR5K_RF_BUFFER);
+       ath5k_hw_reg_write(ah, (data >> 8) & 0x7f, AR5K_RF_BUFFER_CONTROL_5);
+
+       return 0;
+}
+
+/*
+ * Set the channel on the RF2425
+ */
+static int ath5k_hw_rf2425_channel(struct ath5k_hw *ah,
+               struct ieee80211_channel *channel)
+{
+       u32 data, data0, data2;
+       u16 c;
+
+       data = data0 = data2 = 0;
+       c = channel->center_freq;
+
+       if (c < 4800) {
+               data0 = ath5k_hw_bitswap((c - 2272), 8);
+               data2 = 0;
+       /* ? 5GHz ? */
+       } else if ((c - (c % 5)) != 2 || c > 5435) {
+               if (!(c % 20) && c < 5120)
+                       data0 = ath5k_hw_bitswap(((c - 4800) / 20 << 2), 8);
+               else if (!(c % 10))
+                       data0 = ath5k_hw_bitswap(((c - 4800) / 10 << 1), 8);
+               else if (!(c % 5))
+                       data0 = ath5k_hw_bitswap((c - 4800) / 5, 8);
+               else
+                       return -EINVAL;
+               data2 = ath5k_hw_bitswap(1, 2);
+       } else {
+               data0 = ath5k_hw_bitswap((10 * (c - 2) - 4800) / 25 + 1, 8);
+               data2 = ath5k_hw_bitswap(0, 2);
+       }
+
+       data = (data0 << 4) | data2 << 2 | 0x1001;
+
+       ath5k_hw_reg_write(ah, data & 0xff, AR5K_RF_BUFFER);
+       ath5k_hw_reg_write(ah, (data >> 8) & 0x7f, AR5K_RF_BUFFER_CONTROL_5);
+
+       return 0;
+}
+
+/*
+ * Set a channel on the radio chip
+ */
+int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel)
+{
+       int ret;
+       /*
+        * Check bounds supported by the PHY (we don't care about regultory
+        * 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)) {
+               ATH5K_ERR(ah->ah_sc,
+                       "channel frequency (%u MHz) out of supported "
+                       "band range\n",
+                       channel->center_freq);
+                       return -EINVAL;
+       }
+
+       /*
+        * Set the channel and wait
+        */
+       switch (ah->ah_radio) {
+       case AR5K_RF5110:
+               ret = ath5k_hw_rf5110_channel(ah, channel);
+               break;
+       case AR5K_RF5111:
+               ret = ath5k_hw_rf5111_channel(ah, channel);
+               break;
+       case AR5K_RF2425:
+               ret = ath5k_hw_rf2425_channel(ah, channel);
+               break;
+       default:
+               ret = ath5k_hw_rf5112_channel(ah, channel);
+               break;
+       }
+
+       if (ret)
+               return ret;
+
+       /* Set JAPAN setting for channel 14 */
+       if (channel->center_freq == 2484) {
+               AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_CCKTXCTL,
+                               AR5K_PHY_CCKTXCTL_JAPAN);
+       } else {
+               AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_CCKTXCTL,
+                               AR5K_PHY_CCKTXCTL_WORLD);
+       }
+
+       ah->ah_current_channel.center_freq = channel->center_freq;
+       ah->ah_current_channel.hw_value = channel->hw_value;
+       ah->ah_turbo = channel->hw_value == CHANNEL_T ? true : false;
+
+       return 0;
+}
+
+/*****************\
+  PHY calibration
+\*****************/
+
+/**
+ * ath5k_hw_noise_floor_calibration - perform PHY noise floor calibration
+ *
+ * @ah: struct ath5k_hw pointer we are operating on
+ * @freq: the channel frequency, just used for error logging
+ *
+ * This function performs a noise floor calibration of the PHY and waits for
+ * it to complete. Then the noise floor value is compared to some maximum
+ * noise floor we consider valid.
+ *
+ * Note that this is different from what the madwifi HAL does: it reads the
+ * noise floor and afterwards initiates the calibration. Since the noise floor
+ * calibration can take some time to finish, depending on the current channel
+ * use, that avoids the occasional timeout warnings we are seeing now.
+ *
+ * See the following link for an Atheros patent on noise floor calibration:
+ * http://patft.uspto.gov/netacgi/nph-Parser?Sect1=PTO1&Sect2=HITOFF&d=PALL \
+ * &p=1&u=%2Fnetahtml%2FPTO%2Fsrchnum.htm&r=1&f=G&l=50&s1=7245893.PN.&OS=PN/7
+ *
+ * XXX: Since during noise floor calibration antennas are detached according to
+ * the patent, we should stop tx queues here.
+ */
+int
+ath5k_hw_noise_floor_calibration(struct ath5k_hw *ah, short freq)
+{
+       int ret;
+       unsigned int i;
+       s32 noise_floor;
+
+       /*
+        * Enable noise floor calibration
+        */
+       AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
+                               AR5K_PHY_AGCCTL_NF);
+
+       ret = ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL,
+                       AR5K_PHY_AGCCTL_NF, 0, false);
+       if (ret) {
+               ATH5K_ERR(ah->ah_sc,
+                       "noise floor calibration timeout (%uMHz)\n", freq);
+               return -EAGAIN;
+       }
+
+       /* Wait until the noise floor is calibrated and read the value */
+       for (i = 20; i > 0; i--) {
+               mdelay(1);
+               noise_floor = ath5k_hw_reg_read(ah, AR5K_PHY_NF);
+               noise_floor = AR5K_PHY_NF_RVAL(noise_floor);
+               if (noise_floor & AR5K_PHY_NF_ACTIVE) {
+                       noise_floor = AR5K_PHY_NF_AVAL(noise_floor);
+
+                       if (noise_floor <= AR5K_TUNE_NOISE_FLOOR)
+                               break;
+               }
+       }
+
+       ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_CALIBRATE,
+               "noise floor %d\n", noise_floor);
+
+       if (noise_floor > AR5K_TUNE_NOISE_FLOOR) {
+               ATH5K_ERR(ah->ah_sc,
+                       "noise floor calibration failed (%uMHz)\n", freq);
+               return -EAGAIN;
+       }
+
+       ah->ah_noise_floor = noise_floor;
+
+       return 0;
+}
+
+/*
+ * Perform a PHY calibration on RF5110
+ * -Fix BPSK/QAM Constellation (I/Q correction)
+ * -Calculate Noise Floor
+ */
+static int ath5k_hw_rf5110_calibrate(struct ath5k_hw *ah,
+               struct ieee80211_channel *channel)
+{
+       u32 phy_sig, phy_agc, phy_sat, beacon;
+       int ret;
+
+       /*
+        * Disable beacons and RX/TX queues, wait
+        */
+       AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW_5210,
+               AR5K_DIAG_SW_DIS_TX | AR5K_DIAG_SW_DIS_RX_5210);
+       beacon = ath5k_hw_reg_read(ah, AR5K_BEACON_5210);
+       ath5k_hw_reg_write(ah, beacon & ~AR5K_BEACON_ENABLE, AR5K_BEACON_5210);
+
+       mdelay(2);
+
+       /*
+        * Set the channel (with AGC turned off)
+        */
+       AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGC, AR5K_PHY_AGC_DISABLE);
+       udelay(10);
+       ret = ath5k_hw_channel(ah, channel);
+
+       /*
+        * Activate PHY and wait
+        */
+       ath5k_hw_reg_write(ah, AR5K_PHY_ACT_ENABLE, AR5K_PHY_ACT);
+       mdelay(1);
+
+       AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_AGC, AR5K_PHY_AGC_DISABLE);
+
+       if (ret)
+               return ret;
+
+       /*
+        * Calibrate the radio chip
+        */
+
+       /* Remember normal state */
+       phy_sig = ath5k_hw_reg_read(ah, AR5K_PHY_SIG);
+       phy_agc = ath5k_hw_reg_read(ah, AR5K_PHY_AGCCOARSE);
+       phy_sat = ath5k_hw_reg_read(ah, AR5K_PHY_ADCSAT);
+
+       /* Update radio registers */
+       ath5k_hw_reg_write(ah, (phy_sig & ~(AR5K_PHY_SIG_FIRPWR)) |
+               AR5K_REG_SM(-1, AR5K_PHY_SIG_FIRPWR), AR5K_PHY_SIG);
+
+       ath5k_hw_reg_write(ah, (phy_agc & ~(AR5K_PHY_AGCCOARSE_HI |
+                       AR5K_PHY_AGCCOARSE_LO)) |
+               AR5K_REG_SM(-1, AR5K_PHY_AGCCOARSE_HI) |
+               AR5K_REG_SM(-127, AR5K_PHY_AGCCOARSE_LO), AR5K_PHY_AGCCOARSE);
+
+       ath5k_hw_reg_write(ah, (phy_sat & ~(AR5K_PHY_ADCSAT_ICNT |
+                       AR5K_PHY_ADCSAT_THR)) |
+               AR5K_REG_SM(2, AR5K_PHY_ADCSAT_ICNT) |
+               AR5K_REG_SM(12, AR5K_PHY_ADCSAT_THR), AR5K_PHY_ADCSAT);
+
+       udelay(20);
+
+       AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGC, AR5K_PHY_AGC_DISABLE);
+       udelay(10);
+       ath5k_hw_reg_write(ah, AR5K_PHY_RFSTG_DISABLE, AR5K_PHY_RFSTG);
+       AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_AGC, AR5K_PHY_AGC_DISABLE);
+
+       mdelay(1);
+
+       /*
+        * Enable calibration and wait until completion
+        */
+       AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL, AR5K_PHY_AGCCTL_CAL);
+
+       ret = ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL,
+                       AR5K_PHY_AGCCTL_CAL, 0, false);
+
+       /* Reset to normal state */
+       ath5k_hw_reg_write(ah, phy_sig, AR5K_PHY_SIG);
+       ath5k_hw_reg_write(ah, phy_agc, AR5K_PHY_AGCCOARSE);
+       ath5k_hw_reg_write(ah, phy_sat, AR5K_PHY_ADCSAT);
+
+       if (ret) {
+               ATH5K_ERR(ah->ah_sc, "calibration timeout (%uMHz)\n",
+                               channel->center_freq);
+               return ret;
+       }
+
+       ath5k_hw_noise_floor_calibration(ah, channel->center_freq);
+
+       /*
+        * Re-enable RX/TX and beacons
+        */
+       AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW_5210,
+               AR5K_DIAG_SW_DIS_TX | AR5K_DIAG_SW_DIS_RX_5210);
+       ath5k_hw_reg_write(ah, beacon, AR5K_BEACON_5210);
+
+       return 0;
+}
+
+/*
+ * Perform a PHY calibration on RF5111/5112 and newer chips
+ */
+static int ath5k_hw_rf511x_calibrate(struct ath5k_hw *ah,
+               struct ieee80211_channel *channel)
+{
+       u32 i_pwr, q_pwr;
+       s32 iq_corr, i_coff, i_coffd, q_coff, q_coffd;
+       int i;
+       ATH5K_TRACE(ah->ah_sc);
+
+       if (!ah->ah_calibration ||
+               ath5k_hw_reg_read(ah, AR5K_PHY_IQ) & AR5K_PHY_IQ_RUN)
+               goto done;
+
+       /* Calibration has finished, get the results and re-run */
+       for (i = 0; i <= 10; i++) {
+               iq_corr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_CORR);
+               i_pwr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_PWR_I);
+               q_pwr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_PWR_Q);
+       }
+
+       i_coffd = ((i_pwr >> 1) + (q_pwr >> 1)) >> 7;
+       q_coffd = q_pwr >> 7;
+
+       /* No correction */
+       if (i_coffd == 0 || q_coffd == 0)
+               goto done;
+
+       i_coff = ((-iq_corr) / i_coffd) & 0x3f;
+
+       /* Boundary check */
+       if (i_coff > 31)
+               i_coff = 31;
+       if (i_coff < -32)
+               i_coff = -32;
+
+       q_coff = (((s32)i_pwr / q_coffd) - 128) & 0x1f;
+
+       /* Boundary check */
+       if (q_coff > 15)
+               q_coff = 15;
+       if (q_coff < -16)
+               q_coff = -16;
+
+       /* Commit new I/Q value */
+       AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_ENABLE |
+               ((u32)q_coff) | ((u32)i_coff << AR5K_PHY_IQ_CORR_Q_I_COFF_S));
+
+       /* Re-enable calibration -if we don't we'll commit
+        * the same values again and again */
+       AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ,
+                       AR5K_PHY_IQ_CAL_NUM_LOG_MAX, 15);
+       AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_RUN);
+
+done:
+
+       /* TODO: Separate noise floor calibration from I/Q calibration
+        * since noise floor calibration interrupts rx path while I/Q
+        * calibration doesn't. We don't need to run noise floor calibration
+        * as often as I/Q calibration.*/
+       ath5k_hw_noise_floor_calibration(ah, channel->center_freq);
+
+       /* Initiate a gain_F calibration */
+       ath5k_hw_request_rfgain_probe(ah);
+
+       return 0;
+}
+
+/*
+ * Perform a PHY calibration
+ */
+int ath5k_hw_phy_calibrate(struct ath5k_hw *ah,
+               struct ieee80211_channel *channel)
+{
+       int ret;
+
+       if (ah->ah_radio == AR5K_RF5110)
+               ret = ath5k_hw_rf5110_calibrate(ah, channel);
+       else
+               ret = ath5k_hw_rf511x_calibrate(ah, channel);
+
+       return ret;
+}
+
+/***************************\
+* Spur mitigation functions *
+\***************************/
+
+bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah,
+                               struct ieee80211_channel *channel)
+{
+       u8 refclk_freq;
+
+       if ((ah->ah_radio == AR5K_RF5112) ||
+       (ah->ah_radio == AR5K_RF5413) ||
+       (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))
+               refclk_freq = 40;
+       else
+               refclk_freq = 32;
+
+       if ((channel->center_freq % refclk_freq != 0) &&
+       ((channel->center_freq % refclk_freq < 10) ||
+       (channel->center_freq % refclk_freq > 22)))
+               return true;
+       else
+               return false;
+}
+
+void
+ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah,
+                               struct ieee80211_channel *channel)
+{
+       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+       u32 mag_mask[4] = {0, 0, 0, 0};
+       u32 pilot_mask[2] = {0, 0};
+       /* Note: fbin values are scaled up by 2 */
+       u16 spur_chan_fbin, chan_fbin, symbol_width, spur_detection_window;
+       s32 spur_delta_phase, spur_freq_sigma_delta;
+       s32 spur_offset, num_symbols_x16;
+       u8 num_symbol_offsets, i, freq_band;
+
+       /* 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) {
+               chan_fbin = (channel->center_freq - 2300) * 10;
+               freq_band = AR5K_EEPROM_BAND_2GHZ;
+       } else {
+               chan_fbin = (channel->center_freq - 4900) * 10;
+               freq_band = AR5K_EEPROM_BAND_5GHZ;
+       }
+
+       /* Check if any spur_chan_fbin from EEPROM is
+        * within our current channel's spur detection range */
+       spur_chan_fbin = AR5K_EEPROM_NO_SPUR;
+       spur_detection_window = AR5K_SPUR_CHAN_WIDTH;
+       /* XXX: Half/Quarter channels ?*/
+       if (channel->hw_value & CHANNEL_TURBO)
+               spur_detection_window *= 2;
+
+       for (i = 0; i < AR5K_EEPROM_N_SPUR_CHANS; i++) {
+               spur_chan_fbin = ee->ee_spur_chans[i][freq_band];
+
+               /* Note: mask cleans AR5K_EEPROM_NO_SPUR flag
+                * so it's zero if we got nothing from EEPROM */
+               if (spur_chan_fbin == AR5K_EEPROM_NO_SPUR) {
+                       spur_chan_fbin &= AR5K_EEPROM_SPUR_CHAN_MASK;
+                       break;
+               }
+
+               if ((chan_fbin - spur_detection_window <=
+               (spur_chan_fbin & AR5K_EEPROM_SPUR_CHAN_MASK)) &&
+               (chan_fbin + spur_detection_window >=
+               (spur_chan_fbin & AR5K_EEPROM_SPUR_CHAN_MASK))) {
+                       spur_chan_fbin &= AR5K_EEPROM_SPUR_CHAN_MASK;
+                       break;
+               }
+       }
+
+       /* We need to enable spur filter for this channel */
+       if (spur_chan_fbin) {
+               spur_offset = spur_chan_fbin - chan_fbin;
+               /*
+                * Calculate deltas:
+                * spur_freq_sigma_delta -> spur_offset / sample_freq << 21
+                * spur_delta_phase -> spur_offset / chip_freq << 11
+                * Note: Both values have 100KHz resolution
+                */
+               /* XXX: Half/Quarter rate channels ? */
+               switch (channel->hw_value) {
+               case CHANNEL_A:
+                       /* Both sample_freq and chip_freq are 40MHz */
+                       spur_delta_phase = (spur_offset << 17) / 25;
+                       spur_freq_sigma_delta = (spur_delta_phase >> 10);
+                       symbol_width = AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz;
+                       break;
+               case CHANNEL_G:
+                       /* sample_freq -> 40MHz chip_freq -> 44MHz
+                        * (for b compatibility) */
+                       spur_freq_sigma_delta = (spur_offset << 8) / 55;
+                       spur_delta_phase = (spur_offset << 17) / 25;
+                       symbol_width = AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz;
+                       break;
+               case CHANNEL_T:
+               case CHANNEL_TG:
+                       /* Both sample_freq and chip_freq are 80MHz */
+                       spur_delta_phase = (spur_offset << 16) / 25;
+                       spur_freq_sigma_delta = (spur_delta_phase >> 10);
+                       symbol_width = AR5K_SPUR_SYMBOL_WIDTH_TURBO_100Hz;
+                       break;
+               default:
+                       return;
+               }
+
+               /* Calculate pilot and magnitude masks */
+
+               /* Scale up spur_offset by 1000 to switch to 100HZ resolution
+                * and divide by symbol_width to find how many symbols we have
+                * Note: number of symbols is scaled up by 16 */
+               num_symbols_x16 = ((spur_offset * 1000) << 4) / symbol_width;
+
+               /* Spur is on a symbol if num_symbols_x16 % 16 is zero */
+               if (!(num_symbols_x16 & 0xF))
+                       /* _X_ */
+                       num_symbol_offsets = 3;
+               else
+                       /* _xx_ */
+                       num_symbol_offsets = 4;
+
+               for (i = 0; i < num_symbol_offsets; i++) {
+
+                       /* Calculate pilot mask */
+                       s32 curr_sym_off =
+                               (num_symbols_x16 / 16) + i + 25;
+
+                       /* Pilot magnitude mask seems to be a way to
+                        * declare the boundaries for our detection
+                        * window or something, it's 2 for the middle
+                        * value(s) where the symbol is expected to be
+                        * and 1 on the boundary values */
+                       u8 plt_mag_map =
+                               (i == 0 || i == (num_symbol_offsets - 1))
+                                                               ? 1 : 2;
+
+                       if (curr_sym_off >= 0 && curr_sym_off <= 32) {
+                               if (curr_sym_off <= 25)
+                                       pilot_mask[0] |= 1 << curr_sym_off;
+                               else if (curr_sym_off >= 27)
+                                       pilot_mask[0] |= 1 << (curr_sym_off - 1);
+                       } else if (curr_sym_off >= 33 && curr_sym_off <= 52)
+                               pilot_mask[1] |= 1 << (curr_sym_off - 33);
+
+                       /* Calculate magnitude mask (for viterbi decoder) */
+                       if (curr_sym_off >= -1 && curr_sym_off <= 14)
+                               mag_mask[0] |=
+                                       plt_mag_map << (curr_sym_off + 1) * 2;
+                       else if (curr_sym_off >= 15 && curr_sym_off <= 30)
+                               mag_mask[1] |=
+                                       plt_mag_map << (curr_sym_off - 15) * 2;
+                       else if (curr_sym_off >= 31 && curr_sym_off <= 46)
+                               mag_mask[2] |=
+                                       plt_mag_map << (curr_sym_off - 31) * 2;
+                       else if (curr_sym_off >= 46 && curr_sym_off <= 53)
+                               mag_mask[3] |=
+                                       plt_mag_map << (curr_sym_off - 47) * 2;
+
+               }
+
+               /* Write settings on hw to enable spur filter */
+               AR5K_REG_WRITE_BITS(ah, AR5K_PHY_BIN_MASK_CTL,
+                                       AR5K_PHY_BIN_MASK_CTL_RATE, 0xff);
+               /* XXX: Self correlator also ? */
+               AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ,
+                                       AR5K_PHY_IQ_PILOT_MASK_EN |
+                                       AR5K_PHY_IQ_CHAN_MASK_EN |
+                                       AR5K_PHY_IQ_SPUR_FILT_EN);
+
+               /* Set delta phase and freq sigma delta */
+               ath5k_hw_reg_write(ah,
+                               AR5K_REG_SM(spur_delta_phase,
+                                       AR5K_PHY_TIMING_11_SPUR_DELTA_PHASE) |
+                               AR5K_REG_SM(spur_freq_sigma_delta,
+                               AR5K_PHY_TIMING_11_SPUR_FREQ_SD) |
+                               AR5K_PHY_TIMING_11_USE_SPUR_IN_AGC,
+                               AR5K_PHY_TIMING_11);
+
+               /* Write pilot masks */
+               ath5k_hw_reg_write(ah, pilot_mask[0], AR5K_PHY_TIMING_7);
+               AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_8,
+                                       AR5K_PHY_TIMING_8_PILOT_MASK_2,
+                                       pilot_mask[1]);
+
+               ath5k_hw_reg_write(ah, pilot_mask[0], AR5K_PHY_TIMING_9);
+               AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_10,
+                                       AR5K_PHY_TIMING_10_PILOT_MASK_2,
+                                       pilot_mask[1]);
+
+               /* Write magnitude masks */
+               ath5k_hw_reg_write(ah, mag_mask[0], AR5K_PHY_BIN_MASK_1);
+               ath5k_hw_reg_write(ah, mag_mask[1], AR5K_PHY_BIN_MASK_2);
+               ath5k_hw_reg_write(ah, mag_mask[2], AR5K_PHY_BIN_MASK_3);
+               AR5K_REG_WRITE_BITS(ah, AR5K_PHY_BIN_MASK_CTL,
+                                       AR5K_PHY_BIN_MASK_CTL_MASK_4,
+                                       mag_mask[3]);
+
+               ath5k_hw_reg_write(ah, mag_mask[0], AR5K_PHY_BIN_MASK2_1);
+               ath5k_hw_reg_write(ah, mag_mask[1], AR5K_PHY_BIN_MASK2_2);
+               ath5k_hw_reg_write(ah, mag_mask[2], AR5K_PHY_BIN_MASK2_3);
+               AR5K_REG_WRITE_BITS(ah, AR5K_PHY_BIN_MASK2_4,
+                                       AR5K_PHY_BIN_MASK2_4_MASK_4,
+                                       mag_mask[3]);
+
+       } else if (ath5k_hw_reg_read(ah, AR5K_PHY_IQ) &
+       AR5K_PHY_IQ_SPUR_FILT_EN) {
+               /* Clean up spur mitigation settings and disable fliter */
+               AR5K_REG_WRITE_BITS(ah, AR5K_PHY_BIN_MASK_CTL,
+                                       AR5K_PHY_BIN_MASK_CTL_RATE, 0);
+               AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_IQ,
+                                       AR5K_PHY_IQ_PILOT_MASK_EN |
+                                       AR5K_PHY_IQ_CHAN_MASK_EN |
+                                       AR5K_PHY_IQ_SPUR_FILT_EN);
+               ath5k_hw_reg_write(ah, 0, AR5K_PHY_TIMING_11);
+
+               /* Clear pilot masks */
+               ath5k_hw_reg_write(ah, 0, AR5K_PHY_TIMING_7);
+               AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_8,
+                                       AR5K_PHY_TIMING_8_PILOT_MASK_2,
+                                       0);
+
+               ath5k_hw_reg_write(ah, 0, AR5K_PHY_TIMING_9);
+               AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_10,
+                                       AR5K_PHY_TIMING_10_PILOT_MASK_2,
+                                       0);
+
+               /* Clear magnitude masks */
+               ath5k_hw_reg_write(ah, 0, AR5K_PHY_BIN_MASK_1);
+               ath5k_hw_reg_write(ah, 0, AR5K_PHY_BIN_MASK_2);
+               ath5k_hw_reg_write(ah, 0, AR5K_PHY_BIN_MASK_3);
+               AR5K_REG_WRITE_BITS(ah, AR5K_PHY_BIN_MASK_CTL,
+                                       AR5K_PHY_BIN_MASK_CTL_MASK_4,
+                                       0);
+
+               ath5k_hw_reg_write(ah, 0, AR5K_PHY_BIN_MASK2_1);
+               ath5k_hw_reg_write(ah, 0, AR5K_PHY_BIN_MASK2_2);
+               ath5k_hw_reg_write(ah, 0, AR5K_PHY_BIN_MASK2_3);
+               AR5K_REG_WRITE_BITS(ah, AR5K_PHY_BIN_MASK2_4,
+                                       AR5K_PHY_BIN_MASK2_4_MASK_4,
+                                       0);
+       }
+}
+
+/********************\
+  Misc PHY functions
+\********************/
+
+int ath5k_hw_phy_disable(struct ath5k_hw *ah)
+{
+       ATH5K_TRACE(ah->ah_sc);
+       /*Just a try M.F.*/
+       ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT);
+
+       return 0;
+}
+
+/*
+ * Get the PHY Chip revision
+ */
+u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan)
+{
+       unsigned int i;
+       u32 srev;
+       u16 ret;
+
+       ATH5K_TRACE(ah->ah_sc);
+
+       /*
+        * Set the radio chip access register
+        */
+       switch (chan) {
+       case CHANNEL_2GHZ:
+               ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_2GHZ, AR5K_PHY(0));
+               break;
+       case CHANNEL_5GHZ:
+               ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0));
+               break;
+       default:
+               return 0;
+       }
+
+       mdelay(2);
+
+       /* ...wait until PHY is ready and read the selected radio revision */
+       ath5k_hw_reg_write(ah, 0x00001c16, AR5K_PHY(0x34));
+
+       for (i = 0; i < 8; i++)
+               ath5k_hw_reg_write(ah, 0x00010000, AR5K_PHY(0x20));
+
+       if (ah->ah_version == AR5K_AR5210) {
+               srev = ath5k_hw_reg_read(ah, AR5K_PHY(256) >> 28) & 0xf;
+               ret = (u16)ath5k_hw_bitswap(srev, 4) + 1;
+       } else {
+               srev = (ath5k_hw_reg_read(ah, AR5K_PHY(0x100)) >> 24) & 0xff;
+               ret = (u16)ath5k_hw_bitswap(((srev & 0xf0) >> 4) |
+                               ((srev & 0x0f) << 4), 8);
+       }
+
+       /* Reset to the 5GHz mode */
+       ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0));
+
+       return ret;
+}
+
+/*****************\
+* Antenna control *
+\*****************/
+
+void /*TODO:Boundary check*/
+ath5k_hw_set_def_antenna(struct ath5k_hw *ah, u8 ant)
+{
+       ATH5K_TRACE(ah->ah_sc);
+
+       if (ah->ah_version != AR5K_AR5210)
+               ath5k_hw_reg_write(ah, ant & 0x7, AR5K_DEFAULT_ANTENNA);
+}
+
+unsigned int ath5k_hw_get_def_antenna(struct ath5k_hw *ah)
+{
+       ATH5K_TRACE(ah->ah_sc);
+
+       if (ah->ah_version != AR5K_AR5210)
+               return ath5k_hw_reg_read(ah, AR5K_DEFAULT_ANTENNA) & 0x7;
+
+       return false; /*XXX: What do we return for 5210 ?*/
+}
+
+/*
+ * Enable/disable fast rx antenna diversity
+ */
+static void
+ath5k_hw_set_fast_div(struct ath5k_hw *ah, u8 ee_mode, bool enable)
+{
+       switch (ee_mode) {
+       case AR5K_EEPROM_MODE_11G:
+               /* XXX: This is set to
+                * disabled on initvals !!! */
+       case AR5K_EEPROM_MODE_11A:
+               if (enable)
+                       AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_AGCCTL,
+                                       AR5K_PHY_AGCCTL_OFDM_DIV_DIS);
+               else
+                       AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
+                                       AR5K_PHY_AGCCTL_OFDM_DIV_DIS);
+               break;
+       case AR5K_EEPROM_MODE_11B:
+               AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
+                                       AR5K_PHY_AGCCTL_OFDM_DIV_DIS);
+               break;
+       default:
+               return;
+       }
+
+       if (enable) {
+               AR5K_REG_WRITE_BITS(ah, AR5K_PHY_RESTART,
+                               AR5K_PHY_RESTART_DIV_GC, 0xc);
+
+               AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_FAST_ANT_DIV,
+                                       AR5K_PHY_FAST_ANT_DIV_EN);
+       } else {
+               AR5K_REG_WRITE_BITS(ah, AR5K_PHY_RESTART,
+                               AR5K_PHY_RESTART_DIV_GC, 0x8);
+
+               AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_FAST_ANT_DIV,
+                                       AR5K_PHY_FAST_ANT_DIV_EN);
+       }
+}
+
+/*
+ * Set antenna operating mode
+ */
+void
+ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode)
+{
+       struct ieee80211_channel *channel = &ah->ah_current_channel;
+       bool use_def_for_tx, update_def_on_tx, use_def_for_rts, fast_div;
+       bool use_def_for_sg;
+       u8 def_ant, tx_ant, ee_mode;
+       u32 sta_id1 = 0;
+
+       def_ant = ah->ah_def_ant;
+
+       ATH5K_TRACE(ah->ah_sc);
+
+       switch (channel->hw_value & CHANNEL_MODES) {
+       case CHANNEL_A:
+       case CHANNEL_T:
+       case CHANNEL_XR:
+               ee_mode = AR5K_EEPROM_MODE_11A;
+               break;
+       case CHANNEL_G:
+       case CHANNEL_TG:
+               ee_mode = AR5K_EEPROM_MODE_11G;
+               break;
+       case CHANNEL_B:
+               ee_mode = AR5K_EEPROM_MODE_11B;
+               break;
+       default:
+               ATH5K_ERR(ah->ah_sc,
+                       "invalid channel: %d\n", channel->center_freq);
+               return;
+       }
+
+       switch (ant_mode) {
+       case AR5K_ANTMODE_DEFAULT:
+               tx_ant = 0;
+               use_def_for_tx = false;
+               update_def_on_tx = false;
+               use_def_for_rts = false;
+               use_def_for_sg = false;
+               fast_div = true;
+               break;
+       case AR5K_ANTMODE_FIXED_A:
+               def_ant = 1;
+               tx_ant = 0;
+               use_def_for_tx = true;
+               update_def_on_tx = false;
+               use_def_for_rts = true;
+               use_def_for_sg = true;
+               fast_div = false;
+               break;
+       case AR5K_ANTMODE_FIXED_B:
+               def_ant = 2;
+               tx_ant = 0;
+               use_def_for_tx = true;
+               update_def_on_tx = false;
+               use_def_for_rts = true;
+               use_def_for_sg = true;
+               fast_div = false;
+               break;
+       case AR5K_ANTMODE_SINGLE_AP:
+               def_ant = 1;    /* updated on tx */
+               tx_ant = 0;
+               use_def_for_tx = true;
+               update_def_on_tx = true;
+               use_def_for_rts = true;
+               use_def_for_sg = true;
+               fast_div = true;
+               break;
+       case AR5K_ANTMODE_SECTOR_AP:
+               tx_ant = 1;     /* variable */
+               use_def_for_tx = false;
+               update_def_on_tx = false;
+               use_def_for_rts = true;
+               use_def_for_sg = false;
+               fast_div = false;
+               break;
+       case AR5K_ANTMODE_SECTOR_STA:
+               tx_ant = 1;     /* variable */
+               use_def_for_tx = true;
+               update_def_on_tx = false;
+               use_def_for_rts = true;
+               use_def_for_sg = false;
+               fast_div = true;
+               break;
+       case AR5K_ANTMODE_DEBUG:
+               def_ant = 1;
+               tx_ant = 2;
+               use_def_for_tx = false;
+               update_def_on_tx = false;
+               use_def_for_rts = false;
+               use_def_for_sg = false;
+               fast_div = false;
+               break;
+       default:
+               return;
+       }
+
+       ah->ah_tx_ant = tx_ant;
+       ah->ah_ant_mode = ant_mode;
+
+       sta_id1 |= use_def_for_tx ? AR5K_STA_ID1_DEFAULT_ANTENNA : 0;
+       sta_id1 |= update_def_on_tx ? AR5K_STA_ID1_DESC_ANTENNA : 0;
+       sta_id1 |= use_def_for_rts ? AR5K_STA_ID1_RTS_DEF_ANTENNA : 0;
+       sta_id1 |= use_def_for_sg ? AR5K_STA_ID1_SELFGEN_DEF_ANT : 0;
+
+       AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, AR5K_STA_ID1_ANTENNA_SETTINGS);
+
+       if (sta_id1)
+               AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1, sta_id1);
+
+       /* Note: set diversity before default antenna
+        * because it won't work correctly */
+       ath5k_hw_set_fast_div(ah, ee_mode, fast_div);
+       ath5k_hw_set_def_antenna(ah, def_ant);
+}
+
+
+/****************\
+* TX power setup *
+\****************/
+
+/*
+ * Helper functions
+ */
+
+/*
+ * Do linear interpolation between two given (x, y) points
+ */
+static s16
+ath5k_get_interpolated_value(s16 target, s16 x_left, s16 x_right,
+                                       s16 y_left, s16 y_right)
+{
+       s16 ratio, result;
+
+       /* Avoid divide by zero and skip interpolation
+        * if we have the same point */
+       if ((x_left == x_right) || (y_left == y_right))
+               return y_left;
+
+       /*
+        * Since we use ints and not fps, we need to scale up in
+        * order to get a sane ratio value (or else we 'll eg. get
+        * always 1 instead of 1.25, 1.75 etc). We scale up by 100
+        * to have some accuracy both for 0.5 and 0.25 steps.
+        */
+       ratio = ((100 * y_right - 100 * y_left)/(x_right - x_left));
+
+       /* Now scale down to be in range */
+       result = y_left + (ratio * (target - x_left) / 100);
+
+       return result;
+}
+
+/*
+ * Find vertical boundary (min pwr) for the linear PCDAC curve.
+ *
+ * Since we have the top of the curve and we draw the line below
+ * until we reach 1 (1 pcdac step) we need to know which point
+ * (x value) that is so that we don't go below y axis and have negative
+ * pcdac values when creating the curve, or fill the table with zeroes.
+ */
+static s16
+ath5k_get_linear_pcdac_min(const u8 *stepL, const u8 *stepR,
+                               const s16 *pwrL, const s16 *pwrR)
+{
+       s8 tmp;
+       s16 min_pwrL, min_pwrR;
+       s16 pwr_i;
+
+       if (WARN_ON(stepL[0] == stepL[1] || stepR[0] == stepR[1]))
+               return 0;
+
+       if (pwrL[0] == pwrL[1])
+               min_pwrL = pwrL[0];
+       else {
+               pwr_i = pwrL[0];
+               do {
+                       pwr_i--;
+                       tmp = (s8) ath5k_get_interpolated_value(pwr_i,
+                                                       pwrL[0], pwrL[1],
+                                                       stepL[0], stepL[1]);
+               } while (tmp > 1);
+
+               min_pwrL = pwr_i;
+       }
+
+       if (pwrR[0] == pwrR[1])
+               min_pwrR = pwrR[0];
+       else {
+               pwr_i = pwrR[0];
+               do {
+                       pwr_i--;
+                       tmp = (s8) ath5k_get_interpolated_value(pwr_i,
+                                                       pwrR[0], pwrR[1],
+                                                       stepR[0], stepR[1]);
+               } while (tmp > 1);
+
+               min_pwrR = pwr_i;
+       }
+
+       /* Keep the right boundary so that it works for both curves */
+       return max(min_pwrL, min_pwrR);
+}
+
+/*
+ * Interpolate (pwr,vpd) points to create a Power to PDADC or a
+ * Power to PCDAC curve.
+ *
+ * Each curve has power on x axis (in 0.5dB units) and PCDAC/PDADC
+ * steps (offsets) on y axis. Power can go up to 31.5dB and max
+ * PCDAC/PDADC step for each curve is 64 but we can write more than
+ * one curves on hw so we can go up to 128 (which is the max step we
+ * can write on the final table).
+ *
+ * We write y values (PCDAC/PDADC steps) on hw.
+ */
+static void
+ath5k_create_power_curve(s16 pmin, s16 pmax,
+                       const s16 *pwr, const u8 *vpd,
+                       u8 num_points,
+                       u8 *vpd_table, u8 type)
+{
+       u8 idx[2] = { 0, 1 };
+       s16 pwr_i = 2*pmin;
+       int i;
+
+       if (num_points < 2)
+               return;
+
+       /* We want the whole line, so adjust boundaries
+        * to cover the entire power range. Note that
+        * power values are already 0.25dB so no need
+        * to multiply pwr_i by 2 */
+       if (type == AR5K_PWRTABLE_LINEAR_PCDAC) {
+               pwr_i = pmin;
+               pmin = 0;
+               pmax = 63;
+       }
+
+       /* Find surrounding turning points (TPs)
+        * and interpolate between them */
+       for (i = 0; (i <= (u16) (pmax - pmin)) &&
+       (i < AR5K_EEPROM_POWER_TABLE_SIZE); i++) {
+
+               /* We passed the right TP, move to the next set of TPs
+                * if we pass the last TP, extrapolate above using the last
+                * two TPs for ratio */
+               if ((pwr_i > pwr[idx[1]]) && (idx[1] < num_points - 1)) {
+                       idx[0]++;
+                       idx[1]++;
+               }
+
+               vpd_table[i] = (u8) ath5k_get_interpolated_value(pwr_i,
+                                               pwr[idx[0]], pwr[idx[1]],
+                                               vpd[idx[0]], vpd[idx[1]]);
+
+               /* Increase by 0.5dB
+                * (0.25 dB units) */
+               pwr_i += 2;
+       }
+}
+
+/*
+ * Get the surrounding per-channel power calibration piers
+ * for a given frequency so that we can interpolate between
+ * them and come up with an apropriate dataset for our current
+ * channel.
+ */
+static void
+ath5k_get_chan_pcal_surrounding_piers(struct ath5k_hw *ah,
+                       struct ieee80211_channel *channel,
+                       struct ath5k_chan_pcal_info **pcinfo_l,
+                       struct ath5k_chan_pcal_info **pcinfo_r)
+{
+       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+       struct ath5k_chan_pcal_info *pcinfo;
+       u8 idx_l, idx_r;
+       u8 mode, max, i;
+       u32 target = channel->center_freq;
+
+       idx_l = 0;
+       idx_r = 0;
+
+       if (!(channel->hw_value & CHANNEL_OFDM)) {
+               pcinfo = ee->ee_pwr_cal_b;
+               mode = AR5K_EEPROM_MODE_11B;
+       } else if (channel->hw_value & CHANNEL_2GHZ) {
+               pcinfo = ee->ee_pwr_cal_g;
+               mode = AR5K_EEPROM_MODE_11G;
+       } else {
+               pcinfo = ee->ee_pwr_cal_a;
+               mode = AR5K_EEPROM_MODE_11A;
+       }
+       max = ee->ee_n_piers[mode] - 1;
+
+       /* Frequency is below our calibrated
+        * range. Use the lowest power curve
+        * we have */
+       if (target < pcinfo[0].freq) {
+               idx_l = idx_r = 0;
+               goto done;
+       }
+
+       /* Frequency is above our calibrated
+        * range. Use the highest power curve
+        * we have */
+       if (target > pcinfo[max].freq) {
+               idx_l = idx_r = max;
+               goto done;
+       }
+
+       /* Frequency is inside our calibrated
+        * channel range. Pick the surrounding
+        * calibration piers so that we can
+        * interpolate */
+       for (i = 0; i <= max; i++) {
+
+               /* Frequency matches one of our calibration
+                * piers, no need to interpolate, just use
+                * that calibration pier */
+               if (pcinfo[i].freq == target) {
+                       idx_l = idx_r = i;
+                       goto done;
+               }
+
+               /* We found a calibration pier that's above
+                * frequency, use this pier and the previous
+                * one to interpolate */
+               if (target < pcinfo[i].freq) {
+                       idx_r = i;
+                       idx_l = idx_r - 1;
+                       goto done;
+               }
+       }
+
+done:
+       *pcinfo_l = &pcinfo[idx_l];
+       *pcinfo_r = &pcinfo[idx_r];
+
+       return;
+}
+
+/*
+ * Get the surrounding per-rate power calibration data
+ * for a given frequency and interpolate between power
+ * values to set max target power supported by hw for
+ * each rate.
+ */
+static void
+ath5k_get_rate_pcal_data(struct ath5k_hw *ah,
+                       struct ieee80211_channel *channel,
+                       struct ath5k_rate_pcal_info *rates)
+{
+       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+       struct ath5k_rate_pcal_info *rpinfo;
+       u8 idx_l, idx_r;
+       u8 mode, max, i;
+       u32 target = channel->center_freq;
+
+       idx_l = 0;
+       idx_r = 0;
+
+       if (!(channel->hw_value & CHANNEL_OFDM)) {
+               rpinfo = ee->ee_rate_tpwr_b;
+               mode = AR5K_EEPROM_MODE_11B;
+       } else if (channel->hw_value & CHANNEL_2GHZ) {
+               rpinfo = ee->ee_rate_tpwr_g;
+               mode = AR5K_EEPROM_MODE_11G;
+       } else {
+               rpinfo = ee->ee_rate_tpwr_a;
+               mode = AR5K_EEPROM_MODE_11A;
+       }
+       max = ee->ee_rate_target_pwr_num[mode] - 1;
+
+       /* Get the surrounding calibration
+        * piers - same as above */
+       if (target < rpinfo[0].freq) {
+               idx_l = idx_r = 0;
+               goto done;
+       }
+
+       if (target > rpinfo[max].freq) {
+               idx_l = idx_r = max;
+               goto done;
+       }
+
+       for (i = 0; i <= max; i++) {
+
+               if (rpinfo[i].freq == target) {
+                       idx_l = idx_r = i;
+                       goto done;
+               }
+
+               if (target < rpinfo[i].freq) {
+                       idx_r = i;
+                       idx_l = idx_r - 1;
+                       goto done;
+               }
+       }
+
+done:
+       /* Now interpolate power value, based on the frequency */
+       rates->freq = target;
+
+       rates->target_power_6to24 =
+               ath5k_get_interpolated_value(target, rpinfo[idx_l].freq,
+                                       rpinfo[idx_r].freq,
+                                       rpinfo[idx_l].target_power_6to24,
+                                       rpinfo[idx_r].target_power_6to24);
+
+       rates->target_power_36 =
+               ath5k_get_interpolated_value(target, rpinfo[idx_l].freq,
+                                       rpinfo[idx_r].freq,
+                                       rpinfo[idx_l].target_power_36,
+                                       rpinfo[idx_r].target_power_36);
+
+       rates->target_power_48 =
+               ath5k_get_interpolated_value(target, rpinfo[idx_l].freq,
+                                       rpinfo[idx_r].freq,
+                                       rpinfo[idx_l].target_power_48,
+                                       rpinfo[idx_r].target_power_48);
+
+       rates->target_power_54 =
+               ath5k_get_interpolated_value(target, rpinfo[idx_l].freq,
+                                       rpinfo[idx_r].freq,
+                                       rpinfo[idx_l].target_power_54,
+                                       rpinfo[idx_r].target_power_54);
+}
+
+/*
+ * Get the max edge power for this channel if
+ * we have such data from EEPROM's Conformance Test
+ * Limits (CTL), and limit max power if needed.
+ */
+static void
+ath5k_get_max_ctl_power(struct ath5k_hw *ah,
+                       struct ieee80211_channel *channel)
+{
+       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+       struct ath5k_edge_power *rep = ee->ee_ctl_pwr;
+       u8 *ctl_val = ee->ee_ctl;
+       s16 max_chan_pwr = ah->ah_txpower.txp_max_pwr / 4;
+       s16 edge_pwr = 0;
+       u8 rep_idx;
+       u8 i, ctl_mode;
+       u8 ctl_idx = 0xFF;
+       u32 target = channel->center_freq;
+
+       ctl_mode = ath_regd_get_band_ctl(&ah->ah_regulatory, channel->band);
+
+       switch (channel->hw_value & CHANNEL_MODES) {
+       case CHANNEL_A:
+               ctl_mode |= AR5K_CTL_11A;
+               break;
+       case CHANNEL_G:
+               ctl_mode |= AR5K_CTL_11G;
+               break;
+       case CHANNEL_B:
+               ctl_mode |= AR5K_CTL_11B;
+               break;
+       case CHANNEL_T:
+               ctl_mode |= AR5K_CTL_TURBO;
+               break;
+       case CHANNEL_TG:
+               ctl_mode |= AR5K_CTL_TURBOG;
+               break;
+       case CHANNEL_XR:
+               /* Fall through */
+       default:
+               return;
+       }
+
+       for (i = 0; i < ee->ee_ctls; i++) {
+               if (ctl_val[i] == ctl_mode) {
+                       ctl_idx = i;
+                       break;
+               }
+       }
+
+       /* If we have a CTL dataset available grab it and find the
+        * edge power for our frequency */
+       if (ctl_idx == 0xFF)
+               return;
+
+       /* Edge powers are sorted by frequency from lower
+        * to higher. Each CTL corresponds to 8 edge power
+        * measurements. */
+       rep_idx = ctl_idx * AR5K_EEPROM_N_EDGES;
+
+       /* Don't do boundaries check because we
+        * might have more that one bands defined
+        * for this mode */
+
+       /* Get the edge power that's closer to our
+        * frequency */
+       for (i = 0; i < AR5K_EEPROM_N_EDGES; i++) {
+               rep_idx += i;
+               if (target <= rep[rep_idx].freq)
+                       edge_pwr = (s16) rep[rep_idx].edge;
+       }
+
+       if (edge_pwr)
+               ah->ah_txpower.txp_max_pwr = 4*min(edge_pwr, max_chan_pwr);
+}
+
+
+/*
+ * Power to PCDAC table functions
+ */
+
+/*
+ * Fill Power to PCDAC table on RF5111
+ *
+ * No further processing is needed for RF5111, the only thing we have to
+ * do is fill the values below and above calibration range since eeprom data
+ * may not cover the entire PCDAC table.
+ */
+static void
+ath5k_fill_pwr_to_pcdac_table(struct ath5k_hw *ah, s16* table_min,
+                                                       s16 *table_max)
+{
+       u8      *pcdac_out = ah->ah_txpower.txp_pd_table;
+       u8      *pcdac_tmp = ah->ah_txpower.tmpL[0];
+       u8      pcdac_0, pcdac_n, pcdac_i, pwr_idx, i;
+       s16     min_pwr, max_pwr;
+
+       /* Get table boundaries */
+       min_pwr = table_min[0];
+       pcdac_0 = pcdac_tmp[0];
+
+       max_pwr = table_max[0];
+       pcdac_n = pcdac_tmp[table_max[0] - table_min[0]];
+
+       /* Extrapolate below minimum using pcdac_0 */
+       pcdac_i = 0;
+       for (i = 0; i < min_pwr; i++)
+               pcdac_out[pcdac_i++] = pcdac_0;
+
+       /* Copy values from pcdac_tmp */
+       pwr_idx = min_pwr;
+       for (i = 0 ; pwr_idx <= max_pwr &&
+       pcdac_i < AR5K_EEPROM_POWER_TABLE_SIZE; i++) {
+               pcdac_out[pcdac_i++] = pcdac_tmp[i];
+               pwr_idx++;
+       }
+
+       /* Extrapolate above maximum */
+       while (pcdac_i < AR5K_EEPROM_POWER_TABLE_SIZE)
+               pcdac_out[pcdac_i++] = pcdac_n;
+
+}
+
+/*
+ * Combine available XPD Curves and fill Linear Power to PCDAC table
+ * on RF5112
+ *
+ * RFX112 can have up to 2 curves (one for low txpower range and one for
+ * higher txpower range). We need to put them both on pcdac_out and place
+ * them in the correct location. In case we only have one curve available
+ * just fit it on pcdac_out (it's supposed to cover the entire range of
+ * available pwr levels since it's always the higher power curve). Extrapolate
+ * below and above final table if needed.
+ */
+static void
+ath5k_combine_linear_pcdac_curves(struct ath5k_hw *ah, s16* table_min,
+                                               s16 *table_max, u8 pdcurves)
+{
+       u8      *pcdac_out = ah->ah_txpower.txp_pd_table;
+       u8      *pcdac_low_pwr;
+       u8      *pcdac_high_pwr;
+       u8      *pcdac_tmp;
+       u8      pwr;
+       s16     max_pwr_idx;
+       s16     min_pwr_idx;
+       s16     mid_pwr_idx = 0;
+       /* Edge flag turs on the 7nth bit on the PCDAC
+        * to delcare the higher power curve (force values
+        * to be greater than 64). If we only have one curve
+        * we don't need to set this, if we have 2 curves and
+        * fill the table backwards this can also be used to
+        * switch from higher power curve to lower power curve */
+       u8      edge_flag;
+       int     i;
+
+       /* When we have only one curve available
+        * that's the higher power curve. If we have
+        * two curves the first is the high power curve
+        * and the next is the low power curve. */
+       if (pdcurves > 1) {
+               pcdac_low_pwr = ah->ah_txpower.tmpL[1];
+               pcdac_high_pwr = ah->ah_txpower.tmpL[0];
+               mid_pwr_idx = table_max[1] - table_min[1] - 1;
+               max_pwr_idx = (table_max[0] - table_min[0]) / 2;
+
+               /* If table size goes beyond 31.5dB, keep the
+                * upper 31.5dB range when setting tx power.
+                * Note: 126 = 31.5 dB in quarter dB steps */
+               if (table_max[0] - table_min[1] > 126)
+                       min_pwr_idx = table_max[0] - 126;
+               else
+                       min_pwr_idx = table_min[1];
+
+               /* Since we fill table backwards
+                * start from high power curve */
+               pcdac_tmp = pcdac_high_pwr;
+
+               edge_flag = 0x40;
+#if 0
+               /* If both min and max power limits are in lower
+                * power curve's range, only use the low power curve.
+                * TODO: min/max levels are related to target
+                * power values requested from driver/user
+                * XXX: Is this really needed ? */
+               if (min_pwr < table_max[1] &&
+               max_pwr < table_max[1]) {
+                       edge_flag = 0;
+                       pcdac_tmp = pcdac_low_pwr;
+                       max_pwr_idx = (table_max[1] - table_min[1])/2;
+               }
+#endif
+       } else {
+               pcdac_low_pwr = ah->ah_txpower.tmpL[1]; /* Zeroed */
+               pcdac_high_pwr = ah->ah_txpower.tmpL[0];
+               min_pwr_idx = table_min[0];
+               max_pwr_idx = (table_max[0] - table_min[0]) / 2;
+               pcdac_tmp = pcdac_high_pwr;
+               edge_flag = 0;
+       }
+
+       /* This is used when setting tx power*/
+       ah->ah_txpower.txp_min_idx = min_pwr_idx/2;
+
+       /* Fill Power to PCDAC table backwards */
+       pwr = max_pwr_idx;
+       for (i = 63; i >= 0; i--) {
+               /* Entering lower power range, reset
+                * edge flag and set pcdac_tmp to lower
+                * power curve.*/
+               if (edge_flag == 0x40 &&
+               (2*pwr <= (table_max[1] - table_min[0]) || pwr == 0)) {
+                       edge_flag = 0x00;
+                       pcdac_tmp = pcdac_low_pwr;
+                       pwr = mid_pwr_idx/2;
+               }
+
+               /* Don't go below 1, extrapolate below if we have
+                * already swithced to the lower power curve -or
+                * we only have one curve and edge_flag is zero
+                * anyway */
+               if (pcdac_tmp[pwr] < 1 && (edge_flag == 0x00)) {
+                       while (i >= 0) {
+                               pcdac_out[i] = pcdac_out[i + 1];
+                               i--;
+                       }
+                       break;
+               }
+
+               pcdac_out[i] = pcdac_tmp[pwr] | edge_flag;
+
+               /* Extrapolate above if pcdac is greater than
+                * 126 -this can happen because we OR pcdac_out
+                * value with edge_flag on high power curve */
+               if (pcdac_out[i] > 126)
+                       pcdac_out[i] = 126;
+
+               /* Decrease by a 0.5dB step */
+               pwr--;
+       }
+}
+
+/* Write PCDAC values on hw */
+static void
+ath5k_setup_pcdac_table(struct ath5k_hw *ah)
+{
+       u8      *pcdac_out = ah->ah_txpower.txp_pd_table;
+       int     i;
+
+       /*
+        * Write TX power values
+        */
+       for (i = 0; i < (AR5K_EEPROM_POWER_TABLE_SIZE / 2); i++) {
+               ath5k_hw_reg_write(ah,
+                       (((pcdac_out[2*i + 0] << 8 | 0xff) & 0xffff) << 0) |
+                       (((pcdac_out[2*i + 1] << 8 | 0xff) & 0xffff) << 16),
+                       AR5K_PHY_PCDAC_TXPOWER(i));
+       }
+}
+
+
+/*
+ * Power to PDADC table functions
+ */
+
+/*
+ * Set the gain boundaries and create final Power to PDADC table
+ *
+ * We can have up to 4 pd curves, we need to do a simmilar process
+ * as we do for RF5112. This time we don't have an edge_flag but we
+ * set the gain boundaries on a separate register.
+ */
+static void
+ath5k_combine_pwr_to_pdadc_curves(struct ath5k_hw *ah,
+                       s16 *pwr_min, s16 *pwr_max, u8 pdcurves)
+{
+       u8 gain_boundaries[AR5K_EEPROM_N_PD_GAINS];
+       u8 *pdadc_out = ah->ah_txpower.txp_pd_table;
+       u8 *pdadc_tmp;
+       s16 pdadc_0;
+       u8 pdadc_i, pdadc_n, pwr_step, pdg, max_idx, table_size;
+       u8 pd_gain_overlap;
+
+       /* Note: Register value is initialized on initvals
+        * there is no feedback from hw.
+        * XXX: What about pd_gain_overlap from EEPROM ? */
+       pd_gain_overlap = (u8) ath5k_hw_reg_read(ah, AR5K_PHY_TPC_RG5) &
+               AR5K_PHY_TPC_RG5_PD_GAIN_OVERLAP;
+
+       /* Create final PDADC table */
+       for (pdg = 0, pdadc_i = 0; pdg < pdcurves; pdg++) {
+               pdadc_tmp = ah->ah_txpower.tmpL[pdg];
+
+               if (pdg == pdcurves - 1)
+                       /* 2 dB boundary stretch for last
+                        * (higher power) curve */
+                       gain_boundaries[pdg] = pwr_max[pdg] + 4;
+               else
+                       /* Set gain boundary in the middle
+                        * between this curve and the next one */
+                       gain_boundaries[pdg] =
+                               (pwr_max[pdg] + pwr_min[pdg + 1]) / 2;
+
+               /* Sanity check in case our 2 db stretch got out of
+                * range. */
+               if (gain_boundaries[pdg] > AR5K_TUNE_MAX_TXPOWER)
+                       gain_boundaries[pdg] = AR5K_TUNE_MAX_TXPOWER;
+
+               /* For the first curve (lower power)
+                * start from 0 dB */
+               if (pdg == 0)
+                       pdadc_0 = 0;
+               else
+                       /* For the other curves use the gain overlap */
+                       pdadc_0 = (gain_boundaries[pdg - 1] - pwr_min[pdg]) -
+                                                       pd_gain_overlap;
+
+               /* Force each power step to be at least 0.5 dB */
+               if ((pdadc_tmp[1] - pdadc_tmp[0]) > 1)
+                       pwr_step = pdadc_tmp[1] - pdadc_tmp[0];
+               else
+                       pwr_step = 1;
+
+               /* If pdadc_0 is negative, we need to extrapolate
+                * below this pdgain by a number of pwr_steps */
+               while ((pdadc_0 < 0) && (pdadc_i < 128)) {
+                       s16 tmp = pdadc_tmp[0] + pdadc_0 * pwr_step;
+                       pdadc_out[pdadc_i++] = (tmp < 0) ? 0 : (u8) tmp;
+                       pdadc_0++;
+               }
+
+               /* Set last pwr level, using gain boundaries */
+               pdadc_n = gain_boundaries[pdg] + pd_gain_overlap - pwr_min[pdg];
+               /* Limit it to be inside pwr range */
+               table_size = pwr_max[pdg] - pwr_min[pdg];
+               max_idx = (pdadc_n < table_size) ? pdadc_n : table_size;
+
+               /* Fill pdadc_out table */
+               while (pdadc_0 < max_idx)
+                       pdadc_out[pdadc_i++] = pdadc_tmp[pdadc_0++];
+
+               /* Need to extrapolate above this pdgain? */
+               if (pdadc_n <= max_idx)
+                       continue;
+
+               /* Force each power step to be at least 0.5 dB */
+               if ((pdadc_tmp[table_size - 1] - pdadc_tmp[table_size - 2]) > 1)
+                       pwr_step = pdadc_tmp[table_size - 1] -
+                                               pdadc_tmp[table_size - 2];
+               else
+                       pwr_step = 1;
+
+               /* Extrapolate above */
+               while ((pdadc_0 < (s16) pdadc_n) &&
+               (pdadc_i < AR5K_EEPROM_POWER_TABLE_SIZE * 2)) {
+                       s16 tmp = pdadc_tmp[table_size - 1] +
+                                       (pdadc_0 - max_idx) * pwr_step;
+                       pdadc_out[pdadc_i++] = (tmp > 127) ? 127 : (u8) tmp;
+                       pdadc_0++;
+               }
+       }
+
+       while (pdg < AR5K_EEPROM_N_PD_GAINS) {
+               gain_boundaries[pdg] = gain_boundaries[pdg - 1];
+               pdg++;
+       }
+
+       while (pdadc_i < AR5K_EEPROM_POWER_TABLE_SIZE * 2) {
+               pdadc_out[pdadc_i] = pdadc_out[pdadc_i - 1];
+               pdadc_i++;
+       }
+
+       /* Set gain boundaries */
+       ath5k_hw_reg_write(ah,
+               AR5K_REG_SM(pd_gain_overlap,
+                       AR5K_PHY_TPC_RG5_PD_GAIN_OVERLAP) |
+               AR5K_REG_SM(gain_boundaries[0],
+                       AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_1) |
+               AR5K_REG_SM(gain_boundaries[1],
+                       AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_2) |
+               AR5K_REG_SM(gain_boundaries[2],
+                       AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_3) |
+               AR5K_REG_SM(gain_boundaries[3],
+                       AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_4),
+               AR5K_PHY_TPC_RG5);
+
+       /* Used for setting rate power table */
+       ah->ah_txpower.txp_min_idx = pwr_min[0];
+
+}
+
+/* Write PDADC values on hw */
+static void
+ath5k_setup_pwr_to_pdadc_table(struct ath5k_hw *ah,
+                       u8 pdcurves, u8 *pdg_to_idx)
+{
+       u8 *pdadc_out = ah->ah_txpower.txp_pd_table;
+       u32 reg;
+       u8 i;
+
+       /* Select the right pdgain curves */
+
+       /* Clear current settings */
+       reg = ath5k_hw_reg_read(ah, AR5K_PHY_TPC_RG1);
+       reg &= ~(AR5K_PHY_TPC_RG1_PDGAIN_1 |
+               AR5K_PHY_TPC_RG1_PDGAIN_2 |
+               AR5K_PHY_TPC_RG1_PDGAIN_3 |
+               AR5K_PHY_TPC_RG1_NUM_PD_GAIN);
+
+       /*
+        * Use pd_gains curve from eeprom
+        *
+        * This overrides the default setting from initvals
+        * in case some vendors (e.g. Zcomax) don't use the default
+        * curves. If we don't honor their settings we 'll get a
+        * 5dB (1 * gain overlap ?) drop.
+        */
+       reg |= AR5K_REG_SM(pdcurves, AR5K_PHY_TPC_RG1_NUM_PD_GAIN);
+
+       switch (pdcurves) {
+       case 3:
+               reg |= AR5K_REG_SM(pdg_to_idx[2], AR5K_PHY_TPC_RG1_PDGAIN_3);
+               /* Fall through */
+       case 2:
+               reg |= AR5K_REG_SM(pdg_to_idx[1], AR5K_PHY_TPC_RG1_PDGAIN_2);
+               /* Fall through */
+       case 1:
+               reg |= AR5K_REG_SM(pdg_to_idx[0], AR5K_PHY_TPC_RG1_PDGAIN_1);
+               break;
+       }
+       ath5k_hw_reg_write(ah, reg, AR5K_PHY_TPC_RG1);
+
+       /*
+        * Write TX power values
+        */
+       for (i = 0; i < (AR5K_EEPROM_POWER_TABLE_SIZE / 2); i++) {
+               ath5k_hw_reg_write(ah,
+                       ((pdadc_out[4*i + 0] & 0xff) << 0) |
+                       ((pdadc_out[4*i + 1] & 0xff) << 8) |
+                       ((pdadc_out[4*i + 2] & 0xff) << 16) |
+                       ((pdadc_out[4*i + 3] & 0xff) << 24),
+                       AR5K_PHY_PDADC_TXPOWER(i));
+       }
+}
+
+
+/*
+ * Common code for PCDAC/PDADC tables
+ */
+
+/*
+ * This is the main function that uses all of the above
+ * to set PCDAC/PDADC table on hw for the current channel.
+ * This table is used for tx power calibration on the basband,
+ * without it we get weird tx power levels and in some cases
+ * distorted spectral mask
+ */
+static int
+ath5k_setup_channel_powertable(struct ath5k_hw *ah,
+                       struct ieee80211_channel *channel,
+                       u8 ee_mode, u8 type)
+{
+       struct ath5k_pdgain_info *pdg_L, *pdg_R;
+       struct ath5k_chan_pcal_info *pcinfo_L;
+       struct ath5k_chan_pcal_info *pcinfo_R;
+       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+       u8 *pdg_curve_to_idx = ee->ee_pdc_to_idx[ee_mode];
+       s16 table_min[AR5K_EEPROM_N_PD_GAINS];
+       s16 table_max[AR5K_EEPROM_N_PD_GAINS];
+       u8 *tmpL;
+       u8 *tmpR;
+       u32 target = channel->center_freq;
+       int pdg, i;
+
+       /* Get surounding freq piers for this channel */
+       ath5k_get_chan_pcal_surrounding_piers(ah, channel,
+                                               &pcinfo_L,
+                                               &pcinfo_R);
+
+       /* Loop over pd gain curves on
+        * surounding freq piers by index */
+       for (pdg = 0; pdg < ee->ee_pd_gains[ee_mode]; pdg++) {
+
+               /* Fill curves in reverse order
+                * from lower power (max gain)
+                * to higher power. Use curve -> idx
+                * backmaping we did on eeprom init */
+               u8 idx = pdg_curve_to_idx[pdg];
+
+               /* Grab the needed curves by index */
+               pdg_L = &pcinfo_L->pd_curves[idx];
+               pdg_R = &pcinfo_R->pd_curves[idx];
+
+               /* Initialize the temp tables */
+               tmpL = ah->ah_txpower.tmpL[pdg];
+               tmpR = ah->ah_txpower.tmpR[pdg];
+
+               /* Set curve's x boundaries and create
+                * curves so that they cover the same
+                * range (if we don't do that one table
+                * will have values on some range and the
+                * other one won't have any so interpolation
+                * will fail) */
+               table_min[pdg] = min(pdg_L->pd_pwr[0],
+                                       pdg_R->pd_pwr[0]) / 2;
+
+               table_max[pdg] = max(pdg_L->pd_pwr[pdg_L->pd_points - 1],
+                               pdg_R->pd_pwr[pdg_R->pd_points - 1]) / 2;
+
+               /* Now create the curves on surrounding channels
+                * and interpolate if needed to get the final
+                * curve for this gain on this channel */
+               switch (type) {
+               case AR5K_PWRTABLE_LINEAR_PCDAC:
+                       /* Override min/max so that we don't loose
+                        * accuracy (don't divide by 2) */
+                       table_min[pdg] = min(pdg_L->pd_pwr[0],
+                                               pdg_R->pd_pwr[0]);
+
+                       table_max[pdg] =
+                               max(pdg_L->pd_pwr[pdg_L->pd_points - 1],
+                                       pdg_R->pd_pwr[pdg_R->pd_points - 1]);
+
+                       /* Override minimum so that we don't get
+                        * out of bounds while extrapolating
+                        * below. Don't do this when we have 2
+                        * curves and we are on the high power curve
+                        * because table_min is ok in this case */
+                       if (!(ee->ee_pd_gains[ee_mode] > 1 && pdg == 0)) {
+
+                               table_min[pdg] =
+                                       ath5k_get_linear_pcdac_min(pdg_L->pd_step,
+                                                               pdg_R->pd_step,
+                                                               pdg_L->pd_pwr,
+                                                               pdg_R->pd_pwr);
+
+                               /* Don't go too low because we will
+                                * miss the upper part of the curve.
+                                * Note: 126 = 31.5dB (max power supported)
+                                * in 0.25dB units */
+                               if (table_max[pdg] - table_min[pdg] > 126)
+                                       table_min[pdg] = table_max[pdg] - 126;
+                       }
+
+                       /* Fall through */
+               case AR5K_PWRTABLE_PWR_TO_PCDAC:
+               case AR5K_PWRTABLE_PWR_TO_PDADC:
+
+                       ath5k_create_power_curve(table_min[pdg],
+                                               table_max[pdg],
+                                               pdg_L->pd_pwr,
+                                               pdg_L->pd_step,
+                                               pdg_L->pd_points, tmpL, type);
+
+                       /* We are in a calibration
+                        * pier, no need to interpolate
+                        * between freq piers */
+                       if (pcinfo_L == pcinfo_R)
+                               continue;
+
+                       ath5k_create_power_curve(table_min[pdg],
+                                               table_max[pdg],
+                                               pdg_R->pd_pwr,
+                                               pdg_R->pd_step,
+                                               pdg_R->pd_points, tmpR, type);
+                       break;
+               default:
+                       return -EINVAL;
+               }
+
+               /* Interpolate between curves
+                * of surounding freq piers to
+                * get the final curve for this
+                * pd gain. Re-use tmpL for interpolation
+                * output */
+               for (i = 0; (i < (u16) (table_max[pdg] - table_min[pdg])) &&
+               (i < AR5K_EEPROM_POWER_TABLE_SIZE); i++) {
+                       tmpL[i] = (u8) ath5k_get_interpolated_value(target,
+                                                       (s16) pcinfo_L->freq,
+                                                       (s16) pcinfo_R->freq,
+                                                       (s16) tmpL[i],
+                                                       (s16) tmpR[i]);
+               }
+       }
+
+       /* Now we have a set of curves for this
+        * channel on tmpL (x range is table_max - table_min
+        * and y values are tmpL[pdg][]) sorted in the same
+        * order as EEPROM (because we've used the backmaping).
+        * So for RF5112 it's from higher power to lower power
+        * and for RF2413 it's from lower power to higher power.
+        * For RF5111 we only have one curve. */
+
+       /* Fill min and max power levels for this
+        * channel by interpolating the values on
+        * surounding channels to complete the dataset */
+       ah->ah_txpower.txp_min_pwr = ath5k_get_interpolated_value(target,
+                                       (s16) pcinfo_L->freq,
+                                       (s16) pcinfo_R->freq,
+                                       pcinfo_L->min_pwr, pcinfo_R->min_pwr);
+
+       ah->ah_txpower.txp_max_pwr = ath5k_get_interpolated_value(target,
+                                       (s16) pcinfo_L->freq,
+                                       (s16) pcinfo_R->freq,
+                                       pcinfo_L->max_pwr, pcinfo_R->max_pwr);
+
+       /* We are ready to go, fill PCDAC/PDADC
+        * table and write settings on hardware */
+       switch (type) {
+       case AR5K_PWRTABLE_LINEAR_PCDAC:
+               /* For RF5112 we can have one or two curves
+                * and each curve covers a certain power lvl
+                * range so we need to do some more processing */
+               ath5k_combine_linear_pcdac_curves(ah, table_min, table_max,
+                                               ee->ee_pd_gains[ee_mode]);
+
+               /* Set txp.offset so that we can
+                * match max power value with max
+                * table index */
+               ah->ah_txpower.txp_offset = 64 - (table_max[0] / 2);
+
+               /* Write settings on hw */
+               ath5k_setup_pcdac_table(ah);
+               break;
+       case AR5K_PWRTABLE_PWR_TO_PCDAC:
+               /* We are done for RF5111 since it has only
+                * one curve, just fit the curve on the table */
+               ath5k_fill_pwr_to_pcdac_table(ah, table_min, table_max);
+
+               /* No rate powertable adjustment for RF5111 */
+               ah->ah_txpower.txp_min_idx = 0;
+               ah->ah_txpower.txp_offset = 0;
+
+               /* Write settings on hw */
+               ath5k_setup_pcdac_table(ah);
+               break;
+       case AR5K_PWRTABLE_PWR_TO_PDADC:
+               /* Set PDADC boundaries and fill
+                * final PDADC table */
+               ath5k_combine_pwr_to_pdadc_curves(ah, table_min, table_max,
+                                               ee->ee_pd_gains[ee_mode]);
+
+               /* Write settings on hw */
+               ath5k_setup_pwr_to_pdadc_table(ah, pdg, pdg_curve_to_idx);
+
+               /* Set txp.offset, note that table_min
+                * can be negative */
+               ah->ah_txpower.txp_offset = table_min[0];
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+
+/*
+ * Per-rate tx power setting
+ *
+ * This is the code that sets the desired tx power (below
+ * maximum) on hw for each rate (we also have TPC that sets
+ * power per packet). We do that by providing an index on the
+ * PCDAC/PDADC table we set up.
+ */
+
+/*
+ * Set rate power table
+ *
+ * For now we only limit txpower based on maximum tx power
+ * supported by hw (what's inside rate_info). We need to limit
+ * this even more, based on regulatory domain etc.
+ *
+ * Rate power table contains indices to PCDAC/PDADC table (0.5dB steps)
+ * and is indexed as follows:
+ * rates[0] - rates[7] -> OFDM rates
+ * rates[8] - rates[14] -> CCK rates
+ * rates[15] -> XR rates (they all have the same power)
+ */
+static void
+ath5k_setup_rate_powertable(struct ath5k_hw *ah, u16 max_pwr,
+                       struct ath5k_rate_pcal_info *rate_info,
+                       u8 ee_mode)
+{
+       unsigned int i;
+       u16 *rates;
+
+       /* max_pwr is power level we got from driver/user in 0.5dB
+        * units, switch to 0.25dB units so we can compare */
+       max_pwr *= 2;
+       max_pwr = min(max_pwr, (u16) ah->ah_txpower.txp_max_pwr) / 2;
+
+       /* apply rate limits */
+       rates = ah->ah_txpower.txp_rates_power_table;
+
+       /* OFDM rates 6 to 24Mb/s */
+       for (i = 0; i < 5; i++)
+               rates[i] = min(max_pwr, rate_info->target_power_6to24);
+
+       /* Rest OFDM rates */
+       rates[5] = min(rates[0], rate_info->target_power_36);
+       rates[6] = min(rates[0], rate_info->target_power_48);
+       rates[7] = min(rates[0], rate_info->target_power_54);
+
+       /* CCK rates */
+       /* 1L */
+       rates[8] = min(rates[0], rate_info->target_power_6to24);
+       /* 2L */
+       rates[9] = min(rates[0], rate_info->target_power_36);
+       /* 2S */
+       rates[10] = min(rates[0], rate_info->target_power_36);
+       /* 5L */
+       rates[11] = min(rates[0], rate_info->target_power_48);
+       /* 5S */
+       rates[12] = min(rates[0], rate_info->target_power_48);
+       /* 11L */
+       rates[13] = min(rates[0], rate_info->target_power_54);
+       /* 11S */
+       rates[14] = min(rates[0], rate_info->target_power_54);
+
+       /* XR rates */
+       rates[15] = min(rates[0], rate_info->target_power_6to24);
+
+       /* CCK rates have different peak to average ratio
+        * so we have to tweak their power so that gainf
+        * correction works ok. For this we use OFDM to
+        * CCK delta from eeprom */
+       if ((ee_mode == AR5K_EEPROM_MODE_11G) &&
+       (ah->ah_phy_revision < AR5K_SREV_PHY_5212A))
+               for (i = 8; i <= 15; i++)
+                       rates[i] -= ah->ah_txpower.txp_cck_ofdm_gainf_delta;
+
+       /* Now that we have all rates setup use table offset to
+        * match the power range set by user with the power indices
+        * on PCDAC/PDADC table */
+       for (i = 0; i < 16; i++) {
+               rates[i] += ah->ah_txpower.txp_offset;
+               /* Don't get out of bounds */
+               if (rates[i] > 63)
+                       rates[i] = 63;
+       }
+
+       /* Min/max in 0.25dB units */
+       ah->ah_txpower.txp_min_pwr = 2 * rates[7];
+       ah->ah_txpower.txp_max_pwr = 2 * rates[0];
+       ah->ah_txpower.txp_ofdm = rates[7];
+}
+
+
+/*
+ * Set transmition power
+ */
+int
+ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
+               u8 ee_mode, u8 txpower)
+{
+       struct ath5k_rate_pcal_info rate_info;
+       u8 type;
+       int ret;
+
+       ATH5K_TRACE(ah->ah_sc);
+       if (txpower > AR5K_TUNE_MAX_TXPOWER) {
+               ATH5K_ERR(ah->ah_sc, "invalid tx power: %u\n", txpower);
+               return -EINVAL;
+       }
+       if (txpower == 0)
+               txpower = AR5K_TUNE_DEFAULT_TXPOWER;
+
+       /* Reset TX power values */
+       memset(&ah->ah_txpower, 0, sizeof(ah->ah_txpower));
+       ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER;
+       ah->ah_txpower.txp_min_pwr = 0;
+       ah->ah_txpower.txp_max_pwr = AR5K_TUNE_MAX_TXPOWER;
+
+       /* Initialize TX power table */
+       switch (ah->ah_radio) {
+       case AR5K_RF5111:
+               type = AR5K_PWRTABLE_PWR_TO_PCDAC;
+               break;
+       case AR5K_RF5112:
+               type = AR5K_PWRTABLE_LINEAR_PCDAC;
+               break;
+       case AR5K_RF2413:
+       case AR5K_RF5413:
+       case AR5K_RF2316:
+       case AR5K_RF2317:
+       case AR5K_RF2425:
+               type = AR5K_PWRTABLE_PWR_TO_PDADC;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       /* FIXME: Only on channel/mode change */
+       ret = ath5k_setup_channel_powertable(ah, channel, ee_mode, type);
+       if (ret)
+               return ret;
+
+       /* Limit max power if we have a CTL available */
+       ath5k_get_max_ctl_power(ah, channel);
+
+       /* FIXME: Tx power limit for this regdomain
+        * XXX: Mac80211/CRDA will do that anyway ? */
+
+       /* FIXME: Antenna reduction stuff */
+
+       /* FIXME: Limit power on turbo modes */
+
+       /* FIXME: TPC scale reduction */
+
+       /* Get surounding channels for per-rate power table
+        * calibration */
+       ath5k_get_rate_pcal_data(ah, channel, &rate_info);
+
+       /* Setup rate power table */
+       ath5k_setup_rate_powertable(ah, txpower, &rate_info, ee_mode);
+
+       /* Write rate power table on hw */
+       ath5k_hw_reg_write(ah, AR5K_TXPOWER_OFDM(3, 24) |
+               AR5K_TXPOWER_OFDM(2, 16) | AR5K_TXPOWER_OFDM(1, 8) |
+               AR5K_TXPOWER_OFDM(0, 0), AR5K_PHY_TXPOWER_RATE1);
+
+       ath5k_hw_reg_write(ah, AR5K_TXPOWER_OFDM(7, 24) |
+               AR5K_TXPOWER_OFDM(6, 16) | AR5K_TXPOWER_OFDM(5, 8) |
+               AR5K_TXPOWER_OFDM(4, 0), AR5K_PHY_TXPOWER_RATE2);
+
+       ath5k_hw_reg_write(ah, AR5K_TXPOWER_CCK(10, 24) |
+               AR5K_TXPOWER_CCK(9, 16) | AR5K_TXPOWER_CCK(15, 8) |
+               AR5K_TXPOWER_CCK(8, 0), AR5K_PHY_TXPOWER_RATE3);
+
+       ath5k_hw_reg_write(ah, AR5K_TXPOWER_CCK(14, 24) |
+               AR5K_TXPOWER_CCK(13, 16) | AR5K_TXPOWER_CCK(12, 8) |
+               AR5K_TXPOWER_CCK(11, 0), AR5K_PHY_TXPOWER_RATE4);
+
+       /* FIXME: TPC support */
+       if (ah->ah_txpower.txp_tpc) {
+               ath5k_hw_reg_write(ah, AR5K_PHY_TXPOWER_RATE_MAX_TPC_ENABLE |
+                       AR5K_TUNE_MAX_TXPOWER, AR5K_PHY_TXPOWER_RATE_MAX);
+
+               ath5k_hw_reg_write(ah,
+                       AR5K_REG_MS(AR5K_TUNE_MAX_TXPOWER, AR5K_TPC_ACK) |
+                       AR5K_REG_MS(AR5K_TUNE_MAX_TXPOWER, AR5K_TPC_CTS) |
+                       AR5K_REG_MS(AR5K_TUNE_MAX_TXPOWER, AR5K_TPC_CHIRP),
+                       AR5K_TPC);
+       } else {
+               ath5k_hw_reg_write(ah, AR5K_PHY_TXPOWER_RATE_MAX |
+                       AR5K_TUNE_MAX_TXPOWER, AR5K_PHY_TXPOWER_RATE_MAX);
+       }
+
+       return 0;
+}
+
+int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower)
+{
+       /*Just a try M.F.*/
+       struct ieee80211_channel *channel = &ah->ah_current_channel;
+       u8 ee_mode;
+
+       ATH5K_TRACE(ah->ah_sc);
+
+       switch (channel->hw_value & CHANNEL_MODES) {
+       case CHANNEL_A:
+       case CHANNEL_T:
+       case CHANNEL_XR:
+               ee_mode = AR5K_EEPROM_MODE_11A;
+               break;
+       case CHANNEL_G:
+       case CHANNEL_TG:
+               ee_mode = AR5K_EEPROM_MODE_11G;
+               break;
+       case CHANNEL_B:
+               ee_mode = AR5K_EEPROM_MODE_11B;
+               break;
+       default:
+               ATH5K_ERR(ah->ah_sc,
+                       "invalid channel: %d\n", channel->center_freq);
+               return -EINVAL;
+       }
+
+       ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_TXPOWER,
+               "changing txpower to %d\n", txpower);
+
+       return ath5k_hw_txpower(ah, channel, ee_mode, txpower);
+}
+
+#undef _ATH5K_PHY
diff --git a/drivers/net/wireless/ath/ath5k/qcu.c b/drivers/net/wireless/ath/ath5k/qcu.c
new file mode 100644 (file)
index 0000000..73407b3
--- /dev/null
@@ -0,0 +1,549 @@
+/*
+ * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
+ * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
+ *
+ * Permission to use, copy, modify, and 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.
+ *
+ */
+
+/********************************************\
+Queue Control Unit, DFS Control Unit Functions
+\********************************************/
+
+#include "ath5k.h"
+#include "reg.h"
+#include "debug.h"
+#include "base.h"
+
+/*
+ * Get properties for a transmit queue
+ */
+int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue,
+               struct ath5k_txq_info *queue_info)
+{
+       ATH5K_TRACE(ah->ah_sc);
+       memcpy(queue_info, &ah->ah_txq[queue], sizeof(struct ath5k_txq_info));
+       return 0;
+}
+
+/*
+ * Set properties for a transmit queue
+ */
+int ath5k_hw_set_tx_queueprops(struct ath5k_hw *ah, int queue,
+                               const struct ath5k_txq_info *queue_info)
+{
+       ATH5K_TRACE(ah->ah_sc);
+       AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
+
+       if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
+               return -EIO;
+
+       memcpy(&ah->ah_txq[queue], queue_info, sizeof(struct ath5k_txq_info));
+
+       /*XXX: Is this supported on 5210 ?*/
+       if ((queue_info->tqi_type == AR5K_TX_QUEUE_DATA &&
+                       ((queue_info->tqi_subtype == AR5K_WME_AC_VI) ||
+                       (queue_info->tqi_subtype == AR5K_WME_AC_VO))) ||
+                       queue_info->tqi_type == AR5K_TX_QUEUE_UAPSD)
+               ah->ah_txq[queue].tqi_flags |= AR5K_TXQ_FLAG_POST_FR_BKOFF_DIS;
+
+       return 0;
+}
+
+/*
+ * Initialize a transmit queue
+ */
+int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, enum ath5k_tx_queue queue_type,
+               struct ath5k_txq_info *queue_info)
+{
+       unsigned int queue;
+       int ret;
+
+       ATH5K_TRACE(ah->ah_sc);
+
+       /*
+        * Get queue by type
+        */
+       /*5210 only has 2 queues*/
+       if (ah->ah_version == AR5K_AR5210) {
+               switch (queue_type) {
+               case AR5K_TX_QUEUE_DATA:
+                       queue = AR5K_TX_QUEUE_ID_NOQCU_DATA;
+                       break;
+               case AR5K_TX_QUEUE_BEACON:
+               case AR5K_TX_QUEUE_CAB:
+                       queue = AR5K_TX_QUEUE_ID_NOQCU_BEACON;
+                       break;
+               default:
+                       return -EINVAL;
+               }
+       } else {
+               switch (queue_type) {
+               case AR5K_TX_QUEUE_DATA:
+                       for (queue = AR5K_TX_QUEUE_ID_DATA_MIN;
+                               ah->ah_txq[queue].tqi_type !=
+                               AR5K_TX_QUEUE_INACTIVE; queue++) {
+
+                               if (queue > AR5K_TX_QUEUE_ID_DATA_MAX)
+                                       return -EINVAL;
+                       }
+                       break;
+               case AR5K_TX_QUEUE_UAPSD:
+                       queue = AR5K_TX_QUEUE_ID_UAPSD;
+                       break;
+               case AR5K_TX_QUEUE_BEACON:
+                       queue = AR5K_TX_QUEUE_ID_BEACON;
+                       break;
+               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->ah_sc,
+                                       "XR data queues only supported in"
+                                       " 5212!\n");
+                       queue = AR5K_TX_QUEUE_ID_XR_DATA;
+                       break;
+               default:
+                       return -EINVAL;
+               }
+       }
+
+       /*
+        * Setup internal queue structure
+        */
+       memset(&ah->ah_txq[queue], 0, sizeof(struct ath5k_txq_info));
+       ah->ah_txq[queue].tqi_type = queue_type;
+
+       if (queue_info != NULL) {
+               queue_info->tqi_type = queue_type;
+               ret = ath5k_hw_set_tx_queueprops(ah, queue, queue_info);
+               if (ret)
+                       return ret;
+       }
+
+       /*
+        * We use ah_txq_status to hold a temp value for
+        * the Secondary interrupt mask registers on 5211+
+        * check out ath5k_hw_reset_tx_queue
+        */
+       AR5K_Q_ENABLE_BITS(ah->ah_txq_status, queue);
+
+       return queue;
+}
+
+/*
+ * Get number of pending frames
+ * for a specific queue [5211+]
+ */
+u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue)
+{
+       u32 pending;
+       ATH5K_TRACE(ah->ah_sc);
+       AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
+
+       /* Return if queue is declared inactive */
+       if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
+               return false;
+
+       /* XXX: How about AR5K_CFG_TXCNT ? */
+       if (ah->ah_version == AR5K_AR5210)
+               return false;
+
+       pending = ath5k_hw_reg_read(ah, AR5K_QUEUE_STATUS(queue));
+       pending &= AR5K_QCU_STS_FRMPENDCNT;
+
+       /* It's possible to have no frames pending even if TXE
+        * is set. To indicate that q has not stopped return
+        * true */
+       if (!pending && AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, queue))
+               return true;
+
+       return pending;
+}
+
+/*
+ * Set a transmit queue inactive
+ */
+void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue)
+{
+       ATH5K_TRACE(ah->ah_sc);
+       if (WARN_ON(queue >= ah->ah_capabilities.cap_queues.q_tx_num))
+               return;
+
+       /* This queue will be skipped in further operations */
+       ah->ah_txq[queue].tqi_type = AR5K_TX_QUEUE_INACTIVE;
+       /*For SIMR setup*/
+       AR5K_Q_DISABLE_BITS(ah->ah_txq_status, queue);
+}
+
+/*
+ * Set DFS properties for a transmit queue on DCU
+ */
+int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
+{
+       u32 cw_min, cw_max, retry_lg, retry_sh;
+       struct ath5k_txq_info *tq = &ah->ah_txq[queue];
+
+       ATH5K_TRACE(ah->ah_sc);
+       AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
+
+       tq = &ah->ah_txq[queue];
+
+       if (tq->tqi_type == AR5K_TX_QUEUE_INACTIVE)
+               return 0;
+
+       if (ah->ah_version == AR5K_AR5210) {
+               /* Only handle data queues, others will be ignored */
+               if (tq->tqi_type != AR5K_TX_QUEUE_DATA)
+                       return 0;
+
+               /* Set Slot time */
+               ath5k_hw_reg_write(ah, ah->ah_turbo ?
+                       AR5K_INIT_SLOT_TIME_TURBO : AR5K_INIT_SLOT_TIME,
+                       AR5K_SLOT_TIME);
+               /* Set ACK_CTS timeout */
+               ath5k_hw_reg_write(ah, ah->ah_turbo ?
+                       AR5K_INIT_ACK_CTS_TIMEOUT_TURBO :
+                       AR5K_INIT_ACK_CTS_TIMEOUT, AR5K_SLOT_TIME);
+               /* Set Transmit Latency */
+               ath5k_hw_reg_write(ah, ah->ah_turbo ?
+                       AR5K_INIT_TRANSMIT_LATENCY_TURBO :
+                       AR5K_INIT_TRANSMIT_LATENCY, AR5K_USEC_5210);
+
+               /* Set IFS0 */
+               if (ah->ah_turbo) {
+                        ath5k_hw_reg_write(ah, ((AR5K_INIT_SIFS_TURBO +
+                               (ah->ah_aifs + tq->tqi_aifs) *
+                               AR5K_INIT_SLOT_TIME_TURBO) <<
+                               AR5K_IFS0_DIFS_S) | AR5K_INIT_SIFS_TURBO,
+                               AR5K_IFS0);
+               } else {
+                       ath5k_hw_reg_write(ah, ((AR5K_INIT_SIFS +
+                               (ah->ah_aifs + tq->tqi_aifs) *
+                               AR5K_INIT_SLOT_TIME) << AR5K_IFS0_DIFS_S) |
+                               AR5K_INIT_SIFS, AR5K_IFS0);
+               }
+
+               /* Set IFS1 */
+               ath5k_hw_reg_write(ah, ah->ah_turbo ?
+                       AR5K_INIT_PROTO_TIME_CNTRL_TURBO :
+                       AR5K_INIT_PROTO_TIME_CNTRL, AR5K_IFS1);
+               /* Set AR5K_PHY_SETTLING */
+               ath5k_hw_reg_write(ah, ah->ah_turbo ?
+                       (ath5k_hw_reg_read(ah, AR5K_PHY_SETTLING) & ~0x7F)
+                       | 0x38 :
+                       (ath5k_hw_reg_read(ah, AR5K_PHY_SETTLING) & ~0x7F)
+                       | 0x1C,
+                       AR5K_PHY_SETTLING);
+               /* Set Frame Control Register */
+               ath5k_hw_reg_write(ah, ah->ah_turbo ?
+                       (AR5K_PHY_FRAME_CTL_INI | AR5K_PHY_TURBO_MODE |
+                       AR5K_PHY_TURBO_SHORT | 0x2020) :
+                       (AR5K_PHY_FRAME_CTL_INI | 0x1020),
+                       AR5K_PHY_FRAME_CTL_5210);
+       }
+
+       /*
+        * Calculate cwmin/max by channel mode
+        */
+       cw_min = ah->ah_cw_min = AR5K_TUNE_CWMIN;
+       cw_max = ah->ah_cw_max = AR5K_TUNE_CWMAX;
+       ah->ah_aifs = AR5K_TUNE_AIFS;
+       /*XR is only supported on 5212*/
+       if (IS_CHAN_XR(ah->ah_current_channel) &&
+                       ah->ah_version == AR5K_AR5212) {
+               cw_min = ah->ah_cw_min = AR5K_TUNE_CWMIN_XR;
+               cw_max = ah->ah_cw_max = AR5K_TUNE_CWMAX_XR;
+               ah->ah_aifs = AR5K_TUNE_AIFS_XR;
+       /*B mode is not supported on 5210*/
+       } else if (IS_CHAN_B(ah->ah_current_channel) &&
+                       ah->ah_version != AR5K_AR5210) {
+               cw_min = ah->ah_cw_min = AR5K_TUNE_CWMIN_11B;
+               cw_max = ah->ah_cw_max = AR5K_TUNE_CWMAX_11B;
+               ah->ah_aifs = AR5K_TUNE_AIFS_11B;
+       }
+
+       cw_min = 1;
+       while (cw_min < ah->ah_cw_min)
+               cw_min = (cw_min << 1) | 1;
+
+       cw_min = tq->tqi_cw_min < 0 ? (cw_min >> (-tq->tqi_cw_min)) :
+               ((cw_min << tq->tqi_cw_min) + (1 << tq->tqi_cw_min) - 1);
+       cw_max = tq->tqi_cw_max < 0 ? (cw_max >> (-tq->tqi_cw_max)) :
+               ((cw_max << tq->tqi_cw_max) + (1 << tq->tqi_cw_max) - 1);
+
+       /*
+        * Calculate and set retry limits
+        */
+       if (ah->ah_software_retry) {
+               /* XXX Need to test this */
+               retry_lg = ah->ah_limit_tx_retries;
+               retry_sh = retry_lg = retry_lg > AR5K_DCU_RETRY_LMT_SH_RETRY ?
+                       AR5K_DCU_RETRY_LMT_SH_RETRY : retry_lg;
+       } else {
+               retry_lg = AR5K_INIT_LG_RETRY;
+               retry_sh = AR5K_INIT_SH_RETRY;
+       }
+
+       /*No QCU/DCU [5210]*/
+       if (ah->ah_version == AR5K_AR5210) {
+               ath5k_hw_reg_write(ah,
+                       (cw_min << AR5K_NODCU_RETRY_LMT_CW_MIN_S)
+                       | AR5K_REG_SM(AR5K_INIT_SLG_RETRY,
+                               AR5K_NODCU_RETRY_LMT_SLG_RETRY)
+                       | AR5K_REG_SM(AR5K_INIT_SSH_RETRY,
+                               AR5K_NODCU_RETRY_LMT_SSH_RETRY)
+                       | AR5K_REG_SM(retry_lg, AR5K_NODCU_RETRY_LMT_LG_RETRY)
+                       | AR5K_REG_SM(retry_sh, AR5K_NODCU_RETRY_LMT_SH_RETRY),
+                       AR5K_NODCU_RETRY_LMT);
+       } else {
+               /*QCU/DCU [5211+]*/
+               ath5k_hw_reg_write(ah,
+                       AR5K_REG_SM(AR5K_INIT_SLG_RETRY,
+                               AR5K_DCU_RETRY_LMT_SLG_RETRY) |
+                       AR5K_REG_SM(AR5K_INIT_SSH_RETRY,
+                               AR5K_DCU_RETRY_LMT_SSH_RETRY) |
+                       AR5K_REG_SM(retry_lg, AR5K_DCU_RETRY_LMT_LG_RETRY) |
+                       AR5K_REG_SM(retry_sh, AR5K_DCU_RETRY_LMT_SH_RETRY),
+                       AR5K_QUEUE_DFS_RETRY_LIMIT(queue));
+
+       /*===Rest is also for QCU/DCU only [5211+]===*/
+
+               /*
+                * Set initial content window (cw_min/cw_max)
+                * and arbitrated interframe space (aifs)...
+                */
+               ath5k_hw_reg_write(ah,
+                       AR5K_REG_SM(cw_min, AR5K_DCU_LCL_IFS_CW_MIN) |
+                       AR5K_REG_SM(cw_max, AR5K_DCU_LCL_IFS_CW_MAX) |
+                       AR5K_REG_SM(ah->ah_aifs + tq->tqi_aifs,
+                               AR5K_DCU_LCL_IFS_AIFS),
+                       AR5K_QUEUE_DFS_LOCAL_IFS(queue));
+
+               /*
+                * Set misc registers
+                */
+               /* Enable DCU early termination for this queue */
+               AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
+                                       AR5K_QCU_MISC_DCU_EARLY);
+
+               /* Enable DCU to wait for next fragment from QCU */
+               AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
+                                       AR5K_DCU_MISC_FRAG_WAIT);
+
+               /* On Maui and Spirit use the global seqnum on DCU */
+               if (ah->ah_mac_version < AR5K_SREV_AR5211)
+                       AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
+                                               AR5K_DCU_MISC_SEQNUM_CTL);
+
+               if (tq->tqi_cbr_period) {
+                       ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_cbr_period,
+                               AR5K_QCU_CBRCFG_INTVAL) |
+                               AR5K_REG_SM(tq->tqi_cbr_overflow_limit,
+                               AR5K_QCU_CBRCFG_ORN_THRES),
+                               AR5K_QUEUE_CBRCFG(queue));
+                       AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
+                               AR5K_QCU_MISC_FRSHED_CBR);
+                       if (tq->tqi_cbr_overflow_limit)
+                               AR5K_REG_ENABLE_BITS(ah,
+                                       AR5K_QUEUE_MISC(queue),
+                                       AR5K_QCU_MISC_CBR_THRES_ENABLE);
+               }
+
+               if (tq->tqi_ready_time &&
+               (tq->tqi_type != AR5K_TX_QUEUE_ID_CAB))
+                       ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_ready_time,
+                               AR5K_QCU_RDYTIMECFG_INTVAL) |
+                               AR5K_QCU_RDYTIMECFG_ENABLE,
+                               AR5K_QUEUE_RDYTIMECFG(queue));
+
+               if (tq->tqi_burst_time) {
+                       ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_burst_time,
+                               AR5K_DCU_CHAN_TIME_DUR) |
+                               AR5K_DCU_CHAN_TIME_ENABLE,
+                               AR5K_QUEUE_DFS_CHANNEL_TIME(queue));
+
+                       if (tq->tqi_flags
+                       & AR5K_TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE)
+                               AR5K_REG_ENABLE_BITS(ah,
+                                       AR5K_QUEUE_MISC(queue),
+                                       AR5K_QCU_MISC_RDY_VEOL_POLICY);
+               }
+
+               if (tq->tqi_flags & AR5K_TXQ_FLAG_BACKOFF_DISABLE)
+                       ath5k_hw_reg_write(ah, AR5K_DCU_MISC_POST_FR_BKOFF_DIS,
+                               AR5K_QUEUE_DFS_MISC(queue));
+
+               if (tq->tqi_flags & AR5K_TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE)
+                       ath5k_hw_reg_write(ah, AR5K_DCU_MISC_BACKOFF_FRAG,
+                               AR5K_QUEUE_DFS_MISC(queue));
+
+               /*
+                * Set registers by queue type
+                */
+               switch (tq->tqi_type) {
+               case AR5K_TX_QUEUE_BEACON:
+                       AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
+                               AR5K_QCU_MISC_FRSHED_DBA_GT |
+                               AR5K_QCU_MISC_CBREXP_BCN_DIS |
+                               AR5K_QCU_MISC_BCN_ENABLE);
+
+                       AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
+                               (AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL <<
+                               AR5K_DCU_MISC_ARBLOCK_CTL_S) |
+                               AR5K_DCU_MISC_ARBLOCK_IGNORE |
+                               AR5K_DCU_MISC_POST_FR_BKOFF_DIS |
+                               AR5K_DCU_MISC_BCN_ENABLE);
+                       break;
+
+               case AR5K_TX_QUEUE_CAB:
+                       AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
+                               AR5K_QCU_MISC_FRSHED_BCN_SENT_GT |
+                               AR5K_QCU_MISC_CBREXP_DIS |
+                               AR5K_QCU_MISC_RDY_VEOL_POLICY |
+                               AR5K_QCU_MISC_CBREXP_BCN_DIS);
+
+                       ath5k_hw_reg_write(ah, ((AR5K_TUNE_BEACON_INTERVAL -
+                               (AR5K_TUNE_SW_BEACON_RESP -
+                               AR5K_TUNE_DMA_BEACON_RESP) -
+                               AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF) * 1024) |
+                               AR5K_QCU_RDYTIMECFG_ENABLE,
+                               AR5K_QUEUE_RDYTIMECFG(queue));
+
+                       AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
+                               (AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL <<
+                               AR5K_DCU_MISC_ARBLOCK_CTL_S));
+                       break;
+
+               case AR5K_TX_QUEUE_UAPSD:
+                       AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
+                               AR5K_QCU_MISC_CBREXP_DIS);
+                       break;
+
+               case AR5K_TX_QUEUE_DATA:
+               default:
+                       break;
+               }
+
+               /* TODO: Handle frame compression */
+
+               /*
+                * Enable interrupts for this tx queue
+                * in the secondary interrupt mask registers
+                */
+               if (tq->tqi_flags & AR5K_TXQ_FLAG_TXOKINT_ENABLE)
+                       AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txok, queue);
+
+               if (tq->tqi_flags & AR5K_TXQ_FLAG_TXERRINT_ENABLE)
+                       AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txerr, queue);
+
+               if (tq->tqi_flags & AR5K_TXQ_FLAG_TXURNINT_ENABLE)
+                       AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txurn, queue);
+
+               if (tq->tqi_flags & AR5K_TXQ_FLAG_TXDESCINT_ENABLE)
+                       AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txdesc, queue);
+
+               if (tq->tqi_flags & AR5K_TXQ_FLAG_TXEOLINT_ENABLE)
+                       AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txeol, queue);
+
+               if (tq->tqi_flags & AR5K_TXQ_FLAG_CBRORNINT_ENABLE)
+                       AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_cbrorn, queue);
+
+               if (tq->tqi_flags & AR5K_TXQ_FLAG_CBRURNINT_ENABLE)
+                       AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_cbrurn, queue);
+
+               if (tq->tqi_flags & AR5K_TXQ_FLAG_QTRIGINT_ENABLE)
+                       AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_qtrig, queue);
+
+               if (tq->tqi_flags & AR5K_TXQ_FLAG_TXNOFRMINT_ENABLE)
+                       AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_nofrm, queue);
+
+               /* Update secondary interrupt mask registers */
+
+               /* Filter out inactive queues */
+               ah->ah_txq_imr_txok &= ah->ah_txq_status;
+               ah->ah_txq_imr_txerr &= ah->ah_txq_status;
+               ah->ah_txq_imr_txurn &= ah->ah_txq_status;
+               ah->ah_txq_imr_txdesc &= ah->ah_txq_status;
+               ah->ah_txq_imr_txeol &= ah->ah_txq_status;
+               ah->ah_txq_imr_cbrorn &= ah->ah_txq_status;
+               ah->ah_txq_imr_cbrurn &= ah->ah_txq_status;
+               ah->ah_txq_imr_qtrig &= ah->ah_txq_status;
+               ah->ah_txq_imr_nofrm &= ah->ah_txq_status;
+
+               ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txok,
+                       AR5K_SIMR0_QCU_TXOK) |
+                       AR5K_REG_SM(ah->ah_txq_imr_txdesc,
+                       AR5K_SIMR0_QCU_TXDESC), AR5K_SIMR0);
+               ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txerr,
+                       AR5K_SIMR1_QCU_TXERR) |
+                       AR5K_REG_SM(ah->ah_txq_imr_txeol,
+                       AR5K_SIMR1_QCU_TXEOL), AR5K_SIMR1);
+               /* Update simr2 but don't overwrite rest simr2 settings */
+               AR5K_REG_DISABLE_BITS(ah, AR5K_SIMR2, AR5K_SIMR2_QCU_TXURN);
+               AR5K_REG_ENABLE_BITS(ah, AR5K_SIMR2,
+                       AR5K_REG_SM(ah->ah_txq_imr_txurn,
+                       AR5K_SIMR2_QCU_TXURN));
+               ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_cbrorn,
+                       AR5K_SIMR3_QCBRORN) |
+                       AR5K_REG_SM(ah->ah_txq_imr_cbrurn,
+                       AR5K_SIMR3_QCBRURN), AR5K_SIMR3);
+               ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_qtrig,
+                       AR5K_SIMR4_QTRIG), AR5K_SIMR4);
+               /* Set TXNOFRM_QCU for the queues with TXNOFRM enabled */
+               ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_nofrm,
+                       AR5K_TXNOFRM_QCU), AR5K_TXNOFRM);
+               /* No queue has TXNOFRM enabled, disable the interrupt
+                * by setting AR5K_TXNOFRM to zero */
+               if (ah->ah_txq_imr_nofrm == 0)
+                       ath5k_hw_reg_write(ah, 0, AR5K_TXNOFRM);
+
+               /* Set QCU mask for this DCU to save power */
+               AR5K_REG_WRITE_Q(ah, AR5K_QUEUE_QCUMASK(queue), queue);
+       }
+
+       return 0;
+}
+
+/*
+ * Get slot time from DCU
+ */
+unsigned int ath5k_hw_get_slot_time(struct ath5k_hw *ah)
+{
+       ATH5K_TRACE(ah->ah_sc);
+       if (ah->ah_version == AR5K_AR5210)
+               return ath5k_hw_clocktoh(ath5k_hw_reg_read(ah,
+                               AR5K_SLOT_TIME) & 0xffff, ah->ah_turbo);
+       else
+               return ath5k_hw_reg_read(ah, AR5K_DCU_GBL_IFS_SLOT) & 0xffff;
+}
+
+/*
+ * Set slot time on DCU
+ */
+int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time)
+{
+       ATH5K_TRACE(ah->ah_sc);
+       if (slot_time < AR5K_SLOT_TIME_9 || slot_time > AR5K_SLOT_TIME_MAX)
+               return -EINVAL;
+
+       if (ah->ah_version == AR5K_AR5210)
+               ath5k_hw_reg_write(ah, ath5k_hw_htoclock(slot_time,
+                               ah->ah_turbo), AR5K_SLOT_TIME);
+       else
+               ath5k_hw_reg_write(ah, slot_time, AR5K_DCU_GBL_IFS_SLOT);
+
+       return 0;
+}
+
diff --git a/drivers/net/wireless/ath/ath5k/reg.h b/drivers/net/wireless/ath/ath5k/reg.h
new file mode 100644 (file)
index 0000000..6809b54
--- /dev/null
@@ -0,0 +1,2596 @@
+/*
+ * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
+ * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
+ * Copyright (c) 2007-2008 Michael Taylor <mike.taylor@apprion.com>
+ *
+ * Permission to use, copy, modify, and 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.
+ *
+ */
+
+/*
+ * Register values for Atheros 5210/5211/5212 cards from OpenBSD's ar5k
+ * maintained by Reyk Floeter
+ *
+ * I tried to document those registers by looking at ar5k code, some
+ * 802.11 (802.11e mostly) papers and by reading various public available
+ * Atheros presentations and papers like these:
+ *
+ * 5210 - http://nova.stanford.edu/~bbaas/ps/isscc2002_slides.pdf
+ *        http://www.it.iitb.ac.in/~janak/wifire/01222734.pdf
+ *
+ * 5211 - http://www.hotchips.org/archives/hc14/3_Tue/16_mcfarland.pdf
+ *
+ * This file also contains register values found on a memory dump of
+ * Atheros's ART program (Atheros Radio Test), on ath9k, on legacy-hal
+ * released by Atheros and on various debug messages found on the net.
+ */
+
+
+
+/*====MAC DMA REGISTERS====*/
+
+/*
+ * AR5210-Specific TXDP registers
+ * 5210 has only 2 transmit queues so no DCU/QCU, just
+ * 2 transmit descriptor pointers...
+ */
+#define AR5K_NOQCU_TXDP0       0x0000          /* Queue 0 - data */
+#define AR5K_NOQCU_TXDP1       0x0004          /* Queue 1 - beacons */
+
+/*
+ * Mac Control Register
+ */
+#define        AR5K_CR         0x0008                  /* Register Address */
+#define AR5K_CR_TXE0   0x00000001      /* TX Enable for queue 0 on 5210 */
+#define AR5K_CR_TXE1   0x00000002      /* TX Enable for queue 1 on 5210 */
+#define        AR5K_CR_RXE     0x00000004      /* RX Enable */
+#define AR5K_CR_TXD0   0x00000008      /* TX Disable for queue 0 on 5210 */
+#define AR5K_CR_TXD1   0x00000010      /* TX Disable for queue 1 on 5210 */
+#define        AR5K_CR_RXD     0x00000020      /* RX Disable */
+#define        AR5K_CR_SWI     0x00000040      /* Software Interrupt */
+
+/*
+ * RX Descriptor Pointer register
+ */
+#define        AR5K_RXDP       0x000c
+
+/*
+ * Configuration and status register
+ */
+#define        AR5K_CFG                0x0014                  /* Register Address */
+#define        AR5K_CFG_SWTD           0x00000001      /* Byte-swap TX descriptor (for big endian archs) */
+#define        AR5K_CFG_SWTB           0x00000002      /* Byte-swap TX buffer */
+#define        AR5K_CFG_SWRD           0x00000004      /* Byte-swap RX descriptor */
+#define        AR5K_CFG_SWRB           0x00000008      /* Byte-swap RX buffer */
+#define        AR5K_CFG_SWRG           0x00000010      /* Byte-swap Register access */
+#define AR5K_CFG_IBSS          0x00000020      /* 0-BSS, 1-IBSS [5211+] */
+#define AR5K_CFG_PHY_OK                0x00000100      /* [5211+] */
+#define AR5K_CFG_EEBS          0x00000200      /* EEPROM is busy */
+#define        AR5K_CFG_CLKGD          0x00000400      /* Clock gated (Disable dynamic clock) */
+#define AR5K_CFG_TXCNT         0x00007800      /* Tx frame count (?) [5210] */
+#define AR5K_CFG_TXCNT_S       11
+#define AR5K_CFG_TXFSTAT       0x00008000      /* Tx frame status (?) [5210] */
+#define AR5K_CFG_TXFSTRT       0x00010000      /* [5210] */
+#define        AR5K_CFG_PCI_THRES      0x00060000      /* PCI Master req q threshold [5211+] */
+#define        AR5K_CFG_PCI_THRES_S    17
+
+/*
+ * Interrupt enable register
+ */
+#define AR5K_IER               0x0024          /* Register Address */
+#define AR5K_IER_DISABLE       0x00000000      /* Disable card interrupts */
+#define AR5K_IER_ENABLE                0x00000001      /* Enable card interrupts */
+
+
+/*
+ * 0x0028 is Beacon Control Register on 5210
+ * and first RTS duration register on 5211
+ */
+
+/*
+ * Beacon control register [5210]
+ */
+#define AR5K_BCR               0x0028          /* Register Address */
+#define AR5K_BCR_AP            0x00000000      /* AP mode */
+#define AR5K_BCR_ADHOC         0x00000001      /* Ad-Hoc mode */
+#define AR5K_BCR_BDMAE         0x00000002      /* DMA enable */
+#define AR5K_BCR_TQ1FV         0x00000004      /* Use Queue1 for CAB traffic */
+#define AR5K_BCR_TQ1V          0x00000008      /* Use Queue1 for Beacon traffic */
+#define AR5K_BCR_BCGET         0x00000010
+
+/*
+ * First RTS duration register [5211]
+ */
+#define AR5K_RTSD0             0x0028          /* Register Address */
+#define        AR5K_RTSD0_6            0x000000ff      /* 6Mb RTS duration mask (?) */
+#define        AR5K_RTSD0_6_S          0               /* 6Mb RTS duration shift (?) */
+#define        AR5K_RTSD0_9            0x0000ff00      /* 9Mb*/
+#define        AR5K_RTSD0_9_S          8
+#define        AR5K_RTSD0_12           0x00ff0000      /* 12Mb*/
+#define        AR5K_RTSD0_12_S         16
+#define        AR5K_RTSD0_18           0xff000000      /* 16Mb*/
+#define        AR5K_RTSD0_18_S         24
+
+
+/*
+ * 0x002c is Beacon Status Register on 5210
+ * and second RTS duration register on 5211
+ */
+
+/*
+ * Beacon status register [5210]
+ *
+ * As i can see in ar5k_ar5210_tx_start Reyk uses some of the values of BCR
+ * for this register, so i guess TQ1V,TQ1FV and BDMAE have the same meaning
+ * here and SNP/SNAP means "snapshot" (so this register gets synced with BCR).
+ * So SNAPPEDBCRVALID sould also stand for "snapped BCR -values- valid", so i
+ * renamed it to SNAPSHOTSVALID to make more sense. I realy have no idea what
+ * else can it be. I also renamed SNPBCMD to SNPADHOC to match BCR.
+ */
+#define AR5K_BSR               0x002c                  /* Register Address */
+#define AR5K_BSR_BDLYSW                0x00000001      /* SW Beacon delay (?) */
+#define AR5K_BSR_BDLYDMA       0x00000002      /* DMA Beacon delay (?) */
+#define AR5K_BSR_TXQ1F         0x00000004      /* Beacon queue (1) finished */
+#define AR5K_BSR_ATIMDLY       0x00000008      /* ATIM delay (?) */
+#define AR5K_BSR_SNPADHOC      0x00000100      /* Ad-hoc mode set (?) */
+#define AR5K_BSR_SNPBDMAE      0x00000200      /* Beacon DMA enabled (?) */
+#define AR5K_BSR_SNPTQ1FV      0x00000400      /* Queue1 is used for CAB traffic (?) */
+#define AR5K_BSR_SNPTQ1V       0x00000800      /* Queue1 is used for Beacon traffic (?) */
+#define AR5K_BSR_SNAPSHOTSVALID        0x00001000      /* BCR snapshots are valid (?) */
+#define AR5K_BSR_SWBA_CNT      0x00ff0000
+
+/*
+ * Second RTS duration register [5211]
+ */
+#define AR5K_RTSD1             0x002c                  /* Register Address */
+#define        AR5K_RTSD1_24           0x000000ff      /* 24Mb */
+#define        AR5K_RTSD1_24_S         0
+#define        AR5K_RTSD1_36           0x0000ff00      /* 36Mb */
+#define        AR5K_RTSD1_36_S         8
+#define        AR5K_RTSD1_48           0x00ff0000      /* 48Mb */
+#define        AR5K_RTSD1_48_S         16
+#define        AR5K_RTSD1_54           0xff000000      /* 54Mb */
+#define        AR5K_RTSD1_54_S         24
+
+
+/*
+ * Transmit configuration register
+ */
+#define AR5K_TXCFG                     0x0030                  /* Register Address */
+#define AR5K_TXCFG_SDMAMR              0x00000007      /* DMA size (read) */
+#define AR5K_TXCFG_SDMAMR_S            0
+#define AR5K_TXCFG_B_MODE              0x00000008      /* Set b mode for 5111 (enable 2111) */
+#define AR5K_TXCFG_TXFSTP              0x00000008      /* TX DMA full Stop [5210] */
+#define AR5K_TXCFG_TXFULL              0x000003f0      /* TX Triger level mask */
+#define AR5K_TXCFG_TXFULL_S            4
+#define AR5K_TXCFG_TXFULL_0B           0x00000000
+#define AR5K_TXCFG_TXFULL_64B          0x00000010
+#define AR5K_TXCFG_TXFULL_128B         0x00000020
+#define AR5K_TXCFG_TXFULL_192B         0x00000030
+#define AR5K_TXCFG_TXFULL_256B         0x00000040
+#define AR5K_TXCFG_TXCONT_EN           0x00000080
+#define AR5K_TXCFG_DMASIZE             0x00000100      /* Flag for passing DMA size [5210] */
+#define AR5K_TXCFG_JUMBO_DESC_EN       0x00000400      /* Enable jumbo tx descriptors [5211+] */
+#define AR5K_TXCFG_ADHOC_BCN_ATIM      0x00000800      /* Adhoc Beacon ATIM Policy */
+#define AR5K_TXCFG_ATIM_WINDOW_DEF_DIS 0x00001000      /* Disable ATIM window defer [5211+] */
+#define AR5K_TXCFG_RTSRND              0x00001000      /* [5211+] */
+#define AR5K_TXCFG_FRMPAD_DIS          0x00002000      /* [5211+] */
+#define AR5K_TXCFG_RDY_CBR_DIS         0x00004000      /* Ready time CBR disable [5211+] */
+#define AR5K_TXCFG_JUMBO_FRM_MODE      0x00008000      /* Jumbo frame mode [5211+] */
+#define        AR5K_TXCFG_DCU_DBL_BUF_DIS      0x00008000      /* Disable double buffering on DCU */
+#define AR5K_TXCFG_DCU_CACHING_DIS     0x00010000      /* Disable DCU caching */
+
+/*
+ * Receive configuration register
+ */
+#define AR5K_RXCFG             0x0034                  /* Register Address */
+#define AR5K_RXCFG_SDMAMW      0x00000007      /* DMA size (write) */
+#define AR5K_RXCFG_SDMAMW_S    0
+#define AR5K_RXCFG_ZLFDMA      0x00000008      /* Enable Zero-length frame DMA */
+#define        AR5K_RXCFG_DEF_ANTENNA  0x00000010      /* Default antenna (?) */
+#define AR5K_RXCFG_JUMBO_RXE   0x00000020      /* Enable jumbo rx descriptors [5211+] */
+#define AR5K_RXCFG_JUMBO_WRAP  0x00000040      /* Wrap jumbo frames [5211+] */
+#define AR5K_RXCFG_SLE_ENTRY   0x00000080      /* Sleep entry policy */
+
+/*
+ * Receive jumbo descriptor last address register
+ * Only found in 5211 (?)
+ */
+#define AR5K_RXJLA             0x0038
+
+/*
+ * MIB control register
+ */
+#define AR5K_MIBC              0x0040                  /* Register Address */
+#define AR5K_MIBC_COW          0x00000001      /* Warn test indicator */
+#define AR5K_MIBC_FMC          0x00000002      /* Freeze MIB Counters  */
+#define AR5K_MIBC_CMC          0x00000004      /* Clean MIB Counters  */
+#define AR5K_MIBC_MCS          0x00000008      /* MIB counter strobe */
+
+/*
+ * Timeout prescale register
+ */
+#define AR5K_TOPS              0x0044
+#define        AR5K_TOPS_M             0x0000ffff
+
+/*
+ * Receive timeout register (no frame received)
+ */
+#define AR5K_RXNOFRM           0x0048
+#define        AR5K_RXNOFRM_M          0x000003ff
+
+/*
+ * Transmit timeout register (no frame sent)
+ */
+#define AR5K_TXNOFRM           0x004c
+#define        AR5K_TXNOFRM_M          0x000003ff
+#define        AR5K_TXNOFRM_QCU        0x000ffc00
+#define        AR5K_TXNOFRM_QCU_S      10
+
+/*
+ * Receive frame gap timeout register
+ */
+#define AR5K_RPGTO             0x0050
+#define AR5K_RPGTO_M           0x000003ff
+
+/*
+ * Receive frame count limit register
+ */
+#define AR5K_RFCNT             0x0054
+#define AR5K_RFCNT_M           0x0000001f      /* [5211+] (?) */
+#define AR5K_RFCNT_RFCL                0x0000000f      /* [5210] */
+
+/*
+ * Misc settings register
+ * (reserved0-3)
+ */
+#define AR5K_MISC              0x0058                  /* Register Address */
+#define        AR5K_MISC_DMA_OBS_M     0x000001e0
+#define        AR5K_MISC_DMA_OBS_S     5
+#define        AR5K_MISC_MISC_OBS_M    0x00000e00
+#define        AR5K_MISC_MISC_OBS_S    9
+#define        AR5K_MISC_MAC_OBS_LSB_M 0x00007000
+#define        AR5K_MISC_MAC_OBS_LSB_S 12
+#define        AR5K_MISC_MAC_OBS_MSB_M 0x00038000
+#define        AR5K_MISC_MAC_OBS_MSB_S 15
+#define AR5K_MISC_LED_DECAY    0x001c0000      /* [5210] */
+#define AR5K_MISC_LED_BLINK    0x00e00000      /* [5210] */
+
+/*
+ * QCU/DCU clock gating register (5311)
+ * (reserved4-5)
+ */
+#define        AR5K_QCUDCU_CLKGT       0x005c                  /* Register Address (?) */
+#define        AR5K_QCUDCU_CLKGT_QCU   0x0000ffff      /* Mask for QCU clock */
+#define        AR5K_QCUDCU_CLKGT_DCU   0x07ff0000      /* Mask for DCU clock */
+
+/*
+ * Interrupt Status Registers
+ *
+ * For 5210 there is only one status register but for
+ * 5211/5212 we have one primary and 4 secondary registers.
+ * So we have AR5K_ISR for 5210 and AR5K_PISR /SISRx for 5211/5212.
+ * Most of these bits are common for all chipsets.
+ */
+#define AR5K_ISR               0x001c                  /* Register Address [5210] */
+#define AR5K_PISR              0x0080                  /* Register Address [5211+] */
+#define AR5K_ISR_RXOK          0x00000001      /* Frame successfuly recieved */
+#define AR5K_ISR_RXDESC                0x00000002      /* RX descriptor request */
+#define AR5K_ISR_RXERR         0x00000004      /* Receive error */
+#define AR5K_ISR_RXNOFRM       0x00000008      /* No frame received (receive timeout) */
+#define AR5K_ISR_RXEOL         0x00000010      /* Empty RX descriptor */
+#define AR5K_ISR_RXORN         0x00000020      /* Receive FIFO overrun */
+#define AR5K_ISR_TXOK          0x00000040      /* Frame successfuly transmited */
+#define AR5K_ISR_TXDESC                0x00000080      /* TX descriptor request */
+#define AR5K_ISR_TXERR         0x00000100      /* Transmit error */
+#define AR5K_ISR_TXNOFRM       0x00000200      /* No frame transmited (transmit timeout) */
+#define AR5K_ISR_TXEOL         0x00000400      /* Empty TX descriptor */
+#define AR5K_ISR_TXURN         0x00000800      /* Transmit FIFO underrun */
+#define AR5K_ISR_MIB           0x00001000      /* Update MIB counters */
+#define AR5K_ISR_SWI           0x00002000      /* Software interrupt */
+#define AR5K_ISR_RXPHY         0x00004000      /* PHY error */
+#define AR5K_ISR_RXKCM         0x00008000      /* RX Key cache miss */
+#define AR5K_ISR_SWBA          0x00010000      /* Software beacon alert */
+#define AR5K_ISR_BRSSI         0x00020000      /* Beacon rssi below threshold (?) */
+#define AR5K_ISR_BMISS         0x00040000      /* Beacon missed */
+#define AR5K_ISR_HIUERR                0x00080000      /* Host Interface Unit error [5211+] */
+#define AR5K_ISR_BNR           0x00100000      /* Beacon not ready [5211+] */
+#define AR5K_ISR_MCABT         0x00100000      /* Master Cycle Abort [5210] */
+#define AR5K_ISR_RXCHIRP       0x00200000      /* CHIRP Received [5212+] */
+#define AR5K_ISR_SSERR         0x00200000      /* Signaled System Error [5210] */
+#define AR5K_ISR_DPERR         0x00400000      /* Det par Error (?) [5210] */
+#define AR5K_ISR_RXDOPPLER     0x00400000      /* Doppler chirp received [5212+] */
+#define AR5K_ISR_TIM           0x00800000      /* [5211+] */
+#define AR5K_ISR_BCNMISC       0x00800000      /* 'or' of TIM, CAB_END, DTIM_SYNC, BCN_TIMEOUT,
+                                               CAB_TIMEOUT and DTIM bits from SISR2 [5212+] */
+#define AR5K_ISR_GPIO          0x01000000      /* GPIO (rf kill) */
+#define AR5K_ISR_QCBRORN       0x02000000      /* QCU CBR overrun [5211+] */
+#define AR5K_ISR_QCBRURN       0x04000000      /* QCU CBR underrun [5211+] */
+#define AR5K_ISR_QTRIG         0x08000000      /* QCU scheduling trigger [5211+] */
+
+/*
+ * Secondary status registers [5211+] (0 - 4)
+ *
+ * These give the status for each QCU, only QCUs 0-9 are
+ * represented.
+ */
+#define AR5K_SISR0             0x0084                  /* Register Address [5211+] */
+#define AR5K_SISR0_QCU_TXOK    0x000003ff      /* Mask for QCU_TXOK */
+#define AR5K_SISR0_QCU_TXOK_S  0
+#define AR5K_SISR0_QCU_TXDESC  0x03ff0000      /* Mask for QCU_TXDESC */
+#define AR5K_SISR0_QCU_TXDESC_S        16
+
+#define AR5K_SISR1             0x0088                  /* Register Address [5211+] */
+#define AR5K_SISR1_QCU_TXERR   0x000003ff      /* Mask for QCU_TXERR */
+#define AR5K_SISR1_QCU_TXERR_S 0
+#define AR5K_SISR1_QCU_TXEOL   0x03ff0000      /* Mask for QCU_TXEOL */
+#define AR5K_SISR1_QCU_TXEOL_S 16
+
+#define AR5K_SISR2             0x008c                  /* Register Address [5211+] */
+#define AR5K_SISR2_QCU_TXURN   0x000003ff      /* Mask for QCU_TXURN */
+#define        AR5K_SISR2_QCU_TXURN_S  0
+#define        AR5K_SISR2_MCABT        0x00100000      /* Master Cycle Abort */
+#define        AR5K_SISR2_SSERR        0x00200000      /* Signaled System Error */
+#define        AR5K_SISR2_DPERR        0x00400000      /* Bus parity error */
+#define        AR5K_SISR2_TIM          0x01000000      /* [5212+] */
+#define        AR5K_SISR2_CAB_END      0x02000000      /* [5212+] */
+#define        AR5K_SISR2_DTIM_SYNC    0x04000000      /* DTIM sync lost [5212+] */
+#define        AR5K_SISR2_BCN_TIMEOUT  0x08000000      /* Beacon Timeout [5212+] */
+#define        AR5K_SISR2_CAB_TIMEOUT  0x10000000      /* CAB Timeout [5212+] */
+#define        AR5K_SISR2_DTIM         0x20000000      /* [5212+] */
+#define        AR5K_SISR2_TSFOOR       0x80000000      /* TSF OOR (?) */
+
+#define AR5K_SISR3             0x0090                  /* Register Address [5211+] */
+#define AR5K_SISR3_QCBRORN     0x000003ff      /* Mask for QCBRORN */
+#define AR5K_SISR3_QCBRORN_S   0
+#define AR5K_SISR3_QCBRURN     0x03ff0000      /* Mask for QCBRURN */
+#define AR5K_SISR3_QCBRURN_S   16
+
+#define AR5K_SISR4             0x0094                  /* Register Address [5211+] */
+#define AR5K_SISR4_QTRIG       0x000003ff      /* Mask for QTRIG */
+#define AR5K_SISR4_QTRIG_S     0
+
+/*
+ * Shadow read-and-clear interrupt status registers [5211+]
+ */
+#define AR5K_RAC_PISR          0x00c0          /* Read and clear PISR */
+#define AR5K_RAC_SISR0         0x00c4          /* Read and clear SISR0 */
+#define AR5K_RAC_SISR1         0x00c8          /* Read and clear SISR1 */
+#define AR5K_RAC_SISR2         0x00cc          /* Read and clear SISR2 */
+#define AR5K_RAC_SISR3         0x00d0          /* Read and clear SISR3 */
+#define AR5K_RAC_SISR4         0x00d4          /* Read and clear SISR4 */
+
+/*
+ * Interrupt Mask Registers
+ *
+ * As whith ISRs 5210 has one IMR (AR5K_IMR) and 5211/5212 has one primary
+ * (AR5K_PIMR) and 4 secondary IMRs (AR5K_SIMRx). Note that ISR/IMR flags match.
+ */
+#define        AR5K_IMR                0x0020                  /* Register Address [5210] */
+#define AR5K_PIMR              0x00a0                  /* Register Address [5211+] */
+#define AR5K_IMR_RXOK          0x00000001      /* Frame successfuly recieved*/
+#define AR5K_IMR_RXDESC                0x00000002      /* RX descriptor request*/
+#define AR5K_IMR_RXERR         0x00000004      /* Receive error*/
+#define AR5K_IMR_RXNOFRM       0x00000008      /* No frame received (receive timeout)*/
+#define AR5K_IMR_RXEOL         0x00000010      /* Empty RX descriptor*/
+#define AR5K_IMR_RXORN         0x00000020      /* Receive FIFO overrun*/
+#define AR5K_IMR_TXOK          0x00000040      /* Frame successfuly transmited*/
+#define AR5K_IMR_TXDESC                0x00000080      /* TX descriptor request*/
+#define AR5K_IMR_TXERR         0x00000100      /* Transmit error*/
+#define AR5K_IMR_TXNOFRM       0x00000200      /* No frame transmited (transmit timeout)*/
+#define AR5K_IMR_TXEOL         0x00000400      /* Empty TX descriptor*/
+#define AR5K_IMR_TXURN         0x00000800      /* Transmit FIFO underrun*/
+#define AR5K_IMR_MIB           0x00001000      /* Update MIB counters*/
+#define AR5K_IMR_SWI           0x00002000      /* Software interrupt */
+#define AR5K_IMR_RXPHY         0x00004000      /* PHY error*/
+#define AR5K_IMR_RXKCM         0x00008000      /* RX Key cache miss */
+#define AR5K_IMR_SWBA          0x00010000      /* Software beacon alert*/
+#define AR5K_IMR_BRSSI         0x00020000      /* Beacon rssi below threshold (?) */
+#define AR5K_IMR_BMISS         0x00040000      /* Beacon missed*/
+#define AR5K_IMR_HIUERR                0x00080000      /* Host Interface Unit error [5211+] */
+#define AR5K_IMR_BNR           0x00100000      /* Beacon not ready [5211+] */
+#define AR5K_IMR_MCABT         0x00100000      /* Master Cycle Abort [5210] */
+#define AR5K_IMR_RXCHIRP       0x00200000      /* CHIRP Received [5212+]*/
+#define AR5K_IMR_SSERR         0x00200000      /* Signaled System Error [5210] */
+#define AR5K_IMR_DPERR         0x00400000      /* Det par Error (?) [5210] */
+#define AR5K_IMR_RXDOPPLER     0x00400000      /* Doppler chirp received [5212+] */
+#define AR5K_IMR_TIM           0x00800000      /* [5211+] */
+#define AR5K_IMR_BCNMISC       0x00800000      /* 'or' of TIM, CAB_END, DTIM_SYNC, BCN_TIMEOUT,
+                                               CAB_TIMEOUT and DTIM bits from SISR2 [5212+] */
+#define AR5K_IMR_GPIO          0x01000000      /* GPIO (rf kill)*/
+#define AR5K_IMR_QCBRORN       0x02000000      /* QCU CBR overrun (?) [5211+] */
+#define AR5K_IMR_QCBRURN       0x04000000      /* QCU CBR underrun (?) [5211+] */
+#define AR5K_IMR_QTRIG         0x08000000      /* QCU scheduling trigger [5211+] */
+
+/*
+ * Secondary interrupt mask registers [5211+] (0 - 4)
+ */
+#define AR5K_SIMR0             0x00a4                  /* Register Address [5211+] */
+#define AR5K_SIMR0_QCU_TXOK    0x000003ff      /* Mask for QCU_TXOK */
+#define AR5K_SIMR0_QCU_TXOK_S  0
+#define AR5K_SIMR0_QCU_TXDESC  0x03ff0000      /* Mask for QCU_TXDESC */
+#define AR5K_SIMR0_QCU_TXDESC_S        16
+
+#define AR5K_SIMR1             0x00a8                  /* Register Address [5211+] */
+#define AR5K_SIMR1_QCU_TXERR   0x000003ff      /* Mask for QCU_TXERR */
+#define AR5K_SIMR1_QCU_TXERR_S 0
+#define AR5K_SIMR1_QCU_TXEOL   0x03ff0000      /* Mask for QCU_TXEOL */
+#define AR5K_SIMR1_QCU_TXEOL_S 16
+
+#define AR5K_SIMR2             0x00ac                  /* Register Address [5211+] */
+#define AR5K_SIMR2_QCU_TXURN   0x000003ff      /* Mask for QCU_TXURN */
+#define AR5K_SIMR2_QCU_TXURN_S 0
+#define        AR5K_SIMR2_MCABT        0x00100000      /* Master Cycle Abort */
+#define        AR5K_SIMR2_SSERR        0x00200000      /* Signaled System Error */
+#define        AR5K_SIMR2_DPERR        0x00400000      /* Bus parity error */
+#define        AR5K_SIMR2_TIM          0x01000000      /* [5212+] */
+#define        AR5K_SIMR2_CAB_END      0x02000000      /* [5212+] */
+#define        AR5K_SIMR2_DTIM_SYNC    0x04000000      /* DTIM Sync lost [5212+] */
+#define        AR5K_SIMR2_BCN_TIMEOUT  0x08000000      /* Beacon Timeout [5212+] */
+#define        AR5K_SIMR2_CAB_TIMEOUT  0x10000000      /* CAB Timeout [5212+] */
+#define        AR5K_SIMR2_DTIM         0x20000000      /* [5212+] */
+#define        AR5K_SIMR2_TSFOOR       0x80000000      /* TSF OOR (?) */
+
+#define AR5K_SIMR3             0x00b0                  /* Register Address [5211+] */
+#define AR5K_SIMR3_QCBRORN     0x000003ff      /* Mask for QCBRORN */
+#define AR5K_SIMR3_QCBRORN_S   0
+#define AR5K_SIMR3_QCBRURN     0x03ff0000      /* Mask for QCBRURN */
+#define AR5K_SIMR3_QCBRURN_S   16
+
+#define AR5K_SIMR4             0x00b4                  /* Register Address [5211+] */
+#define AR5K_SIMR4_QTRIG       0x000003ff      /* Mask for QTRIG */
+#define AR5K_SIMR4_QTRIG_S     0
+
+/*
+ * DMA Debug registers 0-7
+ * 0xe0 - 0xfc
+ */
+
+/*
+ * Decompression mask registers [5212+]
+ */
+#define AR5K_DCM_ADDR          0x0400          /*Decompression mask address (index) */
+#define AR5K_DCM_DATA          0x0404          /*Decompression mask data */
+
+/*
+ * Wake On Wireless pattern control register [5212+]
+ */
+#define        AR5K_WOW_PCFG                   0x0410                  /* Register Address */
+#define        AR5K_WOW_PCFG_PAT_MATCH_EN      0x00000001      /* Pattern match enable */
+#define        AR5K_WOW_PCFG_LONG_FRAME_POL    0x00000002      /* Long frame policy */
+#define        AR5K_WOW_PCFG_WOBMISS           0x00000004      /* Wake on bea(con) miss (?) */
+#define        AR5K_WOW_PCFG_PAT_0_EN          0x00000100      /* Enable pattern 0 */
+#define        AR5K_WOW_PCFG_PAT_1_EN          0x00000200      /* Enable pattern 1 */
+#define        AR5K_WOW_PCFG_PAT_2_EN          0x00000400      /* Enable pattern 2 */
+#define        AR5K_WOW_PCFG_PAT_3_EN          0x00000800      /* Enable pattern 3 */
+#define        AR5K_WOW_PCFG_PAT_4_EN          0x00001000      /* Enable pattern 4 */
+#define        AR5K_WOW_PCFG_PAT_5_EN          0x00002000      /* Enable pattern 5 */
+
+/*
+ * Wake On Wireless pattern index register (?) [5212+]
+ */
+#define        AR5K_WOW_PAT_IDX        0x0414
+
+/*
+ * Wake On Wireless pattern data register [5212+]
+ */
+#define        AR5K_WOW_PAT_DATA       0x0418                  /* Register Address */
+#define        AR5K_WOW_PAT_DATA_0_3_V 0x00000001      /* Pattern 0, 3 value */
+#define        AR5K_WOW_PAT_DATA_1_4_V 0x00000100      /* Pattern 1, 4 value */
+#define        AR5K_WOW_PAT_DATA_2_5_V 0x00010000      /* Pattern 2, 5 value */
+#define        AR5K_WOW_PAT_DATA_0_3_M 0x01000000      /* Pattern 0, 3 mask */
+#define        AR5K_WOW_PAT_DATA_1_4_M 0x04000000      /* Pattern 1, 4 mask */
+#define        AR5K_WOW_PAT_DATA_2_5_M 0x10000000      /* Pattern 2, 5 mask */
+
+/*
+ * Decompression configuration registers [5212+]
+ */
+#define AR5K_DCCFG             0x0420                  /* Register Address */
+#define AR5K_DCCFG_GLOBAL_EN   0x00000001      /* Enable decompression on all queues */
+#define AR5K_DCCFG_BYPASS_EN   0x00000002      /* Bypass decompression */
+#define AR5K_DCCFG_BCAST_EN    0x00000004      /* Enable decompression for bcast frames */
+#define AR5K_DCCFG_MCAST_EN    0x00000008      /* Enable decompression for mcast frames */
+
+/*
+ * Compression configuration registers [5212+]
+ */
+#define AR5K_CCFG              0x0600                  /* Register Address */
+#define        AR5K_CCFG_WINDOW_SIZE   0x00000007      /* Compression window size */
+#define        AR5K_CCFG_CPC_EN        0x00000008      /* Enable performance counters */
+
+#define AR5K_CCFG_CCU          0x0604                  /* Register Address */
+#define AR5K_CCFG_CCU_CUP_EN   0x00000001      /* CCU Catchup enable */
+#define AR5K_CCFG_CCU_CREDIT   0x00000002      /* CCU Credit (field) */
+#define AR5K_CCFG_CCU_CD_THRES 0x00000080      /* CCU Cyc(lic?) debt threshold (field) */
+#define AR5K_CCFG_CCU_CUP_LCNT 0x00010000      /* CCU Catchup lit(?) count */
+#define        AR5K_CCFG_CCU_INIT      0x00100200      /* Initial value during reset */
+
+/*
+ * Compression performance counter registers [5212+]
+ */
+#define AR5K_CPC0              0x0610          /* Compression performance counter 0 */
+#define AR5K_CPC1              0x0614          /* Compression performance counter 1*/
+#define AR5K_CPC2              0x0618          /* Compression performance counter 2 */
+#define AR5K_CPC3              0x061c          /* Compression performance counter 3 */
+#define AR5K_CPCOVF            0x0620          /* Compression performance overflow */
+
+
+/*
+ * Queue control unit (QCU) registers [5211+]
+ *
+ * Card has 12 TX Queues but i see that only 0-9 are used (?)
+ * both in binary HAL (see ah.h) and ar5k. Each queue has it's own
+ * TXDP at addresses 0x0800 - 0x082c, a CBR (Constant Bit Rate)
+ * configuration register (0x08c0 - 0x08ec), a ready time configuration
+ * register (0x0900 - 0x092c), a misc configuration register (0x09c0 -
+ * 0x09ec) and a status register (0x0a00 - 0x0a2c). We also have some
+ * global registers, QCU transmit enable/disable and "one shot arm (?)"
+ * set/clear, which contain status for all queues (we shift by 1 for each
+ * queue). To access these registers easily we define some macros here
+ * that are used inside HAL. For more infos check out *_tx_queue functs.
+ */
+
+/*
+ * Generic QCU Register access macros
+ */
+#define        AR5K_QUEUE_REG(_r, _q)          (((_q) << 2) + _r)
+#define AR5K_QCU_GLOBAL_READ(_r, _q)   (AR5K_REG_READ(_r) & (1 << _q))
+#define AR5K_QCU_GLOBAL_WRITE(_r, _q)  AR5K_REG_WRITE(_r, (1 << _q))
+
+/*
+ * QCU Transmit descriptor pointer registers
+ */
+#define AR5K_QCU_TXDP_BASE     0x0800          /* Register Address - Queue0 TXDP */
+#define AR5K_QUEUE_TXDP(_q)    AR5K_QUEUE_REG(AR5K_QCU_TXDP_BASE, _q)
+
+/*
+ * QCU Transmit enable register
+ */
+#define AR5K_QCU_TXE           0x0840
+#define AR5K_ENABLE_QUEUE(_q)  AR5K_QCU_GLOBAL_WRITE(AR5K_QCU_TXE, _q)
+#define AR5K_QUEUE_ENABLED(_q) AR5K_QCU_GLOBAL_READ(AR5K_QCU_TXE, _q)
+
+/*
+ * QCU Transmit disable register
+ */
+#define AR5K_QCU_TXD           0x0880
+#define AR5K_DISABLE_QUEUE(_q) AR5K_QCU_GLOBAL_WRITE(AR5K_QCU_TXD, _q)
+#define AR5K_QUEUE_DISABLED(_q)        AR5K_QCU_GLOBAL_READ(AR5K_QCU_TXD, _q)
+
+/*
+ * QCU Constant Bit Rate configuration registers
+ */
+#define        AR5K_QCU_CBRCFG_BASE            0x08c0  /* Register Address - Queue0 CBRCFG */
+#define        AR5K_QCU_CBRCFG_INTVAL          0x00ffffff      /* CBR Interval mask */
+#define AR5K_QCU_CBRCFG_INTVAL_S       0
+#define        AR5K_QCU_CBRCFG_ORN_THRES       0xff000000      /* CBR overrun threshold mask */
+#define AR5K_QCU_CBRCFG_ORN_THRES_S    24
+#define        AR5K_QUEUE_CBRCFG(_q)           AR5K_QUEUE_REG(AR5K_QCU_CBRCFG_BASE, _q)
+
+/*
+ * QCU Ready time configuration registers
+ */
+#define        AR5K_QCU_RDYTIMECFG_BASE        0x0900  /* Register Address - Queue0 RDYTIMECFG */
+#define        AR5K_QCU_RDYTIMECFG_INTVAL      0x00ffffff      /* Ready time interval mask */
+#define AR5K_QCU_RDYTIMECFG_INTVAL_S   0
+#define        AR5K_QCU_RDYTIMECFG_ENABLE      0x01000000      /* Ready time enable mask */
+#define AR5K_QUEUE_RDYTIMECFG(_q)      AR5K_QUEUE_REG(AR5K_QCU_RDYTIMECFG_BASE, _q)
+
+/*
+ * QCU one shot arm set registers
+ */
+#define        AR5K_QCU_ONESHOTARM_SET         0x0940  /* Register Address -QCU "one shot arm set (?)" */
+#define        AR5K_QCU_ONESHOTARM_SET_M       0x0000ffff
+
+/*
+ * QCU one shot arm clear registers
+ */
+#define        AR5K_QCU_ONESHOTARM_CLEAR       0x0980  /* Register Address -QCU "one shot arm clear (?)" */
+#define        AR5K_QCU_ONESHOTARM_CLEAR_M     0x0000ffff
+
+/*
+ * QCU misc registers
+ */
+#define AR5K_QCU_MISC_BASE             0x09c0                  /* Register Address -Queue0 MISC */
+#define        AR5K_QCU_MISC_FRSHED_M          0x0000000f      /* Frame sheduling mask */
+#define        AR5K_QCU_MISC_FRSHED_ASAP               0       /* ASAP */
+#define        AR5K_QCU_MISC_FRSHED_CBR                1       /* Constant Bit Rate */
+#define        AR5K_QCU_MISC_FRSHED_DBA_GT             2       /* DMA Beacon alert gated */
+#define        AR5K_QCU_MISC_FRSHED_TIM_GT             3       /* TIMT gated */
+#define        AR5K_QCU_MISC_FRSHED_BCN_SENT_GT        4       /* Beacon sent gated */
+#define        AR5K_QCU_MISC_ONESHOT_ENABLE    0x00000010      /* Oneshot enable */
+#define        AR5K_QCU_MISC_CBREXP_DIS        0x00000020      /* Disable CBR expired counter (normal queue) */
+#define        AR5K_QCU_MISC_CBREXP_BCN_DIS    0x00000040      /* Disable CBR expired counter (beacon queue) */
+#define        AR5K_QCU_MISC_BCN_ENABLE        0x00000080      /* Enable Beacon use */
+#define        AR5K_QCU_MISC_CBR_THRES_ENABLE  0x00000100      /* CBR expired threshold enabled */
+#define        AR5K_QCU_MISC_RDY_VEOL_POLICY   0x00000200      /* TXE reset when RDYTIME expired or VEOL */
+#define        AR5K_QCU_MISC_CBR_RESET_CNT     0x00000400      /* CBR threshold (counter) reset */
+#define        AR5K_QCU_MISC_DCU_EARLY         0x00000800      /* DCU early termination */
+#define AR5K_QCU_MISC_DCU_CMP_EN       0x00001000      /* Enable frame compression */
+#define AR5K_QUEUE_MISC(_q)            AR5K_QUEUE_REG(AR5K_QCU_MISC_BASE, _q)
+
+
+/*
+ * QCU status registers
+ */
+#define AR5K_QCU_STS_BASE      0x0a00                  /* Register Address - Queue0 STS */
+#define        AR5K_QCU_STS_FRMPENDCNT 0x00000003      /* Frames pending counter */
+#define        AR5K_QCU_STS_CBREXPCNT  0x0000ff00      /* CBR expired counter */
+#define        AR5K_QUEUE_STATUS(_q)   AR5K_QUEUE_REG(AR5K_QCU_STS_BASE, _q)
+
+/*
+ * QCU ready time shutdown register
+ */
+#define AR5K_QCU_RDYTIMESHDN   0x0a40
+#define AR5K_QCU_RDYTIMESHDN_M 0x000003ff
+
+/*
+ * QCU compression buffer base registers [5212+]
+ */
+#define AR5K_QCU_CBB_SELECT    0x0b00
+#define AR5K_QCU_CBB_ADDR      0x0b04
+#define AR5K_QCU_CBB_ADDR_S    9
+
+/*
+ * QCU compression buffer configuration register [5212+]
+ * (buffer size)
+ */
+#define AR5K_QCU_CBCFG         0x0b08
+
+
+
+/*
+ * Distributed Coordination Function (DCF) control unit (DCU)
+ * registers [5211+]
+ *
+ * These registers control the various characteristics of each queue
+ * for 802.11e (WME) combatibility so they go together with
+ * QCU registers in pairs. For each queue we have a QCU mask register,
+ * (0x1000 - 0x102c), a local-IFS settings register (0x1040 - 0x106c),
+ * a retry limit register (0x1080 - 0x10ac), a channel time register
+ * (0x10c0 - 0x10ec), a misc-settings register (0x1100 - 0x112c) and
+ * a sequence number register (0x1140 - 0x116c). It seems that "global"
+ * registers here afect all queues (see use of DCU_GBL_IFS_SLOT in ar5k).
+ * We use the same macros here for easier register access.
+ *
+ */
+
+/*
+ * DCU QCU mask registers
+ */
+#define AR5K_DCU_QCUMASK_BASE  0x1000          /* Register Address -Queue0 DCU_QCUMASK */
+#define AR5K_DCU_QCUMASK_M     0x000003ff
+#define AR5K_QUEUE_QCUMASK(_q) AR5K_QUEUE_REG(AR5K_DCU_QCUMASK_BASE, _q)
+
+/*
+ * DCU local Inter Frame Space settings register
+ */
+#define AR5K_DCU_LCL_IFS_BASE          0x1040                  /* Register Address -Queue0 DCU_LCL_IFS */
+#define        AR5K_DCU_LCL_IFS_CW_MIN         0x000003ff      /* Minimum Contention Window */
+#define        AR5K_DCU_LCL_IFS_CW_MIN_S       0
+#define        AR5K_DCU_LCL_IFS_CW_MAX         0x000ffc00      /* Maximum Contention Window */
+#define        AR5K_DCU_LCL_IFS_CW_MAX_S       10
+#define        AR5K_DCU_LCL_IFS_AIFS           0x0ff00000      /* Arbitrated Interframe Space */
+#define        AR5K_DCU_LCL_IFS_AIFS_S         20
+#define        AR5K_DCU_LCL_IFS_AIFS_MAX       0xfc            /* Anything above that can cause DCU to hang */
+#define        AR5K_QUEUE_DFS_LOCAL_IFS(_q)    AR5K_QUEUE_REG(AR5K_DCU_LCL_IFS_BASE, _q)
+
+/*
+ * DCU retry limit registers
+ */
+#define AR5K_DCU_RETRY_LMT_BASE                0x1080                  /* Register Address -Queue0 DCU_RETRY_LMT */
+#define AR5K_DCU_RETRY_LMT_SH_RETRY    0x0000000f      /* Short retry limit mask */
+#define AR5K_DCU_RETRY_LMT_SH_RETRY_S  0
+#define AR5K_DCU_RETRY_LMT_LG_RETRY    0x000000f0      /* Long retry limit mask */
+#define AR5K_DCU_RETRY_LMT_LG_RETRY_S  4
+#define AR5K_DCU_RETRY_LMT_SSH_RETRY   0x00003f00      /* Station short retry limit mask (?) */
+#define AR5K_DCU_RETRY_LMT_SSH_RETRY_S 8
+#define AR5K_DCU_RETRY_LMT_SLG_RETRY   0x000fc000      /* Station long retry limit mask (?) */
+#define AR5K_DCU_RETRY_LMT_SLG_RETRY_S 14
+#define        AR5K_QUEUE_DFS_RETRY_LIMIT(_q)  AR5K_QUEUE_REG(AR5K_DCU_RETRY_LMT_BASE, _q)
+
+/*
+ * DCU channel time registers
+ */
+#define AR5K_DCU_CHAN_TIME_BASE                0x10c0                  /* Register Address -Queue0 DCU_CHAN_TIME */
+#define        AR5K_DCU_CHAN_TIME_DUR          0x000fffff      /* Channel time duration */
+#define        AR5K_DCU_CHAN_TIME_DUR_S        0
+#define        AR5K_DCU_CHAN_TIME_ENABLE       0x00100000      /* Enable channel time */
+#define AR5K_QUEUE_DFS_CHANNEL_TIME(_q)        AR5K_QUEUE_REG(AR5K_DCU_CHAN_TIME_BASE, _q)
+
+/*
+ * DCU misc registers [5211+]
+ *
+ * Note: Arbiter lockout control controls the
+ * behaviour on low priority queues when we have multiple queues
+ * with pending frames. Intra-frame lockout means we wait until
+ * the queue's current frame transmits (with post frame backoff and bursting)
+ * before we transmit anything else and global lockout means we
+ * wait for the whole queue to finish before higher priority queues
+ * can transmit (this is used on beacon and CAB queues).
+ * No lockout means there is no special handling.
+ */
+#define AR5K_DCU_MISC_BASE             0x1100                  /* Register Address -Queue0 DCU_MISC */
+#define        AR5K_DCU_MISC_BACKOFF           0x0000003f      /* Mask for backoff threshold */
+#define        AR5K_DCU_MISC_ETS_RTS_POL       0x00000040      /* End of transmission series
+                                                       station RTS/data failure count
+                                                       reset policy (?) */
+#define AR5K_DCU_MISC_ETS_CW_POL       0x00000080      /* End of transmission series
+                                                       CW reset policy */
+#define        AR5K_DCU_MISC_FRAG_WAIT         0x00000100      /* Wait for next fragment */
+#define AR5K_DCU_MISC_BACKOFF_FRAG     0x00000200      /* Enable backoff while bursting */
+#define        AR5K_DCU_MISC_HCFPOLL_ENABLE    0x00000800      /* CF - Poll enable */
+#define        AR5K_DCU_MISC_BACKOFF_PERSIST   0x00001000      /* Persistent backoff */
+#define        AR5K_DCU_MISC_FRMPRFTCH_ENABLE  0x00002000      /* Enable frame pre-fetch */
+#define        AR5K_DCU_MISC_VIRTCOL           0x0000c000      /* Mask for Virtual Collision (?) */
+#define        AR5K_DCU_MISC_VIRTCOL_NORMAL    0
+#define        AR5K_DCU_MISC_VIRTCOL_IGNORE    1
+#define        AR5K_DCU_MISC_BCN_ENABLE        0x00010000      /* Enable Beacon use */
+#define        AR5K_DCU_MISC_ARBLOCK_CTL       0x00060000      /* Arbiter lockout control mask */
+#define        AR5K_DCU_MISC_ARBLOCK_CTL_S     17
+#define        AR5K_DCU_MISC_ARBLOCK_CTL_NONE          0       /* No arbiter lockout */
+#define        AR5K_DCU_MISC_ARBLOCK_CTL_INTFRM        1       /* Intra-frame lockout */
+#define        AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL        2       /* Global lockout */
+#define        AR5K_DCU_MISC_ARBLOCK_IGNORE    0x00080000      /* Ignore Arbiter lockout */
+#define        AR5K_DCU_MISC_SEQ_NUM_INCR_DIS  0x00100000      /* Disable sequence number increment */
+#define        AR5K_DCU_MISC_POST_FR_BKOFF_DIS 0x00200000      /* Disable post-frame backoff */
+#define        AR5K_DCU_MISC_VIRT_COLL_POLICY  0x00400000      /* Virtual Collision cw policy */
+#define        AR5K_DCU_MISC_BLOWN_IFS_POLICY  0x00800000      /* Blown IFS policy (?) */
+#define        AR5K_DCU_MISC_SEQNUM_CTL        0x01000000      /* Sequence number control (?) */
+#define AR5K_QUEUE_DFS_MISC(_q)                AR5K_QUEUE_REG(AR5K_DCU_MISC_BASE, _q)
+
+/*
+ * DCU frame sequence number registers
+ */
+#define AR5K_DCU_SEQNUM_BASE           0x1140
+#define        AR5K_DCU_SEQNUM_M               0x00000fff
+#define        AR5K_QUEUE_DCU_SEQNUM(_q)       AR5K_QUEUE_REG(AR5K_DCU_SEQNUM_BASE, _q)
+
+/*
+ * DCU global IFS SIFS register
+ */
+#define AR5K_DCU_GBL_IFS_SIFS  0x1030
+#define AR5K_DCU_GBL_IFS_SIFS_M        0x0000ffff
+
+/*
+ * DCU global IFS slot interval register
+ */
+#define AR5K_DCU_GBL_IFS_SLOT  0x1070
+#define AR5K_DCU_GBL_IFS_SLOT_M        0x0000ffff
+
+/*
+ * DCU global IFS EIFS register
+ */
+#define AR5K_DCU_GBL_IFS_EIFS  0x10b0
+#define AR5K_DCU_GBL_IFS_EIFS_M        0x0000ffff
+
+/*
+ * DCU global IFS misc register
+ *
+ * LFSR stands for Linear Feedback Shift Register
+ * and it's used for generating pseudo-random
+ * number sequences.
+ *
+ * (If i understand corectly, random numbers are
+ * used for idle sensing -multiplied with cwmin/max etc-)
+ */
+#define AR5K_DCU_GBL_IFS_MISC                  0x10f0                  /* Register Address */
+#define        AR5K_DCU_GBL_IFS_MISC_LFSR_SLICE        0x00000007      /* LFSR Slice Select */
+#define        AR5K_DCU_GBL_IFS_MISC_TURBO_MODE        0x00000008      /* Turbo mode */
+#define        AR5K_DCU_GBL_IFS_MISC_SIFS_DUR_USEC     0x000003f0      /* SIFS Duration mask */
+#define        AR5K_DCU_GBL_IFS_MISC_USEC_DUR          0x000ffc00      /* USEC Duration mask */
+#define        AR5K_DCU_GBL_IFS_MISC_USEC_DUR_S        10
+#define        AR5K_DCU_GBL_IFS_MISC_DCU_ARB_DELAY     0x00300000      /* DCU Arbiter delay mask */
+#define AR5K_DCU_GBL_IFS_MISC_SIFS_CNT_RST     0x00400000      /* SIFS cnt reset policy (?) */
+#define AR5K_DCU_GBL_IFS_MISC_AIFS_CNT_RST     0x00800000      /* AIFS cnt reset policy (?) */
+#define AR5K_DCU_GBL_IFS_MISC_RND_LFSR_SL_DIS  0x01000000      /* Disable random LFSR slice */
+
+/*
+ * DCU frame prefetch control register
+ */
+#define AR5K_DCU_FP                    0x1230                  /* Register Address */
+#define AR5K_DCU_FP_NOBURST_DCU_EN     0x00000001      /* Enable non-burst prefetch on DCU (?) */
+#define AR5K_DCU_FP_NOBURST_EN         0x00000010      /* Enable non-burst prefetch (?) */
+#define AR5K_DCU_FP_BURST_DCU_EN       0x00000020      /* Enable burst prefetch on DCU (?) */
+
+/*
+ * DCU transmit pause control/status register
+ */
+#define AR5K_DCU_TXP           0x1270                  /* Register Address */
+#define        AR5K_DCU_TXP_M          0x000003ff      /* Tx pause mask */
+#define        AR5K_DCU_TXP_STATUS     0x00010000      /* Tx pause status */
+
+/*
+ * DCU transmit filter table 0 (32 entries)
+ * each entry contains a 32bit slice of the
+ * 128bit tx filter for each DCU (4 slices per DCU)
+ */
+#define AR5K_DCU_TX_FILTER_0_BASE      0x1038
+#define        AR5K_DCU_TX_FILTER_0(_n)        (AR5K_DCU_TX_FILTER_0_BASE + (_n * 64))
+
+/*
+ * DCU transmit filter table 1 (16 entries)
+ */
+#define AR5K_DCU_TX_FILTER_1_BASE      0x103c
+#define        AR5K_DCU_TX_FILTER_1(_n)        (AR5K_DCU_TX_FILTER_1_BASE + (_n * 64))
+
+/*
+ * DCU clear transmit filter register
+ */
+#define AR5K_DCU_TX_FILTER_CLR 0x143c
+
+/*
+ * DCU set transmit filter register
+ */
+#define AR5K_DCU_TX_FILTER_SET 0x147c
+
+/*
+ * Reset control register
+ */
+#define AR5K_RESET_CTL         0x4000                  /* Register Address */
+#define AR5K_RESET_CTL_PCU     0x00000001      /* Protocol Control Unit reset */
+#define AR5K_RESET_CTL_DMA     0x00000002      /* DMA (Rx/Tx) reset [5210] */
+#define        AR5K_RESET_CTL_BASEBAND 0x00000002      /* Baseband reset [5211+] */
+#define AR5K_RESET_CTL_MAC     0x00000004      /* MAC reset (PCU+Baseband ?) [5210] */
+#define AR5K_RESET_CTL_PHY     0x00000008      /* PHY reset [5210] */
+#define AR5K_RESET_CTL_PCI     0x00000010      /* PCI Core reset (interrupts etc) */
+
+/*
+ * Sleep control register
+ */
+#define AR5K_SLEEP_CTL                 0x4004                  /* Register Address */
+#define AR5K_SLEEP_CTL_SLDUR           0x0000ffff      /* Sleep duration mask */
+#define AR5K_SLEEP_CTL_SLDUR_S         0
+#define AR5K_SLEEP_CTL_SLE             0x00030000      /* Sleep enable mask */
+#define AR5K_SLEEP_CTL_SLE_S           16
+#define AR5K_SLEEP_CTL_SLE_WAKE                0x00000000      /* Force chip awake */
+#define AR5K_SLEEP_CTL_SLE_SLP         0x00010000      /* Force chip sleep */
+#define AR5K_SLEEP_CTL_SLE_ALLOW       0x00020000      /* Normal sleep policy */
+#define AR5K_SLEEP_CTL_SLE_UNITS       0x00000008      /* [5211+] */
+#define AR5K_SLEEP_CTL_DUR_TIM_POL     0x00040000      /* Sleep duration timing policy */
+#define AR5K_SLEEP_CTL_DUR_WRITE_POL   0x00080000      /* Sleep duration write policy */
+#define AR5K_SLEEP_CTL_SLE_POL         0x00100000      /* Sleep policy mode */
+
+/*
+ * Interrupt pending register
+ */
+#define AR5K_INTPEND   0x4008
+#define AR5K_INTPEND_M 0x00000001
+
+/*
+ * Sleep force register
+ */
+#define AR5K_SFR       0x400c
+#define AR5K_SFR_EN    0x00000001
+
+/*
+ * PCI configuration register
+ * TODO: Fix LED stuff
+ */
+#define AR5K_PCICFG                    0x4010                  /* Register Address */
+#define AR5K_PCICFG_EEAE               0x00000001      /* Eeprom access enable [5210] */
+#define AR5K_PCICFG_SLEEP_CLOCK_EN     0x00000002      /* Enable sleep clock */
+#define AR5K_PCICFG_CLKRUNEN           0x00000004      /* CLKRUN enable [5211+] */
+#define AR5K_PCICFG_EESIZE             0x00000018      /* Mask for EEPROM size [5211+] */
+#define AR5K_PCICFG_EESIZE_S           3
+#define AR5K_PCICFG_EESIZE_4K          0               /* 4K */
+#define AR5K_PCICFG_EESIZE_8K          1               /* 8K */
+#define AR5K_PCICFG_EESIZE_16K         2               /* 16K */
+#define AR5K_PCICFG_EESIZE_FAIL                3               /* Failed to get size [5211+] */
+#define AR5K_PCICFG_LED                        0x00000060      /* Led status [5211+] */
+#define AR5K_PCICFG_LED_NONE           0x00000000      /* Default [5211+] */
+#define AR5K_PCICFG_LED_PEND           0x00000020      /* Scan / Auth pending */
+#define AR5K_PCICFG_LED_ASSOC          0x00000040      /* Associated */
+#define        AR5K_PCICFG_BUS_SEL             0x00000380      /* Mask for "bus select" [5211+] (?) */
+#define AR5K_PCICFG_CBEFIX_DIS         0x00000400      /* Disable CBE fix */
+#define AR5K_PCICFG_SL_INTEN           0x00000800      /* Enable interrupts when asleep */
+#define AR5K_PCICFG_LED_BCTL           0x00001000      /* Led blink (?) [5210] */
+#define AR5K_PCICFG_RETRY_FIX          0x00001000      /* Enable pci core retry fix */
+#define AR5K_PCICFG_SL_INPEN           0x00002000      /* Sleep even whith pending interrupts*/
+#define AR5K_PCICFG_SPWR_DN            0x00010000      /* Mask for power status */
+#define AR5K_PCICFG_LEDMODE            0x000e0000      /* Ledmode [5211+] */
+#define AR5K_PCICFG_LEDMODE_PROP       0x00000000      /* Blink on standard traffic [5211+] */
+#define AR5K_PCICFG_LEDMODE_PROM       0x00020000      /* Default mode (blink on any traffic) [5211+] */
+#define AR5K_PCICFG_LEDMODE_PWR                0x00040000      /* Some other blinking mode  (?) [5211+] */
+#define AR5K_PCICFG_LEDMODE_RAND       0x00060000      /* Random blinking (?) [5211+] */
+#define AR5K_PCICFG_LEDBLINK           0x00700000      /* Led blink rate */
+#define AR5K_PCICFG_LEDBLINK_S         20
+#define AR5K_PCICFG_LEDSLOW            0x00800000      /* Slowest led blink rate [5211+] */
+#define AR5K_PCICFG_LEDSTATE                           \
+       (AR5K_PCICFG_LED | AR5K_PCICFG_LEDMODE |        \
+       AR5K_PCICFG_LEDBLINK | AR5K_PCICFG_LEDSLOW)
+#define        AR5K_PCICFG_SLEEP_CLOCK_RATE    0x03000000      /* Sleep clock rate */
+#define        AR5K_PCICFG_SLEEP_CLOCK_RATE_S  24
+
+/*
+ * "General Purpose Input/Output" (GPIO) control register
+ *
+ * I'm not sure about this but after looking at the code
+ * for all chipsets here is what i got.
+ *
+ * We have 6 GPIOs (pins), each GPIO has 4 modes (2 bits)
+ * Mode 0 -> always input
+ * Mode 1 -> output when GPIODO for this GPIO is set to 0
+ * Mode 2 -> output when GPIODO for this GPIO is set to 1
+ * Mode 3 -> always output
+ *
+ * For more infos check out get_gpio/set_gpio and
+ * set_gpio_input/set_gpio_output functs.
+ * For more infos on gpio interrupt check out set_gpio_intr.
+ */
+#define AR5K_NUM_GPIO  6
+
+#define AR5K_GPIOCR            0x4014                          /* Register Address */
+#define AR5K_GPIOCR_INT_ENA    0x00008000              /* Enable GPIO interrupt */
+#define AR5K_GPIOCR_INT_SELL   0x00000000              /* Generate interrupt when pin is low */
+#define AR5K_GPIOCR_INT_SELH   0x00010000              /* Generate interrupt when pin is high */
+#define AR5K_GPIOCR_IN(n)      (0 << ((n) * 2))        /* Mode 0 for pin n */
+#define AR5K_GPIOCR_OUT0(n)    (1 << ((n) * 2))        /* Mode 1 for pin n */
+#define AR5K_GPIOCR_OUT1(n)    (2 << ((n) * 2))        /* Mode 2 for pin n */
+#define AR5K_GPIOCR_OUT(n)     (3 << ((n) * 2))        /* Mode 3 for pin n */
+#define AR5K_GPIOCR_INT_SEL(n) ((n) << 12)             /* Interrupt for GPIO pin n */
+
+/*
+ * "General Purpose Input/Output" (GPIO) data output register
+ */
+#define AR5K_GPIODO    0x4018
+
+/*
+ * "General Purpose Input/Output" (GPIO) data input register
+ */
+#define AR5K_GPIODI    0x401c
+#define AR5K_GPIODI_M  0x0000002f
+
+/*
+ * Silicon revision register
+ */
+#define AR5K_SREV              0x4020                  /* Register Address */
+#define AR5K_SREV_REV          0x0000000f      /* Mask for revision */
+#define AR5K_SREV_REV_S                0
+#define AR5K_SREV_VER          0x000000ff      /* Mask for version */
+#define AR5K_SREV_VER_S                4
+
+/*
+ * TXE write posting register
+ */
+#define        AR5K_TXEPOST    0x4028
+
+/*
+ * QCU sleep mask
+ */
+#define        AR5K_QCU_SLEEP_MASK     0x402c
+
+/* 0x4068 is compression buffer configuration
+ * register on 5414 and pm configuration register
+ * on 5424 and newer pci-e chips. */
+
+/*
+ * Compression buffer configuration
+ * register (enable/disable) [5414]
+ */
+#define AR5K_5414_CBCFG                0x4068
+#define AR5K_5414_CBCFG_BUF_DIS        0x10    /* Disable buffer */
+
+/*
+ * PCI-E Power managment configuration
+ * and status register [5424+]
+ */
+#define        AR5K_PCIE_PM_CTL                0x4068                  /* Register address */
+/* Only 5424 */
+#define        AR5K_PCIE_PM_CTL_L1_WHEN_D2     0x00000001      /* enable PCIe core enter L1
+                                                       when d2_sleep_en is asserted */
+#define        AR5K_PCIE_PM_CTL_L0_L0S_CLEAR   0x00000002      /* Clear L0 and L0S counters */
+#define        AR5K_PCIE_PM_CTL_L0_L0S_EN      0x00000004      /* Start L0 nd L0S counters */
+#define        AR5K_PCIE_PM_CTL_LDRESET_EN     0x00000008      /* Enable reset when link goes
+                                                       down */
+/* Wake On Wireless */
+#define        AR5K_PCIE_PM_CTL_PME_EN         0x00000010      /* PME Enable */
+#define        AR5K_PCIE_PM_CTL_AUX_PWR_DET    0x00000020      /* Aux power detect */
+#define        AR5K_PCIE_PM_CTL_PME_CLEAR      0x00000040      /* Clear PME */
+#define        AR5K_PCIE_PM_CTL_PSM_D0         0x00000080
+#define        AR5K_PCIE_PM_CTL_PSM_D1         0x00000100
+#define        AR5K_PCIE_PM_CTL_PSM_D2         0x00000200
+#define        AR5K_PCIE_PM_CTL_PSM_D3         0x00000400
+
+/*
+ * PCI-E Workaround enable register
+ */
+#define        AR5K_PCIE_WAEN  0x407c
+
+/*
+ * PCI-E Serializer/Desirializer
+ * registers
+ */
+#define        AR5K_PCIE_SERDES        0x4080
+#define        AR5K_PCIE_SERDES_RESET  0x4084
+
+/*====EEPROM REGISTERS====*/
+
+/*
+ * EEPROM access registers
+ *
+ * Here we got a difference between 5210/5211-12
+ * read data register for 5210 is at 0x6800 and
+ * status register is at 0x6c00. There is also
+ * no eeprom command register on 5210 and the
+ * offsets are different.
+ *
+ * To read eeprom data for a specific offset:
+ * 5210 - enable eeprom access (AR5K_PCICFG_EEAE)
+ *        read AR5K_EEPROM_BASE +(4 * offset)
+ *        check the eeprom status register
+ *        and read eeprom data register.
+ *
+ * 5211 - write offset to AR5K_EEPROM_BASE
+ * 5212   write AR5K_EEPROM_CMD_READ on AR5K_EEPROM_CMD
+ *        check the eeprom status register
+ *        and read eeprom data register.
+ *
+ * To write eeprom data for a specific offset:
+ * 5210 - enable eeprom access (AR5K_PCICFG_EEAE)
+ *        write data to AR5K_EEPROM_BASE +(4 * offset)
+ *        check the eeprom status register
+ * 5211 - write AR5K_EEPROM_CMD_RESET on AR5K_EEPROM_CMD
+ * 5212   write offset to AR5K_EEPROM_BASE
+ *        write data to data register
+ *       write AR5K_EEPROM_CMD_WRITE on AR5K_EEPROM_CMD
+ *        check the eeprom status register
+ *
+ * For more infos check eeprom_* functs and the ar5k.c
+ * file posted in madwifi-devel mailing list.
+ * http://sourceforge.net/mailarchive/message.php?msg_id=8966525
+ *
+ */
+#define AR5K_EEPROM_BASE       0x6000
+
+/*
+ * EEPROM data register
+ */
+#define AR5K_EEPROM_DATA_5211  0x6004
+#define AR5K_EEPROM_DATA_5210  0x6800
+#define        AR5K_EEPROM_DATA        (ah->ah_version == AR5K_AR5210 ? \
+                               AR5K_EEPROM_DATA_5210 : AR5K_EEPROM_DATA_5211)
+
+/*
+ * EEPROM command register
+ */
+#define AR5K_EEPROM_CMD                0x6008                  /* Register Addres */
+#define AR5K_EEPROM_CMD_READ   0x00000001      /* EEPROM read */
+#define AR5K_EEPROM_CMD_WRITE  0x00000002      /* EEPROM write */
+#define AR5K_EEPROM_CMD_RESET  0x00000004      /* EEPROM reset */
+
+/*
+ * EEPROM status register
+ */
+#define AR5K_EEPROM_STAT_5210  0x6c00                  /* Register Address [5210] */
+#define AR5K_EEPROM_STAT_5211  0x600c                  /* Register Address [5211+] */
+#define        AR5K_EEPROM_STATUS      (ah->ah_version == AR5K_AR5210 ? \
+                               AR5K_EEPROM_STAT_5210 : AR5K_EEPROM_STAT_5211)
+#define AR5K_EEPROM_STAT_RDERR 0x00000001      /* EEPROM read failed */
+#define AR5K_EEPROM_STAT_RDDONE        0x00000002      /* EEPROM read successful */
+#define AR5K_EEPROM_STAT_WRERR 0x00000004      /* EEPROM write failed */
+#define AR5K_EEPROM_STAT_WRDONE        0x00000008      /* EEPROM write successful */
+
+/*
+ * EEPROM config register
+ */
+#define AR5K_EEPROM_CFG                        0x6010                  /* Register Addres */
+#define AR5K_EEPROM_CFG_SIZE           0x00000003              /* Size determination override */
+#define AR5K_EEPROM_CFG_SIZE_AUTO      0
+#define AR5K_EEPROM_CFG_SIZE_4KBIT     1
+#define AR5K_EEPROM_CFG_SIZE_8KBIT     2
+#define AR5K_EEPROM_CFG_SIZE_16KBIT    3
+#define AR5K_EEPROM_CFG_WR_WAIT_DIS    0x00000004      /* Disable write wait */
+#define AR5K_EEPROM_CFG_CLK_RATE       0x00000018      /* Clock rate */
+#define AR5K_EEPROM_CFG_CLK_RATE_S             3
+#define AR5K_EEPROM_CFG_CLK_RATE_156KHZ        0
+#define AR5K_EEPROM_CFG_CLK_RATE_312KHZ        1
+#define AR5K_EEPROM_CFG_CLK_RATE_625KHZ        2
+#define AR5K_EEPROM_CFG_PROT_KEY       0x00ffff00      /* Protection key */
+#define AR5K_EEPROM_CFG_PROT_KEY_S     8
+#define AR5K_EEPROM_CFG_LIND_EN                0x01000000      /* Enable length indicator (?) */
+
+
+/*
+ * TODO: Wake On Wireless registers
+ * Range 0x7000 - 0x7ce0
+ */
+
+/*
+ * Protocol Control Unit (PCU) registers
+ */
+/*
+ * Used for checking initial register writes
+ * during channel reset (see reset func)
+ */
+#define AR5K_PCU_MIN   0x8000
+#define AR5K_PCU_MAX   0x8fff
+
+/*
+ * First station id register (Lower 32 bits of MAC address)
+ */
+#define AR5K_STA_ID0           0x8000
+#define        AR5K_STA_ID0_ARRD_L32   0xffffffff
+
+/*
+ * Second station id register (Upper 16 bits of MAC address + PCU settings)
+ */
+#define AR5K_STA_ID1                   0x8004                  /* Register Address */
+#define        AR5K_STA_ID1_ADDR_U16           0x0000ffff      /* Upper 16 bits of MAC addres */
+#define AR5K_STA_ID1_AP                        0x00010000      /* Set AP mode */
+#define AR5K_STA_ID1_ADHOC             0x00020000      /* Set Ad-Hoc mode */
+#define AR5K_STA_ID1_PWR_SV            0x00040000      /* Power save reporting */
+#define AR5K_STA_ID1_NO_KEYSRCH                0x00080000      /* No key search */
+#define AR5K_STA_ID1_NO_PSPOLL         0x00100000      /* No power save polling [5210] */
+#define AR5K_STA_ID1_PCF_5211          0x00100000      /* Enable PCF on [5211+] */
+#define AR5K_STA_ID1_PCF_5210          0x00200000      /* Enable PCF on [5210]*/
+#define        AR5K_STA_ID1_PCF                (ah->ah_version == AR5K_AR5210 ? \
+                                       AR5K_STA_ID1_PCF_5210 : AR5K_STA_ID1_PCF_5211)
+#define AR5K_STA_ID1_DEFAULT_ANTENNA   0x00200000      /* Use default antenna */
+#define AR5K_STA_ID1_DESC_ANTENNA      0x00400000      /* Update antenna from descriptor */
+#define AR5K_STA_ID1_RTS_DEF_ANTENNA   0x00800000      /* Use default antenna for RTS */
+#define AR5K_STA_ID1_ACKCTS_6MB                0x01000000      /* Use 6Mbit/s for ACK/CTS */
+#define AR5K_STA_ID1_BASE_RATE_11B     0x02000000      /* Use 11b base rate for ACK/CTS [5211+] */
+#define AR5K_STA_ID1_SELFGEN_DEF_ANT   0x04000000      /* Use def. antenna for self generated frames */
+#define AR5K_STA_ID1_CRYPT_MIC_EN      0x08000000      /* Enable MIC */
+#define AR5K_STA_ID1_KEYSRCH_MODE      0x10000000      /* Look up key when key id != 0 */
+#define AR5K_STA_ID1_PRESERVE_SEQ_NUM  0x20000000      /* Preserve sequence number */
+#define AR5K_STA_ID1_CBCIV_ENDIAN      0x40000000      /* ??? */
+#define AR5K_STA_ID1_KEYSRCH_MCAST     0x80000000      /* Do key cache search for mcast frames */
+
+#define        AR5K_STA_ID1_ANTENNA_SETTINGS   (AR5K_STA_ID1_DEFAULT_ANTENNA | \
+                                       AR5K_STA_ID1_DESC_ANTENNA | \
+                                       AR5K_STA_ID1_RTS_DEF_ANTENNA | \
+                                       AR5K_STA_ID1_SELFGEN_DEF_ANT)
+
+/*
+ * First BSSID register (MAC address, lower 32bits)
+ */
+#define AR5K_BSS_ID0   0x8008
+
+/*
+ * Second BSSID register (MAC address in upper 16 bits)
+ *
+ * AID: Association ID
+ */
+#define AR5K_BSS_ID1           0x800c
+#define AR5K_BSS_ID1_AID       0xffff0000
+#define AR5K_BSS_ID1_AID_S     16
+
+/*
+ * Backoff slot time register
+ */
+#define AR5K_SLOT_TIME 0x8010
+
+/*
+ * ACK/CTS timeout register
+ */
+#define AR5K_TIME_OUT          0x8014                  /* Register Address */
+#define AR5K_TIME_OUT_ACK      0x00001fff      /* ACK timeout mask */
+#define AR5K_TIME_OUT_ACK_S    0
+#define AR5K_TIME_OUT_CTS      0x1fff0000      /* CTS timeout mask */
+#define AR5K_TIME_OUT_CTS_S    16
+
+/*
+ * RSSI threshold register
+ */
+#define AR5K_RSSI_THR                  0x8018          /* Register Address */
+#define AR5K_RSSI_THR_M                        0x000000ff      /* Mask for RSSI threshold [5211+] */
+#define AR5K_RSSI_THR_BMISS_5210       0x00000700      /* Mask for Beacon Missed threshold [5210] */
+#define AR5K_RSSI_THR_BMISS_5210_S     8
+#define AR5K_RSSI_THR_BMISS_5211       0x0000ff00      /* Mask for Beacon Missed threshold [5211+] */
+#define AR5K_RSSI_THR_BMISS_5211_S     8
+#define        AR5K_RSSI_THR_BMISS             (ah->ah_version == AR5K_AR5210 ? \
+                                       AR5K_RSSI_THR_BMISS_5210 : AR5K_RSSI_THR_BMISS_5211)
+#define        AR5K_RSSI_THR_BMISS_S           8
+
+/*
+ * 5210 has more PCU registers because there is no QCU/DCU
+ * so queue parameters are set here, this way a lot common
+ * registers have different address for 5210. To make things
+ * easier we define a macro based on ah->ah_version for common
+ * registers with different addresses and common flags.
+ */
+
+/*
+ * Retry limit register
+ *
+ * Retry limit register for 5210 (no QCU/DCU so it's done in PCU)
+ */
+#define AR5K_NODCU_RETRY_LMT           0x801c                  /* Register Address */
+#define AR5K_NODCU_RETRY_LMT_SH_RETRY  0x0000000f      /* Short retry limit mask */
+#define AR5K_NODCU_RETRY_LMT_SH_RETRY_S        0
+#define AR5K_NODCU_RETRY_LMT_LG_RETRY  0x000000f0      /* Long retry mask */
+#define AR5K_NODCU_RETRY_LMT_LG_RETRY_S        4
+#define AR5K_NODCU_RETRY_LMT_SSH_RETRY 0x00003f00      /* Station short retry limit mask */
+#define AR5K_NODCU_RETRY_LMT_SSH_RETRY_S       8
+#define AR5K_NODCU_RETRY_LMT_SLG_RETRY 0x000fc000      /* Station long retry limit mask */
+#define AR5K_NODCU_RETRY_LMT_SLG_RETRY_S       14
+#define AR5K_NODCU_RETRY_LMT_CW_MIN    0x3ff00000      /* Minimum contention window mask */
+#define AR5K_NODCU_RETRY_LMT_CW_MIN_S  20
+
+/*
+ * Transmit latency register
+ */
+#define AR5K_USEC_5210                 0x8020                  /* Register Address [5210] */
+#define AR5K_USEC_5211                 0x801c                  /* Register Address [5211+] */
+#define AR5K_USEC                      (ah->ah_version == AR5K_AR5210 ? \
+                                       AR5K_USEC_5210 : AR5K_USEC_5211)
+#define AR5K_USEC_1                    0x0000007f      /* clock cycles for 1us */
+#define AR5K_USEC_1_S                  0
+#define AR5K_USEC_32                   0x00003f80      /* clock cycles for 1us while on 32Mhz clock */
+#define AR5K_USEC_32_S                 7
+#define AR5K_USEC_TX_LATENCY_5211      0x007fc000
+#define AR5K_USEC_TX_LATENCY_5211_S    14
+#define AR5K_USEC_RX_LATENCY_5211      0x1f800000
+#define AR5K_USEC_RX_LATENCY_5211_S    23
+#define AR5K_USEC_TX_LATENCY_5210      0x000fc000      /* also for 5311 */
+#define AR5K_USEC_TX_LATENCY_5210_S    14
+#define AR5K_USEC_RX_LATENCY_5210      0x03f00000      /* also for 5311 */
+#define AR5K_USEC_RX_LATENCY_5210_S    20
+
+/*
+ * PCU beacon control register
+ */
+#define AR5K_BEACON_5210       0x8024                  /*Register Address [5210] */
+#define AR5K_BEACON_5211       0x8020                  /*Register Address [5211+] */
+#define AR5K_BEACON            (ah->ah_version == AR5K_AR5210 ? \
+                               AR5K_BEACON_5210 : AR5K_BEACON_5211)
+#define AR5K_BEACON_PERIOD     0x0000ffff      /* Mask for beacon period */
+#define AR5K_BEACON_PERIOD_S   0
+#define AR5K_BEACON_TIM                0x007f0000      /* Mask for TIM offset */
+#define AR5K_BEACON_TIM_S      16
+#define AR5K_BEACON_ENABLE     0x00800000      /* Enable beacons */
+#define AR5K_BEACON_RESET_TSF  0x01000000      /* Force TSF reset */
+
+/*
+ * CFP period register
+ */
+#define AR5K_CFP_PERIOD_5210   0x8028
+#define AR5K_CFP_PERIOD_5211   0x8024
+#define AR5K_CFP_PERIOD                (ah->ah_version == AR5K_AR5210 ? \
+                               AR5K_CFP_PERIOD_5210 : AR5K_CFP_PERIOD_5211)
+
+/*
+ * Next beacon time register
+ */
+#define AR5K_TIMER0_5210       0x802c
+#define AR5K_TIMER0_5211       0x8028
+#define AR5K_TIMER0            (ah->ah_version == AR5K_AR5210 ? \
+                               AR5K_TIMER0_5210 : AR5K_TIMER0_5211)
+
+/*
+ * Next DMA beacon alert register
+ */
+#define AR5K_TIMER1_5210       0x8030
+#define AR5K_TIMER1_5211       0x802c
+#define AR5K_TIMER1            (ah->ah_version == AR5K_AR5210 ? \
+                               AR5K_TIMER1_5210 : AR5K_TIMER1_5211)
+
+/*
+ * Next software beacon alert register
+ */
+#define AR5K_TIMER2_5210       0x8034
+#define AR5K_TIMER2_5211       0x8030
+#define AR5K_TIMER2            (ah->ah_version == AR5K_AR5210 ? \
+                               AR5K_TIMER2_5210 : AR5K_TIMER2_5211)
+
+/*
+ * Next ATIM window time register
+ */
+#define AR5K_TIMER3_5210       0x8038
+#define AR5K_TIMER3_5211       0x8034
+#define AR5K_TIMER3            (ah->ah_version == AR5K_AR5210 ? \
+                               AR5K_TIMER3_5210 : AR5K_TIMER3_5211)
+
+
+/*
+ * 5210 First inter frame spacing register (IFS)
+ */
+#define AR5K_IFS0              0x8040
+#define AR5K_IFS0_SIFS         0x000007ff
+#define AR5K_IFS0_SIFS_S       0
+#define AR5K_IFS0_DIFS         0x007ff800
+#define AR5K_IFS0_DIFS_S       11
+
+/*
+ * 5210 Second inter frame spacing register (IFS)
+ */
+#define AR5K_IFS1              0x8044
+#define AR5K_IFS1_PIFS         0x00000fff
+#define AR5K_IFS1_PIFS_S       0
+#define AR5K_IFS1_EIFS         0x03fff000
+#define AR5K_IFS1_EIFS_S       12
+#define AR5K_IFS1_CS_EN                0x04000000
+
+
+/*
+ * CFP duration register
+ */
+#define AR5K_CFP_DUR_5210      0x8048
+#define AR5K_CFP_DUR_5211      0x8038
+#define AR5K_CFP_DUR           (ah->ah_version == AR5K_AR5210 ? \
+                               AR5K_CFP_DUR_5210 : AR5K_CFP_DUR_5211)
+
+/*
+ * Receive filter register
+ */
+#define AR5K_RX_FILTER_5210    0x804c                  /* Register Address [5210] */
+#define AR5K_RX_FILTER_5211    0x803c                  /* Register Address [5211+] */
+#define AR5K_RX_FILTER         (ah->ah_version == AR5K_AR5210 ? \
+                               AR5K_RX_FILTER_5210 : AR5K_RX_FILTER_5211)
+#define        AR5K_RX_FILTER_UCAST    0x00000001      /* Don't filter unicast frames */
+#define        AR5K_RX_FILTER_MCAST    0x00000002      /* Don't filter multicast frames */
+#define        AR5K_RX_FILTER_BCAST    0x00000004      /* Don't filter broadcast frames */
+#define        AR5K_RX_FILTER_CONTROL  0x00000008      /* Don't filter control frames */
+#define        AR5K_RX_FILTER_BEACON   0x00000010      /* Don't filter beacon frames */
+#define        AR5K_RX_FILTER_PROM     0x00000020      /* Set promiscuous mode */
+#define        AR5K_RX_FILTER_XRPOLL   0x00000040      /* Don't filter XR poll frame [5212+] */
+#define        AR5K_RX_FILTER_PROBEREQ 0x00000080      /* Don't filter probe requests [5212+] */
+#define        AR5K_RX_FILTER_PHYERR_5212      0x00000100      /* Don't filter phy errors [5212+] */
+#define        AR5K_RX_FILTER_RADARERR_5212    0x00000200      /* Don't filter phy radar errors [5212+] */
+#define AR5K_RX_FILTER_PHYERR_5211     0x00000040      /* [5211] */
+#define AR5K_RX_FILTER_RADARERR_5211   0x00000080      /* [5211] */
+#define AR5K_RX_FILTER_PHYERR  \
+       ((ah->ah_version == AR5K_AR5211 ? \
+       AR5K_RX_FILTER_PHYERR_5211 : AR5K_RX_FILTER_PHYERR_5212))
+#define        AR5K_RX_FILTER_RADARERR \
+       ((ah->ah_version == AR5K_AR5211 ? \
+       AR5K_RX_FILTER_RADARERR_5211 : AR5K_RX_FILTER_RADARERR_5212))
+
+/*
+ * Multicast filter register (lower 32 bits)
+ */
+#define AR5K_MCAST_FILTER0_5210        0x8050
+#define AR5K_MCAST_FILTER0_5211        0x8040
+#define AR5K_MCAST_FILTER0     (ah->ah_version == AR5K_AR5210 ? \
+                               AR5K_MCAST_FILTER0_5210 : AR5K_MCAST_FILTER0_5211)
+
+/*
+ * Multicast filter register (higher 16 bits)
+ */
+#define AR5K_MCAST_FILTER1_5210        0x8054
+#define AR5K_MCAST_FILTER1_5211        0x8044
+#define AR5K_MCAST_FILTER1     (ah->ah_version == AR5K_AR5210 ? \
+                               AR5K_MCAST_FILTER1_5210 : AR5K_MCAST_FILTER1_5211)
+
+
+/*
+ * Transmit mask register (lower 32 bits) [5210]
+ */
+#define AR5K_TX_MASK0  0x8058
+
+/*
+ * Transmit mask register (higher 16 bits) [5210]
+ */
+#define AR5K_TX_MASK1  0x805c
+
+/*
+ * Clear transmit mask [5210]
+ */
+#define AR5K_CLR_TMASK 0x8060
+
+/*
+ * Trigger level register (before transmission) [5210]
+ */
+#define AR5K_TRIG_LVL  0x8064
+
+
+/*
+ * PCU control register
+ *
+ * Only DIS_RX is used in the code, the rest i guess are
+ * for tweaking/diagnostics.
+ */
+#define AR5K_DIAG_SW_5210              0x8068                  /* Register Address [5210] */
+#define AR5K_DIAG_SW_5211              0x8048                  /* Register Address [5211+] */
+#define AR5K_DIAG_SW                   (ah->ah_version == AR5K_AR5210 ? \
+                                       AR5K_DIAG_SW_5210 : AR5K_DIAG_SW_5211)
+#define AR5K_DIAG_SW_DIS_WEP_ACK       0x00000001      /* Disable ACKs if WEP key is invalid */
+#define AR5K_DIAG_SW_DIS_ACK           0x00000002      /* Disable ACKs */
+#define AR5K_DIAG_SW_DIS_CTS           0x00000004      /* Disable CTSs */
+#define AR5K_DIAG_SW_DIS_ENC           0x00000008      /* Disable encryption */
+#define AR5K_DIAG_SW_DIS_DEC           0x00000010      /* Disable decryption */
+#define AR5K_DIAG_SW_DIS_TX            0x00000020      /* Disable transmit [5210] */
+#define AR5K_DIAG_SW_DIS_RX_5210       0x00000040      /* Disable recieve */
+#define AR5K_DIAG_SW_DIS_RX_5211       0x00000020
+#define        AR5K_DIAG_SW_DIS_RX             (ah->ah_version == AR5K_AR5210 ? \
+                                       AR5K_DIAG_SW_DIS_RX_5210 : AR5K_DIAG_SW_DIS_RX_5211)
+#define AR5K_DIAG_SW_LOOP_BACK_5210    0x00000080      /* Loopback (i guess it goes with DIS_TX) [5210] */
+#define AR5K_DIAG_SW_LOOP_BACK_5211    0x00000040
+#define AR5K_DIAG_SW_LOOP_BACK         (ah->ah_version == AR5K_AR5210 ? \
+                                       AR5K_DIAG_SW_LOOP_BACK_5210 : AR5K_DIAG_SW_LOOP_BACK_5211)
+#define AR5K_DIAG_SW_CORR_FCS_5210     0x00000100      /* Corrupted FCS */
+#define AR5K_DIAG_SW_CORR_FCS_5211     0x00000080
+#define AR5K_DIAG_SW_CORR_FCS          (ah->ah_version == AR5K_AR5210 ? \
+                                       AR5K_DIAG_SW_CORR_FCS_5210 : AR5K_DIAG_SW_CORR_FCS_5211)
+#define AR5K_DIAG_SW_CHAN_INFO_5210    0x00000200      /* Dump channel info */
+#define AR5K_DIAG_SW_CHAN_INFO_5211    0x00000100
+#define AR5K_DIAG_SW_CHAN_INFO         (ah->ah_version == AR5K_AR5210 ? \
+                                       AR5K_DIAG_SW_CHAN_INFO_5210 : AR5K_DIAG_SW_CHAN_INFO_5211)
+#define AR5K_DIAG_SW_EN_SCRAM_SEED_5210        0x00000400      /* Enable fixed scrambler seed */
+#define AR5K_DIAG_SW_EN_SCRAM_SEED_5211        0x00000200
+#define AR5K_DIAG_SW_EN_SCRAM_SEED     (ah->ah_version == AR5K_AR5210 ? \
+                                       AR5K_DIAG_SW_EN_SCRAM_SEED_5210 : AR5K_DIAG_SW_EN_SCRAM_SEED_5211)
+#define AR5K_DIAG_SW_ECO_ENABLE                0x00000400      /* [5211+] */
+#define AR5K_DIAG_SW_SCVRAM_SEED       0x0003f800      /* [5210] */
+#define AR5K_DIAG_SW_SCRAM_SEED_M      0x0001fc00      /* Scrambler seed mask */
+#define AR5K_DIAG_SW_SCRAM_SEED_S      10
+#define AR5K_DIAG_SW_DIS_SEQ_INC       0x00040000      /* Disable seqnum increment (?)[5210] */
+#define AR5K_DIAG_SW_FRAME_NV0_5210    0x00080000
+#define AR5K_DIAG_SW_FRAME_NV0_5211    0x00020000      /* Accept frames of non-zero protocol number */
+#define        AR5K_DIAG_SW_FRAME_NV0          (ah->ah_version == AR5K_AR5210 ? \
+                                       AR5K_DIAG_SW_FRAME_NV0_5210 : AR5K_DIAG_SW_FRAME_NV0_5211)
+#define AR5K_DIAG_SW_OBSPT_M           0x000c0000      /* Observation point select (?) */
+#define AR5K_DIAG_SW_OBSPT_S           18
+#define AR5K_DIAG_SW_RX_CLEAR_HIGH     0x0010000       /* Force RX Clear high */
+#define AR5K_DIAG_SW_IGNORE_CARR_SENSE 0x0020000       /* Ignore virtual carrier sense */
+#define AR5K_DIAG_SW_CHANEL_IDLE_HIGH  0x0040000       /* Force channel idle high */
+#define AR5K_DIAG_SW_PHEAR_ME          0x0080000       /* ??? */
+
+/*
+ * TSF (clock) register (lower 32 bits)
+ */
+#define AR5K_TSF_L32_5210      0x806c
+#define AR5K_TSF_L32_5211      0x804c
+#define        AR5K_TSF_L32            (ah->ah_version == AR5K_AR5210 ? \
+                               AR5K_TSF_L32_5210 : AR5K_TSF_L32_5211)
+
+/*
+ * TSF (clock) register (higher 32 bits)
+ */
+#define AR5K_TSF_U32_5210      0x8070
+#define AR5K_TSF_U32_5211      0x8050
+#define        AR5K_TSF_U32            (ah->ah_version == AR5K_AR5210 ? \
+                               AR5K_TSF_U32_5210 : AR5K_TSF_U32_5211)
+
+/*
+ * Last beacon timestamp register (Read Only)
+ */
+#define AR5K_LAST_TSTP 0x8080
+
+/*
+ * ADDAC test register [5211+]
+ */
+#define AR5K_ADDAC_TEST                        0x8054                  /* Register Address */
+#define AR5K_ADDAC_TEST_TXCONT                 0x00000001      /* Test continuous tx */
+#define AR5K_ADDAC_TEST_TST_MODE       0x00000002      /* Test mode */
+#define AR5K_ADDAC_TEST_LOOP_EN                0x00000004      /* Enable loop */
+#define AR5K_ADDAC_TEST_LOOP_LEN       0x00000008      /* Loop length (field) */
+#define AR5K_ADDAC_TEST_USE_U8         0x00004000      /* Use upper 8 bits */
+#define AR5K_ADDAC_TEST_MSB            0x00008000      /* State of MSB */
+#define AR5K_ADDAC_TEST_TRIG_SEL       0x00010000      /* Trigger select */
+#define AR5K_ADDAC_TEST_TRIG_PTY       0x00020000      /* Trigger polarity */
+#define AR5K_ADDAC_TEST_RXCONT         0x00040000      /* Continuous capture */
+#define AR5K_ADDAC_TEST_CAPTURE                0x00080000      /* Begin capture */
+#define AR5K_ADDAC_TEST_TST_ARM                0x00100000      /* ARM rx buffer for capture */
+
+/*
+ * Default antenna register [5211+]
+ */
+#define AR5K_DEFAULT_ANTENNA   0x8058
+
+/*
+ * Frame control QoS mask register (?) [5211+]
+ * (FC_QOS_MASK)
+ */
+#define AR5K_FRAME_CTL_QOSM    0x805c
+
+/*
+ * Seq mask register (?) [5211+]
+ */
+#define AR5K_SEQ_MASK  0x8060
+
+/*
+ * Retry count register [5210]
+ */
+#define AR5K_RETRY_CNT         0x8084                  /* Register Address [5210] */
+#define AR5K_RETRY_CNT_SSH     0x0000003f      /* Station short retry count (?) */
+#define AR5K_RETRY_CNT_SLG     0x00000fc0      /* Station long retry count (?) */
+
+/*
+ * Back-off status register [5210]
+ */
+#define AR5K_BACKOFF           0x8088                  /* Register Address [5210] */
+#define AR5K_BACKOFF_CW                0x000003ff      /* Backoff Contention Window (?) */
+#define AR5K_BACKOFF_CNT       0x03ff0000      /* Backoff count (?) */
+
+
+
+/*
+ * NAV register (current)
+ */
+#define AR5K_NAV_5210          0x808c
+#define AR5K_NAV_5211          0x8084
+#define        AR5K_NAV                (ah->ah_version == AR5K_AR5210 ? \
+                               AR5K_NAV_5210 : AR5K_NAV_5211)
+
+/*
+ * RTS success register
+ */
+#define AR5K_RTS_OK_5210       0x8090
+#define AR5K_RTS_OK_5211       0x8088
+#define        AR5K_RTS_OK             (ah->ah_version == AR5K_AR5210 ? \
+                               AR5K_RTS_OK_5210 : AR5K_RTS_OK_5211)
+
+/*
+ * RTS failure register
+ */
+#define AR5K_RTS_FAIL_5210     0x8094
+#define AR5K_RTS_FAIL_5211     0x808c
+#define        AR5K_RTS_FAIL           (ah->ah_version == AR5K_AR5210 ? \
+                               AR5K_RTS_FAIL_5210 : AR5K_RTS_FAIL_5211)
+
+/*
+ * ACK failure register
+ */
+#define AR5K_ACK_FAIL_5210     0x8098
+#define AR5K_ACK_FAIL_5211     0x8090
+#define        AR5K_ACK_FAIL           (ah->ah_version == AR5K_AR5210 ? \
+                               AR5K_ACK_FAIL_5210 : AR5K_ACK_FAIL_5211)
+
+/*
+ * FCS failure register
+ */
+#define AR5K_FCS_FAIL_5210     0x809c
+#define AR5K_FCS_FAIL_5211     0x8094
+#define        AR5K_FCS_FAIL           (ah->ah_version == AR5K_AR5210 ? \
+                               AR5K_FCS_FAIL_5210 : AR5K_FCS_FAIL_5211)
+
+/*
+ * Beacon count register
+ */
+#define AR5K_BEACON_CNT_5210   0x80a0
+#define AR5K_BEACON_CNT_5211   0x8098
+#define        AR5K_BEACON_CNT         (ah->ah_version == AR5K_AR5210 ? \
+                               AR5K_BEACON_CNT_5210 : AR5K_BEACON_CNT_5211)
+
+
+/*===5212 Specific PCU registers===*/
+
+/*
+ * Transmit power control register
+ */
+#define AR5K_TPC                       0x80e8
+#define AR5K_TPC_ACK                   0x0000003f      /* ack frames */
+#define AR5K_TPC_ACK_S                 0
+#define AR5K_TPC_CTS                   0x00003f00      /* cts frames */
+#define AR5K_TPC_CTS_S                 8
+#define AR5K_TPC_CHIRP                 0x003f0000      /* chirp frames */
+#define AR5K_TPC_CHIRP_S               16
+#define AR5K_TPC_DOPPLER               0x0f000000      /* doppler chirp span */
+#define AR5K_TPC_DOPPLER_S             24
+
+/*
+ * XR (eXtended Range) mode register
+ */
+#define AR5K_XRMODE                    0x80c0                  /* Register Address */
+#define        AR5K_XRMODE_POLL_TYPE_M         0x0000003f      /* Mask for Poll type (?) */
+#define        AR5K_XRMODE_POLL_TYPE_S         0
+#define        AR5K_XRMODE_POLL_SUBTYPE_M      0x0000003c      /* Mask for Poll subtype (?) */
+#define        AR5K_XRMODE_POLL_SUBTYPE_S      2
+#define        AR5K_XRMODE_POLL_WAIT_ALL       0x00000080      /* Wait for poll */
+#define        AR5K_XRMODE_SIFS_DELAY          0x000fff00      /* Mask for SIFS delay */
+#define        AR5K_XRMODE_FRAME_HOLD_M        0xfff00000      /* Mask for frame hold (?) */
+#define        AR5K_XRMODE_FRAME_HOLD_S        20
+
+/*
+ * XR delay register
+ */
+#define AR5K_XRDELAY                   0x80c4                  /* Register Address */
+#define AR5K_XRDELAY_SLOT_DELAY_M      0x0000ffff      /* Mask for slot delay */
+#define AR5K_XRDELAY_SLOT_DELAY_S      0
+#define AR5K_XRDELAY_CHIRP_DELAY_M     0xffff0000      /* Mask for CHIRP data delay */
+#define AR5K_XRDELAY_CHIRP_DELAY_S     16
+
+/*
+ * XR timeout register
+ */
+#define AR5K_XRTIMEOUT                 0x80c8                  /* Register Address */
+#define AR5K_XRTIMEOUT_CHIRP_M         0x0000ffff      /* Mask for CHIRP timeout */
+#define AR5K_XRTIMEOUT_CHIRP_S         0
+#define AR5K_XRTIMEOUT_POLL_M          0xffff0000      /* Mask for Poll timeout */
+#define AR5K_XRTIMEOUT_POLL_S          16
+
+/*
+ * XR chirp register
+ */
+#define AR5K_XRCHIRP                   0x80cc                  /* Register Address */
+#define AR5K_XRCHIRP_SEND              0x00000001      /* Send CHIRP */
+#define AR5K_XRCHIRP_GAP               0xffff0000      /* Mask for CHIRP gap (?) */
+
+/*
+ * XR stomp register
+ */
+#define AR5K_XRSTOMP                   0x80d0                  /* Register Address */
+#define AR5K_XRSTOMP_TX                        0x00000001      /* Stomp Tx (?) */
+#define AR5K_XRSTOMP_RX                        0x00000002      /* Stomp Rx (?) */
+#define AR5K_XRSTOMP_TX_RSSI           0x00000004      /* Stomp Tx RSSI (?) */
+#define AR5K_XRSTOMP_TX_BSSID          0x00000008      /* Stomp Tx BSSID (?) */
+#define AR5K_XRSTOMP_DATA              0x00000010      /* Stomp data (?)*/
+#define AR5K_XRSTOMP_RSSI_THRES                0x0000ff00      /* Mask for XR RSSI threshold */
+
+/*
+ * First enhanced sleep register
+ */
+#define AR5K_SLEEP0                    0x80d4                  /* Register Address */
+#define AR5K_SLEEP0_NEXT_DTIM          0x0007ffff      /* Mask for next DTIM (?) */
+#define AR5K_SLEEP0_NEXT_DTIM_S                0
+#define AR5K_SLEEP0_ASSUME_DTIM                0x00080000      /* Assume DTIM */
+#define AR5K_SLEEP0_ENH_SLEEP_EN       0x00100000      /* Enable enchanced sleep control */
+#define AR5K_SLEEP0_CABTO              0xff000000      /* Mask for CAB Time Out */
+#define AR5K_SLEEP0_CABTO_S            24
+
+/*
+ * Second enhanced sleep register
+ */
+#define AR5K_SLEEP1                    0x80d8                  /* Register Address */
+#define AR5K_SLEEP1_NEXT_TIM           0x0007ffff      /* Mask for next TIM (?) */
+#define AR5K_SLEEP1_NEXT_TIM_S         0
+#define AR5K_SLEEP1_BEACON_TO          0xff000000      /* Mask for Beacon Time Out */
+#define AR5K_SLEEP1_BEACON_TO_S                24
+
+/*
+ * Third enhanced sleep register
+ */
+#define AR5K_SLEEP2                    0x80dc                  /* Register Address */
+#define AR5K_SLEEP2_TIM_PER            0x0000ffff      /* Mask for TIM period (?) */
+#define AR5K_SLEEP2_TIM_PER_S          0
+#define AR5K_SLEEP2_DTIM_PER           0xffff0000      /* Mask for DTIM period (?) */
+#define AR5K_SLEEP2_DTIM_PER_S         16
+
+/*
+ * BSSID mask registers
+ */
+#define AR5K_BSS_IDM0                  0x80e0  /* Upper bits */
+#define AR5K_BSS_IDM1                  0x80e4  /* Lower bits */
+
+/*
+ * TX power control (TPC) register
+ *
+ * XXX: PCDAC steps (0.5dbm) or DBM ?
+ *
+ */
+#define AR5K_TXPC                      0x80e8                  /* Register Address */
+#define AR5K_TXPC_ACK_M                        0x0000003f      /* ACK tx power */
+#define AR5K_TXPC_ACK_S                        0
+#define AR5K_TXPC_CTS_M                        0x00003f00      /* CTS tx power */
+#define AR5K_TXPC_CTS_S                        8
+#define AR5K_TXPC_CHIRP_M              0x003f0000      /* CHIRP tx power */
+#define AR5K_TXPC_CHIRP_S              16
+#define AR5K_TXPC_DOPPLER              0x0f000000      /* Doppler chirp span (?) */
+#define AR5K_TXPC_DOPPLER_S            24
+
+/*
+ * Profile count registers
+ */
+#define AR5K_PROFCNT_TX                        0x80ec  /* Tx count */
+#define AR5K_PROFCNT_RX                        0x80f0  /* Rx count */
+#define AR5K_PROFCNT_RXCLR             0x80f4  /* Clear Rx count */
+#define AR5K_PROFCNT_CYCLE             0x80f8  /* Cycle count (?) */
+
+/*
+ * Quiet period control registers
+ */
+#define AR5K_QUIET_CTL1                        0x80fc                  /* Register Address */
+#define AR5K_QUIET_CTL1_NEXT_QT_TSF    0x0000ffff      /* Next quiet period TSF (TU) */
+#define AR5K_QUIET_CTL1_NEXT_QT_TSF_S  0
+#define AR5K_QUIET_CTL1_QT_EN          0x00010000      /* Enable quiet period */
+#define AR5K_QUIET_CTL1_ACK_CTS_EN     0x00020000      /* Send ACK/CTS during quiet period */
+
+#define AR5K_QUIET_CTL2                        0x8100                  /* Register Address */
+#define AR5K_QUIET_CTL2_QT_PER         0x0000ffff      /* Mask for quiet period periodicity */
+#define AR5K_QUIET_CTL2_QT_PER_S       0
+#define AR5K_QUIET_CTL2_QT_DUR         0xffff0000      /* Mask for quiet period duration */
+#define AR5K_QUIET_CTL2_QT_DUR_S       16
+
+/*
+ * TSF parameter register
+ */
+#define AR5K_TSF_PARM                  0x8104                  /* Register Address */
+#define AR5K_TSF_PARM_INC              0x000000ff      /* Mask for TSF increment */
+#define AR5K_TSF_PARM_INC_S            0
+
+/*
+ * QoS NOACK policy
+ */
+#define AR5K_QOS_NOACK                 0x8108                  /* Register Address */
+#define AR5K_QOS_NOACK_2BIT_VALUES     0x0000000f      /* ??? */
+#define AR5K_QOS_NOACK_2BIT_VALUES_S   0
+#define AR5K_QOS_NOACK_BIT_OFFSET      0x00000070      /* ??? */
+#define AR5K_QOS_NOACK_BIT_OFFSET_S    4
+#define AR5K_QOS_NOACK_BYTE_OFFSET     0x00000180      /* ??? */
+#define AR5K_QOS_NOACK_BYTE_OFFSET_S   7
+
+/*
+ * PHY error filter register
+ */
+#define AR5K_PHY_ERR_FIL               0x810c
+#define AR5K_PHY_ERR_FIL_RADAR         0x00000020      /* Radar signal */
+#define AR5K_PHY_ERR_FIL_OFDM          0x00020000      /* OFDM false detect (ANI) */
+#define AR5K_PHY_ERR_FIL_CCK           0x02000000      /* CCK false detect (ANI) */
+
+/*
+ * XR latency register
+ */
+#define AR5K_XRLAT_TX          0x8110
+
+/*
+ * ACK SIFS register
+ */
+#define AR5K_ACKSIFS           0x8114                  /* Register Address */
+#define AR5K_ACKSIFS_INC       0x00000000      /* ACK SIFS Increment (field) */
+
+/*
+ * MIC QoS control register (?)
+ */
+#define        AR5K_MIC_QOS_CTL                0x8118                  /* Register Address */
+#define        AR5K_MIC_QOS_CTL_OFF(_n)        (1 << (_n * 2))
+#define        AR5K_MIC_QOS_CTL_MQ_EN          0x00010000      /* Enable MIC QoS */
+
+/*
+ * MIC QoS select register (?)
+ */
+#define        AR5K_MIC_QOS_SEL                0x811c
+#define        AR5K_MIC_QOS_SEL_OFF(_n)        (1 << (_n * 4))
+
+/*
+ * Misc mode control register (?)
+ */
+#define        AR5K_MISC_MODE                  0x8120                  /* Register Address */
+#define        AR5K_MISC_MODE_FBSSID_MATCH     0x00000001      /* Force BSSID match */
+#define        AR5K_MISC_MODE_ACKSIFS_MEM      0x00000002      /* ACK SIFS memory (?) */
+#define        AR5K_MISC_MODE_COMBINED_MIC     0x00000004      /* use rx/tx MIC key */
+/* more bits */
+
+/*
+ * OFDM Filter counter
+ */
+#define        AR5K_OFDM_FIL_CNT               0x8124
+
+/*
+ * CCK Filter counter
+ */
+#define        AR5K_CCK_FIL_CNT                0x8128
+
+/*
+ * PHY Error Counters (?)
+ */
+#define        AR5K_PHYERR_CNT1                0x812c
+#define        AR5K_PHYERR_CNT1_MASK           0x8130
+
+#define        AR5K_PHYERR_CNT2                0x8134
+#define        AR5K_PHYERR_CNT2_MASK           0x8138
+
+/*
+ * TSF Threshold register (?)
+ */
+#define        AR5K_TSF_THRES                  0x813c
+
+/*
+ * TODO: Wake On Wireless registers
+ * Range: 0x8147 - 0x818c
+ */
+
+/*
+ * Rate -> ACK SIFS mapping table (32 entries)
+ */
+#define        AR5K_RATE_ACKSIFS_BASE          0x8680                  /* Register Address */
+#define        AR5K_RATE_ACKSIFS(_n)           (AR5K_RATE_ACKSIFS_BSE + ((_n) << 2))
+#define        AR5K_RATE_ACKSIFS_NORMAL        0x00000001      /* Normal SIFS (field) */
+#define        AR5K_RATE_ACKSIFS_TURBO         0x00000400      /* Turbo SIFS (field) */
+
+/*
+ * Rate -> duration mapping table (32 entries)
+ */
+#define AR5K_RATE_DUR_BASE             0x8700
+#define AR5K_RATE_DUR(_n)              (AR5K_RATE_DUR_BASE + ((_n) << 2))
+
+/*
+ * Rate -> db mapping table
+ * (8 entries, each one has 4 8bit fields)
+ */
+#define AR5K_RATE2DB_BASE              0x87c0
+#define AR5K_RATE2DB(_n)               (AR5K_RATE2DB_BASE + ((_n) << 2))
+
+/*
+ * db -> Rate mapping table
+ * (8 entries, each one has 4 8bit fields)
+ */
+#define AR5K_DB2RATE_BASE              0x87e0
+#define AR5K_DB2RATE(_n)               (AR5K_DB2RATE_BASE + ((_n) << 2))
+
+/*===5212 end===*/
+
+/*
+ * Key table (WEP) register
+ */
+#define AR5K_KEYTABLE_0_5210           0x9000
+#define AR5K_KEYTABLE_0_5211           0x8800
+#define AR5K_KEYTABLE_5210(_n)         (AR5K_KEYTABLE_0_5210 + ((_n) << 5))
+#define AR5K_KEYTABLE_5211(_n)         (AR5K_KEYTABLE_0_5211 + ((_n) << 5))
+#define        AR5K_KEYTABLE(_n)               (ah->ah_version == AR5K_AR5210 ? \
+                                       AR5K_KEYTABLE_5210(_n) : AR5K_KEYTABLE_5211(_n))
+#define AR5K_KEYTABLE_OFF(_n, x)       (AR5K_KEYTABLE(_n) + (x << 2))
+#define AR5K_KEYTABLE_TYPE(_n)         AR5K_KEYTABLE_OFF(_n, 5)
+#define AR5K_KEYTABLE_TYPE_40          0x00000000
+#define AR5K_KEYTABLE_TYPE_104         0x00000001
+#define AR5K_KEYTABLE_TYPE_128         0x00000003
+#define AR5K_KEYTABLE_TYPE_TKIP                0x00000004      /* [5212+] */
+#define AR5K_KEYTABLE_TYPE_AES         0x00000005      /* [5211+] */
+#define AR5K_KEYTABLE_TYPE_CCM         0x00000006      /* [5212+] */
+#define AR5K_KEYTABLE_TYPE_NULL                0x00000007      /* [5211+] */
+#define AR5K_KEYTABLE_ANTENNA          0x00000008      /* [5212+] */
+#define AR5K_KEYTABLE_MAC0(_n)         AR5K_KEYTABLE_OFF(_n, 6)
+#define AR5K_KEYTABLE_MAC1(_n)         AR5K_KEYTABLE_OFF(_n, 7)
+#define AR5K_KEYTABLE_VALID            0x00008000
+
+/* If key type is TKIP and MIC is enabled
+ * MIC key goes in offset entry + 64 */
+#define        AR5K_KEYTABLE_MIC_OFFSET        64
+
+/* WEP 40-bit  = 40-bit  entered key + 24 bit IV = 64-bit
+ * WEP 104-bit = 104-bit entered key + 24-bit IV = 128-bit
+ * WEP 128-bit = 128-bit entered key + 24 bit IV = 152-bit
+ *
+ * Some vendors have introduced bigger WEP keys to address
+ * security vulnerabilities in WEP. This includes:
+ *
+ * WEP 232-bit = 232-bit entered key + 24 bit IV = 256-bit
+ *
+ * We can expand this if we find ar5k Atheros cards with a larger
+ * key table size.
+ */
+#define AR5K_KEYTABLE_SIZE_5210                64
+#define AR5K_KEYTABLE_SIZE_5211                128
+#define        AR5K_KEYTABLE_SIZE              (ah->ah_version == AR5K_AR5210 ? \
+                                       AR5K_KEYTABLE_SIZE_5210 : AR5K_KEYTABLE_SIZE_5211)
+
+
+/*===PHY REGISTERS===*/
+
+/*
+ * PHY registers start
+ */
+#define        AR5K_PHY_BASE                   0x9800
+#define        AR5K_PHY(_n)                    (AR5K_PHY_BASE + ((_n) << 2))
+
+/*
+ * TST_2 (Misc config parameters)
+ */
+#define        AR5K_PHY_TST2                   0x9800                  /* Register Address */
+#define AR5K_PHY_TST2_TRIG_SEL         0x00000007      /* Trigger select (?)*/
+#define AR5K_PHY_TST2_TRIG             0x00000010      /* Trigger (?) */
+#define AR5K_PHY_TST2_CBUS_MODE                0x00000060      /* Cardbus mode (?) */
+#define AR5K_PHY_TST2_CLK32            0x00000400      /* CLK_OUT is CLK32 (32Khz external) */
+#define AR5K_PHY_TST2_CHANCOR_DUMP_EN  0x00000800      /* Enable Chancor dump (?) */
+#define AR5K_PHY_TST2_EVEN_CHANCOR_DUMP        0x00001000      /* Even Chancor dump (?) */
+#define AR5K_PHY_TST2_RFSILENT_EN      0x00002000      /* Enable RFSILENT */
+#define AR5K_PHY_TST2_ALT_RFDATA       0x00004000      /* Alternate RFDATA (5-2GHz switch ?) */
+#define AR5K_PHY_TST2_MINI_OBS_EN      0x00008000      /* Enable mini OBS (?) */
+#define AR5K_PHY_TST2_RX2_IS_RX5_INV   0x00010000      /* 2GHz rx path is the 5GHz path inverted (?) */
+#define AR5K_PHY_TST2_SLOW_CLK160      0x00020000      /* Slow CLK160 (?) */
+#define AR5K_PHY_TST2_AGC_OBS_SEL_3    0x00040000      /* AGC OBS Select 3 (?) */
+#define AR5K_PHY_TST2_BBB_OBS_SEL      0x00080000      /* BB OBS Select (field ?) */
+#define AR5K_PHY_TST2_ADC_OBS_SEL      0x00800000      /* ADC OBS Select (field ?) */
+#define AR5K_PHY_TST2_RX_CLR_SEL       0x08000000      /* RX Clear Select (?) */
+#define AR5K_PHY_TST2_FORCE_AGC_CLR    0x10000000      /* Force AGC clear (?) */
+#define AR5K_PHY_SHIFT_2GHZ            0x00004007      /* Used to access 2GHz radios */
+#define AR5K_PHY_SHIFT_5GHZ            0x00000007      /* Used to access 5GHz radios (default) */
+
+/*
+ * PHY frame control register [5110] /turbo mode register [5111+]
+ *
+ * There is another frame control register for [5111+]
+ * at address 0x9944 (see below) but the 2 first flags
+ * are common here between 5110 frame control register
+ * and [5111+] turbo mode register, so this also works as
+ * a "turbo mode register" for 5110. We treat this one as
+ * a frame control register for 5110 below.
+ */
+#define        AR5K_PHY_TURBO                  0x9804                  /* Register Address */
+#define        AR5K_PHY_TURBO_MODE             0x00000001      /* Enable turbo mode */
+#define        AR5K_PHY_TURBO_SHORT            0x00000002      /* Set short symbols to turbo mode */
+#define        AR5K_PHY_TURBO_MIMO             0x00000004      /* Set turbo for mimo mimo */
+
+/*
+ * PHY agility command register
+ * (aka TST_1)
+ */
+#define        AR5K_PHY_AGC                    0x9808                  /* Register Address */
+#define        AR5K_PHY_TST1                   0x9808
+#define        AR5K_PHY_AGC_DISABLE            0x08000000      /* Disable AGC to A2 (?)*/
+#define        AR5K_PHY_TST1_TXHOLD            0x00003800      /* Set tx hold (?) */
+#define        AR5K_PHY_TST1_TXSRC_SRC         0x00000002      /* Used with bit 7 (?) */
+#define        AR5K_PHY_TST1_TXSRC_SRC_S       1
+#define        AR5K_PHY_TST1_TXSRC_ALT         0x00000080      /* Set input to tsdac (?) */
+#define        AR5K_PHY_TST1_TXSRC_ALT_S       7
+
+
+/*
+ * PHY timing register 3 [5112+]
+ */
+#define        AR5K_PHY_TIMING_3               0x9814
+#define        AR5K_PHY_TIMING_3_DSC_MAN       0xfffe0000
+#define        AR5K_PHY_TIMING_3_DSC_MAN_S     17
+#define        AR5K_PHY_TIMING_3_DSC_EXP       0x0001e000
+#define        AR5K_PHY_TIMING_3_DSC_EXP_S     13
+
+/*
+ * PHY chip revision register
+ */
+#define        AR5K_PHY_CHIP_ID                0x9818
+
+/*
+ * PHY activation register
+ */
+#define        AR5K_PHY_ACT                    0x981c                  /* Register Address */
+#define        AR5K_PHY_ACT_ENABLE             0x00000001      /* Activate PHY */
+#define        AR5K_PHY_ACT_DISABLE            0x00000002      /* Deactivate PHY */
+
+/*
+ * PHY RF control registers
+ */
+#define AR5K_PHY_RF_CTL2               0x9824                  /* Register Address */
+#define        AR5K_PHY_RF_CTL2_TXF2TXD_START  0x0000000f      /* TX frame to TX data start */
+#define        AR5K_PHY_RF_CTL2_TXF2TXD_START_S        0
+
+#define AR5K_PHY_RF_CTL3               0x9828                  /* Register Address */
+#define AR5K_PHY_RF_CTL3_TXE2XLNA_ON   0x0000ff00      /* TX end to XLNA on */
+#define        AR5K_PHY_RF_CTL3_TXE2XLNA_ON_S  8
+
+#define        AR5K_PHY_ADC_CTL                        0x982c
+#define        AR5K_PHY_ADC_CTL_INBUFGAIN_OFF          0x00000003
+#define        AR5K_PHY_ADC_CTL_INBUFGAIN_OFF_S        0
+#define        AR5K_PHY_ADC_CTL_PWD_DAC_OFF            0x00002000
+#define        AR5K_PHY_ADC_CTL_PWD_BAND_GAP_OFF       0x00004000
+#define        AR5K_PHY_ADC_CTL_PWD_ADC_OFF            0x00008000
+#define        AR5K_PHY_ADC_CTL_INBUFGAIN_ON           0x00030000
+#define        AR5K_PHY_ADC_CTL_INBUFGAIN_ON_S         16
+
+#define AR5K_PHY_RF_CTL4               0x9834                  /* Register Address */
+#define AR5K_PHY_RF_CTL4_TXF2XPA_A_ON  0x00000001      /* TX frame to XPA A on (field) */
+#define AR5K_PHY_RF_CTL4_TXF2XPA_B_ON  0x00000100      /* TX frame to XPA B on (field) */
+#define        AR5K_PHY_RF_CTL4_TXE2XPA_A_OFF  0x00010000      /* TX end to XPA A off (field) */
+#define AR5K_PHY_RF_CTL4_TXE2XPA_B_OFF 0x01000000      /* TX end to XPA B off (field) */
+
+/*
+ * Pre-Amplifier control register
+ * (XPA -> external pre-amplifier)
+ */
+#define        AR5K_PHY_PA_CTL                 0x9838                  /* Register Address */
+#define        AR5K_PHY_PA_CTL_XPA_A_HI        0x00000001      /* XPA A high (?) */
+#define        AR5K_PHY_PA_CTL_XPA_B_HI        0x00000002      /* XPA B high (?) */
+#define        AR5K_PHY_PA_CTL_XPA_A_EN        0x00000004      /* Enable XPA A */
+#define        AR5K_PHY_PA_CTL_XPA_B_EN        0x00000008      /* Enable XPA B */
+
+/*
+ * PHY settling register
+ */
+#define AR5K_PHY_SETTLING              0x9844                  /* Register Address */
+#define        AR5K_PHY_SETTLING_AGC           0x0000007f      /* AGC settling time */
+#define        AR5K_PHY_SETTLING_AGC_S         0
+#define        AR5K_PHY_SETTLING_SWITCH        0x00003f80      /* Switch settlig time */
+#define        AR5K_PHY_SETTLING_SWITCH_S      7
+
+/*
+ * PHY Gain registers
+ */
+#define AR5K_PHY_GAIN                  0x9848                  /* Register Address */
+#define        AR5K_PHY_GAIN_TXRX_ATTEN        0x0003f000      /* TX-RX Attenuation */
+#define        AR5K_PHY_GAIN_TXRX_ATTEN_S      12
+#define        AR5K_PHY_GAIN_TXRX_RF_MAX       0x007c0000
+#define        AR5K_PHY_GAIN_TXRX_RF_MAX_S     18
+
+#define        AR5K_PHY_GAIN_OFFSET            0x984c                  /* Register Address */
+#define        AR5K_PHY_GAIN_OFFSET_RXTX_FLAG  0x00020000      /* RX-TX flag (?) */
+
+/*
+ * Desired ADC/PGA size register
+ * (for more infos read ANI patent)
+ */
+#define AR5K_PHY_DESIRED_SIZE          0x9850                  /* Register Address */
+#define        AR5K_PHY_DESIRED_SIZE_ADC       0x000000ff      /* ADC desired size */
+#define        AR5K_PHY_DESIRED_SIZE_ADC_S     0
+#define        AR5K_PHY_DESIRED_SIZE_PGA       0x0000ff00      /* PGA desired size */
+#define        AR5K_PHY_DESIRED_SIZE_PGA_S     8
+#define        AR5K_PHY_DESIRED_SIZE_TOT       0x0ff00000      /* Total desired size */
+#define        AR5K_PHY_DESIRED_SIZE_TOT_S     20
+
+/*
+ * PHY signal register
+ * (for more infos read ANI patent)
+ */
+#define        AR5K_PHY_SIG                    0x9858                  /* Register Address */
+#define        AR5K_PHY_SIG_FIRSTEP            0x0003f000      /* FIRSTEP */
+#define        AR5K_PHY_SIG_FIRSTEP_S          12
+#define        AR5K_PHY_SIG_FIRPWR             0x03fc0000      /* FIPWR */
+#define        AR5K_PHY_SIG_FIRPWR_S           18
+
+/*
+ * PHY coarse agility control register
+ * (for more infos read ANI patent)
+ */
+#define        AR5K_PHY_AGCCOARSE              0x985c                  /* Register Address */
+#define        AR5K_PHY_AGCCOARSE_LO           0x00007f80      /* AGC Coarse low */
+#define        AR5K_PHY_AGCCOARSE_LO_S         7
+#define        AR5K_PHY_AGCCOARSE_HI           0x003f8000      /* AGC Coarse high */
+#define        AR5K_PHY_AGCCOARSE_HI_S         15
+
+/*
+ * PHY agility control register
+ */
+#define        AR5K_PHY_AGCCTL                 0x9860                  /* Register address */
+#define        AR5K_PHY_AGCCTL_CAL             0x00000001      /* Enable PHY calibration */
+#define        AR5K_PHY_AGCCTL_NF              0x00000002      /* Enable Noise Floor calibration */
+#define        AR5K_PHY_AGCCTL_OFDM_DIV_DIS    0x00000008      /* Disable antenna diversity on OFDM modes */
+#define        AR5K_PHY_AGCCTL_NF_EN           0x00008000      /* Enable nf calibration to happen (?) */
+#define        AR5K_PHY_AGCTL_FLTR_CAL         0x00010000      /* Allow filter calibration (?) */
+#define        AR5K_PHY_AGCCTL_NF_NOUPDATE     0x00020000      /* Don't update nf automaticaly */
+
+/*
+ * PHY noise floor status register
+ */
+#define AR5K_PHY_NF                    0x9864                  /* Register address */
+#define AR5K_PHY_NF_M                  0x000001ff      /* Noise floor mask */
+#define AR5K_PHY_NF_ACTIVE             0x00000100      /* Noise floor calibration still active */
+#define AR5K_PHY_NF_RVAL(_n)           (((_n) >> 19) & AR5K_PHY_NF_M)
+#define AR5K_PHY_NF_AVAL(_n)           (-((_n) ^ AR5K_PHY_NF_M) + 1)
+#define AR5K_PHY_NF_SVAL(_n)           (((_n) & AR5K_PHY_NF_M) | (1 << 9))
+#define        AR5K_PHY_NF_THRESH62            0x0007f000      /* Thresh62 -check ANI patent- (field) */
+#define        AR5K_PHY_NF_THRESH62_S          12
+#define        AR5K_PHY_NF_MINCCA_PWR          0x0ff80000      /* ??? */
+#define        AR5K_PHY_NF_MINCCA_PWR_S        19
+
+/*
+ * PHY ADC saturation register [5110]
+ */
+#define        AR5K_PHY_ADCSAT                 0x9868
+#define        AR5K_PHY_ADCSAT_ICNT            0x0001f800
+#define        AR5K_PHY_ADCSAT_ICNT_S          11
+#define        AR5K_PHY_ADCSAT_THR             0x000007e0
+#define        AR5K_PHY_ADCSAT_THR_S           5
+
+/*
+ * PHY Weak ofdm signal detection threshold registers (ANI) [5212+]
+ */
+
+/* High thresholds */
+#define AR5K_PHY_WEAK_OFDM_HIGH_THR            0x9868
+#define AR5K_PHY_WEAK_OFDM_HIGH_THR_M2_COUNT   0x0000001f
+#define AR5K_PHY_WEAK_OFDM_HIGH_THR_M2_COUNT_S 0
+#define AR5K_PHY_WEAK_OFDM_HIGH_THR_M1         0x00fe0000
+#define AR5K_PHY_WEAK_OFDM_HIGH_THR_M1_S       17
+#define AR5K_PHY_WEAK_OFDM_HIGH_THR_M2         0x7f000000
+#define AR5K_PHY_WEAK_OFDM_HIGH_THR_M2_S       24
+
+/* Low thresholds */
+#define AR5K_PHY_WEAK_OFDM_LOW_THR             0x986c
+#define AR5K_PHY_WEAK_OFDM_LOW_THR_SELFCOR_EN  0x00000001
+#define AR5K_PHY_WEAK_OFDM_LOW_THR_M2_COUNT    0x00003f00
+#define AR5K_PHY_WEAK_OFDM_LOW_THR_M2_COUNT_S  8
+#define AR5K_PHY_WEAK_OFDM_LOW_THR_M1          0x001fc000
+#define AR5K_PHY_WEAK_OFDM_LOW_THR_M1_S                14
+#define AR5K_PHY_WEAK_OFDM_LOW_THR_M2          0x0fe00000
+#define AR5K_PHY_WEAK_OFDM_LOW_THR_M2_S                21
+
+
+/*
+ * PHY sleep registers [5112+]
+ */
+#define AR5K_PHY_SCR                   0x9870
+
+#define AR5K_PHY_SLMT                  0x9874
+#define AR5K_PHY_SLMT_32MHZ            0x0000007f
+
+#define AR5K_PHY_SCAL                  0x9878
+#define AR5K_PHY_SCAL_32MHZ            0x0000000e
+#define        AR5K_PHY_SCAL_32MHZ_2417        0x0000000a
+#define        AR5K_PHY_SCAL_32MHZ_HB63        0x00000032
+
+/*
+ * PHY PLL (Phase Locked Loop) control register
+ */
+#define        AR5K_PHY_PLL                    0x987c
+#define        AR5K_PHY_PLL_20MHZ              0x00000013      /* For half rate (?) */
+/* 40MHz -> 5GHz band */
+#define        AR5K_PHY_PLL_40MHZ_5211         0x00000018
+#define        AR5K_PHY_PLL_40MHZ_5212         0x000000aa
+#define        AR5K_PHY_PLL_40MHZ_5413         0x00000004
+#define        AR5K_PHY_PLL_40MHZ              (ah->ah_version == AR5K_AR5211 ? \
+                                       AR5K_PHY_PLL_40MHZ_5211 : AR5K_PHY_PLL_40MHZ_5212)
+/* 44MHz -> 2.4GHz band */
+#define        AR5K_PHY_PLL_44MHZ_5211         0x00000019
+#define        AR5K_PHY_PLL_44MHZ_5212         0x000000ab
+#define        AR5K_PHY_PLL_44MHZ              (ah->ah_version == AR5K_AR5211 ? \
+                                       AR5K_PHY_PLL_44MHZ_5211 : AR5K_PHY_PLL_44MHZ_5212)
+
+#define AR5K_PHY_PLL_RF5111            0x00000000
+#define AR5K_PHY_PLL_RF5112            0x00000040
+#define        AR5K_PHY_PLL_HALF_RATE          0x00000100
+#define        AR5K_PHY_PLL_QUARTER_RATE       0x00000200
+
+/*
+ * RF Buffer register
+ *
+ * It's obvious from the code that 0x989c is the buffer register but
+ * for the other special registers that we write to after sending each
+ * packet, i have no idea. So i'll name them BUFFER_CONTROL_X registers
+ * for now. It's interesting that they are also used for some other operations.
+ */
+
+#define AR5K_RF_BUFFER                 0x989c
+#define AR5K_RF_BUFFER_CONTROL_0       0x98c0  /* Channel on 5110 */
+#define AR5K_RF_BUFFER_CONTROL_1       0x98c4  /* Bank 7 on 5112 */
+#define AR5K_RF_BUFFER_CONTROL_2       0x98cc  /* Bank 7 on 5111 */
+
+#define AR5K_RF_BUFFER_CONTROL_3       0x98d0  /* Bank 2 on 5112 */
+                                               /* Channel set on 5111 */
+                                               /* Used to read radio revision*/
+
+#define AR5K_RF_BUFFER_CONTROL_4       0x98d4  /* RF Stage register on 5110 */
+                                               /* Bank 0,1,2,6 on 5111 */
+                                               /* Bank 1 on 5112 */
+                                               /* Used during activation on 5111 */
+
+#define AR5K_RF_BUFFER_CONTROL_5       0x98d8  /* Bank 3 on 5111 */
+                                               /* Used during activation on 5111 */
+                                               /* Channel on 5112 */
+                                               /* Bank 6 on 5112 */
+
+#define AR5K_RF_BUFFER_CONTROL_6       0x98dc  /* Bank 3 on 5112 */
+
+/*
+ * PHY RF stage register [5210]
+ */
+#define AR5K_PHY_RFSTG                 0x98d4
+#define AR5K_PHY_RFSTG_DISABLE         0x00000021
+
+/*
+ * BIN masks (?)
+ */
+#define        AR5K_PHY_BIN_MASK_1     0x9900
+#define        AR5K_PHY_BIN_MASK_2     0x9904
+#define        AR5K_PHY_BIN_MASK_3     0x9908
+
+#define        AR5K_PHY_BIN_MASK_CTL           0x990c
+#define        AR5K_PHY_BIN_MASK_CTL_MASK_4    0x00003fff
+#define        AR5K_PHY_BIN_MASK_CTL_MASK_4_S  0
+#define        AR5K_PHY_BIN_MASK_CTL_RATE      0xff000000
+#define        AR5K_PHY_BIN_MASK_CTL_RATE_S    24
+
+/*
+ * PHY Antenna control register
+ */
+#define AR5K_PHY_ANT_CTL               0x9910                  /* Register Address */
+#define        AR5K_PHY_ANT_CTL_TXRX_EN        0x00000001      /* Enable TX/RX (?) */
+#define        AR5K_PHY_ANT_CTL_SECTORED_ANT   0x00000004      /* Sectored Antenna */
+#define        AR5K_PHY_ANT_CTL_HITUNE5        0x00000008      /* Hitune5 (?) */
+#define        AR5K_PHY_ANT_CTL_SWTABLE_IDLE   0x000003f0      /* Switch table idle (?) */
+#define        AR5K_PHY_ANT_CTL_SWTABLE_IDLE_S 4
+
+/*
+ * PHY receiver delay register [5111+]
+ */
+#define        AR5K_PHY_RX_DELAY               0x9914                  /* Register Address */
+#define        AR5K_PHY_RX_DELAY_M             0x00003fff      /* Mask for RX activate to receive delay (/100ns) */
+
+/*
+ * PHY max rx length register (?) [5111]
+ */
+#define        AR5K_PHY_MAX_RX_LEN             0x991c
+
+/*
+ * PHY timing register 4
+ * I(nphase)/Q(adrature) calibration register [5111+]
+ */
+#define        AR5K_PHY_IQ                     0x9920                  /* Register Address */
+#define        AR5K_PHY_IQ_CORR_Q_Q_COFF       0x0000001f      /* Mask for q correction info */
+#define        AR5K_PHY_IQ_CORR_Q_I_COFF       0x000007e0      /* Mask for i correction info */
+#define        AR5K_PHY_IQ_CORR_Q_I_COFF_S     5
+#define        AR5K_PHY_IQ_CORR_ENABLE         0x00000800      /* Enable i/q correction */
+#define        AR5K_PHY_IQ_CAL_NUM_LOG_MAX     0x0000f000      /* Mask for max number of samples in log scale */
+#define        AR5K_PHY_IQ_CAL_NUM_LOG_MAX_S   12
+#define        AR5K_PHY_IQ_RUN                 0x00010000      /* Run i/q calibration */
+#define        AR5K_PHY_IQ_USE_PT_DF           0x00020000      /* Use pilot track df (?) */
+#define        AR5K_PHY_IQ_EARLY_TRIG_THR      0x00200000      /* Early trigger threshold (?) (field) */
+#define        AR5K_PHY_IQ_PILOT_MASK_EN       0x10000000      /* Enable pilot mask (?) */
+#define        AR5K_PHY_IQ_CHAN_MASK_EN        0x20000000      /* Enable channel mask (?) */
+#define        AR5K_PHY_IQ_SPUR_FILT_EN        0x40000000      /* Enable spur filter */
+#define        AR5K_PHY_IQ_SPUR_RSSI_EN        0x80000000      /* Enable spur rssi */
+
+/*
+ * PHY timing register 5
+ * OFDM Self-correlator Cyclic RSSI threshold params
+ * (Check out bb_cycpwr_thr1 on ANI patent)
+ */
+#define        AR5K_PHY_OFDM_SELFCORR                  0x9924                  /* Register Address */
+#define        AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1_EN    0x00000001      /* Enable cyclic RSSI thr 1 */
+#define        AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1       0x000000fe      /* Mask for Cyclic RSSI threshold 1 */
+#define        AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1_S     1
+#define        AR5K_PHY_OFDM_SELFCORR_CYPWR_THR3       0x00000100      /* Cyclic RSSI threshold 3 (field) (?) */
+#define        AR5K_PHY_OFDM_SELFCORR_RSSI_1ATHR_EN    0x00008000      /* Enable 1A RSSI threshold (?) */
+#define        AR5K_PHY_OFDM_SELFCORR_RSSI_1ATHR       0x00010000      /* 1A RSSI threshold (field) (?) */
+#define        AR5K_PHY_OFDM_SELFCORR_LSCTHR_HIRSSI    0x00800000      /* Long sc threshold hi rssi (?) */
+
+/*
+ * PHY-only warm reset register
+ */
+#define        AR5K_PHY_WARM_RESET             0x9928
+
+/*
+ * PHY-only control register
+ */
+#define AR5K_PHY_CTL                   0x992c                  /* Register Address */
+#define        AR5K_PHY_CTL_RX_DRAIN_RATE      0x00000001      /* RX drain rate (?) */
+#define        AR5K_PHY_CTL_LATE_TX_SIG_SYM    0x00000002      /* Late tx signal symbol (?) */
+#define        AR5K_PHY_CTL_GEN_SCRAMBLER      0x00000004      /* Generate scrambler */
+#define        AR5K_PHY_CTL_TX_ANT_SEL         0x00000008      /* TX antenna select */
+#define        AR5K_PHY_CTL_TX_ANT_STATIC      0x00000010      /* Static TX antenna */
+#define        AR5K_PHY_CTL_RX_ANT_SEL         0x00000020      /* RX antenna select */
+#define        AR5K_PHY_CTL_RX_ANT_STATIC      0x00000040      /* Static RX antenna */
+#define        AR5K_PHY_CTL_LOW_FREQ_SLE_EN    0x00000080      /* Enable low freq sleep */
+
+/*
+ * PHY PAPD probe register [5111+]
+ */
+#define        AR5K_PHY_PAPD_PROBE             0x9930
+#define        AR5K_PHY_PAPD_PROBE_SH_HI_PAR   0x00000001
+#define        AR5K_PHY_PAPD_PROBE_PCDAC_BIAS  0x00000002
+#define        AR5K_PHY_PAPD_PROBE_COMP_GAIN   0x00000040
+#define        AR5K_PHY_PAPD_PROBE_TXPOWER     0x00007e00
+#define        AR5K_PHY_PAPD_PROBE_TXPOWER_S   9
+#define        AR5K_PHY_PAPD_PROBE_TX_NEXT     0x00008000
+#define        AR5K_PHY_PAPD_PROBE_PREDIST_EN  0x00010000
+#define        AR5K_PHY_PAPD_PROBE_TYPE        0x01800000      /* [5112+] */
+#define        AR5K_PHY_PAPD_PROBE_TYPE_S      23
+#define        AR5K_PHY_PAPD_PROBE_TYPE_OFDM   0
+#define        AR5K_PHY_PAPD_PROBE_TYPE_XR     1
+#define        AR5K_PHY_PAPD_PROBE_TYPE_CCK    2
+#define        AR5K_PHY_PAPD_PROBE_GAINF       0xfe000000
+#define        AR5K_PHY_PAPD_PROBE_GAINF_S     25
+#define        AR5K_PHY_PAPD_PROBE_INI_5111    0x00004883      /* [5212+] */
+#define        AR5K_PHY_PAPD_PROBE_INI_5112    0x00004882      /* [5212+] */
+
+/*
+ * PHY TX rate power registers [5112+]
+ */
+#define        AR5K_PHY_TXPOWER_RATE1                  0x9934
+#define        AR5K_PHY_TXPOWER_RATE2                  0x9938
+#define        AR5K_PHY_TXPOWER_RATE_MAX               0x993c
+#define        AR5K_PHY_TXPOWER_RATE_MAX_TPC_ENABLE    0x00000040
+#define        AR5K_PHY_TXPOWER_RATE3                  0xa234
+#define        AR5K_PHY_TXPOWER_RATE4                  0xa238
+
+/*
+ * PHY frame control register [5111+]
+ */
+#define        AR5K_PHY_FRAME_CTL_5210         0x9804
+#define        AR5K_PHY_FRAME_CTL_5211         0x9944
+#define        AR5K_PHY_FRAME_CTL              (ah->ah_version == AR5K_AR5210 ? \
+                                       AR5K_PHY_FRAME_CTL_5210 : AR5K_PHY_FRAME_CTL_5211)
+/*---[5111+]---*/
+#define        AR5K_PHY_FRAME_CTL_TX_CLIP      0x00000038      /* Mask for tx clip (?) */
+#define        AR5K_PHY_FRAME_CTL_TX_CLIP_S    3
+#define        AR5K_PHY_FRAME_CTL_PREP_CHINFO  0x00010000      /* Prepend chan info */
+#define        AR5K_PHY_FRAME_CTL_EMU          0x80000000
+#define        AR5K_PHY_FRAME_CTL_EMU_S        31
+/*---[5110/5111]---*/
+#define        AR5K_PHY_FRAME_CTL_TIMING_ERR   0x01000000      /* PHY timing error */
+#define        AR5K_PHY_FRAME_CTL_PARITY_ERR   0x02000000      /* Parity error */
+#define        AR5K_PHY_FRAME_CTL_ILLRATE_ERR  0x04000000      /* Illegal rate */
+#define        AR5K_PHY_FRAME_CTL_ILLLEN_ERR   0x08000000      /* Illegal length */
+#define        AR5K_PHY_FRAME_CTL_SERVICE_ERR  0x20000000
+#define        AR5K_PHY_FRAME_CTL_TXURN_ERR    0x40000000      /* TX underrun */
+#define AR5K_PHY_FRAME_CTL_INI         AR5K_PHY_FRAME_CTL_SERVICE_ERR | \
+                       AR5K_PHY_FRAME_CTL_TXURN_ERR | \
+                       AR5K_PHY_FRAME_CTL_ILLLEN_ERR | \
+                       AR5K_PHY_FRAME_CTL_ILLRATE_ERR | \
+                       AR5K_PHY_FRAME_CTL_PARITY_ERR | \
+                       AR5K_PHY_FRAME_CTL_TIMING_ERR
+
+/*
+ * PHY Tx Power adjustment register [5212A+]
+ */
+#define        AR5K_PHY_TX_PWR_ADJ                     0x994c
+#define        AR5K_PHY_TX_PWR_ADJ_CCK_GAIN_DELTA      0x00000fc0
+#define        AR5K_PHY_TX_PWR_ADJ_CCK_GAIN_DELTA_S    6
+#define        AR5K_PHY_TX_PWR_ADJ_CCK_PCDAC_INDEX     0x00fc0000
+#define        AR5K_PHY_TX_PWR_ADJ_CCK_PCDAC_INDEX_S   18
+
+/*
+ * PHY radar detection register [5111+]
+ */
+#define        AR5K_PHY_RADAR                  0x9954
+#define        AR5K_PHY_RADAR_ENABLE           0x00000001
+#define        AR5K_PHY_RADAR_DISABLE          0x00000000
+#define AR5K_PHY_RADAR_INBANDTHR       0x0000003e      /* Inband threshold
+                                                       5-bits, units unknown {0..31}
+                                                       (? MHz ?) */
+#define AR5K_PHY_RADAR_INBANDTHR_S     1
+
+#define AR5K_PHY_RADAR_PRSSI_THR       0x00000fc0      /* Pulse RSSI/SNR threshold
+                                                       6-bits, dBm range {0..63}
+                                                       in dBm units. */
+#define AR5K_PHY_RADAR_PRSSI_THR_S     6
+
+#define AR5K_PHY_RADAR_PHEIGHT_THR     0x0003f000      /* Pulse height threshold
+                                                       6-bits, dBm range {0..63}
+                                                       in dBm units. */
+#define AR5K_PHY_RADAR_PHEIGHT_THR_S   12
+
+#define AR5K_PHY_RADAR_RSSI_THR        0x00fc0000      /* Radar RSSI/SNR threshold.
+                                                       6-bits, dBm range {0..63}
+                                                       in dBm units. */
+#define AR5K_PHY_RADAR_RSSI_THR_S      18
+
+#define AR5K_PHY_RADAR_FIRPWR_THR      0x7f000000      /* Finite Impulse Response
+                                                       filter power out threshold.
+                                                       7-bits, standard power range
+                                                       {0..127} in 1/2 dBm units. */
+#define AR5K_PHY_RADAR_FIRPWR_THRS     24
+
+/*
+ * PHY antenna switch table registers
+ */
+#define AR5K_PHY_ANT_SWITCH_TABLE_0    0x9960
+#define AR5K_PHY_ANT_SWITCH_TABLE_1    0x9964
+
+/*
+ * PHY Noise floor threshold
+ */
+#define AR5K_PHY_NFTHRES               0x9968
+
+/*
+ * Sigma Delta register (?) [5213]
+ */
+#define AR5K_PHY_SIGMA_DELTA           0x996C
+#define AR5K_PHY_SIGMA_DELTA_ADC_SEL   0x00000003
+#define AR5K_PHY_SIGMA_DELTA_ADC_SEL_S 0
+#define AR5K_PHY_SIGMA_DELTA_FILT2     0x000000f8
+#define AR5K_PHY_SIGMA_DELTA_FILT2_S   3
+#define AR5K_PHY_SIGMA_DELTA_FILT1     0x00001f00
+#define AR5K_PHY_SIGMA_DELTA_FILT1_S   8
+#define AR5K_PHY_SIGMA_DELTA_ADC_CLIP  0x01ffe000
+#define AR5K_PHY_SIGMA_DELTA_ADC_CLIP_S        13
+
+/*
+ * RF restart register [5112+] (?)
+ */
+#define AR5K_PHY_RESTART               0x9970          /* restart */
+#define AR5K_PHY_RESTART_DIV_GC                0x001c0000      /* Fast diversity gc_limit (?) */
+#define AR5K_PHY_RESTART_DIV_GC_S      18
+
+/*
+ * RF Bus access request register (for synth-oly channel switching)
+ */
+#define AR5K_PHY_RFBUS_REQ             0x997C
+#define AR5K_PHY_RFBUS_REQ_REQUEST     0x00000001
+
+/*
+ * Spur mitigation masks (?)
+ */
+#define AR5K_PHY_TIMING_7              0x9980
+#define AR5K_PHY_TIMING_8              0x9984
+#define AR5K_PHY_TIMING_8_PILOT_MASK_2         0x000fffff
+#define AR5K_PHY_TIMING_8_PILOT_MASK_2_S       0
+
+#define AR5K_PHY_BIN_MASK2_1           0x9988
+#define AR5K_PHY_BIN_MASK2_2           0x998c
+#define AR5K_PHY_BIN_MASK2_3           0x9990
+
+#define AR5K_PHY_BIN_MASK2_4           0x9994
+#define AR5K_PHY_BIN_MASK2_4_MASK_4    0x00003fff
+#define AR5K_PHY_BIN_MASK2_4_MASK_4_S  0
+
+#define AR5K_PHY_TIMING_9                      0x9998
+#define AR5K_PHY_TIMING_10                     0x999c
+#define AR5K_PHY_TIMING_10_PILOT_MASK_2                0x000fffff
+#define AR5K_PHY_TIMING_10_PILOT_MASK_2_S      0
+
+/*
+ * Spur mitigation control
+ */
+#define AR5K_PHY_TIMING_11                     0x99a0          /* Register address */
+#define AR5K_PHY_TIMING_11_SPUR_DELTA_PHASE    0x000fffff      /* Spur delta phase */
+#define AR5K_PHY_TIMING_11_SPUR_DELTA_PHASE_S  0
+#define AR5K_PHY_TIMING_11_SPUR_FREQ_SD                0x3ff00000      /* Freq sigma delta */
+#define AR5K_PHY_TIMING_11_SPUR_FREQ_SD_S      20
+#define AR5K_PHY_TIMING_11_USE_SPUR_IN_AGC     0x40000000      /* Spur filter in AGC detector */
+#define AR5K_PHY_TIMING_11_USE_SPUR_IN_SELFCOR 0x80000000      /* Spur filter in OFDM self correlator */
+
+/*
+ * Gain tables
+ */
+#define        AR5K_BB_GAIN_BASE               0x9b00  /* BaseBand Amplifier Gain table base address */
+#define AR5K_BB_GAIN(_n)               (AR5K_BB_GAIN_BASE + ((_n) << 2))
+#define        AR5K_RF_GAIN_BASE               0x9a00  /* RF Amplrifier Gain table base address */
+#define AR5K_RF_GAIN(_n)               (AR5K_RF_GAIN_BASE + ((_n) << 2))
+
+/*
+ * PHY timing IQ calibration result register [5111+]
+ */
+#define        AR5K_PHY_IQRES_CAL_PWR_I        0x9c10  /* I (Inphase) power value */
+#define        AR5K_PHY_IQRES_CAL_PWR_Q        0x9c14  /* Q (Quadrature) power value */
+#define        AR5K_PHY_IQRES_CAL_CORR         0x9c18  /* I/Q Correlation */
+
+/*
+ * PHY current RSSI register [5111+]
+ */
+#define        AR5K_PHY_CURRENT_RSSI   0x9c1c
+
+/*
+ * PHY RF Bus grant register
+ */
+#define        AR5K_PHY_RFBUS_GRANT    0x9c20
+#define        AR5K_PHY_RFBUS_GRANT_OK 0x00000001
+
+/*
+ * PHY ADC test register
+ */
+#define        AR5K_PHY_ADC_TEST       0x9c24
+#define        AR5K_PHY_ADC_TEST_I     0x00000001
+#define        AR5K_PHY_ADC_TEST_Q     0x00000200
+
+/*
+ * PHY DAC test register
+ */
+#define        AR5K_PHY_DAC_TEST       0x9c28
+#define        AR5K_PHY_DAC_TEST_I     0x00000001
+#define        AR5K_PHY_DAC_TEST_Q     0x00000200
+
+/*
+ * PHY PTAT register (?)
+ */
+#define        AR5K_PHY_PTAT           0x9c2c
+
+/*
+ * PHY Illegal TX rate register [5112+]
+ */
+#define        AR5K_PHY_BAD_TX_RATE    0x9c30
+
+/*
+ * PHY SPUR Power register [5112+]
+ */
+#define        AR5K_PHY_SPUR_PWR       0x9c34                  /* Register Address */
+#define        AR5K_PHY_SPUR_PWR_I     0x00000001      /* SPUR Power estimate for I (field) */
+#define        AR5K_PHY_SPUR_PWR_Q     0x00000100      /* SPUR Power estimate for Q (field) */
+#define        AR5K_PHY_SPUR_PWR_FILT  0x00010000      /* Power with SPUR removed (field) */
+
+/*
+ * PHY Channel status register [5112+] (?)
+ */
+#define        AR5K_PHY_CHAN_STATUS            0x9c38
+#define        AR5K_PHY_CHAN_STATUS_BT_ACT     0x00000001
+#define        AR5K_PHY_CHAN_STATUS_RX_CLR_RAW 0x00000002
+#define        AR5K_PHY_CHAN_STATUS_RX_CLR_MAC 0x00000004
+#define        AR5K_PHY_CHAN_STATUS_RX_CLR_PAP 0x00000008
+
+/*
+ * Heavy clip enable register
+ */
+#define        AR5K_PHY_HEAVY_CLIP_ENABLE      0x99e0
+
+/*
+ * PHY clock sleep registers [5112+]
+ */
+#define AR5K_PHY_SCLOCK                        0x99f0
+#define AR5K_PHY_SCLOCK_32MHZ          0x0000000c
+#define AR5K_PHY_SDELAY                        0x99f4
+#define AR5K_PHY_SDELAY_32MHZ          0x000000ff
+#define AR5K_PHY_SPENDING              0x99f8
+
+
+/*
+ * PHY PAPD I (power?) table (?)
+ * (92! entries)
+ */
+#define        AR5K_PHY_PAPD_I_BASE    0xa000
+#define        AR5K_PHY_PAPD_I(_n)     (AR5K_PHY_PAPD_I_BASE + ((_n) << 2))
+
+/*
+ * PHY PCDAC TX power table
+ */
+#define        AR5K_PHY_PCDAC_TXPOWER_BASE     0xa180
+#define        AR5K_PHY_PCDAC_TXPOWER(_n)      (AR5K_PHY_PCDAC_TXPOWER_BASE + ((_n) << 2))
+
+/*
+ * PHY mode register [5111+]
+ */
+#define        AR5K_PHY_MODE                   0x0a200                 /* Register Address */
+#define        AR5K_PHY_MODE_MOD               0x00000001      /* PHY Modulation bit */
+#define AR5K_PHY_MODE_MOD_OFDM         0
+#define AR5K_PHY_MODE_MOD_CCK          1
+#define AR5K_PHY_MODE_FREQ             0x00000002      /* Freq mode bit */
+#define        AR5K_PHY_MODE_FREQ_5GHZ         0
+#define        AR5K_PHY_MODE_FREQ_2GHZ         2
+#define AR5K_PHY_MODE_MOD_DYN          0x00000004      /* Enable Dynamic OFDM/CCK mode [5112+] */
+#define AR5K_PHY_MODE_RAD              0x00000008      /* [5212+] */
+#define AR5K_PHY_MODE_RAD_RF5111       0
+#define AR5K_PHY_MODE_RAD_RF5112       8
+#define AR5K_PHY_MODE_XR               0x00000010      /* Enable XR mode [5112+] */
+#define        AR5K_PHY_MODE_HALF_RATE         0x00000020      /* Enable Half rate (test) */
+#define        AR5K_PHY_MODE_QUARTER_RATE      0x00000040      /* Enable Quarter rat (test) */
+
+/*
+ * PHY CCK transmit control register [5111+ (?)]
+ */
+#define AR5K_PHY_CCKTXCTL              0xa204
+#define AR5K_PHY_CCKTXCTL_WORLD                0x00000000
+#define AR5K_PHY_CCKTXCTL_JAPAN                0x00000010
+#define        AR5K_PHY_CCKTXCTL_SCRAMBLER_DIS 0x00000001
+#define        AR5K_PHY_CCKTXCTK_DAC_SCALE     0x00000004
+
+/*
+ * PHY CCK Cross-correlator Barker RSSI threshold register [5212+]
+ */
+#define AR5K_PHY_CCK_CROSSCORR                 0xa208
+#define AR5K_PHY_CCK_CROSSCORR_WEAK_SIG_THR    0x0000003f
+#define AR5K_PHY_CCK_CROSSCORR_WEAK_SIG_THR_S  0
+
+/* Same address is used for antenna diversity activation */
+#define        AR5K_PHY_FAST_ANT_DIV           0xa208
+#define        AR5K_PHY_FAST_ANT_DIV_EN        0x00002000
+
+/*
+ * PHY 2GHz gain register [5111+]
+ */
+#define        AR5K_PHY_GAIN_2GHZ                      0xa20c
+#define        AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX          0x00fc0000
+#define        AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX_S        18
+#define        AR5K_PHY_GAIN_2GHZ_INI_5111             0x6480416c
+
+#define        AR5K_PHY_CCK_RX_CTL_4                   0xa21c
+#define        AR5K_PHY_CCK_RX_CTL_4_FREQ_EST_SHORT    0x01f80000
+#define        AR5K_PHY_CCK_RX_CTL_4_FREQ_EST_SHORT_S  19
+
+#define        AR5K_PHY_DAG_CCK_CTL                    0xa228
+#define        AR5K_PHY_DAG_CCK_CTL_EN_RSSI_THR        0x00000200
+#define        AR5K_PHY_DAG_CCK_CTL_RSSI_THR           0x0001fc00
+#define        AR5K_PHY_DAG_CCK_CTL_RSSI_THR_S         10
+
+#define        AR5K_PHY_FAST_ADC       0xa24c
+
+#define        AR5K_PHY_BLUETOOTH      0xa254
+
+/*
+ * Transmit Power Control register
+ * [2413+]
+ */
+#define        AR5K_PHY_TPC_RG1                0xa258
+#define        AR5K_PHY_TPC_RG1_NUM_PD_GAIN    0x0000c000
+#define        AR5K_PHY_TPC_RG1_NUM_PD_GAIN_S  14
+#define AR5K_PHY_TPC_RG1_PDGAIN_1      0x00030000
+#define AR5K_PHY_TPC_RG1_PDGAIN_1_S    16
+#define AR5K_PHY_TPC_RG1_PDGAIN_2      0x000c0000
+#define AR5K_PHY_TPC_RG1_PDGAIN_2_S    18
+#define AR5K_PHY_TPC_RG1_PDGAIN_3      0x00300000
+#define AR5K_PHY_TPC_RG1_PDGAIN_3_S    20
+
+#define        AR5K_PHY_TPC_RG5                        0xa26C
+#define        AR5K_PHY_TPC_RG5_PD_GAIN_OVERLAP        0x0000000F
+#define        AR5K_PHY_TPC_RG5_PD_GAIN_OVERLAP_S      0
+#define        AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_1     0x000003F0
+#define        AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_1_S   4
+#define        AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_2     0x0000FC00
+#define        AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_2_S   10
+#define        AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_3     0x003F0000
+#define        AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_3_S   16
+#define        AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_4     0x0FC00000
+#define        AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_4_S   22
+
+/*
+ * PHY PDADC Tx power table
+ */
+#define AR5K_PHY_PDADC_TXPOWER_BASE    0xa280
+#define        AR5K_PHY_PDADC_TXPOWER(_n)      (AR5K_PHY_PDADC_TXPOWER_BASE + ((_n) << 2))
diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c
new file mode 100644 (file)
index 0000000..bd0a97a
--- /dev/null
@@ -0,0 +1,1323 @@
+/*
+ * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
+ * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
+ * Copyright (c) 2007-2008 Luis Rodriguez <mcgrof@winlab.rutgers.edu>
+ * Copyright (c) 2007-2008 Pavel Roskin <proski@gnu.org>
+ * Copyright (c) 2007-2008 Jiri Slaby <jirislaby@gmail.com>
+ *
+ * Permission to use, copy, modify, and 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.
+ *
+ */
+
+#define _ATH5K_RESET
+
+/*****************************\
+  Reset functions and helpers
+\*****************************/
+
+#include <linux/pci.h>                 /* To determine if a card is pci-e */
+#include <linux/log2.h>
+#include "ath5k.h"
+#include "reg.h"
+#include "base.h"
+#include "debug.h"
+
+/**
+ * ath5k_hw_write_ofdm_timings - set OFDM timings on AR5212
+ *
+ * @ah: the &struct ath5k_hw
+ * @channel: the currently set channel upon reset
+ *
+ * Write the delta slope coefficient (used on pilot tracking ?) for OFDM
+ * operation on the AR5212 upon reset. This is a helper for ath5k_hw_reset().
+ *
+ * Since delta slope is floating point we split it on its exponent and
+ * mantissa and provide these values on hw.
+ *
+ * For more infos i think this patent is related
+ * http://www.freepatentsonline.com/7184495.html
+ */
+static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah,
+       struct ieee80211_channel *channel)
+{
+       /* Get exponent and mantissa and set it */
+       u32 coef_scaled, coef_exp, coef_man,
+               ds_coef_exp, ds_coef_man, clock;
+
+       BUG_ON(!(ah->ah_version == AR5K_AR5212) ||
+               !(channel->hw_value & CHANNEL_OFDM));
+
+       /* Get coefficient
+        * ALGO: coef = (5 * clock * carrier_freq) / 2)
+        * we scale coef by shifting clock value by 24 for
+        * better precision since we use integers */
+       /* TODO: Half/quarter rate */
+       clock =  ath5k_hw_htoclock(1, channel->hw_value & CHANNEL_TURBO);
+
+       coef_scaled = ((5 * (clock << 24)) / 2) / channel->center_freq;
+
+       /* Get exponent
+        * ALGO: coef_exp = 14 - highest set bit position */
+       coef_exp = ilog2(coef_scaled);
+
+       /* Doesn't make sense if it's zero*/
+       if (!coef_scaled || !coef_exp)
+               return -EINVAL;
+
+       /* Note: we've shifted coef_scaled by 24 */
+       coef_exp = 14 - (coef_exp - 24);
+
+
+       /* Get mantissa (significant digits)
+        * ALGO: coef_mant = floor(coef_scaled* 2^coef_exp+0.5) */
+       coef_man = coef_scaled +
+               (1 << (24 - coef_exp - 1));
+
+       /* Calculate delta slope coefficient exponent
+        * and mantissa (remove scaling) and set them on hw */
+       ds_coef_man = coef_man >> (24 - coef_exp);
+       ds_coef_exp = coef_exp - 16;
+
+       AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3,
+               AR5K_PHY_TIMING_3_DSC_MAN, ds_coef_man);
+       AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3,
+               AR5K_PHY_TIMING_3_DSC_EXP, ds_coef_exp);
+
+       return 0;
+}
+
+
+/*
+ * index into rates for control rates, we can set it up like this because
+ * this is only used for AR5212 and we know it supports G mode
+ */
+static const unsigned int control_rates[] =
+       { 0, 1, 1, 1, 4, 4, 6, 6, 8, 8, 8, 8 };
+
+/**
+ * ath5k_hw_write_rate_duration - fill rate code to duration table
+ *
+ * @ah: the &struct ath5k_hw
+ * @mode: one of enum ath5k_driver_mode
+ *
+ * Write the rate code to duration table upon hw reset. This is a helper for
+ * ath5k_hw_reset(). It seems all this is doing is setting an ACK timeout on
+ * the hardware, based on current mode, for each rate. The rates which are
+ * capable of short preamble (802.11b rates 2Mbps, 5.5Mbps, and 11Mbps) have
+ * different rate code so we write their value twice (one for long preample
+ * and one for short).
+ *
+ * Note: Band doesn't matter here, if we set the values for OFDM it works
+ * on both a and g modes. So all we have to do is set values for all g rates
+ * that include all OFDM and CCK rates. If we operate in turbo or xr/half/
+ * quarter rate mode, we need to use another set of bitrates (that's why we
+ * need the mode parameter) but we don't handle these proprietary modes yet.
+ */
+static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah,
+       unsigned int mode)
+{
+       struct ath5k_softc *sc = ah->ah_sc;
+       struct ieee80211_rate *rate;
+       unsigned int i;
+
+       /* Write rate duration table */
+       for (i = 0; i < sc->sbands[IEEE80211_BAND_2GHZ].n_bitrates; i++) {
+               u32 reg;
+               u16 tx_time;
+
+               rate = &sc->sbands[IEEE80211_BAND_2GHZ].bitrates[control_rates[i]];
+
+               /* Set ACK timeout */
+               reg = AR5K_RATE_DUR(rate->hw_value);
+
+               /* An ACK frame consists of 10 bytes. If you add the FCS,
+                * which ieee80211_generic_frame_duration() adds,
+                * its 14 bytes. Note we use the control rate and not the
+                * actual rate for this rate. See mac80211 tx.c
+                * ieee80211_duration() for a brief description of
+                * what rate we should choose to TX ACKs. */
+               tx_time = le16_to_cpu(ieee80211_generic_frame_duration(sc->hw,
+                                                       sc->vif, 10, rate));
+
+               ath5k_hw_reg_write(ah, tx_time, reg);
+
+               if (!(rate->flags & IEEE80211_RATE_SHORT_PREAMBLE))
+                       continue;
+
+               /*
+                * We're not distinguishing short preamble here,
+                * This is true, all we'll get is a longer value here
+                * which is not necessarilly bad. We could use
+                * export ieee80211_frame_duration() but that needs to be
+                * fixed first to be properly used by mac802111 drivers:
+                *
+                *  - remove erp stuff and let the routine figure ofdm
+                *    erp rates
+                *  - remove passing argument ieee80211_local as
+                *    drivers don't have access to it
+                *  - move drivers using ieee80211_generic_frame_duration()
+                *    to this
+                */
+               ath5k_hw_reg_write(ah, tx_time,
+                       reg + (AR5K_SET_SHORT_PREAMBLE << 2));
+       }
+}
+
+/*
+ * Reset chipset
+ */
+static int ath5k_hw_nic_reset(struct ath5k_hw *ah, u32 val)
+{
+       int ret;
+       u32 mask = val ? val : ~0U;
+
+       ATH5K_TRACE(ah->ah_sc);
+
+       /* Read-and-clear RX Descriptor Pointer*/
+       ath5k_hw_reg_read(ah, AR5K_RXDP);
+
+       /*
+        * Reset the device and wait until success
+        */
+       ath5k_hw_reg_write(ah, val, AR5K_RESET_CTL);
+
+       /* Wait at least 128 PCI clocks */
+       udelay(15);
+
+       if (ah->ah_version == AR5K_AR5210) {
+               val &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_DMA
+                       | AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_PHY;
+               mask &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_DMA
+                       | AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_PHY;
+       } else {
+               val &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_BASEBAND;
+               mask &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_BASEBAND;
+       }
+
+       ret = ath5k_hw_register_timeout(ah, AR5K_RESET_CTL, mask, val, false);
+
+       /*
+        * Reset configuration register (for hw byte-swap). Note that this
+        * is only set for big endian. We do the necessary magic in
+        * AR5K_INIT_CFG.
+        */
+       if ((val & AR5K_RESET_CTL_PCU) == 0)
+               ath5k_hw_reg_write(ah, AR5K_INIT_CFG, AR5K_CFG);
+
+       return ret;
+}
+
+/*
+ * Sleep control
+ */
+int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode,
+               bool set_chip, u16 sleep_duration)
+{
+       unsigned int i;
+       u32 staid, data;
+
+       ATH5K_TRACE(ah->ah_sc);
+       staid = ath5k_hw_reg_read(ah, AR5K_STA_ID1);
+
+       switch (mode) {
+       case AR5K_PM_AUTO:
+               staid &= ~AR5K_STA_ID1_DEFAULT_ANTENNA;
+               /* fallthrough */
+       case AR5K_PM_NETWORK_SLEEP:
+               if (set_chip)
+                       ath5k_hw_reg_write(ah,
+                               AR5K_SLEEP_CTL_SLE_ALLOW |
+                               sleep_duration,
+                               AR5K_SLEEP_CTL);
+
+               staid |= AR5K_STA_ID1_PWR_SV;
+               break;
+
+       case AR5K_PM_FULL_SLEEP:
+               if (set_chip)
+                       ath5k_hw_reg_write(ah, AR5K_SLEEP_CTL_SLE_SLP,
+                               AR5K_SLEEP_CTL);
+
+               staid |= AR5K_STA_ID1_PWR_SV;
+               break;
+
+       case AR5K_PM_AWAKE:
+
+               staid &= ~AR5K_STA_ID1_PWR_SV;
+
+               if (!set_chip)
+                       goto commit;
+
+               /* Preserve sleep duration */
+               data = ath5k_hw_reg_read(ah, AR5K_SLEEP_CTL);
+               if (data & 0xffc00000)
+                       data = 0;
+               else
+                       data = data & 0xfffcffff;
+
+               ath5k_hw_reg_write(ah, data, AR5K_SLEEP_CTL);
+               udelay(15);
+
+               for (i = 50; i > 0; i--) {
+                       /* Check if the chip did wake up */
+                       if ((ath5k_hw_reg_read(ah, AR5K_PCICFG) &
+                                       AR5K_PCICFG_SPWR_DN) == 0)
+                               break;
+
+                       /* Wait a bit and retry */
+                       udelay(200);
+                       ath5k_hw_reg_write(ah, data, AR5K_SLEEP_CTL);
+               }
+
+               /* Fail if the chip didn't wake up */
+               if (i <= 0)
+                       return -EIO;
+
+               break;
+
+       default:
+               return -EINVAL;
+       }
+
+commit:
+       ah->ah_power_mode = mode;
+       ath5k_hw_reg_write(ah, staid, AR5K_STA_ID1);
+
+       return 0;
+}
+
+/*
+ * Bring up MAC + PHY Chips and program PLL
+ * TODO: Half/Quarter rate support
+ */
+int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
+{
+       struct pci_dev *pdev = ah->ah_sc->pdev;
+       u32 turbo, mode, clock, bus_flags;
+       int ret;
+
+       turbo = 0;
+       mode = 0;
+       clock = 0;
+
+       ATH5K_TRACE(ah->ah_sc);
+
+       /* Wakeup the device */
+       ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);
+       if (ret) {
+               ATH5K_ERR(ah->ah_sc, "failed to wakeup the MAC Chip\n");
+               return ret;
+       }
+
+       if (ah->ah_version != AR5K_AR5210) {
+               /*
+                * Get channel mode flags
+                */
+
+               if (ah->ah_radio >= AR5K_RF5112) {
+                       mode = AR5K_PHY_MODE_RAD_RF5112;
+                       clock = AR5K_PHY_PLL_RF5112;
+               } else {
+                       mode = AR5K_PHY_MODE_RAD_RF5111;        /*Zero*/
+                       clock = AR5K_PHY_PLL_RF5111;            /*Zero*/
+               }
+
+               if (flags & CHANNEL_2GHZ) {
+                       mode |= AR5K_PHY_MODE_FREQ_2GHZ;
+                       clock |= AR5K_PHY_PLL_44MHZ;
+
+                       if (flags & CHANNEL_CCK) {
+                               mode |= AR5K_PHY_MODE_MOD_CCK;
+                       } else if (flags & CHANNEL_OFDM) {
+                               /* 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
+                                * this, 5211 might support ofdm-only g after
+                                * all, there are also initial register values
+                                * in the code for g mode (see initvals.c). */
+                               if (ah->ah_version == AR5K_AR5211)
+                                       mode |= AR5K_PHY_MODE_MOD_OFDM;
+                               else
+                                       mode |= AR5K_PHY_MODE_MOD_DYN;
+                       } else {
+                               ATH5K_ERR(ah->ah_sc,
+                                       "invalid radio modulation mode\n");
+                               return -EINVAL;
+                       }
+               } else if (flags & CHANNEL_5GHZ) {
+                       mode |= AR5K_PHY_MODE_FREQ_5GHZ;
+
+                       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->ah_sc,
+                                       "invalid radio modulation mode\n");
+                               return -EINVAL;
+                       }
+               } else {
+                       ATH5K_ERR(ah->ah_sc, "invalid radio frequency mode\n");
+                       return -EINVAL;
+               }
+
+               if (flags & CHANNEL_TURBO)
+                       turbo = AR5K_PHY_TURBO_MODE | AR5K_PHY_TURBO_SHORT;
+       } else { /* Reset the device */
+
+               /* ...enable Atheros turbo mode if requested */
+               if (flags & CHANNEL_TURBO)
+                       ath5k_hw_reg_write(ah, AR5K_PHY_TURBO_MODE,
+                                       AR5K_PHY_TURBO);
+       }
+
+       /* reseting PCI on PCI-E cards results card to hang
+        * and always return 0xffff... so we ingore that flag
+        * for PCI-E cards */
+       bus_flags = (pdev->is_pcie) ? 0 : AR5K_RESET_CTL_PCI;
+
+       /* Reset chipset */
+       if (ah->ah_version == AR5K_AR5210) {
+               ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
+                       AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_DMA |
+                       AR5K_RESET_CTL_PHY | AR5K_RESET_CTL_PCI);
+                       mdelay(2);
+       } else {
+               ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
+                       AR5K_RESET_CTL_BASEBAND | bus_flags);
+       }
+       if (ret) {
+               ATH5K_ERR(ah->ah_sc, "failed to reset the MAC Chip\n");
+               return -EIO;
+       }
+
+       /* ...wakeup again!*/
+       ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);
+       if (ret) {
+               ATH5K_ERR(ah->ah_sc, "failed to resume the MAC Chip\n");
+               return ret;
+       }
+
+       /* ...final warm reset */
+       if (ath5k_hw_nic_reset(ah, 0)) {
+               ATH5K_ERR(ah->ah_sc, "failed to warm reset the MAC Chip\n");
+               return -EIO;
+       }
+
+       if (ah->ah_version != AR5K_AR5210) {
+
+               /* ...update PLL if needed */
+               if (ath5k_hw_reg_read(ah, AR5K_PHY_PLL) != clock) {
+                       ath5k_hw_reg_write(ah, clock, AR5K_PHY_PLL);
+                       udelay(300);
+               }
+
+               /* ...set the PHY operating mode */
+               ath5k_hw_reg_write(ah, mode, AR5K_PHY_MODE);
+               ath5k_hw_reg_write(ah, turbo, AR5K_PHY_TURBO);
+       }
+
+       return 0;
+}
+
+/*
+ * If there is an external 32KHz crystal available, use it
+ * as ref. clock instead of 32/40MHz clock and baseband clocks
+ * to save power during sleep or restore normal 32/40MHz
+ * operation.
+ *
+ * XXX: When operating on 32KHz certain PHY registers (27 - 31,
+ *     123 - 127) require delay on access.
+ */
+static void ath5k_hw_set_sleep_clock(struct ath5k_hw *ah, bool enable)
+{
+       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+       u32 scal, spending, usec32;
+
+       /* Only set 32KHz settings if we have an external
+        * 32KHz crystal present */
+       if ((AR5K_EEPROM_HAS32KHZCRYSTAL(ee->ee_misc1) ||
+       AR5K_EEPROM_HAS32KHZCRYSTAL_OLD(ee->ee_misc1)) &&
+       enable) {
+
+               /* 1 usec/cycle */
+               AR5K_REG_WRITE_BITS(ah, AR5K_USEC_5211, AR5K_USEC_32, 1);
+               /* Set up tsf increment on each cycle */
+               AR5K_REG_WRITE_BITS(ah, AR5K_TSF_PARM, AR5K_TSF_PARM_INC, 61);
+
+               /* Set baseband sleep control registers
+                * and sleep control rate */
+               ath5k_hw_reg_write(ah, 0x1f, AR5K_PHY_SCR);
+
+               if ((ah->ah_radio == AR5K_RF5112) ||
+               (ah->ah_radio == AR5K_RF5413) ||
+               (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))
+                       spending = 0x14;
+               else
+                       spending = 0x18;
+               ath5k_hw_reg_write(ah, spending, AR5K_PHY_SPENDING);
+
+               if ((ah->ah_radio == AR5K_RF5112) ||
+               (ah->ah_radio == AR5K_RF5413) ||
+               (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) {
+                       ath5k_hw_reg_write(ah, 0x26, AR5K_PHY_SLMT);
+                       ath5k_hw_reg_write(ah, 0x0d, AR5K_PHY_SCAL);
+                       ath5k_hw_reg_write(ah, 0x07, AR5K_PHY_SCLOCK);
+                       ath5k_hw_reg_write(ah, 0x3f, AR5K_PHY_SDELAY);
+                       AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG,
+                               AR5K_PCICFG_SLEEP_CLOCK_RATE, 0x02);
+               } else {
+                       ath5k_hw_reg_write(ah, 0x0a, AR5K_PHY_SLMT);
+                       ath5k_hw_reg_write(ah, 0x0c, AR5K_PHY_SCAL);
+                       ath5k_hw_reg_write(ah, 0x03, AR5K_PHY_SCLOCK);
+                       ath5k_hw_reg_write(ah, 0x20, AR5K_PHY_SDELAY);
+                       AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG,
+                               AR5K_PCICFG_SLEEP_CLOCK_RATE, 0x03);
+               }
+
+               /* Enable sleep clock operation */
+               AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG,
+                               AR5K_PCICFG_SLEEP_CLOCK_EN);
+
+       } else {
+
+               /* Disable sleep clock operation and
+                * restore default parameters */
+               AR5K_REG_DISABLE_BITS(ah, AR5K_PCICFG,
+                               AR5K_PCICFG_SLEEP_CLOCK_EN);
+
+               AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG,
+                               AR5K_PCICFG_SLEEP_CLOCK_RATE, 0);
+
+               ath5k_hw_reg_write(ah, 0x1f, AR5K_PHY_SCR);
+               ath5k_hw_reg_write(ah, AR5K_PHY_SLMT_32MHZ, AR5K_PHY_SLMT);
+
+               if (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))
+                       scal = AR5K_PHY_SCAL_32MHZ_2417;
+               else if (ee->ee_is_hb63)
+                       scal = AR5K_PHY_SCAL_32MHZ_HB63;
+               else
+                       scal = AR5K_PHY_SCAL_32MHZ;
+               ath5k_hw_reg_write(ah, scal, AR5K_PHY_SCAL);
+
+               ath5k_hw_reg_write(ah, AR5K_PHY_SCLOCK_32MHZ, AR5K_PHY_SCLOCK);
+               ath5k_hw_reg_write(ah, AR5K_PHY_SDELAY_32MHZ, AR5K_PHY_SDELAY);
+
+               if ((ah->ah_radio == AR5K_RF5112) ||
+               (ah->ah_radio == AR5K_RF5413) ||
+               (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))
+                       spending = 0x14;
+               else
+                       spending = 0x18;
+               ath5k_hw_reg_write(ah, spending, AR5K_PHY_SPENDING);
+
+               if ((ah->ah_radio == AR5K_RF5112) ||
+               (ah->ah_radio == AR5K_RF5413))
+                       usec32 = 39;
+               else
+                       usec32 = 31;
+               AR5K_REG_WRITE_BITS(ah, AR5K_USEC_5211, AR5K_USEC_32, usec32);
+
+               AR5K_REG_WRITE_BITS(ah, AR5K_TSF_PARM, AR5K_TSF_PARM_INC, 1);
+       }
+       return;
+}
+
+/* TODO: Half/Quarter rate */
+static void ath5k_hw_tweak_initval_settings(struct ath5k_hw *ah,
+                               struct ieee80211_channel *channel)
+{
+       if (ah->ah_version == AR5K_AR5212 &&
+           ah->ah_phy_revision >= AR5K_SREV_PHY_5212A) {
+
+               /* Setup ADC control */
+               ath5k_hw_reg_write(ah,
+                               (AR5K_REG_SM(2,
+                               AR5K_PHY_ADC_CTL_INBUFGAIN_OFF) |
+                               AR5K_REG_SM(2,
+                               AR5K_PHY_ADC_CTL_INBUFGAIN_ON) |
+                               AR5K_PHY_ADC_CTL_PWD_DAC_OFF |
+                               AR5K_PHY_ADC_CTL_PWD_ADC_OFF),
+                               AR5K_PHY_ADC_CTL);
+
+
+
+               /* Disable barker RSSI threshold */
+               AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_DAG_CCK_CTL,
+                               AR5K_PHY_DAG_CCK_CTL_EN_RSSI_THR);
+
+               AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DAG_CCK_CTL,
+                       AR5K_PHY_DAG_CCK_CTL_RSSI_THR, 2);
+
+               /* Set the mute mask */
+               ath5k_hw_reg_write(ah, 0x0000000f, AR5K_SEQ_MASK);
+       }
+
+       /* Clear PHY_BLUETOOTH to allow RX_CLEAR line debug */
+       if (ah->ah_phy_revision >= AR5K_SREV_PHY_5212B)
+               ath5k_hw_reg_write(ah, 0, AR5K_PHY_BLUETOOTH);
+
+       /* Enable DCU double buffering */
+       if (ah->ah_phy_revision > AR5K_SREV_PHY_5212B)
+               AR5K_REG_DISABLE_BITS(ah, AR5K_TXCFG,
+                               AR5K_TXCFG_DCU_DBL_BUF_DIS);
+
+       /* Set DAC/ADC delays */
+       if (ah->ah_version == AR5K_AR5212) {
+               u32 scal;
+               struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+               if (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))
+                       scal = AR5K_PHY_SCAL_32MHZ_2417;
+               else if (ee->ee_is_hb63)
+                       scal = AR5K_PHY_SCAL_32MHZ_HB63;
+               else
+                       scal = AR5K_PHY_SCAL_32MHZ;
+               ath5k_hw_reg_write(ah, scal, AR5K_PHY_SCAL);
+       }
+
+       /* Set fast ADC */
+       if ((ah->ah_radio == AR5K_RF5413) ||
+       (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) {
+               u32 fast_adc = true;
+
+               if (channel->center_freq == 2462 ||
+               channel->center_freq == 2467)
+                       fast_adc = 0;
+
+               /* Only update if needed */
+               if (ath5k_hw_reg_read(ah, AR5K_PHY_FAST_ADC) != fast_adc)
+                               ath5k_hw_reg_write(ah, fast_adc,
+                                               AR5K_PHY_FAST_ADC);
+       }
+
+       /* Fix for first revision of the RF5112 RF chipset */
+       if (ah->ah_radio == AR5K_RF5112 &&
+                       ah->ah_radio_5ghz_revision <
+                       AR5K_SREV_RAD_5112A) {
+               u32 data;
+               ath5k_hw_reg_write(ah, AR5K_PHY_CCKTXCTL_WORLD,
+                               AR5K_PHY_CCKTXCTL);
+               if (channel->hw_value & CHANNEL_5GHZ)
+                       data = 0xffb81020;
+               else
+                       data = 0xffb80d20;
+               ath5k_hw_reg_write(ah, data, AR5K_PHY_FRAME_CTL);
+       }
+
+       if (ah->ah_mac_srev < AR5K_SREV_AR5211) {
+               u32 usec_reg;
+               /* 5311 has different tx/rx latency masks
+                * from 5211, since we deal 5311 the same
+                * as 5211 when setting initvals, shift
+                * values here to their proper locations */
+               usec_reg = ath5k_hw_reg_read(ah, AR5K_USEC_5211);
+               ath5k_hw_reg_write(ah, usec_reg & (AR5K_USEC_1 |
+                               AR5K_USEC_32 |
+                               AR5K_USEC_TX_LATENCY_5211 |
+                               AR5K_REG_SM(29,
+                               AR5K_USEC_RX_LATENCY_5210)),
+                               AR5K_USEC_5211);
+               /* Clear QCU/DCU clock gating register */
+               ath5k_hw_reg_write(ah, 0, AR5K_QCUDCU_CLKGT);
+               /* Set DAC/ADC delays */
+               ath5k_hw_reg_write(ah, 0x08, AR5K_PHY_SCAL);
+               /* Enable PCU FIFO corruption ECO */
+               AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW_5211,
+                                       AR5K_DIAG_SW_ECO_ENABLE);
+       }
+}
+
+static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah,
+               struct ieee80211_channel *channel, u8 *ant, u8 ee_mode)
+{
+       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+       s16 cck_ofdm_pwr_delta;
+
+       /* Adjust power delta for channel 14 */
+       if (channel->center_freq == 2484)
+               cck_ofdm_pwr_delta =
+                       ((ee->ee_cck_ofdm_power_delta -
+                       ee->ee_scaled_cck_delta) * 2) / 10;
+       else
+               cck_ofdm_pwr_delta =
+                       (ee->ee_cck_ofdm_power_delta * 2) / 10;
+
+       /* 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)
+                       ath5k_hw_reg_write(ah,
+                       AR5K_REG_SM((ee->ee_cck_ofdm_gain_delta * -1),
+                               AR5K_PHY_TX_PWR_ADJ_CCK_GAIN_DELTA) |
+                       AR5K_REG_SM((cck_ofdm_pwr_delta * -1),
+                               AR5K_PHY_TX_PWR_ADJ_CCK_PCDAC_INDEX),
+                               AR5K_PHY_TX_PWR_ADJ);
+               else
+                       ath5k_hw_reg_write(ah, 0, AR5K_PHY_TX_PWR_ADJ);
+       } else {
+               /* For older revs we scale power on sw during tx power
+                * setup */
+               ah->ah_txpower.txp_cck_ofdm_pwr_delta = cck_ofdm_pwr_delta;
+               ah->ah_txpower.txp_cck_ofdm_gainf_delta =
+                                               ee->ee_cck_ofdm_gain_delta;
+       }
+
+       /* Set antenna idle switch table */
+       AR5K_REG_WRITE_BITS(ah, AR5K_PHY_ANT_CTL,
+                       AR5K_PHY_ANT_CTL_SWTABLE_IDLE,
+                       (ah->ah_ant_ctl[ee_mode][0] |
+                       AR5K_PHY_ANT_CTL_TXRX_EN));
+
+       /* Set antenna switch tables */
+       ath5k_hw_reg_write(ah, ah->ah_ant_ctl[ee_mode][ant[0]],
+               AR5K_PHY_ANT_SWITCH_TABLE_0);
+       ath5k_hw_reg_write(ah, ah->ah_ant_ctl[ee_mode][ant[1]],
+               AR5K_PHY_ANT_SWITCH_TABLE_1);
+
+       /* Noise floor threshold */
+       ath5k_hw_reg_write(ah,
+               AR5K_PHY_NF_SVAL(ee->ee_noise_floor_thr[ee_mode]),
+               AR5K_PHY_NFTHRES);
+
+       if ((channel->hw_value & CHANNEL_TURBO) &&
+       (ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_0)) {
+               /* Switch settling time (Turbo) */
+               AR5K_REG_WRITE_BITS(ah, AR5K_PHY_SETTLING,
+                               AR5K_PHY_SETTLING_SWITCH,
+                               ee->ee_switch_settling_turbo[ee_mode]);
+
+               /* Tx/Rx attenuation (Turbo) */
+               AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN,
+                               AR5K_PHY_GAIN_TXRX_ATTEN,
+                               ee->ee_atn_tx_rx_turbo[ee_mode]);
+
+               /* ADC/PGA desired size (Turbo) */
+               AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DESIRED_SIZE,
+                               AR5K_PHY_DESIRED_SIZE_ADC,
+                               ee->ee_adc_desired_size_turbo[ee_mode]);
+
+               AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DESIRED_SIZE,
+                               AR5K_PHY_DESIRED_SIZE_PGA,
+                               ee->ee_pga_desired_size_turbo[ee_mode]);
+
+               /* Tx/Rx margin (Turbo) */
+               AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN_2GHZ,
+                               AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX,
+                               ee->ee_margin_tx_rx_turbo[ee_mode]);
+
+       } else {
+               /* Switch settling time */
+               AR5K_REG_WRITE_BITS(ah, AR5K_PHY_SETTLING,
+                               AR5K_PHY_SETTLING_SWITCH,
+                               ee->ee_switch_settling[ee_mode]);
+
+               /* Tx/Rx attenuation */
+               AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN,
+                               AR5K_PHY_GAIN_TXRX_ATTEN,
+                               ee->ee_atn_tx_rx[ee_mode]);
+
+               /* ADC/PGA desired size */
+               AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DESIRED_SIZE,
+                               AR5K_PHY_DESIRED_SIZE_ADC,
+                               ee->ee_adc_desired_size[ee_mode]);
+
+               AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DESIRED_SIZE,
+                               AR5K_PHY_DESIRED_SIZE_PGA,
+                               ee->ee_pga_desired_size[ee_mode]);
+
+               /* Tx/Rx margin */
+               if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1)
+                       AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN_2GHZ,
+                               AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX,
+                               ee->ee_margin_tx_rx[ee_mode]);
+       }
+
+       /* XPA delays */
+       ath5k_hw_reg_write(ah,
+               (ee->ee_tx_end2xpa_disable[ee_mode] << 24) |
+               (ee->ee_tx_end2xpa_disable[ee_mode] << 16) |
+               (ee->ee_tx_frm2xpa_enable[ee_mode] << 8) |
+               (ee->ee_tx_frm2xpa_enable[ee_mode]), AR5K_PHY_RF_CTL4);
+
+       /* XLNA delay */
+       AR5K_REG_WRITE_BITS(ah, AR5K_PHY_RF_CTL3,
+                       AR5K_PHY_RF_CTL3_TXE2XLNA_ON,
+                       ee->ee_tx_end2xlna_enable[ee_mode]);
+
+       /* Thresh64 (ANI) */
+       AR5K_REG_WRITE_BITS(ah, AR5K_PHY_NF,
+                       AR5K_PHY_NF_THRESH62,
+                       ee->ee_thr_62[ee_mode]);
+
+
+       /* False detect backoff for channels
+        * that have spur noise. Write the new
+        * cyclic power RSSI threshold. */
+       if (ath5k_hw_chan_has_spur_noise(ah, channel))
+               AR5K_REG_WRITE_BITS(ah, AR5K_PHY_OFDM_SELFCORR,
+                               AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1,
+                               AR5K_INIT_CYCRSSI_THR1 +
+                               ee->ee_false_detect[ee_mode]);
+       else
+               AR5K_REG_WRITE_BITS(ah, AR5K_PHY_OFDM_SELFCORR,
+                               AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1,
+                               AR5K_INIT_CYCRSSI_THR1);
+
+       /* I/Q correction
+        * TODO: Per channel i/q infos ? */
+       AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ,
+               AR5K_PHY_IQ_CORR_ENABLE |
+               (ee->ee_i_cal[ee_mode] << AR5K_PHY_IQ_CORR_Q_I_COFF_S) |
+               ee->ee_q_cal[ee_mode]);
+
+       /* Heavy clipping -disable for now */
+       if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_1)
+               ath5k_hw_reg_write(ah, 0, AR5K_PHY_HEAVY_CLIP_ENABLE);
+
+       return;
+}
+
+/*
+ * Main reset function
+ */
+int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
+       struct ieee80211_channel *channel, bool change_channel)
+{
+       u32 s_seq[10], s_ant, s_led[3], staid1_flags, tsf_up, tsf_lo;
+       u32 phy_tst1;
+       u8 mode, freq, ee_mode, ant[2];
+       int i, ret;
+
+       ATH5K_TRACE(ah->ah_sc);
+
+       s_ant = 0;
+       ee_mode = 0;
+       staid1_flags = 0;
+       tsf_up = 0;
+       tsf_lo = 0;
+       freq = 0;
+       mode = 0;
+
+       /*
+        * Save some registers before a reset
+        */
+       /*DCU/Antenna selection not available on 5210*/
+       if (ah->ah_version != AR5K_AR5210) {
+
+               switch (channel->hw_value & CHANNEL_MODES) {
+               case CHANNEL_A:
+                       mode = AR5K_MODE_11A;
+                       freq = AR5K_INI_RFGAIN_5GHZ;
+                       ee_mode = AR5K_EEPROM_MODE_11A;
+                       break;
+               case CHANNEL_G:
+                       mode = AR5K_MODE_11G;
+                       freq = AR5K_INI_RFGAIN_2GHZ;
+                       ee_mode = AR5K_EEPROM_MODE_11G;
+                       break;
+               case CHANNEL_B:
+                       mode = AR5K_MODE_11B;
+                       freq = AR5K_INI_RFGAIN_2GHZ;
+                       ee_mode = AR5K_EEPROM_MODE_11B;
+                       break;
+               case CHANNEL_T:
+                       mode = AR5K_MODE_11A_TURBO;
+                       freq = AR5K_INI_RFGAIN_5GHZ;
+                       ee_mode = AR5K_EEPROM_MODE_11A;
+                       break;
+               case CHANNEL_TG:
+                       if (ah->ah_version == AR5K_AR5211) {
+                               ATH5K_ERR(ah->ah_sc,
+                                       "TurboG mode not available on 5211");
+                               return -EINVAL;
+                       }
+                       mode = AR5K_MODE_11G_TURBO;
+                       freq = AR5K_INI_RFGAIN_2GHZ;
+                       ee_mode = AR5K_EEPROM_MODE_11G;
+                       break;
+               case CHANNEL_XR:
+                       if (ah->ah_version == AR5K_AR5211) {
+                               ATH5K_ERR(ah->ah_sc,
+                                       "XR mode not available on 5211");
+                               return -EINVAL;
+                       }
+                       mode = AR5K_MODE_XR;
+                       freq = AR5K_INI_RFGAIN_5GHZ;
+                       ee_mode = AR5K_EEPROM_MODE_11A;
+                       break;
+               default:
+                       ATH5K_ERR(ah->ah_sc,
+                               "invalid channel: %d\n", channel->center_freq);
+                       return -EINVAL;
+               }
+
+               if (change_channel) {
+                       /*
+                        * Save frame sequence count
+                        * For revs. after Oahu, only save
+                        * seq num for DCU 0 (Global seq num)
+                        */
+                       if (ah->ah_mac_srev < AR5K_SREV_AR5211) {
+
+                               for (i = 0; i < 10; i++)
+                                       s_seq[i] = ath5k_hw_reg_read(ah,
+                                               AR5K_QUEUE_DCU_SEQNUM(i));
+
+                       } else {
+                               s_seq[0] = ath5k_hw_reg_read(ah,
+                                               AR5K_QUEUE_DCU_SEQNUM(0));
+                       }
+
+                       /* TSF accelerates on AR5211 durring reset
+                        * As a workaround save it here and restore
+                        * it later so that it's back in time after
+                        * reset. This way it'll get re-synced on the
+                        * next beacon without breaking ad-hoc.
+                        *
+                        * On AR5212 TSF is almost preserved across a
+                        * reset so it stays back in time anyway and
+                        * we don't have to save/restore it.
+                        *
+                        * XXX: Since this breaks power saving we have
+                        * to disable power saving until we receive the
+                        * next beacon, so we can resync beacon timers */
+                       if (ah->ah_version == AR5K_AR5211) {
+                               tsf_up = ath5k_hw_reg_read(ah, AR5K_TSF_U32);
+                               tsf_lo = ath5k_hw_reg_read(ah, AR5K_TSF_L32);
+                       }
+               }
+
+               /* Save default antenna */
+               s_ant = ath5k_hw_reg_read(ah, AR5K_DEFAULT_ANTENNA);
+
+               if (ah->ah_version == AR5K_AR5212) {
+                       /* Restore normal 32/40MHz clock operation
+                        * to avoid register access delay on certain
+                        * PHY registers */
+                       ath5k_hw_set_sleep_clock(ah, false);
+
+                       /* Since we are going to write rf buffer
+                        * check if we have any pending gain_F
+                        * optimization settings */
+                       if (change_channel && ah->ah_rf_banks != NULL)
+                               ath5k_hw_gainf_calibrate(ah);
+               }
+       }
+
+       /*GPIOs*/
+       s_led[0] = ath5k_hw_reg_read(ah, AR5K_PCICFG) &
+                                       AR5K_PCICFG_LEDSTATE;
+       s_led[1] = ath5k_hw_reg_read(ah, AR5K_GPIOCR);
+       s_led[2] = ath5k_hw_reg_read(ah, AR5K_GPIODO);
+
+       /* AR5K_STA_ID1 flags, only preserve antenna
+        * settings and ack/cts rate mode */
+       staid1_flags = ath5k_hw_reg_read(ah, AR5K_STA_ID1) &
+                       (AR5K_STA_ID1_DEFAULT_ANTENNA |
+                       AR5K_STA_ID1_DESC_ANTENNA |
+                       AR5K_STA_ID1_RTS_DEF_ANTENNA |
+                       AR5K_STA_ID1_ACKCTS_6MB |
+                       AR5K_STA_ID1_BASE_RATE_11B |
+                       AR5K_STA_ID1_SELFGEN_DEF_ANT);
+
+       /* Wakeup the device */
+       ret = ath5k_hw_nic_wakeup(ah, channel->hw_value, false);
+       if (ret)
+               return ret;
+
+       /*
+        * Initialize operating mode
+        */
+       ah->ah_op_mode = op_mode;
+
+       /* PHY access enable */
+       if (ah->ah_mac_srev >= AR5K_SREV_AR5211)
+               ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0));
+       else
+               ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ | 0x40,
+                                                       AR5K_PHY(0));
+
+       /* Write initial settings */
+       ret = ath5k_hw_write_initvals(ah, mode, change_channel);
+       if (ret)
+               return ret;
+
+       /*
+        * 5211/5212 Specific
+        */
+       if (ah->ah_version != AR5K_AR5210) {
+
+               /*
+                * Write initial RF gain settings
+                * This should work for both 5111/5112
+                */
+               ret = ath5k_hw_rfgain_init(ah, freq);
+               if (ret)
+                       return ret;
+
+               mdelay(1);
+
+               /*
+                * Tweak initval settings for revised
+                * chipsets and add some more config
+                * bits
+                */
+               ath5k_hw_tweak_initval_settings(ah, channel);
+
+               /*
+                * Set TX power
+                */
+               ret = ath5k_hw_txpower(ah, channel, ee_mode,
+                                       ah->ah_txpower.txp_max_pwr / 2);
+               if (ret)
+                       return ret;
+
+               /* Write rate duration table only on AR5212 and if
+                * virtual interface has already been brought up
+                * XXX: rethink this after new mode changes to
+                * mac80211 are integrated */
+               if (ah->ah_version == AR5K_AR5212 &&
+                       ah->ah_sc->vif != NULL)
+                       ath5k_hw_write_rate_duration(ah, mode);
+
+               /*
+                * Write RF buffer
+                */
+               ret = ath5k_hw_rfregs_init(ah, channel, mode);
+               if (ret)
+                       return ret;
+
+
+               /* Write OFDM timings on 5212*/
+               if (ah->ah_version == AR5K_AR5212 &&
+                       channel->hw_value & CHANNEL_OFDM) {
+                       struct ath5k_eeprom_info *ee =
+                                       &ah->ah_capabilities.cap_eeprom;
+
+                       ret = ath5k_hw_write_ofdm_timings(ah, channel);
+                       if (ret)
+                               return ret;
+
+                       /* Note: According to docs we can have a newer
+                        * EEPROM on old hardware, so we need to verify
+                        * that our hardware is new enough to have spur
+                        * mitigation registers (delta phase etc) */
+                       if (ah->ah_mac_srev >= AR5K_SREV_AR5424 ||
+                       (ah->ah_mac_srev >= AR5K_SREV_AR5424 &&
+                       ee->ee_version >= AR5K_EEPROM_VERSION_5_3))
+                               ath5k_hw_set_spur_mitigation_filter(ah,
+                                                               channel);
+               }
+
+               /*Enable/disable 802.11b mode on 5111
+               (enable 2111 frequency converter + CCK)*/
+               if (ah->ah_radio == AR5K_RF5111) {
+                       if (mode == AR5K_MODE_11B)
+                               AR5K_REG_ENABLE_BITS(ah, AR5K_TXCFG,
+                                   AR5K_TXCFG_B_MODE);
+                       else
+                               AR5K_REG_DISABLE_BITS(ah, AR5K_TXCFG,
+                                   AR5K_TXCFG_B_MODE);
+               }
+
+               /*
+                * In case a fixed antenna was set as default
+                * use the same switch table twice.
+                */
+               if (ah->ah_ant_mode == AR5K_ANTMODE_FIXED_A)
+                               ant[0] = ant[1] = AR5K_ANT_SWTABLE_A;
+               else if (ah->ah_ant_mode == AR5K_ANTMODE_FIXED_B)
+                               ant[0] = ant[1] = AR5K_ANT_SWTABLE_B;
+               else {
+                       ant[0] = AR5K_ANT_SWTABLE_A;
+                       ant[1] = AR5K_ANT_SWTABLE_B;
+               }
+
+               /* Commit values from EEPROM */
+               ath5k_hw_commit_eeprom_settings(ah, channel, ant, ee_mode);
+
+       } else {
+               /*
+                * For 5210 we do all initialization using
+                * initvals, so we don't have to modify
+                * any settings (5210 also only supports
+                * a/aturbo modes)
+                */
+               mdelay(1);
+               /* Disable phy and wait */
+               ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT);
+               mdelay(1);
+       }
+
+       /*
+        * Restore saved values
+        */
+
+       /*DCU/Antenna selection not available on 5210*/
+       if (ah->ah_version != AR5K_AR5210) {
+
+               if (change_channel) {
+                       if (ah->ah_mac_srev < AR5K_SREV_AR5211) {
+                               for (i = 0; i < 10; i++)
+                                       ath5k_hw_reg_write(ah, s_seq[i],
+                                               AR5K_QUEUE_DCU_SEQNUM(i));
+                       } else {
+                               ath5k_hw_reg_write(ah, s_seq[0],
+                                       AR5K_QUEUE_DCU_SEQNUM(0));
+                       }
+
+
+                       if (ah->ah_version == AR5K_AR5211) {
+                               ath5k_hw_reg_write(ah, tsf_up, AR5K_TSF_U32);
+                               ath5k_hw_reg_write(ah, tsf_lo, AR5K_TSF_L32);
+                       }
+               }
+
+               ath5k_hw_reg_write(ah, s_ant, AR5K_DEFAULT_ANTENNA);
+       }
+
+       /* Ledstate */
+       AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, s_led[0]);
+
+       /* Gpio settings */
+       ath5k_hw_reg_write(ah, s_led[1], AR5K_GPIOCR);
+       ath5k_hw_reg_write(ah, s_led[2], AR5K_GPIODO);
+
+       /* Restore sta_id flags and preserve our mac address*/
+       ath5k_hw_reg_write(ah, AR5K_LOW_ID(ah->ah_sta_id),
+                                               AR5K_STA_ID0);
+       ath5k_hw_reg_write(ah, staid1_flags | AR5K_HIGH_ID(ah->ah_sta_id),
+                                               AR5K_STA_ID1);
+
+
+       /*
+        * Configure PCU
+        */
+
+       /* Restore bssid and bssid mask */
+       /* XXX: add ah->aid once mac80211 gives this to us */
+       ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
+
+       /* Set PCU config */
+       ath5k_hw_set_opmode(ah);
+
+       /* Clear any pending interrupts
+        * PISR/SISR Not available on 5210 */
+       if (ah->ah_version != AR5K_AR5210)
+               ath5k_hw_reg_write(ah, 0xffffffff, AR5K_PISR);
+
+       /* Set RSSI/BRSSI thresholds
+        *
+        * Note: If we decide to set this value
+        * dynamicaly, have in mind that when AR5K_RSSI_THR
+        * register is read it might return 0x40 if we haven't
+        * wrote anything to it plus BMISS RSSI threshold is zeroed.
+        * So doing a save/restore procedure here isn't the right
+        * choice. Instead store it on ath5k_hw */
+       ath5k_hw_reg_write(ah, (AR5K_TUNE_RSSI_THRES |
+                               AR5K_TUNE_BMISS_THRES <<
+                               AR5K_RSSI_THR_BMISS_S),
+                               AR5K_RSSI_THR);
+
+       /* MIC QoS support */
+       if (ah->ah_mac_srev >= AR5K_SREV_AR2413) {
+               ath5k_hw_reg_write(ah, 0x000100aa, AR5K_MIC_QOS_CTL);
+               ath5k_hw_reg_write(ah, 0x00003210, AR5K_MIC_QOS_SEL);
+       }
+
+       /* QoS NOACK Policy */
+       if (ah->ah_version == AR5K_AR5212) {
+               ath5k_hw_reg_write(ah,
+                       AR5K_REG_SM(2, AR5K_QOS_NOACK_2BIT_VALUES) |
+                       AR5K_REG_SM(5, AR5K_QOS_NOACK_BIT_OFFSET)  |
+                       AR5K_REG_SM(0, AR5K_QOS_NOACK_BYTE_OFFSET),
+                       AR5K_QOS_NOACK);
+       }
+
+
+       /*
+        * Configure PHY
+        */
+
+       /* Set channel on PHY */
+       ret = ath5k_hw_channel(ah, channel);
+       if (ret)
+               return ret;
+
+       /*
+        * Enable the PHY and wait until completion
+        * This includes BaseBand and Synthesizer
+        * activation.
+        */
+       ath5k_hw_reg_write(ah, AR5K_PHY_ACT_ENABLE, AR5K_PHY_ACT);
+
+       /*
+        * On 5211+ read activation -> rx delay
+        * and use it.
+        *
+        * TODO: Half/quarter rate support
+        */
+       if (ah->ah_version != AR5K_AR5210) {
+               u32 delay;
+               delay = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) &
+                       AR5K_PHY_RX_DELAY_M;
+               delay = (channel->hw_value & CHANNEL_CCK) ?
+                       ((delay << 2) / 22) : (delay / 10);
+
+               udelay(100 + (2 * delay));
+       } else {
+               mdelay(1);
+       }
+
+       /*
+        * Perform ADC test to see if baseband is ready
+        * Set tx hold and check adc test register
+        */
+       phy_tst1 = ath5k_hw_reg_read(ah, AR5K_PHY_TST1);
+       ath5k_hw_reg_write(ah, AR5K_PHY_TST1_TXHOLD, AR5K_PHY_TST1);
+       for (i = 0; i <= 20; i++) {
+               if (!(ath5k_hw_reg_read(ah, AR5K_PHY_ADC_TEST) & 0x10))
+                       break;
+               udelay(200);
+       }
+       ath5k_hw_reg_write(ah, phy_tst1, AR5K_PHY_TST1);
+
+       /*
+        * Start automatic gain control calibration
+        *
+        * During AGC calibration RX path is re-routed to
+        * a power detector so we don't receive anything.
+        *
+        * This method is used to calibrate some static offsets
+        * used together with on-the fly I/Q calibration (the
+        * one performed via ath5k_hw_phy_calibrate), that doesn't
+        * interrupt rx path.
+        *
+        * While rx path is re-routed to the power detector we also
+        * start a noise floor calibration, to measure the
+        * card's noise floor (the noise we measure when we are not
+        * transmiting or receiving anything).
+        *
+        * If we are in a noisy environment AGC calibration may time
+        * out and/or noise floor calibration might timeout.
+        */
+       AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
+                               AR5K_PHY_AGCCTL_CAL);
+
+       /* At the same time start I/Q calibration for QAM constellation
+        * -no need for CCK- */
+       ah->ah_calibration = false;
+       if (!(mode == AR5K_MODE_11B)) {
+               ah->ah_calibration = true;
+               AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ,
+                               AR5K_PHY_IQ_CAL_NUM_LOG_MAX, 15);
+               AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ,
+                               AR5K_PHY_IQ_RUN);
+       }
+
+       /* Wait for gain calibration to finish (we check for I/Q calibration
+        * during ath5k_phy_calibrate) */
+       if (ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL,
+                       AR5K_PHY_AGCCTL_CAL, 0, false)) {
+               ATH5K_ERR(ah->ah_sc, "gain calibration timeout (%uMHz)\n",
+                       channel->center_freq);
+       }
+
+       /*
+        * If we run NF calibration before AGC, it always times out.
+        * Binary HAL starts NF and AGC calibration at the same time
+        * and only waits for AGC to finish. Also if AGC or NF cal.
+        * times out, reset doesn't fail on binary HAL. I believe
+        * that's wrong because since rx path is routed to a detector,
+        * if cal. doesn't finish we won't have RX. Sam's HAL for AR5210/5211
+        * enables noise floor calibration after offset calibration and if noise
+        * floor calibration fails, reset fails. I believe that's
+        * a better approach, we just need to find a polling interval
+        * that suits best, even if reset continues we need to make
+        * sure that rx path is ready.
+        */
+       ath5k_hw_noise_floor_calibration(ah, channel->center_freq);
+
+       /* Restore antenna mode */
+       ath5k_hw_set_antenna_mode(ah, ah->ah_ant_mode);
+
+       /*
+        * Configure QCUs/DCUs
+        */
+
+       /* TODO: HW Compression support for data queues */
+       /* TODO: Burst prefetch for data queues */
+
+       /*
+        * Reset queues and start beacon timers at the end of the reset routine
+        * This also sets QCU mask on each DCU for 1:1 qcu to dcu mapping
+        * Note: If we want we can assign multiple qcus on one dcu.
+        */
+       for (i = 0; i < ah->ah_capabilities.cap_queues.q_tx_num; i++) {
+               ret = ath5k_hw_reset_tx_queue(ah, i);
+               if (ret) {
+                       ATH5K_ERR(ah->ah_sc,
+                               "failed to reset TX queue #%d\n", i);
+                       return ret;
+               }
+       }
+
+
+       /*
+        * Configure DMA/Interrupts
+        */
+
+       /*
+        * Set Rx/Tx DMA Configuration
+        *
+        * Set standard DMA size (128). Note that
+        * a DMA size of 512 causes rx overruns and tx errors
+        * on pci-e cards (tested on 5424 but since rx overruns
+        * also occur on 5416/5418 with madwifi we set 128
+        * for all PCI-E cards to be safe).
+        *
+        * XXX: need to check 5210 for this
+        * TODO: Check out tx triger level, it's always 64 on dumps but I
+        * guess we can tweak it and see how it goes ;-)
+        */
+       if (ah->ah_version != AR5K_AR5210) {
+               AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG,
+                       AR5K_TXCFG_SDMAMR, AR5K_DMASIZE_128B);
+               AR5K_REG_WRITE_BITS(ah, AR5K_RXCFG,
+                       AR5K_RXCFG_SDMAMW, AR5K_DMASIZE_128B);
+       }
+
+       /* Pre-enable interrupts on 5211/5212*/
+       if (ah->ah_version != AR5K_AR5210)
+               ath5k_hw_set_imr(ah, ah->ah_imr);
+
+       /* Enable 32KHz clock function for AR5212+ chips
+        * Set clocks to 32KHz operation and use an
+        * external 32KHz crystal when sleeping if one
+        * exists */
+       if (ah->ah_version == AR5K_AR5212)
+                       ath5k_hw_set_sleep_clock(ah, true);
+
+       /*
+        * Disable beacons and reset the register
+        */
+       AR5K_REG_DISABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE |
+                       AR5K_BEACON_RESET_TSF);
+
+       return 0;
+}
+
+#undef _ATH5K_RESET
diff --git a/drivers/net/wireless/ath/ath5k/rfbuffer.h b/drivers/net/wireless/ath/ath5k/rfbuffer.h
new file mode 100644 (file)
index 0000000..e50baff
--- /dev/null
@@ -0,0 +1,1181 @@
+/*
+ * RF Buffer handling functions
+ *
+ * Copyright (c) 2009 Nick Kossifidis <mickflemm@gmail.com>
+ *
+ * Permission to use, copy, modify, and 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.
+ *
+ */
+
+
+/*
+ * There are some special registers on the RF chip
+ * that control various operation settings related mostly to
+ * the analog parts (channel, gain adjustment etc).
+ *
+ * We don't write on those registers directly but
+ * we send a data packet on the chip, using a special register,
+ * that holds all the settings we need. After we 've sent the
+ * data packet, we write on another special register to notify hw
+ * to apply the settings. This is done so that control registers
+ * can be dynamicaly programmed during operation and the settings
+ * are applied faster on the hw.
+ *
+ * We call each data packet an "RF Bank" and all the data we write
+ * (all RF Banks) "RF Buffer". This file holds initial RF Buffer
+ * data for the different RF chips, and various info to match RF
+ * Buffer offsets with specific RF registers so that we can access
+ * them. We tweak these settings on rfregs_init function.
+ *
+ * Also check out reg.h and U.S. Patent 6677779 B1 (about buffer
+ * registers and control registers):
+ *
+ * http://www.google.com/patents?id=qNURAAAAEBAJ
+ */
+
+
+/*
+ * Struct to hold default mode specific RF
+ * register values (RF Banks)
+ */
+struct ath5k_ini_rfbuffer {
+       u8      rfb_bank;               /* RF Bank number */
+       u16     rfb_ctrl_register;      /* RF Buffer control register */
+       u32     rfb_mode_data[5];       /* RF Buffer data for each mode */
+};
+
+/*
+ * Struct to hold RF Buffer field
+ * infos used to access certain RF
+ * analog registers
+ */
+struct ath5k_rfb_field {
+       u8      len;    /* Field length */
+       u16     pos;    /* Offset on the raw packet */
+       u8      col;    /* Column -used for shifting */
+};
+
+/*
+ * RF analog register definition
+ */
+struct ath5k_rf_reg {
+       u8                      bank;   /* RF Buffer Bank number */
+       u8                      index;  /* Register's index on rf_regs_idx */
+       struct ath5k_rfb_field  field;  /* RF Buffer field for this register */
+};
+
+/* Map RF registers to indexes
+ * We do this to handle common bits and make our
+ * life easier by using an index for each register
+ * instead of a full rfb_field */
+enum ath5k_rf_regs_idx {
+       /* BANK 6 */
+       AR5K_RF_OB_2GHZ = 0,
+       AR5K_RF_OB_5GHZ,
+       AR5K_RF_DB_2GHZ,
+       AR5K_RF_DB_5GHZ,
+       AR5K_RF_FIXED_BIAS_A,
+       AR5K_RF_FIXED_BIAS_B,
+       AR5K_RF_PWD_XPD,
+       AR5K_RF_XPD_SEL,
+       AR5K_RF_XPD_GAIN,
+       AR5K_RF_PD_GAIN_LO,
+       AR5K_RF_PD_GAIN_HI,
+       AR5K_RF_HIGH_VC_CP,
+       AR5K_RF_MID_VC_CP,
+       AR5K_RF_LOW_VC_CP,
+       AR5K_RF_PUSH_UP,
+       AR5K_RF_PAD2GND,
+       AR5K_RF_XB2_LVL,
+       AR5K_RF_XB5_LVL,
+       AR5K_RF_PWD_ICLOBUF_2G,
+       AR5K_RF_PWD_84,
+       AR5K_RF_PWD_90,
+       AR5K_RF_PWD_130,
+       AR5K_RF_PWD_131,
+       AR5K_RF_PWD_132,
+       AR5K_RF_PWD_136,
+       AR5K_RF_PWD_137,
+       AR5K_RF_PWD_138,
+       AR5K_RF_PWD_166,
+       AR5K_RF_PWD_167,
+       AR5K_RF_DERBY_CHAN_SEL_MODE,
+       /* BANK 7 */
+       AR5K_RF_GAIN_I,
+       AR5K_RF_PLO_SEL,
+       AR5K_RF_RFGAIN_SEL,
+       AR5K_RF_RFGAIN_STEP,
+       AR5K_RF_WAIT_S,
+       AR5K_RF_WAIT_I,
+       AR5K_RF_MAX_TIME,
+       AR5K_RF_MIXVGA_OVR,
+       AR5K_RF_MIXGAIN_OVR,
+       AR5K_RF_MIXGAIN_STEP,
+       AR5K_RF_PD_DELAY_A,
+       AR5K_RF_PD_DELAY_B,
+       AR5K_RF_PD_DELAY_XR,
+       AR5K_RF_PD_PERIOD_A,
+       AR5K_RF_PD_PERIOD_B,
+       AR5K_RF_PD_PERIOD_XR,
+};
+
+
+/*******************\
+* RF5111 (Sombrero) *
+\*******************/
+
+/* BANK 6                              len  pos col */
+#define        AR5K_RF5111_OB_2GHZ             { 3, 119, 0 }
+#define        AR5K_RF5111_DB_2GHZ             { 3, 122, 0 }
+
+#define        AR5K_RF5111_OB_5GHZ             { 3, 104, 0 }
+#define        AR5K_RF5111_DB_5GHZ             { 3, 107, 0 }
+
+#define        AR5K_RF5111_PWD_XPD             { 1, 95,  0 }
+#define        AR5K_RF5111_XPD_GAIN            { 4, 96,  0 }
+
+/* Access to PWD registers */
+#define AR5K_RF5111_PWD(_n)            { 1, (135 - _n), 3 }
+
+/* BANK 7                              len  pos col */
+#define        AR5K_RF5111_GAIN_I              { 6, 29,  0 }
+#define        AR5K_RF5111_PLO_SEL             { 1, 4,   0 }
+#define        AR5K_RF5111_RFGAIN_SEL          { 1, 36,  0 }
+#define AR5K_RF5111_RFGAIN_STEP                { 6, 37,  0 }
+/* Only on AR5212 BaseBand and up */
+#define        AR5K_RF5111_WAIT_S              { 5, 19,  0 }
+#define        AR5K_RF5111_WAIT_I              { 5, 24,  0 }
+#define        AR5K_RF5111_MAX_TIME            { 2, 49,  0 }
+
+static const struct ath5k_rf_reg rf_regs_5111[] = {
+       {6, AR5K_RF_OB_2GHZ,            AR5K_RF5111_OB_2GHZ},
+       {6, AR5K_RF_DB_2GHZ,            AR5K_RF5111_DB_2GHZ},
+       {6, AR5K_RF_OB_5GHZ,            AR5K_RF5111_OB_5GHZ},
+       {6, AR5K_RF_DB_5GHZ,            AR5K_RF5111_DB_5GHZ},
+       {6, AR5K_RF_PWD_XPD,            AR5K_RF5111_PWD_XPD},
+       {6, AR5K_RF_XPD_GAIN,           AR5K_RF5111_XPD_GAIN},
+       {6, AR5K_RF_PWD_84,             AR5K_RF5111_PWD(84)},
+       {6, AR5K_RF_PWD_90,             AR5K_RF5111_PWD(90)},
+       {7, AR5K_RF_GAIN_I,             AR5K_RF5111_GAIN_I},
+       {7, AR5K_RF_PLO_SEL,            AR5K_RF5111_PLO_SEL},
+       {7, AR5K_RF_RFGAIN_SEL,         AR5K_RF5111_RFGAIN_SEL},
+       {7, AR5K_RF_RFGAIN_STEP,        AR5K_RF5111_RFGAIN_STEP},
+       {7, AR5K_RF_WAIT_S,             AR5K_RF5111_WAIT_S},
+       {7, AR5K_RF_WAIT_I,             AR5K_RF5111_WAIT_I},
+       {7, AR5K_RF_MAX_TIME,           AR5K_RF5111_MAX_TIME}
+};
+
+/* Default mode specific settings */
+static const struct ath5k_ini_rfbuffer rfb_5111[] = {
+       { 0, 0x989c,
+       /*     mode a/XR  mode aTurbo    mode b     mode g    mode gTurbo */
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 0, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 0, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 0, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 0, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 0, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 0, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 0, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 0, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 0, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 0, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 0, 0x989c,
+           { 0x00380000, 0x00380000, 0x00380000, 0x00380000, 0x00380000 } },
+       { 0, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 0, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 0, 0x989c,
+           { 0x00000000, 0x00000000, 0x000000c0, 0x00000080, 0x00000080 } },
+       { 0, 0x989c,
+           { 0x000400f9, 0x000400f9, 0x000400ff, 0x000400fd, 0x000400fd } },
+       { 0, 0x98d4,
+           { 0x00000000, 0x00000000, 0x00000004, 0x00000004, 0x00000004 } },
+       { 1, 0x98d4,
+           { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
+       { 2, 0x98d4,
+           { 0x00000010, 0x00000014, 0x00000010, 0x00000010, 0x00000014 } },
+       { 3, 0x98d8,
+           { 0x00601068, 0x00601068, 0x00601068, 0x00601068, 0x00601068 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000 } },
+       { 6, 0x989c,
+           { 0x04000000, 0x04000000, 0x04000000, 0x04000000, 0x04000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x0a000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x003800c0, 0x00380080, 0x023800c0, 0x003800c0, 0x003800c0 } },
+       { 6, 0x989c,
+           { 0x00020006, 0x00020006, 0x00000006, 0x00020006, 0x00020006 } },
+       { 6, 0x989c,
+           { 0x00000089, 0x00000089, 0x00000089, 0x00000089, 0x00000089 } },
+       { 6, 0x989c,
+           { 0x000000a0, 0x000000a0, 0x000000a0, 0x000000a0, 0x000000a0 } },
+       { 6, 0x989c,
+           { 0x00040007, 0x00040007, 0x00040007, 0x00040007, 0x00040007 } },
+       { 6, 0x98d4,
+           { 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a } },
+       { 7, 0x989c,
+           { 0x00000040, 0x00000048, 0x00000040, 0x00000040, 0x00000040 } },
+       { 7, 0x989c,
+           { 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010 } },
+       { 7, 0x989c,
+           { 0x00000008, 0x00000008, 0x00000008, 0x00000008, 0x00000008 } },
+       { 7, 0x989c,
+           { 0x0000004f, 0x0000004f, 0x0000004f, 0x0000004f, 0x0000004f } },
+       { 7, 0x989c,
+           { 0x000000f1, 0x000000f1, 0x00000061, 0x000000f1, 0x000000f1 } },
+       { 7, 0x989c,
+           { 0x0000904f, 0x0000904f, 0x0000904c, 0x0000904f, 0x0000904f } },
+       { 7, 0x989c,
+           { 0x0000125a, 0x0000125a, 0x0000129a, 0x0000125a, 0x0000125a } },
+       { 7, 0x98cc,
+           { 0x0000000e, 0x0000000e, 0x0000000f, 0x0000000e, 0x0000000e } },
+};
+
+
+
+/***********************\
+* RF5112/RF2112 (Derby) *
+\***********************/
+
+/* BANK 7 (Common)                     len  pos col */
+#define        AR5K_RF5112X_GAIN_I             { 6, 14,  0 }
+#define        AR5K_RF5112X_MIXVGA_OVR         { 1, 36,  0 }
+#define        AR5K_RF5112X_MIXGAIN_OVR        { 2, 37,  0 }
+#define AR5K_RF5112X_MIXGAIN_STEP      { 4, 32,  0 }
+#define        AR5K_RF5112X_PD_DELAY_A         { 4, 58,  0 }
+#define        AR5K_RF5112X_PD_DELAY_B         { 4, 62,  0 }
+#define        AR5K_RF5112X_PD_DELAY_XR        { 4, 66,  0 }
+#define        AR5K_RF5112X_PD_PERIOD_A        { 4, 70,  0 }
+#define        AR5K_RF5112X_PD_PERIOD_B        { 4, 74,  0 }
+#define        AR5K_RF5112X_PD_PERIOD_XR       { 4, 78,  0 }
+
+/* RFX112 (Derby 1) */
+
+/* BANK 6                              len  pos col */
+#define        AR5K_RF5112_OB_2GHZ             { 3, 269, 0 }
+#define        AR5K_RF5112_DB_2GHZ             { 3, 272, 0 }
+
+#define        AR5K_RF5112_OB_5GHZ             { 3, 261, 0 }
+#define        AR5K_RF5112_DB_5GHZ             { 3, 264, 0 }
+
+#define        AR5K_RF5112_FIXED_BIAS_A        { 1, 260, 0 }
+#define        AR5K_RF5112_FIXED_BIAS_B        { 1, 259, 0 }
+
+#define        AR5K_RF5112_XPD_SEL             { 1, 284, 0 }
+#define        AR5K_RF5112_XPD_GAIN            { 2, 252, 0 }
+
+/* Access to PWD registers */
+#define AR5K_RF5112_PWD(_n)            { 1, (302 - _n), 3 }
+
+static const struct ath5k_rf_reg rf_regs_5112[] = {
+       {6, AR5K_RF_OB_2GHZ,            AR5K_RF5112_OB_2GHZ},
+       {6, AR5K_RF_DB_2GHZ,            AR5K_RF5112_DB_2GHZ},
+       {6, AR5K_RF_OB_5GHZ,            AR5K_RF5112_OB_5GHZ},
+       {6, AR5K_RF_DB_5GHZ,            AR5K_RF5112_DB_5GHZ},
+       {6, AR5K_RF_FIXED_BIAS_A,       AR5K_RF5112_FIXED_BIAS_A},
+       {6, AR5K_RF_FIXED_BIAS_B,       AR5K_RF5112_FIXED_BIAS_B},
+       {6, AR5K_RF_XPD_SEL,            AR5K_RF5112_XPD_SEL},
+       {6, AR5K_RF_XPD_GAIN,           AR5K_RF5112_XPD_GAIN},
+       {6, AR5K_RF_PWD_130,            AR5K_RF5112_PWD(130)},
+       {6, AR5K_RF_PWD_131,            AR5K_RF5112_PWD(131)},
+       {6, AR5K_RF_PWD_132,            AR5K_RF5112_PWD(132)},
+       {6, AR5K_RF_PWD_136,            AR5K_RF5112_PWD(136)},
+       {6, AR5K_RF_PWD_137,            AR5K_RF5112_PWD(137)},
+       {6, AR5K_RF_PWD_138,            AR5K_RF5112_PWD(138)},
+       {7, AR5K_RF_GAIN_I,             AR5K_RF5112X_GAIN_I},
+       {7, AR5K_RF_MIXVGA_OVR,         AR5K_RF5112X_MIXVGA_OVR},
+       {7, AR5K_RF_MIXGAIN_OVR,        AR5K_RF5112X_MIXGAIN_OVR},
+       {7, AR5K_RF_MIXGAIN_STEP,       AR5K_RF5112X_MIXGAIN_STEP},
+       {7, AR5K_RF_PD_DELAY_A,         AR5K_RF5112X_PD_DELAY_A},
+       {7, AR5K_RF_PD_DELAY_B,         AR5K_RF5112X_PD_DELAY_B},
+       {7, AR5K_RF_PD_DELAY_XR,        AR5K_RF5112X_PD_DELAY_XR},
+       {7, AR5K_RF_PD_PERIOD_A,        AR5K_RF5112X_PD_PERIOD_A},
+       {7, AR5K_RF_PD_PERIOD_B,        AR5K_RF5112X_PD_PERIOD_B},
+       {7, AR5K_RF_PD_PERIOD_XR,       AR5K_RF5112X_PD_PERIOD_XR},
+};
+
+/* Default mode specific settings */
+static const struct ath5k_ini_rfbuffer rfb_5112[] = {
+       { 1, 0x98d4,
+       /*     mode a/XR  mode aTurbo    mode b     mode g    mode gTurbo */
+           { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
+       { 2, 0x98d0,
+           { 0x03060408, 0x03070408, 0x03060408, 0x03060408, 0x03070408 } },
+       { 3, 0x98dc,
+           { 0x00a0c0c0, 0x00a0c0c0, 0x00e0c0c0, 0x00e0c0c0, 0x00e0c0c0 } },
+       { 6, 0x989c,
+           { 0x00a00000, 0x00a00000, 0x00a00000, 0x00a00000, 0x00a00000 } },
+       { 6, 0x989c,
+           { 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00660000, 0x00660000, 0x00660000, 0x00660000, 0x00660000 } },
+       { 6, 0x989c,
+           { 0x00db0000, 0x00db0000, 0x00db0000, 0x00db0000, 0x00db0000 } },
+       { 6, 0x989c,
+           { 0x00f10000, 0x00f10000, 0x00f10000, 0x00f10000, 0x00f10000 } },
+       { 6, 0x989c,
+           { 0x00120000, 0x00120000, 0x00120000, 0x00120000, 0x00120000 } },
+       { 6, 0x989c,
+           { 0x00120000, 0x00120000, 0x00120000, 0x00120000, 0x00120000 } },
+       { 6, 0x989c,
+           { 0x00730000, 0x00730000, 0x00730000, 0x00730000, 0x00730000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000 } },
+       { 6, 0x989c,
+           { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
+       { 6, 0x989c,
+           { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
+       { 6, 0x989c,
+           { 0x008b0000, 0x008b0000, 0x008b0000, 0x008b0000, 0x008b0000 } },
+       { 6, 0x989c,
+           { 0x00600000, 0x00600000, 0x00600000, 0x00600000, 0x00600000 } },
+       { 6, 0x989c,
+           { 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000 } },
+       { 6, 0x989c,
+           { 0x00840000, 0x00840000, 0x00840000, 0x00840000, 0x00840000 } },
+       { 6, 0x989c,
+           { 0x00640000, 0x00640000, 0x00640000, 0x00640000, 0x00640000 } },
+       { 6, 0x989c,
+           { 0x00200000, 0x00200000, 0x00200000, 0x00200000, 0x00200000 } },
+       { 6, 0x989c,
+           { 0x00240000, 0x00240000, 0x00240000, 0x00240000, 0x00240000 } },
+       { 6, 0x989c,
+           { 0x00250000, 0x00250000, 0x00250000, 0x00250000, 0x00250000 } },
+       { 6, 0x989c,
+           { 0x00110000, 0x00110000, 0x00110000, 0x00110000, 0x00110000 } },
+       { 6, 0x989c,
+           { 0x00110000, 0x00110000, 0x00110000, 0x00110000, 0x00110000 } },
+       { 6, 0x989c,
+           { 0x00510000, 0x00510000, 0x00510000, 0x00510000, 0x00510000 } },
+       { 6, 0x989c,
+           { 0x1c040000, 0x1c040000, 0x1c040000, 0x1c040000, 0x1c040000 } },
+       { 6, 0x989c,
+           { 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000 } },
+       { 6, 0x989c,
+           { 0x00a10000, 0x00a10000, 0x00a10000, 0x00a10000, 0x00a10000 } },
+       { 6, 0x989c,
+           { 0x00400000, 0x00400000, 0x00400000, 0x00400000, 0x00400000 } },
+       { 6, 0x989c,
+           { 0x03090000, 0x03090000, 0x03090000, 0x03090000, 0x03090000 } },
+       { 6, 0x989c,
+           { 0x06000000, 0x06000000, 0x06000000, 0x06000000, 0x06000000 } },
+       { 6, 0x989c,
+           { 0x000000b0, 0x000000b0, 0x000000a8, 0x000000a8, 0x000000a8 } },
+       { 6, 0x989c,
+           { 0x0000002e, 0x0000002e, 0x0000002e, 0x0000002e, 0x0000002e } },
+       { 6, 0x989c,
+           { 0x006c4a41, 0x006c4a41, 0x006c4af1, 0x006c4a61, 0x006c4a61 } },
+       { 6, 0x989c,
+           { 0x0050892a, 0x0050892a, 0x0050892b, 0x0050892b, 0x0050892b } },
+       { 6, 0x989c,
+           { 0x00842400, 0x00842400, 0x00842400, 0x00842400, 0x00842400 } },
+       { 6, 0x989c,
+           { 0x00c69200, 0x00c69200, 0x00c69200, 0x00c69200, 0x00c69200 } },
+       { 6, 0x98d0,
+           { 0x0002000c, 0x0002000c, 0x0002000c, 0x0002000c, 0x0002000c } },
+       { 7, 0x989c,
+           { 0x00000094, 0x00000094, 0x00000094, 0x00000094, 0x00000094 } },
+       { 7, 0x989c,
+           { 0x00000091, 0x00000091, 0x00000091, 0x00000091, 0x00000091 } },
+       { 7, 0x989c,
+           { 0x0000000a, 0x0000000a, 0x00000012, 0x00000012, 0x00000012 } },
+       { 7, 0x989c,
+           { 0x00000080, 0x00000080, 0x00000080, 0x00000080, 0x00000080 } },
+       { 7, 0x989c,
+           { 0x000000c1, 0x000000c1, 0x000000c1, 0x000000c1, 0x000000c1 } },
+       { 7, 0x989c,
+           { 0x00000060, 0x00000060, 0x00000060, 0x00000060, 0x00000060 } },
+       { 7, 0x989c,
+           { 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0 } },
+       { 7, 0x989c,
+           { 0x00000022, 0x00000022, 0x00000022, 0x00000022, 0x00000022 } },
+       { 7, 0x989c,
+           { 0x00000092, 0x00000092, 0x00000092, 0x00000092, 0x00000092 } },
+       { 7, 0x989c,
+           { 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4 } },
+       { 7, 0x989c,
+           { 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc } },
+       { 7, 0x989c,
+           { 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c } },
+       { 7, 0x98c4,
+           { 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000003 } },
+};
+
+/* RFX112A (Derby 2) */
+
+/* BANK 6                              len  pos col */
+#define        AR5K_RF5112A_OB_2GHZ            { 3, 287, 0 }
+#define        AR5K_RF5112A_DB_2GHZ            { 3, 290, 0 }
+
+#define        AR5K_RF5112A_OB_5GHZ            { 3, 279, 0 }
+#define        AR5K_RF5112A_DB_5GHZ            { 3, 282, 0 }
+
+#define        AR5K_RF5112A_FIXED_BIAS_A       { 1, 278, 0 }
+#define        AR5K_RF5112A_FIXED_BIAS_B       { 1, 277, 0 }
+
+#define        AR5K_RF5112A_XPD_SEL            { 1, 302, 0 }
+#define        AR5K_RF5112A_PDGAINLO           { 2, 270, 0 }
+#define        AR5K_RF5112A_PDGAINHI           { 2, 257, 0 }
+
+/* Access to PWD registers */
+#define AR5K_RF5112A_PWD(_n)           { 1, (306 - _n), 3 }
+
+/* Voltage regulators */
+#define        AR5K_RF5112A_HIGH_VC_CP         { 2, 90,  2 }
+#define        AR5K_RF5112A_MID_VC_CP          { 2, 92,  2 }
+#define        AR5K_RF5112A_LOW_VC_CP          { 2, 94,  2 }
+#define        AR5K_RF5112A_PUSH_UP            { 1, 254,  2 }
+
+/* Power consumption */
+#define        AR5K_RF5112A_PAD2GND            { 1, 281, 1 }
+#define        AR5K_RF5112A_XB2_LVL            { 2, 1,   3 }
+#define        AR5K_RF5112A_XB5_LVL            { 2, 3,   3 }
+
+static const struct ath5k_rf_reg rf_regs_5112a[] = {
+       {6, AR5K_RF_OB_2GHZ,            AR5K_RF5112A_OB_2GHZ},
+       {6, AR5K_RF_DB_2GHZ,            AR5K_RF5112A_DB_2GHZ},
+       {6, AR5K_RF_OB_5GHZ,            AR5K_RF5112A_OB_5GHZ},
+       {6, AR5K_RF_DB_5GHZ,            AR5K_RF5112A_DB_5GHZ},
+       {6, AR5K_RF_FIXED_BIAS_A,       AR5K_RF5112A_FIXED_BIAS_A},
+       {6, AR5K_RF_FIXED_BIAS_B,       AR5K_RF5112A_FIXED_BIAS_B},
+       {6, AR5K_RF_XPD_SEL,            AR5K_RF5112A_XPD_SEL},
+       {6, AR5K_RF_PD_GAIN_LO,         AR5K_RF5112A_PDGAINLO},
+       {6, AR5K_RF_PD_GAIN_HI,         AR5K_RF5112A_PDGAINHI},
+       {6, AR5K_RF_PWD_130,            AR5K_RF5112A_PWD(130)},
+       {6, AR5K_RF_PWD_131,            AR5K_RF5112A_PWD(131)},
+       {6, AR5K_RF_PWD_132,            AR5K_RF5112A_PWD(132)},
+       {6, AR5K_RF_PWD_136,            AR5K_RF5112A_PWD(136)},
+       {6, AR5K_RF_PWD_137,            AR5K_RF5112A_PWD(137)},
+       {6, AR5K_RF_PWD_138,            AR5K_RF5112A_PWD(138)},
+       {6, AR5K_RF_PWD_166,            AR5K_RF5112A_PWD(166)},
+       {6, AR5K_RF_PWD_167,            AR5K_RF5112A_PWD(167)},
+       {6, AR5K_RF_HIGH_VC_CP,         AR5K_RF5112A_HIGH_VC_CP},
+       {6, AR5K_RF_MID_VC_CP,          AR5K_RF5112A_MID_VC_CP},
+       {6, AR5K_RF_LOW_VC_CP,          AR5K_RF5112A_LOW_VC_CP},
+       {6, AR5K_RF_PUSH_UP,            AR5K_RF5112A_PUSH_UP},
+       {6, AR5K_RF_PAD2GND,            AR5K_RF5112A_PAD2GND},
+       {6, AR5K_RF_XB2_LVL,            AR5K_RF5112A_XB2_LVL},
+       {6, AR5K_RF_XB5_LVL,            AR5K_RF5112A_XB5_LVL},
+       {7, AR5K_RF_GAIN_I,             AR5K_RF5112X_GAIN_I},
+       {7, AR5K_RF_MIXVGA_OVR,         AR5K_RF5112X_MIXVGA_OVR},
+       {7, AR5K_RF_MIXGAIN_OVR,        AR5K_RF5112X_MIXGAIN_OVR},
+       {7, AR5K_RF_MIXGAIN_STEP,       AR5K_RF5112X_MIXGAIN_STEP},
+       {7, AR5K_RF_PD_DELAY_A,         AR5K_RF5112X_PD_DELAY_A},
+       {7, AR5K_RF_PD_DELAY_B,         AR5K_RF5112X_PD_DELAY_B},
+       {7, AR5K_RF_PD_DELAY_XR,        AR5K_RF5112X_PD_DELAY_XR},
+       {7, AR5K_RF_PD_PERIOD_A,        AR5K_RF5112X_PD_PERIOD_A},
+       {7, AR5K_RF_PD_PERIOD_B,        AR5K_RF5112X_PD_PERIOD_B},
+       {7, AR5K_RF_PD_PERIOD_XR,       AR5K_RF5112X_PD_PERIOD_XR},
+};
+
+/* Default mode specific settings */
+static const struct ath5k_ini_rfbuffer rfb_5112a[] = {
+       { 1, 0x98d4,
+       /*     mode a/XR  mode aTurbo    mode b     mode g    mode gTurbo */
+           { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
+       { 2, 0x98d0,
+           { 0x03060408, 0x03070408, 0x03060408, 0x03060408, 0x03070408 } },
+       { 3, 0x98dc,
+           { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
+       { 6, 0x989c,
+           { 0x0f000000, 0x0f000000, 0x0f000000, 0x0f000000, 0x0f000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00800000, 0x00800000, 0x00800000, 0x00800000, 0x00800000 } },
+       { 6, 0x989c,
+           { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } },
+       { 6, 0x989c,
+           { 0x00010000, 0x00010000, 0x00010000, 0x00010000, 0x00010000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00180000, 0x00180000, 0x00180000, 0x00180000, 0x00180000 } },
+       { 6, 0x989c,
+           { 0x00600000, 0x00600000, 0x006e0000, 0x006e0000, 0x006e0000 } },
+       { 6, 0x989c,
+           { 0x00c70000, 0x00c70000, 0x00c70000, 0x00c70000, 0x00c70000 } },
+       { 6, 0x989c,
+           { 0x004b0000, 0x004b0000, 0x004b0000, 0x004b0000, 0x004b0000 } },
+       { 6, 0x989c,
+           { 0x04480000, 0x04480000, 0x04480000, 0x04480000, 0x04480000 } },
+       { 6, 0x989c,
+           { 0x004c0000, 0x004c0000, 0x004c0000, 0x004c0000, 0x004c0000 } },
+       { 6, 0x989c,
+           { 0x00e40000, 0x00e40000, 0x00e40000, 0x00e40000, 0x00e40000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00fc0000, 0x00fc0000, 0x00fc0000, 0x00fc0000, 0x00fc0000 } },
+       { 6, 0x989c,
+           { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
+       { 6, 0x989c,
+           { 0x043f0000, 0x043f0000, 0x043f0000, 0x043f0000, 0x043f0000 } },
+       { 6, 0x989c,
+           { 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000 } },
+       { 6, 0x989c,
+           { 0x02190000, 0x02190000, 0x02190000, 0x02190000, 0x02190000 } },
+       { 6, 0x989c,
+           { 0x00240000, 0x00240000, 0x00240000, 0x00240000, 0x00240000 } },
+       { 6, 0x989c,
+           { 0x00b40000, 0x00b40000, 0x00b40000, 0x00b40000, 0x00b40000 } },
+       { 6, 0x989c,
+           { 0x00990000, 0x00990000, 0x00990000, 0x00990000, 0x00990000 } },
+       { 6, 0x989c,
+           { 0x00500000, 0x00500000, 0x00500000, 0x00500000, 0x00500000 } },
+       { 6, 0x989c,
+           { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } },
+       { 6, 0x989c,
+           { 0x00120000, 0x00120000, 0x00120000, 0x00120000, 0x00120000 } },
+       { 6, 0x989c,
+           { 0xc0320000, 0xc0320000, 0xc0320000, 0xc0320000, 0xc0320000 } },
+       { 6, 0x989c,
+           { 0x01740000, 0x01740000, 0x01740000, 0x01740000, 0x01740000 } },
+       { 6, 0x989c,
+           { 0x00110000, 0x00110000, 0x00110000, 0x00110000, 0x00110000 } },
+       { 6, 0x989c,
+           { 0x86280000, 0x86280000, 0x86280000, 0x86280000, 0x86280000 } },
+       { 6, 0x989c,
+           { 0x31840000, 0x31840000, 0x31840000, 0x31840000, 0x31840000 } },
+       { 6, 0x989c,
+           { 0x00f20080, 0x00f20080, 0x00f20080, 0x00f20080, 0x00f20080 } },
+       { 6, 0x989c,
+           { 0x00270019, 0x00270019, 0x00270019, 0x00270019, 0x00270019 } },
+       { 6, 0x989c,
+           { 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000003 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x000000b2, 0x000000b2, 0x000000b2, 0x000000b2, 0x000000b2 } },
+       { 6, 0x989c,
+           { 0x00b02084, 0x00b02084, 0x00b02084, 0x00b02084, 0x00b02084 } },
+       { 6, 0x989c,
+           { 0x004125a4, 0x004125a4, 0x004125a4, 0x004125a4, 0x004125a4 } },
+       { 6, 0x989c,
+           { 0x00119220, 0x00119220, 0x00119220, 0x00119220, 0x00119220 } },
+       { 6, 0x989c,
+           { 0x001a4800, 0x001a4800, 0x001a4800, 0x001a4800, 0x001a4800 } },
+       { 6, 0x98d8,
+           { 0x000b0230, 0x000b0230, 0x000b0230, 0x000b0230, 0x000b0230 } },
+       { 7, 0x989c,
+           { 0x00000094, 0x00000094, 0x00000094, 0x00000094, 0x00000094 } },
+       { 7, 0x989c,
+           { 0x00000091, 0x00000091, 0x00000091, 0x00000091, 0x00000091 } },
+       { 7, 0x989c,
+           { 0x00000012, 0x00000012, 0x00000012, 0x00000012, 0x00000012 } },
+       { 7, 0x989c,
+           { 0x00000080, 0x00000080, 0x00000080, 0x00000080, 0x00000080 } },
+       { 7, 0x989c,
+           { 0x000000d9, 0x000000d9, 0x000000d9, 0x000000d9, 0x000000d9 } },
+       { 7, 0x989c,
+           { 0x00000060, 0x00000060, 0x00000060, 0x00000060, 0x00000060 } },
+       { 7, 0x989c,
+           { 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0 } },
+       { 7, 0x989c,
+           { 0x000000a2, 0x000000a2, 0x000000a2, 0x000000a2, 0x000000a2 } },
+       { 7, 0x989c,
+           { 0x00000052, 0x00000052, 0x00000052, 0x00000052, 0x00000052 } },
+       { 7, 0x989c,
+           { 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4 } },
+       { 7, 0x989c,
+           { 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc } },
+       { 7, 0x989c,
+           { 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c } },
+       { 7, 0x98c4,
+           { 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000003 } },
+};
+
+
+
+/******************\
+* RF2413 (Griffin) *
+\******************/
+
+/* BANK 6                              len  pos col */
+#define        AR5K_RF2413_OB_2GHZ             { 3, 168, 0 }
+#define        AR5K_RF2413_DB_2GHZ             { 3, 165, 0 }
+
+static const struct ath5k_rf_reg rf_regs_2413[] = {
+       {6, AR5K_RF_OB_2GHZ,            AR5K_RF2413_OB_2GHZ},
+       {6, AR5K_RF_DB_2GHZ,            AR5K_RF2413_DB_2GHZ},
+};
+
+/* Default mode specific settings
+ * XXX: a/aTurbo ???
+ */
+static const struct ath5k_ini_rfbuffer rfb_2413[] = {
+       { 1, 0x98d4,
+       /*     mode a/XR  mode aTurbo    mode b     mode g    mode gTurbo */
+           { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
+       { 2, 0x98d0,
+           { 0x02001408, 0x02011408, 0x02001408, 0x02001408, 0x02011408 } },
+       { 3, 0x98dc,
+           { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
+       { 6, 0x989c,
+           { 0xf0000000, 0xf0000000, 0xf0000000, 0xf0000000, 0xf0000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x03000000, 0x03000000, 0x03000000, 0x03000000, 0x03000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x40400000, 0x40400000, 0x40400000, 0x40400000, 0x40400000 } },
+       { 6, 0x989c,
+           { 0x65050000, 0x65050000, 0x65050000, 0x65050000, 0x65050000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00420000, 0x00420000, 0x00420000, 0x00420000, 0x00420000 } },
+       { 6, 0x989c,
+           { 0x00b50000, 0x00b50000, 0x00b50000, 0x00b50000, 0x00b50000 } },
+       { 6, 0x989c,
+           { 0x00030000, 0x00030000, 0x00030000, 0x00030000, 0x00030000 } },
+       { 6, 0x989c,
+           { 0x00f70000, 0x00f70000, 0x00f70000, 0x00f70000, 0x00f70000 } },
+       { 6, 0x989c,
+           { 0x009d0000, 0x009d0000, 0x009d0000, 0x009d0000, 0x009d0000 } },
+       { 6, 0x989c,
+           { 0x00220000, 0x00220000, 0x00220000, 0x00220000, 0x00220000 } },
+       { 6, 0x989c,
+           { 0x04220000, 0x04220000, 0x04220000, 0x04220000, 0x04220000 } },
+       { 6, 0x989c,
+           { 0x00230018, 0x00230018, 0x00230018, 0x00230018, 0x00230018 } },
+       { 6, 0x989c,
+           { 0x00280000, 0x00280000, 0x00280060, 0x00280060, 0x00280060 } },
+       { 6, 0x989c,
+           { 0x005000c0, 0x005000c0, 0x005000c3, 0x005000c3, 0x005000c3 } },
+       { 6, 0x989c,
+           { 0x0004007f, 0x0004007f, 0x0004007f, 0x0004007f, 0x0004007f } },
+       { 6, 0x989c,
+           { 0x00000458, 0x00000458, 0x00000458, 0x00000458, 0x00000458 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x0000c000, 0x0000c000, 0x0000c000, 0x0000c000, 0x0000c000 } },
+       { 6, 0x98d8,
+           { 0x00400230, 0x00400230, 0x00400230, 0x00400230, 0x00400230 } },
+       { 7, 0x989c,
+           { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
+       { 7, 0x989c,
+           { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
+       { 7, 0x98cc,
+           { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
+};
+
+
+
+/***************************\
+* RF2315/RF2316 (Cobra SoC) *
+\***************************/
+
+/* BANK 6                              len  pos col */
+#define        AR5K_RF2316_OB_2GHZ             { 3, 178, 0 }
+#define        AR5K_RF2316_DB_2GHZ             { 3, 175, 0 }
+
+static const struct ath5k_rf_reg rf_regs_2316[] = {
+       {6, AR5K_RF_OB_2GHZ,            AR5K_RF2316_OB_2GHZ},
+       {6, AR5K_RF_DB_2GHZ,            AR5K_RF2316_DB_2GHZ},
+};
+
+/* Default mode specific settings */
+static const struct ath5k_ini_rfbuffer rfb_2316[] = {
+       { 1, 0x98d4,
+       /*     mode a/XR  mode aTurbo    mode b     mode g    mode gTurbo */
+           { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
+       { 2, 0x98d0,
+           { 0x02001408, 0x02011408, 0x02001408, 0x02001408, 0x02011408 } },
+       { 3, 0x98dc,
+           { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0xc0000000, 0xc0000000, 0xc0000000, 0xc0000000, 0xc0000000 } },
+       { 6, 0x989c,
+           { 0x0f000000, 0x0f000000, 0x0f000000, 0x0f000000, 0x0f000000 } },
+       { 6, 0x989c,
+           { 0x02000000, 0x02000000, 0x02000000, 0x02000000, 0x02000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0xf8000000, 0xf8000000, 0xf8000000, 0xf8000000, 0xf8000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x95150000, 0x95150000, 0x95150000, 0x95150000, 0x95150000 } },
+       { 6, 0x989c,
+           { 0xc1000000, 0xc1000000, 0xc1000000, 0xc1000000, 0xc1000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00080000, 0x00080000, 0x00080000, 0x00080000, 0x00080000 } },
+       { 6, 0x989c,
+           { 0x00d50000, 0x00d50000, 0x00d50000, 0x00d50000, 0x00d50000 } },
+       { 6, 0x989c,
+           { 0x000e0000, 0x000e0000, 0x000e0000, 0x000e0000, 0x000e0000 } },
+       { 6, 0x989c,
+           { 0x00dc0000, 0x00dc0000, 0x00dc0000, 0x00dc0000, 0x00dc0000 } },
+       { 6, 0x989c,
+           { 0x00770000, 0x00770000, 0x00770000, 0x00770000, 0x00770000 } },
+       { 6, 0x989c,
+           { 0x008a0000, 0x008a0000, 0x008a0000, 0x008a0000, 0x008a0000 } },
+       { 6, 0x989c,
+           { 0x10880000, 0x10880000, 0x10880000, 0x10880000, 0x10880000 } },
+       { 6, 0x989c,
+           { 0x008c0060, 0x008c0060, 0x008c0060, 0x008c0060, 0x008c0060 } },
+       { 6, 0x989c,
+           { 0x00a00000, 0x00a00000, 0x00a00080, 0x00a00080, 0x00a00080 } },
+       { 6, 0x989c,
+           { 0x00400000, 0x00400000, 0x0040000d, 0x0040000d, 0x0040000d } },
+       { 6, 0x989c,
+           { 0x00110400, 0x00110400, 0x00110400, 0x00110400, 0x00110400 } },
+       { 6, 0x989c,
+           { 0x00000060, 0x00000060, 0x00000060, 0x00000060, 0x00000060 } },
+       { 6, 0x989c,
+           { 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001 } },
+       { 6, 0x989c,
+           { 0x00000b00, 0x00000b00, 0x00000b00, 0x00000b00, 0x00000b00 } },
+       { 6, 0x989c,
+           { 0x00000be8, 0x00000be8, 0x00000be8, 0x00000be8, 0x00000be8 } },
+       { 6, 0x98c0,
+           { 0x00010000, 0x00010000, 0x00010000, 0x00010000, 0x00010000 } },
+       { 7, 0x989c,
+           { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
+       { 7, 0x989c,
+           { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
+       { 7, 0x98cc,
+           { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
+};
+
+
+
+/******************************\
+* RF5413/RF5424 (Eagle/Condor) *
+\******************************/
+
+/* BANK 6                              len  pos col */
+#define        AR5K_RF5413_OB_2GHZ             { 3, 241, 0 }
+#define        AR5K_RF5413_DB_2GHZ             { 3, 238, 0 }
+
+#define        AR5K_RF5413_OB_5GHZ             { 3, 247, 0 }
+#define        AR5K_RF5413_DB_5GHZ             { 3, 244, 0 }
+
+#define        AR5K_RF5413_PWD_ICLOBUF2G       { 3, 131, 3 }
+#define        AR5K_RF5413_DERBY_CHAN_SEL_MODE { 1, 291, 2 }
+
+static const struct ath5k_rf_reg rf_regs_5413[] = {
+       {6, AR5K_RF_OB_2GHZ,             AR5K_RF5413_OB_2GHZ},
+       {6, AR5K_RF_DB_2GHZ,             AR5K_RF5413_DB_2GHZ},
+       {6, AR5K_RF_OB_5GHZ,             AR5K_RF5413_OB_5GHZ},
+       {6, AR5K_RF_DB_5GHZ,             AR5K_RF5413_DB_5GHZ},
+       {6, AR5K_RF_PWD_ICLOBUF_2G,      AR5K_RF5413_PWD_ICLOBUF2G},
+       {6, AR5K_RF_DERBY_CHAN_SEL_MODE, AR5K_RF5413_DERBY_CHAN_SEL_MODE},
+};
+
+/* Default mode specific settings */
+static const struct ath5k_ini_rfbuffer rfb_5413[] = {
+       { 1, 0x98d4,
+       /*     mode a/XR  mode aTurbo    mode b     mode g    mode gTurbo */
+           { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
+       { 2, 0x98d0,
+           { 0x00000008, 0x00000008, 0x00000008, 0x00000008, 0x00000008 } },
+       { 3, 0x98dc,
+           { 0x00a000c0, 0x00a000c0, 0x00e000c0, 0x00e000c0, 0x00e000c0 } },
+       { 6, 0x989c,
+           { 0x33000000, 0x33000000, 0x33000000, 0x33000000, 0x33000000 } },
+       { 6, 0x989c,
+           { 0x01000000, 0x01000000, 0x01000000, 0x01000000, 0x01000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x1f000000, 0x1f000000, 0x1f000000, 0x1f000000, 0x1f000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00b80000, 0x00b80000, 0x00b80000, 0x00b80000, 0x00b80000 } },
+       { 6, 0x989c,
+           { 0x00b70000, 0x00b70000, 0x00b70000, 0x00b70000, 0x00b70000 } },
+       { 6, 0x989c,
+           { 0x00840000, 0x00840000, 0x00840000, 0x00840000, 0x00840000 } },
+       { 6, 0x989c,
+           { 0x00980000, 0x00980000, 0x00980000, 0x00980000, 0x00980000 } },
+       { 6, 0x989c,
+           { 0x00c00000, 0x00c00000, 0x00c00000, 0x00c00000, 0x00c00000 } },
+       { 6, 0x989c,
+           { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
+       { 6, 0x989c,
+           { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
+       { 6, 0x989c,
+           { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
+       { 6, 0x989c,
+           { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
+       { 6, 0x989c,
+           { 0x00d70000, 0x00d70000, 0x00d70000, 0x00d70000, 0x00d70000 } },
+       { 6, 0x989c,
+           { 0x00610000, 0x00610000, 0x00610000, 0x00610000, 0x00610000 } },
+       { 6, 0x989c,
+           { 0x00fe0000, 0x00fe0000, 0x00fe0000, 0x00fe0000, 0x00fe0000 } },
+       { 6, 0x989c,
+           { 0x00de0000, 0x00de0000, 0x00de0000, 0x00de0000, 0x00de0000 } },
+       { 6, 0x989c,
+           { 0x007f0000, 0x007f0000, 0x007f0000, 0x007f0000, 0x007f0000 } },
+       { 6, 0x989c,
+           { 0x043d0000, 0x043d0000, 0x043d0000, 0x043d0000, 0x043d0000 } },
+       { 6, 0x989c,
+           { 0x00770000, 0x00770000, 0x00770000, 0x00770000, 0x00770000 } },
+       { 6, 0x989c,
+           { 0x00440000, 0x00440000, 0x00440000, 0x00440000, 0x00440000 } },
+       { 6, 0x989c,
+           { 0x00980000, 0x00980000, 0x00980000, 0x00980000, 0x00980000 } },
+       { 6, 0x989c,
+           { 0x00100080, 0x00100080, 0x00100080, 0x00100080, 0x00100080 } },
+       { 6, 0x989c,
+           { 0x0005c034, 0x0005c034, 0x0005c034, 0x0005c034, 0x0005c034 } },
+       { 6, 0x989c,
+           { 0x003100f0, 0x003100f0, 0x003100f0, 0x003100f0, 0x003100f0 } },
+       { 6, 0x989c,
+           { 0x000c011f, 0x000c011f, 0x000c011f, 0x000c011f, 0x000c011f } },
+       { 6, 0x989c,
+           { 0x00510040, 0x00510040, 0x00510040, 0x00510040, 0x00510040 } },
+       { 6, 0x989c,
+           { 0x005000da, 0x005000da, 0x005000da, 0x005000da, 0x005000da } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00004044, 0x00004044, 0x00004044, 0x00004044, 0x00004044 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x000060c0, 0x000060c0, 0x000060c0, 0x000060c0, 0x000060c0 } },
+       { 6, 0x989c,
+           { 0x00002c00, 0x00002c00, 0x00003600, 0x00003600, 0x00002c00 } },
+       { 6, 0x98c8,
+           { 0x00000403, 0x00000403, 0x00040403, 0x00040403, 0x00040403 } },
+       { 7, 0x989c,
+           { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
+       { 7, 0x989c,
+           { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
+       { 7, 0x98cc,
+           { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
+};
+
+
+
+/***************************\
+* RF2425/RF2417 (Swan/Nala) *
+* AR2317 (Spider SoC)       *
+\***************************/
+
+/* BANK 6                              len  pos col */
+#define        AR5K_RF2425_OB_2GHZ             { 3, 193, 0 }
+#define        AR5K_RF2425_DB_2GHZ             { 3, 190, 0 }
+
+static const struct ath5k_rf_reg rf_regs_2425[] = {
+       {6, AR5K_RF_OB_2GHZ,            AR5K_RF2425_OB_2GHZ},
+       {6, AR5K_RF_DB_2GHZ,            AR5K_RF2425_DB_2GHZ},
+};
+
+/* Default mode specific settings
+ * XXX: a/aTurbo ?
+ */
+static const struct ath5k_ini_rfbuffer rfb_2425[] = {
+       { 1, 0x98d4,
+       /*     mode a/XR  mode aTurbo    mode b     mode g    mode gTurbo */
+           { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
+       { 2, 0x98d0,
+           { 0x02001408, 0x02001408, 0x02001408, 0x02001408, 0x02001408 } },
+       { 3, 0x98dc,
+           { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
+       { 6, 0x989c,
+           { 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000 } },
+       { 6, 0x989c,
+           { 0x00020000, 0x00020000, 0x00020000, 0x00020000, 0x00020000 } },
+       { 6, 0x989c,
+           { 0x00730000, 0x00730000, 0x00730000, 0x00730000, 0x00730000 } },
+       { 6, 0x989c,
+           { 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000 } },
+       { 6, 0x989c,
+           { 0x00e70000, 0x00e70000, 0x00e70000, 0x00e70000, 0x00e70000 } },
+       { 6, 0x989c,
+           { 0x00140000, 0x00140000, 0x00140000, 0x00140000, 0x00140000 } },
+       { 6, 0x989c,
+           { 0x00910040, 0x00910040, 0x00910040, 0x00910040, 0x00910040 } },
+       { 6, 0x989c,
+           { 0x0007001a, 0x0007001a, 0x0007001a, 0x0007001a, 0x0007001a } },
+       { 6, 0x989c,
+           { 0x00410000, 0x00410000, 0x00410000, 0x00410000, 0x00410000 } },
+       { 6, 0x989c,
+           { 0x00810000, 0x00810000, 0x00810060, 0x00810060, 0x00810060 } },
+       { 6, 0x989c,
+           { 0x00020800, 0x00020800, 0x00020803, 0x00020803, 0x00020803 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00001660, 0x00001660, 0x00001660, 0x00001660, 0x00001660 } },
+       { 6, 0x989c,
+           { 0x00001688, 0x00001688, 0x00001688, 0x00001688, 0x00001688 } },
+       { 6, 0x98c4,
+           { 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001 } },
+       { 7, 0x989c,
+           { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
+       { 7, 0x989c,
+           { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
+       { 7, 0x98cc,
+           { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
+};
+
+/*
+ * TODO: Handle the few differences with swan during
+ * bank modification and get rid of this
+ */
+static const struct ath5k_ini_rfbuffer rfb_2317[] = {
+       { 1, 0x98d4,
+       /*     mode a/XR  mode aTurbo    mode b     mode g    mode gTurbo */
+           { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
+       { 2, 0x98d0,
+           { 0x02001408, 0x02011408, 0x02001408, 0x02001408, 0x02011408 } },
+       { 3, 0x98dc,
+           { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
+       { 6, 0x989c,
+           { 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000 } },
+       { 6, 0x989c,
+           { 0x00020000, 0x00020000, 0x00020000, 0x00020000, 0x00020000 } },
+       { 6, 0x989c,
+           { 0x00730000, 0x00730000, 0x00730000, 0x00730000, 0x00730000 } },
+       { 6, 0x989c,
+           { 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000 } },
+       { 6, 0x989c,
+           { 0x00e70000, 0x00e70000, 0x00e70000, 0x00e70000, 0x00e70000 } },
+       { 6, 0x989c,
+           { 0x00140100, 0x00140100, 0x00140100, 0x00140100, 0x00140100 } },
+       { 6, 0x989c,
+           { 0x00910040, 0x00910040, 0x00910040, 0x00910040, 0x00910040 } },
+       { 6, 0x989c,
+           { 0x0007001a, 0x0007001a, 0x0007001a, 0x0007001a, 0x0007001a } },
+       { 6, 0x989c,
+           { 0x00410000, 0x00410000, 0x00410000, 0x00410000, 0x00410000 } },
+       { 6, 0x989c,
+           { 0x00810000, 0x00810000, 0x00810060, 0x00810060, 0x00810060 } },
+       { 6, 0x989c,
+           { 0x00020800, 0x00020800, 0x00020803, 0x00020803, 0x00020803 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00001660, 0x00001660, 0x00001660, 0x00001660, 0x00001660 } },
+       { 6, 0x989c,
+           { 0x00009688, 0x00009688, 0x00009688, 0x00009688, 0x00009688 } },
+       { 6, 0x98c4,
+           { 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001 } },
+       { 7, 0x989c,
+           { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
+       { 7, 0x989c,
+           { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
+       { 7, 0x98cc,
+           { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
+};
+
+/*
+ * TODO: Handle the few differences with swan during
+ * bank modification and get rid of this
+ * XXX: a/aTurbo ?
+ */
+static const struct ath5k_ini_rfbuffer rfb_2417[] = {
+       { 1, 0x98d4,
+       /*     mode a/XR  mode aTurbo    mode b     mode g    mode gTurbo */
+           { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
+       { 2, 0x98d0,
+           { 0x02001408, 0x02001408, 0x02001408, 0x02001408, 0x02001408 } },
+       { 3, 0x98dc,
+           { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
+       { 6, 0x989c,
+           { 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000 } },
+       { 6, 0x989c,
+           { 0x00020000, 0x00020000, 0x00020000, 0x00020000, 0x00020000 } },
+       { 6, 0x989c,
+           { 0x00730000, 0x00730000, 0x00730000, 0x00730000, 0x00730000 } },
+       { 6, 0x989c,
+           { 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000 } },
+       { 6, 0x989c,
+           { 0x00e70000, 0x00e70000, 0x80e70000, 0x80e70000, 0x00e70000 } },
+       { 6, 0x989c,
+           { 0x00140000, 0x00140000, 0x00140000, 0x00140000, 0x00140000 } },
+       { 6, 0x989c,
+           { 0x00910040, 0x00910040, 0x00910040, 0x00910040, 0x00910040 } },
+       { 6, 0x989c,
+           { 0x0007001a, 0x0007001a, 0x0207001a, 0x0207001a, 0x0007001a } },
+       { 6, 0x989c,
+           { 0x00410000, 0x00410000, 0x00410000, 0x00410000, 0x00410000 } },
+       { 6, 0x989c,
+           { 0x00810000, 0x00810000, 0x00810060, 0x00810060, 0x00810060 } },
+       { 6, 0x989c,
+           { 0x00020800, 0x00020800, 0x00020803, 0x00020803, 0x00020803 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+       { 6, 0x989c,
+           { 0x00001660, 0x00001660, 0x00001660, 0x00001660, 0x00001660 } },
+       { 6, 0x989c,
+           { 0x00001688, 0x00001688, 0x00001688, 0x00001688, 0x00001688 } },
+       { 6, 0x98c4,
+           { 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001 } },
+       { 7, 0x989c,
+           { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
+       { 7, 0x989c,
+           { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
+       { 7, 0x98cc,
+           { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
+};
diff --git a/drivers/net/wireless/ath/ath5k/rfgain.h b/drivers/net/wireless/ath/ath5k/rfgain.h
new file mode 100644 (file)
index 0000000..1354d8c
--- /dev/null
@@ -0,0 +1,516 @@
+/*
+ * RF Gain optimization
+ *
+ * Copyright (c) 2004-2009 Reyk Floeter <reyk@openbsd.org>
+ * Copyright (c) 2006-2009 Nick Kossifidis <mickflemm@gmail.com>
+ *
+ * Permission to use, copy, modify, and 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.
+ *
+ */
+
+/*
+ * Mode-specific RF Gain table (64bytes) for RF5111/5112
+ * (RF5110 only comes with AR5210 and only supports a/turbo a mode so initial
+ * RF Gain values are included in AR5K_AR5210_INI)
+ */
+struct ath5k_ini_rfgain {
+       u16     rfg_register;   /* RF Gain register address */
+       u32     rfg_value[2];   /* [freq (see below)] */
+};
+
+/* Initial RF Gain settings for RF5111 */
+static const struct ath5k_ini_rfgain rfgain_5111[] = {
+       /*                            5Ghz      2Ghz    */
+       { AR5K_RF_GAIN(0),      { 0x000001a9, 0x00000000 } },
+       { AR5K_RF_GAIN(1),      { 0x000001e9, 0x00000040 } },
+       { AR5K_RF_GAIN(2),      { 0x00000029, 0x00000080 } },
+       { AR5K_RF_GAIN(3),      { 0x00000069, 0x00000150 } },
+       { AR5K_RF_GAIN(4),      { 0x00000199, 0x00000190 } },
+       { AR5K_RF_GAIN(5),      { 0x000001d9, 0x000001d0 } },
+       { AR5K_RF_GAIN(6),      { 0x00000019, 0x00000010 } },
+       { AR5K_RF_GAIN(7),      { 0x00000059, 0x00000044 } },
+       { AR5K_RF_GAIN(8),      { 0x00000099, 0x00000084 } },
+       { AR5K_RF_GAIN(9),      { 0x000001a5, 0x00000148 } },
+       { AR5K_RF_GAIN(10),     { 0x000001e5, 0x00000188 } },
+       { AR5K_RF_GAIN(11),     { 0x00000025, 0x000001c8 } },
+       { AR5K_RF_GAIN(12),     { 0x000001c8, 0x00000014 } },
+       { AR5K_RF_GAIN(13),     { 0x00000008, 0x00000042 } },
+       { AR5K_RF_GAIN(14),     { 0x00000048, 0x00000082 } },
+       { AR5K_RF_GAIN(15),     { 0x00000088, 0x00000178 } },
+       { AR5K_RF_GAIN(16),     { 0x00000198, 0x000001b8 } },
+       { AR5K_RF_GAIN(17),     { 0x000001d8, 0x000001f8 } },
+       { AR5K_RF_GAIN(18),     { 0x00000018, 0x00000012 } },
+       { AR5K_RF_GAIN(19),     { 0x00000058, 0x00000052 } },
+       { AR5K_RF_GAIN(20),     { 0x00000098, 0x00000092 } },
+       { AR5K_RF_GAIN(21),     { 0x000001a4, 0x0000017c } },
+       { AR5K_RF_GAIN(22),     { 0x000001e4, 0x000001bc } },
+       { AR5K_RF_GAIN(23),     { 0x00000024, 0x000001fc } },
+       { AR5K_RF_GAIN(24),     { 0x00000064, 0x0000000a } },
+       { AR5K_RF_GAIN(25),     { 0x000000a4, 0x0000004a } },
+       { AR5K_RF_GAIN(26),     { 0x000000e4, 0x0000008a } },
+       { AR5K_RF_GAIN(27),     { 0x0000010a, 0x0000015a } },
+       { AR5K_RF_GAIN(28),     { 0x0000014a, 0x0000019a } },
+       { AR5K_RF_GAIN(29),     { 0x0000018a, 0x000001da } },
+       { AR5K_RF_GAIN(30),     { 0x000001ca, 0x0000000e } },
+       { AR5K_RF_GAIN(31),     { 0x0000000a, 0x0000004e } },
+       { AR5K_RF_GAIN(32),     { 0x0000004a, 0x0000008e } },
+       { AR5K_RF_GAIN(33),     { 0x0000008a, 0x0000015e } },
+       { AR5K_RF_GAIN(34),     { 0x000001ba, 0x0000019e } },
+       { AR5K_RF_GAIN(35),     { 0x000001fa, 0x000001de } },
+       { AR5K_RF_GAIN(36),     { 0x0000003a, 0x00000009 } },
+       { AR5K_RF_GAIN(37),     { 0x0000007a, 0x00000049 } },
+       { AR5K_RF_GAIN(38),     { 0x00000186, 0x00000089 } },
+       { AR5K_RF_GAIN(39),     { 0x000001c6, 0x00000179 } },
+       { AR5K_RF_GAIN(40),     { 0x00000006, 0x000001b9 } },
+       { AR5K_RF_GAIN(41),     { 0x00000046, 0x000001f9 } },
+       { AR5K_RF_GAIN(42),     { 0x00000086, 0x00000039 } },
+       { AR5K_RF_GAIN(43),     { 0x000000c6, 0x00000079 } },
+       { AR5K_RF_GAIN(44),     { 0x000000c6, 0x000000b9 } },
+       { AR5K_RF_GAIN(45),     { 0x000000c6, 0x000001bd } },
+       { AR5K_RF_GAIN(46),     { 0x000000c6, 0x000001fd } },
+       { AR5K_RF_GAIN(47),     { 0x000000c6, 0x0000003d } },
+       { AR5K_RF_GAIN(48),     { 0x000000c6, 0x0000007d } },
+       { AR5K_RF_GAIN(49),     { 0x000000c6, 0x000000bd } },
+       { AR5K_RF_GAIN(50),     { 0x000000c6, 0x000000fd } },
+       { AR5K_RF_GAIN(51),     { 0x000000c6, 0x000000fd } },
+       { AR5K_RF_GAIN(52),     { 0x000000c6, 0x000000fd } },
+       { AR5K_RF_GAIN(53),     { 0x000000c6, 0x000000fd } },
+       { AR5K_RF_GAIN(54),     { 0x000000c6, 0x000000fd } },
+       { AR5K_RF_GAIN(55),     { 0x000000c6, 0x000000fd } },
+       { AR5K_RF_GAIN(56),     { 0x000000c6, 0x000000fd } },
+       { AR5K_RF_GAIN(57),     { 0x000000c6, 0x000000fd } },
+       { AR5K_RF_GAIN(58),     { 0x000000c6, 0x000000fd } },
+       { AR5K_RF_GAIN(59),     { 0x000000c6, 0x000000fd } },
+       { AR5K_RF_GAIN(60),     { 0x000000c6, 0x000000fd } },
+       { AR5K_RF_GAIN(61),     { 0x000000c6, 0x000000fd } },
+       { AR5K_RF_GAIN(62),     { 0x000000c6, 0x000000fd } },
+       { AR5K_RF_GAIN(63),     { 0x000000c6, 0x000000fd } },
+};
+
+/* Initial RF Gain settings for RF5112 */
+static const struct ath5k_ini_rfgain rfgain_5112[] = {
+       /*                            5Ghz      2Ghz    */
+       { AR5K_RF_GAIN(0),      { 0x00000007, 0x00000007 } },
+       { AR5K_RF_GAIN(1),      { 0x00000047, 0x00000047 } },
+       { AR5K_RF_GAIN(2),      { 0x00000087, 0x00000087 } },
+       { AR5K_RF_GAIN(3),      { 0x000001a0, 0x000001a0 } },
+       { AR5K_RF_GAIN(4),      { 0x000001e0, 0x000001e0 } },
+       { AR5K_RF_GAIN(5),      { 0x00000020, 0x00000020 } },
+       { AR5K_RF_GAIN(6),      { 0x00000060, 0x00000060 } },
+       { AR5K_RF_GAIN(7),      { 0x000001a1, 0x000001a1 } },
+       { AR5K_RF_GAIN(8),      { 0x000001e1, 0x000001e1 } },
+       { AR5K_RF_GAIN(9),      { 0x00000021, 0x00000021 } },
+       { AR5K_RF_GAIN(10),     { 0x00000061, 0x00000061 } },
+       { AR5K_RF_GAIN(11),     { 0x00000162, 0x00000162 } },
+       { AR5K_RF_GAIN(12),     { 0x000001a2, 0x000001a2 } },
+       { AR5K_RF_GAIN(13),     { 0x000001e2, 0x000001e2 } },
+       { AR5K_RF_GAIN(14),     { 0x00000022, 0x00000022 } },
+       { AR5K_RF_GAIN(15),     { 0x00000062, 0x00000062 } },
+       { AR5K_RF_GAIN(16),     { 0x00000163, 0x00000163 } },
+       { AR5K_RF_GAIN(17),     { 0x000001a3, 0x000001a3 } },
+       { AR5K_RF_GAIN(18),     { 0x000001e3, 0x000001e3 } },
+       { AR5K_RF_GAIN(19),     { 0x00000023, 0x00000023 } },
+       { AR5K_RF_GAIN(20),     { 0x00000063, 0x00000063 } },
+       { AR5K_RF_GAIN(21),     { 0x00000184, 0x00000184 } },
+       { AR5K_RF_GAIN(22),     { 0x000001c4, 0x000001c4 } },
+       { AR5K_RF_GAIN(23),     { 0x00000004, 0x00000004 } },
+       { AR5K_RF_GAIN(24),     { 0x000001ea, 0x0000000b } },
+       { AR5K_RF_GAIN(25),     { 0x0000002a, 0x0000004b } },
+       { AR5K_RF_GAIN(26),     { 0x0000006a, 0x0000008b } },
+       { AR5K_RF_GAIN(27),     { 0x000000aa, 0x000001ac } },
+       { AR5K_RF_GAIN(28),     { 0x000001ab, 0x000001ec } },
+       { AR5K_RF_GAIN(29),     { 0x000001eb, 0x0000002c } },
+       { AR5K_RF_GAIN(30),     { 0x0000002b, 0x00000012 } },
+       { AR5K_RF_GAIN(31),     { 0x0000006b, 0x00000052 } },
+       { AR5K_RF_GAIN(32),     { 0x000000ab, 0x00000092 } },
+       { AR5K_RF_GAIN(33),     { 0x000001ac, 0x00000193 } },
+       { AR5K_RF_GAIN(34),     { 0x000001ec, 0x000001d3 } },
+       { AR5K_RF_GAIN(35),     { 0x0000002c, 0x00000013 } },
+       { AR5K_RF_GAIN(36),     { 0x0000003a, 0x00000053 } },
+       { AR5K_RF_GAIN(37),     { 0x0000007a, 0x00000093 } },
+       { AR5K_RF_GAIN(38),     { 0x000000ba, 0x00000194 } },
+       { AR5K_RF_GAIN(39),     { 0x000001bb, 0x000001d4 } },
+       { AR5K_RF_GAIN(40),     { 0x000001fb, 0x00000014 } },
+       { AR5K_RF_GAIN(41),     { 0x0000003b, 0x0000003a } },
+       { AR5K_RF_GAIN(42),     { 0x0000007b, 0x0000007a } },
+       { AR5K_RF_GAIN(43),     { 0x000000bb, 0x000000ba } },
+       { AR5K_RF_GAIN(44),     { 0x000001bc, 0x000001bb } },
+       { AR5K_RF_GAIN(45),     { 0x000001fc, 0x000001fb } },
+       { AR5K_RF_GAIN(46),     { 0x0000003c, 0x0000003b } },
+       { AR5K_RF_GAIN(47),     { 0x0000007c, 0x0000007b } },
+       { AR5K_RF_GAIN(48),     { 0x000000bc, 0x000000bb } },
+       { AR5K_RF_GAIN(49),     { 0x000000fc, 0x000001bc } },
+       { AR5K_RF_GAIN(50),     { 0x000000fc, 0x000001fc } },
+       { AR5K_RF_GAIN(51),     { 0x000000fc, 0x0000003c } },
+       { AR5K_RF_GAIN(52),     { 0x000000fc, 0x0000007c } },
+       { AR5K_RF_GAIN(53),     { 0x000000fc, 0x000000bc } },
+       { AR5K_RF_GAIN(54),     { 0x000000fc, 0x000000fc } },
+       { AR5K_RF_GAIN(55),     { 0x000000fc, 0x000000fc } },
+       { AR5K_RF_GAIN(56),     { 0x000000fc, 0x000000fc } },
+       { AR5K_RF_GAIN(57),     { 0x000000fc, 0x000000fc } },
+       { AR5K_RF_GAIN(58),     { 0x000000fc, 0x000000fc } },
+       { AR5K_RF_GAIN(59),     { 0x000000fc, 0x000000fc } },
+       { AR5K_RF_GAIN(60),     { 0x000000fc, 0x000000fc } },
+       { AR5K_RF_GAIN(61),     { 0x000000fc, 0x000000fc } },
+       { AR5K_RF_GAIN(62),     { 0x000000fc, 0x000000fc } },
+       { AR5K_RF_GAIN(63),     { 0x000000fc, 0x000000fc } },
+};
+
+/* Initial RF Gain settings for RF2413 */
+static const struct ath5k_ini_rfgain rfgain_2413[] = {
+       { AR5K_RF_GAIN(0),      { 0x00000000, 0x00000000 } },
+       { AR5K_RF_GAIN(1),      { 0x00000000, 0x00000040 } },
+       { AR5K_RF_GAIN(2),      { 0x00000000, 0x00000080 } },
+       { AR5K_RF_GAIN(3),      { 0x00000000, 0x00000181 } },
+       { AR5K_RF_GAIN(4),      { 0x00000000, 0x000001c1 } },
+       { AR5K_RF_GAIN(5),      { 0x00000000, 0x00000001 } },
+       { AR5K_RF_GAIN(6),      { 0x00000000, 0x00000041 } },
+       { AR5K_RF_GAIN(7),      { 0x00000000, 0x00000081 } },
+       { AR5K_RF_GAIN(8),      { 0x00000000, 0x00000168 } },
+       { AR5K_RF_GAIN(9),      { 0x00000000, 0x000001a8 } },
+       { AR5K_RF_GAIN(10),     { 0x00000000, 0x000001e8 } },
+       { AR5K_RF_GAIN(11),     { 0x00000000, 0x00000028 } },
+       { AR5K_RF_GAIN(12),     { 0x00000000, 0x00000068 } },
+       { AR5K_RF_GAIN(13),     { 0x00000000, 0x00000189 } },
+       { AR5K_RF_GAIN(14),     { 0x00000000, 0x000001c9 } },
+       { AR5K_RF_GAIN(15),     { 0x00000000, 0x00000009 } },
+       { AR5K_RF_GAIN(16),     { 0x00000000, 0x00000049 } },
+       { AR5K_RF_GAIN(17),     { 0x00000000, 0x00000089 } },
+       { AR5K_RF_GAIN(18),     { 0x00000000, 0x00000190 } },
+       { AR5K_RF_GAIN(19),     { 0x00000000, 0x000001d0 } },
+       { AR5K_RF_GAIN(20),     { 0x00000000, 0x00000010 } },
+       { AR5K_RF_GAIN(21),     { 0x00000000, 0x00000050 } },
+       { AR5K_RF_GAIN(22),     { 0x00000000, 0x00000090 } },
+       { AR5K_RF_GAIN(23),     { 0x00000000, 0x00000191 } },
+       { AR5K_RF_GAIN(24),     { 0x00000000, 0x000001d1 } },
+       { AR5K_RF_GAIN(25),     { 0x00000000, 0x00000011 } },
+       { AR5K_RF_GAIN(26),     { 0x00000000, 0x00000051 } },
+       { AR5K_RF_GAIN(27),     { 0x00000000, 0x00000091 } },
+       { AR5K_RF_GAIN(28),     { 0x00000000, 0x00000178 } },
+       { AR5K_RF_GAIN(29),     { 0x00000000, 0x000001b8 } },
+       { AR5K_RF_GAIN(30),     { 0x00000000, 0x000001f8 } },
+       { AR5K_RF_GAIN(31),     { 0x00000000, 0x00000038 } },
+       { AR5K_RF_GAIN(32),     { 0x00000000, 0x00000078 } },
+       { AR5K_RF_GAIN(33),     { 0x00000000, 0x00000199 } },
+       { AR5K_RF_GAIN(34),     { 0x00000000, 0x000001d9 } },
+       { AR5K_RF_GAIN(35),     { 0x00000000, 0x00000019 } },
+       { AR5K_RF_GAIN(36),     { 0x00000000, 0x00000059 } },
+       { AR5K_RF_GAIN(37),     { 0x00000000, 0x00000099 } },
+       { AR5K_RF_GAIN(38),     { 0x00000000, 0x000000d9 } },
+       { AR5K_RF_GAIN(39),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(40),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(41),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(42),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(43),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(44),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(45),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(46),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(47),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(48),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(49),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(50),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(51),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(52),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(53),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(54),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(55),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(56),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(57),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(58),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(59),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(60),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(61),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(62),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(63),     { 0x00000000, 0x000000f9 } },
+};
+
+/* Initial RF Gain settings for AR2316 */
+static const struct ath5k_ini_rfgain rfgain_2316[] = {
+       { AR5K_RF_GAIN(0),      { 0x00000000, 0x00000000 } },
+       { AR5K_RF_GAIN(1),      { 0x00000000, 0x00000040 } },
+       { AR5K_RF_GAIN(2),      { 0x00000000, 0x00000080 } },
+       { AR5K_RF_GAIN(3),      { 0x00000000, 0x000000c0 } },
+       { AR5K_RF_GAIN(4),      { 0x00000000, 0x000000e0 } },
+       { AR5K_RF_GAIN(5),      { 0x00000000, 0x000000e0 } },
+       { AR5K_RF_GAIN(6),      { 0x00000000, 0x00000128 } },
+       { AR5K_RF_GAIN(7),      { 0x00000000, 0x00000128 } },
+       { AR5K_RF_GAIN(8),      { 0x00000000, 0x00000128 } },
+       { AR5K_RF_GAIN(9),      { 0x00000000, 0x00000168 } },
+       { AR5K_RF_GAIN(10),     { 0x00000000, 0x000001a8 } },
+       { AR5K_RF_GAIN(11),     { 0x00000000, 0x000001e8 } },
+       { AR5K_RF_GAIN(12),     { 0x00000000, 0x00000028 } },
+       { AR5K_RF_GAIN(13),     { 0x00000000, 0x00000068 } },
+       { AR5K_RF_GAIN(14),     { 0x00000000, 0x000000a8 } },
+       { AR5K_RF_GAIN(15),     { 0x00000000, 0x000000e8 } },
+       { AR5K_RF_GAIN(16),     { 0x00000000, 0x000000e8 } },
+       { AR5K_RF_GAIN(17),     { 0x00000000, 0x00000130 } },
+       { AR5K_RF_GAIN(18),     { 0x00000000, 0x00000130 } },
+       { AR5K_RF_GAIN(19),     { 0x00000000, 0x00000170 } },
+       { AR5K_RF_GAIN(20),     { 0x00000000, 0x000001b0 } },
+       { AR5K_RF_GAIN(21),     { 0x00000000, 0x000001f0 } },
+       { AR5K_RF_GAIN(22),     { 0x00000000, 0x00000030 } },
+       { AR5K_RF_GAIN(23),     { 0x00000000, 0x00000070 } },
+       { AR5K_RF_GAIN(24),     { 0x00000000, 0x000000b0 } },
+       { AR5K_RF_GAIN(25),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(26),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(27),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(28),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(29),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(30),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(31),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(32),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(33),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(34),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(35),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(36),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(37),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(38),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(39),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(40),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(41),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(42),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(43),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(44),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(45),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(46),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(47),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(48),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(49),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(50),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(51),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(52),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(53),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(54),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(55),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(56),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(57),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(58),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(59),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(60),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(61),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(62),     { 0x00000000, 0x000000f0 } },
+       { AR5K_RF_GAIN(63),     { 0x00000000, 0x000000f0 } },
+};
+
+
+/* Initial RF Gain settings for RF5413 */
+static const struct ath5k_ini_rfgain rfgain_5413[] = {
+       /*                            5Ghz      2Ghz    */
+       { AR5K_RF_GAIN(0),      { 0x00000000, 0x00000000 } },
+       { AR5K_RF_GAIN(1),      { 0x00000040, 0x00000040 } },
+       { AR5K_RF_GAIN(2),      { 0x00000080, 0x00000080 } },
+       { AR5K_RF_GAIN(3),      { 0x000001a1, 0x00000161 } },
+       { AR5K_RF_GAIN(4),      { 0x000001e1, 0x000001a1 } },
+       { AR5K_RF_GAIN(5),      { 0x00000021, 0x000001e1 } },
+       { AR5K_RF_GAIN(6),      { 0x00000061, 0x00000021 } },
+       { AR5K_RF_GAIN(7),      { 0x00000188, 0x00000061 } },
+       { AR5K_RF_GAIN(8),      { 0x000001c8, 0x00000188 } },
+       { AR5K_RF_GAIN(9),      { 0x00000008, 0x000001c8 } },
+       { AR5K_RF_GAIN(10),     { 0x00000048, 0x00000008 } },
+       { AR5K_RF_GAIN(11),     { 0x00000088, 0x00000048 } },
+       { AR5K_RF_GAIN(12),     { 0x000001a9, 0x00000088 } },
+       { AR5K_RF_GAIN(13),     { 0x000001e9, 0x00000169 } },
+       { AR5K_RF_GAIN(14),     { 0x00000029, 0x000001a9 } },
+       { AR5K_RF_GAIN(15),     { 0x00000069, 0x000001e9 } },
+       { AR5K_RF_GAIN(16),     { 0x000001d0, 0x00000029 } },
+       { AR5K_RF_GAIN(17),     { 0x00000010, 0x00000069 } },
+       { AR5K_RF_GAIN(18),     { 0x00000050, 0x00000190 } },
+       { AR5K_RF_GAIN(19),     { 0x00000090, 0x000001d0 } },
+       { AR5K_RF_GAIN(20),     { 0x000001b1, 0x00000010 } },
+       { AR5K_RF_GAIN(21),     { 0x000001f1, 0x00000050 } },
+       { AR5K_RF_GAIN(22),     { 0x00000031, 0x00000090 } },
+       { AR5K_RF_GAIN(23),     { 0x00000071, 0x00000171 } },
+       { AR5K_RF_GAIN(24),     { 0x000001b8, 0x000001b1 } },
+       { AR5K_RF_GAIN(25),     { 0x000001f8, 0x000001f1 } },
+       { AR5K_RF_GAIN(26),     { 0x00000038, 0x00000031 } },
+       { AR5K_RF_GAIN(27),     { 0x00000078, 0x00000071 } },
+       { AR5K_RF_GAIN(28),     { 0x00000199, 0x00000198 } },
+       { AR5K_RF_GAIN(29),     { 0x000001d9, 0x000001d8 } },
+       { AR5K_RF_GAIN(30),     { 0x00000019, 0x00000018 } },
+       { AR5K_RF_GAIN(31),     { 0x00000059, 0x00000058 } },
+       { AR5K_RF_GAIN(32),     { 0x00000099, 0x00000098 } },
+       { AR5K_RF_GAIN(33),     { 0x000000d9, 0x00000179 } },
+       { AR5K_RF_GAIN(34),     { 0x000000f9, 0x000001b9 } },
+       { AR5K_RF_GAIN(35),     { 0x000000f9, 0x000001f9 } },
+       { AR5K_RF_GAIN(36),     { 0x000000f9, 0x00000039 } },
+       { AR5K_RF_GAIN(37),     { 0x000000f9, 0x00000079 } },
+       { AR5K_RF_GAIN(38),     { 0x000000f9, 0x000000b9 } },
+       { AR5K_RF_GAIN(39),     { 0x000000f9, 0x000000f9 } },
+       { AR5K_RF_GAIN(40),     { 0x000000f9, 0x000000f9 } },
+       { AR5K_RF_GAIN(41),     { 0x000000f9, 0x000000f9 } },
+       { AR5K_RF_GAIN(42),     { 0x000000f9, 0x000000f9 } },
+       { AR5K_RF_GAIN(43),     { 0x000000f9, 0x000000f9 } },
+       { AR5K_RF_GAIN(44),     { 0x000000f9, 0x000000f9 } },
+       { AR5K_RF_GAIN(45),     { 0x000000f9, 0x000000f9 } },
+       { AR5K_RF_GAIN(46),     { 0x000000f9, 0x000000f9 } },
+       { AR5K_RF_GAIN(47),     { 0x000000f9, 0x000000f9 } },
+       { AR5K_RF_GAIN(48),     { 0x000000f9, 0x000000f9 } },
+       { AR5K_RF_GAIN(49),     { 0x000000f9, 0x000000f9 } },
+       { AR5K_RF_GAIN(50),     { 0x000000f9, 0x000000f9 } },
+       { AR5K_RF_GAIN(51),     { 0x000000f9, 0x000000f9 } },
+       { AR5K_RF_GAIN(52),     { 0x000000f9, 0x000000f9 } },
+       { AR5K_RF_GAIN(53),     { 0x000000f9, 0x000000f9 } },
+       { AR5K_RF_GAIN(54),     { 0x000000f9, 0x000000f9 } },
+       { AR5K_RF_GAIN(55),     { 0x000000f9, 0x000000f9 } },
+       { AR5K_RF_GAIN(56),     { 0x000000f9, 0x000000f9 } },
+       { AR5K_RF_GAIN(57),     { 0x000000f9, 0x000000f9 } },
+       { AR5K_RF_GAIN(58),     { 0x000000f9, 0x000000f9 } },
+       { AR5K_RF_GAIN(59),     { 0x000000f9, 0x000000f9 } },
+       { AR5K_RF_GAIN(60),     { 0x000000f9, 0x000000f9 } },
+       { AR5K_RF_GAIN(61),     { 0x000000f9, 0x000000f9 } },
+       { AR5K_RF_GAIN(62),     { 0x000000f9, 0x000000f9 } },
+       { AR5K_RF_GAIN(63),     { 0x000000f9, 0x000000f9 } },
+};
+
+
+/* Initial RF Gain settings for RF2425 */
+static const struct ath5k_ini_rfgain rfgain_2425[] = {
+       { AR5K_RF_GAIN(0),      { 0x00000000, 0x00000000 } },
+       { AR5K_RF_GAIN(1),      { 0x00000000, 0x00000040 } },
+       { AR5K_RF_GAIN(2),      { 0x00000000, 0x00000080 } },
+       { AR5K_RF_GAIN(3),      { 0x00000000, 0x00000181 } },
+       { AR5K_RF_GAIN(4),      { 0x00000000, 0x000001c1 } },
+       { AR5K_RF_GAIN(5),      { 0x00000000, 0x00000001 } },
+       { AR5K_RF_GAIN(6),      { 0x00000000, 0x00000041 } },
+       { AR5K_RF_GAIN(7),      { 0x00000000, 0x00000081 } },
+       { AR5K_RF_GAIN(8),      { 0x00000000, 0x00000188 } },
+       { AR5K_RF_GAIN(9),      { 0x00000000, 0x000001c8 } },
+       { AR5K_RF_GAIN(10),     { 0x00000000, 0x00000008 } },
+       { AR5K_RF_GAIN(11),     { 0x00000000, 0x00000048 } },
+       { AR5K_RF_GAIN(12),     { 0x00000000, 0x00000088 } },
+       { AR5K_RF_GAIN(13),     { 0x00000000, 0x00000189 } },
+       { AR5K_RF_GAIN(14),     { 0x00000000, 0x000001c9 } },
+       { AR5K_RF_GAIN(15),     { 0x00000000, 0x00000009 } },
+       { AR5K_RF_GAIN(16),     { 0x00000000, 0x00000049 } },
+       { AR5K_RF_GAIN(17),     { 0x00000000, 0x00000089 } },
+       { AR5K_RF_GAIN(18),     { 0x00000000, 0x000001b0 } },
+       { AR5K_RF_GAIN(19),     { 0x00000000, 0x000001f0 } },
+       { AR5K_RF_GAIN(20),     { 0x00000000, 0x00000030 } },
+       { AR5K_RF_GAIN(21),     { 0x00000000, 0x00000070 } },
+       { AR5K_RF_GAIN(22),     { 0x00000000, 0x00000171 } },
+       { AR5K_RF_GAIN(23),     { 0x00000000, 0x000001b1 } },
+       { AR5K_RF_GAIN(24),     { 0x00000000, 0x000001f1 } },
+       { AR5K_RF_GAIN(25),     { 0x00000000, 0x00000031 } },
+       { AR5K_RF_GAIN(26),     { 0x00000000, 0x00000071 } },
+       { AR5K_RF_GAIN(27),     { 0x00000000, 0x000001b8 } },
+       { AR5K_RF_GAIN(28),     { 0x00000000, 0x000001f8 } },
+       { AR5K_RF_GAIN(29),     { 0x00000000, 0x00000038 } },
+       { AR5K_RF_GAIN(30),     { 0x00000000, 0x00000078 } },
+       { AR5K_RF_GAIN(31),     { 0x00000000, 0x000000b8 } },
+       { AR5K_RF_GAIN(32),     { 0x00000000, 0x000001b9 } },
+       { AR5K_RF_GAIN(33),     { 0x00000000, 0x000001f9 } },
+       { AR5K_RF_GAIN(34),     { 0x00000000, 0x00000039 } },
+       { AR5K_RF_GAIN(35),     { 0x00000000, 0x00000079 } },
+       { AR5K_RF_GAIN(36),     { 0x00000000, 0x000000b9 } },
+       { AR5K_RF_GAIN(37),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(38),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(39),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(40),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(41),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(42),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(43),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(44),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(45),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(46),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(47),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(48),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(49),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(50),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(51),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(52),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(53),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(54),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(55),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(56),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(57),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(58),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(59),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(60),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(61),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(62),     { 0x00000000, 0x000000f9 } },
+       { AR5K_RF_GAIN(63),     { 0x00000000, 0x000000f9 } },
+};
+
+#define AR5K_GAIN_CRN_FIX_BITS_5111            4
+#define AR5K_GAIN_CRN_FIX_BITS_5112            7
+#define AR5K_GAIN_CRN_MAX_FIX_BITS             AR5K_GAIN_CRN_FIX_BITS_5112
+#define AR5K_GAIN_DYN_ADJUST_HI_MARGIN         15
+#define AR5K_GAIN_DYN_ADJUST_LO_MARGIN         20
+#define AR5K_GAIN_CCK_PROBE_CORR               5
+#define AR5K_GAIN_CCK_OFDM_GAIN_DELTA          15
+#define AR5K_GAIN_STEP_COUNT                   10
+
+/* Check if our current measurement is inside our
+ * current variable attenuation window */
+#define AR5K_GAIN_CHECK_ADJUST(_g)             \
+       ((_g)->g_current <= (_g)->g_low || (_g)->g_current >= (_g)->g_high)
+
+struct ath5k_gain_opt_step {
+       s8                              gos_param[AR5K_GAIN_CRN_MAX_FIX_BITS];
+       s8                              gos_gain;
+};
+
+struct ath5k_gain_opt {
+       u8                              go_default;
+       u8                              go_steps_count;
+       const struct ath5k_gain_opt_step        go_step[AR5K_GAIN_STEP_COUNT];
+};
+
+/*
+ * Parameters on gos_param:
+ * 1) Tx clip PHY register
+ * 2) PWD 90 RF register
+ * 3) PWD 84 RF register
+ * 4) RFGainSel RF register
+ */
+static const struct ath5k_gain_opt rfgain_opt_5111 = {
+       4,
+       9,
+       {
+               { { 4, 1, 1, 1 }, 6 },
+               { { 4, 0, 1, 1 }, 4 },
+               { { 3, 1, 1, 1 }, 3 },
+               { { 4, 0, 0, 1 }, 1 },
+               { { 4, 1, 1, 0 }, 0 },
+               { { 4, 0, 1, 0 }, -2 },
+               { { 3, 1, 1, 0 }, -3 },
+               { { 4, 0, 0, 0 }, -4 },
+               { { 2, 1, 1, 0 }, -6 }
+       }
+};
+
+/*
+ * Parameters on gos_param:
+ * 1) Mixgain ovr RF register
+ * 2) PWD 138 RF register
+ * 3) PWD 137 RF register
+ * 4) PWD 136 RF register
+ * 5) PWD 132 RF register
+ * 6) PWD 131 RF register
+ * 7) PWD 130 RF register
+ */
+static const struct ath5k_gain_opt rfgain_opt_5112 = {
+       1,
+       8,
+       {
+               { { 3, 0, 0, 0, 0, 0, 0 }, 6 },
+               { { 2, 0, 0, 0, 0, 0, 0 }, 0 },
+               { { 1, 0, 0, 0, 0, 0, 0 }, -3 },
+               { { 0, 0, 0, 0, 0, 0, 0 }, -6 },
+               { { 0, 1, 1, 0, 0, 0, 0 }, -8 },
+               { { 0, 1, 1, 0, 1, 1, 0 }, -10 },
+               { { 0, 1, 0, 1, 1, 1, 0 }, -13 },
+               { { 0, 1, 0, 1, 1, 0, 1 }, -16 },
+       }
+};
+
diff --git a/drivers/net/wireless/ath/ath5k/rfkill.c b/drivers/net/wireless/ath/ath5k/rfkill.c
new file mode 100644 (file)
index 0000000..41a877b
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ * RFKILL support for ath5k
+ *
+ * Copyright (c) 2009 Tobias Doerffel <tobias.doerffel@gmail.com>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
+ *    redistribution must be conditioned upon including a substantially
+ *    similar Disclaimer requirement for further binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include "base.h"
+
+
+static inline void ath5k_rfkill_disable(struct ath5k_softc *sc)
+{
+       ATH5K_DBG(sc, ATH5K_DEBUG_ANY, "rfkill disable (gpio:%d polarity:%d)\n",
+               sc->rf_kill.gpio, sc->rf_kill.polarity);
+       ath5k_hw_set_gpio_output(sc->ah, sc->rf_kill.gpio);
+       ath5k_hw_set_gpio(sc->ah, sc->rf_kill.gpio, !sc->rf_kill.polarity);
+}
+
+
+static inline void ath5k_rfkill_enable(struct ath5k_softc *sc)
+{
+       ATH5K_DBG(sc, ATH5K_DEBUG_ANY, "rfkill enable (gpio:%d polarity:%d)\n",
+               sc->rf_kill.gpio, sc->rf_kill.polarity);
+       ath5k_hw_set_gpio_output(sc->ah, sc->rf_kill.gpio);
+       ath5k_hw_set_gpio(sc->ah, sc->rf_kill.gpio, sc->rf_kill.polarity);
+}
+
+static inline void ath5k_rfkill_set_intr(struct ath5k_softc *sc, bool enable)
+{
+       struct ath5k_hw *ah = sc->ah;
+       u32 curval;
+
+       ath5k_hw_set_gpio_input(ah, sc->rf_kill.gpio);
+       curval = ath5k_hw_get_gpio(ah, sc->rf_kill.gpio);
+       ath5k_hw_set_gpio_intr(ah, sc->rf_kill.gpio, enable ?
+                                       !!curval : !curval);
+}
+
+static bool
+ath5k_is_rfkill_set(struct ath5k_softc *sc)
+{
+       /* configuring GPIO for input for some reason disables rfkill */
+       /*ath5k_hw_set_gpio_input(sc->ah, sc->rf_kill.gpio);*/
+       return ath5k_hw_get_gpio(sc->ah, sc->rf_kill.gpio) ==
+                                                       sc->rf_kill.polarity;
+}
+
+static void
+ath5k_tasklet_rfkill_toggle(unsigned long data)
+{
+       struct ath5k_softc *sc = (void *)data;
+       bool blocked;
+
+       blocked = ath5k_is_rfkill_set(sc);
+       wiphy_rfkill_set_hw_state(sc->hw->wiphy, blocked);
+}
+
+
+void
+ath5k_rfkill_hw_start(struct ath5k_hw *ah)
+{
+       struct ath5k_softc *sc = ah->ah_sc;
+
+       /* read rfkill GPIO configuration from EEPROM header */
+       sc->rf_kill.gpio = ah->ah_capabilities.cap_eeprom.ee_rfkill_pin;
+       sc->rf_kill.polarity = ah->ah_capabilities.cap_eeprom.ee_rfkill_pol;
+
+       tasklet_init(&sc->rf_kill.toggleq, ath5k_tasklet_rfkill_toggle,
+               (unsigned long)sc);
+
+       ath5k_rfkill_disable(sc);
+
+       /* enable interrupt for rfkill switch */
+       if (AR5K_EEPROM_HDR_RFKILL(ah->ah_capabilities.cap_eeprom.ee_header))
+               ath5k_rfkill_set_intr(sc, true);
+}
+
+
+void
+ath5k_rfkill_hw_stop(struct ath5k_hw *ah)
+{
+       struct ath5k_softc *sc = ah->ah_sc;
+
+       /* disable interrupt for rfkill switch */
+       if (AR5K_EEPROM_HDR_RFKILL(ah->ah_capabilities.cap_eeprom.ee_header))
+               ath5k_rfkill_set_intr(sc, false);
+
+       tasklet_kill(&sc->rf_kill.toggleq);
+
+       /* enable RFKILL when stopping HW so Wifi LED is turned off */
+       ath5k_rfkill_enable(sc);
+}
+
diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig
new file mode 100644 (file)
index 0000000..0ed1ac3
--- /dev/null
@@ -0,0 +1,24 @@
+config ATH9K
+       tristate "Atheros 802.11n wireless cards support"
+       depends on PCI && MAC80211 && WLAN_80211
+       depends on RFKILL || RFKILL=n
+       select ATH_COMMON
+       select MAC80211_LEDS
+       select LEDS_CLASS
+       select NEW_LEDS
+       ---help---
+         This module adds support for wireless adapters based on
+         Atheros IEEE 802.11n AR5008 and AR9001 family of chipsets.
+
+         If you choose to build a module, it'll be called ath9k.
+
+config ATH9K_DEBUG
+       bool "Atheros ath9k debugging"
+       depends on ATH9K
+       ---help---
+         Say Y, if you need ath9k to display debug messages.
+         Pass the debug mask as a module parameter:
+
+         modprobe ath9k debug=0x00002000
+
+         Look in ath9k/core.h for possible debug masks
diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile
new file mode 100644 (file)
index 0000000..783bc39
--- /dev/null
@@ -0,0 +1,18 @@
+ath9k-y +=     hw.o \
+               eeprom.o \
+               mac.o \
+               calib.o \
+               ani.o \
+               phy.o \
+               beacon.o \
+               main.o \
+               recv.o \
+               xmit.o \
+               virtual.o \
+               rc.o
+
+ath9k-$(CONFIG_PCI) += pci.o
+ath9k-$(CONFIG_ATHEROS_AR71XX) += ahb.o
+ath9k-$(CONFIG_ATH9K_DEBUG) += debug.o
+
+obj-$(CONFIG_ATH9K) += ath9k.o
diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c
new file mode 100644 (file)
index 0000000..0e65c51
--- /dev/null
@@ -0,0 +1,192 @@
+/*
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
+ * Copyright (c) 2009 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (c) 2009 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * 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/nl80211.h>
+#include <linux/platform_device.h>
+#include <linux/ath9k_platform.h>
+#include "ath9k.h"
+
+/* return bus cachesize in 4B word units */
+static void ath_ahb_read_cachesize(struct ath_softc *sc, int *csz)
+{
+       *csz = L1_CACHE_BYTES >> 2;
+}
+
+static void ath_ahb_cleanup(struct ath_softc *sc)
+{
+       iounmap(sc->mem);
+}
+
+static bool ath_ahb_eeprom_read(struct ath_hw *ah, u32 off, u16 *data)
+{
+       struct ath_softc *sc = ah->ah_sc;
+       struct platform_device *pdev = to_platform_device(sc->dev);
+       struct ath9k_platform_data *pdata;
+
+       pdata = (struct ath9k_platform_data *) pdev->dev.platform_data;
+       if (off >= (ARRAY_SIZE(pdata->eeprom_data))) {
+               DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+                       "%s: flash read failed, offset %08x is out of range\n",
+                               __func__, off);
+               return false;
+       }
+
+       *data = pdata->eeprom_data[off];
+       return true;
+}
+
+static struct ath_bus_ops ath_ahb_bus_ops  = {
+       .read_cachesize = ath_ahb_read_cachesize,
+       .cleanup = ath_ahb_cleanup,
+
+       .eeprom_read = ath_ahb_eeprom_read,
+};
+
+static int ath_ahb_probe(struct platform_device *pdev)
+{
+       void __iomem *mem;
+       struct ath_wiphy *aphy;
+       struct ath_softc *sc;
+       struct ieee80211_hw *hw;
+       struct resource *res;
+       int irq;
+       int ret = 0;
+       struct ath_hw *ah;
+
+       if (!pdev->dev.platform_data) {
+               dev_err(&pdev->dev, "no platform data specified\n");
+               ret = -EINVAL;
+               goto err_out;
+       }
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (res == NULL) {
+               dev_err(&pdev->dev, "no memory resource found\n");
+               ret = -ENXIO;
+               goto err_out;
+       }
+
+       mem = ioremap_nocache(res->start, res->end - res->start + 1);
+       if (mem == NULL) {
+               dev_err(&pdev->dev, "ioremap failed\n");
+               ret = -ENOMEM;
+               goto err_out;
+       }
+
+       res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+       if (res == NULL) {
+               dev_err(&pdev->dev, "no IRQ resource found\n");
+               ret = -ENXIO;
+               goto err_iounmap;
+       }
+
+       irq = res->start;
+
+       hw = ieee80211_alloc_hw(sizeof(struct ath_wiphy) +
+                               sizeof(struct ath_softc), &ath9k_ops);
+       if (hw == NULL) {
+               dev_err(&pdev->dev, "no memory for ieee80211_hw\n");
+               ret = -ENOMEM;
+               goto err_iounmap;
+       }
+
+       SET_IEEE80211_DEV(hw, &pdev->dev);
+       platform_set_drvdata(pdev, hw);
+
+       aphy = hw->priv;
+       sc = (struct ath_softc *) (aphy + 1);
+       aphy->sc = sc;
+       aphy->hw = hw;
+       sc->pri_wiphy = aphy;
+       sc->hw = hw;
+       sc->dev = &pdev->dev;
+       sc->mem = mem;
+       sc->bus_ops = &ath_ahb_bus_ops;
+       sc->irq = irq;
+
+       ret = ath_attach(AR5416_AR9100_DEVID, sc);
+       if (ret != 0) {
+               dev_err(&pdev->dev, "failed to attach device, err=%d\n", ret);
+               ret = -ENODEV;
+               goto err_free_hw;
+       }
+
+       ret = request_irq(irq, ath_isr, IRQF_SHARED, "ath9k", sc);
+       if (ret) {
+               dev_err(&pdev->dev, "request_irq failed, err=%d\n", ret);
+               ret = -EIO;
+               goto err_detach;
+       }
+
+       ah = sc->sc_ah;
+       printk(KERN_INFO
+              "%s: Atheros AR%s MAC/BB Rev:%x, "
+              "AR%s RF Rev:%x, mem=0x%lx, irq=%d\n",
+              wiphy_name(hw->wiphy),
+              ath_mac_bb_name(ah->hw_version.macVersion),
+              ah->hw_version.macRev,
+              ath_rf_name((ah->hw_version.analog5GhzRev & AR_RADIO_SREV_MAJOR)),
+              ah->hw_version.phyRev,
+              (unsigned long)mem, irq);
+
+       return 0;
+
+ err_detach:
+       ath_detach(sc);
+ err_free_hw:
+       ieee80211_free_hw(hw);
+       platform_set_drvdata(pdev, NULL);
+ err_iounmap:
+       iounmap(mem);
+ err_out:
+       return ret;
+}
+
+static int ath_ahb_remove(struct platform_device *pdev)
+{
+       struct ieee80211_hw *hw = platform_get_drvdata(pdev);
+
+       if (hw) {
+               struct ath_wiphy *aphy = hw->priv;
+               struct ath_softc *sc = aphy->sc;
+
+               ath_cleanup(sc);
+               platform_set_drvdata(pdev, NULL);
+       }
+
+       return 0;
+}
+
+static struct platform_driver ath_ahb_driver = {
+       .probe      = ath_ahb_probe,
+       .remove     = ath_ahb_remove,
+       .driver         = {
+               .name   = "ath9k",
+               .owner  = THIS_MODULE,
+       },
+};
+
+int ath_ahb_init(void)
+{
+       return platform_driver_register(&ath_ahb_driver);
+}
+
+void ath_ahb_exit(void)
+{
+       platform_driver_unregister(&ath_ahb_driver);
+}
diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c
new file mode 100644 (file)
index 0000000..1aeafb5
--- /dev/null
@@ -0,0 +1,822 @@
+/*
+ * Copyright (c) 2008-2009 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 "ath9k.h"
+
+static int ath9k_hw_get_ani_channel_idx(struct ath_hw *ah,
+                                       struct ath9k_channel *chan)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(ah->ani); i++) {
+               if (ah->ani[i].c &&
+                   ah->ani[i].c->channel == chan->channel)
+                       return i;
+               if (ah->ani[i].c == NULL) {
+                       ah->ani[i].c = chan;
+                       return i;
+               }
+       }
+
+       DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+               "No more channel states left. Using channel 0\n");
+
+       return 0;
+}
+
+static bool ath9k_hw_ani_control(struct ath_hw *ah,
+                                enum ath9k_ani_cmd cmd, int param)
+{
+       struct ar5416AniState *aniState = ah->curani;
+
+       switch (cmd & ah->ani_function) {
+       case ATH9K_ANI_NOISE_IMMUNITY_LEVEL:{
+               u32 level = param;
+
+               if (level >= ARRAY_SIZE(ah->totalSizeDesired)) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+                               "level out of range (%u > %u)\n",
+                               level,
+                               (unsigned)ARRAY_SIZE(ah->totalSizeDesired));
+                       return false;
+               }
+
+               REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
+                             AR_PHY_DESIRED_SZ_TOT_DES,
+                             ah->totalSizeDesired[level]);
+               REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1,
+                             AR_PHY_AGC_CTL1_COARSE_LOW,
+                             ah->coarse_low[level]);
+               REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1,
+                             AR_PHY_AGC_CTL1_COARSE_HIGH,
+                             ah->coarse_high[level]);
+               REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
+                             AR_PHY_FIND_SIG_FIRPWR,
+                             ah->firpwr[level]);
+
+               if (level > aniState->noiseImmunityLevel)
+                       ah->stats.ast_ani_niup++;
+               else if (level < aniState->noiseImmunityLevel)
+                       ah->stats.ast_ani_nidown++;
+               aniState->noiseImmunityLevel = level;
+               break;
+       }
+       case ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION:{
+               const int m1ThreshLow[] = { 127, 50 };
+               const int m2ThreshLow[] = { 127, 40 };
+               const int m1Thresh[] = { 127, 0x4d };
+               const int m2Thresh[] = { 127, 0x40 };
+               const int m2CountThr[] = { 31, 16 };
+               const int m2CountThrLow[] = { 63, 48 };
+               u32 on = param ? 1 : 0;
+
+               REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
+                             AR_PHY_SFCORR_LOW_M1_THRESH_LOW,
+                             m1ThreshLow[on]);
+               REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
+                             AR_PHY_SFCORR_LOW_M2_THRESH_LOW,
+                             m2ThreshLow[on]);
+               REG_RMW_FIELD(ah, AR_PHY_SFCORR,
+                             AR_PHY_SFCORR_M1_THRESH,
+                             m1Thresh[on]);
+               REG_RMW_FIELD(ah, AR_PHY_SFCORR,
+                             AR_PHY_SFCORR_M2_THRESH,
+                             m2Thresh[on]);
+               REG_RMW_FIELD(ah, AR_PHY_SFCORR,
+                             AR_PHY_SFCORR_M2COUNT_THR,
+                             m2CountThr[on]);
+               REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
+                             AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW,
+                             m2CountThrLow[on]);
+
+               REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
+                             AR_PHY_SFCORR_EXT_M1_THRESH_LOW,
+                             m1ThreshLow[on]);
+               REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
+                             AR_PHY_SFCORR_EXT_M2_THRESH_LOW,
+                             m2ThreshLow[on]);
+               REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
+                             AR_PHY_SFCORR_EXT_M1_THRESH,
+                             m1Thresh[on]);
+               REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
+                             AR_PHY_SFCORR_EXT_M2_THRESH,
+                             m2Thresh[on]);
+
+               if (on)
+                       REG_SET_BIT(ah, AR_PHY_SFCORR_LOW,
+                                   AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
+               else
+                       REG_CLR_BIT(ah, AR_PHY_SFCORR_LOW,
+                                   AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
+
+               if (!on != aniState->ofdmWeakSigDetectOff) {
+                       if (on)
+                               ah->stats.ast_ani_ofdmon++;
+                       else
+                               ah->stats.ast_ani_ofdmoff++;
+                       aniState->ofdmWeakSigDetectOff = !on;
+               }
+               break;
+       }
+       case ATH9K_ANI_CCK_WEAK_SIGNAL_THR:{
+               const int weakSigThrCck[] = { 8, 6 };
+               u32 high = param ? 1 : 0;
+
+               REG_RMW_FIELD(ah, AR_PHY_CCK_DETECT,
+                             AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK,
+                             weakSigThrCck[high]);
+               if (high != aniState->cckWeakSigThreshold) {
+                       if (high)
+                               ah->stats.ast_ani_cckhigh++;
+                       else
+                               ah->stats.ast_ani_ccklow++;
+                       aniState->cckWeakSigThreshold = high;
+               }
+               break;
+       }
+       case ATH9K_ANI_FIRSTEP_LEVEL:{
+               const int firstep[] = { 0, 4, 8 };
+               u32 level = param;
+
+               if (level >= ARRAY_SIZE(firstep)) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+                               "level out of range (%u > %u)\n",
+                               level,
+                               (unsigned) ARRAY_SIZE(firstep));
+                       return false;
+               }
+               REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
+                             AR_PHY_FIND_SIG_FIRSTEP,
+                             firstep[level]);
+               if (level > aniState->firstepLevel)
+                       ah->stats.ast_ani_stepup++;
+               else if (level < aniState->firstepLevel)
+                       ah->stats.ast_ani_stepdown++;
+               aniState->firstepLevel = level;
+               break;
+       }
+       case ATH9K_ANI_SPUR_IMMUNITY_LEVEL:{
+               const int cycpwrThr1[] =
+                       { 2, 4, 6, 8, 10, 12, 14, 16 };
+               u32 level = param;
+
+               if (level >= ARRAY_SIZE(cycpwrThr1)) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+                               "level out of range (%u > %u)\n",
+                               level,
+                               (unsigned)
+                               ARRAY_SIZE(cycpwrThr1));
+                       return false;
+               }
+               REG_RMW_FIELD(ah, AR_PHY_TIMING5,
+                             AR_PHY_TIMING5_CYCPWR_THR1,
+                             cycpwrThr1[level]);
+               if (level > aniState->spurImmunityLevel)
+                       ah->stats.ast_ani_spurup++;
+               else if (level < aniState->spurImmunityLevel)
+                       ah->stats.ast_ani_spurdown++;
+               aniState->spurImmunityLevel = level;
+               break;
+       }
+       case ATH9K_ANI_PRESENT:
+               break;
+       default:
+               DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+                       "invalid cmd %u\n", cmd);
+               return false;
+       }
+
+       DPRINTF(ah->ah_sc, ATH_DBG_ANI, "ANI parameters:\n");
+       DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+               "noiseImmunityLevel=%d, spurImmunityLevel=%d, "
+               "ofdmWeakSigDetectOff=%d\n",
+               aniState->noiseImmunityLevel, aniState->spurImmunityLevel,
+               !aniState->ofdmWeakSigDetectOff);
+       DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+               "cckWeakSigThreshold=%d, "
+               "firstepLevel=%d, listenTime=%d\n",
+               aniState->cckWeakSigThreshold, aniState->firstepLevel,
+               aniState->listenTime);
+       DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+               "cycleCount=%d, ofdmPhyErrCount=%d, cckPhyErrCount=%d\n\n",
+               aniState->cycleCount, aniState->ofdmPhyErrCount,
+               aniState->cckPhyErrCount);
+
+       return true;
+}
+
+static void ath9k_hw_update_mibstats(struct ath_hw *ah,
+                                    struct ath9k_mib_stats *stats)
+{
+       stats->ackrcv_bad += REG_READ(ah, AR_ACK_FAIL);
+       stats->rts_bad += REG_READ(ah, AR_RTS_FAIL);
+       stats->fcs_bad += REG_READ(ah, AR_FCS_FAIL);
+       stats->rts_good += REG_READ(ah, AR_RTS_OK);
+       stats->beacons += REG_READ(ah, AR_BEACON_CNT);
+}
+
+static void ath9k_ani_restart(struct ath_hw *ah)
+{
+       struct ar5416AniState *aniState;
+
+       if (!DO_ANI(ah))
+               return;
+
+       aniState = ah->curani;
+
+       aniState->listenTime = 0;
+       if (ah->has_hw_phycounters) {
+               if (aniState->ofdmTrigHigh > AR_PHY_COUNTMAX) {
+                       aniState->ofdmPhyErrBase = 0;
+                       DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+                               "OFDM Trigger is too high for hw counters\n");
+               } else {
+                       aniState->ofdmPhyErrBase =
+                               AR_PHY_COUNTMAX - aniState->ofdmTrigHigh;
+               }
+               if (aniState->cckTrigHigh > AR_PHY_COUNTMAX) {
+                       aniState->cckPhyErrBase = 0;
+                       DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+                               "CCK Trigger is too high for hw counters\n");
+               } else {
+                       aniState->cckPhyErrBase =
+                               AR_PHY_COUNTMAX - aniState->cckTrigHigh;
+               }
+               DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+                       "Writing ofdmbase=%u   cckbase=%u\n",
+                       aniState->ofdmPhyErrBase,
+                       aniState->cckPhyErrBase);
+               REG_WRITE(ah, AR_PHY_ERR_1, aniState->ofdmPhyErrBase);
+               REG_WRITE(ah, AR_PHY_ERR_2, aniState->cckPhyErrBase);
+               REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
+               REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
+
+               ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
+       }
+       aniState->ofdmPhyErrCount = 0;
+       aniState->cckPhyErrCount = 0;
+}
+
+static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hw *ah)
+{
+       struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
+       struct ar5416AniState *aniState;
+       int32_t rssi;
+
+       if (!DO_ANI(ah))
+               return;
+
+       aniState = ah->curani;
+
+       if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) {
+               if (ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
+                                        aniState->noiseImmunityLevel + 1)) {
+                       return;
+               }
+       }
+
+       if (aniState->spurImmunityLevel < HAL_SPUR_IMMUNE_MAX) {
+               if (ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL,
+                                        aniState->spurImmunityLevel + 1)) {
+                       return;
+               }
+       }
+
+       if (ah->opmode == NL80211_IFTYPE_AP) {
+               if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) {
+                       ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
+                                            aniState->firstepLevel + 1);
+               }
+               return;
+       }
+       rssi = BEACON_RSSI(ah);
+       if (rssi > aniState->rssiThrHigh) {
+               if (!aniState->ofdmWeakSigDetectOff) {
+                       if (ath9k_hw_ani_control(ah,
+                                        ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
+                                        false)) {
+                               ath9k_hw_ani_control(ah,
+                                       ATH9K_ANI_SPUR_IMMUNITY_LEVEL, 0);
+                               return;
+                       }
+               }
+               if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) {
+                       ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
+                                            aniState->firstepLevel + 1);
+                       return;
+               }
+       } else if (rssi > aniState->rssiThrLow) {
+               if (aniState->ofdmWeakSigDetectOff)
+                       ath9k_hw_ani_control(ah,
+                                    ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
+                                    true);
+               if (aniState->firstepLevel < HAL_FIRST_STEP_MAX)
+                       ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
+                                            aniState->firstepLevel + 1);
+               return;
+       } else {
+               if (conf->channel->band == IEEE80211_BAND_2GHZ) {
+                       if (!aniState->ofdmWeakSigDetectOff)
+                               ath9k_hw_ani_control(ah,
+                                    ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
+                                    false);
+                       if (aniState->firstepLevel > 0)
+                               ath9k_hw_ani_control(ah,
+                                            ATH9K_ANI_FIRSTEP_LEVEL, 0);
+                       return;
+               }
+       }
+}
+
+static void ath9k_hw_ani_cck_err_trigger(struct ath_hw *ah)
+{
+       struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
+       struct ar5416AniState *aniState;
+       int32_t rssi;
+
+       if (!DO_ANI(ah))
+               return;
+
+       aniState = ah->curani;
+       if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) {
+               if (ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
+                                        aniState->noiseImmunityLevel + 1)) {
+                       return;
+               }
+       }
+       if (ah->opmode == NL80211_IFTYPE_AP) {
+               if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) {
+                       ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
+                                            aniState->firstepLevel + 1);
+               }
+               return;
+       }
+       rssi = BEACON_RSSI(ah);
+       if (rssi > aniState->rssiThrLow) {
+               if (aniState->firstepLevel < HAL_FIRST_STEP_MAX)
+                       ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
+                                            aniState->firstepLevel + 1);
+       } else {
+               if (conf->channel->band == IEEE80211_BAND_2GHZ) {
+                       if (aniState->firstepLevel > 0)
+                               ath9k_hw_ani_control(ah,
+                                            ATH9K_ANI_FIRSTEP_LEVEL, 0);
+               }
+       }
+}
+
+static void ath9k_hw_ani_lower_immunity(struct ath_hw *ah)
+{
+       struct ar5416AniState *aniState;
+       int32_t rssi;
+
+       aniState = ah->curani;
+
+       if (ah->opmode == NL80211_IFTYPE_AP) {
+               if (aniState->firstepLevel > 0) {
+                       if (ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
+                                                aniState->firstepLevel - 1))
+                               return;
+               }
+       } else {
+               rssi = BEACON_RSSI(ah);
+               if (rssi > aniState->rssiThrHigh) {
+                       /* XXX: Handle me */
+               } else if (rssi > aniState->rssiThrLow) {
+                       if (aniState->ofdmWeakSigDetectOff) {
+                               if (ath9k_hw_ani_control(ah,
+                                        ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
+                                        true) == true)
+                                       return;
+                       }
+                       if (aniState->firstepLevel > 0) {
+                               if (ath9k_hw_ani_control(ah,
+                                        ATH9K_ANI_FIRSTEP_LEVEL,
+                                        aniState->firstepLevel - 1) == true)
+                                       return;
+                       }
+               } else {
+                       if (aniState->firstepLevel > 0) {
+                               if (ath9k_hw_ani_control(ah,
+                                        ATH9K_ANI_FIRSTEP_LEVEL,
+                                        aniState->firstepLevel - 1) == true)
+                                       return;
+                       }
+               }
+       }
+
+       if (aniState->spurImmunityLevel > 0) {
+               if (ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL,
+                                        aniState->spurImmunityLevel - 1))
+                       return;
+       }
+
+       if (aniState->noiseImmunityLevel > 0) {
+               ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
+                                    aniState->noiseImmunityLevel - 1);
+               return;
+       }
+}
+
+static int32_t ath9k_hw_ani_get_listen_time(struct ath_hw *ah)
+{
+       struct ar5416AniState *aniState;
+       u32 txFrameCount, rxFrameCount, cycleCount;
+       int32_t listenTime;
+
+       txFrameCount = REG_READ(ah, AR_TFCNT);
+       rxFrameCount = REG_READ(ah, AR_RFCNT);
+       cycleCount = REG_READ(ah, AR_CCCNT);
+
+       aniState = ah->curani;
+       if (aniState->cycleCount == 0 || aniState->cycleCount > cycleCount) {
+
+               listenTime = 0;
+               ah->stats.ast_ani_lzero++;
+       } else {
+               int32_t ccdelta = cycleCount - aniState->cycleCount;
+               int32_t rfdelta = rxFrameCount - aniState->rxFrameCount;
+               int32_t tfdelta = txFrameCount - aniState->txFrameCount;
+               listenTime = (ccdelta - rfdelta - tfdelta) / 44000;
+       }
+       aniState->cycleCount = cycleCount;
+       aniState->txFrameCount = txFrameCount;
+       aniState->rxFrameCount = rxFrameCount;
+
+       return listenTime;
+}
+
+void ath9k_ani_reset(struct ath_hw *ah)
+{
+       struct ar5416AniState *aniState;
+       struct ath9k_channel *chan = ah->curchan;
+       int index;
+
+       if (!DO_ANI(ah))
+               return;
+
+       index = ath9k_hw_get_ani_channel_idx(ah, chan);
+       aniState = &ah->ani[index];
+       ah->curani = aniState;
+
+       if (DO_ANI(ah) && ah->opmode != NL80211_IFTYPE_STATION
+           && ah->opmode != NL80211_IFTYPE_ADHOC) {
+               DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+                       "Reset ANI state opmode %u\n", ah->opmode);
+               ah->stats.ast_ani_reset++;
+
+               ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL, 0);
+               ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL, 0);
+               ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, 0);
+               ath9k_hw_ani_control(ah, ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
+                                    !ATH9K_ANI_USE_OFDM_WEAK_SIG);
+               ath9k_hw_ani_control(ah, ATH9K_ANI_CCK_WEAK_SIGNAL_THR,
+                                    ATH9K_ANI_CCK_WEAK_SIG_THR);
+
+               ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) |
+                                    ATH9K_RX_FILTER_PHYERR);
+
+               if (ah->opmode == NL80211_IFTYPE_AP) {
+                       ah->curani->ofdmTrigHigh =
+                               ah->config.ofdm_trig_high;
+                       ah->curani->ofdmTrigLow =
+                               ah->config.ofdm_trig_low;
+                       ah->curani->cckTrigHigh =
+                               ah->config.cck_trig_high;
+                       ah->curani->cckTrigLow =
+                               ah->config.cck_trig_low;
+               }
+               ath9k_ani_restart(ah);
+               return;
+       }
+
+       if (aniState->noiseImmunityLevel != 0)
+               ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
+                                    aniState->noiseImmunityLevel);
+       if (aniState->spurImmunityLevel != 0)
+               ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL,
+                                    aniState->spurImmunityLevel);
+       if (aniState->ofdmWeakSigDetectOff)
+               ath9k_hw_ani_control(ah, ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
+                                    !aniState->ofdmWeakSigDetectOff);
+       if (aniState->cckWeakSigThreshold)
+               ath9k_hw_ani_control(ah, ATH9K_ANI_CCK_WEAK_SIGNAL_THR,
+                                    aniState->cckWeakSigThreshold);
+       if (aniState->firstepLevel != 0)
+               ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
+                                    aniState->firstepLevel);
+       if (ah->has_hw_phycounters) {
+               ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) &
+                                    ~ATH9K_RX_FILTER_PHYERR);
+               ath9k_ani_restart(ah);
+               REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
+               REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
+
+       } else {
+               ath9k_ani_restart(ah);
+               ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) |
+                                    ATH9K_RX_FILTER_PHYERR);
+       }
+}
+
+void ath9k_hw_ani_monitor(struct ath_hw *ah,
+                         const struct ath9k_node_stats *stats,
+                         struct ath9k_channel *chan)
+{
+       struct ar5416AniState *aniState;
+       int32_t listenTime;
+
+       if (!DO_ANI(ah))
+               return;
+
+       aniState = ah->curani;
+       ah->stats.ast_nodestats = *stats;
+
+       listenTime = ath9k_hw_ani_get_listen_time(ah);
+       if (listenTime < 0) {
+               ah->stats.ast_ani_lneg++;
+               ath9k_ani_restart(ah);
+               return;
+       }
+
+       aniState->listenTime += listenTime;
+
+       if (ah->has_hw_phycounters) {
+               u32 phyCnt1, phyCnt2;
+               u32 ofdmPhyErrCnt, cckPhyErrCnt;
+
+               ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
+
+               phyCnt1 = REG_READ(ah, AR_PHY_ERR_1);
+               phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
+
+               if (phyCnt1 < aniState->ofdmPhyErrBase ||
+                   phyCnt2 < aniState->cckPhyErrBase) {
+                       if (phyCnt1 < aniState->ofdmPhyErrBase) {
+                               DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+                                       "phyCnt1 0x%x, resetting "
+                                       "counter value to 0x%x\n",
+                                       phyCnt1, aniState->ofdmPhyErrBase);
+                               REG_WRITE(ah, AR_PHY_ERR_1,
+                                         aniState->ofdmPhyErrBase);
+                               REG_WRITE(ah, AR_PHY_ERR_MASK_1,
+                                         AR_PHY_ERR_OFDM_TIMING);
+                       }
+                       if (phyCnt2 < aniState->cckPhyErrBase) {
+                               DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+                                       "phyCnt2 0x%x, resetting "
+                                       "counter value to 0x%x\n",
+                                       phyCnt2, aniState->cckPhyErrBase);
+                               REG_WRITE(ah, AR_PHY_ERR_2,
+                                         aniState->cckPhyErrBase);
+                               REG_WRITE(ah, AR_PHY_ERR_MASK_2,
+                                         AR_PHY_ERR_CCK_TIMING);
+                       }
+                       return;
+               }
+
+               ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase;
+               ah->stats.ast_ani_ofdmerrs +=
+                       ofdmPhyErrCnt - aniState->ofdmPhyErrCount;
+               aniState->ofdmPhyErrCount = ofdmPhyErrCnt;
+
+               cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase;
+               ah->stats.ast_ani_cckerrs +=
+                       cckPhyErrCnt - aniState->cckPhyErrCount;
+               aniState->cckPhyErrCount = cckPhyErrCnt;
+       }
+
+       if (aniState->listenTime > 5 * ah->aniperiod) {
+               if (aniState->ofdmPhyErrCount <= aniState->listenTime *
+                   aniState->ofdmTrigLow / 1000 &&
+                   aniState->cckPhyErrCount <= aniState->listenTime *
+                   aniState->cckTrigLow / 1000)
+                       ath9k_hw_ani_lower_immunity(ah);
+               ath9k_ani_restart(ah);
+       } else if (aniState->listenTime > ah->aniperiod) {
+               if (aniState->ofdmPhyErrCount > aniState->listenTime *
+                   aniState->ofdmTrigHigh / 1000) {
+                       ath9k_hw_ani_ofdm_err_trigger(ah);
+                       ath9k_ani_restart(ah);
+               } else if (aniState->cckPhyErrCount >
+                          aniState->listenTime * aniState->cckTrigHigh /
+                          1000) {
+                       ath9k_hw_ani_cck_err_trigger(ah);
+                       ath9k_ani_restart(ah);
+               }
+       }
+}
+
+bool ath9k_hw_phycounters(struct ath_hw *ah)
+{
+       return ah->has_hw_phycounters ? true : false;
+}
+
+void ath9k_enable_mib_counters(struct ath_hw *ah)
+{
+       DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Enable MIB counters\n");
+
+       ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
+
+       REG_WRITE(ah, AR_FILT_OFDM, 0);
+       REG_WRITE(ah, AR_FILT_CCK, 0);
+       REG_WRITE(ah, AR_MIBC,
+                 ~(AR_MIBC_COW | AR_MIBC_FMC | AR_MIBC_CMC | AR_MIBC_MCS)
+                 & 0x0f);
+       REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
+       REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
+}
+
+/* Freeze the MIB counters, get the stats and then clear them */
+void ath9k_hw_disable_mib_counters(struct ath_hw *ah)
+{
+       DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Disable MIB counters\n");
+       REG_WRITE(ah, AR_MIBC, AR_MIBC_FMC);
+       ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
+       REG_WRITE(ah, AR_MIBC, AR_MIBC_CMC);
+       REG_WRITE(ah, AR_FILT_OFDM, 0);
+       REG_WRITE(ah, AR_FILT_CCK, 0);
+}
+
+u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hw *ah,
+                                 u32 *rxc_pcnt,
+                                 u32 *rxf_pcnt,
+                                 u32 *txf_pcnt)
+{
+       static u32 cycles, rx_clear, rx_frame, tx_frame;
+       u32 good = 1;
+
+       u32 rc = REG_READ(ah, AR_RCCNT);
+       u32 rf = REG_READ(ah, AR_RFCNT);
+       u32 tf = REG_READ(ah, AR_TFCNT);
+       u32 cc = REG_READ(ah, AR_CCCNT);
+
+       if (cycles == 0 || cycles > cc) {
+               DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+                       "cycle counter wrap. ExtBusy = 0\n");
+               good = 0;
+       } else {
+               u32 cc_d = cc - cycles;
+               u32 rc_d = rc - rx_clear;
+               u32 rf_d = rf - rx_frame;
+               u32 tf_d = tf - tx_frame;
+
+               if (cc_d != 0) {
+                       *rxc_pcnt = rc_d * 100 / cc_d;
+                       *rxf_pcnt = rf_d * 100 / cc_d;
+                       *txf_pcnt = tf_d * 100 / cc_d;
+               } else {
+                       good = 0;
+               }
+       }
+
+       cycles = cc;
+       rx_frame = rf;
+       rx_clear = rc;
+       tx_frame = tf;
+
+       return good;
+}
+
+/*
+ * Process a MIB interrupt.  We may potentially be invoked because
+ * any of the MIB counters overflow/trigger so don't assume we're
+ * here because a PHY error counter triggered.
+ */
+void ath9k_hw_procmibevent(struct ath_hw *ah,
+                          const struct ath9k_node_stats *stats)
+{
+       u32 phyCnt1, phyCnt2;
+
+       /* Reset these counters regardless */
+       REG_WRITE(ah, AR_FILT_OFDM, 0);
+       REG_WRITE(ah, AR_FILT_CCK, 0);
+       if (!(REG_READ(ah, AR_SLP_MIB_CTRL) & AR_SLP_MIB_PENDING))
+               REG_WRITE(ah, AR_SLP_MIB_CTRL, AR_SLP_MIB_CLEAR);
+
+       /* Clear the mib counters and save them in the stats */
+       ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
+       ah->stats.ast_nodestats = *stats;
+
+       if (!DO_ANI(ah))
+               return;
+
+       /* NB: these are not reset-on-read */
+       phyCnt1 = REG_READ(ah, AR_PHY_ERR_1);
+       phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
+       if (((phyCnt1 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK) ||
+           ((phyCnt2 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK)) {
+               struct ar5416AniState *aniState = ah->curani;
+               u32 ofdmPhyErrCnt, cckPhyErrCnt;
+
+               /* NB: only use ast_ani_*errs with AH_PRIVATE_DIAG */
+               ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase;
+               ah->stats.ast_ani_ofdmerrs +=
+                       ofdmPhyErrCnt - aniState->ofdmPhyErrCount;
+               aniState->ofdmPhyErrCount = ofdmPhyErrCnt;
+
+               cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase;
+               ah->stats.ast_ani_cckerrs +=
+                       cckPhyErrCnt - aniState->cckPhyErrCount;
+               aniState->cckPhyErrCount = cckPhyErrCnt;
+
+               /*
+                * NB: figure out which counter triggered.  If both
+                * trigger we'll only deal with one as the processing
+                * clobbers the error counter so the trigger threshold
+                * check will never be true.
+                */
+               if (aniState->ofdmPhyErrCount > aniState->ofdmTrigHigh)
+                       ath9k_hw_ani_ofdm_err_trigger(ah);
+               if (aniState->cckPhyErrCount > aniState->cckTrigHigh)
+                       ath9k_hw_ani_cck_err_trigger(ah);
+               /* NB: always restart to insure the h/w counters are reset */
+               ath9k_ani_restart(ah);
+       }
+}
+
+void ath9k_hw_ani_setup(struct ath_hw *ah)
+{
+       int i;
+
+       const int totalSizeDesired[] = { -55, -55, -55, -55, -62 };
+       const int coarseHigh[] = { -14, -14, -14, -14, -12 };
+       const int coarseLow[] = { -64, -64, -64, -64, -70 };
+       const int firpwr[] = { -78, -78, -78, -78, -80 };
+
+       for (i = 0; i < 5; i++) {
+               ah->totalSizeDesired[i] = totalSizeDesired[i];
+               ah->coarse_high[i] = coarseHigh[i];
+               ah->coarse_low[i] = coarseLow[i];
+               ah->firpwr[i] = firpwr[i];
+       }
+}
+
+void ath9k_hw_ani_attach(struct ath_hw *ah)
+{
+       int i;
+
+       DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Attach ANI\n");
+
+       ah->has_hw_phycounters = 1;
+
+       memset(ah->ani, 0, sizeof(ah->ani));
+       for (i = 0; i < ARRAY_SIZE(ah->ani); i++) {
+               ah->ani[i].ofdmTrigHigh = ATH9K_ANI_OFDM_TRIG_HIGH;
+               ah->ani[i].ofdmTrigLow = ATH9K_ANI_OFDM_TRIG_LOW;
+               ah->ani[i].cckTrigHigh = ATH9K_ANI_CCK_TRIG_HIGH;
+               ah->ani[i].cckTrigLow = ATH9K_ANI_CCK_TRIG_LOW;
+               ah->ani[i].rssiThrHigh = ATH9K_ANI_RSSI_THR_HIGH;
+               ah->ani[i].rssiThrLow = ATH9K_ANI_RSSI_THR_LOW;
+               ah->ani[i].ofdmWeakSigDetectOff =
+                       !ATH9K_ANI_USE_OFDM_WEAK_SIG;
+               ah->ani[i].cckWeakSigThreshold =
+                       ATH9K_ANI_CCK_WEAK_SIG_THR;
+               ah->ani[i].spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL;
+               ah->ani[i].firstepLevel = ATH9K_ANI_FIRSTEP_LVL;
+               if (ah->has_hw_phycounters) {
+                       ah->ani[i].ofdmPhyErrBase =
+                               AR_PHY_COUNTMAX - ATH9K_ANI_OFDM_TRIG_HIGH;
+                       ah->ani[i].cckPhyErrBase =
+                               AR_PHY_COUNTMAX - ATH9K_ANI_CCK_TRIG_HIGH;
+               }
+       }
+       if (ah->has_hw_phycounters) {
+               DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+                       "Setting OfdmErrBase = 0x%08x\n",
+                       ah->ani[0].ofdmPhyErrBase);
+               DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Setting cckErrBase = 0x%08x\n",
+                       ah->ani[0].cckPhyErrBase);
+
+               REG_WRITE(ah, AR_PHY_ERR_1, ah->ani[0].ofdmPhyErrBase);
+               REG_WRITE(ah, AR_PHY_ERR_2, ah->ani[0].cckPhyErrBase);
+               ath9k_enable_mib_counters(ah);
+       }
+       ah->aniperiod = ATH9K_ANI_PERIOD;
+       if (ah->config.enable_ani)
+               ah->proc_phyerr |= HAL_PROCESS_ANI;
+}
+
+void ath9k_hw_ani_detach(struct ath_hw *ah)
+{
+       DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Detach ANI\n");
+
+       if (ah->has_hw_phycounters) {
+               ath9k_hw_disable_mib_counters(ah);
+               REG_WRITE(ah, AR_PHY_ERR_1, 0);
+               REG_WRITE(ah, AR_PHY_ERR_2, 0);
+       }
+}
diff --git a/drivers/net/wireless/ath/ath9k/ani.h b/drivers/net/wireless/ath/ath9k/ani.h
new file mode 100644 (file)
index 0000000..08b4e7e
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2008-2009 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 ANI_H
+#define ANI_H
+
+#define HAL_PROCESS_ANI           0x00000001
+#define ATH9K_RSSI_EP_MULTIPLIER  (1<<7)
+
+#define DO_ANI(ah) (((ah)->proc_phyerr & HAL_PROCESS_ANI))
+
+#define HAL_EP_RND(x, mul)                                             \
+       ((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul))
+#define BEACON_RSSI(ahp)                                       \
+       HAL_EP_RND(ahp->stats.ast_nodestats.ns_avgbrssi,        \
+                  ATH9K_RSSI_EP_MULTIPLIER)
+
+#define ATH9K_ANI_OFDM_TRIG_HIGH          500
+#define ATH9K_ANI_OFDM_TRIG_LOW           200
+#define ATH9K_ANI_CCK_TRIG_HIGH           200
+#define ATH9K_ANI_CCK_TRIG_LOW            100
+#define ATH9K_ANI_NOISE_IMMUNE_LVL        4
+#define ATH9K_ANI_USE_OFDM_WEAK_SIG       true
+#define ATH9K_ANI_CCK_WEAK_SIG_THR        false
+#define ATH9K_ANI_SPUR_IMMUNE_LVL         7
+#define ATH9K_ANI_FIRSTEP_LVL             0
+#define ATH9K_ANI_RSSI_THR_HIGH           40
+#define ATH9K_ANI_RSSI_THR_LOW            7
+#define ATH9K_ANI_PERIOD                  100
+
+#define HAL_NOISE_IMMUNE_MAX              4
+#define HAL_SPUR_IMMUNE_MAX               7
+#define HAL_FIRST_STEP_MAX                2
+
+enum ath9k_ani_cmd {
+       ATH9K_ANI_PRESENT = 0x1,
+       ATH9K_ANI_NOISE_IMMUNITY_LEVEL = 0x2,
+       ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION = 0x4,
+       ATH9K_ANI_CCK_WEAK_SIGNAL_THR = 0x8,
+       ATH9K_ANI_FIRSTEP_LEVEL = 0x10,
+       ATH9K_ANI_SPUR_IMMUNITY_LEVEL = 0x20,
+       ATH9K_ANI_MODE = 0x40,
+       ATH9K_ANI_PHYERR_RESET = 0x80,
+       ATH9K_ANI_ALL = 0xff
+};
+
+struct ath9k_mib_stats {
+       u32 ackrcv_bad;
+       u32 rts_bad;
+       u32 rts_good;
+       u32 fcs_bad;
+       u32 beacons;
+};
+
+struct ath9k_node_stats {
+       u32 ns_avgbrssi;
+       u32 ns_avgrssi;
+       u32 ns_avgtxrssi;
+       u32 ns_avgtxrate;
+};
+
+struct ar5416AniState {
+       struct ath9k_channel *c;
+       u8 noiseImmunityLevel;
+       u8 spurImmunityLevel;
+       u8 firstepLevel;
+       u8 ofdmWeakSigDetectOff;
+       u8 cckWeakSigThreshold;
+       u32 listenTime;
+       u32 ofdmTrigHigh;
+       u32 ofdmTrigLow;
+       int32_t cckTrigHigh;
+       int32_t cckTrigLow;
+       int32_t rssiThrLow;
+       int32_t rssiThrHigh;
+       u32 noiseFloor;
+       u32 txFrameCount;
+       u32 rxFrameCount;
+       u32 cycleCount;
+       u32 ofdmPhyErrCount;
+       u32 cckPhyErrCount;
+       u32 ofdmPhyErrBase;
+       u32 cckPhyErrBase;
+       int16_t pktRssi[2];
+       int16_t ofdmErrRssi[2];
+       int16_t cckErrRssi[2];
+};
+
+struct ar5416Stats {
+       u32 ast_ani_niup;
+       u32 ast_ani_nidown;
+       u32 ast_ani_spurup;
+       u32 ast_ani_spurdown;
+       u32 ast_ani_ofdmon;
+       u32 ast_ani_ofdmoff;
+       u32 ast_ani_cckhigh;
+       u32 ast_ani_ccklow;
+       u32 ast_ani_stepup;
+       u32 ast_ani_stepdown;
+       u32 ast_ani_ofdmerrs;
+       u32 ast_ani_cckerrs;
+       u32 ast_ani_reset;
+       u32 ast_ani_lzero;
+       u32 ast_ani_lneg;
+       struct ath9k_mib_stats ast_mibstats;
+       struct ath9k_node_stats ast_nodestats;
+};
+#define ah_mibStats stats.ast_mibstats
+
+void ath9k_ani_reset(struct ath_hw *ah);
+void ath9k_hw_ani_monitor(struct ath_hw *ah,
+                         const struct ath9k_node_stats *stats,
+                         struct ath9k_channel *chan);
+bool ath9k_hw_phycounters(struct ath_hw *ah);
+void ath9k_enable_mib_counters(struct ath_hw *ah);
+void ath9k_hw_disable_mib_counters(struct ath_hw *ah);
+u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hw *ah, u32 *rxc_pcnt,
+                                 u32 *rxf_pcnt, u32 *txf_pcnt);
+void ath9k_hw_procmibevent(struct ath_hw *ah,
+                          const struct ath9k_node_stats *stats);
+void ath9k_hw_ani_setup(struct ath_hw *ah);
+void ath9k_hw_ani_attach(struct ath_hw *ah);
+void ath9k_hw_ani_detach(struct ath_hw *ah);
+
+#endif /* ANI_H */
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
new file mode 100644 (file)
index 0000000..515880a
--- /dev/null
@@ -0,0 +1,705 @@
+/*
+ * Copyright (c) 2008-2009 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 ATH9K_H
+#define ATH9K_H
+
+#include <linux/etherdevice.h>
+#include <linux/device.h>
+#include <net/mac80211.h>
+#include <linux/leds.h>
+#include <linux/rfkill.h>
+
+#include "hw.h"
+#include "rc.h"
+#include "debug.h"
+
+struct ath_node;
+
+/* Macro to expand scalars to 64-bit objects */
+
+#define        ito64(x) (sizeof(x) == 8) ?                     \
+       (((unsigned long long int)(x)) & (0xff)) :      \
+       (sizeof(x) == 16) ?                             \
+       (((unsigned long long int)(x)) & 0xffff) :      \
+       ((sizeof(x) == 32) ?                            \
+        (((unsigned long long int)(x)) & 0xffffffff) : \
+        (unsigned long long int)(x))
+
+/* increment with wrap-around */
+#define INCR(_l, _sz)   do {                   \
+               (_l)++;                         \
+               (_l) &= ((_sz) - 1);            \
+       } while (0)
+
+/* decrement with wrap-around */
+#define DECR(_l,  _sz)  do {                   \
+               (_l)--;                         \
+               (_l) &= ((_sz) - 1);            \
+       } while (0)
+
+#define A_MAX(a, b) ((a) > (b) ? (a) : (b))
+
+#define ASSERT(exp) BUG_ON(!(exp))
+
+#define TSF_TO_TU(_h,_l) \
+       ((((u32)(_h)) << 22) | (((u32)(_l)) >> 10))
+
+#define        ATH_TXQ_SETUP(sc, i)        ((sc)->tx.txqsetup & (1<<i))
+
+static const u8 ath_bcast_mac[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+
+struct ath_config {
+       u32 ath_aggr_prot;
+       u16 txpowlimit;
+       u8 cabqReadytime;
+};
+
+/*************************/
+/* Descriptor Management */
+/*************************/
+
+#define ATH_TXBUF_RESET(_bf) do {                              \
+               (_bf)->bf_stale = false;                        \
+               (_bf)->bf_lastbf = NULL;                        \
+               (_bf)->bf_next = NULL;                          \
+               memset(&((_bf)->bf_state), 0,                   \
+                      sizeof(struct ath_buf_state));           \
+       } while (0)
+
+#define ATH_RXBUF_RESET(_bf) do {              \
+               (_bf)->bf_stale = false;        \
+       } while (0)
+
+/**
+ * enum buffer_type - Buffer type flags
+ *
+ * @BUF_HT: Send this buffer using HT capabilities
+ * @BUF_AMPDU: This buffer is an ampdu, as part of an aggregate (during TX)
+ * @BUF_AGGR: Indicates whether the buffer can be aggregated
+ *     (used in aggregation scheduling)
+ * @BUF_RETRY: Indicates whether the buffer is retried
+ * @BUF_XRETRY: To denote excessive retries of the buffer
+ */
+enum buffer_type {
+       BUF_HT                  = BIT(1),
+       BUF_AMPDU               = BIT(2),
+       BUF_AGGR                = BIT(3),
+       BUF_RETRY               = BIT(4),
+       BUF_XRETRY              = BIT(5),
+};
+
+struct ath_buf_state {
+       int bfs_nframes;
+       u16 bfs_al;
+       u16 bfs_frmlen;
+       int bfs_seqno;
+       int bfs_tidno;
+       int bfs_retries;
+       u8 bf_type;
+       u32 bfs_keyix;
+       enum ath9k_key_type bfs_keytype;
+};
+
+#define bf_nframes             bf_state.bfs_nframes
+#define bf_al                  bf_state.bfs_al
+#define bf_frmlen              bf_state.bfs_frmlen
+#define bf_retries             bf_state.bfs_retries
+#define bf_seqno               bf_state.bfs_seqno
+#define bf_tidno               bf_state.bfs_tidno
+#define bf_keyix                bf_state.bfs_keyix
+#define bf_keytype             bf_state.bfs_keytype
+#define bf_isht(bf)            (bf->bf_state.bf_type & BUF_HT)
+#define bf_isampdu(bf)         (bf->bf_state.bf_type & BUF_AMPDU)
+#define bf_isaggr(bf)          (bf->bf_state.bf_type & BUF_AGGR)
+#define bf_isretried(bf)       (bf->bf_state.bf_type & BUF_RETRY)
+#define bf_isxretried(bf)      (bf->bf_state.bf_type & BUF_XRETRY)
+
+struct ath_buf {
+       struct list_head list;
+       struct ath_buf *bf_lastbf;      /* last buf of this unit (a frame or
+                                          an aggregate) */
+       struct ath_buf *bf_next;        /* next subframe in the aggregate */
+       struct sk_buff *bf_mpdu;        /* enclosing frame structure */
+       struct ath_desc *bf_desc;       /* virtual addr of desc */
+       dma_addr_t bf_daddr;            /* physical addr of desc */
+       dma_addr_t bf_buf_addr;         /* physical addr of data buffer */
+       bool bf_stale;
+       u16 bf_flags;
+       struct ath_buf_state bf_state;
+       dma_addr_t bf_dmacontext;
+};
+
+struct ath_descdma {
+       struct ath_desc *dd_desc;
+       dma_addr_t dd_desc_paddr;
+       u32 dd_desc_len;
+       struct ath_buf *dd_bufptr;
+};
+
+int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
+                     struct list_head *head, const char *name,
+                     int nbuf, int ndesc);
+void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd,
+                        struct list_head *head);
+
+/***********/
+/* RX / TX */
+/***********/
+
+#define ATH_MAX_ANTENNA         3
+#define ATH_RXBUF               512
+#define WME_NUM_TID             16
+#define ATH_TXBUF               512
+#define ATH_TXMAXTRY            13
+#define ATH_11N_TXMAXTRY        10
+#define ATH_MGT_TXMAXTRY        4
+#define WME_BA_BMP_SIZE         64
+#define WME_MAX_BA              WME_BA_BMP_SIZE
+#define ATH_TID_MAX_BUFS        (2 * WME_MAX_BA)
+
+#define TID_TO_WME_AC(_tid)                            \
+       ((((_tid) == 0) || ((_tid) == 3)) ? WME_AC_BE : \
+        (((_tid) == 1) || ((_tid) == 2)) ? WME_AC_BK : \
+        (((_tid) == 4) || ((_tid) == 5)) ? WME_AC_VI : \
+        WME_AC_VO)
+
+#define WME_AC_BE   0
+#define WME_AC_BK   1
+#define WME_AC_VI   2
+#define WME_AC_VO   3
+#define WME_NUM_AC  4
+
+#define ADDBA_EXCHANGE_ATTEMPTS    10
+#define ATH_AGGR_DELIM_SZ          4
+#define ATH_AGGR_MINPLEN           256 /* in bytes, minimum packet length */
+/* number of delimiters for encryption padding */
+#define ATH_AGGR_ENCRYPTDELIM      10
+/* minimum h/w qdepth to be sustained to maximize aggregation */
+#define ATH_AGGR_MIN_QDEPTH        2
+#define ATH_AMPDU_SUBFRAME_DEFAULT 32
+#define ATH_AMPDU_LIMIT_MAX        (64 * 1024 - 1)
+#define ATH_AMPDU_LIMIT_DEFAULT    ATH_AMPDU_LIMIT_MAX
+
+#define IEEE80211_SEQ_SEQ_SHIFT    4
+#define IEEE80211_SEQ_MAX          4096
+#define IEEE80211_MIN_AMPDU_BUF    0x8
+#define IEEE80211_HTCAP_MAXRXAMPDU_FACTOR 13
+#define IEEE80211_WEP_IVLEN        3
+#define IEEE80211_WEP_KIDLEN       1
+#define IEEE80211_WEP_CRCLEN       4
+#define IEEE80211_MAX_MPDU_LEN     (3840 + FCS_LEN +           \
+                                   (IEEE80211_WEP_IVLEN +      \
+                                    IEEE80211_WEP_KIDLEN +     \
+                                    IEEE80211_WEP_CRCLEN))
+
+/* return whether a bit at index _n in bitmap _bm is set
+ * _sz is the size of the bitmap  */
+#define ATH_BA_ISSET(_bm, _n)  (((_n) < (WME_BA_BMP_SIZE)) &&          \
+                               ((_bm)[(_n) >> 5] & (1 << ((_n) & 31))))
+
+/* return block-ack bitmap index given sequence and starting sequence */
+#define ATH_BA_INDEX(_st, _seq) (((_seq) - (_st)) & (IEEE80211_SEQ_MAX - 1))
+
+/* returns delimiter padding required given the packet length */
+#define ATH_AGGR_GET_NDELIM(_len)                                      \
+       (((((_len) + ATH_AGGR_DELIM_SZ) < ATH_AGGR_MINPLEN) ?           \
+         (ATH_AGGR_MINPLEN - (_len) - ATH_AGGR_DELIM_SZ) : 0) >> 2)
+
+#define BAW_WITHIN(_start, _bawsz, _seqno) \
+       ((((_seqno) - (_start)) & 4095) < (_bawsz))
+
+#define ATH_DS_BA_SEQ(_ds)         ((_ds)->ds_us.tx.ts_seqnum)
+#define ATH_DS_BA_BITMAP(_ds)      (&(_ds)->ds_us.tx.ba_low)
+#define ATH_DS_TX_BA(_ds)          ((_ds)->ds_us.tx.ts_flags & ATH9K_TX_BA)
+#define ATH_AN_2_TID(_an, _tidno)  (&(_an)->tid[(_tidno)])
+
+enum ATH_AGGR_STATUS {
+       ATH_AGGR_DONE,
+       ATH_AGGR_BAW_CLOSED,
+       ATH_AGGR_LIMITED,
+};
+
+struct ath_txq {
+       u32 axq_qnum;
+       u32 *axq_link;
+       struct list_head axq_q;
+       spinlock_t axq_lock;
+       u32 axq_depth;
+       u8 axq_aggr_depth;
+       u32 axq_totalqueued;
+       bool stopped;
+       struct ath_buf *axq_linkbuf;
+
+       /* first desc of the last descriptor that contains CTS */
+       struct ath_desc *axq_lastdsWithCTS;
+
+       /* final desc of the gating desc that determines whether
+          lastdsWithCTS has been DMA'ed or not */
+       struct ath_desc *axq_gatingds;
+
+       struct list_head axq_acq;
+};
+
+#define AGGR_CLEANUP         BIT(1)
+#define AGGR_ADDBA_COMPLETE  BIT(2)
+#define AGGR_ADDBA_PROGRESS  BIT(3)
+
+struct ath_atx_tid {
+       struct list_head list;
+       struct list_head buf_q;
+       struct ath_node *an;
+       struct ath_atx_ac *ac;
+       struct ath_buf *tx_buf[ATH_TID_MAX_BUFS];
+       u16 seq_start;
+       u16 seq_next;
+       u16 baw_size;
+       int tidno;
+       int baw_head;   /* first un-acked tx buffer */
+       int baw_tail;   /* next unused tx buffer slot */
+       int sched;
+       int paused;
+       u8 state;
+       int addba_exchangeattempts;
+};
+
+struct ath_atx_ac {
+       int sched;
+       int qnum;
+       struct list_head list;
+       struct list_head tid_q;
+};
+
+struct ath_tx_control {
+       struct ath_txq *txq;
+       int if_id;
+       enum ath9k_internal_frame_type frame_type;
+};
+
+#define ATH_TX_ERROR        0x01
+#define ATH_TX_XRETRY       0x02
+#define ATH_TX_BAR          0x04
+
+struct ath_node {
+       struct ath_softc *an_sc;
+       struct ath_atx_tid tid[WME_NUM_TID];
+       struct ath_atx_ac ac[WME_NUM_AC];
+       u16 maxampdu;
+       u8 mpdudensity;
+};
+
+struct ath_tx {
+       u16 seq_no;
+       u32 txqsetup;
+       int hwq_map[ATH9K_WME_AC_VO+1];
+       spinlock_t txbuflock;
+       struct list_head txbuf;
+       struct ath_txq txq[ATH9K_NUM_TX_QUEUES];
+       struct ath_descdma txdma;
+};
+
+struct ath_rx {
+       u8 defant;
+       u8 rxotherant;
+       u32 *rxlink;
+       int bufsize;
+       unsigned int rxfilter;
+       spinlock_t rxflushlock;
+       spinlock_t rxbuflock;
+       struct list_head rxbuf;
+       struct ath_descdma rxdma;
+};
+
+int ath_startrecv(struct ath_softc *sc);
+bool ath_stoprecv(struct ath_softc *sc);
+void ath_flushrecv(struct ath_softc *sc);
+u32 ath_calcrxfilter(struct ath_softc *sc);
+int ath_rx_init(struct ath_softc *sc, int nbufs);
+void ath_rx_cleanup(struct ath_softc *sc);
+int ath_rx_tasklet(struct ath_softc *sc, int flush);
+struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype);
+void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq);
+int ath_tx_setup(struct ath_softc *sc, int haltype);
+void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx);
+void ath_draintxq(struct ath_softc *sc,
+                    struct ath_txq *txq, bool retry_tx);
+void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an);
+void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an);
+void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq);
+int ath_tx_init(struct ath_softc *sc, int nbufs);
+void ath_tx_cleanup(struct ath_softc *sc);
+struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb);
+int ath_txq_update(struct ath_softc *sc, int qnum,
+                  struct ath9k_tx_queue_info *q);
+int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
+                struct ath_tx_control *txctl);
+void ath_tx_tasklet(struct ath_softc *sc);
+void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb);
+bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, u8 tidno);
+int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
+                     u16 tid, u16 *ssn);
+int ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid);
+void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid);
+
+/********/
+/* VIFs */
+/********/
+
+struct ath_vif {
+       int av_bslot;
+       __le64 tsf_adjust; /* TSF adjustment for staggered beacons */
+       enum nl80211_iftype av_opmode;
+       struct ath_buf *av_bcbuf;
+       struct ath_tx_control av_btxctl;
+       u8 bssid[ETH_ALEN]; /* current BSSID from config_interface */
+};
+
+/*******************/
+/* Beacon Handling */
+/*******************/
+
+/*
+ * Regardless of the number of beacons we stagger, (i.e. regardless of the
+ * number of BSSIDs) if a given beacon does not go out even after waiting this
+ * number of beacon intervals, the game's up.
+ */
+#define BSTUCK_THRESH                  (9 * ATH_BCBUF)
+#define        ATH_BCBUF                       4
+#define ATH_DEFAULT_BINTVAL            100 /* TU */
+#define ATH_DEFAULT_BMISS_LIMIT        10
+#define IEEE80211_MS_TO_TU(x)           (((x) * 1000) / 1024)
+
+struct ath_beacon_config {
+       u16 beacon_interval;
+       u16 listen_interval;
+       u16 dtim_period;
+       u16 bmiss_timeout;
+       u8 dtim_count;
+};
+
+struct ath_beacon {
+       enum {
+               OK,             /* no change needed */
+               UPDATE,         /* update pending */
+               COMMIT          /* beacon sent, commit change */
+       } updateslot;           /* slot time update fsm */
+
+       u32 beaconq;
+       u32 bmisscnt;
+       u32 ast_be_xmit;
+       u64 bc_tstamp;
+       struct ieee80211_vif *bslot[ATH_BCBUF];
+       struct ath_wiphy *bslot_aphy[ATH_BCBUF];
+       int slottime;
+       int slotupdate;
+       struct ath9k_tx_queue_info beacon_qi;
+       struct ath_descdma bdma;
+       struct ath_txq *cabq;
+       struct list_head bbuf;
+};
+
+void ath_beacon_tasklet(unsigned long data);
+void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif);
+int ath_beaconq_setup(struct ath_hw *ah);
+int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif);
+void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp);
+
+/*******/
+/* ANI */
+/*******/
+
+#define ATH_STA_SHORT_CALINTERVAL 1000    /* 1 second */
+#define ATH_AP_SHORT_CALINTERVAL  100     /* 100 ms */
+#define ATH_ANI_POLLINTERVAL      100     /* 100 ms */
+#define ATH_LONG_CALINTERVAL      30000   /* 30 seconds */
+#define ATH_RESTART_CALINTERVAL   1200000 /* 20 minutes */
+
+struct ath_ani {
+       bool caldone;
+       int16_t noise_floor;
+       unsigned int longcal_timer;
+       unsigned int shortcal_timer;
+       unsigned int resetcal_timer;
+       unsigned int checkani_timer;
+       struct timer_list timer;
+};
+
+/********************/
+/*   LED Control    */
+/********************/
+
+#define ATH_LED_PIN    1
+#define ATH_LED_ON_DURATION_IDLE       350     /* in msecs */
+#define ATH_LED_OFF_DURATION_IDLE      250     /* in msecs */
+
+enum ath_led_type {
+       ATH_LED_RADIO,
+       ATH_LED_ASSOC,
+       ATH_LED_TX,
+       ATH_LED_RX
+};
+
+struct ath_led {
+       struct ath_softc *sc;
+       struct led_classdev led_cdev;
+       enum ath_led_type led_type;
+       char name[32];
+       bool registered;
+};
+
+struct ath_rfkill {
+       struct rfkill *rfkill;
+       struct rfkill_ops ops;
+       char rfkill_name[32];
+};
+
+/********************/
+/* Main driver core */
+/********************/
+
+/*
+ * Default cache line size, in bytes.
+ * Used when PCI device not fully initialized by bootrom/BIOS
+*/
+#define DEFAULT_CACHELINE       32
+#define        ATH_DEFAULT_NOISE_FLOOR -95
+#define ATH_REGCLASSIDS_MAX     10
+#define ATH_CABQ_READY_TIME     80      /* % of beacon interval */
+#define ATH_MAX_SW_RETRIES      10
+#define ATH_CHAN_MAX            255
+#define IEEE80211_WEP_NKID      4       /* number of key ids */
+
+/*
+ * The key cache is used for h/w cipher state and also for
+ * tracking station state such as the current tx antenna.
+ * We also setup a mapping table between key cache slot indices
+ * and station state to short-circuit node lookups on rx.
+ * Different parts have different size key caches.  We handle
+ * up to ATH_KEYMAX entries (could dynamically allocate state).
+ */
+#define        ATH_KEYMAX              128     /* max key cache size we handle */
+
+#define ATH_TXPOWER_MAX         100     /* .5 dBm units */
+#define ATH_RSSI_DUMMY_MARKER   0x127
+#define ATH_RATE_DUMMY_MARKER   0
+
+#define SC_OP_INVALID           BIT(0)
+#define SC_OP_BEACONS           BIT(1)
+#define SC_OP_RXAGGR            BIT(2)
+#define SC_OP_TXAGGR            BIT(3)
+#define SC_OP_FULL_RESET        BIT(4)
+#define SC_OP_PREAMBLE_SHORT    BIT(5)
+#define SC_OP_PROTECT_ENABLE    BIT(6)
+#define SC_OP_RXFLUSH           BIT(7)
+#define SC_OP_LED_ASSOCIATED    BIT(8)
+#define SC_OP_RFKILL_REGISTERED BIT(9)
+#define SC_OP_WAIT_FOR_BEACON   BIT(12)
+#define SC_OP_LED_ON            BIT(13)
+#define SC_OP_SCANNING          BIT(14)
+#define SC_OP_TSF_RESET         BIT(15)
+#define SC_OP_WAIT_FOR_CAB      BIT(16)
+#define SC_OP_WAIT_FOR_PSPOLL_DATA BIT(17)
+#define SC_OP_WAIT_FOR_TX_ACK   BIT(18)
+#define SC_OP_BEACON_SYNC       BIT(19)
+
+struct ath_bus_ops {
+       void            (*read_cachesize)(struct ath_softc *sc, int *csz);
+       void            (*cleanup)(struct ath_softc *sc);
+       bool            (*eeprom_read)(struct ath_hw *ah, u32 off, u16 *data);
+};
+
+struct ath_wiphy;
+
+struct ath_softc {
+       struct ieee80211_hw *hw;
+       struct device *dev;
+
+       spinlock_t wiphy_lock; /* spinlock to protect ath_wiphy data */
+       struct ath_wiphy *pri_wiphy;
+       struct ath_wiphy **sec_wiphy; /* secondary wiphys (virtual radios); may
+                                      * have NULL entries */
+       int num_sec_wiphy; /* number of sec_wiphy pointers in the array */
+       int chan_idx;
+       int chan_is_ht;
+       struct ath_wiphy *next_wiphy;
+       struct work_struct chan_work;
+       int wiphy_select_failures;
+       unsigned long wiphy_select_first_fail;
+       struct delayed_work wiphy_work;
+       unsigned long wiphy_scheduler_int;
+       int wiphy_scheduler_index;
+
+       struct tasklet_struct intr_tq;
+       struct tasklet_struct bcon_tasklet;
+       struct ath_hw *sc_ah;
+       void __iomem *mem;
+       int irq;
+       spinlock_t sc_resetlock;
+       spinlock_t sc_serial_rw;
+       struct mutex mutex;
+
+       u8 curbssid[ETH_ALEN];
+       u8 bssidmask[ETH_ALEN];
+       u32 intrstatus;
+       u32 sc_flags; /* SC_OP_* */
+       u16 curtxpow;
+       u16 curaid;
+       u16 cachelsz;
+       u8 nbcnvifs;
+       u16 nvifs;
+       u8 tx_chainmask;
+       u8 rx_chainmask;
+       u32 keymax;
+       DECLARE_BITMAP(keymap, ATH_KEYMAX);
+       u8 splitmic;
+       atomic_t ps_usecount;
+       enum ath9k_int imask;
+       enum ath9k_ht_extprotspacing ht_extprotspacing;
+       enum ath9k_ht_macmode tx_chan_width;
+
+       struct ath_config config;
+       struct ath_rx rx;
+       struct ath_tx tx;
+       struct ath_beacon beacon;
+       struct ieee80211_rate rates[IEEE80211_NUM_BANDS][ATH_RATE_MAX];
+       const struct ath_rate_table *hw_rate_table[ATH9K_MODE_MAX];
+       const struct ath_rate_table *cur_rate_table;
+       struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
+
+       struct ath_led radio_led;
+       struct ath_led assoc_led;
+       struct ath_led tx_led;
+       struct ath_led rx_led;
+       struct delayed_work ath_led_blink_work;
+       int led_on_duration;
+       int led_off_duration;
+       int led_on_cnt;
+       int led_off_cnt;
+
+       int beacon_interval;
+
+       struct ath_rfkill rf_kill;
+       struct ath_ani ani;
+       struct ath9k_node_stats nodestats;
+#ifdef CONFIG_ATH9K_DEBUG
+       struct ath9k_debug debug;
+#endif
+       struct ath_bus_ops *bus_ops;
+       struct ath_beacon_config cur_beacon_conf;
+};
+
+struct ath_wiphy {
+       struct ath_softc *sc; /* shared for all virtual wiphys */
+       struct ieee80211_hw *hw;
+       enum ath_wiphy_state {
+               ATH_WIPHY_INACTIVE,
+               ATH_WIPHY_ACTIVE,
+               ATH_WIPHY_PAUSING,
+               ATH_WIPHY_PAUSED,
+               ATH_WIPHY_SCAN,
+       } state;
+       int chan_idx;
+       int chan_is_ht;
+};
+
+int ath_reset(struct ath_softc *sc, bool retry_tx);
+int ath_get_hal_qnum(u16 queue, struct ath_softc *sc);
+int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc);
+int ath_cabq_update(struct ath_softc *);
+
+static inline void ath_read_cachesize(struct ath_softc *sc, int *csz)
+{
+       sc->bus_ops->read_cachesize(sc, csz);
+}
+
+static inline void ath_bus_cleanup(struct ath_softc *sc)
+{
+       sc->bus_ops->cleanup(sc);
+}
+
+extern struct ieee80211_ops ath9k_ops;
+
+irqreturn_t ath_isr(int irq, void *dev);
+void ath_cleanup(struct ath_softc *sc);
+int ath_attach(u16 devid, struct ath_softc *sc);
+void ath_detach(struct ath_softc *sc);
+const char *ath_mac_bb_name(u32 mac_bb_version);
+const char *ath_rf_name(u16 rf_version);
+void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw);
+void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw,
+                          struct ath9k_channel *ichan);
+void ath_update_chainmask(struct ath_softc *sc, int is_ht);
+int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
+                   struct ath9k_channel *hchan);
+void ath_radio_enable(struct ath_softc *sc);
+void ath_radio_disable(struct ath_softc *sc);
+
+#ifdef CONFIG_PCI
+int ath_pci_init(void);
+void ath_pci_exit(void);
+#else
+static inline int ath_pci_init(void) { return 0; };
+static inline void ath_pci_exit(void) {};
+#endif
+
+#ifdef CONFIG_ATHEROS_AR71XX
+int ath_ahb_init(void);
+void ath_ahb_exit(void);
+#else
+static inline int ath_ahb_init(void) { return 0; };
+static inline void ath_ahb_exit(void) {};
+#endif
+
+static inline void ath9k_ps_wakeup(struct ath_softc *sc)
+{
+       if (atomic_inc_return(&sc->ps_usecount) == 1)
+               if (sc->sc_ah->power_mode !=  ATH9K_PM_AWAKE) {
+                       sc->sc_ah->restore_mode = sc->sc_ah->power_mode;
+                       ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE);
+               }
+}
+
+static inline void ath9k_ps_restore(struct ath_softc *sc)
+{
+       if (atomic_dec_and_test(&sc->ps_usecount))
+               if ((sc->hw->conf.flags & IEEE80211_CONF_PS) &&
+                   !(sc->sc_flags & (SC_OP_WAIT_FOR_BEACON |
+                                     SC_OP_WAIT_FOR_PSPOLL_DATA |
+                                     SC_OP_WAIT_FOR_TX_ACK)))
+                       ath9k_hw_setpower(sc->sc_ah,
+                                         sc->sc_ah->restore_mode);
+}
+
+
+void ath9k_set_bssid_mask(struct ieee80211_hw *hw);
+int ath9k_wiphy_add(struct ath_softc *sc);
+int ath9k_wiphy_del(struct ath_wiphy *aphy);
+void ath9k_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb);
+int ath9k_wiphy_pause(struct ath_wiphy *aphy);
+int ath9k_wiphy_unpause(struct ath_wiphy *aphy);
+int ath9k_wiphy_select(struct ath_wiphy *aphy);
+void ath9k_wiphy_set_scheduler(struct ath_softc *sc, unsigned int msec_int);
+void ath9k_wiphy_chan_work(struct work_struct *work);
+bool ath9k_wiphy_started(struct ath_softc *sc);
+void ath9k_wiphy_pause_all_forced(struct ath_softc *sc,
+                                 struct ath_wiphy *selected);
+bool ath9k_wiphy_scanning(struct ath_softc *sc);
+void ath9k_wiphy_work(struct work_struct *work);
+
+void ath9k_iowrite32(struct ath_hw *ah, u32 reg_offset, u32 val);
+unsigned int ath9k_ioread32(struct ath_hw *ah, u32 reg_offset);
+
+#endif /* ATH9K_H */
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
new file mode 100644 (file)
index 0000000..3639a2e
--- /dev/null
@@ -0,0 +1,767 @@
+/*
+ * Copyright (c) 2008-2009 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 "ath9k.h"
+
+#define FUDGE 2
+
+/*
+ *  This function will modify certain transmit queue properties depending on
+ *  the operating mode of the station (AP or AdHoc).  Parameters are AIFS
+ *  settings and channel width min/max
+*/
+static int ath_beaconq_config(struct ath_softc *sc)
+{
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath9k_tx_queue_info qi;
+
+       ath9k_hw_get_txq_props(ah, sc->beacon.beaconq, &qi);
+       if (sc->sc_ah->opmode == NL80211_IFTYPE_AP) {
+               /* Always burst out beacon and CAB traffic. */
+               qi.tqi_aifs = 1;
+               qi.tqi_cwmin = 0;
+               qi.tqi_cwmax = 0;
+       } else {
+               /* Adhoc mode; important thing is to use 2x cwmin. */
+               qi.tqi_aifs = sc->beacon.beacon_qi.tqi_aifs;
+               qi.tqi_cwmin = 2*sc->beacon.beacon_qi.tqi_cwmin;
+               qi.tqi_cwmax = sc->beacon.beacon_qi.tqi_cwmax;
+       }
+
+       if (!ath9k_hw_set_txq_props(ah, sc->beacon.beaconq, &qi)) {
+               DPRINTF(sc, ATH_DBG_FATAL,
+                       "Unable to update h/w beacon queue parameters\n");
+               return 0;
+       } else {
+               ath9k_hw_resettxqueue(ah, sc->beacon.beaconq);
+               return 1;
+       }
+}
+
+/*
+ *  Associates the beacon frame buffer with a transmit descriptor.  Will set
+ *  up all required antenna switch parameters, rate codes, and channel flags.
+ *  Beacons are always sent out at the lowest rate, and are not retried.
+*/
+static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp,
+                            struct ath_buf *bf)
+{
+       struct sk_buff *skb = bf->bf_mpdu;
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath_desc *ds;
+       struct ath9k_11n_rate_series series[4];
+       const struct ath_rate_table *rt;
+       int flags, antenna, ctsrate = 0, ctsduration = 0;
+       u8 rate;
+
+       ds = bf->bf_desc;
+       flags = ATH9K_TXDESC_NOACK;
+
+       if (((sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) ||
+            (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) &&
+           (ah->caps.hw_caps & ATH9K_HW_CAP_VEOL)) {
+               ds->ds_link = bf->bf_daddr; /* self-linked */
+               flags |= ATH9K_TXDESC_VEOL;
+               /* Let hardware handle antenna switching. */
+               antenna = 0;
+       } else {
+               ds->ds_link = 0;
+               /*
+                * Switch antenna every beacon.
+                * Should only switch every beacon period, not for every SWBA
+                * XXX assumes two antennae
+                */
+               antenna = ((sc->beacon.ast_be_xmit / sc->nbcnvifs) & 1 ? 2 : 1);
+       }
+
+       ds->ds_data = bf->bf_buf_addr;
+
+       rt = sc->cur_rate_table;
+       rate = rt->info[0].ratecode;
+       if (sc->sc_flags & SC_OP_PREAMBLE_SHORT)
+               rate |= rt->info[0].short_preamble;
+
+       ath9k_hw_set11n_txdesc(ah, ds, skb->len + FCS_LEN,
+                              ATH9K_PKT_TYPE_BEACON,
+                              MAX_RATE_POWER,
+                              ATH9K_TXKEYIX_INVALID,
+                              ATH9K_KEY_TYPE_CLEAR,
+                              flags);
+
+       /* NB: beacon's BufLen must be a multiple of 4 bytes */
+       ath9k_hw_filltxdesc(ah, ds, roundup(skb->len, 4),
+                           true, true, ds);
+
+       memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4);
+       series[0].Tries = 1;
+       series[0].Rate = rate;
+       series[0].ChSel = sc->tx_chainmask;
+       series[0].RateFlags = (ctsrate) ? ATH9K_RATESERIES_RTS_CTS : 0;
+       ath9k_hw_set11n_ratescenario(ah, ds, ds, 0, ctsrate, ctsduration,
+                                    series, 4, 0);
+}
+
+static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw,
+                                          struct ieee80211_vif *vif)
+{
+       struct ath_wiphy *aphy = hw->priv;
+       struct ath_softc *sc = aphy->sc;
+       struct ath_buf *bf;
+       struct ath_vif *avp;
+       struct sk_buff *skb;
+       struct ath_txq *cabq;
+       struct ieee80211_tx_info *info;
+       int cabq_depth;
+
+       if (aphy->state != ATH_WIPHY_ACTIVE)
+               return NULL;
+
+       avp = (void *)vif->drv_priv;
+       cabq = sc->beacon.cabq;
+
+       if (avp->av_bcbuf == NULL)
+               return NULL;
+
+       /* Release the old beacon first */
+
+       bf = avp->av_bcbuf;
+       skb = bf->bf_mpdu;
+       if (skb) {
+               dma_unmap_single(sc->dev, bf->bf_dmacontext,
+                                skb->len, DMA_TO_DEVICE);
+               dev_kfree_skb_any(skb);
+       }
+
+       /* Get a new beacon from mac80211 */
+
+       skb = ieee80211_beacon_get(hw, vif);
+       bf->bf_mpdu = skb;
+       if (skb == NULL)
+               return NULL;
+       ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp =
+               avp->tsf_adjust;
+
+       info = IEEE80211_SKB_CB(skb);
+       if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
+               /*
+                * TODO: make sure the seq# gets assigned properly (vs. other
+                * TX frames)
+                */
+               struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+               sc->tx.seq_no += 0x10;
+               hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
+               hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no);
+       }
+
+       bf->bf_buf_addr = bf->bf_dmacontext =
+               dma_map_single(sc->dev, skb->data,
+                              skb->len, DMA_TO_DEVICE);
+       if (unlikely(dma_mapping_error(sc->dev, bf->bf_buf_addr))) {
+               dev_kfree_skb_any(skb);
+               bf->bf_mpdu = NULL;
+               DPRINTF(sc, ATH_DBG_FATAL, "dma_mapping_error on beaconing\n");
+               return NULL;
+       }
+
+       skb = ieee80211_get_buffered_bc(hw, vif);
+
+       /*
+        * if the CABQ traffic from previous DTIM is pending and the current
+        *  beacon is also a DTIM.
+        *  1) if there is only one vif let the cab traffic continue.
+        *  2) if there are more than one vif and we are using staggered
+        *     beacons, then drain the cabq by dropping all the frames in
+        *     the cabq so that the current vifs cab traffic can be scheduled.
+        */
+       spin_lock_bh(&cabq->axq_lock);
+       cabq_depth = cabq->axq_depth;
+       spin_unlock_bh(&cabq->axq_lock);
+
+       if (skb && cabq_depth) {
+               if (sc->nvifs > 1) {
+                       DPRINTF(sc, ATH_DBG_BEACON,
+                               "Flushing previous cabq traffic\n");
+                       ath_draintxq(sc, cabq, false);
+               }
+       }
+
+       ath_beacon_setup(sc, avp, bf);
+
+       while (skb) {
+               ath_tx_cabq(hw, skb);
+               skb = ieee80211_get_buffered_bc(hw, vif);
+       }
+
+       return bf;
+}
+
+/*
+ * Startup beacon transmission for adhoc mode when they are sent entirely
+ * by the hardware using the self-linked descriptor + veol trick.
+*/
+static void ath_beacon_start_adhoc(struct ath_softc *sc,
+                                  struct ieee80211_vif *vif)
+{
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath_buf *bf;
+       struct ath_vif *avp;
+       struct sk_buff *skb;
+
+       avp = (void *)vif->drv_priv;
+
+       if (avp->av_bcbuf == NULL)
+               return;
+
+       bf = avp->av_bcbuf;
+       skb = bf->bf_mpdu;
+
+       ath_beacon_setup(sc, avp, bf);
+
+       /* NB: caller is known to have already stopped tx dma */
+       ath9k_hw_puttxbuf(ah, sc->beacon.beaconq, bf->bf_daddr);
+       ath9k_hw_txstart(ah, sc->beacon.beaconq);
+       DPRINTF(sc, ATH_DBG_BEACON, "TXDP%u = %llx (%p)\n",
+               sc->beacon.beaconq, ito64(bf->bf_daddr), bf->bf_desc);
+}
+
+int ath_beaconq_setup(struct ath_hw *ah)
+{
+       struct ath9k_tx_queue_info qi;
+
+       memset(&qi, 0, sizeof(qi));
+       qi.tqi_aifs = 1;
+       qi.tqi_cwmin = 0;
+       qi.tqi_cwmax = 0;
+       /* NB: don't enable any interrupts */
+       return ath9k_hw_setuptxqueue(ah, ATH9K_TX_QUEUE_BEACON, &qi);
+}
+
+int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif)
+{
+       struct ath_softc *sc = aphy->sc;
+       struct ath_vif *avp;
+       struct ath_buf *bf;
+       struct sk_buff *skb;
+       __le64 tstamp;
+
+       avp = (void *)vif->drv_priv;
+
+       /* Allocate a beacon descriptor if we haven't done so. */
+       if (!avp->av_bcbuf) {
+               /* Allocate beacon state for hostap/ibss.  We know
+                * a buffer is available. */
+               avp->av_bcbuf = list_first_entry(&sc->beacon.bbuf,
+                                                struct ath_buf, list);
+               list_del(&avp->av_bcbuf->list);
+
+               if (sc->sc_ah->opmode == NL80211_IFTYPE_AP ||
+                   !(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_VEOL)) {
+                       int slot;
+                       /*
+                        * Assign the vif to a beacon xmit slot. As
+                        * above, this cannot fail to find one.
+                        */
+                       avp->av_bslot = 0;
+                       for (slot = 0; slot < ATH_BCBUF; slot++)
+                               if (sc->beacon.bslot[slot] == NULL) {
+                                       /*
+                                        * XXX hack, space out slots to better
+                                        * deal with misses
+                                        */
+                                       if (slot+1 < ATH_BCBUF &&
+                                           sc->beacon.bslot[slot+1] == NULL) {
+                                               avp->av_bslot = slot+1;
+                                               break;
+                                       }
+                                       avp->av_bslot = slot;
+                                       /* NB: keep looking for a double slot */
+                               }
+                       BUG_ON(sc->beacon.bslot[avp->av_bslot] != NULL);
+                       sc->beacon.bslot[avp->av_bslot] = vif;
+                       sc->beacon.bslot_aphy[avp->av_bslot] = aphy;
+                       sc->nbcnvifs++;
+               }
+       }
+
+       /* release the previous beacon frame, if it already exists. */
+       bf = avp->av_bcbuf;
+       if (bf->bf_mpdu != NULL) {
+               skb = bf->bf_mpdu;
+               dma_unmap_single(sc->dev, bf->bf_dmacontext,
+                                skb->len, DMA_TO_DEVICE);
+               dev_kfree_skb_any(skb);
+               bf->bf_mpdu = NULL;
+       }
+
+       /* NB: the beacon data buffer must be 32-bit aligned. */
+       skb = ieee80211_beacon_get(sc->hw, vif);
+       if (skb == NULL) {
+               DPRINTF(sc, ATH_DBG_BEACON, "cannot get skb\n");
+               return -ENOMEM;
+       }
+
+       tstamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp;
+       sc->beacon.bc_tstamp = le64_to_cpu(tstamp);
+       /* Calculate a TSF adjustment factor required for staggered beacons. */
+       if (avp->av_bslot > 0) {
+               u64 tsfadjust;
+               int intval;
+
+               intval = sc->beacon_interval ? : ATH_DEFAULT_BINTVAL;
+
+               /*
+                * Calculate the TSF offset for this beacon slot, i.e., the
+                * number of usecs that need to be added to the timestamp field
+                * in Beacon and Probe Response frames. Beacon slot 0 is
+                * processed at the correct offset, so it does not require TSF
+                * adjustment. Other slots are adjusted to get the timestamp
+                * close to the TBTT for the BSS.
+                */
+               tsfadjust = intval * avp->av_bslot / ATH_BCBUF;
+               avp->tsf_adjust = cpu_to_le64(TU_TO_USEC(tsfadjust));
+
+               DPRINTF(sc, ATH_DBG_BEACON,
+                       "stagger beacons, bslot %d intval %u tsfadjust %llu\n",
+                       avp->av_bslot, intval, (unsigned long long)tsfadjust);
+
+               ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp =
+                       avp->tsf_adjust;
+       } else
+               avp->tsf_adjust = cpu_to_le64(0);
+
+       bf->bf_mpdu = skb;
+       bf->bf_buf_addr = bf->bf_dmacontext =
+               dma_map_single(sc->dev, skb->data,
+                              skb->len, DMA_TO_DEVICE);
+       if (unlikely(dma_mapping_error(sc->dev, bf->bf_buf_addr))) {
+               dev_kfree_skb_any(skb);
+               bf->bf_mpdu = NULL;
+               DPRINTF(sc, ATH_DBG_FATAL,
+                       "dma_mapping_error on beacon alloc\n");
+               return -ENOMEM;
+       }
+
+       return 0;
+}
+
+void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp)
+{
+       if (avp->av_bcbuf != NULL) {
+               struct ath_buf *bf;
+
+               if (avp->av_bslot != -1) {
+                       sc->beacon.bslot[avp->av_bslot] = NULL;
+                       sc->beacon.bslot_aphy[avp->av_bslot] = NULL;
+                       sc->nbcnvifs--;
+               }
+
+               bf = avp->av_bcbuf;
+               if (bf->bf_mpdu != NULL) {
+                       struct sk_buff *skb = bf->bf_mpdu;
+                       dma_unmap_single(sc->dev, bf->bf_dmacontext,
+                                        skb->len, DMA_TO_DEVICE);
+                       dev_kfree_skb_any(skb);
+                       bf->bf_mpdu = NULL;
+               }
+               list_add_tail(&bf->list, &sc->beacon.bbuf);
+
+               avp->av_bcbuf = NULL;
+       }
+}
+
+void ath_beacon_tasklet(unsigned long data)
+{
+       struct ath_softc *sc = (struct ath_softc *)data;
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath_buf *bf = NULL;
+       struct ieee80211_vif *vif;
+       struct ath_wiphy *aphy;
+       int slot;
+       u32 bfaddr, bc = 0, tsftu;
+       u64 tsf;
+       u16 intval;
+
+       /*
+        * Check if the previous beacon has gone out.  If
+        * not don't try to post another, skip this period
+        * and wait for the next.  Missed beacons indicate
+        * a problem and should not occur.  If we miss too
+        * many consecutive beacons reset the device.
+        */
+       if (ath9k_hw_numtxpending(ah, sc->beacon.beaconq) != 0) {
+               sc->beacon.bmisscnt++;
+
+               if (sc->beacon.bmisscnt < BSTUCK_THRESH) {
+                       DPRINTF(sc, ATH_DBG_BEACON,
+                               "missed %u consecutive beacons\n",
+                               sc->beacon.bmisscnt);
+               } else if (sc->beacon.bmisscnt >= BSTUCK_THRESH) {
+                       DPRINTF(sc, ATH_DBG_BEACON,
+                               "beacon is officially stuck\n");
+                       sc->sc_flags |= SC_OP_TSF_RESET;
+                       ath_reset(sc, false);
+               }
+
+               return;
+       }
+
+       if (sc->beacon.bmisscnt != 0) {
+               DPRINTF(sc, ATH_DBG_BEACON,
+                       "resume beacon xmit after %u misses\n",
+                       sc->beacon.bmisscnt);
+               sc->beacon.bmisscnt = 0;
+       }
+
+       /*
+        * Generate beacon frames. we are sending frames
+        * staggered so calculate the slot for this frame based
+        * on the tsf to safeguard against missing an swba.
+        */
+
+       intval = sc->beacon_interval ? : ATH_DEFAULT_BINTVAL;
+
+       tsf = ath9k_hw_gettsf64(ah);
+       tsftu = TSF_TO_TU(tsf>>32, tsf);
+       slot = ((tsftu % intval) * ATH_BCBUF) / intval;
+       /*
+        * Reverse the slot order to get slot 0 on the TBTT offset that does
+        * not require TSF adjustment and other slots adding
+        * slot/ATH_BCBUF * beacon_int to timestamp. For example, with
+        * ATH_BCBUF = 4, we process beacon slots as follows: 3 2 1 0 3 2 1 ..
+        * and slot 0 is at correct offset to TBTT.
+        */
+       slot = ATH_BCBUF - slot - 1;
+       vif = sc->beacon.bslot[slot];
+       aphy = sc->beacon.bslot_aphy[slot];
+
+       DPRINTF(sc, ATH_DBG_BEACON,
+               "slot %d [tsf %llu tsftu %u intval %u] vif %p\n",
+               slot, tsf, tsftu, intval, vif);
+
+       bfaddr = 0;
+       if (vif) {
+               bf = ath_beacon_generate(aphy->hw, vif);
+               if (bf != NULL) {
+                       bfaddr = bf->bf_daddr;
+                       bc = 1;
+               }
+       }
+
+       /*
+        * Handle slot time change when a non-ERP station joins/leaves
+        * an 11g network.  The 802.11 layer notifies us via callback,
+        * we mark updateslot, then wait one beacon before effecting
+        * the change.  This gives associated stations at least one
+        * beacon interval to note the state change.
+        *
+        * NB: The slot time change state machine is clocked according
+        *     to whether we are bursting or staggering beacons.  We
+        *     recognize the request to update and record the current
+        *     slot then don't transition until that slot is reached
+        *     again.  If we miss a beacon for that slot then we'll be
+        *     slow to transition but we'll be sure at least one beacon
+        *     interval has passed.  When bursting slot is always left
+        *     set to ATH_BCBUF so this check is a noop.
+        */
+       if (sc->beacon.updateslot == UPDATE) {
+               sc->beacon.updateslot = COMMIT; /* commit next beacon */
+               sc->beacon.slotupdate = slot;
+       } else if (sc->beacon.updateslot == COMMIT && sc->beacon.slotupdate == slot) {
+               ath9k_hw_setslottime(sc->sc_ah, sc->beacon.slottime);
+               sc->beacon.updateslot = OK;
+       }
+       if (bfaddr != 0) {
+               /*
+                * Stop any current dma and put the new frame(s) on the queue.
+                * This should never fail since we check above that no frames
+                * are still pending on the queue.
+                */
+               if (!ath9k_hw_stoptxdma(ah, sc->beacon.beaconq)) {
+                       DPRINTF(sc, ATH_DBG_FATAL,
+                               "beacon queue %u did not stop?\n", sc->beacon.beaconq);
+               }
+
+               /* NB: cabq traffic should already be queued and primed */
+               ath9k_hw_puttxbuf(ah, sc->beacon.beaconq, bfaddr);
+               ath9k_hw_txstart(ah, sc->beacon.beaconq);
+
+               sc->beacon.ast_be_xmit += bc;     /* XXX per-vif? */
+       }
+}
+
+/*
+ * For multi-bss ap support beacons are either staggered evenly over N slots or
+ * burst together.  For the former arrange for the SWBA to be delivered for each
+ * slot. Slots that are not occupied will generate nothing.
+ */
+static void ath_beacon_config_ap(struct ath_softc *sc,
+                                struct ath_beacon_config *conf)
+{
+       u32 nexttbtt, intval;
+
+       /* Configure the timers only when the TSF has to be reset */
+
+       if (!(sc->sc_flags & SC_OP_TSF_RESET))
+               return;
+
+       /* NB: the beacon interval is kept internally in TU's */
+       intval = conf->beacon_interval & ATH9K_BEACON_PERIOD;
+       intval /= ATH_BCBUF;    /* for staggered beacons */
+       nexttbtt = intval;
+       intval |= ATH9K_BEACON_RESET_TSF;
+
+       /*
+        * In AP mode we enable the beacon timers and SWBA interrupts to
+        * prepare beacon frames.
+        */
+       intval |= ATH9K_BEACON_ENA;
+       sc->imask |= ATH9K_INT_SWBA;
+       ath_beaconq_config(sc);
+
+       /* Set the computed AP beacon timers */
+
+       ath9k_hw_set_interrupts(sc->sc_ah, 0);
+       ath9k_hw_beaconinit(sc->sc_ah, nexttbtt, intval);
+       sc->beacon.bmisscnt = 0;
+       ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
+
+       /* Clear the reset TSF flag, so that subsequent beacon updation
+          will not reset the HW TSF. */
+
+       sc->sc_flags &= ~SC_OP_TSF_RESET;
+}
+
+/*
+ * This sets up the beacon timers according to the timestamp of the last
+ * received beacon and the current TSF, configures PCF and DTIM
+ * handling, programs the sleep registers so the hardware will wakeup in
+ * time to receive beacons, and configures the beacon miss handling so
+ * we'll receive a BMISS interrupt when we stop seeing beacons from the AP
+ * we've associated with.
+ */
+static void ath_beacon_config_sta(struct ath_softc *sc,
+                                 struct ath_beacon_config *conf)
+{
+       struct ath9k_beacon_state bs;
+       int dtimperiod, dtimcount, sleepduration;
+       int cfpperiod, cfpcount;
+       u32 nexttbtt = 0, intval, tsftu;
+       u64 tsf;
+       int num_beacons, offset, dtim_dec_count, cfp_dec_count;
+
+       memset(&bs, 0, sizeof(bs));
+       intval = conf->beacon_interval & ATH9K_BEACON_PERIOD;
+
+       /*
+        * Setup dtim and cfp parameters according to
+        * last beacon we received (which may be none).
+        */
+       dtimperiod = conf->dtim_period;
+       if (dtimperiod <= 0)            /* NB: 0 if not known */
+               dtimperiod = 1;
+       dtimcount = conf->dtim_count;
+       if (dtimcount >= dtimperiod)    /* NB: sanity check */
+               dtimcount = 0;
+       cfpperiod = 1;                  /* NB: no PCF support yet */
+       cfpcount = 0;
+
+       sleepduration = conf->listen_interval * intval;
+       if (sleepduration <= 0)
+               sleepduration = intval;
+
+       /*
+        * Pull nexttbtt forward to reflect the current
+        * TSF and calculate dtim+cfp state for the result.
+        */
+       tsf = ath9k_hw_gettsf64(sc->sc_ah);
+       tsftu = TSF_TO_TU(tsf>>32, tsf) + FUDGE;
+
+       num_beacons = tsftu / intval + 1;
+       offset = tsftu % intval;
+       nexttbtt = tsftu - offset;
+       if (offset)
+               nexttbtt += intval;
+
+       /* DTIM Beacon every dtimperiod Beacon */
+       dtim_dec_count = num_beacons % dtimperiod;
+       /* CFP every cfpperiod DTIM Beacon */
+       cfp_dec_count = (num_beacons / dtimperiod) % cfpperiod;
+       if (dtim_dec_count)
+               cfp_dec_count++;
+
+       dtimcount -= dtim_dec_count;
+       if (dtimcount < 0)
+               dtimcount += dtimperiod;
+
+       cfpcount -= cfp_dec_count;
+       if (cfpcount < 0)
+               cfpcount += cfpperiod;
+
+       bs.bs_intval = intval;
+       bs.bs_nexttbtt = nexttbtt;
+       bs.bs_dtimperiod = dtimperiod*intval;
+       bs.bs_nextdtim = bs.bs_nexttbtt + dtimcount*intval;
+       bs.bs_cfpperiod = cfpperiod*bs.bs_dtimperiod;
+       bs.bs_cfpnext = bs.bs_nextdtim + cfpcount*bs.bs_dtimperiod;
+       bs.bs_cfpmaxduration = 0;
+
+       /*
+        * Calculate the number of consecutive beacons to miss* before taking
+        * a BMISS interrupt. The configuration is specified in TU so we only
+        * need calculate based on the beacon interval.  Note that we clamp the
+        * result to at most 15 beacons.
+        */
+       if (sleepduration > intval) {
+               bs.bs_bmissthreshold = conf->listen_interval *
+                       ATH_DEFAULT_BMISS_LIMIT / 2;
+       } else {
+               bs.bs_bmissthreshold = DIV_ROUND_UP(conf->bmiss_timeout, intval);
+               if (bs.bs_bmissthreshold > 15)
+                       bs.bs_bmissthreshold = 15;
+               else if (bs.bs_bmissthreshold <= 0)
+                       bs.bs_bmissthreshold = 1;
+       }
+
+       /*
+        * Calculate sleep duration. The configuration is given in ms.
+        * We ensure a multiple of the beacon period is used. Also, if the sleep
+        * duration is greater than the DTIM period then it makes senses
+        * to make it a multiple of that.
+        *
+        * XXX fixed at 100ms
+        */
+
+       bs.bs_sleepduration = roundup(IEEE80211_MS_TO_TU(100), sleepduration);
+       if (bs.bs_sleepduration > bs.bs_dtimperiod)
+               bs.bs_sleepduration = bs.bs_dtimperiod;
+
+       /* TSF out of range threshold fixed at 1 second */
+       bs.bs_tsfoor_threshold = ATH9K_TSFOOR_THRESHOLD;
+
+       DPRINTF(sc, ATH_DBG_BEACON, "tsf: %llu tsftu: %u\n", tsf, tsftu);
+       DPRINTF(sc, ATH_DBG_BEACON,
+               "bmiss: %u sleep: %u cfp-period: %u maxdur: %u next: %u\n",
+               bs.bs_bmissthreshold, bs.bs_sleepduration,
+               bs.bs_cfpperiod, bs.bs_cfpmaxduration, bs.bs_cfpnext);
+
+       /* Set the computed STA beacon timers */
+
+       ath9k_hw_set_interrupts(sc->sc_ah, 0);
+       ath9k_hw_set_sta_beacon_timers(sc->sc_ah, &bs);
+       sc->imask |= ATH9K_INT_BMISS;
+       ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
+}
+
+static void ath_beacon_config_adhoc(struct ath_softc *sc,
+                                   struct ath_beacon_config *conf,
+                                   struct ieee80211_vif *vif)
+{
+       u64 tsf;
+       u32 tsftu, intval, nexttbtt;
+
+       intval = conf->beacon_interval & ATH9K_BEACON_PERIOD;
+
+       /*
+        * It looks like mac80211 may end up using beacon interval of zero in
+        * some cases (at least for mesh point). Avoid getting into an
+        * infinite loop by using a bit safer value instead..
+        */
+       if (intval == 0)
+               intval = 100;
+
+       /* Pull nexttbtt forward to reflect the current TSF */
+
+       nexttbtt = TSF_TO_TU(sc->beacon.bc_tstamp >> 32, sc->beacon.bc_tstamp);
+       if (nexttbtt == 0)
+                nexttbtt = intval;
+        else if (intval)
+                nexttbtt = roundup(nexttbtt, intval);
+
+       tsf = ath9k_hw_gettsf64(sc->sc_ah);
+       tsftu = TSF_TO_TU((u32)(tsf>>32), (u32)tsf) + FUDGE;
+       do {
+               nexttbtt += intval;
+       } while (nexttbtt < tsftu);
+
+       DPRINTF(sc, ATH_DBG_BEACON,
+               "IBSS nexttbtt %u intval %u (%u)\n",
+               nexttbtt, intval, conf->beacon_interval);
+
+       /*
+        * In IBSS mode enable the beacon timers but only enable SWBA interrupts
+        * if we need to manually prepare beacon frames.  Otherwise we use a
+        * self-linked tx descriptor and let the hardware deal with things.
+        */
+       intval |= ATH9K_BEACON_ENA;
+       if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_VEOL))
+               sc->imask |= ATH9K_INT_SWBA;
+
+       ath_beaconq_config(sc);
+
+       /* Set the computed ADHOC beacon timers */
+
+       ath9k_hw_set_interrupts(sc->sc_ah, 0);
+       ath9k_hw_beaconinit(sc->sc_ah, nexttbtt, intval);
+       sc->beacon.bmisscnt = 0;
+       ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
+
+       /* FIXME: Handle properly when vif is NULL */
+       if (vif && sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_VEOL)
+               ath_beacon_start_adhoc(sc, vif);
+}
+
+void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif)
+{
+       struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf;
+       enum nl80211_iftype iftype;
+
+       /* Setup the beacon configuration parameters */
+
+       if (vif) {
+               struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
+
+               iftype = vif->type;
+
+               cur_conf->beacon_interval = bss_conf->beacon_int;
+               cur_conf->dtim_period = bss_conf->dtim_period;
+               cur_conf->listen_interval = 1;
+               cur_conf->dtim_count = 1;
+               cur_conf->bmiss_timeout =
+                       ATH_DEFAULT_BMISS_LIMIT * cur_conf->beacon_interval;
+       } else {
+               iftype = sc->sc_ah->opmode;
+       }
+
+
+       switch (iftype) {
+       case NL80211_IFTYPE_AP:
+               ath_beacon_config_ap(sc, cur_conf);
+               break;
+       case NL80211_IFTYPE_ADHOC:
+       case NL80211_IFTYPE_MESH_POINT:
+               ath_beacon_config_adhoc(sc, cur_conf, vif);
+               break;
+       case NL80211_IFTYPE_STATION:
+               ath_beacon_config_sta(sc, cur_conf);
+               break;
+       default:
+               DPRINTF(sc, ATH_DBG_CONFIG,
+                       "Unsupported beaconing mode\n");
+               return;
+       }
+
+       sc->sc_flags |= SC_OP_BEACONS;
+}
diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c
new file mode 100644 (file)
index 0000000..a32d7e7
--- /dev/null
@@ -0,0 +1,1039 @@
+/*
+ * Copyright (c) 2008-2009 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 "ath9k.h"
+
+/* We can tune this as we go by monitoring really low values */
+#define ATH9K_NF_TOO_LOW       -60
+
+/* AR5416 may return very high value (like -31 dBm), in those cases the nf
+ * is incorrect and we should use the static NF value. Later we can try to
+ * find out why they are reporting these values */
+
+static bool ath9k_hw_nf_in_range(struct ath_hw *ah, s16 nf)
+{
+       if (nf > ATH9K_NF_TOO_LOW) {
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "noise floor value detected (%d) is "
+                       "lower than what we think is a "
+                       "reasonable value (%d)\n",
+                       nf, ATH9K_NF_TOO_LOW);
+               return false;
+       }
+       return true;
+}
+
+static int16_t ath9k_hw_get_nf_hist_mid(int16_t *nfCalBuffer)
+{
+       int16_t nfval;
+       int16_t sort[ATH9K_NF_CAL_HIST_MAX];
+       int i, j;
+
+       for (i = 0; i < ATH9K_NF_CAL_HIST_MAX; i++)
+               sort[i] = nfCalBuffer[i];
+
+       for (i = 0; i < ATH9K_NF_CAL_HIST_MAX - 1; i++) {
+               for (j = 1; j < ATH9K_NF_CAL_HIST_MAX - i; j++) {
+                       if (sort[j] > sort[j - 1]) {
+                               nfval = sort[j];
+                               sort[j] = sort[j - 1];
+                               sort[j - 1] = nfval;
+                       }
+               }
+       }
+       nfval = sort[(ATH9K_NF_CAL_HIST_MAX - 1) >> 1];
+
+       return nfval;
+}
+
+static void ath9k_hw_update_nfcal_hist_buffer(struct ath9k_nfcal_hist *h,
+                                             int16_t *nfarray)
+{
+       int i;
+
+       for (i = 0; i < NUM_NF_READINGS; i++) {
+               h[i].nfCalBuffer[h[i].currIndex] = nfarray[i];
+
+               if (++h[i].currIndex >= ATH9K_NF_CAL_HIST_MAX)
+                       h[i].currIndex = 0;
+
+               if (h[i].invalidNFcount > 0) {
+                       if (nfarray[i] < AR_PHY_CCA_MIN_BAD_VALUE ||
+                           nfarray[i] > AR_PHY_CCA_MAX_HIGH_VALUE) {
+                               h[i].invalidNFcount = ATH9K_NF_CAL_HIST_MAX;
+                       } else {
+                               h[i].invalidNFcount--;
+                               h[i].privNF = nfarray[i];
+                       }
+               } else {
+                       h[i].privNF =
+                               ath9k_hw_get_nf_hist_mid(h[i].nfCalBuffer);
+               }
+       }
+       return;
+}
+
+static void ath9k_hw_do_getnf(struct ath_hw *ah,
+                             int16_t nfarray[NUM_NF_READINGS])
+{
+       int16_t nf;
+
+       if (AR_SREV_9280_10_OR_LATER(ah))
+               nf = MS(REG_READ(ah, AR_PHY_CCA), AR9280_PHY_MINCCA_PWR);
+       else
+               nf = MS(REG_READ(ah, AR_PHY_CCA), AR_PHY_MINCCA_PWR);
+
+       if (nf & 0x100)
+               nf = 0 - ((nf ^ 0x1ff) + 1);
+       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+               "NF calibrated [ctl] [chain 0] is %d\n", nf);
+       nfarray[0] = nf;
+
+       if (!AR_SREV_9285(ah)) {
+               if (AR_SREV_9280_10_OR_LATER(ah))
+                       nf = MS(REG_READ(ah, AR_PHY_CH1_CCA),
+                                       AR9280_PHY_CH1_MINCCA_PWR);
+               else
+                       nf = MS(REG_READ(ah, AR_PHY_CH1_CCA),
+                                       AR_PHY_CH1_MINCCA_PWR);
+
+               if (nf & 0x100)
+                       nf = 0 - ((nf ^ 0x1ff) + 1);
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                               "NF calibrated [ctl] [chain 1] is %d\n", nf);
+               nfarray[1] = nf;
+
+               if (!AR_SREV_9280(ah)) {
+                       nf = MS(REG_READ(ah, AR_PHY_CH2_CCA),
+                                       AR_PHY_CH2_MINCCA_PWR);
+                       if (nf & 0x100)
+                               nf = 0 - ((nf ^ 0x1ff) + 1);
+                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                               "NF calibrated [ctl] [chain 2] is %d\n", nf);
+                       nfarray[2] = nf;
+               }
+       }
+
+       if (AR_SREV_9280_10_OR_LATER(ah))
+               nf = MS(REG_READ(ah, AR_PHY_EXT_CCA),
+                       AR9280_PHY_EXT_MINCCA_PWR);
+       else
+               nf = MS(REG_READ(ah, AR_PHY_EXT_CCA),
+                       AR_PHY_EXT_MINCCA_PWR);
+
+       if (nf & 0x100)
+               nf = 0 - ((nf ^ 0x1ff) + 1);
+       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+               "NF calibrated [ext] [chain 0] is %d\n", nf);
+       nfarray[3] = nf;
+
+       if (!AR_SREV_9285(ah)) {
+               if (AR_SREV_9280_10_OR_LATER(ah))
+                       nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA),
+                                       AR9280_PHY_CH1_EXT_MINCCA_PWR);
+               else
+                       nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA),
+                                       AR_PHY_CH1_EXT_MINCCA_PWR);
+
+               if (nf & 0x100)
+                       nf = 0 - ((nf ^ 0x1ff) + 1);
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                               "NF calibrated [ext] [chain 1] is %d\n", nf);
+               nfarray[4] = nf;
+
+               if (!AR_SREV_9280(ah)) {
+                       nf = MS(REG_READ(ah, AR_PHY_CH2_EXT_CCA),
+                                       AR_PHY_CH2_EXT_MINCCA_PWR);
+                       if (nf & 0x100)
+                               nf = 0 - ((nf ^ 0x1ff) + 1);
+                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                               "NF calibrated [ext] [chain 2] is %d\n", nf);
+                       nfarray[5] = nf;
+               }
+       }
+}
+
+static bool getNoiseFloorThresh(struct ath_hw *ah,
+                               enum ieee80211_band band,
+                               int16_t *nft)
+{
+       switch (band) {
+       case IEEE80211_BAND_5GHZ:
+               *nft = (int8_t)ah->eep_ops->get_eeprom(ah, EEP_NFTHRESH_5);
+               break;
+       case IEEE80211_BAND_2GHZ:
+               *nft = (int8_t)ah->eep_ops->get_eeprom(ah, EEP_NFTHRESH_2);
+               break;
+       default:
+               BUG_ON(1);
+               return false;
+       }
+
+       return true;
+}
+
+static void ath9k_hw_setup_calibration(struct ath_hw *ah,
+                                      struct ath9k_cal_list *currCal)
+{
+       REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(0),
+                     AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX,
+                     currCal->calData->calCountMax);
+
+       switch (currCal->calData->calType) {
+       case IQ_MISMATCH_CAL:
+               REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ);
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "starting IQ Mismatch Calibration\n");
+               break;
+       case ADC_GAIN_CAL:
+               REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_GAIN);
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "starting ADC Gain Calibration\n");
+               break;
+       case ADC_DC_CAL:
+               REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_PER);
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "starting ADC DC Calibration\n");
+               break;
+       case ADC_DC_INIT_CAL:
+               REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_INIT);
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "starting Init ADC DC Calibration\n");
+               break;
+       }
+
+       REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0),
+                   AR_PHY_TIMING_CTRL4_DO_CAL);
+}
+
+static void ath9k_hw_reset_calibration(struct ath_hw *ah,
+                                      struct ath9k_cal_list *currCal)
+{
+       int i;
+
+       ath9k_hw_setup_calibration(ah, currCal);
+
+       currCal->calState = CAL_RUNNING;
+
+       for (i = 0; i < AR5416_MAX_CHAINS; i++) {
+               ah->meas0.sign[i] = 0;
+               ah->meas1.sign[i] = 0;
+               ah->meas2.sign[i] = 0;
+               ah->meas3.sign[i] = 0;
+       }
+
+       ah->cal_samples = 0;
+}
+
+static bool ath9k_hw_per_calibration(struct ath_hw *ah,
+                                    struct ath9k_channel *ichan,
+                                    u8 rxchainmask,
+                                    struct ath9k_cal_list *currCal)
+{
+       bool iscaldone = false;
+
+       if (currCal->calState == CAL_RUNNING) {
+               if (!(REG_READ(ah, AR_PHY_TIMING_CTRL4(0)) &
+                     AR_PHY_TIMING_CTRL4_DO_CAL)) {
+
+                       currCal->calData->calCollect(ah);
+                       ah->cal_samples++;
+
+                       if (ah->cal_samples >= currCal->calData->calNumSamples) {
+                               int i, numChains = 0;
+                               for (i = 0; i < AR5416_MAX_CHAINS; i++) {
+                                       if (rxchainmask & (1 << i))
+                                               numChains++;
+                               }
+
+                               currCal->calData->calPostProc(ah, numChains);
+                               ichan->CalValid |= currCal->calData->calType;
+                               currCal->calState = CAL_DONE;
+                               iscaldone = true;
+                       } else {
+                               ath9k_hw_setup_calibration(ah, currCal);
+                       }
+               }
+       } else if (!(ichan->CalValid & currCal->calData->calType)) {
+               ath9k_hw_reset_calibration(ah, currCal);
+       }
+
+       return iscaldone;
+}
+
+/* Assumes you are talking about the currently configured channel */
+static bool ath9k_hw_iscal_supported(struct ath_hw *ah,
+                                    enum ath9k_cal_types calType)
+{
+       struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
+
+       switch (calType & ah->supp_cals) {
+       case IQ_MISMATCH_CAL: /* Both 2 GHz and 5 GHz support OFDM */
+               return true;
+       case ADC_GAIN_CAL:
+       case ADC_DC_CAL:
+               if (!(conf->channel->band == IEEE80211_BAND_2GHZ &&
+                     conf_is_ht20(conf)))
+                       return true;
+               break;
+       }
+       return false;
+}
+
+static void ath9k_hw_iqcal_collect(struct ath_hw *ah)
+{
+       int i;
+
+       for (i = 0; i < AR5416_MAX_CHAINS; i++) {
+               ah->totalPowerMeasI[i] +=
+                       REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
+               ah->totalPowerMeasQ[i] +=
+                       REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
+               ah->totalIqCorrMeas[i] +=
+                       (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n",
+                       ah->cal_samples, i, ah->totalPowerMeasI[i],
+                       ah->totalPowerMeasQ[i],
+                       ah->totalIqCorrMeas[i]);
+       }
+}
+
+static void ath9k_hw_adc_gaincal_collect(struct ath_hw *ah)
+{
+       int i;
+
+       for (i = 0; i < AR5416_MAX_CHAINS; i++) {
+               ah->totalAdcIOddPhase[i] +=
+                       REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
+               ah->totalAdcIEvenPhase[i] +=
+                       REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
+               ah->totalAdcQOddPhase[i] +=
+                       REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
+               ah->totalAdcQEvenPhase[i] +=
+                       REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
+
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
+                       "oddq=0x%08x; evenq=0x%08x;\n",
+                       ah->cal_samples, i,
+                       ah->totalAdcIOddPhase[i],
+                       ah->totalAdcIEvenPhase[i],
+                       ah->totalAdcQOddPhase[i],
+                       ah->totalAdcQEvenPhase[i]);
+       }
+}
+
+static void ath9k_hw_adc_dccal_collect(struct ath_hw *ah)
+{
+       int i;
+
+       for (i = 0; i < AR5416_MAX_CHAINS; i++) {
+               ah->totalAdcDcOffsetIOddPhase[i] +=
+                       (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
+               ah->totalAdcDcOffsetIEvenPhase[i] +=
+                       (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
+               ah->totalAdcDcOffsetQOddPhase[i] +=
+                       (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
+               ah->totalAdcDcOffsetQEvenPhase[i] +=
+                       (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
+
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
+                       "oddq=0x%08x; evenq=0x%08x;\n",
+                       ah->cal_samples, i,
+                       ah->totalAdcDcOffsetIOddPhase[i],
+                       ah->totalAdcDcOffsetIEvenPhase[i],
+                       ah->totalAdcDcOffsetQOddPhase[i],
+                       ah->totalAdcDcOffsetQEvenPhase[i]);
+       }
+}
+
+static void ath9k_hw_iqcalibrate(struct ath_hw *ah, u8 numChains)
+{
+       u32 powerMeasQ, powerMeasI, iqCorrMeas;
+       u32 qCoffDenom, iCoffDenom;
+       int32_t qCoff, iCoff;
+       int iqCorrNeg, i;
+
+       for (i = 0; i < numChains; i++) {
+               powerMeasI = ah->totalPowerMeasI[i];
+               powerMeasQ = ah->totalPowerMeasQ[i];
+               iqCorrMeas = ah->totalIqCorrMeas[i];
+
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "Starting IQ Cal and Correction for Chain %d\n",
+                       i);
+
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "Orignal: Chn %diq_corr_meas = 0x%08x\n",
+                       i, ah->totalIqCorrMeas[i]);
+
+               iqCorrNeg = 0;
+
+               if (iqCorrMeas > 0x80000000) {
+                       iqCorrMeas = (0xffffffff - iqCorrMeas) + 1;
+                       iqCorrNeg = 1;
+               }
+
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "Chn %d pwr_meas_i = 0x%08x\n", i, powerMeasI);
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "Chn %d pwr_meas_q = 0x%08x\n", i, powerMeasQ);
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "iqCorrNeg is 0x%08x\n",
+                       iqCorrNeg);
+
+               iCoffDenom = (powerMeasI / 2 + powerMeasQ / 2) / 128;
+               qCoffDenom = powerMeasQ / 64;
+
+               if (powerMeasQ != 0) {
+                       iCoff = iqCorrMeas / iCoffDenom;
+                       qCoff = powerMeasI / qCoffDenom - 64;
+                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                               "Chn %d iCoff = 0x%08x\n", i, iCoff);
+                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                               "Chn %d qCoff = 0x%08x\n", i, qCoff);
+
+                       iCoff = iCoff & 0x3f;
+                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                               "New: Chn %d iCoff = 0x%08x\n", i, iCoff);
+                       if (iqCorrNeg == 0x0)
+                               iCoff = 0x40 - iCoff;
+
+                       if (qCoff > 15)
+                               qCoff = 15;
+                       else if (qCoff <= -16)
+                               qCoff = 16;
+
+                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                               "Chn %d : iCoff = 0x%x  qCoff = 0x%x\n",
+                               i, iCoff, qCoff);
+
+                       REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i),
+                                     AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF,
+                                     iCoff);
+                       REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i),
+                                     AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF,
+                                     qCoff);
+                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                               "IQ Cal and Correction done for Chain %d\n",
+                               i);
+               }
+       }
+
+       REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0),
+                   AR_PHY_TIMING_CTRL4_IQCORR_ENABLE);
+}
+
+static void ath9k_hw_adc_gaincal_calibrate(struct ath_hw *ah, u8 numChains)
+{
+       u32 iOddMeasOffset, iEvenMeasOffset, qOddMeasOffset, qEvenMeasOffset;
+       u32 qGainMismatch, iGainMismatch, val, i;
+
+       for (i = 0; i < numChains; i++) {
+               iOddMeasOffset = ah->totalAdcIOddPhase[i];
+               iEvenMeasOffset = ah->totalAdcIEvenPhase[i];
+               qOddMeasOffset = ah->totalAdcQOddPhase[i];
+               qEvenMeasOffset = ah->totalAdcQEvenPhase[i];
+
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "Starting ADC Gain Cal for Chain %d\n", i);
+
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "Chn %d pwr_meas_odd_i = 0x%08x\n", i,
+                       iOddMeasOffset);
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "Chn %d pwr_meas_even_i = 0x%08x\n", i,
+                       iEvenMeasOffset);
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "Chn %d pwr_meas_odd_q = 0x%08x\n", i,
+                       qOddMeasOffset);
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "Chn %d pwr_meas_even_q = 0x%08x\n", i,
+                       qEvenMeasOffset);
+
+               if (iOddMeasOffset != 0 && qEvenMeasOffset != 0) {
+                       iGainMismatch =
+                               ((iEvenMeasOffset * 32) /
+                                iOddMeasOffset) & 0x3f;
+                       qGainMismatch =
+                               ((qOddMeasOffset * 32) /
+                                qEvenMeasOffset) & 0x3f;
+
+                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                               "Chn %d gain_mismatch_i = 0x%08x\n", i,
+                               iGainMismatch);
+                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                               "Chn %d gain_mismatch_q = 0x%08x\n", i,
+                               qGainMismatch);
+
+                       val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i));
+                       val &= 0xfffff000;
+                       val |= (qGainMismatch) | (iGainMismatch << 6);
+                       REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val);
+
+                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                               "ADC Gain Cal done for Chain %d\n", i);
+               }
+       }
+
+       REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0),
+                 REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) |
+                 AR_PHY_NEW_ADC_GAIN_CORR_ENABLE);
+}
+
+static void ath9k_hw_adc_dccal_calibrate(struct ath_hw *ah, u8 numChains)
+{
+       u32 iOddMeasOffset, iEvenMeasOffset, val, i;
+       int32_t qOddMeasOffset, qEvenMeasOffset, qDcMismatch, iDcMismatch;
+       const struct ath9k_percal_data *calData =
+               ah->cal_list_curr->calData;
+       u32 numSamples =
+               (1 << (calData->calCountMax + 5)) * calData->calNumSamples;
+
+       for (i = 0; i < numChains; i++) {
+               iOddMeasOffset = ah->totalAdcDcOffsetIOddPhase[i];
+               iEvenMeasOffset = ah->totalAdcDcOffsetIEvenPhase[i];
+               qOddMeasOffset = ah->totalAdcDcOffsetQOddPhase[i];
+               qEvenMeasOffset = ah->totalAdcDcOffsetQEvenPhase[i];
+
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "Starting ADC DC Offset Cal for Chain %d\n", i);
+
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "Chn %d pwr_meas_odd_i = %d\n", i,
+                       iOddMeasOffset);
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "Chn %d pwr_meas_even_i = %d\n", i,
+                       iEvenMeasOffset);
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "Chn %d pwr_meas_odd_q = %d\n", i,
+                       qOddMeasOffset);
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "Chn %d pwr_meas_even_q = %d\n", i,
+                       qEvenMeasOffset);
+
+               iDcMismatch = (((iEvenMeasOffset - iOddMeasOffset) * 2) /
+                              numSamples) & 0x1ff;
+               qDcMismatch = (((qOddMeasOffset - qEvenMeasOffset) * 2) /
+                              numSamples) & 0x1ff;
+
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "Chn %d dc_offset_mismatch_i = 0x%08x\n", i,
+                       iDcMismatch);
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "Chn %d dc_offset_mismatch_q = 0x%08x\n", i,
+                       qDcMismatch);
+
+               val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i));
+               val &= 0xc0000fff;
+               val |= (qDcMismatch << 12) | (iDcMismatch << 21);
+               REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val);
+
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "ADC DC Offset Cal done for Chain %d\n", i);
+       }
+
+       REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0),
+                 REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) |
+                 AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE);
+}
+
+/* This is done for the currently configured channel */
+bool ath9k_hw_reset_calvalid(struct ath_hw *ah)
+{
+       struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
+       struct ath9k_cal_list *currCal = ah->cal_list_curr;
+
+       if (!ah->curchan)
+               return true;
+
+       if (!AR_SREV_9100(ah) && !AR_SREV_9160_10_OR_LATER(ah))
+               return true;
+
+       if (currCal == NULL)
+               return true;
+
+       if (currCal->calState != CAL_DONE) {
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "Calibration state incorrect, %d\n",
+                       currCal->calState);
+               return true;
+       }
+
+       if (!ath9k_hw_iscal_supported(ah, currCal->calData->calType))
+               return true;
+
+       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+               "Resetting Cal %d state for channel %u\n",
+               currCal->calData->calType, conf->channel->center_freq);
+
+       ah->curchan->CalValid &= ~currCal->calData->calType;
+       currCal->calState = CAL_WAITING;
+
+       return false;
+}
+
+void ath9k_hw_start_nfcal(struct ath_hw *ah)
+{
+       REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
+                   AR_PHY_AGC_CONTROL_ENABLE_NF);
+       REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
+                   AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
+       REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
+}
+
+void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
+{
+       struct ath9k_nfcal_hist *h;
+       int i, j;
+       int32_t val;
+       const u32 ar5416_cca_regs[6] = {
+               AR_PHY_CCA,
+               AR_PHY_CH1_CCA,
+               AR_PHY_CH2_CCA,
+               AR_PHY_EXT_CCA,
+               AR_PHY_CH1_EXT_CCA,
+               AR_PHY_CH2_EXT_CCA
+       };
+       u8 chainmask;
+
+       if (AR_SREV_9285(ah))
+               chainmask = 0x9;
+       else if (AR_SREV_9280(ah))
+               chainmask = 0x1B;
+       else
+               chainmask = 0x3F;
+
+       h = ah->nfCalHist;
+
+       for (i = 0; i < NUM_NF_READINGS; i++) {
+               if (chainmask & (1 << i)) {
+                       val = REG_READ(ah, ar5416_cca_regs[i]);
+                       val &= 0xFFFFFE00;
+                       val |= (((u32) (h[i].privNF) << 1) & 0x1ff);
+                       REG_WRITE(ah, ar5416_cca_regs[i], val);
+               }
+       }
+
+       REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
+                   AR_PHY_AGC_CONTROL_ENABLE_NF);
+       REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
+                   AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
+       REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
+
+       for (j = 0; j < 1000; j++) {
+               if ((REG_READ(ah, AR_PHY_AGC_CONTROL) &
+                    AR_PHY_AGC_CONTROL_NF) == 0)
+                       break;
+               udelay(10);
+       }
+
+       for (i = 0; i < NUM_NF_READINGS; i++) {
+               if (chainmask & (1 << i)) {
+                       val = REG_READ(ah, ar5416_cca_regs[i]);
+                       val &= 0xFFFFFE00;
+                       val |= (((u32) (-50) << 1) & 0x1ff);
+                       REG_WRITE(ah, ar5416_cca_regs[i], val);
+               }
+       }
+}
+
+int16_t ath9k_hw_getnf(struct ath_hw *ah,
+                      struct ath9k_channel *chan)
+{
+       int16_t nf, nfThresh;
+       int16_t nfarray[NUM_NF_READINGS] = { 0 };
+       struct ath9k_nfcal_hist *h;
+       struct ieee80211_channel *c = chan->chan;
+
+       chan->channelFlags &= (~CHANNEL_CW_INT);
+       if (REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) {
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                       "NF did not complete in calibration window\n");
+               nf = 0;
+               chan->rawNoiseFloor = nf;
+               return chan->rawNoiseFloor;
+       } else {
+               ath9k_hw_do_getnf(ah, nfarray);
+               nf = nfarray[0];
+               if (getNoiseFloorThresh(ah, c->band, &nfThresh)
+                   && nf > nfThresh) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                               "noise floor failed detected; "
+                               "detected %d, threshold %d\n",
+                               nf, nfThresh);
+                       chan->channelFlags |= CHANNEL_CW_INT;
+               }
+       }
+
+       h = ah->nfCalHist;
+
+       ath9k_hw_update_nfcal_hist_buffer(h, nfarray);
+       chan->rawNoiseFloor = h[0].privNF;
+
+       return chan->rawNoiseFloor;
+}
+
+void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah)
+{
+       int i, j;
+
+       for (i = 0; i < NUM_NF_READINGS; i++) {
+               ah->nfCalHist[i].currIndex = 0;
+               ah->nfCalHist[i].privNF = AR_PHY_CCA_MAX_GOOD_VALUE;
+               ah->nfCalHist[i].invalidNFcount =
+                       AR_PHY_CCA_FILTERWINDOW_LENGTH;
+               for (j = 0; j < ATH9K_NF_CAL_HIST_MAX; j++) {
+                       ah->nfCalHist[i].nfCalBuffer[j] =
+                               AR_PHY_CCA_MAX_GOOD_VALUE;
+               }
+       }
+}
+
+s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan)
+{
+       s16 nf;
+
+       if (chan->rawNoiseFloor == 0)
+               nf = -96;
+       else
+               nf = chan->rawNoiseFloor;
+
+       if (!ath9k_hw_nf_in_range(ah, nf))
+               nf = ATH_DEFAULT_NOISE_FLOOR;
+
+       return nf;
+}
+
+static void ath9k_olc_temp_compensation(struct ath_hw *ah)
+{
+       u32 rddata, i;
+       int delta, currPDADC, regval;
+
+       rddata = REG_READ(ah, AR_PHY_TX_PWRCTRL4);
+
+       currPDADC = MS(rddata, AR_PHY_TX_PWRCTRL_PD_AVG_OUT);
+
+       if (ah->eep_ops->get_eeprom(ah, EEP_DAC_HPWR_5G))
+               delta = (currPDADC - ah->initPDADC + 4) / 8;
+       else
+               delta = (currPDADC - ah->initPDADC + 5) / 10;
+
+       if (delta != ah->PDADCdelta) {
+               ah->PDADCdelta = delta;
+               for (i = 1; i < AR9280_TX_GAIN_TABLE_SIZE; i++) {
+                       regval = ah->originalGain[i] - delta;
+                       if (regval < 0)
+                               regval = 0;
+
+                       REG_RMW_FIELD(ah, AR_PHY_TX_GAIN_TBL1 + i * 4,
+                                       AR_PHY_TX_GAIN, regval);
+               }
+       }
+}
+
+static inline void ath9k_hw_9285_pa_cal(struct ath_hw *ah)
+{
+
+       u32 regVal;
+       int i, offset, offs_6_1, offs_0;
+       u32 ccomp_org, reg_field;
+       u32 regList[][2] = {
+               { 0x786c, 0 },
+               { 0x7854, 0 },
+               { 0x7820, 0 },
+               { 0x7824, 0 },
+               { 0x7868, 0 },
+               { 0x783c, 0 },
+               { 0x7838, 0 },
+       };
+
+       if (AR_SREV_9285_11(ah)) {
+               REG_WRITE(ah, AR9285_AN_TOP4, (AR9285_AN_TOP4_DEFAULT | 0x14));
+               udelay(10);
+       }
+
+       for (i = 0; i < ARRAY_SIZE(regList); i++)
+               regList[i][1] = REG_READ(ah, regList[i][0]);
+
+       regVal = REG_READ(ah, 0x7834);
+       regVal &= (~(0x1));
+       REG_WRITE(ah, 0x7834, regVal);
+       regVal = REG_READ(ah, 0x9808);
+       regVal |= (0x1 << 27);
+       REG_WRITE(ah, 0x9808, regVal);
+
+       REG_RMW_FIELD(ah, AR9285_AN_TOP3, AR9285_AN_TOP3_PWDDAC, 1);
+       REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDRXTXBB1, 1);
+       REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDV2I, 1);
+       REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDDACIF, 1);
+       REG_RMW_FIELD(ah, AR9285_AN_RF2G2, AR9285_AN_RF2G2_OFFCAL, 0);
+       REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PWDDB, 0);
+       REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_ENPACAL, 0);
+       REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV1, 1);
+       REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV2, 0);
+       REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPAOUT, 0);
+       REG_RMW_FIELD(ah, AR9285_AN_RF2G8, AR9285_AN_RF2G8_PADRVGN2TAB0, 7);
+       REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PADRVGN2TAB0, 0);
+       ccomp_org = MS(REG_READ(ah, AR9285_AN_RF2G6), AR9285_AN_RF2G6_CCOMP);
+       REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_CCOMP, 7);
+
+       REG_WRITE(ah, AR9285_AN_TOP2, 0xca0358a0);
+       udelay(30);
+       REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_OFFS, 0);
+       REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, 0);
+
+       for (i = 6; i > 0; i--) {
+               regVal = REG_READ(ah, 0x7834);
+               regVal |= (1 << (19 + i));
+               REG_WRITE(ah, 0x7834, regVal);
+               udelay(1);
+               regVal = REG_READ(ah, 0x7834);
+               regVal &= (~(0x1 << (19 + i)));
+               reg_field = MS(REG_READ(ah, 0x7840), AR9285_AN_RXTXBB1_SPARE9);
+               regVal |= (reg_field << (19 + i));
+               REG_WRITE(ah, 0x7834, regVal);
+       }
+
+       REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, 1);
+       udelay(1);
+       reg_field = MS(REG_READ(ah, AR9285_AN_RF2G9), AR9285_AN_RXTXBB1_SPARE9);
+       REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, reg_field);
+       offs_6_1 = MS(REG_READ(ah, AR9285_AN_RF2G6), AR9285_AN_RF2G6_OFFS);
+       offs_0   = MS(REG_READ(ah, AR9285_AN_RF2G3), AR9285_AN_RF2G3_PDVCCOMP);
+
+       offset = (offs_6_1<<1) | offs_0;
+       offset = offset - 0;
+       offs_6_1 = offset>>1;
+       offs_0 = offset & 1;
+
+       REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_OFFS, offs_6_1);
+       REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, offs_0);
+
+       regVal = REG_READ(ah, 0x7834);
+       regVal |= 0x1;
+       REG_WRITE(ah, 0x7834, regVal);
+       regVal = REG_READ(ah, 0x9808);
+       regVal &= (~(0x1 << 27));
+       REG_WRITE(ah, 0x9808, regVal);
+
+       for (i = 0; i < ARRAY_SIZE(regList); i++)
+               REG_WRITE(ah, regList[i][0], regList[i][1]);
+
+       REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_CCOMP, ccomp_org);
+
+       if (AR_SREV_9285_11(ah))
+               REG_WRITE(ah, AR9285_AN_TOP4, AR9285_AN_TOP4_DEFAULT);
+
+}
+
+bool ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
+                       u8 rxchainmask, bool longcal)
+{
+       bool iscaldone = true;
+       struct ath9k_cal_list *currCal = ah->cal_list_curr;
+
+       if (currCal &&
+           (currCal->calState == CAL_RUNNING ||
+            currCal->calState == CAL_WAITING)) {
+               iscaldone = ath9k_hw_per_calibration(ah, chan,
+                                                    rxchainmask, currCal);
+               if (iscaldone) {
+                       ah->cal_list_curr = currCal = currCal->calNext;
+
+                       if (currCal->calState == CAL_WAITING) {
+                               iscaldone = false;
+                               ath9k_hw_reset_calibration(ah, currCal);
+                       }
+               }
+       }
+
+       if (longcal) {
+               if (AR_SREV_9285_11_OR_LATER(ah))
+                       ath9k_hw_9285_pa_cal(ah);
+
+               if (OLC_FOR_AR9280_20_LATER)
+                       ath9k_olc_temp_compensation(ah);
+               ath9k_hw_getnf(ah, chan);
+               ath9k_hw_loadnf(ah, ah->curchan);
+               ath9k_hw_start_nfcal(ah);
+       }
+
+       return iscaldone;
+}
+
+static bool ar9285_clc(struct ath_hw *ah, struct ath9k_channel *chan)
+{
+       REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
+       if (IS_CHAN_HT20(chan)) {
+               REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_PARALLEL_CAL_ENABLE);
+               REG_SET_BIT(ah, AR_PHY_TURBO, AR_PHY_FC_DYN2040_EN);
+               REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
+                           AR_PHY_AGC_CONTROL_FLTR_CAL);
+               REG_CLR_BIT(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_CAL_ENABLE);
+               REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL);
+               if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
+                                 AR_PHY_AGC_CONTROL_CAL, 0, AH_WAIT_TIMEOUT)) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "offset "
+                               "calibration failed to complete in "
+                               "1ms; noisy ??\n");
+                       return false;
+               }
+               REG_CLR_BIT(ah, AR_PHY_TURBO, AR_PHY_FC_DYN2040_EN);
+               REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_PARALLEL_CAL_ENABLE);
+               REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
+       }
+       REG_CLR_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
+       REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
+       REG_SET_BIT(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_CAL_ENABLE);
+       REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL);
+       if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL,
+                         0, AH_WAIT_TIMEOUT)) {
+               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "offset calibration "
+                               "failed to complete in 1ms; noisy ??\n");
+               return false;
+       }
+
+       REG_SET_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
+       REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
+       REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
+
+       return true;
+}
+
+bool ath9k_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan)
+{
+       if (AR_SREV_9285_12_OR_LATER(ah)) {
+               if (!ar9285_clc(ah, chan))
+                       return false;
+       } else {
+               if (AR_SREV_9280_10_OR_LATER(ah)) {
+                       REG_CLR_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
+                       REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
+               }
+
+               /* Calibrate the AGC */
+               REG_WRITE(ah, AR_PHY_AGC_CONTROL,
+                         REG_READ(ah, AR_PHY_AGC_CONTROL) |
+                         AR_PHY_AGC_CONTROL_CAL);
+
+               /* Poll for offset calibration complete */
+               if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL,
+                                  0, AH_WAIT_TIMEOUT)) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                               "offset calibration failed to complete in 1ms; "
+                               "noisy environment?\n");
+                       return false;
+               }
+
+               if (AR_SREV_9280_10_OR_LATER(ah)) {
+                       REG_SET_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
+                       REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
+               }
+       }
+
+       /* Do PA Calibration */
+       if (AR_SREV_9285_11_OR_LATER(ah))
+               ath9k_hw_9285_pa_cal(ah);
+
+       /* Do NF Calibration after DC offset and other calibrations */
+       REG_WRITE(ah, AR_PHY_AGC_CONTROL,
+                 REG_READ(ah, AR_PHY_AGC_CONTROL) | AR_PHY_AGC_CONTROL_NF);
+
+       ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL;
+
+       /* Enable IQ, ADC Gain and ADC DC offset CALs */
+       if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) {
+               if (ath9k_hw_iscal_supported(ah, ADC_GAIN_CAL)) {
+                       INIT_CAL(&ah->adcgain_caldata);
+                       INSERT_CAL(ah, &ah->adcgain_caldata);
+                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                               "enabling ADC Gain Calibration.\n");
+               }
+               if (ath9k_hw_iscal_supported(ah, ADC_DC_CAL)) {
+                       INIT_CAL(&ah->adcdc_caldata);
+                       INSERT_CAL(ah, &ah->adcdc_caldata);
+                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                               "enabling ADC DC Calibration.\n");
+               }
+               if (ath9k_hw_iscal_supported(ah, IQ_MISMATCH_CAL)) {
+                       INIT_CAL(&ah->iq_caldata);
+                       INSERT_CAL(ah, &ah->iq_caldata);
+                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
+                               "enabling IQ Calibration.\n");
+               }
+
+               ah->cal_list_curr = ah->cal_list;
+
+               if (ah->cal_list_curr)
+                       ath9k_hw_reset_calibration(ah, ah->cal_list_curr);
+       }
+
+       chan->CalValid = 0;
+
+       return true;
+}
+
+const struct ath9k_percal_data iq_cal_multi_sample = {
+       IQ_MISMATCH_CAL,
+       MAX_CAL_SAMPLES,
+       PER_MIN_LOG_COUNT,
+       ath9k_hw_iqcal_collect,
+       ath9k_hw_iqcalibrate
+};
+const struct ath9k_percal_data iq_cal_single_sample = {
+       IQ_MISMATCH_CAL,
+       MIN_CAL_SAMPLES,
+       PER_MAX_LOG_COUNT,
+       ath9k_hw_iqcal_collect,
+       ath9k_hw_iqcalibrate
+};
+const struct ath9k_percal_data adc_gain_cal_multi_sample = {
+       ADC_GAIN_CAL,
+       MAX_CAL_SAMPLES,
+       PER_MIN_LOG_COUNT,
+       ath9k_hw_adc_gaincal_collect,
+       ath9k_hw_adc_gaincal_calibrate
+};
+const struct ath9k_percal_data adc_gain_cal_single_sample = {
+       ADC_GAIN_CAL,
+       MIN_CAL_SAMPLES,
+       PER_MAX_LOG_COUNT,
+       ath9k_hw_adc_gaincal_collect,
+       ath9k_hw_adc_gaincal_calibrate
+};
+const struct ath9k_percal_data adc_dc_cal_multi_sample = {
+       ADC_DC_CAL,
+       MAX_CAL_SAMPLES,
+       PER_MIN_LOG_COUNT,
+       ath9k_hw_adc_dccal_collect,
+       ath9k_hw_adc_dccal_calibrate
+};
+const struct ath9k_percal_data adc_dc_cal_single_sample = {
+       ADC_DC_CAL,
+       MIN_CAL_SAMPLES,
+       PER_MAX_LOG_COUNT,
+       ath9k_hw_adc_dccal_collect,
+       ath9k_hw_adc_dccal_calibrate
+};
+const struct ath9k_percal_data adc_init_dc_cal = {
+       ADC_DC_INIT_CAL,
+       MIN_CAL_SAMPLES,
+       INIT_LOG_COUNT,
+       ath9k_hw_adc_dccal_collect,
+       ath9k_hw_adc_dccal_calibrate
+};
diff --git a/drivers/net/wireless/ath/ath9k/calib.h b/drivers/net/wireless/ath/ath9k/calib.h
new file mode 100644 (file)
index 0000000..fe5367f
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2008-2009 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 CALIB_H
+#define CALIB_H
+
+extern const struct ath9k_percal_data iq_cal_multi_sample;
+extern const struct ath9k_percal_data iq_cal_single_sample;
+extern const struct ath9k_percal_data adc_gain_cal_multi_sample;
+extern const struct ath9k_percal_data adc_gain_cal_single_sample;
+extern const struct ath9k_percal_data adc_dc_cal_multi_sample;
+extern const struct ath9k_percal_data adc_dc_cal_single_sample;
+extern const struct ath9k_percal_data adc_init_dc_cal;
+
+#define AR_PHY_CCA_MAX_GOOD_VALUE                      -85
+#define AR_PHY_CCA_MAX_HIGH_VALUE                      -62
+#define AR_PHY_CCA_MIN_BAD_VALUE                       -140
+#define AR_PHY_CCA_FILTERWINDOW_LENGTH_INIT     3
+#define AR_PHY_CCA_FILTERWINDOW_LENGTH          5
+
+#define NUM_NF_READINGS       6
+#define ATH9K_NF_CAL_HIST_MAX 5
+
+struct ar5416IniArray {
+       u32 *ia_array;
+       u32 ia_rows;
+       u32 ia_columns;
+};
+
+#define INIT_INI_ARRAY(iniarray, array, rows, columns) do {    \
+               (iniarray)->ia_array = (u32 *)(array);          \
+               (iniarray)->ia_rows = (rows);                   \
+               (iniarray)->ia_columns = (columns);             \
+       } while (0)
+
+#define INI_RA(iniarray, row, column) \
+       (((iniarray)->ia_array)[(row) * ((iniarray)->ia_columns) + (column)])
+
+#define INIT_CAL(_perCal) do {                         \
+               (_perCal)->calState = CAL_WAITING;      \
+               (_perCal)->calNext = NULL;              \
+       } while (0)
+
+#define INSERT_CAL(_ahp, _perCal)                                      \
+       do {                                                            \
+               if ((_ahp)->cal_list_last == NULL) {                    \
+                       (_ahp)->cal_list =                              \
+                               (_ahp)->cal_list_last = (_perCal);      \
+                       ((_ahp)->cal_list_last)->calNext = (_perCal); \
+               } else {                                                \
+                       ((_ahp)->cal_list_last)->calNext = (_perCal); \
+                       (_ahp)->cal_list_last = (_perCal);              \
+                       (_perCal)->calNext = (_ahp)->cal_list;  \
+               }                                                       \
+       } while (0)
+
+enum ath9k_cal_types {
+       ADC_DC_INIT_CAL = 0x1,
+       ADC_GAIN_CAL = 0x2,
+       ADC_DC_CAL = 0x4,
+       IQ_MISMATCH_CAL = 0x8
+};
+
+enum ath9k_cal_state {
+       CAL_INACTIVE,
+       CAL_WAITING,
+       CAL_RUNNING,
+       CAL_DONE
+};
+
+#define MIN_CAL_SAMPLES     1
+#define MAX_CAL_SAMPLES    64
+#define INIT_LOG_COUNT      5
+#define PER_MIN_LOG_COUNT   2
+#define PER_MAX_LOG_COUNT  10
+
+struct ath9k_percal_data {
+       enum ath9k_cal_types calType;
+       u32 calNumSamples;
+       u32 calCountMax;
+       void (*calCollect) (struct ath_hw *);
+       void (*calPostProc) (struct ath_hw *, u8);
+};
+
+struct ath9k_cal_list {
+       const struct ath9k_percal_data *calData;
+       enum ath9k_cal_state calState;
+       struct ath9k_cal_list *calNext;
+};
+
+struct ath9k_nfcal_hist {
+       int16_t nfCalBuffer[ATH9K_NF_CAL_HIST_MAX];
+       u8 currIndex;
+       int16_t privNF;
+       u8 invalidNFcount;
+};
+
+bool ath9k_hw_reset_calvalid(struct ath_hw *ah);
+void ath9k_hw_start_nfcal(struct ath_hw *ah);
+void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan);
+int16_t ath9k_hw_getnf(struct ath_hw *ah,
+                      struct ath9k_channel *chan);
+void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah);
+s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan);
+bool ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
+                       u8 rxchainmask, bool longcal);
+bool ath9k_hw_init_cal(struct ath_hw *ah,
+                      struct ath9k_channel *chan);
+
+#endif /* CALIB_H */
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
new file mode 100644 (file)
index 0000000..6d20725
--- /dev/null
@@ -0,0 +1,561 @@
+/*
+ * Copyright (c) 2008-2009 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 <asm/unaligned.h>
+
+#include "ath9k.h"
+
+static unsigned int ath9k_debug = DBG_DEFAULT;
+module_param_named(debug, ath9k_debug, uint, 0);
+
+static struct dentry *ath9k_debugfs_root;
+
+void DPRINTF(struct ath_softc *sc, int dbg_mask, const char *fmt, ...)
+{
+       if (!sc)
+               return;
+
+       if (sc->debug.debug_mask & dbg_mask) {
+               va_list args;
+
+               va_start(args, fmt);
+               printk(KERN_DEBUG "ath9k: ");
+               vprintk(fmt, args);
+               va_end(args);
+       }
+}
+
+static int ath9k_debugfs_open(struct inode *inode, struct file *file)
+{
+       file->private_data = inode->i_private;
+       return 0;
+}
+
+static ssize_t read_file_debug(struct file *file, char __user *user_buf,
+                            size_t count, loff_t *ppos)
+{
+       struct ath_softc *sc = file->private_data;
+       char buf[32];
+       unsigned int len;
+
+       len = snprintf(buf, sizeof(buf), "0x%08x\n", sc->debug.debug_mask);
+       return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static ssize_t write_file_debug(struct file *file, const char __user *user_buf,
+                            size_t count, loff_t *ppos)
+{
+       struct ath_softc *sc = file->private_data;
+       unsigned long mask;
+       char buf[32];
+       ssize_t len;
+
+       len = min(count, sizeof(buf) - 1);
+       if (copy_from_user(buf, user_buf, len))
+               return -EINVAL;
+
+       buf[len] = '\0';
+       if (strict_strtoul(buf, 0, &mask))
+               return -EINVAL;
+
+       sc->debug.debug_mask = mask;
+       return count;
+}
+
+static const struct file_operations fops_debug = {
+       .read = read_file_debug,
+       .write = write_file_debug,
+       .open = ath9k_debugfs_open,
+       .owner = THIS_MODULE
+};
+
+static ssize_t read_file_dma(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;
+       char buf[1024];
+       unsigned int len = 0;
+       u32 val[ATH9K_NUM_DMA_DEBUG_REGS];
+       int i, qcuOffset = 0, dcuOffset = 0;
+       u32 *qcuBase = &val[0], *dcuBase = &val[4];
+
+       REG_WRITE(ah, AR_MACMISC,
+                 ((AR_MACMISC_DMA_OBS_LINE_8 << AR_MACMISC_DMA_OBS_S) |
+                  (AR_MACMISC_MISC_OBS_BUS_1 <<
+                   AR_MACMISC_MISC_OBS_BUS_MSB_S)));
+
+       len += snprintf(buf + len, sizeof(buf) - len,
+                       "Raw DMA Debug values:\n");
+
+       for (i = 0; i < ATH9K_NUM_DMA_DEBUG_REGS; i++) {
+               if (i % 4 == 0)
+                       len += snprintf(buf + len, sizeof(buf) - len, "\n");
+
+               val[i] = REG_READ(ah, AR_DMADBG_0 + (i * sizeof(u32)));
+               len += snprintf(buf + len, sizeof(buf) - len, "%d: %08x ",
+                               i, val[i]);
+       }
+
+       len += snprintf(buf + len, sizeof(buf) - len, "\n\n");
+       len += snprintf(buf + len, sizeof(buf) - len,
+                       "Num QCU: chain_st fsp_ok fsp_st DCU: chain_st\n");
+
+       for (i = 0; i < ATH9K_NUM_QUEUES; i++, qcuOffset += 4, dcuOffset += 5) {
+               if (i == 8) {
+                       qcuOffset = 0;
+                       qcuBase++;
+               }
+
+               if (i == 6) {
+                       dcuOffset = 0;
+                       dcuBase++;
+               }
+
+               len += snprintf(buf + len, sizeof(buf) - len,
+                       "%2d          %2x      %1x     %2x           %2x\n",
+                       i, (*qcuBase & (0x7 << qcuOffset)) >> qcuOffset,
+                       (*qcuBase & (0x8 << qcuOffset)) >> (qcuOffset + 3),
+                       val[2] & (0x7 << (i * 3)) >> (i * 3),
+                       (*dcuBase & (0x1f << dcuOffset)) >> dcuOffset);
+       }
+
+       len += snprintf(buf + len, sizeof(buf) - len, "\n");
+
+       len += snprintf(buf + len, sizeof(buf) - len,
+               "qcu_stitch state:   %2x    qcu_fetch state:        %2x\n",
+               (val[3] & 0x003c0000) >> 18, (val[3] & 0x03c00000) >> 22);
+       len += snprintf(buf + len, sizeof(buf) - len,
+               "qcu_complete state: %2x    dcu_complete state:     %2x\n",
+               (val[3] & 0x1c000000) >> 26, (val[6] & 0x3));
+       len += snprintf(buf + len, sizeof(buf) - len,
+               "dcu_arb state:      %2x    dcu_fp state:           %2x\n",
+               (val[5] & 0x06000000) >> 25, (val[5] & 0x38000000) >> 27);
+       len += snprintf(buf + len, sizeof(buf) - len,
+               "chan_idle_dur:     %3d    chan_idle_dur_valid:     %1d\n",
+               (val[6] & 0x000003fc) >> 2, (val[6] & 0x00000400) >> 10);
+       len += snprintf(buf + len, sizeof(buf) - len,
+               "txfifo_valid_0:      %1d    txfifo_valid_1:          %1d\n",
+               (val[6] & 0x00000800) >> 11, (val[6] & 0x00001000) >> 12);
+       len += snprintf(buf + len, sizeof(buf) - len,
+               "txfifo_dcu_num_0:   %2d    txfifo_dcu_num_1:       %2d\n",
+               (val[6] & 0x0001e000) >> 13, (val[6] & 0x001e0000) >> 17);
+
+       len += snprintf(buf + len, sizeof(buf) - len, "pcu observe: 0x%x \n",
+                       REG_READ(ah, AR_OBS_BUS_1));
+       len += snprintf(buf + len, sizeof(buf) - len,
+                       "AR_CR: 0x%x \n", REG_READ(ah, AR_CR));
+
+       return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static const struct file_operations fops_dma = {
+       .read = read_file_dma,
+       .open = ath9k_debugfs_open,
+       .owner = THIS_MODULE
+};
+
+
+void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status)
+{
+       if (status)
+               sc->debug.stats.istats.total++;
+       if (status & ATH9K_INT_RX)
+               sc->debug.stats.istats.rxok++;
+       if (status & ATH9K_INT_RXEOL)
+               sc->debug.stats.istats.rxeol++;
+       if (status & ATH9K_INT_RXORN)
+               sc->debug.stats.istats.rxorn++;
+       if (status & ATH9K_INT_TX)
+               sc->debug.stats.istats.txok++;
+       if (status & ATH9K_INT_TXURN)
+               sc->debug.stats.istats.txurn++;
+       if (status & ATH9K_INT_MIB)
+               sc->debug.stats.istats.mib++;
+       if (status & ATH9K_INT_RXPHY)
+               sc->debug.stats.istats.rxphyerr++;
+       if (status & ATH9K_INT_RXKCM)
+               sc->debug.stats.istats.rx_keycache_miss++;
+       if (status & ATH9K_INT_SWBA)
+               sc->debug.stats.istats.swba++;
+       if (status & ATH9K_INT_BMISS)
+               sc->debug.stats.istats.bmiss++;
+       if (status & ATH9K_INT_BNR)
+               sc->debug.stats.istats.bnr++;
+       if (status & ATH9K_INT_CST)
+               sc->debug.stats.istats.cst++;
+       if (status & ATH9K_INT_GTT)
+               sc->debug.stats.istats.gtt++;
+       if (status & ATH9K_INT_TIM)
+               sc->debug.stats.istats.tim++;
+       if (status & ATH9K_INT_CABEND)
+               sc->debug.stats.istats.cabend++;
+       if (status & ATH9K_INT_DTIMSYNC)
+               sc->debug.stats.istats.dtimsync++;
+       if (status & ATH9K_INT_DTIM)
+               sc->debug.stats.istats.dtim++;
+}
+
+static ssize_t read_file_interrupt(struct file *file, char __user *user_buf,
+                                  size_t count, loff_t *ppos)
+{
+       struct ath_softc *sc = file->private_data;
+       char buf[512];
+       unsigned int len = 0;
+
+       len += snprintf(buf + len, sizeof(buf) - len,
+               "%8s: %10u\n", "RX", sc->debug.stats.istats.rxok);
+       len += snprintf(buf + len, sizeof(buf) - len,
+               "%8s: %10u\n", "RXEOL", sc->debug.stats.istats.rxeol);
+       len += snprintf(buf + len, sizeof(buf) - len,
+               "%8s: %10u\n", "RXORN", sc->debug.stats.istats.rxorn);
+       len += snprintf(buf + len, sizeof(buf) - len,
+               "%8s: %10u\n", "TX", sc->debug.stats.istats.txok);
+       len += snprintf(buf + len, sizeof(buf) - len,
+               "%8s: %10u\n", "TXURN", sc->debug.stats.istats.txurn);
+       len += snprintf(buf + len, sizeof(buf) - len,
+               "%8s: %10u\n", "MIB", sc->debug.stats.istats.mib);
+       len += snprintf(buf + len, sizeof(buf) - len,
+               "%8s: %10u\n", "RXPHY", sc->debug.stats.istats.rxphyerr);
+       len += snprintf(buf + len, sizeof(buf) - len,
+               "%8s: %10u\n", "RXKCM", sc->debug.stats.istats.rx_keycache_miss);
+       len += snprintf(buf + len, sizeof(buf) - len,
+               "%8s: %10u\n", "SWBA", sc->debug.stats.istats.swba);
+       len += snprintf(buf + len, sizeof(buf) - len,
+               "%8s: %10u\n", "BMISS", sc->debug.stats.istats.bmiss);
+       len += snprintf(buf + len, sizeof(buf) - len,
+               "%8s: %10u\n", "BNR", sc->debug.stats.istats.bnr);
+       len += snprintf(buf + len, sizeof(buf) - len,
+               "%8s: %10u\n", "CST", sc->debug.stats.istats.cst);
+       len += snprintf(buf + len, sizeof(buf) - len,
+               "%8s: %10u\n", "GTT", sc->debug.stats.istats.gtt);
+       len += snprintf(buf + len, sizeof(buf) - len,
+               "%8s: %10u\n", "TIM", sc->debug.stats.istats.tim);
+       len += snprintf(buf + len, sizeof(buf) - len,
+               "%8s: %10u\n", "CABEND", sc->debug.stats.istats.cabend);
+       len += snprintf(buf + len, sizeof(buf) - len,
+               "%8s: %10u\n", "DTIMSYNC", sc->debug.stats.istats.dtimsync);
+       len += snprintf(buf + len, sizeof(buf) - len,
+               "%8s: %10u\n", "DTIM", sc->debug.stats.istats.dtim);
+       len += snprintf(buf + len, sizeof(buf) - len,
+               "%8s: %10u\n", "TOTAL", sc->debug.stats.istats.total);
+
+       return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static const struct file_operations fops_interrupt = {
+       .read = read_file_interrupt,
+       .open = ath9k_debugfs_open,
+       .owner = THIS_MODULE
+};
+
+void ath_debug_stat_rc(struct ath_softc *sc, struct sk_buff *skb)
+{
+       struct ath_tx_info_priv *tx_info_priv = NULL;
+       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+       struct ieee80211_tx_rate *rates = tx_info->status.rates;
+       int final_ts_idx, idx;
+       struct ath_rc_stats *stats;
+
+       tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
+       final_ts_idx = tx_info_priv->tx.ts_rateindex;
+       idx = rates[final_ts_idx].idx;
+       stats = &sc->debug.stats.rcstats[idx];
+       stats->success++;
+}
+
+void ath_debug_stat_retries(struct ath_softc *sc, int rix,
+                           int xretries, int retries, u8 per)
+{
+       struct ath_rc_stats *stats = &sc->debug.stats.rcstats[rix];
+
+       stats->xretries += xretries;
+       stats->retries += retries;
+       stats->per = per;
+}
+
+static ssize_t read_file_rcstat(struct file *file, char __user *user_buf,
+                               size_t count, loff_t *ppos)
+{
+       struct ath_softc *sc = file->private_data;
+       char *buf;
+       unsigned int len = 0, max;
+       int i = 0;
+       ssize_t retval;
+
+       if (sc->cur_rate_table == NULL)
+               return 0;
+
+       max = 80 + sc->cur_rate_table->rate_cnt * 64;
+       buf = kmalloc(max + 1, GFP_KERNEL);
+       if (buf == NULL)
+               return 0;
+       buf[max] = 0;
+
+       len += sprintf(buf, "%5s %15s %8s %9s %3s\n\n", "Rate", "Success",
+                      "Retries", "XRetries", "PER");
+
+       for (i = 0; i < sc->cur_rate_table->rate_cnt; i++) {
+               u32 ratekbps = sc->cur_rate_table->info[i].ratekbps;
+               struct ath_rc_stats *stats = &sc->debug.stats.rcstats[i];
+
+               len += snprintf(buf + len, max - len,
+                       "%3u.%d: %8u %8u %8u %8u\n", ratekbps / 1000,
+                       (ratekbps % 1000) / 100, stats->success,
+                       stats->retries, stats->xretries,
+                       stats->per);
+       }
+
+       retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
+       kfree(buf);
+       return retval;
+}
+
+static const struct file_operations fops_rcstat = {
+       .read = read_file_rcstat,
+       .open = ath9k_debugfs_open,
+       .owner = THIS_MODULE
+};
+
+static const char * ath_wiphy_state_str(enum ath_wiphy_state state)
+{
+       switch (state) {
+       case ATH_WIPHY_INACTIVE:
+               return "INACTIVE";
+       case ATH_WIPHY_ACTIVE:
+               return "ACTIVE";
+       case ATH_WIPHY_PAUSING:
+               return "PAUSING";
+       case ATH_WIPHY_PAUSED:
+               return "PAUSED";
+       case ATH_WIPHY_SCAN:
+               return "SCAN";
+       }
+       return "?";
+}
+
+static ssize_t read_file_wiphy(struct file *file, char __user *user_buf,
+                              size_t count, loff_t *ppos)
+{
+       struct ath_softc *sc = file->private_data;
+       char buf[512];
+       unsigned int len = 0;
+       int i;
+       u8 addr[ETH_ALEN];
+
+       len += snprintf(buf + len, sizeof(buf) - len,
+                       "primary: %s (%s chan=%d ht=%d)\n",
+                       wiphy_name(sc->pri_wiphy->hw->wiphy),
+                       ath_wiphy_state_str(sc->pri_wiphy->state),
+                       sc->pri_wiphy->chan_idx, sc->pri_wiphy->chan_is_ht);
+       for (i = 0; i < sc->num_sec_wiphy; i++) {
+               struct ath_wiphy *aphy = sc->sec_wiphy[i];
+               if (aphy == NULL)
+                       continue;
+               len += snprintf(buf + len, sizeof(buf) - len,
+                               "secondary: %s (%s chan=%d ht=%d)\n",
+                               wiphy_name(aphy->hw->wiphy),
+                               ath_wiphy_state_str(aphy->state),
+                               aphy->chan_idx, aphy->chan_is_ht);
+       }
+
+       put_unaligned_le32(REG_READ(sc->sc_ah, AR_STA_ID0), addr);
+       put_unaligned_le16(REG_READ(sc->sc_ah, AR_STA_ID1) & 0xffff, addr + 4);
+       len += snprintf(buf + len, sizeof(buf) - len,
+                       "addr: %pM\n", addr);
+       put_unaligned_le32(REG_READ(sc->sc_ah, AR_BSSMSKL), addr);
+       put_unaligned_le16(REG_READ(sc->sc_ah, AR_BSSMSKU) & 0xffff, addr + 4);
+       len += snprintf(buf + len, sizeof(buf) - len,
+                       "addrmask: %pM\n", addr);
+
+       return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static struct ath_wiphy * get_wiphy(struct ath_softc *sc, const char *name)
+{
+       int i;
+       if (strcmp(name, wiphy_name(sc->pri_wiphy->hw->wiphy)) == 0)
+               return sc->pri_wiphy;
+       for (i = 0; i < sc->num_sec_wiphy; i++) {
+               struct ath_wiphy *aphy = sc->sec_wiphy[i];
+               if (aphy && strcmp(name, wiphy_name(aphy->hw->wiphy)) == 0)
+                       return aphy;
+       }
+       return NULL;
+}
+
+static int del_wiphy(struct ath_softc *sc, const char *name)
+{
+       struct ath_wiphy *aphy = get_wiphy(sc, name);
+       if (!aphy)
+               return -ENOENT;
+       return ath9k_wiphy_del(aphy);
+}
+
+static int pause_wiphy(struct ath_softc *sc, const char *name)
+{
+       struct ath_wiphy *aphy = get_wiphy(sc, name);
+       if (!aphy)
+               return -ENOENT;
+       return ath9k_wiphy_pause(aphy);
+}
+
+static int unpause_wiphy(struct ath_softc *sc, const char *name)
+{
+       struct ath_wiphy *aphy = get_wiphy(sc, name);
+       if (!aphy)
+               return -ENOENT;
+       return ath9k_wiphy_unpause(aphy);
+}
+
+static int select_wiphy(struct ath_softc *sc, const char *name)
+{
+       struct ath_wiphy *aphy = get_wiphy(sc, name);
+       if (!aphy)
+               return -ENOENT;
+       return ath9k_wiphy_select(aphy);
+}
+
+static int schedule_wiphy(struct ath_softc *sc, const char *msec)
+{
+       ath9k_wiphy_set_scheduler(sc, simple_strtoul(msec, NULL, 0));
+       return 0;
+}
+
+static ssize_t write_file_wiphy(struct file *file, const char __user *user_buf,
+                               size_t count, loff_t *ppos)
+{
+       struct ath_softc *sc = file->private_data;
+       char buf[50];
+       size_t len;
+
+       len = min(count, sizeof(buf) - 1);
+       if (copy_from_user(buf, user_buf, len))
+               return -EFAULT;
+       buf[len] = '\0';
+       if (len > 0 && buf[len - 1] == '\n')
+               buf[len - 1] = '\0';
+
+       if (strncmp(buf, "add", 3) == 0) {
+               int res = ath9k_wiphy_add(sc);
+               if (res < 0)
+                       return res;
+       } else if (strncmp(buf, "del=", 4) == 0) {
+               int res = del_wiphy(sc, buf + 4);
+               if (res < 0)
+                       return res;
+       } else if (strncmp(buf, "pause=", 6) == 0) {
+               int res = pause_wiphy(sc, buf + 6);
+               if (res < 0)
+                       return res;
+       } else if (strncmp(buf, "unpause=", 8) == 0) {
+               int res = unpause_wiphy(sc, buf + 8);
+               if (res < 0)
+                       return res;
+       } else if (strncmp(buf, "select=", 7) == 0) {
+               int res = select_wiphy(sc, buf + 7);
+               if (res < 0)
+                       return res;
+       } else if (strncmp(buf, "schedule=", 9) == 0) {
+               int res = schedule_wiphy(sc, buf + 9);
+               if (res < 0)
+                       return res;
+       } else
+               return -EOPNOTSUPP;
+
+       return count;
+}
+
+static const struct file_operations fops_wiphy = {
+       .read = read_file_wiphy,
+       .write = write_file_wiphy,
+       .open = ath9k_debugfs_open,
+       .owner = THIS_MODULE
+};
+
+
+int ath9k_init_debug(struct ath_softc *sc)
+{
+       sc->debug.debug_mask = ath9k_debug;
+
+       if (!ath9k_debugfs_root)
+               return -ENOENT;
+
+       sc->debug.debugfs_phy = debugfs_create_dir(wiphy_name(sc->hw->wiphy),
+                                                     ath9k_debugfs_root);
+       if (!sc->debug.debugfs_phy)
+               goto err;
+
+       sc->debug.debugfs_debug = debugfs_create_file("debug",
+               S_IRUGO | S_IWUSR, sc->debug.debugfs_phy, sc, &fops_debug);
+       if (!sc->debug.debugfs_debug)
+               goto err;
+
+       sc->debug.debugfs_dma = debugfs_create_file("dma", S_IRUGO,
+                                      sc->debug.debugfs_phy, sc, &fops_dma);
+       if (!sc->debug.debugfs_dma)
+               goto err;
+
+       sc->debug.debugfs_interrupt = debugfs_create_file("interrupt",
+                                                    S_IRUGO,
+                                                    sc->debug.debugfs_phy,
+                                                    sc, &fops_interrupt);
+       if (!sc->debug.debugfs_interrupt)
+               goto err;
+
+       sc->debug.debugfs_rcstat = debugfs_create_file("rcstat",
+                                                 S_IRUGO,
+                                                 sc->debug.debugfs_phy,
+                                                 sc, &fops_rcstat);
+       if (!sc->debug.debugfs_rcstat)
+               goto err;
+
+       sc->debug.debugfs_wiphy = debugfs_create_file(
+               "wiphy", S_IRUGO | S_IWUSR, sc->debug.debugfs_phy, sc,
+               &fops_wiphy);
+       if (!sc->debug.debugfs_wiphy)
+               goto err;
+
+       return 0;
+err:
+       ath9k_exit_debug(sc);
+       return -ENOMEM;
+}
+
+void ath9k_exit_debug(struct ath_softc *sc)
+{
+       debugfs_remove(sc->debug.debugfs_wiphy);
+       debugfs_remove(sc->debug.debugfs_rcstat);
+       debugfs_remove(sc->debug.debugfs_interrupt);
+       debugfs_remove(sc->debug.debugfs_dma);
+       debugfs_remove(sc->debug.debugfs_debug);
+       debugfs_remove(sc->debug.debugfs_phy);
+}
+
+int ath9k_debug_create_root(void)
+{
+       ath9k_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL);
+       if (!ath9k_debugfs_root)
+               return -ENOENT;
+
+       return 0;
+}
+
+void ath9k_debug_remove_root(void)
+{
+       debugfs_remove(ath9k_debugfs_root);
+       ath9k_debugfs_root = NULL;
+}
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h
new file mode 100644 (file)
index 0000000..edda15b
--- /dev/null
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2008-2009 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
+
+enum ATH_DEBUG {
+       ATH_DBG_RESET           = 0x00000001,
+       ATH_DBG_QUEUE           = 0x00000002,
+       ATH_DBG_EEPROM          = 0x00000004,
+       ATH_DBG_CALIBRATE       = 0x00000008,
+       ATH_DBG_INTERRUPT       = 0x00000010,
+       ATH_DBG_REGULATORY      = 0x00000020,
+       ATH_DBG_ANI             = 0x00000040,
+       ATH_DBG_XMIT            = 0x00000080,
+       ATH_DBG_BEACON          = 0x00000100,
+       ATH_DBG_CONFIG          = 0x00000200,
+       ATH_DBG_FATAL           = 0x00000400,
+       ATH_DBG_PS              = 0x00000800,
+       ATH_DBG_ANY             = 0xffffffff
+};
+
+#define DBG_DEFAULT (ATH_DBG_FATAL)
+
+#ifdef CONFIG_ATH9K_DEBUG
+
+/**
+ * struct ath_interrupt_stats - Contains statistics about interrupts
+ * @total: Total no. of interrupts generated so far
+ * @rxok: RX with no errors
+ * @rxeol: RX with no more RXDESC available
+ * @rxorn: RX FIFO overrun
+ * @txok: TX completed at the requested rate
+ * @txurn: TX FIFO underrun
+ * @mib: MIB regs reaching its threshold
+ * @rxphyerr: RX with phy errors
+ * @rx_keycache_miss: RX with key cache misses
+ * @swba: Software Beacon Alert
+ * @bmiss: Beacon Miss
+ * @bnr: Beacon Not Ready
+ * @cst: Carrier Sense TImeout
+ * @gtt: Global TX Timeout
+ * @tim: RX beacon TIM occurrence
+ * @cabend: RX End of CAB traffic
+ * @dtimsync: DTIM sync lossage
+ * @dtim: RX Beacon with DTIM
+ */
+struct ath_interrupt_stats {
+       u32 total;
+       u32 rxok;
+       u32 rxeol;
+       u32 rxorn;
+       u32 txok;
+       u32 txeol;
+       u32 txurn;
+       u32 mib;
+       u32 rxphyerr;
+       u32 rx_keycache_miss;
+       u32 swba;
+       u32 bmiss;
+       u32 bnr;
+       u32 cst;
+       u32 gtt;
+       u32 tim;
+       u32 cabend;
+       u32 dtimsync;
+       u32 dtim;
+};
+
+struct ath_rc_stats {
+       u32 success;
+       u32 retries;
+       u32 xretries;
+       u8 per;
+};
+
+struct ath_stats {
+       struct ath_interrupt_stats istats;
+       struct ath_rc_stats rcstats[RATE_TABLE_SIZE];
+};
+
+struct ath9k_debug {
+       int debug_mask;
+       struct dentry *debugfs_phy;
+       struct dentry *debugfs_debug;
+       struct dentry *debugfs_dma;
+       struct dentry *debugfs_interrupt;
+       struct dentry *debugfs_rcstat;
+       struct dentry *debugfs_wiphy;
+       struct ath_stats stats;
+};
+
+void DPRINTF(struct ath_softc *sc, int dbg_mask, const char *fmt, ...);
+int ath9k_init_debug(struct ath_softc *sc);
+void ath9k_exit_debug(struct ath_softc *sc);
+int ath9k_debug_create_root(void);
+void ath9k_debug_remove_root(void);
+void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status);
+void ath_debug_stat_rc(struct ath_softc *sc, struct sk_buff *skb);
+void ath_debug_stat_retries(struct ath_softc *sc, int rix,
+                           int xretries, int retries, u8 per);
+
+#else
+
+static inline void DPRINTF(struct ath_softc *sc, int dbg_mask,
+                          const char *fmt, ...)
+{
+}
+
+static inline int ath9k_init_debug(struct ath_softc *sc)
+{
+       return 0;
+}
+
+static inline void ath9k_exit_debug(struct ath_softc *sc)
+{
+}
+
+static inline int ath9k_debug_create_root(void)
+{
+       return 0;
+}
+
+static inline void ath9k_debug_remove_root(void)
+{
+}
+
+static inline void ath_debug_stat_interrupt(struct ath_softc *sc,
+                                           enum ath9k_int status)
+{
+}
+
+static inline void ath_debug_stat_rc(struct ath_softc *sc,
+                                    struct sk_buff *skb)
+{
+}
+
+static inline void ath_debug_stat_retries(struct ath_softc *sc, int rix,
+                                         int xretries, int retries, u8 per)
+{
+}
+
+#endif /* CONFIG_ATH9K_DEBUG */
+
+#endif /* DEBUG_H */
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.c b/drivers/net/wireless/ath/ath9k/eeprom.c
new file mode 100644 (file)
index 0000000..a2fda70
--- /dev/null
@@ -0,0 +1,2786 @@
+/*
+ * Copyright (c) 2008-2009 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 "ath9k.h"
+
+static void ath9k_hw_analog_shift_rmw(struct ath_hw *ah,
+                                     u32 reg, u32 mask,
+                                     u32 shift, u32 val)
+{
+       u32 regVal;
+
+       regVal = REG_READ(ah, reg) & ~mask;
+       regVal |= (val << shift) & mask;
+
+       REG_WRITE(ah, reg, regVal);
+
+       if (ah->config.analog_shiftreg)
+               udelay(100);
+
+       return;
+}
+
+static inline u16 ath9k_hw_fbin2freq(u8 fbin, bool is2GHz)
+{
+
+       if (fbin == AR5416_BCHAN_UNUSED)
+               return fbin;
+
+       return (u16) ((is2GHz) ? (2300 + fbin) : (4800 + 5 * fbin));
+}
+
+static inline int16_t ath9k_hw_interpolate(u16 target,
+                                          u16 srcLeft, u16 srcRight,
+                                          int16_t targetLeft,
+                                          int16_t targetRight)
+{
+       int16_t rv;
+
+       if (srcRight == srcLeft) {
+               rv = targetLeft;
+       } else {
+               rv = (int16_t) (((target - srcLeft) * targetRight +
+                                (srcRight - target) * targetLeft) /
+                               (srcRight - srcLeft));
+       }
+       return rv;
+}
+
+static inline bool ath9k_hw_get_lower_upper_index(u8 target, u8 *pList,
+                                                 u16 listSize, u16 *indexL,
+                                                 u16 *indexR)
+{
+       u16 i;
+
+       if (target <= pList[0]) {
+               *indexL = *indexR = 0;
+               return true;
+       }
+       if (target >= pList[listSize - 1]) {
+               *indexL = *indexR = (u16) (listSize - 1);
+               return true;
+       }
+
+       for (i = 0; i < listSize - 1; i++) {
+               if (pList[i] == target) {
+                       *indexL = *indexR = i;
+                       return true;
+               }
+               if (target < pList[i + 1]) {
+                       *indexL = i;
+                       *indexR = (u16) (i + 1);
+                       return false;
+               }
+       }
+       return false;
+}
+
+static inline bool ath9k_hw_nvram_read(struct ath_hw *ah, u32 off, u16 *data)
+{
+       struct ath_softc *sc = ah->ah_sc;
+
+       return sc->bus_ops->eeprom_read(ah, off, data);
+}
+
+static inline bool ath9k_hw_fill_vpd_table(u8 pwrMin, u8 pwrMax, u8 *pPwrList,
+                                          u8 *pVpdList, u16 numIntercepts,
+                                          u8 *pRetVpdList)
+{
+       u16 i, k;
+       u8 currPwr = pwrMin;
+       u16 idxL = 0, idxR = 0;
+
+       for (i = 0; i <= (pwrMax - pwrMin) / 2; i++) {
+               ath9k_hw_get_lower_upper_index(currPwr, pPwrList,
+                                              numIntercepts, &(idxL),
+                                              &(idxR));
+               if (idxR < 1)
+                       idxR = 1;
+               if (idxL == numIntercepts - 1)
+                       idxL = (u16) (numIntercepts - 2);
+               if (pPwrList[idxL] == pPwrList[idxR])
+                       k = pVpdList[idxL];
+               else
+                       k = (u16)(((currPwr - pPwrList[idxL]) * pVpdList[idxR] +
+                                  (pPwrList[idxR] - currPwr) * pVpdList[idxL]) /
+                                 (pPwrList[idxR] - pPwrList[idxL]));
+               pRetVpdList[i] = (u8) k;
+               currPwr += 2;
+       }
+
+       return true;
+}
+
+static void ath9k_hw_get_legacy_target_powers(struct ath_hw *ah,
+                                     struct ath9k_channel *chan,
+                                     struct cal_target_power_leg *powInfo,
+                                     u16 numChannels,
+                                     struct cal_target_power_leg *pNewPower,
+                                     u16 numRates, bool isExtTarget)
+{
+       struct chan_centers centers;
+       u16 clo, chi;
+       int i;
+       int matchIndex = -1, lowIndex = -1;
+       u16 freq;
+
+       ath9k_hw_get_channel_centers(ah, chan, &centers);
+       freq = (isExtTarget) ? centers.ext_center : centers.ctl_center;
+
+       if (freq <= ath9k_hw_fbin2freq(powInfo[0].bChannel,
+                                      IS_CHAN_2GHZ(chan))) {
+               matchIndex = 0;
+       } else {
+               for (i = 0; (i < numChannels) &&
+                            (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
+                       if (freq == ath9k_hw_fbin2freq(powInfo[i].bChannel,
+                                                      IS_CHAN_2GHZ(chan))) {
+                               matchIndex = i;
+                               break;
+                       } else if ((freq < ath9k_hw_fbin2freq(powInfo[i].bChannel,
+                                                     IS_CHAN_2GHZ(chan))) &&
+                                  (freq > ath9k_hw_fbin2freq(powInfo[i - 1].bChannel,
+                                                     IS_CHAN_2GHZ(chan)))) {
+                               lowIndex = i - 1;
+                               break;
+                       }
+               }
+               if ((matchIndex == -1) && (lowIndex == -1))
+                       matchIndex = i - 1;
+       }
+
+       if (matchIndex != -1) {
+               *pNewPower = powInfo[matchIndex];
+       } else {
+               clo = ath9k_hw_fbin2freq(powInfo[lowIndex].bChannel,
+                                        IS_CHAN_2GHZ(chan));
+               chi = ath9k_hw_fbin2freq(powInfo[lowIndex + 1].bChannel,
+                                        IS_CHAN_2GHZ(chan));
+
+               for (i = 0; i < numRates; i++) {
+                       pNewPower->tPow2x[i] =
+                               (u8)ath9k_hw_interpolate(freq, clo, chi,
+                                               powInfo[lowIndex].tPow2x[i],
+                                               powInfo[lowIndex + 1].tPow2x[i]);
+               }
+       }
+}
+
+static void ath9k_get_txgain_index(struct ath_hw *ah,
+               struct ath9k_channel *chan,
+               struct calDataPerFreqOpLoop *rawDatasetOpLoop,
+               u8 *calChans,  u16 availPiers, u8 *pwr, u8 *pcdacIdx)
+{
+       u8 pcdac, i = 0;
+       u16 idxL = 0, idxR = 0, numPiers;
+       bool match;
+       struct chan_centers centers;
+
+       ath9k_hw_get_channel_centers(ah, chan, &centers);
+
+       for (numPiers = 0; numPiers < availPiers; numPiers++)
+               if (calChans[numPiers] == AR5416_BCHAN_UNUSED)
+                       break;
+
+       match = ath9k_hw_get_lower_upper_index(
+                       (u8)FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan)),
+                       calChans, numPiers, &idxL, &idxR);
+       if (match) {
+               pcdac = rawDatasetOpLoop[idxL].pcdac[0][0];
+               *pwr = rawDatasetOpLoop[idxL].pwrPdg[0][0];
+       } else {
+               pcdac = rawDatasetOpLoop[idxR].pcdac[0][0];
+               *pwr = (rawDatasetOpLoop[idxL].pwrPdg[0][0] +
+                               rawDatasetOpLoop[idxR].pwrPdg[0][0])/2;
+       }
+
+       while (pcdac > ah->originalGain[i] &&
+                       i < (AR9280_TX_GAIN_TABLE_SIZE - 1))
+               i++;
+
+       *pcdacIdx = i;
+       return;
+}
+
+static void ath9k_olc_get_pdadcs(struct ath_hw *ah,
+                               u32 initTxGain,
+                               int txPower,
+                               u8 *pPDADCValues)
+{
+       u32 i;
+       u32 offset;
+
+       REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL6_0,
+                       AR_PHY_TX_PWRCTRL_ERR_EST_MODE, 3);
+       REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL6_1,
+                       AR_PHY_TX_PWRCTRL_ERR_EST_MODE, 3);
+
+       REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL7,
+                       AR_PHY_TX_PWRCTRL_INIT_TX_GAIN, initTxGain);
+
+       offset = txPower;
+       for (i = 0; i < AR5416_NUM_PDADC_VALUES; i++)
+               if (i < offset)
+                       pPDADCValues[i] = 0x0;
+               else
+                       pPDADCValues[i] = 0xFF;
+}
+
+
+
+
+static void ath9k_hw_get_target_powers(struct ath_hw *ah,
+                                      struct ath9k_channel *chan,
+                                      struct cal_target_power_ht *powInfo,
+                                      u16 numChannels,
+                                      struct cal_target_power_ht *pNewPower,
+                                      u16 numRates, bool isHt40Target)
+{
+       struct chan_centers centers;
+       u16 clo, chi;
+       int i;
+       int matchIndex = -1, lowIndex = -1;
+       u16 freq;
+
+       ath9k_hw_get_channel_centers(ah, chan, &centers);
+       freq = isHt40Target ? centers.synth_center : centers.ctl_center;
+
+       if (freq <= ath9k_hw_fbin2freq(powInfo[0].bChannel, IS_CHAN_2GHZ(chan))) {
+               matchIndex = 0;
+       } else {
+               for (i = 0; (i < numChannels) &&
+                            (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
+                       if (freq == ath9k_hw_fbin2freq(powInfo[i].bChannel,
+                                                      IS_CHAN_2GHZ(chan))) {
+                               matchIndex = i;
+                               break;
+                       } else
+                               if ((freq < ath9k_hw_fbin2freq(powInfo[i].bChannel,
+                                                      IS_CHAN_2GHZ(chan))) &&
+                                   (freq > ath9k_hw_fbin2freq(powInfo[i - 1].bChannel,
+                                                      IS_CHAN_2GHZ(chan)))) {
+                                       lowIndex = i - 1;
+                                       break;
+                               }
+               }
+               if ((matchIndex == -1) && (lowIndex == -1))
+                       matchIndex = i - 1;
+       }
+
+       if (matchIndex != -1) {
+               *pNewPower = powInfo[matchIndex];
+       } else {
+               clo = ath9k_hw_fbin2freq(powInfo[lowIndex].bChannel,
+                                        IS_CHAN_2GHZ(chan));
+               chi = ath9k_hw_fbin2freq(powInfo[lowIndex + 1].bChannel,
+                                        IS_CHAN_2GHZ(chan));
+
+               for (i = 0; i < numRates; i++) {
+                       pNewPower->tPow2x[i] = (u8)ath9k_hw_interpolate(freq,
+                                               clo, chi,
+                                               powInfo[lowIndex].tPow2x[i],
+                                               powInfo[lowIndex + 1].tPow2x[i]);
+               }
+       }
+}
+
+static u16 ath9k_hw_get_max_edge_power(u16 freq,
+                                      struct cal_ctl_edges *pRdEdgesPower,
+                                      bool is2GHz, int num_band_edges)
+{
+       u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
+       int i;
+
+       for (i = 0; (i < num_band_edges) &&
+                    (pRdEdgesPower[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
+               if (freq == ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel, is2GHz)) {
+                       twiceMaxEdgePower = pRdEdgesPower[i].tPower;
+                       break;
+               } else if ((i > 0) &&
+                          (freq < ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel,
+                                                     is2GHz))) {
+                       if (ath9k_hw_fbin2freq(pRdEdgesPower[i - 1].bChannel,
+                                              is2GHz) < freq &&
+                           pRdEdgesPower[i - 1].flag) {
+                               twiceMaxEdgePower =
+                                       pRdEdgesPower[i - 1].tPower;
+                       }
+                       break;
+               }
+       }
+
+       return twiceMaxEdgePower;
+}
+
+/****************************************/
+/* EEPROM Operations for 4K sized cards */
+/****************************************/
+
+static int ath9k_hw_4k_get_eeprom_ver(struct ath_hw *ah)
+{
+       return ((ah->eeprom.map4k.baseEepHeader.version >> 12) & 0xF);
+}
+
+static int ath9k_hw_4k_get_eeprom_rev(struct ath_hw *ah)
+{
+       return ((ah->eeprom.map4k.baseEepHeader.version) & 0xFFF);
+}
+
+static bool ath9k_hw_4k_fill_eeprom(struct ath_hw *ah)
+{
+#define SIZE_EEPROM_4K (sizeof(struct ar5416_eeprom_4k) / sizeof(u16))
+       u16 *eep_data = (u16 *)&ah->eeprom.map4k;
+       int addr, eep_start_loc = 0;
+
+       eep_start_loc = 64;
+
+       if (!ath9k_hw_use_flash(ah)) {
+               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+                       "Reading from EEPROM, not flash\n");
+       }
+
+       for (addr = 0; addr < SIZE_EEPROM_4K; addr++) {
+               if (!ath9k_hw_nvram_read(ah, addr + eep_start_loc, eep_data)) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+                              "Unable to read eeprom region \n");
+                       return false;
+               }
+               eep_data++;
+       }
+
+       return true;
+#undef SIZE_EEPROM_4K
+}
+
+static int ath9k_hw_4k_check_eeprom(struct ath_hw *ah)
+{
+#define EEPROM_4K_SIZE (sizeof(struct ar5416_eeprom_4k) / sizeof(u16))
+       struct ar5416_eeprom_4k *eep =
+               (struct ar5416_eeprom_4k *) &ah->eeprom.map4k;
+       u16 *eepdata, temp, magic, magic2;
+       u32 sum = 0, el;
+       bool need_swap = false;
+       int i, addr;
+
+
+       if (!ath9k_hw_use_flash(ah)) {
+               if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET,
+                                        &magic)) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+                               "Reading Magic # failed\n");
+                       return false;
+               }
+
+               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+                       "Read Magic = 0x%04X\n", magic);
+
+               if (magic != AR5416_EEPROM_MAGIC) {
+                       magic2 = swab16(magic);
+
+                       if (magic2 == AR5416_EEPROM_MAGIC) {
+                               need_swap = true;
+                               eepdata = (u16 *) (&ah->eeprom);
+
+                               for (addr = 0; addr < EEPROM_4K_SIZE; addr++) {
+                                       temp = swab16(*eepdata);
+                                       *eepdata = temp;
+                                       eepdata++;
+                               }
+                       } else {
+                               DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+                                       "Invalid EEPROM Magic. "
+                                       "endianness mismatch.\n");
+                               return -EINVAL;
+                       }
+               }
+       }
+
+       DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "need_swap = %s.\n",
+               need_swap ? "True" : "False");
+
+       if (need_swap)
+               el = swab16(ah->eeprom.map4k.baseEepHeader.length);
+       else
+               el = ah->eeprom.map4k.baseEepHeader.length;
+
+       if (el > sizeof(struct ar5416_eeprom_4k))
+               el = sizeof(struct ar5416_eeprom_4k) / sizeof(u16);
+       else
+               el = el / sizeof(u16);
+
+       eepdata = (u16 *)(&ah->eeprom);
+
+       for (i = 0; i < el; i++)
+               sum ^= *eepdata++;
+
+       if (need_swap) {
+               u32 integer;
+               u16 word;
+
+               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+                       "EEPROM Endianness is not native.. Changing\n");
+
+               word = swab16(eep->baseEepHeader.length);
+               eep->baseEepHeader.length = word;
+
+               word = swab16(eep->baseEepHeader.checksum);
+               eep->baseEepHeader.checksum = word;
+
+               word = swab16(eep->baseEepHeader.version);
+               eep->baseEepHeader.version = word;
+
+               word = swab16(eep->baseEepHeader.regDmn[0]);
+               eep->baseEepHeader.regDmn[0] = word;
+
+               word = swab16(eep->baseEepHeader.regDmn[1]);
+               eep->baseEepHeader.regDmn[1] = word;
+
+               word = swab16(eep->baseEepHeader.rfSilent);
+               eep->baseEepHeader.rfSilent = word;
+
+               word = swab16(eep->baseEepHeader.blueToothOptions);
+               eep->baseEepHeader.blueToothOptions = word;
+
+               word = swab16(eep->baseEepHeader.deviceCap);
+               eep->baseEepHeader.deviceCap = word;
+
+               integer = swab32(eep->modalHeader.antCtrlCommon);
+               eep->modalHeader.antCtrlCommon = integer;
+
+               for (i = 0; i < AR5416_MAX_CHAINS; i++) {
+                       integer = swab32(eep->modalHeader.antCtrlChain[i]);
+                       eep->modalHeader.antCtrlChain[i] = integer;
+               }
+
+               for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) {
+                       word = swab16(eep->modalHeader.spurChans[i].spurChan);
+                       eep->modalHeader.spurChans[i].spurChan = word;
+               }
+       }
+
+       if (sum != 0xffff || ah->eep_ops->get_eeprom_ver(ah) != AR5416_EEP_VER ||
+           ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_NO_BACK_VER) {
+               DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+                       "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
+                       sum, ah->eep_ops->get_eeprom_ver(ah));
+               return -EINVAL;
+       }
+
+       return 0;
+#undef EEPROM_4K_SIZE
+}
+
+static u32 ath9k_hw_4k_get_eeprom(struct ath_hw *ah,
+                                 enum eeprom_param param)
+{
+       struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
+       struct modal_eep_4k_header *pModal = &eep->modalHeader;
+       struct base_eep_header_4k *pBase = &eep->baseEepHeader;
+
+       switch (param) {
+       case EEP_NFTHRESH_2:
+               return pModal->noiseFloorThreshCh[0];
+       case AR_EEPROM_MAC(0):
+               return pBase->macAddr[0] << 8 | pBase->macAddr[1];
+       case AR_EEPROM_MAC(1):
+               return pBase->macAddr[2] << 8 | pBase->macAddr[3];
+       case AR_EEPROM_MAC(2):
+               return pBase->macAddr[4] << 8 | pBase->macAddr[5];
+       case EEP_REG_0:
+               return pBase->regDmn[0];
+       case EEP_REG_1:
+               return pBase->regDmn[1];
+       case EEP_OP_CAP:
+               return pBase->deviceCap;
+       case EEP_OP_MODE:
+               return pBase->opCapFlags;
+       case EEP_RF_SILENT:
+               return pBase->rfSilent;
+       case EEP_OB_2:
+               return pModal->ob_01;
+       case EEP_DB_2:
+               return pModal->db1_01;
+       case EEP_MINOR_REV:
+               return pBase->version & AR5416_EEP_VER_MINOR_MASK;
+       case EEP_TX_MASK:
+               return pBase->txMask;
+       case EEP_RX_MASK:
+               return pBase->rxMask;
+       case EEP_FRAC_N_5G:
+               return 0;
+       default:
+               return 0;
+       }
+}
+
+static void ath9k_hw_get_4k_gain_boundaries_pdadcs(struct ath_hw *ah,
+                               struct ath9k_channel *chan,
+                               struct cal_data_per_freq_4k *pRawDataSet,
+                               u8 *bChans, u16 availPiers,
+                               u16 tPdGainOverlap, int16_t *pMinCalPower,
+                               u16 *pPdGainBoundaries, u8 *pPDADCValues,
+                               u16 numXpdGains)
+{
+#define TMP_VAL_VPD_TABLE \
+       ((vpdTableI[i][sizeCurrVpdTable - 1] + (ss - maxIndex + 1) * vpdStep));
+       int i, j, k;
+       int16_t ss;
+       u16 idxL = 0, idxR = 0, numPiers;
+       static u8 vpdTableL[AR5416_EEP4K_NUM_PD_GAINS]
+               [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
+       static u8 vpdTableR[AR5416_EEP4K_NUM_PD_GAINS]
+               [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
+       static u8 vpdTableI[AR5416_EEP4K_NUM_PD_GAINS]
+               [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
+
+       u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR;
+       u8 minPwrT4[AR5416_EEP4K_NUM_PD_GAINS];
+       u8 maxPwrT4[AR5416_EEP4K_NUM_PD_GAINS];
+       int16_t vpdStep;
+       int16_t tmpVal;
+       u16 sizeCurrVpdTable, maxIndex, tgtIndex;
+       bool match;
+       int16_t minDelta = 0;
+       struct chan_centers centers;
+#define PD_GAIN_BOUNDARY_DEFAULT 58;
+
+       ath9k_hw_get_channel_centers(ah, chan, &centers);
+
+       for (numPiers = 0; numPiers < availPiers; numPiers++) {
+               if (bChans[numPiers] == AR5416_BCHAN_UNUSED)
+                       break;
+       }
+
+       match = ath9k_hw_get_lower_upper_index(
+                                       (u8)FREQ2FBIN(centers.synth_center,
+                                       IS_CHAN_2GHZ(chan)), bChans, numPiers,
+                                       &idxL, &idxR);
+
+       if (match) {
+               for (i = 0; i < numXpdGains; i++) {
+                       minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0];
+                       maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4];
+                       ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
+                                       pRawDataSet[idxL].pwrPdg[i],
+                                       pRawDataSet[idxL].vpdPdg[i],
+                                       AR5416_EEP4K_PD_GAIN_ICEPTS,
+                                       vpdTableI[i]);
+               }
+       } else {
+               for (i = 0; i < numXpdGains; i++) {
+                       pVpdL = pRawDataSet[idxL].vpdPdg[i];
+                       pPwrL = pRawDataSet[idxL].pwrPdg[i];
+                       pVpdR = pRawDataSet[idxR].vpdPdg[i];
+                       pPwrR = pRawDataSet[idxR].pwrPdg[i];
+
+                       minPwrT4[i] = max(pPwrL[0], pPwrR[0]);
+
+                       maxPwrT4[i] =
+                               min(pPwrL[AR5416_EEP4K_PD_GAIN_ICEPTS - 1],
+                                   pPwrR[AR5416_EEP4K_PD_GAIN_ICEPTS - 1]);
+
+
+                       ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
+                                               pPwrL, pVpdL,
+                                               AR5416_EEP4K_PD_GAIN_ICEPTS,
+                                               vpdTableL[i]);
+                       ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
+                                               pPwrR, pVpdR,
+                                               AR5416_EEP4K_PD_GAIN_ICEPTS,
+                                               vpdTableR[i]);
+
+                       for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
+                               vpdTableI[i][j] =
+                                       (u8)(ath9k_hw_interpolate((u16)
+                                            FREQ2FBIN(centers.
+                                                      synth_center,
+                                                      IS_CHAN_2GHZ
+                                                      (chan)),
+                                            bChans[idxL], bChans[idxR],
+                                            vpdTableL[i][j], vpdTableR[i][j]));
+                       }
+               }
+       }
+
+       *pMinCalPower = (int16_t)(minPwrT4[0] / 2);
+
+       k = 0;
+
+       for (i = 0; i < numXpdGains; i++) {
+               if (i == (numXpdGains - 1))
+                       pPdGainBoundaries[i] =
+                               (u16)(maxPwrT4[i] / 2);
+               else
+                       pPdGainBoundaries[i] =
+                               (u16)((maxPwrT4[i] + minPwrT4[i + 1]) / 4);
+
+               pPdGainBoundaries[i] =
+                       min((u16)AR5416_MAX_RATE_POWER, pPdGainBoundaries[i]);
+
+               if ((i == 0) && !AR_SREV_5416_20_OR_LATER(ah)) {
+                       minDelta = pPdGainBoundaries[0] - 23;
+                       pPdGainBoundaries[0] = 23;
+               } else {
+                       minDelta = 0;
+               }
+
+               if (i == 0) {
+                       if (AR_SREV_9280_10_OR_LATER(ah))
+                               ss = (int16_t)(0 - (minPwrT4[i] / 2));
+                       else
+                               ss = 0;
+               } else {
+                       ss = (int16_t)((pPdGainBoundaries[i - 1] -
+                                       (minPwrT4[i] / 2)) -
+                                      tPdGainOverlap + 1 + minDelta);
+               }
+               vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]);
+               vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
+
+               while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
+                       tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep);
+                       pPDADCValues[k++] = (u8)((tmpVal < 0) ? 0 : tmpVal);
+                       ss++;
+               }
+
+               sizeCurrVpdTable = (u8) ((maxPwrT4[i] - minPwrT4[i]) / 2 + 1);
+               tgtIndex = (u8)(pPdGainBoundaries[i] + tPdGainOverlap -
+                               (minPwrT4[i] / 2));
+               maxIndex = (tgtIndex < sizeCurrVpdTable) ?
+                       tgtIndex : sizeCurrVpdTable;
+
+               while ((ss < maxIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1)))
+                       pPDADCValues[k++] = vpdTableI[i][ss++];
+
+               vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] -
+                                   vpdTableI[i][sizeCurrVpdTable - 2]);
+               vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
+
+               if (tgtIndex >= maxIndex) {
+                       while ((ss <= tgtIndex) &&
+                              (k < (AR5416_NUM_PDADC_VALUES - 1))) {
+                               tmpVal = (int16_t) TMP_VAL_VPD_TABLE;
+                               pPDADCValues[k++] = (u8)((tmpVal > 255) ?
+                                                        255 : tmpVal);
+                               ss++;
+                       }
+               }
+       }
+
+       while (i < AR5416_EEP4K_PD_GAINS_IN_MASK) {
+               pPdGainBoundaries[i] = PD_GAIN_BOUNDARY_DEFAULT;
+               i++;
+       }
+
+       while (k < AR5416_NUM_PDADC_VALUES) {
+               pPDADCValues[k] = pPDADCValues[k - 1];
+               k++;
+       }
+
+       return;
+#undef TMP_VAL_VPD_TABLE
+}
+
+static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
+                                 struct ath9k_channel *chan,
+                                 int16_t *pTxPowerIndexOffset)
+{
+       struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k;
+       struct cal_data_per_freq_4k *pRawDataset;
+       u8 *pCalBChans = NULL;
+       u16 pdGainOverlap_t2;
+       static u8 pdadcValues[AR5416_NUM_PDADC_VALUES];
+       u16 gainBoundaries[AR5416_EEP4K_PD_GAINS_IN_MASK];
+       u16 numPiers, i, j;
+       int16_t tMinCalPower;
+       u16 numXpdGain, xpdMask;
+       u16 xpdGainValues[AR5416_EEP4K_NUM_PD_GAINS] = { 0, 0 };
+       u32 reg32, regOffset, regChainOffset;
+
+       xpdMask = pEepData->modalHeader.xpdGain;
+
+       if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
+           AR5416_EEP_MINOR_VER_2) {
+               pdGainOverlap_t2 =
+                       pEepData->modalHeader.pdGainOverlap;
+       } else {
+               pdGainOverlap_t2 = (u16)(MS(REG_READ(ah, AR_PHY_TPCRG5),
+                                           AR_PHY_TPCRG5_PD_GAIN_OVERLAP));
+       }
+
+       pCalBChans = pEepData->calFreqPier2G;
+       numPiers = AR5416_EEP4K_NUM_2G_CAL_PIERS;
+
+       numXpdGain = 0;
+
+       for (i = 1; i <= AR5416_EEP4K_PD_GAINS_IN_MASK; i++) {
+               if ((xpdMask >> (AR5416_EEP4K_PD_GAINS_IN_MASK - i)) & 1) {
+                       if (numXpdGain >= AR5416_EEP4K_NUM_PD_GAINS)
+                               break;
+                       xpdGainValues[numXpdGain] =
+                               (u16)(AR5416_EEP4K_PD_GAINS_IN_MASK - i);
+                       numXpdGain++;
+               }
+       }
+
+       REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN,
+                     (numXpdGain - 1) & 0x3);
+       REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1,
+                     xpdGainValues[0]);
+       REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2,
+                     xpdGainValues[1]);
+       REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3, 0);
+
+       for (i = 0; i < AR5416_EEP4K_MAX_CHAINS; i++) {
+               if (AR_SREV_5416_20_OR_LATER(ah) &&
+                   (ah->rxchainmask == 5 || ah->txchainmask == 5) &&
+                   (i != 0)) {
+                       regChainOffset = (i == 1) ? 0x2000 : 0x1000;
+               } else
+                       regChainOffset = i * 0x1000;
+
+               if (pEepData->baseEepHeader.txMask & (1 << i)) {
+                       pRawDataset = pEepData->calPierData2G[i];
+
+                       ath9k_hw_get_4k_gain_boundaries_pdadcs(ah, chan,
+                                           pRawDataset, pCalBChans,
+                                           numPiers, pdGainOverlap_t2,
+                                           &tMinCalPower, gainBoundaries,
+                                           pdadcValues, numXpdGain);
+
+                       if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah)) {
+                               REG_WRITE(ah, AR_PHY_TPCRG5 + regChainOffset,
+                                         SM(pdGainOverlap_t2,
+                                            AR_PHY_TPCRG5_PD_GAIN_OVERLAP)
+                                         | SM(gainBoundaries[0],
+                                              AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1)
+                                         | SM(gainBoundaries[1],
+                                              AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2)
+                                         | SM(gainBoundaries[2],
+                                              AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3)
+                                         | SM(gainBoundaries[3],
+                                      AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4));
+                       }
+
+                       regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset;
+                       for (j = 0; j < 32; j++) {
+                               reg32 = ((pdadcValues[4 * j + 0] & 0xFF) << 0) |
+                                       ((pdadcValues[4 * j + 1] & 0xFF) << 8) |
+                                       ((pdadcValues[4 * j + 2] & 0xFF) << 16)|
+                                       ((pdadcValues[4 * j + 3] & 0xFF) << 24);
+                               REG_WRITE(ah, regOffset, reg32);
+
+                               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+                                       "PDADC (%d,%4x): %4.4x %8.8x\n",
+                                       i, regChainOffset, regOffset,
+                                       reg32);
+                               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+                                       "PDADC: Chain %d | "
+                                       "PDADC %3d Value %3d | "
+                                       "PDADC %3d Value %3d | "
+                                       "PDADC %3d Value %3d | "
+                                       "PDADC %3d Value %3d |\n",
+                                       i, 4 * j, pdadcValues[4 * j],
+                                       4 * j + 1, pdadcValues[4 * j + 1],
+                                       4 * j + 2, pdadcValues[4 * j + 2],
+                                       4 * j + 3,
+                                       pdadcValues[4 * j + 3]);
+
+                               regOffset += 4;
+                       }
+               }
+       }
+
+       *pTxPowerIndexOffset = 0;
+}
+
+static void ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah,
+                                                struct ath9k_channel *chan,
+                                                int16_t *ratesArray,
+                                                u16 cfgCtl,
+                                                u16 AntennaReduction,
+                                                u16 twiceMaxRegulatoryPower,
+                                                u16 powerLimit)
+{
+       struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k;
+       u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
+       static const u16 tpScaleReductionTable[5] =
+               { 0, 3, 6, 9, AR5416_MAX_RATE_POWER };
+
+       int i;
+       int16_t twiceLargestAntenna;
+       struct cal_ctl_data_4k *rep;
+       struct cal_target_power_leg targetPowerOfdm, targetPowerCck = {
+               0, { 0, 0, 0, 0}
+       };
+       struct cal_target_power_leg targetPowerOfdmExt = {
+               0, { 0, 0, 0, 0} }, targetPowerCckExt = {
+               0, { 0, 0, 0, 0 }
+       };
+       struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = {
+               0, {0, 0, 0, 0}
+       };
+       u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
+       u16 ctlModesFor11g[] =
+               { CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT,
+                 CTL_2GHT40
+               };
+       u16 numCtlModes, *pCtlMode, ctlMode, freq;
+       struct chan_centers centers;
+       int tx_chainmask;
+       u16 twiceMinEdgePower;
+
+       tx_chainmask = ah->txchainmask;
+
+       ath9k_hw_get_channel_centers(ah, chan, &centers);
+
+       twiceLargestAntenna = pEepData->modalHeader.antennaGainCh[0];
+
+       twiceLargestAntenna = (int16_t)min(AntennaReduction -
+                                          twiceLargestAntenna, 0);
+
+       maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
+
+       if (ah->regulatory.tp_scale != ATH9K_TP_SCALE_MAX) {
+               maxRegAllowedPower -=
+                       (tpScaleReductionTable[(ah->regulatory.tp_scale)] * 2);
+       }
+
+       scaledPower = min(powerLimit, maxRegAllowedPower);
+       scaledPower = max((u16)0, scaledPower);
+
+       numCtlModes = ARRAY_SIZE(ctlModesFor11g) - SUB_NUM_CTL_MODES_AT_2G_40;
+       pCtlMode = ctlModesFor11g;
+
+       ath9k_hw_get_legacy_target_powers(ah, chan,
+                       pEepData->calTargetPowerCck,
+                       AR5416_NUM_2G_CCK_TARGET_POWERS,
+                       &targetPowerCck, 4, false);
+       ath9k_hw_get_legacy_target_powers(ah, chan,
+                       pEepData->calTargetPower2G,
+                       AR5416_NUM_2G_20_TARGET_POWERS,
+                       &targetPowerOfdm, 4, false);
+       ath9k_hw_get_target_powers(ah, chan,
+                       pEepData->calTargetPower2GHT20,
+                       AR5416_NUM_2G_20_TARGET_POWERS,
+                       &targetPowerHt20, 8, false);
+
+       if (IS_CHAN_HT40(chan)) {
+               numCtlModes = ARRAY_SIZE(ctlModesFor11g);
+               ath9k_hw_get_target_powers(ah, chan,
+                               pEepData->calTargetPower2GHT40,
+                               AR5416_NUM_2G_40_TARGET_POWERS,
+                               &targetPowerHt40, 8, true);
+               ath9k_hw_get_legacy_target_powers(ah, chan,
+                               pEepData->calTargetPowerCck,
+                               AR5416_NUM_2G_CCK_TARGET_POWERS,
+                               &targetPowerCckExt, 4, true);
+               ath9k_hw_get_legacy_target_powers(ah, chan,
+                               pEepData->calTargetPower2G,
+                               AR5416_NUM_2G_20_TARGET_POWERS,
+                               &targetPowerOfdmExt, 4, true);
+       }
+
+       for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
+               bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) ||
+                       (pCtlMode[ctlMode] == CTL_2GHT40);
+               if (isHt40CtlMode)
+                       freq = centers.synth_center;
+               else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
+                       freq = centers.ext_center;
+               else
+                       freq = centers.ctl_center;
+
+               if (ah->eep_ops->get_eeprom_ver(ah) == 14 &&
+                   ah->eep_ops->get_eeprom_rev(ah) <= 2)
+                       twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
+
+               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+                       "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, "
+                       "EXT_ADDITIVE %d\n",
+                       ctlMode, numCtlModes, isHt40CtlMode,
+                       (pCtlMode[ctlMode] & EXT_ADDITIVE));
+
+               for (i = 0; (i < AR5416_NUM_CTLS) &&
+                               pEepData->ctlIndex[i]; i++) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+                               "  LOOP-Ctlidx %d: cfgCtl 0x%2.2x "
+                               "pCtlMode 0x%2.2x ctlIndex 0x%2.2x "
+                               "chan %d\n",
+                               i, cfgCtl, pCtlMode[ctlMode],
+                               pEepData->ctlIndex[i], chan->channel);
+
+                       if ((((cfgCtl & ~CTL_MODE_M) |
+                             (pCtlMode[ctlMode] & CTL_MODE_M)) ==
+                            pEepData->ctlIndex[i]) ||
+                           (((cfgCtl & ~CTL_MODE_M) |
+                             (pCtlMode[ctlMode] & CTL_MODE_M)) ==
+                            ((pEepData->ctlIndex[i] & CTL_MODE_M) |
+                             SD_NO_CTL))) {
+                               rep = &(pEepData->ctlData[i]);
+
+                               twiceMinEdgePower =
+                                       ath9k_hw_get_max_edge_power(freq,
+                               rep->ctlEdges[ar5416_get_ntxchains
+                                               (tx_chainmask) - 1],
+                               IS_CHAN_2GHZ(chan),
+                               AR5416_EEP4K_NUM_BAND_EDGES);
+
+                               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+                                       "    MATCH-EE_IDX %d: ch %d is2 %d "
+                                       "2xMinEdge %d chainmask %d chains %d\n",
+                                       i, freq, IS_CHAN_2GHZ(chan),
+                                       twiceMinEdgePower, tx_chainmask,
+                                       ar5416_get_ntxchains
+                                       (tx_chainmask));
+                               if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) {
+                                       twiceMaxEdgePower =
+                                               min(twiceMaxEdgePower,
+                                                   twiceMinEdgePower);
+                               } else {
+                                       twiceMaxEdgePower = twiceMinEdgePower;
+                                       break;
+                               }
+                       }
+               }
+
+               minCtlPower = (u8)min(twiceMaxEdgePower, scaledPower);
+
+               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+                       "    SEL-Min ctlMode %d pCtlMode %d "
+                       "2xMaxEdge %d sP %d minCtlPwr %d\n",
+                       ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower,
+                       scaledPower, minCtlPower);
+
+               switch (pCtlMode[ctlMode]) {
+               case CTL_11B:
+                       for (i = 0; i < ARRAY_SIZE(targetPowerCck.tPow2x);
+                                       i++) {
+                               targetPowerCck.tPow2x[i] =
+                                       min((u16)targetPowerCck.tPow2x[i],
+                                           minCtlPower);
+                       }
+                       break;
+               case CTL_11G:
+                       for (i = 0; i < ARRAY_SIZE(targetPowerOfdm.tPow2x);
+                                       i++) {
+                               targetPowerOfdm.tPow2x[i] =
+                                       min((u16)targetPowerOfdm.tPow2x[i],
+                                           minCtlPower);
+                       }
+                       break;
+               case CTL_2GHT20:
+                       for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x);
+                                       i++) {
+                               targetPowerHt20.tPow2x[i] =
+                                       min((u16)targetPowerHt20.tPow2x[i],
+                                           minCtlPower);
+                       }
+                       break;
+               case CTL_11B_EXT:
+                       targetPowerCckExt.tPow2x[0] = min((u16)
+                                       targetPowerCckExt.tPow2x[0],
+                                       minCtlPower);
+                       break;
+               case CTL_11G_EXT:
+                       targetPowerOfdmExt.tPow2x[0] = min((u16)
+                                       targetPowerOfdmExt.tPow2x[0],
+                                       minCtlPower);
+                       break;
+               case CTL_2GHT40:
+                       for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x);
+                                       i++) {
+                               targetPowerHt40.tPow2x[i] =
+                                       min((u16)targetPowerHt40.tPow2x[i],
+                                           minCtlPower);
+                       }
+                       break;
+               default:
+                       break;
+               }
+       }
+
+       ratesArray[rate6mb] = ratesArray[rate9mb] = ratesArray[rate12mb] =
+               ratesArray[rate18mb] = ratesArray[rate24mb] =
+               targetPowerOfdm.tPow2x[0];
+       ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1];
+       ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2];
+       ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3];
+       ratesArray[rateXr] = targetPowerOfdm.tPow2x[0];
+
+       for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++)
+               ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i];
+
+       ratesArray[rate1l] = targetPowerCck.tPow2x[0];
+       ratesArray[rate2s] = ratesArray[rate2l] = targetPowerCck.tPow2x[1];
+       ratesArray[rate5_5s] = ratesArray[rate5_5l] = targetPowerCck.tPow2x[2];
+       ratesArray[rate11s] = ratesArray[rate11l] = targetPowerCck.tPow2x[3];
+
+       if (IS_CHAN_HT40(chan)) {
+               for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
+                       ratesArray[rateHt40_0 + i] =
+                               targetPowerHt40.tPow2x[i];
+               }
+               ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0];
+               ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0];
+               ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0];
+               ratesArray[rateExtCck] = targetPowerCckExt.tPow2x[0];
+       }
+}
+
+static void ath9k_hw_4k_set_txpower(struct ath_hw *ah,
+                                  struct ath9k_channel *chan,
+                                  u16 cfgCtl,
+                                  u8 twiceAntennaReduction,
+                                  u8 twiceMaxRegulatoryPower,
+                                  u8 powerLimit)
+{
+       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;
+
+       memset(ratesArray, 0, sizeof(ratesArray));
+
+       if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
+           AR5416_EEP_MINOR_VER_2) {
+               ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
+       }
+
+       ath9k_hw_set_4k_power_per_rate_table(ah, chan,
+                                              &ratesArray[0], cfgCtl,
+                                              twiceAntennaReduction,
+                                              twiceMaxRegulatoryPower,
+                                              powerLimit);
+
+       ath9k_hw_set_4k_power_cal_table(ah, chan, &txPowerIndexOffset);
+
+       for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
+               ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]);
+               if (ratesArray[i] > AR5416_MAX_RATE_POWER)
+                       ratesArray[i] = AR5416_MAX_RATE_POWER;
+       }
+
+       if (AR_SREV_9280_10_OR_LATER(ah)) {
+               for (i = 0; i < Ar5416RateSize; i++)
+                       ratesArray[i] -= AR5416_PWR_TABLE_OFFSET * 2;
+       }
+
+       REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
+                 ATH9K_POW_SM(ratesArray[rate18mb], 24)
+                 | ATH9K_POW_SM(ratesArray[rate12mb], 16)
+                 | ATH9K_POW_SM(ratesArray[rate9mb], 8)
+                 | ATH9K_POW_SM(ratesArray[rate6mb], 0));
+       REG_WRITE(ah, AR_PHY_POWER_TX_RATE2,
+                 ATH9K_POW_SM(ratesArray[rate54mb], 24)
+                 | ATH9K_POW_SM(ratesArray[rate48mb], 16)
+                 | ATH9K_POW_SM(ratesArray[rate36mb], 8)
+                 | ATH9K_POW_SM(ratesArray[rate24mb], 0));
+
+       if (IS_CHAN_2GHZ(chan)) {
+               REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
+                         ATH9K_POW_SM(ratesArray[rate2s], 24)
+                         | ATH9K_POW_SM(ratesArray[rate2l], 16)
+                         | ATH9K_POW_SM(ratesArray[rateXr], 8)
+                         | ATH9K_POW_SM(ratesArray[rate1l], 0));
+               REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
+                         ATH9K_POW_SM(ratesArray[rate11s], 24)
+                         | ATH9K_POW_SM(ratesArray[rate11l], 16)
+                         | ATH9K_POW_SM(ratesArray[rate5_5s], 8)
+                         | ATH9K_POW_SM(ratesArray[rate5_5l], 0));
+       }
+
+       REG_WRITE(ah, AR_PHY_POWER_TX_RATE5,
+                 ATH9K_POW_SM(ratesArray[rateHt20_3], 24)
+                 | ATH9K_POW_SM(ratesArray[rateHt20_2], 16)
+                 | ATH9K_POW_SM(ratesArray[rateHt20_1], 8)
+                 | ATH9K_POW_SM(ratesArray[rateHt20_0], 0));
+       REG_WRITE(ah, AR_PHY_POWER_TX_RATE6,
+                 ATH9K_POW_SM(ratesArray[rateHt20_7], 24)
+                 | ATH9K_POW_SM(ratesArray[rateHt20_6], 16)
+                 | ATH9K_POW_SM(ratesArray[rateHt20_5], 8)
+                 | ATH9K_POW_SM(ratesArray[rateHt20_4], 0));
+
+       if (IS_CHAN_HT40(chan)) {
+               REG_WRITE(ah, AR_PHY_POWER_TX_RATE7,
+                         ATH9K_POW_SM(ratesArray[rateHt40_3] +
+                                      ht40PowerIncForPdadc, 24)
+                         | ATH9K_POW_SM(ratesArray[rateHt40_2] +
+                                        ht40PowerIncForPdadc, 16)
+                         | ATH9K_POW_SM(ratesArray[rateHt40_1] +
+                                        ht40PowerIncForPdadc, 8)
+                         | ATH9K_POW_SM(ratesArray[rateHt40_0] +
+                                        ht40PowerIncForPdadc, 0));
+               REG_WRITE(ah, AR_PHY_POWER_TX_RATE8,
+                         ATH9K_POW_SM(ratesArray[rateHt40_7] +
+                                      ht40PowerIncForPdadc, 24)
+                         | ATH9K_POW_SM(ratesArray[rateHt40_6] +
+                                        ht40PowerIncForPdadc, 16)
+                         | ATH9K_POW_SM(ratesArray[rateHt40_5] +
+                                        ht40PowerIncForPdadc, 8)
+                         | ATH9K_POW_SM(ratesArray[rateHt40_4] +
+                                        ht40PowerIncForPdadc, 0));
+
+               REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
+                         ATH9K_POW_SM(ratesArray[rateExtOfdm], 24)
+                         | ATH9K_POW_SM(ratesArray[rateExtCck], 16)
+                         | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
+                         | ATH9K_POW_SM(ratesArray[rateDupCck], 0));
+       }
+
+       i = rate6mb;
+
+       if (IS_CHAN_HT40(chan))
+               i = rateHt40_0;
+       else if (IS_CHAN_HT20(chan))
+               i = rateHt20_0;
+
+       if (AR_SREV_9280_10_OR_LATER(ah))
+               ah->regulatory.max_power_level =
+                       ratesArray[i] + AR5416_PWR_TABLE_OFFSET * 2;
+       else
+               ah->regulatory.max_power_level = ratesArray[i];
+
+}
+
+static void ath9k_hw_4k_set_addac(struct ath_hw *ah,
+                                 struct ath9k_channel *chan)
+{
+       struct modal_eep_4k_header *pModal;
+       struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
+       u8 biaslevel;
+
+       if (ah->hw_version.macVersion != AR_SREV_VERSION_9160)
+               return;
+
+       if (ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_MINOR_VER_7)
+               return;
+
+       pModal = &eep->modalHeader;
+
+       if (pModal->xpaBiasLvl != 0xff) {
+               biaslevel = pModal->xpaBiasLvl;
+               INI_RA(&ah->iniAddac, 7, 1) =
+                 (INI_RA(&ah->iniAddac, 7, 1) & (~0x18)) | biaslevel << 3;
+       }
+}
+
+static void ath9k_hw_4k_set_gain(struct ath_hw *ah,
+                                struct modal_eep_4k_header *pModal,
+                                struct ar5416_eeprom_4k *eep,
+                                u8 txRxAttenLocal, int regChainOffset)
+{
+       REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset,
+                 pModal->antCtrlChain[0]);
+
+       REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset,
+                 (REG_READ(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset) &
+                  ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |
+                    AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
+                 SM(pModal->iqCalICh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
+                 SM(pModal->iqCalQCh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
+
+       if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
+           AR5416_EEP_MINOR_VER_3) {
+               txRxAttenLocal = pModal->txRxAttenCh[0];
+
+               REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+                             AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN, pModal->bswMargin[0]);
+               REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+                             AR_PHY_GAIN_2GHZ_XATTEN1_DB, pModal->bswAtten[0]);
+               REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+                             AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN,
+                             pModal->xatten2Margin[0]);
+               REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+                             AR_PHY_GAIN_2GHZ_XATTEN2_DB, pModal->xatten2Db[0]);
+       }
+
+       REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset,
+                     AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal);
+       REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset,
+                     AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[0]);
+
+       if (AR_SREV_9285_11(ah))
+               REG_WRITE(ah, AR9285_AN_TOP4, (AR9285_AN_TOP4_DEFAULT | 0x14));
+}
+
+static void ath9k_hw_4k_set_board_values(struct ath_hw *ah,
+                                        struct ath9k_channel *chan)
+{
+       struct modal_eep_4k_header *pModal;
+       struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
+       u8 txRxAttenLocal;
+       u8 ob[5], db1[5], db2[5];
+       u8 ant_div_control1, ant_div_control2;
+       u32 regVal;
+
+       pModal = &eep->modalHeader;
+       txRxAttenLocal = 23;
+
+       REG_WRITE(ah, AR_PHY_SWITCH_COM,
+                 ah->eep_ops->get_eeprom_antenna_cfg(ah, chan));
+
+       /* Single chain for 4K EEPROM*/
+       ath9k_hw_4k_set_gain(ah, pModal, eep, txRxAttenLocal, 0);
+
+       /* Initialize Ant Diversity settings from EEPROM */
+       if (pModal->version == 3) {
+               ant_div_control1 = ((pModal->ob_234 >> 12) & 0xf);
+               ant_div_control2 = ((pModal->db1_234 >> 12) & 0xf);
+               regVal = REG_READ(ah, 0x99ac);
+               regVal &= (~(0x7f000000));
+               regVal |= ((ant_div_control1 & 0x1) << 24);
+               regVal |= (((ant_div_control1 >> 1) & 0x1) << 29);
+               regVal |= (((ant_div_control1 >> 2) & 0x1) << 30);
+               regVal |= ((ant_div_control2 & 0x3) << 25);
+               regVal |= (((ant_div_control2 >> 2) & 0x3) << 27);
+               REG_WRITE(ah, 0x99ac, regVal);
+               regVal = REG_READ(ah, 0x99ac);
+               regVal = REG_READ(ah, 0xa208);
+               regVal &= (~(0x1 << 13));
+               regVal |= (((ant_div_control1 >> 3) & 0x1) << 13);
+               REG_WRITE(ah, 0xa208, regVal);
+               regVal = REG_READ(ah, 0xa208);
+       }
+
+       if (pModal->version >= 2) {
+               ob[0] = (pModal->ob_01 & 0xf);
+               ob[1] = (pModal->ob_01 >> 4) & 0xf;
+               ob[2] = (pModal->ob_234 & 0xf);
+               ob[3] = ((pModal->ob_234 >> 4) & 0xf);
+               ob[4] = ((pModal->ob_234 >> 8) & 0xf);
+
+               db1[0] = (pModal->db1_01 & 0xf);
+               db1[1] = ((pModal->db1_01 >> 4) & 0xf);
+               db1[2] = (pModal->db1_234 & 0xf);
+               db1[3] = ((pModal->db1_234 >> 4) & 0xf);
+               db1[4] = ((pModal->db1_234 >> 8) & 0xf);
+
+               db2[0] = (pModal->db2_01 & 0xf);
+               db2[1] = ((pModal->db2_01 >> 4) & 0xf);
+               db2[2] = (pModal->db2_234 & 0xf);
+               db2[3] = ((pModal->db2_234 >> 4) & 0xf);
+               db2[4] = ((pModal->db2_234 >> 8) & 0xf);
+
+       } else if (pModal->version == 1) {
+               ob[0] = (pModal->ob_01 & 0xf);
+               ob[1] = ob[2] = ob[3] = ob[4] = (pModal->ob_01 >> 4) & 0xf;
+               db1[0] = (pModal->db1_01 & 0xf);
+               db1[1] = db1[2] = db1[3] =
+                       db1[4] = ((pModal->db1_01 >> 4) & 0xf);
+               db2[0] = (pModal->db2_01 & 0xf);
+               db2[1] = db2[2] = db2[3] =
+                       db2[4] = ((pModal->db2_01 >> 4) & 0xf);
+       } else {
+               int i;
+               for (i = 0; i < 5; i++) {
+                       ob[i] = pModal->ob_01;
+                       db1[i] = pModal->db1_01;
+                       db2[i] = pModal->db1_01;
+               }
+       }
+
+       ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
+                       AR9285_AN_RF2G3_OB_0, AR9285_AN_RF2G3_OB_0_S, ob[0]);
+       ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
+                       AR9285_AN_RF2G3_OB_1, AR9285_AN_RF2G3_OB_1_S, ob[1]);
+       ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
+                       AR9285_AN_RF2G3_OB_2, AR9285_AN_RF2G3_OB_2_S, ob[2]);
+       ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
+                       AR9285_AN_RF2G3_OB_3, AR9285_AN_RF2G3_OB_3_S, ob[3]);
+       ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
+                       AR9285_AN_RF2G3_OB_4, AR9285_AN_RF2G3_OB_4_S, ob[4]);
+
+       ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
+                       AR9285_AN_RF2G3_DB1_0, AR9285_AN_RF2G3_DB1_0_S, db1[0]);
+       ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
+                       AR9285_AN_RF2G3_DB1_1, AR9285_AN_RF2G3_DB1_1_S, db1[1]);
+       ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
+                       AR9285_AN_RF2G3_DB1_2, AR9285_AN_RF2G3_DB1_2_S, db1[2]);
+       ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
+                       AR9285_AN_RF2G4_DB1_3, AR9285_AN_RF2G4_DB1_3_S, db1[3]);
+       ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
+                       AR9285_AN_RF2G4_DB1_4, AR9285_AN_RF2G4_DB1_4_S, db1[4]);
+
+       ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
+                       AR9285_AN_RF2G4_DB2_0, AR9285_AN_RF2G4_DB2_0_S, db2[0]);
+       ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
+                       AR9285_AN_RF2G4_DB2_1, AR9285_AN_RF2G4_DB2_1_S, db2[1]);
+       ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
+                       AR9285_AN_RF2G4_DB2_2, AR9285_AN_RF2G4_DB2_2_S, db2[2]);
+       ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
+                       AR9285_AN_RF2G4_DB2_3, AR9285_AN_RF2G4_DB2_3_S, db2[3]);
+       ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
+                       AR9285_AN_RF2G4_DB2_4, AR9285_AN_RF2G4_DB2_4_S, db2[4]);
+
+
+       if (AR_SREV_9285_11(ah))
+               REG_WRITE(ah, AR9285_AN_TOP4, AR9285_AN_TOP4_DEFAULT);
+
+       REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH,
+                     pModal->switchSettling);
+       REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC,
+                     pModal->adcDesiredSize);
+
+       REG_WRITE(ah, AR_PHY_RF_CTL4,
+                 SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF) |
+                 SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAB_OFF) |
+                 SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAA_ON)  |
+                 SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAB_ON));
+
+       REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON,
+                     pModal->txEndToRxOn);
+       REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62,
+                     pModal->thresh62);
+       REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0, AR_PHY_EXT_CCA0_THRESH62,
+                     pModal->thresh62);
+
+       if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
+                                               AR5416_EEP_MINOR_VER_2) {
+               REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_DATA_START,
+                             pModal->txFrameToDataStart);
+               REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_PA_ON,
+                             pModal->txFrameToPaOn);
+       }
+
+       if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
+                                               AR5416_EEP_MINOR_VER_3) {
+               if (IS_CHAN_HT40(chan))
+                       REG_RMW_FIELD(ah, AR_PHY_SETTLING,
+                                     AR_PHY_SETTLING_SWITCH,
+                                     pModal->swSettleHt40);
+       }
+}
+
+static u16 ath9k_hw_4k_get_eeprom_antenna_cfg(struct ath_hw *ah,
+                                             struct ath9k_channel *chan)
+{
+       struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
+       struct modal_eep_4k_header *pModal = &eep->modalHeader;
+
+       return pModal->antCtrlCommon & 0xFFFF;
+}
+
+static u8 ath9k_hw_4k_get_num_ant_config(struct ath_hw *ah,
+                                        enum ieee80211_band freq_band)
+{
+       return 1;
+}
+
+static u16 ath9k_hw_4k_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz)
+{
+#define EEP_MAP4K_SPURCHAN \
+       (ah->eeprom.map4k.modalHeader.spurChans[i].spurChan)
+
+       u16 spur_val = AR_NO_SPUR;
+
+       DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+               "Getting spur idx %d is2Ghz. %d val %x\n",
+               i, is2GHz, ah->config.spurchans[i][is2GHz]);
+
+       switch (ah->config.spurmode) {
+       case SPUR_DISABLE:
+               break;
+       case SPUR_ENABLE_IOCTL:
+               spur_val = ah->config.spurchans[i][is2GHz];
+               DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+                       "Getting spur val from new loc. %d\n", spur_val);
+               break;
+       case SPUR_ENABLE_EEPROM:
+               spur_val = EEP_MAP4K_SPURCHAN;
+               break;
+       }
+
+       return spur_val;
+
+#undef EEP_MAP4K_SPURCHAN
+}
+
+static 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,
+       .get_eeprom_ver         = ath9k_hw_4k_get_eeprom_ver,
+       .get_eeprom_rev         = ath9k_hw_4k_get_eeprom_rev,
+       .get_num_ant_config     = ath9k_hw_4k_get_num_ant_config,
+       .get_eeprom_antenna_cfg = ath9k_hw_4k_get_eeprom_antenna_cfg,
+       .set_board_values       = ath9k_hw_4k_set_board_values,
+       .set_addac              = ath9k_hw_4k_set_addac,
+       .set_txpower            = ath9k_hw_4k_set_txpower,
+       .get_spur_channel       = ath9k_hw_4k_get_spur_channel
+};
+
+/************************************************/
+/* EEPROM Operations for non-4K (Default) cards */
+/************************************************/
+
+static int ath9k_hw_def_get_eeprom_ver(struct ath_hw *ah)
+{
+       return ((ah->eeprom.def.baseEepHeader.version >> 12) & 0xF);
+}
+
+static int ath9k_hw_def_get_eeprom_rev(struct ath_hw *ah)
+{
+       return ((ah->eeprom.def.baseEepHeader.version) & 0xFFF);
+}
+
+static bool ath9k_hw_def_fill_eeprom(struct ath_hw *ah)
+{
+#define SIZE_EEPROM_DEF (sizeof(struct ar5416_eeprom_def) / sizeof(u16))
+       u16 *eep_data = (u16 *)&ah->eeprom.def;
+       int addr, ar5416_eep_start_loc = 0x100;
+
+       for (addr = 0; addr < SIZE_EEPROM_DEF; addr++) {
+               if (!ath9k_hw_nvram_read(ah, addr + ar5416_eep_start_loc,
+                                        eep_data)) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+                               "Unable to read eeprom region\n");
+                       return false;
+               }
+               eep_data++;
+       }
+       return true;
+#undef SIZE_EEPROM_DEF
+}
+
+static int ath9k_hw_def_check_eeprom(struct ath_hw *ah)
+{
+       struct ar5416_eeprom_def *eep =
+               (struct ar5416_eeprom_def *) &ah->eeprom.def;
+       u16 *eepdata, temp, magic, magic2;
+       u32 sum = 0, el;
+       bool need_swap = false;
+       int i, addr, size;
+
+       if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET, &magic)) {
+               DPRINTF(ah->ah_sc, ATH_DBG_FATAL, "Reading Magic # failed\n");
+               return false;
+       }
+
+       if (!ath9k_hw_use_flash(ah)) {
+               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+                       "Read Magic = 0x%04X\n", magic);
+
+               if (magic != AR5416_EEPROM_MAGIC) {
+                       magic2 = swab16(magic);
+
+                       if (magic2 == AR5416_EEPROM_MAGIC) {
+                               size = sizeof(struct ar5416_eeprom_def);
+                               need_swap = true;
+                               eepdata = (u16 *) (&ah->eeprom);
+
+                               for (addr = 0; addr < size / sizeof(u16); addr++) {
+                                       temp = swab16(*eepdata);
+                                       *eepdata = temp;
+                                       eepdata++;
+                               }
+                       } else {
+                               DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+                                       "Invalid EEPROM Magic. "
+                                       "Endianness mismatch.\n");
+                               return -EINVAL;
+                       }
+               }
+       }
+
+       DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "need_swap = %s.\n",
+               need_swap ? "True" : "False");
+
+       if (need_swap)
+               el = swab16(ah->eeprom.def.baseEepHeader.length);
+       else
+               el = ah->eeprom.def.baseEepHeader.length;
+
+       if (el > sizeof(struct ar5416_eeprom_def))
+               el = sizeof(struct ar5416_eeprom_def) / sizeof(u16);
+       else
+               el = el / sizeof(u16);
+
+       eepdata = (u16 *)(&ah->eeprom);
+
+       for (i = 0; i < el; i++)
+               sum ^= *eepdata++;
+
+       if (need_swap) {
+               u32 integer, j;
+               u16 word;
+
+               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+                       "EEPROM Endianness is not native.. Changing.\n");
+
+               word = swab16(eep->baseEepHeader.length);
+               eep->baseEepHeader.length = word;
+
+               word = swab16(eep->baseEepHeader.checksum);
+               eep->baseEepHeader.checksum = word;
+
+               word = swab16(eep->baseEepHeader.version);
+               eep->baseEepHeader.version = word;
+
+               word = swab16(eep->baseEepHeader.regDmn[0]);
+               eep->baseEepHeader.regDmn[0] = word;
+
+               word = swab16(eep->baseEepHeader.regDmn[1]);
+               eep->baseEepHeader.regDmn[1] = word;
+
+               word = swab16(eep->baseEepHeader.rfSilent);
+               eep->baseEepHeader.rfSilent = word;
+
+               word = swab16(eep->baseEepHeader.blueToothOptions);
+               eep->baseEepHeader.blueToothOptions = word;
+
+               word = swab16(eep->baseEepHeader.deviceCap);
+               eep->baseEepHeader.deviceCap = word;
+
+               for (j = 0; j < ARRAY_SIZE(eep->modalHeader); j++) {
+                       struct modal_eep_header *pModal =
+                               &eep->modalHeader[j];
+                       integer = swab32(pModal->antCtrlCommon);
+                       pModal->antCtrlCommon = integer;
+
+                       for (i = 0; i < AR5416_MAX_CHAINS; i++) {
+                               integer = swab32(pModal->antCtrlChain[i]);
+                               pModal->antCtrlChain[i] = integer;
+                       }
+
+                       for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) {
+                               word = swab16(pModal->spurChans[i].spurChan);
+                               pModal->spurChans[i].spurChan = word;
+                       }
+               }
+       }
+
+       if (sum != 0xffff || ah->eep_ops->get_eeprom_ver(ah) != AR5416_EEP_VER ||
+           ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_NO_BACK_VER) {
+               DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+                       "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
+                       sum, ah->eep_ops->get_eeprom_ver(ah));
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static u32 ath9k_hw_def_get_eeprom(struct ath_hw *ah,
+                                  enum eeprom_param param)
+{
+       struct ar5416_eeprom_def *eep = &ah->eeprom.def;
+       struct modal_eep_header *pModal = eep->modalHeader;
+       struct base_eep_header *pBase = &eep->baseEepHeader;
+
+       switch (param) {
+       case EEP_NFTHRESH_5:
+               return pModal[0].noiseFloorThreshCh[0];
+       case EEP_NFTHRESH_2:
+               return pModal[1].noiseFloorThreshCh[0];
+       case AR_EEPROM_MAC(0):
+               return pBase->macAddr[0] << 8 | pBase->macAddr[1];
+       case AR_EEPROM_MAC(1):
+               return pBase->macAddr[2] << 8 | pBase->macAddr[3];
+       case AR_EEPROM_MAC(2):
+               return pBase->macAddr[4] << 8 | pBase->macAddr[5];
+       case EEP_REG_0:
+               return pBase->regDmn[0];
+       case EEP_REG_1:
+               return pBase->regDmn[1];
+       case EEP_OP_CAP:
+               return pBase->deviceCap;
+       case EEP_OP_MODE:
+               return pBase->opCapFlags;
+       case EEP_RF_SILENT:
+               return pBase->rfSilent;
+       case EEP_OB_5:
+               return pModal[0].ob;
+       case EEP_DB_5:
+               return pModal[0].db;
+       case EEP_OB_2:
+               return pModal[1].ob;
+       case EEP_DB_2:
+               return pModal[1].db;
+       case EEP_MINOR_REV:
+               return AR5416_VER_MASK;
+       case EEP_TX_MASK:
+               return pBase->txMask;
+       case EEP_RX_MASK:
+               return pBase->rxMask;
+       case EEP_RXGAIN_TYPE:
+               return pBase->rxGainType;
+       case EEP_TXGAIN_TYPE:
+               return pBase->txGainType;
+       case EEP_OL_PWRCTRL:
+               if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19)
+                       return pBase->openLoopPwrCntl ? true : false;
+               else
+                       return false;
+       case EEP_RC_CHAIN_MASK:
+               if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19)
+                       return pBase->rcChainMask;
+               else
+                       return 0;
+       case EEP_DAC_HPWR_5G:
+               if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_20)
+                       return pBase->dacHiPwrMode_5G;
+               else
+                       return 0;
+       case EEP_FRAC_N_5G:
+               if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_22)
+                       return pBase->frac_n_5g;
+               else
+                       return 0;
+       default:
+               return 0;
+       }
+}
+
+static void ath9k_hw_def_set_gain(struct ath_hw *ah,
+                                 struct modal_eep_header *pModal,
+                                 struct ar5416_eeprom_def *eep,
+                                 u8 txRxAttenLocal, int regChainOffset, int i)
+{
+       if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_3) {
+               txRxAttenLocal = pModal->txRxAttenCh[i];
+
+               if (AR_SREV_9280_10_OR_LATER(ah)) {
+                       REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+                             AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN,
+                             pModal->bswMargin[i]);
+                       REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+                             AR_PHY_GAIN_2GHZ_XATTEN1_DB,
+                             pModal->bswAtten[i]);
+                       REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+                             AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN,
+                             pModal->xatten2Margin[i]);
+                       REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+                             AR_PHY_GAIN_2GHZ_XATTEN2_DB,
+                             pModal->xatten2Db[i]);
+               } else {
+                       REG_WRITE(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+                         (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) &
+                          ~AR_PHY_GAIN_2GHZ_BSW_MARGIN)
+                         | SM(pModal-> bswMargin[i],
+                              AR_PHY_GAIN_2GHZ_BSW_MARGIN));
+                       REG_WRITE(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
+                         (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) &
+                          ~AR_PHY_GAIN_2GHZ_BSW_ATTEN)
+                         | SM(pModal->bswAtten[i],
+                              AR_PHY_GAIN_2GHZ_BSW_ATTEN));
+               }
+       }
+
+       if (AR_SREV_9280_10_OR_LATER(ah)) {
+               REG_RMW_FIELD(ah,
+                     AR_PHY_RXGAIN + regChainOffset,
+                     AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal);
+               REG_RMW_FIELD(ah,
+                     AR_PHY_RXGAIN + regChainOffset,
+                     AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[i]);
+       } else {
+               REG_WRITE(ah,
+                         AR_PHY_RXGAIN + regChainOffset,
+                         (REG_READ(ah, AR_PHY_RXGAIN + regChainOffset) &
+                          ~AR_PHY_RXGAIN_TXRX_ATTEN)
+                         | SM(txRxAttenLocal, AR_PHY_RXGAIN_TXRX_ATTEN));
+               REG_WRITE(ah,
+                         AR_PHY_GAIN_2GHZ + regChainOffset,
+                         (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) &
+                          ~AR_PHY_GAIN_2GHZ_RXTX_MARGIN) |
+                         SM(pModal->rxTxMarginCh[i], AR_PHY_GAIN_2GHZ_RXTX_MARGIN));
+       }
+}
+
+static void ath9k_hw_def_set_board_values(struct ath_hw *ah,
+                                         struct ath9k_channel *chan)
+{
+       struct modal_eep_header *pModal;
+       struct ar5416_eeprom_def *eep = &ah->eeprom.def;
+       int i, regChainOffset;
+       u8 txRxAttenLocal;
+
+       pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
+       txRxAttenLocal = IS_CHAN_2GHZ(chan) ? 23 : 44;
+
+       REG_WRITE(ah, AR_PHY_SWITCH_COM,
+                 ah->eep_ops->get_eeprom_antenna_cfg(ah, chan));
+
+       for (i = 0; i < AR5416_MAX_CHAINS; i++) {
+               if (AR_SREV_9280(ah)) {
+                       if (i >= 2)
+                               break;
+               }
+
+               if (AR_SREV_5416_20_OR_LATER(ah) &&
+                   (ah->rxchainmask == 5 || ah->txchainmask == 5) && (i != 0))
+                       regChainOffset = (i == 1) ? 0x2000 : 0x1000;
+               else
+                       regChainOffset = i * 0x1000;
+
+               REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset,
+                         pModal->antCtrlChain[i]);
+
+               REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset,
+                         (REG_READ(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset) &
+                          ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |
+                            AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
+                         SM(pModal->iqCalICh[i],
+                            AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
+                         SM(pModal->iqCalQCh[i],
+                            AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
+
+               if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah))
+                       ath9k_hw_def_set_gain(ah, pModal, eep, txRxAttenLocal,
+                                             regChainOffset, i);
+       }
+
+       if (AR_SREV_9280_10_OR_LATER(ah)) {
+               if (IS_CHAN_2GHZ(chan)) {
+                       ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH0,
+                                                 AR_AN_RF2G1_CH0_OB,
+                                                 AR_AN_RF2G1_CH0_OB_S,
+                                                 pModal->ob);
+                       ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH0,
+                                                 AR_AN_RF2G1_CH0_DB,
+                                                 AR_AN_RF2G1_CH0_DB_S,
+                                                 pModal->db);
+                       ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH1,
+                                                 AR_AN_RF2G1_CH1_OB,
+                                                 AR_AN_RF2G1_CH1_OB_S,
+                                                 pModal->ob_ch1);
+                       ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH1,
+                                                 AR_AN_RF2G1_CH1_DB,
+                                                 AR_AN_RF2G1_CH1_DB_S,
+                                                 pModal->db_ch1);
+               } else {
+                       ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH0,
+                                                 AR_AN_RF5G1_CH0_OB5,
+                                                 AR_AN_RF5G1_CH0_OB5_S,
+                                                 pModal->ob);
+                       ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH0,
+                                                 AR_AN_RF5G1_CH0_DB5,
+                                                 AR_AN_RF5G1_CH0_DB5_S,
+                                                 pModal->db);
+                       ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH1,
+                                                 AR_AN_RF5G1_CH1_OB5,
+                                                 AR_AN_RF5G1_CH1_OB5_S,
+                                                 pModal->ob_ch1);
+                       ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH1,
+                                                 AR_AN_RF5G1_CH1_DB5,
+                                                 AR_AN_RF5G1_CH1_DB5_S,
+                                                 pModal->db_ch1);
+               }
+               ath9k_hw_analog_shift_rmw(ah, AR_AN_TOP2,
+                                         AR_AN_TOP2_XPABIAS_LVL,
+                                         AR_AN_TOP2_XPABIAS_LVL_S,
+                                         pModal->xpaBiasLvl);
+               ath9k_hw_analog_shift_rmw(ah, AR_AN_TOP2,
+                                         AR_AN_TOP2_LOCALBIAS,
+                                         AR_AN_TOP2_LOCALBIAS_S,
+                                         pModal->local_bias);
+               REG_RMW_FIELD(ah, AR_PHY_XPA_CFG, AR_PHY_FORCE_XPA_CFG,
+                             pModal->force_xpaon);
+       }
+
+       REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH,
+                     pModal->switchSettling);
+       REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC,
+                     pModal->adcDesiredSize);
+
+       if (!AR_SREV_9280_10_OR_LATER(ah))
+               REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
+                             AR_PHY_DESIRED_SZ_PGA,
+                             pModal->pgaDesiredSize);
+
+       REG_WRITE(ah, AR_PHY_RF_CTL4,
+                 SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF)
+                 | SM(pModal->txEndToXpaOff,
+                      AR_PHY_RF_CTL4_TX_END_XPAB_OFF)
+                 | SM(pModal->txFrameToXpaOn,
+                      AR_PHY_RF_CTL4_FRAME_XPAA_ON)
+                 | SM(pModal->txFrameToXpaOn,
+                      AR_PHY_RF_CTL4_FRAME_XPAB_ON));
+
+       REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON,
+                     pModal->txEndToRxOn);
+
+       if (AR_SREV_9280_10_OR_LATER(ah)) {
+               REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62,
+                             pModal->thresh62);
+               REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0,
+                             AR_PHY_EXT_CCA0_THRESH62,
+                             pModal->thresh62);
+       } else {
+               REG_RMW_FIELD(ah, AR_PHY_CCA, AR_PHY_CCA_THRESH62,
+                             pModal->thresh62);
+               REG_RMW_FIELD(ah, AR_PHY_EXT_CCA,
+                             AR_PHY_EXT_CCA_THRESH62,
+                             pModal->thresh62);
+       }
+
+       if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_2) {
+               REG_RMW_FIELD(ah, AR_PHY_RF_CTL2,
+                             AR_PHY_TX_END_DATA_START,
+                             pModal->txFrameToDataStart);
+               REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_PA_ON,
+                             pModal->txFrameToPaOn);
+       }
+
+       if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_3) {
+               if (IS_CHAN_HT40(chan))
+                       REG_RMW_FIELD(ah, AR_PHY_SETTLING,
+                                     AR_PHY_SETTLING_SWITCH,
+                                     pModal->swSettleHt40);
+       }
+
+       if (AR_SREV_9280_20_OR_LATER(ah) &&
+           AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19)
+               REG_RMW_FIELD(ah, AR_PHY_CCK_TX_CTRL,
+                             AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK,
+                             pModal->miscBits);
+
+
+       if (AR_SREV_9280_20(ah) && AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_20) {
+               if (IS_CHAN_2GHZ(chan))
+                       REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE,
+                                       eep->baseEepHeader.dacLpMode);
+               else if (eep->baseEepHeader.dacHiPwrMode_5G)
+                       REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE, 0);
+               else
+                       REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE,
+                                     eep->baseEepHeader.dacLpMode);
+
+               REG_RMW_FIELD(ah, AR_PHY_FRAME_CTL, AR_PHY_FRAME_CTL_TX_CLIP,
+                             pModal->miscBits >> 2);
+
+               REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL9,
+                             AR_PHY_TX_DESIRED_SCALE_CCK,
+                             eep->baseEepHeader.desiredScaleCCK);
+       }
+}
+
+static void ath9k_hw_def_set_addac(struct ath_hw *ah,
+                                  struct ath9k_channel *chan)
+{
+#define XPA_LVL_FREQ(cnt) (pModal->xpaBiasLvlFreq[cnt])
+       struct modal_eep_header *pModal;
+       struct ar5416_eeprom_def *eep = &ah->eeprom.def;
+       u8 biaslevel;
+
+       if (ah->hw_version.macVersion != AR_SREV_VERSION_9160)
+               return;
+
+       if (ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_MINOR_VER_7)
+               return;
+
+       pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
+
+       if (pModal->xpaBiasLvl != 0xff) {
+               biaslevel = pModal->xpaBiasLvl;
+       } else {
+               u16 resetFreqBin, freqBin, freqCount = 0;
+               struct chan_centers centers;
+
+               ath9k_hw_get_channel_centers(ah, chan, &centers);
+
+               resetFreqBin = FREQ2FBIN(centers.synth_center,
+                                        IS_CHAN_2GHZ(chan));
+               freqBin = XPA_LVL_FREQ(0) & 0xff;
+               biaslevel = (u8) (XPA_LVL_FREQ(0) >> 14);
+
+               freqCount++;
+
+               while (freqCount < 3) {
+                       if (XPA_LVL_FREQ(freqCount) == 0x0)
+                               break;
+
+                       freqBin = XPA_LVL_FREQ(freqCount) & 0xff;
+                       if (resetFreqBin >= freqBin)
+                               biaslevel = (u8)(XPA_LVL_FREQ(freqCount) >> 14);
+                       else
+                               break;
+                       freqCount++;
+               }
+       }
+
+       if (IS_CHAN_2GHZ(chan)) {
+               INI_RA(&ah->iniAddac, 7, 1) = (INI_RA(&ah->iniAddac,
+                                       7, 1) & (~0x18)) | biaslevel << 3;
+       } else {
+               INI_RA(&ah->iniAddac, 6, 1) = (INI_RA(&ah->iniAddac,
+                                       6, 1) & (~0xc0)) | biaslevel << 6;
+       }
+#undef XPA_LVL_FREQ
+}
+
+static void ath9k_hw_get_def_gain_boundaries_pdadcs(struct ath_hw *ah,
+                               struct ath9k_channel *chan,
+                               struct cal_data_per_freq *pRawDataSet,
+                               u8 *bChans, u16 availPiers,
+                               u16 tPdGainOverlap, int16_t *pMinCalPower,
+                               u16 *pPdGainBoundaries, u8 *pPDADCValues,
+                               u16 numXpdGains)
+{
+       int i, j, k;
+       int16_t ss;
+       u16 idxL = 0, idxR = 0, numPiers;
+       static u8 vpdTableL[AR5416_NUM_PD_GAINS]
+               [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
+       static u8 vpdTableR[AR5416_NUM_PD_GAINS]
+               [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
+       static u8 vpdTableI[AR5416_NUM_PD_GAINS]
+               [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
+
+       u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR;
+       u8 minPwrT4[AR5416_NUM_PD_GAINS];
+       u8 maxPwrT4[AR5416_NUM_PD_GAINS];
+       int16_t vpdStep;
+       int16_t tmpVal;
+       u16 sizeCurrVpdTable, maxIndex, tgtIndex;
+       bool match;
+       int16_t minDelta = 0;
+       struct chan_centers centers;
+
+       ath9k_hw_get_channel_centers(ah, chan, &centers);
+
+       for (numPiers = 0; numPiers < availPiers; numPiers++) {
+               if (bChans[numPiers] == AR5416_BCHAN_UNUSED)
+                       break;
+       }
+
+       match = ath9k_hw_get_lower_upper_index((u8)FREQ2FBIN(centers.synth_center,
+                                                            IS_CHAN_2GHZ(chan)),
+                                              bChans, numPiers, &idxL, &idxR);
+
+       if (match) {
+               for (i = 0; i < numXpdGains; i++) {
+                       minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0];
+                       maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4];
+                       ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
+                                       pRawDataSet[idxL].pwrPdg[i],
+                                       pRawDataSet[idxL].vpdPdg[i],
+                                       AR5416_PD_GAIN_ICEPTS,
+                                       vpdTableI[i]);
+               }
+       } else {
+               for (i = 0; i < numXpdGains; i++) {
+                       pVpdL = pRawDataSet[idxL].vpdPdg[i];
+                       pPwrL = pRawDataSet[idxL].pwrPdg[i];
+                       pVpdR = pRawDataSet[idxR].vpdPdg[i];
+                       pPwrR = pRawDataSet[idxR].pwrPdg[i];
+
+                       minPwrT4[i] = max(pPwrL[0], pPwrR[0]);
+
+                       maxPwrT4[i] =
+                               min(pPwrL[AR5416_PD_GAIN_ICEPTS - 1],
+                                   pPwrR[AR5416_PD_GAIN_ICEPTS - 1]);
+
+
+                       ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
+                                               pPwrL, pVpdL,
+                                               AR5416_PD_GAIN_ICEPTS,
+                                               vpdTableL[i]);
+                       ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
+                                               pPwrR, pVpdR,
+                                               AR5416_PD_GAIN_ICEPTS,
+                                               vpdTableR[i]);
+
+                       for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
+                               vpdTableI[i][j] =
+                                       (u8)(ath9k_hw_interpolate((u16)
+                                            FREQ2FBIN(centers.
+                                                      synth_center,
+                                                      IS_CHAN_2GHZ
+                                                      (chan)),
+                                            bChans[idxL], bChans[idxR],
+                                            vpdTableL[i][j], vpdTableR[i][j]));
+                       }
+               }
+       }
+
+       *pMinCalPower = (int16_t)(minPwrT4[0] / 2);
+
+       k = 0;
+
+       for (i = 0; i < numXpdGains; i++) {
+               if (i == (numXpdGains - 1))
+                       pPdGainBoundaries[i] =
+                               (u16)(maxPwrT4[i] / 2);
+               else
+                       pPdGainBoundaries[i] =
+                               (u16)((maxPwrT4[i] + minPwrT4[i + 1]) / 4);
+
+               pPdGainBoundaries[i] =
+                       min((u16)AR5416_MAX_RATE_POWER, pPdGainBoundaries[i]);
+
+               if ((i == 0) && !AR_SREV_5416_20_OR_LATER(ah)) {
+                       minDelta = pPdGainBoundaries[0] - 23;
+                       pPdGainBoundaries[0] = 23;
+               } else {
+                       minDelta = 0;
+               }
+
+               if (i == 0) {
+                       if (AR_SREV_9280_10_OR_LATER(ah))
+                               ss = (int16_t)(0 - (minPwrT4[i] / 2));
+                       else
+                               ss = 0;
+               } else {
+                       ss = (int16_t)((pPdGainBoundaries[i - 1] -
+                                       (minPwrT4[i] / 2)) -
+                                      tPdGainOverlap + 1 + minDelta);
+               }
+               vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]);
+               vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
+
+               while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
+                       tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep);
+                       pPDADCValues[k++] = (u8)((tmpVal < 0) ? 0 : tmpVal);
+                       ss++;
+               }
+
+               sizeCurrVpdTable = (u8) ((maxPwrT4[i] - minPwrT4[i]) / 2 + 1);
+               tgtIndex = (u8)(pPdGainBoundaries[i] + tPdGainOverlap -
+                               (minPwrT4[i] / 2));
+               maxIndex = (tgtIndex < sizeCurrVpdTable) ?
+                       tgtIndex : sizeCurrVpdTable;
+
+               while ((ss < maxIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
+                       pPDADCValues[k++] = vpdTableI[i][ss++];
+               }
+
+               vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] -
+                                   vpdTableI[i][sizeCurrVpdTable - 2]);
+               vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
+
+               if (tgtIndex > maxIndex) {
+                       while ((ss <= tgtIndex) &&
+                              (k < (AR5416_NUM_PDADC_VALUES - 1))) {
+                               tmpVal = (int16_t)((vpdTableI[i][sizeCurrVpdTable - 1] +
+                                                   (ss - maxIndex + 1) * vpdStep));
+                               pPDADCValues[k++] = (u8)((tmpVal > 255) ?
+                                                        255 : tmpVal);
+                               ss++;
+                       }
+               }
+       }
+
+       while (i < AR5416_PD_GAINS_IN_MASK) {
+               pPdGainBoundaries[i] = pPdGainBoundaries[i - 1];
+               i++;
+       }
+
+       while (k < AR5416_NUM_PDADC_VALUES) {
+               pPDADCValues[k] = pPDADCValues[k - 1];
+               k++;
+       }
+
+       return;
+}
+
+static void ath9k_hw_set_def_power_cal_table(struct ath_hw *ah,
+                                 struct ath9k_channel *chan,
+                                 int16_t *pTxPowerIndexOffset)
+{
+#define SM_PD_GAIN(x) SM(0x38, AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_##x)
+#define SM_PDGAIN_B(x, y) \
+               SM((gainBoundaries[x]), AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_##y)
+
+       struct ar5416_eeprom_def *pEepData = &ah->eeprom.def;
+       struct cal_data_per_freq *pRawDataset;
+       u8 *pCalBChans = NULL;
+       u16 pdGainOverlap_t2;
+       static u8 pdadcValues[AR5416_NUM_PDADC_VALUES];
+       u16 gainBoundaries[AR5416_PD_GAINS_IN_MASK];
+       u16 numPiers, i, j;
+       int16_t tMinCalPower;
+       u16 numXpdGain, xpdMask;
+       u16 xpdGainValues[AR5416_NUM_PD_GAINS] = { 0, 0, 0, 0 };
+       u32 reg32, regOffset, regChainOffset;
+       int16_t modalIdx;
+
+       modalIdx = IS_CHAN_2GHZ(chan) ? 1 : 0;
+       xpdMask = pEepData->modalHeader[modalIdx].xpdGain;
+
+       if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
+           AR5416_EEP_MINOR_VER_2) {
+               pdGainOverlap_t2 =
+                       pEepData->modalHeader[modalIdx].pdGainOverlap;
+       } else {
+               pdGainOverlap_t2 = (u16)(MS(REG_READ(ah, AR_PHY_TPCRG5),
+                                           AR_PHY_TPCRG5_PD_GAIN_OVERLAP));
+       }
+
+       if (IS_CHAN_2GHZ(chan)) {
+               pCalBChans = pEepData->calFreqPier2G;
+               numPiers = AR5416_NUM_2G_CAL_PIERS;
+       } else {
+               pCalBChans = pEepData->calFreqPier5G;
+               numPiers = AR5416_NUM_5G_CAL_PIERS;
+       }
+
+       if (OLC_FOR_AR9280_20_LATER && IS_CHAN_2GHZ(chan)) {
+               pRawDataset = pEepData->calPierData2G[0];
+               ah->initPDADC = ((struct calDataPerFreqOpLoop *)
+                                pRawDataset)->vpdPdg[0][0];
+       }
+
+       numXpdGain = 0;
+
+       for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) {
+               if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) {
+                       if (numXpdGain >= AR5416_NUM_PD_GAINS)
+                               break;
+                       xpdGainValues[numXpdGain] =
+                               (u16)(AR5416_PD_GAINS_IN_MASK - i);
+                       numXpdGain++;
+               }
+       }
+
+       REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN,
+                     (numXpdGain - 1) & 0x3);
+       REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1,
+                     xpdGainValues[0]);
+       REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2,
+                     xpdGainValues[1]);
+       REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3,
+                     xpdGainValues[2]);
+
+       for (i = 0; i < AR5416_MAX_CHAINS; i++) {
+               if (AR_SREV_5416_20_OR_LATER(ah) &&
+                   (ah->rxchainmask == 5 || ah->txchainmask == 5) &&
+                   (i != 0)) {
+                       regChainOffset = (i == 1) ? 0x2000 : 0x1000;
+               } else
+                       regChainOffset = i * 0x1000;
+
+               if (pEepData->baseEepHeader.txMask & (1 << i)) {
+                       if (IS_CHAN_2GHZ(chan))
+                               pRawDataset = pEepData->calPierData2G[i];
+                       else
+                               pRawDataset = pEepData->calPierData5G[i];
+
+
+                       if (OLC_FOR_AR9280_20_LATER) {
+                               u8 pcdacIdx;
+                               u8 txPower;
+
+                               ath9k_get_txgain_index(ah, chan,
+                               (struct calDataPerFreqOpLoop *)pRawDataset,
+                               pCalBChans, numPiers, &txPower, &pcdacIdx);
+                               ath9k_olc_get_pdadcs(ah, pcdacIdx,
+                                                    txPower/2, pdadcValues);
+                       } else {
+                               ath9k_hw_get_def_gain_boundaries_pdadcs(ah,
+                                                       chan, pRawDataset,
+                                                       pCalBChans, numPiers,
+                                                       pdGainOverlap_t2,
+                                                       &tMinCalPower,
+                                                       gainBoundaries,
+                                                       pdadcValues,
+                                                       numXpdGain);
+                       }
+
+                       if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah)) {
+                               if (OLC_FOR_AR9280_20_LATER) {
+                                       REG_WRITE(ah,
+                                               AR_PHY_TPCRG5 + regChainOffset,
+                                               SM(0x6,
+                                               AR_PHY_TPCRG5_PD_GAIN_OVERLAP) |
+                                               SM_PD_GAIN(1) | SM_PD_GAIN(2) |
+                                               SM_PD_GAIN(3) | SM_PD_GAIN(4));
+                               } else {
+                                       REG_WRITE(ah,
+                                               AR_PHY_TPCRG5 + regChainOffset,
+                                               SM(pdGainOverlap_t2,
+                                               AR_PHY_TPCRG5_PD_GAIN_OVERLAP)|
+                                               SM_PDGAIN_B(0, 1) |
+                                               SM_PDGAIN_B(1, 2) |
+                                               SM_PDGAIN_B(2, 3) |
+                                               SM_PDGAIN_B(3, 4));
+                               }
+                       }
+
+                       regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset;
+                       for (j = 0; j < 32; j++) {
+                               reg32 = ((pdadcValues[4 * j + 0] & 0xFF) << 0) |
+                                       ((pdadcValues[4 * j + 1] & 0xFF) << 8) |
+                                       ((pdadcValues[4 * j + 2] & 0xFF) << 16)|
+                                       ((pdadcValues[4 * j + 3] & 0xFF) << 24);
+                               REG_WRITE(ah, regOffset, reg32);
+
+                               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+                                       "PDADC (%d,%4x): %4.4x %8.8x\n",
+                                       i, regChainOffset, regOffset,
+                                       reg32);
+                               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+                                       "PDADC: Chain %d | PDADC %3d "
+                                       "Value %3d | PDADC %3d Value %3d | "
+                                       "PDADC %3d Value %3d | PDADC %3d "
+                                       "Value %3d |\n",
+                                       i, 4 * j, pdadcValues[4 * j],
+                                       4 * j + 1, pdadcValues[4 * j + 1],
+                                       4 * j + 2, pdadcValues[4 * j + 2],
+                                       4 * j + 3,
+                                       pdadcValues[4 * j + 3]);
+
+                               regOffset += 4;
+                       }
+               }
+       }
+
+       *pTxPowerIndexOffset = 0;
+#undef SM_PD_GAIN
+#undef SM_PDGAIN_B
+}
+
+static void ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah,
+                                                 struct ath9k_channel *chan,
+                                                 int16_t *ratesArray,
+                                                 u16 cfgCtl,
+                                                 u16 AntennaReduction,
+                                                 u16 twiceMaxRegulatoryPower,
+                                                 u16 powerLimit)
+{
+#define REDUCE_SCALED_POWER_BY_TWO_CHAIN     6  /* 10*log10(2)*2 */
+#define REDUCE_SCALED_POWER_BY_THREE_CHAIN   10 /* 10*log10(3)*2 */
+
+       struct ar5416_eeprom_def *pEepData = &ah->eeprom.def;
+       u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
+       static const u16 tpScaleReductionTable[5] =
+               { 0, 3, 6, 9, AR5416_MAX_RATE_POWER };
+
+       int i;
+       int16_t twiceLargestAntenna;
+       struct cal_ctl_data *rep;
+       struct cal_target_power_leg targetPowerOfdm, targetPowerCck = {
+               0, { 0, 0, 0, 0}
+       };
+       struct cal_target_power_leg targetPowerOfdmExt = {
+               0, { 0, 0, 0, 0} }, targetPowerCckExt = {
+               0, { 0, 0, 0, 0 }
+       };
+       struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = {
+               0, {0, 0, 0, 0}
+       };
+       u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
+       u16 ctlModesFor11a[] =
+               { CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40 };
+       u16 ctlModesFor11g[] =
+               { CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT,
+                 CTL_2GHT40
+               };
+       u16 numCtlModes, *pCtlMode, ctlMode, freq;
+       struct chan_centers centers;
+       int tx_chainmask;
+       u16 twiceMinEdgePower;
+
+       tx_chainmask = ah->txchainmask;
+
+       ath9k_hw_get_channel_centers(ah, chan, &centers);
+
+       twiceLargestAntenna = max(
+               pEepData->modalHeader
+                       [IS_CHAN_2GHZ(chan)].antennaGainCh[0],
+               pEepData->modalHeader
+                       [IS_CHAN_2GHZ(chan)].antennaGainCh[1]);
+
+       twiceLargestAntenna = max((u8)twiceLargestAntenna,
+                                 pEepData->modalHeader
+                                 [IS_CHAN_2GHZ(chan)].antennaGainCh[2]);
+
+       twiceLargestAntenna = (int16_t)min(AntennaReduction -
+                                          twiceLargestAntenna, 0);
+
+       maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
+
+       if (ah->regulatory.tp_scale != ATH9K_TP_SCALE_MAX) {
+               maxRegAllowedPower -=
+                       (tpScaleReductionTable[(ah->regulatory.tp_scale)] * 2);
+       }
+
+       scaledPower = min(powerLimit, maxRegAllowedPower);
+
+       switch (ar5416_get_ntxchains(tx_chainmask)) {
+       case 1:
+               break;
+       case 2:
+               scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN;
+               break;
+       case 3:
+               scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN;
+               break;
+       }
+
+       scaledPower = max((u16)0, scaledPower);
+
+       if (IS_CHAN_2GHZ(chan)) {
+               numCtlModes = ARRAY_SIZE(ctlModesFor11g) -
+                       SUB_NUM_CTL_MODES_AT_2G_40;
+               pCtlMode = ctlModesFor11g;
+
+               ath9k_hw_get_legacy_target_powers(ah, chan,
+                       pEepData->calTargetPowerCck,
+                       AR5416_NUM_2G_CCK_TARGET_POWERS,
+                       &targetPowerCck, 4, false);
+               ath9k_hw_get_legacy_target_powers(ah, chan,
+                       pEepData->calTargetPower2G,
+                       AR5416_NUM_2G_20_TARGET_POWERS,
+                       &targetPowerOfdm, 4, false);
+               ath9k_hw_get_target_powers(ah, chan,
+                       pEepData->calTargetPower2GHT20,
+                       AR5416_NUM_2G_20_TARGET_POWERS,
+                       &targetPowerHt20, 8, false);
+
+               if (IS_CHAN_HT40(chan)) {
+                       numCtlModes = ARRAY_SIZE(ctlModesFor11g);
+                       ath9k_hw_get_target_powers(ah, chan,
+                               pEepData->calTargetPower2GHT40,
+                               AR5416_NUM_2G_40_TARGET_POWERS,
+                               &targetPowerHt40, 8, true);
+                       ath9k_hw_get_legacy_target_powers(ah, chan,
+                               pEepData->calTargetPowerCck,
+                               AR5416_NUM_2G_CCK_TARGET_POWERS,
+                               &targetPowerCckExt, 4, true);
+                       ath9k_hw_get_legacy_target_powers(ah, chan,
+                               pEepData->calTargetPower2G,
+                               AR5416_NUM_2G_20_TARGET_POWERS,
+                               &targetPowerOfdmExt, 4, true);
+               }
+       } else {
+               numCtlModes = ARRAY_SIZE(ctlModesFor11a) -
+                       SUB_NUM_CTL_MODES_AT_5G_40;
+               pCtlMode = ctlModesFor11a;
+
+               ath9k_hw_get_legacy_target_powers(ah, chan,
+                       pEepData->calTargetPower5G,
+                       AR5416_NUM_5G_20_TARGET_POWERS,
+                       &targetPowerOfdm, 4, false);
+               ath9k_hw_get_target_powers(ah, chan,
+                       pEepData->calTargetPower5GHT20,
+                       AR5416_NUM_5G_20_TARGET_POWERS,
+                       &targetPowerHt20, 8, false);
+
+               if (IS_CHAN_HT40(chan)) {
+                       numCtlModes = ARRAY_SIZE(ctlModesFor11a);
+                       ath9k_hw_get_target_powers(ah, chan,
+                               pEepData->calTargetPower5GHT40,
+                               AR5416_NUM_5G_40_TARGET_POWERS,
+                               &targetPowerHt40, 8, true);
+                       ath9k_hw_get_legacy_target_powers(ah, chan,
+                               pEepData->calTargetPower5G,
+                               AR5416_NUM_5G_20_TARGET_POWERS,
+                               &targetPowerOfdmExt, 4, true);
+               }
+       }
+
+       for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
+               bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) ||
+                       (pCtlMode[ctlMode] == CTL_2GHT40);
+               if (isHt40CtlMode)
+                       freq = centers.synth_center;
+               else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
+                       freq = centers.ext_center;
+               else
+                       freq = centers.ctl_center;
+
+               if (ah->eep_ops->get_eeprom_ver(ah) == 14 &&
+                   ah->eep_ops->get_eeprom_rev(ah) <= 2)
+                       twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
+
+               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+                       "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, "
+                       "EXT_ADDITIVE %d\n",
+                       ctlMode, numCtlModes, isHt40CtlMode,
+                       (pCtlMode[ctlMode] & EXT_ADDITIVE));
+
+               for (i = 0; (i < AR5416_NUM_CTLS) && pEepData->ctlIndex[i]; i++) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+                               "  LOOP-Ctlidx %d: cfgCtl 0x%2.2x "
+                               "pCtlMode 0x%2.2x ctlIndex 0x%2.2x "
+                               "chan %d\n",
+                               i, cfgCtl, pCtlMode[ctlMode],
+                               pEepData->ctlIndex[i], chan->channel);
+
+                       if ((((cfgCtl & ~CTL_MODE_M) |
+                             (pCtlMode[ctlMode] & CTL_MODE_M)) ==
+                            pEepData->ctlIndex[i]) ||
+                           (((cfgCtl & ~CTL_MODE_M) |
+                             (pCtlMode[ctlMode] & CTL_MODE_M)) ==
+                            ((pEepData->ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL))) {
+                               rep = &(pEepData->ctlData[i]);
+
+                               twiceMinEdgePower = ath9k_hw_get_max_edge_power(freq,
+                               rep->ctlEdges[ar5416_get_ntxchains(tx_chainmask) - 1],
+                               IS_CHAN_2GHZ(chan), AR5416_NUM_BAND_EDGES);
+
+                               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+                                       "    MATCH-EE_IDX %d: ch %d is2 %d "
+                                       "2xMinEdge %d chainmask %d chains %d\n",
+                                       i, freq, IS_CHAN_2GHZ(chan),
+                                       twiceMinEdgePower, tx_chainmask,
+                                       ar5416_get_ntxchains
+                                       (tx_chainmask));
+                               if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) {
+                                       twiceMaxEdgePower = min(twiceMaxEdgePower,
+                                                               twiceMinEdgePower);
+                               } else {
+                                       twiceMaxEdgePower = twiceMinEdgePower;
+                                       break;
+                               }
+                       }
+               }
+
+               minCtlPower = min(twiceMaxEdgePower, scaledPower);
+
+               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+                       "    SEL-Min ctlMode %d pCtlMode %d "
+                       "2xMaxEdge %d sP %d minCtlPwr %d\n",
+                       ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower,
+                       scaledPower, minCtlPower);
+
+               switch (pCtlMode[ctlMode]) {
+               case CTL_11B:
+                       for (i = 0; i < ARRAY_SIZE(targetPowerCck.tPow2x); i++) {
+                               targetPowerCck.tPow2x[i] =
+                                       min((u16)targetPowerCck.tPow2x[i],
+                                           minCtlPower);
+                       }
+                       break;
+               case CTL_11A:
+               case CTL_11G:
+                       for (i = 0; i < ARRAY_SIZE(targetPowerOfdm.tPow2x); i++) {
+                               targetPowerOfdm.tPow2x[i] =
+                                       min((u16)targetPowerOfdm.tPow2x[i],
+                                           minCtlPower);
+                       }
+                       break;
+               case CTL_5GHT20:
+               case CTL_2GHT20:
+                       for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++) {
+                               targetPowerHt20.tPow2x[i] =
+                                       min((u16)targetPowerHt20.tPow2x[i],
+                                           minCtlPower);
+                       }
+                       break;
+               case CTL_11B_EXT:
+                       targetPowerCckExt.tPow2x[0] = min((u16)
+                                       targetPowerCckExt.tPow2x[0],
+                                       minCtlPower);
+                       break;
+               case CTL_11A_EXT:
+               case CTL_11G_EXT:
+                       targetPowerOfdmExt.tPow2x[0] = min((u16)
+                                       targetPowerOfdmExt.tPow2x[0],
+                                       minCtlPower);
+                       break;
+               case CTL_5GHT40:
+               case CTL_2GHT40:
+                       for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
+                               targetPowerHt40.tPow2x[i] =
+                                       min((u16)targetPowerHt40.tPow2x[i],
+                                           minCtlPower);
+                       }
+                       break;
+               default:
+                       break;
+               }
+       }
+
+       ratesArray[rate6mb] = ratesArray[rate9mb] = ratesArray[rate12mb] =
+               ratesArray[rate18mb] = ratesArray[rate24mb] =
+               targetPowerOfdm.tPow2x[0];
+       ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1];
+       ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2];
+       ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3];
+       ratesArray[rateXr] = targetPowerOfdm.tPow2x[0];
+
+       for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++)
+               ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i];
+
+       if (IS_CHAN_2GHZ(chan)) {
+               ratesArray[rate1l] = targetPowerCck.tPow2x[0];
+               ratesArray[rate2s] = ratesArray[rate2l] =
+                       targetPowerCck.tPow2x[1];
+               ratesArray[rate5_5s] = ratesArray[rate5_5l] =
+                       targetPowerCck.tPow2x[2];
+               ;
+               ratesArray[rate11s] = ratesArray[rate11l] =
+                       targetPowerCck.tPow2x[3];
+               ;
+       }
+       if (IS_CHAN_HT40(chan)) {
+               for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
+                       ratesArray[rateHt40_0 + i] =
+                               targetPowerHt40.tPow2x[i];
+               }
+               ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0];
+               ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0];
+               ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0];
+               if (IS_CHAN_2GHZ(chan)) {
+                       ratesArray[rateExtCck] =
+                               targetPowerCckExt.tPow2x[0];
+               }
+       }
+}
+
+static void ath9k_hw_def_set_txpower(struct ath_hw *ah,
+                                   struct ath9k_channel *chan,
+                                   u16 cfgCtl,
+                                   u8 twiceAntennaReduction,
+                                   u8 twiceMaxRegulatoryPower,
+                                   u8 powerLimit)
+{
+#define RT_AR_DELTA(x) (ratesArray[x] - cck_ofdm_delta)
+       struct ar5416_eeprom_def *pEepData = &ah->eeprom.def;
+       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;
+
+       memset(ratesArray, 0, sizeof(ratesArray));
+
+       if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
+           AR5416_EEP_MINOR_VER_2) {
+               ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
+       }
+
+       ath9k_hw_set_def_power_per_rate_table(ah, chan,
+                                              &ratesArray[0], cfgCtl,
+                                              twiceAntennaReduction,
+                                              twiceMaxRegulatoryPower,
+                                              powerLimit);
+
+       ath9k_hw_set_def_power_cal_table(ah, chan, &txPowerIndexOffset);
+
+       for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
+               ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]);
+               if (ratesArray[i] > AR5416_MAX_RATE_POWER)
+                       ratesArray[i] = AR5416_MAX_RATE_POWER;
+       }
+
+       if (AR_SREV_9280_10_OR_LATER(ah)) {
+               for (i = 0; i < Ar5416RateSize; i++)
+                       ratesArray[i] -= AR5416_PWR_TABLE_OFFSET * 2;
+       }
+
+       REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
+                 ATH9K_POW_SM(ratesArray[rate18mb], 24)
+                 | ATH9K_POW_SM(ratesArray[rate12mb], 16)
+                 | ATH9K_POW_SM(ratesArray[rate9mb], 8)
+                 | ATH9K_POW_SM(ratesArray[rate6mb], 0));
+       REG_WRITE(ah, AR_PHY_POWER_TX_RATE2,
+                 ATH9K_POW_SM(ratesArray[rate54mb], 24)
+                 | ATH9K_POW_SM(ratesArray[rate48mb], 16)
+                 | ATH9K_POW_SM(ratesArray[rate36mb], 8)
+                 | ATH9K_POW_SM(ratesArray[rate24mb], 0));
+
+       if (IS_CHAN_2GHZ(chan)) {
+               if (OLC_FOR_AR9280_20_LATER) {
+                       cck_ofdm_delta = 2;
+                       REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
+                               ATH9K_POW_SM(RT_AR_DELTA(rate2s), 24)
+                               | ATH9K_POW_SM(RT_AR_DELTA(rate2l), 16)
+                               | ATH9K_POW_SM(ratesArray[rateXr], 8)
+                               | ATH9K_POW_SM(RT_AR_DELTA(rate1l), 0));
+                       REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
+                               ATH9K_POW_SM(RT_AR_DELTA(rate11s), 24)
+                               | ATH9K_POW_SM(RT_AR_DELTA(rate11l), 16)
+                               | ATH9K_POW_SM(RT_AR_DELTA(rate5_5s), 8)
+                               | ATH9K_POW_SM(RT_AR_DELTA(rate5_5l), 0));
+               } else {
+                       REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
+                               ATH9K_POW_SM(ratesArray[rate2s], 24)
+                               | ATH9K_POW_SM(ratesArray[rate2l], 16)
+                               | ATH9K_POW_SM(ratesArray[rateXr], 8)
+                               | ATH9K_POW_SM(ratesArray[rate1l], 0));
+                       REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
+                               ATH9K_POW_SM(ratesArray[rate11s], 24)
+                               | ATH9K_POW_SM(ratesArray[rate11l], 16)
+                               | ATH9K_POW_SM(ratesArray[rate5_5s], 8)
+                               | ATH9K_POW_SM(ratesArray[rate5_5l], 0));
+               }
+       }
+
+       REG_WRITE(ah, AR_PHY_POWER_TX_RATE5,
+                 ATH9K_POW_SM(ratesArray[rateHt20_3], 24)
+                 | ATH9K_POW_SM(ratesArray[rateHt20_2], 16)
+                 | ATH9K_POW_SM(ratesArray[rateHt20_1], 8)
+                 | ATH9K_POW_SM(ratesArray[rateHt20_0], 0));
+       REG_WRITE(ah, AR_PHY_POWER_TX_RATE6,
+                 ATH9K_POW_SM(ratesArray[rateHt20_7], 24)
+                 | ATH9K_POW_SM(ratesArray[rateHt20_6], 16)
+                 | ATH9K_POW_SM(ratesArray[rateHt20_5], 8)
+                 | ATH9K_POW_SM(ratesArray[rateHt20_4], 0));
+
+       if (IS_CHAN_HT40(chan)) {
+               REG_WRITE(ah, AR_PHY_POWER_TX_RATE7,
+                         ATH9K_POW_SM(ratesArray[rateHt40_3] +
+                                      ht40PowerIncForPdadc, 24)
+                         | ATH9K_POW_SM(ratesArray[rateHt40_2] +
+                                        ht40PowerIncForPdadc, 16)
+                         | ATH9K_POW_SM(ratesArray[rateHt40_1] +
+                                        ht40PowerIncForPdadc, 8)
+                         | ATH9K_POW_SM(ratesArray[rateHt40_0] +
+                                        ht40PowerIncForPdadc, 0));
+               REG_WRITE(ah, AR_PHY_POWER_TX_RATE8,
+                         ATH9K_POW_SM(ratesArray[rateHt40_7] +
+                                      ht40PowerIncForPdadc, 24)
+                         | ATH9K_POW_SM(ratesArray[rateHt40_6] +
+                                        ht40PowerIncForPdadc, 16)
+                         | ATH9K_POW_SM(ratesArray[rateHt40_5] +
+                                        ht40PowerIncForPdadc, 8)
+                         | ATH9K_POW_SM(ratesArray[rateHt40_4] +
+                                        ht40PowerIncForPdadc, 0));
+               if (OLC_FOR_AR9280_20_LATER) {
+                       REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
+                               ATH9K_POW_SM(ratesArray[rateExtOfdm], 24)
+                               | ATH9K_POW_SM(RT_AR_DELTA(rateExtCck), 16)
+                               | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
+                               | ATH9K_POW_SM(RT_AR_DELTA(rateDupCck), 0));
+               } else {
+                       REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
+                               ATH9K_POW_SM(ratesArray[rateExtOfdm], 24)
+                               | ATH9K_POW_SM(ratesArray[rateExtCck], 16)
+                               | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
+                               | ATH9K_POW_SM(ratesArray[rateDupCck], 0));
+               }
+       }
+
+       REG_WRITE(ah, AR_PHY_POWER_TX_SUB,
+                 ATH9K_POW_SM(pModal->pwrDecreaseFor3Chain, 6)
+                 | ATH9K_POW_SM(pModal->pwrDecreaseFor2Chain, 0));
+
+       i = rate6mb;
+
+       if (IS_CHAN_HT40(chan))
+               i = rateHt40_0;
+       else if (IS_CHAN_HT20(chan))
+               i = rateHt20_0;
+
+       if (AR_SREV_9280_10_OR_LATER(ah))
+               ah->regulatory.max_power_level =
+                       ratesArray[i] + AR5416_PWR_TABLE_OFFSET * 2;
+       else
+               ah->regulatory.max_power_level = ratesArray[i];
+
+       switch(ar5416_get_ntxchains(ah->txchainmask)) {
+       case 1:
+               break;
+       case 2:
+               ah->regulatory.max_power_level += INCREASE_MAXPOW_BY_TWO_CHAIN;
+               break;
+       case 3:
+               ah->regulatory.max_power_level += INCREASE_MAXPOW_BY_THREE_CHAIN;
+               break;
+       default:
+               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+                       "Invalid chainmask configuration\n");
+               break;
+       }
+}
+
+static u8 ath9k_hw_def_get_num_ant_config(struct ath_hw *ah,
+                                         enum ieee80211_band freq_band)
+{
+       struct ar5416_eeprom_def *eep = &ah->eeprom.def;
+       struct modal_eep_header *pModal =
+               &(eep->modalHeader[ATH9K_HAL_FREQ_BAND_2GHZ == freq_band]);
+       struct base_eep_header *pBase = &eep->baseEepHeader;
+       u8 num_ant_config;
+
+       num_ant_config = 1;
+
+       if (pBase->version >= 0x0E0D)
+               if (pModal->useAnt1)
+                       num_ant_config += 1;
+
+       return num_ant_config;
+}
+
+static u16 ath9k_hw_def_get_eeprom_antenna_cfg(struct ath_hw *ah,
+                                              struct ath9k_channel *chan)
+{
+       struct ar5416_eeprom_def *eep = &ah->eeprom.def;
+       struct modal_eep_header *pModal =
+               &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
+
+       return pModal->antCtrlCommon & 0xFFFF;
+}
+
+static u16 ath9k_hw_def_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz)
+{
+#define EEP_DEF_SPURCHAN \
+       (ah->eeprom.def.modalHeader[is2GHz].spurChans[i].spurChan)
+
+       u16 spur_val = AR_NO_SPUR;
+
+       DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+               "Getting spur idx %d is2Ghz. %d val %x\n",
+               i, is2GHz, ah->config.spurchans[i][is2GHz]);
+
+       switch (ah->config.spurmode) {
+       case SPUR_DISABLE:
+               break;
+       case SPUR_ENABLE_IOCTL:
+               spur_val = ah->config.spurchans[i][is2GHz];
+               DPRINTF(ah->ah_sc, ATH_DBG_ANI,
+                       "Getting spur val from new loc. %d\n", spur_val);
+               break;
+       case SPUR_ENABLE_EEPROM:
+               spur_val = EEP_DEF_SPURCHAN;
+               break;
+       }
+
+       return spur_val;
+
+#undef EEP_DEF_SPURCHAN
+}
+
+static 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,
+       .get_eeprom_ver         = ath9k_hw_def_get_eeprom_ver,
+       .get_eeprom_rev         = ath9k_hw_def_get_eeprom_rev,
+       .get_num_ant_config     = ath9k_hw_def_get_num_ant_config,
+       .get_eeprom_antenna_cfg = ath9k_hw_def_get_eeprom_antenna_cfg,
+       .set_board_values       = ath9k_hw_def_set_board_values,
+       .set_addac              = ath9k_hw_def_set_addac,
+       .set_txpower            = ath9k_hw_def_set_txpower,
+       .get_spur_channel       = ath9k_hw_def_get_spur_channel
+};
+
+int ath9k_hw_eeprom_attach(struct ath_hw *ah)
+{
+       int status;
+
+       if (AR_SREV_9285(ah)) {
+               ah->eep_map = EEP_MAP_4KBITS;
+               ah->eep_ops = &eep_4k_ops;
+       } else {
+               ah->eep_map = EEP_MAP_DEFAULT;
+               ah->eep_ops = &eep_def_ops;
+       }
+
+       if (!ah->eep_ops->fill_eeprom(ah))
+               return -EIO;
+
+       status = ah->eep_ops->check_eeprom(ah);
+
+       return status;
+}
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h
new file mode 100644 (file)
index 0000000..67b8bd1
--- /dev/null
@@ -0,0 +1,509 @@
+/*
+ * Copyright (c) 2008-2009 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 EEPROM_H
+#define EEPROM_H
+
+#include <net/cfg80211.h>
+
+#define AH_USE_EEPROM   0x1
+
+#ifdef __BIG_ENDIAN
+#define AR5416_EEPROM_MAGIC 0x5aa5
+#else
+#define AR5416_EEPROM_MAGIC 0xa55a
+#endif
+
+#define CTRY_DEBUG   0x1ff
+#define        CTRY_DEFAULT 0
+
+#define AR_EEPROM_EEPCAP_COMPRESS_DIS   0x0001
+#define AR_EEPROM_EEPCAP_AES_DIS        0x0002
+#define AR_EEPROM_EEPCAP_FASTFRAME_DIS  0x0004
+#define AR_EEPROM_EEPCAP_BURST_DIS      0x0008
+#define AR_EEPROM_EEPCAP_MAXQCU         0x01F0
+#define AR_EEPROM_EEPCAP_MAXQCU_S       4
+#define AR_EEPROM_EEPCAP_HEAVY_CLIP_EN  0x0200
+#define AR_EEPROM_EEPCAP_KC_ENTRIES     0xF000
+#define AR_EEPROM_EEPCAP_KC_ENTRIES_S   12
+
+#define AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND   0x0040
+#define AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN    0x0080
+#define AR_EEPROM_EEREGCAP_EN_KK_U2         0x0100
+#define AR_EEPROM_EEREGCAP_EN_KK_MIDBAND    0x0200
+#define AR_EEPROM_EEREGCAP_EN_KK_U1_ODD     0x0400
+#define AR_EEPROM_EEREGCAP_EN_KK_NEW_11A    0x0800
+
+#define AR_EEPROM_EEREGCAP_EN_KK_U1_ODD_PRE4_0  0x4000
+#define AR_EEPROM_EEREGCAP_EN_KK_NEW_11A_PRE4_0 0x8000
+
+#define AR5416_EEPROM_MAGIC_OFFSET  0x0
+#define AR5416_EEPROM_S             2
+#define AR5416_EEPROM_OFFSET        0x2000
+#define AR5416_EEPROM_MAX           0xae0
+
+#define AR5416_EEPROM_START_ADDR \
+       (AR_SREV_9100(ah)) ? 0x1fff1000 : 0x503f1200
+
+#define SD_NO_CTL               0xE0
+#define NO_CTL                  0xff
+#define CTL_MODE_M              7
+#define CTL_11A                 0
+#define CTL_11B                 1
+#define CTL_11G                 2
+#define CTL_2GHT20              5
+#define CTL_5GHT20              6
+#define CTL_2GHT40              7
+#define CTL_5GHT40              8
+
+#define EXT_ADDITIVE (0x8000)
+#define CTL_11A_EXT (CTL_11A | EXT_ADDITIVE)
+#define CTL_11G_EXT (CTL_11G | EXT_ADDITIVE)
+#define CTL_11B_EXT (CTL_11B | EXT_ADDITIVE)
+
+#define SUB_NUM_CTL_MODES_AT_5G_40 2
+#define SUB_NUM_CTL_MODES_AT_2G_40 3
+
+#define INCREASE_MAXPOW_BY_TWO_CHAIN     6  /* 10*log10(2)*2 */
+#define INCREASE_MAXPOW_BY_THREE_CHAIN   10 /* 10*log10(3)*2 */
+
+/*
+ * For AR9285 and later chipsets, the following bits are not being programmed
+ * in EEPROM and so need to be enabled always.
+ *
+ * Bit 0: en_fcc_mid
+ * Bit 1: en_jap_mid
+ * Bit 2: en_fcc_dfs_ht40
+ * Bit 3: en_jap_ht40
+ * Bit 4: en_jap_dfs_ht40
+ */
+#define AR9285_RDEXT_DEFAULT    0x1F
+
+#define AR_EEPROM_MAC(i)       (0x1d+(i))
+#define ATH9K_POW_SM(_r, _s)   (((_r) & 0x3f) << (_s))
+#define FREQ2FBIN(x, y)                ((y) ? ((x) - 2300) : (((x) - 4800) / 5))
+#define ath9k_hw_use_flash(_ah)        (!(_ah->ah_flags & AH_USE_EEPROM))
+
+#define AR5416_VER_MASK (eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK)
+#define OLC_FOR_AR9280_20_LATER (AR_SREV_9280_20_OR_LATER(ah) && \
+                                ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL))
+
+#define AR_EEPROM_RFSILENT_GPIO_SEL     0x001c
+#define AR_EEPROM_RFSILENT_GPIO_SEL_S   2
+#define AR_EEPROM_RFSILENT_POLARITY     0x0002
+#define AR_EEPROM_RFSILENT_POLARITY_S   1
+
+#define EEP_RFSILENT_ENABLED        0x0001
+#define EEP_RFSILENT_ENABLED_S      0
+#define EEP_RFSILENT_POLARITY       0x0002
+#define EEP_RFSILENT_POLARITY_S     1
+#define EEP_RFSILENT_GPIO_SEL       0x001c
+#define EEP_RFSILENT_GPIO_SEL_S     2
+
+#define AR5416_OPFLAGS_11A           0x01
+#define AR5416_OPFLAGS_11G           0x02
+#define AR5416_OPFLAGS_N_5G_HT40     0x04
+#define AR5416_OPFLAGS_N_2G_HT40     0x08
+#define AR5416_OPFLAGS_N_5G_HT20     0x10
+#define AR5416_OPFLAGS_N_2G_HT20     0x20
+
+#define AR5416_EEP_NO_BACK_VER       0x1
+#define AR5416_EEP_VER               0xE
+#define AR5416_EEP_VER_MINOR_MASK    0x0FFF
+#define AR5416_EEP_MINOR_VER_2       0x2
+#define AR5416_EEP_MINOR_VER_3       0x3
+#define AR5416_EEP_MINOR_VER_7       0x7
+#define AR5416_EEP_MINOR_VER_9       0x9
+#define AR5416_EEP_MINOR_VER_16      0x10
+#define AR5416_EEP_MINOR_VER_17      0x11
+#define AR5416_EEP_MINOR_VER_19      0x13
+#define AR5416_EEP_MINOR_VER_20      0x14
+#define AR5416_EEP_MINOR_VER_22      0x16
+
+#define AR5416_NUM_5G_CAL_PIERS         8
+#define AR5416_NUM_2G_CAL_PIERS         4
+#define AR5416_NUM_5G_20_TARGET_POWERS  8
+#define AR5416_NUM_5G_40_TARGET_POWERS  8
+#define AR5416_NUM_2G_CCK_TARGET_POWERS 3
+#define AR5416_NUM_2G_20_TARGET_POWERS  4
+#define AR5416_NUM_2G_40_TARGET_POWERS  4
+#define AR5416_NUM_CTLS                 24
+#define AR5416_NUM_BAND_EDGES           8
+#define AR5416_NUM_PD_GAINS             4
+#define AR5416_PD_GAINS_IN_MASK         4
+#define AR5416_PD_GAIN_ICEPTS           5
+#define AR5416_EEPROM_MODAL_SPURS       5
+#define AR5416_MAX_RATE_POWER           63
+#define AR5416_NUM_PDADC_VALUES         128
+#define AR5416_BCHAN_UNUSED             0xFF
+#define AR5416_MAX_PWR_RANGE_IN_HALF_DB 64
+#define AR5416_MAX_CHAINS               3
+#define AR5416_PWR_TABLE_OFFSET         -5
+
+/* Rx gain type values */
+#define AR5416_EEP_RXGAIN_23DB_BACKOFF     0
+#define AR5416_EEP_RXGAIN_13DB_BACKOFF     1
+#define AR5416_EEP_RXGAIN_ORIG             2
+
+/* Tx gain type values */
+#define AR5416_EEP_TXGAIN_ORIGINAL         0
+#define AR5416_EEP_TXGAIN_HIGH_POWER       1
+
+#define AR5416_EEP4K_START_LOC                64
+#define AR5416_EEP4K_NUM_2G_CAL_PIERS         3
+#define AR5416_EEP4K_NUM_2G_CCK_TARGET_POWERS 3
+#define AR5416_EEP4K_NUM_2G_20_TARGET_POWERS  3
+#define AR5416_EEP4K_NUM_2G_40_TARGET_POWERS  3
+#define AR5416_EEP4K_NUM_CTLS                 12
+#define AR5416_EEP4K_NUM_BAND_EDGES           4
+#define AR5416_EEP4K_NUM_PD_GAINS             2
+#define AR5416_EEP4K_PD_GAINS_IN_MASK         4
+#define AR5416_EEP4K_PD_GAIN_ICEPTS           5
+#define AR5416_EEP4K_MAX_CHAINS               1
+
+#define AR9280_TX_GAIN_TABLE_SIZE 22
+
+enum eeprom_param {
+       EEP_NFTHRESH_5,
+       EEP_NFTHRESH_2,
+       EEP_MAC_MSW,
+       EEP_MAC_MID,
+       EEP_MAC_LSW,
+       EEP_REG_0,
+       EEP_REG_1,
+       EEP_OP_CAP,
+       EEP_OP_MODE,
+       EEP_RF_SILENT,
+       EEP_OB_5,
+       EEP_DB_5,
+       EEP_OB_2,
+       EEP_DB_2,
+       EEP_MINOR_REV,
+       EEP_TX_MASK,
+       EEP_RX_MASK,
+       EEP_RXGAIN_TYPE,
+       EEP_TXGAIN_TYPE,
+       EEP_OL_PWRCTRL,
+       EEP_RC_CHAIN_MASK,
+       EEP_DAC_HPWR_5G,
+       EEP_FRAC_N_5G
+};
+
+enum ar5416_rates {
+       rate6mb, rate9mb, rate12mb, rate18mb,
+       rate24mb, rate36mb, rate48mb, rate54mb,
+       rate1l, rate2l, rate2s, rate5_5l,
+       rate5_5s, rate11l, rate11s, rateXr,
+       rateHt20_0, rateHt20_1, rateHt20_2, rateHt20_3,
+       rateHt20_4, rateHt20_5, rateHt20_6, rateHt20_7,
+       rateHt40_0, rateHt40_1, rateHt40_2, rateHt40_3,
+       rateHt40_4, rateHt40_5, rateHt40_6, rateHt40_7,
+       rateDupCck, rateDupOfdm, rateExtCck, rateExtOfdm,
+       Ar5416RateSize
+};
+
+enum ath9k_hal_freq_band {
+       ATH9K_HAL_FREQ_BAND_5GHZ = 0,
+       ATH9K_HAL_FREQ_BAND_2GHZ = 1
+};
+
+struct base_eep_header {
+       u16 length;
+       u16 checksum;
+       u16 version;
+       u8 opCapFlags;
+       u8 eepMisc;
+       u16 regDmn[2];
+       u8 macAddr[6];
+       u8 rxMask;
+       u8 txMask;
+       u16 rfSilent;
+       u16 blueToothOptions;
+       u16 deviceCap;
+       u32 binBuildNumber;
+       u8 deviceType;
+       u8 pwdclkind;
+       u8 futureBase_1[2];
+       u8 rxGainType;
+       u8 dacHiPwrMode_5G;
+       u8 openLoopPwrCntl;
+       u8 dacLpMode;
+       u8 txGainType;
+       u8 rcChainMask;
+       u8 desiredScaleCCK;
+       u8 power_table_offset;
+       u8 frac_n_5g;
+       u8 futureBase_3[21];
+} __packed;
+
+struct base_eep_header_4k {
+       u16 length;
+       u16 checksum;
+       u16 version;
+       u8 opCapFlags;
+       u8 eepMisc;
+       u16 regDmn[2];
+       u8 macAddr[6];
+       u8 rxMask;
+       u8 txMask;
+       u16 rfSilent;
+       u16 blueToothOptions;
+       u16 deviceCap;
+       u32 binBuildNumber;
+       u8 deviceType;
+       u8 txGainType;
+} __packed;
+
+
+struct spur_chan {
+       u16 spurChan;
+       u8 spurRangeLow;
+       u8 spurRangeHigh;
+} __packed;
+
+struct modal_eep_header {
+       u32 antCtrlChain[AR5416_MAX_CHAINS];
+       u32 antCtrlCommon;
+       u8 antennaGainCh[AR5416_MAX_CHAINS];
+       u8 switchSettling;
+       u8 txRxAttenCh[AR5416_MAX_CHAINS];
+       u8 rxTxMarginCh[AR5416_MAX_CHAINS];
+       u8 adcDesiredSize;
+       u8 pgaDesiredSize;
+       u8 xlnaGainCh[AR5416_MAX_CHAINS];
+       u8 txEndToXpaOff;
+       u8 txEndToRxOn;
+       u8 txFrameToXpaOn;
+       u8 thresh62;
+       u8 noiseFloorThreshCh[AR5416_MAX_CHAINS];
+       u8 xpdGain;
+       u8 xpd;
+       u8 iqCalICh[AR5416_MAX_CHAINS];
+       u8 iqCalQCh[AR5416_MAX_CHAINS];
+       u8 pdGainOverlap;
+       u8 ob;
+       u8 db;
+       u8 xpaBiasLvl;
+       u8 pwrDecreaseFor2Chain;
+       u8 pwrDecreaseFor3Chain;
+       u8 txFrameToDataStart;
+       u8 txFrameToPaOn;
+       u8 ht40PowerIncForPdadc;
+       u8 bswAtten[AR5416_MAX_CHAINS];
+       u8 bswMargin[AR5416_MAX_CHAINS];
+       u8 swSettleHt40;
+       u8 xatten2Db[AR5416_MAX_CHAINS];
+       u8 xatten2Margin[AR5416_MAX_CHAINS];
+       u8 ob_ch1;
+       u8 db_ch1;
+       u8 useAnt1:1,
+           force_xpaon:1,
+           local_bias:1,
+           femBandSelectUsed:1, xlnabufin:1, xlnaisel:2, xlnabufmode:1;
+       u8 miscBits;
+       u16 xpaBiasLvlFreq[3];
+       u8 futureModal[6];
+
+       struct spur_chan spurChans[AR5416_EEPROM_MODAL_SPURS];
+} __packed;
+
+struct calDataPerFreqOpLoop {
+       u8 pwrPdg[2][5];
+       u8 vpdPdg[2][5];
+       u8 pcdac[2][5];
+       u8 empty[2][5];
+} __packed;
+
+struct modal_eep_4k_header {
+       u32  antCtrlChain[AR5416_EEP4K_MAX_CHAINS];
+       u32  antCtrlCommon;
+       u8   antennaGainCh[AR5416_EEP4K_MAX_CHAINS];
+       u8   switchSettling;
+       u8   txRxAttenCh[AR5416_EEP4K_MAX_CHAINS];
+       u8   rxTxMarginCh[AR5416_EEP4K_MAX_CHAINS];
+       u8   adcDesiredSize;
+       u8   pgaDesiredSize;
+       u8   xlnaGainCh[AR5416_EEP4K_MAX_CHAINS];
+       u8   txEndToXpaOff;
+       u8   txEndToRxOn;
+       u8   txFrameToXpaOn;
+       u8   thresh62;
+       u8   noiseFloorThreshCh[AR5416_EEP4K_MAX_CHAINS];
+       u8   xpdGain;
+       u8   xpd;
+       u8   iqCalICh[AR5416_EEP4K_MAX_CHAINS];
+       u8   iqCalQCh[AR5416_EEP4K_MAX_CHAINS];
+       u8   pdGainOverlap;
+       u8   ob_01;
+       u8   db1_01;
+       u8   xpaBiasLvl;
+       u8   txFrameToDataStart;
+       u8   txFrameToPaOn;
+       u8   ht40PowerIncForPdadc;
+       u8   bswAtten[AR5416_EEP4K_MAX_CHAINS];
+       u8   bswMargin[AR5416_EEP4K_MAX_CHAINS];
+       u8   swSettleHt40;
+       u8   xatten2Db[AR5416_EEP4K_MAX_CHAINS];
+       u8   xatten2Margin[AR5416_EEP4K_MAX_CHAINS];
+       u8   db2_01;
+       u8   version;
+       u16  ob_234;
+       u16  db1_234;
+       u16  db2_234;
+       u8   futureModal[4];
+
+       struct spur_chan spurChans[AR5416_EEPROM_MODAL_SPURS];
+} __packed;
+
+
+struct cal_data_per_freq {
+       u8 pwrPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
+       u8 vpdPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
+} __packed;
+
+struct cal_data_per_freq_4k {
+       u8 pwrPdg[AR5416_EEP4K_NUM_PD_GAINS][AR5416_EEP4K_PD_GAIN_ICEPTS];
+       u8 vpdPdg[AR5416_EEP4K_NUM_PD_GAINS][AR5416_EEP4K_PD_GAIN_ICEPTS];
+} __packed;
+
+struct cal_target_power_leg {
+       u8 bChannel;
+       u8 tPow2x[4];
+} __packed;
+
+struct cal_target_power_ht {
+       u8 bChannel;
+       u8 tPow2x[8];
+} __packed;
+
+
+#ifdef __BIG_ENDIAN_BITFIELD
+struct cal_ctl_edges {
+       u8 bChannel;
+       u8 flag:2, tPower:6;
+} __packed;
+#else
+struct cal_ctl_edges {
+       u8 bChannel;
+       u8 tPower:6, flag:2;
+} __packed;
+#endif
+
+struct cal_ctl_data {
+       struct cal_ctl_edges
+       ctlEdges[AR5416_MAX_CHAINS][AR5416_NUM_BAND_EDGES];
+} __packed;
+
+struct cal_ctl_data_4k {
+       struct cal_ctl_edges
+       ctlEdges[AR5416_EEP4K_MAX_CHAINS][AR5416_EEP4K_NUM_BAND_EDGES];
+} __packed;
+
+struct ar5416_eeprom_def {
+       struct base_eep_header baseEepHeader;
+       u8 custData[64];
+       struct modal_eep_header modalHeader[2];
+       u8 calFreqPier5G[AR5416_NUM_5G_CAL_PIERS];
+       u8 calFreqPier2G[AR5416_NUM_2G_CAL_PIERS];
+       struct cal_data_per_freq
+        calPierData5G[AR5416_MAX_CHAINS][AR5416_NUM_5G_CAL_PIERS];
+       struct cal_data_per_freq
+        calPierData2G[AR5416_MAX_CHAINS][AR5416_NUM_2G_CAL_PIERS];
+       struct cal_target_power_leg
+        calTargetPower5G[AR5416_NUM_5G_20_TARGET_POWERS];
+       struct cal_target_power_ht
+        calTargetPower5GHT20[AR5416_NUM_5G_20_TARGET_POWERS];
+       struct cal_target_power_ht
+        calTargetPower5GHT40[AR5416_NUM_5G_40_TARGET_POWERS];
+       struct cal_target_power_leg
+        calTargetPowerCck[AR5416_NUM_2G_CCK_TARGET_POWERS];
+       struct cal_target_power_leg
+        calTargetPower2G[AR5416_NUM_2G_20_TARGET_POWERS];
+       struct cal_target_power_ht
+        calTargetPower2GHT20[AR5416_NUM_2G_20_TARGET_POWERS];
+       struct cal_target_power_ht
+        calTargetPower2GHT40[AR5416_NUM_2G_40_TARGET_POWERS];
+       u8 ctlIndex[AR5416_NUM_CTLS];
+       struct cal_ctl_data ctlData[AR5416_NUM_CTLS];
+       u8 padding;
+} __packed;
+
+struct ar5416_eeprom_4k {
+       struct base_eep_header_4k baseEepHeader;
+       u8 custData[20];
+       struct modal_eep_4k_header modalHeader;
+       u8 calFreqPier2G[AR5416_EEP4K_NUM_2G_CAL_PIERS];
+       struct cal_data_per_freq_4k
+       calPierData2G[AR5416_EEP4K_MAX_CHAINS][AR5416_EEP4K_NUM_2G_CAL_PIERS];
+       struct cal_target_power_leg
+       calTargetPowerCck[AR5416_EEP4K_NUM_2G_CCK_TARGET_POWERS];
+       struct cal_target_power_leg
+       calTargetPower2G[AR5416_EEP4K_NUM_2G_20_TARGET_POWERS];
+       struct cal_target_power_ht
+       calTargetPower2GHT20[AR5416_EEP4K_NUM_2G_20_TARGET_POWERS];
+       struct cal_target_power_ht
+       calTargetPower2GHT40[AR5416_EEP4K_NUM_2G_40_TARGET_POWERS];
+       u8 ctlIndex[AR5416_EEP4K_NUM_CTLS];
+       struct cal_ctl_data_4k ctlData[AR5416_EEP4K_NUM_CTLS];
+       u8 padding;
+} __packed;
+
+enum reg_ext_bitmap {
+       REG_EXT_JAPAN_MIDBAND = 1,
+       REG_EXT_FCC_DFS_HT40 = 2,
+       REG_EXT_JAPAN_NONDFS_HT40 = 3,
+       REG_EXT_JAPAN_DFS_HT40 = 4
+};
+
+struct ath9k_country_entry {
+       u16 countryCode;
+       u16 regDmnEnum;
+       u16 regDmn5G;
+       u16 regDmn2G;
+       u8 isMultidomain;
+       u8 iso[3];
+};
+
+enum ath9k_eep_map {
+       EEP_MAP_DEFAULT = 0x0,
+       EEP_MAP_4KBITS,
+       EEP_MAP_MAX
+};
+
+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);
+       int (*get_eeprom_ver)(struct ath_hw *hw);
+       int (*get_eeprom_rev)(struct ath_hw *hw);
+       u8 (*get_num_ant_config)(struct ath_hw *hw, enum ieee80211_band band);
+       u16 (*get_eeprom_antenna_cfg)(struct ath_hw *hw,
+                                     struct ath9k_channel *chan);
+       void (*set_board_values)(struct ath_hw *hw, struct ath9k_channel *chan);
+       void (*set_addac)(struct ath_hw *hw, struct ath9k_channel *chan);
+       void (*set_txpower)(struct ath_hw *hw, struct ath9k_channel *chan,
+                          u16 cfgCtl, u8 twiceAntennaReduction,
+                          u8 twiceMaxRegulatoryPower, u8 powerLimit);
+       u16 (*get_spur_channel)(struct ath_hw *ah, u16 i, bool is2GHz);
+};
+
+#define ar5416_get_ntxchains(_txchainmask)                     \
+       (((_txchainmask >> 2) & 1) +                            \
+        ((_txchainmask >> 1) & 1) + (_txchainmask & 1))
+
+int ath9k_hw_eeprom_attach(struct ath_hw *ah);
+
+#endif /* EEPROM_H */
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
new file mode 100644 (file)
index 0000000..1579c94
--- /dev/null
@@ -0,0 +1,3873 @@
+/*
+ * Copyright (c) 2008-2009 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/io.h>
+#include <asm/unaligned.h>
+
+#include "ath9k.h"
+#include "initvals.h"
+
+static int btcoex_enable;
+module_param(btcoex_enable, bool, 0);
+MODULE_PARM_DESC(btcoex_enable, "Enable Bluetooth coexistence support");
+
+#define ATH9K_CLOCK_RATE_CCK           22
+#define ATH9K_CLOCK_RATE_5GHZ_OFDM     40
+#define ATH9K_CLOCK_RATE_2GHZ_OFDM     44
+
+static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type);
+static void ath9k_hw_set_regs(struct ath_hw *ah, struct ath9k_channel *chan,
+                             enum ath9k_ht_macmode macmode);
+static u32 ath9k_hw_ini_fixup(struct ath_hw *ah,
+                             struct ar5416_eeprom_def *pEepData,
+                             u32 reg, u32 value);
+static void ath9k_hw_9280_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan);
+static void ath9k_hw_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan);
+
+/********************/
+/* Helper Functions */
+/********************/
+
+static u32 ath9k_hw_mac_usec(struct ath_hw *ah, u32 clks)
+{
+       struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
+
+       if (!ah->curchan) /* should really check for CCK instead */
+               return clks / ATH9K_CLOCK_RATE_CCK;
+       if (conf->channel->band == IEEE80211_BAND_2GHZ)
+               return clks / ATH9K_CLOCK_RATE_2GHZ_OFDM;
+
+       return clks / ATH9K_CLOCK_RATE_5GHZ_OFDM;
+}
+
+static u32 ath9k_hw_mac_to_usec(struct ath_hw *ah, u32 clks)
+{
+       struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
+
+       if (conf_is_ht40(conf))
+               return ath9k_hw_mac_usec(ah, clks) / 2;
+       else
+               return ath9k_hw_mac_usec(ah, clks);
+}
+
+static u32 ath9k_hw_mac_clks(struct ath_hw *ah, u32 usecs)
+{
+       struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
+
+       if (!ah->curchan) /* should really check for CCK instead */
+               return usecs *ATH9K_CLOCK_RATE_CCK;
+       if (conf->channel->band == IEEE80211_BAND_2GHZ)
+               return usecs *ATH9K_CLOCK_RATE_2GHZ_OFDM;
+       return usecs *ATH9K_CLOCK_RATE_5GHZ_OFDM;
+}
+
+static u32 ath9k_hw_mac_to_clks(struct ath_hw *ah, u32 usecs)
+{
+       struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
+
+       if (conf_is_ht40(conf))
+               return ath9k_hw_mac_clks(ah, usecs) * 2;
+       else
+               return ath9k_hw_mac_clks(ah, usecs);
+}
+
+/*
+ * Read and write, they both share the same lock. We do this to serialize
+ * reads and writes on Atheros 802.11n PCI devices only. This is required
+ * as the FIFO on these devices can only accept sanely 2 requests. After
+ * that the device goes bananas. Serializing the reads/writes prevents this
+ * from happening.
+ */
+
+void ath9k_iowrite32(struct ath_hw *ah, u32 reg_offset, u32 val)
+{
+       if (ah->config.serialize_regmode == SER_REG_MODE_ON) {
+               unsigned long flags;
+               spin_lock_irqsave(&ah->ah_sc->sc_serial_rw, flags);
+               iowrite32(val, ah->ah_sc->mem + reg_offset);
+               spin_unlock_irqrestore(&ah->ah_sc->sc_serial_rw, flags);
+       } else
+               iowrite32(val, ah->ah_sc->mem + reg_offset);
+}
+
+unsigned int ath9k_ioread32(struct ath_hw *ah, u32 reg_offset)
+{
+       u32 val;
+       if (ah->config.serialize_regmode == SER_REG_MODE_ON) {
+               unsigned long flags;
+               spin_lock_irqsave(&ah->ah_sc->sc_serial_rw, flags);
+               val = ioread32(ah->ah_sc->mem + reg_offset);
+               spin_unlock_irqrestore(&ah->ah_sc->sc_serial_rw, flags);
+       } else
+               val = ioread32(ah->ah_sc->mem + reg_offset);
+       return val;
+}
+
+bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout)
+{
+       int i;
+
+       BUG_ON(timeout < AH_TIME_QUANTUM);
+
+       for (i = 0; i < (timeout / AH_TIME_QUANTUM); i++) {
+               if ((REG_READ(ah, reg) & mask) == val)
+                       return true;
+
+               udelay(AH_TIME_QUANTUM);
+       }
+
+       DPRINTF(ah->ah_sc, ATH_DBG_ANY,
+               "timeout (%d us) on reg 0x%x: 0x%08x & 0x%08x != 0x%08x\n",
+               timeout, reg, REG_READ(ah, reg), mask, val);
+
+       return false;
+}
+
+u32 ath9k_hw_reverse_bits(u32 val, u32 n)
+{
+       u32 retval;
+       int i;
+
+       for (i = 0, retval = 0; i < n; i++) {
+               retval = (retval << 1) | (val & 1);
+               val >>= 1;
+       }
+       return retval;
+}
+
+bool ath9k_get_channel_edges(struct ath_hw *ah,
+                            u16 flags, u16 *low,
+                            u16 *high)
+{
+       struct ath9k_hw_capabilities *pCap = &ah->caps;
+
+       if (flags & CHANNEL_5GHZ) {
+               *low = pCap->low_5ghz_chan;
+               *high = pCap->high_5ghz_chan;
+               return true;
+       }
+       if ((flags & CHANNEL_2GHZ)) {
+               *low = pCap->low_2ghz_chan;
+               *high = pCap->high_2ghz_chan;
+               return true;
+       }
+       return false;
+}
+
+u16 ath9k_hw_computetxtime(struct ath_hw *ah,
+                          const struct ath_rate_table *rates,
+                          u32 frameLen, u16 rateix,
+                          bool shortPreamble)
+{
+       u32 bitsPerSymbol, numBits, numSymbols, phyTime, txTime;
+       u32 kbps;
+
+       kbps = rates->info[rateix].ratekbps;
+
+       if (kbps == 0)
+               return 0;
+
+       switch (rates->info[rateix].phy) {
+       case WLAN_RC_PHY_CCK:
+               phyTime = CCK_PREAMBLE_BITS + CCK_PLCP_BITS;
+               if (shortPreamble && rates->info[rateix].short_preamble)
+                       phyTime >>= 1;
+               numBits = frameLen << 3;
+               txTime = CCK_SIFS_TIME + phyTime + ((numBits * 1000) / kbps);
+               break;
+       case WLAN_RC_PHY_OFDM:
+               if (ah->curchan && IS_CHAN_QUARTER_RATE(ah->curchan)) {
+                       bitsPerSymbol = (kbps * OFDM_SYMBOL_TIME_QUARTER) / 1000;
+                       numBits = OFDM_PLCP_BITS + (frameLen << 3);
+                       numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol);
+                       txTime = OFDM_SIFS_TIME_QUARTER
+                               + OFDM_PREAMBLE_TIME_QUARTER
+                               + (numSymbols * OFDM_SYMBOL_TIME_QUARTER);
+               } else if (ah->curchan &&
+                          IS_CHAN_HALF_RATE(ah->curchan)) {
+                       bitsPerSymbol = (kbps * OFDM_SYMBOL_TIME_HALF) / 1000;
+                       numBits = OFDM_PLCP_BITS + (frameLen << 3);
+                       numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol);
+                       txTime = OFDM_SIFS_TIME_HALF +
+                               OFDM_PREAMBLE_TIME_HALF
+                               + (numSymbols * OFDM_SYMBOL_TIME_HALF);
+               } else {
+                       bitsPerSymbol = (kbps * OFDM_SYMBOL_TIME) / 1000;
+                       numBits = OFDM_PLCP_BITS + (frameLen << 3);
+                       numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol);
+                       txTime = OFDM_SIFS_TIME + OFDM_PREAMBLE_TIME
+                               + (numSymbols * OFDM_SYMBOL_TIME);
+               }
+               break;
+       default:
+               DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+                       "Unknown phy %u (rate ix %u)\n",
+                       rates->info[rateix].phy, rateix);
+               txTime = 0;
+               break;
+       }
+
+       return txTime;
+}
+
+void ath9k_hw_get_channel_centers(struct ath_hw *ah,
+                                 struct ath9k_channel *chan,
+                                 struct chan_centers *centers)
+{
+       int8_t extoff;
+
+       if (!IS_CHAN_HT40(chan)) {
+               centers->ctl_center = centers->ext_center =
+                       centers->synth_center = chan->channel;
+               return;
+       }
+
+       if ((chan->chanmode == CHANNEL_A_HT40PLUS) ||
+           (chan->chanmode == CHANNEL_G_HT40PLUS)) {
+               centers->synth_center =
+                       chan->channel + HT40_CHANNEL_CENTER_SHIFT;
+               extoff = 1;
+       } else {
+               centers->synth_center =
+                       chan->channel - HT40_CHANNEL_CENTER_SHIFT;
+               extoff = -1;
+       }
+
+       centers->ctl_center =
+               centers->synth_center - (extoff * HT40_CHANNEL_CENTER_SHIFT);
+       centers->ext_center =
+               centers->synth_center + (extoff *
+                        ((ah->extprotspacing == ATH9K_HT_EXTPROTSPACING_20) ?
+                         HT40_CHANNEL_CENTER_SHIFT : 15));
+}
+
+/******************/
+/* Chip Revisions */
+/******************/
+
+static void ath9k_hw_read_revisions(struct ath_hw *ah)
+{
+       u32 val;
+
+       val = REG_READ(ah, AR_SREV) & AR_SREV_ID;
+
+       if (val == 0xFF) {
+               val = REG_READ(ah, AR_SREV);
+               ah->hw_version.macVersion =
+                       (val & AR_SREV_VERSION2) >> AR_SREV_TYPE2_S;
+               ah->hw_version.macRev = MS(val, AR_SREV_REVISION2);
+               ah->is_pciexpress = (val & AR_SREV_TYPE2_HOST_MODE) ? 0 : 1;
+       } else {
+               if (!AR_SREV_9100(ah))
+                       ah->hw_version.macVersion = MS(val, AR_SREV_VERSION);
+
+               ah->hw_version.macRev = val & AR_SREV_REVISION;
+
+               if (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCIE)
+                       ah->is_pciexpress = true;
+       }
+}
+
+static int ath9k_hw_get_radiorev(struct ath_hw *ah)
+{
+       u32 val;
+       int i;
+
+       REG_WRITE(ah, AR_PHY(0x36), 0x00007058);
+
+       for (i = 0; i < 8; i++)
+               REG_WRITE(ah, AR_PHY(0x20), 0x00010000);
+       val = (REG_READ(ah, AR_PHY(256)) >> 24) & 0xff;
+       val = ((val & 0xf0) >> 4) | ((val & 0x0f) << 4);
+
+       return ath9k_hw_reverse_bits(val, 8);
+}
+
+/************************************/
+/* HW Attach, Detach, Init Routines */
+/************************************/
+
+static void ath9k_hw_disablepcie(struct ath_hw *ah)
+{
+       if (AR_SREV_9100(ah))
+               return;
+
+       REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00);
+       REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
+       REG_WRITE(ah, AR_PCIE_SERDES, 0x28000029);
+       REG_WRITE(ah, AR_PCIE_SERDES, 0x57160824);
+       REG_WRITE(ah, AR_PCIE_SERDES, 0x25980579);
+       REG_WRITE(ah, AR_PCIE_SERDES, 0x00000000);
+       REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
+       REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
+       REG_WRITE(ah, AR_PCIE_SERDES, 0x000e1007);
+
+       REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
+}
+
+static bool ath9k_hw_chip_test(struct ath_hw *ah)
+{
+       u32 regAddr[2] = { AR_STA_ID0, AR_PHY_BASE + (8 << 2) };
+       u32 regHold[2];
+       u32 patternData[4] = { 0x55555555,
+                              0xaaaaaaaa,
+                              0x66666666,
+                              0x99999999 };
+       int i, j;
+
+       for (i = 0; i < 2; i++) {
+               u32 addr = regAddr[i];
+               u32 wrData, rdData;
+
+               regHold[i] = REG_READ(ah, addr);
+               for (j = 0; j < 0x100; j++) {
+                       wrData = (j << 16) | j;
+                       REG_WRITE(ah, addr, wrData);
+                       rdData = REG_READ(ah, addr);
+                       if (rdData != wrData) {
+                               DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+                                       "address test failed "
+                                       "addr: 0x%08x - wr:0x%08x != rd:0x%08x\n",
+                                       addr, wrData, rdData);
+                               return false;
+                       }
+               }
+               for (j = 0; j < 4; j++) {
+                       wrData = patternData[j];
+                       REG_WRITE(ah, addr, wrData);
+                       rdData = REG_READ(ah, addr);
+                       if (wrData != rdData) {
+                               DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+                                       "address test failed "
+                                       "addr: 0x%08x - wr:0x%08x != rd:0x%08x\n",
+                                       addr, wrData, rdData);
+                               return false;
+                       }
+               }
+               REG_WRITE(ah, regAddr[i], regHold[i]);
+       }
+       udelay(100);
+
+       return true;
+}
+
+static const char *ath9k_hw_devname(u16 devid)
+{
+       switch (devid) {
+       case AR5416_DEVID_PCI:
+               return "Atheros 5416";
+       case AR5416_DEVID_PCIE:
+               return "Atheros 5418";
+       case AR9160_DEVID_PCI:
+               return "Atheros 9160";
+       case AR5416_AR9100_DEVID:
+               return "Atheros 9100";
+       case AR9280_DEVID_PCI:
+       case AR9280_DEVID_PCIE:
+               return "Atheros 9280";
+       case AR9285_DEVID_PCIE:
+               return "Atheros 9285";
+       }
+
+       return NULL;
+}
+
+static void ath9k_hw_set_defaults(struct ath_hw *ah)
+{
+       int i;
+
+       ah->config.dma_beacon_response_time = 2;
+       ah->config.sw_beacon_response_time = 10;
+       ah->config.additional_swba_backoff = 0;
+       ah->config.ack_6mb = 0x0;
+       ah->config.cwm_ignore_extcca = 0;
+       ah->config.pcie_powersave_enable = 0;
+       ah->config.pcie_clock_req = 0;
+       ah->config.pcie_waen = 0;
+       ah->config.analog_shiftreg = 1;
+       ah->config.ht_enable = 1;
+       ah->config.ofdm_trig_low = 200;
+       ah->config.ofdm_trig_high = 500;
+       ah->config.cck_trig_high = 200;
+       ah->config.cck_trig_low = 100;
+       ah->config.enable_ani = 1;
+       ah->config.diversity_control = 0;
+       ah->config.antenna_switch_swap = 0;
+
+       for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
+               ah->config.spurchans[i][0] = AR_NO_SPUR;
+               ah->config.spurchans[i][1] = AR_NO_SPUR;
+       }
+
+       ah->config.intr_mitigation = true;
+
+       /*
+        * We need this for PCI devices only (Cardbus, PCI, miniPCI)
+        * _and_ if on non-uniprocessor systems (Multiprocessor/HT).
+        * This means we use it for all AR5416 devices, and the few
+        * minor PCI AR9280 devices out there.
+        *
+        * Serialization is required because these devices do not handle
+        * well the case of two concurrent reads/writes due to the latency
+        * involved. During one read/write another read/write can be issued
+        * on another CPU while the previous read/write may still be working
+        * on our hardware, if we hit this case the hardware poops in a loop.
+        * We prevent this by serializing reads and writes.
+        *
+        * This issue is not present on PCI-Express devices or pre-AR5416
+        * devices (legacy, 802.11abg).
+        */
+       if (num_possible_cpus() > 1)
+               ah->config.serialize_regmode = SER_REG_MODE_AUTO;
+}
+
+static struct ath_hw *ath9k_hw_newstate(u16 devid, struct ath_softc *sc,
+                                       int *status)
+{
+       struct ath_hw *ah;
+
+       ah = kzalloc(sizeof(struct ath_hw), GFP_KERNEL);
+       if (ah == NULL) {
+               DPRINTF(sc, ATH_DBG_FATAL,
+                       "Cannot allocate memory for state block\n");
+               *status = -ENOMEM;
+               return NULL;
+       }
+
+       ah->ah_sc = sc;
+       ah->hw_version.magic = AR5416_MAGIC;
+       ah->regulatory.country_code = CTRY_DEFAULT;
+       ah->hw_version.devid = devid;
+       ah->hw_version.subvendorid = 0;
+
+       ah->ah_flags = 0;
+       if ((devid == AR5416_AR9100_DEVID))
+               ah->hw_version.macVersion = AR_SREV_VERSION_9100;
+       if (!AR_SREV_9100(ah))
+               ah->ah_flags = AH_USE_EEPROM;
+
+       ah->regulatory.power_limit = MAX_RATE_POWER;
+       ah->regulatory.tp_scale = ATH9K_TP_SCALE_MAX;
+       ah->atim_window = 0;
+       ah->diversity_control = ah->config.diversity_control;
+       ah->antenna_switch_swap =
+               ah->config.antenna_switch_swap;
+       ah->sta_id1_defaults = AR_STA_ID1_CRPT_MIC_ENABLE;
+       ah->beacon_interval = 100;
+       ah->enable_32kHz_clock = DONT_USE_32KHZ;
+       ah->slottime = (u32) -1;
+       ah->acktimeout = (u32) -1;
+       ah->ctstimeout = (u32) -1;
+       ah->globaltxtimeout = (u32) -1;
+
+       ah->gbeacon_rate = 0;
+
+       return ah;
+}
+
+static int ath9k_hw_rfattach(struct ath_hw *ah)
+{
+       bool rfStatus = false;
+       int ecode = 0;
+
+       rfStatus = ath9k_hw_init_rf(ah, &ecode);
+       if (!rfStatus) {
+               DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+                       "RF setup failed, status: %u\n", ecode);
+               return ecode;
+       }
+
+       return 0;
+}
+
+static int ath9k_hw_rf_claim(struct ath_hw *ah)
+{
+       u32 val;
+
+       REG_WRITE(ah, AR_PHY(0), 0x00000007);
+
+       val = ath9k_hw_get_radiorev(ah);
+       switch (val & AR_RADIO_SREV_MAJOR) {
+       case 0:
+               val = AR_RAD5133_SREV_MAJOR;
+               break;
+       case AR_RAD5133_SREV_MAJOR:
+       case AR_RAD5122_SREV_MAJOR:
+       case AR_RAD2133_SREV_MAJOR:
+       case AR_RAD2122_SREV_MAJOR:
+               break;
+       default:
+               DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+                       "Radio Chip Rev 0x%02X not supported\n",
+                       val & AR_RADIO_SREV_MAJOR);
+               return -EOPNOTSUPP;
+       }
+
+       ah->hw_version.analog5GhzRev = val;
+
+       return 0;
+}
+
+static int ath9k_hw_init_macaddr(struct ath_hw *ah)
+{
+       u32 sum;
+       int i;
+       u16 eeval;
+
+       sum = 0;
+       for (i = 0; i < 3; i++) {
+               eeval = ah->eep_ops->get_eeprom(ah, AR_EEPROM_MAC(i));
+               sum += eeval;
+               ah->macaddr[2 * i] = eeval >> 8;
+               ah->macaddr[2 * i + 1] = eeval & 0xff;
+       }
+       if (sum == 0 || sum == 0xffff * 3)
+               return -EADDRNOTAVAIL;
+
+       return 0;
+}
+
+static void ath9k_hw_init_rxgain_ini(struct ath_hw *ah)
+{
+       u32 rxgain_type;
+
+       if (ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV) >= AR5416_EEP_MINOR_VER_17) {
+               rxgain_type = ah->eep_ops->get_eeprom(ah, EEP_RXGAIN_TYPE);
+
+               if (rxgain_type == AR5416_EEP_RXGAIN_13DB_BACKOFF)
+                       INIT_INI_ARRAY(&ah->iniModesRxGain,
+                       ar9280Modes_backoff_13db_rxgain_9280_2,
+                       ARRAY_SIZE(ar9280Modes_backoff_13db_rxgain_9280_2), 6);
+               else if (rxgain_type == AR5416_EEP_RXGAIN_23DB_BACKOFF)
+                       INIT_INI_ARRAY(&ah->iniModesRxGain,
+                       ar9280Modes_backoff_23db_rxgain_9280_2,
+                       ARRAY_SIZE(ar9280Modes_backoff_23db_rxgain_9280_2), 6);
+               else
+                       INIT_INI_ARRAY(&ah->iniModesRxGain,
+                       ar9280Modes_original_rxgain_9280_2,
+                       ARRAY_SIZE(ar9280Modes_original_rxgain_9280_2), 6);
+       } else {
+               INIT_INI_ARRAY(&ah->iniModesRxGain,
+                       ar9280Modes_original_rxgain_9280_2,
+                       ARRAY_SIZE(ar9280Modes_original_rxgain_9280_2), 6);
+       }
+}
+
+static void ath9k_hw_init_txgain_ini(struct ath_hw *ah)
+{
+       u32 txgain_type;
+
+       if (ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV) >= AR5416_EEP_MINOR_VER_19) {
+               txgain_type = ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE);
+
+               if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER)
+                       INIT_INI_ARRAY(&ah->iniModesTxGain,
+                       ar9280Modes_high_power_tx_gain_9280_2,
+                       ARRAY_SIZE(ar9280Modes_high_power_tx_gain_9280_2), 6);
+               else
+                       INIT_INI_ARRAY(&ah->iniModesTxGain,
+                       ar9280Modes_original_tx_gain_9280_2,
+                       ARRAY_SIZE(ar9280Modes_original_tx_gain_9280_2), 6);
+       } else {
+               INIT_INI_ARRAY(&ah->iniModesTxGain,
+               ar9280Modes_original_tx_gain_9280_2,
+               ARRAY_SIZE(ar9280Modes_original_tx_gain_9280_2), 6);
+       }
+}
+
+static int ath9k_hw_post_attach(struct ath_hw *ah)
+{
+       int ecode;
+
+       if (!ath9k_hw_chip_test(ah))
+               return -ENODEV;
+
+       ecode = ath9k_hw_rf_claim(ah);
+       if (ecode != 0)
+               return ecode;
+
+       ecode = ath9k_hw_eeprom_attach(ah);
+       if (ecode != 0)
+               return ecode;
+
+       DPRINTF(ah->ah_sc, ATH_DBG_CONFIG, "Eeprom VER: %d, REV: %d\n",
+               ah->eep_ops->get_eeprom_ver(ah), ah->eep_ops->get_eeprom_rev(ah));
+
+       ecode = ath9k_hw_rfattach(ah);
+       if (ecode != 0)
+               return ecode;
+
+       if (!AR_SREV_9100(ah)) {
+               ath9k_hw_ani_setup(ah);
+               ath9k_hw_ani_attach(ah);
+       }
+
+       return 0;
+}
+
+static struct ath_hw *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc,
+                                        int *status)
+{
+       struct ath_hw *ah;
+       int ecode;
+       u32 i, j;
+
+       ah = ath9k_hw_newstate(devid, sc, status);
+       if (ah == NULL)
+               return NULL;
+
+       ath9k_hw_set_defaults(ah);
+
+       if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) {
+               DPRINTF(sc, ATH_DBG_FATAL, "Couldn't reset chip\n");
+               ecode = -EIO;
+               goto bad;
+       }
+
+       if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) {
+               DPRINTF(sc, ATH_DBG_FATAL, "Couldn't wakeup chip\n");
+               ecode = -EIO;
+               goto bad;
+       }
+
+       if (ah->config.serialize_regmode == SER_REG_MODE_AUTO) {
+               if (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCI ||
+                   (AR_SREV_9280(ah) && !ah->is_pciexpress)) {
+                       ah->config.serialize_regmode =
+                               SER_REG_MODE_ON;
+               } else {
+                       ah->config.serialize_regmode =
+                               SER_REG_MODE_OFF;
+               }
+       }
+
+       DPRINTF(sc, ATH_DBG_RESET, "serialize_regmode is %d\n",
+               ah->config.serialize_regmode);
+
+       if ((ah->hw_version.macVersion != AR_SREV_VERSION_5416_PCI) &&
+           (ah->hw_version.macVersion != AR_SREV_VERSION_5416_PCIE) &&
+           (ah->hw_version.macVersion != AR_SREV_VERSION_9160) &&
+           (!AR_SREV_9100(ah)) && (!AR_SREV_9280(ah)) && (!AR_SREV_9285(ah))) {
+               DPRINTF(sc, ATH_DBG_FATAL,
+                       "Mac Chip Rev 0x%02x.%x is not supported by "
+                       "this driver\n", ah->hw_version.macVersion,
+                       ah->hw_version.macRev);
+               ecode = -EOPNOTSUPP;
+               goto bad;
+       }
+
+       if (AR_SREV_9100(ah)) {
+               ah->iq_caldata.calData = &iq_cal_multi_sample;
+               ah->supp_cals = IQ_MISMATCH_CAL;
+               ah->is_pciexpress = false;
+       }
+       ah->hw_version.phyRev = REG_READ(ah, AR_PHY_CHIP_ID);
+
+       if (AR_SREV_9160_10_OR_LATER(ah)) {
+               if (AR_SREV_9280_10_OR_LATER(ah)) {
+                       ah->iq_caldata.calData = &iq_cal_single_sample;
+                       ah->adcgain_caldata.calData =
+                               &adc_gain_cal_single_sample;
+                       ah->adcdc_caldata.calData =
+                               &adc_dc_cal_single_sample;
+                       ah->adcdc_calinitdata.calData =
+                               &adc_init_dc_cal;
+               } else {
+                       ah->iq_caldata.calData = &iq_cal_multi_sample;
+                       ah->adcgain_caldata.calData =
+                               &adc_gain_cal_multi_sample;
+                       ah->adcdc_caldata.calData =
+                               &adc_dc_cal_multi_sample;
+                       ah->adcdc_calinitdata.calData =
+                               &adc_init_dc_cal;
+               }
+               ah->supp_cals = ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL;
+       }
+
+       ah->ani_function = ATH9K_ANI_ALL;
+       if (AR_SREV_9280_10_OR_LATER(ah))
+               ah->ani_function &= ~ATH9K_ANI_NOISE_IMMUNITY_LEVEL;
+
+       if (AR_SREV_9285_12_OR_LATER(ah)) {
+
+               INIT_INI_ARRAY(&ah->iniModes, ar9285Modes_9285_1_2,
+                              ARRAY_SIZE(ar9285Modes_9285_1_2), 6);
+               INIT_INI_ARRAY(&ah->iniCommon, ar9285Common_9285_1_2,
+                              ARRAY_SIZE(ar9285Common_9285_1_2), 2);
+
+               if (ah->config.pcie_clock_req) {
+                       INIT_INI_ARRAY(&ah->iniPcieSerdes,
+                       ar9285PciePhy_clkreq_off_L1_9285_1_2,
+                       ARRAY_SIZE(ar9285PciePhy_clkreq_off_L1_9285_1_2), 2);
+               } else {
+                       INIT_INI_ARRAY(&ah->iniPcieSerdes,
+                       ar9285PciePhy_clkreq_always_on_L1_9285_1_2,
+                       ARRAY_SIZE(ar9285PciePhy_clkreq_always_on_L1_9285_1_2),
+                                 2);
+               }
+       } else if (AR_SREV_9285_10_OR_LATER(ah)) {
+               INIT_INI_ARRAY(&ah->iniModes, ar9285Modes_9285,
+                              ARRAY_SIZE(ar9285Modes_9285), 6);
+               INIT_INI_ARRAY(&ah->iniCommon, ar9285Common_9285,
+                              ARRAY_SIZE(ar9285Common_9285), 2);
+
+               if (ah->config.pcie_clock_req) {
+                       INIT_INI_ARRAY(&ah->iniPcieSerdes,
+                       ar9285PciePhy_clkreq_off_L1_9285,
+                       ARRAY_SIZE(ar9285PciePhy_clkreq_off_L1_9285), 2);
+               } else {
+                       INIT_INI_ARRAY(&ah->iniPcieSerdes,
+                       ar9285PciePhy_clkreq_always_on_L1_9285,
+                       ARRAY_SIZE(ar9285PciePhy_clkreq_always_on_L1_9285), 2);
+               }
+       } else if (AR_SREV_9280_20_OR_LATER(ah)) {
+               INIT_INI_ARRAY(&ah->iniModes, ar9280Modes_9280_2,
+                              ARRAY_SIZE(ar9280Modes_9280_2), 6);
+               INIT_INI_ARRAY(&ah->iniCommon, ar9280Common_9280_2,
+                              ARRAY_SIZE(ar9280Common_9280_2), 2);
+
+               if (ah->config.pcie_clock_req) {
+                       INIT_INI_ARRAY(&ah->iniPcieSerdes,
+                              ar9280PciePhy_clkreq_off_L1_9280,
+                              ARRAY_SIZE(ar9280PciePhy_clkreq_off_L1_9280),2);
+               } else {
+                       INIT_INI_ARRAY(&ah->iniPcieSerdes,
+                              ar9280PciePhy_clkreq_always_on_L1_9280,
+                              ARRAY_SIZE(ar9280PciePhy_clkreq_always_on_L1_9280), 2);
+               }
+               INIT_INI_ARRAY(&ah->iniModesAdditional,
+                              ar9280Modes_fast_clock_9280_2,
+                              ARRAY_SIZE(ar9280Modes_fast_clock_9280_2), 3);
+       } else if (AR_SREV_9280_10_OR_LATER(ah)) {
+               INIT_INI_ARRAY(&ah->iniModes, ar9280Modes_9280,
+                              ARRAY_SIZE(ar9280Modes_9280), 6);
+               INIT_INI_ARRAY(&ah->iniCommon, ar9280Common_9280,
+                              ARRAY_SIZE(ar9280Common_9280), 2);
+       } else if (AR_SREV_9160_10_OR_LATER(ah)) {
+               INIT_INI_ARRAY(&ah->iniModes, ar5416Modes_9160,
+                              ARRAY_SIZE(ar5416Modes_9160), 6);
+               INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9160,
+                              ARRAY_SIZE(ar5416Common_9160), 2);
+               INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0_9160,
+                              ARRAY_SIZE(ar5416Bank0_9160), 2);
+               INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain_9160,
+                              ARRAY_SIZE(ar5416BB_RfGain_9160), 3);
+               INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1_9160,
+                              ARRAY_SIZE(ar5416Bank1_9160), 2);
+               INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2_9160,
+                              ARRAY_SIZE(ar5416Bank2_9160), 2);
+               INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3_9160,
+                              ARRAY_SIZE(ar5416Bank3_9160), 3);
+               INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6_9160,
+                              ARRAY_SIZE(ar5416Bank6_9160), 3);
+               INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC_9160,
+                              ARRAY_SIZE(ar5416Bank6TPC_9160), 3);
+               INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7_9160,
+                              ARRAY_SIZE(ar5416Bank7_9160), 2);
+               if (AR_SREV_9160_11(ah)) {
+                       INIT_INI_ARRAY(&ah->iniAddac,
+                                      ar5416Addac_91601_1,
+                                      ARRAY_SIZE(ar5416Addac_91601_1), 2);
+               } else {
+                       INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac_9160,
+                                      ARRAY_SIZE(ar5416Addac_9160), 2);
+               }
+       } else if (AR_SREV_9100_OR_LATER(ah)) {
+               INIT_INI_ARRAY(&ah->iniModes, ar5416Modes_9100,
+                              ARRAY_SIZE(ar5416Modes_9100), 6);
+               INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9100,
+                              ARRAY_SIZE(ar5416Common_9100), 2);
+               INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0_9100,
+                              ARRAY_SIZE(ar5416Bank0_9100), 2);
+               INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain_9100,
+                              ARRAY_SIZE(ar5416BB_RfGain_9100), 3);
+               INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1_9100,
+                              ARRAY_SIZE(ar5416Bank1_9100), 2);
+               INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2_9100,
+                              ARRAY_SIZE(ar5416Bank2_9100), 2);
+               INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3_9100,
+                              ARRAY_SIZE(ar5416Bank3_9100), 3);
+               INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6_9100,
+                              ARRAY_SIZE(ar5416Bank6_9100), 3);
+               INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC_9100,
+                              ARRAY_SIZE(ar5416Bank6TPC_9100), 3);
+               INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7_9100,
+                              ARRAY_SIZE(ar5416Bank7_9100), 2);
+               INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac_9100,
+                              ARRAY_SIZE(ar5416Addac_9100), 2);
+       } else {
+               INIT_INI_ARRAY(&ah->iniModes, ar5416Modes,
+                              ARRAY_SIZE(ar5416Modes), 6);
+               INIT_INI_ARRAY(&ah->iniCommon, ar5416Common,
+                              ARRAY_SIZE(ar5416Common), 2);
+               INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0,
+                              ARRAY_SIZE(ar5416Bank0), 2);
+               INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain,
+                              ARRAY_SIZE(ar5416BB_RfGain), 3);
+               INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1,
+                              ARRAY_SIZE(ar5416Bank1), 2);
+               INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2,
+                              ARRAY_SIZE(ar5416Bank2), 2);
+               INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3,
+                              ARRAY_SIZE(ar5416Bank3), 3);
+               INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6,
+                              ARRAY_SIZE(ar5416Bank6), 3);
+               INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC,
+                              ARRAY_SIZE(ar5416Bank6TPC), 3);
+               INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7,
+                              ARRAY_SIZE(ar5416Bank7), 2);
+               INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac,
+                              ARRAY_SIZE(ar5416Addac), 2);
+       }
+
+       if (ah->is_pciexpress)
+               ath9k_hw_configpcipowersave(ah, 0);
+       else
+               ath9k_hw_disablepcie(ah);
+
+       ecode = ath9k_hw_post_attach(ah);
+       if (ecode != 0)
+               goto bad;
+
+       if (AR_SREV_9285_12_OR_LATER(ah)) {
+               u32 txgain_type = ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE);
+
+               /* txgain table */
+               if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER) {
+                       INIT_INI_ARRAY(&ah->iniModesTxGain,
+                       ar9285Modes_high_power_tx_gain_9285_1_2,
+                       ARRAY_SIZE(ar9285Modes_high_power_tx_gain_9285_1_2), 6);
+               } else {
+                       INIT_INI_ARRAY(&ah->iniModesTxGain,
+                       ar9285Modes_original_tx_gain_9285_1_2,
+                       ARRAY_SIZE(ar9285Modes_original_tx_gain_9285_1_2), 6);
+               }
+
+       }
+
+       /* rxgain table */
+       if (AR_SREV_9280_20(ah))
+               ath9k_hw_init_rxgain_ini(ah);
+
+       /* txgain table */
+       if (AR_SREV_9280_20(ah))
+               ath9k_hw_init_txgain_ini(ah);
+
+       ath9k_hw_fill_cap_info(ah);
+
+       if ((ah->hw_version.devid == AR9280_DEVID_PCI) &&
+           test_bit(ATH9K_MODE_11A, ah->caps.wireless_modes)) {
+
+               /* EEPROM Fixup */
+               for (i = 0; i < ah->iniModes.ia_rows; i++) {
+                       u32 reg = INI_RA(&ah->iniModes, i, 0);
+
+                       for (j = 1; j < ah->iniModes.ia_columns; j++) {
+                               u32 val = INI_RA(&ah->iniModes, i, j);
+
+                               INI_RA(&ah->iniModes, i, j) =
+                                       ath9k_hw_ini_fixup(ah,
+                                                          &ah->eeprom.def,
+                                                          reg, val);
+                       }
+               }
+       }
+
+       ecode = ath9k_hw_init_macaddr(ah);
+       if (ecode != 0) {
+               DPRINTF(sc, ATH_DBG_FATAL,
+                       "Failed to initialize MAC address\n");
+               goto bad;
+       }
+
+       if (AR_SREV_9285(ah))
+               ah->tx_trig_level = (AR_FTRIG_256B >> AR_FTRIG_S);
+       else
+               ah->tx_trig_level = (AR_FTRIG_512B >> AR_FTRIG_S);
+
+       ath9k_init_nfcal_hist_buffer(ah);
+
+       return ah;
+bad:
+       if (ah)
+               ath9k_hw_detach(ah);
+       if (status)
+               *status = ecode;
+
+       return NULL;
+}
+
+static void ath9k_hw_init_bb(struct ath_hw *ah,
+                            struct ath9k_channel *chan)
+{
+       u32 synthDelay;
+
+       synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
+       if (IS_CHAN_B(chan))
+               synthDelay = (4 * synthDelay) / 22;
+       else
+               synthDelay /= 10;
+
+       REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
+
+       udelay(synthDelay + BASE_ACTIVATE_DELAY);
+}
+
+static void ath9k_hw_init_qos(struct ath_hw *ah)
+{
+       REG_WRITE(ah, AR_MIC_QOS_CONTROL, 0x100aa);
+       REG_WRITE(ah, AR_MIC_QOS_SELECT, 0x3210);
+
+       REG_WRITE(ah, AR_QOS_NO_ACK,
+                 SM(2, AR_QOS_NO_ACK_TWO_BIT) |
+                 SM(5, AR_QOS_NO_ACK_BIT_OFF) |
+                 SM(0, AR_QOS_NO_ACK_BYTE_OFF));
+
+       REG_WRITE(ah, AR_TXOP_X, AR_TXOP_X_VAL);
+       REG_WRITE(ah, AR_TXOP_0_3, 0xFFFFFFFF);
+       REG_WRITE(ah, AR_TXOP_4_7, 0xFFFFFFFF);
+       REG_WRITE(ah, AR_TXOP_8_11, 0xFFFFFFFF);
+       REG_WRITE(ah, AR_TXOP_12_15, 0xFFFFFFFF);
+}
+
+static void ath9k_hw_init_pll(struct ath_hw *ah,
+                             struct ath9k_channel *chan)
+{
+       u32 pll;
+
+       if (AR_SREV_9100(ah)) {
+               if (chan && IS_CHAN_5GHZ(chan))
+                       pll = 0x1450;
+               else
+                       pll = 0x1458;
+       } else {
+               if (AR_SREV_9280_10_OR_LATER(ah)) {
+                       pll = SM(0x5, AR_RTC_9160_PLL_REFDIV);
+
+                       if (chan && IS_CHAN_HALF_RATE(chan))
+                               pll |= SM(0x1, AR_RTC_9160_PLL_CLKSEL);
+                       else if (chan && IS_CHAN_QUARTER_RATE(chan))
+                               pll |= SM(0x2, AR_RTC_9160_PLL_CLKSEL);
+
+                       if (chan && IS_CHAN_5GHZ(chan)) {
+                               pll |= SM(0x28, AR_RTC_9160_PLL_DIV);
+
+
+                               if (AR_SREV_9280_20(ah)) {
+                                       if (((chan->channel % 20) == 0)
+                                           || ((chan->channel % 10) == 0))
+                                               pll = 0x2850;
+                                       else
+                                               pll = 0x142c;
+                               }
+                       } else {
+                               pll |= SM(0x2c, AR_RTC_9160_PLL_DIV);
+                       }
+
+               } else if (AR_SREV_9160_10_OR_LATER(ah)) {
+
+                       pll = SM(0x5, AR_RTC_9160_PLL_REFDIV);
+
+                       if (chan && IS_CHAN_HALF_RATE(chan))
+                               pll |= SM(0x1, AR_RTC_9160_PLL_CLKSEL);
+                       else if (chan && IS_CHAN_QUARTER_RATE(chan))
+                               pll |= SM(0x2, AR_RTC_9160_PLL_CLKSEL);
+
+                       if (chan && IS_CHAN_5GHZ(chan))
+                               pll |= SM(0x50, AR_RTC_9160_PLL_DIV);
+                       else
+                               pll |= SM(0x58, AR_RTC_9160_PLL_DIV);
+               } else {
+                       pll = AR_RTC_PLL_REFDIV_5 | AR_RTC_PLL_DIV2;
+
+                       if (chan && IS_CHAN_HALF_RATE(chan))
+                               pll |= SM(0x1, AR_RTC_PLL_CLKSEL);
+                       else if (chan && IS_CHAN_QUARTER_RATE(chan))
+                               pll |= SM(0x2, AR_RTC_PLL_CLKSEL);
+
+                       if (chan && IS_CHAN_5GHZ(chan))
+                               pll |= SM(0xa, AR_RTC_PLL_DIV);
+                       else
+                               pll |= SM(0xb, AR_RTC_PLL_DIV);
+               }
+       }
+       REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll);
+
+       udelay(RTC_PLL_SETTLE_DELAY);
+
+       REG_WRITE(ah, AR_RTC_SLEEP_CLK, AR_RTC_FORCE_DERIVED_CLK);
+}
+
+static void ath9k_hw_init_chain_masks(struct ath_hw *ah)
+{
+       int rx_chainmask, tx_chainmask;
+
+       rx_chainmask = ah->rxchainmask;
+       tx_chainmask = ah->txchainmask;
+
+       switch (rx_chainmask) {
+       case 0x5:
+               REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
+                           AR_PHY_SWAP_ALT_CHAIN);
+       case 0x3:
+               if (((ah)->hw_version.macVersion <= AR_SREV_VERSION_9160)) {
+                       REG_WRITE(ah, AR_PHY_RX_CHAINMASK, 0x7);
+                       REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, 0x7);
+                       break;
+               }
+       case 0x1:
+       case 0x2:
+       case 0x7:
+               REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
+               REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
+               break;
+       default:
+               break;
+       }
+
+       REG_WRITE(ah, AR_SELFGEN_MASK, tx_chainmask);
+       if (tx_chainmask == 0x5) {
+               REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
+                           AR_PHY_SWAP_ALT_CHAIN);
+       }
+       if (AR_SREV_9100(ah))
+               REG_WRITE(ah, AR_PHY_ANALOG_SWAP,
+                         REG_READ(ah, AR_PHY_ANALOG_SWAP) | 0x00000001);
+}
+
+static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah,
+                                         enum nl80211_iftype opmode)
+{
+       ah->mask_reg = AR_IMR_TXERR |
+               AR_IMR_TXURN |
+               AR_IMR_RXERR |
+               AR_IMR_RXORN |
+               AR_IMR_BCNMISC;
+
+       if (ah->config.intr_mitigation)
+               ah->mask_reg |= AR_IMR_RXINTM | AR_IMR_RXMINTR;
+       else
+               ah->mask_reg |= AR_IMR_RXOK;
+
+       ah->mask_reg |= AR_IMR_TXOK;
+
+       if (opmode == NL80211_IFTYPE_AP)
+               ah->mask_reg |= AR_IMR_MIB;
+
+       REG_WRITE(ah, AR_IMR, ah->mask_reg);
+       REG_WRITE(ah, AR_IMR_S2, REG_READ(ah, AR_IMR_S2) | AR_IMR_S2_GTT);
+
+       if (!AR_SREV_9100(ah)) {
+               REG_WRITE(ah, AR_INTR_SYNC_CAUSE, 0xFFFFFFFF);
+               REG_WRITE(ah, AR_INTR_SYNC_ENABLE, AR_INTR_SYNC_DEFAULT);
+               REG_WRITE(ah, AR_INTR_SYNC_MASK, 0);
+       }
+}
+
+static bool ath9k_hw_set_ack_timeout(struct ath_hw *ah, u32 us)
+{
+       if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_ACK))) {
+               DPRINTF(ah->ah_sc, ATH_DBG_RESET, "bad ack timeout %u\n", us);
+               ah->acktimeout = (u32) -1;
+               return false;
+       } else {
+               REG_RMW_FIELD(ah, AR_TIME_OUT,
+                             AR_TIME_OUT_ACK, ath9k_hw_mac_to_clks(ah, us));
+               ah->acktimeout = us;
+               return true;
+       }
+}
+
+static bool ath9k_hw_set_cts_timeout(struct ath_hw *ah, u32 us)
+{
+       if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_CTS))) {
+               DPRINTF(ah->ah_sc, ATH_DBG_RESET, "bad cts timeout %u\n", us);
+               ah->ctstimeout = (u32) -1;
+               return false;
+       } else {
+               REG_RMW_FIELD(ah, AR_TIME_OUT,
+                             AR_TIME_OUT_CTS, ath9k_hw_mac_to_clks(ah, us));
+               ah->ctstimeout = us;
+               return true;
+       }
+}
+
+static bool ath9k_hw_set_global_txtimeout(struct ath_hw *ah, u32 tu)
+{
+       if (tu > 0xFFFF) {
+               DPRINTF(ah->ah_sc, ATH_DBG_XMIT,
+                       "bad global tx timeout %u\n", tu);
+               ah->globaltxtimeout = (u32) -1;
+               return false;
+       } else {
+               REG_RMW_FIELD(ah, AR_GTXTO, AR_GTXTO_TIMEOUT_LIMIT, tu);
+               ah->globaltxtimeout = tu;
+               return true;
+       }
+}
+
+static void ath9k_hw_init_user_settings(struct ath_hw *ah)
+{
+       DPRINTF(ah->ah_sc, ATH_DBG_RESET, "ah->misc_mode 0x%x\n",
+               ah->misc_mode);
+
+       if (ah->misc_mode != 0)
+               REG_WRITE(ah, AR_PCU_MISC,
+                         REG_READ(ah, AR_PCU_MISC) | ah->misc_mode);
+       if (ah->slottime != (u32) -1)
+               ath9k_hw_setslottime(ah, ah->slottime);
+       if (ah->acktimeout != (u32) -1)
+               ath9k_hw_set_ack_timeout(ah, ah->acktimeout);
+       if (ah->ctstimeout != (u32) -1)
+               ath9k_hw_set_cts_timeout(ah, ah->ctstimeout);
+       if (ah->globaltxtimeout != (u32) -1)
+               ath9k_hw_set_global_txtimeout(ah, ah->globaltxtimeout);
+}
+
+const char *ath9k_hw_probe(u16 vendorid, u16 devid)
+{
+       return vendorid == ATHEROS_VENDOR_ID ?
+               ath9k_hw_devname(devid) : NULL;
+}
+
+void ath9k_hw_detach(struct ath_hw *ah)
+{
+       if (!AR_SREV_9100(ah))
+               ath9k_hw_ani_detach(ah);
+
+       ath9k_hw_rfdetach(ah);
+       ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP);
+       kfree(ah);
+}
+
+struct ath_hw *ath9k_hw_attach(u16 devid, struct ath_softc *sc, int *error)
+{
+       struct ath_hw *ah = NULL;
+
+       switch (devid) {
+       case AR5416_DEVID_PCI:
+       case AR5416_DEVID_PCIE:
+       case AR5416_AR9100_DEVID:
+       case AR9160_DEVID_PCI:
+       case AR9280_DEVID_PCI:
+       case AR9280_DEVID_PCIE:
+       case AR9285_DEVID_PCIE:
+               ah = ath9k_hw_do_attach(devid, sc, error);
+               break;
+       default:
+               *error = -ENXIO;
+               break;
+       }
+
+       return ah;
+}
+
+/*******/
+/* INI */
+/*******/
+
+static void ath9k_hw_override_ini(struct ath_hw *ah,
+                                 struct ath9k_channel *chan)
+{
+       /*
+        * Set the RX_ABORT and RX_DIS and clear if off only after
+        * RXE is set for MAC. This prevents frames with corrupted
+        * descriptor status.
+        */
+       REG_SET_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
+
+
+       if (!AR_SREV_5416_20_OR_LATER(ah) ||
+           AR_SREV_9280_10_OR_LATER(ah))
+               return;
+
+       REG_WRITE(ah, 0x9800 + (651 << 2), 0x11);
+}
+
+static u32 ath9k_hw_def_ini_fixup(struct ath_hw *ah,
+                             struct ar5416_eeprom_def *pEepData,
+                             u32 reg, u32 value)
+{
+       struct base_eep_header *pBase = &(pEepData->baseEepHeader);
+
+       switch (ah->hw_version.devid) {
+       case AR9280_DEVID_PCI:
+               if (reg == 0x7894) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+                               "ini VAL: %x  EEPROM: %x\n", value,
+                               (pBase->version & 0xff));
+
+                       if ((pBase->version & 0xff) > 0x0a) {
+                               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+                                       "PWDCLKIND: %d\n",
+                                       pBase->pwdclkind);
+                               value &= ~AR_AN_TOP2_PWDCLKIND;
+                               value |= AR_AN_TOP2_PWDCLKIND &
+                                       (pBase->pwdclkind << AR_AN_TOP2_PWDCLKIND_S);
+                       } else {
+                               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+                                       "PWDCLKIND Earlier Rev\n");
+                       }
+
+                       DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
+                               "final ini VAL: %x\n", value);
+               }
+               break;
+       }
+
+       return value;
+}
+
+static u32 ath9k_hw_ini_fixup(struct ath_hw *ah,
+                             struct ar5416_eeprom_def *pEepData,
+                             u32 reg, u32 value)
+{
+       if (ah->eep_map == EEP_MAP_4KBITS)
+               return value;
+       else
+               return ath9k_hw_def_ini_fixup(ah, pEepData, reg, value);
+}
+
+static void ath9k_olc_init(struct ath_hw *ah)
+{
+       u32 i;
+
+       for (i = 0; i < AR9280_TX_GAIN_TABLE_SIZE; i++)
+               ah->originalGain[i] =
+                       MS(REG_READ(ah, AR_PHY_TX_GAIN_TBL1 + i * 4),
+                                       AR_PHY_TX_GAIN);
+       ah->PDADCdelta = 0;
+}
+
+static u32 ath9k_regd_get_ctl(struct ath_regulatory *reg,
+                             struct ath9k_channel *chan)
+{
+       u32 ctl = ath_regd_get_band_ctl(reg, chan->chan->band);
+
+       if (IS_CHAN_B(chan))
+               ctl |= CTL_11B;
+       else if (IS_CHAN_G(chan))
+               ctl |= CTL_11G;
+       else
+               ctl |= CTL_11A;
+
+       return ctl;
+}
+
+static int ath9k_hw_process_ini(struct ath_hw *ah,
+                               struct ath9k_channel *chan,
+                               enum ath9k_ht_macmode macmode)
+{
+       int i, regWrites = 0;
+       struct ieee80211_channel *channel = chan->chan;
+       u32 modesIndex, freqIndex;
+
+       switch (chan->chanmode) {
+       case CHANNEL_A:
+       case CHANNEL_A_HT20:
+               modesIndex = 1;
+               freqIndex = 1;
+               break;
+       case CHANNEL_A_HT40PLUS:
+       case CHANNEL_A_HT40MINUS:
+               modesIndex = 2;
+               freqIndex = 1;
+               break;
+       case CHANNEL_G:
+       case CHANNEL_G_HT20:
+       case CHANNEL_B:
+               modesIndex = 4;
+               freqIndex = 2;
+               break;
+       case CHANNEL_G_HT40PLUS:
+       case CHANNEL_G_HT40MINUS:
+               modesIndex = 3;
+               freqIndex = 2;
+               break;
+
+       default:
+               return -EINVAL;
+       }
+
+       REG_WRITE(ah, AR_PHY(0), 0x00000007);
+       REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_EXTERNAL_RADIO);
+       ah->eep_ops->set_addac(ah, chan);
+
+       if (AR_SREV_5416_22_OR_LATER(ah)) {
+               REG_WRITE_ARRAY(&ah->iniAddac, 1, regWrites);
+       } else {
+               struct ar5416IniArray temp;
+               u32 addacSize =
+                       sizeof(u32) * ah->iniAddac.ia_rows *
+                       ah->iniAddac.ia_columns;
+
+               memcpy(ah->addac5416_21,
+                      ah->iniAddac.ia_array, addacSize);
+
+               (ah->addac5416_21)[31 * ah->iniAddac.ia_columns + 1] = 0;
+
+               temp.ia_array = ah->addac5416_21;
+               temp.ia_columns = ah->iniAddac.ia_columns;
+               temp.ia_rows = ah->iniAddac.ia_rows;
+               REG_WRITE_ARRAY(&temp, 1, regWrites);
+       }
+
+       REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_INTERNAL_ADDAC);
+
+       for (i = 0; i < ah->iniModes.ia_rows; i++) {
+               u32 reg = INI_RA(&ah->iniModes, i, 0);
+               u32 val = INI_RA(&ah->iniModes, i, modesIndex);
+
+               REG_WRITE(ah, reg, val);
+
+               if (reg >= 0x7800 && reg < 0x78a0
+                   && ah->config.analog_shiftreg) {
+                       udelay(100);
+               }
+
+               DO_DELAY(regWrites);
+       }
+
+       if (AR_SREV_9280(ah))
+               REG_WRITE_ARRAY(&ah->iniModesRxGain, modesIndex, regWrites);
+
+       if (AR_SREV_9280(ah) || AR_SREV_9285_12_OR_LATER(ah))
+               REG_WRITE_ARRAY(&ah->iniModesTxGain, modesIndex, regWrites);
+
+       for (i = 0; i < ah->iniCommon.ia_rows; i++) {
+               u32 reg = INI_RA(&ah->iniCommon, i, 0);
+               u32 val = INI_RA(&ah->iniCommon, i, 1);
+
+               REG_WRITE(ah, reg, val);
+
+               if (reg >= 0x7800 && reg < 0x78a0
+                   && ah->config.analog_shiftreg) {
+                       udelay(100);
+               }
+
+               DO_DELAY(regWrites);
+       }
+
+       ath9k_hw_write_regs(ah, modesIndex, freqIndex, regWrites);
+
+       if (AR_SREV_9280_20(ah) && IS_CHAN_A_5MHZ_SPACED(chan)) {
+               REG_WRITE_ARRAY(&ah->iniModesAdditional, modesIndex,
+                               regWrites);
+       }
+
+       ath9k_hw_override_ini(ah, chan);
+       ath9k_hw_set_regs(ah, chan, macmode);
+       ath9k_hw_init_chain_masks(ah);
+
+       if (OLC_FOR_AR9280_20_LATER)
+               ath9k_olc_init(ah);
+
+       ah->eep_ops->set_txpower(ah, chan,
+                                ath9k_regd_get_ctl(&ah->regulatory, chan),
+                                channel->max_antenna_gain * 2,
+                                channel->max_power * 2,
+                                min((u32) MAX_RATE_POWER,
+                                (u32) ah->regulatory.power_limit));
+
+       if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) {
+               DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+                       "ar5416SetRfRegs failed\n");
+               return -EIO;
+       }
+
+       return 0;
+}
+
+/****************************************/
+/* Reset and Channel Switching Routines */
+/****************************************/
+
+static void ath9k_hw_set_rfmode(struct ath_hw *ah, struct ath9k_channel *chan)
+{
+       u32 rfMode = 0;
+
+       if (chan == NULL)
+               return;
+
+       rfMode |= (IS_CHAN_B(chan) || IS_CHAN_G(chan))
+               ? AR_PHY_MODE_DYNAMIC : AR_PHY_MODE_OFDM;
+
+       if (!AR_SREV_9280_10_OR_LATER(ah))
+               rfMode |= (IS_CHAN_5GHZ(chan)) ?
+                       AR_PHY_MODE_RF5GHZ : AR_PHY_MODE_RF2GHZ;
+
+       if (AR_SREV_9280_20(ah) && IS_CHAN_A_5MHZ_SPACED(chan))
+               rfMode |= (AR_PHY_MODE_DYNAMIC | AR_PHY_MODE_DYN_CCK_DISABLE);
+
+       REG_WRITE(ah, AR_PHY_MODE, rfMode);
+}
+
+static void ath9k_hw_mark_phy_inactive(struct ath_hw *ah)
+{
+       REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
+}
+
+static inline void ath9k_hw_set_dma(struct ath_hw *ah)
+{
+       u32 regval;
+
+       regval = REG_READ(ah, AR_AHB_MODE);
+       REG_WRITE(ah, AR_AHB_MODE, regval | AR_AHB_PREFETCH_RD_EN);
+
+       regval = REG_READ(ah, AR_TXCFG) & ~AR_TXCFG_DMASZ_MASK;
+       REG_WRITE(ah, AR_TXCFG, regval | AR_TXCFG_DMASZ_128B);
+
+       REG_RMW_FIELD(ah, AR_TXCFG, AR_FTRIG, ah->tx_trig_level);
+
+       regval = REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_DMASZ_MASK;
+       REG_WRITE(ah, AR_RXCFG, regval | AR_RXCFG_DMASZ_128B);
+
+       REG_WRITE(ah, AR_RXFIFO_CFG, 0x200);
+
+       if (AR_SREV_9285(ah)) {
+               REG_WRITE(ah, AR_PCU_TXBUF_CTRL,
+                         AR_9285_PCU_TXBUF_CTRL_USABLE_SIZE);
+       } else {
+               REG_WRITE(ah, AR_PCU_TXBUF_CTRL,
+                         AR_PCU_TXBUF_CTRL_USABLE_SIZE);
+       }
+}
+
+static void ath9k_hw_set_operating_mode(struct ath_hw *ah, int opmode)
+{
+       u32 val;
+
+       val = REG_READ(ah, AR_STA_ID1);
+       val &= ~(AR_STA_ID1_STA_AP | AR_STA_ID1_ADHOC);
+       switch (opmode) {
+       case NL80211_IFTYPE_AP:
+               REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_STA_AP
+                         | AR_STA_ID1_KSRCH_MODE);
+               REG_CLR_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);
+               break;
+       case NL80211_IFTYPE_ADHOC:
+       case NL80211_IFTYPE_MESH_POINT:
+               REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_ADHOC
+                         | AR_STA_ID1_KSRCH_MODE);
+               REG_SET_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);
+               break;
+       case NL80211_IFTYPE_STATION:
+       case NL80211_IFTYPE_MONITOR:
+               REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_KSRCH_MODE);
+               break;
+       }
+}
+
+static inline void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah,
+                                                u32 coef_scaled,
+                                                u32 *coef_mantissa,
+                                                u32 *coef_exponent)
+{
+       u32 coef_exp, coef_man;
+
+       for (coef_exp = 31; coef_exp > 0; coef_exp--)
+               if ((coef_scaled >> coef_exp) & 0x1)
+                       break;
+
+       coef_exp = 14 - (coef_exp - COEF_SCALE_S);
+
+       coef_man = coef_scaled + (1 << (COEF_SCALE_S - coef_exp - 1));
+
+       *coef_mantissa = coef_man >> (COEF_SCALE_S - coef_exp);
+       *coef_exponent = coef_exp - 16;
+}
+
+static void ath9k_hw_set_delta_slope(struct ath_hw *ah,
+                                    struct ath9k_channel *chan)
+{
+       u32 coef_scaled, ds_coef_exp, ds_coef_man;
+       u32 clockMhzScaled = 0x64000000;
+       struct chan_centers centers;
+
+       if (IS_CHAN_HALF_RATE(chan))
+               clockMhzScaled = clockMhzScaled >> 1;
+       else if (IS_CHAN_QUARTER_RATE(chan))
+               clockMhzScaled = clockMhzScaled >> 2;
+
+       ath9k_hw_get_channel_centers(ah, chan, &centers);
+       coef_scaled = clockMhzScaled / centers.synth_center;
+
+       ath9k_hw_get_delta_slope_vals(ah, coef_scaled, &ds_coef_man,
+                                     &ds_coef_exp);
+
+       REG_RMW_FIELD(ah, AR_PHY_TIMING3,
+                     AR_PHY_TIMING3_DSC_MAN, ds_coef_man);
+       REG_RMW_FIELD(ah, AR_PHY_TIMING3,
+                     AR_PHY_TIMING3_DSC_EXP, ds_coef_exp);
+
+       coef_scaled = (9 * coef_scaled) / 10;
+
+       ath9k_hw_get_delta_slope_vals(ah, coef_scaled, &ds_coef_man,
+                                     &ds_coef_exp);
+
+       REG_RMW_FIELD(ah, AR_PHY_HALFGI,
+                     AR_PHY_HALFGI_DSC_MAN, ds_coef_man);
+       REG_RMW_FIELD(ah, AR_PHY_HALFGI,
+                     AR_PHY_HALFGI_DSC_EXP, ds_coef_exp);
+}
+
+static bool ath9k_hw_set_reset(struct ath_hw *ah, int type)
+{
+       u32 rst_flags;
+       u32 tmpReg;
+
+       if (AR_SREV_9100(ah)) {
+               u32 val = REG_READ(ah, AR_RTC_DERIVED_CLK);
+               val &= ~AR_RTC_DERIVED_CLK_PERIOD;
+               val |= SM(1, AR_RTC_DERIVED_CLK_PERIOD);
+               REG_WRITE(ah, AR_RTC_DERIVED_CLK, val);
+               (void)REG_READ(ah, AR_RTC_DERIVED_CLK);
+       }
+
+       REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN |
+                 AR_RTC_FORCE_WAKE_ON_INT);
+
+       if (AR_SREV_9100(ah)) {
+               rst_flags = AR_RTC_RC_MAC_WARM | AR_RTC_RC_MAC_COLD |
+                       AR_RTC_RC_COLD_RESET | AR_RTC_RC_WARM_RESET;
+       } else {
+               tmpReg = REG_READ(ah, AR_INTR_SYNC_CAUSE);
+               if (tmpReg &
+                   (AR_INTR_SYNC_LOCAL_TIMEOUT |
+                    AR_INTR_SYNC_RADM_CPL_TIMEOUT)) {
+                       REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0);
+                       REG_WRITE(ah, AR_RC, AR_RC_AHB | AR_RC_HOSTIF);
+               } else {
+                       REG_WRITE(ah, AR_RC, AR_RC_AHB);
+               }
+
+               rst_flags = AR_RTC_RC_MAC_WARM;
+               if (type == ATH9K_RESET_COLD)
+                       rst_flags |= AR_RTC_RC_MAC_COLD;
+       }
+
+       REG_WRITE(ah, AR_RTC_RC, rst_flags);
+       udelay(50);
+
+       REG_WRITE(ah, AR_RTC_RC, 0);
+       if (!ath9k_hw_wait(ah, AR_RTC_RC, AR_RTC_RC_M, 0, AH_WAIT_TIMEOUT)) {
+               DPRINTF(ah->ah_sc, ATH_DBG_RESET,
+                       "RTC stuck in MAC reset\n");
+               return false;
+       }
+
+       if (!AR_SREV_9100(ah))
+               REG_WRITE(ah, AR_RC, 0);
+
+       ath9k_hw_init_pll(ah, NULL);
+
+       if (AR_SREV_9100(ah))
+               udelay(50);
+
+       return true;
+}
+
+static bool ath9k_hw_set_reset_power_on(struct ath_hw *ah)
+{
+       REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN |
+                 AR_RTC_FORCE_WAKE_ON_INT);
+
+       REG_WRITE(ah, AR_RTC_RESET, 0);
+       udelay(2);
+       REG_WRITE(ah, AR_RTC_RESET, 1);
+
+       if (!ath9k_hw_wait(ah,
+                          AR_RTC_STATUS,
+                          AR_RTC_STATUS_M,
+                          AR_RTC_STATUS_ON,
+                          AH_WAIT_TIMEOUT)) {
+               DPRINTF(ah->ah_sc, ATH_DBG_RESET, "RTC not waking up\n");
+               return false;
+       }
+
+       ath9k_hw_read_revisions(ah);
+
+       return ath9k_hw_set_reset(ah, ATH9K_RESET_WARM);
+}
+
+static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type)
+{
+       REG_WRITE(ah, AR_RTC_FORCE_WAKE,
+                 AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT);
+
+       switch (type) {
+       case ATH9K_RESET_POWER_ON:
+               return ath9k_hw_set_reset_power_on(ah);
+       case ATH9K_RESET_WARM:
+       case ATH9K_RESET_COLD:
+               return ath9k_hw_set_reset(ah, type);
+       default:
+               return false;
+       }
+}
+
+static void ath9k_hw_set_regs(struct ath_hw *ah, struct ath9k_channel *chan,
+                             enum ath9k_ht_macmode macmode)
+{
+       u32 phymode;
+       u32 enableDacFifo = 0;
+
+       if (AR_SREV_9285_10_OR_LATER(ah))
+               enableDacFifo = (REG_READ(ah, AR_PHY_TURBO) &
+                                        AR_PHY_FC_ENABLE_DAC_FIFO);
+
+       phymode = AR_PHY_FC_HT_EN | AR_PHY_FC_SHORT_GI_40
+               | AR_PHY_FC_SINGLE_HT_LTF1 | AR_PHY_FC_WALSH | enableDacFifo;
+
+       if (IS_CHAN_HT40(chan)) {
+               phymode |= AR_PHY_FC_DYN2040_EN;
+
+               if ((chan->chanmode == CHANNEL_A_HT40PLUS) ||
+                   (chan->chanmode == CHANNEL_G_HT40PLUS))
+                       phymode |= AR_PHY_FC_DYN2040_PRI_CH;
+
+               if (ah->extprotspacing == ATH9K_HT_EXTPROTSPACING_25)
+                       phymode |= AR_PHY_FC_DYN2040_EXT_CH;
+       }
+       REG_WRITE(ah, AR_PHY_TURBO, phymode);
+
+       ath9k_hw_set11nmac2040(ah, macmode);
+
+       REG_WRITE(ah, AR_GTXTO, 25 << AR_GTXTO_TIMEOUT_LIMIT_S);
+       REG_WRITE(ah, AR_CST, 0xF << AR_CST_TIMEOUT_LIMIT_S);
+}
+
+static bool ath9k_hw_chip_reset(struct ath_hw *ah,
+                               struct ath9k_channel *chan)
+{
+       if (OLC_FOR_AR9280_20_LATER) {
+               if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON))
+                       return false;
+       } else if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM))
+               return false;
+
+       if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
+               return false;
+
+       ah->chip_fullsleep = false;
+       ath9k_hw_init_pll(ah, chan);
+       ath9k_hw_set_rfmode(ah, chan);
+
+       return true;
+}
+
+static bool ath9k_hw_channel_change(struct ath_hw *ah,
+                                   struct ath9k_channel *chan,
+                                   enum ath9k_ht_macmode macmode)
+{
+       struct ieee80211_channel *channel = chan->chan;
+       u32 synthDelay, qnum;
+
+       for (qnum = 0; qnum < AR_NUM_QCU; qnum++) {
+               if (ath9k_hw_numtxpending(ah, qnum)) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
+                               "Transmit frames pending on queue %d\n", qnum);
+                       return false;
+               }
+       }
+
+       REG_WRITE(ah, AR_PHY_RFBUS_REQ, AR_PHY_RFBUS_REQ_EN);
+       if (!ath9k_hw_wait(ah, AR_PHY_RFBUS_GRANT, AR_PHY_RFBUS_GRANT_EN,
+                          AR_PHY_RFBUS_GRANT_EN, AH_WAIT_TIMEOUT)) {
+               DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+                       "Could not kill baseband RX\n");
+               return false;
+       }
+
+       ath9k_hw_set_regs(ah, chan, macmode);
+
+       if (AR_SREV_9280_10_OR_LATER(ah)) {
+               ath9k_hw_ar9280_set_channel(ah, chan);
+       } else {
+               if (!(ath9k_hw_set_channel(ah, chan))) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+                               "Failed to set channel\n");
+                       return false;
+               }
+       }
+
+       ah->eep_ops->set_txpower(ah, chan,
+                            ath9k_regd_get_ctl(&ah->regulatory, chan),
+                            channel->max_antenna_gain * 2,
+                            channel->max_power * 2,
+                            min((u32) MAX_RATE_POWER,
+                            (u32) ah->regulatory.power_limit));
+
+       synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
+       if (IS_CHAN_B(chan))
+               synthDelay = (4 * synthDelay) / 22;
+       else
+               synthDelay /= 10;
+
+       udelay(synthDelay + BASE_ACTIVATE_DELAY);
+
+       REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0);
+
+       if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan))
+               ath9k_hw_set_delta_slope(ah, chan);
+
+       if (AR_SREV_9280_10_OR_LATER(ah))
+               ath9k_hw_9280_spur_mitigate(ah, chan);
+       else
+               ath9k_hw_spur_mitigate(ah, chan);
+
+       if (!chan->oneTimeCalsDone)
+               chan->oneTimeCalsDone = true;
+
+       return true;
+}
+
+static void ath9k_hw_9280_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan)
+{
+       int bb_spur = AR_NO_SPUR;
+       int freq;
+       int bin, cur_bin;
+       int bb_spur_off, spur_subchannel_sd;
+       int spur_freq_sd;
+       int spur_delta_phase;
+       int denominator;
+       int upper, lower, cur_vit_mask;
+       int tmp, newVal;
+       int i;
+       int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8,
+                         AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60
+       };
+       int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10,
+                        AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60
+       };
+       int inc[4] = { 0, 100, 0, 0 };
+       struct chan_centers centers;
+
+       int8_t mask_m[123];
+       int8_t mask_p[123];
+       int8_t mask_amt;
+       int tmp_mask;
+       int cur_bb_spur;
+       bool is2GHz = IS_CHAN_2GHZ(chan);
+
+       memset(&mask_m, 0, sizeof(int8_t) * 123);
+       memset(&mask_p, 0, sizeof(int8_t) * 123);
+
+       ath9k_hw_get_channel_centers(ah, chan, &centers);
+       freq = centers.synth_center;
+
+       ah->config.spurmode = SPUR_ENABLE_EEPROM;
+       for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
+               cur_bb_spur = ah->eep_ops->get_spur_channel(ah, i, is2GHz);
+
+               if (is2GHz)
+                       cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_2GHZ;
+               else
+                       cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_5GHZ;
+
+               if (AR_NO_SPUR == cur_bb_spur)
+                       break;
+               cur_bb_spur = cur_bb_spur - freq;
+
+               if (IS_CHAN_HT40(chan)) {
+                       if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT40) &&
+                           (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT40)) {
+                               bb_spur = cur_bb_spur;
+                               break;
+                       }
+               } else if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT20) &&
+                          (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT20)) {
+                       bb_spur = cur_bb_spur;
+                       break;
+               }
+       }
+
+       if (AR_NO_SPUR == bb_spur) {
+               REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK,
+                           AR_PHY_FORCE_CLKEN_CCK_MRC_MUX);
+               return;
+       } else {
+               REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK,
+                           AR_PHY_FORCE_CLKEN_CCK_MRC_MUX);
+       }
+
+       bin = bb_spur * 320;
+
+       tmp = REG_READ(ah, AR_PHY_TIMING_CTRL4(0));
+
+       newVal = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI |
+                       AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER |
+                       AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK |
+                       AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK);
+       REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0), newVal);
+
+       newVal = (AR_PHY_SPUR_REG_MASK_RATE_CNTL |
+                 AR_PHY_SPUR_REG_ENABLE_MASK_PPM |
+                 AR_PHY_SPUR_REG_MASK_RATE_SELECT |
+                 AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI |
+                 SM(SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH));
+       REG_WRITE(ah, AR_PHY_SPUR_REG, newVal);
+
+       if (IS_CHAN_HT40(chan)) {
+               if (bb_spur < 0) {
+                       spur_subchannel_sd = 1;
+                       bb_spur_off = bb_spur + 10;
+               } else {
+                       spur_subchannel_sd = 0;
+                       bb_spur_off = bb_spur - 10;
+               }
+       } else {
+               spur_subchannel_sd = 0;
+               bb_spur_off = bb_spur;
+       }
+
+       if (IS_CHAN_HT40(chan))
+               spur_delta_phase =
+                       ((bb_spur * 262144) /
+                        10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE;
+       else
+               spur_delta_phase =
+                       ((bb_spur * 524288) /
+                        10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE;
+
+       denominator = IS_CHAN_2GHZ(chan) ? 44 : 40;
+       spur_freq_sd = ((bb_spur_off * 2048) / denominator) & 0x3ff;
+
+       newVal = (AR_PHY_TIMING11_USE_SPUR_IN_AGC |
+                 SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) |
+                 SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE));
+       REG_WRITE(ah, AR_PHY_TIMING11, newVal);
+
+       newVal = spur_subchannel_sd << AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S;
+       REG_WRITE(ah, AR_PHY_SFCORR_EXT, newVal);
+
+       cur_bin = -6000;
+       upper = bin + 100;
+       lower = bin - 100;
+
+       for (i = 0; i < 4; i++) {
+               int pilot_mask = 0;
+               int chan_mask = 0;
+               int bp = 0;
+               for (bp = 0; bp < 30; bp++) {
+                       if ((cur_bin > lower) && (cur_bin < upper)) {
+                               pilot_mask = pilot_mask | 0x1 << bp;
+                               chan_mask = chan_mask | 0x1 << bp;
+                       }
+                       cur_bin += 100;
+               }
+               cur_bin += inc[i];
+               REG_WRITE(ah, pilot_mask_reg[i], pilot_mask);
+               REG_WRITE(ah, chan_mask_reg[i], chan_mask);
+       }
+
+       cur_vit_mask = 6100;
+       upper = bin + 120;
+       lower = bin - 120;
+
+       for (i = 0; i < 123; i++) {
+               if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
+
+                       /* workaround for gcc bug #37014 */
+                       volatile int tmp_v = abs(cur_vit_mask - bin);
+
+                       if (tmp_v < 75)
+                               mask_amt = 1;
+                       else
+                               mask_amt = 0;
+                       if (cur_vit_mask < 0)
+                               mask_m[abs(cur_vit_mask / 100)] = mask_amt;
+                       else
+                               mask_p[cur_vit_mask / 100] = mask_amt;
+               }
+               cur_vit_mask -= 100;
+       }
+
+       tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28)
+               | (mask_m[48] << 26) | (mask_m[49] << 24)
+               | (mask_m[50] << 22) | (mask_m[51] << 20)
+               | (mask_m[52] << 18) | (mask_m[53] << 16)
+               | (mask_m[54] << 14) | (mask_m[55] << 12)
+               | (mask_m[56] << 10) | (mask_m[57] << 8)
+               | (mask_m[58] << 6) | (mask_m[59] << 4)
+               | (mask_m[60] << 2) | (mask_m[61] << 0);
+       REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask);
+       REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask);
+
+       tmp_mask = (mask_m[31] << 28)
+               | (mask_m[32] << 26) | (mask_m[33] << 24)
+               | (mask_m[34] << 22) | (mask_m[35] << 20)
+               | (mask_m[36] << 18) | (mask_m[37] << 16)
+               | (mask_m[48] << 14) | (mask_m[39] << 12)
+               | (mask_m[40] << 10) | (mask_m[41] << 8)
+               | (mask_m[42] << 6) | (mask_m[43] << 4)
+               | (mask_m[44] << 2) | (mask_m[45] << 0);
+       REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask);
+       REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask);
+
+       tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28)
+               | (mask_m[18] << 26) | (mask_m[18] << 24)
+               | (mask_m[20] << 22) | (mask_m[20] << 20)
+               | (mask_m[22] << 18) | (mask_m[22] << 16)
+               | (mask_m[24] << 14) | (mask_m[24] << 12)
+               | (mask_m[25] << 10) | (mask_m[26] << 8)
+               | (mask_m[27] << 6) | (mask_m[28] << 4)
+               | (mask_m[29] << 2) | (mask_m[30] << 0);
+       REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask);
+       REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask);
+
+       tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28)
+               | (mask_m[2] << 26) | (mask_m[3] << 24)
+               | (mask_m[4] << 22) | (mask_m[5] << 20)
+               | (mask_m[6] << 18) | (mask_m[7] << 16)
+               | (mask_m[8] << 14) | (mask_m[9] << 12)
+               | (mask_m[10] << 10) | (mask_m[11] << 8)
+               | (mask_m[12] << 6) | (mask_m[13] << 4)
+               | (mask_m[14] << 2) | (mask_m[15] << 0);
+       REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask);
+       REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask);
+
+       tmp_mask = (mask_p[15] << 28)
+               | (mask_p[14] << 26) | (mask_p[13] << 24)
+               | (mask_p[12] << 22) | (mask_p[11] << 20)
+               | (mask_p[10] << 18) | (mask_p[9] << 16)
+               | (mask_p[8] << 14) | (mask_p[7] << 12)
+               | (mask_p[6] << 10) | (mask_p[5] << 8)
+               | (mask_p[4] << 6) | (mask_p[3] << 4)
+               | (mask_p[2] << 2) | (mask_p[1] << 0);
+       REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask);
+       REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask);
+
+       tmp_mask = (mask_p[30] << 28)
+               | (mask_p[29] << 26) | (mask_p[28] << 24)
+               | (mask_p[27] << 22) | (mask_p[26] << 20)
+               | (mask_p[25] << 18) | (mask_p[24] << 16)
+               | (mask_p[23] << 14) | (mask_p[22] << 12)
+               | (mask_p[21] << 10) | (mask_p[20] << 8)
+               | (mask_p[19] << 6) | (mask_p[18] << 4)
+               | (mask_p[17] << 2) | (mask_p[16] << 0);
+       REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask);
+       REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask);
+
+       tmp_mask = (mask_p[45] << 28)
+               | (mask_p[44] << 26) | (mask_p[43] << 24)
+               | (mask_p[42] << 22) | (mask_p[41] << 20)
+               | (mask_p[40] << 18) | (mask_p[39] << 16)
+               | (mask_p[38] << 14) | (mask_p[37] << 12)
+               | (mask_p[36] << 10) | (mask_p[35] << 8)
+               | (mask_p[34] << 6) | (mask_p[33] << 4)
+               | (mask_p[32] << 2) | (mask_p[31] << 0);
+       REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask);
+       REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask);
+
+       tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28)
+               | (mask_p[59] << 26) | (mask_p[58] << 24)
+               | (mask_p[57] << 22) | (mask_p[56] << 20)
+               | (mask_p[55] << 18) | (mask_p[54] << 16)
+               | (mask_p[53] << 14) | (mask_p[52] << 12)
+               | (mask_p[51] << 10) | (mask_p[50] << 8)
+               | (mask_p[49] << 6) | (mask_p[48] << 4)
+               | (mask_p[47] << 2) | (mask_p[46] << 0);
+       REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask);
+       REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
+}
+
+static void ath9k_hw_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan)
+{
+       int bb_spur = AR_NO_SPUR;
+       int bin, cur_bin;
+       int spur_freq_sd;
+       int spur_delta_phase;
+       int denominator;
+       int upper, lower, cur_vit_mask;
+       int tmp, new;
+       int i;
+       int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8,
+                         AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60
+       };
+       int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10,
+                        AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60
+       };
+       int inc[4] = { 0, 100, 0, 0 };
+
+       int8_t mask_m[123];
+       int8_t mask_p[123];
+       int8_t mask_amt;
+       int tmp_mask;
+       int cur_bb_spur;
+       bool is2GHz = IS_CHAN_2GHZ(chan);
+
+       memset(&mask_m, 0, sizeof(int8_t) * 123);
+       memset(&mask_p, 0, sizeof(int8_t) * 123);
+
+       for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
+               cur_bb_spur = ah->eep_ops->get_spur_channel(ah, i, is2GHz);
+               if (AR_NO_SPUR == cur_bb_spur)
+                       break;
+               cur_bb_spur = cur_bb_spur - (chan->channel * 10);
+               if ((cur_bb_spur > -95) && (cur_bb_spur < 95)) {
+                       bb_spur = cur_bb_spur;
+                       break;
+               }
+       }
+
+       if (AR_NO_SPUR == bb_spur)
+               return;
+
+       bin = bb_spur * 32;
+
+       tmp = REG_READ(ah, AR_PHY_TIMING_CTRL4(0));
+       new = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI |
+                    AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER |
+                    AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK |
+                    AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK);
+
+       REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0), new);
+
+       new = (AR_PHY_SPUR_REG_MASK_RATE_CNTL |
+              AR_PHY_SPUR_REG_ENABLE_MASK_PPM |
+              AR_PHY_SPUR_REG_MASK_RATE_SELECT |
+              AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI |
+              SM(SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH));
+       REG_WRITE(ah, AR_PHY_SPUR_REG, new);
+
+       spur_delta_phase = ((bb_spur * 524288) / 100) &
+               AR_PHY_TIMING11_SPUR_DELTA_PHASE;
+
+       denominator = IS_CHAN_2GHZ(chan) ? 440 : 400;
+       spur_freq_sd = ((bb_spur * 2048) / denominator) & 0x3ff;
+
+       new = (AR_PHY_TIMING11_USE_SPUR_IN_AGC |
+              SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) |
+              SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE));
+       REG_WRITE(ah, AR_PHY_TIMING11, new);
+
+       cur_bin = -6000;
+       upper = bin + 100;
+       lower = bin - 100;
+
+       for (i = 0; i < 4; i++) {
+               int pilot_mask = 0;
+               int chan_mask = 0;
+               int bp = 0;
+               for (bp = 0; bp < 30; bp++) {
+                       if ((cur_bin > lower) && (cur_bin < upper)) {
+                               pilot_mask = pilot_mask | 0x1 << bp;
+                               chan_mask = chan_mask | 0x1 << bp;
+                       }
+                       cur_bin += 100;
+               }
+               cur_bin += inc[i];
+               REG_WRITE(ah, pilot_mask_reg[i], pilot_mask);
+               REG_WRITE(ah, chan_mask_reg[i], chan_mask);
+       }
+
+       cur_vit_mask = 6100;
+       upper = bin + 120;
+       lower = bin - 120;
+
+       for (i = 0; i < 123; i++) {
+               if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
+
+                       /* workaround for gcc bug #37014 */
+                       volatile int tmp_v = abs(cur_vit_mask - bin);
+
+                       if (tmp_v < 75)
+                               mask_amt = 1;
+                       else
+                               mask_amt = 0;
+                       if (cur_vit_mask < 0)
+                               mask_m[abs(cur_vit_mask / 100)] = mask_amt;
+                       else
+                               mask_p[cur_vit_mask / 100] = mask_amt;
+               }
+               cur_vit_mask -= 100;
+       }
+
+       tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28)
+               | (mask_m[48] << 26) | (mask_m[49] << 24)
+               | (mask_m[50] << 22) | (mask_m[51] << 20)
+               | (mask_m[52] << 18) | (mask_m[53] << 16)
+               | (mask_m[54] << 14) | (mask_m[55] << 12)
+               | (mask_m[56] << 10) | (mask_m[57] << 8)
+               | (mask_m[58] << 6) | (mask_m[59] << 4)
+               | (mask_m[60] << 2) | (mask_m[61] << 0);
+       REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask);
+       REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask);
+
+       tmp_mask = (mask_m[31] << 28)
+               | (mask_m[32] << 26) | (mask_m[33] << 24)
+               | (mask_m[34] << 22) | (mask_m[35] << 20)
+               | (mask_m[36] << 18) | (mask_m[37] << 16)
+               | (mask_m[48] << 14) | (mask_m[39] << 12)
+               | (mask_m[40] << 10) | (mask_m[41] << 8)
+               | (mask_m[42] << 6) | (mask_m[43] << 4)
+               | (mask_m[44] << 2) | (mask_m[45] << 0);
+       REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask);
+       REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask);
+
+       tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28)
+               | (mask_m[18] << 26) | (mask_m[18] << 24)
+               | (mask_m[20] << 22) | (mask_m[20] << 20)
+               | (mask_m[22] << 18) | (mask_m[22] << 16)
+               | (mask_m[24] << 14) | (mask_m[24] << 12)
+               | (mask_m[25] << 10) | (mask_m[26] << 8)
+               | (mask_m[27] << 6) | (mask_m[28] << 4)
+               | (mask_m[29] << 2) | (mask_m[30] << 0);
+       REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask);
+       REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask);
+
+       tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28)
+               | (mask_m[2] << 26) | (mask_m[3] << 24)
+               | (mask_m[4] << 22) | (mask_m[5] << 20)
+               | (mask_m[6] << 18) | (mask_m[7] << 16)
+               | (mask_m[8] << 14) | (mask_m[9] << 12)
+               | (mask_m[10] << 10) | (mask_m[11] << 8)
+               | (mask_m[12] << 6) | (mask_m[13] << 4)
+               | (mask_m[14] << 2) | (mask_m[15] << 0);
+       REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask);
+       REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask);
+
+       tmp_mask = (mask_p[15] << 28)
+               | (mask_p[14] << 26) | (mask_p[13] << 24)
+               | (mask_p[12] << 22) | (mask_p[11] << 20)
+               | (mask_p[10] << 18) | (mask_p[9] << 16)
+               | (mask_p[8] << 14) | (mask_p[7] << 12)
+               | (mask_p[6] << 10) | (mask_p[5] << 8)
+               | (mask_p[4] << 6) | (mask_p[3] << 4)
+               | (mask_p[2] << 2) | (mask_p[1] << 0);
+       REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask);
+       REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask);
+
+       tmp_mask = (mask_p[30] << 28)
+               | (mask_p[29] << 26) | (mask_p[28] << 24)
+               | (mask_p[27] << 22) | (mask_p[26] << 20)
+               | (mask_p[25] << 18) | (mask_p[24] << 16)
+               | (mask_p[23] << 14) | (mask_p[22] << 12)
+               | (mask_p[21] << 10) | (mask_p[20] << 8)
+               | (mask_p[19] << 6) | (mask_p[18] << 4)
+               | (mask_p[17] << 2) | (mask_p[16] << 0);
+       REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask);
+       REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask);
+
+       tmp_mask = (mask_p[45] << 28)
+               | (mask_p[44] << 26) | (mask_p[43] << 24)
+               | (mask_p[42] << 22) | (mask_p[41] << 20)
+               | (mask_p[40] << 18) | (mask_p[39] << 16)
+               | (mask_p[38] << 14) | (mask_p[37] << 12)
+               | (mask_p[36] << 10) | (mask_p[35] << 8)
+               | (mask_p[34] << 6) | (mask_p[33] << 4)
+               | (mask_p[32] << 2) | (mask_p[31] << 0);
+       REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask);
+       REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask);
+
+       tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28)
+               | (mask_p[59] << 26) | (mask_p[58] << 24)
+               | (mask_p[57] << 22) | (mask_p[56] << 20)
+               | (mask_p[55] << 18) | (mask_p[54] << 16)
+               | (mask_p[53] << 14) | (mask_p[52] << 12)
+               | (mask_p[51] << 10) | (mask_p[50] << 8)
+               | (mask_p[49] << 6) | (mask_p[48] << 4)
+               | (mask_p[47] << 2) | (mask_p[46] << 0);
+       REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask);
+       REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
+}
+
+int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
+                   bool bChannelChange)
+{
+       u32 saveLedState;
+       struct ath_softc *sc = ah->ah_sc;
+       struct ath9k_channel *curchan = ah->curchan;
+       u32 saveDefAntenna;
+       u32 macStaId1;
+       int i, rx_chainmask, r;
+
+       ah->extprotspacing = sc->ht_extprotspacing;
+       ah->txchainmask = sc->tx_chainmask;
+       ah->rxchainmask = sc->rx_chainmask;
+
+       if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
+               return -EIO;
+
+       if (curchan)
+               ath9k_hw_getnf(ah, curchan);
+
+       if (bChannelChange &&
+           (ah->chip_fullsleep != true) &&
+           (ah->curchan != NULL) &&
+           (chan->channel != ah->curchan->channel) &&
+           ((chan->channelFlags & CHANNEL_ALL) ==
+            (ah->curchan->channelFlags & CHANNEL_ALL)) &&
+           (!AR_SREV_9280(ah) || (!IS_CHAN_A_5MHZ_SPACED(chan) &&
+                                  !IS_CHAN_A_5MHZ_SPACED(ah->curchan)))) {
+
+               if (ath9k_hw_channel_change(ah, chan, sc->tx_chan_width)) {
+                       ath9k_hw_loadnf(ah, ah->curchan);
+                       ath9k_hw_start_nfcal(ah);
+                       return 0;
+               }
+       }
+
+       saveDefAntenna = REG_READ(ah, AR_DEF_ANTENNA);
+       if (saveDefAntenna == 0)
+               saveDefAntenna = 1;
+
+       macStaId1 = REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_BASE_RATE_11B;
+
+       saveLedState = REG_READ(ah, AR_CFG_LED) &
+               (AR_CFG_LED_ASSOC_CTL | AR_CFG_LED_MODE_SEL |
+                AR_CFG_LED_BLINK_THRESH_SEL | AR_CFG_LED_BLINK_SLOW);
+
+       ath9k_hw_mark_phy_inactive(ah);
+
+       if (!ath9k_hw_chip_reset(ah, chan)) {
+               DPRINTF(ah->ah_sc, ATH_DBG_FATAL, "Chip reset failed\n");
+               return -EINVAL;
+       }
+
+       if (AR_SREV_9280_10_OR_LATER(ah))
+               REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE);
+
+       r = ath9k_hw_process_ini(ah, chan, sc->tx_chan_width);
+       if (r)
+               return r;
+
+       /* Setup MFP options for CCMP */
+       if (AR_SREV_9280_20_OR_LATER(ah)) {
+               /* Mask Retry(b11), PwrMgt(b12), MoreData(b13) to 0 in mgmt
+                * frames when constructing CCMP AAD. */
+               REG_RMW_FIELD(ah, AR_AES_MUTE_MASK1, AR_AES_MUTE_MASK1_FC_MGMT,
+                             0xc7ff);
+               ah->sw_mgmt_crypto = false;
+       } else if (AR_SREV_9160_10_OR_LATER(ah)) {
+               /* Disable hardware crypto for management frames */
+               REG_CLR_BIT(ah, AR_PCU_MISC_MODE2,
+                           AR_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE);
+               REG_SET_BIT(ah, AR_PCU_MISC_MODE2,
+                           AR_PCU_MISC_MODE2_NO_CRYPTO_FOR_NON_DATA_PKT);
+               ah->sw_mgmt_crypto = true;
+       } else
+               ah->sw_mgmt_crypto = true;
+
+       if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan))
+               ath9k_hw_set_delta_slope(ah, chan);
+
+       if (AR_SREV_9280_10_OR_LATER(ah))
+               ath9k_hw_9280_spur_mitigate(ah, chan);
+       else
+               ath9k_hw_spur_mitigate(ah, chan);
+
+       ah->eep_ops->set_board_values(ah, chan);
+
+       ath9k_hw_decrease_chain_power(ah, chan);
+
+       REG_WRITE(ah, AR_STA_ID0, get_unaligned_le32(ah->macaddr));
+       REG_WRITE(ah, AR_STA_ID1, get_unaligned_le16(ah->macaddr + 4)
+                 | macStaId1
+                 | AR_STA_ID1_RTS_USE_DEF
+                 | (ah->config.
+                    ack_6mb ? AR_STA_ID1_ACKCTS_6MB : 0)
+                 | ah->sta_id1_defaults);
+       ath9k_hw_set_operating_mode(ah, ah->opmode);
+
+       REG_WRITE(ah, AR_BSSMSKL, get_unaligned_le32(sc->bssidmask));
+       REG_WRITE(ah, AR_BSSMSKU, get_unaligned_le16(sc->bssidmask + 4));
+
+       REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna);
+
+       REG_WRITE(ah, AR_BSS_ID0, get_unaligned_le32(sc->curbssid));
+       REG_WRITE(ah, AR_BSS_ID1, get_unaligned_le16(sc->curbssid + 4) |
+                 ((sc->curaid & 0x3fff) << AR_BSS_ID1_AID_S));
+
+       REG_WRITE(ah, AR_ISR, ~0);
+
+       REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR);
+
+       if (AR_SREV_9280_10_OR_LATER(ah))
+               ath9k_hw_ar9280_set_channel(ah, chan);
+       else
+               if (!(ath9k_hw_set_channel(ah, chan)))
+                       return -EIO;
+
+       for (i = 0; i < AR_NUM_DCU; i++)
+               REG_WRITE(ah, AR_DQCUMASK(i), 1 << i);
+
+       ah->intr_txqs = 0;
+       for (i = 0; i < ah->caps.total_queues; i++)
+               ath9k_hw_resettxqueue(ah, i);
+
+       ath9k_hw_init_interrupt_masks(ah, ah->opmode);
+       ath9k_hw_init_qos(ah);
+
+#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
+       if (ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
+               ath9k_enable_rfkill(ah);
+#endif
+       ath9k_hw_init_user_settings(ah);
+
+       REG_WRITE(ah, AR_STA_ID1,
+                 REG_READ(ah, AR_STA_ID1) | AR_STA_ID1_PRESERVE_SEQNUM);
+
+       ath9k_hw_set_dma(ah);
+
+       REG_WRITE(ah, AR_OBS, 8);
+
+       if (ah->config.intr_mitigation) {
+               REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 500);
+               REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, 2000);
+       }
+
+       ath9k_hw_init_bb(ah, chan);
+
+       if (!ath9k_hw_init_cal(ah, chan))
+               return -EIO;;
+
+       rx_chainmask = ah->rxchainmask;
+       if ((rx_chainmask == 0x5) || (rx_chainmask == 0x3)) {
+               REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
+               REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
+       }
+
+       REG_WRITE(ah, AR_CFG_LED, saveLedState | AR_CFG_SCLK_32KHZ);
+
+       if (AR_SREV_9100(ah)) {
+               u32 mask;
+               mask = REG_READ(ah, AR_CFG);
+               if (mask & (AR_CFG_SWRB | AR_CFG_SWTB | AR_CFG_SWRG)) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_RESET,
+                               "CFG Byte Swap Set 0x%x\n", mask);
+               } else {
+                       mask =
+                               INIT_CONFIG_STATUS | AR_CFG_SWRB | AR_CFG_SWTB;
+                       REG_WRITE(ah, AR_CFG, mask);
+                       DPRINTF(ah->ah_sc, ATH_DBG_RESET,
+                               "Setting CFG 0x%x\n", REG_READ(ah, AR_CFG));
+               }
+       } else {
+#ifdef __BIG_ENDIAN
+               REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD);
+#endif
+       }
+
+       return 0;
+}
+
+/************************/
+/* Key Cache Management */
+/************************/
+
+bool ath9k_hw_keyreset(struct ath_hw *ah, u16 entry)
+{
+       u32 keyType;
+
+       if (entry >= ah->caps.keycache_size) {
+               DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+                       "keychache entry %u out of range\n", entry);
+               return false;
+       }
+
+       keyType = REG_READ(ah, AR_KEYTABLE_TYPE(entry));
+
+       REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), 0);
+       REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), 0);
+       REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), 0);
+       REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), 0);
+       REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), 0);
+       REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), AR_KEYTABLE_TYPE_CLR);
+       REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), 0);
+       REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), 0);
+
+       if (keyType == AR_KEYTABLE_TYPE_TKIP && ATH9K_IS_MIC_ENABLED(ah)) {
+               u16 micentry = entry + 64;
+
+               REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), 0);
+               REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
+               REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), 0);
+               REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0);
+
+       }
+
+       if (ah->curchan == NULL)
+               return true;
+
+       return true;
+}
+
+bool ath9k_hw_keysetmac(struct ath_hw *ah, u16 entry, const u8 *mac)
+{
+       u32 macHi, macLo;
+
+       if (entry >= ah->caps.keycache_size) {
+               DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+                       "keychache entry %u out of range\n", entry);
+               return false;
+       }
+
+       if (mac != NULL) {
+               macHi = (mac[5] << 8) | mac[4];
+               macLo = (mac[3] << 24) |
+                       (mac[2] << 16) |
+                       (mac[1] << 8) |
+                       mac[0];
+               macLo >>= 1;
+               macLo |= (macHi & 1) << 31;
+               macHi >>= 1;
+       } else {
+               macLo = macHi = 0;
+       }
+       REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), macLo);
+       REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), macHi | AR_KEYTABLE_VALID);
+
+       return true;
+}
+
+bool ath9k_hw_set_keycache_entry(struct ath_hw *ah, u16 entry,
+                                const struct ath9k_keyval *k,
+                                const u8 *mac)
+{
+       const struct ath9k_hw_capabilities *pCap = &ah->caps;
+       u32 key0, key1, key2, key3, key4;
+       u32 keyType;
+
+       if (entry >= pCap->keycache_size) {
+               DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+                       "keycache entry %u out of range\n", entry);
+               return false;
+       }
+
+       switch (k->kv_type) {
+       case ATH9K_CIPHER_AES_OCB:
+               keyType = AR_KEYTABLE_TYPE_AES;
+               break;
+       case ATH9K_CIPHER_AES_CCM:
+               if (!(pCap->hw_caps & ATH9K_HW_CAP_CIPHER_AESCCM)) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_ANY,
+                               "AES-CCM not supported by mac rev 0x%x\n",
+                               ah->hw_version.macRev);
+                       return false;
+               }
+               keyType = AR_KEYTABLE_TYPE_CCM;
+               break;
+       case ATH9K_CIPHER_TKIP:
+               keyType = AR_KEYTABLE_TYPE_TKIP;
+               if (ATH9K_IS_MIC_ENABLED(ah)
+                   && entry + 64 >= pCap->keycache_size) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_ANY,
+                               "entry %u inappropriate for TKIP\n", entry);
+                       return false;
+               }
+               break;
+       case ATH9K_CIPHER_WEP:
+               if (k->kv_len < WLAN_KEY_LEN_WEP40) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_ANY,
+                               "WEP key length %u too small\n", k->kv_len);
+                       return false;
+               }
+               if (k->kv_len <= WLAN_KEY_LEN_WEP40)
+                       keyType = AR_KEYTABLE_TYPE_40;
+               else if (k->kv_len <= WLAN_KEY_LEN_WEP104)
+                       keyType = AR_KEYTABLE_TYPE_104;
+               else
+                       keyType = AR_KEYTABLE_TYPE_128;
+               break;
+       case ATH9K_CIPHER_CLR:
+               keyType = AR_KEYTABLE_TYPE_CLR;
+               break;
+       default:
+               DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+                       "cipher %u not supported\n", k->kv_type);
+               return false;
+       }
+
+       key0 = get_unaligned_le32(k->kv_val + 0);
+       key1 = get_unaligned_le16(k->kv_val + 4);
+       key2 = get_unaligned_le32(k->kv_val + 6);
+       key3 = get_unaligned_le16(k->kv_val + 10);
+       key4 = get_unaligned_le32(k->kv_val + 12);
+       if (k->kv_len <= WLAN_KEY_LEN_WEP104)
+               key4 &= 0xff;
+
+       /*
+        * Note: Key cache registers access special memory area that requires
+        * two 32-bit writes to actually update the values in the internal
+        * memory. Consequently, the exact order and pairs used here must be
+        * maintained.
+        */
+
+       if (keyType == AR_KEYTABLE_TYPE_TKIP && ATH9K_IS_MIC_ENABLED(ah)) {
+               u16 micentry = entry + 64;
+
+               /*
+                * Write inverted key[47:0] first to avoid Michael MIC errors
+                * on frames that could be sent or received at the same time.
+                * The correct key will be written in the end once everything
+                * else is ready.
+                */
+               REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), ~key0);
+               REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), ~key1);
+
+               /* Write key[95:48] */
+               REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);
+               REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);
+
+               /* Write key[127:96] and key type */
+               REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
+               REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType);
+
+               /* Write MAC address for the entry */
+               (void) ath9k_hw_keysetmac(ah, entry, mac);
+
+               if (ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA) {
+                       /*
+                        * TKIP uses two key cache entries:
+                        * Michael MIC TX/RX keys in the same key cache entry
+                        * (idx = main index + 64):
+                        * key0 [31:0] = RX key [31:0]
+                        * key1 [15:0] = TX key [31:16]
+                        * key1 [31:16] = reserved
+                        * key2 [31:0] = RX key [63:32]
+                        * key3 [15:0] = TX key [15:0]
+                        * key3 [31:16] = reserved
+                        * key4 [31:0] = TX key [63:32]
+                        */
+                       u32 mic0, mic1, mic2, mic3, mic4;
+
+                       mic0 = get_unaligned_le32(k->kv_mic + 0);
+                       mic2 = get_unaligned_le32(k->kv_mic + 4);
+                       mic1 = get_unaligned_le16(k->kv_txmic + 2) & 0xffff;
+                       mic3 = get_unaligned_le16(k->kv_txmic + 0) & 0xffff;
+                       mic4 = get_unaligned_le32(k->kv_txmic + 4);
+
+                       /* Write RX[31:0] and TX[31:16] */
+                       REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
+                       REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), mic1);
+
+                       /* Write RX[63:32] and TX[15:0] */
+                       REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2);
+                       REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), mic3);
+
+                       /* Write TX[63:32] and keyType(reserved) */
+                       REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), mic4);
+                       REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
+                                 AR_KEYTABLE_TYPE_CLR);
+
+               } else {
+                       /*
+                        * TKIP uses four key cache entries (two for group
+                        * keys):
+                        * Michael MIC TX/RX keys are in different key cache
+                        * entries (idx = main index + 64 for TX and
+                        * main index + 32 + 96 for RX):
+                        * key0 [31:0] = TX/RX MIC key [31:0]
+                        * key1 [31:0] = reserved
+                        * key2 [31:0] = TX/RX MIC key [63:32]
+                        * key3 [31:0] = reserved
+                        * key4 [31:0] = reserved
+                        *
+                        * Upper layer code will call this function separately
+                        * for TX and RX keys when these registers offsets are
+                        * used.
+                        */
+                       u32 mic0, mic2;
+
+                       mic0 = get_unaligned_le32(k->kv_mic + 0);
+                       mic2 = get_unaligned_le32(k->kv_mic + 4);
+
+                       /* Write MIC key[31:0] */
+                       REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
+                       REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
+
+                       /* Write MIC key[63:32] */
+                       REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2);
+                       REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0);
+
+                       /* Write TX[63:32] and keyType(reserved) */
+                       REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), 0);
+                       REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
+                                 AR_KEYTABLE_TYPE_CLR);
+               }
+
+               /* MAC address registers are reserved for the MIC entry */
+               REG_WRITE(ah, AR_KEYTABLE_MAC0(micentry), 0);
+               REG_WRITE(ah, AR_KEYTABLE_MAC1(micentry), 0);
+
+               /*
+                * Write the correct (un-inverted) key[47:0] last to enable
+                * TKIP now that all other registers are set with correct
+                * values.
+                */
+               REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
+               REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
+       } else {
+               /* Write key[47:0] */
+               REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
+               REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
+
+               /* Write key[95:48] */
+               REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);
+               REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);
+
+               /* Write key[127:96] and key type */
+               REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
+               REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType);
+
+               /* Write MAC address for the entry */
+               (void) ath9k_hw_keysetmac(ah, entry, mac);
+       }
+
+       return true;
+}
+
+bool ath9k_hw_keyisvalid(struct ath_hw *ah, u16 entry)
+{
+       if (entry < ah->caps.keycache_size) {
+               u32 val = REG_READ(ah, AR_KEYTABLE_MAC1(entry));
+               if (val & AR_KEYTABLE_VALID)
+                       return true;
+       }
+       return false;
+}
+
+/******************************/
+/* Power Management (Chipset) */
+/******************************/
+
+static void ath9k_set_power_sleep(struct ath_hw *ah, int setChip)
+{
+       REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
+       if (setChip) {
+               REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE,
+                           AR_RTC_FORCE_WAKE_EN);
+               if (!AR_SREV_9100(ah))
+                       REG_WRITE(ah, AR_RC, AR_RC_AHB | AR_RC_HOSTIF);
+
+               REG_CLR_BIT(ah, (AR_RTC_RESET),
+                           AR_RTC_RESET_EN);
+       }
+}
+
+static void ath9k_set_power_network_sleep(struct ath_hw *ah, int setChip)
+{
+       REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
+       if (setChip) {
+               struct ath9k_hw_capabilities *pCap = &ah->caps;
+
+               if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
+                       REG_WRITE(ah, AR_RTC_FORCE_WAKE,
+                                 AR_RTC_FORCE_WAKE_ON_INT);
+               } else {
+                       REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE,
+                                   AR_RTC_FORCE_WAKE_EN);
+               }
+       }
+}
+
+static bool ath9k_hw_set_power_awake(struct ath_hw *ah, int setChip)
+{
+       u32 val;
+       int i;
+
+       if (setChip) {
+               if ((REG_READ(ah, AR_RTC_STATUS) &
+                    AR_RTC_STATUS_M) == AR_RTC_STATUS_SHUTDOWN) {
+                       if (ath9k_hw_set_reset_reg(ah,
+                                          ATH9K_RESET_POWER_ON) != true) {
+                               return false;
+                       }
+               }
+               if (AR_SREV_9100(ah))
+                       REG_SET_BIT(ah, AR_RTC_RESET,
+                                   AR_RTC_RESET_EN);
+
+               REG_SET_BIT(ah, AR_RTC_FORCE_WAKE,
+                           AR_RTC_FORCE_WAKE_EN);
+               udelay(50);
+
+               for (i = POWER_UP_TIME / 50; i > 0; i--) {
+                       val = REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M;
+                       if (val == AR_RTC_STATUS_ON)
+                               break;
+                       udelay(50);
+                       REG_SET_BIT(ah, AR_RTC_FORCE_WAKE,
+                                   AR_RTC_FORCE_WAKE_EN);
+               }
+               if (i == 0) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+                               "Failed to wakeup in %uus\n", POWER_UP_TIME / 20);
+                       return false;
+               }
+       }
+
+       REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
+
+       return true;
+}
+
+bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode)
+{
+       int status = true, setChip = true;
+       static const char *modes[] = {
+               "AWAKE",
+               "FULL-SLEEP",
+               "NETWORK SLEEP",
+               "UNDEFINED"
+       };
+
+       DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s -> %s\n",
+               modes[ah->power_mode], modes[mode]);
+
+       switch (mode) {
+       case ATH9K_PM_AWAKE:
+               status = ath9k_hw_set_power_awake(ah, setChip);
+               break;
+       case ATH9K_PM_FULL_SLEEP:
+               ath9k_set_power_sleep(ah, setChip);
+               ah->chip_fullsleep = true;
+               break;
+       case ATH9K_PM_NETWORK_SLEEP:
+               ath9k_set_power_network_sleep(ah, setChip);
+               break;
+       default:
+               DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+                       "Unknown power mode %u\n", mode);
+               return false;
+       }
+       ah->power_mode = mode;
+
+       return status;
+}
+
+/*
+ * Helper for ASPM support.
+ *
+ * Disable PLL when in L0s as well as receiver clock when in L1.
+ * This power saving option must be enabled through the SerDes.
+ *
+ * Programming the SerDes must go through the same 288 bit serial shift
+ * register as the other analog registers.  Hence the 9 writes.
+ */
+void ath9k_hw_configpcipowersave(struct ath_hw *ah, int restore)
+{
+       u8 i;
+
+       if (ah->is_pciexpress != true)
+               return;
+
+       /* Do not touch SerDes registers */
+       if (ah->config.pcie_powersave_enable == 2)
+               return;
+
+       /* Nothing to do on restore for 11N */
+       if (restore)
+               return;
+
+       if (AR_SREV_9280_20_OR_LATER(ah)) {
+               /*
+                * AR9280 2.0 or later chips use SerDes values from the
+                * initvals.h initialized depending on chipset during
+                * ath9k_hw_do_attach()
+                */
+               for (i = 0; i < ah->iniPcieSerdes.ia_rows; i++) {
+                       REG_WRITE(ah, INI_RA(&ah->iniPcieSerdes, i, 0),
+                                 INI_RA(&ah->iniPcieSerdes, i, 1));
+               }
+       } else if (AR_SREV_9280(ah) &&
+                  (ah->hw_version.macRev == AR_SREV_REVISION_9280_10)) {
+               REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fd00);
+               REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
+
+               /* RX shut off when elecidle is asserted */
+               REG_WRITE(ah, AR_PCIE_SERDES, 0xa8000019);
+               REG_WRITE(ah, AR_PCIE_SERDES, 0x13160820);
+               REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980560);
+
+               /* Shut off CLKREQ active in L1 */
+               if (ah->config.pcie_clock_req)
+                       REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffc);
+               else
+                       REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffd);
+
+               REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
+               REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
+               REG_WRITE(ah, AR_PCIE_SERDES, 0x00043007);
+
+               /* Load the new settings */
+               REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
+
+       } else {
+               REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00);
+               REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
+
+               /* RX shut off when elecidle is asserted */
+               REG_WRITE(ah, AR_PCIE_SERDES, 0x28000039);
+               REG_WRITE(ah, AR_PCIE_SERDES, 0x53160824);
+               REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980579);
+
+               /*
+                * Ignore ah->ah_config.pcie_clock_req setting for
+                * pre-AR9280 11n
+                */
+               REG_WRITE(ah, AR_PCIE_SERDES, 0x001defff);
+
+               REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
+               REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
+               REG_WRITE(ah, AR_PCIE_SERDES, 0x000e3007);
+
+               /* Load the new settings */
+               REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
+       }
+
+       udelay(1000);
+
+       /* 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);
+
+       /* Several PCIe massages to ensure proper behaviour */
+       if (ah->config.pcie_waen) {
+               REG_WRITE(ah, AR_WA, ah->config.pcie_waen);
+       } else {
+               if (AR_SREV_9285(ah))
+                       REG_WRITE(ah, AR_WA, AR9285_WA_DEFAULT);
+               /*
+                * On AR9280 chips bit 22 of 0x4004 needs to be set to
+                * otherwise card may disappear.
+                */
+               else if (AR_SREV_9280(ah))
+                       REG_WRITE(ah, AR_WA, AR9280_WA_DEFAULT);
+               else
+                       REG_WRITE(ah, AR_WA, AR_WA_DEFAULT);
+       }
+}
+
+/**********************/
+/* Interrupt Handling */
+/**********************/
+
+bool ath9k_hw_intrpend(struct ath_hw *ah)
+{
+       u32 host_isr;
+
+       if (AR_SREV_9100(ah))
+               return true;
+
+       host_isr = REG_READ(ah, AR_INTR_ASYNC_CAUSE);
+       if ((host_isr & AR_INTR_MAC_IRQ) && (host_isr != AR_INTR_SPURIOUS))
+               return true;
+
+       host_isr = REG_READ(ah, AR_INTR_SYNC_CAUSE);
+       if ((host_isr & AR_INTR_SYNC_DEFAULT)
+           && (host_isr != AR_INTR_SPURIOUS))
+               return true;
+
+       return false;
+}
+
+bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked)
+{
+       u32 isr = 0;
+       u32 mask2 = 0;
+       struct ath9k_hw_capabilities *pCap = &ah->caps;
+       u32 sync_cause = 0;
+       bool fatal_int = false;
+
+       if (!AR_SREV_9100(ah)) {
+               if (REG_READ(ah, AR_INTR_ASYNC_CAUSE) & AR_INTR_MAC_IRQ) {
+                       if ((REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M)
+                           == AR_RTC_STATUS_ON) {
+                               isr = REG_READ(ah, AR_ISR);
+                       }
+               }
+
+               sync_cause = REG_READ(ah, AR_INTR_SYNC_CAUSE) &
+                       AR_INTR_SYNC_DEFAULT;
+
+               *masked = 0;
+
+               if (!isr && !sync_cause)
+                       return false;
+       } else {
+               *masked = 0;
+               isr = REG_READ(ah, AR_ISR);
+       }
+
+       if (isr) {
+               if (isr & AR_ISR_BCNMISC) {
+                       u32 isr2;
+                       isr2 = REG_READ(ah, AR_ISR_S2);
+                       if (isr2 & AR_ISR_S2_TIM)
+                               mask2 |= ATH9K_INT_TIM;
+                       if (isr2 & AR_ISR_S2_DTIM)
+                               mask2 |= ATH9K_INT_DTIM;
+                       if (isr2 & AR_ISR_S2_DTIMSYNC)
+                               mask2 |= ATH9K_INT_DTIMSYNC;
+                       if (isr2 & (AR_ISR_S2_CABEND))
+                               mask2 |= ATH9K_INT_CABEND;
+                       if (isr2 & AR_ISR_S2_GTT)
+                               mask2 |= ATH9K_INT_GTT;
+                       if (isr2 & AR_ISR_S2_CST)
+                               mask2 |= ATH9K_INT_CST;
+                       if (isr2 & AR_ISR_S2_TSFOOR)
+                               mask2 |= ATH9K_INT_TSFOOR;
+               }
+
+               isr = REG_READ(ah, AR_ISR_RAC);
+               if (isr == 0xffffffff) {
+                       *masked = 0;
+                       return false;
+               }
+
+               *masked = isr & ATH9K_INT_COMMON;
+
+               if (ah->config.intr_mitigation) {
+                       if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM))
+                               *masked |= ATH9K_INT_RX;
+               }
+
+               if (isr & (AR_ISR_RXOK | AR_ISR_RXERR))
+                       *masked |= ATH9K_INT_RX;
+               if (isr &
+                   (AR_ISR_TXOK | AR_ISR_TXDESC | AR_ISR_TXERR |
+                    AR_ISR_TXEOL)) {
+                       u32 s0_s, s1_s;
+
+                       *masked |= ATH9K_INT_TX;
+
+                       s0_s = REG_READ(ah, AR_ISR_S0_S);
+                       ah->intr_txqs |= MS(s0_s, AR_ISR_S0_QCU_TXOK);
+                       ah->intr_txqs |= MS(s0_s, AR_ISR_S0_QCU_TXDESC);
+
+                       s1_s = REG_READ(ah, AR_ISR_S1_S);
+                       ah->intr_txqs |= MS(s1_s, AR_ISR_S1_QCU_TXERR);
+                       ah->intr_txqs |= MS(s1_s, AR_ISR_S1_QCU_TXEOL);
+               }
+
+               if (isr & AR_ISR_RXORN) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
+                               "receive FIFO overrun interrupt\n");
+               }
+
+               if (!AR_SREV_9100(ah)) {
+                       if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
+                               u32 isr5 = REG_READ(ah, AR_ISR_S5_S);
+                               if (isr5 & AR_ISR_S5_TIM_TIMER)
+                                       *masked |= ATH9K_INT_TIM_TIMER;
+                       }
+               }
+
+               *masked |= mask2;
+       }
+
+       if (AR_SREV_9100(ah))
+               return true;
+
+       if (sync_cause) {
+               fatal_int =
+                       (sync_cause &
+                        (AR_INTR_SYNC_HOST1_FATAL | AR_INTR_SYNC_HOST1_PERR))
+                       ? true : false;
+
+               if (fatal_int) {
+                       if (sync_cause & AR_INTR_SYNC_HOST1_FATAL) {
+                               DPRINTF(ah->ah_sc, ATH_DBG_ANY,
+                                       "received PCI FATAL interrupt\n");
+                       }
+                       if (sync_cause & AR_INTR_SYNC_HOST1_PERR) {
+                               DPRINTF(ah->ah_sc, ATH_DBG_ANY,
+                                       "received PCI PERR interrupt\n");
+                       }
+                       *masked |= ATH9K_INT_FATAL;
+               }
+               if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
+                               "AR_INTR_SYNC_RADM_CPL_TIMEOUT\n");
+                       REG_WRITE(ah, AR_RC, AR_RC_HOSTIF);
+                       REG_WRITE(ah, AR_RC, 0);
+                       *masked |= ATH9K_INT_FATAL;
+               }
+               if (sync_cause & AR_INTR_SYNC_LOCAL_TIMEOUT) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
+                               "AR_INTR_SYNC_LOCAL_TIMEOUT\n");
+               }
+
+               REG_WRITE(ah, AR_INTR_SYNC_CAUSE_CLR, sync_cause);
+               (void) REG_READ(ah, AR_INTR_SYNC_CAUSE_CLR);
+       }
+
+       return true;
+}
+
+enum ath9k_int ath9k_hw_intrget(struct ath_hw *ah)
+{
+       return ah->mask_reg;
+}
+
+enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints)
+{
+       u32 omask = ah->mask_reg;
+       u32 mask, mask2;
+       struct ath9k_hw_capabilities *pCap = &ah->caps;
+
+       DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "0x%x => 0x%x\n", omask, ints);
+
+       if (omask & ATH9K_INT_GLOBAL) {
+               DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "disable IER\n");
+               REG_WRITE(ah, AR_IER, AR_IER_DISABLE);
+               (void) REG_READ(ah, AR_IER);
+               if (!AR_SREV_9100(ah)) {
+                       REG_WRITE(ah, AR_INTR_ASYNC_ENABLE, 0);
+                       (void) REG_READ(ah, AR_INTR_ASYNC_ENABLE);
+
+                       REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0);
+                       (void) REG_READ(ah, AR_INTR_SYNC_ENABLE);
+               }
+       }
+
+       mask = ints & ATH9K_INT_COMMON;
+       mask2 = 0;
+
+       if (ints & ATH9K_INT_TX) {
+               if (ah->txok_interrupt_mask)
+                       mask |= AR_IMR_TXOK;
+               if (ah->txdesc_interrupt_mask)
+                       mask |= AR_IMR_TXDESC;
+               if (ah->txerr_interrupt_mask)
+                       mask |= AR_IMR_TXERR;
+               if (ah->txeol_interrupt_mask)
+                       mask |= AR_IMR_TXEOL;
+       }
+       if (ints & ATH9K_INT_RX) {
+               mask |= AR_IMR_RXERR;
+               if (ah->config.intr_mitigation)
+                       mask |= AR_IMR_RXMINTR | AR_IMR_RXINTM;
+               else
+                       mask |= AR_IMR_RXOK | AR_IMR_RXDESC;
+               if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
+                       mask |= AR_IMR_GENTMR;
+       }
+
+       if (ints & (ATH9K_INT_BMISC)) {
+               mask |= AR_IMR_BCNMISC;
+               if (ints & ATH9K_INT_TIM)
+                       mask2 |= AR_IMR_S2_TIM;
+               if (ints & ATH9K_INT_DTIM)
+                       mask2 |= AR_IMR_S2_DTIM;
+               if (ints & ATH9K_INT_DTIMSYNC)
+                       mask2 |= AR_IMR_S2_DTIMSYNC;
+               if (ints & ATH9K_INT_CABEND)
+                       mask2 |= AR_IMR_S2_CABEND;
+               if (ints & ATH9K_INT_TSFOOR)
+                       mask2 |= AR_IMR_S2_TSFOOR;
+       }
+
+       if (ints & (ATH9K_INT_GTT | ATH9K_INT_CST)) {
+               mask |= AR_IMR_BCNMISC;
+               if (ints & ATH9K_INT_GTT)
+                       mask2 |= AR_IMR_S2_GTT;
+               if (ints & ATH9K_INT_CST)
+                       mask2 |= AR_IMR_S2_CST;
+       }
+
+       DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "new IMR 0x%x\n", mask);
+       REG_WRITE(ah, AR_IMR, mask);
+       mask = REG_READ(ah, AR_IMR_S2) & ~(AR_IMR_S2_TIM |
+                                          AR_IMR_S2_DTIM |
+                                          AR_IMR_S2_DTIMSYNC |
+                                          AR_IMR_S2_CABEND |
+                                          AR_IMR_S2_CABTO |
+                                          AR_IMR_S2_TSFOOR |
+                                          AR_IMR_S2_GTT | AR_IMR_S2_CST);
+       REG_WRITE(ah, AR_IMR_S2, mask | mask2);
+       ah->mask_reg = ints;
+
+       if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
+               if (ints & ATH9K_INT_TIM_TIMER)
+                       REG_SET_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);
+               else
+                       REG_CLR_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);
+       }
+
+       if (ints & ATH9K_INT_GLOBAL) {
+               DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "enable IER\n");
+               REG_WRITE(ah, AR_IER, AR_IER_ENABLE);
+               if (!AR_SREV_9100(ah)) {
+                       REG_WRITE(ah, AR_INTR_ASYNC_ENABLE,
+                                 AR_INTR_MAC_IRQ);
+                       REG_WRITE(ah, AR_INTR_ASYNC_MASK, AR_INTR_MAC_IRQ);
+
+
+                       REG_WRITE(ah, AR_INTR_SYNC_ENABLE,
+                                 AR_INTR_SYNC_DEFAULT);
+                       REG_WRITE(ah, AR_INTR_SYNC_MASK,
+                                 AR_INTR_SYNC_DEFAULT);
+               }
+               DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "AR_IMR 0x%x IER 0x%x\n",
+                        REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER));
+       }
+
+       return omask;
+}
+
+/*******************/
+/* Beacon Handling */
+/*******************/
+
+void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period)
+{
+       int flags = 0;
+
+       ah->beacon_interval = beacon_period;
+
+       switch (ah->opmode) {
+       case NL80211_IFTYPE_STATION:
+       case NL80211_IFTYPE_MONITOR:
+               REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon));
+               REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, 0xffff);
+               REG_WRITE(ah, AR_NEXT_SWBA, 0x7ffff);
+               flags |= AR_TBTT_TIMER_EN;
+               break;
+       case NL80211_IFTYPE_ADHOC:
+       case NL80211_IFTYPE_MESH_POINT:
+               REG_SET_BIT(ah, AR_TXCFG,
+                           AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY);
+               REG_WRITE(ah, AR_NEXT_NDP_TIMER,
+                         TU_TO_USEC(next_beacon +
+                                    (ah->atim_window ? ah->
+                                     atim_window : 1)));
+               flags |= AR_NDP_TIMER_EN;
+       case NL80211_IFTYPE_AP:
+               REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon));
+               REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT,
+                         TU_TO_USEC(next_beacon -
+                                    ah->config.
+                                    dma_beacon_response_time));
+               REG_WRITE(ah, AR_NEXT_SWBA,
+                         TU_TO_USEC(next_beacon -
+                                    ah->config.
+                                    sw_beacon_response_time));
+               flags |=
+                       AR_TBTT_TIMER_EN | AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN;
+               break;
+       default:
+               DPRINTF(ah->ah_sc, ATH_DBG_BEACON,
+                       "%s: unsupported opmode: %d\n",
+                       __func__, ah->opmode);
+               return;
+               break;
+       }
+
+       REG_WRITE(ah, AR_BEACON_PERIOD, TU_TO_USEC(beacon_period));
+       REG_WRITE(ah, AR_DMA_BEACON_PERIOD, TU_TO_USEC(beacon_period));
+       REG_WRITE(ah, AR_SWBA_PERIOD, TU_TO_USEC(beacon_period));
+       REG_WRITE(ah, AR_NDP_PERIOD, TU_TO_USEC(beacon_period));
+
+       beacon_period &= ~ATH9K_BEACON_ENA;
+       if (beacon_period & ATH9K_BEACON_RESET_TSF) {
+               beacon_period &= ~ATH9K_BEACON_RESET_TSF;
+               ath9k_hw_reset_tsf(ah);
+       }
+
+       REG_SET_BIT(ah, AR_TIMER_MODE, flags);
+}
+
+void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
+                                   const struct ath9k_beacon_state *bs)
+{
+       u32 nextTbtt, beaconintval, dtimperiod, beacontimeout;
+       struct ath9k_hw_capabilities *pCap = &ah->caps;
+
+       REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(bs->bs_nexttbtt));
+
+       REG_WRITE(ah, AR_BEACON_PERIOD,
+                 TU_TO_USEC(bs->bs_intval & ATH9K_BEACON_PERIOD));
+       REG_WRITE(ah, AR_DMA_BEACON_PERIOD,
+                 TU_TO_USEC(bs->bs_intval & ATH9K_BEACON_PERIOD));
+
+       REG_RMW_FIELD(ah, AR_RSSI_THR,
+                     AR_RSSI_THR_BM_THR, bs->bs_bmissthreshold);
+
+       beaconintval = bs->bs_intval & ATH9K_BEACON_PERIOD;
+
+       if (bs->bs_sleepduration > beaconintval)
+               beaconintval = bs->bs_sleepduration;
+
+       dtimperiod = bs->bs_dtimperiod;
+       if (bs->bs_sleepduration > dtimperiod)
+               dtimperiod = bs->bs_sleepduration;
+
+       if (beaconintval == dtimperiod)
+               nextTbtt = bs->bs_nextdtim;
+       else
+               nextTbtt = bs->bs_nexttbtt;
+
+       DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "next DTIM %d\n", bs->bs_nextdtim);
+       DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "next beacon %d\n", nextTbtt);
+       DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "beacon period %d\n", beaconintval);
+       DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "DTIM period %d\n", dtimperiod);
+
+       REG_WRITE(ah, AR_NEXT_DTIM,
+                 TU_TO_USEC(bs->bs_nextdtim - SLEEP_SLOP));
+       REG_WRITE(ah, AR_NEXT_TIM, TU_TO_USEC(nextTbtt - SLEEP_SLOP));
+
+       REG_WRITE(ah, AR_SLEEP1,
+                 SM((CAB_TIMEOUT_VAL << 3), AR_SLEEP1_CAB_TIMEOUT)
+                 | AR_SLEEP1_ASSUME_DTIM);
+
+       if (pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)
+               beacontimeout = (BEACON_TIMEOUT_VAL << 3);
+       else
+               beacontimeout = MIN_BEACON_TIMEOUT_VAL;
+
+       REG_WRITE(ah, AR_SLEEP2,
+                 SM(beacontimeout, AR_SLEEP2_BEACON_TIMEOUT));
+
+       REG_WRITE(ah, AR_TIM_PERIOD, TU_TO_USEC(beaconintval));
+       REG_WRITE(ah, AR_DTIM_PERIOD, TU_TO_USEC(dtimperiod));
+
+       REG_SET_BIT(ah, AR_TIMER_MODE,
+                   AR_TBTT_TIMER_EN | AR_TIM_TIMER_EN |
+                   AR_DTIM_TIMER_EN);
+
+       /* TSF Out of Range Threshold */
+       REG_WRITE(ah, AR_TSFOOR_THRESHOLD, bs->bs_tsfoor_threshold);
+}
+
+/*******************/
+/* HW Capabilities */
+/*******************/
+
+void ath9k_hw_fill_cap_info(struct ath_hw *ah)
+{
+       struct ath9k_hw_capabilities *pCap = &ah->caps;
+       u16 capField = 0, eeval;
+
+       eeval = ah->eep_ops->get_eeprom(ah, EEP_REG_0);
+       ah->regulatory.current_rd = eeval;
+
+       eeval = ah->eep_ops->get_eeprom(ah, EEP_REG_1);
+       if (AR_SREV_9285_10_OR_LATER(ah))
+               eeval |= AR9285_RDEXT_DEFAULT;
+       ah->regulatory.current_rd_ext = eeval;
+
+       capField = ah->eep_ops->get_eeprom(ah, EEP_OP_CAP);
+
+       if (ah->opmode != NL80211_IFTYPE_AP &&
+           ah->hw_version.subvendorid == AR_SUBVENDOR_ID_NEW_A) {
+               if (ah->regulatory.current_rd == 0x64 ||
+                   ah->regulatory.current_rd == 0x65)
+                       ah->regulatory.current_rd += 5;
+               else if (ah->regulatory.current_rd == 0x41)
+                       ah->regulatory.current_rd = 0x43;
+               DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
+                       "regdomain mapped to 0x%x\n", ah->regulatory.current_rd);
+       }
+
+       eeval = ah->eep_ops->get_eeprom(ah, EEP_OP_MODE);
+       bitmap_zero(pCap->wireless_modes, ATH9K_MODE_MAX);
+
+       if (eeval & AR5416_OPFLAGS_11A) {
+               set_bit(ATH9K_MODE_11A, pCap->wireless_modes);
+               if (ah->config.ht_enable) {
+                       if (!(eeval & AR5416_OPFLAGS_N_5G_HT20))
+                               set_bit(ATH9K_MODE_11NA_HT20,
+                                       pCap->wireless_modes);
+                       if (!(eeval & AR5416_OPFLAGS_N_5G_HT40)) {
+                               set_bit(ATH9K_MODE_11NA_HT40PLUS,
+                                       pCap->wireless_modes);
+                               set_bit(ATH9K_MODE_11NA_HT40MINUS,
+                                       pCap->wireless_modes);
+                       }
+               }
+       }
+
+       if (eeval & AR5416_OPFLAGS_11G) {
+               set_bit(ATH9K_MODE_11B, pCap->wireless_modes);
+               set_bit(ATH9K_MODE_11G, pCap->wireless_modes);
+               if (ah->config.ht_enable) {
+                       if (!(eeval & AR5416_OPFLAGS_N_2G_HT20))
+                               set_bit(ATH9K_MODE_11NG_HT20,
+                                       pCap->wireless_modes);
+                       if (!(eeval & AR5416_OPFLAGS_N_2G_HT40)) {
+                               set_bit(ATH9K_MODE_11NG_HT40PLUS,
+                                       pCap->wireless_modes);
+                               set_bit(ATH9K_MODE_11NG_HT40MINUS,
+                                       pCap->wireless_modes);
+                       }
+               }
+       }
+
+       pCap->tx_chainmask = ah->eep_ops->get_eeprom(ah, EEP_TX_MASK);
+       if ((ah->hw_version.devid == AR5416_DEVID_PCI) &&
+           !(eeval & AR5416_OPFLAGS_11A))
+               pCap->rx_chainmask = ath9k_hw_gpio_get(ah, 0) ? 0x5 : 0x7;
+       else
+               pCap->rx_chainmask = ah->eep_ops->get_eeprom(ah, EEP_RX_MASK);
+
+       if (!(AR_SREV_9280(ah) && (ah->hw_version.macRev == 0)))
+               ah->misc_mode |= AR_PCU_MIC_NEW_LOC_ENA;
+
+       pCap->low_2ghz_chan = 2312;
+       pCap->high_2ghz_chan = 2732;
+
+       pCap->low_5ghz_chan = 4920;
+       pCap->high_5ghz_chan = 6100;
+
+       pCap->hw_caps &= ~ATH9K_HW_CAP_CIPHER_CKIP;
+       pCap->hw_caps |= ATH9K_HW_CAP_CIPHER_TKIP;
+       pCap->hw_caps |= ATH9K_HW_CAP_CIPHER_AESCCM;
+
+       pCap->hw_caps &= ~ATH9K_HW_CAP_MIC_CKIP;
+       pCap->hw_caps |= ATH9K_HW_CAP_MIC_TKIP;
+       pCap->hw_caps |= ATH9K_HW_CAP_MIC_AESCCM;
+
+       if (ah->config.ht_enable)
+               pCap->hw_caps |= ATH9K_HW_CAP_HT;
+       else
+               pCap->hw_caps &= ~ATH9K_HW_CAP_HT;
+
+       pCap->hw_caps |= ATH9K_HW_CAP_GTT;
+       pCap->hw_caps |= ATH9K_HW_CAP_VEOL;
+       pCap->hw_caps |= ATH9K_HW_CAP_BSSIDMASK;
+       pCap->hw_caps &= ~ATH9K_HW_CAP_MCAST_KEYSEARCH;
+
+       if (capField & AR_EEPROM_EEPCAP_MAXQCU)
+               pCap->total_queues =
+                       MS(capField, AR_EEPROM_EEPCAP_MAXQCU);
+       else
+               pCap->total_queues = ATH9K_NUM_TX_QUEUES;
+
+       if (capField & AR_EEPROM_EEPCAP_KC_ENTRIES)
+               pCap->keycache_size =
+                       1 << MS(capField, AR_EEPROM_EEPCAP_KC_ENTRIES);
+       else
+               pCap->keycache_size = AR_KEYTABLE_SIZE;
+
+       pCap->hw_caps |= ATH9K_HW_CAP_FASTCC;
+       pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD;
+
+       if (AR_SREV_9285_10_OR_LATER(ah))
+               pCap->num_gpio_pins = AR9285_NUM_GPIO;
+       else if (AR_SREV_9280_10_OR_LATER(ah))
+               pCap->num_gpio_pins = AR928X_NUM_GPIO;
+       else
+               pCap->num_gpio_pins = AR_NUM_GPIO;
+
+       if (AR_SREV_9160_10_OR_LATER(ah) || AR_SREV_9100(ah)) {
+               pCap->hw_caps |= ATH9K_HW_CAP_CST;
+               pCap->rts_aggr_limit = ATH_AMPDU_LIMIT_MAX;
+       } else {
+               pCap->rts_aggr_limit = (8 * 1024);
+       }
+
+       pCap->hw_caps |= ATH9K_HW_CAP_ENHANCEDPM;
+
+#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
+       ah->rfsilent = ah->eep_ops->get_eeprom(ah, EEP_RF_SILENT);
+       if (ah->rfsilent & EEP_RFSILENT_ENABLED) {
+               ah->rfkill_gpio =
+                       MS(ah->rfsilent, EEP_RFSILENT_GPIO_SEL);
+               ah->rfkill_polarity =
+                       MS(ah->rfsilent, EEP_RFSILENT_POLARITY);
+
+               pCap->hw_caps |= ATH9K_HW_CAP_RFSILENT;
+       }
+#endif
+
+       if ((ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) ||
+           (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCIE) ||
+           (ah->hw_version.macVersion == AR_SREV_VERSION_9160) ||
+           (ah->hw_version.macVersion == AR_SREV_VERSION_9100) ||
+           (ah->hw_version.macVersion == AR_SREV_VERSION_9280) ||
+           (ah->hw_version.macVersion == AR_SREV_VERSION_9285))
+               pCap->hw_caps &= ~ATH9K_HW_CAP_AUTOSLEEP;
+       else
+               pCap->hw_caps |= ATH9K_HW_CAP_AUTOSLEEP;
+
+       if (AR_SREV_9280(ah) || AR_SREV_9285(ah))
+               pCap->hw_caps &= ~ATH9K_HW_CAP_4KB_SPLITTRANS;
+       else
+               pCap->hw_caps |= ATH9K_HW_CAP_4KB_SPLITTRANS;
+
+       if (ah->regulatory.current_rd_ext & (1 << REG_EXT_JAPAN_MIDBAND)) {
+               pCap->reg_cap =
+                       AR_EEPROM_EEREGCAP_EN_KK_NEW_11A |
+                       AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN |
+                       AR_EEPROM_EEREGCAP_EN_KK_U2 |
+                       AR_EEPROM_EEREGCAP_EN_KK_MIDBAND;
+       } else {
+               pCap->reg_cap =
+                       AR_EEPROM_EEREGCAP_EN_KK_NEW_11A |
+                       AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN;
+       }
+
+       pCap->reg_cap |= AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND;
+
+       pCap->num_antcfg_5ghz =
+               ah->eep_ops->get_num_ant_config(ah, ATH9K_HAL_FREQ_BAND_5GHZ);
+       pCap->num_antcfg_2ghz =
+               ah->eep_ops->get_num_ant_config(ah, ATH9K_HAL_FREQ_BAND_2GHZ);
+
+       if (AR_SREV_9280_10_OR_LATER(ah) && btcoex_enable) {
+               pCap->hw_caps |= ATH9K_HW_CAP_BT_COEX;
+               ah->btactive_gpio = 6;
+               ah->wlanactive_gpio = 5;
+       }
+}
+
+bool ath9k_hw_getcapability(struct ath_hw *ah, enum ath9k_capability_type type,
+                           u32 capability, u32 *result)
+{
+       switch (type) {
+       case ATH9K_CAP_CIPHER:
+               switch (capability) {
+               case ATH9K_CIPHER_AES_CCM:
+               case ATH9K_CIPHER_AES_OCB:
+               case ATH9K_CIPHER_TKIP:
+               case ATH9K_CIPHER_WEP:
+               case ATH9K_CIPHER_MIC:
+               case ATH9K_CIPHER_CLR:
+                       return true;
+               default:
+                       return false;
+               }
+       case ATH9K_CAP_TKIP_MIC:
+               switch (capability) {
+               case 0:
+                       return true;
+               case 1:
+                       return (ah->sta_id1_defaults &
+                               AR_STA_ID1_CRPT_MIC_ENABLE) ? true :
+                       false;
+               }
+       case ATH9K_CAP_TKIP_SPLIT:
+               return (ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA) ?
+                       false : true;
+       case ATH9K_CAP_DIVERSITY:
+               return (REG_READ(ah, AR_PHY_CCK_DETECT) &
+                       AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV) ?
+                       true : false;
+       case ATH9K_CAP_MCAST_KEYSRCH:
+               switch (capability) {
+               case 0:
+                       return true;
+               case 1:
+                       if (REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_ADHOC) {
+                               return false;
+                       } else {
+                               return (ah->sta_id1_defaults &
+                                       AR_STA_ID1_MCAST_KSRCH) ? true :
+                                       false;
+                       }
+               }
+               return false;
+       case ATH9K_CAP_TXPOW:
+               switch (capability) {
+               case 0:
+                       return 0;
+               case 1:
+                       *result = ah->regulatory.power_limit;
+                       return 0;
+               case 2:
+                       *result = ah->regulatory.max_power_level;
+                       return 0;
+               case 3:
+                       *result = ah->regulatory.tp_scale;
+                       return 0;
+               }
+               return false;
+       case ATH9K_CAP_DS:
+               return (AR_SREV_9280_20_OR_LATER(ah) &&
+                       (ah->eep_ops->get_eeprom(ah, EEP_RC_CHAIN_MASK) == 1))
+                       ? false : true;
+       default:
+               return false;
+       }
+}
+
+bool ath9k_hw_setcapability(struct ath_hw *ah, enum ath9k_capability_type type,
+                           u32 capability, u32 setting, int *status)
+{
+       u32 v;
+
+       switch (type) {
+       case ATH9K_CAP_TKIP_MIC:
+               if (setting)
+                       ah->sta_id1_defaults |=
+                               AR_STA_ID1_CRPT_MIC_ENABLE;
+               else
+                       ah->sta_id1_defaults &=
+                               ~AR_STA_ID1_CRPT_MIC_ENABLE;
+               return true;
+       case ATH9K_CAP_DIVERSITY:
+               v = REG_READ(ah, AR_PHY_CCK_DETECT);
+               if (setting)
+                       v |= AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV;
+               else
+                       v &= ~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV;
+               REG_WRITE(ah, AR_PHY_CCK_DETECT, v);
+               return true;
+       case ATH9K_CAP_MCAST_KEYSRCH:
+               if (setting)
+                       ah->sta_id1_defaults |= AR_STA_ID1_MCAST_KSRCH;
+               else
+                       ah->sta_id1_defaults &= ~AR_STA_ID1_MCAST_KSRCH;
+               return true;
+       default:
+               return false;
+       }
+}
+
+/****************************/
+/* GPIO / RFKILL / Antennae */
+/****************************/
+
+static void ath9k_hw_gpio_cfg_output_mux(struct ath_hw *ah,
+                                        u32 gpio, u32 type)
+{
+       int addr;
+       u32 gpio_shift, tmp;
+
+       if (gpio > 11)
+               addr = AR_GPIO_OUTPUT_MUX3;
+       else if (gpio > 5)
+               addr = AR_GPIO_OUTPUT_MUX2;
+       else
+               addr = AR_GPIO_OUTPUT_MUX1;
+
+       gpio_shift = (gpio % 6) * 5;
+
+       if (AR_SREV_9280_20_OR_LATER(ah)
+           || (addr != AR_GPIO_OUTPUT_MUX1)) {
+               REG_RMW(ah, addr, (type << gpio_shift),
+                       (0x1f << gpio_shift));
+       } else {
+               tmp = REG_READ(ah, addr);
+               tmp = ((tmp & 0x1F0) << 1) | (tmp & ~0x1F0);
+               tmp &= ~(0x1f << gpio_shift);
+               tmp |= (type << gpio_shift);
+               REG_WRITE(ah, addr, tmp);
+       }
+}
+
+void ath9k_hw_cfg_gpio_input(struct ath_hw *ah, u32 gpio)
+{
+       u32 gpio_shift;
+
+       ASSERT(gpio < ah->caps.num_gpio_pins);
+
+       gpio_shift = gpio << 1;
+
+       REG_RMW(ah,
+               AR_GPIO_OE_OUT,
+               (AR_GPIO_OE_OUT_DRV_NO << gpio_shift),
+               (AR_GPIO_OE_OUT_DRV << gpio_shift));
+}
+
+u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio)
+{
+#define MS_REG_READ(x, y) \
+       (MS(REG_READ(ah, AR_GPIO_IN_OUT), x##_GPIO_IN_VAL) & (AR_GPIO_BIT(y)))
+
+       if (gpio >= ah->caps.num_gpio_pins)
+               return 0xffffffff;
+
+       if (AR_SREV_9285_10_OR_LATER(ah))
+               return MS_REG_READ(AR9285, gpio) != 0;
+       else if (AR_SREV_9280_10_OR_LATER(ah))
+               return MS_REG_READ(AR928X, gpio) != 0;
+       else
+               return MS_REG_READ(AR, gpio) != 0;
+}
+
+void ath9k_hw_cfg_output(struct ath_hw *ah, u32 gpio,
+                        u32 ah_signal_type)
+{
+       u32 gpio_shift;
+
+       ath9k_hw_gpio_cfg_output_mux(ah, gpio, ah_signal_type);
+
+       gpio_shift = 2 * gpio;
+
+       REG_RMW(ah,
+               AR_GPIO_OE_OUT,
+               (AR_GPIO_OE_OUT_DRV_ALL << gpio_shift),
+               (AR_GPIO_OE_OUT_DRV << gpio_shift));
+}
+
+void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val)
+{
+       REG_RMW(ah, AR_GPIO_IN_OUT, ((val & 1) << gpio),
+               AR_GPIO_BIT(gpio));
+}
+
+#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
+void ath9k_enable_rfkill(struct ath_hw *ah)
+{
+       REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
+                   AR_GPIO_INPUT_EN_VAL_RFSILENT_BB);
+
+       REG_CLR_BIT(ah, AR_GPIO_INPUT_MUX2,
+                   AR_GPIO_INPUT_MUX2_RFSILENT);
+
+       ath9k_hw_cfg_gpio_input(ah, ah->rfkill_gpio);
+       REG_SET_BIT(ah, AR_PHY_TEST, RFSILENT_BB);
+}
+#endif
+
+u32 ath9k_hw_getdefantenna(struct ath_hw *ah)
+{
+       return REG_READ(ah, AR_DEF_ANTENNA) & 0x7;
+}
+
+void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna)
+{
+       REG_WRITE(ah, AR_DEF_ANTENNA, (antenna & 0x7));
+}
+
+bool ath9k_hw_setantennaswitch(struct ath_hw *ah,
+                              enum ath9k_ant_setting settings,
+                              struct ath9k_channel *chan,
+                              u8 *tx_chainmask,
+                              u8 *rx_chainmask,
+                              u8 *antenna_cfgd)
+{
+       static u8 tx_chainmask_cfg, rx_chainmask_cfg;
+
+       if (AR_SREV_9280(ah)) {
+               if (!tx_chainmask_cfg) {
+
+                       tx_chainmask_cfg = *tx_chainmask;
+                       rx_chainmask_cfg = *rx_chainmask;
+               }
+
+               switch (settings) {
+               case ATH9K_ANT_FIXED_A:
+                       *tx_chainmask = ATH9K_ANTENNA0_CHAINMASK;
+                       *rx_chainmask = ATH9K_ANTENNA0_CHAINMASK;
+                       *antenna_cfgd = true;
+                       break;
+               case ATH9K_ANT_FIXED_B:
+                       if (ah->caps.tx_chainmask >
+                           ATH9K_ANTENNA1_CHAINMASK) {
+                               *tx_chainmask = ATH9K_ANTENNA1_CHAINMASK;
+                       }
+                       *rx_chainmask = ATH9K_ANTENNA1_CHAINMASK;
+                       *antenna_cfgd = true;
+                       break;
+               case ATH9K_ANT_VARIABLE:
+                       *tx_chainmask = tx_chainmask_cfg;
+                       *rx_chainmask = rx_chainmask_cfg;
+                       *antenna_cfgd = true;
+                       break;
+               default:
+                       break;
+               }
+       } else {
+               ah->diversity_control = settings;
+       }
+
+       return true;
+}
+
+/*********************/
+/* General Operation */
+/*********************/
+
+u32 ath9k_hw_getrxfilter(struct ath_hw *ah)
+{
+       u32 bits = REG_READ(ah, AR_RX_FILTER);
+       u32 phybits = REG_READ(ah, AR_PHY_ERR);
+
+       if (phybits & AR_PHY_ERR_RADAR)
+               bits |= ATH9K_RX_FILTER_PHYRADAR;
+       if (phybits & (AR_PHY_ERR_OFDM_TIMING | AR_PHY_ERR_CCK_TIMING))
+               bits |= ATH9K_RX_FILTER_PHYERR;
+
+       return bits;
+}
+
+void ath9k_hw_setrxfilter(struct ath_hw *ah, u32 bits)
+{
+       u32 phybits;
+
+       REG_WRITE(ah, AR_RX_FILTER, (bits & 0xffff) | AR_RX_COMPR_BAR);
+       phybits = 0;
+       if (bits & ATH9K_RX_FILTER_PHYRADAR)
+               phybits |= AR_PHY_ERR_RADAR;
+       if (bits & ATH9K_RX_FILTER_PHYERR)
+               phybits |= AR_PHY_ERR_OFDM_TIMING | AR_PHY_ERR_CCK_TIMING;
+       REG_WRITE(ah, AR_PHY_ERR, phybits);
+
+       if (phybits)
+               REG_WRITE(ah, AR_RXCFG,
+                         REG_READ(ah, AR_RXCFG) | AR_RXCFG_ZLFDMA);
+       else
+               REG_WRITE(ah, AR_RXCFG,
+                         REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_ZLFDMA);
+}
+
+bool ath9k_hw_phy_disable(struct ath_hw *ah)
+{
+       return ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM);
+}
+
+bool ath9k_hw_disable(struct ath_hw *ah)
+{
+       if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
+               return false;
+
+       return ath9k_hw_set_reset_reg(ah, ATH9K_RESET_COLD);
+}
+
+void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit)
+{
+       struct ath9k_channel *chan = ah->curchan;
+       struct ieee80211_channel *channel = chan->chan;
+
+       ah->regulatory.power_limit = min(limit, (u32) MAX_RATE_POWER);
+
+       ah->eep_ops->set_txpower(ah, chan,
+                                ath9k_regd_get_ctl(&ah->regulatory, chan),
+                                channel->max_antenna_gain * 2,
+                                channel->max_power * 2,
+                                min((u32) MAX_RATE_POWER,
+                                (u32) ah->regulatory.power_limit));
+}
+
+void ath9k_hw_setmac(struct ath_hw *ah, const u8 *mac)
+{
+       memcpy(ah->macaddr, mac, ETH_ALEN);
+}
+
+void ath9k_hw_setopmode(struct ath_hw *ah)
+{
+       ath9k_hw_set_operating_mode(ah, ah->opmode);
+}
+
+void ath9k_hw_setmcastfilter(struct ath_hw *ah, u32 filter0, u32 filter1)
+{
+       REG_WRITE(ah, AR_MCAST_FIL0, filter0);
+       REG_WRITE(ah, AR_MCAST_FIL1, filter1);
+}
+
+void ath9k_hw_setbssidmask(struct ath_softc *sc)
+{
+       REG_WRITE(sc->sc_ah, AR_BSSMSKL, get_unaligned_le32(sc->bssidmask));
+       REG_WRITE(sc->sc_ah, AR_BSSMSKU, get_unaligned_le16(sc->bssidmask + 4));
+}
+
+void ath9k_hw_write_associd(struct ath_softc *sc)
+{
+       REG_WRITE(sc->sc_ah, AR_BSS_ID0, get_unaligned_le32(sc->curbssid));
+       REG_WRITE(sc->sc_ah, AR_BSS_ID1, get_unaligned_le16(sc->curbssid + 4) |
+                 ((sc->curaid & 0x3fff) << AR_BSS_ID1_AID_S));
+}
+
+u64 ath9k_hw_gettsf64(struct ath_hw *ah)
+{
+       u64 tsf;
+
+       tsf = REG_READ(ah, AR_TSF_U32);
+       tsf = (tsf << 32) | REG_READ(ah, AR_TSF_L32);
+
+       return tsf;
+}
+
+void ath9k_hw_settsf64(struct ath_hw *ah, u64 tsf64)
+{
+       REG_WRITE(ah, AR_TSF_L32, tsf64 & 0xffffffff);
+       REG_WRITE(ah, AR_TSF_U32, (tsf64 >> 32) & 0xffffffff);
+}
+
+void ath9k_hw_reset_tsf(struct ath_hw *ah)
+{
+       int count;
+
+       count = 0;
+       while (REG_READ(ah, AR_SLP32_MODE) & AR_SLP32_TSF_WRITE_STATUS) {
+               count++;
+               if (count > 10) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_RESET,
+                               "AR_SLP32_TSF_WRITE_STATUS limit exceeded\n");
+                       break;
+               }
+               udelay(10);
+       }
+       REG_WRITE(ah, AR_RESET_TSF, AR_RESET_TSF_ONCE);
+}
+
+bool ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting)
+{
+       if (setting)
+               ah->misc_mode |= AR_PCU_TX_ADD_TSF;
+       else
+               ah->misc_mode &= ~AR_PCU_TX_ADD_TSF;
+
+       return true;
+}
+
+bool ath9k_hw_setslottime(struct ath_hw *ah, u32 us)
+{
+       if (us < ATH9K_SLOT_TIME_9 || us > ath9k_hw_mac_to_usec(ah, 0xffff)) {
+               DPRINTF(ah->ah_sc, ATH_DBG_RESET, "bad slot time %u\n", us);
+               ah->slottime = (u32) -1;
+               return false;
+       } else {
+               REG_WRITE(ah, AR_D_GBL_IFS_SLOT, ath9k_hw_mac_to_clks(ah, us));
+               ah->slottime = us;
+               return true;
+       }
+}
+
+void ath9k_hw_set11nmac2040(struct ath_hw *ah, enum ath9k_ht_macmode mode)
+{
+       u32 macmode;
+
+       if (mode == ATH9K_HT_MACMODE_2040 &&
+           !ah->config.cwm_ignore_extcca)
+               macmode = AR_2040_JOINED_RX_CLEAR;
+       else
+               macmode = 0;
+
+       REG_WRITE(ah, AR_2040_MODE, macmode);
+}
+
+/***************************/
+/*  Bluetooth Coexistence  */
+/***************************/
+
+void ath9k_hw_btcoex_enable(struct ath_hw *ah)
+{
+       /* connect bt_active to baseband */
+       REG_CLR_BIT(ah, AR_GPIO_INPUT_EN_VAL,
+                       (AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_DEF |
+                        AR_GPIO_INPUT_EN_VAL_BT_FREQUENCY_DEF));
+
+       REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
+                       AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_BB);
+
+       /* Set input mux for bt_active to gpio pin */
+       REG_RMW_FIELD(ah, AR_GPIO_INPUT_MUX1,
+                       AR_GPIO_INPUT_MUX1_BT_ACTIVE,
+                       ah->btactive_gpio);
+
+       /* Configure the desired gpio port for input */
+       ath9k_hw_cfg_gpio_input(ah, ah->btactive_gpio);
+
+       /* Configure the desired GPIO port for TX_FRAME output */
+       ath9k_hw_cfg_output(ah, ah->wlanactive_gpio,
+                           AR_GPIO_OUTPUT_MUX_AS_TX_FRAME);
+}
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
new file mode 100644 (file)
index 0000000..dd8508e
--- /dev/null
@@ -0,0 +1,620 @@
+/*
+ * Copyright (c) 2008-2009 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 HW_H
+#define HW_H
+
+#include <linux/if_ether.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+
+#include "mac.h"
+#include "ani.h"
+#include "eeprom.h"
+#include "calib.h"
+#include "reg.h"
+#include "phy.h"
+
+#include "../regd.h"
+
+#define ATHEROS_VENDOR_ID      0x168c
+#define AR5416_DEVID_PCI       0x0023
+#define AR5416_DEVID_PCIE      0x0024
+#define AR9160_DEVID_PCI       0x0027
+#define AR9280_DEVID_PCI       0x0029
+#define AR9280_DEVID_PCIE      0x002a
+#define AR9285_DEVID_PCIE      0x002b
+#define AR5416_AR9100_DEVID    0x000b
+#define        AR_SUBVENDOR_ID_NOG     0x0e11
+#define AR_SUBVENDOR_ID_NEW_A  0x7065
+#define AR5416_MAGIC           0x19641014
+
+/* Register read/write primitives */
+#define REG_WRITE(_ah, _reg, _val) ath9k_iowrite32((_ah), (_reg), (_val))
+#define REG_READ(_ah, _reg) ath9k_ioread32((_ah), (_reg))
+
+#define SM(_v, _f)  (((_v) << _f##_S) & _f)
+#define MS(_v, _f)  (((_v) & _f) >> _f##_S)
+#define REG_RMW(_a, _r, _set, _clr)    \
+       REG_WRITE(_a, _r, (REG_READ(_a, _r) & ~(_clr)) | (_set))
+#define REG_RMW_FIELD(_a, _r, _f, _v) \
+       REG_WRITE(_a, _r, \
+       (REG_READ(_a, _r) & ~_f) | (((_v) << _f##_S) & _f))
+#define REG_SET_BIT(_a, _r, _f) \
+       REG_WRITE(_a, _r, REG_READ(_a, _r) | _f)
+#define REG_CLR_BIT(_a, _r, _f) \
+       REG_WRITE(_a, _r, REG_READ(_a, _r) & ~_f)
+
+#define DO_DELAY(x) do {                       \
+               if ((++(x) % 64) == 0)          \
+                       udelay(1);              \
+       } while (0)
+
+#define REG_WRITE_ARRAY(iniarray, column, regWr) do {                   \
+               int r;                                                  \
+               for (r = 0; r < ((iniarray)->ia_rows); r++) {           \
+                       REG_WRITE(ah, INI_RA((iniarray), (r), 0),       \
+                                 INI_RA((iniarray), r, (column)));     \
+                       DO_DELAY(regWr);                                \
+               }                                                       \
+       } while (0)
+
+#define AR_GPIO_OUTPUT_MUX_AS_OUTPUT             0
+#define AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED 1
+#define AR_GPIO_OUTPUT_MUX_AS_PCIE_POWER_LED     2
+#define AR_GPIO_OUTPUT_MUX_AS_TX_FRAME           3
+#define AR_GPIO_OUTPUT_MUX_AS_MAC_NETWORK_LED    5
+#define AR_GPIO_OUTPUT_MUX_AS_MAC_POWER_LED      6
+
+#define AR_GPIOD_MASK               0x00001FFF
+#define AR_GPIO_BIT(_gpio)          (1 << (_gpio))
+
+#define BASE_ACTIVATE_DELAY         100
+#define RTC_PLL_SETTLE_DELAY        1000
+#define COEF_SCALE_S                24
+#define HT40_CHANNEL_CENTER_SHIFT   10
+
+#define ATH9K_ANTENNA0_CHAINMASK    0x1
+#define ATH9K_ANTENNA1_CHAINMASK    0x2
+
+#define ATH9K_NUM_DMA_DEBUG_REGS    8
+#define ATH9K_NUM_QUEUES            10
+
+#define MAX_RATE_POWER              63
+#define AH_WAIT_TIMEOUT             100000 /* (us) */
+#define AH_TIME_QUANTUM             10
+#define AR_KEYTABLE_SIZE            128
+#define POWER_UP_TIME               200000
+#define SPUR_RSSI_THRESH            40
+
+#define CAB_TIMEOUT_VAL             10
+#define BEACON_TIMEOUT_VAL          10
+#define MIN_BEACON_TIMEOUT_VAL      1
+#define SLEEP_SLOP                  3
+
+#define INIT_CONFIG_STATUS          0x00000000
+#define INIT_RSSI_THR               0x00000700
+#define INIT_BCON_CNTRL_REG         0x00000000
+
+#define TU_TO_USEC(_tu)             ((_tu) << 10)
+
+enum wireless_mode {
+       ATH9K_MODE_11A = 0,
+       ATH9K_MODE_11B = 2,
+       ATH9K_MODE_11G = 3,
+       ATH9K_MODE_11NA_HT20 = 6,
+       ATH9K_MODE_11NG_HT20 = 7,
+       ATH9K_MODE_11NA_HT40PLUS = 8,
+       ATH9K_MODE_11NA_HT40MINUS = 9,
+       ATH9K_MODE_11NG_HT40PLUS = 10,
+       ATH9K_MODE_11NG_HT40MINUS = 11,
+       ATH9K_MODE_MAX
+};
+
+enum ath9k_hw_caps {
+       ATH9K_HW_CAP_MIC_AESCCM                 = BIT(0),
+       ATH9K_HW_CAP_MIC_CKIP                   = BIT(1),
+       ATH9K_HW_CAP_MIC_TKIP                   = BIT(2),
+       ATH9K_HW_CAP_CIPHER_AESCCM              = BIT(3),
+       ATH9K_HW_CAP_CIPHER_CKIP                = BIT(4),
+       ATH9K_HW_CAP_CIPHER_TKIP                = BIT(5),
+       ATH9K_HW_CAP_VEOL                       = BIT(6),
+       ATH9K_HW_CAP_BSSIDMASK                  = BIT(7),
+       ATH9K_HW_CAP_MCAST_KEYSEARCH            = BIT(8),
+       ATH9K_HW_CAP_HT                         = BIT(9),
+       ATH9K_HW_CAP_GTT                        = BIT(10),
+       ATH9K_HW_CAP_FASTCC                     = BIT(11),
+       ATH9K_HW_CAP_RFSILENT                   = BIT(12),
+       ATH9K_HW_CAP_CST                        = BIT(13),
+       ATH9K_HW_CAP_ENHANCEDPM                 = BIT(14),
+       ATH9K_HW_CAP_AUTOSLEEP                  = BIT(15),
+       ATH9K_HW_CAP_4KB_SPLITTRANS             = BIT(16),
+       ATH9K_HW_CAP_BT_COEX                    = BIT(17)
+};
+
+enum ath9k_capability_type {
+       ATH9K_CAP_CIPHER = 0,
+       ATH9K_CAP_TKIP_MIC,
+       ATH9K_CAP_TKIP_SPLIT,
+       ATH9K_CAP_DIVERSITY,
+       ATH9K_CAP_TXPOW,
+       ATH9K_CAP_MCAST_KEYSRCH,
+       ATH9K_CAP_DS
+};
+
+struct ath9k_hw_capabilities {
+       u32 hw_caps; /* ATH9K_HW_CAP_* from ath9k_hw_caps */
+       DECLARE_BITMAP(wireless_modes, ATH9K_MODE_MAX); /* ATH9K_MODE_* */
+       u16 total_queues;
+       u16 keycache_size;
+       u16 low_5ghz_chan, high_5ghz_chan;
+       u16 low_2ghz_chan, high_2ghz_chan;
+       u16 rts_aggr_limit;
+       u8 tx_chainmask;
+       u8 rx_chainmask;
+       u16 tx_triglevel_max;
+       u16 reg_cap;
+       u8 num_gpio_pins;
+       u8 num_antcfg_2ghz;
+       u8 num_antcfg_5ghz;
+};
+
+struct ath9k_ops_config {
+       int dma_beacon_response_time;
+       int sw_beacon_response_time;
+       int additional_swba_backoff;
+       int ack_6mb;
+       int cwm_ignore_extcca;
+       u8 pcie_powersave_enable;
+       u8 pcie_clock_req;
+       u32 pcie_waen;
+       u8 analog_shiftreg;
+       u8 ht_enable;
+       u32 ofdm_trig_low;
+       u32 ofdm_trig_high;
+       u32 cck_trig_high;
+       u32 cck_trig_low;
+       u32 enable_ani;
+       u16 diversity_control;
+       u16 antenna_switch_swap;
+       int serialize_regmode;
+       bool intr_mitigation;
+#define SPUR_DISABLE           0
+#define SPUR_ENABLE_IOCTL      1
+#define SPUR_ENABLE_EEPROM     2
+#define AR_EEPROM_MODAL_SPURS   5
+#define AR_SPUR_5413_1         1640
+#define AR_SPUR_5413_2         1200
+#define AR_NO_SPUR             0x8000
+#define AR_BASE_FREQ_2GHZ      2300
+#define AR_BASE_FREQ_5GHZ      4900
+#define AR_SPUR_FEEQ_BOUND_HT40 19
+#define AR_SPUR_FEEQ_BOUND_HT20 10
+       int spurmode;
+       u16 spurchans[AR_EEPROM_MODAL_SPURS][2];
+};
+
+enum ath9k_int {
+       ATH9K_INT_RX = 0x00000001,
+       ATH9K_INT_RXDESC = 0x00000002,
+       ATH9K_INT_RXNOFRM = 0x00000008,
+       ATH9K_INT_RXEOL = 0x00000010,
+       ATH9K_INT_RXORN = 0x00000020,
+       ATH9K_INT_TX = 0x00000040,
+       ATH9K_INT_TXDESC = 0x00000080,
+       ATH9K_INT_TIM_TIMER = 0x00000100,
+       ATH9K_INT_TXURN = 0x00000800,
+       ATH9K_INT_MIB = 0x00001000,
+       ATH9K_INT_RXPHY = 0x00004000,
+       ATH9K_INT_RXKCM = 0x00008000,
+       ATH9K_INT_SWBA = 0x00010000,
+       ATH9K_INT_BMISS = 0x00040000,
+       ATH9K_INT_BNR = 0x00100000,
+       ATH9K_INT_TIM = 0x00200000,
+       ATH9K_INT_DTIM = 0x00400000,
+       ATH9K_INT_DTIMSYNC = 0x00800000,
+       ATH9K_INT_GPIO = 0x01000000,
+       ATH9K_INT_CABEND = 0x02000000,
+       ATH9K_INT_TSFOOR = 0x04000000,
+       ATH9K_INT_CST = 0x10000000,
+       ATH9K_INT_GTT = 0x20000000,
+       ATH9K_INT_FATAL = 0x40000000,
+       ATH9K_INT_GLOBAL = 0x80000000,
+       ATH9K_INT_BMISC = ATH9K_INT_TIM |
+               ATH9K_INT_DTIM |
+               ATH9K_INT_DTIMSYNC |
+               ATH9K_INT_TSFOOR |
+               ATH9K_INT_CABEND,
+       ATH9K_INT_COMMON = ATH9K_INT_RXNOFRM |
+               ATH9K_INT_RXDESC |
+               ATH9K_INT_RXEOL |
+               ATH9K_INT_RXORN |
+               ATH9K_INT_TXURN |
+               ATH9K_INT_TXDESC |
+               ATH9K_INT_MIB |
+               ATH9K_INT_RXPHY |
+               ATH9K_INT_RXKCM |
+               ATH9K_INT_SWBA |
+               ATH9K_INT_BMISS |
+               ATH9K_INT_GPIO,
+       ATH9K_INT_NOCARD = 0xffffffff
+};
+
+#define CHANNEL_CW_INT    0x00002
+#define CHANNEL_CCK       0x00020
+#define CHANNEL_OFDM      0x00040
+#define CHANNEL_2GHZ      0x00080
+#define CHANNEL_5GHZ      0x00100
+#define CHANNEL_PASSIVE   0x00200
+#define CHANNEL_DYN       0x00400
+#define CHANNEL_HALF      0x04000
+#define CHANNEL_QUARTER   0x08000
+#define CHANNEL_HT20      0x10000
+#define CHANNEL_HT40PLUS  0x20000
+#define CHANNEL_HT40MINUS 0x40000
+
+#define CHANNEL_A           (CHANNEL_5GHZ|CHANNEL_OFDM)
+#define CHANNEL_B           (CHANNEL_2GHZ|CHANNEL_CCK)
+#define CHANNEL_G           (CHANNEL_2GHZ|CHANNEL_OFDM)
+#define CHANNEL_G_HT20      (CHANNEL_2GHZ|CHANNEL_HT20)
+#define CHANNEL_A_HT20      (CHANNEL_5GHZ|CHANNEL_HT20)
+#define CHANNEL_G_HT40PLUS  (CHANNEL_2GHZ|CHANNEL_HT40PLUS)
+#define CHANNEL_G_HT40MINUS (CHANNEL_2GHZ|CHANNEL_HT40MINUS)
+#define CHANNEL_A_HT40PLUS  (CHANNEL_5GHZ|CHANNEL_HT40PLUS)
+#define CHANNEL_A_HT40MINUS (CHANNEL_5GHZ|CHANNEL_HT40MINUS)
+#define CHANNEL_ALL                            \
+       (CHANNEL_OFDM|                          \
+        CHANNEL_CCK|                           \
+        CHANNEL_2GHZ |                         \
+        CHANNEL_5GHZ |                         \
+        CHANNEL_HT20 |                         \
+        CHANNEL_HT40PLUS |                     \
+        CHANNEL_HT40MINUS)
+
+struct ath9k_channel {
+       struct ieee80211_channel *chan;
+       u16 channel;
+       u32 channelFlags;
+       u32 chanmode;
+       int32_t CalValid;
+       bool oneTimeCalsDone;
+       int8_t iCoff;
+       int8_t qCoff;
+       int16_t rawNoiseFloor;
+};
+
+#define IS_CHAN_G(_c) ((((_c)->channelFlags & (CHANNEL_G)) == CHANNEL_G) || \
+       (((_c)->channelFlags & CHANNEL_G_HT20) == CHANNEL_G_HT20) || \
+       (((_c)->channelFlags & CHANNEL_G_HT40PLUS) == CHANNEL_G_HT40PLUS) || \
+       (((_c)->channelFlags & CHANNEL_G_HT40MINUS) == CHANNEL_G_HT40MINUS))
+#define IS_CHAN_OFDM(_c) (((_c)->channelFlags & CHANNEL_OFDM) != 0)
+#define IS_CHAN_5GHZ(_c) (((_c)->channelFlags & CHANNEL_5GHZ) != 0)
+#define IS_CHAN_2GHZ(_c) (((_c)->channelFlags & CHANNEL_2GHZ) != 0)
+#define IS_CHAN_HALF_RATE(_c) (((_c)->channelFlags & CHANNEL_HALF) != 0)
+#define IS_CHAN_QUARTER_RATE(_c) (((_c)->channelFlags & CHANNEL_QUARTER) != 0)
+#define IS_CHAN_A_5MHZ_SPACED(_c)                      \
+       ((((_c)->channelFlags & CHANNEL_5GHZ) != 0) &&  \
+        (((_c)->channel % 20) != 0) &&                 \
+        (((_c)->channel % 10) != 0))
+
+/* These macros check chanmode and not channelFlags */
+#define IS_CHAN_B(_c) ((_c)->chanmode == CHANNEL_B)
+#define IS_CHAN_HT20(_c) (((_c)->chanmode == CHANNEL_A_HT20) ||        \
+                         ((_c)->chanmode == CHANNEL_G_HT20))
+#define IS_CHAN_HT40(_c) (((_c)->chanmode == CHANNEL_A_HT40PLUS) ||    \
+                         ((_c)->chanmode == CHANNEL_A_HT40MINUS) ||    \
+                         ((_c)->chanmode == CHANNEL_G_HT40PLUS) ||     \
+                         ((_c)->chanmode == CHANNEL_G_HT40MINUS))
+#define IS_CHAN_HT(_c) (IS_CHAN_HT20((_c)) || IS_CHAN_HT40((_c)))
+
+enum ath9k_power_mode {
+       ATH9K_PM_AWAKE = 0,
+       ATH9K_PM_FULL_SLEEP,
+       ATH9K_PM_NETWORK_SLEEP,
+       ATH9K_PM_UNDEFINED
+};
+
+enum ath9k_ant_setting {
+       ATH9K_ANT_VARIABLE = 0,
+       ATH9K_ANT_FIXED_A,
+       ATH9K_ANT_FIXED_B
+};
+
+enum ath9k_tp_scale {
+       ATH9K_TP_SCALE_MAX = 0,
+       ATH9K_TP_SCALE_50,
+       ATH9K_TP_SCALE_25,
+       ATH9K_TP_SCALE_12,
+       ATH9K_TP_SCALE_MIN
+};
+
+enum ser_reg_mode {
+       SER_REG_MODE_OFF = 0,
+       SER_REG_MODE_ON = 1,
+       SER_REG_MODE_AUTO = 2,
+};
+
+struct ath9k_beacon_state {
+       u32 bs_nexttbtt;
+       u32 bs_nextdtim;
+       u32 bs_intval;
+#define ATH9K_BEACON_PERIOD       0x0000ffff
+#define ATH9K_BEACON_ENA          0x00800000
+#define ATH9K_BEACON_RESET_TSF    0x01000000
+#define ATH9K_TSFOOR_THRESHOLD    0x00004240 /* 16k us */
+       u32 bs_dtimperiod;
+       u16 bs_cfpperiod;
+       u16 bs_cfpmaxduration;
+       u32 bs_cfpnext;
+       u16 bs_timoffset;
+       u16 bs_bmissthreshold;
+       u32 bs_sleepduration;
+       u32 bs_tsfoor_threshold;
+};
+
+struct chan_centers {
+       u16 synth_center;
+       u16 ctl_center;
+       u16 ext_center;
+};
+
+enum {
+       ATH9K_RESET_POWER_ON,
+       ATH9K_RESET_WARM,
+       ATH9K_RESET_COLD,
+};
+
+struct ath9k_hw_version {
+       u32 magic;
+       u16 devid;
+       u16 subvendorid;
+       u32 macVersion;
+       u16 macRev;
+       u16 phyRev;
+       u16 analog5GhzRev;
+       u16 analog2GhzRev;
+};
+
+struct ath_hw {
+       struct ath_softc *ah_sc;
+       struct ath9k_hw_version hw_version;
+       struct ath9k_ops_config config;
+       struct ath9k_hw_capabilities caps;
+       struct ath_regulatory regulatory;
+       struct ath9k_channel channels[38];
+       struct ath9k_channel *curchan;
+
+       union {
+               struct ar5416_eeprom_def def;
+               struct ar5416_eeprom_4k map4k;
+       } eeprom;
+       const struct eeprom_ops *eep_ops;
+       enum ath9k_eep_map eep_map;
+
+       bool sw_mgmt_crypto;
+       bool is_pciexpress;
+       u8 macaddr[ETH_ALEN];
+       u16 tx_trig_level;
+       u16 rfsilent;
+       u32 rfkill_gpio;
+       u32 rfkill_polarity;
+       u32 btactive_gpio;
+       u32 wlanactive_gpio;
+       u32 ah_flags;
+
+       enum nl80211_iftype opmode;
+       enum ath9k_power_mode power_mode;
+       enum ath9k_power_mode restore_mode;
+
+       struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS];
+       struct ar5416Stats stats;
+       struct ath9k_tx_queue_info txq[ATH9K_NUM_TX_QUEUES];
+
+       int16_t curchan_rad_index;
+       u32 mask_reg;
+       u32 txok_interrupt_mask;
+       u32 txerr_interrupt_mask;
+       u32 txdesc_interrupt_mask;
+       u32 txeol_interrupt_mask;
+       u32 txurn_interrupt_mask;
+       bool chip_fullsleep;
+       u32 atim_window;
+       u16 antenna_switch_swap;
+       enum ath9k_ant_setting diversity_control;
+
+       /* Calibration */
+       enum ath9k_cal_types supp_cals;
+       struct ath9k_cal_list iq_caldata;
+       struct ath9k_cal_list adcgain_caldata;
+       struct ath9k_cal_list adcdc_calinitdata;
+       struct ath9k_cal_list adcdc_caldata;
+       struct ath9k_cal_list *cal_list;
+       struct ath9k_cal_list *cal_list_last;
+       struct ath9k_cal_list *cal_list_curr;
+#define totalPowerMeasI meas0.unsign
+#define totalPowerMeasQ meas1.unsign
+#define totalIqCorrMeas meas2.sign
+#define totalAdcIOddPhase  meas0.unsign
+#define totalAdcIEvenPhase meas1.unsign
+#define totalAdcQOddPhase  meas2.unsign
+#define totalAdcQEvenPhase meas3.unsign
+#define totalAdcDcOffsetIOddPhase  meas0.sign
+#define totalAdcDcOffsetIEvenPhase meas1.sign
+#define totalAdcDcOffsetQOddPhase  meas2.sign
+#define totalAdcDcOffsetQEvenPhase meas3.sign
+       union {
+               u32 unsign[AR5416_MAX_CHAINS];
+               int32_t sign[AR5416_MAX_CHAINS];
+       } meas0;
+       union {
+               u32 unsign[AR5416_MAX_CHAINS];
+               int32_t sign[AR5416_MAX_CHAINS];
+       } meas1;
+       union {
+               u32 unsign[AR5416_MAX_CHAINS];
+               int32_t sign[AR5416_MAX_CHAINS];
+       } meas2;
+       union {
+               u32 unsign[AR5416_MAX_CHAINS];
+               int32_t sign[AR5416_MAX_CHAINS];
+       } meas3;
+       u16 cal_samples;
+
+       u32 sta_id1_defaults;
+       u32 misc_mode;
+       enum {
+               AUTO_32KHZ,
+               USE_32KHZ,
+               DONT_USE_32KHZ,
+       } enable_32kHz_clock;
+
+       /* RF */
+       u32 *analogBank0Data;
+       u32 *analogBank1Data;
+       u32 *analogBank2Data;
+       u32 *analogBank3Data;
+       u32 *analogBank6Data;
+       u32 *analogBank6TPCData;
+       u32 *analogBank7Data;
+       u32 *addac5416_21;
+       u32 *bank6Temp;
+
+       int16_t txpower_indexoffset;
+       u32 beacon_interval;
+       u32 slottime;
+       u32 acktimeout;
+       u32 ctstimeout;
+       u32 globaltxtimeout;
+       u8 gbeacon_rate;
+
+       /* ANI */
+       u32 proc_phyerr;
+       bool has_hw_phycounters;
+       u32 aniperiod;
+       struct ar5416AniState *curani;
+       struct ar5416AniState ani[255];
+       int totalSizeDesired[5];
+       int coarse_high[5];
+       int coarse_low[5];
+       int firpwr[5];
+       enum ath9k_ani_cmd ani_function;
+
+       u32 intr_txqs;
+       enum ath9k_ht_extprotspacing extprotspacing;
+       u8 txchainmask;
+       u8 rxchainmask;
+
+       u32 originalGain[22];
+       int initPDADC;
+       int PDADCdelta;
+
+       struct ar5416IniArray iniModes;
+       struct ar5416IniArray iniCommon;
+       struct ar5416IniArray iniBank0;
+       struct ar5416IniArray iniBB_RfGain;
+       struct ar5416IniArray iniBank1;
+       struct ar5416IniArray iniBank2;
+       struct ar5416IniArray iniBank3;
+       struct ar5416IniArray iniBank6;
+       struct ar5416IniArray iniBank6TPC;
+       struct ar5416IniArray iniBank7;
+       struct ar5416IniArray iniAddac;
+       struct ar5416IniArray iniPcieSerdes;
+       struct ar5416IniArray iniModesAdditional;
+       struct ar5416IniArray iniModesRxGain;
+       struct ar5416IniArray iniModesTxGain;
+};
+
+/* Attach, Detach, Reset */
+const char *ath9k_hw_probe(u16 vendorid, u16 devid);
+void ath9k_hw_detach(struct ath_hw *ah);
+struct ath_hw *ath9k_hw_attach(u16 devid, struct ath_softc *sc, int *error);
+void ath9k_hw_rfdetach(struct ath_hw *ah);
+int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
+                  bool bChannelChange);
+void ath9k_hw_fill_cap_info(struct ath_hw *ah);
+bool ath9k_hw_getcapability(struct ath_hw *ah, enum ath9k_capability_type type,
+                           u32 capability, u32 *result);
+bool ath9k_hw_setcapability(struct ath_hw *ah, enum ath9k_capability_type type,
+                           u32 capability, u32 setting, int *status);
+
+/* Key Cache Management */
+bool ath9k_hw_keyreset(struct ath_hw *ah, u16 entry);
+bool ath9k_hw_keysetmac(struct ath_hw *ah, u16 entry, const u8 *mac);
+bool ath9k_hw_set_keycache_entry(struct ath_hw *ah, u16 entry,
+                                const struct ath9k_keyval *k,
+                                const u8 *mac);
+bool ath9k_hw_keyisvalid(struct ath_hw *ah, u16 entry);
+
+/* GPIO / RFKILL / Antennae */
+void ath9k_hw_cfg_gpio_input(struct ath_hw *ah, u32 gpio);
+u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio);
+void ath9k_hw_cfg_output(struct ath_hw *ah, u32 gpio,
+                        u32 ah_signal_type);
+void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val);
+#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
+void ath9k_enable_rfkill(struct ath_hw *ah);
+#endif
+u32 ath9k_hw_getdefantenna(struct ath_hw *ah);
+void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna);
+bool ath9k_hw_setantennaswitch(struct ath_hw *ah,
+                              enum ath9k_ant_setting settings,
+                              struct ath9k_channel *chan,
+                              u8 *tx_chainmask, u8 *rx_chainmask,
+                              u8 *antenna_cfgd);
+
+/* General Operation */
+bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout);
+u32 ath9k_hw_reverse_bits(u32 val, u32 n);
+bool ath9k_get_channel_edges(struct ath_hw *ah, u16 flags, u16 *low, u16 *high);
+u16 ath9k_hw_computetxtime(struct ath_hw *ah,
+                          const struct ath_rate_table *rates,
+                          u32 frameLen, u16 rateix, bool shortPreamble);
+void ath9k_hw_get_channel_centers(struct ath_hw *ah,
+                                 struct ath9k_channel *chan,
+                                 struct chan_centers *centers);
+u32 ath9k_hw_getrxfilter(struct ath_hw *ah);
+void ath9k_hw_setrxfilter(struct ath_hw *ah, u32 bits);
+bool ath9k_hw_phy_disable(struct ath_hw *ah);
+bool ath9k_hw_disable(struct ath_hw *ah);
+void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit);
+void ath9k_hw_setmac(struct ath_hw *ah, const u8 *mac);
+void ath9k_hw_setopmode(struct ath_hw *ah);
+void ath9k_hw_setmcastfilter(struct ath_hw *ah, u32 filter0, u32 filter1);
+void ath9k_hw_setbssidmask(struct ath_softc *sc);
+void ath9k_hw_write_associd(struct ath_softc *sc);
+u64 ath9k_hw_gettsf64(struct ath_hw *ah);
+void ath9k_hw_settsf64(struct ath_hw *ah, u64 tsf64);
+void ath9k_hw_reset_tsf(struct ath_hw *ah);
+bool ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting);
+bool ath9k_hw_setslottime(struct ath_hw *ah, u32 us);
+void ath9k_hw_set11nmac2040(struct ath_hw *ah, enum ath9k_ht_macmode mode);
+void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period);
+void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
+                                   const struct ath9k_beacon_state *bs);
+bool ath9k_hw_setpower(struct ath_hw *ah,
+                      enum ath9k_power_mode mode);
+void ath9k_hw_configpcipowersave(struct ath_hw *ah, int restore);
+
+/* Interrupt Handling */
+bool ath9k_hw_intrpend(struct ath_hw *ah);
+bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked);
+enum ath9k_int ath9k_hw_intrget(struct ath_hw *ah);
+enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints);
+
+void ath9k_hw_btcoex_enable(struct ath_hw *ah);
+
+#endif
diff --git a/drivers/net/wireless/ath/ath9k/initvals.h b/drivers/net/wireless/ath/ath9k/initvals.h
new file mode 100644 (file)
index 0000000..e2f0a34
--- /dev/null
@@ -0,0 +1,4848 @@
+/*
+ * Copyright (c) 2008-2009 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.
+ */
+
+static const u32 ar5416Modes[][6] = {
+    { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
+    { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
+    { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
+    { 0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000, 0x00014008 },
+    { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 },
+    { 0x0000801c, 0x128d93a7, 0x128d93cf, 0x12e013d7, 0x12e013ab, 0x098813cf },
+    { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 },
+    { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 },
+    { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
+    { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 },
+    { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
+    { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 },
+    { 0x00009844, 0x1372161e, 0x1372161e, 0x137216a0, 0x137216a0, 0x137216a0 },
+    { 0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
+    { 0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
+    { 0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
+    { 0x00009850, 0x6c48b4e0, 0x6c48b4e0, 0x6c48b0de, 0x6c48b0de, 0x6c48b0de },
+    { 0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e },
+    { 0x0000985c, 0x31395d5e, 0x31395d5e, 0x31395d5e, 0x31395d5e, 0x31395d5e },
+    { 0x00009860, 0x00049d18, 0x00049d18, 0x00049d18, 0x00049d18, 0x00049d18 },
+    { 0x0000c864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 },
+    { 0x00009868, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190 },
+    { 0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 },
+    { 0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0 },
+    { 0x00009918, 0x000001b8, 0x00000370, 0x00000268, 0x00000134, 0x00000134 },
+    { 0x00009924, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b },
+    { 0x00009944, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020 },
+    { 0x00009960, 0x00000900, 0x00000900, 0x00012d80, 0x00012d80, 0x00012d80 },
+    { 0x0000a960, 0x00000900, 0x00000900, 0x00012d80, 0x00012d80, 0x00012d80 },
+    { 0x0000b960, 0x00000900, 0x00000900, 0x00012d80, 0x00012d80, 0x00012d80 },
+    { 0x00009964, 0x00000000, 0x00000000, 0x00001120, 0x00001120, 0x00001120 },
+    { 0x0000c9bc, 0x001a0a00, 0x001a0a00, 0x001a0a00, 0x001a0a00, 0x001a0a00 },
+    { 0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, 0x038919be },
+    { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 },
+    { 0x000099c8, 0x60f6532c, 0x60f6532c, 0x60f6532c, 0x60f6532c, 0x60f6532c },
+    { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 },
+    { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 },
+    { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x0000a204, 0x00000880, 0x00000880, 0x00000880, 0x00000880, 0x00000880 },
+    { 0x0000a208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, 0xd03e4788 },
+    { 0x0000a20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 },
+    { 0x0000b20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 },
+    { 0x0000c20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 },
+    { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a },
+    { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
+    { 0x0000a274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, 0x0a1a7caa },
+    { 0x0000a300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000 },
+    { 0x0000a304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, 0x2e032402 },
+    { 0x0000a308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, 0x4a0a3c06 },
+    { 0x0000a30c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, 0x621a540b },
+    { 0x0000a310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, 0x764f6c1b },
+    { 0x0000a314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, 0x845b7a5a },
+    { 0x0000a318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, 0x950f8ccf },
+    { 0x0000a31c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, 0xa5cf9b4f },
+    { 0x0000a320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, 0xbddfaf1f },
+    { 0x0000a324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, 0xd1ffc93f },
+    { 0x0000a328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x0000a32c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x0000a330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+};
+
+static const u32 ar5416Common[][2] = {
+    { 0x0000000c, 0x00000000 },
+    { 0x00000030, 0x00020015 },
+    { 0x00000034, 0x00000005 },
+    { 0x00000040, 0x00000000 },
+    { 0x00000044, 0x00000008 },
+    { 0x00000048, 0x00000008 },
+    { 0x0000004c, 0x00000010 },
+    { 0x00000050, 0x00000000 },
+    { 0x00000054, 0x0000001f },
+    { 0x00000800, 0x00000000 },
+    { 0x00000804, 0x00000000 },
+    { 0x00000808, 0x00000000 },
+    { 0x0000080c, 0x00000000 },
+    { 0x00000810, 0x00000000 },
+    { 0x00000814, 0x00000000 },
+    { 0x00000818, 0x00000000 },
+    { 0x0000081c, 0x00000000 },
+    { 0x00000820, 0x00000000 },
+    { 0x00000824, 0x00000000 },
+    { 0x00001040, 0x002ffc0f },
+    { 0x00001044, 0x002ffc0f },
+    { 0x00001048, 0x002ffc0f },
+    { 0x0000104c, 0x002ffc0f },
+    { 0x00001050, 0x002ffc0f },
+    { 0x00001054, 0x002ffc0f },
+    { 0x00001058, 0x002ffc0f },
+    { 0x0000105c, 0x002ffc0f },
+    { 0x00001060, 0x002ffc0f },
+    { 0x00001064, 0x002ffc0f },
+    { 0x00001230, 0x00000000 },
+    { 0x00001270, 0x00000000 },
+    { 0x00001038, 0x00000000 },
+    { 0x00001078, 0x00000000 },
+    { 0x000010b8, 0x00000000 },
+    { 0x000010f8, 0x00000000 },
+    { 0x00001138, 0x00000000 },
+    { 0x00001178, 0x00000000 },
+    { 0x000011b8, 0x00000000 },
+    { 0x000011f8, 0x00000000 },
+    { 0x00001238, 0x00000000 },
+    { 0x00001278, 0x00000000 },
+    { 0x000012b8, 0x00000000 },
+    { 0x000012f8, 0x00000000 },
+    { 0x00001338, 0x00000000 },
+    { 0x00001378, 0x00000000 },
+    { 0x000013b8, 0x00000000 },
+    { 0x000013f8, 0x00000000 },
+    { 0x00001438, 0x00000000 },
+    { 0x00001478, 0x00000000 },
+    { 0x000014b8, 0x00000000 },
+    { 0x000014f8, 0x00000000 },
+    { 0x00001538, 0x00000000 },
+    { 0x00001578, 0x00000000 },
+    { 0x000015b8, 0x00000000 },
+    { 0x000015f8, 0x00000000 },
+    { 0x00001638, 0x00000000 },
+    { 0x00001678, 0x00000000 },
+    { 0x000016b8, 0x00000000 },
+    { 0x000016f8, 0x00000000 },
+    { 0x00001738, 0x00000000 },
+    { 0x00001778, 0x00000000 },
+    { 0x000017b8, 0x00000000 },
+    { 0x000017f8, 0x00000000 },
+    { 0x0000103c, 0x00000000 },
+    { 0x0000107c, 0x00000000 },
+    { 0x000010bc, 0x00000000 },
+    { 0x000010fc, 0x00000000 },
+    { 0x0000113c, 0x00000000 },
+    { 0x0000117c, 0x00000000 },
+    { 0x000011bc, 0x00000000 },
+    { 0x000011fc, 0x00000000 },
+    { 0x0000123c, 0x00000000 },
+    { 0x0000127c, 0x00000000 },
+    { 0x000012bc, 0x00000000 },
+    { 0x000012fc, 0x00000000 },
+    { 0x0000133c, 0x00000000 },
+    { 0x0000137c, 0x00000000 },
+    { 0x000013bc, 0x00000000 },
+    { 0x000013fc, 0x00000000 },
+    { 0x0000143c, 0x00000000 },
+    { 0x0000147c, 0x00000000 },
+    { 0x00004030, 0x00000002 },
+    { 0x0000403c, 0x00000002 },
+    { 0x00007010, 0x00000000 },
+    { 0x00007038, 0x000004c2 },
+    { 0x00008004, 0x00000000 },
+    { 0x00008008, 0x00000000 },
+    { 0x0000800c, 0x00000000 },
+    { 0x00008018, 0x00000700 },
+    { 0x00008020, 0x00000000 },
+    { 0x00008038, 0x00000000 },
+    { 0x0000803c, 0x00000000 },
+    { 0x00008048, 0x40000000 },
+    { 0x00008054, 0x00000000 },
+    { 0x00008058, 0x00000000 },
+    { 0x0000805c, 0x000fc78f },
+    { 0x00008060, 0x0000000f },
+    { 0x00008064, 0x00000000 },
+    { 0x000080c0, 0x2a82301a },
+    { 0x000080c4, 0x05dc01e0 },
+    { 0x000080c8, 0x1f402710 },
+    { 0x000080cc, 0x01f40000 },
+    { 0x000080d0, 0x00001e00 },
+    { 0x000080d4, 0x00000000 },
+    { 0x000080d8, 0x00400000 },
+    { 0x000080e0, 0xffffffff },
+    { 0x000080e4, 0x0000ffff },
+    { 0x000080e8, 0x003f3f3f },
+    { 0x000080ec, 0x00000000 },
+    { 0x000080f0, 0x00000000 },
+    { 0x000080f4, 0x00000000 },
+    { 0x000080f8, 0x00000000 },
+    { 0x000080fc, 0x00020000 },
+    { 0x00008100, 0x00020000 },
+    { 0x00008104, 0x00000001 },
+    { 0x00008108, 0x00000052 },
+    { 0x0000810c, 0x00000000 },
+    { 0x00008110, 0x00000168 },
+    { 0x00008118, 0x000100aa },
+    { 0x0000811c, 0x00003210 },
+    { 0x00008120, 0x08f04800 },
+    { 0x00008124, 0x00000000 },
+    { 0x00008128, 0x00000000 },
+    { 0x0000812c, 0x00000000 },
+    { 0x00008130, 0x00000000 },
+    { 0x00008134, 0x00000000 },
+    { 0x00008138, 0x00000000 },
+    { 0x0000813c, 0x00000000 },
+    { 0x00008144, 0xffffffff },
+    { 0x00008168, 0x00000000 },
+    { 0x0000816c, 0x00000000 },
+    { 0x00008170, 0x32143320 },
+    { 0x00008174, 0xfaa4fa50 },
+    { 0x00008178, 0x00000100 },
+    { 0x0000817c, 0x00000000 },
+    { 0x000081c4, 0x00000000 },
+    { 0x000081d0, 0x00003210 },
+    { 0x000081ec, 0x00000000 },
+    { 0x000081f0, 0x00000000 },
+    { 0x000081f4, 0x00000000 },
+    { 0x000081f8, 0x00000000 },
+    { 0x000081fc, 0x00000000 },
+    { 0x00008200, 0x00000000 },
+    { 0x00008204, 0x00000000 },
+    { 0x00008208, 0x00000000 },
+    { 0x0000820c, 0x00000000 },
+    { 0x00008210, 0x00000000 },
+    { 0x00008214, 0x00000000 },
+    { 0x00008218, 0x00000000 },
+    { 0x0000821c, 0x00000000 },
+    { 0x00008220, 0x00000000 },
+    { 0x00008224, 0x00000000 },
+    { 0x00008228, 0x00000000 },
+    { 0x0000822c, 0x00000000 },
+    { 0x00008230, 0x00000000 },
+    { 0x00008234, 0x00000000 },
+    { 0x00008238, 0x00000000 },
+    { 0x0000823c, 0x00000000 },
+    { 0x00008240, 0x00100000 },
+    { 0x00008244, 0x0010f400 },
+    { 0x00008248, 0x00000100 },
+    { 0x0000824c, 0x0001e800 },
+    { 0x00008250, 0x00000000 },
+    { 0x00008254, 0x00000000 },
+    { 0x00008258, 0x00000000 },
+    { 0x0000825c, 0x400000ff },
+    { 0x00008260, 0x00080922 },
+    { 0x00008270, 0x00000000 },
+    { 0x00008274, 0x40000000 },
+    { 0x00008278, 0x003e4180 },
+    { 0x0000827c, 0x00000000 },
+    { 0x00008284, 0x0000002c },
+    { 0x00008288, 0x0000002c },
+    { 0x0000828c, 0x00000000 },
+    { 0x00008294, 0x00000000 },
+    { 0x00008298, 0x00000000 },
+    { 0x00008300, 0x00000000 },
+    { 0x00008304, 0x00000000 },
+    { 0x00008308, 0x00000000 },
+    { 0x0000830c, 0x00000000 },
+    { 0x00008310, 0x00000000 },
+    { 0x00008314, 0x00000000 },
+    { 0x00008318, 0x00000000 },
+    { 0x00008328, 0x00000000 },
+    { 0x0000832c, 0x00000007 },
+    { 0x00008330, 0x00000302 },
+    { 0x00008334, 0x00000e00 },
+    { 0x00008338, 0x00070000 },
+    { 0x0000833c, 0x00000000 },
+    { 0x00008340, 0x000107ff },
+    { 0x00009808, 0x00000000 },
+    { 0x0000980c, 0xad848e19 },
+    { 0x00009810, 0x7d14e000 },
+    { 0x00009814, 0x9c0a9f6b },
+    { 0x0000981c, 0x00000000 },
+    { 0x0000982c, 0x0000a000 },
+    { 0x00009830, 0x00000000 },
+    { 0x0000983c, 0x00200400 },
+    { 0x00009840, 0x206a002e },
+    { 0x0000984c, 0x1284233c },
+    { 0x00009854, 0x00000859 },
+    { 0x00009900, 0x00000000 },
+    { 0x00009904, 0x00000000 },
+    { 0x00009908, 0x00000000 },
+    { 0x0000990c, 0x00000000 },
+    { 0x0000991c, 0x10000fff },
+    { 0x00009920, 0x05100000 },
+    { 0x0000a920, 0x05100000 },
+    { 0x0000b920, 0x05100000 },
+    { 0x00009928, 0x00000001 },
+    { 0x0000992c, 0x00000004 },
+    { 0x00009934, 0x1e1f2022 },
+    { 0x00009938, 0x0a0b0c0d },
+    { 0x0000993c, 0x00000000 },
+    { 0x00009948, 0x9280b212 },
+    { 0x0000994c, 0x00020028 },
+    { 0x00009954, 0x5d50e188 },
+    { 0x00009958, 0x00081fff },
+    { 0x0000c95c, 0x004b6a8e },
+    { 0x0000c968, 0x000003ce },
+    { 0x00009970, 0x190fb515 },
+    { 0x00009974, 0x00000000 },
+    { 0x00009978, 0x00000001 },
+    { 0x0000997c, 0x00000000 },
+    { 0x00009980, 0x00000000 },
+    { 0x00009984, 0x00000000 },
+    { 0x00009988, 0x00000000 },
+    { 0x0000998c, 0x00000000 },
+    { 0x00009990, 0x00000000 },
+    { 0x00009994, 0x00000000 },
+    { 0x00009998, 0x00000000 },
+    { 0x0000999c, 0x00000000 },
+    { 0x000099a0, 0x00000000 },
+    { 0x000099a4, 0x00000001 },
+    { 0x000099a8, 0x001fff00 },
+    { 0x000099ac, 0x00000000 },
+    { 0x000099b0, 0x03051000 },
+    { 0x000099dc, 0x00000000 },
+    { 0x000099e0, 0x00000200 },
+    { 0x000099e4, 0xaaaaaaaa },
+    { 0x000099e8, 0x3c466478 },
+    { 0x000099ec, 0x000000aa },
+    { 0x000099fc, 0x00001042 },
+    { 0x00009b00, 0x00000000 },
+    { 0x00009b04, 0x00000001 },
+    { 0x00009b08, 0x00000002 },
+    { 0x00009b0c, 0x00000003 },
+    { 0x00009b10, 0x00000004 },
+    { 0x00009b14, 0x00000005 },
+    { 0x00009b18, 0x00000008 },
+    { 0x00009b1c, 0x00000009 },
+    { 0x00009b20, 0x0000000a },
+    { 0x00009b24, 0x0000000b },
+    { 0x00009b28, 0x0000000c },
+    { 0x00009b2c, 0x0000000d },
+    { 0x00009b30, 0x00000010 },
+    { 0x00009b34, 0x00000011 },
+    { 0x00009b38, 0x00000012 },
+    { 0x00009b3c, 0x00000013 },
+    { 0x00009b40, 0x00000014 },
+    { 0x00009b44, 0x00000015 },
+    { 0x00009b48, 0x00000018 },
+    { 0x00009b4c, 0x00000019 },
+    { 0x00009b50, 0x0000001a },
+    { 0x00009b54, 0x0000001b },
+    { 0x00009b58, 0x0000001c },
+    { 0x00009b5c, 0x0000001d },
+    { 0x00009b60, 0x00000020 },
+    { 0x00009b64, 0x00000021 },
+    { 0x00009b68, 0x00000022 },
+    { 0x00009b6c, 0x00000023 },
+    { 0x00009b70, 0x00000024 },
+    { 0x00009b74, 0x00000025 },
+    { 0x00009b78, 0x00000028 },
+    { 0x00009b7c, 0x00000029 },
+    { 0x00009b80, 0x0000002a },
+    { 0x00009b84, 0x0000002b },
+    { 0x00009b88, 0x0000002c },
+    { 0x00009b8c, 0x0000002d },
+    { 0x00009b90, 0x00000030 },
+    { 0x00009b94, 0x00000031 },
+    { 0x00009b98, 0x00000032 },
+    { 0x00009b9c, 0x00000033 },
+    { 0x00009ba0, 0x00000034 },
+    { 0x00009ba4, 0x00000035 },
+    { 0x00009ba8, 0x00000035 },
+    { 0x00009bac, 0x00000035 },
+    { 0x00009bb0, 0x00000035 },
+    { 0x00009bb4, 0x00000035 },
+    { 0x00009bb8, 0x00000035 },
+    { 0x00009bbc, 0x00000035 },
+    { 0x00009bc0, 0x00000035 },
+    { 0x00009bc4, 0x00000035 },
+    { 0x00009bc8, 0x00000035 },
+    { 0x00009bcc, 0x00000035 },
+    { 0x00009bd0, 0x00000035 },
+    { 0x00009bd4, 0x00000035 },
+    { 0x00009bd8, 0x00000035 },
+    { 0x00009bdc, 0x00000035 },
+    { 0x00009be0, 0x00000035 },
+    { 0x00009be4, 0x00000035 },
+    { 0x00009be8, 0x00000035 },
+    { 0x00009bec, 0x00000035 },
+    { 0x00009bf0, 0x00000035 },
+    { 0x00009bf4, 0x00000035 },
+    { 0x00009bf8, 0x00000010 },
+    { 0x00009bfc, 0x0000001a },
+    { 0x0000a210, 0x40806333 },
+    { 0x0000a214, 0x00106c10 },
+    { 0x0000a218, 0x009c4060 },
+    { 0x0000a220, 0x018830c6 },
+    { 0x0000a224, 0x00000400 },
+    { 0x0000a228, 0x00000bb5 },
+    { 0x0000a22c, 0x00000011 },
+    { 0x0000a234, 0x20202020 },
+    { 0x0000a238, 0x20202020 },
+    { 0x0000a23c, 0x13c889af },
+    { 0x0000a240, 0x38490a20 },
+    { 0x0000a244, 0x00007bb6 },
+    { 0x0000a248, 0x0fff3ffc },
+    { 0x0000a24c, 0x00000001 },
+    { 0x0000a250, 0x0000a000 },
+    { 0x0000a254, 0x00000000 },
+    { 0x0000a258, 0x0cc75380 },
+    { 0x0000a25c, 0x0f0f0f01 },
+    { 0x0000a260, 0xdfa91f01 },
+    { 0x0000a268, 0x00000000 },
+    { 0x0000a26c, 0x0ebae9c6 },
+    { 0x0000b26c, 0x0ebae9c6 },
+    { 0x0000c26c, 0x0ebae9c6 },
+    { 0x0000d270, 0x00820820 },
+    { 0x0000a278, 0x1ce739ce },
+    { 0x0000a27c, 0x051701ce },
+    { 0x0000a338, 0x00000000 },
+    { 0x0000a33c, 0x00000000 },
+    { 0x0000a340, 0x00000000 },
+    { 0x0000a344, 0x00000000 },
+    { 0x0000a348, 0x3fffffff },
+    { 0x0000a34c, 0x3fffffff },
+    { 0x0000a350, 0x3fffffff },
+    { 0x0000a354, 0x0003ffff },
+    { 0x0000a358, 0x79a8aa1f },
+    { 0x0000d35c, 0x07ffffef },
+    { 0x0000d360, 0x0fffffe7 },
+    { 0x0000d364, 0x17ffffe5 },
+    { 0x0000d368, 0x1fffffe4 },
+    { 0x0000d36c, 0x37ffffe3 },
+    { 0x0000d370, 0x3fffffe3 },
+    { 0x0000d374, 0x57ffffe3 },
+    { 0x0000d378, 0x5fffffe2 },
+    { 0x0000d37c, 0x7fffffe2 },
+    { 0x0000d380, 0x7f3c7bba },
+    { 0x0000d384, 0xf3307ff0 },
+    { 0x0000a388, 0x08000000 },
+    { 0x0000a38c, 0x20202020 },
+    { 0x0000a390, 0x20202020 },
+    { 0x0000a394, 0x1ce739ce },
+    { 0x0000a398, 0x000001ce },
+    { 0x0000a39c, 0x00000001 },
+    { 0x0000a3a0, 0x00000000 },
+    { 0x0000a3a4, 0x00000000 },
+    { 0x0000a3a8, 0x00000000 },
+    { 0x0000a3ac, 0x00000000 },
+    { 0x0000a3b0, 0x00000000 },
+    { 0x0000a3b4, 0x00000000 },
+    { 0x0000a3b8, 0x00000000 },
+    { 0x0000a3bc, 0x00000000 },
+    { 0x0000a3c0, 0x00000000 },
+    { 0x0000a3c4, 0x00000000 },
+    { 0x0000a3c8, 0x00000246 },
+    { 0x0000a3cc, 0x20202020 },
+    { 0x0000a3d0, 0x20202020 },
+    { 0x0000a3d4, 0x20202020 },
+    { 0x0000a3dc, 0x1ce739ce },
+    { 0x0000a3e0, 0x000001ce },
+};
+
+static const u32 ar5416Bank0[][2] = {
+    { 0x000098b0, 0x1e5795e5 },
+    { 0x000098e0, 0x02008020 },
+};
+
+static const u32 ar5416BB_RfGain[][3] = {
+    { 0x00009a00, 0x00000000, 0x00000000 },
+    { 0x00009a04, 0x00000040, 0x00000040 },
+    { 0x00009a08, 0x00000080, 0x00000080 },
+    { 0x00009a0c, 0x000001a1, 0x00000141 },
+    { 0x00009a10, 0x000001e1, 0x00000181 },
+    { 0x00009a14, 0x00000021, 0x000001c1 },
+    { 0x00009a18, 0x00000061, 0x00000001 },
+    { 0x00009a1c, 0x00000168, 0x00000041 },
+    { 0x00009a20, 0x000001a8, 0x000001a8 },
+    { 0x00009a24, 0x000001e8, 0x000001e8 },
+    { 0x00009a28, 0x00000028, 0x00000028 },
+    { 0x00009a2c, 0x00000068, 0x00000068 },
+    { 0x00009a30, 0x00000189, 0x000000a8 },
+    { 0x00009a34, 0x000001c9, 0x00000169 },
+    { 0x00009a38, 0x00000009, 0x000001a9 },
+    { 0x00009a3c, 0x00000049, 0x000001e9 },
+    { 0x00009a40, 0x00000089, 0x00000029 },
+    { 0x00009a44, 0x00000170, 0x00000069 },
+    { 0x00009a48, 0x000001b0, 0x00000190 },
+    { 0x00009a4c, 0x000001f0, 0x000001d0 },
+    { 0x00009a50, 0x00000030, 0x00000010 },
+    { 0x00009a54, 0x00000070, 0x00000050 },
+    { 0x00009a58, 0x00000191, 0x00000090 },
+    { 0x00009a5c, 0x000001d1, 0x00000151 },
+    { 0x00009a60, 0x00000011, 0x00000191 },
+    { 0x00009a64, 0x00000051, 0x000001d1 },
+    { 0x00009a68, 0x00000091, 0x00000011 },
+    { 0x00009a6c, 0x000001b8, 0x00000051 },
+    { 0x00009a70, 0x000001f8, 0x00000198 },
+    { 0x00009a74, 0x00000038, 0x000001d8 },
+    { 0x00009a78, 0x00000078, 0x00000018 },
+    { 0x00009a7c, 0x00000199, 0x00000058 },
+    { 0x00009a80, 0x000001d9, 0x00000098 },
+    { 0x00009a84, 0x00000019, 0x00000159 },
+    { 0x00009a88, 0x00000059, 0x00000199 },
+    { 0x00009a8c, 0x00000099, 0x000001d9 },
+    { 0x00009a90, 0x000000d9, 0x00000019 },
+    { 0x00009a94, 0x000000f9, 0x00000059 },
+    { 0x00009a98, 0x000000f9, 0x00000099 },
+    { 0x00009a9c, 0x000000f9, 0x000000d9 },
+    { 0x00009aa0, 0x000000f9, 0x000000f9 },
+    { 0x00009aa4, 0x000000f9, 0x000000f9 },
+    { 0x00009aa8, 0x000000f9, 0x000000f9 },
+    { 0x00009aac, 0x000000f9, 0x000000f9 },
+    { 0x00009ab0, 0x000000f9, 0x000000f9 },
+    { 0x00009ab4, 0x000000f9, 0x000000f9 },
+    { 0x00009ab8, 0x000000f9, 0x000000f9 },
+    { 0x00009abc, 0x000000f9, 0x000000f9 },
+    { 0x00009ac0, 0x000000f9, 0x000000f9 },
+    { 0x00009ac4, 0x000000f9, 0x000000f9 },
+    { 0x00009ac8, 0x000000f9, 0x000000f9 },
+    { 0x00009acc, 0x000000f9, 0x000000f9 },
+    { 0x00009ad0, 0x000000f9, 0x000000f9 },
+    { 0x00009ad4, 0x000000f9, 0x000000f9 },
+    { 0x00009ad8, 0x000000f9, 0x000000f9 },
+    { 0x00009adc, 0x000000f9, 0x000000f9 },
+    { 0x00009ae0, 0x000000f9, 0x000000f9 },
+    { 0x00009ae4, 0x000000f9, 0x000000f9 },
+    { 0x00009ae8, 0x000000f9, 0x000000f9 },
+    { 0x00009aec, 0x000000f9, 0x000000f9 },
+    { 0x00009af0, 0x000000f9, 0x000000f9 },
+    { 0x00009af4, 0x000000f9, 0x000000f9 },
+    { 0x00009af8, 0x000000f9, 0x000000f9 },
+    { 0x00009afc, 0x000000f9, 0x000000f9 },
+};
+
+static const u32 ar5416Bank1[][2] = {
+    { 0x000098b0, 0x02108421 },
+    { 0x000098ec, 0x00000008 },
+};
+
+static const u32 ar5416Bank2[][2] = {
+    { 0x000098b0, 0x0e73ff17 },
+    { 0x000098e0, 0x00000420 },
+};
+
+static const u32 ar5416Bank3[][3] = {
+    { 0x000098f0, 0x01400018, 0x01c00018 },
+};
+
+static const u32 ar5416Bank6[][3] = {
+
+    { 0x0000989c, 0x00000000, 0x00000000 },
+    { 0x0000989c, 0x00000000, 0x00000000 },
+    { 0x0000989c, 0x00000000, 0x00000000 },
+    { 0x0000989c, 0x00e00000, 0x00e00000 },
+    { 0x0000989c, 0x005e0000, 0x005e0000 },
+    { 0x0000989c, 0x00120000, 0x00120000 },
+    { 0x0000989c, 0x00620000, 0x00620000 },
+    { 0x0000989c, 0x00020000, 0x00020000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x40ff0000, 0x40ff0000 },
+    { 0x0000989c, 0x005f0000, 0x005f0000 },
+    { 0x0000989c, 0x00870000, 0x00870000 },
+    { 0x0000989c, 0x00f90000, 0x00f90000 },
+    { 0x0000989c, 0x007b0000, 0x007b0000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x00f50000, 0x00f50000 },
+    { 0x0000989c, 0x00dc0000, 0x00dc0000 },
+    { 0x0000989c, 0x00110000, 0x00110000 },
+    { 0x0000989c, 0x006100a8, 0x006100a8 },
+    { 0x0000989c, 0x004210a2, 0x004210a2 },
+    { 0x0000989c, 0x0014008f, 0x0014008f },
+    { 0x0000989c, 0x00c40003, 0x00c40003 },
+    { 0x0000989c, 0x003000f2, 0x003000f2 },
+    { 0x0000989c, 0x00440016, 0x00440016 },
+    { 0x0000989c, 0x00410040, 0x00410040 },
+    { 0x0000989c, 0x0001805e, 0x0001805e },
+    { 0x0000989c, 0x0000c0ab, 0x0000c0ab },
+    { 0x0000989c, 0x000000f1, 0x000000f1 },
+    { 0x0000989c, 0x00002081, 0x00002081 },
+    { 0x0000989c, 0x000000d4, 0x000000d4 },
+    { 0x000098d0, 0x0000000f, 0x0010000f },
+};
+
+static const u32 ar5416Bank6TPC[][3] = {
+    { 0x0000989c, 0x00000000, 0x00000000 },
+    { 0x0000989c, 0x00000000, 0x00000000 },
+    { 0x0000989c, 0x00000000, 0x00000000 },
+    { 0x0000989c, 0x00e00000, 0x00e00000 },
+    { 0x0000989c, 0x005e0000, 0x005e0000 },
+    { 0x0000989c, 0x00120000, 0x00120000 },
+    { 0x0000989c, 0x00620000, 0x00620000 },
+    { 0x0000989c, 0x00020000, 0x00020000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x40ff0000, 0x40ff0000 },
+    { 0x0000989c, 0x005f0000, 0x005f0000 },
+    { 0x0000989c, 0x00870000, 0x00870000 },
+    { 0x0000989c, 0x00f90000, 0x00f90000 },
+    { 0x0000989c, 0x007b0000, 0x007b0000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x00f50000, 0x00f50000 },
+    { 0x0000989c, 0x00dc0000, 0x00dc0000 },
+    { 0x0000989c, 0x00110000, 0x00110000 },
+    { 0x0000989c, 0x006100a8, 0x006100a8 },
+    { 0x0000989c, 0x00423022, 0x00423022 },
+    { 0x0000989c, 0x201400df, 0x201400df },
+    { 0x0000989c, 0x00c40002, 0x00c40002 },
+    { 0x0000989c, 0x003000f2, 0x003000f2 },
+    { 0x0000989c, 0x00440016, 0x00440016 },
+    { 0x0000989c, 0x00410040, 0x00410040 },
+    { 0x0000989c, 0x0001805e, 0x0001805e },
+    { 0x0000989c, 0x0000c0ab, 0x0000c0ab },
+    { 0x0000989c, 0x000000e1, 0x000000e1 },
+    { 0x0000989c, 0x00007081, 0x00007081 },
+    { 0x0000989c, 0x000000d4, 0x000000d4 },
+    { 0x000098d0, 0x0000000f, 0x0010000f },
+};
+
+static const u32 ar5416Bank7[][2] = {
+    { 0x0000989c, 0x00000500 },
+    { 0x0000989c, 0x00000800 },
+    { 0x000098cc, 0x0000000e },
+};
+
+static const u32 ar5416Addac[][2] = {
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000003 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x0000000c },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000030 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000060 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000058 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x000098cc,  0x00000000 },
+};
+
+static const u32 ar5416Modes_9100[][6] = {
+    { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
+    { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
+    { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
+    { 0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000, 0x00014008 },
+    { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 },
+    { 0x0000801c, 0x128d93a7, 0x128d93cf, 0x12e013d7, 0x12e013ab, 0x098813cf },
+    { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 },
+    { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 },
+    { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
+    { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 },
+    { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
+    { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 },
+    { 0x00009844, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0, 0x037216a0 },
+    { 0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
+    { 0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
+    { 0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
+    { 0x00009850, 0x6d48b4e2, 0x6d48b4e2, 0x6d48b0e2, 0x6d48b0e2, 0x6d48b0e2 },
+    { 0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec86d2e, 0x7ec84d2e, 0x7ec82d2e },
+    { 0x0000985c, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e },
+    { 0x00009860, 0x00048d18, 0x00048d18, 0x00048d20, 0x00048d20, 0x00048d18 },
+    { 0x0000c864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 },
+    { 0x00009868, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0 },
+    { 0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 },
+    { 0x00009914, 0x000007d0, 0x000007d0, 0x00000898, 0x00000898, 0x000007d0 },
+    { 0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016 },
+    { 0x00009924, 0xd00a8a07, 0xd00a8a07, 0xd00a8a11, 0xd00a8a0d, 0xd00a8a0d },
+    { 0x00009940, 0x00754604, 0x00754604, 0xfff81204, 0xfff81204, 0xfff81204 },
+    { 0x00009944, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020 },
+    { 0x00009954, 0x5f3ca3de, 0x5f3ca3de, 0xe250a51e, 0xe250a51e, 0xe250a51e },
+    { 0x00009958, 0x2108ecff, 0x2108ecff, 0x3388ffff, 0x3388ffff, 0x3388ffff },
+#ifdef TB243
+    { 0x00009960, 0x00000900, 0x00000900, 0x00009b40, 0x00009b40, 0x00012d80 },
+    { 0x0000a960, 0x00000900, 0x00000900, 0x00009b40, 0x00009b40, 0x00012d80 },
+    { 0x0000b960, 0x00000900, 0x00000900, 0x00009b40, 0x00009b40, 0x00012d80 },
+    { 0x00009964, 0x00000000, 0x00000000, 0x00002210, 0x00002210, 0x00001120 },
+#else
+    { 0x00009960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0 },
+    { 0x0000a960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0 },
+    { 0x0000b960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0 },
+    { 0x00009964, 0x00001120, 0x00001120, 0x00001120, 0x00001120, 0x00001120 },
+#endif
+    { 0x0000c9bc, 0x001a0600, 0x001a0600, 0x001a1000, 0x001a0c00, 0x001a0c00 },
+    { 0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, 0x038919be },
+    { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 },
+    { 0x000099c8, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329 },
+    { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 },
+    { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 },
+    { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x0000a204, 0x00000880, 0x00000880, 0x00000880, 0x00000880, 0x00000880 },
+    { 0x0000a208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, 0xd03e4788 },
+    { 0x0000a20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 },
+    { 0x0000b20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 },
+    { 0x0000c20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 },
+    { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a },
+    { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
+    { 0x0000a274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, 0x0a1a7caa },
+    { 0x0000a300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000 },
+    { 0x0000a304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, 0x2e032402 },
+    { 0x0000a308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, 0x4a0a3c06 },
+    { 0x0000a30c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, 0x621a540b },
+    { 0x0000a310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, 0x764f6c1b },
+    { 0x0000a314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, 0x845b7a5a },
+    { 0x0000a318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, 0x950f8ccf },
+    { 0x0000a31c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, 0xa5cf9b4f },
+    { 0x0000a320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, 0xbddfaf1f },
+    { 0x0000a324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, 0xd1ffc93f },
+    { 0x0000a328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x0000a32c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x0000a330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+};
+
+static const u32 ar5416Common_9100[][2] = {
+    { 0x0000000c, 0x00000000 },
+    { 0x00000030, 0x00020015 },
+    { 0x00000034, 0x00000005 },
+    { 0x00000040, 0x00000000 },
+    { 0x00000044, 0x00000008 },
+    { 0x00000048, 0x00000008 },
+    { 0x0000004c, 0x00000010 },
+    { 0x00000050, 0x00000000 },
+    { 0x00000054, 0x0000001f },
+    { 0x00000800, 0x00000000 },
+    { 0x00000804, 0x00000000 },
+    { 0x00000808, 0x00000000 },
+    { 0x0000080c, 0x00000000 },
+    { 0x00000810, 0x00000000 },
+    { 0x00000814, 0x00000000 },
+    { 0x00000818, 0x00000000 },
+    { 0x0000081c, 0x00000000 },
+    { 0x00000820, 0x00000000 },
+    { 0x00000824, 0x00000000 },
+    { 0x00001040, 0x002ffc0f },
+    { 0x00001044, 0x002ffc0f },
+    { 0x00001048, 0x002ffc0f },
+    { 0x0000104c, 0x002ffc0f },
+    { 0x00001050, 0x002ffc0f },
+    { 0x00001054, 0x002ffc0f },
+    { 0x00001058, 0x002ffc0f },
+    { 0x0000105c, 0x002ffc0f },
+    { 0x00001060, 0x002ffc0f },
+    { 0x00001064, 0x002ffc0f },
+    { 0x00001230, 0x00000000 },
+    { 0x00001270, 0x00000000 },
+    { 0x00001038, 0x00000000 },
+    { 0x00001078, 0x00000000 },
+    { 0x000010b8, 0x00000000 },
+    { 0x000010f8, 0x00000000 },
+    { 0x00001138, 0x00000000 },
+    { 0x00001178, 0x00000000 },
+    { 0x000011b8, 0x00000000 },
+    { 0x000011f8, 0x00000000 },
+    { 0x00001238, 0x00000000 },
+    { 0x00001278, 0x00000000 },
+    { 0x000012b8, 0x00000000 },
+    { 0x000012f8, 0x00000000 },
+    { 0x00001338, 0x00000000 },
+    { 0x00001378, 0x00000000 },
+    { 0x000013b8, 0x00000000 },
+    { 0x000013f8, 0x00000000 },
+    { 0x00001438, 0x00000000 },
+    { 0x00001478, 0x00000000 },
+    { 0x000014b8, 0x00000000 },
+    { 0x000014f8, 0x00000000 },
+    { 0x00001538, 0x00000000 },
+    { 0x00001578, 0x00000000 },
+    { 0x000015b8, 0x00000000 },
+    { 0x000015f8, 0x00000000 },
+    { 0x00001638, 0x00000000 },
+    { 0x00001678, 0x00000000 },
+    { 0x000016b8, 0x00000000 },
+    { 0x000016f8, 0x00000000 },
+    { 0x00001738, 0x00000000 },
+    { 0x00001778, 0x00000000 },
+    { 0x000017b8, 0x00000000 },
+    { 0x000017f8, 0x00000000 },
+    { 0x0000103c, 0x00000000 },
+    { 0x0000107c, 0x00000000 },
+    { 0x000010bc, 0x00000000 },
+    { 0x000010fc, 0x00000000 },
+    { 0x0000113c, 0x00000000 },
+    { 0x0000117c, 0x00000000 },
+    { 0x000011bc, 0x00000000 },
+    { 0x000011fc, 0x00000000 },
+    { 0x0000123c, 0x00000000 },
+    { 0x0000127c, 0x00000000 },
+    { 0x000012bc, 0x00000000 },
+    { 0x000012fc, 0x00000000 },
+    { 0x0000133c, 0x00000000 },
+    { 0x0000137c, 0x00000000 },
+    { 0x000013bc, 0x00000000 },
+    { 0x000013fc, 0x00000000 },
+    { 0x0000143c, 0x00000000 },
+    { 0x0000147c, 0x00000000 },
+    { 0x00020010, 0x00000003 },
+    { 0x00020038, 0x000004c2 },
+    { 0x00008004, 0x00000000 },
+    { 0x00008008, 0x00000000 },
+    { 0x0000800c, 0x00000000 },
+    { 0x00008018, 0x00000700 },
+    { 0x00008020, 0x00000000 },
+    { 0x00008038, 0x00000000 },
+    { 0x0000803c, 0x00000000 },
+    { 0x00008048, 0x40000000 },
+    { 0x00008054, 0x00004000 },
+    { 0x00008058, 0x00000000 },
+    { 0x0000805c, 0x000fc78f },
+    { 0x00008060, 0x0000000f },
+    { 0x00008064, 0x00000000 },
+    { 0x000080c0, 0x2a82301a },
+    { 0x000080c4, 0x05dc01e0 },
+    { 0x000080c8, 0x1f402710 },
+    { 0x000080cc, 0x01f40000 },
+    { 0x000080d0, 0x00001e00 },
+    { 0x000080d4, 0x00000000 },
+    { 0x000080d8, 0x00400000 },
+    { 0x000080e0, 0xffffffff },
+    { 0x000080e4, 0x0000ffff },
+    { 0x000080e8, 0x003f3f3f },
+    { 0x000080ec, 0x00000000 },
+    { 0x000080f0, 0x00000000 },
+    { 0x000080f4, 0x00000000 },
+    { 0x000080f8, 0x00000000 },
+    { 0x000080fc, 0x00020000 },
+    { 0x00008100, 0x00020000 },
+    { 0x00008104, 0x00000001 },
+    { 0x00008108, 0x00000052 },
+    { 0x0000810c, 0x00000000 },
+    { 0x00008110, 0x00000168 },
+    { 0x00008118, 0x000100aa },
+    { 0x0000811c, 0x00003210 },
+    { 0x00008120, 0x08f04800 },
+    { 0x00008124, 0x00000000 },
+    { 0x00008128, 0x00000000 },
+    { 0x0000812c, 0x00000000 },
+    { 0x00008130, 0x00000000 },
+    { 0x00008134, 0x00000000 },
+    { 0x00008138, 0x00000000 },
+    { 0x0000813c, 0x00000000 },
+    { 0x00008144, 0x00000000 },
+    { 0x00008168, 0x00000000 },
+    { 0x0000816c, 0x00000000 },
+    { 0x00008170, 0x32143320 },
+    { 0x00008174, 0xfaa4fa50 },
+    { 0x00008178, 0x00000100 },
+    { 0x0000817c, 0x00000000 },
+    { 0x000081c4, 0x00000000 },
+    { 0x000081d0, 0x00003210 },
+    { 0x000081ec, 0x00000000 },
+    { 0x000081f0, 0x00000000 },
+    { 0x000081f4, 0x00000000 },
+    { 0x000081f8, 0x00000000 },
+    { 0x000081fc, 0x00000000 },
+    { 0x00008200, 0x00000000 },
+    { 0x00008204, 0x00000000 },
+    { 0x00008208, 0x00000000 },
+    { 0x0000820c, 0x00000000 },
+    { 0x00008210, 0x00000000 },
+    { 0x00008214, 0x00000000 },
+    { 0x00008218, 0x00000000 },
+    { 0x0000821c, 0x00000000 },
+    { 0x00008220, 0x00000000 },
+    { 0x00008224, 0x00000000 },
+    { 0x00008228, 0x00000000 },
+    { 0x0000822c, 0x00000000 },
+    { 0x00008230, 0x00000000 },
+    { 0x00008234, 0x00000000 },
+    { 0x00008238, 0x00000000 },
+    { 0x0000823c, 0x00000000 },
+    { 0x00008240, 0x00100000 },
+    { 0x00008244, 0x0010f400 },
+    { 0x00008248, 0x00000100 },
+    { 0x0000824c, 0x0001e800 },
+    { 0x00008250, 0x00000000 },
+    { 0x00008254, 0x00000000 },
+    { 0x00008258, 0x00000000 },
+    { 0x0000825c, 0x400000ff },
+    { 0x00008260, 0x00080922 },
+    { 0x00008270, 0x00000000 },
+    { 0x00008274, 0x40000000 },
+    { 0x00008278, 0x003e4180 },
+    { 0x0000827c, 0x00000000 },
+    { 0x00008284, 0x0000002c },
+    { 0x00008288, 0x0000002c },
+    { 0x0000828c, 0x00000000 },
+    { 0x00008294, 0x00000000 },
+    { 0x00008298, 0x00000000 },
+    { 0x00008300, 0x00000000 },
+    { 0x00008304, 0x00000000 },
+    { 0x00008308, 0x00000000 },
+    { 0x0000830c, 0x00000000 },
+    { 0x00008310, 0x00000000 },
+    { 0x00008314, 0x00000000 },
+    { 0x00008318, 0x00000000 },
+    { 0x00008328, 0x00000000 },
+    { 0x0000832c, 0x00000007 },
+    { 0x00008330, 0x00000302 },
+    { 0x00008334, 0x00000e00 },
+    { 0x00008338, 0x00000000 },
+    { 0x0000833c, 0x00000000 },
+    { 0x00008340, 0x000107ff },
+    { 0x00009808, 0x00000000 },
+    { 0x0000980c, 0xad848e19 },
+    { 0x00009810, 0x7d14e000 },
+    { 0x00009814, 0x9c0a9f6b },
+    { 0x0000981c, 0x00000000 },
+    { 0x0000982c, 0x0000a000 },
+    { 0x00009830, 0x00000000 },
+    { 0x0000983c, 0x00200400 },
+    { 0x00009840, 0x206a01ae },
+    { 0x0000984c, 0x1284233c },
+    { 0x00009854, 0x00000859 },
+    { 0x00009900, 0x00000000 },
+    { 0x00009904, 0x00000000 },
+    { 0x00009908, 0x00000000 },
+    { 0x0000990c, 0x00000000 },
+    { 0x0000991c, 0x10000fff },
+    { 0x00009920, 0x05100000 },
+    { 0x0000a920, 0x05100000 },
+    { 0x0000b920, 0x05100000 },
+    { 0x00009928, 0x00000001 },
+    { 0x0000992c, 0x00000004 },
+    { 0x00009934, 0x1e1f2022 },
+    { 0x00009938, 0x0a0b0c0d },
+    { 0x0000993c, 0x00000000 },
+    { 0x00009948, 0x9280b212 },
+    { 0x0000994c, 0x00020028 },
+    { 0x0000c95c, 0x004b6a8e },
+    { 0x0000c968, 0x000003ce },
+    { 0x00009970, 0x190fb515 },
+    { 0x00009974, 0x00000000 },
+    { 0x00009978, 0x00000001 },
+    { 0x0000997c, 0x00000000 },
+    { 0x00009980, 0x00000000 },
+    { 0x00009984, 0x00000000 },
+    { 0x00009988, 0x00000000 },
+    { 0x0000998c, 0x00000000 },
+    { 0x00009990, 0x00000000 },
+    { 0x00009994, 0x00000000 },
+    { 0x00009998, 0x00000000 },
+    { 0x0000999c, 0x00000000 },
+    { 0x000099a0, 0x00000000 },
+    { 0x000099a4, 0x00000001 },
+    { 0x000099a8, 0x201fff00 },
+    { 0x000099ac, 0x006f0000 },
+    { 0x000099b0, 0x03051000 },
+    { 0x000099dc, 0x00000000 },
+    { 0x000099e0, 0x00000200 },
+    { 0x000099e4, 0xaaaaaaaa },
+    { 0x000099e8, 0x3c466478 },
+    { 0x000099ec, 0x0cc80caa },
+    { 0x000099fc, 0x00001042 },
+    { 0x00009b00, 0x00000000 },
+    { 0x00009b04, 0x00000001 },
+    { 0x00009b08, 0x00000002 },
+    { 0x00009b0c, 0x00000003 },
+    { 0x00009b10, 0x00000004 },
+    { 0x00009b14, 0x00000005 },
+    { 0x00009b18, 0x00000008 },
+    { 0x00009b1c, 0x00000009 },
+    { 0x00009b20, 0x0000000a },
+    { 0x00009b24, 0x0000000b },
+    { 0x00009b28, 0x0000000c },
+    { 0x00009b2c, 0x0000000d },
+    { 0x00009b30, 0x00000010 },
+    { 0x00009b34, 0x00000011 },
+    { 0x00009b38, 0x00000012 },
+    { 0x00009b3c, 0x00000013 },
+    { 0x00009b40, 0x00000014 },
+    { 0x00009b44, 0x00000015 },
+    { 0x00009b48, 0x00000018 },
+    { 0x00009b4c, 0x00000019 },
+    { 0x00009b50, 0x0000001a },
+    { 0x00009b54, 0x0000001b },
+    { 0x00009b58, 0x0000001c },
+    { 0x00009b5c, 0x0000001d },
+    { 0x00009b60, 0x00000020 },
+    { 0x00009b64, 0x00000021 },
+    { 0x00009b68, 0x00000022 },
+    { 0x00009b6c, 0x00000023 },
+    { 0x00009b70, 0x00000024 },
+    { 0x00009b74, 0x00000025 },
+    { 0x00009b78, 0x00000028 },
+    { 0x00009b7c, 0x00000029 },
+    { 0x00009b80, 0x0000002a },
+    { 0x00009b84, 0x0000002b },
+    { 0x00009b88, 0x0000002c },
+    { 0x00009b8c, 0x0000002d },
+    { 0x00009b90, 0x00000030 },
+    { 0x00009b94, 0x00000031 },
+    { 0x00009b98, 0x00000032 },
+    { 0x00009b9c, 0x00000033 },
+    { 0x00009ba0, 0x00000034 },
+    { 0x00009ba4, 0x00000035 },
+    { 0x00009ba8, 0x00000035 },
+    { 0x00009bac, 0x00000035 },
+    { 0x00009bb0, 0x00000035 },
+    { 0x00009bb4, 0x00000035 },
+    { 0x00009bb8, 0x00000035 },
+    { 0x00009bbc, 0x00000035 },
+    { 0x00009bc0, 0x00000035 },
+    { 0x00009bc4, 0x00000035 },
+    { 0x00009bc8, 0x00000035 },
+    { 0x00009bcc, 0x00000035 },
+    { 0x00009bd0, 0x00000035 },
+    { 0x00009bd4, 0x00000035 },
+    { 0x00009bd8, 0x00000035 },
+    { 0x00009bdc, 0x00000035 },
+    { 0x00009be0, 0x00000035 },
+    { 0x00009be4, 0x00000035 },
+    { 0x00009be8, 0x00000035 },
+    { 0x00009bec, 0x00000035 },
+    { 0x00009bf0, 0x00000035 },
+    { 0x00009bf4, 0x00000035 },
+    { 0x00009bf8, 0x00000010 },
+    { 0x00009bfc, 0x0000001a },
+    { 0x0000a210, 0x40806333 },
+    { 0x0000a214, 0x00106c10 },
+    { 0x0000a218, 0x009c4060 },
+    { 0x0000a220, 0x018830c6 },
+    { 0x0000a224, 0x00000400 },
+    { 0x0000a228, 0x001a0bb5 },
+    { 0x0000a22c, 0x00000000 },
+    { 0x0000a234, 0x20202020 },
+    { 0x0000a238, 0x20202020 },
+    { 0x0000a23c, 0x13c889ae },
+    { 0x0000a240, 0x38490a20 },
+    { 0x0000a244, 0x00007bb6 },
+    { 0x0000a248, 0x0fff3ffc },
+    { 0x0000a24c, 0x00000001 },
+    { 0x0000a250, 0x0000a000 },
+    { 0x0000a254, 0x00000000 },
+    { 0x0000a258, 0x0cc75380 },
+    { 0x0000a25c, 0x0f0f0f01 },
+    { 0x0000a260, 0xdfa91f01 },
+    { 0x0000a268, 0x00000001 },
+    { 0x0000a26c, 0x0ebae9c6 },
+    { 0x0000b26c, 0x0ebae9c6 },
+    { 0x0000c26c, 0x0ebae9c6 },
+    { 0x0000d270, 0x00820820 },
+    { 0x0000a278, 0x1ce739ce },
+    { 0x0000a27c, 0x050701ce },
+    { 0x0000a338, 0x00000000 },
+    { 0x0000a33c, 0x00000000 },
+    { 0x0000a340, 0x00000000 },
+    { 0x0000a344, 0x00000000 },
+    { 0x0000a348, 0x3fffffff },
+    { 0x0000a34c, 0x3fffffff },
+    { 0x0000a350, 0x3fffffff },
+    { 0x0000a354, 0x0003ffff },
+    { 0x0000a358, 0x79a8aa33 },
+    { 0x0000d35c, 0x07ffffef },
+    { 0x0000d360, 0x0fffffe7 },
+    { 0x0000d364, 0x17ffffe5 },
+    { 0x0000d368, 0x1fffffe4 },
+    { 0x0000d36c, 0x37ffffe3 },
+    { 0x0000d370, 0x3fffffe3 },
+    { 0x0000d374, 0x57ffffe3 },
+    { 0x0000d378, 0x5fffffe2 },
+    { 0x0000d37c, 0x7fffffe2 },
+    { 0x0000d380, 0x7f3c7bba },
+    { 0x0000d384, 0xf3307ff0 },
+    { 0x0000a388, 0x0c000000 },
+    { 0x0000a38c, 0x20202020 },
+    { 0x0000a390, 0x20202020 },
+    { 0x0000a394, 0x1ce739ce },
+    { 0x0000a398, 0x000001ce },
+    { 0x0000a39c, 0x00000001 },
+    { 0x0000a3a0, 0x00000000 },
+    { 0x0000a3a4, 0x00000000 },
+    { 0x0000a3a8, 0x00000000 },
+    { 0x0000a3ac, 0x00000000 },
+    { 0x0000a3b0, 0x00000000 },
+    { 0x0000a3b4, 0x00000000 },
+    { 0x0000a3b8, 0x00000000 },
+    { 0x0000a3bc, 0x00000000 },
+    { 0x0000a3c0, 0x00000000 },
+    { 0x0000a3c4, 0x00000000 },
+    { 0x0000a3c8, 0x00000246 },
+    { 0x0000a3cc, 0x20202020 },
+    { 0x0000a3d0, 0x20202020 },
+    { 0x0000a3d4, 0x20202020 },
+    { 0x0000a3dc, 0x1ce739ce },
+    { 0x0000a3e0, 0x000001ce },
+};
+
+static const u32 ar5416Bank0_9100[][2] = {
+    { 0x000098b0, 0x1e5795e5 },
+    { 0x000098e0, 0x02008020 },
+};
+
+static const u32 ar5416BB_RfGain_9100[][3] = {
+    { 0x00009a00, 0x00000000, 0x00000000 },
+    { 0x00009a04, 0x00000040, 0x00000040 },
+    { 0x00009a08, 0x00000080, 0x00000080 },
+    { 0x00009a0c, 0x000001a1, 0x00000141 },
+    { 0x00009a10, 0x000001e1, 0x00000181 },
+    { 0x00009a14, 0x00000021, 0x000001c1 },
+    { 0x00009a18, 0x00000061, 0x00000001 },
+    { 0x00009a1c, 0x00000168, 0x00000041 },
+    { 0x00009a20, 0x000001a8, 0x000001a8 },
+    { 0x00009a24, 0x000001e8, 0x000001e8 },
+    { 0x00009a28, 0x00000028, 0x00000028 },
+    { 0x00009a2c, 0x00000068, 0x00000068 },
+    { 0x00009a30, 0x00000189, 0x000000a8 },
+    { 0x00009a34, 0x000001c9, 0x00000169 },
+    { 0x00009a38, 0x00000009, 0x000001a9 },
+    { 0x00009a3c, 0x00000049, 0x000001e9 },
+    { 0x00009a40, 0x00000089, 0x00000029 },
+    { 0x00009a44, 0x00000170, 0x00000069 },
+    { 0x00009a48, 0x000001b0, 0x00000190 },
+    { 0x00009a4c, 0x000001f0, 0x000001d0 },
+    { 0x00009a50, 0x00000030, 0x00000010 },
+    { 0x00009a54, 0x00000070, 0x00000050 },
+    { 0x00009a58, 0x00000191, 0x00000090 },
+    { 0x00009a5c, 0x000001d1, 0x00000151 },
+    { 0x00009a60, 0x00000011, 0x00000191 },
+    { 0x00009a64, 0x00000051, 0x000001d1 },
+    { 0x00009a68, 0x00000091, 0x00000011 },
+    { 0x00009a6c, 0x000001b8, 0x00000051 },
+    { 0x00009a70, 0x000001f8, 0x00000198 },
+    { 0x00009a74, 0x00000038, 0x000001d8 },
+    { 0x00009a78, 0x00000078, 0x00000018 },
+    { 0x00009a7c, 0x00000199, 0x00000058 },
+    { 0x00009a80, 0x000001d9, 0x00000098 },
+    { 0x00009a84, 0x00000019, 0x00000159 },
+    { 0x00009a88, 0x00000059, 0x00000199 },
+    { 0x00009a8c, 0x00000099, 0x000001d9 },
+    { 0x00009a90, 0x000000d9, 0x00000019 },
+    { 0x00009a94, 0x000000f9, 0x00000059 },
+    { 0x00009a98, 0x000000f9, 0x00000099 },
+    { 0x00009a9c, 0x000000f9, 0x000000d9 },
+    { 0x00009aa0, 0x000000f9, 0x000000f9 },
+    { 0x00009aa4, 0x000000f9, 0x000000f9 },
+    { 0x00009aa8, 0x000000f9, 0x000000f9 },
+    { 0x00009aac, 0x000000f9, 0x000000f9 },
+    { 0x00009ab0, 0x000000f9, 0x000000f9 },
+    { 0x00009ab4, 0x000000f9, 0x000000f9 },
+    { 0x00009ab8, 0x000000f9, 0x000000f9 },
+    { 0x00009abc, 0x000000f9, 0x000000f9 },
+    { 0x00009ac0, 0x000000f9, 0x000000f9 },
+    { 0x00009ac4, 0x000000f9, 0x000000f9 },
+    { 0x00009ac8, 0x000000f9, 0x000000f9 },
+    { 0x00009acc, 0x000000f9, 0x000000f9 },
+    { 0x00009ad0, 0x000000f9, 0x000000f9 },
+    { 0x00009ad4, 0x000000f9, 0x000000f9 },
+    { 0x00009ad8, 0x000000f9, 0x000000f9 },
+    { 0x00009adc, 0x000000f9, 0x000000f9 },
+    { 0x00009ae0, 0x000000f9, 0x000000f9 },
+    { 0x00009ae4, 0x000000f9, 0x000000f9 },
+    { 0x00009ae8, 0x000000f9, 0x000000f9 },
+    { 0x00009aec, 0x000000f9, 0x000000f9 },
+    { 0x00009af0, 0x000000f9, 0x000000f9 },
+    { 0x00009af4, 0x000000f9, 0x000000f9 },
+    { 0x00009af8, 0x000000f9, 0x000000f9 },
+    { 0x00009afc, 0x000000f9, 0x000000f9 },
+};
+
+static const u32 ar5416Bank1_9100[][2] = {
+    { 0x000098b0, 0x02108421},
+    { 0x000098ec, 0x00000008},
+};
+
+static const u32 ar5416Bank2_9100[][2] = {
+    { 0x000098b0, 0x0e73ff17},
+    { 0x000098e0, 0x00000420},
+};
+
+static const u32 ar5416Bank3_9100[][3] = {
+    { 0x000098f0, 0x01400018, 0x01c00018 },
+};
+
+static const u32 ar5416Bank6_9100[][3] = {
+
+    { 0x0000989c, 0x00000000, 0x00000000 },
+    { 0x0000989c, 0x00000000, 0x00000000 },
+    { 0x0000989c, 0x00000000, 0x00000000 },
+    { 0x0000989c, 0x00e00000, 0x00e00000 },
+    { 0x0000989c, 0x005e0000, 0x005e0000 },
+    { 0x0000989c, 0x00120000, 0x00120000 },
+    { 0x0000989c, 0x00620000, 0x00620000 },
+    { 0x0000989c, 0x00020000, 0x00020000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x005f0000, 0x005f0000 },
+    { 0x0000989c, 0x00870000, 0x00870000 },
+    { 0x0000989c, 0x00f90000, 0x00f90000 },
+    { 0x0000989c, 0x007b0000, 0x007b0000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x00f50000, 0x00f50000 },
+    { 0x0000989c, 0x00dc0000, 0x00dc0000 },
+    { 0x0000989c, 0x00110000, 0x00110000 },
+    { 0x0000989c, 0x006100a8, 0x006100a8 },
+    { 0x0000989c, 0x004210a2, 0x004210a2 },
+    { 0x0000989c, 0x0014000f, 0x0014000f },
+    { 0x0000989c, 0x00c40002, 0x00c40002 },
+    { 0x0000989c, 0x003000f2, 0x003000f2 },
+    { 0x0000989c, 0x00440016, 0x00440016 },
+    { 0x0000989c, 0x00410040, 0x00410040 },
+    { 0x0000989c, 0x000180d6, 0x000180d6 },
+    { 0x0000989c, 0x0000c0aa, 0x0000c0aa },
+    { 0x0000989c, 0x000000b1, 0x000000b1 },
+    { 0x0000989c, 0x00002000, 0x00002000 },
+    { 0x0000989c, 0x000000d4, 0x000000d4 },
+    { 0x000098d0, 0x0000000f, 0x0010000f },
+};
+
+
+static const u32 ar5416Bank6TPC_9100[][3] = {
+
+    { 0x0000989c, 0x00000000, 0x00000000 },
+    { 0x0000989c, 0x00000000, 0x00000000 },
+    { 0x0000989c, 0x00000000, 0x00000000 },
+    { 0x0000989c, 0x00e00000, 0x00e00000 },
+    { 0x0000989c, 0x005e0000, 0x005e0000 },
+    { 0x0000989c, 0x00120000, 0x00120000 },
+    { 0x0000989c, 0x00620000, 0x00620000 },
+    { 0x0000989c, 0x00020000, 0x00020000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x40ff0000, 0x40ff0000 },
+    { 0x0000989c, 0x005f0000, 0x005f0000 },
+    { 0x0000989c, 0x00870000, 0x00870000 },
+    { 0x0000989c, 0x00f90000, 0x00f90000 },
+    { 0x0000989c, 0x007b0000, 0x007b0000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x00f50000, 0x00f50000 },
+    { 0x0000989c, 0x00dc0000, 0x00dc0000 },
+    { 0x0000989c, 0x00110000, 0x00110000 },
+    { 0x0000989c, 0x006100a8, 0x006100a8 },
+    { 0x0000989c, 0x00423022, 0x00423022 },
+    { 0x0000989c, 0x2014008f, 0x2014008f },
+    { 0x0000989c, 0x00c40002, 0x00c40002 },
+    { 0x0000989c, 0x003000f2, 0x003000f2 },
+    { 0x0000989c, 0x00440016, 0x00440016 },
+    { 0x0000989c, 0x00410040, 0x00410040 },
+    { 0x0000989c, 0x0001805e, 0x0001805e },
+    { 0x0000989c, 0x0000c0ab, 0x0000c0ab },
+    { 0x0000989c, 0x000000e1, 0x000000e1 },
+    { 0x0000989c, 0x00007080, 0x00007080 },
+    { 0x0000989c, 0x000000d4, 0x000000d4 },
+    { 0x000098d0, 0x0000000f, 0x0010000f },
+};
+
+static const u32 ar5416Bank7_9100[][2] = {
+    { 0x0000989c, 0x00000500 },
+    { 0x0000989c, 0x00000800 },
+    { 0x000098cc, 0x0000000e },
+};
+
+static const u32 ar5416Addac_9100[][2] = {
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000010 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x000000c0 },
+    {0x0000989c, 0x00000015 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x0000989c, 0x00000000 },
+    {0x000098cc, 0x00000000 },
+};
+
+static const u32 ar5416Modes_9160[][6] = {
+    { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
+    { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
+    { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
+    { 0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000, 0x00014008 },
+    { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 },
+    { 0x0000801c, 0x128d93a7, 0x128d93cf, 0x12e013d7, 0x12e013ab, 0x098813cf },
+    { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 },
+    { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 },
+    { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
+    { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 },
+    { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
+    { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 },
+    { 0x00009844, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0, 0x037216a0 },
+    { 0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
+    { 0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
+    { 0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
+    { 0x00009850, 0x6c48b4e2, 0x6c48b4e2, 0x6c48b0e2, 0x6c48b0e2, 0x6c48b0e2 },
+    { 0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e },
+    { 0x0000985c, 0x31395d5e, 0x31395d5e, 0x31395d5e, 0x31395d5e, 0x31395d5e },
+    { 0x00009860, 0x00048d18, 0x00048d18, 0x00048d20, 0x00048d20, 0x00048d18 },
+    { 0x0000c864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 },
+    { 0x00009868, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0 },
+    { 0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 },
+    { 0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0 },
+    { 0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016 },
+    { 0x00009924, 0xd00a8a07, 0xd00a8a07, 0xd00a8a0d, 0xd00a8a0d, 0xd00a8a0d },
+    { 0x00009944, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020 },
+    { 0x00009960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40 },
+    { 0x0000a960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40 },
+    { 0x0000b960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40 },
+    { 0x00009964, 0x00001120, 0x00001120, 0x00001120, 0x00001120, 0x00001120 },
+    { 0x0000c968, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce, 0x000003ce },
+    { 0x0000c9bc, 0x001a0600, 0x001a0600, 0x001a0c00, 0x001a0c00, 0x001a0c00 },
+    { 0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, 0x038919be },
+    { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 },
+    { 0x000099c8, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329 },
+    { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 },
+    { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 },
+    { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x0000a204, 0x00000880, 0x00000880, 0x00000880, 0x00000880, 0x00000880 },
+    { 0x0000a208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, 0xd03e4788 },
+    { 0x0000a20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 },
+    { 0x0000b20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 },
+    { 0x0000c20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 },
+    { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a },
+    { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
+    { 0x0000a274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, 0x0a1a7caa },
+    { 0x0000a300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000 },
+    { 0x0000a304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, 0x2e032402 },
+    { 0x0000a308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, 0x4a0a3c06 },
+    { 0x0000a30c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, 0x621a540b },
+    { 0x0000a310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, 0x764f6c1b },
+    { 0x0000a314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, 0x845b7a5a },
+    { 0x0000a318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, 0x950f8ccf },
+    { 0x0000a31c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, 0xa5cf9b4f },
+    { 0x0000a320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, 0xbddfaf1f },
+    { 0x0000a324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, 0xd1ffc93f },
+    { 0x0000a328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x0000a32c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x0000a330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+};
+
+static const u32 ar5416Common_9160[][2] = {
+    { 0x0000000c, 0x00000000 },
+    { 0x00000030, 0x00020015 },
+    { 0x00000034, 0x00000005 },
+    { 0x00000040, 0x00000000 },
+    { 0x00000044, 0x00000008 },
+    { 0x00000048, 0x00000008 },
+    { 0x0000004c, 0x00000010 },
+    { 0x00000050, 0x00000000 },
+    { 0x00000054, 0x0000001f },
+    { 0x00000800, 0x00000000 },
+    { 0x00000804, 0x00000000 },
+    { 0x00000808, 0x00000000 },
+    { 0x0000080c, 0x00000000 },
+    { 0x00000810, 0x00000000 },
+    { 0x00000814, 0x00000000 },
+    { 0x00000818, 0x00000000 },
+    { 0x0000081c, 0x00000000 },
+    { 0x00000820, 0x00000000 },
+    { 0x00000824, 0x00000000 },
+    { 0x00001040, 0x002ffc0f },
+    { 0x00001044, 0x002ffc0f },
+    { 0x00001048, 0x002ffc0f },
+    { 0x0000104c, 0x002ffc0f },
+    { 0x00001050, 0x002ffc0f },
+    { 0x00001054, 0x002ffc0f },
+    { 0x00001058, 0x002ffc0f },
+    { 0x0000105c, 0x002ffc0f },
+    { 0x00001060, 0x002ffc0f },
+    { 0x00001064, 0x002ffc0f },
+    { 0x00001230, 0x00000000 },
+    { 0x00001270, 0x00000000 },
+    { 0x00001038, 0x00000000 },
+    { 0x00001078, 0x00000000 },
+    { 0x000010b8, 0x00000000 },
+    { 0x000010f8, 0x00000000 },
+    { 0x00001138, 0x00000000 },
+    { 0x00001178, 0x00000000 },
+    { 0x000011b8, 0x00000000 },
+    { 0x000011f8, 0x00000000 },
+    { 0x00001238, 0x00000000 },
+    { 0x00001278, 0x00000000 },
+    { 0x000012b8, 0x00000000 },
+    { 0x000012f8, 0x00000000 },
+    { 0x00001338, 0x00000000 },
+    { 0x00001378, 0x00000000 },
+    { 0x000013b8, 0x00000000 },
+    { 0x000013f8, 0x00000000 },
+    { 0x00001438, 0x00000000 },
+    { 0x00001478, 0x00000000 },
+    { 0x000014b8, 0x00000000 },
+    { 0x000014f8, 0x00000000 },
+    { 0x00001538, 0x00000000 },
+    { 0x00001578, 0x00000000 },
+    { 0x000015b8, 0x00000000 },
+    { 0x000015f8, 0x00000000 },
+    { 0x00001638, 0x00000000 },
+    { 0x00001678, 0x00000000 },
+    { 0x000016b8, 0x00000000 },
+    { 0x000016f8, 0x00000000 },
+    { 0x00001738, 0x00000000 },
+    { 0x00001778, 0x00000000 },
+    { 0x000017b8, 0x00000000 },
+    { 0x000017f8, 0x00000000 },
+    { 0x0000103c, 0x00000000 },
+    { 0x0000107c, 0x00000000 },
+    { 0x000010bc, 0x00000000 },
+    { 0x000010fc, 0x00000000 },
+    { 0x0000113c, 0x00000000 },
+    { 0x0000117c, 0x00000000 },
+    { 0x000011bc, 0x00000000 },
+    { 0x000011fc, 0x00000000 },
+    { 0x0000123c, 0x00000000 },
+    { 0x0000127c, 0x00000000 },
+    { 0x000012bc, 0x00000000 },
+    { 0x000012fc, 0x00000000 },
+    { 0x0000133c, 0x00000000 },
+    { 0x0000137c, 0x00000000 },
+    { 0x000013bc, 0x00000000 },
+    { 0x000013fc, 0x00000000 },
+    { 0x0000143c, 0x00000000 },
+    { 0x0000147c, 0x00000000 },
+    { 0x00004030, 0x00000002 },
+    { 0x0000403c, 0x00000002 },
+    { 0x00007010, 0x00000020 },
+    { 0x00007038, 0x000004c2 },
+    { 0x00008004, 0x00000000 },
+    { 0x00008008, 0x00000000 },
+    { 0x0000800c, 0x00000000 },
+    { 0x00008018, 0x00000700 },
+    { 0x00008020, 0x00000000 },
+    { 0x00008038, 0x00000000 },
+    { 0x0000803c, 0x00000000 },
+    { 0x00008048, 0x40000000 },
+    { 0x00008054, 0x00000000 },
+    { 0x00008058, 0x00000000 },
+    { 0x0000805c, 0x000fc78f },
+    { 0x00008060, 0x0000000f },
+    { 0x00008064, 0x00000000 },
+    { 0x000080c0, 0x2a82301a },
+    { 0x000080c4, 0x05dc01e0 },
+    { 0x000080c8, 0x1f402710 },
+    { 0x000080cc, 0x01f40000 },
+    { 0x000080d0, 0x00001e00 },
+    { 0x000080d4, 0x00000000 },
+    { 0x000080d8, 0x00400000 },
+    { 0x000080e0, 0xffffffff },
+    { 0x000080e4, 0x0000ffff },
+    { 0x000080e8, 0x003f3f3f },
+    { 0x000080ec, 0x00000000 },
+    { 0x000080f0, 0x00000000 },
+    { 0x000080f4, 0x00000000 },
+    { 0x000080f8, 0x00000000 },
+    { 0x000080fc, 0x00020000 },
+    { 0x00008100, 0x00020000 },
+    { 0x00008104, 0x00000001 },
+    { 0x00008108, 0x00000052 },
+    { 0x0000810c, 0x00000000 },
+    { 0x00008110, 0x00000168 },
+    { 0x00008118, 0x000100aa },
+    { 0x0000811c, 0x00003210 },
+    { 0x00008120, 0x08f04800 },
+    { 0x00008124, 0x00000000 },
+    { 0x00008128, 0x00000000 },
+    { 0x0000812c, 0x00000000 },
+    { 0x00008130, 0x00000000 },
+    { 0x00008134, 0x00000000 },
+    { 0x00008138, 0x00000000 },
+    { 0x0000813c, 0x00000000 },
+    { 0x00008144, 0xffffffff },
+    { 0x00008168, 0x00000000 },
+    { 0x0000816c, 0x00000000 },
+    { 0x00008170, 0x32143320 },
+    { 0x00008174, 0xfaa4fa50 },
+    { 0x00008178, 0x00000100 },
+    { 0x0000817c, 0x00000000 },
+    { 0x000081c4, 0x00000000 },
+    { 0x000081d0, 0x00003210 },
+    { 0x000081ec, 0x00000000 },
+    { 0x000081f0, 0x00000000 },
+    { 0x000081f4, 0x00000000 },
+    { 0x000081f8, 0x00000000 },
+    { 0x000081fc, 0x00000000 },
+    { 0x00008200, 0x00000000 },
+    { 0x00008204, 0x00000000 },
+    { 0x00008208, 0x00000000 },
+    { 0x0000820c, 0x00000000 },
+    { 0x00008210, 0x00000000 },
+    { 0x00008214, 0x00000000 },
+    { 0x00008218, 0x00000000 },
+    { 0x0000821c, 0x00000000 },
+    { 0x00008220, 0x00000000 },
+    { 0x00008224, 0x00000000 },
+    { 0x00008228, 0x00000000 },
+    { 0x0000822c, 0x00000000 },
+    { 0x00008230, 0x00000000 },
+    { 0x00008234, 0x00000000 },
+    { 0x00008238, 0x00000000 },
+    { 0x0000823c, 0x00000000 },
+    { 0x00008240, 0x00100000 },
+    { 0x00008244, 0x0010f400 },
+    { 0x00008248, 0x00000100 },
+    { 0x0000824c, 0x0001e800 },
+    { 0x00008250, 0x00000000 },
+    { 0x00008254, 0x00000000 },
+    { 0x00008258, 0x00000000 },
+    { 0x0000825c, 0x400000ff },
+    { 0x00008260, 0x00080922 },
+    { 0x00008270, 0x00000000 },
+    { 0x00008274, 0x40000000 },
+    { 0x00008278, 0x003e4180 },
+    { 0x0000827c, 0x00000000 },
+    { 0x00008284, 0x0000002c },
+    { 0x00008288, 0x0000002c },
+    { 0x0000828c, 0x00000000 },
+    { 0x00008294, 0x00000000 },
+    { 0x00008298, 0x00000000 },
+    { 0x00008300, 0x00000000 },
+    { 0x00008304, 0x00000000 },
+    { 0x00008308, 0x00000000 },
+    { 0x0000830c, 0x00000000 },
+    { 0x00008310, 0x00000000 },
+    { 0x00008314, 0x00000000 },
+    { 0x00008318, 0x00000000 },
+    { 0x00008328, 0x00000000 },
+    { 0x0000832c, 0x00000007 },
+    { 0x00008330, 0x00000302 },
+    { 0x00008334, 0x00000e00 },
+    { 0x00008338, 0x00ff0000 },
+    { 0x0000833c, 0x00000000 },
+    { 0x00008340, 0x000107ff },
+    { 0x00009808, 0x00000000 },
+    { 0x0000980c, 0xad848e19 },
+    { 0x00009810, 0x7d14e000 },
+    { 0x00009814, 0x9c0a9f6b },
+    { 0x0000981c, 0x00000000 },
+    { 0x0000982c, 0x0000a000 },
+    { 0x00009830, 0x00000000 },
+    { 0x0000983c, 0x00200400 },
+    { 0x00009840, 0x206a01ae },
+    { 0x0000984c, 0x1284233c },
+    { 0x00009854, 0x00000859 },
+    { 0x00009900, 0x00000000 },
+    { 0x00009904, 0x00000000 },
+    { 0x00009908, 0x00000000 },
+    { 0x0000990c, 0x00000000 },
+    { 0x0000991c, 0x10000fff },
+    { 0x00009920, 0x05100000 },
+    { 0x0000a920, 0x05100000 },
+    { 0x0000b920, 0x05100000 },
+    { 0x00009928, 0x00000001 },
+    { 0x0000992c, 0x00000004 },
+    { 0x00009934, 0x1e1f2022 },
+    { 0x00009938, 0x0a0b0c0d },
+    { 0x0000993c, 0x00000000 },
+    { 0x00009948, 0x9280b212 },
+    { 0x0000994c, 0x00020028 },
+    { 0x00009954, 0x5f3ca3de },
+    { 0x00009958, 0x2108ecff },
+    { 0x00009940, 0x00750604 },
+    { 0x0000c95c, 0x004b6a8e },
+    { 0x00009970, 0x190fb515 },
+    { 0x00009974, 0x00000000 },
+    { 0x00009978, 0x00000001 },
+    { 0x0000997c, 0x00000000 },
+    { 0x00009980, 0x00000000 },
+    { 0x00009984, 0x00000000 },
+    { 0x00009988, 0x00000000 },
+    { 0x0000998c, 0x00000000 },
+    { 0x00009990, 0x00000000 },
+    { 0x00009994, 0x00000000 },
+    { 0x00009998, 0x00000000 },
+    { 0x0000999c, 0x00000000 },
+    { 0x000099a0, 0x00000000 },
+    { 0x000099a4, 0x00000001 },
+    { 0x000099a8, 0x201fff00 },
+    { 0x000099ac, 0x006f0000 },
+    { 0x000099b0, 0x03051000 },
+    { 0x000099dc, 0x00000000 },
+    { 0x000099e0, 0x00000200 },
+    { 0x000099e4, 0xaaaaaaaa },
+    { 0x000099e8, 0x3c466478 },
+    { 0x000099ec, 0x0cc80caa },
+    { 0x000099fc, 0x00001042 },
+    { 0x00009b00, 0x00000000 },
+    { 0x00009b04, 0x00000001 },
+    { 0x00009b08, 0x00000002 },
+    { 0x00009b0c, 0x00000003 },
+    { 0x00009b10, 0x00000004 },
+    { 0x00009b14, 0x00000005 },
+    { 0x00009b18, 0x00000008 },
+    { 0x00009b1c, 0x00000009 },
+    { 0x00009b20, 0x0000000a },
+    { 0x00009b24, 0x0000000b },
+    { 0x00009b28, 0x0000000c },
+    { 0x00009b2c, 0x0000000d },
+    { 0x00009b30, 0x00000010 },
+    { 0x00009b34, 0x00000011 },
+    { 0x00009b38, 0x00000012 },
+    { 0x00009b3c, 0x00000013 },
+    { 0x00009b40, 0x00000014 },
+    { 0x00009b44, 0x00000015 },
+    { 0x00009b48, 0x00000018 },
+    { 0x00009b4c, 0x00000019 },
+    { 0x00009b50, 0x0000001a },
+    { 0x00009b54, 0x0000001b },
+    { 0x00009b58, 0x0000001c },
+    { 0x00009b5c, 0x0000001d },
+    { 0x00009b60, 0x00000020 },
+    { 0x00009b64, 0x00000021 },
+    { 0x00009b68, 0x00000022 },
+    { 0x00009b6c, 0x00000023 },
+    { 0x00009b70, 0x00000024 },
+    { 0x00009b74, 0x00000025 },
+    { 0x00009b78, 0x00000028 },
+    { 0x00009b7c, 0x00000029 },
+    { 0x00009b80, 0x0000002a },
+    { 0x00009b84, 0x0000002b },
+    { 0x00009b88, 0x0000002c },
+    { 0x00009b8c, 0x0000002d },
+    { 0x00009b90, 0x00000030 },
+    { 0x00009b94, 0x00000031 },
+    { 0x00009b98, 0x00000032 },
+    { 0x00009b9c, 0x00000033 },
+    { 0x00009ba0, 0x00000034 },
+    { 0x00009ba4, 0x00000035 },
+    { 0x00009ba8, 0x00000035 },
+    { 0x00009bac, 0x00000035 },
+    { 0x00009bb0, 0x00000035 },
+    { 0x00009bb4, 0x00000035 },
+    { 0x00009bb8, 0x00000035 },
+    { 0x00009bbc, 0x00000035 },
+    { 0x00009bc0, 0x00000035 },
+    { 0x00009bc4, 0x00000035 },
+    { 0x00009bc8, 0x00000035 },
+    { 0x00009bcc, 0x00000035 },
+    { 0x00009bd0, 0x00000035 },
+    { 0x00009bd4, 0x00000035 },
+    { 0x00009bd8, 0x00000035 },
+    { 0x00009bdc, 0x00000035 },
+    { 0x00009be0, 0x00000035 },
+    { 0x00009be4, 0x00000035 },
+    { 0x00009be8, 0x00000035 },
+    { 0x00009bec, 0x00000035 },
+    { 0x00009bf0, 0x00000035 },
+    { 0x00009bf4, 0x00000035 },
+    { 0x00009bf8, 0x00000010 },
+    { 0x00009bfc, 0x0000001a },
+    { 0x0000a210, 0x40806333 },
+    { 0x0000a214, 0x00106c10 },
+    { 0x0000a218, 0x009c4060 },
+    { 0x0000a220, 0x018830c6 },
+    { 0x0000a224, 0x00000400 },
+    { 0x0000a228, 0x001a0bb5 },
+    { 0x0000a22c, 0x00000000 },
+    { 0x0000a234, 0x20202020 },
+    { 0x0000a238, 0x20202020 },
+    { 0x0000a23c, 0x13c889af },
+    { 0x0000a240, 0x38490a20 },
+    { 0x0000a244, 0x00007bb6 },
+    { 0x0000a248, 0x0fff3ffc },
+    { 0x0000a24c, 0x00000001 },
+    { 0x0000a250, 0x0000e000 },
+    { 0x0000a254, 0x00000000 },
+    { 0x0000a258, 0x0cc75380 },
+    { 0x0000a25c, 0x0f0f0f01 },
+    { 0x0000a260, 0xdfa91f01 },
+    { 0x0000a268, 0x00000001 },
+    { 0x0000a26c, 0x0ebae9c6 },
+    { 0x0000b26c, 0x0ebae9c6 },
+    { 0x0000c26c, 0x0ebae9c6 },
+    { 0x0000d270, 0x00820820 },
+    { 0x0000a278, 0x1ce739ce },
+    { 0x0000a27c, 0x050701ce },
+    { 0x0000a338, 0x00000000 },
+    { 0x0000a33c, 0x00000000 },
+    { 0x0000a340, 0x00000000 },
+    { 0x0000a344, 0x00000000 },
+    { 0x0000a348, 0x3fffffff },
+    { 0x0000a34c, 0x3fffffff },
+    { 0x0000a350, 0x3fffffff },
+    { 0x0000a354, 0x0003ffff },
+    { 0x0000a358, 0x79bfaa03 },
+    { 0x0000d35c, 0x07ffffef },
+    { 0x0000d360, 0x0fffffe7 },
+    { 0x0000d364, 0x17ffffe5 },
+    { 0x0000d368, 0x1fffffe4 },
+    { 0x0000d36c, 0x37ffffe3 },
+    { 0x0000d370, 0x3fffffe3 },
+    { 0x0000d374, 0x57ffffe3 },
+    { 0x0000d378, 0x5fffffe2 },
+    { 0x0000d37c, 0x7fffffe2 },
+    { 0x0000d380, 0x7f3c7bba },
+    { 0x0000d384, 0xf3307ff0 },
+    { 0x0000a388, 0x0c000000 },
+    { 0x0000a38c, 0x20202020 },
+    { 0x0000a390, 0x20202020 },
+    { 0x0000a394, 0x1ce739ce },
+    { 0x0000a398, 0x000001ce },
+    { 0x0000a39c, 0x00000001 },
+    { 0x0000a3a0, 0x00000000 },
+    { 0x0000a3a4, 0x00000000 },
+    { 0x0000a3a8, 0x00000000 },
+    { 0x0000a3ac, 0x00000000 },
+    { 0x0000a3b0, 0x00000000 },
+    { 0x0000a3b4, 0x00000000 },
+    { 0x0000a3b8, 0x00000000 },
+    { 0x0000a3bc, 0x00000000 },
+    { 0x0000a3c0, 0x00000000 },
+    { 0x0000a3c4, 0x00000000 },
+    { 0x0000a3c8, 0x00000246 },
+    { 0x0000a3cc, 0x20202020 },
+    { 0x0000a3d0, 0x20202020 },
+    { 0x0000a3d4, 0x20202020 },
+    { 0x0000a3dc, 0x1ce739ce },
+    { 0x0000a3e0, 0x000001ce },
+};
+
+static const u32 ar5416Bank0_9160[][2] = {
+    { 0x000098b0, 0x1e5795e5 },
+    { 0x000098e0, 0x02008020 },
+};
+
+static const u32 ar5416BB_RfGain_9160[][3] = {
+    { 0x00009a00, 0x00000000, 0x00000000 },
+    { 0x00009a04, 0x00000040, 0x00000040 },
+    { 0x00009a08, 0x00000080, 0x00000080 },
+    { 0x00009a0c, 0x000001a1, 0x00000141 },
+    { 0x00009a10, 0x000001e1, 0x00000181 },
+    { 0x00009a14, 0x00000021, 0x000001c1 },
+    { 0x00009a18, 0x00000061, 0x00000001 },
+    { 0x00009a1c, 0x00000168, 0x00000041 },
+    { 0x00009a20, 0x000001a8, 0x000001a8 },
+    { 0x00009a24, 0x000001e8, 0x000001e8 },
+    { 0x00009a28, 0x00000028, 0x00000028 },
+    { 0x00009a2c, 0x00000068, 0x00000068 },
+    { 0x00009a30, 0x00000189, 0x000000a8 },
+    { 0x00009a34, 0x000001c9, 0x00000169 },
+    { 0x00009a38, 0x00000009, 0x000001a9 },
+    { 0x00009a3c, 0x00000049, 0x000001e9 },
+    { 0x00009a40, 0x00000089, 0x00000029 },
+    { 0x00009a44, 0x00000170, 0x00000069 },
+    { 0x00009a48, 0x000001b0, 0x00000190 },
+    { 0x00009a4c, 0x000001f0, 0x000001d0 },
+    { 0x00009a50, 0x00000030, 0x00000010 },
+    { 0x00009a54, 0x00000070, 0x00000050 },
+    { 0x00009a58, 0x00000191, 0x00000090 },
+    { 0x00009a5c, 0x000001d1, 0x00000151 },
+    { 0x00009a60, 0x00000011, 0x00000191 },
+    { 0x00009a64, 0x00000051, 0x000001d1 },
+    { 0x00009a68, 0x00000091, 0x00000011 },
+    { 0x00009a6c, 0x000001b8, 0x00000051 },
+    { 0x00009a70, 0x000001f8, 0x00000198 },
+    { 0x00009a74, 0x00000038, 0x000001d8 },
+    { 0x00009a78, 0x00000078, 0x00000018 },
+    { 0x00009a7c, 0x00000199, 0x00000058 },
+    { 0x00009a80, 0x000001d9, 0x00000098 },
+    { 0x00009a84, 0x00000019, 0x00000159 },
+    { 0x00009a88, 0x00000059, 0x00000199 },
+    { 0x00009a8c, 0x00000099, 0x000001d9 },
+    { 0x00009a90, 0x000000d9, 0x00000019 },
+    { 0x00009a94, 0x000000f9, 0x00000059 },
+    { 0x00009a98, 0x000000f9, 0x00000099 },
+    { 0x00009a9c, 0x000000f9, 0x000000d9 },
+    { 0x00009aa0, 0x000000f9, 0x000000f9 },
+    { 0x00009aa4, 0x000000f9, 0x000000f9 },
+    { 0x00009aa8, 0x000000f9, 0x000000f9 },
+    { 0x00009aac, 0x000000f9, 0x000000f9 },
+    { 0x00009ab0, 0x000000f9, 0x000000f9 },
+    { 0x00009ab4, 0x000000f9, 0x000000f9 },
+    { 0x00009ab8, 0x000000f9, 0x000000f9 },
+    { 0x00009abc, 0x000000f9, 0x000000f9 },
+    { 0x00009ac0, 0x000000f9, 0x000000f9 },
+    { 0x00009ac4, 0x000000f9, 0x000000f9 },
+    { 0x00009ac8, 0x000000f9, 0x000000f9 },
+    { 0x00009acc, 0x000000f9, 0x000000f9 },
+    { 0x00009ad0, 0x000000f9, 0x000000f9 },
+    { 0x00009ad4, 0x000000f9, 0x000000f9 },
+    { 0x00009ad8, 0x000000f9, 0x000000f9 },
+    { 0x00009adc, 0x000000f9, 0x000000f9 },
+    { 0x00009ae0, 0x000000f9, 0x000000f9 },
+    { 0x00009ae4, 0x000000f9, 0x000000f9 },
+    { 0x00009ae8, 0x000000f9, 0x000000f9 },
+    { 0x00009aec, 0x000000f9, 0x000000f9 },
+    { 0x00009af0, 0x000000f9, 0x000000f9 },
+    { 0x00009af4, 0x000000f9, 0x000000f9 },
+    { 0x00009af8, 0x000000f9, 0x000000f9 },
+    { 0x00009afc, 0x000000f9, 0x000000f9 },
+};
+
+static const u32 ar5416Bank1_9160[][2] = {
+    { 0x000098b0, 0x02108421 },
+    { 0x000098ec, 0x00000008 },
+};
+
+static const u32 ar5416Bank2_9160[][2] = {
+    { 0x000098b0, 0x0e73ff17 },
+    { 0x000098e0, 0x00000420 },
+};
+
+static const u32 ar5416Bank3_9160[][3] = {
+    { 0x000098f0, 0x01400018, 0x01c00018 },
+};
+
+static const u32 ar5416Bank6_9160[][3] = {
+    { 0x0000989c, 0x00000000, 0x00000000 },
+    { 0x0000989c, 0x00000000, 0x00000000 },
+    { 0x0000989c, 0x00000000, 0x00000000 },
+    { 0x0000989c, 0x00e00000, 0x00e00000 },
+    { 0x0000989c, 0x005e0000, 0x005e0000 },
+    { 0x0000989c, 0x00120000, 0x00120000 },
+    { 0x0000989c, 0x00620000, 0x00620000 },
+    { 0x0000989c, 0x00020000, 0x00020000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x40ff0000, 0x40ff0000 },
+    { 0x0000989c, 0x005f0000, 0x005f0000 },
+    { 0x0000989c, 0x00870000, 0x00870000 },
+    { 0x0000989c, 0x00f90000, 0x00f90000 },
+    { 0x0000989c, 0x007b0000, 0x007b0000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x00f50000, 0x00f50000 },
+    { 0x0000989c, 0x00dc0000, 0x00dc0000 },
+    { 0x0000989c, 0x00110000, 0x00110000 },
+    { 0x0000989c, 0x006100a8, 0x006100a8 },
+    { 0x0000989c, 0x004210a2, 0x004210a2 },
+    { 0x0000989c, 0x0014008f, 0x0014008f },
+    { 0x0000989c, 0x00c40003, 0x00c40003 },
+    { 0x0000989c, 0x003000f2, 0x003000f2 },
+    { 0x0000989c, 0x00440016, 0x00440016 },
+    { 0x0000989c, 0x00410040, 0x00410040 },
+    { 0x0000989c, 0x0001805e, 0x0001805e },
+    { 0x0000989c, 0x0000c0ab, 0x0000c0ab },
+    { 0x0000989c, 0x000000f1, 0x000000f1 },
+    { 0x0000989c, 0x00002081, 0x00002081 },
+    { 0x0000989c, 0x000000d4, 0x000000d4 },
+    { 0x000098d0, 0x0000000f, 0x0010000f },
+};
+
+static const u32 ar5416Bank6TPC_9160[][3] = {
+    { 0x0000989c, 0x00000000, 0x00000000 },
+    { 0x0000989c, 0x00000000, 0x00000000 },
+    { 0x0000989c, 0x00000000, 0x00000000 },
+    { 0x0000989c, 0x00e00000, 0x00e00000 },
+    { 0x0000989c, 0x005e0000, 0x005e0000 },
+    { 0x0000989c, 0x00120000, 0x00120000 },
+    { 0x0000989c, 0x00620000, 0x00620000 },
+    { 0x0000989c, 0x00020000, 0x00020000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x40ff0000, 0x40ff0000 },
+    { 0x0000989c, 0x005f0000, 0x005f0000 },
+    { 0x0000989c, 0x00870000, 0x00870000 },
+    { 0x0000989c, 0x00f90000, 0x00f90000 },
+    { 0x0000989c, 0x007b0000, 0x007b0000 },
+    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
+    { 0x0000989c, 0x00f50000, 0x00f50000 },
+    { 0x0000989c, 0x00dc0000, 0x00dc0000 },
+    { 0x0000989c, 0x00110000, 0x00110000 },
+    { 0x0000989c, 0x006100a8, 0x006100a8 },
+    { 0x0000989c, 0x00423022, 0x00423022 },
+    { 0x0000989c, 0x2014008f, 0x2014008f },
+    { 0x0000989c, 0x00c40002, 0x00c40002 },
+    { 0x0000989c, 0x003000f2, 0x003000f2 },
+    { 0x0000989c, 0x00440016, 0x00440016 },
+    { 0x0000989c, 0x00410040, 0x00410040 },
+    { 0x0000989c, 0x0001805e, 0x0001805e },
+    { 0x0000989c, 0x0000c0ab, 0x0000c0ab },
+    { 0x0000989c, 0x000000e1, 0x000000e1 },
+    { 0x0000989c, 0x00007080, 0x00007080 },
+    { 0x0000989c, 0x000000d4, 0x000000d4 },
+    { 0x000098d0, 0x0000000f, 0x0010000f },
+};
+
+static const u32 ar5416Bank7_9160[][2] = {
+    { 0x0000989c, 0x00000500 },
+    { 0x0000989c, 0x00000800 },
+    { 0x000098cc, 0x0000000e },
+};
+
+static u32 ar5416Addac_9160[][2] = {
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x000000c0 },
+    {0x0000989c,  0x00000018 },
+    {0x0000989c,  0x00000004 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x000000c0 },
+    {0x0000989c,  0x00000019 },
+    {0x0000989c,  0x00000004 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000004 },
+    {0x0000989c,  0x00000003 },
+    {0x0000989c,  0x00000008 },
+    {0x0000989c,  0x00000000 },
+    {0x000098cc,  0x00000000 },
+};
+
+static u32 ar5416Addac_91601_1[][2] = {
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x000000c0 },
+    {0x0000989c,  0x00000018 },
+    {0x0000989c,  0x00000004 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x000000c0 },
+    {0x0000989c,  0x00000019 },
+    {0x0000989c,  0x00000004 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x0000989c,  0x00000000 },
+    {0x000098cc,  0x00000000 },
+};
+
+/* XXX 9280 1 */
+static const u32 ar9280Modes_9280[][6] = {
+    { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
+    { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
+    { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
+    { 0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000, 0x00014008 },
+    { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801080, 0x08400840, 0x06e006e0 },
+    { 0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b, 0x0988004f },
+    { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 },
+    { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 },
+    { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
+    { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 },
+    { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
+    { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 },
+    { 0x00009844, 0x1372161e, 0x1372161e, 0x137216a0, 0x137216a0, 0x137216a0 },
+    { 0x00009848, 0x00028566, 0x00028566, 0x00028563, 0x00028563, 0x00028563 },
+    { 0x0000a848, 0x00028566, 0x00028566, 0x00028563, 0x00028563, 0x00028563 },
+    { 0x00009850, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2 },
+    { 0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e },
+    { 0x0000985c, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e },
+    { 0x00009860, 0x00049d18, 0x00049d18, 0x00049d20, 0x00049d20, 0x00049d18 },
+    { 0x0000c864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 },
+    { 0x00009868, 0x5ac64190, 0x5ac64190, 0x5ac64190, 0x5ac64190, 0x5ac64190 },
+    { 0x0000986c, 0x06903081, 0x06903081, 0x06903881, 0x06903881, 0x06903881 },
+    { 0x00009914, 0x000007d0, 0x000007d0, 0x00000898, 0x00000898, 0x000007d0 },
+    { 0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016 },
+    { 0x00009924, 0xd00a8a07, 0xd00a8a07, 0xd00a8a0d, 0xd00a8a0d, 0xd00a8a0d },
+    { 0x00009944, 0xdfbc1010, 0xdfbc1010, 0xdfbc1010, 0xdfbc1010, 0xdfbc1010 },
+    { 0x00009960, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010 },
+    { 0x0000a960, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010 },
+    { 0x00009964, 0x00000210, 0x00000210, 0x00000210, 0x00000210, 0x00000210 },
+    { 0x0000c9b8, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a },
+    { 0x0000c9bc, 0x00000600, 0x00000600, 0x00000c00, 0x00000c00, 0x00000c00 },
+    { 0x000099c0, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4 },
+    { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 },
+    { 0x000099c8, 0x60f6532c, 0x60f6532c, 0x60f6532c, 0x60f6532c, 0x60f6532c },
+    { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 },
+    { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 },
+    { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x00009a00, 0x00008184, 0x00008184, 0x00000214, 0x00000214, 0x00000214 },
+    { 0x00009a04, 0x00008188, 0x00008188, 0x00000218, 0x00000218, 0x00000218 },
+    { 0x00009a08, 0x0000818c, 0x0000818c, 0x00000224, 0x00000224, 0x00000224 },
+    { 0x00009a0c, 0x00008190, 0x00008190, 0x00000228, 0x00000228, 0x00000228 },
+    { 0x00009a10, 0x00008194, 0x00008194, 0x0000022c, 0x0000022c, 0x0000022c },
+    { 0x00009a14, 0x00008200, 0x00008200, 0x00000230, 0x00000230, 0x00000230 },
+    { 0x00009a18, 0x00008204, 0x00008204, 0x000002a4, 0x000002a4, 0x000002a4 },
+    { 0x00009a1c, 0x00008208, 0x00008208, 0x000002a8, 0x000002a8, 0x000002a8 },
+    { 0x00009a20, 0x0000820c, 0x0000820c, 0x000002ac, 0x000002ac, 0x000002ac },
+    { 0x00009a24, 0x00008210, 0x00008210, 0x000002b0, 0x000002b0, 0x000002b0 },
+    { 0x00009a28, 0x00008214, 0x00008214, 0x000002b4, 0x000002b4, 0x000002b4 },
+    { 0x00009a2c, 0x00008280, 0x00008280, 0x000002b8, 0x000002b8, 0x000002b8 },
+    { 0x00009a30, 0x00008284, 0x00008284, 0x00000390, 0x00000390, 0x00000390 },
+    { 0x00009a34, 0x00008288, 0x00008288, 0x00000394, 0x00000394, 0x00000394 },
+    { 0x00009a38, 0x0000828c, 0x0000828c, 0x00000398, 0x00000398, 0x00000398 },
+    { 0x00009a3c, 0x00008290, 0x00008290, 0x00000334, 0x00000334, 0x00000334 },
+    { 0x00009a40, 0x00008300, 0x00008300, 0x00000338, 0x00000338, 0x00000338 },
+    { 0x00009a44, 0x00008304, 0x00008304, 0x000003ac, 0x000003ac, 0x000003ac },
+    { 0x00009a48, 0x00008308, 0x00008308, 0x000003b0, 0x000003b0, 0x000003b0 },
+    { 0x00009a4c, 0x0000830c, 0x0000830c, 0x000003b4, 0x000003b4, 0x000003b4 },
+    { 0x00009a50, 0x00008310, 0x00008310, 0x000003b8, 0x000003b8, 0x000003b8 },
+    { 0x00009a54, 0x00008314, 0x00008314, 0x000003a5, 0x000003a5, 0x000003a5 },
+    { 0x00009a58, 0x00008380, 0x00008380, 0x000003a9, 0x000003a9, 0x000003a9 },
+    { 0x00009a5c, 0x00008384, 0x00008384, 0x000003ad, 0x000003ad, 0x000003ad },
+    { 0x00009a60, 0x00008388, 0x00008388, 0x00008194, 0x00008194, 0x00008194 },
+    { 0x00009a64, 0x0000838c, 0x0000838c, 0x000081a0, 0x000081a0, 0x000081a0 },
+    { 0x00009a68, 0x00008390, 0x00008390, 0x0000820c, 0x0000820c, 0x0000820c },
+    { 0x00009a6c, 0x00008394, 0x00008394, 0x000081a8, 0x000081a8, 0x000081a8 },
+    { 0x00009a70, 0x0000a380, 0x0000a380, 0x00008284, 0x00008284, 0x00008284 },
+    { 0x00009a74, 0x0000a384, 0x0000a384, 0x00008288, 0x00008288, 0x00008288 },
+    { 0x00009a78, 0x0000a388, 0x0000a388, 0x00008224, 0x00008224, 0x00008224 },
+    { 0x00009a7c, 0x0000a38c, 0x0000a38c, 0x00008290, 0x00008290, 0x00008290 },
+    { 0x00009a80, 0x0000a390, 0x0000a390, 0x00008300, 0x00008300, 0x00008300 },
+    { 0x00009a84, 0x0000a394, 0x0000a394, 0x00008304, 0x00008304, 0x00008304 },
+    { 0x00009a88, 0x0000a780, 0x0000a780, 0x00008308, 0x00008308, 0x00008308 },
+    { 0x00009a8c, 0x0000a784, 0x0000a784, 0x0000830c, 0x0000830c, 0x0000830c },
+    { 0x00009a90, 0x0000a788, 0x0000a788, 0x00008380, 0x00008380, 0x00008380 },
+    { 0x00009a94, 0x0000a78c, 0x0000a78c, 0x00008384, 0x00008384, 0x00008384 },
+    { 0x00009a98, 0x0000a790, 0x0000a790, 0x00008700, 0x00008700, 0x00008700 },
+    { 0x00009a9c, 0x0000a794, 0x0000a794, 0x00008704, 0x00008704, 0x00008704 },
+    { 0x00009aa0, 0x0000ab84, 0x0000ab84, 0x00008708, 0x00008708, 0x00008708 },
+    { 0x00009aa4, 0x0000ab88, 0x0000ab88, 0x0000870c, 0x0000870c, 0x0000870c },
+    { 0x00009aa8, 0x0000ab8c, 0x0000ab8c, 0x00008780, 0x00008780, 0x00008780 },
+    { 0x00009aac, 0x0000ab90, 0x0000ab90, 0x00008784, 0x00008784, 0x00008784 },
+    { 0x00009ab0, 0x0000ab94, 0x0000ab94, 0x00008b00, 0x00008b00, 0x00008b00 },
+    { 0x00009ab4, 0x0000af80, 0x0000af80, 0x00008b04, 0x00008b04, 0x00008b04 },
+    { 0x00009ab8, 0x0000af84, 0x0000af84, 0x00008b08, 0x00008b08, 0x00008b08 },
+    { 0x00009abc, 0x0000af88, 0x0000af88, 0x00008b0c, 0x00008b0c, 0x00008b0c },
+    { 0x00009ac0, 0x0000af8c, 0x0000af8c, 0x00008b80, 0x00008b80, 0x00008b80 },
+    { 0x00009ac4, 0x0000af90, 0x0000af90, 0x00008b84, 0x00008b84, 0x00008b84 },
+    { 0x00009ac8, 0x0000af94, 0x0000af94, 0x00008b88, 0x00008b88, 0x00008b88 },
+    { 0x00009acc, 0x0000b380, 0x0000b380, 0x00008b8c, 0x00008b8c, 0x00008b8c },
+    { 0x00009ad0, 0x0000b384, 0x0000b384, 0x00008b90, 0x00008b90, 0x00008b90 },
+    { 0x00009ad4, 0x0000b388, 0x0000b388, 0x00008f80, 0x00008f80, 0x00008f80 },
+    { 0x00009ad8, 0x0000b38c, 0x0000b38c, 0x00008f84, 0x00008f84, 0x00008f84 },
+    { 0x00009adc, 0x0000b390, 0x0000b390, 0x00008f88, 0x00008f88, 0x00008f88 },
+    { 0x00009ae0, 0x0000b394, 0x0000b394, 0x00008f8c, 0x00008f8c, 0x00008f8c },
+    { 0x00009ae4, 0x0000b398, 0x0000b398, 0x00008f90, 0x00008f90, 0x00008f90 },
+    { 0x00009ae8, 0x0000b780, 0x0000b780, 0x0000930c, 0x0000930c, 0x0000930c },
+    { 0x00009aec, 0x0000b784, 0x0000b784, 0x00009310, 0x00009310, 0x00009310 },
+    { 0x00009af0, 0x0000b788, 0x0000b788, 0x00009384, 0x00009384, 0x00009384 },
+    { 0x00009af4, 0x0000b78c, 0x0000b78c, 0x00009388, 0x00009388, 0x00009388 },
+    { 0x00009af8, 0x0000b790, 0x0000b790, 0x00009324, 0x00009324, 0x00009324 },
+    { 0x00009afc, 0x0000b794, 0x0000b794, 0x00009704, 0x00009704, 0x00009704 },
+    { 0x00009b00, 0x0000b798, 0x0000b798, 0x000096a4, 0x000096a4, 0x000096a4 },
+    { 0x00009b04, 0x0000d784, 0x0000d784, 0x000096a8, 0x000096a8, 0x000096a8 },
+    { 0x00009b08, 0x0000d788, 0x0000d788, 0x00009710, 0x00009710, 0x00009710 },
+    { 0x00009b0c, 0x0000d78c, 0x0000d78c, 0x00009714, 0x00009714, 0x00009714 },
+    { 0x00009b10, 0x0000d790, 0x0000d790, 0x00009720, 0x00009720, 0x00009720 },
+    { 0x00009b14, 0x0000f780, 0x0000f780, 0x00009724, 0x00009724, 0x00009724 },
+    { 0x00009b18, 0x0000f784, 0x0000f784, 0x00009728, 0x00009728, 0x00009728 },
+    { 0x00009b1c, 0x0000f788, 0x0000f788, 0x0000972c, 0x0000972c, 0x0000972c },
+    { 0x00009b20, 0x0000f78c, 0x0000f78c, 0x000097a0, 0x000097a0, 0x000097a0 },
+    { 0x00009b24, 0x0000f790, 0x0000f790, 0x000097a4, 0x000097a4, 0x000097a4 },
+    { 0x00009b28, 0x0000f794, 0x0000f794, 0x000097a8, 0x000097a8, 0x000097a8 },
+    { 0x00009b2c, 0x0000f7a4, 0x0000f7a4, 0x000097b0, 0x000097b0, 0x000097b0 },
+    { 0x00009b30, 0x0000f7a8, 0x0000f7a8, 0x000097b4, 0x000097b4, 0x000097b4 },
+    { 0x00009b34, 0x0000f7ac, 0x0000f7ac, 0x000097b8, 0x000097b8, 0x000097b8 },
+    { 0x00009b38, 0x0000f7b0, 0x0000f7b0, 0x000097a5, 0x000097a5, 0x000097a5 },
+    { 0x00009b3c, 0x0000f7b4, 0x0000f7b4, 0x000097a9, 0x000097a9, 0x000097a9 },
+    { 0x00009b40, 0x0000f7a1, 0x0000f7a1, 0x000097ad, 0x000097ad, 0x000097ad },
+    { 0x00009b44, 0x0000f7a5, 0x0000f7a5, 0x000097b1, 0x000097b1, 0x000097b1 },
+    { 0x00009b48, 0x0000f7a9, 0x0000f7a9, 0x000097b5, 0x000097b5, 0x000097b5 },
+    { 0x00009b4c, 0x0000f7ad, 0x0000f7ad, 0x000097b9, 0x000097b9, 0x000097b9 },
+    { 0x00009b50, 0x0000f7b1, 0x0000f7b1, 0x000097c5, 0x000097c5, 0x000097c5 },
+    { 0x00009b54, 0x0000f7b5, 0x0000f7b5, 0x000097c9, 0x000097c9, 0x000097c9 },
+    { 0x00009b58, 0x0000f7c5, 0x0000f7c5, 0x000097d1, 0x000097d1, 0x000097d1 },
+    { 0x00009b5c, 0x0000f7c9, 0x0000f7c9, 0x000097d5, 0x000097d5, 0x000097d5 },
+    { 0x00009b60, 0x0000f7cd, 0x0000f7cd, 0x000097d9, 0x000097d9, 0x000097d9 },
+    { 0x00009b64, 0x0000f7d1, 0x0000f7d1, 0x000097c6, 0x000097c6, 0x000097c6 },
+    { 0x00009b68, 0x0000f7d5, 0x0000f7d5, 0x000097ca, 0x000097ca, 0x000097ca },
+    { 0x00009b6c, 0x0000f7c2, 0x0000f7c2, 0x000097ce, 0x000097ce, 0x000097ce },
+    { 0x00009b70, 0x0000f7c6, 0x0000f7c6, 0x000097d2, 0x000097d2, 0x000097d2 },
+    { 0x00009b74, 0x0000f7ca, 0x0000f7ca, 0x000097d6, 0x000097d6, 0x000097d6 },
+    { 0x00009b78, 0x0000f7ce, 0x0000f7ce, 0x000097c3, 0x000097c3, 0x000097c3 },
+    { 0x00009b7c, 0x0000f7d2, 0x0000f7d2, 0x000097c7, 0x000097c7, 0x000097c7 },
+    { 0x00009b80, 0x0000f7d6, 0x0000f7d6, 0x000097cb, 0x000097cb, 0x000097cb },
+    { 0x00009b84, 0x0000f7c3, 0x0000f7c3, 0x000097cf, 0x000097cf, 0x000097cf },
+    { 0x00009b88, 0x0000f7c7, 0x0000f7c7, 0x000097d7, 0x000097d7, 0x000097d7 },
+    { 0x00009b8c, 0x0000f7cb, 0x0000f7cb, 0x000097db, 0x000097db, 0x000097db },
+    { 0x00009b90, 0x0000f7d3, 0x0000f7d3, 0x000097db, 0x000097db, 0x000097db },
+    { 0x00009b94, 0x0000f7d7, 0x0000f7d7, 0x000097db, 0x000097db, 0x000097db },
+    { 0x00009b98, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
+    { 0x00009b9c, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
+    { 0x00009ba0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
+    { 0x00009ba4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
+    { 0x00009ba8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
+    { 0x00009bac, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
+    { 0x00009bb0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
+    { 0x00009bb4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
+    { 0x00009bb8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
+    { 0x00009bbc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
+    { 0x00009bc0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
+    { 0x00009bc4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
+    { 0x00009bc8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
+    { 0x00009bcc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
+    { 0x00009bd0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
+    { 0x00009bd4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
+    { 0x00009bd8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
+    { 0x00009bdc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
+    { 0x00009be0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
+    { 0x00009be4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
+    { 0x00009be8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
+    { 0x00009bec, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
+    { 0x00009bf0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
+    { 0x00009bf4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
+    { 0x00009bf8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
+    { 0x00009bfc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
+    { 0x0000a204, 0x00000444, 0x00000444, 0x00000444, 0x00000444, 0x00000444 },
+    { 0x0000a208, 0x803e4788, 0x803e4788, 0x803e4788, 0x803e4788, 0x803e4788 },
+    { 0x0000a20c, 0x000c6019, 0x000c6019, 0x000c6019, 0x000c6019, 0x000c6019 },
+    { 0x0000b20c, 0x000c6019, 0x000c6019, 0x000c6019, 0x000c6019, 0x000c6019 },
+    { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a },
+    { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
+    { 0x0000a274, 0x0a19c652, 0x0a19c652, 0x0a1aa652, 0x0a1aa652, 0x0a1aa652 },
+    { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x0000a304, 0x00003002, 0x00003002, 0x00003002, 0x00003002, 0x00003002 },
+    { 0x0000a308, 0x00006004, 0x00006004, 0x00008009, 0x00008009, 0x00008009 },
+    { 0x0000a30c, 0x0000a006, 0x0000a006, 0x0000b00b, 0x0000b00b, 0x0000b00b },
+    { 0x0000a310, 0x0000e012, 0x0000e012, 0x0000e012, 0x0000e012, 0x0000e012 },
+    { 0x0000a314, 0x00011014, 0x00011014, 0x00012048, 0x00012048, 0x00012048 },
+    { 0x0000a318, 0x0001504a, 0x0001504a, 0x0001604a, 0x0001604a, 0x0001604a },
+    { 0x0000a31c, 0x0001904c, 0x0001904c, 0x0001a211, 0x0001a211, 0x0001a211 },
+    { 0x0000a320, 0x0001c04e, 0x0001c04e, 0x0001e213, 0x0001e213, 0x0001e213 },
+    { 0x0000a324, 0x00020092, 0x00020092, 0x0002121b, 0x0002121b, 0x0002121b },
+    { 0x0000a328, 0x0002410a, 0x0002410a, 0x00024412, 0x00024412, 0x00024412 },
+    { 0x0000a32c, 0x0002710c, 0x0002710c, 0x00028414, 0x00028414, 0x00028414 },
+    { 0x0000a330, 0x0002b18b, 0x0002b18b, 0x0002b44a, 0x0002b44a, 0x0002b44a },
+    { 0x0000a334, 0x0002e1cc, 0x0002e1cc, 0x00030649, 0x00030649, 0x00030649 },
+    { 0x0000a338, 0x000321ec, 0x000321ec, 0x0003364b, 0x0003364b, 0x0003364b },
+    { 0x0000a33c, 0x000321ec, 0x000321ec, 0x00038a49, 0x00038a49, 0x00038a49 },
+    { 0x0000a340, 0x000321ec, 0x000321ec, 0x0003be48, 0x0003be48, 0x0003be48 },
+    { 0x0000a344, 0x000321ec, 0x000321ec, 0x0003ee4a, 0x0003ee4a, 0x0003ee4a },
+    { 0x0000a348, 0x000321ec, 0x000321ec, 0x00042e88, 0x00042e88, 0x00042e88 },
+    { 0x0000a34c, 0x000321ec, 0x000321ec, 0x00046e8a, 0x00046e8a, 0x00046e8a },
+    { 0x0000a350, 0x000321ec, 0x000321ec, 0x00049ec9, 0x00049ec9, 0x00049ec9 },
+    { 0x0000a354, 0x000321ec, 0x000321ec, 0x0004bf42, 0x0004bf42, 0x0004bf42 },
+    { 0x0000784c, 0x0e4f048c, 0x0e4f048c, 0x0e4d048c, 0x0e4d048c, 0x0e4d048c },
+    { 0x00007854, 0x12031828, 0x12031828, 0x12035828, 0x12035828, 0x12035828 },
+    { 0x00007870, 0x807ec400, 0x807ec400, 0x807ec000, 0x807ec000, 0x807ec000 },
+    { 0x0000788c, 0x00010000, 0x00010000, 0x00110000, 0x00110000, 0x00110000 },
+};
+
+static const u32 ar9280Common_9280[][2] = {
+    { 0x0000000c, 0x00000000 },
+    { 0x00000030, 0x00020015 },
+    { 0x00000034, 0x00000005 },
+    { 0x00000040, 0x00000000 },
+    { 0x00000044, 0x00000008 },
+    { 0x00000048, 0x00000008 },
+    { 0x0000004c, 0x00000010 },
+    { 0x00000050, 0x00000000 },
+    { 0x00000054, 0x0000001f },
+    { 0x00000800, 0x00000000 },
+    { 0x00000804, 0x00000000 },
+    { 0x00000808, 0x00000000 },
+    { 0x0000080c, 0x00000000 },
+    { 0x00000810, 0x00000000 },
+    { 0x00000814, 0x00000000 },
+    { 0x00000818, 0x00000000 },
+    { 0x0000081c, 0x00000000 },
+    { 0x00000820, 0x00000000 },
+    { 0x00000824, 0x00000000 },
+    { 0x00001040, 0x002ffc0f },
+    { 0x00001044, 0x002ffc0f },
+    { 0x00001048, 0x002ffc0f },
+    { 0x0000104c, 0x002ffc0f },
+    { 0x00001050, 0x002ffc0f },
+    { 0x00001054, 0x002ffc0f },
+    { 0x00001058, 0x002ffc0f },
+    { 0x0000105c, 0x002ffc0f },
+    { 0x00001060, 0x002ffc0f },
+    { 0x00001064, 0x002ffc0f },
+    { 0x00001230, 0x00000000 },
+    { 0x00001270, 0x00000000 },
+    { 0x00001038, 0x00000000 },
+    { 0x00001078, 0x00000000 },
+    { 0x000010b8, 0x00000000 },
+    { 0x000010f8, 0x00000000 },
+    { 0x00001138, 0x00000000 },
+    { 0x00001178, 0x00000000 },
+    { 0x000011b8, 0x00000000 },
+    { 0x000011f8, 0x00000000 },
+    { 0x00001238, 0x00000000 },
+    { 0x00001278, 0x00000000 },
+    { 0x000012b8, 0x00000000 },
+    { 0x000012f8, 0x00000000 },
+    { 0x00001338, 0x00000000 },
+    { 0x00001378, 0x00000000 },
+    { 0x000013b8, 0x00000000 },
+    { 0x000013f8, 0x00000000 },
+    { 0x00001438, 0x00000000 },
+    { 0x00001478, 0x00000000 },
+    { 0x000014b8, 0x00000000 },
+    { 0x000014f8, 0x00000000 },
+    { 0x00001538, 0x00000000 },
+    { 0x00001578, 0x00000000 },
+    { 0x000015b8, 0x00000000 },
+    { 0x000015f8, 0x00000000 },
+    { 0x00001638, 0x00000000 },
+    { 0x00001678, 0x00000000 },
+    { 0x000016b8, 0x00000000 },
+    { 0x000016f8, 0x00000000 },
+    { 0x00001738, 0x00000000 },
+    { 0x00001778, 0x00000000 },
+    { 0x000017b8, 0x00000000 },
+    { 0x000017f8, 0x00000000 },
+    { 0x0000103c, 0x00000000 },
+    { 0x0000107c, 0x00000000 },
+    { 0x000010bc, 0x00000000 },
+    { 0x000010fc, 0x00000000 },
+    { 0x0000113c, 0x00000000 },
+    { 0x0000117c, 0x00000000 },
+    { 0x000011bc, 0x00000000 },
+    { 0x000011fc, 0x00000000 },
+    { 0x0000123c, 0x00000000 },
+    { 0x0000127c, 0x00000000 },
+    { 0x000012bc, 0x00000000 },
+    { 0x000012fc, 0x00000000 },
+    { 0x0000133c, 0x00000000 },
+    { 0x0000137c, 0x00000000 },
+    { 0x000013bc, 0x00000000 },
+    { 0x000013fc, 0x00000000 },
+    { 0x0000143c, 0x00000000 },
+    { 0x0000147c, 0x00000000 },
+    { 0x00004030, 0x00000002 },
+    { 0x0000403c, 0x00000002 },
+    { 0x00004024, 0x0000001f },
+    { 0x00007010, 0x00000033 },
+    { 0x00007038, 0x000004c2 },
+    { 0x00008004, 0x00000000 },
+    { 0x00008008, 0x00000000 },
+    { 0x0000800c, 0x00000000 },
+    { 0x00008018, 0x00000700 },
+    { 0x00008020, 0x00000000 },
+    { 0x00008038, 0x00000000 },
+    { 0x0000803c, 0x00000000 },
+    { 0x00008048, 0x40000000 },
+    { 0x00008054, 0x00000000 },
+    { 0x00008058, 0x00000000 },
+    { 0x0000805c, 0x000fc78f },
+    { 0x00008060, 0x0000000f },
+    { 0x00008064, 0x00000000 },
+    { 0x00008070, 0x00000000 },
+    { 0x000080c0, 0x2a82301a },
+    { 0x000080c4, 0x05dc01e0 },
+    { 0x000080c8, 0x1f402710 },
+    { 0x000080cc, 0x01f40000 },
+    { 0x000080d0, 0x00001e00 },
+    { 0x000080d4, 0x00000000 },
+    { 0x000080d8, 0x00400000 },
+    { 0x000080e0, 0xffffffff },
+    { 0x000080e4, 0x0000ffff },
+    { 0x000080e8, 0x003f3f3f },
+    { 0x000080ec, 0x00000000 },
+    { 0x000080f0, 0x00000000 },
+    { 0x000080f4, 0x00000000 },
+    { 0x000080f8, 0x00000000 },
+    { 0x000080fc, 0x00020000 },
+    { 0x00008100, 0x00020000 },
+    { 0x00008104, 0x00000001 },
+    { 0x00008108, 0x00000052 },
+    { 0x0000810c, 0x00000000 },
+    { 0x00008110, 0x00000168 },
+    { 0x00008118, 0x000100aa },
+    { 0x0000811c, 0x00003210 },
+    { 0x00008120, 0x08f04800 },
+    { 0x00008124, 0x00000000 },
+    { 0x00008128, 0x00000000 },
+    { 0x0000812c, 0x00000000 },
+    { 0x00008130, 0x00000000 },
+    { 0x00008134, 0x00000000 },
+    { 0x00008138, 0x00000000 },
+    { 0x0000813c, 0x00000000 },
+    { 0x00008144, 0x00000000 },
+    { 0x00008168, 0x00000000 },
+    { 0x0000816c, 0x00000000 },
+    { 0x00008170, 0x32143320 },
+    { 0x00008174, 0xfaa4fa50 },
+    { 0x00008178, 0x00000100 },
+    { 0x0000817c, 0x00000000 },
+    { 0x000081c4, 0x00000000 },
+    { 0x000081d0, 0x00003210 },
+    { 0x000081ec, 0x00000000 },
+    { 0x000081f0, 0x00000000 },
+    { 0x000081f4, 0x00000000 },
+    { 0x000081f8, 0x00000000 },
+    { 0x000081fc, 0x00000000 },
+    { 0x00008200, 0x00000000 },
+    { 0x00008204, 0x00000000 },
+    { 0x00008208, 0x00000000 },
+    { 0x0000820c, 0x00000000 },
+    { 0x00008210, 0x00000000 },
+    { 0x00008214, 0x00000000 },
+    { 0x00008218, 0x00000000 },
+    { 0x0000821c, 0x00000000 },
+    { 0x00008220, 0x00000000 },
+    { 0x00008224, 0x00000000 },
+    { 0x00008228, 0x00000000 },
+    { 0x0000822c, 0x00000000 },
+    { 0x00008230, 0x00000000 },
+    { 0x00008234, 0x00000000 },
+    { 0x00008238, 0x00000000 },
+    { 0x0000823c, 0x00000000 },
+    { 0x00008240, 0x00100000 },
+    { 0x00008244, 0x0010f400 },
+    { 0x00008248, 0x00000100 },
+    { 0x0000824c, 0x0001e800 },
+    { 0x00008250, 0x00000000 },
+    { 0x00008254, 0x00000000 },
+    { 0x00008258, 0x00000000 },
+    { 0x0000825c, 0x400000ff },
+    { 0x00008260, 0x00080922 },
+    { 0x00008270, 0x00000000 },
+    { 0x00008274, 0x40000000 },
+    { 0x00008278, 0x003e4180 },
+    { 0x0000827c, 0x00000000 },
+    { 0x00008284, 0x0000002c },
+    { 0x00008288, 0x0000002c },
+    { 0x0000828c, 0x00000000 },
+    { 0x00008294, 0x00000000 },
+    { 0x00008298, 0x00000000 },
+    { 0x00008300, 0x00000000 },
+    { 0x00008304, 0x00000000 },
+    { 0x00008308, 0x00000000 },
+    { 0x0000830c, 0x00000000 },
+    { 0x00008310, 0x00000000 },
+    { 0x00008314, 0x00000000 },
+    { 0x00008318, 0x00000000 },
+    { 0x00008328, 0x00000000 },
+    { 0x0000832c, 0x00000007 },
+    { 0x00008330, 0x00000302 },
+    { 0x00008334, 0x00000e00 },
+    { 0x00008338, 0x00000000 },
+    { 0x0000833c, 0x00000000 },
+    { 0x00008340, 0x000107ff },
+    { 0x00008344, 0x00000000 },
+    { 0x00009808, 0x00000000 },
+    { 0x0000980c, 0xaf268e30 },
+    { 0x00009810, 0xfd14e000 },
+    { 0x00009814, 0x9c0a9f6b },
+    { 0x0000981c, 0x00000000 },
+    { 0x0000982c, 0x0000a000 },
+    { 0x00009830, 0x00000000 },
+    { 0x0000983c, 0x00200400 },
+    { 0x00009840, 0x206a01ae },
+    { 0x0000984c, 0x0040233c },
+    { 0x0000a84c, 0x0040233c },
+    { 0x00009854, 0x00000044 },
+    { 0x00009900, 0x00000000 },
+    { 0x00009904, 0x00000000 },
+    { 0x00009908, 0x00000000 },
+    { 0x0000990c, 0x00000000 },
+    { 0x0000991c, 0x10000fff },
+    { 0x00009920, 0x04900000 },
+    { 0x0000a920, 0x04900000 },
+    { 0x00009928, 0x00000001 },
+    { 0x0000992c, 0x00000004 },
+    { 0x00009934, 0x1e1f2022 },
+    { 0x00009938, 0x0a0b0c0d },
+    { 0x0000993c, 0x00000000 },
+    { 0x00009948, 0x9280c00a },
+    { 0x0000994c, 0x00020028 },
+    { 0x00009954, 0xe250a51e },
+    { 0x00009958, 0x3388ffff },
+    { 0x00009940, 0x00781204 },
+    { 0x0000c95c, 0x004b6a8e },
+    { 0x0000c968, 0x000003ce },
+    { 0x00009970, 0x190fb514 },
+    { 0x00009974, 0x00000000 },
+    { 0x00009978, 0x00000001 },
+    { 0x0000997c, 0x00000000 },
+    { 0x00009980, 0x00000000 },
+    { 0x00009984, 0x00000000 },
+    { 0x00009988, 0x00000000 },
+    { 0x0000998c, 0x00000000 },
+    { 0x00009990, 0x00000000 },
+    { 0x00009994, 0x00000000 },
+    { 0x00009998, 0x00000000 },
+    { 0x0000999c, 0x00000000 },
+    { 0x000099a0, 0x00000000 },
+    { 0x000099a4, 0x00000001 },
+    { 0x000099a8, 0x201fff00 },
+    { 0x000099ac, 0x006f00c4 },
+    { 0x000099b0, 0x03051000 },
+    { 0x000099b4, 0x00000820 },
+    { 0x000099dc, 0x00000000 },
+    { 0x000099e0, 0x00000000 },
+    { 0x000099e4, 0xaaaaaaaa },
+    { 0x000099e8, 0x3c466478 },
+    { 0x000099ec, 0x0cc80caa },
+    { 0x000099fc, 0x00001042 },
+    { 0x0000a210, 0x4080a333 },
+    { 0x0000a214, 0x40206c10 },
+    { 0x0000a218, 0x009c4060 },
+    { 0x0000a220, 0x01834061 },
+    { 0x0000a224, 0x00000400 },
+    { 0x0000a228, 0x000003b5 },
+    { 0x0000a22c, 0x23277200 },
+    { 0x0000a234, 0x20202020 },
+    { 0x0000a238, 0x20202020 },
+    { 0x0000a23c, 0x13c889af },
+    { 0x0000a240, 0x38490a20 },
+    { 0x0000a244, 0x00007bb6 },
+    { 0x0000a248, 0x0fff3ffc },
+    { 0x0000a24c, 0x00000001 },
+    { 0x0000a250, 0x001da000 },
+    { 0x0000a254, 0x00000000 },
+    { 0x0000a258, 0x0cdbd380 },
+    { 0x0000a25c, 0x0f0f0f01 },
+    { 0x0000a260, 0xdfa91f01 },
+    { 0x0000a268, 0x00000000 },
+    { 0x0000a26c, 0x0ebae9c6 },
+    { 0x0000b26c, 0x0ebae9c6 },
+    { 0x0000d270, 0x00820820 },
+    { 0x0000a278, 0x1ce739ce },
+    { 0x0000a27c, 0x050701ce },
+    { 0x0000a358, 0x7999aa0f },
+    { 0x0000d35c, 0x07ffffef },
+    { 0x0000d360, 0x0fffffe7 },
+    { 0x0000d364, 0x17ffffe5 },
+    { 0x0000d368, 0x1fffffe4 },
+    { 0x0000d36c, 0x37ffffe3 },
+    { 0x0000d370, 0x3fffffe3 },
+    { 0x0000d374, 0x57ffffe3 },
+    { 0x0000d378, 0x5fffffe2 },
+    { 0x0000d37c, 0x7fffffe2 },
+    { 0x0000d380, 0x7f3c7bba },
+    { 0x0000d384, 0xf3307ff0 },
+    { 0x0000a388, 0x0c000000 },
+    { 0x0000a38c, 0x20202020 },
+    { 0x0000a390, 0x20202020 },
+    { 0x0000a394, 0x1ce739ce },
+    { 0x0000a398, 0x000001ce },
+    { 0x0000a39c, 0x00000001 },
+    { 0x0000a3a0, 0x00000000 },
+    { 0x0000a3a4, 0x00000000 },
+    { 0x0000a3a8, 0x00000000 },
+    { 0x0000a3ac, 0x00000000 },
+    { 0x0000a3b0, 0x00000000 },
+    { 0x0000a3b4, 0x00000000 },
+    { 0x0000a3b8, 0x00000000 },
+    { 0x0000a3bc, 0x00000000 },
+    { 0x0000a3c0, 0x00000000 },
+    { 0x0000a3c4, 0x00000000 },
+    { 0x0000a3c8, 0x00000246 },
+    { 0x0000a3cc, 0x20202020 },
+    { 0x0000a3d0, 0x20202020 },
+    { 0x0000a3d4, 0x20202020 },
+    { 0x0000a3dc, 0x1ce739ce },
+    { 0x0000a3e0, 0x000001ce },
+    { 0x0000a3e4, 0x00000000 },
+    { 0x0000a3e8, 0x18c43433 },
+    { 0x0000a3ec, 0x00f38081 },
+    { 0x00007800, 0x00040000 },
+    { 0x00007804, 0xdb005012 },
+    { 0x00007808, 0x04924914 },
+    { 0x0000780c, 0x21084210 },
+    { 0x00007810, 0x6d801300 },
+    { 0x00007814, 0x0019beff },
+    { 0x00007818, 0x07e40000 },
+    { 0x0000781c, 0x00492000 },
+    { 0x00007820, 0x92492480 },
+    { 0x00007824, 0x00040000 },
+    { 0x00007828, 0xdb005012 },
+    { 0x0000782c, 0x04924914 },
+    { 0x00007830, 0x21084210 },
+    { 0x00007834, 0x6d801300 },
+    { 0x00007838, 0x0019beff },
+    { 0x0000783c, 0x07e40000 },
+    { 0x00007840, 0x00492000 },
+    { 0x00007844, 0x92492480 },
+    { 0x00007848, 0x00120000 },
+    { 0x00007850, 0x54214514 },
+    { 0x00007858, 0x92592692 },
+    { 0x00007860, 0x52802000 },
+    { 0x00007864, 0x0a8e370e },
+    { 0x00007868, 0xc0102850 },
+    { 0x0000786c, 0x812d4000 },
+    { 0x00007874, 0x001b6db0 },
+    { 0x00007878, 0x00376b63 },
+    { 0x0000787c, 0x06db6db6 },
+    { 0x00007880, 0x006d8000 },
+    { 0x00007884, 0xffeffffe },
+    { 0x00007888, 0xffeffffe },
+    { 0x00007890, 0x00060aeb },
+    { 0x00007894, 0x5a108000 },
+    { 0x00007898, 0x2a850160 },
+};
+
+/* XXX 9280 2 */
+static const u32 ar9280Modes_9280_2[][6] = {
+    { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
+    { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
+    { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
+    { 0x000010f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008 },
+    { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 },
+    { 0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b, 0x0988004f },
+    { 0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810, 0x08f04810 },
+    { 0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a, 0x0000320a },
+    { 0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440, 0x00006880 },
+    { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 },
+    { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 },
+    { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
+    { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 },
+    { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
+    { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 },
+    { 0x00009840, 0x206a022e, 0x206a022e, 0x206a012e, 0x206a012e, 0x206a012e },
+    { 0x00009844, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0, 0x037216a0 },
+    { 0x00009850, 0x6c4000e2, 0x6c4000e2, 0x6d4000e2, 0x6c4000e2, 0x6c4000e2 },
+    { 0x00009858, 0x7ec88d2e, 0x7ec88d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e },
+    { 0x0000985c, 0x31395d5e, 0x31395d5e, 0x3139605e, 0x31395d5e, 0x31395d5e },
+    { 0x00009860, 0x00048d18, 0x00048d18, 0x00048d20, 0x00048d20, 0x00048d18 },
+    { 0x00009864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 },
+    { 0x00009868, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0 },
+    { 0x0000986c, 0x06903081, 0x06903081, 0x06903881, 0x06903881, 0x06903881 },
+    { 0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0 },
+    { 0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016 },
+    { 0x00009924, 0xd00a8a0b, 0xd00a8a0b, 0xd00a8a0d, 0xd00a8a0d, 0xd00a8a0d },
+    { 0x00009944, 0xffbc1010, 0xffbc1010, 0xffbc1010, 0xffbc1010, 0xffbc1010 },
+    { 0x00009960, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010 },
+    { 0x0000a960, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010 },
+    { 0x00009964, 0x00000210, 0x00000210, 0x00000210, 0x00000210, 0x00000210 },
+    { 0x000099b8, 0x0000001c, 0x0000001c, 0x0000001c, 0x0000001c, 0x0000001c },
+    { 0x000099bc, 0x00000a00, 0x00000a00, 0x00000c00, 0x00000c00, 0x00000c00 },
+    { 0x000099c0, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4 },
+    { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 },
+    { 0x000099c8, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329 },
+    { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 },
+    { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 },
+    { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x0000a204, 0x00000444, 0x00000444, 0x00000444, 0x00000444, 0x00000444 },
+    { 0x0000a20c, 0x00000014, 0x00000014, 0x0001f019, 0x0001f019, 0x0001f019 },
+    { 0x0000b20c, 0x00000014, 0x00000014, 0x0001f019, 0x0001f019, 0x0001f019 },
+    { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a },
+    { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
+    { 0x0000a250, 0x001ff000, 0x001ff000, 0x0004a000, 0x0004a000, 0x0004a000 },
+    { 0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e },
+    { 0x0000a3d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x00007894, 0x5a508000, 0x5a508000, 0x5a508000, 0x5a508000, 0x5a508000 },
+};
+
+static const u32 ar9280Common_9280_2[][2] = {
+    { 0x0000000c, 0x00000000 },
+    { 0x00000030, 0x00020015 },
+    { 0x00000034, 0x00000005 },
+    { 0x00000040, 0x00000000 },
+    { 0x00000044, 0x00000008 },
+    { 0x00000048, 0x00000008 },
+    { 0x0000004c, 0x00000010 },
+    { 0x00000050, 0x00000000 },
+    { 0x00000054, 0x0000001f },
+    { 0x00000800, 0x00000000 },
+    { 0x00000804, 0x00000000 },
+    { 0x00000808, 0x00000000 },
+    { 0x0000080c, 0x00000000 },
+    { 0x00000810, 0x00000000 },
+    { 0x00000814, 0x00000000 },
+    { 0x00000818, 0x00000000 },
+    { 0x0000081c, 0x00000000 },
+    { 0x00000820, 0x00000000 },
+    { 0x00000824, 0x00000000 },
+    { 0x00001040, 0x002ffc0f },
+    { 0x00001044, 0x002ffc0f },
+    { 0x00001048, 0x002ffc0f },
+    { 0x0000104c, 0x002ffc0f },
+    { 0x00001050, 0x002ffc0f },
+    { 0x00001054, 0x002ffc0f },
+    { 0x00001058, 0x002ffc0f },
+    { 0x0000105c, 0x002ffc0f },
+    { 0x00001060, 0x002ffc0f },
+    { 0x00001064, 0x002ffc0f },
+    { 0x00001230, 0x00000000 },
+    { 0x00001270, 0x00000000 },
+    { 0x00001038, 0x00000000 },
+    { 0x00001078, 0x00000000 },
+    { 0x000010b8, 0x00000000 },
+    { 0x000010f8, 0x00000000 },
+    { 0x00001138, 0x00000000 },
+    { 0x00001178, 0x00000000 },
+    { 0x000011b8, 0x00000000 },
+    { 0x000011f8, 0x00000000 },
+    { 0x00001238, 0x00000000 },
+    { 0x00001278, 0x00000000 },
+    { 0x000012b8, 0x00000000 },
+    { 0x000012f8, 0x00000000 },
+    { 0x00001338, 0x00000000 },
+    { 0x00001378, 0x00000000 },
+    { 0x000013b8, 0x00000000 },
+    { 0x000013f8, 0x00000000 },
+    { 0x00001438, 0x00000000 },
+    { 0x00001478, 0x00000000 },
+    { 0x000014b8, 0x00000000 },
+    { 0x000014f8, 0x00000000 },
+    { 0x00001538, 0x00000000 },
+    { 0x00001578, 0x00000000 },
+    { 0x000015b8, 0x00000000 },
+    { 0x000015f8, 0x00000000 },
+    { 0x00001638, 0x00000000 },
+    { 0x00001678, 0x00000000 },
+    { 0x000016b8, 0x00000000 },
+    { 0x000016f8, 0x00000000 },
+    { 0x00001738, 0x00000000 },
+    { 0x00001778, 0x00000000 },
+    { 0x000017b8, 0x00000000 },
+    { 0x000017f8, 0x00000000 },
+    { 0x0000103c, 0x00000000 },
+    { 0x0000107c, 0x00000000 },
+    { 0x000010bc, 0x00000000 },
+    { 0x000010fc, 0x00000000 },
+    { 0x0000113c, 0x00000000 },
+    { 0x0000117c, 0x00000000 },
+    { 0x000011bc, 0x00000000 },
+    { 0x000011fc, 0x00000000 },
+    { 0x0000123c, 0x00000000 },
+    { 0x0000127c, 0x00000000 },
+    { 0x000012bc, 0x00000000 },
+    { 0x000012fc, 0x00000000 },
+    { 0x0000133c, 0x00000000 },
+    { 0x0000137c, 0x00000000 },
+    { 0x000013bc, 0x00000000 },
+    { 0x000013fc, 0x00000000 },
+    { 0x0000143c, 0x00000000 },
+    { 0x0000147c, 0x00000000 },
+    { 0x00004030, 0x00000002 },
+    { 0x0000403c, 0x00000002 },
+    { 0x00004024, 0x0000001f },
+    { 0x00004060, 0x00000000 },
+    { 0x00004064, 0x00000000 },
+    { 0x00007010, 0x00000033 },
+    { 0x00007034, 0x00000002 },
+    { 0x00007038, 0x000004c2 },
+    { 0x00008004, 0x00000000 },
+    { 0x00008008, 0x00000000 },
+    { 0x0000800c, 0x00000000 },
+    { 0x00008018, 0x00000700 },
+    { 0x00008020, 0x00000000 },
+    { 0x00008038, 0x00000000 },
+    { 0x0000803c, 0x00000000 },
+    { 0x00008048, 0x40000000 },
+    { 0x00008054, 0x00000000 },
+    { 0x00008058, 0x00000000 },
+    { 0x0000805c, 0x000fc78f },
+    { 0x00008060, 0x0000000f },
+    { 0x00008064, 0x00000000 },
+    { 0x00008070, 0x00000000 },
+    { 0x000080c0, 0x2a80001a },
+    { 0x000080c4, 0x05dc01e0 },
+    { 0x000080c8, 0x1f402710 },
+    { 0x000080cc, 0x01f40000 },
+    { 0x000080d0, 0x00001e00 },
+    { 0x000080d4, 0x00000000 },
+    { 0x000080d8, 0x00400000 },
+    { 0x000080e0, 0xffffffff },
+    { 0x000080e4, 0x0000ffff },
+    { 0x000080e8, 0x003f3f3f },
+    { 0x000080ec, 0x00000000 },
+    { 0x000080f0, 0x00000000 },
+    { 0x000080f4, 0x00000000 },
+    { 0x000080f8, 0x00000000 },
+    { 0x000080fc, 0x00020000 },
+    { 0x00008100, 0x00020000 },
+    { 0x00008104, 0x00000001 },
+    { 0x00008108, 0x00000052 },
+    { 0x0000810c, 0x00000000 },
+    { 0x00008110, 0x00000168 },
+    { 0x00008118, 0x000100aa },
+    { 0x0000811c, 0x00003210 },
+    { 0x00008124, 0x00000000 },
+    { 0x00008128, 0x00000000 },
+    { 0x0000812c, 0x00000000 },
+    { 0x00008130, 0x00000000 },
+    { 0x00008134, 0x00000000 },
+    { 0x00008138, 0x00000000 },
+    { 0x0000813c, 0x00000000 },
+    { 0x00008144, 0xffffffff },
+    { 0x00008168, 0x00000000 },
+    { 0x0000816c, 0x00000000 },
+    { 0x00008170, 0x32143320 },
+    { 0x00008174, 0xfaa4fa50 },
+    { 0x00008178, 0x00000100 },
+    { 0x0000817c, 0x00000000 },
+    { 0x000081c0, 0x00000000 },
+    { 0x000081ec, 0x00000000 },
+    { 0x000081f0, 0x00000000 },
+    { 0x000081f4, 0x00000000 },
+    { 0x000081f8, 0x00000000 },
+    { 0x000081fc, 0x00000000 },
+    { 0x00008200, 0x00000000 },
+    { 0x00008204, 0x00000000 },
+    { 0x00008208, 0x00000000 },
+    { 0x0000820c, 0x00000000 },
+    { 0x00008210, 0x00000000 },
+    { 0x00008214, 0x00000000 },
+    { 0x00008218, 0x00000000 },
+    { 0x0000821c, 0x00000000 },
+    { 0x00008220, 0x00000000 },
+    { 0x00008224, 0x00000000 },
+    { 0x00008228, 0x00000000 },
+    { 0x0000822c, 0x00000000 },
+    { 0x00008230, 0x00000000 },
+    { 0x00008234, 0x00000000 },
+    { 0x00008238, 0x00000000 },
+    { 0x0000823c, 0x00000000 },
+    { 0x00008240, 0x00100000 },
+    { 0x00008244, 0x0010f400 },
+    { 0x00008248, 0x00000100 },
+    { 0x0000824c, 0x0001e800 },
+    { 0x00008250, 0x00000000 },
+    { 0x00008254, 0x00000000 },
+    { 0x00008258, 0x00000000 },
+    { 0x0000825c, 0x400000ff },
+    { 0x00008260, 0x00080922 },
+    { 0x00008264, 0xa8a00010 },
+    { 0x00008270, 0x00000000 },
+    { 0x00008274, 0x40000000 },
+    { 0x00008278, 0x003e4180 },
+    { 0x0000827c, 0x00000000 },
+    { 0x00008284, 0x0000002c },
+    { 0x00008288, 0x0000002c },
+    { 0x0000828c, 0x00000000 },
+    { 0x00008294, 0x00000000 },
+    { 0x00008298, 0x00000000 },
+    { 0x0000829c, 0x00000000 },
+    { 0x00008300, 0x00000040 },
+    { 0x00008314, 0x00000000 },
+    { 0x00008328, 0x00000000 },
+    { 0x0000832c, 0x00000007 },
+    { 0x00008330, 0x00000302 },
+    { 0x00008334, 0x00000e00 },
+    { 0x00008338, 0x00ff0000 },
+    { 0x0000833c, 0x00000000 },
+    { 0x00008340, 0x000107ff },
+    { 0x00008344, 0x00581043 },
+    { 0x00009808, 0x00000000 },
+    { 0x0000980c, 0xafa68e30 },
+    { 0x00009810, 0xfd14e000 },
+    { 0x00009814, 0x9c0a9f6b },
+    { 0x0000981c, 0x00000000 },
+    { 0x0000982c, 0x0000a000 },
+    { 0x00009830, 0x00000000 },
+    { 0x0000983c, 0x00200400 },
+    { 0x0000984c, 0x0040233c },
+    { 0x0000a84c, 0x0040233c },
+    { 0x00009854, 0x00000044 },
+    { 0x00009900, 0x00000000 },
+    { 0x00009904, 0x00000000 },
+    { 0x00009908, 0x00000000 },
+    { 0x0000990c, 0x00000000 },
+    { 0x00009910, 0x01002310 },
+    { 0x0000991c, 0x10000fff },
+    { 0x00009920, 0x04900000 },
+    { 0x0000a920, 0x04900000 },
+    { 0x00009928, 0x00000001 },
+    { 0x0000992c, 0x00000004 },
+    { 0x00009934, 0x1e1f2022 },
+    { 0x00009938, 0x0a0b0c0d },
+    { 0x0000993c, 0x00000000 },
+    { 0x00009948, 0x9280c00a },
+    { 0x0000994c, 0x00020028 },
+    { 0x00009954, 0x5f3ca3de },
+    { 0x00009958, 0x2108ecff },
+    { 0x00009940, 0x14750604 },
+    { 0x0000c95c, 0x004b6a8e },
+    { 0x0000c968, 0x000003ce },
+    { 0x00009970, 0x190fb515 },
+    { 0x00009974, 0x00000000 },
+    { 0x00009978, 0x00000001 },
+    { 0x0000997c, 0x00000000 },
+    { 0x00009980, 0x00000000 },
+    { 0x00009984, 0x00000000 },
+    { 0x00009988, 0x00000000 },
+    { 0x0000998c, 0x00000000 },
+    { 0x00009990, 0x00000000 },
+    { 0x00009994, 0x00000000 },
+    { 0x00009998, 0x00000000 },
+    { 0x0000999c, 0x00000000 },
+    { 0x000099a0, 0x00000000 },
+    { 0x000099a4, 0x00000001 },
+    { 0x000099a8, 0x201fff00 },
+    { 0x000099ac, 0x006f0000 },
+    { 0x000099b0, 0x03051000 },
+    { 0x000099b4, 0x00000820 },
+    { 0x000099dc, 0x00000000 },
+    { 0x000099e0, 0x00000000 },
+    { 0x000099e4, 0xaaaaaaaa },
+    { 0x000099e8, 0x3c466478 },
+    { 0x000099ec, 0x0cc80caa },
+    { 0x000099f0, 0x00000000 },
+    { 0x000099fc, 0x00001042 },
+    { 0x0000a208, 0x803e4788 },
+    { 0x0000a210, 0x4080a333 },
+    { 0x0000a214, 0x40206c10 },
+    { 0x0000a218, 0x009c4060 },
+    { 0x0000a220, 0x01834061 },
+    { 0x0000a224, 0x00000400 },
+    { 0x0000a228, 0x000003b5 },
+    { 0x0000a22c, 0x233f7180 },
+    { 0x0000a234, 0x20202020 },
+    { 0x0000a238, 0x20202020 },
+    { 0x0000a23c, 0x13c88000 },
+    { 0x0000a240, 0x38490a20 },
+    { 0x0000a244, 0x00007bb6 },
+    { 0x0000a248, 0x0fff3ffc },
+    { 0x0000a24c, 0x00000000 },
+    { 0x0000a254, 0x00000000 },
+    { 0x0000a258, 0x0cdbd380 },
+    { 0x0000a25c, 0x0f0f0f01 },
+    { 0x0000a260, 0xdfa91f01 },
+    { 0x0000a268, 0x00000000 },
+    { 0x0000a26c, 0x0ebae9c6 },
+    { 0x0000b26c, 0x0ebae9c6 },
+    { 0x0000d270, 0x00820820 },
+    { 0x0000a278, 0x1ce739ce },
+    { 0x0000d35c, 0x07ffffef },
+    { 0x0000d360, 0x0fffffe7 },
+    { 0x0000d364, 0x17ffffe5 },
+    { 0x0000d368, 0x1fffffe4 },
+    { 0x0000d36c, 0x37ffffe3 },
+    { 0x0000d370, 0x3fffffe3 },
+    { 0x0000d374, 0x57ffffe3 },
+    { 0x0000d378, 0x5fffffe2 },
+    { 0x0000d37c, 0x7fffffe2 },
+    { 0x0000d380, 0x7f3c7bba },
+    { 0x0000d384, 0xf3307ff0 },
+    { 0x0000a388, 0x0c000000 },
+    { 0x0000a38c, 0x20202020 },
+    { 0x0000a390, 0x20202020 },
+    { 0x0000a394, 0x1ce739ce },
+    { 0x0000a398, 0x000001ce },
+    { 0x0000a39c, 0x00000001 },
+    { 0x0000a3a0, 0x00000000 },
+    { 0x0000a3a4, 0x00000000 },
+    { 0x0000a3a8, 0x00000000 },
+    { 0x0000a3ac, 0x00000000 },
+    { 0x0000a3b0, 0x00000000 },
+    { 0x0000a3b4, 0x00000000 },
+    { 0x0000a3b8, 0x00000000 },
+    { 0x0000a3bc, 0x00000000 },
+    { 0x0000a3c0, 0x00000000 },
+    { 0x0000a3c4, 0x00000000 },
+    { 0x0000a3c8, 0x00000246 },
+    { 0x0000a3cc, 0x20202020 },
+    { 0x0000a3d0, 0x20202020 },
+    { 0x0000a3d4, 0x20202020 },
+    { 0x0000a3dc, 0x1ce739ce },
+    { 0x0000a3e0, 0x000001ce },
+    { 0x0000a3e4, 0x00000000 },
+    { 0x0000a3e8, 0x18c43433 },
+    { 0x0000a3ec, 0x00f70081 },
+    { 0x00007800, 0x00040000 },
+    { 0x00007804, 0xdb005012 },
+    { 0x00007808, 0x04924914 },
+    { 0x0000780c, 0x21084210 },
+    { 0x00007810, 0x6d801300 },
+    { 0x00007818, 0x07e41000 },
+    { 0x00007824, 0x00040000 },
+    { 0x00007828, 0xdb005012 },
+    { 0x0000782c, 0x04924914 },
+    { 0x00007830, 0x21084210 },
+    { 0x00007834, 0x6d801300 },
+    { 0x0000783c, 0x07e40000 },
+    { 0x00007848, 0x00100000 },
+    { 0x0000784c, 0x773f0567 },
+    { 0x00007850, 0x54214514 },
+    { 0x00007854, 0x12035828 },
+    { 0x00007858, 0x9259269a },
+    { 0x00007860, 0x52802000 },
+    { 0x00007864, 0x0a8e370e },
+    { 0x00007868, 0xc0102850 },
+    { 0x0000786c, 0x812d4000 },
+    { 0x00007870, 0x807ec400 },
+    { 0x00007874, 0x001b6db0 },
+    { 0x00007878, 0x00376b63 },
+    { 0x0000787c, 0x06db6db6 },
+    { 0x00007880, 0x006d8000 },
+    { 0x00007884, 0xffeffffe },
+    { 0x00007888, 0xffeffffe },
+    { 0x0000788c, 0x00010000 },
+    { 0x00007890, 0x02060aeb },
+    { 0x00007898, 0x2a850160 },
+};
+
+static const u32 ar9280Modes_fast_clock_9280_2[][3] = {
+    { 0x00001030, 0x00000268, 0x000004d0 },
+    { 0x00001070, 0x0000018c, 0x00000318 },
+    { 0x000010b0, 0x00000fd0, 0x00001fa0 },
+    { 0x00008014, 0x044c044c, 0x08980898 },
+    { 0x0000801c, 0x148ec02b, 0x148ec057 },
+    { 0x00008318, 0x000044c0, 0x00008980 },
+    { 0x00009820, 0x02020200, 0x02020200 },
+    { 0x00009824, 0x00000f0f, 0x00000f0f },
+    { 0x00009828, 0x0b020001, 0x0b020001 },
+    { 0x00009834, 0x00000f0f, 0x00000f0f },
+    { 0x00009844, 0x03721821, 0x03721821 },
+    { 0x00009914, 0x00000898, 0x00001130 },
+    { 0x00009918, 0x0000000b, 0x00000016 },
+};
+
+static const u32 ar9280Modes_backoff_23db_rxgain_9280_2[][6] = {
+    { 0x00009a00, 0x00008184, 0x00008184, 0x00000290, 0x00000290, 0x00000290 },
+    { 0x00009a04, 0x00008188, 0x00008188, 0x00000300, 0x00000300, 0x00000300 },
+    { 0x00009a08, 0x0000818c, 0x0000818c, 0x00000304, 0x00000304, 0x00000304 },
+    { 0x00009a0c, 0x00008190, 0x00008190, 0x00000308, 0x00000308, 0x00000308 },
+    { 0x00009a10, 0x00008194, 0x00008194, 0x0000030c, 0x0000030c, 0x0000030c },
+    { 0x00009a14, 0x00008200, 0x00008200, 0x00008000, 0x00008000, 0x00008000 },
+    { 0x00009a18, 0x00008204, 0x00008204, 0x00008004, 0x00008004, 0x00008004 },
+    { 0x00009a1c, 0x00008208, 0x00008208, 0x00008008, 0x00008008, 0x00008008 },
+    { 0x00009a20, 0x0000820c, 0x0000820c, 0x0000800c, 0x0000800c, 0x0000800c },
+    { 0x00009a24, 0x00008210, 0x00008210, 0x00008080, 0x00008080, 0x00008080 },
+    { 0x00009a28, 0x00008214, 0x00008214, 0x00008084, 0x00008084, 0x00008084 },
+    { 0x00009a2c, 0x00008280, 0x00008280, 0x00008088, 0x00008088, 0x00008088 },
+    { 0x00009a30, 0x00008284, 0x00008284, 0x0000808c, 0x0000808c, 0x0000808c },
+    { 0x00009a34, 0x00008288, 0x00008288, 0x00008100, 0x00008100, 0x00008100 },
+    { 0x00009a38, 0x0000828c, 0x0000828c, 0x00008104, 0x00008104, 0x00008104 },
+    { 0x00009a3c, 0x00008290, 0x00008290, 0x00008108, 0x00008108, 0x00008108 },
+    { 0x00009a40, 0x00008300, 0x00008300, 0x0000810c, 0x0000810c, 0x0000810c },
+    { 0x00009a44, 0x00008304, 0x00008304, 0x00008110, 0x00008110, 0x00008110 },
+    { 0x00009a48, 0x00008308, 0x00008308, 0x00008114, 0x00008114, 0x00008114 },
+    { 0x00009a4c, 0x0000830c, 0x0000830c, 0x00008180, 0x00008180, 0x00008180 },
+    { 0x00009a50, 0x00008310, 0x00008310, 0x00008184, 0x00008184, 0x00008184 },
+    { 0x00009a54, 0x00008314, 0x00008314, 0x00008188, 0x00008188, 0x00008188 },
+    { 0x00009a58, 0x00008380, 0x00008380, 0x0000818c, 0x0000818c, 0x0000818c },
+    { 0x00009a5c, 0x00008384, 0x00008384, 0x00008190, 0x00008190, 0x00008190 },
+    { 0x00009a60, 0x00008388, 0x00008388, 0x00008194, 0x00008194, 0x00008194 },
+    { 0x00009a64, 0x0000838c, 0x0000838c, 0x000081a0, 0x000081a0, 0x000081a0 },
+    { 0x00009a68, 0x00008390, 0x00008390, 0x0000820c, 0x0000820c, 0x0000820c },
+    { 0x00009a6c, 0x00008394, 0x00008394, 0x000081a8, 0x000081a8, 0x000081a8 },
+    { 0x00009a70, 0x0000a380, 0x0000a380, 0x00008284, 0x00008284, 0x00008284 },
+    { 0x00009a74, 0x0000a384, 0x0000a384, 0x00008288, 0x00008288, 0x00008288 },
+    { 0x00009a78, 0x0000a388, 0x0000a388, 0x00008224, 0x00008224, 0x00008224 },
+    { 0x00009a7c, 0x0000a38c, 0x0000a38c, 0x00008290, 0x00008290, 0x00008290 },
+    { 0x00009a80, 0x0000a390, 0x0000a390, 0x00008300, 0x00008300, 0x00008300 },
+    { 0x00009a84, 0x0000a394, 0x0000a394, 0x00008304, 0x00008304, 0x00008304 },
+    { 0x00009a88, 0x0000a780, 0x0000a780, 0x00008308, 0x00008308, 0x00008308 },
+    { 0x00009a8c, 0x0000a784, 0x0000a784, 0x0000830c, 0x0000830c, 0x0000830c },
+    { 0x00009a90, 0x0000a788, 0x0000a788, 0x00008380, 0x00008380, 0x00008380 },
+    { 0x00009a94, 0x0000a78c, 0x0000a78c, 0x00008384, 0x00008384, 0x00008384 },
+    { 0x00009a98, 0x0000a790, 0x0000a790, 0x00008700, 0x00008700, 0x00008700 },
+    { 0x00009a9c, 0x0000a794, 0x0000a794, 0x00008704, 0x00008704, 0x00008704 },
+    { 0x00009aa0, 0x0000ab84, 0x0000ab84, 0x00008708, 0x00008708, 0x00008708 },
+    { 0x00009aa4, 0x0000ab88, 0x0000ab88, 0x0000870c, 0x0000870c, 0x0000870c },
+    { 0x00009aa8, 0x0000ab8c, 0x0000ab8c, 0x00008780, 0x00008780, 0x00008780 },
+    { 0x00009aac, 0x0000ab90, 0x0000ab90, 0x00008784, 0x00008784, 0x00008784 },
+    { 0x00009ab0, 0x0000ab94, 0x0000ab94, 0x00008b00, 0x00008b00, 0x00008b00 },
+    { 0x00009ab4, 0x0000af80, 0x0000af80, 0x00008b04, 0x00008b04, 0x00008b04 },
+    { 0x00009ab8, 0x0000af84, 0x0000af84, 0x00008b08, 0x00008b08, 0x00008b08 },
+    { 0x00009abc, 0x0000af88, 0x0000af88, 0x00008b0c, 0x00008b0c, 0x00008b0c },
+    { 0x00009ac0, 0x0000af8c, 0x0000af8c, 0x00008b10, 0x00008b10, 0x00008b10 },
+    { 0x00009ac4, 0x0000af90, 0x0000af90, 0x00008b14, 0x00008b14, 0x00008b14 },
+    { 0x00009ac8, 0x0000af94, 0x0000af94, 0x00008b01, 0x00008b01, 0x00008b01 },
+    { 0x00009acc, 0x0000b380, 0x0000b380, 0x00008b05, 0x00008b05, 0x00008b05 },
+    { 0x00009ad0, 0x0000b384, 0x0000b384, 0x00008b09, 0x00008b09, 0x00008b09 },
+    { 0x00009ad4, 0x0000b388, 0x0000b388, 0x00008b0d, 0x00008b0d, 0x00008b0d },
+    { 0x00009ad8, 0x0000b38c, 0x0000b38c, 0x00008b11, 0x00008b11, 0x00008b11 },
+    { 0x00009adc, 0x0000b390, 0x0000b390, 0x00008b15, 0x00008b15, 0x00008b15 },
+    { 0x00009ae0, 0x0000b394, 0x0000b394, 0x00008b02, 0x00008b02, 0x00008b02 },
+    { 0x00009ae4, 0x0000b398, 0x0000b398, 0x00008b06, 0x00008b06, 0x00008b06 },
+    { 0x00009ae8, 0x0000b780, 0x0000b780, 0x00008b0a, 0x00008b0a, 0x00008b0a },
+    { 0x00009aec, 0x0000b784, 0x0000b784, 0x00008b0e, 0x00008b0e, 0x00008b0e },
+    { 0x00009af0, 0x0000b788, 0x0000b788, 0x00008b12, 0x00008b12, 0x00008b12 },
+    { 0x00009af4, 0x0000b78c, 0x0000b78c, 0x00008b16, 0x00008b16, 0x00008b16 },
+    { 0x00009af8, 0x0000b790, 0x0000b790, 0x00008b03, 0x00008b03, 0x00008b03 },
+    { 0x00009afc, 0x0000b794, 0x0000b794, 0x00008b07, 0x00008b07, 0x00008b07 },
+    { 0x00009b00, 0x0000b798, 0x0000b798, 0x00008b0b, 0x00008b0b, 0x00008b0b },
+    { 0x00009b04, 0x0000d784, 0x0000d784, 0x00008b0f, 0x00008b0f, 0x00008b0f },
+    { 0x00009b08, 0x0000d788, 0x0000d788, 0x00008b13, 0x00008b13, 0x00008b13 },
+    { 0x00009b0c, 0x0000d78c, 0x0000d78c, 0x00008b17, 0x00008b17, 0x00008b17 },
+    { 0x00009b10, 0x0000d790, 0x0000d790, 0x00008b23, 0x00008b23, 0x00008b23 },
+    { 0x00009b14, 0x0000f780, 0x0000f780, 0x00008b27, 0x00008b27, 0x00008b27 },
+    { 0x00009b18, 0x0000f784, 0x0000f784, 0x00008b2b, 0x00008b2b, 0x00008b2b },
+    { 0x00009b1c, 0x0000f788, 0x0000f788, 0x00008b2f, 0x00008b2f, 0x00008b2f },
+    { 0x00009b20, 0x0000f78c, 0x0000f78c, 0x00008b33, 0x00008b33, 0x00008b33 },
+    { 0x00009b24, 0x0000f790, 0x0000f790, 0x00008b37, 0x00008b37, 0x00008b37 },
+    { 0x00009b28, 0x0000f794, 0x0000f794, 0x00008b43, 0x00008b43, 0x00008b43 },
+    { 0x00009b2c, 0x0000f7a4, 0x0000f7a4, 0x00008b47, 0x00008b47, 0x00008b47 },
+    { 0x00009b30, 0x0000f7a8, 0x0000f7a8, 0x00008b4b, 0x00008b4b, 0x00008b4b },
+    { 0x00009b34, 0x0000f7ac, 0x0000f7ac, 0x00008b4f, 0x00008b4f, 0x00008b4f },
+    { 0x00009b38, 0x0000f7b0, 0x0000f7b0, 0x00008b53, 0x00008b53, 0x00008b53 },
+    { 0x00009b3c, 0x0000f7b4, 0x0000f7b4, 0x00008b57, 0x00008b57, 0x00008b57 },
+    { 0x00009b40, 0x0000f7a1, 0x0000f7a1, 0x00008b5b, 0x00008b5b, 0x00008b5b },
+    { 0x00009b44, 0x0000f7a5, 0x0000f7a5, 0x00008b5b, 0x00008b5b, 0x00008b5b },
+    { 0x00009b48, 0x0000f7a9, 0x0000f7a9, 0x00008b5b, 0x00008b5b, 0x00008b5b },
+    { 0x00009b4c, 0x0000f7ad, 0x0000f7ad, 0x00008b5b, 0x00008b5b, 0x00008b5b },
+    { 0x00009b50, 0x0000f7b1, 0x0000f7b1, 0x00008b5b, 0x00008b5b, 0x00008b5b },
+    { 0x00009b54, 0x0000f7b5, 0x0000f7b5, 0x00008b5b, 0x00008b5b, 0x00008b5b },
+    { 0x00009b58, 0x0000f7c5, 0x0000f7c5, 0x00008b5b, 0x00008b5b, 0x00008b5b },
+    { 0x00009b5c, 0x0000f7c9, 0x0000f7c9, 0x00008b5b, 0x00008b5b, 0x00008b5b },
+    { 0x00009b60, 0x0000f7cd, 0x0000f7cd, 0x00008b5b, 0x00008b5b, 0x00008b5b },
+    { 0x00009b64, 0x0000f7d1, 0x0000f7d1, 0x00008b5b, 0x00008b5b, 0x00008b5b },
+    { 0x00009b68, 0x0000f7d5, 0x0000f7d5, 0x00008b5b, 0x00008b5b, 0x00008b5b },
+    { 0x00009b6c, 0x0000f7c2, 0x0000f7c2, 0x00008b5b, 0x00008b5b, 0x00008b5b },
+    { 0x00009b70, 0x0000f7c6, 0x0000f7c6, 0x00008b5b, 0x00008b5b, 0x00008b5b },
+    { 0x00009b74, 0x0000f7ca, 0x0000f7ca, 0x00008b5b, 0x00008b5b, 0x00008b5b },
+    { 0x00009b78, 0x0000f7ce, 0x0000f7ce, 0x00008b5b, 0x00008b5b, 0x00008b5b },
+    { 0x00009b7c, 0x0000f7d2, 0x0000f7d2, 0x00008b5b, 0x00008b5b, 0x00008b5b },
+    { 0x00009b80, 0x0000f7d6, 0x0000f7d6, 0x00008b5b, 0x00008b5b, 0x00008b5b },
+    { 0x00009b84, 0x0000f7c3, 0x0000f7c3, 0x00008b5b, 0x00008b5b, 0x00008b5b },
+    { 0x00009b88, 0x0000f7c7, 0x0000f7c7, 0x00008b5b, 0x00008b5b, 0x00008b5b },
+    { 0x00009b8c, 0x0000f7cb, 0x0000f7cb, 0x00008b5b, 0x00008b5b, 0x00008b5b },
+    { 0x00009b90, 0x0000f7d3, 0x0000f7d3, 0x00008b5b, 0x00008b5b, 0x00008b5b },
+    { 0x00009b94, 0x0000f7d7, 0x0000f7d7, 0x00008b5b, 0x00008b5b, 0x00008b5b },
+    { 0x00009b98, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b },
+    { 0x00009b9c, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b },
+    { 0x00009ba0, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b },
+    { 0x00009ba4, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b },
+    { 0x00009ba8, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b },
+    { 0x00009bac, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b },
+    { 0x00009bb0, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b },
+    { 0x00009bb4, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b },
+    { 0x00009bb8, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b },
+    { 0x00009bbc, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b },
+    { 0x00009bc0, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b },
+    { 0x00009bc4, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b },
+    { 0x00009bc8, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b },
+    { 0x00009bcc, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b },
+    { 0x00009bd0, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b },
+    { 0x00009bd4, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b },
+    { 0x00009bd8, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b },
+    { 0x00009bdc, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b },
+    { 0x00009be0, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b },
+    { 0x00009be4, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b },
+    { 0x00009be8, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b },
+    { 0x00009bec, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b },
+    { 0x00009bf0, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b },
+    { 0x00009bf4, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b },
+    { 0x00009bf8, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b },
+    { 0x00009bfc, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b },
+    { 0x00009848, 0x00001066, 0x00001066, 0x00001050, 0x00001050, 0x00001050 },
+    { 0x0000a848, 0x00001066, 0x00001066, 0x00001050, 0x00001050, 0x00001050 },
+};
+
+static const u32 ar9280Modes_original_rxgain_9280_2[][6] = {
+    { 0x00009a00, 0x00008184, 0x00008184, 0x00000290, 0x00000290, 0x00000290 },
+    { 0x00009a04, 0x00008188, 0x00008188, 0x00000300, 0x00000300, 0x00000300 },
+    { 0x00009a08, 0x0000818c, 0x0000818c, 0x00000304, 0x00000304, 0x00000304 },
+    { 0x00009a0c, 0x00008190, 0x00008190, 0x00000308, 0x00000308, 0x00000308 },
+    { 0x00009a10, 0x00008194, 0x00008194, 0x0000030c, 0x0000030c, 0x0000030c },
+    { 0x00009a14, 0x00008200, 0x00008200, 0x00008000, 0x00008000, 0x00008000 },
+    { 0x00009a18, 0x00008204, 0x00008204, 0x00008004, 0x00008004, 0x00008004 },
+    { 0x00009a1c, 0x00008208, 0x00008208, 0x00008008, 0x00008008, 0x00008008 },
+    { 0x00009a20, 0x0000820c, 0x0000820c, 0x0000800c, 0x0000800c, 0x0000800c },
+    { 0x00009a24, 0x00008210, 0x00008210, 0x00008080, 0x00008080, 0x00008080 },
+    { 0x00009a28, 0x00008214, 0x00008214, 0x00008084, 0x00008084, 0x00008084 },
+    { 0x00009a2c, 0x00008280, 0x00008280, 0x00008088, 0x00008088, 0x00008088 },
+    { 0x00009a30, 0x00008284, 0x00008284, 0x0000808c, 0x0000808c, 0x0000808c },
+    { 0x00009a34, 0x00008288, 0x00008288, 0x00008100, 0x00008100, 0x00008100 },
+    { 0x00009a38, 0x0000828c, 0x0000828c, 0x00008104, 0x00008104, 0x00008104 },
+    { 0x00009a3c, 0x00008290, 0x00008290, 0x00008108, 0x00008108, 0x00008108 },
+    { 0x00009a40, 0x00008300, 0x00008300, 0x0000810c, 0x0000810c, 0x0000810c },
+    { 0x00009a44, 0x00008304, 0x00008304, 0x00008110, 0x00008110, 0x00008110 },
+    { 0x00009a48, 0x00008308, 0x00008308, 0x00008114, 0x00008114, 0x00008114 },
+    { 0x00009a4c, 0x0000830c, 0x0000830c, 0x00008180, 0x00008180, 0x00008180 },
+    { 0x00009a50, 0x00008310, 0x00008310, 0x00008184, 0x00008184, 0x00008184 },
+    { 0x00009a54, 0x00008314, 0x00008314, 0x00008188, 0x00008188, 0x00008188 },
+    { 0x00009a58, 0x00008380, 0x00008380, 0x0000818c, 0x0000818c, 0x0000818c },
+    { 0x00009a5c, 0x00008384, 0x00008384, 0x00008190, 0x00008190, 0x00008190 },
+    { 0x00009a60, 0x00008388, 0x00008388, 0x00008194, 0x00008194, 0x00008194 },
+    { 0x00009a64, 0x0000838c, 0x0000838c, 0x000081a0, 0x000081a0, 0x000081a0 },
+    { 0x00009a68, 0x00008390, 0x00008390, 0x0000820c, 0x0000820c, 0x0000820c },
+    { 0x00009a6c, 0x00008394, 0x00008394, 0x000081a8, 0x000081a8, 0x000081a8 },
+    { 0x00009a70, 0x0000a380, 0x0000a380, 0x00008284, 0x00008284, 0x00008284 },
+    { 0x00009a74, 0x0000a384, 0x0000a384, 0x00008288, 0x00008288, 0x00008288 },
+    { 0x00009a78, 0x0000a388, 0x0000a388, 0x00008224, 0x00008224, 0x00008224 },
+    { 0x00009a7c, 0x0000a38c, 0x0000a38c, 0x00008290, 0x00008290, 0x00008290 },
+    { 0x00009a80, 0x0000a390, 0x0000a390, 0x00008300, 0x00008300, 0x00008300 },
+    { 0x00009a84, 0x0000a394, 0x0000a394, 0x00008304, 0x00008304, 0x00008304 },
+    { 0x00009a88, 0x0000a780, 0x0000a780, 0x00008308, 0x00008308, 0x00008308 },
+    { 0x00009a8c, 0x0000a784, 0x0000a784, 0x0000830c, 0x0000830c, 0x0000830c },
+    { 0x00009a90, 0x0000a788, 0x0000a788, 0x00008380, 0x00008380, 0x00008380 },
+    { 0x00009a94, 0x0000a78c, 0x0000a78c, 0x00008384, 0x00008384, 0x00008384 },
+    { 0x00009a98, 0x0000a790, 0x0000a790, 0x00008700, 0x00008700, 0x00008700 },
+    { 0x00009a9c, 0x0000a794, 0x0000a794, 0x00008704, 0x00008704, 0x00008704 },
+    { 0x00009aa0, 0x0000ab84, 0x0000ab84, 0x00008708, 0x00008708, 0x00008708 },
+    { 0x00009aa4, 0x0000ab88, 0x0000ab88, 0x0000870c, 0x0000870c, 0x0000870c },
+    { 0x00009aa8, 0x0000ab8c, 0x0000ab8c, 0x00008780, 0x00008780, 0x00008780 },
+    { 0x00009aac, 0x0000ab90, 0x0000ab90, 0x00008784, 0x00008784, 0x00008784 },
+    { 0x00009ab0, 0x0000ab94, 0x0000ab94, 0x00008b00, 0x00008b00, 0x00008b00 },
+    { 0x00009ab4, 0x0000af80, 0x0000af80, 0x00008b04, 0x00008b04, 0x00008b04 },
+    { 0x00009ab8, 0x0000af84, 0x0000af84, 0x00008b08, 0x00008b08, 0x00008b08 },
+    { 0x00009abc, 0x0000af88, 0x0000af88, 0x00008b0c, 0x00008b0c, 0x00008b0c },
+    { 0x00009ac0, 0x0000af8c, 0x0000af8c, 0x00008b80, 0x00008b80, 0x00008b80 },
+    { 0x00009ac4, 0x0000af90, 0x0000af90, 0x00008b84, 0x00008b84, 0x00008b84 },
+    { 0x00009ac8, 0x0000af94, 0x0000af94, 0x00008b88, 0x00008b88, 0x00008b88 },
+    { 0x00009acc, 0x0000b380, 0x0000b380, 0x00008b8c, 0x00008b8c, 0x00008b8c },
+    { 0x00009ad0, 0x0000b384, 0x0000b384, 0x00008b90, 0x00008b90, 0x00008b90 },
+    { 0x00009ad4, 0x0000b388, 0x0000b388, 0x00008f80, 0x00008f80, 0x00008f80 },
+    { 0x00009ad8, 0x0000b38c, 0x0000b38c, 0x00008f84, 0x00008f84, 0x00008f84 },
+    { 0x00009adc, 0x0000b390, 0x0000b390, 0x00008f88, 0x00008f88, 0x00008f88 },
+    { 0x00009ae0, 0x0000b394, 0x0000b394, 0x00008f8c, 0x00008f8c, 0x00008f8c },
+    { 0x00009ae4, 0x0000b398, 0x0000b398, 0x00008f90, 0x00008f90, 0x00008f90 },
+    { 0x00009ae8, 0x0000b780, 0x0000b780, 0x0000930c, 0x0000930c, 0x0000930c },
+    { 0x00009aec, 0x0000b784, 0x0000b784, 0x00009310, 0x00009310, 0x00009310 },
+    { 0x00009af0, 0x0000b788, 0x0000b788, 0x00009384, 0x00009384, 0x00009384 },
+    { 0x00009af4, 0x0000b78c, 0x0000b78c, 0x00009388, 0x00009388, 0x00009388 },
+    { 0x00009af8, 0x0000b790, 0x0000b790, 0x00009324, 0x00009324, 0x00009324 },
+    { 0x00009afc, 0x0000b794, 0x0000b794, 0x00009704, 0x00009704, 0x00009704 },
+    { 0x00009b00, 0x0000b798, 0x0000b798, 0x000096a4, 0x000096a4, 0x000096a4 },
+    { 0x00009b04, 0x0000d784, 0x0000d784, 0x000096a8, 0x000096a8, 0x000096a8 },
+    { 0x00009b08, 0x0000d788, 0x0000d788, 0x00009710, 0x00009710, 0x00009710 },
+    { 0x00009b0c, 0x0000d78c, 0x0000d78c, 0x00009714, 0x00009714, 0x00009714 },
+    { 0x00009b10, 0x0000d790, 0x0000d790, 0x00009720, 0x00009720, 0x00009720 },
+    { 0x00009b14, 0x0000f780, 0x0000f780, 0x00009724, 0x00009724, 0x00009724 },
+    { 0x00009b18, 0x0000f784, 0x0000f784, 0x00009728, 0x00009728, 0x00009728 },
+    { 0x00009b1c, 0x0000f788, 0x0000f788, 0x0000972c, 0x0000972c, 0x0000972c },
+    { 0x00009b20, 0x0000f78c, 0x0000f78c, 0x000097a0, 0x000097a0, 0x000097a0 },
+    { 0x00009b24, 0x0000f790, 0x0000f790, 0x000097a4, 0x000097a4, 0x000097a4 },
+    { 0x00009b28, 0x0000f794, 0x0000f794, 0x000097a8, 0x000097a8, 0x000097a8 },
+    { 0x00009b2c, 0x0000f7a4, 0x0000f7a4, 0x000097b0, 0x000097b0, 0x000097b0 },
+    { 0x00009b30, 0x0000f7a8, 0x0000f7a8, 0x000097b4, 0x000097b4, 0x000097b4 },
+    { 0x00009b34, 0x0000f7ac, 0x0000f7ac, 0x000097b8, 0x000097b8, 0x000097b8 },
+    { 0x00009b38, 0x0000f7b0, 0x0000f7b0, 0x000097a5, 0x000097a5, 0x000097a5 },
+    { 0x00009b3c, 0x0000f7b4, 0x0000f7b4, 0x000097a9, 0x000097a9, 0x000097a9 },
+    { 0x00009b40, 0x0000f7a1, 0x0000f7a1, 0x000097ad, 0x000097ad, 0x000097ad },
+    { 0x00009b44, 0x0000f7a5, 0x0000f7a5, 0x000097b1, 0x000097b1, 0x000097b1 },
+    { 0x00009b48, 0x0000f7a9, 0x0000f7a9, 0x000097b5, 0x000097b5, 0x000097b5 },
+    { 0x00009b4c, 0x0000f7ad, 0x0000f7ad, 0x000097b9, 0x000097b9, 0x000097b9 },
+    { 0x00009b50, 0x0000f7b1, 0x0000f7b1, 0x000097c5, 0x000097c5, 0x000097c5 },
+    { 0x00009b54, 0x0000f7b5, 0x0000f7b5, 0x000097c9, 0x000097c9, 0x000097c9 },
+    { 0x00009b58, 0x0000f7c5, 0x0000f7c5, 0x000097d1, 0x000097d1, 0x000097d1 },
+    { 0x00009b5c, 0x0000f7c9, 0x0000f7c9, 0x000097d5, 0x000097d5, 0x000097d5 },
+    { 0x00009b60, 0x0000f7cd, 0x0000f7cd, 0x000097d9, 0x000097d9, 0x000097d9 },
+    { 0x00009b64, 0x0000f7d1, 0x0000f7d1, 0x000097c6, 0x000097c6, 0x000097c6 },
+    { 0x00009b68, 0x0000f7d5, 0x0000f7d5, 0x000097ca, 0x000097ca, 0x000097ca },
+    { 0x00009b6c, 0x0000f7c2, 0x0000f7c2, 0x000097ce, 0x000097ce, 0x000097ce },
+    { 0x00009b70, 0x0000f7c6, 0x0000f7c6, 0x000097d2, 0x000097d2, 0x000097d2 },
+    { 0x00009b74, 0x0000f7ca, 0x0000f7ca, 0x000097d6, 0x000097d6, 0x000097d6 },
+    { 0x00009b78, 0x0000f7ce, 0x0000f7ce, 0x000097c3, 0x000097c3, 0x000097c3 },
+    { 0x00009b7c, 0x0000f7d2, 0x0000f7d2, 0x000097c7, 0x000097c7, 0x000097c7 },
+    { 0x00009b80, 0x0000f7d6, 0x0000f7d6, 0x000097cb, 0x000097cb, 0x000097cb },
+    { 0x00009b84, 0x0000f7c3, 0x0000f7c3, 0x000097cf, 0x000097cf, 0x000097cf },
+    { 0x00009b88, 0x0000f7c7, 0x0000f7c7, 0x000097d7, 0x000097d7, 0x000097d7 },
+    { 0x00009b8c, 0x0000f7cb, 0x0000f7cb, 0x000097db, 0x000097db, 0x000097db },
+    { 0x00009b90, 0x0000f7d3, 0x0000f7d3, 0x000097db, 0x000097db, 0x000097db },
+    { 0x00009b94, 0x0000f7d7, 0x0000f7d7, 0x000097db, 0x000097db, 0x000097db },
+    { 0x00009b98, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
+    { 0x00009b9c, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
+    { 0x00009ba0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
+    { 0x00009ba4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
+    { 0x00009ba8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
+    { 0x00009bac, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
+    { 0x00009bb0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
+    { 0x00009bb4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
+    { 0x00009bb8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
+    { 0x00009bbc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
+    { 0x00009bc0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
+    { 0x00009bc4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
+    { 0x00009bc8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
+    { 0x00009bcc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
+    { 0x00009bd0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
+    { 0x00009bd4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
+    { 0x00009bd8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
+    { 0x00009bdc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
+    { 0x00009be0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
+    { 0x00009be4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
+    { 0x00009be8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
+    { 0x00009bec, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
+    { 0x00009bf0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
+    { 0x00009bf4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
+    { 0x00009bf8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
+    { 0x00009bfc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
+    { 0x00009848, 0x00001066, 0x00001066, 0x00001063, 0x00001063, 0x00001063 },
+    { 0x0000a848, 0x00001066, 0x00001066, 0x00001063, 0x00001063, 0x00001063 },
+};
+
+static const u32 ar9280Modes_backoff_13db_rxgain_9280_2[][6] = {
+    { 0x00009a00, 0x00008184, 0x00008184, 0x00000290, 0x00000290, 0x00000290 },
+    { 0x00009a04, 0x00008188, 0x00008188, 0x00000300, 0x00000300, 0x00000300 },
+    { 0x00009a08, 0x0000818c, 0x0000818c, 0x00000304, 0x00000304, 0x00000304 },
+    { 0x00009a0c, 0x00008190, 0x00008190, 0x00000308, 0x00000308, 0x00000308 },
+    { 0x00009a10, 0x00008194, 0x00008194, 0x0000030c, 0x0000030c, 0x0000030c },
+    { 0x00009a14, 0x00008200, 0x00008200, 0x00008000, 0x00008000, 0x00008000 },
+    { 0x00009a18, 0x00008204, 0x00008204, 0x00008004, 0x00008004, 0x00008004 },
+    { 0x00009a1c, 0x00008208, 0x00008208, 0x00008008, 0x00008008, 0x00008008 },
+    { 0x00009a20, 0x0000820c, 0x0000820c, 0x0000800c, 0x0000800c, 0x0000800c },
+    { 0x00009a24, 0x00008210, 0x00008210, 0x00008080, 0x00008080, 0x00008080 },
+    { 0x00009a28, 0x00008214, 0x00008214, 0x00008084, 0x00008084, 0x00008084 },
+    { 0x00009a2c, 0x00008280, 0x00008280, 0x00008088, 0x00008088, 0x00008088 },
+    { 0x00009a30, 0x00008284, 0x00008284, 0x0000808c, 0x0000808c, 0x0000808c },
+    { 0x00009a34, 0x00008288, 0x00008288, 0x00008100, 0x00008100, 0x00008100 },
+    { 0x00009a38, 0x0000828c, 0x0000828c, 0x00008104, 0x00008104, 0x00008104 },
+    { 0x00009a3c, 0x00008290, 0x00008290, 0x00008108, 0x00008108, 0x00008108 },
+    { 0x00009a40, 0x00008300, 0x00008300, 0x0000810c, 0x0000810c, 0x0000810c },
+    { 0x00009a44, 0x00008304, 0x00008304, 0x00008110, 0x00008110, 0x00008110 },
+    { 0x00009a48, 0x00008308, 0x00008308, 0x00008114, 0x00008114, 0x00008114 },
+    { 0x00009a4c, 0x0000830c, 0x0000830c, 0x00008180, 0x00008180, 0x00008180 },
+    { 0x00009a50, 0x00008310, 0x00008310, 0x00008184, 0x00008184, 0x00008184 },
+    { 0x00009a54, 0x00008314, 0x00008314, 0x00008188, 0x00008188, 0x00008188 },
+    { 0x00009a58, 0x00008380, 0x00008380, 0x0000818c, 0x0000818c, 0x0000818c },
+    { 0x00009a5c, 0x00008384, 0x00008384, 0x00008190, 0x00008190, 0x00008190 },
+    { 0x00009a60, 0x00008388, 0x00008388, 0x00008194, 0x00008194, 0x00008194 },
+    { 0x00009a64, 0x0000838c, 0x0000838c, 0x000081a0, 0x000081a0, 0x000081a0 },
+    { 0x00009a68, 0x00008390, 0x00008390, 0x0000820c, 0x0000820c, 0x0000820c },
+    { 0x00009a6c, 0x00008394, 0x00008394, 0x000081a8, 0x000081a8, 0x000081a8 },
+    { 0x00009a70, 0x0000a380, 0x0000a380, 0x00008284, 0x00008284, 0x00008284 },
+    { 0x00009a74, 0x0000a384, 0x0000a384, 0x00008288, 0x00008288, 0x00008288 },
+    { 0x00009a78, 0x0000a388, 0x0000a388, 0x00008224, 0x00008224, 0x00008224 },
+    { 0x00009a7c, 0x0000a38c, 0x0000a38c, 0x00008290, 0x00008290, 0x00008290 },
+    { 0x00009a80, 0x0000a390, 0x0000a390, 0x00008300, 0x00008300, 0x00008300 },
+    { 0x00009a84, 0x0000a394, 0x0000a394, 0x00008304, 0x00008304, 0x00008304 },
+    { 0x00009a88, 0x0000a780, 0x0000a780, 0x00008308, 0x00008308, 0x00008308 },
+    { 0x00009a8c, 0x0000a784, 0x0000a784, 0x0000830c, 0x0000830c, 0x0000830c },
+    { 0x00009a90, 0x0000a788, 0x0000a788, 0x00008380, 0x00008380, 0x00008380 },
+    { 0x00009a94, 0x0000a78c, 0x0000a78c, 0x00008384, 0x00008384, 0x00008384 },
+    { 0x00009a98, 0x0000a790, 0x0000a790, 0x00008700, 0x00008700, 0x00008700 },
+    { 0x00009a9c, 0x0000a794, 0x0000a794, 0x00008704, 0x00008704, 0x00008704 },
+    { 0x00009aa0, 0x0000ab84, 0x0000ab84, 0x00008708, 0x00008708, 0x00008708 },
+    { 0x00009aa4, 0x0000ab88, 0x0000ab88, 0x0000870c, 0x0000870c, 0x0000870c },
+    { 0x00009aa8, 0x0000ab8c, 0x0000ab8c, 0x00008780, 0x00008780, 0x00008780 },
+    { 0x00009aac, 0x0000ab90, 0x0000ab90, 0x00008784, 0x00008784, 0x00008784 },
+    { 0x00009ab0, 0x0000ab94, 0x0000ab94, 0x00008b00, 0x00008b00, 0x00008b00 },
+    { 0x00009ab4, 0x0000af80, 0x0000af80, 0x00008b04, 0x00008b04, 0x00008b04 },
+    { 0x00009ab8, 0x0000af84, 0x0000af84, 0x00008b08, 0x00008b08, 0x00008b08 },
+    { 0x00009abc, 0x0000af88, 0x0000af88, 0x00008b0c, 0x00008b0c, 0x00008b0c },
+    { 0x00009ac0, 0x0000af8c, 0x0000af8c, 0x00008b80, 0x00008b80, 0x00008b80 },
+    { 0x00009ac4, 0x0000af90, 0x0000af90, 0x00008b84, 0x00008b84, 0x00008b84 },
+    { 0x00009ac8, 0x0000af94, 0x0000af94, 0x00008b88, 0x00008b88, 0x00008b88 },
+    { 0x00009acc, 0x0000b380, 0x0000b380, 0x00008b8c, 0x00008b8c, 0x00008b8c },
+    { 0x00009ad0, 0x0000b384, 0x0000b384, 0x00008b90, 0x00008b90, 0x00008b90 },
+    { 0x00009ad4, 0x0000b388, 0x0000b388, 0x00008f80, 0x00008f80, 0x00008f80 },
+    { 0x00009ad8, 0x0000b38c, 0x0000b38c, 0x00008f84, 0x00008f84, 0x00008f84 },
+    { 0x00009adc, 0x0000b390, 0x0000b390, 0x00008f88, 0x00008f88, 0x00008f88 },
+    { 0x00009ae0, 0x0000b394, 0x0000b394, 0x00008f8c, 0x00008f8c, 0x00008f8c },
+    { 0x00009ae4, 0x0000b398, 0x0000b398, 0x00008f90, 0x00008f90, 0x00008f90 },
+    { 0x00009ae8, 0x0000b780, 0x0000b780, 0x00009310, 0x00009310, 0x00009310 },
+    { 0x00009aec, 0x0000b784, 0x0000b784, 0x00009314, 0x00009314, 0x00009314 },
+    { 0x00009af0, 0x0000b788, 0x0000b788, 0x00009320, 0x00009320, 0x00009320 },
+    { 0x00009af4, 0x0000b78c, 0x0000b78c, 0x00009324, 0x00009324, 0x00009324 },
+    { 0x00009af8, 0x0000b790, 0x0000b790, 0x00009328, 0x00009328, 0x00009328 },
+    { 0x00009afc, 0x0000b794, 0x0000b794, 0x0000932c, 0x0000932c, 0x0000932c },
+    { 0x00009b00, 0x0000b798, 0x0000b798, 0x00009330, 0x00009330, 0x00009330 },
+    { 0x00009b04, 0x0000d784, 0x0000d784, 0x00009334, 0x00009334, 0x00009334 },
+    { 0x00009b08, 0x0000d788, 0x0000d788, 0x00009321, 0x00009321, 0x00009321 },
+    { 0x00009b0c, 0x0000d78c, 0x0000d78c, 0x00009325, 0x00009325, 0x00009325 },
+    { 0x00009b10, 0x0000d790, 0x0000d790, 0x00009329, 0x00009329, 0x00009329 },
+    { 0x00009b14, 0x0000f780, 0x0000f780, 0x0000932d, 0x0000932d, 0x0000932d },
+    { 0x00009b18, 0x0000f784, 0x0000f784, 0x00009331, 0x00009331, 0x00009331 },
+    { 0x00009b1c, 0x0000f788, 0x0000f788, 0x00009335, 0x00009335, 0x00009335 },
+    { 0x00009b20, 0x0000f78c, 0x0000f78c, 0x00009322, 0x00009322, 0x00009322 },
+    { 0x00009b24, 0x0000f790, 0x0000f790, 0x00009326, 0x00009326, 0x00009326 },
+    { 0x00009b28, 0x0000f794, 0x0000f794, 0x0000932a, 0x0000932a, 0x0000932a },
+    { 0x00009b2c, 0x0000f7a4, 0x0000f7a4, 0x0000932e, 0x0000932e, 0x0000932e },
+    { 0x00009b30, 0x0000f7a8, 0x0000f7a8, 0x00009332, 0x00009332, 0x00009332 },
+    { 0x00009b34, 0x0000f7ac, 0x0000f7ac, 0x00009336, 0x00009336, 0x00009336 },
+    { 0x00009b38, 0x0000f7b0, 0x0000f7b0, 0x00009323, 0x00009323, 0x00009323 },
+    { 0x00009b3c, 0x0000f7b4, 0x0000f7b4, 0x00009327, 0x00009327, 0x00009327 },
+    { 0x00009b40, 0x0000f7a1, 0x0000f7a1, 0x0000932b, 0x0000932b, 0x0000932b },
+    { 0x00009b44, 0x0000f7a5, 0x0000f7a5, 0x0000932f, 0x0000932f, 0x0000932f },
+    { 0x00009b48, 0x0000f7a9, 0x0000f7a9, 0x00009333, 0x00009333, 0x00009333 },
+    { 0x00009b4c, 0x0000f7ad, 0x0000f7ad, 0x00009337, 0x00009337, 0x00009337 },
+    { 0x00009b50, 0x0000f7b1, 0x0000f7b1, 0x00009343, 0x00009343, 0x00009343 },
+    { 0x00009b54, 0x0000f7b5, 0x0000f7b5, 0x00009347, 0x00009347, 0x00009347 },
+    { 0x00009b58, 0x0000f7c5, 0x0000f7c5, 0x0000934b, 0x0000934b, 0x0000934b },
+    { 0x00009b5c, 0x0000f7c9, 0x0000f7c9, 0x0000934f, 0x0000934f, 0x0000934f },
+    { 0x00009b60, 0x0000f7cd, 0x0000f7cd, 0x00009353, 0x00009353, 0x00009353 },
+    { 0x00009b64, 0x0000f7d1, 0x0000f7d1, 0x00009357, 0x00009357, 0x00009357 },
+    { 0x00009b68, 0x0000f7d5, 0x0000f7d5, 0x0000935b, 0x0000935b, 0x0000935b },
+    { 0x00009b6c, 0x0000f7c2, 0x0000f7c2, 0x0000935b, 0x0000935b, 0x0000935b },
+    { 0x00009b70, 0x0000f7c6, 0x0000f7c6, 0x0000935b, 0x0000935b, 0x0000935b },
+    { 0x00009b74, 0x0000f7ca, 0x0000f7ca, 0x0000935b, 0x0000935b, 0x0000935b },
+    { 0x00009b78, 0x0000f7ce, 0x0000f7ce, 0x0000935b, 0x0000935b, 0x0000935b },
+    { 0x00009b7c, 0x0000f7d2, 0x0000f7d2, 0x0000935b, 0x0000935b, 0x0000935b },
+    { 0x00009b80, 0x0000f7d6, 0x0000f7d6, 0x0000935b, 0x0000935b, 0x0000935b },
+    { 0x00009b84, 0x0000f7c3, 0x0000f7c3, 0x0000935b, 0x0000935b, 0x0000935b },
+    { 0x00009b88, 0x0000f7c7, 0x0000f7c7, 0x0000935b, 0x0000935b, 0x0000935b },
+    { 0x00009b8c, 0x0000f7cb, 0x0000f7cb, 0x0000935b, 0x0000935b, 0x0000935b },
+    { 0x00009b90, 0x0000f7d3, 0x0000f7d3, 0x0000935b, 0x0000935b, 0x0000935b },
+    { 0x00009b94, 0x0000f7d7, 0x0000f7d7, 0x0000935b, 0x0000935b, 0x0000935b },
+    { 0x00009b98, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b },
+    { 0x00009b9c, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b },
+    { 0x00009ba0, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b },
+    { 0x00009ba4, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b },
+    { 0x00009ba8, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b },
+    { 0x00009bac, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b },
+    { 0x00009bb0, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b },
+    { 0x00009bb4, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b },
+    { 0x00009bb8, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b },
+    { 0x00009bbc, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b },
+    { 0x00009bc0, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b },
+    { 0x00009bc4, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b },
+    { 0x00009bc8, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b },
+    { 0x00009bcc, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b },
+    { 0x00009bd0, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b },
+    { 0x00009bd4, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b },
+    { 0x00009bd8, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b },
+    { 0x00009bdc, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b },
+    { 0x00009be0, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b },
+    { 0x00009be4, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b },
+    { 0x00009be8, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b },
+    { 0x00009bec, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b },
+    { 0x00009bf0, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b },
+    { 0x00009bf4, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b },
+    { 0x00009bf8, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b },
+    { 0x00009bfc, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b },
+    { 0x00009848, 0x00001066, 0x00001066, 0x0000105a, 0x0000105a, 0x0000105a },
+    { 0x0000a848, 0x00001066, 0x00001066, 0x0000105a, 0x0000105a, 0x0000105a },
+};
+
+static const u32 ar9280Modes_high_power_tx_gain_9280_2[][6] = {
+    { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x0000a304, 0x00003002, 0x00003002, 0x00004002, 0x00004002, 0x00004002 },
+    { 0x0000a308, 0x00006004, 0x00006004, 0x00007008, 0x00007008, 0x00007008 },
+    { 0x0000a30c, 0x0000a006, 0x0000a006, 0x0000c010, 0x0000c010, 0x0000c010 },
+    { 0x0000a310, 0x0000e012, 0x0000e012, 0x00010012, 0x00010012, 0x00010012 },
+    { 0x0000a314, 0x00011014, 0x00011014, 0x00013014, 0x00013014, 0x00013014 },
+    { 0x0000a318, 0x0001504a, 0x0001504a, 0x0001820a, 0x0001820a, 0x0001820a },
+    { 0x0000a31c, 0x0001904c, 0x0001904c, 0x0001b211, 0x0001b211, 0x0001b211 },
+    { 0x0000a320, 0x0001c04e, 0x0001c04e, 0x0001e213, 0x0001e213, 0x0001e213 },
+    { 0x0000a324, 0x00021092, 0x00021092, 0x00022411, 0x00022411, 0x00022411 },
+    { 0x0000a328, 0x0002510a, 0x0002510a, 0x00025413, 0x00025413, 0x00025413 },
+    { 0x0000a32c, 0x0002910c, 0x0002910c, 0x00029811, 0x00029811, 0x00029811 },
+    { 0x0000a330, 0x0002c18b, 0x0002c18b, 0x0002c813, 0x0002c813, 0x0002c813 },
+    { 0x0000a334, 0x0002f1cc, 0x0002f1cc, 0x00030a14, 0x00030a14, 0x00030a14 },
+    { 0x0000a338, 0x000321eb, 0x000321eb, 0x00035a50, 0x00035a50, 0x00035a50 },
+    { 0x0000a33c, 0x000341ec, 0x000341ec, 0x00039c4c, 0x00039c4c, 0x00039c4c },
+    { 0x0000a340, 0x000341ec, 0x000341ec, 0x0003de8a, 0x0003de8a, 0x0003de8a },
+    { 0x0000a344, 0x000341ec, 0x000341ec, 0x00042e92, 0x00042e92, 0x00042e92 },
+    { 0x0000a348, 0x000341ec, 0x000341ec, 0x00046ed2, 0x00046ed2, 0x00046ed2 },
+    { 0x0000a34c, 0x000341ec, 0x000341ec, 0x0004bed5, 0x0004bed5, 0x0004bed5 },
+    { 0x0000a350, 0x000341ec, 0x000341ec, 0x0004ff54, 0x0004ff54, 0x0004ff54 },
+    { 0x0000a354, 0x000341ec, 0x000341ec, 0x00055fd5, 0x00055fd5, 0x00055fd5 },
+    { 0x00007814, 0x00198eff, 0x00198eff, 0x00198eff, 0x00198eff, 0x00198eff },
+    { 0x00007838, 0x00198eff, 0x00198eff, 0x00198eff, 0x00198eff, 0x00198eff },
+    { 0x0000781c, 0x00172000, 0x00172000, 0x00172000, 0x00172000, 0x00172000 },
+    { 0x00007840, 0x00172000, 0x00172000, 0x00172000, 0x00172000, 0x00172000 },
+    { 0x00007820, 0xf258a480, 0xf258a480, 0xf258a480, 0xf258a480, 0xf258a480 },
+    { 0x00007844, 0xf258a480, 0xf258a480, 0xf258a480, 0xf258a480, 0xf258a480 },
+    { 0x0000a274, 0x0a19e652, 0x0a19e652, 0x0a1aa652, 0x0a1aa652, 0x0a1aa652 },
+    { 0x0000a27c, 0x050739ce, 0x050739ce, 0x050739ce, 0x050739ce, 0x050739ce },
+};
+
+static const u32 ar9280Modes_original_tx_gain_9280_2[][6] = {
+    { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x0000a304, 0x00003002, 0x00003002, 0x00003002, 0x00003002, 0x00003002 },
+    { 0x0000a308, 0x00006004, 0x00006004, 0x00008009, 0x00008009, 0x00008009 },
+    { 0x0000a30c, 0x0000a006, 0x0000a006, 0x0000b00b, 0x0000b00b, 0x0000b00b },
+    { 0x0000a310, 0x0000e012, 0x0000e012, 0x0000e012, 0x0000e012, 0x0000e012 },
+    { 0x0000a314, 0x00011014, 0x00011014, 0x00012048, 0x00012048, 0x00012048 },
+    { 0x0000a318, 0x0001504a, 0x0001504a, 0x0001604a, 0x0001604a, 0x0001604a },
+    { 0x0000a31c, 0x0001904c, 0x0001904c, 0x0001a211, 0x0001a211, 0x0001a211 },
+    { 0x0000a320, 0x0001c04e, 0x0001c04e, 0x0001e213, 0x0001e213, 0x0001e213 },
+    { 0x0000a324, 0x00020092, 0x00020092, 0x0002121b, 0x0002121b, 0x0002121b },
+    { 0x0000a328, 0x0002410a, 0x0002410a, 0x00024412, 0x00024412, 0x00024412 },
+    { 0x0000a32c, 0x0002710c, 0x0002710c, 0x00028414, 0x00028414, 0x00028414 },
+    { 0x0000a330, 0x0002b18b, 0x0002b18b, 0x0002b44a, 0x0002b44a, 0x0002b44a },
+    { 0x0000a334, 0x0002e1cc, 0x0002e1cc, 0x00030649, 0x00030649, 0x00030649 },
+    { 0x0000a338, 0x000321ec, 0x000321ec, 0x0003364b, 0x0003364b, 0x0003364b },
+    { 0x0000a33c, 0x000321ec, 0x000321ec, 0x00038a49, 0x00038a49, 0x00038a49 },
+    { 0x0000a340, 0x000321ec, 0x000321ec, 0x0003be48, 0x0003be48, 0x0003be48 },
+    { 0x0000a344, 0x000321ec, 0x000321ec, 0x0003ee4a, 0x0003ee4a, 0x0003ee4a },
+    { 0x0000a348, 0x000321ec, 0x000321ec, 0x00042e88, 0x00042e88, 0x00042e88 },
+    { 0x0000a34c, 0x000321ec, 0x000321ec, 0x00046e8a, 0x00046e8a, 0x00046e8a },
+    { 0x0000a350, 0x000321ec, 0x000321ec, 0x00049ec9, 0x00049ec9, 0x00049ec9 },
+    { 0x0000a354, 0x000321ec, 0x000321ec, 0x0004bf42, 0x0004bf42, 0x0004bf42 },
+    { 0x00007814, 0x0019beff, 0x0019beff, 0x0019beff, 0x0019beff, 0x0019beff },
+    { 0x00007838, 0x0019beff, 0x0019beff, 0x0019beff, 0x0019beff, 0x0019beff },
+    { 0x0000781c, 0x00392000, 0x00392000, 0x00392000, 0x00392000, 0x00392000 },
+    { 0x00007840, 0x00392000, 0x00392000, 0x00392000, 0x00392000, 0x00392000 },
+    { 0x00007820, 0x92592480, 0x92592480, 0x92592480, 0x92592480, 0x92592480 },
+    { 0x00007844, 0x92592480, 0x92592480, 0x92592480, 0x92592480, 0x92592480 },
+    { 0x0000a274, 0x0a19c652, 0x0a19c652, 0x0a1aa652, 0x0a1aa652, 0x0a1aa652 },
+    { 0x0000a27c, 0x050701ce, 0x050701ce, 0x050701ce, 0x050701ce, 0x050701ce },
+};
+
+static const u32 ar9280PciePhy_clkreq_off_L1_9280[][2] = {
+    {0x00004040,  0x9248fd00 },
+    {0x00004040,  0x24924924 },
+    {0x00004040,  0xa8000019 },
+    {0x00004040,  0x13160820 },
+    {0x00004040,  0xe5980560 },
+    {0x00004040,  0xc01dcffc },
+    {0x00004040,  0x1aaabe41 },
+    {0x00004040,  0xbe105554 },
+    {0x00004040,  0x00043007 },
+    {0x00004044,  0x00000000 },
+};
+
+static const u32 ar9280PciePhy_clkreq_always_on_L1_9280[][2] = {
+    {0x00004040,  0x9248fd00 },
+    {0x00004040,  0x24924924 },
+    {0x00004040,  0xa8000019 },
+    {0x00004040,  0x13160820 },
+    {0x00004040,  0xe5980560 },
+    {0x00004040,  0xc01dcffd },
+    {0x00004040,  0x1aaabe41 },
+    {0x00004040,  0xbe105554 },
+    {0x00004040,  0x00043007 },
+    {0x00004044,  0x00000000 },
+};
+
+/* AR9285 */
+static const u_int32_t ar9285Modes_9285[][6] = {
+    { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
+    { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
+    { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
+    { 0x000010f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008 },
+    { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 },
+    { 0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b, 0x0988004f },
+    { 0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440, 0x00006880 },
+    { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 },
+    { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 },
+    { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
+    { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 },
+    { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
+    { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 },
+    { 0x00009840, 0x206a012e, 0x206a012e, 0x206a012e, 0x206a012e, 0x206a012e },
+    { 0x00009844, 0x0372161e, 0x0372161e, 0x03720020, 0x03720020, 0x037216a0 },
+    { 0x00009848, 0x00001066, 0x00001066, 0x0000004e, 0x0000004e, 0x00001059 },
+    { 0x00009850, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2 },
+    { 0x00009858, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e },
+    { 0x0000985c, 0x3139605e, 0x3139605e, 0x3136605e, 0x3136605e, 0x3139605e },
+    { 0x00009860, 0x00058d18, 0x00058d18, 0x00058d20, 0x00058d20, 0x00058d18 },
+    { 0x00009864, 0x0000fe00, 0x0000fe00, 0x0001ce00, 0x0001ce00, 0x0001ce00 },
+    { 0x00009868, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0 },
+    { 0x0000986c, 0x06903081, 0x06903081, 0x06903881, 0x06903881, 0x06903881 },
+    { 0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0 },
+    { 0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016 },
+    { 0x00009924, 0xd00a8007, 0xd00a8007, 0xd00a800d, 0xd00a800d, 0xd00a800d },
+    { 0x00009944, 0xdfbc1010, 0xdfbc1010, 0xdfbc1020, 0xdfbc1020, 0xdfbc1010 },
+    { 0x00009960, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x00009964, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x000099b8, 0x00cf4d1c, 0x00cf4d1c, 0x00cf4d1c, 0x00cf4d1c, 0x00cf4d1c },
+    { 0x000099bc, 0x00000600, 0x00000600, 0x00000c00, 0x00000c00, 0x00000c00 },
+    { 0x000099c0, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4 },
+    { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 },
+    { 0x000099c8, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329 },
+    { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 },
+    { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 },
+    { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x00009a00, 0x00000000, 0x00000000, 0x00068084, 0x00068084, 0x00000000 },
+    { 0x00009a04, 0x00000000, 0x00000000, 0x00068088, 0x00068088, 0x00000000 },
+    { 0x00009a08, 0x00000000, 0x00000000, 0x0006808c, 0x0006808c, 0x00000000 },
+    { 0x00009a0c, 0x00000000, 0x00000000, 0x00068100, 0x00068100, 0x00000000 },
+    { 0x00009a10, 0x00000000, 0x00000000, 0x00068104, 0x00068104, 0x00000000 },
+    { 0x00009a14, 0x00000000, 0x00000000, 0x00068108, 0x00068108, 0x00000000 },
+    { 0x00009a18, 0x00000000, 0x00000000, 0x0006810c, 0x0006810c, 0x00000000 },
+    { 0x00009a1c, 0x00000000, 0x00000000, 0x00068110, 0x00068110, 0x00000000 },
+    { 0x00009a20, 0x00000000, 0x00000000, 0x00068114, 0x00068114, 0x00000000 },
+    { 0x00009a24, 0x00000000, 0x00000000, 0x00068180, 0x00068180, 0x00000000 },
+    { 0x00009a28, 0x00000000, 0x00000000, 0x00068184, 0x00068184, 0x00000000 },
+    { 0x00009a2c, 0x00000000, 0x00000000, 0x00068188, 0x00068188, 0x00000000 },
+    { 0x00009a30, 0x00000000, 0x00000000, 0x0006818c, 0x0006818c, 0x00000000 },
+    { 0x00009a34, 0x00000000, 0x00000000, 0x00068190, 0x00068190, 0x00000000 },
+    { 0x00009a38, 0x00000000, 0x00000000, 0x00068194, 0x00068194, 0x00000000 },
+    { 0x00009a3c, 0x00000000, 0x00000000, 0x000681a0, 0x000681a0, 0x00000000 },
+    { 0x00009a40, 0x00000000, 0x00000000, 0x0006820c, 0x0006820c, 0x00000000 },
+    { 0x00009a44, 0x00000000, 0x00000000, 0x000681a8, 0x000681a8, 0x00000000 },
+    { 0x00009a48, 0x00000000, 0x00000000, 0x00068284, 0x00068284, 0x00000000 },
+    { 0x00009a4c, 0x00000000, 0x00000000, 0x00068288, 0x00068288, 0x00000000 },
+    { 0x00009a50, 0x00000000, 0x00000000, 0x00068220, 0x00068220, 0x00000000 },
+    { 0x00009a54, 0x00000000, 0x00000000, 0x00068290, 0x00068290, 0x00000000 },
+    { 0x00009a58, 0x00000000, 0x00000000, 0x00068300, 0x00068300, 0x00000000 },
+    { 0x00009a5c, 0x00000000, 0x00000000, 0x00068304, 0x00068304, 0x00000000 },
+    { 0x00009a60, 0x00000000, 0x00000000, 0x00068308, 0x00068308, 0x00000000 },
+    { 0x00009a64, 0x00000000, 0x00000000, 0x0006830c, 0x0006830c, 0x00000000 },
+    { 0x00009a68, 0x00000000, 0x00000000, 0x00068380, 0x00068380, 0x00000000 },
+    { 0x00009a6c, 0x00000000, 0x00000000, 0x00068384, 0x00068384, 0x00000000 },
+    { 0x00009a70, 0x00000000, 0x00000000, 0x00068700, 0x00068700, 0x00000000 },
+    { 0x00009a74, 0x00000000, 0x00000000, 0x00068704, 0x00068704, 0x00000000 },
+    { 0x00009a78, 0x00000000, 0x00000000, 0x00068708, 0x00068708, 0x00000000 },
+    { 0x00009a7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000 },
+    { 0x00009a80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000 },
+    { 0x00009a84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000 },
+    { 0x00009a88, 0x00000000, 0x00000000, 0x00068b04, 0x00068b04, 0x00000000 },
+    { 0x00009a8c, 0x00000000, 0x00000000, 0x00068b08, 0x00068b08, 0x00000000 },
+    { 0x00009a90, 0x00000000, 0x00000000, 0x00068b08, 0x00068b08, 0x00000000 },
+    { 0x00009a94, 0x00000000, 0x00000000, 0x00068b0c, 0x00068b0c, 0x00000000 },
+    { 0x00009a98, 0x00000000, 0x00000000, 0x00068b80, 0x00068b80, 0x00000000 },
+    { 0x00009a9c, 0x00000000, 0x00000000, 0x00068b84, 0x00068b84, 0x00000000 },
+    { 0x00009aa0, 0x00000000, 0x00000000, 0x00068b88, 0x00068b88, 0x00000000 },
+    { 0x00009aa4, 0x00000000, 0x00000000, 0x00068b8c, 0x00068b8c, 0x00000000 },
+    { 0x00009aa8, 0x00000000, 0x00000000, 0x000b8b90, 0x000b8b90, 0x00000000 },
+    { 0x00009aac, 0x00000000, 0x00000000, 0x000b8f80, 0x000b8f80, 0x00000000 },
+    { 0x00009ab0, 0x00000000, 0x00000000, 0x000b8f84, 0x000b8f84, 0x00000000 },
+    { 0x00009ab4, 0x00000000, 0x00000000, 0x000b8f88, 0x000b8f88, 0x00000000 },
+    { 0x00009ab8, 0x00000000, 0x00000000, 0x000b8f8c, 0x000b8f8c, 0x00000000 },
+    { 0x00009abc, 0x00000000, 0x00000000, 0x000b8f90, 0x000b8f90, 0x00000000 },
+    { 0x00009ac0, 0x00000000, 0x00000000, 0x000bb30c, 0x000bb30c, 0x00000000 },
+    { 0x00009ac4, 0x00000000, 0x00000000, 0x000bb310, 0x000bb310, 0x00000000 },
+    { 0x00009ac8, 0x00000000, 0x00000000, 0x000bb384, 0x000bb384, 0x00000000 },
+    { 0x00009acc, 0x00000000, 0x00000000, 0x000bb388, 0x000bb388, 0x00000000 },
+    { 0x00009ad0, 0x00000000, 0x00000000, 0x000bb324, 0x000bb324, 0x00000000 },
+    { 0x00009ad4, 0x00000000, 0x00000000, 0x000bb704, 0x000bb704, 0x00000000 },
+    { 0x00009ad8, 0x00000000, 0x00000000, 0x000f96a4, 0x000f96a4, 0x00000000 },
+    { 0x00009adc, 0x00000000, 0x00000000, 0x000f96a8, 0x000f96a8, 0x00000000 },
+    { 0x00009ae0, 0x00000000, 0x00000000, 0x000f9710, 0x000f9710, 0x00000000 },
+    { 0x00009ae4, 0x00000000, 0x00000000, 0x000f9714, 0x000f9714, 0x00000000 },
+    { 0x00009ae8, 0x00000000, 0x00000000, 0x000f9720, 0x000f9720, 0x00000000 },
+    { 0x00009aec, 0x00000000, 0x00000000, 0x000f9724, 0x000f9724, 0x00000000 },
+    { 0x00009af0, 0x00000000, 0x00000000, 0x000f9728, 0x000f9728, 0x00000000 },
+    { 0x00009af4, 0x00000000, 0x00000000, 0x000f972c, 0x000f972c, 0x00000000 },
+    { 0x00009af8, 0x00000000, 0x00000000, 0x000f97a0, 0x000f97a0, 0x00000000 },
+    { 0x00009afc, 0x00000000, 0x00000000, 0x000f97a4, 0x000f97a4, 0x00000000 },
+    { 0x00009b00, 0x00000000, 0x00000000, 0x000fb7a8, 0x000fb7a8, 0x00000000 },
+    { 0x00009b04, 0x00000000, 0x00000000, 0x000fb7b0, 0x000fb7b0, 0x00000000 },
+    { 0x00009b08, 0x00000000, 0x00000000, 0x000fb7b4, 0x000fb7b4, 0x00000000 },
+    { 0x00009b0c, 0x00000000, 0x00000000, 0x000fb7b8, 0x000fb7b8, 0x00000000 },
+    { 0x00009b10, 0x00000000, 0x00000000, 0x000fb7a5, 0x000fb7a5, 0x00000000 },
+    { 0x00009b14, 0x00000000, 0x00000000, 0x000fb7a9, 0x000fb7a9, 0x00000000 },
+    { 0x00009b18, 0x00000000, 0x00000000, 0x000fb7ad, 0x000fb7ad, 0x00000000 },
+    { 0x00009b1c, 0x00000000, 0x00000000, 0x000fb7b1, 0x000fb7b1, 0x00000000 },
+    { 0x00009b20, 0x00000000, 0x00000000, 0x000fb7b5, 0x000fb7b5, 0x00000000 },
+    { 0x00009b24, 0x00000000, 0x00000000, 0x000fb7b9, 0x000fb7b9, 0x00000000 },
+    { 0x00009b28, 0x00000000, 0x00000000, 0x000fb7c5, 0x000fb7c5, 0x00000000 },
+    { 0x00009b2c, 0x00000000, 0x00000000, 0x000fb7c9, 0x000fb7c9, 0x00000000 },
+    { 0x00009b30, 0x00000000, 0x00000000, 0x000fb7d1, 0x000fb7d1, 0x00000000 },
+    { 0x00009b34, 0x00000000, 0x00000000, 0x000fb7d5, 0x000fb7d5, 0x00000000 },
+    { 0x00009b38, 0x00000000, 0x00000000, 0x000fb7d9, 0x000fb7d9, 0x00000000 },
+    { 0x00009b3c, 0x00000000, 0x00000000, 0x000fb7c6, 0x000fb7c6, 0x00000000 },
+    { 0x00009b40, 0x00000000, 0x00000000, 0x000fb7ca, 0x000fb7ca, 0x00000000 },
+    { 0x00009b44, 0x00000000, 0x00000000, 0x000fb7ce, 0x000fb7ce, 0x00000000 },
+    { 0x00009b48, 0x00000000, 0x00000000, 0x000fb7d2, 0x000fb7d2, 0x00000000 },
+    { 0x00009b4c, 0x00000000, 0x00000000, 0x000fb7d6, 0x000fb7d6, 0x00000000 },
+    { 0x00009b50, 0x00000000, 0x00000000, 0x000fb7c3, 0x000fb7c3, 0x00000000 },
+    { 0x00009b54, 0x00000000, 0x00000000, 0x000fb7c7, 0x000fb7c7, 0x00000000 },
+    { 0x00009b58, 0x00000000, 0x00000000, 0x000fb7cb, 0x000fb7cb, 0x00000000 },
+    { 0x00009b5c, 0x00000000, 0x00000000, 0x000fb7cf, 0x000fb7cf, 0x00000000 },
+    { 0x00009b60, 0x00000000, 0x00000000, 0x000fb7d7, 0x000fb7d7, 0x00000000 },
+    { 0x00009b64, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+    { 0x00009b68, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+    { 0x00009b6c, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+    { 0x00009b70, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+    { 0x00009b74, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+    { 0x00009b78, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+    { 0x00009b7c, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+    { 0x00009b80, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+    { 0x00009b84, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+    { 0x00009b88, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+    { 0x00009b8c, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+    { 0x00009b90, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+    { 0x00009b94, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+    { 0x00009b98, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+    { 0x00009b9c, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+    { 0x00009ba0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+    { 0x00009ba4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+    { 0x00009ba8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+    { 0x00009bac, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+    { 0x00009bb0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+    { 0x00009bb4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+    { 0x00009bb8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+    { 0x00009bbc, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+    { 0x00009bc0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+    { 0x00009bc4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+    { 0x00009bc8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+    { 0x00009bcc, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+    { 0x00009bd0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+    { 0x00009bd4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+    { 0x00009bd8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+    { 0x00009bdc, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+    { 0x00009be0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+    { 0x00009be4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+    { 0x00009be8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+    { 0x00009bec, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+    { 0x00009bf0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+    { 0x00009bf4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+    { 0x00009bf8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+    { 0x00009bfc, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
+    { 0x0000aa00, 0x00000000, 0x00000000, 0x0006801c, 0x0006801c, 0x00000000 },
+    { 0x0000aa04, 0x00000000, 0x00000000, 0x00068080, 0x00068080, 0x00000000 },
+    { 0x0000aa08, 0x00000000, 0x00000000, 0x00068084, 0x00068084, 0x00000000 },
+    { 0x0000aa0c, 0x00000000, 0x00000000, 0x00068088, 0x00068088, 0x00000000 },
+    { 0x0000aa10, 0x00000000, 0x00000000, 0x0006808c, 0x0006808c, 0x00000000 },
+    { 0x0000aa14, 0x00000000, 0x00000000, 0x00068100, 0x00068100, 0x00000000 },
+    { 0x0000aa18, 0x00000000, 0x00000000, 0x00068104, 0x00068104, 0x00000000 },
+    { 0x0000aa1c, 0x00000000, 0x00000000, 0x00068108, 0x00068108, 0x00000000 },
+    { 0x0000aa20, 0x00000000, 0x00000000, 0x0006810c, 0x0006810c, 0x00000000 },
+    { 0x0000aa24, 0x00000000, 0x00000000, 0x00068110, 0x00068110, 0x00000000 },
+    { 0x0000aa28, 0x00000000, 0x00000000, 0x00068110, 0x00068110, 0x00000000 },
+    { 0x0000aa2c, 0x00000000, 0x00000000, 0x00068180, 0x00068180, 0x00000000 },
+    { 0x0000aa30, 0x00000000, 0x00000000, 0x00068184, 0x00068184, 0x00000000 },
+    { 0x0000aa34, 0x00000000, 0x00000000, 0x00068188, 0x00068188, 0x00000000 },
+    { 0x0000aa38, 0x00000000, 0x00000000, 0x0006818c, 0x0006818c, 0x00000000 },
+    { 0x0000aa3c, 0x00000000, 0x00000000, 0x00068190, 0x00068190, 0x00000000 },
+    { 0x0000aa40, 0x00000000, 0x00000000, 0x00068194, 0x00068194, 0x00000000 },
+    { 0x0000aa44, 0x00000000, 0x00000000, 0x000681a0, 0x000681a0, 0x00000000 },
+    { 0x0000aa48, 0x00000000, 0x00000000, 0x0006820c, 0x0006820c, 0x00000000 },
+    { 0x0000aa4c, 0x00000000, 0x00000000, 0x000681a8, 0x000681a8, 0x00000000 },
+    { 0x0000aa50, 0x00000000, 0x00000000, 0x000681ac, 0x000681ac, 0x00000000 },
+    { 0x0000aa54, 0x00000000, 0x00000000, 0x0006821c, 0x0006821c, 0x00000000 },
+    { 0x0000aa58, 0x00000000, 0x00000000, 0x00068224, 0x00068224, 0x00000000 },
+    { 0x0000aa5c, 0x00000000, 0x00000000, 0x00068290, 0x00068290, 0x00000000 },
+    { 0x0000aa60, 0x00000000, 0x00000000, 0x00068300, 0x00068300, 0x00000000 },
+    { 0x0000aa64, 0x00000000, 0x00000000, 0x00068308, 0x00068308, 0x00000000 },
+    { 0x0000aa68, 0x00000000, 0x00000000, 0x0006830c, 0x0006830c, 0x00000000 },
+    { 0x0000aa6c, 0x00000000, 0x00000000, 0x00068310, 0x00068310, 0x00000000 },
+    { 0x0000aa70, 0x00000000, 0x00000000, 0x00068788, 0x00068788, 0x00000000 },
+    { 0x0000aa74, 0x00000000, 0x00000000, 0x0006878c, 0x0006878c, 0x00000000 },
+    { 0x0000aa78, 0x00000000, 0x00000000, 0x00068790, 0x00068790, 0x00000000 },
+    { 0x0000aa7c, 0x00000000, 0x00000000, 0x00068794, 0x00068794, 0x00000000 },
+    { 0x0000aa80, 0x00000000, 0x00000000, 0x00068798, 0x00068798, 0x00000000 },
+    { 0x0000aa84, 0x00000000, 0x00000000, 0x0006879c, 0x0006879c, 0x00000000 },
+    { 0x0000aa88, 0x00000000, 0x00000000, 0x00068b89, 0x00068b89, 0x00000000 },
+    { 0x0000aa8c, 0x00000000, 0x00000000, 0x00068b8d, 0x00068b8d, 0x00000000 },
+    { 0x0000aa90, 0x00000000, 0x00000000, 0x00068b91, 0x00068b91, 0x00000000 },
+    { 0x0000aa94, 0x00000000, 0x00000000, 0x00068b95, 0x00068b95, 0x00000000 },
+    { 0x0000aa98, 0x00000000, 0x00000000, 0x00068b99, 0x00068b99, 0x00000000 },
+    { 0x0000aa9c, 0x00000000, 0x00000000, 0x00068ba5, 0x00068ba5, 0x00000000 },
+    { 0x0000aaa0, 0x00000000, 0x00000000, 0x00068ba9, 0x00068ba9, 0x00000000 },
+    { 0x0000aaa4, 0x00000000, 0x00000000, 0x00068bad, 0x00068bad, 0x00000000 },
+    { 0x0000aaa8, 0x00000000, 0x00000000, 0x000b8b0c, 0x000b8b0c, 0x00000000 },
+    { 0x0000aaac, 0x00000000, 0x00000000, 0x000b8f10, 0x000b8f10, 0x00000000 },
+    { 0x0000aab0, 0x00000000, 0x00000000, 0x000b8f14, 0x000b8f14, 0x00000000 },
+    { 0x0000aab4, 0x00000000, 0x00000000, 0x000b8f84, 0x000b8f84, 0x00000000 },
+    { 0x0000aab8, 0x00000000, 0x00000000, 0x000b8f84, 0x000b8f84, 0x00000000 },
+    { 0x0000aabc, 0x00000000, 0x00000000, 0x000b8f88, 0x000b8f88, 0x00000000 },
+    { 0x0000aac0, 0x00000000, 0x00000000, 0x000bb380, 0x000bb380, 0x00000000 },
+    { 0x0000aac4, 0x00000000, 0x00000000, 0x000bb384, 0x000bb384, 0x00000000 },
+    { 0x0000aac8, 0x00000000, 0x00000000, 0x000bb388, 0x000bb388, 0x00000000 },
+    { 0x0000aacc, 0x00000000, 0x00000000, 0x000bb38c, 0x000bb38c, 0x00000000 },
+    { 0x0000aad0, 0x00000000, 0x00000000, 0x000bb394, 0x000bb394, 0x00000000 },
+    { 0x0000aad4, 0x00000000, 0x00000000, 0x000bb798, 0x000bb798, 0x00000000 },
+    { 0x0000aad8, 0x00000000, 0x00000000, 0x000f970c, 0x000f970c, 0x00000000 },
+    { 0x0000aadc, 0x00000000, 0x00000000, 0x000f9710, 0x000f9710, 0x00000000 },
+    { 0x0000aae0, 0x00000000, 0x00000000, 0x000f9714, 0x000f9714, 0x00000000 },
+    { 0x0000aae4, 0x00000000, 0x00000000, 0x000f9718, 0x000f9718, 0x00000000 },
+    { 0x0000aae8, 0x00000000, 0x00000000, 0x000f9705, 0x000f9705, 0x00000000 },
+    { 0x0000aaec, 0x00000000, 0x00000000, 0x000f9709, 0x000f9709, 0x00000000 },
+    { 0x0000aaf0, 0x00000000, 0x00000000, 0x000f970d, 0x000f970d, 0x00000000 },
+    { 0x0000aaf4, 0x00000000, 0x00000000, 0x000f9711, 0x000f9711, 0x00000000 },
+    { 0x0000aaf8, 0x00000000, 0x00000000, 0x000f9715, 0x000f9715, 0x00000000 },
+    { 0x0000aafc, 0x00000000, 0x00000000, 0x000f9719, 0x000f9719, 0x00000000 },
+    { 0x0000ab00, 0x00000000, 0x00000000, 0x000fb7a4, 0x000fb7a4, 0x00000000 },
+    { 0x0000ab04, 0x00000000, 0x00000000, 0x000fb7a8, 0x000fb7a8, 0x00000000 },
+    { 0x0000ab08, 0x00000000, 0x00000000, 0x000fb7ac, 0x000fb7ac, 0x00000000 },
+    { 0x0000ab0c, 0x00000000, 0x00000000, 0x000fb7ac, 0x000fb7ac, 0x00000000 },
+    { 0x0000ab10, 0x00000000, 0x00000000, 0x000fb7b0, 0x000fb7b0, 0x00000000 },
+    { 0x0000ab14, 0x00000000, 0x00000000, 0x000fb7b8, 0x000fb7b8, 0x00000000 },
+    { 0x0000ab18, 0x00000000, 0x00000000, 0x000fb7bc, 0x000fb7bc, 0x00000000 },
+    { 0x0000ab1c, 0x00000000, 0x00000000, 0x000fb7a1, 0x000fb7a1, 0x00000000 },
+    { 0x0000ab20, 0x00000000, 0x00000000, 0x000fb7a5, 0x000fb7a5, 0x00000000 },
+    { 0x0000ab24, 0x00000000, 0x00000000, 0x000fb7a9, 0x000fb7a9, 0x00000000 },
+    { 0x0000ab28, 0x00000000, 0x00000000, 0x000fb7b1, 0x000fb7b1, 0x00000000 },
+    { 0x0000ab2c, 0x00000000, 0x00000000, 0x000fb7b5, 0x000fb7b5, 0x00000000 },
+    { 0x0000ab30, 0x00000000, 0x00000000, 0x000fb7bd, 0x000fb7bd, 0x00000000 },
+    { 0x0000ab34, 0x00000000, 0x00000000, 0x000fb7c9, 0x000fb7c9, 0x00000000 },
+    { 0x0000ab38, 0x00000000, 0x00000000, 0x000fb7cd, 0x000fb7cd, 0x00000000 },
+    { 0x0000ab3c, 0x00000000, 0x00000000, 0x000fb7d1, 0x000fb7d1, 0x00000000 },
+    { 0x0000ab40, 0x00000000, 0x00000000, 0x000fb7d9, 0x000fb7d9, 0x00000000 },
+    { 0x0000ab44, 0x00000000, 0x00000000, 0x000fb7c2, 0x000fb7c2, 0x00000000 },
+    { 0x0000ab48, 0x00000000, 0x00000000, 0x000fb7c6, 0x000fb7c6, 0x00000000 },
+    { 0x0000ab4c, 0x00000000, 0x00000000, 0x000fb7ca, 0x000fb7ca, 0x00000000 },
+    { 0x0000ab50, 0x00000000, 0x00000000, 0x000fb7ce, 0x000fb7ce, 0x00000000 },
+    { 0x0000ab54, 0x00000000, 0x00000000, 0x000fb7d2, 0x000fb7d2, 0x00000000 },
+    { 0x0000ab58, 0x00000000, 0x00000000, 0x000fb7d6, 0x000fb7d6, 0x00000000 },
+    { 0x0000ab5c, 0x00000000, 0x00000000, 0x000fb7c3, 0x000fb7c3, 0x00000000 },
+    { 0x0000ab60, 0x00000000, 0x00000000, 0x000fb7cb, 0x000fb7cb, 0x00000000 },
+    { 0x0000ab64, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+    { 0x0000ab68, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+    { 0x0000ab6c, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+    { 0x0000ab70, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+    { 0x0000ab74, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+    { 0x0000ab78, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+    { 0x0000ab7c, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+    { 0x0000ab80, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+    { 0x0000ab84, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+    { 0x0000ab88, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+    { 0x0000ab8c, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+    { 0x0000ab90, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+    { 0x0000ab94, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+    { 0x0000ab98, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+    { 0x0000ab9c, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+    { 0x0000aba0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+    { 0x0000aba4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+    { 0x0000aba8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+    { 0x0000abac, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+    { 0x0000abb0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+    { 0x0000abb4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+    { 0x0000abb8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+    { 0x0000abbc, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+    { 0x0000abc0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+    { 0x0000abc4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+    { 0x0000abc8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+    { 0x0000abcc, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+    { 0x0000abd0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+    { 0x0000abd4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+    { 0x0000abd8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+    { 0x0000abdc, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+    { 0x0000abe0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+    { 0x0000abe4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+    { 0x0000abe8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+    { 0x0000abec, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+    { 0x0000abf0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+    { 0x0000abf4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+    { 0x0000abf8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+    { 0x0000abfc, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
+    { 0x0000a204, 0x00000004, 0x00000004, 0x00000004, 0x00000004, 0x00000004 },
+    { 0x0000a20c, 0x00000014, 0x00000014, 0x00000000, 0x00000000, 0x0001f000 },
+    { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a },
+    { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
+    { 0x0000a250, 0x001ff000, 0x001ff000, 0x001ca000, 0x001ca000, 0x001da000 },
+    { 0x0000a274, 0x0a81c652, 0x0a81c652, 0x0a820652, 0x0a820652, 0x0a82a652 },
+    { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x0000a304, 0x00000000, 0x00000000, 0x00007201, 0x00007201, 0x00000000 },
+    { 0x0000a308, 0x00000000, 0x00000000, 0x00010408, 0x00010408, 0x00000000 },
+    { 0x0000a30c, 0x00000000, 0x00000000, 0x0001860a, 0x0001860a, 0x00000000 },
+    { 0x0000a310, 0x00000000, 0x00000000, 0x00020818, 0x00020818, 0x00000000 },
+    { 0x0000a314, 0x00000000, 0x00000000, 0x00024858, 0x00024858, 0x00000000 },
+    { 0x0000a318, 0x00000000, 0x00000000, 0x00026859, 0x00026859, 0x00000000 },
+    { 0x0000a31c, 0x00000000, 0x00000000, 0x0002985b, 0x0002985b, 0x00000000 },
+    { 0x0000a320, 0x00000000, 0x00000000, 0x0002c89a, 0x0002c89a, 0x00000000 },
+    { 0x0000a324, 0x00000000, 0x00000000, 0x0002e89b, 0x0002e89b, 0x00000000 },
+    { 0x0000a328, 0x00000000, 0x00000000, 0x0003089c, 0x0003089c, 0x00000000 },
+    { 0x0000a32c, 0x00000000, 0x00000000, 0x0003289d, 0x0003289d, 0x00000000 },
+    { 0x0000a330, 0x00000000, 0x00000000, 0x0003489e, 0x0003489e, 0x00000000 },
+    { 0x0000a334, 0x00000000, 0x00000000, 0x000388de, 0x000388de, 0x00000000 },
+    { 0x0000a338, 0x00000000, 0x00000000, 0x0003b91e, 0x0003b91e, 0x00000000 },
+    { 0x0000a33c, 0x00000000, 0x00000000, 0x0003d95e, 0x0003d95e, 0x00000000 },
+    { 0x0000a340, 0x00000000, 0x00000000, 0x000419df, 0x000419df, 0x00000000 },
+    { 0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
+    { 0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e },
+};
+
+static const u_int32_t ar9285Common_9285[][2] = {
+    { 0x0000000c, 0x00000000 },
+    { 0x00000030, 0x00020045 },
+    { 0x00000034, 0x00000005 },
+    { 0x00000040, 0x00000000 },
+    { 0x00000044, 0x00000008 },
+    { 0x00000048, 0x00000008 },
+    { 0x0000004c, 0x00000010 },
+    { 0x00000050, 0x00000000 },
+    { 0x00000054, 0x0000001f },
+    { 0x00000800, 0x00000000 },
+    { 0x00000804, 0x00000000 },
+    { 0x00000808, 0x00000000 },
+    { 0x0000080c, 0x00000000 },
+    { 0x00000810, 0x00000000 },
+    { 0x00000814, 0x00000000 },
+    { 0x00000818, 0x00000000 },
+    { 0x0000081c, 0x00000000 },
+    { 0x00000820, 0x00000000 },
+    { 0x00000824, 0x00000000 },
+    { 0x00001040, 0x002ffc0f },
+    { 0x00001044, 0x002ffc0f },
+    { 0x00001048, 0x002ffc0f },
+    { 0x0000104c, 0x002ffc0f },
+    { 0x00001050, 0x002ffc0f },
+    { 0x00001054, 0x002ffc0f },
+    { 0x00001058, 0x002ffc0f },
+    { 0x0000105c, 0x002ffc0f },
+    { 0x00001060, 0x002ffc0f },
+    { 0x00001064, 0x002ffc0f },
+    { 0x00001230, 0x00000000 },
+    { 0x00001270, 0x00000000 },
+    { 0x00001038, 0x00000000 },
+    { 0x00001078, 0x00000000 },
+    { 0x000010b8, 0x00000000 },
+    { 0x000010f8, 0x00000000 },
+    { 0x00001138, 0x00000000 },
+    { 0x00001178, 0x00000000 },
+    { 0x000011b8, 0x00000000 },
+    { 0x000011f8, 0x00000000 },
+    { 0x00001238, 0x00000000 },
+    { 0x00001278, 0x00000000 },
+    { 0x000012b8, 0x00000000 },
+    { 0x000012f8, 0x00000000 },
+    { 0x00001338, 0x00000000 },
+    { 0x00001378, 0x00000000 },
+    { 0x000013b8, 0x00000000 },
+    { 0x000013f8, 0x00000000 },
+    { 0x00001438, 0x00000000 },
+    { 0x00001478, 0x00000000 },
+    { 0x000014b8, 0x00000000 },
+    { 0x000014f8, 0x00000000 },
+    { 0x00001538, 0x00000000 },
+    { 0x00001578, 0x00000000 },
+    { 0x000015b8, 0x00000000 },
+    { 0x000015f8, 0x00000000 },
+    { 0x00001638, 0x00000000 },
+    { 0x00001678, 0x00000000 },
+    { 0x000016b8, 0x00000000 },
+    { 0x000016f8, 0x00000000 },
+    { 0x00001738, 0x00000000 },
+    { 0x00001778, 0x00000000 },
+    { 0x000017b8, 0x00000000 },
+    { 0x000017f8, 0x00000000 },
+    { 0x0000103c, 0x00000000 },
+    { 0x0000107c, 0x00000000 },
+    { 0x000010bc, 0x00000000 },
+    { 0x000010fc, 0x00000000 },
+    { 0x0000113c, 0x00000000 },
+    { 0x0000117c, 0x00000000 },
+    { 0x000011bc, 0x00000000 },
+    { 0x000011fc, 0x00000000 },
+    { 0x0000123c, 0x00000000 },
+    { 0x0000127c, 0x00000000 },
+    { 0x000012bc, 0x00000000 },
+    { 0x000012fc, 0x00000000 },
+    { 0x0000133c, 0x00000000 },
+    { 0x0000137c, 0x00000000 },
+    { 0x000013bc, 0x00000000 },
+    { 0x000013fc, 0x00000000 },
+    { 0x0000143c, 0x00000000 },
+    { 0x0000147c, 0x00000000 },
+    { 0x00004030, 0x00000002 },
+    { 0x0000403c, 0x00000002 },
+    { 0x00004024, 0x0000001f },
+    { 0x00004060, 0x00000000 },
+    { 0x00004064, 0x00000000 },
+    { 0x00007010, 0x00000031 },
+    { 0x00007034, 0x00000002 },
+    { 0x00007038, 0x000004c2 },
+    { 0x00008004, 0x00000000 },
+    { 0x00008008, 0x00000000 },
+    { 0x0000800c, 0x00000000 },
+    { 0x00008018, 0x00000700 },
+    { 0x00008020, 0x00000000 },
+    { 0x00008038, 0x00000000 },
+    { 0x0000803c, 0x00000000 },
+    { 0x00008048, 0x00000000 },
+    { 0x00008054, 0x00000000 },
+    { 0x00008058, 0x00000000 },
+    { 0x0000805c, 0x000fc78f },
+    { 0x00008060, 0x0000000f },
+    { 0x00008064, 0x00000000 },
+    { 0x00008070, 0x00000000 },
+    { 0x000080c0, 0x2a80001a },
+    { 0x000080c4, 0x05dc01e0 },
+    { 0x000080c8, 0x1f402710 },
+    { 0x000080cc, 0x01f40000 },
+    { 0x000080d0, 0x00001e00 },
+    { 0x000080d4, 0x00000000 },
+    { 0x000080d8, 0x00400000 },
+    { 0x000080e0, 0xffffffff },
+    { 0x000080e4, 0x0000ffff },
+    { 0x000080e8, 0x003f3f3f },
+    { 0x000080ec, 0x00000000 },
+    { 0x000080f0, 0x00000000 },
+    { 0x000080f4, 0x00000000 },
+    { 0x000080f8, 0x00000000 },
+    { 0x000080fc, 0x00020000 },
+    { 0x00008100, 0x00020000 },
+    { 0x00008104, 0x00000001 },
+    { 0x00008108, 0x00000052 },
+    { 0x0000810c, 0x00000000 },
+    { 0x00008110, 0x00000168 },
+    { 0x00008118, 0x000100aa },
+    { 0x0000811c, 0x00003210 },
+    { 0x00008120, 0x08f04800 },
+    { 0x00008124, 0x00000000 },
+    { 0x00008128, 0x00000000 },
+    { 0x0000812c, 0x00000000 },
+    { 0x00008130, 0x00000000 },
+    { 0x00008134, 0x00000000 },
+    { 0x00008138, 0x00000000 },
+    { 0x0000813c, 0x00000000 },
+    { 0x00008144, 0x00000000 },
+    { 0x00008168, 0x00000000 },
+    { 0x0000816c, 0x00000000 },
+    { 0x00008170, 0x32143320 },
+    { 0x00008174, 0xfaa4fa50 },
+    { 0x00008178, 0x00000100 },
+    { 0x0000817c, 0x00000000 },
+    { 0x000081c0, 0x00000000 },
+    { 0x000081d0, 0x00003210 },
+    { 0x000081ec, 0x00000000 },
+    { 0x000081f0, 0x00000000 },
+    { 0x000081f4, 0x00000000 },
+    { 0x000081f8, 0x00000000 },
+    { 0x000081fc, 0x00000000 },
+    { 0x00008200, 0x00000000 },
+    { 0x00008204, 0x00000000 },
+    { 0x00008208, 0x00000000 },
+    { 0x0000820c, 0x00000000 },
+    { 0x00008210, 0x00000000 },
+    { 0x00008214, 0x00000000 },
+    { 0x00008218, 0x00000000 },
+    { 0x0000821c, 0x00000000 },
+    { 0x00008220, 0x00000000 },
+    { 0x00008224, 0x00000000 },
+    { 0x00008228, 0x00000000 },
+    { 0x0000822c, 0x00000000 },
+    { 0x00008230, 0x00000000 },
+    { 0x00008234, 0x00000000 },
+    { 0x00008238, 0x00000000 },
+    { 0x0000823c, 0x00000000 },
+    { 0x00008240, 0x00100000 },
+    { 0x00008244, 0x0010f400 },
+    { 0x00008248, 0x00000100 },
+    { 0x0000824c, 0x0001e800 },
+    { 0x00008250, 0x00000000 },
+    { 0x00008254, 0x00000000 },
+    { 0x00008258, 0x00000000 },
+    { 0x0000825c, 0x400000ff },
+    { 0x00008260, 0x00080922 },
+    { 0x00008264, 0xa8a00010 },
+    { 0x00008270, 0x00000000 },
+    { 0x00008274, 0x40000000 },
+    { 0x00008278, 0x003e4180 },
+    { 0x0000827c, 0x00000000 },
+    { 0x00008284, 0x0000002c },
+    { 0x00008288, 0x0000002c },
+    { 0x0000828c, 0x00000000 },
+    { 0x00008294, 0x00000000 },
+    { 0x00008298, 0x00000000 },
+    { 0x0000829c, 0x00000000 },
+    { 0x00008300, 0x00000040 },
+    { 0x00008314, 0x00000000 },
+    { 0x00008328, 0x00000000 },
+    { 0x0000832c, 0x00000001 },
+    { 0x00008330, 0x00000302 },
+    { 0x00008334, 0x00000e00 },
+    { 0x00008338, 0x00000000 },
+    { 0x0000833c, 0x00000000 },
+    { 0x00008340, 0x00010380 },
+    { 0x00008344, 0x00581043 },
+    { 0x00009808, 0x00000000 },
+    { 0x0000980c, 0xafe68e30 },
+    { 0x00009810, 0xfd14e000 },
+    { 0x00009814, 0x9c0a9f6b },
+    { 0x0000981c, 0x00000000 },
+    { 0x0000982c, 0x0000a000 },
+    { 0x00009830, 0x00000000 },
+    { 0x0000983c, 0x00200400 },
+    { 0x0000984c, 0x0040233c },
+    { 0x00009854, 0x00000044 },
+    { 0x00009900, 0x00000000 },
+    { 0x00009904, 0x00000000 },
+    { 0x00009908, 0x00000000 },
+    { 0x0000990c, 0x00000000 },
+    { 0x00009910, 0x01002310 },
+    { 0x0000991c, 0x10000fff },
+    { 0x00009920, 0x04900000 },
+    { 0x00009928, 0x00000001 },
+    { 0x0000992c, 0x00000004 },
+    { 0x00009934, 0x1e1f2022 },
+    { 0x00009938, 0x0a0b0c0d },
+    { 0x0000993c, 0x00000000 },
+    { 0x00009940, 0x14750604 },
+    { 0x00009948, 0x9280c00a },
+    { 0x0000994c, 0x00020028 },
+    { 0x00009954, 0x5f3ca3de },
+    { 0x00009958, 0x2108ecff },
+    { 0x00009968, 0x000003ce },
+    { 0x00009970, 0x1927b515 },
+    { 0x00009974, 0x00000000 },
+    { 0x00009978, 0x00000001 },
+    { 0x0000997c, 0x00000000 },
+    { 0x00009980, 0x00000000 },
+    { 0x00009984, 0x00000000 },
+    { 0x00009988, 0x00000000 },
+    { 0x0000998c, 0x00000000 },
+    { 0x00009990, 0x00000000 },
+    { 0x00009994, 0x00000000 },
+    { 0x00009998, 0x00000000 },
+    { 0x0000999c, 0x00000000 },
+    { 0x000099a0, 0x00000000 },
+    { 0x000099a4, 0x00000001 },
+    { 0x000099a8, 0x201fff00 },
+    { 0x000099ac, 0x2def0a00 },
+    { 0x000099b0, 0x03051000 },
+    { 0x000099b4, 0x00000820 },
+    { 0x000099dc, 0x00000000 },
+    { 0x000099e0, 0x00000000 },
+    { 0x000099e4, 0xaaaaaaaa },
+    { 0x000099e8, 0x3c466478 },
+    { 0x000099ec, 0x0cc80caa },
+    { 0x000099f0, 0x00000000 },
+    { 0x0000a208, 0x803e6788 },
+    { 0x0000a210, 0x4080a333 },
+    { 0x0000a214, 0x00206c10 },
+    { 0x0000a218, 0x009c4060 },
+    { 0x0000a220, 0x01834061 },
+    { 0x0000a224, 0x00000400 },
+    { 0x0000a228, 0x000003b5 },
+    { 0x0000a22c, 0x00000000 },
+    { 0x0000a234, 0x20202020 },
+    { 0x0000a238, 0x20202020 },
+    { 0x0000a244, 0x00000000 },
+    { 0x0000a248, 0xfffffffc },
+    { 0x0000a24c, 0x00000000 },
+    { 0x0000a254, 0x00000000 },
+    { 0x0000a258, 0x0ccb5380 },
+    { 0x0000a25c, 0x15151501 },
+    { 0x0000a260, 0xdfa90f01 },
+    { 0x0000a268, 0x00000000 },
+    { 0x0000a26c, 0x0ebae9e6 },
+    { 0x0000d270, 0x0d820820 },
+    { 0x0000a278, 0x39ce739c },
+    { 0x0000a27c, 0x050e039c },
+    { 0x0000d35c, 0x07ffffef },
+    { 0x0000d360, 0x0fffffe7 },
+    { 0x0000d364, 0x17ffffe5 },
+    { 0x0000d368, 0x1fffffe4 },
+    { 0x0000d36c, 0x37ffffe3 },
+    { 0x0000d370, 0x3fffffe3 },
+    { 0x0000d374, 0x57ffffe3 },
+    { 0x0000d378, 0x5fffffe2 },
+    { 0x0000d37c, 0x7fffffe2 },
+    { 0x0000d380, 0x7f3c7bba },
+    { 0x0000d384, 0xf3307ff0 },
+    { 0x0000a388, 0x0c000000 },
+    { 0x0000a38c, 0x20202020 },
+    { 0x0000a390, 0x20202020 },
+    { 0x0000a394, 0x39ce739c },
+    { 0x0000a398, 0x0000039c },
+    { 0x0000a39c, 0x00000001 },
+    { 0x0000a3a0, 0x00000000 },
+    { 0x0000a3a4, 0x00000000 },
+    { 0x0000a3a8, 0x00000000 },
+    { 0x0000a3ac, 0x00000000 },
+    { 0x0000a3b0, 0x00000000 },
+    { 0x0000a3b4, 0x00000000 },
+    { 0x0000a3b8, 0x00000000 },
+    { 0x0000a3bc, 0x00000000 },
+    { 0x0000a3c0, 0x00000000 },
+    { 0x0000a3c4, 0x00000000 },
+    { 0x0000a3cc, 0x20202020 },
+    { 0x0000a3d0, 0x20202020 },
+    { 0x0000a3d4, 0x20202020 },
+    { 0x0000a3dc, 0x39ce739c },
+    { 0x0000a3e0, 0x0000039c },
+    { 0x0000a3e4, 0x00000000 },
+    { 0x0000a3e8, 0x18c43433 },
+    { 0x0000a3ec, 0x00f70081 },
+    { 0x00007800, 0x00140000 },
+    { 0x00007804, 0x0e4548d8 },
+    { 0x00007808, 0x54214514 },
+    { 0x0000780c, 0x02025820 },
+    { 0x00007810, 0x71c0d388 },
+    { 0x00007814, 0x924934a8 },
+    { 0x0000781c, 0x00000000 },
+    { 0x00007820, 0x00000c04 },
+    { 0x00007824, 0x00d86fff },
+    { 0x00007828, 0x26d2491b },
+    { 0x0000782c, 0x6e36d97b },
+    { 0x00007830, 0xedb6d96c },
+    { 0x00007834, 0x71400086 },
+    { 0x00007838, 0xfac68800 },
+    { 0x0000783c, 0x0001fffe },
+    { 0x00007840, 0xffeb1a20 },
+    { 0x00007844, 0x000c0db6 },
+    { 0x00007848, 0x6db61b6f },
+    { 0x0000784c, 0x6d9b66db },
+    { 0x00007850, 0x6d8c6dba },
+    { 0x00007854, 0x00040000 },
+    { 0x00007858, 0xdb003012 },
+    { 0x0000785c, 0x04924914 },
+    { 0x00007860, 0x21084210 },
+    { 0x00007864, 0xf7d7ffde },
+    { 0x00007868, 0xc2034080 },
+    { 0x0000786c, 0x48609eb4 },
+    { 0x00007870, 0x10142c00 },
+};
+
+static const u_int32_t ar9285PciePhy_clkreq_always_on_L1_9285[][2] = {
+    {0x00004040,  0x9248fd00 },
+    {0x00004040,  0x24924924 },
+    {0x00004040,  0xa8000019 },
+    {0x00004040,  0x13160820 },
+    {0x00004040,  0xe5980560 },
+    {0x00004040,  0xc01dcffd },
+    {0x00004040,  0x1aaabe41 },
+    {0x00004040,  0xbe105554 },
+    {0x00004040,  0x00043007 },
+    {0x00004044,  0x00000000 },
+};
+
+static const u_int32_t ar9285PciePhy_clkreq_off_L1_9285[][2] = {
+    {0x00004040,  0x9248fd00 },
+    {0x00004040,  0x24924924 },
+    {0x00004040,  0xa8000019 },
+    {0x00004040,  0x13160820 },
+    {0x00004040,  0xe5980560 },
+    {0x00004040,  0xc01dcffc },
+    {0x00004040,  0x1aaabe41 },
+    {0x00004040,  0xbe105554 },
+    {0x00004040,  0x00043007 },
+    {0x00004044,  0x00000000 },
+};
+
+/* AR9285 v1_2 PCI Register Writes.  Created: 03/04/09 */
+static const u_int32_t ar9285Modes_9285_1_2[][6] = {
+    { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
+    { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
+    { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
+    { 0x000010f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008 },
+    { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 },
+    { 0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b, 0x0988004f },
+    { 0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440, 0x00006880 },
+    { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 },
+    { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 },
+    { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
+    { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 },
+    { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
+    { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 },
+    { 0x00009840, 0x206a012e, 0x206a012e, 0x206a012e, 0x206a012e, 0x206a012e },
+    { 0x00009844, 0x0372161e, 0x0372161e, 0x03721620, 0x03721620, 0x037216a0 },
+    { 0x00009848, 0x00001066, 0x00001066, 0x00001053, 0x00001053, 0x00001059 },
+    { 0x00009850, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2 },
+    { 0x00009858, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e },
+    { 0x0000985c, 0x3139605e, 0x3139605e, 0x3137605e, 0x3137605e, 0x3139605e },
+    { 0x00009860, 0x00058d18, 0x00058d18, 0x00058d20, 0x00058d20, 0x00058d18 },
+    { 0x00009864, 0x0000fe00, 0x0000fe00, 0x0001ce00, 0x0001ce00, 0x0001ce00 },
+    { 0x00009868, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0 },
+    { 0x0000986c, 0x06903081, 0x06903081, 0x06903881, 0x06903881, 0x06903881 },
+    { 0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0 },
+    { 0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016 },
+    { 0x00009924, 0xd00a8007, 0xd00a8007, 0xd00a800d, 0xd00a800d, 0xd00a800d },
+    { 0x00009944, 0xffbc1010, 0xffbc1010, 0xffbc1020, 0xffbc1020, 0xffbc1010 },
+    { 0x00009960, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x00009964, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x000099b8, 0x0000421c, 0x0000421c, 0x0000421c, 0x0000421c, 0x0000421c },
+    { 0x000099bc, 0x00000600, 0x00000600, 0x00000c00, 0x00000c00, 0x00000c00 },
+    { 0x000099c0, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4 },
+    { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 },
+    { 0x000099c8, 0x6af65329, 0x6af65329, 0x6af65329, 0x6af65329, 0x6af65329 },
+    { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 },
+    { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 },
+    { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x00009a00, 0x00000000, 0x00000000, 0x00058084, 0x00058084, 0x00000000 },
+    { 0x00009a04, 0x00000000, 0x00000000, 0x00058088, 0x00058088, 0x00000000 },
+    { 0x00009a08, 0x00000000, 0x00000000, 0x0005808c, 0x0005808c, 0x00000000 },
+    { 0x00009a0c, 0x00000000, 0x00000000, 0x00058100, 0x00058100, 0x00000000 },
+    { 0x00009a10, 0x00000000, 0x00000000, 0x00058104, 0x00058104, 0x00000000 },
+    { 0x00009a14, 0x00000000, 0x00000000, 0x00058108, 0x00058108, 0x00000000 },
+    { 0x00009a18, 0x00000000, 0x00000000, 0x0005810c, 0x0005810c, 0x00000000 },
+    { 0x00009a1c, 0x00000000, 0x00000000, 0x00058110, 0x00058110, 0x00000000 },
+    { 0x00009a20, 0x00000000, 0x00000000, 0x00058114, 0x00058114, 0x00000000 },
+    { 0x00009a24, 0x00000000, 0x00000000, 0x00058180, 0x00058180, 0x00000000 },
+    { 0x00009a28, 0x00000000, 0x00000000, 0x00058184, 0x00058184, 0x00000000 },
+    { 0x00009a2c, 0x00000000, 0x00000000, 0x00058188, 0x00058188, 0x00000000 },
+    { 0x00009a30, 0x00000000, 0x00000000, 0x0005818c, 0x0005818c, 0x00000000 },
+    { 0x00009a34, 0x00000000, 0x00000000, 0x00058190, 0x00058190, 0x00000000 },
+    { 0x00009a38, 0x00000000, 0x00000000, 0x00058194, 0x00058194, 0x00000000 },
+    { 0x00009a3c, 0x00000000, 0x00000000, 0x000581a0, 0x000581a0, 0x00000000 },
+    { 0x00009a40, 0x00000000, 0x00000000, 0x0005820c, 0x0005820c, 0x00000000 },
+    { 0x00009a44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000 },
+    { 0x00009a48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000 },
+    { 0x00009a4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000 },
+    { 0x00009a50, 0x00000000, 0x00000000, 0x00058220, 0x00058220, 0x00000000 },
+    { 0x00009a54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000 },
+    { 0x00009a58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000 },
+    { 0x00009a5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000 },
+    { 0x00009a60, 0x00000000, 0x00000000, 0x00058308, 0x00058308, 0x00000000 },
+    { 0x00009a64, 0x00000000, 0x00000000, 0x0005830c, 0x0005830c, 0x00000000 },
+    { 0x00009a68, 0x00000000, 0x00000000, 0x00058380, 0x00058380, 0x00000000 },
+    { 0x00009a6c, 0x00000000, 0x00000000, 0x00058384, 0x00058384, 0x00000000 },
+    { 0x00009a70, 0x00000000, 0x00000000, 0x00068700, 0x00068700, 0x00000000 },
+    { 0x00009a74, 0x00000000, 0x00000000, 0x00068704, 0x00068704, 0x00000000 },
+    { 0x00009a78, 0x00000000, 0x00000000, 0x00068708, 0x00068708, 0x00000000 },
+    { 0x00009a7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000 },
+    { 0x00009a80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000 },
+    { 0x00009a84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000 },
+    { 0x00009a88, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000 },
+    { 0x00009a8c, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 },
+    { 0x00009a90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 },
+    { 0x00009a94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000 },
+    { 0x00009a98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000 },
+    { 0x00009a9c, 0x00000000, 0x00000000, 0x00078b84, 0x00078b84, 0x00000000 },
+    { 0x00009aa0, 0x00000000, 0x00000000, 0x00078b88, 0x00078b88, 0x00000000 },
+    { 0x00009aa4, 0x00000000, 0x00000000, 0x00078b8c, 0x00078b8c, 0x00000000 },
+    { 0x00009aa8, 0x00000000, 0x00000000, 0x00078b90, 0x00078b90, 0x00000000 },
+    { 0x00009aac, 0x00000000, 0x00000000, 0x000caf80, 0x000caf80, 0x00000000 },
+    { 0x00009ab0, 0x00000000, 0x00000000, 0x000caf84, 0x000caf84, 0x00000000 },
+    { 0x00009ab4, 0x00000000, 0x00000000, 0x000caf88, 0x000caf88, 0x00000000 },
+    { 0x00009ab8, 0x00000000, 0x00000000, 0x000caf8c, 0x000caf8c, 0x00000000 },
+    { 0x00009abc, 0x00000000, 0x00000000, 0x000caf90, 0x000caf90, 0x00000000 },
+    { 0x00009ac0, 0x00000000, 0x00000000, 0x000db30c, 0x000db30c, 0x00000000 },
+    { 0x00009ac4, 0x00000000, 0x00000000, 0x000db310, 0x000db310, 0x00000000 },
+    { 0x00009ac8, 0x00000000, 0x00000000, 0x000db384, 0x000db384, 0x00000000 },
+    { 0x00009acc, 0x00000000, 0x00000000, 0x000db388, 0x000db388, 0x00000000 },
+    { 0x00009ad0, 0x00000000, 0x00000000, 0x000db324, 0x000db324, 0x00000000 },
+    { 0x00009ad4, 0x00000000, 0x00000000, 0x000eb704, 0x000eb704, 0x00000000 },
+    { 0x00009ad8, 0x00000000, 0x00000000, 0x000eb6a4, 0x000eb6a4, 0x00000000 },
+    { 0x00009adc, 0x00000000, 0x00000000, 0x000eb6a8, 0x000eb6a8, 0x00000000 },
+    { 0x00009ae0, 0x00000000, 0x00000000, 0x000eb710, 0x000eb710, 0x00000000 },
+    { 0x00009ae4, 0x00000000, 0x00000000, 0x000eb714, 0x000eb714, 0x00000000 },
+    { 0x00009ae8, 0x00000000, 0x00000000, 0x000eb720, 0x000eb720, 0x00000000 },
+    { 0x00009aec, 0x00000000, 0x00000000, 0x000eb724, 0x000eb724, 0x00000000 },
+    { 0x00009af0, 0x00000000, 0x00000000, 0x000eb728, 0x000eb728, 0x00000000 },
+    { 0x00009af4, 0x00000000, 0x00000000, 0x000eb72c, 0x000eb72c, 0x00000000 },
+    { 0x00009af8, 0x00000000, 0x00000000, 0x000eb7a0, 0x000eb7a0, 0x00000000 },
+    { 0x00009afc, 0x00000000, 0x00000000, 0x000eb7a4, 0x000eb7a4, 0x00000000 },
+    { 0x00009b00, 0x00000000, 0x00000000, 0x000eb7a8, 0x000eb7a8, 0x00000000 },
+    { 0x00009b04, 0x00000000, 0x00000000, 0x000eb7b0, 0x000eb7b0, 0x00000000 },
+    { 0x00009b08, 0x00000000, 0x00000000, 0x000eb7b4, 0x000eb7b4, 0x00000000 },
+    { 0x00009b0c, 0x00000000, 0x00000000, 0x000eb7b8, 0x000eb7b8, 0x00000000 },
+    { 0x00009b10, 0x00000000, 0x00000000, 0x000eb7a5, 0x000eb7a5, 0x00000000 },
+    { 0x00009b14, 0x00000000, 0x00000000, 0x000eb7a9, 0x000eb7a9, 0x00000000 },
+    { 0x00009b18, 0x00000000, 0x00000000, 0x000eb7ad, 0x000eb7ad, 0x00000000 },
+    { 0x00009b1c, 0x00000000, 0x00000000, 0x000eb7b1, 0x000eb7b1, 0x00000000 },
+    { 0x00009b20, 0x00000000, 0x00000000, 0x000eb7b5, 0x000eb7b5, 0x00000000 },
+    { 0x00009b24, 0x00000000, 0x00000000, 0x000eb7b9, 0x000eb7b9, 0x00000000 },
+    { 0x00009b28, 0x00000000, 0x00000000, 0x000eb7c5, 0x000eb7c5, 0x00000000 },
+    { 0x00009b2c, 0x00000000, 0x00000000, 0x000eb7c9, 0x000eb7c9, 0x00000000 },
+    { 0x00009b30, 0x00000000, 0x00000000, 0x000eb7d1, 0x000eb7d1, 0x00000000 },
+    { 0x00009b34, 0x00000000, 0x00000000, 0x000eb7d5, 0x000eb7d5, 0x00000000 },
+    { 0x00009b38, 0x00000000, 0x00000000, 0x000eb7d9, 0x000eb7d9, 0x00000000 },
+    { 0x00009b3c, 0x00000000, 0x00000000, 0x000eb7c6, 0x000eb7c6, 0x00000000 },
+    { 0x00009b40, 0x00000000, 0x00000000, 0x000eb7ca, 0x000eb7ca, 0x00000000 },
+    { 0x00009b44, 0x00000000, 0x00000000, 0x000eb7ce, 0x000eb7ce, 0x00000000 },
+    { 0x00009b48, 0x00000000, 0x00000000, 0x000eb7d2, 0x000eb7d2, 0x00000000 },
+    { 0x00009b4c, 0x00000000, 0x00000000, 0x000eb7d6, 0x000eb7d6, 0x00000000 },
+    { 0x00009b50, 0x00000000, 0x00000000, 0x000eb7c3, 0x000eb7c3, 0x00000000 },
+    { 0x00009b54, 0x00000000, 0x00000000, 0x000eb7c7, 0x000eb7c7, 0x00000000 },
+    { 0x00009b58, 0x00000000, 0x00000000, 0x000eb7cb, 0x000eb7cb, 0x00000000 },
+    { 0x00009b5c, 0x00000000, 0x00000000, 0x000eb7cf, 0x000eb7cf, 0x00000000 },
+    { 0x00009b60, 0x00000000, 0x00000000, 0x000eb7d7, 0x000eb7d7, 0x00000000 },
+    { 0x00009b64, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009b68, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009b6c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009b70, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009b74, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009b78, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009b7c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009b80, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009b84, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009b88, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009b8c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009b90, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009b94, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009b98, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009b9c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009ba0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009ba4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009ba8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bac, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bb0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bb4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bb8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bbc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bc0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bc4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bc8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bcc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bd0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bd4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bd8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bdc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009be0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009be4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009be8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bec, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bf0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bf4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bf8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x00009bfc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000aa00, 0x00000000, 0x00000000, 0x00058084, 0x00058084, 0x00000000 },
+    { 0x0000aa04, 0x00000000, 0x00000000, 0x00058088, 0x00058088, 0x00000000 },
+    { 0x0000aa08, 0x00000000, 0x00000000, 0x0005808c, 0x0005808c, 0x00000000 },
+    { 0x0000aa0c, 0x00000000, 0x00000000, 0x00058100, 0x00058100, 0x00000000 },
+    { 0x0000aa10, 0x00000000, 0x00000000, 0x00058104, 0x00058104, 0x00000000 },
+    { 0x0000aa14, 0x00000000, 0x00000000, 0x00058108, 0x00058108, 0x00000000 },
+    { 0x0000aa18, 0x00000000, 0x00000000, 0x0005810c, 0x0005810c, 0x00000000 },
+    { 0x0000aa1c, 0x00000000, 0x00000000, 0x00058110, 0x00058110, 0x00000000 },
+    { 0x0000aa20, 0x00000000, 0x00000000, 0x00058114, 0x00058114, 0x00000000 },
+    { 0x0000aa24, 0x00000000, 0x00000000, 0x00058180, 0x00058180, 0x00000000 },
+    { 0x0000aa28, 0x00000000, 0x00000000, 0x00058184, 0x00058184, 0x00000000 },
+    { 0x0000aa2c, 0x00000000, 0x00000000, 0x00058188, 0x00058188, 0x00000000 },
+    { 0x0000aa30, 0x00000000, 0x00000000, 0x0005818c, 0x0005818c, 0x00000000 },
+    { 0x0000aa34, 0x00000000, 0x00000000, 0x00058190, 0x00058190, 0x00000000 },
+    { 0x0000aa38, 0x00000000, 0x00000000, 0x00058194, 0x00058194, 0x00000000 },
+    { 0x0000aa3c, 0x00000000, 0x00000000, 0x000581a0, 0x000581a0, 0x00000000 },
+    { 0x0000aa40, 0x00000000, 0x00000000, 0x0005820c, 0x0005820c, 0x00000000 },
+    { 0x0000aa44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000 },
+    { 0x0000aa48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000 },
+    { 0x0000aa4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000 },
+    { 0x0000aa50, 0x00000000, 0x00000000, 0x00058220, 0x00058220, 0x00000000 },
+    { 0x0000aa54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000 },
+    { 0x0000aa58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000 },
+    { 0x0000aa5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000 },
+    { 0x0000aa60, 0x00000000, 0x00000000, 0x00058308, 0x00058308, 0x00000000 },
+    { 0x0000aa64, 0x00000000, 0x00000000, 0x0005830c, 0x0005830c, 0x00000000 },
+    { 0x0000aa68, 0x00000000, 0x00000000, 0x00058380, 0x00058380, 0x00000000 },
+    { 0x0000aa6c, 0x00000000, 0x00000000, 0x00058384, 0x00058384, 0x00000000 },
+    { 0x0000aa70, 0x00000000, 0x00000000, 0x00068700, 0x00068700, 0x00000000 },
+    { 0x0000aa74, 0x00000000, 0x00000000, 0x00068704, 0x00068704, 0x00000000 },
+    { 0x0000aa78, 0x00000000, 0x00000000, 0x00068708, 0x00068708, 0x00000000 },
+    { 0x0000aa7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000 },
+    { 0x0000aa80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000 },
+    { 0x0000aa84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000 },
+    { 0x0000aa88, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000 },
+    { 0x0000aa8c, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 },
+    { 0x0000aa90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 },
+    { 0x0000aa94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000 },
+    { 0x0000aa98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000 },
+    { 0x0000aa9c, 0x00000000, 0x00000000, 0x00078b84, 0x00078b84, 0x00000000 },
+    { 0x0000aaa0, 0x00000000, 0x00000000, 0x00078b88, 0x00078b88, 0x00000000 },
+    { 0x0000aaa4, 0x00000000, 0x00000000, 0x00078b8c, 0x00078b8c, 0x00000000 },
+    { 0x0000aaa8, 0x00000000, 0x00000000, 0x00078b90, 0x00078b90, 0x00000000 },
+    { 0x0000aaac, 0x00000000, 0x00000000, 0x000caf80, 0x000caf80, 0x00000000 },
+    { 0x0000aab0, 0x00000000, 0x00000000, 0x000caf84, 0x000caf84, 0x00000000 },
+    { 0x0000aab4, 0x00000000, 0x00000000, 0x000caf88, 0x000caf88, 0x00000000 },
+    { 0x0000aab8, 0x00000000, 0x00000000, 0x000caf8c, 0x000caf8c, 0x00000000 },
+    { 0x0000aabc, 0x00000000, 0x00000000, 0x000caf90, 0x000caf90, 0x00000000 },
+    { 0x0000aac0, 0x00000000, 0x00000000, 0x000db30c, 0x000db30c, 0x00000000 },
+    { 0x0000aac4, 0x00000000, 0x00000000, 0x000db310, 0x000db310, 0x00000000 },
+    { 0x0000aac8, 0x00000000, 0x00000000, 0x000db384, 0x000db384, 0x00000000 },
+    { 0x0000aacc, 0x00000000, 0x00000000, 0x000db388, 0x000db388, 0x00000000 },
+    { 0x0000aad0, 0x00000000, 0x00000000, 0x000db324, 0x000db324, 0x00000000 },
+    { 0x0000aad4, 0x00000000, 0x00000000, 0x000eb704, 0x000eb704, 0x00000000 },
+    { 0x0000aad8, 0x00000000, 0x00000000, 0x000eb6a4, 0x000eb6a4, 0x00000000 },
+    { 0x0000aadc, 0x00000000, 0x00000000, 0x000eb6a8, 0x000eb6a8, 0x00000000 },
+    { 0x0000aae0, 0x00000000, 0x00000000, 0x000eb710, 0x000eb710, 0x00000000 },
+    { 0x0000aae4, 0x00000000, 0x00000000, 0x000eb714, 0x000eb714, 0x00000000 },
+    { 0x0000aae8, 0x00000000, 0x00000000, 0x000eb720, 0x000eb720, 0x00000000 },
+    { 0x0000aaec, 0x00000000, 0x00000000, 0x000eb724, 0x000eb724, 0x00000000 },
+    { 0x0000aaf0, 0x00000000, 0x00000000, 0x000eb728, 0x000eb728, 0x00000000 },
+    { 0x0000aaf4, 0x00000000, 0x00000000, 0x000eb72c, 0x000eb72c, 0x00000000 },
+    { 0x0000aaf8, 0x00000000, 0x00000000, 0x000eb7a0, 0x000eb7a0, 0x00000000 },
+    { 0x0000aafc, 0x00000000, 0x00000000, 0x000eb7a4, 0x000eb7a4, 0x00000000 },
+    { 0x0000ab00, 0x00000000, 0x00000000, 0x000eb7a8, 0x000eb7a8, 0x00000000 },
+    { 0x0000ab04, 0x00000000, 0x00000000, 0x000eb7b0, 0x000eb7b0, 0x00000000 },
+    { 0x0000ab08, 0x00000000, 0x00000000, 0x000eb7b4, 0x000eb7b4, 0x00000000 },
+    { 0x0000ab0c, 0x00000000, 0x00000000, 0x000eb7b8, 0x000eb7b8, 0x00000000 },
+    { 0x0000ab10, 0x00000000, 0x00000000, 0x000eb7a5, 0x000eb7a5, 0x00000000 },
+    { 0x0000ab14, 0x00000000, 0x00000000, 0x000eb7a9, 0x000eb7a9, 0x00000000 },
+    { 0x0000ab18, 0x00000000, 0x00000000, 0x000eb7ad, 0x000eb7ad, 0x00000000 },
+    { 0x0000ab1c, 0x00000000, 0x00000000, 0x000eb7b1, 0x000eb7b1, 0x00000000 },
+    { 0x0000ab20, 0x00000000, 0x00000000, 0x000eb7b5, 0x000eb7b5, 0x00000000 },
+    { 0x0000ab24, 0x00000000, 0x00000000, 0x000eb7b9, 0x000eb7b9, 0x00000000 },
+    { 0x0000ab28, 0x00000000, 0x00000000, 0x000eb7c5, 0x000eb7c5, 0x00000000 },
+    { 0x0000ab2c, 0x00000000, 0x00000000, 0x000eb7c9, 0x000eb7c9, 0x00000000 },
+    { 0x0000ab30, 0x00000000, 0x00000000, 0x000eb7d1, 0x000eb7d1, 0x00000000 },
+    { 0x0000ab34, 0x00000000, 0x00000000, 0x000eb7d5, 0x000eb7d5, 0x00000000 },
+    { 0x0000ab38, 0x00000000, 0x00000000, 0x000eb7d9, 0x000eb7d9, 0x00000000 },
+    { 0x0000ab3c, 0x00000000, 0x00000000, 0x000eb7c6, 0x000eb7c6, 0x00000000 },
+    { 0x0000ab40, 0x00000000, 0x00000000, 0x000eb7ca, 0x000eb7ca, 0x00000000 },
+    { 0x0000ab44, 0x00000000, 0x00000000, 0x000eb7ce, 0x000eb7ce, 0x00000000 },
+    { 0x0000ab48, 0x00000000, 0x00000000, 0x000eb7d2, 0x000eb7d2, 0x00000000 },
+    { 0x0000ab4c, 0x00000000, 0x00000000, 0x000eb7d6, 0x000eb7d6, 0x00000000 },
+    { 0x0000ab50, 0x00000000, 0x00000000, 0x000eb7c3, 0x000eb7c3, 0x00000000 },
+    { 0x0000ab54, 0x00000000, 0x00000000, 0x000eb7c7, 0x000eb7c7, 0x00000000 },
+    { 0x0000ab58, 0x00000000, 0x00000000, 0x000eb7cb, 0x000eb7cb, 0x00000000 },
+    { 0x0000ab5c, 0x00000000, 0x00000000, 0x000eb7cf, 0x000eb7cf, 0x00000000 },
+    { 0x0000ab60, 0x00000000, 0x00000000, 0x000eb7d7, 0x000eb7d7, 0x00000000 },
+    { 0x0000ab64, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000ab68, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000ab6c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000ab70, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000ab74, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000ab78, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000ab7c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000ab80, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000ab84, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000ab88, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000ab8c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000ab90, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000ab94, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000ab98, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000ab9c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000aba0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000aba4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000aba8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abac, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abb0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abb4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abb8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abbc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abc0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abc4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abc8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abcc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abd0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abd4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abd8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abdc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abe0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abe4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abe8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abec, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abf0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abf4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abf8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000abfc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
+    { 0x0000a204, 0x00000004, 0x00000004, 0x00000004, 0x00000004, 0x00000004 },
+    { 0x0000a20c, 0x00000014, 0x00000014, 0x0001f000, 0x0001f000, 0x0001f000 },
+    { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a },
+    { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
+    { 0x0000a250, 0x0004f000, 0x0004f000, 0x0004a000, 0x0004a000, 0x0004a000 },
+    { 0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e },
+};
+
+static const u_int32_t ar9285Common_9285_1_2[][2] = {
+    { 0x0000000c, 0x00000000 },
+    { 0x00000030, 0x00020045 },
+    { 0x00000034, 0x00000005 },
+    { 0x00000040, 0x00000000 },
+    { 0x00000044, 0x00000008 },
+    { 0x00000048, 0x00000008 },
+    { 0x0000004c, 0x00000010 },
+    { 0x00000050, 0x00000000 },
+    { 0x00000054, 0x0000001f },
+    { 0x00000800, 0x00000000 },
+    { 0x00000804, 0x00000000 },
+    { 0x00000808, 0x00000000 },
+    { 0x0000080c, 0x00000000 },
+    { 0x00000810, 0x00000000 },
+    { 0x00000814, 0x00000000 },
+    { 0x00000818, 0x00000000 },
+    { 0x0000081c, 0x00000000 },
+    { 0x00000820, 0x00000000 },
+    { 0x00000824, 0x00000000 },
+    { 0x00001040, 0x002ffc0f },
+    { 0x00001044, 0x002ffc0f },
+    { 0x00001048, 0x002ffc0f },
+    { 0x0000104c, 0x002ffc0f },
+    { 0x00001050, 0x002ffc0f },
+    { 0x00001054, 0x002ffc0f },
+    { 0x00001058, 0x002ffc0f },
+    { 0x0000105c, 0x002ffc0f },
+    { 0x00001060, 0x002ffc0f },
+    { 0x00001064, 0x002ffc0f },
+    { 0x00001230, 0x00000000 },
+    { 0x00001270, 0x00000000 },
+    { 0x00001038, 0x00000000 },
+    { 0x00001078, 0x00000000 },
+    { 0x000010b8, 0x00000000 },
+    { 0x000010f8, 0x00000000 },
+    { 0x00001138, 0x00000000 },
+    { 0x00001178, 0x00000000 },
+    { 0x000011b8, 0x00000000 },
+    { 0x000011f8, 0x00000000 },
+    { 0x00001238, 0x00000000 },
+    { 0x00001278, 0x00000000 },
+    { 0x000012b8, 0x00000000 },
+    { 0x000012f8, 0x00000000 },
+    { 0x00001338, 0x00000000 },
+    { 0x00001378, 0x00000000 },
+    { 0x000013b8, 0x00000000 },
+    { 0x000013f8, 0x00000000 },
+    { 0x00001438, 0x00000000 },
+    { 0x00001478, 0x00000000 },
+    { 0x000014b8, 0x00000000 },
+    { 0x000014f8, 0x00000000 },
+    { 0x00001538, 0x00000000 },
+    { 0x00001578, 0x00000000 },
+    { 0x000015b8, 0x00000000 },
+    { 0x000015f8, 0x00000000 },
+    { 0x00001638, 0x00000000 },
+    { 0x00001678, 0x00000000 },
+    { 0x000016b8, 0x00000000 },
+    { 0x000016f8, 0x00000000 },
+    { 0x00001738, 0x00000000 },
+    { 0x00001778, 0x00000000 },
+    { 0x000017b8, 0x00000000 },
+    { 0x000017f8, 0x00000000 },
+    { 0x0000103c, 0x00000000 },
+    { 0x0000107c, 0x00000000 },
+    { 0x000010bc, 0x00000000 },
+    { 0x000010fc, 0x00000000 },
+    { 0x0000113c, 0x00000000 },
+    { 0x0000117c, 0x00000000 },
+    { 0x000011bc, 0x00000000 },
+    { 0x000011fc, 0x00000000 },
+    { 0x0000123c, 0x00000000 },
+    { 0x0000127c, 0x00000000 },
+    { 0x000012bc, 0x00000000 },
+    { 0x000012fc, 0x00000000 },
+    { 0x0000133c, 0x00000000 },
+    { 0x0000137c, 0x00000000 },
+    { 0x000013bc, 0x00000000 },
+    { 0x000013fc, 0x00000000 },
+    { 0x0000143c, 0x00000000 },
+    { 0x0000147c, 0x00000000 },
+    { 0x00004030, 0x00000002 },
+    { 0x0000403c, 0x00000002 },
+    { 0x00004024, 0x0000001f },
+    { 0x00004060, 0x00000000 },
+    { 0x00004064, 0x00000000 },
+    { 0x00007010, 0x00000031 },
+    { 0x00007034, 0x00000002 },
+    { 0x00007038, 0x000004c2 },
+    { 0x00008004, 0x00000000 },
+    { 0x00008008, 0x00000000 },
+    { 0x0000800c, 0x00000000 },
+    { 0x00008018, 0x00000700 },
+    { 0x00008020, 0x00000000 },
+    { 0x00008038, 0x00000000 },
+    { 0x0000803c, 0x00000000 },
+    { 0x00008048, 0x00000000 },
+    { 0x00008054, 0x00000000 },
+    { 0x00008058, 0x00000000 },
+    { 0x0000805c, 0x000fc78f },
+    { 0x00008060, 0x0000000f },
+    { 0x00008064, 0x00000000 },
+    { 0x00008070, 0x00000000 },
+    { 0x000080c0, 0x2a80001a },
+    { 0x000080c4, 0x05dc01e0 },
+    { 0x000080c8, 0x1f402710 },
+    { 0x000080cc, 0x01f40000 },
+    { 0x000080d0, 0x00001e00 },
+    { 0x000080d4, 0x00000000 },
+    { 0x000080d8, 0x00400000 },
+    { 0x000080e0, 0xffffffff },
+    { 0x000080e4, 0x0000ffff },
+    { 0x000080e8, 0x003f3f3f },
+    { 0x000080ec, 0x00000000 },
+    { 0x000080f0, 0x00000000 },
+    { 0x000080f4, 0x00000000 },
+    { 0x000080f8, 0x00000000 },
+    { 0x000080fc, 0x00020000 },
+    { 0x00008100, 0x00020000 },
+    { 0x00008104, 0x00000001 },
+    { 0x00008108, 0x00000052 },
+    { 0x0000810c, 0x00000000 },
+    { 0x00008110, 0x00000168 },
+    { 0x00008118, 0x000100aa },
+    { 0x0000811c, 0x00003210 },
+    { 0x00008120, 0x08f04810 },
+    { 0x00008124, 0x00000000 },
+    { 0x00008128, 0x00000000 },
+    { 0x0000812c, 0x00000000 },
+    { 0x00008130, 0x00000000 },
+    { 0x00008134, 0x00000000 },
+    { 0x00008138, 0x00000000 },
+    { 0x0000813c, 0x00000000 },
+    { 0x00008144, 0xffffffff },
+    { 0x00008168, 0x00000000 },
+    { 0x0000816c, 0x00000000 },
+    { 0x00008170, 0x32143320 },
+    { 0x00008174, 0xfaa4fa50 },
+    { 0x00008178, 0x00000100 },
+    { 0x0000817c, 0x00000000 },
+    { 0x000081c0, 0x00000000 },
+    { 0x000081d0, 0x0000320a },
+    { 0x000081ec, 0x00000000 },
+    { 0x000081f0, 0x00000000 },
+    { 0x000081f4, 0x00000000 },
+    { 0x000081f8, 0x00000000 },
+    { 0x000081fc, 0x00000000 },
+    { 0x00008200, 0x00000000 },
+    { 0x00008204, 0x00000000 },
+    { 0x00008208, 0x00000000 },
+    { 0x0000820c, 0x00000000 },
+    { 0x00008210, 0x00000000 },
+    { 0x00008214, 0x00000000 },
+    { 0x00008218, 0x00000000 },
+    { 0x0000821c, 0x00000000 },
+    { 0x00008220, 0x00000000 },
+    { 0x00008224, 0x00000000 },
+    { 0x00008228, 0x00000000 },
+    { 0x0000822c, 0x00000000 },
+    { 0x00008230, 0x00000000 },
+    { 0x00008234, 0x00000000 },
+    { 0x00008238, 0x00000000 },
+    { 0x0000823c, 0x00000000 },
+    { 0x00008240, 0x00100000 },
+    { 0x00008244, 0x0010f400 },
+    { 0x00008248, 0x00000100 },
+    { 0x0000824c, 0x0001e800 },
+    { 0x00008250, 0x00000000 },
+    { 0x00008254, 0x00000000 },
+    { 0x00008258, 0x00000000 },
+    { 0x0000825c, 0x400000ff },
+    { 0x00008260, 0x00080922 },
+    { 0x00008264, 0xa8a00010 },
+    { 0x00008270, 0x00000000 },
+    { 0x00008274, 0x40000000 },
+    { 0x00008278, 0x003e4180 },
+    { 0x0000827c, 0x00000000 },
+    { 0x00008284, 0x0000002c },
+    { 0x00008288, 0x0000002c },
+    { 0x0000828c, 0x00000000 },
+    { 0x00008294, 0x00000000 },
+    { 0x00008298, 0x00000000 },
+    { 0x0000829c, 0x00000000 },
+    { 0x00008300, 0x00000040 },
+    { 0x00008314, 0x00000000 },
+    { 0x00008328, 0x00000000 },
+    { 0x0000832c, 0x00000001 },
+    { 0x00008330, 0x00000302 },
+    { 0x00008334, 0x00000e00 },
+    { 0x00008338, 0x00ff0000 },
+    { 0x0000833c, 0x00000000 },
+    { 0x00008340, 0x00010380 },
+    { 0x00008344, 0x00581043 },
+    { 0x00009808, 0x00000000 },
+    { 0x0000980c, 0xafe68e30 },
+    { 0x00009810, 0xfd14e000 },
+    { 0x00009814, 0x9c0a9f6b },
+    { 0x0000981c, 0x00000000 },
+    { 0x0000982c, 0x0000a000 },
+    { 0x00009830, 0x00000000 },
+    { 0x0000983c, 0x00200400 },
+    { 0x0000984c, 0x0040233c },
+    { 0x00009854, 0x00000044 },
+    { 0x00009900, 0x00000000 },
+    { 0x00009904, 0x00000000 },
+    { 0x00009908, 0x00000000 },
+    { 0x0000990c, 0x00000000 },
+    { 0x00009910, 0x01002310 },
+    { 0x0000991c, 0x10000fff },
+    { 0x00009920, 0x04900000 },
+    { 0x00009928, 0x00000001 },
+    { 0x0000992c, 0x00000004 },
+    { 0x00009934, 0x1e1f2022 },
+    { 0x00009938, 0x0a0b0c0d },
+    { 0x0000993c, 0x00000000 },
+    { 0x00009940, 0x14750604 },
+    { 0x00009948, 0x9280c00a },
+    { 0x0000994c, 0x00020028 },
+    { 0x00009954, 0x5f3ca3de },
+    { 0x00009958, 0x2108ecff },
+    { 0x00009968, 0x000003ce },
+    { 0x00009970, 0x192bb515 },
+    { 0x00009974, 0x00000000 },
+    { 0x00009978, 0x00000001 },
+    { 0x0000997c, 0x00000000 },
+    { 0x00009980, 0x00000000 },
+    { 0x00009984, 0x00000000 },
+    { 0x00009988, 0x00000000 },
+    { 0x0000998c, 0x00000000 },
+    { 0x00009990, 0x00000000 },
+    { 0x00009994, 0x00000000 },
+    { 0x00009998, 0x00000000 },
+    { 0x0000999c, 0x00000000 },
+    { 0x000099a0, 0x00000000 },
+    { 0x000099a4, 0x00000001 },
+    { 0x000099a8, 0x201fff00 },
+    { 0x000099ac, 0x2def0400 },
+    { 0x000099b0, 0x03051000 },
+    { 0x000099b4, 0x00000820 },
+    { 0x000099dc, 0x00000000 },
+    { 0x000099e0, 0x00000000 },
+    { 0x000099e4, 0xaaaaaaaa },
+    { 0x000099e8, 0x3c466478 },
+    { 0x000099ec, 0x0cc80caa },
+    { 0x000099f0, 0x00000000 },
+    { 0x0000a208, 0x803e68c8 },
+    { 0x0000a210, 0x4080a333 },
+    { 0x0000a214, 0x00206c10 },
+    { 0x0000a218, 0x009c4060 },
+    { 0x0000a220, 0x01834061 },
+    { 0x0000a224, 0x00000400 },
+    { 0x0000a228, 0x000003b5 },
+    { 0x0000a22c, 0x00000000 },
+    { 0x0000a234, 0x20202020 },
+    { 0x0000a238, 0x20202020 },
+    { 0x0000a244, 0x00000000 },
+    { 0x0000a248, 0xfffffffc },
+    { 0x0000a24c, 0x00000000 },
+    { 0x0000a254, 0x00000000 },
+    { 0x0000a258, 0x0ccb5380 },
+    { 0x0000a25c, 0x15151501 },
+    { 0x0000a260, 0xdfa90f01 },
+    { 0x0000a268, 0x00000000 },
+    { 0x0000a26c, 0x0ebae9e6 },
+    { 0x0000d270, 0x0d820820 },
+    { 0x0000d35c, 0x07ffffef },
+    { 0x0000d360, 0x0fffffe7 },
+    { 0x0000d364, 0x17ffffe5 },
+    { 0x0000d368, 0x1fffffe4 },
+    { 0x0000d36c, 0x37ffffe3 },
+    { 0x0000d370, 0x3fffffe3 },
+    { 0x0000d374, 0x57ffffe3 },
+    { 0x0000d378, 0x5fffffe2 },
+    { 0x0000d37c, 0x7fffffe2 },
+    { 0x0000d380, 0x7f3c7bba },
+    { 0x0000d384, 0xf3307ff0 },
+    { 0x0000a388, 0x0c000000 },
+    { 0x0000a38c, 0x20202020 },
+    { 0x0000a390, 0x20202020 },
+    { 0x0000a39c, 0x00000001 },
+    { 0x0000a3a0, 0x00000000 },
+    { 0x0000a3a4, 0x00000000 },
+    { 0x0000a3a8, 0x00000000 },
+    { 0x0000a3ac, 0x00000000 },
+    { 0x0000a3b0, 0x00000000 },
+    { 0x0000a3b4, 0x00000000 },
+    { 0x0000a3b8, 0x00000000 },
+    { 0x0000a3bc, 0x00000000 },
+    { 0x0000a3c0, 0x00000000 },
+    { 0x0000a3c4, 0x00000000 },
+    { 0x0000a3cc, 0x20202020 },
+    { 0x0000a3d0, 0x20202020 },
+    { 0x0000a3d4, 0x20202020 },
+    { 0x0000a3e4, 0x00000000 },
+    { 0x0000a3e8, 0x18c43433 },
+    { 0x0000a3ec, 0x00f70081 },
+    { 0x00007800, 0x00140000 },
+    { 0x00007804, 0x0e4548d8 },
+    { 0x00007808, 0x54214514 },
+    { 0x0000780c, 0x02025820 },
+    { 0x00007810, 0x71c0d388 },
+    { 0x00007814, 0x924934a8 },
+    { 0x0000781c, 0x00000000 },
+    { 0x00007824, 0x00d86fff },
+    { 0x00007828, 0x26d2491b },
+    { 0x0000782c, 0x6e36d97b },
+    { 0x00007830, 0xedb6d96e },
+    { 0x00007834, 0x71400087 },
+    { 0x0000783c, 0x0001fffe },
+    { 0x00007840, 0xffeb1a20 },
+    { 0x00007844, 0x000c0db6 },
+    { 0x00007848, 0x6db61b6f },
+    { 0x0000784c, 0x6d9b66db },
+    { 0x00007850, 0x6d8c6dba },
+    { 0x00007854, 0x00040000 },
+    { 0x00007858, 0xdb003012 },
+    { 0x0000785c, 0x04924914 },
+    { 0x00007860, 0x21084210 },
+    { 0x00007864, 0xf7d7ffde },
+    { 0x00007868, 0xc2034080 },
+    { 0x00007870, 0x10142c00 },
+};
+
+static const u_int32_t ar9285Modes_high_power_tx_gain_9285_1_2[][6] = {
+    /* Address      5G-HT20     5G-HT40     2G-HT40     2G-HT20     Turbo   */
+    { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x0000a304, 0x00000000, 0x00000000, 0x00005200, 0x00005200, 0x00000000 },
+    { 0x0000a308, 0x00000000, 0x00000000, 0x00007201, 0x00007201, 0x00000000 },
+    { 0x0000a30c, 0x00000000, 0x00000000, 0x0000b240, 0x0000b240, 0x00000000 },
+    { 0x0000a310, 0x00000000, 0x00000000, 0x0000d241, 0x0000d241, 0x00000000 },
+    { 0x0000a314, 0x00000000, 0x00000000, 0x0000f440, 0x0000f440, 0x00000000 },
+    { 0x0000a318, 0x00000000, 0x00000000, 0x00014640, 0x00014640, 0x00000000 },
+    { 0x0000a31c, 0x00000000, 0x00000000, 0x00018680, 0x00018680, 0x00000000 },
+    { 0x0000a320, 0x00000000, 0x00000000, 0x00019841, 0x00019841, 0x00000000 },
+    { 0x0000a324, 0x00000000, 0x00000000, 0x0001ca40, 0x0001ca40, 0x00000000 },
+    { 0x0000a328, 0x00000000, 0x00000000, 0x0001fa80, 0x0001fa80, 0x00000000 },
+    { 0x0000a32c, 0x00000000, 0x00000000, 0x00023ac0, 0x00023ac0, 0x00000000 },
+    { 0x0000a330, 0x00000000, 0x00000000, 0x0002ab40, 0x0002ab40, 0x00000000 },
+    { 0x0000a334, 0x00000000, 0x00000000, 0x00033d82, 0x00033d82, 0x00000000 },
+    { 0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000 },
+    { 0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000 },
+    { 0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
+    { 0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
+    { 0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
+    { 0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
+    { 0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
+    { 0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
+    { 0x00007838, 0xfac68803, 0xfac68803, 0xfac68803, 0xfac68803, 0xfac68803 },
+    { 0x0000786c, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe },
+    { 0x00007820, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00 },
+    { 0x0000a274, 0x0a22a652, 0x0a22a652, 0x0a21a652, 0x0a21a652, 0x0a22a652 },
+    { 0x0000a278, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce },
+    { 0x0000a27c, 0x050701ce, 0x050701ce, 0x050701ce, 0x050701ce, 0x050701ce },
+    { 0x0000a394, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce },
+    { 0x0000a398, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce },
+    { 0x0000a3dc, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce },
+    { 0x0000a3e0, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce },
+};
+
+static const u_int32_t ar9285Modes_original_tx_gain_9285_1_2[][6] = {
+    /* Address      5G-HT20     5G-HT40     2G-HT40     2G-HT20     Turbo   */
+    { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
+    { 0x0000a304, 0x00000000, 0x00000000, 0x00009200, 0x00009200, 0x00000000 },
+    { 0x0000a308, 0x00000000, 0x00000000, 0x00010208, 0x00010208, 0x00000000 },
+    { 0x0000a30c, 0x00000000, 0x00000000, 0x00019608, 0x00019608, 0x00000000 },
+    { 0x0000a310, 0x00000000, 0x00000000, 0x00022618, 0x00022618, 0x00000000 },
+    { 0x0000a314, 0x00000000, 0x00000000, 0x0002a6c9, 0x0002a6c9, 0x00000000 },
+    { 0x0000a318, 0x00000000, 0x00000000, 0x00031710, 0x00031710, 0x00000000 },
+    { 0x0000a31c, 0x00000000, 0x00000000, 0x00035718, 0x00035718, 0x00000000 },
+    { 0x0000a320, 0x00000000, 0x00000000, 0x00038758, 0x00038758, 0x00000000 },
+    { 0x0000a324, 0x00000000, 0x00000000, 0x0003c75a, 0x0003c75a, 0x00000000 },
+    { 0x0000a328, 0x00000000, 0x00000000, 0x0004075c, 0x0004075c, 0x00000000 },
+    { 0x0000a32c, 0x00000000, 0x00000000, 0x0004475e, 0x0004475e, 0x00000000 },
+    { 0x0000a330, 0x00000000, 0x00000000, 0x0004679f, 0x0004679f, 0x00000000 },
+    { 0x0000a334, 0x00000000, 0x00000000, 0x000487df, 0x000487df, 0x00000000 },
+    { 0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000 },
+    { 0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000 },
+    { 0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
+    { 0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
+    { 0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
+    { 0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
+    { 0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
+    { 0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
+    { 0x00007838, 0xfac68801, 0xfac68801, 0xfac68801, 0xfac68801, 0xfac68801 },
+    { 0x0000786c, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4 },
+    { 0x00007820, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04 },
+    { 0x0000a274, 0x0a21c652, 0x0a21c652, 0x0a21a652, 0x0a21a652, 0x0a22a652 },
+    { 0x0000a278, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c },
+    { 0x0000a27c, 0x050e039c, 0x050e039c, 0x050e039c, 0x050e039c, 0x050e039c },
+    { 0x0000a394, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c },
+    { 0x0000a398, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c },
+    { 0x0000a3dc, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c },
+    { 0x0000a3e0, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c },
+};
+
+static const u_int32_t ar9285PciePhy_clkreq_always_on_L1_9285_1_2[][2] = {
+    {0x00004040,  0x9248fd00 },
+    {0x00004040,  0x24924924 },
+    {0x00004040,  0xa8000019 },
+    {0x00004040,  0x13160820 },
+    {0x00004040,  0xe5980560 },
+    {0x00004040,  0xc01dcffd },
+    {0x00004040,  0x1aaabe41 },
+    {0x00004040,  0xbe105554 },
+    {0x00004040,  0x00043007 },
+    {0x00004044,  0x00000000 },
+};
+
+static const u_int32_t ar9285PciePhy_clkreq_off_L1_9285_1_2[][2] = {
+    {0x00004040,  0x9248fd00 },
+    {0x00004040,  0x24924924 },
+    {0x00004040,  0xa8000019 },
+    {0x00004040,  0x13160820 },
+    {0x00004040,  0xe5980560 },
+    {0x00004040,  0xc01dcffc },
+    {0x00004040,  0x1aaabe41 },
+    {0x00004040,  0xbe105554 },
+    {0x00004040,  0x00043007 },
+    {0x00004044,  0x00000000 },
+};
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c
new file mode 100644 (file)
index 0000000..8ae4ec2
--- /dev/null
@@ -0,0 +1,976 @@
+/*
+ * Copyright (c) 2008-2009 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 "ath9k.h"
+
+static void ath9k_hw_set_txq_interrupts(struct ath_hw *ah,
+                                       struct ath9k_tx_queue_info *qi)
+{
+       DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
+               "tx ok 0x%x err 0x%x desc 0x%x eol 0x%x urn 0x%x\n",
+               ah->txok_interrupt_mask, ah->txerr_interrupt_mask,
+               ah->txdesc_interrupt_mask, ah->txeol_interrupt_mask,
+               ah->txurn_interrupt_mask);
+
+       REG_WRITE(ah, AR_IMR_S0,
+                 SM(ah->txok_interrupt_mask, AR_IMR_S0_QCU_TXOK)
+                 | SM(ah->txdesc_interrupt_mask, AR_IMR_S0_QCU_TXDESC));
+       REG_WRITE(ah, AR_IMR_S1,
+                 SM(ah->txerr_interrupt_mask, AR_IMR_S1_QCU_TXERR)
+                 | SM(ah->txeol_interrupt_mask, AR_IMR_S1_QCU_TXEOL));
+       REG_RMW_FIELD(ah, AR_IMR_S2,
+                     AR_IMR_S2_QCU_TXURN, ah->txurn_interrupt_mask);
+}
+
+u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q)
+{
+       return REG_READ(ah, AR_QTXDP(q));
+}
+
+bool ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp)
+{
+       REG_WRITE(ah, AR_QTXDP(q), txdp);
+
+       return true;
+}
+
+bool ath9k_hw_txstart(struct ath_hw *ah, u32 q)
+{
+       DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Enable TXE on queue: %u\n", q);
+
+       REG_WRITE(ah, AR_Q_TXE, 1 << q);
+
+       return true;
+}
+
+u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q)
+{
+       u32 npend;
+
+       npend = REG_READ(ah, AR_QSTS(q)) & AR_Q_STS_PEND_FR_CNT;
+       if (npend == 0) {
+
+               if (REG_READ(ah, AR_Q_TXE) & (1 << q))
+                       npend = 1;
+       }
+
+       return npend;
+}
+
+bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel)
+{
+       u32 txcfg, curLevel, newLevel;
+       enum ath9k_int omask;
+
+       if (ah->tx_trig_level >= MAX_TX_FIFO_THRESHOLD)
+               return false;
+
+       omask = ath9k_hw_set_interrupts(ah, ah->mask_reg & ~ATH9K_INT_GLOBAL);
+
+       txcfg = REG_READ(ah, AR_TXCFG);
+       curLevel = MS(txcfg, AR_FTRIG);
+       newLevel = curLevel;
+       if (bIncTrigLevel) {
+               if (curLevel < MAX_TX_FIFO_THRESHOLD)
+                       newLevel++;
+       } else if (curLevel > MIN_TX_FIFO_THRESHOLD)
+               newLevel--;
+       if (newLevel != curLevel)
+               REG_WRITE(ah, AR_TXCFG,
+                         (txcfg & ~AR_FTRIG) | SM(newLevel, AR_FTRIG));
+
+       ath9k_hw_set_interrupts(ah, omask);
+
+       ah->tx_trig_level = newLevel;
+
+       return newLevel != curLevel;
+}
+
+bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q)
+{
+#define ATH9K_TX_STOP_DMA_TIMEOUT      4000    /* usec */
+#define ATH9K_TIME_QUANTUM             100     /* usec */
+
+       struct ath9k_hw_capabilities *pCap = &ah->caps;
+       struct ath9k_tx_queue_info *qi;
+       u32 tsfLow, j, wait;
+       u32 wait_time = ATH9K_TX_STOP_DMA_TIMEOUT / ATH9K_TIME_QUANTUM;
+
+       if (q >= pCap->total_queues) {
+               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Stopping TX DMA, "
+                       "invalid queue: %u\n", q);
+               return false;
+       }
+
+       qi = &ah->txq[q];
+       if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
+               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Stopping TX DMA, "
+                       "inactive queue: %u\n", q);
+               return false;
+       }
+
+       REG_WRITE(ah, AR_Q_TXD, 1 << q);
+
+       for (wait = wait_time; wait != 0; wait--) {
+               if (ath9k_hw_numtxpending(ah, q) == 0)
+                       break;
+               udelay(ATH9K_TIME_QUANTUM);
+       }
+
+       if (ath9k_hw_numtxpending(ah, q)) {
+               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
+                       "%s: Num of pending TX Frames %d on Q %d\n",
+                       __func__, ath9k_hw_numtxpending(ah, q), q);
+
+               for (j = 0; j < 2; j++) {
+                       tsfLow = REG_READ(ah, AR_TSF_L32);
+                       REG_WRITE(ah, AR_QUIET2,
+                                 SM(10, AR_QUIET2_QUIET_DUR));
+                       REG_WRITE(ah, AR_QUIET_PERIOD, 100);
+                       REG_WRITE(ah, AR_NEXT_QUIET_TIMER, tsfLow >> 10);
+                       REG_SET_BIT(ah, AR_TIMER_MODE,
+                                      AR_QUIET_TIMER_EN);
+
+                       if ((REG_READ(ah, AR_TSF_L32) >> 10) == (tsfLow >> 10))
+                               break;
+
+                       DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
+                               "TSF has moved while trying to set "
+                               "quiet time TSF: 0x%08x\n", tsfLow);
+               }
+
+               REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
+
+               udelay(200);
+               REG_CLR_BIT(ah, AR_TIMER_MODE, AR_QUIET_TIMER_EN);
+
+               wait = wait_time;
+               while (ath9k_hw_numtxpending(ah, q)) {
+                       if ((--wait) == 0) {
+                               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
+                                       "Failed to stop TX DMA in 100 "
+                                       "msec after killing last frame\n");
+                               break;
+                       }
+                       udelay(ATH9K_TIME_QUANTUM);
+               }
+
+               REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
+       }
+
+       REG_WRITE(ah, AR_Q_TXD, 0);
+       return wait != 0;
+
+#undef ATH9K_TX_STOP_DMA_TIMEOUT
+#undef ATH9K_TIME_QUANTUM
+}
+
+bool ath9k_hw_filltxdesc(struct ath_hw *ah, struct ath_desc *ds,
+                        u32 segLen, bool firstSeg,
+                        bool lastSeg, const struct ath_desc *ds0)
+{
+       struct ar5416_desc *ads = AR5416DESC(ds);
+
+       if (firstSeg) {
+               ads->ds_ctl1 |= segLen | (lastSeg ? 0 : AR_TxMore);
+       } else if (lastSeg) {
+               ads->ds_ctl0 = 0;
+               ads->ds_ctl1 = segLen;
+               ads->ds_ctl2 = AR5416DESC_CONST(ds0)->ds_ctl2;
+               ads->ds_ctl3 = AR5416DESC_CONST(ds0)->ds_ctl3;
+       } else {
+               ads->ds_ctl0 = 0;
+               ads->ds_ctl1 = segLen | AR_TxMore;
+               ads->ds_ctl2 = 0;
+               ads->ds_ctl3 = 0;
+       }
+       ads->ds_txstatus0 = ads->ds_txstatus1 = 0;
+       ads->ds_txstatus2 = ads->ds_txstatus3 = 0;
+       ads->ds_txstatus4 = ads->ds_txstatus5 = 0;
+       ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
+       ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
+
+       return true;
+}
+
+void ath9k_hw_cleartxdesc(struct ath_hw *ah, struct ath_desc *ds)
+{
+       struct ar5416_desc *ads = AR5416DESC(ds);
+
+       ads->ds_txstatus0 = ads->ds_txstatus1 = 0;
+       ads->ds_txstatus2 = ads->ds_txstatus3 = 0;
+       ads->ds_txstatus4 = ads->ds_txstatus5 = 0;
+       ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
+       ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
+}
+
+int ath9k_hw_txprocdesc(struct ath_hw *ah, struct ath_desc *ds)
+{
+       struct ar5416_desc *ads = AR5416DESC(ds);
+
+       if ((ads->ds_txstatus9 & AR_TxDone) == 0)
+               return -EINPROGRESS;
+
+       ds->ds_txstat.ts_seqnum = MS(ads->ds_txstatus9, AR_SeqNum);
+       ds->ds_txstat.ts_tstamp = ads->AR_SendTimestamp;
+       ds->ds_txstat.ts_status = 0;
+       ds->ds_txstat.ts_flags = 0;
+
+       if (ads->ds_txstatus1 & AR_ExcessiveRetries)
+               ds->ds_txstat.ts_status |= ATH9K_TXERR_XRETRY;
+       if (ads->ds_txstatus1 & AR_Filtered)
+               ds->ds_txstat.ts_status |= ATH9K_TXERR_FILT;
+       if (ads->ds_txstatus1 & AR_FIFOUnderrun) {
+               ds->ds_txstat.ts_status |= ATH9K_TXERR_FIFO;
+               ath9k_hw_updatetxtriglevel(ah, true);
+       }
+       if (ads->ds_txstatus9 & AR_TxOpExceeded)
+               ds->ds_txstat.ts_status |= ATH9K_TXERR_XTXOP;
+       if (ads->ds_txstatus1 & AR_TxTimerExpired)
+               ds->ds_txstat.ts_status |= ATH9K_TXERR_TIMER_EXPIRED;
+
+       if (ads->ds_txstatus1 & AR_DescCfgErr)
+               ds->ds_txstat.ts_flags |= ATH9K_TX_DESC_CFG_ERR;
+       if (ads->ds_txstatus1 & AR_TxDataUnderrun) {
+               ds->ds_txstat.ts_flags |= ATH9K_TX_DATA_UNDERRUN;
+               ath9k_hw_updatetxtriglevel(ah, true);
+       }
+       if (ads->ds_txstatus1 & AR_TxDelimUnderrun) {
+               ds->ds_txstat.ts_flags |= ATH9K_TX_DELIM_UNDERRUN;
+               ath9k_hw_updatetxtriglevel(ah, true);
+       }
+       if (ads->ds_txstatus0 & AR_TxBaStatus) {
+               ds->ds_txstat.ts_flags |= ATH9K_TX_BA;
+               ds->ds_txstat.ba_low = ads->AR_BaBitmapLow;
+               ds->ds_txstat.ba_high = ads->AR_BaBitmapHigh;
+       }
+
+       ds->ds_txstat.ts_rateindex = MS(ads->ds_txstatus9, AR_FinalTxIdx);
+       switch (ds->ds_txstat.ts_rateindex) {
+       case 0:
+               ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate0);
+               break;
+       case 1:
+               ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate1);
+               break;
+       case 2:
+               ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate2);
+               break;
+       case 3:
+               ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate3);
+               break;
+       }
+
+       ds->ds_txstat.ts_rssi = MS(ads->ds_txstatus5, AR_TxRSSICombined);
+       ds->ds_txstat.ts_rssi_ctl0 = MS(ads->ds_txstatus0, AR_TxRSSIAnt00);
+       ds->ds_txstat.ts_rssi_ctl1 = MS(ads->ds_txstatus0, AR_TxRSSIAnt01);
+       ds->ds_txstat.ts_rssi_ctl2 = MS(ads->ds_txstatus0, AR_TxRSSIAnt02);
+       ds->ds_txstat.ts_rssi_ext0 = MS(ads->ds_txstatus5, AR_TxRSSIAnt10);
+       ds->ds_txstat.ts_rssi_ext1 = MS(ads->ds_txstatus5, AR_TxRSSIAnt11);
+       ds->ds_txstat.ts_rssi_ext2 = MS(ads->ds_txstatus5, AR_TxRSSIAnt12);
+       ds->ds_txstat.evm0 = ads->AR_TxEVM0;
+       ds->ds_txstat.evm1 = ads->AR_TxEVM1;
+       ds->ds_txstat.evm2 = ads->AR_TxEVM2;
+       ds->ds_txstat.ts_shortretry = MS(ads->ds_txstatus1, AR_RTSFailCnt);
+       ds->ds_txstat.ts_longretry = MS(ads->ds_txstatus1, AR_DataFailCnt);
+       ds->ds_txstat.ts_virtcol = MS(ads->ds_txstatus1, AR_VirtRetryCnt);
+       ds->ds_txstat.ts_antenna = 0;
+
+       return 0;
+}
+
+void ath9k_hw_set11n_txdesc(struct ath_hw *ah, struct ath_desc *ds,
+                           u32 pktLen, enum ath9k_pkt_type type, u32 txPower,
+                           u32 keyIx, enum ath9k_key_type keyType, u32 flags)
+{
+       struct ar5416_desc *ads = AR5416DESC(ds);
+
+       txPower += ah->txpower_indexoffset;
+       if (txPower > 63)
+               txPower = 63;
+
+       ads->ds_ctl0 = (pktLen & AR_FrameLen)
+               | (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0)
+               | SM(txPower, AR_XmitPower)
+               | (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0)
+               | (flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0)
+               | (flags & ATH9K_TXDESC_INTREQ ? AR_TxIntrReq : 0)
+               | (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0);
+
+       ads->ds_ctl1 =
+               (keyIx != ATH9K_TXKEYIX_INVALID ? SM(keyIx, AR_DestIdx) : 0)
+               | SM(type, AR_FrameType)
+               | (flags & ATH9K_TXDESC_NOACK ? AR_NoAck : 0)
+               | (flags & ATH9K_TXDESC_EXT_ONLY ? AR_ExtOnly : 0)
+               | (flags & ATH9K_TXDESC_EXT_AND_CTL ? AR_ExtAndCtl : 0);
+
+       ads->ds_ctl6 = SM(keyType, AR_EncrType);
+
+       if (AR_SREV_9285(ah)) {
+               ads->ds_ctl8 = 0;
+               ads->ds_ctl9 = 0;
+               ads->ds_ctl10 = 0;
+               ads->ds_ctl11 = 0;
+       }
+}
+
+void ath9k_hw_set11n_ratescenario(struct ath_hw *ah, struct ath_desc *ds,
+                                 struct ath_desc *lastds,
+                                 u32 durUpdateEn, u32 rtsctsRate,
+                                 u32 rtsctsDuration,
+                                 struct ath9k_11n_rate_series series[],
+                                 u32 nseries, u32 flags)
+{
+       struct ar5416_desc *ads = AR5416DESC(ds);
+       struct ar5416_desc *last_ads = AR5416DESC(lastds);
+       u32 ds_ctl0;
+
+       if (flags & (ATH9K_TXDESC_RTSENA | ATH9K_TXDESC_CTSENA)) {
+               ds_ctl0 = ads->ds_ctl0;
+
+               if (flags & ATH9K_TXDESC_RTSENA) {
+                       ds_ctl0 &= ~AR_CTSEnable;
+                       ds_ctl0 |= AR_RTSEnable;
+               } else {
+                       ds_ctl0 &= ~AR_RTSEnable;
+                       ds_ctl0 |= AR_CTSEnable;
+               }
+
+               ads->ds_ctl0 = ds_ctl0;
+       } else {
+               ads->ds_ctl0 =
+                       (ads->ds_ctl0 & ~(AR_RTSEnable | AR_CTSEnable));
+       }
+
+       ads->ds_ctl2 = set11nTries(series, 0)
+               | set11nTries(series, 1)
+               | set11nTries(series, 2)
+               | set11nTries(series, 3)
+               | (durUpdateEn ? AR_DurUpdateEna : 0)
+               | SM(0, AR_BurstDur);
+
+       ads->ds_ctl3 = set11nRate(series, 0)
+               | set11nRate(series, 1)
+               | set11nRate(series, 2)
+               | set11nRate(series, 3);
+
+       ads->ds_ctl4 = set11nPktDurRTSCTS(series, 0)
+               | set11nPktDurRTSCTS(series, 1);
+
+       ads->ds_ctl5 = set11nPktDurRTSCTS(series, 2)
+               | set11nPktDurRTSCTS(series, 3);
+
+       ads->ds_ctl7 = set11nRateFlags(series, 0)
+               | set11nRateFlags(series, 1)
+               | set11nRateFlags(series, 2)
+               | set11nRateFlags(series, 3)
+               | SM(rtsctsRate, AR_RTSCTSRate);
+       last_ads->ds_ctl2 = ads->ds_ctl2;
+       last_ads->ds_ctl3 = ads->ds_ctl3;
+}
+
+void ath9k_hw_set11n_aggr_first(struct ath_hw *ah, struct ath_desc *ds,
+                               u32 aggrLen)
+{
+       struct ar5416_desc *ads = AR5416DESC(ds);
+
+       ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
+       ads->ds_ctl6 &= ~AR_AggrLen;
+       ads->ds_ctl6 |= SM(aggrLen, AR_AggrLen);
+}
+
+void ath9k_hw_set11n_aggr_middle(struct ath_hw *ah, struct ath_desc *ds,
+                                u32 numDelims)
+{
+       struct ar5416_desc *ads = AR5416DESC(ds);
+       unsigned int ctl6;
+
+       ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
+
+       ctl6 = ads->ds_ctl6;
+       ctl6 &= ~AR_PadDelim;
+       ctl6 |= SM(numDelims, AR_PadDelim);
+       ads->ds_ctl6 = ctl6;
+}
+
+void ath9k_hw_set11n_aggr_last(struct ath_hw *ah, struct ath_desc *ds)
+{
+       struct ar5416_desc *ads = AR5416DESC(ds);
+
+       ads->ds_ctl1 |= AR_IsAggr;
+       ads->ds_ctl1 &= ~AR_MoreAggr;
+       ads->ds_ctl6 &= ~AR_PadDelim;
+}
+
+void ath9k_hw_clr11n_aggr(struct ath_hw *ah, struct ath_desc *ds)
+{
+       struct ar5416_desc *ads = AR5416DESC(ds);
+
+       ads->ds_ctl1 &= (~AR_IsAggr & ~AR_MoreAggr);
+}
+
+void ath9k_hw_set11n_burstduration(struct ath_hw *ah, struct ath_desc *ds,
+                                  u32 burstDuration)
+{
+       struct ar5416_desc *ads = AR5416DESC(ds);
+
+       ads->ds_ctl2 &= ~AR_BurstDur;
+       ads->ds_ctl2 |= SM(burstDuration, AR_BurstDur);
+}
+
+void ath9k_hw_set11n_virtualmorefrag(struct ath_hw *ah, struct ath_desc *ds,
+                                    u32 vmf)
+{
+       struct ar5416_desc *ads = AR5416DESC(ds);
+
+       if (vmf)
+               ads->ds_ctl0 |= AR_VirtMoreFrag;
+       else
+               ads->ds_ctl0 &= ~AR_VirtMoreFrag;
+}
+
+void ath9k_hw_gettxintrtxqs(struct ath_hw *ah, u32 *txqs)
+{
+       *txqs &= ah->intr_txqs;
+       ah->intr_txqs &= ~(*txqs);
+}
+
+bool ath9k_hw_set_txq_props(struct ath_hw *ah, int q,
+                           const struct ath9k_tx_queue_info *qinfo)
+{
+       u32 cw;
+       struct ath9k_hw_capabilities *pCap = &ah->caps;
+       struct ath9k_tx_queue_info *qi;
+
+       if (q >= pCap->total_queues) {
+               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Set TXQ properties, "
+                       "invalid queue: %u\n", q);
+               return false;
+       }
+
+       qi = &ah->txq[q];
+       if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
+               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Set TXQ properties, "
+                       "inactive queue: %u\n", q);
+               return false;
+       }
+
+       DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Set queue properties for: %u\n", q);
+
+       qi->tqi_ver = qinfo->tqi_ver;
+       qi->tqi_subtype = qinfo->tqi_subtype;
+       qi->tqi_qflags = qinfo->tqi_qflags;
+       qi->tqi_priority = qinfo->tqi_priority;
+       if (qinfo->tqi_aifs != ATH9K_TXQ_USEDEFAULT)
+               qi->tqi_aifs = min(qinfo->tqi_aifs, 255U);
+       else
+               qi->tqi_aifs = INIT_AIFS;
+       if (qinfo->tqi_cwmin != ATH9K_TXQ_USEDEFAULT) {
+               cw = min(qinfo->tqi_cwmin, 1024U);
+               qi->tqi_cwmin = 1;
+               while (qi->tqi_cwmin < cw)
+                       qi->tqi_cwmin = (qi->tqi_cwmin << 1) | 1;
+       } else
+               qi->tqi_cwmin = qinfo->tqi_cwmin;
+       if (qinfo->tqi_cwmax != ATH9K_TXQ_USEDEFAULT) {
+               cw = min(qinfo->tqi_cwmax, 1024U);
+               qi->tqi_cwmax = 1;
+               while (qi->tqi_cwmax < cw)
+                       qi->tqi_cwmax = (qi->tqi_cwmax << 1) | 1;
+       } else
+               qi->tqi_cwmax = INIT_CWMAX;
+
+       if (qinfo->tqi_shretry != 0)
+               qi->tqi_shretry = min((u32) qinfo->tqi_shretry, 15U);
+       else
+               qi->tqi_shretry = INIT_SH_RETRY;
+       if (qinfo->tqi_lgretry != 0)
+               qi->tqi_lgretry = min((u32) qinfo->tqi_lgretry, 15U);
+       else
+               qi->tqi_lgretry = INIT_LG_RETRY;
+       qi->tqi_cbrPeriod = qinfo->tqi_cbrPeriod;
+       qi->tqi_cbrOverflowLimit = qinfo->tqi_cbrOverflowLimit;
+       qi->tqi_burstTime = qinfo->tqi_burstTime;
+       qi->tqi_readyTime = qinfo->tqi_readyTime;
+
+       switch (qinfo->tqi_subtype) {
+       case ATH9K_WME_UPSD:
+               if (qi->tqi_type == ATH9K_TX_QUEUE_DATA)
+                       qi->tqi_intFlags = ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS;
+               break;
+       default:
+               break;
+       }
+
+       return true;
+}
+
+bool ath9k_hw_get_txq_props(struct ath_hw *ah, int q,
+                           struct ath9k_tx_queue_info *qinfo)
+{
+       struct ath9k_hw_capabilities *pCap = &ah->caps;
+       struct ath9k_tx_queue_info *qi;
+
+       if (q >= pCap->total_queues) {
+               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Get TXQ properties, "
+                       "invalid queue: %u\n", q);
+               return false;
+       }
+
+       qi = &ah->txq[q];
+       if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
+               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Get TXQ properties, "
+                       "inactive queue: %u\n", q);
+               return false;
+       }
+
+       qinfo->tqi_qflags = qi->tqi_qflags;
+       qinfo->tqi_ver = qi->tqi_ver;
+       qinfo->tqi_subtype = qi->tqi_subtype;
+       qinfo->tqi_qflags = qi->tqi_qflags;
+       qinfo->tqi_priority = qi->tqi_priority;
+       qinfo->tqi_aifs = qi->tqi_aifs;
+       qinfo->tqi_cwmin = qi->tqi_cwmin;
+       qinfo->tqi_cwmax = qi->tqi_cwmax;
+       qinfo->tqi_shretry = qi->tqi_shretry;
+       qinfo->tqi_lgretry = qi->tqi_lgretry;
+       qinfo->tqi_cbrPeriod = qi->tqi_cbrPeriod;
+       qinfo->tqi_cbrOverflowLimit = qi->tqi_cbrOverflowLimit;
+       qinfo->tqi_burstTime = qi->tqi_burstTime;
+       qinfo->tqi_readyTime = qi->tqi_readyTime;
+
+       return true;
+}
+
+int ath9k_hw_setuptxqueue(struct ath_hw *ah, enum ath9k_tx_queue type,
+                         const struct ath9k_tx_queue_info *qinfo)
+{
+       struct ath9k_tx_queue_info *qi;
+       struct ath9k_hw_capabilities *pCap = &ah->caps;
+       int q;
+
+       switch (type) {
+       case ATH9K_TX_QUEUE_BEACON:
+               q = pCap->total_queues - 1;
+               break;
+       case ATH9K_TX_QUEUE_CAB:
+               q = pCap->total_queues - 2;
+               break;
+       case ATH9K_TX_QUEUE_PSPOLL:
+               q = 1;
+               break;
+       case ATH9K_TX_QUEUE_UAPSD:
+               q = pCap->total_queues - 3;
+               break;
+       case ATH9K_TX_QUEUE_DATA:
+               for (q = 0; q < pCap->total_queues; q++)
+                       if (ah->txq[q].tqi_type ==
+                           ATH9K_TX_QUEUE_INACTIVE)
+                               break;
+               if (q == pCap->total_queues) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+                               "No available TX queue\n");
+                       return -1;
+               }
+               break;
+       default:
+               DPRINTF(ah->ah_sc, ATH_DBG_FATAL, "Invalid TX queue type: %u\n",
+                       type);
+               return -1;
+       }
+
+       DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Setup TX queue: %u\n", q);
+
+       qi = &ah->txq[q];
+       if (qi->tqi_type != ATH9K_TX_QUEUE_INACTIVE) {
+               DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+                       "TX queue: %u already active\n", q);
+               return -1;
+       }
+       memset(qi, 0, sizeof(struct ath9k_tx_queue_info));
+       qi->tqi_type = type;
+       if (qinfo == NULL) {
+               qi->tqi_qflags =
+                       TXQ_FLAG_TXOKINT_ENABLE
+                       | TXQ_FLAG_TXERRINT_ENABLE
+                       | TXQ_FLAG_TXDESCINT_ENABLE | TXQ_FLAG_TXURNINT_ENABLE;
+               qi->tqi_aifs = INIT_AIFS;
+               qi->tqi_cwmin = ATH9K_TXQ_USEDEFAULT;
+               qi->tqi_cwmax = INIT_CWMAX;
+               qi->tqi_shretry = INIT_SH_RETRY;
+               qi->tqi_lgretry = INIT_LG_RETRY;
+               qi->tqi_physCompBuf = 0;
+       } else {
+               qi->tqi_physCompBuf = qinfo->tqi_physCompBuf;
+               (void) ath9k_hw_set_txq_props(ah, q, qinfo);
+       }
+
+       return q;
+}
+
+bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q)
+{
+       struct ath9k_hw_capabilities *pCap = &ah->caps;
+       struct ath9k_tx_queue_info *qi;
+
+       if (q >= pCap->total_queues) {
+               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Release TXQ, "
+                       "invalid queue: %u\n", q);
+               return false;
+       }
+       qi = &ah->txq[q];
+       if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
+               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Release TXQ, "
+                       "inactive queue: %u\n", q);
+               return false;
+       }
+
+       DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Release TX queue: %u\n", q);
+
+       qi->tqi_type = ATH9K_TX_QUEUE_INACTIVE;
+       ah->txok_interrupt_mask &= ~(1 << q);
+       ah->txerr_interrupt_mask &= ~(1 << q);
+       ah->txdesc_interrupt_mask &= ~(1 << q);
+       ah->txeol_interrupt_mask &= ~(1 << q);
+       ah->txurn_interrupt_mask &= ~(1 << q);
+       ath9k_hw_set_txq_interrupts(ah, qi);
+
+       return true;
+}
+
+bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
+{
+       struct ath9k_hw_capabilities *pCap = &ah->caps;
+       struct ath9k_channel *chan = ah->curchan;
+       struct ath9k_tx_queue_info *qi;
+       u32 cwMin, chanCwMin, value;
+
+       if (q >= pCap->total_queues) {
+               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Reset TXQ, "
+                       "invalid queue: %u\n", q);
+               return false;
+       }
+
+       qi = &ah->txq[q];
+       if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
+               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Reset TXQ, "
+                       "inactive queue: %u\n", q);
+               return true;
+       }
+
+       DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "Reset TX queue: %u\n", q);
+
+       if (qi->tqi_cwmin == ATH9K_TXQ_USEDEFAULT) {
+               if (chan && IS_CHAN_B(chan))
+                       chanCwMin = INIT_CWMIN_11B;
+               else
+                       chanCwMin = INIT_CWMIN;
+
+               for (cwMin = 1; cwMin < chanCwMin; cwMin = (cwMin << 1) | 1);
+       } else
+               cwMin = qi->tqi_cwmin;
+
+       REG_WRITE(ah, AR_DLCL_IFS(q),
+                 SM(cwMin, AR_D_LCL_IFS_CWMIN) |
+                 SM(qi->tqi_cwmax, AR_D_LCL_IFS_CWMAX) |
+                 SM(qi->tqi_aifs, AR_D_LCL_IFS_AIFS));
+
+       REG_WRITE(ah, AR_DRETRY_LIMIT(q),
+                 SM(INIT_SSH_RETRY, AR_D_RETRY_LIMIT_STA_SH) |
+                 SM(INIT_SLG_RETRY, AR_D_RETRY_LIMIT_STA_LG) |
+                 SM(qi->tqi_shretry, AR_D_RETRY_LIMIT_FR_SH));
+
+       REG_WRITE(ah, AR_QMISC(q), AR_Q_MISC_DCU_EARLY_TERM_REQ);
+       REG_WRITE(ah, AR_DMISC(q),
+                 AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x2);
+
+       if (qi->tqi_cbrPeriod) {
+               REG_WRITE(ah, AR_QCBRCFG(q),
+                         SM(qi->tqi_cbrPeriod, AR_Q_CBRCFG_INTERVAL) |
+                         SM(qi->tqi_cbrOverflowLimit, AR_Q_CBRCFG_OVF_THRESH));
+               REG_WRITE(ah, AR_QMISC(q),
+                         REG_READ(ah, AR_QMISC(q)) | AR_Q_MISC_FSP_CBR |
+                         (qi->tqi_cbrOverflowLimit ?
+                          AR_Q_MISC_CBR_EXP_CNTR_LIMIT_EN : 0));
+       }
+       if (qi->tqi_readyTime && (qi->tqi_type != ATH9K_TX_QUEUE_CAB)) {
+               REG_WRITE(ah, AR_QRDYTIMECFG(q),
+                         SM(qi->tqi_readyTime, AR_Q_RDYTIMECFG_DURATION) |
+                         AR_Q_RDYTIMECFG_EN);
+       }
+
+       REG_WRITE(ah, AR_DCHNTIME(q),
+                 SM(qi->tqi_burstTime, AR_D_CHNTIME_DUR) |
+                 (qi->tqi_burstTime ? AR_D_CHNTIME_EN : 0));
+
+       if (qi->tqi_burstTime
+           && (qi->tqi_qflags & TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE)) {
+               REG_WRITE(ah, AR_QMISC(q),
+                         REG_READ(ah, AR_QMISC(q)) |
+                         AR_Q_MISC_RDYTIME_EXP_POLICY);
+
+       }
+
+       if (qi->tqi_qflags & TXQ_FLAG_BACKOFF_DISABLE) {
+               REG_WRITE(ah, AR_DMISC(q),
+                         REG_READ(ah, AR_DMISC(q)) |
+                         AR_D_MISC_POST_FR_BKOFF_DIS);
+       }
+       if (qi->tqi_qflags & TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE) {
+               REG_WRITE(ah, AR_DMISC(q),
+                         REG_READ(ah, AR_DMISC(q)) |
+                         AR_D_MISC_FRAG_BKOFF_EN);
+       }
+       switch (qi->tqi_type) {
+       case ATH9K_TX_QUEUE_BEACON:
+               REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q))
+                         | AR_Q_MISC_FSP_DBA_GATED
+                         | AR_Q_MISC_BEACON_USE
+                         | AR_Q_MISC_CBR_INCR_DIS1);
+
+               REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q))
+                         | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL <<
+                            AR_D_MISC_ARB_LOCKOUT_CNTRL_S)
+                         | AR_D_MISC_BEACON_USE
+                         | AR_D_MISC_POST_FR_BKOFF_DIS);
+               break;
+       case ATH9K_TX_QUEUE_CAB:
+               REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q))
+                         | AR_Q_MISC_FSP_DBA_GATED
+                         | AR_Q_MISC_CBR_INCR_DIS1
+                         | AR_Q_MISC_CBR_INCR_DIS0);
+               value = (qi->tqi_readyTime -
+                        (ah->config.sw_beacon_response_time -
+                         ah->config.dma_beacon_response_time) -
+                        ah->config.additional_swba_backoff) * 1024;
+               REG_WRITE(ah, AR_QRDYTIMECFG(q),
+                         value | AR_Q_RDYTIMECFG_EN);
+               REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q))
+                         | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL <<
+                            AR_D_MISC_ARB_LOCKOUT_CNTRL_S));
+               break;
+       case ATH9K_TX_QUEUE_PSPOLL:
+               REG_WRITE(ah, AR_QMISC(q),
+                         REG_READ(ah, AR_QMISC(q)) | AR_Q_MISC_CBR_INCR_DIS1);
+               break;
+       case ATH9K_TX_QUEUE_UAPSD:
+               REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q)) |
+                         AR_D_MISC_POST_FR_BKOFF_DIS);
+               break;
+       default:
+               break;
+       }
+
+       if (qi->tqi_intFlags & ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS) {
+               REG_WRITE(ah, AR_DMISC(q),
+                         REG_READ(ah, AR_DMISC(q)) |
+                         SM(AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL,
+                            AR_D_MISC_ARB_LOCKOUT_CNTRL) |
+                         AR_D_MISC_POST_FR_BKOFF_DIS);
+       }
+
+       if (qi->tqi_qflags & TXQ_FLAG_TXOKINT_ENABLE)
+               ah->txok_interrupt_mask |= 1 << q;
+       else
+               ah->txok_interrupt_mask &= ~(1 << q);
+       if (qi->tqi_qflags & TXQ_FLAG_TXERRINT_ENABLE)
+               ah->txerr_interrupt_mask |= 1 << q;
+       else
+               ah->txerr_interrupt_mask &= ~(1 << q);
+       if (qi->tqi_qflags & TXQ_FLAG_TXDESCINT_ENABLE)
+               ah->txdesc_interrupt_mask |= 1 << q;
+       else
+               ah->txdesc_interrupt_mask &= ~(1 << q);
+       if (qi->tqi_qflags & TXQ_FLAG_TXEOLINT_ENABLE)
+               ah->txeol_interrupt_mask |= 1 << q;
+       else
+               ah->txeol_interrupt_mask &= ~(1 << q);
+       if (qi->tqi_qflags & TXQ_FLAG_TXURNINT_ENABLE)
+               ah->txurn_interrupt_mask |= 1 << q;
+       else
+               ah->txurn_interrupt_mask &= ~(1 << q);
+       ath9k_hw_set_txq_interrupts(ah, qi);
+
+       return true;
+}
+
+int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
+                       u32 pa, struct ath_desc *nds, u64 tsf)
+{
+       struct ar5416_desc ads;
+       struct ar5416_desc *adsp = AR5416DESC(ds);
+       u32 phyerr;
+
+       if ((adsp->ds_rxstatus8 & AR_RxDone) == 0)
+               return -EINPROGRESS;
+
+       ads.u.rx = adsp->u.rx;
+
+       ds->ds_rxstat.rs_status = 0;
+       ds->ds_rxstat.rs_flags = 0;
+
+       ds->ds_rxstat.rs_datalen = ads.ds_rxstatus1 & AR_DataLen;
+       ds->ds_rxstat.rs_tstamp = ads.AR_RcvTimestamp;
+
+       ds->ds_rxstat.rs_rssi = MS(ads.ds_rxstatus4, AR_RxRSSICombined);
+       ds->ds_rxstat.rs_rssi_ctl0 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt00);
+       ds->ds_rxstat.rs_rssi_ctl1 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt01);
+       ds->ds_rxstat.rs_rssi_ctl2 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt02);
+       ds->ds_rxstat.rs_rssi_ext0 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt10);
+       ds->ds_rxstat.rs_rssi_ext1 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt11);
+       ds->ds_rxstat.rs_rssi_ext2 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt12);
+       if (ads.ds_rxstatus8 & AR_RxKeyIdxValid)
+               ds->ds_rxstat.rs_keyix = MS(ads.ds_rxstatus8, AR_KeyIdx);
+       else
+               ds->ds_rxstat.rs_keyix = ATH9K_RXKEYIX_INVALID;
+
+       ds->ds_rxstat.rs_rate = RXSTATUS_RATE(ah, (&ads));
+       ds->ds_rxstat.rs_more = (ads.ds_rxstatus1 & AR_RxMore) ? 1 : 0;
+
+       ds->ds_rxstat.rs_isaggr = (ads.ds_rxstatus8 & AR_RxAggr) ? 1 : 0;
+       ds->ds_rxstat.rs_moreaggr =
+               (ads.ds_rxstatus8 & AR_RxMoreAggr) ? 1 : 0;
+       ds->ds_rxstat.rs_antenna = MS(ads.ds_rxstatus3, AR_RxAntenna);
+       ds->ds_rxstat.rs_flags =
+               (ads.ds_rxstatus3 & AR_GI) ? ATH9K_RX_GI : 0;
+       ds->ds_rxstat.rs_flags |=
+               (ads.ds_rxstatus3 & AR_2040) ? ATH9K_RX_2040 : 0;
+
+       if (ads.ds_rxstatus8 & AR_PreDelimCRCErr)
+               ds->ds_rxstat.rs_flags |= ATH9K_RX_DELIM_CRC_PRE;
+       if (ads.ds_rxstatus8 & AR_PostDelimCRCErr)
+               ds->ds_rxstat.rs_flags |= ATH9K_RX_DELIM_CRC_POST;
+       if (ads.ds_rxstatus8 & AR_DecryptBusyErr)
+               ds->ds_rxstat.rs_flags |= ATH9K_RX_DECRYPT_BUSY;
+
+       if ((ads.ds_rxstatus8 & AR_RxFrameOK) == 0) {
+               if (ads.ds_rxstatus8 & AR_CRCErr)
+                       ds->ds_rxstat.rs_status |= ATH9K_RXERR_CRC;
+               else if (ads.ds_rxstatus8 & AR_PHYErr) {
+                       ds->ds_rxstat.rs_status |= ATH9K_RXERR_PHY;
+                       phyerr = MS(ads.ds_rxstatus8, AR_PHYErrCode);
+                       ds->ds_rxstat.rs_phyerr = phyerr;
+               } else if (ads.ds_rxstatus8 & AR_DecryptCRCErr)
+                       ds->ds_rxstat.rs_status |= ATH9K_RXERR_DECRYPT;
+               else if (ads.ds_rxstatus8 & AR_MichaelErr)
+                       ds->ds_rxstat.rs_status |= ATH9K_RXERR_MIC;
+       }
+
+       return 0;
+}
+
+bool ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds,
+                         u32 size, u32 flags)
+{
+       struct ar5416_desc *ads = AR5416DESC(ds);
+       struct ath9k_hw_capabilities *pCap = &ah->caps;
+
+       ads->ds_ctl1 = size & AR_BufLen;
+       if (flags & ATH9K_RXDESC_INTREQ)
+               ads->ds_ctl1 |= AR_RxIntrReq;
+
+       ads->ds_rxstatus8 &= ~AR_RxDone;
+       if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
+               memset(&(ads->u), 0, sizeof(ads->u));
+
+       return true;
+}
+
+bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set)
+{
+       u32 reg;
+
+       if (set) {
+               REG_SET_BIT(ah, AR_DIAG_SW,
+                           (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
+
+               if (!ath9k_hw_wait(ah, AR_OBS_BUS_1, AR_OBS_BUS_1_RX_STATE,
+                                  0, AH_WAIT_TIMEOUT)) {
+                       REG_CLR_BIT(ah, AR_DIAG_SW,
+                                   (AR_DIAG_RX_DIS |
+                                    AR_DIAG_RX_ABORT));
+
+                       reg = REG_READ(ah, AR_OBS_BUS_1);
+                       DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+                               "RX failed to go idle in 10 ms RXSM=0x%x\n", reg);
+
+                       return false;
+               }
+       } else {
+               REG_CLR_BIT(ah, AR_DIAG_SW,
+                           (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
+       }
+
+       return true;
+}
+
+void ath9k_hw_putrxbuf(struct ath_hw *ah, u32 rxdp)
+{
+       REG_WRITE(ah, AR_RXDP, rxdp);
+}
+
+void ath9k_hw_rxena(struct ath_hw *ah)
+{
+       REG_WRITE(ah, AR_CR, AR_CR_RXE);
+}
+
+void ath9k_hw_startpcureceive(struct ath_hw *ah)
+{
+       ath9k_enable_mib_counters(ah);
+
+       ath9k_ani_reset(ah);
+
+       REG_CLR_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
+}
+
+void ath9k_hw_stoppcurecv(struct ath_hw *ah)
+{
+       REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS);
+
+       ath9k_hw_disable_mib_counters(ah);
+}
+
+bool ath9k_hw_stopdmarecv(struct ath_hw *ah)
+{
+#define AH_RX_STOP_DMA_TIMEOUT 10000   /* usec */
+#define AH_RX_TIME_QUANTUM     100     /* usec */
+
+       int i;
+
+       REG_WRITE(ah, AR_CR, AR_CR_RXD);
+
+       /* Wait for rx enable bit to go low */
+       for (i = AH_RX_STOP_DMA_TIMEOUT / AH_TIME_QUANTUM; i != 0; i--) {
+               if ((REG_READ(ah, AR_CR) & AR_CR_RXE) == 0)
+                       break;
+               udelay(AH_TIME_QUANTUM);
+       }
+
+       if (i == 0) {
+               DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+                       "DMA failed to stop in %d ms "
+                       "AR_CR=0x%08x AR_DIAG_SW=0x%08x\n",
+                       AH_RX_STOP_DMA_TIMEOUT / 1000,
+                       REG_READ(ah, AR_CR),
+                       REG_READ(ah, AR_DIAG_SW));
+               return false;
+       } else {
+               return true;
+       }
+
+#undef AH_RX_TIME_QUANTUM
+#undef AH_RX_STOP_DMA_TIMEOUT
+}
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h
new file mode 100644 (file)
index 0000000..1176bce
--- /dev/null
@@ -0,0 +1,680 @@
+/*
+ * Copyright (c) 2008-2009 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 MAC_H
+#define MAC_H
+
+#define RXSTATUS_RATE(ah, ads) (AR_SREV_5416_20_OR_LATER(ah) ?         \
+                               MS(ads->ds_rxstatus0, AR_RxRate) :      \
+                               (ads->ds_rxstatus3 >> 2) & 0xFF)
+
+#define set11nTries(_series, _index) \
+       (SM((_series)[_index].Tries, AR_XmitDataTries##_index))
+
+#define set11nRate(_series, _index) \
+       (SM((_series)[_index].Rate, AR_XmitRate##_index))
+
+#define set11nPktDurRTSCTS(_series, _index)                            \
+       (SM((_series)[_index].PktDuration, AR_PacketDur##_index) |      \
+        ((_series)[_index].RateFlags & ATH9K_RATESERIES_RTS_CTS   ?    \
+         AR_RTSCTSQual##_index : 0))
+
+#define set11nRateFlags(_series, _index)                               \
+       (((_series)[_index].RateFlags & ATH9K_RATESERIES_2040 ?         \
+         AR_2040_##_index : 0)                                         \
+        |((_series)[_index].RateFlags & ATH9K_RATESERIES_HALFGI ?      \
+          AR_GI##_index : 0)                                           \
+        |SM((_series)[_index].ChSel, AR_ChainSel##_index))
+
+#define CCK_SIFS_TIME        10
+#define CCK_PREAMBLE_BITS   144
+#define CCK_PLCP_BITS        48
+
+#define OFDM_SIFS_TIME        16
+#define OFDM_PREAMBLE_TIME    20
+#define OFDM_PLCP_BITS        22
+#define OFDM_SYMBOL_TIME      4
+
+#define OFDM_SIFS_TIME_HALF     32
+#define OFDM_PREAMBLE_TIME_HALF 40
+#define OFDM_PLCP_BITS_HALF     22
+#define OFDM_SYMBOL_TIME_HALF   8
+
+#define OFDM_SIFS_TIME_QUARTER      64
+#define OFDM_PREAMBLE_TIME_QUARTER  80
+#define OFDM_PLCP_BITS_QUARTER      22
+#define OFDM_SYMBOL_TIME_QUARTER    16
+
+#define INIT_AIFS       2
+#define INIT_CWMIN      15
+#define INIT_CWMIN_11B  31
+#define INIT_CWMAX      1023
+#define INIT_SH_RETRY   10
+#define INIT_LG_RETRY   10
+#define INIT_SSH_RETRY  32
+#define INIT_SLG_RETRY  32
+
+#define ATH9K_SLOT_TIME_6 6
+#define ATH9K_SLOT_TIME_9 9
+#define ATH9K_SLOT_TIME_20 20
+
+#define ATH9K_TXERR_XRETRY         0x01
+#define ATH9K_TXERR_FILT           0x02
+#define ATH9K_TXERR_FIFO           0x04
+#define ATH9K_TXERR_XTXOP          0x08
+#define ATH9K_TXERR_TIMER_EXPIRED  0x10
+
+#define ATH9K_TX_BA                0x01
+#define ATH9K_TX_PWRMGMT           0x02
+#define ATH9K_TX_DESC_CFG_ERR      0x04
+#define ATH9K_TX_DATA_UNDERRUN     0x08
+#define ATH9K_TX_DELIM_UNDERRUN    0x10
+#define ATH9K_TX_SW_ABORTED        0x40
+#define ATH9K_TX_SW_FILTERED       0x80
+
+#define MIN_TX_FIFO_THRESHOLD   0x1
+#define MAX_TX_FIFO_THRESHOLD   ((4096 / 64) - 1)
+#define INIT_TX_FIFO_THRESHOLD  MIN_TX_FIFO_THRESHOLD
+
+struct ath_tx_status {
+       u32 ts_tstamp;
+       u16 ts_seqnum;
+       u8 ts_status;
+       u8 ts_ratecode;
+       u8 ts_rateindex;
+       int8_t ts_rssi;
+       u8 ts_shortretry;
+       u8 ts_longretry;
+       u8 ts_virtcol;
+       u8 ts_antenna;
+       u8 ts_flags;
+       int8_t ts_rssi_ctl0;
+       int8_t ts_rssi_ctl1;
+       int8_t ts_rssi_ctl2;
+       int8_t ts_rssi_ext0;
+       int8_t ts_rssi_ext1;
+       int8_t ts_rssi_ext2;
+       u8 pad[3];
+       u32 ba_low;
+       u32 ba_high;
+       u32 evm0;
+       u32 evm1;
+       u32 evm2;
+};
+
+struct ath_rx_status {
+       u32 rs_tstamp;
+       u16 rs_datalen;
+       u8 rs_status;
+       u8 rs_phyerr;
+       int8_t rs_rssi;
+       u8 rs_keyix;
+       u8 rs_rate;
+       u8 rs_antenna;
+       u8 rs_more;
+       int8_t rs_rssi_ctl0;
+       int8_t rs_rssi_ctl1;
+       int8_t rs_rssi_ctl2;
+       int8_t rs_rssi_ext0;
+       int8_t rs_rssi_ext1;
+       int8_t rs_rssi_ext2;
+       u8 rs_isaggr;
+       u8 rs_moreaggr;
+       u8 rs_num_delims;
+       u8 rs_flags;
+       u32 evm0;
+       u32 evm1;
+       u32 evm2;
+};
+
+#define ATH9K_RXERR_CRC           0x01
+#define ATH9K_RXERR_PHY           0x02
+#define ATH9K_RXERR_FIFO          0x04
+#define ATH9K_RXERR_DECRYPT       0x08
+#define ATH9K_RXERR_MIC           0x10
+
+#define ATH9K_RX_MORE             0x01
+#define ATH9K_RX_MORE_AGGR        0x02
+#define ATH9K_RX_GI               0x04
+#define ATH9K_RX_2040             0x08
+#define ATH9K_RX_DELIM_CRC_PRE    0x10
+#define ATH9K_RX_DELIM_CRC_POST   0x20
+#define ATH9K_RX_DECRYPT_BUSY     0x40
+
+#define ATH9K_RXKEYIX_INVALID  ((u8)-1)
+#define ATH9K_TXKEYIX_INVALID  ((u32)-1)
+
+struct ath_desc {
+       u32 ds_link;
+       u32 ds_data;
+       u32 ds_ctl0;
+       u32 ds_ctl1;
+       u32 ds_hw[20];
+       union {
+               struct ath_tx_status tx;
+               struct ath_rx_status rx;
+               void *stats;
+       } ds_us;
+       void *ds_vdata;
+} __packed;
+
+#define        ds_txstat       ds_us.tx
+#define        ds_rxstat       ds_us.rx
+#define ds_stat                ds_us.stats
+
+#define ATH9K_TXDESC_CLRDMASK          0x0001
+#define ATH9K_TXDESC_NOACK             0x0002
+#define ATH9K_TXDESC_RTSENA            0x0004
+#define ATH9K_TXDESC_CTSENA            0x0008
+/* ATH9K_TXDESC_INTREQ forces a tx interrupt to be generated for
+ * the descriptor its marked on.  We take a tx interrupt to reap
+ * descriptors when the h/w hits an EOL condition or
+ * when the descriptor is specifically marked to generate
+ * an interrupt with this flag. Descriptors should be
+ * marked periodically to insure timely replenishing of the
+ * supply needed for sending frames. Defering interrupts
+ * reduces system load and potentially allows more concurrent
+ * work to be done but if done to aggressively can cause
+ * senders to backup. When the hardware queue is left too
+ * large rate control information may also be too out of
+ * date. An Alternative for this is TX interrupt mitigation
+ * but this needs more testing. */
+#define ATH9K_TXDESC_INTREQ            0x0010
+#define ATH9K_TXDESC_VEOL              0x0020
+#define ATH9K_TXDESC_EXT_ONLY          0x0040
+#define ATH9K_TXDESC_EXT_AND_CTL       0x0080
+#define ATH9K_TXDESC_VMF               0x0100
+#define ATH9K_TXDESC_FRAG_IS_ON        0x0200
+#define ATH9K_TXDESC_CAB               0x0400
+
+#define ATH9K_RXDESC_INTREQ            0x0020
+
+struct ar5416_desc {
+       u32 ds_link;
+       u32 ds_data;
+       u32 ds_ctl0;
+       u32 ds_ctl1;
+       union {
+               struct {
+                       u32 ctl2;
+                       u32 ctl3;
+                       u32 ctl4;
+                       u32 ctl5;
+                       u32 ctl6;
+                       u32 ctl7;
+                       u32 ctl8;
+                       u32 ctl9;
+                       u32 ctl10;
+                       u32 ctl11;
+                       u32 status0;
+                       u32 status1;
+                       u32 status2;
+                       u32 status3;
+                       u32 status4;
+                       u32 status5;
+                       u32 status6;
+                       u32 status7;
+                       u32 status8;
+                       u32 status9;
+               } tx;
+               struct {
+                       u32 status0;
+                       u32 status1;
+                       u32 status2;
+                       u32 status3;
+                       u32 status4;
+                       u32 status5;
+                       u32 status6;
+                       u32 status7;
+                       u32 status8;
+               } rx;
+       } u;
+} __packed;
+
+#define AR5416DESC(_ds)         ((struct ar5416_desc *)(_ds))
+#define AR5416DESC_CONST(_ds)   ((const struct ar5416_desc *)(_ds))
+
+#define ds_ctl2     u.tx.ctl2
+#define ds_ctl3     u.tx.ctl3
+#define ds_ctl4     u.tx.ctl4
+#define ds_ctl5     u.tx.ctl5
+#define ds_ctl6     u.tx.ctl6
+#define ds_ctl7     u.tx.ctl7
+#define ds_ctl8     u.tx.ctl8
+#define ds_ctl9     u.tx.ctl9
+#define ds_ctl10    u.tx.ctl10
+#define ds_ctl11    u.tx.ctl11
+
+#define ds_txstatus0    u.tx.status0
+#define ds_txstatus1    u.tx.status1
+#define ds_txstatus2    u.tx.status2
+#define ds_txstatus3    u.tx.status3
+#define ds_txstatus4    u.tx.status4
+#define ds_txstatus5    u.tx.status5
+#define ds_txstatus6    u.tx.status6
+#define ds_txstatus7    u.tx.status7
+#define ds_txstatus8    u.tx.status8
+#define ds_txstatus9    u.tx.status9
+
+#define ds_rxstatus0    u.rx.status0
+#define ds_rxstatus1    u.rx.status1
+#define ds_rxstatus2    u.rx.status2
+#define ds_rxstatus3    u.rx.status3
+#define ds_rxstatus4    u.rx.status4
+#define ds_rxstatus5    u.rx.status5
+#define ds_rxstatus6    u.rx.status6
+#define ds_rxstatus7    u.rx.status7
+#define ds_rxstatus8    u.rx.status8
+
+#define AR_FrameLen         0x00000fff
+#define AR_VirtMoreFrag     0x00001000
+#define AR_TxCtlRsvd00      0x0000e000
+#define AR_XmitPower        0x003f0000
+#define AR_XmitPower_S      16
+#define AR_RTSEnable        0x00400000
+#define AR_VEOL             0x00800000
+#define AR_ClrDestMask      0x01000000
+#define AR_TxCtlRsvd01      0x1e000000
+#define AR_TxIntrReq        0x20000000
+#define AR_DestIdxValid     0x40000000
+#define AR_CTSEnable        0x80000000
+
+#define AR_BufLen           0x00000fff
+#define AR_TxMore           0x00001000
+#define AR_DestIdx          0x000fe000
+#define AR_DestIdx_S        13
+#define AR_FrameType        0x00f00000
+#define AR_FrameType_S      20
+#define AR_NoAck            0x01000000
+#define AR_InsertTS         0x02000000
+#define AR_CorruptFCS       0x04000000
+#define AR_ExtOnly          0x08000000
+#define AR_ExtAndCtl        0x10000000
+#define AR_MoreAggr         0x20000000
+#define AR_IsAggr           0x40000000
+
+#define AR_BurstDur         0x00007fff
+#define AR_BurstDur_S       0
+#define AR_DurUpdateEna     0x00008000
+#define AR_XmitDataTries0   0x000f0000
+#define AR_XmitDataTries0_S 16
+#define AR_XmitDataTries1   0x00f00000
+#define AR_XmitDataTries1_S 20
+#define AR_XmitDataTries2   0x0f000000
+#define AR_XmitDataTries2_S 24
+#define AR_XmitDataTries3   0xf0000000
+#define AR_XmitDataTries3_S 28
+
+#define AR_XmitRate0        0x000000ff
+#define AR_XmitRate0_S      0
+#define AR_XmitRate1        0x0000ff00
+#define AR_XmitRate1_S      8
+#define AR_XmitRate2        0x00ff0000
+#define AR_XmitRate2_S      16
+#define AR_XmitRate3        0xff000000
+#define AR_XmitRate3_S      24
+
+#define AR_PacketDur0       0x00007fff
+#define AR_PacketDur0_S     0
+#define AR_RTSCTSQual0      0x00008000
+#define AR_PacketDur1       0x7fff0000
+#define AR_PacketDur1_S     16
+#define AR_RTSCTSQual1      0x80000000
+
+#define AR_PacketDur2       0x00007fff
+#define AR_PacketDur2_S     0
+#define AR_RTSCTSQual2      0x00008000
+#define AR_PacketDur3       0x7fff0000
+#define AR_PacketDur3_S     16
+#define AR_RTSCTSQual3      0x80000000
+
+#define AR_AggrLen          0x0000ffff
+#define AR_AggrLen_S        0
+#define AR_TxCtlRsvd60      0x00030000
+#define AR_PadDelim         0x03fc0000
+#define AR_PadDelim_S       18
+#define AR_EncrType         0x0c000000
+#define AR_EncrType_S       26
+#define AR_TxCtlRsvd61      0xf0000000
+
+#define AR_2040_0           0x00000001
+#define AR_GI0              0x00000002
+#define AR_ChainSel0        0x0000001c
+#define AR_ChainSel0_S      2
+#define AR_2040_1           0x00000020
+#define AR_GI1              0x00000040
+#define AR_ChainSel1        0x00000380
+#define AR_ChainSel1_S      7
+#define AR_2040_2           0x00000400
+#define AR_GI2              0x00000800
+#define AR_ChainSel2        0x00007000
+#define AR_ChainSel2_S      12
+#define AR_2040_3           0x00008000
+#define AR_GI3              0x00010000
+#define AR_ChainSel3        0x000e0000
+#define AR_ChainSel3_S      17
+#define AR_RTSCTSRate       0x0ff00000
+#define AR_RTSCTSRate_S     20
+#define AR_TxCtlRsvd70      0xf0000000
+
+#define AR_TxRSSIAnt00      0x000000ff
+#define AR_TxRSSIAnt00_S    0
+#define AR_TxRSSIAnt01      0x0000ff00
+#define AR_TxRSSIAnt01_S    8
+#define AR_TxRSSIAnt02      0x00ff0000
+#define AR_TxRSSIAnt02_S    16
+#define AR_TxStatusRsvd00   0x3f000000
+#define AR_TxBaStatus       0x40000000
+#define AR_TxStatusRsvd01   0x80000000
+
+#define AR_FrmXmitOK            0x00000001
+#define AR_ExcessiveRetries     0x00000002
+#define AR_FIFOUnderrun         0x00000004
+#define AR_Filtered             0x00000008
+#define AR_RTSFailCnt           0x000000f0
+#define AR_RTSFailCnt_S         4
+#define AR_DataFailCnt          0x00000f00
+#define AR_DataFailCnt_S        8
+#define AR_VirtRetryCnt         0x0000f000
+#define AR_VirtRetryCnt_S       12
+#define AR_TxDelimUnderrun      0x00010000
+#define AR_TxDataUnderrun       0x00020000
+#define AR_DescCfgErr           0x00040000
+#define AR_TxTimerExpired       0x00080000
+#define AR_TxStatusRsvd10       0xfff00000
+
+#define AR_SendTimestamp    ds_txstatus2
+#define AR_BaBitmapLow      ds_txstatus3
+#define AR_BaBitmapHigh     ds_txstatus4
+
+#define AR_TxRSSIAnt10      0x000000ff
+#define AR_TxRSSIAnt10_S    0
+#define AR_TxRSSIAnt11      0x0000ff00
+#define AR_TxRSSIAnt11_S    8
+#define AR_TxRSSIAnt12      0x00ff0000
+#define AR_TxRSSIAnt12_S    16
+#define AR_TxRSSICombined   0xff000000
+#define AR_TxRSSICombined_S 24
+
+#define AR_TxEVM0           ds_txstatus5
+#define AR_TxEVM1           ds_txstatus6
+#define AR_TxEVM2           ds_txstatus7
+
+#define AR_TxDone           0x00000001
+#define AR_SeqNum           0x00001ffe
+#define AR_SeqNum_S         1
+#define AR_TxStatusRsvd80   0x0001e000
+#define AR_TxOpExceeded     0x00020000
+#define AR_TxStatusRsvd81   0x001c0000
+#define AR_FinalTxIdx       0x00600000
+#define AR_FinalTxIdx_S     21
+#define AR_TxStatusRsvd82   0x01800000
+#define AR_PowerMgmt        0x02000000
+#define AR_TxStatusRsvd83   0xfc000000
+
+#define AR_RxCTLRsvd00  0xffffffff
+
+#define AR_BufLen       0x00000fff
+#define AR_RxCtlRsvd00  0x00001000
+#define AR_RxIntrReq    0x00002000
+#define AR_RxCtlRsvd01  0xffffc000
+
+#define AR_RxRSSIAnt00      0x000000ff
+#define AR_RxRSSIAnt00_S    0
+#define AR_RxRSSIAnt01      0x0000ff00
+#define AR_RxRSSIAnt01_S    8
+#define AR_RxRSSIAnt02      0x00ff0000
+#define AR_RxRSSIAnt02_S    16
+#define AR_RxRate           0xff000000
+#define AR_RxRate_S         24
+#define AR_RxStatusRsvd00   0xff000000
+
+#define AR_DataLen          0x00000fff
+#define AR_RxMore           0x00001000
+#define AR_NumDelim         0x003fc000
+#define AR_NumDelim_S       14
+#define AR_RxStatusRsvd10   0xff800000
+
+#define AR_RcvTimestamp     ds_rxstatus2
+
+#define AR_GI               0x00000001
+#define AR_2040             0x00000002
+#define AR_Parallel40       0x00000004
+#define AR_Parallel40_S     2
+#define AR_RxStatusRsvd30   0x000000f8
+#define AR_RxAntenna       0xffffff00
+#define AR_RxAntenna_S     8
+
+#define AR_RxRSSIAnt10            0x000000ff
+#define AR_RxRSSIAnt10_S          0
+#define AR_RxRSSIAnt11            0x0000ff00
+#define AR_RxRSSIAnt11_S          8
+#define AR_RxRSSIAnt12            0x00ff0000
+#define AR_RxRSSIAnt12_S          16
+#define AR_RxRSSICombined         0xff000000
+#define AR_RxRSSICombined_S       24
+
+#define AR_RxEVM0           ds_rxstatus4
+#define AR_RxEVM1           ds_rxstatus5
+#define AR_RxEVM2           ds_rxstatus6
+
+#define AR_RxDone           0x00000001
+#define AR_RxFrameOK        0x00000002
+#define AR_CRCErr           0x00000004
+#define AR_DecryptCRCErr    0x00000008
+#define AR_PHYErr           0x00000010
+#define AR_MichaelErr       0x00000020
+#define AR_PreDelimCRCErr   0x00000040
+#define AR_RxStatusRsvd70   0x00000080
+#define AR_RxKeyIdxValid    0x00000100
+#define AR_KeyIdx           0x0000fe00
+#define AR_KeyIdx_S         9
+#define AR_PHYErrCode       0x0000ff00
+#define AR_PHYErrCode_S     8
+#define AR_RxMoreAggr       0x00010000
+#define AR_RxAggr           0x00020000
+#define AR_PostDelimCRCErr  0x00040000
+#define AR_RxStatusRsvd71   0x3ff80000
+#define AR_DecryptBusyErr   0x40000000
+#define AR_KeyMiss          0x80000000
+
+enum ath9k_tx_queue {
+       ATH9K_TX_QUEUE_INACTIVE = 0,
+       ATH9K_TX_QUEUE_DATA,
+       ATH9K_TX_QUEUE_BEACON,
+       ATH9K_TX_QUEUE_CAB,
+       ATH9K_TX_QUEUE_UAPSD,
+       ATH9K_TX_QUEUE_PSPOLL
+};
+
+#define        ATH9K_NUM_TX_QUEUES 10
+
+enum ath9k_tx_queue_subtype {
+       ATH9K_WME_AC_BK = 0,
+       ATH9K_WME_AC_BE,
+       ATH9K_WME_AC_VI,
+       ATH9K_WME_AC_VO,
+       ATH9K_WME_UPSD
+};
+
+enum ath9k_tx_queue_flags {
+       TXQ_FLAG_TXOKINT_ENABLE = 0x0001,
+       TXQ_FLAG_TXERRINT_ENABLE = 0x0001,
+       TXQ_FLAG_TXDESCINT_ENABLE = 0x0002,
+       TXQ_FLAG_TXEOLINT_ENABLE = 0x0004,
+       TXQ_FLAG_TXURNINT_ENABLE = 0x0008,
+       TXQ_FLAG_BACKOFF_DISABLE = 0x0010,
+       TXQ_FLAG_COMPRESSION_ENABLE = 0x0020,
+       TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE = 0x0040,
+       TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE = 0x0080,
+};
+
+#define ATH9K_TXQ_USEDEFAULT ((u32) -1)
+#define ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS 0x00000001
+
+#define ATH9K_DECOMP_MASK_SIZE     128
+#define ATH9K_READY_TIME_LO_BOUND  50
+#define ATH9K_READY_TIME_HI_BOUND  96
+
+enum ath9k_pkt_type {
+       ATH9K_PKT_TYPE_NORMAL = 0,
+       ATH9K_PKT_TYPE_ATIM,
+       ATH9K_PKT_TYPE_PSPOLL,
+       ATH9K_PKT_TYPE_BEACON,
+       ATH9K_PKT_TYPE_PROBE_RESP,
+       ATH9K_PKT_TYPE_CHIRP,
+       ATH9K_PKT_TYPE_GRP_POLL,
+};
+
+struct ath9k_tx_queue_info {
+       u32 tqi_ver;
+       enum ath9k_tx_queue tqi_type;
+       enum ath9k_tx_queue_subtype tqi_subtype;
+       enum ath9k_tx_queue_flags tqi_qflags;
+       u32 tqi_priority;
+       u32 tqi_aifs;
+       u32 tqi_cwmin;
+       u32 tqi_cwmax;
+       u16 tqi_shretry;
+       u16 tqi_lgretry;
+       u32 tqi_cbrPeriod;
+       u32 tqi_cbrOverflowLimit;
+       u32 tqi_burstTime;
+       u32 tqi_readyTime;
+       u32 tqi_physCompBuf;
+       u32 tqi_intFlags;
+};
+
+enum ath9k_rx_filter {
+       ATH9K_RX_FILTER_UCAST = 0x00000001,
+       ATH9K_RX_FILTER_MCAST = 0x00000002,
+       ATH9K_RX_FILTER_BCAST = 0x00000004,
+       ATH9K_RX_FILTER_CONTROL = 0x00000008,
+       ATH9K_RX_FILTER_BEACON = 0x00000010,
+       ATH9K_RX_FILTER_PROM = 0x00000020,
+       ATH9K_RX_FILTER_PROBEREQ = 0x00000080,
+       ATH9K_RX_FILTER_PHYERR = 0x00000100,
+       ATH9K_RX_FILTER_MYBEACON = 0x00000200,
+       ATH9K_RX_FILTER_PSPOLL = 0x00004000,
+       ATH9K_RX_FILTER_PHYRADAR = 0x00002000,
+       ATH9K_RX_FILTER_MCAST_BCAST_ALL = 0x00008000,
+};
+
+#define ATH9K_RATESERIES_RTS_CTS  0x0001
+#define ATH9K_RATESERIES_2040     0x0002
+#define ATH9K_RATESERIES_HALFGI   0x0004
+
+struct ath9k_11n_rate_series {
+       u32 Tries;
+       u32 Rate;
+       u32 PktDuration;
+       u32 ChSel;
+       u32 RateFlags;
+};
+
+struct ath9k_keyval {
+       u8 kv_type;
+       u8 kv_pad;
+       u16 kv_len;
+       u8 kv_val[16]; /* TK */
+       u8 kv_mic[8]; /* Michael MIC key */
+       u8 kv_txmic[8]; /* Michael MIC TX key (used only if the hardware
+                        * supports both MIC keys in the same key cache entry;
+                        * in that case, kv_mic is the RX key) */
+};
+
+enum ath9k_key_type {
+       ATH9K_KEY_TYPE_CLEAR,
+       ATH9K_KEY_TYPE_WEP,
+       ATH9K_KEY_TYPE_AES,
+       ATH9K_KEY_TYPE_TKIP,
+};
+
+enum ath9k_cipher {
+       ATH9K_CIPHER_WEP = 0,
+       ATH9K_CIPHER_AES_OCB = 1,
+       ATH9K_CIPHER_AES_CCM = 2,
+       ATH9K_CIPHER_CKIP = 3,
+       ATH9K_CIPHER_TKIP = 4,
+       ATH9K_CIPHER_CLR = 5,
+       ATH9K_CIPHER_MIC = 127
+};
+
+enum ath9k_ht_macmode {
+       ATH9K_HT_MACMODE_20 = 0,
+       ATH9K_HT_MACMODE_2040 = 1,
+};
+
+enum ath9k_ht_extprotspacing {
+       ATH9K_HT_EXTPROTSPACING_20 = 0,
+       ATH9K_HT_EXTPROTSPACING_25 = 1,
+};
+
+struct ath_hw;
+struct ath9k_channel;
+struct ath_rate_table;
+
+u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q);
+bool ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp);
+bool ath9k_hw_txstart(struct ath_hw *ah, u32 q);
+u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q);
+bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel);
+bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q);
+bool ath9k_hw_filltxdesc(struct ath_hw *ah, struct ath_desc *ds,
+                        u32 segLen, bool firstSeg,
+                        bool lastSeg, const struct ath_desc *ds0);
+void ath9k_hw_cleartxdesc(struct ath_hw *ah, struct ath_desc *ds);
+int ath9k_hw_txprocdesc(struct ath_hw *ah, struct ath_desc *ds);
+void ath9k_hw_set11n_txdesc(struct ath_hw *ah, struct ath_desc *ds,
+                           u32 pktLen, enum ath9k_pkt_type type, u32 txPower,
+                           u32 keyIx, enum ath9k_key_type keyType, u32 flags);
+void ath9k_hw_set11n_ratescenario(struct ath_hw *ah, struct ath_desc *ds,
+                                 struct ath_desc *lastds,
+                                 u32 durUpdateEn, u32 rtsctsRate,
+                                 u32 rtsctsDuration,
+                                 struct ath9k_11n_rate_series series[],
+                                 u32 nseries, u32 flags);
+void ath9k_hw_set11n_aggr_first(struct ath_hw *ah, struct ath_desc *ds,
+                               u32 aggrLen);
+void ath9k_hw_set11n_aggr_middle(struct ath_hw *ah, struct ath_desc *ds,
+                                u32 numDelims);
+void ath9k_hw_set11n_aggr_last(struct ath_hw *ah, struct ath_desc *ds);
+void ath9k_hw_clr11n_aggr(struct ath_hw *ah, struct ath_desc *ds);
+void ath9k_hw_set11n_burstduration(struct ath_hw *ah, struct ath_desc *ds,
+                                  u32 burstDuration);
+void ath9k_hw_set11n_virtualmorefrag(struct ath_hw *ah, struct ath_desc *ds,
+                                    u32 vmf);
+void ath9k_hw_gettxintrtxqs(struct ath_hw *ah, u32 *txqs);
+bool ath9k_hw_set_txq_props(struct ath_hw *ah, int q,
+                           const struct ath9k_tx_queue_info *qinfo);
+bool ath9k_hw_get_txq_props(struct ath_hw *ah, int q,
+                           struct ath9k_tx_queue_info *qinfo);
+int ath9k_hw_setuptxqueue(struct ath_hw *ah, enum ath9k_tx_queue type,
+                         const struct ath9k_tx_queue_info *qinfo);
+bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q);
+bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q);
+int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
+                       u32 pa, struct ath_desc *nds, u64 tsf);
+bool ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds,
+                         u32 size, u32 flags);
+bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set);
+void ath9k_hw_putrxbuf(struct ath_hw *ah, u32 rxdp);
+void ath9k_hw_rxena(struct ath_hw *ah);
+void ath9k_hw_startpcureceive(struct ath_hw *ah);
+void ath9k_hw_stoppcurecv(struct ath_hw *ah);
+bool ath9k_hw_stopdmarecv(struct ath_hw *ah);
+
+#endif /* MAC_H */
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
new file mode 100644 (file)
index 0000000..f7baa40
--- /dev/null
@@ -0,0 +1,2885 @@
+/*
+ * Copyright (c) 2008-2009 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/nl80211.h>
+#include "ath9k.h"
+
+#define ATH_PCI_VERSION "0.1"
+
+static char *dev_info = "ath9k";
+
+MODULE_AUTHOR("Atheros Communications");
+MODULE_DESCRIPTION("Support for Atheros 802.11n wireless LAN cards.");
+MODULE_SUPPORTED_DEVICE("Atheros 802.11n WLAN cards");
+MODULE_LICENSE("Dual BSD/GPL");
+
+static int modparam_nohwcrypt;
+module_param_named(nohwcrypt, modparam_nohwcrypt, int, 0444);
+MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption");
+
+/* We use the hw_value as an index into our private channel structure */
+
+#define CHAN2G(_freq, _idx)  { \
+       .center_freq = (_freq), \
+       .hw_value = (_idx), \
+       .max_power = 20, \
+}
+
+#define CHAN5G(_freq, _idx) { \
+       .band = IEEE80211_BAND_5GHZ, \
+       .center_freq = (_freq), \
+       .hw_value = (_idx), \
+       .max_power = 20, \
+}
+
+/* Some 2 GHz radios are actually tunable on 2312-2732
+ * on 5 MHz steps, we support the channels which we know
+ * we have calibration data for all cards though to make
+ * this static */
+static struct ieee80211_channel ath9k_2ghz_chantable[] = {
+       CHAN2G(2412, 0), /* Channel 1 */
+       CHAN2G(2417, 1), /* Channel 2 */
+       CHAN2G(2422, 2), /* Channel 3 */
+       CHAN2G(2427, 3), /* Channel 4 */
+       CHAN2G(2432, 4), /* Channel 5 */
+       CHAN2G(2437, 5), /* Channel 6 */
+       CHAN2G(2442, 6), /* Channel 7 */
+       CHAN2G(2447, 7), /* Channel 8 */
+       CHAN2G(2452, 8), /* Channel 9 */
+       CHAN2G(2457, 9), /* Channel 10 */
+       CHAN2G(2462, 10), /* Channel 11 */
+       CHAN2G(2467, 11), /* Channel 12 */
+       CHAN2G(2472, 12), /* Channel 13 */
+       CHAN2G(2484, 13), /* Channel 14 */
+};
+
+/* Some 5 GHz radios are actually tunable on XXXX-YYYY
+ * on 5 MHz steps, we support the channels which we know
+ * we have calibration data for all cards though to make
+ * this static */
+static struct ieee80211_channel ath9k_5ghz_chantable[] = {
+       /* _We_ call this UNII 1 */
+       CHAN5G(5180, 14), /* Channel 36 */
+       CHAN5G(5200, 15), /* Channel 40 */
+       CHAN5G(5220, 16), /* Channel 44 */
+       CHAN5G(5240, 17), /* Channel 48 */
+       /* _We_ call this UNII 2 */
+       CHAN5G(5260, 18), /* Channel 52 */
+       CHAN5G(5280, 19), /* Channel 56 */
+       CHAN5G(5300, 20), /* Channel 60 */
+       CHAN5G(5320, 21), /* Channel 64 */
+       /* _We_ call this "Middle band" */
+       CHAN5G(5500, 22), /* Channel 100 */
+       CHAN5G(5520, 23), /* Channel 104 */
+       CHAN5G(5540, 24), /* Channel 108 */
+       CHAN5G(5560, 25), /* Channel 112 */
+       CHAN5G(5580, 26), /* Channel 116 */
+       CHAN5G(5600, 27), /* Channel 120 */
+       CHAN5G(5620, 28), /* Channel 124 */
+       CHAN5G(5640, 29), /* Channel 128 */
+       CHAN5G(5660, 30), /* Channel 132 */
+       CHAN5G(5680, 31), /* Channel 136 */
+       CHAN5G(5700, 32), /* Channel 140 */
+       /* _We_ call this UNII 3 */
+       CHAN5G(5745, 33), /* Channel 149 */
+       CHAN5G(5765, 34), /* Channel 153 */
+       CHAN5G(5785, 35), /* Channel 157 */
+       CHAN5G(5805, 36), /* Channel 161 */
+       CHAN5G(5825, 37), /* Channel 165 */
+};
+
+static void ath_cache_conf_rate(struct ath_softc *sc,
+                               struct ieee80211_conf *conf)
+{
+       switch (conf->channel->band) {
+       case IEEE80211_BAND_2GHZ:
+               if (conf_is_ht20(conf))
+                       sc->cur_rate_table =
+                         sc->hw_rate_table[ATH9K_MODE_11NG_HT20];
+               else if (conf_is_ht40_minus(conf))
+                       sc->cur_rate_table =
+                         sc->hw_rate_table[ATH9K_MODE_11NG_HT40MINUS];
+               else if (conf_is_ht40_plus(conf))
+                       sc->cur_rate_table =
+                         sc->hw_rate_table[ATH9K_MODE_11NG_HT40PLUS];
+               else
+                       sc->cur_rate_table =
+                         sc->hw_rate_table[ATH9K_MODE_11G];
+               break;
+       case IEEE80211_BAND_5GHZ:
+               if (conf_is_ht20(conf))
+                       sc->cur_rate_table =
+                         sc->hw_rate_table[ATH9K_MODE_11NA_HT20];
+               else if (conf_is_ht40_minus(conf))
+                       sc->cur_rate_table =
+                         sc->hw_rate_table[ATH9K_MODE_11NA_HT40MINUS];
+               else if (conf_is_ht40_plus(conf))
+                       sc->cur_rate_table =
+                         sc->hw_rate_table[ATH9K_MODE_11NA_HT40PLUS];
+               else
+                       sc->cur_rate_table =
+                         sc->hw_rate_table[ATH9K_MODE_11A];
+               break;
+       default:
+               BUG_ON(1);
+               break;
+       }
+}
+
+static void ath_update_txpow(struct ath_softc *sc)
+{
+       struct ath_hw *ah = sc->sc_ah;
+       u32 txpow;
+
+       if (sc->curtxpow != sc->config.txpowlimit) {
+               ath9k_hw_set_txpowerlimit(ah, sc->config.txpowlimit);
+               /* read back in case value is clamped */
+               ath9k_hw_getcapability(ah, ATH9K_CAP_TXPOW, 1, &txpow);
+               sc->curtxpow = txpow;
+       }
+}
+
+static u8 parse_mpdudensity(u8 mpdudensity)
+{
+       /*
+        * 802.11n D2.0 defined values for "Minimum MPDU Start Spacing":
+        *   0 for no restriction
+        *   1 for 1/4 us
+        *   2 for 1/2 us
+        *   3 for 1 us
+        *   4 for 2 us
+        *   5 for 4 us
+        *   6 for 8 us
+        *   7 for 16 us
+        */
+       switch (mpdudensity) {
+       case 0:
+               return 0;
+       case 1:
+       case 2:
+       case 3:
+               /* Our lower layer calculations limit our precision to
+                  1 microsecond */
+               return 1;
+       case 4:
+               return 2;
+       case 5:
+               return 4;
+       case 6:
+               return 8;
+       case 7:
+               return 16;
+       default:
+               return 0;
+       }
+}
+
+static void ath_setup_rates(struct ath_softc *sc, enum ieee80211_band band)
+{
+       const struct ath_rate_table *rate_table = NULL;
+       struct ieee80211_supported_band *sband;
+       struct ieee80211_rate *rate;
+       int i, maxrates;
+
+       switch (band) {
+       case IEEE80211_BAND_2GHZ:
+               rate_table = sc->hw_rate_table[ATH9K_MODE_11G];
+               break;
+       case IEEE80211_BAND_5GHZ:
+               rate_table = sc->hw_rate_table[ATH9K_MODE_11A];
+               break;
+       default:
+               break;
+       }
+
+       if (rate_table == NULL)
+               return;
+
+       sband = &sc->sbands[band];
+       rate = sc->rates[band];
+
+       if (rate_table->rate_cnt > ATH_RATE_MAX)
+               maxrates = ATH_RATE_MAX;
+       else
+               maxrates = rate_table->rate_cnt;
+
+       for (i = 0; i < maxrates; i++) {
+               rate[i].bitrate = rate_table->info[i].ratekbps / 100;
+               rate[i].hw_value = rate_table->info[i].ratecode;
+               if (rate_table->info[i].short_preamble) {
+                       rate[i].hw_value_short = rate_table->info[i].ratecode |
+                               rate_table->info[i].short_preamble;
+                       rate[i].flags = IEEE80211_RATE_SHORT_PREAMBLE;
+               }
+               sband->n_bitrates++;
+
+               DPRINTF(sc, ATH_DBG_CONFIG, "Rate: %2dMbps, ratecode: %2d\n",
+                       rate[i].bitrate / 10, rate[i].hw_value);
+       }
+}
+
+/*
+ * Set/change channels.  If the channel is really being changed, it's done
+ * by reseting the chip.  To accomplish this we must first cleanup any pending
+ * DMA, then restart stuff.
+*/
+int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
+                   struct ath9k_channel *hchan)
+{
+       struct ath_hw *ah = sc->sc_ah;
+       bool fastcc = true, stopped;
+       struct ieee80211_channel *channel = hw->conf.channel;
+       int r;
+
+       if (sc->sc_flags & SC_OP_INVALID)
+               return -EIO;
+
+       ath9k_ps_wakeup(sc);
+
+       /*
+        * This is only performed if the channel settings have
+        * actually changed.
+        *
+        * To switch channels clear any pending DMA operations;
+        * wait long enough for the RX fifo to drain, reset the
+        * hardware at the new frequency, and then re-enable
+        * the relevant bits of the h/w.
+        */
+       ath9k_hw_set_interrupts(ah, 0);
+       ath_drain_all_txq(sc, false);
+       stopped = ath_stoprecv(sc);
+
+       /* XXX: do not flush receive queue here. We don't want
+        * to flush data frames already in queue because of
+        * changing channel. */
+
+       if (!stopped || (sc->sc_flags & SC_OP_FULL_RESET))
+               fastcc = false;
+
+       DPRINTF(sc, ATH_DBG_CONFIG,
+               "(%u MHz) -> (%u MHz), chanwidth: %d\n",
+               sc->sc_ah->curchan->channel,
+               channel->center_freq, sc->tx_chan_width);
+
+       spin_lock_bh(&sc->sc_resetlock);
+
+       r = ath9k_hw_reset(ah, hchan, fastcc);
+       if (r) {
+               DPRINTF(sc, ATH_DBG_FATAL,
+                       "Unable to reset channel (%u Mhz) "
+                       "reset status %d\n",
+                       channel->center_freq, r);
+               spin_unlock_bh(&sc->sc_resetlock);
+               return r;
+       }
+       spin_unlock_bh(&sc->sc_resetlock);
+
+       sc->sc_flags &= ~SC_OP_FULL_RESET;
+
+       if (ath_startrecv(sc) != 0) {
+               DPRINTF(sc, ATH_DBG_FATAL,
+                       "Unable to restart recv logic\n");
+               return -EIO;
+       }
+
+       ath_cache_conf_rate(sc, &hw->conf);
+       ath_update_txpow(sc);
+       ath9k_hw_set_interrupts(ah, sc->imask);
+       ath9k_ps_restore(sc);
+       return 0;
+}
+
+/*
+ *  This routine performs the periodic noise floor calibration function
+ *  that is used to adjust and optimize the chip performance.  This
+ *  takes environmental changes (location, temperature) into account.
+ *  When the task is complete, it reschedules itself depending on the
+ *  appropriate interval that was calculated.
+ */
+static void ath_ani_calibrate(unsigned long data)
+{
+       struct ath_softc *sc = (struct ath_softc *)data;
+       struct ath_hw *ah = sc->sc_ah;
+       bool longcal = false;
+       bool shortcal = false;
+       bool aniflag = false;
+       unsigned int timestamp = jiffies_to_msecs(jiffies);
+       u32 cal_interval, short_cal_interval;
+
+       short_cal_interval = (ah->opmode == NL80211_IFTYPE_AP) ?
+               ATH_AP_SHORT_CALINTERVAL : ATH_STA_SHORT_CALINTERVAL;
+
+       /*
+       * don't calibrate when we're scanning.
+       * we are most likely not on our home channel.
+       */
+       if (sc->sc_flags & SC_OP_SCANNING)
+               goto set_timer;
+
+       /* Only calibrate if awake */
+       if (sc->sc_ah->power_mode != ATH9K_PM_AWAKE)
+               goto set_timer;
+
+       ath9k_ps_wakeup(sc);
+
+       /* Long calibration runs independently of short calibration. */
+       if ((timestamp - sc->ani.longcal_timer) >= ATH_LONG_CALINTERVAL) {
+               longcal = true;
+               DPRINTF(sc, ATH_DBG_ANI, "longcal @%lu\n", jiffies);
+               sc->ani.longcal_timer = timestamp;
+       }
+
+       /* Short calibration applies only while caldone is false */
+       if (!sc->ani.caldone) {
+               if ((timestamp - sc->ani.shortcal_timer) >= short_cal_interval) {
+                       shortcal = true;
+                       DPRINTF(sc, ATH_DBG_ANI, "shortcal @%lu\n", jiffies);
+                       sc->ani.shortcal_timer = timestamp;
+                       sc->ani.resetcal_timer = timestamp;
+               }
+       } else {
+               if ((timestamp - sc->ani.resetcal_timer) >=
+                   ATH_RESTART_CALINTERVAL) {
+                       sc->ani.caldone = ath9k_hw_reset_calvalid(ah);
+                       if (sc->ani.caldone)
+                               sc->ani.resetcal_timer = timestamp;
+               }
+       }
+
+       /* Verify whether we must check ANI */
+       if ((timestamp - sc->ani.checkani_timer) >= ATH_ANI_POLLINTERVAL) {
+               aniflag = true;
+               sc->ani.checkani_timer = timestamp;
+       }
+
+       /* Skip all processing if there's nothing to do. */
+       if (longcal || shortcal || aniflag) {
+               /* Call ANI routine if necessary */
+               if (aniflag)
+                       ath9k_hw_ani_monitor(ah, &sc->nodestats, ah->curchan);
+
+               /* Perform calibration if necessary */
+               if (longcal || shortcal) {
+                       sc->ani.caldone = ath9k_hw_calibrate(ah, ah->curchan,
+                                                    sc->rx_chainmask, longcal);
+
+                       if (longcal)
+                               sc->ani.noise_floor = ath9k_hw_getchan_noise(ah,
+                                                                    ah->curchan);
+
+                       DPRINTF(sc, ATH_DBG_ANI," calibrate chan %u/%x nf: %d\n",
+                               ah->curchan->channel, ah->curchan->channelFlags,
+                               sc->ani.noise_floor);
+               }
+       }
+
+       ath9k_ps_restore(sc);
+
+set_timer:
+       /*
+       * Set timer interval based on previous results.
+       * The interval must be the shortest necessary to satisfy ANI,
+       * short calibration and long calibration.
+       */
+       cal_interval = ATH_LONG_CALINTERVAL;
+       if (sc->sc_ah->config.enable_ani)
+               cal_interval = min(cal_interval, (u32)ATH_ANI_POLLINTERVAL);
+       if (!sc->ani.caldone)
+               cal_interval = min(cal_interval, (u32)short_cal_interval);
+
+       mod_timer(&sc->ani.timer, jiffies + msecs_to_jiffies(cal_interval));
+}
+
+static void ath_start_ani(struct ath_softc *sc)
+{
+       unsigned long timestamp = jiffies_to_msecs(jiffies);
+
+       sc->ani.longcal_timer = timestamp;
+       sc->ani.shortcal_timer = timestamp;
+       sc->ani.checkani_timer = timestamp;
+
+       mod_timer(&sc->ani.timer,
+                 jiffies + msecs_to_jiffies(ATH_ANI_POLLINTERVAL));
+}
+
+/*
+ * Update tx/rx chainmask. For legacy association,
+ * hard code chainmask to 1x1, for 11n association, use
+ * the chainmask configuration, for bt coexistence, use
+ * the chainmask configuration even in legacy mode.
+ */
+void ath_update_chainmask(struct ath_softc *sc, int is_ht)
+{
+       if (is_ht ||
+           (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_BT_COEX)) {
+               sc->tx_chainmask = sc->sc_ah->caps.tx_chainmask;
+               sc->rx_chainmask = sc->sc_ah->caps.rx_chainmask;
+       } else {
+               sc->tx_chainmask = 1;
+               sc->rx_chainmask = 1;
+       }
+
+       DPRINTF(sc, ATH_DBG_CONFIG, "tx chmask: %d, rx chmask: %d\n",
+               sc->tx_chainmask, sc->rx_chainmask);
+}
+
+static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta)
+{
+       struct ath_node *an;
+
+       an = (struct ath_node *)sta->drv_priv;
+
+       if (sc->sc_flags & SC_OP_TXAGGR) {
+               ath_tx_node_init(sc, an);
+               an->maxampdu = 1 << (IEEE80211_HTCAP_MAXRXAMPDU_FACTOR +
+                                    sta->ht_cap.ampdu_factor);
+               an->mpdudensity = parse_mpdudensity(sta->ht_cap.ampdu_density);
+       }
+}
+
+static void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta)
+{
+       struct ath_node *an = (struct ath_node *)sta->drv_priv;
+
+       if (sc->sc_flags & SC_OP_TXAGGR)
+               ath_tx_node_cleanup(sc, an);
+}
+
+static void ath9k_tasklet(unsigned long data)
+{
+       struct ath_softc *sc = (struct ath_softc *)data;
+       u32 status = sc->intrstatus;
+
+       ath9k_ps_wakeup(sc);
+
+       if (status & ATH9K_INT_FATAL) {
+               ath_reset(sc, false);
+               ath9k_ps_restore(sc);
+               return;
+       }
+
+       if (status & (ATH9K_INT_RX | ATH9K_INT_RXEOL | ATH9K_INT_RXORN)) {
+               spin_lock_bh(&sc->rx.rxflushlock);
+               ath_rx_tasklet(sc, 0);
+               spin_unlock_bh(&sc->rx.rxflushlock);
+       }
+
+       if (status & ATH9K_INT_TX)
+               ath_tx_tasklet(sc);
+
+       if ((status & ATH9K_INT_TSFOOR) &&
+           (sc->hw->conf.flags & IEEE80211_CONF_PS)) {
+               /*
+                * TSF sync does not look correct; remain awake to sync with
+                * the next Beacon.
+                */
+               DPRINTF(sc, ATH_DBG_PS, "TSFOOR - Sync with next Beacon\n");
+               sc->sc_flags |= SC_OP_WAIT_FOR_BEACON | SC_OP_BEACON_SYNC;
+       }
+
+       /* re-enable hardware interrupt */
+       ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
+       ath9k_ps_restore(sc);
+}
+
+irqreturn_t ath_isr(int irq, void *dev)
+{
+#define SCHED_INTR (                           \
+               ATH9K_INT_FATAL |               \
+               ATH9K_INT_RXORN |               \
+               ATH9K_INT_RXEOL |               \
+               ATH9K_INT_RX |                  \
+               ATH9K_INT_TX |                  \
+               ATH9K_INT_BMISS |               \
+               ATH9K_INT_CST |                 \
+               ATH9K_INT_TSFOOR)
+
+       struct ath_softc *sc = dev;
+       struct ath_hw *ah = sc->sc_ah;
+       enum ath9k_int status;
+       bool sched = false;
+
+       /*
+        * The hardware is not ready/present, don't
+        * touch anything. Note this can happen early
+        * on if the IRQ is shared.
+        */
+       if (sc->sc_flags & SC_OP_INVALID)
+               return IRQ_NONE;
+
+
+       /* shared irq, not for us */
+
+       if (!ath9k_hw_intrpend(ah))
+               return IRQ_NONE;
+
+       /*
+        * Figure out the reason(s) for the interrupt.  Note
+        * that the hal returns a pseudo-ISR that may include
+        * bits we haven't explicitly enabled so we mask the
+        * value to insure we only process bits we requested.
+        */
+       ath9k_hw_getisr(ah, &status);   /* NB: clears ISR too */
+       status &= sc->imask;    /* discard unasked-for bits */
+
+       /*
+        * If there are no status bits set, then this interrupt was not
+        * for me (should have been caught above).
+        */
+       if (!status)
+               return IRQ_NONE;
+
+       /* Cache the status */
+       sc->intrstatus = status;
+
+       if (status & SCHED_INTR)
+               sched = true;
+
+       /*
+        * If a FATAL or RXORN interrupt is received, we have to reset the
+        * chip immediately.
+        */
+       if (status & (ATH9K_INT_FATAL | ATH9K_INT_RXORN))
+               goto chip_reset;
+
+       if (status & ATH9K_INT_SWBA)
+               tasklet_schedule(&sc->bcon_tasklet);
+
+       if (status & ATH9K_INT_TXURN)
+               ath9k_hw_updatetxtriglevel(ah, true);
+
+       if (status & ATH9K_INT_MIB) {
+               /*
+                * Disable interrupts until we service the MIB
+                * interrupt; otherwise it will continue to
+                * fire.
+                */
+               ath9k_hw_set_interrupts(ah, 0);
+               /*
+                * Let the hal handle the event. We assume
+                * it will clear whatever condition caused
+                * the interrupt.
+                */
+               ath9k_hw_procmibevent(ah, &sc->nodestats);
+               ath9k_hw_set_interrupts(ah, sc->imask);
+       }
+
+       if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
+               if (status & ATH9K_INT_TIM_TIMER) {
+                       /* Clear RxAbort bit so that we can
+                        * receive frames */
+                       ath9k_hw_setpower(ah, ATH9K_PM_AWAKE);
+                       ath9k_hw_setrxabort(sc->sc_ah, 0);
+                       sc->sc_flags |= SC_OP_WAIT_FOR_BEACON;
+               }
+
+chip_reset:
+
+       ath_debug_stat_interrupt(sc, status);
+
+       if (sched) {
+               /* turn off every interrupt except SWBA */
+               ath9k_hw_set_interrupts(ah, (sc->imask & ATH9K_INT_SWBA));
+               tasklet_schedule(&sc->intr_tq);
+       }
+
+       return IRQ_HANDLED;
+
+#undef SCHED_INTR
+}
+
+static u32 ath_get_extchanmode(struct ath_softc *sc,
+                              struct ieee80211_channel *chan,
+                              enum nl80211_channel_type channel_type)
+{
+       u32 chanmode = 0;
+
+       switch (chan->band) {
+       case IEEE80211_BAND_2GHZ:
+               switch(channel_type) {
+               case NL80211_CHAN_NO_HT:
+               case NL80211_CHAN_HT20:
+                       chanmode = CHANNEL_G_HT20;
+                       break;
+               case NL80211_CHAN_HT40PLUS:
+                       chanmode = CHANNEL_G_HT40PLUS;
+                       break;
+               case NL80211_CHAN_HT40MINUS:
+                       chanmode = CHANNEL_G_HT40MINUS;
+                       break;
+               }
+               break;
+       case IEEE80211_BAND_5GHZ:
+               switch(channel_type) {
+               case NL80211_CHAN_NO_HT:
+               case NL80211_CHAN_HT20:
+                       chanmode = CHANNEL_A_HT20;
+                       break;
+               case NL80211_CHAN_HT40PLUS:
+                       chanmode = CHANNEL_A_HT40PLUS;
+                       break;
+               case NL80211_CHAN_HT40MINUS:
+                       chanmode = CHANNEL_A_HT40MINUS;
+                       break;
+               }
+               break;
+       default:
+               break;
+       }
+
+       return chanmode;
+}
+
+static int ath_setkey_tkip(struct ath_softc *sc, u16 keyix, const u8 *key,
+                          struct ath9k_keyval *hk, const u8 *addr,
+                          bool authenticator)
+{
+       const u8 *key_rxmic;
+       const u8 *key_txmic;
+
+       key_txmic = key + NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY;
+       key_rxmic = key + NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY;
+
+       if (addr == NULL) {
+               /*
+                * Group key installation - only two key cache entries are used
+                * regardless of splitmic capability since group key is only
+                * used either for TX or RX.
+                */
+               if (authenticator) {
+                       memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic));
+                       memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_mic));
+               } else {
+                       memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
+                       memcpy(hk->kv_txmic, key_rxmic, sizeof(hk->kv_mic));
+               }
+               return ath9k_hw_set_keycache_entry(sc->sc_ah, keyix, hk, addr);
+       }
+       if (!sc->splitmic) {
+               /* TX and RX keys share the same key cache entry. */
+               memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
+               memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_txmic));
+               return ath9k_hw_set_keycache_entry(sc->sc_ah, keyix, hk, addr);
+       }
+
+       /* Separate key cache entries for TX and RX */
+
+       /* TX key goes at first index, RX key at +32. */
+       memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic));
+       if (!ath9k_hw_set_keycache_entry(sc->sc_ah, keyix, hk, NULL)) {
+               /* TX MIC entry failed. No need to proceed further */
+               DPRINTF(sc, ATH_DBG_FATAL,
+                       "Setting TX MIC Key Failed\n");
+               return 0;
+       }
+
+       memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
+       /* XXX delete tx key on failure? */
+       return ath9k_hw_set_keycache_entry(sc->sc_ah, keyix + 32, hk, addr);
+}
+
+static int ath_reserve_key_cache_slot_tkip(struct ath_softc *sc)
+{
+       int i;
+
+       for (i = IEEE80211_WEP_NKID; i < sc->keymax / 2; i++) {
+               if (test_bit(i, sc->keymap) ||
+                   test_bit(i + 64, sc->keymap))
+                       continue; /* At least one part of TKIP key allocated */
+               if (sc->splitmic &&
+                   (test_bit(i + 32, sc->keymap) ||
+                    test_bit(i + 64 + 32, sc->keymap)))
+                       continue; /* At least one part of TKIP key allocated */
+
+               /* Found a free slot for a TKIP key */
+               return i;
+       }
+       return -1;
+}
+
+static int ath_reserve_key_cache_slot(struct ath_softc *sc)
+{
+       int i;
+
+       /* First, try to find slots that would not be available for TKIP. */
+       if (sc->splitmic) {
+               for (i = IEEE80211_WEP_NKID; i < sc->keymax / 4; i++) {
+                       if (!test_bit(i, sc->keymap) &&
+                           (test_bit(i + 32, sc->keymap) ||
+                            test_bit(i + 64, sc->keymap) ||
+                            test_bit(i + 64 + 32, sc->keymap)))
+                               return i;
+                       if (!test_bit(i + 32, sc->keymap) &&
+                           (test_bit(i, sc->keymap) ||
+                            test_bit(i + 64, sc->keymap) ||
+                            test_bit(i + 64 + 32, sc->keymap)))
+                               return i + 32;
+                       if (!test_bit(i + 64, sc->keymap) &&
+                           (test_bit(i , sc->keymap) ||
+                            test_bit(i + 32, sc->keymap) ||
+                            test_bit(i + 64 + 32, sc->keymap)))
+                               return i + 64;
+                       if (!test_bit(i + 64 + 32, sc->keymap) &&
+                           (test_bit(i, sc->keymap) ||
+                            test_bit(i + 32, sc->keymap) ||
+                            test_bit(i + 64, sc->keymap)))
+                               return i + 64 + 32;
+               }
+       } else {
+               for (i = IEEE80211_WEP_NKID; i < sc->keymax / 2; i++) {
+                       if (!test_bit(i, sc->keymap) &&
+                           test_bit(i + 64, sc->keymap))
+                               return i;
+                       if (test_bit(i, sc->keymap) &&
+                           !test_bit(i + 64, sc->keymap))
+                               return i + 64;
+               }
+       }
+
+       /* No partially used TKIP slots, pick any available slot */
+       for (i = IEEE80211_WEP_NKID; i < sc->keymax; i++) {
+               /* Do not allow slots that could be needed for TKIP group keys
+                * to be used. This limitation could be removed if we know that
+                * TKIP will not be used. */
+               if (i >= 64 && i < 64 + IEEE80211_WEP_NKID)
+                       continue;
+               if (sc->splitmic) {
+                       if (i >= 32 && i < 32 + IEEE80211_WEP_NKID)
+                               continue;
+                       if (i >= 64 + 32 && i < 64 + 32 + IEEE80211_WEP_NKID)
+                               continue;
+               }
+
+               if (!test_bit(i, sc->keymap))
+                       return i; /* Found a free slot for a key */
+       }
+
+       /* No free slot found */
+       return -1;
+}
+
+static int ath_key_config(struct ath_softc *sc,
+                         struct ieee80211_vif *vif,
+                         struct ieee80211_sta *sta,
+                         struct ieee80211_key_conf *key)
+{
+       struct ath9k_keyval hk;
+       const u8 *mac = NULL;
+       int ret = 0;
+       int idx;
+
+       memset(&hk, 0, sizeof(hk));
+
+       switch (key->alg) {
+       case ALG_WEP:
+               hk.kv_type = ATH9K_CIPHER_WEP;
+               break;
+       case ALG_TKIP:
+               hk.kv_type = ATH9K_CIPHER_TKIP;
+               break;
+       case ALG_CCMP:
+               hk.kv_type = ATH9K_CIPHER_AES_CCM;
+               break;
+       default:
+               return -EOPNOTSUPP;
+       }
+
+       hk.kv_len = key->keylen;
+       memcpy(hk.kv_val, key->key, key->keylen);
+
+       if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) {
+               /* For now, use the default keys for broadcast keys. This may
+                * need to change with virtual interfaces. */
+               idx = key->keyidx;
+       } else if (key->keyidx) {
+               if (WARN_ON(!sta))
+                       return -EOPNOTSUPP;
+               mac = sta->addr;
+
+               if (vif->type != NL80211_IFTYPE_AP) {
+                       /* Only keyidx 0 should be used with unicast key, but
+                        * allow this for client mode for now. */
+                       idx = key->keyidx;
+               } else
+                       return -EIO;
+       } else {
+               if (WARN_ON(!sta))
+                       return -EOPNOTSUPP;
+               mac = sta->addr;
+
+               if (key->alg == ALG_TKIP)
+                       idx = ath_reserve_key_cache_slot_tkip(sc);
+               else
+                       idx = ath_reserve_key_cache_slot(sc);
+               if (idx < 0)
+                       return -ENOSPC; /* no free key cache entries */
+       }
+
+       if (key->alg == ALG_TKIP)
+               ret = ath_setkey_tkip(sc, idx, key->key, &hk, mac,
+                                     vif->type == NL80211_IFTYPE_AP);
+       else
+               ret = ath9k_hw_set_keycache_entry(sc->sc_ah, idx, &hk, mac);
+
+       if (!ret)
+               return -EIO;
+
+       set_bit(idx, sc->keymap);
+       if (key->alg == ALG_TKIP) {
+               set_bit(idx + 64, sc->keymap);
+               if (sc->splitmic) {
+                       set_bit(idx + 32, sc->keymap);
+                       set_bit(idx + 64 + 32, sc->keymap);
+               }
+       }
+
+       return idx;
+}
+
+static void ath_key_delete(struct ath_softc *sc, struct ieee80211_key_conf *key)
+{
+       ath9k_hw_keyreset(sc->sc_ah, key->hw_key_idx);
+       if (key->hw_key_idx < IEEE80211_WEP_NKID)
+               return;
+
+       clear_bit(key->hw_key_idx, sc->keymap);
+       if (key->alg != ALG_TKIP)
+               return;
+
+       clear_bit(key->hw_key_idx + 64, sc->keymap);
+       if (sc->splitmic) {
+               clear_bit(key->hw_key_idx + 32, sc->keymap);
+               clear_bit(key->hw_key_idx + 64 + 32, sc->keymap);
+       }
+}
+
+static void setup_ht_cap(struct ath_softc *sc,
+                        struct ieee80211_sta_ht_cap *ht_info)
+{
+#define        ATH9K_HT_CAP_MAXRXAMPDU_65536 0x3       /* 2 ^ 16 */
+#define        ATH9K_HT_CAP_MPDUDENSITY_8 0x6          /* 8 usec */
+
+       ht_info->ht_supported = true;
+       ht_info->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
+                      IEEE80211_HT_CAP_SM_PS |
+                      IEEE80211_HT_CAP_SGI_40 |
+                      IEEE80211_HT_CAP_DSSSCCK40;
+
+       ht_info->ampdu_factor = ATH9K_HT_CAP_MAXRXAMPDU_65536;
+       ht_info->ampdu_density = ATH9K_HT_CAP_MPDUDENSITY_8;
+
+       /* set up supported mcs set */
+       memset(&ht_info->mcs, 0, sizeof(ht_info->mcs));
+
+       switch(sc->rx_chainmask) {
+       case 1:
+               ht_info->mcs.rx_mask[0] = 0xff;
+               break;
+       case 3:
+       case 5:
+       case 7:
+       default:
+               ht_info->mcs.rx_mask[0] = 0xff;
+               ht_info->mcs.rx_mask[1] = 0xff;
+               break;
+       }
+
+       ht_info->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
+}
+
+static void ath9k_bss_assoc_info(struct ath_softc *sc,
+                                struct ieee80211_vif *vif,
+                                struct ieee80211_bss_conf *bss_conf)
+{
+       struct ath_vif *avp = (void *)vif->drv_priv;
+
+       if (bss_conf->assoc) {
+               DPRINTF(sc, ATH_DBG_CONFIG, "Bss Info ASSOC %d, bssid: %pM\n",
+                       bss_conf->aid, sc->curbssid);
+
+               /* New association, store aid */
+               if (avp->av_opmode == NL80211_IFTYPE_STATION) {
+                       sc->curaid = bss_conf->aid;
+                       ath9k_hw_write_associd(sc);
+
+                       /*
+                        * Request a re-configuration of Beacon related timers
+                        * on the receipt of the first Beacon frame (i.e.,
+                        * after time sync with the AP).
+                        */
+                       sc->sc_flags |= SC_OP_BEACON_SYNC;
+               }
+
+               /* Configure the beacon */
+               ath_beacon_config(sc, vif);
+
+               /* Reset rssi stats */
+               sc->nodestats.ns_avgbrssi = ATH_RSSI_DUMMY_MARKER;
+               sc->nodestats.ns_avgrssi = ATH_RSSI_DUMMY_MARKER;
+               sc->nodestats.ns_avgtxrssi = ATH_RSSI_DUMMY_MARKER;
+               sc->nodestats.ns_avgtxrate = ATH_RATE_DUMMY_MARKER;
+
+               ath_start_ani(sc);
+       } else {
+               DPRINTF(sc, ATH_DBG_CONFIG, "Bss Info DISASSOC\n");
+               sc->curaid = 0;
+       }
+}
+
+/********************************/
+/*      LED functions          */
+/********************************/
+
+static void ath_led_blink_work(struct work_struct *work)
+{
+       struct ath_softc *sc = container_of(work, struct ath_softc,
+                                           ath_led_blink_work.work);
+
+       if (!(sc->sc_flags & SC_OP_LED_ASSOCIATED))
+               return;
+
+       if ((sc->led_on_duration == ATH_LED_ON_DURATION_IDLE) ||
+           (sc->led_off_duration == ATH_LED_OFF_DURATION_IDLE))
+               ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 0);
+       else
+               ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN,
+                                 (sc->sc_flags & SC_OP_LED_ON) ? 1 : 0);
+
+       queue_delayed_work(sc->hw->workqueue, &sc->ath_led_blink_work,
+                          (sc->sc_flags & SC_OP_LED_ON) ?
+                          msecs_to_jiffies(sc->led_off_duration) :
+                          msecs_to_jiffies(sc->led_on_duration));
+
+       sc->led_on_duration = sc->led_on_cnt ?
+                       max((ATH_LED_ON_DURATION_IDLE - sc->led_on_cnt), 25) :
+                       ATH_LED_ON_DURATION_IDLE;
+       sc->led_off_duration = sc->led_off_cnt ?
+                       max((ATH_LED_OFF_DURATION_IDLE - sc->led_off_cnt), 10) :
+                       ATH_LED_OFF_DURATION_IDLE;
+       sc->led_on_cnt = sc->led_off_cnt = 0;
+       if (sc->sc_flags & SC_OP_LED_ON)
+               sc->sc_flags &= ~SC_OP_LED_ON;
+       else
+               sc->sc_flags |= SC_OP_LED_ON;
+}
+
+static void ath_led_brightness(struct led_classdev *led_cdev,
+                              enum led_brightness brightness)
+{
+       struct ath_led *led = container_of(led_cdev, struct ath_led, led_cdev);
+       struct ath_softc *sc = led->sc;
+
+       switch (brightness) {
+       case LED_OFF:
+               if (led->led_type == ATH_LED_ASSOC ||
+                   led->led_type == ATH_LED_RADIO) {
+                       ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN,
+                               (led->led_type == ATH_LED_RADIO));
+                       sc->sc_flags &= ~SC_OP_LED_ASSOCIATED;
+                       if (led->led_type == ATH_LED_RADIO)
+                               sc->sc_flags &= ~SC_OP_LED_ON;
+               } else {
+                       sc->led_off_cnt++;
+               }
+               break;
+       case LED_FULL:
+               if (led->led_type == ATH_LED_ASSOC) {
+                       sc->sc_flags |= SC_OP_LED_ASSOCIATED;
+                       queue_delayed_work(sc->hw->workqueue,
+                                          &sc->ath_led_blink_work, 0);
+               } else if (led->led_type == ATH_LED_RADIO) {
+                       ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 0);
+                       sc->sc_flags |= SC_OP_LED_ON;
+               } else {
+                       sc->led_on_cnt++;
+               }
+               break;
+       default:
+               break;
+       }
+}
+
+static int ath_register_led(struct ath_softc *sc, struct ath_led *led,
+                           char *trigger)
+{
+       int ret;
+
+       led->sc = sc;
+       led->led_cdev.name = led->name;
+       led->led_cdev.default_trigger = trigger;
+       led->led_cdev.brightness_set = ath_led_brightness;
+
+       ret = led_classdev_register(wiphy_dev(sc->hw->wiphy), &led->led_cdev);
+       if (ret)
+               DPRINTF(sc, ATH_DBG_FATAL,
+                       "Failed to register led:%s", led->name);
+       else
+               led->registered = 1;
+       return ret;
+}
+
+static void ath_unregister_led(struct ath_led *led)
+{
+       if (led->registered) {
+               led_classdev_unregister(&led->led_cdev);
+               led->registered = 0;
+       }
+}
+
+static void ath_deinit_leds(struct ath_softc *sc)
+{
+       cancel_delayed_work_sync(&sc->ath_led_blink_work);
+       ath_unregister_led(&sc->assoc_led);
+       sc->sc_flags &= ~SC_OP_LED_ASSOCIATED;
+       ath_unregister_led(&sc->tx_led);
+       ath_unregister_led(&sc->rx_led);
+       ath_unregister_led(&sc->radio_led);
+       ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1);
+}
+
+static void ath_init_leds(struct ath_softc *sc)
+{
+       char *trigger;
+       int ret;
+
+       /* Configure gpio 1 for output */
+       ath9k_hw_cfg_output(sc->sc_ah, ATH_LED_PIN,
+                           AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
+       /* LED off, active low */
+       ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1);
+
+       INIT_DELAYED_WORK(&sc->ath_led_blink_work, ath_led_blink_work);
+
+       trigger = ieee80211_get_radio_led_name(sc->hw);
+       snprintf(sc->radio_led.name, sizeof(sc->radio_led.name),
+               "ath9k-%s::radio", wiphy_name(sc->hw->wiphy));
+       ret = ath_register_led(sc, &sc->radio_led, trigger);
+       sc->radio_led.led_type = ATH_LED_RADIO;
+       if (ret)
+               goto fail;
+
+       trigger = ieee80211_get_assoc_led_name(sc->hw);
+       snprintf(sc->assoc_led.name, sizeof(sc->assoc_led.name),
+               "ath9k-%s::assoc", wiphy_name(sc->hw->wiphy));
+       ret = ath_register_led(sc, &sc->assoc_led, trigger);
+       sc->assoc_led.led_type = ATH_LED_ASSOC;
+       if (ret)
+               goto fail;
+
+       trigger = ieee80211_get_tx_led_name(sc->hw);
+       snprintf(sc->tx_led.name, sizeof(sc->tx_led.name),
+               "ath9k-%s::tx", wiphy_name(sc->hw->wiphy));
+       ret = ath_register_led(sc, &sc->tx_led, trigger);
+       sc->tx_led.led_type = ATH_LED_TX;
+       if (ret)
+               goto fail;
+
+       trigger = ieee80211_get_rx_led_name(sc->hw);
+       snprintf(sc->rx_led.name, sizeof(sc->rx_led.name),
+               "ath9k-%s::rx", wiphy_name(sc->hw->wiphy));
+       ret = ath_register_led(sc, &sc->rx_led, trigger);
+       sc->rx_led.led_type = ATH_LED_RX;
+       if (ret)
+               goto fail;
+
+       return;
+
+fail:
+       ath_deinit_leds(sc);
+}
+
+void ath_radio_enable(struct ath_softc *sc)
+{
+       struct ath_hw *ah = sc->sc_ah;
+       struct ieee80211_channel *channel = sc->hw->conf.channel;
+       int r;
+
+       ath9k_ps_wakeup(sc);
+       ath9k_hw_configpcipowersave(ah, 0);
+
+       spin_lock_bh(&sc->sc_resetlock);
+       r = ath9k_hw_reset(ah, ah->curchan, false);
+       if (r) {
+               DPRINTF(sc, ATH_DBG_FATAL,
+                       "Unable to reset channel %u (%uMhz) ",
+                       "reset status %d\n",
+                       channel->center_freq, r);
+       }
+       spin_unlock_bh(&sc->sc_resetlock);
+
+       ath_update_txpow(sc);
+       if (ath_startrecv(sc) != 0) {
+               DPRINTF(sc, ATH_DBG_FATAL,
+                       "Unable to restart recv logic\n");
+               return;
+       }
+
+       if (sc->sc_flags & SC_OP_BEACONS)
+               ath_beacon_config(sc, NULL);    /* restart beacons */
+
+       /* Re-Enable  interrupts */
+       ath9k_hw_set_interrupts(ah, sc->imask);
+
+       /* Enable LED */
+       ath9k_hw_cfg_output(ah, ATH_LED_PIN,
+                           AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
+       ath9k_hw_set_gpio(ah, ATH_LED_PIN, 0);
+
+       ieee80211_wake_queues(sc->hw);
+       ath9k_ps_restore(sc);
+}
+
+void ath_radio_disable(struct ath_softc *sc)
+{
+       struct ath_hw *ah = sc->sc_ah;
+       struct ieee80211_channel *channel = sc->hw->conf.channel;
+       int r;
+
+       ath9k_ps_wakeup(sc);
+       ieee80211_stop_queues(sc->hw);
+
+       /* Disable LED */
+       ath9k_hw_set_gpio(ah, ATH_LED_PIN, 1);
+       ath9k_hw_cfg_gpio_input(ah, ATH_LED_PIN);
+
+       /* Disable interrupts */
+       ath9k_hw_set_interrupts(ah, 0);
+
+       ath_drain_all_txq(sc, false);   /* clear pending tx frames */
+       ath_stoprecv(sc);               /* turn off frame recv */
+       ath_flushrecv(sc);              /* flush recv queue */
+
+       spin_lock_bh(&sc->sc_resetlock);
+       r = ath9k_hw_reset(ah, ah->curchan, false);
+       if (r) {
+               DPRINTF(sc, ATH_DBG_FATAL,
+                       "Unable to reset channel %u (%uMhz) "
+                       "reset status %d\n",
+                       channel->center_freq, r);
+       }
+       spin_unlock_bh(&sc->sc_resetlock);
+
+       ath9k_hw_phy_disable(ah);
+       ath9k_hw_configpcipowersave(ah, 1);
+       ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP);
+       ath9k_ps_restore(sc);
+}
+
+#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
+
+/*******************/
+/*     Rfkill     */
+/*******************/
+
+static bool ath_is_rfkill_set(struct ath_softc *sc)
+{
+       struct ath_hw *ah = sc->sc_ah;
+
+       return ath9k_hw_gpio_get(ah, ah->rfkill_gpio) ==
+                                 ah->rfkill_polarity;
+}
+
+/* s/w rfkill handlers */
+static int ath_rfkill_set_block(void *data, bool blocked)
+{
+       struct ath_softc *sc = data;
+
+       if (blocked)
+               ath_radio_disable(sc);
+       else
+               ath_radio_enable(sc);
+
+       return 0;
+}
+
+static void ath_rfkill_poll_state(struct rfkill *rfkill, void *data)
+{
+       struct ath_softc *sc = data;
+       bool blocked = !!ath_is_rfkill_set(sc);
+
+       if (rfkill_set_hw_state(rfkill, blocked))
+               ath_radio_disable(sc);
+       else
+               ath_radio_enable(sc);
+}
+
+/* Init s/w rfkill */
+static int ath_init_sw_rfkill(struct ath_softc *sc)
+{
+       sc->rf_kill.ops.set_block = ath_rfkill_set_block;
+       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
+               sc->rf_kill.ops.poll = ath_rfkill_poll_state;
+
+       snprintf(sc->rf_kill.rfkill_name, sizeof(sc->rf_kill.rfkill_name),
+               "ath9k-%s::rfkill", wiphy_name(sc->hw->wiphy));
+
+       sc->rf_kill.rfkill = rfkill_alloc(sc->rf_kill.rfkill_name,
+                                         wiphy_dev(sc->hw->wiphy),
+                                         RFKILL_TYPE_WLAN,
+                                         &sc->rf_kill.ops, sc);
+       if (!sc->rf_kill.rfkill) {
+               DPRINTF(sc, ATH_DBG_FATAL, "Failed to allocate rfkill\n");
+               return -ENOMEM;
+       }
+
+       return 0;
+}
+
+/* Deinitialize rfkill */
+static void ath_deinit_rfkill(struct ath_softc *sc)
+{
+       if (sc->sc_flags & SC_OP_RFKILL_REGISTERED) {
+               rfkill_unregister(sc->rf_kill.rfkill);
+               rfkill_destroy(sc->rf_kill.rfkill);
+               sc->sc_flags &= ~SC_OP_RFKILL_REGISTERED;
+       }
+}
+
+static int ath_start_rfkill_poll(struct ath_softc *sc)
+{
+       if (!(sc->sc_flags & SC_OP_RFKILL_REGISTERED)) {
+               if (rfkill_register(sc->rf_kill.rfkill)) {
+                       DPRINTF(sc, ATH_DBG_FATAL,
+                               "Unable to register rfkill\n");
+                       rfkill_destroy(sc->rf_kill.rfkill);
+
+                       /* Deinitialize the device */
+                       ath_cleanup(sc);
+                       return -EIO;
+               } else {
+                       sc->sc_flags |= SC_OP_RFKILL_REGISTERED;
+               }
+       }
+
+       return 0;
+}
+#endif /* CONFIG_RFKILL */
+
+void ath_cleanup(struct ath_softc *sc)
+{
+       ath_detach(sc);
+       free_irq(sc->irq, sc);
+       ath_bus_cleanup(sc);
+       kfree(sc->sec_wiphy);
+       ieee80211_free_hw(sc->hw);
+}
+
+void ath_detach(struct ath_softc *sc)
+{
+       struct ieee80211_hw *hw = sc->hw;
+       int i = 0;
+
+       ath9k_ps_wakeup(sc);
+
+       DPRINTF(sc, ATH_DBG_CONFIG, "Detach ATH hw\n");
+
+#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
+       ath_deinit_rfkill(sc);
+#endif
+       ath_deinit_leds(sc);
+       cancel_work_sync(&sc->chan_work);
+       cancel_delayed_work_sync(&sc->wiphy_work);
+
+       for (i = 0; i < sc->num_sec_wiphy; i++) {
+               struct ath_wiphy *aphy = sc->sec_wiphy[i];
+               if (aphy == NULL)
+                       continue;
+               sc->sec_wiphy[i] = NULL;
+               ieee80211_unregister_hw(aphy->hw);
+               ieee80211_free_hw(aphy->hw);
+       }
+       ieee80211_unregister_hw(hw);
+       ath_rx_cleanup(sc);
+       ath_tx_cleanup(sc);
+
+       tasklet_kill(&sc->intr_tq);
+       tasklet_kill(&sc->bcon_tasklet);
+
+       if (!(sc->sc_flags & SC_OP_INVALID))
+               ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE);
+
+       /* cleanup tx queues */
+       for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
+               if (ATH_TXQ_SETUP(sc, i))
+                       ath_tx_cleanupq(sc, &sc->tx.txq[i]);
+
+       ath9k_hw_detach(sc->sc_ah);
+       ath9k_exit_debug(sc);
+       ath9k_ps_restore(sc);
+}
+
+static int ath9k_reg_notifier(struct wiphy *wiphy,
+                             struct regulatory_request *request)
+{
+       struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
+       struct ath_wiphy *aphy = hw->priv;
+       struct ath_softc *sc = aphy->sc;
+       struct ath_regulatory *reg = &sc->sc_ah->regulatory;
+
+       return ath_reg_notifier_apply(wiphy, request, reg);
+}
+
+static int ath_init(u16 devid, struct ath_softc *sc)
+{
+       struct ath_hw *ah = NULL;
+       int status;
+       int error = 0, i;
+       int csz = 0;
+
+       /* XXX: hardware will not be ready until ath_open() being called */
+       sc->sc_flags |= SC_OP_INVALID;
+
+       if (ath9k_init_debug(sc) < 0)
+               printk(KERN_ERR "Unable to create debugfs files\n");
+
+       spin_lock_init(&sc->wiphy_lock);
+       spin_lock_init(&sc->sc_resetlock);
+       spin_lock_init(&sc->sc_serial_rw);
+       mutex_init(&sc->mutex);
+       tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc);
+       tasklet_init(&sc->bcon_tasklet, ath_beacon_tasklet,
+                    (unsigned long)sc);
+
+       /*
+        * Cache line size is used to size and align various
+        * structures used to communicate with the hardware.
+        */
+       ath_read_cachesize(sc, &csz);
+       /* XXX assert csz is non-zero */
+       sc->cachelsz = csz << 2;        /* convert to bytes */
+
+       ah = ath9k_hw_attach(devid, sc, &status);
+       if (ah == NULL) {
+               DPRINTF(sc, ATH_DBG_FATAL,
+                       "Unable to attach hardware; HAL status %d\n", status);
+               error = -ENXIO;
+               goto bad;
+       }
+       sc->sc_ah = ah;
+
+       /* Get the hardware key cache size. */
+       sc->keymax = ah->caps.keycache_size;
+       if (sc->keymax > ATH_KEYMAX) {
+               DPRINTF(sc, ATH_DBG_ANY,
+                       "Warning, using only %u entries in %u key cache\n",
+                       ATH_KEYMAX, sc->keymax);
+               sc->keymax = ATH_KEYMAX;
+       }
+
+       /*
+        * Reset the key cache since some parts do not
+        * reset the contents on initial power up.
+        */
+       for (i = 0; i < sc->keymax; i++)
+               ath9k_hw_keyreset(ah, (u16) i);
+
+       if (error)
+               goto bad;
+
+       /* default to MONITOR mode */
+       sc->sc_ah->opmode = NL80211_IFTYPE_MONITOR;
+
+       /* Setup rate tables */
+
+       ath_rate_attach(sc);
+       ath_setup_rates(sc, IEEE80211_BAND_2GHZ);
+       ath_setup_rates(sc, IEEE80211_BAND_5GHZ);
+
+       /*
+        * Allocate hardware transmit queues: one queue for
+        * beacon frames and one data queue for each QoS
+        * priority.  Note that the hal handles reseting
+        * these queues at the needed time.
+        */
+       sc->beacon.beaconq = ath_beaconq_setup(ah);
+       if (sc->beacon.beaconq == -1) {
+               DPRINTF(sc, ATH_DBG_FATAL,
+                       "Unable to setup a beacon xmit queue\n");
+               error = -EIO;
+               goto bad2;
+       }
+       sc->beacon.cabq = ath_txq_setup(sc, ATH9K_TX_QUEUE_CAB, 0);
+       if (sc->beacon.cabq == NULL) {
+               DPRINTF(sc, ATH_DBG_FATAL,
+                       "Unable to setup CAB xmit queue\n");
+               error = -EIO;
+               goto bad2;
+       }
+
+       sc->config.cabqReadytime = ATH_CABQ_READY_TIME;
+       ath_cabq_update(sc);
+
+       for (i = 0; i < ARRAY_SIZE(sc->tx.hwq_map); i++)
+               sc->tx.hwq_map[i] = -1;
+
+       /* Setup data queues */
+       /* NB: ensure BK queue is the lowest priority h/w queue */
+       if (!ath_tx_setup(sc, ATH9K_WME_AC_BK)) {
+               DPRINTF(sc, ATH_DBG_FATAL,
+                       "Unable to setup xmit queue for BK traffic\n");
+               error = -EIO;
+               goto bad2;
+       }
+
+       if (!ath_tx_setup(sc, ATH9K_WME_AC_BE)) {
+               DPRINTF(sc, ATH_DBG_FATAL,
+                       "Unable to setup xmit queue for BE traffic\n");
+               error = -EIO;
+               goto bad2;
+       }
+       if (!ath_tx_setup(sc, ATH9K_WME_AC_VI)) {
+               DPRINTF(sc, ATH_DBG_FATAL,
+                       "Unable to setup xmit queue for VI traffic\n");
+               error = -EIO;
+               goto bad2;
+       }
+       if (!ath_tx_setup(sc, ATH9K_WME_AC_VO)) {
+               DPRINTF(sc, ATH_DBG_FATAL,
+                       "Unable to setup xmit queue for VO traffic\n");
+               error = -EIO;
+               goto bad2;
+       }
+
+       /* Initializes the noise floor to a reasonable default value.
+        * Later on this will be updated during ANI processing. */
+
+       sc->ani.noise_floor = ATH_DEFAULT_NOISE_FLOOR;
+       setup_timer(&sc->ani.timer, ath_ani_calibrate, (unsigned long)sc);
+
+       if (ath9k_hw_getcapability(ah, ATH9K_CAP_CIPHER,
+                                  ATH9K_CIPHER_TKIP, NULL)) {
+               /*
+                * Whether we should enable h/w TKIP MIC.
+                * XXX: if we don't support WME TKIP MIC, then we wouldn't
+                * report WMM capable, so it's always safe to turn on
+                * TKIP MIC in this case.
+                */
+               ath9k_hw_setcapability(sc->sc_ah, ATH9K_CAP_TKIP_MIC,
+                                      0, 1, NULL);
+       }
+
+       /*
+        * Check whether the separate key cache entries
+        * are required to handle both tx+rx MIC keys.
+        * With split mic keys the number of stations is limited
+        * to 27 otherwise 59.
+        */
+       if (ath9k_hw_getcapability(ah, ATH9K_CAP_CIPHER,
+                                  ATH9K_CIPHER_TKIP, NULL)
+           && ath9k_hw_getcapability(ah, ATH9K_CAP_CIPHER,
+                                     ATH9K_CIPHER_MIC, NULL)
+           && ath9k_hw_getcapability(ah, ATH9K_CAP_TKIP_SPLIT,
+                                     0, NULL))
+               sc->splitmic = 1;
+
+       /* turn on mcast key search if possible */
+       if (!ath9k_hw_getcapability(ah, ATH9K_CAP_MCAST_KEYSRCH, 0, NULL))
+               (void)ath9k_hw_setcapability(ah, ATH9K_CAP_MCAST_KEYSRCH, 1,
+                                            1, NULL);
+
+       sc->config.txpowlimit = ATH_TXPOWER_MAX;
+
+       /* 11n Capabilities */
+       if (ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
+               sc->sc_flags |= SC_OP_TXAGGR;
+               sc->sc_flags |= SC_OP_RXAGGR;
+       }
+
+       sc->tx_chainmask = ah->caps.tx_chainmask;
+       sc->rx_chainmask = ah->caps.rx_chainmask;
+
+       ath9k_hw_setcapability(ah, ATH9K_CAP_DIVERSITY, 1, true, NULL);
+       sc->rx.defant = ath9k_hw_getdefantenna(ah);
+
+       if (ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK)
+               memcpy(sc->bssidmask, ath_bcast_mac, ETH_ALEN);
+
+       sc->beacon.slottime = ATH9K_SLOT_TIME_9;        /* default to short slot time */
+
+       /* initialize beacon slots */
+       for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) {
+               sc->beacon.bslot[i] = NULL;
+               sc->beacon.bslot_aphy[i] = NULL;
+       }
+
+       /* setup channels and rates */
+
+       sc->sbands[IEEE80211_BAND_2GHZ].channels = ath9k_2ghz_chantable;
+       sc->sbands[IEEE80211_BAND_2GHZ].bitrates =
+               sc->rates[IEEE80211_BAND_2GHZ];
+       sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ;
+       sc->sbands[IEEE80211_BAND_2GHZ].n_channels =
+               ARRAY_SIZE(ath9k_2ghz_chantable);
+
+       if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes)) {
+               sc->sbands[IEEE80211_BAND_5GHZ].channels = ath9k_5ghz_chantable;
+               sc->sbands[IEEE80211_BAND_5GHZ].bitrates =
+                       sc->rates[IEEE80211_BAND_5GHZ];
+               sc->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ;
+               sc->sbands[IEEE80211_BAND_5GHZ].n_channels =
+                       ARRAY_SIZE(ath9k_5ghz_chantable);
+       }
+
+       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_BT_COEX)
+               ath9k_hw_btcoex_enable(sc->sc_ah);
+
+       return 0;
+bad2:
+       /* cleanup tx queues */
+       for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
+               if (ATH_TXQ_SETUP(sc, i))
+                       ath_tx_cleanupq(sc, &sc->tx.txq[i]);
+bad:
+       if (ah)
+               ath9k_hw_detach(ah);
+       ath9k_exit_debug(sc);
+
+       return error;
+}
+
+void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
+{
+       hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
+               IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
+               IEEE80211_HW_SIGNAL_DBM |
+               IEEE80211_HW_AMPDU_AGGREGATION |
+               IEEE80211_HW_SUPPORTS_PS |
+               IEEE80211_HW_PS_NULLFUNC_STACK |
+               IEEE80211_HW_SPECTRUM_MGMT;
+
+       if (AR_SREV_9160_10_OR_LATER(sc->sc_ah) || modparam_nohwcrypt)
+               hw->flags |= IEEE80211_HW_MFP_CAPABLE;
+
+       hw->wiphy->interface_modes =
+               BIT(NL80211_IFTYPE_AP) |
+               BIT(NL80211_IFTYPE_STATION) |
+               BIT(NL80211_IFTYPE_ADHOC) |
+               BIT(NL80211_IFTYPE_MESH_POINT);
+
+       hw->queues = 4;
+       hw->max_rates = 4;
+       hw->channel_change_time = 5000;
+       hw->max_listen_interval = 10;
+       hw->max_rate_tries = ATH_11N_TXMAXTRY;
+       hw->sta_data_size = sizeof(struct ath_node);
+       hw->vif_data_size = sizeof(struct ath_vif);
+
+       hw->rate_control_algorithm = "ath9k_rate_control";
+
+       hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
+               &sc->sbands[IEEE80211_BAND_2GHZ];
+       if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes))
+               hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
+                       &sc->sbands[IEEE80211_BAND_5GHZ];
+}
+
+int ath_attach(u16 devid, struct ath_softc *sc)
+{
+       struct ieee80211_hw *hw = sc->hw;
+       int error = 0, i;
+       struct ath_regulatory *reg;
+
+       DPRINTF(sc, ATH_DBG_CONFIG, "Attach ATH hw\n");
+
+       error = ath_init(devid, sc);
+       if (error != 0)
+               return error;
+
+       /* get mac address from hardware and set in mac80211 */
+
+       SET_IEEE80211_PERM_ADDR(hw, sc->sc_ah->macaddr);
+
+       ath_set_hw_capab(sc, hw);
+
+       error = ath_regd_init(&sc->sc_ah->regulatory, sc->hw->wiphy,
+                             ath9k_reg_notifier);
+       if (error)
+               return error;
+
+       reg = &sc->sc_ah->regulatory;
+
+       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
+               setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_2GHZ].ht_cap);
+               if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes))
+                       setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_5GHZ].ht_cap);
+       }
+
+       /* initialize tx/rx engine */
+       error = ath_tx_init(sc, ATH_TXBUF);
+       if (error != 0)
+               goto error_attach;
+
+       error = ath_rx_init(sc, ATH_RXBUF);
+       if (error != 0)
+               goto error_attach;
+
+#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
+       /* Initialize s/w rfkill */
+       error = ath_init_sw_rfkill(sc);
+       if (error)
+               goto error_attach;
+#endif
+
+       INIT_WORK(&sc->chan_work, ath9k_wiphy_chan_work);
+       INIT_DELAYED_WORK(&sc->wiphy_work, ath9k_wiphy_work);
+       sc->wiphy_scheduler_int = msecs_to_jiffies(500);
+
+       error = ieee80211_register_hw(hw);
+
+       if (!ath_is_world_regd(reg)) {
+               error = regulatory_hint(hw->wiphy, reg->alpha2);
+               if (error)
+                       goto error_attach;
+       }
+
+       /* Initialize LED control */
+       ath_init_leds(sc);
+
+
+       return 0;
+
+error_attach:
+       /* cleanup tx queues */
+       for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
+               if (ATH_TXQ_SETUP(sc, i))
+                       ath_tx_cleanupq(sc, &sc->tx.txq[i]);
+
+       ath9k_hw_detach(sc->sc_ah);
+       ath9k_exit_debug(sc);
+
+       return error;
+}
+
+int ath_reset(struct ath_softc *sc, bool retry_tx)
+{
+       struct ath_hw *ah = sc->sc_ah;
+       struct ieee80211_hw *hw = sc->hw;
+       int r;
+
+       ath9k_hw_set_interrupts(ah, 0);
+       ath_drain_all_txq(sc, retry_tx);
+       ath_stoprecv(sc);
+       ath_flushrecv(sc);
+
+       spin_lock_bh(&sc->sc_resetlock);
+       r = ath9k_hw_reset(ah, sc->sc_ah->curchan, false);
+       if (r)
+               DPRINTF(sc, ATH_DBG_FATAL,
+                       "Unable to reset hardware; reset status %d\n", r);
+       spin_unlock_bh(&sc->sc_resetlock);
+
+       if (ath_startrecv(sc) != 0)
+               DPRINTF(sc, ATH_DBG_FATAL, "Unable to start recv logic\n");
+
+       /*
+        * We may be doing a reset in response to a request
+        * that changes the channel so update any state that
+        * might change as a result.
+        */
+       ath_cache_conf_rate(sc, &hw->conf);
+
+       ath_update_txpow(sc);
+
+       if (sc->sc_flags & SC_OP_BEACONS)
+               ath_beacon_config(sc, NULL);    /* restart beacons */
+
+       ath9k_hw_set_interrupts(ah, sc->imask);
+
+       if (retry_tx) {
+               int i;
+               for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
+                       if (ATH_TXQ_SETUP(sc, i)) {
+                               spin_lock_bh(&sc->tx.txq[i].axq_lock);
+                               ath_txq_schedule(sc, &sc->tx.txq[i]);
+                               spin_unlock_bh(&sc->tx.txq[i].axq_lock);
+                       }
+               }
+       }
+
+       return r;
+}
+
+/*
+ *  This function will allocate both the DMA descriptor structure, and the
+ *  buffers it contains.  These are used to contain the descriptors used
+ *  by the system.
+*/
+int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
+                     struct list_head *head, const char *name,
+                     int nbuf, int ndesc)
+{
+#define        DS2PHYS(_dd, _ds)                                               \
+       ((_dd)->dd_desc_paddr + ((caddr_t)(_ds) - (caddr_t)(_dd)->dd_desc))
+#define ATH_DESC_4KB_BOUND_CHECK(_daddr) ((((_daddr) & 0xFFF) > 0xF7F) ? 1 : 0)
+#define ATH_DESC_4KB_BOUND_NUM_SKIPPED(_len) ((_len) / 4096)
+
+       struct ath_desc *ds;
+       struct ath_buf *bf;
+       int i, bsize, error;
+
+       DPRINTF(sc, ATH_DBG_CONFIG, "%s DMA: %u buffers %u desc/buf\n",
+               name, nbuf, ndesc);
+
+       INIT_LIST_HEAD(head);
+       /* ath_desc must be a multiple of DWORDs */
+       if ((sizeof(struct ath_desc) % 4) != 0) {
+               DPRINTF(sc, ATH_DBG_FATAL, "ath_desc not DWORD aligned\n");
+               ASSERT((sizeof(struct ath_desc) % 4) == 0);
+               error = -ENOMEM;
+               goto fail;
+       }
+
+       dd->dd_desc_len = sizeof(struct ath_desc) * nbuf * ndesc;
+
+       /*
+        * Need additional DMA memory because we can't use
+        * descriptors that cross the 4K page boundary. Assume
+        * one skipped descriptor per 4K page.
+        */
+       if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_4KB_SPLITTRANS)) {
+               u32 ndesc_skipped =
+                       ATH_DESC_4KB_BOUND_NUM_SKIPPED(dd->dd_desc_len);
+               u32 dma_len;
+
+               while (ndesc_skipped) {
+                       dma_len = ndesc_skipped * sizeof(struct ath_desc);
+                       dd->dd_desc_len += dma_len;
+
+                       ndesc_skipped = ATH_DESC_4KB_BOUND_NUM_SKIPPED(dma_len);
+               };
+       }
+
+       /* allocate descriptors */
+       dd->dd_desc = dma_alloc_coherent(sc->dev, dd->dd_desc_len,
+                                        &dd->dd_desc_paddr, GFP_KERNEL);
+       if (dd->dd_desc == NULL) {
+               error = -ENOMEM;
+               goto fail;
+       }
+       ds = dd->dd_desc;
+       DPRINTF(sc, ATH_DBG_CONFIG, "%s DMA map: %p (%u) -> %llx (%u)\n",
+               name, ds, (u32) dd->dd_desc_len,
+               ito64(dd->dd_desc_paddr), /*XXX*/(u32) dd->dd_desc_len);
+
+       /* allocate buffers */
+       bsize = sizeof(struct ath_buf) * nbuf;
+       bf = kzalloc(bsize, GFP_KERNEL);
+       if (bf == NULL) {
+               error = -ENOMEM;
+               goto fail2;
+       }
+       dd->dd_bufptr = bf;
+
+       for (i = 0; i < nbuf; i++, bf++, ds += ndesc) {
+               bf->bf_desc = ds;
+               bf->bf_daddr = DS2PHYS(dd, ds);
+
+               if (!(sc->sc_ah->caps.hw_caps &
+                     ATH9K_HW_CAP_4KB_SPLITTRANS)) {
+                       /*
+                        * Skip descriptor addresses which can cause 4KB
+                        * boundary crossing (addr + length) with a 32 dword
+                        * descriptor fetch.
+                        */
+                       while (ATH_DESC_4KB_BOUND_CHECK(bf->bf_daddr)) {
+                               ASSERT((caddr_t) bf->bf_desc <
+                                      ((caddr_t) dd->dd_desc +
+                                       dd->dd_desc_len));
+
+                               ds += ndesc;
+                               bf->bf_desc = ds;
+                               bf->bf_daddr = DS2PHYS(dd, ds);
+                       }
+               }
+               list_add_tail(&bf->list, head);
+       }
+       return 0;
+fail2:
+       dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc,
+                         dd->dd_desc_paddr);
+fail:
+       memset(dd, 0, sizeof(*dd));
+       return error;
+#undef ATH_DESC_4KB_BOUND_CHECK
+#undef ATH_DESC_4KB_BOUND_NUM_SKIPPED
+#undef DS2PHYS
+}
+
+void ath_descdma_cleanup(struct ath_softc *sc,
+                        struct ath_descdma *dd,
+                        struct list_head *head)
+{
+       dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc,
+                         dd->dd_desc_paddr);
+
+       INIT_LIST_HEAD(head);
+       kfree(dd->dd_bufptr);
+       memset(dd, 0, sizeof(*dd));
+}
+
+int ath_get_hal_qnum(u16 queue, struct ath_softc *sc)
+{
+       int qnum;
+
+       switch (queue) {
+       case 0:
+               qnum = sc->tx.hwq_map[ATH9K_WME_AC_VO];
+               break;
+       case 1:
+               qnum = sc->tx.hwq_map[ATH9K_WME_AC_VI];
+               break;
+       case 2:
+               qnum = sc->tx.hwq_map[ATH9K_WME_AC_BE];
+               break;
+       case 3:
+               qnum = sc->tx.hwq_map[ATH9K_WME_AC_BK];
+               break;
+       default:
+               qnum = sc->tx.hwq_map[ATH9K_WME_AC_BE];
+               break;
+       }
+
+       return qnum;
+}
+
+int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc)
+{
+       int qnum;
+
+       switch (queue) {
+       case ATH9K_WME_AC_VO:
+               qnum = 0;
+               break;
+       case ATH9K_WME_AC_VI:
+               qnum = 1;
+               break;
+       case ATH9K_WME_AC_BE:
+               qnum = 2;
+               break;
+       case ATH9K_WME_AC_BK:
+               qnum = 3;
+               break;
+       default:
+               qnum = -1;
+               break;
+       }
+
+       return qnum;
+}
+
+/* XXX: Remove me once we don't depend on ath9k_channel for all
+ * this redundant data */
+void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw,
+                          struct ath9k_channel *ichan)
+{
+       struct ieee80211_channel *chan = hw->conf.channel;
+       struct ieee80211_conf *conf = &hw->conf;
+
+       ichan->channel = chan->center_freq;
+       ichan->chan = chan;
+
+       if (chan->band == IEEE80211_BAND_2GHZ) {
+               ichan->chanmode = CHANNEL_G;
+               ichan->channelFlags = CHANNEL_2GHZ | CHANNEL_OFDM;
+       } else {
+               ichan->chanmode = CHANNEL_A;
+               ichan->channelFlags = CHANNEL_5GHZ | CHANNEL_OFDM;
+       }
+
+       sc->tx_chan_width = ATH9K_HT_MACMODE_20;
+
+       if (conf_is_ht(conf)) {
+               if (conf_is_ht40(conf))
+                       sc->tx_chan_width = ATH9K_HT_MACMODE_2040;
+
+               ichan->chanmode = ath_get_extchanmode(sc, chan,
+                                           conf->channel_type);
+       }
+}
+
+/**********************/
+/* mac80211 callbacks */
+/**********************/
+
+static int ath9k_start(struct ieee80211_hw *hw)
+{
+       struct ath_wiphy *aphy = hw->priv;
+       struct ath_softc *sc = aphy->sc;
+       struct ieee80211_channel *curchan = hw->conf.channel;
+       struct ath9k_channel *init_channel;
+       int r, pos;
+
+       DPRINTF(sc, ATH_DBG_CONFIG, "Starting driver with "
+               "initial channel: %d MHz\n", curchan->center_freq);
+
+       mutex_lock(&sc->mutex);
+
+       if (ath9k_wiphy_started(sc)) {
+               if (sc->chan_idx == curchan->hw_value) {
+                       /*
+                        * Already on the operational channel, the new wiphy
+                        * can be marked active.
+                        */
+                       aphy->state = ATH_WIPHY_ACTIVE;
+                       ieee80211_wake_queues(hw);
+               } else {
+                       /*
+                        * Another wiphy is on another channel, start the new
+                        * wiphy in paused state.
+                        */
+                       aphy->state = ATH_WIPHY_PAUSED;
+                       ieee80211_stop_queues(hw);
+               }
+               mutex_unlock(&sc->mutex);
+               return 0;
+       }
+       aphy->state = ATH_WIPHY_ACTIVE;
+
+       /* setup initial channel */
+
+       pos = curchan->hw_value;
+
+       sc->chan_idx = pos;
+       init_channel = &sc->sc_ah->channels[pos];
+       ath9k_update_ichannel(sc, hw, init_channel);
+
+       /* Reset SERDES registers */
+       ath9k_hw_configpcipowersave(sc->sc_ah, 0);
+
+       /*
+        * The basic interface to setting the hardware in a good
+        * state is ``reset''.  On return the hardware is known to
+        * be powered up and with interrupts disabled.  This must
+        * be followed by initialization of the appropriate bits
+        * and then setup of the interrupt mask.
+        */
+       spin_lock_bh(&sc->sc_resetlock);
+       r = ath9k_hw_reset(sc->sc_ah, init_channel, false);
+       if (r) {
+               DPRINTF(sc, ATH_DBG_FATAL,
+                       "Unable to reset hardware; reset status %d "
+                       "(freq %u MHz)\n", r,
+                       curchan->center_freq);
+               spin_unlock_bh(&sc->sc_resetlock);
+               goto mutex_unlock;
+       }
+       spin_unlock_bh(&sc->sc_resetlock);
+
+       /*
+        * This is needed only to setup initial state
+        * but it's best done after a reset.
+        */
+       ath_update_txpow(sc);
+
+       /*
+        * Setup the hardware after reset:
+        * The receive engine is set going.
+        * Frame transmit is handled entirely
+        * in the frame output path; there's nothing to do
+        * here except setup the interrupt mask.
+        */
+       if (ath_startrecv(sc) != 0) {
+               DPRINTF(sc, ATH_DBG_FATAL, "Unable to start recv logic\n");
+               r = -EIO;
+               goto mutex_unlock;
+       }
+
+       /* Setup our intr mask. */
+       sc->imask = ATH9K_INT_RX | ATH9K_INT_TX
+               | ATH9K_INT_RXEOL | ATH9K_INT_RXORN
+               | ATH9K_INT_FATAL | ATH9K_INT_GLOBAL;
+
+       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_GTT)
+               sc->imask |= ATH9K_INT_GTT;
+
+       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT)
+               sc->imask |= ATH9K_INT_CST;
+
+       ath_cache_conf_rate(sc, &hw->conf);
+
+       sc->sc_flags &= ~SC_OP_INVALID;
+
+       /* Disable BMISS interrupt when we're not associated */
+       sc->imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS);
+       ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
+
+       ieee80211_wake_queues(hw);
+
+#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
+       r = ath_start_rfkill_poll(sc);
+#endif
+
+mutex_unlock:
+       mutex_unlock(&sc->mutex);
+
+       return r;
+}
+
+static int ath9k_tx(struct ieee80211_hw *hw,
+                   struct sk_buff *skb)
+{
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+       struct ath_wiphy *aphy = hw->priv;
+       struct ath_softc *sc = aphy->sc;
+       struct ath_tx_control txctl;
+       int hdrlen, padsize;
+
+       if (aphy->state != ATH_WIPHY_ACTIVE && aphy->state != ATH_WIPHY_SCAN) {
+               printk(KERN_DEBUG "ath9k: %s: TX in unexpected wiphy state "
+                      "%d\n", wiphy_name(hw->wiphy), aphy->state);
+               goto exit;
+       }
+
+       if (sc->hw->conf.flags & IEEE80211_CONF_PS) {
+               struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+               /*
+                * mac80211 does not set PM field for normal data frames, so we
+                * need to update that based on the current PS mode.
+                */
+               if (ieee80211_is_data(hdr->frame_control) &&
+                   !ieee80211_is_nullfunc(hdr->frame_control) &&
+                   !ieee80211_has_pm(hdr->frame_control)) {
+                       DPRINTF(sc, ATH_DBG_PS, "Add PM=1 for a TX frame "
+                               "while in PS mode\n");
+                       hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM);
+               }
+       }
+
+       if (unlikely(sc->sc_ah->power_mode != ATH9K_PM_AWAKE)) {
+               /*
+                * We are using PS-Poll and mac80211 can request TX while in
+                * power save mode. Need to wake up hardware for the TX to be
+                * completed and if needed, also for RX of buffered frames.
+                */
+               struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+               ath9k_ps_wakeup(sc);
+               ath9k_hw_setrxabort(sc->sc_ah, 0);
+               if (ieee80211_is_pspoll(hdr->frame_control)) {
+                       DPRINTF(sc, ATH_DBG_PS, "Sending PS-Poll to pick a "
+                               "buffered frame\n");
+                       sc->sc_flags |= SC_OP_WAIT_FOR_PSPOLL_DATA;
+               } else {
+                       DPRINTF(sc, ATH_DBG_PS, "Wake up to complete TX\n");
+                       sc->sc_flags |= SC_OP_WAIT_FOR_TX_ACK;
+               }
+               /*
+                * The actual restore operation will happen only after
+                * the sc_flags bit is cleared. We are just dropping
+                * the ps_usecount here.
+                */
+               ath9k_ps_restore(sc);
+       }
+
+       memset(&txctl, 0, sizeof(struct ath_tx_control));
+
+       /*
+        * As a temporary workaround, assign seq# here; this will likely need
+        * to be cleaned up to work better with Beacon transmission and virtual
+        * BSSes.
+        */
+       if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
+               struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+               if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
+                       sc->tx.seq_no += 0x10;
+               hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
+               hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no);
+       }
+
+       /* Add the padding after the header if this is not already done */
+       hdrlen = ieee80211_get_hdrlen_from_skb(skb);
+       if (hdrlen & 3) {
+               padsize = hdrlen % 4;
+               if (skb_headroom(skb) < padsize)
+                       return -1;
+               skb_push(skb, padsize);
+               memmove(skb->data, skb->data + padsize, hdrlen);
+       }
+
+       /* Check if a tx queue is available */
+
+       txctl.txq = ath_test_get_txq(sc, skb);
+       if (!txctl.txq)
+               goto exit;
+
+       DPRINTF(sc, ATH_DBG_XMIT, "transmitting packet, skb: %p\n", skb);
+
+       if (ath_tx_start(hw, skb, &txctl) != 0) {
+               DPRINTF(sc, ATH_DBG_XMIT, "TX failed\n");
+               goto exit;
+       }
+
+       return 0;
+exit:
+       dev_kfree_skb_any(skb);
+       return 0;
+}
+
+static void ath9k_stop(struct ieee80211_hw *hw)
+{
+       struct ath_wiphy *aphy = hw->priv;
+       struct ath_softc *sc = aphy->sc;
+
+       aphy->state = ATH_WIPHY_INACTIVE;
+
+       if (sc->sc_flags & SC_OP_INVALID) {
+               DPRINTF(sc, ATH_DBG_ANY, "Device not present\n");
+               return;
+       }
+
+       mutex_lock(&sc->mutex);
+
+       ieee80211_stop_queues(hw);
+
+       if (ath9k_wiphy_started(sc)) {
+               mutex_unlock(&sc->mutex);
+               return; /* another wiphy still in use */
+       }
+
+       /* make sure h/w will not generate any interrupt
+        * before setting the invalid flag. */
+       ath9k_hw_set_interrupts(sc->sc_ah, 0);
+
+       if (!(sc->sc_flags & SC_OP_INVALID)) {
+               ath_drain_all_txq(sc, false);
+               ath_stoprecv(sc);
+               ath9k_hw_phy_disable(sc->sc_ah);
+       } else
+               sc->rx.rxlink = NULL;
+
+       rfkill_pause_polling(sc->rf_kill.rfkill);
+
+       /* disable HAL and put h/w to sleep */
+       ath9k_hw_disable(sc->sc_ah);
+       ath9k_hw_configpcipowersave(sc->sc_ah, 1);
+
+       sc->sc_flags |= SC_OP_INVALID;
+
+       mutex_unlock(&sc->mutex);
+
+       DPRINTF(sc, ATH_DBG_CONFIG, "Driver halt\n");
+}
+
+static int ath9k_add_interface(struct ieee80211_hw *hw,
+                              struct ieee80211_if_init_conf *conf)
+{
+       struct ath_wiphy *aphy = hw->priv;
+       struct ath_softc *sc = aphy->sc;
+       struct ath_vif *avp = (void *)conf->vif->drv_priv;
+       enum nl80211_iftype ic_opmode = NL80211_IFTYPE_UNSPECIFIED;
+       int ret = 0;
+
+       mutex_lock(&sc->mutex);
+
+       if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) &&
+           sc->nvifs > 0) {
+               ret = -ENOBUFS;
+               goto out;
+       }
+
+       switch (conf->type) {
+       case NL80211_IFTYPE_STATION:
+               ic_opmode = NL80211_IFTYPE_STATION;
+               break;
+       case NL80211_IFTYPE_ADHOC:
+       case NL80211_IFTYPE_AP:
+       case NL80211_IFTYPE_MESH_POINT:
+               if (sc->nbcnvifs >= ATH_BCBUF) {
+                       ret = -ENOBUFS;
+                       goto out;
+               }
+               ic_opmode = conf->type;
+               break;
+       default:
+               DPRINTF(sc, ATH_DBG_FATAL,
+                       "Interface type %d not yet supported\n", conf->type);
+               ret = -EOPNOTSUPP;
+               goto out;
+       }
+
+       DPRINTF(sc, ATH_DBG_CONFIG, "Attach a VIF of type: %d\n", ic_opmode);
+
+       /* Set the VIF opmode */
+       avp->av_opmode = ic_opmode;
+       avp->av_bslot = -1;
+
+       sc->nvifs++;
+
+       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK)
+               ath9k_set_bssid_mask(hw);
+
+       if (sc->nvifs > 1)
+               goto out; /* skip global settings for secondary vif */
+
+       if (ic_opmode == NL80211_IFTYPE_AP) {
+               ath9k_hw_set_tsfadjust(sc->sc_ah, 1);
+               sc->sc_flags |= SC_OP_TSF_RESET;
+       }
+
+       /* Set the device opmode */
+       sc->sc_ah->opmode = ic_opmode;
+
+       /*
+        * Enable MIB interrupts when there are hardware phy counters.
+        * Note we only do this (at the moment) for station mode.
+        */
+       if ((conf->type == NL80211_IFTYPE_STATION) ||
+           (conf->type == NL80211_IFTYPE_ADHOC) ||
+           (conf->type == NL80211_IFTYPE_MESH_POINT)) {
+               if (ath9k_hw_phycounters(sc->sc_ah))
+                       sc->imask |= ATH9K_INT_MIB;
+               sc->imask |= ATH9K_INT_TSFOOR;
+       }
+
+       ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
+
+       if (conf->type == NL80211_IFTYPE_AP)
+               ath_start_ani(sc);
+
+out:
+       mutex_unlock(&sc->mutex);
+       return ret;
+}
+
+static void ath9k_remove_interface(struct ieee80211_hw *hw,
+                                  struct ieee80211_if_init_conf *conf)
+{
+       struct ath_wiphy *aphy = hw->priv;
+       struct ath_softc *sc = aphy->sc;
+       struct ath_vif *avp = (void *)conf->vif->drv_priv;
+       int i;
+
+       DPRINTF(sc, ATH_DBG_CONFIG, "Detach Interface\n");
+
+       mutex_lock(&sc->mutex);
+
+       /* Stop ANI */
+       del_timer_sync(&sc->ani.timer);
+
+       /* Reclaim beacon resources */
+       if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) ||
+           (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) ||
+           (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) {
+               ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
+               ath_beacon_return(sc, avp);
+       }
+
+       sc->sc_flags &= ~SC_OP_BEACONS;
+
+       for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) {
+               if (sc->beacon.bslot[i] == conf->vif) {
+                       printk(KERN_DEBUG "%s: vif had allocated beacon "
+                              "slot\n", __func__);
+                       sc->beacon.bslot[i] = NULL;
+                       sc->beacon.bslot_aphy[i] = NULL;
+               }
+       }
+
+       sc->nvifs--;
+
+       mutex_unlock(&sc->mutex);
+}
+
+static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
+{
+       struct ath_wiphy *aphy = hw->priv;
+       struct ath_softc *sc = aphy->sc;
+       struct ieee80211_conf *conf = &hw->conf;
+       struct ath_hw *ah = sc->sc_ah;
+
+       mutex_lock(&sc->mutex);
+
+       if (changed & IEEE80211_CONF_CHANGE_PS) {
+               if (conf->flags & IEEE80211_CONF_PS) {
+                       if (!(ah->caps.hw_caps &
+                             ATH9K_HW_CAP_AUTOSLEEP)) {
+                               if ((sc->imask & ATH9K_INT_TIM_TIMER) == 0) {
+                                       sc->imask |= ATH9K_INT_TIM_TIMER;
+                                       ath9k_hw_set_interrupts(sc->sc_ah,
+                                                       sc->imask);
+                               }
+                               ath9k_hw_setrxabort(sc->sc_ah, 1);
+                       }
+                       ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_NETWORK_SLEEP);
+               } else {
+                       ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE);
+                       if (!(ah->caps.hw_caps &
+                             ATH9K_HW_CAP_AUTOSLEEP)) {
+                               ath9k_hw_setrxabort(sc->sc_ah, 0);
+                               sc->sc_flags &= ~(SC_OP_WAIT_FOR_BEACON |
+                                                 SC_OP_WAIT_FOR_CAB |
+                                                 SC_OP_WAIT_FOR_PSPOLL_DATA |
+                                                 SC_OP_WAIT_FOR_TX_ACK);
+                               if (sc->imask & ATH9K_INT_TIM_TIMER) {
+                                       sc->imask &= ~ATH9K_INT_TIM_TIMER;
+                                       ath9k_hw_set_interrupts(sc->sc_ah,
+                                                       sc->imask);
+                               }
+                       }
+               }
+       }
+
+       if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
+               struct ieee80211_channel *curchan = hw->conf.channel;
+               int pos = curchan->hw_value;
+
+               aphy->chan_idx = pos;
+               aphy->chan_is_ht = conf_is_ht(conf);
+
+               if (aphy->state == ATH_WIPHY_SCAN ||
+                   aphy->state == ATH_WIPHY_ACTIVE)
+                       ath9k_wiphy_pause_all_forced(sc, aphy);
+               else {
+                       /*
+                        * Do not change operational channel based on a paused
+                        * wiphy changes.
+                        */
+                       goto skip_chan_change;
+               }
+
+               DPRINTF(sc, ATH_DBG_CONFIG, "Set channel: %d MHz\n",
+                       curchan->center_freq);
+
+               /* XXX: remove me eventualy */
+               ath9k_update_ichannel(sc, hw, &sc->sc_ah->channels[pos]);
+
+               ath_update_chainmask(sc, conf_is_ht(conf));
+
+               if (ath_set_channel(sc, hw, &sc->sc_ah->channels[pos]) < 0) {
+                       DPRINTF(sc, ATH_DBG_FATAL, "Unable to set channel\n");
+                       mutex_unlock(&sc->mutex);
+                       return -EINVAL;
+               }
+       }
+
+skip_chan_change:
+       if (changed & IEEE80211_CONF_CHANGE_POWER)
+               sc->config.txpowlimit = 2 * conf->power_level;
+
+       mutex_unlock(&sc->mutex);
+
+       return 0;
+}
+
+#define SUPPORTED_FILTERS                      \
+       (FIF_PROMISC_IN_BSS |                   \
+       FIF_ALLMULTI |                          \
+       FIF_CONTROL |                           \
+       FIF_OTHER_BSS |                         \
+       FIF_BCN_PRBRESP_PROMISC |               \
+       FIF_FCSFAIL)
+
+/* FIXME: sc->sc_full_reset ? */
+static void ath9k_configure_filter(struct ieee80211_hw *hw,
+                                  unsigned int changed_flags,
+                                  unsigned int *total_flags,
+                                  int mc_count,
+                                  struct dev_mc_list *mclist)
+{
+       struct ath_wiphy *aphy = hw->priv;
+       struct ath_softc *sc = aphy->sc;
+       u32 rfilt;
+
+       changed_flags &= SUPPORTED_FILTERS;
+       *total_flags &= SUPPORTED_FILTERS;
+
+       sc->rx.rxfilter = *total_flags;
+       ath9k_ps_wakeup(sc);
+       rfilt = ath_calcrxfilter(sc);
+       ath9k_hw_setrxfilter(sc->sc_ah, rfilt);
+       ath9k_ps_restore(sc);
+
+       DPRINTF(sc, ATH_DBG_CONFIG, "Set HW RX filter: 0x%x\n", sc->rx.rxfilter);
+}
+
+static void ath9k_sta_notify(struct ieee80211_hw *hw,
+                            struct ieee80211_vif *vif,
+                            enum sta_notify_cmd cmd,
+                            struct ieee80211_sta *sta)
+{
+       struct ath_wiphy *aphy = hw->priv;
+       struct ath_softc *sc = aphy->sc;
+
+       switch (cmd) {
+       case STA_NOTIFY_ADD:
+               ath_node_attach(sc, sta);
+               break;
+       case STA_NOTIFY_REMOVE:
+               ath_node_detach(sc, sta);
+               break;
+       default:
+               break;
+       }
+}
+
+static int ath9k_conf_tx(struct ieee80211_hw *hw, u16 queue,
+                        const struct ieee80211_tx_queue_params *params)
+{
+       struct ath_wiphy *aphy = hw->priv;
+       struct ath_softc *sc = aphy->sc;
+       struct ath9k_tx_queue_info qi;
+       int ret = 0, qnum;
+
+       if (queue >= WME_NUM_AC)
+               return 0;
+
+       mutex_lock(&sc->mutex);
+
+       memset(&qi, 0, sizeof(struct ath9k_tx_queue_info));
+
+       qi.tqi_aifs = params->aifs;
+       qi.tqi_cwmin = params->cw_min;
+       qi.tqi_cwmax = params->cw_max;
+       qi.tqi_burstTime = params->txop;
+       qnum = ath_get_hal_qnum(queue, sc);
+
+       DPRINTF(sc, ATH_DBG_CONFIG,
+               "Configure tx [queue/halq] [%d/%d],  "
+               "aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n",
+               queue, qnum, params->aifs, params->cw_min,
+               params->cw_max, params->txop);
+
+       ret = ath_txq_update(sc, qnum, &qi);
+       if (ret)
+               DPRINTF(sc, ATH_DBG_FATAL, "TXQ Update failed\n");
+
+       mutex_unlock(&sc->mutex);
+
+       return ret;
+}
+
+static int ath9k_set_key(struct ieee80211_hw *hw,
+                        enum set_key_cmd cmd,
+                        struct ieee80211_vif *vif,
+                        struct ieee80211_sta *sta,
+                        struct ieee80211_key_conf *key)
+{
+       struct ath_wiphy *aphy = hw->priv;
+       struct ath_softc *sc = aphy->sc;
+       int ret = 0;
+
+       if (modparam_nohwcrypt)
+               return -ENOSPC;
+
+       mutex_lock(&sc->mutex);
+       ath9k_ps_wakeup(sc);
+       DPRINTF(sc, ATH_DBG_CONFIG, "Set HW Key\n");
+
+       switch (cmd) {
+       case SET_KEY:
+               ret = ath_key_config(sc, vif, sta, key);
+               if (ret >= 0) {
+                       key->hw_key_idx = ret;
+                       /* push IV and Michael MIC generation to stack */
+                       key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
+                       if (key->alg == ALG_TKIP)
+                               key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
+                       if (sc->sc_ah->sw_mgmt_crypto && key->alg == ALG_CCMP)
+                               key->flags |= IEEE80211_KEY_FLAG_SW_MGMT;
+                       ret = 0;
+               }
+               break;
+       case DISABLE_KEY:
+               ath_key_delete(sc, key);
+               break;
+       default:
+               ret = -EINVAL;
+       }
+
+       ath9k_ps_restore(sc);
+       mutex_unlock(&sc->mutex);
+
+       return ret;
+}
+
+static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
+                                  struct ieee80211_vif *vif,
+                                  struct ieee80211_bss_conf *bss_conf,
+                                  u32 changed)
+{
+       struct ath_wiphy *aphy = hw->priv;
+       struct ath_softc *sc = aphy->sc;
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath_vif *avp = (void *)vif->drv_priv;
+       u32 rfilt = 0;
+       int error, i;
+
+       mutex_lock(&sc->mutex);
+
+       /*
+        * TODO: Need to decide which hw opmode to use for
+        *       multi-interface cases
+        * XXX: This belongs into add_interface!
+        */
+       if (vif->type == NL80211_IFTYPE_AP &&
+           ah->opmode != NL80211_IFTYPE_AP) {
+               ah->opmode = NL80211_IFTYPE_STATION;
+               ath9k_hw_setopmode(ah);
+               memcpy(sc->curbssid, sc->sc_ah->macaddr, ETH_ALEN);
+               sc->curaid = 0;
+               ath9k_hw_write_associd(sc);
+               /* Request full reset to get hw opmode changed properly */
+               sc->sc_flags |= SC_OP_FULL_RESET;
+       }
+
+       if ((changed & BSS_CHANGED_BSSID) &&
+           !is_zero_ether_addr(bss_conf->bssid)) {
+               switch (vif->type) {
+               case NL80211_IFTYPE_STATION:
+               case NL80211_IFTYPE_ADHOC:
+               case NL80211_IFTYPE_MESH_POINT:
+                       /* Set BSSID */
+                       memcpy(sc->curbssid, bss_conf->bssid, ETH_ALEN);
+                       memcpy(avp->bssid, bss_conf->bssid, ETH_ALEN);
+                       sc->curaid = 0;
+                       ath9k_hw_write_associd(sc);
+
+                       /* Set aggregation protection mode parameters */
+                       sc->config.ath_aggr_prot = 0;
+
+                       DPRINTF(sc, ATH_DBG_CONFIG,
+                               "RX filter 0x%x bssid %pM aid 0x%x\n",
+                               rfilt, sc->curbssid, sc->curaid);
+
+                       /* need to reconfigure the beacon */
+                       sc->sc_flags &= ~SC_OP_BEACONS ;
+
+                       break;
+               default:
+                       break;
+               }
+       }
+
+       if ((vif->type == NL80211_IFTYPE_ADHOC) ||
+           (vif->type == NL80211_IFTYPE_AP) ||
+           (vif->type == NL80211_IFTYPE_MESH_POINT)) {
+               if ((changed & BSS_CHANGED_BEACON) ||
+                   (changed & BSS_CHANGED_BEACON_ENABLED &&
+                    bss_conf->enable_beacon)) {
+                       /*
+                        * Allocate and setup the beacon frame.
+                        *
+                        * Stop any previous beacon DMA.  This may be
+                        * necessary, for example, when an ibss merge
+                        * causes reconfiguration; we may be called
+                        * with beacon transmission active.
+                        */
+                       ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
+
+                       error = ath_beacon_alloc(aphy, vif);
+                       if (!error)
+                               ath_beacon_config(sc, vif);
+               }
+       }
+
+       /* Check for WLAN_CAPABILITY_PRIVACY ? */
+       if ((avp->av_opmode != NL80211_IFTYPE_STATION)) {
+               for (i = 0; i < IEEE80211_WEP_NKID; i++)
+                       if (ath9k_hw_keyisvalid(sc->sc_ah, (u16)i))
+                               ath9k_hw_keysetmac(sc->sc_ah,
+                                                  (u16)i,
+                                                  sc->curbssid);
+       }
+
+       /* Only legacy IBSS for now */
+       if (vif->type == NL80211_IFTYPE_ADHOC)
+               ath_update_chainmask(sc, 0);
+
+       if (changed & BSS_CHANGED_ERP_PREAMBLE) {
+               DPRINTF(sc, ATH_DBG_CONFIG, "BSS Changed PREAMBLE %d\n",
+                       bss_conf->use_short_preamble);
+               if (bss_conf->use_short_preamble)
+                       sc->sc_flags |= SC_OP_PREAMBLE_SHORT;
+               else
+                       sc->sc_flags &= ~SC_OP_PREAMBLE_SHORT;
+       }
+
+       if (changed & BSS_CHANGED_ERP_CTS_PROT) {
+               DPRINTF(sc, ATH_DBG_CONFIG, "BSS Changed CTS PROT %d\n",
+                       bss_conf->use_cts_prot);
+               if (bss_conf->use_cts_prot &&
+                   hw->conf.channel->band != IEEE80211_BAND_5GHZ)
+                       sc->sc_flags |= SC_OP_PROTECT_ENABLE;
+               else
+                       sc->sc_flags &= ~SC_OP_PROTECT_ENABLE;
+       }
+
+       if (changed & BSS_CHANGED_ASSOC) {
+               DPRINTF(sc, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n",
+                       bss_conf->assoc);
+               ath9k_bss_assoc_info(sc, vif, bss_conf);
+       }
+
+       /*
+        * The HW TSF has to be reset when the beacon interval changes.
+        * We set the flag here, and ath_beacon_config_ap() would take this
+        * into account when it gets called through the subsequent
+        * config_interface() call - with IFCC_BEACON in the changed field.
+        */
+
+       if (changed & BSS_CHANGED_BEACON_INT) {
+               sc->sc_flags |= SC_OP_TSF_RESET;
+               sc->beacon_interval = bss_conf->beacon_int;
+       }
+
+       mutex_unlock(&sc->mutex);
+}
+
+static u64 ath9k_get_tsf(struct ieee80211_hw *hw)
+{
+       u64 tsf;
+       struct ath_wiphy *aphy = hw->priv;
+       struct ath_softc *sc = aphy->sc;
+
+       mutex_lock(&sc->mutex);
+       tsf = ath9k_hw_gettsf64(sc->sc_ah);
+       mutex_unlock(&sc->mutex);
+
+       return tsf;
+}
+
+static void ath9k_set_tsf(struct ieee80211_hw *hw, u64 tsf)
+{
+       struct ath_wiphy *aphy = hw->priv;
+       struct ath_softc *sc = aphy->sc;
+
+       mutex_lock(&sc->mutex);
+       ath9k_hw_settsf64(sc->sc_ah, tsf);
+       mutex_unlock(&sc->mutex);
+}
+
+static void ath9k_reset_tsf(struct ieee80211_hw *hw)
+{
+       struct ath_wiphy *aphy = hw->priv;
+       struct ath_softc *sc = aphy->sc;
+
+       mutex_lock(&sc->mutex);
+       ath9k_hw_reset_tsf(sc->sc_ah);
+       mutex_unlock(&sc->mutex);
+}
+
+static int ath9k_ampdu_action(struct ieee80211_hw *hw,
+                             enum ieee80211_ampdu_mlme_action action,
+                             struct ieee80211_sta *sta,
+                             u16 tid, u16 *ssn)
+{
+       struct ath_wiphy *aphy = hw->priv;
+       struct ath_softc *sc = aphy->sc;
+       int ret = 0;
+
+       switch (action) {
+       case IEEE80211_AMPDU_RX_START:
+               if (!(sc->sc_flags & SC_OP_RXAGGR))
+                       ret = -ENOTSUPP;
+               break;
+       case IEEE80211_AMPDU_RX_STOP:
+               break;
+       case IEEE80211_AMPDU_TX_START:
+               ret = ath_tx_aggr_start(sc, sta, tid, ssn);
+               if (ret < 0)
+                       DPRINTF(sc, ATH_DBG_FATAL,
+                               "Unable to start TX aggregation\n");
+               else
+                       ieee80211_start_tx_ba_cb_irqsafe(hw, sta->addr, tid);
+               break;
+       case IEEE80211_AMPDU_TX_STOP:
+               ret = ath_tx_aggr_stop(sc, sta, tid);
+               if (ret < 0)
+                       DPRINTF(sc, ATH_DBG_FATAL,
+                               "Unable to stop TX aggregation\n");
+
+               ieee80211_stop_tx_ba_cb_irqsafe(hw, sta->addr, tid);
+               break;
+       case IEEE80211_AMPDU_TX_OPERATIONAL:
+               ath_tx_aggr_resume(sc, sta, tid);
+               break;
+       default:
+               DPRINTF(sc, ATH_DBG_FATAL, "Unknown AMPDU action\n");
+       }
+
+       return ret;
+}
+
+static void ath9k_sw_scan_start(struct ieee80211_hw *hw)
+{
+       struct ath_wiphy *aphy = hw->priv;
+       struct ath_softc *sc = aphy->sc;
+
+       if (ath9k_wiphy_scanning(sc)) {
+               printk(KERN_DEBUG "ath9k: Two wiphys trying to scan at the "
+                      "same time\n");
+               /*
+                * Do not allow the concurrent scanning state for now. This
+                * could be improved with scanning control moved into ath9k.
+                */
+               return;
+       }
+
+       aphy->state = ATH_WIPHY_SCAN;
+       ath9k_wiphy_pause_all_forced(sc, aphy);
+
+       mutex_lock(&sc->mutex);
+       sc->sc_flags |= SC_OP_SCANNING;
+       mutex_unlock(&sc->mutex);
+}
+
+static void ath9k_sw_scan_complete(struct ieee80211_hw *hw)
+{
+       struct ath_wiphy *aphy = hw->priv;
+       struct ath_softc *sc = aphy->sc;
+
+       mutex_lock(&sc->mutex);
+       aphy->state = ATH_WIPHY_ACTIVE;
+       sc->sc_flags &= ~SC_OP_SCANNING;
+       sc->sc_flags |= SC_OP_FULL_RESET;
+       mutex_unlock(&sc->mutex);
+}
+
+struct ieee80211_ops ath9k_ops = {
+       .tx                 = ath9k_tx,
+       .start              = ath9k_start,
+       .stop               = ath9k_stop,
+       .add_interface      = ath9k_add_interface,
+       .remove_interface   = ath9k_remove_interface,
+       .config             = ath9k_config,
+       .configure_filter   = ath9k_configure_filter,
+       .sta_notify         = ath9k_sta_notify,
+       .conf_tx            = ath9k_conf_tx,
+       .bss_info_changed   = ath9k_bss_info_changed,
+       .set_key            = ath9k_set_key,
+       .get_tsf            = ath9k_get_tsf,
+       .set_tsf            = ath9k_set_tsf,
+       .reset_tsf          = ath9k_reset_tsf,
+       .ampdu_action       = ath9k_ampdu_action,
+       .sw_scan_start      = ath9k_sw_scan_start,
+       .sw_scan_complete   = ath9k_sw_scan_complete,
+};
+
+static struct {
+       u32 version;
+       const char * name;
+} ath_mac_bb_names[] = {
+       { AR_SREV_VERSION_5416_PCI,     "5416" },
+       { AR_SREV_VERSION_5416_PCIE,    "5418" },
+       { AR_SREV_VERSION_9100,         "9100" },
+       { AR_SREV_VERSION_9160,         "9160" },
+       { AR_SREV_VERSION_9280,         "9280" },
+       { AR_SREV_VERSION_9285,         "9285" }
+};
+
+static struct {
+       u16 version;
+       const char * name;
+} ath_rf_names[] = {
+       { 0,                            "5133" },
+       { AR_RAD5133_SREV_MAJOR,        "5133" },
+       { AR_RAD5122_SREV_MAJOR,        "5122" },
+       { AR_RAD2133_SREV_MAJOR,        "2133" },
+       { AR_RAD2122_SREV_MAJOR,        "2122" }
+};
+
+/*
+ * Return the MAC/BB name. "????" is returned if the MAC/BB is unknown.
+ */
+const char *
+ath_mac_bb_name(u32 mac_bb_version)
+{
+       int i;
+
+       for (i=0; i<ARRAY_SIZE(ath_mac_bb_names); i++) {
+               if (ath_mac_bb_names[i].version == mac_bb_version) {
+                       return ath_mac_bb_names[i].name;
+               }
+       }
+
+       return "????";
+}
+
+/*
+ * Return the RF name. "????" is returned if the RF is unknown.
+ */
+const char *
+ath_rf_name(u16 rf_version)
+{
+       int i;
+
+       for (i=0; i<ARRAY_SIZE(ath_rf_names); i++) {
+               if (ath_rf_names[i].version == rf_version) {
+                       return ath_rf_names[i].name;
+               }
+       }
+
+       return "????";
+}
+
+static int __init ath9k_init(void)
+{
+       int error;
+
+       /* Register rate control algorithm */
+       error = ath_rate_control_register();
+       if (error != 0) {
+               printk(KERN_ERR
+                       "ath9k: Unable to register rate control "
+                       "algorithm: %d\n",
+                       error);
+               goto err_out;
+       }
+
+       error = ath9k_debug_create_root();
+       if (error) {
+               printk(KERN_ERR
+                       "ath9k: Unable to create debugfs root: %d\n",
+                       error);
+               goto err_rate_unregister;
+       }
+
+       error = ath_pci_init();
+       if (error < 0) {
+               printk(KERN_ERR
+                       "ath9k: No PCI devices found, driver not installed.\n");
+               error = -ENODEV;
+               goto err_remove_root;
+       }
+
+       error = ath_ahb_init();
+       if (error < 0) {
+               error = -ENODEV;
+               goto err_pci_exit;
+       }
+
+       return 0;
+
+ err_pci_exit:
+       ath_pci_exit();
+
+ err_remove_root:
+       ath9k_debug_remove_root();
+ err_rate_unregister:
+       ath_rate_control_unregister();
+ err_out:
+       return error;
+}
+module_init(ath9k_init);
+
+static void __exit ath9k_exit(void)
+{
+       ath_ahb_exit();
+       ath_pci_exit();
+       ath9k_debug_remove_root();
+       ath_rate_control_unregister();
+       printk(KERN_INFO "%s: Driver unloaded\n", dev_info);
+}
+module_exit(ath9k_exit);
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
new file mode 100644 (file)
index 0000000..ccdf20a
--- /dev/null
@@ -0,0 +1,280 @@
+/*
+ * Copyright (c) 2008-2009 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/nl80211.h>
+#include <linux/pci.h>
+#include "ath9k.h"
+
+static struct pci_device_id ath_pci_id_table[] __devinitdata = {
+       { PCI_VDEVICE(ATHEROS, 0x0023) }, /* PCI   */
+       { PCI_VDEVICE(ATHEROS, 0x0024) }, /* PCI-E */
+       { PCI_VDEVICE(ATHEROS, 0x0027) }, /* PCI   */
+       { PCI_VDEVICE(ATHEROS, 0x0029) }, /* PCI   */
+       { PCI_VDEVICE(ATHEROS, 0x002A) }, /* PCI-E */
+       { PCI_VDEVICE(ATHEROS, 0x002B) }, /* PCI-E */
+       { 0 }
+};
+
+/* return bus cachesize in 4B word units */
+static void ath_pci_read_cachesize(struct ath_softc *sc, int *csz)
+{
+       u8 u8tmp;
+
+       pci_read_config_byte(to_pci_dev(sc->dev), PCI_CACHE_LINE_SIZE,
+                            (u8 *)&u8tmp);
+       *csz = (int)u8tmp;
+
+       /*
+        * This check was put in to avoid "unplesant" consequences if
+        * the bootrom has not fully initialized all PCI devices.
+        * Sometimes the cache line size register is not set
+        */
+
+       if (*csz == 0)
+               *csz = DEFAULT_CACHELINE >> 2;   /* Use the default size */
+}
+
+static void ath_pci_cleanup(struct ath_softc *sc)
+{
+       struct pci_dev *pdev = to_pci_dev(sc->dev);
+
+       pci_iounmap(pdev, sc->mem);
+       pci_disable_device(pdev);
+       pci_release_region(pdev, 0);
+}
+
+static bool ath_pci_eeprom_read(struct ath_hw *ah, u32 off, u16 *data)
+{
+       (void)REG_READ(ah, AR5416_EEPROM_OFFSET + (off << AR5416_EEPROM_S));
+
+       if (!ath9k_hw_wait(ah,
+                          AR_EEPROM_STATUS_DATA,
+                          AR_EEPROM_STATUS_DATA_BUSY |
+                          AR_EEPROM_STATUS_DATA_PROT_ACCESS, 0,
+                          AH_WAIT_TIMEOUT)) {
+               return false;
+       }
+
+       *data = MS(REG_READ(ah, AR_EEPROM_STATUS_DATA),
+                  AR_EEPROM_STATUS_DATA_VAL);
+
+       return true;
+}
+
+static struct ath_bus_ops ath_pci_bus_ops = {
+       .read_cachesize = ath_pci_read_cachesize,
+       .cleanup = ath_pci_cleanup,
+       .eeprom_read = ath_pci_eeprom_read,
+};
+
+static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+{
+       void __iomem *mem;
+       struct ath_wiphy *aphy;
+       struct ath_softc *sc;
+       struct ieee80211_hw *hw;
+       u8 csz;
+       int ret = 0;
+       struct ath_hw *ah;
+
+       if (pci_enable_device(pdev))
+               return -EIO;
+
+       ret =  pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+
+       if (ret) {
+               printk(KERN_ERR "ath9k: 32-bit DMA not available\n");
+               goto bad;
+       }
+
+       ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
+
+       if (ret) {
+               printk(KERN_ERR "ath9k: 32-bit DMA consistent "
+                       "DMA enable failed\n");
+               goto bad;
+       }
+
+       /*
+        * Cache line size is used to size and align various
+        * structures used to communicate with the hardware.
+        */
+       pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &csz);
+       if (csz == 0) {
+               /*
+                * Linux 2.4.18 (at least) writes the cache line size
+                * register as a 16-bit wide register which is wrong.
+                * We must have this setup properly for rx buffer
+                * DMA to work so force a reasonable value here if it
+                * comes up zero.
+                */
+               csz = L1_CACHE_BYTES / sizeof(u32);
+               pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz);
+       }
+       /*
+        * The default setting of latency timer yields poor results,
+        * set it to the value used by other systems. It may be worth
+        * tweaking this setting more.
+        */
+       pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xa8);
+
+       pci_set_master(pdev);
+
+       ret = pci_request_region(pdev, 0, "ath9k");
+       if (ret) {
+               dev_err(&pdev->dev, "PCI memory region reserve error\n");
+               ret = -ENODEV;
+               goto bad;
+       }
+
+       mem = pci_iomap(pdev, 0, 0);
+       if (!mem) {
+               printk(KERN_ERR "PCI memory map error\n") ;
+               ret = -EIO;
+               goto bad1;
+       }
+
+       hw = ieee80211_alloc_hw(sizeof(struct ath_wiphy) +
+                               sizeof(struct ath_softc), &ath9k_ops);
+       if (hw == NULL) {
+               printk(KERN_ERR "ath_pci: no memory for ieee80211_hw\n");
+               goto bad2;
+       }
+
+       SET_IEEE80211_DEV(hw, &pdev->dev);
+       pci_set_drvdata(pdev, hw);
+
+       aphy = hw->priv;
+       sc = (struct ath_softc *) (aphy + 1);
+       aphy->sc = sc;
+       aphy->hw = hw;
+       sc->pri_wiphy = aphy;
+       sc->hw = hw;
+       sc->dev = &pdev->dev;
+       sc->mem = mem;
+       sc->bus_ops = &ath_pci_bus_ops;
+
+       if (ath_attach(id->device, sc) != 0) {
+               ret = -ENODEV;
+               goto bad3;
+       }
+
+       /* setup interrupt service routine */
+
+       if (request_irq(pdev->irq, ath_isr, IRQF_SHARED, "ath", sc)) {
+               printk(KERN_ERR "%s: request_irq failed\n",
+                       wiphy_name(hw->wiphy));
+               ret = -EIO;
+               goto bad4;
+       }
+
+       sc->irq = pdev->irq;
+
+       ah = sc->sc_ah;
+       printk(KERN_INFO
+              "%s: Atheros AR%s MAC/BB Rev:%x "
+              "AR%s RF Rev:%x: mem=0x%lx, irq=%d\n",
+              wiphy_name(hw->wiphy),
+              ath_mac_bb_name(ah->hw_version.macVersion),
+              ah->hw_version.macRev,
+              ath_rf_name((ah->hw_version.analog5GhzRev & AR_RADIO_SREV_MAJOR)),
+              ah->hw_version.phyRev,
+              (unsigned long)mem, pdev->irq);
+
+       return 0;
+bad4:
+       ath_detach(sc);
+bad3:
+       ieee80211_free_hw(hw);
+bad2:
+       pci_iounmap(pdev, mem);
+bad1:
+       pci_release_region(pdev, 0);
+bad:
+       pci_disable_device(pdev);
+       return ret;
+}
+
+static void ath_pci_remove(struct pci_dev *pdev)
+{
+       struct ieee80211_hw *hw = pci_get_drvdata(pdev);
+       struct ath_wiphy *aphy = hw->priv;
+       struct ath_softc *sc = aphy->sc;
+
+       ath_cleanup(sc);
+}
+
+#ifdef CONFIG_PM
+
+static int ath_pci_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+       struct ieee80211_hw *hw = pci_get_drvdata(pdev);
+       struct ath_wiphy *aphy = hw->priv;
+       struct ath_softc *sc = aphy->sc;
+
+       ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1);
+
+       pci_save_state(pdev);
+       pci_disable_device(pdev);
+       pci_set_power_state(pdev, PCI_D3hot);
+
+       return 0;
+}
+
+static int ath_pci_resume(struct pci_dev *pdev)
+{
+       struct ieee80211_hw *hw = pci_get_drvdata(pdev);
+       struct ath_wiphy *aphy = hw->priv;
+       struct ath_softc *sc = aphy->sc;
+       int err;
+
+       err = pci_enable_device(pdev);
+       if (err)
+               return err;
+       pci_restore_state(pdev);
+
+       /* Enable LED */
+       ath9k_hw_cfg_output(sc->sc_ah, ATH_LED_PIN,
+                           AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
+       ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1);
+
+       return 0;
+}
+
+#endif /* CONFIG_PM */
+
+MODULE_DEVICE_TABLE(pci, ath_pci_id_table);
+
+static struct pci_driver ath_pci_driver = {
+       .name       = "ath9k",
+       .id_table   = ath_pci_id_table,
+       .probe      = ath_pci_probe,
+       .remove     = ath_pci_remove,
+#ifdef CONFIG_PM
+       .suspend    = ath_pci_suspend,
+       .resume     = ath_pci_resume,
+#endif /* CONFIG_PM */
+};
+
+int ath_pci_init(void)
+{
+       return pci_register_driver(&ath_pci_driver);
+}
+
+void ath_pci_exit(void)
+{
+       pci_unregister_driver(&ath_pci_driver);
+}
diff --git a/drivers/net/wireless/ath/ath9k/phy.c b/drivers/net/wireless/ath/ath9k/phy.c
new file mode 100644 (file)
index 0000000..aaa9415
--- /dev/null
@@ -0,0 +1,421 @@
+/*
+ * Copyright (c) 2008-2009 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 "ath9k.h"
+
+void
+ath9k_hw_write_regs(struct ath_hw *ah, u32 modesIndex, u32 freqIndex,
+                   int regWrites)
+{
+       REG_WRITE_ARRAY(&ah->iniBB_RfGain, freqIndex, regWrites);
+}
+
+bool
+ath9k_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
+{
+       u32 channelSel = 0;
+       u32 bModeSynth = 0;
+       u32 aModeRefSel = 0;
+       u32 reg32 = 0;
+       u16 freq;
+       struct chan_centers centers;
+
+       ath9k_hw_get_channel_centers(ah, chan, &centers);
+       freq = centers.synth_center;
+
+       if (freq < 4800) {
+               u32 txctl;
+
+               if (((freq - 2192) % 5) == 0) {
+                       channelSel = ((freq - 672) * 2 - 3040) / 10;
+                       bModeSynth = 0;
+               } else if (((freq - 2224) % 5) == 0) {
+                       channelSel = ((freq - 704) * 2 - 3040) / 10;
+                       bModeSynth = 1;
+               } else {
+                       DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+                               "Invalid channel %u MHz\n", freq);
+                       return false;
+               }
+
+               channelSel = (channelSel << 2) & 0xff;
+               channelSel = ath9k_hw_reverse_bits(channelSel, 8);
+
+               txctl = REG_READ(ah, AR_PHY_CCK_TX_CTRL);
+               if (freq == 2484) {
+
+                       REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
+                                 txctl | AR_PHY_CCK_TX_CTRL_JAPAN);
+               } else {
+                       REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
+                                 txctl & ~AR_PHY_CCK_TX_CTRL_JAPAN);
+               }
+
+       } else if ((freq % 20) == 0 && freq >= 5120) {
+               channelSel =
+                   ath9k_hw_reverse_bits(((freq - 4800) / 20 << 2), 8);
+               aModeRefSel = ath9k_hw_reverse_bits(1, 2);
+       } else if ((freq % 10) == 0) {
+               channelSel =
+                   ath9k_hw_reverse_bits(((freq - 4800) / 10 << 1), 8);
+               if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah))
+                       aModeRefSel = ath9k_hw_reverse_bits(2, 2);
+               else
+                       aModeRefSel = ath9k_hw_reverse_bits(1, 2);
+       } else if ((freq % 5) == 0) {
+               channelSel = ath9k_hw_reverse_bits((freq - 4800) / 5, 8);
+               aModeRefSel = ath9k_hw_reverse_bits(1, 2);
+       } else {
+               DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+                       "Invalid channel %u MHz\n", freq);
+               return false;
+       }
+
+       reg32 =
+           (channelSel << 8) | (aModeRefSel << 2) | (bModeSynth << 1) |
+           (1 << 5) | 0x1;
+
+       REG_WRITE(ah, AR_PHY(0x37), reg32);
+
+       ah->curchan = chan;
+       ah->curchan_rad_index = -1;
+
+       return true;
+}
+
+void ath9k_hw_ar9280_set_channel(struct ath_hw *ah,
+                                struct ath9k_channel *chan)
+{
+       u16 bMode, fracMode, aModeRefSel = 0;
+       u32 freq, ndiv, channelSel = 0, channelFrac = 0, reg32 = 0;
+       struct chan_centers centers;
+       u32 refDivA = 24;
+
+       ath9k_hw_get_channel_centers(ah, chan, &centers);
+       freq = centers.synth_center;
+
+       reg32 = REG_READ(ah, AR_PHY_SYNTH_CONTROL);
+       reg32 &= 0xc0000000;
+
+       if (freq < 4800) {
+               u32 txctl;
+
+               bMode = 1;
+               fracMode = 1;
+               aModeRefSel = 0;
+               channelSel = (freq * 0x10000) / 15;
+
+               txctl = REG_READ(ah, AR_PHY_CCK_TX_CTRL);
+               if (freq == 2484) {
+
+                       REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
+                                 txctl | AR_PHY_CCK_TX_CTRL_JAPAN);
+               } else {
+                       REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
+                                 txctl & ~AR_PHY_CCK_TX_CTRL_JAPAN);
+               }
+       } else {
+               bMode = 0;
+               fracMode = 0;
+
+               switch(ah->eep_ops->get_eeprom(ah, EEP_FRAC_N_5G)) {
+               case 0:
+                       if ((freq % 20) == 0) {
+                               aModeRefSel = 3;
+                       } else if ((freq % 10) == 0) {
+                               aModeRefSel = 2;
+                       }
+                       if (aModeRefSel)
+                               break;
+               case 1:
+               default:
+                       aModeRefSel = 0;
+                       fracMode = 1;
+                       refDivA = 1;
+                       channelSel = (freq * 0x8000) / 15;
+
+                       REG_RMW_FIELD(ah, AR_AN_SYNTH9,
+                                     AR_AN_SYNTH9_REFDIVA, refDivA);
+
+               }
+
+               if (!fracMode) {
+                       ndiv = (freq * (refDivA >> aModeRefSel)) / 60;
+                       channelSel = ndiv & 0x1ff;
+                       channelFrac = (ndiv & 0xfffffe00) * 2;
+                       channelSel = (channelSel << 17) | channelFrac;
+               }
+       }
+
+       reg32 = reg32 |
+           (bMode << 29) |
+           (fracMode << 28) | (aModeRefSel << 26) | (channelSel);
+
+       REG_WRITE(ah, AR_PHY_SYNTH_CONTROL, reg32);
+
+       ah->curchan = chan;
+       ah->curchan_rad_index = -1;
+}
+
+static void
+ath9k_phy_modify_rx_buffer(u32 *rfBuf, u32 reg32,
+                          u32 numBits, u32 firstBit,
+                          u32 column)
+{
+       u32 tmp32, mask, arrayEntry, lastBit;
+       int32_t bitPosition, bitsLeft;
+
+       tmp32 = ath9k_hw_reverse_bits(reg32, numBits);
+       arrayEntry = (firstBit - 1) / 8;
+       bitPosition = (firstBit - 1) % 8;
+       bitsLeft = numBits;
+       while (bitsLeft > 0) {
+               lastBit = (bitPosition + bitsLeft > 8) ?
+                   8 : bitPosition + bitsLeft;
+               mask = (((1 << lastBit) - 1) ^ ((1 << bitPosition) - 1)) <<
+                   (column * 8);
+               rfBuf[arrayEntry] &= ~mask;
+               rfBuf[arrayEntry] |= ((tmp32 << bitPosition) <<
+                                     (column * 8)) & mask;
+               bitsLeft -= 8 - bitPosition;
+               tmp32 = tmp32 >> (8 - bitPosition);
+               bitPosition = 0;
+               arrayEntry++;
+       }
+}
+
+bool
+ath9k_hw_set_rf_regs(struct ath_hw *ah, struct ath9k_channel *chan,
+                    u16 modesIndex)
+{
+       u32 eepMinorRev;
+       u32 ob5GHz = 0, db5GHz = 0;
+       u32 ob2GHz = 0, db2GHz = 0;
+       int regWrites = 0;
+
+       if (AR_SREV_9280_10_OR_LATER(ah))
+               return true;
+
+       eepMinorRev = ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV);
+
+       RF_BANK_SETUP(ah->analogBank0Data, &ah->iniBank0, 1);
+
+       RF_BANK_SETUP(ah->analogBank1Data, &ah->iniBank1, 1);
+
+       RF_BANK_SETUP(ah->analogBank2Data, &ah->iniBank2, 1);
+
+       RF_BANK_SETUP(ah->analogBank3Data, &ah->iniBank3,
+                     modesIndex);
+       {
+               int i;
+               for (i = 0; i < ah->iniBank6TPC.ia_rows; i++) {
+                       ah->analogBank6Data[i] =
+                           INI_RA(&ah->iniBank6TPC, i, modesIndex);
+               }
+       }
+
+       if (eepMinorRev >= 2) {
+               if (IS_CHAN_2GHZ(chan)) {
+                       ob2GHz = ah->eep_ops->get_eeprom(ah, EEP_OB_2);
+                       db2GHz = ah->eep_ops->get_eeprom(ah, EEP_DB_2);
+                       ath9k_phy_modify_rx_buffer(ah->analogBank6Data,
+                                                  ob2GHz, 3, 197, 0);
+                       ath9k_phy_modify_rx_buffer(ah->analogBank6Data,
+                                                  db2GHz, 3, 194, 0);
+               } else {
+                       ob5GHz = ah->eep_ops->get_eeprom(ah, EEP_OB_5);
+                       db5GHz = ah->eep_ops->get_eeprom(ah, EEP_DB_5);
+                       ath9k_phy_modify_rx_buffer(ah->analogBank6Data,
+                                                  ob5GHz, 3, 203, 0);
+                       ath9k_phy_modify_rx_buffer(ah->analogBank6Data,
+                                                  db5GHz, 3, 200, 0);
+               }
+       }
+
+       RF_BANK_SETUP(ah->analogBank7Data, &ah->iniBank7, 1);
+
+       REG_WRITE_RF_ARRAY(&ah->iniBank0, ah->analogBank0Data,
+                          regWrites);
+       REG_WRITE_RF_ARRAY(&ah->iniBank1, ah->analogBank1Data,
+                          regWrites);
+       REG_WRITE_RF_ARRAY(&ah->iniBank2, ah->analogBank2Data,
+                          regWrites);
+       REG_WRITE_RF_ARRAY(&ah->iniBank3, ah->analogBank3Data,
+                          regWrites);
+       REG_WRITE_RF_ARRAY(&ah->iniBank6TPC, ah->analogBank6Data,
+                          regWrites);
+       REG_WRITE_RF_ARRAY(&ah->iniBank7, ah->analogBank7Data,
+                          regWrites);
+
+       return true;
+}
+
+void
+ath9k_hw_rfdetach(struct ath_hw *ah)
+{
+       if (ah->analogBank0Data != NULL) {
+               kfree(ah->analogBank0Data);
+               ah->analogBank0Data = NULL;
+       }
+       if (ah->analogBank1Data != NULL) {
+               kfree(ah->analogBank1Data);
+               ah->analogBank1Data = NULL;
+       }
+       if (ah->analogBank2Data != NULL) {
+               kfree(ah->analogBank2Data);
+               ah->analogBank2Data = NULL;
+       }
+       if (ah->analogBank3Data != NULL) {
+               kfree(ah->analogBank3Data);
+               ah->analogBank3Data = NULL;
+       }
+       if (ah->analogBank6Data != NULL) {
+               kfree(ah->analogBank6Data);
+               ah->analogBank6Data = NULL;
+       }
+       if (ah->analogBank6TPCData != NULL) {
+               kfree(ah->analogBank6TPCData);
+               ah->analogBank6TPCData = NULL;
+       }
+       if (ah->analogBank7Data != NULL) {
+               kfree(ah->analogBank7Data);
+               ah->analogBank7Data = NULL;
+       }
+       if (ah->addac5416_21 != NULL) {
+               kfree(ah->addac5416_21);
+               ah->addac5416_21 = NULL;
+       }
+       if (ah->bank6Temp != NULL) {
+               kfree(ah->bank6Temp);
+               ah->bank6Temp = NULL;
+       }
+}
+
+bool ath9k_hw_init_rf(struct ath_hw *ah, int *status)
+{
+       if (!AR_SREV_9280_10_OR_LATER(ah)) {
+               ah->analogBank0Data =
+                   kzalloc((sizeof(u32) *
+                            ah->iniBank0.ia_rows), GFP_KERNEL);
+               ah->analogBank1Data =
+                   kzalloc((sizeof(u32) *
+                            ah->iniBank1.ia_rows), GFP_KERNEL);
+               ah->analogBank2Data =
+                   kzalloc((sizeof(u32) *
+                            ah->iniBank2.ia_rows), GFP_KERNEL);
+               ah->analogBank3Data =
+                   kzalloc((sizeof(u32) *
+                            ah->iniBank3.ia_rows), GFP_KERNEL);
+               ah->analogBank6Data =
+                   kzalloc((sizeof(u32) *
+                            ah->iniBank6.ia_rows), GFP_KERNEL);
+               ah->analogBank6TPCData =
+                   kzalloc((sizeof(u32) *
+                            ah->iniBank6TPC.ia_rows), GFP_KERNEL);
+               ah->analogBank7Data =
+                   kzalloc((sizeof(u32) *
+                            ah->iniBank7.ia_rows), GFP_KERNEL);
+
+               if (ah->analogBank0Data == NULL
+                   || ah->analogBank1Data == NULL
+                   || ah->analogBank2Data == NULL
+                   || ah->analogBank3Data == NULL
+                   || ah->analogBank6Data == NULL
+                   || ah->analogBank6TPCData == NULL
+                   || ah->analogBank7Data == NULL) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+                               "Cannot allocate RF banks\n");
+                       *status = -ENOMEM;
+                       return false;
+               }
+
+               ah->addac5416_21 =
+                   kzalloc((sizeof(u32) *
+                            ah->iniAddac.ia_rows *
+                            ah->iniAddac.ia_columns), GFP_KERNEL);
+               if (ah->addac5416_21 == NULL) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+                               "Cannot allocate addac5416_21\n");
+                       *status = -ENOMEM;
+                       return false;
+               }
+
+               ah->bank6Temp =
+                   kzalloc((sizeof(u32) *
+                            ah->iniBank6.ia_rows), GFP_KERNEL);
+               if (ah->bank6Temp == NULL) {
+                       DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
+                               "Cannot allocate bank6Temp\n");
+                       *status = -ENOMEM;
+                       return false;
+               }
+       }
+
+       return true;
+}
+
+void
+ath9k_hw_decrease_chain_power(struct ath_hw *ah, struct ath9k_channel *chan)
+{
+       int i, regWrites = 0;
+       u32 bank6SelMask;
+       u32 *bank6Temp = ah->bank6Temp;
+
+       switch (ah->diversity_control) {
+       case ATH9K_ANT_FIXED_A:
+               bank6SelMask =
+                   (ah->
+                    antenna_switch_swap & ANTSWAP_AB) ? REDUCE_CHAIN_0 :
+                   REDUCE_CHAIN_1;
+               break;
+       case ATH9K_ANT_FIXED_B:
+               bank6SelMask =
+                   (ah->
+                    antenna_switch_swap & ANTSWAP_AB) ? REDUCE_CHAIN_1 :
+                   REDUCE_CHAIN_0;
+               break;
+       case ATH9K_ANT_VARIABLE:
+               return;
+               break;
+       default:
+               return;
+               break;
+       }
+
+       for (i = 0; i < ah->iniBank6.ia_rows; i++)
+               bank6Temp[i] = ah->analogBank6Data[i];
+
+       REG_WRITE(ah, AR_PHY_BASE + 0xD8, bank6SelMask);
+
+       ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 189, 0);
+       ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 190, 0);
+       ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 191, 0);
+       ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 192, 0);
+       ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 193, 0);
+       ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 222, 0);
+       ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 245, 0);
+       ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 246, 0);
+       ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 247, 0);
+
+       REG_WRITE_RF_ARRAY(&ah->iniBank6, bank6Temp, regWrites);
+
+       REG_WRITE(ah, AR_PHY_BASE + 0xD8, 0x00000053);
+#ifdef ALTER_SWITCH
+       REG_WRITE(ah, PHY_SWITCH_CHAIN_0,
+                 (REG_READ(ah, PHY_SWITCH_CHAIN_0) & ~0x38)
+                 | ((REG_READ(ah, PHY_SWITCH_CHAIN_0) >> 3) & 0x38));
+#endif
+}
diff --git a/drivers/net/wireless/ath/ath9k/phy.h b/drivers/net/wireless/ath/ath9k/phy.h
new file mode 100644 (file)
index 0000000..c70f530
--- /dev/null
@@ -0,0 +1,576 @@
+/*
+ * Copyright (c) 2008-2009 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 PHY_H
+#define PHY_H
+
+void ath9k_hw_ar9280_set_channel(struct ath_hw *ah,
+                                struct ath9k_channel
+                                *chan);
+bool ath9k_hw_set_channel(struct ath_hw *ah,
+                         struct ath9k_channel *chan);
+void ath9k_hw_write_regs(struct ath_hw *ah, u32 modesIndex,
+                        u32 freqIndex, int regWrites);
+bool ath9k_hw_set_rf_regs(struct ath_hw *ah,
+                         struct ath9k_channel *chan,
+                         u16 modesIndex);
+void ath9k_hw_decrease_chain_power(struct ath_hw *ah,
+                                  struct ath9k_channel *chan);
+bool ath9k_hw_init_rf(struct ath_hw *ah,
+                     int *status);
+
+#define AR_PHY_BASE     0x9800
+#define AR_PHY(_n)      (AR_PHY_BASE + ((_n)<<2))
+
+#define AR_PHY_TEST             0x9800
+#define PHY_AGC_CLR             0x10000000
+#define RFSILENT_BB             0x00002000
+
+#define AR_PHY_TURBO                0x9804
+#define AR_PHY_FC_TURBO_MODE        0x00000001
+#define AR_PHY_FC_TURBO_SHORT       0x00000002
+#define AR_PHY_FC_DYN2040_EN        0x00000004
+#define AR_PHY_FC_DYN2040_PRI_ONLY  0x00000008
+#define AR_PHY_FC_DYN2040_PRI_CH    0x00000010
+#define AR_PHY_FC_DYN2040_EXT_CH    0x00000020
+#define AR_PHY_FC_HT_EN             0x00000040
+#define AR_PHY_FC_SHORT_GI_40       0x00000080
+#define AR_PHY_FC_WALSH             0x00000100
+#define AR_PHY_FC_SINGLE_HT_LTF1    0x00000200
+#define AR_PHY_FC_ENABLE_DAC_FIFO   0x00000800
+
+#define AR_PHY_TEST2               0x9808
+
+#define AR_PHY_TIMING2           0x9810
+#define AR_PHY_TIMING3           0x9814
+#define AR_PHY_TIMING3_DSC_MAN   0xFFFE0000
+#define AR_PHY_TIMING3_DSC_MAN_S 17
+#define AR_PHY_TIMING3_DSC_EXP   0x0001E000
+#define AR_PHY_TIMING3_DSC_EXP_S 13
+
+#define AR_PHY_CHIP_ID            0x9818
+#define AR_PHY_CHIP_ID_REV_0      0x80
+#define AR_PHY_CHIP_ID_REV_1      0x81
+#define AR_PHY_CHIP_ID_9160_REV_0 0xb0
+
+#define AR_PHY_ACTIVE       0x981C
+#define AR_PHY_ACTIVE_EN    0x00000001
+#define AR_PHY_ACTIVE_DIS   0x00000000
+
+#define AR_PHY_RF_CTL2             0x9824
+#define AR_PHY_TX_END_DATA_START   0x000000FF
+#define AR_PHY_TX_END_DATA_START_S 0
+#define AR_PHY_TX_END_PA_ON        0x0000FF00
+#define AR_PHY_TX_END_PA_ON_S      8
+
+#define AR_PHY_RF_CTL3                  0x9828
+#define AR_PHY_TX_END_TO_A2_RX_ON       0x00FF0000
+#define AR_PHY_TX_END_TO_A2_RX_ON_S     16
+
+#define AR_PHY_ADC_CTL                  0x982C
+#define AR_PHY_ADC_CTL_OFF_INBUFGAIN    0x00000003
+#define AR_PHY_ADC_CTL_OFF_INBUFGAIN_S  0
+#define AR_PHY_ADC_CTL_OFF_PWDDAC       0x00002000
+#define AR_PHY_ADC_CTL_OFF_PWDBANDGAP   0x00004000
+#define AR_PHY_ADC_CTL_OFF_PWDADC       0x00008000
+#define AR_PHY_ADC_CTL_ON_INBUFGAIN     0x00030000
+#define AR_PHY_ADC_CTL_ON_INBUFGAIN_S   16
+
+#define AR_PHY_ADC_SERIAL_CTL       0x9830
+#define AR_PHY_SEL_INTERNAL_ADDAC   0x00000000
+#define AR_PHY_SEL_EXTERNAL_RADIO   0x00000001
+
+#define AR_PHY_RF_CTL4                    0x9834
+#define AR_PHY_RF_CTL4_TX_END_XPAB_OFF    0xFF000000
+#define AR_PHY_RF_CTL4_TX_END_XPAB_OFF_S  24
+#define AR_PHY_RF_CTL4_TX_END_XPAA_OFF    0x00FF0000
+#define AR_PHY_RF_CTL4_TX_END_XPAA_OFF_S  16
+#define AR_PHY_RF_CTL4_FRAME_XPAB_ON      0x0000FF00
+#define AR_PHY_RF_CTL4_FRAME_XPAB_ON_S    8
+#define AR_PHY_RF_CTL4_FRAME_XPAA_ON      0x000000FF
+#define AR_PHY_RF_CTL4_FRAME_XPAA_ON_S    0
+
+#define AR_PHY_TSTDAC_CONST               0x983c
+
+#define AR_PHY_SETTLING          0x9844
+#define AR_PHY_SETTLING_SWITCH   0x00003F80
+#define AR_PHY_SETTLING_SWITCH_S 7
+
+#define AR_PHY_RXGAIN                   0x9848
+#define AR_PHY_RXGAIN_TXRX_ATTEN        0x0003F000
+#define AR_PHY_RXGAIN_TXRX_ATTEN_S      12
+#define AR_PHY_RXGAIN_TXRX_RF_MAX       0x007C0000
+#define AR_PHY_RXGAIN_TXRX_RF_MAX_S     18
+#define AR9280_PHY_RXGAIN_TXRX_ATTEN    0x00003F80
+#define AR9280_PHY_RXGAIN_TXRX_ATTEN_S  7
+#define AR9280_PHY_RXGAIN_TXRX_MARGIN   0x001FC000
+#define AR9280_PHY_RXGAIN_TXRX_MARGIN_S 14
+
+#define AR_PHY_DESIRED_SZ           0x9850
+#define AR_PHY_DESIRED_SZ_ADC       0x000000FF
+#define AR_PHY_DESIRED_SZ_ADC_S     0
+#define AR_PHY_DESIRED_SZ_PGA       0x0000FF00
+#define AR_PHY_DESIRED_SZ_PGA_S     8
+#define AR_PHY_DESIRED_SZ_TOT_DES   0x0FF00000
+#define AR_PHY_DESIRED_SZ_TOT_DES_S 20
+
+#define AR_PHY_FIND_SIG           0x9858
+#define AR_PHY_FIND_SIG_FIRSTEP   0x0003F000
+#define AR_PHY_FIND_SIG_FIRSTEP_S 12
+#define AR_PHY_FIND_SIG_FIRPWR    0x03FC0000
+#define AR_PHY_FIND_SIG_FIRPWR_S  18
+
+#define AR_PHY_AGC_CTL1                  0x985C
+#define AR_PHY_AGC_CTL1_COARSE_LOW       0x00007F80
+#define AR_PHY_AGC_CTL1_COARSE_LOW_S     7
+#define AR_PHY_AGC_CTL1_COARSE_HIGH      0x003F8000
+#define AR_PHY_AGC_CTL1_COARSE_HIGH_S    15
+
+#define AR_PHY_AGC_CONTROL               0x9860
+#define AR_PHY_AGC_CONTROL_CAL           0x00000001
+#define AR_PHY_AGC_CONTROL_NF            0x00000002
+#define AR_PHY_AGC_CONTROL_ENABLE_NF     0x00008000
+#define AR_PHY_AGC_CONTROL_FLTR_CAL      0x00010000
+#define AR_PHY_AGC_CONTROL_NO_UPDATE_NF  0x00020000
+
+#define AR_PHY_CCA                  0x9864
+#define AR_PHY_MINCCA_PWR           0x0FF80000
+#define AR_PHY_MINCCA_PWR_S         19
+#define AR_PHY_CCA_THRESH62         0x0007F000
+#define AR_PHY_CCA_THRESH62_S       12
+#define AR9280_PHY_MINCCA_PWR       0x1FF00000
+#define AR9280_PHY_MINCCA_PWR_S     20
+#define AR9280_PHY_CCA_THRESH62     0x000FF000
+#define AR9280_PHY_CCA_THRESH62_S   12
+
+#define AR_PHY_SFCORR_LOW                    0x986C
+#define AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW  0x00000001
+#define AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW    0x00003F00
+#define AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW_S  8
+#define AR_PHY_SFCORR_LOW_M1_THRESH_LOW      0x001FC000
+#define AR_PHY_SFCORR_LOW_M1_THRESH_LOW_S    14
+#define AR_PHY_SFCORR_LOW_M2_THRESH_LOW      0x0FE00000
+#define AR_PHY_SFCORR_LOW_M2_THRESH_LOW_S    21
+
+#define AR_PHY_SFCORR                0x9868
+#define AR_PHY_SFCORR_M2COUNT_THR    0x0000001F
+#define AR_PHY_SFCORR_M2COUNT_THR_S  0
+#define AR_PHY_SFCORR_M1_THRESH      0x00FE0000
+#define AR_PHY_SFCORR_M1_THRESH_S    17
+#define AR_PHY_SFCORR_M2_THRESH      0x7F000000
+#define AR_PHY_SFCORR_M2_THRESH_S    24
+
+#define AR_PHY_SLEEP_CTR_CONTROL    0x9870
+#define AR_PHY_SLEEP_CTR_LIMIT      0x9874
+#define AR_PHY_SYNTH_CONTROL        0x9874
+#define AR_PHY_SLEEP_SCAL           0x9878
+
+#define AR_PHY_PLL_CTL          0x987c
+#define AR_PHY_PLL_CTL_40       0xaa
+#define AR_PHY_PLL_CTL_40_5413  0x04
+#define AR_PHY_PLL_CTL_44       0xab
+#define AR_PHY_PLL_CTL_44_2133  0xeb
+#define AR_PHY_PLL_CTL_40_2133  0xea
+
+#define AR_PHY_RX_DELAY           0x9914
+#define AR_PHY_SEARCH_START_DELAY 0x9918
+#define AR_PHY_RX_DELAY_DELAY     0x00003FFF
+
+#define AR_PHY_TIMING_CTRL4(_i)     (0x9920 + ((_i) << 12))
+#define AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF 0x01F
+#define AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF_S   0
+#define AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF 0x7E0
+#define AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF_S   5
+#define AR_PHY_TIMING_CTRL4_IQCORR_ENABLE   0x800
+#define AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX 0xF000
+#define AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX_S   12
+#define AR_PHY_TIMING_CTRL4_DO_CAL    0x10000
+
+#define AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI   0x80000000
+#define        AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER  0x40000000
+#define        AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK    0x20000000
+#define        AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK   0x10000000
+
+#define AR_PHY_TIMING5               0x9924
+#define AR_PHY_TIMING5_CYCPWR_THR1   0x000000FE
+#define AR_PHY_TIMING5_CYCPWR_THR1_S 1
+
+#define AR_PHY_POWER_TX_RATE1               0x9934
+#define AR_PHY_POWER_TX_RATE2               0x9938
+#define AR_PHY_POWER_TX_RATE_MAX            0x993c
+#define AR_PHY_POWER_TX_RATE_MAX_TPC_ENABLE 0x00000040
+
+#define AR_PHY_FRAME_CTL            0x9944
+#define AR_PHY_FRAME_CTL_TX_CLIP    0x00000038
+#define AR_PHY_FRAME_CTL_TX_CLIP_S  3
+
+#define AR_PHY_TXPWRADJ                   0x994C
+#define AR_PHY_TXPWRADJ_CCK_GAIN_DELTA    0x00000FC0
+#define AR_PHY_TXPWRADJ_CCK_GAIN_DELTA_S  6
+#define AR_PHY_TXPWRADJ_CCK_PCDAC_INDEX   0x00FC0000
+#define AR_PHY_TXPWRADJ_CCK_PCDAC_INDEX_S 18
+
+#define AR_PHY_RADAR_EXT      0x9940
+#define AR_PHY_RADAR_EXT_ENA  0x00004000
+
+#define AR_PHY_RADAR_0          0x9954
+#define AR_PHY_RADAR_0_ENA      0x00000001
+#define AR_PHY_RADAR_0_FFT_ENA  0x80000000
+#define AR_PHY_RADAR_0_INBAND   0x0000003e
+#define AR_PHY_RADAR_0_INBAND_S 1
+#define AR_PHY_RADAR_0_PRSSI    0x00000FC0
+#define AR_PHY_RADAR_0_PRSSI_S  6
+#define AR_PHY_RADAR_0_HEIGHT   0x0003F000
+#define AR_PHY_RADAR_0_HEIGHT_S 12
+#define AR_PHY_RADAR_0_RRSSI    0x00FC0000
+#define AR_PHY_RADAR_0_RRSSI_S  18
+#define AR_PHY_RADAR_0_FIRPWR   0x7F000000
+#define AR_PHY_RADAR_0_FIRPWR_S 24
+
+#define AR_PHY_RADAR_1                  0x9958
+#define AR_PHY_RADAR_1_RELPWR_ENA       0x00800000
+#define AR_PHY_RADAR_1_USE_FIR128       0x00400000
+#define AR_PHY_RADAR_1_RELPWR_THRESH    0x003F0000
+#define AR_PHY_RADAR_1_RELPWR_THRESH_S  16
+#define AR_PHY_RADAR_1_BLOCK_CHECK      0x00008000
+#define AR_PHY_RADAR_1_MAX_RRSSI        0x00004000
+#define AR_PHY_RADAR_1_RELSTEP_CHECK    0x00002000
+#define AR_PHY_RADAR_1_RELSTEP_THRESH   0x00001F00
+#define AR_PHY_RADAR_1_RELSTEP_THRESH_S 8
+#define AR_PHY_RADAR_1_MAXLEN           0x000000FF
+#define AR_PHY_RADAR_1_MAXLEN_S         0
+
+#define AR_PHY_SWITCH_CHAIN_0     0x9960
+#define AR_PHY_SWITCH_COM         0x9964
+
+#define AR_PHY_SIGMA_DELTA            0x996C
+#define AR_PHY_SIGMA_DELTA_ADC_SEL    0x00000003
+#define AR_PHY_SIGMA_DELTA_ADC_SEL_S  0
+#define AR_PHY_SIGMA_DELTA_FILT2      0x000000F8
+#define AR_PHY_SIGMA_DELTA_FILT2_S    3
+#define AR_PHY_SIGMA_DELTA_FILT1      0x00001F00
+#define AR_PHY_SIGMA_DELTA_FILT1_S    8
+#define AR_PHY_SIGMA_DELTA_ADC_CLIP   0x01FFE000
+#define AR_PHY_SIGMA_DELTA_ADC_CLIP_S 13
+
+#define AR_PHY_RESTART          0x9970
+#define AR_PHY_RESTART_DIV_GC   0x001C0000
+#define AR_PHY_RESTART_DIV_GC_S 18
+
+#define AR_PHY_RFBUS_REQ        0x997C
+#define AR_PHY_RFBUS_REQ_EN     0x00000001
+
+#define        AR_PHY_TIMING7                  0x9980
+#define        AR_PHY_TIMING8                  0x9984
+#define        AR_PHY_TIMING8_PILOT_MASK_2     0x000FFFFF
+#define        AR_PHY_TIMING8_PILOT_MASK_2_S   0
+
+#define        AR_PHY_BIN_MASK2_1      0x9988
+#define        AR_PHY_BIN_MASK2_2      0x998c
+#define        AR_PHY_BIN_MASK2_3      0x9990
+#define        AR_PHY_BIN_MASK2_4      0x9994
+
+#define        AR_PHY_BIN_MASK_1       0x9900
+#define        AR_PHY_BIN_MASK_2       0x9904
+#define        AR_PHY_BIN_MASK_3       0x9908
+
+#define        AR_PHY_MASK_CTL         0x990c
+
+#define        AR_PHY_BIN_MASK2_4_MASK_4       0x00003FFF
+#define        AR_PHY_BIN_MASK2_4_MASK_4_S     0
+
+#define        AR_PHY_TIMING9                  0x9998
+#define        AR_PHY_TIMING10                 0x999c
+#define        AR_PHY_TIMING10_PILOT_MASK_2    0x000FFFFF
+#define        AR_PHY_TIMING10_PILOT_MASK_2_S  0
+
+#define        AR_PHY_TIMING11                         0x99a0
+#define        AR_PHY_TIMING11_SPUR_DELTA_PHASE        0x000FFFFF
+#define        AR_PHY_TIMING11_SPUR_DELTA_PHASE_S      0
+#define        AR_PHY_TIMING11_SPUR_FREQ_SD            0x3FF00000
+#define        AR_PHY_TIMING11_SPUR_FREQ_SD_S          20
+#define AR_PHY_TIMING11_USE_SPUR_IN_AGC                0x40000000
+#define AR_PHY_TIMING11_USE_SPUR_IN_SELFCOR    0x80000000
+
+#define AR_PHY_RX_CHAINMASK     0x99a4
+#define AR_PHY_NEW_ADC_DC_GAIN_CORR(_i) (0x99b4 + ((_i) << 12))
+#define AR_PHY_NEW_ADC_GAIN_CORR_ENABLE 0x40000000
+#define AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE 0x80000000
+#define AR_PHY_MULTICHAIN_GAIN_CTL  0x99ac
+
+#define AR_PHY_EXT_CCA0             0x99b8
+#define AR_PHY_EXT_CCA0_THRESH62    0x000000FF
+#define AR_PHY_EXT_CCA0_THRESH62_S  0
+
+#define AR_PHY_EXT_CCA                  0x99bc
+#define AR_PHY_EXT_CCA_CYCPWR_THR1      0x0000FE00
+#define AR_PHY_EXT_CCA_CYCPWR_THR1_S    9
+#define AR_PHY_EXT_CCA_THRESH62         0x007F0000
+#define AR_PHY_EXT_CCA_THRESH62_S       16
+#define AR_PHY_EXT_MINCCA_PWR           0xFF800000
+#define AR_PHY_EXT_MINCCA_PWR_S         23
+#define AR9280_PHY_EXT_MINCCA_PWR       0x01FF0000
+#define AR9280_PHY_EXT_MINCCA_PWR_S     16
+
+#define AR_PHY_SFCORR_EXT                 0x99c0
+#define AR_PHY_SFCORR_EXT_M1_THRESH       0x0000007F
+#define AR_PHY_SFCORR_EXT_M1_THRESH_S     0
+#define AR_PHY_SFCORR_EXT_M2_THRESH       0x00003F80
+#define AR_PHY_SFCORR_EXT_M2_THRESH_S     7
+#define AR_PHY_SFCORR_EXT_M1_THRESH_LOW   0x001FC000
+#define AR_PHY_SFCORR_EXT_M1_THRESH_LOW_S 14
+#define AR_PHY_SFCORR_EXT_M2_THRESH_LOW   0x0FE00000
+#define AR_PHY_SFCORR_EXT_M2_THRESH_LOW_S 21
+#define AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S   28
+
+#define AR_PHY_HALFGI           0x99D0
+#define AR_PHY_HALFGI_DSC_MAN   0x0007FFF0
+#define AR_PHY_HALFGI_DSC_MAN_S 4
+#define AR_PHY_HALFGI_DSC_EXP   0x0000000F
+#define AR_PHY_HALFGI_DSC_EXP_S 0
+
+#define AR_PHY_CHAN_INFO_MEMORY               0x99DC
+#define AR_PHY_CHAN_INFO_MEMORY_CAPTURE_MASK  0x0001
+
+#define AR_PHY_HEAVY_CLIP_ENABLE         0x99E0
+
+#define AR_PHY_M_SLEEP      0x99f0
+#define AR_PHY_REFCLKDLY    0x99f4
+#define AR_PHY_REFCLKPD     0x99f8
+
+#define AR_PHY_CALMODE      0x99f0
+
+#define AR_PHY_CALMODE_IQ           0x00000000
+#define AR_PHY_CALMODE_ADC_GAIN     0x00000001
+#define AR_PHY_CALMODE_ADC_DC_PER   0x00000002
+#define AR_PHY_CALMODE_ADC_DC_INIT  0x00000003
+
+#define AR_PHY_CAL_MEAS_0(_i)     (0x9c10 + ((_i) << 12))
+#define AR_PHY_CAL_MEAS_1(_i)     (0x9c14 + ((_i) << 12))
+#define AR_PHY_CAL_MEAS_2(_i)     (0x9c18 + ((_i) << 12))
+#define AR_PHY_CAL_MEAS_3(_i)     (0x9c1c + ((_i) << 12))
+
+#define AR_PHY_CURRENT_RSSI 0x9c1c
+#define AR9280_PHY_CURRENT_RSSI 0x9c3c
+
+#define AR_PHY_RFBUS_GRANT       0x9C20
+#define AR_PHY_RFBUS_GRANT_EN    0x00000001
+
+#define AR_PHY_CHAN_INFO_GAIN_DIFF             0x9CF4
+#define AR_PHY_CHAN_INFO_GAIN_DIFF_UPPER_LIMIT 320
+
+#define AR_PHY_CHAN_INFO_GAIN          0x9CFC
+
+#define AR_PHY_MODE         0xA200
+#define AR_PHY_MODE_AR2133  0x08
+#define AR_PHY_MODE_AR5111  0x00
+#define AR_PHY_MODE_AR5112  0x08
+#define AR_PHY_MODE_DYNAMIC 0x04
+#define AR_PHY_MODE_RF2GHZ  0x02
+#define AR_PHY_MODE_RF5GHZ  0x00
+#define AR_PHY_MODE_CCK     0x01
+#define AR_PHY_MODE_OFDM    0x00
+#define AR_PHY_MODE_DYN_CCK_DISABLE 0x100
+
+#define AR_PHY_CCK_TX_CTRL       0xA204
+#define AR_PHY_CCK_TX_CTRL_JAPAN 0x00000010
+#define AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK         0x0000000C
+#define AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK_S       2
+
+#define AR_PHY_CCK_DETECT                           0xA208
+#define AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK          0x0000003F
+#define AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK_S        0
+/* [12:6] settling time for antenna switch */
+#define AR_PHY_CCK_DETECT_ANT_SWITCH_TIME           0x00001FC0
+#define AR_PHY_CCK_DETECT_ANT_SWITCH_TIME_S         6
+#define AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV    0x2000
+
+#define AR_PHY_GAIN_2GHZ                0xA20C
+#define AR_PHY_GAIN_2GHZ_RXTX_MARGIN    0x00FC0000
+#define AR_PHY_GAIN_2GHZ_RXTX_MARGIN_S  18
+#define AR_PHY_GAIN_2GHZ_BSW_MARGIN     0x00003C00
+#define AR_PHY_GAIN_2GHZ_BSW_MARGIN_S   10
+#define AR_PHY_GAIN_2GHZ_BSW_ATTEN      0x0000001F
+#define AR_PHY_GAIN_2GHZ_BSW_ATTEN_S    0
+
+#define AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN     0x003E0000
+#define AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN_S   17
+#define AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN     0x0001F000
+#define AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN_S   12
+#define AR_PHY_GAIN_2GHZ_XATTEN2_DB         0x00000FC0
+#define AR_PHY_GAIN_2GHZ_XATTEN2_DB_S       6
+#define AR_PHY_GAIN_2GHZ_XATTEN1_DB         0x0000003F
+#define AR_PHY_GAIN_2GHZ_XATTEN1_DB_S       0
+
+#define AR_PHY_CCK_RXCTRL4  0xA21C
+#define AR_PHY_CCK_RXCTRL4_FREQ_EST_SHORT   0x01F80000
+#define AR_PHY_CCK_RXCTRL4_FREQ_EST_SHORT_S 19
+
+#define AR_PHY_DAG_CTRLCCK  0xA228
+#define AR_PHY_DAG_CTRLCCK_EN_RSSI_THR  0x00000200
+#define AR_PHY_DAG_CTRLCCK_RSSI_THR     0x0001FC00
+#define AR_PHY_DAG_CTRLCCK_RSSI_THR_S   10
+
+#define AR_PHY_FORCE_CLKEN_CCK              0xA22C
+#define AR_PHY_FORCE_CLKEN_CCK_MRC_MUX      0x00000040
+
+#define AR_PHY_POWER_TX_RATE3   0xA234
+#define AR_PHY_POWER_TX_RATE4   0xA238
+
+#define AR_PHY_SCRM_SEQ_XR       0xA23C
+#define AR_PHY_HEADER_DETECT_XR  0xA240
+#define AR_PHY_CHIRP_DETECTED_XR 0xA244
+#define AR_PHY_BLUETOOTH         0xA254
+
+#define AR_PHY_TPCRG1   0xA258
+#define AR_PHY_TPCRG1_NUM_PD_GAIN   0x0000c000
+#define AR_PHY_TPCRG1_NUM_PD_GAIN_S 14
+
+#define AR_PHY_TPCRG1_PD_GAIN_1    0x00030000
+#define AR_PHY_TPCRG1_PD_GAIN_1_S  16
+#define AR_PHY_TPCRG1_PD_GAIN_2    0x000C0000
+#define AR_PHY_TPCRG1_PD_GAIN_2_S  18
+#define AR_PHY_TPCRG1_PD_GAIN_3    0x00300000
+#define AR_PHY_TPCRG1_PD_GAIN_3_S  20
+
+#define AR_PHY_TPCRG1_PD_CAL_ENABLE   0x00400000
+#define AR_PHY_TPCRG1_PD_CAL_ENABLE_S 22
+
+#define AR_PHY_TX_PWRCTRL4       0xa264
+#define AR_PHY_TX_PWRCTRL_PD_AVG_VALID     0x00000001
+#define AR_PHY_TX_PWRCTRL_PD_AVG_VALID_S   0
+#define AR_PHY_TX_PWRCTRL_PD_AVG_OUT       0x000001FE
+#define AR_PHY_TX_PWRCTRL_PD_AVG_OUT_S     1
+
+#define AR_PHY_TX_PWRCTRL6_0     0xa270
+#define AR_PHY_TX_PWRCTRL6_1     0xb270
+#define AR_PHY_TX_PWRCTRL_ERR_EST_MODE     0x03000000
+#define AR_PHY_TX_PWRCTRL_ERR_EST_MODE_S   24
+
+#define AR_PHY_TX_PWRCTRL7       0xa274
+#define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN     0x01F80000
+#define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN_S   19
+
+#define AR_PHY_TX_PWRCTRL9       0xa27C
+#define AR_PHY_TX_DESIRED_SCALE_CCK        0x00007C00
+#define AR_PHY_TX_DESIRED_SCALE_CCK_S      10
+
+#define AR_PHY_TX_GAIN_TBL1      0xa300
+#define AR_PHY_TX_GAIN                     0x0007F000
+#define AR_PHY_TX_GAIN_S                   12
+
+#define AR_PHY_VIT_MASK2_M_46_61 0xa3a0
+#define AR_PHY_MASK2_M_31_45     0xa3a4
+#define AR_PHY_MASK2_M_16_30     0xa3a8
+#define AR_PHY_MASK2_M_00_15     0xa3ac
+#define AR_PHY_MASK2_P_15_01     0xa3b8
+#define AR_PHY_MASK2_P_30_16     0xa3bc
+#define AR_PHY_MASK2_P_45_31     0xa3c0
+#define AR_PHY_MASK2_P_61_45     0xa3c4
+#define AR_PHY_SPUR_REG          0x994c
+
+#define AR_PHY_SPUR_REG_MASK_RATE_CNTL       (0xFF << 18)
+#define AR_PHY_SPUR_REG_MASK_RATE_CNTL_S     18
+
+#define AR_PHY_SPUR_REG_ENABLE_MASK_PPM      0x20000
+#define AR_PHY_SPUR_REG_MASK_RATE_SELECT     (0xFF << 9)
+#define AR_PHY_SPUR_REG_MASK_RATE_SELECT_S   9
+#define AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI 0x100
+#define AR_PHY_SPUR_REG_SPUR_RSSI_THRESH     0x7F
+#define AR_PHY_SPUR_REG_SPUR_RSSI_THRESH_S   0
+
+#define AR_PHY_PILOT_MASK_01_30   0xa3b0
+#define AR_PHY_PILOT_MASK_31_60   0xa3b4
+
+#define AR_PHY_CHANNEL_MASK_01_30 0x99d4
+#define AR_PHY_CHANNEL_MASK_31_60 0x99d8
+
+#define AR_PHY_ANALOG_SWAP      0xa268
+#define AR_PHY_SWAP_ALT_CHAIN   0x00000040
+
+#define AR_PHY_TPCRG5   0xA26C
+#define AR_PHY_TPCRG5_PD_GAIN_OVERLAP       0x0000000F
+#define AR_PHY_TPCRG5_PD_GAIN_OVERLAP_S     0
+#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1    0x000003F0
+#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1_S  4
+#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2    0x0000FC00
+#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2_S  10
+#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3    0x003F0000
+#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3_S  16
+#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4    0x0FC00000
+#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4_S  22
+
+/* Carrier leak calibration control, do it after AGC calibration */
+#define AR_PHY_CL_CAL_CTL       0xA358
+#define AR_PHY_CL_CAL_ENABLE    0x00000002
+#define AR_PHY_PARALLEL_CAL_ENABLE    0x00000001
+
+#define AR_PHY_POWER_TX_RATE5   0xA38C
+#define AR_PHY_POWER_TX_RATE6   0xA390
+
+#define AR_PHY_CAL_CHAINMASK    0xA39C
+
+#define AR_PHY_POWER_TX_SUB     0xA3C8
+#define AR_PHY_POWER_TX_RATE7   0xA3CC
+#define AR_PHY_POWER_TX_RATE8   0xA3D0
+#define AR_PHY_POWER_TX_RATE9   0xA3D4
+
+#define AR_PHY_XPA_CFG         0xA3D8
+#define AR_PHY_FORCE_XPA_CFG   0x000000001
+#define AR_PHY_FORCE_XPA_CFG_S 0
+
+#define AR_PHY_CH1_CCA          0xa864
+#define AR_PHY_CH1_MINCCA_PWR   0x0FF80000
+#define AR_PHY_CH1_MINCCA_PWR_S 19
+#define AR9280_PHY_CH1_MINCCA_PWR   0x1FF00000
+#define AR9280_PHY_CH1_MINCCA_PWR_S 20
+
+#define AR_PHY_CH2_CCA          0xb864
+#define AR_PHY_CH2_MINCCA_PWR   0x0FF80000
+#define AR_PHY_CH2_MINCCA_PWR_S 19
+
+#define AR_PHY_CH1_EXT_CCA          0xa9bc
+#define AR_PHY_CH1_EXT_MINCCA_PWR   0xFF800000
+#define AR_PHY_CH1_EXT_MINCCA_PWR_S 23
+#define AR9280_PHY_CH1_EXT_MINCCA_PWR   0x01FF0000
+#define AR9280_PHY_CH1_EXT_MINCCA_PWR_S 16
+
+#define AR_PHY_CH2_EXT_CCA          0xb9bc
+#define AR_PHY_CH2_EXT_MINCCA_PWR   0xFF800000
+#define AR_PHY_CH2_EXT_MINCCA_PWR_S 23
+
+#define REG_WRITE_RF_ARRAY(iniarray, regData, regWr) do {               \
+               int r;                                                  \
+               for (r = 0; r < ((iniarray)->ia_rows); r++) {           \
+                       REG_WRITE(ah, INI_RA((iniarray), r, 0), (regData)[r]); \
+                       DO_DELAY(regWr);                                \
+               }                                                       \
+       } while (0)
+
+#define ATH9K_IS_MIC_ENABLED(ah)                                       \
+       ((ah)->sta_id1_defaults & AR_STA_ID1_CRPT_MIC_ENABLE)
+
+#define ANTSWAP_AB 0x0001
+#define REDUCE_CHAIN_0 0x00000050
+#define REDUCE_CHAIN_1 0x00000051
+
+#define RF_BANK_SETUP(_bank, _iniarray, _col) do {                     \
+               int i;                                                  \
+               for (i = 0; i < (_iniarray)->ia_rows; i++)              \
+                       (_bank)[i] = INI_RA((_iniarray), i, _col);;     \
+       } while (0)
+
+#endif
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
new file mode 100644 (file)
index 0000000..ba06e78
--- /dev/null
@@ -0,0 +1,1756 @@
+/*
+ * Copyright (c) 2004 Video54 Technologies, Inc.
+ * Copyright (c) 2004-2009 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 "ath9k.h"
+
+static const struct ath_rate_table ar5416_11na_ratetable = {
+       42,
+       {
+               { VALID, VALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
+                       5400, 0x0b, 0x00, 12,
+                       0, 2, 1, 0, 0, 0, 0, 0 },
+               { VALID, VALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
+                       7800,  0x0f, 0x00, 18,
+                       0, 3, 1, 1, 1, 1, 1, 0 },
+               { VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
+                       10000, 0x0a, 0x00, 24,
+                       2, 4, 2, 2, 2, 2, 2, 0 },
+               { VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
+                       13900, 0x0e, 0x00, 36,
+                       2, 6,  2, 3, 3, 3, 3, 0 },
+               { VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
+                       17300, 0x09, 0x00, 48,
+                       4, 10, 3, 4, 4, 4, 4, 0 },
+               { VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
+                       23000, 0x0d, 0x00, 72,
+                       4, 14, 3, 5, 5, 5, 5, 0 },
+               { VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
+                       27400, 0x08, 0x00, 96,
+                       4, 20, 3, 6, 6, 6, 6, 0 },
+               { VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
+                       29300, 0x0c, 0x00, 108,
+                       4, 23, 3, 7, 7, 7, 7, 0 },
+               { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 6500, /* 6.5 Mb */
+                       6400, 0x80, 0x00, 0,
+                       0, 2, 3, 8, 24, 8, 24, 3216 },
+               { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 13000, /* 13 Mb */
+                       12700, 0x81, 0x00, 1,
+                       2, 4, 3, 9, 25, 9, 25, 6434 },
+               { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 19500, /* 19.5 Mb */
+                       18800, 0x82, 0x00, 2,
+                       2, 6, 3, 10, 26, 10, 26, 9650 },
+               { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 26000, /* 26 Mb */
+                       25000, 0x83, 0x00, 3,
+                       4, 10, 3, 11, 27, 11, 27, 12868 },
+               { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 39000, /* 39 Mb */
+                       36700, 0x84, 0x00, 4,
+                       4, 14, 3, 12, 28, 12, 28, 19304 },
+               { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 52000, /* 52 Mb */
+                       48100, 0x85, 0x00, 5,
+                       4, 20, 3, 13, 29, 13, 29, 25740 },
+               { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 58500, /* 58.5 Mb */
+                       53500, 0x86, 0x00, 6,
+                       4, 23, 3, 14, 30, 14, 30,  28956 },
+               { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 65000, /* 65 Mb */
+                       59000, 0x87, 0x00, 7,
+                       4, 25, 3, 15, 31, 15, 32, 32180 },
+               { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 13000, /* 13 Mb */
+                       12700, 0x88, 0x00,
+                       8, 0, 2, 3, 16, 33, 16, 33, 6430 },
+               { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 26000, /* 26 Mb */
+                       24800, 0x89, 0x00, 9,
+                       2, 4, 3, 17, 34, 17, 34, 12860 },
+               { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 39000, /* 39 Mb */
+                       36600, 0x8a, 0x00, 10,
+                       2, 6, 3, 18, 35, 18, 35, 19300 },
+               { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 52000, /* 52 Mb */
+                       48100, 0x8b, 0x00, 11,
+                       4, 10, 3, 19, 36, 19, 36, 25736 },
+               { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 78000, /* 78 Mb */
+                       69500, 0x8c, 0x00, 12,
+                       4, 14, 3, 20, 37, 20, 37, 38600 },
+               { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 104000, /* 104 Mb */
+                       89500, 0x8d, 0x00, 13,
+                       4, 20, 3, 21, 38, 21, 38, 51472 },
+               { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 117000, /* 117 Mb */
+                       98900, 0x8e, 0x00, 14,
+                       4, 23, 3, 22, 39, 22, 39, 57890 },
+               { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 130000, /* 130 Mb */
+                       108300, 0x8f, 0x00, 15,
+                       4, 25, 3, 23, 40, 23, 41, 64320 },
+               { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 13500, /* 13.5 Mb */
+                       13200, 0x80, 0x00, 0,
+                       0, 2, 3, 8, 24, 24, 24, 6684 },
+               { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 27500, /* 27.0 Mb */
+                       25900, 0x81, 0x00, 1,
+                       2, 4, 3, 9, 25, 25, 25, 13368 },
+               { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 40500, /* 40.5 Mb */
+                       38600, 0x82, 0x00, 2,
+                       2, 6, 3, 10, 26, 26, 26, 20052 },
+               { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 54000, /* 54 Mb */
+                       49800, 0x83, 0x00, 3,
+                       4, 10, 3, 11, 27, 27, 27, 26738 },
+               { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 81500, /* 81 Mb */
+                       72200, 0x84, 0x00, 4,
+                       4, 14, 3, 12, 28, 28, 28, 40104 },
+               { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 108000, /* 108 Mb */
+                       92900, 0x85, 0x00, 5,
+                       4, 20, 3, 13, 29, 29, 29, 53476 },
+               { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 121500, /* 121.5 Mb */
+                       102700, 0x86, 0x00, 6,
+                       4, 23, 3, 14, 30, 30, 30, 60156 },
+               { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 135000, /* 135 Mb */
+                       112000, 0x87, 0x00, 7,
+                       4, 25, 3, 15, 31, 32, 32, 66840 },
+               { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000, /* 150 Mb */
+                       122000, 0x87, 0x00, 7,
+                       4, 25, 3, 15, 31, 32, 32, 74200 },
+               { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 27000, /* 27 Mb */
+                       25800, 0x88, 0x00, 8,
+                       0, 2, 3, 16, 33, 33, 33, 13360 },
+               { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 54000, /* 54 Mb */
+                       49800, 0x89, 0x00, 9,
+                       2, 4, 3, 17, 34, 34, 34, 26720 },
+               { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 81000, /* 81 Mb */
+                       71900, 0x8a, 0x00, 10,
+                       2, 6, 3, 18, 35, 35, 35, 40080 },
+               { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 108000, /* 108 Mb */
+                       92500, 0x8b, 0x00, 11,
+                       4, 10, 3, 19, 36, 36, 36, 53440 },
+               { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 162000, /* 162 Mb */
+                       130300, 0x8c, 0x00, 12,
+                       4, 14, 3, 20, 37, 37, 37, 80160 },
+               { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 216000, /* 216 Mb */
+                       162800, 0x8d, 0x00, 13,
+                       4, 20, 3, 21, 38, 38, 38, 106880 },
+               { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 243000, /* 243 Mb */
+                       178200, 0x8e, 0x00, 14,
+                       4, 23, 3, 22, 39, 39, 39, 120240 },
+               { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 270000, /* 270 Mb */
+                       192100, 0x8f, 0x00, 15,
+                       4, 25, 3, 23, 40, 41, 41, 133600 },
+               { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS_HGI, 300000, /* 300 Mb */
+                       207000, 0x8f, 0x00, 15,
+                       4, 25, 3, 23, 40, 41, 41, 148400 },
+       },
+       50,  /* probe interval */
+       50,  /* rssi reduce interval */
+       WLAN_RC_HT_FLAG,  /* Phy rates allowed initially */
+};
+
+/* 4ms frame limit not used for NG mode.  The values filled
+ * for HT are the 64K max aggregate limit */
+
+static const struct ath_rate_table ar5416_11ng_ratetable = {
+       46,
+       {
+               { VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */
+                       900, 0x1b, 0x00, 2,
+                       0, 0, 1, 0, 0, 0, 0, 0 },
+               { VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */
+                       1900, 0x1a, 0x04, 4,
+                       1, 1, 1, 1, 1, 1, 1, 0 },
+               { VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */
+                       4900, 0x19, 0x04, 11,
+                       2, 2, 2, 2, 2, 2, 2, 0 },
+               { VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */
+                       8100, 0x18, 0x04, 22,
+                       3, 3, 2, 3, 3, 3, 3, 0 },
+               { INVALID, INVALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
+                       5400, 0x0b, 0x00, 12,
+                       4, 2, 1, 4, 4, 4, 4, 0 },
+               { INVALID, INVALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
+                       7800, 0x0f, 0x00, 18,
+                       4, 3, 1, 5, 5, 5, 5, 0 },
+               { VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
+                       10100, 0x0a, 0x00, 24,
+                       6, 4, 1, 6, 6, 6, 6, 0 },
+               { VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
+                       14100,  0x0e, 0x00, 36,
+                       6, 6, 2, 7, 7, 7, 7, 0 },
+               { VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
+                       17700, 0x09, 0x00, 48,
+                       8, 10, 3, 8, 8, 8, 8, 0 },
+               { VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
+                       23700, 0x0d, 0x00, 72,
+                       8, 14, 3, 9, 9, 9, 9, 0 },
+               { VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
+                       27400, 0x08, 0x00, 96,
+                       8, 20, 3, 10, 10, 10, 10, 0 },
+               { VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
+                       30900, 0x0c, 0x00, 108,
+                       8, 23, 3, 11, 11, 11, 11, 0 },
+               { INVALID, INVALID, WLAN_RC_PHY_HT_20_SS, 6500, /* 6.5 Mb */
+                       6400, 0x80, 0x00, 0,
+                       4, 2, 3, 12, 28, 12, 28, 3216 },
+               { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 13000, /* 13 Mb */
+                       12700, 0x81, 0x00, 1,
+                       6, 4, 3, 13, 29, 13, 29, 6434 },
+               { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 19500, /* 19.5 Mb */
+                       18800, 0x82, 0x00, 2,
+                       6, 6, 3, 14, 30, 14, 30, 9650 },
+               { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 26000, /* 26 Mb */
+                       25000, 0x83, 0x00, 3,
+                       8, 10, 3, 15, 31, 15, 31, 12868 },
+               { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 39000, /* 39 Mb */
+                       36700, 0x84, 0x00, 4,
+                       8, 14, 3, 16, 32, 16, 32, 19304 },
+               { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 52000, /* 52 Mb */
+                       48100, 0x85, 0x00, 5,
+                       8, 20, 3, 17, 33, 17, 33, 25740 },
+               { INVALID,  VALID_20, WLAN_RC_PHY_HT_20_SS, 58500, /* 58.5 Mb */
+                       53500, 0x86, 0x00, 6,
+                       8, 23, 3, 18, 34, 18, 34, 28956 },
+               { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 65000, /* 65 Mb */
+                       59000, 0x87, 0x00, 7,
+                       8, 25, 3, 19, 35, 19, 36, 32180 },
+               { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 13000, /* 13 Mb */
+                       12700, 0x88, 0x00, 8,
+                       4, 2, 3, 20, 37, 20, 37, 6430 },
+               { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 26000, /* 26 Mb */
+                       24800, 0x89, 0x00, 9,
+                       6, 4, 3, 21, 38, 21, 38, 12860 },
+               { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 39000, /* 39 Mb */
+                       36600, 0x8a, 0x00, 10,
+                       6, 6, 3, 22, 39, 22, 39, 19300 },
+               { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 52000, /* 52 Mb */
+                       48100, 0x8b, 0x00, 11,
+                       8, 10, 3, 23, 40, 23, 40, 25736 },
+               { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 78000, /* 78 Mb */
+                       69500, 0x8c, 0x00, 12,
+                       8, 14, 3, 24, 41, 24, 41, 38600 },
+               { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 104000, /* 104 Mb */
+                       89500, 0x8d, 0x00, 13,
+                       8, 20, 3, 25, 42, 25, 42, 51472 },
+               { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 117000, /* 117 Mb */
+                       98900, 0x8e, 0x00, 14,
+                       8, 23, 3, 26, 43, 26, 44, 57890 },
+               { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 130000, /* 130 Mb */
+                       108300, 0x8f, 0x00, 15,
+                       8, 25, 3, 27, 44, 27, 45, 64320 },
+               { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 13500, /* 13.5 Mb */
+                       13200, 0x80, 0x00, 0,
+                       8, 2, 3, 12, 28, 28, 28, 6684 },
+               { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 27500, /* 27.0 Mb */
+                       25900, 0x81, 0x00, 1,
+                       8, 4, 3, 13, 29, 29, 29, 13368 },
+               { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 40500, /* 40.5 Mb */
+                       38600, 0x82, 0x00, 2,
+                       8, 6, 3, 14, 30, 30, 30, 20052 },
+               { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 54000, /* 54 Mb */
+                       49800, 0x83, 0x00, 3,
+                       8, 10, 3, 15, 31, 31, 31, 26738 },
+               { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 81500, /* 81 Mb */
+                       72200, 0x84, 0x00, 4,
+                       8, 14, 3, 16, 32, 32, 32, 40104 },
+               { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 108000, /* 108 Mb */
+                       92900, 0x85, 0x00, 5,
+                       8, 20, 3, 17, 33, 33, 33, 53476 },
+               { INVALID,  VALID_40, WLAN_RC_PHY_HT_40_SS, 121500, /* 121.5 Mb */
+                       102700, 0x86, 0x00, 6,
+                       8, 23, 3, 18, 34, 34, 34, 60156 },
+               { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 135000, /* 135 Mb */
+                       112000, 0x87, 0x00, 7,
+                       8, 23, 3, 19, 35, 36, 36, 66840 },
+               { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000, /* 150 Mb */
+                       122000, 0x87, 0x00, 7,
+                       8, 25, 3, 19, 35, 36, 36, 74200 },
+               { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 27000, /* 27 Mb */
+                       25800, 0x88, 0x00, 8,
+                       8, 2, 3, 20, 37, 37, 37, 13360 },
+               { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 54000, /* 54 Mb */
+                       49800, 0x89, 0x00, 9,
+                       8, 4, 3, 21, 38, 38, 38, 26720 },
+               { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 81000, /* 81 Mb */
+                       71900, 0x8a, 0x00, 10,
+                       8, 6, 3, 22, 39, 39, 39, 40080 },
+               { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 108000, /* 108 Mb */
+                       92500, 0x8b, 0x00, 11,
+                       8, 10, 3, 23, 40, 40, 40, 53440 },
+               { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 162000, /* 162 Mb */
+                       130300, 0x8c, 0x00, 12,
+                       8, 14, 3, 24, 41, 41, 41, 80160 },
+               { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 216000, /* 216 Mb */
+                       162800, 0x8d, 0x00, 13,
+                       8, 20, 3, 25, 42, 42, 42, 106880 },
+               { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 243000, /* 243 Mb */
+                       178200, 0x8e, 0x00, 14,
+                       8, 23, 3, 26, 43, 43, 43, 120240 },
+               { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 270000, /* 270 Mb */
+                       192100, 0x8f, 0x00, 15,
+                       8, 23, 3, 27, 44, 45, 45, 133600 },
+               { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS_HGI, 300000, /* 300 Mb */
+                       207000, 0x8f, 0x00, 15,
+                       8, 25, 3, 27, 44, 45, 45, 148400 },
+               },
+       50,  /* probe interval */
+       50,  /* rssi reduce interval */
+       WLAN_RC_HT_FLAG,  /* Phy rates allowed initially */
+};
+
+static const struct ath_rate_table ar5416_11a_ratetable = {
+       8,
+       {
+               { VALID, VALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
+                       5400, 0x0b, 0x00, (0x80|12),
+                       0, 2, 1, 0, 0 },
+               { VALID, VALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
+                       7800, 0x0f, 0x00, 18,
+                       0, 3, 1, 1, 0 },
+               { VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
+                       10000, 0x0a, 0x00, (0x80|24),
+                       2, 4, 2, 2, 0 },
+               { VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
+                       13900, 0x0e, 0x00, 36,
+                       2, 6, 2, 3, 0 },
+               { VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
+                       17300, 0x09, 0x00, (0x80|48),
+                       4, 10, 3, 4, 0 },
+               { VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
+                       23000, 0x0d, 0x00, 72,
+                       4, 14, 3, 5, 0 },
+               { VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
+                       27400, 0x08, 0x00, 96,
+                       4, 19, 3, 6, 0 },
+               { VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
+                       29300, 0x0c, 0x00, 108,
+                       4, 23, 3, 7, 0 },
+       },
+       50,  /* probe interval */
+       50,  /* rssi reduce interval */
+       0,   /* Phy rates allowed initially */
+};
+
+static const struct ath_rate_table ar5416_11g_ratetable = {
+       12,
+       {
+               { VALID, VALID, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */
+                       900, 0x1b, 0x00, 2,
+                       0, 0, 1, 0, 0 },
+               { VALID, VALID, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */
+                       1900, 0x1a, 0x04, 4,
+                       1, 1, 1, 1, 0 },
+               { VALID, VALID, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */
+                       4900, 0x19, 0x04, 11,
+                       2, 2, 2, 2, 0 },
+               { VALID, VALID, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */
+                       8100, 0x18, 0x04, 22,
+                       3, 3, 2, 3, 0 },
+               { INVALID, INVALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
+                       5400, 0x0b, 0x00, 12,
+                       4, 2, 1, 4, 0 },
+               { INVALID, INVALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
+                       7800, 0x0f, 0x00, 18,
+                       4, 3, 1, 5, 0 },
+               { VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
+                       10000, 0x0a, 0x00, 24,
+                       6, 4, 1, 6, 0 },
+               { VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
+                       13900, 0x0e, 0x00, 36,
+                       6, 6, 2, 7, 0 },
+               { VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
+                       17300, 0x09, 0x00, 48,
+                       8, 10, 3, 8, 0 },
+               { VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
+                       23000, 0x0d, 0x00, 72,
+                       8, 14, 3, 9, 0 },
+               { VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
+                       27400, 0x08, 0x00, 96,
+                       8, 19, 3, 10, 0 },
+               { VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
+                       29300, 0x0c, 0x00, 108,
+                       8, 23, 3, 11, 0 },
+       },
+       50,  /* probe interval */
+       50,  /* rssi reduce interval */
+       0,   /* Phy rates allowed initially */
+};
+
+static const struct ath_rate_table ar5416_11b_ratetable = {
+       4,
+       {
+               { VALID, VALID, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */
+                       900, 0x1b,  0x00, (0x80|2),
+                       0, 0, 1, 0, 0 },
+               { VALID, VALID, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */
+                       1800, 0x1a, 0x04, (0x80|4),
+                       1, 1, 1, 1, 0 },
+               { VALID, VALID, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */
+                       4300, 0x19, 0x04, (0x80|11),
+                       1, 2, 2, 2, 0 },
+               { VALID, VALID, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */
+                       7100, 0x18, 0x04, (0x80|22),
+                       1, 4, 100, 3, 0 },
+       },
+       100, /* probe interval */
+       100, /* rssi reduce interval */
+       0,   /* Phy rates allowed initially */
+};
+
+static inline int8_t median(int8_t a, int8_t b, int8_t c)
+{
+       if (a >= b) {
+               if (b >= c)
+                       return b;
+               else if (a > c)
+                       return c;
+               else
+                       return a;
+       } else {
+               if (a >= c)
+                       return a;
+               else if (b >= c)
+                       return c;
+               else
+                       return b;
+       }
+}
+
+static void ath_rc_sort_validrates(const struct ath_rate_table *rate_table,
+                                  struct ath_rate_priv *ath_rc_priv)
+{
+       u8 i, j, idx, idx_next;
+
+       for (i = ath_rc_priv->max_valid_rate - 1; i > 0; i--) {
+               for (j = 0; j <= i-1; j++) {
+                       idx = ath_rc_priv->valid_rate_index[j];
+                       idx_next = ath_rc_priv->valid_rate_index[j+1];
+
+                       if (rate_table->info[idx].ratekbps >
+                               rate_table->info[idx_next].ratekbps) {
+                               ath_rc_priv->valid_rate_index[j] = idx_next;
+                               ath_rc_priv->valid_rate_index[j+1] = idx;
+                       }
+               }
+       }
+}
+
+static void ath_rc_init_valid_txmask(struct ath_rate_priv *ath_rc_priv)
+{
+       u8 i;
+
+       for (i = 0; i < ath_rc_priv->rate_table_size; i++)
+               ath_rc_priv->valid_rate_index[i] = 0;
+}
+
+static inline void ath_rc_set_valid_txmask(struct ath_rate_priv *ath_rc_priv,
+                                          u8 index, int valid_tx_rate)
+{
+       ASSERT(index <= ath_rc_priv->rate_table_size);
+       ath_rc_priv->valid_rate_index[index] = valid_tx_rate ? 1 : 0;
+}
+
+static inline int ath_rc_isvalid_txmask(struct ath_rate_priv *ath_rc_priv,
+                                       u8 index)
+{
+       ASSERT(index <= ath_rc_priv->rate_table_size);
+       return ath_rc_priv->valid_rate_index[index];
+}
+
+static inline
+int ath_rc_get_nextvalid_txrate(const struct ath_rate_table *rate_table,
+                               struct ath_rate_priv *ath_rc_priv,
+                               u8 cur_valid_txrate,
+                               u8 *next_idx)
+{
+       u8 i;
+
+       for (i = 0; i < ath_rc_priv->max_valid_rate - 1; i++) {
+               if (ath_rc_priv->valid_rate_index[i] == cur_valid_txrate) {
+                       *next_idx = ath_rc_priv->valid_rate_index[i+1];
+                       return 1;
+               }
+       }
+
+       /* No more valid rates */
+       *next_idx = 0;
+
+       return 0;
+}
+
+/* Return true only for single stream */
+
+static int ath_rc_valid_phyrate(u32 phy, u32 capflag, int ignore_cw)
+{
+       if (WLAN_RC_PHY_HT(phy) && !(capflag & WLAN_RC_HT_FLAG))
+               return 0;
+       if (WLAN_RC_PHY_DS(phy) && !(capflag & WLAN_RC_DS_FLAG))
+               return 0;
+       if (WLAN_RC_PHY_SGI(phy) && !(capflag & WLAN_RC_SGI_FLAG))
+               return 0;
+       if (!ignore_cw && WLAN_RC_PHY_HT(phy))
+               if (WLAN_RC_PHY_40(phy) && !(capflag & WLAN_RC_40_FLAG))
+                       return 0;
+               if (!WLAN_RC_PHY_40(phy) && (capflag & WLAN_RC_40_FLAG))
+                       return 0;
+       return 1;
+}
+
+static inline int
+ath_rc_get_nextlowervalid_txrate(const struct ath_rate_table *rate_table,
+                                struct ath_rate_priv *ath_rc_priv,
+                                u8 cur_valid_txrate, u8 *next_idx)
+{
+       int8_t i;
+
+       for (i = 1; i < ath_rc_priv->max_valid_rate ; i++) {
+               if (ath_rc_priv->valid_rate_index[i] == cur_valid_txrate) {
+                       *next_idx = ath_rc_priv->valid_rate_index[i-1];
+                       return 1;
+               }
+       }
+
+       return 0;
+}
+
+static u8 ath_rc_init_validrates(struct ath_rate_priv *ath_rc_priv,
+                                const struct ath_rate_table *rate_table,
+                                u32 capflag)
+{
+       u8 i, hi = 0;
+       u32 valid;
+
+       for (i = 0; i < rate_table->rate_cnt; i++) {
+               valid = (!(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG) ?
+                        rate_table->info[i].valid_single_stream :
+                        rate_table->info[i].valid);
+               if (valid == 1) {
+                       u32 phy = rate_table->info[i].phy;
+                       u8 valid_rate_count = 0;
+
+                       if (!ath_rc_valid_phyrate(phy, capflag, 0))
+                               continue;
+
+                       valid_rate_count = ath_rc_priv->valid_phy_ratecnt[phy];
+
+                       ath_rc_priv->valid_phy_rateidx[phy][valid_rate_count] = i;
+                       ath_rc_priv->valid_phy_ratecnt[phy] += 1;
+                       ath_rc_set_valid_txmask(ath_rc_priv, i, 1);
+                       hi = A_MAX(hi, i);
+               }
+       }
+
+       return hi;
+}
+
+static u8 ath_rc_setvalid_rates(struct ath_rate_priv *ath_rc_priv,
+                               const struct ath_rate_table *rate_table,
+                               struct ath_rateset *rateset,
+                               u32 capflag)
+{
+       u8 i, j, hi = 0;
+
+       /* Use intersection of working rates and valid rates */
+       for (i = 0; i < rateset->rs_nrates; i++) {
+               for (j = 0; j < rate_table->rate_cnt; j++) {
+                       u32 phy = rate_table->info[j].phy;
+                       u32 valid = (!(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG) ?
+                                    rate_table->info[j].valid_single_stream :
+                                    rate_table->info[j].valid);
+                       u8 rate = rateset->rs_rates[i];
+                       u8 dot11rate = rate_table->info[j].dot11rate;
+
+                       /* We allow a rate only if its valid and the
+                        * capflag matches one of the validity
+                        * (VALID/VALID_20/VALID_40) flags */
+
+                       if (((rate & 0x7F) == (dot11rate & 0x7F)) &&
+                           ((valid & WLAN_RC_CAP_MODE(capflag)) ==
+                            WLAN_RC_CAP_MODE(capflag)) &&
+                           !WLAN_RC_PHY_HT(phy)) {
+                               u8 valid_rate_count = 0;
+
+                               if (!ath_rc_valid_phyrate(phy, capflag, 0))
+                                       continue;
+
+                               valid_rate_count =
+                                       ath_rc_priv->valid_phy_ratecnt[phy];
+
+                               ath_rc_priv->valid_phy_rateidx[phy]
+                                       [valid_rate_count] = j;
+                               ath_rc_priv->valid_phy_ratecnt[phy] += 1;
+                               ath_rc_set_valid_txmask(ath_rc_priv, j, 1);
+                               hi = A_MAX(hi, j);
+                       }
+               }
+       }
+
+       return hi;
+}
+
+static u8 ath_rc_setvalid_htrates(struct ath_rate_priv *ath_rc_priv,
+                                 const struct ath_rate_table *rate_table,
+                                 u8 *mcs_set, u32 capflag)
+{
+       struct ath_rateset *rateset = (struct ath_rateset *)mcs_set;
+
+       u8 i, j, hi = 0;
+
+       /* Use intersection of working rates and valid rates */
+       for (i = 0; i < rateset->rs_nrates; i++) {
+               for (j = 0; j < rate_table->rate_cnt; j++) {
+                       u32 phy = rate_table->info[j].phy;
+                       u32 valid = (!(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG) ?
+                                    rate_table->info[j].valid_single_stream :
+                                    rate_table->info[j].valid);
+                       u8 rate = rateset->rs_rates[i];
+                       u8 dot11rate = rate_table->info[j].dot11rate;
+
+                       if (((rate & 0x7F) != (dot11rate & 0x7F)) ||
+                           !WLAN_RC_PHY_HT(phy) ||
+                           !WLAN_RC_PHY_HT_VALID(valid, capflag))
+                               continue;
+
+                       if (!ath_rc_valid_phyrate(phy, capflag, 0))
+                               continue;
+
+                       ath_rc_priv->valid_phy_rateidx[phy]
+                               [ath_rc_priv->valid_phy_ratecnt[phy]] = j;
+                       ath_rc_priv->valid_phy_ratecnt[phy] += 1;
+                       ath_rc_set_valid_txmask(ath_rc_priv, j, 1);
+                       hi = A_MAX(hi, j);
+               }
+       }
+
+       return hi;
+}
+
+static u8 ath_rc_ratefind_ht(struct ath_softc *sc,
+                            struct ath_rate_priv *ath_rc_priv,
+                            const struct ath_rate_table *rate_table,
+                            int *is_probing)
+{
+       u32 dt, best_thruput, this_thruput, now_msec;
+       u8 rate, next_rate, best_rate, maxindex, minindex;
+       int8_t  rssi_last, rssi_reduce = 0, index = 0;
+
+       *is_probing = 0;
+
+       rssi_last = median(ath_rc_priv->rssi_last,
+                          ath_rc_priv->rssi_last_prev,
+                          ath_rc_priv->rssi_last_prev2);
+
+       /*
+        * Age (reduce) last ack rssi based on how old it is.
+        * The bizarre numbers are so the delta is 160msec,
+        * meaning we divide by 16.
+        *   0msec   <= dt <= 25msec:   don't derate
+        *   25msec  <= dt <= 185msec:  derate linearly from 0 to 10dB
+        *   185msec <= dt:             derate by 10dB
+        */
+
+       now_msec = jiffies_to_msecs(jiffies);
+       dt = now_msec - ath_rc_priv->rssi_time;
+
+       if (dt >= 185)
+               rssi_reduce = 10;
+       else if (dt >= 25)
+               rssi_reduce = (u8)((dt - 25) >> 4);
+
+       /* Now reduce rssi_last by rssi_reduce */
+       if (rssi_last < rssi_reduce)
+               rssi_last = 0;
+       else
+               rssi_last -= rssi_reduce;
+
+       /*
+        * Now look up the rate in the rssi table and return it.
+        * If no rates match then we return 0 (lowest rate)
+        */
+
+       best_thruput = 0;
+       maxindex = ath_rc_priv->max_valid_rate-1;
+
+       minindex = 0;
+       best_rate = minindex;
+
+       /*
+        * Try the higher rate first. It will reduce memory moving time
+        * if we have very good channel characteristics.
+        */
+       for (index = maxindex; index >= minindex ; index--) {
+               u8 per_thres;
+
+               rate = ath_rc_priv->valid_rate_index[index];
+               if (rate > ath_rc_priv->rate_max_phy)
+                       continue;
+
+               /*
+                * For TCP the average collision rate is around 11%,
+                * so we ignore PERs less than this.  This is to
+                * prevent the rate we are currently using (whose
+                * PER might be in the 10-15 range because of TCP
+                * collisions) looking worse than the next lower
+                * rate whose PER has decayed close to 0.  If we
+                * used to next lower rate, its PER would grow to
+                * 10-15 and we would be worse off then staying
+                * at the current rate.
+                */
+               per_thres = ath_rc_priv->state[rate].per;
+               if (per_thres < 12)
+                       per_thres = 12;
+
+               this_thruput = rate_table->info[rate].user_ratekbps *
+                       (100 - per_thres);
+
+               if (best_thruput <= this_thruput) {
+                       best_thruput = this_thruput;
+                       best_rate    = rate;
+               }
+       }
+
+       rate = best_rate;
+       ath_rc_priv->rssi_last_lookup = rssi_last;
+
+       /*
+        * Must check the actual rate (ratekbps) to account for
+        * non-monoticity of 11g's rate table
+        */
+
+       if (rate >= ath_rc_priv->rate_max_phy) {
+               rate = ath_rc_priv->rate_max_phy;
+
+               /* Probe the next allowed phy state */
+               if (ath_rc_get_nextvalid_txrate(rate_table,
+                                       ath_rc_priv, rate, &next_rate) &&
+                   (now_msec - ath_rc_priv->probe_time >
+                    rate_table->probe_interval) &&
+                   (ath_rc_priv->hw_maxretry_pktcnt >= 1)) {
+                       rate = next_rate;
+                       ath_rc_priv->probe_rate = rate;
+                       ath_rc_priv->probe_time = now_msec;
+                       ath_rc_priv->hw_maxretry_pktcnt = 0;
+                       *is_probing = 1;
+               }
+       }
+
+       if (rate > (ath_rc_priv->rate_table_size - 1))
+               rate = ath_rc_priv->rate_table_size - 1;
+
+       ASSERT((rate_table->info[rate].valid &&
+               (ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG)) ||
+              (rate_table->info[rate].valid_single_stream &&
+               !(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG)));
+
+       return rate;
+}
+
+static void ath_rc_rate_set_series(const struct ath_rate_table *rate_table,
+                                  struct ieee80211_tx_rate *rate,
+                                  struct ieee80211_tx_rate_control *txrc,
+                                  u8 tries, u8 rix, int rtsctsenable)
+{
+       rate->count = tries;
+       rate->idx = rix;
+
+       if (txrc->short_preamble)
+               rate->flags |= IEEE80211_TX_RC_USE_SHORT_PREAMBLE;
+       if (txrc->rts || rtsctsenable)
+               rate->flags |= IEEE80211_TX_RC_USE_RTS_CTS;
+       if (WLAN_RC_PHY_40(rate_table->info[rix].phy))
+               rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
+       if (WLAN_RC_PHY_SGI(rate_table->info[rix].phy))
+               rate->flags |= IEEE80211_TX_RC_SHORT_GI;
+       if (WLAN_RC_PHY_HT(rate_table->info[rix].phy))
+               rate->flags |= IEEE80211_TX_RC_MCS;
+}
+
+static void ath_rc_rate_set_rtscts(struct ath_softc *sc,
+                                  const struct ath_rate_table *rate_table,
+                                  struct ieee80211_tx_info *tx_info)
+{
+       struct ieee80211_tx_rate *rates = tx_info->control.rates;
+       int i = 0, rix = 0, cix, enable_g_protection = 0;
+
+       /* get the cix for the lowest valid rix */
+       for (i = 3; i >= 0; i--) {
+               if (rates[i].count && (rates[i].idx >= 0)) {
+                       rix = rates[i].idx;
+                       break;
+               }
+       }
+       cix = rate_table->info[rix].ctrl_rate;
+
+       /* All protection frames are transmited at 2Mb/s for 802.11g,
+        * otherwise we transmit them at 1Mb/s */
+       if (sc->hw->conf.channel->band == IEEE80211_BAND_2GHZ &&
+           !conf_is_ht(&sc->hw->conf))
+               enable_g_protection = 1;
+
+       /*
+        * If 802.11g protection is enabled, determine whether to use RTS/CTS or
+        * just CTS.  Note that this is only done for OFDM/HT unicast frames.
+        */
+       if ((sc->sc_flags & SC_OP_PROTECT_ENABLE) &&
+           !(tx_info->flags & IEEE80211_TX_CTL_NO_ACK) &&
+           (rate_table->info[rix].phy == WLAN_RC_PHY_OFDM ||
+            WLAN_RC_PHY_HT(rate_table->info[rix].phy))) {
+               rates[0].flags |= IEEE80211_TX_RC_USE_CTS_PROTECT;
+               cix = rate_table->info[enable_g_protection].ctrl_rate;
+       }
+
+       tx_info->control.rts_cts_rate_idx = cix;
+}
+
+static u8 ath_rc_rate_getidx(struct ath_softc *sc,
+                            struct ath_rate_priv *ath_rc_priv,
+                            const struct ath_rate_table *rate_table,
+                            u8 rix, u16 stepdown,
+                            u16 min_rate)
+{
+       u32 j;
+       u8 nextindex = 0;
+
+       if (min_rate) {
+               for (j = RATE_TABLE_SIZE; j > 0; j--) {
+                       if (ath_rc_get_nextlowervalid_txrate(rate_table,
+                                               ath_rc_priv, rix, &nextindex))
+                               rix = nextindex;
+                       else
+                               break;
+               }
+       } else {
+               for (j = stepdown; j > 0; j--) {
+                       if (ath_rc_get_nextlowervalid_txrate(rate_table,
+                                               ath_rc_priv, rix, &nextindex))
+                               rix = nextindex;
+                       else
+                               break;
+               }
+       }
+       return rix;
+}
+
+static void ath_rc_ratefind(struct ath_softc *sc,
+                           struct ath_rate_priv *ath_rc_priv,
+                           struct ieee80211_tx_rate_control *txrc)
+{
+       const struct ath_rate_table *rate_table;
+       struct sk_buff *skb = txrc->skb;
+       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+       struct ieee80211_tx_rate *rates = tx_info->control.rates;
+       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+       __le16 fc = hdr->frame_control;
+       u8 try_per_rate = 0, i = 0, rix, nrix;
+       int is_probe = 0;
+
+       rate_table = sc->cur_rate_table;
+       rix = ath_rc_ratefind_ht(sc, ath_rc_priv, rate_table, &is_probe);
+       nrix = rix;
+
+       if (is_probe) {
+               /* set one try for probe rates. For the
+                * probes don't enable rts */
+               ath_rc_rate_set_series(rate_table, &rates[i++], txrc,
+                                      1, nrix, 0);
+
+               try_per_rate = (ATH_11N_TXMAXTRY/4);
+               /* Get the next tried/allowed rate. No RTS for the next series
+                * after the probe rate
+                */
+               nrix = ath_rc_rate_getidx(sc, ath_rc_priv,
+                                         rate_table, nrix, 1, 0);
+               ath_rc_rate_set_series(rate_table, &rates[i++], txrc,
+                                      try_per_rate, nrix, 0);
+
+               tx_info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE;
+       } else {
+               try_per_rate = (ATH_11N_TXMAXTRY/4);
+               /* Set the choosen rate. No RTS for first series entry. */
+               ath_rc_rate_set_series(rate_table, &rates[i++], txrc,
+                                      try_per_rate, nrix, 0);
+       }
+
+       /* Fill in the other rates for multirate retry */
+       for ( ; i < 4; i++) {
+               u8 try_num;
+               u8 min_rate;
+
+               try_num = ((i + 1) == 4) ?
+                       ATH_11N_TXMAXTRY - (try_per_rate * i) : try_per_rate ;
+               min_rate = (((i + 1) == 4) && 0);
+
+               nrix = ath_rc_rate_getidx(sc, ath_rc_priv,
+                                         rate_table, nrix, 1, min_rate);
+               /* All other rates in the series have RTS enabled */
+               ath_rc_rate_set_series(rate_table, &rates[i], txrc,
+                                      try_num, nrix, 1);
+       }
+
+       /*
+        * NB:Change rate series to enable aggregation when operating
+        * at lower MCS rates. When first rate in series is MCS2
+        * in HT40 @ 2.4GHz, series should look like:
+        *
+        * {MCS2, MCS1, MCS0, MCS0}.
+        *
+        * When first rate in series is MCS3 in HT20 @ 2.4GHz, series should
+        * look like:
+        *
+        * {MCS3, MCS2, MCS1, MCS1}
+        *
+        * So, set fourth rate in series to be same as third one for
+        * above conditions.
+        */
+       if ((sc->hw->conf.channel->band == IEEE80211_BAND_2GHZ) &&
+           (conf_is_ht(&sc->hw->conf))) {
+               u8 dot11rate = rate_table->info[rix].dot11rate;
+               u8 phy = rate_table->info[rix].phy;
+               if (i == 4 &&
+                   ((dot11rate == 2 && phy == WLAN_RC_PHY_HT_40_SS) ||
+                    (dot11rate == 3 && phy == WLAN_RC_PHY_HT_20_SS))) {
+                       rates[3].idx = rates[2].idx;
+                       rates[3].flags = rates[2].flags;
+               }
+       }
+
+       /*
+        * Force hardware to use computed duration for next
+        * fragment by disabling multi-rate retry, which
+        * updates duration based on the multi-rate duration table.
+        *
+        * FIXME: Fix duration
+        */
+       if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK) &&
+           (ieee80211_has_morefrags(fc) ||
+            (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG))) {
+               rates[1].count = rates[2].count = rates[3].count = 0;
+               rates[1].idx = rates[2].idx = rates[3].idx = 0;
+               rates[0].count = ATH_TXMAXTRY;
+       }
+
+       /* Setup RTS/CTS */
+       ath_rc_rate_set_rtscts(sc, rate_table, tx_info);
+}
+
+static bool ath_rc_update_per(struct ath_softc *sc,
+                             const struct ath_rate_table *rate_table,
+                             struct ath_rate_priv *ath_rc_priv,
+                             struct ath_tx_info_priv *tx_info_priv,
+                             int tx_rate, int xretries, int retries,
+                             u32 now_msec)
+{
+       bool state_change = false;
+       int count;
+       u8 last_per;
+       static u32 nretry_to_per_lookup[10] = {
+               100 * 0 / 1,
+               100 * 1 / 4,
+               100 * 1 / 2,
+               100 * 3 / 4,
+               100 * 4 / 5,
+               100 * 5 / 6,
+               100 * 6 / 7,
+               100 * 7 / 8,
+               100 * 8 / 9,
+               100 * 9 / 10
+       };
+
+       last_per = ath_rc_priv->state[tx_rate].per;
+
+       if (xretries) {
+               if (xretries == 1) {
+                       ath_rc_priv->state[tx_rate].per += 30;
+                       if (ath_rc_priv->state[tx_rate].per > 100)
+                               ath_rc_priv->state[tx_rate].per = 100;
+               } else {
+                       /* xretries == 2 */
+                       count = ARRAY_SIZE(nretry_to_per_lookup);
+                       if (retries >= count)
+                               retries = count - 1;
+
+                       /* new_PER = 7/8*old_PER + 1/8*(currentPER) */
+                       ath_rc_priv->state[tx_rate].per =
+                               (u8)(last_per - (last_per >> 3) + (100 >> 3));
+               }
+
+               /* xretries == 1 or 2 */
+
+               if (ath_rc_priv->probe_rate == tx_rate)
+                       ath_rc_priv->probe_rate = 0;
+
+       } else { /* xretries == 0 */
+               count = ARRAY_SIZE(nretry_to_per_lookup);
+               if (retries >= count)
+                       retries = count - 1;
+
+               if (tx_info_priv->n_bad_frames) {
+                       /* new_PER = 7/8*old_PER + 1/8*(currentPER)
+                        * Assuming that n_frames is not 0.  The current PER
+                        * from the retries is 100 * retries / (retries+1),
+                        * since the first retries attempts failed, and the
+                        * next one worked.  For the one that worked,
+                        * n_bad_frames subframes out of n_frames wored,
+                        * so the PER for that part is
+                        * 100 * n_bad_frames / n_frames, and it contributes
+                        * 100 * n_bad_frames / (n_frames * (retries+1)) to
+                        * the above PER.  The expression below is a
+                        * simplified version of the sum of these two terms.
+                        */
+                       if (tx_info_priv->n_frames > 0) {
+                               int n_frames, n_bad_frames;
+                               u8 cur_per, new_per;
+
+                               n_bad_frames = retries * tx_info_priv->n_frames +
+                                       tx_info_priv->n_bad_frames;
+                               n_frames = tx_info_priv->n_frames * (retries + 1);
+                               cur_per = (100 * n_bad_frames / n_frames) >> 3;
+                               new_per = (u8)(last_per - (last_per >> 3) + cur_per);
+                               ath_rc_priv->state[tx_rate].per = new_per;
+                       }
+               } else {
+                       ath_rc_priv->state[tx_rate].per =
+                               (u8)(last_per - (last_per >> 3) +
+                                    (nretry_to_per_lookup[retries] >> 3));
+               }
+
+               ath_rc_priv->rssi_last_prev2 = ath_rc_priv->rssi_last_prev;
+               ath_rc_priv->rssi_last_prev  = ath_rc_priv->rssi_last;
+               ath_rc_priv->rssi_last = tx_info_priv->tx.ts_rssi;
+               ath_rc_priv->rssi_time = now_msec;
+
+               /*
+                * If we got at most one retry then increase the max rate if
+                * this was a probe.  Otherwise, ignore the probe.
+                */
+               if (ath_rc_priv->probe_rate && ath_rc_priv->probe_rate == tx_rate) {
+                       if (retries > 0 || 2 * tx_info_priv->n_bad_frames >
+                               tx_info_priv->n_frames) {
+                               /*
+                                * Since we probed with just a single attempt,
+                                * any retries means the probe failed.  Also,
+                                * if the attempt worked, but more than half
+                                * the subframes were bad then also consider
+                                * the probe a failure.
+                                */
+                               ath_rc_priv->probe_rate = 0;
+                       } else {
+                               u8 probe_rate = 0;
+
+                               ath_rc_priv->rate_max_phy =
+                                       ath_rc_priv->probe_rate;
+                               probe_rate = ath_rc_priv->probe_rate;
+
+                               if (ath_rc_priv->state[probe_rate].per > 30)
+                                       ath_rc_priv->state[probe_rate].per = 20;
+
+                               ath_rc_priv->probe_rate = 0;
+
+                               /*
+                                * Since this probe succeeded, we allow the next
+                                * probe twice as soon.  This allows the maxRate
+                                * to move up faster if the probes are
+                                * succesful.
+                                */
+                               ath_rc_priv->probe_time =
+                                       now_msec - rate_table->probe_interval / 2;
+                       }
+               }
+
+               if (retries > 0) {
+                       /*
+                        * Don't update anything.  We don't know if
+                        * this was because of collisions or poor signal.
+                        *
+                        * Later: if rssi_ack is close to
+                        * ath_rc_priv->state[txRate].rssi_thres and we see lots
+                        * of retries, then we could increase
+                        * ath_rc_priv->state[txRate].rssi_thres.
+                        */
+                       ath_rc_priv->hw_maxretry_pktcnt = 0;
+               } else {
+                       int32_t rssi_ackAvg;
+                       int8_t rssi_thres;
+                       int8_t rssi_ack_vmin;
+
+                       /*
+                        * It worked with no retries. First ignore bogus (small)
+                        * rssi_ack values.
+                        */
+                       if (tx_rate == ath_rc_priv->rate_max_phy &&
+                           ath_rc_priv->hw_maxretry_pktcnt < 255) {
+                               ath_rc_priv->hw_maxretry_pktcnt++;
+                       }
+
+                       if (tx_info_priv->tx.ts_rssi <
+                           rate_table->info[tx_rate].rssi_ack_validmin)
+                               goto exit;
+
+                       /* Average the rssi */
+                       if (tx_rate != ath_rc_priv->rssi_sum_rate) {
+                               ath_rc_priv->rssi_sum_rate = tx_rate;
+                               ath_rc_priv->rssi_sum =
+                                       ath_rc_priv->rssi_sum_cnt = 0;
+                       }
+
+                       ath_rc_priv->rssi_sum += tx_info_priv->tx.ts_rssi;
+                       ath_rc_priv->rssi_sum_cnt++;
+
+                       if (ath_rc_priv->rssi_sum_cnt < 4)
+                               goto exit;
+
+                       rssi_ackAvg =
+                               (ath_rc_priv->rssi_sum + 2) / 4;
+                       rssi_thres =
+                               ath_rc_priv->state[tx_rate].rssi_thres;
+                       rssi_ack_vmin =
+                               rate_table->info[tx_rate].rssi_ack_validmin;
+
+                       ath_rc_priv->rssi_sum =
+                               ath_rc_priv->rssi_sum_cnt = 0;
+
+                       /* Now reduce the current rssi threshold */
+                       if ((rssi_ackAvg < rssi_thres + 2) &&
+                           (rssi_thres > rssi_ack_vmin)) {
+                               ath_rc_priv->state[tx_rate].rssi_thres--;
+                       }
+
+                       state_change = true;
+               }
+       }
+exit:
+       return state_change;
+}
+
+/* Update PER, RSSI and whatever else that the code thinks it is doing.
+   If you can make sense of all this, you really need to go out more. */
+
+static void ath_rc_update_ht(struct ath_softc *sc,
+                            struct ath_rate_priv *ath_rc_priv,
+                            struct ath_tx_info_priv *tx_info_priv,
+                            int tx_rate, int xretries, int retries)
+{
+#define CHK_RSSI(rate)                                 \
+       ((ath_rc_priv->state[(rate)].rssi_thres +       \
+         rate_table->info[(rate)].rssi_ack_deltamin) > \
+        ath_rc_priv->state[(rate)+1].rssi_thres)
+
+       u32 now_msec = jiffies_to_msecs(jiffies);
+       int rate;
+       u8 last_per;
+       bool state_change = false;
+       const struct ath_rate_table *rate_table = sc->cur_rate_table;
+       int size = ath_rc_priv->rate_table_size;
+
+       if ((tx_rate < 0) || (tx_rate > rate_table->rate_cnt))
+               return;
+
+       /* To compensate for some imbalance between ctrl and ext. channel */
+
+       if (WLAN_RC_PHY_40(rate_table->info[tx_rate].phy))
+               tx_info_priv->tx.ts_rssi =
+                       tx_info_priv->tx.ts_rssi < 3 ? 0 :
+                       tx_info_priv->tx.ts_rssi - 3;
+
+       last_per = ath_rc_priv->state[tx_rate].per;
+
+       /* Update PER first */
+       state_change = ath_rc_update_per(sc, rate_table, ath_rc_priv,
+                                        tx_info_priv, tx_rate, xretries,
+                                        retries, now_msec);
+
+       /*
+        * If this rate looks bad (high PER) then stop using it for
+        * a while (except if we are probing).
+        */
+       if (ath_rc_priv->state[tx_rate].per >= 55 && tx_rate > 0 &&
+           rate_table->info[tx_rate].ratekbps <=
+           rate_table->info[ath_rc_priv->rate_max_phy].ratekbps) {
+               ath_rc_get_nextlowervalid_txrate(rate_table, ath_rc_priv,
+                                (u8)tx_rate, &ath_rc_priv->rate_max_phy);
+
+               /* Don't probe for a little while. */
+               ath_rc_priv->probe_time = now_msec;
+       }
+
+       if (state_change) {
+               /*
+                * Make sure the rates above this have higher rssi thresholds.
+                * (Note:  Monotonicity is kept within the OFDM rates and
+                *         within the CCK rates. However, no adjustment is
+                *         made to keep the rssi thresholds monotonically
+                *         increasing between the CCK and OFDM rates.)
+                */
+               for (rate = tx_rate; rate < size - 1; rate++) {
+                       if (rate_table->info[rate+1].phy !=
+                           rate_table->info[tx_rate].phy)
+                               break;
+
+                       if (CHK_RSSI(rate)) {
+                               ath_rc_priv->state[rate+1].rssi_thres =
+                                       ath_rc_priv->state[rate].rssi_thres +
+                                       rate_table->info[rate].rssi_ack_deltamin;
+                       }
+               }
+
+               /* Make sure the rates below this have lower rssi thresholds. */
+               for (rate = tx_rate - 1; rate >= 0; rate--) {
+                       if (rate_table->info[rate].phy !=
+                           rate_table->info[tx_rate].phy)
+                               break;
+
+                       if (CHK_RSSI(rate)) {
+                               if (ath_rc_priv->state[rate+1].rssi_thres <
+                                   rate_table->info[rate].rssi_ack_deltamin)
+                                       ath_rc_priv->state[rate].rssi_thres = 0;
+                               else {
+                                       ath_rc_priv->state[rate].rssi_thres =
+                                       ath_rc_priv->state[rate+1].rssi_thres -
+                                       rate_table->info[rate].rssi_ack_deltamin;
+                               }
+
+                               if (ath_rc_priv->state[rate].rssi_thres <
+                                   rate_table->info[rate].rssi_ack_validmin) {
+                                       ath_rc_priv->state[rate].rssi_thres =
+                                       rate_table->info[rate].rssi_ack_validmin;
+                               }
+                       }
+               }
+       }
+
+       /* Make sure the rates below this have lower PER */
+       /* Monotonicity is kept only for rates below the current rate. */
+       if (ath_rc_priv->state[tx_rate].per < last_per) {
+               for (rate = tx_rate - 1; rate >= 0; rate--) {
+                       if (rate_table->info[rate].phy !=
+                           rate_table->info[tx_rate].phy)
+                               break;
+
+                       if (ath_rc_priv->state[rate].per >
+                           ath_rc_priv->state[rate+1].per) {
+                               ath_rc_priv->state[rate].per =
+                                       ath_rc_priv->state[rate+1].per;
+                       }
+               }
+       }
+
+       /* Maintain monotonicity for rates above the current rate */
+       for (rate = tx_rate; rate < size - 1; rate++) {
+               if (ath_rc_priv->state[rate+1].per <
+                   ath_rc_priv->state[rate].per)
+                       ath_rc_priv->state[rate+1].per =
+                               ath_rc_priv->state[rate].per;
+       }
+
+       /* Every so often, we reduce the thresholds and
+        * PER (different for CCK and OFDM). */
+       if (now_msec - ath_rc_priv->rssi_down_time >=
+           rate_table->rssi_reduce_interval) {
+
+               for (rate = 0; rate < size; rate++) {
+                       if (ath_rc_priv->state[rate].rssi_thres >
+                           rate_table->info[rate].rssi_ack_validmin)
+                               ath_rc_priv->state[rate].rssi_thres -= 1;
+               }
+               ath_rc_priv->rssi_down_time = now_msec;
+       }
+
+       /* Every so often, we reduce the thresholds
+        * and PER (different for CCK and OFDM). */
+       if (now_msec - ath_rc_priv->per_down_time >=
+           rate_table->rssi_reduce_interval) {
+               for (rate = 0; rate < size; rate++) {
+                       ath_rc_priv->state[rate].per =
+                               7 * ath_rc_priv->state[rate].per / 8;
+               }
+
+               ath_rc_priv->per_down_time = now_msec;
+       }
+
+       ath_debug_stat_retries(sc, tx_rate, xretries, retries,
+                              ath_rc_priv->state[tx_rate].per);
+
+#undef CHK_RSSI
+}
+
+static int ath_rc_get_rateindex(const struct ath_rate_table *rate_table,
+                               struct ieee80211_tx_rate *rate)
+{
+       int rix;
+
+       if ((rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) &&
+           (rate->flags & IEEE80211_TX_RC_SHORT_GI))
+               rix = rate_table->info[rate->idx].ht_index;
+       else if (rate->flags & IEEE80211_TX_RC_SHORT_GI)
+               rix = rate_table->info[rate->idx].sgi_index;
+       else if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
+               rix = rate_table->info[rate->idx].cw40index;
+       else
+               rix = rate_table->info[rate->idx].base_index;
+
+       return rix;
+}
+
+static void ath_rc_tx_status(struct ath_softc *sc,
+                            struct ath_rate_priv *ath_rc_priv,
+                            struct ieee80211_tx_info *tx_info,
+                            int final_ts_idx, int xretries, int long_retry)
+{
+       struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
+       const struct ath_rate_table *rate_table;
+       struct ieee80211_tx_rate *rates = tx_info->status.rates;
+       u8 flags;
+       u32 i = 0, rix;
+
+       rate_table = sc->cur_rate_table;
+
+       /*
+        * If the first rate is not the final index, there
+        * are intermediate rate failures to be processed.
+        */
+       if (final_ts_idx != 0) {
+               /* Process intermediate rates that failed.*/
+               for (i = 0; i < final_ts_idx ; i++) {
+                       if (rates[i].count != 0 && (rates[i].idx >= 0)) {
+                               flags = rates[i].flags;
+
+                               /* If HT40 and we have switched mode from
+                                * 40 to 20 => don't update */
+
+                               if ((flags & IEEE80211_TX_RC_40_MHZ_WIDTH) &&
+                                   !(ath_rc_priv->ht_cap & WLAN_RC_40_FLAG))
+                                       return;
+
+                               rix = ath_rc_get_rateindex(rate_table, &rates[i]);
+                               ath_rc_update_ht(sc, ath_rc_priv,
+                                               tx_info_priv, rix,
+                                               xretries ? 1 : 2,
+                                               rates[i].count);
+                       }
+               }
+       } else {
+               /*
+                * Handle the special case of MIMO PS burst, where the second
+                * aggregate is sent out with only one rate and one try.
+                * Treating it as an excessive retry penalizes the rate
+                * inordinately.
+                */
+               if (rates[0].count == 1 && xretries == 1)
+                       xretries = 2;
+       }
+
+       flags = rates[i].flags;
+
+       /* If HT40 and we have switched mode from 40 to 20 => don't update */
+       if ((flags & IEEE80211_TX_RC_40_MHZ_WIDTH) &&
+           !(ath_rc_priv->ht_cap & WLAN_RC_40_FLAG))
+               return;
+
+       rix = ath_rc_get_rateindex(rate_table, &rates[i]);
+       ath_rc_update_ht(sc, ath_rc_priv, tx_info_priv, rix,
+                        xretries, long_retry);
+}
+
+static const
+struct ath_rate_table *ath_choose_rate_table(struct ath_softc *sc,
+                                            enum ieee80211_band band,
+                                            bool is_ht,
+                                            bool is_cw_40)
+{
+       int mode = 0;
+
+       switch(band) {
+       case IEEE80211_BAND_2GHZ:
+               mode = ATH9K_MODE_11G;
+               if (is_ht)
+                       mode = ATH9K_MODE_11NG_HT20;
+               if (is_cw_40)
+                       mode = ATH9K_MODE_11NG_HT40PLUS;
+               break;
+       case IEEE80211_BAND_5GHZ:
+               mode = ATH9K_MODE_11A;
+               if (is_ht)
+                       mode = ATH9K_MODE_11NA_HT20;
+               if (is_cw_40)
+                       mode = ATH9K_MODE_11NA_HT40PLUS;
+               break;
+       default:
+               DPRINTF(sc, ATH_DBG_CONFIG, "Invalid band\n");
+               return NULL;
+       }
+
+       BUG_ON(mode >= ATH9K_MODE_MAX);
+
+       DPRINTF(sc, ATH_DBG_CONFIG, "Choosing rate table for mode: %d\n", mode);
+       return sc->hw_rate_table[mode];
+}
+
+static void ath_rc_init(struct ath_softc *sc,
+                       struct ath_rate_priv *ath_rc_priv,
+                       struct ieee80211_supported_band *sband,
+                       struct ieee80211_sta *sta,
+                       const struct ath_rate_table *rate_table)
+{
+       struct ath_rateset *rateset = &ath_rc_priv->neg_rates;
+       u8 *ht_mcs = (u8 *)&ath_rc_priv->neg_ht_rates;
+       u8 i, j, k, hi = 0, hthi = 0;
+
+       if (!rate_table) {
+               DPRINTF(sc, ATH_DBG_FATAL, "Rate table not initialized\n");
+               return;
+       }
+
+       /* Initial rate table size. Will change depending
+        * on the working rate set */
+       ath_rc_priv->rate_table_size = RATE_TABLE_SIZE;
+
+       /* Initialize thresholds according to the global rate table */
+       for (i = 0 ; i < ath_rc_priv->rate_table_size; i++) {
+               ath_rc_priv->state[i].rssi_thres =
+                       rate_table->info[i].rssi_ack_validmin;
+               ath_rc_priv->state[i].per = 0;
+       }
+
+       /* Determine the valid rates */
+       ath_rc_init_valid_txmask(ath_rc_priv);
+
+       for (i = 0; i < WLAN_RC_PHY_MAX; i++) {
+               for (j = 0; j < MAX_TX_RATE_PHY; j++)
+                       ath_rc_priv->valid_phy_rateidx[i][j] = 0;
+               ath_rc_priv->valid_phy_ratecnt[i] = 0;
+       }
+
+       if (!rateset->rs_nrates) {
+               /* No working rate, just initialize valid rates */
+               hi = ath_rc_init_validrates(ath_rc_priv, rate_table,
+                                           ath_rc_priv->ht_cap);
+       } else {
+               /* Use intersection of working rates and valid rates */
+               hi = ath_rc_setvalid_rates(ath_rc_priv, rate_table,
+                                          rateset, ath_rc_priv->ht_cap);
+               if (ath_rc_priv->ht_cap & WLAN_RC_HT_FLAG) {
+                       hthi = ath_rc_setvalid_htrates(ath_rc_priv,
+                                                      rate_table,
+                                                      ht_mcs,
+                                                      ath_rc_priv->ht_cap);
+               }
+               hi = A_MAX(hi, hthi);
+       }
+
+       ath_rc_priv->rate_table_size = hi + 1;
+       ath_rc_priv->rate_max_phy = 0;
+       ASSERT(ath_rc_priv->rate_table_size <= RATE_TABLE_SIZE);
+
+       for (i = 0, k = 0; i < WLAN_RC_PHY_MAX; i++) {
+               for (j = 0; j < ath_rc_priv->valid_phy_ratecnt[i]; j++) {
+                       ath_rc_priv->valid_rate_index[k++] =
+                               ath_rc_priv->valid_phy_rateidx[i][j];
+               }
+
+               if (!ath_rc_valid_phyrate(i, rate_table->initial_ratemax, 1)
+                   || !ath_rc_priv->valid_phy_ratecnt[i])
+                       continue;
+
+               ath_rc_priv->rate_max_phy = ath_rc_priv->valid_phy_rateidx[i][j-1];
+       }
+       ASSERT(ath_rc_priv->rate_table_size <= RATE_TABLE_SIZE);
+       ASSERT(k <= RATE_TABLE_SIZE);
+
+       ath_rc_priv->max_valid_rate = k;
+       ath_rc_sort_validrates(rate_table, ath_rc_priv);
+       ath_rc_priv->rate_max_phy = ath_rc_priv->valid_rate_index[k-4];
+       sc->cur_rate_table = rate_table;
+
+       DPRINTF(sc, ATH_DBG_CONFIG, "RC Initialized with capabilities: 0x%x\n",
+               ath_rc_priv->ht_cap);
+}
+
+static u8 ath_rc_build_ht_caps(struct ath_softc *sc, struct ieee80211_sta *sta,
+                              bool is_cw40, bool is_sgi40)
+{
+       u8 caps = 0;
+
+       if (sta->ht_cap.ht_supported) {
+               caps = WLAN_RC_HT_FLAG;
+               if (sc->sc_ah->caps.tx_chainmask != 1 &&
+                   ath9k_hw_getcapability(sc->sc_ah, ATH9K_CAP_DS, 0, NULL)) {
+                       if (sta->ht_cap.mcs.rx_mask[1])
+                               caps |= WLAN_RC_DS_FLAG;
+               }
+               if (is_cw40)
+                       caps |= WLAN_RC_40_FLAG;
+               if (is_sgi40)
+                       caps |= WLAN_RC_SGI_FLAG;
+       }
+
+       return caps;
+}
+
+/***********************************/
+/* mac80211 Rate Control callbacks */
+/***********************************/
+
+static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
+                         struct ieee80211_sta *sta, void *priv_sta,
+                         struct sk_buff *skb)
+{
+       struct ath_softc *sc = priv;
+       struct ath_rate_priv *ath_rc_priv = priv_sta;
+       struct ath_tx_info_priv *tx_info_priv = NULL;
+       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+       struct ieee80211_hdr *hdr;
+       int final_ts_idx, tx_status = 0, is_underrun = 0;
+       __le16 fc;
+
+       hdr = (struct ieee80211_hdr *)skb->data;
+       fc = hdr->frame_control;
+       tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
+       final_ts_idx = tx_info_priv->tx.ts_rateindex;
+
+       if (!priv_sta || !ieee80211_is_data(fc) ||
+           !tx_info_priv->update_rc)
+               goto exit;
+
+       if (tx_info_priv->tx.ts_status & ATH9K_TXERR_FILT)
+               goto exit;
+
+       /*
+        * If underrun error is seen assume it as an excessive retry only
+        * if prefetch trigger level have reached the max (0x3f for 5416)
+        * Adjust the long retry as if the frame was tried ATH_11N_TXMAXTRY
+        * times. This affects how ratectrl updates PER for the failed rate.
+        */
+       if (tx_info_priv->tx.ts_flags &
+           (ATH9K_TX_DATA_UNDERRUN | ATH9K_TX_DELIM_UNDERRUN) &&
+           ((sc->sc_ah->tx_trig_level) >= ath_rc_priv->tx_triglevel_max)) {
+               tx_status = 1;
+               is_underrun = 1;
+       }
+
+       if ((tx_info_priv->tx.ts_status & ATH9K_TXERR_XRETRY) ||
+           (tx_info_priv->tx.ts_status & ATH9K_TXERR_FIFO))
+               tx_status = 1;
+
+       ath_rc_tx_status(sc, ath_rc_priv, tx_info, final_ts_idx, tx_status,
+                        (is_underrun) ? ATH_11N_TXMAXTRY :
+                        tx_info_priv->tx.ts_longretry);
+
+       /* Check if aggregation has to be enabled for this tid */
+       if (conf_is_ht(&sc->hw->conf) &&
+           !(skb->protocol == cpu_to_be16(ETH_P_PAE))) {
+               if (ieee80211_is_data_qos(fc)) {
+                       u8 *qc, tid;
+                       struct ath_node *an;
+
+                       qc = ieee80211_get_qos_ctl(hdr);
+                       tid = qc[0] & 0xf;
+                       an = (struct ath_node *)sta->drv_priv;
+
+                       if(ath_tx_aggr_check(sc, an, tid))
+                               ieee80211_start_tx_ba_session(sc->hw, hdr->addr1, tid);
+               }
+       }
+
+       ath_debug_stat_rc(sc, skb);
+exit:
+       kfree(tx_info_priv);
+}
+
+static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
+                        struct ieee80211_tx_rate_control *txrc)
+{
+       struct ieee80211_supported_band *sband = txrc->sband;
+       struct sk_buff *skb = txrc->skb;
+       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+       struct ath_softc *sc = priv;
+       struct ath_rate_priv *ath_rc_priv = priv_sta;
+       __le16 fc = hdr->frame_control;
+
+       /* lowest rate for management and NO_ACK frames */
+       if (!ieee80211_is_data(fc) ||
+           tx_info->flags & IEEE80211_TX_CTL_NO_ACK || !sta) {
+               tx_info->control.rates[0].idx = rate_lowest_index(sband, sta);
+               tx_info->control.rates[0].count =
+                       (tx_info->flags & IEEE80211_TX_CTL_NO_ACK) ?
+                               1 : ATH_MGT_TXMAXTRY;
+               return;
+       }
+
+       /* Find tx rate for unicast frames */
+       ath_rc_ratefind(sc, ath_rc_priv, txrc);
+}
+
+static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband,
+                          struct ieee80211_sta *sta, void *priv_sta)
+{
+       struct ath_softc *sc = priv;
+       struct ath_rate_priv *ath_rc_priv = priv_sta;
+       const struct ath_rate_table *rate_table = NULL;
+       bool is_cw40, is_sgi40;
+       int i, j = 0;
+
+       for (i = 0; i < sband->n_bitrates; i++) {
+               if (sta->supp_rates[sband->band] & BIT(i)) {
+                       ath_rc_priv->neg_rates.rs_rates[j]
+                               = (sband->bitrates[i].bitrate * 2) / 10;
+                       j++;
+               }
+       }
+       ath_rc_priv->neg_rates.rs_nrates = j;
+
+       if (sta->ht_cap.ht_supported) {
+               for (i = 0, j = 0; i < 77; i++) {
+                       if (sta->ht_cap.mcs.rx_mask[i/8] & (1<<(i%8)))
+                               ath_rc_priv->neg_ht_rates.rs_rates[j++] = i;
+                       if (j == ATH_RATE_MAX)
+                               break;
+               }
+               ath_rc_priv->neg_ht_rates.rs_nrates = j;
+       }
+
+       is_cw40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40;
+       is_sgi40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40;
+
+       /* Choose rate table first */
+
+       if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) ||
+           (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT) ||
+           (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC)) {
+               rate_table = ath_choose_rate_table(sc, sband->band,
+                                                  sta->ht_cap.ht_supported,
+                                                  is_cw40);
+       } else if (sc->sc_ah->opmode == NL80211_IFTYPE_AP) {
+               /* cur_rate_table would be set on init through config() */
+               rate_table = sc->cur_rate_table;
+       }
+
+       ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc, sta, is_cw40, is_sgi40);
+       ath_rc_init(sc, priv_sta, sband, sta, rate_table);
+}
+
+static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband,
+                           struct ieee80211_sta *sta, void *priv_sta,
+                           u32 changed)
+{
+       struct ath_softc *sc = priv;
+       struct ath_rate_priv *ath_rc_priv = priv_sta;
+       const struct ath_rate_table *rate_table = NULL;
+       bool oper_cw40 = false, oper_sgi40;
+       bool local_cw40 = (ath_rc_priv->ht_cap & WLAN_RC_40_FLAG) ?
+               true : false;
+       bool local_sgi40 = (ath_rc_priv->ht_cap & WLAN_RC_SGI_FLAG) ?
+               true : false;
+
+       /* FIXME: Handle AP mode later when we support CWM */
+
+       if (changed & IEEE80211_RC_HT_CHANGED) {
+               if (sc->sc_ah->opmode != NL80211_IFTYPE_STATION)
+                       return;
+
+               if (sc->hw->conf.channel_type == NL80211_CHAN_HT40MINUS ||
+                   sc->hw->conf.channel_type == NL80211_CHAN_HT40PLUS)
+                       oper_cw40 = true;
+
+               oper_sgi40 = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
+                       true : false;
+
+               if ((local_cw40 != oper_cw40) || (local_sgi40 != oper_sgi40)) {
+                       rate_table = ath_choose_rate_table(sc, sband->band,
+                                                  sta->ht_cap.ht_supported,
+                                                  oper_cw40);
+                       ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc, sta,
+                                                  oper_cw40, oper_sgi40);
+                       ath_rc_init(sc, priv_sta, sband, sta, rate_table);
+
+                       DPRINTF(sc, ATH_DBG_CONFIG,
+                               "Operating HT Bandwidth changed to: %d\n",
+                               sc->hw->conf.channel_type);
+               }
+       }
+}
+
+static void *ath_rate_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
+{
+       struct ath_wiphy *aphy = hw->priv;
+       return aphy->sc;
+}
+
+static void ath_rate_free(void *priv)
+{
+       return;
+}
+
+static void *ath_rate_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp)
+{
+       struct ath_softc *sc = priv;
+       struct ath_rate_priv *rate_priv;
+
+       rate_priv = kzalloc(sizeof(struct ath_rate_priv), gfp);
+       if (!rate_priv) {
+               DPRINTF(sc, ATH_DBG_FATAL,
+                       "Unable to allocate private rc structure\n");
+               return NULL;
+       }
+
+       rate_priv->rssi_down_time = jiffies_to_msecs(jiffies);
+       rate_priv->tx_triglevel_max = sc->sc_ah->caps.tx_triglevel_max;
+
+       return rate_priv;
+}
+
+static void ath_rate_free_sta(void *priv, struct ieee80211_sta *sta,
+                             void *priv_sta)
+{
+       struct ath_rate_priv *rate_priv = priv_sta;
+       kfree(rate_priv);
+}
+
+static struct rate_control_ops ath_rate_ops = {
+       .module = NULL,
+       .name = "ath9k_rate_control",
+       .tx_status = ath_tx_status,
+       .get_rate = ath_get_rate,
+       .rate_init = ath_rate_init,
+       .rate_update = ath_rate_update,
+       .alloc = ath_rate_alloc,
+       .free = ath_rate_free,
+       .alloc_sta = ath_rate_alloc_sta,
+       .free_sta = ath_rate_free_sta,
+};
+
+void ath_rate_attach(struct ath_softc *sc)
+{
+       sc->hw_rate_table[ATH9K_MODE_11B] =
+               &ar5416_11b_ratetable;
+       sc->hw_rate_table[ATH9K_MODE_11A] =
+               &ar5416_11a_ratetable;
+       sc->hw_rate_table[ATH9K_MODE_11G] =
+               &ar5416_11g_ratetable;
+       sc->hw_rate_table[ATH9K_MODE_11NA_HT20] =
+               &ar5416_11na_ratetable;
+       sc->hw_rate_table[ATH9K_MODE_11NG_HT20] =
+               &ar5416_11ng_ratetable;
+       sc->hw_rate_table[ATH9K_MODE_11NA_HT40PLUS] =
+               &ar5416_11na_ratetable;
+       sc->hw_rate_table[ATH9K_MODE_11NA_HT40MINUS] =
+               &ar5416_11na_ratetable;
+       sc->hw_rate_table[ATH9K_MODE_11NG_HT40PLUS] =
+               &ar5416_11ng_ratetable;
+       sc->hw_rate_table[ATH9K_MODE_11NG_HT40MINUS] =
+               &ar5416_11ng_ratetable;
+}
+
+int ath_rate_control_register(void)
+{
+       return ieee80211_rate_control_register(&ath_rate_ops);
+}
+
+void ath_rate_control_unregister(void)
+{
+       ieee80211_rate_control_unregister(&ath_rate_ops);
+}
diff --git a/drivers/net/wireless/ath/ath9k/rc.h b/drivers/net/wireless/ath/ath9k/rc.h
new file mode 100644 (file)
index 0000000..e3abd76
--- /dev/null
@@ -0,0 +1,216 @@
+/*
+ * Copyright (c) 2004 Sam Leffler, Errno Consulting
+ * Copyright (c) 2004 Video54 Technologies, Inc.
+ * Copyright (c) 2008-2009 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 RC_H
+#define RC_H
+
+struct ath_softc;
+
+#define ATH_RATE_MAX     30
+#define RATE_TABLE_SIZE  64
+#define MAX_TX_RATE_PHY  48
+
+/* VALID_ALL - valid for 20/40/Legacy,
+ * VALID - Legacy only,
+ * VALID_20 - HT 20 only,
+ * VALID_40 - HT 40 only */
+
+#define INVALID    0x0
+#define VALID      0x1
+#define VALID_20   0x2
+#define VALID_40   0x4
+#define VALID_2040 (VALID_20|VALID_40)
+#define VALID_ALL  (VALID_2040|VALID)
+
+enum {
+       WLAN_RC_PHY_OFDM,
+       WLAN_RC_PHY_CCK,
+       WLAN_RC_PHY_HT_20_SS,
+       WLAN_RC_PHY_HT_20_DS,
+       WLAN_RC_PHY_HT_40_SS,
+       WLAN_RC_PHY_HT_40_DS,
+       WLAN_RC_PHY_HT_20_SS_HGI,
+       WLAN_RC_PHY_HT_20_DS_HGI,
+       WLAN_RC_PHY_HT_40_SS_HGI,
+       WLAN_RC_PHY_HT_40_DS_HGI,
+       WLAN_RC_PHY_MAX
+};
+
+#define WLAN_RC_PHY_DS(_phy)   ((_phy == WLAN_RC_PHY_HT_20_DS)         \
+                               || (_phy == WLAN_RC_PHY_HT_40_DS)       \
+                               || (_phy == WLAN_RC_PHY_HT_20_DS_HGI)   \
+                               || (_phy == WLAN_RC_PHY_HT_40_DS_HGI))
+#define WLAN_RC_PHY_40(_phy)   ((_phy == WLAN_RC_PHY_HT_40_SS)         \
+                               || (_phy == WLAN_RC_PHY_HT_40_DS)       \
+                               || (_phy == WLAN_RC_PHY_HT_40_SS_HGI)   \
+                               || (_phy == WLAN_RC_PHY_HT_40_DS_HGI))
+#define WLAN_RC_PHY_SGI(_phy)  ((_phy == WLAN_RC_PHY_HT_20_SS_HGI)      \
+                               || (_phy == WLAN_RC_PHY_HT_20_DS_HGI)   \
+                               || (_phy == WLAN_RC_PHY_HT_40_SS_HGI)   \
+                               || (_phy == WLAN_RC_PHY_HT_40_DS_HGI))
+
+#define WLAN_RC_PHY_HT(_phy)    (_phy >= WLAN_RC_PHY_HT_20_SS)
+
+#define WLAN_RC_CAP_MODE(capflag) (((capflag & WLAN_RC_HT_FLAG) ?      \
+               (capflag & WLAN_RC_40_FLAG) ? VALID_40 : VALID_20 : VALID))
+
+/* Return TRUE if flag supports HT20 && client supports HT20 or
+ * return TRUE if flag supports HT40 && client supports HT40.
+ * This is used becos some rates overlap between HT20/HT40.
+ */
+#define WLAN_RC_PHY_HT_VALID(flag, capflag)                    \
+       (((flag & VALID_20) && !(capflag & WLAN_RC_40_FLAG)) || \
+        ((flag & VALID_40) && (capflag & WLAN_RC_40_FLAG)))
+
+#define WLAN_RC_DS_FLAG         (0x01)
+#define WLAN_RC_40_FLAG         (0x02)
+#define WLAN_RC_SGI_FLAG        (0x04)
+#define WLAN_RC_HT_FLAG         (0x08)
+
+/**
+ * struct ath_rate_table - Rate Control table
+ * @valid: valid for use in rate control
+ * @valid_single_stream: valid for use in rate control for
+ *     single stream operation
+ * @phy: CCK/OFDM
+ * @ratekbps: rate in Kbits per second
+ * @user_ratekbps: user rate in Kbits per second
+ * @ratecode: rate that goes into HW descriptors
+ * @short_preamble: Mask for enabling short preamble in ratecode for CCK
+ * @dot11rate: value that goes into supported
+ *     rates info element of MLME
+ * @ctrl_rate: Index of next lower basic rate, used for duration computation
+ * @max_4ms_framelen: maximum frame length(bytes) for tx duration
+ * @probe_interval: interval for rate control to probe for other rates
+ * @rssi_reduce_interval: interval for rate control to reduce rssi
+ * @initial_ratemax: initial ratemax value
+ */
+struct ath_rate_table {
+       int rate_cnt;
+       struct {
+               int valid;
+               int valid_single_stream;
+               u8 phy;
+               u32 ratekbps;
+               u32 user_ratekbps;
+               u8 ratecode;
+               u8 short_preamble;
+               u8 dot11rate;
+               u8 ctrl_rate;
+               int8_t rssi_ack_validmin;
+               int8_t rssi_ack_deltamin;
+               u8 base_index;
+               u8 cw40index;
+               u8 sgi_index;
+               u8 ht_index;
+               u32 max_4ms_framelen;
+       } info[RATE_TABLE_SIZE];
+       u32 probe_interval;
+       u32 rssi_reduce_interval;
+       u8 initial_ratemax;
+};
+
+struct ath_tx_ratectrl_state {
+       int8_t rssi_thres;      /* required rssi for this rate (dB) */
+       u8 per;                 /* recent estimate of packet error rate (%) */
+};
+
+struct ath_rateset {
+       u8 rs_nrates;
+       u8 rs_rates[ATH_RATE_MAX];
+};
+
+/**
+ * struct ath_rate_priv - Rate Control priv data
+ * @state: RC state
+ * @rssi_last: last ACK rssi
+ * @rssi_last_lookup: last ACK rssi used for lookup
+ * @rssi_last_prev: previous last ACK rssi
+ * @rssi_last_prev2: 2nd previous last ACK rssi
+ * @rssi_sum_cnt: count of rssi_sum for averaging
+ * @rssi_sum_rate: rate that we are averaging
+ * @rssi_sum: running sum of rssi for averaging
+ * @probe_rate: rate we are probing at
+ * @rssi_time: msec timestamp for last ack rssi
+ * @rssi_down_time: msec timestamp for last down step
+ * @probe_time: msec timestamp for last probe
+ * @hw_maxretry_pktcnt: num of packets since we got HW max retry error
+ * @max_valid_rate: maximum number of valid rate
+ * @per_down_time: msec timestamp for last PER down step
+ * @valid_phy_ratecnt: valid rate count
+ * @rate_max_phy: phy index for the max rate
+ * @probe_interval: interval for ratectrl to probe for other rates
+ * @prev_data_rix: rate idx of last data frame
+ * @ht_cap: HT capabilities
+ * @neg_rates: Negotatied rates
+ * @neg_ht_rates: Negotiated HT rates
+ */
+struct ath_rate_priv {
+       int8_t rssi_last;
+       int8_t rssi_last_lookup;
+       int8_t rssi_last_prev;
+       int8_t rssi_last_prev2;
+       int32_t rssi_sum_cnt;
+       int32_t rssi_sum_rate;
+       int32_t rssi_sum;
+       u8 rate_table_size;
+       u8 probe_rate;
+       u8 hw_maxretry_pktcnt;
+       u8 max_valid_rate;
+       u8 valid_rate_index[RATE_TABLE_SIZE];
+       u8 ht_cap;
+       u8 valid_phy_ratecnt[WLAN_RC_PHY_MAX];
+       u8 valid_phy_rateidx[WLAN_RC_PHY_MAX][RATE_TABLE_SIZE];
+       u8 rate_max_phy;
+       u32 rssi_time;
+       u32 rssi_down_time;
+       u32 probe_time;
+       u32 per_down_time;
+       u32 probe_interval;
+       u32 prev_data_rix;
+       u32 tx_triglevel_max;
+       struct ath_tx_ratectrl_state state[RATE_TABLE_SIZE];
+       struct ath_rateset neg_rates;
+       struct ath_rateset neg_ht_rates;
+       struct ath_rate_softc *asc;
+};
+
+enum ath9k_internal_frame_type {
+       ATH9K_NOT_INTERNAL,
+       ATH9K_INT_PAUSE,
+       ATH9K_INT_UNPAUSE
+};
+
+struct ath_tx_info_priv {
+       struct ath_wiphy *aphy;
+       struct ath_tx_status tx;
+       int n_frames;
+       int n_bad_frames;
+       bool update_rc;
+       enum ath9k_internal_frame_type frame_type;
+};
+
+#define ATH_TX_INFO_PRIV(tx_info) \
+       ((struct ath_tx_info_priv *)((tx_info)->rate_driver_data[0]))
+
+void ath_rate_attach(struct ath_softc *sc);
+u8 ath_rate_findrateix(struct ath_softc *sc, u8 dot11_rate);
+int ath_rate_control_register(void);
+void ath_rate_control_unregister(void);
+
+#endif /* RC_H */
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
new file mode 100644 (file)
index 0000000..5014a19
--- /dev/null
@@ -0,0 +1,834 @@
+/*
+ * Copyright (c) 2008-2009 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 "ath9k.h"
+
+static struct ieee80211_hw * ath_get_virt_hw(struct ath_softc *sc,
+                                            struct ieee80211_hdr *hdr)
+{
+       struct ieee80211_hw *hw = sc->pri_wiphy->hw;
+       int i;
+
+       spin_lock_bh(&sc->wiphy_lock);
+       for (i = 0; i < sc->num_sec_wiphy; i++) {
+               struct ath_wiphy *aphy = sc->sec_wiphy[i];
+               if (aphy == NULL)
+                       continue;
+               if (compare_ether_addr(hdr->addr1, aphy->hw->wiphy->perm_addr)
+                   == 0) {
+                       hw = aphy->hw;
+                       break;
+               }
+       }
+       spin_unlock_bh(&sc->wiphy_lock);
+       return hw;
+}
+
+/*
+ * Setup and link descriptors.
+ *
+ * 11N: we can no longer afford to self link the last descriptor.
+ * MAC acknowledges BA status as long as it copies frames to host
+ * buffer (or rx fifo). This can incorrectly acknowledge packets
+ * to a sender if last desc is self-linked.
+ */
+static void ath_rx_buf_link(struct ath_softc *sc, struct ath_buf *bf)
+{
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath_desc *ds;
+       struct sk_buff *skb;
+
+       ATH_RXBUF_RESET(bf);
+
+       ds = bf->bf_desc;
+       ds->ds_link = 0; /* link to null */
+       ds->ds_data = bf->bf_buf_addr;
+
+       /* virtual addr of the beginning of the buffer. */
+       skb = bf->bf_mpdu;
+       ASSERT(skb != NULL);
+       ds->ds_vdata = skb->data;
+
+       /* setup rx descriptors. The rx.bufsize here tells the harware
+        * how much data it can DMA to us and that we are prepared
+        * to process */
+       ath9k_hw_setuprxdesc(ah, ds,
+                            sc->rx.bufsize,
+                            0);
+
+       if (sc->rx.rxlink == NULL)
+               ath9k_hw_putrxbuf(ah, bf->bf_daddr);
+       else
+               *sc->rx.rxlink = bf->bf_daddr;
+
+       sc->rx.rxlink = &ds->ds_link;
+       ath9k_hw_rxena(ah);
+}
+
+static void ath_setdefantenna(struct ath_softc *sc, u32 antenna)
+{
+       /* XXX block beacon interrupts */
+       ath9k_hw_setantenna(sc->sc_ah, antenna);
+       sc->rx.defant = antenna;
+       sc->rx.rxotherant = 0;
+}
+
+/*
+ *  Extend 15-bit time stamp from rx descriptor to
+ *  a full 64-bit TSF using the current h/w TSF.
+*/
+static u64 ath_extend_tsf(struct ath_softc *sc, u32 rstamp)
+{
+       u64 tsf;
+
+       tsf = ath9k_hw_gettsf64(sc->sc_ah);
+       if ((tsf & 0x7fff) < rstamp)
+               tsf -= 0x8000;
+       return (tsf & ~0x7fff) | rstamp;
+}
+
+static struct sk_buff *ath_rxbuf_alloc(struct ath_softc *sc, u32 len, gfp_t gfp_mask)
+{
+       struct sk_buff *skb;
+       u32 off;
+
+       /*
+        * Cache-line-align.  This is important (for the
+        * 5210 at least) as not doing so causes bogus data
+        * in rx'd frames.
+        */
+
+       /* Note: the kernel can allocate a value greater than
+        * what we ask it to give us. We really only need 4 KB as that
+        * is this hardware supports and in fact we need at least 3849
+        * as that is the MAX AMSDU size this hardware supports.
+        * Unfortunately this means we may get 8 KB here from the
+        * kernel... and that is actually what is observed on some
+        * systems :( */
+       skb = __dev_alloc_skb(len + sc->cachelsz - 1, gfp_mask);
+       if (skb != NULL) {
+               off = ((unsigned long) skb->data) % sc->cachelsz;
+               if (off != 0)
+                       skb_reserve(skb, sc->cachelsz - off);
+       } else {
+               DPRINTF(sc, ATH_DBG_FATAL,
+                       "skbuff alloc of size %u failed\n", len);
+               return NULL;
+       }
+
+       return skb;
+}
+
+/*
+ * For Decrypt or Demic errors, we only mark packet status here and always push
+ * up the frame up to let mac80211 handle the actual error case, be it no
+ * decryption key or real decryption error. This let us keep statistics there.
+ */
+static int ath_rx_prepare(struct sk_buff *skb, struct ath_desc *ds,
+                         struct ieee80211_rx_status *rx_status, bool *decrypt_error,
+                         struct ath_softc *sc)
+{
+       struct ieee80211_hdr *hdr;
+       u8 ratecode;
+       __le16 fc;
+       struct ieee80211_hw *hw;
+
+       hdr = (struct ieee80211_hdr *)skb->data;
+       fc = hdr->frame_control;
+       memset(rx_status, 0, sizeof(struct ieee80211_rx_status));
+       hw = ath_get_virt_hw(sc, hdr);
+
+       if (ds->ds_rxstat.rs_more) {
+               /*
+                * Frame spans multiple descriptors; this cannot happen yet
+                * as we don't support jumbograms. If not in monitor mode,
+                * discard the frame. Enable this if you want to see
+                * error frames in Monitor mode.
+                */
+               if (sc->sc_ah->opmode != NL80211_IFTYPE_MONITOR)
+                       goto rx_next;
+       } else if (ds->ds_rxstat.rs_status != 0) {
+               if (ds->ds_rxstat.rs_status & ATH9K_RXERR_CRC)
+                       rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
+               if (ds->ds_rxstat.rs_status & ATH9K_RXERR_PHY)
+                       goto rx_next;
+
+               if (ds->ds_rxstat.rs_status & ATH9K_RXERR_DECRYPT) {
+                       *decrypt_error = true;
+               } else if (ds->ds_rxstat.rs_status & ATH9K_RXERR_MIC) {
+                       if (ieee80211_is_ctl(fc))
+                               /*
+                                * Sometimes, we get invalid
+                                * MIC failures on valid control frames.
+                                * Remove these mic errors.
+                                */
+                               ds->ds_rxstat.rs_status &= ~ATH9K_RXERR_MIC;
+                       else
+                               rx_status->flag |= RX_FLAG_MMIC_ERROR;
+               }
+               /*
+                * Reject error frames with the exception of
+                * decryption and MIC failures. For monitor mode,
+                * we also ignore the CRC error.
+                */
+               if (sc->sc_ah->opmode == NL80211_IFTYPE_MONITOR) {
+                       if (ds->ds_rxstat.rs_status &
+                           ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC |
+                             ATH9K_RXERR_CRC))
+                               goto rx_next;
+               } else {
+                       if (ds->ds_rxstat.rs_status &
+                           ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC)) {
+                               goto rx_next;
+                       }
+               }
+       }
+
+       ratecode = ds->ds_rxstat.rs_rate;
+
+       if (ratecode & 0x80) {
+               /* HT rate */
+               rx_status->flag |= RX_FLAG_HT;
+               if (ds->ds_rxstat.rs_flags & ATH9K_RX_2040)
+                       rx_status->flag |= RX_FLAG_40MHZ;
+               if (ds->ds_rxstat.rs_flags & ATH9K_RX_GI)
+                       rx_status->flag |= RX_FLAG_SHORT_GI;
+               rx_status->rate_idx = ratecode & 0x7f;
+       } else {
+               int i = 0, cur_band, n_rates;
+
+               cur_band = hw->conf.channel->band;
+               n_rates = sc->sbands[cur_band].n_bitrates;
+
+               for (i = 0; i < n_rates; i++) {
+                       if (sc->sbands[cur_band].bitrates[i].hw_value ==
+                           ratecode) {
+                               rx_status->rate_idx = i;
+                               break;
+                       }
+
+                       if (sc->sbands[cur_band].bitrates[i].hw_value_short ==
+                           ratecode) {
+                               rx_status->rate_idx = i;
+                               rx_status->flag |= RX_FLAG_SHORTPRE;
+                               break;
+                       }
+               }
+       }
+
+       rx_status->mactime = ath_extend_tsf(sc, ds->ds_rxstat.rs_tstamp);
+       rx_status->band = hw->conf.channel->band;
+       rx_status->freq = hw->conf.channel->center_freq;
+       rx_status->noise = sc->ani.noise_floor;
+       rx_status->signal = rx_status->noise + ds->ds_rxstat.rs_rssi;
+       rx_status->antenna = ds->ds_rxstat.rs_antenna;
+
+       /* at 45 you will be able to use MCS 15 reliably. A more elaborate
+        * scheme can be used here but it requires tables of SNR/throughput for
+        * each possible mode used. */
+       rx_status->qual =  ds->ds_rxstat.rs_rssi * 100 / 45;
+
+       /* rssi can be more than 45 though, anything above that
+        * should be considered at 100% */
+       if (rx_status->qual > 100)
+               rx_status->qual = 100;
+
+       rx_status->flag |= RX_FLAG_TSFT;
+
+       return 1;
+rx_next:
+       return 0;
+}
+
+static void ath_opmode_init(struct ath_softc *sc)
+{
+       struct ath_hw *ah = sc->sc_ah;
+       u32 rfilt, mfilt[2];
+
+       /* configure rx filter */
+       rfilt = ath_calcrxfilter(sc);
+       ath9k_hw_setrxfilter(ah, rfilt);
+
+       /* configure bssid mask */
+       if (ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK)
+               ath9k_hw_setbssidmask(sc);
+
+       /* configure operational mode */
+       ath9k_hw_setopmode(ah);
+
+       /* Handle any link-level address change. */
+       ath9k_hw_setmac(ah, sc->sc_ah->macaddr);
+
+       /* calculate and install multicast filter */
+       mfilt[0] = mfilt[1] = ~0;
+       ath9k_hw_setmcastfilter(ah, mfilt[0], mfilt[1]);
+}
+
+int ath_rx_init(struct ath_softc *sc, int nbufs)
+{
+       struct sk_buff *skb;
+       struct ath_buf *bf;
+       int error = 0;
+
+       spin_lock_init(&sc->rx.rxflushlock);
+       sc->sc_flags &= ~SC_OP_RXFLUSH;
+       spin_lock_init(&sc->rx.rxbuflock);
+
+       sc->rx.bufsize = roundup(IEEE80211_MAX_MPDU_LEN,
+                                min(sc->cachelsz, (u16)64));
+
+       DPRINTF(sc, ATH_DBG_CONFIG, "cachelsz %u rxbufsize %u\n",
+               sc->cachelsz, sc->rx.bufsize);
+
+       /* Initialize rx descriptors */
+
+       error = ath_descdma_setup(sc, &sc->rx.rxdma, &sc->rx.rxbuf,
+                                 "rx", nbufs, 1);
+       if (error != 0) {
+               DPRINTF(sc, ATH_DBG_FATAL,
+                       "failed to allocate rx descriptors: %d\n", error);
+               goto err;
+       }
+
+       list_for_each_entry(bf, &sc->rx.rxbuf, list) {
+               skb = ath_rxbuf_alloc(sc, sc->rx.bufsize, GFP_KERNEL);
+               if (skb == NULL) {
+                       error = -ENOMEM;
+                       goto err;
+               }
+
+               bf->bf_mpdu = skb;
+               bf->bf_buf_addr = dma_map_single(sc->dev, skb->data,
+                                                sc->rx.bufsize,
+                                                DMA_FROM_DEVICE);
+               if (unlikely(dma_mapping_error(sc->dev,
+                                              bf->bf_buf_addr))) {
+                       dev_kfree_skb_any(skb);
+                       bf->bf_mpdu = NULL;
+                       DPRINTF(sc, ATH_DBG_FATAL,
+                               "dma_mapping_error() on RX init\n");
+                       error = -ENOMEM;
+                       goto err;
+               }
+               bf->bf_dmacontext = bf->bf_buf_addr;
+       }
+       sc->rx.rxlink = NULL;
+
+err:
+       if (error)
+               ath_rx_cleanup(sc);
+
+       return error;
+}
+
+void ath_rx_cleanup(struct ath_softc *sc)
+{
+       struct sk_buff *skb;
+       struct ath_buf *bf;
+
+       list_for_each_entry(bf, &sc->rx.rxbuf, list) {
+               skb = bf->bf_mpdu;
+               if (skb) {
+                       dma_unmap_single(sc->dev, bf->bf_buf_addr,
+                                        sc->rx.bufsize, DMA_FROM_DEVICE);
+                       dev_kfree_skb(skb);
+               }
+       }
+
+       if (sc->rx.rxdma.dd_desc_len != 0)
+               ath_descdma_cleanup(sc, &sc->rx.rxdma, &sc->rx.rxbuf);
+}
+
+/*
+ * Calculate the receive filter according to the
+ * operating mode and state:
+ *
+ * o always accept unicast, broadcast, and multicast traffic
+ * o maintain current state of phy error reception (the hal
+ *   may enable phy error frames for noise immunity work)
+ * o probe request frames are accepted only when operating in
+ *   hostap, adhoc, or monitor modes
+ * o enable promiscuous mode according to the interface state
+ * o accept beacons:
+ *   - when operating in adhoc mode so the 802.11 layer creates
+ *     node table entries for peers,
+ *   - when operating in station mode for collecting rssi data when
+ *     the station is otherwise quiet, or
+ *   - when operating as a repeater so we see repeater-sta beacons
+ *   - when scanning
+ */
+
+u32 ath_calcrxfilter(struct ath_softc *sc)
+{
+#define        RX_FILTER_PRESERVE (ATH9K_RX_FILTER_PHYERR | ATH9K_RX_FILTER_PHYRADAR)
+
+       u32 rfilt;
+
+       rfilt = (ath9k_hw_getrxfilter(sc->sc_ah) & RX_FILTER_PRESERVE)
+               | ATH9K_RX_FILTER_UCAST | ATH9K_RX_FILTER_BCAST
+               | ATH9K_RX_FILTER_MCAST;
+
+       /* If not a STA, enable processing of Probe Requests */
+       if (sc->sc_ah->opmode != NL80211_IFTYPE_STATION)
+               rfilt |= ATH9K_RX_FILTER_PROBEREQ;
+
+       /*
+        * Set promiscuous mode when FIF_PROMISC_IN_BSS is enabled for station
+        * mode interface or when in monitor mode. AP mode does not need this
+        * since it receives all in-BSS frames anyway.
+        */
+       if (((sc->sc_ah->opmode != NL80211_IFTYPE_AP) &&
+            (sc->rx.rxfilter & FIF_PROMISC_IN_BSS)) ||
+           (sc->sc_ah->opmode == NL80211_IFTYPE_MONITOR))
+               rfilt |= ATH9K_RX_FILTER_PROM;
+
+       if (sc->rx.rxfilter & FIF_CONTROL)
+               rfilt |= ATH9K_RX_FILTER_CONTROL;
+
+       if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) &&
+           !(sc->rx.rxfilter & FIF_BCN_PRBRESP_PROMISC))
+               rfilt |= ATH9K_RX_FILTER_MYBEACON;
+       else
+               rfilt |= ATH9K_RX_FILTER_BEACON;
+
+       /* If in HOSTAP mode, want to enable reception of PSPOLL frames */
+       if (sc->sc_ah->opmode == NL80211_IFTYPE_AP)
+               rfilt |= ATH9K_RX_FILTER_PSPOLL;
+
+       if (sc->sec_wiphy) {
+               /* TODO: only needed if more than one BSSID is in use in
+                * station/adhoc mode */
+               /* TODO: for older chips, may need to add ATH9K_RX_FILTER_PROM
+                */
+               rfilt |= ATH9K_RX_FILTER_MCAST_BCAST_ALL;
+       }
+
+       return rfilt;
+
+#undef RX_FILTER_PRESERVE
+}
+
+int ath_startrecv(struct ath_softc *sc)
+{
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath_buf *bf, *tbf;
+
+       spin_lock_bh(&sc->rx.rxbuflock);
+       if (list_empty(&sc->rx.rxbuf))
+               goto start_recv;
+
+       sc->rx.rxlink = NULL;
+       list_for_each_entry_safe(bf, tbf, &sc->rx.rxbuf, list) {
+               ath_rx_buf_link(sc, bf);
+       }
+
+       /* We could have deleted elements so the list may be empty now */
+       if (list_empty(&sc->rx.rxbuf))
+               goto start_recv;
+
+       bf = list_first_entry(&sc->rx.rxbuf, struct ath_buf, list);
+       ath9k_hw_putrxbuf(ah, bf->bf_daddr);
+       ath9k_hw_rxena(ah);
+
+start_recv:
+       spin_unlock_bh(&sc->rx.rxbuflock);
+       ath_opmode_init(sc);
+       ath9k_hw_startpcureceive(ah);
+
+       return 0;
+}
+
+bool ath_stoprecv(struct ath_softc *sc)
+{
+       struct ath_hw *ah = sc->sc_ah;
+       bool stopped;
+
+       ath9k_hw_stoppcurecv(ah);
+       ath9k_hw_setrxfilter(ah, 0);
+       stopped = ath9k_hw_stopdmarecv(ah);
+       sc->rx.rxlink = NULL;
+
+       return stopped;
+}
+
+void ath_flushrecv(struct ath_softc *sc)
+{
+       spin_lock_bh(&sc->rx.rxflushlock);
+       sc->sc_flags |= SC_OP_RXFLUSH;
+       ath_rx_tasklet(sc, 1);
+       sc->sc_flags &= ~SC_OP_RXFLUSH;
+       spin_unlock_bh(&sc->rx.rxflushlock);
+}
+
+static bool ath_beacon_dtim_pending_cab(struct sk_buff *skb)
+{
+       /* Check whether the Beacon frame has DTIM indicating buffered bc/mc */
+       struct ieee80211_mgmt *mgmt;
+       u8 *pos, *end, id, elen;
+       struct ieee80211_tim_ie *tim;
+
+       mgmt = (struct ieee80211_mgmt *)skb->data;
+       pos = mgmt->u.beacon.variable;
+       end = skb->data + skb->len;
+
+       while (pos + 2 < end) {
+               id = *pos++;
+               elen = *pos++;
+               if (pos + elen > end)
+                       break;
+
+               if (id == WLAN_EID_TIM) {
+                       if (elen < sizeof(*tim))
+                               break;
+                       tim = (struct ieee80211_tim_ie *) pos;
+                       if (tim->dtim_count != 0)
+                               break;
+                       return tim->bitmap_ctrl & 0x01;
+               }
+
+               pos += elen;
+       }
+
+       return false;
+}
+
+static void ath_rx_ps_back_to_sleep(struct ath_softc *sc)
+{
+       sc->sc_flags &= ~(SC_OP_WAIT_FOR_BEACON | SC_OP_WAIT_FOR_CAB);
+}
+
+static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb)
+{
+       struct ieee80211_mgmt *mgmt;
+
+       if (skb->len < 24 + 8 + 2 + 2)
+               return;
+
+       mgmt = (struct ieee80211_mgmt *)skb->data;
+       if (memcmp(sc->curbssid, mgmt->bssid, ETH_ALEN) != 0)
+               return; /* not from our current AP */
+
+       if (sc->sc_flags & SC_OP_BEACON_SYNC) {
+               sc->sc_flags &= ~SC_OP_BEACON_SYNC;
+               DPRINTF(sc, ATH_DBG_PS, "Reconfigure Beacon timers based on "
+                       "timestamp from the AP\n");
+               ath_beacon_config(sc, NULL);
+       }
+
+       if (!(sc->hw->conf.flags & IEEE80211_CONF_PS)) {
+               /* We are not in PS mode anymore; remain awake */
+               DPRINTF(sc, ATH_DBG_PS, "Not in PS mode anymore, remain "
+                       "awake\n");
+               sc->sc_flags &= ~(SC_OP_WAIT_FOR_BEACON | SC_OP_WAIT_FOR_CAB);
+               return;
+       }
+
+       if (ath_beacon_dtim_pending_cab(skb)) {
+               /*
+                * Remain awake waiting for buffered broadcast/multicast
+                * frames.
+                */
+               DPRINTF(sc, ATH_DBG_PS, "Received DTIM beacon indicating "
+                       "buffered broadcast/multicast frame(s)\n");
+               sc->sc_flags |= SC_OP_WAIT_FOR_CAB;
+               return;
+       }
+
+       if (sc->sc_flags & SC_OP_WAIT_FOR_CAB) {
+               /*
+                * This can happen if a broadcast frame is dropped or the AP
+                * fails to send a frame indicating that all CAB frames have
+                * been delivered.
+                */
+               DPRINTF(sc, ATH_DBG_PS, "PS wait for CAB frames timed out\n");
+       }
+
+       /* No more broadcast/multicast frames to be received at this point. */
+       ath_rx_ps_back_to_sleep(sc);
+}
+
+static void ath_rx_ps(struct ath_softc *sc, struct sk_buff *skb)
+{
+       struct ieee80211_hdr *hdr;
+
+       hdr = (struct ieee80211_hdr *)skb->data;
+
+       /* Process Beacon and CAB receive in PS state */
+       if ((sc->sc_flags & SC_OP_WAIT_FOR_BEACON) &&
+           ieee80211_is_beacon(hdr->frame_control))
+               ath_rx_ps_beacon(sc, skb);
+       else if ((sc->sc_flags & SC_OP_WAIT_FOR_CAB) &&
+                (ieee80211_is_data(hdr->frame_control) ||
+                 ieee80211_is_action(hdr->frame_control)) &&
+                is_multicast_ether_addr(hdr->addr1) &&
+                !ieee80211_has_moredata(hdr->frame_control)) {
+               DPRINTF(sc, ATH_DBG_PS, "All PS CAB frames received, back to "
+                       "sleep\n");
+               /*
+                * No more broadcast/multicast frames to be received at this
+                * point.
+                */
+               ath_rx_ps_back_to_sleep(sc);
+       } else if ((sc->sc_flags & SC_OP_WAIT_FOR_PSPOLL_DATA) &&
+                  !is_multicast_ether_addr(hdr->addr1) &&
+                  !ieee80211_has_morefrags(hdr->frame_control)) {
+               sc->sc_flags &= ~SC_OP_WAIT_FOR_PSPOLL_DATA;
+               DPRINTF(sc, ATH_DBG_PS, "Going back to sleep after having "
+                       "received PS-Poll data (0x%x)\n",
+                       sc->sc_flags & (SC_OP_WAIT_FOR_BEACON |
+                                       SC_OP_WAIT_FOR_CAB |
+                                       SC_OP_WAIT_FOR_PSPOLL_DATA |
+                                       SC_OP_WAIT_FOR_TX_ACK));
+       }
+}
+
+static void ath_rx_send_to_mac80211(struct ath_softc *sc, struct sk_buff *skb,
+                                   struct ieee80211_rx_status *rx_status)
+{
+       struct ieee80211_hdr *hdr;
+
+       hdr = (struct ieee80211_hdr *)skb->data;
+
+       /* Send the frame to mac80211 */
+       if (is_multicast_ether_addr(hdr->addr1)) {
+               int i;
+               /*
+                * Deliver broadcast/multicast frames to all suitable
+                * virtual wiphys.
+                */
+               /* TODO: filter based on channel configuration */
+               for (i = 0; i < sc->num_sec_wiphy; i++) {
+                       struct ath_wiphy *aphy = sc->sec_wiphy[i];
+                       struct sk_buff *nskb;
+                       if (aphy == NULL)
+                               continue;
+                       nskb = skb_copy(skb, GFP_ATOMIC);
+                       if (nskb)
+                               __ieee80211_rx(aphy->hw, nskb, rx_status);
+               }
+               __ieee80211_rx(sc->hw, skb, rx_status);
+       } else {
+               /* Deliver unicast frames based on receiver address */
+               __ieee80211_rx(ath_get_virt_hw(sc, hdr), skb, rx_status);
+       }
+}
+
+int ath_rx_tasklet(struct ath_softc *sc, int flush)
+{
+#define PA2DESC(_sc, _pa)                                               \
+       ((struct ath_desc *)((caddr_t)(_sc)->rx.rxdma.dd_desc +         \
+                            ((_pa) - (_sc)->rx.rxdma.dd_desc_paddr)))
+
+       struct ath_buf *bf;
+       struct ath_desc *ds;
+       struct sk_buff *skb = NULL, *requeue_skb;
+       struct ieee80211_rx_status rx_status;
+       struct ath_hw *ah = sc->sc_ah;
+       struct ieee80211_hdr *hdr;
+       int hdrlen, padsize, retval;
+       bool decrypt_error = false;
+       u8 keyix;
+       __le16 fc;
+
+       spin_lock_bh(&sc->rx.rxbuflock);
+
+       do {
+               /* If handling rx interrupt and flush is in progress => exit */
+               if ((sc->sc_flags & SC_OP_RXFLUSH) && (flush == 0))
+                       break;
+
+               if (list_empty(&sc->rx.rxbuf)) {
+                       sc->rx.rxlink = NULL;
+                       break;
+               }
+
+               bf = list_first_entry(&sc->rx.rxbuf, struct ath_buf, list);
+               ds = bf->bf_desc;
+
+               /*
+                * Must provide the virtual address of the current
+                * descriptor, the physical address, and the virtual
+                * address of the next descriptor in the h/w chain.
+                * This allows the HAL to look ahead to see if the
+                * hardware is done with a descriptor by checking the
+                * done bit in the following descriptor and the address
+                * of the current descriptor the DMA engine is working
+                * on.  All this is necessary because of our use of
+                * a self-linked list to avoid rx overruns.
+                */
+               retval = ath9k_hw_rxprocdesc(ah, ds,
+                                            bf->bf_daddr,
+                                            PA2DESC(sc, ds->ds_link),
+                                            0);
+               if (retval == -EINPROGRESS) {
+                       struct ath_buf *tbf;
+                       struct ath_desc *tds;
+
+                       if (list_is_last(&bf->list, &sc->rx.rxbuf)) {
+                               sc->rx.rxlink = NULL;
+                               break;
+                       }
+
+                       tbf = list_entry(bf->list.next, struct ath_buf, list);
+
+                       /*
+                        * On some hardware the descriptor status words could
+                        * get corrupted, including the done bit. Because of
+                        * this, check if the next descriptor's done bit is
+                        * set or not.
+                        *
+                        * If the next descriptor's done bit is set, the current
+                        * descriptor has been corrupted. Force s/w to discard
+                        * this descriptor and continue...
+                        */
+
+                       tds = tbf->bf_desc;
+                       retval = ath9k_hw_rxprocdesc(ah, tds, tbf->bf_daddr,
+                                            PA2DESC(sc, tds->ds_link), 0);
+                       if (retval == -EINPROGRESS) {
+                               break;
+                       }
+               }
+
+               skb = bf->bf_mpdu;
+               if (!skb)
+                       continue;
+
+               /*
+                * Synchronize the DMA transfer with CPU before
+                * 1. accessing the frame
+                * 2. requeueing the same buffer to h/w
+                */
+               dma_sync_single_for_cpu(sc->dev, bf->bf_buf_addr,
+                               sc->rx.bufsize,
+                               DMA_FROM_DEVICE);
+
+               /*
+                * If we're asked to flush receive queue, directly
+                * chain it back at the queue without processing it.
+                */
+               if (flush)
+                       goto requeue;
+
+               if (!ds->ds_rxstat.rs_datalen)
+                       goto requeue;
+
+               /* The status portion of the descriptor could get corrupted. */
+               if (sc->rx.bufsize < ds->ds_rxstat.rs_datalen)
+                       goto requeue;
+
+               if (!ath_rx_prepare(skb, ds, &rx_status, &decrypt_error, sc))
+                       goto requeue;
+
+               /* Ensure we always have an skb to requeue once we are done
+                * processing the current buffer's skb */
+               requeue_skb = ath_rxbuf_alloc(sc, sc->rx.bufsize, GFP_ATOMIC);
+
+               /* If there is no memory we ignore the current RX'd frame,
+                * tell hardware it can give us a new frame using the old
+                * skb and put it at the tail of the sc->rx.rxbuf list for
+                * processing. */
+               if (!requeue_skb)
+                       goto requeue;
+
+               /* Unmap the frame */
+               dma_unmap_single(sc->dev, bf->bf_buf_addr,
+                                sc->rx.bufsize,
+                                DMA_FROM_DEVICE);
+
+               skb_put(skb, ds->ds_rxstat.rs_datalen);
+               skb->protocol = cpu_to_be16(ETH_P_CONTROL);
+
+               /* see if any padding is done by the hw and remove it */
+               hdr = (struct ieee80211_hdr *)skb->data;
+               hdrlen = ieee80211_get_hdrlen_from_skb(skb);
+               fc = hdr->frame_control;
+
+               /* The MAC header is padded to have 32-bit boundary if the
+                * packet payload is non-zero. The general calculation for
+                * padsize would take into account odd header lengths:
+                * padsize = (4 - hdrlen % 4) % 4; However, since only
+                * even-length headers are used, padding can only be 0 or 2
+                * bytes and we can optimize this a bit. In addition, we must
+                * not try to remove padding from short control frames that do
+                * not have payload. */
+               padsize = hdrlen & 3;
+               if (padsize && hdrlen >= 24) {
+                       memmove(skb->data + padsize, skb->data, hdrlen);
+                       skb_pull(skb, padsize);
+               }
+
+               keyix = ds->ds_rxstat.rs_keyix;
+
+               if (!(keyix == ATH9K_RXKEYIX_INVALID) && !decrypt_error) {
+                       rx_status.flag |= RX_FLAG_DECRYPTED;
+               } else if (ieee80211_has_protected(fc)
+                          && !decrypt_error && skb->len >= hdrlen + 4) {
+                       keyix = skb->data[hdrlen + 3] >> 6;
+
+                       if (test_bit(keyix, sc->keymap))
+                               rx_status.flag |= RX_FLAG_DECRYPTED;
+               }
+               if (ah->sw_mgmt_crypto &&
+                   (rx_status.flag & RX_FLAG_DECRYPTED) &&
+                   ieee80211_is_mgmt(fc)) {
+                       /* Use software decrypt for management frames. */
+                       rx_status.flag &= ~RX_FLAG_DECRYPTED;
+               }
+
+               /* We will now give hardware our shiny new allocated skb */
+               bf->bf_mpdu = requeue_skb;
+               bf->bf_buf_addr = dma_map_single(sc->dev, requeue_skb->data,
+                                        sc->rx.bufsize,
+                                        DMA_FROM_DEVICE);
+               if (unlikely(dma_mapping_error(sc->dev,
+                         bf->bf_buf_addr))) {
+                       dev_kfree_skb_any(requeue_skb);
+                       bf->bf_mpdu = NULL;
+                       DPRINTF(sc, ATH_DBG_FATAL,
+                               "dma_mapping_error() on RX\n");
+                       ath_rx_send_to_mac80211(sc, skb, &rx_status);
+                       break;
+               }
+               bf->bf_dmacontext = bf->bf_buf_addr;
+
+               /*
+                * change the default rx antenna if rx diversity chooses the
+                * other antenna 3 times in a row.
+                */
+               if (sc->rx.defant != ds->ds_rxstat.rs_antenna) {
+                       if (++sc->rx.rxotherant >= 3)
+                               ath_setdefantenna(sc, ds->ds_rxstat.rs_antenna);
+               } else {
+                       sc->rx.rxotherant = 0;
+               }
+
+               if (unlikely(sc->sc_flags & (SC_OP_WAIT_FOR_BEACON |
+                                            SC_OP_WAIT_FOR_PSPOLL_DATA)))
+                       ath_rx_ps(sc, skb);
+
+               ath_rx_send_to_mac80211(sc, skb, &rx_status);
+
+requeue:
+               list_move_tail(&bf->list, &sc->rx.rxbuf);
+               ath_rx_buf_link(sc, bf);
+       } while (1);
+
+       spin_unlock_bh(&sc->rx.rxbuflock);
+
+       return 0;
+#undef PA2DESC
+}
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
new file mode 100644 (file)
index 0000000..5260524
--- /dev/null
@@ -0,0 +1,1511 @@
+/*
+ * Copyright (c) 2008-2009 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 REG_H
+#define REG_H
+
+#define AR_CR                0x0008
+#define AR_CR_RXE            0x00000004
+#define AR_CR_RXD            0x00000020
+#define AR_CR_SWI            0x00000040
+
+#define AR_RXDP              0x000C
+
+#define AR_CFG               0x0014
+#define AR_CFG_SWTD          0x00000001
+#define AR_CFG_SWTB          0x00000002
+#define AR_CFG_SWRD          0x00000004
+#define AR_CFG_SWRB          0x00000008
+#define AR_CFG_SWRG          0x00000010
+#define AR_CFG_AP_ADHOC_INDICATION 0x00000020
+#define AR_CFG_PHOK          0x00000100
+#define AR_CFG_CLK_GATE_DIS  0x00000400
+#define AR_CFG_EEBS          0x00000200
+#define AR_CFG_PCI_MASTER_REQ_Q_THRESH         0x00060000
+#define AR_CFG_PCI_MASTER_REQ_Q_THRESH_S       17
+
+#define AR_MIRT              0x0020
+#define AR_MIRT_VAL          0x0000ffff
+#define AR_MIRT_VAL_S        16
+
+#define AR_IER               0x0024
+#define AR_IER_ENABLE        0x00000001
+#define AR_IER_DISABLE       0x00000000
+
+#define AR_TIMT              0x0028
+#define AR_TIMT_LAST         0x0000ffff
+#define AR_TIMT_LAST_S       0
+#define AR_TIMT_FIRST        0xffff0000
+#define AR_TIMT_FIRST_S      16
+
+#define AR_RIMT              0x002C
+#define AR_RIMT_LAST         0x0000ffff
+#define AR_RIMT_LAST_S       0
+#define AR_RIMT_FIRST        0xffff0000
+#define AR_RIMT_FIRST_S      16
+
+#define AR_DMASIZE_4B        0x00000000
+#define AR_DMASIZE_8B        0x00000001
+#define AR_DMASIZE_16B       0x00000002
+#define AR_DMASIZE_32B       0x00000003
+#define AR_DMASIZE_64B       0x00000004
+#define AR_DMASIZE_128B      0x00000005
+#define AR_DMASIZE_256B      0x00000006
+#define AR_DMASIZE_512B      0x00000007
+
+#define AR_TXCFG             0x0030
+#define AR_TXCFG_DMASZ_MASK  0x00000007
+#define AR_TXCFG_DMASZ_4B    0
+#define AR_TXCFG_DMASZ_8B    1
+#define AR_TXCFG_DMASZ_16B   2
+#define AR_TXCFG_DMASZ_32B   3
+#define AR_TXCFG_DMASZ_64B   4
+#define AR_TXCFG_DMASZ_128B  5
+#define AR_TXCFG_DMASZ_256B  6
+#define AR_TXCFG_DMASZ_512B  7
+#define AR_FTRIG             0x000003F0
+#define AR_FTRIG_S           4
+#define AR_FTRIG_IMMED       0x00000000
+#define AR_FTRIG_64B         0x00000010
+#define AR_FTRIG_128B        0x00000020
+#define AR_FTRIG_192B        0x00000030
+#define AR_FTRIG_256B        0x00000040
+#define AR_FTRIG_512B        0x00000080
+#define AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY 0x00000800
+
+#define AR_RXCFG             0x0034
+#define AR_RXCFG_CHIRP       0x00000008
+#define AR_RXCFG_ZLFDMA      0x00000010
+#define AR_RXCFG_DMASZ_MASK  0x00000007
+#define AR_RXCFG_DMASZ_4B    0
+#define AR_RXCFG_DMASZ_8B    1
+#define AR_RXCFG_DMASZ_16B   2
+#define AR_RXCFG_DMASZ_32B   3
+#define AR_RXCFG_DMASZ_64B   4
+#define AR_RXCFG_DMASZ_128B  5
+#define AR_RXCFG_DMASZ_256B  6
+#define AR_RXCFG_DMASZ_512B  7
+
+#define AR_MIBC              0x0040
+#define AR_MIBC_COW          0x00000001
+#define AR_MIBC_FMC          0x00000002
+#define AR_MIBC_CMC          0x00000004
+#define AR_MIBC_MCS          0x00000008
+
+#define AR_TOPS              0x0044
+#define AR_TOPS_MASK         0x0000FFFF
+
+#define AR_RXNPTO            0x0048
+#define AR_RXNPTO_MASK       0x000003FF
+
+#define AR_TXNPTO            0x004C
+#define AR_TXNPTO_MASK       0x000003FF
+#define AR_TXNPTO_QCU_MASK   0x000FFC00
+
+#define AR_RPGTO             0x0050
+#define AR_RPGTO_MASK        0x000003FF
+
+#define AR_RPCNT             0x0054
+#define AR_RPCNT_MASK        0x0000001F
+
+#define AR_MACMISC           0x0058
+#define AR_MACMISC_PCI_EXT_FORCE        0x00000010
+#define AR_MACMISC_DMA_OBS              0x000001E0
+#define AR_MACMISC_DMA_OBS_S            5
+#define AR_MACMISC_DMA_OBS_LINE_0       0
+#define AR_MACMISC_DMA_OBS_LINE_1       1
+#define AR_MACMISC_DMA_OBS_LINE_2       2
+#define AR_MACMISC_DMA_OBS_LINE_3       3
+#define AR_MACMISC_DMA_OBS_LINE_4       4
+#define AR_MACMISC_DMA_OBS_LINE_5       5
+#define AR_MACMISC_DMA_OBS_LINE_6       6
+#define AR_MACMISC_DMA_OBS_LINE_7       7
+#define AR_MACMISC_DMA_OBS_LINE_8       8
+#define AR_MACMISC_MISC_OBS             0x00000E00
+#define AR_MACMISC_MISC_OBS_S           9
+#define AR_MACMISC_MISC_OBS_BUS_LSB     0x00007000
+#define AR_MACMISC_MISC_OBS_BUS_LSB_S   12
+#define AR_MACMISC_MISC_OBS_BUS_MSB     0x00038000
+#define AR_MACMISC_MISC_OBS_BUS_MSB_S   15
+#define AR_MACMISC_MISC_OBS_BUS_1       1
+
+#define AR_GTXTO    0x0064
+#define AR_GTXTO_TIMEOUT_COUNTER    0x0000FFFF
+#define AR_GTXTO_TIMEOUT_LIMIT      0xFFFF0000
+#define AR_GTXTO_TIMEOUT_LIMIT_S    16
+
+#define AR_GTTM     0x0068
+#define AR_GTTM_USEC          0x00000001
+#define AR_GTTM_IGNORE_IDLE   0x00000002
+#define AR_GTTM_RESET_IDLE    0x00000004
+#define AR_GTTM_CST_USEC      0x00000008
+
+#define AR_CST         0x006C
+#define AR_CST_TIMEOUT_COUNTER    0x0000FFFF
+#define AR_CST_TIMEOUT_LIMIT      0xFFFF0000
+#define AR_CST_TIMEOUT_LIMIT_S    16
+
+#define AR_ISR               0x0080
+#define AR_ISR_RXOK          0x00000001
+#define AR_ISR_RXDESC        0x00000002
+#define AR_ISR_RXERR         0x00000004
+#define AR_ISR_RXNOPKT       0x00000008
+#define AR_ISR_RXEOL         0x00000010
+#define AR_ISR_RXORN         0x00000020
+#define AR_ISR_TXOK          0x00000040
+#define AR_ISR_TXDESC        0x00000080
+#define AR_ISR_TXERR         0x00000100
+#define AR_ISR_TXNOPKT       0x00000200
+#define AR_ISR_TXEOL         0x00000400
+#define AR_ISR_TXURN         0x00000800
+#define AR_ISR_MIB           0x00001000
+#define AR_ISR_SWI           0x00002000
+#define AR_ISR_RXPHY         0x00004000
+#define AR_ISR_RXKCM         0x00008000
+#define AR_ISR_SWBA          0x00010000
+#define AR_ISR_BRSSI         0x00020000
+#define AR_ISR_BMISS         0x00040000
+#define AR_ISR_BNR           0x00100000
+#define AR_ISR_RXCHIRP       0x00200000
+#define AR_ISR_BCNMISC       0x00800000
+#define AR_ISR_TIM           0x00800000
+#define AR_ISR_QCBROVF       0x02000000
+#define AR_ISR_QCBRURN       0x04000000
+#define AR_ISR_QTRIG         0x08000000
+#define AR_ISR_GENTMR        0x10000000
+
+#define AR_ISR_TXMINTR       0x00080000
+#define AR_ISR_RXMINTR       0x01000000
+#define AR_ISR_TXINTM        0x40000000
+#define AR_ISR_RXINTM        0x80000000
+
+#define AR_ISR_S0               0x0084
+#define AR_ISR_S0_QCU_TXOK      0x000003FF
+#define AR_ISR_S0_QCU_TXOK_S    0
+#define AR_ISR_S0_QCU_TXDESC    0x03FF0000
+#define AR_ISR_S0_QCU_TXDESC_S  16
+
+#define AR_ISR_S1              0x0088
+#define AR_ISR_S1_QCU_TXERR    0x000003FF
+#define AR_ISR_S1_QCU_TXERR_S  0
+#define AR_ISR_S1_QCU_TXEOL    0x03FF0000
+#define AR_ISR_S1_QCU_TXEOL_S  16
+
+#define AR_ISR_S2              0x008c
+#define AR_ISR_S2_QCU_TXURN    0x000003FF
+#define AR_ISR_S2_CST          0x00400000
+#define AR_ISR_S2_GTT          0x00800000
+#define AR_ISR_S2_TIM          0x01000000
+#define AR_ISR_S2_CABEND       0x02000000
+#define AR_ISR_S2_DTIMSYNC     0x04000000
+#define AR_ISR_S2_BCNTO        0x08000000
+#define AR_ISR_S2_CABTO        0x10000000
+#define AR_ISR_S2_DTIM         0x20000000
+#define AR_ISR_S2_TSFOOR       0x40000000
+#define AR_ISR_S2_TBTT_TIME    0x80000000
+
+#define AR_ISR_S3             0x0090
+#define AR_ISR_S3_QCU_QCBROVF    0x000003FF
+#define AR_ISR_S3_QCU_QCBRURN    0x03FF0000
+
+#define AR_ISR_S4              0x0094
+#define AR_ISR_S4_QCU_QTRIG    0x000003FF
+#define AR_ISR_S4_RESV0        0xFFFFFC00
+
+#define AR_ISR_S5                   0x0098
+#define AR_ISR_S5_TIMER_TRIG        0x000000FF
+#define AR_ISR_S5_TIMER_THRESH      0x0007FE00
+#define AR_ISR_S5_TIM_TIMER         0x00000010
+#define AR_ISR_S5_DTIM_TIMER        0x00000020
+#define AR_ISR_S5_S                 0x00d8
+#define AR_IMR_S5                   0x00b8
+#define AR_IMR_S5_TIM_TIMER         0x00000010
+#define AR_IMR_S5_DTIM_TIMER        0x00000020
+
+
+#define AR_IMR               0x00a0
+#define AR_IMR_RXOK          0x00000001
+#define AR_IMR_RXDESC        0x00000002
+#define AR_IMR_RXERR         0x00000004
+#define AR_IMR_RXNOPKT       0x00000008
+#define AR_IMR_RXEOL         0x00000010
+#define AR_IMR_RXORN         0x00000020
+#define AR_IMR_TXOK          0x00000040
+#define AR_IMR_TXDESC        0x00000080
+#define AR_IMR_TXERR         0x00000100
+#define AR_IMR_TXNOPKT       0x00000200
+#define AR_IMR_TXEOL         0x00000400
+#define AR_IMR_TXURN         0x00000800
+#define AR_IMR_MIB           0x00001000
+#define AR_IMR_SWI           0x00002000
+#define AR_IMR_RXPHY         0x00004000
+#define AR_IMR_RXKCM         0x00008000
+#define AR_IMR_SWBA          0x00010000
+#define AR_IMR_BRSSI         0x00020000
+#define AR_IMR_BMISS         0x00040000
+#define AR_IMR_BNR           0x00100000
+#define AR_IMR_RXCHIRP       0x00200000
+#define AR_IMR_BCNMISC       0x00800000
+#define AR_IMR_TIM           0x00800000
+#define AR_IMR_QCBROVF       0x02000000
+#define AR_IMR_QCBRURN       0x04000000
+#define AR_IMR_QTRIG         0x08000000
+#define AR_IMR_GENTMR        0x10000000
+
+#define AR_IMR_TXMINTR       0x00080000
+#define AR_IMR_RXMINTR       0x01000000
+#define AR_IMR_TXINTM        0x40000000
+#define AR_IMR_RXINTM        0x80000000
+
+#define AR_IMR_S0               0x00a4
+#define AR_IMR_S0_QCU_TXOK      0x000003FF
+#define AR_IMR_S0_QCU_TXOK_S    0
+#define AR_IMR_S0_QCU_TXDESC    0x03FF0000
+#define AR_IMR_S0_QCU_TXDESC_S  16
+
+#define AR_IMR_S1              0x00a8
+#define AR_IMR_S1_QCU_TXERR    0x000003FF
+#define AR_IMR_S1_QCU_TXERR_S  0
+#define AR_IMR_S1_QCU_TXEOL    0x03FF0000
+#define AR_IMR_S1_QCU_TXEOL_S  16
+
+#define AR_IMR_S2              0x00ac
+#define AR_IMR_S2_QCU_TXURN    0x000003FF
+#define AR_IMR_S2_QCU_TXURN_S  0
+#define AR_IMR_S2_CST          0x00400000
+#define AR_IMR_S2_GTT          0x00800000
+#define AR_IMR_S2_TIM          0x01000000
+#define AR_IMR_S2_CABEND       0x02000000
+#define AR_IMR_S2_DTIMSYNC     0x04000000
+#define AR_IMR_S2_BCNTO        0x08000000
+#define AR_IMR_S2_CABTO        0x10000000
+#define AR_IMR_S2_DTIM         0x20000000
+#define AR_IMR_S2_TSFOOR       0x40000000
+
+#define AR_IMR_S3                0x00b0
+#define AR_IMR_S3_QCU_QCBROVF    0x000003FF
+#define AR_IMR_S3_QCU_QCBRURN    0x03FF0000
+#define AR_IMR_S3_QCU_QCBRURN_S  16
+
+#define AR_IMR_S4              0x00b4
+#define AR_IMR_S4_QCU_QTRIG    0x000003FF
+#define AR_IMR_S4_RESV0        0xFFFFFC00
+
+#define AR_IMR_S5              0x00b8
+#define AR_IMR_S5_TIMER_TRIG        0x000000FF
+#define AR_IMR_S5_TIMER_THRESH      0x0000FF00
+
+
+#define AR_ISR_RAC            0x00c0
+#define AR_ISR_S0_S           0x00c4
+#define AR_ISR_S0_QCU_TXOK      0x000003FF
+#define AR_ISR_S0_QCU_TXOK_S    0
+#define AR_ISR_S0_QCU_TXDESC    0x03FF0000
+#define AR_ISR_S0_QCU_TXDESC_S  16
+
+#define AR_ISR_S1_S           0x00c8
+#define AR_ISR_S1_QCU_TXERR    0x000003FF
+#define AR_ISR_S1_QCU_TXERR_S  0
+#define AR_ISR_S1_QCU_TXEOL    0x03FF0000
+#define AR_ISR_S1_QCU_TXEOL_S  16
+
+#define AR_ISR_S2_S           0x00cc
+#define AR_ISR_S3_S           0x00d0
+#define AR_ISR_S4_S           0x00d4
+#define AR_ISR_S5_S           0x00d8
+#define AR_DMADBG_0           0x00e0
+#define AR_DMADBG_1           0x00e4
+#define AR_DMADBG_2           0x00e8
+#define AR_DMADBG_3           0x00ec
+#define AR_DMADBG_4           0x00f0
+#define AR_DMADBG_5           0x00f4
+#define AR_DMADBG_6           0x00f8
+#define AR_DMADBG_7           0x00fc
+
+#define AR_NUM_QCU      10
+#define AR_QCU_0        0x0001
+#define AR_QCU_1        0x0002
+#define AR_QCU_2        0x0004
+#define AR_QCU_3        0x0008
+#define AR_QCU_4        0x0010
+#define AR_QCU_5        0x0020
+#define AR_QCU_6        0x0040
+#define AR_QCU_7        0x0080
+#define AR_QCU_8        0x0100
+#define AR_QCU_9        0x0200
+
+#define AR_Q0_TXDP           0x0800
+#define AR_Q1_TXDP           0x0804
+#define AR_Q2_TXDP           0x0808
+#define AR_Q3_TXDP           0x080c
+#define AR_Q4_TXDP           0x0810
+#define AR_Q5_TXDP           0x0814
+#define AR_Q6_TXDP           0x0818
+#define AR_Q7_TXDP           0x081c
+#define AR_Q8_TXDP           0x0820
+#define AR_Q9_TXDP           0x0824
+#define AR_QTXDP(_i)    (AR_Q0_TXDP + ((_i)<<2))
+
+#define AR_Q_TXE             0x0840
+#define AR_Q_TXE_M           0x000003FF
+
+#define AR_Q_TXD             0x0880
+#define AR_Q_TXD_M           0x000003FF
+
+#define AR_Q0_CBRCFG         0x08c0
+#define AR_Q1_CBRCFG         0x08c4
+#define AR_Q2_CBRCFG         0x08c8
+#define AR_Q3_CBRCFG         0x08cc
+#define AR_Q4_CBRCFG         0x08d0
+#define AR_Q5_CBRCFG         0x08d4
+#define AR_Q6_CBRCFG         0x08d8
+#define AR_Q7_CBRCFG         0x08dc
+#define AR_Q8_CBRCFG         0x08e0
+#define AR_Q9_CBRCFG         0x08e4
+#define AR_QCBRCFG(_i)      (AR_Q0_CBRCFG + ((_i)<<2))
+#define AR_Q_CBRCFG_INTERVAL     0x00FFFFFF
+#define AR_Q_CBRCFG_INTERVAL_S   0
+#define AR_Q_CBRCFG_OVF_THRESH   0xFF000000
+#define AR_Q_CBRCFG_OVF_THRESH_S 24
+
+#define AR_Q0_RDYTIMECFG         0x0900
+#define AR_Q1_RDYTIMECFG         0x0904
+#define AR_Q2_RDYTIMECFG         0x0908
+#define AR_Q3_RDYTIMECFG         0x090c
+#define AR_Q4_RDYTIMECFG         0x0910
+#define AR_Q5_RDYTIMECFG         0x0914
+#define AR_Q6_RDYTIMECFG         0x0918
+#define AR_Q7_RDYTIMECFG         0x091c
+#define AR_Q8_RDYTIMECFG         0x0920
+#define AR_Q9_RDYTIMECFG         0x0924
+#define AR_QRDYTIMECFG(_i)       (AR_Q0_RDYTIMECFG + ((_i)<<2))
+#define AR_Q_RDYTIMECFG_DURATION   0x00FFFFFF
+#define AR_Q_RDYTIMECFG_DURATION_S 0
+#define AR_Q_RDYTIMECFG_EN         0x01000000
+
+#define AR_Q_ONESHOTARM_SC       0x0940
+#define AR_Q_ONESHOTARM_SC_M     0x000003FF
+#define AR_Q_ONESHOTARM_SC_RESV0 0xFFFFFC00
+
+#define AR_Q_ONESHOTARM_CC       0x0980
+#define AR_Q_ONESHOTARM_CC_M     0x000003FF
+#define AR_Q_ONESHOTARM_CC_RESV0 0xFFFFFC00
+
+#define AR_Q0_MISC         0x09c0
+#define AR_Q1_MISC         0x09c4
+#define AR_Q2_MISC         0x09c8
+#define AR_Q3_MISC         0x09cc
+#define AR_Q4_MISC         0x09d0
+#define AR_Q5_MISC         0x09d4
+#define AR_Q6_MISC         0x09d8
+#define AR_Q7_MISC         0x09dc
+#define AR_Q8_MISC         0x09e0
+#define AR_Q9_MISC         0x09e4
+#define AR_QMISC(_i)       (AR_Q0_MISC + ((_i)<<2))
+#define AR_Q_MISC_FSP                     0x0000000F
+#define AR_Q_MISC_FSP_ASAP                0
+#define AR_Q_MISC_FSP_CBR                 1
+#define AR_Q_MISC_FSP_DBA_GATED           2
+#define AR_Q_MISC_FSP_TIM_GATED           3
+#define AR_Q_MISC_FSP_BEACON_SENT_GATED   4
+#define AR_Q_MISC_FSP_BEACON_RCVD_GATED   5
+#define AR_Q_MISC_ONE_SHOT_EN             0x00000010
+#define AR_Q_MISC_CBR_INCR_DIS1           0x00000020
+#define AR_Q_MISC_CBR_INCR_DIS0           0x00000040
+#define AR_Q_MISC_BEACON_USE              0x00000080
+#define AR_Q_MISC_CBR_EXP_CNTR_LIMIT_EN   0x00000100
+#define AR_Q_MISC_RDYTIME_EXP_POLICY      0x00000200
+#define AR_Q_MISC_RESET_CBR_EXP_CTR       0x00000400
+#define AR_Q_MISC_DCU_EARLY_TERM_REQ      0x00000800
+#define AR_Q_MISC_RESV0                   0xFFFFF000
+
+#define AR_Q0_STS         0x0a00
+#define AR_Q1_STS         0x0a04
+#define AR_Q2_STS         0x0a08
+#define AR_Q3_STS         0x0a0c
+#define AR_Q4_STS         0x0a10
+#define AR_Q5_STS         0x0a14
+#define AR_Q6_STS         0x0a18
+#define AR_Q7_STS         0x0a1c
+#define AR_Q8_STS         0x0a20
+#define AR_Q9_STS         0x0a24
+#define AR_QSTS(_i)       (AR_Q0_STS + ((_i)<<2))
+#define AR_Q_STS_PEND_FR_CNT          0x00000003
+#define AR_Q_STS_RESV0                0x000000FC
+#define AR_Q_STS_CBR_EXP_CNT          0x0000FF00
+#define AR_Q_STS_RESV1                0xFFFF0000
+
+#define AR_Q_RDYTIMESHDN    0x0a40
+#define AR_Q_RDYTIMESHDN_M  0x000003FF
+
+
+#define AR_NUM_DCU      10
+#define AR_DCU_0        0x0001
+#define AR_DCU_1        0x0002
+#define AR_DCU_2        0x0004
+#define AR_DCU_3        0x0008
+#define AR_DCU_4        0x0010
+#define AR_DCU_5        0x0020
+#define AR_DCU_6        0x0040
+#define AR_DCU_7        0x0080
+#define AR_DCU_8        0x0100
+#define AR_DCU_9        0x0200
+
+#define AR_D0_QCUMASK     0x1000
+#define AR_D1_QCUMASK     0x1004
+#define AR_D2_QCUMASK     0x1008
+#define AR_D3_QCUMASK     0x100c
+#define AR_D4_QCUMASK     0x1010
+#define AR_D5_QCUMASK     0x1014
+#define AR_D6_QCUMASK     0x1018
+#define AR_D7_QCUMASK     0x101c
+#define AR_D8_QCUMASK     0x1020
+#define AR_D9_QCUMASK     0x1024
+#define AR_DQCUMASK(_i)   (AR_D0_QCUMASK + ((_i)<<2))
+#define AR_D_QCUMASK         0x000003FF
+#define AR_D_QCUMASK_RESV0   0xFFFFFC00
+
+#define AR_D_TXBLK_CMD  0x1038
+#define AR_D_TXBLK_DATA(i) (AR_D_TXBLK_CMD+(i))
+
+#define AR_D0_LCL_IFS     0x1040
+#define AR_D1_LCL_IFS     0x1044
+#define AR_D2_LCL_IFS     0x1048
+#define AR_D3_LCL_IFS     0x104c
+#define AR_D4_LCL_IFS     0x1050
+#define AR_D5_LCL_IFS     0x1054
+#define AR_D6_LCL_IFS     0x1058
+#define AR_D7_LCL_IFS     0x105c
+#define AR_D8_LCL_IFS     0x1060
+#define AR_D9_LCL_IFS     0x1064
+#define AR_DLCL_IFS(_i)   (AR_D0_LCL_IFS + ((_i)<<2))
+#define AR_D_LCL_IFS_CWMIN       0x000003FF
+#define AR_D_LCL_IFS_CWMIN_S     0
+#define AR_D_LCL_IFS_CWMAX       0x000FFC00
+#define AR_D_LCL_IFS_CWMAX_S     10
+#define AR_D_LCL_IFS_AIFS        0x0FF00000
+#define AR_D_LCL_IFS_AIFS_S      20
+
+#define AR_D_LCL_IFS_RESV0    0xF0000000
+
+#define AR_D0_RETRY_LIMIT     0x1080
+#define AR_D1_RETRY_LIMIT     0x1084
+#define AR_D2_RETRY_LIMIT     0x1088
+#define AR_D3_RETRY_LIMIT     0x108c
+#define AR_D4_RETRY_LIMIT     0x1090
+#define AR_D5_RETRY_LIMIT     0x1094
+#define AR_D6_RETRY_LIMIT     0x1098
+#define AR_D7_RETRY_LIMIT     0x109c
+#define AR_D8_RETRY_LIMIT     0x10a0
+#define AR_D9_RETRY_LIMIT     0x10a4
+#define AR_DRETRY_LIMIT(_i)   (AR_D0_RETRY_LIMIT + ((_i)<<2))
+#define AR_D_RETRY_LIMIT_FR_SH       0x0000000F
+#define AR_D_RETRY_LIMIT_FR_SH_S     0
+#define AR_D_RETRY_LIMIT_STA_SH      0x00003F00
+#define AR_D_RETRY_LIMIT_STA_SH_S    8
+#define AR_D_RETRY_LIMIT_STA_LG      0x000FC000
+#define AR_D_RETRY_LIMIT_STA_LG_S    14
+#define AR_D_RETRY_LIMIT_RESV0       0xFFF00000
+
+#define AR_D0_CHNTIME     0x10c0
+#define AR_D1_CHNTIME     0x10c4
+#define AR_D2_CHNTIME     0x10c8
+#define AR_D3_CHNTIME     0x10cc
+#define AR_D4_CHNTIME     0x10d0
+#define AR_D5_CHNTIME     0x10d4
+#define AR_D6_CHNTIME     0x10d8
+#define AR_D7_CHNTIME     0x10dc
+#define AR_D8_CHNTIME     0x10e0
+#define AR_D9_CHNTIME     0x10e4
+#define AR_DCHNTIME(_i)   (AR_D0_CHNTIME + ((_i)<<2))
+#define AR_D_CHNTIME_DUR         0x000FFFFF
+#define AR_D_CHNTIME_DUR_S       0
+#define AR_D_CHNTIME_EN          0x00100000
+#define AR_D_CHNTIME_RESV0       0xFFE00000
+
+#define AR_D0_MISC        0x1100
+#define AR_D1_MISC        0x1104
+#define AR_D2_MISC        0x1108
+#define AR_D3_MISC        0x110c
+#define AR_D4_MISC        0x1110
+#define AR_D5_MISC        0x1114
+#define AR_D6_MISC        0x1118
+#define AR_D7_MISC        0x111c
+#define AR_D8_MISC        0x1120
+#define AR_D9_MISC        0x1124
+#define AR_DMISC(_i)      (AR_D0_MISC + ((_i)<<2))
+#define AR_D_MISC_BKOFF_THRESH        0x0000003F
+#define AR_D_MISC_RETRY_CNT_RESET_EN  0x00000040
+#define AR_D_MISC_CW_RESET_EN         0x00000080
+#define AR_D_MISC_FRAG_WAIT_EN        0x00000100
+#define AR_D_MISC_FRAG_BKOFF_EN       0x00000200
+#define AR_D_MISC_CW_BKOFF_EN         0x00001000
+#define AR_D_MISC_VIR_COL_HANDLING    0x0000C000
+#define AR_D_MISC_VIR_COL_HANDLING_S  14
+#define AR_D_MISC_VIR_COL_HANDLING_DEFAULT 0
+#define AR_D_MISC_VIR_COL_HANDLING_IGNORE  1
+#define AR_D_MISC_BEACON_USE          0x00010000
+#define AR_D_MISC_ARB_LOCKOUT_CNTRL   0x00060000
+#define AR_D_MISC_ARB_LOCKOUT_CNTRL_S 17
+#define AR_D_MISC_ARB_LOCKOUT_CNTRL_NONE     0
+#define AR_D_MISC_ARB_LOCKOUT_CNTRL_INTRA_FR 1
+#define AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL   2
+#define AR_D_MISC_ARB_LOCKOUT_IGNORE  0x00080000
+#define AR_D_MISC_SEQ_NUM_INCR_DIS    0x00100000
+#define AR_D_MISC_POST_FR_BKOFF_DIS   0x00200000
+#define AR_D_MISC_VIT_COL_CW_BKOFF_EN 0x00400000
+#define AR_D_MISC_BLOWN_IFS_RETRY_EN  0x00800000
+#define AR_D_MISC_RESV0               0xFF000000
+
+#define AR_D_SEQNUM      0x1140
+
+#define AR_D_GBL_IFS_SIFS         0x1030
+#define AR_D_GBL_IFS_SIFS_M       0x0000FFFF
+#define AR_D_GBL_IFS_SIFS_RESV0   0xFFFFFFFF
+
+#define AR_D_TXBLK_BASE            0x1038
+#define AR_D_TXBLK_WRITE_BITMASK    0x0000FFFF
+#define AR_D_TXBLK_WRITE_BITMASK_S  0
+#define AR_D_TXBLK_WRITE_SLICE      0x000F0000
+#define AR_D_TXBLK_WRITE_SLICE_S    16
+#define AR_D_TXBLK_WRITE_DCU        0x00F00000
+#define AR_D_TXBLK_WRITE_DCU_S      20
+#define AR_D_TXBLK_WRITE_COMMAND    0x0F000000
+#define AR_D_TXBLK_WRITE_COMMAND_S      24
+
+#define AR_D_GBL_IFS_SLOT         0x1070
+#define AR_D_GBL_IFS_SLOT_M       0x0000FFFF
+#define AR_D_GBL_IFS_SLOT_RESV0   0xFFFF0000
+
+#define AR_D_GBL_IFS_EIFS         0x10b0
+#define AR_D_GBL_IFS_EIFS_M       0x0000FFFF
+#define AR_D_GBL_IFS_EIFS_RESV0   0xFFFF0000
+
+#define AR_D_GBL_IFS_MISC        0x10f0
+#define AR_D_GBL_IFS_MISC_LFSR_SLICE_SEL        0x00000007
+#define AR_D_GBL_IFS_MISC_TURBO_MODE            0x00000008
+#define AR_D_GBL_IFS_MISC_USEC_DURATION         0x000FFC00
+#define AR_D_GBL_IFS_MISC_DCU_ARBITER_DLY       0x00300000
+#define AR_D_GBL_IFS_MISC_RANDOM_LFSR_SLICE_DIS 0x01000000
+#define AR_D_GBL_IFS_MISC_SLOT_XMIT_WIND_LEN    0x06000000
+#define AR_D_GBL_IFS_MISC_FORCE_XMIT_SLOT_BOUND 0x08000000
+#define AR_D_GBL_IFS_MISC_IGNORE_BACKOFF        0x10000000
+
+#define AR_D_FPCTL                  0x1230
+#define AR_D_FPCTL_DCU              0x0000000F
+#define AR_D_FPCTL_DCU_S            0
+#define AR_D_FPCTL_PREFETCH_EN      0x00000010
+#define AR_D_FPCTL_BURST_PREFETCH   0x00007FE0
+#define AR_D_FPCTL_BURST_PREFETCH_S 5
+
+#define AR_D_TXPSE                 0x1270
+#define AR_D_TXPSE_CTRL            0x000003FF
+#define AR_D_TXPSE_RESV0           0x0000FC00
+#define AR_D_TXPSE_STATUS          0x00010000
+#define AR_D_TXPSE_RESV1           0xFFFE0000
+
+#define AR_D_TXSLOTMASK            0x12f0
+#define AR_D_TXSLOTMASK_NUM        0x0000000F
+
+#define AR_CFG_LED                     0x1f04
+#define AR_CFG_SCLK_RATE_IND           0x00000003
+#define AR_CFG_SCLK_RATE_IND_S         0
+#define AR_CFG_SCLK_32MHZ              0x00000000
+#define AR_CFG_SCLK_4MHZ               0x00000001
+#define AR_CFG_SCLK_1MHZ               0x00000002
+#define AR_CFG_SCLK_32KHZ              0x00000003
+#define AR_CFG_LED_BLINK_SLOW          0x00000008
+#define AR_CFG_LED_BLINK_THRESH_SEL    0x00000070
+#define AR_CFG_LED_MODE_SEL            0x00000380
+#define AR_CFG_LED_MODE_SEL_S          7
+#define AR_CFG_LED_POWER               0x00000280
+#define AR_CFG_LED_POWER_S             7
+#define AR_CFG_LED_NETWORK             0x00000300
+#define AR_CFG_LED_NETWORK_S           7
+#define AR_CFG_LED_MODE_PROP           0x0
+#define AR_CFG_LED_MODE_RPROP          0x1
+#define AR_CFG_LED_MODE_SPLIT          0x2
+#define AR_CFG_LED_MODE_RAND           0x3
+#define AR_CFG_LED_MODE_POWER_OFF      0x4
+#define AR_CFG_LED_MODE_POWER_ON       0x5
+#define AR_CFG_LED_MODE_NETWORK_OFF    0x4
+#define AR_CFG_LED_MODE_NETWORK_ON     0x6
+#define AR_CFG_LED_ASSOC_CTL           0x00000c00
+#define AR_CFG_LED_ASSOC_CTL_S         10
+#define AR_CFG_LED_ASSOC_NONE          0x0
+#define AR_CFG_LED_ASSOC_ACTIVE        0x1
+#define AR_CFG_LED_ASSOC_PENDING       0x2
+
+#define AR_CFG_LED_BLINK_SLOW          0x00000008
+#define AR_CFG_LED_BLINK_SLOW_S        3
+
+#define AR_CFG_LED_BLINK_THRESH_SEL    0x00000070
+#define AR_CFG_LED_BLINK_THRESH_SEL_S  4
+
+#define AR_MAC_SLEEP                0x1f00
+#define AR_MAC_SLEEP_MAC_AWAKE      0x00000000
+#define AR_MAC_SLEEP_MAC_ASLEEP     0x00000001
+
+#define AR_RC                0x4000
+#define AR_RC_AHB            0x00000001
+#define AR_RC_APB            0x00000002
+#define AR_RC_HOSTIF         0x00000100
+
+#define AR_WA                          0x4004
+#define AR9285_WA_DEFAULT              0x004a05cb
+#define AR9280_WA_DEFAULT              0x0040073f
+#define AR_WA_DEFAULT                  0x0000073f
+
+
+#define AR_PM_STATE                 0x4008
+#define AR_PM_STATE_PME_D3COLD_VAUX 0x00100000
+
+#define AR_HOST_TIMEOUT             0x4018
+#define AR_HOST_TIMEOUT_APB_CNTR    0x0000FFFF
+#define AR_HOST_TIMEOUT_APB_CNTR_S  0
+#define AR_HOST_TIMEOUT_LCL_CNTR    0xFFFF0000
+#define AR_HOST_TIMEOUT_LCL_CNTR_S  16
+
+#define AR_EEPROM                0x401c
+#define AR_EEPROM_ABSENT         0x00000100
+#define AR_EEPROM_CORRUPT        0x00000200
+#define AR_EEPROM_PROT_MASK      0x03FFFC00
+#define AR_EEPROM_PROT_MASK_S    10
+
+#define EEPROM_PROTECT_RP_0_31        0x0001
+#define EEPROM_PROTECT_WP_0_31        0x0002
+#define EEPROM_PROTECT_RP_32_63       0x0004
+#define EEPROM_PROTECT_WP_32_63       0x0008
+#define EEPROM_PROTECT_RP_64_127      0x0010
+#define EEPROM_PROTECT_WP_64_127      0x0020
+#define EEPROM_PROTECT_RP_128_191     0x0040
+#define EEPROM_PROTECT_WP_128_191     0x0080
+#define EEPROM_PROTECT_RP_192_255     0x0100
+#define EEPROM_PROTECT_WP_192_255     0x0200
+#define EEPROM_PROTECT_RP_256_511     0x0400
+#define EEPROM_PROTECT_WP_256_511     0x0800
+#define EEPROM_PROTECT_RP_512_1023    0x1000
+#define EEPROM_PROTECT_WP_512_1023    0x2000
+#define EEPROM_PROTECT_RP_1024_2047   0x4000
+#define EEPROM_PROTECT_WP_1024_2047   0x8000
+
+#define AR_SREV \
+       ((AR_SREV_9100(ah)) ? 0x0600 : 0x4020)
+
+#define AR_SREV_ID \
+       ((AR_SREV_9100(ah)) ? 0x00000FFF : 0x000000FF)
+#define AR_SREV_VERSION                       0x000000F0
+#define AR_SREV_VERSION_S                     4
+#define AR_SREV_REVISION                      0x00000007
+
+#define AR_SREV_ID2                           0xFFFFFFFF
+#define AR_SREV_VERSION2                     0xFFFC0000
+#define AR_SREV_VERSION2_S                    18
+#define AR_SREV_TYPE2                        0x0003F000
+#define AR_SREV_TYPE2_S                       12
+#define AR_SREV_TYPE2_CHAIN                  0x00001000
+#define AR_SREV_TYPE2_HOST_MODE                      0x00002000
+#define AR_SREV_REVISION2                    0x00000F00
+#define AR_SREV_REVISION2_S                  8
+
+#define AR_SREV_VERSION_5416_PCI               0xD
+#define AR_SREV_VERSION_5416_PCIE              0xC
+#define AR_SREV_REVISION_5416_10               0
+#define AR_SREV_REVISION_5416_20               1
+#define AR_SREV_REVISION_5416_22               2
+#define AR_SREV_VERSION_9100                  0x14
+#define AR_SREV_VERSION_9160                 0x40
+#define AR_SREV_REVISION_9160_10             0
+#define AR_SREV_REVISION_9160_11             1
+#define AR_SREV_VERSION_9280                0x80
+#define AR_SREV_REVISION_9280_10            0
+#define AR_SREV_REVISION_9280_20            1
+#define AR_SREV_REVISION_9280_21            2
+#define AR_SREV_VERSION_9285                  0xC0
+#define AR_SREV_REVISION_9285_10              0
+#define AR_SREV_REVISION_9285_11              1
+#define AR_SREV_REVISION_9285_12              2
+
+#define AR_SREV_5416(_ah) \
+       (((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) || \
+        ((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCIE))
+#define AR_SREV_5416_20_OR_LATER(_ah) \
+       (((AR_SREV_5416(_ah)) && \
+        ((_ah)->hw_version.macRev >= AR_SREV_REVISION_5416_20)) || \
+        ((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9100))
+#define AR_SREV_5416_22_OR_LATER(_ah) \
+       (((AR_SREV_5416(_ah)) && \
+        ((_ah)->hw_version.macRev >= AR_SREV_REVISION_5416_22)) || \
+        ((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9100))
+
+#define AR_SREV_9100(ah) \
+       ((ah->hw_version.macVersion) == AR_SREV_VERSION_9100)
+#define AR_SREV_9100_OR_LATER(_ah) \
+       (((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9100))
+
+#define AR_SREV_9160(_ah) \
+       (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9160))
+#define AR_SREV_9160_10_OR_LATER(_ah) \
+       (((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9160))
+#define AR_SREV_9160_11(_ah) \
+       (AR_SREV_9160(_ah) && \
+        ((_ah)->hw_version.macRev == AR_SREV_REVISION_9160_11))
+#define AR_SREV_9280(_ah) \
+       (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9280))
+#define AR_SREV_9280_10_OR_LATER(_ah) \
+       (((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9280))
+#define AR_SREV_9280_20(_ah) \
+       (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9280) && \
+               ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9280_20))
+#define AR_SREV_9280_20_OR_LATER(_ah) \
+       (((_ah)->hw_version.macVersion > AR_SREV_VERSION_9280) || \
+       (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9280) && \
+       ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9280_20)))
+
+#define AR_SREV_9285(_ah) \
+       (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9285))
+#define AR_SREV_9285_10_OR_LATER(_ah) \
+       (((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9285))
+#define AR_SREV_9285_11(_ah) \
+       (AR_SREV_9285(ah) && \
+        ((_ah)->hw_version.macRev == AR_SREV_REVISION_9285_11))
+#define AR_SREV_9285_11_OR_LATER(_ah) \
+       (((_ah)->hw_version.macVersion > AR_SREV_VERSION_9285) || \
+        (AR_SREV_9285(ah) && ((_ah)->hw_version.macRev >= \
+                              AR_SREV_REVISION_9285_11)))
+#define AR_SREV_9285_12(_ah) \
+       (AR_SREV_9285(ah) && \
+        ((_ah)->hw_version.macRev == AR_SREV_REVISION_9285_12))
+#define AR_SREV_9285_12_OR_LATER(_ah) \
+       (((_ah)->hw_version.macVersion > AR_SREV_VERSION_9285) || \
+        (AR_SREV_9285(ah) && ((_ah)->hw_version.macRev >= \
+                              AR_SREV_REVISION_9285_12)))
+
+#define AR_RADIO_SREV_MAJOR                   0xf0
+#define AR_RAD5133_SREV_MAJOR                 0xc0
+#define AR_RAD2133_SREV_MAJOR                 0xd0
+#define AR_RAD5122_SREV_MAJOR                 0xe0
+#define AR_RAD2122_SREV_MAJOR                 0xf0
+
+#define AR_AHB_MODE                           0x4024
+#define AR_AHB_EXACT_WR_EN                    0x00000000
+#define AR_AHB_BUF_WR_EN                      0x00000001
+#define AR_AHB_EXACT_RD_EN                    0x00000000
+#define AR_AHB_CACHELINE_RD_EN                0x00000002
+#define AR_AHB_PREFETCH_RD_EN                 0x00000004
+#define AR_AHB_PAGE_SIZE_1K                   0x00000000
+#define AR_AHB_PAGE_SIZE_2K                   0x00000008
+#define AR_AHB_PAGE_SIZE_4K                   0x00000010
+
+#define AR_INTR_RTC_IRQ                       0x00000001
+#define AR_INTR_MAC_IRQ                       0x00000002
+#define AR_INTR_EEP_PROT_ACCESS               0x00000004
+#define AR_INTR_MAC_AWAKE                     0x00020000
+#define AR_INTR_MAC_ASLEEP                    0x00040000
+#define AR_INTR_SPURIOUS                      0xFFFFFFFF
+
+
+#define AR_INTR_SYNC_CAUSE_CLR                0x4028
+
+#define AR_INTR_SYNC_CAUSE                    0x4028
+
+#define AR_INTR_SYNC_ENABLE                   0x402c
+#define AR_INTR_SYNC_ENABLE_GPIO              0xFFFC0000
+#define AR_INTR_SYNC_ENABLE_GPIO_S            18
+
+enum {
+       AR_INTR_SYNC_RTC_IRQ = 0x00000001,
+       AR_INTR_SYNC_MAC_IRQ = 0x00000002,
+       AR_INTR_SYNC_EEPROM_ILLEGAL_ACCESS = 0x00000004,
+       AR_INTR_SYNC_APB_TIMEOUT = 0x00000008,
+       AR_INTR_SYNC_PCI_MODE_CONFLICT = 0x00000010,
+       AR_INTR_SYNC_HOST1_FATAL = 0x00000020,
+       AR_INTR_SYNC_HOST1_PERR = 0x00000040,
+       AR_INTR_SYNC_TRCV_FIFO_PERR = 0x00000080,
+       AR_INTR_SYNC_RADM_CPL_EP = 0x00000100,
+       AR_INTR_SYNC_RADM_CPL_DLLP_ABORT = 0x00000200,
+       AR_INTR_SYNC_RADM_CPL_TLP_ABORT = 0x00000400,
+       AR_INTR_SYNC_RADM_CPL_ECRC_ERR = 0x00000800,
+       AR_INTR_SYNC_RADM_CPL_TIMEOUT = 0x00001000,
+       AR_INTR_SYNC_LOCAL_TIMEOUT = 0x00002000,
+       AR_INTR_SYNC_PM_ACCESS = 0x00004000,
+       AR_INTR_SYNC_MAC_AWAKE = 0x00008000,
+       AR_INTR_SYNC_MAC_ASLEEP = 0x00010000,
+       AR_INTR_SYNC_MAC_SLEEP_ACCESS = 0x00020000,
+       AR_INTR_SYNC_ALL = 0x0003FFFF,
+
+
+       AR_INTR_SYNC_DEFAULT = (AR_INTR_SYNC_HOST1_FATAL |
+                               AR_INTR_SYNC_HOST1_PERR |
+                               AR_INTR_SYNC_RADM_CPL_EP |
+                               AR_INTR_SYNC_RADM_CPL_DLLP_ABORT |
+                               AR_INTR_SYNC_RADM_CPL_TLP_ABORT |
+                               AR_INTR_SYNC_RADM_CPL_ECRC_ERR |
+                               AR_INTR_SYNC_RADM_CPL_TIMEOUT |
+                               AR_INTR_SYNC_LOCAL_TIMEOUT |
+                               AR_INTR_SYNC_MAC_SLEEP_ACCESS),
+
+       AR_INTR_SYNC_SPURIOUS = 0xFFFFFFFF,
+
+};
+
+#define AR_INTR_ASYNC_MASK                       0x4030
+#define AR_INTR_ASYNC_MASK_GPIO                  0xFFFC0000
+#define AR_INTR_ASYNC_MASK_GPIO_S                18
+
+#define AR_INTR_SYNC_MASK                        0x4034
+#define AR_INTR_SYNC_MASK_GPIO                   0xFFFC0000
+#define AR_INTR_SYNC_MASK_GPIO_S                 18
+
+#define AR_INTR_ASYNC_CAUSE_CLR                  0x4038
+#define AR_INTR_ASYNC_CAUSE                      0x4038
+
+#define AR_INTR_ASYNC_ENABLE                     0x403c
+#define AR_INTR_ASYNC_ENABLE_GPIO                0xFFFC0000
+#define AR_INTR_ASYNC_ENABLE_GPIO_S              18
+
+#define AR_PCIE_SERDES                           0x4040
+#define AR_PCIE_SERDES2                          0x4044
+#define AR_PCIE_PM_CTRL                          0x4014
+#define AR_PCIE_PM_CTRL_ENA                      0x00080000
+
+#define AR_NUM_GPIO                              14
+#define AR928X_NUM_GPIO                          10
+#define AR9285_NUM_GPIO                          12
+
+#define AR_GPIO_IN_OUT                           0x4048
+#define AR_GPIO_IN_VAL                           0x0FFFC000
+#define AR_GPIO_IN_VAL_S                         14
+#define AR928X_GPIO_IN_VAL                       0x000FFC00
+#define AR928X_GPIO_IN_VAL_S                     10
+#define AR9285_GPIO_IN_VAL                       0x00FFF000
+#define AR9285_GPIO_IN_VAL_S                     12
+
+#define AR_GPIO_OE_OUT                           0x404c
+#define AR_GPIO_OE_OUT_DRV                       0x3
+#define AR_GPIO_OE_OUT_DRV_NO                    0x0
+#define AR_GPIO_OE_OUT_DRV_LOW                   0x1
+#define AR_GPIO_OE_OUT_DRV_HI                    0x2
+#define AR_GPIO_OE_OUT_DRV_ALL                   0x3
+
+#define AR_GPIO_INTR_POL                         0x4050
+#define AR_GPIO_INTR_POL_VAL                     0x00001FFF
+#define AR_GPIO_INTR_POL_VAL_S                   0
+
+#define AR_GPIO_INPUT_EN_VAL                     0x4054
+#define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_DEF     0x00000004
+#define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_S       2
+#define AR_GPIO_INPUT_EN_VAL_BT_FREQUENCY_DEF    0x00000008
+#define AR_GPIO_INPUT_EN_VAL_BT_FREQUENCY_S      3
+#define AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_DEF       0x00000010
+#define AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_S         4
+#define AR_GPIO_INPUT_EN_VAL_RFSILENT_DEF        0x00000080
+#define AR_GPIO_INPUT_EN_VAL_RFSILENT_DEF_S      7
+#define AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_BB        0x00001000
+#define AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_BB_S      12
+#define AR_GPIO_INPUT_EN_VAL_RFSILENT_BB         0x00008000
+#define AR_GPIO_INPUT_EN_VAL_RFSILENT_BB_S       15
+#define AR_GPIO_RTC_RESET_OVERRIDE_ENABLE        0x00010000
+#define AR_GPIO_JTAG_DISABLE                     0x00020000
+
+#define AR_GPIO_INPUT_MUX1                       0x4058
+#define AR_GPIO_INPUT_MUX1_BT_ACTIVE             0x000f0000
+#define AR_GPIO_INPUT_MUX1_BT_ACTIVE_S           16
+
+#define AR_GPIO_INPUT_MUX2                       0x405c
+#define AR_GPIO_INPUT_MUX2_CLK25                 0x0000000f
+#define AR_GPIO_INPUT_MUX2_CLK25_S               0
+#define AR_GPIO_INPUT_MUX2_RFSILENT              0x000000f0
+#define AR_GPIO_INPUT_MUX2_RFSILENT_S            4
+#define AR_GPIO_INPUT_MUX2_RTC_RESET             0x00000f00
+#define AR_GPIO_INPUT_MUX2_RTC_RESET_S           8
+
+#define AR_GPIO_OUTPUT_MUX1                      0x4060
+#define AR_GPIO_OUTPUT_MUX2                      0x4064
+#define AR_GPIO_OUTPUT_MUX3                      0x4068
+
+#define AR_INPUT_STATE                           0x406c
+
+#define AR_EEPROM_STATUS_DATA                    0x407c
+#define AR_EEPROM_STATUS_DATA_VAL                0x0000ffff
+#define AR_EEPROM_STATUS_DATA_VAL_S              0
+#define AR_EEPROM_STATUS_DATA_BUSY               0x00010000
+#define AR_EEPROM_STATUS_DATA_BUSY_ACCESS        0x00020000
+#define AR_EEPROM_STATUS_DATA_PROT_ACCESS        0x00040000
+#define AR_EEPROM_STATUS_DATA_ABSENT_ACCESS      0x00080000
+
+#define AR_OBS                  0x4080
+
+#define AR_PCIE_MSI                              0x4094
+#define AR_PCIE_MSI_ENABLE                       0x00000001
+
+
+#define AR_RTC_9160_PLL_DIV    0x000003ff
+#define AR_RTC_9160_PLL_DIV_S   0
+#define AR_RTC_9160_PLL_REFDIV  0x00003C00
+#define AR_RTC_9160_PLL_REFDIV_S 10
+#define AR_RTC_9160_PLL_CLKSEL 0x0000C000
+#define AR_RTC_9160_PLL_CLKSEL_S 14
+
+#define AR_RTC_BASE             0x00020000
+#define AR_RTC_RC \
+       ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0000) : 0x7000)
+#define AR_RTC_RC_M            0x00000003
+#define AR_RTC_RC_MAC_WARM      0x00000001
+#define AR_RTC_RC_MAC_COLD      0x00000002
+#define AR_RTC_RC_COLD_RESET    0x00000004
+#define AR_RTC_RC_WARM_RESET    0x00000008
+
+#define AR_RTC_PLL_CONTROL \
+       ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0014) : 0x7014)
+
+#define AR_RTC_PLL_DIV          0x0000001f
+#define AR_RTC_PLL_DIV_S        0
+#define AR_RTC_PLL_DIV2         0x00000020
+#define AR_RTC_PLL_REFDIV_5     0x000000c0
+#define AR_RTC_PLL_CLKSEL       0x00000300
+#define AR_RTC_PLL_CLKSEL_S     8
+
+#define AR_RTC_RESET \
+       ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0040) : 0x7040)
+#define AR_RTC_RESET_EN                (0x00000001)
+
+#define AR_RTC_STATUS \
+       ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0044) : 0x7044)
+
+#define AR_RTC_STATUS_M \
+       ((AR_SREV_9100(ah)) ? 0x0000003f : 0x0000000f)
+
+#define AR_RTC_PM_STATUS_M      0x0000000f
+
+#define AR_RTC_STATUS_SHUTDOWN  0x00000001
+#define AR_RTC_STATUS_ON        0x00000002
+#define AR_RTC_STATUS_SLEEP     0x00000004
+#define AR_RTC_STATUS_WAKEUP    0x00000008
+
+#define AR_RTC_SLEEP_CLK \
+       ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0048) : 0x7048)
+#define AR_RTC_FORCE_DERIVED_CLK    0x2
+
+#define AR_RTC_FORCE_WAKE \
+       ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x004c) : 0x704c)
+#define AR_RTC_FORCE_WAKE_EN        0x00000001
+#define AR_RTC_FORCE_WAKE_ON_INT    0x00000002
+
+
+#define AR_RTC_INTR_CAUSE \
+       ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0050) : 0x7050)
+
+#define AR_RTC_INTR_ENABLE \
+       ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0054) : 0x7054)
+
+#define AR_RTC_INTR_MASK \
+       ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0058) : 0x7058)
+
+/* RTC_DERIVED_* - only for AR9100 */
+
+#define AR_RTC_DERIVED_CLK           (AR_RTC_BASE + 0x0038)
+#define AR_RTC_DERIVED_CLK_PERIOD    0x0000fffe
+#define AR_RTC_DERIVED_CLK_PERIOD_S  1
+
+#define        AR_SEQ_MASK     0x8060
+
+#define AR_AN_RF2G1_CH0         0x7810
+#define AR_AN_RF2G1_CH0_OB      0x03800000
+#define AR_AN_RF2G1_CH0_OB_S    23
+#define AR_AN_RF2G1_CH0_DB      0x1C000000
+#define AR_AN_RF2G1_CH0_DB_S    26
+
+#define AR_AN_RF5G1_CH0         0x7818
+#define AR_AN_RF5G1_CH0_OB5     0x00070000
+#define AR_AN_RF5G1_CH0_OB5_S   16
+#define AR_AN_RF5G1_CH0_DB5     0x00380000
+#define AR_AN_RF5G1_CH0_DB5_S   19
+
+#define AR_AN_RF2G1_CH1         0x7834
+#define AR_AN_RF2G1_CH1_OB      0x03800000
+#define AR_AN_RF2G1_CH1_OB_S    23
+#define AR_AN_RF2G1_CH1_DB      0x1C000000
+#define AR_AN_RF2G1_CH1_DB_S    26
+
+#define AR_AN_RF5G1_CH1         0x783C
+#define AR_AN_RF5G1_CH1_OB5     0x00070000
+#define AR_AN_RF5G1_CH1_OB5_S   16
+#define AR_AN_RF5G1_CH1_DB5     0x00380000
+#define AR_AN_RF5G1_CH1_DB5_S   19
+
+#define AR_AN_TOP1                  0x7890
+#define AR_AN_TOP1_DACIPMODE       0x00040000
+#define AR_AN_TOP1_DACIPMODE_S     18
+
+#define AR_AN_TOP2                  0x7894
+#define AR_AN_TOP2_XPABIAS_LVL      0xC0000000
+#define AR_AN_TOP2_XPABIAS_LVL_S    30
+#define AR_AN_TOP2_LOCALBIAS        0x00200000
+#define AR_AN_TOP2_LOCALBIAS_S      21
+#define AR_AN_TOP2_PWDCLKIND        0x00400000
+#define AR_AN_TOP2_PWDCLKIND_S      22
+
+#define AR_AN_SYNTH9            0x7868
+#define AR_AN_SYNTH9_REFDIVA    0xf8000000
+#define AR_AN_SYNTH9_REFDIVA_S  27
+
+#define AR9285_AN_RF2G1              0x7820
+#define AR9285_AN_RF2G1_ENPACAL      0x00000800
+#define AR9285_AN_RF2G1_ENPACAL_S    11
+#define AR9285_AN_RF2G1_PDPADRV1     0x02000000
+#define AR9285_AN_RF2G1_PDPADRV1_S   25
+#define AR9285_AN_RF2G1_PDPADRV2     0x01000000
+#define AR9285_AN_RF2G1_PDPADRV2_S   24
+#define AR9285_AN_RF2G1_PDPAOUT      0x00800000
+#define AR9285_AN_RF2G1_PDPAOUT_S    23
+
+
+#define AR9285_AN_RF2G2              0x7824
+#define AR9285_AN_RF2G2_OFFCAL       0x00001000
+#define AR9285_AN_RF2G2_OFFCAL_S     12
+
+#define AR9285_AN_RF2G3             0x7828
+#define AR9285_AN_RF2G3_PDVCCOMP    0x02000000
+#define AR9285_AN_RF2G3_PDVCCOMP_S  25
+#define AR9285_AN_RF2G3_OB_0    0x00E00000
+#define AR9285_AN_RF2G3_OB_0_S    21
+#define AR9285_AN_RF2G3_OB_1    0x001C0000
+#define AR9285_AN_RF2G3_OB_1_S    18
+#define AR9285_AN_RF2G3_OB_2    0x00038000
+#define AR9285_AN_RF2G3_OB_2_S    15
+#define AR9285_AN_RF2G3_OB_3    0x00007000
+#define AR9285_AN_RF2G3_OB_3_S    12
+#define AR9285_AN_RF2G3_OB_4    0x00000E00
+#define AR9285_AN_RF2G3_OB_4_S    9
+
+#define AR9285_AN_RF2G3_DB1_0    0x000001C0
+#define AR9285_AN_RF2G3_DB1_0_S    6
+#define AR9285_AN_RF2G3_DB1_1    0x00000038
+#define AR9285_AN_RF2G3_DB1_1_S    3
+#define AR9285_AN_RF2G3_DB1_2    0x00000007
+#define AR9285_AN_RF2G3_DB1_2_S    0
+#define AR9285_AN_RF2G4         0x782C
+#define AR9285_AN_RF2G4_DB1_3    0xE0000000
+#define AR9285_AN_RF2G4_DB1_3_S    29
+#define AR9285_AN_RF2G4_DB1_4    0x1C000000
+#define AR9285_AN_RF2G4_DB1_4_S    26
+
+#define AR9285_AN_RF2G4_DB2_0    0x03800000
+#define AR9285_AN_RF2G4_DB2_0_S    23
+#define AR9285_AN_RF2G4_DB2_1    0x00700000
+#define AR9285_AN_RF2G4_DB2_1_S    20
+#define AR9285_AN_RF2G4_DB2_2    0x000E0000
+#define AR9285_AN_RF2G4_DB2_2_S    17
+#define AR9285_AN_RF2G4_DB2_3    0x0001C000
+#define AR9285_AN_RF2G4_DB2_3_S    14
+#define AR9285_AN_RF2G4_DB2_4    0x00003800
+#define AR9285_AN_RF2G4_DB2_4_S    11
+
+#define AR9285_AN_RF2G6                 0x7834
+#define AR9285_AN_RF2G6_CCOMP           0x00007800
+#define AR9285_AN_RF2G6_CCOMP_S         11
+#define AR9285_AN_RF2G6_OFFS            0x03f00000
+#define AR9285_AN_RF2G6_OFFS_S          20
+
+#define AR9285_AN_RF2G7                 0x7838
+#define AR9285_AN_RF2G7_PWDDB           0x00000002
+#define AR9285_AN_RF2G7_PWDDB_S         1
+#define AR9285_AN_RF2G7_PADRVGN2TAB0    0xE0000000
+#define AR9285_AN_RF2G7_PADRVGN2TAB0_S  29
+
+#define AR9285_AN_RF2G8                  0x783C
+#define AR9285_AN_RF2G8_PADRVGN2TAB0     0x0001C000
+#define AR9285_AN_RF2G8_PADRVGN2TAB0_S   14
+
+
+#define AR9285_AN_RF2G9          0x7840
+#define AR9285_AN_RXTXBB1              0x7854
+#define AR9285_AN_RXTXBB1_PDRXTXBB1    0x00000020
+#define AR9285_AN_RXTXBB1_PDRXTXBB1_S  5
+#define AR9285_AN_RXTXBB1_PDV2I        0x00000080
+#define AR9285_AN_RXTXBB1_PDV2I_S      7
+#define AR9285_AN_RXTXBB1_PDDACIF      0x00000100
+#define AR9285_AN_RXTXBB1_PDDACIF_S    8
+#define AR9285_AN_RXTXBB1_SPARE9       0x00000001
+#define AR9285_AN_RXTXBB1_SPARE9_S     0
+
+#define AR9285_AN_TOP2           0x7868
+
+#define AR9285_AN_TOP3                  0x786c
+#define AR9285_AN_TOP3_XPABIAS_LVL      0x0000000C
+#define AR9285_AN_TOP3_XPABIAS_LVL_S    2
+#define AR9285_AN_TOP3_PWDDAC           0x00800000
+#define AR9285_AN_TOP3_PWDDAC_S    23
+
+#define AR9285_AN_TOP4           0x7870
+#define AR9285_AN_TOP4_DEFAULT   0x10142c00
+
+#define AR_STA_ID0                 0x8000
+#define AR_STA_ID1                 0x8004
+#define AR_STA_ID1_SADH_MASK       0x0000FFFF
+#define AR_STA_ID1_STA_AP          0x00010000
+#define AR_STA_ID1_ADHOC           0x00020000
+#define AR_STA_ID1_PWR_SAV         0x00040000
+#define AR_STA_ID1_KSRCHDIS        0x00080000
+#define AR_STA_ID1_PCF             0x00100000
+#define AR_STA_ID1_USE_DEFANT      0x00200000
+#define AR_STA_ID1_DEFANT_UPDATE   0x00400000
+#define AR_STA_ID1_RTS_USE_DEF     0x00800000
+#define AR_STA_ID1_ACKCTS_6MB      0x01000000
+#define AR_STA_ID1_BASE_RATE_11B   0x02000000
+#define AR_STA_ID1_SECTOR_SELF_GEN 0x04000000
+#define AR_STA_ID1_CRPT_MIC_ENABLE 0x08000000
+#define AR_STA_ID1_KSRCH_MODE      0x10000000
+#define AR_STA_ID1_PRESERVE_SEQNUM 0x20000000
+#define AR_STA_ID1_CBCIV_ENDIAN    0x40000000
+#define AR_STA_ID1_MCAST_KSRCH     0x80000000
+
+#define AR_BSS_ID0          0x8008
+#define AR_BSS_ID1          0x800C
+#define AR_BSS_ID1_U16       0x0000FFFF
+#define AR_BSS_ID1_AID       0x07FF0000
+#define AR_BSS_ID1_AID_S     16
+
+#define AR_BCN_RSSI_AVE      0x8010
+#define AR_BCN_RSSI_AVE_MASK 0x00000FFF
+
+#define AR_TIME_OUT         0x8014
+#define AR_TIME_OUT_ACK      0x00003FFF
+#define AR_TIME_OUT_ACK_S    0
+#define AR_TIME_OUT_CTS      0x3FFF0000
+#define AR_TIME_OUT_CTS_S    16
+
+#define AR_RSSI_THR          0x8018
+#define AR_RSSI_THR_MASK     0x000000FF
+#define AR_RSSI_THR_BM_THR   0x0000FF00
+#define AR_RSSI_THR_BM_THR_S 8
+#define AR_RSSI_BCN_WEIGHT   0x1F000000
+#define AR_RSSI_BCN_WEIGHT_S 24
+#define AR_RSSI_BCN_RSSI_RST 0x20000000
+
+#define AR_USEC              0x801c
+#define AR_USEC_USEC         0x0000007F
+#define AR_USEC_TX_LAT       0x007FC000
+#define AR_USEC_TX_LAT_S     14
+#define AR_USEC_RX_LAT       0x1F800000
+#define AR_USEC_RX_LAT_S     23
+
+#define AR_RESET_TSF        0x8020
+#define AR_RESET_TSF_ONCE   0x01000000
+
+#define AR_MAX_CFP_DUR      0x8038
+#define AR_CFP_VAL          0x0000FFFF
+
+#define AR_RX_FILTER        0x803C
+#define AR_RX_COMPR_BAR     0x00000400
+
+#define AR_MCAST_FIL0       0x8040
+#define AR_MCAST_FIL1       0x8044
+
+#define AR_DIAG_SW                  0x8048
+#define AR_DIAG_CACHE_ACK           0x00000001
+#define AR_DIAG_ACK_DIS             0x00000002
+#define AR_DIAG_CTS_DIS             0x00000004
+#define AR_DIAG_ENCRYPT_DIS         0x00000008
+#define AR_DIAG_DECRYPT_DIS         0x00000010
+#define AR_DIAG_RX_DIS              0x00000020
+#define AR_DIAG_LOOP_BACK           0x00000040
+#define AR_DIAG_CORR_FCS            0x00000080
+#define AR_DIAG_CHAN_INFO           0x00000100
+#define AR_DIAG_SCRAM_SEED          0x0001FE00
+#define AR_DIAG_SCRAM_SEED_S        8
+#define AR_DIAG_FRAME_NV0           0x00020000
+#define AR_DIAG_OBS_PT_SEL1         0x000C0000
+#define AR_DIAG_OBS_PT_SEL1_S       18
+#define AR_DIAG_FORCE_RX_CLEAR      0x00100000
+#define AR_DIAG_IGNORE_VIRT_CS      0x00200000
+#define AR_DIAG_FORCE_CH_IDLE_HIGH  0x00400000
+#define AR_DIAG_EIFS_CTRL_ENA       0x00800000
+#define AR_DIAG_DUAL_CHAIN_INFO     0x01000000
+#define AR_DIAG_RX_ABORT            0x02000000
+#define AR_DIAG_SATURATE_CYCLE_CNT  0x04000000
+#define AR_DIAG_OBS_PT_SEL2         0x08000000
+#define AR_DIAG_RX_CLEAR_CTL_LOW    0x10000000
+#define AR_DIAG_RX_CLEAR_EXT_LOW    0x20000000
+
+#define AR_TSF_L32          0x804c
+#define AR_TSF_U32          0x8050
+
+#define AR_TST_ADDAC        0x8054
+#define AR_DEF_ANTENNA      0x8058
+
+#define AR_AES_MUTE_MASK0       0x805c
+#define AR_AES_MUTE_MASK0_FC    0x0000FFFF
+#define AR_AES_MUTE_MASK0_QOS   0xFFFF0000
+#define AR_AES_MUTE_MASK0_QOS_S 16
+
+#define AR_AES_MUTE_MASK1       0x8060
+#define AR_AES_MUTE_MASK1_SEQ   0x0000FFFF
+#define AR_AES_MUTE_MASK1_FC_MGMT 0xFFFF0000
+#define AR_AES_MUTE_MASK1_FC_MGMT_S 16
+
+#define AR_GATED_CLKS       0x8064
+#define AR_GATED_CLKS_TX    0x00000002
+#define AR_GATED_CLKS_RX    0x00000004
+#define AR_GATED_CLKS_REG   0x00000008
+
+#define AR_OBS_BUS_CTRL     0x8068
+#define AR_OBS_BUS_SEL_1    0x00040000
+#define AR_OBS_BUS_SEL_2    0x00080000
+#define AR_OBS_BUS_SEL_3    0x000C0000
+#define AR_OBS_BUS_SEL_4    0x08040000
+#define AR_OBS_BUS_SEL_5    0x08080000
+
+#define AR_OBS_BUS_1               0x806c
+#define AR_OBS_BUS_1_PCU           0x00000001
+#define AR_OBS_BUS_1_RX_END        0x00000002
+#define AR_OBS_BUS_1_RX_WEP        0x00000004
+#define AR_OBS_BUS_1_RX_BEACON     0x00000008
+#define AR_OBS_BUS_1_RX_FILTER     0x00000010
+#define AR_OBS_BUS_1_TX_HCF        0x00000020
+#define AR_OBS_BUS_1_QUIET_TIME    0x00000040
+#define AR_OBS_BUS_1_CHAN_IDLE     0x00000080
+#define AR_OBS_BUS_1_TX_HOLD       0x00000100
+#define AR_OBS_BUS_1_TX_FRAME      0x00000200
+#define AR_OBS_BUS_1_RX_FRAME      0x00000400
+#define AR_OBS_BUS_1_RX_CLEAR      0x00000800
+#define AR_OBS_BUS_1_WEP_STATE     0x0003F000
+#define AR_OBS_BUS_1_WEP_STATE_S   12
+#define AR_OBS_BUS_1_RX_STATE      0x01F00000
+#define AR_OBS_BUS_1_RX_STATE_S    20
+#define AR_OBS_BUS_1_TX_STATE      0x7E000000
+#define AR_OBS_BUS_1_TX_STATE_S    25
+
+#define AR_LAST_TSTP        0x8080
+#define AR_NAV              0x8084
+#define AR_RTS_OK           0x8088
+#define AR_RTS_FAIL         0x808c
+#define AR_ACK_FAIL         0x8090
+#define AR_FCS_FAIL         0x8094
+#define AR_BEACON_CNT       0x8098
+
+#define AR_SLEEP1               0x80d4
+#define AR_SLEEP1_ASSUME_DTIM   0x00080000
+#define AR_SLEEP1_CAB_TIMEOUT   0xFFE00000
+#define AR_SLEEP1_CAB_TIMEOUT_S 21
+
+#define AR_SLEEP2                   0x80d8
+#define AR_SLEEP2_BEACON_TIMEOUT    0xFFE00000
+#define AR_SLEEP2_BEACON_TIMEOUT_S  21
+
+#define AR_BSSMSKL            0x80e0
+#define AR_BSSMSKU            0x80e4
+
+#define AR_TPC                 0x80e8
+#define AR_TPC_ACK             0x0000003f
+#define AR_TPC_ACK_S           0x00
+#define AR_TPC_CTS             0x00003f00
+#define AR_TPC_CTS_S           0x08
+#define AR_TPC_CHIRP           0x003f0000
+#define AR_TPC_CHIRP_S         0x16
+
+#define AR_TFCNT           0x80ec
+#define AR_RFCNT           0x80f0
+#define AR_RCCNT           0x80f4
+#define AR_CCCNT           0x80f8
+
+#define AR_QUIET1          0x80fc
+#define AR_QUIET1_NEXT_QUIET_S         0
+#define AR_QUIET1_NEXT_QUIET_M         0x0000ffff
+#define AR_QUIET1_QUIET_ENABLE         0x00010000
+#define AR_QUIET1_QUIET_ACK_CTS_ENABLE 0x00020000
+#define AR_QUIET2          0x8100
+#define AR_QUIET2_QUIET_PERIOD_S       0
+#define AR_QUIET2_QUIET_PERIOD_M       0x0000ffff
+#define AR_QUIET2_QUIET_DUR_S     16
+#define AR_QUIET2_QUIET_DUR       0xffff0000
+
+#define AR_TSF_PARM        0x8104
+#define AR_TSF_INCREMENT_M     0x000000ff
+#define AR_TSF_INCREMENT_S     0x00
+
+#define AR_QOS_NO_ACK              0x8108
+#define AR_QOS_NO_ACK_TWO_BIT      0x0000000f
+#define AR_QOS_NO_ACK_TWO_BIT_S    0
+#define AR_QOS_NO_ACK_BIT_OFF      0x00000070
+#define AR_QOS_NO_ACK_BIT_OFF_S    4
+#define AR_QOS_NO_ACK_BYTE_OFF     0x00000180
+#define AR_QOS_NO_ACK_BYTE_OFF_S   7
+
+#define AR_PHY_ERR         0x810c
+
+#define AR_PHY_ERR_DCHIRP      0x00000008
+#define AR_PHY_ERR_RADAR       0x00000020
+#define AR_PHY_ERR_OFDM_TIMING 0x00020000
+#define AR_PHY_ERR_CCK_TIMING  0x02000000
+
+#define AR_RXFIFO_CFG          0x8114
+
+
+#define AR_MIC_QOS_CONTROL 0x8118
+#define AR_MIC_QOS_SELECT  0x811c
+
+#define AR_PCU_MISC                0x8120
+#define AR_PCU_FORCE_BSSID_MATCH   0x00000001
+#define AR_PCU_MIC_NEW_LOC_ENA     0x00000004
+#define AR_PCU_TX_ADD_TSF          0x00000008
+#define AR_PCU_CCK_SIFS_MODE       0x00000010
+#define AR_PCU_RX_ANT_UPDT         0x00000800
+#define AR_PCU_TXOP_TBTT_LIMIT_ENA 0x00001000
+#define AR_PCU_MISS_BCN_IN_SLEEP   0x00004000
+#define AR_PCU_BUG_12306_FIX_ENA   0x00020000
+#define AR_PCU_FORCE_QUIET_COLL    0x00040000
+#define AR_PCU_TBTT_PROTECT        0x00200000
+#define AR_PCU_CLEAR_VMF           0x01000000
+#define AR_PCU_CLEAR_BA_VALID      0x04000000
+
+
+#define AR_FILT_OFDM           0x8124
+#define AR_FILT_OFDM_COUNT     0x00FFFFFF
+
+#define AR_FILT_CCK            0x8128
+#define AR_FILT_CCK_COUNT      0x00FFFFFF
+
+#define AR_PHY_ERR_1           0x812c
+#define AR_PHY_ERR_1_COUNT     0x00FFFFFF
+#define AR_PHY_ERR_MASK_1      0x8130
+
+#define AR_PHY_ERR_2           0x8134
+#define AR_PHY_ERR_2_COUNT     0x00FFFFFF
+#define AR_PHY_ERR_MASK_2      0x8138
+
+#define AR_PHY_COUNTMAX        (3 << 22)
+#define AR_MIBCNT_INTRMASK     (3 << 22)
+
+#define AR_TSFOOR_THRESHOLD       0x813c
+#define AR_TSFOOR_THRESHOLD_VAL   0x0000FFFF
+
+#define AR_PHY_ERR_EIFS_MASK   8144
+
+#define AR_PHY_ERR_3           0x8168
+#define AR_PHY_ERR_3_COUNT     0x00FFFFFF
+#define AR_PHY_ERR_MASK_3      0x816c
+
+#define AR_TXSIFS              0x81d0
+#define AR_TXSIFS_TIME         0x000000FF
+#define AR_TXSIFS_TX_LATENCY   0x00000F00
+#define AR_TXSIFS_TX_LATENCY_S 8
+#define AR_TXSIFS_ACK_SHIFT    0x00007000
+#define AR_TXSIFS_ACK_SHIFT_S  12
+
+#define AR_TXOP_X          0x81ec
+#define AR_TXOP_X_VAL      0x000000FF
+
+
+#define AR_TXOP_0_3    0x81f0
+#define AR_TXOP_4_7    0x81f4
+#define AR_TXOP_8_11   0x81f8
+#define AR_TXOP_12_15  0x81fc
+
+
+#define AR_NEXT_TBTT_TIMER                  0x8200
+#define AR_NEXT_DMA_BEACON_ALERT            0x8204
+#define AR_NEXT_SWBA                        0x8208
+#define AR_NEXT_CFP                         0x8208
+#define AR_NEXT_HCF                         0x820C
+#define AR_NEXT_TIM                         0x8210
+#define AR_NEXT_DTIM                        0x8214
+#define AR_NEXT_QUIET_TIMER                 0x8218
+#define AR_NEXT_NDP_TIMER                   0x821C
+
+#define AR_BEACON_PERIOD                    0x8220
+#define AR_DMA_BEACON_PERIOD                0x8224
+#define AR_SWBA_PERIOD                      0x8228
+#define AR_HCF_PERIOD                       0x822C
+#define AR_TIM_PERIOD                       0x8230
+#define AR_DTIM_PERIOD                      0x8234
+#define AR_QUIET_PERIOD                     0x8238
+#define AR_NDP_PERIOD                       0x823C
+
+#define AR_TIMER_MODE                       0x8240
+#define AR_TBTT_TIMER_EN                    0x00000001
+#define AR_DBA_TIMER_EN                     0x00000002
+#define AR_SWBA_TIMER_EN                    0x00000004
+#define AR_HCF_TIMER_EN                     0x00000008
+#define AR_TIM_TIMER_EN                     0x00000010
+#define AR_DTIM_TIMER_EN                    0x00000020
+#define AR_QUIET_TIMER_EN                   0x00000040
+#define AR_NDP_TIMER_EN                     0x00000080
+#define AR_TIMER_OVERFLOW_INDEX             0x00000700
+#define AR_TIMER_OVERFLOW_INDEX_S           8
+#define AR_TIMER_THRESH                     0xFFFFF000
+#define AR_TIMER_THRESH_S                   12
+
+#define AR_SLP32_MODE                  0x8244
+#define AR_SLP32_HALF_CLK_LATENCY      0x000FFFFF
+#define AR_SLP32_ENA                   0x00100000
+#define AR_SLP32_TSF_WRITE_STATUS      0x00200000
+
+#define AR_SLP32_WAKE              0x8248
+#define AR_SLP32_WAKE_XTL_TIME     0x0000FFFF
+
+#define AR_SLP32_INC               0x824c
+#define AR_SLP32_TST_INC           0x000FFFFF
+
+#define AR_SLP_CNT         0x8250
+#define AR_SLP_CYCLE_CNT   0x8254
+
+#define AR_SLP_MIB_CTRL    0x8258
+#define AR_SLP_MIB_CLEAR   0x00000001
+#define AR_SLP_MIB_PENDING 0x00000002
+
+#define AR_2040_MODE                0x8318
+#define AR_2040_JOINED_RX_CLEAR 0x00000001
+
+
+#define AR_EXTRCCNT         0x8328
+
+#define AR_SELFGEN_MASK         0x832c
+
+#define AR_PCU_TXBUF_CTRL               0x8340
+#define AR_PCU_TXBUF_CTRL_SIZE_MASK     0x7FF
+#define AR_PCU_TXBUF_CTRL_USABLE_SIZE   0x700
+#define AR_9285_PCU_TXBUF_CTRL_USABLE_SIZE   0x380
+
+#define AR_PCU_MISC_MODE2               0x8344
+#define AR_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE           0x00000002
+#define AR_PCU_MISC_MODE2_NO_CRYPTO_FOR_NON_DATA_PKT   0x00000004
+
+#define AR_KEYTABLE_0           0x8800
+#define AR_KEYTABLE(_n)         (AR_KEYTABLE_0 + ((_n)*32))
+#define AR_KEY_CACHE_SIZE       128
+#define AR_RSVD_KEYTABLE_ENTRIES 4
+#define AR_KEY_TYPE             0x00000007
+#define AR_KEYTABLE_TYPE_40     0x00000000
+#define AR_KEYTABLE_TYPE_104    0x00000001
+#define AR_KEYTABLE_TYPE_128    0x00000003
+#define AR_KEYTABLE_TYPE_TKIP   0x00000004
+#define AR_KEYTABLE_TYPE_AES    0x00000005
+#define AR_KEYTABLE_TYPE_CCM    0x00000006
+#define AR_KEYTABLE_TYPE_CLR    0x00000007
+#define AR_KEYTABLE_ANT         0x00000008
+#define AR_KEYTABLE_VALID       0x00008000
+#define AR_KEYTABLE_KEY0(_n)    (AR_KEYTABLE(_n) + 0)
+#define AR_KEYTABLE_KEY1(_n)    (AR_KEYTABLE(_n) + 4)
+#define AR_KEYTABLE_KEY2(_n)    (AR_KEYTABLE(_n) + 8)
+#define AR_KEYTABLE_KEY3(_n)    (AR_KEYTABLE(_n) + 12)
+#define AR_KEYTABLE_KEY4(_n)    (AR_KEYTABLE(_n) + 16)
+#define AR_KEYTABLE_TYPE(_n)    (AR_KEYTABLE(_n) + 20)
+#define AR_KEYTABLE_MAC0(_n)    (AR_KEYTABLE(_n) + 24)
+#define AR_KEYTABLE_MAC1(_n)    (AR_KEYTABLE(_n) + 28)
+
+#endif
diff --git a/drivers/net/wireless/ath/ath9k/virtual.c b/drivers/net/wireless/ath/ath9k/virtual.c
new file mode 100644 (file)
index 0000000..1ff429b
--- /dev/null
@@ -0,0 +1,662 @@
+/*
+ * Copyright (c) 2008-2009 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 "ath9k.h"
+
+struct ath9k_vif_iter_data {
+       int count;
+       u8 *addr;
+};
+
+static void ath9k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
+{
+       struct ath9k_vif_iter_data *iter_data = data;
+       u8 *nbuf;
+
+       nbuf = krealloc(iter_data->addr, (iter_data->count + 1) * ETH_ALEN,
+                       GFP_ATOMIC);
+       if (nbuf == NULL)
+               return;
+
+       memcpy(nbuf + iter_data->count * ETH_ALEN, mac, ETH_ALEN);
+       iter_data->addr = nbuf;
+       iter_data->count++;
+}
+
+void ath9k_set_bssid_mask(struct ieee80211_hw *hw)
+{
+       struct ath_wiphy *aphy = hw->priv;
+       struct ath_softc *sc = aphy->sc;
+       struct ath9k_vif_iter_data iter_data;
+       int i, j;
+       u8 mask[ETH_ALEN];
+
+       /*
+        * Add primary MAC address even if it is not in active use since it
+        * will be configured to the hardware as the starting point and the
+        * BSSID mask will need to be changed if another address is active.
+        */
+       iter_data.addr = kmalloc(ETH_ALEN, GFP_ATOMIC);
+       if (iter_data.addr) {
+               memcpy(iter_data.addr, sc->sc_ah->macaddr, ETH_ALEN);
+               iter_data.count = 1;
+       } else
+               iter_data.count = 0;
+
+       /* Get list of all active MAC addresses */
+       spin_lock_bh(&sc->wiphy_lock);
+       ieee80211_iterate_active_interfaces_atomic(sc->hw, ath9k_vif_iter,
+                                                  &iter_data);
+       for (i = 0; i < sc->num_sec_wiphy; i++) {
+               if (sc->sec_wiphy[i] == NULL)
+                       continue;
+               ieee80211_iterate_active_interfaces_atomic(
+                       sc->sec_wiphy[i]->hw, ath9k_vif_iter, &iter_data);
+       }
+       spin_unlock_bh(&sc->wiphy_lock);
+
+       /* Generate an address mask to cover all active addresses */
+       memset(mask, 0, ETH_ALEN);
+       for (i = 0; i < iter_data.count; i++) {
+               u8 *a1 = iter_data.addr + i * ETH_ALEN;
+               for (j = i + 1; j < iter_data.count; j++) {
+                       u8 *a2 = iter_data.addr + j * ETH_ALEN;
+                       mask[0] |= a1[0] ^ a2[0];
+                       mask[1] |= a1[1] ^ a2[1];
+                       mask[2] |= a1[2] ^ a2[2];
+                       mask[3] |= a1[3] ^ a2[3];
+                       mask[4] |= a1[4] ^ a2[4];
+                       mask[5] |= a1[5] ^ a2[5];
+               }
+       }
+
+       kfree(iter_data.addr);
+
+       /* Invert the mask and configure hardware */
+       sc->bssidmask[0] = ~mask[0];
+       sc->bssidmask[1] = ~mask[1];
+       sc->bssidmask[2] = ~mask[2];
+       sc->bssidmask[3] = ~mask[3];
+       sc->bssidmask[4] = ~mask[4];
+       sc->bssidmask[5] = ~mask[5];
+
+       ath9k_hw_setbssidmask(sc);
+}
+
+int ath9k_wiphy_add(struct ath_softc *sc)
+{
+       int i, error;
+       struct ath_wiphy *aphy;
+       struct ieee80211_hw *hw;
+       u8 addr[ETH_ALEN];
+
+       hw = ieee80211_alloc_hw(sizeof(struct ath_wiphy), &ath9k_ops);
+       if (hw == NULL)
+               return -ENOMEM;
+
+       spin_lock_bh(&sc->wiphy_lock);
+       for (i = 0; i < sc->num_sec_wiphy; i++) {
+               if (sc->sec_wiphy[i] == NULL)
+                       break;
+       }
+
+       if (i == sc->num_sec_wiphy) {
+               /* No empty slot available; increase array length */
+               struct ath_wiphy **n;
+               n = krealloc(sc->sec_wiphy,
+                            (sc->num_sec_wiphy + 1) *
+                            sizeof(struct ath_wiphy *),
+                            GFP_ATOMIC);
+               if (n == NULL) {
+                       spin_unlock_bh(&sc->wiphy_lock);
+                       ieee80211_free_hw(hw);
+                       return -ENOMEM;
+               }
+               n[i] = NULL;
+               sc->sec_wiphy = n;
+               sc->num_sec_wiphy++;
+       }
+
+       SET_IEEE80211_DEV(hw, sc->dev);
+
+       aphy = hw->priv;
+       aphy->sc = sc;
+       aphy->hw = hw;
+       sc->sec_wiphy[i] = aphy;
+       spin_unlock_bh(&sc->wiphy_lock);
+
+       memcpy(addr, sc->sc_ah->macaddr, ETH_ALEN);
+       addr[0] |= 0x02; /* Locally managed address */
+       /*
+        * XOR virtual wiphy index into the least significant bits to generate
+        * a different MAC address for each virtual wiphy.
+        */
+       addr[5] ^= i & 0xff;
+       addr[4] ^= (i & 0xff00) >> 8;
+       addr[3] ^= (i & 0xff0000) >> 16;
+
+       SET_IEEE80211_PERM_ADDR(hw, addr);
+
+       ath_set_hw_capab(sc, hw);
+
+       error = ieee80211_register_hw(hw);
+
+       if (error == 0) {
+               /* Make sure wiphy scheduler is started (if enabled) */
+               ath9k_wiphy_set_scheduler(sc, sc->wiphy_scheduler_int);
+       }
+
+       return error;
+}
+
+int ath9k_wiphy_del(struct ath_wiphy *aphy)
+{
+       struct ath_softc *sc = aphy->sc;
+       int i;
+
+       spin_lock_bh(&sc->wiphy_lock);
+       for (i = 0; i < sc->num_sec_wiphy; i++) {
+               if (aphy == sc->sec_wiphy[i]) {
+                       sc->sec_wiphy[i] = NULL;
+                       spin_unlock_bh(&sc->wiphy_lock);
+                       ieee80211_unregister_hw(aphy->hw);
+                       ieee80211_free_hw(aphy->hw);
+                       return 0;
+               }
+       }
+       spin_unlock_bh(&sc->wiphy_lock);
+       return -ENOENT;
+}
+
+static int ath9k_send_nullfunc(struct ath_wiphy *aphy,
+                              struct ieee80211_vif *vif, const u8 *bssid,
+                              int ps)
+{
+       struct ath_softc *sc = aphy->sc;
+       struct ath_tx_control txctl;
+       struct sk_buff *skb;
+       struct ieee80211_hdr *hdr;
+       __le16 fc;
+       struct ieee80211_tx_info *info;
+
+       skb = dev_alloc_skb(24);
+       if (skb == NULL)
+               return -ENOMEM;
+       hdr = (struct ieee80211_hdr *) skb_put(skb, 24);
+       memset(hdr, 0, 24);
+       fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC |
+                        IEEE80211_FCTL_TODS);
+       if (ps)
+               fc |= cpu_to_le16(IEEE80211_FCTL_PM);
+       hdr->frame_control = fc;
+       memcpy(hdr->addr1, bssid, ETH_ALEN);
+       memcpy(hdr->addr2, aphy->hw->wiphy->perm_addr, ETH_ALEN);
+       memcpy(hdr->addr3, bssid, ETH_ALEN);
+
+       info = IEEE80211_SKB_CB(skb);
+       memset(info, 0, sizeof(*info));
+       info->flags = IEEE80211_TX_CTL_REQ_TX_STATUS;
+       info->control.vif = vif;
+       info->control.rates[0].idx = 0;
+       info->control.rates[0].count = 4;
+       info->control.rates[1].idx = -1;
+
+       memset(&txctl, 0, sizeof(struct ath_tx_control));
+       txctl.txq = &sc->tx.txq[sc->tx.hwq_map[ATH9K_WME_AC_VO]];
+       txctl.frame_type = ps ? ATH9K_INT_PAUSE : ATH9K_INT_UNPAUSE;
+
+       if (ath_tx_start(aphy->hw, skb, &txctl) != 0)
+               goto exit;
+
+       return 0;
+exit:
+       dev_kfree_skb_any(skb);
+       return -1;
+}
+
+static bool __ath9k_wiphy_pausing(struct ath_softc *sc)
+{
+       int i;
+       if (sc->pri_wiphy->state == ATH_WIPHY_PAUSING)
+               return true;
+       for (i = 0; i < sc->num_sec_wiphy; i++) {
+               if (sc->sec_wiphy[i] &&
+                   sc->sec_wiphy[i]->state == ATH_WIPHY_PAUSING)
+                       return true;
+       }
+       return false;
+}
+
+static bool ath9k_wiphy_pausing(struct ath_softc *sc)
+{
+       bool ret;
+       spin_lock_bh(&sc->wiphy_lock);
+       ret = __ath9k_wiphy_pausing(sc);
+       spin_unlock_bh(&sc->wiphy_lock);
+       return ret;
+}
+
+static bool __ath9k_wiphy_scanning(struct ath_softc *sc)
+{
+       int i;
+       if (sc->pri_wiphy->state == ATH_WIPHY_SCAN)
+               return true;
+       for (i = 0; i < sc->num_sec_wiphy; i++) {
+               if (sc->sec_wiphy[i] &&
+                   sc->sec_wiphy[i]->state == ATH_WIPHY_SCAN)
+                       return true;
+       }
+       return false;
+}
+
+bool ath9k_wiphy_scanning(struct ath_softc *sc)
+{
+       bool ret;
+       spin_lock_bh(&sc->wiphy_lock);
+       ret = __ath9k_wiphy_scanning(sc);
+       spin_unlock_bh(&sc->wiphy_lock);
+       return ret;
+}
+
+static int __ath9k_wiphy_unpause(struct ath_wiphy *aphy);
+
+/* caller must hold wiphy_lock */
+static void __ath9k_wiphy_unpause_ch(struct ath_wiphy *aphy)
+{
+       if (aphy == NULL)
+               return;
+       if (aphy->chan_idx != aphy->sc->chan_idx)
+               return; /* wiphy not on the selected channel */
+       __ath9k_wiphy_unpause(aphy);
+}
+
+static void ath9k_wiphy_unpause_channel(struct ath_softc *sc)
+{
+       int i;
+       spin_lock_bh(&sc->wiphy_lock);
+       __ath9k_wiphy_unpause_ch(sc->pri_wiphy);
+       for (i = 0; i < sc->num_sec_wiphy; i++)
+               __ath9k_wiphy_unpause_ch(sc->sec_wiphy[i]);
+       spin_unlock_bh(&sc->wiphy_lock);
+}
+
+void ath9k_wiphy_chan_work(struct work_struct *work)
+{
+       struct ath_softc *sc = container_of(work, struct ath_softc, chan_work);
+       struct ath_wiphy *aphy = sc->next_wiphy;
+
+       if (aphy == NULL)
+               return;
+
+       /*
+        * All pending interfaces paused; ready to change
+        * channels.
+        */
+
+       /* Change channels */
+       mutex_lock(&sc->mutex);
+       /* XXX: remove me eventually */
+       ath9k_update_ichannel(sc, aphy->hw,
+                             &sc->sc_ah->channels[sc->chan_idx]);
+       ath_update_chainmask(sc, sc->chan_is_ht);
+       if (ath_set_channel(sc, aphy->hw,
+                           &sc->sc_ah->channels[sc->chan_idx]) < 0) {
+               printk(KERN_DEBUG "ath9k: Failed to set channel for new "
+                      "virtual wiphy\n");
+               mutex_unlock(&sc->mutex);
+               return;
+       }
+       mutex_unlock(&sc->mutex);
+
+       ath9k_wiphy_unpause_channel(sc);
+}
+
+/*
+ * ath9k version of ieee80211_tx_status() for TX frames that are generated
+ * internally in the driver.
+ */
+void ath9k_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
+{
+       struct ath_wiphy *aphy = hw->priv;
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+       struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
+
+       if (tx_info_priv && tx_info_priv->frame_type == ATH9K_INT_PAUSE &&
+           aphy->state == ATH_WIPHY_PAUSING) {
+               if (!(info->flags & IEEE80211_TX_STAT_ACK)) {
+                       printk(KERN_DEBUG "ath9k: %s: no ACK for pause "
+                              "frame\n", wiphy_name(hw->wiphy));
+                       /*
+                        * The AP did not reply; ignore this to allow us to
+                        * continue.
+                        */
+               }
+               aphy->state = ATH_WIPHY_PAUSED;
+               if (!ath9k_wiphy_pausing(aphy->sc)) {
+                       /*
+                        * Drop from tasklet to work to allow mutex for channel
+                        * change.
+                        */
+                       queue_work(aphy->sc->hw->workqueue,
+                                  &aphy->sc->chan_work);
+               }
+       }
+
+       kfree(tx_info_priv);
+       tx_info->rate_driver_data[0] = NULL;
+
+       dev_kfree_skb(skb);
+}
+
+static void ath9k_mark_paused(struct ath_wiphy *aphy)
+{
+       struct ath_softc *sc = aphy->sc;
+       aphy->state = ATH_WIPHY_PAUSED;
+       if (!__ath9k_wiphy_pausing(sc))
+               queue_work(sc->hw->workqueue, &sc->chan_work);
+}
+
+static void ath9k_pause_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
+{
+       struct ath_wiphy *aphy = data;
+       struct ath_vif *avp = (void *) vif->drv_priv;
+
+       switch (vif->type) {
+       case NL80211_IFTYPE_STATION:
+               if (!vif->bss_conf.assoc) {
+                       ath9k_mark_paused(aphy);
+                       break;
+               }
+               /* TODO: could avoid this if already in PS mode */
+               if (ath9k_send_nullfunc(aphy, vif, avp->bssid, 1)) {
+                       printk(KERN_DEBUG "%s: failed to send PS nullfunc\n",
+                              __func__);
+                       ath9k_mark_paused(aphy);
+               }
+               break;
+       case NL80211_IFTYPE_AP:
+               /* Beacon transmission is paused by aphy->state change */
+               ath9k_mark_paused(aphy);
+               break;
+       default:
+               break;
+       }
+}
+
+/* caller must hold wiphy_lock */
+static int __ath9k_wiphy_pause(struct ath_wiphy *aphy)
+{
+       ieee80211_stop_queues(aphy->hw);
+       aphy->state = ATH_WIPHY_PAUSING;
+       /*
+        * TODO: handle PAUSING->PAUSED for the case where there are multiple
+        * active vifs (now we do it on the first vif getting ready; should be
+        * on the last)
+        */
+       ieee80211_iterate_active_interfaces_atomic(aphy->hw, ath9k_pause_iter,
+                                                  aphy);
+       return 0;
+}
+
+int ath9k_wiphy_pause(struct ath_wiphy *aphy)
+{
+       int ret;
+       spin_lock_bh(&aphy->sc->wiphy_lock);
+       ret = __ath9k_wiphy_pause(aphy);
+       spin_unlock_bh(&aphy->sc->wiphy_lock);
+       return ret;
+}
+
+static void ath9k_unpause_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
+{
+       struct ath_wiphy *aphy = data;
+       struct ath_vif *avp = (void *) vif->drv_priv;
+
+       switch (vif->type) {
+       case NL80211_IFTYPE_STATION:
+               if (!vif->bss_conf.assoc)
+                       break;
+               ath9k_send_nullfunc(aphy, vif, avp->bssid, 0);
+               break;
+       case NL80211_IFTYPE_AP:
+               /* Beacon transmission is re-enabled by aphy->state change */
+               break;
+       default:
+               break;
+       }
+}
+
+/* caller must hold wiphy_lock */
+static int __ath9k_wiphy_unpause(struct ath_wiphy *aphy)
+{
+       ieee80211_iterate_active_interfaces_atomic(aphy->hw,
+                                                  ath9k_unpause_iter, aphy);
+       aphy->state = ATH_WIPHY_ACTIVE;
+       ieee80211_wake_queues(aphy->hw);
+       return 0;
+}
+
+int ath9k_wiphy_unpause(struct ath_wiphy *aphy)
+{
+       int ret;
+       spin_lock_bh(&aphy->sc->wiphy_lock);
+       ret = __ath9k_wiphy_unpause(aphy);
+       spin_unlock_bh(&aphy->sc->wiphy_lock);
+       return ret;
+}
+
+static void __ath9k_wiphy_mark_all_paused(struct ath_softc *sc)
+{
+       int i;
+       if (sc->pri_wiphy->state != ATH_WIPHY_INACTIVE)
+               sc->pri_wiphy->state = ATH_WIPHY_PAUSED;
+       for (i = 0; i < sc->num_sec_wiphy; i++) {
+               if (sc->sec_wiphy[i] &&
+                   sc->sec_wiphy[i]->state != ATH_WIPHY_INACTIVE)
+                       sc->sec_wiphy[i]->state = ATH_WIPHY_PAUSED;
+       }
+}
+
+/* caller must hold wiphy_lock */
+static void __ath9k_wiphy_pause_all(struct ath_softc *sc)
+{
+       int i;
+       if (sc->pri_wiphy->state == ATH_WIPHY_ACTIVE)
+               __ath9k_wiphy_pause(sc->pri_wiphy);
+       for (i = 0; i < sc->num_sec_wiphy; i++) {
+               if (sc->sec_wiphy[i] &&
+                   sc->sec_wiphy[i]->state == ATH_WIPHY_ACTIVE)
+                       __ath9k_wiphy_pause(sc->sec_wiphy[i]);
+       }
+}
+
+int ath9k_wiphy_select(struct ath_wiphy *aphy)
+{
+       struct ath_softc *sc = aphy->sc;
+       bool now;
+
+       spin_lock_bh(&sc->wiphy_lock);
+       if (__ath9k_wiphy_scanning(sc)) {
+               /*
+                * For now, we are using mac80211 sw scan and it expects to
+                * have full control over channel changes, so avoid wiphy
+                * scheduling during a scan. This could be optimized if the
+                * scanning control were moved into the driver.
+                */
+               spin_unlock_bh(&sc->wiphy_lock);
+               return -EBUSY;
+       }
+       if (__ath9k_wiphy_pausing(sc)) {
+               if (sc->wiphy_select_failures == 0)
+                       sc->wiphy_select_first_fail = jiffies;
+               sc->wiphy_select_failures++;
+               if (time_after(jiffies, sc->wiphy_select_first_fail + HZ / 2))
+               {
+                       printk(KERN_DEBUG "ath9k: Previous wiphy select timed "
+                              "out; disable/enable hw to recover\n");
+                       __ath9k_wiphy_mark_all_paused(sc);
+                       /*
+                        * TODO: this workaround to fix hardware is unlikely to
+                        * be specific to virtual wiphy changes. It can happen
+                        * on normal channel change, too, and as such, this
+                        * should really be made more generic. For example,
+                        * tricker radio disable/enable on GTT interrupt burst
+                        * (say, 10 GTT interrupts received without any TX
+                        * frame being completed)
+                        */
+                       spin_unlock_bh(&sc->wiphy_lock);
+                       ath_radio_disable(sc);
+                       ath_radio_enable(sc);
+                       queue_work(aphy->sc->hw->workqueue,
+                                  &aphy->sc->chan_work);
+                       return -EBUSY; /* previous select still in progress */
+               }
+               spin_unlock_bh(&sc->wiphy_lock);
+               return -EBUSY; /* previous select still in progress */
+       }
+       sc->wiphy_select_failures = 0;
+
+       /* Store the new channel */
+       sc->chan_idx = aphy->chan_idx;
+       sc->chan_is_ht = aphy->chan_is_ht;
+       sc->next_wiphy = aphy;
+
+       __ath9k_wiphy_pause_all(sc);
+       now = !__ath9k_wiphy_pausing(aphy->sc);
+       spin_unlock_bh(&sc->wiphy_lock);
+
+       if (now) {
+               /* Ready to request channel change immediately */
+               queue_work(aphy->sc->hw->workqueue, &aphy->sc->chan_work);
+       }
+
+       /*
+        * wiphys will be unpaused in ath9k_tx_status() once channel has been
+        * changed if any wiphy needs time to become paused.
+        */
+
+       return 0;
+}
+
+bool ath9k_wiphy_started(struct ath_softc *sc)
+{
+       int i;
+       spin_lock_bh(&sc->wiphy_lock);
+       if (sc->pri_wiphy->state != ATH_WIPHY_INACTIVE) {
+               spin_unlock_bh(&sc->wiphy_lock);
+               return true;
+       }
+       for (i = 0; i < sc->num_sec_wiphy; i++) {
+               if (sc->sec_wiphy[i] &&
+                   sc->sec_wiphy[i]->state != ATH_WIPHY_INACTIVE) {
+                       spin_unlock_bh(&sc->wiphy_lock);
+                       return true;
+               }
+       }
+       spin_unlock_bh(&sc->wiphy_lock);
+       return false;
+}
+
+static void ath9k_wiphy_pause_chan(struct ath_wiphy *aphy,
+                                  struct ath_wiphy *selected)
+{
+       if (selected->state == ATH_WIPHY_SCAN) {
+               if (aphy == selected)
+                       return;
+               /*
+                * Pause all other wiphys for the duration of the scan even if
+                * they are on the current channel now.
+                */
+       } else if (aphy->chan_idx == selected->chan_idx)
+               return;
+       aphy->state = ATH_WIPHY_PAUSED;
+       ieee80211_stop_queues(aphy->hw);
+}
+
+void ath9k_wiphy_pause_all_forced(struct ath_softc *sc,
+                                 struct ath_wiphy *selected)
+{
+       int i;
+       spin_lock_bh(&sc->wiphy_lock);
+       if (sc->pri_wiphy->state == ATH_WIPHY_ACTIVE)
+               ath9k_wiphy_pause_chan(sc->pri_wiphy, selected);
+       for (i = 0; i < sc->num_sec_wiphy; i++) {
+               if (sc->sec_wiphy[i] &&
+                   sc->sec_wiphy[i]->state == ATH_WIPHY_ACTIVE)
+                       ath9k_wiphy_pause_chan(sc->sec_wiphy[i], selected);
+       }
+       spin_unlock_bh(&sc->wiphy_lock);
+}
+
+void ath9k_wiphy_work(struct work_struct *work)
+{
+       struct ath_softc *sc = container_of(work, struct ath_softc,
+                                           wiphy_work.work);
+       struct ath_wiphy *aphy = NULL;
+       bool first = true;
+
+       spin_lock_bh(&sc->wiphy_lock);
+
+       if (sc->wiphy_scheduler_int == 0) {
+               /* wiphy scheduler is disabled */
+               spin_unlock_bh(&sc->wiphy_lock);
+               return;
+       }
+
+try_again:
+       sc->wiphy_scheduler_index++;
+       while (sc->wiphy_scheduler_index <= sc->num_sec_wiphy) {
+               aphy = sc->sec_wiphy[sc->wiphy_scheduler_index - 1];
+               if (aphy && aphy->state != ATH_WIPHY_INACTIVE)
+                       break;
+
+               sc->wiphy_scheduler_index++;
+               aphy = NULL;
+       }
+       if (aphy == NULL) {
+               sc->wiphy_scheduler_index = 0;
+               if (sc->pri_wiphy->state == ATH_WIPHY_INACTIVE) {
+                       if (first) {
+                               first = false;
+                               goto try_again;
+                       }
+                       /* No wiphy is ready to be scheduled */
+               } else
+                       aphy = sc->pri_wiphy;
+       }
+
+       spin_unlock_bh(&sc->wiphy_lock);
+
+       if (aphy &&
+           aphy->state != ATH_WIPHY_ACTIVE && aphy->state != ATH_WIPHY_SCAN &&
+           ath9k_wiphy_select(aphy)) {
+               printk(KERN_DEBUG "ath9k: Failed to schedule virtual wiphy "
+                      "change\n");
+       }
+
+       queue_delayed_work(sc->hw->workqueue, &sc->wiphy_work,
+                          sc->wiphy_scheduler_int);
+}
+
+void ath9k_wiphy_set_scheduler(struct ath_softc *sc, unsigned int msec_int)
+{
+       cancel_delayed_work_sync(&sc->wiphy_work);
+       sc->wiphy_scheduler_int = msecs_to_jiffies(msec_int);
+       if (sc->wiphy_scheduler_int)
+               queue_delayed_work(sc->hw->workqueue, &sc->wiphy_work,
+                                  sc->wiphy_scheduler_int);
+}
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
new file mode 100644 (file)
index 0000000..b61a071
--- /dev/null
@@ -0,0 +1,2183 @@
+/*
+ * Copyright (c) 2008-2009 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 "ath9k.h"
+
+#define BITS_PER_BYTE           8
+#define OFDM_PLCP_BITS          22
+#define HT_RC_2_MCS(_rc)        ((_rc) & 0x0f)
+#define HT_RC_2_STREAMS(_rc)    ((((_rc) & 0x78) >> 3) + 1)
+#define L_STF                   8
+#define L_LTF                   8
+#define L_SIG                   4
+#define HT_SIG                  8
+#define HT_STF                  4
+#define HT_LTF(_ns)             (4 * (_ns))
+#define SYMBOL_TIME(_ns)        ((_ns) << 2) /* ns * 4 us */
+#define SYMBOL_TIME_HALFGI(_ns) (((_ns) * 18 + 4) / 5)  /* ns * 3.6 us */
+#define NUM_SYMBOLS_PER_USEC(_usec) (_usec >> 2)
+#define NUM_SYMBOLS_PER_USEC_HALFGI(_usec) (((_usec*5)-4)/18)
+
+#define OFDM_SIFS_TIME             16
+
+static u32 bits_per_symbol[][2] = {
+       /* 20MHz 40MHz */
+       {    26,   54 },     /*  0: BPSK */
+       {    52,  108 },     /*  1: QPSK 1/2 */
+       {    78,  162 },     /*  2: QPSK 3/4 */
+       {   104,  216 },     /*  3: 16-QAM 1/2 */
+       {   156,  324 },     /*  4: 16-QAM 3/4 */
+       {   208,  432 },     /*  5: 64-QAM 2/3 */
+       {   234,  486 },     /*  6: 64-QAM 3/4 */
+       {   260,  540 },     /*  7: 64-QAM 5/6 */
+       {    52,  108 },     /*  8: BPSK */
+       {   104,  216 },     /*  9: QPSK 1/2 */
+       {   156,  324 },     /* 10: QPSK 3/4 */
+       {   208,  432 },     /* 11: 16-QAM 1/2 */
+       {   312,  648 },     /* 12: 16-QAM 3/4 */
+       {   416,  864 },     /* 13: 64-QAM 2/3 */
+       {   468,  972 },     /* 14: 64-QAM 3/4 */
+       {   520, 1080 },     /* 15: 64-QAM 5/6 */
+};
+
+#define IS_HT_RATE(_rate)     ((_rate) & 0x80)
+
+static void ath_tx_send_ht_normal(struct ath_softc *sc, struct ath_txq *txq,
+                                 struct ath_atx_tid *tid,
+                                 struct list_head *bf_head);
+static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
+                               struct list_head *bf_q,
+                               int txok, int sendbar);
+static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
+                            struct list_head *head);
+static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf);
+static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf,
+                             int txok);
+static void ath_tx_rc_status(struct ath_buf *bf, struct ath_desc *ds,
+                            int nbad, int txok, bool update_rc);
+
+/*********************/
+/* Aggregation logic */
+/*********************/
+
+static int ath_aggr_query(struct ath_softc *sc, struct ath_node *an, u8 tidno)
+{
+       struct ath_atx_tid *tid;
+       tid = ATH_AN_2_TID(an, tidno);
+
+       if (tid->state & AGGR_ADDBA_COMPLETE ||
+           tid->state & AGGR_ADDBA_PROGRESS)
+               return 1;
+       else
+               return 0;
+}
+
+static void ath_tx_queue_tid(struct ath_txq *txq, struct ath_atx_tid *tid)
+{
+       struct ath_atx_ac *ac = tid->ac;
+
+       if (tid->paused)
+               return;
+
+       if (tid->sched)
+               return;
+
+       tid->sched = true;
+       list_add_tail(&tid->list, &ac->tid_q);
+
+       if (ac->sched)
+               return;
+
+       ac->sched = true;
+       list_add_tail(&ac->list, &txq->axq_acq);
+}
+
+static void ath_tx_pause_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
+{
+       struct ath_txq *txq = &sc->tx.txq[tid->ac->qnum];
+
+       spin_lock_bh(&txq->axq_lock);
+       tid->paused++;
+       spin_unlock_bh(&txq->axq_lock);
+}
+
+static void ath_tx_resume_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
+{
+       struct ath_txq *txq = &sc->tx.txq[tid->ac->qnum];
+
+       ASSERT(tid->paused > 0);
+       spin_lock_bh(&txq->axq_lock);
+
+       tid->paused--;
+
+       if (tid->paused > 0)
+               goto unlock;
+
+       if (list_empty(&tid->buf_q))
+               goto unlock;
+
+       ath_tx_queue_tid(txq, tid);
+       ath_txq_schedule(sc, txq);
+unlock:
+       spin_unlock_bh(&txq->axq_lock);
+}
+
+static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
+{
+       struct ath_txq *txq = &sc->tx.txq[tid->ac->qnum];
+       struct ath_buf *bf;
+       struct list_head bf_head;
+       INIT_LIST_HEAD(&bf_head);
+
+       ASSERT(tid->paused > 0);
+       spin_lock_bh(&txq->axq_lock);
+
+       tid->paused--;
+
+       if (tid->paused > 0) {
+               spin_unlock_bh(&txq->axq_lock);
+               return;
+       }
+
+       while (!list_empty(&tid->buf_q)) {
+               bf = list_first_entry(&tid->buf_q, struct ath_buf, list);
+               ASSERT(!bf_isretried(bf));
+               list_move_tail(&bf->list, &bf_head);
+               ath_tx_send_ht_normal(sc, txq, tid, &bf_head);
+       }
+
+       spin_unlock_bh(&txq->axq_lock);
+}
+
+static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid,
+                             int seqno)
+{
+       int index, cindex;
+
+       index  = ATH_BA_INDEX(tid->seq_start, seqno);
+       cindex = (tid->baw_head + index) & (ATH_TID_MAX_BUFS - 1);
+
+       tid->tx_buf[cindex] = NULL;
+
+       while (tid->baw_head != tid->baw_tail && !tid->tx_buf[tid->baw_head]) {
+               INCR(tid->seq_start, IEEE80211_SEQ_MAX);
+               INCR(tid->baw_head, ATH_TID_MAX_BUFS);
+       }
+}
+
+static void ath_tx_addto_baw(struct ath_softc *sc, struct ath_atx_tid *tid,
+                            struct ath_buf *bf)
+{
+       int index, cindex;
+
+       if (bf_isretried(bf))
+               return;
+
+       index  = ATH_BA_INDEX(tid->seq_start, bf->bf_seqno);
+       cindex = (tid->baw_head + index) & (ATH_TID_MAX_BUFS - 1);
+
+       ASSERT(tid->tx_buf[cindex] == NULL);
+       tid->tx_buf[cindex] = bf;
+
+       if (index >= ((tid->baw_tail - tid->baw_head) &
+               (ATH_TID_MAX_BUFS - 1))) {
+               tid->baw_tail = cindex;
+               INCR(tid->baw_tail, ATH_TID_MAX_BUFS);
+       }
+}
+
+/*
+ * TODO: For frame(s) that are in the retry state, we will reuse the
+ * sequence number(s) without setting the retry bit. The
+ * alternative is to give up on these and BAR the receiver's window
+ * forward.
+ */
+static void ath_tid_drain(struct ath_softc *sc, struct ath_txq *txq,
+                         struct ath_atx_tid *tid)
+
+{
+       struct ath_buf *bf;
+       struct list_head bf_head;
+       INIT_LIST_HEAD(&bf_head);
+
+       for (;;) {
+               if (list_empty(&tid->buf_q))
+                       break;
+
+               bf = list_first_entry(&tid->buf_q, struct ath_buf, list);
+               list_move_tail(&bf->list, &bf_head);
+
+               if (bf_isretried(bf))
+                       ath_tx_update_baw(sc, tid, bf->bf_seqno);
+
+               spin_unlock(&txq->axq_lock);
+               ath_tx_complete_buf(sc, bf, &bf_head, 0, 0);
+               spin_lock(&txq->axq_lock);
+       }
+
+       tid->seq_next = tid->seq_start;
+       tid->baw_tail = tid->baw_head;
+}
+
+static void ath_tx_set_retry(struct ath_softc *sc, struct ath_buf *bf)
+{
+       struct sk_buff *skb;
+       struct ieee80211_hdr *hdr;
+
+       bf->bf_state.bf_type |= BUF_RETRY;
+       bf->bf_retries++;
+
+       skb = bf->bf_mpdu;
+       hdr = (struct ieee80211_hdr *)skb->data;
+       hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_RETRY);
+}
+
+static struct ath_buf* ath_clone_txbuf(struct ath_softc *sc, struct ath_buf *bf)
+{
+       struct ath_buf *tbf;
+
+       spin_lock_bh(&sc->tx.txbuflock);
+       ASSERT(!list_empty((&sc->tx.txbuf)));
+       tbf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list);
+       list_del(&tbf->list);
+       spin_unlock_bh(&sc->tx.txbuflock);
+
+       ATH_TXBUF_RESET(tbf);
+
+       tbf->bf_mpdu = bf->bf_mpdu;
+       tbf->bf_buf_addr = bf->bf_buf_addr;
+       *(tbf->bf_desc) = *(bf->bf_desc);
+       tbf->bf_state = bf->bf_state;
+       tbf->bf_dmacontext = bf->bf_dmacontext;
+
+       return tbf;
+}
+
+static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
+                                struct ath_buf *bf, struct list_head *bf_q,
+                                int txok)
+{
+       struct ath_node *an = NULL;
+       struct sk_buff *skb;
+       struct ieee80211_sta *sta;
+       struct ieee80211_hdr *hdr;
+       struct ath_atx_tid *tid = NULL;
+       struct ath_buf *bf_next, *bf_last = bf->bf_lastbf;
+       struct ath_desc *ds = bf_last->bf_desc;
+       struct list_head bf_head, bf_pending;
+       u16 seq_st = 0, acked_cnt = 0, txfail_cnt = 0;
+       u32 ba[WME_BA_BMP_SIZE >> 5];
+       int isaggr, txfail, txpending, sendbar = 0, needreset = 0, nbad = 0;
+       bool rc_update = true;
+
+       skb = bf->bf_mpdu;
+       hdr = (struct ieee80211_hdr *)skb->data;
+
+       rcu_read_lock();
+
+       sta = ieee80211_find_sta(sc->hw, hdr->addr1);
+       if (!sta) {
+               rcu_read_unlock();
+               return;
+       }
+
+       an = (struct ath_node *)sta->drv_priv;
+       tid = ATH_AN_2_TID(an, bf->bf_tidno);
+
+       isaggr = bf_isaggr(bf);
+       memset(ba, 0, WME_BA_BMP_SIZE >> 3);
+
+       if (isaggr && txok) {
+               if (ATH_DS_TX_BA(ds)) {
+                       seq_st = ATH_DS_BA_SEQ(ds);
+                       memcpy(ba, ATH_DS_BA_BITMAP(ds),
+                              WME_BA_BMP_SIZE >> 3);
+               } else {
+                       /*
+                        * AR5416 can become deaf/mute when BA
+                        * issue happens. Chip needs to be reset.
+                        * But AP code may have sychronization issues
+                        * when perform internal reset in this routine.
+                        * Only enable reset in STA mode for now.
+                        */
+                       if (sc->sc_ah->opmode == NL80211_IFTYPE_STATION)
+                               needreset = 1;
+               }
+       }
+
+       INIT_LIST_HEAD(&bf_pending);
+       INIT_LIST_HEAD(&bf_head);
+
+       nbad = ath_tx_num_badfrms(sc, bf, txok);
+       while (bf) {
+               txfail = txpending = 0;
+               bf_next = bf->bf_next;
+
+               if (ATH_BA_ISSET(ba, ATH_BA_INDEX(seq_st, bf->bf_seqno))) {
+                       /* transmit completion, subframe is
+                        * acked by block ack */
+                       acked_cnt++;
+               } else if (!isaggr && txok) {
+                       /* transmit completion */
+                       acked_cnt++;
+               } else {
+                       if (!(tid->state & AGGR_CLEANUP) &&
+                           ds->ds_txstat.ts_flags != ATH9K_TX_SW_ABORTED) {
+                               if (bf->bf_retries < ATH_MAX_SW_RETRIES) {
+                                       ath_tx_set_retry(sc, bf);
+                                       txpending = 1;
+                               } else {
+                                       bf->bf_state.bf_type |= BUF_XRETRY;
+                                       txfail = 1;
+                                       sendbar = 1;
+                                       txfail_cnt++;
+                               }
+                       } else {
+                               /*
+                                * cleanup in progress, just fail
+                                * the un-acked sub-frames
+                                */
+                               txfail = 1;
+                       }
+               }
+
+               if (bf_next == NULL) {
+                       INIT_LIST_HEAD(&bf_head);
+               } else {
+                       ASSERT(!list_empty(bf_q));
+                       list_move_tail(&bf->list, &bf_head);
+               }
+
+               if (!txpending) {
+                       /*
+                        * complete the acked-ones/xretried ones; update
+                        * block-ack window
+                        */
+                       spin_lock_bh(&txq->axq_lock);
+                       ath_tx_update_baw(sc, tid, bf->bf_seqno);
+                       spin_unlock_bh(&txq->axq_lock);
+
+                       if (rc_update && (acked_cnt == 1 || txfail_cnt == 1)) {
+                               ath_tx_rc_status(bf, ds, nbad, txok, true);
+                               rc_update = false;
+                       } else {
+                               ath_tx_rc_status(bf, ds, nbad, txok, false);
+                       }
+
+                       ath_tx_complete_buf(sc, bf, &bf_head, !txfail, sendbar);
+               } else {
+                       /* retry the un-acked ones */
+                       if (bf->bf_next == NULL && bf_last->bf_stale) {
+                               struct ath_buf *tbf;
+
+                               tbf = ath_clone_txbuf(sc, bf_last);
+                               ath9k_hw_cleartxdesc(sc->sc_ah, tbf->bf_desc);
+                               list_add_tail(&tbf->list, &bf_head);
+                       } else {
+                               /*
+                                * Clear descriptor status words for
+                                * software retry
+                                */
+                               ath9k_hw_cleartxdesc(sc->sc_ah, bf->bf_desc);
+                       }
+
+                       /*
+                        * Put this buffer to the temporary pending
+                        * queue to retain ordering
+                        */
+                       list_splice_tail_init(&bf_head, &bf_pending);
+               }
+
+               bf = bf_next;
+       }
+
+       if (tid->state & AGGR_CLEANUP) {
+               if (tid->baw_head == tid->baw_tail) {
+                       tid->state &= ~AGGR_ADDBA_COMPLETE;
+                       tid->addba_exchangeattempts = 0;
+                       tid->state &= ~AGGR_CLEANUP;
+
+                       /* send buffered frames as singles */
+                       ath_tx_flush_tid(sc, tid);
+               }
+               rcu_read_unlock();
+               return;
+       }
+
+       /* prepend un-acked frames to the beginning of the pending frame queue */
+       if (!list_empty(&bf_pending)) {
+               spin_lock_bh(&txq->axq_lock);
+               list_splice(&bf_pending, &tid->buf_q);
+               ath_tx_queue_tid(txq, tid);
+               spin_unlock_bh(&txq->axq_lock);
+       }
+
+       rcu_read_unlock();
+
+       if (needreset)
+               ath_reset(sc, false);
+}
+
+static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf,
+                          struct ath_atx_tid *tid)
+{
+       const struct ath_rate_table *rate_table = sc->cur_rate_table;
+       struct sk_buff *skb;
+       struct ieee80211_tx_info *tx_info;
+       struct ieee80211_tx_rate *rates;
+       struct ath_tx_info_priv *tx_info_priv;
+       u32 max_4ms_framelen, frmlen;
+       u16 aggr_limit, legacy = 0, maxampdu;
+       int i;
+
+       skb = bf->bf_mpdu;
+       tx_info = IEEE80211_SKB_CB(skb);
+       rates = tx_info->control.rates;
+       tx_info_priv = (struct ath_tx_info_priv *)tx_info->rate_driver_data[0];
+
+       /*
+        * Find the lowest frame length among the rate series that will have a
+        * 4ms transmit duration.
+        * TODO - TXOP limit needs to be considered.
+        */
+       max_4ms_framelen = ATH_AMPDU_LIMIT_MAX;
+
+       for (i = 0; i < 4; i++) {
+               if (rates[i].count) {
+                       if (!WLAN_RC_PHY_HT(rate_table->info[rates[i].idx].phy)) {
+                               legacy = 1;
+                               break;
+                       }
+
+                       frmlen = rate_table->info[rates[i].idx].max_4ms_framelen;
+                       max_4ms_framelen = min(max_4ms_framelen, frmlen);
+               }
+       }
+
+       /*
+        * limit aggregate size by the minimum rate if rate selected is
+        * not a probe rate, if rate selected is a probe rate then
+        * avoid aggregation of this packet.
+        */
+       if (tx_info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE || legacy)
+               return 0;
+
+       aggr_limit = min(max_4ms_framelen, (u32)ATH_AMPDU_LIMIT_DEFAULT);
+
+       /*
+        * h/w can accept aggregates upto 16 bit lengths (65535).
+        * The IE, however can hold upto 65536, which shows up here
+        * as zero. Ignore 65536 since we  are constrained by hw.
+        */
+       maxampdu = tid->an->maxampdu;
+       if (maxampdu)
+               aggr_limit = min(aggr_limit, maxampdu);
+
+       return aggr_limit;
+}
+
+/*
+ * Returns the number of delimiters to be added to
+ * meet the minimum required mpdudensity.
+ * caller should make sure that the rate is HT rate .
+ */
+static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid,
+                                 struct ath_buf *bf, u16 frmlen)
+{
+       const struct ath_rate_table *rt = sc->cur_rate_table;
+       struct sk_buff *skb = bf->bf_mpdu;
+       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+       u32 nsymbits, nsymbols, mpdudensity;
+       u16 minlen;
+       u8 rc, flags, rix;
+       int width, half_gi, ndelim, mindelim;
+
+       /* Select standard number of delimiters based on frame length alone */
+       ndelim = ATH_AGGR_GET_NDELIM(frmlen);
+
+       /*
+        * If encryption enabled, hardware requires some more padding between
+        * subframes.
+        * TODO - this could be improved to be dependent on the rate.
+        *      The hardware can keep up at lower rates, but not higher rates
+        */
+       if (bf->bf_keytype != ATH9K_KEY_TYPE_CLEAR)
+               ndelim += ATH_AGGR_ENCRYPTDELIM;
+
+       /*
+        * Convert desired mpdu density from microeconds to bytes based
+        * on highest rate in rate series (i.e. first rate) to determine
+        * required minimum length for subframe. Take into account
+        * whether high rate is 20 or 40Mhz and half or full GI.
+        */
+       mpdudensity = tid->an->mpdudensity;
+
+       /*
+        * If there is no mpdu density restriction, no further calculation
+        * is needed.
+        */
+       if (mpdudensity == 0)
+               return ndelim;
+
+       rix = tx_info->control.rates[0].idx;
+       flags = tx_info->control.rates[0].flags;
+       rc = rt->info[rix].ratecode;
+       width = (flags & IEEE80211_TX_RC_40_MHZ_WIDTH) ? 1 : 0;
+       half_gi = (flags & IEEE80211_TX_RC_SHORT_GI) ? 1 : 0;
+
+       if (half_gi)
+               nsymbols = NUM_SYMBOLS_PER_USEC_HALFGI(mpdudensity);
+       else
+               nsymbols = NUM_SYMBOLS_PER_USEC(mpdudensity);
+
+       if (nsymbols == 0)
+               nsymbols = 1;
+
+       nsymbits = bits_per_symbol[HT_RC_2_MCS(rc)][width];
+       minlen = (nsymbols * nsymbits) / BITS_PER_BYTE;
+
+       if (frmlen < minlen) {
+               mindelim = (minlen - frmlen) / ATH_AGGR_DELIM_SZ;
+               ndelim = max(mindelim, ndelim);
+       }
+
+       return ndelim;
+}
+
+static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
+                                            struct ath_atx_tid *tid,
+                                            struct list_head *bf_q)
+{
+#define PADBYTES(_len) ((4 - ((_len) % 4)) % 4)
+       struct ath_buf *bf, *bf_first, *bf_prev = NULL;
+       int rl = 0, nframes = 0, ndelim, prev_al = 0;
+       u16 aggr_limit = 0, al = 0, bpad = 0,
+               al_delta, h_baw = tid->baw_size / 2;
+       enum ATH_AGGR_STATUS status = ATH_AGGR_DONE;
+
+       bf_first = list_first_entry(&tid->buf_q, struct ath_buf, list);
+
+       do {
+               bf = list_first_entry(&tid->buf_q, struct ath_buf, list);
+
+               /* do not step over block-ack window */
+               if (!BAW_WITHIN(tid->seq_start, tid->baw_size, bf->bf_seqno)) {
+                       status = ATH_AGGR_BAW_CLOSED;
+                       break;
+               }
+
+               if (!rl) {
+                       aggr_limit = ath_lookup_rate(sc, bf, tid);
+                       rl = 1;
+               }
+
+               /* do not exceed aggregation limit */
+               al_delta = ATH_AGGR_DELIM_SZ + bf->bf_frmlen;
+
+               if (nframes &&
+                   (aggr_limit < (al + bpad + al_delta + prev_al))) {
+                       status = ATH_AGGR_LIMITED;
+                       break;
+               }
+
+               /* do not exceed subframe limit */
+               if (nframes >= min((int)h_baw, ATH_AMPDU_SUBFRAME_DEFAULT)) {
+                       status = ATH_AGGR_LIMITED;
+                       break;
+               }
+               nframes++;
+
+               /* add padding for previous frame to aggregation length */
+               al += bpad + al_delta;
+
+               /*
+                * Get the delimiters needed to meet the MPDU
+                * density for this node.
+                */
+               ndelim = ath_compute_num_delims(sc, tid, bf_first, bf->bf_frmlen);
+               bpad = PADBYTES(al_delta) + (ndelim << 2);
+
+               bf->bf_next = NULL;
+               bf->bf_desc->ds_link = 0;
+
+               /* link buffers of this frame to the aggregate */
+               ath_tx_addto_baw(sc, tid, bf);
+               ath9k_hw_set11n_aggr_middle(sc->sc_ah, bf->bf_desc, ndelim);
+               list_move_tail(&bf->list, bf_q);
+               if (bf_prev) {
+                       bf_prev->bf_next = bf;
+                       bf_prev->bf_desc->ds_link = bf->bf_daddr;
+               }
+               bf_prev = bf;
+       } while (!list_empty(&tid->buf_q));
+
+       bf_first->bf_al = al;
+       bf_first->bf_nframes = nframes;
+
+       return status;
+#undef PADBYTES
+}
+
+static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq,
+                             struct ath_atx_tid *tid)
+{
+       struct ath_buf *bf;
+       enum ATH_AGGR_STATUS status;
+       struct list_head bf_q;
+
+       do {
+               if (list_empty(&tid->buf_q))
+                       return;
+
+               INIT_LIST_HEAD(&bf_q);
+
+               status = ath_tx_form_aggr(sc, tid, &bf_q);
+
+               /*
+                * no frames picked up to be aggregated;
+                * block-ack window is not open.
+                */
+               if (list_empty(&bf_q))
+                       break;
+
+               bf = list_first_entry(&bf_q, struct ath_buf, list);
+               bf->bf_lastbf = list_entry(bf_q.prev, struct ath_buf, list);
+
+               /* if only one frame, send as non-aggregate */
+               if (bf->bf_nframes == 1) {
+                       bf->bf_state.bf_type &= ~BUF_AGGR;
+                       ath9k_hw_clr11n_aggr(sc->sc_ah, bf->bf_desc);
+                       ath_buf_set_rate(sc, bf);
+                       ath_tx_txqaddbuf(sc, txq, &bf_q);
+                       continue;
+               }
+
+               /* setup first desc of aggregate */
+               bf->bf_state.bf_type |= BUF_AGGR;
+               ath_buf_set_rate(sc, bf);
+               ath9k_hw_set11n_aggr_first(sc->sc_ah, bf->bf_desc, bf->bf_al);
+
+               /* anchor last desc of aggregate */
+               ath9k_hw_set11n_aggr_last(sc->sc_ah, bf->bf_lastbf->bf_desc);
+
+               txq->axq_aggr_depth++;
+               ath_tx_txqaddbuf(sc, txq, &bf_q);
+
+       } while (txq->axq_depth < ATH_AGGR_MIN_QDEPTH &&
+                status != ATH_AGGR_BAW_CLOSED);
+}
+
+int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
+                     u16 tid, u16 *ssn)
+{
+       struct ath_atx_tid *txtid;
+       struct ath_node *an;
+
+       an = (struct ath_node *)sta->drv_priv;
+
+       if (sc->sc_flags & SC_OP_TXAGGR) {
+               txtid = ATH_AN_2_TID(an, tid);
+               txtid->state |= AGGR_ADDBA_PROGRESS;
+               ath_tx_pause_tid(sc, txtid);
+               *ssn = txtid->seq_start;
+       }
+
+       return 0;
+}
+
+int ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
+{
+       struct ath_node *an = (struct ath_node *)sta->drv_priv;
+       struct ath_atx_tid *txtid = ATH_AN_2_TID(an, tid);
+       struct ath_txq *txq = &sc->tx.txq[txtid->ac->qnum];
+       struct ath_buf *bf;
+       struct list_head bf_head;
+       INIT_LIST_HEAD(&bf_head);
+
+       if (txtid->state & AGGR_CLEANUP)
+               return 0;
+
+       if (!(txtid->state & AGGR_ADDBA_COMPLETE)) {
+               txtid->state &= ~AGGR_ADDBA_PROGRESS;
+               txtid->addba_exchangeattempts = 0;
+               return 0;
+       }
+
+       ath_tx_pause_tid(sc, txtid);
+
+       /* drop all software retried frames and mark this TID */
+       spin_lock_bh(&txq->axq_lock);
+       while (!list_empty(&txtid->buf_q)) {
+               bf = list_first_entry(&txtid->buf_q, struct ath_buf, list);
+               if (!bf_isretried(bf)) {
+                       /*
+                        * NB: it's based on the assumption that
+                        * software retried frame will always stay
+                        * at the head of software queue.
+                        */
+                       break;
+               }
+               list_move_tail(&bf->list, &bf_head);
+               ath_tx_update_baw(sc, txtid, bf->bf_seqno);
+               ath_tx_complete_buf(sc, bf, &bf_head, 0, 0);
+       }
+       spin_unlock_bh(&txq->axq_lock);
+
+       if (txtid->baw_head != txtid->baw_tail) {
+               txtid->state |= AGGR_CLEANUP;
+       } else {
+               txtid->state &= ~AGGR_ADDBA_COMPLETE;
+               txtid->addba_exchangeattempts = 0;
+               ath_tx_flush_tid(sc, txtid);
+       }
+
+       return 0;
+}
+
+void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
+{
+       struct ath_atx_tid *txtid;
+       struct ath_node *an;
+
+       an = (struct ath_node *)sta->drv_priv;
+
+       if (sc->sc_flags & SC_OP_TXAGGR) {
+               txtid = ATH_AN_2_TID(an, tid);
+               txtid->baw_size =
+                       IEEE80211_MIN_AMPDU_BUF << sta->ht_cap.ampdu_factor;
+               txtid->state |= AGGR_ADDBA_COMPLETE;
+               txtid->state &= ~AGGR_ADDBA_PROGRESS;
+               ath_tx_resume_tid(sc, txtid);
+       }
+}
+
+bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, u8 tidno)
+{
+       struct ath_atx_tid *txtid;
+
+       if (!(sc->sc_flags & SC_OP_TXAGGR))
+               return false;
+
+       txtid = ATH_AN_2_TID(an, tidno);
+
+       if (!(txtid->state & AGGR_ADDBA_COMPLETE)) {
+               if (!(txtid->state & AGGR_ADDBA_PROGRESS) &&
+                   (txtid->addba_exchangeattempts < ADDBA_EXCHANGE_ATTEMPTS)) {
+                       txtid->addba_exchangeattempts++;
+                       return true;
+               }
+       }
+
+       return false;
+}
+
+/********************/
+/* Queue Management */
+/********************/
+
+static void ath_txq_drain_pending_buffers(struct ath_softc *sc,
+                                         struct ath_txq *txq)
+{
+       struct ath_atx_ac *ac, *ac_tmp;
+       struct ath_atx_tid *tid, *tid_tmp;
+
+       list_for_each_entry_safe(ac, ac_tmp, &txq->axq_acq, list) {
+               list_del(&ac->list);
+               ac->sched = false;
+               list_for_each_entry_safe(tid, tid_tmp, &ac->tid_q, list) {
+                       list_del(&tid->list);
+                       tid->sched = false;
+                       ath_tid_drain(sc, txq, tid);
+               }
+       }
+}
+
+struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
+{
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath9k_tx_queue_info qi;
+       int qnum;
+
+       memset(&qi, 0, sizeof(qi));
+       qi.tqi_subtype = subtype;
+       qi.tqi_aifs = ATH9K_TXQ_USEDEFAULT;
+       qi.tqi_cwmin = ATH9K_TXQ_USEDEFAULT;
+       qi.tqi_cwmax = ATH9K_TXQ_USEDEFAULT;
+       qi.tqi_physCompBuf = 0;
+
+       /*
+        * Enable interrupts only for EOL and DESC conditions.
+        * We mark tx descriptors to receive a DESC interrupt
+        * when a tx queue gets deep; otherwise waiting for the
+        * EOL to reap descriptors.  Note that this is done to
+        * reduce interrupt load and this only defers reaping
+        * descriptors, never transmitting frames.  Aside from
+        * reducing interrupts this also permits more concurrency.
+        * The only potential downside is if the tx queue backs
+        * up in which case the top half of the kernel may backup
+        * due to a lack of tx descriptors.
+        *
+        * The UAPSD queue is an exception, since we take a desc-
+        * based intr on the EOSP frames.
+        */
+       if (qtype == ATH9K_TX_QUEUE_UAPSD)
+               qi.tqi_qflags = TXQ_FLAG_TXDESCINT_ENABLE;
+       else
+               qi.tqi_qflags = TXQ_FLAG_TXEOLINT_ENABLE |
+                       TXQ_FLAG_TXDESCINT_ENABLE;
+       qnum = ath9k_hw_setuptxqueue(ah, qtype, &qi);
+       if (qnum == -1) {
+               /*
+                * NB: don't print a message, this happens
+                * normally on parts with too few tx queues
+                */
+               return NULL;
+       }
+       if (qnum >= ARRAY_SIZE(sc->tx.txq)) {
+               DPRINTF(sc, ATH_DBG_FATAL,
+                       "qnum %u out of range, max %u!\n",
+                       qnum, (unsigned int)ARRAY_SIZE(sc->tx.txq));
+               ath9k_hw_releasetxqueue(ah, qnum);
+               return NULL;
+       }
+       if (!ATH_TXQ_SETUP(sc, qnum)) {
+               struct ath_txq *txq = &sc->tx.txq[qnum];
+
+               txq->axq_qnum = qnum;
+               txq->axq_link = NULL;
+               INIT_LIST_HEAD(&txq->axq_q);
+               INIT_LIST_HEAD(&txq->axq_acq);
+               spin_lock_init(&txq->axq_lock);
+               txq->axq_depth = 0;
+               txq->axq_aggr_depth = 0;
+               txq->axq_totalqueued = 0;
+               txq->axq_linkbuf = NULL;
+               sc->tx.txqsetup |= 1<<qnum;
+       }
+       return &sc->tx.txq[qnum];
+}
+
+static int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype)
+{
+       int qnum;
+
+       switch (qtype) {
+       case ATH9K_TX_QUEUE_DATA:
+               if (haltype >= ARRAY_SIZE(sc->tx.hwq_map)) {
+                       DPRINTF(sc, ATH_DBG_FATAL,
+                               "HAL AC %u out of range, max %zu!\n",
+                               haltype, ARRAY_SIZE(sc->tx.hwq_map));
+                       return -1;
+               }
+               qnum = sc->tx.hwq_map[haltype];
+               break;
+       case ATH9K_TX_QUEUE_BEACON:
+               qnum = sc->beacon.beaconq;
+               break;
+       case ATH9K_TX_QUEUE_CAB:
+               qnum = sc->beacon.cabq->axq_qnum;
+               break;
+       default:
+               qnum = -1;
+       }
+       return qnum;
+}
+
+struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb)
+{
+       struct ath_txq *txq = NULL;
+       int qnum;
+
+       qnum = ath_get_hal_qnum(skb_get_queue_mapping(skb), sc);
+       txq = &sc->tx.txq[qnum];
+
+       spin_lock_bh(&txq->axq_lock);
+
+       if (txq->axq_depth >= (ATH_TXBUF - 20)) {
+               DPRINTF(sc, ATH_DBG_XMIT,
+                       "TX queue: %d is full, depth: %d\n",
+                       qnum, txq->axq_depth);
+               ieee80211_stop_queue(sc->hw, skb_get_queue_mapping(skb));
+               txq->stopped = 1;
+               spin_unlock_bh(&txq->axq_lock);
+               return NULL;
+       }
+
+       spin_unlock_bh(&txq->axq_lock);
+
+       return txq;
+}
+
+int ath_txq_update(struct ath_softc *sc, int qnum,
+                  struct ath9k_tx_queue_info *qinfo)
+{
+       struct ath_hw *ah = sc->sc_ah;
+       int error = 0;
+       struct ath9k_tx_queue_info qi;
+
+       if (qnum == sc->beacon.beaconq) {
+               /*
+                * XXX: for beacon queue, we just save the parameter.
+                * It will be picked up by ath_beaconq_config when
+                * it's necessary.
+                */
+               sc->beacon.beacon_qi = *qinfo;
+               return 0;
+       }
+
+       ASSERT(sc->tx.txq[qnum].axq_qnum == qnum);
+
+       ath9k_hw_get_txq_props(ah, qnum, &qi);
+       qi.tqi_aifs = qinfo->tqi_aifs;
+       qi.tqi_cwmin = qinfo->tqi_cwmin;
+       qi.tqi_cwmax = qinfo->tqi_cwmax;
+       qi.tqi_burstTime = qinfo->tqi_burstTime;
+       qi.tqi_readyTime = qinfo->tqi_readyTime;
+
+       if (!ath9k_hw_set_txq_props(ah, qnum, &qi)) {
+               DPRINTF(sc, ATH_DBG_FATAL,
+                       "Unable to update hardware queue %u!\n", qnum);
+               error = -EIO;
+       } else {
+               ath9k_hw_resettxqueue(ah, qnum);
+       }
+
+       return error;
+}
+
+int ath_cabq_update(struct ath_softc *sc)
+{
+       struct ath9k_tx_queue_info qi;
+       int qnum = sc->beacon.cabq->axq_qnum;
+
+       ath9k_hw_get_txq_props(sc->sc_ah, qnum, &qi);
+       /*
+        * Ensure the readytime % is within the bounds.
+        */
+       if (sc->config.cabqReadytime < ATH9K_READY_TIME_LO_BOUND)
+               sc->config.cabqReadytime = ATH9K_READY_TIME_LO_BOUND;
+       else if (sc->config.cabqReadytime > ATH9K_READY_TIME_HI_BOUND)
+               sc->config.cabqReadytime = ATH9K_READY_TIME_HI_BOUND;
+
+       qi.tqi_readyTime = (sc->beacon_interval *
+                           sc->config.cabqReadytime) / 100;
+       ath_txq_update(sc, qnum, &qi);
+
+       return 0;
+}
+
+/*
+ * Drain a given TX queue (could be Beacon or Data)
+ *
+ * This assumes output has been stopped and
+ * we do not need to block ath_tx_tasklet.
+ */
+void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx)
+{
+       struct ath_buf *bf, *lastbf;
+       struct list_head bf_head;
+
+       INIT_LIST_HEAD(&bf_head);
+
+       for (;;) {
+               spin_lock_bh(&txq->axq_lock);
+
+               if (list_empty(&txq->axq_q)) {
+                       txq->axq_link = NULL;
+                       txq->axq_linkbuf = NULL;
+                       spin_unlock_bh(&txq->axq_lock);
+                       break;
+               }
+
+               bf = list_first_entry(&txq->axq_q, struct ath_buf, list);
+
+               if (bf->bf_stale) {
+                       list_del(&bf->list);
+                       spin_unlock_bh(&txq->axq_lock);
+
+                       spin_lock_bh(&sc->tx.txbuflock);
+                       list_add_tail(&bf->list, &sc->tx.txbuf);
+                       spin_unlock_bh(&sc->tx.txbuflock);
+                       continue;
+               }
+
+               lastbf = bf->bf_lastbf;
+               if (!retry_tx)
+                       lastbf->bf_desc->ds_txstat.ts_flags =
+                               ATH9K_TX_SW_ABORTED;
+
+               /* remove ath_buf's of the same mpdu from txq */
+               list_cut_position(&bf_head, &txq->axq_q, &lastbf->list);
+               txq->axq_depth--;
+
+               spin_unlock_bh(&txq->axq_lock);
+
+               if (bf_isampdu(bf))
+                       ath_tx_complete_aggr(sc, txq, bf, &bf_head, 0);
+               else
+                       ath_tx_complete_buf(sc, bf, &bf_head, 0, 0);
+       }
+
+       /* flush any pending frames if aggregation is enabled */
+       if (sc->sc_flags & SC_OP_TXAGGR) {
+               if (!retry_tx) {
+                       spin_lock_bh(&txq->axq_lock);
+                       ath_txq_drain_pending_buffers(sc, txq);
+                       spin_unlock_bh(&txq->axq_lock);
+               }
+       }
+}
+
+void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx)
+{
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath_txq *txq;
+       int i, npend = 0;
+
+       if (sc->sc_flags & SC_OP_INVALID)
+               return;
+
+       /* Stop beacon queue */
+       ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
+
+       /* Stop data queues */
+       for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
+               if (ATH_TXQ_SETUP(sc, i)) {
+                       txq = &sc->tx.txq[i];
+                       ath9k_hw_stoptxdma(ah, txq->axq_qnum);
+                       npend += ath9k_hw_numtxpending(ah, txq->axq_qnum);
+               }
+       }
+
+       if (npend) {
+               int r;
+
+               DPRINTF(sc, ATH_DBG_XMIT, "Unable to stop TxDMA. Reset HAL!\n");
+
+               spin_lock_bh(&sc->sc_resetlock);
+               r = ath9k_hw_reset(ah, sc->sc_ah->curchan, true);
+               if (r)
+                       DPRINTF(sc, ATH_DBG_FATAL,
+                               "Unable to reset hardware; reset status %d\n",
+                               r);
+               spin_unlock_bh(&sc->sc_resetlock);
+       }
+
+       for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
+               if (ATH_TXQ_SETUP(sc, i))
+                       ath_draintxq(sc, &sc->tx.txq[i], retry_tx);
+       }
+}
+
+void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq)
+{
+       ath9k_hw_releasetxqueue(sc->sc_ah, txq->axq_qnum);
+       sc->tx.txqsetup &= ~(1<<txq->axq_qnum);
+}
+
+void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
+{
+       struct ath_atx_ac *ac;
+       struct ath_atx_tid *tid;
+
+       if (list_empty(&txq->axq_acq))
+               return;
+
+       ac = list_first_entry(&txq->axq_acq, struct ath_atx_ac, list);
+       list_del(&ac->list);
+       ac->sched = false;
+
+       do {
+               if (list_empty(&ac->tid_q))
+                       return;
+
+               tid = list_first_entry(&ac->tid_q, struct ath_atx_tid, list);
+               list_del(&tid->list);
+               tid->sched = false;
+
+               if (tid->paused)
+                       continue;
+
+               if ((txq->axq_depth % 2) == 0)
+                       ath_tx_sched_aggr(sc, txq, tid);
+
+               /*
+                * add tid to round-robin queue if more frames
+                * are pending for the tid
+                */
+               if (!list_empty(&tid->buf_q))
+                       ath_tx_queue_tid(txq, tid);
+
+               break;
+       } while (!list_empty(&ac->tid_q));
+
+       if (!list_empty(&ac->tid_q)) {
+               if (!ac->sched) {
+                       ac->sched = true;
+                       list_add_tail(&ac->list, &txq->axq_acq);
+               }
+       }
+}
+
+int ath_tx_setup(struct ath_softc *sc, int haltype)
+{
+       struct ath_txq *txq;
+
+       if (haltype >= ARRAY_SIZE(sc->tx.hwq_map)) {
+               DPRINTF(sc, ATH_DBG_FATAL,
+                       "HAL AC %u out of range, max %zu!\n",
+                        haltype, ARRAY_SIZE(sc->tx.hwq_map));
+               return 0;
+       }
+       txq = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, haltype);
+       if (txq != NULL) {
+               sc->tx.hwq_map[haltype] = txq->axq_qnum;
+               return 1;
+       } else
+               return 0;
+}
+
+/***********/
+/* TX, DMA */
+/***********/
+
+/*
+ * Insert a chain of ath_buf (descriptors) on a txq and
+ * assume the descriptors are already chained together by caller.
+ */
+static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
+                            struct list_head *head)
+{
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath_buf *bf;
+
+       /*
+        * Insert the frame on the outbound list and
+        * pass it on to the hardware.
+        */
+
+       if (list_empty(head))
+               return;
+
+       bf = list_first_entry(head, struct ath_buf, list);
+
+       list_splice_tail_init(head, &txq->axq_q);
+       txq->axq_depth++;
+       txq->axq_totalqueued++;
+       txq->axq_linkbuf = list_entry(txq->axq_q.prev, struct ath_buf, list);
+
+       DPRINTF(sc, ATH_DBG_QUEUE,
+               "qnum: %d, txq depth: %d\n", txq->axq_qnum, txq->axq_depth);
+
+       if (txq->axq_link == NULL) {
+               ath9k_hw_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr);
+               DPRINTF(sc, ATH_DBG_XMIT,
+                       "TXDP[%u] = %llx (%p)\n",
+                       txq->axq_qnum, ito64(bf->bf_daddr), bf->bf_desc);
+       } else {
+               *txq->axq_link = bf->bf_daddr;
+               DPRINTF(sc, ATH_DBG_XMIT, "link[%u] (%p)=%llx (%p)\n",
+                       txq->axq_qnum, txq->axq_link,
+                       ito64(bf->bf_daddr), bf->bf_desc);
+       }
+       txq->axq_link = &(bf->bf_lastbf->bf_desc->ds_link);
+       ath9k_hw_txstart(ah, txq->axq_qnum);
+}
+
+static struct ath_buf *ath_tx_get_buffer(struct ath_softc *sc)
+{
+       struct ath_buf *bf = NULL;
+
+       spin_lock_bh(&sc->tx.txbuflock);
+
+       if (unlikely(list_empty(&sc->tx.txbuf))) {
+               spin_unlock_bh(&sc->tx.txbuflock);
+               return NULL;
+       }
+
+       bf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list);
+       list_del(&bf->list);
+
+       spin_unlock_bh(&sc->tx.txbuflock);
+
+       return bf;
+}
+
+static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid,
+                             struct list_head *bf_head,
+                             struct ath_tx_control *txctl)
+{
+       struct ath_buf *bf;
+
+       bf = list_first_entry(bf_head, struct ath_buf, list);
+       bf->bf_state.bf_type |= BUF_AMPDU;
+
+       /*
+        * Do not queue to h/w when any of the following conditions is true:
+        * - there are pending frames in software queue
+        * - the TID is currently paused for ADDBA/BAR request
+        * - seqno is not within block-ack window
+        * - h/w queue depth exceeds low water mark
+        */
+       if (!list_empty(&tid->buf_q) || tid->paused ||
+           !BAW_WITHIN(tid->seq_start, tid->baw_size, bf->bf_seqno) ||
+           txctl->txq->axq_depth >= ATH_AGGR_MIN_QDEPTH) {
+               /*
+                * Add this frame to software queue for scheduling later
+                * for aggregation.
+                */
+               list_move_tail(&bf->list, &tid->buf_q);
+               ath_tx_queue_tid(txctl->txq, tid);
+               return;
+       }
+
+       /* Add sub-frame to BAW */
+       ath_tx_addto_baw(sc, tid, bf);
+
+       /* Queue to h/w without aggregation */
+       bf->bf_nframes = 1;
+       bf->bf_lastbf = bf;
+       ath_buf_set_rate(sc, bf);
+       ath_tx_txqaddbuf(sc, txctl->txq, bf_head);
+}
+
+static void ath_tx_send_ht_normal(struct ath_softc *sc, struct ath_txq *txq,
+                                 struct ath_atx_tid *tid,
+                                 struct list_head *bf_head)
+{
+       struct ath_buf *bf;
+
+       bf = list_first_entry(bf_head, struct ath_buf, list);
+       bf->bf_state.bf_type &= ~BUF_AMPDU;
+
+       /* update starting sequence number for subsequent ADDBA request */
+       INCR(tid->seq_start, IEEE80211_SEQ_MAX);
+
+       bf->bf_nframes = 1;
+       bf->bf_lastbf = bf;
+       ath_buf_set_rate(sc, bf);
+       ath_tx_txqaddbuf(sc, txq, bf_head);
+}
+
+static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq,
+                              struct list_head *bf_head)
+{
+       struct ath_buf *bf;
+
+       bf = list_first_entry(bf_head, struct ath_buf, list);
+
+       bf->bf_lastbf = bf;
+       bf->bf_nframes = 1;
+       ath_buf_set_rate(sc, bf);
+       ath_tx_txqaddbuf(sc, txq, bf_head);
+}
+
+static enum ath9k_pkt_type get_hw_packet_type(struct sk_buff *skb)
+{
+       struct ieee80211_hdr *hdr;
+       enum ath9k_pkt_type htype;
+       __le16 fc;
+
+       hdr = (struct ieee80211_hdr *)skb->data;
+       fc = hdr->frame_control;
+
+       if (ieee80211_is_beacon(fc))
+               htype = ATH9K_PKT_TYPE_BEACON;
+       else if (ieee80211_is_probe_resp(fc))
+               htype = ATH9K_PKT_TYPE_PROBE_RESP;
+       else if (ieee80211_is_atim(fc))
+               htype = ATH9K_PKT_TYPE_ATIM;
+       else if (ieee80211_is_pspoll(fc))
+               htype = ATH9K_PKT_TYPE_PSPOLL;
+       else
+               htype = ATH9K_PKT_TYPE_NORMAL;
+
+       return htype;
+}
+
+static bool is_pae(struct sk_buff *skb)
+{
+       struct ieee80211_hdr *hdr;
+       __le16 fc;
+
+       hdr = (struct ieee80211_hdr *)skb->data;
+       fc = hdr->frame_control;
+
+       if (ieee80211_is_data(fc)) {
+               if (ieee80211_is_nullfunc(fc) ||
+                   /* Port Access Entity (IEEE 802.1X) */
+                   (skb->protocol == cpu_to_be16(ETH_P_PAE))) {
+                       return true;
+               }
+       }
+
+       return false;
+}
+
+static int get_hw_crypto_keytype(struct sk_buff *skb)
+{
+       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+
+       if (tx_info->control.hw_key) {
+               if (tx_info->control.hw_key->alg == ALG_WEP)
+                       return ATH9K_KEY_TYPE_WEP;
+               else if (tx_info->control.hw_key->alg == ALG_TKIP)
+                       return ATH9K_KEY_TYPE_TKIP;
+               else if (tx_info->control.hw_key->alg == ALG_CCMP)
+                       return ATH9K_KEY_TYPE_AES;
+       }
+
+       return ATH9K_KEY_TYPE_CLEAR;
+}
+
+static void assign_aggr_tid_seqno(struct sk_buff *skb,
+                                 struct ath_buf *bf)
+{
+       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+       struct ieee80211_hdr *hdr;
+       struct ath_node *an;
+       struct ath_atx_tid *tid;
+       __le16 fc;
+       u8 *qc;
+
+       if (!tx_info->control.sta)
+               return;
+
+       an = (struct ath_node *)tx_info->control.sta->drv_priv;
+       hdr = (struct ieee80211_hdr *)skb->data;
+       fc = hdr->frame_control;
+
+       if (ieee80211_is_data_qos(fc)) {
+               qc = ieee80211_get_qos_ctl(hdr);
+               bf->bf_tidno = qc[0] & 0xf;
+       }
+
+       /*
+        * For HT capable stations, we save tidno for later use.
+        * We also override seqno set by upper layer with the one
+        * in tx aggregation state.
+        *
+        * If fragmentation is on, the sequence number is
+        * not overridden, since it has been
+        * incremented by the fragmentation routine.
+        *
+        * FIXME: check if the fragmentation threshold exceeds
+        * IEEE80211 max.
+        */
+       tid = ATH_AN_2_TID(an, bf->bf_tidno);
+       hdr->seq_ctrl = cpu_to_le16(tid->seq_next <<
+                       IEEE80211_SEQ_SEQ_SHIFT);
+       bf->bf_seqno = tid->seq_next;
+       INCR(tid->seq_next, IEEE80211_SEQ_MAX);
+}
+
+static int setup_tx_flags(struct ath_softc *sc, struct sk_buff *skb,
+                         struct ath_txq *txq)
+{
+       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+       int flags = 0;
+
+       flags |= ATH9K_TXDESC_CLRDMASK; /* needed for crypto errors */
+       flags |= ATH9K_TXDESC_INTREQ;
+
+       if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK)
+               flags |= ATH9K_TXDESC_NOACK;
+
+       return flags;
+}
+
+/*
+ * rix - rate index
+ * pktlen - total bytes (delims + data + fcs + pads + pad delims)
+ * width  - 0 for 20 MHz, 1 for 40 MHz
+ * half_gi - to use 4us v/s 3.6 us for symbol time
+ */
+static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, struct ath_buf *bf,
+                           int width, int half_gi, bool shortPreamble)
+{
+       const struct ath_rate_table *rate_table = sc->cur_rate_table;
+       u32 nbits, nsymbits, duration, nsymbols;
+       u8 rc;
+       int streams, pktlen;
+
+       pktlen = bf_isaggr(bf) ? bf->bf_al : bf->bf_frmlen;
+       rc = rate_table->info[rix].ratecode;
+
+       /* for legacy rates, use old function to compute packet duration */
+       if (!IS_HT_RATE(rc))
+               return ath9k_hw_computetxtime(sc->sc_ah, rate_table, pktlen,
+                                             rix, shortPreamble);
+
+       /* find number of symbols: PLCP + data */
+       nbits = (pktlen << 3) + OFDM_PLCP_BITS;
+       nsymbits = bits_per_symbol[HT_RC_2_MCS(rc)][width];
+       nsymbols = (nbits + nsymbits - 1) / nsymbits;
+
+       if (!half_gi)
+               duration = SYMBOL_TIME(nsymbols);
+       else
+               duration = SYMBOL_TIME_HALFGI(nsymbols);
+
+       /* addup duration for legacy/ht training and signal fields */
+       streams = HT_RC_2_STREAMS(rc);
+       duration += L_STF + L_LTF + L_SIG + HT_SIG + HT_STF + HT_LTF(streams);
+
+       return duration;
+}
+
+static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
+{
+       const struct ath_rate_table *rt = sc->cur_rate_table;
+       struct ath9k_11n_rate_series series[4];
+       struct sk_buff *skb;
+       struct ieee80211_tx_info *tx_info;
+       struct ieee80211_tx_rate *rates;
+       struct ieee80211_hdr *hdr;
+       int i, flags = 0;
+       u8 rix = 0, ctsrate = 0;
+       bool is_pspoll;
+
+       memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4);
+
+       skb = bf->bf_mpdu;
+       tx_info = IEEE80211_SKB_CB(skb);
+       rates = tx_info->control.rates;
+       hdr = (struct ieee80211_hdr *)skb->data;
+       is_pspoll = ieee80211_is_pspoll(hdr->frame_control);
+
+       /*
+        * We check if Short Preamble is needed for the CTS rate by
+        * checking the BSS's global flag.
+        * But for the rate series, IEEE80211_TX_RC_USE_SHORT_PREAMBLE is used.
+        */
+       if (sc->sc_flags & SC_OP_PREAMBLE_SHORT)
+               ctsrate = rt->info[tx_info->control.rts_cts_rate_idx].ratecode |
+                       rt->info[tx_info->control.rts_cts_rate_idx].short_preamble;
+       else
+               ctsrate = rt->info[tx_info->control.rts_cts_rate_idx].ratecode;
+
+       /*
+        * ATH9K_TXDESC_RTSENA and ATH9K_TXDESC_CTSENA are mutually exclusive.
+        * Check the first rate in the series to decide whether RTS/CTS
+        * or CTS-to-self has to be used.
+        */
+       if (rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
+               flags = ATH9K_TXDESC_CTSENA;
+       else if (rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS)
+               flags = ATH9K_TXDESC_RTSENA;
+
+       /* FIXME: Handle aggregation protection */
+       if (sc->config.ath_aggr_prot &&
+           (!bf_isaggr(bf) || (bf_isaggr(bf) && bf->bf_al < 8192))) {
+               flags = ATH9K_TXDESC_RTSENA;
+       }
+
+       /* For AR5416 - RTS cannot be followed by a frame larger than 8K */
+       if (bf_isaggr(bf) && (bf->bf_al > sc->sc_ah->caps.rts_aggr_limit))
+               flags &= ~(ATH9K_TXDESC_RTSENA);
+
+       for (i = 0; i < 4; i++) {
+               if (!rates[i].count || (rates[i].idx < 0))
+                       continue;
+
+               rix = rates[i].idx;
+               series[i].Tries = rates[i].count;
+               series[i].ChSel = sc->tx_chainmask;
+
+               if (rates[i].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
+                       series[i].Rate = rt->info[rix].ratecode |
+                               rt->info[rix].short_preamble;
+               else
+                       series[i].Rate = rt->info[rix].ratecode;
+
+               if (rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS)
+                       series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS;
+               if (rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
+                       series[i].RateFlags |= ATH9K_RATESERIES_2040;
+               if (rates[i].flags & IEEE80211_TX_RC_SHORT_GI)
+                       series[i].RateFlags |= ATH9K_RATESERIES_HALFGI;
+
+               series[i].PktDuration = ath_pkt_duration(sc, rix, bf,
+                        (rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH) != 0,
+                        (rates[i].flags & IEEE80211_TX_RC_SHORT_GI),
+                        (rates[i].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE));
+       }
+
+       /* set dur_update_en for l-sig computation except for PS-Poll frames */
+       ath9k_hw_set11n_ratescenario(sc->sc_ah, bf->bf_desc,
+                                    bf->bf_lastbf->bf_desc,
+                                    !is_pspoll, ctsrate,
+                                    0, series, 4, flags);
+
+       if (sc->config.ath_aggr_prot && flags)
+               ath9k_hw_set11n_burstduration(sc->sc_ah, bf->bf_desc, 8192);
+}
+
+static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf,
+                               struct sk_buff *skb,
+                               struct ath_tx_control *txctl)
+{
+       struct ath_wiphy *aphy = hw->priv;
+       struct ath_softc *sc = aphy->sc;
+       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+       struct ath_tx_info_priv *tx_info_priv;
+       int hdrlen;
+       __le16 fc;
+
+       tx_info_priv = kzalloc(sizeof(*tx_info_priv), GFP_ATOMIC);
+       if (unlikely(!tx_info_priv))
+               return -ENOMEM;
+       tx_info->rate_driver_data[0] = tx_info_priv;
+       tx_info_priv->aphy = aphy;
+       tx_info_priv->frame_type = txctl->frame_type;
+       hdrlen = ieee80211_get_hdrlen_from_skb(skb);
+       fc = hdr->frame_control;
+
+       ATH_TXBUF_RESET(bf);
+
+       bf->bf_frmlen = skb->len + FCS_LEN - (hdrlen & 3);
+
+       if (conf_is_ht(&sc->hw->conf) && !is_pae(skb))
+               bf->bf_state.bf_type |= BUF_HT;
+
+       bf->bf_flags = setup_tx_flags(sc, skb, txctl->txq);
+
+       bf->bf_keytype = get_hw_crypto_keytype(skb);
+       if (bf->bf_keytype != ATH9K_KEY_TYPE_CLEAR) {
+               bf->bf_frmlen += tx_info->control.hw_key->icv_len;
+               bf->bf_keyix = tx_info->control.hw_key->hw_key_idx;
+       } else {
+               bf->bf_keyix = ATH9K_TXKEYIX_INVALID;
+       }
+
+       if (ieee80211_is_data_qos(fc) && (sc->sc_flags & SC_OP_TXAGGR))
+               assign_aggr_tid_seqno(skb, bf);
+
+       bf->bf_mpdu = skb;
+
+       bf->bf_dmacontext = dma_map_single(sc->dev, skb->data,
+                                          skb->len, DMA_TO_DEVICE);
+       if (unlikely(dma_mapping_error(sc->dev, bf->bf_dmacontext))) {
+               bf->bf_mpdu = NULL;
+               kfree(tx_info_priv);
+               tx_info->rate_driver_data[0] = NULL;
+               DPRINTF(sc, ATH_DBG_FATAL, "dma_mapping_error() on TX\n");
+               return -ENOMEM;
+       }
+
+       bf->bf_buf_addr = bf->bf_dmacontext;
+       return 0;
+}
+
+/* FIXME: tx power */
+static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf,
+                            struct ath_tx_control *txctl)
+{
+       struct sk_buff *skb = bf->bf_mpdu;
+       struct ieee80211_tx_info *tx_info =  IEEE80211_SKB_CB(skb);
+       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+       struct ath_node *an = NULL;
+       struct list_head bf_head;
+       struct ath_desc *ds;
+       struct ath_atx_tid *tid;
+       struct ath_hw *ah = sc->sc_ah;
+       int frm_type;
+       __le16 fc;
+
+       frm_type = get_hw_packet_type(skb);
+       fc = hdr->frame_control;
+
+       INIT_LIST_HEAD(&bf_head);
+       list_add_tail(&bf->list, &bf_head);
+
+       ds = bf->bf_desc;
+       ds->ds_link = 0;
+       ds->ds_data = bf->bf_buf_addr;
+
+       ath9k_hw_set11n_txdesc(ah, ds, bf->bf_frmlen, frm_type, MAX_RATE_POWER,
+                              bf->bf_keyix, bf->bf_keytype, bf->bf_flags);
+
+       ath9k_hw_filltxdesc(ah, ds,
+                           skb->len,   /* segment length */
+                           true,       /* first segment */
+                           true,       /* last segment */
+                           ds);        /* first descriptor */
+
+       spin_lock_bh(&txctl->txq->axq_lock);
+
+       if (bf_isht(bf) && (sc->sc_flags & SC_OP_TXAGGR) &&
+           tx_info->control.sta) {
+               an = (struct ath_node *)tx_info->control.sta->drv_priv;
+               tid = ATH_AN_2_TID(an, bf->bf_tidno);
+
+               if (!ieee80211_is_data_qos(fc)) {
+                       ath_tx_send_normal(sc, txctl->txq, &bf_head);
+                       goto tx_done;
+               }
+
+               if (ath_aggr_query(sc, an, bf->bf_tidno)) {
+                       /*
+                        * Try aggregation if it's a unicast data frame
+                        * and the destination is HT capable.
+                        */
+                       ath_tx_send_ampdu(sc, tid, &bf_head, txctl);
+               } else {
+                       /*
+                        * Send this frame as regular when ADDBA
+                        * exchange is neither complete nor pending.
+                        */
+                       ath_tx_send_ht_normal(sc, txctl->txq,
+                                             tid, &bf_head);
+               }
+       } else {
+               ath_tx_send_normal(sc, txctl->txq, &bf_head);
+       }
+
+tx_done:
+       spin_unlock_bh(&txctl->txq->axq_lock);
+}
+
+/* Upon failure caller should free skb */
+int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
+                struct ath_tx_control *txctl)
+{
+       struct ath_wiphy *aphy = hw->priv;
+       struct ath_softc *sc = aphy->sc;
+       struct ath_buf *bf;
+       int r;
+
+       bf = ath_tx_get_buffer(sc);
+       if (!bf) {
+               DPRINTF(sc, ATH_DBG_XMIT, "TX buffers are full\n");
+               return -1;
+       }
+
+       r = ath_tx_setup_buffer(hw, bf, skb, txctl);
+       if (unlikely(r)) {
+               struct ath_txq *txq = txctl->txq;
+
+               DPRINTF(sc, ATH_DBG_FATAL, "TX mem alloc failure\n");
+
+               /* upon ath_tx_processq() this TX queue will be resumed, we
+                * guarantee this will happen by knowing beforehand that
+                * we will at least have to run TX completionon one buffer
+                * on the queue */
+               spin_lock_bh(&txq->axq_lock);
+               if (sc->tx.txq[txq->axq_qnum].axq_depth > 1) {
+                       ieee80211_stop_queue(sc->hw,
+                               skb_get_queue_mapping(skb));
+                       txq->stopped = 1;
+               }
+               spin_unlock_bh(&txq->axq_lock);
+
+               spin_lock_bh(&sc->tx.txbuflock);
+               list_add_tail(&bf->list, &sc->tx.txbuf);
+               spin_unlock_bh(&sc->tx.txbuflock);
+
+               return r;
+       }
+
+       ath_tx_start_dma(sc, bf, txctl);
+
+       return 0;
+}
+
+void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb)
+{
+       struct ath_wiphy *aphy = hw->priv;
+       struct ath_softc *sc = aphy->sc;
+       int hdrlen, padsize;
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+       struct ath_tx_control txctl;
+
+       memset(&txctl, 0, sizeof(struct ath_tx_control));
+
+       /*
+        * As a temporary workaround, assign seq# here; this will likely need
+        * to be cleaned up to work better with Beacon transmission and virtual
+        * BSSes.
+        */
+       if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
+               struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+               if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
+                       sc->tx.seq_no += 0x10;
+               hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
+               hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no);
+       }
+
+       /* Add the padding after the header if this is not already done */
+       hdrlen = ieee80211_get_hdrlen_from_skb(skb);
+       if (hdrlen & 3) {
+               padsize = hdrlen % 4;
+               if (skb_headroom(skb) < padsize) {
+                       DPRINTF(sc, ATH_DBG_XMIT, "TX CABQ padding failed\n");
+                       dev_kfree_skb_any(skb);
+                       return;
+               }
+               skb_push(skb, padsize);
+               memmove(skb->data, skb->data + padsize, hdrlen);
+       }
+
+       txctl.txq = sc->beacon.cabq;
+
+       DPRINTF(sc, ATH_DBG_XMIT, "transmitting CABQ packet, skb: %p\n", skb);
+
+       if (ath_tx_start(hw, skb, &txctl) != 0) {
+               DPRINTF(sc, ATH_DBG_XMIT, "CABQ TX failed\n");
+               goto exit;
+       }
+
+       return;
+exit:
+       dev_kfree_skb_any(skb);
+}
+
+/*****************/
+/* TX Completion */
+/*****************/
+
+static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
+                           int tx_flags)
+{
+       struct ieee80211_hw *hw = sc->hw;
+       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+       struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
+       int hdrlen, padsize;
+       int frame_type = ATH9K_NOT_INTERNAL;
+
+       DPRINTF(sc, ATH_DBG_XMIT, "TX complete: skb: %p\n", skb);
+
+       if (tx_info_priv) {
+               hw = tx_info_priv->aphy->hw;
+               frame_type = tx_info_priv->frame_type;
+       }
+
+       if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK ||
+           tx_info->flags & IEEE80211_TX_STAT_TX_FILTERED) {
+               kfree(tx_info_priv);
+               tx_info->rate_driver_data[0] = NULL;
+       }
+
+       if (tx_flags & ATH_TX_BAR)
+               tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
+
+       if (!(tx_flags & (ATH_TX_ERROR | ATH_TX_XRETRY))) {
+               /* Frame was ACKed */
+               tx_info->flags |= IEEE80211_TX_STAT_ACK;
+       }
+
+       hdrlen = ieee80211_get_hdrlen_from_skb(skb);
+       padsize = hdrlen & 3;
+       if (padsize && hdrlen >= 24) {
+               /*
+                * Remove MAC header padding before giving the frame back to
+                * mac80211.
+                */
+               memmove(skb->data + padsize, skb->data, hdrlen);
+               skb_pull(skb, padsize);
+       }
+
+       if (sc->sc_flags & SC_OP_WAIT_FOR_TX_ACK) {
+               sc->sc_flags &= ~SC_OP_WAIT_FOR_TX_ACK;
+               DPRINTF(sc, ATH_DBG_PS, "Going back to sleep after having "
+                       "received TX status (0x%x)\n",
+                       sc->sc_flags & (SC_OP_WAIT_FOR_BEACON |
+                                       SC_OP_WAIT_FOR_CAB |
+                                       SC_OP_WAIT_FOR_PSPOLL_DATA |
+                                       SC_OP_WAIT_FOR_TX_ACK));
+       }
+
+       if (frame_type == ATH9K_NOT_INTERNAL)
+               ieee80211_tx_status(hw, skb);
+       else
+               ath9k_tx_status(hw, skb);
+}
+
+static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
+                               struct list_head *bf_q,
+                               int txok, int sendbar)
+{
+       struct sk_buff *skb = bf->bf_mpdu;
+       unsigned long flags;
+       int tx_flags = 0;
+
+
+       if (sendbar)
+               tx_flags = ATH_TX_BAR;
+
+       if (!txok) {
+               tx_flags |= ATH_TX_ERROR;
+
+               if (bf_isxretried(bf))
+                       tx_flags |= ATH_TX_XRETRY;
+       }
+
+       dma_unmap_single(sc->dev, bf->bf_dmacontext, skb->len, DMA_TO_DEVICE);
+       ath_tx_complete(sc, skb, tx_flags);
+
+       /*
+        * Return the list of ath_buf of this mpdu to free queue
+        */
+       spin_lock_irqsave(&sc->tx.txbuflock, flags);
+       list_splice_tail_init(bf_q, &sc->tx.txbuf);
+       spin_unlock_irqrestore(&sc->tx.txbuflock, flags);
+}
+
+static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf,
+                             int txok)
+{
+       struct ath_buf *bf_last = bf->bf_lastbf;
+       struct ath_desc *ds = bf_last->bf_desc;
+       u16 seq_st = 0;
+       u32 ba[WME_BA_BMP_SIZE >> 5];
+       int ba_index;
+       int nbad = 0;
+       int isaggr = 0;
+
+       if (ds->ds_txstat.ts_flags == ATH9K_TX_SW_ABORTED)
+               return 0;
+
+       isaggr = bf_isaggr(bf);
+       if (isaggr) {
+               seq_st = ATH_DS_BA_SEQ(ds);
+               memcpy(ba, ATH_DS_BA_BITMAP(ds), WME_BA_BMP_SIZE >> 3);
+       }
+
+       while (bf) {
+               ba_index = ATH_BA_INDEX(seq_st, bf->bf_seqno);
+               if (!txok || (isaggr && !ATH_BA_ISSET(ba, ba_index)))
+                       nbad++;
+
+               bf = bf->bf_next;
+       }
+
+       return nbad;
+}
+
+static void ath_tx_rc_status(struct ath_buf *bf, struct ath_desc *ds,
+                            int nbad, int txok, bool update_rc)
+{
+       struct sk_buff *skb = bf->bf_mpdu;
+       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+       struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
+       struct ieee80211_hw *hw = tx_info_priv->aphy->hw;
+       u8 i, tx_rateindex;
+
+       if (txok)
+               tx_info->status.ack_signal = ds->ds_txstat.ts_rssi;
+
+       tx_rateindex = ds->ds_txstat.ts_rateindex;
+       WARN_ON(tx_rateindex >= hw->max_rates);
+
+       tx_info_priv->update_rc = update_rc;
+       if (ds->ds_txstat.ts_status & ATH9K_TXERR_FILT)
+               tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
+
+       if ((ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) == 0 &&
+           (bf->bf_flags & ATH9K_TXDESC_NOACK) == 0 && update_rc) {
+               if (ieee80211_is_data(hdr->frame_control)) {
+                       memcpy(&tx_info_priv->tx, &ds->ds_txstat,
+                              sizeof(tx_info_priv->tx));
+                       tx_info_priv->n_frames = bf->bf_nframes;
+                       tx_info_priv->n_bad_frames = nbad;
+               }
+       }
+
+       for (i = tx_rateindex + 1; i < hw->max_rates; i++)
+               tx_info->status.rates[i].count = 0;
+
+       tx_info->status.rates[tx_rateindex].count = bf->bf_retries + 1;
+}
+
+static void ath_wake_mac80211_queue(struct ath_softc *sc, struct ath_txq *txq)
+{
+       int qnum;
+
+       spin_lock_bh(&txq->axq_lock);
+       if (txq->stopped &&
+           sc->tx.txq[txq->axq_qnum].axq_depth <= (ATH_TXBUF - 20)) {
+               qnum = ath_get_mac80211_qnum(txq->axq_qnum, sc);
+               if (qnum != -1) {
+                       ieee80211_wake_queue(sc->hw, qnum);
+                       txq->stopped = 0;
+               }
+       }
+       spin_unlock_bh(&txq->axq_lock);
+}
+
+static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
+{
+       struct ath_hw *ah = sc->sc_ah;
+       struct ath_buf *bf, *lastbf, *bf_held = NULL;
+       struct list_head bf_head;
+       struct ath_desc *ds;
+       int txok;
+       int status;
+
+       DPRINTF(sc, ATH_DBG_QUEUE, "tx queue %d (%x), link %p\n",
+               txq->axq_qnum, ath9k_hw_gettxbuf(sc->sc_ah, txq->axq_qnum),
+               txq->axq_link);
+
+       for (;;) {
+               spin_lock_bh(&txq->axq_lock);
+               if (list_empty(&txq->axq_q)) {
+                       txq->axq_link = NULL;
+                       txq->axq_linkbuf = NULL;
+                       spin_unlock_bh(&txq->axq_lock);
+                       break;
+               }
+               bf = list_first_entry(&txq->axq_q, struct ath_buf, list);
+
+               /*
+                * There is a race condition that a BH gets scheduled
+                * after sw writes TxE and before hw re-load the last
+                * descriptor to get the newly chained one.
+                * Software must keep the last DONE descriptor as a
+                * holding descriptor - software does so by marking
+                * it with the STALE flag.
+                */
+               bf_held = NULL;
+               if (bf->bf_stale) {
+                       bf_held = bf;
+                       if (list_is_last(&bf_held->list, &txq->axq_q)) {
+                               txq->axq_link = NULL;
+                               txq->axq_linkbuf = NULL;
+                               spin_unlock_bh(&txq->axq_lock);
+
+                               /*
+                                * The holding descriptor is the last
+                                * descriptor in queue. It's safe to remove
+                                * the last holding descriptor in BH context.
+                                */
+                               spin_lock_bh(&sc->tx.txbuflock);
+                               list_move_tail(&bf_held->list, &sc->tx.txbuf);
+                               spin_unlock_bh(&sc->tx.txbuflock);
+
+                               break;
+                       } else {
+                               bf = list_entry(bf_held->list.next,
+                                               struct ath_buf, list);
+                       }
+               }
+
+               lastbf = bf->bf_lastbf;
+               ds = lastbf->bf_desc;
+
+               status = ath9k_hw_txprocdesc(ah, ds);
+               if (status == -EINPROGRESS) {
+                       spin_unlock_bh(&txq->axq_lock);
+                       break;
+               }
+               if (bf->bf_desc == txq->axq_lastdsWithCTS)
+                       txq->axq_lastdsWithCTS = NULL;
+               if (ds == txq->axq_gatingds)
+                       txq->axq_gatingds = NULL;
+
+               /*
+                * Remove ath_buf's of the same transmit unit from txq,
+                * however leave the last descriptor back as the holding
+                * descriptor for hw.
+                */
+               lastbf->bf_stale = true;
+               INIT_LIST_HEAD(&bf_head);
+               if (!list_is_singular(&lastbf->list))
+                       list_cut_position(&bf_head,
+                               &txq->axq_q, lastbf->list.prev);
+
+               txq->axq_depth--;
+               if (bf_isaggr(bf))
+                       txq->axq_aggr_depth--;
+
+               txok = (ds->ds_txstat.ts_status == 0);
+               spin_unlock_bh(&txq->axq_lock);
+
+               if (bf_held) {
+                       spin_lock_bh(&sc->tx.txbuflock);
+                       list_move_tail(&bf_held->list, &sc->tx.txbuf);
+                       spin_unlock_bh(&sc->tx.txbuflock);
+               }
+
+               if (!bf_isampdu(bf)) {
+                       /*
+                        * This frame is sent out as a single frame.
+                        * Use hardware retry status for this frame.
+                        */
+                       bf->bf_retries = ds->ds_txstat.ts_longretry;
+                       if (ds->ds_txstat.ts_status & ATH9K_TXERR_XRETRY)
+                               bf->bf_state.bf_type |= BUF_XRETRY;
+                       ath_tx_rc_status(bf, ds, 0, txok, true);
+               }
+
+               if (bf_isampdu(bf))
+                       ath_tx_complete_aggr(sc, txq, bf, &bf_head, txok);
+               else
+                       ath_tx_complete_buf(sc, bf, &bf_head, txok, 0);
+
+               ath_wake_mac80211_queue(sc, txq);
+
+               spin_lock_bh(&txq->axq_lock);
+               if (sc->sc_flags & SC_OP_TXAGGR)
+                       ath_txq_schedule(sc, txq);
+               spin_unlock_bh(&txq->axq_lock);
+       }
+}
+
+
+void ath_tx_tasklet(struct ath_softc *sc)
+{
+       int i;
+       u32 qcumask = ((1 << ATH9K_NUM_TX_QUEUES) - 1);
+
+       ath9k_hw_gettxintrtxqs(sc->sc_ah, &qcumask);
+
+       for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
+               if (ATH_TXQ_SETUP(sc, i) && (qcumask & (1 << i)))
+                       ath_tx_processq(sc, &sc->tx.txq[i]);
+       }
+}
+
+/*****************/
+/* Init, Cleanup */
+/*****************/
+
+int ath_tx_init(struct ath_softc *sc, int nbufs)
+{
+       int error = 0;
+
+       spin_lock_init(&sc->tx.txbuflock);
+
+       error = ath_descdma_setup(sc, &sc->tx.txdma, &sc->tx.txbuf,
+                                 "tx", nbufs, 1);
+       if (error != 0) {
+               DPRINTF(sc, ATH_DBG_FATAL,
+                       "Failed to allocate tx descriptors: %d\n", error);
+               goto err;
+       }
+
+       error = ath_descdma_setup(sc, &sc->beacon.bdma, &sc->beacon.bbuf,
+                                 "beacon", ATH_BCBUF, 1);
+       if (error != 0) {
+               DPRINTF(sc, ATH_DBG_FATAL,
+                       "Failed to allocate beacon descriptors: %d\n", error);
+               goto err;
+       }
+
+err:
+       if (error != 0)
+               ath_tx_cleanup(sc);
+
+       return error;
+}
+
+void ath_tx_cleanup(struct ath_softc *sc)
+{
+       if (sc->beacon.bdma.dd_desc_len != 0)
+               ath_descdma_cleanup(sc, &sc->beacon.bdma, &sc->beacon.bbuf);
+
+       if (sc->tx.txdma.dd_desc_len != 0)
+               ath_descdma_cleanup(sc, &sc->tx.txdma, &sc->tx.txbuf);
+}
+
+void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an)
+{
+       struct ath_atx_tid *tid;
+       struct ath_atx_ac *ac;
+       int tidno, acno;
+
+       for (tidno = 0, tid = &an->tid[tidno];
+            tidno < WME_NUM_TID;
+            tidno++, tid++) {
+               tid->an        = an;
+               tid->tidno     = tidno;
+               tid->seq_start = tid->seq_next = 0;
+               tid->baw_size  = WME_MAX_BA;
+               tid->baw_head  = tid->baw_tail = 0;
+               tid->sched     = false;
+               tid->paused    = false;
+               tid->state &= ~AGGR_CLEANUP;
+               INIT_LIST_HEAD(&tid->buf_q);
+               acno = TID_TO_WME_AC(tidno);
+               tid->ac = &an->ac[acno];
+               tid->state &= ~AGGR_ADDBA_COMPLETE;
+               tid->state &= ~AGGR_ADDBA_PROGRESS;
+               tid->addba_exchangeattempts = 0;
+       }
+
+       for (acno = 0, ac = &an->ac[acno];
+            acno < WME_NUM_AC; acno++, ac++) {
+               ac->sched    = false;
+               INIT_LIST_HEAD(&ac->tid_q);
+
+               switch (acno) {
+               case WME_AC_BE:
+                       ac->qnum = ath_tx_get_qnum(sc,
+                                  ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_BE);
+                       break;
+               case WME_AC_BK:
+                       ac->qnum = ath_tx_get_qnum(sc,
+                                  ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_BK);
+                       break;
+               case WME_AC_VI:
+                       ac->qnum = ath_tx_get_qnum(sc,
+                                  ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_VI);
+                       break;
+               case WME_AC_VO:
+                       ac->qnum = ath_tx_get_qnum(sc,
+                                  ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_VO);
+                       break;
+               }
+       }
+}
+
+void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an)
+{
+       int i;
+       struct ath_atx_ac *ac, *ac_tmp;
+       struct ath_atx_tid *tid, *tid_tmp;
+       struct ath_txq *txq;
+
+       for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
+               if (ATH_TXQ_SETUP(sc, i)) {
+                       txq = &sc->tx.txq[i];
+
+                       spin_lock(&txq->axq_lock);
+
+                       list_for_each_entry_safe(ac,
+                                       ac_tmp, &txq->axq_acq, list) {
+                               tid = list_first_entry(&ac->tid_q,
+                                               struct ath_atx_tid, list);
+                               if (tid && tid->an != an)
+                                       continue;
+                               list_del(&ac->list);
+                               ac->sched = false;
+
+                               list_for_each_entry_safe(tid,
+                                               tid_tmp, &ac->tid_q, list) {
+                                       list_del(&tid->list);
+                                       tid->sched = false;
+                                       ath_tid_drain(sc, txq, tid);
+                                       tid->state &= ~AGGR_ADDBA_COMPLETE;
+                                       tid->addba_exchangeattempts = 0;
+                                       tid->state &= ~AGGR_CLEANUP;
+                               }
+                       }
+
+                       spin_unlock(&txq->axq_lock);
+               }
+       }
+}
diff --git a/drivers/net/wireless/ath/main.c b/drivers/net/wireless/ath/main.c
new file mode 100644 (file)
index 0000000..9949b11
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2009 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/kernel.h>
+#include <linux/module.h>
+
+MODULE_AUTHOR("Atheros Communications");
+MODULE_DESCRIPTION("Shared library for Atheros wireless LAN cards.");
+MODULE_LICENSE("Dual BSD/GPL");
diff --git a/drivers/net/wireless/ath/regd.c b/drivers/net/wireless/ath/regd.c
new file mode 100644 (file)
index 0000000..eef370b
--- /dev/null
@@ -0,0 +1,575 @@
+/*
+ * Copyright (c) 2008-2009 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/kernel.h>
+#include <linux/slab.h>
+#include <net/cfg80211.h>
+#include <net/mac80211.h>
+#include "regd.h"
+#include "regd_common.h"
+
+/*
+ * This is a set of common rules used by our world regulatory domains.
+ * We have 12 world regulatory domains. To save space we consolidate
+ * the regulatory domains in 5 structures by frequency and change
+ * the flags on our reg_notifier() on a case by case basis.
+ */
+
+/* Only these channels all allow active scan on all world regulatory domains */
+#define ATH9K_2GHZ_CH01_11     REG_RULE(2412-10, 2462+10, 40, 0, 20, 0)
+
+/* We enable active scan on these a case by case basis by regulatory domain */
+#define ATH9K_2GHZ_CH12_13     REG_RULE(2467-10, 2472+10, 40, 0, 20,\
+                                       NL80211_RRF_PASSIVE_SCAN)
+#define ATH9K_2GHZ_CH14                REG_RULE(2484-10, 2484+10, 40, 0, 20,\
+                               NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_OFDM)
+
+/* We allow IBSS on these on a case by case basis by regulatory domain */
+#define ATH9K_5GHZ_5150_5350   REG_RULE(5150-10, 5350+10, 40, 0, 30,\
+                               NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS)
+#define ATH9K_5GHZ_5470_5850   REG_RULE(5470-10, 5850+10, 40, 0, 30,\
+                               NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS)
+#define ATH9K_5GHZ_5725_5850   REG_RULE(5725-10, 5850+10, 40, 0, 30,\
+                               NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS)
+
+#define ATH9K_2GHZ_ALL         ATH9K_2GHZ_CH01_11, \
+                               ATH9K_2GHZ_CH12_13, \
+                               ATH9K_2GHZ_CH14
+
+#define ATH9K_5GHZ_ALL         ATH9K_5GHZ_5150_5350, \
+                               ATH9K_5GHZ_5470_5850
+/* This one skips what we call "mid band" */
+#define ATH9K_5GHZ_NO_MIDBAND  ATH9K_5GHZ_5150_5350, \
+                               ATH9K_5GHZ_5725_5850
+
+/* Can be used for:
+ * 0x60, 0x61, 0x62 */
+static const struct ieee80211_regdomain ath_world_regdom_60_61_62 = {
+       .n_reg_rules = 5,
+       .alpha2 =  "99",
+       .reg_rules = {
+               ATH9K_2GHZ_ALL,
+               ATH9K_5GHZ_ALL,
+       }
+};
+
+/* Can be used by 0x63 and 0x65 */
+static const struct ieee80211_regdomain ath_world_regdom_63_65 = {
+       .n_reg_rules = 4,
+       .alpha2 =  "99",
+       .reg_rules = {
+               ATH9K_2GHZ_CH01_11,
+               ATH9K_2GHZ_CH12_13,
+               ATH9K_5GHZ_NO_MIDBAND,
+       }
+};
+
+/* Can be used by 0x64 only */
+static const struct ieee80211_regdomain ath_world_regdom_64 = {
+       .n_reg_rules = 3,
+       .alpha2 =  "99",
+       .reg_rules = {
+               ATH9K_2GHZ_CH01_11,
+               ATH9K_5GHZ_NO_MIDBAND,
+       }
+};
+
+/* Can be used by 0x66 and 0x69 */
+static const struct ieee80211_regdomain ath_world_regdom_66_69 = {
+       .n_reg_rules = 3,
+       .alpha2 =  "99",
+       .reg_rules = {
+               ATH9K_2GHZ_CH01_11,
+               ATH9K_5GHZ_ALL,
+       }
+};
+
+/* Can be used by 0x67, 0x6A and 0x68 */
+static const struct ieee80211_regdomain ath_world_regdom_67_68_6A = {
+       .n_reg_rules = 4,
+       .alpha2 =  "99",
+       .reg_rules = {
+               ATH9K_2GHZ_CH01_11,
+               ATH9K_2GHZ_CH12_13,
+               ATH9K_5GHZ_ALL,
+       }
+};
+
+static inline bool is_wwr_sku(u16 regd)
+{
+       return ((regd & WORLD_SKU_MASK) == WORLD_SKU_PREFIX) ||
+               (regd == WORLD);
+}
+
+static u16 ath_regd_get_eepromRD(struct ath_regulatory *reg)
+{
+       return reg->current_rd & ~WORLDWIDE_ROAMING_FLAG;
+}
+
+bool ath_is_world_regd(struct ath_regulatory *reg)
+{
+       return is_wwr_sku(ath_regd_get_eepromRD(reg));
+}
+EXPORT_SYMBOL(ath_is_world_regd);
+
+static const struct ieee80211_regdomain *ath_default_world_regdomain(void)
+{
+       /* this is the most restrictive */
+       return &ath_world_regdom_64;
+}
+
+static const struct
+ieee80211_regdomain *ath_world_regdomain(struct ath_regulatory *reg)
+{
+       switch (reg->regpair->regDmnEnum) {
+       case 0x60:
+       case 0x61:
+       case 0x62:
+               return &ath_world_regdom_60_61_62;
+       case 0x63:
+       case 0x65:
+               return &ath_world_regdom_63_65;
+       case 0x64:
+               return &ath_world_regdom_64;
+       case 0x66:
+       case 0x69:
+               return &ath_world_regdom_66_69;
+       case 0x67:
+       case 0x68:
+       case 0x6A:
+               return &ath_world_regdom_67_68_6A;
+       default:
+               WARN_ON(1);
+               return ath_default_world_regdomain();
+       }
+}
+
+/* Frequency is one where radar detection is required */
+static bool ath_is_radar_freq(u16 center_freq)
+{
+       return (center_freq >= 5260 && center_freq <= 5700);
+}
+
+/*
+ * N.B: These exception rules do not apply radar freqs.
+ *
+ * - We enable adhoc (or beaconing) if allowed by 11d
+ * - We enable active scan if the channel is allowed by 11d
+ * - If no country IE has been processed and a we determine we have
+ *   received a beacon on a channel we can enable active scan and
+ *   adhoc (or beaconing).
+ */
+static void
+ath_reg_apply_beaconing_flags(struct wiphy *wiphy,
+                             enum nl80211_reg_initiator initiator)
+{
+       enum ieee80211_band band;
+       struct ieee80211_supported_band *sband;
+       const struct ieee80211_reg_rule *reg_rule;
+       struct ieee80211_channel *ch;
+       unsigned int i;
+       u32 bandwidth = 0;
+       int r;
+
+       for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
+
+               if (!wiphy->bands[band])
+                       continue;
+
+               sband = wiphy->bands[band];
+
+               for (i = 0; i < sband->n_channels; i++) {
+
+                       ch = &sband->channels[i];
+
+                       if (ath_is_radar_freq(ch->center_freq) ||
+                           (ch->flags & IEEE80211_CHAN_RADAR))
+                               continue;
+
+                       if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) {
+                               r = freq_reg_info(wiphy,
+                                                 ch->center_freq,
+                                                 bandwidth,
+                                                 &reg_rule);
+                               if (r)
+                                       continue;
+                               /*
+                                * If 11d had a rule for this channel ensure
+                                * we enable adhoc/beaconing if it allows us to
+                                * use it. Note that we would have disabled it
+                                * by applying our static world regdomain by
+                                * default during init, prior to calling our
+                                * regulatory_hint().
+                                */
+                               if (!(reg_rule->flags &
+                                   NL80211_RRF_NO_IBSS))
+                                       ch->flags &=
+                                         ~IEEE80211_CHAN_NO_IBSS;
+                               if (!(reg_rule->flags &
+                                   NL80211_RRF_PASSIVE_SCAN))
+                                       ch->flags &=
+                                         ~IEEE80211_CHAN_PASSIVE_SCAN;
+                       } else {
+                               if (ch->beacon_found)
+                                       ch->flags &= ~(IEEE80211_CHAN_NO_IBSS |
+                                         IEEE80211_CHAN_PASSIVE_SCAN);
+                       }
+               }
+       }
+
+}
+
+/* Allows active scan scan on Ch 12 and 13 */
+static void
+ath_reg_apply_active_scan_flags(struct wiphy *wiphy,
+                               enum nl80211_reg_initiator initiator)
+{
+       struct ieee80211_supported_band *sband;
+       struct ieee80211_channel *ch;
+       const struct ieee80211_reg_rule *reg_rule;
+       u32 bandwidth = 0;
+       int r;
+
+       sband = wiphy->bands[IEEE80211_BAND_2GHZ];
+
+       /*
+        * If no country IE has been received always enable active scan
+        * on these channels. This is only done for specific regulatory SKUs
+        */
+       if (initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE) {
+               ch = &sband->channels[11]; /* CH 12 */
+               if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
+                       ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
+               ch = &sband->channels[12]; /* CH 13 */
+               if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
+                       ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
+               return;
+       }
+
+       /*
+        * If a country IE has been recieved check its rule for this
+        * channel first before enabling active scan. The passive scan
+        * would have been enforced by the initial processing of our
+        * custom regulatory domain.
+        */
+
+       ch = &sband->channels[11]; /* CH 12 */
+       r = freq_reg_info(wiphy, ch->center_freq, bandwidth, &reg_rule);
+       if (!r) {
+               if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN))
+                       if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
+                               ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
+       }
+
+       ch = &sband->channels[12]; /* CH 13 */
+       r = freq_reg_info(wiphy, ch->center_freq, bandwidth, &reg_rule);
+       if (!r) {
+               if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN))
+                       if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
+                               ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
+       }
+}
+
+/* Always apply Radar/DFS rules on freq range 5260 MHz - 5700 MHz */
+static void ath_reg_apply_radar_flags(struct wiphy *wiphy)
+{
+       struct ieee80211_supported_band *sband;
+       struct ieee80211_channel *ch;
+       unsigned int i;
+
+       if (!wiphy->bands[IEEE80211_BAND_5GHZ])
+               return;
+
+       sband = wiphy->bands[IEEE80211_BAND_5GHZ];
+
+       for (i = 0; i < sband->n_channels; i++) {
+               ch = &sband->channels[i];
+               if (!ath_is_radar_freq(ch->center_freq))
+                       continue;
+               /* We always enable radar detection/DFS on this
+                * frequency range. Additionally we also apply on
+                * this frequency range:
+                * - If STA mode does not yet have DFS supports disable
+                *   active scanning
+                * - If adhoc mode does not support DFS yet then
+                *   disable adhoc in the frequency.
+                * - If AP mode does not yet support radar detection/DFS
+                *   do not allow AP mode
+                */
+               if (!(ch->flags & IEEE80211_CHAN_DISABLED))
+                       ch->flags |= IEEE80211_CHAN_RADAR |
+                                    IEEE80211_CHAN_NO_IBSS |
+                                    IEEE80211_CHAN_PASSIVE_SCAN;
+       }
+}
+
+static void ath_reg_apply_world_flags(struct wiphy *wiphy,
+                                     enum nl80211_reg_initiator initiator,
+                                     struct ath_regulatory *reg)
+{
+       switch (reg->regpair->regDmnEnum) {
+       case 0x60:
+       case 0x63:
+       case 0x66:
+       case 0x67:
+               ath_reg_apply_beaconing_flags(wiphy, initiator);
+               break;
+       case 0x68:
+               ath_reg_apply_beaconing_flags(wiphy, initiator);
+               ath_reg_apply_active_scan_flags(wiphy, initiator);
+               break;
+       }
+       return;
+}
+
+int ath_reg_notifier_apply(struct wiphy *wiphy,
+                          struct regulatory_request *request,
+                          struct ath_regulatory *reg)
+{
+       /* We always apply this */
+       ath_reg_apply_radar_flags(wiphy);
+
+       switch (request->initiator) {
+       case NL80211_REGDOM_SET_BY_DRIVER:
+       case NL80211_REGDOM_SET_BY_CORE:
+       case NL80211_REGDOM_SET_BY_USER:
+               break;
+       case NL80211_REGDOM_SET_BY_COUNTRY_IE:
+               if (ath_is_world_regd(reg))
+                       ath_reg_apply_world_flags(wiphy, request->initiator,
+                                                 reg);
+               break;
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL(ath_reg_notifier_apply);
+
+static bool ath_regd_is_eeprom_valid(struct ath_regulatory *reg)
+{
+        u16 rd = ath_regd_get_eepromRD(reg);
+       int i;
+
+       if (rd & COUNTRY_ERD_FLAG) {
+               /* EEPROM value is a country code */
+               u16 cc = rd & ~COUNTRY_ERD_FLAG;
+               printk(KERN_DEBUG
+                      "ath: EEPROM indicates we should expect "
+                       "a country code\n");
+               for (i = 0; i < ARRAY_SIZE(allCountries); i++)
+                       if (allCountries[i].countryCode == cc)
+                               return true;
+       } else {
+               /* EEPROM value is a regpair value */
+               if (rd != CTRY_DEFAULT)
+                       printk(KERN_DEBUG "ath: EEPROM indicates we "
+                              "should expect a direct regpair map\n");
+               for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++)
+                       if (regDomainPairs[i].regDmnEnum == rd)
+                               return true;
+       }
+       printk(KERN_DEBUG
+                "ath: invalid regulatory domain/country code 0x%x\n", rd);
+       return false;
+}
+
+/* EEPROM country code to regpair mapping */
+static struct country_code_to_enum_rd*
+ath_regd_find_country(u16 countryCode)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(allCountries); i++) {
+               if (allCountries[i].countryCode == countryCode)
+                       return &allCountries[i];
+       }
+       return NULL;
+}
+
+/* EEPROM rd code to regpair mapping */
+static struct country_code_to_enum_rd*
+ath_regd_find_country_by_rd(int regdmn)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(allCountries); i++) {
+               if (allCountries[i].regDmnEnum == regdmn)
+                       return &allCountries[i];
+       }
+       return NULL;
+}
+
+/* Returns the map of the EEPROM set RD to a country code */
+static u16 ath_regd_get_default_country(u16 rd)
+{
+       if (rd & COUNTRY_ERD_FLAG) {
+               struct country_code_to_enum_rd *country = NULL;
+               u16 cc = rd & ~COUNTRY_ERD_FLAG;
+
+               country = ath_regd_find_country(cc);
+               if (country != NULL)
+                       return cc;
+       }
+
+       return CTRY_DEFAULT;
+}
+
+static struct reg_dmn_pair_mapping*
+ath_get_regpair(int regdmn)
+{
+       int i;
+
+       if (regdmn == NO_ENUMRD)
+               return NULL;
+       for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++) {
+               if (regDomainPairs[i].regDmnEnum == regdmn)
+                       return &regDomainPairs[i];
+       }
+       return NULL;
+}
+
+static int
+ath_regd_init_wiphy(struct ath_regulatory *reg,
+                   struct wiphy *wiphy,
+                   int (*reg_notifier)(struct wiphy *wiphy,
+                                       struct regulatory_request *request))
+{
+       const struct ieee80211_regdomain *regd;
+
+       wiphy->reg_notifier = reg_notifier;
+       wiphy->strict_regulatory = true;
+
+       if (ath_is_world_regd(reg)) {
+               /*
+                * Anything applied here (prior to wiphy registration) gets
+                * saved on the wiphy orig_* parameters
+                */
+               regd = ath_world_regdomain(reg);
+               wiphy->custom_regulatory = true;
+               wiphy->strict_regulatory = false;
+       } else {
+               /*
+                * This gets applied in the case of the absense of CRDA,
+                * it's our own custom world regulatory domain, similar to
+                * cfg80211's but we enable passive scanning.
+                */
+               regd = ath_default_world_regdomain();
+       }
+       wiphy_apply_custom_regulatory(wiphy, regd);
+       ath_reg_apply_radar_flags(wiphy);
+       ath_reg_apply_world_flags(wiphy, NL80211_REGDOM_SET_BY_DRIVER, reg);
+       return 0;
+}
+
+int
+ath_regd_init(struct ath_regulatory *reg,
+             struct wiphy *wiphy,
+             int (*reg_notifier)(struct wiphy *wiphy,
+                                 struct regulatory_request *request))
+{
+       struct country_code_to_enum_rd *country = NULL;
+       u16 regdmn;
+
+       if (!reg)
+               return -EINVAL;
+
+       printk(KERN_DEBUG "ath: EEPROM regdomain: 0x%0x\n", reg->current_rd);
+
+       if (!ath_regd_is_eeprom_valid(reg)) {
+               printk(KERN_ERR "ath: Invalid EEPROM contents\n");
+               return -EINVAL;
+       }
+
+       regdmn = ath_regd_get_eepromRD(reg);
+       reg->country_code = ath_regd_get_default_country(regdmn);
+
+       if (reg->country_code == CTRY_DEFAULT &&
+           regdmn == CTRY_DEFAULT) {
+               printk(KERN_DEBUG "ath: EEPROM indicates default "
+                      "country code should be used\n");
+               reg->country_code = CTRY_UNITED_STATES;
+       }
+
+       if (reg->country_code == CTRY_DEFAULT) {
+               country = NULL;
+       } else {
+               printk(KERN_DEBUG "ath: doing EEPROM country->regdmn "
+                      "map search\n");
+               country = ath_regd_find_country(reg->country_code);
+               if (country == NULL) {
+                       printk(KERN_DEBUG
+                               "ath: no valid country maps found for "
+                               "country code: 0x%0x\n",
+                               reg->country_code);
+                       return -EINVAL;
+               } else {
+                       regdmn = country->regDmnEnum;
+                       printk(KERN_DEBUG "ath: country maps to "
+                              "regdmn code: 0x%0x\n",
+                              regdmn);
+               }
+       }
+
+       reg->regpair = ath_get_regpair(regdmn);
+
+       if (!reg->regpair) {
+               printk(KERN_DEBUG "ath: "
+                       "No regulatory domain pair found, cannot continue\n");
+               return -EINVAL;
+       }
+
+       if (!country)
+               country = ath_regd_find_country_by_rd(regdmn);
+
+       if (country) {
+               reg->alpha2[0] = country->isoName[0];
+               reg->alpha2[1] = country->isoName[1];
+       } else {
+               reg->alpha2[0] = '0';
+               reg->alpha2[1] = '0';
+       }
+
+       printk(KERN_DEBUG "ath: Country alpha2 being used: %c%c\n",
+               reg->alpha2[0], reg->alpha2[1]);
+       printk(KERN_DEBUG "ath: Regpair used: 0x%0x\n",
+               reg->regpair->regDmnEnum);
+
+       ath_regd_init_wiphy(reg, wiphy, reg_notifier);
+       return 0;
+}
+EXPORT_SYMBOL(ath_regd_init);
+
+u32 ath_regd_get_band_ctl(struct ath_regulatory *reg,
+                         enum ieee80211_band band)
+{
+       if (!reg->regpair ||
+           (reg->country_code == CTRY_DEFAULT &&
+            is_wwr_sku(ath_regd_get_eepromRD(reg)))) {
+               return SD_NO_CTL;
+       }
+
+       switch (band) {
+       case IEEE80211_BAND_2GHZ:
+               return reg->regpair->reg_2ghz_ctl;
+       case IEEE80211_BAND_5GHZ:
+               return reg->regpair->reg_5ghz_ctl;
+       default:
+               return NO_CTL;
+       }
+
+       return NO_CTL;
+}
+EXPORT_SYMBOL(ath_regd_get_band_ctl);
diff --git a/drivers/net/wireless/ath/regd.h b/drivers/net/wireless/ath/regd.h
new file mode 100644 (file)
index 0000000..07291cc
--- /dev/null
@@ -0,0 +1,265 @@
+/*
+ * Copyright (c) 2008-2009 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 REGD_H
+#define REGD_H
+
+#include <linux/nl80211.h>
+
+#include <net/cfg80211.h>
+
+#define NO_CTL 0xff
+#define SD_NO_CTL               0xE0
+#define NO_CTL                  0xff
+#define CTL_MODE_M              7
+#define CTL_11A                 0
+#define CTL_11B                 1
+#define CTL_11G                 2
+#define CTL_2GHT20              5
+#define CTL_5GHT20              6
+#define CTL_2GHT40              7
+#define CTL_5GHT40              8
+
+#define CTRY_DEBUG 0x1ff
+#define CTRY_DEFAULT 0
+
+#define COUNTRY_ERD_FLAG        0x8000
+#define WORLDWIDE_ROAMING_FLAG  0x4000
+
+#define MULTI_DOMAIN_MASK 0xFF00
+
+#define WORLD_SKU_MASK          0x00F0
+#define WORLD_SKU_PREFIX        0x0060
+
+#define CHANNEL_HALF_BW         10
+#define CHANNEL_QUARTER_BW      5
+
+struct reg_dmn_pair_mapping {
+       u16 regDmnEnum;
+       u16 reg_5ghz_ctl;
+       u16 reg_2ghz_ctl;
+};
+
+struct country_code_to_enum_rd {
+       u16 countryCode;
+       u16 regDmnEnum;
+       const char *isoName;
+};
+
+struct ath_regulatory {
+       char alpha2[2];
+       u16 country_code;
+       u16 max_power_level;
+       u32 tp_scale;
+       u16 current_rd;
+       u16 current_rd_ext;
+       int16_t power_limit;
+       struct reg_dmn_pair_mapping *regpair;
+};
+
+enum CountryCode {
+       CTRY_ALBANIA = 8,
+       CTRY_ALGERIA = 12,
+       CTRY_ARGENTINA = 32,
+       CTRY_ARMENIA = 51,
+       CTRY_AUSTRALIA = 36,
+       CTRY_AUSTRIA = 40,
+       CTRY_AZERBAIJAN = 31,
+       CTRY_BAHRAIN = 48,
+       CTRY_BELARUS = 112,
+       CTRY_BELGIUM = 56,
+       CTRY_BELIZE = 84,
+       CTRY_BOLIVIA = 68,
+       CTRY_BOSNIA_HERZ = 70,
+       CTRY_BRAZIL = 76,
+       CTRY_BRUNEI_DARUSSALAM = 96,
+       CTRY_BULGARIA = 100,
+       CTRY_CANADA = 124,
+       CTRY_CHILE = 152,
+       CTRY_CHINA = 156,
+       CTRY_COLOMBIA = 170,
+       CTRY_COSTA_RICA = 188,
+       CTRY_CROATIA = 191,
+       CTRY_CYPRUS = 196,
+       CTRY_CZECH = 203,
+       CTRY_DENMARK = 208,
+       CTRY_DOMINICAN_REPUBLIC = 214,
+       CTRY_ECUADOR = 218,
+       CTRY_EGYPT = 818,
+       CTRY_EL_SALVADOR = 222,
+       CTRY_ESTONIA = 233,
+       CTRY_FAEROE_ISLANDS = 234,
+       CTRY_FINLAND = 246,
+       CTRY_FRANCE = 250,
+       CTRY_GEORGIA = 268,
+       CTRY_GERMANY = 276,
+       CTRY_GREECE = 300,
+       CTRY_GUATEMALA = 320,
+       CTRY_HONDURAS = 340,
+       CTRY_HONG_KONG = 344,
+       CTRY_HUNGARY = 348,
+       CTRY_ICELAND = 352,
+       CTRY_INDIA = 356,
+       CTRY_INDONESIA = 360,
+       CTRY_IRAN = 364,
+       CTRY_IRAQ = 368,
+       CTRY_IRELAND = 372,
+       CTRY_ISRAEL = 376,
+       CTRY_ITALY = 380,
+       CTRY_JAMAICA = 388,
+       CTRY_JAPAN = 392,
+       CTRY_JORDAN = 400,
+       CTRY_KAZAKHSTAN = 398,
+       CTRY_KENYA = 404,
+       CTRY_KOREA_NORTH = 408,
+       CTRY_KOREA_ROC = 410,
+       CTRY_KOREA_ROC2 = 411,
+       CTRY_KOREA_ROC3 = 412,
+       CTRY_KUWAIT = 414,
+       CTRY_LATVIA = 428,
+       CTRY_LEBANON = 422,
+       CTRY_LIBYA = 434,
+       CTRY_LIECHTENSTEIN = 438,
+       CTRY_LITHUANIA = 440,
+       CTRY_LUXEMBOURG = 442,
+       CTRY_MACAU = 446,
+       CTRY_MACEDONIA = 807,
+       CTRY_MALAYSIA = 458,
+       CTRY_MALTA = 470,
+       CTRY_MEXICO = 484,
+       CTRY_MONACO = 492,
+       CTRY_MOROCCO = 504,
+       CTRY_NEPAL = 524,
+       CTRY_NETHERLANDS = 528,
+       CTRY_NETHERLANDS_ANTILLES = 530,
+       CTRY_NEW_ZEALAND = 554,
+       CTRY_NICARAGUA = 558,
+       CTRY_NORWAY = 578,
+       CTRY_OMAN = 512,
+       CTRY_PAKISTAN = 586,
+       CTRY_PANAMA = 591,
+       CTRY_PAPUA_NEW_GUINEA = 598,
+       CTRY_PARAGUAY = 600,
+       CTRY_PERU = 604,
+       CTRY_PHILIPPINES = 608,
+       CTRY_POLAND = 616,
+       CTRY_PORTUGAL = 620,
+       CTRY_PUERTO_RICO = 630,
+       CTRY_QATAR = 634,
+       CTRY_ROMANIA = 642,
+       CTRY_RUSSIA = 643,
+       CTRY_SAUDI_ARABIA = 682,
+       CTRY_SERBIA_MONTENEGRO = 891,
+       CTRY_SINGAPORE = 702,
+       CTRY_SLOVAKIA = 703,
+       CTRY_SLOVENIA = 705,
+       CTRY_SOUTH_AFRICA = 710,
+       CTRY_SPAIN = 724,
+       CTRY_SRI_LANKA = 144,
+       CTRY_SWEDEN = 752,
+       CTRY_SWITZERLAND = 756,
+       CTRY_SYRIA = 760,
+       CTRY_TAIWAN = 158,
+       CTRY_THAILAND = 764,
+       CTRY_TRINIDAD_Y_TOBAGO = 780,
+       CTRY_TUNISIA = 788,
+       CTRY_TURKEY = 792,
+       CTRY_UAE = 784,
+       CTRY_UKRAINE = 804,
+       CTRY_UNITED_KINGDOM = 826,
+       CTRY_UNITED_STATES = 840,
+       CTRY_UNITED_STATES_FCC49 = 842,
+       CTRY_URUGUAY = 858,
+       CTRY_UZBEKISTAN = 860,
+       CTRY_VENEZUELA = 862,
+       CTRY_VIET_NAM = 704,
+       CTRY_YEMEN = 887,
+       CTRY_ZIMBABWE = 716,
+       CTRY_JAPAN1 = 393,
+       CTRY_JAPAN2 = 394,
+       CTRY_JAPAN3 = 395,
+       CTRY_JAPAN4 = 396,
+       CTRY_JAPAN5 = 397,
+       CTRY_JAPAN6 = 4006,
+       CTRY_JAPAN7 = 4007,
+       CTRY_JAPAN8 = 4008,
+       CTRY_JAPAN9 = 4009,
+       CTRY_JAPAN10 = 4010,
+       CTRY_JAPAN11 = 4011,
+       CTRY_JAPAN12 = 4012,
+       CTRY_JAPAN13 = 4013,
+       CTRY_JAPAN14 = 4014,
+       CTRY_JAPAN15 = 4015,
+       CTRY_JAPAN16 = 4016,
+       CTRY_JAPAN17 = 4017,
+       CTRY_JAPAN18 = 4018,
+       CTRY_JAPAN19 = 4019,
+       CTRY_JAPAN20 = 4020,
+       CTRY_JAPAN21 = 4021,
+       CTRY_JAPAN22 = 4022,
+       CTRY_JAPAN23 = 4023,
+       CTRY_JAPAN24 = 4024,
+       CTRY_JAPAN25 = 4025,
+       CTRY_JAPAN26 = 4026,
+       CTRY_JAPAN27 = 4027,
+       CTRY_JAPAN28 = 4028,
+       CTRY_JAPAN29 = 4029,
+       CTRY_JAPAN30 = 4030,
+       CTRY_JAPAN31 = 4031,
+       CTRY_JAPAN32 = 4032,
+       CTRY_JAPAN33 = 4033,
+       CTRY_JAPAN34 = 4034,
+       CTRY_JAPAN35 = 4035,
+       CTRY_JAPAN36 = 4036,
+       CTRY_JAPAN37 = 4037,
+       CTRY_JAPAN38 = 4038,
+       CTRY_JAPAN39 = 4039,
+       CTRY_JAPAN40 = 4040,
+       CTRY_JAPAN41 = 4041,
+       CTRY_JAPAN42 = 4042,
+       CTRY_JAPAN43 = 4043,
+       CTRY_JAPAN44 = 4044,
+       CTRY_JAPAN45 = 4045,
+       CTRY_JAPAN46 = 4046,
+       CTRY_JAPAN47 = 4047,
+       CTRY_JAPAN48 = 4048,
+       CTRY_JAPAN49 = 4049,
+       CTRY_JAPAN50 = 4050,
+       CTRY_JAPAN51 = 4051,
+       CTRY_JAPAN52 = 4052,
+       CTRY_JAPAN53 = 4053,
+       CTRY_JAPAN54 = 4054,
+       CTRY_JAPAN55 = 4055,
+       CTRY_JAPAN56 = 4056,
+       CTRY_JAPAN57 = 4057,
+       CTRY_JAPAN58 = 4058,
+       CTRY_JAPAN59 = 4059,
+       CTRY_AUSTRALIA2 = 5000,
+       CTRY_CANADA2 = 5001,
+       CTRY_BELGIUM2 = 5002
+};
+
+bool ath_is_world_regd(struct ath_regulatory *reg);
+int ath_regd_init(struct ath_regulatory *reg, struct wiphy *wiphy,
+                 int (*reg_notifier)(struct wiphy *wiphy,
+                 struct regulatory_request *request));
+u32 ath_regd_get_band_ctl(struct ath_regulatory *reg,
+                         enum ieee80211_band band);
+int ath_reg_notifier_apply(struct wiphy *wiphy,
+                          struct regulatory_request *request,
+                          struct ath_regulatory *reg);
+
+#endif
diff --git a/drivers/net/wireless/ath/regd_common.h b/drivers/net/wireless/ath/regd_common.h
new file mode 100644 (file)
index 0000000..4d0e298
--- /dev/null
@@ -0,0 +1,473 @@
+/*
+ * Copyright (c) 2008-2009 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 REGD_COMMON_H
+#define REGD_COMMON_H
+
+enum EnumRd {
+       NO_ENUMRD = 0x00,
+       NULL1_WORLD = 0x03,
+       NULL1_ETSIB = 0x07,
+       NULL1_ETSIC = 0x08,
+       FCC1_FCCA = 0x10,
+       FCC1_WORLD = 0x11,
+       FCC4_FCCA = 0x12,
+       FCC5_FCCA = 0x13,
+       FCC6_FCCA = 0x14,
+
+       FCC2_FCCA = 0x20,
+       FCC2_WORLD = 0x21,
+       FCC2_ETSIC = 0x22,
+       FCC6_WORLD = 0x23,
+       FRANCE_RES = 0x31,
+       FCC3_FCCA = 0x3A,
+       FCC3_WORLD = 0x3B,
+
+       ETSI1_WORLD = 0x37,
+       ETSI3_ETSIA = 0x32,
+       ETSI2_WORLD = 0x35,
+       ETSI3_WORLD = 0x36,
+       ETSI4_WORLD = 0x30,
+       ETSI4_ETSIC = 0x38,
+       ETSI5_WORLD = 0x39,
+       ETSI6_WORLD = 0x34,
+       ETSI_RESERVED = 0x33,
+
+       MKK1_MKKA = 0x40,
+       MKK1_MKKB = 0x41,
+       APL4_WORLD = 0x42,
+       MKK2_MKKA = 0x43,
+       APL_RESERVED = 0x44,
+       APL2_WORLD = 0x45,
+       APL2_APLC = 0x46,
+       APL3_WORLD = 0x47,
+       MKK1_FCCA = 0x48,
+       APL2_APLD = 0x49,
+       MKK1_MKKA1 = 0x4A,
+       MKK1_MKKA2 = 0x4B,
+       MKK1_MKKC = 0x4C,
+
+       APL3_FCCA = 0x50,
+       APL1_WORLD = 0x52,
+       APL1_FCCA = 0x53,
+       APL1_APLA = 0x54,
+       APL1_ETSIC = 0x55,
+       APL2_ETSIC = 0x56,
+       APL5_WORLD = 0x58,
+       APL6_WORLD = 0x5B,
+       APL7_FCCA = 0x5C,
+       APL8_WORLD = 0x5D,
+       APL9_WORLD = 0x5E,
+
+       WOR0_WORLD = 0x60,
+       WOR1_WORLD = 0x61,
+       WOR2_WORLD = 0x62,
+       WOR3_WORLD = 0x63,
+       WOR4_WORLD = 0x64,
+       WOR5_ETSIC = 0x65,
+
+       WOR01_WORLD = 0x66,
+       WOR02_WORLD = 0x67,
+       EU1_WORLD = 0x68,
+
+       WOR9_WORLD = 0x69,
+       WORA_WORLD = 0x6A,
+       WORB_WORLD = 0x6B,
+
+       MKK3_MKKB = 0x80,
+       MKK3_MKKA2 = 0x81,
+       MKK3_MKKC = 0x82,
+
+       MKK4_MKKB = 0x83,
+       MKK4_MKKA2 = 0x84,
+       MKK4_MKKC = 0x85,
+
+       MKK5_MKKB = 0x86,
+       MKK5_MKKA2 = 0x87,
+       MKK5_MKKC = 0x88,
+
+       MKK6_MKKB = 0x89,
+       MKK6_MKKA2 = 0x8A,
+       MKK6_MKKC = 0x8B,
+
+       MKK7_MKKB = 0x8C,
+       MKK7_MKKA2 = 0x8D,
+       MKK7_MKKC = 0x8E,
+
+       MKK8_MKKB = 0x8F,
+       MKK8_MKKA2 = 0x90,
+       MKK8_MKKC = 0x91,
+
+       MKK14_MKKA1 = 0x92,
+       MKK15_MKKA1 = 0x93,
+
+       MKK10_FCCA = 0xD0,
+       MKK10_MKKA1 = 0xD1,
+       MKK10_MKKC = 0xD2,
+       MKK10_MKKA2 = 0xD3,
+
+       MKK11_MKKA = 0xD4,
+       MKK11_FCCA = 0xD5,
+       MKK11_MKKA1 = 0xD6,
+       MKK11_MKKC = 0xD7,
+       MKK11_MKKA2 = 0xD8,
+
+       MKK12_MKKA = 0xD9,
+       MKK12_FCCA = 0xDA,
+       MKK12_MKKA1 = 0xDB,
+       MKK12_MKKC = 0xDC,
+       MKK12_MKKA2 = 0xDD,
+
+       MKK13_MKKB = 0xDE,
+
+       MKK3_MKKA = 0xF0,
+       MKK3_MKKA1 = 0xF1,
+       MKK3_FCCA = 0xF2,
+       MKK4_MKKA = 0xF3,
+       MKK4_MKKA1 = 0xF4,
+       MKK4_FCCA = 0xF5,
+       MKK9_MKKA = 0xF6,
+       MKK10_MKKA = 0xF7,
+       MKK6_MKKA1 = 0xF8,
+       MKK6_FCCA = 0xF9,
+       MKK7_MKKA1 = 0xFA,
+       MKK7_FCCA = 0xFB,
+       MKK9_FCCA = 0xFC,
+       MKK9_MKKA1 = 0xFD,
+       MKK9_MKKC = 0xFE,
+       MKK9_MKKA2 = 0xFF,
+
+       WORLD = 0x0199,
+       DEBUG_REG_DMN = 0x01ff,
+};
+
+enum ctl_group {
+       CTL_FCC = 0x10,
+       CTL_MKK = 0x40,
+       CTL_ETSI = 0x30,
+};
+
+/* Regpair to CTL band mapping */
+static struct reg_dmn_pair_mapping regDomainPairs[] = {
+       /* regpair, 5 GHz CTL, 2 GHz CTL */
+       {NO_ENUMRD, DEBUG_REG_DMN, DEBUG_REG_DMN},
+       {NULL1_WORLD, NO_CTL, CTL_ETSI},
+       {NULL1_ETSIB, NO_CTL, CTL_ETSI},
+       {NULL1_ETSIC, NO_CTL, CTL_ETSI},
+
+       {FCC2_FCCA, CTL_FCC, CTL_FCC},
+       {FCC2_WORLD, CTL_FCC, CTL_ETSI},
+       {FCC2_ETSIC, CTL_FCC, CTL_ETSI},
+       {FCC3_FCCA, CTL_FCC, CTL_FCC},
+       {FCC3_WORLD, CTL_FCC, CTL_ETSI},
+       {FCC4_FCCA, CTL_FCC, CTL_FCC},
+       {FCC5_FCCA, CTL_FCC, CTL_FCC},
+       {FCC6_FCCA, CTL_FCC, CTL_FCC},
+       {FCC6_WORLD, CTL_FCC, CTL_ETSI},
+
+       {ETSI1_WORLD, CTL_ETSI, CTL_ETSI},
+       {ETSI2_WORLD, CTL_ETSI, CTL_ETSI},
+       {ETSI3_WORLD, CTL_ETSI, CTL_ETSI},
+       {ETSI4_WORLD, CTL_ETSI, CTL_ETSI},
+       {ETSI5_WORLD, CTL_ETSI, CTL_ETSI},
+       {ETSI6_WORLD, CTL_ETSI, CTL_ETSI},
+
+       /* XXX: For ETSI3_ETSIA, Was NO_CTL meant for the 2 GHz band ? */
+       {ETSI3_ETSIA, CTL_ETSI, CTL_ETSI},
+       {FRANCE_RES, CTL_ETSI, CTL_ETSI},
+
+       {FCC1_WORLD, CTL_FCC, CTL_ETSI},
+       {FCC1_FCCA, CTL_FCC, CTL_FCC},
+       {APL1_WORLD, CTL_FCC, CTL_ETSI},
+       {APL2_WORLD, CTL_FCC, CTL_ETSI},
+       {APL3_WORLD, CTL_FCC, CTL_ETSI},
+       {APL4_WORLD, CTL_FCC, CTL_ETSI},
+       {APL5_WORLD, CTL_FCC, CTL_ETSI},
+       {APL6_WORLD, CTL_ETSI, CTL_ETSI},
+       {APL8_WORLD, CTL_ETSI, CTL_ETSI},
+       {APL9_WORLD, CTL_ETSI, CTL_ETSI},
+
+       {APL3_FCCA, CTL_FCC, CTL_FCC},
+       {APL1_ETSIC, CTL_FCC, CTL_ETSI},
+       {APL2_ETSIC, CTL_FCC, CTL_ETSI},
+       {APL2_APLD, CTL_FCC, NO_CTL},
+
+       {MKK1_MKKA, CTL_MKK, CTL_MKK},
+       {MKK1_MKKB, CTL_MKK, CTL_MKK},
+       {MKK1_FCCA, CTL_MKK, CTL_FCC},
+       {MKK1_MKKA1, CTL_MKK, CTL_MKK},
+       {MKK1_MKKA2, CTL_MKK, CTL_MKK},
+       {MKK1_MKKC, CTL_MKK, CTL_MKK},
+
+       {MKK2_MKKA, CTL_MKK, CTL_MKK},
+       {MKK3_MKKA, CTL_MKK, CTL_MKK},
+       {MKK3_MKKB, CTL_MKK, CTL_MKK},
+       {MKK3_MKKA1, CTL_MKK, CTL_MKK},
+       {MKK3_MKKA2, CTL_MKK, CTL_MKK},
+       {MKK3_MKKC, CTL_MKK, CTL_MKK},
+       {MKK3_FCCA, CTL_MKK, CTL_FCC},
+
+       {MKK4_MKKA, CTL_MKK, CTL_MKK},
+       {MKK4_MKKB, CTL_MKK, CTL_MKK},
+       {MKK4_MKKA1, CTL_MKK, CTL_MKK},
+       {MKK4_MKKA2, CTL_MKK, CTL_MKK},
+       {MKK4_MKKC, CTL_MKK, CTL_MKK},
+       {MKK4_FCCA, CTL_MKK, CTL_FCC},
+
+       {MKK5_MKKB, CTL_MKK, CTL_MKK},
+       {MKK5_MKKA2, CTL_MKK, CTL_MKK},
+       {MKK5_MKKC, CTL_MKK, CTL_MKK},
+
+       {MKK6_MKKB, CTL_MKK, CTL_MKK},
+       {MKK6_MKKA1, CTL_MKK, CTL_MKK},
+       {MKK6_MKKA2, CTL_MKK, CTL_MKK},
+       {MKK6_MKKC, CTL_MKK, CTL_MKK},
+       {MKK6_FCCA, CTL_MKK, CTL_FCC},
+
+       {MKK7_MKKB, CTL_MKK, CTL_MKK},
+       {MKK7_MKKA1, CTL_MKK, CTL_MKK},
+       {MKK7_MKKA2, CTL_MKK, CTL_MKK},
+       {MKK7_MKKC, CTL_MKK, CTL_MKK},
+       {MKK7_FCCA, CTL_MKK, CTL_FCC},
+
+       {MKK8_MKKB, CTL_MKK, CTL_MKK},
+       {MKK8_MKKA2, CTL_MKK, CTL_MKK},
+       {MKK8_MKKC, CTL_MKK, CTL_MKK},
+
+       {MKK9_MKKA, CTL_MKK, CTL_MKK},
+       {MKK9_FCCA, CTL_MKK, CTL_FCC},
+       {MKK9_MKKA1, CTL_MKK, CTL_MKK},
+       {MKK9_MKKA2, CTL_MKK, CTL_MKK},
+       {MKK9_MKKC, CTL_MKK, CTL_MKK},
+
+       {MKK10_MKKA, CTL_MKK, CTL_MKK},
+       {MKK10_FCCA, CTL_MKK, CTL_FCC},
+       {MKK10_MKKA1, CTL_MKK, CTL_MKK},
+       {MKK10_MKKA2, CTL_MKK, CTL_MKK},
+       {MKK10_MKKC, CTL_MKK, CTL_MKK},
+
+       {MKK11_MKKA, CTL_MKK, CTL_MKK},
+       {MKK11_FCCA, CTL_MKK, CTL_FCC},
+       {MKK11_MKKA1, CTL_MKK, CTL_MKK},
+       {MKK11_MKKA2, CTL_MKK, CTL_MKK},
+       {MKK11_MKKC, CTL_MKK, CTL_MKK},
+
+       {MKK12_MKKA, CTL_MKK, CTL_MKK},
+       {MKK12_FCCA, CTL_MKK, CTL_FCC},
+       {MKK12_MKKA1, CTL_MKK, CTL_MKK},
+       {MKK12_MKKA2, CTL_MKK, CTL_MKK},
+       {MKK12_MKKC, CTL_MKK, CTL_MKK},
+
+       {MKK13_MKKB, CTL_MKK, CTL_MKK},
+       {MKK14_MKKA1, CTL_MKK, CTL_MKK},
+       {MKK15_MKKA1, CTL_MKK, CTL_MKK},
+
+       {WOR0_WORLD, NO_CTL, NO_CTL},
+       {WOR1_WORLD, NO_CTL, NO_CTL},
+       {WOR2_WORLD, NO_CTL, NO_CTL},
+       {WOR3_WORLD, NO_CTL, NO_CTL},
+       {WOR4_WORLD, NO_CTL, NO_CTL},
+       {WOR5_ETSIC, NO_CTL, NO_CTL},
+       {WOR01_WORLD, NO_CTL, NO_CTL},
+       {WOR02_WORLD, NO_CTL, NO_CTL},
+       {EU1_WORLD, NO_CTL, NO_CTL},
+       {WOR9_WORLD, NO_CTL, NO_CTL},
+       {WORA_WORLD, NO_CTL, NO_CTL},
+       {WORB_WORLD, NO_CTL, NO_CTL},
+};
+
+static struct country_code_to_enum_rd allCountries[] = {
+       {CTRY_DEBUG, NO_ENUMRD, "DB"},
+       {CTRY_DEFAULT, FCC1_FCCA, "CO"},
+       {CTRY_ALBANIA, NULL1_WORLD, "AL"},
+       {CTRY_ALGERIA, NULL1_WORLD, "DZ"},
+       {CTRY_ARGENTINA, APL3_WORLD, "AR"},
+       {CTRY_ARMENIA, ETSI4_WORLD, "AM"},
+       {CTRY_AUSTRALIA, FCC2_WORLD, "AU"},
+       {CTRY_AUSTRALIA2, FCC6_WORLD, "AU"},
+       {CTRY_AUSTRIA, ETSI1_WORLD, "AT"},
+       {CTRY_AZERBAIJAN, ETSI4_WORLD, "AZ"},
+       {CTRY_BAHRAIN, APL6_WORLD, "BH"},
+       {CTRY_BELARUS, ETSI1_WORLD, "BY"},
+       {CTRY_BELGIUM, ETSI1_WORLD, "BE"},
+       {CTRY_BELGIUM2, ETSI4_WORLD, "BL"},
+       {CTRY_BELIZE, APL1_ETSIC, "BZ"},
+       {CTRY_BOLIVIA, APL1_ETSIC, "BO"},
+       {CTRY_BOSNIA_HERZ, ETSI1_WORLD, "BA"},
+       {CTRY_BRAZIL, FCC3_WORLD, "BR"},
+       {CTRY_BRUNEI_DARUSSALAM, APL1_WORLD, "BN"},
+       {CTRY_BULGARIA, ETSI6_WORLD, "BG"},
+       {CTRY_CANADA, FCC2_FCCA, "CA"},
+       {CTRY_CANADA2, FCC6_FCCA, "CA"},
+       {CTRY_CHILE, APL6_WORLD, "CL"},
+       {CTRY_CHINA, APL1_WORLD, "CN"},
+       {CTRY_COLOMBIA, FCC1_FCCA, "CO"},
+       {CTRY_COSTA_RICA, FCC1_WORLD, "CR"},
+       {CTRY_CROATIA, ETSI3_WORLD, "HR"},
+       {CTRY_CYPRUS, ETSI1_WORLD, "CY"},
+       {CTRY_CZECH, ETSI3_WORLD, "CZ"},
+       {CTRY_DENMARK, ETSI1_WORLD, "DK"},
+       {CTRY_DOMINICAN_REPUBLIC, FCC1_FCCA, "DO"},
+       {CTRY_ECUADOR, FCC1_WORLD, "EC"},
+       {CTRY_EGYPT, ETSI3_WORLD, "EG"},
+       {CTRY_EL_SALVADOR, FCC1_WORLD, "SV"},
+       {CTRY_ESTONIA, ETSI1_WORLD, "EE"},
+       {CTRY_FINLAND, ETSI1_WORLD, "FI"},
+       {CTRY_FRANCE, ETSI1_WORLD, "FR"},
+       {CTRY_GEORGIA, ETSI4_WORLD, "GE"},
+       {CTRY_GERMANY, ETSI1_WORLD, "DE"},
+       {CTRY_GREECE, ETSI1_WORLD, "GR"},
+       {CTRY_GUATEMALA, FCC1_FCCA, "GT"},
+       {CTRY_HONDURAS, NULL1_WORLD, "HN"},
+       {CTRY_HONG_KONG, FCC2_WORLD, "HK"},
+       {CTRY_HUNGARY, ETSI1_WORLD, "HU"},
+       {CTRY_ICELAND, ETSI1_WORLD, "IS"},
+       {CTRY_INDIA, APL6_WORLD, "IN"},
+       {CTRY_INDONESIA, APL1_WORLD, "ID"},
+       {CTRY_IRAN, APL1_WORLD, "IR"},
+       {CTRY_IRELAND, ETSI1_WORLD, "IE"},
+       {CTRY_ISRAEL, NULL1_WORLD, "IL"},
+       {CTRY_ITALY, ETSI1_WORLD, "IT"},
+       {CTRY_JAMAICA, ETSI1_WORLD, "JM"},
+
+       {CTRY_JAPAN, MKK1_MKKA, "JP"},
+       {CTRY_JAPAN1, MKK1_MKKB, "JP"},
+       {CTRY_JAPAN2, MKK1_FCCA, "JP"},
+       {CTRY_JAPAN3, MKK2_MKKA, "JP"},
+       {CTRY_JAPAN4, MKK1_MKKA1, "JP"},
+       {CTRY_JAPAN5, MKK1_MKKA2, "JP"},
+       {CTRY_JAPAN6, MKK1_MKKC, "JP"},
+       {CTRY_JAPAN7, MKK3_MKKB, "JP"},
+       {CTRY_JAPAN8, MKK3_MKKA2, "JP"},
+       {CTRY_JAPAN9, MKK3_MKKC, "JP"},
+       {CTRY_JAPAN10, MKK4_MKKB, "JP"},
+       {CTRY_JAPAN11, MKK4_MKKA2, "JP"},
+       {CTRY_JAPAN12, MKK4_MKKC, "JP"},
+       {CTRY_JAPAN13, MKK5_MKKB, "JP"},
+       {CTRY_JAPAN14, MKK5_MKKA2, "JP"},
+       {CTRY_JAPAN15, MKK5_MKKC, "JP"},
+       {CTRY_JAPAN16, MKK6_MKKB, "JP"},
+       {CTRY_JAPAN17, MKK6_MKKA2, "JP"},
+       {CTRY_JAPAN18, MKK6_MKKC, "JP"},
+       {CTRY_JAPAN19, MKK7_MKKB, "JP"},
+       {CTRY_JAPAN20, MKK7_MKKA2, "JP"},
+       {CTRY_JAPAN21, MKK7_MKKC, "JP"},
+       {CTRY_JAPAN22, MKK8_MKKB, "JP"},
+       {CTRY_JAPAN23, MKK8_MKKA2, "JP"},
+       {CTRY_JAPAN24, MKK8_MKKC, "JP"},
+       {CTRY_JAPAN25, MKK3_MKKA, "JP"},
+       {CTRY_JAPAN26, MKK3_MKKA1, "JP"},
+       {CTRY_JAPAN27, MKK3_FCCA, "JP"},
+       {CTRY_JAPAN28, MKK4_MKKA1, "JP"},
+       {CTRY_JAPAN29, MKK4_FCCA, "JP"},
+       {CTRY_JAPAN30, MKK6_MKKA1, "JP"},
+       {CTRY_JAPAN31, MKK6_FCCA, "JP"},
+       {CTRY_JAPAN32, MKK7_MKKA1, "JP"},
+       {CTRY_JAPAN33, MKK7_FCCA, "JP"},
+       {CTRY_JAPAN34, MKK9_MKKA, "JP"},
+       {CTRY_JAPAN35, MKK10_MKKA, "JP"},
+       {CTRY_JAPAN36, MKK4_MKKA, "JP"},
+       {CTRY_JAPAN37, MKK9_FCCA, "JP"},
+       {CTRY_JAPAN38, MKK9_MKKA1, "JP"},
+       {CTRY_JAPAN39, MKK9_MKKC, "JP"},
+       {CTRY_JAPAN40, MKK9_MKKA2, "JP"},
+       {CTRY_JAPAN41, MKK10_FCCA, "JP"},
+       {CTRY_JAPAN42, MKK10_MKKA1, "JP"},
+       {CTRY_JAPAN43, MKK10_MKKC, "JP"},
+       {CTRY_JAPAN44, MKK10_MKKA2, "JP"},
+       {CTRY_JAPAN45, MKK11_MKKA, "JP"},
+       {CTRY_JAPAN46, MKK11_FCCA, "JP"},
+       {CTRY_JAPAN47, MKK11_MKKA1, "JP"},
+       {CTRY_JAPAN48, MKK11_MKKC, "JP"},
+       {CTRY_JAPAN49, MKK11_MKKA2, "JP"},
+       {CTRY_JAPAN50, MKK12_MKKA, "JP"},
+       {CTRY_JAPAN51, MKK12_FCCA, "JP"},
+       {CTRY_JAPAN52, MKK12_MKKA1, "JP"},
+       {CTRY_JAPAN53, MKK12_MKKC, "JP"},
+       {CTRY_JAPAN54, MKK12_MKKA2, "JP"},
+       {CTRY_JAPAN57, MKK13_MKKB, "JP"},
+       {CTRY_JAPAN58, MKK14_MKKA1, "JP"},
+       {CTRY_JAPAN59, MKK15_MKKA1, "JP"},
+
+       {CTRY_JORDAN, ETSI2_WORLD, "JO"},
+       {CTRY_KAZAKHSTAN, NULL1_WORLD, "KZ"},
+       {CTRY_KOREA_NORTH, APL9_WORLD, "KP"},
+       {CTRY_KOREA_ROC, APL9_WORLD, "KR"},
+       {CTRY_KOREA_ROC2, APL2_WORLD, "K2"},
+       {CTRY_KOREA_ROC3, APL9_WORLD, "K3"},
+       {CTRY_KUWAIT, NULL1_WORLD, "KW"},
+       {CTRY_LATVIA, ETSI1_WORLD, "LV"},
+       {CTRY_LEBANON, NULL1_WORLD, "LB"},
+       {CTRY_LIECHTENSTEIN, ETSI1_WORLD, "LI"},
+       {CTRY_LITHUANIA, ETSI1_WORLD, "LT"},
+       {CTRY_LUXEMBOURG, ETSI1_WORLD, "LU"},
+       {CTRY_MACAU, FCC2_WORLD, "MO"},
+       {CTRY_MACEDONIA, NULL1_WORLD, "MK"},
+       {CTRY_MALAYSIA, APL8_WORLD, "MY"},
+       {CTRY_MALTA, ETSI1_WORLD, "MT"},
+       {CTRY_MEXICO, FCC1_FCCA, "MX"},
+       {CTRY_MONACO, ETSI4_WORLD, "MC"},
+       {CTRY_MOROCCO, NULL1_WORLD, "MA"},
+       {CTRY_NEPAL, APL1_WORLD, "NP"},
+       {CTRY_NETHERLANDS, ETSI1_WORLD, "NL"},
+       {CTRY_NETHERLANDS_ANTILLES, ETSI1_WORLD, "AN"},
+       {CTRY_NEW_ZEALAND, FCC2_ETSIC, "NZ"},
+       {CTRY_NORWAY, ETSI1_WORLD, "NO"},
+       {CTRY_OMAN, APL6_WORLD, "OM"},
+       {CTRY_PAKISTAN, NULL1_WORLD, "PK"},
+       {CTRY_PANAMA, FCC1_FCCA, "PA"},
+       {CTRY_PAPUA_NEW_GUINEA, FCC1_WORLD, "PG"},
+       {CTRY_PERU, APL1_WORLD, "PE"},
+       {CTRY_PHILIPPINES, APL1_WORLD, "PH"},
+       {CTRY_POLAND, ETSI1_WORLD, "PL"},
+       {CTRY_PORTUGAL, ETSI1_WORLD, "PT"},
+       {CTRY_PUERTO_RICO, FCC1_FCCA, "PR"},
+       {CTRY_QATAR, NULL1_WORLD, "QA"},
+       {CTRY_ROMANIA, NULL1_WORLD, "RO"},
+       {CTRY_RUSSIA, NULL1_WORLD, "RU"},
+       {CTRY_SAUDI_ARABIA, NULL1_WORLD, "SA"},
+       {CTRY_SERBIA_MONTENEGRO, ETSI1_WORLD, "CS"},
+       {CTRY_SINGAPORE, APL6_WORLD, "SG"},
+       {CTRY_SLOVAKIA, ETSI1_WORLD, "SK"},
+       {CTRY_SLOVENIA, ETSI1_WORLD, "SI"},
+       {CTRY_SOUTH_AFRICA, FCC3_WORLD, "ZA"},
+       {CTRY_SPAIN, ETSI1_WORLD, "ES"},
+       {CTRY_SRI_LANKA, FCC3_WORLD, "LK"},
+       {CTRY_SWEDEN, ETSI1_WORLD, "SE"},
+       {CTRY_SWITZERLAND, ETSI1_WORLD, "CH"},
+       {CTRY_SYRIA, NULL1_WORLD, "SY"},
+       {CTRY_TAIWAN, APL3_FCCA, "TW"},
+       {CTRY_THAILAND, NULL1_WORLD, "TH"},
+       {CTRY_TRINIDAD_Y_TOBAGO, ETSI4_WORLD, "TT"},
+       {CTRY_TUNISIA, ETSI3_WORLD, "TN"},
+       {CTRY_TURKEY, ETSI3_WORLD, "TR"},
+       {CTRY_UKRAINE, NULL1_WORLD, "UA"},
+       {CTRY_UAE, NULL1_WORLD, "AE"},
+       {CTRY_UNITED_KINGDOM, ETSI1_WORLD, "GB"},
+       {CTRY_UNITED_STATES, FCC3_FCCA, "US"},
+       /* This "PS" is for US public safety actually... to support this we
+        * would need to assign new special alpha2 to CRDA db as with the world
+        * regdomain and use another alpha2 */
+       {CTRY_UNITED_STATES_FCC49, FCC4_FCCA, "PS"},
+       {CTRY_URUGUAY, APL2_WORLD, "UY"},
+       {CTRY_UZBEKISTAN, FCC3_FCCA, "UZ"},
+       {CTRY_VENEZUELA, APL2_ETSIC, "VE"},
+       {CTRY_VIET_NAM, NULL1_WORLD, "VN"},
+       {CTRY_YEMEN, NULL1_WORLD, "YE"},
+       {CTRY_ZIMBABWE, NULL1_WORLD, "ZW"},
+};
+
+#endif
diff --git a/drivers/net/wireless/ath5k/Kconfig b/drivers/net/wireless/ath5k/Kconfig
deleted file mode 100644 (file)
index 75383a5..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-config ATH5K
-       tristate "Atheros 5xxx wireless cards support"
-       depends on PCI && MAC80211 && WLAN_80211 && EXPERIMENTAL
-       select MAC80211_LEDS
-       select LEDS_CLASS
-       select NEW_LEDS
-       ---help---
-         This module adds support for wireless adapters based on
-         Atheros 5xxx chipset.
-
-         Currently the following chip versions are supported:
-
-         MAC: AR5211 AR5212
-         PHY: RF5111/2111 RF5112/2112 RF5413/2413
-
-         This driver uses the kernel's mac80211 subsystem.
-
-         If you choose to build a module, it'll be called ath5k. Say M if
-         unsure.
-
-config ATH5K_DEBUG
-       bool "Atheros 5xxx debugging"
-       depends on ATH5K
-       ---help---
-         Atheros 5xxx debugging messages.
-
-         Say Y, if and you will get debug options for ath5k.
-         To use this, you need to mount debugfs:
-
-         mkdir /debug/
-         mount -t debugfs debug /debug/
-
-         You will get access to files under:
-         /debug/ath5k/phy0/
-
-         To enable debug, pass the debug level to the debug module
-         parameter. For example:
-
-         modprobe ath5k debug=0x00000400
-
diff --git a/drivers/net/wireless/ath5k/Makefile b/drivers/net/wireless/ath5k/Makefile
deleted file mode 100644 (file)
index 84a74c5..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-ath5k-y                                += caps.o
-ath5k-y                                += initvals.o
-ath5k-y                                += eeprom.o
-ath5k-y                                += gpio.o
-ath5k-y                                += desc.o
-ath5k-y                                += dma.o
-ath5k-y                                += qcu.o
-ath5k-y                                += pcu.o
-ath5k-y                                += phy.o
-ath5k-y                                += reset.o
-ath5k-y                                += attach.o
-ath5k-y                                += base.o
-ath5k-y                                += led.o
-ath5k-$(CONFIG_ATH5K_DEBUG)    += debug.o
-obj-$(CONFIG_ATH5K)            += ath5k.o
diff --git a/drivers/net/wireless/ath5k/ath5k.h b/drivers/net/wireless/ath5k/ath5k.h
deleted file mode 100644 (file)
index 0b616e7..0000000
+++ /dev/null
@@ -1,1353 +0,0 @@
-/*
- * Copyright (c) 2004-2007 Reyk Floeter <reyk@openbsd.org>
- * Copyright (c) 2006-2007 Nick Kossifidis <mickflemm@gmail.com>
- *
- * Permission to use, copy, modify, and 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 _ATH5K_H
-#define _ATH5K_H
-
-/* TODO: Clean up channel debuging -doesn't work anyway- and start
- * working on reg. control code using all available eeprom information
- * -rev. engineering needed- */
-#define CHAN_DEBUG     0
-
-#include <linux/io.h>
-#include <linux/types.h>
-#include <net/mac80211.h>
-
-/* RX/TX descriptor hw structs
- * TODO: Driver part should only see sw structs */
-#include "desc.h"
-
-/* EEPROM structs/offsets
- * TODO: Make a more generic struct (eg. add more stuff to ath5k_capabilities)
- * and clean up common bits, then introduce set/get functions in eeprom.c */
-#include "eeprom.h"
-
-/* PCI IDs */
-#define PCI_DEVICE_ID_ATHEROS_AR5210           0x0007 /* AR5210 */
-#define PCI_DEVICE_ID_ATHEROS_AR5311           0x0011 /* AR5311 */
-#define PCI_DEVICE_ID_ATHEROS_AR5211           0x0012 /* AR5211 */
-#define PCI_DEVICE_ID_ATHEROS_AR5212           0x0013 /* AR5212 */
-#define PCI_DEVICE_ID_3COM_3CRDAG675           0x0013 /* 3CRDAG675 (Atheros AR5212) */
-#define PCI_DEVICE_ID_3COM_2_3CRPAG175                 0x0013 /* 3CRPAG175 (Atheros AR5212) */
-#define PCI_DEVICE_ID_ATHEROS_AR5210_AP        0x0207 /* AR5210 (Early) */
-#define PCI_DEVICE_ID_ATHEROS_AR5212_IBM       0x1014 /* AR5212 (IBM MiniPCI) */
-#define PCI_DEVICE_ID_ATHEROS_AR5210_DEFAULT   0x1107 /* AR5210 (no eeprom) */
-#define PCI_DEVICE_ID_ATHEROS_AR5212_DEFAULT   0x1113 /* AR5212 (no eeprom) */
-#define PCI_DEVICE_ID_ATHEROS_AR5211_DEFAULT   0x1112 /* AR5211 (no eeprom) */
-#define PCI_DEVICE_ID_ATHEROS_AR5212_FPGA      0xf013 /* AR5212 (emulation board) */
-#define PCI_DEVICE_ID_ATHEROS_AR5211_LEGACY    0xff12 /* AR5211 (emulation board) */
-#define PCI_DEVICE_ID_ATHEROS_AR5211_FPGA11B   0xf11b /* AR5211 (emulation board) */
-#define PCI_DEVICE_ID_ATHEROS_AR5312_REV2      0x0052 /* AR5312 WMAC (AP31) */
-#define PCI_DEVICE_ID_ATHEROS_AR5312_REV7      0x0057 /* AR5312 WMAC (AP30-040) */
-#define PCI_DEVICE_ID_ATHEROS_AR5312_REV8      0x0058 /* AR5312 WMAC (AP43-030) */
-#define PCI_DEVICE_ID_ATHEROS_AR5212_0014      0x0014 /* AR5212 compatible */
-#define PCI_DEVICE_ID_ATHEROS_AR5212_0015      0x0015 /* AR5212 compatible */
-#define PCI_DEVICE_ID_ATHEROS_AR5212_0016      0x0016 /* AR5212 compatible */
-#define PCI_DEVICE_ID_ATHEROS_AR5212_0017      0x0017 /* AR5212 compatible */
-#define PCI_DEVICE_ID_ATHEROS_AR5212_0018      0x0018 /* AR5212 compatible */
-#define PCI_DEVICE_ID_ATHEROS_AR5212_0019      0x0019 /* AR5212 compatible */
-#define PCI_DEVICE_ID_ATHEROS_AR2413           0x001a /* AR2413 (Griffin-lite) */
-#define PCI_DEVICE_ID_ATHEROS_AR5413           0x001b /* AR5413 (Eagle) */
-#define PCI_DEVICE_ID_ATHEROS_AR5424           0x001c /* AR5424 (Condor PCI-E) */
-#define PCI_DEVICE_ID_ATHEROS_AR5416           0x0023 /* AR5416 */
-#define PCI_DEVICE_ID_ATHEROS_AR5418           0x0024 /* AR5418 */
-
-/****************************\
-  GENERIC DRIVER DEFINITIONS
-\****************************/
-
-#define ATH5K_PRINTF(fmt, ...)   printk("%s: " fmt, __func__, ##__VA_ARGS__)
-
-#define ATH5K_PRINTK(_sc, _level, _fmt, ...) \
-       printk(_level "ath5k %s: " _fmt, \
-               ((_sc) && (_sc)->hw) ? wiphy_name((_sc)->hw->wiphy) : "", \
-               ##__VA_ARGS__)
-
-#define ATH5K_PRINTK_LIMIT(_sc, _level, _fmt, ...) do { \
-       if (net_ratelimit()) \
-               ATH5K_PRINTK(_sc, _level, _fmt, ##__VA_ARGS__); \
-       } while (0)
-
-#define ATH5K_INFO(_sc, _fmt, ...) \
-       ATH5K_PRINTK(_sc, KERN_INFO, _fmt, ##__VA_ARGS__)
-
-#define ATH5K_WARN(_sc, _fmt, ...) \
-       ATH5K_PRINTK_LIMIT(_sc, KERN_WARNING, _fmt, ##__VA_ARGS__)
-
-#define ATH5K_ERR(_sc, _fmt, ...) \
-       ATH5K_PRINTK_LIMIT(_sc, KERN_ERR, _fmt, ##__VA_ARGS__)
-
-/*
- * AR5K REGISTER ACCESS
- */
-
-/* Some macros to read/write fields */
-
-/* First shift, then mask */
-#define AR5K_REG_SM(_val, _flags)                                      \
-       (((_val) << _flags##_S) & (_flags))
-
-/* First mask, then shift */
-#define AR5K_REG_MS(_val, _flags)                                      \
-       (((_val) & (_flags)) >> _flags##_S)
-
-/* Some registers can hold multiple values of interest. For this
- * reason when we want to write to these registers we must first
- * retrieve the values which we do not want to clear (lets call this
- * old_data) and then set the register with this and our new_value:
- * ( old_data | new_value) */
-#define AR5K_REG_WRITE_BITS(ah, _reg, _flags, _val)                    \
-       ath5k_hw_reg_write(ah, (ath5k_hw_reg_read(ah, _reg) & ~(_flags)) | \
-           (((_val) << _flags##_S) & (_flags)), _reg)
-
-#define AR5K_REG_MASKED_BITS(ah, _reg, _flags, _mask)                  \
-       ath5k_hw_reg_write(ah, (ath5k_hw_reg_read(ah, _reg) &           \
-                       (_mask)) | (_flags), _reg)
-
-#define AR5K_REG_ENABLE_BITS(ah, _reg, _flags)                         \
-       ath5k_hw_reg_write(ah, ath5k_hw_reg_read(ah, _reg) | (_flags), _reg)
-
-#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_REG_WRITE_Q(ah, _reg, _queue)                             \
-       ath5k_hw_reg_write(ah, (1 << _queue), _reg)
-
-#define AR5K_Q_ENABLE_BITS(_reg, _queue) do {                          \
-       _reg |= 1 << _queue;                                            \
-} while (0)
-
-#define AR5K_Q_DISABLE_BITS(_reg, _queue) do {                         \
-       _reg &= ~(1 << _queue);                                         \
-} while (0)
-
-/* Used while writing initvals */
-#define AR5K_REG_WAIT(_i) do {                                         \
-       if (_i % 64)                                                    \
-               udelay(1);                                              \
-} while (0)
-
-/* Register dumps are done per operation mode */
-#define AR5K_INI_RFGAIN_5GHZ           0
-#define AR5K_INI_RFGAIN_2GHZ           1
-
-/* TODO: Clean this up */
-#define AR5K_INI_VAL_11A               0
-#define AR5K_INI_VAL_11A_TURBO         1
-#define AR5K_INI_VAL_11B               2
-#define AR5K_INI_VAL_11G               3
-#define AR5K_INI_VAL_11G_TURBO         4
-#define AR5K_INI_VAL_XR                        0
-#define AR5K_INI_VAL_MAX               5
-
-/* Used for BSSID etc manipulation */
-#define AR5K_LOW_ID(_a)(                               \
-(_a)[0] | (_a)[1] << 8 | (_a)[2] << 16 | (_a)[3] << 24 \
-)
-
-#define AR5K_HIGH_ID(_a)       ((_a)[4] | (_a)[5] << 8)
-
-/*
- * Some tuneable values (these should be changeable by the user)
- * TODO: Make use of them and add more options OR use debug/configfs
- */
-#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_LEN / 64) + 1)
-#define AR5K_TUNE_REGISTER_TIMEOUT             20000
-/* Register for RSSI threshold has a mask of 0xff, so 255 seems to
- * be the max value. */
-#define AR5K_TUNE_RSSI_THRES                   129
-/* This must be set when setting the RSSI threshold otherwise it can
- * prevent a reset. If AR5K_RSSI_THR is read after writing to it
- * the BMISS_THRES will be seen as 0, seems harware doesn't keep
- * track of it. Max value depends on harware. For AR5210 this is just 7.
- * For AR5211+ this seems to be up to 255. */
-#define AR5K_TUNE_BMISS_THRES                  7
-#define AR5K_TUNE_REGISTER_DWELL_TIME          20000
-#define AR5K_TUNE_BEACON_INTERVAL              100
-#define AR5K_TUNE_AIFS                         2
-#define AR5K_TUNE_AIFS_11B                     2
-#define AR5K_TUNE_AIFS_XR                      0
-#define AR5K_TUNE_CWMIN                                15
-#define AR5K_TUNE_CWMIN_11B                    31
-#define AR5K_TUNE_CWMIN_XR                     3
-#define AR5K_TUNE_CWMAX                                1023
-#define AR5K_TUNE_CWMAX_11B                    1023
-#define AR5K_TUNE_CWMAX_XR                     7
-#define AR5K_TUNE_NOISE_FLOOR                  -72
-#define AR5K_TUNE_MAX_TXPOWER                  63
-#define AR5K_TUNE_DEFAULT_TXPOWER              25
-#define AR5K_TUNE_TPC_TXPOWER                  false
-#define AR5K_TUNE_ANT_DIVERSITY                        true
-#define AR5K_TUNE_HWTXTRIES                    4
-
-#define AR5K_INIT_CARR_SENSE_EN                        1
-
-/*Swap RX/TX Descriptor for big endian archs*/
-#if defined(__BIG_ENDIAN)
-#define AR5K_INIT_CFG  (               \
-       AR5K_CFG_SWTD | AR5K_CFG_SWRD   \
-)
-#else
-#define AR5K_INIT_CFG  0x00000000
-#endif
-
-/* Initial values */
-#define        AR5K_INIT_CYCRSSI_THR1                  2
-#define AR5K_INIT_TX_LATENCY                   502
-#define AR5K_INIT_USEC                         39
-#define AR5K_INIT_USEC_TURBO                   79
-#define AR5K_INIT_USEC_32                      31
-#define AR5K_INIT_SLOT_TIME                    396
-#define AR5K_INIT_SLOT_TIME_TURBO              480
-#define AR5K_INIT_ACK_CTS_TIMEOUT              1024
-#define AR5K_INIT_ACK_CTS_TIMEOUT_TURBO                0x08000800
-#define AR5K_INIT_PROG_IFS                     920
-#define AR5K_INIT_PROG_IFS_TURBO               960
-#define AR5K_INIT_EIFS                         3440
-#define AR5K_INIT_EIFS_TURBO                   6880
-#define AR5K_INIT_SIFS                         560
-#define AR5K_INIT_SIFS_TURBO                   480
-#define AR5K_INIT_SH_RETRY                     10
-#define AR5K_INIT_LG_RETRY                     AR5K_INIT_SH_RETRY
-#define AR5K_INIT_SSH_RETRY                    32
-#define AR5K_INIT_SLG_RETRY                    AR5K_INIT_SSH_RETRY
-#define AR5K_INIT_TX_RETRY                     10
-
-#define AR5K_INIT_TRANSMIT_LATENCY             (                       \
-       (AR5K_INIT_TX_LATENCY << 14) | (AR5K_INIT_USEC_32 << 7) |       \
-       (AR5K_INIT_USEC)                                                \
-)
-#define AR5K_INIT_TRANSMIT_LATENCY_TURBO       (                       \
-       (AR5K_INIT_TX_LATENCY << 14) | (AR5K_INIT_USEC_32 << 7) |       \
-       (AR5K_INIT_USEC_TURBO)                                          \
-)
-#define AR5K_INIT_PROTO_TIME_CNTRL             (                       \
-       (AR5K_INIT_CARR_SENSE_EN << 26) | (AR5K_INIT_EIFS << 12) |      \
-       (AR5K_INIT_PROG_IFS)                                            \
-)
-#define AR5K_INIT_PROTO_TIME_CNTRL_TURBO       (                       \
-       (AR5K_INIT_CARR_SENSE_EN << 26) | (AR5K_INIT_EIFS_TURBO << 12) | \
-       (AR5K_INIT_PROG_IFS_TURBO)                                      \
-)
-
-/* token to use for aifs, cwmin, cwmax in MadWiFi */
-#define        AR5K_TXQ_USEDEFAULT     ((u32) -1)
-
-/* GENERIC CHIPSET DEFINITIONS */
-
-/* MAC Chips */
-enum ath5k_version {
-       AR5K_AR5210     = 0,
-       AR5K_AR5211     = 1,
-       AR5K_AR5212     = 2,
-};
-
-/* PHY Chips */
-enum ath5k_radio {
-       AR5K_RF5110     = 0,
-       AR5K_RF5111     = 1,
-       AR5K_RF5112     = 2,
-       AR5K_RF2413     = 3,
-       AR5K_RF5413     = 4,
-       AR5K_RF2316     = 5,
-       AR5K_RF2317     = 6,
-       AR5K_RF2425     = 7,
-};
-
-/*
- * 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 */
-#define AR5K_SREV_AR5311       0x10 /* Maui 1 */
-#define AR5K_SREV_AR5311A      0x20 /* Maui 2 */
-#define AR5K_SREV_AR5311B      0x30 /* Spirit */
-#define AR5K_SREV_AR5211       0x40 /* Oahu */
-#define AR5K_SREV_AR5212       0x50 /* Venice */
-#define AR5K_SREV_AR5213       0x55 /* ??? */
-#define AR5K_SREV_AR5213A      0x59 /* Hainan */
-#define AR5K_SREV_AR2413       0x78 /* Griffin lite */
-#define AR5K_SREV_AR2414       0x70 /* Griffin */
-#define AR5K_SREV_AR5424       0x90 /* Condor */
-#define AR5K_SREV_AR5413       0xa4 /* Eagle lite */
-#define AR5K_SREV_AR5414       0xa0 /* Eagle */
-#define AR5K_SREV_AR2415       0xb0 /* Talon */
-#define AR5K_SREV_AR5416       0xc0 /* PCI-E */
-#define AR5K_SREV_AR5418       0xca /* PCI-E */
-#define AR5K_SREV_AR2425       0xe0 /* Swan */
-#define AR5K_SREV_AR2417       0xf0 /* Nala */
-
-#define AR5K_SREV_RAD_5110     0x00
-#define AR5K_SREV_RAD_5111     0x10
-#define AR5K_SREV_RAD_5111A    0x15
-#define AR5K_SREV_RAD_2111     0x20
-#define AR5K_SREV_RAD_5112     0x30
-#define AR5K_SREV_RAD_5112A    0x35
-#define        AR5K_SREV_RAD_5112B     0x36
-#define AR5K_SREV_RAD_2112     0x40
-#define AR5K_SREV_RAD_2112A    0x45
-#define        AR5K_SREV_RAD_2112B     0x46
-#define AR5K_SREV_RAD_2413     0x50
-#define AR5K_SREV_RAD_5413     0x60
-#define AR5K_SREV_RAD_2316     0x70 /* Cobra SoC */
-#define AR5K_SREV_RAD_2317     0x80
-#define AR5K_SREV_RAD_5424     0xa0 /* Mostly same as 5413 */
-#define AR5K_SREV_RAD_2425     0xa2
-#define AR5K_SREV_RAD_5133     0xc0
-
-#define AR5K_SREV_PHY_5211     0x30
-#define AR5K_SREV_PHY_5212     0x41
-#define        AR5K_SREV_PHY_5212A     0x42
-#define AR5K_SREV_PHY_5212B    0x43
-#define AR5K_SREV_PHY_2413     0x45
-#define AR5K_SREV_PHY_5413     0x61
-#define AR5K_SREV_PHY_2425     0x70
-
-/* IEEE defs */
-#define IEEE80211_MAX_LEN       2500
-
-/* TODO add support to mac80211 for vendor-specific rates and modes */
-
-/*
- * Some of this information is based on Documentation from:
- *
- * http://madwifi.org/wiki/ChipsetFeatures/SuperAG
- *
- * Modulation for Atheros' eXtended Range - range enhancing extension that is
- * supposed to double the distance an Atheros client device can keep a
- * connection with an Atheros access point. This is achieved by increasing
- * the receiver sensitivity up to, -105dBm, which is about 20dB above what
- * the 802.11 specifications demand. In addition, new (proprietary) data rates
- * are introduced: 3, 2, 1, 0.5 and 0.25 MBit/s.
- *
- * Please note that can you either use XR or TURBO but you cannot use both,
- * they are exclusive.
- *
- */
-#define MODULATION_XR          0x00000200
-/*
- * Modulation for Atheros' Turbo G and Turbo A, its supposed to provide a
- * throughput transmission speed up to 40Mbit/s-60Mbit/s at a 108Mbit/s
- * signaling rate achieved through the bonding of two 54Mbit/s 802.11g
- * channels. To use this feature your Access Point must also suport it.
- * There is also a distinction between "static" and "dynamic" turbo modes:
- *
- * - Static: is the dumb version: devices set to this mode stick to it until
- *     the mode is turned off.
- * - Dynamic: is the intelligent version, the network decides itself if it
- *     is ok to use turbo. As soon as traffic is detected on adjacent channels
- *     (which would get used in turbo mode), or when a non-turbo station joins
- *     the network, turbo mode won't be used until the situation changes again.
- *     Dynamic mode is achieved by Atheros' Adaptive Radio (AR) feature which
- *     monitors the used radio band in order to decide whether turbo mode may
- *     be used or not.
- *
- * This article claims Super G sticks to bonding of channels 5 and 6 for
- * USA:
- *
- * http://www.pcworld.com/article/id,113428-page,1/article.html
- *
- * The channel bonding seems to be driver specific though. In addition to
- * deciding what channels will be used, these "Turbo" modes are accomplished
- * by also enabling the following features:
- *
- * - Bursting: allows multiple frames to be sent at once, rather than pausing
- *     after each frame. Bursting is a standards-compliant feature that can be
- *     used with any Access Point.
- * - Fast frames: increases the amount of information that can be sent per
- *     frame, also resulting in a reduction of transmission overhead. It is a
- *     proprietary feature that needs to be supported by the Access Point.
- * - Compression: data frames are compressed in real time using a Lempel Ziv
- *     algorithm. This is done transparently. Once this feature is enabled,
- *     compression and decompression takes place inside the chipset, without
- *     putting additional load on the host CPU.
- *
- */
-#define MODULATION_TURBO       0x00000080
-
-enum ath5k_driver_mode {
-       AR5K_MODE_11A           =       0,
-       AR5K_MODE_11A_TURBO     =       1,
-       AR5K_MODE_11B           =       2,
-       AR5K_MODE_11G           =       3,
-       AR5K_MODE_11G_TURBO     =       4,
-       AR5K_MODE_XR            =       0,
-       AR5K_MODE_MAX           =       5
-};
-
-
-/****************\
-  TX DEFINITIONS
-\****************/
-
-/*
- * TX Status descriptor
- */
-struct ath5k_tx_status {
-       u16     ts_seqnum;
-       u16     ts_tstamp;
-       u8      ts_status;
-       u8      ts_rate[4];
-       u8      ts_retry[4];
-       u8      ts_final_idx;
-       s8      ts_rssi;
-       u8      ts_shortretry;
-       u8      ts_longretry;
-       u8      ts_virtcol;
-       u8      ts_antenna;
-};
-
-#define AR5K_TXSTAT_ALTRATE    0x80
-#define AR5K_TXERR_XRETRY      0x01
-#define AR5K_TXERR_FILT                0x02
-#define AR5K_TXERR_FIFO                0x04
-
-/**
- * enum ath5k_tx_queue - Queue types used to classify tx queues.
- * @AR5K_TX_QUEUE_INACTIVE: q is unused -- see ath5k_hw_release_tx_queue
- * @AR5K_TX_QUEUE_DATA: A normal data queue
- * @AR5K_TX_QUEUE_XR_DATA: An XR-data queue
- * @AR5K_TX_QUEUE_BEACON: The beacon queue
- * @AR5K_TX_QUEUE_CAB: The after-beacon queue
- * @AR5K_TX_QUEUE_UAPSD: Unscheduled Automatic Power Save Delivery queue
- */
-enum ath5k_tx_queue {
-       AR5K_TX_QUEUE_INACTIVE = 0,
-       AR5K_TX_QUEUE_DATA,
-       AR5K_TX_QUEUE_XR_DATA,
-       AR5K_TX_QUEUE_BEACON,
-       AR5K_TX_QUEUE_CAB,
-       AR5K_TX_QUEUE_UAPSD,
-};
-
-#define        AR5K_NUM_TX_QUEUES              10
-#define        AR5K_NUM_TX_QUEUES_NOQCU        2
-
-/*
- * Queue syb-types to classify normal data queues.
- * These are the 4 Access Categories as defined in
- * WME spec. 0 is the lowest priority and 4 is the
- * highest. Normal data that hasn't been classified
- * goes to the Best Effort AC.
- */
-enum ath5k_tx_queue_subtype {
-       AR5K_WME_AC_BK = 0,     /*Background traffic*/
-       AR5K_WME_AC_BE,         /*Best-effort (normal) traffic)*/
-       AR5K_WME_AC_VI,         /*Video traffic*/
-       AR5K_WME_AC_VO,         /*Voice traffic*/
-};
-
-/*
- * Queue ID numbers as returned by the hw functions, each number
- * represents a hw queue. If hw does not support hw queues
- * (eg 5210) all data goes in one queue. These match
- * d80211 definitions (net80211/MadWiFi don't use them).
- */
-enum ath5k_tx_queue_id {
-       AR5K_TX_QUEUE_ID_NOQCU_DATA     = 0,
-       AR5K_TX_QUEUE_ID_NOQCU_BEACON   = 1,
-       AR5K_TX_QUEUE_ID_DATA_MIN       = 0, /*IEEE80211_TX_QUEUE_DATA0*/
-       AR5K_TX_QUEUE_ID_DATA_MAX       = 4, /*IEEE80211_TX_QUEUE_DATA4*/
-       AR5K_TX_QUEUE_ID_DATA_SVP       = 5, /*IEEE80211_TX_QUEUE_SVP - Spectralink Voice Protocol*/
-       AR5K_TX_QUEUE_ID_CAB            = 6, /*IEEE80211_TX_QUEUE_AFTER_BEACON*/
-       AR5K_TX_QUEUE_ID_BEACON         = 7, /*IEEE80211_TX_QUEUE_BEACON*/
-       AR5K_TX_QUEUE_ID_UAPSD          = 8,
-       AR5K_TX_QUEUE_ID_XR_DATA        = 9,
-};
-
-/*
- * Flags to set hw queue's parameters...
- */
-#define AR5K_TXQ_FLAG_TXOKINT_ENABLE           0x0001  /* Enable TXOK interrupt */
-#define AR5K_TXQ_FLAG_TXERRINT_ENABLE          0x0002  /* Enable TXERR interrupt */
-#define AR5K_TXQ_FLAG_TXEOLINT_ENABLE          0x0004  /* Enable TXEOL interrupt -not used- */
-#define AR5K_TXQ_FLAG_TXDESCINT_ENABLE         0x0008  /* Enable TXDESC interrupt -not used- */
-#define AR5K_TXQ_FLAG_TXURNINT_ENABLE          0x0010  /* Enable TXURN interrupt */
-#define AR5K_TXQ_FLAG_CBRORNINT_ENABLE         0x0020  /* Enable CBRORN interrupt */
-#define AR5K_TXQ_FLAG_CBRURNINT_ENABLE         0x0040  /* Enable CBRURN interrupt */
-#define AR5K_TXQ_FLAG_QTRIGINT_ENABLE          0x0080  /* Enable QTRIG interrupt */
-#define AR5K_TXQ_FLAG_TXNOFRMINT_ENABLE                0x0100  /* Enable TXNOFRM interrupt */
-#define AR5K_TXQ_FLAG_BACKOFF_DISABLE          0x0200  /* Disable random post-backoff */
-#define AR5K_TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE        0x0300  /* Enable ready time expiry policy (?)*/
-#define AR5K_TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE        0x0800  /* Enable backoff while bursting */
-#define AR5K_TXQ_FLAG_POST_FR_BKOFF_DIS                0x1000  /* Disable backoff while bursting */
-#define AR5K_TXQ_FLAG_COMPRESSION_ENABLE       0x2000  /* Enable hw compression -not implemented-*/
-
-/*
- * A struct to hold tx queue's parameters
- */
-struct ath5k_txq_info {
-       enum ath5k_tx_queue tqi_type;
-       enum ath5k_tx_queue_subtype tqi_subtype;
-       u16     tqi_flags;      /* Tx queue flags (see above) */
-       u32     tqi_aifs;       /* Arbitrated Interframe Space */
-       s32     tqi_cw_min;     /* Minimum Contention Window */
-       s32     tqi_cw_max;     /* Maximum Contention Window */
-       u32     tqi_cbr_period; /* Constant bit rate period */
-       u32     tqi_cbr_overflow_limit;
-       u32     tqi_burst_time;
-       u32     tqi_ready_time; /* Not used */
-};
-
-/*
- * Transmit packet types.
- * used on tx control descriptor
- * TODO: Use them inside base.c corectly
- */
-enum ath5k_pkt_type {
-       AR5K_PKT_TYPE_NORMAL            = 0,
-       AR5K_PKT_TYPE_ATIM              = 1,
-       AR5K_PKT_TYPE_PSPOLL            = 2,
-       AR5K_PKT_TYPE_BEACON            = 3,
-       AR5K_PKT_TYPE_PROBE_RESP        = 4,
-       AR5K_PKT_TYPE_PIFS              = 5,
-};
-
-/*
- * TX power and TPC settings
- */
-#define AR5K_TXPOWER_OFDM(_r, _v)      (                       \
-       ((0 & 1) << ((_v) + 6)) |                               \
-       (((ah->ah_txpower.txp_rates_power_table[(_r)]) & 0x3f) << (_v)) \
-)
-
-#define AR5K_TXPOWER_CCK(_r, _v)       (                       \
-       (ah->ah_txpower.txp_rates_power_table[(_r)] & 0x3f) << (_v)     \
-)
-
-/*
- * DMA size definitions (2^n+2)
- */
-enum ath5k_dmasize {
-       AR5K_DMASIZE_4B = 0,
-       AR5K_DMASIZE_8B,
-       AR5K_DMASIZE_16B,
-       AR5K_DMASIZE_32B,
-       AR5K_DMASIZE_64B,
-       AR5K_DMASIZE_128B,
-       AR5K_DMASIZE_256B,
-       AR5K_DMASIZE_512B
-};
-
-
-/****************\
-  RX DEFINITIONS
-\****************/
-
-/*
- * RX Status descriptor
- */
-struct ath5k_rx_status {
-       u16     rs_datalen;
-       u16     rs_tstamp;
-       u8      rs_status;
-       u8      rs_phyerr;
-       s8      rs_rssi;
-       u8      rs_keyix;
-       u8      rs_rate;
-       u8      rs_antenna;
-       u8      rs_more;
-};
-
-#define AR5K_RXERR_CRC         0x01
-#define AR5K_RXERR_PHY         0x02
-#define AR5K_RXERR_FIFO                0x04
-#define AR5K_RXERR_DECRYPT     0x08
-#define AR5K_RXERR_MIC         0x10
-#define AR5K_RXKEYIX_INVALID   ((u8) - 1)
-#define AR5K_TXKEYIX_INVALID   ((u32) - 1)
-
-
-/**************************\
- BEACON TIMERS DEFINITIONS
-\**************************/
-
-#define AR5K_BEACON_PERIOD     0x0000ffff
-#define AR5K_BEACON_ENA                0x00800000 /*enable beacon xmit*/
-#define AR5K_BEACON_RESET_TSF  0x01000000 /*force a TSF reset*/
-
-#if 0
-/**
- * struct ath5k_beacon_state - Per-station beacon timer state.
- * @bs_interval: in TU's, can also include the above flags
- * @bs_cfp_max_duration: if non-zero hw is setup to coexist with a
- *     Point Coordination Function capable AP
- */
-struct ath5k_beacon_state {
-       u32     bs_next_beacon;
-       u32     bs_next_dtim;
-       u32     bs_interval;
-       u8      bs_dtim_period;
-       u8      bs_cfp_period;
-       u16     bs_cfp_max_duration;
-       u16     bs_cfp_du_remain;
-       u16     bs_tim_offset;
-       u16     bs_sleep_duration;
-       u16     bs_bmiss_threshold;
-       u32     bs_cfp_next;
-};
-#endif
-
-
-/*
- * TSF to TU conversion:
- *
- * TSF is a 64bit value in usec (microseconds).
- * TU is a 32bit value and defined by IEEE802.11 (page 6) as "A measurement of
- * time equal to 1024 usec", so it's roughly milliseconds (usec / 1024).
- */
-#define TSF_TO_TU(_tsf) (u32)((_tsf) >> 10)
-
-
-/*******************************\
-  GAIN OPTIMIZATION DEFINITIONS
-\*******************************/
-
-enum ath5k_rfgain {
-       AR5K_RFGAIN_INACTIVE = 0,
-       AR5K_RFGAIN_ACTIVE,
-       AR5K_RFGAIN_READ_REQUESTED,
-       AR5K_RFGAIN_NEED_CHANGE,
-};
-
-struct ath5k_gain {
-       u8                      g_step_idx;
-       u8                      g_current;
-       u8                      g_target;
-       u8                      g_low;
-       u8                      g_high;
-       u8                      g_f_corr;
-       u8                      g_state;
-};
-
-/********************\
-  COMMON DEFINITIONS
-\********************/
-
-#define AR5K_SLOT_TIME_9       396
-#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_TURBO   0x0010  /* Turbo Channel */
-#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_T       (CHANNEL_5GHZ|CHANNEL_OFDM|CHANNEL_TURBO)
-#define        CHANNEL_TG      (CHANNEL_2GHZ|CHANNEL_OFDM|CHANNEL_TURBO)
-#define        CHANNEL_108A    CHANNEL_T
-#define        CHANNEL_108G    CHANNEL_TG
-#define        CHANNEL_X       (CHANNEL_5GHZ|CHANNEL_OFDM|CHANNEL_XR)
-
-#define        CHANNEL_ALL     (CHANNEL_OFDM|CHANNEL_CCK|CHANNEL_2GHZ|CHANNEL_5GHZ| \
-               CHANNEL_TURBO)
-
-#define        CHANNEL_ALL_NOTURBO     (CHANNEL_ALL & ~CHANNEL_TURBO)
-#define CHANNEL_MODES          CHANNEL_ALL
-
-/*
- * Used internaly for 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.
- * TODO: Clean up
- */
-struct ath5k_athchan_2ghz {
-       u32     a2_flags;
-       u16     a2_athchan;
-};
-
-
-/******************\
-  RATE DEFINITIONS
-\******************/
-
-/**
- * Seems the ar5xxx harware supports up to 32 rates, indexed by 1-32.
- *
- * The rate code is used to get the RX rate or set the TX rate on the
- * hardware descriptors. It is also used for internal modulation control
- * and settings.
- *
- * This is the hardware rate map we are aware of:
- *
- * rate_code   0x01    0x02    0x03    0x04    0x05    0x06    0x07    0x08
- * rate_kbps   3000    1000    ?       ?       ?       2000    500     48000
- *
- * rate_code   0x09    0x0A    0x0B    0x0C    0x0D    0x0E    0x0F    0x10
- * rate_kbps   24000   12000   6000    54000   36000   18000   9000    ?
- *
- * rate_code   17      18      19      20      21      22      23      24
- * rate_kbps   ?       ?       ?       ?       ?       ?       ?       11000
- *
- * rate_code   25      26      27      28      29      30      31      32
- * rate_kbps   5500    2000    1000    11000S  5500S   2000S   ?       ?
- *
- * "S" indicates CCK rates with short preamble.
- *
- * AR5211 has different rate codes for CCK (802.11B) rates. It only uses the
- * lowest 4 bits, so they are the same as below with a 0xF mask.
- * (0xB, 0xA, 0x9 and 0x8 for 1M, 2M, 5.5M and 11M).
- * We handle this in ath5k_setup_bands().
- */
-#define AR5K_MAX_RATES 32
-
-/* B */
-#define ATH5K_RATE_CODE_1M     0x1B
-#define ATH5K_RATE_CODE_2M     0x1A
-#define ATH5K_RATE_CODE_5_5M   0x19
-#define ATH5K_RATE_CODE_11M    0x18
-/* A and G */
-#define ATH5K_RATE_CODE_6M     0x0B
-#define ATH5K_RATE_CODE_9M     0x0F
-#define ATH5K_RATE_CODE_12M    0x0A
-#define ATH5K_RATE_CODE_18M    0x0E
-#define ATH5K_RATE_CODE_24M    0x09
-#define ATH5K_RATE_CODE_36M    0x0D
-#define ATH5K_RATE_CODE_48M    0x08
-#define ATH5K_RATE_CODE_54M    0x0C
-/* XR */
-#define ATH5K_RATE_CODE_XR_500K        0x07
-#define ATH5K_RATE_CODE_XR_1M  0x02
-#define ATH5K_RATE_CODE_XR_2M  0x06
-#define ATH5K_RATE_CODE_XR_3M  0x01
-
-/* adding this flag to rate_code enables short preamble */
-#define AR5K_SET_SHORT_PREAMBLE 0x04
-
-/*
- * Crypto definitions
- */
-
-#define AR5K_KEYCACHE_SIZE     8
-
-/***********************\
- HW RELATED DEFINITIONS
-\***********************/
-
-/*
- * Misc definitions
- */
-#define        AR5K_RSSI_EP_MULTIPLIER (1<<7)
-
-#define AR5K_ASSERT_ENTRY(_e, _s) do {         \
-       if (_e >= _s)                           \
-               return (false);                 \
-} while (0)
-
-/*
- * Hardware interrupt abstraction
- */
-
-/**
- * enum ath5k_int - Hardware interrupt masks helpers
- *
- * @AR5K_INT_RX: mask to identify received frame interrupts, of type
- *     AR5K_ISR_RXOK or AR5K_ISR_RXERR
- * @AR5K_INT_RXDESC: Request RX descriptor/Read RX descriptor (?)
- * @AR5K_INT_RXNOFRM: No frame received (?)
- * @AR5K_INT_RXEOL: received End Of List for VEOL (Virtual End Of List). The
- *     Queue Control Unit (QCU) signals an EOL interrupt only if a descriptor's
- *     LinkPtr is NULL. For more details, refer to:
- *     http://www.freepatentsonline.com/20030225739.html
- * @AR5K_INT_RXORN: Indicates we got RX overrun (eg. no more descriptors).
- *     Note that Rx overrun is not always fatal, on some chips we can continue
- *     operation without reseting the card, that's why int_fatal is not
- *     common for all chips.
- * @AR5K_INT_TX: mask to identify received frame interrupts, of type
- *     AR5K_ISR_TXOK or AR5K_ISR_TXERR
- * @AR5K_INT_TXDESC: Request TX descriptor/Read TX status descriptor (?)
- * @AR5K_INT_TXURN: received when we should increase the TX trigger threshold
- *     We currently do increments on interrupt by
- *     (AR5K_TUNE_MAX_TX_FIFO_THRES - current_trigger_level) / 2
- * @AR5K_INT_MIB: Indicates the Management Information Base counters should be
- *     checked. We should do this with ath5k_hw_update_mib_counters() but
- *     it seems we should also then do some noise immunity work.
- * @AR5K_INT_RXPHY: RX PHY Error
- * @AR5K_INT_RXKCM: RX Key cache miss
- * @AR5K_INT_SWBA: SoftWare Beacon Alert - indicates its time to send a
- *     beacon that must be handled in software. The alternative is if you
- *     have VEOL support, in that case you let the hardware deal with things.
- * @AR5K_INT_BMISS: If in STA mode this indicates we have stopped seeing
- *     beacons from the AP have associated with, we should probably try to
- *     reassociate. When in IBSS mode this might mean we have not received
- *     any beacons from any local stations. Note that every station in an
- *     IBSS schedules to send beacons at the Target Beacon Transmission Time
- *     (TBTT) with a random backoff.
- * @AR5K_INT_BNR: Beacon Not Ready interrupt - ??
- * @AR5K_INT_GPIO: GPIO interrupt is used for RF Kill, disabled for now
- *     until properly handled
- * @AR5K_INT_FATAL: Fatal errors were encountered, typically caused by DMA
- *     errors. These types of errors we can enable seem to be of type
- *     AR5K_SIMR2_MCABT, AR5K_SIMR2_SSERR and AR5K_SIMR2_DPERR.
- * @AR5K_INT_GLOBAL: Used to clear and set the IER
- * @AR5K_INT_NOCARD: signals the card has been removed
- * @AR5K_INT_COMMON: common interrupts shared amogst MACs with the same
- *     bit value
- *
- * These are mapped to take advantage of some common bits
- * between the MACs, to be able to set intr properties
- * easier. Some of them are not used yet inside hw.c. Most map
- * to the respective hw interrupt value as they are common amogst different
- * MACs.
- */
-enum ath5k_int {
-       AR5K_INT_RXOK   = 0x00000001,
-       AR5K_INT_RXDESC = 0x00000002,
-       AR5K_INT_RXERR  = 0x00000004,
-       AR5K_INT_RXNOFRM = 0x00000008,
-       AR5K_INT_RXEOL  = 0x00000010,
-       AR5K_INT_RXORN  = 0x00000020,
-       AR5K_INT_TXOK   = 0x00000040,
-       AR5K_INT_TXDESC = 0x00000080,
-       AR5K_INT_TXERR  = 0x00000100,
-       AR5K_INT_TXNOFRM = 0x00000200,
-       AR5K_INT_TXEOL  = 0x00000400,
-       AR5K_INT_TXURN  = 0x00000800,
-       AR5K_INT_MIB    = 0x00001000,
-       AR5K_INT_SWI    = 0x00002000,
-       AR5K_INT_RXPHY  = 0x00004000,
-       AR5K_INT_RXKCM  = 0x00008000,
-       AR5K_INT_SWBA   = 0x00010000,
-       AR5K_INT_BRSSI  = 0x00020000,
-       AR5K_INT_BMISS  = 0x00040000,
-       AR5K_INT_FATAL  = 0x00080000, /* Non common */
-       AR5K_INT_BNR    = 0x00100000, /* Non common */
-       AR5K_INT_TIM    = 0x00200000, /* Non common */
-       AR5K_INT_DTIM   = 0x00400000, /* Non common */
-       AR5K_INT_DTIM_SYNC =    0x00800000, /* Non common */
-       AR5K_INT_GPIO   =       0x01000000,
-       AR5K_INT_BCN_TIMEOUT =  0x02000000, /* Non common */
-       AR5K_INT_CAB_TIMEOUT =  0x04000000, /* Non common */
-       AR5K_INT_RX_DOPPLER =   0x08000000, /* Non common */
-       AR5K_INT_QCBRORN =      0x10000000, /* Non common */
-       AR5K_INT_QCBRURN =      0x20000000, /* Non common */
-       AR5K_INT_QTRIG  =       0x40000000, /* Non common */
-       AR5K_INT_GLOBAL =       0x80000000,
-
-       AR5K_INT_COMMON  = AR5K_INT_RXOK
-               | AR5K_INT_RXDESC
-               | AR5K_INT_RXERR
-               | AR5K_INT_RXNOFRM
-               | AR5K_INT_RXEOL
-               | AR5K_INT_RXORN
-               | AR5K_INT_TXOK
-               | AR5K_INT_TXDESC
-               | AR5K_INT_TXERR
-               | AR5K_INT_TXNOFRM
-               | AR5K_INT_TXEOL
-               | AR5K_INT_TXURN
-               | AR5K_INT_MIB
-               | AR5K_INT_SWI
-               | AR5K_INT_RXPHY
-               | AR5K_INT_RXKCM
-               | AR5K_INT_SWBA
-               | AR5K_INT_BRSSI
-               | AR5K_INT_BMISS
-               | AR5K_INT_GPIO
-               | AR5K_INT_GLOBAL,
-
-       AR5K_INT_NOCARD = 0xffffffff
-};
-
-/*
- * Power management
- */
-enum ath5k_power_mode {
-       AR5K_PM_UNDEFINED = 0,
-       AR5K_PM_AUTO,
-       AR5K_PM_AWAKE,
-       AR5K_PM_FULL_SLEEP,
-       AR5K_PM_NETWORK_SLEEP,
-};
-
-/*
- * These match net80211 definitions (not used in
- * mac80211).
- * TODO: Clean this up
- */
-#define AR5K_LED_INIT  0 /*IEEE80211_S_INIT*/
-#define AR5K_LED_SCAN  1 /*IEEE80211_S_SCAN*/
-#define AR5K_LED_AUTH  2 /*IEEE80211_S_AUTH*/
-#define AR5K_LED_ASSOC 3 /*IEEE80211_S_ASSOC*/
-#define AR5K_LED_RUN   4 /*IEEE80211_S_RUN*/
-
-/* GPIO-controlled software LED */
-#define AR5K_SOFTLED_PIN       0
-#define AR5K_SOFTLED_ON                0
-#define AR5K_SOFTLED_OFF       1
-
-/*
- * Chipset capabilities -see ath5k_hw_get_capability-
- * get_capability function is not yet fully implemented
- * in ath5k so most of these don't work yet...
- * TODO: Implement these & merge with _TUNE_ stuff above
- */
-enum ath5k_capability_type {
-       AR5K_CAP_REG_DMN                = 0,    /* Used to get current reg. domain id */
-       AR5K_CAP_TKIP_MIC               = 2,    /* Can handle TKIP MIC in hardware */
-       AR5K_CAP_TKIP_SPLIT             = 3,    /* TKIP uses split keys */
-       AR5K_CAP_PHYCOUNTERS            = 4,    /* PHY error counters */
-       AR5K_CAP_DIVERSITY              = 5,    /* Supports fast diversity */
-       AR5K_CAP_NUM_TXQUEUES           = 6,    /* Used to get max number of hw txqueues */
-       AR5K_CAP_VEOL                   = 7,    /* Supports virtual EOL */
-       AR5K_CAP_COMPRESSION            = 8,    /* Supports compression */
-       AR5K_CAP_BURST                  = 9,    /* Supports packet bursting */
-       AR5K_CAP_FASTFRAME              = 10,   /* Supports fast frames */
-       AR5K_CAP_TXPOW                  = 11,   /* Used to get global tx power limit */
-       AR5K_CAP_TPC                    = 12,   /* Can do per-packet tx power control (needed for 802.11a) */
-       AR5K_CAP_BSSIDMASK              = 13,   /* Supports bssid mask */
-       AR5K_CAP_MCAST_KEYSRCH          = 14,   /* Supports multicast key search */
-       AR5K_CAP_TSF_ADJUST             = 15,   /* Supports beacon tsf adjust */
-       AR5K_CAP_XR                     = 16,   /* Supports XR mode */
-       AR5K_CAP_WME_TKIPMIC            = 17,   /* Supports TKIP MIC when using WMM */
-       AR5K_CAP_CHAN_HALFRATE          = 18,   /* Supports half rate channels */
-       AR5K_CAP_CHAN_QUARTERRATE       = 19,   /* Supports quarter rate channels */
-       AR5K_CAP_RFSILENT               = 20,   /* Supports RFsilent */
-};
-
-
-/* XXX: we *may* move cap_range stuff to struct wiphy */
-struct ath5k_capabilities {
-       /*
-        * Supported PHY modes
-        * (ie. CHANNEL_A, CHANNEL_B, ...)
-        */
-       DECLARE_BITMAP(cap_mode, AR5K_MODE_MAX);
-
-       /*
-        * Frequency range (without regulation restrictions)
-        */
-       struct {
-               u16     range_2ghz_min;
-               u16     range_2ghz_max;
-               u16     range_5ghz_min;
-               u16     range_5ghz_max;
-       } cap_range;
-
-       /*
-        * Values stored in the EEPROM (some of them...)
-        */
-       struct ath5k_eeprom_info        cap_eeprom;
-
-       /*
-        * Queue information
-        */
-       struct {
-               u8      q_tx_num;
-       } cap_queues;
-};
-
-
-/***************************************\
-  HARDWARE ABSTRACTION LAYER STRUCTURE
-\***************************************/
-
-/*
- * Misc defines
- */
-
-#define AR5K_MAX_GPIO          10
-#define AR5K_MAX_RF_BANKS      8
-
-/* TODO: Clean up and merge with ath5k_softc */
-struct ath5k_hw {
-       u32                     ah_magic;
-
-       struct ath5k_softc      *ah_sc;
-       void __iomem            *ah_iobase;
-
-       enum ath5k_int          ah_imr;
-
-       enum nl80211_iftype     ah_op_mode;
-       enum ath5k_power_mode   ah_power_mode;
-       struct ieee80211_channel ah_current_channel;
-       bool                    ah_turbo;
-       bool                    ah_calibration;
-       bool                    ah_running;
-       bool                    ah_single_chip;
-       bool                    ah_combined_mic;
-
-       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;
-
-       enum ath5k_version      ah_version;
-       enum ath5k_radio        ah_radio;
-       u32                     ah_phy;
-
-       bool                    ah_5ghz;
-       bool                    ah_2ghz;
-
-#define ah_regdomain           ah_capabilities.cap_regdomain.reg_current
-#define ah_regdomain_hw                ah_capabilities.cap_regdomain.reg_hw
-#define ah_modes               ah_capabilities.cap_mode
-#define ah_ee_version          ah_capabilities.cap_eeprom.ee_version
-
-       u32                     ah_atim_window;
-       u32                     ah_aifs;
-       u32                     ah_cw_min;
-       u32                     ah_cw_max;
-       bool                    ah_software_retry;
-       u32                     ah_limit_tx_retries;
-
-       u32                     ah_antenna[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX];
-       bool                    ah_ant_diversity;
-
-       u8                      ah_sta_id[ETH_ALEN];
-
-       /* Current BSSID we are trying to assoc to / create.
-        * This is passed by mac80211 on config_interface() and cached here for
-        * use in resets */
-       u8                      ah_bssid[ETH_ALEN];
-       u8                      ah_bssid_mask[ETH_ALEN];
-
-       u32                     ah_gpio[AR5K_MAX_GPIO];
-       int                     ah_gpio_npins;
-
-       struct ath5k_capabilities ah_capabilities;
-
-       struct ath5k_txq_info   ah_txq[AR5K_NUM_TX_QUEUES];
-       u32                     ah_txq_status;
-       u32                     ah_txq_imr_txok;
-       u32                     ah_txq_imr_txerr;
-       u32                     ah_txq_imr_txurn;
-       u32                     ah_txq_imr_txdesc;
-       u32                     ah_txq_imr_txeol;
-       u32                     ah_txq_imr_cbrorn;
-       u32                     ah_txq_imr_cbrurn;
-       u32                     ah_txq_imr_qtrig;
-       u32                     ah_txq_imr_nofrm;
-       u32                     ah_txq_isr;
-       u32                     *ah_rf_banks;
-       size_t                  ah_rf_banks_size;
-       size_t                  ah_rf_regs_count;
-       struct ath5k_gain       ah_gain;
-       u8                      ah_offset[AR5K_MAX_RF_BANKS];
-
-
-       struct {
-               /* Temporary tables used for interpolation */
-               u8              tmpL[AR5K_EEPROM_N_PD_GAINS]
-                                       [AR5K_EEPROM_POWER_TABLE_SIZE];
-               u8              tmpR[AR5K_EEPROM_N_PD_GAINS]
-                                       [AR5K_EEPROM_POWER_TABLE_SIZE];
-               u8              txp_pd_table[AR5K_EEPROM_POWER_TABLE_SIZE * 2];
-               u16             txp_rates_power_table[AR5K_MAX_RATES];
-               u8              txp_min_idx;
-               bool            txp_tpc;
-               /* Values in 0.25dB units */
-               s16             txp_min_pwr;
-               s16             txp_max_pwr;
-               s16             txp_offset;
-               s16             txp_ofdm;
-               /* Values in dB units */
-               s16             txp_cck_ofdm_pwr_delta;
-               s16             txp_cck_ofdm_gainf_delta;
-       } ah_txpower;
-
-       struct {
-               bool            r_enabled;
-               int             r_last_alert;
-               struct ieee80211_channel r_last_channel;
-       } ah_radar;
-
-       /* noise floor from last periodic calibration */
-       s32                     ah_noise_floor;
-
-       /*
-        * Function pointers
-        */
-       int (*ah_setup_rx_desc)(struct ath5k_hw *ah, struct ath5k_desc *desc,
-                               u32 size, unsigned int flags);
-       int (*ah_setup_tx_desc)(struct ath5k_hw *, struct ath5k_desc *,
-               unsigned int, unsigned int, enum ath5k_pkt_type, unsigned int,
-               unsigned int, unsigned int, unsigned int, unsigned int,
-               unsigned int, unsigned int, unsigned int);
-       int (*ah_setup_mrr_tx_desc)(struct ath5k_hw *, struct ath5k_desc *,
-               unsigned int, unsigned int, unsigned int, unsigned int,
-               unsigned int, unsigned int);
-       int (*ah_proc_tx_desc)(struct ath5k_hw *, struct ath5k_desc *,
-               struct ath5k_tx_status *);
-       int (*ah_proc_rx_desc)(struct ath5k_hw *, struct ath5k_desc *,
-               struct ath5k_rx_status *);
-};
-
-/*
- * Prototypes
- */
-
-/* Attach/Detach Functions */
-extern struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version);
-extern void ath5k_hw_detach(struct ath5k_hw *ah);
-
-/* LED functions */
-extern int ath5k_init_leds(struct ath5k_softc *sc);
-extern void ath5k_led_enable(struct ath5k_softc *sc);
-extern void ath5k_led_off(struct ath5k_softc *sc);
-extern void ath5k_unregister_leds(struct ath5k_softc *sc);
-
-/* Reset Functions */
-extern int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial);
-extern int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, struct ieee80211_channel *channel, bool change_channel);
-/* Power management functions */
-extern int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode, bool set_chip, u16 sleep_duration);
-
-/* DMA Related Functions */
-extern void ath5k_hw_start_rx_dma(struct ath5k_hw *ah);
-extern int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah);
-extern u32 ath5k_hw_get_rxdp(struct ath5k_hw *ah);
-extern void ath5k_hw_set_rxdp(struct ath5k_hw *ah, u32 phys_addr);
-extern int ath5k_hw_start_tx_dma(struct ath5k_hw *ah, unsigned int queue);
-extern int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue);
-extern u32 ath5k_hw_get_txdp(struct ath5k_hw *ah, unsigned int queue);
-extern int ath5k_hw_set_txdp(struct ath5k_hw *ah, unsigned int queue,
-                               u32 phys_addr);
-extern int ath5k_hw_update_tx_triglevel(struct ath5k_hw *ah, bool increase);
-/* Interrupt handling */
-extern bool ath5k_hw_is_intr_pending(struct ath5k_hw *ah);
-extern int ath5k_hw_get_isr(struct ath5k_hw *ah, enum ath5k_int *interrupt_mask);
-extern enum ath5k_int ath5k_hw_set_imr(struct ath5k_hw *ah, enum
-ath5k_int new_mask);
-extern void ath5k_hw_update_mib_counters(struct ath5k_hw *ah, struct ieee80211_low_level_stats *stats);
-
-/* EEPROM access functions */
-extern int ath5k_eeprom_init(struct ath5k_hw *ah);
-extern void ath5k_eeprom_detach(struct ath5k_hw *ah);
-extern int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac);
-extern bool ath5k_eeprom_is_hb63(struct ath5k_hw *ah);
-
-/* Protocol Control Unit Functions */
-extern int ath5k_hw_set_opmode(struct ath5k_hw *ah);
-/* BSSID Functions */
-extern void ath5k_hw_get_lladdr(struct ath5k_hw *ah, u8 *mac);
-extern int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac);
-extern void ath5k_hw_set_associd(struct ath5k_hw *ah, const u8 *bssid, u16 assoc_id);
-extern int ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask);
-/* Receive start/stop functions */
-extern void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah);
-extern void ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah);
-/* RX Filter functions */
-extern void ath5k_hw_set_mcast_filter(struct ath5k_hw *ah, u32 filter0, u32 filter1);
-extern int ath5k_hw_set_mcast_filter_idx(struct ath5k_hw *ah, u32 index);
-extern int ath5k_hw_clear_mcast_filter_idx(struct ath5k_hw *ah, u32 index);
-extern u32 ath5k_hw_get_rx_filter(struct ath5k_hw *ah);
-extern void ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter);
-/* Beacon control functions */
-extern u32 ath5k_hw_get_tsf32(struct ath5k_hw *ah);
-extern u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah);
-extern void ath5k_hw_set_tsf64(struct ath5k_hw *ah, u64 tsf64);
-extern void ath5k_hw_reset_tsf(struct ath5k_hw *ah);
-extern void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval);
-#if 0
-extern int ath5k_hw_set_beacon_timers(struct ath5k_hw *ah, const struct ath5k_beacon_state *state);
-extern void ath5k_hw_reset_beacon(struct ath5k_hw *ah);
-extern int ath5k_hw_beaconq_finish(struct ath5k_hw *ah, unsigned long phys_addr);
-#endif
-/* ACK bit rate */
-void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high);
-/* ACK/CTS Timeouts */
-extern int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout);
-extern unsigned int ath5k_hw_get_ack_timeout(struct ath5k_hw *ah);
-extern int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout);
-extern unsigned int ath5k_hw_get_cts_timeout(struct ath5k_hw *ah);
-/* Key table (WEP) functions */
-extern int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry);
-extern int ath5k_hw_is_key_valid(struct ath5k_hw *ah, u16 entry);
-extern int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry, const struct ieee80211_key_conf *key, const u8 *mac);
-extern int ath5k_hw_set_key_lladdr(struct ath5k_hw *ah, u16 entry, const u8 *mac);
-
-/* Queue Control Unit, DFS Control Unit Functions */
-extern int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue, struct ath5k_txq_info *queue_info);
-extern int ath5k_hw_set_tx_queueprops(struct ath5k_hw *ah, int queue,
-                               const struct ath5k_txq_info *queue_info);
-extern int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah,
-                               enum ath5k_tx_queue queue_type,
-                               struct ath5k_txq_info *queue_info);
-extern u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue);
-extern void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue);
-extern int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue);
-extern unsigned int ath5k_hw_get_slot_time(struct ath5k_hw *ah);
-extern int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time);
-
-/* Hardware Descriptor Functions */
-extern int ath5k_hw_init_desc_functions(struct ath5k_hw *ah);
-
-/* GPIO Functions */
-extern void ath5k_hw_set_ledstate(struct ath5k_hw *ah, unsigned int state);
-extern int ath5k_hw_set_gpio_input(struct ath5k_hw *ah, u32 gpio);
-extern int ath5k_hw_set_gpio_output(struct ath5k_hw *ah, u32 gpio);
-extern u32 ath5k_hw_get_gpio(struct ath5k_hw *ah, u32 gpio);
-extern int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val);
-extern void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio, u32 interrupt_level);
-
-/* Misc functions */
-int ath5k_hw_set_capabilities(struct ath5k_hw *ah);
-extern int ath5k_hw_get_capability(struct ath5k_hw *ah, enum ath5k_capability_type cap_type, u32 capability, u32 *result);
-extern int ath5k_hw_enable_pspoll(struct ath5k_hw *ah, u8 *bssid, u16 assoc_id);
-extern int ath5k_hw_disable_pspoll(struct ath5k_hw *ah);
-
-/* Initial register settings functions */
-extern int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel);
-
-/* Initialize RF */
-extern int ath5k_hw_rfregs_init(struct ath5k_hw *ah,
-                               struct ieee80211_channel *channel,
-                               unsigned int mode);
-extern int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq);
-extern enum ath5k_rfgain ath5k_hw_gainf_calibrate(struct ath5k_hw *ah);
-extern int ath5k_hw_rfgain_opt_init(struct ath5k_hw *ah);
-/* PHY/RF channel functions */
-extern bool ath5k_channel_ok(struct ath5k_hw *ah, u16 freq, unsigned int flags);
-extern int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel);
-/* PHY calibration */
-extern int ath5k_hw_phy_calibrate(struct ath5k_hw *ah, struct ieee80211_channel *channel);
-extern int ath5k_hw_noise_floor_calibration(struct ath5k_hw *ah, short freq);
-/* Misc PHY functions */
-extern u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan);
-extern void ath5k_hw_set_def_antenna(struct ath5k_hw *ah, unsigned int ant);
-extern unsigned int ath5k_hw_get_def_antenna(struct ath5k_hw *ah);
-extern int ath5k_hw_phy_disable(struct ath5k_hw *ah);
-/* TX power setup */
-extern int ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, u8 ee_mode, u8 txpower);
-extern int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 ee_mode, u8 txpower);
-
-/*
- * Functions used internaly
- */
-
-/*
- * Translate usec to hw clock units
- * TODO: Half/quarter rate
- */
-static inline unsigned int ath5k_hw_htoclock(unsigned int usec, bool turbo)
-{
-       return turbo ? (usec * 80) : (usec * 40);
-}
-
-/*
- * Translate hw clock units to usec
- * TODO: Half/quarter rate
- */
-static inline unsigned int ath5k_hw_clocktoh(unsigned int clock, bool turbo)
-{
-       return turbo ? (clock / 80) : (clock / 40);
-}
-
-/*
- * Read from a register
- */
-static inline u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg)
-{
-       return ioread32(ah->ah_iobase + reg);
-}
-
-/*
- * Write to a register
- */
-static inline void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg)
-{
-       iowrite32(val, ah->ah_iobase + reg);
-}
-
-#if defined(_ATH5K_RESET) || defined(_ATH5K_PHY)
-/*
- * Check if a register write has been completed
- */
-static int ath5k_hw_register_timeout(struct ath5k_hw *ah, u32 reg, u32 flag,
-               u32 val, bool is_set)
-{
-       int i;
-       u32 data;
-
-       for (i = AR5K_TUNE_REGISTER_TIMEOUT; i > 0; i--) {
-               data = ath5k_hw_reg_read(ah, reg);
-               if (is_set && (data & flag))
-                       break;
-               else if ((data & flag) == val)
-                       break;
-               udelay(15);
-       }
-
-       return (i <= 0) ? -EAGAIN : 0;
-}
-#endif
-
-static inline u32 ath5k_hw_bitswap(u32 val, unsigned int bits)
-{
-       u32 retval = 0, bit, i;
-
-       for (i = 0; i < bits; i++) {
-               bit = (val >> i) & 1;
-               retval = (retval << 1) | bit;
-       }
-
-       return retval;
-}
-
-static inline int ath5k_pad_size(int hdrlen)
-{
-       return (hdrlen < 24) ? 0 : hdrlen & 3;
-}
-
-#endif
diff --git a/drivers/net/wireless/ath5k/attach.c b/drivers/net/wireless/ath5k/attach.c
deleted file mode 100644 (file)
index 70d376c..0000000
+++ /dev/null
@@ -1,348 +0,0 @@
-/*
- * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
- * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
- *
- * Permission to use, copy, modify, and 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.
- *
- */
-
-/*************************************\
-* Attach/Detach Functions and helpers *
-\*************************************/
-
-#include <linux/pci.h>
-#include "ath5k.h"
-#include "reg.h"
-#include "debug.h"
-#include "base.h"
-
-/**
- * ath5k_hw_post - Power On Self Test helper function
- *
- * @ah: The &struct ath5k_hw
- */
-static int ath5k_hw_post(struct ath5k_hw *ah)
-{
-
-       static const u32 static_pattern[4] = {
-               0x55555555,     0xaaaaaaaa,
-               0x66666666,     0x99999999
-       };
-       static const u16 regs[2] = { AR5K_STA_ID0, AR5K_PHY(8) };
-       int i, c;
-       u16 cur_reg;
-       u32 var_pattern;
-       u32 init_val;
-       u32 cur_val;
-
-       for (c = 0; c < 2; c++) {
-
-               cur_reg = regs[c];
-
-               /* Save previous value */
-               init_val = ath5k_hw_reg_read(ah, cur_reg);
-
-               for (i = 0; i < 256; i++) {
-                       var_pattern = i << 16 | i;
-                       ath5k_hw_reg_write(ah, var_pattern, cur_reg);
-                       cur_val = ath5k_hw_reg_read(ah, cur_reg);
-
-                       if (cur_val != var_pattern) {
-                               ATH5K_ERR(ah->ah_sc, "POST Failed !!!\n");
-                               return -EAGAIN;
-                       }
-
-                       /* Found on ndiswrapper dumps */
-                       var_pattern = 0x0039080f;
-                       ath5k_hw_reg_write(ah, var_pattern, cur_reg);
-               }
-
-               for (i = 0; i < 4; i++) {
-                       var_pattern = static_pattern[i];
-                       ath5k_hw_reg_write(ah, var_pattern, cur_reg);
-                       cur_val = ath5k_hw_reg_read(ah, cur_reg);
-
-                       if (cur_val != var_pattern) {
-                               ATH5K_ERR(ah->ah_sc, "POST Failed !!!\n");
-                               return -EAGAIN;
-                       }
-
-                       /* Found on ndiswrapper dumps */
-                       var_pattern = 0x003b080f;
-                       ath5k_hw_reg_write(ah, var_pattern, cur_reg);
-               }
-
-               /* Restore previous value */
-               ath5k_hw_reg_write(ah, init_val, cur_reg);
-
-       }
-
-       return 0;
-
-}
-
-/**
- * ath5k_hw_attach - Check if hw is supported and init the needed structs
- *
- * @sc: The &struct ath5k_softc we got from the driver's attach function
- * @mac_version: The mac version id (check out ath5k.h) based on pci id
- *
- * 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,
- * -ENODEV if the device is not supported or prints an error msg if something
- * else went wrong.
- */
-struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
-{
-       struct ath5k_hw *ah;
-       struct pci_dev *pdev = sc->pdev;
-       int ret;
-       u32 srev;
-
-       /*If we passed the test malloc a ath5k_hw struct*/
-       ah = kzalloc(sizeof(struct ath5k_hw), GFP_KERNEL);
-       if (ah == NULL) {
-               ret = -ENOMEM;
-               ATH5K_ERR(sc, "out of memory\n");
-               goto err;
-       }
-
-       ah->ah_sc = sc;
-       ah->ah_iobase = sc->iobase;
-
-       /*
-        * HW information
-        */
-       ah->ah_op_mode = NL80211_IFTYPE_STATION;
-       ah->ah_radar.r_enabled = AR5K_TUNE_RADAR_ALERT;
-       ah->ah_turbo = false;
-       ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER;
-       ah->ah_imr = 0;
-       ah->ah_atim_window = 0;
-       ah->ah_aifs = AR5K_TUNE_AIFS;
-       ah->ah_cw_min = AR5K_TUNE_CWMIN;
-       ah->ah_limit_tx_retries = AR5K_INIT_TX_RETRY;
-       ah->ah_software_retry = false;
-       ah->ah_ant_diversity = AR5K_TUNE_ANT_DIVERSITY;
-
-       /*
-        * Set the mac version based on the pci id
-        */
-       ah->ah_version = mac_version;
-
-       /*Fill the ath5k_hw struct with the needed functions*/
-       ret = ath5k_hw_init_desc_functions(ah);
-       if (ret)
-               goto err_free;
-
-       /* Bring device out of sleep and reset it's units */
-       ret = ath5k_hw_nic_wakeup(ah, CHANNEL_B, true);
-       if (ret)
-               goto err_free;
-
-       /* Get MAC, PHY and RADIO revisions */
-       srev = ath5k_hw_reg_read(ah, AR5K_SREV);
-       ah->ah_mac_srev = srev;
-       ah->ah_mac_version = AR5K_REG_MS(srev, AR5K_SREV_VER);
-       ah->ah_mac_revision = AR5K_REG_MS(srev, AR5K_SREV_REV);
-       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);
-
-       /* Try to identify radio chip based on it's srev */
-       switch (ah->ah_radio_5ghz_revision & 0xf0) {
-       case AR5K_SREV_RAD_5111:
-               ah->ah_radio = AR5K_RF5111;
-               ah->ah_single_chip = false;
-               ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah,
-                                                       CHANNEL_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);
-               break;
-       case AR5K_SREV_RAD_2413:
-               ah->ah_radio = AR5K_RF2413;
-               ah->ah_single_chip = true;
-               break;
-       case AR5K_SREV_RAD_5413:
-               ah->ah_radio = AR5K_RF5413;
-               ah->ah_single_chip = true;
-               break;
-       case AR5K_SREV_RAD_2316:
-               ah->ah_radio = AR5K_RF2316;
-               ah->ah_single_chip = true;
-               break;
-       case AR5K_SREV_RAD_2317:
-               ah->ah_radio = AR5K_RF2317;
-               ah->ah_single_chip = true;
-               break;
-       case AR5K_SREV_RAD_5424:
-               if (ah->ah_mac_version == AR5K_SREV_AR2425 ||
-               ah->ah_mac_version == AR5K_SREV_AR2417){
-                       ah->ah_radio = AR5K_RF2425;
-                       ah->ah_single_chip = true;
-               } else {
-                       ah->ah_radio = AR5K_RF5413;
-                       ah->ah_single_chip = true;
-               }
-               break;
-       default:
-               /* Identify radio based on mac/phy srev */
-               if (ah->ah_version == AR5K_AR5210) {
-                       ah->ah_radio = AR5K_RF5110;
-                       ah->ah_single_chip = false;
-               } else if (ah->ah_version == AR5K_AR5211) {
-                       ah->ah_radio = AR5K_RF5111;
-                       ah->ah_single_chip = false;
-                       ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah,
-                                                               CHANNEL_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) {
-                       ah->ah_radio = AR5K_RF2425;
-                       ah->ah_single_chip = true;
-                       ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2425;
-               } else if (srev == AR5K_SREV_AR5213A &&
-               ah->ah_phy_revision == AR5K_SREV_PHY_5212B) {
-                       ah->ah_radio = AR5K_RF5112;
-                       ah->ah_single_chip = false;
-                       ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_5112B;
-               } else if (ah->ah_mac_version == (AR5K_SREV_AR2415 >> 4)) {
-                       ah->ah_radio = AR5K_RF2316;
-                       ah->ah_single_chip = true;
-                       ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2316;
-               } else if (ah->ah_mac_version == (AR5K_SREV_AR5414 >> 4) ||
-               ah->ah_phy_revision == AR5K_SREV_PHY_5413) {
-                       ah->ah_radio = AR5K_RF5413;
-                       ah->ah_single_chip = true;
-                       ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_5413;
-               } else if (ah->ah_mac_version == (AR5K_SREV_AR2414 >> 4) ||
-               ah->ah_phy_revision == AR5K_SREV_PHY_2413) {
-                       ah->ah_radio = AR5K_RF2413;
-                       ah->ah_single_chip = true;
-                       ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2413;
-               } else {
-                       ATH5K_ERR(sc, "Couldn't identify radio revision.\n");
-                       ret = -ENODEV;
-                       goto err_free;
-               }
-       }
-
-
-       /* Return on unsuported chips (unsupported eeprom etc) */
-       if ((srev >= AR5K_SREV_AR5416) &&
-       (srev < AR5K_SREV_AR2425)) {
-               ATH5K_ERR(sc, "Device not yet supported.\n");
-               ret = -ENODEV;
-               goto err_free;
-       }
-
-       /*
-        * Write PCI-E power save settings
-        */
-       if ((ah->ah_version == AR5K_AR5212) && (pdev->is_pcie)) {
-               ath5k_hw_reg_write(ah, 0x9248fc00, AR5K_PCIE_SERDES);
-               ath5k_hw_reg_write(ah, 0x24924924, AR5K_PCIE_SERDES);
-               /* Shut off RX when elecidle is asserted */
-               ath5k_hw_reg_write(ah, 0x28000039, AR5K_PCIE_SERDES);
-               ath5k_hw_reg_write(ah, 0x53160824, AR5K_PCIE_SERDES);
-               /* TODO: EEPROM work */
-               ath5k_hw_reg_write(ah, 0xe5980579, AR5K_PCIE_SERDES);
-               /* Shut off PLL and CLKREQ active in L1 */
-               ath5k_hw_reg_write(ah, 0x001defff, AR5K_PCIE_SERDES);
-               /* Preserce other settings */
-               ath5k_hw_reg_write(ah, 0x1aaabe40, AR5K_PCIE_SERDES);
-               ath5k_hw_reg_write(ah, 0xbe105554, AR5K_PCIE_SERDES);
-               ath5k_hw_reg_write(ah, 0x000e3007, AR5K_PCIE_SERDES);
-               /* Reset SERDES to load new settings */
-               ath5k_hw_reg_write(ah, 0x00000000, AR5K_PCIE_SERDES_RESET);
-               mdelay(1);
-       }
-
-       /*
-        * POST
-        */
-       ret = ath5k_hw_post(ah);
-       if (ret)
-               goto err_free;
-
-       /* Enable pci core retry fix on Hainan (5213A) and later chips */
-       if (srev >= AR5K_SREV_AR5213A)
-               ath5k_hw_reg_write(ah, AR5K_PCICFG_RETRY_FIX, AR5K_PCICFG);
-
-       /*
-        * Get card capabilities, calibration values etc
-        * TODO: EEPROM work
-        */
-       ret = ath5k_eeprom_init(ah);
-       if (ret) {
-               ATH5K_ERR(sc, "unable to init EEPROM\n");
-               goto err_free;
-       }
-
-       /* Get misc capabilities */
-       ret = ath5k_hw_set_capabilities(ah);
-       if (ret) {
-               ATH5K_ERR(sc, "unable to get device capabilities: 0x%04x\n",
-                       sc->pdev->device);
-               goto err_free;
-       }
-
-       if (srev >= AR5K_SREV_AR2414) {
-               ah->ah_combined_mic = true;
-               AR5K_REG_ENABLE_BITS(ah, AR5K_MISC_MODE,
-                       AR5K_MISC_MODE_COMBINED_MIC);
-       }
-
-       /* MAC address is cleared until add_interface */
-       ath5k_hw_set_lladdr(ah, (u8[ETH_ALEN]){});
-
-       /* Set BSSID to bcast address: ff:ff:ff:ff:ff:ff for now */
-       memset(ah->ah_bssid, 0xff, ETH_ALEN);
-       ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
-       ath5k_hw_set_opmode(ah);
-
-       ath5k_hw_rfgain_opt_init(ah);
-
-       return ah;
-err_free:
-       kfree(ah);
-err:
-       return ERR_PTR(ret);
-}
-
-/**
- * ath5k_hw_detach - Free the ath5k_hw struct
- *
- * @ah: The &struct ath5k_hw
- */
-void ath5k_hw_detach(struct ath5k_hw *ah)
-{
-       ATH5K_TRACE(ah->ah_sc);
-
-       __set_bit(ATH_STAT_INVALID, ah->ah_sc->status);
-
-       if (ah->ah_rf_banks != NULL)
-               kfree(ah->ah_rf_banks);
-
-       ath5k_eeprom_detach(ah);
-
-       /* assume interrupts are down */
-       kfree(ah);
-}
diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c
deleted file mode 100644 (file)
index 32df27a..0000000
+++ /dev/null
@@ -1,3073 +0,0 @@
-/*-
- * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
- * Copyright (c) 2004-2005 Atheros Communications, Inc.
- * Copyright (c) 2006 Devicescape Software, Inc.
- * Copyright (c) 2007 Jiri Slaby <jirislaby@gmail.com>
- * Copyright (c) 2007 Luis R. Rodriguez <mcgrof@winlab.rutgers.edu>
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer,
- *    without modification.
- * 2. Redistributions in binary form must reproduce at minimum a disclaimer
- *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
- *    redistribution must be conditioned upon including a substantially
- *    similar Disclaimer requirement for further binary redistribution.
- * 3. Neither the names of the above-listed copyright holders nor the names
- *    of any contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * Alternatively, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") version 2 as published by the Free
- * Software Foundation.
- *
- * NO WARRANTY
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGES.
- *
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/hardirq.h>
-#include <linux/if.h>
-#include <linux/io.h>
-#include <linux/netdevice.h>
-#include <linux/cache.h>
-#include <linux/pci.h>
-#include <linux/ethtool.h>
-#include <linux/uaccess.h>
-
-#include <net/ieee80211_radiotap.h>
-
-#include <asm/unaligned.h>
-
-#include "base.h"
-#include "reg.h"
-#include "debug.h"
-
-static int ath5k_calinterval = 10; /* Calibrate PHY every 10 secs (TODO: Fixme) */
-static int modparam_nohwcrypt;
-module_param_named(nohwcrypt, modparam_nohwcrypt, int, 0444);
-MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
-
-
-/******************\
-* Internal defines *
-\******************/
-
-/* Module info */
-MODULE_AUTHOR("Jiri Slaby");
-MODULE_AUTHOR("Nick Kossifidis");
-MODULE_DESCRIPTION("Support for 5xxx series of Atheros 802.11 wireless LAN cards.");
-MODULE_SUPPORTED_DEVICE("Atheros 5xxx WLAN cards");
-MODULE_LICENSE("Dual BSD/GPL");
-MODULE_VERSION("0.6.0 (EXPERIMENTAL)");
-
-
-/* Known PCI ids */
-static const struct pci_device_id ath5k_pci_id_table[] = {
-       { PCI_VDEVICE(ATHEROS, 0x0207), .driver_data = AR5K_AR5210 }, /* 5210 early */
-       { PCI_VDEVICE(ATHEROS, 0x0007), .driver_data = AR5K_AR5210 }, /* 5210 */
-       { PCI_VDEVICE(ATHEROS, 0x0011), .driver_data = AR5K_AR5211 }, /* 5311 - this is on AHB bus !*/
-       { PCI_VDEVICE(ATHEROS, 0x0012), .driver_data = AR5K_AR5211 }, /* 5211 */
-       { PCI_VDEVICE(ATHEROS, 0x0013), .driver_data = AR5K_AR5212 }, /* 5212 */
-       { PCI_VDEVICE(3COM_2,  0x0013), .driver_data = AR5K_AR5212 }, /* 3com 5212 */
-       { PCI_VDEVICE(3COM,    0x0013), .driver_data = AR5K_AR5212 }, /* 3com 3CRDAG675 5212 */
-       { PCI_VDEVICE(ATHEROS, 0x1014), .driver_data = AR5K_AR5212 }, /* IBM minipci 5212 */
-       { PCI_VDEVICE(ATHEROS, 0x0014), .driver_data = AR5K_AR5212 }, /* 5212 combatible */
-       { PCI_VDEVICE(ATHEROS, 0x0015), .driver_data = AR5K_AR5212 }, /* 5212 combatible */
-       { PCI_VDEVICE(ATHEROS, 0x0016), .driver_data = AR5K_AR5212 }, /* 5212 combatible */
-       { PCI_VDEVICE(ATHEROS, 0x0017), .driver_data = AR5K_AR5212 }, /* 5212 combatible */
-       { PCI_VDEVICE(ATHEROS, 0x0018), .driver_data = AR5K_AR5212 }, /* 5212 combatible */
-       { PCI_VDEVICE(ATHEROS, 0x0019), .driver_data = AR5K_AR5212 }, /* 5212 combatible */
-       { PCI_VDEVICE(ATHEROS, 0x001a), .driver_data = AR5K_AR5212 }, /* 2413 Griffin-lite */
-       { PCI_VDEVICE(ATHEROS, 0x001b), .driver_data = AR5K_AR5212 }, /* 5413 Eagle */
-       { PCI_VDEVICE(ATHEROS, 0x001c), .driver_data = AR5K_AR5212 }, /* PCI-E cards */
-       { PCI_VDEVICE(ATHEROS, 0x001d), .driver_data = AR5K_AR5212 }, /* 2417 Nala */
-       { 0 }
-};
-MODULE_DEVICE_TABLE(pci, ath5k_pci_id_table);
-
-/* Known SREVs */
-static const struct ath5k_srev_name srev_names[] = {
-       { "5210",       AR5K_VERSION_MAC,       AR5K_SREV_AR5210 },
-       { "5311",       AR5K_VERSION_MAC,       AR5K_SREV_AR5311 },
-       { "5311A",      AR5K_VERSION_MAC,       AR5K_SREV_AR5311A },
-       { "5311B",      AR5K_VERSION_MAC,       AR5K_SREV_AR5311B },
-       { "5211",       AR5K_VERSION_MAC,       AR5K_SREV_AR5211 },
-       { "5212",       AR5K_VERSION_MAC,       AR5K_SREV_AR5212 },
-       { "5213",       AR5K_VERSION_MAC,       AR5K_SREV_AR5213 },
-       { "5213A",      AR5K_VERSION_MAC,       AR5K_SREV_AR5213A },
-       { "2413",       AR5K_VERSION_MAC,       AR5K_SREV_AR2413 },
-       { "2414",       AR5K_VERSION_MAC,       AR5K_SREV_AR2414 },
-       { "5424",       AR5K_VERSION_MAC,       AR5K_SREV_AR5424 },
-       { "5413",       AR5K_VERSION_MAC,       AR5K_SREV_AR5413 },
-       { "5414",       AR5K_VERSION_MAC,       AR5K_SREV_AR5414 },
-       { "2415",       AR5K_VERSION_MAC,       AR5K_SREV_AR2415 },
-       { "5416",       AR5K_VERSION_MAC,       AR5K_SREV_AR5416 },
-       { "5418",       AR5K_VERSION_MAC,       AR5K_SREV_AR5418 },
-       { "2425",       AR5K_VERSION_MAC,       AR5K_SREV_AR2425 },
-       { "2417",       AR5K_VERSION_MAC,       AR5K_SREV_AR2417 },
-       { "xxxxx",      AR5K_VERSION_MAC,       AR5K_SREV_UNKNOWN },
-       { "5110",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_5110 },
-       { "5111",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_5111 },
-       { "5111A",      AR5K_VERSION_RAD,       AR5K_SREV_RAD_5111A },
-       { "2111",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_2111 },
-       { "5112",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_5112 },
-       { "5112A",      AR5K_VERSION_RAD,       AR5K_SREV_RAD_5112A },
-       { "5112B",      AR5K_VERSION_RAD,       AR5K_SREV_RAD_5112B },
-       { "2112",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_2112 },
-       { "2112A",      AR5K_VERSION_RAD,       AR5K_SREV_RAD_2112A },
-       { "2112B",      AR5K_VERSION_RAD,       AR5K_SREV_RAD_2112B },
-       { "2413",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_2413 },
-       { "5413",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_5413 },
-       { "2316",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_2316 },
-       { "2317",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_2317 },
-       { "5424",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_5424 },
-       { "5133",       AR5K_VERSION_RAD,       AR5K_SREV_RAD_5133 },
-       { "xxxxx",      AR5K_VERSION_RAD,       AR5K_SREV_UNKNOWN },
-};
-
-static const struct ieee80211_rate ath5k_rates[] = {
-       { .bitrate = 10,
-         .hw_value = ATH5K_RATE_CODE_1M, },
-       { .bitrate = 20,
-         .hw_value = ATH5K_RATE_CODE_2M,
-         .hw_value_short = ATH5K_RATE_CODE_2M | AR5K_SET_SHORT_PREAMBLE,
-         .flags = IEEE80211_RATE_SHORT_PREAMBLE },
-       { .bitrate = 55,
-         .hw_value = ATH5K_RATE_CODE_5_5M,
-         .hw_value_short = ATH5K_RATE_CODE_5_5M | AR5K_SET_SHORT_PREAMBLE,
-         .flags = IEEE80211_RATE_SHORT_PREAMBLE },
-       { .bitrate = 110,
-         .hw_value = ATH5K_RATE_CODE_11M,
-         .hw_value_short = ATH5K_RATE_CODE_11M | AR5K_SET_SHORT_PREAMBLE,
-         .flags = IEEE80211_RATE_SHORT_PREAMBLE },
-       { .bitrate = 60,
-         .hw_value = ATH5K_RATE_CODE_6M,
-         .flags = 0 },
-       { .bitrate = 90,
-         .hw_value = ATH5K_RATE_CODE_9M,
-         .flags = 0 },
-       { .bitrate = 120,
-         .hw_value = ATH5K_RATE_CODE_12M,
-         .flags = 0 },
-       { .bitrate = 180,
-         .hw_value = ATH5K_RATE_CODE_18M,
-         .flags = 0 },
-       { .bitrate = 240,
-         .hw_value = ATH5K_RATE_CODE_24M,
-         .flags = 0 },
-       { .bitrate = 360,
-         .hw_value = ATH5K_RATE_CODE_36M,
-         .flags = 0 },
-       { .bitrate = 480,
-         .hw_value = ATH5K_RATE_CODE_48M,
-         .flags = 0 },
-       { .bitrate = 540,
-         .hw_value = ATH5K_RATE_CODE_54M,
-         .flags = 0 },
-       /* XR missing */
-};
-
-/*
- * Prototypes - PCI stack related functions
- */
-static int __devinit   ath5k_pci_probe(struct pci_dev *pdev,
-                               const struct pci_device_id *id);
-static void __devexit  ath5k_pci_remove(struct pci_dev *pdev);
-#ifdef CONFIG_PM
-static int             ath5k_pci_suspend(struct pci_dev *pdev,
-                                       pm_message_t state);
-static int             ath5k_pci_resume(struct pci_dev *pdev);
-#else
-#define ath5k_pci_suspend NULL
-#define ath5k_pci_resume NULL
-#endif /* CONFIG_PM */
-
-static struct pci_driver ath5k_pci_driver = {
-       .name           = KBUILD_MODNAME,
-       .id_table       = ath5k_pci_id_table,
-       .probe          = ath5k_pci_probe,
-       .remove         = __devexit_p(ath5k_pci_remove),
-       .suspend        = ath5k_pci_suspend,
-       .resume         = ath5k_pci_resume,
-};
-
-
-
-/*
- * Prototypes - MAC 802.11 stack related functions
- */
-static int ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
-static int ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan);
-static int ath5k_reset_wake(struct ath5k_softc *sc);
-static int ath5k_start(struct ieee80211_hw *hw);
-static void ath5k_stop(struct ieee80211_hw *hw);
-static int ath5k_add_interface(struct ieee80211_hw *hw,
-               struct ieee80211_if_init_conf *conf);
-static void ath5k_remove_interface(struct ieee80211_hw *hw,
-               struct ieee80211_if_init_conf *conf);
-static int ath5k_config(struct ieee80211_hw *hw, u32 changed);
-static int ath5k_config_interface(struct ieee80211_hw *hw,
-               struct ieee80211_vif *vif,
-               struct ieee80211_if_conf *conf);
-static void ath5k_configure_filter(struct ieee80211_hw *hw,
-               unsigned int changed_flags,
-               unsigned int *new_flags,
-               int mc_count, struct dev_mc_list *mclist);
-static int ath5k_set_key(struct ieee80211_hw *hw,
-               enum set_key_cmd cmd,
-               struct ieee80211_vif *vif, struct ieee80211_sta *sta,
-               struct ieee80211_key_conf *key);
-static int ath5k_get_stats(struct ieee80211_hw *hw,
-               struct ieee80211_low_level_stats *stats);
-static int ath5k_get_tx_stats(struct ieee80211_hw *hw,
-               struct ieee80211_tx_queue_stats *stats);
-static u64 ath5k_get_tsf(struct ieee80211_hw *hw);
-static void ath5k_set_tsf(struct ieee80211_hw *hw, u64 tsf);
-static void ath5k_reset_tsf(struct ieee80211_hw *hw);
-static int ath5k_beacon_update(struct ath5k_softc *sc,
-               struct sk_buff *skb);
-static void ath5k_bss_info_changed(struct ieee80211_hw *hw,
-               struct ieee80211_vif *vif,
-               struct ieee80211_bss_conf *bss_conf,
-               u32 changes);
-
-static const struct ieee80211_ops ath5k_hw_ops = {
-       .tx             = ath5k_tx,
-       .start          = ath5k_start,
-       .stop           = ath5k_stop,
-       .add_interface  = ath5k_add_interface,
-       .remove_interface = ath5k_remove_interface,
-       .config         = ath5k_config,
-       .config_interface = ath5k_config_interface,
-       .configure_filter = ath5k_configure_filter,
-       .set_key        = ath5k_set_key,
-       .get_stats      = ath5k_get_stats,
-       .conf_tx        = NULL,
-       .get_tx_stats   = ath5k_get_tx_stats,
-       .get_tsf        = ath5k_get_tsf,
-       .set_tsf        = ath5k_set_tsf,
-       .reset_tsf      = ath5k_reset_tsf,
-       .bss_info_changed = ath5k_bss_info_changed,
-};
-
-/*
- * Prototypes - Internal functions
- */
-/* Attach detach */
-static int     ath5k_attach(struct pci_dev *pdev,
-                       struct ieee80211_hw *hw);
-static void    ath5k_detach(struct pci_dev *pdev,
-                       struct ieee80211_hw *hw);
-/* Channel/mode setup */
-static inline short ath5k_ieee2mhz(short chan);
-static unsigned int ath5k_copy_channels(struct ath5k_hw *ah,
-                               struct ieee80211_channel *channels,
-                               unsigned int mode,
-                               unsigned int max);
-static int     ath5k_setup_bands(struct ieee80211_hw *hw);
-static int     ath5k_chan_set(struct ath5k_softc *sc,
-                               struct ieee80211_channel *chan);
-static void    ath5k_setcurmode(struct ath5k_softc *sc,
-                               unsigned int mode);
-static void    ath5k_mode_setup(struct ath5k_softc *sc);
-
-/* Descriptor setup */
-static int     ath5k_desc_alloc(struct ath5k_softc *sc,
-                               struct pci_dev *pdev);
-static void    ath5k_desc_free(struct ath5k_softc *sc,
-                               struct pci_dev *pdev);
-/* Buffers setup */
-static int     ath5k_rxbuf_setup(struct ath5k_softc *sc,
-                               struct ath5k_buf *bf);
-static int     ath5k_txbuf_setup(struct ath5k_softc *sc,
-                               struct ath5k_buf *bf);
-static inline void ath5k_txbuf_free(struct ath5k_softc *sc,
-                               struct ath5k_buf *bf)
-{
-       BUG_ON(!bf);
-       if (!bf->skb)
-               return;
-       pci_unmap_single(sc->pdev, bf->skbaddr, bf->skb->len,
-                       PCI_DMA_TODEVICE);
-       dev_kfree_skb_any(bf->skb);
-       bf->skb = NULL;
-}
-
-static inline void ath5k_rxbuf_free(struct ath5k_softc *sc,
-                               struct ath5k_buf *bf)
-{
-       BUG_ON(!bf);
-       if (!bf->skb)
-               return;
-       pci_unmap_single(sc->pdev, bf->skbaddr, sc->rxbufsize,
-                       PCI_DMA_FROMDEVICE);
-       dev_kfree_skb_any(bf->skb);
-       bf->skb = NULL;
-}
-
-
-/* Queues setup */
-static struct  ath5k_txq *ath5k_txq_setup(struct ath5k_softc *sc,
-                               int qtype, int subtype);
-static int     ath5k_beaconq_setup(struct ath5k_hw *ah);
-static int     ath5k_beaconq_config(struct ath5k_softc *sc);
-static void    ath5k_txq_drainq(struct ath5k_softc *sc,
-                               struct ath5k_txq *txq);
-static void    ath5k_txq_cleanup(struct ath5k_softc *sc);
-static void    ath5k_txq_release(struct ath5k_softc *sc);
-/* Rx handling */
-static int     ath5k_rx_start(struct ath5k_softc *sc);
-static void    ath5k_rx_stop(struct ath5k_softc *sc);
-static unsigned int ath5k_rx_decrypted(struct ath5k_softc *sc,
-                                       struct ath5k_desc *ds,
-                                       struct sk_buff *skb,
-                                       struct ath5k_rx_status *rs);
-static void    ath5k_tasklet_rx(unsigned long data);
-/* Tx handling */
-static void    ath5k_tx_processq(struct ath5k_softc *sc,
-                               struct ath5k_txq *txq);
-static void    ath5k_tasklet_tx(unsigned long data);
-/* Beacon handling */
-static int     ath5k_beacon_setup(struct ath5k_softc *sc,
-                                       struct ath5k_buf *bf);
-static void    ath5k_beacon_send(struct ath5k_softc *sc);
-static void    ath5k_beacon_config(struct ath5k_softc *sc);
-static void    ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf);
-static void    ath5k_tasklet_beacon(unsigned long data);
-
-static inline u64 ath5k_extend_tsf(struct ath5k_hw *ah, u32 rstamp)
-{
-       u64 tsf = ath5k_hw_get_tsf64(ah);
-
-       if ((tsf & 0x7fff) < rstamp)
-               tsf -= 0x8000;
-
-       return (tsf & ~0x7fff) | rstamp;
-}
-
-/* Interrupt handling */
-static int     ath5k_init(struct ath5k_softc *sc);
-static int     ath5k_stop_locked(struct ath5k_softc *sc);
-static int     ath5k_stop_hw(struct ath5k_softc *sc);
-static irqreturn_t ath5k_intr(int irq, void *dev_id);
-static void    ath5k_tasklet_reset(unsigned long data);
-
-static void    ath5k_calibrate(unsigned long data);
-
-/*
- * Module init/exit functions
- */
-static int __init
-init_ath5k_pci(void)
-{
-       int ret;
-
-       ath5k_debug_init();
-
-       ret = pci_register_driver(&ath5k_pci_driver);
-       if (ret) {
-               printk(KERN_ERR "ath5k_pci: can't register pci driver\n");
-               return ret;
-       }
-
-       return 0;
-}
-
-static void __exit
-exit_ath5k_pci(void)
-{
-       pci_unregister_driver(&ath5k_pci_driver);
-
-       ath5k_debug_finish();
-}
-
-module_init(init_ath5k_pci);
-module_exit(exit_ath5k_pci);
-
-
-/********************\
-* PCI Initialization *
-\********************/
-
-static const char *
-ath5k_chip_name(enum ath5k_srev_type type, u_int16_t val)
-{
-       const char *name = "xxxxx";
-       unsigned int i;
-
-       for (i = 0; i < ARRAY_SIZE(srev_names); i++) {
-               if (srev_names[i].sr_type != type)
-                       continue;
-
-               if ((val & 0xf0) == srev_names[i].sr_val)
-                       name = srev_names[i].sr_name;
-
-               if ((val & 0xff) == srev_names[i].sr_val) {
-                       name = srev_names[i].sr_name;
-                       break;
-               }
-       }
-
-       return name;
-}
-
-static int __devinit
-ath5k_pci_probe(struct pci_dev *pdev,
-               const struct pci_device_id *id)
-{
-       void __iomem *mem;
-       struct ath5k_softc *sc;
-       struct ieee80211_hw *hw;
-       int ret;
-       u8 csz;
-
-       ret = pci_enable_device(pdev);
-       if (ret) {
-               dev_err(&pdev->dev, "can't enable device\n");
-               goto err;
-       }
-
-       /* XXX 32-bit addressing only */
-       ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
-       if (ret) {
-               dev_err(&pdev->dev, "32-bit DMA not available\n");
-               goto err_dis;
-       }
-
-       /*
-        * Cache line size is used to size and align various
-        * structures used to communicate with the hardware.
-        */
-       pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &csz);
-       if (csz == 0) {
-               /*
-                * Linux 2.4.18 (at least) writes the cache line size
-                * register as a 16-bit wide register which is wrong.
-                * We must have this setup properly for rx buffer
-                * DMA to work so force a reasonable value here if it
-                * comes up zero.
-                */
-               csz = L1_CACHE_BYTES / sizeof(u32);
-               pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz);
-       }
-       /*
-        * The default setting of latency timer yields poor results,
-        * set it to the value used by other systems.  It may be worth
-        * tweaking this setting more.
-        */
-       pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xa8);
-
-       /* Enable bus mastering */
-       pci_set_master(pdev);
-
-       /*
-        * Disable the RETRY_TIMEOUT register (0x41) to keep
-        * PCI Tx retries from interfering with C3 CPU state.
-        */
-       pci_write_config_byte(pdev, 0x41, 0);
-
-       ret = pci_request_region(pdev, 0, "ath5k");
-       if (ret) {
-               dev_err(&pdev->dev, "cannot reserve PCI memory region\n");
-               goto err_dis;
-       }
-
-       mem = pci_iomap(pdev, 0, 0);
-       if (!mem) {
-               dev_err(&pdev->dev, "cannot remap PCI memory region\n") ;
-               ret = -EIO;
-               goto err_reg;
-       }
-
-       /*
-        * Allocate hw (mac80211 main struct)
-        * and hw->priv (driver private data)
-        */
-       hw = ieee80211_alloc_hw(sizeof(*sc), &ath5k_hw_ops);
-       if (hw == NULL) {
-               dev_err(&pdev->dev, "cannot allocate ieee80211_hw\n");
-               ret = -ENOMEM;
-               goto err_map;
-       }
-
-       dev_info(&pdev->dev, "registered as '%s'\n", wiphy_name(hw->wiphy));
-
-       /* Initialize driver private data */
-       SET_IEEE80211_DEV(hw, &pdev->dev);
-       hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
-                   IEEE80211_HW_SIGNAL_DBM |
-                   IEEE80211_HW_NOISE_DBM;
-
-       hw->wiphy->interface_modes =
-               BIT(NL80211_IFTYPE_STATION) |
-               BIT(NL80211_IFTYPE_ADHOC) |
-               BIT(NL80211_IFTYPE_MESH_POINT);
-
-       hw->extra_tx_headroom = 2;
-       hw->channel_change_time = 5000;
-       sc = hw->priv;
-       sc->hw = hw;
-       sc->pdev = pdev;
-
-       ath5k_debug_init_device(sc);
-
-       /*
-        * Mark the device as detached to avoid processing
-        * interrupts until setup is complete.
-        */
-       __set_bit(ATH_STAT_INVALID, sc->status);
-
-       sc->iobase = mem; /* So we can unmap it on detach */
-       sc->cachelsz = csz * sizeof(u32); /* convert to bytes */
-       sc->opmode = NL80211_IFTYPE_STATION;
-       mutex_init(&sc->lock);
-       spin_lock_init(&sc->rxbuflock);
-       spin_lock_init(&sc->txbuflock);
-       spin_lock_init(&sc->block);
-
-       /* Set private data */
-       pci_set_drvdata(pdev, hw);
-
-       /* Setup interrupt handler */
-       ret = request_irq(pdev->irq, ath5k_intr, IRQF_SHARED, "ath", sc);
-       if (ret) {
-               ATH5K_ERR(sc, "request_irq failed\n");
-               goto err_free;
-       }
-
-       /* Initialize device */
-       sc->ah = ath5k_hw_attach(sc, id->driver_data);
-       if (IS_ERR(sc->ah)) {
-               ret = PTR_ERR(sc->ah);
-               goto err_irq;
-       }
-
-       /* set up multi-rate retry capabilities */
-       if (sc->ah->ah_version == AR5K_AR5212) {
-               hw->max_rates = 4;
-               hw->max_rate_tries = 11;
-       }
-
-       /* Finish private driver data initialization */
-       ret = ath5k_attach(pdev, hw);
-       if (ret)
-               goto err_ah;
-
-       ATH5K_INFO(sc, "Atheros AR%s chip found (MAC: 0x%x, PHY: 0x%x)\n",
-                       ath5k_chip_name(AR5K_VERSION_MAC, sc->ah->ah_mac_srev),
-                                       sc->ah->ah_mac_srev,
-                                       sc->ah->ah_phy_revision);
-
-       if (!sc->ah->ah_single_chip) {
-               /* Single chip radio (!RF5111) */
-               if (sc->ah->ah_radio_5ghz_revision &&
-                       !sc->ah->ah_radio_2ghz_revision) {
-                       /* No 5GHz support -> report 2GHz radio */
-                       if (!test_bit(AR5K_MODE_11A,
-                               sc->ah->ah_capabilities.cap_mode)) {
-                               ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n",
-                                       ath5k_chip_name(AR5K_VERSION_RAD,
-                                               sc->ah->ah_radio_5ghz_revision),
-                                               sc->ah->ah_radio_5ghz_revision);
-                       /* No 2GHz support (5110 and some
-                        * 5Ghz only cards) -> report 5Ghz radio */
-                       } else if (!test_bit(AR5K_MODE_11B,
-                               sc->ah->ah_capabilities.cap_mode)) {
-                               ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n",
-                                       ath5k_chip_name(AR5K_VERSION_RAD,
-                                               sc->ah->ah_radio_5ghz_revision),
-                                               sc->ah->ah_radio_5ghz_revision);
-                       /* Multiband radio */
-                       } else {
-                               ATH5K_INFO(sc, "RF%s multiband radio found"
-                                       " (0x%x)\n",
-                                       ath5k_chip_name(AR5K_VERSION_RAD,
-                                               sc->ah->ah_radio_5ghz_revision),
-                                               sc->ah->ah_radio_5ghz_revision);
-                       }
-               }
-               /* Multi chip radio (RF5111 - RF2111) ->
-                * report both 2GHz/5GHz radios */
-               else if (sc->ah->ah_radio_5ghz_revision &&
-                               sc->ah->ah_radio_2ghz_revision){
-                       ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n",
-                               ath5k_chip_name(AR5K_VERSION_RAD,
-                                       sc->ah->ah_radio_5ghz_revision),
-                                       sc->ah->ah_radio_5ghz_revision);
-                       ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n",
-                               ath5k_chip_name(AR5K_VERSION_RAD,
-                                       sc->ah->ah_radio_2ghz_revision),
-                                       sc->ah->ah_radio_2ghz_revision);
-               }
-       }
-
-
-       /* ready to process interrupts */
-       __clear_bit(ATH_STAT_INVALID, sc->status);
-
-       return 0;
-err_ah:
-       ath5k_hw_detach(sc->ah);
-err_irq:
-       free_irq(pdev->irq, sc);
-err_free:
-       ieee80211_free_hw(hw);
-err_map:
-       pci_iounmap(pdev, mem);
-err_reg:
-       pci_release_region(pdev, 0);
-err_dis:
-       pci_disable_device(pdev);
-err:
-       return ret;
-}
-
-static void __devexit
-ath5k_pci_remove(struct pci_dev *pdev)
-{
-       struct ieee80211_hw *hw = pci_get_drvdata(pdev);
-       struct ath5k_softc *sc = hw->priv;
-
-       ath5k_debug_finish_device(sc);
-       ath5k_detach(pdev, hw);
-       ath5k_hw_detach(sc->ah);
-       free_irq(pdev->irq, sc);
-       pci_iounmap(pdev, sc->iobase);
-       pci_release_region(pdev, 0);
-       pci_disable_device(pdev);
-       ieee80211_free_hw(hw);
-}
-
-#ifdef CONFIG_PM
-static int
-ath5k_pci_suspend(struct pci_dev *pdev, pm_message_t state)
-{
-       struct ieee80211_hw *hw = pci_get_drvdata(pdev);
-       struct ath5k_softc *sc = hw->priv;
-
-       ath5k_led_off(sc);
-
-       free_irq(pdev->irq, sc);
-       pci_save_state(pdev);
-       pci_disable_device(pdev);
-       pci_set_power_state(pdev, PCI_D3hot);
-
-       return 0;
-}
-
-static int
-ath5k_pci_resume(struct pci_dev *pdev)
-{
-       struct ieee80211_hw *hw = pci_get_drvdata(pdev);
-       struct ath5k_softc *sc = hw->priv;
-       int err;
-
-       pci_restore_state(pdev);
-
-       err = pci_enable_device(pdev);
-       if (err)
-               return err;
-
-       err = request_irq(pdev->irq, ath5k_intr, IRQF_SHARED, "ath", sc);
-       if (err) {
-               ATH5K_ERR(sc, "request_irq failed\n");
-               goto err_no_irq;
-       }
-
-       ath5k_led_enable(sc);
-       return 0;
-
-err_no_irq:
-       pci_disable_device(pdev);
-       return err;
-}
-#endif /* CONFIG_PM */
-
-
-/***********************\
-* Driver Initialization *
-\***********************/
-
-static int
-ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
-{
-       struct ath5k_softc *sc = hw->priv;
-       struct ath5k_hw *ah = sc->ah;
-       u8 mac[ETH_ALEN] = {};
-       int ret;
-
-       ATH5K_DBG(sc, ATH5K_DEBUG_ANY, "devid 0x%x\n", pdev->device);
-
-       /*
-        * Check if the MAC has multi-rate retry support.
-        * We do this by trying to setup a fake extended
-        * descriptor.  MAC's that don't have support will
-        * return false w/o doing anything.  MAC's that do
-        * support it will return true w/o doing anything.
-        */
-       ret = ah->ah_setup_mrr_tx_desc(ah, NULL, 0, 0, 0, 0, 0, 0);
-       if (ret < 0)
-               goto err;
-       if (ret > 0)
-               __set_bit(ATH_STAT_MRRETRY, sc->status);
-
-       /*
-        * Collect the channel list.  The 802.11 layer
-        * is resposible for filtering this list based
-        * on settings like the phy mode and regulatory
-        * domain restrictions.
-        */
-       ret = ath5k_setup_bands(hw);
-       if (ret) {
-               ATH5K_ERR(sc, "can't get channels\n");
-               goto err;
-       }
-
-       /* NB: setup here so ath5k_rate_update is happy */
-       if (test_bit(AR5K_MODE_11A, ah->ah_modes))
-               ath5k_setcurmode(sc, AR5K_MODE_11A);
-       else
-               ath5k_setcurmode(sc, AR5K_MODE_11B);
-
-       /*
-        * Allocate tx+rx descriptors and populate the lists.
-        */
-       ret = ath5k_desc_alloc(sc, pdev);
-       if (ret) {
-               ATH5K_ERR(sc, "can't allocate descriptors\n");
-               goto err;
-       }
-
-       /*
-        * Allocate hardware transmit queues: one queue for
-        * beacon frames and one data queue for each QoS
-        * priority.  Note that hw functions handle reseting
-        * these queues at the needed time.
-        */
-       ret = ath5k_beaconq_setup(ah);
-       if (ret < 0) {
-               ATH5K_ERR(sc, "can't setup a beacon xmit queue\n");
-               goto err_desc;
-       }
-       sc->bhalq = ret;
-
-       sc->txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_BK);
-       if (IS_ERR(sc->txq)) {
-               ATH5K_ERR(sc, "can't setup xmit queue\n");
-               ret = PTR_ERR(sc->txq);
-               goto err_bhal;
-       }
-
-       tasklet_init(&sc->rxtq, ath5k_tasklet_rx, (unsigned long)sc);
-       tasklet_init(&sc->txtq, ath5k_tasklet_tx, (unsigned long)sc);
-       tasklet_init(&sc->restq, ath5k_tasklet_reset, (unsigned long)sc);
-       tasklet_init(&sc->beacontq, ath5k_tasklet_beacon, (unsigned long)sc);
-       setup_timer(&sc->calib_tim, ath5k_calibrate, (unsigned long)sc);
-
-       ret = ath5k_eeprom_read_mac(ah, mac);
-       if (ret) {
-               ATH5K_ERR(sc, "unable to read address from EEPROM: 0x%04x\n",
-                       sc->pdev->device);
-               goto err_queues;
-       }
-
-       SET_IEEE80211_PERM_ADDR(hw, mac);
-       /* All MAC address bits matter for ACKs */
-       memset(sc->bssidmask, 0xff, ETH_ALEN);
-       ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask);
-
-       ret = ieee80211_register_hw(hw);
-       if (ret) {
-               ATH5K_ERR(sc, "can't register ieee80211 hw\n");
-               goto err_queues;
-       }
-
-       ath5k_init_leds(sc);
-
-       return 0;
-err_queues:
-       ath5k_txq_release(sc);
-err_bhal:
-       ath5k_hw_release_tx_queue(ah, sc->bhalq);
-err_desc:
-       ath5k_desc_free(sc, pdev);
-err:
-       return ret;
-}
-
-static void
-ath5k_detach(struct pci_dev *pdev, struct ieee80211_hw *hw)
-{
-       struct ath5k_softc *sc = hw->priv;
-
-       /*
-        * NB: the order of these is important:
-        * o call the 802.11 layer before detaching ath5k_hw to
-        *   insure callbacks into the driver to delete global
-        *   key cache entries can be handled
-        * o reclaim the tx queue data structures after calling
-        *   the 802.11 layer as we'll get called back to reclaim
-        *   node state and potentially want to use them
-        * o to cleanup the tx queues the hal is called, so detach
-        *   it last
-        * XXX: ??? detach ath5k_hw ???
-        * Other than that, it's straightforward...
-        */
-       ieee80211_unregister_hw(hw);
-       ath5k_desc_free(sc, pdev);
-       ath5k_txq_release(sc);
-       ath5k_hw_release_tx_queue(sc->ah, sc->bhalq);
-       ath5k_unregister_leds(sc);
-
-       /*
-        * NB: can't reclaim these until after ieee80211_ifdetach
-        * returns because we'll get called back to reclaim node
-        * state and potentially want to use them.
-        */
-}
-
-
-
-
-/********************\
-* Channel/mode setup *
-\********************/
-
-/*
- * Convert IEEE channel number to MHz frequency.
- */
-static inline short
-ath5k_ieee2mhz(short chan)
-{
-       if (chan <= 14 || chan >= 27)
-               return ieee80211chan2mhz(chan);
-       else
-               return 2212 + chan * 20;
-}
-
-static unsigned int
-ath5k_copy_channels(struct ath5k_hw *ah,
-               struct ieee80211_channel *channels,
-               unsigned int mode,
-               unsigned int max)
-{
-       unsigned int i, count, size, chfreq, freq, ch;
-
-       if (!test_bit(mode, ah->ah_modes))
-               return 0;
-
-       switch (mode) {
-       case AR5K_MODE_11A:
-       case AR5K_MODE_11A_TURBO:
-               /* 1..220, but 2GHz frequencies are filtered by check_channel */
-               size = 220 ;
-               chfreq = CHANNEL_5GHZ;
-               break;
-       case AR5K_MODE_11B:
-       case AR5K_MODE_11G:
-       case AR5K_MODE_11G_TURBO:
-               size = 26;
-               chfreq = CHANNEL_2GHZ;
-               break;
-       default:
-               ATH5K_WARN(ah->ah_sc, "bad mode, not copying channels\n");
-               return 0;
-       }
-
-       for (i = 0, count = 0; i < size && max > 0; i++) {
-               ch = i + 1 ;
-               freq = ath5k_ieee2mhz(ch);
-
-               /* Check if channel is supported by the chipset */
-               if (!ath5k_channel_ok(ah, freq, chfreq))
-                       continue;
-
-               /* Write channel info and increment counter */
-               channels[count].center_freq = freq;
-               channels[count].band = (chfreq == CHANNEL_2GHZ) ?
-                       IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
-               switch (mode) {
-               case AR5K_MODE_11A:
-               case AR5K_MODE_11G:
-                       channels[count].hw_value = chfreq | CHANNEL_OFDM;
-                       break;
-               case AR5K_MODE_11A_TURBO:
-               case AR5K_MODE_11G_TURBO:
-                       channels[count].hw_value = chfreq |
-                               CHANNEL_OFDM | CHANNEL_TURBO;
-                       break;
-               case AR5K_MODE_11B:
-                       channels[count].hw_value = CHANNEL_B;
-               }
-
-               count++;
-               max--;
-       }
-
-       return count;
-}
-
-static void
-ath5k_setup_rate_idx(struct ath5k_softc *sc, struct ieee80211_supported_band *b)
-{
-       u8 i;
-
-       for (i = 0; i < AR5K_MAX_RATES; i++)
-               sc->rate_idx[b->band][i] = -1;
-
-       for (i = 0; i < b->n_bitrates; i++) {
-               sc->rate_idx[b->band][b->bitrates[i].hw_value] = i;
-               if (b->bitrates[i].hw_value_short)
-                       sc->rate_idx[b->band][b->bitrates[i].hw_value_short] = i;
-       }
-}
-
-static int
-ath5k_setup_bands(struct ieee80211_hw *hw)
-{
-       struct ath5k_softc *sc = hw->priv;
-       struct ath5k_hw *ah = sc->ah;
-       struct ieee80211_supported_band *sband;
-       int max_c, count_c = 0;
-       int i;
-
-       BUILD_BUG_ON(ARRAY_SIZE(sc->sbands) < IEEE80211_NUM_BANDS);
-       max_c = ARRAY_SIZE(sc->channels);
-
-       /* 2GHz band */
-       sband = &sc->sbands[IEEE80211_BAND_2GHZ];
-       sband->band = IEEE80211_BAND_2GHZ;
-       sband->bitrates = &sc->rates[IEEE80211_BAND_2GHZ][0];
-
-       if (test_bit(AR5K_MODE_11G, sc->ah->ah_capabilities.cap_mode)) {
-               /* G mode */
-               memcpy(sband->bitrates, &ath5k_rates[0],
-                      sizeof(struct ieee80211_rate) * 12);
-               sband->n_bitrates = 12;
-
-               sband->channels = sc->channels;
-               sband->n_channels = ath5k_copy_channels(ah, sband->channels,
-                                       AR5K_MODE_11G, max_c);
-
-               hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband;
-               count_c = sband->n_channels;
-               max_c -= count_c;
-       } else if (test_bit(AR5K_MODE_11B, sc->ah->ah_capabilities.cap_mode)) {
-               /* B mode */
-               memcpy(sband->bitrates, &ath5k_rates[0],
-                      sizeof(struct ieee80211_rate) * 4);
-               sband->n_bitrates = 4;
-
-               /* 5211 only supports B rates and uses 4bit rate codes
-                * (e.g normally we have 0x1B for 1M, but on 5211 we have 0x0B)
-                * fix them up here:
-                */
-               if (ah->ah_version == AR5K_AR5211) {
-                       for (i = 0; i < 4; i++) {
-                               sband->bitrates[i].hw_value =
-                                       sband->bitrates[i].hw_value & 0xF;
-                               sband->bitrates[i].hw_value_short =
-                                       sband->bitrates[i].hw_value_short & 0xF;
-                       }
-               }
-
-               sband->channels = sc->channels;
-               sband->n_channels = ath5k_copy_channels(ah, sband->channels,
-                                       AR5K_MODE_11B, max_c);
-
-               hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband;
-               count_c = sband->n_channels;
-               max_c -= count_c;
-       }
-       ath5k_setup_rate_idx(sc, sband);
-
-       /* 5GHz band, A mode */
-       if (test_bit(AR5K_MODE_11A, sc->ah->ah_capabilities.cap_mode)) {
-               sband = &sc->sbands[IEEE80211_BAND_5GHZ];
-               sband->band = IEEE80211_BAND_5GHZ;
-               sband->bitrates = &sc->rates[IEEE80211_BAND_5GHZ][0];
-
-               memcpy(sband->bitrates, &ath5k_rates[4],
-                      sizeof(struct ieee80211_rate) * 8);
-               sband->n_bitrates = 8;
-
-               sband->channels = &sc->channels[count_c];
-               sband->n_channels = ath5k_copy_channels(ah, sband->channels,
-                                       AR5K_MODE_11A, max_c);
-
-               hw->wiphy->bands[IEEE80211_BAND_5GHZ] = sband;
-       }
-       ath5k_setup_rate_idx(sc, sband);
-
-       ath5k_debug_dump_bands(sc);
-
-       return 0;
-}
-
-/*
- * Set/change channels.  If the channel is really being changed,
- * it's done by reseting the chip.  To accomplish this we must
- * first cleanup any pending DMA, then restart stuff after a la
- * ath5k_init.
- *
- * Called with sc->lock.
- */
-static int
-ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan)
-{
-       ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "(%u MHz) -> (%u MHz)\n",
-               sc->curchan->center_freq, chan->center_freq);
-
-       if (chan->center_freq != sc->curchan->center_freq ||
-               chan->hw_value != sc->curchan->hw_value) {
-
-               /*
-                * To switch channels clear any pending DMA operations;
-                * wait long enough for the RX fifo to drain, reset the
-                * hardware at the new frequency, and then re-enable
-                * the relevant bits of the h/w.
-                */
-               return ath5k_reset(sc, chan);
-       }
-
-       return 0;
-}
-
-static void
-ath5k_setcurmode(struct ath5k_softc *sc, unsigned int mode)
-{
-       sc->curmode = mode;
-
-       if (mode == AR5K_MODE_11A) {
-               sc->curband = &sc->sbands[IEEE80211_BAND_5GHZ];
-       } else {
-               sc->curband = &sc->sbands[IEEE80211_BAND_2GHZ];
-       }
-}
-
-static void
-ath5k_mode_setup(struct ath5k_softc *sc)
-{
-       struct ath5k_hw *ah = sc->ah;
-       u32 rfilt;
-
-       /* configure rx filter */
-       rfilt = sc->filter_flags;
-       ath5k_hw_set_rx_filter(ah, rfilt);
-
-       if (ath5k_hw_hasbssidmask(ah))
-               ath5k_hw_set_bssid_mask(ah, sc->bssidmask);
-
-       /* configure operational mode */
-       ath5k_hw_set_opmode(ah);
-
-       ath5k_hw_set_mcast_filter(ah, 0, 0);
-       ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "RX filter 0x%x\n", rfilt);
-}
-
-static inline int
-ath5k_hw_to_driver_rix(struct ath5k_softc *sc, int hw_rix)
-{
-       int rix;
-
-       /* return base rate on errors */
-       if (WARN(hw_rix < 0 || hw_rix >= AR5K_MAX_RATES,
-                       "hw_rix out of bounds: %x\n", hw_rix))
-               return 0;
-
-       rix = sc->rate_idx[sc->curband->band][hw_rix];
-       if (WARN(rix < 0, "invalid hw_rix: %x\n", hw_rix))
-               rix = 0;
-
-       return rix;
-}
-
-/***************\
-* Buffers setup *
-\***************/
-
-static
-struct sk_buff *ath5k_rx_skb_alloc(struct ath5k_softc *sc, dma_addr_t *skb_addr)
-{
-       struct sk_buff *skb;
-       unsigned int off;
-
-       /*
-        * Allocate buffer with headroom_needed space for the
-        * fake physical layer header at the start.
-        */
-       skb = dev_alloc_skb(sc->rxbufsize + sc->cachelsz - 1);
-
-       if (!skb) {
-               ATH5K_ERR(sc, "can't alloc skbuff of size %u\n",
-                               sc->rxbufsize + sc->cachelsz - 1);
-               return NULL;
-       }
-       /*
-        * Cache-line-align.  This is important (for the
-        * 5210 at least) as not doing so causes bogus data
-        * in rx'd frames.
-        */
-       off = ((unsigned long)skb->data) % sc->cachelsz;
-       if (off != 0)
-               skb_reserve(skb, sc->cachelsz - off);
-
-       *skb_addr = pci_map_single(sc->pdev,
-               skb->data, sc->rxbufsize, PCI_DMA_FROMDEVICE);
-       if (unlikely(pci_dma_mapping_error(sc->pdev, *skb_addr))) {
-               ATH5K_ERR(sc, "%s: DMA mapping failed\n", __func__);
-               dev_kfree_skb(skb);
-               return NULL;
-       }
-       return skb;
-}
-
-static int
-ath5k_rxbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
-{
-       struct ath5k_hw *ah = sc->ah;
-       struct sk_buff *skb = bf->skb;
-       struct ath5k_desc *ds;
-
-       if (!skb) {
-               skb = ath5k_rx_skb_alloc(sc, &bf->skbaddr);
-               if (!skb)
-                       return -ENOMEM;
-               bf->skb = skb;
-       }
-
-       /*
-        * Setup descriptors.  For receive we always terminate
-        * the descriptor list with a self-linked entry so we'll
-        * not get overrun under high load (as can happen with a
-        * 5212 when ANI processing enables PHY error frames).
-        *
-        * To insure the last descriptor is self-linked we create
-        * each descriptor as self-linked and add it to the end.  As
-        * each additional descriptor is added the previous self-linked
-        * entry is ``fixed'' naturally.  This should be safe even
-        * if DMA is happening.  When processing RX interrupts we
-        * never remove/process the last, self-linked, entry on the
-        * descriptor list.  This insures the hardware always has
-        * someplace to write a new frame.
-        */
-       ds = bf->desc;
-       ds->ds_link = bf->daddr;        /* link to self */
-       ds->ds_data = bf->skbaddr;
-       ah->ah_setup_rx_desc(ah, ds,
-               skb_tailroom(skb),      /* buffer size */
-               0);
-
-       if (sc->rxlink != NULL)
-               *sc->rxlink = bf->daddr;
-       sc->rxlink = &ds->ds_link;
-       return 0;
-}
-
-static int
-ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
-{
-       struct ath5k_hw *ah = sc->ah;
-       struct ath5k_txq *txq = sc->txq;
-       struct ath5k_desc *ds = bf->desc;
-       struct sk_buff *skb = bf->skb;
-       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-       unsigned int pktlen, flags, keyidx = AR5K_TXKEYIX_INVALID;
-       struct ieee80211_rate *rate;
-       unsigned int mrr_rate[3], mrr_tries[3];
-       int i, ret;
-       u16 hw_rate;
-       u16 cts_rate = 0;
-       u16 duration = 0;
-       u8 rc_flags;
-
-       flags = AR5K_TXDESC_INTREQ | AR5K_TXDESC_CLRDMASK;
-
-       /* XXX endianness */
-       bf->skbaddr = pci_map_single(sc->pdev, skb->data, skb->len,
-                       PCI_DMA_TODEVICE);
-
-       rate = ieee80211_get_tx_rate(sc->hw, info);
-
-       if (info->flags & IEEE80211_TX_CTL_NO_ACK)
-               flags |= AR5K_TXDESC_NOACK;
-
-       rc_flags = info->control.rates[0].flags;
-       hw_rate = (rc_flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) ?
-               rate->hw_value_short : rate->hw_value;
-
-       pktlen = skb->len;
-
-       /* FIXME: If we are in g mode and rate is a CCK rate
-        * subtract ah->ah_txpower.txp_cck_ofdm_pwr_delta
-        * from tx power (value is in dB units already) */
-       if (info->control.hw_key) {
-               keyidx = info->control.hw_key->hw_key_idx;
-               pktlen += info->control.hw_key->icv_len;
-       }
-       if (rc_flags & IEEE80211_TX_RC_USE_RTS_CTS) {
-               flags |= AR5K_TXDESC_RTSENA;
-               cts_rate = ieee80211_get_rts_cts_rate(sc->hw, info)->hw_value;
-               duration = le16_to_cpu(ieee80211_rts_duration(sc->hw,
-                       sc->vif, pktlen, info));
-       }
-       if (rc_flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
-               flags |= AR5K_TXDESC_CTSENA;
-               cts_rate = ieee80211_get_rts_cts_rate(sc->hw, info)->hw_value;
-               duration = le16_to_cpu(ieee80211_ctstoself_duration(sc->hw,
-                       sc->vif, pktlen, info));
-       }
-       ret = ah->ah_setup_tx_desc(ah, ds, pktlen,
-               ieee80211_get_hdrlen_from_skb(skb), AR5K_PKT_TYPE_NORMAL,
-               (sc->power_level * 2),
-               hw_rate,
-               info->control.rates[0].count, keyidx, 0, flags,
-               cts_rate, duration);
-       if (ret)
-               goto err_unmap;
-
-       memset(mrr_rate, 0, sizeof(mrr_rate));
-       memset(mrr_tries, 0, sizeof(mrr_tries));
-       for (i = 0; i < 3; i++) {
-               rate = ieee80211_get_alt_retry_rate(sc->hw, info, i);
-               if (!rate)
-                       break;
-
-               mrr_rate[i] = rate->hw_value;
-               mrr_tries[i] = info->control.rates[i + 1].count;
-       }
-
-       ah->ah_setup_mrr_tx_desc(ah, ds,
-               mrr_rate[0], mrr_tries[0],
-               mrr_rate[1], mrr_tries[1],
-               mrr_rate[2], mrr_tries[2]);
-
-       ds->ds_link = 0;
-       ds->ds_data = bf->skbaddr;
-
-       spin_lock_bh(&txq->lock);
-       list_add_tail(&bf->list, &txq->q);
-       sc->tx_stats[txq->qnum].len++;
-       if (txq->link == NULL) /* is this first packet? */
-               ath5k_hw_set_txdp(ah, txq->qnum, bf->daddr);
-       else /* no, so only link it */
-               *txq->link = bf->daddr;
-
-       txq->link = &ds->ds_link;
-       ath5k_hw_start_tx_dma(ah, txq->qnum);
-       mmiowb();
-       spin_unlock_bh(&txq->lock);
-
-       return 0;
-err_unmap:
-       pci_unmap_single(sc->pdev, bf->skbaddr, skb->len, PCI_DMA_TODEVICE);
-       return ret;
-}
-
-/*******************\
-* Descriptors setup *
-\*******************/
-
-static int
-ath5k_desc_alloc(struct ath5k_softc *sc, struct pci_dev *pdev)
-{
-       struct ath5k_desc *ds;
-       struct ath5k_buf *bf;
-       dma_addr_t da;
-       unsigned int i;
-       int ret;
-
-       /* allocate descriptors */
-       sc->desc_len = sizeof(struct ath5k_desc) *
-                       (ATH_TXBUF + ATH_RXBUF + ATH_BCBUF + 1);
-       sc->desc = pci_alloc_consistent(pdev, sc->desc_len, &sc->desc_daddr);
-       if (sc->desc == NULL) {
-               ATH5K_ERR(sc, "can't allocate descriptors\n");
-               ret = -ENOMEM;
-               goto err;
-       }
-       ds = sc->desc;
-       da = sc->desc_daddr;
-       ATH5K_DBG(sc, ATH5K_DEBUG_ANY, "DMA map: %p (%zu) -> %llx\n",
-               ds, sc->desc_len, (unsigned long long)sc->desc_daddr);
-
-       bf = kcalloc(1 + ATH_TXBUF + ATH_RXBUF + ATH_BCBUF,
-                       sizeof(struct ath5k_buf), GFP_KERNEL);
-       if (bf == NULL) {
-               ATH5K_ERR(sc, "can't allocate bufptr\n");
-               ret = -ENOMEM;
-               goto err_free;
-       }
-       sc->bufptr = bf;
-
-       INIT_LIST_HEAD(&sc->rxbuf);
-       for (i = 0; i < ATH_RXBUF; i++, bf++, ds++, da += sizeof(*ds)) {
-               bf->desc = ds;
-               bf->daddr = da;
-               list_add_tail(&bf->list, &sc->rxbuf);
-       }
-
-       INIT_LIST_HEAD(&sc->txbuf);
-       sc->txbuf_len = ATH_TXBUF;
-       for (i = 0; i < ATH_TXBUF; i++, bf++, ds++,
-                       da += sizeof(*ds)) {
-               bf->desc = ds;
-               bf->daddr = da;
-               list_add_tail(&bf->list, &sc->txbuf);
-       }
-
-       /* beacon buffer */
-       bf->desc = ds;
-       bf->daddr = da;
-       sc->bbuf = bf;
-
-       return 0;
-err_free:
-       pci_free_consistent(pdev, sc->desc_len, sc->desc, sc->desc_daddr);
-err:
-       sc->desc = NULL;
-       return ret;
-}
-
-static void
-ath5k_desc_free(struct ath5k_softc *sc, struct pci_dev *pdev)
-{
-       struct ath5k_buf *bf;
-
-       ath5k_txbuf_free(sc, sc->bbuf);
-       list_for_each_entry(bf, &sc->txbuf, list)
-               ath5k_txbuf_free(sc, bf);
-       list_for_each_entry(bf, &sc->rxbuf, list)
-               ath5k_rxbuf_free(sc, bf);
-
-       /* Free memory associated with all descriptors */
-       pci_free_consistent(pdev, sc->desc_len, sc->desc, sc->desc_daddr);
-
-       kfree(sc->bufptr);
-       sc->bufptr = NULL;
-}
-
-
-
-
-
-/**************\
-* Queues setup *
-\**************/
-
-static struct ath5k_txq *
-ath5k_txq_setup(struct ath5k_softc *sc,
-               int qtype, int subtype)
-{
-       struct ath5k_hw *ah = sc->ah;
-       struct ath5k_txq *txq;
-       struct ath5k_txq_info qi = {
-               .tqi_subtype = subtype,
-               .tqi_aifs = AR5K_TXQ_USEDEFAULT,
-               .tqi_cw_min = AR5K_TXQ_USEDEFAULT,
-               .tqi_cw_max = AR5K_TXQ_USEDEFAULT
-       };
-       int qnum;
-
-       /*
-        * Enable interrupts only for EOL and DESC conditions.
-        * We mark tx descriptors to receive a DESC interrupt
-        * when a tx queue gets deep; otherwise waiting for the
-        * EOL to reap descriptors.  Note that this is done to
-        * reduce interrupt load and this only defers reaping
-        * descriptors, never transmitting frames.  Aside from
-        * reducing interrupts this also permits more concurrency.
-        * The only potential downside is if the tx queue backs
-        * up in which case the top half of the kernel may backup
-        * due to a lack of tx descriptors.
-        */
-       qi.tqi_flags = AR5K_TXQ_FLAG_TXEOLINT_ENABLE |
-                               AR5K_TXQ_FLAG_TXDESCINT_ENABLE;
-       qnum = ath5k_hw_setup_tx_queue(ah, qtype, &qi);
-       if (qnum < 0) {
-               /*
-                * NB: don't print a message, this happens
-                * normally on parts with too few tx queues
-                */
-               return ERR_PTR(qnum);
-       }
-       if (qnum >= ARRAY_SIZE(sc->txqs)) {
-               ATH5K_ERR(sc, "hw qnum %u out of range, max %tu!\n",
-                       qnum, ARRAY_SIZE(sc->txqs));
-               ath5k_hw_release_tx_queue(ah, qnum);
-               return ERR_PTR(-EINVAL);
-       }
-       txq = &sc->txqs[qnum];
-       if (!txq->setup) {
-               txq->qnum = qnum;
-               txq->link = NULL;
-               INIT_LIST_HEAD(&txq->q);
-               spin_lock_init(&txq->lock);
-               txq->setup = true;
-       }
-       return &sc->txqs[qnum];
-}
-
-static int
-ath5k_beaconq_setup(struct ath5k_hw *ah)
-{
-       struct ath5k_txq_info qi = {
-               .tqi_aifs = AR5K_TXQ_USEDEFAULT,
-               .tqi_cw_min = AR5K_TXQ_USEDEFAULT,
-               .tqi_cw_max = AR5K_TXQ_USEDEFAULT,
-               /* NB: for dynamic turbo, don't enable any other interrupts */
-               .tqi_flags = AR5K_TXQ_FLAG_TXDESCINT_ENABLE
-       };
-
-       return ath5k_hw_setup_tx_queue(ah, AR5K_TX_QUEUE_BEACON, &qi);
-}
-
-static int
-ath5k_beaconq_config(struct ath5k_softc *sc)
-{
-       struct ath5k_hw *ah = sc->ah;
-       struct ath5k_txq_info qi;
-       int ret;
-
-       ret = ath5k_hw_get_tx_queueprops(ah, sc->bhalq, &qi);
-       if (ret)
-               return ret;
-       if (sc->opmode == NL80211_IFTYPE_AP ||
-               sc->opmode == NL80211_IFTYPE_MESH_POINT) {
-               /*
-                * Always burst out beacon and CAB traffic
-                * (aifs = cwmin = cwmax = 0)
-                */
-               qi.tqi_aifs = 0;
-               qi.tqi_cw_min = 0;
-               qi.tqi_cw_max = 0;
-       } else if (sc->opmode == NL80211_IFTYPE_ADHOC) {
-               /*
-                * Adhoc mode; backoff between 0 and (2 * cw_min).
-                */
-               qi.tqi_aifs = 0;
-               qi.tqi_cw_min = 0;
-               qi.tqi_cw_max = 2 * ah->ah_cw_min;
-       }
-
-       ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
-               "beacon queueprops tqi_aifs:%d tqi_cw_min:%d tqi_cw_max:%d\n",
-               qi.tqi_aifs, qi.tqi_cw_min, qi.tqi_cw_max);
-
-       ret = ath5k_hw_set_tx_queueprops(ah, sc->bhalq, &qi);
-       if (ret) {
-               ATH5K_ERR(sc, "%s: unable to update parameters for beacon "
-                       "hardware queue!\n", __func__);
-               return ret;
-       }
-
-       return ath5k_hw_reset_tx_queue(ah, sc->bhalq); /* push to h/w */;
-}
-
-static void
-ath5k_txq_drainq(struct ath5k_softc *sc, struct ath5k_txq *txq)
-{
-       struct ath5k_buf *bf, *bf0;
-
-       /*
-        * NB: this assumes output has been stopped and
-        *     we do not need to block ath5k_tx_tasklet
-        */
-       spin_lock_bh(&txq->lock);
-       list_for_each_entry_safe(bf, bf0, &txq->q, list) {
-               ath5k_debug_printtxbuf(sc, bf);
-
-               ath5k_txbuf_free(sc, bf);
-
-               spin_lock_bh(&sc->txbuflock);
-               sc->tx_stats[txq->qnum].len--;
-               list_move_tail(&bf->list, &sc->txbuf);
-               sc->txbuf_len++;
-               spin_unlock_bh(&sc->txbuflock);
-       }
-       txq->link = NULL;
-       spin_unlock_bh(&txq->lock);
-}
-
-/*
- * Drain the transmit queues and reclaim resources.
- */
-static void
-ath5k_txq_cleanup(struct ath5k_softc *sc)
-{
-       struct ath5k_hw *ah = sc->ah;
-       unsigned int i;
-
-       /* XXX return value */
-       if (likely(!test_bit(ATH_STAT_INVALID, sc->status))) {
-               /* don't touch the hardware if marked invalid */
-               ath5k_hw_stop_tx_dma(ah, sc->bhalq);
-               ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "beacon queue %x\n",
-                       ath5k_hw_get_txdp(ah, sc->bhalq));
-               for (i = 0; i < ARRAY_SIZE(sc->txqs); i++)
-                       if (sc->txqs[i].setup) {
-                               ath5k_hw_stop_tx_dma(ah, sc->txqs[i].qnum);
-                               ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "txq [%u] %x, "
-                                       "link %p\n",
-                                       sc->txqs[i].qnum,
-                                       ath5k_hw_get_txdp(ah,
-                                                       sc->txqs[i].qnum),
-                                       sc->txqs[i].link);
-                       }
-       }
-       ieee80211_wake_queues(sc->hw); /* XXX move to callers */
-
-       for (i = 0; i < ARRAY_SIZE(sc->txqs); i++)
-               if (sc->txqs[i].setup)
-                       ath5k_txq_drainq(sc, &sc->txqs[i]);
-}
-
-static void
-ath5k_txq_release(struct ath5k_softc *sc)
-{
-       struct ath5k_txq *txq = sc->txqs;
-       unsigned int i;
-
-       for (i = 0; i < ARRAY_SIZE(sc->txqs); i++, txq++)
-               if (txq->setup) {
-                       ath5k_hw_release_tx_queue(sc->ah, txq->qnum);
-                       txq->setup = false;
-               }
-}
-
-
-
-
-/*************\
-* RX Handling *
-\*************/
-
-/*
- * Enable the receive h/w following a reset.
- */
-static int
-ath5k_rx_start(struct ath5k_softc *sc)
-{
-       struct ath5k_hw *ah = sc->ah;
-       struct ath5k_buf *bf;
-       int ret;
-
-       sc->rxbufsize = roundup(IEEE80211_MAX_LEN, sc->cachelsz);
-
-       ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "cachelsz %u rxbufsize %u\n",
-               sc->cachelsz, sc->rxbufsize);
-
-       sc->rxlink = NULL;
-
-       spin_lock_bh(&sc->rxbuflock);
-       list_for_each_entry(bf, &sc->rxbuf, list) {
-               ret = ath5k_rxbuf_setup(sc, bf);
-               if (ret != 0) {
-                       spin_unlock_bh(&sc->rxbuflock);
-                       goto err;
-               }
-       }
-       bf = list_first_entry(&sc->rxbuf, struct ath5k_buf, list);
-       spin_unlock_bh(&sc->rxbuflock);
-
-       ath5k_hw_set_rxdp(ah, bf->daddr);
-       ath5k_hw_start_rx_dma(ah);      /* enable recv descriptors */
-       ath5k_mode_setup(sc);           /* set filters, etc. */
-       ath5k_hw_start_rx_pcu(ah);      /* re-enable PCU/DMA engine */
-
-       return 0;
-err:
-       return ret;
-}
-
-/*
- * Disable the receive h/w in preparation for a reset.
- */
-static void
-ath5k_rx_stop(struct ath5k_softc *sc)
-{
-       struct ath5k_hw *ah = sc->ah;
-
-       ath5k_hw_stop_rx_pcu(ah);       /* disable PCU */
-       ath5k_hw_set_rx_filter(ah, 0);  /* clear recv filter */
-       ath5k_hw_stop_rx_dma(ah);       /* disable DMA engine */
-
-       ath5k_debug_printrxbuffs(sc, ah);
-
-       sc->rxlink = NULL;              /* just in case */
-}
-
-static unsigned int
-ath5k_rx_decrypted(struct ath5k_softc *sc, struct ath5k_desc *ds,
-               struct sk_buff *skb, struct ath5k_rx_status *rs)
-{
-       struct ieee80211_hdr *hdr = (void *)skb->data;
-       unsigned int keyix, hlen;
-
-       if (!(rs->rs_status & AR5K_RXERR_DECRYPT) &&
-                       rs->rs_keyix != AR5K_RXKEYIX_INVALID)
-               return RX_FLAG_DECRYPTED;
-
-       /* Apparently when a default key is used to decrypt the packet
-          the hw does not set the index used to decrypt.  In such cases
-          get the index from the packet. */
-       hlen = ieee80211_hdrlen(hdr->frame_control);
-       if (ieee80211_has_protected(hdr->frame_control) &&
-           !(rs->rs_status & AR5K_RXERR_DECRYPT) &&
-           skb->len >= hlen + 4) {
-               keyix = skb->data[hlen + 3] >> 6;
-
-               if (test_bit(keyix, sc->keymap))
-                       return RX_FLAG_DECRYPTED;
-       }
-
-       return 0;
-}
-
-
-static void
-ath5k_check_ibss_tsf(struct ath5k_softc *sc, struct sk_buff *skb,
-                    struct ieee80211_rx_status *rxs)
-{
-       u64 tsf, bc_tstamp;
-       u32 hw_tu;
-       struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
-
-       if (ieee80211_is_beacon(mgmt->frame_control) &&
-           le16_to_cpu(mgmt->u.beacon.capab_info) & WLAN_CAPABILITY_IBSS &&
-           memcmp(mgmt->bssid, sc->ah->ah_bssid, ETH_ALEN) == 0) {
-               /*
-                * Received an IBSS beacon with the same BSSID. Hardware *must*
-                * have updated the local TSF. We have to work around various
-                * hardware bugs, though...
-                */
-               tsf = ath5k_hw_get_tsf64(sc->ah);
-               bc_tstamp = le64_to_cpu(mgmt->u.beacon.timestamp);
-               hw_tu = TSF_TO_TU(tsf);
-
-               ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON,
-                       "beacon %llx mactime %llx (diff %lld) tsf now %llx\n",
-                       (unsigned long long)bc_tstamp,
-                       (unsigned long long)rxs->mactime,
-                       (unsigned long long)(rxs->mactime - bc_tstamp),
-                       (unsigned long long)tsf);
-
-               /*
-                * Sometimes the HW will give us a wrong tstamp in the rx
-                * status, causing the timestamp extension to go wrong.
-                * (This seems to happen especially with beacon frames bigger
-                * than 78 byte (incl. FCS))
-                * But we know that the receive timestamp must be later than the
-                * timestamp of the beacon since HW must have synced to that.
-                *
-                * NOTE: here we assume mactime to be after the frame was
-                * received, not like mac80211 which defines it at the start.
-                */
-               if (bc_tstamp > rxs->mactime) {
-                       ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON,
-                               "fixing mactime from %llx to %llx\n",
-                               (unsigned long long)rxs->mactime,
-                               (unsigned long long)tsf);
-                       rxs->mactime = tsf;
-               }
-
-               /*
-                * Local TSF might have moved higher than our beacon timers,
-                * in that case we have to update them to continue sending
-                * beacons. This also takes care of synchronizing beacon sending
-                * times with other stations.
-                */
-               if (hw_tu >= sc->nexttbtt)
-                       ath5k_beacon_update_timers(sc, bc_tstamp);
-       }
-}
-
-static void ath5k_tasklet_beacon(unsigned long data)
-{
-       struct ath5k_softc *sc = (struct ath5k_softc *) data;
-
-       /*
-        * Software beacon alert--time to send a beacon.
-        *
-        * In IBSS mode we use this interrupt just to
-        * keep track of the next TBTT (target beacon
-        * transmission time) in order to detect wether
-        * automatic TSF updates happened.
-        */
-       if (sc->opmode == NL80211_IFTYPE_ADHOC) {
-               /* XXX: only if VEOL suppported */
-               u64 tsf = ath5k_hw_get_tsf64(sc->ah);
-               sc->nexttbtt += sc->bintval;
-               ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
-                               "SWBA nexttbtt: %x hw_tu: %x "
-                               "TSF: %llx\n",
-                               sc->nexttbtt,
-                               TSF_TO_TU(tsf),
-                               (unsigned long long) tsf);
-       } else {
-               spin_lock(&sc->block);
-               ath5k_beacon_send(sc);
-               spin_unlock(&sc->block);
-       }
-}
-
-static void
-ath5k_tasklet_rx(unsigned long data)
-{
-       struct ieee80211_rx_status rxs = {};
-       struct ath5k_rx_status rs = {};
-       struct sk_buff *skb, *next_skb;
-       dma_addr_t next_skb_addr;
-       struct ath5k_softc *sc = (void *)data;
-       struct ath5k_buf *bf, *bf_last;
-       struct ath5k_desc *ds;
-       int ret;
-       int hdrlen;
-       int padsize;
-
-       spin_lock(&sc->rxbuflock);
-       if (list_empty(&sc->rxbuf)) {
-               ATH5K_WARN(sc, "empty rx buf pool\n");
-               goto unlock;
-       }
-       bf_last = list_entry(sc->rxbuf.prev, struct ath5k_buf, list);
-       do {
-               rxs.flag = 0;
-
-               bf = list_first_entry(&sc->rxbuf, struct ath5k_buf, list);
-               BUG_ON(bf->skb == NULL);
-               skb = bf->skb;
-               ds = bf->desc;
-
-               /*
-                * last buffer must not be freed to ensure proper hardware
-                * function. When the hardware finishes also a packet next to
-                * it, we are sure, it doesn't use it anymore and we can go on.
-                */
-               if (bf_last == bf)
-                       bf->flags |= 1;
-               if (bf->flags) {
-                       struct ath5k_buf *bf_next = list_entry(bf->list.next,
-                                       struct ath5k_buf, list);
-                       ret = sc->ah->ah_proc_rx_desc(sc->ah, bf_next->desc,
-                                       &rs);
-                       if (ret)
-                               break;
-                       bf->flags &= ~1;
-                       /* skip the overwritten one (even status is martian) */
-                       goto next;
-               }
-
-               ret = sc->ah->ah_proc_rx_desc(sc->ah, ds, &rs);
-               if (unlikely(ret == -EINPROGRESS))
-                       break;
-               else if (unlikely(ret)) {
-                       ATH5K_ERR(sc, "error in processing rx descriptor\n");
-                       spin_unlock(&sc->rxbuflock);
-                       return;
-               }
-
-               if (unlikely(rs.rs_more)) {
-                       ATH5K_WARN(sc, "unsupported jumbo\n");
-                       goto next;
-               }
-
-               if (unlikely(rs.rs_status)) {
-                       if (rs.rs_status & AR5K_RXERR_PHY)
-                               goto next;
-                       if (rs.rs_status & AR5K_RXERR_DECRYPT) {
-                               /*
-                                * Decrypt error.  If the error occurred
-                                * because there was no hardware key, then
-                                * let the frame through so the upper layers
-                                * can process it.  This is necessary for 5210
-                                * parts which have no way to setup a ``clear''
-                                * key cache entry.
-                                *
-                                * XXX do key cache faulting
-                                */
-                               if (rs.rs_keyix == AR5K_RXKEYIX_INVALID &&
-                                   !(rs.rs_status & AR5K_RXERR_CRC))
-                                       goto accept;
-                       }
-                       if (rs.rs_status & AR5K_RXERR_MIC) {
-                               rxs.flag |= RX_FLAG_MMIC_ERROR;
-                               goto accept;
-                       }
-
-                       /* let crypto-error packets fall through in MNTR */
-                       if ((rs.rs_status &
-                               ~(AR5K_RXERR_DECRYPT|AR5K_RXERR_MIC)) ||
-                                       sc->opmode != NL80211_IFTYPE_MONITOR)
-                               goto next;
-               }
-accept:
-               next_skb = ath5k_rx_skb_alloc(sc, &next_skb_addr);
-
-               /*
-                * If we can't replace bf->skb with a new skb under memory
-                * pressure, just skip this packet
-                */
-               if (!next_skb)
-                       goto next;
-
-               pci_unmap_single(sc->pdev, bf->skbaddr, sc->rxbufsize,
-                               PCI_DMA_FROMDEVICE);
-               skb_put(skb, rs.rs_datalen);
-
-               /* The MAC header is padded to have 32-bit boundary if the
-                * packet payload is non-zero. The general calculation for
-                * padsize would take into account odd header lengths:
-                * padsize = (4 - hdrlen % 4) % 4; However, since only
-                * even-length headers are used, padding can only be 0 or 2
-                * bytes and we can optimize this a bit. In addition, we must
-                * not try to remove padding from short control frames that do
-                * not have payload. */
-               hdrlen = ieee80211_get_hdrlen_from_skb(skb);
-               padsize = ath5k_pad_size(hdrlen);
-               if (padsize) {
-                       memmove(skb->data + padsize, skb->data, hdrlen);
-                       skb_pull(skb, padsize);
-               }
-
-               /*
-                * always extend the mac timestamp, since this information is
-                * also needed for proper IBSS merging.
-                *
-                * XXX: it might be too late to do it here, since rs_tstamp is
-                * 15bit only. that means TSF extension has to be done within
-                * 32768usec (about 32ms). it might be necessary to move this to
-                * the interrupt handler, like it is done in madwifi.
-                *
-                * Unfortunately we don't know when the hardware takes the rx
-                * timestamp (beginning of phy frame, data frame, end of rx?).
-                * The only thing we know is that it is hardware specific...
-                * On AR5213 it seems the rx timestamp is at the end of the
-                * frame, but i'm not sure.
-                *
-                * NOTE: mac80211 defines mactime at the beginning of the first
-                * data symbol. Since we don't have any time references it's
-                * impossible to comply to that. This affects IBSS merge only
-                * right now, so it's not too bad...
-                */
-               rxs.mactime = ath5k_extend_tsf(sc->ah, rs.rs_tstamp);
-               rxs.flag |= RX_FLAG_TSFT;
-
-               rxs.freq = sc->curchan->center_freq;
-               rxs.band = sc->curband->band;
-
-               rxs.noise = sc->ah->ah_noise_floor;
-               rxs.signal = rxs.noise + rs.rs_rssi;
-
-               /* An rssi of 35 indicates you should be able use
-                * 54 Mbps reliably. A more elaborate scheme can be used
-                * here but it requires a map of SNR/throughput for each
-                * possible mode used */
-               rxs.qual = rs.rs_rssi * 100 / 35;
-
-               /* rssi can be more than 35 though, anything above that
-                * should be considered at 100% */
-               if (rxs.qual > 100)
-                       rxs.qual = 100;
-
-               rxs.antenna = rs.rs_antenna;
-               rxs.rate_idx = ath5k_hw_to_driver_rix(sc, rs.rs_rate);
-               rxs.flag |= ath5k_rx_decrypted(sc, ds, skb, &rs);
-
-               if (rxs.rate_idx >= 0 && rs.rs_rate ==
-                   sc->curband->bitrates[rxs.rate_idx].hw_value_short)
-                       rxs.flag |= RX_FLAG_SHORTPRE;
-
-               ath5k_debug_dump_skb(sc, skb, "RX  ", 0);
-
-               /* check beacons in IBSS mode */
-               if (sc->opmode == NL80211_IFTYPE_ADHOC)
-                       ath5k_check_ibss_tsf(sc, skb, &rxs);
-
-               __ieee80211_rx(sc->hw, skb, &rxs);
-
-               bf->skb = next_skb;
-               bf->skbaddr = next_skb_addr;
-next:
-               list_move_tail(&bf->list, &sc->rxbuf);
-       } while (ath5k_rxbuf_setup(sc, bf) == 0);
-unlock:
-       spin_unlock(&sc->rxbuflock);
-}
-
-
-
-
-/*************\
-* TX Handling *
-\*************/
-
-static void
-ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq)
-{
-       struct ath5k_tx_status ts = {};
-       struct ath5k_buf *bf, *bf0;
-       struct ath5k_desc *ds;
-       struct sk_buff *skb;
-       struct ieee80211_tx_info *info;
-       int i, ret;
-
-       spin_lock(&txq->lock);
-       list_for_each_entry_safe(bf, bf0, &txq->q, list) {
-               ds = bf->desc;
-
-               ret = sc->ah->ah_proc_tx_desc(sc->ah, ds, &ts);
-               if (unlikely(ret == -EINPROGRESS))
-                       break;
-               else if (unlikely(ret)) {
-                       ATH5K_ERR(sc, "error %d while processing queue %u\n",
-                               ret, txq->qnum);
-                       break;
-               }
-
-               skb = bf->skb;
-               info = IEEE80211_SKB_CB(skb);
-               bf->skb = NULL;
-
-               pci_unmap_single(sc->pdev, bf->skbaddr, skb->len,
-                               PCI_DMA_TODEVICE);
-
-               ieee80211_tx_info_clear_status(info);
-               for (i = 0; i < 4; i++) {
-                       struct ieee80211_tx_rate *r =
-                               &info->status.rates[i];
-
-                       if (ts.ts_rate[i]) {
-                               r->idx = ath5k_hw_to_driver_rix(sc, ts.ts_rate[i]);
-                               r->count = ts.ts_retry[i];
-                       } else {
-                               r->idx = -1;
-                               r->count = 0;
-                       }
-               }
-
-               /* count the successful attempt as well */
-               info->status.rates[ts.ts_final_idx].count++;
-
-               if (unlikely(ts.ts_status)) {
-                       sc->ll_stats.dot11ACKFailureCount++;
-                       if (ts.ts_status & AR5K_TXERR_FILT)
-                               info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
-               } else {
-                       info->flags |= IEEE80211_TX_STAT_ACK;
-                       info->status.ack_signal = ts.ts_rssi;
-               }
-
-               ieee80211_tx_status(sc->hw, skb);
-               sc->tx_stats[txq->qnum].count++;
-
-               spin_lock(&sc->txbuflock);
-               sc->tx_stats[txq->qnum].len--;
-               list_move_tail(&bf->list, &sc->txbuf);
-               sc->txbuf_len++;
-               spin_unlock(&sc->txbuflock);
-       }
-       if (likely(list_empty(&txq->q)))
-               txq->link = NULL;
-       spin_unlock(&txq->lock);
-       if (sc->txbuf_len > ATH_TXBUF / 5)
-               ieee80211_wake_queues(sc->hw);
-}
-
-static void
-ath5k_tasklet_tx(unsigned long data)
-{
-       struct ath5k_softc *sc = (void *)data;
-
-       ath5k_tx_processq(sc, sc->txq);
-}
-
-
-/*****************\
-* Beacon handling *
-\*****************/
-
-/*
- * Setup the beacon frame for transmit.
- */
-static int
-ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
-{
-       struct sk_buff *skb = bf->skb;
-       struct  ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-       struct ath5k_hw *ah = sc->ah;
-       struct ath5k_desc *ds;
-       int ret, antenna = 0;
-       u32 flags;
-
-       bf->skbaddr = pci_map_single(sc->pdev, skb->data, skb->len,
-                       PCI_DMA_TODEVICE);
-       ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, "skb %p [data %p len %u] "
-                       "skbaddr %llx\n", skb, skb->data, skb->len,
-                       (unsigned long long)bf->skbaddr);
-       if (pci_dma_mapping_error(sc->pdev, bf->skbaddr)) {
-               ATH5K_ERR(sc, "beacon DMA mapping failed\n");
-               return -EIO;
-       }
-
-       ds = bf->desc;
-
-       flags = AR5K_TXDESC_NOACK;
-       if (sc->opmode == NL80211_IFTYPE_ADHOC && ath5k_hw_hasveol(ah)) {
-               ds->ds_link = bf->daddr;        /* self-linked */
-               flags |= AR5K_TXDESC_VEOL;
-               /*
-                * Let hardware handle antenna switching if txantenna is not set
-                */
-       } else {
-               ds->ds_link = 0;
-               /*
-                * Switch antenna every 4 beacons if txantenna is not set
-                * XXX assumes two antennas
-                */
-               if (antenna == 0)
-                       antenna = sc->bsent & 4 ? 2 : 1;
-       }
-
-       /* FIXME: If we are in g mode and rate is a CCK rate
-        * subtract ah->ah_txpower.txp_cck_ofdm_pwr_delta
-        * from tx power (value is in dB units already) */
-       ds->ds_data = bf->skbaddr;
-       ret = ah->ah_setup_tx_desc(ah, ds, skb->len,
-                       ieee80211_get_hdrlen_from_skb(skb),
-                       AR5K_PKT_TYPE_BEACON, (sc->power_level * 2),
-                       ieee80211_get_tx_rate(sc->hw, info)->hw_value,
-                       1, AR5K_TXKEYIX_INVALID,
-                       antenna, flags, 0, 0);
-       if (ret)
-               goto err_unmap;
-
-       return 0;
-err_unmap:
-       pci_unmap_single(sc->pdev, bf->skbaddr, skb->len, PCI_DMA_TODEVICE);
-       return ret;
-}
-
-/*
- * Transmit a beacon frame at SWBA.  Dynamic updates to the
- * frame contents are done as needed and the slot time is
- * also adjusted based on current state.
- *
- * This is called from software irq context (beacontq or restq
- * tasklets) or user context from ath5k_beacon_config.
- */
-static void
-ath5k_beacon_send(struct ath5k_softc *sc)
-{
-       struct ath5k_buf *bf = sc->bbuf;
-       struct ath5k_hw *ah = sc->ah;
-
-       ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON, "in beacon_send\n");
-
-       if (unlikely(bf->skb == NULL || sc->opmode == NL80211_IFTYPE_STATION ||
-                       sc->opmode == NL80211_IFTYPE_MONITOR)) {
-               ATH5K_WARN(sc, "bf=%p bf_skb=%p\n", bf, bf ? bf->skb : NULL);
-               return;
-       }
-       /*
-        * Check if the previous beacon has gone out.  If
-        * not don't don't try to post another, skip this
-        * period and wait for the next.  Missed beacons
-        * indicate a problem and should not occur.  If we
-        * miss too many consecutive beacons reset the device.
-        */
-       if (unlikely(ath5k_hw_num_tx_pending(ah, sc->bhalq) != 0)) {
-               sc->bmisscount++;
-               ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
-                       "missed %u consecutive beacons\n", sc->bmisscount);
-               if (sc->bmisscount > 3) {               /* NB: 3 is a guess */
-                       ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
-                               "stuck beacon time (%u missed)\n",
-                               sc->bmisscount);
-                       tasklet_schedule(&sc->restq);
-               }
-               return;
-       }
-       if (unlikely(sc->bmisscount != 0)) {
-               ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
-                       "resume beacon xmit after %u misses\n",
-                       sc->bmisscount);
-               sc->bmisscount = 0;
-       }
-
-       /*
-        * Stop any current dma and put the new frame on the queue.
-        * This should never fail since we check above that no frames
-        * are still pending on the queue.
-        */
-       if (unlikely(ath5k_hw_stop_tx_dma(ah, sc->bhalq))) {
-               ATH5K_WARN(sc, "beacon queue %u didn't stop?\n", sc->bhalq);
-               /* NB: hw still stops DMA, so proceed */
-       }
-
-       ath5k_hw_set_txdp(ah, sc->bhalq, bf->daddr);
-       ath5k_hw_start_tx_dma(ah, sc->bhalq);
-       ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, "TXDP[%u] = %llx (%p)\n",
-               sc->bhalq, (unsigned long long)bf->daddr, bf->desc);
-
-       sc->bsent++;
-}
-
-
-/**
- * ath5k_beacon_update_timers - update beacon timers
- *
- * @sc: struct ath5k_softc pointer we are operating on
- * @bc_tsf: the timestamp of the beacon. 0 to reset the TSF. -1 to perform a
- *          beacon timer update based on the current HW TSF.
- *
- * Calculate the next target beacon transmit time (TBTT) based on the timestamp
- * of a received beacon or the current local hardware TSF and write it to the
- * beacon timer registers.
- *
- * This is called in a variety of situations, e.g. when a beacon is received,
- * when a TSF update has been detected, but also when an new IBSS is created or
- * when we otherwise know we have to update the timers, but we keep it in this
- * function to have it all together in one place.
- */
-static void
-ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf)
-{
-       struct ath5k_hw *ah = sc->ah;
-       u32 nexttbtt, intval, hw_tu, bc_tu;
-       u64 hw_tsf;
-
-       intval = sc->bintval & AR5K_BEACON_PERIOD;
-       if (WARN_ON(!intval))
-               return;
-
-       /* beacon TSF converted to TU */
-       bc_tu = TSF_TO_TU(bc_tsf);
-
-       /* current TSF converted to TU */
-       hw_tsf = ath5k_hw_get_tsf64(ah);
-       hw_tu = TSF_TO_TU(hw_tsf);
-
-#define FUDGE 3
-       /* we use FUDGE to make sure the next TBTT is ahead of the current TU */
-       if (bc_tsf == -1) {
-               /*
-                * no beacons received, called internally.
-                * just need to refresh timers based on HW TSF.
-                */
-               nexttbtt = roundup(hw_tu + FUDGE, intval);
-       } else if (bc_tsf == 0) {
-               /*
-                * no beacon received, probably called by ath5k_reset_tsf().
-                * reset TSF to start with 0.
-                */
-               nexttbtt = intval;
-               intval |= AR5K_BEACON_RESET_TSF;
-       } else if (bc_tsf > hw_tsf) {
-               /*
-                * beacon received, SW merge happend but HW TSF not yet updated.
-                * not possible to reconfigure timers yet, but next time we
-                * receive a beacon with the same BSSID, the hardware will
-                * automatically update the TSF and then we need to reconfigure
-                * the timers.
-                */
-               ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON,
-                       "need to wait for HW TSF sync\n");
-               return;
-       } else {
-               /*
-                * most important case for beacon synchronization between STA.
-                *
-                * beacon received and HW TSF has been already updated by HW.
-                * update next TBTT based on the TSF of the beacon, but make
-                * sure it is ahead of our local TSF timer.
-                */
-               nexttbtt = bc_tu + roundup(hw_tu + FUDGE - bc_tu, intval);
-       }
-#undef FUDGE
-
-       sc->nexttbtt = nexttbtt;
-
-       intval |= AR5K_BEACON_ENA;
-       ath5k_hw_init_beacon(ah, nexttbtt, intval);
-
-       /*
-        * debugging output last in order to preserve the time critical aspect
-        * of this function
-        */
-       if (bc_tsf == -1)
-               ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON,
-                       "reconfigured timers based on HW TSF\n");
-       else if (bc_tsf == 0)
-               ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON,
-                       "reset HW TSF and timers\n");
-       else
-               ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON,
-                       "updated timers based on beacon TSF\n");
-
-       ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON,
-                         "bc_tsf %llx hw_tsf %llx bc_tu %u hw_tu %u nexttbtt %u\n",
-                         (unsigned long long) bc_tsf,
-                         (unsigned long long) hw_tsf, bc_tu, hw_tu, nexttbtt);
-       ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON, "intval %u %s %s\n",
-               intval & AR5K_BEACON_PERIOD,
-               intval & AR5K_BEACON_ENA ? "AR5K_BEACON_ENA" : "",
-               intval & AR5K_BEACON_RESET_TSF ? "AR5K_BEACON_RESET_TSF" : "");
-}
-
-
-/**
- * ath5k_beacon_config - Configure the beacon queues and interrupts
- *
- * @sc: struct ath5k_softc pointer we are operating on
- *
- * In IBSS mode we use a self-linked tx descriptor if possible. We enable SWBA
- * interrupts to detect TSF updates only.
- */
-static void
-ath5k_beacon_config(struct ath5k_softc *sc)
-{
-       struct ath5k_hw *ah = sc->ah;
-       unsigned long flags;
-
-       ath5k_hw_set_imr(ah, 0);
-       sc->bmisscount = 0;
-       sc->imask &= ~(AR5K_INT_BMISS | AR5K_INT_SWBA);
-
-       if (sc->opmode == NL80211_IFTYPE_ADHOC ||
-                       sc->opmode == NL80211_IFTYPE_MESH_POINT ||
-                       sc->opmode == NL80211_IFTYPE_AP) {
-               /*
-                * In IBSS mode we use a self-linked tx descriptor and let the
-                * hardware send the beacons automatically. We have to load it
-                * only once here.
-                * We use the SWBA interrupt only to keep track of the beacon
-                * timers in order to detect automatic TSF updates.
-                */
-               ath5k_beaconq_config(sc);
-
-               sc->imask |= AR5K_INT_SWBA;
-
-               if (sc->opmode == NL80211_IFTYPE_ADHOC) {
-                       if (ath5k_hw_hasveol(ah)) {
-                               spin_lock_irqsave(&sc->block, flags);
-                               ath5k_beacon_send(sc);
-                               spin_unlock_irqrestore(&sc->block, flags);
-                       }
-               } else
-                       ath5k_beacon_update_timers(sc, -1);
-       }
-
-       ath5k_hw_set_imr(ah, sc->imask);
-}
-
-
-/********************\
-* Interrupt handling *
-\********************/
-
-static int
-ath5k_init(struct ath5k_softc *sc)
-{
-       struct ath5k_hw *ah = sc->ah;
-       int ret, i;
-
-       mutex_lock(&sc->lock);
-
-       ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "mode %d\n", sc->opmode);
-
-       /*
-        * Stop anything previously setup.  This is safe
-        * no matter this is the first time through or not.
-        */
-       ath5k_stop_locked(sc);
-
-       /*
-        * The basic interface to setting the hardware in a good
-        * state is ``reset''.  On return the hardware is known to
-        * be powered up and with interrupts disabled.  This must
-        * be followed by initialization of the appropriate bits
-        * and then setup of the interrupt mask.
-        */
-       sc->curchan = sc->hw->conf.channel;
-       sc->curband = &sc->sbands[sc->curchan->band];
-       sc->imask = AR5K_INT_RXOK | AR5K_INT_RXERR | AR5K_INT_RXEOL |
-               AR5K_INT_RXORN | AR5K_INT_TXDESC | AR5K_INT_TXEOL |
-               AR5K_INT_FATAL | AR5K_INT_GLOBAL;
-       ret = ath5k_reset(sc, NULL);
-       if (ret)
-               goto done;
-
-       /*
-        * Reset the key cache since some parts do not reset the
-        * contents on initial power up or resume from suspend.
-        */
-       for (i = 0; i < AR5K_KEYTABLE_SIZE; i++)
-               ath5k_hw_reset_key(ah, i);
-
-       /* Set ack to be sent at low bit-rates */
-       ath5k_hw_set_ack_bitrate_high(ah, false);
-
-       mod_timer(&sc->calib_tim, round_jiffies(jiffies +
-                       msecs_to_jiffies(ath5k_calinterval * 1000)));
-
-       ret = 0;
-done:
-       mmiowb();
-       mutex_unlock(&sc->lock);
-       return ret;
-}
-
-static int
-ath5k_stop_locked(struct ath5k_softc *sc)
-{
-       struct ath5k_hw *ah = sc->ah;
-
-       ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "invalid %u\n",
-                       test_bit(ATH_STAT_INVALID, sc->status));
-
-       /*
-        * Shutdown the hardware and driver:
-        *    stop output from above
-        *    disable interrupts
-        *    turn off timers
-        *    turn off the radio
-        *    clear transmit machinery
-        *    clear receive machinery
-        *    drain and release tx queues
-        *    reclaim beacon resources
-        *    power down hardware
-        *
-        * Note that some of this work is not possible if the
-        * hardware is gone (invalid).
-        */
-       ieee80211_stop_queues(sc->hw);
-
-       if (!test_bit(ATH_STAT_INVALID, sc->status)) {
-               ath5k_led_off(sc);
-               ath5k_hw_set_imr(ah, 0);
-               synchronize_irq(sc->pdev->irq);
-       }
-       ath5k_txq_cleanup(sc);
-       if (!test_bit(ATH_STAT_INVALID, sc->status)) {
-               ath5k_rx_stop(sc);
-               ath5k_hw_phy_disable(ah);
-       } else
-               sc->rxlink = NULL;
-
-       return 0;
-}
-
-/*
- * Stop the device, grabbing the top-level lock to protect
- * against concurrent entry through ath5k_init (which can happen
- * if another thread does a system call and the thread doing the
- * stop is preempted).
- */
-static int
-ath5k_stop_hw(struct ath5k_softc *sc)
-{
-       int ret;
-
-       mutex_lock(&sc->lock);
-       ret = ath5k_stop_locked(sc);
-       if (ret == 0 && !test_bit(ATH_STAT_INVALID, sc->status)) {
-               /*
-                * Set the chip in full sleep mode.  Note that we are
-                * careful to do this only when bringing the interface
-                * completely to a stop.  When the chip is in this state
-                * it must be carefully woken up or references to
-                * registers in the PCI clock domain may freeze the bus
-                * (and system).  This varies by chip and is mostly an
-                * issue with newer parts that go to sleep more quickly.
-                */
-               if (sc->ah->ah_mac_srev >= 0x78) {
-                       /*
-                        * XXX
-                        * don't put newer MAC revisions > 7.8 to sleep because
-                        * of the above mentioned problems
-                        */
-                       ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "mac version > 7.8, "
-                               "not putting device to sleep\n");
-               } else {
-                       ATH5K_DBG(sc, ATH5K_DEBUG_RESET,
-                               "putting device to full sleep\n");
-                       ath5k_hw_set_power(sc->ah, AR5K_PM_FULL_SLEEP, true, 0);
-               }
-       }
-       ath5k_txbuf_free(sc, sc->bbuf);
-
-       mmiowb();
-       mutex_unlock(&sc->lock);
-
-       del_timer_sync(&sc->calib_tim);
-       tasklet_kill(&sc->rxtq);
-       tasklet_kill(&sc->txtq);
-       tasklet_kill(&sc->restq);
-       tasklet_kill(&sc->beacontq);
-
-       return ret;
-}
-
-static irqreturn_t
-ath5k_intr(int irq, void *dev_id)
-{
-       struct ath5k_softc *sc = dev_id;
-       struct ath5k_hw *ah = sc->ah;
-       enum ath5k_int status;
-       unsigned int counter = 1000;
-
-       if (unlikely(test_bit(ATH_STAT_INVALID, sc->status) ||
-                               !ath5k_hw_is_intr_pending(ah)))
-               return IRQ_NONE;
-
-       do {
-               ath5k_hw_get_isr(ah, &status);          /* NB: clears IRQ too */
-               ATH5K_DBG(sc, ATH5K_DEBUG_INTR, "status 0x%x/0x%x\n",
-                               status, sc->imask);
-               if (unlikely(status & AR5K_INT_FATAL)) {
-                       /*
-                        * Fatal errors are unrecoverable.
-                        * Typically these are caused by DMA errors.
-                        */
-                       tasklet_schedule(&sc->restq);
-               } else if (unlikely(status & AR5K_INT_RXORN)) {
-                       tasklet_schedule(&sc->restq);
-               } else {
-                       if (status & AR5K_INT_SWBA) {
-                               tasklet_schedule(&sc->beacontq);
-                       }
-                       if (status & AR5K_INT_RXEOL) {
-                               /*
-                               * NB: the hardware should re-read the link when
-                               *     RXE bit is written, but it doesn't work at
-                               *     least on older hardware revs.
-                               */
-                               sc->rxlink = NULL;
-                       }
-                       if (status & AR5K_INT_TXURN) {
-                               /* bump tx trigger level */
-                               ath5k_hw_update_tx_triglevel(ah, true);
-                       }
-                       if (status & (AR5K_INT_RXOK | AR5K_INT_RXERR))
-                               tasklet_schedule(&sc->rxtq);
-                       if (status & (AR5K_INT_TXOK | AR5K_INT_TXDESC
-                                       | AR5K_INT_TXERR | AR5K_INT_TXEOL))
-                               tasklet_schedule(&sc->txtq);
-                       if (status & AR5K_INT_BMISS) {
-                               /* TODO */
-                       }
-                       if (status & AR5K_INT_MIB) {
-                               /*
-                                * These stats are also used for ANI i think
-                                * so how about updating them more often ?
-                                */
-                               ath5k_hw_update_mib_counters(ah, &sc->ll_stats);
-                       }
-               }
-       } while (ath5k_hw_is_intr_pending(ah) && counter-- > 0);
-
-       if (unlikely(!counter))
-               ATH5K_WARN(sc, "too many interrupts, giving up for now\n");
-
-       return IRQ_HANDLED;
-}
-
-static void
-ath5k_tasklet_reset(unsigned long data)
-{
-       struct ath5k_softc *sc = (void *)data;
-
-       ath5k_reset_wake(sc);
-}
-
-/*
- * Periodically recalibrate the PHY to account
- * for temperature/environment changes.
- */
-static void
-ath5k_calibrate(unsigned long data)
-{
-       struct ath5k_softc *sc = (void *)data;
-       struct ath5k_hw *ah = sc->ah;
-
-       ATH5K_DBG(sc, ATH5K_DEBUG_CALIBRATE, "channel %u/%x\n",
-               ieee80211_frequency_to_channel(sc->curchan->center_freq),
-               sc->curchan->hw_value);
-
-       if (ath5k_hw_gainf_calibrate(ah) == AR5K_RFGAIN_NEED_CHANGE) {
-               /*
-                * Rfgain is out of bounds, reset the chip
-                * to load new gain values.
-                */
-               ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "calibration, resetting\n");
-               ath5k_reset_wake(sc);
-       }
-       if (ath5k_hw_phy_calibrate(ah, sc->curchan))
-               ATH5K_ERR(sc, "calibration of channel %u failed\n",
-                       ieee80211_frequency_to_channel(
-                               sc->curchan->center_freq));
-
-       mod_timer(&sc->calib_tim, round_jiffies(jiffies +
-                       msecs_to_jiffies(ath5k_calinterval * 1000)));
-}
-
-
-/********************\
-* Mac80211 functions *
-\********************/
-
-static int
-ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
-{
-       struct ath5k_softc *sc = hw->priv;
-       struct ath5k_buf *bf;
-       unsigned long flags;
-       int hdrlen;
-       int padsize;
-
-       ath5k_debug_dump_skb(sc, skb, "TX  ", 1);
-
-       if (sc->opmode == NL80211_IFTYPE_MONITOR)
-               ATH5K_DBG(sc, ATH5K_DEBUG_XMIT, "tx in monitor (scan?)\n");
-
-       /*
-        * the hardware expects the header padded to 4 byte boundaries
-        * if this is not the case we add the padding after the header
-        */
-       hdrlen = ieee80211_get_hdrlen_from_skb(skb);
-       padsize = ath5k_pad_size(hdrlen);
-       if (padsize) {
-
-               if (skb_headroom(skb) < padsize) {
-                       ATH5K_ERR(sc, "tx hdrlen not %%4: %d not enough"
-                                 " headroom to pad %d\n", hdrlen, padsize);
-                       goto drop_packet;
-               }
-               skb_push(skb, padsize);
-               memmove(skb->data, skb->data+padsize, hdrlen);
-       }
-
-       spin_lock_irqsave(&sc->txbuflock, flags);
-       if (list_empty(&sc->txbuf)) {
-               ATH5K_ERR(sc, "no further txbuf available, dropping packet\n");
-               spin_unlock_irqrestore(&sc->txbuflock, flags);
-               ieee80211_stop_queue(hw, skb_get_queue_mapping(skb));
-               goto drop_packet;
-       }
-       bf = list_first_entry(&sc->txbuf, struct ath5k_buf, list);
-       list_del(&bf->list);
-       sc->txbuf_len--;
-       if (list_empty(&sc->txbuf))
-               ieee80211_stop_queues(hw);
-       spin_unlock_irqrestore(&sc->txbuflock, flags);
-
-       bf->skb = skb;
-
-       if (ath5k_txbuf_setup(sc, bf)) {
-               bf->skb = NULL;
-               spin_lock_irqsave(&sc->txbuflock, flags);
-               list_add_tail(&bf->list, &sc->txbuf);
-               sc->txbuf_len++;
-               spin_unlock_irqrestore(&sc->txbuflock, flags);
-               goto drop_packet;
-       }
-       return NETDEV_TX_OK;
-
-drop_packet:
-       dev_kfree_skb_any(skb);
-       return NETDEV_TX_OK;
-}
-
-/*
- * Reset the hardware.  If chan is not NULL, then also pause rx/tx
- * and change to the given channel.
- */
-static int
-ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan)
-{
-       struct ath5k_hw *ah = sc->ah;
-       int ret;
-
-       ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "resetting\n");
-
-       if (chan) {
-               ath5k_hw_set_imr(ah, 0);
-               ath5k_txq_cleanup(sc);
-               ath5k_rx_stop(sc);
-
-               sc->curchan = chan;
-               sc->curband = &sc->sbands[chan->band];
-       }
-       ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, true);
-       if (ret) {
-               ATH5K_ERR(sc, "can't reset hardware (%d)\n", ret);
-               goto err;
-       }
-
-       ret = ath5k_rx_start(sc);
-       if (ret) {
-               ATH5K_ERR(sc, "can't start recv logic\n");
-               goto err;
-       }
-
-       /*
-        * Change channels and update the h/w rate map if we're switching;
-        * e.g. 11a to 11b/g.
-        *
-        * We may be doing a reset in response to an ioctl that changes the
-        * channel so update any state that might change as a result.
-        *
-        * XXX needed?
-        */
-/*     ath5k_chan_change(sc, c); */
-
-       ath5k_beacon_config(sc);
-       /* intrs are enabled by ath5k_beacon_config */
-
-       return 0;
-err:
-       return ret;
-}
-
-static int
-ath5k_reset_wake(struct ath5k_softc *sc)
-{
-       int ret;
-
-       ret = ath5k_reset(sc, sc->curchan);
-       if (!ret)
-               ieee80211_wake_queues(sc->hw);
-
-       return ret;
-}
-
-static int ath5k_start(struct ieee80211_hw *hw)
-{
-       return ath5k_init(hw->priv);
-}
-
-static void ath5k_stop(struct ieee80211_hw *hw)
-{
-       ath5k_stop_hw(hw->priv);
-}
-
-static int ath5k_add_interface(struct ieee80211_hw *hw,
-               struct ieee80211_if_init_conf *conf)
-{
-       struct ath5k_softc *sc = hw->priv;
-       int ret;
-
-       mutex_lock(&sc->lock);
-       if (sc->vif) {
-               ret = 0;
-               goto end;
-       }
-
-       sc->vif = conf->vif;
-
-       switch (conf->type) {
-       case NL80211_IFTYPE_AP:
-       case NL80211_IFTYPE_STATION:
-       case NL80211_IFTYPE_ADHOC:
-       case NL80211_IFTYPE_MESH_POINT:
-       case NL80211_IFTYPE_MONITOR:
-               sc->opmode = conf->type;
-               break;
-       default:
-               ret = -EOPNOTSUPP;
-               goto end;
-       }
-
-       /* Set to a reasonable value. Note that this will
-        * be set to mac80211's value at ath5k_config(). */
-       sc->bintval = 1000;
-       ath5k_hw_set_lladdr(sc->ah, conf->mac_addr);
-
-       ret = 0;
-end:
-       mutex_unlock(&sc->lock);
-       return ret;
-}
-
-static void
-ath5k_remove_interface(struct ieee80211_hw *hw,
-                       struct ieee80211_if_init_conf *conf)
-{
-       struct ath5k_softc *sc = hw->priv;
-       u8 mac[ETH_ALEN] = {};
-
-       mutex_lock(&sc->lock);
-       if (sc->vif != conf->vif)
-               goto end;
-
-       ath5k_hw_set_lladdr(sc->ah, mac);
-       sc->vif = NULL;
-end:
-       mutex_unlock(&sc->lock);
-}
-
-/*
- * TODO: Phy disable/diversity etc
- */
-static int
-ath5k_config(struct ieee80211_hw *hw, u32 changed)
-{
-       struct ath5k_softc *sc = hw->priv;
-       struct ieee80211_conf *conf = &hw->conf;
-       int ret;
-
-       mutex_lock(&sc->lock);
-
-       sc->bintval = conf->beacon_int;
-       sc->power_level = conf->power_level;
-
-       ret = ath5k_chan_set(sc, conf->channel);
-
-       mutex_unlock(&sc->lock);
-       return ret;
-}
-
-static int
-ath5k_config_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
-                       struct ieee80211_if_conf *conf)
-{
-       struct ath5k_softc *sc = hw->priv;
-       struct ath5k_hw *ah = sc->ah;
-       int ret = 0;
-
-       mutex_lock(&sc->lock);
-       if (sc->vif != vif) {
-               ret = -EIO;
-               goto unlock;
-       }
-       if (conf->changed & IEEE80211_IFCC_BSSID && conf->bssid) {
-               /* Cache for later use during resets */
-               memcpy(ah->ah_bssid, conf->bssid, ETH_ALEN);
-               /* XXX: assoc id is set to 0 for now, mac80211 doesn't have
-                * a clean way of letting us retrieve this yet. */
-               ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
-               mmiowb();
-       }
-       if (conf->changed & IEEE80211_IFCC_BEACON &&
-                       (vif->type == NL80211_IFTYPE_ADHOC ||
-                        vif->type == NL80211_IFTYPE_MESH_POINT ||
-                        vif->type == NL80211_IFTYPE_AP)) {
-               struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
-               if (!beacon) {
-                       ret = -ENOMEM;
-                       goto unlock;
-               }
-               ath5k_beacon_update(sc, beacon);
-       }
-
-unlock:
-       mutex_unlock(&sc->lock);
-       return ret;
-}
-
-#define SUPPORTED_FIF_FLAGS \
-       FIF_PROMISC_IN_BSS |  FIF_ALLMULTI | FIF_FCSFAIL | \
-       FIF_PLCPFAIL | FIF_CONTROL | FIF_OTHER_BSS | \
-       FIF_BCN_PRBRESP_PROMISC
-/*
- * o always accept unicast, broadcast, and multicast traffic
- * o multicast traffic for all BSSIDs will be enabled if mac80211
- *   says it should be
- * o maintain current state of phy ofdm or phy cck error reception.
- *   If the hardware detects any of these type of errors then
- *   ath5k_hw_get_rx_filter() will pass to us the respective
- *   hardware filters to be able to receive these type of frames.
- * o probe request frames are accepted only when operating in
- *   hostap, adhoc, or monitor modes
- * o enable promiscuous mode according to the interface state
- * o accept beacons:
- *   - when operating in adhoc mode so the 802.11 layer creates
- *     node table entries for peers,
- *   - when operating in station mode for collecting rssi data when
- *     the station is otherwise quiet, or
- *   - when scanning
- */
-static void ath5k_configure_filter(struct ieee80211_hw *hw,
-               unsigned int changed_flags,
-               unsigned int *new_flags,
-               int mc_count, struct dev_mc_list *mclist)
-{
-       struct ath5k_softc *sc = hw->priv;
-       struct ath5k_hw *ah = sc->ah;
-       u32 mfilt[2], val, rfilt;
-       u8 pos;
-       int i;
-
-       mfilt[0] = 0;
-       mfilt[1] = 0;
-
-       /* Only deal with supported flags */
-       changed_flags &= SUPPORTED_FIF_FLAGS;
-       *new_flags &= SUPPORTED_FIF_FLAGS;
-
-       /* If HW detects any phy or radar errors, leave those filters on.
-        * Also, always enable Unicast, Broadcasts and Multicast
-        * XXX: move unicast, bssid broadcasts and multicast to mac80211 */
-       rfilt = (ath5k_hw_get_rx_filter(ah) & (AR5K_RX_FILTER_PHYERR)) |
-               (AR5K_RX_FILTER_UCAST | AR5K_RX_FILTER_BCAST |
-               AR5K_RX_FILTER_MCAST);
-
-       if (changed_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS)) {
-               if (*new_flags & FIF_PROMISC_IN_BSS) {
-                       rfilt |= AR5K_RX_FILTER_PROM;
-                       __set_bit(ATH_STAT_PROMISC, sc->status);
-               } else {
-                       __clear_bit(ATH_STAT_PROMISC, sc->status);
-               }
-       }
-
-       /* Note, AR5K_RX_FILTER_MCAST is already enabled */
-       if (*new_flags & FIF_ALLMULTI) {
-               mfilt[0] =  ~0;
-               mfilt[1] =  ~0;
-       } else {
-               for (i = 0; i < mc_count; i++) {
-                       if (!mclist)
-                               break;
-                       /* calculate XOR of eight 6-bit values */
-                       val = get_unaligned_le32(mclist->dmi_addr + 0);
-                       pos = (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val;
-                       val = get_unaligned_le32(mclist->dmi_addr + 3);
-                       pos ^= (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val;
-                       pos &= 0x3f;
-                       mfilt[pos / 32] |= (1 << (pos % 32));
-                       /* XXX: we might be able to just do this instead,
-                       * but not sure, needs testing, if we do use this we'd
-                       * neet to inform below to not reset the mcast */
-                       /* ath5k_hw_set_mcast_filterindex(ah,
-                        *      mclist->dmi_addr[5]); */
-                       mclist = mclist->next;
-               }
-       }
-
-       /* This is the best we can do */
-       if (*new_flags & (FIF_FCSFAIL | FIF_PLCPFAIL))
-               rfilt |= AR5K_RX_FILTER_PHYERR;
-
-       /* FIF_BCN_PRBRESP_PROMISC really means to enable beacons
-       * and probes for any BSSID, this needs testing */
-       if (*new_flags & FIF_BCN_PRBRESP_PROMISC)
-               rfilt |= AR5K_RX_FILTER_BEACON | AR5K_RX_FILTER_PROBEREQ;
-
-       /* FIF_CONTROL doc says that if FIF_PROMISC_IN_BSS is not
-        * set we should only pass on control frames for this
-        * station. This needs testing. I believe right now this
-        * enables *all* control frames, which is OK.. but
-        * but we should see if we can improve on granularity */
-       if (*new_flags & FIF_CONTROL)
-               rfilt |= AR5K_RX_FILTER_CONTROL;
-
-       /* Additional settings per mode -- this is per ath5k */
-
-       /* XXX move these to mac80211, and add a beacon IFF flag to mac80211 */
-
-       if (sc->opmode == NL80211_IFTYPE_MONITOR)
-               rfilt |= AR5K_RX_FILTER_CONTROL | AR5K_RX_FILTER_BEACON |
-                       AR5K_RX_FILTER_PROBEREQ | AR5K_RX_FILTER_PROM;
-       if (sc->opmode != NL80211_IFTYPE_STATION)
-               rfilt |= AR5K_RX_FILTER_PROBEREQ;
-       if (sc->opmode != NL80211_IFTYPE_AP &&
-               sc->opmode != NL80211_IFTYPE_MESH_POINT &&
-               test_bit(ATH_STAT_PROMISC, sc->status))
-               rfilt |= AR5K_RX_FILTER_PROM;
-       if ((sc->opmode == NL80211_IFTYPE_STATION && sc->assoc) ||
-               sc->opmode == NL80211_IFTYPE_ADHOC ||
-               sc->opmode == NL80211_IFTYPE_AP)
-               rfilt |= AR5K_RX_FILTER_BEACON;
-       if (sc->opmode == NL80211_IFTYPE_MESH_POINT)
-               rfilt |= AR5K_RX_FILTER_CONTROL | AR5K_RX_FILTER_BEACON |
-                       AR5K_RX_FILTER_PROBEREQ | AR5K_RX_FILTER_PROM;
-
-       /* Set filters */
-       ath5k_hw_set_rx_filter(ah, rfilt);
-
-       /* Set multicast bits */
-       ath5k_hw_set_mcast_filter(ah, mfilt[0], mfilt[1]);
-       /* Set the cached hw filter flags, this will alter actually
-        * be set in HW */
-       sc->filter_flags = rfilt;
-}
-
-static int
-ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
-             struct ieee80211_vif *vif, struct ieee80211_sta *sta,
-             struct ieee80211_key_conf *key)
-{
-       struct ath5k_softc *sc = hw->priv;
-       int ret = 0;
-
-       if (modparam_nohwcrypt)
-               return -EOPNOTSUPP;
-
-       switch (key->alg) {
-       case ALG_WEP:
-       case ALG_TKIP:
-               break;
-       case ALG_CCMP:
-               return -EOPNOTSUPP;
-       default:
-               WARN_ON(1);
-               return -EINVAL;
-       }
-
-       mutex_lock(&sc->lock);
-
-       switch (cmd) {
-       case SET_KEY:
-               ret = ath5k_hw_set_key(sc->ah, key->keyidx, key,
-                                      sta ? sta->addr : NULL);
-               if (ret) {
-                       ATH5K_ERR(sc, "can't set the key\n");
-                       goto unlock;
-               }
-               __set_bit(key->keyidx, sc->keymap);
-               key->hw_key_idx = key->keyidx;
-               key->flags |= (IEEE80211_KEY_FLAG_GENERATE_IV |
-                              IEEE80211_KEY_FLAG_GENERATE_MMIC);
-               break;
-       case DISABLE_KEY:
-               ath5k_hw_reset_key(sc->ah, key->keyidx);
-               __clear_bit(key->keyidx, sc->keymap);
-               break;
-       default:
-               ret = -EINVAL;
-               goto unlock;
-       }
-
-unlock:
-       mmiowb();
-       mutex_unlock(&sc->lock);
-       return ret;
-}
-
-static int
-ath5k_get_stats(struct ieee80211_hw *hw,
-               struct ieee80211_low_level_stats *stats)
-{
-       struct ath5k_softc *sc = hw->priv;
-       struct ath5k_hw *ah = sc->ah;
-
-       /* Force update */
-       ath5k_hw_update_mib_counters(ah, &sc->ll_stats);
-
-       memcpy(stats, &sc->ll_stats, sizeof(sc->ll_stats));
-
-       return 0;
-}
-
-static int
-ath5k_get_tx_stats(struct ieee80211_hw *hw,
-               struct ieee80211_tx_queue_stats *stats)
-{
-       struct ath5k_softc *sc = hw->priv;
-
-       memcpy(stats, &sc->tx_stats, sizeof(sc->tx_stats));
-
-       return 0;
-}
-
-static u64
-ath5k_get_tsf(struct ieee80211_hw *hw)
-{
-       struct ath5k_softc *sc = hw->priv;
-
-       return ath5k_hw_get_tsf64(sc->ah);
-}
-
-static void
-ath5k_set_tsf(struct ieee80211_hw *hw, u64 tsf)
-{
-       struct ath5k_softc *sc = hw->priv;
-
-       ath5k_hw_set_tsf64(sc->ah, tsf);
-}
-
-static void
-ath5k_reset_tsf(struct ieee80211_hw *hw)
-{
-       struct ath5k_softc *sc = hw->priv;
-
-       /*
-        * in IBSS mode we need to update the beacon timers too.
-        * this will also reset the TSF if we call it with 0
-        */
-       if (sc->opmode == NL80211_IFTYPE_ADHOC)
-               ath5k_beacon_update_timers(sc, 0);
-       else
-               ath5k_hw_reset_tsf(sc->ah);
-}
-
-static int
-ath5k_beacon_update(struct ath5k_softc *sc, struct sk_buff *skb)
-{
-       unsigned long flags;
-       int ret;
-
-       ath5k_debug_dump_skb(sc, skb, "BC  ", 1);
-
-       spin_lock_irqsave(&sc->block, flags);
-       ath5k_txbuf_free(sc, sc->bbuf);
-       sc->bbuf->skb = skb;
-       ret = ath5k_beacon_setup(sc, sc->bbuf);
-       if (ret)
-               sc->bbuf->skb = NULL;
-       spin_unlock_irqrestore(&sc->block, flags);
-       if (!ret) {
-               ath5k_beacon_config(sc);
-               mmiowb();
-       }
-
-       return ret;
-}
-static void
-set_beacon_filter(struct ieee80211_hw *hw, bool enable)
-{
-       struct ath5k_softc *sc = hw->priv;
-       struct ath5k_hw *ah = sc->ah;
-       u32 rfilt;
-       rfilt = ath5k_hw_get_rx_filter(ah);
-       if (enable)
-               rfilt |= AR5K_RX_FILTER_BEACON;
-       else
-               rfilt &= ~AR5K_RX_FILTER_BEACON;
-       ath5k_hw_set_rx_filter(ah, rfilt);
-       sc->filter_flags = rfilt;
-}
-
-static void ath5k_bss_info_changed(struct ieee80211_hw *hw,
-                                   struct ieee80211_vif *vif,
-                                   struct ieee80211_bss_conf *bss_conf,
-                                   u32 changes)
-{
-       struct ath5k_softc *sc = hw->priv;
-       if (changes & BSS_CHANGED_ASSOC) {
-               mutex_lock(&sc->lock);
-               sc->assoc = bss_conf->assoc;
-               if (sc->opmode == NL80211_IFTYPE_STATION)
-                       set_beacon_filter(hw, sc->assoc);
-               mutex_unlock(&sc->lock);
-       }
-}
diff --git a/drivers/net/wireless/ath5k/base.h b/drivers/net/wireless/ath5k/base.h
deleted file mode 100644 (file)
index 8229561..0000000
+++ /dev/null
@@ -1,190 +0,0 @@
-/*-
- * Copyright (c) 2002-2007 Sam Leffler, Errno Consulting
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer,
- *    without modification.
- * 2. Redistributions in binary form must reproduce at minimum a disclaimer
- *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
- *    redistribution must be conditioned upon including a substantially
- *    similar Disclaimer requirement for further binary redistribution.
- * 3. Neither the names of the above-listed copyright holders nor the names
- *    of any contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * Alternatively, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") version 2 as published by the Free
- * Software Foundation.
- *
- * NO WARRANTY
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGES.
- *
- */
-
-/*
- * Defintions for the Atheros Wireless LAN controller driver.
- */
-#ifndef _DEV_ATH_ATHVAR_H
-#define _DEV_ATH_ATHVAR_H
-
-#include <linux/interrupt.h>
-#include <linux/list.h>
-#include <linux/wireless.h>
-#include <linux/if_ether.h>
-#include <linux/leds.h>
-
-#include "ath5k.h"
-#include "debug.h"
-
-#define        ATH_RXBUF       40              /* number of RX buffers */
-#define        ATH_TXBUF       200             /* number of TX buffers */
-#define ATH_BCBUF      1               /* number of beacon buffers */
-
-struct ath5k_buf {
-       struct list_head        list;
-       unsigned int            flags;  /* rx descriptor flags */
-       struct ath5k_desc       *desc;  /* virtual addr of desc */
-       dma_addr_t              daddr;  /* physical addr of desc */
-       struct sk_buff          *skb;   /* skbuff for buf */
-       dma_addr_t              skbaddr;/* physical addr of skb data */
-};
-
-/*
- * Data transmit queue state.  One of these exists for each
- * hardware transmit queue.  Packets sent to us from above
- * are assigned to queues based on their priority.  Not all
- * devices support a complete set of hardware transmit queues.
- * For those devices the array sc_ac2q will map multiple
- * priorities to fewer hardware queues (typically all to one
- * hardware queue).
- */
-struct ath5k_txq {
-       unsigned int            qnum;   /* hardware q number */
-       u32                     *link;  /* link ptr in last TX desc */
-       struct list_head        q;      /* transmit queue */
-       spinlock_t              lock;   /* lock on q and link */
-       bool                    setup;
-};
-
-#define ATH5K_LED_MAX_NAME_LEN 31
-
-/*
- * State for LED triggers
- */
-struct ath5k_led
-{
-       char name[ATH5K_LED_MAX_NAME_LEN + 1];  /* name of the LED in sysfs */
-       struct ath5k_softc *sc;                 /* driver state */
-       struct led_classdev led_dev;            /* led classdev */
-};
-
-
-#if CHAN_DEBUG
-#define ATH_CHAN_MAX   (26+26+26+200+200)
-#else
-#define ATH_CHAN_MAX   (14+14+14+252+20)
-#endif
-
-/* Software Carrier, keeps track of the driver state
- * associated with an instance of a device */
-struct ath5k_softc {
-       struct pci_dev          *pdev;          /* for dma mapping */
-       void __iomem            *iobase;        /* address of the device */
-       struct mutex            lock;           /* dev-level lock */
-       /* FIXME: how many does it really need? */
-       struct ieee80211_tx_queue_stats tx_stats[16];
-       struct ieee80211_low_level_stats ll_stats;
-       struct ieee80211_hw     *hw;            /* IEEE 802.11 common */
-       struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
-       struct ieee80211_channel channels[ATH_CHAN_MAX];
-       struct ieee80211_rate   rates[IEEE80211_NUM_BANDS][AR5K_MAX_RATES];
-       s8                      rate_idx[IEEE80211_NUM_BANDS][AR5K_MAX_RATES];
-       enum nl80211_iftype     opmode;
-       struct ath5k_hw         *ah;            /* Atheros HW */
-
-       struct ieee80211_supported_band         *curband;
-
-#ifdef CONFIG_ATH5K_DEBUG
-       struct ath5k_dbg_info   debug;          /* debug info */
-#endif /* CONFIG_ATH5K_DEBUG */
-
-       struct ath5k_buf        *bufptr;        /* allocated buffer ptr */
-       struct ath5k_desc       *desc;          /* TX/RX descriptors */
-       dma_addr_t              desc_daddr;     /* DMA (physical) address */
-       size_t                  desc_len;       /* size of TX/RX descriptors */
-       u16                     cachelsz;       /* cache line size */
-
-       DECLARE_BITMAP(status, 5);
-#define ATH_STAT_INVALID       0               /* disable hardware accesses */
-#define ATH_STAT_MRRETRY       1               /* multi-rate retry support */
-#define ATH_STAT_PROMISC       2
-#define ATH_STAT_LEDSOFT       3               /* enable LED gpio status */
-#define ATH_STAT_STARTED       4               /* opened & irqs enabled */
-
-       unsigned int            filter_flags;   /* HW flags, AR5K_RX_FILTER_* */
-       unsigned int            curmode;        /* current phy mode */
-       struct ieee80211_channel *curchan;      /* current h/w channel */
-
-       struct ieee80211_vif *vif;
-
-       enum ath5k_int          imask;          /* interrupt mask copy */
-
-       DECLARE_BITMAP(keymap, AR5K_KEYCACHE_SIZE); /* key use bit map */
-
-       u8                      bssidmask[ETH_ALEN];
-
-       unsigned int            led_pin,        /* GPIO pin for driving LED */
-                               led_on;         /* pin setting for LED on */
-
-       struct tasklet_struct   restq;          /* reset tasklet */
-
-       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 */
-       struct tasklet_struct   rxtq;           /* rx intr tasklet */
-       struct ath5k_led        rx_led;         /* rx led */
-
-       struct list_head        txbuf;          /* transmit buffer */
-       spinlock_t              txbuflock;
-       unsigned int            txbuf_len;      /* buf count in txbuf list */
-       struct ath5k_txq        txqs[2];        /* beacon and tx */
-
-       struct ath5k_txq        *txq;           /* beacon and tx*/
-       struct tasklet_struct   txtq;           /* tx intr tasklet */
-       struct ath5k_led        tx_led;         /* tx led */
-
-       spinlock_t              block;          /* protects beacon */
-       struct tasklet_struct   beacontq;       /* beacon intr tasklet */
-       struct ath5k_buf        *bbuf;          /* beacon buffer */
-       unsigned int            bhalq,          /* SW q for outgoing beacons */
-                               bmisscount,     /* missed beacon transmits */
-                               bintval,        /* beacon interval in TU */
-                               bsent;
-       unsigned int            nexttbtt;       /* next beacon time in TU */
-
-       struct timer_list       calib_tim;      /* calibration timer */
-       int                     power_level;    /* Requested tx power in dbm */
-       bool                    assoc;          /* assocate state */
-};
-
-#define ath5k_hw_hasbssidmask(_ah) \
-       (ath5k_hw_get_capability(_ah, AR5K_CAP_BSSIDMASK, 0, NULL) == 0)
-#define ath5k_hw_hasveol(_ah) \
-       (ath5k_hw_get_capability(_ah, AR5K_CAP_VEOL, 0, NULL) == 0)
-
-#endif
diff --git a/drivers/net/wireless/ath5k/caps.c b/drivers/net/wireless/ath5k/caps.c
deleted file mode 100644 (file)
index 367a6c7..0000000
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
- * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
- * Copyright (c) 2007-2008 Jiri Slaby <jirislaby@gmail.com>
- *
- * Permission to use, copy, modify, and 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.
- *
- */
-
-/**************\
-* Capabilities *
-\**************/
-
-#include "ath5k.h"
-#include "reg.h"
-#include "debug.h"
-#include "base.h"
-
-/*
- * Fill the capabilities struct
- * TODO: Merge this with EEPROM code when we are done with it
- */
-int ath5k_hw_set_capabilities(struct ath5k_hw *ah)
-{
-       u16 ee_header;
-
-       ATH5K_TRACE(ah->ah_sc);
-       /* Capabilities stored in the EEPROM */
-       ee_header = ah->ah_capabilities.cap_eeprom.ee_header;
-
-       if (ah->ah_version == AR5K_AR5210) {
-               /*
-                * Set radio capabilities
-                * (The AR5110 only supports the middle 5GHz band)
-                */
-               ah->ah_capabilities.cap_range.range_5ghz_min = 5120;
-               ah->ah_capabilities.cap_range.range_5ghz_max = 5430;
-               ah->ah_capabilities.cap_range.range_2ghz_min = 0;
-               ah->ah_capabilities.cap_range.range_2ghz_max = 0;
-
-               /* Set supported modes */
-               __set_bit(AR5K_MODE_11A, ah->ah_capabilities.cap_mode);
-               __set_bit(AR5K_MODE_11A_TURBO, ah->ah_capabilities.cap_mode);
-       } else {
-               /*
-                * XXX The tranceiver supports frequencies from 4920 to 6100GHz
-                * XXX and from 2312 to 2732GHz. There are problems with the
-                * XXX current ieee80211 implementation because the IEEE
-                * XXX channel mapping does not support negative channel
-                * XXX numbers (2312MHz is channel -19). Of course, this
-                * XXX doesn't matter because these channels are out of range
-                * XXX but some regulation domains like MKK (Japan) will
-                * XXX support frequencies somewhere around 4.8GHz.
-                */
-
-               /*
-                * Set radio capabilities
-                */
-
-               if (AR5K_EEPROM_HDR_11A(ee_header)) {
-                       /* 4920 */
-                       ah->ah_capabilities.cap_range.range_5ghz_min = 5005;
-                       ah->ah_capabilities.cap_range.range_5ghz_max = 6100;
-
-                       /* Set supported modes */
-                       __set_bit(AR5K_MODE_11A,
-                                       ah->ah_capabilities.cap_mode);
-                       __set_bit(AR5K_MODE_11A_TURBO,
-                                       ah->ah_capabilities.cap_mode);
-                       if (ah->ah_version == AR5K_AR5212)
-                               __set_bit(AR5K_MODE_11G_TURBO,
-                                               ah->ah_capabilities.cap_mode);
-               }
-
-               /* Enable  802.11b if a 2GHz capable radio (2111/5112) is
-                * connected */
-               if (AR5K_EEPROM_HDR_11B(ee_header) ||
-                   (AR5K_EEPROM_HDR_11G(ee_header) &&
-                    ah->ah_version != AR5K_AR5211)) {
-                       /* 2312 */
-                       ah->ah_capabilities.cap_range.range_2ghz_min = 2412;
-                       ah->ah_capabilities.cap_range.range_2ghz_max = 2732;
-
-                       if (AR5K_EEPROM_HDR_11B(ee_header))
-                               __set_bit(AR5K_MODE_11B,
-                                               ah->ah_capabilities.cap_mode);
-
-                       if (AR5K_EEPROM_HDR_11G(ee_header) &&
-                           ah->ah_version != AR5K_AR5211)
-                               __set_bit(AR5K_MODE_11G,
-                                               ah->ah_capabilities.cap_mode);
-               }
-       }
-
-       /* GPIO */
-       ah->ah_gpio_npins = AR5K_NUM_GPIO;
-
-       /* Set number of supported TX queues */
-       if (ah->ah_version == AR5K_AR5210)
-               ah->ah_capabilities.cap_queues.q_tx_num =
-                       AR5K_NUM_TX_QUEUES_NOQCU;
-       else
-               ah->ah_capabilities.cap_queues.q_tx_num = AR5K_NUM_TX_QUEUES;
-
-       return 0;
-}
-
-/* Main function used by the driver part to check caps */
-int ath5k_hw_get_capability(struct ath5k_hw *ah,
-               enum ath5k_capability_type cap_type,
-               u32 capability, u32 *result)
-{
-       ATH5K_TRACE(ah->ah_sc);
-
-       switch (cap_type) {
-       case AR5K_CAP_NUM_TXQUEUES:
-               if (result) {
-                       if (ah->ah_version == AR5K_AR5210)
-                               *result = AR5K_NUM_TX_QUEUES_NOQCU;
-                       else
-                               *result = AR5K_NUM_TX_QUEUES;
-                       goto yes;
-               }
-       case AR5K_CAP_VEOL:
-               goto yes;
-       case AR5K_CAP_COMPRESSION:
-               if (ah->ah_version == AR5K_AR5212)
-                       goto yes;
-               else
-                       goto no;
-       case AR5K_CAP_BURST:
-               goto yes;
-       case AR5K_CAP_TPC:
-               goto yes;
-       case AR5K_CAP_BSSIDMASK:
-               if (ah->ah_version == AR5K_AR5212)
-                       goto yes;
-               else
-                       goto no;
-       case AR5K_CAP_XR:
-               if (ah->ah_version == AR5K_AR5212)
-                       goto yes;
-               else
-                       goto no;
-       default:
-               goto no;
-       }
-
-no:
-       return -EINVAL;
-yes:
-       return 0;
-}
-
-/*
- * TODO: Following functions should be part of a new function
- * set_capability
- */
-
-int ath5k_hw_enable_pspoll(struct ath5k_hw *ah, u8 *bssid,
-               u16 assoc_id)
-{
-       ATH5K_TRACE(ah->ah_sc);
-
-       if (ah->ah_version == AR5K_AR5210) {
-               AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1,
-                       AR5K_STA_ID1_NO_PSPOLL | AR5K_STA_ID1_DEFAULT_ANTENNA);
-               return 0;
-       }
-
-       return -EIO;
-}
-
-int ath5k_hw_disable_pspoll(struct ath5k_hw *ah)
-{
-       ATH5K_TRACE(ah->ah_sc);
-
-       if (ah->ah_version == AR5K_AR5210) {
-               AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1,
-                       AR5K_STA_ID1_NO_PSPOLL | AR5K_STA_ID1_DEFAULT_ANTENNA);
-               return 0;
-       }
-
-       return -EIO;
-}
diff --git a/drivers/net/wireless/ath5k/debug.c b/drivers/net/wireless/ath5k/debug.c
deleted file mode 100644 (file)
index 4904a07..0000000
+++ /dev/null
@@ -1,538 +0,0 @@
-/*
- * Copyright (c) 2007-2008 Bruno Randolf <bruno@thinktube.com>
- *
- *  This file is free software: you may copy, redistribute 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 file 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, see <http://www.gnu.org/licenses/>.
- *
- *
- * This file incorporates work covered by the following copyright and
- * permission notice:
- *
- * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
- * Copyright (c) 2004-2005 Atheros Communications, Inc.
- * Copyright (c) 2006 Devicescape Software, Inc.
- * Copyright (c) 2007 Jiri Slaby <jirislaby@gmail.com>
- * Copyright (c) 2007 Luis R. Rodriguez <mcgrof@winlab.rutgers.edu>
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer,
- *    without modification.
- * 2. Redistributions in binary form must reproduce at minimum a disclaimer
- *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
- *    redistribution must be conditioned upon including a substantially
- *    similar Disclaimer requirement for further binary redistribution.
- * 3. Neither the names of the above-listed copyright holders nor the names
- *    of any contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * Alternatively, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") version 2 as published by the Free
- * Software Foundation.
- *
- * NO WARRANTY
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGES.
- */
-
-#include "base.h"
-#include "debug.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"
-
-static struct dentry *ath5k_global_debugfs;
-
-static int ath5k_debugfs_open(struct inode *inode, struct file *file)
-{
-       file->private_data = inode->i_private;
-       return 0;
-}
-
-
-/* debugfs: registers */
-
-struct reg {
-       const char *name;
-       int addr;
-};
-
-#define REG_STRUCT_INIT(r) { #r, r }
-
-/* just a few random registers, might want to add more */
-static const struct reg regs[] = {
-       REG_STRUCT_INIT(AR5K_CR),
-       REG_STRUCT_INIT(AR5K_RXDP),
-       REG_STRUCT_INIT(AR5K_CFG),
-       REG_STRUCT_INIT(AR5K_IER),
-       REG_STRUCT_INIT(AR5K_BCR),
-       REG_STRUCT_INIT(AR5K_RTSD0),
-       REG_STRUCT_INIT(AR5K_RTSD1),
-       REG_STRUCT_INIT(AR5K_TXCFG),
-       REG_STRUCT_INIT(AR5K_RXCFG),
-       REG_STRUCT_INIT(AR5K_RXJLA),
-       REG_STRUCT_INIT(AR5K_MIBC),
-       REG_STRUCT_INIT(AR5K_TOPS),
-       REG_STRUCT_INIT(AR5K_RXNOFRM),
-       REG_STRUCT_INIT(AR5K_TXNOFRM),
-       REG_STRUCT_INIT(AR5K_RPGTO),
-       REG_STRUCT_INIT(AR5K_RFCNT),
-       REG_STRUCT_INIT(AR5K_MISC),
-       REG_STRUCT_INIT(AR5K_QCUDCU_CLKGT),
-       REG_STRUCT_INIT(AR5K_ISR),
-       REG_STRUCT_INIT(AR5K_PISR),
-       REG_STRUCT_INIT(AR5K_SISR0),
-       REG_STRUCT_INIT(AR5K_SISR1),
-       REG_STRUCT_INIT(AR5K_SISR2),
-       REG_STRUCT_INIT(AR5K_SISR3),
-       REG_STRUCT_INIT(AR5K_SISR4),
-       REG_STRUCT_INIT(AR5K_IMR),
-       REG_STRUCT_INIT(AR5K_PIMR),
-       REG_STRUCT_INIT(AR5K_SIMR0),
-       REG_STRUCT_INIT(AR5K_SIMR1),
-       REG_STRUCT_INIT(AR5K_SIMR2),
-       REG_STRUCT_INIT(AR5K_SIMR3),
-       REG_STRUCT_INIT(AR5K_SIMR4),
-       REG_STRUCT_INIT(AR5K_DCM_ADDR),
-       REG_STRUCT_INIT(AR5K_DCCFG),
-       REG_STRUCT_INIT(AR5K_CCFG),
-       REG_STRUCT_INIT(AR5K_CPC0),
-       REG_STRUCT_INIT(AR5K_CPC1),
-       REG_STRUCT_INIT(AR5K_CPC2),
-       REG_STRUCT_INIT(AR5K_CPC3),
-       REG_STRUCT_INIT(AR5K_CPCOVF),
-       REG_STRUCT_INIT(AR5K_RESET_CTL),
-       REG_STRUCT_INIT(AR5K_SLEEP_CTL),
-       REG_STRUCT_INIT(AR5K_INTPEND),
-       REG_STRUCT_INIT(AR5K_SFR),
-       REG_STRUCT_INIT(AR5K_PCICFG),
-       REG_STRUCT_INIT(AR5K_GPIOCR),
-       REG_STRUCT_INIT(AR5K_GPIODO),
-       REG_STRUCT_INIT(AR5K_SREV),
-};
-
-static void *reg_start(struct seq_file *seq, loff_t *pos)
-{
-       return *pos < ARRAY_SIZE(regs) ? (void *)&regs[*pos] : NULL;
-}
-
-static void reg_stop(struct seq_file *seq, void *p)
-{
-       /* nothing to do */
-}
-
-static void *reg_next(struct seq_file *seq, void *p, loff_t *pos)
-{
-       ++*pos;
-       return *pos < ARRAY_SIZE(regs) ? (void *)&regs[*pos] : NULL;
-}
-
-static int reg_show(struct seq_file *seq, void *p)
-{
-       struct ath5k_softc *sc = seq->private;
-       struct reg *r = p;
-       seq_printf(seq, "%-25s0x%08x\n", r->name,
-               ath5k_hw_reg_read(sc->ah, r->addr));
-       return 0;
-}
-
-static const struct seq_operations register_seq_ops = {
-       .start = reg_start,
-       .next  = reg_next,
-       .stop  = reg_stop,
-       .show  = reg_show
-};
-
-static int open_file_registers(struct inode *inode, struct file *file)
-{
-       struct seq_file *s;
-       int res;
-       res = seq_open(file, &register_seq_ops);
-       if (res == 0) {
-               s = file->private_data;
-               s->private = inode->i_private;
-       }
-       return res;
-}
-
-static const struct file_operations fops_registers = {
-       .open = open_file_registers,
-       .read    = seq_read,
-       .llseek  = seq_lseek,
-       .release = seq_release,
-       .owner = THIS_MODULE,
-};
-
-
-/* debugfs: beacons */
-
-static ssize_t read_file_beacon(struct file *file, char __user *user_buf,
-                                  size_t count, loff_t *ppos)
-{
-       struct ath5k_softc *sc = file->private_data;
-       struct ath5k_hw *ah = sc->ah;
-       char buf[500];
-       unsigned int len = 0;
-       unsigned int v;
-       u64 tsf;
-
-       v = ath5k_hw_reg_read(sc->ah, AR5K_BEACON);
-       len += snprintf(buf+len, sizeof(buf)-len,
-               "%-24s0x%08x\tintval: %d\tTIM: 0x%x\n",
-               "AR5K_BEACON", v, v & AR5K_BEACON_PERIOD,
-               (v & AR5K_BEACON_TIM) >> AR5K_BEACON_TIM_S);
-
-       len += snprintf(buf+len, sizeof(buf)-len, "%-24s0x%08x\n",
-               "AR5K_LAST_TSTP", ath5k_hw_reg_read(sc->ah, AR5K_LAST_TSTP));
-
-       len += snprintf(buf+len, sizeof(buf)-len, "%-24s0x%08x\n\n",
-               "AR5K_BEACON_CNT", ath5k_hw_reg_read(sc->ah, AR5K_BEACON_CNT));
-
-       v = ath5k_hw_reg_read(sc->ah, AR5K_TIMER0);
-       len += snprintf(buf+len, sizeof(buf)-len, "%-24s0x%08x\tTU: %08x\n",
-               "AR5K_TIMER0 (TBTT)", v, v);
-
-       v = ath5k_hw_reg_read(sc->ah, AR5K_TIMER1);
-       len += snprintf(buf+len, sizeof(buf)-len, "%-24s0x%08x\tTU: %08x\n",
-               "AR5K_TIMER1 (DMA)", v, v >> 3);
-
-       v = ath5k_hw_reg_read(sc->ah, AR5K_TIMER2);
-       len += snprintf(buf+len, sizeof(buf)-len, "%-24s0x%08x\tTU: %08x\n",
-               "AR5K_TIMER2 (SWBA)", v, v >> 3);
-
-       v = ath5k_hw_reg_read(sc->ah, AR5K_TIMER3);
-       len += snprintf(buf+len, sizeof(buf)-len, "%-24s0x%08x\tTU: %08x\n",
-               "AR5K_TIMER3 (ATIM)", v, v);
-
-       tsf = ath5k_hw_get_tsf64(sc->ah);
-       len += snprintf(buf+len, sizeof(buf)-len,
-               "TSF\t\t0x%016llx\tTU: %08x\n",
-               (unsigned long long)tsf, TSF_TO_TU(tsf));
-
-       return simple_read_from_buffer(user_buf, count, ppos, buf, len);
-}
-
-static ssize_t write_file_beacon(struct file *file,
-                                const char __user *userbuf,
-                                size_t count, loff_t *ppos)
-{
-       struct ath5k_softc *sc = file->private_data;
-       struct ath5k_hw *ah = sc->ah;
-       char buf[20];
-
-       if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
-               return -EFAULT;
-
-       if (strncmp(buf, "disable", 7) == 0) {
-               AR5K_REG_DISABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE);
-               printk(KERN_INFO "debugfs disable beacons\n");
-       } else if (strncmp(buf, "enable", 6) == 0) {
-               AR5K_REG_ENABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE);
-               printk(KERN_INFO "debugfs enable beacons\n");
-       }
-       return count;
-}
-
-static const struct file_operations fops_beacon = {
-       .read = read_file_beacon,
-       .write = write_file_beacon,
-       .open = ath5k_debugfs_open,
-       .owner = THIS_MODULE,
-};
-
-
-/* debugfs: reset */
-
-static ssize_t write_file_reset(struct file *file,
-                                const char __user *userbuf,
-                                size_t count, loff_t *ppos)
-{
-       struct ath5k_softc *sc = file->private_data;
-       tasklet_schedule(&sc->restq);
-       return count;
-}
-
-static const struct file_operations fops_reset = {
-       .write = write_file_reset,
-       .open = ath5k_debugfs_open,
-       .owner = THIS_MODULE,
-};
-
-
-/* debugfs: debug level */
-
-static const struct {
-       enum ath5k_debug_level level;
-       const char *name;
-       const char *desc;
-} dbg_info[] = {
-       { ATH5K_DEBUG_RESET,    "reset",        "reset and initialization" },
-       { ATH5K_DEBUG_INTR,     "intr",         "interrupt handling" },
-       { ATH5K_DEBUG_MODE,     "mode",         "mode init/setup" },
-       { ATH5K_DEBUG_XMIT,     "xmit",         "basic xmit operation" },
-       { ATH5K_DEBUG_BEACON,   "beacon",       "beacon handling" },
-       { ATH5K_DEBUG_CALIBRATE, "calib",       "periodic calibration" },
-       { ATH5K_DEBUG_TXPOWER,  "txpower",      "transmit power setting" },
-       { ATH5K_DEBUG_LED,      "led",          "LED management" },
-       { ATH5K_DEBUG_DUMP_RX,  "dumprx",       "print received skb content" },
-       { ATH5K_DEBUG_DUMP_TX,  "dumptx",       "print transmit skb content" },
-       { ATH5K_DEBUG_DUMPBANDS, "dumpbands",   "dump bands" },
-       { ATH5K_DEBUG_TRACE,    "trace",        "trace function calls" },
-       { ATH5K_DEBUG_ANY,      "all",          "show all debug levels" },
-};
-
-static ssize_t read_file_debug(struct file *file, char __user *user_buf,
-                                  size_t count, loff_t *ppos)
-{
-       struct ath5k_softc *sc = file->private_data;
-       char buf[700];
-       unsigned int len = 0;
-       unsigned int i;
-
-       len += snprintf(buf+len, sizeof(buf)-len,
-               "DEBUG LEVEL: 0x%08x\n\n", sc->debug.level);
-
-       for (i = 0; i < ARRAY_SIZE(dbg_info) - 1; i++) {
-               len += snprintf(buf+len, sizeof(buf)-len,
-                       "%10s %c 0x%08x - %s\n", dbg_info[i].name,
-                       sc->debug.level & dbg_info[i].level ? '+' : ' ',
-                       dbg_info[i].level, dbg_info[i].desc);
-       }
-       len += snprintf(buf+len, sizeof(buf)-len,
-               "%10s %c 0x%08x - %s\n", dbg_info[i].name,
-               sc->debug.level == dbg_info[i].level ? '+' : ' ',
-               dbg_info[i].level, dbg_info[i].desc);
-
-       return simple_read_from_buffer(user_buf, count, ppos, buf, len);
-}
-
-static ssize_t write_file_debug(struct file *file,
-                                const char __user *userbuf,
-                                size_t count, loff_t *ppos)
-{
-       struct ath5k_softc *sc = file->private_data;
-       unsigned int i;
-       char buf[20];
-
-       if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
-               return -EFAULT;
-
-       for (i = 0; i < ARRAY_SIZE(dbg_info); i++) {
-               if (strncmp(buf, dbg_info[i].name,
-                                       strlen(dbg_info[i].name)) == 0) {
-                       sc->debug.level ^= dbg_info[i].level; /* toggle bit */
-                       break;
-               }
-       }
-       return count;
-}
-
-static const struct file_operations fops_debug = {
-       .read = read_file_debug,
-       .write = write_file_debug,
-       .open = ath5k_debugfs_open,
-       .owner = THIS_MODULE,
-};
-
-
-/* init */
-
-void
-ath5k_debug_init(void)
-{
-       ath5k_global_debugfs = debugfs_create_dir("ath5k", NULL);
-}
-
-void
-ath5k_debug_init_device(struct ath5k_softc *sc)
-{
-       sc->debug.level = ath5k_debug;
-
-       sc->debug.debugfs_phydir = debugfs_create_dir(wiphy_name(sc->hw->wiphy),
-                               ath5k_global_debugfs);
-
-       sc->debug.debugfs_debug = debugfs_create_file("debug", S_IWUSR | S_IRUGO,
-                               sc->debug.debugfs_phydir, sc, &fops_debug);
-
-       sc->debug.debugfs_registers = debugfs_create_file("registers", S_IRUGO,
-                               sc->debug.debugfs_phydir, sc, &fops_registers);
-
-       sc->debug.debugfs_beacon = debugfs_create_file("beacon", S_IWUSR | S_IRUGO,
-                               sc->debug.debugfs_phydir, sc, &fops_beacon);
-
-       sc->debug.debugfs_reset = debugfs_create_file("reset", S_IWUSR,
-                               sc->debug.debugfs_phydir, sc, &fops_reset);
-}
-
-void
-ath5k_debug_finish(void)
-{
-       debugfs_remove(ath5k_global_debugfs);
-}
-
-void
-ath5k_debug_finish_device(struct ath5k_softc *sc)
-{
-       debugfs_remove(sc->debug.debugfs_debug);
-       debugfs_remove(sc->debug.debugfs_registers);
-       debugfs_remove(sc->debug.debugfs_beacon);
-       debugfs_remove(sc->debug.debugfs_reset);
-       debugfs_remove(sc->debug.debugfs_phydir);
-}
-
-
-/* functions used in other places */
-
-void
-ath5k_debug_dump_bands(struct ath5k_softc *sc)
-{
-       unsigned int b, i;
-
-       if (likely(!(sc->debug.level & ATH5K_DEBUG_DUMPBANDS)))
-               return;
-
-       BUG_ON(!sc->sbands);
-
-       for (b = 0; b < IEEE80211_NUM_BANDS; b++) {
-               struct ieee80211_supported_band *band = &sc->sbands[b];
-               char bname[6];
-               switch (band->band) {
-               case IEEE80211_BAND_2GHZ:
-                       strcpy(bname, "2 GHz");
-                       break;
-               case IEEE80211_BAND_5GHZ:
-                       strcpy(bname, "5 GHz");
-                       break;
-               default:
-                       printk(KERN_DEBUG "Band not supported: %d\n",
-                               band->band);
-                       return;
-               }
-               printk(KERN_DEBUG "Band %s: channels %d, rates %d\n", bname,
-                               band->n_channels, band->n_bitrates);
-               printk(KERN_DEBUG " channels:\n");
-               for (i = 0; i < band->n_channels; i++)
-                       printk(KERN_DEBUG "  %3d %d %.4x %.4x\n",
-                                       ieee80211_frequency_to_channel(
-                                               band->channels[i].center_freq),
-                                       band->channels[i].center_freq,
-                                       band->channels[i].hw_value,
-                                       band->channels[i].flags);
-               printk(KERN_DEBUG " rates:\n");
-               for (i = 0; i < band->n_bitrates; i++)
-                       printk(KERN_DEBUG "  %4d %.4x %.4x %.4x\n",
-                                       band->bitrates[i].bitrate,
-                                       band->bitrates[i].hw_value,
-                                       band->bitrates[i].flags,
-                                       band->bitrates[i].hw_value_short);
-       }
-}
-
-static inline void
-ath5k_debug_printrxbuf(struct ath5k_buf *bf, int done,
-                      struct ath5k_rx_status *rs)
-{
-       struct ath5k_desc *ds = bf->desc;
-       struct ath5k_hw_all_rx_desc *rd = &ds->ud.ds_rx;
-
-       printk(KERN_DEBUG "R (%p %llx) %08x %08x %08x %08x %08x %08x %c\n",
-               ds, (unsigned long long)bf->daddr,
-               ds->ds_link, ds->ds_data,
-               rd->rx_ctl.rx_control_0, rd->rx_ctl.rx_control_1,
-               rd->u.rx_stat.rx_status_0, rd->u.rx_stat.rx_status_0,
-               !done ? ' ' : (rs->rs_status == 0) ? '*' : '!');
-}
-
-void
-ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah)
-{
-       struct ath5k_desc *ds;
-       struct ath5k_buf *bf;
-       struct ath5k_rx_status rs = {};
-       int status;
-
-       if (likely(!(sc->debug.level & ATH5K_DEBUG_RESET)))
-               return;
-
-       printk(KERN_DEBUG "rx queue %x, link %p\n",
-               ath5k_hw_get_rxdp(ah), sc->rxlink);
-
-       spin_lock_bh(&sc->rxbuflock);
-       list_for_each_entry(bf, &sc->rxbuf, list) {
-               ds = bf->desc;
-               status = ah->ah_proc_rx_desc(ah, ds, &rs);
-               if (!status)
-                       ath5k_debug_printrxbuf(bf, status == 0, &rs);
-       }
-       spin_unlock_bh(&sc->rxbuflock);
-}
-
-void
-ath5k_debug_dump_skb(struct ath5k_softc *sc,
-                       struct sk_buff *skb, const char *prefix, int tx)
-{
-       char buf[16];
-
-       if (likely(!((tx && (sc->debug.level & ATH5K_DEBUG_DUMP_TX)) ||
-                    (!tx && (sc->debug.level & ATH5K_DEBUG_DUMP_RX)))))
-               return;
-
-       snprintf(buf, sizeof(buf), "%s %s", wiphy_name(sc->hw->wiphy), prefix);
-
-       print_hex_dump_bytes(buf, DUMP_PREFIX_NONE, skb->data,
-               min(200U, skb->len));
-
-       printk(KERN_DEBUG "\n");
-}
-
-void
-ath5k_debug_printtxbuf(struct ath5k_softc *sc, struct ath5k_buf *bf)
-{
-       struct ath5k_desc *ds = bf->desc;
-       struct ath5k_hw_5212_tx_desc *td = &ds->ud.ds_tx5212;
-       struct ath5k_tx_status ts = {};
-       int done;
-
-       if (likely(!(sc->debug.level & ATH5K_DEBUG_RESET)))
-               return;
-
-       done = sc->ah->ah_proc_tx_desc(sc->ah, bf->desc, &ts);
-
-       printk(KERN_DEBUG "T (%p %llx) %08x %08x %08x %08x %08x %08x %08x "
-               "%08x %c\n", ds, (unsigned long long)bf->daddr, ds->ds_link,
-               ds->ds_data, td->tx_ctl.tx_control_0, td->tx_ctl.tx_control_1,
-               td->tx_ctl.tx_control_2, td->tx_ctl.tx_control_3,
-               td->tx_stat.tx_status_0, td->tx_stat.tx_status_1,
-               done ? ' ' : (ts.ts_status == 0) ? '*' : '!');
-}
-
-#endif /* ifdef CONFIG_ATH5K_DEBUG */
diff --git a/drivers/net/wireless/ath5k/debug.h b/drivers/net/wireless/ath5k/debug.h
deleted file mode 100644 (file)
index 66f69f0..0000000
+++ /dev/null
@@ -1,203 +0,0 @@
-/*
- * Copyright (c) 2007 Bruno Randolf <bruno@thinktube.com>
- *
- *  This file is free software: you may copy, redistribute 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 file 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, see <http://www.gnu.org/licenses/>.
- *
- *
- * This file incorporates work covered by the following copyright and
- * permission notice:
- *
- * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
- * Copyright (c) 2004-2005 Atheros Communications, Inc.
- * Copyright (c) 2006 Devicescape Software, Inc.
- * Copyright (c) 2007 Jiri Slaby <jirislaby@gmail.com>
- * Copyright (c) 2007 Luis R. Rodriguez <mcgrof@winlab.rutgers.edu>
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer,
- *    without modification.
- * 2. Redistributions in binary form must reproduce at minimum a disclaimer
- *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
- *    redistribution must be conditioned upon including a substantially
- *    similar Disclaimer requirement for further binary redistribution.
- * 3. Neither the names of the above-listed copyright holders nor the names
- *    of any contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * Alternatively, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") version 2 as published by the Free
- * Software Foundation.
- *
- * NO WARRANTY
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGES.
- */
-
-#ifndef _ATH5K_DEBUG_H
-#define _ATH5K_DEBUG_H
-
-struct ath5k_softc;
-struct ath5k_hw;
-struct sk_buff;
-struct ath5k_buf;
-
-struct ath5k_dbg_info {
-       unsigned int            level;          /* debug level */
-       /* debugfs entries */
-       struct dentry           *debugfs_phydir;
-       struct dentry           *debugfs_debug;
-       struct dentry           *debugfs_registers;
-       struct dentry           *debugfs_beacon;
-       struct dentry           *debugfs_reset;
-};
-
-/**
- * enum ath5k_debug_level - ath5k debug level
- *
- * @ATH5K_DEBUG_RESET: reset processing
- * @ATH5K_DEBUG_INTR: interrupt handling
- * @ATH5K_DEBUG_MODE: mode init/setup
- * @ATH5K_DEBUG_XMIT: basic xmit operation
- * @ATH5K_DEBUG_BEACON: beacon handling
- * @ATH5K_DEBUG_CALIBRATE: periodic calibration
- * @ATH5K_DEBUG_TXPOWER: transmit power setting
- * @ATH5K_DEBUG_LED: led management
- * @ATH5K_DEBUG_DUMP_RX: print received skb content
- * @ATH5K_DEBUG_DUMP_TX: print transmit skb content
- * @ATH5K_DEBUG_DUMPBANDS: dump bands
- * @ATH5K_DEBUG_TRACE: trace function calls
- * @ATH5K_DEBUG_ANY: show at any debug level
- *
- * The debug level is used to control the amount and type of debugging output
- * we want to see. The debug level is given in calls to ATH5K_DBG to specify
- * where the message should appear, and the user can control the debugging
- * messages he wants to see, either by the module parameter 'debug' on module
- * load, or dynamically by using debugfs 'ath5k/phyX/debug'. these levels can
- * be combined together by bitwise OR.
- */
-enum ath5k_debug_level {
-       ATH5K_DEBUG_RESET       = 0x00000001,
-       ATH5K_DEBUG_INTR        = 0x00000002,
-       ATH5K_DEBUG_MODE        = 0x00000004,
-       ATH5K_DEBUG_XMIT        = 0x00000008,
-       ATH5K_DEBUG_BEACON      = 0x00000010,
-       ATH5K_DEBUG_CALIBRATE   = 0x00000020,
-       ATH5K_DEBUG_TXPOWER     = 0x00000040,
-       ATH5K_DEBUG_LED         = 0x00000080,
-       ATH5K_DEBUG_DUMP_RX     = 0x00000100,
-       ATH5K_DEBUG_DUMP_TX     = 0x00000200,
-       ATH5K_DEBUG_DUMPBANDS   = 0x00000400,
-       ATH5K_DEBUG_TRACE       = 0x00001000,
-       ATH5K_DEBUG_ANY         = 0xffffffff
-};
-
-#ifdef CONFIG_ATH5K_DEBUG
-
-#define ATH5K_TRACE(_sc) do { \
-       if (unlikely((_sc)->debug.level & ATH5K_DEBUG_TRACE)) \
-               printk(KERN_DEBUG "ath5k trace %s:%d\n", __func__, __LINE__); \
-       } while (0)
-
-#define ATH5K_DBG(_sc, _m, _fmt, ...) do { \
-       if (unlikely((_sc)->debug.level & (_m) && net_ratelimit())) \
-               ATH5K_PRINTK(_sc, KERN_DEBUG, "(%s:%d): " _fmt, \
-                       __func__, __LINE__, ##__VA_ARGS__); \
-       } while (0)
-
-#define ATH5K_DBG_UNLIMIT(_sc, _m, _fmt, ...) do { \
-       if (unlikely((_sc)->debug.level & (_m))) \
-               ATH5K_PRINTK(_sc, KERN_DEBUG, "(%s:%d): " _fmt, \
-                       __func__, __LINE__, ##__VA_ARGS__); \
-       } while (0)
-
-void
-ath5k_debug_init(void);
-
-void
-ath5k_debug_init_device(struct ath5k_softc *sc);
-
-void
-ath5k_debug_finish(void);
-
-void
-ath5k_debug_finish_device(struct ath5k_softc *sc);
-
-void
-ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah);
-
-void
-ath5k_debug_dump_bands(struct ath5k_softc *sc);
-
-void
-ath5k_debug_dump_skb(struct ath5k_softc *sc,
-                       struct sk_buff *skb, const char *prefix, int tx);
-
-void
-ath5k_debug_printtxbuf(struct ath5k_softc *sc, struct ath5k_buf *bf);
-
-#else /* no debugging */
-
-#include <linux/compiler.h>
-
-#define ATH5K_TRACE(_sc) typecheck(struct ath5k_softc *, (_sc))
-
-static inline void __attribute__ ((format (printf, 3, 4)))
-ATH5K_DBG(struct ath5k_softc *sc, unsigned int m, const char *fmt, ...) {}
-
-static inline void __attribute__ ((format (printf, 3, 4)))
-ATH5K_DBG_UNLIMIT(struct ath5k_softc *sc, unsigned int m, const char *fmt, ...)
-{}
-
-static inline void
-ath5k_debug_init(void) {}
-
-static inline void
-ath5k_debug_init_device(struct ath5k_softc *sc) {}
-
-static inline void
-ath5k_debug_finish(void) {}
-
-static inline void
-ath5k_debug_finish_device(struct ath5k_softc *sc) {}
-
-static inline void
-ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah) {}
-
-static inline void
-ath5k_debug_dump_bands(struct ath5k_softc *sc) {}
-
-static inline void
-ath5k_debug_dump_skb(struct ath5k_softc *sc,
-                       struct sk_buff *skb, const char *prefix, int tx) {}
-
-static inline void
-ath5k_debug_printtxbuf(struct ath5k_softc *sc, struct ath5k_buf *bf) {}
-
-#endif /* ifdef CONFIG_ATH5K_DEBUG */
-
-#endif /* ifndef _ATH5K_DEBUG_H */
diff --git a/drivers/net/wireless/ath5k/desc.c b/drivers/net/wireless/ath5k/desc.c
deleted file mode 100644 (file)
index dc30a2b..0000000
+++ /dev/null
@@ -1,696 +0,0 @@
-/*
- * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
- * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
- * Copyright (c) 2007-2008 Pavel Roskin <proski@gnu.org>
- *
- * Permission to use, copy, modify, and 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.
- *
- */
-
-/******************************\
- Hardware Descriptor Functions
-\******************************/
-
-#include "ath5k.h"
-#include "reg.h"
-#include "debug.h"
-#include "base.h"
-
-/*
- * TX Descriptors
- */
-
-/*
- * Initialize the 2-word tx control descriptor on 5210/5211
- */
-static int
-ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
-       unsigned int pkt_len, unsigned int hdr_len, enum ath5k_pkt_type type,
-       unsigned int tx_power, unsigned int tx_rate0, unsigned int tx_tries0,
-       unsigned int key_index, unsigned int antenna_mode, unsigned int flags,
-       unsigned int rtscts_rate, unsigned int rtscts_duration)
-{
-       u32 frame_type;
-       struct ath5k_hw_2w_tx_ctl *tx_ctl;
-       unsigned int frame_len;
-
-       tx_ctl = &desc->ud.ds_tx5210.tx_ctl;
-
-       /*
-        * Validate input
-        * - Zero retries don't make sense.
-        * - A zero rate will put the HW into a mode where it continously sends
-        *   noise on the channel, so it is important to avoid this.
-        */
-       if (unlikely(tx_tries0 == 0)) {
-               ATH5K_ERR(ah->ah_sc, "zero retries\n");
-               WARN_ON(1);
-               return -EINVAL;
-       }
-       if (unlikely(tx_rate0 == 0)) {
-               ATH5K_ERR(ah->ah_sc, "zero rate\n");
-               WARN_ON(1);
-               return -EINVAL;
-       }
-
-       /* Clear descriptor */
-       memset(&desc->ud.ds_tx5210, 0, sizeof(struct ath5k_hw_5210_tx_desc));
-
-       /* Setup control descriptor */
-
-       /* Verify and set frame length */
-
-       /* remove padding we might have added before */
-       frame_len = pkt_len - ath5k_pad_size(hdr_len) + FCS_LEN;
-
-       if (frame_len & ~AR5K_2W_TX_DESC_CTL0_FRAME_LEN)
-               return -EINVAL;
-
-       tx_ctl->tx_control_0 = frame_len & AR5K_2W_TX_DESC_CTL0_FRAME_LEN;
-
-       /* Verify and set buffer length */
-
-       /* NB: beacon's BufLen must be a multiple of 4 bytes */
-       if (type == AR5K_PKT_TYPE_BEACON)
-               pkt_len = roundup(pkt_len, 4);
-
-       if (pkt_len & ~AR5K_2W_TX_DESC_CTL1_BUF_LEN)
-               return -EINVAL;
-
-       tx_ctl->tx_control_1 = pkt_len & AR5K_2W_TX_DESC_CTL1_BUF_LEN;
-
-       /*
-        * Verify and set header length
-        * XXX: I only found that on 5210 code, does it work on 5211 ?
-        */
-       if (ah->ah_version == AR5K_AR5210) {
-               if (hdr_len & ~AR5K_2W_TX_DESC_CTL0_HEADER_LEN)
-                       return -EINVAL;
-               tx_ctl->tx_control_0 |=
-                       AR5K_REG_SM(hdr_len, AR5K_2W_TX_DESC_CTL0_HEADER_LEN);
-       }
-
-       /*Diferences between 5210-5211*/
-       if (ah->ah_version == AR5K_AR5210) {
-               switch (type) {
-               case AR5K_PKT_TYPE_BEACON:
-               case AR5K_PKT_TYPE_PROBE_RESP:
-                       frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_NO_DELAY;
-               case AR5K_PKT_TYPE_PIFS:
-                       frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_PIFS;
-               default:
-                       frame_type = type /*<< 2 ?*/;
-               }
-
-               tx_ctl->tx_control_0 |=
-               AR5K_REG_SM(frame_type, AR5K_2W_TX_DESC_CTL0_FRAME_TYPE) |
-               AR5K_REG_SM(tx_rate0, AR5K_2W_TX_DESC_CTL0_XMIT_RATE);
-
-       } else {
-               tx_ctl->tx_control_0 |=
-                       AR5K_REG_SM(tx_rate0, AR5K_2W_TX_DESC_CTL0_XMIT_RATE) |
-                       AR5K_REG_SM(antenna_mode,
-                               AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT);
-               tx_ctl->tx_control_1 |=
-                       AR5K_REG_SM(type, AR5K_2W_TX_DESC_CTL1_FRAME_TYPE);
-       }
-#define _TX_FLAGS(_c, _flag)                                   \
-       if (flags & AR5K_TXDESC_##_flag) {                      \
-               tx_ctl->tx_control_##_c |=                      \
-                       AR5K_2W_TX_DESC_CTL##_c##_##_flag;      \
-       }
-
-       _TX_FLAGS(0, CLRDMASK);
-       _TX_FLAGS(0, VEOL);
-       _TX_FLAGS(0, INTREQ);
-       _TX_FLAGS(0, RTSENA);
-       _TX_FLAGS(1, NOACK);
-
-#undef _TX_FLAGS
-
-       /*
-        * WEP crap
-        */
-       if (key_index != AR5K_TXKEYIX_INVALID) {
-               tx_ctl->tx_control_0 |=
-                       AR5K_2W_TX_DESC_CTL0_ENCRYPT_KEY_VALID;
-               tx_ctl->tx_control_1 |=
-                       AR5K_REG_SM(key_index,
-                       AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX);
-       }
-
-       /*
-        * RTS/CTS Duration [5210 ?]
-        */
-       if ((ah->ah_version == AR5K_AR5210) &&
-                       (flags & (AR5K_TXDESC_RTSENA | AR5K_TXDESC_CTSENA)))
-               tx_ctl->tx_control_1 |= rtscts_duration &
-                               AR5K_2W_TX_DESC_CTL1_RTS_DURATION;
-
-       return 0;
-}
-
-/*
- * Initialize the 4-word tx control descriptor on 5212
- */
-static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah,
-       struct ath5k_desc *desc, unsigned int pkt_len, unsigned int hdr_len,
-       enum ath5k_pkt_type type, unsigned int tx_power, unsigned int tx_rate0,
-       unsigned int tx_tries0, unsigned int key_index,
-       unsigned int antenna_mode, unsigned int flags,
-       unsigned int rtscts_rate,
-       unsigned int rtscts_duration)
-{
-       struct ath5k_hw_4w_tx_ctl *tx_ctl;
-       unsigned int frame_len;
-
-       ATH5K_TRACE(ah->ah_sc);
-       tx_ctl = &desc->ud.ds_tx5212.tx_ctl;
-
-       /*
-        * Validate input
-        * - Zero retries don't make sense.
-        * - A zero rate will put the HW into a mode where it continously sends
-        *   noise on the channel, so it is important to avoid this.
-        */
-       if (unlikely(tx_tries0 == 0)) {
-               ATH5K_ERR(ah->ah_sc, "zero retries\n");
-               WARN_ON(1);
-               return -EINVAL;
-       }
-       if (unlikely(tx_rate0 == 0)) {
-               ATH5K_ERR(ah->ah_sc, "zero rate\n");
-               WARN_ON(1);
-               return -EINVAL;
-       }
-
-       tx_power += ah->ah_txpower.txp_offset;
-       if (tx_power > AR5K_TUNE_MAX_TXPOWER)
-               tx_power = AR5K_TUNE_MAX_TXPOWER;
-
-       /* Clear descriptor */
-       memset(&desc->ud.ds_tx5212, 0, sizeof(struct ath5k_hw_5212_tx_desc));
-
-       /* Setup control descriptor */
-
-       /* Verify and set frame length */
-
-       /* remove padding we might have added before */
-       frame_len = pkt_len - ath5k_pad_size(hdr_len) + FCS_LEN;
-
-       if (frame_len & ~AR5K_4W_TX_DESC_CTL0_FRAME_LEN)
-               return -EINVAL;
-
-       tx_ctl->tx_control_0 = frame_len & AR5K_4W_TX_DESC_CTL0_FRAME_LEN;
-
-       /* Verify and set buffer length */
-
-       /* NB: beacon's BufLen must be a multiple of 4 bytes */
-       if (type == AR5K_PKT_TYPE_BEACON)
-               pkt_len = roundup(pkt_len, 4);
-
-       if (pkt_len & ~AR5K_4W_TX_DESC_CTL1_BUF_LEN)
-               return -EINVAL;
-
-       tx_ctl->tx_control_1 = pkt_len & AR5K_4W_TX_DESC_CTL1_BUF_LEN;
-
-       tx_ctl->tx_control_0 |=
-               AR5K_REG_SM(tx_power, AR5K_4W_TX_DESC_CTL0_XMIT_POWER) |
-               AR5K_REG_SM(antenna_mode, AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT);
-       tx_ctl->tx_control_1 |= AR5K_REG_SM(type,
-                                       AR5K_4W_TX_DESC_CTL1_FRAME_TYPE);
-       tx_ctl->tx_control_2 = AR5K_REG_SM(tx_tries0 + AR5K_TUNE_HWTXTRIES,
-                                       AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0);
-       tx_ctl->tx_control_3 = tx_rate0 & AR5K_4W_TX_DESC_CTL3_XMIT_RATE0;
-
-#define _TX_FLAGS(_c, _flag)                                   \
-       if (flags & AR5K_TXDESC_##_flag) {                      \
-               tx_ctl->tx_control_##_c |=                      \
-                       AR5K_4W_TX_DESC_CTL##_c##_##_flag;      \
-       }
-
-       _TX_FLAGS(0, CLRDMASK);
-       _TX_FLAGS(0, VEOL);
-       _TX_FLAGS(0, INTREQ);
-       _TX_FLAGS(0, RTSENA);
-       _TX_FLAGS(0, CTSENA);
-       _TX_FLAGS(1, NOACK);
-
-#undef _TX_FLAGS
-
-       /*
-        * WEP crap
-        */
-       if (key_index != AR5K_TXKEYIX_INVALID) {
-               tx_ctl->tx_control_0 |= AR5K_4W_TX_DESC_CTL0_ENCRYPT_KEY_VALID;
-               tx_ctl->tx_control_1 |= AR5K_REG_SM(key_index,
-                               AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX);
-       }
-
-       /*
-        * RTS/CTS
-        */
-       if (flags & (AR5K_TXDESC_RTSENA | AR5K_TXDESC_CTSENA)) {
-               if ((flags & AR5K_TXDESC_RTSENA) &&
-                               (flags & AR5K_TXDESC_CTSENA))
-                       return -EINVAL;
-               tx_ctl->tx_control_2 |= rtscts_duration &
-                               AR5K_4W_TX_DESC_CTL2_RTS_DURATION;
-               tx_ctl->tx_control_3 |= AR5K_REG_SM(rtscts_rate,
-                               AR5K_4W_TX_DESC_CTL3_RTS_CTS_RATE);
-       }
-
-       return 0;
-}
-
-/*
- * Initialize a 4-word multi rate retry tx control descriptor on 5212
- */
-static int
-ath5k_hw_setup_mrr_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
-       unsigned int tx_rate1, u_int tx_tries1, u_int tx_rate2,
-       u_int tx_tries2, unsigned int tx_rate3, u_int tx_tries3)
-{
-       struct ath5k_hw_4w_tx_ctl *tx_ctl;
-
-       /*
-        * Rates can be 0 as long as the retry count is 0 too.
-        * A zero rate and nonzero retry count will put the HW into a mode where
-        * it continously sends noise on the channel, so it is important to
-        * avoid this.
-        */
-       if (unlikely((tx_rate1 == 0 && tx_tries1 != 0) ||
-                    (tx_rate2 == 0 && tx_tries2 != 0) ||
-                    (tx_rate3 == 0 && tx_tries3 != 0))) {
-               ATH5K_ERR(ah->ah_sc, "zero rate\n");
-               WARN_ON(1);
-               return -EINVAL;
-       }
-
-       if (ah->ah_version == AR5K_AR5212) {
-               tx_ctl = &desc->ud.ds_tx5212.tx_ctl;
-
-#define _XTX_TRIES(_n)                                                 \
-       if (tx_tries##_n) {                                             \
-               tx_ctl->tx_control_2 |=                                 \
-                   AR5K_REG_SM(tx_tries##_n,                           \
-                   AR5K_4W_TX_DESC_CTL2_XMIT_TRIES##_n);               \
-               tx_ctl->tx_control_3 |=                                 \
-                   AR5K_REG_SM(tx_rate##_n,                            \
-                   AR5K_4W_TX_DESC_CTL3_XMIT_RATE##_n);                \
-       }
-
-               _XTX_TRIES(1);
-               _XTX_TRIES(2);
-               _XTX_TRIES(3);
-
-#undef _XTX_TRIES
-
-               return 1;
-       }
-
-       return 0;
-}
-
-/* no mrr support for cards older than 5212 */
-static int
-ath5k_hw_setup_no_mrr(struct ath5k_hw *ah, struct ath5k_desc *desc,
-       unsigned int tx_rate1, u_int tx_tries1, u_int tx_rate2,
-       u_int tx_tries2, unsigned int tx_rate3, u_int tx_tries3)
-{
-       return 0;
-}
-
-/*
- * Proccess the tx status descriptor on 5210/5211
- */
-static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *ah,
-               struct ath5k_desc *desc, struct ath5k_tx_status *ts)
-{
-       struct ath5k_hw_2w_tx_ctl *tx_ctl;
-       struct ath5k_hw_tx_status *tx_status;
-
-       ATH5K_TRACE(ah->ah_sc);
-
-       tx_ctl = &desc->ud.ds_tx5210.tx_ctl;
-       tx_status = &desc->ud.ds_tx5210.tx_stat;
-
-       /* No frame has been send or error */
-       if (unlikely((tx_status->tx_status_1 & AR5K_DESC_TX_STATUS1_DONE) == 0))
-               return -EINPROGRESS;
-
-       /*
-        * Get descriptor status
-        */
-       ts->ts_tstamp = AR5K_REG_MS(tx_status->tx_status_0,
-               AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP);
-       ts->ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0,
-               AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT);
-       ts->ts_longretry = AR5K_REG_MS(tx_status->tx_status_0,
-               AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT);
-       /*TODO: ts->ts_virtcol + test*/
-       ts->ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1,
-               AR5K_DESC_TX_STATUS1_SEQ_NUM);
-       ts->ts_rssi = AR5K_REG_MS(tx_status->tx_status_1,
-               AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH);
-       ts->ts_antenna = 1;
-       ts->ts_status = 0;
-       ts->ts_rate[0] = AR5K_REG_MS(tx_ctl->tx_control_0,
-               AR5K_2W_TX_DESC_CTL0_XMIT_RATE);
-       ts->ts_retry[0] = ts->ts_longretry;
-       ts->ts_final_idx = 0;
-
-       if (!(tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) {
-               if (tx_status->tx_status_0 &
-                               AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES)
-                       ts->ts_status |= AR5K_TXERR_XRETRY;
-
-               if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN)
-                       ts->ts_status |= AR5K_TXERR_FIFO;
-
-               if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FILTERED)
-                       ts->ts_status |= AR5K_TXERR_FILT;
-       }
-
-       return 0;
-}
-
-/*
- * Proccess a tx status descriptor on 5212
- */
-static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah,
-               struct ath5k_desc *desc, struct ath5k_tx_status *ts)
-{
-       struct ath5k_hw_4w_tx_ctl *tx_ctl;
-       struct ath5k_hw_tx_status *tx_status;
-
-       ATH5K_TRACE(ah->ah_sc);
-
-       tx_ctl = &desc->ud.ds_tx5212.tx_ctl;
-       tx_status = &desc->ud.ds_tx5212.tx_stat;
-
-       /* No frame has been send or error */
-       if (unlikely(!(tx_status->tx_status_1 & AR5K_DESC_TX_STATUS1_DONE)))
-               return -EINPROGRESS;
-
-       /*
-        * Get descriptor status
-        */
-       ts->ts_tstamp = AR5K_REG_MS(tx_status->tx_status_0,
-               AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP);
-       ts->ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0,
-               AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT);
-       ts->ts_longretry = AR5K_REG_MS(tx_status->tx_status_0,
-               AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT);
-       ts->ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1,
-               AR5K_DESC_TX_STATUS1_SEQ_NUM);
-       ts->ts_rssi = AR5K_REG_MS(tx_status->tx_status_1,
-               AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH);
-       ts->ts_antenna = (tx_status->tx_status_1 &
-               AR5K_DESC_TX_STATUS1_XMIT_ANTENNA) ? 2 : 1;
-       ts->ts_status = 0;
-
-       ts->ts_final_idx = AR5K_REG_MS(tx_status->tx_status_1,
-                       AR5K_DESC_TX_STATUS1_FINAL_TS_INDEX);
-
-       /* The longretry counter has the number of un-acked retries
-        * for the final rate. To get the total number of retries
-        * we have to add the retry counters for the other rates
-        * as well
-        */
-       ts->ts_retry[ts->ts_final_idx] = ts->ts_longretry;
-       switch (ts->ts_final_idx) {
-       case 3:
-               ts->ts_rate[3] = AR5K_REG_MS(tx_ctl->tx_control_3,
-                       AR5K_4W_TX_DESC_CTL3_XMIT_RATE3);
-
-               ts->ts_retry[2] = AR5K_REG_MS(tx_ctl->tx_control_2,
-                       AR5K_4W_TX_DESC_CTL2_XMIT_TRIES2);
-               ts->ts_longretry += ts->ts_retry[2];
-               /* fall through */
-       case 2:
-               ts->ts_rate[2] = AR5K_REG_MS(tx_ctl->tx_control_3,
-                       AR5K_4W_TX_DESC_CTL3_XMIT_RATE2);
-
-               ts->ts_retry[1] = AR5K_REG_MS(tx_ctl->tx_control_2,
-                       AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1);
-               ts->ts_longretry += ts->ts_retry[1];
-               /* fall through */
-       case 1:
-               ts->ts_rate[1] = AR5K_REG_MS(tx_ctl->tx_control_3,
-                       AR5K_4W_TX_DESC_CTL3_XMIT_RATE1);
-
-               ts->ts_retry[0] = AR5K_REG_MS(tx_ctl->tx_control_2,
-                       AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1);
-               ts->ts_longretry += ts->ts_retry[0];
-               /* fall through */
-       case 0:
-               ts->ts_rate[0] = tx_ctl->tx_control_3 &
-                       AR5K_4W_TX_DESC_CTL3_XMIT_RATE0;
-               break;
-       }
-
-       /* TX error */
-       if (!(tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) {
-               if (tx_status->tx_status_0 &
-                               AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES)
-                       ts->ts_status |= AR5K_TXERR_XRETRY;
-
-               if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN)
-                       ts->ts_status |= AR5K_TXERR_FIFO;
-
-               if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FILTERED)
-                       ts->ts_status |= AR5K_TXERR_FILT;
-       }
-
-       return 0;
-}
-
-/*
- * RX Descriptors
- */
-
-/*
- * Initialize an rx control descriptor
- */
-static int ath5k_hw_setup_rx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
-                       u32 size, unsigned int flags)
-{
-       struct ath5k_hw_rx_ctl *rx_ctl;
-
-       ATH5K_TRACE(ah->ah_sc);
-       rx_ctl = &desc->ud.ds_rx.rx_ctl;
-
-       /*
-        * Clear the descriptor
-        * If we don't clean the status descriptor,
-        * while scanning we get too many results,
-        * most of them virtual, after some secs
-        * of scanning system hangs. M.F.
-       */
-       memset(&desc->ud.ds_rx, 0, sizeof(struct ath5k_hw_all_rx_desc));
-
-       /* Setup descriptor */
-       rx_ctl->rx_control_1 = size & AR5K_DESC_RX_CTL1_BUF_LEN;
-       if (unlikely(rx_ctl->rx_control_1 != size))
-               return -EINVAL;
-
-       if (flags & AR5K_RXDESC_INTREQ)
-               rx_ctl->rx_control_1 |= AR5K_DESC_RX_CTL1_INTREQ;
-
-       return 0;
-}
-
-/*
- * Proccess the rx status descriptor on 5210/5211
- */
-static int ath5k_hw_proc_5210_rx_status(struct ath5k_hw *ah,
-               struct ath5k_desc *desc, struct ath5k_rx_status *rs)
-{
-       struct ath5k_hw_rx_status *rx_status;
-
-       rx_status = &desc->ud.ds_rx.u.rx_stat;
-
-       /* No frame received / not ready */
-       if (unlikely(!(rx_status->rx_status_1 &
-       AR5K_5210_RX_DESC_STATUS1_DONE)))
-               return -EINPROGRESS;
-
-       /*
-        * Frame receive status
-        */
-       rs->rs_datalen = rx_status->rx_status_0 &
-               AR5K_5210_RX_DESC_STATUS0_DATA_LEN;
-       rs->rs_rssi = AR5K_REG_MS(rx_status->rx_status_0,
-               AR5K_5210_RX_DESC_STATUS0_RECEIVE_SIGNAL);
-       rs->rs_rate = AR5K_REG_MS(rx_status->rx_status_0,
-               AR5K_5210_RX_DESC_STATUS0_RECEIVE_RATE);
-       rs->rs_antenna = AR5K_REG_MS(rx_status->rx_status_0,
-               AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANTENNA);
-       rs->rs_more = !!(rx_status->rx_status_0 &
-               AR5K_5210_RX_DESC_STATUS0_MORE);
-       /* TODO: this timestamp is 13 bit, later on we assume 15 bit */
-       rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1,
-               AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP);
-       rs->rs_status = 0;
-       rs->rs_phyerr = 0;
-
-       /*
-        * Key table status
-        */
-       if (rx_status->rx_status_1 & AR5K_5210_RX_DESC_STATUS1_KEY_INDEX_VALID)
-               rs->rs_keyix = AR5K_REG_MS(rx_status->rx_status_1,
-                       AR5K_5210_RX_DESC_STATUS1_KEY_INDEX);
-       else
-               rs->rs_keyix = AR5K_RXKEYIX_INVALID;
-
-       /*
-        * Receive/descriptor errors
-        */
-       if (!(rx_status->rx_status_1 &
-       AR5K_5210_RX_DESC_STATUS1_FRAME_RECEIVE_OK)) {
-               if (rx_status->rx_status_1 &
-                               AR5K_5210_RX_DESC_STATUS1_CRC_ERROR)
-                       rs->rs_status |= AR5K_RXERR_CRC;
-
-               if (rx_status->rx_status_1 &
-                               AR5K_5210_RX_DESC_STATUS1_FIFO_OVERRUN)
-                       rs->rs_status |= AR5K_RXERR_FIFO;
-
-               if (rx_status->rx_status_1 &
-                               AR5K_5210_RX_DESC_STATUS1_PHY_ERROR) {
-                       rs->rs_status |= AR5K_RXERR_PHY;
-                       rs->rs_phyerr |= AR5K_REG_MS(rx_status->rx_status_1,
-                               AR5K_5210_RX_DESC_STATUS1_PHY_ERROR);
-               }
-
-               if (rx_status->rx_status_1 &
-                               AR5K_5210_RX_DESC_STATUS1_DECRYPT_CRC_ERROR)
-                       rs->rs_status |= AR5K_RXERR_DECRYPT;
-       }
-
-       return 0;
-}
-
-/*
- * Proccess the rx status descriptor on 5212
- */
-static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah,
-               struct ath5k_desc *desc, struct ath5k_rx_status *rs)
-{
-       struct ath5k_hw_rx_status *rx_status;
-       struct ath5k_hw_rx_error *rx_err;
-
-       ATH5K_TRACE(ah->ah_sc);
-       rx_status = &desc->ud.ds_rx.u.rx_stat;
-
-       /* Overlay on error */
-       rx_err = &desc->ud.ds_rx.u.rx_err;
-
-       /* No frame received / not ready */
-       if (unlikely(!(rx_status->rx_status_1 &
-       AR5K_5212_RX_DESC_STATUS1_DONE)))
-               return -EINPROGRESS;
-
-       /*
-        * Frame receive status
-        */
-       rs->rs_datalen = rx_status->rx_status_0 &
-               AR5K_5212_RX_DESC_STATUS0_DATA_LEN;
-       rs->rs_rssi = AR5K_REG_MS(rx_status->rx_status_0,
-               AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL);
-       rs->rs_rate = AR5K_REG_MS(rx_status->rx_status_0,
-               AR5K_5212_RX_DESC_STATUS0_RECEIVE_RATE);
-       rs->rs_antenna = AR5K_REG_MS(rx_status->rx_status_0,
-               AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA);
-       rs->rs_more = !!(rx_status->rx_status_0 &
-               AR5K_5212_RX_DESC_STATUS0_MORE);
-       rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1,
-               AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP);
-       rs->rs_status = 0;
-       rs->rs_phyerr = 0;
-
-       /*
-        * Key table status
-        */
-       if (rx_status->rx_status_1 & AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_VALID)
-               rs->rs_keyix = AR5K_REG_MS(rx_status->rx_status_1,
-                               AR5K_5212_RX_DESC_STATUS1_KEY_INDEX);
-       else
-               rs->rs_keyix = AR5K_RXKEYIX_INVALID;
-
-       /*
-        * Receive/descriptor errors
-        */
-       if (!(rx_status->rx_status_1 &
-       AR5K_5212_RX_DESC_STATUS1_FRAME_RECEIVE_OK)) {
-               if (rx_status->rx_status_1 &
-                               AR5K_5212_RX_DESC_STATUS1_CRC_ERROR)
-                       rs->rs_status |= AR5K_RXERR_CRC;
-
-               if (rx_status->rx_status_1 &
-                               AR5K_5212_RX_DESC_STATUS1_PHY_ERROR) {
-                       rs->rs_status |= AR5K_RXERR_PHY;
-                       rs->rs_phyerr |= AR5K_REG_MS(rx_err->rx_error_1,
-                                          AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE);
-               }
-
-               if (rx_status->rx_status_1 &
-                               AR5K_5212_RX_DESC_STATUS1_DECRYPT_CRC_ERROR)
-                       rs->rs_status |= AR5K_RXERR_DECRYPT;
-
-               if (rx_status->rx_status_1 &
-                               AR5K_5212_RX_DESC_STATUS1_MIC_ERROR)
-                       rs->rs_status |= AR5K_RXERR_MIC;
-       }
-
-       return 0;
-}
-
-/*
- * Init function pointers inside ath5k_hw struct
- */
-int ath5k_hw_init_desc_functions(struct ath5k_hw *ah)
-{
-
-       if (ah->ah_version != AR5K_AR5210 &&
-               ah->ah_version != AR5K_AR5211 &&
-               ah->ah_version != AR5K_AR5212)
-                       return -ENOTSUPP;
-
-       /* XXX: What is this magic value and where is it used ? */
-       if (ah->ah_version == AR5K_AR5212)
-               ah->ah_magic = AR5K_EEPROM_MAGIC_5212;
-       else if (ah->ah_version == AR5K_AR5211)
-               ah->ah_magic = AR5K_EEPROM_MAGIC_5211;
-
-       if (ah->ah_version == AR5K_AR5212) {
-               ah->ah_setup_rx_desc = ath5k_hw_setup_rx_desc;
-               ah->ah_setup_tx_desc = ath5k_hw_setup_4word_tx_desc;
-               ah->ah_setup_mrr_tx_desc = ath5k_hw_setup_mrr_tx_desc;
-               ah->ah_proc_tx_desc = ath5k_hw_proc_4word_tx_status;
-       } else {
-               ah->ah_setup_rx_desc = ath5k_hw_setup_rx_desc;
-               ah->ah_setup_tx_desc = ath5k_hw_setup_2word_tx_desc;
-               ah->ah_setup_mrr_tx_desc = ath5k_hw_setup_no_mrr;
-               ah->ah_proc_tx_desc = ath5k_hw_proc_2word_tx_status;
-       }
-
-       if (ah->ah_version == AR5K_AR5212)
-               ah->ah_proc_rx_desc = ath5k_hw_proc_5212_rx_status;
-       else if (ah->ah_version <= AR5K_AR5211)
-               ah->ah_proc_rx_desc = ath5k_hw_proc_5210_rx_status;
-
-       return 0;
-}
-
diff --git a/drivers/net/wireless/ath5k/desc.h b/drivers/net/wireless/ath5k/desc.h
deleted file mode 100644 (file)
index 56158c8..0000000
+++ /dev/null
@@ -1,332 +0,0 @@
-/*
- * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
- * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
- *
- * Permission to use, copy, modify, and 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 RX/TX descriptor structures
- * (rX: reserved fields possibily used by future versions of the ar5k chipset)
- */
-
-/*
- * common hardware RX control descriptor
- */
-struct ath5k_hw_rx_ctl {
-       u32     rx_control_0; /* RX control word 0 */
-       u32     rx_control_1; /* RX control word 1 */
-} __packed;
-
-/* RX control word 0 field/sflags */
-#define AR5K_DESC_RX_CTL0                      0x00000000
-
-/* RX control word 1 fields/flags */
-#define AR5K_DESC_RX_CTL1_BUF_LEN              0x00000fff
-#define AR5K_DESC_RX_CTL1_INTREQ               0x00002000
-
-/*
- * common hardware RX status descriptor
- * 5210/11 and 5212 differ only in the flags defined below
- */
-struct ath5k_hw_rx_status {
-       u32     rx_status_0; /* RX status word 0 */
-       u32     rx_status_1; /* RX status word 1 */
-} __packed;
-
-/* 5210/5211 */
-/* RX status word 0 fields/flags */
-#define AR5K_5210_RX_DESC_STATUS0_DATA_LEN             0x00000fff
-#define AR5K_5210_RX_DESC_STATUS0_MORE                 0x00001000
-#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_RATE         0x00078000
-#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_RATE_S       15
-#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_SIGNAL       0x07f80000
-#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_SIGNAL_S     19
-#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANTENNA      0x38000000
-#define AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANTENNA_S    27
-
-/* RX status word 1 fields/flags */
-#define AR5K_5210_RX_DESC_STATUS1_DONE                 0x00000001
-#define AR5K_5210_RX_DESC_STATUS1_FRAME_RECEIVE_OK     0x00000002
-#define AR5K_5210_RX_DESC_STATUS1_CRC_ERROR            0x00000004
-#define AR5K_5210_RX_DESC_STATUS1_FIFO_OVERRUN         0x00000008
-#define AR5K_5210_RX_DESC_STATUS1_DECRYPT_CRC_ERROR    0x00000010
-#define AR5K_5210_RX_DESC_STATUS1_PHY_ERROR            0x000000e0
-#define AR5K_5210_RX_DESC_STATUS1_PHY_ERROR_S          5
-#define AR5K_5210_RX_DESC_STATUS1_KEY_INDEX_VALID      0x00000100
-#define AR5K_5210_RX_DESC_STATUS1_KEY_INDEX            0x00007e00
-#define AR5K_5210_RX_DESC_STATUS1_KEY_INDEX_S          9
-#define AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP    0x0fff8000
-#define AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP_S  15
-#define AR5K_5210_RX_DESC_STATUS1_KEY_CACHE_MISS       0x10000000
-
-/* 5212 */
-/* RX status word 0 fields/flags */
-#define AR5K_5212_RX_DESC_STATUS0_DATA_LEN             0x00000fff
-#define AR5K_5212_RX_DESC_STATUS0_MORE                 0x00001000
-#define AR5K_5212_RX_DESC_STATUS0_DECOMP_CRC_ERROR     0x00002000
-#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_RATE         0x000f8000
-#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_RATE_S       15
-#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL       0x0ff00000
-#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL_S     20
-#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA      0xf0000000
-#define AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA_S    28
-
-/* RX status word 1 fields/flags */
-#define AR5K_5212_RX_DESC_STATUS1_DONE                 0x00000001
-#define AR5K_5212_RX_DESC_STATUS1_FRAME_RECEIVE_OK     0x00000002
-#define AR5K_5212_RX_DESC_STATUS1_CRC_ERROR            0x00000004
-#define AR5K_5212_RX_DESC_STATUS1_DECRYPT_CRC_ERROR    0x00000008
-#define AR5K_5212_RX_DESC_STATUS1_PHY_ERROR            0x00000010
-#define AR5K_5212_RX_DESC_STATUS1_MIC_ERROR            0x00000020
-#define AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_VALID      0x00000100
-#define AR5K_5212_RX_DESC_STATUS1_KEY_INDEX            0x0000fe00
-#define AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_S          9
-#define AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP    0x7fff0000
-#define AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP_S  16
-#define AR5K_5212_RX_DESC_STATUS1_KEY_CACHE_MISS       0x80000000
-
-/*
- * common hardware RX error descriptor
- */
-struct ath5k_hw_rx_error {
-       u32     rx_error_0; /* RX status word 0 */
-       u32     rx_error_1; /* RX status word 1 */
-} __packed;
-
-/* RX error word 0 fields/flags */
-#define AR5K_RX_DESC_ERROR0                    0x00000000
-
-/* RX error word 1 fields/flags */
-#define AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE     0x0000ff00
-#define AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE_S   8
-
-/* PHY Error codes */
-#define AR5K_DESC_RX_PHY_ERROR_NONE            0x00
-#define AR5K_DESC_RX_PHY_ERROR_TIMING          0x20
-#define AR5K_DESC_RX_PHY_ERROR_PARITY          0x40
-#define AR5K_DESC_RX_PHY_ERROR_RATE            0x60
-#define AR5K_DESC_RX_PHY_ERROR_LENGTH          0x80
-#define AR5K_DESC_RX_PHY_ERROR_64QAM           0xa0
-#define AR5K_DESC_RX_PHY_ERROR_SERVICE         0xc0
-#define AR5K_DESC_RX_PHY_ERROR_TRANSMITOVR     0xe0
-
-/*
- * 5210/5211 hardware 2-word TX control descriptor
- */
-struct ath5k_hw_2w_tx_ctl {
-       u32     tx_control_0; /* TX control word 0 */
-       u32     tx_control_1; /* TX control word 1 */
-} __packed;
-
-/* TX control word 0 fields/flags */
-#define AR5K_2W_TX_DESC_CTL0_FRAME_LEN         0x00000fff
-#define AR5K_2W_TX_DESC_CTL0_HEADER_LEN                0x0003f000 /*[5210 ?]*/
-#define AR5K_2W_TX_DESC_CTL0_HEADER_LEN_S      12
-#define AR5K_2W_TX_DESC_CTL0_XMIT_RATE         0x003c0000
-#define AR5K_2W_TX_DESC_CTL0_XMIT_RATE_S       18
-#define AR5K_2W_TX_DESC_CTL0_RTSENA            0x00400000
-#define AR5K_2W_TX_DESC_CTL0_CLRDMASK          0x01000000
-#define AR5K_2W_TX_DESC_CTL0_LONG_PACKET       0x00800000 /*[5210]*/
-#define AR5K_2W_TX_DESC_CTL0_VEOL              0x00800000 /*[5211]*/
-#define AR5K_2W_TX_DESC_CTL0_FRAME_TYPE                0x1c000000 /*[5210]*/
-#define AR5K_2W_TX_DESC_CTL0_FRAME_TYPE_S      26
-#define AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_5210        0x02000000
-#define AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_5211        0x1e000000
-
-#define AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT                     \
-               (ah->ah_version == AR5K_AR5210 ?                \
-               AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_5210 :       \
-               AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_5211)
-
-#define AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_S   25
-#define AR5K_2W_TX_DESC_CTL0_INTREQ            0x20000000
-#define AR5K_2W_TX_DESC_CTL0_ENCRYPT_KEY_VALID 0x40000000
-
-/* TX control word 1 fields/flags */
-#define AR5K_2W_TX_DESC_CTL1_BUF_LEN           0x00000fff
-#define AR5K_2W_TX_DESC_CTL1_MORE              0x00001000
-#define AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX_5210    0x0007e000
-#define AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX_5211    0x000fe000
-
-#define AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX                         \
-                       (ah->ah_version == AR5K_AR5210 ?                \
-                       AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX_5210 :   \
-                       AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX_5211)
-
-#define AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX_S       13
-#define AR5K_2W_TX_DESC_CTL1_FRAME_TYPE                0x00700000 /*[5211]*/
-#define AR5K_2W_TX_DESC_CTL1_FRAME_TYPE_S      20
-#define AR5K_2W_TX_DESC_CTL1_NOACK             0x00800000 /*[5211]*/
-#define AR5K_2W_TX_DESC_CTL1_RTS_DURATION      0xfff80000 /*[5210 ?]*/
-
-/* Frame types */
-#define AR5K_AR5210_TX_DESC_FRAME_TYPE_NORMAL   0x00
-#define AR5K_AR5210_TX_DESC_FRAME_TYPE_ATIM     0x04
-#define AR5K_AR5210_TX_DESC_FRAME_TYPE_PSPOLL   0x08
-#define AR5K_AR5210_TX_DESC_FRAME_TYPE_NO_DELAY 0x0c
-#define AR5K_AR5210_TX_DESC_FRAME_TYPE_PIFS     0x10
-
-/*
- * 5212 hardware 4-word TX control descriptor
- */
-struct ath5k_hw_4w_tx_ctl {
-       u32     tx_control_0; /* TX control word 0 */
-
-#define AR5K_4W_TX_DESC_CTL0_FRAME_LEN         0x00000fff
-#define AR5K_4W_TX_DESC_CTL0_XMIT_POWER                0x003f0000
-#define AR5K_4W_TX_DESC_CTL0_XMIT_POWER_S      16
-#define AR5K_4W_TX_DESC_CTL0_RTSENA            0x00400000
-#define AR5K_4W_TX_DESC_CTL0_VEOL              0x00800000
-#define AR5K_4W_TX_DESC_CTL0_CLRDMASK          0x01000000
-#define AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT     0x1e000000
-#define AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT_S   25
-#define AR5K_4W_TX_DESC_CTL0_INTREQ            0x20000000
-#define AR5K_4W_TX_DESC_CTL0_ENCRYPT_KEY_VALID 0x40000000
-#define AR5K_4W_TX_DESC_CTL0_CTSENA            0x80000000
-
-       u32     tx_control_1; /* TX control word 1 */
-
-#define AR5K_4W_TX_DESC_CTL1_BUF_LEN           0x00000fff
-#define AR5K_4W_TX_DESC_CTL1_MORE              0x00001000
-#define AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX 0x000fe000
-#define AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX_S       13
-#define AR5K_4W_TX_DESC_CTL1_FRAME_TYPE                0x00f00000
-#define AR5K_4W_TX_DESC_CTL1_FRAME_TYPE_S      20
-#define AR5K_4W_TX_DESC_CTL1_NOACK             0x01000000
-#define AR5K_4W_TX_DESC_CTL1_COMP_PROC         0x06000000
-#define AR5K_4W_TX_DESC_CTL1_COMP_PROC_S       25
-#define AR5K_4W_TX_DESC_CTL1_COMP_IV_LEN       0x18000000
-#define AR5K_4W_TX_DESC_CTL1_COMP_IV_LEN_S     27
-#define AR5K_4W_TX_DESC_CTL1_COMP_ICV_LEN      0x60000000
-#define AR5K_4W_TX_DESC_CTL1_COMP_ICV_LEN_S    29
-
-       u32     tx_control_2; /* TX control word 2 */
-
-#define AR5K_4W_TX_DESC_CTL2_RTS_DURATION              0x00007fff
-#define AR5K_4W_TX_DESC_CTL2_DURATION_UPDATE_ENABLE    0x00008000
-#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0               0x000f0000
-#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0_S             16
-#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1               0x00f00000
-#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1_S             20
-#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES2               0x0f000000
-#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES2_S             24
-#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES3               0xf0000000
-#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES3_S             28
-
-       u32     tx_control_3; /* TX control word 3 */
-
-#define AR5K_4W_TX_DESC_CTL3_XMIT_RATE0                0x0000001f
-#define AR5K_4W_TX_DESC_CTL3_XMIT_RATE1                0x000003e0
-#define AR5K_4W_TX_DESC_CTL3_XMIT_RATE1_S      5
-#define AR5K_4W_TX_DESC_CTL3_XMIT_RATE2                0x00007c00
-#define AR5K_4W_TX_DESC_CTL3_XMIT_RATE2_S      10
-#define AR5K_4W_TX_DESC_CTL3_XMIT_RATE3                0x000f8000
-#define AR5K_4W_TX_DESC_CTL3_XMIT_RATE3_S      15
-#define AR5K_4W_TX_DESC_CTL3_RTS_CTS_RATE      0x01f00000
-#define AR5K_4W_TX_DESC_CTL3_RTS_CTS_RATE_S    20
-} __packed;
-
-/*
- * Common TX status descriptor
- */
-struct ath5k_hw_tx_status {
-       u32     tx_status_0; /* TX status word 0 */
-       u32     tx_status_1; /* TX status word 1 */
-} __packed;
-
-/* TX status word 0 fields/flags */
-#define AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK     0x00000001
-#define AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES 0x00000002
-#define AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN     0x00000004
-#define AR5K_DESC_TX_STATUS0_FILTERED          0x00000008
-/*???
-#define AR5K_DESC_TX_STATUS0_RTS_FAIL_COUNT    0x000000f0
-#define AR5K_DESC_TX_STATUS0_RTS_FAIL_COUNT_S  4
-*/
-#define AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT 0x000000f0
-#define AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT_S       4
-/*???
-#define AR5K_DESC_TX_STATUS0_DATA_FAIL_COUNT   0x00000f00
-#define AR5K_DESC_TX_STATUS0_DATA_FAIL_COUNT_S 8
-*/
-#define AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT  0x00000f00
-#define AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT_S        8
-#define AR5K_DESC_TX_STATUS0_VIRT_COLL_COUNT   0x0000f000
-#define AR5K_DESC_TX_STATUS0_VIRT_COLL_COUNT_S 12
-#define AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP    0xffff0000
-#define AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP_S  16
-
-/* TX status word 1 fields/flags */
-#define AR5K_DESC_TX_STATUS1_DONE              0x00000001
-#define AR5K_DESC_TX_STATUS1_SEQ_NUM           0x00001ffe
-#define AR5K_DESC_TX_STATUS1_SEQ_NUM_S         1
-#define AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH  0x001fe000
-#define AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH_S        13
-#define AR5K_DESC_TX_STATUS1_FINAL_TS_INDEX    0x00600000
-#define AR5K_DESC_TX_STATUS1_FINAL_TS_INDEX_S  21
-#define AR5K_DESC_TX_STATUS1_COMP_SUCCESS      0x00800000
-#define AR5K_DESC_TX_STATUS1_XMIT_ANTENNA      0x01000000
-
-/*
- * 5210/5211 hardware TX descriptor
- */
-struct ath5k_hw_5210_tx_desc {
-       struct ath5k_hw_2w_tx_ctl       tx_ctl;
-       struct ath5k_hw_tx_status       tx_stat;
-} __packed;
-
-/*
- * 5212 hardware TX descriptor
- */
-struct ath5k_hw_5212_tx_desc {
-       struct ath5k_hw_4w_tx_ctl       tx_ctl;
-       struct ath5k_hw_tx_status       tx_stat;
-} __packed;
-
-/*
- * common hardware RX descriptor
- */
-struct ath5k_hw_all_rx_desc {
-       struct ath5k_hw_rx_ctl                  rx_ctl;
-       union {
-               struct ath5k_hw_rx_status       rx_stat;
-               struct ath5k_hw_rx_error        rx_err;
-       } u;
-} __packed;
-
-/*
- * Atheros hardware descriptor
- * This is read and written to by the hardware
- */
-struct ath5k_desc {
-       u32     ds_link;        /* physical address of the next descriptor */
-       u32     ds_data;        /* physical address of data buffer (skb) */
-
-       union {
-               struct ath5k_hw_5210_tx_desc    ds_tx5210;
-               struct ath5k_hw_5212_tx_desc    ds_tx5212;
-               struct ath5k_hw_all_rx_desc     ds_rx;
-       } ud;
-} __packed;
-
-#define AR5K_RXDESC_INTREQ     0x0020
-
-#define AR5K_TXDESC_CLRDMASK   0x0001
-#define AR5K_TXDESC_NOACK      0x0002  /*[5211+]*/
-#define AR5K_TXDESC_RTSENA     0x0004
-#define AR5K_TXDESC_CTSENA     0x0008
-#define AR5K_TXDESC_INTREQ     0x0010
-#define AR5K_TXDESC_VEOL       0x0020  /*[5211+]*/
-
diff --git a/drivers/net/wireless/ath5k/dma.c b/drivers/net/wireless/ath5k/dma.c
deleted file mode 100644 (file)
index b65b4fe..0000000
+++ /dev/null
@@ -1,705 +0,0 @@
-/*
- * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
- * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
- *
- * Permission to use, copy, modify, and 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.
- *
- */
-
-/*************************************\
-* DMA and interrupt masking functions *
-\*************************************/
-
-/*
- * dma.c - DMA and interrupt masking functions
- *
- * Here we setup descriptor pointers (rxdp/txdp) start/stop dma engine and
- * handle queue setup for 5210 chipset (rest are handled on qcu.c).
- * Also we setup interrupt mask register (IMR) and read the various iterrupt
- * status registers (ISR).
- *
- * TODO: Handle SISR on 5211+ and introduce a function to return the queue
- * number that resulted the interrupt.
- */
-
-#include "ath5k.h"
-#include "reg.h"
-#include "debug.h"
-#include "base.h"
-
-/*********\
-* Receive *
-\*********/
-
-/**
- * ath5k_hw_start_rx_dma - Start DMA receive
- *
- * @ah:        The &struct ath5k_hw
- */
-void ath5k_hw_start_rx_dma(struct ath5k_hw *ah)
-{
-       ATH5K_TRACE(ah->ah_sc);
-       ath5k_hw_reg_write(ah, AR5K_CR_RXE, AR5K_CR);
-       ath5k_hw_reg_read(ah, AR5K_CR);
-}
-
-/**
- * ath5k_hw_stop_rx_dma - Stop DMA receive
- *
- * @ah:        The &struct ath5k_hw
- */
-int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah)
-{
-       unsigned int i;
-
-       ATH5K_TRACE(ah->ah_sc);
-       ath5k_hw_reg_write(ah, AR5K_CR_RXD, AR5K_CR);
-
-       /*
-        * It may take some time to disable the DMA receive unit
-        */
-       for (i = 1000; i > 0 &&
-                       (ath5k_hw_reg_read(ah, AR5K_CR) & AR5K_CR_RXE) != 0;
-                       i--)
-               udelay(10);
-
-       return i ? 0 : -EBUSY;
-}
-
-/**
- * ath5k_hw_get_rxdp - Get RX Descriptor's address
- *
- * @ah: The &struct ath5k_hw
- *
- * XXX: Is RXDP read and clear ?
- */
-u32 ath5k_hw_get_rxdp(struct ath5k_hw *ah)
-{
-       return ath5k_hw_reg_read(ah, AR5K_RXDP);
-}
-
-/**
- * ath5k_hw_set_rxdp - Set RX Descriptor's address
- *
- * @ah: The &struct ath5k_hw
- * @phys_addr: RX descriptor address
- *
- * XXX: Should we check if rx is enabled before setting rxdp ?
- */
-void ath5k_hw_set_rxdp(struct ath5k_hw *ah, u32 phys_addr)
-{
-       ATH5K_TRACE(ah->ah_sc);
-
-       ath5k_hw_reg_write(ah, phys_addr, AR5K_RXDP);
-}
-
-
-/**********\
-* Transmit *
-\**********/
-
-/**
- * ath5k_hw_start_tx_dma - Start DMA transmit for a specific queue
- *
- * @ah: The &struct ath5k_hw
- * @queue: The hw queue number
- *
- * Start DMA transmit for a specific queue and since 5210 doesn't have
- * QCU/DCU, set up queue parameters for 5210 here based on queue type (one
- * queue for normal data and one queue for beacons). For queue setup
- * on newer chips check out qcu.c. Returns -EINVAL if queue number is out
- * of range or if queue is already disabled.
- *
- * NOTE: Must be called after setting up tx control descriptor for that
- * queue (see below).
- */
-int ath5k_hw_start_tx_dma(struct ath5k_hw *ah, unsigned int queue)
-{
-       u32 tx_queue;
-
-       ATH5K_TRACE(ah->ah_sc);
-       AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
-
-       /* Return if queue is declared inactive */
-       if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
-               return -EIO;
-
-       if (ah->ah_version == AR5K_AR5210) {
-               tx_queue = ath5k_hw_reg_read(ah, AR5K_CR);
-
-               /*
-                * Set the queue by type on 5210
-                */
-               switch (ah->ah_txq[queue].tqi_type) {
-               case AR5K_TX_QUEUE_DATA:
-                       tx_queue |= AR5K_CR_TXE0 & ~AR5K_CR_TXD0;
-                       break;
-               case AR5K_TX_QUEUE_BEACON:
-                       tx_queue |= AR5K_CR_TXE1 & ~AR5K_CR_TXD1;
-                       ath5k_hw_reg_write(ah, AR5K_BCR_TQ1V | AR5K_BCR_BDMAE,
-                                       AR5K_BSR);
-                       break;
-               case AR5K_TX_QUEUE_CAB:
-                       tx_queue |= AR5K_CR_TXE1 & ~AR5K_CR_TXD1;
-                       ath5k_hw_reg_write(ah, AR5K_BCR_TQ1FV | AR5K_BCR_TQ1V |
-                               AR5K_BCR_BDMAE, AR5K_BSR);
-                       break;
-               default:
-                       return -EINVAL;
-               }
-               /* Start queue */
-               ath5k_hw_reg_write(ah, tx_queue, AR5K_CR);
-               ath5k_hw_reg_read(ah, AR5K_CR);
-       } else {
-               /* Return if queue is disabled */
-               if (AR5K_REG_READ_Q(ah, AR5K_QCU_TXD, queue))
-                       return -EIO;
-
-               /* Start queue */
-               AR5K_REG_WRITE_Q(ah, AR5K_QCU_TXE, queue);
-       }
-
-       return 0;
-}
-
-/**
- * ath5k_hw_stop_tx_dma - Stop DMA transmit on a specific queue
- *
- * @ah: The &struct ath5k_hw
- * @queue: The hw queue number
- *
- * Stop DMA transmit on a specific hw queue and drain queue so we don't
- * have any pending frames. Returns -EBUSY if we still have pending frames,
- * -EINVAL if queue number is out of range.
- *
- */
-int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue)
-{
-       unsigned int i = 40;
-       u32 tx_queue, pending;
-
-       ATH5K_TRACE(ah->ah_sc);
-       AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
-
-       /* Return if queue is declared inactive */
-       if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
-               return -EIO;
-
-       if (ah->ah_version == AR5K_AR5210) {
-               tx_queue = ath5k_hw_reg_read(ah, AR5K_CR);
-
-               /*
-                * Set by queue type
-                */
-               switch (ah->ah_txq[queue].tqi_type) {
-               case AR5K_TX_QUEUE_DATA:
-                       tx_queue |= AR5K_CR_TXD0 & ~AR5K_CR_TXE0;
-                       break;
-               case AR5K_TX_QUEUE_BEACON:
-               case AR5K_TX_QUEUE_CAB:
-                       /* XXX Fix me... */
-                       tx_queue |= AR5K_CR_TXD1 & ~AR5K_CR_TXD1;
-                       ath5k_hw_reg_write(ah, 0, AR5K_BSR);
-                       break;
-               default:
-                       return -EINVAL;
-               }
-
-               /* Stop queue */
-               ath5k_hw_reg_write(ah, tx_queue, AR5K_CR);
-               ath5k_hw_reg_read(ah, AR5K_CR);
-       } else {
-               /*
-                * Schedule TX disable and wait until queue is empty
-                */
-               AR5K_REG_WRITE_Q(ah, AR5K_QCU_TXD, queue);
-
-               /*Check for pending frames*/
-               do {
-                       pending = ath5k_hw_reg_read(ah,
-                               AR5K_QUEUE_STATUS(queue)) &
-                               AR5K_QCU_STS_FRMPENDCNT;
-                       udelay(100);
-               } while (--i && pending);
-
-               /* For 2413+ order PCU to drop packets using
-                * QUIET mechanism */
-               if (ah->ah_mac_version >= (AR5K_SREV_AR2414 >> 4) &&
-               pending){
-                       /* Set periodicity and duration */
-                       ath5k_hw_reg_write(ah,
-                               AR5K_REG_SM(100, AR5K_QUIET_CTL2_QT_PER)|
-                               AR5K_REG_SM(10, AR5K_QUIET_CTL2_QT_DUR),
-                               AR5K_QUIET_CTL2);
-
-                       /* Enable quiet period for current TSF */
-                       ath5k_hw_reg_write(ah,
-                               AR5K_QUIET_CTL1_QT_EN |
-                               AR5K_REG_SM(ath5k_hw_reg_read(ah,
-                                               AR5K_TSF_L32_5211) >> 10,
-                                               AR5K_QUIET_CTL1_NEXT_QT_TSF),
-                               AR5K_QUIET_CTL1);
-
-                       /* Force channel idle high */
-                       AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW_5211,
-                                       AR5K_DIAG_SW_CHANEL_IDLE_HIGH);
-
-                       /* Wait a while and disable mechanism */
-                       udelay(200);
-                       AR5K_REG_DISABLE_BITS(ah, AR5K_QUIET_CTL1,
-                                               AR5K_QUIET_CTL1_QT_EN);
-
-                       /* Re-check for pending frames */
-                       i = 40;
-                       do {
-                               pending = ath5k_hw_reg_read(ah,
-                                       AR5K_QUEUE_STATUS(queue)) &
-                                       AR5K_QCU_STS_FRMPENDCNT;
-                               udelay(100);
-                       } while (--i && pending);
-
-                       AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW_5211,
-                                       AR5K_DIAG_SW_CHANEL_IDLE_HIGH);
-               }
-
-               /* Clear register */
-               ath5k_hw_reg_write(ah, 0, AR5K_QCU_TXD);
-               if (pending)
-                       return -EBUSY;
-       }
-
-       /* TODO: Check for success on 5210 else return error */
-       return 0;
-}
-
-/**
- * ath5k_hw_get_txdp - Get TX Descriptor's address for a specific queue
- *
- * @ah: The &struct ath5k_hw
- * @queue: The hw queue number
- *
- * Get TX descriptor's address for a specific queue. For 5210 we ignore
- * the queue number and use tx queue type since we only have 2 queues.
- * We use TXDP0 for normal data queue and TXDP1 for beacon queue.
- * For newer chips with QCU/DCU we just read the corresponding TXDP register.
- *
- * XXX: Is TXDP read and clear ?
- */
-u32 ath5k_hw_get_txdp(struct ath5k_hw *ah, unsigned int queue)
-{
-       u16 tx_reg;
-
-       ATH5K_TRACE(ah->ah_sc);
-       AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
-
-       /*
-        * Get the transmit queue descriptor pointer from the selected queue
-        */
-       /*5210 doesn't have QCU*/
-       if (ah->ah_version == AR5K_AR5210) {
-               switch (ah->ah_txq[queue].tqi_type) {
-               case AR5K_TX_QUEUE_DATA:
-                       tx_reg = AR5K_NOQCU_TXDP0;
-                       break;
-               case AR5K_TX_QUEUE_BEACON:
-               case AR5K_TX_QUEUE_CAB:
-                       tx_reg = AR5K_NOQCU_TXDP1;
-                       break;
-               default:
-                       return 0xffffffff;
-               }
-       } else {
-               tx_reg = AR5K_QUEUE_TXDP(queue);
-       }
-
-       return ath5k_hw_reg_read(ah, tx_reg);
-}
-
-/**
- * ath5k_hw_set_txdp - Set TX Descriptor's address for a specific queue
- *
- * @ah: The &struct ath5k_hw
- * @queue: The hw queue number
- *
- * Set TX descriptor's address for a specific queue. For 5210 we ignore
- * the queue number and we use tx queue type since we only have 2 queues
- * so as above we use TXDP0 for normal data queue and TXDP1 for beacon queue.
- * For newer chips with QCU/DCU we just set the corresponding TXDP register.
- * Returns -EINVAL if queue type is invalid for 5210 and -EIO if queue is still
- * active.
- */
-int ath5k_hw_set_txdp(struct ath5k_hw *ah, unsigned int queue, u32 phys_addr)
-{
-       u16 tx_reg;
-
-       ATH5K_TRACE(ah->ah_sc);
-       AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
-
-       /*
-        * Set the transmit queue descriptor pointer register by type
-        * on 5210
-        */
-       if (ah->ah_version == AR5K_AR5210) {
-               switch (ah->ah_txq[queue].tqi_type) {
-               case AR5K_TX_QUEUE_DATA:
-                       tx_reg = AR5K_NOQCU_TXDP0;
-                       break;
-               case AR5K_TX_QUEUE_BEACON:
-               case AR5K_TX_QUEUE_CAB:
-                       tx_reg = AR5K_NOQCU_TXDP1;
-                       break;
-               default:
-                       return -EINVAL;
-               }
-       } else {
-               /*
-                * Set the transmit queue descriptor pointer for
-                * the selected queue on QCU for 5211+
-                * (this won't work if the queue is still active)
-                */
-               if (AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, queue))
-                       return -EIO;
-
-               tx_reg = AR5K_QUEUE_TXDP(queue);
-       }
-
-       /* Set descriptor pointer */
-       ath5k_hw_reg_write(ah, phys_addr, tx_reg);
-
-       return 0;
-}
-
-/**
- * ath5k_hw_update_tx_triglevel - Update tx trigger level
- *
- * @ah: The &struct ath5k_hw
- * @increase: Flag to force increase of trigger level
- *
- * This function increases/decreases the tx trigger level for the tx fifo
- * buffer (aka FIFO threshold) that is used to indicate when PCU flushes
- * the buffer and transmits it's data. Lowering this results sending small
- * frames more quickly but can lead to tx underruns, raising it a lot can
- * result other problems (i think bmiss is related). Right now we start with
- * the lowest possible (64Bytes) and if we get tx underrun we increase it using
- * the increase flag. Returns -EIO if we have have reached maximum/minimum.
- *
- * XXX: Link this with tx DMA size ?
- * XXX: Use it to save interrupts ?
- * TODO: Needs testing, i think it's related to bmiss...
- */
-int ath5k_hw_update_tx_triglevel(struct ath5k_hw *ah, bool increase)
-{
-       u32 trigger_level, imr;
-       int ret = -EIO;
-
-       ATH5K_TRACE(ah->ah_sc);
-
-       /*
-        * Disable interrupts by setting the mask
-        */
-       imr = ath5k_hw_set_imr(ah, ah->ah_imr & ~AR5K_INT_GLOBAL);
-
-       trigger_level = AR5K_REG_MS(ath5k_hw_reg_read(ah, AR5K_TXCFG),
-                       AR5K_TXCFG_TXFULL);
-
-       if (!increase) {
-               if (--trigger_level < AR5K_TUNE_MIN_TX_FIFO_THRES)
-                       goto done;
-       } else
-               trigger_level +=
-                       ((AR5K_TUNE_MAX_TX_FIFO_THRES - trigger_level) / 2);
-
-       /*
-        * Update trigger level on success
-        */
-       if (ah->ah_version == AR5K_AR5210)
-               ath5k_hw_reg_write(ah, trigger_level, AR5K_TRIG_LVL);
-       else
-               AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG,
-                               AR5K_TXCFG_TXFULL, trigger_level);
-
-       ret = 0;
-
-done:
-       /*
-        * Restore interrupt mask
-        */
-       ath5k_hw_set_imr(ah, imr);
-
-       return ret;
-}
-
-/*******************\
-* Interrupt masking *
-\*******************/
-
-/**
- * ath5k_hw_is_intr_pending - Check if we have pending interrupts
- *
- * @ah: The &struct ath5k_hw
- *
- * Check if we have pending interrupts to process. Returns 1 if we
- * have pending interrupts and 0 if we haven't.
- */
-bool ath5k_hw_is_intr_pending(struct ath5k_hw *ah)
-{
-       ATH5K_TRACE(ah->ah_sc);
-       return ath5k_hw_reg_read(ah, AR5K_INTPEND) == 1 ? 1 : 0;
-}
-
-/**
- * ath5k_hw_get_isr - Get interrupt status
- *
- * @ah: The @struct ath5k_hw
- * @interrupt_mask: Driver's interrupt mask used to filter out
- * interrupts in sw.
- *
- * This function is used inside our interrupt handler to determine the reason
- * for the interrupt by reading Primary Interrupt Status Register. Returns an
- * abstract interrupt status mask which is mostly ISR with some uncommon bits
- * being mapped on some standard non hw-specific positions
- * (check out &ath5k_int).
- *
- * NOTE: We use read-and-clear register, so after this function is called ISR
- * is zeroed.
- */
-int ath5k_hw_get_isr(struct ath5k_hw *ah, enum ath5k_int *interrupt_mask)
-{
-       u32 data;
-
-       ATH5K_TRACE(ah->ah_sc);
-
-       /*
-        * Read interrupt status from the Interrupt Status register
-        * on 5210
-        */
-       if (ah->ah_version == AR5K_AR5210) {
-               data = ath5k_hw_reg_read(ah, AR5K_ISR);
-               if (unlikely(data == AR5K_INT_NOCARD)) {
-                       *interrupt_mask = data;
-                       return -ENODEV;
-               }
-       } else {
-               /*
-                * Read interrupt status from Interrupt
-                * Status Register shadow copy (Read And Clear)
-                *
-                * Note: PISR/SISR Not available on 5210
-                */
-               data = ath5k_hw_reg_read(ah, AR5K_RAC_PISR);
-               if (unlikely(data == AR5K_INT_NOCARD)) {
-                       *interrupt_mask = data;
-                       return -ENODEV;
-               }
-       }
-
-       /*
-        * Get abstract interrupt mask (driver-compatible)
-        */
-       *interrupt_mask = (data & AR5K_INT_COMMON) & ah->ah_imr;
-
-       if (ah->ah_version != AR5K_AR5210) {
-               u32 sisr2 = ath5k_hw_reg_read(ah, AR5K_RAC_SISR2);
-
-               /*HIU = Host Interface Unit (PCI etc)*/
-               if (unlikely(data & (AR5K_ISR_HIUERR)))
-                       *interrupt_mask |= AR5K_INT_FATAL;
-
-               /*Beacon Not Ready*/
-               if (unlikely(data & (AR5K_ISR_BNR)))
-                       *interrupt_mask |= AR5K_INT_BNR;
-
-               if (unlikely(sisr2 & (AR5K_SISR2_SSERR |
-                                       AR5K_SISR2_DPERR |
-                                       AR5K_SISR2_MCABT)))
-                       *interrupt_mask |= AR5K_INT_FATAL;
-
-               if (data & AR5K_ISR_TIM)
-                       *interrupt_mask |= AR5K_INT_TIM;
-
-               if (data & AR5K_ISR_BCNMISC) {
-                       if (sisr2 & AR5K_SISR2_TIM)
-                               *interrupt_mask |= AR5K_INT_TIM;
-                       if (sisr2 & AR5K_SISR2_DTIM)
-                               *interrupt_mask |= AR5K_INT_DTIM;
-                       if (sisr2 & AR5K_SISR2_DTIM_SYNC)
-                               *interrupt_mask |= AR5K_INT_DTIM_SYNC;
-                       if (sisr2 & AR5K_SISR2_BCN_TIMEOUT)
-                               *interrupt_mask |= AR5K_INT_BCN_TIMEOUT;
-                       if (sisr2 & AR5K_SISR2_CAB_TIMEOUT)
-                               *interrupt_mask |= AR5K_INT_CAB_TIMEOUT;
-               }
-
-               if (data & AR5K_ISR_RXDOPPLER)
-                       *interrupt_mask |= AR5K_INT_RX_DOPPLER;
-               if (data & AR5K_ISR_QCBRORN) {
-                       *interrupt_mask |= AR5K_INT_QCBRORN;
-                       ah->ah_txq_isr |= AR5K_REG_MS(
-                                       ath5k_hw_reg_read(ah, AR5K_RAC_SISR3),
-                                       AR5K_SISR3_QCBRORN);
-               }
-               if (data & AR5K_ISR_QCBRURN) {
-                       *interrupt_mask |= AR5K_INT_QCBRURN;
-                       ah->ah_txq_isr |= AR5K_REG_MS(
-                                       ath5k_hw_reg_read(ah, AR5K_RAC_SISR3),
-                                       AR5K_SISR3_QCBRURN);
-               }
-               if (data & AR5K_ISR_QTRIG) {
-                       *interrupt_mask |= AR5K_INT_QTRIG;
-                       ah->ah_txq_isr |= AR5K_REG_MS(
-                                       ath5k_hw_reg_read(ah, AR5K_RAC_SISR4),
-                                       AR5K_SISR4_QTRIG);
-               }
-
-               if (data & AR5K_ISR_TXOK)
-                       ah->ah_txq_isr |= AR5K_REG_MS(
-                                       ath5k_hw_reg_read(ah, AR5K_RAC_SISR0),
-                                       AR5K_SISR0_QCU_TXOK);
-
-               if (data & AR5K_ISR_TXDESC)
-                       ah->ah_txq_isr |= AR5K_REG_MS(
-                                       ath5k_hw_reg_read(ah, AR5K_RAC_SISR0),
-                                       AR5K_SISR0_QCU_TXDESC);
-
-               if (data & AR5K_ISR_TXERR)
-                       ah->ah_txq_isr |= AR5K_REG_MS(
-                                       ath5k_hw_reg_read(ah, AR5K_RAC_SISR1),
-                                       AR5K_SISR1_QCU_TXERR);
-
-               if (data & AR5K_ISR_TXEOL)
-                       ah->ah_txq_isr |= AR5K_REG_MS(
-                                       ath5k_hw_reg_read(ah, AR5K_RAC_SISR1),
-                                       AR5K_SISR1_QCU_TXEOL);
-
-               if (data & AR5K_ISR_TXURN)
-                       ah->ah_txq_isr |= AR5K_REG_MS(
-                                       ath5k_hw_reg_read(ah, AR5K_RAC_SISR2),
-                                       AR5K_SISR2_QCU_TXURN);
-       } else {
-               if (unlikely(data & (AR5K_ISR_SSERR | AR5K_ISR_MCABT
-                               | AR5K_ISR_HIUERR | AR5K_ISR_DPERR)))
-                       *interrupt_mask |= AR5K_INT_FATAL;
-
-               /*
-                * XXX: BMISS interrupts may occur after association.
-                * I found this on 5210 code but it needs testing. If this is
-                * true we should disable them before assoc and re-enable them
-                * after a successful assoc + some jiffies.
-                       interrupt_mask &= ~AR5K_INT_BMISS;
-                */
-       }
-
-       /*
-        * In case we didn't handle anything,
-        * print the register value.
-        */
-       if (unlikely(*interrupt_mask == 0 && net_ratelimit()))
-               ATH5K_PRINTF("ISR: 0x%08x IMR: 0x%08x\n", data, ah->ah_imr);
-
-       return 0;
-}
-
-/**
- * ath5k_hw_set_imr - Set interrupt mask
- *
- * @ah: The &struct ath5k_hw
- * @new_mask: The new interrupt mask to be set
- *
- * Set the interrupt mask in hw to save interrupts. We do that by mapping
- * ath5k_int bits to hw-specific bits to remove abstraction and writing
- * Interrupt Mask Register.
- */
-enum ath5k_int ath5k_hw_set_imr(struct ath5k_hw *ah, enum ath5k_int new_mask)
-{
-       enum ath5k_int old_mask, int_mask;
-
-       old_mask = ah->ah_imr;
-
-       /*
-        * Disable card interrupts to prevent any race conditions
-        * (they will be re-enabled afterwards if AR5K_INT GLOBAL
-        * is set again on the new mask).
-        */
-       if (old_mask & AR5K_INT_GLOBAL) {
-               ath5k_hw_reg_write(ah, AR5K_IER_DISABLE, AR5K_IER);
-               ath5k_hw_reg_read(ah, AR5K_IER);
-       }
-
-       /*
-        * Add additional, chipset-dependent interrupt mask flags
-        * and write them to the IMR (interrupt mask register).
-        */
-       int_mask = new_mask & AR5K_INT_COMMON;
-
-       if (ah->ah_version != AR5K_AR5210) {
-               /* Preserve per queue TXURN interrupt mask */
-               u32 simr2 = ath5k_hw_reg_read(ah, AR5K_SIMR2)
-                               & AR5K_SIMR2_QCU_TXURN;
-
-               if (new_mask & AR5K_INT_FATAL) {
-                       int_mask |= AR5K_IMR_HIUERR;
-                       simr2 |= (AR5K_SIMR2_MCABT | AR5K_SIMR2_SSERR
-                               | AR5K_SIMR2_DPERR);
-               }
-
-               /*Beacon Not Ready*/
-               if (new_mask & AR5K_INT_BNR)
-                       int_mask |= AR5K_INT_BNR;
-
-               if (new_mask & AR5K_INT_TIM)
-                       int_mask |= AR5K_IMR_TIM;
-
-               if (new_mask & AR5K_INT_TIM)
-                       simr2 |= AR5K_SISR2_TIM;
-               if (new_mask & AR5K_INT_DTIM)
-                       simr2 |= AR5K_SISR2_DTIM;
-               if (new_mask & AR5K_INT_DTIM_SYNC)
-                       simr2 |= AR5K_SISR2_DTIM_SYNC;
-               if (new_mask & AR5K_INT_BCN_TIMEOUT)
-                       simr2 |= AR5K_SISR2_BCN_TIMEOUT;
-               if (new_mask & AR5K_INT_CAB_TIMEOUT)
-                       simr2 |= AR5K_SISR2_CAB_TIMEOUT;
-
-               if (new_mask & AR5K_INT_RX_DOPPLER)
-                       int_mask |= AR5K_IMR_RXDOPPLER;
-
-               /* Note: Per queue interrupt masks
-                * are set via reset_tx_queue (qcu.c) */
-               ath5k_hw_reg_write(ah, int_mask, AR5K_PIMR);
-               ath5k_hw_reg_write(ah, simr2, AR5K_SIMR2);
-
-       } else {
-               if (new_mask & AR5K_INT_FATAL)
-                       int_mask |= (AR5K_IMR_SSERR | AR5K_IMR_MCABT
-                               | AR5K_IMR_HIUERR | AR5K_IMR_DPERR);
-
-               ath5k_hw_reg_write(ah, int_mask, AR5K_IMR);
-       }
-
-       /* If RXNOFRM interrupt is masked disable it
-        * by setting AR5K_RXNOFRM to zero */
-       if (!(new_mask & AR5K_INT_RXNOFRM))
-               ath5k_hw_reg_write(ah, 0, AR5K_RXNOFRM);
-
-       /* Store new interrupt mask */
-       ah->ah_imr = new_mask;
-
-       /* ..re-enable interrupts if AR5K_INT_GLOBAL is set */
-       if (new_mask & AR5K_INT_GLOBAL) {
-               ath5k_hw_reg_write(ah, AR5K_IER_ENABLE, AR5K_IER);
-               ath5k_hw_reg_read(ah, AR5K_IER);
-       }
-
-       return old_mask;
-}
-
diff --git a/drivers/net/wireless/ath5k/eeprom.c b/drivers/net/wireless/ath5k/eeprom.c
deleted file mode 100644 (file)
index c0fb3b0..0000000
+++ /dev/null
@@ -1,1769 +0,0 @@
-/*
- * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
- * Copyright (c) 2006-2009 Nick Kossifidis <mickflemm@gmail.com>
- * Copyright (c) 2008-2009 Felix Fietkau <nbd@openwrt.org>
- *
- * Permission to use, copy, modify, and 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.
- *
- */
-
-/*************************************\
-* EEPROM access functions and helpers *
-\*************************************/
-
-#include "ath5k.h"
-#include "reg.h"
-#include "debug.h"
-#include "base.h"
-
-/*
- * Read from eeprom
- */
-static int ath5k_hw_eeprom_read(struct ath5k_hw *ah, u32 offset, u16 *data)
-{
-       u32 status, timeout;
-
-       ATH5K_TRACE(ah->ah_sc);
-       /*
-        * Initialize EEPROM access
-        */
-       if (ah->ah_version == AR5K_AR5210) {
-               AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, AR5K_PCICFG_EEAE);
-               (void)ath5k_hw_reg_read(ah, AR5K_EEPROM_BASE + (4 * offset));
-       } else {
-               ath5k_hw_reg_write(ah, offset, AR5K_EEPROM_BASE);
-               AR5K_REG_ENABLE_BITS(ah, AR5K_EEPROM_CMD,
-                               AR5K_EEPROM_CMD_READ);
-       }
-
-       for (timeout = AR5K_TUNE_REGISTER_TIMEOUT; timeout > 0; timeout--) {
-               status = ath5k_hw_reg_read(ah, AR5K_EEPROM_STATUS);
-               if (status & AR5K_EEPROM_STAT_RDDONE) {
-                       if (status & AR5K_EEPROM_STAT_RDERR)
-                               return -EIO;
-                       *data = (u16)(ath5k_hw_reg_read(ah, AR5K_EEPROM_DATA) &
-                                       0xffff);
-                       return 0;
-               }
-               udelay(15);
-       }
-
-       return -ETIMEDOUT;
-}
-
-/*
- * Translate binary channel representation in EEPROM to frequency
- */
-static u16 ath5k_eeprom_bin2freq(struct ath5k_eeprom_info *ee, u16 bin,
-                                 unsigned int mode)
-{
-       u16 val;
-
-       if (bin == AR5K_EEPROM_CHANNEL_DIS)
-               return bin;
-
-       if (mode == AR5K_EEPROM_MODE_11A) {
-               if (ee->ee_version > AR5K_EEPROM_VERSION_3_2)
-                       val = (5 * bin) + 4800;
-               else
-                       val = bin > 62 ? (10 * 62) + (5 * (bin - 62)) + 5100 :
-                               (bin * 10) + 5100;
-       } else {
-               if (ee->ee_version > AR5K_EEPROM_VERSION_3_2)
-                       val = bin + 2300;
-               else
-                       val = bin + 2400;
-       }
-
-       return val;
-}
-
-/*
- * Initialize eeprom & capabilities structs
- */
-static int
-ath5k_eeprom_init_header(struct ath5k_hw *ah)
-{
-       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
-       int ret;
-       u16 val;
-
-       /*
-        * Read values from EEPROM and store them in the capability structure
-        */
-       AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MAGIC, ee_magic);
-       AR5K_EEPROM_READ_HDR(AR5K_EEPROM_PROTECT, ee_protect);
-       AR5K_EEPROM_READ_HDR(AR5K_EEPROM_REG_DOMAIN, ee_regdomain);
-       AR5K_EEPROM_READ_HDR(AR5K_EEPROM_VERSION, ee_version);
-       AR5K_EEPROM_READ_HDR(AR5K_EEPROM_HDR, ee_header);
-
-       /* Return if we have an old EEPROM */
-       if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_0)
-               return 0;
-
-#ifdef notyet
-       /*
-        * Validate the checksum of the EEPROM date. There are some
-        * devices with invalid EEPROMs.
-        */
-       for (cksum = 0, offset = 0; offset < AR5K_EEPROM_INFO_MAX; offset++) {
-               AR5K_EEPROM_READ(AR5K_EEPROM_INFO(offset), val);
-               cksum ^= val;
-       }
-       if (cksum != AR5K_EEPROM_INFO_CKSUM) {
-               ATH5K_ERR(ah->ah_sc, "Invalid EEPROM checksum 0x%04x\n", cksum);
-               return -EIO;
-       }
-#endif
-
-       AR5K_EEPROM_READ_HDR(AR5K_EEPROM_ANT_GAIN(ah->ah_ee_version),
-           ee_ant_gain);
-
-       if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) {
-               AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC0, ee_misc0);
-               AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC1, ee_misc1);
-
-               /* XXX: Don't know which versions include these two */
-               AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC2, ee_misc2);
-
-               if (ee->ee_version >= AR5K_EEPROM_VERSION_4_3)
-                       AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC3, ee_misc3);
-
-               if (ee->ee_version >= AR5K_EEPROM_VERSION_5_0) {
-                       AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC4, ee_misc4);
-                       AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC5, ee_misc5);
-                       AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC6, ee_misc6);
-               }
-       }
-
-       if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_3) {
-               AR5K_EEPROM_READ(AR5K_EEPROM_OBDB0_2GHZ, val);
-               ee->ee_ob[AR5K_EEPROM_MODE_11B][0] = val & 0x7;
-               ee->ee_db[AR5K_EEPROM_MODE_11B][0] = (val >> 3) & 0x7;
-
-               AR5K_EEPROM_READ(AR5K_EEPROM_OBDB1_2GHZ, val);
-               ee->ee_ob[AR5K_EEPROM_MODE_11G][0] = val & 0x7;
-               ee->ee_db[AR5K_EEPROM_MODE_11G][0] = (val >> 3) & 0x7;
-       }
-
-       return 0;
-}
-
-
-/*
- * Read antenna infos from eeprom
- */
-static int ath5k_eeprom_read_ants(struct ath5k_hw *ah, u32 *offset,
-               unsigned int mode)
-{
-       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
-       u32 o = *offset;
-       u16 val;
-       int ret, i = 0;
-
-       AR5K_EEPROM_READ(o++, val);
-       ee->ee_switch_settling[mode]    = (val >> 8) & 0x7f;
-       ee->ee_atn_tx_rx[mode]          = (val >> 2) & 0x3f;
-       ee->ee_ant_control[mode][i]     = (val << 4) & 0x3f;
-
-       AR5K_EEPROM_READ(o++, val);
-       ee->ee_ant_control[mode][i++]   |= (val >> 12) & 0xf;
-       ee->ee_ant_control[mode][i++]   = (val >> 6) & 0x3f;
-       ee->ee_ant_control[mode][i++]   = val & 0x3f;
-
-       AR5K_EEPROM_READ(o++, val);
-       ee->ee_ant_control[mode][i++]   = (val >> 10) & 0x3f;
-       ee->ee_ant_control[mode][i++]   = (val >> 4) & 0x3f;
-       ee->ee_ant_control[mode][i]     = (val << 2) & 0x3f;
-
-       AR5K_EEPROM_READ(o++, val);
-       ee->ee_ant_control[mode][i++]   |= (val >> 14) & 0x3;
-       ee->ee_ant_control[mode][i++]   = (val >> 8) & 0x3f;
-       ee->ee_ant_control[mode][i++]   = (val >> 2) & 0x3f;
-       ee->ee_ant_control[mode][i]     = (val << 4) & 0x3f;
-
-       AR5K_EEPROM_READ(o++, val);
-       ee->ee_ant_control[mode][i++]   |= (val >> 12) & 0xf;
-       ee->ee_ant_control[mode][i++]   = (val >> 6) & 0x3f;
-       ee->ee_ant_control[mode][i++]   = val & 0x3f;
-
-       /* Get antenna modes */
-       ah->ah_antenna[mode][0] =
-           (ee->ee_ant_control[mode][0] << 4);
-       ah->ah_antenna[mode][AR5K_ANT_FIXED_A] =
-            ee->ee_ant_control[mode][1]        |
-           (ee->ee_ant_control[mode][2] << 6)  |
-           (ee->ee_ant_control[mode][3] << 12) |
-           (ee->ee_ant_control[mode][4] << 18) |
-           (ee->ee_ant_control[mode][5] << 24);
-       ah->ah_antenna[mode][AR5K_ANT_FIXED_B] =
-            ee->ee_ant_control[mode][6]        |
-           (ee->ee_ant_control[mode][7] << 6)  |
-           (ee->ee_ant_control[mode][8] << 12) |
-           (ee->ee_ant_control[mode][9] << 18) |
-           (ee->ee_ant_control[mode][10] << 24);
-
-       /* return new offset */
-       *offset = o;
-
-       return 0;
-}
-
-/*
- * Read supported modes and some mode-specific calibration data
- * from eeprom
- */
-static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset,
-               unsigned int mode)
-{
-       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
-       u32 o = *offset;
-       u16 val;
-       int ret;
-
-       ee->ee_n_piers[mode] = 0;
-       AR5K_EEPROM_READ(o++, val);
-       ee->ee_adc_desired_size[mode]   = (s8)((val >> 8) & 0xff);
-       switch(mode) {
-       case AR5K_EEPROM_MODE_11A:
-               ee->ee_ob[mode][3]      = (val >> 5) & 0x7;
-               ee->ee_db[mode][3]      = (val >> 2) & 0x7;
-               ee->ee_ob[mode][2]      = (val << 1) & 0x7;
-
-               AR5K_EEPROM_READ(o++, val);
-               ee->ee_ob[mode][2]      |= (val >> 15) & 0x1;
-               ee->ee_db[mode][2]      = (val >> 12) & 0x7;
-               ee->ee_ob[mode][1]      = (val >> 9) & 0x7;
-               ee->ee_db[mode][1]      = (val >> 6) & 0x7;
-               ee->ee_ob[mode][0]      = (val >> 3) & 0x7;
-               ee->ee_db[mode][0]      = val & 0x7;
-               break;
-       case AR5K_EEPROM_MODE_11G:
-       case AR5K_EEPROM_MODE_11B:
-               ee->ee_ob[mode][1]      = (val >> 4) & 0x7;
-               ee->ee_db[mode][1]      = val & 0x7;
-               break;
-       }
-
-       AR5K_EEPROM_READ(o++, val);
-       ee->ee_tx_end2xlna_enable[mode] = (val >> 8) & 0xff;
-       ee->ee_thr_62[mode]             = val & 0xff;
-
-       if (ah->ah_ee_version <= AR5K_EEPROM_VERSION_3_2)
-               ee->ee_thr_62[mode] = mode == AR5K_EEPROM_MODE_11A ? 15 : 28;
-
-       AR5K_EEPROM_READ(o++, val);
-       ee->ee_tx_end2xpa_disable[mode] = (val >> 8) & 0xff;
-       ee->ee_tx_frm2xpa_enable[mode]  = val & 0xff;
-
-       AR5K_EEPROM_READ(o++, val);
-       ee->ee_pga_desired_size[mode]   = (val >> 8) & 0xff;
-
-       if ((val & 0xff) & 0x80)
-               ee->ee_noise_floor_thr[mode] = -((((val & 0xff) ^ 0xff)) + 1);
-       else
-               ee->ee_noise_floor_thr[mode] = val & 0xff;
-
-       if (ah->ah_ee_version <= AR5K_EEPROM_VERSION_3_2)
-               ee->ee_noise_floor_thr[mode] =
-                   mode == AR5K_EEPROM_MODE_11A ? -54 : -1;
-
-       AR5K_EEPROM_READ(o++, val);
-       ee->ee_xlna_gain[mode]          = (val >> 5) & 0xff;
-       ee->ee_x_gain[mode]             = (val >> 1) & 0xf;
-       ee->ee_xpd[mode]                = val & 0x1;
-
-       if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0)
-               ee->ee_fixed_bias[mode] = (val >> 13) & 0x1;
-
-       if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_3_3) {
-               AR5K_EEPROM_READ(o++, val);
-               ee->ee_false_detect[mode] = (val >> 6) & 0x7f;
-
-               if (mode == AR5K_EEPROM_MODE_11A)
-                       ee->ee_xr_power[mode] = val & 0x3f;
-               else {
-                       ee->ee_ob[mode][0] = val & 0x7;
-                       ee->ee_db[mode][0] = (val >> 3) & 0x7;
-               }
-       }
-
-       if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_4) {
-               ee->ee_i_gain[mode] = AR5K_EEPROM_I_GAIN;
-               ee->ee_cck_ofdm_power_delta = AR5K_EEPROM_CCK_OFDM_DELTA;
-       } else {
-               ee->ee_i_gain[mode] = (val >> 13) & 0x7;
-
-               AR5K_EEPROM_READ(o++, val);
-               ee->ee_i_gain[mode] |= (val << 3) & 0x38;
-
-               if (mode == AR5K_EEPROM_MODE_11G) {
-                       ee->ee_cck_ofdm_power_delta = (val >> 3) & 0xff;
-                       if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_6)
-                               ee->ee_scaled_cck_delta = (val >> 11) & 0x1f;
-               }
-       }
-
-       if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0 &&
-                       mode == AR5K_EEPROM_MODE_11A) {
-               ee->ee_i_cal[mode] = (val >> 8) & 0x3f;
-               ee->ee_q_cal[mode] = (val >> 3) & 0x1f;
-       }
-
-       if (ah->ah_ee_version < AR5K_EEPROM_VERSION_4_0)
-               goto done;
-
-       /* Note: >= v5 have bg freq piers on another location
-        * so these freq piers are ignored for >= v5 (should be 0xff
-        * anyway) */
-       switch(mode) {
-       case AR5K_EEPROM_MODE_11A:
-               if (ah->ah_ee_version < AR5K_EEPROM_VERSION_4_1)
-                       break;
-
-               AR5K_EEPROM_READ(o++, val);
-               ee->ee_margin_tx_rx[mode] = val & 0x3f;
-               break;
-       case AR5K_EEPROM_MODE_11B:
-               AR5K_EEPROM_READ(o++, val);
-
-               ee->ee_pwr_cal_b[0].freq =
-                       ath5k_eeprom_bin2freq(ee, val & 0xff, mode);
-               if (ee->ee_pwr_cal_b[0].freq != AR5K_EEPROM_CHANNEL_DIS)
-                       ee->ee_n_piers[mode]++;
-
-               ee->ee_pwr_cal_b[1].freq =
-                       ath5k_eeprom_bin2freq(ee, (val >> 8) & 0xff, mode);
-               if (ee->ee_pwr_cal_b[1].freq != AR5K_EEPROM_CHANNEL_DIS)
-                       ee->ee_n_piers[mode]++;
-
-               AR5K_EEPROM_READ(o++, val);
-               ee->ee_pwr_cal_b[2].freq =
-                       ath5k_eeprom_bin2freq(ee, val & 0xff, mode);
-               if (ee->ee_pwr_cal_b[2].freq != AR5K_EEPROM_CHANNEL_DIS)
-                       ee->ee_n_piers[mode]++;
-
-               if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1)
-                       ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f;
-               break;
-       case AR5K_EEPROM_MODE_11G:
-               AR5K_EEPROM_READ(o++, val);
-
-               ee->ee_pwr_cal_g[0].freq =
-                       ath5k_eeprom_bin2freq(ee, val & 0xff, mode);
-               if (ee->ee_pwr_cal_g[0].freq != AR5K_EEPROM_CHANNEL_DIS)
-                       ee->ee_n_piers[mode]++;
-
-               ee->ee_pwr_cal_g[1].freq =
-                       ath5k_eeprom_bin2freq(ee, (val >> 8) & 0xff, mode);
-               if (ee->ee_pwr_cal_g[1].freq != AR5K_EEPROM_CHANNEL_DIS)
-                       ee->ee_n_piers[mode]++;
-
-               AR5K_EEPROM_READ(o++, val);
-               ee->ee_turbo_max_power[mode] = val & 0x7f;
-               ee->ee_xr_power[mode] = (val >> 7) & 0x3f;
-
-               AR5K_EEPROM_READ(o++, val);
-               ee->ee_pwr_cal_g[2].freq =
-                       ath5k_eeprom_bin2freq(ee, val & 0xff, mode);
-               if (ee->ee_pwr_cal_g[2].freq != AR5K_EEPROM_CHANNEL_DIS)
-                       ee->ee_n_piers[mode]++;
-
-               if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1)
-                       ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f;
-
-               AR5K_EEPROM_READ(o++, val);
-               ee->ee_i_cal[mode] = (val >> 8) & 0x3f;
-               ee->ee_q_cal[mode] = (val >> 3) & 0x1f;
-
-               if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_2) {
-                       AR5K_EEPROM_READ(o++, val);
-                       ee->ee_cck_ofdm_gain_delta = val & 0xff;
-               }
-               break;
-       }
-
-done:
-       /* return new offset */
-       *offset = o;
-
-       return 0;
-}
-
-/*
- * Read turbo mode information on newer EEPROM versions
- */
-static int
-ath5k_eeprom_read_turbo_modes(struct ath5k_hw *ah,
-                             u32 *offset, unsigned int mode)
-{
-       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
-       u32 o = *offset;
-       u16 val;
-       int ret;
-
-       if (ee->ee_version < AR5K_EEPROM_VERSION_5_0)
-               return 0;
-
-       switch (mode){
-       case AR5K_EEPROM_MODE_11A:
-               ee->ee_switch_settling_turbo[mode] = (val >> 6) & 0x7f;
-
-               ee->ee_atn_tx_rx_turbo[mode] = (val >> 13) & 0x7;
-               AR5K_EEPROM_READ(o++, val);
-               ee->ee_atn_tx_rx_turbo[mode] |= (val & 0x7) << 3;
-               ee->ee_margin_tx_rx_turbo[mode] = (val >> 3) & 0x3f;
-
-               ee->ee_adc_desired_size_turbo[mode] = (val >> 9) & 0x7f;
-               AR5K_EEPROM_READ(o++, val);
-               ee->ee_adc_desired_size_turbo[mode] |= (val & 0x1) << 7;
-               ee->ee_pga_desired_size_turbo[mode] = (val >> 1) & 0xff;
-
-               if (AR5K_EEPROM_EEMAP(ee->ee_misc0) >=2)
-                       ee->ee_pd_gain_overlap = (val >> 9) & 0xf;
-               break;
-       case AR5K_EEPROM_MODE_11G:
-               ee->ee_switch_settling_turbo[mode] = (val >> 8) & 0x7f;
-
-               ee->ee_atn_tx_rx_turbo[mode] = (val >> 15) & 0x7;
-               AR5K_EEPROM_READ(o++, val);
-               ee->ee_atn_tx_rx_turbo[mode] |= (val & 0x1f) << 1;
-               ee->ee_margin_tx_rx_turbo[mode] = (val >> 5) & 0x3f;
-
-               ee->ee_adc_desired_size_turbo[mode] = (val >> 11) & 0x7f;
-               AR5K_EEPROM_READ(o++, val);
-               ee->ee_adc_desired_size_turbo[mode] |= (val & 0x7) << 5;
-               ee->ee_pga_desired_size_turbo[mode] = (val >> 3) & 0xff;
-               break;
-       }
-
-       /* return new offset */
-       *offset = o;
-
-       return 0;
-}
-
-/* Read mode-specific data (except power calibration data) */
-static int
-ath5k_eeprom_init_modes(struct ath5k_hw *ah)
-{
-       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
-       u32 mode_offset[3];
-       unsigned int mode;
-       u32 offset;
-       int ret;
-
-       /*
-        * Get values for all modes
-        */
-       mode_offset[AR5K_EEPROM_MODE_11A] = AR5K_EEPROM_MODES_11A(ah->ah_ee_version);
-       mode_offset[AR5K_EEPROM_MODE_11B] = AR5K_EEPROM_MODES_11B(ah->ah_ee_version);
-       mode_offset[AR5K_EEPROM_MODE_11G] = AR5K_EEPROM_MODES_11G(ah->ah_ee_version);
-
-       ee->ee_turbo_max_power[AR5K_EEPROM_MODE_11A] =
-               AR5K_EEPROM_HDR_T_5GHZ_DBM(ee->ee_header);
-
-       for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G; mode++) {
-               offset = mode_offset[mode];
-
-               ret = ath5k_eeprom_read_ants(ah, &offset, mode);
-               if (ret)
-                       return ret;
-
-               ret = ath5k_eeprom_read_modes(ah, &offset, mode);
-               if (ret)
-                       return ret;
-
-               ret = ath5k_eeprom_read_turbo_modes(ah, &offset, mode);
-               if (ret)
-                       return ret;
-       }
-
-       /* override for older eeprom versions for better performance */
-       if (ah->ah_ee_version <= AR5K_EEPROM_VERSION_3_2) {
-               ee->ee_thr_62[AR5K_EEPROM_MODE_11A] = 15;
-               ee->ee_thr_62[AR5K_EEPROM_MODE_11B] = 28;
-               ee->ee_thr_62[AR5K_EEPROM_MODE_11G] = 28;
-       }
-
-       return 0;
-}
-
-/* Read the frequency piers for each mode (mostly used on newer eeproms with 0xff
- * frequency mask) */
-static inline int
-ath5k_eeprom_read_freq_list(struct ath5k_hw *ah, int *offset, int max,
-                       struct ath5k_chan_pcal_info *pc, unsigned int mode)
-{
-       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
-       int o = *offset;
-       int i = 0;
-       u8 freq1, freq2;
-       int ret;
-       u16 val;
-
-       ee->ee_n_piers[mode] = 0;
-       while(i < max) {
-               AR5K_EEPROM_READ(o++, val);
-
-               freq1 = val & 0xff;
-               if (!freq1)
-                       break;
-
-               pc[i++].freq = ath5k_eeprom_bin2freq(ee,
-                               freq1, mode);
-               ee->ee_n_piers[mode]++;
-
-               freq2 = (val >> 8) & 0xff;
-               if (!freq2)
-                       break;
-
-               pc[i++].freq = ath5k_eeprom_bin2freq(ee,
-                               freq2, mode);
-               ee->ee_n_piers[mode]++;
-       }
-
-       /* return new offset */
-       *offset = o;
-
-       return 0;
-}
-
-/* Read frequency piers for 802.11a */
-static int
-ath5k_eeprom_init_11a_pcal_freq(struct ath5k_hw *ah, int offset)
-{
-       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
-       struct ath5k_chan_pcal_info *pcal = ee->ee_pwr_cal_a;
-       int i, ret;
-       u16 val;
-       u8 mask;
-
-       if (ee->ee_version >= AR5K_EEPROM_VERSION_3_3) {
-               ath5k_eeprom_read_freq_list(ah, &offset,
-                       AR5K_EEPROM_N_5GHZ_CHAN, pcal,
-                       AR5K_EEPROM_MODE_11A);
-       } else {
-               mask = AR5K_EEPROM_FREQ_M(ah->ah_ee_version);
-
-               AR5K_EEPROM_READ(offset++, val);
-               pcal[0].freq  = (val >> 9) & mask;
-               pcal[1].freq  = (val >> 2) & mask;
-               pcal[2].freq  = (val << 5) & mask;
-
-               AR5K_EEPROM_READ(offset++, val);
-               pcal[2].freq |= (val >> 11) & 0x1f;
-               pcal[3].freq  = (val >> 4) & mask;
-               pcal[4].freq  = (val << 3) & mask;
-
-               AR5K_EEPROM_READ(offset++, val);
-               pcal[4].freq |= (val >> 13) & 0x7;
-               pcal[5].freq  = (val >> 6) & mask;
-               pcal[6].freq  = (val << 1) & mask;
-
-               AR5K_EEPROM_READ(offset++, val);
-               pcal[6].freq |= (val >> 15) & 0x1;
-               pcal[7].freq  = (val >> 8) & mask;
-               pcal[8].freq  = (val >> 1) & mask;
-               pcal[9].freq  = (val << 6) & mask;
-
-               AR5K_EEPROM_READ(offset++, val);
-               pcal[9].freq |= (val >> 10) & 0x3f;
-
-               /* Fixed number of piers */
-               ee->ee_n_piers[AR5K_EEPROM_MODE_11A] = 10;
-
-               for (i = 0; i < AR5K_EEPROM_N_5GHZ_CHAN; i++) {
-                       pcal[i].freq = ath5k_eeprom_bin2freq(ee,
-                               pcal[i].freq, AR5K_EEPROM_MODE_11A);
-               }
-       }
-
-       return 0;
-}
-
-/* Read frequency piers for 802.11bg on eeprom versions >= 5 and eemap >= 2 */
-static inline int
-ath5k_eeprom_init_11bg_2413(struct ath5k_hw *ah, unsigned int mode, int offset)
-{
-       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
-       struct ath5k_chan_pcal_info *pcal;
-
-       switch(mode) {
-       case AR5K_EEPROM_MODE_11B:
-               pcal = ee->ee_pwr_cal_b;
-               break;
-       case AR5K_EEPROM_MODE_11G:
-               pcal = ee->ee_pwr_cal_g;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       ath5k_eeprom_read_freq_list(ah, &offset,
-               AR5K_EEPROM_N_2GHZ_CHAN_2413, pcal,
-               mode);
-
-       return 0;
-}
-
-/*
- * Read power calibration for RF5111 chips
- *
- * For RF5111 we have an XPD -eXternal Power Detector- curve
- * for each calibrated channel. Each curve has 0,5dB Power steps
- * on x axis and PCDAC steps (offsets) on y axis and looks like an
- * exponential function. To recreate the curve we read 11 points
- * here and interpolate later.
- */
-
-/* Used to match PCDAC steps with power values on RF5111 chips
- * (eeprom versions < 4). For RF5111 we have 11 pre-defined PCDAC
- * steps that match with the power values we read from eeprom. On
- * older eeprom versions (< 3.2) these steps are equaly spaced at
- * 10% of the pcdac curve -until the curve reaches it's maximum-
- * (11 steps from 0 to 100%) but on newer eeprom versions (>= 3.2)
- * these 11 steps are spaced in a different way. This function returns
- * the pcdac steps based on eeprom version and curve min/max so that we
- * can have pcdac/pwr points.
- */
-static inline void
-ath5k_get_pcdac_intercepts(struct ath5k_hw *ah, u8 min, u8 max, u8 *vp)
-{
-       const static u16 intercepts3[] =
-               { 0, 5, 10, 20, 30, 50, 70, 85, 90, 95, 100 };
-       const static u16 intercepts3_2[] =
-               { 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 };
-       const u16 *ip;
-       int i;
-
-       if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_3_2)
-               ip = intercepts3_2;
-       else
-               ip = intercepts3;
-
-       for (i = 0; i < ARRAY_SIZE(intercepts3); i++)
-               vp[i] = (ip[i] * max + (100 - ip[i]) * min) / 100;
-}
-
-/* Convert RF5111 specific data to generic raw data
- * used by interpolation code */
-static int
-ath5k_eeprom_convert_pcal_info_5111(struct ath5k_hw *ah, int mode,
-                               struct ath5k_chan_pcal_info *chinfo)
-{
-       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
-       struct ath5k_chan_pcal_info_rf5111 *pcinfo;
-       struct ath5k_pdgain_info *pd;
-       u8 pier, point, idx;
-       u8 *pdgain_idx = ee->ee_pdc_to_idx[mode];
-
-       /* Fill raw data for each calibration pier */
-       for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) {
-
-               pcinfo = &chinfo[pier].rf5111_info;
-
-               /* Allocate pd_curves for this cal pier */
-               chinfo[pier].pd_curves =
-                       kcalloc(AR5K_EEPROM_N_PD_CURVES,
-                               sizeof(struct ath5k_pdgain_info),
-                               GFP_KERNEL);
-
-               if (!chinfo[pier].pd_curves)
-                       return -ENOMEM;
-
-               /* Only one curve for RF5111
-                * find out which one and place
-                * in in pd_curves.
-                * Note: ee_x_gain is reversed here */
-               for (idx = 0; idx < AR5K_EEPROM_N_PD_CURVES; idx++) {
-
-                       if (!((ee->ee_x_gain[mode] >> idx) & 0x1)) {
-                               pdgain_idx[0] = idx;
-                               break;
-                       }
-               }
-
-               ee->ee_pd_gains[mode] = 1;
-
-               pd = &chinfo[pier].pd_curves[idx];
-
-               pd->pd_points = AR5K_EEPROM_N_PWR_POINTS_5111;
-
-               /* Allocate pd points for this curve */
-               pd->pd_step = kcalloc(AR5K_EEPROM_N_PWR_POINTS_5111,
-                                       sizeof(u8), GFP_KERNEL);
-               if (!pd->pd_step)
-                       return -ENOMEM;
-
-               pd->pd_pwr = kcalloc(AR5K_EEPROM_N_PWR_POINTS_5111,
-                                       sizeof(s16), GFP_KERNEL);
-               if (!pd->pd_pwr)
-                       return -ENOMEM;
-
-               /* Fill raw dataset
-                * (convert power to 0.25dB units
-                * for RF5112 combatibility) */
-               for (point = 0; point < pd->pd_points; point++) {
-
-                       /* Absolute values */
-                       pd->pd_pwr[point] = 2 * pcinfo->pwr[point];
-
-                       /* Already sorted */
-                       pd->pd_step[point] = pcinfo->pcdac[point];
-               }
-
-               /* Set min/max pwr */
-               chinfo[pier].min_pwr = pd->pd_pwr[0];
-               chinfo[pier].max_pwr = pd->pd_pwr[10];
-
-       }
-
-       return 0;
-}
-
-/* Parse EEPROM data */
-static int
-ath5k_eeprom_read_pcal_info_5111(struct ath5k_hw *ah, int mode)
-{
-       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
-       struct ath5k_chan_pcal_info *pcal;
-       int offset, ret;
-       int i;
-       u16 val;
-
-       offset = AR5K_EEPROM_GROUPS_START(ee->ee_version);
-       switch(mode) {
-       case AR5K_EEPROM_MODE_11A:
-               if (!AR5K_EEPROM_HDR_11A(ee->ee_header))
-                       return 0;
-
-               ret = ath5k_eeprom_init_11a_pcal_freq(ah,
-                       offset + AR5K_EEPROM_GROUP1_OFFSET);
-               if (ret < 0)
-                       return ret;
-
-               offset += AR5K_EEPROM_GROUP2_OFFSET;
-               pcal = ee->ee_pwr_cal_a;
-               break;
-       case AR5K_EEPROM_MODE_11B:
-               if (!AR5K_EEPROM_HDR_11B(ee->ee_header) &&
-                   !AR5K_EEPROM_HDR_11G(ee->ee_header))
-                       return 0;
-
-               pcal = ee->ee_pwr_cal_b;
-               offset += AR5K_EEPROM_GROUP3_OFFSET;
-
-               /* fixed piers */
-               pcal[0].freq = 2412;
-               pcal[1].freq = 2447;
-               pcal[2].freq = 2484;
-               ee->ee_n_piers[mode] = 3;
-               break;
-       case AR5K_EEPROM_MODE_11G:
-               if (!AR5K_EEPROM_HDR_11G(ee->ee_header))
-                       return 0;
-
-               pcal = ee->ee_pwr_cal_g;
-               offset += AR5K_EEPROM_GROUP4_OFFSET;
-
-               /* fixed piers */
-               pcal[0].freq = 2312;
-               pcal[1].freq = 2412;
-               pcal[2].freq = 2484;
-               ee->ee_n_piers[mode] = 3;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       for (i = 0; i < ee->ee_n_piers[mode]; i++) {
-               struct ath5k_chan_pcal_info_rf5111 *cdata =
-                       &pcal[i].rf5111_info;
-
-               AR5K_EEPROM_READ(offset++, val);
-               cdata->pcdac_max = ((val >> 10) & AR5K_EEPROM_PCDAC_M);
-               cdata->pcdac_min = ((val >> 4) & AR5K_EEPROM_PCDAC_M);
-               cdata->pwr[0] = ((val << 2) & AR5K_EEPROM_POWER_M);
-
-               AR5K_EEPROM_READ(offset++, val);
-               cdata->pwr[0] |= ((val >> 14) & 0x3);
-               cdata->pwr[1] = ((val >> 8) & AR5K_EEPROM_POWER_M);
-               cdata->pwr[2] = ((val >> 2) & AR5K_EEPROM_POWER_M);
-               cdata->pwr[3] = ((val << 4) & AR5K_EEPROM_POWER_M);
-
-               AR5K_EEPROM_READ(offset++, val);
-               cdata->pwr[3] |= ((val >> 12) & 0xf);
-               cdata->pwr[4] = ((val >> 6) & AR5K_EEPROM_POWER_M);
-               cdata->pwr[5] = (val  & AR5K_EEPROM_POWER_M);
-
-               AR5K_EEPROM_READ(offset++, val);
-               cdata->pwr[6] = ((val >> 10) & AR5K_EEPROM_POWER_M);
-               cdata->pwr[7] = ((val >> 4) & AR5K_EEPROM_POWER_M);
-               cdata->pwr[8] = ((val << 2) & AR5K_EEPROM_POWER_M);
-
-               AR5K_EEPROM_READ(offset++, val);
-               cdata->pwr[8] |= ((val >> 14) & 0x3);
-               cdata->pwr[9] = ((val >> 8) & AR5K_EEPROM_POWER_M);
-               cdata->pwr[10] = ((val >> 2) & AR5K_EEPROM_POWER_M);
-
-               ath5k_get_pcdac_intercepts(ah, cdata->pcdac_min,
-                       cdata->pcdac_max, cdata->pcdac);
-       }
-
-       return ath5k_eeprom_convert_pcal_info_5111(ah, mode, pcal);
-}
-
-
-/*
- * Read power calibration for RF5112 chips
- *
- * For RF5112 we have 4 XPD -eXternal Power Detector- curves
- * for each calibrated channel on 0, -6, -12 and -18dbm but we only
- * use the higher (3) and the lower (0) curves. Each curve has 0.5dB
- * power steps on x axis and PCDAC steps on y axis and looks like a
- * linear function. To recreate the curve and pass the power values
- * on hw, we read 4 points for xpd 0 (lower gain -> max power)
- * and 3 points for xpd 3 (higher gain -> lower power) here and
- * interpolate later.
- *
- * Note: Many vendors just use xpd 0 so xpd 3 is zeroed.
- */
-
-/* Convert RF5112 specific data to generic raw data
- * used by interpolation code */
-static int
-ath5k_eeprom_convert_pcal_info_5112(struct ath5k_hw *ah, int mode,
-                               struct ath5k_chan_pcal_info *chinfo)
-{
-       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
-       struct ath5k_chan_pcal_info_rf5112 *pcinfo;
-       u8 *pdgain_idx = ee->ee_pdc_to_idx[mode];
-       unsigned int pier, pdg, point;
-
-       /* Fill raw data for each calibration pier */
-       for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) {
-
-               pcinfo = &chinfo[pier].rf5112_info;
-
-               /* Allocate pd_curves for this cal pier */
-               chinfo[pier].pd_curves =
-                               kcalloc(AR5K_EEPROM_N_PD_CURVES,
-                                       sizeof(struct ath5k_pdgain_info),
-                                       GFP_KERNEL);
-
-               if (!chinfo[pier].pd_curves)
-                       return -ENOMEM;
-
-               /* Fill pd_curves */
-               for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) {
-
-                       u8 idx = pdgain_idx[pdg];
-                       struct ath5k_pdgain_info *pd =
-                                       &chinfo[pier].pd_curves[idx];
-
-                       /* Lowest gain curve (max power) */
-                       if (pdg == 0) {
-                               /* One more point for better accuracy */
-                               pd->pd_points = AR5K_EEPROM_N_XPD0_POINTS;
-
-                               /* Allocate pd points for this curve */
-                               pd->pd_step = kcalloc(pd->pd_points,
-                                               sizeof(u8), GFP_KERNEL);
-
-                               if (!pd->pd_step)
-                                       return -ENOMEM;
-
-                               pd->pd_pwr = kcalloc(pd->pd_points,
-                                               sizeof(s16), GFP_KERNEL);
-
-                               if (!pd->pd_pwr)
-                                       return -ENOMEM;
-
-
-                               /* Fill raw dataset
-                                * (all power levels are in 0.25dB units) */
-                               pd->pd_step[0] = pcinfo->pcdac_x0[0];
-                               pd->pd_pwr[0] = pcinfo->pwr_x0[0];
-
-                               for (point = 1; point < pd->pd_points;
-                               point++) {
-                                       /* Absolute values */
-                                       pd->pd_pwr[point] =
-                                               pcinfo->pwr_x0[point];
-
-                                       /* Deltas */
-                                       pd->pd_step[point] =
-                                               pd->pd_step[point - 1] +
-                                               pcinfo->pcdac_x0[point];
-                               }
-
-                               /* Set min power for this frequency */
-                               chinfo[pier].min_pwr = pd->pd_pwr[0];
-
-                       /* Highest gain curve (min power) */
-                       } else if (pdg == 1) {
-
-                               pd->pd_points = AR5K_EEPROM_N_XPD3_POINTS;
-
-                               /* Allocate pd points for this curve */
-                               pd->pd_step = kcalloc(pd->pd_points,
-                                               sizeof(u8), GFP_KERNEL);
-
-                               if (!pd->pd_step)
-                                       return -ENOMEM;
-
-                               pd->pd_pwr = kcalloc(pd->pd_points,
-                                               sizeof(s16), GFP_KERNEL);
-
-                               if (!pd->pd_pwr)
-                                       return -ENOMEM;
-
-                               /* Fill raw dataset
-                                * (all power levels are in 0.25dB units) */
-                               for (point = 0; point < pd->pd_points;
-                               point++) {
-                                       /* Absolute values */
-                                       pd->pd_pwr[point] =
-                                               pcinfo->pwr_x3[point];
-
-                                       /* Fixed points */
-                                       pd->pd_step[point] =
-                                               pcinfo->pcdac_x3[point];
-                               }
-
-                               /* Since we have a higher gain curve
-                                * override min power */
-                               chinfo[pier].min_pwr = pd->pd_pwr[0];
-                       }
-               }
-       }
-
-       return 0;
-}
-
-/* Parse EEPROM data */
-static int
-ath5k_eeprom_read_pcal_info_5112(struct ath5k_hw *ah, int mode)
-{
-       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
-       struct ath5k_chan_pcal_info_rf5112 *chan_pcal_info;
-       struct ath5k_chan_pcal_info *gen_chan_info;
-       u8 *pdgain_idx = ee->ee_pdc_to_idx[mode];
-       u32 offset;
-       u8 i, c;
-       u16 val;
-       int ret;
-       u8 pd_gains = 0;
-
-       /* Count how many curves we have and
-        * identify them (which one of the 4
-        * available curves we have on each count).
-        * Curves are stored from lower (x0) to
-        * higher (x3) gain */
-       for (i = 0; i < AR5K_EEPROM_N_PD_CURVES; i++) {
-               /* ee_x_gain[mode] is x gain mask */
-               if ((ee->ee_x_gain[mode] >> i) & 0x1)
-                       pdgain_idx[pd_gains++] = i;
-       }
-       ee->ee_pd_gains[mode] = pd_gains;
-
-       if (pd_gains == 0 || pd_gains > 2)
-               return -EINVAL;
-
-       switch (mode) {
-       case AR5K_EEPROM_MODE_11A:
-               /*
-                * Read 5GHz EEPROM channels
-                */
-               offset = AR5K_EEPROM_GROUPS_START(ee->ee_version);
-               ath5k_eeprom_init_11a_pcal_freq(ah, offset);
-
-               offset += AR5K_EEPROM_GROUP2_OFFSET;
-               gen_chan_info = ee->ee_pwr_cal_a;
-               break;
-       case AR5K_EEPROM_MODE_11B:
-               offset = AR5K_EEPROM_GROUPS_START(ee->ee_version);
-               if (AR5K_EEPROM_HDR_11A(ee->ee_header))
-                       offset += AR5K_EEPROM_GROUP3_OFFSET;
-
-               /* NB: frequency piers parsed during mode init */
-               gen_chan_info = ee->ee_pwr_cal_b;
-               break;
-       case AR5K_EEPROM_MODE_11G:
-               offset = AR5K_EEPROM_GROUPS_START(ee->ee_version);
-               if (AR5K_EEPROM_HDR_11A(ee->ee_header))
-                       offset += AR5K_EEPROM_GROUP4_OFFSET;
-               else if (AR5K_EEPROM_HDR_11B(ee->ee_header))
-                       offset += AR5K_EEPROM_GROUP2_OFFSET;
-
-               /* NB: frequency piers parsed during mode init */
-               gen_chan_info = ee->ee_pwr_cal_g;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       for (i = 0; i < ee->ee_n_piers[mode]; i++) {
-               chan_pcal_info = &gen_chan_info[i].rf5112_info;
-
-               /* Power values in quarter dB
-                * for the lower xpd gain curve
-                * (0 dBm -> higher output power) */
-               for (c = 0; c < AR5K_EEPROM_N_XPD0_POINTS; c++) {
-                       AR5K_EEPROM_READ(offset++, val);
-                       chan_pcal_info->pwr_x0[c] = (s8) (val & 0xff);
-                       chan_pcal_info->pwr_x0[++c] = (s8) ((val >> 8) & 0xff);
-               }
-
-               /* PCDAC steps
-                * corresponding to the above power
-                * measurements */
-               AR5K_EEPROM_READ(offset++, val);
-               chan_pcal_info->pcdac_x0[1] = (val & 0x1f);
-               chan_pcal_info->pcdac_x0[2] = ((val >> 5) & 0x1f);
-               chan_pcal_info->pcdac_x0[3] = ((val >> 10) & 0x1f);
-
-               /* Power values in quarter dB
-                * for the higher xpd gain curve
-                * (18 dBm -> lower output power) */
-               AR5K_EEPROM_READ(offset++, val);
-               chan_pcal_info->pwr_x3[0] = (s8) (val & 0xff);
-               chan_pcal_info->pwr_x3[1] = (s8) ((val >> 8) & 0xff);
-
-               AR5K_EEPROM_READ(offset++, val);
-               chan_pcal_info->pwr_x3[2] = (val & 0xff);
-
-               /* PCDAC steps
-                * corresponding to the above power
-                * measurements (fixed) */
-               chan_pcal_info->pcdac_x3[0] = 20;
-               chan_pcal_info->pcdac_x3[1] = 35;
-               chan_pcal_info->pcdac_x3[2] = 63;
-
-               if (ee->ee_version >= AR5K_EEPROM_VERSION_4_3) {
-                       chan_pcal_info->pcdac_x0[0] = ((val >> 8) & 0x3f);
-
-                       /* Last xpd0 power level is also channel maximum */
-                       gen_chan_info[i].max_pwr = chan_pcal_info->pwr_x0[3];
-               } else {
-                       chan_pcal_info->pcdac_x0[0] = 1;
-                       gen_chan_info[i].max_pwr = (s8) ((val >> 8) & 0xff);
-               }
-
-       }
-
-       return ath5k_eeprom_convert_pcal_info_5112(ah, mode, gen_chan_info);
-}
-
-
-/*
- * Read power calibration for RF2413 chips
- *
- * For RF2413 we have a Power to PDDAC table (Power Detector)
- * instead of a PCDAC and 4 pd gain curves for each calibrated channel.
- * Each curve has power on x axis in 0.5 db steps and PDDADC steps on y
- * axis and looks like an exponential function like the RF5111 curve.
- *
- * To recreate the curves we read here the points and interpolate
- * later. Note that in most cases only 2 (higher and lower) curves are
- * used (like RF5112) but vendors have the oportunity to include all
- * 4 curves on eeprom. The final curve (higher power) has an extra
- * point for better accuracy like RF5112.
- */
-
-/* For RF2413 power calibration data doesn't start on a fixed location and
- * if a mode is not supported, it's section is missing -not zeroed-.
- * So we need to calculate the starting offset for each section by using
- * these two functions */
-
-/* Return the size of each section based on the mode and the number of pd
- * gains available (maximum 4). */
-static inline unsigned int
-ath5k_pdgains_size_2413(struct ath5k_eeprom_info *ee, unsigned int mode)
-{
-       static const unsigned int pdgains_size[] = { 4, 6, 9, 12 };
-       unsigned int sz;
-
-       sz = pdgains_size[ee->ee_pd_gains[mode] - 1];
-       sz *= ee->ee_n_piers[mode];
-
-       return sz;
-}
-
-/* Return the starting offset for a section based on the modes supported
- * and each section's size. */
-static unsigned int
-ath5k_cal_data_offset_2413(struct ath5k_eeprom_info *ee, int mode)
-{
-       u32 offset = AR5K_EEPROM_CAL_DATA_START(ee->ee_misc4);
-
-       switch(mode) {
-       case AR5K_EEPROM_MODE_11G:
-               if (AR5K_EEPROM_HDR_11B(ee->ee_header))
-                       offset += ath5k_pdgains_size_2413(ee,
-                                       AR5K_EEPROM_MODE_11B) +
-                                       AR5K_EEPROM_N_2GHZ_CHAN_2413 / 2;
-               /* fall through */
-       case AR5K_EEPROM_MODE_11B:
-               if (AR5K_EEPROM_HDR_11A(ee->ee_header))
-                       offset += ath5k_pdgains_size_2413(ee,
-                                       AR5K_EEPROM_MODE_11A) +
-                                       AR5K_EEPROM_N_5GHZ_CHAN / 2;
-               /* fall through */
-       case AR5K_EEPROM_MODE_11A:
-               break;
-       default:
-               break;
-       }
-
-       return offset;
-}
-
-/* Convert RF2413 specific data to generic raw data
- * used by interpolation code */
-static int
-ath5k_eeprom_convert_pcal_info_2413(struct ath5k_hw *ah, int mode,
-                               struct ath5k_chan_pcal_info *chinfo)
-{
-       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
-       struct ath5k_chan_pcal_info_rf2413 *pcinfo;
-       u8 *pdgain_idx = ee->ee_pdc_to_idx[mode];
-       unsigned int pier, pdg, point;
-
-       /* Fill raw data for each calibration pier */
-       for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) {
-
-               pcinfo = &chinfo[pier].rf2413_info;
-
-               /* Allocate pd_curves for this cal pier */
-               chinfo[pier].pd_curves =
-                               kcalloc(AR5K_EEPROM_N_PD_CURVES,
-                                       sizeof(struct ath5k_pdgain_info),
-                                       GFP_KERNEL);
-
-               if (!chinfo[pier].pd_curves)
-                       return -ENOMEM;
-
-               /* Fill pd_curves */
-               for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) {
-
-                       u8 idx = pdgain_idx[pdg];
-                       struct ath5k_pdgain_info *pd =
-                                       &chinfo[pier].pd_curves[idx];
-
-                       /* One more point for the highest power
-                        * curve (lowest gain) */
-                       if (pdg == ee->ee_pd_gains[mode] - 1)
-                               pd->pd_points = AR5K_EEPROM_N_PD_POINTS;
-                       else
-                               pd->pd_points = AR5K_EEPROM_N_PD_POINTS - 1;
-
-                       /* Allocate pd points for this curve */
-                       pd->pd_step = kcalloc(pd->pd_points,
-                                       sizeof(u8), GFP_KERNEL);
-
-                       if (!pd->pd_step)
-                               return -ENOMEM;
-
-                       pd->pd_pwr = kcalloc(pd->pd_points,
-                                       sizeof(s16), GFP_KERNEL);
-
-                       if (!pd->pd_pwr)
-                               return -ENOMEM;
-
-                       /* Fill raw dataset
-                        * convert all pwr levels to
-                        * quarter dB for RF5112 combatibility */
-                       pd->pd_step[0] = pcinfo->pddac_i[pdg];
-                       pd->pd_pwr[0] = 4 * pcinfo->pwr_i[pdg];
-
-                       for (point = 1; point < pd->pd_points; point++) {
-
-                               pd->pd_pwr[point] = pd->pd_pwr[point - 1] +
-                                       2 * pcinfo->pwr[pdg][point - 1];
-
-                               pd->pd_step[point] = pd->pd_step[point - 1] +
-                                               pcinfo->pddac[pdg][point - 1];
-
-                       }
-
-                       /* Highest gain curve -> min power */
-                       if (pdg == 0)
-                               chinfo[pier].min_pwr = pd->pd_pwr[0];
-
-                       /* Lowest gain curve -> max power */
-                       if (pdg == ee->ee_pd_gains[mode] - 1)
-                               chinfo[pier].max_pwr =
-                                       pd->pd_pwr[pd->pd_points - 1];
-               }
-       }
-
-       return 0;
-}
-
-/* Parse EEPROM data */
-static int
-ath5k_eeprom_read_pcal_info_2413(struct ath5k_hw *ah, int mode)
-{
-       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
-       struct ath5k_chan_pcal_info_rf2413 *pcinfo;
-       struct ath5k_chan_pcal_info *chinfo;
-       u8 *pdgain_idx = ee->ee_pdc_to_idx[mode];
-       u32 offset;
-       int idx, i, ret;
-       u16 val;
-       u8 pd_gains = 0;
-
-       /* Count how many curves we have and
-        * identify them (which one of the 4
-        * available curves we have on each count).
-        * Curves are stored from higher to
-        * lower gain so we go backwards */
-       for (idx = AR5K_EEPROM_N_PD_CURVES - 1; idx >= 0; idx--) {
-               /* ee_x_gain[mode] is x gain mask */
-               if ((ee->ee_x_gain[mode] >> idx) & 0x1)
-                       pdgain_idx[pd_gains++] = idx;
-
-       }
-       ee->ee_pd_gains[mode] = pd_gains;
-
-       if (pd_gains == 0)
-               return -EINVAL;
-
-       offset = ath5k_cal_data_offset_2413(ee, mode);
-       switch (mode) {
-       case AR5K_EEPROM_MODE_11A:
-               if (!AR5K_EEPROM_HDR_11A(ee->ee_header))
-                       return 0;
-
-               ath5k_eeprom_init_11a_pcal_freq(ah, offset);
-               offset += AR5K_EEPROM_N_5GHZ_CHAN / 2;
-               chinfo = ee->ee_pwr_cal_a;
-               break;
-       case AR5K_EEPROM_MODE_11B:
-               if (!AR5K_EEPROM_HDR_11B(ee->ee_header))
-                       return 0;
-
-               ath5k_eeprom_init_11bg_2413(ah, mode, offset);
-               offset += AR5K_EEPROM_N_2GHZ_CHAN_2413 / 2;
-               chinfo = ee->ee_pwr_cal_b;
-               break;
-       case AR5K_EEPROM_MODE_11G:
-               if (!AR5K_EEPROM_HDR_11G(ee->ee_header))
-                       return 0;
-
-               ath5k_eeprom_init_11bg_2413(ah, mode, offset);
-               offset += AR5K_EEPROM_N_2GHZ_CHAN_2413 / 2;
-               chinfo = ee->ee_pwr_cal_g;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       for (i = 0; i < ee->ee_n_piers[mode]; i++) {
-               pcinfo = &chinfo[i].rf2413_info;
-
-               /*
-                * Read pwr_i, pddac_i and the first
-                * 2 pd points (pwr, pddac)
-                */
-               AR5K_EEPROM_READ(offset++, val);
-               pcinfo->pwr_i[0] = val & 0x1f;
-               pcinfo->pddac_i[0] = (val >> 5) & 0x7f;
-               pcinfo->pwr[0][0] = (val >> 12) & 0xf;
-
-               AR5K_EEPROM_READ(offset++, val);
-               pcinfo->pddac[0][0] = val & 0x3f;
-               pcinfo->pwr[0][1] = (val >> 6) & 0xf;
-               pcinfo->pddac[0][1] = (val >> 10) & 0x3f;
-
-               AR5K_EEPROM_READ(offset++, val);
-               pcinfo->pwr[0][2] = val & 0xf;
-               pcinfo->pddac[0][2] = (val >> 4) & 0x3f;
-
-               pcinfo->pwr[0][3] = 0;
-               pcinfo->pddac[0][3] = 0;
-
-               if (pd_gains > 1) {
-                       /*
-                        * Pd gain 0 is not the last pd gain
-                        * so it only has 2 pd points.
-                        * Continue wih pd gain 1.
-                        */
-                       pcinfo->pwr_i[1] = (val >> 10) & 0x1f;
-
-                       pcinfo->pddac_i[1] = (val >> 15) & 0x1;
-                       AR5K_EEPROM_READ(offset++, val);
-                       pcinfo->pddac_i[1] |= (val & 0x3F) << 1;
-
-                       pcinfo->pwr[1][0] = (val >> 6) & 0xf;
-                       pcinfo->pddac[1][0] = (val >> 10) & 0x3f;
-
-                       AR5K_EEPROM_READ(offset++, val);
-                       pcinfo->pwr[1][1] = val & 0xf;
-                       pcinfo->pddac[1][1] = (val >> 4) & 0x3f;
-                       pcinfo->pwr[1][2] = (val >> 10) & 0xf;
-
-                       pcinfo->pddac[1][2] = (val >> 14) & 0x3;
-                       AR5K_EEPROM_READ(offset++, val);
-                       pcinfo->pddac[1][2] |= (val & 0xF) << 2;
-
-                       pcinfo->pwr[1][3] = 0;
-                       pcinfo->pddac[1][3] = 0;
-               } else if (pd_gains == 1) {
-                       /*
-                        * Pd gain 0 is the last one so
-                        * read the extra point.
-                        */
-                       pcinfo->pwr[0][3] = (val >> 10) & 0xf;
-
-                       pcinfo->pddac[0][3] = (val >> 14) & 0x3;
-                       AR5K_EEPROM_READ(offset++, val);
-                       pcinfo->pddac[0][3] |= (val & 0xF) << 2;
-               }
-
-               /*
-                * Proceed with the other pd_gains
-                * as above.
-                */
-               if (pd_gains > 2) {
-                       pcinfo->pwr_i[2] = (val >> 4) & 0x1f;
-                       pcinfo->pddac_i[2] = (val >> 9) & 0x7f;
-
-                       AR5K_EEPROM_READ(offset++, val);
-                       pcinfo->pwr[2][0] = (val >> 0) & 0xf;
-                       pcinfo->pddac[2][0] = (val >> 4) & 0x3f;
-                       pcinfo->pwr[2][1] = (val >> 10) & 0xf;
-
-                       pcinfo->pddac[2][1] = (val >> 14) & 0x3;
-                       AR5K_EEPROM_READ(offset++, val);
-                       pcinfo->pddac[2][1] |= (val & 0xF) << 2;
-
-                       pcinfo->pwr[2][2] = (val >> 4) & 0xf;
-                       pcinfo->pddac[2][2] = (val >> 8) & 0x3f;
-
-                       pcinfo->pwr[2][3] = 0;
-                       pcinfo->pddac[2][3] = 0;
-               } else if (pd_gains == 2) {
-                       pcinfo->pwr[1][3] = (val >> 4) & 0xf;
-                       pcinfo->pddac[1][3] = (val >> 8) & 0x3f;
-               }
-
-               if (pd_gains > 3) {
-                       pcinfo->pwr_i[3] = (val >> 14) & 0x3;
-                       AR5K_EEPROM_READ(offset++, val);
-                       pcinfo->pwr_i[3] |= ((val >> 0) & 0x7) << 2;
-
-                       pcinfo->pddac_i[3] = (val >> 3) & 0x7f;
-                       pcinfo->pwr[3][0] = (val >> 10) & 0xf;
-                       pcinfo->pddac[3][0] = (val >> 14) & 0x3;
-
-                       AR5K_EEPROM_READ(offset++, val);
-                       pcinfo->pddac[3][0] |= (val & 0xF) << 2;
-                       pcinfo->pwr[3][1] = (val >> 4) & 0xf;
-                       pcinfo->pddac[3][1] = (val >> 8) & 0x3f;
-
-                       pcinfo->pwr[3][2] = (val >> 14) & 0x3;
-                       AR5K_EEPROM_READ(offset++, val);
-                       pcinfo->pwr[3][2] |= ((val >> 0) & 0x3) << 2;
-
-                       pcinfo->pddac[3][2] = (val >> 2) & 0x3f;
-                       pcinfo->pwr[3][3] = (val >> 8) & 0xf;
-
-                       pcinfo->pddac[3][3] = (val >> 12) & 0xF;
-                       AR5K_EEPROM_READ(offset++, val);
-                       pcinfo->pddac[3][3] |= ((val >> 0) & 0x3) << 4;
-               } else if (pd_gains == 3) {
-                       pcinfo->pwr[2][3] = (val >> 14) & 0x3;
-                       AR5K_EEPROM_READ(offset++, val);
-                       pcinfo->pwr[2][3] |= ((val >> 0) & 0x3) << 2;
-
-                       pcinfo->pddac[2][3] = (val >> 2) & 0x3f;
-               }
-       }
-
-       return ath5k_eeprom_convert_pcal_info_2413(ah, mode, chinfo);
-}
-
-
-/*
- * Read per rate target power (this is the maximum tx power
- * supported by the card). This info is used when setting
- * tx power, no matter the channel.
- *
- * This also works for v5 EEPROMs.
- */
-static int
-ath5k_eeprom_read_target_rate_pwr_info(struct ath5k_hw *ah, unsigned int mode)
-{
-       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
-       struct ath5k_rate_pcal_info *rate_pcal_info;
-       u8 *rate_target_pwr_num;
-       u32 offset;
-       u16 val;
-       int ret, i;
-
-       offset = AR5K_EEPROM_TARGET_PWRSTART(ee->ee_misc1);
-       rate_target_pwr_num = &ee->ee_rate_target_pwr_num[mode];
-       switch (mode) {
-       case AR5K_EEPROM_MODE_11A:
-               offset += AR5K_EEPROM_TARGET_PWR_OFF_11A(ee->ee_version);
-               rate_pcal_info = ee->ee_rate_tpwr_a;
-               ee->ee_rate_target_pwr_num[mode] = AR5K_EEPROM_N_5GHZ_CHAN;
-               break;
-       case AR5K_EEPROM_MODE_11B:
-               offset += AR5K_EEPROM_TARGET_PWR_OFF_11B(ee->ee_version);
-               rate_pcal_info = ee->ee_rate_tpwr_b;
-               ee->ee_rate_target_pwr_num[mode] = 2; /* 3rd is g mode's 1st */
-               break;
-       case AR5K_EEPROM_MODE_11G:
-               offset += AR5K_EEPROM_TARGET_PWR_OFF_11G(ee->ee_version);
-               rate_pcal_info = ee->ee_rate_tpwr_g;
-               ee->ee_rate_target_pwr_num[mode] = AR5K_EEPROM_N_2GHZ_CHAN;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       /* Different freq mask for older eeproms (<= v3.2) */
-       if (ee->ee_version <= AR5K_EEPROM_VERSION_3_2) {
-               for (i = 0; i < (*rate_target_pwr_num); i++) {
-                       AR5K_EEPROM_READ(offset++, val);
-                       rate_pcal_info[i].freq =
-                           ath5k_eeprom_bin2freq(ee, (val >> 9) & 0x7f, mode);
-
-                       rate_pcal_info[i].target_power_6to24 = ((val >> 3) & 0x3f);
-                       rate_pcal_info[i].target_power_36 = (val << 3) & 0x3f;
-
-                       AR5K_EEPROM_READ(offset++, val);
-
-                       if (rate_pcal_info[i].freq == AR5K_EEPROM_CHANNEL_DIS ||
-                           val == 0) {
-                               (*rate_target_pwr_num) = i;
-                               break;
-                       }
-
-                       rate_pcal_info[i].target_power_36 |= ((val >> 13) & 0x7);
-                       rate_pcal_info[i].target_power_48 = ((val >> 7) & 0x3f);
-                       rate_pcal_info[i].target_power_54 = ((val >> 1) & 0x3f);
-               }
-       } else {
-               for (i = 0; i < (*rate_target_pwr_num); i++) {
-                       AR5K_EEPROM_READ(offset++, val);
-                       rate_pcal_info[i].freq =
-                           ath5k_eeprom_bin2freq(ee, (val >> 8) & 0xff, mode);
-
-                       rate_pcal_info[i].target_power_6to24 = ((val >> 2) & 0x3f);
-                       rate_pcal_info[i].target_power_36 = (val << 4) & 0x3f;
-
-                       AR5K_EEPROM_READ(offset++, val);
-
-                       if (rate_pcal_info[i].freq == AR5K_EEPROM_CHANNEL_DIS ||
-                           val == 0) {
-                               (*rate_target_pwr_num) = i;
-                               break;
-                       }
-
-                       rate_pcal_info[i].target_power_36 |= (val >> 12) & 0xf;
-                       rate_pcal_info[i].target_power_48 = ((val >> 6) & 0x3f);
-                       rate_pcal_info[i].target_power_54 = (val & 0x3f);
-               }
-       }
-
-       return 0;
-}
-
-/*
- * Read per channel calibration info from EEPROM
- *
- * This info is used to calibrate the baseband power table. Imagine
- * that for each channel there is a power curve that's hw specific
- * (depends on amplifier etc) and we try to "correct" this curve using
- * offests we pass on to phy chip (baseband -> before amplifier) so that
- * it can use accurate power values when setting tx power (takes amplifier's
- * performance on each channel into account).
- *
- * EEPROM provides us with the offsets for some pre-calibrated channels
- * and we have to interpolate to create the full table for these channels and
- * also the table for any channel.
- */
-static int
-ath5k_eeprom_read_pcal_info(struct ath5k_hw *ah)
-{
-       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
-       int (*read_pcal)(struct ath5k_hw *hw, int mode);
-       int mode;
-       int err;
-
-       if ((ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) &&
-                       (AR5K_EEPROM_EEMAP(ee->ee_misc0) == 1))
-               read_pcal = ath5k_eeprom_read_pcal_info_5112;
-       else if ((ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_0) &&
-                       (AR5K_EEPROM_EEMAP(ee->ee_misc0) == 2))
-               read_pcal = ath5k_eeprom_read_pcal_info_2413;
-       else
-               read_pcal = ath5k_eeprom_read_pcal_info_5111;
-
-
-       for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G;
-       mode++) {
-               err = read_pcal(ah, mode);
-               if (err)
-                       return err;
-
-               err = ath5k_eeprom_read_target_rate_pwr_info(ah, mode);
-               if (err < 0)
-                       return err;
-       }
-
-       return 0;
-}
-
-static int
-ath5k_eeprom_free_pcal_info(struct ath5k_hw *ah, int mode)
-{
-       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
-       struct ath5k_chan_pcal_info *chinfo;
-       u8 pier, pdg;
-
-       switch (mode) {
-       case AR5K_EEPROM_MODE_11A:
-               if (!AR5K_EEPROM_HDR_11A(ee->ee_header))
-                       return 0;
-               chinfo = ee->ee_pwr_cal_a;
-               break;
-       case AR5K_EEPROM_MODE_11B:
-               if (!AR5K_EEPROM_HDR_11B(ee->ee_header))
-                       return 0;
-               chinfo = ee->ee_pwr_cal_b;
-               break;
-       case AR5K_EEPROM_MODE_11G:
-               if (!AR5K_EEPROM_HDR_11G(ee->ee_header))
-                       return 0;
-               chinfo = ee->ee_pwr_cal_g;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) {
-               if (!chinfo[pier].pd_curves)
-                       continue;
-
-               for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) {
-                       struct ath5k_pdgain_info *pd =
-                                       &chinfo[pier].pd_curves[pdg];
-
-                       if (pd != NULL) {
-                               kfree(pd->pd_step);
-                               kfree(pd->pd_pwr);
-                       }
-               }
-
-               kfree(chinfo[pier].pd_curves);
-       }
-
-       return 0;
-}
-
-void
-ath5k_eeprom_detach(struct ath5k_hw *ah)
-{
-       u8 mode;
-
-       for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G; mode++)
-               ath5k_eeprom_free_pcal_info(ah, mode);
-}
-
-/* Read conformance test limits used for regulatory control */
-static int
-ath5k_eeprom_read_ctl_info(struct ath5k_hw *ah)
-{
-       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
-       struct ath5k_edge_power *rep;
-       unsigned int fmask, pmask;
-       unsigned int ctl_mode;
-       int ret, i, j;
-       u32 offset;
-       u16 val;
-
-       pmask = AR5K_EEPROM_POWER_M;
-       fmask = AR5K_EEPROM_FREQ_M(ee->ee_version);
-       offset = AR5K_EEPROM_CTL(ee->ee_version);
-       ee->ee_ctls = AR5K_EEPROM_N_CTLS(ee->ee_version);
-       for (i = 0; i < ee->ee_ctls; i += 2) {
-               AR5K_EEPROM_READ(offset++, val);
-               ee->ee_ctl[i] = (val >> 8) & 0xff;
-               ee->ee_ctl[i + 1] = val & 0xff;
-       }
-
-       offset = AR5K_EEPROM_GROUP8_OFFSET;
-       if (ee->ee_version >= AR5K_EEPROM_VERSION_4_0)
-               offset += AR5K_EEPROM_TARGET_PWRSTART(ee->ee_misc1) -
-                       AR5K_EEPROM_GROUP5_OFFSET;
-       else
-               offset += AR5K_EEPROM_GROUPS_START(ee->ee_version);
-
-       rep = ee->ee_ctl_pwr;
-       for(i = 0; i < ee->ee_ctls; i++) {
-               switch(ee->ee_ctl[i] & AR5K_CTL_MODE_M) {
-               case AR5K_CTL_11A:
-               case AR5K_CTL_TURBO:
-                       ctl_mode = AR5K_EEPROM_MODE_11A;
-                       break;
-               default:
-                       ctl_mode = AR5K_EEPROM_MODE_11G;
-                       break;
-               }
-               if (ee->ee_ctl[i] == 0) {
-                       if (ee->ee_version >= AR5K_EEPROM_VERSION_3_3)
-                               offset += 8;
-                       else
-                               offset += 7;
-                       rep += AR5K_EEPROM_N_EDGES;
-                       continue;
-               }
-               if (ee->ee_version >= AR5K_EEPROM_VERSION_3_3) {
-                       for (j = 0; j < AR5K_EEPROM_N_EDGES; j += 2) {
-                               AR5K_EEPROM_READ(offset++, val);
-                               rep[j].freq = (val >> 8) & fmask;
-                               rep[j + 1].freq = val & fmask;
-                       }
-                       for (j = 0; j < AR5K_EEPROM_N_EDGES; j += 2) {
-                               AR5K_EEPROM_READ(offset++, val);
-                               rep[j].edge = (val >> 8) & pmask;
-                               rep[j].flag = (val >> 14) & 1;
-                               rep[j + 1].edge = val & pmask;
-                               rep[j + 1].flag = (val >> 6) & 1;
-                       }
-               } else {
-                       AR5K_EEPROM_READ(offset++, val);
-                       rep[0].freq = (val >> 9) & fmask;
-                       rep[1].freq = (val >> 2) & fmask;
-                       rep[2].freq = (val << 5) & fmask;
-
-                       AR5K_EEPROM_READ(offset++, val);
-                       rep[2].freq |= (val >> 11) & 0x1f;
-                       rep[3].freq = (val >> 4) & fmask;
-                       rep[4].freq = (val << 3) & fmask;
-
-                       AR5K_EEPROM_READ(offset++, val);
-                       rep[4].freq |= (val >> 13) & 0x7;
-                       rep[5].freq = (val >> 6) & fmask;
-                       rep[6].freq = (val << 1) & fmask;
-
-                       AR5K_EEPROM_READ(offset++, val);
-                       rep[6].freq |= (val >> 15) & 0x1;
-                       rep[7].freq = (val >> 8) & fmask;
-
-                       rep[0].edge = (val >> 2) & pmask;
-                       rep[1].edge = (val << 4) & pmask;
-
-                       AR5K_EEPROM_READ(offset++, val);
-                       rep[1].edge |= (val >> 12) & 0xf;
-                       rep[2].edge = (val >> 6) & pmask;
-                       rep[3].edge = val & pmask;
-
-                       AR5K_EEPROM_READ(offset++, val);
-                       rep[4].edge = (val >> 10) & pmask;
-                       rep[5].edge = (val >> 4) & pmask;
-                       rep[6].edge = (val << 2) & pmask;
-
-                       AR5K_EEPROM_READ(offset++, val);
-                       rep[6].edge |= (val >> 14) & 0x3;
-                       rep[7].edge = (val >> 8) & pmask;
-               }
-               for (j = 0; j < AR5K_EEPROM_N_EDGES; j++) {
-                       rep[j].freq = ath5k_eeprom_bin2freq(ee,
-                               rep[j].freq, ctl_mode);
-               }
-               rep += AR5K_EEPROM_N_EDGES;
-       }
-
-       return 0;
-}
-
-
-/*
- * Initialize eeprom power tables
- */
-int
-ath5k_eeprom_init(struct ath5k_hw *ah)
-{
-       int err;
-
-       err = ath5k_eeprom_init_header(ah);
-       if (err < 0)
-               return err;
-
-       err = ath5k_eeprom_init_modes(ah);
-       if (err < 0)
-               return err;
-
-       err = ath5k_eeprom_read_pcal_info(ah);
-       if (err < 0)
-               return err;
-
-       err = ath5k_eeprom_read_ctl_info(ah);
-       if (err < 0)
-               return err;
-
-       return 0;
-}
-
-/*
- * Read the MAC address from eeprom
- */
-int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac)
-{
-       u8 mac_d[ETH_ALEN] = {};
-       u32 total, offset;
-       u16 data;
-       int octet, ret;
-
-       ret = ath5k_hw_eeprom_read(ah, 0x20, &data);
-       if (ret)
-               return ret;
-
-       for (offset = 0x1f, octet = 0, total = 0; offset >= 0x1d; offset--) {
-               ret = ath5k_hw_eeprom_read(ah, offset, &data);
-               if (ret)
-                       return ret;
-
-               total += data;
-               mac_d[octet + 1] = data & 0xff;
-               mac_d[octet] = data >> 8;
-               octet += 2;
-       }
-
-       if (!total || total == 3 * 0xffff)
-               return -EINVAL;
-
-       memcpy(mac, mac_d, ETH_ALEN);
-
-       return 0;
-}
-
-bool ath5k_eeprom_is_hb63(struct ath5k_hw *ah)
-{
-       u16 data;
-
-       ath5k_hw_eeprom_read(ah, AR5K_EEPROM_IS_HB63, &data);
-
-       if ((ah->ah_mac_version == (AR5K_SREV_AR2425 >> 4)) && data)
-               return true;
-       else
-               return false;
-}
-
diff --git a/drivers/net/wireless/ath5k/eeprom.h b/drivers/net/wireless/ath5k/eeprom.h
deleted file mode 100644 (file)
index b0c0606..0000000
+++ /dev/null
@@ -1,441 +0,0 @@
-/*
- * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
- * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
- *
- * Permission to use, copy, modify, and 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 ar5xxx EEPROM data offsets (set these on AR5K_EEPROM_BASE)
- */
-#define AR5K_EEPROM_MAGIC              0x003d  /* EEPROM Magic number */
-#define AR5K_EEPROM_MAGIC_VALUE                0x5aa5  /* Default - found on EEPROM */
-#define AR5K_EEPROM_MAGIC_5212         0x0000145c /* 5212 */
-#define AR5K_EEPROM_MAGIC_5211         0x0000145b /* 5211 */
-#define AR5K_EEPROM_MAGIC_5210         0x0000145a /* 5210 */
-
-#define        AR5K_EEPROM_IS_HB63             0x000b  /* Talon detect */
-#define AR5K_EEPROM_REG_DOMAIN         0x00bf  /* EEPROM regdom */
-#define AR5K_EEPROM_CHECKSUM           0x00c0  /* EEPROM checksum */
-#define AR5K_EEPROM_INFO_BASE          0x00c0  /* EEPROM header */
-#define AR5K_EEPROM_INFO_MAX           (0x400 - AR5K_EEPROM_INFO_BASE)
-#define AR5K_EEPROM_INFO_CKSUM         0xffff
-#define AR5K_EEPROM_INFO(_n)           (AR5K_EEPROM_INFO_BASE + (_n))
-
-#define AR5K_EEPROM_VERSION            AR5K_EEPROM_INFO(1)     /* EEPROM Version */
-#define AR5K_EEPROM_VERSION_3_0                0x3000  /* No idea what's going on before this version */
-#define AR5K_EEPROM_VERSION_3_1                0x3001  /* ob/db values for 2Ghz (ar5211_rfregs) */
-#define AR5K_EEPROM_VERSION_3_2                0x3002  /* different frequency representation (eeprom_bin2freq) */
-#define AR5K_EEPROM_VERSION_3_3                0x3003  /* offsets changed, has 32 CTLs (see below) and ee_false_detect (eeprom_read_modes) */
-#define AR5K_EEPROM_VERSION_3_4                0x3004  /* has ee_i_gain, ee_cck_ofdm_power_delta (eeprom_read_modes) */
-#define AR5K_EEPROM_VERSION_4_0                0x4000  /* has ee_misc, ee_cal_pier, ee_turbo_max_power and ee_xr_power (eeprom_init) */
-#define AR5K_EEPROM_VERSION_4_1                0x4001  /* has ee_margin_tx_rx (eeprom_init) */
-#define AR5K_EEPROM_VERSION_4_2                0x4002  /* has ee_cck_ofdm_gain_delta (eeprom_init) */
-#define AR5K_EEPROM_VERSION_4_3                0x4003  /* power calibration changes */
-#define AR5K_EEPROM_VERSION_4_4                0x4004
-#define AR5K_EEPROM_VERSION_4_5                0x4005
-#define AR5K_EEPROM_VERSION_4_6                0x4006  /* has ee_scaled_cck_delta */
-#define AR5K_EEPROM_VERSION_4_7                0x3007  /* 4007 ? */
-#define AR5K_EEPROM_VERSION_4_9                0x4009  /* EAR futureproofing */
-#define AR5K_EEPROM_VERSION_5_0                0x5000  /* Has 2413 PDADC calibration etc */
-#define AR5K_EEPROM_VERSION_5_1                0x5001  /* Has capability values */
-#define AR5K_EEPROM_VERSION_5_3                0x5003  /* Has spur mitigation tables */
-
-#define AR5K_EEPROM_MODE_11A           0
-#define AR5K_EEPROM_MODE_11B           1
-#define AR5K_EEPROM_MODE_11G           2
-
-#define AR5K_EEPROM_HDR                        AR5K_EEPROM_INFO(2)     /* Header that contains the device caps */
-#define AR5K_EEPROM_HDR_11A(_v)                (((_v) >> AR5K_EEPROM_MODE_11A) & 0x1)
-#define AR5K_EEPROM_HDR_11B(_v)                (((_v) >> AR5K_EEPROM_MODE_11B) & 0x1)
-#define AR5K_EEPROM_HDR_11G(_v)                (((_v) >> AR5K_EEPROM_MODE_11G) & 0x1)
-#define AR5K_EEPROM_HDR_T_2GHZ_DIS(_v) (((_v) >> 3) & 0x1)     /* Disable turbo for 2Ghz (?) */
-#define AR5K_EEPROM_HDR_T_5GHZ_DBM(_v) (((_v) >> 4) & 0x7f)    /* Max turbo power for a/XR mode (eeprom_init) */
-#define AR5K_EEPROM_HDR_DEVICE(_v)     (((_v) >> 11) & 0x7)
-#define AR5K_EEPROM_HDR_RFKILL(_v)     (((_v) >> 14) & 0x1)    /* Device has RFKill support */
-#define AR5K_EEPROM_HDR_T_5GHZ_DIS(_v) (((_v) >> 15) & 0x1)    /* Disable turbo for 5Ghz */
-
-#define AR5K_EEPROM_RFKILL_GPIO_SEL    0x0000001c
-#define AR5K_EEPROM_RFKILL_GPIO_SEL_S  2
-#define AR5K_EEPROM_RFKILL_POLARITY    0x00000002
-#define AR5K_EEPROM_RFKILL_POLARITY_S  1
-
-/* Newer EEPROMs are using a different offset */
-#define AR5K_EEPROM_OFF(_v, _v3_0, _v3_3) \
-       (((_v) >= AR5K_EEPROM_VERSION_3_3) ? _v3_3 : _v3_0)
-
-#define AR5K_EEPROM_ANT_GAIN(_v)       AR5K_EEPROM_OFF(_v, 0x00c4, 0x00c3)
-#define AR5K_EEPROM_ANT_GAIN_5GHZ(_v)  ((s8)(((_v) >> 8) & 0xff))
-#define AR5K_EEPROM_ANT_GAIN_2GHZ(_v)  ((s8)((_v) & 0xff))
-
-/* Misc values available since EEPROM 4.0 */
-#define AR5K_EEPROM_MISC0              AR5K_EEPROM_INFO(4)
-#define AR5K_EEPROM_EARSTART(_v)       ((_v) & 0xfff)
-#define AR5K_EEPROM_HDR_XR2_DIS(_v)    (((_v) >> 12) & 0x1)
-#define AR5K_EEPROM_HDR_XR5_DIS(_v)    (((_v) >> 13) & 0x1)
-#define AR5K_EEPROM_EEMAP(_v)          (((_v) >> 14) & 0x3)
-
-#define AR5K_EEPROM_MISC1                      AR5K_EEPROM_INFO(5)
-#define AR5K_EEPROM_TARGET_PWRSTART(_v)                ((_v) & 0xfff)
-#define AR5K_EEPROM_HAS32KHZCRYSTAL(_v)                (((_v) >> 14) & 0x1)
-#define AR5K_EEPROM_HAS32KHZCRYSTAL_OLD(_v)    (((_v) >> 15) & 0x1)
-
-#define AR5K_EEPROM_MISC2                      AR5K_EEPROM_INFO(6)
-#define AR5K_EEPROM_EEP_FILE_VERSION(_v)       (((_v) >> 8) & 0xff)
-#define AR5K_EEPROM_EAR_FILE_VERSION(_v)       ((_v) & 0xff)
-
-#define AR5K_EEPROM_MISC3              AR5K_EEPROM_INFO(7)
-#define AR5K_EEPROM_ART_BUILD_NUM(_v)  (((_v) >> 10) & 0x3f)
-#define AR5K_EEPROM_EAR_FILE_ID(_v)    ((_v) & 0xff)
-
-#define AR5K_EEPROM_MISC4              AR5K_EEPROM_INFO(8)
-#define AR5K_EEPROM_CAL_DATA_START(_v) (((_v) >> 4) & 0xfff)
-#define AR5K_EEPROM_MASK_R0(_v)                (((_v) >> 2) & 0x3)
-#define AR5K_EEPROM_MASK_R1(_v)                ((_v) & 0x3)
-
-#define AR5K_EEPROM_MISC5              AR5K_EEPROM_INFO(9)
-#define AR5K_EEPROM_COMP_DIS(_v)       ((_v) & 0x1)
-#define AR5K_EEPROM_AES_DIS(_v)                (((_v) >> 1) & 0x1)
-#define AR5K_EEPROM_FF_DIS(_v)         (((_v) >> 2) & 0x1)
-#define AR5K_EEPROM_BURST_DIS(_v)      (((_v) >> 3) & 0x1)
-#define AR5K_EEPROM_MAX_QCU(_v)                (((_v) >> 4) & 0xf)
-#define AR5K_EEPROM_HEAVY_CLIP_EN(_v)  (((_v) >> 8) & 0x1)
-#define AR5K_EEPROM_KEY_CACHE_SIZE(_v) (((_v) >> 12) & 0xf)
-
-#define AR5K_EEPROM_MISC6              AR5K_EEPROM_INFO(10)
-#define AR5K_EEPROM_TX_CHAIN_DIS       ((_v) & 0x8)
-#define AR5K_EEPROM_RX_CHAIN_DIS       (((_v) >> 3) & 0x8)
-#define AR5K_EEPROM_FCC_MID_EN         (((_v) >> 6) & 0x1)
-#define AR5K_EEPROM_JAP_U1EVEN_EN      (((_v) >> 7) & 0x1)
-#define AR5K_EEPROM_JAP_U2_EN          (((_v) >> 8) & 0x1)
-#define AR5K_EEPROM_JAP_U1ODD_EN       (((_v) >> 9) & 0x1)
-#define AR5K_EEPROM_JAP_11A_NEW_EN     (((_v) >> 10) & 0x1)
-
-/* calibration settings */
-#define AR5K_EEPROM_MODES_11A(_v)      AR5K_EEPROM_OFF(_v, 0x00c5, 0x00d4)
-#define AR5K_EEPROM_MODES_11B(_v)      AR5K_EEPROM_OFF(_v, 0x00d0, 0x00f2)
-#define AR5K_EEPROM_MODES_11G(_v)      AR5K_EEPROM_OFF(_v, 0x00da, 0x010d)
-#define AR5K_EEPROM_CTL(_v)            AR5K_EEPROM_OFF(_v, 0x00e4, 0x0128)     /* Conformance test limits */
-#define AR5K_EEPROM_GROUPS_START(_v)   AR5K_EEPROM_OFF(_v, 0x0100, 0x0150)     /* Start of Groups */
-#define AR5K_EEPROM_GROUP1_OFFSET      0x0
-#define AR5K_EEPROM_GROUP2_OFFSET      0x5
-#define AR5K_EEPROM_GROUP3_OFFSET      0x37
-#define AR5K_EEPROM_GROUP4_OFFSET      0x46
-#define AR5K_EEPROM_GROUP5_OFFSET      0x55
-#define AR5K_EEPROM_GROUP6_OFFSET      0x65
-#define AR5K_EEPROM_GROUP7_OFFSET      0x69
-#define AR5K_EEPROM_GROUP8_OFFSET      0x6f
-
-#define AR5K_EEPROM_TARGET_PWR_OFF_11A(_v)     AR5K_EEPROM_OFF(_v, AR5K_EEPROM_GROUPS_START(_v) + \
-                                                               AR5K_EEPROM_GROUP5_OFFSET, 0x0000)
-#define AR5K_EEPROM_TARGET_PWR_OFF_11B(_v)     AR5K_EEPROM_OFF(_v, AR5K_EEPROM_GROUPS_START(_v) + \
-                                                               AR5K_EEPROM_GROUP6_OFFSET, 0x0010)
-#define AR5K_EEPROM_TARGET_PWR_OFF_11G(_v)     AR5K_EEPROM_OFF(_v, AR5K_EEPROM_GROUPS_START(_v) + \
-                                                               AR5K_EEPROM_GROUP7_OFFSET, 0x0014)
-
-/* [3.1 - 3.3] */
-#define AR5K_EEPROM_OBDB0_2GHZ         0x00ec
-#define AR5K_EEPROM_OBDB1_2GHZ         0x00ed
-
-#define AR5K_EEPROM_PROTECT            0x003f  /* EEPROM protect status */
-#define AR5K_EEPROM_PROTECT_RD_0_31    0x0001  /* Read protection bit for offsets 0x0 - 0x1f */
-#define AR5K_EEPROM_PROTECT_WR_0_31    0x0002  /* Write protection bit for offsets 0x0 - 0x1f */
-#define AR5K_EEPROM_PROTECT_RD_32_63   0x0004  /* 0x20 - 0x3f */
-#define AR5K_EEPROM_PROTECT_WR_32_63   0x0008
-#define AR5K_EEPROM_PROTECT_RD_64_127  0x0010  /* 0x40 - 0x7f */
-#define AR5K_EEPROM_PROTECT_WR_64_127  0x0020
-#define AR5K_EEPROM_PROTECT_RD_128_191 0x0040  /* 0x80 - 0xbf (regdom) */
-#define AR5K_EEPROM_PROTECT_WR_128_191 0x0080
-#define AR5K_EEPROM_PROTECT_RD_192_207 0x0100  /* 0xc0 - 0xcf */
-#define AR5K_EEPROM_PROTECT_WR_192_207 0x0200
-#define AR5K_EEPROM_PROTECT_RD_208_223 0x0400  /* 0xd0 - 0xdf */
-#define AR5K_EEPROM_PROTECT_WR_208_223 0x0800
-#define AR5K_EEPROM_PROTECT_RD_224_239 0x1000  /* 0xe0 - 0xef */
-#define AR5K_EEPROM_PROTECT_WR_224_239 0x2000
-#define AR5K_EEPROM_PROTECT_RD_240_255 0x4000  /* 0xf0 - 0xff */
-#define AR5K_EEPROM_PROTECT_WR_240_255 0x8000
-
-/* Some EEPROM defines */
-#define AR5K_EEPROM_EEP_SCALE          100
-#define AR5K_EEPROM_EEP_DELTA          10
-#define AR5K_EEPROM_N_MODES            3
-#define AR5K_EEPROM_N_5GHZ_CHAN                10
-#define AR5K_EEPROM_N_2GHZ_CHAN                3
-#define AR5K_EEPROM_N_2GHZ_CHAN_2413   4
-#define        AR5K_EEPROM_N_2GHZ_CHAN_MAX     4
-#define AR5K_EEPROM_MAX_CHAN           10
-#define AR5K_EEPROM_N_PWR_POINTS_5111  11
-#define AR5K_EEPROM_N_PCDAC            11
-#define AR5K_EEPROM_N_PHASE_CAL                5
-#define AR5K_EEPROM_N_TEST_FREQ                8
-#define AR5K_EEPROM_N_EDGES            8
-#define AR5K_EEPROM_N_INTERCEPTS       11
-#define AR5K_EEPROM_FREQ_M(_v)         AR5K_EEPROM_OFF(_v, 0x7f, 0xff)
-#define AR5K_EEPROM_PCDAC_M            0x3f
-#define AR5K_EEPROM_PCDAC_START                1
-#define AR5K_EEPROM_PCDAC_STOP         63
-#define AR5K_EEPROM_PCDAC_STEP         1
-#define AR5K_EEPROM_NON_EDGE_M         0x40
-#define AR5K_EEPROM_CHANNEL_POWER      8
-#define AR5K_EEPROM_N_OBDB             4
-#define AR5K_EEPROM_OBDB_DIS           0xffff
-#define AR5K_EEPROM_CHANNEL_DIS                0xff
-#define AR5K_EEPROM_SCALE_OC_DELTA(_x) (((_x) * 2) / 10)
-#define AR5K_EEPROM_N_CTLS(_v)         AR5K_EEPROM_OFF(_v, 16, 32)
-#define AR5K_EEPROM_MAX_CTLS           32
-#define AR5K_EEPROM_N_PD_CURVES                4
-#define AR5K_EEPROM_N_XPD0_POINTS      4
-#define AR5K_EEPROM_N_XPD3_POINTS      3
-#define AR5K_EEPROM_N_PD_GAINS         4
-#define AR5K_EEPROM_N_PD_POINTS                5
-#define AR5K_EEPROM_N_INTERCEPT_10_2GHZ        35
-#define AR5K_EEPROM_N_INTERCEPT_10_5GHZ        55
-#define AR5K_EEPROM_POWER_M            0x3f
-#define AR5K_EEPROM_POWER_MIN          0
-#define AR5K_EEPROM_POWER_MAX          3150
-#define AR5K_EEPROM_POWER_STEP         50
-#define AR5K_EEPROM_POWER_TABLE_SIZE   64
-#define AR5K_EEPROM_N_POWER_LOC_11B    4
-#define AR5K_EEPROM_N_POWER_LOC_11G    6
-#define AR5K_EEPROM_I_GAIN             10
-#define AR5K_EEPROM_CCK_OFDM_DELTA     15
-#define AR5K_EEPROM_N_IQ_CAL           2
-
-#define AR5K_EEPROM_READ(_o, _v) do {                  \
-       ret = ath5k_hw_eeprom_read(ah, (_o), &(_v));    \
-       if (ret)                                        \
-               return ret;                             \
-} while (0)
-
-#define AR5K_EEPROM_READ_HDR(_o, _v)                                   \
-       AR5K_EEPROM_READ(_o, ah->ah_capabilities.cap_eeprom._v);        \
-
-enum ath5k_ant_setting {
-       AR5K_ANT_VARIABLE       = 0,    /* variable by programming */
-       AR5K_ANT_FIXED_A        = 1,    /* fixed to 11a frequencies */
-       AR5K_ANT_FIXED_B        = 2,    /* fixed to 11b frequencies */
-       AR5K_ANT_MAX            = 3,
-};
-
-enum ath5k_ctl_mode {
-       AR5K_CTL_11A = 0,
-       AR5K_CTL_11B = 1,
-       AR5K_CTL_11G = 2,
-       AR5K_CTL_TURBO = 3,
-       AR5K_CTL_TURBOG = 4,
-       AR5K_CTL_2GHT20 = 5,
-       AR5K_CTL_5GHT20 = 6,
-       AR5K_CTL_2GHT40 = 7,
-       AR5K_CTL_5GHT40 = 8,
-       AR5K_CTL_MODE_M = 15,
-};
-
-/* Default CTL ids for the 3 main reg domains.
- * Atheros only uses these by default but vendors
- * can have up to 32 different CTLs for different
- * scenarios. Note that theese values are ORed with
- * the mode id (above) so we can have up to 24 CTL
- * datasets out of these 3 main regdomains. That leaves
- * 8 ids that can be used by vendors and since 0x20 is
- * missing from HAL sources i guess this is the set of
- * custom CTLs vendors can use. */
-#define        AR5K_CTL_FCC    0x10
-#define        AR5K_CTL_CUSTOM 0x20
-#define        AR5K_CTL_ETSI   0x30
-#define        AR5K_CTL_MKK    0x40
-
-/* Indicates a CTL with only mode set and
- * no reg domain mapping, such CTLs are used
- * for world roaming domains or simply when
- * a reg domain is not set */
-#define        AR5K_CTL_NO_REGDOMAIN   0xf0
-
-/* Indicates an empty (invalid) CTL */
-#define AR5K_CTL_NO_CTL                0xff
-
-/* Per channel calibration data, used for power table setup */
-struct ath5k_chan_pcal_info_rf5111 {
-       /* Power levels in half dbm units
-        * for one power curve. */
-       u8 pwr[AR5K_EEPROM_N_PWR_POINTS_5111];
-       /* PCDAC table steps
-        * for the above values */
-       u8 pcdac[AR5K_EEPROM_N_PWR_POINTS_5111];
-       /* Starting PCDAC step */
-       u8 pcdac_min;
-       /* Final PCDAC step */
-       u8 pcdac_max;
-};
-
-struct ath5k_chan_pcal_info_rf5112 {
-       /* Power levels in quarter dBm units
-        * for lower (0) and higher (3)
-        * level curves in 0.25dB units */
-       s8 pwr_x0[AR5K_EEPROM_N_XPD0_POINTS];
-       s8 pwr_x3[AR5K_EEPROM_N_XPD3_POINTS];
-       /* PCDAC table steps
-        * for the above values */
-       u8 pcdac_x0[AR5K_EEPROM_N_XPD0_POINTS];
-       u8 pcdac_x3[AR5K_EEPROM_N_XPD3_POINTS];
-};
-
-struct ath5k_chan_pcal_info_rf2413 {
-       /* Starting pwr/pddac values */
-       s8 pwr_i[AR5K_EEPROM_N_PD_GAINS];
-       u8 pddac_i[AR5K_EEPROM_N_PD_GAINS];
-       /* (pwr,pddac) points
-        * power levels in 0.5dB units */
-       s8 pwr[AR5K_EEPROM_N_PD_GAINS]
-               [AR5K_EEPROM_N_PD_POINTS];
-       u8 pddac[AR5K_EEPROM_N_PD_GAINS]
-               [AR5K_EEPROM_N_PD_POINTS];
-};
-
-enum ath5k_powertable_type {
-       AR5K_PWRTABLE_PWR_TO_PCDAC = 0,
-       AR5K_PWRTABLE_LINEAR_PCDAC = 1,
-       AR5K_PWRTABLE_PWR_TO_PDADC = 2,
-};
-
-struct ath5k_pdgain_info {
-       u8 pd_points;
-       u8 *pd_step;
-       /* Power values are in
-        * 0.25dB units */
-       s16 *pd_pwr;
-};
-
-struct ath5k_chan_pcal_info {
-       /* Frequency */
-       u16     freq;
-       /* Tx power boundaries */
-       s16     max_pwr;
-       s16     min_pwr;
-       union {
-               struct ath5k_chan_pcal_info_rf5111 rf5111_info;
-               struct ath5k_chan_pcal_info_rf5112 rf5112_info;
-               struct ath5k_chan_pcal_info_rf2413 rf2413_info;
-       };
-       /* Raw values used by phy code
-        * Curves are stored in order from lower
-        * gain to higher gain (max txpower -> min txpower) */
-       struct ath5k_pdgain_info *pd_curves;
-};
-
-/* Per rate calibration data for each mode,
- * used for rate power table setup.
- * Note: Values in 0.5dB units */
-struct ath5k_rate_pcal_info {
-       u16     freq; /* Frequency */
-       /* Power level for 6-24Mbit/s rates or
-        * 1Mb rate */
-       u16     target_power_6to24;
-       /* Power level for 36Mbit rate or
-        * 2Mb rate */
-       u16     target_power_36;
-       /* Power level for 48Mbit rate or
-        * 5.5Mbit rate */
-       u16     target_power_48;
-       /* Power level for 54Mbit rate or
-        * 11Mbit rate */
-       u16     target_power_54;
-};
-
-/* Power edges for conformance test limits */
-struct ath5k_edge_power {
-       u16 freq;
-       u16 edge; /* in half dBm */
-       bool flag;
-};
-
-/* EEPROM calibration data */
-struct ath5k_eeprom_info {
-
-       /* Header information */
-       u16     ee_magic;
-       u16     ee_protect;
-       u16     ee_regdomain;
-       u16     ee_version;
-       u16     ee_header;
-       u16     ee_ant_gain;
-       u16     ee_misc0;
-       u16     ee_misc1;
-       u16     ee_misc2;
-       u16     ee_misc3;
-       u16     ee_misc4;
-       u16     ee_misc5;
-       u16     ee_misc6;
-       u16     ee_cck_ofdm_gain_delta;
-       u16     ee_cck_ofdm_power_delta;
-       u16     ee_scaled_cck_delta;
-
-       /* RF Calibration settings (reset, rfregs) */
-       u16     ee_i_cal[AR5K_EEPROM_N_MODES];
-       u16     ee_q_cal[AR5K_EEPROM_N_MODES];
-       u16     ee_fixed_bias[AR5K_EEPROM_N_MODES];
-       u16     ee_turbo_max_power[AR5K_EEPROM_N_MODES];
-       u16     ee_xr_power[AR5K_EEPROM_N_MODES];
-       u16     ee_switch_settling[AR5K_EEPROM_N_MODES];
-       u16     ee_atn_tx_rx[AR5K_EEPROM_N_MODES];
-       u16     ee_ant_control[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_PCDAC];
-       u16     ee_ob[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_OBDB];
-       u16     ee_db[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_OBDB];
-       u16     ee_tx_end2xlna_enable[AR5K_EEPROM_N_MODES];
-       u16     ee_tx_end2xpa_disable[AR5K_EEPROM_N_MODES];
-       u16     ee_tx_frm2xpa_enable[AR5K_EEPROM_N_MODES];
-       u16     ee_thr_62[AR5K_EEPROM_N_MODES];
-       u16     ee_xlna_gain[AR5K_EEPROM_N_MODES];
-       u16     ee_xpd[AR5K_EEPROM_N_MODES];
-       u16     ee_x_gain[AR5K_EEPROM_N_MODES];
-       u16     ee_i_gain[AR5K_EEPROM_N_MODES];
-       u16     ee_margin_tx_rx[AR5K_EEPROM_N_MODES];
-       u16     ee_switch_settling_turbo[AR5K_EEPROM_N_MODES];
-       u16     ee_margin_tx_rx_turbo[AR5K_EEPROM_N_MODES];
-       u16     ee_atn_tx_rx_turbo[AR5K_EEPROM_N_MODES];
-
-       /* Power calibration data */
-       u16     ee_false_detect[AR5K_EEPROM_N_MODES];
-
-       /* Number of pd gain curves per mode */
-       u8      ee_pd_gains[AR5K_EEPROM_N_MODES];
-       /* Back mapping pdcurve number -> pdcurve index in pd->pd_curves */
-       u8      ee_pdc_to_idx[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_PD_GAINS];
-
-       u8      ee_n_piers[AR5K_EEPROM_N_MODES];
-       struct ath5k_chan_pcal_info     ee_pwr_cal_a[AR5K_EEPROM_N_5GHZ_CHAN];
-       struct ath5k_chan_pcal_info     ee_pwr_cal_b[AR5K_EEPROM_N_2GHZ_CHAN_MAX];
-       struct ath5k_chan_pcal_info     ee_pwr_cal_g[AR5K_EEPROM_N_2GHZ_CHAN_MAX];
-
-       /* Per rate target power levels */
-       u8      ee_rate_target_pwr_num[AR5K_EEPROM_N_MODES];
-       struct ath5k_rate_pcal_info     ee_rate_tpwr_a[AR5K_EEPROM_N_5GHZ_CHAN];
-       struct ath5k_rate_pcal_info     ee_rate_tpwr_b[AR5K_EEPROM_N_2GHZ_CHAN_MAX];
-       struct ath5k_rate_pcal_info     ee_rate_tpwr_g[AR5K_EEPROM_N_2GHZ_CHAN_MAX];
-
-       /* Conformance test limits (Unused) */
-       u8      ee_ctls;
-       u8      ee_ctl[AR5K_EEPROM_MAX_CTLS];
-       struct ath5k_edge_power ee_ctl_pwr[AR5K_EEPROM_N_EDGES * AR5K_EEPROM_MAX_CTLS];
-
-       /* Noise Floor Calibration settings */
-       s16     ee_noise_floor_thr[AR5K_EEPROM_N_MODES];
-       s8      ee_adc_desired_size[AR5K_EEPROM_N_MODES];
-       s8      ee_pga_desired_size[AR5K_EEPROM_N_MODES];
-       s8      ee_adc_desired_size_turbo[AR5K_EEPROM_N_MODES];
-       s8      ee_pga_desired_size_turbo[AR5K_EEPROM_N_MODES];
-       s8      ee_pd_gain_overlap;
-
-       u32     ee_antenna[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX];
-};
-
diff --git a/drivers/net/wireless/ath5k/gpio.c b/drivers/net/wireless/ath5k/gpio.c
deleted file mode 100644 (file)
index 64a27e7..0000000
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
- * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
- *
- * Permission to use, copy, modify, and 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.
- *
- */
-
-/****************\
-  GPIO Functions
-\****************/
-
-#include "ath5k.h"
-#include "reg.h"
-#include "debug.h"
-#include "base.h"
-
-/*
- * Set led state
- */
-void ath5k_hw_set_ledstate(struct ath5k_hw *ah, unsigned int state)
-{
-       u32 led;
-       /*5210 has different led mode handling*/
-       u32 led_5210;
-
-       ATH5K_TRACE(ah->ah_sc);
-
-       /*Reset led status*/
-       if (ah->ah_version != AR5K_AR5210)
-               AR5K_REG_DISABLE_BITS(ah, AR5K_PCICFG,
-                       AR5K_PCICFG_LEDMODE |  AR5K_PCICFG_LED);
-       else
-               AR5K_REG_DISABLE_BITS(ah, AR5K_PCICFG, AR5K_PCICFG_LED);
-
-       /*
-        * Some blinking values, define at your wish
-        */
-       switch (state) {
-       case AR5K_LED_SCAN:
-       case AR5K_LED_AUTH:
-               led = AR5K_PCICFG_LEDMODE_PROP | AR5K_PCICFG_LED_PEND;
-               led_5210 = AR5K_PCICFG_LED_PEND | AR5K_PCICFG_LED_BCTL;
-               break;
-
-       case AR5K_LED_INIT:
-               led = AR5K_PCICFG_LEDMODE_PROP | AR5K_PCICFG_LED_NONE;
-               led_5210 = AR5K_PCICFG_LED_PEND;
-               break;
-
-       case AR5K_LED_ASSOC:
-       case AR5K_LED_RUN:
-               led = AR5K_PCICFG_LEDMODE_PROP | AR5K_PCICFG_LED_ASSOC;
-               led_5210 = AR5K_PCICFG_LED_ASSOC;
-               break;
-
-       default:
-               led = AR5K_PCICFG_LEDMODE_PROM | AR5K_PCICFG_LED_NONE;
-               led_5210 = AR5K_PCICFG_LED_PEND;
-               break;
-       }
-
-       /*Write new status to the register*/
-       if (ah->ah_version != AR5K_AR5210)
-               AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, led);
-       else
-               AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, led_5210);
-}
-
-/*
- * Set GPIO inputs
- */
-int ath5k_hw_set_gpio_input(struct ath5k_hw *ah, u32 gpio)
-{
-       ATH5K_TRACE(ah->ah_sc);
-       if (gpio >= AR5K_NUM_GPIO)
-               return -EINVAL;
-
-       ath5k_hw_reg_write(ah,
-               (ath5k_hw_reg_read(ah, AR5K_GPIOCR) & ~AR5K_GPIOCR_OUT(gpio))
-               | AR5K_GPIOCR_IN(gpio), AR5K_GPIOCR);
-
-       return 0;
-}
-
-/*
- * Set GPIO outputs
- */
-int ath5k_hw_set_gpio_output(struct ath5k_hw *ah, u32 gpio)
-{
-       ATH5K_TRACE(ah->ah_sc);
-       if (gpio >= AR5K_NUM_GPIO)
-               return -EINVAL;
-
-       ath5k_hw_reg_write(ah,
-               (ath5k_hw_reg_read(ah, AR5K_GPIOCR) & ~AR5K_GPIOCR_OUT(gpio))
-               | AR5K_GPIOCR_OUT(gpio), AR5K_GPIOCR);
-
-       return 0;
-}
-
-/*
- * Get GPIO state
- */
-u32 ath5k_hw_get_gpio(struct ath5k_hw *ah, u32 gpio)
-{
-       ATH5K_TRACE(ah->ah_sc);
-       if (gpio >= AR5K_NUM_GPIO)
-               return 0xffffffff;
-
-       /* GPIO input magic */
-       return ((ath5k_hw_reg_read(ah, AR5K_GPIODI) & AR5K_GPIODI_M) >> gpio) &
-               0x1;
-}
-
-/*
- * Set GPIO state
- */
-int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val)
-{
-       u32 data;
-       ATH5K_TRACE(ah->ah_sc);
-
-       if (gpio >= AR5K_NUM_GPIO)
-               return -EINVAL;
-
-       /* GPIO output magic */
-       data = ath5k_hw_reg_read(ah, AR5K_GPIODO);
-
-       data &= ~(1 << gpio);
-       data |= (val & 1) << gpio;
-
-       ath5k_hw_reg_write(ah, data, AR5K_GPIODO);
-
-       return 0;
-}
-
-/*
- * Initialize the GPIO interrupt (RFKill switch)
- */
-void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio,
-               u32 interrupt_level)
-{
-       u32 data;
-
-       ATH5K_TRACE(ah->ah_sc);
-       if (gpio >= AR5K_NUM_GPIO)
-               return;
-
-       /*
-        * Set the GPIO interrupt
-        */
-       data = (ath5k_hw_reg_read(ah, AR5K_GPIOCR) &
-               ~(AR5K_GPIOCR_INT_SEL(gpio) | AR5K_GPIOCR_INT_SELH |
-               AR5K_GPIOCR_INT_ENA | AR5K_GPIOCR_OUT(gpio))) |
-               (AR5K_GPIOCR_INT_SEL(gpio) | AR5K_GPIOCR_INT_ENA);
-
-       ath5k_hw_reg_write(ah, interrupt_level ? data :
-               (data | AR5K_GPIOCR_INT_SELH), AR5K_GPIOCR);
-
-       ah->ah_imr |= AR5K_IMR_GPIO;
-
-       /* Enable GPIO interrupts */
-       AR5K_REG_ENABLE_BITS(ah, AR5K_PIMR, AR5K_IMR_GPIO);
-}
-
diff --git a/drivers/net/wireless/ath5k/initvals.c b/drivers/net/wireless/ath5k/initvals.c
deleted file mode 100644 (file)
index 61fb621..0000000
+++ /dev/null
@@ -1,1557 +0,0 @@
-/*
- * Initial register settings functions
- *
- * Copyright (c) 2004-2007 Reyk Floeter <reyk@openbsd.org>
- * Copyright (c) 2006-2009 Nick Kossifidis <mickflemm@gmail.com>
- * Copyright (c) 2007-2008 Jiri Slaby <jirislaby@gmail.com>
- *
- * Permission to use, copy, modify, and 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 "ath5k.h"
-#include "reg.h"
-#include "debug.h"
-#include "base.h"
-
-/*
- * Mode-independent initial register writes
- */
-
-struct ath5k_ini {
-       u16     ini_register;
-       u32     ini_value;
-
-       enum {
-               AR5K_INI_WRITE = 0,     /* Default */
-               AR5K_INI_READ = 1,      /* Cleared on read */
-       } ini_mode;
-};
-
-/*
- * Mode specific initial register values
- */
-
-struct ath5k_ini_mode {
-       u16     mode_register;
-       u32     mode_value[5];
-};
-
-/* Initial register settings for AR5210 */
-static const struct ath5k_ini ar5210_ini[] = {
-       /* PCU and MAC registers */
-       { AR5K_NOQCU_TXDP0,     0 },
-       { AR5K_NOQCU_TXDP1,     0 },
-       { AR5K_RXDP,            0 },
-       { AR5K_CR,              0 },
-       { AR5K_ISR,             0, AR5K_INI_READ },
-       { AR5K_IMR,             0 },
-       { AR5K_IER,             AR5K_IER_DISABLE },
-       { AR5K_BSR,             0, AR5K_INI_READ },
-       { AR5K_TXCFG,           AR5K_DMASIZE_128B },
-       { AR5K_RXCFG,           AR5K_DMASIZE_128B },
-       { AR5K_CFG,             AR5K_INIT_CFG },
-       { AR5K_TOPS,            8 },
-       { AR5K_RXNOFRM,         8 },
-       { AR5K_RPGTO,           0 },
-       { AR5K_TXNOFRM,         0 },
-       { AR5K_SFR,             0 },
-       { AR5K_MIBC,            0 },
-       { AR5K_MISC,            0 },
-       { AR5K_RX_FILTER_5210,  0 },
-       { AR5K_MCAST_FILTER0_5210, 0 },
-       { AR5K_MCAST_FILTER1_5210, 0 },
-       { AR5K_TX_MASK0,        0 },
-       { AR5K_TX_MASK1,        0 },
-       { AR5K_CLR_TMASK,       0 },
-       { AR5K_TRIG_LVL,        AR5K_TUNE_MIN_TX_FIFO_THRES },
-       { AR5K_DIAG_SW_5210,    0 },
-       { AR5K_RSSI_THR,        AR5K_TUNE_RSSI_THRES },
-       { AR5K_TSF_L32_5210,    0 },
-       { AR5K_TIMER0_5210,     0 },
-       { AR5K_TIMER1_5210,     0xffffffff },
-       { AR5K_TIMER2_5210,     0xffffffff },
-       { AR5K_TIMER3_5210,     1 },
-       { AR5K_CFP_DUR_5210,    0 },
-       { AR5K_CFP_PERIOD_5210, 0 },
-       /* PHY registers */
-       { AR5K_PHY(0),  0x00000047 },
-       { AR5K_PHY_AGC, 0x00000000 },
-       { AR5K_PHY(3),  0x09848ea6 },
-       { AR5K_PHY(4),  0x3d32e000 },
-       { AR5K_PHY(5),  0x0000076b },
-       { AR5K_PHY_ACT, AR5K_PHY_ACT_DISABLE },
-       { AR5K_PHY(8),  0x02020200 },
-       { AR5K_PHY(9),  0x00000e0e },
-       { AR5K_PHY(10), 0x0a020201 },
-       { AR5K_PHY(11), 0x00036ffc },
-       { AR5K_PHY(12), 0x00000000 },
-       { AR5K_PHY(13), 0x00000e0e },
-       { AR5K_PHY(14), 0x00000007 },
-       { AR5K_PHY(15), 0x00020100 },
-       { AR5K_PHY(16), 0x89630000 },
-       { AR5K_PHY(17), 0x1372169c },
-       { AR5K_PHY(18), 0x0018b633 },
-       { AR5K_PHY(19), 0x1284613c },
-       { AR5K_PHY(20), 0x0de8b8e0 },
-       { AR5K_PHY(21), 0x00074859 },
-       { AR5K_PHY(22), 0x7e80beba },
-       { AR5K_PHY(23), 0x313a665e },
-       { AR5K_PHY_AGCCTL, 0x00001d08 },
-       { AR5K_PHY(25), 0x0001ce00 },
-       { AR5K_PHY(26), 0x409a4190 },
-       { AR5K_PHY(28), 0x0000000f },
-       { AR5K_PHY(29), 0x00000080 },
-       { AR5K_PHY(30), 0x00000004 },
-       { AR5K_PHY(31), 0x00000018 },   /* 0x987c */
-       { AR5K_PHY(64), 0x00000000 },   /* 0x9900 */
-       { AR5K_PHY(65), 0x00000000 },
-       { AR5K_PHY(66), 0x00000000 },
-       { AR5K_PHY(67), 0x00800000 },
-       { AR5K_PHY(68), 0x00000003 },
-       /* BB gain table (64bytes) */
-       { AR5K_BB_GAIN(0), 0x00000000 },
-       { AR5K_BB_GAIN(1), 0x00000020 },
-       { AR5K_BB_GAIN(2), 0x00000010 },
-       { AR5K_BB_GAIN(3), 0x00000030 },
-       { AR5K_BB_GAIN(4), 0x00000008 },
-       { AR5K_BB_GAIN(5), 0x00000028 },
-       { AR5K_BB_GAIN(6), 0x00000028 },
-       { AR5K_BB_GAIN(7), 0x00000004 },
-       { AR5K_BB_GAIN(8), 0x00000024 },
-       { AR5K_BB_GAIN(9), 0x00000014 },
-       { AR5K_BB_GAIN(10), 0x00000034 },
-       { AR5K_BB_GAIN(11), 0x0000000c },
-       { AR5K_BB_GAIN(12), 0x0000002c },
-       { AR5K_BB_GAIN(13), 0x00000002 },
-       { AR5K_BB_GAIN(14), 0x00000022 },
-       { AR5K_BB_GAIN(15), 0x00000012 },
-       { AR5K_BB_GAIN(16), 0x00000032 },
-       { AR5K_BB_GAIN(17), 0x0000000a },
-       { AR5K_BB_GAIN(18), 0x0000002a },
-       { AR5K_BB_GAIN(19), 0x00000001 },
-       { AR5K_BB_GAIN(20), 0x00000021 },
-       { AR5K_BB_GAIN(21), 0x00000011 },
-       { AR5K_BB_GAIN(22), 0x00000031 },
-       { AR5K_BB_GAIN(23), 0x00000009 },
-       { AR5K_BB_GAIN(24), 0x00000029 },
-       { AR5K_BB_GAIN(25), 0x00000005 },
-       { AR5K_BB_GAIN(26), 0x00000025 },
-       { AR5K_BB_GAIN(27), 0x00000015 },
-       { AR5K_BB_GAIN(28), 0x00000035 },
-       { AR5K_BB_GAIN(29), 0x0000000d },
-       { AR5K_BB_GAIN(30), 0x0000002d },
-       { AR5K_BB_GAIN(31), 0x00000003 },
-       { AR5K_BB_GAIN(32), 0x00000023 },
-       { AR5K_BB_GAIN(33), 0x00000013 },
-       { AR5K_BB_GAIN(34), 0x00000033 },
-       { AR5K_BB_GAIN(35), 0x0000000b },
-       { AR5K_BB_GAIN(36), 0x0000002b },
-       { AR5K_BB_GAIN(37), 0x00000007 },
-       { AR5K_BB_GAIN(38), 0x00000027 },
-       { AR5K_BB_GAIN(39), 0x00000017 },
-       { AR5K_BB_GAIN(40), 0x00000037 },
-       { AR5K_BB_GAIN(41), 0x0000000f },
-       { AR5K_BB_GAIN(42), 0x0000002f },
-       { AR5K_BB_GAIN(43), 0x0000002f },
-       { AR5K_BB_GAIN(44), 0x0000002f },
-       { AR5K_BB_GAIN(45), 0x0000002f },
-       { AR5K_BB_GAIN(46), 0x0000002f },
-       { AR5K_BB_GAIN(47), 0x0000002f },
-       { AR5K_BB_GAIN(48), 0x0000002f },
-       { AR5K_BB_GAIN(49), 0x0000002f },
-       { AR5K_BB_GAIN(50), 0x0000002f },
-       { AR5K_BB_GAIN(51), 0x0000002f },
-       { AR5K_BB_GAIN(52), 0x0000002f },
-       { AR5K_BB_GAIN(53), 0x0000002f },
-       { AR5K_BB_GAIN(54), 0x0000002f },
-       { AR5K_BB_GAIN(55), 0x0000002f },
-       { AR5K_BB_GAIN(56), 0x0000002f },
-       { AR5K_BB_GAIN(57), 0x0000002f },
-       { AR5K_BB_GAIN(58), 0x0000002f },
-       { AR5K_BB_GAIN(59), 0x0000002f },
-       { AR5K_BB_GAIN(60), 0x0000002f },
-       { AR5K_BB_GAIN(61), 0x0000002f },
-       { AR5K_BB_GAIN(62), 0x0000002f },
-       { AR5K_BB_GAIN(63), 0x0000002f },
-       /* 5110 RF gain table (64btes) */
-       { AR5K_RF_GAIN(0), 0x0000001d },
-       { AR5K_RF_GAIN(1), 0x0000005d },
-       { AR5K_RF_GAIN(2), 0x0000009d },
-       { AR5K_RF_GAIN(3), 0x000000dd },
-       { AR5K_RF_GAIN(4), 0x0000011d },
-       { AR5K_RF_GAIN(5), 0x00000021 },
-       { AR5K_RF_GAIN(6), 0x00000061 },
-       { AR5K_RF_GAIN(7), 0x000000a1 },
-       { AR5K_RF_GAIN(8), 0x000000e1 },
-       { AR5K_RF_GAIN(9), 0x00000031 },
-       { AR5K_RF_GAIN(10), 0x00000071 },
-       { AR5K_RF_GAIN(11), 0x000000b1 },
-       { AR5K_RF_GAIN(12), 0x0000001c },
-       { AR5K_RF_GAIN(13), 0x0000005c },
-       { AR5K_RF_GAIN(14), 0x00000029 },
-       { AR5K_RF_GAIN(15), 0x00000069 },
-       { AR5K_RF_GAIN(16), 0x000000a9 },
-       { AR5K_RF_GAIN(17), 0x00000020 },
-       { AR5K_RF_GAIN(18), 0x00000019 },
-       { AR5K_RF_GAIN(19), 0x00000059 },
-       { AR5K_RF_GAIN(20), 0x00000099 },
-       { AR5K_RF_GAIN(21), 0x00000030 },
-       { AR5K_RF_GAIN(22), 0x00000005 },
-       { AR5K_RF_GAIN(23), 0x00000025 },
-       { AR5K_RF_GAIN(24), 0x00000065 },
-       { AR5K_RF_GAIN(25), 0x000000a5 },
-       { AR5K_RF_GAIN(26), 0x00000028 },
-       { AR5K_RF_GAIN(27), 0x00000068 },
-       { AR5K_RF_GAIN(28), 0x0000001f },
-       { AR5K_RF_GAIN(29), 0x0000001e },
-       { AR5K_RF_GAIN(30), 0x00000018 },
-       { AR5K_RF_GAIN(31), 0x00000058 },
-       { AR5K_RF_GAIN(32), 0x00000098 },
-       { AR5K_RF_GAIN(33), 0x00000003 },
-       { AR5K_RF_GAIN(34), 0x00000004 },
-       { AR5K_RF_GAIN(35), 0x00000044 },
-       { AR5K_RF_GAIN(36), 0x00000084 },
-       { AR5K_RF_GAIN(37), 0x00000013 },
-       { AR5K_RF_GAIN(38), 0x00000012 },
-       { AR5K_RF_GAIN(39), 0x00000052 },
-       { AR5K_RF_GAIN(40), 0x00000092 },
-       { AR5K_RF_GAIN(41), 0x000000d2 },
-       { AR5K_RF_GAIN(42), 0x0000002b },
-       { AR5K_RF_GAIN(43), 0x0000002a },
-       { AR5K_RF_GAIN(44), 0x0000006a },
-       { AR5K_RF_GAIN(45), 0x000000aa },
-       { AR5K_RF_GAIN(46), 0x0000001b },
-       { AR5K_RF_GAIN(47), 0x0000001a },
-       { AR5K_RF_GAIN(48), 0x0000005a },
-       { AR5K_RF_GAIN(49), 0x0000009a },
-       { AR5K_RF_GAIN(50), 0x000000da },
-       { AR5K_RF_GAIN(51), 0x00000006 },
-       { AR5K_RF_GAIN(52), 0x00000006 },
-       { AR5K_RF_GAIN(53), 0x00000006 },
-       { AR5K_RF_GAIN(54), 0x00000006 },
-       { AR5K_RF_GAIN(55), 0x00000006 },
-       { AR5K_RF_GAIN(56), 0x00000006 },
-       { AR5K_RF_GAIN(57), 0x00000006 },
-       { AR5K_RF_GAIN(58), 0x00000006 },
-       { AR5K_RF_GAIN(59), 0x00000006 },
-       { AR5K_RF_GAIN(60), 0x00000006 },
-       { AR5K_RF_GAIN(61), 0x00000006 },
-       { AR5K_RF_GAIN(62), 0x00000006 },
-       { AR5K_RF_GAIN(63), 0x00000006 },
-       /* PHY activation */
-       { AR5K_PHY(53), 0x00000020 },
-       { AR5K_PHY(51), 0x00000004 },
-       { AR5K_PHY(50), 0x00060106 },
-       { AR5K_PHY(39), 0x0000006d },
-       { AR5K_PHY(48), 0x00000000 },
-       { AR5K_PHY(52), 0x00000014 },
-       { AR5K_PHY_ACT, AR5K_PHY_ACT_ENABLE },
-};
-
-/* Initial register settings for AR5211 */
-static const struct ath5k_ini ar5211_ini[] = {
-       { AR5K_RXDP,            0x00000000 },
-       { AR5K_RTSD0,           0x84849c9c },
-       { AR5K_RTSD1,           0x7c7c7c7c },
-       { AR5K_RXCFG,           0x00000005 },
-       { AR5K_MIBC,            0x00000000 },
-       { AR5K_TOPS,            0x00000008 },
-       { AR5K_RXNOFRM,         0x00000008 },
-       { AR5K_TXNOFRM,         0x00000010 },
-       { AR5K_RPGTO,           0x00000000 },
-       { AR5K_RFCNT,           0x0000001f },
-       { AR5K_QUEUE_TXDP(0),   0x00000000 },
-       { AR5K_QUEUE_TXDP(1),   0x00000000 },
-       { AR5K_QUEUE_TXDP(2),   0x00000000 },
-       { AR5K_QUEUE_TXDP(3),   0x00000000 },
-       { AR5K_QUEUE_TXDP(4),   0x00000000 },
-       { AR5K_QUEUE_TXDP(5),   0x00000000 },
-       { AR5K_QUEUE_TXDP(6),   0x00000000 },
-       { AR5K_QUEUE_TXDP(7),   0x00000000 },
-       { AR5K_QUEUE_TXDP(8),   0x00000000 },
-       { AR5K_QUEUE_TXDP(9),   0x00000000 },
-       { AR5K_DCU_FP,          0x00000000 },
-       { AR5K_STA_ID1,         0x00000000 },
-       { AR5K_BSS_ID0,         0x00000000 },
-       { AR5K_BSS_ID1,         0x00000000 },
-       { AR5K_RSSI_THR,        0x00000000 },
-       { AR5K_CFP_PERIOD_5211, 0x00000000 },
-       { AR5K_TIMER0_5211,     0x00000030 },
-       { AR5K_TIMER1_5211,     0x0007ffff },
-       { AR5K_TIMER2_5211,     0x01ffffff },
-       { AR5K_TIMER3_5211,     0x00000031 },
-       { AR5K_CFP_DUR_5211,    0x00000000 },
-       { AR5K_RX_FILTER_5211,  0x00000000 },
-       { AR5K_MCAST_FILTER0_5211, 0x00000000 },
-       { AR5K_MCAST_FILTER1_5211, 0x00000002 },
-       { AR5K_DIAG_SW_5211,    0x00000000 },
-       { AR5K_ADDAC_TEST,      0x00000000 },
-       { AR5K_DEFAULT_ANTENNA, 0x00000000 },
-       /* PHY registers */
-       { AR5K_PHY_AGC, 0x00000000 },
-       { AR5K_PHY(3),  0x2d849093 },
-       { AR5K_PHY(4),  0x7d32e000 },
-       { AR5K_PHY(5),  0x00000f6b },
-       { AR5K_PHY_ACT, 0x00000000 },
-       { AR5K_PHY(11), 0x00026ffe },
-       { AR5K_PHY(12), 0x00000000 },
-       { AR5K_PHY(15), 0x00020100 },
-       { AR5K_PHY(16), 0x206a017a },
-       { AR5K_PHY(19), 0x1284613c },
-       { AR5K_PHY(21), 0x00000859 },
-       { AR5K_PHY(26), 0x409a4190 },   /* 0x9868 */
-       { AR5K_PHY(27), 0x050cb081 },
-       { AR5K_PHY(28), 0x0000000f },
-       { AR5K_PHY(29), 0x00000080 },
-       { AR5K_PHY(30), 0x0000000c },
-       { AR5K_PHY(64), 0x00000000 },
-       { AR5K_PHY(65), 0x00000000 },
-       { AR5K_PHY(66), 0x00000000 },
-       { AR5K_PHY(67), 0x00800000 },
-       { AR5K_PHY(68), 0x00000001 },
-       { AR5K_PHY(71), 0x0000092a },
-       { AR5K_PHY_IQ,  0x00000000 },
-       { AR5K_PHY(73), 0x00058a05 },
-       { AR5K_PHY(74), 0x00000001 },
-       { AR5K_PHY(75), 0x00000000 },
-       { AR5K_PHY_PAPD_PROBE, 0x00000000 },
-       { AR5K_PHY(77), 0x00000000 },   /* 0x9934 */
-       { AR5K_PHY(78), 0x00000000 },   /* 0x9938 */
-       { AR5K_PHY(79), 0x0000003f },   /* 0x993c */
-       { AR5K_PHY(80), 0x00000004 },
-       { AR5K_PHY(82), 0x00000000 },
-       { AR5K_PHY(83), 0x00000000 },
-       { AR5K_PHY(84), 0x00000000 },
-       { AR5K_PHY_RADAR, 0x5d50f14c },
-       { AR5K_PHY(86), 0x00000018 },
-       { AR5K_PHY(87), 0x004b6a8e },
-       /* Initial Power table (32bytes)
-        * common on all cards/modes.
-        * Note: Table is rewritten during
-        * txpower setup later using calibration
-        * data etc. so next write is non-common */
-       { AR5K_PHY_PCDAC_TXPOWER(1), 0x06ff05ff },
-       { AR5K_PHY_PCDAC_TXPOWER(2), 0x07ff07ff },
-       { AR5K_PHY_PCDAC_TXPOWER(3), 0x08ff08ff },
-       { AR5K_PHY_PCDAC_TXPOWER(4), 0x09ff09ff },
-       { AR5K_PHY_PCDAC_TXPOWER(5), 0x0aff0aff },
-       { AR5K_PHY_PCDAC_TXPOWER(6), 0x0bff0bff },
-       { AR5K_PHY_PCDAC_TXPOWER(7), 0x0cff0cff },
-       { AR5K_PHY_PCDAC_TXPOWER(8), 0x0dff0dff },
-       { AR5K_PHY_PCDAC_TXPOWER(9), 0x0fff0eff },
-       { AR5K_PHY_PCDAC_TXPOWER(10), 0x12ff12ff },
-       { AR5K_PHY_PCDAC_TXPOWER(11), 0x14ff13ff },
-       { AR5K_PHY_PCDAC_TXPOWER(12), 0x16ff15ff },
-       { AR5K_PHY_PCDAC_TXPOWER(13), 0x19ff17ff },
-       { AR5K_PHY_PCDAC_TXPOWER(14), 0x1bff1aff },
-       { AR5K_PHY_PCDAC_TXPOWER(15), 0x1eff1dff },
-       { AR5K_PHY_PCDAC_TXPOWER(16), 0x23ff20ff },
-       { AR5K_PHY_PCDAC_TXPOWER(17), 0x27ff25ff },
-       { AR5K_PHY_PCDAC_TXPOWER(18), 0x2cff29ff },
-       { AR5K_PHY_PCDAC_TXPOWER(19), 0x31ff2fff },
-       { AR5K_PHY_PCDAC_TXPOWER(20), 0x37ff34ff },
-       { AR5K_PHY_PCDAC_TXPOWER(21), 0x3aff3aff },
-       { AR5K_PHY_PCDAC_TXPOWER(22), 0x3aff3aff },
-       { AR5K_PHY_PCDAC_TXPOWER(23), 0x3aff3aff },
-       { AR5K_PHY_PCDAC_TXPOWER(24), 0x3aff3aff },
-       { AR5K_PHY_PCDAC_TXPOWER(25), 0x3aff3aff },
-       { AR5K_PHY_PCDAC_TXPOWER(26), 0x3aff3aff },
-       { AR5K_PHY_PCDAC_TXPOWER(27), 0x3aff3aff },
-       { AR5K_PHY_PCDAC_TXPOWER(28), 0x3aff3aff },
-       { AR5K_PHY_PCDAC_TXPOWER(29), 0x3aff3aff },
-       { AR5K_PHY_PCDAC_TXPOWER(30), 0x3aff3aff },
-       { AR5K_PHY_PCDAC_TXPOWER(31), 0x3aff3aff },
-       { AR5K_PHY_CCKTXCTL, 0x00000000 },
-       { AR5K_PHY(642), 0x503e4646 },
-       { AR5K_PHY_GAIN_2GHZ, 0x6480416c },
-       { AR5K_PHY(644), 0x0199a003 },
-       { AR5K_PHY(645), 0x044cd610 },
-       { AR5K_PHY(646), 0x13800040 },
-       { AR5K_PHY(647), 0x1be00060 },
-       { AR5K_PHY(648), 0x0c53800a },
-       { AR5K_PHY(649), 0x0014df3b },
-       { AR5K_PHY(650), 0x000001b5 },
-       { AR5K_PHY(651), 0x00000020 },
-};
-
-/* Initial mode-specific settings for AR5211
- * 5211 supports OFDM-only g (draft g) but we
- * need to test it !
- */
-static const struct ath5k_ini_mode ar5211_ini_mode[] = {
-       { AR5K_TXCFG,
-       /*        a         aTurbo        b       g (OFDM)    */
-          { 0x00000015, 0x00000015, 0x0000001d, 0x00000015 } },
-       { AR5K_QUEUE_DFS_LOCAL_IFS(0),
-          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
-       { AR5K_QUEUE_DFS_LOCAL_IFS(1),
-          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
-       { AR5K_QUEUE_DFS_LOCAL_IFS(2),
-          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
-       { AR5K_QUEUE_DFS_LOCAL_IFS(3),
-          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
-       { AR5K_QUEUE_DFS_LOCAL_IFS(4),
-          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
-       { AR5K_QUEUE_DFS_LOCAL_IFS(5),
-          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
-       { AR5K_QUEUE_DFS_LOCAL_IFS(6),
-          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
-       { AR5K_QUEUE_DFS_LOCAL_IFS(7),
-          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
-       { AR5K_QUEUE_DFS_LOCAL_IFS(8),
-          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
-       { AR5K_QUEUE_DFS_LOCAL_IFS(9),
-          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f } },
-       { AR5K_DCU_GBL_IFS_SLOT,
-          { 0x00000168, 0x000001e0, 0x000001b8, 0x00000168 } },
-       { AR5K_DCU_GBL_IFS_SIFS,
-          { 0x00000230, 0x000001e0, 0x000000b0, 0x00000230 } },
-       { AR5K_DCU_GBL_IFS_EIFS,
-          { 0x00000d98, 0x00001180, 0x00001f48, 0x00000d98 } },
-       { AR5K_DCU_GBL_IFS_MISC,
-          { 0x0000a0e0, 0x00014068, 0x00005880, 0x0000a0e0 } },
-       { AR5K_TIME_OUT,
-          { 0x04000400, 0x08000800, 0x20003000, 0x04000400 } },
-       { AR5K_USEC_5211,
-          { 0x0e8d8fa7, 0x0e8d8fcf, 0x01608f95, 0x0e8d8fa7 } },
-       { AR5K_PHY_TURBO,
-          { 0x00000000, 0x00000003, 0x00000000, 0x00000000 } },
-       { AR5K_PHY(8),
-          { 0x02020200, 0x02020200, 0x02010200, 0x02020200 } },
-       { AR5K_PHY(9),
-          { 0x00000e0e, 0x00000e0e, 0x00000707, 0x00000e0e } },
-       { AR5K_PHY(10),
-          { 0x0a020001, 0x0a020001, 0x05010000, 0x0a020001 } },
-       { AR5K_PHY(13),
-          { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
-       { AR5K_PHY(14),
-          { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b } },
-       { AR5K_PHY(17),
-          { 0x1372169c, 0x137216a5, 0x137216a8, 0x1372169c } },
-       { AR5K_PHY(18),
-          { 0x0018ba67, 0x0018ba67, 0x0018ba69, 0x0018ba69 } },
-       { AR5K_PHY(20),
-          { 0x0c28b4e0, 0x0c28b4e0, 0x0c28b4e0, 0x0c28b4e0 } },
-       { AR5K_PHY_SIG,
-          { 0x7e800d2e, 0x7e800d2e, 0x7ec00d2e, 0x7e800d2e } },
-       { AR5K_PHY_AGCCOARSE,
-          { 0x31375d5e, 0x31375d5e, 0x313a5d5e, 0x31375d5e } },
-       { AR5K_PHY_AGCCTL,
-          { 0x0000bd10, 0x0000bd10, 0x0000bd38, 0x0000bd10 } },
-       { AR5K_PHY_NF,
-          { 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 } },
-       { AR5K_PHY_RX_DELAY,
-          { 0x00002710, 0x00002710, 0x0000157c, 0x00002710 } },
-       { AR5K_PHY(70),
-          { 0x00000190, 0x00000190, 0x00000084, 0x00000190 } },
-       { AR5K_PHY_FRAME_CTL_5211,
-          { 0x6fe01020, 0x6fe01020, 0x6fe00920, 0x6fe01020 } },
-       { AR5K_PHY_PCDAC_TXPOWER_BASE,
-          { 0x05ff14ff, 0x05ff14ff, 0x05ff14ff, 0x05ff19ff } },
-       { AR5K_RF_BUFFER_CONTROL_4,
-          { 0x00000010, 0x00000014, 0x00000010, 0x00000010 } },
-};
-
-/* Initial register settings for AR5212 */
-static const struct ath5k_ini ar5212_ini_common_start[] = {
-       { AR5K_RXDP,            0x00000000 },
-       { AR5K_RXCFG,           0x00000005 },
-       { AR5K_MIBC,            0x00000000 },
-       { AR5K_TOPS,            0x00000008 },
-       { AR5K_RXNOFRM,         0x00000008 },
-       { AR5K_TXNOFRM,         0x00000010 },
-       { AR5K_RPGTO,           0x00000000 },
-       { AR5K_RFCNT,           0x0000001f },
-       { AR5K_QUEUE_TXDP(0),   0x00000000 },
-       { AR5K_QUEUE_TXDP(1),   0x00000000 },
-       { AR5K_QUEUE_TXDP(2),   0x00000000 },
-       { AR5K_QUEUE_TXDP(3),   0x00000000 },
-       { AR5K_QUEUE_TXDP(4),   0x00000000 },
-       { AR5K_QUEUE_TXDP(5),   0x00000000 },
-       { AR5K_QUEUE_TXDP(6),   0x00000000 },
-       { AR5K_QUEUE_TXDP(7),   0x00000000 },
-       { AR5K_QUEUE_TXDP(8),   0x00000000 },
-       { AR5K_QUEUE_TXDP(9),   0x00000000 },
-       { AR5K_DCU_FP,          0x00000000 },
-       { AR5K_DCU_TXP,         0x00000000 },
-       /* Tx filter table 0 (32 entries) */
-       { AR5K_DCU_TX_FILTER_0(0),  0x00000000 }, /* DCU 0 */
-       { AR5K_DCU_TX_FILTER_0(1),  0x00000000 },
-       { AR5K_DCU_TX_FILTER_0(2),  0x00000000 },
-       { AR5K_DCU_TX_FILTER_0(3),  0x00000000 },
-       { AR5K_DCU_TX_FILTER_0(4),  0x00000000 }, /* DCU 1 */
-       { AR5K_DCU_TX_FILTER_0(5),  0x00000000 },
-       { AR5K_DCU_TX_FILTER_0(6),  0x00000000 },
-       { AR5K_DCU_TX_FILTER_0(7),  0x00000000 },
-       { AR5K_DCU_TX_FILTER_0(8),  0x00000000 }, /* DCU 2 */
-       { AR5K_DCU_TX_FILTER_0(9),  0x00000000 },
-       { AR5K_DCU_TX_FILTER_0(10), 0x00000000 },
-       { AR5K_DCU_TX_FILTER_0(11), 0x00000000 },
-       { AR5K_DCU_TX_FILTER_0(12), 0x00000000 }, /* DCU 3 */
-       { AR5K_DCU_TX_FILTER_0(13), 0x00000000 },
-       { AR5K_DCU_TX_FILTER_0(14), 0x00000000 },
-       { AR5K_DCU_TX_FILTER_0(15), 0x00000000 },
-       { AR5K_DCU_TX_FILTER_0(16), 0x00000000 }, /* DCU 4 */
-       { AR5K_DCU_TX_FILTER_0(17), 0x00000000 },
-       { AR5K_DCU_TX_FILTER_0(18), 0x00000000 },
-       { AR5K_DCU_TX_FILTER_0(19), 0x00000000 },
-       { AR5K_DCU_TX_FILTER_0(20), 0x00000000 }, /* DCU 5 */
-       { AR5K_DCU_TX_FILTER_0(21), 0x00000000 },
-       { AR5K_DCU_TX_FILTER_0(22), 0x00000000 },
-       { AR5K_DCU_TX_FILTER_0(23), 0x00000000 },
-       { AR5K_DCU_TX_FILTER_0(24), 0x00000000 }, /* DCU 6 */
-       { AR5K_DCU_TX_FILTER_0(25), 0x00000000 },
-       { AR5K_DCU_TX_FILTER_0(26), 0x00000000 },
-       { AR5K_DCU_TX_FILTER_0(27), 0x00000000 },
-       { AR5K_DCU_TX_FILTER_0(28), 0x00000000 }, /* DCU 7 */
-       { AR5K_DCU_TX_FILTER_0(29), 0x00000000 },
-       { AR5K_DCU_TX_FILTER_0(30), 0x00000000 },
-       { AR5K_DCU_TX_FILTER_0(31), 0x00000000 },
-       /* Tx filter table 1 (16 entries) */
-       { AR5K_DCU_TX_FILTER_1(0),  0x00000000 },
-       { AR5K_DCU_TX_FILTER_1(1),  0x00000000 },
-       { AR5K_DCU_TX_FILTER_1(2),  0x00000000 },
-       { AR5K_DCU_TX_FILTER_1(3),  0x00000000 },
-       { AR5K_DCU_TX_FILTER_1(4),  0x00000000 },
-       { AR5K_DCU_TX_FILTER_1(5),  0x00000000 },
-       { AR5K_DCU_TX_FILTER_1(6),  0x00000000 },
-       { AR5K_DCU_TX_FILTER_1(7),  0x00000000 },
-       { AR5K_DCU_TX_FILTER_1(8),  0x00000000 },
-       { AR5K_DCU_TX_FILTER_1(9),  0x00000000 },
-       { AR5K_DCU_TX_FILTER_1(10), 0x00000000 },
-       { AR5K_DCU_TX_FILTER_1(11), 0x00000000 },
-       { AR5K_DCU_TX_FILTER_1(12), 0x00000000 },
-       { AR5K_DCU_TX_FILTER_1(13), 0x00000000 },
-       { AR5K_DCU_TX_FILTER_1(14), 0x00000000 },
-       { AR5K_DCU_TX_FILTER_1(15), 0x00000000 },
-       { AR5K_DCU_TX_FILTER_CLR, 0x00000000 },
-       { AR5K_DCU_TX_FILTER_SET, 0x00000000 },
-       { AR5K_DCU_TX_FILTER_CLR, 0x00000000 },
-       { AR5K_DCU_TX_FILTER_SET, 0x00000000 },
-       { AR5K_STA_ID1,         0x00000000 },
-       { AR5K_BSS_ID0,         0x00000000 },
-       { AR5K_BSS_ID1,         0x00000000 },
-       { AR5K_BEACON_5211,     0x00000000 },
-       { AR5K_CFP_PERIOD_5211, 0x00000000 },
-       { AR5K_TIMER0_5211,     0x00000030 },
-       { AR5K_TIMER1_5211,     0x0007ffff },
-       { AR5K_TIMER2_5211,     0x01ffffff },
-       { AR5K_TIMER3_5211,     0x00000031 },
-       { AR5K_CFP_DUR_5211,    0x00000000 },
-       { AR5K_RX_FILTER_5211,  0x00000000 },
-       { AR5K_DIAG_SW_5211,    0x00000000 },
-       { AR5K_ADDAC_TEST,      0x00000000 },
-       { AR5K_DEFAULT_ANTENNA, 0x00000000 },
-       { AR5K_FRAME_CTL_QOSM,  0x000fc78f },
-       { AR5K_XRMODE,          0x2a82301a },
-       { AR5K_XRDELAY,         0x05dc01e0 },
-       { AR5K_XRTIMEOUT,       0x1f402710 },
-       { AR5K_XRCHIRP,         0x01f40000 },
-       { AR5K_XRSTOMP,         0x00001e1c },
-       { AR5K_SLEEP0,          0x0002aaaa },
-       { AR5K_SLEEP1,          0x02005555 },
-       { AR5K_SLEEP2,          0x00000000 },
-       { AR5K_BSS_IDM0,        0xffffffff },
-       { AR5K_BSS_IDM1,        0x0000ffff },
-       { AR5K_TXPC,            0x00000000 },
-       { AR5K_PROFCNT_TX,      0x00000000 },
-       { AR5K_PROFCNT_RX,      0x00000000 },
-       { AR5K_PROFCNT_RXCLR,   0x00000000 },
-       { AR5K_PROFCNT_CYCLE,   0x00000000 },
-       { AR5K_QUIET_CTL1,      0x00000088 },
-       /* Initial rate duration table (32 entries )*/
-       { AR5K_RATE_DUR(0),     0x00000000 },
-       { AR5K_RATE_DUR(1),     0x0000008c },
-       { AR5K_RATE_DUR(2),     0x000000e4 },
-       { AR5K_RATE_DUR(3),     0x000002d5 },
-       { AR5K_RATE_DUR(4),     0x00000000 },
-       { AR5K_RATE_DUR(5),     0x00000000 },
-       { AR5K_RATE_DUR(6),     0x000000a0 },
-       { AR5K_RATE_DUR(7),     0x000001c9 },
-       { AR5K_RATE_DUR(8),     0x0000002c },
-       { AR5K_RATE_DUR(9),     0x0000002c },
-       { AR5K_RATE_DUR(10),    0x00000030 },
-       { AR5K_RATE_DUR(11),    0x0000003c },
-       { AR5K_RATE_DUR(12),    0x0000002c },
-       { AR5K_RATE_DUR(13),    0x0000002c },
-       { AR5K_RATE_DUR(14),    0x00000030 },
-       { AR5K_RATE_DUR(15),    0x0000003c },
-       { AR5K_RATE_DUR(16),    0x00000000 },
-       { AR5K_RATE_DUR(17),    0x00000000 },
-       { AR5K_RATE_DUR(18),    0x00000000 },
-       { AR5K_RATE_DUR(19),    0x00000000 },
-       { AR5K_RATE_DUR(20),    0x00000000 },
-       { AR5K_RATE_DUR(21),    0x00000000 },
-       { AR5K_RATE_DUR(22),    0x00000000 },
-       { AR5K_RATE_DUR(23),    0x00000000 },
-       { AR5K_RATE_DUR(24),    0x000000d5 },
-       { AR5K_RATE_DUR(25),    0x000000df },
-       { AR5K_RATE_DUR(26),    0x00000102 },
-       { AR5K_RATE_DUR(27),    0x0000013a },
-       { AR5K_RATE_DUR(28),    0x00000075 },
-       { AR5K_RATE_DUR(29),    0x0000007f },
-       { AR5K_RATE_DUR(30),    0x000000a2 },
-       { AR5K_RATE_DUR(31),    0x00000000 },
-       { AR5K_QUIET_CTL2,      0x00010002 },
-       { AR5K_TSF_PARM,        0x00000001 },
-       { AR5K_QOS_NOACK,       0x000000c0 },
-       { AR5K_PHY_ERR_FIL,     0x00000000 },
-       { AR5K_XRLAT_TX,        0x00000168 },
-       { AR5K_ACKSIFS,         0x00000000 },
-       /* Rate -> db table
-        * notice ...03<-02<-01<-00 ! */
-       { AR5K_RATE2DB(0),      0x03020100 },
-       { AR5K_RATE2DB(1),      0x07060504 },
-       { AR5K_RATE2DB(2),      0x0b0a0908 },
-       { AR5K_RATE2DB(3),      0x0f0e0d0c },
-       { AR5K_RATE2DB(4),      0x13121110 },
-       { AR5K_RATE2DB(5),      0x17161514 },
-       { AR5K_RATE2DB(6),      0x1b1a1918 },
-       { AR5K_RATE2DB(7),      0x1f1e1d1c },
-       /* Db -> Rate table */
-       { AR5K_DB2RATE(0),      0x03020100 },
-       { AR5K_DB2RATE(1),      0x07060504 },
-       { AR5K_DB2RATE(2),      0x0b0a0908 },
-       { AR5K_DB2RATE(3),      0x0f0e0d0c },
-       { AR5K_DB2RATE(4),      0x13121110 },
-       { AR5K_DB2RATE(5),      0x17161514 },
-       { AR5K_DB2RATE(6),      0x1b1a1918 },
-       { AR5K_DB2RATE(7),      0x1f1e1d1c },
-       /* PHY registers (Common settings
-        * for all chips/modes) */
-       { AR5K_PHY(3),          0xad848e19 },
-       { AR5K_PHY(4),          0x7d28e000 },
-       { AR5K_PHY_TIMING_3,    0x9c0a9f6b },
-       { AR5K_PHY_ACT,         0x00000000 },
-       { AR5K_PHY(16),         0x206a017a },
-       { AR5K_PHY(21),         0x00000859 },
-       { AR5K_PHY_BIN_MASK_1,  0x00000000 },
-       { AR5K_PHY_BIN_MASK_2,  0x00000000 },
-       { AR5K_PHY_BIN_MASK_3,  0x00000000 },
-       { AR5K_PHY_BIN_MASK_CTL, 0x00800000 },
-       { AR5K_PHY_ANT_CTL,     0x00000001 },
-       /*{ AR5K_PHY(71), 0x0000092a },*/ /* Old value */
-       { AR5K_PHY_MAX_RX_LEN,  0x00000c80 },
-       { AR5K_PHY_IQ,          0x05100000 },
-       { AR5K_PHY_WARM_RESET,  0x00000001 },
-       { AR5K_PHY_CTL,         0x00000004 },
-       { AR5K_PHY_TXPOWER_RATE1, 0x1e1f2022 },
-       { AR5K_PHY_TXPOWER_RATE2, 0x0a0b0c0d },
-       { AR5K_PHY_TXPOWER_RATE_MAX, 0x0000003f },
-       { AR5K_PHY(82),         0x9280b212 },
-       { AR5K_PHY_RADAR,       0x5d50e188 },
-       /*{ AR5K_PHY(86), 0x000000ff },*/
-       { AR5K_PHY(87),         0x004b6a8e },
-       { AR5K_PHY_NFTHRES,     0x000003ce },
-       { AR5K_PHY_RESTART,     0x192fb515 },
-       { AR5K_PHY(94),         0x00000001 },
-       { AR5K_PHY_RFBUS_REQ,   0x00000000 },
-       /*{ AR5K_PHY(644), 0x0080a333 },*/ /* Old value */
-       /*{ AR5K_PHY(645), 0x00206c10 },*/ /* Old value */
-       { AR5K_PHY(644),        0x00806333 },
-       { AR5K_PHY(645),        0x00106c10 },
-       { AR5K_PHY(646),        0x009c4060 },
-       /* { AR5K_PHY(647), 0x1483800a }, */
-       /* { AR5K_PHY(648), 0x01831061 }, */ /* Old value */
-       { AR5K_PHY(648),        0x018830c6 },
-       { AR5K_PHY(649),        0x00000400 },
-       /*{ AR5K_PHY(650), 0x000001b5 },*/
-       { AR5K_PHY(651),        0x00000000 },
-       { AR5K_PHY_TXPOWER_RATE3, 0x20202020 },
-       { AR5K_PHY_TXPOWER_RATE2, 0x20202020 },
-       /*{ AR5K_PHY(655), 0x13c889af },*/
-       { AR5K_PHY(656),        0x38490a20 },
-       { AR5K_PHY(657),        0x00007bb6 },
-       { AR5K_PHY(658),        0x0fff3ffc },
-};
-
-/* Initial mode-specific settings for AR5212 (Written before ar5212_ini) */
-static const struct ath5k_ini_mode ar5212_ini_mode_start[] = {
-       { AR5K_QUEUE_DFS_LOCAL_IFS(0),
-       /*      a/XR       aTurbo         b        g (DYN)     gTurbo     */
-          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
-       { AR5K_QUEUE_DFS_LOCAL_IFS(1),
-          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
-       { AR5K_QUEUE_DFS_LOCAL_IFS(2),
-          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
-       { AR5K_QUEUE_DFS_LOCAL_IFS(3),
-          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
-       { AR5K_QUEUE_DFS_LOCAL_IFS(4),
-          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
-       { AR5K_QUEUE_DFS_LOCAL_IFS(5),
-          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
-       { AR5K_QUEUE_DFS_LOCAL_IFS(6),
-          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
-       { AR5K_QUEUE_DFS_LOCAL_IFS(7),
-          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
-       { AR5K_QUEUE_DFS_LOCAL_IFS(8),
-          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
-       { AR5K_QUEUE_DFS_LOCAL_IFS(9),
-          { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
-       { AR5K_DCU_GBL_IFS_SIFS,
-          { 0x00000230, 0x000001e0, 0x000000b0, 0x00000160, 0x000001e0 } },
-       { AR5K_DCU_GBL_IFS_SLOT,
-          { 0x00000168, 0x000001e0, 0x000001b8, 0x0000018c, 0x000001e0 } },
-       { AR5K_DCU_GBL_IFS_EIFS,
-          { 0x00000e60, 0x00001180, 0x00001f1c, 0x00003e38, 0x00001180 } },
-       { AR5K_DCU_GBL_IFS_MISC,
-          { 0x0000a0e0, 0x00014068, 0x00005880, 0x0000b0e0, 0x00014068 } },
-       { AR5K_TIME_OUT,
-          { 0x03e803e8, 0x06e006e0, 0x04200420, 0x08400840, 0x06e006e0 } },
-       { AR5K_PHY_TURBO,
-          { 0x00000000, 0x00000003, 0x00000000, 0x00000000, 0x00000003 } },
-       { AR5K_PHY(8),
-          { 0x02020200, 0x02020200, 0x02010200, 0x02020200, 0x02020200 } },
-       { AR5K_PHY_RF_CTL2,
-          { 0x00000e0e, 0x00000e0e, 0x00000707, 0x00000e0e, 0x00000e0e } },
-       { AR5K_PHY_SETTLING,
-          { 0x1372161c, 0x13721c25, 0x13721722, 0x137216a2, 0x13721c25 } },
-       { AR5K_PHY_AGCCTL,
-          { 0x00009d10, 0x00009d10, 0x00009d18, 0x00009d18, 0x00009d18 } },
-       { AR5K_PHY_NF,
-          { 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 } },
-       { AR5K_PHY_WEAK_OFDM_HIGH_THR,
-          { 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190 } },
-       { AR5K_PHY(70),
-          { 0x000001b8, 0x000001b8, 0x00000084, 0x00000108, 0x000001b8 } },
-       { AR5K_PHY_OFDM_SELFCORR,
-          { 0x10058a05, 0x10058a05, 0x10058a05, 0x10058a05, 0x10058a05 } },
-       { 0xa230,
-          { 0x00000000, 0x00000000, 0x00000000, 0x00000108, 0x00000000 } },
-};
-
-/* Initial mode-specific settings for AR5212 + RF5111 (Written after ar5212_ini) */
-static const struct ath5k_ini_mode rf5111_ini_mode_end[] = {
-       { AR5K_TXCFG,
-       /*      a/XR       aTurbo         b        g (DYN)     gTurbo     */
-          { 0x00008015, 0x00008015, 0x00008015, 0x00008015, 0x00008015 } },
-       { AR5K_USEC_5211,
-          { 0x128d8fa7, 0x09880fcf, 0x04e00f95, 0x12e00fab, 0x09880fcf } },
-       { AR5K_PHY_RF_CTL3,
-          { 0x0a020001, 0x0a020001, 0x05010100, 0x0a020001, 0x0a020001 } },
-       { AR5K_PHY_RF_CTL4,
-          { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
-       { AR5K_PHY_PA_CTL,
-          { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b, 0x0000000b } },
-       { AR5K_PHY_GAIN,
-          { 0x0018da5a, 0x0018da5a, 0x0018ca69, 0x0018ca69, 0x0018ca69 } },
-       { AR5K_PHY_DESIRED_SIZE,
-          { 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0 } },
-       { AR5K_PHY_SIG,
-          { 0x7e800d2e, 0x7e800d2e, 0x7ee84d2e, 0x7ee84d2e, 0x7e800d2e } },
-       { AR5K_PHY_AGCCOARSE,
-          { 0x3137665e, 0x3137665e, 0x3137665e, 0x3137665e, 0x3137615e } },
-       { AR5K_PHY_WEAK_OFDM_LOW_THR,
-          { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb080, 0x050cb080 } },
-       { AR5K_PHY_RX_DELAY,
-          { 0x00002710, 0x00002710, 0x0000157c, 0x00002af8, 0x00002710 } },
-       { AR5K_PHY_FRAME_CTL_5211,
-          { 0xf7b81020, 0xf7b81020, 0xf7b80d20, 0xf7b81020, 0xf7b81020 } },
-       { AR5K_PHY_GAIN_2GHZ,
-          { 0x642c416a, 0x642c416a, 0x6440416a, 0x6440416a, 0x6440416a } },
-       { AR5K_PHY_CCK_RX_CTL_4,
-          { 0x1883800a, 0x1883800a, 0x1873800a, 0x1883800a, 0x1883800a } },
-};
-
-static const struct ath5k_ini rf5111_ini_common_end[] = {
-       { AR5K_DCU_FP,          0x00000000 },
-       { AR5K_PHY_AGC,         0x00000000 },
-       { AR5K_PHY_ADC_CTL,     0x00022ffe },
-       { 0x983c,               0x00020100 },
-       { AR5K_PHY_GAIN_OFFSET, 0x1284613c },
-       { AR5K_PHY_PAPD_PROBE,  0x00004883 },
-       { 0x9940,               0x00000004 },
-       { 0x9958,               0x000000ff },
-       { 0x9974,               0x00000000 },
-       { AR5K_PHY_SPENDING,    0x00000018 },
-       { AR5K_PHY_CCKTXCTL,    0x00000000 },
-       { AR5K_PHY_CCK_CROSSCORR, 0xd03e6788 },
-       { AR5K_PHY_DAG_CCK_CTL, 0x000001b5 },
-       { 0xa23c,               0x13c889af },
-};
-
-/* Initial mode-specific settings for AR5212 + RF5112 (Written after ar5212_ini) */
-static const struct ath5k_ini_mode rf5112_ini_mode_end[] = {
-       { AR5K_TXCFG,
-       /*      a/XR       aTurbo         b        g (DYN)     gTurbo     */
-          { 0x00008015, 0x00008015, 0x00008015, 0x00008015, 0x00008015 } },
-       { AR5K_USEC_5211,
-          { 0x128d93a7, 0x098813cf, 0x04e01395, 0x12e013ab, 0x098813cf } },
-       { AR5K_PHY_RF_CTL3,
-          { 0x0a020001, 0x0a020001, 0x05020100, 0x0a020001, 0x0a020001 } },
-       { AR5K_PHY_RF_CTL4,
-          { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
-       { AR5K_PHY_PA_CTL,
-          { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b, 0x0000000b } },
-       { AR5K_PHY_GAIN,
-          { 0x0018da6d, 0x0018da6d, 0x0018ca75, 0x0018ca75, 0x0018ca75 } },
-       { AR5K_PHY_DESIRED_SIZE,
-          { 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0 } },
-       { AR5K_PHY_SIG,
-          { 0x7e800d2e, 0x7e800d2e, 0x7ee80d2e, 0x7ee80d2e, 0x7ee80d2e } },
-       { AR5K_PHY_AGCCOARSE,
-          { 0x3137665e, 0x3137665e, 0x3137665e, 0x3137665e, 0x3137665e } },
-       { AR5K_PHY_WEAK_OFDM_LOW_THR,
-          { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 } },
-       { AR5K_PHY_RX_DELAY,
-          { 0x000007d0, 0x000007d0, 0x0000044c, 0x00000898, 0x000007d0 } },
-       { AR5K_PHY_FRAME_CTL_5211,
-          { 0xf7b81020, 0xf7b81020, 0xf7b80d10, 0xf7b81010, 0xf7b81010 } },
-       { AR5K_PHY_CCKTXCTL,
-          { 0x00000000, 0x00000000, 0x00000008, 0x00000008, 0x00000008 } },
-       { AR5K_PHY_CCK_CROSSCORR,
-          { 0xd6be6788, 0xd6be6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } },
-       { AR5K_PHY_GAIN_2GHZ,
-          { 0x642c0140, 0x642c0140, 0x6442c160, 0x6442c160, 0x6442c160 } },
-       { AR5K_PHY_CCK_RX_CTL_4,
-          { 0x1883800a, 0x1883800a, 0x1873800a, 0x1883800a, 0x1883800a } },
-};
-
-static const struct ath5k_ini rf5112_ini_common_end[] = {
-       { AR5K_DCU_FP,          0x00000000 },
-       { AR5K_PHY_AGC,         0x00000000 },
-       { AR5K_PHY_ADC_CTL,     0x00022ffe },
-       { 0x983c,               0x00020100 },
-       { AR5K_PHY_GAIN_OFFSET, 0x1284613c },
-       { AR5K_PHY_PAPD_PROBE,  0x00004882 },
-       { 0x9940,               0x00000004 },
-       { 0x9958,               0x000000ff },
-       { 0x9974,               0x00000000 },
-       { AR5K_PHY_DAG_CCK_CTL, 0x000001b5 },
-       { 0xa23c,               0x13c889af },
-};
-
-/* Initial mode-specific settings for RF5413/5414 (Written after ar5212_ini) */
-static const struct ath5k_ini_mode rf5413_ini_mode_end[] = {
-       { AR5K_TXCFG,
-       /*      a/XR       aTurbo         b        g (DYN)     gTurbo     */
-          { 0x00000015, 0x00000015, 0x00000015, 0x00000015, 0x00000015 } },
-       { AR5K_USEC_5211,
-          { 0x128d93a7, 0x098813cf, 0x04e01395, 0x12e013ab, 0x098813cf } },
-       { AR5K_PHY_RF_CTL3,
-          { 0x0a020001, 0x0a020001, 0x05020100, 0x0a020001, 0x0a020001 } },
-       { AR5K_PHY_RF_CTL4,
-          { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
-       { AR5K_PHY_PA_CTL,
-          { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b, 0x0000000b } },
-       { AR5K_PHY_GAIN,
-          { 0x0018fa61, 0x0018fa61, 0x001a1a63, 0x001a1a63, 0x001a1a63 } },
-       { AR5K_PHY_DESIRED_SIZE,
-          { 0x0c98b4e0, 0x0c98b4e0, 0x0c98b0da, 0x0c98b0da, 0x0c98b0da } },
-       { AR5K_PHY_SIG,
-          { 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e } },
-       { AR5K_PHY_AGCCOARSE,
-          { 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e } },
-       { AR5K_PHY_WEAK_OFDM_LOW_THR,
-          { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 } },
-       { AR5K_PHY_RX_DELAY,
-          { 0x000007d0, 0x000007d0, 0x0000044c, 0x00000898, 0x000007d0 } },
-       { AR5K_PHY_FRAME_CTL_5211,
-          { 0xf7b81000, 0xf7b81000, 0xf7b80d00, 0xf7b81000, 0xf7b81000 } },
-       { AR5K_PHY_CCKTXCTL,
-          { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { AR5K_PHY_CCK_CROSSCORR,
-          { 0xd6be6788, 0xd6be6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } },
-       { AR5K_PHY_GAIN_2GHZ,
-          { 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 } },
-       { AR5K_PHY_CCK_RX_CTL_4,
-          { 0x1883800a, 0x1883800a, 0x1863800a, 0x1883800a, 0x1883800a } },
-       { 0xa300,
-          { 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000 } },
-       { 0xa304,
-          { 0x30032602, 0x30032602, 0x30032602, 0x30032602, 0x30032602 } },
-       { 0xa308,
-          { 0x48073e06, 0x48073e06, 0x48073e06, 0x48073e06, 0x48073e06 } },
-       { 0xa30c,
-          { 0x560b4c0a, 0x560b4c0a, 0x560b4c0a, 0x560b4c0a, 0x560b4c0a } },
-       { 0xa310,
-          { 0x641a600f, 0x641a600f, 0x641a600f, 0x641a600f, 0x641a600f } },
-       { 0xa314,
-          { 0x784f6e1b, 0x784f6e1b, 0x784f6e1b, 0x784f6e1b, 0x784f6e1b } },
-       { 0xa318,
-          { 0x868f7c5a, 0x868f7c5a, 0x868f7c5a, 0x868f7c5a, 0x868f7c5a } },
-       { 0xa31c,
-          { 0x90cf865b, 0x90cf865b, 0x8ecf865b, 0x8ecf865b, 0x8ecf865b } },
-       { 0xa320,
-          { 0x9d4f970f, 0x9d4f970f, 0x9b4f970f, 0x9b4f970f, 0x9b4f970f } },
-       { 0xa324,
-          { 0xa7cfa38f, 0xa7cfa38f, 0xa3cf9f8f, 0xa3cf9f8f, 0xa3cf9f8f } },
-       { 0xa328,
-          { 0xb55faf1f, 0xb55faf1f, 0xb35faf1f, 0xb35faf1f, 0xb35faf1f } },
-       { 0xa32c,
-          { 0xbddfb99f, 0xbddfb99f, 0xbbdfb99f, 0xbbdfb99f, 0xbbdfb99f } },
-       { 0xa330,
-          { 0xcb7fc53f, 0xcb7fc53f, 0xcb7fc73f, 0xcb7fc73f, 0xcb7fc73f } },
-       { 0xa334,
-          { 0xd5ffd1bf, 0xd5ffd1bf, 0xd3ffd1bf, 0xd3ffd1bf, 0xd3ffd1bf } },
-};
-
-static const struct ath5k_ini rf5413_ini_common_end[] = {
-       { AR5K_DCU_FP,          0x000003e0 },
-       { AR5K_5414_CBCFG,      0x00000010 },
-       { AR5K_SEQ_MASK,        0x0000000f },
-       { 0x809c,               0x00000000 },
-       { 0x80a0,               0x00000000 },
-       { AR5K_MIC_QOS_CTL,     0x00000000 },
-       { AR5K_MIC_QOS_SEL,     0x00000000 },
-       { AR5K_MISC_MODE,       0x00000000 },
-       { AR5K_OFDM_FIL_CNT,    0x00000000 },
-       { AR5K_CCK_FIL_CNT,     0x00000000 },
-       { AR5K_PHYERR_CNT1,     0x00000000 },
-       { AR5K_PHYERR_CNT1_MASK, 0x00000000 },
-       { AR5K_PHYERR_CNT2,     0x00000000 },
-       { AR5K_PHYERR_CNT2_MASK, 0x00000000 },
-       { AR5K_TSF_THRES,       0x00000000 },
-       { 0x8140,               0x800003f9 },
-       { 0x8144,               0x00000000 },
-       { AR5K_PHY_AGC,         0x00000000 },
-       { AR5K_PHY_ADC_CTL,     0x0000a000 },
-       { 0x983c,               0x00200400 },
-       { AR5K_PHY_GAIN_OFFSET, 0x1284233c },
-       { AR5K_PHY_SCR,         0x0000001f },
-       { AR5K_PHY_SLMT,        0x00000080 },
-       { AR5K_PHY_SCAL,        0x0000000e },
-       { 0x9958,               0x00081fff },
-       { AR5K_PHY_TIMING_7,    0x00000000 },
-       { AR5K_PHY_TIMING_8,    0x02800000 },
-       { AR5K_PHY_TIMING_11,   0x00000000 },
-       { AR5K_PHY_HEAVY_CLIP_ENABLE, 0x00000000 },
-       { 0x99e4,               0xaaaaaaaa },
-       { 0x99e8,               0x3c466478 },
-       { 0x99ec,               0x000000aa },
-       { AR5K_PHY_SCLOCK,      0x0000000c },
-       { AR5K_PHY_SDELAY,      0x000000ff },
-       { AR5K_PHY_SPENDING,    0x00000014 },
-       { AR5K_PHY_DAG_CCK_CTL, 0x000009b5 },
-       { 0xa23c,               0x93c889af },
-       { AR5K_PHY_FAST_ADC,    0x00000001 },
-       { 0xa250,               0x0000a000 },
-       { AR5K_PHY_BLUETOOTH,   0x00000000 },
-       { AR5K_PHY_TPC_RG1,     0x0cc75380 },
-       { 0xa25c,               0x0f0f0f01 },
-       { 0xa260,               0x5f690f01 },
-       { 0xa264,               0x00418a11 },
-       { 0xa268,               0x00000000 },
-       { AR5K_PHY_TPC_RG5,     0x0c30c16a },
-       { 0xa270, 0x00820820 },
-       { 0xa274, 0x081b7caa },
-       { 0xa278, 0x1ce739ce },
-       { 0xa27c, 0x051701ce },
-       { 0xa338, 0x00000000 },
-       { 0xa33c, 0x00000000 },
-       { 0xa340, 0x00000000 },
-       { 0xa344, 0x00000000 },
-       { 0xa348, 0x3fffffff },
-       { 0xa34c, 0x3fffffff },
-       { 0xa350, 0x3fffffff },
-       { 0xa354, 0x0003ffff },
-       { 0xa358, 0x79a8aa1f },
-       { 0xa35c, 0x066c420f },
-       { 0xa360, 0x0f282207 },
-       { 0xa364, 0x17601685 },
-       { 0xa368, 0x1f801104 },
-       { 0xa36c, 0x37a00c03 },
-       { 0xa370, 0x3fc40883 },
-       { 0xa374, 0x57c00803 },
-       { 0xa378, 0x5fd80682 },
-       { 0xa37c, 0x7fe00482 },
-       { 0xa380, 0x7f3c7bba },
-       { 0xa384, 0xf3307ff0 },
-};
-
-/* Initial mode-specific settings for RF2413/2414 (Written after ar5212_ini) */
-/* XXX: a mode ? */
-static const struct ath5k_ini_mode rf2413_ini_mode_end[] = {
-       { AR5K_TXCFG,
-       /*      a/XR       aTurbo         b        g (DYN)     gTurbo     */
-          { 0x00000015, 0x00000015, 0x00000015, 0x00000015, 0x00000015 } },
-       { AR5K_USEC_5211,
-          { 0x128d93a7, 0x098813cf, 0x04e01395, 0x12e013ab, 0x098813cf } },
-       { AR5K_PHY_RF_CTL3,
-          { 0x0a020001, 0x0a020001, 0x05020000, 0x0a020001, 0x0a020001 } },
-       { AR5K_PHY_RF_CTL4,
-          { 0x00000e00, 0x00000e00, 0x00000e00, 0x00000e00, 0x00000e00 } },
-       { AR5K_PHY_PA_CTL,
-          { 0x00000002, 0x00000002, 0x0000000a, 0x0000000a, 0x0000000a } },
-       { AR5K_PHY_GAIN,
-          { 0x0018da6d, 0x0018da6d, 0x001a6a64, 0x001a6a64, 0x001a6a64 } },
-       { AR5K_PHY_DESIRED_SIZE,
-          { 0x0de8b4e0, 0x0de8b4e0, 0x0de8b0da, 0x0c98b0da, 0x0de8b0da } },
-       { AR5K_PHY_SIG,
-          { 0x7e800d2e, 0x7e800d2e, 0x7ee80d2e, 0x7ec80d2e, 0x7e800d2e } },
-       { AR5K_PHY_AGCCOARSE,
-          { 0x3137665e, 0x3137665e, 0x3137665e, 0x3139605e, 0x3137665e } },
-       { AR5K_PHY_WEAK_OFDM_LOW_THR,
-          { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 } },
-       { AR5K_PHY_RX_DELAY,
-          { 0x000007d0, 0x000007d0, 0x0000044c, 0x00000898, 0x000007d0 } },
-       { AR5K_PHY_FRAME_CTL_5211,
-          { 0xf7b81000, 0xf7b81000, 0xf7b80d00, 0xf7b81000, 0xf7b81000 } },
-       { AR5K_PHY_CCKTXCTL,
-          { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { AR5K_PHY_CCK_CROSSCORR,
-          { 0xd6be6788, 0xd6be6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } },
-       { AR5K_PHY_GAIN_2GHZ,
-          { 0x002c0140, 0x002c0140, 0x0042c140, 0x0042c140, 0x0042c140 } },
-       { AR5K_PHY_CCK_RX_CTL_4,
-          { 0x1883800a, 0x1883800a, 0x1863800a, 0x1883800a, 0x1883800a } },
-};
-
-static const struct ath5k_ini rf2413_ini_common_end[] = {
-       { AR5K_DCU_FP,          0x000003e0 },
-       { AR5K_SEQ_MASK,        0x0000000f },
-       { AR5K_MIC_QOS_CTL,     0x00000000 },
-       { AR5K_MIC_QOS_SEL,     0x00000000 },
-       { AR5K_MISC_MODE,       0x00000000 },
-       { AR5K_OFDM_FIL_CNT,    0x00000000 },
-       { AR5K_CCK_FIL_CNT,     0x00000000 },
-       { AR5K_PHYERR_CNT1,     0x00000000 },
-       { AR5K_PHYERR_CNT1_MASK, 0x00000000 },
-       { AR5K_PHYERR_CNT2,     0x00000000 },
-       { AR5K_PHYERR_CNT2_MASK, 0x00000000 },
-       { AR5K_TSF_THRES,       0x00000000 },
-       { 0x8140,               0x800000a8 },
-       { 0x8144,               0x00000000 },
-       { AR5K_PHY_AGC,         0x00000000 },
-       { AR5K_PHY_ADC_CTL,     0x0000a000 },
-       { 0x983c,               0x00200400 },
-       { AR5K_PHY_GAIN_OFFSET, 0x1284233c },
-       { AR5K_PHY_SCR,         0x0000001f },
-       { AR5K_PHY_SLMT,        0x00000080 },
-       { AR5K_PHY_SCAL,        0x0000000e },
-       { 0x9958,               0x000000ff },
-       { AR5K_PHY_TIMING_7,    0x00000000 },
-       { AR5K_PHY_TIMING_8,    0x02800000 },
-       { AR5K_PHY_TIMING_11,   0x00000000 },
-       { AR5K_PHY_HEAVY_CLIP_ENABLE, 0x00000000 },
-       { 0x99e4,               0xaaaaaaaa },
-       { 0x99e8,               0x3c466478 },
-       { 0x99ec,               0x000000aa },
-       { AR5K_PHY_SCLOCK,      0x0000000c },
-       { AR5K_PHY_SDELAY,      0x000000ff },
-       { AR5K_PHY_SPENDING,    0x00000014 },
-       { AR5K_PHY_DAG_CCK_CTL, 0x000009b5 },
-       { 0xa23c,               0x93c889af },
-       { AR5K_PHY_FAST_ADC,    0x00000001 },
-       { 0xa250,               0x0000a000 },
-       { AR5K_PHY_BLUETOOTH,   0x00000000 },
-       { AR5K_PHY_TPC_RG1,     0x0cc75380 },
-       { 0xa25c,               0x0f0f0f01 },
-       { 0xa260,               0x5f690f01 },
-       { 0xa264,               0x00418a11 },
-       { 0xa268,               0x00000000 },
-       { AR5K_PHY_TPC_RG5,     0x0c30c16a },
-       { 0xa270, 0x00820820 },
-       { 0xa274, 0x001b7caa },
-       { 0xa278, 0x1ce739ce },
-       { 0xa27c, 0x051701ce },
-       { 0xa300, 0x18010000 },
-       { 0xa304, 0x30032602 },
-       { 0xa308, 0x48073e06 },
-       { 0xa30c, 0x560b4c0a },
-       { 0xa310, 0x641a600f },
-       { 0xa314, 0x784f6e1b },
-       { 0xa318, 0x868f7c5a },
-       { 0xa31c, 0x8ecf865b },
-       { 0xa320, 0x9d4f970f },
-       { 0xa324, 0xa5cfa18f },
-       { 0xa328, 0xb55faf1f },
-       { 0xa32c, 0xbddfb99f },
-       { 0xa330, 0xcd7fc73f },
-       { 0xa334, 0xd5ffd1bf },
-       { 0xa338, 0x00000000 },
-       { 0xa33c, 0x00000000 },
-       { 0xa340, 0x00000000 },
-       { 0xa344, 0x00000000 },
-       { 0xa348, 0x3fffffff },
-       { 0xa34c, 0x3fffffff },
-       { 0xa350, 0x3fffffff },
-       { 0xa354, 0x0003ffff },
-       { 0xa358, 0x79a8aa1f },
-       { 0xa35c, 0x066c420f },
-       { 0xa360, 0x0f282207 },
-       { 0xa364, 0x17601685 },
-       { 0xa368, 0x1f801104 },
-       { 0xa36c, 0x37a00c03 },
-       { 0xa370, 0x3fc40883 },
-       { 0xa374, 0x57c00803 },
-       { 0xa378, 0x5fd80682 },
-       { 0xa37c, 0x7fe00482 },
-       { 0xa380, 0x7f3c7bba },
-       { 0xa384, 0xf3307ff0 },
-};
-
-/* Initial mode-specific settings for RF2425 (Written after ar5212_ini) */
-/* XXX: a mode ? */
-static const struct ath5k_ini_mode rf2425_ini_mode_end[] = {
-       { AR5K_TXCFG,
-       /*      a/XR       aTurbo         b        g (DYN)     gTurbo     */
-          { 0x00000015, 0x00000015, 0x00000015, 0x00000015, 0x00000015 } },
-       { AR5K_USEC_5211,
-          { 0x128d93a7, 0x098813cf, 0x04e01395, 0x12e013ab, 0x098813cf } },
-       { AR5K_PHY_TURBO,
-          { 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000001 } },
-       { AR5K_PHY_RF_CTL3,
-          { 0x0a020001, 0x0a020001, 0x05020100, 0x0a020001, 0x0a020001 } },
-       { AR5K_PHY_RF_CTL4,
-          { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
-       { AR5K_PHY_PA_CTL,
-          { 0x00000003, 0x00000003, 0x0000000b, 0x0000000b, 0x0000000b } },
-       { AR5K_PHY_SETTLING,
-          { 0x1372161c, 0x13721c25, 0x13721722, 0x13721422, 0x13721c25 } },
-       { AR5K_PHY_GAIN,
-          { 0x0018fa61, 0x0018fa61, 0x00199a65, 0x00199a65, 0x00199a65 } },
-       { AR5K_PHY_DESIRED_SIZE,
-          { 0x0c98b4e0, 0x0c98b4e0, 0x0c98b0da, 0x0c98b0da, 0x0c98b0da } },
-       { AR5K_PHY_SIG,
-          { 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e } },
-       { AR5K_PHY_AGCCOARSE,
-          { 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e } },
-       { AR5K_PHY_WEAK_OFDM_LOW_THR,
-          { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 } },
-       { AR5K_PHY_RX_DELAY,
-          { 0x000007d0, 0x000007d0, 0x0000044c, 0x00000898, 0x000007d0 } },
-       { AR5K_PHY_FRAME_CTL_5211,
-          { 0xf7b81000, 0xf7b81000, 0xf7b80d00, 0xf7b81000, 0xf7b81000 } },
-       { AR5K_PHY_CCKTXCTL,
-          { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { AR5K_PHY_CCK_CROSSCORR,
-          { 0xd6be6788, 0xd6be6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } },
-       { AR5K_PHY_GAIN_2GHZ,
-          { 0x00000140, 0x00000140, 0x0052c140, 0x0052c140, 0x0052c140 } },
-       { AR5K_PHY_CCK_RX_CTL_4,
-          { 0x1883800a, 0x1883800a, 0x1863800a, 0x1883800a, 0x1883800a } },
-       { 0xa324,
-          { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
-       { 0xa328,
-          { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
-       { 0xa32c,
-          { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
-       { 0xa330,
-          { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
-       { 0xa334,
-          { 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf, 0xa7cfa7cf } },
-};
-
-static const struct ath5k_ini rf2425_ini_common_end[] = {
-       { AR5K_DCU_FP,          0x000003e0 },
-       { AR5K_SEQ_MASK,        0x0000000f },
-       { 0x809c,               0x00000000 },
-       { 0x80a0,               0x00000000 },
-       { AR5K_MIC_QOS_CTL,     0x00000000 },
-       { AR5K_MIC_QOS_SEL,     0x00000000 },
-       { AR5K_MISC_MODE,       0x00000000 },
-       { AR5K_OFDM_FIL_CNT,    0x00000000 },
-       { AR5K_CCK_FIL_CNT,     0x00000000 },
-       { AR5K_PHYERR_CNT1,     0x00000000 },
-       { AR5K_PHYERR_CNT1_MASK, 0x00000000 },
-       { AR5K_PHYERR_CNT2,     0x00000000 },
-       { AR5K_PHYERR_CNT2_MASK, 0x00000000 },
-       { AR5K_TSF_THRES,       0x00000000 },
-       { 0x8140,               0x800003f9 },
-       { 0x8144,               0x00000000 },
-       { AR5K_PHY_AGC,         0x00000000 },
-       { AR5K_PHY_ADC_CTL,     0x0000a000 },
-       { 0x983c,               0x00200400 },
-       { AR5K_PHY_GAIN_OFFSET, 0x1284233c },
-       { AR5K_PHY_SCR,         0x0000001f },
-       { AR5K_PHY_SLMT,        0x00000080 },
-       { AR5K_PHY_SCAL,        0x0000000e },
-       { 0x9958,               0x00081fff },
-       { AR5K_PHY_TIMING_7,    0x00000000 },
-       { AR5K_PHY_TIMING_8,    0x02800000 },
-       { AR5K_PHY_TIMING_11,   0x00000000 },
-       { 0x99dc,               0xfebadbe8 },
-       { AR5K_PHY_HEAVY_CLIP_ENABLE, 0x00000000 },
-       { 0x99e4,               0xaaaaaaaa },
-       { 0x99e8,               0x3c466478 },
-       { 0x99ec,               0x000000aa },
-       { AR5K_PHY_SCLOCK,      0x0000000c },
-       { AR5K_PHY_SDELAY,      0x000000ff },
-       { AR5K_PHY_SPENDING,    0x00000014 },
-       { AR5K_PHY_DAG_CCK_CTL, 0x000009b5 },
-       { AR5K_PHY_TXPOWER_RATE3, 0x20202020 },
-       { AR5K_PHY_TXPOWER_RATE4, 0x20202020 },
-       { 0xa23c,               0x93c889af },
-       { AR5K_PHY_FAST_ADC,    0x00000001 },
-       { 0xa250,               0x0000a000 },
-       { AR5K_PHY_BLUETOOTH,   0x00000000 },
-       { AR5K_PHY_TPC_RG1,     0x0cc75380 },
-       { 0xa25c,               0x0f0f0f01 },
-       { 0xa260,               0x5f690f01 },
-       { 0xa264,               0x00418a11 },
-       { 0xa268,               0x00000000 },
-       { AR5K_PHY_TPC_RG5,     0x0c30c166 },
-       { 0xa270, 0x00820820 },
-       { 0xa274, 0x081a3caa },
-       { 0xa278, 0x1ce739ce },
-       { 0xa27c, 0x051701ce },
-       { 0xa300, 0x16010000 },
-       { 0xa304, 0x2c032402 },
-       { 0xa308, 0x48433e42 },
-       { 0xa30c, 0x5a0f500b },
-       { 0xa310, 0x6c4b624a },
-       { 0xa314, 0x7e8b748a },
-       { 0xa318, 0x96cf8ccb },
-       { 0xa31c, 0xa34f9d0f },
-       { 0xa320, 0xa7cfa58f },
-       { 0xa348, 0x3fffffff },
-       { 0xa34c, 0x3fffffff },
-       { 0xa350, 0x3fffffff },
-       { 0xa354, 0x0003ffff },
-       { 0xa358, 0x79a8aa1f },
-       { 0xa35c, 0x066c420f },
-       { 0xa360, 0x0f282207 },
-       { 0xa364, 0x17601685 },
-       { 0xa368, 0x1f801104 },
-       { 0xa36c, 0x37a00c03 },
-       { 0xa370, 0x3fc40883 },
-       { 0xa374, 0x57c00803 },
-       { 0xa378, 0x5fd80682 },
-       { 0xa37c, 0x7fe00482 },
-       { 0xa380, 0x7f3c7bba },
-       { 0xa384, 0xf3307ff0 },
-};
-
-/*
- * Initial BaseBand Gain settings for RF5111/5112 (AR5210 comes with
- * RF5110 only so initial BB Gain settings are included in AR5K_AR5210_INI)
- */
-
-/* RF5111 Initial BaseBand Gain settings */
-static const struct ath5k_ini rf5111_ini_bbgain[] = {
-       { AR5K_BB_GAIN(0), 0x00000000 },
-       { AR5K_BB_GAIN(1), 0x00000020 },
-       { AR5K_BB_GAIN(2), 0x00000010 },
-       { AR5K_BB_GAIN(3), 0x00000030 },
-       { AR5K_BB_GAIN(4), 0x00000008 },
-       { AR5K_BB_GAIN(5), 0x00000028 },
-       { AR5K_BB_GAIN(6), 0x00000004 },
-       { AR5K_BB_GAIN(7), 0x00000024 },
-       { AR5K_BB_GAIN(8), 0x00000014 },
-       { AR5K_BB_GAIN(9), 0x00000034 },
-       { AR5K_BB_GAIN(10), 0x0000000c },
-       { AR5K_BB_GAIN(11), 0x0000002c },
-       { AR5K_BB_GAIN(12), 0x00000002 },
-       { AR5K_BB_GAIN(13), 0x00000022 },
-       { AR5K_BB_GAIN(14), 0x00000012 },
-       { AR5K_BB_GAIN(15), 0x00000032 },
-       { AR5K_BB_GAIN(16), 0x0000000a },
-       { AR5K_BB_GAIN(17), 0x0000002a },
-       { AR5K_BB_GAIN(18), 0x00000006 },
-       { AR5K_BB_GAIN(19), 0x00000026 },
-       { AR5K_BB_GAIN(20), 0x00000016 },
-       { AR5K_BB_GAIN(21), 0x00000036 },
-       { AR5K_BB_GAIN(22), 0x0000000e },
-       { AR5K_BB_GAIN(23), 0x0000002e },
-       { AR5K_BB_GAIN(24), 0x00000001 },
-       { AR5K_BB_GAIN(25), 0x00000021 },
-       { AR5K_BB_GAIN(26), 0x00000011 },
-       { AR5K_BB_GAIN(27), 0x00000031 },
-       { AR5K_BB_GAIN(28), 0x00000009 },
-       { AR5K_BB_GAIN(29), 0x00000029 },
-       { AR5K_BB_GAIN(30), 0x00000005 },
-       { AR5K_BB_GAIN(31), 0x00000025 },
-       { AR5K_BB_GAIN(32), 0x00000015 },
-       { AR5K_BB_GAIN(33), 0x00000035 },
-       { AR5K_BB_GAIN(34), 0x0000000d },
-       { AR5K_BB_GAIN(35), 0x0000002d },
-       { AR5K_BB_GAIN(36), 0x00000003 },
-       { AR5K_BB_GAIN(37), 0x00000023 },
-       { AR5K_BB_GAIN(38), 0x00000013 },
-       { AR5K_BB_GAIN(39), 0x00000033 },
-       { AR5K_BB_GAIN(40), 0x0000000b },
-       { AR5K_BB_GAIN(41), 0x0000002b },
-       { AR5K_BB_GAIN(42), 0x0000002b },
-       { AR5K_BB_GAIN(43), 0x0000002b },
-       { AR5K_BB_GAIN(44), 0x0000002b },
-       { AR5K_BB_GAIN(45), 0x0000002b },
-       { AR5K_BB_GAIN(46), 0x0000002b },
-       { AR5K_BB_GAIN(47), 0x0000002b },
-       { AR5K_BB_GAIN(48), 0x0000002b },
-       { AR5K_BB_GAIN(49), 0x0000002b },
-       { AR5K_BB_GAIN(50), 0x0000002b },
-       { AR5K_BB_GAIN(51), 0x0000002b },
-       { AR5K_BB_GAIN(52), 0x0000002b },
-       { AR5K_BB_GAIN(53), 0x0000002b },
-       { AR5K_BB_GAIN(54), 0x0000002b },
-       { AR5K_BB_GAIN(55), 0x0000002b },
-       { AR5K_BB_GAIN(56), 0x0000002b },
-       { AR5K_BB_GAIN(57), 0x0000002b },
-       { AR5K_BB_GAIN(58), 0x0000002b },
-       { AR5K_BB_GAIN(59), 0x0000002b },
-       { AR5K_BB_GAIN(60), 0x0000002b },
-       { AR5K_BB_GAIN(61), 0x0000002b },
-       { AR5K_BB_GAIN(62), 0x00000002 },
-       { AR5K_BB_GAIN(63), 0x00000016 },
-};
-
-/* RF5112 Initial BaseBand Gain settings (Same for RF5413/5414+) */
-static const struct ath5k_ini rf5112_ini_bbgain[] = {
-       { AR5K_BB_GAIN(0), 0x00000000 },
-       { AR5K_BB_GAIN(1), 0x00000001 },
-       { AR5K_BB_GAIN(2), 0x00000002 },
-       { AR5K_BB_GAIN(3), 0x00000003 },
-       { AR5K_BB_GAIN(4), 0x00000004 },
-       { AR5K_BB_GAIN(5), 0x00000005 },
-       { AR5K_BB_GAIN(6), 0x00000008 },
-       { AR5K_BB_GAIN(7), 0x00000009 },
-       { AR5K_BB_GAIN(8), 0x0000000a },
-       { AR5K_BB_GAIN(9), 0x0000000b },
-       { AR5K_BB_GAIN(10), 0x0000000c },
-       { AR5K_BB_GAIN(11), 0x0000000d },
-       { AR5K_BB_GAIN(12), 0x00000010 },
-       { AR5K_BB_GAIN(13), 0x00000011 },
-       { AR5K_BB_GAIN(14), 0x00000012 },
-       { AR5K_BB_GAIN(15), 0x00000013 },
-       { AR5K_BB_GAIN(16), 0x00000014 },
-       { AR5K_BB_GAIN(17), 0x00000015 },
-       { AR5K_BB_GAIN(18), 0x00000018 },
-       { AR5K_BB_GAIN(19), 0x00000019 },
-       { AR5K_BB_GAIN(20), 0x0000001a },
-       { AR5K_BB_GAIN(21), 0x0000001b },
-       { AR5K_BB_GAIN(22), 0x0000001c },
-       { AR5K_BB_GAIN(23), 0x0000001d },
-       { AR5K_BB_GAIN(24), 0x00000020 },
-       { AR5K_BB_GAIN(25), 0x00000021 },
-       { AR5K_BB_GAIN(26), 0x00000022 },
-       { AR5K_BB_GAIN(27), 0x00000023 },
-       { AR5K_BB_GAIN(28), 0x00000024 },
-       { AR5K_BB_GAIN(29), 0x00000025 },
-       { AR5K_BB_GAIN(30), 0x00000028 },
-       { AR5K_BB_GAIN(31), 0x00000029 },
-       { AR5K_BB_GAIN(32), 0x0000002a },
-       { AR5K_BB_GAIN(33), 0x0000002b },
-       { AR5K_BB_GAIN(34), 0x0000002c },
-       { AR5K_BB_GAIN(35), 0x0000002d },
-       { AR5K_BB_GAIN(36), 0x00000030 },
-       { AR5K_BB_GAIN(37), 0x00000031 },
-       { AR5K_BB_GAIN(38), 0x00000032 },
-       { AR5K_BB_GAIN(39), 0x00000033 },
-       { AR5K_BB_GAIN(40), 0x00000034 },
-       { AR5K_BB_GAIN(41), 0x00000035 },
-       { AR5K_BB_GAIN(42), 0x00000035 },
-       { AR5K_BB_GAIN(43), 0x00000035 },
-       { AR5K_BB_GAIN(44), 0x00000035 },
-       { AR5K_BB_GAIN(45), 0x00000035 },
-       { AR5K_BB_GAIN(46), 0x00000035 },
-       { AR5K_BB_GAIN(47), 0x00000035 },
-       { AR5K_BB_GAIN(48), 0x00000035 },
-       { AR5K_BB_GAIN(49), 0x00000035 },
-       { AR5K_BB_GAIN(50), 0x00000035 },
-       { AR5K_BB_GAIN(51), 0x00000035 },
-       { AR5K_BB_GAIN(52), 0x00000035 },
-       { AR5K_BB_GAIN(53), 0x00000035 },
-       { AR5K_BB_GAIN(54), 0x00000035 },
-       { AR5K_BB_GAIN(55), 0x00000035 },
-       { AR5K_BB_GAIN(56), 0x00000035 },
-       { AR5K_BB_GAIN(57), 0x00000035 },
-       { AR5K_BB_GAIN(58), 0x00000035 },
-       { AR5K_BB_GAIN(59), 0x00000035 },
-       { AR5K_BB_GAIN(60), 0x00000035 },
-       { AR5K_BB_GAIN(61), 0x00000035 },
-       { AR5K_BB_GAIN(62), 0x00000010 },
-       { AR5K_BB_GAIN(63), 0x0000001a },
-};
-
-
-/*
- * Write initial register dump
- */
-static void ath5k_hw_ini_registers(struct ath5k_hw *ah, unsigned int size,
-               const struct ath5k_ini *ini_regs, bool change_channel)
-{
-       unsigned int i;
-
-       /* Write initial registers */
-       for (i = 0; i < size; i++) {
-               /* On channel change there is
-                * no need to mess with PCU */
-               if (change_channel &&
-                               ini_regs[i].ini_register >= AR5K_PCU_MIN &&
-                               ini_regs[i].ini_register <= AR5K_PCU_MAX)
-                       continue;
-
-               switch (ini_regs[i].ini_mode) {
-               case AR5K_INI_READ:
-                       /* Cleared on read */
-                       ath5k_hw_reg_read(ah, ini_regs[i].ini_register);
-                       break;
-               case AR5K_INI_WRITE:
-               default:
-                       AR5K_REG_WAIT(i);
-                       ath5k_hw_reg_write(ah, ini_regs[i].ini_value,
-                                       ini_regs[i].ini_register);
-               }
-       }
-}
-
-static void ath5k_hw_ini_mode_registers(struct ath5k_hw *ah,
-               unsigned int size, const struct ath5k_ini_mode *ini_mode,
-               u8 mode)
-{
-       unsigned int i;
-
-       for (i = 0; i < size; i++) {
-               AR5K_REG_WAIT(i);
-               ath5k_hw_reg_write(ah, ini_mode[i].mode_value[mode],
-                       (u32)ini_mode[i].mode_register);
-       }
-
-}
-
-int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel)
-{
-       /*
-        * Write initial register settings
-        */
-
-       /* For AR5212 and combatible */
-       if (ah->ah_version == AR5K_AR5212) {
-
-               /* First set of mode-specific settings */
-               ath5k_hw_ini_mode_registers(ah,
-                       ARRAY_SIZE(ar5212_ini_mode_start),
-                       ar5212_ini_mode_start, mode);
-
-               /*
-                * Write initial settings common for all modes
-                */
-               ath5k_hw_ini_registers(ah, ARRAY_SIZE(ar5212_ini_common_start),
-                               ar5212_ini_common_start, change_channel);
-
-               /* Second set of mode-specific settings */
-               switch (ah->ah_radio) {
-               case AR5K_RF5111:
-
-                       ath5k_hw_ini_mode_registers(ah,
-                                       ARRAY_SIZE(rf5111_ini_mode_end),
-                                       rf5111_ini_mode_end, mode);
-
-                       ath5k_hw_ini_registers(ah,
-                                       ARRAY_SIZE(rf5111_ini_common_end),
-                                       rf5111_ini_common_end, change_channel);
-
-                       /* Baseband gain table */
-                       ath5k_hw_ini_registers(ah,
-                                       ARRAY_SIZE(rf5111_ini_bbgain),
-                                       rf5111_ini_bbgain, change_channel);
-
-                       break;
-               case AR5K_RF5112:
-
-                       ath5k_hw_ini_mode_registers(ah,
-                                       ARRAY_SIZE(rf5112_ini_mode_end),
-                                       rf5112_ini_mode_end, mode);
-
-                       ath5k_hw_ini_registers(ah,
-                                       ARRAY_SIZE(rf5112_ini_common_end),
-                                       rf5112_ini_common_end, change_channel);
-
-                       ath5k_hw_ini_registers(ah,
-                                       ARRAY_SIZE(rf5112_ini_bbgain),
-                                       rf5112_ini_bbgain, change_channel);
-
-                       break;
-               case AR5K_RF5413:
-
-                       ath5k_hw_ini_mode_registers(ah,
-                                       ARRAY_SIZE(rf5413_ini_mode_end),
-                                       rf5413_ini_mode_end, mode);
-
-                       ath5k_hw_ini_registers(ah,
-                                       ARRAY_SIZE(rf5413_ini_common_end),
-                                       rf5413_ini_common_end, change_channel);
-
-                       ath5k_hw_ini_registers(ah,
-                                       ARRAY_SIZE(rf5112_ini_bbgain),
-                                       rf5112_ini_bbgain, change_channel);
-
-                       break;
-               case AR5K_RF2316:
-               case AR5K_RF2413:
-
-                       ath5k_hw_ini_mode_registers(ah,
-                                       ARRAY_SIZE(rf2413_ini_mode_end),
-                                       rf2413_ini_mode_end, mode);
-
-                       ath5k_hw_ini_registers(ah,
-                                       ARRAY_SIZE(rf2413_ini_common_end),
-                                       rf2413_ini_common_end, change_channel);
-
-                       /* Override settings from rf2413_ini_common_end */
-                       if (ah->ah_radio == AR5K_RF2316) {
-                               ath5k_hw_reg_write(ah, 0x00004000,
-                                                       AR5K_PHY_AGC);
-                               ath5k_hw_reg_write(ah, 0x081b7caa,
-                                                       0xa274);
-                       }
-
-                       ath5k_hw_ini_registers(ah,
-                                       ARRAY_SIZE(rf5112_ini_bbgain),
-                                       rf5112_ini_bbgain, change_channel);
-                       break;
-               case AR5K_RF2317:
-               case AR5K_RF2425:
-
-                       ath5k_hw_ini_mode_registers(ah,
-                                       ARRAY_SIZE(rf2425_ini_mode_end),
-                                       rf2425_ini_mode_end, mode);
-
-                       ath5k_hw_ini_registers(ah,
-                                       ARRAY_SIZE(rf2425_ini_common_end),
-                                       rf2425_ini_common_end, change_channel);
-
-                       ath5k_hw_ini_registers(ah,
-                                       ARRAY_SIZE(rf5112_ini_bbgain),
-                                       rf5112_ini_bbgain, change_channel);
-                       break;
-               default:
-                       return -EINVAL;
-
-               }
-
-       /* For AR5211 */
-       } else if (ah->ah_version == AR5K_AR5211) {
-
-               /* AR5K_MODE_11B */
-               if (mode > 2) {
-                       ATH5K_ERR(ah->ah_sc,
-                               "unsupported channel mode: %d\n", mode);
-                       return -EINVAL;
-               }
-
-               /* Mode-specific settings */
-               ath5k_hw_ini_mode_registers(ah, ARRAY_SIZE(ar5211_ini_mode),
-                               ar5211_ini_mode, mode);
-
-               /*
-                * Write initial settings common for all modes
-                */
-               ath5k_hw_ini_registers(ah, ARRAY_SIZE(ar5211_ini),
-                               ar5211_ini, change_channel);
-
-               /* AR5211 only comes with 5111 */
-
-               /* Baseband gain table */
-               ath5k_hw_ini_registers(ah, ARRAY_SIZE(rf5111_ini_bbgain),
-                               rf5111_ini_bbgain, change_channel);
-       /* For AR5210 (for mode settings check out ath5k_hw_reset_tx_queue) */
-       } else if (ah->ah_version == AR5K_AR5210) {
-               ath5k_hw_ini_registers(ah, ARRAY_SIZE(ar5210_ini),
-                               ar5210_ini, change_channel);
-       }
-
-       return 0;
-}
diff --git a/drivers/net/wireless/ath5k/led.c b/drivers/net/wireless/ath5k/led.c
deleted file mode 100644 (file)
index 19555fb..0000000
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
- * Copyright (c) 2004-2005 Atheros Communications, Inc.
- * Copyright (c) 2007 Jiri Slaby <jirislaby@gmail.com>
- * Copyright (c) 2009 Bob Copeland <me@bobcopeland.com>
- *
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer,
- *    without modification.
- * 2. Redistributions in binary form must reproduce at minimum a disclaimer
- *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
- *    redistribution must be conditioned upon including a substantially
- *    similar Disclaimer requirement for further binary redistribution.
- * 3. Neither the names of the above-listed copyright holders nor the names
- *    of any contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
- *
- * Alternatively, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") version 2 as published by the Free
- * Software Foundation.
- *
- * NO WARRANTY
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGES.
- *
- */
-
-#include <linux/pci.h>
-#include "ath5k.h"
-#include "base.h"
-
-#define ATH_SDEVICE(subv,subd) \
-       .vendor = PCI_ANY_ID, .device = PCI_ANY_ID, \
-       .subvendor = (subv), .subdevice = (subd)
-
-#define ATH_LED(pin,polarity) .driver_data = (((pin) << 8) | (polarity))
-#define ATH_PIN(data) ((data) >> 8)
-#define ATH_POLARITY(data) ((data) & 0xff)
-
-/* Devices we match on for LED config info (typically laptops) */
-static const struct pci_device_id ath5k_led_devices[] = {
-       /* IBM-specific AR5212 */
-       { PCI_VDEVICE(ATHEROS, PCI_DEVICE_ID_ATHEROS_AR5212_IBM), ATH_LED(0, 0) },
-       /* AR5211 */
-       { PCI_VDEVICE(ATHEROS, PCI_DEVICE_ID_ATHEROS_AR5211), ATH_LED(0, 0) },
-       /* HP Compaq nc6xx, nc4000, nx6000 */
-       { ATH_SDEVICE(PCI_VENDOR_ID_COMPAQ, PCI_ANY_ID), ATH_LED(1, 1) },
-       /* Acer Aspire One A150 (maximlevitsky@gmail.com) */
-       { ATH_SDEVICE(PCI_VENDOR_ID_FOXCONN, 0xe008), ATH_LED(3, 0) },
-       /* Acer Ferrari 5000 (russ.dill@gmail.com) */
-       { ATH_SDEVICE(PCI_VENDOR_ID_AMBIT, 0x0422), ATH_LED(1, 1) },
-       /* E-machines E510 (tuliom@gmail.com) */
-       { ATH_SDEVICE(PCI_VENDOR_ID_AMBIT, 0x0428), ATH_LED(3, 0) },
-       /* Acer Extensa 5620z (nekoreeve@gmail.com) */
-       { ATH_SDEVICE(PCI_VENDOR_ID_QMI, 0x0105), ATH_LED(3, 0) },
-       { }
-};
-
-void ath5k_led_enable(struct ath5k_softc *sc)
-{
-       if (test_bit(ATH_STAT_LEDSOFT, sc->status)) {
-               ath5k_hw_set_gpio_output(sc->ah, sc->led_pin);
-               ath5k_led_off(sc);
-       }
-}
-
-void ath5k_led_on(struct ath5k_softc *sc)
-{
-       if (!test_bit(ATH_STAT_LEDSOFT, sc->status))
-               return;
-       ath5k_hw_set_gpio(sc->ah, sc->led_pin, sc->led_on);
-}
-
-void ath5k_led_off(struct ath5k_softc *sc)
-{
-       if (!test_bit(ATH_STAT_LEDSOFT, sc->status))
-               return;
-       ath5k_hw_set_gpio(sc->ah, sc->led_pin, !sc->led_on);
-}
-
-static void
-ath5k_led_brightness_set(struct led_classdev *led_dev,
-       enum led_brightness brightness)
-{
-       struct ath5k_led *led = container_of(led_dev, struct ath5k_led,
-               led_dev);
-
-       if (brightness == LED_OFF)
-               ath5k_led_off(led->sc);
-       else
-               ath5k_led_on(led->sc);
-}
-
-static int
-ath5k_register_led(struct ath5k_softc *sc, struct ath5k_led *led,
-                  const char *name, char *trigger)
-{
-       int err;
-
-       led->sc = sc;
-       strncpy(led->name, name, sizeof(led->name));
-       led->led_dev.name = led->name;
-       led->led_dev.default_trigger = trigger;
-       led->led_dev.brightness_set = ath5k_led_brightness_set;
-
-       err = led_classdev_register(&sc->pdev->dev, &led->led_dev);
-       if (err) {
-               ATH5K_WARN(sc, "could not register LED %s\n", name);
-               led->sc = NULL;
-       }
-       return err;
-}
-
-static void
-ath5k_unregister_led(struct ath5k_led *led)
-{
-       if (!led->sc)
-               return;
-       led_classdev_unregister(&led->led_dev);
-       ath5k_led_off(led->sc);
-       led->sc = NULL;
-}
-
-void ath5k_unregister_leds(struct ath5k_softc *sc)
-{
-       ath5k_unregister_led(&sc->rx_led);
-       ath5k_unregister_led(&sc->tx_led);
-}
-
-int ath5k_init_leds(struct ath5k_softc *sc)
-{
-       int ret = 0;
-       struct ieee80211_hw *hw = sc->hw;
-       struct pci_dev *pdev = sc->pdev;
-       char name[ATH5K_LED_MAX_NAME_LEN + 1];
-       const struct pci_device_id *match;
-
-       match = pci_match_id(&ath5k_led_devices[0], pdev);
-       if (match) {
-               __set_bit(ATH_STAT_LEDSOFT, sc->status);
-               sc->led_pin = ATH_PIN(match->driver_data);
-               sc->led_on = ATH_POLARITY(match->driver_data);
-       }
-
-       if (!test_bit(ATH_STAT_LEDSOFT, sc->status))
-               goto out;
-
-       ath5k_led_enable(sc);
-
-       snprintf(name, sizeof(name), "ath5k-%s::rx", wiphy_name(hw->wiphy));
-       ret = ath5k_register_led(sc, &sc->rx_led, name,
-               ieee80211_get_rx_led_name(hw));
-       if (ret)
-               goto out;
-
-       snprintf(name, sizeof(name), "ath5k-%s::tx", wiphy_name(hw->wiphy));
-       ret = ath5k_register_led(sc, &sc->tx_led, name,
-               ieee80211_get_tx_led_name(hw));
-out:
-       return ret;
-}
-
diff --git a/drivers/net/wireless/ath5k/pcu.c b/drivers/net/wireless/ath5k/pcu.c
deleted file mode 100644 (file)
index 55122f1..0000000
+++ /dev/null
@@ -1,1174 +0,0 @@
-/*
- * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
- * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
- * Copyright (c) 2007-2008 Matthew W. S. Bell  <mentor@madwifi.org>
- * Copyright (c) 2007-2008 Luis Rodriguez <mcgrof@winlab.rutgers.edu>
- * Copyright (c) 2007-2008 Pavel Roskin <proski@gnu.org>
- * Copyright (c) 2007-2008 Jiri Slaby <jirislaby@gmail.com>
- *
- * Permission to use, copy, modify, and 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 Control Unit Functions *
-\*********************************/
-
-#include "ath5k.h"
-#include "reg.h"
-#include "debug.h"
-#include "base.h"
-
-/*******************\
-* Generic functions *
-\*******************/
-
-/**
- * ath5k_hw_set_opmode - Set PCU operating mode
- *
- * @ah: The &struct ath5k_hw
- *
- * Initialize PCU for the various operating modes (AP/STA etc)
- *
- * NOTE: ah->ah_op_mode must be set before calling this.
- */
-int ath5k_hw_set_opmode(struct ath5k_hw *ah)
-{
-       u32 pcu_reg, beacon_reg, low_id, high_id;
-
-
-       /* Preserve rest settings */
-       pcu_reg = ath5k_hw_reg_read(ah, AR5K_STA_ID1) & 0xffff0000;
-       pcu_reg &= ~(AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_AP
-                       | AR5K_STA_ID1_KEYSRCH_MODE
-                       | (ah->ah_version == AR5K_AR5210 ?
-                       (AR5K_STA_ID1_PWR_SV | AR5K_STA_ID1_NO_PSPOLL) : 0));
-
-       beacon_reg = 0;
-
-       ATH5K_TRACE(ah->ah_sc);
-
-       switch (ah->ah_op_mode) {
-       case NL80211_IFTYPE_ADHOC:
-               pcu_reg |= AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_KEYSRCH_MODE;
-               beacon_reg |= AR5K_BCR_ADHOC;
-               if (ah->ah_version == AR5K_AR5210)
-                       pcu_reg |= AR5K_STA_ID1_NO_PSPOLL;
-               else
-                       AR5K_REG_ENABLE_BITS(ah, AR5K_CFG, AR5K_CFG_IBSS);
-               break;
-
-       case NL80211_IFTYPE_AP:
-       case NL80211_IFTYPE_MESH_POINT:
-               pcu_reg |= AR5K_STA_ID1_AP | AR5K_STA_ID1_KEYSRCH_MODE;
-               beacon_reg |= AR5K_BCR_AP;
-               if (ah->ah_version == AR5K_AR5210)
-                       pcu_reg |= AR5K_STA_ID1_NO_PSPOLL;
-               else
-                       AR5K_REG_DISABLE_BITS(ah, AR5K_CFG, AR5K_CFG_IBSS);
-               break;
-
-       case NL80211_IFTYPE_STATION:
-               pcu_reg |= AR5K_STA_ID1_KEYSRCH_MODE
-                       | (ah->ah_version == AR5K_AR5210 ?
-                               AR5K_STA_ID1_PWR_SV : 0);
-       case NL80211_IFTYPE_MONITOR:
-               pcu_reg |= AR5K_STA_ID1_KEYSRCH_MODE
-                       | (ah->ah_version == AR5K_AR5210 ?
-                               AR5K_STA_ID1_NO_PSPOLL : 0);
-               break;
-
-       default:
-               return -EINVAL;
-       }
-
-       /*
-        * Set PCU registers
-        */
-       low_id = AR5K_LOW_ID(ah->ah_sta_id);
-       high_id = AR5K_HIGH_ID(ah->ah_sta_id);
-       ath5k_hw_reg_write(ah, low_id, AR5K_STA_ID0);
-       ath5k_hw_reg_write(ah, pcu_reg | high_id, AR5K_STA_ID1);
-
-       /*
-        * Set Beacon Control Register on 5210
-        */
-       if (ah->ah_version == AR5K_AR5210)
-               ath5k_hw_reg_write(ah, beacon_reg, AR5K_BCR);
-
-       return 0;
-}
-
-/**
- * ath5k_hw_update - Update mib counters (mac layer statistics)
- *
- * @ah: The &struct ath5k_hw
- * @stats: The &struct ieee80211_low_level_stats we use to track
- * statistics on the driver
- *
- * Reads MIB counters from PCU and updates sw statistics. Must be
- * called after a MIB interrupt.
- */
-void ath5k_hw_update_mib_counters(struct ath5k_hw *ah,
-               struct ieee80211_low_level_stats  *stats)
-{
-       ATH5K_TRACE(ah->ah_sc);
-
-       /* Read-And-Clear */
-       stats->dot11ACKFailureCount += ath5k_hw_reg_read(ah, AR5K_ACK_FAIL);
-       stats->dot11RTSFailureCount += ath5k_hw_reg_read(ah, AR5K_RTS_FAIL);
-       stats->dot11RTSSuccessCount += ath5k_hw_reg_read(ah, AR5K_RTS_OK);
-       stats->dot11FCSErrorCount += ath5k_hw_reg_read(ah, AR5K_FCS_FAIL);
-
-       /* XXX: Should we use this to track beacon count ?
-        * -we read it anyway to clear the register */
-       ath5k_hw_reg_read(ah, AR5K_BEACON_CNT);
-
-       /* Reset profile count registers on 5212*/
-       if (ah->ah_version == AR5K_AR5212) {
-               ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_TX);
-               ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_RX);
-               ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_RXCLR);
-               ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_CYCLE);
-       }
-
-       /* TODO: Handle ANI stats */
-}
-
-/**
- * ath5k_hw_set_ack_bitrate - set bitrate for ACKs
- *
- * @ah: The &struct ath5k_hw
- * @high: Flag to determine if we want to use high transmition rate
- * for ACKs or not
- *
- * If high flag is set, we tell hw to use a set of control rates based on
- * the current transmition rate (check out control_rates array inside reset.c).
- * If not hw just uses the lowest rate available for the current modulation
- * scheme being used (1Mbit for CCK and 6Mbits for OFDM).
- */
-void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high)
-{
-       if (ah->ah_version != AR5K_AR5212)
-               return;
-       else {
-               u32 val = AR5K_STA_ID1_BASE_RATE_11B | AR5K_STA_ID1_ACKCTS_6MB;
-               if (high)
-                       AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1, val);
-               else
-                       AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, val);
-       }
-}
-
-
-/******************\
-* ACK/CTS Timeouts *
-\******************/
-
-/**
- * ath5k_hw_het_ack_timeout - Get ACK timeout from PCU in usec
- *
- * @ah: The &struct ath5k_hw
- */
-unsigned int ath5k_hw_get_ack_timeout(struct ath5k_hw *ah)
-{
-       ATH5K_TRACE(ah->ah_sc);
-
-       return ath5k_hw_clocktoh(AR5K_REG_MS(ath5k_hw_reg_read(ah,
-                       AR5K_TIME_OUT), AR5K_TIME_OUT_ACK), ah->ah_turbo);
-}
-
-/**
- * ath5k_hw_set_ack_timeout - Set ACK timeout on PCU
- *
- * @ah: The &struct ath5k_hw
- * @timeout: Timeout in usec
- */
-int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout)
-{
-       ATH5K_TRACE(ah->ah_sc);
-       if (ath5k_hw_clocktoh(AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_ACK),
-                       ah->ah_turbo) <= timeout)
-               return -EINVAL;
-
-       AR5K_REG_WRITE_BITS(ah, AR5K_TIME_OUT, AR5K_TIME_OUT_ACK,
-               ath5k_hw_htoclock(timeout, ah->ah_turbo));
-
-       return 0;
-}
-
-/**
- * ath5k_hw_get_cts_timeout - Get CTS timeout from PCU in usec
- *
- * @ah: The &struct ath5k_hw
- */
-unsigned int ath5k_hw_get_cts_timeout(struct ath5k_hw *ah)
-{
-       ATH5K_TRACE(ah->ah_sc);
-       return ath5k_hw_clocktoh(AR5K_REG_MS(ath5k_hw_reg_read(ah,
-                       AR5K_TIME_OUT), AR5K_TIME_OUT_CTS), ah->ah_turbo);
-}
-
-/**
- * ath5k_hw_set_cts_timeout - Set CTS timeout on PCU
- *
- * @ah: The &struct ath5k_hw
- * @timeout: Timeout in usec
- */
-int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout)
-{
-       ATH5K_TRACE(ah->ah_sc);
-       if (ath5k_hw_clocktoh(AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_CTS),
-                       ah->ah_turbo) <= timeout)
-               return -EINVAL;
-
-       AR5K_REG_WRITE_BITS(ah, AR5K_TIME_OUT, AR5K_TIME_OUT_CTS,
-                       ath5k_hw_htoclock(timeout, ah->ah_turbo));
-
-       return 0;
-}
-
-
-/****************\
-* BSSID handling *
-\****************/
-
-/**
- * ath5k_hw_get_lladdr - Get station id
- *
- * @ah: The &struct ath5k_hw
- * @mac: The card's mac address
- *
- * Initialize ah->ah_sta_id using the mac address provided
- * (just a memcpy).
- *
- * TODO: Remove it once we merge ath5k_softc and ath5k_hw
- */
-void ath5k_hw_get_lladdr(struct ath5k_hw *ah, u8 *mac)
-{
-       ATH5K_TRACE(ah->ah_sc);
-       memcpy(mac, ah->ah_sta_id, ETH_ALEN);
-}
-
-/**
- * ath5k_hw_set_lladdr - Set station id
- *
- * @ah: The &struct ath5k_hw
- * @mac: The card's mac address
- *
- * Set station id on hw using the provided mac address
- */
-int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac)
-{
-       u32 low_id, high_id;
-       u32 pcu_reg;
-
-       ATH5K_TRACE(ah->ah_sc);
-       /* Set new station ID */
-       memcpy(ah->ah_sta_id, mac, ETH_ALEN);
-
-       pcu_reg = ath5k_hw_reg_read(ah, AR5K_STA_ID1) & 0xffff0000;
-
-       low_id = AR5K_LOW_ID(mac);
-       high_id = AR5K_HIGH_ID(mac);
-
-       ath5k_hw_reg_write(ah, low_id, AR5K_STA_ID0);
-       ath5k_hw_reg_write(ah, pcu_reg | high_id, AR5K_STA_ID1);
-
-       return 0;
-}
-
-/**
- * ath5k_hw_set_associd - Set BSSID for association
- *
- * @ah: The &struct ath5k_hw
- * @bssid: BSSID
- * @assoc_id: Assoc id
- *
- * Sets the BSSID which trigers the "SME Join" operation
- */
-void ath5k_hw_set_associd(struct ath5k_hw *ah, const u8 *bssid, u16 assoc_id)
-{
-       u32 low_id, high_id;
-       u16 tim_offset = 0;
-
-       /*
-        * Set simple BSSID mask on 5212
-        */
-       if (ah->ah_version == AR5K_AR5212) {
-               ath5k_hw_reg_write(ah, AR5K_LOW_ID(ah->ah_bssid_mask),
-                                                       AR5K_BSS_IDM0);
-               ath5k_hw_reg_write(ah, AR5K_HIGH_ID(ah->ah_bssid_mask),
-                                                       AR5K_BSS_IDM1);
-       }
-
-       /*
-        * Set BSSID which triggers the "SME Join" operation
-        */
-       low_id = AR5K_LOW_ID(bssid);
-       high_id = AR5K_HIGH_ID(bssid);
-       ath5k_hw_reg_write(ah, low_id, AR5K_BSS_ID0);
-       ath5k_hw_reg_write(ah, high_id | ((assoc_id & 0x3fff) <<
-                               AR5K_BSS_ID1_AID_S), AR5K_BSS_ID1);
-
-       if (assoc_id == 0) {
-               ath5k_hw_disable_pspoll(ah);
-               return;
-       }
-
-       AR5K_REG_WRITE_BITS(ah, AR5K_BEACON, AR5K_BEACON_TIM,
-                       tim_offset ? tim_offset + 4 : 0);
-
-       ath5k_hw_enable_pspoll(ah, NULL, 0);
-}
-
-/**
- * ath5k_hw_set_bssid_mask - filter out bssids we listen
- *
- * @ah: the &struct ath5k_hw
- * @mask: the bssid_mask, a u8 array of size ETH_ALEN
- *
- * BSSID masking is a method used by AR5212 and newer hardware to inform PCU
- * which bits of the interface's MAC address should be looked at when trying
- * to decide which packets to ACK. In station mode and AP mode with a single
- * BSS every bit matters since we lock to only one BSS. In AP mode with
- * multiple BSSes (virtual interfaces) not every bit matters because hw must
- * accept frames for all BSSes and so we tweak some bits of our mac address
- * in order to have multiple BSSes.
- *
- * NOTE: This is a simple filter and does *not* filter out all
- * relevant frames. Some frames that are not for us might get ACKed from us
- * by PCU because they just match the mask.
- *
- * When handling multiple BSSes you can get the BSSID mask by computing the
- * set of  ~ ( MAC XOR BSSID ) for all bssids we handle.
- *
- * When you do this you are essentially computing the common bits of all your
- * BSSes. Later it is assumed the harware will "and" (&) the BSSID mask with
- * the MAC address to obtain the relevant bits and compare the result with
- * (frame's BSSID & mask) to see if they match.
- */
-/*
- * Simple example: on your card you have have two BSSes you have created with
- * BSSID-01 and BSSID-02. Lets assume BSSID-01 will not use the MAC address.
- * There is another BSSID-03 but you are not part of it. For simplicity's sake,
- * assuming only 4 bits for a mac address and for BSSIDs you can then have:
- *
- *                  \
- * MAC:                0001 |
- * BSSID-01:   0100 | --> Belongs to us
- * BSSID-02:   1001 |
- *                  /
- * -------------------
- * BSSID-03:   0110  | --> External
- * -------------------
- *
- * Our bssid_mask would then be:
- *
- *             On loop iteration for BSSID-01:
- *             ~(0001 ^ 0100)  -> ~(0101)
- *                             ->   1010
- *             bssid_mask      =    1010
- *
- *             On loop iteration for BSSID-02:
- *             bssid_mask &= ~(0001   ^   1001)
- *             bssid_mask =   (1010)  & ~(0001 ^ 1001)
- *             bssid_mask =   (1010)  & ~(1001)
- *             bssid_mask =   (1010)  &  (0110)
- *             bssid_mask =   0010
- *
- * A bssid_mask of 0010 means "only pay attention to the second least
- * significant bit". This is because its the only bit common
- * amongst the MAC and all BSSIDs we support. To findout what the real
- * common bit is we can simply "&" the bssid_mask now with any BSSID we have
- * or our MAC address (we assume the hardware uses the MAC address).
- *
- * Now, suppose there's an incoming frame for BSSID-03:
- *
- * IFRAME-01:  0110
- *
- * An easy eye-inspeciton of this already should tell you that this frame
- * will not pass our check. This is beacuse the bssid_mask tells the
- * hardware to only look at the second least significant bit and the
- * common bit amongst the MAC and BSSIDs is 0, this frame has the 2nd LSB
- * as 1, which does not match 0.
- *
- * So with IFRAME-01 we *assume* the hardware will do:
- *
- *     allow = (IFRAME-01 & bssid_mask) == (bssid_mask & MAC) ? 1 : 0;
- *  --> allow = (0110 & 0010) == (0010 & 0001) ? 1 : 0;
- *  --> allow = (0010) == 0000 ? 1 : 0;
- *  --> allow = 0
- *
- *  Lets now test a frame that should work:
- *
- * IFRAME-02:  0001 (we should allow)
- *
- *     allow = (0001 & 1010) == 1010
- *
- *     allow = (IFRAME-02 & bssid_mask) == (bssid_mask & MAC) ? 1 : 0;
- *  --> allow = (0001 & 0010) ==  (0010 & 0001) ? 1 :0;
- *  --> allow = (0010) == (0010)
- *  --> allow = 1
- *
- * Other examples:
- *
- * IFRAME-03:  0100 --> allowed
- * IFRAME-04:  1001 --> allowed
- * IFRAME-05:  1101 --> allowed but its not for us!!!
- *
- */
-int ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask)
-{
-       u32 low_id, high_id;
-       ATH5K_TRACE(ah->ah_sc);
-
-       /* Cache bssid mask so that we can restore it
-        * on reset */
-       memcpy(ah->ah_bssid_mask, mask, ETH_ALEN);
-       if (ah->ah_version == AR5K_AR5212) {
-               low_id = AR5K_LOW_ID(mask);
-               high_id = AR5K_HIGH_ID(mask);
-
-               ath5k_hw_reg_write(ah, low_id, AR5K_BSS_IDM0);
-               ath5k_hw_reg_write(ah, high_id, AR5K_BSS_IDM1);
-
-               return 0;
-       }
-
-       return -EIO;
-}
-
-
-/************\
-* RX Control *
-\************/
-
-/**
- * ath5k_hw_start_rx_pcu - Start RX engine
- *
- * @ah: The &struct ath5k_hw
- *
- * Starts RX engine on PCU so that hw can process RXed frames
- * (ACK etc).
- *
- * NOTE: RX DMA should be already enabled using ath5k_hw_start_rx_dma
- * TODO: Init ANI here
- */
-void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah)
-{
-       ATH5K_TRACE(ah->ah_sc);
-       AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX);
-}
-
-/**
- * at5k_hw_stop_rx_pcu - Stop RX engine
- *
- * @ah: The &struct ath5k_hw
- *
- * Stops RX engine on PCU
- *
- * TODO: Detach ANI here
- */
-void ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah)
-{
-       ATH5K_TRACE(ah->ah_sc);
-       AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX);
-}
-
-/*
- * Set multicast filter
- */
-void ath5k_hw_set_mcast_filter(struct ath5k_hw *ah, u32 filter0, u32 filter1)
-{
-       ATH5K_TRACE(ah->ah_sc);
-       /* Set the multicat filter */
-       ath5k_hw_reg_write(ah, filter0, AR5K_MCAST_FILTER0);
-       ath5k_hw_reg_write(ah, filter1, AR5K_MCAST_FILTER1);
-}
-
-/*
- * Set multicast filter by index
- */
-int ath5k_hw_set_mcast_filter_idx(struct ath5k_hw *ah, u32 index)
-{
-
-       ATH5K_TRACE(ah->ah_sc);
-       if (index >= 64)
-               return -EINVAL;
-       else if (index >= 32)
-               AR5K_REG_ENABLE_BITS(ah, AR5K_MCAST_FILTER1,
-                               (1 << (index - 32)));
-       else
-               AR5K_REG_ENABLE_BITS(ah, AR5K_MCAST_FILTER0, (1 << index));
-
-       return 0;
-}
-
-/*
- * Clear Multicast filter by index
- */
-int ath5k_hw_clear_mcast_filter_idx(struct ath5k_hw *ah, u32 index)
-{
-
-       ATH5K_TRACE(ah->ah_sc);
-       if (index >= 64)
-               return -EINVAL;
-       else if (index >= 32)
-               AR5K_REG_DISABLE_BITS(ah, AR5K_MCAST_FILTER1,
-                               (1 << (index - 32)));
-       else
-               AR5K_REG_DISABLE_BITS(ah, AR5K_MCAST_FILTER0, (1 << index));
-
-       return 0;
-}
-
-/**
- * ath5k_hw_get_rx_filter - Get current rx filter
- *
- * @ah: The &struct ath5k_hw
- *
- * Returns the RX filter by reading rx filter and
- * phy error filter registers. RX filter is used
- * to set the allowed frame types that PCU will accept
- * and pass to the driver. For a list of frame types
- * check out reg.h.
- */
-u32 ath5k_hw_get_rx_filter(struct ath5k_hw *ah)
-{
-       u32 data, filter = 0;
-
-       ATH5K_TRACE(ah->ah_sc);
-       filter = ath5k_hw_reg_read(ah, AR5K_RX_FILTER);
-
-       /*Radar detection for 5212*/
-       if (ah->ah_version == AR5K_AR5212) {
-               data = ath5k_hw_reg_read(ah, AR5K_PHY_ERR_FIL);
-
-               if (data & AR5K_PHY_ERR_FIL_RADAR)
-                       filter |= AR5K_RX_FILTER_RADARERR;
-               if (data & (AR5K_PHY_ERR_FIL_OFDM | AR5K_PHY_ERR_FIL_CCK))
-                       filter |= AR5K_RX_FILTER_PHYERR;
-       }
-
-       return filter;
-}
-
-/**
- * ath5k_hw_set_rx_filter - Set rx filter
- *
- * @ah: The &struct ath5k_hw
- * @filter: RX filter mask (see reg.h)
- *
- * Sets RX filter register and also handles PHY error filter
- * register on 5212 and newer chips so that we have proper PHY
- * error reporting.
- */
-void ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter)
-{
-       u32 data = 0;
-
-       ATH5K_TRACE(ah->ah_sc);
-
-       /* Set PHY error filter register on 5212*/
-       if (ah->ah_version == AR5K_AR5212) {
-               if (filter & AR5K_RX_FILTER_RADARERR)
-                       data |= AR5K_PHY_ERR_FIL_RADAR;
-               if (filter & AR5K_RX_FILTER_PHYERR)
-                       data |= AR5K_PHY_ERR_FIL_OFDM | AR5K_PHY_ERR_FIL_CCK;
-       }
-
-       /*
-        * The AR5210 uses promiscous mode to detect radar activity
-        */
-       if (ah->ah_version == AR5K_AR5210 &&
-                       (filter & AR5K_RX_FILTER_RADARERR)) {
-               filter &= ~AR5K_RX_FILTER_RADARERR;
-               filter |= AR5K_RX_FILTER_PROM;
-       }
-
-       /*Zero length DMA (phy error reporting) */
-       if (data)
-               AR5K_REG_ENABLE_BITS(ah, AR5K_RXCFG, AR5K_RXCFG_ZLFDMA);
-       else
-               AR5K_REG_DISABLE_BITS(ah, AR5K_RXCFG, AR5K_RXCFG_ZLFDMA);
-
-       /*Write RX Filter register*/
-       ath5k_hw_reg_write(ah, filter & 0xff, AR5K_RX_FILTER);
-
-       /*Write PHY error filter register on 5212*/
-       if (ah->ah_version == AR5K_AR5212)
-               ath5k_hw_reg_write(ah, data, AR5K_PHY_ERR_FIL);
-
-}
-
-
-/****************\
-* Beacon control *
-\****************/
-
-/**
- * ath5k_hw_get_tsf32 - Get a 32bit TSF
- *
- * @ah: The &struct ath5k_hw
- *
- * Returns lower 32 bits of current TSF
- */
-u32 ath5k_hw_get_tsf32(struct ath5k_hw *ah)
-{
-       ATH5K_TRACE(ah->ah_sc);
-       return ath5k_hw_reg_read(ah, AR5K_TSF_L32);
-}
-
-/**
- * ath5k_hw_get_tsf64 - Get the full 64bit TSF
- *
- * @ah: The &struct ath5k_hw
- *
- * Returns the current TSF
- */
-u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah)
-{
-       u64 tsf = ath5k_hw_reg_read(ah, AR5K_TSF_U32);
-       ATH5K_TRACE(ah->ah_sc);
-
-       return ath5k_hw_reg_read(ah, AR5K_TSF_L32) | (tsf << 32);
-}
-
-/**
- * ath5k_hw_set_tsf64 - Set a new 64bit TSF
- *
- * @ah: The &struct ath5k_hw
- * @tsf64: The new 64bit TSF
- *
- * Sets the new TSF
- */
-void ath5k_hw_set_tsf64(struct ath5k_hw *ah, u64 tsf64)
-{
-       ATH5K_TRACE(ah->ah_sc);
-
-       ath5k_hw_reg_write(ah, tsf64 & 0xffffffff, AR5K_TSF_L32);
-       ath5k_hw_reg_write(ah, (tsf64 >> 32) & 0xffffffff, AR5K_TSF_U32);
-}
-
-/**
- * ath5k_hw_reset_tsf - Force a TSF reset
- *
- * @ah: The &struct ath5k_hw
- *
- * Forces a TSF reset on PCU
- */
-void ath5k_hw_reset_tsf(struct ath5k_hw *ah)
-{
-       u32 val;
-
-       ATH5K_TRACE(ah->ah_sc);
-
-       val = ath5k_hw_reg_read(ah, AR5K_BEACON) | AR5K_BEACON_RESET_TSF;
-
-       /*
-        * Each write to the RESET_TSF bit toggles a hardware internal
-        * signal to reset TSF, but if left high it will cause a TSF reset
-        * on the next chip reset as well.  Thus we always write the value
-        * twice to clear the signal.
-        */
-       ath5k_hw_reg_write(ah, val, AR5K_BEACON);
-       ath5k_hw_reg_write(ah, val, AR5K_BEACON);
-}
-
-/*
- * Initialize beacon timers
- */
-void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval)
-{
-       u32 timer1, timer2, timer3;
-
-       ATH5K_TRACE(ah->ah_sc);
-       /*
-        * Set the additional timers by mode
-        */
-       switch (ah->ah_op_mode) {
-       case NL80211_IFTYPE_MONITOR:
-       case NL80211_IFTYPE_STATION:
-               /* In STA mode timer1 is used as next wakeup
-                * timer and timer2 as next CFP duration start
-                * timer. Both in 1/8TUs. */
-               /* TODO: PCF handling */
-               if (ah->ah_version == AR5K_AR5210) {
-                       timer1 = 0xffffffff;
-                       timer2 = 0xffffffff;
-               } else {
-                       timer1 = 0x0000ffff;
-                       timer2 = 0x0007ffff;
-               }
-               /* Mark associated AP as PCF incapable for now */
-               AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, AR5K_STA_ID1_PCF);
-               break;
-       case NL80211_IFTYPE_ADHOC:
-               AR5K_REG_ENABLE_BITS(ah, AR5K_TXCFG, AR5K_TXCFG_ADHOC_BCN_ATIM);
-       default:
-               /* On non-STA modes timer1 is used as next DMA
-                * beacon alert (DBA) timer and timer2 as next
-                * software beacon alert. Both in 1/8TUs. */
-               timer1 = (next_beacon - AR5K_TUNE_DMA_BEACON_RESP) << 3;
-               timer2 = (next_beacon - AR5K_TUNE_SW_BEACON_RESP) << 3;
-               break;
-       }
-
-       /* Timer3 marks the end of our ATIM window
-        * a zero length window is not allowed because
-        * we 'll get no beacons */
-       timer3 = next_beacon + (ah->ah_atim_window ? ah->ah_atim_window : 1);
-
-       /*
-        * Set the beacon register and enable all timers.
-        */
-       /* When in AP mode zero timer0 to start TSF */
-       if (ah->ah_op_mode == NL80211_IFTYPE_AP)
-               ath5k_hw_reg_write(ah, 0, AR5K_TIMER0);
-       else
-               ath5k_hw_reg_write(ah, next_beacon, AR5K_TIMER0);
-       ath5k_hw_reg_write(ah, timer1, AR5K_TIMER1);
-       ath5k_hw_reg_write(ah, timer2, AR5K_TIMER2);
-       ath5k_hw_reg_write(ah, timer3, AR5K_TIMER3);
-
-       /* Force a TSF reset if requested and enable beacons */
-       if (interval & AR5K_BEACON_RESET_TSF)
-               ath5k_hw_reset_tsf(ah);
-
-       ath5k_hw_reg_write(ah, interval & (AR5K_BEACON_PERIOD |
-                                       AR5K_BEACON_ENABLE),
-                                               AR5K_BEACON);
-
-       /* Flush any pending BMISS interrupts on ISR by
-        * performing a clear-on-write operation on PISR
-        * register for the BMISS bit (writing a bit on
-        * ISR togles a reset for that bit and leaves
-        * the rest bits intact) */
-       if (ah->ah_version == AR5K_AR5210)
-               ath5k_hw_reg_write(ah, AR5K_ISR_BMISS, AR5K_ISR);
-       else
-               ath5k_hw_reg_write(ah, AR5K_ISR_BMISS, AR5K_PISR);
-
-       /* TODO: Set enchanced sleep registers on AR5212
-        * based on vif->bss_conf params, until then
-        * disable power save reporting.*/
-       AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, AR5K_STA_ID1_PWR_SV);
-
-}
-
-#if 0
-/*
- * Set beacon timers
- */
-int ath5k_hw_set_beacon_timers(struct ath5k_hw *ah,
-               const struct ath5k_beacon_state *state)
-{
-       u32 cfp_period, next_cfp, dtim, interval, next_beacon;
-
-       /*
-        * TODO: should be changed through *state
-        * review struct ath5k_beacon_state struct
-        *
-        * XXX: These are used for cfp period bellow, are they
-        * ok ? Is it O.K. for tsf here to be 0 or should we use
-        * get_tsf ?
-        */
-       u32 dtim_count = 0; /* XXX */
-       u32 cfp_count = 0; /* XXX */
-       u32 tsf = 0; /* XXX */
-
-       ATH5K_TRACE(ah->ah_sc);
-       /* Return on an invalid beacon state */
-       if (state->bs_interval < 1)
-               return -EINVAL;
-
-       interval = state->bs_interval;
-       dtim = state->bs_dtim_period;
-
-       /*
-        * PCF support?
-        */
-       if (state->bs_cfp_period > 0) {
-               /*
-                * Enable PCF mode and set the CFP
-                * (Contention Free Period) and timer registers
-                */
-               cfp_period = state->bs_cfp_period * state->bs_dtim_period *
-                       state->bs_interval;
-               next_cfp = (cfp_count * state->bs_dtim_period + dtim_count) *
-                       state->bs_interval;
-
-               AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1,
-                               AR5K_STA_ID1_DEFAULT_ANTENNA |
-                               AR5K_STA_ID1_PCF);
-               ath5k_hw_reg_write(ah, cfp_period, AR5K_CFP_PERIOD);
-               ath5k_hw_reg_write(ah, state->bs_cfp_max_duration,
-                               AR5K_CFP_DUR);
-               ath5k_hw_reg_write(ah, (tsf + (next_cfp == 0 ? cfp_period :
-                                               next_cfp)) << 3, AR5K_TIMER2);
-       } else {
-               /* Disable PCF mode */
-               AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1,
-                               AR5K_STA_ID1_DEFAULT_ANTENNA |
-                               AR5K_STA_ID1_PCF);
-       }
-
-       /*
-        * Enable the beacon timer register
-        */
-       ath5k_hw_reg_write(ah, state->bs_next_beacon, AR5K_TIMER0);
-
-       /*
-        * Start the beacon timers
-        */
-       ath5k_hw_reg_write(ah, (ath5k_hw_reg_read(ah, AR5K_BEACON) &
-               ~(AR5K_BEACON_PERIOD | AR5K_BEACON_TIM)) |
-               AR5K_REG_SM(state->bs_tim_offset ? state->bs_tim_offset + 4 : 0,
-               AR5K_BEACON_TIM) | AR5K_REG_SM(state->bs_interval,
-               AR5K_BEACON_PERIOD), AR5K_BEACON);
-
-       /*
-        * Write new beacon miss threshold, if it appears to be valid
-        * XXX: Figure out right values for min <= bs_bmiss_threshold <= max
-        * and return if its not in range. We can test this by reading value and
-        * setting value to a largest value and seeing which values register.
-        */
-
-       AR5K_REG_WRITE_BITS(ah, AR5K_RSSI_THR, AR5K_RSSI_THR_BMISS,
-                       state->bs_bmiss_threshold);
-
-       /*
-        * Set sleep control register
-        * XXX: Didn't find this in 5210 code but since this register
-        * exists also in ar5k's 5210 headers i leave it as common code.
-        */
-       AR5K_REG_WRITE_BITS(ah, AR5K_SLEEP_CTL, AR5K_SLEEP_CTL_SLDUR,
-                       (state->bs_sleep_duration - 3) << 3);
-
-       /*
-        * Set enhanced sleep registers on 5212
-        */
-       if (ah->ah_version == AR5K_AR5212) {
-               if (state->bs_sleep_duration > state->bs_interval &&
-                               roundup(state->bs_sleep_duration, interval) ==
-                               state->bs_sleep_duration)
-                       interval = state->bs_sleep_duration;
-
-               if (state->bs_sleep_duration > dtim && (dtim == 0 ||
-                               roundup(state->bs_sleep_duration, dtim) ==
-                               state->bs_sleep_duration))
-                       dtim = state->bs_sleep_duration;
-
-               if (interval > dtim)
-                       return -EINVAL;
-
-               next_beacon = interval == dtim ? state->bs_next_dtim :
-                       state->bs_next_beacon;
-
-               ath5k_hw_reg_write(ah,
-                       AR5K_REG_SM((state->bs_next_dtim - 3) << 3,
-                       AR5K_SLEEP0_NEXT_DTIM) |
-                       AR5K_REG_SM(10, AR5K_SLEEP0_CABTO) |
-                       AR5K_SLEEP0_ENH_SLEEP_EN |
-                       AR5K_SLEEP0_ASSUME_DTIM, AR5K_SLEEP0);
-
-               ath5k_hw_reg_write(ah, AR5K_REG_SM((next_beacon - 3) << 3,
-                       AR5K_SLEEP1_NEXT_TIM) |
-                       AR5K_REG_SM(10, AR5K_SLEEP1_BEACON_TO), AR5K_SLEEP1);
-
-               ath5k_hw_reg_write(ah,
-                       AR5K_REG_SM(interval, AR5K_SLEEP2_TIM_PER) |
-                       AR5K_REG_SM(dtim, AR5K_SLEEP2_DTIM_PER), AR5K_SLEEP2);
-       }
-
-       return 0;
-}
-
-/*
- * Reset beacon timers
- */
-void ath5k_hw_reset_beacon(struct ath5k_hw *ah)
-{
-       ATH5K_TRACE(ah->ah_sc);
-       /*
-        * Disable beacon timer
-        */
-       ath5k_hw_reg_write(ah, 0, AR5K_TIMER0);
-
-       /*
-        * Disable some beacon register values
-        */
-       AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1,
-                       AR5K_STA_ID1_DEFAULT_ANTENNA | AR5K_STA_ID1_PCF);
-       ath5k_hw_reg_write(ah, AR5K_BEACON_PERIOD, AR5K_BEACON);
-}
-
-/*
- * Wait for beacon queue to finish
- */
-int ath5k_hw_beaconq_finish(struct ath5k_hw *ah, unsigned long phys_addr)
-{
-       unsigned int i;
-       int ret;
-
-       ATH5K_TRACE(ah->ah_sc);
-
-       /* 5210 doesn't have QCU*/
-       if (ah->ah_version == AR5K_AR5210) {
-               /*
-                * Wait for beaconn queue to finish by checking
-                * Control Register and Beacon Status Register.
-                */
-               for (i = AR5K_TUNE_BEACON_INTERVAL / 2; i > 0; i--) {
-                       if (!(ath5k_hw_reg_read(ah, AR5K_BSR) & AR5K_BSR_TXQ1F)
-                                       ||
-                           !(ath5k_hw_reg_read(ah, AR5K_CR) & AR5K_BSR_TXQ1F))
-                               break;
-                       udelay(10);
-               }
-
-               /* Timeout... */
-               if (i <= 0) {
-                       /*
-                        * Re-schedule the beacon queue
-                        */
-                       ath5k_hw_reg_write(ah, phys_addr, AR5K_NOQCU_TXDP1);
-                       ath5k_hw_reg_write(ah, AR5K_BCR_TQ1V | AR5K_BCR_BDMAE,
-                                       AR5K_BCR);
-
-                       return -EIO;
-               }
-               ret = 0;
-       } else {
-       /*5211/5212*/
-               ret = ath5k_hw_register_timeout(ah,
-                       AR5K_QUEUE_STATUS(AR5K_TX_QUEUE_ID_BEACON),
-                       AR5K_QCU_STS_FRMPENDCNT, 0, false);
-
-               if (AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, AR5K_TX_QUEUE_ID_BEACON))
-                       return -EIO;
-       }
-
-       return ret;
-}
-#endif
-
-
-/*********************\
-* Key table functions *
-\*********************/
-
-/*
- * Reset a key entry on the table
- */
-int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry)
-{
-       unsigned int i, type;
-       u16 micentry = entry + AR5K_KEYTABLE_MIC_OFFSET;
-
-       ATH5K_TRACE(ah->ah_sc);
-       AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE);
-
-       type = ath5k_hw_reg_read(ah, AR5K_KEYTABLE_TYPE(entry));
-
-       for (i = 0; i < AR5K_KEYCACHE_SIZE; i++)
-               ath5k_hw_reg_write(ah, 0, AR5K_KEYTABLE_OFF(entry, i));
-
-       /* Reset associated MIC entry if TKIP
-        * is enabled located at offset (entry + 64) */
-       if (type == AR5K_KEYTABLE_TYPE_TKIP) {
-               AR5K_ASSERT_ENTRY(micentry, AR5K_KEYTABLE_SIZE);
-               for (i = 0; i < AR5K_KEYCACHE_SIZE / 2 ; i++)
-                       ath5k_hw_reg_write(ah, 0,
-                               AR5K_KEYTABLE_OFF(micentry, i));
-       }
-
-       /*
-        * Set NULL encryption on AR5212+
-        *
-        * Note: AR5K_KEYTABLE_TYPE -> AR5K_KEYTABLE_OFF(entry, 5)
-        *       AR5K_KEYTABLE_TYPE_NULL -> 0x00000007
-        *
-        * Note2: Windows driver (ndiswrapper) sets this to
-        *        0x00000714 instead of 0x00000007
-        */
-       if (ah->ah_version > AR5K_AR5211) {
-               ath5k_hw_reg_write(ah, AR5K_KEYTABLE_TYPE_NULL,
-                               AR5K_KEYTABLE_TYPE(entry));
-
-               if (type == AR5K_KEYTABLE_TYPE_TKIP) {
-                       ath5k_hw_reg_write(ah, AR5K_KEYTABLE_TYPE_NULL,
-                               AR5K_KEYTABLE_TYPE(micentry));
-               }
-       }
-
-       return 0;
-}
-
-/*
- * Check if a table entry is valid
- */
-int ath5k_hw_is_key_valid(struct ath5k_hw *ah, u16 entry)
-{
-       ATH5K_TRACE(ah->ah_sc);
-       AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE);
-
-       /* Check the validation flag at the end of the entry */
-       return ath5k_hw_reg_read(ah, AR5K_KEYTABLE_MAC1(entry)) &
-               AR5K_KEYTABLE_VALID;
-}
-
-static
-int ath5k_keycache_type(const struct ieee80211_key_conf *key)
-{
-       switch (key->alg) {
-       case ALG_TKIP:
-               return AR5K_KEYTABLE_TYPE_TKIP;
-       case ALG_CCMP:
-               return AR5K_KEYTABLE_TYPE_CCM;
-       case ALG_WEP:
-               if (key->keylen == LEN_WEP40)
-                       return AR5K_KEYTABLE_TYPE_40;
-               else if (key->keylen == LEN_WEP104)
-                       return AR5K_KEYTABLE_TYPE_104;
-               return -EINVAL;
-       default:
-               return -EINVAL;
-       }
-       return -EINVAL;
-}
-
-/*
- * Set a key entry on the table
- */
-int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry,
-               const struct ieee80211_key_conf *key, const u8 *mac)
-{
-       unsigned int i;
-       int keylen;
-       __le32 key_v[5] = {};
-       __le32 key0 = 0, key1 = 0;
-       __le32 *rxmic, *txmic;
-       int keytype;
-       u16 micentry = entry + AR5K_KEYTABLE_MIC_OFFSET;
-       bool is_tkip;
-       const u8 *key_ptr;
-
-       ATH5K_TRACE(ah->ah_sc);
-
-       is_tkip = (key->alg == ALG_TKIP);
-
-       /*
-        * key->keylen comes in from mac80211 in bytes.
-        * TKIP is 128 bit + 128 bit mic
-        */
-       keylen = (is_tkip) ? (128 / 8) : key->keylen;
-
-       if (entry > AR5K_KEYTABLE_SIZE ||
-               (is_tkip && micentry > AR5K_KEYTABLE_SIZE))
-               return -EOPNOTSUPP;
-
-       if (unlikely(keylen > 16))
-               return -EOPNOTSUPP;
-
-       keytype = ath5k_keycache_type(key);
-       if (keytype < 0)
-               return keytype;
-
-       /*
-        * each key block is 6 bytes wide, written as pairs of
-        * alternating 32 and 16 bit le values.
-        */
-       key_ptr = key->key;
-       for (i = 0; keylen >= 6; keylen -= 6) {
-               memcpy(&key_v[i], key_ptr, 6);
-               i += 2;
-               key_ptr += 6;
-       }
-       if (keylen)
-               memcpy(&key_v[i], key_ptr, keylen);
-
-       /* intentionally corrupt key until mic is installed */
-       if (is_tkip) {
-               key0 = key_v[0] = ~key_v[0];
-               key1 = key_v[1] = ~key_v[1];
-       }
-
-       for (i = 0; i < ARRAY_SIZE(key_v); i++)
-               ath5k_hw_reg_write(ah, le32_to_cpu(key_v[i]),
-                               AR5K_KEYTABLE_OFF(entry, i));
-
-       ath5k_hw_reg_write(ah, keytype, AR5K_KEYTABLE_TYPE(entry));
-
-       if (is_tkip) {
-               /* Install rx/tx MIC */
-               rxmic = (__le32 *) &key->key[16];
-               txmic = (__le32 *) &key->key[24];
-
-               if (ah->ah_combined_mic) {
-                       key_v[0] = rxmic[0];
-                       key_v[1] = cpu_to_le32(le32_to_cpu(txmic[0]) >> 16);
-                       key_v[2] = rxmic[1];
-                       key_v[3] = cpu_to_le32(le32_to_cpu(txmic[0]) & 0xffff);
-                       key_v[4] = txmic[1];
-               } else {
-                       key_v[0] = rxmic[0];
-                       key_v[1] = 0;
-                       key_v[2] = rxmic[1];
-                       key_v[3] = 0;
-                       key_v[4] = 0;
-               }
-               for (i = 0; i < ARRAY_SIZE(key_v); i++)
-                       ath5k_hw_reg_write(ah, le32_to_cpu(key_v[i]),
-                               AR5K_KEYTABLE_OFF(micentry, i));
-
-               ath5k_hw_reg_write(ah, AR5K_KEYTABLE_TYPE_NULL,
-                       AR5K_KEYTABLE_TYPE(micentry));
-               ath5k_hw_reg_write(ah, 0, AR5K_KEYTABLE_MAC0(micentry));
-               ath5k_hw_reg_write(ah, 0, AR5K_KEYTABLE_MAC1(micentry));
-
-               /* restore first 2 words of key */
-               ath5k_hw_reg_write(ah, le32_to_cpu(~key0),
-                       AR5K_KEYTABLE_OFF(entry, 0));
-               ath5k_hw_reg_write(ah, le32_to_cpu(~key1),
-                       AR5K_KEYTABLE_OFF(entry, 1));
-       }
-
-       return ath5k_hw_set_key_lladdr(ah, entry, mac);
-}
-
-int ath5k_hw_set_key_lladdr(struct ath5k_hw *ah, u16 entry, const u8 *mac)
-{
-       u32 low_id, high_id;
-
-       ATH5K_TRACE(ah->ah_sc);
-        /* Invalid entry (key table overflow) */
-       AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE);
-
-       /* MAC may be NULL if it's a broadcast key. In this case no need to
-        * to compute AR5K_LOW_ID and AR5K_HIGH_ID as we already know it. */
-       if (!mac) {
-               low_id = 0xffffffff;
-               high_id = 0xffff | AR5K_KEYTABLE_VALID;
-       } else {
-               low_id = AR5K_LOW_ID(mac);
-               high_id = AR5K_HIGH_ID(mac) | AR5K_KEYTABLE_VALID;
-       }
-
-       ath5k_hw_reg_write(ah, low_id, AR5K_KEYTABLE_MAC0(entry));
-       ath5k_hw_reg_write(ah, high_id, AR5K_KEYTABLE_MAC1(entry));
-
-       return 0;
-}
-
diff --git a/drivers/net/wireless/ath5k/phy.c b/drivers/net/wireless/ath5k/phy.c
deleted file mode 100644 (file)
index b48b29d..0000000
+++ /dev/null
@@ -1,2606 +0,0 @@
-/*
- * PHY functions
- *
- * Copyright (c) 2004-2007 Reyk Floeter <reyk@openbsd.org>
- * Copyright (c) 2006-2009 Nick Kossifidis <mickflemm@gmail.com>
- * Copyright (c) 2007-2008 Jiri Slaby <jirislaby@gmail.com>
- * Copyright (c) 2008-2009 Felix Fietkau <nbd@openwrt.org>
- *
- * Permission to use, copy, modify, and 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.
- *
- */
-
-#define _ATH5K_PHY
-
-#include <linux/delay.h>
-
-#include "ath5k.h"
-#include "reg.h"
-#include "base.h"
-#include "rfbuffer.h"
-#include "rfgain.h"
-
-/*
- * Used to modify RF Banks before writing them to AR5K_RF_BUFFER
- */
-static unsigned int ath5k_hw_rfb_op(struct ath5k_hw *ah,
-                                       const struct ath5k_rf_reg *rf_regs,
-                                       u32 val, u8 reg_id, bool set)
-{
-       const struct ath5k_rf_reg *rfreg = NULL;
-       u8 offset, bank, num_bits, col, position;
-       u16 entry;
-       u32 mask, data, last_bit, bits_shifted, first_bit;
-       u32 *rfb;
-       s32 bits_left;
-       int i;
-
-       data = 0;
-       rfb = ah->ah_rf_banks;
-
-       for (i = 0; i < ah->ah_rf_regs_count; i++) {
-               if (rf_regs[i].index == reg_id) {
-                       rfreg = &rf_regs[i];
-                       break;
-               }
-       }
-
-       if (rfb == NULL || rfreg == NULL) {
-               ATH5K_PRINTF("Rf register not found!\n");
-               /* should not happen */
-               return 0;
-       }
-
-       bank = rfreg->bank;
-       num_bits = rfreg->field.len;
-       first_bit = rfreg->field.pos;
-       col = rfreg->field.col;
-
-       /* first_bit is an offset from bank's
-        * start. Since we have all banks on
-        * the same array, we use this offset
-        * to mark each bank's start */
-       offset = ah->ah_offset[bank];
-
-       /* Boundary check */
-       if (!(col <= 3 && num_bits <= 32 && first_bit + num_bits <= 319)) {
-               ATH5K_PRINTF("invalid values at offset %u\n", offset);
-               return 0;
-       }
-
-       entry = ((first_bit - 1) / 8) + offset;
-       position = (first_bit - 1) % 8;
-
-       if (set)
-               data = ath5k_hw_bitswap(val, num_bits);
-
-       for (bits_shifted = 0, bits_left = num_bits; bits_left > 0;
-       position = 0, entry++) {
-
-               last_bit = (position + bits_left > 8) ? 8 :
-                                       position + bits_left;
-
-               mask = (((1 << last_bit) - 1) ^ ((1 << position) - 1)) <<
-                                                               (col * 8);
-
-               if (set) {
-                       rfb[entry] &= ~mask;
-                       rfb[entry] |= ((data << position) << (col * 8)) & mask;
-                       data >>= (8 - position);
-               } else {
-                       data |= (((rfb[entry] & mask) >> (col * 8)) >> position)
-                               << bits_shifted;
-                       bits_shifted += last_bit - position;
-               }
-
-               bits_left -= 8 - position;
-       }
-
-       data = set ? 1 : ath5k_hw_bitswap(data, num_bits);
-
-       return data;
-}
-
-/**********************\
-* RF Gain optimization *
-\**********************/
-
-/*
- * This code is used to optimize rf gain on different environments
- * (temprature mostly) based on feedback from a power detector.
- *
- * It's only used on RF5111 and RF5112, later RF chips seem to have
- * auto adjustment on hw -notice they have a much smaller BANK 7 and
- * no gain optimization ladder-.
- *
- * For more infos check out this patent doc
- * http://www.freepatentsonline.com/7400691.html
- *
- * This paper describes power drops as seen on the receiver due to
- * probe packets
- * http://www.cnri.dit.ie/publications/ICT08%20-%20Practical%20Issues
- * %20of%20Power%20Control.pdf
- *
- * And this is the MadWiFi bug entry related to the above
- * http://madwifi-project.org/ticket/1659
- * with various measurements and diagrams
- *
- * TODO: Deal with power drops due to probes by setting an apropriate
- * tx power on the probe packets ! Make this part of the calibration process.
- */
-
-/* Initialize ah_gain durring attach */
-int ath5k_hw_rfgain_opt_init(struct ath5k_hw *ah)
-{
-       /* Initialize the gain optimization values */
-       switch (ah->ah_radio) {
-       case AR5K_RF5111:
-               ah->ah_gain.g_step_idx = rfgain_opt_5111.go_default;
-               ah->ah_gain.g_low = 20;
-               ah->ah_gain.g_high = 35;
-               ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
-               break;
-       case AR5K_RF5112:
-               ah->ah_gain.g_step_idx = rfgain_opt_5112.go_default;
-               ah->ah_gain.g_low = 20;
-               ah->ah_gain.g_high = 85;
-               ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-/* Schedule a gain probe check on the next transmited packet.
- * That means our next packet is going to be sent with lower
- * tx power and a Peak to Average Power Detector (PAPD) will try
- * to measure the gain.
- *
- * TODO: Use propper tx power setting for the probe packet so
- * that we don't observe a serious power drop on the receiver
- *
- * XXX:  How about forcing a tx packet (bypassing PCU arbitrator etc)
- * just after we enable the probe so that we don't mess with
- * standard traffic ? Maybe it's time to use sw interrupts and
- * a probe tasklet !!!
- */
-static void ath5k_hw_request_rfgain_probe(struct ath5k_hw *ah)
-{
-
-       /* Skip if gain calibration is inactive or
-        * we already handle a probe request */
-       if (ah->ah_gain.g_state != AR5K_RFGAIN_ACTIVE)
-               return;
-
-       /* Send the packet with 2dB below max power as
-        * patent doc suggest */
-       ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txpower.txp_max_pwr - 4,
-                       AR5K_PHY_PAPD_PROBE_TXPOWER) |
-                       AR5K_PHY_PAPD_PROBE_TX_NEXT, AR5K_PHY_PAPD_PROBE);
-
-       ah->ah_gain.g_state = AR5K_RFGAIN_READ_REQUESTED;
-
-}
-
-/* Calculate gain_F measurement correction
- * based on the current step for RF5112 rev. 2 */
-static u32 ath5k_hw_rf_gainf_corr(struct ath5k_hw *ah)
-{
-       u32 mix, step;
-       u32 *rf;
-       const struct ath5k_gain_opt *go;
-       const struct ath5k_gain_opt_step *g_step;
-       const struct ath5k_rf_reg *rf_regs;
-
-       /* Only RF5112 Rev. 2 supports it */
-       if ((ah->ah_radio != AR5K_RF5112) ||
-       (ah->ah_radio_5ghz_revision <= AR5K_SREV_RAD_5112A))
-               return 0;
-
-       go = &rfgain_opt_5112;
-       rf_regs = rf_regs_5112a;
-       ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5112a);
-
-       g_step = &go->go_step[ah->ah_gain.g_step_idx];
-
-       if (ah->ah_rf_banks == NULL)
-               return 0;
-
-       rf = ah->ah_rf_banks;
-       ah->ah_gain.g_f_corr = 0;
-
-       /* No VGA (Variable Gain Amplifier) override, skip */
-       if (ath5k_hw_rfb_op(ah, rf_regs, 0, AR5K_RF_MIXVGA_OVR, false) != 1)
-               return 0;
-
-       /* Mix gain stepping */
-       step = ath5k_hw_rfb_op(ah, rf_regs, 0, AR5K_RF_MIXGAIN_STEP, false);
-
-       /* Mix gain override */
-       mix = g_step->gos_param[0];
-
-       switch (mix) {
-       case 3:
-               ah->ah_gain.g_f_corr = step * 2;
-               break;
-       case 2:
-               ah->ah_gain.g_f_corr = (step - 5) * 2;
-               break;
-       case 1:
-               ah->ah_gain.g_f_corr = step;
-               break;
-       default:
-               ah->ah_gain.g_f_corr = 0;
-               break;
-       }
-
-       return ah->ah_gain.g_f_corr;
-}
-
-/* Check if current gain_F measurement is in the range of our
- * power detector windows. If we get a measurement outside range
- * we know it's not accurate (detectors can't measure anything outside
- * their detection window) so we must ignore it */
-static bool ath5k_hw_rf_check_gainf_readback(struct ath5k_hw *ah)
-{
-       const struct ath5k_rf_reg *rf_regs;
-       u32 step, mix_ovr, level[4];
-       u32 *rf;
-
-       if (ah->ah_rf_banks == NULL)
-               return false;
-
-       rf = ah->ah_rf_banks;
-
-       if (ah->ah_radio == AR5K_RF5111) {
-
-               rf_regs = rf_regs_5111;
-               ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5111);
-
-               step = ath5k_hw_rfb_op(ah, rf_regs, 0, AR5K_RF_RFGAIN_STEP,
-                       false);
-
-               level[0] = 0;
-               level[1] = (step == 63) ? 50 : step + 4;
-               level[2] = (step != 63) ? 64 : level[0];
-               level[3] = level[2] + 50 ;
-
-               ah->ah_gain.g_high = level[3] -
-                       (step == 63 ? AR5K_GAIN_DYN_ADJUST_HI_MARGIN : -5);
-               ah->ah_gain.g_low = level[0] +
-                       (step == 63 ? AR5K_GAIN_DYN_ADJUST_LO_MARGIN : 0);
-       } else {
-
-               rf_regs = rf_regs_5112;
-               ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5112);
-
-               mix_ovr = ath5k_hw_rfb_op(ah, rf_regs, 0, AR5K_RF_MIXVGA_OVR,
-                       false);
-
-               level[0] = level[2] = 0;
-
-               if (mix_ovr == 1) {
-                       level[1] = level[3] = 83;
-               } else {
-                       level[1] = level[3] = 107;
-                       ah->ah_gain.g_high = 55;
-               }
-       }
-
-       return (ah->ah_gain.g_current >= level[0] &&
-                       ah->ah_gain.g_current <= level[1]) ||
-               (ah->ah_gain.g_current >= level[2] &&
-                       ah->ah_gain.g_current <= level[3]);
-}
-
-/* Perform gain_F adjustment by choosing the right set
- * of parameters from rf gain optimization ladder */
-static s8 ath5k_hw_rf_gainf_adjust(struct ath5k_hw *ah)
-{
-       const struct ath5k_gain_opt *go;
-       const struct ath5k_gain_opt_step *g_step;
-       int ret = 0;
-
-       switch (ah->ah_radio) {
-       case AR5K_RF5111:
-               go = &rfgain_opt_5111;
-               break;
-       case AR5K_RF5112:
-               go = &rfgain_opt_5112;
-               break;
-       default:
-               return 0;
-       }
-
-       g_step = &go->go_step[ah->ah_gain.g_step_idx];
-
-       if (ah->ah_gain.g_current >= ah->ah_gain.g_high) {
-
-               /* Reached maximum */
-               if (ah->ah_gain.g_step_idx == 0)
-                       return -1;
-
-               for (ah->ah_gain.g_target = ah->ah_gain.g_current;
-                               ah->ah_gain.g_target >=  ah->ah_gain.g_high &&
-                               ah->ah_gain.g_step_idx > 0;
-                               g_step = &go->go_step[ah->ah_gain.g_step_idx])
-                       ah->ah_gain.g_target -= 2 *
-                           (go->go_step[--(ah->ah_gain.g_step_idx)].gos_gain -
-                           g_step->gos_gain);
-
-               ret = 1;
-               goto done;
-       }
-
-       if (ah->ah_gain.g_current <= ah->ah_gain.g_low) {
-
-               /* Reached minimum */
-               if (ah->ah_gain.g_step_idx == (go->go_steps_count - 1))
-                       return -2;
-
-               for (ah->ah_gain.g_target = ah->ah_gain.g_current;
-                               ah->ah_gain.g_target <= ah->ah_gain.g_low &&
-                               ah->ah_gain.g_step_idx < go->go_steps_count-1;
-                               g_step = &go->go_step[ah->ah_gain.g_step_idx])
-                       ah->ah_gain.g_target -= 2 *
-                           (go->go_step[++ah->ah_gain.g_step_idx].gos_gain -
-                           g_step->gos_gain);
-
-               ret = 2;
-               goto done;
-       }
-
-done:
-       ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_CALIBRATE,
-               "ret %d, gain step %u, current gain %u, target gain %u\n",
-               ret, ah->ah_gain.g_step_idx, ah->ah_gain.g_current,
-               ah->ah_gain.g_target);
-
-       return ret;
-}
-
-/* Main callback for thermal rf gain calibration engine
- * Check for a new gain reading and schedule an adjustment
- * if needed.
- *
- * TODO: Use sw interrupt to schedule reset if gain_F needs
- * adjustment */
-enum ath5k_rfgain ath5k_hw_gainf_calibrate(struct ath5k_hw *ah)
-{
-       u32 data, type;
-       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
-
-       ATH5K_TRACE(ah->ah_sc);
-
-       if (ah->ah_rf_banks == NULL ||
-       ah->ah_gain.g_state == AR5K_RFGAIN_INACTIVE)
-               return AR5K_RFGAIN_INACTIVE;
-
-       /* No check requested, either engine is inactive
-        * or an adjustment is already requested */
-       if (ah->ah_gain.g_state != AR5K_RFGAIN_READ_REQUESTED)
-               goto done;
-
-       /* Read the PAPD (Peak to Average Power Detector)
-        * register */
-       data = ath5k_hw_reg_read(ah, AR5K_PHY_PAPD_PROBE);
-
-       /* No probe is scheduled, read gain_F measurement */
-       if (!(data & AR5K_PHY_PAPD_PROBE_TX_NEXT)) {
-               ah->ah_gain.g_current = data >> AR5K_PHY_PAPD_PROBE_GAINF_S;
-               type = AR5K_REG_MS(data, AR5K_PHY_PAPD_PROBE_TYPE);
-
-               /* If tx packet is CCK correct the gain_F measurement
-                * by cck ofdm gain delta */
-               if (type == AR5K_PHY_PAPD_PROBE_TYPE_CCK) {
-                       if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A)
-                               ah->ah_gain.g_current +=
-                                       ee->ee_cck_ofdm_gain_delta;
-                       else
-                               ah->ah_gain.g_current +=
-                                       AR5K_GAIN_CCK_PROBE_CORR;
-               }
-
-               /* Further correct gain_F measurement for
-                * RF5112A radios */
-               if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A) {
-                       ath5k_hw_rf_gainf_corr(ah);
-                       ah->ah_gain.g_current =
-                               ah->ah_gain.g_current >= ah->ah_gain.g_f_corr ?
-                               (ah->ah_gain.g_current-ah->ah_gain.g_f_corr) :
-                               0;
-               }
-
-               /* Check if measurement is ok and if we need
-                * to adjust gain, schedule a gain adjustment,
-                * else switch back to the acive state */
-               if (ath5k_hw_rf_check_gainf_readback(ah) &&
-               AR5K_GAIN_CHECK_ADJUST(&ah->ah_gain) &&
-               ath5k_hw_rf_gainf_adjust(ah)) {
-                       ah->ah_gain.g_state = AR5K_RFGAIN_NEED_CHANGE;
-               } else {
-                       ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
-               }
-       }
-
-done:
-       return ah->ah_gain.g_state;
-}
-
-/* Write initial rf gain table to set the RF sensitivity
- * this one works on all RF chips and has nothing to do
- * with gain_F calibration */
-int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq)
-{
-       const struct ath5k_ini_rfgain *ath5k_rfg;
-       unsigned int i, size;
-
-       switch (ah->ah_radio) {
-       case AR5K_RF5111:
-               ath5k_rfg = rfgain_5111;
-               size = ARRAY_SIZE(rfgain_5111);
-               break;
-       case AR5K_RF5112:
-               ath5k_rfg = rfgain_5112;
-               size = ARRAY_SIZE(rfgain_5112);
-               break;
-       case AR5K_RF2413:
-               ath5k_rfg = rfgain_2413;
-               size = ARRAY_SIZE(rfgain_2413);
-               break;
-       case AR5K_RF2316:
-               ath5k_rfg = rfgain_2316;
-               size = ARRAY_SIZE(rfgain_2316);
-               break;
-       case AR5K_RF5413:
-               ath5k_rfg = rfgain_5413;
-               size = ARRAY_SIZE(rfgain_5413);
-               break;
-       case AR5K_RF2317:
-       case AR5K_RF2425:
-               ath5k_rfg = rfgain_2425;
-               size = ARRAY_SIZE(rfgain_2425);
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       switch (freq) {
-       case AR5K_INI_RFGAIN_2GHZ:
-       case AR5K_INI_RFGAIN_5GHZ:
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       for (i = 0; i < size; i++) {
-               AR5K_REG_WAIT(i);
-               ath5k_hw_reg_write(ah, ath5k_rfg[i].rfg_value[freq],
-                       (u32)ath5k_rfg[i].rfg_register);
-       }
-
-       return 0;
-}
-
-
-
-/********************\
-* RF Registers setup *
-\********************/
-
-
-/*
- * Setup RF registers by writing rf buffer on hw
- */
-int ath5k_hw_rfregs_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
-               unsigned int mode)
-{
-       const struct ath5k_rf_reg *rf_regs;
-       const struct ath5k_ini_rfbuffer *ini_rfb;
-       const struct ath5k_gain_opt *go = NULL;
-       const struct ath5k_gain_opt_step *g_step;
-       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
-       u8 ee_mode = 0;
-       u32 *rfb;
-       int i, obdb = -1, bank = -1;
-
-       switch (ah->ah_radio) {
-       case AR5K_RF5111:
-               rf_regs = rf_regs_5111;
-               ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5111);
-               ini_rfb = rfb_5111;
-               ah->ah_rf_banks_size = ARRAY_SIZE(rfb_5111);
-               go = &rfgain_opt_5111;
-               break;
-       case AR5K_RF5112:
-               if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A) {
-                       rf_regs = rf_regs_5112a;
-                       ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5112a);
-                       ini_rfb = rfb_5112a;
-                       ah->ah_rf_banks_size = ARRAY_SIZE(rfb_5112a);
-               } else {
-                       rf_regs = rf_regs_5112;
-                       ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5112);
-                       ini_rfb = rfb_5112;
-                       ah->ah_rf_banks_size = ARRAY_SIZE(rfb_5112);
-               }
-               go = &rfgain_opt_5112;
-               break;
-       case AR5K_RF2413:
-               rf_regs = rf_regs_2413;
-               ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_2413);
-               ini_rfb = rfb_2413;
-               ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2413);
-               break;
-       case AR5K_RF2316:
-               rf_regs = rf_regs_2316;
-               ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_2316);
-               ini_rfb = rfb_2316;
-               ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2316);
-               break;
-       case AR5K_RF5413:
-               rf_regs = rf_regs_5413;
-               ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_5413);
-               ini_rfb = rfb_5413;
-               ah->ah_rf_banks_size = ARRAY_SIZE(rfb_5413);
-               break;
-       case AR5K_RF2317:
-               rf_regs = rf_regs_2425;
-               ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_2425);
-               ini_rfb = rfb_2317;
-               ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2317);
-               break;
-       case AR5K_RF2425:
-               rf_regs = rf_regs_2425;
-               ah->ah_rf_regs_count = ARRAY_SIZE(rf_regs_2425);
-               if (ah->ah_mac_srev < AR5K_SREV_AR2417) {
-                       ini_rfb = rfb_2425;
-                       ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2425);
-               } else {
-                       ini_rfb = rfb_2417;
-                       ah->ah_rf_banks_size = ARRAY_SIZE(rfb_2417);
-               }
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       /* If it's the first time we set rf buffer, allocate
-        * ah->ah_rf_banks based on ah->ah_rf_banks_size
-        * we set above */
-       if (ah->ah_rf_banks == NULL) {
-               ah->ah_rf_banks = kmalloc(sizeof(u32) * ah->ah_rf_banks_size,
-                                                               GFP_KERNEL);
-               if (ah->ah_rf_banks == NULL) {
-                       ATH5K_ERR(ah->ah_sc, "out of memory\n");
-                       return -ENOMEM;
-               }
-       }
-
-       /* Copy values to modify them */
-       rfb = ah->ah_rf_banks;
-
-       for (i = 0; i < ah->ah_rf_banks_size; i++) {
-               if (ini_rfb[i].rfb_bank >= AR5K_MAX_RF_BANKS) {
-                       ATH5K_ERR(ah->ah_sc, "invalid bank\n");
-                       return -EINVAL;
-               }
-
-               /* Bank changed, write down the offset */
-               if (bank != ini_rfb[i].rfb_bank) {
-                       bank = ini_rfb[i].rfb_bank;
-                       ah->ah_offset[bank] = i;
-               }
-
-               rfb[i] = ini_rfb[i].rfb_mode_data[mode];
-       }
-
-       /* Set Output and Driver bias current (OB/DB) */
-       if (channel->hw_value & CHANNEL_2GHZ) {
-
-               if (channel->hw_value & CHANNEL_CCK)
-                       ee_mode = AR5K_EEPROM_MODE_11B;
-               else
-                       ee_mode = AR5K_EEPROM_MODE_11G;
-
-               /* For RF511X/RF211X combination we
-                * use b_OB and b_DB parameters stored
-                * in eeprom on ee->ee_ob[ee_mode][0]
-                *
-                * For all other chips we use OB/DB for 2Ghz
-                * stored in the b/g modal section just like
-                * 802.11a on ee->ee_ob[ee_mode][1] */
-               if ((ah->ah_radio == AR5K_RF5111) ||
-               (ah->ah_radio == AR5K_RF5112))
-                       obdb = 0;
-               else
-                       obdb = 1;
-
-               ath5k_hw_rfb_op(ah, rf_regs, ee->ee_ob[ee_mode][obdb],
-                                               AR5K_RF_OB_2GHZ, true);
-
-               ath5k_hw_rfb_op(ah, rf_regs, ee->ee_db[ee_mode][obdb],
-                                               AR5K_RF_DB_2GHZ, true);
-
-       /* RF5111 always needs OB/DB for 5GHz, even if we use 2GHz */
-       } else if ((channel->hw_value & CHANNEL_5GHZ) ||
-                       (ah->ah_radio == AR5K_RF5111)) {
-
-               /* For 11a, Turbo and XR we need to choose
-                * OB/DB based on frequency range */
-               ee_mode = AR5K_EEPROM_MODE_11A;
-               obdb =   channel->center_freq >= 5725 ? 3 :
-                       (channel->center_freq >= 5500 ? 2 :
-                       (channel->center_freq >= 5260 ? 1 :
-                        (channel->center_freq > 4000 ? 0 : -1)));
-
-               if (obdb < 0)
-                       return -EINVAL;
-
-               ath5k_hw_rfb_op(ah, rf_regs, ee->ee_ob[ee_mode][obdb],
-                                               AR5K_RF_OB_5GHZ, true);
-
-               ath5k_hw_rfb_op(ah, rf_regs, ee->ee_db[ee_mode][obdb],
-                                               AR5K_RF_DB_5GHZ, true);
-       }
-
-       g_step = &go->go_step[ah->ah_gain.g_step_idx];
-
-       /* Bank Modifications (chip-specific) */
-       if (ah->ah_radio == AR5K_RF5111) {
-
-               /* Set gain_F settings according to current step */
-               if (channel->hw_value & CHANNEL_OFDM) {
-
-                       AR5K_REG_WRITE_BITS(ah, AR5K_PHY_FRAME_CTL,
-                                       AR5K_PHY_FRAME_CTL_TX_CLIP,
-                                       g_step->gos_param[0]);
-
-                       ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[1],
-                                                       AR5K_RF_PWD_90, true);
-
-                       ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[2],
-                                                       AR5K_RF_PWD_84, true);
-
-                       ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[3],
-                                               AR5K_RF_RFGAIN_SEL, true);
-
-                       /* We programmed gain_F parameters, switch back
-                        * to active state */
-                       ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
-
-               }
-
-               /* Bank 6/7 setup */
-
-               ath5k_hw_rfb_op(ah, rf_regs, !ee->ee_xpd[ee_mode],
-                                               AR5K_RF_PWD_XPD, true);
-
-               ath5k_hw_rfb_op(ah, rf_regs, ee->ee_x_gain[ee_mode],
-                                               AR5K_RF_XPD_GAIN, true);
-
-               ath5k_hw_rfb_op(ah, rf_regs, ee->ee_i_gain[ee_mode],
-                                               AR5K_RF_GAIN_I, true);
-
-               ath5k_hw_rfb_op(ah, rf_regs, ee->ee_xpd[ee_mode],
-                                               AR5K_RF_PLO_SEL, true);
-
-               /* TODO: Half/quarter channel support */
-       }
-
-       if (ah->ah_radio == AR5K_RF5112) {
-
-               /* Set gain_F settings according to current step */
-               if (channel->hw_value & CHANNEL_OFDM) {
-
-                       ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[0],
-                                               AR5K_RF_MIXGAIN_OVR, true);
-
-                       ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[1],
-                                               AR5K_RF_PWD_138, true);
-
-                       ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[2],
-                                               AR5K_RF_PWD_137, true);
-
-                       ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[3],
-                                               AR5K_RF_PWD_136, true);
-
-                       ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[4],
-                                               AR5K_RF_PWD_132, true);
-
-                       ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[5],
-                                               AR5K_RF_PWD_131, true);
-
-                       ath5k_hw_rfb_op(ah, rf_regs, g_step->gos_param[6],
-                                               AR5K_RF_PWD_130, true);
-
-                       /* We programmed gain_F parameters, switch back
-                        * to active state */
-                       ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
-               }
-
-               /* Bank 6/7 setup */
-
-               ath5k_hw_rfb_op(ah, rf_regs, ee->ee_xpd[ee_mode],
-                                               AR5K_RF_XPD_SEL, true);
-
-               if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5112A) {
-                       /* Rev. 1 supports only one xpd */
-                       ath5k_hw_rfb_op(ah, rf_regs,
-                                               ee->ee_x_gain[ee_mode],
-                                               AR5K_RF_XPD_GAIN, true);
-
-               } else {
-                       /* TODO: Set high and low gain bits */
-                       ath5k_hw_rfb_op(ah, rf_regs,
-                                               ee->ee_x_gain[ee_mode],
-                                               AR5K_RF_PD_GAIN_LO, true);
-                       ath5k_hw_rfb_op(ah, rf_regs,
-                                               ee->ee_x_gain[ee_mode],
-                                               AR5K_RF_PD_GAIN_HI, true);
-
-                       /* Lower synth voltage on Rev 2 */
-                       ath5k_hw_rfb_op(ah, rf_regs, 2,
-                                       AR5K_RF_HIGH_VC_CP, true);
-
-                       ath5k_hw_rfb_op(ah, rf_regs, 2,
-                                       AR5K_RF_MID_VC_CP, true);
-
-                       ath5k_hw_rfb_op(ah, rf_regs, 2,
-                                       AR5K_RF_LOW_VC_CP, true);
-
-                       ath5k_hw_rfb_op(ah, rf_regs, 2,
-                                       AR5K_RF_PUSH_UP, true);
-
-                       /* Decrease power consumption on 5213+ BaseBand */
-                       if (ah->ah_phy_revision >= AR5K_SREV_PHY_5212A) {
-                               ath5k_hw_rfb_op(ah, rf_regs, 1,
-                                               AR5K_RF_PAD2GND, true);
-
-                               ath5k_hw_rfb_op(ah, rf_regs, 1,
-                                               AR5K_RF_XB2_LVL, true);
-
-                               ath5k_hw_rfb_op(ah, rf_regs, 1,
-                                               AR5K_RF_XB5_LVL, true);
-
-                               ath5k_hw_rfb_op(ah, rf_regs, 1,
-                                               AR5K_RF_PWD_167, true);
-
-                               ath5k_hw_rfb_op(ah, rf_regs, 1,
-                                               AR5K_RF_PWD_166, true);
-                       }
-               }
-
-               ath5k_hw_rfb_op(ah, rf_regs, ee->ee_i_gain[ee_mode],
-                                               AR5K_RF_GAIN_I, true);
-
-               /* TODO: Half/quarter channel support */
-
-       }
-
-       if (ah->ah_radio == AR5K_RF5413 &&
-       channel->hw_value & CHANNEL_2GHZ) {
-
-               ath5k_hw_rfb_op(ah, rf_regs, 1, AR5K_RF_DERBY_CHAN_SEL_MODE,
-                                                                       true);
-
-               /* Set optimum value for early revisions (on pci-e chips) */
-               if (ah->ah_mac_srev >= AR5K_SREV_AR5424 &&
-               ah->ah_mac_srev < AR5K_SREV_AR5413)
-                       ath5k_hw_rfb_op(ah, rf_regs, ath5k_hw_bitswap(6, 3),
-                                               AR5K_RF_PWD_ICLOBUF_2G, true);
-
-       }
-
-       /* Write RF banks on hw */
-       for (i = 0; i < ah->ah_rf_banks_size; i++) {
-               AR5K_REG_WAIT(i);
-               ath5k_hw_reg_write(ah, rfb[i], ini_rfb[i].rfb_ctrl_register);
-       }
-
-       return 0;
-}
-
-
-/**************************\
-  PHY/RF channel functions
-\**************************/
-
-/*
- * Check if a channel is supported
- */
-bool ath5k_channel_ok(struct ath5k_hw *ah, u16 freq, unsigned int flags)
-{
-       /* Check if the channel is in our supported range */
-       if (flags & CHANNEL_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)
-               if ((freq >= ah->ah_capabilities.cap_range.range_5ghz_min) &&
-                   (freq <= ah->ah_capabilities.cap_range.range_5ghz_max))
-                       return true;
-
-       return false;
-}
-
-/*
- * Convertion needed for RF5110
- */
-static u32 ath5k_hw_rf5110_chan2athchan(struct ieee80211_channel *channel)
-{
-       u32 athchan;
-
-       /*
-        * Convert IEEE channel/MHz to an internal channel value used
-        * by the AR5210 chipset. This has not been verified with
-        * newer chipsets like the AR5212A who have a completely
-        * different RF/PHY part.
-        */
-       athchan = (ath5k_hw_bitswap(
-                       (ieee80211_frequency_to_channel(
-                               channel->center_freq) - 24) / 2, 5)
-                               << 1) | (1 << 6) | 0x1;
-       return athchan;
-}
-
-/*
- * Set channel on RF5110
- */
-static int ath5k_hw_rf5110_channel(struct ath5k_hw *ah,
-               struct ieee80211_channel *channel)
-{
-       u32 data;
-
-       /*
-        * Set the channel and wait
-        */
-       data = ath5k_hw_rf5110_chan2athchan(channel);
-       ath5k_hw_reg_write(ah, data, AR5K_RF_BUFFER);
-       ath5k_hw_reg_write(ah, 0, AR5K_RF_BUFFER_CONTROL_0);
-       mdelay(1);
-
-       return 0;
-}
-
-/*
- * Convertion needed for 5111
- */
-static int ath5k_hw_rf5111_chan2athchan(unsigned int ieee,
-               struct ath5k_athchan_2ghz *athchan)
-{
-       int channel;
-
-       /* Cast this value to catch negative channel numbers (>= -19) */
-       channel = (int)ieee;
-
-       /*
-        * Map 2GHz IEEE channel to 5GHz Atheros channel
-        */
-       if (channel <= 13) {
-               athchan->a2_athchan = 115 + channel;
-               athchan->a2_flags = 0x46;
-       } else if (channel == 14) {
-               athchan->a2_athchan = 124;
-               athchan->a2_flags = 0x44;
-       } else if (channel >= 15 && channel <= 26) {
-               athchan->a2_athchan = ((channel - 14) * 4) + 132;
-               athchan->a2_flags = 0x46;
-       } else
-               return -EINVAL;
-
-       return 0;
-}
-
-/*
- * Set channel on 5111
- */
-static int ath5k_hw_rf5111_channel(struct ath5k_hw *ah,
-               struct ieee80211_channel *channel)
-{
-       struct ath5k_athchan_2ghz ath5k_channel_2ghz;
-       unsigned int ath5k_channel =
-               ieee80211_frequency_to_channel(channel->center_freq);
-       u32 data0, data1, clock;
-       int ret;
-
-       /*
-        * Set the channel on the RF5111 radio
-        */
-       data0 = data1 = 0;
-
-       if (channel->hw_value & CHANNEL_2GHZ) {
-               /* Map 2GHz channel to 5GHz Atheros channel ID */
-               ret = ath5k_hw_rf5111_chan2athchan(
-                       ieee80211_frequency_to_channel(channel->center_freq),
-                       &ath5k_channel_2ghz);
-               if (ret)
-                       return ret;
-
-               ath5k_channel = ath5k_channel_2ghz.a2_athchan;
-               data0 = ((ath5k_hw_bitswap(ath5k_channel_2ghz.a2_flags, 8) & 0xff)
-                   << 5) | (1 << 4);
-       }
-
-       if (ath5k_channel < 145 || !(ath5k_channel & 1)) {
-               clock = 1;
-               data1 = ((ath5k_hw_bitswap(ath5k_channel - 24, 8) & 0xff) << 2) |
-                       (clock << 1) | (1 << 10) | 1;
-       } else {
-               clock = 0;
-               data1 = ((ath5k_hw_bitswap((ath5k_channel - 24) / 2, 8) & 0xff)
-                       << 2) | (clock << 1) | (1 << 10) | 1;
-       }
-
-       ath5k_hw_reg_write(ah, (data1 & 0xff) | ((data0 & 0xff) << 8),
-                       AR5K_RF_BUFFER);
-       ath5k_hw_reg_write(ah, ((data1 >> 8) & 0xff) | (data0 & 0xff00),
-                       AR5K_RF_BUFFER_CONTROL_3);
-
-       return 0;
-}
-
-/*
- * Set channel on 5112 and newer
- */
-static int ath5k_hw_rf5112_channel(struct ath5k_hw *ah,
-               struct ieee80211_channel *channel)
-{
-       u32 data, data0, data1, data2;
-       u16 c;
-
-       data = data0 = data1 = data2 = 0;
-       c = channel->center_freq;
-
-       if (c < 4800) {
-               if (!((c - 2224) % 5)) {
-                       data0 = ((2 * (c - 704)) - 3040) / 10;
-                       data1 = 1;
-               } else if (!((c - 2192) % 5)) {
-                       data0 = ((2 * (c - 672)) - 3040) / 10;
-                       data1 = 0;
-               } else
-                       return -EINVAL;
-
-               data0 = ath5k_hw_bitswap((data0 << 2) & 0xff, 8);
-       } else if ((c - (c % 5)) != 2 || c > 5435) {
-               if (!(c % 20) && c >= 5120) {
-                       data0 = ath5k_hw_bitswap(((c - 4800) / 20 << 2), 8);
-                       data2 = ath5k_hw_bitswap(3, 2);
-               } else if (!(c % 10)) {
-                       data0 = ath5k_hw_bitswap(((c - 4800) / 10 << 1), 8);
-                       data2 = ath5k_hw_bitswap(2, 2);
-               } else if (!(c % 5)) {
-                       data0 = ath5k_hw_bitswap((c - 4800) / 5, 8);
-                       data2 = ath5k_hw_bitswap(1, 2);
-               } else
-                       return -EINVAL;
-       } else {
-               data0 = ath5k_hw_bitswap((10 * (c - 2) - 4800) / 25 + 1, 8);
-               data2 = ath5k_hw_bitswap(0, 2);
-       }
-
-       data = (data0 << 4) | (data1 << 1) | (data2 << 2) | 0x1001;
-
-       ath5k_hw_reg_write(ah, data & 0xff, AR5K_RF_BUFFER);
-       ath5k_hw_reg_write(ah, (data >> 8) & 0x7f, AR5K_RF_BUFFER_CONTROL_5);
-
-       return 0;
-}
-
-/*
- * Set the channel on the RF2425
- */
-static int ath5k_hw_rf2425_channel(struct ath5k_hw *ah,
-               struct ieee80211_channel *channel)
-{
-       u32 data, data0, data2;
-       u16 c;
-
-       data = data0 = data2 = 0;
-       c = channel->center_freq;
-
-       if (c < 4800) {
-               data0 = ath5k_hw_bitswap((c - 2272), 8);
-               data2 = 0;
-       /* ? 5GHz ? */
-       } else if ((c - (c % 5)) != 2 || c > 5435) {
-               if (!(c % 20) && c < 5120)
-                       data0 = ath5k_hw_bitswap(((c - 4800) / 20 << 2), 8);
-               else if (!(c % 10))
-                       data0 = ath5k_hw_bitswap(((c - 4800) / 10 << 1), 8);
-               else if (!(c % 5))
-                       data0 = ath5k_hw_bitswap((c - 4800) / 5, 8);
-               else
-                       return -EINVAL;
-               data2 = ath5k_hw_bitswap(1, 2);
-       } else {
-               data0 = ath5k_hw_bitswap((10 * (c - 2) - 4800) / 25 + 1, 8);
-               data2 = ath5k_hw_bitswap(0, 2);
-       }
-
-       data = (data0 << 4) | data2 << 2 | 0x1001;
-
-       ath5k_hw_reg_write(ah, data & 0xff, AR5K_RF_BUFFER);
-       ath5k_hw_reg_write(ah, (data >> 8) & 0x7f, AR5K_RF_BUFFER_CONTROL_5);
-
-       return 0;
-}
-
-/*
- * Set a channel on the radio chip
- */
-int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel)
-{
-       int ret;
-       /*
-        * Check bounds supported by the PHY (we don't care about regultory
-        * 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)) {
-               ATH5K_ERR(ah->ah_sc,
-                       "channel frequency (%u MHz) out of supported "
-                       "band range\n",
-                       channel->center_freq);
-                       return -EINVAL;
-       }
-
-       /*
-        * Set the channel and wait
-        */
-       switch (ah->ah_radio) {
-       case AR5K_RF5110:
-               ret = ath5k_hw_rf5110_channel(ah, channel);
-               break;
-       case AR5K_RF5111:
-               ret = ath5k_hw_rf5111_channel(ah, channel);
-               break;
-       case AR5K_RF2425:
-               ret = ath5k_hw_rf2425_channel(ah, channel);
-               break;
-       default:
-               ret = ath5k_hw_rf5112_channel(ah, channel);
-               break;
-       }
-
-       if (ret)
-               return ret;
-
-       /* Set JAPAN setting for channel 14 */
-       if (channel->center_freq == 2484) {
-               AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_CCKTXCTL,
-                               AR5K_PHY_CCKTXCTL_JAPAN);
-       } else {
-               AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_CCKTXCTL,
-                               AR5K_PHY_CCKTXCTL_WORLD);
-       }
-
-       ah->ah_current_channel.center_freq = channel->center_freq;
-       ah->ah_current_channel.hw_value = channel->hw_value;
-       ah->ah_turbo = channel->hw_value == CHANNEL_T ? true : false;
-
-       return 0;
-}
-
-/*****************\
-  PHY calibration
-\*****************/
-
-/**
- * ath5k_hw_noise_floor_calibration - perform PHY noise floor calibration
- *
- * @ah: struct ath5k_hw pointer we are operating on
- * @freq: the channel frequency, just used for error logging
- *
- * This function performs a noise floor calibration of the PHY and waits for
- * it to complete. Then the noise floor value is compared to some maximum
- * noise floor we consider valid.
- *
- * Note that this is different from what the madwifi HAL does: it reads the
- * noise floor and afterwards initiates the calibration. Since the noise floor
- * calibration can take some time to finish, depending on the current channel
- * use, that avoids the occasional timeout warnings we are seeing now.
- *
- * See the following link for an Atheros patent on noise floor calibration:
- * http://patft.uspto.gov/netacgi/nph-Parser?Sect1=PTO1&Sect2=HITOFF&d=PALL \
- * &p=1&u=%2Fnetahtml%2FPTO%2Fsrchnum.htm&r=1&f=G&l=50&s1=7245893.PN.&OS=PN/7
- *
- * XXX: Since during noise floor calibration antennas are detached according to
- * the patent, we should stop tx queues here.
- */
-int
-ath5k_hw_noise_floor_calibration(struct ath5k_hw *ah, short freq)
-{
-       int ret;
-       unsigned int i;
-       s32 noise_floor;
-
-       /*
-        * Enable noise floor calibration
-        */
-       AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
-                               AR5K_PHY_AGCCTL_NF);
-
-       ret = ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL,
-                       AR5K_PHY_AGCCTL_NF, 0, false);
-       if (ret) {
-               ATH5K_ERR(ah->ah_sc,
-                       "noise floor calibration timeout (%uMHz)\n", freq);
-               return -EAGAIN;
-       }
-
-       /* Wait until the noise floor is calibrated and read the value */
-       for (i = 20; i > 0; i--) {
-               mdelay(1);
-               noise_floor = ath5k_hw_reg_read(ah, AR5K_PHY_NF);
-               noise_floor = AR5K_PHY_NF_RVAL(noise_floor);
-               if (noise_floor & AR5K_PHY_NF_ACTIVE) {
-                       noise_floor = AR5K_PHY_NF_AVAL(noise_floor);
-
-                       if (noise_floor <= AR5K_TUNE_NOISE_FLOOR)
-                               break;
-               }
-       }
-
-       ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_CALIBRATE,
-               "noise floor %d\n", noise_floor);
-
-       if (noise_floor > AR5K_TUNE_NOISE_FLOOR) {
-               ATH5K_ERR(ah->ah_sc,
-                       "noise floor calibration failed (%uMHz)\n", freq);
-               return -EAGAIN;
-       }
-
-       ah->ah_noise_floor = noise_floor;
-
-       return 0;
-}
-
-/*
- * Perform a PHY calibration on RF5110
- * -Fix BPSK/QAM Constellation (I/Q correction)
- * -Calculate Noise Floor
- */
-static int ath5k_hw_rf5110_calibrate(struct ath5k_hw *ah,
-               struct ieee80211_channel *channel)
-{
-       u32 phy_sig, phy_agc, phy_sat, beacon;
-       int ret;
-
-       /*
-        * Disable beacons and RX/TX queues, wait
-        */
-       AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW_5210,
-               AR5K_DIAG_SW_DIS_TX | AR5K_DIAG_SW_DIS_RX_5210);
-       beacon = ath5k_hw_reg_read(ah, AR5K_BEACON_5210);
-       ath5k_hw_reg_write(ah, beacon & ~AR5K_BEACON_ENABLE, AR5K_BEACON_5210);
-
-       mdelay(2);
-
-       /*
-        * Set the channel (with AGC turned off)
-        */
-       AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGC, AR5K_PHY_AGC_DISABLE);
-       udelay(10);
-       ret = ath5k_hw_channel(ah, channel);
-
-       /*
-        * Activate PHY and wait
-        */
-       ath5k_hw_reg_write(ah, AR5K_PHY_ACT_ENABLE, AR5K_PHY_ACT);
-       mdelay(1);
-
-       AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_AGC, AR5K_PHY_AGC_DISABLE);
-
-       if (ret)
-               return ret;
-
-       /*
-        * Calibrate the radio chip
-        */
-
-       /* Remember normal state */
-       phy_sig = ath5k_hw_reg_read(ah, AR5K_PHY_SIG);
-       phy_agc = ath5k_hw_reg_read(ah, AR5K_PHY_AGCCOARSE);
-       phy_sat = ath5k_hw_reg_read(ah, AR5K_PHY_ADCSAT);
-
-       /* Update radio registers */
-       ath5k_hw_reg_write(ah, (phy_sig & ~(AR5K_PHY_SIG_FIRPWR)) |
-               AR5K_REG_SM(-1, AR5K_PHY_SIG_FIRPWR), AR5K_PHY_SIG);
-
-       ath5k_hw_reg_write(ah, (phy_agc & ~(AR5K_PHY_AGCCOARSE_HI |
-                       AR5K_PHY_AGCCOARSE_LO)) |
-               AR5K_REG_SM(-1, AR5K_PHY_AGCCOARSE_HI) |
-               AR5K_REG_SM(-127, AR5K_PHY_AGCCOARSE_LO), AR5K_PHY_AGCCOARSE);
-
-       ath5k_hw_reg_write(ah, (phy_sat & ~(AR5K_PHY_ADCSAT_ICNT |
-                       AR5K_PHY_ADCSAT_THR)) |
-               AR5K_REG_SM(2, AR5K_PHY_ADCSAT_ICNT) |
-               AR5K_REG_SM(12, AR5K_PHY_ADCSAT_THR), AR5K_PHY_ADCSAT);
-
-       udelay(20);
-
-       AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGC, AR5K_PHY_AGC_DISABLE);
-       udelay(10);
-       ath5k_hw_reg_write(ah, AR5K_PHY_RFSTG_DISABLE, AR5K_PHY_RFSTG);
-       AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_AGC, AR5K_PHY_AGC_DISABLE);
-
-       mdelay(1);
-
-       /*
-        * Enable calibration and wait until completion
-        */
-       AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL, AR5K_PHY_AGCCTL_CAL);
-
-       ret = ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL,
-                       AR5K_PHY_AGCCTL_CAL, 0, false);
-
-       /* Reset to normal state */
-       ath5k_hw_reg_write(ah, phy_sig, AR5K_PHY_SIG);
-       ath5k_hw_reg_write(ah, phy_agc, AR5K_PHY_AGCCOARSE);
-       ath5k_hw_reg_write(ah, phy_sat, AR5K_PHY_ADCSAT);
-
-       if (ret) {
-               ATH5K_ERR(ah->ah_sc, "calibration timeout (%uMHz)\n",
-                               channel->center_freq);
-               return ret;
-       }
-
-       ath5k_hw_noise_floor_calibration(ah, channel->center_freq);
-
-       /*
-        * Re-enable RX/TX and beacons
-        */
-       AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW_5210,
-               AR5K_DIAG_SW_DIS_TX | AR5K_DIAG_SW_DIS_RX_5210);
-       ath5k_hw_reg_write(ah, beacon, AR5K_BEACON_5210);
-
-       return 0;
-}
-
-/*
- * Perform a PHY calibration on RF5111/5112 and newer chips
- */
-static int ath5k_hw_rf511x_calibrate(struct ath5k_hw *ah,
-               struct ieee80211_channel *channel)
-{
-       u32 i_pwr, q_pwr;
-       s32 iq_corr, i_coff, i_coffd, q_coff, q_coffd;
-       int i;
-       ATH5K_TRACE(ah->ah_sc);
-
-       if (!ah->ah_calibration ||
-               ath5k_hw_reg_read(ah, AR5K_PHY_IQ) & AR5K_PHY_IQ_RUN)
-               goto done;
-
-       /* Calibration has finished, get the results and re-run */
-       for (i = 0; i <= 10; i++) {
-               iq_corr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_CORR);
-               i_pwr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_PWR_I);
-               q_pwr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_PWR_Q);
-       }
-
-       i_coffd = ((i_pwr >> 1) + (q_pwr >> 1)) >> 7;
-       q_coffd = q_pwr >> 7;
-
-       /* No correction */
-       if (i_coffd == 0 || q_coffd == 0)
-               goto done;
-
-       i_coff = ((-iq_corr) / i_coffd) & 0x3f;
-
-       /* Boundary check */
-       if (i_coff > 31)
-               i_coff = 31;
-       if (i_coff < -32)
-               i_coff = -32;
-
-       q_coff = (((s32)i_pwr / q_coffd) - 128) & 0x1f;
-
-       /* Boundary check */
-       if (q_coff > 15)
-               q_coff = 15;
-       if (q_coff < -16)
-               q_coff = -16;
-
-       /* Commit new I/Q value */
-       AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_ENABLE |
-               ((u32)q_coff) | ((u32)i_coff << AR5K_PHY_IQ_CORR_Q_I_COFF_S));
-
-       /* Re-enable calibration -if we don't we'll commit
-        * the same values again and again */
-       AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ,
-                       AR5K_PHY_IQ_CAL_NUM_LOG_MAX, 15);
-       AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_RUN);
-
-done:
-
-       /* TODO: Separate noise floor calibration from I/Q calibration
-        * since noise floor calibration interrupts rx path while I/Q
-        * calibration doesn't. We don't need to run noise floor calibration
-        * as often as I/Q calibration.*/
-       ath5k_hw_noise_floor_calibration(ah, channel->center_freq);
-
-       /* Initiate a gain_F calibration */
-       ath5k_hw_request_rfgain_probe(ah);
-
-       return 0;
-}
-
-/*
- * Perform a PHY calibration
- */
-int ath5k_hw_phy_calibrate(struct ath5k_hw *ah,
-               struct ieee80211_channel *channel)
-{
-       int ret;
-
-       if (ah->ah_radio == AR5K_RF5110)
-               ret = ath5k_hw_rf5110_calibrate(ah, channel);
-       else
-               ret = ath5k_hw_rf511x_calibrate(ah, channel);
-
-       return ret;
-}
-
-int ath5k_hw_phy_disable(struct ath5k_hw *ah)
-{
-       ATH5K_TRACE(ah->ah_sc);
-       /*Just a try M.F.*/
-       ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT);
-
-       return 0;
-}
-
-/********************\
-  Misc PHY functions
-\********************/
-
-/*
- * Get the PHY Chip revision
- */
-u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan)
-{
-       unsigned int i;
-       u32 srev;
-       u16 ret;
-
-       ATH5K_TRACE(ah->ah_sc);
-
-       /*
-        * Set the radio chip access register
-        */
-       switch (chan) {
-       case CHANNEL_2GHZ:
-               ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_2GHZ, AR5K_PHY(0));
-               break;
-       case CHANNEL_5GHZ:
-               ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0));
-               break;
-       default:
-               return 0;
-       }
-
-       mdelay(2);
-
-       /* ...wait until PHY is ready and read the selected radio revision */
-       ath5k_hw_reg_write(ah, 0x00001c16, AR5K_PHY(0x34));
-
-       for (i = 0; i < 8; i++)
-               ath5k_hw_reg_write(ah, 0x00010000, AR5K_PHY(0x20));
-
-       if (ah->ah_version == AR5K_AR5210) {
-               srev = ath5k_hw_reg_read(ah, AR5K_PHY(256) >> 28) & 0xf;
-               ret = (u16)ath5k_hw_bitswap(srev, 4) + 1;
-       } else {
-               srev = (ath5k_hw_reg_read(ah, AR5K_PHY(0x100)) >> 24) & 0xff;
-               ret = (u16)ath5k_hw_bitswap(((srev & 0xf0) >> 4) |
-                               ((srev & 0x0f) << 4), 8);
-       }
-
-       /* Reset to the 5GHz mode */
-       ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0));
-
-       return ret;
-}
-
-void /*TODO:Boundary check*/
-ath5k_hw_set_def_antenna(struct ath5k_hw *ah, unsigned int ant)
-{
-       ATH5K_TRACE(ah->ah_sc);
-       /*Just a try M.F.*/
-       if (ah->ah_version != AR5K_AR5210)
-               ath5k_hw_reg_write(ah, ant, AR5K_DEFAULT_ANTENNA);
-}
-
-unsigned int ath5k_hw_get_def_antenna(struct ath5k_hw *ah)
-{
-       ATH5K_TRACE(ah->ah_sc);
-       /*Just a try M.F.*/
-       if (ah->ah_version != AR5K_AR5210)
-               return ath5k_hw_reg_read(ah, AR5K_DEFAULT_ANTENNA);
-
-       return false; /*XXX: What do we return for 5210 ?*/
-}
-
-
-/****************\
-* TX power setup *
-\****************/
-
-/*
- * Helper functions
- */
-
-/*
- * Do linear interpolation between two given (x, y) points
- */
-static s16
-ath5k_get_interpolated_value(s16 target, s16 x_left, s16 x_right,
-                                       s16 y_left, s16 y_right)
-{
-       s16 ratio, result;
-
-       /* Avoid divide by zero and skip interpolation
-        * if we have the same point */
-       if ((x_left == x_right) || (y_left == y_right))
-               return y_left;
-
-       /*
-        * Since we use ints and not fps, we need to scale up in
-        * order to get a sane ratio value (or else we 'll eg. get
-        * always 1 instead of 1.25, 1.75 etc). We scale up by 100
-        * to have some accuracy both for 0.5 and 0.25 steps.
-        */
-       ratio = ((100 * y_right - 100 * y_left)/(x_right - x_left));
-
-       /* Now scale down to be in range */
-       result = y_left + (ratio * (target - x_left) / 100);
-
-       return result;
-}
-
-/*
- * Find vertical boundary (min pwr) for the linear PCDAC curve.
- *
- * Since we have the top of the curve and we draw the line below
- * until we reach 1 (1 pcdac step) we need to know which point
- * (x value) that is so that we don't go below y axis and have negative
- * pcdac values when creating the curve, or fill the table with zeroes.
- */
-static s16
-ath5k_get_linear_pcdac_min(const u8 *stepL, const u8 *stepR,
-                               const s16 *pwrL, const s16 *pwrR)
-{
-       s8 tmp;
-       s16 min_pwrL, min_pwrR;
-       s16 pwr_i;
-
-       if (pwrL[0] == pwrL[1])
-               min_pwrL = pwrL[0];
-       else {
-               pwr_i = pwrL[0];
-               do {
-                       pwr_i--;
-                       tmp = (s8) ath5k_get_interpolated_value(pwr_i,
-                                                       pwrL[0], pwrL[1],
-                                                       stepL[0], stepL[1]);
-               } while (tmp > 1);
-
-               min_pwrL = pwr_i;
-       }
-
-       if (pwrR[0] == pwrR[1])
-               min_pwrR = pwrR[0];
-       else {
-               pwr_i = pwrR[0];
-               do {
-                       pwr_i--;
-                       tmp = (s8) ath5k_get_interpolated_value(pwr_i,
-                                                       pwrR[0], pwrR[1],
-                                                       stepR[0], stepR[1]);
-               } while (tmp > 1);
-
-               min_pwrR = pwr_i;
-       }
-
-       /* Keep the right boundary so that it works for both curves */
-       return max(min_pwrL, min_pwrR);
-}
-
-/*
- * Interpolate (pwr,vpd) points to create a Power to PDADC or a
- * Power to PCDAC curve.
- *
- * Each curve has power on x axis (in 0.5dB units) and PCDAC/PDADC
- * steps (offsets) on y axis. Power can go up to 31.5dB and max
- * PCDAC/PDADC step for each curve is 64 but we can write more than
- * one curves on hw so we can go up to 128 (which is the max step we
- * can write on the final table).
- *
- * We write y values (PCDAC/PDADC steps) on hw.
- */
-static void
-ath5k_create_power_curve(s16 pmin, s16 pmax,
-                       const s16 *pwr, const u8 *vpd,
-                       u8 num_points,
-                       u8 *vpd_table, u8 type)
-{
-       u8 idx[2] = { 0, 1 };
-       s16 pwr_i = 2*pmin;
-       int i;
-
-       if (num_points < 2)
-               return;
-
-       /* We want the whole line, so adjust boundaries
-        * to cover the entire power range. Note that
-        * power values are already 0.25dB so no need
-        * to multiply pwr_i by 2 */
-       if (type == AR5K_PWRTABLE_LINEAR_PCDAC) {
-               pwr_i = pmin;
-               pmin = 0;
-               pmax = 63;
-       }
-
-       /* Find surrounding turning points (TPs)
-        * and interpolate between them */
-       for (i = 0; (i <= (u16) (pmax - pmin)) &&
-       (i < AR5K_EEPROM_POWER_TABLE_SIZE); i++) {
-
-               /* We passed the right TP, move to the next set of TPs
-                * if we pass the last TP, extrapolate above using the last
-                * two TPs for ratio */
-               if ((pwr_i > pwr[idx[1]]) && (idx[1] < num_points - 1)) {
-                       idx[0]++;
-                       idx[1]++;
-               }
-
-               vpd_table[i] = (u8) ath5k_get_interpolated_value(pwr_i,
-                                               pwr[idx[0]], pwr[idx[1]],
-                                               vpd[idx[0]], vpd[idx[1]]);
-
-               /* Increase by 0.5dB
-                * (0.25 dB units) */
-               pwr_i += 2;
-       }
-}
-
-/*
- * Get the surrounding per-channel power calibration piers
- * for a given frequency so that we can interpolate between
- * them and come up with an apropriate dataset for our current
- * channel.
- */
-static void
-ath5k_get_chan_pcal_surrounding_piers(struct ath5k_hw *ah,
-                       struct ieee80211_channel *channel,
-                       struct ath5k_chan_pcal_info **pcinfo_l,
-                       struct ath5k_chan_pcal_info **pcinfo_r)
-{
-       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
-       struct ath5k_chan_pcal_info *pcinfo;
-       u8 idx_l, idx_r;
-       u8 mode, max, i;
-       u32 target = channel->center_freq;
-
-       idx_l = 0;
-       idx_r = 0;
-
-       if (!(channel->hw_value & CHANNEL_OFDM)) {
-               pcinfo = ee->ee_pwr_cal_b;
-               mode = AR5K_EEPROM_MODE_11B;
-       } else if (channel->hw_value & CHANNEL_2GHZ) {
-               pcinfo = ee->ee_pwr_cal_g;
-               mode = AR5K_EEPROM_MODE_11G;
-       } else {
-               pcinfo = ee->ee_pwr_cal_a;
-               mode = AR5K_EEPROM_MODE_11A;
-       }
-       max = ee->ee_n_piers[mode] - 1;
-
-       /* Frequency is below our calibrated
-        * range. Use the lowest power curve
-        * we have */
-       if (target < pcinfo[0].freq) {
-               idx_l = idx_r = 0;
-               goto done;
-       }
-
-       /* Frequency is above our calibrated
-        * range. Use the highest power curve
-        * we have */
-       if (target > pcinfo[max].freq) {
-               idx_l = idx_r = max;
-               goto done;
-       }
-
-       /* Frequency is inside our calibrated
-        * channel range. Pick the surrounding
-        * calibration piers so that we can
-        * interpolate */
-       for (i = 0; i <= max; i++) {
-
-               /* Frequency matches one of our calibration
-                * piers, no need to interpolate, just use
-                * that calibration pier */
-               if (pcinfo[i].freq == target) {
-                       idx_l = idx_r = i;
-                       goto done;
-               }
-
-               /* We found a calibration pier that's above
-                * frequency, use this pier and the previous
-                * one to interpolate */
-               if (target < pcinfo[i].freq) {
-                       idx_r = i;
-                       idx_l = idx_r - 1;
-                       goto done;
-               }
-       }
-
-done:
-       *pcinfo_l = &pcinfo[idx_l];
-       *pcinfo_r = &pcinfo[idx_r];
-
-       return;
-}
-
-/*
- * Get the surrounding per-rate power calibration data
- * for a given frequency and interpolate between power
- * values to set max target power supported by hw for
- * each rate.
- */
-static void
-ath5k_get_rate_pcal_data(struct ath5k_hw *ah,
-                       struct ieee80211_channel *channel,
-                       struct ath5k_rate_pcal_info *rates)
-{
-       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
-       struct ath5k_rate_pcal_info *rpinfo;
-       u8 idx_l, idx_r;
-       u8 mode, max, i;
-       u32 target = channel->center_freq;
-
-       idx_l = 0;
-       idx_r = 0;
-
-       if (!(channel->hw_value & CHANNEL_OFDM)) {
-               rpinfo = ee->ee_rate_tpwr_b;
-               mode = AR5K_EEPROM_MODE_11B;
-       } else if (channel->hw_value & CHANNEL_2GHZ) {
-               rpinfo = ee->ee_rate_tpwr_g;
-               mode = AR5K_EEPROM_MODE_11G;
-       } else {
-               rpinfo = ee->ee_rate_tpwr_a;
-               mode = AR5K_EEPROM_MODE_11A;
-       }
-       max = ee->ee_rate_target_pwr_num[mode] - 1;
-
-       /* Get the surrounding calibration
-        * piers - same as above */
-       if (target < rpinfo[0].freq) {
-               idx_l = idx_r = 0;
-               goto done;
-       }
-
-       if (target > rpinfo[max].freq) {
-               idx_l = idx_r = max;
-               goto done;
-       }
-
-       for (i = 0; i <= max; i++) {
-
-               if (rpinfo[i].freq == target) {
-                       idx_l = idx_r = i;
-                       goto done;
-               }
-
-               if (target < rpinfo[i].freq) {
-                       idx_r = i;
-                       idx_l = idx_r - 1;
-                       goto done;
-               }
-       }
-
-done:
-       /* Now interpolate power value, based on the frequency */
-       rates->freq = target;
-
-       rates->target_power_6to24 =
-               ath5k_get_interpolated_value(target, rpinfo[idx_l].freq,
-                                       rpinfo[idx_r].freq,
-                                       rpinfo[idx_l].target_power_6to24,
-                                       rpinfo[idx_r].target_power_6to24);
-
-       rates->target_power_36 =
-               ath5k_get_interpolated_value(target, rpinfo[idx_l].freq,
-                                       rpinfo[idx_r].freq,
-                                       rpinfo[idx_l].target_power_36,
-                                       rpinfo[idx_r].target_power_36);
-
-       rates->target_power_48 =
-               ath5k_get_interpolated_value(target, rpinfo[idx_l].freq,
-                                       rpinfo[idx_r].freq,
-                                       rpinfo[idx_l].target_power_48,
-                                       rpinfo[idx_r].target_power_48);
-
-       rates->target_power_54 =
-               ath5k_get_interpolated_value(target, rpinfo[idx_l].freq,
-                                       rpinfo[idx_r].freq,
-                                       rpinfo[idx_l].target_power_54,
-                                       rpinfo[idx_r].target_power_54);
-}
-
-/*
- * Get the max edge power for this channel if
- * we have such data from EEPROM's Conformance Test
- * Limits (CTL), and limit max power if needed.
- *
- * FIXME: Only works for world regulatory domains
- */
-static void
-ath5k_get_max_ctl_power(struct ath5k_hw *ah,
-                       struct ieee80211_channel *channel)
-{
-       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
-       struct ath5k_edge_power *rep = ee->ee_ctl_pwr;
-       u8 *ctl_val = ee->ee_ctl;
-       s16 max_chan_pwr = ah->ah_txpower.txp_max_pwr / 4;
-       s16 edge_pwr = 0;
-       u8 rep_idx;
-       u8 i, ctl_mode;
-       u8 ctl_idx = 0xFF;
-       u32 target = channel->center_freq;
-
-       /* Find out a CTL for our mode that's not mapped
-        * on a specific reg domain.
-        *
-        * TODO: Map our current reg domain to one of the 3 available
-        * reg domain ids so that we can support more CTLs. */
-       switch (channel->hw_value & CHANNEL_MODES) {
-       case CHANNEL_A:
-               ctl_mode = AR5K_CTL_11A | AR5K_CTL_NO_REGDOMAIN;
-               break;
-       case CHANNEL_G:
-               ctl_mode = AR5K_CTL_11G | AR5K_CTL_NO_REGDOMAIN;
-               break;
-       case CHANNEL_B:
-               ctl_mode = AR5K_CTL_11B | AR5K_CTL_NO_REGDOMAIN;
-               break;
-       case CHANNEL_T:
-               ctl_mode = AR5K_CTL_TURBO | AR5K_CTL_NO_REGDOMAIN;
-               break;
-       case CHANNEL_TG:
-               ctl_mode = AR5K_CTL_TURBOG | AR5K_CTL_NO_REGDOMAIN;
-               break;
-       case CHANNEL_XR:
-               /* Fall through */
-       default:
-               return;
-       }
-
-       for (i = 0; i < ee->ee_ctls; i++) {
-               if (ctl_val[i] == ctl_mode) {
-                       ctl_idx = i;
-                       break;
-               }
-       }
-
-       /* If we have a CTL dataset available grab it and find the
-        * edge power for our frequency */
-       if (ctl_idx == 0xFF)
-               return;
-
-       /* Edge powers are sorted by frequency from lower
-        * to higher. Each CTL corresponds to 8 edge power
-        * measurements. */
-       rep_idx = ctl_idx * AR5K_EEPROM_N_EDGES;
-
-       /* Don't do boundaries check because we
-        * might have more that one bands defined
-        * for this mode */
-
-       /* Get the edge power that's closer to our
-        * frequency */
-       for (i = 0; i < AR5K_EEPROM_N_EDGES; i++) {
-               rep_idx += i;
-               if (target <= rep[rep_idx].freq)
-                       edge_pwr = (s16) rep[rep_idx].edge;
-       }
-
-       if (edge_pwr)
-               ah->ah_txpower.txp_max_pwr = 4*min(edge_pwr, max_chan_pwr);
-}
-
-
-/*
- * Power to PCDAC table functions
- */
-
-/*
- * Fill Power to PCDAC table on RF5111
- *
- * No further processing is needed for RF5111, the only thing we have to
- * do is fill the values below and above calibration range since eeprom data
- * may not cover the entire PCDAC table.
- */
-static void
-ath5k_fill_pwr_to_pcdac_table(struct ath5k_hw *ah, s16* table_min,
-                                                       s16 *table_max)
-{
-       u8      *pcdac_out = ah->ah_txpower.txp_pd_table;
-       u8      *pcdac_tmp = ah->ah_txpower.tmpL[0];
-       u8      pcdac_0, pcdac_n, pcdac_i, pwr_idx, i;
-       s16     min_pwr, max_pwr;
-
-       /* Get table boundaries */
-       min_pwr = table_min[0];
-       pcdac_0 = pcdac_tmp[0];
-
-       max_pwr = table_max[0];
-       pcdac_n = pcdac_tmp[table_max[0] - table_min[0]];
-
-       /* Extrapolate below minimum using pcdac_0 */
-       pcdac_i = 0;
-       for (i = 0; i < min_pwr; i++)
-               pcdac_out[pcdac_i++] = pcdac_0;
-
-       /* Copy values from pcdac_tmp */
-       pwr_idx = min_pwr;
-       for (i = 0 ; pwr_idx <= max_pwr &&
-       pcdac_i < AR5K_EEPROM_POWER_TABLE_SIZE; i++) {
-               pcdac_out[pcdac_i++] = pcdac_tmp[i];
-               pwr_idx++;
-       }
-
-       /* Extrapolate above maximum */
-       while (pcdac_i < AR5K_EEPROM_POWER_TABLE_SIZE)
-               pcdac_out[pcdac_i++] = pcdac_n;
-
-}
-
-/*
- * Combine available XPD Curves and fill Linear Power to PCDAC table
- * on RF5112
- *
- * RFX112 can have up to 2 curves (one for low txpower range and one for
- * higher txpower range). We need to put them both on pcdac_out and place
- * them in the correct location. In case we only have one curve available
- * just fit it on pcdac_out (it's supposed to cover the entire range of
- * available pwr levels since it's always the higher power curve). Extrapolate
- * below and above final table if needed.
- */
-static void
-ath5k_combine_linear_pcdac_curves(struct ath5k_hw *ah, s16* table_min,
-                                               s16 *table_max, u8 pdcurves)
-{
-       u8      *pcdac_out = ah->ah_txpower.txp_pd_table;
-       u8      *pcdac_low_pwr;
-       u8      *pcdac_high_pwr;
-       u8      *pcdac_tmp;
-       u8      pwr;
-       s16     max_pwr_idx;
-       s16     min_pwr_idx;
-       s16     mid_pwr_idx = 0;
-       /* Edge flag turs on the 7nth bit on the PCDAC
-        * to delcare the higher power curve (force values
-        * to be greater than 64). If we only have one curve
-        * we don't need to set this, if we have 2 curves and
-        * fill the table backwards this can also be used to
-        * switch from higher power curve to lower power curve */
-       u8      edge_flag;
-       int     i;
-
-       /* When we have only one curve available
-        * that's the higher power curve. If we have
-        * two curves the first is the high power curve
-        * and the next is the low power curve. */
-       if (pdcurves > 1) {
-               pcdac_low_pwr = ah->ah_txpower.tmpL[1];
-               pcdac_high_pwr = ah->ah_txpower.tmpL[0];
-               mid_pwr_idx = table_max[1] - table_min[1] - 1;
-               max_pwr_idx = (table_max[0] - table_min[0]) / 2;
-
-               /* If table size goes beyond 31.5dB, keep the
-                * upper 31.5dB range when setting tx power.
-                * Note: 126 = 31.5 dB in quarter dB steps */
-               if (table_max[0] - table_min[1] > 126)
-                       min_pwr_idx = table_max[0] - 126;
-               else
-                       min_pwr_idx = table_min[1];
-
-               /* Since we fill table backwards
-                * start from high power curve */
-               pcdac_tmp = pcdac_high_pwr;
-
-               edge_flag = 0x40;
-#if 0
-               /* If both min and max power limits are in lower
-                * power curve's range, only use the low power curve.
-                * TODO: min/max levels are related to target
-                * power values requested from driver/user
-                * XXX: Is this really needed ? */
-               if (min_pwr < table_max[1] &&
-               max_pwr < table_max[1]) {
-                       edge_flag = 0;
-                       pcdac_tmp = pcdac_low_pwr;
-                       max_pwr_idx = (table_max[1] - table_min[1])/2;
-               }
-#endif
-       } else {
-               pcdac_low_pwr = ah->ah_txpower.tmpL[1]; /* Zeroed */
-               pcdac_high_pwr = ah->ah_txpower.tmpL[0];
-               min_pwr_idx = table_min[0];
-               max_pwr_idx = (table_max[0] - table_min[0]) / 2;
-               pcdac_tmp = pcdac_high_pwr;
-               edge_flag = 0;
-       }
-
-       /* This is used when setting tx power*/
-       ah->ah_txpower.txp_min_idx = min_pwr_idx/2;
-
-       /* Fill Power to PCDAC table backwards */
-       pwr = max_pwr_idx;
-       for (i = 63; i >= 0; i--) {
-               /* Entering lower power range, reset
-                * edge flag and set pcdac_tmp to lower
-                * power curve.*/
-               if (edge_flag == 0x40 &&
-               (2*pwr <= (table_max[1] - table_min[0]) || pwr == 0)) {
-                       edge_flag = 0x00;
-                       pcdac_tmp = pcdac_low_pwr;
-                       pwr = mid_pwr_idx/2;
-               }
-
-               /* Don't go below 1, extrapolate below if we have
-                * already swithced to the lower power curve -or
-                * we only have one curve and edge_flag is zero
-                * anyway */
-               if (pcdac_tmp[pwr] < 1 && (edge_flag == 0x00)) {
-                       while (i >= 0) {
-                               pcdac_out[i] = pcdac_out[i + 1];
-                               i--;
-                       }
-                       break;
-               }
-
-               pcdac_out[i] = pcdac_tmp[pwr] | edge_flag;
-
-               /* Extrapolate above if pcdac is greater than
-                * 126 -this can happen because we OR pcdac_out
-                * value with edge_flag on high power curve */
-               if (pcdac_out[i] > 126)
-                       pcdac_out[i] = 126;
-
-               /* Decrease by a 0.5dB step */
-               pwr--;
-       }
-}
-
-/* Write PCDAC values on hw */
-static void
-ath5k_setup_pcdac_table(struct ath5k_hw *ah)
-{
-       u8      *pcdac_out = ah->ah_txpower.txp_pd_table;
-       int     i;
-
-       /*
-        * Write TX power values
-        */
-       for (i = 0; i < (AR5K_EEPROM_POWER_TABLE_SIZE / 2); i++) {
-               ath5k_hw_reg_write(ah,
-                       (((pcdac_out[2*i + 0] << 8 | 0xff) & 0xffff) << 0) |
-                       (((pcdac_out[2*i + 1] << 8 | 0xff) & 0xffff) << 16),
-                       AR5K_PHY_PCDAC_TXPOWER(i));
-       }
-}
-
-
-/*
- * Power to PDADC table functions
- */
-
-/*
- * Set the gain boundaries and create final Power to PDADC table
- *
- * We can have up to 4 pd curves, we need to do a simmilar process
- * as we do for RF5112. This time we don't have an edge_flag but we
- * set the gain boundaries on a separate register.
- */
-static void
-ath5k_combine_pwr_to_pdadc_curves(struct ath5k_hw *ah,
-                       s16 *pwr_min, s16 *pwr_max, u8 pdcurves)
-{
-       u8 gain_boundaries[AR5K_EEPROM_N_PD_GAINS];
-       u8 *pdadc_out = ah->ah_txpower.txp_pd_table;
-       u8 *pdadc_tmp;
-       s16 pdadc_0;
-       u8 pdadc_i, pdadc_n, pwr_step, pdg, max_idx, table_size;
-       u8 pd_gain_overlap;
-
-       /* Note: Register value is initialized on initvals
-        * there is no feedback from hw.
-        * XXX: What about pd_gain_overlap from EEPROM ? */
-       pd_gain_overlap = (u8) ath5k_hw_reg_read(ah, AR5K_PHY_TPC_RG5) &
-               AR5K_PHY_TPC_RG5_PD_GAIN_OVERLAP;
-
-       /* Create final PDADC table */
-       for (pdg = 0, pdadc_i = 0; pdg < pdcurves; pdg++) {
-               pdadc_tmp = ah->ah_txpower.tmpL[pdg];
-
-               if (pdg == pdcurves - 1)
-                       /* 2 dB boundary stretch for last
-                        * (higher power) curve */
-                       gain_boundaries[pdg] = pwr_max[pdg] + 4;
-               else
-                       /* Set gain boundary in the middle
-                        * between this curve and the next one */
-                       gain_boundaries[pdg] =
-                               (pwr_max[pdg] + pwr_min[pdg + 1]) / 2;
-
-               /* Sanity check in case our 2 db stretch got out of
-                * range. */
-               if (gain_boundaries[pdg] > AR5K_TUNE_MAX_TXPOWER)
-                       gain_boundaries[pdg] = AR5K_TUNE_MAX_TXPOWER;
-
-               /* For the first curve (lower power)
-                * start from 0 dB */
-               if (pdg == 0)
-                       pdadc_0 = 0;
-               else
-                       /* For the other curves use the gain overlap */
-                       pdadc_0 = (gain_boundaries[pdg - 1] - pwr_min[pdg]) -
-                                                       pd_gain_overlap;
-
-               /* Force each power step to be at least 0.5 dB */
-               if ((pdadc_tmp[1] - pdadc_tmp[0]) > 1)
-                       pwr_step = pdadc_tmp[1] - pdadc_tmp[0];
-               else
-                       pwr_step = 1;
-
-               /* If pdadc_0 is negative, we need to extrapolate
-                * below this pdgain by a number of pwr_steps */
-               while ((pdadc_0 < 0) && (pdadc_i < 128)) {
-                       s16 tmp = pdadc_tmp[0] + pdadc_0 * pwr_step;
-                       pdadc_out[pdadc_i++] = (tmp < 0) ? 0 : (u8) tmp;
-                       pdadc_0++;
-               }
-
-               /* Set last pwr level, using gain boundaries */
-               pdadc_n = gain_boundaries[pdg] + pd_gain_overlap - pwr_min[pdg];
-               /* Limit it to be inside pwr range */
-               table_size = pwr_max[pdg] - pwr_min[pdg];
-               max_idx = (pdadc_n < table_size) ? pdadc_n : table_size;
-
-               /* Fill pdadc_out table */
-               while (pdadc_0 < max_idx)
-                       pdadc_out[pdadc_i++] = pdadc_tmp[pdadc_0++];
-
-               /* Need to extrapolate above this pdgain? */
-               if (pdadc_n <= max_idx)
-                       continue;
-
-               /* Force each power step to be at least 0.5 dB */
-               if ((pdadc_tmp[table_size - 1] - pdadc_tmp[table_size - 2]) > 1)
-                       pwr_step = pdadc_tmp[table_size - 1] -
-                                               pdadc_tmp[table_size - 2];
-               else
-                       pwr_step = 1;
-
-               /* Extrapolate above */
-               while ((pdadc_0 < (s16) pdadc_n) &&
-               (pdadc_i < AR5K_EEPROM_POWER_TABLE_SIZE * 2)) {
-                       s16 tmp = pdadc_tmp[table_size - 1] +
-                                       (pdadc_0 - max_idx) * pwr_step;
-                       pdadc_out[pdadc_i++] = (tmp > 127) ? 127 : (u8) tmp;
-                       pdadc_0++;
-               }
-       }
-
-       while (pdg < AR5K_EEPROM_N_PD_GAINS) {
-               gain_boundaries[pdg] = gain_boundaries[pdg - 1];
-               pdg++;
-       }
-
-       while (pdadc_i < AR5K_EEPROM_POWER_TABLE_SIZE * 2) {
-               pdadc_out[pdadc_i] = pdadc_out[pdadc_i - 1];
-               pdadc_i++;
-       }
-
-       /* Set gain boundaries */
-       ath5k_hw_reg_write(ah,
-               AR5K_REG_SM(pd_gain_overlap,
-                       AR5K_PHY_TPC_RG5_PD_GAIN_OVERLAP) |
-               AR5K_REG_SM(gain_boundaries[0],
-                       AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_1) |
-               AR5K_REG_SM(gain_boundaries[1],
-                       AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_2) |
-               AR5K_REG_SM(gain_boundaries[2],
-                       AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_3) |
-               AR5K_REG_SM(gain_boundaries[3],
-                       AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_4),
-               AR5K_PHY_TPC_RG5);
-
-       /* Used for setting rate power table */
-       ah->ah_txpower.txp_min_idx = pwr_min[0];
-
-}
-
-/* Write PDADC values on hw */
-static void
-ath5k_setup_pwr_to_pdadc_table(struct ath5k_hw *ah,
-                       u8 pdcurves, u8 *pdg_to_idx)
-{
-       u8 *pdadc_out = ah->ah_txpower.txp_pd_table;
-       u32 reg;
-       u8 i;
-
-       /* Select the right pdgain curves */
-
-       /* Clear current settings */
-       reg = ath5k_hw_reg_read(ah, AR5K_PHY_TPC_RG1);
-       reg &= ~(AR5K_PHY_TPC_RG1_PDGAIN_1 |
-               AR5K_PHY_TPC_RG1_PDGAIN_2 |
-               AR5K_PHY_TPC_RG1_PDGAIN_3 |
-               AR5K_PHY_TPC_RG1_NUM_PD_GAIN);
-
-       /*
-        * Use pd_gains curve from eeprom
-        *
-        * This overrides the default setting from initvals
-        * in case some vendors (e.g. Zcomax) don't use the default
-        * curves. If we don't honor their settings we 'll get a
-        * 5dB (1 * gain overlap ?) drop.
-        */
-       reg |= AR5K_REG_SM(pdcurves, AR5K_PHY_TPC_RG1_NUM_PD_GAIN);
-
-       switch (pdcurves) {
-       case 3:
-               reg |= AR5K_REG_SM(pdg_to_idx[2], AR5K_PHY_TPC_RG1_PDGAIN_3);
-               /* Fall through */
-       case 2:
-               reg |= AR5K_REG_SM(pdg_to_idx[1], AR5K_PHY_TPC_RG1_PDGAIN_2);
-               /* Fall through */
-       case 1:
-               reg |= AR5K_REG_SM(pdg_to_idx[0], AR5K_PHY_TPC_RG1_PDGAIN_1);
-               break;
-       }
-       ath5k_hw_reg_write(ah, reg, AR5K_PHY_TPC_RG1);
-
-       /*
-        * Write TX power values
-        */
-       for (i = 0; i < (AR5K_EEPROM_POWER_TABLE_SIZE / 2); i++) {
-               ath5k_hw_reg_write(ah,
-                       ((pdadc_out[4*i + 0] & 0xff) << 0) |
-                       ((pdadc_out[4*i + 1] & 0xff) << 8) |
-                       ((pdadc_out[4*i + 2] & 0xff) << 16) |
-                       ((pdadc_out[4*i + 3] & 0xff) << 24),
-                       AR5K_PHY_PDADC_TXPOWER(i));
-       }
-}
-
-
-/*
- * Common code for PCDAC/PDADC tables
- */
-
-/*
- * This is the main function that uses all of the above
- * to set PCDAC/PDADC table on hw for the current channel.
- * This table is used for tx power calibration on the basband,
- * without it we get weird tx power levels and in some cases
- * distorted spectral mask
- */
-static int
-ath5k_setup_channel_powertable(struct ath5k_hw *ah,
-                       struct ieee80211_channel *channel,
-                       u8 ee_mode, u8 type)
-{
-       struct ath5k_pdgain_info *pdg_L, *pdg_R;
-       struct ath5k_chan_pcal_info *pcinfo_L;
-       struct ath5k_chan_pcal_info *pcinfo_R;
-       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
-       u8 *pdg_curve_to_idx = ee->ee_pdc_to_idx[ee_mode];
-       s16 table_min[AR5K_EEPROM_N_PD_GAINS];
-       s16 table_max[AR5K_EEPROM_N_PD_GAINS];
-       u8 *tmpL;
-       u8 *tmpR;
-       u32 target = channel->center_freq;
-       int pdg, i;
-
-       /* Get surounding freq piers for this channel */
-       ath5k_get_chan_pcal_surrounding_piers(ah, channel,
-                                               &pcinfo_L,
-                                               &pcinfo_R);
-
-       /* Loop over pd gain curves on
-        * surounding freq piers by index */
-       for (pdg = 0; pdg < ee->ee_pd_gains[ee_mode]; pdg++) {
-
-               /* Fill curves in reverse order
-                * from lower power (max gain)
-                * to higher power. Use curve -> idx
-                * backmaping we did on eeprom init */
-               u8 idx = pdg_curve_to_idx[pdg];
-
-               /* Grab the needed curves by index */
-               pdg_L = &pcinfo_L->pd_curves[idx];
-               pdg_R = &pcinfo_R->pd_curves[idx];
-
-               /* Initialize the temp tables */
-               tmpL = ah->ah_txpower.tmpL[pdg];
-               tmpR = ah->ah_txpower.tmpR[pdg];
-
-               /* Set curve's x boundaries and create
-                * curves so that they cover the same
-                * range (if we don't do that one table
-                * will have values on some range and the
-                * other one won't have any so interpolation
-                * will fail) */
-               table_min[pdg] = min(pdg_L->pd_pwr[0],
-                                       pdg_R->pd_pwr[0]) / 2;
-
-               table_max[pdg] = max(pdg_L->pd_pwr[pdg_L->pd_points - 1],
-                               pdg_R->pd_pwr[pdg_R->pd_points - 1]) / 2;
-
-               /* Now create the curves on surrounding channels
-                * and interpolate if needed to get the final
-                * curve for this gain on this channel */
-               switch (type) {
-               case AR5K_PWRTABLE_LINEAR_PCDAC:
-                       /* Override min/max so that we don't loose
-                        * accuracy (don't divide by 2) */
-                       table_min[pdg] = min(pdg_L->pd_pwr[0],
-                                               pdg_R->pd_pwr[0]);
-
-                       table_max[pdg] =
-                               max(pdg_L->pd_pwr[pdg_L->pd_points - 1],
-                                       pdg_R->pd_pwr[pdg_R->pd_points - 1]);
-
-                       /* Override minimum so that we don't get
-                        * out of bounds while extrapolating
-                        * below. Don't do this when we have 2
-                        * curves and we are on the high power curve
-                        * because table_min is ok in this case */
-                       if (!(ee->ee_pd_gains[ee_mode] > 1 && pdg == 0)) {
-
-                               table_min[pdg] =
-                                       ath5k_get_linear_pcdac_min(pdg_L->pd_step,
-                                                               pdg_R->pd_step,
-                                                               pdg_L->pd_pwr,
-                                                               pdg_R->pd_pwr);
-
-                               /* Don't go too low because we will
-                                * miss the upper part of the curve.
-                                * Note: 126 = 31.5dB (max power supported)
-                                * in 0.25dB units */
-                               if (table_max[pdg] - table_min[pdg] > 126)
-                                       table_min[pdg] = table_max[pdg] - 126;
-                       }
-
-                       /* Fall through */
-               case AR5K_PWRTABLE_PWR_TO_PCDAC:
-               case AR5K_PWRTABLE_PWR_TO_PDADC:
-
-                       ath5k_create_power_curve(table_min[pdg],
-                                               table_max[pdg],
-                                               pdg_L->pd_pwr,
-                                               pdg_L->pd_step,
-                                               pdg_L->pd_points, tmpL, type);
-
-                       /* We are in a calibration
-                        * pier, no need to interpolate
-                        * between freq piers */
-                       if (pcinfo_L == pcinfo_R)
-                               continue;
-
-                       ath5k_create_power_curve(table_min[pdg],
-                                               table_max[pdg],
-                                               pdg_R->pd_pwr,
-                                               pdg_R->pd_step,
-                                               pdg_R->pd_points, tmpR, type);
-                       break;
-               default:
-                       return -EINVAL;
-               }
-
-               /* Interpolate between curves
-                * of surounding freq piers to
-                * get the final curve for this
-                * pd gain. Re-use tmpL for interpolation
-                * output */
-               for (i = 0; (i < (u16) (table_max[pdg] - table_min[pdg])) &&
-               (i < AR5K_EEPROM_POWER_TABLE_SIZE); i++) {
-                       tmpL[i] = (u8) ath5k_get_interpolated_value(target,
-                                                       (s16) pcinfo_L->freq,
-                                                       (s16) pcinfo_R->freq,
-                                                       (s16) tmpL[i],
-                                                       (s16) tmpR[i]);
-               }
-       }
-
-       /* Now we have a set of curves for this
-        * channel on tmpL (x range is table_max - table_min
-        * and y values are tmpL[pdg][]) sorted in the same
-        * order as EEPROM (because we've used the backmaping).
-        * So for RF5112 it's from higher power to lower power
-        * and for RF2413 it's from lower power to higher power.
-        * For RF5111 we only have one curve. */
-
-       /* Fill min and max power levels for this
-        * channel by interpolating the values on
-        * surounding channels to complete the dataset */
-       ah->ah_txpower.txp_min_pwr = ath5k_get_interpolated_value(target,
-                                       (s16) pcinfo_L->freq,
-                                       (s16) pcinfo_R->freq,
-                                       pcinfo_L->min_pwr, pcinfo_R->min_pwr);
-
-       ah->ah_txpower.txp_max_pwr = ath5k_get_interpolated_value(target,
-                                       (s16) pcinfo_L->freq,
-                                       (s16) pcinfo_R->freq,
-                                       pcinfo_L->max_pwr, pcinfo_R->max_pwr);
-
-       /* We are ready to go, fill PCDAC/PDADC
-        * table and write settings on hardware */
-       switch (type) {
-       case AR5K_PWRTABLE_LINEAR_PCDAC:
-               /* For RF5112 we can have one or two curves
-                * and each curve covers a certain power lvl
-                * range so we need to do some more processing */
-               ath5k_combine_linear_pcdac_curves(ah, table_min, table_max,
-                                               ee->ee_pd_gains[ee_mode]);
-
-               /* Set txp.offset so that we can
-                * match max power value with max
-                * table index */
-               ah->ah_txpower.txp_offset = 64 - (table_max[0] / 2);
-
-               /* Write settings on hw */
-               ath5k_setup_pcdac_table(ah);
-               break;
-       case AR5K_PWRTABLE_PWR_TO_PCDAC:
-               /* We are done for RF5111 since it has only
-                * one curve, just fit the curve on the table */
-               ath5k_fill_pwr_to_pcdac_table(ah, table_min, table_max);
-
-               /* No rate powertable adjustment for RF5111 */
-               ah->ah_txpower.txp_min_idx = 0;
-               ah->ah_txpower.txp_offset = 0;
-
-               /* Write settings on hw */
-               ath5k_setup_pcdac_table(ah);
-               break;
-       case AR5K_PWRTABLE_PWR_TO_PDADC:
-               /* Set PDADC boundaries and fill
-                * final PDADC table */
-               ath5k_combine_pwr_to_pdadc_curves(ah, table_min, table_max,
-                                               ee->ee_pd_gains[ee_mode]);
-
-               /* Write settings on hw */
-               ath5k_setup_pwr_to_pdadc_table(ah, pdg, pdg_curve_to_idx);
-
-               /* Set txp.offset, note that table_min
-                * can be negative */
-               ah->ah_txpower.txp_offset = table_min[0];
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-
-/*
- * Per-rate tx power setting
- *
- * This is the code that sets the desired tx power (below
- * maximum) on hw for each rate (we also have TPC that sets
- * power per packet). We do that by providing an index on the
- * PCDAC/PDADC table we set up.
- */
-
-/*
- * Set rate power table
- *
- * For now we only limit txpower based on maximum tx power
- * supported by hw (what's inside rate_info). We need to limit
- * this even more, based on regulatory domain etc.
- *
- * Rate power table contains indices to PCDAC/PDADC table (0.5dB steps)
- * and is indexed as follows:
- * rates[0] - rates[7] -> OFDM rates
- * rates[8] - rates[14] -> CCK rates
- * rates[15] -> XR rates (they all have the same power)
- */
-static void
-ath5k_setup_rate_powertable(struct ath5k_hw *ah, u16 max_pwr,
-                       struct ath5k_rate_pcal_info *rate_info,
-                       u8 ee_mode)
-{
-       unsigned int i;
-       u16 *rates;
-
-       /* max_pwr is power level we got from driver/user in 0.5dB
-        * units, switch to 0.25dB units so we can compare */
-       max_pwr *= 2;
-       max_pwr = min(max_pwr, (u16) ah->ah_txpower.txp_max_pwr) / 2;
-
-       /* apply rate limits */
-       rates = ah->ah_txpower.txp_rates_power_table;
-
-       /* OFDM rates 6 to 24Mb/s */
-       for (i = 0; i < 5; i++)
-               rates[i] = min(max_pwr, rate_info->target_power_6to24);
-
-       /* Rest OFDM rates */
-       rates[5] = min(rates[0], rate_info->target_power_36);
-       rates[6] = min(rates[0], rate_info->target_power_48);
-       rates[7] = min(rates[0], rate_info->target_power_54);
-
-       /* CCK rates */
-       /* 1L */
-       rates[8] = min(rates[0], rate_info->target_power_6to24);
-       /* 2L */
-       rates[9] = min(rates[0], rate_info->target_power_36);
-       /* 2S */
-       rates[10] = min(rates[0], rate_info->target_power_36);
-       /* 5L */
-       rates[11] = min(rates[0], rate_info->target_power_48);
-       /* 5S */
-       rates[12] = min(rates[0], rate_info->target_power_48);
-       /* 11L */
-       rates[13] = min(rates[0], rate_info->target_power_54);
-       /* 11S */
-       rates[14] = min(rates[0], rate_info->target_power_54);
-
-       /* XR rates */
-       rates[15] = min(rates[0], rate_info->target_power_6to24);
-
-       /* CCK rates have different peak to average ratio
-        * so we have to tweak their power so that gainf
-        * correction works ok. For this we use OFDM to
-        * CCK delta from eeprom */
-       if ((ee_mode == AR5K_EEPROM_MODE_11G) &&
-       (ah->ah_phy_revision < AR5K_SREV_PHY_5212A))
-               for (i = 8; i <= 15; i++)
-                       rates[i] -= ah->ah_txpower.txp_cck_ofdm_gainf_delta;
-
-       ah->ah_txpower.txp_min_pwr = rates[7];
-       ah->ah_txpower.txp_max_pwr = rates[0];
-       ah->ah_txpower.txp_ofdm = rates[7];
-}
-
-
-/*
- * Set transmition power
- */
-int
-ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
-               u8 ee_mode, u8 txpower)
-{
-       struct ath5k_rate_pcal_info rate_info;
-       u8 type;
-       int ret;
-
-       ATH5K_TRACE(ah->ah_sc);
-       if (txpower > AR5K_TUNE_MAX_TXPOWER) {
-               ATH5K_ERR(ah->ah_sc, "invalid tx power: %u\n", txpower);
-               return -EINVAL;
-       }
-       if (txpower == 0)
-               txpower = AR5K_TUNE_DEFAULT_TXPOWER;
-
-       /* Reset TX power values */
-       memset(&ah->ah_txpower, 0, sizeof(ah->ah_txpower));
-       ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER;
-       ah->ah_txpower.txp_min_pwr = 0;
-       ah->ah_txpower.txp_max_pwr = AR5K_TUNE_MAX_TXPOWER;
-
-       /* Initialize TX power table */
-       switch (ah->ah_radio) {
-       case AR5K_RF5111:
-               type = AR5K_PWRTABLE_PWR_TO_PCDAC;
-               break;
-       case AR5K_RF5112:
-               type = AR5K_PWRTABLE_LINEAR_PCDAC;
-               break;
-       case AR5K_RF2413:
-       case AR5K_RF5413:
-       case AR5K_RF2316:
-       case AR5K_RF2317:
-       case AR5K_RF2425:
-               type = AR5K_PWRTABLE_PWR_TO_PDADC;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       /* FIXME: Only on channel/mode change */
-       ret = ath5k_setup_channel_powertable(ah, channel, ee_mode, type);
-       if (ret)
-               return ret;
-
-       /* Limit max power if we have a CTL available */
-       ath5k_get_max_ctl_power(ah, channel);
-
-       /* FIXME: Tx power limit for this regdomain
-        * XXX: Mac80211/CRDA will do that anyway ? */
-
-       /* FIXME: Antenna reduction stuff */
-
-       /* FIXME: Limit power on turbo modes */
-
-       /* FIXME: TPC scale reduction */
-
-       /* Get surounding channels for per-rate power table
-        * calibration */
-       ath5k_get_rate_pcal_data(ah, channel, &rate_info);
-
-       /* Setup rate power table */
-       ath5k_setup_rate_powertable(ah, txpower, &rate_info, ee_mode);
-
-       /* Write rate power table on hw */
-       ath5k_hw_reg_write(ah, AR5K_TXPOWER_OFDM(3, 24) |
-               AR5K_TXPOWER_OFDM(2, 16) | AR5K_TXPOWER_OFDM(1, 8) |
-               AR5K_TXPOWER_OFDM(0, 0), AR5K_PHY_TXPOWER_RATE1);
-
-       ath5k_hw_reg_write(ah, AR5K_TXPOWER_OFDM(7, 24) |
-               AR5K_TXPOWER_OFDM(6, 16) | AR5K_TXPOWER_OFDM(5, 8) |
-               AR5K_TXPOWER_OFDM(4, 0), AR5K_PHY_TXPOWER_RATE2);
-
-       ath5k_hw_reg_write(ah, AR5K_TXPOWER_CCK(10, 24) |
-               AR5K_TXPOWER_CCK(9, 16) | AR5K_TXPOWER_CCK(15, 8) |
-               AR5K_TXPOWER_CCK(8, 0), AR5K_PHY_TXPOWER_RATE3);
-
-       ath5k_hw_reg_write(ah, AR5K_TXPOWER_CCK(14, 24) |
-               AR5K_TXPOWER_CCK(13, 16) | AR5K_TXPOWER_CCK(12, 8) |
-               AR5K_TXPOWER_CCK(11, 0), AR5K_PHY_TXPOWER_RATE4);
-
-       /* FIXME: TPC support */
-       if (ah->ah_txpower.txp_tpc) {
-               ath5k_hw_reg_write(ah, AR5K_PHY_TXPOWER_RATE_MAX_TPC_ENABLE |
-                       AR5K_TUNE_MAX_TXPOWER, AR5K_PHY_TXPOWER_RATE_MAX);
-
-               ath5k_hw_reg_write(ah,
-                       AR5K_REG_MS(AR5K_TUNE_MAX_TXPOWER, AR5K_TPC_ACK) |
-                       AR5K_REG_MS(AR5K_TUNE_MAX_TXPOWER, AR5K_TPC_CTS) |
-                       AR5K_REG_MS(AR5K_TUNE_MAX_TXPOWER, AR5K_TPC_CHIRP),
-                       AR5K_TPC);
-       } else {
-               ath5k_hw_reg_write(ah, AR5K_PHY_TXPOWER_RATE_MAX |
-                       AR5K_TUNE_MAX_TXPOWER, AR5K_PHY_TXPOWER_RATE_MAX);
-       }
-
-       return 0;
-}
-
-int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 mode, u8 txpower)
-{
-       /*Just a try M.F.*/
-       struct ieee80211_channel *channel = &ah->ah_current_channel;
-
-       ATH5K_TRACE(ah->ah_sc);
-       ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_TXPOWER,
-               "changing txpower to %d\n", txpower);
-
-       return ath5k_hw_txpower(ah, channel, mode, txpower);
-}
-
-#undef _ATH5K_PHY
diff --git a/drivers/net/wireless/ath5k/qcu.c b/drivers/net/wireless/ath5k/qcu.c
deleted file mode 100644 (file)
index 5094c39..0000000
+++ /dev/null
@@ -1,546 +0,0 @@
-/*
- * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
- * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
- *
- * Permission to use, copy, modify, and 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.
- *
- */
-
-/********************************************\
-Queue Control Unit, DFS Control Unit Functions
-\********************************************/
-
-#include "ath5k.h"
-#include "reg.h"
-#include "debug.h"
-#include "base.h"
-
-/*
- * Get properties for a transmit queue
- */
-int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue,
-               struct ath5k_txq_info *queue_info)
-{
-       ATH5K_TRACE(ah->ah_sc);
-       memcpy(queue_info, &ah->ah_txq[queue], sizeof(struct ath5k_txq_info));
-       return 0;
-}
-
-/*
- * Set properties for a transmit queue
- */
-int ath5k_hw_set_tx_queueprops(struct ath5k_hw *ah, int queue,
-                               const struct ath5k_txq_info *queue_info)
-{
-       ATH5K_TRACE(ah->ah_sc);
-       AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
-
-       if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
-               return -EIO;
-
-       memcpy(&ah->ah_txq[queue], queue_info, sizeof(struct ath5k_txq_info));
-
-       /*XXX: Is this supported on 5210 ?*/
-       if ((queue_info->tqi_type == AR5K_TX_QUEUE_DATA &&
-                       ((queue_info->tqi_subtype == AR5K_WME_AC_VI) ||
-                       (queue_info->tqi_subtype == AR5K_WME_AC_VO))) ||
-                       queue_info->tqi_type == AR5K_TX_QUEUE_UAPSD)
-               ah->ah_txq[queue].tqi_flags |= AR5K_TXQ_FLAG_POST_FR_BKOFF_DIS;
-
-       return 0;
-}
-
-/*
- * Initialize a transmit queue
- */
-int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, enum ath5k_tx_queue queue_type,
-               struct ath5k_txq_info *queue_info)
-{
-       unsigned int queue;
-       int ret;
-
-       ATH5K_TRACE(ah->ah_sc);
-
-       /*
-        * Get queue by type
-        */
-       /*5210 only has 2 queues*/
-       if (ah->ah_version == AR5K_AR5210) {
-               switch (queue_type) {
-               case AR5K_TX_QUEUE_DATA:
-                       queue = AR5K_TX_QUEUE_ID_NOQCU_DATA;
-                       break;
-               case AR5K_TX_QUEUE_BEACON:
-               case AR5K_TX_QUEUE_CAB:
-                       queue = AR5K_TX_QUEUE_ID_NOQCU_BEACON;
-                       break;
-               default:
-                       return -EINVAL;
-               }
-       } else {
-               switch (queue_type) {
-               case AR5K_TX_QUEUE_DATA:
-                       for (queue = AR5K_TX_QUEUE_ID_DATA_MIN;
-                               ah->ah_txq[queue].tqi_type !=
-                               AR5K_TX_QUEUE_INACTIVE; queue++) {
-
-                               if (queue > AR5K_TX_QUEUE_ID_DATA_MAX)
-                                       return -EINVAL;
-                       }
-                       break;
-               case AR5K_TX_QUEUE_UAPSD:
-                       queue = AR5K_TX_QUEUE_ID_UAPSD;
-                       break;
-               case AR5K_TX_QUEUE_BEACON:
-                       queue = AR5K_TX_QUEUE_ID_BEACON;
-                       break;
-               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->ah_sc,
-                                       "XR data queues only supported in"
-                                       " 5212!\n");
-                       queue = AR5K_TX_QUEUE_ID_XR_DATA;
-                       break;
-               default:
-                       return -EINVAL;
-               }
-       }
-
-       /*
-        * Setup internal queue structure
-        */
-       memset(&ah->ah_txq[queue], 0, sizeof(struct ath5k_txq_info));
-       ah->ah_txq[queue].tqi_type = queue_type;
-
-       if (queue_info != NULL) {
-               queue_info->tqi_type = queue_type;
-               ret = ath5k_hw_set_tx_queueprops(ah, queue, queue_info);
-               if (ret)
-                       return ret;
-       }
-
-       /*
-        * We use ah_txq_status to hold a temp value for
-        * the Secondary interrupt mask registers on 5211+
-        * check out ath5k_hw_reset_tx_queue
-        */
-       AR5K_Q_ENABLE_BITS(ah->ah_txq_status, queue);
-
-       return queue;
-}
-
-/*
- * Get number of pending frames
- * for a specific queue [5211+]
- */
-u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue)
-{
-       u32 pending;
-       ATH5K_TRACE(ah->ah_sc);
-       AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
-
-       /* Return if queue is declared inactive */
-       if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
-               return false;
-
-       /* XXX: How about AR5K_CFG_TXCNT ? */
-       if (ah->ah_version == AR5K_AR5210)
-               return false;
-
-       pending = (AR5K_QUEUE_STATUS(queue) & AR5K_QCU_STS_FRMPENDCNT);
-
-       /* It's possible to have no frames pending even if TXE
-        * is set. To indicate that q has not stopped return
-        * true */
-       if (!pending && AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, queue))
-               return true;
-
-       return pending;
-}
-
-/*
- * Set a transmit queue inactive
- */
-void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue)
-{
-       ATH5K_TRACE(ah->ah_sc);
-       if (WARN_ON(queue >= ah->ah_capabilities.cap_queues.q_tx_num))
-               return;
-
-       /* This queue will be skipped in further operations */
-       ah->ah_txq[queue].tqi_type = AR5K_TX_QUEUE_INACTIVE;
-       /*For SIMR setup*/
-       AR5K_Q_DISABLE_BITS(ah->ah_txq_status, queue);
-}
-
-/*
- * Set DFS properties for a transmit queue on DCU
- */
-int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
-{
-       u32 cw_min, cw_max, retry_lg, retry_sh;
-       struct ath5k_txq_info *tq = &ah->ah_txq[queue];
-
-       ATH5K_TRACE(ah->ah_sc);
-       AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
-
-       tq = &ah->ah_txq[queue];
-
-       if (tq->tqi_type == AR5K_TX_QUEUE_INACTIVE)
-               return 0;
-
-       if (ah->ah_version == AR5K_AR5210) {
-               /* Only handle data queues, others will be ignored */
-               if (tq->tqi_type != AR5K_TX_QUEUE_DATA)
-                       return 0;
-
-               /* Set Slot time */
-               ath5k_hw_reg_write(ah, ah->ah_turbo ?
-                       AR5K_INIT_SLOT_TIME_TURBO : AR5K_INIT_SLOT_TIME,
-                       AR5K_SLOT_TIME);
-               /* Set ACK_CTS timeout */
-               ath5k_hw_reg_write(ah, ah->ah_turbo ?
-                       AR5K_INIT_ACK_CTS_TIMEOUT_TURBO :
-                       AR5K_INIT_ACK_CTS_TIMEOUT, AR5K_SLOT_TIME);
-               /* Set Transmit Latency */
-               ath5k_hw_reg_write(ah, ah->ah_turbo ?
-                       AR5K_INIT_TRANSMIT_LATENCY_TURBO :
-                       AR5K_INIT_TRANSMIT_LATENCY, AR5K_USEC_5210);
-
-               /* Set IFS0 */
-               if (ah->ah_turbo) {
-                        ath5k_hw_reg_write(ah, ((AR5K_INIT_SIFS_TURBO +
-                               (ah->ah_aifs + tq->tqi_aifs) *
-                               AR5K_INIT_SLOT_TIME_TURBO) <<
-                               AR5K_IFS0_DIFS_S) | AR5K_INIT_SIFS_TURBO,
-                               AR5K_IFS0);
-               } else {
-                       ath5k_hw_reg_write(ah, ((AR5K_INIT_SIFS +
-                               (ah->ah_aifs + tq->tqi_aifs) *
-                               AR5K_INIT_SLOT_TIME) << AR5K_IFS0_DIFS_S) |
-                               AR5K_INIT_SIFS, AR5K_IFS0);
-               }
-
-               /* Set IFS1 */
-               ath5k_hw_reg_write(ah, ah->ah_turbo ?
-                       AR5K_INIT_PROTO_TIME_CNTRL_TURBO :
-                       AR5K_INIT_PROTO_TIME_CNTRL, AR5K_IFS1);
-               /* Set AR5K_PHY_SETTLING */
-               ath5k_hw_reg_write(ah, ah->ah_turbo ?
-                       (ath5k_hw_reg_read(ah, AR5K_PHY_SETTLING) & ~0x7F)
-                       | 0x38 :
-                       (ath5k_hw_reg_read(ah, AR5K_PHY_SETTLING) & ~0x7F)
-                       | 0x1C,
-                       AR5K_PHY_SETTLING);
-               /* Set Frame Control Register */
-               ath5k_hw_reg_write(ah, ah->ah_turbo ?
-                       (AR5K_PHY_FRAME_CTL_INI | AR5K_PHY_TURBO_MODE |
-                       AR5K_PHY_TURBO_SHORT | 0x2020) :
-                       (AR5K_PHY_FRAME_CTL_INI | 0x1020),
-                       AR5K_PHY_FRAME_CTL_5210);
-       }
-
-       /*
-        * Calculate cwmin/max by channel mode
-        */
-       cw_min = ah->ah_cw_min = AR5K_TUNE_CWMIN;
-       cw_max = ah->ah_cw_max = AR5K_TUNE_CWMAX;
-       ah->ah_aifs = AR5K_TUNE_AIFS;
-       /*XR is only supported on 5212*/
-       if (IS_CHAN_XR(ah->ah_current_channel) &&
-                       ah->ah_version == AR5K_AR5212) {
-               cw_min = ah->ah_cw_min = AR5K_TUNE_CWMIN_XR;
-               cw_max = ah->ah_cw_max = AR5K_TUNE_CWMAX_XR;
-               ah->ah_aifs = AR5K_TUNE_AIFS_XR;
-       /*B mode is not supported on 5210*/
-       } else if (IS_CHAN_B(ah->ah_current_channel) &&
-                       ah->ah_version != AR5K_AR5210) {
-               cw_min = ah->ah_cw_min = AR5K_TUNE_CWMIN_11B;
-               cw_max = ah->ah_cw_max = AR5K_TUNE_CWMAX_11B;
-               ah->ah_aifs = AR5K_TUNE_AIFS_11B;
-       }
-
-       cw_min = 1;
-       while (cw_min < ah->ah_cw_min)
-               cw_min = (cw_min << 1) | 1;
-
-       cw_min = tq->tqi_cw_min < 0 ? (cw_min >> (-tq->tqi_cw_min)) :
-               ((cw_min << tq->tqi_cw_min) + (1 << tq->tqi_cw_min) - 1);
-       cw_max = tq->tqi_cw_max < 0 ? (cw_max >> (-tq->tqi_cw_max)) :
-               ((cw_max << tq->tqi_cw_max) + (1 << tq->tqi_cw_max) - 1);
-
-       /*
-        * Calculate and set retry limits
-        */
-       if (ah->ah_software_retry) {
-               /* XXX Need to test this */
-               retry_lg = ah->ah_limit_tx_retries;
-               retry_sh = retry_lg = retry_lg > AR5K_DCU_RETRY_LMT_SH_RETRY ?
-                       AR5K_DCU_RETRY_LMT_SH_RETRY : retry_lg;
-       } else {
-               retry_lg = AR5K_INIT_LG_RETRY;
-               retry_sh = AR5K_INIT_SH_RETRY;
-       }
-
-       /*No QCU/DCU [5210]*/
-       if (ah->ah_version == AR5K_AR5210) {
-               ath5k_hw_reg_write(ah,
-                       (cw_min << AR5K_NODCU_RETRY_LMT_CW_MIN_S)
-                       | AR5K_REG_SM(AR5K_INIT_SLG_RETRY,
-                               AR5K_NODCU_RETRY_LMT_SLG_RETRY)
-                       | AR5K_REG_SM(AR5K_INIT_SSH_RETRY,
-                               AR5K_NODCU_RETRY_LMT_SSH_RETRY)
-                       | AR5K_REG_SM(retry_lg, AR5K_NODCU_RETRY_LMT_LG_RETRY)
-                       | AR5K_REG_SM(retry_sh, AR5K_NODCU_RETRY_LMT_SH_RETRY),
-                       AR5K_NODCU_RETRY_LMT);
-       } else {
-               /*QCU/DCU [5211+]*/
-               ath5k_hw_reg_write(ah,
-                       AR5K_REG_SM(AR5K_INIT_SLG_RETRY,
-                               AR5K_DCU_RETRY_LMT_SLG_RETRY) |
-                       AR5K_REG_SM(AR5K_INIT_SSH_RETRY,
-                               AR5K_DCU_RETRY_LMT_SSH_RETRY) |
-                       AR5K_REG_SM(retry_lg, AR5K_DCU_RETRY_LMT_LG_RETRY) |
-                       AR5K_REG_SM(retry_sh, AR5K_DCU_RETRY_LMT_SH_RETRY),
-                       AR5K_QUEUE_DFS_RETRY_LIMIT(queue));
-
-       /*===Rest is also for QCU/DCU only [5211+]===*/
-
-               /*
-                * Set initial content window (cw_min/cw_max)
-                * and arbitrated interframe space (aifs)...
-                */
-               ath5k_hw_reg_write(ah,
-                       AR5K_REG_SM(cw_min, AR5K_DCU_LCL_IFS_CW_MIN) |
-                       AR5K_REG_SM(cw_max, AR5K_DCU_LCL_IFS_CW_MAX) |
-                       AR5K_REG_SM(ah->ah_aifs + tq->tqi_aifs,
-                               AR5K_DCU_LCL_IFS_AIFS),
-                       AR5K_QUEUE_DFS_LOCAL_IFS(queue));
-
-               /*
-                * Set misc registers
-                */
-               /* Enable DCU early termination for this queue */
-               AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
-                                       AR5K_QCU_MISC_DCU_EARLY);
-
-               /* Enable DCU to wait for next fragment from QCU */
-               AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
-                                       AR5K_DCU_MISC_FRAG_WAIT);
-
-               /* On Maui and Spirit use the global seqnum on DCU */
-               if (ah->ah_mac_version < AR5K_SREV_AR5211)
-                       AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
-                                               AR5K_DCU_MISC_SEQNUM_CTL);
-
-               if (tq->tqi_cbr_period) {
-                       ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_cbr_period,
-                               AR5K_QCU_CBRCFG_INTVAL) |
-                               AR5K_REG_SM(tq->tqi_cbr_overflow_limit,
-                               AR5K_QCU_CBRCFG_ORN_THRES),
-                               AR5K_QUEUE_CBRCFG(queue));
-                       AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
-                               AR5K_QCU_MISC_FRSHED_CBR);
-                       if (tq->tqi_cbr_overflow_limit)
-                               AR5K_REG_ENABLE_BITS(ah,
-                                       AR5K_QUEUE_MISC(queue),
-                                       AR5K_QCU_MISC_CBR_THRES_ENABLE);
-               }
-
-               if (tq->tqi_ready_time &&
-               (tq->tqi_type != AR5K_TX_QUEUE_ID_CAB))
-                       ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_ready_time,
-                               AR5K_QCU_RDYTIMECFG_INTVAL) |
-                               AR5K_QCU_RDYTIMECFG_ENABLE,
-                               AR5K_QUEUE_RDYTIMECFG(queue));
-
-               if (tq->tqi_burst_time) {
-                       ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_burst_time,
-                               AR5K_DCU_CHAN_TIME_DUR) |
-                               AR5K_DCU_CHAN_TIME_ENABLE,
-                               AR5K_QUEUE_DFS_CHANNEL_TIME(queue));
-
-                       if (tq->tqi_flags
-                       & AR5K_TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE)
-                               AR5K_REG_ENABLE_BITS(ah,
-                                       AR5K_QUEUE_MISC(queue),
-                                       AR5K_QCU_MISC_RDY_VEOL_POLICY);
-               }
-
-               if (tq->tqi_flags & AR5K_TXQ_FLAG_BACKOFF_DISABLE)
-                       ath5k_hw_reg_write(ah, AR5K_DCU_MISC_POST_FR_BKOFF_DIS,
-                               AR5K_QUEUE_DFS_MISC(queue));
-
-               if (tq->tqi_flags & AR5K_TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE)
-                       ath5k_hw_reg_write(ah, AR5K_DCU_MISC_BACKOFF_FRAG,
-                               AR5K_QUEUE_DFS_MISC(queue));
-
-               /*
-                * Set registers by queue type
-                */
-               switch (tq->tqi_type) {
-               case AR5K_TX_QUEUE_BEACON:
-                       AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
-                               AR5K_QCU_MISC_FRSHED_DBA_GT |
-                               AR5K_QCU_MISC_CBREXP_BCN_DIS |
-                               AR5K_QCU_MISC_BCN_ENABLE);
-
-                       AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
-                               (AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL <<
-                               AR5K_DCU_MISC_ARBLOCK_CTL_S) |
-                               AR5K_DCU_MISC_POST_FR_BKOFF_DIS |
-                               AR5K_DCU_MISC_BCN_ENABLE);
-                       break;
-
-               case AR5K_TX_QUEUE_CAB:
-                       AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
-                               AR5K_QCU_MISC_FRSHED_DBA_GT |
-                               AR5K_QCU_MISC_CBREXP_DIS |
-                               AR5K_QCU_MISC_CBREXP_BCN_DIS);
-
-                       ath5k_hw_reg_write(ah, ((AR5K_TUNE_BEACON_INTERVAL -
-                               (AR5K_TUNE_SW_BEACON_RESP -
-                               AR5K_TUNE_DMA_BEACON_RESP) -
-                               AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF) * 1024) |
-                               AR5K_QCU_RDYTIMECFG_ENABLE,
-                               AR5K_QUEUE_RDYTIMECFG(queue));
-
-                       AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
-                               (AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL <<
-                               AR5K_DCU_MISC_ARBLOCK_CTL_S));
-                       break;
-
-               case AR5K_TX_QUEUE_UAPSD:
-                       AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
-                               AR5K_QCU_MISC_CBREXP_DIS);
-                       break;
-
-               case AR5K_TX_QUEUE_DATA:
-               default:
-                       break;
-               }
-
-               /* TODO: Handle frame compression */
-
-               /*
-                * Enable interrupts for this tx queue
-                * in the secondary interrupt mask registers
-                */
-               if (tq->tqi_flags & AR5K_TXQ_FLAG_TXOKINT_ENABLE)
-                       AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txok, queue);
-
-               if (tq->tqi_flags & AR5K_TXQ_FLAG_TXERRINT_ENABLE)
-                       AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txerr, queue);
-
-               if (tq->tqi_flags & AR5K_TXQ_FLAG_TXURNINT_ENABLE)
-                       AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txurn, queue);
-
-               if (tq->tqi_flags & AR5K_TXQ_FLAG_TXDESCINT_ENABLE)
-                       AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txdesc, queue);
-
-               if (tq->tqi_flags & AR5K_TXQ_FLAG_TXEOLINT_ENABLE)
-                       AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txeol, queue);
-
-               if (tq->tqi_flags & AR5K_TXQ_FLAG_CBRORNINT_ENABLE)
-                       AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_cbrorn, queue);
-
-               if (tq->tqi_flags & AR5K_TXQ_FLAG_CBRURNINT_ENABLE)
-                       AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_cbrurn, queue);
-
-               if (tq->tqi_flags & AR5K_TXQ_FLAG_QTRIGINT_ENABLE)
-                       AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_qtrig, queue);
-
-               if (tq->tqi_flags & AR5K_TXQ_FLAG_TXNOFRMINT_ENABLE)
-                       AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_nofrm, queue);
-
-               /* Update secondary interrupt mask registers */
-
-               /* Filter out inactive queues */
-               ah->ah_txq_imr_txok &= ah->ah_txq_status;
-               ah->ah_txq_imr_txerr &= ah->ah_txq_status;
-               ah->ah_txq_imr_txurn &= ah->ah_txq_status;
-               ah->ah_txq_imr_txdesc &= ah->ah_txq_status;
-               ah->ah_txq_imr_txeol &= ah->ah_txq_status;
-               ah->ah_txq_imr_cbrorn &= ah->ah_txq_status;
-               ah->ah_txq_imr_cbrurn &= ah->ah_txq_status;
-               ah->ah_txq_imr_qtrig &= ah->ah_txq_status;
-               ah->ah_txq_imr_nofrm &= ah->ah_txq_status;
-
-               ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txok,
-                       AR5K_SIMR0_QCU_TXOK) |
-                       AR5K_REG_SM(ah->ah_txq_imr_txdesc,
-                       AR5K_SIMR0_QCU_TXDESC), AR5K_SIMR0);
-               ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txerr,
-                       AR5K_SIMR1_QCU_TXERR) |
-                       AR5K_REG_SM(ah->ah_txq_imr_txeol,
-                       AR5K_SIMR1_QCU_TXEOL), AR5K_SIMR1);
-               /* Update simr2 but don't overwrite rest simr2 settings */
-               AR5K_REG_DISABLE_BITS(ah, AR5K_SIMR2, AR5K_SIMR2_QCU_TXURN);
-               AR5K_REG_ENABLE_BITS(ah, AR5K_SIMR2,
-                       AR5K_REG_SM(ah->ah_txq_imr_txurn,
-                       AR5K_SIMR2_QCU_TXURN));
-               ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_cbrorn,
-                       AR5K_SIMR3_QCBRORN) |
-                       AR5K_REG_SM(ah->ah_txq_imr_cbrurn,
-                       AR5K_SIMR3_QCBRURN), AR5K_SIMR3);
-               ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_qtrig,
-                       AR5K_SIMR4_QTRIG), AR5K_SIMR4);
-               /* Set TXNOFRM_QCU for the queues with TXNOFRM enabled */
-               ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_nofrm,
-                       AR5K_TXNOFRM_QCU), AR5K_TXNOFRM);
-               /* No queue has TXNOFRM enabled, disable the interrupt
-                * by setting AR5K_TXNOFRM to zero */
-               if (ah->ah_txq_imr_nofrm == 0)
-                       ath5k_hw_reg_write(ah, 0, AR5K_TXNOFRM);
-
-               /* Set QCU mask for this DCU to save power */
-               AR5K_REG_WRITE_Q(ah, AR5K_QUEUE_QCUMASK(queue), queue);
-       }
-
-       return 0;
-}
-
-/*
- * Get slot time from DCU
- */
-unsigned int ath5k_hw_get_slot_time(struct ath5k_hw *ah)
-{
-       ATH5K_TRACE(ah->ah_sc);
-       if (ah->ah_version == AR5K_AR5210)
-               return ath5k_hw_clocktoh(ath5k_hw_reg_read(ah,
-                               AR5K_SLOT_TIME) & 0xffff, ah->ah_turbo);
-       else
-               return ath5k_hw_reg_read(ah, AR5K_DCU_GBL_IFS_SLOT) & 0xffff;
-}
-
-/*
- * Set slot time on DCU
- */
-int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time)
-{
-       ATH5K_TRACE(ah->ah_sc);
-       if (slot_time < AR5K_SLOT_TIME_9 || slot_time > AR5K_SLOT_TIME_MAX)
-               return -EINVAL;
-
-       if (ah->ah_version == AR5K_AR5210)
-               ath5k_hw_reg_write(ah, ath5k_hw_htoclock(slot_time,
-                               ah->ah_turbo), AR5K_SLOT_TIME);
-       else
-               ath5k_hw_reg_write(ah, slot_time, AR5K_DCU_GBL_IFS_SLOT);
-
-       return 0;
-}
-
diff --git a/drivers/net/wireless/ath5k/reg.h b/drivers/net/wireless/ath5k/reg.h
deleted file mode 100644 (file)
index 7070d15..0000000
+++ /dev/null
@@ -1,2589 +0,0 @@
-/*
- * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
- * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
- * Copyright (c) 2007-2008 Michael Taylor <mike.taylor@apprion.com>
- *
- * Permission to use, copy, modify, and 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.
- *
- */
-
-/*
- * Register values for Atheros 5210/5211/5212 cards from OpenBSD's ar5k
- * maintained by Reyk Floeter
- *
- * I tried to document those registers by looking at ar5k code, some
- * 802.11 (802.11e mostly) papers and by reading various public available
- * Atheros presentations and papers like these:
- *
- * 5210 - http://nova.stanford.edu/~bbaas/ps/isscc2002_slides.pdf
- *        http://www.it.iitb.ac.in/~janak/wifire/01222734.pdf
- *
- * 5211 - http://www.hotchips.org/archives/hc14/3_Tue/16_mcfarland.pdf
- *
- * This file also contains register values found on a memory dump of
- * Atheros's ART program (Atheros Radio Test), on ath9k, on legacy-hal
- * released by Atheros and on various debug messages found on the net.
- */
-
-
-
-/*====MAC DMA REGISTERS====*/
-
-/*
- * AR5210-Specific TXDP registers
- * 5210 has only 2 transmit queues so no DCU/QCU, just
- * 2 transmit descriptor pointers...
- */
-#define AR5K_NOQCU_TXDP0       0x0000          /* Queue 0 - data */
-#define AR5K_NOQCU_TXDP1       0x0004          /* Queue 1 - beacons */
-
-/*
- * Mac Control Register
- */
-#define        AR5K_CR         0x0008                  /* Register Address */
-#define AR5K_CR_TXE0   0x00000001      /* TX Enable for queue 0 on 5210 */
-#define AR5K_CR_TXE1   0x00000002      /* TX Enable for queue 1 on 5210 */
-#define        AR5K_CR_RXE     0x00000004      /* RX Enable */
-#define AR5K_CR_TXD0   0x00000008      /* TX Disable for queue 0 on 5210 */
-#define AR5K_CR_TXD1   0x00000010      /* TX Disable for queue 1 on 5210 */
-#define        AR5K_CR_RXD     0x00000020      /* RX Disable */
-#define        AR5K_CR_SWI     0x00000040      /* Software Interrupt */
-
-/*
- * RX Descriptor Pointer register
- */
-#define        AR5K_RXDP       0x000c
-
-/*
- * Configuration and status register
- */
-#define        AR5K_CFG                0x0014                  /* Register Address */
-#define        AR5K_CFG_SWTD           0x00000001      /* Byte-swap TX descriptor (for big endian archs) */
-#define        AR5K_CFG_SWTB           0x00000002      /* Byte-swap TX buffer */
-#define        AR5K_CFG_SWRD           0x00000004      /* Byte-swap RX descriptor */
-#define        AR5K_CFG_SWRB           0x00000008      /* Byte-swap RX buffer */
-#define        AR5K_CFG_SWRG           0x00000010      /* Byte-swap Register access */
-#define AR5K_CFG_IBSS          0x00000020      /* 0-BSS, 1-IBSS [5211+] */
-#define AR5K_CFG_PHY_OK                0x00000100      /* [5211+] */
-#define AR5K_CFG_EEBS          0x00000200      /* EEPROM is busy */
-#define        AR5K_CFG_CLKGD          0x00000400      /* Clock gated (Disable dynamic clock) */
-#define AR5K_CFG_TXCNT         0x00007800      /* Tx frame count (?) [5210] */
-#define AR5K_CFG_TXCNT_S       11
-#define AR5K_CFG_TXFSTAT       0x00008000      /* Tx frame status (?) [5210] */
-#define AR5K_CFG_TXFSTRT       0x00010000      /* [5210] */
-#define        AR5K_CFG_PCI_THRES      0x00060000      /* PCI Master req q threshold [5211+] */
-#define        AR5K_CFG_PCI_THRES_S    17
-
-/*
- * Interrupt enable register
- */
-#define AR5K_IER               0x0024          /* Register Address */
-#define AR5K_IER_DISABLE       0x00000000      /* Disable card interrupts */
-#define AR5K_IER_ENABLE                0x00000001      /* Enable card interrupts */
-
-
-/*
- * 0x0028 is Beacon Control Register on 5210
- * and first RTS duration register on 5211
- */
-
-/*
- * Beacon control register [5210]
- */
-#define AR5K_BCR               0x0028          /* Register Address */
-#define AR5K_BCR_AP            0x00000000      /* AP mode */
-#define AR5K_BCR_ADHOC         0x00000001      /* Ad-Hoc mode */
-#define AR5K_BCR_BDMAE         0x00000002      /* DMA enable */
-#define AR5K_BCR_TQ1FV         0x00000004      /* Use Queue1 for CAB traffic */
-#define AR5K_BCR_TQ1V          0x00000008      /* Use Queue1 for Beacon traffic */
-#define AR5K_BCR_BCGET         0x00000010
-
-/*
- * First RTS duration register [5211]
- */
-#define AR5K_RTSD0             0x0028          /* Register Address */
-#define        AR5K_RTSD0_6            0x000000ff      /* 6Mb RTS duration mask (?) */
-#define        AR5K_RTSD0_6_S          0               /* 6Mb RTS duration shift (?) */
-#define        AR5K_RTSD0_9            0x0000ff00      /* 9Mb*/
-#define        AR5K_RTSD0_9_S          8
-#define        AR5K_RTSD0_12           0x00ff0000      /* 12Mb*/
-#define        AR5K_RTSD0_12_S         16
-#define        AR5K_RTSD0_18           0xff000000      /* 16Mb*/
-#define        AR5K_RTSD0_18_S         24
-
-
-/*
- * 0x002c is Beacon Status Register on 5210
- * and second RTS duration register on 5211
- */
-
-/*
- * Beacon status register [5210]
- *
- * As i can see in ar5k_ar5210_tx_start Reyk uses some of the values of BCR
- * for this register, so i guess TQ1V,TQ1FV and BDMAE have the same meaning
- * here and SNP/SNAP means "snapshot" (so this register gets synced with BCR).
- * So SNAPPEDBCRVALID sould also stand for "snapped BCR -values- valid", so i
- * renamed it to SNAPSHOTSVALID to make more sense. I realy have no idea what
- * else can it be. I also renamed SNPBCMD to SNPADHOC to match BCR.
- */
-#define AR5K_BSR               0x002c                  /* Register Address */
-#define AR5K_BSR_BDLYSW                0x00000001      /* SW Beacon delay (?) */
-#define AR5K_BSR_BDLYDMA       0x00000002      /* DMA Beacon delay (?) */
-#define AR5K_BSR_TXQ1F         0x00000004      /* Beacon queue (1) finished */
-#define AR5K_BSR_ATIMDLY       0x00000008      /* ATIM delay (?) */
-#define AR5K_BSR_SNPADHOC      0x00000100      /* Ad-hoc mode set (?) */
-#define AR5K_BSR_SNPBDMAE      0x00000200      /* Beacon DMA enabled (?) */
-#define AR5K_BSR_SNPTQ1FV      0x00000400      /* Queue1 is used for CAB traffic (?) */
-#define AR5K_BSR_SNPTQ1V       0x00000800      /* Queue1 is used for Beacon traffic (?) */
-#define AR5K_BSR_SNAPSHOTSVALID        0x00001000      /* BCR snapshots are valid (?) */
-#define AR5K_BSR_SWBA_CNT      0x00ff0000
-
-/*
- * Second RTS duration register [5211]
- */
-#define AR5K_RTSD1             0x002c                  /* Register Address */
-#define        AR5K_RTSD1_24           0x000000ff      /* 24Mb */
-#define        AR5K_RTSD1_24_S         0
-#define        AR5K_RTSD1_36           0x0000ff00      /* 36Mb */
-#define        AR5K_RTSD1_36_S         8
-#define        AR5K_RTSD1_48           0x00ff0000      /* 48Mb */
-#define        AR5K_RTSD1_48_S         16
-#define        AR5K_RTSD1_54           0xff000000      /* 54Mb */
-#define        AR5K_RTSD1_54_S         24
-
-
-/*
- * Transmit configuration register
- */
-#define AR5K_TXCFG                     0x0030                  /* Register Address */
-#define AR5K_TXCFG_SDMAMR              0x00000007      /* DMA size (read) */
-#define AR5K_TXCFG_SDMAMR_S            0
-#define AR5K_TXCFG_B_MODE              0x00000008      /* Set b mode for 5111 (enable 2111) */
-#define AR5K_TXCFG_TXFSTP              0x00000008      /* TX DMA full Stop [5210] */
-#define AR5K_TXCFG_TXFULL              0x000003f0      /* TX Triger level mask */
-#define AR5K_TXCFG_TXFULL_S            4
-#define AR5K_TXCFG_TXFULL_0B           0x00000000
-#define AR5K_TXCFG_TXFULL_64B          0x00000010
-#define AR5K_TXCFG_TXFULL_128B         0x00000020
-#define AR5K_TXCFG_TXFULL_192B         0x00000030
-#define AR5K_TXCFG_TXFULL_256B         0x00000040
-#define AR5K_TXCFG_TXCONT_EN           0x00000080
-#define AR5K_TXCFG_DMASIZE             0x00000100      /* Flag for passing DMA size [5210] */
-#define AR5K_TXCFG_JUMBO_DESC_EN       0x00000400      /* Enable jumbo tx descriptors [5211+] */
-#define AR5K_TXCFG_ADHOC_BCN_ATIM      0x00000800      /* Adhoc Beacon ATIM Policy */
-#define AR5K_TXCFG_ATIM_WINDOW_DEF_DIS 0x00001000      /* Disable ATIM window defer [5211+] */
-#define AR5K_TXCFG_RTSRND              0x00001000      /* [5211+] */
-#define AR5K_TXCFG_FRMPAD_DIS          0x00002000      /* [5211+] */
-#define AR5K_TXCFG_RDY_CBR_DIS         0x00004000      /* Ready time CBR disable [5211+] */
-#define AR5K_TXCFG_JUMBO_FRM_MODE      0x00008000      /* Jumbo frame mode [5211+] */
-#define        AR5K_TXCFG_DCU_DBL_BUF_DIS      0x00008000      /* Disable double buffering on DCU */
-#define AR5K_TXCFG_DCU_CACHING_DIS     0x00010000      /* Disable DCU caching */
-
-/*
- * Receive configuration register
- */
-#define AR5K_RXCFG             0x0034                  /* Register Address */
-#define AR5K_RXCFG_SDMAMW      0x00000007      /* DMA size (write) */
-#define AR5K_RXCFG_SDMAMW_S    0
-#define AR5K_RXCFG_ZLFDMA      0x00000008      /* Enable Zero-length frame DMA */
-#define        AR5K_RXCFG_DEF_ANTENNA  0x00000010      /* Default antenna (?) */
-#define AR5K_RXCFG_JUMBO_RXE   0x00000020      /* Enable jumbo rx descriptors [5211+] */
-#define AR5K_RXCFG_JUMBO_WRAP  0x00000040      /* Wrap jumbo frames [5211+] */
-#define AR5K_RXCFG_SLE_ENTRY   0x00000080      /* Sleep entry policy */
-
-/*
- * Receive jumbo descriptor last address register
- * Only found in 5211 (?)
- */
-#define AR5K_RXJLA             0x0038
-
-/*
- * MIB control register
- */
-#define AR5K_MIBC              0x0040                  /* Register Address */
-#define AR5K_MIBC_COW          0x00000001      /* Warn test indicator */
-#define AR5K_MIBC_FMC          0x00000002      /* Freeze MIB Counters  */
-#define AR5K_MIBC_CMC          0x00000004      /* Clean MIB Counters  */
-#define AR5K_MIBC_MCS          0x00000008      /* MIB counter strobe */
-
-/*
- * Timeout prescale register
- */
-#define AR5K_TOPS              0x0044
-#define        AR5K_TOPS_M             0x0000ffff
-
-/*
- * Receive timeout register (no frame received)
- */
-#define AR5K_RXNOFRM           0x0048
-#define        AR5K_RXNOFRM_M          0x000003ff
-
-/*
- * Transmit timeout register (no frame sent)
- */
-#define AR5K_TXNOFRM           0x004c
-#define        AR5K_TXNOFRM_M          0x000003ff
-#define        AR5K_TXNOFRM_QCU        0x000ffc00
-#define        AR5K_TXNOFRM_QCU_S      10
-
-/*
- * Receive frame gap timeout register
- */
-#define AR5K_RPGTO             0x0050
-#define AR5K_RPGTO_M           0x000003ff
-
-/*
- * Receive frame count limit register
- */
-#define AR5K_RFCNT             0x0054
-#define AR5K_RFCNT_M           0x0000001f      /* [5211+] (?) */
-#define AR5K_RFCNT_RFCL                0x0000000f      /* [5210] */
-
-/*
- * Misc settings register
- * (reserved0-3)
- */
-#define AR5K_MISC              0x0058                  /* Register Address */
-#define        AR5K_MISC_DMA_OBS_M     0x000001e0
-#define        AR5K_MISC_DMA_OBS_S     5
-#define        AR5K_MISC_MISC_OBS_M    0x00000e00
-#define        AR5K_MISC_MISC_OBS_S    9
-#define        AR5K_MISC_MAC_OBS_LSB_M 0x00007000
-#define        AR5K_MISC_MAC_OBS_LSB_S 12
-#define        AR5K_MISC_MAC_OBS_MSB_M 0x00038000
-#define        AR5K_MISC_MAC_OBS_MSB_S 15
-#define AR5K_MISC_LED_DECAY    0x001c0000      /* [5210] */
-#define AR5K_MISC_LED_BLINK    0x00e00000      /* [5210] */
-
-/*
- * QCU/DCU clock gating register (5311)
- * (reserved4-5)
- */
-#define        AR5K_QCUDCU_CLKGT       0x005c                  /* Register Address (?) */
-#define        AR5K_QCUDCU_CLKGT_QCU   0x0000ffff      /* Mask for QCU clock */
-#define        AR5K_QCUDCU_CLKGT_DCU   0x07ff0000      /* Mask for DCU clock */
-
-/*
- * Interrupt Status Registers
- *
- * For 5210 there is only one status register but for
- * 5211/5212 we have one primary and 4 secondary registers.
- * So we have AR5K_ISR for 5210 and AR5K_PISR /SISRx for 5211/5212.
- * Most of these bits are common for all chipsets.
- */
-#define AR5K_ISR               0x001c                  /* Register Address [5210] */
-#define AR5K_PISR              0x0080                  /* Register Address [5211+] */
-#define AR5K_ISR_RXOK          0x00000001      /* Frame successfuly recieved */
-#define AR5K_ISR_RXDESC                0x00000002      /* RX descriptor request */
-#define AR5K_ISR_RXERR         0x00000004      /* Receive error */
-#define AR5K_ISR_RXNOFRM       0x00000008      /* No frame received (receive timeout) */
-#define AR5K_ISR_RXEOL         0x00000010      /* Empty RX descriptor */
-#define AR5K_ISR_RXORN         0x00000020      /* Receive FIFO overrun */
-#define AR5K_ISR_TXOK          0x00000040      /* Frame successfuly transmited */
-#define AR5K_ISR_TXDESC                0x00000080      /* TX descriptor request */
-#define AR5K_ISR_TXERR         0x00000100      /* Transmit error */
-#define AR5K_ISR_TXNOFRM       0x00000200      /* No frame transmited (transmit timeout) */
-#define AR5K_ISR_TXEOL         0x00000400      /* Empty TX descriptor */
-#define AR5K_ISR_TXURN         0x00000800      /* Transmit FIFO underrun */
-#define AR5K_ISR_MIB           0x00001000      /* Update MIB counters */
-#define AR5K_ISR_SWI           0x00002000      /* Software interrupt */
-#define AR5K_ISR_RXPHY         0x00004000      /* PHY error */
-#define AR5K_ISR_RXKCM         0x00008000      /* RX Key cache miss */
-#define AR5K_ISR_SWBA          0x00010000      /* Software beacon alert */
-#define AR5K_ISR_BRSSI         0x00020000      /* Beacon rssi below threshold (?) */
-#define AR5K_ISR_BMISS         0x00040000      /* Beacon missed */
-#define AR5K_ISR_HIUERR                0x00080000      /* Host Interface Unit error [5211+] */
-#define AR5K_ISR_BNR           0x00100000      /* Beacon not ready [5211+] */
-#define AR5K_ISR_MCABT         0x00100000      /* Master Cycle Abort [5210] */
-#define AR5K_ISR_RXCHIRP       0x00200000      /* CHIRP Received [5212+] */
-#define AR5K_ISR_SSERR         0x00200000      /* Signaled System Error [5210] */
-#define AR5K_ISR_DPERR         0x00400000      /* Det par Error (?) [5210] */
-#define AR5K_ISR_RXDOPPLER     0x00400000      /* Doppler chirp received [5212+] */
-#define AR5K_ISR_TIM           0x00800000      /* [5211+] */
-#define AR5K_ISR_BCNMISC       0x00800000      /* 'or' of TIM, CAB_END, DTIM_SYNC, BCN_TIMEOUT,
-                                               CAB_TIMEOUT and DTIM bits from SISR2 [5212+] */
-#define AR5K_ISR_GPIO          0x01000000      /* GPIO (rf kill) */
-#define AR5K_ISR_QCBRORN       0x02000000      /* QCU CBR overrun [5211+] */
-#define AR5K_ISR_QCBRURN       0x04000000      /* QCU CBR underrun [5211+] */
-#define AR5K_ISR_QTRIG         0x08000000      /* QCU scheduling trigger [5211+] */
-
-/*
- * Secondary status registers [5211+] (0 - 4)
- *
- * These give the status for each QCU, only QCUs 0-9 are
- * represented.
- */
-#define AR5K_SISR0             0x0084                  /* Register Address [5211+] */
-#define AR5K_SISR0_QCU_TXOK    0x000003ff      /* Mask for QCU_TXOK */
-#define AR5K_SISR0_QCU_TXOK_S  0
-#define AR5K_SISR0_QCU_TXDESC  0x03ff0000      /* Mask for QCU_TXDESC */
-#define AR5K_SISR0_QCU_TXDESC_S        16
-
-#define AR5K_SISR1             0x0088                  /* Register Address [5211+] */
-#define AR5K_SISR1_QCU_TXERR   0x000003ff      /* Mask for QCU_TXERR */
-#define AR5K_SISR1_QCU_TXERR_S 0
-#define AR5K_SISR1_QCU_TXEOL   0x03ff0000      /* Mask for QCU_TXEOL */
-#define AR5K_SISR1_QCU_TXEOL_S 16
-
-#define AR5K_SISR2             0x008c                  /* Register Address [5211+] */
-#define AR5K_SISR2_QCU_TXURN   0x000003ff      /* Mask for QCU_TXURN */
-#define        AR5K_SISR2_QCU_TXURN_S  0
-#define        AR5K_SISR2_MCABT        0x00100000      /* Master Cycle Abort */
-#define        AR5K_SISR2_SSERR        0x00200000      /* Signaled System Error */
-#define        AR5K_SISR2_DPERR        0x00400000      /* Bus parity error */
-#define        AR5K_SISR2_TIM          0x01000000      /* [5212+] */
-#define        AR5K_SISR2_CAB_END      0x02000000      /* [5212+] */
-#define        AR5K_SISR2_DTIM_SYNC    0x04000000      /* DTIM sync lost [5212+] */
-#define        AR5K_SISR2_BCN_TIMEOUT  0x08000000      /* Beacon Timeout [5212+] */
-#define        AR5K_SISR2_CAB_TIMEOUT  0x10000000      /* CAB Timeout [5212+] */
-#define        AR5K_SISR2_DTIM         0x20000000      /* [5212+] */
-#define        AR5K_SISR2_TSFOOR       0x80000000      /* TSF OOR (?) */
-
-#define AR5K_SISR3             0x0090                  /* Register Address [5211+] */
-#define AR5K_SISR3_QCBRORN     0x000003ff      /* Mask for QCBRORN */
-#define AR5K_SISR3_QCBRORN_S   0
-#define AR5K_SISR3_QCBRURN     0x03ff0000      /* Mask for QCBRURN */
-#define AR5K_SISR3_QCBRURN_S   16
-
-#define AR5K_SISR4             0x0094                  /* Register Address [5211+] */
-#define AR5K_SISR4_QTRIG       0x000003ff      /* Mask for QTRIG */
-#define AR5K_SISR4_QTRIG_S     0
-
-/*
- * Shadow read-and-clear interrupt status registers [5211+]
- */
-#define AR5K_RAC_PISR          0x00c0          /* Read and clear PISR */
-#define AR5K_RAC_SISR0         0x00c4          /* Read and clear SISR0 */
-#define AR5K_RAC_SISR1         0x00c8          /* Read and clear SISR1 */
-#define AR5K_RAC_SISR2         0x00cc          /* Read and clear SISR2 */
-#define AR5K_RAC_SISR3         0x00d0          /* Read and clear SISR3 */
-#define AR5K_RAC_SISR4         0x00d4          /* Read and clear SISR4 */
-
-/*
- * Interrupt Mask Registers
- *
- * As whith ISRs 5210 has one IMR (AR5K_IMR) and 5211/5212 has one primary
- * (AR5K_PIMR) and 4 secondary IMRs (AR5K_SIMRx). Note that ISR/IMR flags match.
- */
-#define        AR5K_IMR                0x0020                  /* Register Address [5210] */
-#define AR5K_PIMR              0x00a0                  /* Register Address [5211+] */
-#define AR5K_IMR_RXOK          0x00000001      /* Frame successfuly recieved*/
-#define AR5K_IMR_RXDESC                0x00000002      /* RX descriptor request*/
-#define AR5K_IMR_RXERR         0x00000004      /* Receive error*/
-#define AR5K_IMR_RXNOFRM       0x00000008      /* No frame received (receive timeout)*/
-#define AR5K_IMR_RXEOL         0x00000010      /* Empty RX descriptor*/
-#define AR5K_IMR_RXORN         0x00000020      /* Receive FIFO overrun*/
-#define AR5K_IMR_TXOK          0x00000040      /* Frame successfuly transmited*/
-#define AR5K_IMR_TXDESC                0x00000080      /* TX descriptor request*/
-#define AR5K_IMR_TXERR         0x00000100      /* Transmit error*/
-#define AR5K_IMR_TXNOFRM       0x00000200      /* No frame transmited (transmit timeout)*/
-#define AR5K_IMR_TXEOL         0x00000400      /* Empty TX descriptor*/
-#define AR5K_IMR_TXURN         0x00000800      /* Transmit FIFO underrun*/
-#define AR5K_IMR_MIB           0x00001000      /* Update MIB counters*/
-#define AR5K_IMR_SWI           0x00002000      /* Software interrupt */
-#define AR5K_IMR_RXPHY         0x00004000      /* PHY error*/
-#define AR5K_IMR_RXKCM         0x00008000      /* RX Key cache miss */
-#define AR5K_IMR_SWBA          0x00010000      /* Software beacon alert*/
-#define AR5K_IMR_BRSSI         0x00020000      /* Beacon rssi below threshold (?) */
-#define AR5K_IMR_BMISS         0x00040000      /* Beacon missed*/
-#define AR5K_IMR_HIUERR                0x00080000      /* Host Interface Unit error [5211+] */
-#define AR5K_IMR_BNR           0x00100000      /* Beacon not ready [5211+] */
-#define AR5K_IMR_MCABT         0x00100000      /* Master Cycle Abort [5210] */
-#define AR5K_IMR_RXCHIRP       0x00200000      /* CHIRP Received [5212+]*/
-#define AR5K_IMR_SSERR         0x00200000      /* Signaled System Error [5210] */
-#define AR5K_IMR_DPERR         0x00400000      /* Det par Error (?) [5210] */
-#define AR5K_IMR_RXDOPPLER     0x00400000      /* Doppler chirp received [5212+] */
-#define AR5K_IMR_TIM           0x00800000      /* [5211+] */
-#define AR5K_IMR_BCNMISC       0x00800000      /* 'or' of TIM, CAB_END, DTIM_SYNC, BCN_TIMEOUT,
-                                               CAB_TIMEOUT and DTIM bits from SISR2 [5212+] */
-#define AR5K_IMR_GPIO          0x01000000      /* GPIO (rf kill)*/
-#define AR5K_IMR_QCBRORN       0x02000000      /* QCU CBR overrun (?) [5211+] */
-#define AR5K_IMR_QCBRURN       0x04000000      /* QCU CBR underrun (?) [5211+] */
-#define AR5K_IMR_QTRIG         0x08000000      /* QCU scheduling trigger [5211+] */
-
-/*
- * Secondary interrupt mask registers [5211+] (0 - 4)
- */
-#define AR5K_SIMR0             0x00a4                  /* Register Address [5211+] */
-#define AR5K_SIMR0_QCU_TXOK    0x000003ff      /* Mask for QCU_TXOK */
-#define AR5K_SIMR0_QCU_TXOK_S  0
-#define AR5K_SIMR0_QCU_TXDESC  0x03ff0000      /* Mask for QCU_TXDESC */
-#define AR5K_SIMR0_QCU_TXDESC_S        16
-
-#define AR5K_SIMR1             0x00a8                  /* Register Address [5211+] */
-#define AR5K_SIMR1_QCU_TXERR   0x000003ff      /* Mask for QCU_TXERR */
-#define AR5K_SIMR1_QCU_TXERR_S 0
-#define AR5K_SIMR1_QCU_TXEOL   0x03ff0000      /* Mask for QCU_TXEOL */
-#define AR5K_SIMR1_QCU_TXEOL_S 16
-
-#define AR5K_SIMR2             0x00ac                  /* Register Address [5211+] */
-#define AR5K_SIMR2_QCU_TXURN   0x000003ff      /* Mask for QCU_TXURN */
-#define AR5K_SIMR2_QCU_TXURN_S 0
-#define        AR5K_SIMR2_MCABT        0x00100000      /* Master Cycle Abort */
-#define        AR5K_SIMR2_SSERR        0x00200000      /* Signaled System Error */
-#define        AR5K_SIMR2_DPERR        0x00400000      /* Bus parity error */
-#define        AR5K_SIMR2_TIM          0x01000000      /* [5212+] */
-#define        AR5K_SIMR2_CAB_END      0x02000000      /* [5212+] */
-#define        AR5K_SIMR2_DTIM_SYNC    0x04000000      /* DTIM Sync lost [5212+] */
-#define        AR5K_SIMR2_BCN_TIMEOUT  0x08000000      /* Beacon Timeout [5212+] */
-#define        AR5K_SIMR2_CAB_TIMEOUT  0x10000000      /* CAB Timeout [5212+] */
-#define        AR5K_SIMR2_DTIM         0x20000000      /* [5212+] */
-#define        AR5K_SIMR2_TSFOOR       0x80000000      /* TSF OOR (?) */
-
-#define AR5K_SIMR3             0x00b0                  /* Register Address [5211+] */
-#define AR5K_SIMR3_QCBRORN     0x000003ff      /* Mask for QCBRORN */
-#define AR5K_SIMR3_QCBRORN_S   0
-#define AR5K_SIMR3_QCBRURN     0x03ff0000      /* Mask for QCBRURN */
-#define AR5K_SIMR3_QCBRURN_S   16
-
-#define AR5K_SIMR4             0x00b4                  /* Register Address [5211+] */
-#define AR5K_SIMR4_QTRIG       0x000003ff      /* Mask for QTRIG */
-#define AR5K_SIMR4_QTRIG_S     0
-
-/*
- * DMA Debug registers 0-7
- * 0xe0 - 0xfc
- */
-
-/*
- * Decompression mask registers [5212+]
- */
-#define AR5K_DCM_ADDR          0x0400          /*Decompression mask address (index) */
-#define AR5K_DCM_DATA          0x0404          /*Decompression mask data */
-
-/*
- * Wake On Wireless pattern control register [5212+]
- */
-#define        AR5K_WOW_PCFG                   0x0410                  /* Register Address */
-#define        AR5K_WOW_PCFG_PAT_MATCH_EN      0x00000001      /* Pattern match enable */
-#define        AR5K_WOW_PCFG_LONG_FRAME_POL    0x00000002      /* Long frame policy */
-#define        AR5K_WOW_PCFG_WOBMISS           0x00000004      /* Wake on bea(con) miss (?) */
-#define        AR5K_WOW_PCFG_PAT_0_EN          0x00000100      /* Enable pattern 0 */
-#define        AR5K_WOW_PCFG_PAT_1_EN          0x00000200      /* Enable pattern 1 */
-#define        AR5K_WOW_PCFG_PAT_2_EN          0x00000400      /* Enable pattern 2 */
-#define        AR5K_WOW_PCFG_PAT_3_EN          0x00000800      /* Enable pattern 3 */
-#define        AR5K_WOW_PCFG_PAT_4_EN          0x00001000      /* Enable pattern 4 */
-#define        AR5K_WOW_PCFG_PAT_5_EN          0x00002000      /* Enable pattern 5 */
-
-/*
- * Wake On Wireless pattern index register (?) [5212+]
- */
-#define        AR5K_WOW_PAT_IDX        0x0414
-
-/*
- * Wake On Wireless pattern data register [5212+]
- */
-#define        AR5K_WOW_PAT_DATA       0x0418                  /* Register Address */
-#define        AR5K_WOW_PAT_DATA_0_3_V 0x00000001      /* Pattern 0, 3 value */
-#define        AR5K_WOW_PAT_DATA_1_4_V 0x00000100      /* Pattern 1, 4 value */
-#define        AR5K_WOW_PAT_DATA_2_5_V 0x00010000      /* Pattern 2, 5 value */
-#define        AR5K_WOW_PAT_DATA_0_3_M 0x01000000      /* Pattern 0, 3 mask */
-#define        AR5K_WOW_PAT_DATA_1_4_M 0x04000000      /* Pattern 1, 4 mask */
-#define        AR5K_WOW_PAT_DATA_2_5_M 0x10000000      /* Pattern 2, 5 mask */
-
-/*
- * Decompression configuration registers [5212+]
- */
-#define AR5K_DCCFG             0x0420                  /* Register Address */
-#define AR5K_DCCFG_GLOBAL_EN   0x00000001      /* Enable decompression on all queues */
-#define AR5K_DCCFG_BYPASS_EN   0x00000002      /* Bypass decompression */
-#define AR5K_DCCFG_BCAST_EN    0x00000004      /* Enable decompression for bcast frames */
-#define AR5K_DCCFG_MCAST_EN    0x00000008      /* Enable decompression for mcast frames */
-
-/*
- * Compression configuration registers [5212+]
- */
-#define AR5K_CCFG              0x0600                  /* Register Address */
-#define        AR5K_CCFG_WINDOW_SIZE   0x00000007      /* Compression window size */
-#define        AR5K_CCFG_CPC_EN        0x00000008      /* Enable performance counters */
-
-#define AR5K_CCFG_CCU          0x0604                  /* Register Address */
-#define AR5K_CCFG_CCU_CUP_EN   0x00000001      /* CCU Catchup enable */
-#define AR5K_CCFG_CCU_CREDIT   0x00000002      /* CCU Credit (field) */
-#define AR5K_CCFG_CCU_CD_THRES 0x00000080      /* CCU Cyc(lic?) debt threshold (field) */
-#define AR5K_CCFG_CCU_CUP_LCNT 0x00010000      /* CCU Catchup lit(?) count */
-#define        AR5K_CCFG_CCU_INIT      0x00100200      /* Initial value during reset */
-
-/*
- * Compression performance counter registers [5212+]
- */
-#define AR5K_CPC0              0x0610          /* Compression performance counter 0 */
-#define AR5K_CPC1              0x0614          /* Compression performance counter 1*/
-#define AR5K_CPC2              0x0618          /* Compression performance counter 2 */
-#define AR5K_CPC3              0x061c          /* Compression performance counter 3 */
-#define AR5K_CPCOVF            0x0620          /* Compression performance overflow */
-
-
-/*
- * Queue control unit (QCU) registers [5211+]
- *
- * Card has 12 TX Queues but i see that only 0-9 are used (?)
- * both in binary HAL (see ah.h) and ar5k. Each queue has it's own
- * TXDP at addresses 0x0800 - 0x082c, a CBR (Constant Bit Rate)
- * configuration register (0x08c0 - 0x08ec), a ready time configuration
- * register (0x0900 - 0x092c), a misc configuration register (0x09c0 -
- * 0x09ec) and a status register (0x0a00 - 0x0a2c). We also have some
- * global registers, QCU transmit enable/disable and "one shot arm (?)"
- * set/clear, which contain status for all queues (we shift by 1 for each
- * queue). To access these registers easily we define some macros here
- * that are used inside HAL. For more infos check out *_tx_queue functs.
- */
-
-/*
- * Generic QCU Register access macros
- */
-#define        AR5K_QUEUE_REG(_r, _q)          (((_q) << 2) + _r)
-#define AR5K_QCU_GLOBAL_READ(_r, _q)   (AR5K_REG_READ(_r) & (1 << _q))
-#define AR5K_QCU_GLOBAL_WRITE(_r, _q)  AR5K_REG_WRITE(_r, (1 << _q))
-
-/*
- * QCU Transmit descriptor pointer registers
- */
-#define AR5K_QCU_TXDP_BASE     0x0800          /* Register Address - Queue0 TXDP */
-#define AR5K_QUEUE_TXDP(_q)    AR5K_QUEUE_REG(AR5K_QCU_TXDP_BASE, _q)
-
-/*
- * QCU Transmit enable register
- */
-#define AR5K_QCU_TXE           0x0840
-#define AR5K_ENABLE_QUEUE(_q)  AR5K_QCU_GLOBAL_WRITE(AR5K_QCU_TXE, _q)
-#define AR5K_QUEUE_ENABLED(_q) AR5K_QCU_GLOBAL_READ(AR5K_QCU_TXE, _q)
-
-/*
- * QCU Transmit disable register
- */
-#define AR5K_QCU_TXD           0x0880
-#define AR5K_DISABLE_QUEUE(_q) AR5K_QCU_GLOBAL_WRITE(AR5K_QCU_TXD, _q)
-#define AR5K_QUEUE_DISABLED(_q)        AR5K_QCU_GLOBAL_READ(AR5K_QCU_TXD, _q)
-
-/*
- * QCU Constant Bit Rate configuration registers
- */
-#define        AR5K_QCU_CBRCFG_BASE            0x08c0  /* Register Address - Queue0 CBRCFG */
-#define        AR5K_QCU_CBRCFG_INTVAL          0x00ffffff      /* CBR Interval mask */
-#define AR5K_QCU_CBRCFG_INTVAL_S       0
-#define        AR5K_QCU_CBRCFG_ORN_THRES       0xff000000      /* CBR overrun threshold mask */
-#define AR5K_QCU_CBRCFG_ORN_THRES_S    24
-#define        AR5K_QUEUE_CBRCFG(_q)           AR5K_QUEUE_REG(AR5K_QCU_CBRCFG_BASE, _q)
-
-/*
- * QCU Ready time configuration registers
- */
-#define        AR5K_QCU_RDYTIMECFG_BASE        0x0900  /* Register Address - Queue0 RDYTIMECFG */
-#define        AR5K_QCU_RDYTIMECFG_INTVAL      0x00ffffff      /* Ready time interval mask */
-#define AR5K_QCU_RDYTIMECFG_INTVAL_S   0
-#define        AR5K_QCU_RDYTIMECFG_ENABLE      0x01000000      /* Ready time enable mask */
-#define AR5K_QUEUE_RDYTIMECFG(_q)      AR5K_QUEUE_REG(AR5K_QCU_RDYTIMECFG_BASE, _q)
-
-/*
- * QCU one shot arm set registers
- */
-#define        AR5K_QCU_ONESHOTARM_SET         0x0940  /* Register Address -QCU "one shot arm set (?)" */
-#define        AR5K_QCU_ONESHOTARM_SET_M       0x0000ffff
-
-/*
- * QCU one shot arm clear registers
- */
-#define        AR5K_QCU_ONESHOTARM_CLEAR       0x0980  /* Register Address -QCU "one shot arm clear (?)" */
-#define        AR5K_QCU_ONESHOTARM_CLEAR_M     0x0000ffff
-
-/*
- * QCU misc registers
- */
-#define AR5K_QCU_MISC_BASE             0x09c0                  /* Register Address -Queue0 MISC */
-#define        AR5K_QCU_MISC_FRSHED_M          0x0000000f      /* Frame sheduling mask */
-#define        AR5K_QCU_MISC_FRSHED_ASAP               0       /* ASAP */
-#define        AR5K_QCU_MISC_FRSHED_CBR                1       /* Constant Bit Rate */
-#define        AR5K_QCU_MISC_FRSHED_DBA_GT             2       /* DMA Beacon alert gated */
-#define        AR5K_QCU_MISC_FRSHED_TIM_GT             3       /* TIMT gated */
-#define        AR5K_QCU_MISC_FRSHED_BCN_SENT_GT        4       /* Beacon sent gated */
-#define        AR5K_QCU_MISC_ONESHOT_ENABLE    0x00000010      /* Oneshot enable */
-#define        AR5K_QCU_MISC_CBREXP_DIS        0x00000020      /* Disable CBR expired counter (normal queue) */
-#define        AR5K_QCU_MISC_CBREXP_BCN_DIS    0x00000040      /* Disable CBR expired counter (beacon queue) */
-#define        AR5K_QCU_MISC_BCN_ENABLE        0x00000080      /* Enable Beacon use */
-#define        AR5K_QCU_MISC_CBR_THRES_ENABLE  0x00000100      /* CBR expired threshold enabled */
-#define        AR5K_QCU_MISC_RDY_VEOL_POLICY   0x00000200      /* TXE reset when RDYTIME expired or VEOL */
-#define        AR5K_QCU_MISC_CBR_RESET_CNT     0x00000400      /* CBR threshold (counter) reset */
-#define        AR5K_QCU_MISC_DCU_EARLY         0x00000800      /* DCU early termination */
-#define AR5K_QCU_MISC_DCU_CMP_EN       0x00001000      /* Enable frame compression */
-#define AR5K_QUEUE_MISC(_q)            AR5K_QUEUE_REG(AR5K_QCU_MISC_BASE, _q)
-
-
-/*
- * QCU status registers
- */
-#define AR5K_QCU_STS_BASE      0x0a00                  /* Register Address - Queue0 STS */
-#define        AR5K_QCU_STS_FRMPENDCNT 0x00000003      /* Frames pending counter */
-#define        AR5K_QCU_STS_CBREXPCNT  0x0000ff00      /* CBR expired counter */
-#define        AR5K_QUEUE_STATUS(_q)   AR5K_QUEUE_REG(AR5K_QCU_STS_BASE, _q)
-
-/*
- * QCU ready time shutdown register
- */
-#define AR5K_QCU_RDYTIMESHDN   0x0a40
-#define AR5K_QCU_RDYTIMESHDN_M 0x000003ff
-
-/*
- * QCU compression buffer base registers [5212+]
- */
-#define AR5K_QCU_CBB_SELECT    0x0b00
-#define AR5K_QCU_CBB_ADDR      0x0b04
-#define AR5K_QCU_CBB_ADDR_S    9
-
-/*
- * QCU compression buffer configuration register [5212+]
- * (buffer size)
- */
-#define AR5K_QCU_CBCFG         0x0b08
-
-
-
-/*
- * Distributed Coordination Function (DCF) control unit (DCU)
- * registers [5211+]
- *
- * These registers control the various characteristics of each queue
- * for 802.11e (WME) combatibility so they go together with
- * QCU registers in pairs. For each queue we have a QCU mask register,
- * (0x1000 - 0x102c), a local-IFS settings register (0x1040 - 0x106c),
- * a retry limit register (0x1080 - 0x10ac), a channel time register
- * (0x10c0 - 0x10ec), a misc-settings register (0x1100 - 0x112c) and
- * a sequence number register (0x1140 - 0x116c). It seems that "global"
- * registers here afect all queues (see use of DCU_GBL_IFS_SLOT in ar5k).
- * We use the same macros here for easier register access.
- *
- */
-
-/*
- * DCU QCU mask registers
- */
-#define AR5K_DCU_QCUMASK_BASE  0x1000          /* Register Address -Queue0 DCU_QCUMASK */
-#define AR5K_DCU_QCUMASK_M     0x000003ff
-#define AR5K_QUEUE_QCUMASK(_q) AR5K_QUEUE_REG(AR5K_DCU_QCUMASK_BASE, _q)
-
-/*
- * DCU local Inter Frame Space settings register
- */
-#define AR5K_DCU_LCL_IFS_BASE          0x1040                  /* Register Address -Queue0 DCU_LCL_IFS */
-#define        AR5K_DCU_LCL_IFS_CW_MIN         0x000003ff      /* Minimum Contention Window */
-#define        AR5K_DCU_LCL_IFS_CW_MIN_S       0
-#define        AR5K_DCU_LCL_IFS_CW_MAX         0x000ffc00      /* Maximum Contention Window */
-#define        AR5K_DCU_LCL_IFS_CW_MAX_S       10
-#define        AR5K_DCU_LCL_IFS_AIFS           0x0ff00000      /* Arbitrated Interframe Space */
-#define        AR5K_DCU_LCL_IFS_AIFS_S         20
-#define        AR5K_DCU_LCL_IFS_AIFS_MAX       0xfc            /* Anything above that can cause DCU to hang */
-#define        AR5K_QUEUE_DFS_LOCAL_IFS(_q)    AR5K_QUEUE_REG(AR5K_DCU_LCL_IFS_BASE, _q)
-
-/*
- * DCU retry limit registers
- */
-#define AR5K_DCU_RETRY_LMT_BASE                0x1080                  /* Register Address -Queue0 DCU_RETRY_LMT */
-#define AR5K_DCU_RETRY_LMT_SH_RETRY    0x0000000f      /* Short retry limit mask */
-#define AR5K_DCU_RETRY_LMT_SH_RETRY_S  0
-#define AR5K_DCU_RETRY_LMT_LG_RETRY    0x000000f0      /* Long retry limit mask */
-#define AR5K_DCU_RETRY_LMT_LG_RETRY_S  4
-#define AR5K_DCU_RETRY_LMT_SSH_RETRY   0x00003f00      /* Station short retry limit mask (?) */
-#define AR5K_DCU_RETRY_LMT_SSH_RETRY_S 8
-#define AR5K_DCU_RETRY_LMT_SLG_RETRY   0x000fc000      /* Station long retry limit mask (?) */
-#define AR5K_DCU_RETRY_LMT_SLG_RETRY_S 14
-#define        AR5K_QUEUE_DFS_RETRY_LIMIT(_q)  AR5K_QUEUE_REG(AR5K_DCU_RETRY_LMT_BASE, _q)
-
-/*
- * DCU channel time registers
- */
-#define AR5K_DCU_CHAN_TIME_BASE                0x10c0                  /* Register Address -Queue0 DCU_CHAN_TIME */
-#define        AR5K_DCU_CHAN_TIME_DUR          0x000fffff      /* Channel time duration */
-#define        AR5K_DCU_CHAN_TIME_DUR_S        0
-#define        AR5K_DCU_CHAN_TIME_ENABLE       0x00100000      /* Enable channel time */
-#define AR5K_QUEUE_DFS_CHANNEL_TIME(_q)        AR5K_QUEUE_REG(AR5K_DCU_CHAN_TIME_BASE, _q)
-
-/*
- * DCU misc registers [5211+]
- *
- * Note: Arbiter lockout control controls the
- * behaviour on low priority queues when we have multiple queues
- * with pending frames. Intra-frame lockout means we wait until
- * the queue's current frame transmits (with post frame backoff and bursting)
- * before we transmit anything else and global lockout means we
- * wait for the whole queue to finish before higher priority queues
- * can transmit (this is used on beacon and CAB queues).
- * No lockout means there is no special handling.
- */
-#define AR5K_DCU_MISC_BASE             0x1100                  /* Register Address -Queue0 DCU_MISC */
-#define        AR5K_DCU_MISC_BACKOFF           0x0000003f      /* Mask for backoff threshold */
-#define        AR5K_DCU_MISC_ETS_RTS_POL       0x00000040      /* End of transmission series
-                                                       station RTS/data failure count
-                                                       reset policy (?) */
-#define AR5K_DCU_MISC_ETS_CW_POL       0x00000080      /* End of transmission series
-                                                       CW reset policy */
-#define        AR5K_DCU_MISC_FRAG_WAIT         0x00000100      /* Wait for next fragment */
-#define AR5K_DCU_MISC_BACKOFF_FRAG     0x00000200      /* Enable backoff while bursting */
-#define        AR5K_DCU_MISC_HCFPOLL_ENABLE    0x00000800      /* CF - Poll enable */
-#define        AR5K_DCU_MISC_BACKOFF_PERSIST   0x00001000      /* Persistent backoff */
-#define        AR5K_DCU_MISC_FRMPRFTCH_ENABLE  0x00002000      /* Enable frame pre-fetch */
-#define        AR5K_DCU_MISC_VIRTCOL           0x0000c000      /* Mask for Virtual Collision (?) */
-#define        AR5K_DCU_MISC_VIRTCOL_NORMAL    0
-#define        AR5K_DCU_MISC_VIRTCOL_IGNORE    1
-#define        AR5K_DCU_MISC_BCN_ENABLE        0x00010000      /* Enable Beacon use */
-#define        AR5K_DCU_MISC_ARBLOCK_CTL       0x00060000      /* Arbiter lockout control mask */
-#define        AR5K_DCU_MISC_ARBLOCK_CTL_S     17
-#define        AR5K_DCU_MISC_ARBLOCK_CTL_NONE          0       /* No arbiter lockout */
-#define        AR5K_DCU_MISC_ARBLOCK_CTL_INTFRM        1       /* Intra-frame lockout */
-#define        AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL        2       /* Global lockout */
-#define        AR5K_DCU_MISC_ARBLOCK_IGNORE    0x00080000      /* Ignore Arbiter lockout */
-#define        AR5K_DCU_MISC_SEQ_NUM_INCR_DIS  0x00100000      /* Disable sequence number increment */
-#define        AR5K_DCU_MISC_POST_FR_BKOFF_DIS 0x00200000      /* Disable post-frame backoff */
-#define        AR5K_DCU_MISC_VIRT_COLL_POLICY  0x00400000      /* Virtual Collision cw policy */
-#define        AR5K_DCU_MISC_BLOWN_IFS_POLICY  0x00800000      /* Blown IFS policy (?) */
-#define        AR5K_DCU_MISC_SEQNUM_CTL        0x01000000      /* Sequence number control (?) */
-#define AR5K_QUEUE_DFS_MISC(_q)                AR5K_QUEUE_REG(AR5K_DCU_MISC_BASE, _q)
-
-/*
- * DCU frame sequence number registers
- */
-#define AR5K_DCU_SEQNUM_BASE           0x1140
-#define        AR5K_DCU_SEQNUM_M               0x00000fff
-#define        AR5K_QUEUE_DCU_SEQNUM(_q)       AR5K_QUEUE_REG(AR5K_DCU_SEQNUM_BASE, _q)
-
-/*
- * DCU global IFS SIFS register
- */
-#define AR5K_DCU_GBL_IFS_SIFS  0x1030
-#define AR5K_DCU_GBL_IFS_SIFS_M        0x0000ffff
-
-/*
- * DCU global IFS slot interval register
- */
-#define AR5K_DCU_GBL_IFS_SLOT  0x1070
-#define AR5K_DCU_GBL_IFS_SLOT_M        0x0000ffff
-
-/*
- * DCU global IFS EIFS register
- */
-#define AR5K_DCU_GBL_IFS_EIFS  0x10b0
-#define AR5K_DCU_GBL_IFS_EIFS_M        0x0000ffff
-
-/*
- * DCU global IFS misc register
- *
- * LFSR stands for Linear Feedback Shift Register
- * and it's used for generating pseudo-random
- * number sequences.
- *
- * (If i understand corectly, random numbers are
- * used for idle sensing -multiplied with cwmin/max etc-)
- */
-#define AR5K_DCU_GBL_IFS_MISC                  0x10f0                  /* Register Address */
-#define        AR5K_DCU_GBL_IFS_MISC_LFSR_SLICE        0x00000007      /* LFSR Slice Select */
-#define        AR5K_DCU_GBL_IFS_MISC_TURBO_MODE        0x00000008      /* Turbo mode */
-#define        AR5K_DCU_GBL_IFS_MISC_SIFS_DUR_USEC     0x000003f0      /* SIFS Duration mask */
-#define        AR5K_DCU_GBL_IFS_MISC_USEC_DUR          0x000ffc00      /* USEC Duration mask */
-#define        AR5K_DCU_GBL_IFS_MISC_USEC_DUR_S        10
-#define        AR5K_DCU_GBL_IFS_MISC_DCU_ARB_DELAY     0x00300000      /* DCU Arbiter delay mask */
-#define AR5K_DCU_GBL_IFS_MISC_SIFS_CNT_RST     0x00400000      /* SIFS cnt reset policy (?) */
-#define AR5K_DCU_GBL_IFS_MISC_AIFS_CNT_RST     0x00800000      /* AIFS cnt reset policy (?) */
-#define AR5K_DCU_GBL_IFS_MISC_RND_LFSR_SL_DIS  0x01000000      /* Disable random LFSR slice */
-
-/*
- * DCU frame prefetch control register
- */
-#define AR5K_DCU_FP                    0x1230                  /* Register Address */
-#define AR5K_DCU_FP_NOBURST_DCU_EN     0x00000001      /* Enable non-burst prefetch on DCU (?) */
-#define AR5K_DCU_FP_NOBURST_EN         0x00000010      /* Enable non-burst prefetch (?) */
-#define AR5K_DCU_FP_BURST_DCU_EN       0x00000020      /* Enable burst prefetch on DCU (?) */
-
-/*
- * DCU transmit pause control/status register
- */
-#define AR5K_DCU_TXP           0x1270                  /* Register Address */
-#define        AR5K_DCU_TXP_M          0x000003ff      /* Tx pause mask */
-#define        AR5K_DCU_TXP_STATUS     0x00010000      /* Tx pause status */
-
-/*
- * DCU transmit filter table 0 (32 entries)
- * each entry contains a 32bit slice of the
- * 128bit tx filter for each DCU (4 slices per DCU)
- */
-#define AR5K_DCU_TX_FILTER_0_BASE      0x1038
-#define        AR5K_DCU_TX_FILTER_0(_n)        (AR5K_DCU_TX_FILTER_0_BASE + (_n * 64))
-
-/*
- * DCU transmit filter table 1 (16 entries)
- */
-#define AR5K_DCU_TX_FILTER_1_BASE      0x103c
-#define        AR5K_DCU_TX_FILTER_1(_n)        (AR5K_DCU_TX_FILTER_1_BASE + (_n * 64))
-
-/*
- * DCU clear transmit filter register
- */
-#define AR5K_DCU_TX_FILTER_CLR 0x143c
-
-/*
- * DCU set transmit filter register
- */
-#define AR5K_DCU_TX_FILTER_SET 0x147c
-
-/*
- * Reset control register
- */
-#define AR5K_RESET_CTL         0x4000                  /* Register Address */
-#define AR5K_RESET_CTL_PCU     0x00000001      /* Protocol Control Unit reset */
-#define AR5K_RESET_CTL_DMA     0x00000002      /* DMA (Rx/Tx) reset [5210] */
-#define        AR5K_RESET_CTL_BASEBAND 0x00000002      /* Baseband reset [5211+] */
-#define AR5K_RESET_CTL_MAC     0x00000004      /* MAC reset (PCU+Baseband ?) [5210] */
-#define AR5K_RESET_CTL_PHY     0x00000008      /* PHY reset [5210] */
-#define AR5K_RESET_CTL_PCI     0x00000010      /* PCI Core reset (interrupts etc) */
-
-/*
- * Sleep control register
- */
-#define AR5K_SLEEP_CTL                 0x4004                  /* Register Address */
-#define AR5K_SLEEP_CTL_SLDUR           0x0000ffff      /* Sleep duration mask */
-#define AR5K_SLEEP_CTL_SLDUR_S         0
-#define AR5K_SLEEP_CTL_SLE             0x00030000      /* Sleep enable mask */
-#define AR5K_SLEEP_CTL_SLE_S           16
-#define AR5K_SLEEP_CTL_SLE_WAKE                0x00000000      /* Force chip awake */
-#define AR5K_SLEEP_CTL_SLE_SLP         0x00010000      /* Force chip sleep */
-#define AR5K_SLEEP_CTL_SLE_ALLOW       0x00020000      /* Normal sleep policy */
-#define AR5K_SLEEP_CTL_SLE_UNITS       0x00000008      /* [5211+] */
-#define AR5K_SLEEP_CTL_DUR_TIM_POL     0x00040000      /* Sleep duration timing policy */
-#define AR5K_SLEEP_CTL_DUR_WRITE_POL   0x00080000      /* Sleep duration write policy */
-#define AR5K_SLEEP_CTL_SLE_POL         0x00100000      /* Sleep policy mode */
-
-/*
- * Interrupt pending register
- */
-#define AR5K_INTPEND   0x4008
-#define AR5K_INTPEND_M 0x00000001
-
-/*
- * Sleep force register
- */
-#define AR5K_SFR       0x400c
-#define AR5K_SFR_EN    0x00000001
-
-/*
- * PCI configuration register
- * TODO: Fix LED stuff
- */
-#define AR5K_PCICFG                    0x4010                  /* Register Address */
-#define AR5K_PCICFG_EEAE               0x00000001      /* Eeprom access enable [5210] */
-#define AR5K_PCICFG_SLEEP_CLOCK_EN     0x00000002      /* Enable sleep clock */
-#define AR5K_PCICFG_CLKRUNEN           0x00000004      /* CLKRUN enable [5211+] */
-#define AR5K_PCICFG_EESIZE             0x00000018      /* Mask for EEPROM size [5211+] */
-#define AR5K_PCICFG_EESIZE_S           3
-#define AR5K_PCICFG_EESIZE_4K          0               /* 4K */
-#define AR5K_PCICFG_EESIZE_8K          1               /* 8K */
-#define AR5K_PCICFG_EESIZE_16K         2               /* 16K */
-#define AR5K_PCICFG_EESIZE_FAIL                3               /* Failed to get size [5211+] */
-#define AR5K_PCICFG_LED                        0x00000060      /* Led status [5211+] */
-#define AR5K_PCICFG_LED_NONE           0x00000000      /* Default [5211+] */
-#define AR5K_PCICFG_LED_PEND           0x00000020      /* Scan / Auth pending */
-#define AR5K_PCICFG_LED_ASSOC          0x00000040      /* Associated */
-#define        AR5K_PCICFG_BUS_SEL             0x00000380      /* Mask for "bus select" [5211+] (?) */
-#define AR5K_PCICFG_CBEFIX_DIS         0x00000400      /* Disable CBE fix */
-#define AR5K_PCICFG_SL_INTEN           0x00000800      /* Enable interrupts when asleep */
-#define AR5K_PCICFG_LED_BCTL           0x00001000      /* Led blink (?) [5210] */
-#define AR5K_PCICFG_RETRY_FIX          0x00001000      /* Enable pci core retry fix */
-#define AR5K_PCICFG_SL_INPEN           0x00002000      /* Sleep even whith pending interrupts*/
-#define AR5K_PCICFG_SPWR_DN            0x00010000      /* Mask for power status */
-#define AR5K_PCICFG_LEDMODE            0x000e0000      /* Ledmode [5211+] */
-#define AR5K_PCICFG_LEDMODE_PROP       0x00000000      /* Blink on standard traffic [5211+] */
-#define AR5K_PCICFG_LEDMODE_PROM       0x00020000      /* Default mode (blink on any traffic) [5211+] */
-#define AR5K_PCICFG_LEDMODE_PWR                0x00040000      /* Some other blinking mode  (?) [5211+] */
-#define AR5K_PCICFG_LEDMODE_RAND       0x00060000      /* Random blinking (?) [5211+] */
-#define AR5K_PCICFG_LEDBLINK           0x00700000      /* Led blink rate */
-#define AR5K_PCICFG_LEDBLINK_S         20
-#define AR5K_PCICFG_LEDSLOW            0x00800000      /* Slowest led blink rate [5211+] */
-#define AR5K_PCICFG_LEDSTATE                           \
-       (AR5K_PCICFG_LED | AR5K_PCICFG_LEDMODE |        \
-       AR5K_PCICFG_LEDBLINK | AR5K_PCICFG_LEDSLOW)
-#define        AR5K_PCICFG_SLEEP_CLOCK_RATE    0x03000000      /* Sleep clock rate */
-#define        AR5K_PCICFG_SLEEP_CLOCK_RATE_S  24
-
-/*
- * "General Purpose Input/Output" (GPIO) control register
- *
- * I'm not sure about this but after looking at the code
- * for all chipsets here is what i got.
- *
- * We have 6 GPIOs (pins), each GPIO has 4 modes (2 bits)
- * Mode 0 -> always input
- * Mode 1 -> output when GPIODO for this GPIO is set to 0
- * Mode 2 -> output when GPIODO for this GPIO is set to 1
- * Mode 3 -> always output
- *
- * For more infos check out get_gpio/set_gpio and
- * set_gpio_input/set_gpio_output functs.
- * For more infos on gpio interrupt check out set_gpio_intr.
- */
-#define AR5K_NUM_GPIO  6
-
-#define AR5K_GPIOCR            0x4014                          /* Register Address */
-#define AR5K_GPIOCR_INT_ENA    0x00008000              /* Enable GPIO interrupt */
-#define AR5K_GPIOCR_INT_SELL   0x00000000              /* Generate interrupt when pin is low */
-#define AR5K_GPIOCR_INT_SELH   0x00010000              /* Generate interrupt when pin is high */
-#define AR5K_GPIOCR_IN(n)      (0 << ((n) * 2))        /* Mode 0 for pin n */
-#define AR5K_GPIOCR_OUT0(n)    (1 << ((n) * 2))        /* Mode 1 for pin n */
-#define AR5K_GPIOCR_OUT1(n)    (2 << ((n) * 2))        /* Mode 2 for pin n */
-#define AR5K_GPIOCR_OUT(n)     (3 << ((n) * 2))        /* Mode 3 for pin n */
-#define AR5K_GPIOCR_INT_SEL(n) ((n) << 12)             /* Interrupt for GPIO pin n */
-
-/*
- * "General Purpose Input/Output" (GPIO) data output register
- */
-#define AR5K_GPIODO    0x4018
-
-/*
- * "General Purpose Input/Output" (GPIO) data input register
- */
-#define AR5K_GPIODI    0x401c
-#define AR5K_GPIODI_M  0x0000002f
-
-/*
- * Silicon revision register
- */
-#define AR5K_SREV              0x4020                  /* Register Address */
-#define AR5K_SREV_REV          0x0000000f      /* Mask for revision */
-#define AR5K_SREV_REV_S                0
-#define AR5K_SREV_VER          0x000000ff      /* Mask for version */
-#define AR5K_SREV_VER_S                4
-
-/*
- * TXE write posting register
- */
-#define        AR5K_TXEPOST    0x4028
-
-/*
- * QCU sleep mask
- */
-#define        AR5K_QCU_SLEEP_MASK     0x402c
-
-/* 0x4068 is compression buffer configuration
- * register on 5414 and pm configuration register
- * on 5424 and newer pci-e chips. */
-
-/*
- * Compression buffer configuration
- * register (enable/disable) [5414]
- */
-#define AR5K_5414_CBCFG                0x4068
-#define AR5K_5414_CBCFG_BUF_DIS        0x10    /* Disable buffer */
-
-/*
- * PCI-E Power managment configuration
- * and status register [5424+]
- */
-#define        AR5K_PCIE_PM_CTL                0x4068                  /* Register address */
-/* Only 5424 */
-#define        AR5K_PCIE_PM_CTL_L1_WHEN_D2     0x00000001      /* enable PCIe core enter L1
-                                                       when d2_sleep_en is asserted */
-#define        AR5K_PCIE_PM_CTL_L0_L0S_CLEAR   0x00000002      /* Clear L0 and L0S counters */
-#define        AR5K_PCIE_PM_CTL_L0_L0S_EN      0x00000004      /* Start L0 nd L0S counters */
-#define        AR5K_PCIE_PM_CTL_LDRESET_EN     0x00000008      /* Enable reset when link goes
-                                                       down */
-/* Wake On Wireless */
-#define        AR5K_PCIE_PM_CTL_PME_EN         0x00000010      /* PME Enable */
-#define        AR5K_PCIE_PM_CTL_AUX_PWR_DET    0x00000020      /* Aux power detect */
-#define        AR5K_PCIE_PM_CTL_PME_CLEAR      0x00000040      /* Clear PME */
-#define        AR5K_PCIE_PM_CTL_PSM_D0         0x00000080
-#define        AR5K_PCIE_PM_CTL_PSM_D1         0x00000100
-#define        AR5K_PCIE_PM_CTL_PSM_D2         0x00000200
-#define        AR5K_PCIE_PM_CTL_PSM_D3         0x00000400
-
-/*
- * PCI-E Workaround enable register
- */
-#define        AR5K_PCIE_WAEN  0x407c
-
-/*
- * PCI-E Serializer/Desirializer
- * registers
- */
-#define        AR5K_PCIE_SERDES        0x4080
-#define        AR5K_PCIE_SERDES_RESET  0x4084
-
-/*====EEPROM REGISTERS====*/
-
-/*
- * EEPROM access registers
- *
- * Here we got a difference between 5210/5211-12
- * read data register for 5210 is at 0x6800 and
- * status register is at 0x6c00. There is also
- * no eeprom command register on 5210 and the
- * offsets are different.
- *
- * To read eeprom data for a specific offset:
- * 5210 - enable eeprom access (AR5K_PCICFG_EEAE)
- *        read AR5K_EEPROM_BASE +(4 * offset)
- *        check the eeprom status register
- *        and read eeprom data register.
- *
- * 5211 - write offset to AR5K_EEPROM_BASE
- * 5212   write AR5K_EEPROM_CMD_READ on AR5K_EEPROM_CMD
- *        check the eeprom status register
- *        and read eeprom data register.
- *
- * To write eeprom data for a specific offset:
- * 5210 - enable eeprom access (AR5K_PCICFG_EEAE)
- *        write data to AR5K_EEPROM_BASE +(4 * offset)
- *        check the eeprom status register
- * 5211 - write AR5K_EEPROM_CMD_RESET on AR5K_EEPROM_CMD
- * 5212   write offset to AR5K_EEPROM_BASE
- *        write data to data register
- *       write AR5K_EEPROM_CMD_WRITE on AR5K_EEPROM_CMD
- *        check the eeprom status register
- *
- * For more infos check eeprom_* functs and the ar5k.c
- * file posted in madwifi-devel mailing list.
- * http://sourceforge.net/mailarchive/message.php?msg_id=8966525
- *
- */
-#define AR5K_EEPROM_BASE       0x6000
-
-/*
- * EEPROM data register
- */
-#define AR5K_EEPROM_DATA_5211  0x6004
-#define AR5K_EEPROM_DATA_5210  0x6800
-#define        AR5K_EEPROM_DATA        (ah->ah_version == AR5K_AR5210 ? \
-                               AR5K_EEPROM_DATA_5210 : AR5K_EEPROM_DATA_5211)
-
-/*
- * EEPROM command register
- */
-#define AR5K_EEPROM_CMD                0x6008                  /* Register Addres */
-#define AR5K_EEPROM_CMD_READ   0x00000001      /* EEPROM read */
-#define AR5K_EEPROM_CMD_WRITE  0x00000002      /* EEPROM write */
-#define AR5K_EEPROM_CMD_RESET  0x00000004      /* EEPROM reset */
-
-/*
- * EEPROM status register
- */
-#define AR5K_EEPROM_STAT_5210  0x6c00                  /* Register Address [5210] */
-#define AR5K_EEPROM_STAT_5211  0x600c                  /* Register Address [5211+] */
-#define        AR5K_EEPROM_STATUS      (ah->ah_version == AR5K_AR5210 ? \
-                               AR5K_EEPROM_STAT_5210 : AR5K_EEPROM_STAT_5211)
-#define AR5K_EEPROM_STAT_RDERR 0x00000001      /* EEPROM read failed */
-#define AR5K_EEPROM_STAT_RDDONE        0x00000002      /* EEPROM read successful */
-#define AR5K_EEPROM_STAT_WRERR 0x00000004      /* EEPROM write failed */
-#define AR5K_EEPROM_STAT_WRDONE        0x00000008      /* EEPROM write successful */
-
-/*
- * EEPROM config register
- */
-#define AR5K_EEPROM_CFG                        0x6010                  /* Register Addres */
-#define AR5K_EEPROM_CFG_SIZE           0x00000003              /* Size determination override */
-#define AR5K_EEPROM_CFG_SIZE_AUTO      0
-#define AR5K_EEPROM_CFG_SIZE_4KBIT     1
-#define AR5K_EEPROM_CFG_SIZE_8KBIT     2
-#define AR5K_EEPROM_CFG_SIZE_16KBIT    3
-#define AR5K_EEPROM_CFG_WR_WAIT_DIS    0x00000004      /* Disable write wait */
-#define AR5K_EEPROM_CFG_CLK_RATE       0x00000018      /* Clock rate */
-#define AR5K_EEPROM_CFG_CLK_RATE_S             3
-#define AR5K_EEPROM_CFG_CLK_RATE_156KHZ        0
-#define AR5K_EEPROM_CFG_CLK_RATE_312KHZ        1
-#define AR5K_EEPROM_CFG_CLK_RATE_625KHZ        2
-#define AR5K_EEPROM_CFG_PROT_KEY       0x00ffff00      /* Protection key */
-#define AR5K_EEPROM_CFG_PROT_KEY_S     8
-#define AR5K_EEPROM_CFG_LIND_EN                0x01000000      /* Enable length indicator (?) */
-
-
-/*
- * TODO: Wake On Wireless registers
- * Range 0x7000 - 0x7ce0
- */
-
-/*
- * Protocol Control Unit (PCU) registers
- */
-/*
- * Used for checking initial register writes
- * during channel reset (see reset func)
- */
-#define AR5K_PCU_MIN   0x8000
-#define AR5K_PCU_MAX   0x8fff
-
-/*
- * First station id register (Lower 32 bits of MAC address)
- */
-#define AR5K_STA_ID0           0x8000
-#define        AR5K_STA_ID0_ARRD_L32   0xffffffff
-
-/*
- * Second station id register (Upper 16 bits of MAC address + PCU settings)
- */
-#define AR5K_STA_ID1                   0x8004                  /* Register Address */
-#define        AR5K_STA_ID1_ADDR_U16           0x0000ffff      /* Upper 16 bits of MAC addres */
-#define AR5K_STA_ID1_AP                        0x00010000      /* Set AP mode */
-#define AR5K_STA_ID1_ADHOC             0x00020000      /* Set Ad-Hoc mode */
-#define AR5K_STA_ID1_PWR_SV            0x00040000      /* Power save reporting */
-#define AR5K_STA_ID1_NO_KEYSRCH                0x00080000      /* No key search */
-#define AR5K_STA_ID1_NO_PSPOLL         0x00100000      /* No power save polling [5210] */
-#define AR5K_STA_ID1_PCF_5211          0x00100000      /* Enable PCF on [5211+] */
-#define AR5K_STA_ID1_PCF_5210          0x00200000      /* Enable PCF on [5210]*/
-#define        AR5K_STA_ID1_PCF                (ah->ah_version == AR5K_AR5210 ? \
-                                       AR5K_STA_ID1_PCF_5210 : AR5K_STA_ID1_PCF_5211)
-#define AR5K_STA_ID1_DEFAULT_ANTENNA   0x00200000      /* Use default antenna */
-#define AR5K_STA_ID1_DESC_ANTENNA      0x00400000      /* Update antenna from descriptor */
-#define AR5K_STA_ID1_RTS_DEF_ANTENNA   0x00800000      /* Use default antenna for RTS */
-#define AR5K_STA_ID1_ACKCTS_6MB                0x01000000      /* Use 6Mbit/s for ACK/CTS */
-#define AR5K_STA_ID1_BASE_RATE_11B     0x02000000      /* Use 11b base rate for ACK/CTS [5211+] */
-#define AR5K_STA_ID1_SELFGEN_DEF_ANT   0x04000000      /* Use def. antenna for self generated frames */
-#define AR5K_STA_ID1_CRYPT_MIC_EN      0x08000000      /* Enable MIC */
-#define AR5K_STA_ID1_KEYSRCH_MODE      0x10000000      /* Look up key when key id != 0 */
-#define AR5K_STA_ID1_PRESERVE_SEQ_NUM  0x20000000      /* Preserve sequence number */
-#define AR5K_STA_ID1_CBCIV_ENDIAN      0x40000000      /* ??? */
-#define AR5K_STA_ID1_KEYSRCH_MCAST     0x80000000      /* Do key cache search for mcast frames */
-
-/*
- * First BSSID register (MAC address, lower 32bits)
- */
-#define AR5K_BSS_ID0   0x8008
-
-/*
- * Second BSSID register (MAC address in upper 16 bits)
- *
- * AID: Association ID
- */
-#define AR5K_BSS_ID1           0x800c
-#define AR5K_BSS_ID1_AID       0xffff0000
-#define AR5K_BSS_ID1_AID_S     16
-
-/*
- * Backoff slot time register
- */
-#define AR5K_SLOT_TIME 0x8010
-
-/*
- * ACK/CTS timeout register
- */
-#define AR5K_TIME_OUT          0x8014                  /* Register Address */
-#define AR5K_TIME_OUT_ACK      0x00001fff      /* ACK timeout mask */
-#define AR5K_TIME_OUT_ACK_S    0
-#define AR5K_TIME_OUT_CTS      0x1fff0000      /* CTS timeout mask */
-#define AR5K_TIME_OUT_CTS_S    16
-
-/*
- * RSSI threshold register
- */
-#define AR5K_RSSI_THR                  0x8018          /* Register Address */
-#define AR5K_RSSI_THR_M                        0x000000ff      /* Mask for RSSI threshold [5211+] */
-#define AR5K_RSSI_THR_BMISS_5210       0x00000700      /* Mask for Beacon Missed threshold [5210] */
-#define AR5K_RSSI_THR_BMISS_5210_S     8
-#define AR5K_RSSI_THR_BMISS_5211       0x0000ff00      /* Mask for Beacon Missed threshold [5211+] */
-#define AR5K_RSSI_THR_BMISS_5211_S     8
-#define        AR5K_RSSI_THR_BMISS             (ah->ah_version == AR5K_AR5210 ? \
-                                       AR5K_RSSI_THR_BMISS_5210 : AR5K_RSSI_THR_BMISS_5211)
-#define        AR5K_RSSI_THR_BMISS_S           8
-
-/*
- * 5210 has more PCU registers because there is no QCU/DCU
- * so queue parameters are set here, this way a lot common
- * registers have different address for 5210. To make things
- * easier we define a macro based on ah->ah_version for common
- * registers with different addresses and common flags.
- */
-
-/*
- * Retry limit register
- *
- * Retry limit register for 5210 (no QCU/DCU so it's done in PCU)
- */
-#define AR5K_NODCU_RETRY_LMT           0x801c                  /* Register Address */
-#define AR5K_NODCU_RETRY_LMT_SH_RETRY  0x0000000f      /* Short retry limit mask */
-#define AR5K_NODCU_RETRY_LMT_SH_RETRY_S        0
-#define AR5K_NODCU_RETRY_LMT_LG_RETRY  0x000000f0      /* Long retry mask */
-#define AR5K_NODCU_RETRY_LMT_LG_RETRY_S        4
-#define AR5K_NODCU_RETRY_LMT_SSH_RETRY 0x00003f00      /* Station short retry limit mask */
-#define AR5K_NODCU_RETRY_LMT_SSH_RETRY_S       8
-#define AR5K_NODCU_RETRY_LMT_SLG_RETRY 0x000fc000      /* Station long retry limit mask */
-#define AR5K_NODCU_RETRY_LMT_SLG_RETRY_S       14
-#define AR5K_NODCU_RETRY_LMT_CW_MIN    0x3ff00000      /* Minimum contention window mask */
-#define AR5K_NODCU_RETRY_LMT_CW_MIN_S  20
-
-/*
- * Transmit latency register
- */
-#define AR5K_USEC_5210                 0x8020                  /* Register Address [5210] */
-#define AR5K_USEC_5211                 0x801c                  /* Register Address [5211+] */
-#define AR5K_USEC                      (ah->ah_version == AR5K_AR5210 ? \
-                                       AR5K_USEC_5210 : AR5K_USEC_5211)
-#define AR5K_USEC_1                    0x0000007f      /* clock cycles for 1us */
-#define AR5K_USEC_1_S                  0
-#define AR5K_USEC_32                   0x00003f80      /* clock cycles for 1us while on 32Mhz clock */
-#define AR5K_USEC_32_S                 7
-#define AR5K_USEC_TX_LATENCY_5211      0x007fc000
-#define AR5K_USEC_TX_LATENCY_5211_S    14
-#define AR5K_USEC_RX_LATENCY_5211      0x1f800000
-#define AR5K_USEC_RX_LATENCY_5211_S    23
-#define AR5K_USEC_TX_LATENCY_5210      0x000fc000      /* also for 5311 */
-#define AR5K_USEC_TX_LATENCY_5210_S    14
-#define AR5K_USEC_RX_LATENCY_5210      0x03f00000      /* also for 5311 */
-#define AR5K_USEC_RX_LATENCY_5210_S    20
-
-/*
- * PCU beacon control register
- */
-#define AR5K_BEACON_5210       0x8024                  /*Register Address [5210] */
-#define AR5K_BEACON_5211       0x8020                  /*Register Address [5211+] */
-#define AR5K_BEACON            (ah->ah_version == AR5K_AR5210 ? \
-                               AR5K_BEACON_5210 : AR5K_BEACON_5211)
-#define AR5K_BEACON_PERIOD     0x0000ffff      /* Mask for beacon period */
-#define AR5K_BEACON_PERIOD_S   0
-#define AR5K_BEACON_TIM                0x007f0000      /* Mask for TIM offset */
-#define AR5K_BEACON_TIM_S      16
-#define AR5K_BEACON_ENABLE     0x00800000      /* Enable beacons */
-#define AR5K_BEACON_RESET_TSF  0x01000000      /* Force TSF reset */
-
-/*
- * CFP period register
- */
-#define AR5K_CFP_PERIOD_5210   0x8028
-#define AR5K_CFP_PERIOD_5211   0x8024
-#define AR5K_CFP_PERIOD                (ah->ah_version == AR5K_AR5210 ? \
-                               AR5K_CFP_PERIOD_5210 : AR5K_CFP_PERIOD_5211)
-
-/*
- * Next beacon time register
- */
-#define AR5K_TIMER0_5210       0x802c
-#define AR5K_TIMER0_5211       0x8028
-#define AR5K_TIMER0            (ah->ah_version == AR5K_AR5210 ? \
-                               AR5K_TIMER0_5210 : AR5K_TIMER0_5211)
-
-/*
- * Next DMA beacon alert register
- */
-#define AR5K_TIMER1_5210       0x8030
-#define AR5K_TIMER1_5211       0x802c
-#define AR5K_TIMER1            (ah->ah_version == AR5K_AR5210 ? \
-                               AR5K_TIMER1_5210 : AR5K_TIMER1_5211)
-
-/*
- * Next software beacon alert register
- */
-#define AR5K_TIMER2_5210       0x8034
-#define AR5K_TIMER2_5211       0x8030
-#define AR5K_TIMER2            (ah->ah_version == AR5K_AR5210 ? \
-                               AR5K_TIMER2_5210 : AR5K_TIMER2_5211)
-
-/*
- * Next ATIM window time register
- */
-#define AR5K_TIMER3_5210       0x8038
-#define AR5K_TIMER3_5211       0x8034
-#define AR5K_TIMER3            (ah->ah_version == AR5K_AR5210 ? \
-                               AR5K_TIMER3_5210 : AR5K_TIMER3_5211)
-
-
-/*
- * 5210 First inter frame spacing register (IFS)
- */
-#define AR5K_IFS0              0x8040
-#define AR5K_IFS0_SIFS         0x000007ff
-#define AR5K_IFS0_SIFS_S       0
-#define AR5K_IFS0_DIFS         0x007ff800
-#define AR5K_IFS0_DIFS_S       11
-
-/*
- * 5210 Second inter frame spacing register (IFS)
- */
-#define AR5K_IFS1              0x8044
-#define AR5K_IFS1_PIFS         0x00000fff
-#define AR5K_IFS1_PIFS_S       0
-#define AR5K_IFS1_EIFS         0x03fff000
-#define AR5K_IFS1_EIFS_S       12
-#define AR5K_IFS1_CS_EN                0x04000000
-
-
-/*
- * CFP duration register
- */
-#define AR5K_CFP_DUR_5210      0x8048
-#define AR5K_CFP_DUR_5211      0x8038
-#define AR5K_CFP_DUR           (ah->ah_version == AR5K_AR5210 ? \
-                               AR5K_CFP_DUR_5210 : AR5K_CFP_DUR_5211)
-
-/*
- * Receive filter register
- */
-#define AR5K_RX_FILTER_5210    0x804c                  /* Register Address [5210] */
-#define AR5K_RX_FILTER_5211    0x803c                  /* Register Address [5211+] */
-#define AR5K_RX_FILTER         (ah->ah_version == AR5K_AR5210 ? \
-                               AR5K_RX_FILTER_5210 : AR5K_RX_FILTER_5211)
-#define        AR5K_RX_FILTER_UCAST    0x00000001      /* Don't filter unicast frames */
-#define        AR5K_RX_FILTER_MCAST    0x00000002      /* Don't filter multicast frames */
-#define        AR5K_RX_FILTER_BCAST    0x00000004      /* Don't filter broadcast frames */
-#define        AR5K_RX_FILTER_CONTROL  0x00000008      /* Don't filter control frames */
-#define        AR5K_RX_FILTER_BEACON   0x00000010      /* Don't filter beacon frames */
-#define        AR5K_RX_FILTER_PROM     0x00000020      /* Set promiscuous mode */
-#define        AR5K_RX_FILTER_XRPOLL   0x00000040      /* Don't filter XR poll frame [5212+] */
-#define        AR5K_RX_FILTER_PROBEREQ 0x00000080      /* Don't filter probe requests [5212+] */
-#define        AR5K_RX_FILTER_PHYERR_5212      0x00000100      /* Don't filter phy errors [5212+] */
-#define        AR5K_RX_FILTER_RADARERR_5212    0x00000200      /* Don't filter phy radar errors [5212+] */
-#define AR5K_RX_FILTER_PHYERR_5211     0x00000040      /* [5211] */
-#define AR5K_RX_FILTER_RADARERR_5211   0x00000080      /* [5211] */
-#define AR5K_RX_FILTER_PHYERR  \
-       ((ah->ah_version == AR5K_AR5211 ? \
-       AR5K_RX_FILTER_PHYERR_5211 : AR5K_RX_FILTER_PHYERR_5212))
-#define        AR5K_RX_FILTER_RADARERR \
-       ((ah->ah_version == AR5K_AR5211 ? \
-       AR5K_RX_FILTER_RADARERR_5211 : AR5K_RX_FILTER_RADARERR_5212))
-
-/*
- * Multicast filter register (lower 32 bits)
- */
-#define AR5K_MCAST_FILTER0_5210        0x8050
-#define AR5K_MCAST_FILTER0_5211        0x8040
-#define AR5K_MCAST_FILTER0     (ah->ah_version == AR5K_AR5210 ? \
-                               AR5K_MCAST_FILTER0_5210 : AR5K_MCAST_FILTER0_5211)
-
-/*
- * Multicast filter register (higher 16 bits)
- */
-#define AR5K_MCAST_FILTER1_5210        0x8054
-#define AR5K_MCAST_FILTER1_5211        0x8044
-#define AR5K_MCAST_FILTER1     (ah->ah_version == AR5K_AR5210 ? \
-                               AR5K_MCAST_FILTER1_5210 : AR5K_MCAST_FILTER1_5211)
-
-
-/*
- * Transmit mask register (lower 32 bits) [5210]
- */
-#define AR5K_TX_MASK0  0x8058
-
-/*
- * Transmit mask register (higher 16 bits) [5210]
- */
-#define AR5K_TX_MASK1  0x805c
-
-/*
- * Clear transmit mask [5210]
- */
-#define AR5K_CLR_TMASK 0x8060
-
-/*
- * Trigger level register (before transmission) [5210]
- */
-#define AR5K_TRIG_LVL  0x8064
-
-
-/*
- * PCU control register
- *
- * Only DIS_RX is used in the code, the rest i guess are
- * for tweaking/diagnostics.
- */
-#define AR5K_DIAG_SW_5210              0x8068                  /* Register Address [5210] */
-#define AR5K_DIAG_SW_5211              0x8048                  /* Register Address [5211+] */
-#define AR5K_DIAG_SW                   (ah->ah_version == AR5K_AR5210 ? \
-                                       AR5K_DIAG_SW_5210 : AR5K_DIAG_SW_5211)
-#define AR5K_DIAG_SW_DIS_WEP_ACK       0x00000001      /* Disable ACKs if WEP key is invalid */
-#define AR5K_DIAG_SW_DIS_ACK           0x00000002      /* Disable ACKs */
-#define AR5K_DIAG_SW_DIS_CTS           0x00000004      /* Disable CTSs */
-#define AR5K_DIAG_SW_DIS_ENC           0x00000008      /* Disable encryption */
-#define AR5K_DIAG_SW_DIS_DEC           0x00000010      /* Disable decryption */
-#define AR5K_DIAG_SW_DIS_TX            0x00000020      /* Disable transmit [5210] */
-#define AR5K_DIAG_SW_DIS_RX_5210       0x00000040      /* Disable recieve */
-#define AR5K_DIAG_SW_DIS_RX_5211       0x00000020
-#define        AR5K_DIAG_SW_DIS_RX             (ah->ah_version == AR5K_AR5210 ? \
-                                       AR5K_DIAG_SW_DIS_RX_5210 : AR5K_DIAG_SW_DIS_RX_5211)
-#define AR5K_DIAG_SW_LOOP_BACK_5210    0x00000080      /* Loopback (i guess it goes with DIS_TX) [5210] */
-#define AR5K_DIAG_SW_LOOP_BACK_5211    0x00000040
-#define AR5K_DIAG_SW_LOOP_BACK         (ah->ah_version == AR5K_AR5210 ? \
-                                       AR5K_DIAG_SW_LOOP_BACK_5210 : AR5K_DIAG_SW_LOOP_BACK_5211)
-#define AR5K_DIAG_SW_CORR_FCS_5210     0x00000100      /* Corrupted FCS */
-#define AR5K_DIAG_SW_CORR_FCS_5211     0x00000080
-#define AR5K_DIAG_SW_CORR_FCS          (ah->ah_version == AR5K_AR5210 ? \
-                                       AR5K_DIAG_SW_CORR_FCS_5210 : AR5K_DIAG_SW_CORR_FCS_5211)
-#define AR5K_DIAG_SW_CHAN_INFO_5210    0x00000200      /* Dump channel info */
-#define AR5K_DIAG_SW_CHAN_INFO_5211    0x00000100
-#define AR5K_DIAG_SW_CHAN_INFO         (ah->ah_version == AR5K_AR5210 ? \
-                                       AR5K_DIAG_SW_CHAN_INFO_5210 : AR5K_DIAG_SW_CHAN_INFO_5211)
-#define AR5K_DIAG_SW_EN_SCRAM_SEED_5210        0x00000400      /* Enable fixed scrambler seed */
-#define AR5K_DIAG_SW_EN_SCRAM_SEED_5211        0x00000200
-#define AR5K_DIAG_SW_EN_SCRAM_SEED     (ah->ah_version == AR5K_AR5210 ? \
-                                       AR5K_DIAG_SW_EN_SCRAM_SEED_5210 : AR5K_DIAG_SW_EN_SCRAM_SEED_5211)
-#define AR5K_DIAG_SW_ECO_ENABLE                0x00000400      /* [5211+] */
-#define AR5K_DIAG_SW_SCVRAM_SEED       0x0003f800      /* [5210] */
-#define AR5K_DIAG_SW_SCRAM_SEED_M      0x0001fc00      /* Scrambler seed mask */
-#define AR5K_DIAG_SW_SCRAM_SEED_S      10
-#define AR5K_DIAG_SW_DIS_SEQ_INC       0x00040000      /* Disable seqnum increment (?)[5210] */
-#define AR5K_DIAG_SW_FRAME_NV0_5210    0x00080000
-#define AR5K_DIAG_SW_FRAME_NV0_5211    0x00020000      /* Accept frames of non-zero protocol number */
-#define        AR5K_DIAG_SW_FRAME_NV0          (ah->ah_version == AR5K_AR5210 ? \
-                                       AR5K_DIAG_SW_FRAME_NV0_5210 : AR5K_DIAG_SW_FRAME_NV0_5211)
-#define AR5K_DIAG_SW_OBSPT_M           0x000c0000      /* Observation point select (?) */
-#define AR5K_DIAG_SW_OBSPT_S           18
-#define AR5K_DIAG_SW_RX_CLEAR_HIGH     0x0010000       /* Force RX Clear high */
-#define AR5K_DIAG_SW_IGNORE_CARR_SENSE 0x0020000       /* Ignore virtual carrier sense */
-#define AR5K_DIAG_SW_CHANEL_IDLE_HIGH  0x0040000       /* Force channel idle high */
-#define AR5K_DIAG_SW_PHEAR_ME          0x0080000       /* ??? */
-
-/*
- * TSF (clock) register (lower 32 bits)
- */
-#define AR5K_TSF_L32_5210      0x806c
-#define AR5K_TSF_L32_5211      0x804c
-#define        AR5K_TSF_L32            (ah->ah_version == AR5K_AR5210 ? \
-                               AR5K_TSF_L32_5210 : AR5K_TSF_L32_5211)
-
-/*
- * TSF (clock) register (higher 32 bits)
- */
-#define AR5K_TSF_U32_5210      0x8070
-#define AR5K_TSF_U32_5211      0x8050
-#define        AR5K_TSF_U32            (ah->ah_version == AR5K_AR5210 ? \
-                               AR5K_TSF_U32_5210 : AR5K_TSF_U32_5211)
-
-/*
- * Last beacon timestamp register (Read Only)
- */
-#define AR5K_LAST_TSTP 0x8080
-
-/*
- * ADDAC test register [5211+]
- */
-#define AR5K_ADDAC_TEST                        0x8054                  /* Register Address */
-#define AR5K_ADDAC_TEST_TXCONT                 0x00000001      /* Test continuous tx */
-#define AR5K_ADDAC_TEST_TST_MODE       0x00000002      /* Test mode */
-#define AR5K_ADDAC_TEST_LOOP_EN                0x00000004      /* Enable loop */
-#define AR5K_ADDAC_TEST_LOOP_LEN       0x00000008      /* Loop length (field) */
-#define AR5K_ADDAC_TEST_USE_U8         0x00004000      /* Use upper 8 bits */
-#define AR5K_ADDAC_TEST_MSB            0x00008000      /* State of MSB */
-#define AR5K_ADDAC_TEST_TRIG_SEL       0x00010000      /* Trigger select */
-#define AR5K_ADDAC_TEST_TRIG_PTY       0x00020000      /* Trigger polarity */
-#define AR5K_ADDAC_TEST_RXCONT         0x00040000      /* Continuous capture */
-#define AR5K_ADDAC_TEST_CAPTURE                0x00080000      /* Begin capture */
-#define AR5K_ADDAC_TEST_TST_ARM                0x00100000      /* ARM rx buffer for capture */
-
-/*
- * Default antenna register [5211+]
- */
-#define AR5K_DEFAULT_ANTENNA   0x8058
-
-/*
- * Frame control QoS mask register (?) [5211+]
- * (FC_QOS_MASK)
- */
-#define AR5K_FRAME_CTL_QOSM    0x805c
-
-/*
- * Seq mask register (?) [5211+]
- */
-#define AR5K_SEQ_MASK  0x8060
-
-/*
- * Retry count register [5210]
- */
-#define AR5K_RETRY_CNT         0x8084                  /* Register Address [5210] */
-#define AR5K_RETRY_CNT_SSH     0x0000003f      /* Station short retry count (?) */
-#define AR5K_RETRY_CNT_SLG     0x00000fc0      /* Station long retry count (?) */
-
-/*
- * Back-off status register [5210]
- */
-#define AR5K_BACKOFF           0x8088                  /* Register Address [5210] */
-#define AR5K_BACKOFF_CW                0x000003ff      /* Backoff Contention Window (?) */
-#define AR5K_BACKOFF_CNT       0x03ff0000      /* Backoff count (?) */
-
-
-
-/*
- * NAV register (current)
- */
-#define AR5K_NAV_5210          0x808c
-#define AR5K_NAV_5211          0x8084
-#define        AR5K_NAV                (ah->ah_version == AR5K_AR5210 ? \
-                               AR5K_NAV_5210 : AR5K_NAV_5211)
-
-/*
- * RTS success register
- */
-#define AR5K_RTS_OK_5210       0x8090
-#define AR5K_RTS_OK_5211       0x8088
-#define        AR5K_RTS_OK             (ah->ah_version == AR5K_AR5210 ? \
-                               AR5K_RTS_OK_5210 : AR5K_RTS_OK_5211)
-
-/*
- * RTS failure register
- */
-#define AR5K_RTS_FAIL_5210     0x8094
-#define AR5K_RTS_FAIL_5211     0x808c
-#define        AR5K_RTS_FAIL           (ah->ah_version == AR5K_AR5210 ? \
-                               AR5K_RTS_FAIL_5210 : AR5K_RTS_FAIL_5211)
-
-/*
- * ACK failure register
- */
-#define AR5K_ACK_FAIL_5210     0x8098
-#define AR5K_ACK_FAIL_5211     0x8090
-#define        AR5K_ACK_FAIL           (ah->ah_version == AR5K_AR5210 ? \
-                               AR5K_ACK_FAIL_5210 : AR5K_ACK_FAIL_5211)
-
-/*
- * FCS failure register
- */
-#define AR5K_FCS_FAIL_5210     0x809c
-#define AR5K_FCS_FAIL_5211     0x8094
-#define        AR5K_FCS_FAIL           (ah->ah_version == AR5K_AR5210 ? \
-                               AR5K_FCS_FAIL_5210 : AR5K_FCS_FAIL_5211)
-
-/*
- * Beacon count register
- */
-#define AR5K_BEACON_CNT_5210   0x80a0
-#define AR5K_BEACON_CNT_5211   0x8098
-#define        AR5K_BEACON_CNT         (ah->ah_version == AR5K_AR5210 ? \
-                               AR5K_BEACON_CNT_5210 : AR5K_BEACON_CNT_5211)
-
-
-/*===5212 Specific PCU registers===*/
-
-/*
- * Transmit power control register
- */
-#define AR5K_TPC                       0x80e8
-#define AR5K_TPC_ACK                   0x0000003f      /* ack frames */
-#define AR5K_TPC_ACK_S                 0
-#define AR5K_TPC_CTS                   0x00003f00      /* cts frames */
-#define AR5K_TPC_CTS_S                 8
-#define AR5K_TPC_CHIRP                 0x003f0000      /* chirp frames */
-#define AR5K_TPC_CHIRP_S               16
-#define AR5K_TPC_DOPPLER               0x0f000000      /* doppler chirp span */
-#define AR5K_TPC_DOPPLER_S             24
-
-/*
- * XR (eXtended Range) mode register
- */
-#define AR5K_XRMODE                    0x80c0                  /* Register Address */
-#define        AR5K_XRMODE_POLL_TYPE_M         0x0000003f      /* Mask for Poll type (?) */
-#define        AR5K_XRMODE_POLL_TYPE_S         0
-#define        AR5K_XRMODE_POLL_SUBTYPE_M      0x0000003c      /* Mask for Poll subtype (?) */
-#define        AR5K_XRMODE_POLL_SUBTYPE_S      2
-#define        AR5K_XRMODE_POLL_WAIT_ALL       0x00000080      /* Wait for poll */
-#define        AR5K_XRMODE_SIFS_DELAY          0x000fff00      /* Mask for SIFS delay */
-#define        AR5K_XRMODE_FRAME_HOLD_M        0xfff00000      /* Mask for frame hold (?) */
-#define        AR5K_XRMODE_FRAME_HOLD_S        20
-
-/*
- * XR delay register
- */
-#define AR5K_XRDELAY                   0x80c4                  /* Register Address */
-#define AR5K_XRDELAY_SLOT_DELAY_M      0x0000ffff      /* Mask for slot delay */
-#define AR5K_XRDELAY_SLOT_DELAY_S      0
-#define AR5K_XRDELAY_CHIRP_DELAY_M     0xffff0000      /* Mask for CHIRP data delay */
-#define AR5K_XRDELAY_CHIRP_DELAY_S     16
-
-/*
- * XR timeout register
- */
-#define AR5K_XRTIMEOUT                 0x80c8                  /* Register Address */
-#define AR5K_XRTIMEOUT_CHIRP_M         0x0000ffff      /* Mask for CHIRP timeout */
-#define AR5K_XRTIMEOUT_CHIRP_S         0
-#define AR5K_XRTIMEOUT_POLL_M          0xffff0000      /* Mask for Poll timeout */
-#define AR5K_XRTIMEOUT_POLL_S          16
-
-/*
- * XR chirp register
- */
-#define AR5K_XRCHIRP                   0x80cc                  /* Register Address */
-#define AR5K_XRCHIRP_SEND              0x00000001      /* Send CHIRP */
-#define AR5K_XRCHIRP_GAP               0xffff0000      /* Mask for CHIRP gap (?) */
-
-/*
- * XR stomp register
- */
-#define AR5K_XRSTOMP                   0x80d0                  /* Register Address */
-#define AR5K_XRSTOMP_TX                        0x00000001      /* Stomp Tx (?) */
-#define AR5K_XRSTOMP_RX                        0x00000002      /* Stomp Rx (?) */
-#define AR5K_XRSTOMP_TX_RSSI           0x00000004      /* Stomp Tx RSSI (?) */
-#define AR5K_XRSTOMP_TX_BSSID          0x00000008      /* Stomp Tx BSSID (?) */
-#define AR5K_XRSTOMP_DATA              0x00000010      /* Stomp data (?)*/
-#define AR5K_XRSTOMP_RSSI_THRES                0x0000ff00      /* Mask for XR RSSI threshold */
-
-/*
- * First enhanced sleep register
- */
-#define AR5K_SLEEP0                    0x80d4                  /* Register Address */
-#define AR5K_SLEEP0_NEXT_DTIM          0x0007ffff      /* Mask for next DTIM (?) */
-#define AR5K_SLEEP0_NEXT_DTIM_S                0
-#define AR5K_SLEEP0_ASSUME_DTIM                0x00080000      /* Assume DTIM */
-#define AR5K_SLEEP0_ENH_SLEEP_EN       0x00100000      /* Enable enchanced sleep control */
-#define AR5K_SLEEP0_CABTO              0xff000000      /* Mask for CAB Time Out */
-#define AR5K_SLEEP0_CABTO_S            24
-
-/*
- * Second enhanced sleep register
- */
-#define AR5K_SLEEP1                    0x80d8                  /* Register Address */
-#define AR5K_SLEEP1_NEXT_TIM           0x0007ffff      /* Mask for next TIM (?) */
-#define AR5K_SLEEP1_NEXT_TIM_S         0
-#define AR5K_SLEEP1_BEACON_TO          0xff000000      /* Mask for Beacon Time Out */
-#define AR5K_SLEEP1_BEACON_TO_S                24
-
-/*
- * Third enhanced sleep register
- */
-#define AR5K_SLEEP2                    0x80dc                  /* Register Address */
-#define AR5K_SLEEP2_TIM_PER            0x0000ffff      /* Mask for TIM period (?) */
-#define AR5K_SLEEP2_TIM_PER_S          0
-#define AR5K_SLEEP2_DTIM_PER           0xffff0000      /* Mask for DTIM period (?) */
-#define AR5K_SLEEP2_DTIM_PER_S         16
-
-/*
- * BSSID mask registers
- */
-#define AR5K_BSS_IDM0                  0x80e0  /* Upper bits */
-#define AR5K_BSS_IDM1                  0x80e4  /* Lower bits */
-
-/*
- * TX power control (TPC) register
- *
- * XXX: PCDAC steps (0.5dbm) or DBM ?
- *
- */
-#define AR5K_TXPC                      0x80e8                  /* Register Address */
-#define AR5K_TXPC_ACK_M                        0x0000003f      /* ACK tx power */
-#define AR5K_TXPC_ACK_S                        0
-#define AR5K_TXPC_CTS_M                        0x00003f00      /* CTS tx power */
-#define AR5K_TXPC_CTS_S                        8
-#define AR5K_TXPC_CHIRP_M              0x003f0000      /* CHIRP tx power */
-#define AR5K_TXPC_CHIRP_S              16
-#define AR5K_TXPC_DOPPLER              0x0f000000      /* Doppler chirp span (?) */
-#define AR5K_TXPC_DOPPLER_S            24
-
-/*
- * Profile count registers
- */
-#define AR5K_PROFCNT_TX                        0x80ec  /* Tx count */
-#define AR5K_PROFCNT_RX                        0x80f0  /* Rx count */
-#define AR5K_PROFCNT_RXCLR             0x80f4  /* Clear Rx count */
-#define AR5K_PROFCNT_CYCLE             0x80f8  /* Cycle count (?) */
-
-/*
- * Quiet period control registers
- */
-#define AR5K_QUIET_CTL1                        0x80fc                  /* Register Address */
-#define AR5K_QUIET_CTL1_NEXT_QT_TSF    0x0000ffff      /* Next quiet period TSF (TU) */
-#define AR5K_QUIET_CTL1_NEXT_QT_TSF_S  0
-#define AR5K_QUIET_CTL1_QT_EN          0x00010000      /* Enable quiet period */
-#define AR5K_QUIET_CTL1_ACK_CTS_EN     0x00020000      /* Send ACK/CTS during quiet period */
-
-#define AR5K_QUIET_CTL2                        0x8100                  /* Register Address */
-#define AR5K_QUIET_CTL2_QT_PER         0x0000ffff      /* Mask for quiet period periodicity */
-#define AR5K_QUIET_CTL2_QT_PER_S       0
-#define AR5K_QUIET_CTL2_QT_DUR         0xffff0000      /* Mask for quiet period duration */
-#define AR5K_QUIET_CTL2_QT_DUR_S       16
-
-/*
- * TSF parameter register
- */
-#define AR5K_TSF_PARM                  0x8104                  /* Register Address */
-#define AR5K_TSF_PARM_INC              0x000000ff      /* Mask for TSF increment */
-#define AR5K_TSF_PARM_INC_S            0
-
-/*
- * QoS NOACK policy
- */
-#define AR5K_QOS_NOACK                 0x8108                  /* Register Address */
-#define AR5K_QOS_NOACK_2BIT_VALUES     0x0000000f      /* ??? */
-#define AR5K_QOS_NOACK_2BIT_VALUES_S   0
-#define AR5K_QOS_NOACK_BIT_OFFSET      0x00000070      /* ??? */
-#define AR5K_QOS_NOACK_BIT_OFFSET_S    4
-#define AR5K_QOS_NOACK_BYTE_OFFSET     0x00000180      /* ??? */
-#define AR5K_QOS_NOACK_BYTE_OFFSET_S   7
-
-/*
- * PHY error filter register
- */
-#define AR5K_PHY_ERR_FIL               0x810c
-#define AR5K_PHY_ERR_FIL_RADAR         0x00000020      /* Radar signal */
-#define AR5K_PHY_ERR_FIL_OFDM          0x00020000      /* OFDM false detect (ANI) */
-#define AR5K_PHY_ERR_FIL_CCK           0x02000000      /* CCK false detect (ANI) */
-
-/*
- * XR latency register
- */
-#define AR5K_XRLAT_TX          0x8110
-
-/*
- * ACK SIFS register
- */
-#define AR5K_ACKSIFS           0x8114                  /* Register Address */
-#define AR5K_ACKSIFS_INC       0x00000000      /* ACK SIFS Increment (field) */
-
-/*
- * MIC QoS control register (?)
- */
-#define        AR5K_MIC_QOS_CTL                0x8118                  /* Register Address */
-#define        AR5K_MIC_QOS_CTL_OFF(_n)        (1 << (_n * 2))
-#define        AR5K_MIC_QOS_CTL_MQ_EN          0x00010000      /* Enable MIC QoS */
-
-/*
- * MIC QoS select register (?)
- */
-#define        AR5K_MIC_QOS_SEL                0x811c
-#define        AR5K_MIC_QOS_SEL_OFF(_n)        (1 << (_n * 4))
-
-/*
- * Misc mode control register (?)
- */
-#define        AR5K_MISC_MODE                  0x8120                  /* Register Address */
-#define        AR5K_MISC_MODE_FBSSID_MATCH     0x00000001      /* Force BSSID match */
-#define        AR5K_MISC_MODE_ACKSIFS_MEM      0x00000002      /* ACK SIFS memory (?) */
-#define        AR5K_MISC_MODE_COMBINED_MIC     0x00000004      /* use rx/tx MIC key */
-/* more bits */
-
-/*
- * OFDM Filter counter
- */
-#define        AR5K_OFDM_FIL_CNT               0x8124
-
-/*
- * CCK Filter counter
- */
-#define        AR5K_CCK_FIL_CNT                0x8128
-
-/*
- * PHY Error Counters (?)
- */
-#define        AR5K_PHYERR_CNT1                0x812c
-#define        AR5K_PHYERR_CNT1_MASK           0x8130
-
-#define        AR5K_PHYERR_CNT2                0x8134
-#define        AR5K_PHYERR_CNT2_MASK           0x8138
-
-/*
- * TSF Threshold register (?)
- */
-#define        AR5K_TSF_THRES                  0x813c
-
-/*
- * TODO: Wake On Wireless registers
- * Range: 0x8147 - 0x818c
- */
-
-/*
- * Rate -> ACK SIFS mapping table (32 entries)
- */
-#define        AR5K_RATE_ACKSIFS_BASE          0x8680                  /* Register Address */
-#define        AR5K_RATE_ACKSIFS(_n)           (AR5K_RATE_ACKSIFS_BSE + ((_n) << 2))
-#define        AR5K_RATE_ACKSIFS_NORMAL        0x00000001      /* Normal SIFS (field) */
-#define        AR5K_RATE_ACKSIFS_TURBO         0x00000400      /* Turbo SIFS (field) */
-
-/*
- * Rate -> duration mapping table (32 entries)
- */
-#define AR5K_RATE_DUR_BASE             0x8700
-#define AR5K_RATE_DUR(_n)              (AR5K_RATE_DUR_BASE + ((_n) << 2))
-
-/*
- * Rate -> db mapping table
- * (8 entries, each one has 4 8bit fields)
- */
-#define AR5K_RATE2DB_BASE              0x87c0
-#define AR5K_RATE2DB(_n)               (AR5K_RATE2DB_BASE + ((_n) << 2))
-
-/*
- * db -> Rate mapping table
- * (8 entries, each one has 4 8bit fields)
- */
-#define AR5K_DB2RATE_BASE              0x87e0
-#define AR5K_DB2RATE(_n)               (AR5K_DB2RATE_BASE + ((_n) << 2))
-
-/*===5212 end===*/
-
-/*
- * Key table (WEP) register
- */
-#define AR5K_KEYTABLE_0_5210           0x9000
-#define AR5K_KEYTABLE_0_5211           0x8800
-#define AR5K_KEYTABLE_5210(_n)         (AR5K_KEYTABLE_0_5210 + ((_n) << 5))
-#define AR5K_KEYTABLE_5211(_n)         (AR5K_KEYTABLE_0_5211 + ((_n) << 5))
-#define        AR5K_KEYTABLE(_n)               (ah->ah_version == AR5K_AR5210 ? \
-                                       AR5K_KEYTABLE_5210(_n) : AR5K_KEYTABLE_5211(_n))
-#define AR5K_KEYTABLE_OFF(_n, x)       (AR5K_KEYTABLE(_n) + (x << 2))
-#define AR5K_KEYTABLE_TYPE(_n)         AR5K_KEYTABLE_OFF(_n, 5)
-#define AR5K_KEYTABLE_TYPE_40          0x00000000
-#define AR5K_KEYTABLE_TYPE_104         0x00000001
-#define AR5K_KEYTABLE_TYPE_128         0x00000003
-#define AR5K_KEYTABLE_TYPE_TKIP                0x00000004      /* [5212+] */
-#define AR5K_KEYTABLE_TYPE_AES         0x00000005      /* [5211+] */
-#define AR5K_KEYTABLE_TYPE_CCM         0x00000006      /* [5212+] */
-#define AR5K_KEYTABLE_TYPE_NULL                0x00000007      /* [5211+] */
-#define AR5K_KEYTABLE_ANTENNA          0x00000008      /* [5212+] */
-#define AR5K_KEYTABLE_MAC0(_n)         AR5K_KEYTABLE_OFF(_n, 6)
-#define AR5K_KEYTABLE_MAC1(_n)         AR5K_KEYTABLE_OFF(_n, 7)
-#define AR5K_KEYTABLE_VALID            0x00008000
-
-/* If key type is TKIP and MIC is enabled
- * MIC key goes in offset entry + 64 */
-#define        AR5K_KEYTABLE_MIC_OFFSET        64
-
-/* WEP 40-bit  = 40-bit  entered key + 24 bit IV = 64-bit
- * WEP 104-bit = 104-bit entered key + 24-bit IV = 128-bit
- * WEP 128-bit = 128-bit entered key + 24 bit IV = 152-bit
- *
- * Some vendors have introduced bigger WEP keys to address
- * security vulnerabilities in WEP. This includes:
- *
- * WEP 232-bit = 232-bit entered key + 24 bit IV = 256-bit
- *
- * We can expand this if we find ar5k Atheros cards with a larger
- * key table size.
- */
-#define AR5K_KEYTABLE_SIZE_5210                64
-#define AR5K_KEYTABLE_SIZE_5211                128
-#define        AR5K_KEYTABLE_SIZE              (ah->ah_version == AR5K_AR5210 ? \
-                                       AR5K_KEYTABLE_SIZE_5210 : AR5K_KEYTABLE_SIZE_5211)
-
-
-/*===PHY REGISTERS===*/
-
-/*
- * PHY registers start
- */
-#define        AR5K_PHY_BASE                   0x9800
-#define        AR5K_PHY(_n)                    (AR5K_PHY_BASE + ((_n) << 2))
-
-/*
- * TST_2 (Misc config parameters)
- */
-#define        AR5K_PHY_TST2                   0x9800                  /* Register Address */
-#define AR5K_PHY_TST2_TRIG_SEL         0x00000007      /* Trigger select (?)*/
-#define AR5K_PHY_TST2_TRIG             0x00000010      /* Trigger (?) */
-#define AR5K_PHY_TST2_CBUS_MODE                0x00000060      /* Cardbus mode (?) */
-#define AR5K_PHY_TST2_CLK32            0x00000400      /* CLK_OUT is CLK32 (32Khz external) */
-#define AR5K_PHY_TST2_CHANCOR_DUMP_EN  0x00000800      /* Enable Chancor dump (?) */
-#define AR5K_PHY_TST2_EVEN_CHANCOR_DUMP        0x00001000      /* Even Chancor dump (?) */
-#define AR5K_PHY_TST2_RFSILENT_EN      0x00002000      /* Enable RFSILENT */
-#define AR5K_PHY_TST2_ALT_RFDATA       0x00004000      /* Alternate RFDATA (5-2GHz switch ?) */
-#define AR5K_PHY_TST2_MINI_OBS_EN      0x00008000      /* Enable mini OBS (?) */
-#define AR5K_PHY_TST2_RX2_IS_RX5_INV   0x00010000      /* 2GHz rx path is the 5GHz path inverted (?) */
-#define AR5K_PHY_TST2_SLOW_CLK160      0x00020000      /* Slow CLK160 (?) */
-#define AR5K_PHY_TST2_AGC_OBS_SEL_3    0x00040000      /* AGC OBS Select 3 (?) */
-#define AR5K_PHY_TST2_BBB_OBS_SEL      0x00080000      /* BB OBS Select (field ?) */
-#define AR5K_PHY_TST2_ADC_OBS_SEL      0x00800000      /* ADC OBS Select (field ?) */
-#define AR5K_PHY_TST2_RX_CLR_SEL       0x08000000      /* RX Clear Select (?) */
-#define AR5K_PHY_TST2_FORCE_AGC_CLR    0x10000000      /* Force AGC clear (?) */
-#define AR5K_PHY_SHIFT_2GHZ            0x00004007      /* Used to access 2GHz radios */
-#define AR5K_PHY_SHIFT_5GHZ            0x00000007      /* Used to access 5GHz radios (default) */
-
-/*
- * PHY frame control register [5110] /turbo mode register [5111+]
- *
- * There is another frame control register for [5111+]
- * at address 0x9944 (see below) but the 2 first flags
- * are common here between 5110 frame control register
- * and [5111+] turbo mode register, so this also works as
- * a "turbo mode register" for 5110. We treat this one as
- * a frame control register for 5110 below.
- */
-#define        AR5K_PHY_TURBO                  0x9804                  /* Register Address */
-#define        AR5K_PHY_TURBO_MODE             0x00000001      /* Enable turbo mode */
-#define        AR5K_PHY_TURBO_SHORT            0x00000002      /* Set short symbols to turbo mode */
-#define        AR5K_PHY_TURBO_MIMO             0x00000004      /* Set turbo for mimo mimo */
-
-/*
- * PHY agility command register
- * (aka TST_1)
- */
-#define        AR5K_PHY_AGC                    0x9808                  /* Register Address */
-#define        AR5K_PHY_TST1                   0x9808
-#define        AR5K_PHY_AGC_DISABLE            0x08000000      /* Disable AGC to A2 (?)*/
-#define        AR5K_PHY_TST1_TXHOLD            0x00003800      /* Set tx hold (?) */
-#define        AR5K_PHY_TST1_TXSRC_SRC         0x00000002      /* Used with bit 7 (?) */
-#define        AR5K_PHY_TST1_TXSRC_SRC_S       1
-#define        AR5K_PHY_TST1_TXSRC_ALT         0x00000080      /* Set input to tsdac (?) */
-#define        AR5K_PHY_TST1_TXSRC_ALT_S       7
-
-
-/*
- * PHY timing register 3 [5112+]
- */
-#define        AR5K_PHY_TIMING_3               0x9814
-#define        AR5K_PHY_TIMING_3_DSC_MAN       0xfffe0000
-#define        AR5K_PHY_TIMING_3_DSC_MAN_S     17
-#define        AR5K_PHY_TIMING_3_DSC_EXP       0x0001e000
-#define        AR5K_PHY_TIMING_3_DSC_EXP_S     13
-
-/*
- * PHY chip revision register
- */
-#define        AR5K_PHY_CHIP_ID                0x9818
-
-/*
- * PHY activation register
- */
-#define        AR5K_PHY_ACT                    0x981c                  /* Register Address */
-#define        AR5K_PHY_ACT_ENABLE             0x00000001      /* Activate PHY */
-#define        AR5K_PHY_ACT_DISABLE            0x00000002      /* Deactivate PHY */
-
-/*
- * PHY RF control registers
- */
-#define AR5K_PHY_RF_CTL2               0x9824                  /* Register Address */
-#define        AR5K_PHY_RF_CTL2_TXF2TXD_START  0x0000000f      /* TX frame to TX data start */
-#define        AR5K_PHY_RF_CTL2_TXF2TXD_START_S        0
-
-#define AR5K_PHY_RF_CTL3               0x9828                  /* Register Address */
-#define AR5K_PHY_RF_CTL3_TXE2XLNA_ON   0x0000ff00      /* TX end to XLNA on */
-#define        AR5K_PHY_RF_CTL3_TXE2XLNA_ON_S  8
-
-#define        AR5K_PHY_ADC_CTL                        0x982c
-#define        AR5K_PHY_ADC_CTL_INBUFGAIN_OFF          0x00000003
-#define        AR5K_PHY_ADC_CTL_INBUFGAIN_OFF_S        0
-#define        AR5K_PHY_ADC_CTL_PWD_DAC_OFF            0x00002000
-#define        AR5K_PHY_ADC_CTL_PWD_BAND_GAP_OFF       0x00004000
-#define        AR5K_PHY_ADC_CTL_PWD_ADC_OFF            0x00008000
-#define        AR5K_PHY_ADC_CTL_INBUFGAIN_ON           0x00030000
-#define        AR5K_PHY_ADC_CTL_INBUFGAIN_ON_S         16
-
-#define AR5K_PHY_RF_CTL4               0x9834                  /* Register Address */
-#define AR5K_PHY_RF_CTL4_TXF2XPA_A_ON  0x00000001      /* TX frame to XPA A on (field) */
-#define AR5K_PHY_RF_CTL4_TXF2XPA_B_ON  0x00000100      /* TX frame to XPA B on (field) */
-#define        AR5K_PHY_RF_CTL4_TXE2XPA_A_OFF  0x00010000      /* TX end to XPA A off (field) */
-#define AR5K_PHY_RF_CTL4_TXE2XPA_B_OFF 0x01000000      /* TX end to XPA B off (field) */
-
-/*
- * Pre-Amplifier control register
- * (XPA -> external pre-amplifier)
- */
-#define        AR5K_PHY_PA_CTL                 0x9838                  /* Register Address */
-#define        AR5K_PHY_PA_CTL_XPA_A_HI        0x00000001      /* XPA A high (?) */
-#define        AR5K_PHY_PA_CTL_XPA_B_HI        0x00000002      /* XPA B high (?) */
-#define        AR5K_PHY_PA_CTL_XPA_A_EN        0x00000004      /* Enable XPA A */
-#define        AR5K_PHY_PA_CTL_XPA_B_EN        0x00000008      /* Enable XPA B */
-
-/*
- * PHY settling register
- */
-#define AR5K_PHY_SETTLING              0x9844                  /* Register Address */
-#define        AR5K_PHY_SETTLING_AGC           0x0000007f      /* AGC settling time */
-#define        AR5K_PHY_SETTLING_AGC_S         0
-#define        AR5K_PHY_SETTLING_SWITCH        0x00003f80      /* Switch settlig time */
-#define        AR5K_PHY_SETTLING_SWITCH_S      7
-
-/*
- * PHY Gain registers
- */
-#define AR5K_PHY_GAIN                  0x9848                  /* Register Address */
-#define        AR5K_PHY_GAIN_TXRX_ATTEN        0x0003f000      /* TX-RX Attenuation */
-#define        AR5K_PHY_GAIN_TXRX_ATTEN_S      12
-#define        AR5K_PHY_GAIN_TXRX_RF_MAX       0x007c0000
-#define        AR5K_PHY_GAIN_TXRX_RF_MAX_S     18
-
-#define        AR5K_PHY_GAIN_OFFSET            0x984c                  /* Register Address */
-#define        AR5K_PHY_GAIN_OFFSET_RXTX_FLAG  0x00020000      /* RX-TX flag (?) */
-
-/*
- * Desired ADC/PGA size register
- * (for more infos read ANI patent)
- */
-#define AR5K_PHY_DESIRED_SIZE          0x9850                  /* Register Address */
-#define        AR5K_PHY_DESIRED_SIZE_ADC       0x000000ff      /* ADC desired size */
-#define        AR5K_PHY_DESIRED_SIZE_ADC_S     0
-#define        AR5K_PHY_DESIRED_SIZE_PGA       0x0000ff00      /* PGA desired size */
-#define        AR5K_PHY_DESIRED_SIZE_PGA_S     8
-#define        AR5K_PHY_DESIRED_SIZE_TOT       0x0ff00000      /* Total desired size */
-#define        AR5K_PHY_DESIRED_SIZE_TOT_S     20
-
-/*
- * PHY signal register
- * (for more infos read ANI patent)
- */
-#define        AR5K_PHY_SIG                    0x9858                  /* Register Address */
-#define        AR5K_PHY_SIG_FIRSTEP            0x0003f000      /* FIRSTEP */
-#define        AR5K_PHY_SIG_FIRSTEP_S          12
-#define        AR5K_PHY_SIG_FIRPWR             0x03fc0000      /* FIPWR */
-#define        AR5K_PHY_SIG_FIRPWR_S           18
-
-/*
- * PHY coarse agility control register
- * (for more infos read ANI patent)
- */
-#define        AR5K_PHY_AGCCOARSE              0x985c                  /* Register Address */
-#define        AR5K_PHY_AGCCOARSE_LO           0x00007f80      /* AGC Coarse low */
-#define        AR5K_PHY_AGCCOARSE_LO_S         7
-#define        AR5K_PHY_AGCCOARSE_HI           0x003f8000      /* AGC Coarse high */
-#define        AR5K_PHY_AGCCOARSE_HI_S         15
-
-/*
- * PHY agility control register
- */
-#define        AR5K_PHY_AGCCTL                 0x9860                  /* Register address */
-#define        AR5K_PHY_AGCCTL_CAL             0x00000001      /* Enable PHY calibration */
-#define        AR5K_PHY_AGCCTL_NF              0x00000002      /* Enable Noise Floor calibration */
-#define        AR5K_PHY_AGCCTL_NF_EN           0x00008000      /* Enable nf calibration to happen (?) */
-#define        AR5K_PHY_AGCCTL_NF_NOUPDATE     0x00020000      /* Don't update nf automaticaly */
-
-/*
- * PHY noise floor status register
- */
-#define AR5K_PHY_NF                    0x9864                  /* Register address */
-#define AR5K_PHY_NF_M                  0x000001ff      /* Noise floor mask */
-#define AR5K_PHY_NF_ACTIVE             0x00000100      /* Noise floor calibration still active */
-#define AR5K_PHY_NF_RVAL(_n)           (((_n) >> 19) & AR5K_PHY_NF_M)
-#define AR5K_PHY_NF_AVAL(_n)           (-((_n) ^ AR5K_PHY_NF_M) + 1)
-#define AR5K_PHY_NF_SVAL(_n)           (((_n) & AR5K_PHY_NF_M) | (1 << 9))
-#define        AR5K_PHY_NF_THRESH62            0x0007f000      /* Thresh62 -check ANI patent- (field) */
-#define        AR5K_PHY_NF_THRESH62_S          12
-#define        AR5K_PHY_NF_MINCCA_PWR          0x0ff80000      /* ??? */
-#define        AR5K_PHY_NF_MINCCA_PWR_S        19
-
-/*
- * PHY ADC saturation register [5110]
- */
-#define        AR5K_PHY_ADCSAT                 0x9868
-#define        AR5K_PHY_ADCSAT_ICNT            0x0001f800
-#define        AR5K_PHY_ADCSAT_ICNT_S          11
-#define        AR5K_PHY_ADCSAT_THR             0x000007e0
-#define        AR5K_PHY_ADCSAT_THR_S           5
-
-/*
- * PHY Weak ofdm signal detection threshold registers (ANI) [5212+]
- */
-
-/* High thresholds */
-#define AR5K_PHY_WEAK_OFDM_HIGH_THR            0x9868
-#define AR5K_PHY_WEAK_OFDM_HIGH_THR_M2_COUNT   0x0000001f
-#define AR5K_PHY_WEAK_OFDM_HIGH_THR_M2_COUNT_S 0
-#define AR5K_PHY_WEAK_OFDM_HIGH_THR_M1         0x00fe0000
-#define AR5K_PHY_WEAK_OFDM_HIGH_THR_M1_S       17
-#define AR5K_PHY_WEAK_OFDM_HIGH_THR_M2         0x7f000000
-#define AR5K_PHY_WEAK_OFDM_HIGH_THR_M2_S       24
-
-/* Low thresholds */
-#define AR5K_PHY_WEAK_OFDM_LOW_THR             0x986c
-#define AR5K_PHY_WEAK_OFDM_LOW_THR_SELFCOR_EN  0x00000001
-#define AR5K_PHY_WEAK_OFDM_LOW_THR_M2_COUNT    0x00003f00
-#define AR5K_PHY_WEAK_OFDM_LOW_THR_M2_COUNT_S  8
-#define AR5K_PHY_WEAK_OFDM_LOW_THR_M1          0x001fc000
-#define AR5K_PHY_WEAK_OFDM_LOW_THR_M1_S                14
-#define AR5K_PHY_WEAK_OFDM_LOW_THR_M2          0x0fe00000
-#define AR5K_PHY_WEAK_OFDM_LOW_THR_M2_S                21
-
-
-/*
- * PHY sleep registers [5112+]
- */
-#define AR5K_PHY_SCR                   0x9870
-
-#define AR5K_PHY_SLMT                  0x9874
-#define AR5K_PHY_SLMT_32MHZ            0x0000007f
-
-#define AR5K_PHY_SCAL                  0x9878
-#define AR5K_PHY_SCAL_32MHZ            0x0000000e
-#define        AR5K_PHY_SCAL_32MHZ_2417        0x0000000a
-#define        AR5K_PHY_SCAL_32MHZ_HB63        0x00000032
-
-/*
- * PHY PLL (Phase Locked Loop) control register
- */
-#define        AR5K_PHY_PLL                    0x987c
-#define        AR5K_PHY_PLL_20MHZ              0x00000013      /* For half rate (?) */
-/* 40MHz -> 5GHz band */
-#define        AR5K_PHY_PLL_40MHZ_5211         0x00000018
-#define        AR5K_PHY_PLL_40MHZ_5212         0x000000aa
-#define        AR5K_PHY_PLL_40MHZ_5413         0x00000004
-#define        AR5K_PHY_PLL_40MHZ              (ah->ah_version == AR5K_AR5211 ? \
-                                       AR5K_PHY_PLL_40MHZ_5211 : AR5K_PHY_PLL_40MHZ_5212)
-/* 44MHz -> 2.4GHz band */
-#define        AR5K_PHY_PLL_44MHZ_5211         0x00000019
-#define        AR5K_PHY_PLL_44MHZ_5212         0x000000ab
-#define        AR5K_PHY_PLL_44MHZ              (ah->ah_version == AR5K_AR5211 ? \
-                                       AR5K_PHY_PLL_44MHZ_5211 : AR5K_PHY_PLL_44MHZ_5212)
-
-#define AR5K_PHY_PLL_RF5111            0x00000000
-#define AR5K_PHY_PLL_RF5112            0x00000040
-#define        AR5K_PHY_PLL_HALF_RATE          0x00000100
-#define        AR5K_PHY_PLL_QUARTER_RATE       0x00000200
-
-/*
- * RF Buffer register
- *
- * It's obvious from the code that 0x989c is the buffer register but
- * for the other special registers that we write to after sending each
- * packet, i have no idea. So i'll name them BUFFER_CONTROL_X registers
- * for now. It's interesting that they are also used for some other operations.
- */
-
-#define AR5K_RF_BUFFER                 0x989c
-#define AR5K_RF_BUFFER_CONTROL_0       0x98c0  /* Channel on 5110 */
-#define AR5K_RF_BUFFER_CONTROL_1       0x98c4  /* Bank 7 on 5112 */
-#define AR5K_RF_BUFFER_CONTROL_2       0x98cc  /* Bank 7 on 5111 */
-
-#define AR5K_RF_BUFFER_CONTROL_3       0x98d0  /* Bank 2 on 5112 */
-                                               /* Channel set on 5111 */
-                                               /* Used to read radio revision*/
-
-#define AR5K_RF_BUFFER_CONTROL_4       0x98d4  /* RF Stage register on 5110 */
-                                               /* Bank 0,1,2,6 on 5111 */
-                                               /* Bank 1 on 5112 */
-                                               /* Used during activation on 5111 */
-
-#define AR5K_RF_BUFFER_CONTROL_5       0x98d8  /* Bank 3 on 5111 */
-                                               /* Used during activation on 5111 */
-                                               /* Channel on 5112 */
-                                               /* Bank 6 on 5112 */
-
-#define AR5K_RF_BUFFER_CONTROL_6       0x98dc  /* Bank 3 on 5112 */
-
-/*
- * PHY RF stage register [5210]
- */
-#define AR5K_PHY_RFSTG                 0x98d4
-#define AR5K_PHY_RFSTG_DISABLE         0x00000021
-
-/*
- * BIN masks (?)
- */
-#define        AR5K_PHY_BIN_MASK_1     0x9900
-#define        AR5K_PHY_BIN_MASK_2     0x9904
-#define        AR5K_PHY_BIN_MASK_3     0x9908
-
-#define        AR5K_PHY_BIN_MASK_CTL           0x990c
-#define        AR5K_PHY_BIN_MASK_CTL_MASK_4    0x00003fff
-#define        AR5K_PHY_BIN_MASK_CTL_MASK_4_S  0
-#define        AR5K_PHY_BIN_MASK_CTL_RATE      0xff000000
-#define        AR5K_PHY_BIN_MASK_CTL_RATE_S    24
-
-/*
- * PHY Antenna control register
- */
-#define AR5K_PHY_ANT_CTL               0x9910                  /* Register Address */
-#define        AR5K_PHY_ANT_CTL_TXRX_EN        0x00000001      /* Enable TX/RX (?) */
-#define        AR5K_PHY_ANT_CTL_SECTORED_ANT   0x00000004      /* Sectored Antenna */
-#define        AR5K_PHY_ANT_CTL_HITUNE5        0x00000008      /* Hitune5 (?) */
-#define        AR5K_PHY_ANT_CTL_SWTABLE_IDLE   0x000003f0      /* Switch table idle (?) */
-#define        AR5K_PHY_ANT_CTL_SWTABLE_IDLE_S 4
-
-/*
- * PHY receiver delay register [5111+]
- */
-#define        AR5K_PHY_RX_DELAY               0x9914                  /* Register Address */
-#define        AR5K_PHY_RX_DELAY_M             0x00003fff      /* Mask for RX activate to receive delay (/100ns) */
-
-/*
- * PHY max rx length register (?) [5111]
- */
-#define        AR5K_PHY_MAX_RX_LEN             0x991c
-
-/*
- * PHY timing register 4
- * I(nphase)/Q(adrature) calibration register [5111+]
- */
-#define        AR5K_PHY_IQ                     0x9920                  /* Register Address */
-#define        AR5K_PHY_IQ_CORR_Q_Q_COFF       0x0000001f      /* Mask for q correction info */
-#define        AR5K_PHY_IQ_CORR_Q_I_COFF       0x000007e0      /* Mask for i correction info */
-#define        AR5K_PHY_IQ_CORR_Q_I_COFF_S     5
-#define        AR5K_PHY_IQ_CORR_ENABLE         0x00000800      /* Enable i/q correction */
-#define        AR5K_PHY_IQ_CAL_NUM_LOG_MAX     0x0000f000      /* Mask for max number of samples in log scale */
-#define        AR5K_PHY_IQ_CAL_NUM_LOG_MAX_S   12
-#define        AR5K_PHY_IQ_RUN                 0x00010000      /* Run i/q calibration */
-#define        AR5K_PHY_IQ_USE_PT_DF           0x00020000      /* Use pilot track df (?) */
-#define        AR5K_PHY_IQ_EARLY_TRIG_THR      0x00200000      /* Early trigger threshold (?) (field) */
-#define        AR5K_PHY_IQ_PILOT_MASK_EN       0x10000000      /* Enable pilot mask (?) */
-#define        AR5K_PHY_IQ_CHAN_MASK_EN        0x20000000      /* Enable channel mask (?) */
-#define        AR5K_PHY_IQ_SPUR_FILT_EN        0x40000000      /* Enable spur filter */
-#define        AR5K_PHY_IQ_SPUR_RSSI_EN        0x80000000      /* Enable spur rssi */
-
-/*
- * PHY timing register 5
- * OFDM Self-correlator Cyclic RSSI threshold params
- * (Check out bb_cycpwr_thr1 on ANI patent)
- */
-#define        AR5K_PHY_OFDM_SELFCORR                  0x9924                  /* Register Address */
-#define        AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1_EN    0x00000001      /* Enable cyclic RSSI thr 1 */
-#define        AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1       0x000000fe      /* Mask for Cyclic RSSI threshold 1 */
-#define        AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1_S     1
-#define        AR5K_PHY_OFDM_SELFCORR_CYPWR_THR3       0x00000100      /* Cyclic RSSI threshold 3 (field) (?) */
-#define        AR5K_PHY_OFDM_SELFCORR_RSSI_1ATHR_EN    0x00008000      /* Enable 1A RSSI threshold (?) */
-#define        AR5K_PHY_OFDM_SELFCORR_RSSI_1ATHR       0x00010000      /* 1A RSSI threshold (field) (?) */
-#define        AR5K_PHY_OFDM_SELFCORR_LSCTHR_HIRSSI    0x00800000      /* Long sc threshold hi rssi (?) */
-
-/*
- * PHY-only warm reset register
- */
-#define        AR5K_PHY_WARM_RESET             0x9928
-
-/*
- * PHY-only control register
- */
-#define AR5K_PHY_CTL                   0x992c                  /* Register Address */
-#define        AR5K_PHY_CTL_RX_DRAIN_RATE      0x00000001      /* RX drain rate (?) */
-#define        AR5K_PHY_CTL_LATE_TX_SIG_SYM    0x00000002      /* Late tx signal symbol (?) */
-#define        AR5K_PHY_CTL_GEN_SCRAMBLER      0x00000004      /* Generate scrambler */
-#define        AR5K_PHY_CTL_TX_ANT_SEL         0x00000008      /* TX antenna select */
-#define        AR5K_PHY_CTL_TX_ANT_STATIC      0x00000010      /* Static TX antenna */
-#define        AR5K_PHY_CTL_RX_ANT_SEL         0x00000020      /* RX antenna select */
-#define        AR5K_PHY_CTL_RX_ANT_STATIC      0x00000040      /* Static RX antenna */
-#define        AR5K_PHY_CTL_LOW_FREQ_SLE_EN    0x00000080      /* Enable low freq sleep */
-
-/*
- * PHY PAPD probe register [5111+]
- */
-#define        AR5K_PHY_PAPD_PROBE             0x9930
-#define        AR5K_PHY_PAPD_PROBE_SH_HI_PAR   0x00000001
-#define        AR5K_PHY_PAPD_PROBE_PCDAC_BIAS  0x00000002
-#define        AR5K_PHY_PAPD_PROBE_COMP_GAIN   0x00000040
-#define        AR5K_PHY_PAPD_PROBE_TXPOWER     0x00007e00
-#define        AR5K_PHY_PAPD_PROBE_TXPOWER_S   9
-#define        AR5K_PHY_PAPD_PROBE_TX_NEXT     0x00008000
-#define        AR5K_PHY_PAPD_PROBE_PREDIST_EN  0x00010000
-#define        AR5K_PHY_PAPD_PROBE_TYPE        0x01800000      /* [5112+] */
-#define        AR5K_PHY_PAPD_PROBE_TYPE_S      23
-#define        AR5K_PHY_PAPD_PROBE_TYPE_OFDM   0
-#define        AR5K_PHY_PAPD_PROBE_TYPE_XR     1
-#define        AR5K_PHY_PAPD_PROBE_TYPE_CCK    2
-#define        AR5K_PHY_PAPD_PROBE_GAINF       0xfe000000
-#define        AR5K_PHY_PAPD_PROBE_GAINF_S     25
-#define        AR5K_PHY_PAPD_PROBE_INI_5111    0x00004883      /* [5212+] */
-#define        AR5K_PHY_PAPD_PROBE_INI_5112    0x00004882      /* [5212+] */
-
-/*
- * PHY TX rate power registers [5112+]
- */
-#define        AR5K_PHY_TXPOWER_RATE1                  0x9934
-#define        AR5K_PHY_TXPOWER_RATE2                  0x9938
-#define        AR5K_PHY_TXPOWER_RATE_MAX               0x993c
-#define        AR5K_PHY_TXPOWER_RATE_MAX_TPC_ENABLE    0x00000040
-#define        AR5K_PHY_TXPOWER_RATE3                  0xa234
-#define        AR5K_PHY_TXPOWER_RATE4                  0xa238
-
-/*
- * PHY frame control register [5111+]
- */
-#define        AR5K_PHY_FRAME_CTL_5210         0x9804
-#define        AR5K_PHY_FRAME_CTL_5211         0x9944
-#define        AR5K_PHY_FRAME_CTL              (ah->ah_version == AR5K_AR5210 ? \
-                                       AR5K_PHY_FRAME_CTL_5210 : AR5K_PHY_FRAME_CTL_5211)
-/*---[5111+]---*/
-#define        AR5K_PHY_FRAME_CTL_TX_CLIP      0x00000038      /* Mask for tx clip (?) */
-#define        AR5K_PHY_FRAME_CTL_TX_CLIP_S    3
-#define        AR5K_PHY_FRAME_CTL_PREP_CHINFO  0x00010000      /* Prepend chan info */
-#define        AR5K_PHY_FRAME_CTL_EMU          0x80000000
-#define        AR5K_PHY_FRAME_CTL_EMU_S        31
-/*---[5110/5111]---*/
-#define        AR5K_PHY_FRAME_CTL_TIMING_ERR   0x01000000      /* PHY timing error */
-#define        AR5K_PHY_FRAME_CTL_PARITY_ERR   0x02000000      /* Parity error */
-#define        AR5K_PHY_FRAME_CTL_ILLRATE_ERR  0x04000000      /* Illegal rate */
-#define        AR5K_PHY_FRAME_CTL_ILLLEN_ERR   0x08000000      /* Illegal length */
-#define        AR5K_PHY_FRAME_CTL_SERVICE_ERR  0x20000000
-#define        AR5K_PHY_FRAME_CTL_TXURN_ERR    0x40000000      /* TX underrun */
-#define AR5K_PHY_FRAME_CTL_INI         AR5K_PHY_FRAME_CTL_SERVICE_ERR | \
-                       AR5K_PHY_FRAME_CTL_TXURN_ERR | \
-                       AR5K_PHY_FRAME_CTL_ILLLEN_ERR | \
-                       AR5K_PHY_FRAME_CTL_ILLRATE_ERR | \
-                       AR5K_PHY_FRAME_CTL_PARITY_ERR | \
-                       AR5K_PHY_FRAME_CTL_TIMING_ERR
-
-/*
- * PHY Tx Power adjustment register [5212A+]
- */
-#define        AR5K_PHY_TX_PWR_ADJ                     0x994c
-#define        AR5K_PHY_TX_PWR_ADJ_CCK_GAIN_DELTA      0x00000fc0
-#define        AR5K_PHY_TX_PWR_ADJ_CCK_GAIN_DELTA_S    6
-#define        AR5K_PHY_TX_PWR_ADJ_CCK_PCDAC_INDEX     0x00fc0000
-#define        AR5K_PHY_TX_PWR_ADJ_CCK_PCDAC_INDEX_S   18
-
-/*
- * PHY radar detection register [5111+]
- */
-#define        AR5K_PHY_RADAR                  0x9954
-#define        AR5K_PHY_RADAR_ENABLE           0x00000001
-#define        AR5K_PHY_RADAR_DISABLE          0x00000000
-#define AR5K_PHY_RADAR_INBANDTHR       0x0000003e      /* Inband threshold
-                                                       5-bits, units unknown {0..31}
-                                                       (? MHz ?) */
-#define AR5K_PHY_RADAR_INBANDTHR_S     1
-
-#define AR5K_PHY_RADAR_PRSSI_THR       0x00000fc0      /* Pulse RSSI/SNR threshold
-                                                       6-bits, dBm range {0..63}
-                                                       in dBm units. */
-#define AR5K_PHY_RADAR_PRSSI_THR_S     6
-
-#define AR5K_PHY_RADAR_PHEIGHT_THR     0x0003f000      /* Pulse height threshold
-                                                       6-bits, dBm range {0..63}
-                                                       in dBm units. */
-#define AR5K_PHY_RADAR_PHEIGHT_THR_S   12
-
-#define AR5K_PHY_RADAR_RSSI_THR        0x00fc0000      /* Radar RSSI/SNR threshold.
-                                                       6-bits, dBm range {0..63}
-                                                       in dBm units. */
-#define AR5K_PHY_RADAR_RSSI_THR_S      18
-
-#define AR5K_PHY_RADAR_FIRPWR_THR      0x7f000000      /* Finite Impulse Response
-                                                       filter power out threshold.
-                                                       7-bits, standard power range
-                                                       {0..127} in 1/2 dBm units. */
-#define AR5K_PHY_RADAR_FIRPWR_THRS     24
-
-/*
- * PHY antenna switch table registers
- */
-#define AR5K_PHY_ANT_SWITCH_TABLE_0    0x9960
-#define AR5K_PHY_ANT_SWITCH_TABLE_1    0x9964
-
-/*
- * PHY Noise floor threshold
- */
-#define AR5K_PHY_NFTHRES               0x9968
-
-/*
- * Sigma Delta register (?) [5213]
- */
-#define AR5K_PHY_SIGMA_DELTA           0x996C
-#define AR5K_PHY_SIGMA_DELTA_ADC_SEL   0x00000003
-#define AR5K_PHY_SIGMA_DELTA_ADC_SEL_S 0
-#define AR5K_PHY_SIGMA_DELTA_FILT2     0x000000f8
-#define AR5K_PHY_SIGMA_DELTA_FILT2_S   3
-#define AR5K_PHY_SIGMA_DELTA_FILT1     0x00001f00
-#define AR5K_PHY_SIGMA_DELTA_FILT1_S   8
-#define AR5K_PHY_SIGMA_DELTA_ADC_CLIP  0x01ffe000
-#define AR5K_PHY_SIGMA_DELTA_ADC_CLIP_S        13
-
-/*
- * RF restart register [5112+] (?)
- */
-#define AR5K_PHY_RESTART               0x9970          /* restart */
-#define AR5K_PHY_RESTART_DIV_GC                0x001c0000      /* Fast diversity gc_limit (?) */
-#define AR5K_PHY_RESTART_DIV_GC_S      18
-
-/*
- * RF Bus access request register (for synth-oly channel switching)
- */
-#define AR5K_PHY_RFBUS_REQ             0x997C
-#define AR5K_PHY_RFBUS_REQ_REQUEST     0x00000001
-
-/*
- * Spur mitigation masks (?)
- */
-#define AR5K_PHY_TIMING_7              0x9980
-#define AR5K_PHY_TIMING_8              0x9984
-#define AR5K_PHY_TIMING_8_PILOT_MASK_2         0x000fffff
-#define AR5K_PHY_TIMING_8_PILOT_MASK_2_S       0
-
-#define AR5K_PHY_BIN_MASK2_1           0x9988
-#define AR5K_PHY_BIN_MASK2_2           0x998c
-#define AR5K_PHY_BIN_MASK2_3           0x9990
-
-#define AR5K_PHY_BIN_MASK2_4           0x9994
-#define AR5K_PHY_BIN_MASK2_4_MASK_4    0x00003fff
-#define AR5K_PHY_BIN_MASK2_4_MASK_4_S  0
-
-#define AR5K_PHY_TIMING_9                      0x9998
-#define AR5K_PHY_TIMING_10                     0x999c
-#define AR5K_PHY_TIMING_10_PILOT_MASK_2                0x000fffff
-#define AR5K_PHY_TIMING_10_PILOT_MASK_2_S      0
-
-/*
- * Spur mitigation control
- */
-#define AR5K_PHY_TIMING_11                     0x99a0          /* Register address */
-#define AR5K_PHY_TIMING_11_SPUR_DELTA_PHASE    0x000fffff      /* Spur delta phase */
-#define AR5K_PHY_TIMING_11_SPUR_DELTA_PHASE_S  0
-#define AR5K_PHY_TIMING_11_SPUR_FREQ_SD                0x3ff00000      /* Freq sigma delta */
-#define AR5K_PHY_TIMING_11_SPUR_FREQ_SD_S      20
-#define AR5K_PHY_TIMING_11_USE_SPUR_IN_AGC     0x40000000      /* Spur filter in AGC detector */
-#define AR5K_PHY_TIMING_11_USE_SPUR_IN_SELFCOR 0x80000000      /* Spur filter in OFDM self correlator */
-
-/*
- * Gain tables
- */
-#define        AR5K_BB_GAIN_BASE               0x9b00  /* BaseBand Amplifier Gain table base address */
-#define AR5K_BB_GAIN(_n)               (AR5K_BB_GAIN_BASE + ((_n) << 2))
-#define        AR5K_RF_GAIN_BASE               0x9a00  /* RF Amplrifier Gain table base address */
-#define AR5K_RF_GAIN(_n)               (AR5K_RF_GAIN_BASE + ((_n) << 2))
-
-/*
- * PHY timing IQ calibration result register [5111+]
- */
-#define        AR5K_PHY_IQRES_CAL_PWR_I        0x9c10  /* I (Inphase) power value */
-#define        AR5K_PHY_IQRES_CAL_PWR_Q        0x9c14  /* Q (Quadrature) power value */
-#define        AR5K_PHY_IQRES_CAL_CORR         0x9c18  /* I/Q Correlation */
-
-/*
- * PHY current RSSI register [5111+]
- */
-#define        AR5K_PHY_CURRENT_RSSI   0x9c1c
-
-/*
- * PHY RF Bus grant register
- */
-#define        AR5K_PHY_RFBUS_GRANT    0x9c20
-#define        AR5K_PHY_RFBUS_GRANT_OK 0x00000001
-
-/*
- * PHY ADC test register
- */
-#define        AR5K_PHY_ADC_TEST       0x9c24
-#define        AR5K_PHY_ADC_TEST_I     0x00000001
-#define        AR5K_PHY_ADC_TEST_Q     0x00000200
-
-/*
- * PHY DAC test register
- */
-#define        AR5K_PHY_DAC_TEST       0x9c28
-#define        AR5K_PHY_DAC_TEST_I     0x00000001
-#define        AR5K_PHY_DAC_TEST_Q     0x00000200
-
-/*
- * PHY PTAT register (?)
- */
-#define        AR5K_PHY_PTAT           0x9c2c
-
-/*
- * PHY Illegal TX rate register [5112+]
- */
-#define        AR5K_PHY_BAD_TX_RATE    0x9c30
-
-/*
- * PHY SPUR Power register [5112+]
- */
-#define        AR5K_PHY_SPUR_PWR       0x9c34                  /* Register Address */
-#define        AR5K_PHY_SPUR_PWR_I     0x00000001      /* SPUR Power estimate for I (field) */
-#define        AR5K_PHY_SPUR_PWR_Q     0x00000100      /* SPUR Power estimate for Q (field) */
-#define        AR5K_PHY_SPUR_PWR_FILT  0x00010000      /* Power with SPUR removed (field) */
-
-/*
- * PHY Channel status register [5112+] (?)
- */
-#define        AR5K_PHY_CHAN_STATUS            0x9c38
-#define        AR5K_PHY_CHAN_STATUS_BT_ACT     0x00000001
-#define        AR5K_PHY_CHAN_STATUS_RX_CLR_RAW 0x00000002
-#define        AR5K_PHY_CHAN_STATUS_RX_CLR_MAC 0x00000004
-#define        AR5K_PHY_CHAN_STATUS_RX_CLR_PAP 0x00000008
-
-/*
- * Heavy clip enable register
- */
-#define        AR5K_PHY_HEAVY_CLIP_ENABLE      0x99e0
-
-/*
- * PHY clock sleep registers [5112+]
- */
-#define AR5K_PHY_SCLOCK                        0x99f0
-#define AR5K_PHY_SCLOCK_32MHZ          0x0000000c
-#define AR5K_PHY_SDELAY                        0x99f4
-#define AR5K_PHY_SDELAY_32MHZ          0x000000ff
-#define AR5K_PHY_SPENDING              0x99f8
-
-
-/*
- * PHY PAPD I (power?) table (?)
- * (92! entries)
- */
-#define        AR5K_PHY_PAPD_I_BASE    0xa000
-#define        AR5K_PHY_PAPD_I(_n)     (AR5K_PHY_PAPD_I_BASE + ((_n) << 2))
-
-/*
- * PHY PCDAC TX power table
- */
-#define        AR5K_PHY_PCDAC_TXPOWER_BASE     0xa180
-#define        AR5K_PHY_PCDAC_TXPOWER(_n)      (AR5K_PHY_PCDAC_TXPOWER_BASE + ((_n) << 2))
-
-/*
- * PHY mode register [5111+]
- */
-#define        AR5K_PHY_MODE                   0x0a200                 /* Register Address */
-#define        AR5K_PHY_MODE_MOD               0x00000001      /* PHY Modulation bit */
-#define AR5K_PHY_MODE_MOD_OFDM         0
-#define AR5K_PHY_MODE_MOD_CCK          1
-#define AR5K_PHY_MODE_FREQ             0x00000002      /* Freq mode bit */
-#define        AR5K_PHY_MODE_FREQ_5GHZ         0
-#define        AR5K_PHY_MODE_FREQ_2GHZ         2
-#define AR5K_PHY_MODE_MOD_DYN          0x00000004      /* Enable Dynamic OFDM/CCK mode [5112+] */
-#define AR5K_PHY_MODE_RAD              0x00000008      /* [5212+] */
-#define AR5K_PHY_MODE_RAD_RF5111       0
-#define AR5K_PHY_MODE_RAD_RF5112       8
-#define AR5K_PHY_MODE_XR               0x00000010      /* Enable XR mode [5112+] */
-#define        AR5K_PHY_MODE_HALF_RATE         0x00000020      /* Enable Half rate (test) */
-#define        AR5K_PHY_MODE_QUARTER_RATE      0x00000040      /* Enable Quarter rat (test) */
-
-/*
- * PHY CCK transmit control register [5111+ (?)]
- */
-#define AR5K_PHY_CCKTXCTL              0xa204
-#define AR5K_PHY_CCKTXCTL_WORLD                0x00000000
-#define AR5K_PHY_CCKTXCTL_JAPAN                0x00000010
-#define        AR5K_PHY_CCKTXCTL_SCRAMBLER_DIS 0x00000001
-#define        AR5K_PHY_CCKTXCTK_DAC_SCALE     0x00000004
-
-/*
- * PHY CCK Cross-correlator Barker RSSI threshold register [5212+]
- */
-#define AR5K_PHY_CCK_CROSSCORR                 0xa208
-#define AR5K_PHY_CCK_CROSSCORR_WEAK_SIG_THR    0x0000000f
-#define AR5K_PHY_CCK_CROSSCORR_WEAK_SIG_THR_S  0
-
-/* Same address is used for antenna diversity activation */
-#define        AR5K_PHY_FAST_ANT_DIV           0xa208
-#define        AR5K_PHY_FAST_ANT_DIV_EN        0x00002000
-
-/*
- * PHY 2GHz gain register [5111+]
- */
-#define        AR5K_PHY_GAIN_2GHZ                      0xa20c
-#define        AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX          0x00fc0000
-#define        AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX_S        18
-#define        AR5K_PHY_GAIN_2GHZ_INI_5111             0x6480416c
-
-#define        AR5K_PHY_CCK_RX_CTL_4                   0xa21c
-#define        AR5K_PHY_CCK_RX_CTL_4_FREQ_EST_SHORT    0x01f80000
-#define        AR5K_PHY_CCK_RX_CTL_4_FREQ_EST_SHORT_S  19
-
-#define        AR5K_PHY_DAG_CCK_CTL                    0xa228
-#define        AR5K_PHY_DAG_CCK_CTL_EN_RSSI_THR        0x00000200
-#define        AR5K_PHY_DAG_CCK_CTL_RSSI_THR           0x0001fc00
-#define        AR5K_PHY_DAG_CCK_CTL_RSSI_THR_S         10
-
-#define        AR5K_PHY_FAST_ADC       0xa24c
-
-#define        AR5K_PHY_BLUETOOTH      0xa254
-
-/*
- * Transmit Power Control register
- * [2413+]
- */
-#define        AR5K_PHY_TPC_RG1                0xa258
-#define        AR5K_PHY_TPC_RG1_NUM_PD_GAIN    0x0000c000
-#define        AR5K_PHY_TPC_RG1_NUM_PD_GAIN_S  14
-#define AR5K_PHY_TPC_RG1_PDGAIN_1      0x00030000
-#define AR5K_PHY_TPC_RG1_PDGAIN_1_S    16
-#define AR5K_PHY_TPC_RG1_PDGAIN_2      0x000c0000
-#define AR5K_PHY_TPC_RG1_PDGAIN_2_S    18
-#define AR5K_PHY_TPC_RG1_PDGAIN_3      0x00300000
-#define AR5K_PHY_TPC_RG1_PDGAIN_3_S    20
-
-#define        AR5K_PHY_TPC_RG5                        0xa26C
-#define        AR5K_PHY_TPC_RG5_PD_GAIN_OVERLAP        0x0000000F
-#define        AR5K_PHY_TPC_RG5_PD_GAIN_OVERLAP_S      0
-#define        AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_1     0x000003F0
-#define        AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_1_S   4
-#define        AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_2     0x0000FC00
-#define        AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_2_S   10
-#define        AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_3     0x003F0000
-#define        AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_3_S   16
-#define        AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_4     0x0FC00000
-#define        AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_4_S   22
-
-/*
- * PHY PDADC Tx power table
- */
-#define AR5K_PHY_PDADC_TXPOWER_BASE    0xa280
-#define        AR5K_PHY_PDADC_TXPOWER(_n)      (AR5K_PHY_PDADC_TXPOWER_BASE + ((_n) << 2))
diff --git a/drivers/net/wireless/ath5k/reset.c b/drivers/net/wireless/ath5k/reset.c
deleted file mode 100644 (file)
index 5f72c11..0000000
+++ /dev/null
@@ -1,1347 +0,0 @@
-/*
- * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
- * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
- * Copyright (c) 2007-2008 Luis Rodriguez <mcgrof@winlab.rutgers.edu>
- * Copyright (c) 2007-2008 Pavel Roskin <proski@gnu.org>
- * Copyright (c) 2007-2008 Jiri Slaby <jirislaby@gmail.com>
- *
- * Permission to use, copy, modify, and 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.
- *
- */
-
-#define _ATH5K_RESET
-
-/*****************************\
-  Reset functions and helpers
-\*****************************/
-
-#include <linux/pci.h>                 /* To determine if a card is pci-e */
-#include <linux/log2.h>
-#include "ath5k.h"
-#include "reg.h"
-#include "base.h"
-#include "debug.h"
-
-/**
- * ath5k_hw_write_ofdm_timings - set OFDM timings on AR5212
- *
- * @ah: the &struct ath5k_hw
- * @channel: the currently set channel upon reset
- *
- * Write the delta slope coefficient (used on pilot tracking ?) for OFDM
- * operation on the AR5212 upon reset. This is a helper for ath5k_hw_reset().
- *
- * Since delta slope is floating point we split it on its exponent and
- * mantissa and provide these values on hw.
- *
- * For more infos i think this patent is related
- * http://www.freepatentsonline.com/7184495.html
- */
-static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah,
-       struct ieee80211_channel *channel)
-{
-       /* Get exponent and mantissa and set it */
-       u32 coef_scaled, coef_exp, coef_man,
-               ds_coef_exp, ds_coef_man, clock;
-
-       if (!(ah->ah_version == AR5K_AR5212) ||
-               !(channel->hw_value & CHANNEL_OFDM))
-               BUG();
-
-       /* Get coefficient
-        * ALGO: coef = (5 * clock * carrier_freq) / 2)
-        * we scale coef by shifting clock value by 24 for
-        * better precision since we use integers */
-       /* TODO: Half/quarter rate */
-       clock =  ath5k_hw_htoclock(1, channel->hw_value & CHANNEL_TURBO);
-
-       coef_scaled = ((5 * (clock << 24)) / 2) / channel->center_freq;
-
-       /* Get exponent
-        * ALGO: coef_exp = 14 - highest set bit position */
-       coef_exp = ilog2(coef_scaled);
-
-       /* Doesn't make sense if it's zero*/
-       if (!coef_scaled || !coef_exp)
-               return -EINVAL;
-
-       /* Note: we've shifted coef_scaled by 24 */
-       coef_exp = 14 - (coef_exp - 24);
-
-
-       /* Get mantissa (significant digits)
-        * ALGO: coef_mant = floor(coef_scaled* 2^coef_exp+0.5) */
-       coef_man = coef_scaled +
-               (1 << (24 - coef_exp - 1));
-
-       /* Calculate delta slope coefficient exponent
-        * and mantissa (remove scaling) and set them on hw */
-       ds_coef_man = coef_man >> (24 - coef_exp);
-       ds_coef_exp = coef_exp - 16;
-
-       AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3,
-               AR5K_PHY_TIMING_3_DSC_MAN, ds_coef_man);
-       AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3,
-               AR5K_PHY_TIMING_3_DSC_EXP, ds_coef_exp);
-
-       return 0;
-}
-
-
-/*
- * index into rates for control rates, we can set it up like this because
- * this is only used for AR5212 and we know it supports G mode
- */
-static const unsigned int control_rates[] =
-       { 0, 1, 1, 1, 4, 4, 6, 6, 8, 8, 8, 8 };
-
-/**
- * ath5k_hw_write_rate_duration - fill rate code to duration table
- *
- * @ah: the &struct ath5k_hw
- * @mode: one of enum ath5k_driver_mode
- *
- * Write the rate code to duration table upon hw reset. This is a helper for
- * ath5k_hw_reset(). It seems all this is doing is setting an ACK timeout on
- * the hardware, based on current mode, for each rate. The rates which are
- * capable of short preamble (802.11b rates 2Mbps, 5.5Mbps, and 11Mbps) have
- * different rate code so we write their value twice (one for long preample
- * and one for short).
- *
- * Note: Band doesn't matter here, if we set the values for OFDM it works
- * on both a and g modes. So all we have to do is set values for all g rates
- * that include all OFDM and CCK rates. If we operate in turbo or xr/half/
- * quarter rate mode, we need to use another set of bitrates (that's why we
- * need the mode parameter) but we don't handle these proprietary modes yet.
- */
-static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah,
-       unsigned int mode)
-{
-       struct ath5k_softc *sc = ah->ah_sc;
-       struct ieee80211_rate *rate;
-       unsigned int i;
-
-       /* Write rate duration table */
-       for (i = 0; i < sc->sbands[IEEE80211_BAND_2GHZ].n_bitrates; i++) {
-               u32 reg;
-               u16 tx_time;
-
-               rate = &sc->sbands[IEEE80211_BAND_2GHZ].bitrates[control_rates[i]];
-
-               /* Set ACK timeout */
-               reg = AR5K_RATE_DUR(rate->hw_value);
-
-               /* An ACK frame consists of 10 bytes. If you add the FCS,
-                * which ieee80211_generic_frame_duration() adds,
-                * its 14 bytes. Note we use the control rate and not the
-                * actual rate for this rate. See mac80211 tx.c
-                * ieee80211_duration() for a brief description of
-                * what rate we should choose to TX ACKs. */
-               tx_time = le16_to_cpu(ieee80211_generic_frame_duration(sc->hw,
-                                                       sc->vif, 10, rate));
-
-               ath5k_hw_reg_write(ah, tx_time, reg);
-
-               if (!(rate->flags & IEEE80211_RATE_SHORT_PREAMBLE))
-                       continue;
-
-               /*
-                * We're not distinguishing short preamble here,
-                * This is true, all we'll get is a longer value here
-                * which is not necessarilly bad. We could use
-                * export ieee80211_frame_duration() but that needs to be
-                * fixed first to be properly used by mac802111 drivers:
-                *
-                *  - remove erp stuff and let the routine figure ofdm
-                *    erp rates
-                *  - remove passing argument ieee80211_local as
-                *    drivers don't have access to it
-                *  - move drivers using ieee80211_generic_frame_duration()
-                *    to this
-                */
-               ath5k_hw_reg_write(ah, tx_time,
-                       reg + (AR5K_SET_SHORT_PREAMBLE << 2));
-       }
-}
-
-/*
- * Reset chipset
- */
-static int ath5k_hw_nic_reset(struct ath5k_hw *ah, u32 val)
-{
-       int ret;
-       u32 mask = val ? val : ~0U;
-
-       ATH5K_TRACE(ah->ah_sc);
-
-       /* Read-and-clear RX Descriptor Pointer*/
-       ath5k_hw_reg_read(ah, AR5K_RXDP);
-
-       /*
-        * Reset the device and wait until success
-        */
-       ath5k_hw_reg_write(ah, val, AR5K_RESET_CTL);
-
-       /* Wait at least 128 PCI clocks */
-       udelay(15);
-
-       if (ah->ah_version == AR5K_AR5210) {
-               val &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_DMA
-                       | AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_PHY;
-               mask &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_DMA
-                       | AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_PHY;
-       } else {
-               val &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_BASEBAND;
-               mask &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_BASEBAND;
-       }
-
-       ret = ath5k_hw_register_timeout(ah, AR5K_RESET_CTL, mask, val, false);
-
-       /*
-        * Reset configuration register (for hw byte-swap). Note that this
-        * is only set for big endian. We do the necessary magic in
-        * AR5K_INIT_CFG.
-        */
-       if ((val & AR5K_RESET_CTL_PCU) == 0)
-               ath5k_hw_reg_write(ah, AR5K_INIT_CFG, AR5K_CFG);
-
-       return ret;
-}
-
-/*
- * Sleep control
- */
-int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode,
-               bool set_chip, u16 sleep_duration)
-{
-       unsigned int i;
-       u32 staid, data;
-
-       ATH5K_TRACE(ah->ah_sc);
-       staid = ath5k_hw_reg_read(ah, AR5K_STA_ID1);
-
-       switch (mode) {
-       case AR5K_PM_AUTO:
-               staid &= ~AR5K_STA_ID1_DEFAULT_ANTENNA;
-               /* fallthrough */
-       case AR5K_PM_NETWORK_SLEEP:
-               if (set_chip)
-                       ath5k_hw_reg_write(ah,
-                               AR5K_SLEEP_CTL_SLE_ALLOW |
-                               sleep_duration,
-                               AR5K_SLEEP_CTL);
-
-               staid |= AR5K_STA_ID1_PWR_SV;
-               break;
-
-       case AR5K_PM_FULL_SLEEP:
-               if (set_chip)
-                       ath5k_hw_reg_write(ah, AR5K_SLEEP_CTL_SLE_SLP,
-                               AR5K_SLEEP_CTL);
-
-               staid |= AR5K_STA_ID1_PWR_SV;
-               break;
-
-       case AR5K_PM_AWAKE:
-
-               staid &= ~AR5K_STA_ID1_PWR_SV;
-
-               if (!set_chip)
-                       goto commit;
-
-               /* Preserve sleep duration */
-               data = ath5k_hw_reg_read(ah, AR5K_SLEEP_CTL);
-               if (data & 0xffc00000)
-                       data = 0;
-               else
-                       data = data & 0xfffcffff;
-
-               ath5k_hw_reg_write(ah, data, AR5K_SLEEP_CTL);
-               udelay(15);
-
-               for (i = 50; i > 0; i--) {
-                       /* Check if the chip did wake up */
-                       if ((ath5k_hw_reg_read(ah, AR5K_PCICFG) &
-                                       AR5K_PCICFG_SPWR_DN) == 0)
-                               break;
-
-                       /* Wait a bit and retry */
-                       udelay(200);
-                       ath5k_hw_reg_write(ah, data, AR5K_SLEEP_CTL);
-               }
-
-               /* Fail if the chip didn't wake up */
-               if (i <= 0)
-                       return -EIO;
-
-               break;
-
-       default:
-               return -EINVAL;
-       }
-
-commit:
-       ah->ah_power_mode = mode;
-       ath5k_hw_reg_write(ah, staid, AR5K_STA_ID1);
-
-       return 0;
-}
-
-/*
- * Bring up MAC + PHY Chips and program PLL
- * TODO: Half/Quarter rate support
- */
-int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
-{
-       struct pci_dev *pdev = ah->ah_sc->pdev;
-       u32 turbo, mode, clock, bus_flags;
-       int ret;
-
-       turbo = 0;
-       mode = 0;
-       clock = 0;
-
-       ATH5K_TRACE(ah->ah_sc);
-
-       /* Wakeup the device */
-       ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);
-       if (ret) {
-               ATH5K_ERR(ah->ah_sc, "failed to wakeup the MAC Chip\n");
-               return ret;
-       }
-
-       if (ah->ah_version != AR5K_AR5210) {
-               /*
-                * Get channel mode flags
-                */
-
-               if (ah->ah_radio >= AR5K_RF5112) {
-                       mode = AR5K_PHY_MODE_RAD_RF5112;
-                       clock = AR5K_PHY_PLL_RF5112;
-               } else {
-                       mode = AR5K_PHY_MODE_RAD_RF5111;        /*Zero*/
-                       clock = AR5K_PHY_PLL_RF5111;            /*Zero*/
-               }
-
-               if (flags & CHANNEL_2GHZ) {
-                       mode |= AR5K_PHY_MODE_FREQ_2GHZ;
-                       clock |= AR5K_PHY_PLL_44MHZ;
-
-                       if (flags & CHANNEL_CCK) {
-                               mode |= AR5K_PHY_MODE_MOD_CCK;
-                       } else if (flags & CHANNEL_OFDM) {
-                               /* 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
-                                * this, 5211 might support ofdm-only g after
-                                * all, there are also initial register values
-                                * in the code for g mode (see initvals.c). */
-                               if (ah->ah_version == AR5K_AR5211)
-                                       mode |= AR5K_PHY_MODE_MOD_OFDM;
-                               else
-                                       mode |= AR5K_PHY_MODE_MOD_DYN;
-                       } else {
-                               ATH5K_ERR(ah->ah_sc,
-                                       "invalid radio modulation mode\n");
-                               return -EINVAL;
-                       }
-               } else if (flags & CHANNEL_5GHZ) {
-                       mode |= AR5K_PHY_MODE_FREQ_5GHZ;
-
-                       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->ah_sc,
-                                       "invalid radio modulation mode\n");
-                               return -EINVAL;
-                       }
-               } else {
-                       ATH5K_ERR(ah->ah_sc, "invalid radio frequency mode\n");
-                       return -EINVAL;
-               }
-
-               if (flags & CHANNEL_TURBO)
-                       turbo = AR5K_PHY_TURBO_MODE | AR5K_PHY_TURBO_SHORT;
-       } else { /* Reset the device */
-
-               /* ...enable Atheros turbo mode if requested */
-               if (flags & CHANNEL_TURBO)
-                       ath5k_hw_reg_write(ah, AR5K_PHY_TURBO_MODE,
-                                       AR5K_PHY_TURBO);
-       }
-
-       /* reseting PCI on PCI-E cards results card to hang
-        * and always return 0xffff... so we ingore that flag
-        * for PCI-E cards */
-       bus_flags = (pdev->is_pcie) ? 0 : AR5K_RESET_CTL_PCI;
-
-       /* Reset chipset */
-       if (ah->ah_version == AR5K_AR5210) {
-               ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
-                       AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_DMA |
-                       AR5K_RESET_CTL_PHY | AR5K_RESET_CTL_PCI);
-                       mdelay(2);
-       } else {
-               ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
-                       AR5K_RESET_CTL_BASEBAND | bus_flags);
-       }
-       if (ret) {
-               ATH5K_ERR(ah->ah_sc, "failed to reset the MAC Chip\n");
-               return -EIO;
-       }
-
-       /* ...wakeup again!*/
-       ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);
-       if (ret) {
-               ATH5K_ERR(ah->ah_sc, "failed to resume the MAC Chip\n");
-               return ret;
-       }
-
-       /* ...final warm reset */
-       if (ath5k_hw_nic_reset(ah, 0)) {
-               ATH5K_ERR(ah->ah_sc, "failed to warm reset the MAC Chip\n");
-               return -EIO;
-       }
-
-       if (ah->ah_version != AR5K_AR5210) {
-
-               /* ...update PLL if needed */
-               if (ath5k_hw_reg_read(ah, AR5K_PHY_PLL) != clock) {
-                       ath5k_hw_reg_write(ah, clock, AR5K_PHY_PLL);
-                       udelay(300);
-               }
-
-               /* ...set the PHY operating mode */
-               ath5k_hw_reg_write(ah, mode, AR5K_PHY_MODE);
-               ath5k_hw_reg_write(ah, turbo, AR5K_PHY_TURBO);
-       }
-
-       return 0;
-}
-
-/*
- * If there is an external 32KHz crystal available, use it
- * as ref. clock instead of 32/40MHz clock and baseband clocks
- * to save power during sleep or restore normal 32/40MHz
- * operation.
- *
- * XXX: When operating on 32KHz certain PHY registers (27 - 31,
- *     123 - 127) require delay on access.
- */
-static void ath5k_hw_set_sleep_clock(struct ath5k_hw *ah, bool enable)
-{
-       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
-       u32 scal, spending, usec32;
-
-       /* Only set 32KHz settings if we have an external
-        * 32KHz crystal present */
-       if ((AR5K_EEPROM_HAS32KHZCRYSTAL(ee->ee_misc1) ||
-       AR5K_EEPROM_HAS32KHZCRYSTAL_OLD(ee->ee_misc1)) &&
-       enable) {
-
-               /* 1 usec/cycle */
-               AR5K_REG_WRITE_BITS(ah, AR5K_USEC_5211, AR5K_USEC_32, 1);
-               /* Set up tsf increment on each cycle */
-               AR5K_REG_WRITE_BITS(ah, AR5K_TSF_PARM, AR5K_TSF_PARM_INC, 61);
-
-               /* Set baseband sleep control registers
-                * and sleep control rate */
-               ath5k_hw_reg_write(ah, 0x1f, AR5K_PHY_SCR);
-
-               if ((ah->ah_radio == AR5K_RF5112) ||
-               (ah->ah_radio == AR5K_RF5413) ||
-               (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))
-                       spending = 0x14;
-               else
-                       spending = 0x18;
-               ath5k_hw_reg_write(ah, spending, AR5K_PHY_SPENDING);
-
-               if ((ah->ah_radio == AR5K_RF5112) ||
-               (ah->ah_radio == AR5K_RF5413) ||
-               (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) {
-                       ath5k_hw_reg_write(ah, 0x26, AR5K_PHY_SLMT);
-                       ath5k_hw_reg_write(ah, 0x0d, AR5K_PHY_SCAL);
-                       ath5k_hw_reg_write(ah, 0x07, AR5K_PHY_SCLOCK);
-                       ath5k_hw_reg_write(ah, 0x3f, AR5K_PHY_SDELAY);
-                       AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG,
-                               AR5K_PCICFG_SLEEP_CLOCK_RATE, 0x02);
-               } else {
-                       ath5k_hw_reg_write(ah, 0x0a, AR5K_PHY_SLMT);
-                       ath5k_hw_reg_write(ah, 0x0c, AR5K_PHY_SCAL);
-                       ath5k_hw_reg_write(ah, 0x03, AR5K_PHY_SCLOCK);
-                       ath5k_hw_reg_write(ah, 0x20, AR5K_PHY_SDELAY);
-                       AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG,
-                               AR5K_PCICFG_SLEEP_CLOCK_RATE, 0x03);
-               }
-
-               /* Enable sleep clock operation */
-               AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG,
-                               AR5K_PCICFG_SLEEP_CLOCK_EN);
-
-       } else {
-
-               /* Disable sleep clock operation and
-                * restore default parameters */
-               AR5K_REG_DISABLE_BITS(ah, AR5K_PCICFG,
-                               AR5K_PCICFG_SLEEP_CLOCK_EN);
-
-               AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG,
-                               AR5K_PCICFG_SLEEP_CLOCK_RATE, 0);
-
-               ath5k_hw_reg_write(ah, 0x1f, AR5K_PHY_SCR);
-               ath5k_hw_reg_write(ah, AR5K_PHY_SLMT_32MHZ, AR5K_PHY_SLMT);
-
-               if (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))
-                       scal = AR5K_PHY_SCAL_32MHZ_2417;
-               else if (ath5k_eeprom_is_hb63(ah))
-                       scal = AR5K_PHY_SCAL_32MHZ_HB63;
-               else
-                       scal = AR5K_PHY_SCAL_32MHZ;
-               ath5k_hw_reg_write(ah, scal, AR5K_PHY_SCAL);
-
-               ath5k_hw_reg_write(ah, AR5K_PHY_SCLOCK_32MHZ, AR5K_PHY_SCLOCK);
-               ath5k_hw_reg_write(ah, AR5K_PHY_SDELAY_32MHZ, AR5K_PHY_SDELAY);
-
-               if ((ah->ah_radio == AR5K_RF5112) ||
-               (ah->ah_radio == AR5K_RF5413) ||
-               (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))
-                       spending = 0x14;
-               else
-                       spending = 0x18;
-               ath5k_hw_reg_write(ah, spending, AR5K_PHY_SPENDING);
-
-               if ((ah->ah_radio == AR5K_RF5112) ||
-               (ah->ah_radio == AR5K_RF5413))
-                       usec32 = 39;
-               else
-                       usec32 = 31;
-               AR5K_REG_WRITE_BITS(ah, AR5K_USEC_5211, AR5K_USEC_32, usec32);
-
-               AR5K_REG_WRITE_BITS(ah, AR5K_TSF_PARM, AR5K_TSF_PARM_INC, 1);
-       }
-       return;
-}
-
-static bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah,
-                               struct ieee80211_channel *channel)
-{
-       u8 refclk_freq;
-
-       if ((ah->ah_radio == AR5K_RF5112) ||
-       (ah->ah_radio == AR5K_RF5413) ||
-       (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)))
-               refclk_freq = 40;
-       else
-               refclk_freq = 32;
-
-       if ((channel->center_freq % refclk_freq != 0) &&
-       ((channel->center_freq % refclk_freq < 10) ||
-       (channel->center_freq % refclk_freq > 22)))
-               return true;
-       else
-               return false;
-}
-
-/* TODO: Half/Quarter rate */
-static void ath5k_hw_tweak_initval_settings(struct ath5k_hw *ah,
-                               struct ieee80211_channel *channel)
-{
-       if (ah->ah_version == AR5K_AR5212 &&
-           ah->ah_phy_revision >= AR5K_SREV_PHY_5212A) {
-
-               /* Setup ADC control */
-               ath5k_hw_reg_write(ah,
-                               (AR5K_REG_SM(2,
-                               AR5K_PHY_ADC_CTL_INBUFGAIN_OFF) |
-                               AR5K_REG_SM(2,
-                               AR5K_PHY_ADC_CTL_INBUFGAIN_ON) |
-                               AR5K_PHY_ADC_CTL_PWD_DAC_OFF |
-                               AR5K_PHY_ADC_CTL_PWD_ADC_OFF),
-                               AR5K_PHY_ADC_CTL);
-
-
-
-               /* Disable barker RSSI threshold */
-               AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_DAG_CCK_CTL,
-                               AR5K_PHY_DAG_CCK_CTL_EN_RSSI_THR);
-
-               AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DAG_CCK_CTL,
-                       AR5K_PHY_DAG_CCK_CTL_RSSI_THR, 2);
-
-               /* Set the mute mask */
-               ath5k_hw_reg_write(ah, 0x0000000f, AR5K_SEQ_MASK);
-       }
-
-       /* Clear PHY_BLUETOOTH to allow RX_CLEAR line debug */
-       if (ah->ah_phy_revision >= AR5K_SREV_PHY_5212B)
-               ath5k_hw_reg_write(ah, 0, AR5K_PHY_BLUETOOTH);
-
-       /* Enable DCU double buffering */
-       if (ah->ah_phy_revision > AR5K_SREV_PHY_5212B)
-               AR5K_REG_DISABLE_BITS(ah, AR5K_TXCFG,
-                               AR5K_TXCFG_DCU_DBL_BUF_DIS);
-
-       /* Set DAC/ADC delays */
-       if (ah->ah_version == AR5K_AR5212) {
-               u32 scal;
-               if (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))
-                       scal = AR5K_PHY_SCAL_32MHZ_2417;
-               else if (ath5k_eeprom_is_hb63(ah))
-                       scal = AR5K_PHY_SCAL_32MHZ_HB63;
-               else
-                       scal = AR5K_PHY_SCAL_32MHZ;
-               ath5k_hw_reg_write(ah, scal, AR5K_PHY_SCAL);
-       }
-
-       /* Set fast ADC */
-       if ((ah->ah_radio == AR5K_RF5413) ||
-       (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) {
-               u32 fast_adc = true;
-
-               if (channel->center_freq == 2462 ||
-               channel->center_freq == 2467)
-                       fast_adc = 0;
-
-               /* Only update if needed */
-               if (ath5k_hw_reg_read(ah, AR5K_PHY_FAST_ADC) != fast_adc)
-                               ath5k_hw_reg_write(ah, fast_adc,
-                                               AR5K_PHY_FAST_ADC);
-       }
-
-       /* Fix for first revision of the RF5112 RF chipset */
-       if (ah->ah_radio == AR5K_RF5112 &&
-                       ah->ah_radio_5ghz_revision <
-                       AR5K_SREV_RAD_5112A) {
-               u32 data;
-               ath5k_hw_reg_write(ah, AR5K_PHY_CCKTXCTL_WORLD,
-                               AR5K_PHY_CCKTXCTL);
-               if (channel->hw_value & CHANNEL_5GHZ)
-                       data = 0xffb81020;
-               else
-                       data = 0xffb80d20;
-               ath5k_hw_reg_write(ah, data, AR5K_PHY_FRAME_CTL);
-       }
-
-       if (ah->ah_mac_srev < AR5K_SREV_AR5211) {
-               u32 usec_reg;
-               /* 5311 has different tx/rx latency masks
-                * from 5211, since we deal 5311 the same
-                * as 5211 when setting initvals, shift
-                * values here to their proper locations */
-               usec_reg = ath5k_hw_reg_read(ah, AR5K_USEC_5211);
-               ath5k_hw_reg_write(ah, usec_reg & (AR5K_USEC_1 |
-                               AR5K_USEC_32 |
-                               AR5K_USEC_TX_LATENCY_5211 |
-                               AR5K_REG_SM(29,
-                               AR5K_USEC_RX_LATENCY_5210)),
-                               AR5K_USEC_5211);
-               /* Clear QCU/DCU clock gating register */
-               ath5k_hw_reg_write(ah, 0, AR5K_QCUDCU_CLKGT);
-               /* Set DAC/ADC delays */
-               ath5k_hw_reg_write(ah, 0x08, AR5K_PHY_SCAL);
-               /* Enable PCU FIFO corruption ECO */
-               AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW_5211,
-                                       AR5K_DIAG_SW_ECO_ENABLE);
-       }
-}
-
-static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah,
-               struct ieee80211_channel *channel, u8 *ant, u8 ee_mode)
-{
-       struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
-       s16 cck_ofdm_pwr_delta;
-
-       /* Adjust power delta for channel 14 */
-       if (channel->center_freq == 2484)
-               cck_ofdm_pwr_delta =
-                       ((ee->ee_cck_ofdm_power_delta -
-                       ee->ee_scaled_cck_delta) * 2) / 10;
-       else
-               cck_ofdm_pwr_delta =
-                       (ee->ee_cck_ofdm_power_delta * 2) / 10;
-
-       /* 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)
-                       ath5k_hw_reg_write(ah,
-                       AR5K_REG_SM((ee->ee_cck_ofdm_gain_delta * -1),
-                               AR5K_PHY_TX_PWR_ADJ_CCK_GAIN_DELTA) |
-                       AR5K_REG_SM((cck_ofdm_pwr_delta * -1),
-                               AR5K_PHY_TX_PWR_ADJ_CCK_PCDAC_INDEX),
-                               AR5K_PHY_TX_PWR_ADJ);
-               else
-                       ath5k_hw_reg_write(ah, 0, AR5K_PHY_TX_PWR_ADJ);
-       } else {
-               /* For older revs we scale power on sw during tx power
-                * setup */
-               ah->ah_txpower.txp_cck_ofdm_pwr_delta = cck_ofdm_pwr_delta;
-               ah->ah_txpower.txp_cck_ofdm_gainf_delta =
-                                               ee->ee_cck_ofdm_gain_delta;
-       }
-
-       /* Set antenna idle switch table */
-       AR5K_REG_WRITE_BITS(ah, AR5K_PHY_ANT_CTL,
-                       AR5K_PHY_ANT_CTL_SWTABLE_IDLE,
-                       (ah->ah_antenna[ee_mode][0] |
-                       AR5K_PHY_ANT_CTL_TXRX_EN));
-
-       /* Set antenna switch table */
-       ath5k_hw_reg_write(ah, ah->ah_antenna[ee_mode][ant[0]],
-               AR5K_PHY_ANT_SWITCH_TABLE_0);
-       ath5k_hw_reg_write(ah, ah->ah_antenna[ee_mode][ant[1]],
-               AR5K_PHY_ANT_SWITCH_TABLE_1);
-
-       /* Noise floor threshold */
-       ath5k_hw_reg_write(ah,
-               AR5K_PHY_NF_SVAL(ee->ee_noise_floor_thr[ee_mode]),
-               AR5K_PHY_NFTHRES);
-
-       if ((channel->hw_value & CHANNEL_TURBO) &&
-       (ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_0)) {
-               /* Switch settling time (Turbo) */
-               AR5K_REG_WRITE_BITS(ah, AR5K_PHY_SETTLING,
-                               AR5K_PHY_SETTLING_SWITCH,
-                               ee->ee_switch_settling_turbo[ee_mode]);
-
-               /* Tx/Rx attenuation (Turbo) */
-               AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN,
-                               AR5K_PHY_GAIN_TXRX_ATTEN,
-                               ee->ee_atn_tx_rx_turbo[ee_mode]);
-
-               /* ADC/PGA desired size (Turbo) */
-               AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DESIRED_SIZE,
-                               AR5K_PHY_DESIRED_SIZE_ADC,
-                               ee->ee_adc_desired_size_turbo[ee_mode]);
-
-               AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DESIRED_SIZE,
-                               AR5K_PHY_DESIRED_SIZE_PGA,
-                               ee->ee_pga_desired_size_turbo[ee_mode]);
-
-               /* Tx/Rx margin (Turbo) */
-               AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN_2GHZ,
-                               AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX,
-                               ee->ee_margin_tx_rx_turbo[ee_mode]);
-
-       } else {
-               /* Switch settling time */
-               AR5K_REG_WRITE_BITS(ah, AR5K_PHY_SETTLING,
-                               AR5K_PHY_SETTLING_SWITCH,
-                               ee->ee_switch_settling[ee_mode]);
-
-               /* Tx/Rx attenuation */
-               AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN,
-                               AR5K_PHY_GAIN_TXRX_ATTEN,
-                               ee->ee_atn_tx_rx[ee_mode]);
-
-               /* ADC/PGA desired size */
-               AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DESIRED_SIZE,
-                               AR5K_PHY_DESIRED_SIZE_ADC,
-                               ee->ee_adc_desired_size[ee_mode]);
-
-               AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DESIRED_SIZE,
-                               AR5K_PHY_DESIRED_SIZE_PGA,
-                               ee->ee_pga_desired_size[ee_mode]);
-
-               /* Tx/Rx margin */
-               if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1)
-                       AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN_2GHZ,
-                               AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX,
-                               ee->ee_margin_tx_rx[ee_mode]);
-       }
-
-       /* XPA delays */
-       ath5k_hw_reg_write(ah,
-               (ee->ee_tx_end2xpa_disable[ee_mode] << 24) |
-               (ee->ee_tx_end2xpa_disable[ee_mode] << 16) |
-               (ee->ee_tx_frm2xpa_enable[ee_mode] << 8) |
-               (ee->ee_tx_frm2xpa_enable[ee_mode]), AR5K_PHY_RF_CTL4);
-
-       /* XLNA delay */
-       AR5K_REG_WRITE_BITS(ah, AR5K_PHY_RF_CTL3,
-                       AR5K_PHY_RF_CTL3_TXE2XLNA_ON,
-                       ee->ee_tx_end2xlna_enable[ee_mode]);
-
-       /* Thresh64 (ANI) */
-       AR5K_REG_WRITE_BITS(ah, AR5K_PHY_NF,
-                       AR5K_PHY_NF_THRESH62,
-                       ee->ee_thr_62[ee_mode]);
-
-
-       /* False detect backoff for channels
-        * that have spur noise. Write the new
-        * cyclic power RSSI threshold. */
-       if (ath5k_hw_chan_has_spur_noise(ah, channel))
-               AR5K_REG_WRITE_BITS(ah, AR5K_PHY_OFDM_SELFCORR,
-                               AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1,
-                               AR5K_INIT_CYCRSSI_THR1 +
-                               ee->ee_false_detect[ee_mode]);
-       else
-               AR5K_REG_WRITE_BITS(ah, AR5K_PHY_OFDM_SELFCORR,
-                               AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1,
-                               AR5K_INIT_CYCRSSI_THR1);
-
-       /* I/Q correction
-        * TODO: Per channel i/q infos ? */
-       AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ,
-               AR5K_PHY_IQ_CORR_ENABLE |
-               (ee->ee_i_cal[ee_mode] << AR5K_PHY_IQ_CORR_Q_I_COFF_S) |
-               ee->ee_q_cal[ee_mode]);
-
-       /* Heavy clipping -disable for now */
-       if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_1)
-               ath5k_hw_reg_write(ah, 0, AR5K_PHY_HEAVY_CLIP_ENABLE);
-
-       return;
-}
-
-/*
- * Main reset function
- */
-int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
-       struct ieee80211_channel *channel, bool change_channel)
-{
-       u32 s_seq[10], s_ant, s_led[3], staid1_flags, tsf_up, tsf_lo;
-       u32 phy_tst1;
-       u8 mode, freq, ee_mode, ant[2];
-       int i, ret;
-
-       ATH5K_TRACE(ah->ah_sc);
-
-       s_ant = 0;
-       ee_mode = 0;
-       staid1_flags = 0;
-       tsf_up = 0;
-       tsf_lo = 0;
-       freq = 0;
-       mode = 0;
-
-       /*
-        * Save some registers before a reset
-        */
-       /*DCU/Antenna selection not available on 5210*/
-       if (ah->ah_version != AR5K_AR5210) {
-
-               switch (channel->hw_value & CHANNEL_MODES) {
-               case CHANNEL_A:
-                       mode = AR5K_MODE_11A;
-                       freq = AR5K_INI_RFGAIN_5GHZ;
-                       ee_mode = AR5K_EEPROM_MODE_11A;
-                       break;
-               case CHANNEL_G:
-                       mode = AR5K_MODE_11G;
-                       freq = AR5K_INI_RFGAIN_2GHZ;
-                       ee_mode = AR5K_EEPROM_MODE_11G;
-                       break;
-               case CHANNEL_B:
-                       mode = AR5K_MODE_11B;
-                       freq = AR5K_INI_RFGAIN_2GHZ;
-                       ee_mode = AR5K_EEPROM_MODE_11B;
-                       break;
-               case CHANNEL_T:
-                       mode = AR5K_MODE_11A_TURBO;
-                       freq = AR5K_INI_RFGAIN_5GHZ;
-                       ee_mode = AR5K_EEPROM_MODE_11A;
-                       break;
-               case CHANNEL_TG:
-                       if (ah->ah_version == AR5K_AR5211) {
-                               ATH5K_ERR(ah->ah_sc,
-                                       "TurboG mode not available on 5211");
-                               return -EINVAL;
-                       }
-                       mode = AR5K_MODE_11G_TURBO;
-                       freq = AR5K_INI_RFGAIN_2GHZ;
-                       ee_mode = AR5K_EEPROM_MODE_11G;
-                       break;
-               case CHANNEL_XR:
-                       if (ah->ah_version == AR5K_AR5211) {
-                               ATH5K_ERR(ah->ah_sc,
-                                       "XR mode not available on 5211");
-                               return -EINVAL;
-                       }
-                       mode = AR5K_MODE_XR;
-                       freq = AR5K_INI_RFGAIN_5GHZ;
-                       ee_mode = AR5K_EEPROM_MODE_11A;
-                       break;
-               default:
-                       ATH5K_ERR(ah->ah_sc,
-                               "invalid channel: %d\n", channel->center_freq);
-                       return -EINVAL;
-               }
-
-               if (change_channel) {
-                       /*
-                        * Save frame sequence count
-                        * For revs. after Oahu, only save
-                        * seq num for DCU 0 (Global seq num)
-                        */
-                       if (ah->ah_mac_srev < AR5K_SREV_AR5211) {
-
-                               for (i = 0; i < 10; i++)
-                                       s_seq[i] = ath5k_hw_reg_read(ah,
-                                               AR5K_QUEUE_DCU_SEQNUM(i));
-
-                       } else {
-                               s_seq[0] = ath5k_hw_reg_read(ah,
-                                               AR5K_QUEUE_DCU_SEQNUM(0));
-                       }
-
-                       /* TSF accelerates on AR5211 durring reset
-                        * As a workaround save it here and restore
-                        * it later so that it's back in time after
-                        * reset. This way it'll get re-synced on the
-                        * next beacon without breaking ad-hoc.
-                        *
-                        * On AR5212 TSF is almost preserved across a
-                        * reset so it stays back in time anyway and
-                        * we don't have to save/restore it.
-                        *
-                        * XXX: Since this breaks power saving we have
-                        * to disable power saving until we receive the
-                        * next beacon, so we can resync beacon timers */
-                       if (ah->ah_version == AR5K_AR5211) {
-                               tsf_up = ath5k_hw_reg_read(ah, AR5K_TSF_U32);
-                               tsf_lo = ath5k_hw_reg_read(ah, AR5K_TSF_L32);
-                       }
-               }
-
-               /* Save default antenna */
-               s_ant = ath5k_hw_reg_read(ah, AR5K_DEFAULT_ANTENNA);
-
-               if (ah->ah_version == AR5K_AR5212) {
-                       /* Restore normal 32/40MHz clock operation
-                        * to avoid register access delay on certain
-                        * PHY registers */
-                       ath5k_hw_set_sleep_clock(ah, false);
-
-                       /* Since we are going to write rf buffer
-                        * check if we have any pending gain_F
-                        * optimization settings */
-                       if (change_channel && ah->ah_rf_banks != NULL)
-                               ath5k_hw_gainf_calibrate(ah);
-               }
-       }
-
-       /*GPIOs*/
-       s_led[0] = ath5k_hw_reg_read(ah, AR5K_PCICFG) &
-                                       AR5K_PCICFG_LEDSTATE;
-       s_led[1] = ath5k_hw_reg_read(ah, AR5K_GPIOCR);
-       s_led[2] = ath5k_hw_reg_read(ah, AR5K_GPIODO);
-
-       /* AR5K_STA_ID1 flags, only preserve antenna
-        * settings and ack/cts rate mode */
-       staid1_flags = ath5k_hw_reg_read(ah, AR5K_STA_ID1) &
-                       (AR5K_STA_ID1_DEFAULT_ANTENNA |
-                       AR5K_STA_ID1_DESC_ANTENNA |
-                       AR5K_STA_ID1_RTS_DEF_ANTENNA |
-                       AR5K_STA_ID1_ACKCTS_6MB |
-                       AR5K_STA_ID1_BASE_RATE_11B |
-                       AR5K_STA_ID1_SELFGEN_DEF_ANT);
-
-       /* Wakeup the device */
-       ret = ath5k_hw_nic_wakeup(ah, channel->hw_value, false);
-       if (ret)
-               return ret;
-
-       /*
-        * Initialize operating mode
-        */
-       ah->ah_op_mode = op_mode;
-
-       /* PHY access enable */
-       if (ah->ah_mac_srev >= AR5K_SREV_AR5211)
-               ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0));
-       else
-               ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ | 0x40,
-                                                       AR5K_PHY(0));
-
-       /* Write initial settings */
-       ret = ath5k_hw_write_initvals(ah, mode, change_channel);
-       if (ret)
-               return ret;
-
-       /*
-        * 5211/5212 Specific
-        */
-       if (ah->ah_version != AR5K_AR5210) {
-
-               /*
-                * Write initial RF gain settings
-                * This should work for both 5111/5112
-                */
-               ret = ath5k_hw_rfgain_init(ah, freq);
-               if (ret)
-                       return ret;
-
-               mdelay(1);
-
-               /*
-                * Tweak initval settings for revised
-                * chipsets and add some more config
-                * bits
-                */
-               ath5k_hw_tweak_initval_settings(ah, channel);
-
-               /*
-                * Set TX power (FIXME)
-                */
-               ret = ath5k_hw_txpower(ah, channel, ee_mode,
-                                       AR5K_TUNE_DEFAULT_TXPOWER);
-               if (ret)
-                       return ret;
-
-               /* Write rate duration table only on AR5212 and if
-                * virtual interface has already been brought up
-                * XXX: rethink this after new mode changes to
-                * mac80211 are integrated */
-               if (ah->ah_version == AR5K_AR5212 &&
-                       ah->ah_sc->vif != NULL)
-                       ath5k_hw_write_rate_duration(ah, mode);
-
-               /*
-                * Write RF buffer
-                */
-               ret = ath5k_hw_rfregs_init(ah, channel, mode);
-               if (ret)
-                       return ret;
-
-
-               /* Write OFDM timings on 5212*/
-               if (ah->ah_version == AR5K_AR5212 &&
-                       channel->hw_value & CHANNEL_OFDM) {
-                       ret = ath5k_hw_write_ofdm_timings(ah, channel);
-                       if (ret)
-                               return ret;
-               }
-
-               /*Enable/disable 802.11b mode on 5111
-               (enable 2111 frequency converter + CCK)*/
-               if (ah->ah_radio == AR5K_RF5111) {
-                       if (mode == AR5K_MODE_11B)
-                               AR5K_REG_ENABLE_BITS(ah, AR5K_TXCFG,
-                                   AR5K_TXCFG_B_MODE);
-                       else
-                               AR5K_REG_DISABLE_BITS(ah, AR5K_TXCFG,
-                                   AR5K_TXCFG_B_MODE);
-               }
-
-               /*
-                * In case a fixed antenna was set as default
-                * write the same settings on both AR5K_PHY_ANT_SWITCH_TABLE
-                * registers.
-                */
-               if (s_ant != 0) {
-                       if (s_ant == AR5K_ANT_FIXED_A) /* 1 - Main */
-                               ant[0] = ant[1] = AR5K_ANT_FIXED_A;
-                       else    /* 2 - Aux */
-                               ant[0] = ant[1] = AR5K_ANT_FIXED_B;
-               } else {
-                       ant[0] = AR5K_ANT_FIXED_A;
-                       ant[1] = AR5K_ANT_FIXED_B;
-               }
-
-               /* Commit values from EEPROM */
-               ath5k_hw_commit_eeprom_settings(ah, channel, ant, ee_mode);
-
-       } else {
-               /*
-                * For 5210 we do all initialization using
-                * initvals, so we don't have to modify
-                * any settings (5210 also only supports
-                * a/aturbo modes)
-                */
-               mdelay(1);
-               /* Disable phy and wait */
-               ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT);
-               mdelay(1);
-       }
-
-       /*
-        * Restore saved values
-        */
-
-       /*DCU/Antenna selection not available on 5210*/
-       if (ah->ah_version != AR5K_AR5210) {
-
-               if (change_channel) {
-                       if (ah->ah_mac_srev < AR5K_SREV_AR5211) {
-                               for (i = 0; i < 10; i++)
-                                       ath5k_hw_reg_write(ah, s_seq[i],
-                                               AR5K_QUEUE_DCU_SEQNUM(i));
-                       } else {
-                               ath5k_hw_reg_write(ah, s_seq[0],
-                                       AR5K_QUEUE_DCU_SEQNUM(0));
-                       }
-
-
-                       if (ah->ah_version == AR5K_AR5211) {
-                               ath5k_hw_reg_write(ah, tsf_up, AR5K_TSF_U32);
-                               ath5k_hw_reg_write(ah, tsf_lo, AR5K_TSF_L32);
-                       }
-               }
-
-               ath5k_hw_reg_write(ah, s_ant, AR5K_DEFAULT_ANTENNA);
-       }
-
-       /* Ledstate */
-       AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, s_led[0]);
-
-       /* Gpio settings */
-       ath5k_hw_reg_write(ah, s_led[1], AR5K_GPIOCR);
-       ath5k_hw_reg_write(ah, s_led[2], AR5K_GPIODO);
-
-       /* Restore sta_id flags and preserve our mac address*/
-       ath5k_hw_reg_write(ah, AR5K_LOW_ID(ah->ah_sta_id),
-                                               AR5K_STA_ID0);
-       ath5k_hw_reg_write(ah, staid1_flags | AR5K_HIGH_ID(ah->ah_sta_id),
-                                               AR5K_STA_ID1);
-
-
-       /*
-        * Configure PCU
-        */
-
-       /* Restore bssid and bssid mask */
-       /* XXX: add ah->aid once mac80211 gives this to us */
-       ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
-
-       /* Set PCU config */
-       ath5k_hw_set_opmode(ah);
-
-       /* Clear any pending interrupts
-        * PISR/SISR Not available on 5210 */
-       if (ah->ah_version != AR5K_AR5210)
-               ath5k_hw_reg_write(ah, 0xffffffff, AR5K_PISR);
-
-       /* Set RSSI/BRSSI thresholds
-        *
-        * Note: If we decide to set this value
-        * dynamicaly, have in mind that when AR5K_RSSI_THR
-        * register is read it might return 0x40 if we haven't
-        * wrote anything to it plus BMISS RSSI threshold is zeroed.
-        * So doing a save/restore procedure here isn't the right
-        * choice. Instead store it on ath5k_hw */
-       ath5k_hw_reg_write(ah, (AR5K_TUNE_RSSI_THRES |
-                               AR5K_TUNE_BMISS_THRES <<
-                               AR5K_RSSI_THR_BMISS_S),
-                               AR5K_RSSI_THR);
-
-       /* MIC QoS support */
-       if (ah->ah_mac_srev >= AR5K_SREV_AR2413) {
-               ath5k_hw_reg_write(ah, 0x000100aa, AR5K_MIC_QOS_CTL);
-               ath5k_hw_reg_write(ah, 0x00003210, AR5K_MIC_QOS_SEL);
-       }
-
-       /* QoS NOACK Policy */
-       if (ah->ah_version == AR5K_AR5212) {
-               ath5k_hw_reg_write(ah,
-                       AR5K_REG_SM(2, AR5K_QOS_NOACK_2BIT_VALUES) |
-                       AR5K_REG_SM(5, AR5K_QOS_NOACK_BIT_OFFSET)  |
-                       AR5K_REG_SM(0, AR5K_QOS_NOACK_BYTE_OFFSET),
-                       AR5K_QOS_NOACK);
-       }
-
-
-       /*
-        * Configure PHY
-        */
-
-       /* Set channel on PHY */
-       ret = ath5k_hw_channel(ah, channel);
-       if (ret)
-               return ret;
-
-       /*
-        * Enable the PHY and wait until completion
-        * This includes BaseBand and Synthesizer
-        * activation.
-        */
-       ath5k_hw_reg_write(ah, AR5K_PHY_ACT_ENABLE, AR5K_PHY_ACT);
-
-       /*
-        * On 5211+ read activation -> rx delay
-        * and use it.
-        *
-        * TODO: Half/quarter rate support
-        */
-       if (ah->ah_version != AR5K_AR5210) {
-               u32 delay;
-               delay = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) &
-                       AR5K_PHY_RX_DELAY_M;
-               delay = (channel->hw_value & CHANNEL_CCK) ?
-                       ((delay << 2) / 22) : (delay / 10);
-
-               udelay(100 + (2 * delay));
-       } else {
-               mdelay(1);
-       }
-
-       /*
-        * Perform ADC test to see if baseband is ready
-        * Set tx hold and check adc test register
-        */
-       phy_tst1 = ath5k_hw_reg_read(ah, AR5K_PHY_TST1);
-       ath5k_hw_reg_write(ah, AR5K_PHY_TST1_TXHOLD, AR5K_PHY_TST1);
-       for (i = 0; i <= 20; i++) {
-               if (!(ath5k_hw_reg_read(ah, AR5K_PHY_ADC_TEST) & 0x10))
-                       break;
-               udelay(200);
-       }
-       ath5k_hw_reg_write(ah, phy_tst1, AR5K_PHY_TST1);
-
-       /*
-        * Start automatic gain control calibration
-        *
-        * During AGC calibration RX path is re-routed to
-        * a power detector so we don't receive anything.
-        *
-        * This method is used to calibrate some static offsets
-        * used together with on-the fly I/Q calibration (the
-        * one performed via ath5k_hw_phy_calibrate), that doesn't
-        * interrupt rx path.
-        *
-        * While rx path is re-routed to the power detector we also
-        * start a noise floor calibration, to measure the
-        * card's noise floor (the noise we measure when we are not
-        * transmiting or receiving anything).
-        *
-        * If we are in a noisy environment AGC calibration may time
-        * out and/or noise floor calibration might timeout.
-        */
-       AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
-                               AR5K_PHY_AGCCTL_CAL);
-
-       /* At the same time start I/Q calibration for QAM constellation
-        * -no need for CCK- */
-       ah->ah_calibration = false;
-       if (!(mode == AR5K_MODE_11B)) {
-               ah->ah_calibration = true;
-               AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ,
-                               AR5K_PHY_IQ_CAL_NUM_LOG_MAX, 15);
-               AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ,
-                               AR5K_PHY_IQ_RUN);
-       }
-
-       /* Wait for gain calibration to finish (we check for I/Q calibration
-        * during ath5k_phy_calibrate) */
-       if (ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL,
-                       AR5K_PHY_AGCCTL_CAL, 0, false)) {
-               ATH5K_ERR(ah->ah_sc, "gain calibration timeout (%uMHz)\n",
-                       channel->center_freq);
-       }
-
-       /*
-        * If we run NF calibration before AGC, it always times out.
-        * Binary HAL starts NF and AGC calibration at the same time
-        * and only waits for AGC to finish. Also if AGC or NF cal.
-        * times out, reset doesn't fail on binary HAL. I believe
-        * that's wrong because since rx path is routed to a detector,
-        * if cal. doesn't finish we won't have RX. Sam's HAL for AR5210/5211
-        * enables noise floor calibration after offset calibration and if noise
-        * floor calibration fails, reset fails. I believe that's
-        * a better approach, we just need to find a polling interval
-        * that suits best, even if reset continues we need to make
-        * sure that rx path is ready.
-        */
-       ath5k_hw_noise_floor_calibration(ah, channel->center_freq);
-
-
-       /*
-        * Configure QCUs/DCUs
-        */
-
-       /* TODO: HW Compression support for data queues */
-       /* TODO: Burst prefetch for data queues */
-
-       /*
-        * Reset queues and start beacon timers at the end of the reset routine
-        * This also sets QCU mask on each DCU for 1:1 qcu to dcu mapping
-        * Note: If we want we can assign multiple qcus on one dcu.
-        */
-       for (i = 0; i < ah->ah_capabilities.cap_queues.q_tx_num; i++) {
-               ret = ath5k_hw_reset_tx_queue(ah, i);
-               if (ret) {
-                       ATH5K_ERR(ah->ah_sc,
-                               "failed to reset TX queue #%d\n", i);
-                       return ret;
-               }
-       }
-
-
-       /*
-        * Configure DMA/Interrupts
-        */
-
-       /*
-        * Set Rx/Tx DMA Configuration
-        *
-        * Set standard DMA size (128). Note that
-        * a DMA size of 512 causes rx overruns and tx errors
-        * on pci-e cards (tested on 5424 but since rx overruns
-        * also occur on 5416/5418 with madwifi we set 128
-        * for all PCI-E cards to be safe).
-        *
-        * XXX: need to check 5210 for this
-        * TODO: Check out tx triger level, it's always 64 on dumps but I
-        * guess we can tweak it and see how it goes ;-)
-        */
-       if (ah->ah_version != AR5K_AR5210) {
-               AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG,
-                       AR5K_TXCFG_SDMAMR, AR5K_DMASIZE_128B);
-               AR5K_REG_WRITE_BITS(ah, AR5K_RXCFG,
-                       AR5K_RXCFG_SDMAMW, AR5K_DMASIZE_128B);
-       }
-
-       /* Pre-enable interrupts on 5211/5212*/
-       if (ah->ah_version != AR5K_AR5210)
-               ath5k_hw_set_imr(ah, ah->ah_imr);
-
-       /*
-        * Setup RFKill interrupt if rfkill flag is set on eeprom.
-        * TODO: Use gpio pin and polarity infos from eeprom
-        * TODO: Handle this in ath5k_intr because it'll result
-        *       a nasty interrupt storm.
-        */
-#if 0
-       if (AR5K_EEPROM_HDR_RFKILL(ah->ah_capabilities.cap_eeprom.ee_header)) {
-               ath5k_hw_set_gpio_input(ah, 0);
-               ah->ah_gpio[0] = ath5k_hw_get_gpio(ah, 0);
-               if (ah->ah_gpio[0] == 0)
-                       ath5k_hw_set_gpio_intr(ah, 0, 1);
-               else
-                       ath5k_hw_set_gpio_intr(ah, 0, 0);
-       }
-#endif
-
-       /* Enable 32KHz clock function for AR5212+ chips
-        * Set clocks to 32KHz operation and use an
-        * external 32KHz crystal when sleeping if one
-        * exists */
-       if (ah->ah_version == AR5K_AR5212)
-                       ath5k_hw_set_sleep_clock(ah, true);
-
-       /*
-        * Disable beacons and reset the register
-        */
-       AR5K_REG_DISABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE |
-                       AR5K_BEACON_RESET_TSF);
-
-       return 0;
-}
-
-#undef _ATH5K_RESET
diff --git a/drivers/net/wireless/ath5k/rfbuffer.h b/drivers/net/wireless/ath5k/rfbuffer.h
deleted file mode 100644 (file)
index e50baff..0000000
+++ /dev/null
@@ -1,1181 +0,0 @@
-/*
- * RF Buffer handling functions
- *
- * Copyright (c) 2009 Nick Kossifidis <mickflemm@gmail.com>
- *
- * Permission to use, copy, modify, and 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.
- *
- */
-
-
-/*
- * There are some special registers on the RF chip
- * that control various operation settings related mostly to
- * the analog parts (channel, gain adjustment etc).
- *
- * We don't write on those registers directly but
- * we send a data packet on the chip, using a special register,
- * that holds all the settings we need. After we 've sent the
- * data packet, we write on another special register to notify hw
- * to apply the settings. This is done so that control registers
- * can be dynamicaly programmed during operation and the settings
- * are applied faster on the hw.
- *
- * We call each data packet an "RF Bank" and all the data we write
- * (all RF Banks) "RF Buffer". This file holds initial RF Buffer
- * data for the different RF chips, and various info to match RF
- * Buffer offsets with specific RF registers so that we can access
- * them. We tweak these settings on rfregs_init function.
- *
- * Also check out reg.h and U.S. Patent 6677779 B1 (about buffer
- * registers and control registers):
- *
- * http://www.google.com/patents?id=qNURAAAAEBAJ
- */
-
-
-/*
- * Struct to hold default mode specific RF
- * register values (RF Banks)
- */
-struct ath5k_ini_rfbuffer {
-       u8      rfb_bank;               /* RF Bank number */
-       u16     rfb_ctrl_register;      /* RF Buffer control register */
-       u32     rfb_mode_data[5];       /* RF Buffer data for each mode */
-};
-
-/*
- * Struct to hold RF Buffer field
- * infos used to access certain RF
- * analog registers
- */
-struct ath5k_rfb_field {
-       u8      len;    /* Field length */
-       u16     pos;    /* Offset on the raw packet */
-       u8      col;    /* Column -used for shifting */
-};
-
-/*
- * RF analog register definition
- */
-struct ath5k_rf_reg {
-       u8                      bank;   /* RF Buffer Bank number */
-       u8                      index;  /* Register's index on rf_regs_idx */
-       struct ath5k_rfb_field  field;  /* RF Buffer field for this register */
-};
-
-/* Map RF registers to indexes
- * We do this to handle common bits and make our
- * life easier by using an index for each register
- * instead of a full rfb_field */
-enum ath5k_rf_regs_idx {
-       /* BANK 6 */
-       AR5K_RF_OB_2GHZ = 0,
-       AR5K_RF_OB_5GHZ,
-       AR5K_RF_DB_2GHZ,
-       AR5K_RF_DB_5GHZ,
-       AR5K_RF_FIXED_BIAS_A,
-       AR5K_RF_FIXED_BIAS_B,
-       AR5K_RF_PWD_XPD,
-       AR5K_RF_XPD_SEL,
-       AR5K_RF_XPD_GAIN,
-       AR5K_RF_PD_GAIN_LO,
-       AR5K_RF_PD_GAIN_HI,
-       AR5K_RF_HIGH_VC_CP,
-       AR5K_RF_MID_VC_CP,
-       AR5K_RF_LOW_VC_CP,
-       AR5K_RF_PUSH_UP,
-       AR5K_RF_PAD2GND,
-       AR5K_RF_XB2_LVL,
-       AR5K_RF_XB5_LVL,
-       AR5K_RF_PWD_ICLOBUF_2G,
-       AR5K_RF_PWD_84,
-       AR5K_RF_PWD_90,
-       AR5K_RF_PWD_130,
-       AR5K_RF_PWD_131,
-       AR5K_RF_PWD_132,
-       AR5K_RF_PWD_136,
-       AR5K_RF_PWD_137,
-       AR5K_RF_PWD_138,
-       AR5K_RF_PWD_166,
-       AR5K_RF_PWD_167,
-       AR5K_RF_DERBY_CHAN_SEL_MODE,
-       /* BANK 7 */
-       AR5K_RF_GAIN_I,
-       AR5K_RF_PLO_SEL,
-       AR5K_RF_RFGAIN_SEL,
-       AR5K_RF_RFGAIN_STEP,
-       AR5K_RF_WAIT_S,
-       AR5K_RF_WAIT_I,
-       AR5K_RF_MAX_TIME,
-       AR5K_RF_MIXVGA_OVR,
-       AR5K_RF_MIXGAIN_OVR,
-       AR5K_RF_MIXGAIN_STEP,
-       AR5K_RF_PD_DELAY_A,
-       AR5K_RF_PD_DELAY_B,
-       AR5K_RF_PD_DELAY_XR,
-       AR5K_RF_PD_PERIOD_A,
-       AR5K_RF_PD_PERIOD_B,
-       AR5K_RF_PD_PERIOD_XR,
-};
-
-
-/*******************\
-* RF5111 (Sombrero) *
-\*******************/
-
-/* BANK 6                              len  pos col */
-#define        AR5K_RF5111_OB_2GHZ             { 3, 119, 0 }
-#define        AR5K_RF5111_DB_2GHZ             { 3, 122, 0 }
-
-#define        AR5K_RF5111_OB_5GHZ             { 3, 104, 0 }
-#define        AR5K_RF5111_DB_5GHZ             { 3, 107, 0 }
-
-#define        AR5K_RF5111_PWD_XPD             { 1, 95,  0 }
-#define        AR5K_RF5111_XPD_GAIN            { 4, 96,  0 }
-
-/* Access to PWD registers */
-#define AR5K_RF5111_PWD(_n)            { 1, (135 - _n), 3 }
-
-/* BANK 7                              len  pos col */
-#define        AR5K_RF5111_GAIN_I              { 6, 29,  0 }
-#define        AR5K_RF5111_PLO_SEL             { 1, 4,   0 }
-#define        AR5K_RF5111_RFGAIN_SEL          { 1, 36,  0 }
-#define AR5K_RF5111_RFGAIN_STEP                { 6, 37,  0 }
-/* Only on AR5212 BaseBand and up */
-#define        AR5K_RF5111_WAIT_S              { 5, 19,  0 }
-#define        AR5K_RF5111_WAIT_I              { 5, 24,  0 }
-#define        AR5K_RF5111_MAX_TIME            { 2, 49,  0 }
-
-static const struct ath5k_rf_reg rf_regs_5111[] = {
-       {6, AR5K_RF_OB_2GHZ,            AR5K_RF5111_OB_2GHZ},
-       {6, AR5K_RF_DB_2GHZ,            AR5K_RF5111_DB_2GHZ},
-       {6, AR5K_RF_OB_5GHZ,            AR5K_RF5111_OB_5GHZ},
-       {6, AR5K_RF_DB_5GHZ,            AR5K_RF5111_DB_5GHZ},
-       {6, AR5K_RF_PWD_XPD,            AR5K_RF5111_PWD_XPD},
-       {6, AR5K_RF_XPD_GAIN,           AR5K_RF5111_XPD_GAIN},
-       {6, AR5K_RF_PWD_84,             AR5K_RF5111_PWD(84)},
-       {6, AR5K_RF_PWD_90,             AR5K_RF5111_PWD(90)},
-       {7, AR5K_RF_GAIN_I,             AR5K_RF5111_GAIN_I},
-       {7, AR5K_RF_PLO_SEL,            AR5K_RF5111_PLO_SEL},
-       {7, AR5K_RF_RFGAIN_SEL,         AR5K_RF5111_RFGAIN_SEL},
-       {7, AR5K_RF_RFGAIN_STEP,        AR5K_RF5111_RFGAIN_STEP},
-       {7, AR5K_RF_WAIT_S,             AR5K_RF5111_WAIT_S},
-       {7, AR5K_RF_WAIT_I,             AR5K_RF5111_WAIT_I},
-       {7, AR5K_RF_MAX_TIME,           AR5K_RF5111_MAX_TIME}
-};
-
-/* Default mode specific settings */
-static const struct ath5k_ini_rfbuffer rfb_5111[] = {
-       { 0, 0x989c,
-       /*     mode a/XR  mode aTurbo    mode b     mode g    mode gTurbo */
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 0, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 0, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 0, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 0, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 0, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 0, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 0, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 0, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 0, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 0, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 0, 0x989c,
-           { 0x00380000, 0x00380000, 0x00380000, 0x00380000, 0x00380000 } },
-       { 0, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 0, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 0, 0x989c,
-           { 0x00000000, 0x00000000, 0x000000c0, 0x00000080, 0x00000080 } },
-       { 0, 0x989c,
-           { 0x000400f9, 0x000400f9, 0x000400ff, 0x000400fd, 0x000400fd } },
-       { 0, 0x98d4,
-           { 0x00000000, 0x00000000, 0x00000004, 0x00000004, 0x00000004 } },
-       { 1, 0x98d4,
-           { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
-       { 2, 0x98d4,
-           { 0x00000010, 0x00000014, 0x00000010, 0x00000010, 0x00000014 } },
-       { 3, 0x98d8,
-           { 0x00601068, 0x00601068, 0x00601068, 0x00601068, 0x00601068 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000 } },
-       { 6, 0x989c,
-           { 0x04000000, 0x04000000, 0x04000000, 0x04000000, 0x04000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x0a000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x003800c0, 0x00380080, 0x023800c0, 0x003800c0, 0x003800c0 } },
-       { 6, 0x989c,
-           { 0x00020006, 0x00020006, 0x00000006, 0x00020006, 0x00020006 } },
-       { 6, 0x989c,
-           { 0x00000089, 0x00000089, 0x00000089, 0x00000089, 0x00000089 } },
-       { 6, 0x989c,
-           { 0x000000a0, 0x000000a0, 0x000000a0, 0x000000a0, 0x000000a0 } },
-       { 6, 0x989c,
-           { 0x00040007, 0x00040007, 0x00040007, 0x00040007, 0x00040007 } },
-       { 6, 0x98d4,
-           { 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a } },
-       { 7, 0x989c,
-           { 0x00000040, 0x00000048, 0x00000040, 0x00000040, 0x00000040 } },
-       { 7, 0x989c,
-           { 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010 } },
-       { 7, 0x989c,
-           { 0x00000008, 0x00000008, 0x00000008, 0x00000008, 0x00000008 } },
-       { 7, 0x989c,
-           { 0x0000004f, 0x0000004f, 0x0000004f, 0x0000004f, 0x0000004f } },
-       { 7, 0x989c,
-           { 0x000000f1, 0x000000f1, 0x00000061, 0x000000f1, 0x000000f1 } },
-       { 7, 0x989c,
-           { 0x0000904f, 0x0000904f, 0x0000904c, 0x0000904f, 0x0000904f } },
-       { 7, 0x989c,
-           { 0x0000125a, 0x0000125a, 0x0000129a, 0x0000125a, 0x0000125a } },
-       { 7, 0x98cc,
-           { 0x0000000e, 0x0000000e, 0x0000000f, 0x0000000e, 0x0000000e } },
-};
-
-
-
-/***********************\
-* RF5112/RF2112 (Derby) *
-\***********************/
-
-/* BANK 7 (Common)                     len  pos col */
-#define        AR5K_RF5112X_GAIN_I             { 6, 14,  0 }
-#define        AR5K_RF5112X_MIXVGA_OVR         { 1, 36,  0 }
-#define        AR5K_RF5112X_MIXGAIN_OVR        { 2, 37,  0 }
-#define AR5K_RF5112X_MIXGAIN_STEP      { 4, 32,  0 }
-#define        AR5K_RF5112X_PD_DELAY_A         { 4, 58,  0 }
-#define        AR5K_RF5112X_PD_DELAY_B         { 4, 62,  0 }
-#define        AR5K_RF5112X_PD_DELAY_XR        { 4, 66,  0 }
-#define        AR5K_RF5112X_PD_PERIOD_A        { 4, 70,  0 }
-#define        AR5K_RF5112X_PD_PERIOD_B        { 4, 74,  0 }
-#define        AR5K_RF5112X_PD_PERIOD_XR       { 4, 78,  0 }
-
-/* RFX112 (Derby 1) */
-
-/* BANK 6                              len  pos col */
-#define        AR5K_RF5112_OB_2GHZ             { 3, 269, 0 }
-#define        AR5K_RF5112_DB_2GHZ             { 3, 272, 0 }
-
-#define        AR5K_RF5112_OB_5GHZ             { 3, 261, 0 }
-#define        AR5K_RF5112_DB_5GHZ             { 3, 264, 0 }
-
-#define        AR5K_RF5112_FIXED_BIAS_A        { 1, 260, 0 }
-#define        AR5K_RF5112_FIXED_BIAS_B        { 1, 259, 0 }
-
-#define        AR5K_RF5112_XPD_SEL             { 1, 284, 0 }
-#define        AR5K_RF5112_XPD_GAIN            { 2, 252, 0 }
-
-/* Access to PWD registers */
-#define AR5K_RF5112_PWD(_n)            { 1, (302 - _n), 3 }
-
-static const struct ath5k_rf_reg rf_regs_5112[] = {
-       {6, AR5K_RF_OB_2GHZ,            AR5K_RF5112_OB_2GHZ},
-       {6, AR5K_RF_DB_2GHZ,            AR5K_RF5112_DB_2GHZ},
-       {6, AR5K_RF_OB_5GHZ,            AR5K_RF5112_OB_5GHZ},
-       {6, AR5K_RF_DB_5GHZ,            AR5K_RF5112_DB_5GHZ},
-       {6, AR5K_RF_FIXED_BIAS_A,       AR5K_RF5112_FIXED_BIAS_A},
-       {6, AR5K_RF_FIXED_BIAS_B,       AR5K_RF5112_FIXED_BIAS_B},
-       {6, AR5K_RF_XPD_SEL,            AR5K_RF5112_XPD_SEL},
-       {6, AR5K_RF_XPD_GAIN,           AR5K_RF5112_XPD_GAIN},
-       {6, AR5K_RF_PWD_130,            AR5K_RF5112_PWD(130)},
-       {6, AR5K_RF_PWD_131,            AR5K_RF5112_PWD(131)},
-       {6, AR5K_RF_PWD_132,            AR5K_RF5112_PWD(132)},
-       {6, AR5K_RF_PWD_136,            AR5K_RF5112_PWD(136)},
-       {6, AR5K_RF_PWD_137,            AR5K_RF5112_PWD(137)},
-       {6, AR5K_RF_PWD_138,            AR5K_RF5112_PWD(138)},
-       {7, AR5K_RF_GAIN_I,             AR5K_RF5112X_GAIN_I},
-       {7, AR5K_RF_MIXVGA_OVR,         AR5K_RF5112X_MIXVGA_OVR},
-       {7, AR5K_RF_MIXGAIN_OVR,        AR5K_RF5112X_MIXGAIN_OVR},
-       {7, AR5K_RF_MIXGAIN_STEP,       AR5K_RF5112X_MIXGAIN_STEP},
-       {7, AR5K_RF_PD_DELAY_A,         AR5K_RF5112X_PD_DELAY_A},
-       {7, AR5K_RF_PD_DELAY_B,         AR5K_RF5112X_PD_DELAY_B},
-       {7, AR5K_RF_PD_DELAY_XR,        AR5K_RF5112X_PD_DELAY_XR},
-       {7, AR5K_RF_PD_PERIOD_A,        AR5K_RF5112X_PD_PERIOD_A},
-       {7, AR5K_RF_PD_PERIOD_B,        AR5K_RF5112X_PD_PERIOD_B},
-       {7, AR5K_RF_PD_PERIOD_XR,       AR5K_RF5112X_PD_PERIOD_XR},
-};
-
-/* Default mode specific settings */
-static const struct ath5k_ini_rfbuffer rfb_5112[] = {
-       { 1, 0x98d4,
-       /*     mode a/XR  mode aTurbo    mode b     mode g    mode gTurbo */
-           { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
-       { 2, 0x98d0,
-           { 0x03060408, 0x03070408, 0x03060408, 0x03060408, 0x03070408 } },
-       { 3, 0x98dc,
-           { 0x00a0c0c0, 0x00a0c0c0, 0x00e0c0c0, 0x00e0c0c0, 0x00e0c0c0 } },
-       { 6, 0x989c,
-           { 0x00a00000, 0x00a00000, 0x00a00000, 0x00a00000, 0x00a00000 } },
-       { 6, 0x989c,
-           { 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00660000, 0x00660000, 0x00660000, 0x00660000, 0x00660000 } },
-       { 6, 0x989c,
-           { 0x00db0000, 0x00db0000, 0x00db0000, 0x00db0000, 0x00db0000 } },
-       { 6, 0x989c,
-           { 0x00f10000, 0x00f10000, 0x00f10000, 0x00f10000, 0x00f10000 } },
-       { 6, 0x989c,
-           { 0x00120000, 0x00120000, 0x00120000, 0x00120000, 0x00120000 } },
-       { 6, 0x989c,
-           { 0x00120000, 0x00120000, 0x00120000, 0x00120000, 0x00120000 } },
-       { 6, 0x989c,
-           { 0x00730000, 0x00730000, 0x00730000, 0x00730000, 0x00730000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000 } },
-       { 6, 0x989c,
-           { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
-       { 6, 0x989c,
-           { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
-       { 6, 0x989c,
-           { 0x008b0000, 0x008b0000, 0x008b0000, 0x008b0000, 0x008b0000 } },
-       { 6, 0x989c,
-           { 0x00600000, 0x00600000, 0x00600000, 0x00600000, 0x00600000 } },
-       { 6, 0x989c,
-           { 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000 } },
-       { 6, 0x989c,
-           { 0x00840000, 0x00840000, 0x00840000, 0x00840000, 0x00840000 } },
-       { 6, 0x989c,
-           { 0x00640000, 0x00640000, 0x00640000, 0x00640000, 0x00640000 } },
-       { 6, 0x989c,
-           { 0x00200000, 0x00200000, 0x00200000, 0x00200000, 0x00200000 } },
-       { 6, 0x989c,
-           { 0x00240000, 0x00240000, 0x00240000, 0x00240000, 0x00240000 } },
-       { 6, 0x989c,
-           { 0x00250000, 0x00250000, 0x00250000, 0x00250000, 0x00250000 } },
-       { 6, 0x989c,
-           { 0x00110000, 0x00110000, 0x00110000, 0x00110000, 0x00110000 } },
-       { 6, 0x989c,
-           { 0x00110000, 0x00110000, 0x00110000, 0x00110000, 0x00110000 } },
-       { 6, 0x989c,
-           { 0x00510000, 0x00510000, 0x00510000, 0x00510000, 0x00510000 } },
-       { 6, 0x989c,
-           { 0x1c040000, 0x1c040000, 0x1c040000, 0x1c040000, 0x1c040000 } },
-       { 6, 0x989c,
-           { 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000 } },
-       { 6, 0x989c,
-           { 0x00a10000, 0x00a10000, 0x00a10000, 0x00a10000, 0x00a10000 } },
-       { 6, 0x989c,
-           { 0x00400000, 0x00400000, 0x00400000, 0x00400000, 0x00400000 } },
-       { 6, 0x989c,
-           { 0x03090000, 0x03090000, 0x03090000, 0x03090000, 0x03090000 } },
-       { 6, 0x989c,
-           { 0x06000000, 0x06000000, 0x06000000, 0x06000000, 0x06000000 } },
-       { 6, 0x989c,
-           { 0x000000b0, 0x000000b0, 0x000000a8, 0x000000a8, 0x000000a8 } },
-       { 6, 0x989c,
-           { 0x0000002e, 0x0000002e, 0x0000002e, 0x0000002e, 0x0000002e } },
-       { 6, 0x989c,
-           { 0x006c4a41, 0x006c4a41, 0x006c4af1, 0x006c4a61, 0x006c4a61 } },
-       { 6, 0x989c,
-           { 0x0050892a, 0x0050892a, 0x0050892b, 0x0050892b, 0x0050892b } },
-       { 6, 0x989c,
-           { 0x00842400, 0x00842400, 0x00842400, 0x00842400, 0x00842400 } },
-       { 6, 0x989c,
-           { 0x00c69200, 0x00c69200, 0x00c69200, 0x00c69200, 0x00c69200 } },
-       { 6, 0x98d0,
-           { 0x0002000c, 0x0002000c, 0x0002000c, 0x0002000c, 0x0002000c } },
-       { 7, 0x989c,
-           { 0x00000094, 0x00000094, 0x00000094, 0x00000094, 0x00000094 } },
-       { 7, 0x989c,
-           { 0x00000091, 0x00000091, 0x00000091, 0x00000091, 0x00000091 } },
-       { 7, 0x989c,
-           { 0x0000000a, 0x0000000a, 0x00000012, 0x00000012, 0x00000012 } },
-       { 7, 0x989c,
-           { 0x00000080, 0x00000080, 0x00000080, 0x00000080, 0x00000080 } },
-       { 7, 0x989c,
-           { 0x000000c1, 0x000000c1, 0x000000c1, 0x000000c1, 0x000000c1 } },
-       { 7, 0x989c,
-           { 0x00000060, 0x00000060, 0x00000060, 0x00000060, 0x00000060 } },
-       { 7, 0x989c,
-           { 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0 } },
-       { 7, 0x989c,
-           { 0x00000022, 0x00000022, 0x00000022, 0x00000022, 0x00000022 } },
-       { 7, 0x989c,
-           { 0x00000092, 0x00000092, 0x00000092, 0x00000092, 0x00000092 } },
-       { 7, 0x989c,
-           { 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4 } },
-       { 7, 0x989c,
-           { 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc } },
-       { 7, 0x989c,
-           { 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c } },
-       { 7, 0x98c4,
-           { 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000003 } },
-};
-
-/* RFX112A (Derby 2) */
-
-/* BANK 6                              len  pos col */
-#define        AR5K_RF5112A_OB_2GHZ            { 3, 287, 0 }
-#define        AR5K_RF5112A_DB_2GHZ            { 3, 290, 0 }
-
-#define        AR5K_RF5112A_OB_5GHZ            { 3, 279, 0 }
-#define        AR5K_RF5112A_DB_5GHZ            { 3, 282, 0 }
-
-#define        AR5K_RF5112A_FIXED_BIAS_A       { 1, 278, 0 }
-#define        AR5K_RF5112A_FIXED_BIAS_B       { 1, 277, 0 }
-
-#define        AR5K_RF5112A_XPD_SEL            { 1, 302, 0 }
-#define        AR5K_RF5112A_PDGAINLO           { 2, 270, 0 }
-#define        AR5K_RF5112A_PDGAINHI           { 2, 257, 0 }
-
-/* Access to PWD registers */
-#define AR5K_RF5112A_PWD(_n)           { 1, (306 - _n), 3 }
-
-/* Voltage regulators */
-#define        AR5K_RF5112A_HIGH_VC_CP         { 2, 90,  2 }
-#define        AR5K_RF5112A_MID_VC_CP          { 2, 92,  2 }
-#define        AR5K_RF5112A_LOW_VC_CP          { 2, 94,  2 }
-#define        AR5K_RF5112A_PUSH_UP            { 1, 254,  2 }
-
-/* Power consumption */
-#define        AR5K_RF5112A_PAD2GND            { 1, 281, 1 }
-#define        AR5K_RF5112A_XB2_LVL            { 2, 1,   3 }
-#define        AR5K_RF5112A_XB5_LVL            { 2, 3,   3 }
-
-static const struct ath5k_rf_reg rf_regs_5112a[] = {
-       {6, AR5K_RF_OB_2GHZ,            AR5K_RF5112A_OB_2GHZ},
-       {6, AR5K_RF_DB_2GHZ,            AR5K_RF5112A_DB_2GHZ},
-       {6, AR5K_RF_OB_5GHZ,            AR5K_RF5112A_OB_5GHZ},
-       {6, AR5K_RF_DB_5GHZ,            AR5K_RF5112A_DB_5GHZ},
-       {6, AR5K_RF_FIXED_BIAS_A,       AR5K_RF5112A_FIXED_BIAS_A},
-       {6, AR5K_RF_FIXED_BIAS_B,       AR5K_RF5112A_FIXED_BIAS_B},
-       {6, AR5K_RF_XPD_SEL,            AR5K_RF5112A_XPD_SEL},
-       {6, AR5K_RF_PD_GAIN_LO,         AR5K_RF5112A_PDGAINLO},
-       {6, AR5K_RF_PD_GAIN_HI,         AR5K_RF5112A_PDGAINHI},
-       {6, AR5K_RF_PWD_130,            AR5K_RF5112A_PWD(130)},
-       {6, AR5K_RF_PWD_131,            AR5K_RF5112A_PWD(131)},
-       {6, AR5K_RF_PWD_132,            AR5K_RF5112A_PWD(132)},
-       {6, AR5K_RF_PWD_136,            AR5K_RF5112A_PWD(136)},
-       {6, AR5K_RF_PWD_137,            AR5K_RF5112A_PWD(137)},
-       {6, AR5K_RF_PWD_138,            AR5K_RF5112A_PWD(138)},
-       {6, AR5K_RF_PWD_166,            AR5K_RF5112A_PWD(166)},
-       {6, AR5K_RF_PWD_167,            AR5K_RF5112A_PWD(167)},
-       {6, AR5K_RF_HIGH_VC_CP,         AR5K_RF5112A_HIGH_VC_CP},
-       {6, AR5K_RF_MID_VC_CP,          AR5K_RF5112A_MID_VC_CP},
-       {6, AR5K_RF_LOW_VC_CP,          AR5K_RF5112A_LOW_VC_CP},
-       {6, AR5K_RF_PUSH_UP,            AR5K_RF5112A_PUSH_UP},
-       {6, AR5K_RF_PAD2GND,            AR5K_RF5112A_PAD2GND},
-       {6, AR5K_RF_XB2_LVL,            AR5K_RF5112A_XB2_LVL},
-       {6, AR5K_RF_XB5_LVL,            AR5K_RF5112A_XB5_LVL},
-       {7, AR5K_RF_GAIN_I,             AR5K_RF5112X_GAIN_I},
-       {7, AR5K_RF_MIXVGA_OVR,         AR5K_RF5112X_MIXVGA_OVR},
-       {7, AR5K_RF_MIXGAIN_OVR,        AR5K_RF5112X_MIXGAIN_OVR},
-       {7, AR5K_RF_MIXGAIN_STEP,       AR5K_RF5112X_MIXGAIN_STEP},
-       {7, AR5K_RF_PD_DELAY_A,         AR5K_RF5112X_PD_DELAY_A},
-       {7, AR5K_RF_PD_DELAY_B,         AR5K_RF5112X_PD_DELAY_B},
-       {7, AR5K_RF_PD_DELAY_XR,        AR5K_RF5112X_PD_DELAY_XR},
-       {7, AR5K_RF_PD_PERIOD_A,        AR5K_RF5112X_PD_PERIOD_A},
-       {7, AR5K_RF_PD_PERIOD_B,        AR5K_RF5112X_PD_PERIOD_B},
-       {7, AR5K_RF_PD_PERIOD_XR,       AR5K_RF5112X_PD_PERIOD_XR},
-};
-
-/* Default mode specific settings */
-static const struct ath5k_ini_rfbuffer rfb_5112a[] = {
-       { 1, 0x98d4,
-       /*     mode a/XR  mode aTurbo    mode b     mode g    mode gTurbo */
-           { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
-       { 2, 0x98d0,
-           { 0x03060408, 0x03070408, 0x03060408, 0x03060408, 0x03070408 } },
-       { 3, 0x98dc,
-           { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
-       { 6, 0x989c,
-           { 0x0f000000, 0x0f000000, 0x0f000000, 0x0f000000, 0x0f000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00800000, 0x00800000, 0x00800000, 0x00800000, 0x00800000 } },
-       { 6, 0x989c,
-           { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } },
-       { 6, 0x989c,
-           { 0x00010000, 0x00010000, 0x00010000, 0x00010000, 0x00010000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00180000, 0x00180000, 0x00180000, 0x00180000, 0x00180000 } },
-       { 6, 0x989c,
-           { 0x00600000, 0x00600000, 0x006e0000, 0x006e0000, 0x006e0000 } },
-       { 6, 0x989c,
-           { 0x00c70000, 0x00c70000, 0x00c70000, 0x00c70000, 0x00c70000 } },
-       { 6, 0x989c,
-           { 0x004b0000, 0x004b0000, 0x004b0000, 0x004b0000, 0x004b0000 } },
-       { 6, 0x989c,
-           { 0x04480000, 0x04480000, 0x04480000, 0x04480000, 0x04480000 } },
-       { 6, 0x989c,
-           { 0x004c0000, 0x004c0000, 0x004c0000, 0x004c0000, 0x004c0000 } },
-       { 6, 0x989c,
-           { 0x00e40000, 0x00e40000, 0x00e40000, 0x00e40000, 0x00e40000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00fc0000, 0x00fc0000, 0x00fc0000, 0x00fc0000, 0x00fc0000 } },
-       { 6, 0x989c,
-           { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
-       { 6, 0x989c,
-           { 0x043f0000, 0x043f0000, 0x043f0000, 0x043f0000, 0x043f0000 } },
-       { 6, 0x989c,
-           { 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000 } },
-       { 6, 0x989c,
-           { 0x02190000, 0x02190000, 0x02190000, 0x02190000, 0x02190000 } },
-       { 6, 0x989c,
-           { 0x00240000, 0x00240000, 0x00240000, 0x00240000, 0x00240000 } },
-       { 6, 0x989c,
-           { 0x00b40000, 0x00b40000, 0x00b40000, 0x00b40000, 0x00b40000 } },
-       { 6, 0x989c,
-           { 0x00990000, 0x00990000, 0x00990000, 0x00990000, 0x00990000 } },
-       { 6, 0x989c,
-           { 0x00500000, 0x00500000, 0x00500000, 0x00500000, 0x00500000 } },
-       { 6, 0x989c,
-           { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } },
-       { 6, 0x989c,
-           { 0x00120000, 0x00120000, 0x00120000, 0x00120000, 0x00120000 } },
-       { 6, 0x989c,
-           { 0xc0320000, 0xc0320000, 0xc0320000, 0xc0320000, 0xc0320000 } },
-       { 6, 0x989c,
-           { 0x01740000, 0x01740000, 0x01740000, 0x01740000, 0x01740000 } },
-       { 6, 0x989c,
-           { 0x00110000, 0x00110000, 0x00110000, 0x00110000, 0x00110000 } },
-       { 6, 0x989c,
-           { 0x86280000, 0x86280000, 0x86280000, 0x86280000, 0x86280000 } },
-       { 6, 0x989c,
-           { 0x31840000, 0x31840000, 0x31840000, 0x31840000, 0x31840000 } },
-       { 6, 0x989c,
-           { 0x00f20080, 0x00f20080, 0x00f20080, 0x00f20080, 0x00f20080 } },
-       { 6, 0x989c,
-           { 0x00270019, 0x00270019, 0x00270019, 0x00270019, 0x00270019 } },
-       { 6, 0x989c,
-           { 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000003 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x000000b2, 0x000000b2, 0x000000b2, 0x000000b2, 0x000000b2 } },
-       { 6, 0x989c,
-           { 0x00b02084, 0x00b02084, 0x00b02084, 0x00b02084, 0x00b02084 } },
-       { 6, 0x989c,
-           { 0x004125a4, 0x004125a4, 0x004125a4, 0x004125a4, 0x004125a4 } },
-       { 6, 0x989c,
-           { 0x00119220, 0x00119220, 0x00119220, 0x00119220, 0x00119220 } },
-       { 6, 0x989c,
-           { 0x001a4800, 0x001a4800, 0x001a4800, 0x001a4800, 0x001a4800 } },
-       { 6, 0x98d8,
-           { 0x000b0230, 0x000b0230, 0x000b0230, 0x000b0230, 0x000b0230 } },
-       { 7, 0x989c,
-           { 0x00000094, 0x00000094, 0x00000094, 0x00000094, 0x00000094 } },
-       { 7, 0x989c,
-           { 0x00000091, 0x00000091, 0x00000091, 0x00000091, 0x00000091 } },
-       { 7, 0x989c,
-           { 0x00000012, 0x00000012, 0x00000012, 0x00000012, 0x00000012 } },
-       { 7, 0x989c,
-           { 0x00000080, 0x00000080, 0x00000080, 0x00000080, 0x00000080 } },
-       { 7, 0x989c,
-           { 0x000000d9, 0x000000d9, 0x000000d9, 0x000000d9, 0x000000d9 } },
-       { 7, 0x989c,
-           { 0x00000060, 0x00000060, 0x00000060, 0x00000060, 0x00000060 } },
-       { 7, 0x989c,
-           { 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0 } },
-       { 7, 0x989c,
-           { 0x000000a2, 0x000000a2, 0x000000a2, 0x000000a2, 0x000000a2 } },
-       { 7, 0x989c,
-           { 0x00000052, 0x00000052, 0x00000052, 0x00000052, 0x00000052 } },
-       { 7, 0x989c,
-           { 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4 } },
-       { 7, 0x989c,
-           { 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc } },
-       { 7, 0x989c,
-           { 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c } },
-       { 7, 0x98c4,
-           { 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000003 } },
-};
-
-
-
-/******************\
-* RF2413 (Griffin) *
-\******************/
-
-/* BANK 6                              len  pos col */
-#define        AR5K_RF2413_OB_2GHZ             { 3, 168, 0 }
-#define        AR5K_RF2413_DB_2GHZ             { 3, 165, 0 }
-
-static const struct ath5k_rf_reg rf_regs_2413[] = {
-       {6, AR5K_RF_OB_2GHZ,            AR5K_RF2413_OB_2GHZ},
-       {6, AR5K_RF_DB_2GHZ,            AR5K_RF2413_DB_2GHZ},
-};
-
-/* Default mode specific settings
- * XXX: a/aTurbo ???
- */
-static const struct ath5k_ini_rfbuffer rfb_2413[] = {
-       { 1, 0x98d4,
-       /*     mode a/XR  mode aTurbo    mode b     mode g    mode gTurbo */
-           { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
-       { 2, 0x98d0,
-           { 0x02001408, 0x02011408, 0x02001408, 0x02001408, 0x02011408 } },
-       { 3, 0x98dc,
-           { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
-       { 6, 0x989c,
-           { 0xf0000000, 0xf0000000, 0xf0000000, 0xf0000000, 0xf0000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x03000000, 0x03000000, 0x03000000, 0x03000000, 0x03000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x40400000, 0x40400000, 0x40400000, 0x40400000, 0x40400000 } },
-       { 6, 0x989c,
-           { 0x65050000, 0x65050000, 0x65050000, 0x65050000, 0x65050000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00420000, 0x00420000, 0x00420000, 0x00420000, 0x00420000 } },
-       { 6, 0x989c,
-           { 0x00b50000, 0x00b50000, 0x00b50000, 0x00b50000, 0x00b50000 } },
-       { 6, 0x989c,
-           { 0x00030000, 0x00030000, 0x00030000, 0x00030000, 0x00030000 } },
-       { 6, 0x989c,
-           { 0x00f70000, 0x00f70000, 0x00f70000, 0x00f70000, 0x00f70000 } },
-       { 6, 0x989c,
-           { 0x009d0000, 0x009d0000, 0x009d0000, 0x009d0000, 0x009d0000 } },
-       { 6, 0x989c,
-           { 0x00220000, 0x00220000, 0x00220000, 0x00220000, 0x00220000 } },
-       { 6, 0x989c,
-           { 0x04220000, 0x04220000, 0x04220000, 0x04220000, 0x04220000 } },
-       { 6, 0x989c,
-           { 0x00230018, 0x00230018, 0x00230018, 0x00230018, 0x00230018 } },
-       { 6, 0x989c,
-           { 0x00280000, 0x00280000, 0x00280060, 0x00280060, 0x00280060 } },
-       { 6, 0x989c,
-           { 0x005000c0, 0x005000c0, 0x005000c3, 0x005000c3, 0x005000c3 } },
-       { 6, 0x989c,
-           { 0x0004007f, 0x0004007f, 0x0004007f, 0x0004007f, 0x0004007f } },
-       { 6, 0x989c,
-           { 0x00000458, 0x00000458, 0x00000458, 0x00000458, 0x00000458 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x0000c000, 0x0000c000, 0x0000c000, 0x0000c000, 0x0000c000 } },
-       { 6, 0x98d8,
-           { 0x00400230, 0x00400230, 0x00400230, 0x00400230, 0x00400230 } },
-       { 7, 0x989c,
-           { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
-       { 7, 0x989c,
-           { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
-       { 7, 0x98cc,
-           { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
-};
-
-
-
-/***************************\
-* RF2315/RF2316 (Cobra SoC) *
-\***************************/
-
-/* BANK 6                              len  pos col */
-#define        AR5K_RF2316_OB_2GHZ             { 3, 178, 0 }
-#define        AR5K_RF2316_DB_2GHZ             { 3, 175, 0 }
-
-static const struct ath5k_rf_reg rf_regs_2316[] = {
-       {6, AR5K_RF_OB_2GHZ,            AR5K_RF2316_OB_2GHZ},
-       {6, AR5K_RF_DB_2GHZ,            AR5K_RF2316_DB_2GHZ},
-};
-
-/* Default mode specific settings */
-static const struct ath5k_ini_rfbuffer rfb_2316[] = {
-       { 1, 0x98d4,
-       /*     mode a/XR  mode aTurbo    mode b     mode g    mode gTurbo */
-           { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
-       { 2, 0x98d0,
-           { 0x02001408, 0x02011408, 0x02001408, 0x02001408, 0x02011408 } },
-       { 3, 0x98dc,
-           { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0xc0000000, 0xc0000000, 0xc0000000, 0xc0000000, 0xc0000000 } },
-       { 6, 0x989c,
-           { 0x0f000000, 0x0f000000, 0x0f000000, 0x0f000000, 0x0f000000 } },
-       { 6, 0x989c,
-           { 0x02000000, 0x02000000, 0x02000000, 0x02000000, 0x02000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0xf8000000, 0xf8000000, 0xf8000000, 0xf8000000, 0xf8000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x95150000, 0x95150000, 0x95150000, 0x95150000, 0x95150000 } },
-       { 6, 0x989c,
-           { 0xc1000000, 0xc1000000, 0xc1000000, 0xc1000000, 0xc1000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00080000, 0x00080000, 0x00080000, 0x00080000, 0x00080000 } },
-       { 6, 0x989c,
-           { 0x00d50000, 0x00d50000, 0x00d50000, 0x00d50000, 0x00d50000 } },
-       { 6, 0x989c,
-           { 0x000e0000, 0x000e0000, 0x000e0000, 0x000e0000, 0x000e0000 } },
-       { 6, 0x989c,
-           { 0x00dc0000, 0x00dc0000, 0x00dc0000, 0x00dc0000, 0x00dc0000 } },
-       { 6, 0x989c,
-           { 0x00770000, 0x00770000, 0x00770000, 0x00770000, 0x00770000 } },
-       { 6, 0x989c,
-           { 0x008a0000, 0x008a0000, 0x008a0000, 0x008a0000, 0x008a0000 } },
-       { 6, 0x989c,
-           { 0x10880000, 0x10880000, 0x10880000, 0x10880000, 0x10880000 } },
-       { 6, 0x989c,
-           { 0x008c0060, 0x008c0060, 0x008c0060, 0x008c0060, 0x008c0060 } },
-       { 6, 0x989c,
-           { 0x00a00000, 0x00a00000, 0x00a00080, 0x00a00080, 0x00a00080 } },
-       { 6, 0x989c,
-           { 0x00400000, 0x00400000, 0x0040000d, 0x0040000d, 0x0040000d } },
-       { 6, 0x989c,
-           { 0x00110400, 0x00110400, 0x00110400, 0x00110400, 0x00110400 } },
-       { 6, 0x989c,
-           { 0x00000060, 0x00000060, 0x00000060, 0x00000060, 0x00000060 } },
-       { 6, 0x989c,
-           { 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001 } },
-       { 6, 0x989c,
-           { 0x00000b00, 0x00000b00, 0x00000b00, 0x00000b00, 0x00000b00 } },
-       { 6, 0x989c,
-           { 0x00000be8, 0x00000be8, 0x00000be8, 0x00000be8, 0x00000be8 } },
-       { 6, 0x98c0,
-           { 0x00010000, 0x00010000, 0x00010000, 0x00010000, 0x00010000 } },
-       { 7, 0x989c,
-           { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
-       { 7, 0x989c,
-           { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
-       { 7, 0x98cc,
-           { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
-};
-
-
-
-/******************************\
-* RF5413/RF5424 (Eagle/Condor) *
-\******************************/
-
-/* BANK 6                              len  pos col */
-#define        AR5K_RF5413_OB_2GHZ             { 3, 241, 0 }
-#define        AR5K_RF5413_DB_2GHZ             { 3, 238, 0 }
-
-#define        AR5K_RF5413_OB_5GHZ             { 3, 247, 0 }
-#define        AR5K_RF5413_DB_5GHZ             { 3, 244, 0 }
-
-#define        AR5K_RF5413_PWD_ICLOBUF2G       { 3, 131, 3 }
-#define        AR5K_RF5413_DERBY_CHAN_SEL_MODE { 1, 291, 2 }
-
-static const struct ath5k_rf_reg rf_regs_5413[] = {
-       {6, AR5K_RF_OB_2GHZ,             AR5K_RF5413_OB_2GHZ},
-       {6, AR5K_RF_DB_2GHZ,             AR5K_RF5413_DB_2GHZ},
-       {6, AR5K_RF_OB_5GHZ,             AR5K_RF5413_OB_5GHZ},
-       {6, AR5K_RF_DB_5GHZ,             AR5K_RF5413_DB_5GHZ},
-       {6, AR5K_RF_PWD_ICLOBUF_2G,      AR5K_RF5413_PWD_ICLOBUF2G},
-       {6, AR5K_RF_DERBY_CHAN_SEL_MODE, AR5K_RF5413_DERBY_CHAN_SEL_MODE},
-};
-
-/* Default mode specific settings */
-static const struct ath5k_ini_rfbuffer rfb_5413[] = {
-       { 1, 0x98d4,
-       /*     mode a/XR  mode aTurbo    mode b     mode g    mode gTurbo */
-           { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
-       { 2, 0x98d0,
-           { 0x00000008, 0x00000008, 0x00000008, 0x00000008, 0x00000008 } },
-       { 3, 0x98dc,
-           { 0x00a000c0, 0x00a000c0, 0x00e000c0, 0x00e000c0, 0x00e000c0 } },
-       { 6, 0x989c,
-           { 0x33000000, 0x33000000, 0x33000000, 0x33000000, 0x33000000 } },
-       { 6, 0x989c,
-           { 0x01000000, 0x01000000, 0x01000000, 0x01000000, 0x01000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x1f000000, 0x1f000000, 0x1f000000, 0x1f000000, 0x1f000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00b80000, 0x00b80000, 0x00b80000, 0x00b80000, 0x00b80000 } },
-       { 6, 0x989c,
-           { 0x00b70000, 0x00b70000, 0x00b70000, 0x00b70000, 0x00b70000 } },
-       { 6, 0x989c,
-           { 0x00840000, 0x00840000, 0x00840000, 0x00840000, 0x00840000 } },
-       { 6, 0x989c,
-           { 0x00980000, 0x00980000, 0x00980000, 0x00980000, 0x00980000 } },
-       { 6, 0x989c,
-           { 0x00c00000, 0x00c00000, 0x00c00000, 0x00c00000, 0x00c00000 } },
-       { 6, 0x989c,
-           { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
-       { 6, 0x989c,
-           { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
-       { 6, 0x989c,
-           { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
-       { 6, 0x989c,
-           { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
-       { 6, 0x989c,
-           { 0x00d70000, 0x00d70000, 0x00d70000, 0x00d70000, 0x00d70000 } },
-       { 6, 0x989c,
-           { 0x00610000, 0x00610000, 0x00610000, 0x00610000, 0x00610000 } },
-       { 6, 0x989c,
-           { 0x00fe0000, 0x00fe0000, 0x00fe0000, 0x00fe0000, 0x00fe0000 } },
-       { 6, 0x989c,
-           { 0x00de0000, 0x00de0000, 0x00de0000, 0x00de0000, 0x00de0000 } },
-       { 6, 0x989c,
-           { 0x007f0000, 0x007f0000, 0x007f0000, 0x007f0000, 0x007f0000 } },
-       { 6, 0x989c,
-           { 0x043d0000, 0x043d0000, 0x043d0000, 0x043d0000, 0x043d0000 } },
-       { 6, 0x989c,
-           { 0x00770000, 0x00770000, 0x00770000, 0x00770000, 0x00770000 } },
-       { 6, 0x989c,
-           { 0x00440000, 0x00440000, 0x00440000, 0x00440000, 0x00440000 } },
-       { 6, 0x989c,
-           { 0x00980000, 0x00980000, 0x00980000, 0x00980000, 0x00980000 } },
-       { 6, 0x989c,
-           { 0x00100080, 0x00100080, 0x00100080, 0x00100080, 0x00100080 } },
-       { 6, 0x989c,
-           { 0x0005c034, 0x0005c034, 0x0005c034, 0x0005c034, 0x0005c034 } },
-       { 6, 0x989c,
-           { 0x003100f0, 0x003100f0, 0x003100f0, 0x003100f0, 0x003100f0 } },
-       { 6, 0x989c,
-           { 0x000c011f, 0x000c011f, 0x000c011f, 0x000c011f, 0x000c011f } },
-       { 6, 0x989c,
-           { 0x00510040, 0x00510040, 0x00510040, 0x00510040, 0x00510040 } },
-       { 6, 0x989c,
-           { 0x005000da, 0x005000da, 0x005000da, 0x005000da, 0x005000da } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00004044, 0x00004044, 0x00004044, 0x00004044, 0x00004044 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x000060c0, 0x000060c0, 0x000060c0, 0x000060c0, 0x000060c0 } },
-       { 6, 0x989c,
-           { 0x00002c00, 0x00002c00, 0x00003600, 0x00003600, 0x00002c00 } },
-       { 6, 0x98c8,
-           { 0x00000403, 0x00000403, 0x00040403, 0x00040403, 0x00040403 } },
-       { 7, 0x989c,
-           { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
-       { 7, 0x989c,
-           { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
-       { 7, 0x98cc,
-           { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
-};
-
-
-
-/***************************\
-* RF2425/RF2417 (Swan/Nala) *
-* AR2317 (Spider SoC)       *
-\***************************/
-
-/* BANK 6                              len  pos col */
-#define        AR5K_RF2425_OB_2GHZ             { 3, 193, 0 }
-#define        AR5K_RF2425_DB_2GHZ             { 3, 190, 0 }
-
-static const struct ath5k_rf_reg rf_regs_2425[] = {
-       {6, AR5K_RF_OB_2GHZ,            AR5K_RF2425_OB_2GHZ},
-       {6, AR5K_RF_DB_2GHZ,            AR5K_RF2425_DB_2GHZ},
-};
-
-/* Default mode specific settings
- * XXX: a/aTurbo ?
- */
-static const struct ath5k_ini_rfbuffer rfb_2425[] = {
-       { 1, 0x98d4,
-       /*     mode a/XR  mode aTurbo    mode b     mode g    mode gTurbo */
-           { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
-       { 2, 0x98d0,
-           { 0x02001408, 0x02001408, 0x02001408, 0x02001408, 0x02001408 } },
-       { 3, 0x98dc,
-           { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
-       { 6, 0x989c,
-           { 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000 } },
-       { 6, 0x989c,
-           { 0x00020000, 0x00020000, 0x00020000, 0x00020000, 0x00020000 } },
-       { 6, 0x989c,
-           { 0x00730000, 0x00730000, 0x00730000, 0x00730000, 0x00730000 } },
-       { 6, 0x989c,
-           { 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000 } },
-       { 6, 0x989c,
-           { 0x00e70000, 0x00e70000, 0x00e70000, 0x00e70000, 0x00e70000 } },
-       { 6, 0x989c,
-           { 0x00140000, 0x00140000, 0x00140000, 0x00140000, 0x00140000 } },
-       { 6, 0x989c,
-           { 0x00910040, 0x00910040, 0x00910040, 0x00910040, 0x00910040 } },
-       { 6, 0x989c,
-           { 0x0007001a, 0x0007001a, 0x0007001a, 0x0007001a, 0x0007001a } },
-       { 6, 0x989c,
-           { 0x00410000, 0x00410000, 0x00410000, 0x00410000, 0x00410000 } },
-       { 6, 0x989c,
-           { 0x00810000, 0x00810000, 0x00810060, 0x00810060, 0x00810060 } },
-       { 6, 0x989c,
-           { 0x00020800, 0x00020800, 0x00020803, 0x00020803, 0x00020803 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00001660, 0x00001660, 0x00001660, 0x00001660, 0x00001660 } },
-       { 6, 0x989c,
-           { 0x00001688, 0x00001688, 0x00001688, 0x00001688, 0x00001688 } },
-       { 6, 0x98c4,
-           { 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001 } },
-       { 7, 0x989c,
-           { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
-       { 7, 0x989c,
-           { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
-       { 7, 0x98cc,
-           { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
-};
-
-/*
- * TODO: Handle the few differences with swan during
- * bank modification and get rid of this
- */
-static const struct ath5k_ini_rfbuffer rfb_2317[] = {
-       { 1, 0x98d4,
-       /*     mode a/XR  mode aTurbo    mode b     mode g    mode gTurbo */
-           { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
-       { 2, 0x98d0,
-           { 0x02001408, 0x02011408, 0x02001408, 0x02001408, 0x02011408 } },
-       { 3, 0x98dc,
-           { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
-       { 6, 0x989c,
-           { 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000 } },
-       { 6, 0x989c,
-           { 0x00020000, 0x00020000, 0x00020000, 0x00020000, 0x00020000 } },
-       { 6, 0x989c,
-           { 0x00730000, 0x00730000, 0x00730000, 0x00730000, 0x00730000 } },
-       { 6, 0x989c,
-           { 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000 } },
-       { 6, 0x989c,
-           { 0x00e70000, 0x00e70000, 0x00e70000, 0x00e70000, 0x00e70000 } },
-       { 6, 0x989c,
-           { 0x00140100, 0x00140100, 0x00140100, 0x00140100, 0x00140100 } },
-       { 6, 0x989c,
-           { 0x00910040, 0x00910040, 0x00910040, 0x00910040, 0x00910040 } },
-       { 6, 0x989c,
-           { 0x0007001a, 0x0007001a, 0x0007001a, 0x0007001a, 0x0007001a } },
-       { 6, 0x989c,
-           { 0x00410000, 0x00410000, 0x00410000, 0x00410000, 0x00410000 } },
-       { 6, 0x989c,
-           { 0x00810000, 0x00810000, 0x00810060, 0x00810060, 0x00810060 } },
-       { 6, 0x989c,
-           { 0x00020800, 0x00020800, 0x00020803, 0x00020803, 0x00020803 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00001660, 0x00001660, 0x00001660, 0x00001660, 0x00001660 } },
-       { 6, 0x989c,
-           { 0x00009688, 0x00009688, 0x00009688, 0x00009688, 0x00009688 } },
-       { 6, 0x98c4,
-           { 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001 } },
-       { 7, 0x989c,
-           { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
-       { 7, 0x989c,
-           { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
-       { 7, 0x98cc,
-           { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
-};
-
-/*
- * TODO: Handle the few differences with swan during
- * bank modification and get rid of this
- * XXX: a/aTurbo ?
- */
-static const struct ath5k_ini_rfbuffer rfb_2417[] = {
-       { 1, 0x98d4,
-       /*     mode a/XR  mode aTurbo    mode b     mode g    mode gTurbo */
-           { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
-       { 2, 0x98d0,
-           { 0x02001408, 0x02001408, 0x02001408, 0x02001408, 0x02001408 } },
-       { 3, 0x98dc,
-           { 0x00a020c0, 0x00a020c0, 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
-       { 6, 0x989c,
-           { 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000 } },
-       { 6, 0x989c,
-           { 0x00020000, 0x00020000, 0x00020000, 0x00020000, 0x00020000 } },
-       { 6, 0x989c,
-           { 0x00730000, 0x00730000, 0x00730000, 0x00730000, 0x00730000 } },
-       { 6, 0x989c,
-           { 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000, 0x00f80000 } },
-       { 6, 0x989c,
-           { 0x00e70000, 0x00e70000, 0x80e70000, 0x80e70000, 0x00e70000 } },
-       { 6, 0x989c,
-           { 0x00140000, 0x00140000, 0x00140000, 0x00140000, 0x00140000 } },
-       { 6, 0x989c,
-           { 0x00910040, 0x00910040, 0x00910040, 0x00910040, 0x00910040 } },
-       { 6, 0x989c,
-           { 0x0007001a, 0x0007001a, 0x0207001a, 0x0207001a, 0x0007001a } },
-       { 6, 0x989c,
-           { 0x00410000, 0x00410000, 0x00410000, 0x00410000, 0x00410000 } },
-       { 6, 0x989c,
-           { 0x00810000, 0x00810000, 0x00810060, 0x00810060, 0x00810060 } },
-       { 6, 0x989c,
-           { 0x00020800, 0x00020800, 0x00020803, 0x00020803, 0x00020803 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
-       { 6, 0x989c,
-           { 0x00001660, 0x00001660, 0x00001660, 0x00001660, 0x00001660 } },
-       { 6, 0x989c,
-           { 0x00001688, 0x00001688, 0x00001688, 0x00001688, 0x00001688 } },
-       { 6, 0x98c4,
-           { 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001 } },
-       { 7, 0x989c,
-           { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
-       { 7, 0x989c,
-           { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
-       { 7, 0x98cc,
-           { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
-};
diff --git a/drivers/net/wireless/ath5k/rfgain.h b/drivers/net/wireless/ath5k/rfgain.h
deleted file mode 100644 (file)
index 1354d8c..0000000
+++ /dev/null
@@ -1,516 +0,0 @@
-/*
- * RF Gain optimization
- *
- * Copyright (c) 2004-2009 Reyk Floeter <reyk@openbsd.org>
- * Copyright (c) 2006-2009 Nick Kossifidis <mickflemm@gmail.com>
- *
- * Permission to use, copy, modify, and 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.
- *
- */
-
-/*
- * Mode-specific RF Gain table (64bytes) for RF5111/5112
- * (RF5110 only comes with AR5210 and only supports a/turbo a mode so initial
- * RF Gain values are included in AR5K_AR5210_INI)
- */
-struct ath5k_ini_rfgain {
-       u16     rfg_register;   /* RF Gain register address */
-       u32     rfg_value[2];   /* [freq (see below)] */
-};
-
-/* Initial RF Gain settings for RF5111 */
-static const struct ath5k_ini_rfgain rfgain_5111[] = {
-       /*                            5Ghz      2Ghz    */
-       { AR5K_RF_GAIN(0),      { 0x000001a9, 0x00000000 } },
-       { AR5K_RF_GAIN(1),      { 0x000001e9, 0x00000040 } },
-       { AR5K_RF_GAIN(2),      { 0x00000029, 0x00000080 } },
-       { AR5K_RF_GAIN(3),      { 0x00000069, 0x00000150 } },
-       { AR5K_RF_GAIN(4),      { 0x00000199, 0x00000190 } },
-       { AR5K_RF_GAIN(5),      { 0x000001d9, 0x000001d0 } },
-       { AR5K_RF_GAIN(6),      { 0x00000019, 0x00000010 } },
-       { AR5K_RF_GAIN(7),      { 0x00000059, 0x00000044 } },
-       { AR5K_RF_GAIN(8),      { 0x00000099, 0x00000084 } },
-       { AR5K_RF_GAIN(9),      { 0x000001a5, 0x00000148 } },
-       { AR5K_RF_GAIN(10),     { 0x000001e5, 0x00000188 } },
-       { AR5K_RF_GAIN(11),     { 0x00000025, 0x000001c8 } },
-       { AR5K_RF_GAIN(12),     { 0x000001c8, 0x00000014 } },
-       { AR5K_RF_GAIN(13),     { 0x00000008, 0x00000042 } },
-       { AR5K_RF_GAIN(14),     { 0x00000048, 0x00000082 } },
-       { AR5K_RF_GAIN(15),     { 0x00000088, 0x00000178 } },
-       { AR5K_RF_GAIN(16),     { 0x00000198, 0x000001b8 } },
-       { AR5K_RF_GAIN(17),     { 0x000001d8, 0x000001f8 } },
-       { AR5K_RF_GAIN(18),     { 0x00000018, 0x00000012 } },
-       { AR5K_RF_GAIN(19),     { 0x00000058, 0x00000052 } },
-       { AR5K_RF_GAIN(20),     { 0x00000098, 0x00000092 } },
-       { AR5K_RF_GAIN(21),     { 0x000001a4, 0x0000017c } },
-       { AR5K_RF_GAIN(22),     { 0x000001e4, 0x000001bc } },
-       { AR5K_RF_GAIN(23),     { 0x00000024, 0x000001fc } },
-       { AR5K_RF_GAIN(24),     { 0x00000064, 0x0000000a } },
-       { AR5K_RF_GAIN(25),     { 0x000000a4, 0x0000004a } },
-       { AR5K_RF_GAIN(26),     { 0x000000e4, 0x0000008a } },
-       { AR5K_RF_GAIN(27),     { 0x0000010a, 0x0000015a } },
-       { AR5K_RF_GAIN(28),     { 0x0000014a, 0x0000019a } },
-       { AR5K_RF_GAIN(29),     { 0x0000018a, 0x000001da } },
-       { AR5K_RF_GAIN(30),     { 0x000001ca, 0x0000000e } },
-       { AR5K_RF_GAIN(31),     { 0x0000000a, 0x0000004e } },
-       { AR5K_RF_GAIN(32),     { 0x0000004a, 0x0000008e } },
-       { AR5K_RF_GAIN(33),     { 0x0000008a, 0x0000015e } },
-       { AR5K_RF_GAIN(34),     { 0x000001ba, 0x0000019e } },
-       { AR5K_RF_GAIN(35),     { 0x000001fa, 0x000001de } },
-       { AR5K_RF_GAIN(36),     { 0x0000003a, 0x00000009 } },
-       { AR5K_RF_GAIN(37),     { 0x0000007a, 0x00000049 } },
-       { AR5K_RF_GAIN(38),     { 0x00000186, 0x00000089 } },
-       { AR5K_RF_GAIN(39),     { 0x000001c6, 0x00000179 } },
-       { AR5K_RF_GAIN(40),     { 0x00000006, 0x000001b9 } },
-       { AR5K_RF_GAIN(41),     { 0x00000046, 0x000001f9 } },
-       { AR5K_RF_GAIN(42),     { 0x00000086, 0x00000039 } },
-       { AR5K_RF_GAIN(43),     { 0x000000c6, 0x00000079 } },
-       { AR5K_RF_GAIN(44),     { 0x000000c6, 0x000000b9 } },
-       { AR5K_RF_GAIN(45),     { 0x000000c6, 0x000001bd } },
-       { AR5K_RF_GAIN(46),     { 0x000000c6, 0x000001fd } },
-       { AR5K_RF_GAIN(47),     { 0x000000c6, 0x0000003d } },
-       { AR5K_RF_GAIN(48),     { 0x000000c6, 0x0000007d } },
-       { AR5K_RF_GAIN(49),     { 0x000000c6, 0x000000bd } },
-       { AR5K_RF_GAIN(50),     { 0x000000c6, 0x000000fd } },
-       { AR5K_RF_GAIN(51),     { 0x000000c6, 0x000000fd } },
-       { AR5K_RF_GAIN(52),     { 0x000000c6, 0x000000fd } },
-       { AR5K_RF_GAIN(53),     { 0x000000c6, 0x000000fd } },
-       { AR5K_RF_GAIN(54),     { 0x000000c6, 0x000000fd } },
-       { AR5K_RF_GAIN(55),     { 0x000000c6, 0x000000fd } },
-       { AR5K_RF_GAIN(56),     { 0x000000c6, 0x000000fd } },
-       { AR5K_RF_GAIN(57),     { 0x000000c6, 0x000000fd } },
-       { AR5K_RF_GAIN(58),     { 0x000000c6, 0x000000fd } },
-       { AR5K_RF_GAIN(59),     { 0x000000c6, 0x000000fd } },
-       { AR5K_RF_GAIN(60),     { 0x000000c6, 0x000000fd } },
-       { AR5K_RF_GAIN(61),     { 0x000000c6, 0x000000fd } },
-       { AR5K_RF_GAIN(62),     { 0x000000c6, 0x000000fd } },
-       { AR5K_RF_GAIN(63),     { 0x000000c6, 0x000000fd } },
-};
-
-/* Initial RF Gain settings for RF5112 */
-static const struct ath5k_ini_rfgain rfgain_5112[] = {
-       /*                            5Ghz      2Ghz    */
-       { AR5K_RF_GAIN(0),      { 0x00000007, 0x00000007 } },
-       { AR5K_RF_GAIN(1),      { 0x00000047, 0x00000047 } },
-       { AR5K_RF_GAIN(2),      { 0x00000087, 0x00000087 } },
-       { AR5K_RF_GAIN(3),      { 0x000001a0, 0x000001a0 } },
-       { AR5K_RF_GAIN(4),      { 0x000001e0, 0x000001e0 } },
-       { AR5K_RF_GAIN(5),      { 0x00000020, 0x00000020 } },
-       { AR5K_RF_GAIN(6),      { 0x00000060, 0x00000060 } },
-       { AR5K_RF_GAIN(7),      { 0x000001a1, 0x000001a1 } },
-       { AR5K_RF_GAIN(8),      { 0x000001e1, 0x000001e1 } },
-       { AR5K_RF_GAIN(9),      { 0x00000021, 0x00000021 } },
-       { AR5K_RF_GAIN(10),     { 0x00000061, 0x00000061 } },
-       { AR5K_RF_GAIN(11),     { 0x00000162, 0x00000162 } },
-       { AR5K_RF_GAIN(12),     { 0x000001a2, 0x000001a2 } },
-       { AR5K_RF_GAIN(13),     { 0x000001e2, 0x000001e2 } },
-       { AR5K_RF_GAIN(14),     { 0x00000022, 0x00000022 } },
-       { AR5K_RF_GAIN(15),     { 0x00000062, 0x00000062 } },
-       { AR5K_RF_GAIN(16),     { 0x00000163, 0x00000163 } },
-       { AR5K_RF_GAIN(17),     { 0x000001a3, 0x000001a3 } },
-       { AR5K_RF_GAIN(18),     { 0x000001e3, 0x000001e3 } },
-       { AR5K_RF_GAIN(19),     { 0x00000023, 0x00000023 } },
-       { AR5K_RF_GAIN(20),     { 0x00000063, 0x00000063 } },
-       { AR5K_RF_GAIN(21),     { 0x00000184, 0x00000184 } },
-       { AR5K_RF_GAIN(22),     { 0x000001c4, 0x000001c4 } },
-       { AR5K_RF_GAIN(23),     { 0x00000004, 0x00000004 } },
-       { AR5K_RF_GAIN(24),     { 0x000001ea, 0x0000000b } },
-       { AR5K_RF_GAIN(25),     { 0x0000002a, 0x0000004b } },
-       { AR5K_RF_GAIN(26),     { 0x0000006a, 0x0000008b } },
-       { AR5K_RF_GAIN(27),     { 0x000000aa, 0x000001ac } },
-       { AR5K_RF_GAIN(28),     { 0x000001ab, 0x000001ec } },
-       { AR5K_RF_GAIN(29),     { 0x000001eb, 0x0000002c } },
-       { AR5K_RF_GAIN(30),     { 0x0000002b, 0x00000012 } },
-       { AR5K_RF_GAIN(31),     { 0x0000006b, 0x00000052 } },
-       { AR5K_RF_GAIN(32),     { 0x000000ab, 0x00000092 } },
-       { AR5K_RF_GAIN(33),     { 0x000001ac, 0x00000193 } },
-       { AR5K_RF_GAIN(34),     { 0x000001ec, 0x000001d3 } },
-       { AR5K_RF_GAIN(35),     { 0x0000002c, 0x00000013 } },
-       { AR5K_RF_GAIN(36),     { 0x0000003a, 0x00000053 } },
-       { AR5K_RF_GAIN(37),     { 0x0000007a, 0x00000093 } },
-       { AR5K_RF_GAIN(38),     { 0x000000ba, 0x00000194 } },
-       { AR5K_RF_GAIN(39),     { 0x000001bb, 0x000001d4 } },
-       { AR5K_RF_GAIN(40),     { 0x000001fb, 0x00000014 } },
-       { AR5K_RF_GAIN(41),     { 0x0000003b, 0x0000003a } },
-       { AR5K_RF_GAIN(42),     { 0x0000007b, 0x0000007a } },
-       { AR5K_RF_GAIN(43),     { 0x000000bb, 0x000000ba } },
-       { AR5K_RF_GAIN(44),     { 0x000001bc, 0x000001bb } },
-       { AR5K_RF_GAIN(45),     { 0x000001fc, 0x000001fb } },
-       { AR5K_RF_GAIN(46),     { 0x0000003c, 0x0000003b } },
-       { AR5K_RF_GAIN(47),     { 0x0000007c, 0x0000007b } },
-       { AR5K_RF_GAIN(48),     { 0x000000bc, 0x000000bb } },
-       { AR5K_RF_GAIN(49),     { 0x000000fc, 0x000001bc } },
-       { AR5K_RF_GAIN(50),     { 0x000000fc, 0x000001fc } },
-       { AR5K_RF_GAIN(51),     { 0x000000fc, 0x0000003c } },
-       { AR5K_RF_GAIN(52),     { 0x000000fc, 0x0000007c } },
-       { AR5K_RF_GAIN(53),     { 0x000000fc, 0x000000bc } },
-       { AR5K_RF_GAIN(54),     { 0x000000fc, 0x000000fc } },
-       { AR5K_RF_GAIN(55),     { 0x000000fc, 0x000000fc } },
-       { AR5K_RF_GAIN(56),     { 0x000000fc, 0x000000fc } },
-       { AR5K_RF_GAIN(57),     { 0x000000fc, 0x000000fc } },
-       { AR5K_RF_GAIN(58),     { 0x000000fc, 0x000000fc } },
-       { AR5K_RF_GAIN(59),     { 0x000000fc, 0x000000fc } },
-       { AR5K_RF_GAIN(60),     { 0x000000fc, 0x000000fc } },
-       { AR5K_RF_GAIN(61),     { 0x000000fc, 0x000000fc } },
-       { AR5K_RF_GAIN(62),     { 0x000000fc, 0x000000fc } },
-       { AR5K_RF_GAIN(63),     { 0x000000fc, 0x000000fc } },
-};
-
-/* Initial RF Gain settings for RF2413 */
-static const struct ath5k_ini_rfgain rfgain_2413[] = {
-       { AR5K_RF_GAIN(0),      { 0x00000000, 0x00000000 } },
-       { AR5K_RF_GAIN(1),      { 0x00000000, 0x00000040 } },
-       { AR5K_RF_GAIN(2),      { 0x00000000, 0x00000080 } },
-       { AR5K_RF_GAIN(3),      { 0x00000000, 0x00000181 } },
-       { AR5K_RF_GAIN(4),      { 0x00000000, 0x000001c1 } },
-       { AR5K_RF_GAIN(5),      { 0x00000000, 0x00000001 } },
-       { AR5K_RF_GAIN(6),      { 0x00000000, 0x00000041 } },
-       { AR5K_RF_GAIN(7),      { 0x00000000, 0x00000081 } },
-       { AR5K_RF_GAIN(8),      { 0x00000000, 0x00000168 } },
-       { AR5K_RF_GAIN(9),      { 0x00000000, 0x000001a8 } },
-       { AR5K_RF_GAIN(10),     { 0x00000000, 0x000001e8 } },
-       { AR5K_RF_GAIN(11),     { 0x00000000, 0x00000028 } },
-       { AR5K_RF_GAIN(12),     { 0x00000000, 0x00000068 } },
-       { AR5K_RF_GAIN(13),     { 0x00000000, 0x00000189 } },
-       { AR5K_RF_GAIN(14),     { 0x00000000, 0x000001c9 } },
-       { AR5K_RF_GAIN(15),     { 0x00000000, 0x00000009 } },
-       { AR5K_RF_GAIN(16),     { 0x00000000, 0x00000049 } },
-       { AR5K_RF_GAIN(17),     { 0x00000000, 0x00000089 } },
-       { AR5K_RF_GAIN(18),     { 0x00000000, 0x00000190 } },
-       { AR5K_RF_GAIN(19),     { 0x00000000, 0x000001d0 } },
-       { AR5K_RF_GAIN(20),     { 0x00000000, 0x00000010 } },
-       { AR5K_RF_GAIN(21),     { 0x00000000, 0x00000050 } },
-       { AR5K_RF_GAIN(22),     { 0x00000000, 0x00000090 } },
-       { AR5K_RF_GAIN(23),     { 0x00000000, 0x00000191 } },
-       { AR5K_RF_GAIN(24),     { 0x00000000, 0x000001d1 } },
-       { AR5K_RF_GAIN(25),     { 0x00000000, 0x00000011 } },
-       { AR5K_RF_GAIN(26),     { 0x00000000, 0x00000051 } },
-       { AR5K_RF_GAIN(27),     { 0x00000000, 0x00000091 } },
-       { AR5K_RF_GAIN(28),     { 0x00000000, 0x00000178 } },
-       { AR5K_RF_GAIN(29),     { 0x00000000, 0x000001b8 } },
-       { AR5K_RF_GAIN(30),     { 0x00000000, 0x000001f8 } },
-       { AR5K_RF_GAIN(31),     { 0x00000000, 0x00000038 } },
-       { AR5K_RF_GAIN(32),     { 0x00000000, 0x00000078 } },
-       { AR5K_RF_GAIN(33),     { 0x00000000, 0x00000199 } },
-       { AR5K_RF_GAIN(34),     { 0x00000000, 0x000001d9 } },
-       { AR5K_RF_GAIN(35),     { 0x00000000, 0x00000019 } },
-       { AR5K_RF_GAIN(36),     { 0x00000000, 0x00000059 } },
-       { AR5K_RF_GAIN(37),     { 0x00000000, 0x00000099 } },
-       { AR5K_RF_GAIN(38),     { 0x00000000, 0x000000d9 } },
-       { AR5K_RF_GAIN(39),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(40),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(41),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(42),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(43),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(44),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(45),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(46),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(47),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(48),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(49),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(50),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(51),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(52),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(53),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(54),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(55),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(56),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(57),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(58),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(59),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(60),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(61),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(62),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(63),     { 0x00000000, 0x000000f9 } },
-};
-
-/* Initial RF Gain settings for AR2316 */
-static const struct ath5k_ini_rfgain rfgain_2316[] = {
-       { AR5K_RF_GAIN(0),      { 0x00000000, 0x00000000 } },
-       { AR5K_RF_GAIN(1),      { 0x00000000, 0x00000040 } },
-       { AR5K_RF_GAIN(2),      { 0x00000000, 0x00000080 } },
-       { AR5K_RF_GAIN(3),      { 0x00000000, 0x000000c0 } },
-       { AR5K_RF_GAIN(4),      { 0x00000000, 0x000000e0 } },
-       { AR5K_RF_GAIN(5),      { 0x00000000, 0x000000e0 } },
-       { AR5K_RF_GAIN(6),      { 0x00000000, 0x00000128 } },
-       { AR5K_RF_GAIN(7),      { 0x00000000, 0x00000128 } },
-       { AR5K_RF_GAIN(8),      { 0x00000000, 0x00000128 } },
-       { AR5K_RF_GAIN(9),      { 0x00000000, 0x00000168 } },
-       { AR5K_RF_GAIN(10),     { 0x00000000, 0x000001a8 } },
-       { AR5K_RF_GAIN(11),     { 0x00000000, 0x000001e8 } },
-       { AR5K_RF_GAIN(12),     { 0x00000000, 0x00000028 } },
-       { AR5K_RF_GAIN(13),     { 0x00000000, 0x00000068 } },
-       { AR5K_RF_GAIN(14),     { 0x00000000, 0x000000a8 } },
-       { AR5K_RF_GAIN(15),     { 0x00000000, 0x000000e8 } },
-       { AR5K_RF_GAIN(16),     { 0x00000000, 0x000000e8 } },
-       { AR5K_RF_GAIN(17),     { 0x00000000, 0x00000130 } },
-       { AR5K_RF_GAIN(18),     { 0x00000000, 0x00000130 } },
-       { AR5K_RF_GAIN(19),     { 0x00000000, 0x00000170 } },
-       { AR5K_RF_GAIN(20),     { 0x00000000, 0x000001b0 } },
-       { AR5K_RF_GAIN(21),     { 0x00000000, 0x000001f0 } },
-       { AR5K_RF_GAIN(22),     { 0x00000000, 0x00000030 } },
-       { AR5K_RF_GAIN(23),     { 0x00000000, 0x00000070 } },
-       { AR5K_RF_GAIN(24),     { 0x00000000, 0x000000b0 } },
-       { AR5K_RF_GAIN(25),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(26),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(27),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(28),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(29),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(30),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(31),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(32),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(33),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(34),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(35),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(36),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(37),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(38),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(39),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(40),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(41),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(42),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(43),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(44),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(45),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(46),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(47),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(48),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(49),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(50),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(51),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(52),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(53),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(54),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(55),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(56),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(57),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(58),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(59),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(60),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(61),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(62),     { 0x00000000, 0x000000f0 } },
-       { AR5K_RF_GAIN(63),     { 0x00000000, 0x000000f0 } },
-};
-
-
-/* Initial RF Gain settings for RF5413 */
-static const struct ath5k_ini_rfgain rfgain_5413[] = {
-       /*                            5Ghz      2Ghz    */
-       { AR5K_RF_GAIN(0),      { 0x00000000, 0x00000000 } },
-       { AR5K_RF_GAIN(1),      { 0x00000040, 0x00000040 } },
-       { AR5K_RF_GAIN(2),      { 0x00000080, 0x00000080 } },
-       { AR5K_RF_GAIN(3),      { 0x000001a1, 0x00000161 } },
-       { AR5K_RF_GAIN(4),      { 0x000001e1, 0x000001a1 } },
-       { AR5K_RF_GAIN(5),      { 0x00000021, 0x000001e1 } },
-       { AR5K_RF_GAIN(6),      { 0x00000061, 0x00000021 } },
-       { AR5K_RF_GAIN(7),      { 0x00000188, 0x00000061 } },
-       { AR5K_RF_GAIN(8),      { 0x000001c8, 0x00000188 } },
-       { AR5K_RF_GAIN(9),      { 0x00000008, 0x000001c8 } },
-       { AR5K_RF_GAIN(10),     { 0x00000048, 0x00000008 } },
-       { AR5K_RF_GAIN(11),     { 0x00000088, 0x00000048 } },
-       { AR5K_RF_GAIN(12),     { 0x000001a9, 0x00000088 } },
-       { AR5K_RF_GAIN(13),     { 0x000001e9, 0x00000169 } },
-       { AR5K_RF_GAIN(14),     { 0x00000029, 0x000001a9 } },
-       { AR5K_RF_GAIN(15),     { 0x00000069, 0x000001e9 } },
-       { AR5K_RF_GAIN(16),     { 0x000001d0, 0x00000029 } },
-       { AR5K_RF_GAIN(17),     { 0x00000010, 0x00000069 } },
-       { AR5K_RF_GAIN(18),     { 0x00000050, 0x00000190 } },
-       { AR5K_RF_GAIN(19),     { 0x00000090, 0x000001d0 } },
-       { AR5K_RF_GAIN(20),     { 0x000001b1, 0x00000010 } },
-       { AR5K_RF_GAIN(21),     { 0x000001f1, 0x00000050 } },
-       { AR5K_RF_GAIN(22),     { 0x00000031, 0x00000090 } },
-       { AR5K_RF_GAIN(23),     { 0x00000071, 0x00000171 } },
-       { AR5K_RF_GAIN(24),     { 0x000001b8, 0x000001b1 } },
-       { AR5K_RF_GAIN(25),     { 0x000001f8, 0x000001f1 } },
-       { AR5K_RF_GAIN(26),     { 0x00000038, 0x00000031 } },
-       { AR5K_RF_GAIN(27),     { 0x00000078, 0x00000071 } },
-       { AR5K_RF_GAIN(28),     { 0x00000199, 0x00000198 } },
-       { AR5K_RF_GAIN(29),     { 0x000001d9, 0x000001d8 } },
-       { AR5K_RF_GAIN(30),     { 0x00000019, 0x00000018 } },
-       { AR5K_RF_GAIN(31),     { 0x00000059, 0x00000058 } },
-       { AR5K_RF_GAIN(32),     { 0x00000099, 0x00000098 } },
-       { AR5K_RF_GAIN(33),     { 0x000000d9, 0x00000179 } },
-       { AR5K_RF_GAIN(34),     { 0x000000f9, 0x000001b9 } },
-       { AR5K_RF_GAIN(35),     { 0x000000f9, 0x000001f9 } },
-       { AR5K_RF_GAIN(36),     { 0x000000f9, 0x00000039 } },
-       { AR5K_RF_GAIN(37),     { 0x000000f9, 0x00000079 } },
-       { AR5K_RF_GAIN(38),     { 0x000000f9, 0x000000b9 } },
-       { AR5K_RF_GAIN(39),     { 0x000000f9, 0x000000f9 } },
-       { AR5K_RF_GAIN(40),     { 0x000000f9, 0x000000f9 } },
-       { AR5K_RF_GAIN(41),     { 0x000000f9, 0x000000f9 } },
-       { AR5K_RF_GAIN(42),     { 0x000000f9, 0x000000f9 } },
-       { AR5K_RF_GAIN(43),     { 0x000000f9, 0x000000f9 } },
-       { AR5K_RF_GAIN(44),     { 0x000000f9, 0x000000f9 } },
-       { AR5K_RF_GAIN(45),     { 0x000000f9, 0x000000f9 } },
-       { AR5K_RF_GAIN(46),     { 0x000000f9, 0x000000f9 } },
-       { AR5K_RF_GAIN(47),     { 0x000000f9, 0x000000f9 } },
-       { AR5K_RF_GAIN(48),     { 0x000000f9, 0x000000f9 } },
-       { AR5K_RF_GAIN(49),     { 0x000000f9, 0x000000f9 } },
-       { AR5K_RF_GAIN(50),     { 0x000000f9, 0x000000f9 } },
-       { AR5K_RF_GAIN(51),     { 0x000000f9, 0x000000f9 } },
-       { AR5K_RF_GAIN(52),     { 0x000000f9, 0x000000f9 } },
-       { AR5K_RF_GAIN(53),     { 0x000000f9, 0x000000f9 } },
-       { AR5K_RF_GAIN(54),     { 0x000000f9, 0x000000f9 } },
-       { AR5K_RF_GAIN(55),     { 0x000000f9, 0x000000f9 } },
-       { AR5K_RF_GAIN(56),     { 0x000000f9, 0x000000f9 } },
-       { AR5K_RF_GAIN(57),     { 0x000000f9, 0x000000f9 } },
-       { AR5K_RF_GAIN(58),     { 0x000000f9, 0x000000f9 } },
-       { AR5K_RF_GAIN(59),     { 0x000000f9, 0x000000f9 } },
-       { AR5K_RF_GAIN(60),     { 0x000000f9, 0x000000f9 } },
-       { AR5K_RF_GAIN(61),     { 0x000000f9, 0x000000f9 } },
-       { AR5K_RF_GAIN(62),     { 0x000000f9, 0x000000f9 } },
-       { AR5K_RF_GAIN(63),     { 0x000000f9, 0x000000f9 } },
-};
-
-
-/* Initial RF Gain settings for RF2425 */
-static const struct ath5k_ini_rfgain rfgain_2425[] = {
-       { AR5K_RF_GAIN(0),      { 0x00000000, 0x00000000 } },
-       { AR5K_RF_GAIN(1),      { 0x00000000, 0x00000040 } },
-       { AR5K_RF_GAIN(2),      { 0x00000000, 0x00000080 } },
-       { AR5K_RF_GAIN(3),      { 0x00000000, 0x00000181 } },
-       { AR5K_RF_GAIN(4),      { 0x00000000, 0x000001c1 } },
-       { AR5K_RF_GAIN(5),      { 0x00000000, 0x00000001 } },
-       { AR5K_RF_GAIN(6),      { 0x00000000, 0x00000041 } },
-       { AR5K_RF_GAIN(7),      { 0x00000000, 0x00000081 } },
-       { AR5K_RF_GAIN(8),      { 0x00000000, 0x00000188 } },
-       { AR5K_RF_GAIN(9),      { 0x00000000, 0x000001c8 } },
-       { AR5K_RF_GAIN(10),     { 0x00000000, 0x00000008 } },
-       { AR5K_RF_GAIN(11),     { 0x00000000, 0x00000048 } },
-       { AR5K_RF_GAIN(12),     { 0x00000000, 0x00000088 } },
-       { AR5K_RF_GAIN(13),     { 0x00000000, 0x00000189 } },
-       { AR5K_RF_GAIN(14),     { 0x00000000, 0x000001c9 } },
-       { AR5K_RF_GAIN(15),     { 0x00000000, 0x00000009 } },
-       { AR5K_RF_GAIN(16),     { 0x00000000, 0x00000049 } },
-       { AR5K_RF_GAIN(17),     { 0x00000000, 0x00000089 } },
-       { AR5K_RF_GAIN(18),     { 0x00000000, 0x000001b0 } },
-       { AR5K_RF_GAIN(19),     { 0x00000000, 0x000001f0 } },
-       { AR5K_RF_GAIN(20),     { 0x00000000, 0x00000030 } },
-       { AR5K_RF_GAIN(21),     { 0x00000000, 0x00000070 } },
-       { AR5K_RF_GAIN(22),     { 0x00000000, 0x00000171 } },
-       { AR5K_RF_GAIN(23),     { 0x00000000, 0x000001b1 } },
-       { AR5K_RF_GAIN(24),     { 0x00000000, 0x000001f1 } },
-       { AR5K_RF_GAIN(25),     { 0x00000000, 0x00000031 } },
-       { AR5K_RF_GAIN(26),     { 0x00000000, 0x00000071 } },
-       { AR5K_RF_GAIN(27),     { 0x00000000, 0x000001b8 } },
-       { AR5K_RF_GAIN(28),     { 0x00000000, 0x000001f8 } },
-       { AR5K_RF_GAIN(29),     { 0x00000000, 0x00000038 } },
-       { AR5K_RF_GAIN(30),     { 0x00000000, 0x00000078 } },
-       { AR5K_RF_GAIN(31),     { 0x00000000, 0x000000b8 } },
-       { AR5K_RF_GAIN(32),     { 0x00000000, 0x000001b9 } },
-       { AR5K_RF_GAIN(33),     { 0x00000000, 0x000001f9 } },
-       { AR5K_RF_GAIN(34),     { 0x00000000, 0x00000039 } },
-       { AR5K_RF_GAIN(35),     { 0x00000000, 0x00000079 } },
-       { AR5K_RF_GAIN(36),     { 0x00000000, 0x000000b9 } },
-       { AR5K_RF_GAIN(37),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(38),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(39),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(40),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(41),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(42),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(43),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(44),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(45),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(46),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(47),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(48),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(49),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(50),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(51),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(52),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(53),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(54),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(55),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(56),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(57),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(58),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(59),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(60),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(61),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(62),     { 0x00000000, 0x000000f9 } },
-       { AR5K_RF_GAIN(63),     { 0x00000000, 0x000000f9 } },
-};
-
-#define AR5K_GAIN_CRN_FIX_BITS_5111            4
-#define AR5K_GAIN_CRN_FIX_BITS_5112            7
-#define AR5K_GAIN_CRN_MAX_FIX_BITS             AR5K_GAIN_CRN_FIX_BITS_5112
-#define AR5K_GAIN_DYN_ADJUST_HI_MARGIN         15
-#define AR5K_GAIN_DYN_ADJUST_LO_MARGIN         20
-#define AR5K_GAIN_CCK_PROBE_CORR               5
-#define AR5K_GAIN_CCK_OFDM_GAIN_DELTA          15
-#define AR5K_GAIN_STEP_COUNT                   10
-
-/* Check if our current measurement is inside our
- * current variable attenuation window */
-#define AR5K_GAIN_CHECK_ADJUST(_g)             \
-       ((_g)->g_current <= (_g)->g_low || (_g)->g_current >= (_g)->g_high)
-
-struct ath5k_gain_opt_step {
-       s8                              gos_param[AR5K_GAIN_CRN_MAX_FIX_BITS];
-       s8                              gos_gain;
-};
-
-struct ath5k_gain_opt {
-       u8                              go_default;
-       u8                              go_steps_count;
-       const struct ath5k_gain_opt_step        go_step[AR5K_GAIN_STEP_COUNT];
-};
-
-/*
- * Parameters on gos_param:
- * 1) Tx clip PHY register
- * 2) PWD 90 RF register
- * 3) PWD 84 RF register
- * 4) RFGainSel RF register
- */
-static const struct ath5k_gain_opt rfgain_opt_5111 = {
-       4,
-       9,
-       {
-               { { 4, 1, 1, 1 }, 6 },
-               { { 4, 0, 1, 1 }, 4 },
-               { { 3, 1, 1, 1 }, 3 },
-               { { 4, 0, 0, 1 }, 1 },
-               { { 4, 1, 1, 0 }, 0 },
-               { { 4, 0, 1, 0 }, -2 },
-               { { 3, 1, 1, 0 }, -3 },
-               { { 4, 0, 0, 0 }, -4 },
-               { { 2, 1, 1, 0 }, -6 }
-       }
-};
-
-/*
- * Parameters on gos_param:
- * 1) Mixgain ovr RF register
- * 2) PWD 138 RF register
- * 3) PWD 137 RF register
- * 4) PWD 136 RF register
- * 5) PWD 132 RF register
- * 6) PWD 131 RF register
- * 7) PWD 130 RF register
- */
-static const struct ath5k_gain_opt rfgain_opt_5112 = {
-       1,
-       8,
-       {
-               { { 3, 0, 0, 0, 0, 0, 0 }, 6 },
-               { { 2, 0, 0, 0, 0, 0, 0 }, 0 },
-               { { 1, 0, 0, 0, 0, 0, 0 }, -3 },
-               { { 0, 0, 0, 0, 0, 0, 0 }, -6 },
-               { { 0, 1, 1, 0, 0, 0, 0 }, -8 },
-               { { 0, 1, 1, 0, 1, 1, 0 }, -10 },
-               { { 0, 1, 0, 1, 1, 1, 0 }, -13 },
-               { { 0, 1, 0, 1, 1, 0, 1 }, -16 },
-       }
-};
-
diff --git a/drivers/net/wireless/ath9k/Kconfig b/drivers/net/wireless/ath9k/Kconfig
deleted file mode 100644 (file)
index 90a8dd8..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-config ATH9K
-       tristate "Atheros 802.11n wireless cards support"
-       depends on PCI && MAC80211 && WLAN_80211
-       depends on RFKILL || RFKILL=n
-       select MAC80211_LEDS
-       select LEDS_CLASS
-       select NEW_LEDS
-       ---help---
-         This module adds support for wireless adapters based on
-         Atheros IEEE 802.11n AR5008 and AR9001 family of chipsets.
-
-         If you choose to build a module, it'll be called ath9k.
-
-config ATH9K_DEBUG
-       bool "Atheros ath9k debugging"
-       depends on ATH9K
-       ---help---
-         Say Y, if you need ath9k to display debug messages.
-         Pass the debug mask as a module parameter:
-
-         modprobe ath9k debug=0x00002000
-
-         Look in ath9k/core.h for possible debug masks
diff --git a/drivers/net/wireless/ath9k/Makefile b/drivers/net/wireless/ath9k/Makefile
deleted file mode 100644 (file)
index 1a4d4ea..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-ath9k-y +=     hw.o \
-               eeprom.o \
-               mac.o \
-               calib.o \
-               ani.o \
-               phy.o \
-               regd.o \
-               beacon.o \
-               main.o \
-               recv.o \
-               xmit.o \
-               virtual.o \
-               rc.o
-
-ath9k-$(CONFIG_PCI) += pci.o
-ath9k-$(CONFIG_ATHEROS_AR71XX) += ahb.o
-ath9k-$(CONFIG_ATH9K_DEBUG) += debug.o
-
-obj-$(CONFIG_ATH9K) += ath9k.o
diff --git a/drivers/net/wireless/ath9k/ahb.c b/drivers/net/wireless/ath9k/ahb.c
deleted file mode 100644 (file)
index 0e65c51..0000000
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * Copyright (c) 2008-2009 Atheros Communications Inc.
- * Copyright (c) 2009 Gabor Juhos <juhosg@openwrt.org>
- * Copyright (c) 2009 Imre Kaloz <kaloz@openwrt.org>
- *
- * 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/nl80211.h>
-#include <linux/platform_device.h>
-#include <linux/ath9k_platform.h>
-#include "ath9k.h"
-
-/* return bus cachesize in 4B word units */
-static void ath_ahb_read_cachesize(struct ath_softc *sc, int *csz)
-{
-       *csz = L1_CACHE_BYTES >> 2;
-}
-
-static void ath_ahb_cleanup(struct ath_softc *sc)
-{
-       iounmap(sc->mem);
-}
-
-static bool ath_ahb_eeprom_read(struct ath_hw *ah, u32 off, u16 *data)
-{
-       struct ath_softc *sc = ah->ah_sc;
-       struct platform_device *pdev = to_platform_device(sc->dev);
-       struct ath9k_platform_data *pdata;
-
-       pdata = (struct ath9k_platform_data *) pdev->dev.platform_data;
-       if (off >= (ARRAY_SIZE(pdata->eeprom_data))) {
-               DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-                       "%s: flash read failed, offset %08x is out of range\n",
-                               __func__, off);
-               return false;
-       }
-
-       *data = pdata->eeprom_data[off];
-       return true;
-}
-
-static struct ath_bus_ops ath_ahb_bus_ops  = {
-       .read_cachesize = ath_ahb_read_cachesize,
-       .cleanup = ath_ahb_cleanup,
-
-       .eeprom_read = ath_ahb_eeprom_read,
-};
-
-static int ath_ahb_probe(struct platform_device *pdev)
-{
-       void __iomem *mem;
-       struct ath_wiphy *aphy;
-       struct ath_softc *sc;
-       struct ieee80211_hw *hw;
-       struct resource *res;
-       int irq;
-       int ret = 0;
-       struct ath_hw *ah;
-
-       if (!pdev->dev.platform_data) {
-               dev_err(&pdev->dev, "no platform data specified\n");
-               ret = -EINVAL;
-               goto err_out;
-       }
-
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (res == NULL) {
-               dev_err(&pdev->dev, "no memory resource found\n");
-               ret = -ENXIO;
-               goto err_out;
-       }
-
-       mem = ioremap_nocache(res->start, res->end - res->start + 1);
-       if (mem == NULL) {
-               dev_err(&pdev->dev, "ioremap failed\n");
-               ret = -ENOMEM;
-               goto err_out;
-       }
-
-       res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-       if (res == NULL) {
-               dev_err(&pdev->dev, "no IRQ resource found\n");
-               ret = -ENXIO;
-               goto err_iounmap;
-       }
-
-       irq = res->start;
-
-       hw = ieee80211_alloc_hw(sizeof(struct ath_wiphy) +
-                               sizeof(struct ath_softc), &ath9k_ops);
-       if (hw == NULL) {
-               dev_err(&pdev->dev, "no memory for ieee80211_hw\n");
-               ret = -ENOMEM;
-               goto err_iounmap;
-       }
-
-       SET_IEEE80211_DEV(hw, &pdev->dev);
-       platform_set_drvdata(pdev, hw);
-
-       aphy = hw->priv;
-       sc = (struct ath_softc *) (aphy + 1);
-       aphy->sc = sc;
-       aphy->hw = hw;
-       sc->pri_wiphy = aphy;
-       sc->hw = hw;
-       sc->dev = &pdev->dev;
-       sc->mem = mem;
-       sc->bus_ops = &ath_ahb_bus_ops;
-       sc->irq = irq;
-
-       ret = ath_attach(AR5416_AR9100_DEVID, sc);
-       if (ret != 0) {
-               dev_err(&pdev->dev, "failed to attach device, err=%d\n", ret);
-               ret = -ENODEV;
-               goto err_free_hw;
-       }
-
-       ret = request_irq(irq, ath_isr, IRQF_SHARED, "ath9k", sc);
-       if (ret) {
-               dev_err(&pdev->dev, "request_irq failed, err=%d\n", ret);
-               ret = -EIO;
-               goto err_detach;
-       }
-
-       ah = sc->sc_ah;
-       printk(KERN_INFO
-              "%s: Atheros AR%s MAC/BB Rev:%x, "
-              "AR%s RF Rev:%x, mem=0x%lx, irq=%d\n",
-              wiphy_name(hw->wiphy),
-              ath_mac_bb_name(ah->hw_version.macVersion),
-              ah->hw_version.macRev,
-              ath_rf_name((ah->hw_version.analog5GhzRev & AR_RADIO_SREV_MAJOR)),
-              ah->hw_version.phyRev,
-              (unsigned long)mem, irq);
-
-       return 0;
-
- err_detach:
-       ath_detach(sc);
- err_free_hw:
-       ieee80211_free_hw(hw);
-       platform_set_drvdata(pdev, NULL);
- err_iounmap:
-       iounmap(mem);
- err_out:
-       return ret;
-}
-
-static int ath_ahb_remove(struct platform_device *pdev)
-{
-       struct ieee80211_hw *hw = platform_get_drvdata(pdev);
-
-       if (hw) {
-               struct ath_wiphy *aphy = hw->priv;
-               struct ath_softc *sc = aphy->sc;
-
-               ath_cleanup(sc);
-               platform_set_drvdata(pdev, NULL);
-       }
-
-       return 0;
-}
-
-static struct platform_driver ath_ahb_driver = {
-       .probe      = ath_ahb_probe,
-       .remove     = ath_ahb_remove,
-       .driver         = {
-               .name   = "ath9k",
-               .owner  = THIS_MODULE,
-       },
-};
-
-int ath_ahb_init(void)
-{
-       return platform_driver_register(&ath_ahb_driver);
-}
-
-void ath_ahb_exit(void)
-{
-       platform_driver_unregister(&ath_ahb_driver);
-}
diff --git a/drivers/net/wireless/ath9k/ani.c b/drivers/net/wireless/ath9k/ani.c
deleted file mode 100644 (file)
index 6c5e887..0000000
+++ /dev/null
@@ -1,824 +0,0 @@
-/*
- * Copyright (c) 2008-2009 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 "ath9k.h"
-
-static int ath9k_hw_get_ani_channel_idx(struct ath_hw *ah,
-                                       struct ath9k_channel *chan)
-{
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(ah->ani); i++) {
-               if (ah->ani[i].c &&
-                   ah->ani[i].c->channel == chan->channel)
-                       return i;
-               if (ah->ani[i].c == NULL) {
-                       ah->ani[i].c = chan;
-                       return i;
-               }
-       }
-
-       DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-               "No more channel states left. Using channel 0\n");
-
-       return 0;
-}
-
-static bool ath9k_hw_ani_control(struct ath_hw *ah,
-                                enum ath9k_ani_cmd cmd, int param)
-{
-       struct ar5416AniState *aniState = ah->curani;
-
-       switch (cmd & ah->ani_function) {
-       case ATH9K_ANI_NOISE_IMMUNITY_LEVEL:{
-               u32 level = param;
-
-               if (level >= ARRAY_SIZE(ah->totalSizeDesired)) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-                               "level out of range (%u > %u)\n",
-                               level,
-                               (unsigned)ARRAY_SIZE(ah->totalSizeDesired));
-                       return false;
-               }
-
-               REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
-                             AR_PHY_DESIRED_SZ_TOT_DES,
-                             ah->totalSizeDesired[level]);
-               REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1,
-                             AR_PHY_AGC_CTL1_COARSE_LOW,
-                             ah->coarse_low[level]);
-               REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1,
-                             AR_PHY_AGC_CTL1_COARSE_HIGH,
-                             ah->coarse_high[level]);
-               REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
-                             AR_PHY_FIND_SIG_FIRPWR,
-                             ah->firpwr[level]);
-
-               if (level > aniState->noiseImmunityLevel)
-                       ah->stats.ast_ani_niup++;
-               else if (level < aniState->noiseImmunityLevel)
-                       ah->stats.ast_ani_nidown++;
-               aniState->noiseImmunityLevel = level;
-               break;
-       }
-       case ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION:{
-               const int m1ThreshLow[] = { 127, 50 };
-               const int m2ThreshLow[] = { 127, 40 };
-               const int m1Thresh[] = { 127, 0x4d };
-               const int m2Thresh[] = { 127, 0x40 };
-               const int m2CountThr[] = { 31, 16 };
-               const int m2CountThrLow[] = { 63, 48 };
-               u32 on = param ? 1 : 0;
-
-               REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
-                             AR_PHY_SFCORR_LOW_M1_THRESH_LOW,
-                             m1ThreshLow[on]);
-               REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
-                             AR_PHY_SFCORR_LOW_M2_THRESH_LOW,
-                             m2ThreshLow[on]);
-               REG_RMW_FIELD(ah, AR_PHY_SFCORR,
-                             AR_PHY_SFCORR_M1_THRESH,
-                             m1Thresh[on]);
-               REG_RMW_FIELD(ah, AR_PHY_SFCORR,
-                             AR_PHY_SFCORR_M2_THRESH,
-                             m2Thresh[on]);
-               REG_RMW_FIELD(ah, AR_PHY_SFCORR,
-                             AR_PHY_SFCORR_M2COUNT_THR,
-                             m2CountThr[on]);
-               REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
-                             AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW,
-                             m2CountThrLow[on]);
-
-               REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
-                             AR_PHY_SFCORR_EXT_M1_THRESH_LOW,
-                             m1ThreshLow[on]);
-               REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
-                             AR_PHY_SFCORR_EXT_M2_THRESH_LOW,
-                             m2ThreshLow[on]);
-               REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
-                             AR_PHY_SFCORR_EXT_M1_THRESH,
-                             m1Thresh[on]);
-               REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
-                             AR_PHY_SFCORR_EXT_M2_THRESH,
-                             m2Thresh[on]);
-
-               if (on)
-                       REG_SET_BIT(ah, AR_PHY_SFCORR_LOW,
-                                   AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
-               else
-                       REG_CLR_BIT(ah, AR_PHY_SFCORR_LOW,
-                                   AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
-
-               if (!on != aniState->ofdmWeakSigDetectOff) {
-                       if (on)
-                               ah->stats.ast_ani_ofdmon++;
-                       else
-                               ah->stats.ast_ani_ofdmoff++;
-                       aniState->ofdmWeakSigDetectOff = !on;
-               }
-               break;
-       }
-       case ATH9K_ANI_CCK_WEAK_SIGNAL_THR:{
-               const int weakSigThrCck[] = { 8, 6 };
-               u32 high = param ? 1 : 0;
-
-               REG_RMW_FIELD(ah, AR_PHY_CCK_DETECT,
-                             AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK,
-                             weakSigThrCck[high]);
-               if (high != aniState->cckWeakSigThreshold) {
-                       if (high)
-                               ah->stats.ast_ani_cckhigh++;
-                       else
-                               ah->stats.ast_ani_ccklow++;
-                       aniState->cckWeakSigThreshold = high;
-               }
-               break;
-       }
-       case ATH9K_ANI_FIRSTEP_LEVEL:{
-               const int firstep[] = { 0, 4, 8 };
-               u32 level = param;
-
-               if (level >= ARRAY_SIZE(firstep)) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-                               "level out of range (%u > %u)\n",
-                               level,
-                               (unsigned) ARRAY_SIZE(firstep));
-                       return false;
-               }
-               REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
-                             AR_PHY_FIND_SIG_FIRSTEP,
-                             firstep[level]);
-               if (level > aniState->firstepLevel)
-                       ah->stats.ast_ani_stepup++;
-               else if (level < aniState->firstepLevel)
-                       ah->stats.ast_ani_stepdown++;
-               aniState->firstepLevel = level;
-               break;
-       }
-       case ATH9K_ANI_SPUR_IMMUNITY_LEVEL:{
-               const int cycpwrThr1[] =
-                       { 2, 4, 6, 8, 10, 12, 14, 16 };
-               u32 level = param;
-
-               if (level >= ARRAY_SIZE(cycpwrThr1)) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-                               "level out of range (%u > %u)\n",
-                               level,
-                               (unsigned)
-                               ARRAY_SIZE(cycpwrThr1));
-                       return false;
-               }
-               REG_RMW_FIELD(ah, AR_PHY_TIMING5,
-                             AR_PHY_TIMING5_CYCPWR_THR1,
-                             cycpwrThr1[level]);
-               if (level > aniState->spurImmunityLevel)
-                       ah->stats.ast_ani_spurup++;
-               else if (level < aniState->spurImmunityLevel)
-                       ah->stats.ast_ani_spurdown++;
-               aniState->spurImmunityLevel = level;
-               break;
-       }
-       case ATH9K_ANI_PRESENT:
-               break;
-       default:
-               DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-                       "invalid cmd %u\n", cmd);
-               return false;
-       }
-
-       DPRINTF(ah->ah_sc, ATH_DBG_ANI, "ANI parameters:\n");
-       DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-               "noiseImmunityLevel=%d, spurImmunityLevel=%d, "
-               "ofdmWeakSigDetectOff=%d\n",
-               aniState->noiseImmunityLevel, aniState->spurImmunityLevel,
-               !aniState->ofdmWeakSigDetectOff);
-       DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-               "cckWeakSigThreshold=%d, "
-               "firstepLevel=%d, listenTime=%d\n",
-               aniState->cckWeakSigThreshold, aniState->firstepLevel,
-               aniState->listenTime);
-       DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-               "cycleCount=%d, ofdmPhyErrCount=%d, cckPhyErrCount=%d\n\n",
-               aniState->cycleCount, aniState->ofdmPhyErrCount,
-               aniState->cckPhyErrCount);
-
-       return true;
-}
-
-static void ath9k_hw_update_mibstats(struct ath_hw *ah,
-                                    struct ath9k_mib_stats *stats)
-{
-       stats->ackrcv_bad += REG_READ(ah, AR_ACK_FAIL);
-       stats->rts_bad += REG_READ(ah, AR_RTS_FAIL);
-       stats->fcs_bad += REG_READ(ah, AR_FCS_FAIL);
-       stats->rts_good += REG_READ(ah, AR_RTS_OK);
-       stats->beacons += REG_READ(ah, AR_BEACON_CNT);
-}
-
-static void ath9k_ani_restart(struct ath_hw *ah)
-{
-       struct ar5416AniState *aniState;
-
-       if (!DO_ANI(ah))
-               return;
-
-       aniState = ah->curani;
-
-       aniState->listenTime = 0;
-       if (ah->has_hw_phycounters) {
-               if (aniState->ofdmTrigHigh > AR_PHY_COUNTMAX) {
-                       aniState->ofdmPhyErrBase = 0;
-                       DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-                               "OFDM Trigger is too high for hw counters\n");
-               } else {
-                       aniState->ofdmPhyErrBase =
-                               AR_PHY_COUNTMAX - aniState->ofdmTrigHigh;
-               }
-               if (aniState->cckTrigHigh > AR_PHY_COUNTMAX) {
-                       aniState->cckPhyErrBase = 0;
-                       DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-                               "CCK Trigger is too high for hw counters\n");
-               } else {
-                       aniState->cckPhyErrBase =
-                               AR_PHY_COUNTMAX - aniState->cckTrigHigh;
-               }
-               DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-                       "Writing ofdmbase=%u   cckbase=%u\n",
-                       aniState->ofdmPhyErrBase,
-                       aniState->cckPhyErrBase);
-               REG_WRITE(ah, AR_PHY_ERR_1, aniState->ofdmPhyErrBase);
-               REG_WRITE(ah, AR_PHY_ERR_2, aniState->cckPhyErrBase);
-               REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
-               REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
-
-               ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
-       }
-       aniState->ofdmPhyErrCount = 0;
-       aniState->cckPhyErrCount = 0;
-}
-
-static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hw *ah)
-{
-       struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
-       struct ar5416AniState *aniState;
-       int32_t rssi;
-
-       if (!DO_ANI(ah))
-               return;
-
-       aniState = ah->curani;
-
-       if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) {
-               if (ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
-                                        aniState->noiseImmunityLevel + 1)) {
-                       return;
-               }
-       }
-
-       if (aniState->spurImmunityLevel < HAL_SPUR_IMMUNE_MAX) {
-               if (ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL,
-                                        aniState->spurImmunityLevel + 1)) {
-                       return;
-               }
-       }
-
-       if (ah->opmode == NL80211_IFTYPE_AP) {
-               if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) {
-                       ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
-                                            aniState->firstepLevel + 1);
-               }
-               return;
-       }
-       rssi = BEACON_RSSI(ah);
-       if (rssi > aniState->rssiThrHigh) {
-               if (!aniState->ofdmWeakSigDetectOff) {
-                       if (ath9k_hw_ani_control(ah,
-                                        ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
-                                        false)) {
-                               ath9k_hw_ani_control(ah,
-                                       ATH9K_ANI_SPUR_IMMUNITY_LEVEL, 0);
-                               return;
-                       }
-               }
-               if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) {
-                       ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
-                                            aniState->firstepLevel + 1);
-                       return;
-               }
-       } else if (rssi > aniState->rssiThrLow) {
-               if (aniState->ofdmWeakSigDetectOff)
-                       ath9k_hw_ani_control(ah,
-                                    ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
-                                    true);
-               if (aniState->firstepLevel < HAL_FIRST_STEP_MAX)
-                       ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
-                                            aniState->firstepLevel + 1);
-               return;
-       } else {
-               if (conf->channel->band == IEEE80211_BAND_2GHZ) {
-                       if (!aniState->ofdmWeakSigDetectOff)
-                               ath9k_hw_ani_control(ah,
-                                    ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
-                                    false);
-                       if (aniState->firstepLevel > 0)
-                               ath9k_hw_ani_control(ah,
-                                            ATH9K_ANI_FIRSTEP_LEVEL, 0);
-                       return;
-               }
-       }
-}
-
-static void ath9k_hw_ani_cck_err_trigger(struct ath_hw *ah)
-{
-       struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
-       struct ar5416AniState *aniState;
-       int32_t rssi;
-
-       if (!DO_ANI(ah))
-               return;
-
-       aniState = ah->curani;
-       if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) {
-               if (ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
-                                        aniState->noiseImmunityLevel + 1)) {
-                       return;
-               }
-       }
-       if (ah->opmode == NL80211_IFTYPE_AP) {
-               if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) {
-                       ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
-                                            aniState->firstepLevel + 1);
-               }
-               return;
-       }
-       rssi = BEACON_RSSI(ah);
-       if (rssi > aniState->rssiThrLow) {
-               if (aniState->firstepLevel < HAL_FIRST_STEP_MAX)
-                       ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
-                                            aniState->firstepLevel + 1);
-       } else {
-               if (conf->channel->band == IEEE80211_BAND_2GHZ) {
-                       if (aniState->firstepLevel > 0)
-                               ath9k_hw_ani_control(ah,
-                                            ATH9K_ANI_FIRSTEP_LEVEL, 0);
-               }
-       }
-}
-
-static void ath9k_hw_ani_lower_immunity(struct ath_hw *ah)
-{
-       struct ar5416AniState *aniState;
-       int32_t rssi;
-
-       aniState = ah->curani;
-
-       if (ah->opmode == NL80211_IFTYPE_AP) {
-               if (aniState->firstepLevel > 0) {
-                       if (ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
-                                                aniState->firstepLevel - 1))
-                               return;
-               }
-       } else {
-               rssi = BEACON_RSSI(ah);
-               if (rssi > aniState->rssiThrHigh) {
-                       /* XXX: Handle me */
-               } else if (rssi > aniState->rssiThrLow) {
-                       if (aniState->ofdmWeakSigDetectOff) {
-                               if (ath9k_hw_ani_control(ah,
-                                        ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
-                                        true) == true)
-                                       return;
-                       }
-                       if (aniState->firstepLevel > 0) {
-                               if (ath9k_hw_ani_control(ah,
-                                        ATH9K_ANI_FIRSTEP_LEVEL,
-                                        aniState->firstepLevel - 1) == true)
-                                       return;
-                       }
-               } else {
-                       if (aniState->firstepLevel > 0) {
-                               if (ath9k_hw_ani_control(ah,
-                                        ATH9K_ANI_FIRSTEP_LEVEL,
-                                        aniState->firstepLevel - 1) == true)
-                                       return;
-                       }
-               }
-       }
-
-       if (aniState->spurImmunityLevel > 0) {
-               if (ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL,
-                                        aniState->spurImmunityLevel - 1))
-                       return;
-       }
-
-       if (aniState->noiseImmunityLevel > 0) {
-               ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
-                                    aniState->noiseImmunityLevel - 1);
-               return;
-       }
-}
-
-static int32_t ath9k_hw_ani_get_listen_time(struct ath_hw *ah)
-{
-       struct ar5416AniState *aniState;
-       u32 txFrameCount, rxFrameCount, cycleCount;
-       int32_t listenTime;
-
-       txFrameCount = REG_READ(ah, AR_TFCNT);
-       rxFrameCount = REG_READ(ah, AR_RFCNT);
-       cycleCount = REG_READ(ah, AR_CCCNT);
-
-       aniState = ah->curani;
-       if (aniState->cycleCount == 0 || aniState->cycleCount > cycleCount) {
-
-               listenTime = 0;
-               ah->stats.ast_ani_lzero++;
-       } else {
-               int32_t ccdelta = cycleCount - aniState->cycleCount;
-               int32_t rfdelta = rxFrameCount - aniState->rxFrameCount;
-               int32_t tfdelta = txFrameCount - aniState->txFrameCount;
-               listenTime = (ccdelta - rfdelta - tfdelta) / 44000;
-       }
-       aniState->cycleCount = cycleCount;
-       aniState->txFrameCount = txFrameCount;
-       aniState->rxFrameCount = rxFrameCount;
-
-       return listenTime;
-}
-
-void ath9k_ani_reset(struct ath_hw *ah)
-{
-       struct ar5416AniState *aniState;
-       struct ath9k_channel *chan = ah->curchan;
-       int index;
-
-       if (!DO_ANI(ah))
-               return;
-
-       index = ath9k_hw_get_ani_channel_idx(ah, chan);
-       aniState = &ah->ani[index];
-       ah->curani = aniState;
-
-       if (DO_ANI(ah) && ah->opmode != NL80211_IFTYPE_STATION
-           && ah->opmode != NL80211_IFTYPE_ADHOC) {
-               DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-                       "Reset ANI state opmode %u\n", ah->opmode);
-               ah->stats.ast_ani_reset++;
-
-               ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL, 0);
-               ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL, 0);
-               ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, 0);
-               ath9k_hw_ani_control(ah, ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
-                                    !ATH9K_ANI_USE_OFDM_WEAK_SIG);
-               ath9k_hw_ani_control(ah, ATH9K_ANI_CCK_WEAK_SIGNAL_THR,
-                                    ATH9K_ANI_CCK_WEAK_SIG_THR);
-
-               ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) |
-                                    ATH9K_RX_FILTER_PHYERR);
-
-               if (ah->opmode == NL80211_IFTYPE_AP) {
-                       ah->curani->ofdmTrigHigh =
-                               ah->config.ofdm_trig_high;
-                       ah->curani->ofdmTrigLow =
-                               ah->config.ofdm_trig_low;
-                       ah->curani->cckTrigHigh =
-                               ah->config.cck_trig_high;
-                       ah->curani->cckTrigLow =
-                               ah->config.cck_trig_low;
-               }
-               ath9k_ani_restart(ah);
-               return;
-       }
-
-       if (aniState->noiseImmunityLevel != 0)
-               ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
-                                    aniState->noiseImmunityLevel);
-       if (aniState->spurImmunityLevel != 0)
-               ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL,
-                                    aniState->spurImmunityLevel);
-       if (aniState->ofdmWeakSigDetectOff)
-               ath9k_hw_ani_control(ah, ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
-                                    !aniState->ofdmWeakSigDetectOff);
-       if (aniState->cckWeakSigThreshold)
-               ath9k_hw_ani_control(ah, ATH9K_ANI_CCK_WEAK_SIGNAL_THR,
-                                    aniState->cckWeakSigThreshold);
-       if (aniState->firstepLevel != 0)
-               ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
-                                    aniState->firstepLevel);
-       if (ah->has_hw_phycounters) {
-               ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) &
-                                    ~ATH9K_RX_FILTER_PHYERR);
-               ath9k_ani_restart(ah);
-               REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
-               REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
-
-       } else {
-               ath9k_ani_restart(ah);
-               ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) |
-                                    ATH9K_RX_FILTER_PHYERR);
-       }
-}
-
-void ath9k_hw_ani_monitor(struct ath_hw *ah,
-                         const struct ath9k_node_stats *stats,
-                         struct ath9k_channel *chan)
-{
-       struct ar5416AniState *aniState;
-       int32_t listenTime;
-
-       if (!DO_ANI(ah))
-               return;
-
-       aniState = ah->curani;
-       ah->stats.ast_nodestats = *stats;
-
-       listenTime = ath9k_hw_ani_get_listen_time(ah);
-       if (listenTime < 0) {
-               ah->stats.ast_ani_lneg++;
-               ath9k_ani_restart(ah);
-               return;
-       }
-
-       aniState->listenTime += listenTime;
-
-       if (ah->has_hw_phycounters) {
-               u32 phyCnt1, phyCnt2;
-               u32 ofdmPhyErrCnt, cckPhyErrCnt;
-
-               ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
-
-               phyCnt1 = REG_READ(ah, AR_PHY_ERR_1);
-               phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
-
-               if (phyCnt1 < aniState->ofdmPhyErrBase ||
-                   phyCnt2 < aniState->cckPhyErrBase) {
-                       if (phyCnt1 < aniState->ofdmPhyErrBase) {
-                               DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-                                       "phyCnt1 0x%x, resetting "
-                                       "counter value to 0x%x\n",
-                                       phyCnt1,
-                                       aniState->ofdmPhyErrBase);
-                               REG_WRITE(ah, AR_PHY_ERR_1,
-                                         aniState->ofdmPhyErrBase);
-                               REG_WRITE(ah, AR_PHY_ERR_MASK_1,
-                                         AR_PHY_ERR_OFDM_TIMING);
-                       }
-                       if (phyCnt2 < aniState->cckPhyErrBase) {
-                               DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-                                       "phyCnt2 0x%x, resetting "
-                                       "counter value to 0x%x\n",
-                                       phyCnt2,
-                                       aniState->cckPhyErrBase);
-                               REG_WRITE(ah, AR_PHY_ERR_2,
-                                         aniState->cckPhyErrBase);
-                               REG_WRITE(ah, AR_PHY_ERR_MASK_2,
-                                         AR_PHY_ERR_CCK_TIMING);
-                       }
-                       return;
-               }
-
-               ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase;
-               ah->stats.ast_ani_ofdmerrs +=
-                       ofdmPhyErrCnt - aniState->ofdmPhyErrCount;
-               aniState->ofdmPhyErrCount = ofdmPhyErrCnt;
-
-               cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase;
-               ah->stats.ast_ani_cckerrs +=
-                       cckPhyErrCnt - aniState->cckPhyErrCount;
-               aniState->cckPhyErrCount = cckPhyErrCnt;
-       }
-
-       if (aniState->listenTime > 5 * ah->aniperiod) {
-               if (aniState->ofdmPhyErrCount <= aniState->listenTime *
-                   aniState->ofdmTrigLow / 1000 &&
-                   aniState->cckPhyErrCount <= aniState->listenTime *
-                   aniState->cckTrigLow / 1000)
-                       ath9k_hw_ani_lower_immunity(ah);
-               ath9k_ani_restart(ah);
-       } else if (aniState->listenTime > ah->aniperiod) {
-               if (aniState->ofdmPhyErrCount > aniState->listenTime *
-                   aniState->ofdmTrigHigh / 1000) {
-                       ath9k_hw_ani_ofdm_err_trigger(ah);
-                       ath9k_ani_restart(ah);
-               } else if (aniState->cckPhyErrCount >
-                          aniState->listenTime * aniState->cckTrigHigh /
-                          1000) {
-                       ath9k_hw_ani_cck_err_trigger(ah);
-                       ath9k_ani_restart(ah);
-               }
-       }
-}
-
-bool ath9k_hw_phycounters(struct ath_hw *ah)
-{
-       return ah->has_hw_phycounters ? true : false;
-}
-
-void ath9k_enable_mib_counters(struct ath_hw *ah)
-{
-       DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Enable MIB counters\n");
-
-       ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
-
-       REG_WRITE(ah, AR_FILT_OFDM, 0);
-       REG_WRITE(ah, AR_FILT_CCK, 0);
-       REG_WRITE(ah, AR_MIBC,
-                 ~(AR_MIBC_COW | AR_MIBC_FMC | AR_MIBC_CMC | AR_MIBC_MCS)
-                 & 0x0f);
-       REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
-       REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
-}
-
-/* Freeze the MIB counters, get the stats and then clear them */
-void ath9k_hw_disable_mib_counters(struct ath_hw *ah)
-{
-       DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Disable MIB counters\n");
-       REG_WRITE(ah, AR_MIBC, AR_MIBC_FMC);
-       ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
-       REG_WRITE(ah, AR_MIBC, AR_MIBC_CMC);
-       REG_WRITE(ah, AR_FILT_OFDM, 0);
-       REG_WRITE(ah, AR_FILT_CCK, 0);
-}
-
-u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hw *ah,
-                                 u32 *rxc_pcnt,
-                                 u32 *rxf_pcnt,
-                                 u32 *txf_pcnt)
-{
-       static u32 cycles, rx_clear, rx_frame, tx_frame;
-       u32 good = 1;
-
-       u32 rc = REG_READ(ah, AR_RCCNT);
-       u32 rf = REG_READ(ah, AR_RFCNT);
-       u32 tf = REG_READ(ah, AR_TFCNT);
-       u32 cc = REG_READ(ah, AR_CCCNT);
-
-       if (cycles == 0 || cycles > cc) {
-               DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
-                       "cycle counter wrap. ExtBusy = 0\n");
-               good = 0;
-       } else {
-               u32 cc_d = cc - cycles;
-               u32 rc_d = rc - rx_clear;
-               u32 rf_d = rf - rx_frame;
-               u32 tf_d = tf - tx_frame;
-
-               if (cc_d != 0) {
-                       *rxc_pcnt = rc_d * 100 / cc_d;
-                       *rxf_pcnt = rf_d * 100 / cc_d;
-                       *txf_pcnt = tf_d * 100 / cc_d;
-               } else {
-                       good = 0;
-               }
-       }
-
-       cycles = cc;
-       rx_frame = rf;
-       rx_clear = rc;
-       tx_frame = tf;
-
-       return good;
-}
-
-/*
- * Process a MIB interrupt.  We may potentially be invoked because
- * any of the MIB counters overflow/trigger so don't assume we're
- * here because a PHY error counter triggered.
- */
-void ath9k_hw_procmibevent(struct ath_hw *ah,
-                          const struct ath9k_node_stats *stats)
-{
-       u32 phyCnt1, phyCnt2;
-
-       /* Reset these counters regardless */
-       REG_WRITE(ah, AR_FILT_OFDM, 0);
-       REG_WRITE(ah, AR_FILT_CCK, 0);
-       if (!(REG_READ(ah, AR_SLP_MIB_CTRL) & AR_SLP_MIB_PENDING))
-               REG_WRITE(ah, AR_SLP_MIB_CTRL, AR_SLP_MIB_CLEAR);
-
-       /* Clear the mib counters and save them in the stats */
-       ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
-       ah->stats.ast_nodestats = *stats;
-
-       if (!DO_ANI(ah))
-               return;
-
-       /* NB: these are not reset-on-read */
-       phyCnt1 = REG_READ(ah, AR_PHY_ERR_1);
-       phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
-       if (((phyCnt1 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK) ||
-           ((phyCnt2 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK)) {
-               struct ar5416AniState *aniState = ah->curani;
-               u32 ofdmPhyErrCnt, cckPhyErrCnt;
-
-               /* NB: only use ast_ani_*errs with AH_PRIVATE_DIAG */
-               ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase;
-               ah->stats.ast_ani_ofdmerrs +=
-                       ofdmPhyErrCnt - aniState->ofdmPhyErrCount;
-               aniState->ofdmPhyErrCount = ofdmPhyErrCnt;
-
-               cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase;
-               ah->stats.ast_ani_cckerrs +=
-                       cckPhyErrCnt - aniState->cckPhyErrCount;
-               aniState->cckPhyErrCount = cckPhyErrCnt;
-
-               /*
-                * NB: figure out which counter triggered.  If both
-                * trigger we'll only deal with one as the processing
-                * clobbers the error counter so the trigger threshold
-                * check will never be true.
-                */
-               if (aniState->ofdmPhyErrCount > aniState->ofdmTrigHigh)
-                       ath9k_hw_ani_ofdm_err_trigger(ah);
-               if (aniState->cckPhyErrCount > aniState->cckTrigHigh)
-                       ath9k_hw_ani_cck_err_trigger(ah);
-               /* NB: always restart to insure the h/w counters are reset */
-               ath9k_ani_restart(ah);
-       }
-}
-
-void ath9k_hw_ani_setup(struct ath_hw *ah)
-{
-       int i;
-
-       const int totalSizeDesired[] = { -55, -55, -55, -55, -62 };
-       const int coarseHigh[] = { -14, -14, -14, -14, -12 };
-       const int coarseLow[] = { -64, -64, -64, -64, -70 };
-       const int firpwr[] = { -78, -78, -78, -78, -80 };
-
-       for (i = 0; i < 5; i++) {
-               ah->totalSizeDesired[i] = totalSizeDesired[i];
-               ah->coarse_high[i] = coarseHigh[i];
-               ah->coarse_low[i] = coarseLow[i];
-               ah->firpwr[i] = firpwr[i];
-       }
-}
-
-void ath9k_hw_ani_attach(struct ath_hw *ah)
-{
-       int i;
-
-       DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Attach ANI\n");
-
-       ah->has_hw_phycounters = 1;
-
-       memset(ah->ani, 0, sizeof(ah->ani));
-       for (i = 0; i < ARRAY_SIZE(ah->ani); i++) {
-               ah->ani[i].ofdmTrigHigh = ATH9K_ANI_OFDM_TRIG_HIGH;
-               ah->ani[i].ofdmTrigLow = ATH9K_ANI_OFDM_TRIG_LOW;
-               ah->ani[i].cckTrigHigh = ATH9K_ANI_CCK_TRIG_HIGH;
-               ah->ani[i].cckTrigLow = ATH9K_ANI_CCK_TRIG_LOW;
-               ah->ani[i].rssiThrHigh = ATH9K_ANI_RSSI_THR_HIGH;
-               ah->ani[i].rssiThrLow = ATH9K_ANI_RSSI_THR_LOW;
-               ah->ani[i].ofdmWeakSigDetectOff =
-                       !ATH9K_ANI_USE_OFDM_WEAK_SIG;
-               ah->ani[i].cckWeakSigThreshold =
-                       ATH9K_ANI_CCK_WEAK_SIG_THR;
-               ah->ani[i].spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL;
-               ah->ani[i].firstepLevel = ATH9K_ANI_FIRSTEP_LVL;
-               if (ah->has_hw_phycounters) {
-                       ah->ani[i].ofdmPhyErrBase =
-                               AR_PHY_COUNTMAX - ATH9K_ANI_OFDM_TRIG_HIGH;
-                       ah->ani[i].cckPhyErrBase =
-                               AR_PHY_COUNTMAX - ATH9K_ANI_CCK_TRIG_HIGH;
-               }
-       }
-       if (ah->has_hw_phycounters) {
-               DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-                       "Setting OfdmErrBase = 0x%08x\n",
-                       ah->ani[0].ofdmPhyErrBase);
-               DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Setting cckErrBase = 0x%08x\n",
-                       ah->ani[0].cckPhyErrBase);
-
-               REG_WRITE(ah, AR_PHY_ERR_1, ah->ani[0].ofdmPhyErrBase);
-               REG_WRITE(ah, AR_PHY_ERR_2, ah->ani[0].cckPhyErrBase);
-               ath9k_enable_mib_counters(ah);
-       }
-       ah->aniperiod = ATH9K_ANI_PERIOD;
-       if (ah->config.enable_ani)
-               ah->proc_phyerr |= HAL_PROCESS_ANI;
-}
-
-void ath9k_hw_ani_detach(struct ath_hw *ah)
-{
-       DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Detach ANI\n");
-
-       if (ah->has_hw_phycounters) {
-               ath9k_hw_disable_mib_counters(ah);
-               REG_WRITE(ah, AR_PHY_ERR_1, 0);
-               REG_WRITE(ah, AR_PHY_ERR_2, 0);
-       }
-}
diff --git a/drivers/net/wireless/ath9k/ani.h b/drivers/net/wireless/ath9k/ani.h
deleted file mode 100644 (file)
index 08b4e7e..0000000
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (c) 2008-2009 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 ANI_H
-#define ANI_H
-
-#define HAL_PROCESS_ANI           0x00000001
-#define ATH9K_RSSI_EP_MULTIPLIER  (1<<7)
-
-#define DO_ANI(ah) (((ah)->proc_phyerr & HAL_PROCESS_ANI))
-
-#define HAL_EP_RND(x, mul)                                             \
-       ((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul))
-#define BEACON_RSSI(ahp)                                       \
-       HAL_EP_RND(ahp->stats.ast_nodestats.ns_avgbrssi,        \
-                  ATH9K_RSSI_EP_MULTIPLIER)
-
-#define ATH9K_ANI_OFDM_TRIG_HIGH          500
-#define ATH9K_ANI_OFDM_TRIG_LOW           200
-#define ATH9K_ANI_CCK_TRIG_HIGH           200
-#define ATH9K_ANI_CCK_TRIG_LOW            100
-#define ATH9K_ANI_NOISE_IMMUNE_LVL        4
-#define ATH9K_ANI_USE_OFDM_WEAK_SIG       true
-#define ATH9K_ANI_CCK_WEAK_SIG_THR        false
-#define ATH9K_ANI_SPUR_IMMUNE_LVL         7
-#define ATH9K_ANI_FIRSTEP_LVL             0
-#define ATH9K_ANI_RSSI_THR_HIGH           40
-#define ATH9K_ANI_RSSI_THR_LOW            7
-#define ATH9K_ANI_PERIOD                  100
-
-#define HAL_NOISE_IMMUNE_MAX              4
-#define HAL_SPUR_IMMUNE_MAX               7
-#define HAL_FIRST_STEP_MAX                2
-
-enum ath9k_ani_cmd {
-       ATH9K_ANI_PRESENT = 0x1,
-       ATH9K_ANI_NOISE_IMMUNITY_LEVEL = 0x2,
-       ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION = 0x4,
-       ATH9K_ANI_CCK_WEAK_SIGNAL_THR = 0x8,
-       ATH9K_ANI_FIRSTEP_LEVEL = 0x10,
-       ATH9K_ANI_SPUR_IMMUNITY_LEVEL = 0x20,
-       ATH9K_ANI_MODE = 0x40,
-       ATH9K_ANI_PHYERR_RESET = 0x80,
-       ATH9K_ANI_ALL = 0xff
-};
-
-struct ath9k_mib_stats {
-       u32 ackrcv_bad;
-       u32 rts_bad;
-       u32 rts_good;
-       u32 fcs_bad;
-       u32 beacons;
-};
-
-struct ath9k_node_stats {
-       u32 ns_avgbrssi;
-       u32 ns_avgrssi;
-       u32 ns_avgtxrssi;
-       u32 ns_avgtxrate;
-};
-
-struct ar5416AniState {
-       struct ath9k_channel *c;
-       u8 noiseImmunityLevel;
-       u8 spurImmunityLevel;
-       u8 firstepLevel;
-       u8 ofdmWeakSigDetectOff;
-       u8 cckWeakSigThreshold;
-       u32 listenTime;
-       u32 ofdmTrigHigh;
-       u32 ofdmTrigLow;
-       int32_t cckTrigHigh;
-       int32_t cckTrigLow;
-       int32_t rssiThrLow;
-       int32_t rssiThrHigh;
-       u32 noiseFloor;
-       u32 txFrameCount;
-       u32 rxFrameCount;
-       u32 cycleCount;
-       u32 ofdmPhyErrCount;
-       u32 cckPhyErrCount;
-       u32 ofdmPhyErrBase;
-       u32 cckPhyErrBase;
-       int16_t pktRssi[2];
-       int16_t ofdmErrRssi[2];
-       int16_t cckErrRssi[2];
-};
-
-struct ar5416Stats {
-       u32 ast_ani_niup;
-       u32 ast_ani_nidown;
-       u32 ast_ani_spurup;
-       u32 ast_ani_spurdown;
-       u32 ast_ani_ofdmon;
-       u32 ast_ani_ofdmoff;
-       u32 ast_ani_cckhigh;
-       u32 ast_ani_ccklow;
-       u32 ast_ani_stepup;
-       u32 ast_ani_stepdown;
-       u32 ast_ani_ofdmerrs;
-       u32 ast_ani_cckerrs;
-       u32 ast_ani_reset;
-       u32 ast_ani_lzero;
-       u32 ast_ani_lneg;
-       struct ath9k_mib_stats ast_mibstats;
-       struct ath9k_node_stats ast_nodestats;
-};
-#define ah_mibStats stats.ast_mibstats
-
-void ath9k_ani_reset(struct ath_hw *ah);
-void ath9k_hw_ani_monitor(struct ath_hw *ah,
-                         const struct ath9k_node_stats *stats,
-                         struct ath9k_channel *chan);
-bool ath9k_hw_phycounters(struct ath_hw *ah);
-void ath9k_enable_mib_counters(struct ath_hw *ah);
-void ath9k_hw_disable_mib_counters(struct ath_hw *ah);
-u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hw *ah, u32 *rxc_pcnt,
-                                 u32 *rxf_pcnt, u32 *txf_pcnt);
-void ath9k_hw_procmibevent(struct ath_hw *ah,
-                          const struct ath9k_node_stats *stats);
-void ath9k_hw_ani_setup(struct ath_hw *ah);
-void ath9k_hw_ani_attach(struct ath_hw *ah);
-void ath9k_hw_ani_detach(struct ath_hw *ah);
-
-#endif /* ANI_H */
diff --git a/drivers/net/wireless/ath9k/ath9k.h b/drivers/net/wireless/ath9k/ath9k.h
deleted file mode 100644 (file)
index 2689a08..0000000
+++ /dev/null
@@ -1,757 +0,0 @@
-/*
- * Copyright (c) 2008-2009 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 ATH9K_H
-#define ATH9K_H
-
-#include <linux/etherdevice.h>
-#include <linux/device.h>
-#include <net/mac80211.h>
-#include <linux/leds.h>
-#include <linux/rfkill.h>
-
-#include "hw.h"
-#include "rc.h"
-#include "debug.h"
-
-struct ath_node;
-
-/* Macro to expand scalars to 64-bit objects */
-
-#define        ito64(x) (sizeof(x) == 8) ?                     \
-       (((unsigned long long int)(x)) & (0xff)) :      \
-       (sizeof(x) == 16) ?                             \
-       (((unsigned long long int)(x)) & 0xffff) :      \
-       ((sizeof(x) == 32) ?                            \
-        (((unsigned long long int)(x)) & 0xffffffff) : \
-        (unsigned long long int)(x))
-
-/* increment with wrap-around */
-#define INCR(_l, _sz)   do {                   \
-               (_l)++;                         \
-               (_l) &= ((_sz) - 1);            \
-       } while (0)
-
-/* decrement with wrap-around */
-#define DECR(_l,  _sz)  do {                   \
-               (_l)--;                         \
-               (_l) &= ((_sz) - 1);            \
-       } while (0)
-
-#define A_MAX(a, b) ((a) > (b) ? (a) : (b))
-
-#define ASSERT(exp) do {                       \
-               if (unlikely(!(exp))) {         \
-                       BUG();                  \
-               }                               \
-       } while (0)
-
-#define TSF_TO_TU(_h,_l) \
-       ((((u32)(_h)) << 22) | (((u32)(_l)) >> 10))
-
-#define        ATH_TXQ_SETUP(sc, i)        ((sc)->tx.txqsetup & (1<<i))
-
-static const u8 ath_bcast_mac[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
-
-struct ath_config {
-       u32 ath_aggr_prot;
-       u16 txpowlimit;
-       u8 cabqReadytime;
-       u8 swBeaconProcess;
-};
-
-/*************************/
-/* Descriptor Management */
-/*************************/
-
-#define ATH_TXBUF_RESET(_bf) do {                              \
-               (_bf)->bf_status = 0;                           \
-               (_bf)->bf_lastbf = NULL;                        \
-               (_bf)->bf_next = NULL;                          \
-               memset(&((_bf)->bf_state), 0,                   \
-                      sizeof(struct ath_buf_state));           \
-       } while (0)
-
-/**
- * enum buffer_type - Buffer type flags
- *
- * @BUF_HT: Send this buffer using HT capabilities
- * @BUF_AMPDU: This buffer is an ampdu, as part of an aggregate (during TX)
- * @BUF_AGGR: Indicates whether the buffer can be aggregated
- *     (used in aggregation scheduling)
- * @BUF_RETRY: Indicates whether the buffer is retried
- * @BUF_XRETRY: To denote excessive retries of the buffer
- */
-enum buffer_type {
-       BUF_HT                  = BIT(1),
-       BUF_AMPDU               = BIT(2),
-       BUF_AGGR                = BIT(3),
-       BUF_RETRY               = BIT(4),
-       BUF_XRETRY              = BIT(5),
-};
-
-struct ath_buf_state {
-       int bfs_nframes;
-       u16 bfs_al;
-       u16 bfs_frmlen;
-       int bfs_seqno;
-       int bfs_tidno;
-       int bfs_retries;
-       u32 bf_type;
-       u32 bfs_keyix;
-       enum ath9k_key_type bfs_keytype;
-};
-
-#define bf_nframes             bf_state.bfs_nframes
-#define bf_al                  bf_state.bfs_al
-#define bf_frmlen              bf_state.bfs_frmlen
-#define bf_retries             bf_state.bfs_retries
-#define bf_seqno               bf_state.bfs_seqno
-#define bf_tidno               bf_state.bfs_tidno
-#define bf_keyix                bf_state.bfs_keyix
-#define bf_keytype             bf_state.bfs_keytype
-#define bf_isht(bf)            (bf->bf_state.bf_type & BUF_HT)
-#define bf_isampdu(bf)         (bf->bf_state.bf_type & BUF_AMPDU)
-#define bf_isaggr(bf)          (bf->bf_state.bf_type & BUF_AGGR)
-#define bf_isretried(bf)       (bf->bf_state.bf_type & BUF_RETRY)
-#define bf_isxretried(bf)      (bf->bf_state.bf_type & BUF_XRETRY)
-
-struct ath_buf {
-       struct list_head list;
-       struct ath_buf *bf_lastbf;      /* last buf of this unit (a frame or
-                                          an aggregate) */
-       struct ath_buf *bf_next;        /* next subframe in the aggregate */
-       void *bf_mpdu;                  /* enclosing frame structure */
-       struct ath_desc *bf_desc;       /* virtual addr of desc */
-       dma_addr_t bf_daddr;            /* physical addr of desc */
-       dma_addr_t bf_buf_addr;         /* physical addr of data buffer */
-       u32 bf_status;
-       u16 bf_flags;
-       struct ath_buf_state bf_state;
-       dma_addr_t bf_dmacontext;
-};
-
-#define ATH_RXBUF_RESET(_bf)    ((_bf)->bf_status = 0)
-#define ATH_BUFSTATUS_STALE     0x00000002
-
-struct ath_descdma {
-       const char *dd_name;
-       struct ath_desc *dd_desc;
-       dma_addr_t dd_desc_paddr;
-       u32 dd_desc_len;
-       struct ath_buf *dd_bufptr;
-       dma_addr_t dd_dmacontext;
-};
-
-int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
-                     struct list_head *head, const char *name,
-                     int nbuf, int ndesc);
-void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd,
-                        struct list_head *head);
-
-/***********/
-/* RX / TX */
-/***********/
-
-#define ATH_MAX_ANTENNA         3
-#define ATH_RXBUF               512
-#define WME_NUM_TID             16
-#define ATH_TXBUF               512
-#define ATH_TXMAXTRY            13
-#define ATH_11N_TXMAXTRY        10
-#define ATH_MGT_TXMAXTRY        4
-#define WME_BA_BMP_SIZE         64
-#define WME_MAX_BA              WME_BA_BMP_SIZE
-#define ATH_TID_MAX_BUFS        (2 * WME_MAX_BA)
-
-#define TID_TO_WME_AC(_tid)                            \
-       ((((_tid) == 0) || ((_tid) == 3)) ? WME_AC_BE : \
-        (((_tid) == 1) || ((_tid) == 2)) ? WME_AC_BK : \
-        (((_tid) == 4) || ((_tid) == 5)) ? WME_AC_VI : \
-        WME_AC_VO)
-
-#define WME_AC_BE   0
-#define WME_AC_BK   1
-#define WME_AC_VI   2
-#define WME_AC_VO   3
-#define WME_NUM_AC  4
-
-#define ADDBA_EXCHANGE_ATTEMPTS    10
-#define ATH_AGGR_DELIM_SZ          4
-#define ATH_AGGR_MINPLEN           256 /* in bytes, minimum packet length */
-/* number of delimiters for encryption padding */
-#define ATH_AGGR_ENCRYPTDELIM      10
-/* minimum h/w qdepth to be sustained to maximize aggregation */
-#define ATH_AGGR_MIN_QDEPTH        2
-#define ATH_AMPDU_SUBFRAME_DEFAULT 32
-#define ATH_AMPDU_LIMIT_MAX        (64 * 1024 - 1)
-#define ATH_AMPDU_LIMIT_DEFAULT    ATH_AMPDU_LIMIT_MAX
-
-#define IEEE80211_SEQ_SEQ_SHIFT    4
-#define IEEE80211_SEQ_MAX          4096
-#define IEEE80211_MIN_AMPDU_BUF    0x8
-#define IEEE80211_HTCAP_MAXRXAMPDU_FACTOR 13
-#define IEEE80211_WEP_IVLEN        3
-#define IEEE80211_WEP_KIDLEN       1
-#define IEEE80211_WEP_CRCLEN       4
-#define IEEE80211_MAX_MPDU_LEN     (3840 + FCS_LEN +           \
-                                   (IEEE80211_WEP_IVLEN +      \
-                                    IEEE80211_WEP_KIDLEN +     \
-                                    IEEE80211_WEP_CRCLEN))
-
-/* return whether a bit at index _n in bitmap _bm is set
- * _sz is the size of the bitmap  */
-#define ATH_BA_ISSET(_bm, _n)  (((_n) < (WME_BA_BMP_SIZE)) &&          \
-                               ((_bm)[(_n) >> 5] & (1 << ((_n) & 31))))
-
-/* return block-ack bitmap index given sequence and starting sequence */
-#define ATH_BA_INDEX(_st, _seq) (((_seq) - (_st)) & (IEEE80211_SEQ_MAX - 1))
-
-/* returns delimiter padding required given the packet length */
-#define ATH_AGGR_GET_NDELIM(_len)                                      \
-       (((((_len) + ATH_AGGR_DELIM_SZ) < ATH_AGGR_MINPLEN) ?           \
-         (ATH_AGGR_MINPLEN - (_len) - ATH_AGGR_DELIM_SZ) : 0) >> 2)
-
-#define BAW_WITHIN(_start, _bawsz, _seqno) \
-       ((((_seqno) - (_start)) & 4095) < (_bawsz))
-
-#define ATH_DS_BA_SEQ(_ds)         ((_ds)->ds_us.tx.ts_seqnum)
-#define ATH_DS_BA_BITMAP(_ds)      (&(_ds)->ds_us.tx.ba_low)
-#define ATH_DS_TX_BA(_ds)          ((_ds)->ds_us.tx.ts_flags & ATH9K_TX_BA)
-#define ATH_AN_2_TID(_an, _tidno)  (&(_an)->tid[(_tidno)])
-
-enum ATH_AGGR_STATUS {
-       ATH_AGGR_DONE,
-       ATH_AGGR_BAW_CLOSED,
-       ATH_AGGR_LIMITED,
-};
-
-struct ath_txq {
-       u32 axq_qnum;
-       u32 *axq_link;
-       struct list_head axq_q;
-       spinlock_t axq_lock;
-       u32 axq_depth;
-       u8 axq_aggr_depth;
-       u32 axq_totalqueued;
-       bool stopped;
-       struct ath_buf *axq_linkbuf;
-
-       /* first desc of the last descriptor that contains CTS */
-       struct ath_desc *axq_lastdsWithCTS;
-
-       /* final desc of the gating desc that determines whether
-          lastdsWithCTS has been DMA'ed or not */
-       struct ath_desc *axq_gatingds;
-
-       struct list_head axq_acq;
-};
-
-#define AGGR_CLEANUP         BIT(1)
-#define AGGR_ADDBA_COMPLETE  BIT(2)
-#define AGGR_ADDBA_PROGRESS  BIT(3)
-
-struct ath_atx_tid {
-       struct list_head list;
-       struct list_head buf_q;
-       struct ath_node *an;
-       struct ath_atx_ac *ac;
-       struct ath_buf *tx_buf[ATH_TID_MAX_BUFS];
-       u16 seq_start;
-       u16 seq_next;
-       u16 baw_size;
-       int tidno;
-       int baw_head;   /* first un-acked tx buffer */
-       int baw_tail;   /* next unused tx buffer slot */
-       int sched;
-       int paused;
-       u8 state;
-       int addba_exchangeattempts;
-};
-
-struct ath_atx_ac {
-       int sched;
-       int qnum;
-       struct list_head list;
-       struct list_head tid_q;
-};
-
-struct ath_tx_control {
-       struct ath_txq *txq;
-       int if_id;
-       enum ath9k_internal_frame_type frame_type;
-};
-
-#define ATH_TX_ERROR        0x01
-#define ATH_TX_XRETRY       0x02
-#define ATH_TX_BAR          0x04
-
-/* All RSSI values are noise floor adjusted */
-struct ath_tx_stat {
-       int rssi;
-       int rssictl[ATH_MAX_ANTENNA];
-       int rssiextn[ATH_MAX_ANTENNA];
-       int rateieee;
-       int rateKbps;
-       int ratecode;
-       int flags;
-       u32 airtime;    /* time on air per final tx rate */
-};
-
-struct aggr_rifs_param {
-       int param_max_frames;
-       int param_max_len;
-       int param_rl;
-       int param_al;
-       struct ath_rc_series *param_rcs;
-};
-
-struct ath_node {
-       struct ath_softc *an_sc;
-       struct ath_atx_tid tid[WME_NUM_TID];
-       struct ath_atx_ac ac[WME_NUM_AC];
-       u16 maxampdu;
-       u8 mpdudensity;
-};
-
-struct ath_tx {
-       u16 seq_no;
-       u32 txqsetup;
-       int hwq_map[ATH9K_WME_AC_VO+1];
-       spinlock_t txbuflock;
-       struct list_head txbuf;
-       struct ath_txq txq[ATH9K_NUM_TX_QUEUES];
-       struct ath_descdma txdma;
-};
-
-struct ath_rx {
-       u8 defant;
-       u8 rxotherant;
-       u32 *rxlink;
-       int bufsize;
-       unsigned int rxfilter;
-       spinlock_t rxflushlock;
-       spinlock_t rxbuflock;
-       struct list_head rxbuf;
-       struct ath_descdma rxdma;
-};
-
-int ath_startrecv(struct ath_softc *sc);
-bool ath_stoprecv(struct ath_softc *sc);
-void ath_flushrecv(struct ath_softc *sc);
-u32 ath_calcrxfilter(struct ath_softc *sc);
-int ath_rx_init(struct ath_softc *sc, int nbufs);
-void ath_rx_cleanup(struct ath_softc *sc);
-int ath_rx_tasklet(struct ath_softc *sc, int flush);
-struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype);
-void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq);
-int ath_tx_setup(struct ath_softc *sc, int haltype);
-void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx);
-void ath_draintxq(struct ath_softc *sc,
-                    struct ath_txq *txq, bool retry_tx);
-void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an);
-void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an);
-void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq);
-int ath_tx_init(struct ath_softc *sc, int nbufs);
-int ath_tx_cleanup(struct ath_softc *sc);
-struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb);
-int ath_txq_update(struct ath_softc *sc, int qnum,
-                  struct ath9k_tx_queue_info *q);
-int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
-                struct ath_tx_control *txctl);
-void ath_tx_tasklet(struct ath_softc *sc);
-void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb);
-bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, u8 tidno);
-int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
-                     u16 tid, u16 *ssn);
-int ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid);
-void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid);
-
-/********/
-/* VIFs */
-/********/
-
-struct ath_vif {
-       int av_bslot;
-       __le64 tsf_adjust; /* TSF adjustment for staggered beacons */
-       enum nl80211_iftype av_opmode;
-       struct ath_buf *av_bcbuf;
-       struct ath_tx_control av_btxctl;
-       u8 bssid[ETH_ALEN]; /* current BSSID from config_interface */
-};
-
-/*******************/
-/* Beacon Handling */
-/*******************/
-
-/*
- * Regardless of the number of beacons we stagger, (i.e. regardless of the
- * number of BSSIDs) if a given beacon does not go out even after waiting this
- * number of beacon intervals, the game's up.
- */
-#define BSTUCK_THRESH                  (9 * ATH_BCBUF)
-#define        ATH_BCBUF                       4
-#define ATH_DEFAULT_BINTVAL            100 /* TU */
-#define ATH_DEFAULT_BMISS_LIMIT        10
-#define IEEE80211_MS_TO_TU(x)           (((x) * 1000) / 1024)
-
-struct ath_beacon_config {
-       u16 beacon_interval;
-       u16 listen_interval;
-       u16 dtim_period;
-       u16 bmiss_timeout;
-       u8 dtim_count;
-};
-
-struct ath_beacon {
-       enum {
-               OK,             /* no change needed */
-               UPDATE,         /* update pending */
-               COMMIT          /* beacon sent, commit change */
-       } updateslot;           /* slot time update fsm */
-
-       u32 beaconq;
-       u32 bmisscnt;
-       u32 ast_be_xmit;
-       u64 bc_tstamp;
-       struct ieee80211_vif *bslot[ATH_BCBUF];
-       struct ath_wiphy *bslot_aphy[ATH_BCBUF];
-       int slottime;
-       int slotupdate;
-       struct ath9k_tx_queue_info beacon_qi;
-       struct ath_descdma bdma;
-       struct ath_txq *cabq;
-       struct list_head bbuf;
-};
-
-void ath_beacon_tasklet(unsigned long data);
-void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif);
-int ath_beaconq_setup(struct ath_hw *ah);
-int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif);
-void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp);
-
-/*******/
-/* ANI */
-/*******/
-
-#define ATH_STA_SHORT_CALINTERVAL 1000    /* 1 second */
-#define ATH_AP_SHORT_CALINTERVAL  100     /* 100 ms */
-#define ATH_ANI_POLLINTERVAL      100     /* 100 ms */
-#define ATH_LONG_CALINTERVAL      30000   /* 30 seconds */
-#define ATH_RESTART_CALINTERVAL   1200000 /* 20 minutes */
-
-struct ath_ani {
-       bool caldone;
-       int16_t noise_floor;
-       unsigned int longcal_timer;
-       unsigned int shortcal_timer;
-       unsigned int resetcal_timer;
-       unsigned int checkani_timer;
-       struct timer_list timer;
-};
-
-/********************/
-/*   LED Control    */
-/********************/
-
-#define ATH_LED_PIN    1
-#define ATH_LED_ON_DURATION_IDLE       350     /* in msecs */
-#define ATH_LED_OFF_DURATION_IDLE      250     /* in msecs */
-
-enum ath_led_type {
-       ATH_LED_RADIO,
-       ATH_LED_ASSOC,
-       ATH_LED_TX,
-       ATH_LED_RX
-};
-
-struct ath_led {
-       struct ath_softc *sc;
-       struct led_classdev led_cdev;
-       enum ath_led_type led_type;
-       char name[32];
-       bool registered;
-};
-
-/* Rfkill */
-#define ATH_RFKILL_POLL_INTERVAL       2000 /* msecs */
-
-struct ath_rfkill {
-       struct rfkill *rfkill;
-       struct delayed_work rfkill_poll;
-       char rfkill_name[32];
-};
-
-/********************/
-/* Main driver core */
-/********************/
-
-/*
- * Default cache line size, in bytes.
- * Used when PCI device not fully initialized by bootrom/BIOS
-*/
-#define DEFAULT_CACHELINE       32
-#define        ATH_DEFAULT_NOISE_FLOOR -95
-#define ATH_REGCLASSIDS_MAX     10
-#define ATH_CABQ_READY_TIME     80      /* % of beacon interval */
-#define ATH_MAX_SW_RETRIES      10
-#define ATH_CHAN_MAX            255
-#define IEEE80211_WEP_NKID      4       /* number of key ids */
-
-/*
- * The key cache is used for h/w cipher state and also for
- * tracking station state such as the current tx antenna.
- * We also setup a mapping table between key cache slot indices
- * and station state to short-circuit node lookups on rx.
- * Different parts have different size key caches.  We handle
- * up to ATH_KEYMAX entries (could dynamically allocate state).
- */
-#define        ATH_KEYMAX              128     /* max key cache size we handle */
-
-#define ATH_TXPOWER_MAX         100     /* .5 dBm units */
-#define ATH_RSSI_DUMMY_MARKER   0x127
-#define ATH_RATE_DUMMY_MARKER   0
-
-#define SC_OP_INVALID           BIT(0)
-#define SC_OP_BEACONS           BIT(1)
-#define SC_OP_RXAGGR            BIT(2)
-#define SC_OP_TXAGGR            BIT(3)
-#define SC_OP_CHAINMASK_UPDATE  BIT(4)
-#define SC_OP_FULL_RESET        BIT(5)
-#define SC_OP_PREAMBLE_SHORT    BIT(6)
-#define SC_OP_PROTECT_ENABLE    BIT(7)
-#define SC_OP_RXFLUSH           BIT(8)
-#define SC_OP_LED_ASSOCIATED    BIT(9)
-#define SC_OP_RFKILL_REGISTERED BIT(10)
-#define SC_OP_RFKILL_SW_BLOCKED BIT(11)
-#define SC_OP_RFKILL_HW_BLOCKED BIT(12)
-#define SC_OP_WAIT_FOR_BEACON   BIT(13)
-#define SC_OP_LED_ON            BIT(14)
-#define SC_OP_SCANNING          BIT(15)
-#define SC_OP_TSF_RESET         BIT(16)
-
-struct ath_bus_ops {
-       void            (*read_cachesize)(struct ath_softc *sc, int *csz);
-       void            (*cleanup)(struct ath_softc *sc);
-       bool            (*eeprom_read)(struct ath_hw *ah, u32 off, u16 *data);
-};
-
-struct ath_wiphy;
-
-struct ath_softc {
-       struct ieee80211_hw *hw;
-       struct device *dev;
-
-       spinlock_t wiphy_lock; /* spinlock to protect ath_wiphy data */
-       struct ath_wiphy *pri_wiphy;
-       struct ath_wiphy **sec_wiphy; /* secondary wiphys (virtual radios); may
-                                      * have NULL entries */
-       int num_sec_wiphy; /* number of sec_wiphy pointers in the array */
-       int chan_idx;
-       int chan_is_ht;
-       struct ath_wiphy *next_wiphy;
-       struct work_struct chan_work;
-       int wiphy_select_failures;
-       unsigned long wiphy_select_first_fail;
-       struct delayed_work wiphy_work;
-       unsigned long wiphy_scheduler_int;
-       int wiphy_scheduler_index;
-
-       struct tasklet_struct intr_tq;
-       struct tasklet_struct bcon_tasklet;
-       struct ath_hw *sc_ah;
-       void __iomem *mem;
-       int irq;
-       spinlock_t sc_resetlock;
-       spinlock_t sc_serial_rw;
-       struct mutex mutex;
-
-       u8 curbssid[ETH_ALEN];
-       u8 bssidmask[ETH_ALEN];
-       u32 intrstatus;
-       u32 sc_flags; /* SC_OP_* */
-       u16 curtxpow;
-       u16 curaid;
-       u16 cachelsz;
-       u8 nbcnvifs;
-       u16 nvifs;
-       u8 tx_chainmask;
-       u8 rx_chainmask;
-       u32 keymax;
-       DECLARE_BITMAP(keymap, ATH_KEYMAX);
-       u8 splitmic;
-       atomic_t ps_usecount;
-       enum ath9k_int imask;
-       enum ath9k_ht_extprotspacing ht_extprotspacing;
-       enum ath9k_ht_macmode tx_chan_width;
-
-       struct ath_config config;
-       struct ath_rx rx;
-       struct ath_tx tx;
-       struct ath_beacon beacon;
-       struct ieee80211_rate rates[IEEE80211_NUM_BANDS][ATH_RATE_MAX];
-       struct ath_rate_table *hw_rate_table[ATH9K_MODE_MAX];
-       struct ath_rate_table *cur_rate_table;
-       struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
-
-       struct ath_led radio_led;
-       struct ath_led assoc_led;
-       struct ath_led tx_led;
-       struct ath_led rx_led;
-       struct delayed_work ath_led_blink_work;
-       int led_on_duration;
-       int led_off_duration;
-       int led_on_cnt;
-       int led_off_cnt;
-
-       struct ath_rfkill rf_kill;
-       struct ath_ani ani;
-       struct ath9k_node_stats nodestats;
-#ifdef CONFIG_ATH9K_DEBUG
-       struct ath9k_debug debug;
-#endif
-       struct ath_bus_ops *bus_ops;
-};
-
-struct ath_wiphy {
-       struct ath_softc *sc; /* shared for all virtual wiphys */
-       struct ieee80211_hw *hw;
-       enum ath_wiphy_state {
-               ATH_WIPHY_INACTIVE,
-               ATH_WIPHY_ACTIVE,
-               ATH_WIPHY_PAUSING,
-               ATH_WIPHY_PAUSED,
-               ATH_WIPHY_SCAN,
-       } state;
-       int chan_idx;
-       int chan_is_ht;
-};
-
-int ath_reset(struct ath_softc *sc, bool retry_tx);
-int ath_get_hal_qnum(u16 queue, struct ath_softc *sc);
-int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc);
-int ath_cabq_update(struct ath_softc *);
-
-static inline void ath_read_cachesize(struct ath_softc *sc, int *csz)
-{
-       sc->bus_ops->read_cachesize(sc, csz);
-}
-
-static inline void ath_bus_cleanup(struct ath_softc *sc)
-{
-       sc->bus_ops->cleanup(sc);
-}
-
-extern struct ieee80211_ops ath9k_ops;
-
-irqreturn_t ath_isr(int irq, void *dev);
-void ath_cleanup(struct ath_softc *sc);
-int ath_attach(u16 devid, struct ath_softc *sc);
-void ath_detach(struct ath_softc *sc);
-const char *ath_mac_bb_name(u32 mac_bb_version);
-const char *ath_rf_name(u16 rf_version);
-void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw);
-void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw,
-                          struct ath9k_channel *ichan);
-void ath_update_chainmask(struct ath_softc *sc, int is_ht);
-int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
-                   struct ath9k_channel *hchan);
-void ath_radio_enable(struct ath_softc *sc);
-void ath_radio_disable(struct ath_softc *sc);
-
-#ifdef CONFIG_PCI
-int ath_pci_init(void);
-void ath_pci_exit(void);
-#else
-static inline int ath_pci_init(void) { return 0; };
-static inline void ath_pci_exit(void) {};
-#endif
-
-#ifdef CONFIG_ATHEROS_AR71XX
-int ath_ahb_init(void);
-void ath_ahb_exit(void);
-#else
-static inline int ath_ahb_init(void) { return 0; };
-static inline void ath_ahb_exit(void) {};
-#endif
-
-static inline void ath9k_ps_wakeup(struct ath_softc *sc)
-{
-       if (atomic_inc_return(&sc->ps_usecount) == 1)
-               if (sc->sc_ah->power_mode !=  ATH9K_PM_AWAKE) {
-                       sc->sc_ah->restore_mode = sc->sc_ah->power_mode;
-                       ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE);
-               }
-}
-
-static inline void ath9k_ps_restore(struct ath_softc *sc)
-{
-       if (atomic_dec_and_test(&sc->ps_usecount))
-               if ((sc->hw->conf.flags & IEEE80211_CONF_PS) &&
-                   !(sc->sc_flags & SC_OP_WAIT_FOR_BEACON))
-                       ath9k_hw_setpower(sc->sc_ah,
-                                         sc->sc_ah->restore_mode);
-}
-
-
-void ath9k_set_bssid_mask(struct ieee80211_hw *hw);
-int ath9k_wiphy_add(struct ath_softc *sc);
-int ath9k_wiphy_del(struct ath_wiphy *aphy);
-void ath9k_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb);
-int ath9k_wiphy_pause(struct ath_wiphy *aphy);
-int ath9k_wiphy_unpause(struct ath_wiphy *aphy);
-int ath9k_wiphy_select(struct ath_wiphy *aphy);
-void ath9k_wiphy_set_scheduler(struct ath_softc *sc, unsigned int msec_int);
-void ath9k_wiphy_chan_work(struct work_struct *work);
-bool ath9k_wiphy_started(struct ath_softc *sc);
-void ath9k_wiphy_pause_all_forced(struct ath_softc *sc,
-                                 struct ath_wiphy *selected);
-bool ath9k_wiphy_scanning(struct ath_softc *sc);
-void ath9k_wiphy_work(struct work_struct *work);
-
-/*
- * Read and write, they both share the same lock. We do this to serialize
- * reads and writes on Atheros 802.11n PCI devices only. This is required
- * as the FIFO on these devices can only accept sanely 2 requests. After
- * that the device goes bananas. Serializing the reads/writes prevents this
- * from happening.
- */
-
-static inline void ath9k_iowrite32(struct ath_hw *ah, u32 reg_offset, u32 val)
-{
-       if (ah->config.serialize_regmode == SER_REG_MODE_ON) {
-               unsigned long flags;
-               spin_lock_irqsave(&ah->ah_sc->sc_serial_rw, flags);
-               iowrite32(val, ah->ah_sc->mem + reg_offset);
-               spin_unlock_irqrestore(&ah->ah_sc->sc_serial_rw, flags);
-       } else
-               iowrite32(val, ah->ah_sc->mem + reg_offset);
-}
-
-static inline unsigned int ath9k_ioread32(struct ath_hw *ah, u32 reg_offset)
-{
-       u32 val;
-       if (ah->config.serialize_regmode == SER_REG_MODE_ON) {
-               unsigned long flags;
-               spin_lock_irqsave(&ah->ah_sc->sc_serial_rw, flags);
-               val = ioread32(ah->ah_sc->mem + reg_offset);
-               spin_unlock_irqrestore(&ah->ah_sc->sc_serial_rw, flags);
-       } else
-               val = ioread32(ah->ah_sc->mem + reg_offset);
-       return val;
-}
-
-#endif /* ATH9K_H */
diff --git a/drivers/net/wireless/ath9k/beacon.c b/drivers/net/wireless/ath9k/beacon.c
deleted file mode 100644 (file)
index ec99573..0000000
+++ /dev/null
@@ -1,746 +0,0 @@
-/*
- * Copyright (c) 2008-2009 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 "ath9k.h"
-
-#define FUDGE 2
-
-/*
- *  This function will modify certain transmit queue properties depending on
- *  the operating mode of the station (AP or AdHoc).  Parameters are AIFS
- *  settings and channel width min/max
-*/
-static int ath_beaconq_config(struct ath_softc *sc)
-{
-       struct ath_hw *ah = sc->sc_ah;
-       struct ath9k_tx_queue_info qi;
-
-       ath9k_hw_get_txq_props(ah, sc->beacon.beaconq, &qi);
-       if (sc->sc_ah->opmode == NL80211_IFTYPE_AP) {
-               /* Always burst out beacon and CAB traffic. */
-               qi.tqi_aifs = 1;
-               qi.tqi_cwmin = 0;
-               qi.tqi_cwmax = 0;
-       } else {
-               /* Adhoc mode; important thing is to use 2x cwmin. */
-               qi.tqi_aifs = sc->beacon.beacon_qi.tqi_aifs;
-               qi.tqi_cwmin = 2*sc->beacon.beacon_qi.tqi_cwmin;
-               qi.tqi_cwmax = sc->beacon.beacon_qi.tqi_cwmax;
-       }
-
-       if (!ath9k_hw_set_txq_props(ah, sc->beacon.beaconq, &qi)) {
-               DPRINTF(sc, ATH_DBG_FATAL,
-                       "unable to update h/w beacon queue parameters\n");
-               return 0;
-       } else {
-               ath9k_hw_resettxqueue(ah, sc->beacon.beaconq);
-               return 1;
-       }
-}
-
-/*
- *  Associates the beacon frame buffer with a transmit descriptor.  Will set
- *  up all required antenna switch parameters, rate codes, and channel flags.
- *  Beacons are always sent out at the lowest rate, and are not retried.
-*/
-static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp,
-                            struct ath_buf *bf)
-{
-       struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu;
-       struct ath_hw *ah = sc->sc_ah;
-       struct ath_desc *ds;
-       struct ath9k_11n_rate_series series[4];
-       struct ath_rate_table *rt;
-       int flags, antenna, ctsrate = 0, ctsduration = 0;
-       u8 rate;
-
-       ds = bf->bf_desc;
-       flags = ATH9K_TXDESC_NOACK;
-
-       if (((sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) ||
-            (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) &&
-           (ah->caps.hw_caps & ATH9K_HW_CAP_VEOL)) {
-               ds->ds_link = bf->bf_daddr; /* self-linked */
-               flags |= ATH9K_TXDESC_VEOL;
-               /* Let hardware handle antenna switching. */
-               antenna = 0;
-       } else {
-               ds->ds_link = 0;
-               /*
-                * Switch antenna every beacon.
-                * Should only switch every beacon period, not for every SWBA
-                * XXX assumes two antennae
-                */
-               antenna = ((sc->beacon.ast_be_xmit / sc->nbcnvifs) & 1 ? 2 : 1);
-       }
-
-       ds->ds_data = bf->bf_buf_addr;
-
-       rt = sc->cur_rate_table;
-       rate = rt->info[0].ratecode;
-       if (sc->sc_flags & SC_OP_PREAMBLE_SHORT)
-               rate |= rt->info[0].short_preamble;
-
-       ath9k_hw_set11n_txdesc(ah, ds, skb->len + FCS_LEN,
-                              ATH9K_PKT_TYPE_BEACON,
-                              MAX_RATE_POWER,
-                              ATH9K_TXKEYIX_INVALID,
-                              ATH9K_KEY_TYPE_CLEAR,
-                              flags);
-
-       /* NB: beacon's BufLen must be a multiple of 4 bytes */
-       ath9k_hw_filltxdesc(ah, ds, roundup(skb->len, 4),
-                           true, true, ds);
-
-       memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4);
-       series[0].Tries = 1;
-       series[0].Rate = rate;
-       series[0].ChSel = sc->tx_chainmask;
-       series[0].RateFlags = (ctsrate) ? ATH9K_RATESERIES_RTS_CTS : 0;
-       ath9k_hw_set11n_ratescenario(ah, ds, ds, 0, ctsrate, ctsduration,
-                                    series, 4, 0);
-}
-
-static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw,
-                                          struct ieee80211_vif *vif)
-{
-       struct ath_wiphy *aphy = hw->priv;
-       struct ath_softc *sc = aphy->sc;
-       struct ath_buf *bf;
-       struct ath_vif *avp;
-       struct sk_buff *skb;
-       struct ath_txq *cabq;
-       struct ieee80211_tx_info *info;
-       int cabq_depth;
-
-       if (aphy->state != ATH_WIPHY_ACTIVE)
-               return NULL;
-
-       avp = (void *)vif->drv_priv;
-       cabq = sc->beacon.cabq;
-
-       if (avp->av_bcbuf == NULL) {
-               DPRINTF(sc, ATH_DBG_BEACON, "avp=%p av_bcbuf=%p\n",
-                       avp, avp->av_bcbuf);
-               return NULL;
-       }
-
-       /* Release the old beacon first */
-
-       bf = avp->av_bcbuf;
-       skb = (struct sk_buff *)bf->bf_mpdu;
-       if (skb) {
-               dma_unmap_single(sc->dev, bf->bf_dmacontext,
-                                skb->len, DMA_TO_DEVICE);
-               dev_kfree_skb_any(skb);
-       }
-
-       /* Get a new beacon from mac80211 */
-
-       skb = ieee80211_beacon_get(hw, vif);
-       bf->bf_mpdu = skb;
-       if (skb == NULL)
-               return NULL;
-       ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp =
-               avp->tsf_adjust;
-
-       info = IEEE80211_SKB_CB(skb);
-       if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
-               /*
-                * TODO: make sure the seq# gets assigned properly (vs. other
-                * TX frames)
-                */
-               struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-               sc->tx.seq_no += 0x10;
-               hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
-               hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no);
-       }
-
-       bf->bf_buf_addr = bf->bf_dmacontext =
-               dma_map_single(sc->dev, skb->data,
-                              skb->len, DMA_TO_DEVICE);
-       if (unlikely(dma_mapping_error(sc->dev, bf->bf_buf_addr))) {
-               dev_kfree_skb_any(skb);
-               bf->bf_mpdu = NULL;
-               DPRINTF(sc, ATH_DBG_FATAL, "dma_mapping_error on beaconing\n");
-               return NULL;
-       }
-
-       skb = ieee80211_get_buffered_bc(hw, vif);
-
-       /*
-        * if the CABQ traffic from previous DTIM is pending and the current
-        *  beacon is also a DTIM.
-        *  1) if there is only one vif let the cab traffic continue.
-        *  2) if there are more than one vif and we are using staggered
-        *     beacons, then drain the cabq by dropping all the frames in
-        *     the cabq so that the current vifs cab traffic can be scheduled.
-        */
-       spin_lock_bh(&cabq->axq_lock);
-       cabq_depth = cabq->axq_depth;
-       spin_unlock_bh(&cabq->axq_lock);
-
-       if (skb && cabq_depth) {
-               if (sc->nvifs > 1) {
-                       DPRINTF(sc, ATH_DBG_BEACON,
-                               "Flushing previous cabq traffic\n");
-                       ath_draintxq(sc, cabq, false);
-               }
-       }
-
-       ath_beacon_setup(sc, avp, bf);
-
-       while (skb) {
-               ath_tx_cabq(hw, skb);
-               skb = ieee80211_get_buffered_bc(hw, vif);
-       }
-
-       return bf;
-}
-
-/*
- * Startup beacon transmission for adhoc mode when they are sent entirely
- * by the hardware using the self-linked descriptor + veol trick.
-*/
-static void ath_beacon_start_adhoc(struct ath_softc *sc,
-                                  struct ieee80211_vif *vif)
-{
-       struct ath_hw *ah = sc->sc_ah;
-       struct ath_buf *bf;
-       struct ath_vif *avp;
-       struct sk_buff *skb;
-
-       avp = (void *)vif->drv_priv;
-
-       if (avp->av_bcbuf == NULL)
-               return;
-
-       bf = avp->av_bcbuf;
-       skb = (struct sk_buff *) bf->bf_mpdu;
-
-       ath_beacon_setup(sc, avp, bf);
-
-       /* NB: caller is known to have already stopped tx dma */
-       ath9k_hw_puttxbuf(ah, sc->beacon.beaconq, bf->bf_daddr);
-       ath9k_hw_txstart(ah, sc->beacon.beaconq);
-       DPRINTF(sc, ATH_DBG_BEACON, "TXDP%u = %llx (%p)\n",
-               sc->beacon.beaconq, ito64(bf->bf_daddr), bf->bf_desc);
-}
-
-int ath_beaconq_setup(struct ath_hw *ah)
-{
-       struct ath9k_tx_queue_info qi;
-
-       memset(&qi, 0, sizeof(qi));
-       qi.tqi_aifs = 1;
-       qi.tqi_cwmin = 0;
-       qi.tqi_cwmax = 0;
-       /* NB: don't enable any interrupts */
-       return ath9k_hw_setuptxqueue(ah, ATH9K_TX_QUEUE_BEACON, &qi);
-}
-
-int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif)
-{
-       struct ath_softc *sc = aphy->sc;
-       struct ath_vif *avp;
-       struct ath_buf *bf;
-       struct sk_buff *skb;
-       __le64 tstamp;
-
-       avp = (void *)vif->drv_priv;
-
-       /* Allocate a beacon descriptor if we haven't done so. */
-       if (!avp->av_bcbuf) {
-               /* Allocate beacon state for hostap/ibss.  We know
-                * a buffer is available. */
-               avp->av_bcbuf = list_first_entry(&sc->beacon.bbuf,
-                                                struct ath_buf, list);
-               list_del(&avp->av_bcbuf->list);
-
-               if (sc->sc_ah->opmode == NL80211_IFTYPE_AP ||
-                   !(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_VEOL)) {
-                       int slot;
-                       /*
-                        * Assign the vif to a beacon xmit slot. As
-                        * above, this cannot fail to find one.
-                        */
-                       avp->av_bslot = 0;
-                       for (slot = 0; slot < ATH_BCBUF; slot++)
-                               if (sc->beacon.bslot[slot] == NULL) {
-                                       /*
-                                        * XXX hack, space out slots to better
-                                        * deal with misses
-                                        */
-                                       if (slot+1 < ATH_BCBUF &&
-                                           sc->beacon.bslot[slot+1] == NULL) {
-                                               avp->av_bslot = slot+1;
-                                               break;
-                                       }
-                                       avp->av_bslot = slot;
-                                       /* NB: keep looking for a double slot */
-                               }
-                       BUG_ON(sc->beacon.bslot[avp->av_bslot] != NULL);
-                       sc->beacon.bslot[avp->av_bslot] = vif;
-                       sc->beacon.bslot_aphy[avp->av_bslot] = aphy;
-                       sc->nbcnvifs++;
-               }
-       }
-
-       /* release the previous beacon frame, if it already exists. */
-       bf = avp->av_bcbuf;
-       if (bf->bf_mpdu != NULL) {
-               skb = (struct sk_buff *)bf->bf_mpdu;
-               dma_unmap_single(sc->dev, bf->bf_dmacontext,
-                                skb->len, DMA_TO_DEVICE);
-               dev_kfree_skb_any(skb);
-               bf->bf_mpdu = NULL;
-       }
-
-       /* NB: the beacon data buffer must be 32-bit aligned. */
-       skb = ieee80211_beacon_get(sc->hw, vif);
-       if (skb == NULL) {
-               DPRINTF(sc, ATH_DBG_BEACON, "cannot get skb\n");
-               return -ENOMEM;
-       }
-
-       tstamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp;
-       sc->beacon.bc_tstamp = le64_to_cpu(tstamp);
-       /* Calculate a TSF adjustment factor required for staggered beacons. */
-       if (avp->av_bslot > 0) {
-               u64 tsfadjust;
-               int intval;
-
-               intval = sc->hw->conf.beacon_int ?
-                       sc->hw->conf.beacon_int : ATH_DEFAULT_BINTVAL;
-
-               /*
-                * Calculate the TSF offset for this beacon slot, i.e., the
-                * number of usecs that need to be added to the timestamp field
-                * in Beacon and Probe Response frames. Beacon slot 0 is
-                * processed at the correct offset, so it does not require TSF
-                * adjustment. Other slots are adjusted to get the timestamp
-                * close to the TBTT for the BSS.
-                */
-               tsfadjust = intval * avp->av_bslot / ATH_BCBUF;
-               avp->tsf_adjust = cpu_to_le64(TU_TO_USEC(tsfadjust));
-
-               DPRINTF(sc, ATH_DBG_BEACON,
-                       "stagger beacons, bslot %d intval %u tsfadjust %llu\n",
-                       avp->av_bslot, intval, (unsigned long long)tsfadjust);
-
-               ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp =
-                       avp->tsf_adjust;
-       } else
-               avp->tsf_adjust = cpu_to_le64(0);
-
-       bf->bf_mpdu = skb;
-       bf->bf_buf_addr = bf->bf_dmacontext =
-               dma_map_single(sc->dev, skb->data,
-                              skb->len, DMA_TO_DEVICE);
-       if (unlikely(dma_mapping_error(sc->dev, bf->bf_buf_addr))) {
-               dev_kfree_skb_any(skb);
-               bf->bf_mpdu = NULL;
-               DPRINTF(sc, ATH_DBG_FATAL,
-                       "dma_mapping_error on beacon alloc\n");
-               return -ENOMEM;
-       }
-
-       return 0;
-}
-
-void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp)
-{
-       if (avp->av_bcbuf != NULL) {
-               struct ath_buf *bf;
-
-               if (avp->av_bslot != -1) {
-                       sc->beacon.bslot[avp->av_bslot] = NULL;
-                       sc->beacon.bslot_aphy[avp->av_bslot] = NULL;
-                       sc->nbcnvifs--;
-               }
-
-               bf = avp->av_bcbuf;
-               if (bf->bf_mpdu != NULL) {
-                       struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu;
-                       dma_unmap_single(sc->dev, bf->bf_dmacontext,
-                                        skb->len, DMA_TO_DEVICE);
-                       dev_kfree_skb_any(skb);
-                       bf->bf_mpdu = NULL;
-               }
-               list_add_tail(&bf->list, &sc->beacon.bbuf);
-
-               avp->av_bcbuf = NULL;
-       }
-}
-
-void ath_beacon_tasklet(unsigned long data)
-{
-       struct ath_softc *sc = (struct ath_softc *)data;
-       struct ath_hw *ah = sc->sc_ah;
-       struct ath_buf *bf = NULL;
-       struct ieee80211_vif *vif;
-       struct ath_wiphy *aphy;
-       int slot;
-       u32 bfaddr, bc = 0, tsftu;
-       u64 tsf;
-       u16 intval;
-
-       /*
-        * Check if the previous beacon has gone out.  If
-        * not don't try to post another, skip this period
-        * and wait for the next.  Missed beacons indicate
-        * a problem and should not occur.  If we miss too
-        * many consecutive beacons reset the device.
-        */
-       if (ath9k_hw_numtxpending(ah, sc->beacon.beaconq) != 0) {
-               sc->beacon.bmisscnt++;
-
-               if (sc->beacon.bmisscnt < BSTUCK_THRESH) {
-                       DPRINTF(sc, ATH_DBG_BEACON,
-                               "missed %u consecutive beacons\n",
-                               sc->beacon.bmisscnt);
-               } else if (sc->beacon.bmisscnt >= BSTUCK_THRESH) {
-                       DPRINTF(sc, ATH_DBG_BEACON,
-                               "beacon is officially stuck\n");
-                       ath_reset(sc, false);
-               }
-
-               return;
-       }
-
-       if (sc->beacon.bmisscnt != 0) {
-               DPRINTF(sc, ATH_DBG_BEACON,
-                       "resume beacon xmit after %u misses\n",
-                       sc->beacon.bmisscnt);
-               sc->beacon.bmisscnt = 0;
-       }
-
-       /*
-        * Generate beacon frames. we are sending frames
-        * staggered so calculate the slot for this frame based
-        * on the tsf to safeguard against missing an swba.
-        */
-
-       intval = sc->hw->conf.beacon_int ?
-               sc->hw->conf.beacon_int : ATH_DEFAULT_BINTVAL;
-
-       tsf = ath9k_hw_gettsf64(ah);
-       tsftu = TSF_TO_TU(tsf>>32, tsf);
-       slot = ((tsftu % intval) * ATH_BCBUF) / intval;
-       /*
-        * Reverse the slot order to get slot 0 on the TBTT offset that does
-        * not require TSF adjustment and other slots adding
-        * slot/ATH_BCBUF * beacon_int to timestamp. For example, with
-        * ATH_BCBUF = 4, we process beacon slots as follows: 3 2 1 0 3 2 1 ..
-        * and slot 0 is at correct offset to TBTT.
-        */
-       slot = ATH_BCBUF - slot - 1;
-       vif = sc->beacon.bslot[slot];
-       aphy = sc->beacon.bslot_aphy[slot];
-
-       DPRINTF(sc, ATH_DBG_BEACON,
-               "slot %d [tsf %llu tsftu %u intval %u] vif %p\n",
-               slot, tsf, tsftu, intval, vif);
-
-       bfaddr = 0;
-       if (vif) {
-               bf = ath_beacon_generate(aphy->hw, vif);
-               if (bf != NULL) {
-                       bfaddr = bf->bf_daddr;
-                       bc = 1;
-               }
-       }
-
-       /*
-        * Handle slot time change when a non-ERP station joins/leaves
-        * an 11g network.  The 802.11 layer notifies us via callback,
-        * we mark updateslot, then wait one beacon before effecting
-        * the change.  This gives associated stations at least one
-        * beacon interval to note the state change.
-        *
-        * NB: The slot time change state machine is clocked according
-        *     to whether we are bursting or staggering beacons.  We
-        *     recognize the request to update and record the current
-        *     slot then don't transition until that slot is reached
-        *     again.  If we miss a beacon for that slot then we'll be
-        *     slow to transition but we'll be sure at least one beacon
-        *     interval has passed.  When bursting slot is always left
-        *     set to ATH_BCBUF so this check is a noop.
-        */
-       if (sc->beacon.updateslot == UPDATE) {
-               sc->beacon.updateslot = COMMIT; /* commit next beacon */
-               sc->beacon.slotupdate = slot;
-       } else if (sc->beacon.updateslot == COMMIT && sc->beacon.slotupdate == slot) {
-               ath9k_hw_setslottime(sc->sc_ah, sc->beacon.slottime);
-               sc->beacon.updateslot = OK;
-       }
-       if (bfaddr != 0) {
-               /*
-                * Stop any current dma and put the new frame(s) on the queue.
-                * This should never fail since we check above that no frames
-                * are still pending on the queue.
-                */
-               if (!ath9k_hw_stoptxdma(ah, sc->beacon.beaconq)) {
-                       DPRINTF(sc, ATH_DBG_FATAL,
-                               "beacon queue %u did not stop?\n", sc->beacon.beaconq);
-               }
-
-               /* NB: cabq traffic should already be queued and primed */
-               ath9k_hw_puttxbuf(ah, sc->beacon.beaconq, bfaddr);
-               ath9k_hw_txstart(ah, sc->beacon.beaconq);
-
-               sc->beacon.ast_be_xmit += bc;     /* XXX per-vif? */
-       }
-}
-
-/*
- * For multi-bss ap support beacons are either staggered evenly over N slots or
- * burst together.  For the former arrange for the SWBA to be delivered for each
- * slot. Slots that are not occupied will generate nothing.
- */
-static void ath_beacon_config_ap(struct ath_softc *sc,
-                                struct ath_beacon_config *conf,
-                                struct ath_vif *avp)
-{
-       u32 nexttbtt, intval;
-
-       /* Configure the timers only when the TSF has to be reset */
-
-       if (!(sc->sc_flags & SC_OP_TSF_RESET))
-               return;
-
-       /* NB: the beacon interval is kept internally in TU's */
-       intval = conf->beacon_interval & ATH9K_BEACON_PERIOD;
-       intval /= ATH_BCBUF;    /* for staggered beacons */
-       nexttbtt = intval;
-       intval |= ATH9K_BEACON_RESET_TSF;
-
-       /*
-        * In AP mode we enable the beacon timers and SWBA interrupts to
-        * prepare beacon frames.
-        */
-       intval |= ATH9K_BEACON_ENA;
-       sc->imask |= ATH9K_INT_SWBA;
-       ath_beaconq_config(sc);
-
-       /* Set the computed AP beacon timers */
-
-       ath9k_hw_set_interrupts(sc->sc_ah, 0);
-       ath9k_hw_beaconinit(sc->sc_ah, nexttbtt, intval);
-       sc->beacon.bmisscnt = 0;
-       ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
-
-       /* Clear the reset TSF flag, so that subsequent beacon updation
-          will not reset the HW TSF. */
-
-       sc->sc_flags &= ~SC_OP_TSF_RESET;
-}
-
-/*
- * This sets up the beacon timers according to the timestamp of the last
- * received beacon and the current TSF, configures PCF and DTIM
- * handling, programs the sleep registers so the hardware will wakeup in
- * time to receive beacons, and configures the beacon miss handling so
- * we'll receive a BMISS interrupt when we stop seeing beacons from the AP
- * we've associated with.
- */
-static void ath_beacon_config_sta(struct ath_softc *sc,
-                                 struct ath_beacon_config *conf,
-                                 struct ath_vif *avp)
-{
-       struct ath9k_beacon_state bs;
-       int dtimperiod, dtimcount, sleepduration;
-       int cfpperiod, cfpcount;
-       u32 nexttbtt = 0, intval, tsftu;
-       u64 tsf;
-
-       memset(&bs, 0, sizeof(bs));
-       intval = conf->beacon_interval & ATH9K_BEACON_PERIOD;
-
-       /*
-        * Setup dtim and cfp parameters according to
-        * last beacon we received (which may be none).
-        */
-       dtimperiod = conf->dtim_period;
-       if (dtimperiod <= 0)            /* NB: 0 if not known */
-               dtimperiod = 1;
-       dtimcount = conf->dtim_count;
-       if (dtimcount >= dtimperiod)    /* NB: sanity check */
-               dtimcount = 0;
-       cfpperiod = 1;                  /* NB: no PCF support yet */
-       cfpcount = 0;
-
-       sleepduration = conf->listen_interval * intval;
-       if (sleepduration <= 0)
-               sleepduration = intval;
-
-       /*
-        * Pull nexttbtt forward to reflect the current
-        * TSF and calculate dtim+cfp state for the result.
-        */
-       tsf = ath9k_hw_gettsf64(sc->sc_ah);
-       tsftu = TSF_TO_TU(tsf>>32, tsf) + FUDGE;
-       do {
-               nexttbtt += intval;
-               if (--dtimcount < 0) {
-                       dtimcount = dtimperiod - 1;
-                       if (--cfpcount < 0)
-                               cfpcount = cfpperiod - 1;
-               }
-       } while (nexttbtt < tsftu);
-
-       bs.bs_intval = intval;
-       bs.bs_nexttbtt = nexttbtt;
-       bs.bs_dtimperiod = dtimperiod*intval;
-       bs.bs_nextdtim = bs.bs_nexttbtt + dtimcount*intval;
-       bs.bs_cfpperiod = cfpperiod*bs.bs_dtimperiod;
-       bs.bs_cfpnext = bs.bs_nextdtim + cfpcount*bs.bs_dtimperiod;
-       bs.bs_cfpmaxduration = 0;
-
-       /*
-        * Calculate the number of consecutive beacons to miss* before taking
-        * a BMISS interrupt. The configuration is specified in TU so we only
-        * need calculate based on the beacon interval.  Note that we clamp the
-        * result to at most 15 beacons.
-        */
-       if (sleepduration > intval) {
-               bs.bs_bmissthreshold = conf->listen_interval *
-                       ATH_DEFAULT_BMISS_LIMIT / 2;
-       } else {
-               bs.bs_bmissthreshold = DIV_ROUND_UP(conf->bmiss_timeout, intval);
-               if (bs.bs_bmissthreshold > 15)
-                       bs.bs_bmissthreshold = 15;
-               else if (bs.bs_bmissthreshold <= 0)
-                       bs.bs_bmissthreshold = 1;
-       }
-
-       /*
-        * Calculate sleep duration. The configuration is given in ms.
-        * We ensure a multiple of the beacon period is used. Also, if the sleep
-        * duration is greater than the DTIM period then it makes senses
-        * to make it a multiple of that.
-        *
-        * XXX fixed at 100ms
-        */
-
-       bs.bs_sleepduration = roundup(IEEE80211_MS_TO_TU(100), sleepduration);
-       if (bs.bs_sleepduration > bs.bs_dtimperiod)
-               bs.bs_sleepduration = bs.bs_dtimperiod;
-
-       /* TSF out of range threshold fixed at 1 second */
-       bs.bs_tsfoor_threshold = ATH9K_TSFOOR_THRESHOLD;
-
-       DPRINTF(sc, ATH_DBG_BEACON, "tsf: %llu tsftu: %u\n", tsf, tsftu);
-       DPRINTF(sc, ATH_DBG_BEACON,
-               "bmiss: %u sleep: %u cfp-period: %u maxdur: %u next: %u\n",
-               bs.bs_bmissthreshold, bs.bs_sleepduration,
-               bs.bs_cfpperiod, bs.bs_cfpmaxduration, bs.bs_cfpnext);
-
-       /* Set the computed STA beacon timers */
-
-       ath9k_hw_set_interrupts(sc->sc_ah, 0);
-       ath9k_hw_set_sta_beacon_timers(sc->sc_ah, &bs);
-       sc->imask |= ATH9K_INT_BMISS;
-       ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
-}
-
-static void ath_beacon_config_adhoc(struct ath_softc *sc,
-                                   struct ath_beacon_config *conf,
-                                   struct ath_vif *avp,
-                                   struct ieee80211_vif *vif)
-{
-       u64 tsf;
-       u32 tsftu, intval, nexttbtt;
-
-       intval = conf->beacon_interval & ATH9K_BEACON_PERIOD;
-
-       /* Pull nexttbtt forward to reflect the current TSF */
-
-       nexttbtt = TSF_TO_TU(sc->beacon.bc_tstamp >> 32, sc->beacon.bc_tstamp);
-       if (nexttbtt == 0)
-                nexttbtt = intval;
-        else if (intval)
-                nexttbtt = roundup(nexttbtt, intval);
-
-       tsf = ath9k_hw_gettsf64(sc->sc_ah);
-       tsftu = TSF_TO_TU((u32)(tsf>>32), (u32)tsf) + FUDGE;
-       do {
-               nexttbtt += intval;
-       } while (nexttbtt < tsftu);
-
-       DPRINTF(sc, ATH_DBG_BEACON,
-               "IBSS nexttbtt %u intval %u (%u)\n",
-               nexttbtt, intval, conf->beacon_interval);
-
-       /*
-        * In IBSS mode enable the beacon timers but only enable SWBA interrupts
-        * if we need to manually prepare beacon frames.  Otherwise we use a
-        * self-linked tx descriptor and let the hardware deal with things.
-        */
-       intval |= ATH9K_BEACON_ENA;
-       if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_VEOL))
-               sc->imask |= ATH9K_INT_SWBA;
-
-       ath_beaconq_config(sc);
-
-       /* Set the computed ADHOC beacon timers */
-
-       ath9k_hw_set_interrupts(sc->sc_ah, 0);
-       ath9k_hw_beaconinit(sc->sc_ah, nexttbtt, intval);
-       sc->beacon.bmisscnt = 0;
-       ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
-
-       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_VEOL)
-               ath_beacon_start_adhoc(sc, vif);
-}
-
-void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif)
-{
-       struct ath_beacon_config conf;
-
-       /* Setup the beacon configuration parameters */
-
-       memset(&conf, 0, sizeof(struct ath_beacon_config));
-       conf.beacon_interval = sc->hw->conf.beacon_int ?
-               sc->hw->conf.beacon_int : ATH_DEFAULT_BINTVAL;
-       conf.listen_interval = 1;
-       conf.dtim_period = conf.beacon_interval;
-       conf.dtim_count = 1;
-       conf.bmiss_timeout = ATH_DEFAULT_BMISS_LIMIT * conf.beacon_interval;
-
-       if (vif) {
-               struct ath_vif *avp = (struct ath_vif *)vif->drv_priv;
-
-               switch(avp->av_opmode) {
-               case NL80211_IFTYPE_AP:
-                       ath_beacon_config_ap(sc, &conf, avp);
-                       break;
-               case NL80211_IFTYPE_ADHOC:
-               case NL80211_IFTYPE_MESH_POINT:
-                       ath_beacon_config_adhoc(sc, &conf, avp, vif);
-                       break;
-               case NL80211_IFTYPE_STATION:
-                       ath_beacon_config_sta(sc, &conf, avp);
-                       break;
-               default:
-                       DPRINTF(sc, ATH_DBG_CONFIG,
-                               "Unsupported beaconing mode\n");
-                       return;
-               }
-
-               sc->sc_flags |= SC_OP_BEACONS;
-       }
-}
diff --git a/drivers/net/wireless/ath9k/calib.c b/drivers/net/wireless/ath9k/calib.c
deleted file mode 100644 (file)
index e2d62e9..0000000
+++ /dev/null
@@ -1,1060 +0,0 @@
-/*
- * Copyright (c) 2008-2009 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 "ath9k.h"
-
-/* We can tune this as we go by monitoring really low values */
-#define ATH9K_NF_TOO_LOW       -60
-
-/* AR5416 may return very high value (like -31 dBm), in those cases the nf
- * is incorrect and we should use the static NF value. Later we can try to
- * find out why they are reporting these values */
-
-static bool ath9k_hw_nf_in_range(struct ath_hw *ah, s16 nf)
-{
-       if (nf > ATH9K_NF_TOO_LOW) {
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                       "noise floor value detected (%d) is "
-                       "lower than what we think is a "
-                       "reasonable value (%d)\n",
-                       nf, ATH9K_NF_TOO_LOW);
-               return false;
-       }
-       return true;
-}
-
-static int16_t ath9k_hw_get_nf_hist_mid(int16_t *nfCalBuffer)
-{
-       int16_t nfval;
-       int16_t sort[ATH9K_NF_CAL_HIST_MAX];
-       int i, j;
-
-       for (i = 0; i < ATH9K_NF_CAL_HIST_MAX; i++)
-               sort[i] = nfCalBuffer[i];
-
-       for (i = 0; i < ATH9K_NF_CAL_HIST_MAX - 1; i++) {
-               for (j = 1; j < ATH9K_NF_CAL_HIST_MAX - i; j++) {
-                       if (sort[j] > sort[j - 1]) {
-                               nfval = sort[j];
-                               sort[j] = sort[j - 1];
-                               sort[j - 1] = nfval;
-                       }
-               }
-       }
-       nfval = sort[(ATH9K_NF_CAL_HIST_MAX - 1) >> 1];
-
-       return nfval;
-}
-
-static void ath9k_hw_update_nfcal_hist_buffer(struct ath9k_nfcal_hist *h,
-                                             int16_t *nfarray)
-{
-       int i;
-
-       for (i = 0; i < NUM_NF_READINGS; i++) {
-               h[i].nfCalBuffer[h[i].currIndex] = nfarray[i];
-
-               if (++h[i].currIndex >= ATH9K_NF_CAL_HIST_MAX)
-                       h[i].currIndex = 0;
-
-               if (h[i].invalidNFcount > 0) {
-                       if (nfarray[i] < AR_PHY_CCA_MIN_BAD_VALUE ||
-                           nfarray[i] > AR_PHY_CCA_MAX_HIGH_VALUE) {
-                               h[i].invalidNFcount = ATH9K_NF_CAL_HIST_MAX;
-                       } else {
-                               h[i].invalidNFcount--;
-                               h[i].privNF = nfarray[i];
-                       }
-               } else {
-                       h[i].privNF =
-                               ath9k_hw_get_nf_hist_mid(h[i].nfCalBuffer);
-               }
-       }
-       return;
-}
-
-static void ath9k_hw_do_getnf(struct ath_hw *ah,
-                             int16_t nfarray[NUM_NF_READINGS])
-{
-       int16_t nf;
-
-       if (AR_SREV_9280_10_OR_LATER(ah))
-               nf = MS(REG_READ(ah, AR_PHY_CCA), AR9280_PHY_MINCCA_PWR);
-       else
-               nf = MS(REG_READ(ah, AR_PHY_CCA), AR_PHY_MINCCA_PWR);
-
-       if (nf & 0x100)
-               nf = 0 - ((nf ^ 0x1ff) + 1);
-       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-               "NF calibrated [ctl] [chain 0] is %d\n", nf);
-       nfarray[0] = nf;
-
-       if (!AR_SREV_9285(ah)) {
-               if (AR_SREV_9280_10_OR_LATER(ah))
-                       nf = MS(REG_READ(ah, AR_PHY_CH1_CCA),
-                                       AR9280_PHY_CH1_MINCCA_PWR);
-               else
-                       nf = MS(REG_READ(ah, AR_PHY_CH1_CCA),
-                                       AR_PHY_CH1_MINCCA_PWR);
-
-               if (nf & 0x100)
-                       nf = 0 - ((nf ^ 0x1ff) + 1);
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                               "NF calibrated [ctl] [chain 1] is %d\n", nf);
-               nfarray[1] = nf;
-
-               if (!AR_SREV_9280(ah)) {
-                       nf = MS(REG_READ(ah, AR_PHY_CH2_CCA),
-                                       AR_PHY_CH2_MINCCA_PWR);
-                       if (nf & 0x100)
-                               nf = 0 - ((nf ^ 0x1ff) + 1);
-                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                               "NF calibrated [ctl] [chain 2] is %d\n", nf);
-                       nfarray[2] = nf;
-               }
-       }
-
-       if (AR_SREV_9280_10_OR_LATER(ah))
-               nf = MS(REG_READ(ah, AR_PHY_EXT_CCA),
-                       AR9280_PHY_EXT_MINCCA_PWR);
-       else
-               nf = MS(REG_READ(ah, AR_PHY_EXT_CCA),
-                       AR_PHY_EXT_MINCCA_PWR);
-
-       if (nf & 0x100)
-               nf = 0 - ((nf ^ 0x1ff) + 1);
-       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-               "NF calibrated [ext] [chain 0] is %d\n", nf);
-       nfarray[3] = nf;
-
-       if (!AR_SREV_9285(ah)) {
-               if (AR_SREV_9280_10_OR_LATER(ah))
-                       nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA),
-                                       AR9280_PHY_CH1_EXT_MINCCA_PWR);
-               else
-                       nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA),
-                                       AR_PHY_CH1_EXT_MINCCA_PWR);
-
-               if (nf & 0x100)
-                       nf = 0 - ((nf ^ 0x1ff) + 1);
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                               "NF calibrated [ext] [chain 1] is %d\n", nf);
-               nfarray[4] = nf;
-
-               if (!AR_SREV_9280(ah)) {
-                       nf = MS(REG_READ(ah, AR_PHY_CH2_EXT_CCA),
-                                       AR_PHY_CH2_EXT_MINCCA_PWR);
-                       if (nf & 0x100)
-                               nf = 0 - ((nf ^ 0x1ff) + 1);
-                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                               "NF calibrated [ext] [chain 2] is %d\n", nf);
-                       nfarray[5] = nf;
-               }
-       }
-}
-
-static bool getNoiseFloorThresh(struct ath_hw *ah,
-                               enum ieee80211_band band,
-                               int16_t *nft)
-{
-       switch (band) {
-       case IEEE80211_BAND_5GHZ:
-               *nft = (int8_t)ah->eep_ops->get_eeprom(ah, EEP_NFTHRESH_5);
-               break;
-       case IEEE80211_BAND_2GHZ:
-               *nft = (int8_t)ah->eep_ops->get_eeprom(ah, EEP_NFTHRESH_2);
-               break;
-       default:
-               BUG_ON(1);
-               return false;
-       }
-
-       return true;
-}
-
-static void ath9k_hw_setup_calibration(struct ath_hw *ah,
-                                      struct hal_cal_list *currCal)
-{
-       REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(0),
-                     AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX,
-                     currCal->calData->calCountMax);
-
-       switch (currCal->calData->calType) {
-       case IQ_MISMATCH_CAL:
-               REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ);
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                       "starting IQ Mismatch Calibration\n");
-               break;
-       case ADC_GAIN_CAL:
-               REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_GAIN);
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                       "starting ADC Gain Calibration\n");
-               break;
-       case ADC_DC_CAL:
-               REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_PER);
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                       "starting ADC DC Calibration\n");
-               break;
-       case ADC_DC_INIT_CAL:
-               REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_INIT);
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                       "starting Init ADC DC Calibration\n");
-               break;
-       }
-
-       REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0),
-                   AR_PHY_TIMING_CTRL4_DO_CAL);
-}
-
-static void ath9k_hw_reset_calibration(struct ath_hw *ah,
-                                      struct hal_cal_list *currCal)
-{
-       int i;
-
-       ath9k_hw_setup_calibration(ah, currCal);
-
-       currCal->calState = CAL_RUNNING;
-
-       for (i = 0; i < AR5416_MAX_CHAINS; i++) {
-               ah->meas0.sign[i] = 0;
-               ah->meas1.sign[i] = 0;
-               ah->meas2.sign[i] = 0;
-               ah->meas3.sign[i] = 0;
-       }
-
-       ah->cal_samples = 0;
-}
-
-static void ath9k_hw_per_calibration(struct ath_hw *ah,
-                                    struct ath9k_channel *ichan,
-                                    u8 rxchainmask,
-                                    struct hal_cal_list *currCal,
-                                    bool *isCalDone)
-{
-       *isCalDone = false;
-
-       if (currCal->calState == CAL_RUNNING) {
-               if (!(REG_READ(ah, AR_PHY_TIMING_CTRL4(0)) &
-                     AR_PHY_TIMING_CTRL4_DO_CAL)) {
-
-                       currCal->calData->calCollect(ah);
-                       ah->cal_samples++;
-
-                       if (ah->cal_samples >= currCal->calData->calNumSamples) {
-                               int i, numChains = 0;
-                               for (i = 0; i < AR5416_MAX_CHAINS; i++) {
-                                       if (rxchainmask & (1 << i))
-                                               numChains++;
-                               }
-
-                               currCal->calData->calPostProc(ah, numChains);
-                               ichan->CalValid |= currCal->calData->calType;
-                               currCal->calState = CAL_DONE;
-                               *isCalDone = true;
-                       } else {
-                               ath9k_hw_setup_calibration(ah, currCal);
-                       }
-               }
-       } else if (!(ichan->CalValid & currCal->calData->calType)) {
-               ath9k_hw_reset_calibration(ah, currCal);
-       }
-}
-
-/* Assumes you are talking about the currently configured channel */
-static bool ath9k_hw_iscal_supported(struct ath_hw *ah,
-                                    enum hal_cal_types calType)
-{
-       struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
-
-       switch (calType & ah->supp_cals) {
-       case IQ_MISMATCH_CAL: /* Both 2 GHz and 5 GHz support OFDM */
-               return true;
-       case ADC_GAIN_CAL:
-       case ADC_DC_CAL:
-               if (conf->channel->band == IEEE80211_BAND_5GHZ &&
-                 conf_is_ht20(conf))
-                       return true;
-               break;
-       }
-       return false;
-}
-
-static void ath9k_hw_iqcal_collect(struct ath_hw *ah)
-{
-       int i;
-
-       for (i = 0; i < AR5416_MAX_CHAINS; i++) {
-               ah->totalPowerMeasI[i] +=
-                       REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
-               ah->totalPowerMeasQ[i] +=
-                       REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
-               ah->totalIqCorrMeas[i] +=
-                       (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                       "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n",
-                       ah->cal_samples, i, ah->totalPowerMeasI[i],
-                       ah->totalPowerMeasQ[i],
-                       ah->totalIqCorrMeas[i]);
-       }
-}
-
-static void ath9k_hw_adc_gaincal_collect(struct ath_hw *ah)
-{
-       int i;
-
-       for (i = 0; i < AR5416_MAX_CHAINS; i++) {
-               ah->totalAdcIOddPhase[i] +=
-                       REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
-               ah->totalAdcIEvenPhase[i] +=
-                       REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
-               ah->totalAdcQOddPhase[i] +=
-                       REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
-               ah->totalAdcQEvenPhase[i] +=
-                       REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
-
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                       "%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
-                       "oddq=0x%08x; evenq=0x%08x;\n",
-                       ah->cal_samples, i,
-                       ah->totalAdcIOddPhase[i],
-                       ah->totalAdcIEvenPhase[i],
-                       ah->totalAdcQOddPhase[i],
-                       ah->totalAdcQEvenPhase[i]);
-       }
-}
-
-static void ath9k_hw_adc_dccal_collect(struct ath_hw *ah)
-{
-       int i;
-
-       for (i = 0; i < AR5416_MAX_CHAINS; i++) {
-               ah->totalAdcDcOffsetIOddPhase[i] +=
-                       (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
-               ah->totalAdcDcOffsetIEvenPhase[i] +=
-                       (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
-               ah->totalAdcDcOffsetQOddPhase[i] +=
-                       (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
-               ah->totalAdcDcOffsetQEvenPhase[i] +=
-                       (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
-
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                       "%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
-                       "oddq=0x%08x; evenq=0x%08x;\n",
-                       ah->cal_samples, i,
-                       ah->totalAdcDcOffsetIOddPhase[i],
-                       ah->totalAdcDcOffsetIEvenPhase[i],
-                       ah->totalAdcDcOffsetQOddPhase[i],
-                       ah->totalAdcDcOffsetQEvenPhase[i]);
-       }
-}
-
-static void ath9k_hw_iqcalibrate(struct ath_hw *ah, u8 numChains)
-{
-       u32 powerMeasQ, powerMeasI, iqCorrMeas;
-       u32 qCoffDenom, iCoffDenom;
-       int32_t qCoff, iCoff;
-       int iqCorrNeg, i;
-
-       for (i = 0; i < numChains; i++) {
-               powerMeasI = ah->totalPowerMeasI[i];
-               powerMeasQ = ah->totalPowerMeasQ[i];
-               iqCorrMeas = ah->totalIqCorrMeas[i];
-
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                       "Starting IQ Cal and Correction for Chain %d\n",
-                       i);
-
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                       "Orignal: Chn %diq_corr_meas = 0x%08x\n",
-                       i, ah->totalIqCorrMeas[i]);
-
-               iqCorrNeg = 0;
-
-               if (iqCorrMeas > 0x80000000) {
-                       iqCorrMeas = (0xffffffff - iqCorrMeas) + 1;
-                       iqCorrNeg = 1;
-               }
-
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                       "Chn %d pwr_meas_i = 0x%08x\n", i, powerMeasI);
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                       "Chn %d pwr_meas_q = 0x%08x\n", i, powerMeasQ);
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "iqCorrNeg is 0x%08x\n",
-                       iqCorrNeg);
-
-               iCoffDenom = (powerMeasI / 2 + powerMeasQ / 2) / 128;
-               qCoffDenom = powerMeasQ / 64;
-
-               if (powerMeasQ != 0) {
-                       iCoff = iqCorrMeas / iCoffDenom;
-                       qCoff = powerMeasI / qCoffDenom - 64;
-                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                               "Chn %d iCoff = 0x%08x\n", i, iCoff);
-                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                               "Chn %d qCoff = 0x%08x\n", i, qCoff);
-
-                       iCoff = iCoff & 0x3f;
-                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                               "New: Chn %d iCoff = 0x%08x\n", i, iCoff);
-                       if (iqCorrNeg == 0x0)
-                               iCoff = 0x40 - iCoff;
-
-                       if (qCoff > 15)
-                               qCoff = 15;
-                       else if (qCoff <= -16)
-                               qCoff = 16;
-
-                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                               "Chn %d : iCoff = 0x%x  qCoff = 0x%x\n",
-                               i, iCoff, qCoff);
-
-                       REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i),
-                                     AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF,
-                                     iCoff);
-                       REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i),
-                                     AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF,
-                                     qCoff);
-                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                               "IQ Cal and Correction done for Chain %d\n",
-                               i);
-               }
-       }
-
-       REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0),
-                   AR_PHY_TIMING_CTRL4_IQCORR_ENABLE);
-}
-
-static void ath9k_hw_adc_gaincal_calibrate(struct ath_hw *ah, u8 numChains)
-{
-       u32 iOddMeasOffset, iEvenMeasOffset, qOddMeasOffset, qEvenMeasOffset;
-       u32 qGainMismatch, iGainMismatch, val, i;
-
-       for (i = 0; i < numChains; i++) {
-               iOddMeasOffset = ah->totalAdcIOddPhase[i];
-               iEvenMeasOffset = ah->totalAdcIEvenPhase[i];
-               qOddMeasOffset = ah->totalAdcQOddPhase[i];
-               qEvenMeasOffset = ah->totalAdcQEvenPhase[i];
-
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                       "Starting ADC Gain Cal for Chain %d\n", i);
-
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                       "Chn %d pwr_meas_odd_i = 0x%08x\n", i,
-                       iOddMeasOffset);
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                       "Chn %d pwr_meas_even_i = 0x%08x\n", i,
-                       iEvenMeasOffset);
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                       "Chn %d pwr_meas_odd_q = 0x%08x\n", i,
-                       qOddMeasOffset);
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                       "Chn %d pwr_meas_even_q = 0x%08x\n", i,
-                       qEvenMeasOffset);
-
-               if (iOddMeasOffset != 0 && qEvenMeasOffset != 0) {
-                       iGainMismatch =
-                               ((iEvenMeasOffset * 32) /
-                                iOddMeasOffset) & 0x3f;
-                       qGainMismatch =
-                               ((qOddMeasOffset * 32) /
-                                qEvenMeasOffset) & 0x3f;
-
-                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                               "Chn %d gain_mismatch_i = 0x%08x\n", i,
-                               iGainMismatch);
-                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                               "Chn %d gain_mismatch_q = 0x%08x\n", i,
-                               qGainMismatch);
-
-                       val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i));
-                       val &= 0xfffff000;
-                       val |= (qGainMismatch) | (iGainMismatch << 6);
-                       REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val);
-
-                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                               "ADC Gain Cal done for Chain %d\n", i);
-               }
-       }
-
-       REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0),
-                 REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) |
-                 AR_PHY_NEW_ADC_GAIN_CORR_ENABLE);
-}
-
-static void ath9k_hw_adc_dccal_calibrate(struct ath_hw *ah, u8 numChains)
-{
-       u32 iOddMeasOffset, iEvenMeasOffset, val, i;
-       int32_t qOddMeasOffset, qEvenMeasOffset, qDcMismatch, iDcMismatch;
-       const struct hal_percal_data *calData =
-               ah->cal_list_curr->calData;
-       u32 numSamples =
-               (1 << (calData->calCountMax + 5)) * calData->calNumSamples;
-
-       for (i = 0; i < numChains; i++) {
-               iOddMeasOffset = ah->totalAdcDcOffsetIOddPhase[i];
-               iEvenMeasOffset = ah->totalAdcDcOffsetIEvenPhase[i];
-               qOddMeasOffset = ah->totalAdcDcOffsetQOddPhase[i];
-               qEvenMeasOffset = ah->totalAdcDcOffsetQEvenPhase[i];
-
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                       "Starting ADC DC Offset Cal for Chain %d\n", i);
-
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                       "Chn %d pwr_meas_odd_i = %d\n", i,
-                       iOddMeasOffset);
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                       "Chn %d pwr_meas_even_i = %d\n", i,
-                       iEvenMeasOffset);
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                       "Chn %d pwr_meas_odd_q = %d\n", i,
-                       qOddMeasOffset);
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                       "Chn %d pwr_meas_even_q = %d\n", i,
-                       qEvenMeasOffset);
-
-               iDcMismatch = (((iEvenMeasOffset - iOddMeasOffset) * 2) /
-                              numSamples) & 0x1ff;
-               qDcMismatch = (((qOddMeasOffset - qEvenMeasOffset) * 2) /
-                              numSamples) & 0x1ff;
-
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                       "Chn %d dc_offset_mismatch_i = 0x%08x\n", i,
-                       iDcMismatch);
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                       "Chn %d dc_offset_mismatch_q = 0x%08x\n", i,
-                       qDcMismatch);
-
-               val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i));
-               val &= 0xc0000fff;
-               val |= (qDcMismatch << 12) | (iDcMismatch << 21);
-               REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val);
-
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                       "ADC DC Offset Cal done for Chain %d\n", i);
-       }
-
-       REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0),
-                 REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) |
-                 AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE);
-}
-
-/* This is done for the currently configured channel */
-bool ath9k_hw_reset_calvalid(struct ath_hw *ah)
-{
-       struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
-       struct hal_cal_list *currCal = ah->cal_list_curr;
-
-       if (!ah->curchan)
-               return true;
-
-       if (!AR_SREV_9100(ah) && !AR_SREV_9160_10_OR_LATER(ah))
-               return true;
-
-       if (currCal == NULL)
-               return true;
-
-       if (currCal->calState != CAL_DONE) {
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                       "Calibration state incorrect, %d\n",
-                       currCal->calState);
-               return true;
-       }
-
-       if (!ath9k_hw_iscal_supported(ah, currCal->calData->calType))
-               return true;
-
-       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-               "Resetting Cal %d state for channel %u\n",
-               currCal->calData->calType, conf->channel->center_freq);
-
-       ah->curchan->CalValid &= ~currCal->calData->calType;
-       currCal->calState = CAL_WAITING;
-
-       return false;
-}
-
-void ath9k_hw_start_nfcal(struct ath_hw *ah)
-{
-       REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
-                   AR_PHY_AGC_CONTROL_ENABLE_NF);
-       REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
-                   AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
-       REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
-}
-
-void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
-{
-       struct ath9k_nfcal_hist *h;
-       int i, j;
-       int32_t val;
-       const u32 ar5416_cca_regs[6] = {
-               AR_PHY_CCA,
-               AR_PHY_CH1_CCA,
-               AR_PHY_CH2_CCA,
-               AR_PHY_EXT_CCA,
-               AR_PHY_CH1_EXT_CCA,
-               AR_PHY_CH2_EXT_CCA
-       };
-       u8 chainmask;
-
-       if (AR_SREV_9285(ah))
-               chainmask = 0x9;
-       else if (AR_SREV_9280(ah))
-               chainmask = 0x1B;
-       else
-               chainmask = 0x3F;
-
-       h = ah->nfCalHist;
-
-       for (i = 0; i < NUM_NF_READINGS; i++) {
-               if (chainmask & (1 << i)) {
-                       val = REG_READ(ah, ar5416_cca_regs[i]);
-                       val &= 0xFFFFFE00;
-                       val |= (((u32) (h[i].privNF) << 1) & 0x1ff);
-                       REG_WRITE(ah, ar5416_cca_regs[i], val);
-               }
-       }
-
-       REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
-                   AR_PHY_AGC_CONTROL_ENABLE_NF);
-       REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
-                   AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
-       REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
-
-       for (j = 0; j < 1000; j++) {
-               if ((REG_READ(ah, AR_PHY_AGC_CONTROL) &
-                    AR_PHY_AGC_CONTROL_NF) == 0)
-                       break;
-               udelay(10);
-       }
-
-       for (i = 0; i < NUM_NF_READINGS; i++) {
-               if (chainmask & (1 << i)) {
-                       val = REG_READ(ah, ar5416_cca_regs[i]);
-                       val &= 0xFFFFFE00;
-                       val |= (((u32) (-50) << 1) & 0x1ff);
-                       REG_WRITE(ah, ar5416_cca_regs[i], val);
-               }
-       }
-}
-
-int16_t ath9k_hw_getnf(struct ath_hw *ah,
-                      struct ath9k_channel *chan)
-{
-       int16_t nf, nfThresh;
-       int16_t nfarray[NUM_NF_READINGS] = { 0 };
-       struct ath9k_nfcal_hist *h;
-       struct ieee80211_channel *c = chan->chan;
-
-       chan->channelFlags &= (~CHANNEL_CW_INT);
-       if (REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) {
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                       "NF did not complete in calibration window\n");
-               nf = 0;
-               chan->rawNoiseFloor = nf;
-               return chan->rawNoiseFloor;
-       } else {
-               ath9k_hw_do_getnf(ah, nfarray);
-               nf = nfarray[0];
-               if (getNoiseFloorThresh(ah, c->band, &nfThresh)
-                   && nf > nfThresh) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                               "noise floor failed detected; "
-                               "detected %d, threshold %d\n",
-                               nf, nfThresh);
-                       chan->channelFlags |= CHANNEL_CW_INT;
-               }
-       }
-
-       h = ah->nfCalHist;
-
-       ath9k_hw_update_nfcal_hist_buffer(h, nfarray);
-       chan->rawNoiseFloor = h[0].privNF;
-
-       return chan->rawNoiseFloor;
-}
-
-void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah)
-{
-       int i, j;
-
-       for (i = 0; i < NUM_NF_READINGS; i++) {
-               ah->nfCalHist[i].currIndex = 0;
-               ah->nfCalHist[i].privNF = AR_PHY_CCA_MAX_GOOD_VALUE;
-               ah->nfCalHist[i].invalidNFcount =
-                       AR_PHY_CCA_FILTERWINDOW_LENGTH;
-               for (j = 0; j < ATH9K_NF_CAL_HIST_MAX; j++) {
-                       ah->nfCalHist[i].nfCalBuffer[j] =
-                               AR_PHY_CCA_MAX_GOOD_VALUE;
-               }
-       }
-}
-
-s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan)
-{
-       s16 nf;
-
-       if (chan->rawNoiseFloor == 0)
-               nf = -96;
-       else
-               nf = chan->rawNoiseFloor;
-
-       if (!ath9k_hw_nf_in_range(ah, nf))
-               nf = ATH_DEFAULT_NOISE_FLOOR;
-
-       return nf;
-}
-
-static void ath9k_olc_temp_compensation(struct ath_hw *ah)
-{
-       u32 rddata, i;
-       int delta, currPDADC, regval;
-
-       rddata = REG_READ(ah, AR_PHY_TX_PWRCTRL4);
-
-       currPDADC = MS(rddata, AR_PHY_TX_PWRCTRL_PD_AVG_OUT);
-
-       if (ah->eep_ops->get_eeprom(ah, EEP_DAC_HPWR_5G))
-               delta = (currPDADC - ah->initPDADC + 4) / 8;
-       else
-               delta = (currPDADC - ah->initPDADC + 5) / 10;
-
-       if (delta != ah->PDADCdelta) {
-               ah->PDADCdelta = delta;
-               for (i = 1; i < AR9280_TX_GAIN_TABLE_SIZE; i++) {
-                       regval = ah->originalGain[i] - delta;
-                       if (regval < 0)
-                               regval = 0;
-
-                       REG_RMW_FIELD(ah, AR_PHY_TX_GAIN_TBL1 + i * 4,
-                                       AR_PHY_TX_GAIN, regval);
-               }
-       }
-}
-
-static inline void ath9k_hw_9285_pa_cal(struct ath_hw *ah)
-{
-
-       u32 regVal;
-       int i, offset, offs_6_1, offs_0;
-       u32 ccomp_org, reg_field;
-       u32 regList[][2] = {
-               { 0x786c, 0 },
-               { 0x7854, 0 },
-               { 0x7820, 0 },
-               { 0x7824, 0 },
-               { 0x7868, 0 },
-               { 0x783c, 0 },
-               { 0x7838, 0 },
-       };
-
-       if (AR_SREV_9285_11(ah)) {
-               REG_WRITE(ah, AR9285_AN_TOP4, (AR9285_AN_TOP4_DEFAULT | 0x14));
-               udelay(10);
-       }
-
-       for (i = 0; i < ARRAY_SIZE(regList); i++)
-               regList[i][1] = REG_READ(ah, regList[i][0]);
-
-       regVal = REG_READ(ah, 0x7834);
-       regVal &= (~(0x1));
-       REG_WRITE(ah, 0x7834, regVal);
-       regVal = REG_READ(ah, 0x9808);
-       regVal |= (0x1 << 27);
-       REG_WRITE(ah, 0x9808, regVal);
-
-       REG_RMW_FIELD(ah, AR9285_AN_TOP3, AR9285_AN_TOP3_PWDDAC, 1);
-       REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDRXTXBB1, 1);
-       REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDV2I, 1);
-       REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDDACIF, 1);
-       REG_RMW_FIELD(ah, AR9285_AN_RF2G2, AR9285_AN_RF2G2_OFFCAL, 0);
-       REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PWDDB, 0);
-       REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_ENPACAL, 0);
-       REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV1, 1);
-       REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV2, 0);
-       REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPAOUT, 0);
-       REG_RMW_FIELD(ah, AR9285_AN_RF2G8, AR9285_AN_RF2G8_PADRVGN2TAB0, 7);
-       REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PADRVGN2TAB0, 0);
-       ccomp_org = MS(REG_READ(ah, AR9285_AN_RF2G6), AR9285_AN_RF2G6_CCOMP);
-       REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_CCOMP, 7);
-
-       REG_WRITE(ah, AR9285_AN_TOP2, 0xca0358a0);
-       udelay(30);
-       REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_OFFS, 0);
-       REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, 0);
-
-       for (i = 6; i > 0; i--) {
-               regVal = REG_READ(ah, 0x7834);
-               regVal |= (1 << (19 + i));
-               REG_WRITE(ah, 0x7834, regVal);
-               udelay(1);
-               regVal = REG_READ(ah, 0x7834);
-               regVal &= (~(0x1 << (19 + i)));
-               reg_field = MS(REG_READ(ah, 0x7840), AR9285_AN_RXTXBB1_SPARE9);
-               regVal |= (reg_field << (19 + i));
-               REG_WRITE(ah, 0x7834, regVal);
-       }
-
-       REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, 1);
-       udelay(1);
-       reg_field = MS(REG_READ(ah, AR9285_AN_RF2G9), AR9285_AN_RXTXBB1_SPARE9);
-       REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, reg_field);
-       offs_6_1 = MS(REG_READ(ah, AR9285_AN_RF2G6), AR9285_AN_RF2G6_OFFS);
-       offs_0   = MS(REG_READ(ah, AR9285_AN_RF2G3), AR9285_AN_RF2G3_PDVCCOMP);
-
-       offset = (offs_6_1<<1) | offs_0;
-       offset = offset - 0;
-       offs_6_1 = offset>>1;
-       offs_0 = offset & 1;
-
-       REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_OFFS, offs_6_1);
-       REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, offs_0);
-
-       regVal = REG_READ(ah, 0x7834);
-       regVal |= 0x1;
-       REG_WRITE(ah, 0x7834, regVal);
-       regVal = REG_READ(ah, 0x9808);
-       regVal &= (~(0x1 << 27));
-       REG_WRITE(ah, 0x9808, regVal);
-
-       for (i = 0; i < ARRAY_SIZE(regList); i++)
-               REG_WRITE(ah, regList[i][0], regList[i][1]);
-
-       REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_CCOMP, ccomp_org);
-
-       if (AR_SREV_9285_11(ah))
-               REG_WRITE(ah, AR9285_AN_TOP4, AR9285_AN_TOP4_DEFAULT);
-
-}
-
-bool ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
-                       u8 rxchainmask, bool longcal,
-                       bool *isCalDone)
-{
-       struct hal_cal_list *currCal = ah->cal_list_curr;
-
-       *isCalDone = true;
-
-       if (currCal &&
-           (currCal->calState == CAL_RUNNING ||
-            currCal->calState == CAL_WAITING)) {
-               ath9k_hw_per_calibration(ah, chan, rxchainmask, currCal,
-                                        isCalDone);
-               if (*isCalDone) {
-                       ah->cal_list_curr = currCal = currCal->calNext;
-
-                       if (currCal->calState == CAL_WAITING) {
-                               *isCalDone = false;
-                               ath9k_hw_reset_calibration(ah, currCal);
-                       }
-               }
-       }
-
-       if (longcal) {
-               if (AR_SREV_9285(ah) && AR_SREV_9285_11_OR_LATER(ah))
-                       ath9k_hw_9285_pa_cal(ah);
-
-               if (OLC_FOR_AR9280_20_LATER)
-                       ath9k_olc_temp_compensation(ah);
-               ath9k_hw_getnf(ah, chan);
-               ath9k_hw_loadnf(ah, ah->curchan);
-               ath9k_hw_start_nfcal(ah);
-
-               if (chan->channelFlags & CHANNEL_CW_INT)
-                       chan->channelFlags &= ~CHANNEL_CW_INT;
-       }
-
-       return true;
-}
-
-static bool ar9285_clc(struct ath_hw *ah, struct ath9k_channel *chan)
-{
-       REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
-       if (chan->channelFlags & CHANNEL_HT20) {
-               REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_PARALLEL_CAL_ENABLE);
-               REG_SET_BIT(ah, AR_PHY_TURBO, AR_PHY_FC_DYN2040_EN);
-               REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
-                           AR_PHY_AGC_CONTROL_FLTR_CAL);
-               REG_CLR_BIT(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_CAL_ENABLE);
-               REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL);
-               if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
-                                 AR_PHY_AGC_CONTROL_CAL, 0, AH_WAIT_TIMEOUT)) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "offset "
-                               "calibration failed to complete in "
-                               "1ms; noisy ??\n");
-                       return false;
-               }
-               REG_CLR_BIT(ah, AR_PHY_TURBO, AR_PHY_FC_DYN2040_EN);
-               REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_PARALLEL_CAL_ENABLE);
-               REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
-       }
-       REG_CLR_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
-       REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
-       REG_SET_BIT(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_CAL_ENABLE);
-       REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL);
-       if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL,
-                         0, AH_WAIT_TIMEOUT)) {
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "offset calibration "
-                               "failed to complete in 1ms; noisy ??\n");
-               return false;
-       }
-
-       REG_SET_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
-       REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
-       REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
-
-       return true;
-}
-
-bool ath9k_hw_init_cal(struct ath_hw *ah,
-                      struct ath9k_channel *chan)
-{
-       if (AR_SREV_9285(ah) && AR_SREV_9285_12_OR_LATER(ah)) {
-               if (!ar9285_clc(ah, chan))
-                       return false;
-       } else if (AR_SREV_9280_10_OR_LATER(ah)) {
-               REG_CLR_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
-               REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
-               REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
-
-               /* Kick off the cal */
-               REG_WRITE(ah, AR_PHY_AGC_CONTROL,
-                               REG_READ(ah, AR_PHY_AGC_CONTROL) |
-                               AR_PHY_AGC_CONTROL_CAL);
-
-               if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
-                                       AR_PHY_AGC_CONTROL_CAL, 0,
-                                       AH_WAIT_TIMEOUT)) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                               "offset calibration failed to complete in 1ms; "
-                               "noisy environment?\n");
-                       return false;
-               }
-
-               REG_CLR_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
-               REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
-               REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
-       }
-
-       /* Calibrate the AGC */
-       REG_WRITE(ah, AR_PHY_AGC_CONTROL,
-                       REG_READ(ah, AR_PHY_AGC_CONTROL) |
-                       AR_PHY_AGC_CONTROL_CAL);
-
-       if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL,
-                               0, AH_WAIT_TIMEOUT)) {
-               DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                       "offset calibration failed to complete in 1ms; "
-                       "noisy environment?\n");
-               return false;
-       }
-
-       if (AR_SREV_9280_10_OR_LATER(ah)) {
-               REG_SET_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC);
-               REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL);
-       }
-
-       /* Do PA Calibration */
-       if (AR_SREV_9285(ah) && AR_SREV_9285_11_OR_LATER(ah))
-               ath9k_hw_9285_pa_cal(ah);
-
-       /* Do NF Calibration */
-       REG_WRITE(ah, AR_PHY_AGC_CONTROL,
-                       REG_READ(ah, AR_PHY_AGC_CONTROL) |
-                       AR_PHY_AGC_CONTROL_NF);
-
-       ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL;
-
-       if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) {
-               if (ath9k_hw_iscal_supported(ah, ADC_GAIN_CAL)) {
-                       INIT_CAL(&ah->adcgain_caldata);
-                       INSERT_CAL(ah, &ah->adcgain_caldata);
-                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                                       "enabling ADC Gain Calibration.\n");
-               }
-               if (ath9k_hw_iscal_supported(ah, ADC_DC_CAL)) {
-                       INIT_CAL(&ah->adcdc_caldata);
-                       INSERT_CAL(ah, &ah->adcdc_caldata);
-                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                                       "enabling ADC DC Calibration.\n");
-               }
-               if (ath9k_hw_iscal_supported(ah, IQ_MISMATCH_CAL)) {
-                       INIT_CAL(&ah->iq_caldata);
-                       INSERT_CAL(ah, &ah->iq_caldata);
-                       DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
-                                       "enabling IQ Calibration.\n");
-               }
-
-               ah->cal_list_curr = ah->cal_list;
-
-               if (ah->cal_list_curr)
-                       ath9k_hw_reset_calibration(ah, ah->cal_list_curr);
-       }
-
-       chan->CalValid = 0;
-
-       return true;
-}
-
-const struct hal_percal_data iq_cal_multi_sample = {
-       IQ_MISMATCH_CAL,
-       MAX_CAL_SAMPLES,
-       PER_MIN_LOG_COUNT,
-       ath9k_hw_iqcal_collect,
-       ath9k_hw_iqcalibrate
-};
-const struct hal_percal_data iq_cal_single_sample = {
-       IQ_MISMATCH_CAL,
-       MIN_CAL_SAMPLES,
-       PER_MAX_LOG_COUNT,
-       ath9k_hw_iqcal_collect,
-       ath9k_hw_iqcalibrate
-};
-const struct hal_percal_data adc_gain_cal_multi_sample = {
-       ADC_GAIN_CAL,
-       MAX_CAL_SAMPLES,
-       PER_MIN_LOG_COUNT,
-       ath9k_hw_adc_gaincal_collect,
-       ath9k_hw_adc_gaincal_calibrate
-};
-const struct hal_percal_data adc_gain_cal_single_sample = {
-       ADC_GAIN_CAL,
-       MIN_CAL_SAMPLES,
-       PER_MAX_LOG_COUNT,
-       ath9k_hw_adc_gaincal_collect,
-       ath9k_hw_adc_gaincal_calibrate
-};
-const struct hal_percal_data adc_dc_cal_multi_sample = {
-       ADC_DC_CAL,
-       MAX_CAL_SAMPLES,
-       PER_MIN_LOG_COUNT,
-       ath9k_hw_adc_dccal_collect,
-       ath9k_hw_adc_dccal_calibrate
-};
-const struct hal_percal_data adc_dc_cal_single_sample = {
-       ADC_DC_CAL,
-       MIN_CAL_SAMPLES,
-       PER_MAX_LOG_COUNT,
-       ath9k_hw_adc_dccal_collect,
-       ath9k_hw_adc_dccal_calibrate
-};
-const struct hal_percal_data adc_init_dc_cal = {
-       ADC_DC_INIT_CAL,
-       MIN_CAL_SAMPLES,
-       INIT_LOG_COUNT,
-       ath9k_hw_adc_dccal_collect,
-       ath9k_hw_adc_dccal_calibrate
-};
diff --git a/drivers/net/wireless/ath9k/calib.h b/drivers/net/wireless/ath9k/calib.h
deleted file mode 100644 (file)
index 1c74bd5..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (c) 2008-2009 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 CALIB_H
-#define CALIB_H
-
-extern const struct hal_percal_data iq_cal_multi_sample;
-extern const struct hal_percal_data iq_cal_single_sample;
-extern const struct hal_percal_data adc_gain_cal_multi_sample;
-extern const struct hal_percal_data adc_gain_cal_single_sample;
-extern const struct hal_percal_data adc_dc_cal_multi_sample;
-extern const struct hal_percal_data adc_dc_cal_single_sample;
-extern const struct hal_percal_data adc_init_dc_cal;
-
-#define AR_PHY_CCA_MAX_GOOD_VALUE                      -85
-#define AR_PHY_CCA_MAX_HIGH_VALUE                      -62
-#define AR_PHY_CCA_MIN_BAD_VALUE                       -140
-#define AR_PHY_CCA_FILTERWINDOW_LENGTH_INIT     3
-#define AR_PHY_CCA_FILTERWINDOW_LENGTH          5
-
-#define NUM_NF_READINGS       6
-#define ATH9K_NF_CAL_HIST_MAX 5
-
-struct ar5416IniArray {
-       u32 *ia_array;
-       u32 ia_rows;
-       u32 ia_columns;
-};
-
-#define INIT_INI_ARRAY(iniarray, array, rows, columns) do {    \
-               (iniarray)->ia_array = (u32 *)(array);          \
-               (iniarray)->ia_rows = (rows);                   \
-               (iniarray)->ia_columns = (columns);             \
-       } while (0)
-
-#define INI_RA(iniarray, row, column) \
-       (((iniarray)->ia_array)[(row) * ((iniarray)->ia_columns) + (column)])
-
-#define INIT_CAL(_perCal) do {                         \
-               (_perCal)->calState = CAL_WAITING;      \
-               (_perCal)->calNext = NULL;              \
-       } while (0)
-
-#define INSERT_CAL(_ahp, _perCal)                                      \
-       do {                                                            \
-               if ((_ahp)->cal_list_last == NULL) {                    \
-                       (_ahp)->cal_list =                              \
-                               (_ahp)->cal_list_last = (_perCal);      \
-                       ((_ahp)->cal_list_last)->calNext = (_perCal); \
-               } else {                                                \
-                       ((_ahp)->cal_list_last)->calNext = (_perCal); \
-                       (_ahp)->cal_list_last = (_perCal);              \
-                       (_perCal)->calNext = (_ahp)->cal_list;  \
-               }                                                       \
-       } while (0)
-
-enum hal_cal_types {
-       ADC_DC_INIT_CAL = 0x1,
-       ADC_GAIN_CAL = 0x2,
-       ADC_DC_CAL = 0x4,
-       IQ_MISMATCH_CAL = 0x8
-};
-
-enum hal_cal_state {
-       CAL_INACTIVE,
-       CAL_WAITING,
-       CAL_RUNNING,
-       CAL_DONE
-};
-
-#define MIN_CAL_SAMPLES     1
-#define MAX_CAL_SAMPLES    64
-#define INIT_LOG_COUNT      5
-#define PER_MIN_LOG_COUNT   2
-#define PER_MAX_LOG_COUNT  10
-
-struct hal_percal_data {
-       enum hal_cal_types calType;
-       u32 calNumSamples;
-       u32 calCountMax;
-       void (*calCollect) (struct ath_hw *);
-       void (*calPostProc) (struct ath_hw *, u8);
-};
-
-struct hal_cal_list {
-       const struct hal_percal_data *calData;
-       enum hal_cal_state calState;
-       struct hal_cal_list *calNext;
-};
-
-struct ath9k_nfcal_hist {
-       int16_t nfCalBuffer[ATH9K_NF_CAL_HIST_MAX];
-       u8 currIndex;
-       int16_t privNF;
-       u8 invalidNFcount;
-};
-
-bool ath9k_hw_reset_calvalid(struct ath_hw *ah);
-void ath9k_hw_start_nfcal(struct ath_hw *ah);
-void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan);
-int16_t ath9k_hw_getnf(struct ath_hw *ah,
-                      struct ath9k_channel *chan);
-void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah);
-s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan);
-bool ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
-                       u8 rxchainmask, bool longcal,
-                       bool *isCalDone);
-bool ath9k_hw_init_cal(struct ath_hw *ah,
-                      struct ath9k_channel *chan);
-
-#endif /* CALIB_H */
diff --git a/drivers/net/wireless/ath9k/debug.c b/drivers/net/wireless/ath9k/debug.c
deleted file mode 100644 (file)
index fdf9528..0000000
+++ /dev/null
@@ -1,559 +0,0 @@
-/*
- * Copyright (c) 2008-2009 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 <asm/unaligned.h>
-
-#include "ath9k.h"
-
-static unsigned int ath9k_debug = DBG_DEFAULT;
-module_param_named(debug, ath9k_debug, uint, 0);
-
-static struct dentry *ath9k_debugfs_root;
-
-void DPRINTF(struct ath_softc *sc, int dbg_mask, const char *fmt, ...)
-{
-       if (!sc)
-               return;
-
-       if (sc->debug.debug_mask & dbg_mask) {
-               va_list args;
-
-               va_start(args, fmt);
-               printk(KERN_DEBUG "ath9k: ");
-               vprintk(fmt, args);
-               va_end(args);
-       }
-}
-
-static int ath9k_debugfs_open(struct inode *inode, struct file *file)
-{
-       file->private_data = inode->i_private;
-       return 0;
-}
-
-static ssize_t read_file_dma(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;
-       char buf[1024];
-       unsigned int len = 0;
-       u32 val[ATH9K_NUM_DMA_DEBUG_REGS];
-       int i, qcuOffset = 0, dcuOffset = 0;
-       u32 *qcuBase = &val[0], *dcuBase = &val[4];
-
-       REG_WRITE(ah, AR_MACMISC,
-                 ((AR_MACMISC_DMA_OBS_LINE_8 << AR_MACMISC_DMA_OBS_S) |
-                  (AR_MACMISC_MISC_OBS_BUS_1 <<
-                   AR_MACMISC_MISC_OBS_BUS_MSB_S)));
-
-       len += snprintf(buf + len, sizeof(buf) - len,
-                       "Raw DMA Debug values:\n");
-
-       for (i = 0; i < ATH9K_NUM_DMA_DEBUG_REGS; i++) {
-               if (i % 4 == 0)
-                       len += snprintf(buf + len, sizeof(buf) - len, "\n");
-
-               val[i] = REG_READ(ah, AR_DMADBG_0 + (i * sizeof(u32)));
-               len += snprintf(buf + len, sizeof(buf) - len, "%d: %08x ",
-                               i, val[i]);
-       }
-
-       len += snprintf(buf + len, sizeof(buf) - len, "\n\n");
-       len += snprintf(buf + len, sizeof(buf) - len,
-                       "Num QCU: chain_st fsp_ok fsp_st DCU: chain_st\n");
-
-       for (i = 0; i < ATH9K_NUM_QUEUES; i++, qcuOffset += 4, dcuOffset += 5) {
-               if (i == 8) {
-                       qcuOffset = 0;
-                       qcuBase++;
-               }
-
-               if (i == 6) {
-                       dcuOffset = 0;
-                       dcuBase++;
-               }
-
-               len += snprintf(buf + len, sizeof(buf) - len,
-                       "%2d          %2x      %1x     %2x           %2x\n",
-                       i, (*qcuBase & (0x7 << qcuOffset)) >> qcuOffset,
-                       (*qcuBase & (0x8 << qcuOffset)) >> (qcuOffset + 3),
-                       val[2] & (0x7 << (i * 3)) >> (i * 3),
-                       (*dcuBase & (0x1f << dcuOffset)) >> dcuOffset);
-       }
-
-       len += snprintf(buf + len, sizeof(buf) - len, "\n");
-
-       len += snprintf(buf + len, sizeof(buf) - len,
-               "qcu_stitch state:   %2x    qcu_fetch state:        %2x\n",
-               (val[3] & 0x003c0000) >> 18, (val[3] & 0x03c00000) >> 22);
-       len += snprintf(buf + len, sizeof(buf) - len,
-               "qcu_complete state: %2x    dcu_complete state:     %2x\n",
-               (val[3] & 0x1c000000) >> 26, (val[6] & 0x3));
-       len += snprintf(buf + len, sizeof(buf) - len,
-               "dcu_arb state:      %2x    dcu_fp state:           %2x\n",
-               (val[5] & 0x06000000) >> 25, (val[5] & 0x38000000) >> 27);
-       len += snprintf(buf + len, sizeof(buf) - len,
-               "chan_idle_dur:     %3d    chan_idle_dur_valid:     %1d\n",
-               (val[6] & 0x000003fc) >> 2, (val[6] & 0x00000400) >> 10);
-       len += snprintf(buf + len, sizeof(buf) - len,
-               "txfifo_valid_0:      %1d    txfifo_valid_1:          %1d\n",
-               (val[6] & 0x00000800) >> 11, (val[6] & 0x00001000) >> 12);
-       len += snprintf(buf + len, sizeof(buf) - len,
-               "txfifo_dcu_num_0:   %2d    txfifo_dcu_num_1:       %2d\n",
-               (val[6] & 0x0001e000) >> 13, (val[6] & 0x001e0000) >> 17);
-
-       len += snprintf(buf + len, sizeof(buf) - len, "pcu observe: 0x%x \n",
-                       REG_READ(ah, AR_OBS_BUS_1));
-       len += snprintf(buf + len, sizeof(buf) - len,
-                       "AR_CR: 0x%x \n", REG_READ(ah, AR_CR));
-
-       return simple_read_from_buffer(user_buf, count, ppos, buf, len);
-}
-
-static const struct file_operations fops_dma = {
-       .read = read_file_dma,
-       .open = ath9k_debugfs_open,
-       .owner = THIS_MODULE
-};
-
-
-void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status)
-{
-       if (status)
-               sc->debug.stats.istats.total++;
-       if (status & ATH9K_INT_RX)
-               sc->debug.stats.istats.rxok++;
-       if (status & ATH9K_INT_RXEOL)
-               sc->debug.stats.istats.rxeol++;
-       if (status & ATH9K_INT_RXORN)
-               sc->debug.stats.istats.rxorn++;
-       if (status & ATH9K_INT_TX)
-               sc->debug.stats.istats.txok++;
-       if (status & ATH9K_INT_TXURN)
-               sc->debug.stats.istats.txurn++;
-       if (status & ATH9K_INT_MIB)
-               sc->debug.stats.istats.mib++;
-       if (status & ATH9K_INT_RXPHY)
-               sc->debug.stats.istats.rxphyerr++;
-       if (status & ATH9K_INT_RXKCM)
-               sc->debug.stats.istats.rx_keycache_miss++;
-       if (status & ATH9K_INT_SWBA)
-               sc->debug.stats.istats.swba++;
-       if (status & ATH9K_INT_BMISS)
-               sc->debug.stats.istats.bmiss++;
-       if (status & ATH9K_INT_BNR)
-               sc->debug.stats.istats.bnr++;
-       if (status & ATH9K_INT_CST)
-               sc->debug.stats.istats.cst++;
-       if (status & ATH9K_INT_GTT)
-               sc->debug.stats.istats.gtt++;
-       if (status & ATH9K_INT_TIM)
-               sc->debug.stats.istats.tim++;
-       if (status & ATH9K_INT_CABEND)
-               sc->debug.stats.istats.cabend++;
-       if (status & ATH9K_INT_DTIMSYNC)
-               sc->debug.stats.istats.dtimsync++;
-       if (status & ATH9K_INT_DTIM)
-               sc->debug.stats.istats.dtim++;
-}
-
-static ssize_t read_file_interrupt(struct file *file, char __user *user_buf,
-                                  size_t count, loff_t *ppos)
-{
-       struct ath_softc *sc = file->private_data;
-       char buf[512];
-       unsigned int len = 0;
-
-       len += snprintf(buf + len, sizeof(buf) - len,
-               "%8s: %10u\n", "RX", sc->debug.stats.istats.rxok);
-       len += snprintf(buf + len, sizeof(buf) - len,
-               "%8s: %10u\n", "RXEOL", sc->debug.stats.istats.rxeol);
-       len += snprintf(buf + len, sizeof(buf) - len,
-               "%8s: %10u\n", "RXORN", sc->debug.stats.istats.rxorn);
-       len += snprintf(buf + len, sizeof(buf) - len,
-               "%8s: %10u\n", "TX", sc->debug.stats.istats.txok);
-       len += snprintf(buf + len, sizeof(buf) - len,
-               "%8s: %10u\n", "TXURN", sc->debug.stats.istats.txurn);
-       len += snprintf(buf + len, sizeof(buf) - len,
-               "%8s: %10u\n", "MIB", sc->debug.stats.istats.mib);
-       len += snprintf(buf + len, sizeof(buf) - len,
-               "%8s: %10u\n", "RXPHY", sc->debug.stats.istats.rxphyerr);
-       len += snprintf(buf + len, sizeof(buf) - len,
-               "%8s: %10u\n", "RXKCM", sc->debug.stats.istats.rx_keycache_miss);
-       len += snprintf(buf + len, sizeof(buf) - len,
-               "%8s: %10u\n", "SWBA", sc->debug.stats.istats.swba);
-       len += snprintf(buf + len, sizeof(buf) - len,
-               "%8s: %10u\n", "BMISS", sc->debug.stats.istats.bmiss);
-       len += snprintf(buf + len, sizeof(buf) - len,
-               "%8s: %10u\n", "BNR", sc->debug.stats.istats.bnr);
-       len += snprintf(buf + len, sizeof(buf) - len,
-               "%8s: %10u\n", "CST", sc->debug.stats.istats.cst);
-       len += snprintf(buf + len, sizeof(buf) - len,
-               "%8s: %10u\n", "GTT", sc->debug.stats.istats.gtt);
-       len += snprintf(buf + len, sizeof(buf) - len,
-               "%8s: %10u\n", "TIM", sc->debug.stats.istats.tim);
-       len += snprintf(buf + len, sizeof(buf) - len,
-               "%8s: %10u\n", "CABEND", sc->debug.stats.istats.cabend);
-       len += snprintf(buf + len, sizeof(buf) - len,
-               "%8s: %10u\n", "DTIMSYNC", sc->debug.stats.istats.dtimsync);
-       len += snprintf(buf + len, sizeof(buf) - len,
-               "%8s: %10u\n", "DTIM", sc->debug.stats.istats.dtim);
-       len += snprintf(buf + len, sizeof(buf) - len,
-               "%8s: %10u\n", "TOTAL", sc->debug.stats.istats.total);
-
-       return simple_read_from_buffer(user_buf, count, ppos, buf, len);
-}
-
-static const struct file_operations fops_interrupt = {
-       .read = read_file_interrupt,
-       .open = ath9k_debugfs_open,
-       .owner = THIS_MODULE
-};
-
-static void ath_debug_stat_11n_rc(struct ath_softc *sc, struct sk_buff *skb)
-{
-       struct ath_tx_info_priv *tx_info_priv = NULL;
-       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
-       struct ieee80211_tx_rate *rates = tx_info->status.rates;
-       int final_ts_idx, idx;
-
-       tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
-       final_ts_idx = tx_info_priv->tx.ts_rateindex;
-       idx = sc->cur_rate_table->info[rates[final_ts_idx].idx].dot11rate;
-
-       sc->debug.stats.n_rcstats[idx].success++;
-}
-
-static void ath_debug_stat_legacy_rc(struct ath_softc *sc, struct sk_buff *skb)
-{
-       struct ath_tx_info_priv *tx_info_priv = NULL;
-       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
-       struct ieee80211_tx_rate *rates = tx_info->status.rates;
-       int final_ts_idx, idx;
-
-       tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
-       final_ts_idx = tx_info_priv->tx.ts_rateindex;
-       idx = rates[final_ts_idx].idx;
-
-       sc->debug.stats.legacy_rcstats[idx].success++;
-}
-
-void ath_debug_stat_rc(struct ath_softc *sc, struct sk_buff *skb)
-{
-       if (conf_is_ht(&sc->hw->conf))
-               ath_debug_stat_11n_rc(sc, skb);
-       else
-               ath_debug_stat_legacy_rc(sc, skb);
-}
-
-/* FIXME: legacy rates, later on .. */
-void ath_debug_stat_retries(struct ath_softc *sc, int rix,
-                           int xretries, int retries, u8 per)
-{
-       if (conf_is_ht(&sc->hw->conf)) {
-               int idx = sc->cur_rate_table->info[rix].dot11rate;
-
-               sc->debug.stats.n_rcstats[idx].xretries += xretries;
-               sc->debug.stats.n_rcstats[idx].retries += retries;
-               sc->debug.stats.n_rcstats[idx].per = per;
-       }
-}
-
-static ssize_t ath_read_file_stat_11n_rc(struct file *file,
-                                        char __user *user_buf,
-                                        size_t count, loff_t *ppos)
-{
-       struct ath_softc *sc = file->private_data;
-       char buf[1024];
-       unsigned int len = 0;
-       int i = 0;
-
-       len += sprintf(buf, "%7s %13s %8s %8s %6s\n\n", "Rate", "Success",
-                      "Retries", "XRetries", "PER");
-
-       for (i = 0; i <= 15; i++) {
-               len += snprintf(buf + len, sizeof(buf) - len,
-                               "%5s%3d: %8u %8u %8u %8u\n", "MCS", i,
-                               sc->debug.stats.n_rcstats[i].success,
-                               sc->debug.stats.n_rcstats[i].retries,
-                               sc->debug.stats.n_rcstats[i].xretries,
-                               sc->debug.stats.n_rcstats[i].per);
-       }
-
-       return simple_read_from_buffer(user_buf, count, ppos, buf, len);
-}
-
-static ssize_t ath_read_file_stat_legacy_rc(struct file *file,
-                                           char __user *user_buf,
-                                           size_t count, loff_t *ppos)
-{
-       struct ath_softc *sc = file->private_data;
-       char buf[512];
-       unsigned int len = 0;
-       int i = 0;
-
-       len += sprintf(buf, "%7s %13s\n\n", "Rate", "Success");
-
-       for (i = 0; i < sc->cur_rate_table->rate_cnt; i++) {
-               len += snprintf(buf + len, sizeof(buf) - len, "%5u: %12u\n",
-                               sc->cur_rate_table->info[i].ratekbps / 1000,
-                               sc->debug.stats.legacy_rcstats[i].success);
-       }
-
-       return simple_read_from_buffer(user_buf, count, ppos, buf, len);
-}
-
-static ssize_t read_file_rcstat(struct file *file, char __user *user_buf,
-                               size_t count, loff_t *ppos)
-{
-       struct ath_softc *sc = file->private_data;
-
-       if (sc->cur_rate_table == NULL)
-               return 0;
-
-       if (conf_is_ht(&sc->hw->conf))
-               return ath_read_file_stat_11n_rc(file, user_buf, count, ppos);
-       else
-               return ath_read_file_stat_legacy_rc(file, user_buf, count ,ppos);
-}
-
-static const struct file_operations fops_rcstat = {
-       .read = read_file_rcstat,
-       .open = ath9k_debugfs_open,
-       .owner = THIS_MODULE
-};
-
-static const char * ath_wiphy_state_str(enum ath_wiphy_state state)
-{
-       switch (state) {
-       case ATH_WIPHY_INACTIVE:
-               return "INACTIVE";
-       case ATH_WIPHY_ACTIVE:
-               return "ACTIVE";
-       case ATH_WIPHY_PAUSING:
-               return "PAUSING";
-       case ATH_WIPHY_PAUSED:
-               return "PAUSED";
-       case ATH_WIPHY_SCAN:
-               return "SCAN";
-       }
-       return "?";
-}
-
-static ssize_t read_file_wiphy(struct file *file, char __user *user_buf,
-                              size_t count, loff_t *ppos)
-{
-       struct ath_softc *sc = file->private_data;
-       char buf[512];
-       unsigned int len = 0;
-       int i;
-       u8 addr[ETH_ALEN];
-
-       len += snprintf(buf + len, sizeof(buf) - len,
-                       "primary: %s (%s chan=%d ht=%d)\n",
-                       wiphy_name(sc->pri_wiphy->hw->wiphy),
-                       ath_wiphy_state_str(sc->pri_wiphy->state),
-                       sc->pri_wiphy->chan_idx, sc->pri_wiphy->chan_is_ht);
-       for (i = 0; i < sc->num_sec_wiphy; i++) {
-               struct ath_wiphy *aphy = sc->sec_wiphy[i];
-               if (aphy == NULL)
-                       continue;
-               len += snprintf(buf + len, sizeof(buf) - len,
-                               "secondary: %s (%s chan=%d ht=%d)\n",
-                               wiphy_name(aphy->hw->wiphy),
-                               ath_wiphy_state_str(aphy->state),
-                               aphy->chan_idx, aphy->chan_is_ht);
-       }
-
-       put_unaligned_le32(REG_READ(sc->sc_ah, AR_STA_ID0), addr);
-       put_unaligned_le16(REG_READ(sc->sc_ah, AR_STA_ID1) & 0xffff, addr + 4);
-       len += snprintf(buf + len, sizeof(buf) - len,
-                       "addr: %pM\n", addr);
-       put_unaligned_le32(REG_READ(sc->sc_ah, AR_BSSMSKL), addr);
-       put_unaligned_le16(REG_READ(sc->sc_ah, AR_BSSMSKU) & 0xffff, addr + 4);
-       len += snprintf(buf + len, sizeof(buf) - len,
-                       "addrmask: %pM\n", addr);
-
-       return simple_read_from_buffer(user_buf, count, ppos, buf, len);
-}
-
-static struct ath_wiphy * get_wiphy(struct ath_softc *sc, const char *name)
-{
-       int i;
-       if (strcmp(name, wiphy_name(sc->pri_wiphy->hw->wiphy)) == 0)
-               return sc->pri_wiphy;
-       for (i = 0; i < sc->num_sec_wiphy; i++) {
-               struct ath_wiphy *aphy = sc->sec_wiphy[i];
-               if (aphy && strcmp(name, wiphy_name(aphy->hw->wiphy)) == 0)
-                       return aphy;
-       }
-       return NULL;
-}
-
-static int del_wiphy(struct ath_softc *sc, const char *name)
-{
-       struct ath_wiphy *aphy = get_wiphy(sc, name);
-       if (!aphy)
-               return -ENOENT;
-       return ath9k_wiphy_del(aphy);
-}
-
-static int pause_wiphy(struct ath_softc *sc, const char *name)
-{
-       struct ath_wiphy *aphy = get_wiphy(sc, name);
-       if (!aphy)
-               return -ENOENT;
-       return ath9k_wiphy_pause(aphy);
-}
-
-static int unpause_wiphy(struct ath_softc *sc, const char *name)
-{
-       struct ath_wiphy *aphy = get_wiphy(sc, name);
-       if (!aphy)
-               return -ENOENT;
-       return ath9k_wiphy_unpause(aphy);
-}
-
-static int select_wiphy(struct ath_softc *sc, const char *name)
-{
-       struct ath_wiphy *aphy = get_wiphy(sc, name);
-       if (!aphy)
-               return -ENOENT;
-       return ath9k_wiphy_select(aphy);
-}
-
-static int schedule_wiphy(struct ath_softc *sc, const char *msec)
-{
-       ath9k_wiphy_set_scheduler(sc, simple_strtoul(msec, NULL, 0));
-       return 0;
-}
-
-static ssize_t write_file_wiphy(struct file *file, const char __user *user_buf,
-                               size_t count, loff_t *ppos)
-{
-       struct ath_softc *sc = file->private_data;
-       char buf[50];
-       size_t len;
-
-       len = min(count, sizeof(buf) - 1);
-       if (copy_from_user(buf, user_buf, len))
-               return -EFAULT;
-       buf[len] = '\0';
-       if (len > 0 && buf[len - 1] == '\n')
-               buf[len - 1] = '\0';
-
-       if (strncmp(buf, "add", 3) == 0) {
-               int res = ath9k_wiphy_add(sc);
-               if (res < 0)
-                       return res;
-       } else if (strncmp(buf, "del=", 4) == 0) {
-               int res = del_wiphy(sc, buf + 4);
-               if (res < 0)
-                       return res;
-       } else if (strncmp(buf, "pause=", 6) == 0) {
-               int res = pause_wiphy(sc, buf + 6);
-               if (res < 0)
-                       return res;
-       } else if (strncmp(buf, "unpause=", 8) == 0) {
-               int res = unpause_wiphy(sc, buf + 8);
-               if (res < 0)
-                       return res;
-       } else if (strncmp(buf, "select=", 7) == 0) {
-               int res = select_wiphy(sc, buf + 7);
-               if (res < 0)
-                       return res;
-       } else if (strncmp(buf, "schedule=", 9) == 0) {
-               int res = schedule_wiphy(sc, buf + 9);
-               if (res < 0)
-                       return res;
-       } else
-               return -EOPNOTSUPP;
-
-       return count;
-}
-
-static const struct file_operations fops_wiphy = {
-       .read = read_file_wiphy,
-       .write = write_file_wiphy,
-       .open = ath9k_debugfs_open,
-       .owner = THIS_MODULE
-};
-
-
-int ath9k_init_debug(struct ath_softc *sc)
-{
-       sc->debug.debug_mask = ath9k_debug;
-
-       sc->debug.debugfs_phy = debugfs_create_dir(wiphy_name(sc->hw->wiphy),
-                                                     ath9k_debugfs_root);
-       if (!sc->debug.debugfs_phy)
-               goto err;
-
-       sc->debug.debugfs_dma = debugfs_create_file("dma", S_IRUGO,
-                                      sc->debug.debugfs_phy, sc, &fops_dma);
-       if (!sc->debug.debugfs_dma)
-               goto err;
-
-       sc->debug.debugfs_interrupt = debugfs_create_file("interrupt",
-                                                    S_IRUGO,
-                                                    sc->debug.debugfs_phy,
-                                                    sc, &fops_interrupt);
-       if (!sc->debug.debugfs_interrupt)
-               goto err;
-
-       sc->debug.debugfs_rcstat = debugfs_create_file("rcstat",
-                                                 S_IRUGO,
-                                                 sc->debug.debugfs_phy,
-                                                 sc, &fops_rcstat);
-       if (!sc->debug.debugfs_rcstat)
-               goto err;
-
-       sc->debug.debugfs_wiphy = debugfs_create_file(
-               "wiphy", S_IRUGO | S_IWUSR, sc->debug.debugfs_phy, sc,
-               &fops_wiphy);
-       if (!sc->debug.debugfs_wiphy)
-               goto err;
-
-       return 0;
-err:
-       ath9k_exit_debug(sc);
-       return -ENOMEM;
-}
-
-void ath9k_exit_debug(struct ath_softc *sc)
-{
-       debugfs_remove(sc->debug.debugfs_wiphy);
-       debugfs_remove(sc->debug.debugfs_rcstat);
-       debugfs_remove(sc->debug.debugfs_interrupt);
-       debugfs_remove(sc->debug.debugfs_dma);
-       debugfs_remove(sc->debug.debugfs_phy);
-}
-
-int ath9k_debug_create_root(void)
-{
-       ath9k_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL);
-       if (!ath9k_debugfs_root)
-               return -ENOENT;
-
-       return 0;
-}
-
-void ath9k_debug_remove_root(void)
-{
-       debugfs_remove(ath9k_debugfs_root);
-       ath9k_debugfs_root = NULL;
-}
diff --git a/drivers/net/wireless/ath9k/debug.h b/drivers/net/wireless/ath9k/debug.h
deleted file mode 100644 (file)
index 7b0e541..0000000
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright (c) 2008-2009 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
-
-enum ATH_DEBUG {
-       ATH_DBG_RESET           = 0x00000001,
-       ATH_DBG_REG_IO          = 0x00000002,
-       ATH_DBG_QUEUE           = 0x00000004,
-       ATH_DBG_EEPROM          = 0x00000008,
-       ATH_DBG_CALIBRATE       = 0x00000010,
-       ATH_DBG_CHANNEL         = 0x00000020,
-       ATH_DBG_INTERRUPT       = 0x00000040,
-       ATH_DBG_REGULATORY      = 0x00000080,
-       ATH_DBG_ANI             = 0x00000100,
-       ATH_DBG_POWER_MGMT      = 0x00000200,
-       ATH_DBG_XMIT            = 0x00000400,
-       ATH_DBG_BEACON          = 0x00001000,
-       ATH_DBG_CONFIG          = 0x00002000,
-       ATH_DBG_KEYCACHE        = 0x00004000,
-       ATH_DBG_FATAL           = 0x00008000,
-       ATH_DBG_ANY             = 0xffffffff
-};
-
-#define DBG_DEFAULT (ATH_DBG_FATAL)
-
-#ifdef CONFIG_ATH9K_DEBUG
-
-/**
- * struct ath_interrupt_stats - Contains statistics about interrupts
- * @total: Total no. of interrupts generated so far
- * @rxok: RX with no errors
- * @rxeol: RX with no more RXDESC available
- * @rxorn: RX FIFO overrun
- * @txok: TX completed at the requested rate
- * @txurn: TX FIFO underrun
- * @mib: MIB regs reaching its threshold
- * @rxphyerr: RX with phy errors
- * @rx_keycache_miss: RX with key cache misses
- * @swba: Software Beacon Alert
- * @bmiss: Beacon Miss
- * @bnr: Beacon Not Ready
- * @cst: Carrier Sense TImeout
- * @gtt: Global TX Timeout
- * @tim: RX beacon TIM occurrence
- * @cabend: RX End of CAB traffic
- * @dtimsync: DTIM sync lossage
- * @dtim: RX Beacon with DTIM
- */
-struct ath_interrupt_stats {
-       u32 total;
-       u32 rxok;
-       u32 rxeol;
-       u32 rxorn;
-       u32 txok;
-       u32 txeol;
-       u32 txurn;
-       u32 mib;
-       u32 rxphyerr;
-       u32 rx_keycache_miss;
-       u32 swba;
-       u32 bmiss;
-       u32 bnr;
-       u32 cst;
-       u32 gtt;
-       u32 tim;
-       u32 cabend;
-       u32 dtimsync;
-       u32 dtim;
-};
-
-struct ath_legacy_rc_stats {
-       u32 success;
-};
-
-struct ath_11n_rc_stats {
-       u32 success;
-       u32 retries;
-       u32 xretries;
-       u8 per;
-};
-
-struct ath_stats {
-       struct ath_interrupt_stats istats;
-       struct ath_legacy_rc_stats legacy_rcstats[12];  /* max(11a,11b,11g) */
-       struct ath_11n_rc_stats n_rcstats[16];          /* 0..15 MCS rates */
-};
-
-struct ath9k_debug {
-       int debug_mask;
-       struct dentry *debugfs_phy;
-       struct dentry *debugfs_dma;
-       struct dentry *debugfs_interrupt;
-       struct dentry *debugfs_rcstat;
-       struct dentry *debugfs_wiphy;
-       struct ath_stats stats;
-};
-
-void DPRINTF(struct ath_softc *sc, int dbg_mask, const char *fmt, ...);
-int ath9k_init_debug(struct ath_softc *sc);
-void ath9k_exit_debug(struct ath_softc *sc);
-int ath9k_debug_create_root(void);
-void ath9k_debug_remove_root(void);
-void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status);
-void ath_debug_stat_rc(struct ath_softc *sc, struct sk_buff *skb);
-void ath_debug_stat_retries(struct ath_softc *sc, int rix,
-                           int xretries, int retries, u8 per);
-
-#else
-
-static inline void DPRINTF(struct ath_softc *sc, int dbg_mask,
-                          const char *fmt, ...)
-{
-}
-
-static inline int ath9k_init_debug(struct ath_softc *sc)
-{
-       return 0;
-}
-
-static inline void ath9k_exit_debug(struct ath_softc *sc)
-{
-}
-
-static inline int ath9k_debug_create_root(void)
-{
-       return 0;
-}
-
-static inline void ath9k_debug_remove_root(void)
-{
-}
-
-static inline void ath_debug_stat_interrupt(struct ath_softc *sc,
-                                           enum ath9k_int status)
-{
-}
-
-static inline void ath_debug_stat_rc(struct ath_softc *sc,
-                                    struct sk_buff *skb)
-{
-}
-
-static inline void ath_debug_stat_retries(struct ath_softc *sc, int rix,
-                                         int xretries, int retries, u8 per)
-{
-}
-
-#endif /* CONFIG_ATH9K_DEBUG */
-
-#endif /* DEBUG_H */
diff --git a/drivers/net/wireless/ath9k/eeprom.c b/drivers/net/wireless/ath9k/eeprom.c
deleted file mode 100644 (file)
index ffc36b0..0000000
+++ /dev/null
@@ -1,2813 +0,0 @@
-/*
- * Copyright (c) 2008-2009 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 "ath9k.h"
-
-static void ath9k_hw_analog_shift_rmw(struct ath_hw *ah,
-                                     u32 reg, u32 mask,
-                                     u32 shift, u32 val)
-{
-       u32 regVal;
-
-       regVal = REG_READ(ah, reg) & ~mask;
-       regVal |= (val << shift) & mask;
-
-       REG_WRITE(ah, reg, regVal);
-
-       if (ah->config.analog_shiftreg)
-               udelay(100);
-
-       return;
-}
-
-static inline u16 ath9k_hw_fbin2freq(u8 fbin, bool is2GHz)
-{
-
-       if (fbin == AR5416_BCHAN_UNUSED)
-               return fbin;
-
-       return (u16) ((is2GHz) ? (2300 + fbin) : (4800 + 5 * fbin));
-}
-
-static inline int16_t ath9k_hw_interpolate(u16 target,
-                                          u16 srcLeft, u16 srcRight,
-                                          int16_t targetLeft,
-                                          int16_t targetRight)
-{
-       int16_t rv;
-
-       if (srcRight == srcLeft) {
-               rv = targetLeft;
-       } else {
-               rv = (int16_t) (((target - srcLeft) * targetRight +
-                                (srcRight - target) * targetLeft) /
-                               (srcRight - srcLeft));
-       }
-       return rv;
-}
-
-static inline bool ath9k_hw_get_lower_upper_index(u8 target, u8 *pList,
-                                                 u16 listSize, u16 *indexL,
-                                                 u16 *indexR)
-{
-       u16 i;
-
-       if (target <= pList[0]) {
-               *indexL = *indexR = 0;
-               return true;
-       }
-       if (target >= pList[listSize - 1]) {
-               *indexL = *indexR = (u16) (listSize - 1);
-               return true;
-       }
-
-       for (i = 0; i < listSize - 1; i++) {
-               if (pList[i] == target) {
-                       *indexL = *indexR = i;
-                       return true;
-               }
-               if (target < pList[i + 1]) {
-                       *indexL = i;
-                       *indexR = (u16) (i + 1);
-                       return false;
-               }
-       }
-       return false;
-}
-
-static inline bool ath9k_hw_nvram_read(struct ath_hw *ah, u32 off, u16 *data)
-{
-       struct ath_softc *sc = ah->ah_sc;
-
-       return sc->bus_ops->eeprom_read(ah, off, data);
-}
-
-static inline bool ath9k_hw_fill_vpd_table(u8 pwrMin, u8 pwrMax, u8 *pPwrList,
-                                          u8 *pVpdList, u16 numIntercepts,
-                                          u8 *pRetVpdList)
-{
-       u16 i, k;
-       u8 currPwr = pwrMin;
-       u16 idxL = 0, idxR = 0;
-
-       for (i = 0; i <= (pwrMax - pwrMin) / 2; i++) {
-               ath9k_hw_get_lower_upper_index(currPwr, pPwrList,
-                                              numIntercepts, &(idxL),
-                                              &(idxR));
-               if (idxR < 1)
-                       idxR = 1;
-               if (idxL == numIntercepts - 1)
-                       idxL = (u16) (numIntercepts - 2);
-               if (pPwrList[idxL] == pPwrList[idxR])
-                       k = pVpdList[idxL];
-               else
-                       k = (u16)(((currPwr - pPwrList[idxL]) * pVpdList[idxR] +
-                                  (pPwrList[idxR] - currPwr) * pVpdList[idxL]) /
-                                 (pPwrList[idxR] - pPwrList[idxL]));
-               pRetVpdList[i] = (u8) k;
-               currPwr += 2;
-       }
-
-       return true;
-}
-
-static void ath9k_hw_get_legacy_target_powers(struct ath_hw *ah,
-                                     struct ath9k_channel *chan,
-                                     struct cal_target_power_leg *powInfo,
-                                     u16 numChannels,
-                                     struct cal_target_power_leg *pNewPower,
-                                     u16 numRates, bool isExtTarget)
-{
-       struct chan_centers centers;
-       u16 clo, chi;
-       int i;
-       int matchIndex = -1, lowIndex = -1;
-       u16 freq;
-
-       ath9k_hw_get_channel_centers(ah, chan, &centers);
-       freq = (isExtTarget) ? centers.ext_center : centers.ctl_center;
-
-       if (freq <= ath9k_hw_fbin2freq(powInfo[0].bChannel,
-                                      IS_CHAN_2GHZ(chan))) {
-               matchIndex = 0;
-       } else {
-               for (i = 0; (i < numChannels) &&
-                            (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
-                       if (freq == ath9k_hw_fbin2freq(powInfo[i].bChannel,
-                                                      IS_CHAN_2GHZ(chan))) {
-                               matchIndex = i;
-                               break;
-                       } else if ((freq < ath9k_hw_fbin2freq(powInfo[i].bChannel,
-                                                     IS_CHAN_2GHZ(chan))) &&
-                                  (freq > ath9k_hw_fbin2freq(powInfo[i - 1].bChannel,
-                                                     IS_CHAN_2GHZ(chan)))) {
-                               lowIndex = i - 1;
-                               break;
-                       }
-               }
-               if ((matchIndex == -1) && (lowIndex == -1))
-                       matchIndex = i - 1;
-       }
-
-       if (matchIndex != -1) {
-               *pNewPower = powInfo[matchIndex];
-       } else {
-               clo = ath9k_hw_fbin2freq(powInfo[lowIndex].bChannel,
-                                        IS_CHAN_2GHZ(chan));
-               chi = ath9k_hw_fbin2freq(powInfo[lowIndex + 1].bChannel,
-                                        IS_CHAN_2GHZ(chan));
-
-               for (i = 0; i < numRates; i++) {
-                       pNewPower->tPow2x[i] =
-                               (u8)ath9k_hw_interpolate(freq, clo, chi,
-                                               powInfo[lowIndex].tPow2x[i],
-                                               powInfo[lowIndex + 1].tPow2x[i]);
-               }
-       }
-}
-
-static void ath9k_get_txgain_index(struct ath_hw *ah,
-               struct ath9k_channel *chan,
-               struct calDataPerFreqOpLoop *rawDatasetOpLoop,
-               u8 *calChans,  u16 availPiers, u8 *pwr, u8 *pcdacIdx)
-{
-       u8 pcdac, i = 0;
-       u16 idxL = 0, idxR = 0, numPiers;
-       bool match;
-       struct chan_centers centers;
-
-       ath9k_hw_get_channel_centers(ah, chan, &centers);
-
-       for (numPiers = 0; numPiers < availPiers; numPiers++)
-               if (calChans[numPiers] == AR5416_BCHAN_UNUSED)
-                       break;
-
-       match = ath9k_hw_get_lower_upper_index(
-                       (u8)FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan)),
-                       calChans, numPiers, &idxL, &idxR);
-       if (match) {
-               pcdac = rawDatasetOpLoop[idxL].pcdac[0][0];
-               *pwr = rawDatasetOpLoop[idxL].pwrPdg[0][0];
-       } else {
-               pcdac = rawDatasetOpLoop[idxR].pcdac[0][0];
-               *pwr = (rawDatasetOpLoop[idxL].pwrPdg[0][0] +
-                               rawDatasetOpLoop[idxR].pwrPdg[0][0])/2;
-       }
-
-       while (pcdac > ah->originalGain[i] &&
-                       i < (AR9280_TX_GAIN_TABLE_SIZE - 1))
-               i++;
-
-       *pcdacIdx = i;
-       return;
-}
-
-static void ath9k_olc_get_pdadcs(struct ath_hw *ah,
-                               u32 initTxGain,
-                               int txPower,
-                               u8 *pPDADCValues)
-{
-       u32 i;
-       u32 offset;
-
-       REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL6_0,
-                       AR_PHY_TX_PWRCTRL_ERR_EST_MODE, 3);
-       REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL6_1,
-                       AR_PHY_TX_PWRCTRL_ERR_EST_MODE, 3);
-
-       REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL7,
-                       AR_PHY_TX_PWRCTRL_INIT_TX_GAIN, initTxGain);
-
-       offset = txPower;
-       for (i = 0; i < AR5416_NUM_PDADC_VALUES; i++)
-               if (i < offset)
-                       pPDADCValues[i] = 0x0;
-               else
-                       pPDADCValues[i] = 0xFF;
-}
-
-
-
-
-static void ath9k_hw_get_target_powers(struct ath_hw *ah,
-                                      struct ath9k_channel *chan,
-                                      struct cal_target_power_ht *powInfo,
-                                      u16 numChannels,
-                                      struct cal_target_power_ht *pNewPower,
-                                      u16 numRates, bool isHt40Target)
-{
-       struct chan_centers centers;
-       u16 clo, chi;
-       int i;
-       int matchIndex = -1, lowIndex = -1;
-       u16 freq;
-
-       ath9k_hw_get_channel_centers(ah, chan, &centers);
-       freq = isHt40Target ? centers.synth_center : centers.ctl_center;
-
-       if (freq <= ath9k_hw_fbin2freq(powInfo[0].bChannel, IS_CHAN_2GHZ(chan))) {
-               matchIndex = 0;
-       } else {
-               for (i = 0; (i < numChannels) &&
-                            (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
-                       if (freq == ath9k_hw_fbin2freq(powInfo[i].bChannel,
-                                                      IS_CHAN_2GHZ(chan))) {
-                               matchIndex = i;
-                               break;
-                       } else
-                               if ((freq < ath9k_hw_fbin2freq(powInfo[i].bChannel,
-                                                      IS_CHAN_2GHZ(chan))) &&
-                                   (freq > ath9k_hw_fbin2freq(powInfo[i - 1].bChannel,
-                                                      IS_CHAN_2GHZ(chan)))) {
-                                       lowIndex = i - 1;
-                                       break;
-                               }
-               }
-               if ((matchIndex == -1) && (lowIndex == -1))
-                       matchIndex = i - 1;
-       }
-
-       if (matchIndex != -1) {
-               *pNewPower = powInfo[matchIndex];
-       } else {
-               clo = ath9k_hw_fbin2freq(powInfo[lowIndex].bChannel,
-                                        IS_CHAN_2GHZ(chan));
-               chi = ath9k_hw_fbin2freq(powInfo[lowIndex + 1].bChannel,
-                                        IS_CHAN_2GHZ(chan));
-
-               for (i = 0; i < numRates; i++) {
-                       pNewPower->tPow2x[i] = (u8)ath9k_hw_interpolate(freq,
-                                               clo, chi,
-                                               powInfo[lowIndex].tPow2x[i],
-                                               powInfo[lowIndex + 1].tPow2x[i]);
-               }
-       }
-}
-
-static u16 ath9k_hw_get_max_edge_power(u16 freq,
-                                      struct cal_ctl_edges *pRdEdgesPower,
-                                      bool is2GHz, int num_band_edges)
-{
-       u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
-       int i;
-
-       for (i = 0; (i < num_band_edges) &&
-                    (pRdEdgesPower[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
-               if (freq == ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel, is2GHz)) {
-                       twiceMaxEdgePower = pRdEdgesPower[i].tPower;
-                       break;
-               } else if ((i > 0) &&
-                          (freq < ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel,
-                                                     is2GHz))) {
-                       if (ath9k_hw_fbin2freq(pRdEdgesPower[i - 1].bChannel,
-                                              is2GHz) < freq &&
-                           pRdEdgesPower[i - 1].flag) {
-                               twiceMaxEdgePower =
-                                       pRdEdgesPower[i - 1].tPower;
-                       }
-                       break;
-               }
-       }
-
-       return twiceMaxEdgePower;
-}
-
-/****************************************/
-/* EEPROM Operations for 4K sized cards */
-/****************************************/
-
-static int ath9k_hw_4k_get_eeprom_ver(struct ath_hw *ah)
-{
-       return ((ah->eeprom.map4k.baseEepHeader.version >> 12) & 0xF);
-}
-
-static int ath9k_hw_4k_get_eeprom_rev(struct ath_hw *ah)
-{
-       return ((ah->eeprom.map4k.baseEepHeader.version) & 0xFFF);
-}
-
-static bool ath9k_hw_4k_fill_eeprom(struct ath_hw *ah)
-{
-#define SIZE_EEPROM_4K (sizeof(struct ar5416_eeprom_4k) / sizeof(u16))
-       u16 *eep_data = (u16 *)&ah->eeprom.map4k;
-       int addr, eep_start_loc = 0;
-
-       eep_start_loc = 64;
-
-       if (!ath9k_hw_use_flash(ah)) {
-               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-                       "Reading from EEPROM, not flash\n");
-       }
-
-       for (addr = 0; addr < SIZE_EEPROM_4K; addr++) {
-               if (!ath9k_hw_nvram_read(ah, addr + eep_start_loc, eep_data)) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-                              "Unable to read eeprom region \n");
-                       return false;
-               }
-               eep_data++;
-       }
-
-       return true;
-#undef SIZE_EEPROM_4K
-}
-
-static int ath9k_hw_4k_check_eeprom(struct ath_hw *ah)
-{
-#define EEPROM_4K_SIZE (sizeof(struct ar5416_eeprom_4k) / sizeof(u16))
-       struct ar5416_eeprom_4k *eep =
-               (struct ar5416_eeprom_4k *) &ah->eeprom.map4k;
-       u16 *eepdata, temp, magic, magic2;
-       u32 sum = 0, el;
-       bool need_swap = false;
-       int i, addr;
-
-
-       if (!ath9k_hw_use_flash(ah)) {
-               if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET,
-                                        &magic)) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-                               "Reading Magic # failed\n");
-                       return false;
-               }
-
-               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-                       "Read Magic = 0x%04X\n", magic);
-
-               if (magic != AR5416_EEPROM_MAGIC) {
-                       magic2 = swab16(magic);
-
-                       if (magic2 == AR5416_EEPROM_MAGIC) {
-                               need_swap = true;
-                               eepdata = (u16 *) (&ah->eeprom);
-
-                               for (addr = 0; addr < EEPROM_4K_SIZE; addr++) {
-                                       temp = swab16(*eepdata);
-                                       *eepdata = temp;
-                                       eepdata++;
-                               }
-                       } else {
-                               DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-                                       "Invalid EEPROM Magic. "
-                                       "endianness mismatch.\n");
-                               return -EINVAL;
-                       }
-               }
-       }
-
-       DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "need_swap = %s.\n",
-               need_swap ? "True" : "False");
-
-       if (need_swap)
-               el = swab16(ah->eeprom.map4k.baseEepHeader.length);
-       else
-               el = ah->eeprom.map4k.baseEepHeader.length;
-
-       if (el > sizeof(struct ar5416_eeprom_4k))
-               el = sizeof(struct ar5416_eeprom_4k) / sizeof(u16);
-       else
-               el = el / sizeof(u16);
-
-       eepdata = (u16 *)(&ah->eeprom);
-
-       for (i = 0; i < el; i++)
-               sum ^= *eepdata++;
-
-       if (need_swap) {
-               u32 integer;
-               u16 word;
-
-               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-                       "EEPROM Endianness is not native.. Changing\n");
-
-               word = swab16(eep->baseEepHeader.length);
-               eep->baseEepHeader.length = word;
-
-               word = swab16(eep->baseEepHeader.checksum);
-               eep->baseEepHeader.checksum = word;
-
-               word = swab16(eep->baseEepHeader.version);
-               eep->baseEepHeader.version = word;
-
-               word = swab16(eep->baseEepHeader.regDmn[0]);
-               eep->baseEepHeader.regDmn[0] = word;
-
-               word = swab16(eep->baseEepHeader.regDmn[1]);
-               eep->baseEepHeader.regDmn[1] = word;
-
-               word = swab16(eep->baseEepHeader.rfSilent);
-               eep->baseEepHeader.rfSilent = word;
-
-               word = swab16(eep->baseEepHeader.blueToothOptions);
-               eep->baseEepHeader.blueToothOptions = word;
-
-               word = swab16(eep->baseEepHeader.deviceCap);
-               eep->baseEepHeader.deviceCap = word;
-
-               integer = swab32(eep->modalHeader.antCtrlCommon);
-               eep->modalHeader.antCtrlCommon = integer;
-
-               for (i = 0; i < AR5416_MAX_CHAINS; i++) {
-                       integer = swab32(eep->modalHeader.antCtrlChain[i]);
-                       eep->modalHeader.antCtrlChain[i] = integer;
-               }
-
-               for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) {
-                       word = swab16(eep->modalHeader.spurChans[i].spurChan);
-                       eep->modalHeader.spurChans[i].spurChan = word;
-               }
-       }
-
-       if (sum != 0xffff || ah->eep_ops->get_eeprom_ver(ah) != AR5416_EEP_VER ||
-           ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_NO_BACK_VER) {
-               DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-                       "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
-                       sum, ah->eep_ops->get_eeprom_ver(ah));
-               return -EINVAL;
-       }
-
-       return 0;
-#undef EEPROM_4K_SIZE
-}
-
-static u32 ath9k_hw_4k_get_eeprom(struct ath_hw *ah,
-                                 enum eeprom_param param)
-{
-       struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
-       struct modal_eep_4k_header *pModal = &eep->modalHeader;
-       struct base_eep_header_4k *pBase = &eep->baseEepHeader;
-
-       switch (param) {
-       case EEP_NFTHRESH_2:
-               return pModal->noiseFloorThreshCh[0];
-       case AR_EEPROM_MAC(0):
-               return pBase->macAddr[0] << 8 | pBase->macAddr[1];
-       case AR_EEPROM_MAC(1):
-               return pBase->macAddr[2] << 8 | pBase->macAddr[3];
-       case AR_EEPROM_MAC(2):
-               return pBase->macAddr[4] << 8 | pBase->macAddr[5];
-       case EEP_REG_0:
-               return pBase->regDmn[0];
-       case EEP_REG_1:
-               return pBase->regDmn[1];
-       case EEP_OP_CAP:
-               return pBase->deviceCap;
-       case EEP_OP_MODE:
-               return pBase->opCapFlags;
-       case EEP_RF_SILENT:
-               return pBase->rfSilent;
-       case EEP_OB_2:
-               return pModal->ob_01;
-       case EEP_DB_2:
-               return pModal->db1_01;
-       case EEP_MINOR_REV:
-               return pBase->version & AR5416_EEP_VER_MINOR_MASK;
-       case EEP_TX_MASK:
-               return pBase->txMask;
-       case EEP_RX_MASK:
-               return pBase->rxMask;
-       case EEP_FRAC_N_5G:
-               return 0;
-       default:
-               return 0;
-       }
-}
-
-static void ath9k_hw_get_4k_gain_boundaries_pdadcs(struct ath_hw *ah,
-                               struct ath9k_channel *chan,
-                               struct cal_data_per_freq_4k *pRawDataSet,
-                               u8 *bChans, u16 availPiers,
-                               u16 tPdGainOverlap, int16_t *pMinCalPower,
-                               u16 *pPdGainBoundaries, u8 *pPDADCValues,
-                               u16 numXpdGains)
-{
-#define TMP_VAL_VPD_TABLE \
-       ((vpdTableI[i][sizeCurrVpdTable - 1] + (ss - maxIndex + 1) * vpdStep));
-       int i, j, k;
-       int16_t ss;
-       u16 idxL = 0, idxR = 0, numPiers;
-       static u8 vpdTableL[AR5416_EEP4K_NUM_PD_GAINS]
-               [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
-       static u8 vpdTableR[AR5416_EEP4K_NUM_PD_GAINS]
-               [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
-       static u8 vpdTableI[AR5416_EEP4K_NUM_PD_GAINS]
-               [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
-
-       u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR;
-       u8 minPwrT4[AR5416_EEP4K_NUM_PD_GAINS];
-       u8 maxPwrT4[AR5416_EEP4K_NUM_PD_GAINS];
-       int16_t vpdStep;
-       int16_t tmpVal;
-       u16 sizeCurrVpdTable, maxIndex, tgtIndex;
-       bool match;
-       int16_t minDelta = 0;
-       struct chan_centers centers;
-#define PD_GAIN_BOUNDARY_DEFAULT 58;
-
-       ath9k_hw_get_channel_centers(ah, chan, &centers);
-
-       for (numPiers = 0; numPiers < availPiers; numPiers++) {
-               if (bChans[numPiers] == AR5416_BCHAN_UNUSED)
-                       break;
-       }
-
-       match = ath9k_hw_get_lower_upper_index(
-                                       (u8)FREQ2FBIN(centers.synth_center,
-                                       IS_CHAN_2GHZ(chan)), bChans, numPiers,
-                                       &idxL, &idxR);
-
-       if (match) {
-               for (i = 0; i < numXpdGains; i++) {
-                       minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0];
-                       maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4];
-                       ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
-                                       pRawDataSet[idxL].pwrPdg[i],
-                                       pRawDataSet[idxL].vpdPdg[i],
-                                       AR5416_EEP4K_PD_GAIN_ICEPTS,
-                                       vpdTableI[i]);
-               }
-       } else {
-               for (i = 0; i < numXpdGains; i++) {
-                       pVpdL = pRawDataSet[idxL].vpdPdg[i];
-                       pPwrL = pRawDataSet[idxL].pwrPdg[i];
-                       pVpdR = pRawDataSet[idxR].vpdPdg[i];
-                       pPwrR = pRawDataSet[idxR].pwrPdg[i];
-
-                       minPwrT4[i] = max(pPwrL[0], pPwrR[0]);
-
-                       maxPwrT4[i] =
-                               min(pPwrL[AR5416_EEP4K_PD_GAIN_ICEPTS - 1],
-                                   pPwrR[AR5416_EEP4K_PD_GAIN_ICEPTS - 1]);
-
-
-                       ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
-                                               pPwrL, pVpdL,
-                                               AR5416_EEP4K_PD_GAIN_ICEPTS,
-                                               vpdTableL[i]);
-                       ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
-                                               pPwrR, pVpdR,
-                                               AR5416_EEP4K_PD_GAIN_ICEPTS,
-                                               vpdTableR[i]);
-
-                       for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
-                               vpdTableI[i][j] =
-                                       (u8)(ath9k_hw_interpolate((u16)
-                                            FREQ2FBIN(centers.
-                                                      synth_center,
-                                                      IS_CHAN_2GHZ
-                                                      (chan)),
-                                            bChans[idxL], bChans[idxR],
-                                            vpdTableL[i][j], vpdTableR[i][j]));
-                       }
-               }
-       }
-
-       *pMinCalPower = (int16_t)(minPwrT4[0] / 2);
-
-       k = 0;
-
-       for (i = 0; i < numXpdGains; i++) {
-               if (i == (numXpdGains - 1))
-                       pPdGainBoundaries[i] =
-                               (u16)(maxPwrT4[i] / 2);
-               else
-                       pPdGainBoundaries[i] =
-                               (u16)((maxPwrT4[i] + minPwrT4[i + 1]) / 4);
-
-               pPdGainBoundaries[i] =
-                       min((u16)AR5416_MAX_RATE_POWER, pPdGainBoundaries[i]);
-
-               if ((i == 0) && !AR_SREV_5416_20_OR_LATER(ah)) {
-                       minDelta = pPdGainBoundaries[0] - 23;
-                       pPdGainBoundaries[0] = 23;
-               } else {
-                       minDelta = 0;
-               }
-
-               if (i == 0) {
-                       if (AR_SREV_9280_10_OR_LATER(ah))
-                               ss = (int16_t)(0 - (minPwrT4[i] / 2));
-                       else
-                               ss = 0;
-               } else {
-                       ss = (int16_t)((pPdGainBoundaries[i - 1] -
-                                       (minPwrT4[i] / 2)) -
-                                      tPdGainOverlap + 1 + minDelta);
-               }
-               vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]);
-               vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
-
-               while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
-                       tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep);
-                       pPDADCValues[k++] = (u8)((tmpVal < 0) ? 0 : tmpVal);
-                       ss++;
-               }
-
-               sizeCurrVpdTable = (u8) ((maxPwrT4[i] - minPwrT4[i]) / 2 + 1);
-               tgtIndex = (u8)(pPdGainBoundaries[i] + tPdGainOverlap -
-                               (minPwrT4[i] / 2));
-               maxIndex = (tgtIndex < sizeCurrVpdTable) ?
-                       tgtIndex : sizeCurrVpdTable;
-
-               while ((ss < maxIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1)))
-                       pPDADCValues[k++] = vpdTableI[i][ss++];
-
-               vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] -
-                                   vpdTableI[i][sizeCurrVpdTable - 2]);
-               vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
-
-               if (tgtIndex >= maxIndex) {
-                       while ((ss <= tgtIndex) &&
-                              (k < (AR5416_NUM_PDADC_VALUES - 1))) {
-                               tmpVal = (int16_t) TMP_VAL_VPD_TABLE;
-                               pPDADCValues[k++] = (u8)((tmpVal > 255) ?
-                                                        255 : tmpVal);
-                               ss++;
-                       }
-               }
-       }
-
-       while (i < AR5416_EEP4K_PD_GAINS_IN_MASK) {
-               pPdGainBoundaries[i] = PD_GAIN_BOUNDARY_DEFAULT;
-               i++;
-       }
-
-       while (k < AR5416_NUM_PDADC_VALUES) {
-               pPDADCValues[k] = pPDADCValues[k - 1];
-               k++;
-       }
-
-       return;
-#undef TMP_VAL_VPD_TABLE
-}
-
-static bool ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
-                                 struct ath9k_channel *chan,
-                                 int16_t *pTxPowerIndexOffset)
-{
-       struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k;
-       struct cal_data_per_freq_4k *pRawDataset;
-       u8 *pCalBChans = NULL;
-       u16 pdGainOverlap_t2;
-       static u8 pdadcValues[AR5416_NUM_PDADC_VALUES];
-       u16 gainBoundaries[AR5416_EEP4K_PD_GAINS_IN_MASK];
-       u16 numPiers, i, j;
-       int16_t tMinCalPower;
-       u16 numXpdGain, xpdMask;
-       u16 xpdGainValues[AR5416_EEP4K_NUM_PD_GAINS] = { 0, 0 };
-       u32 reg32, regOffset, regChainOffset;
-
-       xpdMask = pEepData->modalHeader.xpdGain;
-
-       if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
-           AR5416_EEP_MINOR_VER_2) {
-               pdGainOverlap_t2 =
-                       pEepData->modalHeader.pdGainOverlap;
-       } else {
-               pdGainOverlap_t2 = (u16)(MS(REG_READ(ah, AR_PHY_TPCRG5),
-                                           AR_PHY_TPCRG5_PD_GAIN_OVERLAP));
-       }
-
-       pCalBChans = pEepData->calFreqPier2G;
-       numPiers = AR5416_EEP4K_NUM_2G_CAL_PIERS;
-
-       numXpdGain = 0;
-
-       for (i = 1; i <= AR5416_EEP4K_PD_GAINS_IN_MASK; i++) {
-               if ((xpdMask >> (AR5416_EEP4K_PD_GAINS_IN_MASK - i)) & 1) {
-                       if (numXpdGain >= AR5416_EEP4K_NUM_PD_GAINS)
-                               break;
-                       xpdGainValues[numXpdGain] =
-                               (u16)(AR5416_EEP4K_PD_GAINS_IN_MASK - i);
-                       numXpdGain++;
-               }
-       }
-
-       REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN,
-                     (numXpdGain - 1) & 0x3);
-       REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1,
-                     xpdGainValues[0]);
-       REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2,
-                     xpdGainValues[1]);
-       REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3, 0);
-
-       for (i = 0; i < AR5416_EEP4K_MAX_CHAINS; i++) {
-               if (AR_SREV_5416_20_OR_LATER(ah) &&
-                   (ah->rxchainmask == 5 || ah->txchainmask == 5) &&
-                   (i != 0)) {
-                       regChainOffset = (i == 1) ? 0x2000 : 0x1000;
-               } else
-                       regChainOffset = i * 0x1000;
-
-               if (pEepData->baseEepHeader.txMask & (1 << i)) {
-                       pRawDataset = pEepData->calPierData2G[i];
-
-                       ath9k_hw_get_4k_gain_boundaries_pdadcs(ah, chan,
-                                           pRawDataset, pCalBChans,
-                                           numPiers, pdGainOverlap_t2,
-                                           &tMinCalPower, gainBoundaries,
-                                           pdadcValues, numXpdGain);
-
-                       if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah)) {
-                               REG_WRITE(ah, AR_PHY_TPCRG5 + regChainOffset,
-                                         SM(pdGainOverlap_t2,
-                                            AR_PHY_TPCRG5_PD_GAIN_OVERLAP)
-                                         | SM(gainBoundaries[0],
-                                              AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1)
-                                         | SM(gainBoundaries[1],
-                                              AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2)
-                                         | SM(gainBoundaries[2],
-                                              AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3)
-                                         | SM(gainBoundaries[3],
-                                      AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4));
-                       }
-
-                       regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset;
-                       for (j = 0; j < 32; j++) {
-                               reg32 = ((pdadcValues[4 * j + 0] & 0xFF) << 0) |
-                                       ((pdadcValues[4 * j + 1] & 0xFF) << 8) |
-                                       ((pdadcValues[4 * j + 2] & 0xFF) << 16)|
-                                       ((pdadcValues[4 * j + 3] & 0xFF) << 24);
-                               REG_WRITE(ah, regOffset, reg32);
-
-                               DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
-                                       "PDADC (%d,%4x): %4.4x %8.8x\n",
-                                       i, regChainOffset, regOffset,
-                                       reg32);
-                               DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
-                                       "PDADC: Chain %d | "
-                                       "PDADC %3d Value %3d | "
-                                       "PDADC %3d Value %3d | "
-                                       "PDADC %3d Value %3d | "
-                                       "PDADC %3d Value %3d |\n",
-                                       i, 4 * j, pdadcValues[4 * j],
-                                       4 * j + 1, pdadcValues[4 * j + 1],
-                                       4 * j + 2, pdadcValues[4 * j + 2],
-                                       4 * j + 3,
-                                       pdadcValues[4 * j + 3]);
-
-                               regOffset += 4;
-                       }
-               }
-       }
-
-       *pTxPowerIndexOffset = 0;
-
-       return true;
-}
-
-static bool ath9k_hw_set_4k_power_per_rate_table(struct ath_hw *ah,
-                                                struct ath9k_channel *chan,
-                                                int16_t *ratesArray,
-                                                u16 cfgCtl,
-                                                u16 AntennaReduction,
-                                                u16 twiceMaxRegulatoryPower,
-                                                u16 powerLimit)
-{
-       struct ar5416_eeprom_4k *pEepData = &ah->eeprom.map4k;
-       u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
-       static const u16 tpScaleReductionTable[5] =
-               { 0, 3, 6, 9, AR5416_MAX_RATE_POWER };
-
-       int i;
-       int16_t twiceLargestAntenna;
-       struct cal_ctl_data_4k *rep;
-       struct cal_target_power_leg targetPowerOfdm, targetPowerCck = {
-               0, { 0, 0, 0, 0}
-       };
-       struct cal_target_power_leg targetPowerOfdmExt = {
-               0, { 0, 0, 0, 0} }, targetPowerCckExt = {
-               0, { 0, 0, 0, 0 }
-       };
-       struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = {
-               0, {0, 0, 0, 0}
-       };
-       u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
-       u16 ctlModesFor11g[] =
-               { CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT,
-                 CTL_2GHT40
-               };
-       u16 numCtlModes, *pCtlMode, ctlMode, freq;
-       struct chan_centers centers;
-       int tx_chainmask;
-       u16 twiceMinEdgePower;
-
-       tx_chainmask = ah->txchainmask;
-
-       ath9k_hw_get_channel_centers(ah, chan, &centers);
-
-       twiceLargestAntenna = pEepData->modalHeader.antennaGainCh[0];
-
-       twiceLargestAntenna = (int16_t)min(AntennaReduction -
-                                          twiceLargestAntenna, 0);
-
-       maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
-
-       if (ah->regulatory.tp_scale != ATH9K_TP_SCALE_MAX) {
-               maxRegAllowedPower -=
-                       (tpScaleReductionTable[(ah->regulatory.tp_scale)] * 2);
-       }
-
-       scaledPower = min(powerLimit, maxRegAllowedPower);
-       scaledPower = max((u16)0, scaledPower);
-
-       numCtlModes = ARRAY_SIZE(ctlModesFor11g) - SUB_NUM_CTL_MODES_AT_2G_40;
-       pCtlMode = ctlModesFor11g;
-
-       ath9k_hw_get_legacy_target_powers(ah, chan,
-                       pEepData->calTargetPowerCck,
-                       AR5416_NUM_2G_CCK_TARGET_POWERS,
-                       &targetPowerCck, 4, false);
-       ath9k_hw_get_legacy_target_powers(ah, chan,
-                       pEepData->calTargetPower2G,
-                       AR5416_NUM_2G_20_TARGET_POWERS,
-                       &targetPowerOfdm, 4, false);
-       ath9k_hw_get_target_powers(ah, chan,
-                       pEepData->calTargetPower2GHT20,
-                       AR5416_NUM_2G_20_TARGET_POWERS,
-                       &targetPowerHt20, 8, false);
-
-       if (IS_CHAN_HT40(chan)) {
-               numCtlModes = ARRAY_SIZE(ctlModesFor11g);
-               ath9k_hw_get_target_powers(ah, chan,
-                               pEepData->calTargetPower2GHT40,
-                               AR5416_NUM_2G_40_TARGET_POWERS,
-                               &targetPowerHt40, 8, true);
-               ath9k_hw_get_legacy_target_powers(ah, chan,
-                               pEepData->calTargetPowerCck,
-                               AR5416_NUM_2G_CCK_TARGET_POWERS,
-                               &targetPowerCckExt, 4, true);
-               ath9k_hw_get_legacy_target_powers(ah, chan,
-                               pEepData->calTargetPower2G,
-                               AR5416_NUM_2G_20_TARGET_POWERS,
-                               &targetPowerOfdmExt, 4, true);
-       }
-
-       for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
-               bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) ||
-                       (pCtlMode[ctlMode] == CTL_2GHT40);
-               if (isHt40CtlMode)
-                       freq = centers.synth_center;
-               else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
-                       freq = centers.ext_center;
-               else
-                       freq = centers.ctl_center;
-
-               if (ah->eep_ops->get_eeprom_ver(ah) == 14 &&
-                   ah->eep_ops->get_eeprom_rev(ah) <= 2)
-                       twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
-
-               DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
-                       "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, "
-                       "EXT_ADDITIVE %d\n",
-                       ctlMode, numCtlModes, isHt40CtlMode,
-                       (pCtlMode[ctlMode] & EXT_ADDITIVE));
-
-               for (i = 0; (i < AR5416_NUM_CTLS) &&
-                               pEepData->ctlIndex[i]; i++) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
-                               "  LOOP-Ctlidx %d: cfgCtl 0x%2.2x "
-                               "pCtlMode 0x%2.2x ctlIndex 0x%2.2x "
-                               "chan %d\n",
-                               i, cfgCtl, pCtlMode[ctlMode],
-                               pEepData->ctlIndex[i], chan->channel);
-
-                       if ((((cfgCtl & ~CTL_MODE_M) |
-                             (pCtlMode[ctlMode] & CTL_MODE_M)) ==
-                            pEepData->ctlIndex[i]) ||
-                           (((cfgCtl & ~CTL_MODE_M) |
-                             (pCtlMode[ctlMode] & CTL_MODE_M)) ==
-                            ((pEepData->ctlIndex[i] & CTL_MODE_M) |
-                             SD_NO_CTL))) {
-                               rep = &(pEepData->ctlData[i]);
-
-                               twiceMinEdgePower =
-                                       ath9k_hw_get_max_edge_power(freq,
-                               rep->ctlEdges[ar5416_get_ntxchains
-                                               (tx_chainmask) - 1],
-                               IS_CHAN_2GHZ(chan),
-                               AR5416_EEP4K_NUM_BAND_EDGES);
-
-                               DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
-                                       "    MATCH-EE_IDX %d: ch %d is2 %d "
-                                       "2xMinEdge %d chainmask %d chains %d\n",
-                                       i, freq, IS_CHAN_2GHZ(chan),
-                                       twiceMinEdgePower, tx_chainmask,
-                                       ar5416_get_ntxchains
-                                       (tx_chainmask));
-                               if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) {
-                                       twiceMaxEdgePower =
-                                               min(twiceMaxEdgePower,
-                                                   twiceMinEdgePower);
-                               } else {
-                                       twiceMaxEdgePower = twiceMinEdgePower;
-                                       break;
-                               }
-                       }
-               }
-
-               minCtlPower = (u8)min(twiceMaxEdgePower, scaledPower);
-
-               DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
-                       "    SEL-Min ctlMode %d pCtlMode %d "
-                       "2xMaxEdge %d sP %d minCtlPwr %d\n",
-                       ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower,
-                       scaledPower, minCtlPower);
-
-               switch (pCtlMode[ctlMode]) {
-               case CTL_11B:
-                       for (i = 0; i < ARRAY_SIZE(targetPowerCck.tPow2x);
-                                       i++) {
-                               targetPowerCck.tPow2x[i] =
-                                       min((u16)targetPowerCck.tPow2x[i],
-                                           minCtlPower);
-                       }
-                       break;
-               case CTL_11G:
-                       for (i = 0; i < ARRAY_SIZE(targetPowerOfdm.tPow2x);
-                                       i++) {
-                               targetPowerOfdm.tPow2x[i] =
-                                       min((u16)targetPowerOfdm.tPow2x[i],
-                                           minCtlPower);
-                       }
-                       break;
-               case CTL_2GHT20:
-                       for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x);
-                                       i++) {
-                               targetPowerHt20.tPow2x[i] =
-                                       min((u16)targetPowerHt20.tPow2x[i],
-                                           minCtlPower);
-                       }
-                       break;
-               case CTL_11B_EXT:
-                       targetPowerCckExt.tPow2x[0] = min((u16)
-                                       targetPowerCckExt.tPow2x[0],
-                                       minCtlPower);
-                       break;
-               case CTL_11G_EXT:
-                       targetPowerOfdmExt.tPow2x[0] = min((u16)
-                                       targetPowerOfdmExt.tPow2x[0],
-                                       minCtlPower);
-                       break;
-               case CTL_2GHT40:
-                       for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x);
-                                       i++) {
-                               targetPowerHt40.tPow2x[i] =
-                                       min((u16)targetPowerHt40.tPow2x[i],
-                                           minCtlPower);
-                       }
-                       break;
-               default:
-                       break;
-               }
-       }
-
-       ratesArray[rate6mb] = ratesArray[rate9mb] = ratesArray[rate12mb] =
-               ratesArray[rate18mb] = ratesArray[rate24mb] =
-               targetPowerOfdm.tPow2x[0];
-       ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1];
-       ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2];
-       ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3];
-       ratesArray[rateXr] = targetPowerOfdm.tPow2x[0];
-
-       for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++)
-               ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i];
-
-       ratesArray[rate1l] = targetPowerCck.tPow2x[0];
-       ratesArray[rate2s] = ratesArray[rate2l] = targetPowerCck.tPow2x[1];
-       ratesArray[rate5_5s] = ratesArray[rate5_5l] = targetPowerCck.tPow2x[2];
-       ratesArray[rate11s] = ratesArray[rate11l] = targetPowerCck.tPow2x[3];
-
-       if (IS_CHAN_HT40(chan)) {
-               for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
-                       ratesArray[rateHt40_0 + i] =
-                               targetPowerHt40.tPow2x[i];
-               }
-               ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0];
-               ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0];
-               ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0];
-               ratesArray[rateExtCck] = targetPowerCckExt.tPow2x[0];
-       }
-       return true;
-}
-
-static int ath9k_hw_4k_set_txpower(struct ath_hw *ah,
-                                  struct ath9k_channel *chan,
-                                  u16 cfgCtl,
-                                  u8 twiceAntennaReduction,
-                                  u8 twiceMaxRegulatoryPower,
-                                  u8 powerLimit)
-{
-       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;
-
-       memset(ratesArray, 0, sizeof(ratesArray));
-
-       if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
-           AR5416_EEP_MINOR_VER_2) {
-               ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
-       }
-
-       if (!ath9k_hw_set_4k_power_per_rate_table(ah, chan,
-                                              &ratesArray[0], cfgCtl,
-                                              twiceAntennaReduction,
-                                              twiceMaxRegulatoryPower,
-                                              powerLimit)) {
-               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-                       "ath9k_hw_set_txpower: unable to set "
-                       "tx power per rate table\n");
-               return -EIO;
-       }
-
-       if (!ath9k_hw_set_4k_power_cal_table(ah, chan, &txPowerIndexOffset)) {
-               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-                        "ath9k_hw_set_txpower: unable to set power table\n");
-               return -EIO;
-       }
-
-       for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
-               ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]);
-               if (ratesArray[i] > AR5416_MAX_RATE_POWER)
-                       ratesArray[i] = AR5416_MAX_RATE_POWER;
-       }
-
-       if (AR_SREV_9280_10_OR_LATER(ah)) {
-               for (i = 0; i < Ar5416RateSize; i++)
-                       ratesArray[i] -= AR5416_PWR_TABLE_OFFSET * 2;
-       }
-
-       REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
-                 ATH9K_POW_SM(ratesArray[rate18mb], 24)
-                 | ATH9K_POW_SM(ratesArray[rate12mb], 16)
-                 | ATH9K_POW_SM(ratesArray[rate9mb], 8)
-                 | ATH9K_POW_SM(ratesArray[rate6mb], 0));
-       REG_WRITE(ah, AR_PHY_POWER_TX_RATE2,
-                 ATH9K_POW_SM(ratesArray[rate54mb], 24)
-                 | ATH9K_POW_SM(ratesArray[rate48mb], 16)
-                 | ATH9K_POW_SM(ratesArray[rate36mb], 8)
-                 | ATH9K_POW_SM(ratesArray[rate24mb], 0));
-
-       if (IS_CHAN_2GHZ(chan)) {
-               REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
-                         ATH9K_POW_SM(ratesArray[rate2s], 24)
-                         | ATH9K_POW_SM(ratesArray[rate2l], 16)
-                         | ATH9K_POW_SM(ratesArray[rateXr], 8)
-                         | ATH9K_POW_SM(ratesArray[rate1l], 0));
-               REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
-                         ATH9K_POW_SM(ratesArray[rate11s], 24)
-                         | ATH9K_POW_SM(ratesArray[rate11l], 16)
-                         | ATH9K_POW_SM(ratesArray[rate5_5s], 8)
-                         | ATH9K_POW_SM(ratesArray[rate5_5l], 0));
-       }
-
-       REG_WRITE(ah, AR_PHY_POWER_TX_RATE5,
-                 ATH9K_POW_SM(ratesArray[rateHt20_3], 24)
-                 | ATH9K_POW_SM(ratesArray[rateHt20_2], 16)
-                 | ATH9K_POW_SM(ratesArray[rateHt20_1], 8)
-                 | ATH9K_POW_SM(ratesArray[rateHt20_0], 0));
-       REG_WRITE(ah, AR_PHY_POWER_TX_RATE6,
-                 ATH9K_POW_SM(ratesArray[rateHt20_7], 24)
-                 | ATH9K_POW_SM(ratesArray[rateHt20_6], 16)
-                 | ATH9K_POW_SM(ratesArray[rateHt20_5], 8)
-                 | ATH9K_POW_SM(ratesArray[rateHt20_4], 0));
-
-       if (IS_CHAN_HT40(chan)) {
-               REG_WRITE(ah, AR_PHY_POWER_TX_RATE7,
-                         ATH9K_POW_SM(ratesArray[rateHt40_3] +
-                                      ht40PowerIncForPdadc, 24)
-                         | ATH9K_POW_SM(ratesArray[rateHt40_2] +
-                                        ht40PowerIncForPdadc, 16)
-                         | ATH9K_POW_SM(ratesArray[rateHt40_1] +
-                                        ht40PowerIncForPdadc, 8)
-                         | ATH9K_POW_SM(ratesArray[rateHt40_0] +
-                                        ht40PowerIncForPdadc, 0));
-               REG_WRITE(ah, AR_PHY_POWER_TX_RATE8,
-                         ATH9K_POW_SM(ratesArray[rateHt40_7] +
-                                      ht40PowerIncForPdadc, 24)
-                         | ATH9K_POW_SM(ratesArray[rateHt40_6] +
-                                        ht40PowerIncForPdadc, 16)
-                         | ATH9K_POW_SM(ratesArray[rateHt40_5] +
-                                        ht40PowerIncForPdadc, 8)
-                         | ATH9K_POW_SM(ratesArray[rateHt40_4] +
-                                        ht40PowerIncForPdadc, 0));
-
-               REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
-                         ATH9K_POW_SM(ratesArray[rateExtOfdm], 24)
-                         | ATH9K_POW_SM(ratesArray[rateExtCck], 16)
-                         | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
-                         | ATH9K_POW_SM(ratesArray[rateDupCck], 0));
-       }
-
-       i = rate6mb;
-
-       if (IS_CHAN_HT40(chan))
-               i = rateHt40_0;
-       else if (IS_CHAN_HT20(chan))
-               i = rateHt20_0;
-
-       if (AR_SREV_9280_10_OR_LATER(ah))
-               ah->regulatory.max_power_level =
-                       ratesArray[i] + AR5416_PWR_TABLE_OFFSET * 2;
-       else
-               ah->regulatory.max_power_level = ratesArray[i];
-
-       return 0;
-}
-
-static void ath9k_hw_4k_set_addac(struct ath_hw *ah,
-                                 struct ath9k_channel *chan)
-{
-       struct modal_eep_4k_header *pModal;
-       struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
-       u8 biaslevel;
-
-       if (ah->hw_version.macVersion != AR_SREV_VERSION_9160)
-               return;
-
-       if (ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_MINOR_VER_7)
-               return;
-
-       pModal = &eep->modalHeader;
-
-       if (pModal->xpaBiasLvl != 0xff) {
-               biaslevel = pModal->xpaBiasLvl;
-               INI_RA(&ah->iniAddac, 7, 1) =
-                 (INI_RA(&ah->iniAddac, 7, 1) & (~0x18)) | biaslevel << 3;
-       }
-}
-
-static void ath9k_hw_4k_set_gain(struct ath_hw *ah,
-                                struct modal_eep_4k_header *pModal,
-                                struct ar5416_eeprom_4k *eep,
-                                u8 txRxAttenLocal, int regChainOffset)
-{
-       REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset,
-                 pModal->antCtrlChain[0]);
-
-       REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset,
-                 (REG_READ(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset) &
-                  ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |
-                    AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
-                 SM(pModal->iqCalICh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
-                 SM(pModal->iqCalQCh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
-
-       if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
-           AR5416_EEP_MINOR_VER_3) {
-               txRxAttenLocal = pModal->txRxAttenCh[0];
-
-               REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
-                             AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN, pModal->bswMargin[0]);
-               REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
-                             AR_PHY_GAIN_2GHZ_XATTEN1_DB, pModal->bswAtten[0]);
-               REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
-                             AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN,
-                             pModal->xatten2Margin[0]);
-               REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
-                             AR_PHY_GAIN_2GHZ_XATTEN2_DB, pModal->xatten2Db[0]);
-       }
-
-       REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset,
-                     AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal);
-       REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset,
-                     AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[0]);
-
-       if (AR_SREV_9285_11(ah))
-               REG_WRITE(ah, AR9285_AN_TOP4, (AR9285_AN_TOP4_DEFAULT | 0x14));
-}
-
-static void ath9k_hw_4k_set_board_values(struct ath_hw *ah,
-                                        struct ath9k_channel *chan)
-{
-       struct modal_eep_4k_header *pModal;
-       struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
-       u8 txRxAttenLocal;
-       u8 ob[5], db1[5], db2[5];
-       u8 ant_div_control1, ant_div_control2;
-       u32 regVal;
-
-       pModal = &eep->modalHeader;
-       txRxAttenLocal = 23;
-
-       REG_WRITE(ah, AR_PHY_SWITCH_COM,
-                 ah->eep_ops->get_eeprom_antenna_cfg(ah, chan));
-
-       /* Single chain for 4K EEPROM*/
-       ath9k_hw_4k_set_gain(ah, pModal, eep, txRxAttenLocal, 0);
-
-       /* Initialize Ant Diversity settings from EEPROM */
-       if (pModal->version == 3) {
-               ant_div_control1 = ((pModal->ob_234 >> 12) & 0xf);
-               ant_div_control2 = ((pModal->db1_234 >> 12) & 0xf);
-               regVal = REG_READ(ah, 0x99ac);
-               regVal &= (~(0x7f000000));
-               regVal |= ((ant_div_control1 & 0x1) << 24);
-               regVal |= (((ant_div_control1 >> 1) & 0x1) << 29);
-               regVal |= (((ant_div_control1 >> 2) & 0x1) << 30);
-               regVal |= ((ant_div_control2 & 0x3) << 25);
-               regVal |= (((ant_div_control2 >> 2) & 0x3) << 27);
-               REG_WRITE(ah, 0x99ac, regVal);
-               regVal = REG_READ(ah, 0x99ac);
-               regVal = REG_READ(ah, 0xa208);
-               regVal &= (~(0x1 << 13));
-               regVal |= (((ant_div_control1 >> 3) & 0x1) << 13);
-               REG_WRITE(ah, 0xa208, regVal);
-               regVal = REG_READ(ah, 0xa208);
-       }
-
-       if (pModal->version >= 2) {
-               ob[0] = (pModal->ob_01 & 0xf);
-               ob[1] = (pModal->ob_01 >> 4) & 0xf;
-               ob[2] = (pModal->ob_234 & 0xf);
-               ob[3] = ((pModal->ob_234 >> 4) & 0xf);
-               ob[4] = ((pModal->ob_234 >> 8) & 0xf);
-
-               db1[0] = (pModal->db1_01 & 0xf);
-               db1[1] = ((pModal->db1_01 >> 4) & 0xf);
-               db1[2] = (pModal->db1_234 & 0xf);
-               db1[3] = ((pModal->db1_234 >> 4) & 0xf);
-               db1[4] = ((pModal->db1_234 >> 8) & 0xf);
-
-               db2[0] = (pModal->db2_01 & 0xf);
-               db2[1] = ((pModal->db2_01 >> 4) & 0xf);
-               db2[2] = (pModal->db2_234 & 0xf);
-               db2[3] = ((pModal->db2_234 >> 4) & 0xf);
-               db2[4] = ((pModal->db2_234 >> 8) & 0xf);
-
-       } else if (pModal->version == 1) {
-               ob[0] = (pModal->ob_01 & 0xf);
-               ob[1] = ob[2] = ob[3] = ob[4] = (pModal->ob_01 >> 4) & 0xf;
-               db1[0] = (pModal->db1_01 & 0xf);
-               db1[1] = db1[2] = db1[3] =
-                       db1[4] = ((pModal->db1_01 >> 4) & 0xf);
-               db2[0] = (pModal->db2_01 & 0xf);
-               db2[1] = db2[2] = db2[3] =
-                       db2[4] = ((pModal->db2_01 >> 4) & 0xf);
-       } else {
-               int i;
-               for (i = 0; i < 5; i++) {
-                       ob[i] = pModal->ob_01;
-                       db1[i] = pModal->db1_01;
-                       db2[i] = pModal->db1_01;
-               }
-       }
-
-       ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
-                       AR9285_AN_RF2G3_OB_0, AR9285_AN_RF2G3_OB_0_S, ob[0]);
-       ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
-                       AR9285_AN_RF2G3_OB_1, AR9285_AN_RF2G3_OB_1_S, ob[1]);
-       ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
-                       AR9285_AN_RF2G3_OB_2, AR9285_AN_RF2G3_OB_2_S, ob[2]);
-       ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
-                       AR9285_AN_RF2G3_OB_3, AR9285_AN_RF2G3_OB_3_S, ob[3]);
-       ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
-                       AR9285_AN_RF2G3_OB_4, AR9285_AN_RF2G3_OB_4_S, ob[4]);
-
-       ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
-                       AR9285_AN_RF2G3_DB1_0, AR9285_AN_RF2G3_DB1_0_S, db1[0]);
-       ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
-                       AR9285_AN_RF2G3_DB1_1, AR9285_AN_RF2G3_DB1_1_S, db1[1]);
-       ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3,
-                       AR9285_AN_RF2G3_DB1_2, AR9285_AN_RF2G3_DB1_2_S, db1[2]);
-       ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
-                       AR9285_AN_RF2G4_DB1_3, AR9285_AN_RF2G4_DB1_3_S, db1[3]);
-       ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
-                       AR9285_AN_RF2G4_DB1_4, AR9285_AN_RF2G4_DB1_4_S, db1[4]);
-
-       ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
-                       AR9285_AN_RF2G4_DB2_0, AR9285_AN_RF2G4_DB2_0_S, db2[0]);
-       ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
-                       AR9285_AN_RF2G4_DB2_1, AR9285_AN_RF2G4_DB2_1_S, db2[1]);
-       ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
-                       AR9285_AN_RF2G4_DB2_2, AR9285_AN_RF2G4_DB2_2_S, db2[2]);
-       ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
-                       AR9285_AN_RF2G4_DB2_3, AR9285_AN_RF2G4_DB2_3_S, db2[3]);
-       ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4,
-                       AR9285_AN_RF2G4_DB2_4, AR9285_AN_RF2G4_DB2_4_S, db2[4]);
-
-
-       if (AR_SREV_9285_11(ah))
-               REG_WRITE(ah, AR9285_AN_TOP4, AR9285_AN_TOP4_DEFAULT);
-
-       REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH,
-                     pModal->switchSettling);
-       REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC,
-                     pModal->adcDesiredSize);
-
-       REG_WRITE(ah, AR_PHY_RF_CTL4,
-                 SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF) |
-                 SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAB_OFF) |
-                 SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAA_ON)  |
-                 SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAB_ON));
-
-       REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON,
-                     pModal->txEndToRxOn);
-       REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62,
-                     pModal->thresh62);
-       REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0, AR_PHY_EXT_CCA0_THRESH62,
-                     pModal->thresh62);
-
-       if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
-                                               AR5416_EEP_MINOR_VER_2) {
-               REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_DATA_START,
-                             pModal->txFrameToDataStart);
-               REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_PA_ON,
-                             pModal->txFrameToPaOn);
-       }
-
-       if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
-                                               AR5416_EEP_MINOR_VER_3) {
-               if (IS_CHAN_HT40(chan))
-                       REG_RMW_FIELD(ah, AR_PHY_SETTLING,
-                                     AR_PHY_SETTLING_SWITCH,
-                                     pModal->swSettleHt40);
-       }
-}
-
-static u16 ath9k_hw_4k_get_eeprom_antenna_cfg(struct ath_hw *ah,
-                                             struct ath9k_channel *chan)
-{
-       struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
-       struct modal_eep_4k_header *pModal = &eep->modalHeader;
-
-       return pModal->antCtrlCommon & 0xFFFF;
-}
-
-static u8 ath9k_hw_4k_get_num_ant_config(struct ath_hw *ah,
-                                        enum ieee80211_band freq_band)
-{
-       return 1;
-}
-
-static u16 ath9k_hw_4k_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz)
-{
-#define EEP_MAP4K_SPURCHAN \
-       (ah->eeprom.map4k.modalHeader.spurChans[i].spurChan)
-
-       u16 spur_val = AR_NO_SPUR;
-
-       DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-               "Getting spur idx %d is2Ghz. %d val %x\n",
-               i, is2GHz, ah->config.spurchans[i][is2GHz]);
-
-       switch (ah->config.spurmode) {
-       case SPUR_DISABLE:
-               break;
-       case SPUR_ENABLE_IOCTL:
-               spur_val = ah->config.spurchans[i][is2GHz];
-               DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-                       "Getting spur val from new loc. %d\n", spur_val);
-               break;
-       case SPUR_ENABLE_EEPROM:
-               spur_val = EEP_MAP4K_SPURCHAN;
-               break;
-       }
-
-       return spur_val;
-
-#undef EEP_MAP4K_SPURCHAN
-}
-
-static 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,
-       .get_eeprom_ver         = ath9k_hw_4k_get_eeprom_ver,
-       .get_eeprom_rev         = ath9k_hw_4k_get_eeprom_rev,
-       .get_num_ant_config     = ath9k_hw_4k_get_num_ant_config,
-       .get_eeprom_antenna_cfg = ath9k_hw_4k_get_eeprom_antenna_cfg,
-       .set_board_values       = ath9k_hw_4k_set_board_values,
-       .set_addac              = ath9k_hw_4k_set_addac,
-       .set_txpower            = ath9k_hw_4k_set_txpower,
-       .get_spur_channel       = ath9k_hw_4k_get_spur_channel
-};
-
-/************************************************/
-/* EEPROM Operations for non-4K (Default) cards */
-/************************************************/
-
-static int ath9k_hw_def_get_eeprom_ver(struct ath_hw *ah)
-{
-       return ((ah->eeprom.def.baseEepHeader.version >> 12) & 0xF);
-}
-
-static int ath9k_hw_def_get_eeprom_rev(struct ath_hw *ah)
-{
-       return ((ah->eeprom.def.baseEepHeader.version) & 0xFFF);
-}
-
-static bool ath9k_hw_def_fill_eeprom(struct ath_hw *ah)
-{
-#define SIZE_EEPROM_DEF (sizeof(struct ar5416_eeprom_def) / sizeof(u16))
-       u16 *eep_data = (u16 *)&ah->eeprom.def;
-       int addr, ar5416_eep_start_loc = 0x100;
-
-       for (addr = 0; addr < SIZE_EEPROM_DEF; addr++) {
-               if (!ath9k_hw_nvram_read(ah, addr + ar5416_eep_start_loc,
-                                        eep_data)) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-                               "Unable to read eeprom region\n");
-                       return false;
-               }
-               eep_data++;
-       }
-       return true;
-#undef SIZE_EEPROM_DEF
-}
-
-static int ath9k_hw_def_check_eeprom(struct ath_hw *ah)
-{
-       struct ar5416_eeprom_def *eep =
-               (struct ar5416_eeprom_def *) &ah->eeprom.def;
-       u16 *eepdata, temp, magic, magic2;
-       u32 sum = 0, el;
-       bool need_swap = false;
-       int i, addr, size;
-
-       if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET, &magic)) {
-               DPRINTF(ah->ah_sc, ATH_DBG_FATAL, "Reading Magic # failed\n");
-               return false;
-       }
-
-       if (!ath9k_hw_use_flash(ah)) {
-               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-                       "Read Magic = 0x%04X\n", magic);
-
-               if (magic != AR5416_EEPROM_MAGIC) {
-                       magic2 = swab16(magic);
-
-                       if (magic2 == AR5416_EEPROM_MAGIC) {
-                               size = sizeof(struct ar5416_eeprom_def);
-                               need_swap = true;
-                               eepdata = (u16 *) (&ah->eeprom);
-
-                               for (addr = 0; addr < size / sizeof(u16); addr++) {
-                                       temp = swab16(*eepdata);
-                                       *eepdata = temp;
-                                       eepdata++;
-                               }
-                       } else {
-                               DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-                                       "Invalid EEPROM Magic. "
-                                       "Endianness mismatch.\n");
-                               return -EINVAL;
-                       }
-               }
-       }
-
-       DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "need_swap = %s.\n",
-               need_swap ? "True" : "False");
-
-       if (need_swap)
-               el = swab16(ah->eeprom.def.baseEepHeader.length);
-       else
-               el = ah->eeprom.def.baseEepHeader.length;
-
-       if (el > sizeof(struct ar5416_eeprom_def))
-               el = sizeof(struct ar5416_eeprom_def) / sizeof(u16);
-       else
-               el = el / sizeof(u16);
-
-       eepdata = (u16 *)(&ah->eeprom);
-
-       for (i = 0; i < el; i++)
-               sum ^= *eepdata++;
-
-       if (need_swap) {
-               u32 integer, j;
-               u16 word;
-
-               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-                       "EEPROM Endianness is not native.. Changing.\n");
-
-               word = swab16(eep->baseEepHeader.length);
-               eep->baseEepHeader.length = word;
-
-               word = swab16(eep->baseEepHeader.checksum);
-               eep->baseEepHeader.checksum = word;
-
-               word = swab16(eep->baseEepHeader.version);
-               eep->baseEepHeader.version = word;
-
-               word = swab16(eep->baseEepHeader.regDmn[0]);
-               eep->baseEepHeader.regDmn[0] = word;
-
-               word = swab16(eep->baseEepHeader.regDmn[1]);
-               eep->baseEepHeader.regDmn[1] = word;
-
-               word = swab16(eep->baseEepHeader.rfSilent);
-               eep->baseEepHeader.rfSilent = word;
-
-               word = swab16(eep->baseEepHeader.blueToothOptions);
-               eep->baseEepHeader.blueToothOptions = word;
-
-               word = swab16(eep->baseEepHeader.deviceCap);
-               eep->baseEepHeader.deviceCap = word;
-
-               for (j = 0; j < ARRAY_SIZE(eep->modalHeader); j++) {
-                       struct modal_eep_header *pModal =
-                               &eep->modalHeader[j];
-                       integer = swab32(pModal->antCtrlCommon);
-                       pModal->antCtrlCommon = integer;
-
-                       for (i = 0; i < AR5416_MAX_CHAINS; i++) {
-                               integer = swab32(pModal->antCtrlChain[i]);
-                               pModal->antCtrlChain[i] = integer;
-                       }
-
-                       for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) {
-                               word = swab16(pModal->spurChans[i].spurChan);
-                               pModal->spurChans[i].spurChan = word;
-                       }
-               }
-       }
-
-       if (sum != 0xffff || ah->eep_ops->get_eeprom_ver(ah) != AR5416_EEP_VER ||
-           ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_NO_BACK_VER) {
-               DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-                       "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
-                       sum, ah->eep_ops->get_eeprom_ver(ah));
-               return -EINVAL;
-       }
-
-       return 0;
-}
-
-static u32 ath9k_hw_def_get_eeprom(struct ath_hw *ah,
-                                  enum eeprom_param param)
-{
-       struct ar5416_eeprom_def *eep = &ah->eeprom.def;
-       struct modal_eep_header *pModal = eep->modalHeader;
-       struct base_eep_header *pBase = &eep->baseEepHeader;
-
-       switch (param) {
-       case EEP_NFTHRESH_5:
-               return pModal[0].noiseFloorThreshCh[0];
-       case EEP_NFTHRESH_2:
-               return pModal[1].noiseFloorThreshCh[0];
-       case AR_EEPROM_MAC(0):
-               return pBase->macAddr[0] << 8 | pBase->macAddr[1];
-       case AR_EEPROM_MAC(1):
-               return pBase->macAddr[2] << 8 | pBase->macAddr[3];
-       case AR_EEPROM_MAC(2):
-               return pBase->macAddr[4] << 8 | pBase->macAddr[5];
-       case EEP_REG_0:
-               return pBase->regDmn[0];
-       case EEP_REG_1:
-               return pBase->regDmn[1];
-       case EEP_OP_CAP:
-               return pBase->deviceCap;
-       case EEP_OP_MODE:
-               return pBase->opCapFlags;
-       case EEP_RF_SILENT:
-               return pBase->rfSilent;
-       case EEP_OB_5:
-               return pModal[0].ob;
-       case EEP_DB_5:
-               return pModal[0].db;
-       case EEP_OB_2:
-               return pModal[1].ob;
-       case EEP_DB_2:
-               return pModal[1].db;
-       case EEP_MINOR_REV:
-               return AR5416_VER_MASK;
-       case EEP_TX_MASK:
-               return pBase->txMask;
-       case EEP_RX_MASK:
-               return pBase->rxMask;
-       case EEP_RXGAIN_TYPE:
-               return pBase->rxGainType;
-       case EEP_TXGAIN_TYPE:
-               return pBase->txGainType;
-       case EEP_OL_PWRCTRL:
-               if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19)
-                       return pBase->openLoopPwrCntl ? true : false;
-               else
-                       return false;
-       case EEP_RC_CHAIN_MASK:
-               if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19)
-                       return pBase->rcChainMask;
-               else
-                       return 0;
-       case EEP_DAC_HPWR_5G:
-               if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_20)
-                       return pBase->dacHiPwrMode_5G;
-               else
-                       return 0;
-       case EEP_FRAC_N_5G:
-               if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_22)
-                       return pBase->frac_n_5g;
-               else
-                       return 0;
-       default:
-               return 0;
-       }
-}
-
-static void ath9k_hw_def_set_gain(struct ath_hw *ah,
-                                 struct modal_eep_header *pModal,
-                                 struct ar5416_eeprom_def *eep,
-                                 u8 txRxAttenLocal, int regChainOffset, int i)
-{
-       if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_3) {
-               txRxAttenLocal = pModal->txRxAttenCh[i];
-
-               if (AR_SREV_9280_10_OR_LATER(ah)) {
-                       REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
-                             AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN,
-                             pModal->bswMargin[i]);
-                       REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
-                             AR_PHY_GAIN_2GHZ_XATTEN1_DB,
-                             pModal->bswAtten[i]);
-                       REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
-                             AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN,
-                             pModal->xatten2Margin[i]);
-                       REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
-                             AR_PHY_GAIN_2GHZ_XATTEN2_DB,
-                             pModal->xatten2Db[i]);
-               } else {
-                       REG_WRITE(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
-                         (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) &
-                          ~AR_PHY_GAIN_2GHZ_BSW_MARGIN)
-                         | SM(pModal-> bswMargin[i],
-                              AR_PHY_GAIN_2GHZ_BSW_MARGIN));
-                       REG_WRITE(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
-                         (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) &
-                          ~AR_PHY_GAIN_2GHZ_BSW_ATTEN)
-                         | SM(pModal->bswAtten[i],
-                              AR_PHY_GAIN_2GHZ_BSW_ATTEN));
-               }
-       }
-
-       if (AR_SREV_9280_10_OR_LATER(ah)) {
-               REG_RMW_FIELD(ah,
-                     AR_PHY_RXGAIN + regChainOffset,
-                     AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal);
-               REG_RMW_FIELD(ah,
-                     AR_PHY_RXGAIN + regChainOffset,
-                     AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[i]);
-       } else {
-               REG_WRITE(ah,
-                         AR_PHY_RXGAIN + regChainOffset,
-                         (REG_READ(ah, AR_PHY_RXGAIN + regChainOffset) &
-                          ~AR_PHY_RXGAIN_TXRX_ATTEN)
-                         | SM(txRxAttenLocal, AR_PHY_RXGAIN_TXRX_ATTEN));
-               REG_WRITE(ah,
-                         AR_PHY_GAIN_2GHZ + regChainOffset,
-                         (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) &
-                          ~AR_PHY_GAIN_2GHZ_RXTX_MARGIN) |
-                         SM(pModal->rxTxMarginCh[i], AR_PHY_GAIN_2GHZ_RXTX_MARGIN));
-       }
-}
-
-static void ath9k_hw_def_set_board_values(struct ath_hw *ah,
-                                         struct ath9k_channel *chan)
-{
-       struct modal_eep_header *pModal;
-       struct ar5416_eeprom_def *eep = &ah->eeprom.def;
-       int i, regChainOffset;
-       u8 txRxAttenLocal;
-
-       pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
-       txRxAttenLocal = IS_CHAN_2GHZ(chan) ? 23 : 44;
-
-       REG_WRITE(ah, AR_PHY_SWITCH_COM,
-                 ah->eep_ops->get_eeprom_antenna_cfg(ah, chan));
-
-       for (i = 0; i < AR5416_MAX_CHAINS; i++) {
-               if (AR_SREV_9280(ah)) {
-                       if (i >= 2)
-                               break;
-               }
-
-               if (AR_SREV_5416_20_OR_LATER(ah) &&
-                   (ah->rxchainmask == 5 || ah->txchainmask == 5) && (i != 0))
-                       regChainOffset = (i == 1) ? 0x2000 : 0x1000;
-               else
-                       regChainOffset = i * 0x1000;
-
-               REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset,
-                         pModal->antCtrlChain[i]);
-
-               REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset,
-                         (REG_READ(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset) &
-                          ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |
-                            AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
-                         SM(pModal->iqCalICh[i],
-                            AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
-                         SM(pModal->iqCalQCh[i],
-                            AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
-
-               if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah))
-                       ath9k_hw_def_set_gain(ah, pModal, eep, txRxAttenLocal,
-                                             regChainOffset, i);
-       }
-
-       if (AR_SREV_9280_10_OR_LATER(ah)) {
-               if (IS_CHAN_2GHZ(chan)) {
-                       ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH0,
-                                                 AR_AN_RF2G1_CH0_OB,
-                                                 AR_AN_RF2G1_CH0_OB_S,
-                                                 pModal->ob);
-                       ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH0,
-                                                 AR_AN_RF2G1_CH0_DB,
-                                                 AR_AN_RF2G1_CH0_DB_S,
-                                                 pModal->db);
-                       ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH1,
-                                                 AR_AN_RF2G1_CH1_OB,
-                                                 AR_AN_RF2G1_CH1_OB_S,
-                                                 pModal->ob_ch1);
-                       ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH1,
-                                                 AR_AN_RF2G1_CH1_DB,
-                                                 AR_AN_RF2G1_CH1_DB_S,
-                                                 pModal->db_ch1);
-               } else {
-                       ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH0,
-                                                 AR_AN_RF5G1_CH0_OB5,
-                                                 AR_AN_RF5G1_CH0_OB5_S,
-                                                 pModal->ob);
-                       ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH0,
-                                                 AR_AN_RF5G1_CH0_DB5,
-                                                 AR_AN_RF5G1_CH0_DB5_S,
-                                                 pModal->db);
-                       ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH1,
-                                                 AR_AN_RF5G1_CH1_OB5,
-                                                 AR_AN_RF5G1_CH1_OB5_S,
-                                                 pModal->ob_ch1);
-                       ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH1,
-                                                 AR_AN_RF5G1_CH1_DB5,
-                                                 AR_AN_RF5G1_CH1_DB5_S,
-                                                 pModal->db_ch1);
-               }
-               ath9k_hw_analog_shift_rmw(ah, AR_AN_TOP2,
-                                         AR_AN_TOP2_XPABIAS_LVL,
-                                         AR_AN_TOP2_XPABIAS_LVL_S,
-                                         pModal->xpaBiasLvl);
-               ath9k_hw_analog_shift_rmw(ah, AR_AN_TOP2,
-                                         AR_AN_TOP2_LOCALBIAS,
-                                         AR_AN_TOP2_LOCALBIAS_S,
-                                         pModal->local_bias);
-               REG_RMW_FIELD(ah, AR_PHY_XPA_CFG, AR_PHY_FORCE_XPA_CFG,
-                             pModal->force_xpaon);
-       }
-
-       REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH,
-                     pModal->switchSettling);
-       REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC,
-                     pModal->adcDesiredSize);
-
-       if (!AR_SREV_9280_10_OR_LATER(ah))
-               REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
-                             AR_PHY_DESIRED_SZ_PGA,
-                             pModal->pgaDesiredSize);
-
-       REG_WRITE(ah, AR_PHY_RF_CTL4,
-                 SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF)
-                 | SM(pModal->txEndToXpaOff,
-                      AR_PHY_RF_CTL4_TX_END_XPAB_OFF)
-                 | SM(pModal->txFrameToXpaOn,
-                      AR_PHY_RF_CTL4_FRAME_XPAA_ON)
-                 | SM(pModal->txFrameToXpaOn,
-                      AR_PHY_RF_CTL4_FRAME_XPAB_ON));
-
-       REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON,
-                     pModal->txEndToRxOn);
-
-       if (AR_SREV_9280_10_OR_LATER(ah)) {
-               REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62,
-                             pModal->thresh62);
-               REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0,
-                             AR_PHY_EXT_CCA0_THRESH62,
-                             pModal->thresh62);
-       } else {
-               REG_RMW_FIELD(ah, AR_PHY_CCA, AR_PHY_CCA_THRESH62,
-                             pModal->thresh62);
-               REG_RMW_FIELD(ah, AR_PHY_EXT_CCA,
-                             AR_PHY_EXT_CCA_THRESH62,
-                             pModal->thresh62);
-       }
-
-       if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_2) {
-               REG_RMW_FIELD(ah, AR_PHY_RF_CTL2,
-                             AR_PHY_TX_END_DATA_START,
-                             pModal->txFrameToDataStart);
-               REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_PA_ON,
-                             pModal->txFrameToPaOn);
-       }
-
-       if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_3) {
-               if (IS_CHAN_HT40(chan))
-                       REG_RMW_FIELD(ah, AR_PHY_SETTLING,
-                                     AR_PHY_SETTLING_SWITCH,
-                                     pModal->swSettleHt40);
-       }
-
-       if (AR_SREV_9280_20_OR_LATER(ah) &&
-           AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19)
-               REG_RMW_FIELD(ah, AR_PHY_CCK_TX_CTRL,
-                             AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK,
-                             pModal->miscBits);
-
-
-       if (AR_SREV_9280_20(ah) && AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_20) {
-               if (IS_CHAN_2GHZ(chan))
-                       REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE,
-                                       eep->baseEepHeader.dacLpMode);
-               else if (eep->baseEepHeader.dacHiPwrMode_5G)
-                       REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE, 0);
-               else
-                       REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE,
-                                     eep->baseEepHeader.dacLpMode);
-
-               REG_RMW_FIELD(ah, AR_PHY_FRAME_CTL, AR_PHY_FRAME_CTL_TX_CLIP,
-                             pModal->miscBits >> 2);
-
-               REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL9,
-                             AR_PHY_TX_DESIRED_SCALE_CCK,
-                             eep->baseEepHeader.desiredScaleCCK);
-       }
-}
-
-static void ath9k_hw_def_set_addac(struct ath_hw *ah,
-                                  struct ath9k_channel *chan)
-{
-#define XPA_LVL_FREQ(cnt) (pModal->xpaBiasLvlFreq[cnt])
-       struct modal_eep_header *pModal;
-       struct ar5416_eeprom_def *eep = &ah->eeprom.def;
-       u8 biaslevel;
-
-       if (ah->hw_version.macVersion != AR_SREV_VERSION_9160)
-               return;
-
-       if (ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_MINOR_VER_7)
-               return;
-
-       pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
-
-       if (pModal->xpaBiasLvl != 0xff) {
-               biaslevel = pModal->xpaBiasLvl;
-       } else {
-               u16 resetFreqBin, freqBin, freqCount = 0;
-               struct chan_centers centers;
-
-               ath9k_hw_get_channel_centers(ah, chan, &centers);
-
-               resetFreqBin = FREQ2FBIN(centers.synth_center,
-                                        IS_CHAN_2GHZ(chan));
-               freqBin = XPA_LVL_FREQ(0) & 0xff;
-               biaslevel = (u8) (XPA_LVL_FREQ(0) >> 14);
-
-               freqCount++;
-
-               while (freqCount < 3) {
-                       if (XPA_LVL_FREQ(freqCount) == 0x0)
-                               break;
-
-                       freqBin = XPA_LVL_FREQ(freqCount) & 0xff;
-                       if (resetFreqBin >= freqBin)
-                               biaslevel = (u8)(XPA_LVL_FREQ(freqCount) >> 14);
-                       else
-                               break;
-                       freqCount++;
-               }
-       }
-
-       if (IS_CHAN_2GHZ(chan)) {
-               INI_RA(&ah->iniAddac, 7, 1) = (INI_RA(&ah->iniAddac,
-                                       7, 1) & (~0x18)) | biaslevel << 3;
-       } else {
-               INI_RA(&ah->iniAddac, 6, 1) = (INI_RA(&ah->iniAddac,
-                                       6, 1) & (~0xc0)) | biaslevel << 6;
-       }
-#undef XPA_LVL_FREQ
-}
-
-static void ath9k_hw_get_def_gain_boundaries_pdadcs(struct ath_hw *ah,
-                               struct ath9k_channel *chan,
-                               struct cal_data_per_freq *pRawDataSet,
-                               u8 *bChans, u16 availPiers,
-                               u16 tPdGainOverlap, int16_t *pMinCalPower,
-                               u16 *pPdGainBoundaries, u8 *pPDADCValues,
-                               u16 numXpdGains)
-{
-       int i, j, k;
-       int16_t ss;
-       u16 idxL = 0, idxR = 0, numPiers;
-       static u8 vpdTableL[AR5416_NUM_PD_GAINS]
-               [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
-       static u8 vpdTableR[AR5416_NUM_PD_GAINS]
-               [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
-       static u8 vpdTableI[AR5416_NUM_PD_GAINS]
-               [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
-
-       u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR;
-       u8 minPwrT4[AR5416_NUM_PD_GAINS];
-       u8 maxPwrT4[AR5416_NUM_PD_GAINS];
-       int16_t vpdStep;
-       int16_t tmpVal;
-       u16 sizeCurrVpdTable, maxIndex, tgtIndex;
-       bool match;
-       int16_t minDelta = 0;
-       struct chan_centers centers;
-
-       ath9k_hw_get_channel_centers(ah, chan, &centers);
-
-       for (numPiers = 0; numPiers < availPiers; numPiers++) {
-               if (bChans[numPiers] == AR5416_BCHAN_UNUSED)
-                       break;
-       }
-
-       match = ath9k_hw_get_lower_upper_index((u8)FREQ2FBIN(centers.synth_center,
-                                                            IS_CHAN_2GHZ(chan)),
-                                              bChans, numPiers, &idxL, &idxR);
-
-       if (match) {
-               for (i = 0; i < numXpdGains; i++) {
-                       minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0];
-                       maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4];
-                       ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
-                                       pRawDataSet[idxL].pwrPdg[i],
-                                       pRawDataSet[idxL].vpdPdg[i],
-                                       AR5416_PD_GAIN_ICEPTS,
-                                       vpdTableI[i]);
-               }
-       } else {
-               for (i = 0; i < numXpdGains; i++) {
-                       pVpdL = pRawDataSet[idxL].vpdPdg[i];
-                       pPwrL = pRawDataSet[idxL].pwrPdg[i];
-                       pVpdR = pRawDataSet[idxR].vpdPdg[i];
-                       pPwrR = pRawDataSet[idxR].pwrPdg[i];
-
-                       minPwrT4[i] = max(pPwrL[0], pPwrR[0]);
-
-                       maxPwrT4[i] =
-                               min(pPwrL[AR5416_PD_GAIN_ICEPTS - 1],
-                                   pPwrR[AR5416_PD_GAIN_ICEPTS - 1]);
-
-
-                       ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
-                                               pPwrL, pVpdL,
-                                               AR5416_PD_GAIN_ICEPTS,
-                                               vpdTableL[i]);
-                       ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
-                                               pPwrR, pVpdR,
-                                               AR5416_PD_GAIN_ICEPTS,
-                                               vpdTableR[i]);
-
-                       for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
-                               vpdTableI[i][j] =
-                                       (u8)(ath9k_hw_interpolate((u16)
-                                            FREQ2FBIN(centers.
-                                                      synth_center,
-                                                      IS_CHAN_2GHZ
-                                                      (chan)),
-                                            bChans[idxL], bChans[idxR],
-                                            vpdTableL[i][j], vpdTableR[i][j]));
-                       }
-               }
-       }
-
-       *pMinCalPower = (int16_t)(minPwrT4[0] / 2);
-
-       k = 0;
-
-       for (i = 0; i < numXpdGains; i++) {
-               if (i == (numXpdGains - 1))
-                       pPdGainBoundaries[i] =
-                               (u16)(maxPwrT4[i] / 2);
-               else
-                       pPdGainBoundaries[i] =
-                               (u16)((maxPwrT4[i] + minPwrT4[i + 1]) / 4);
-
-               pPdGainBoundaries[i] =
-                       min((u16)AR5416_MAX_RATE_POWER, pPdGainBoundaries[i]);
-
-               if ((i == 0) && !AR_SREV_5416_20_OR_LATER(ah)) {
-                       minDelta = pPdGainBoundaries[0] - 23;
-                       pPdGainBoundaries[0] = 23;
-               } else {
-                       minDelta = 0;
-               }
-
-               if (i == 0) {
-                       if (AR_SREV_9280_10_OR_LATER(ah))
-                               ss = (int16_t)(0 - (minPwrT4[i] / 2));
-                       else
-                               ss = 0;
-               } else {
-                       ss = (int16_t)((pPdGainBoundaries[i - 1] -
-                                       (minPwrT4[i] / 2)) -
-                                      tPdGainOverlap + 1 + minDelta);
-               }
-               vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]);
-               vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
-
-               while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
-                       tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep);
-                       pPDADCValues[k++] = (u8)((tmpVal < 0) ? 0 : tmpVal);
-                       ss++;
-               }
-
-               sizeCurrVpdTable = (u8) ((maxPwrT4[i] - minPwrT4[i]) / 2 + 1);
-               tgtIndex = (u8)(pPdGainBoundaries[i] + tPdGainOverlap -
-                               (minPwrT4[i] / 2));
-               maxIndex = (tgtIndex < sizeCurrVpdTable) ?
-                       tgtIndex : sizeCurrVpdTable;
-
-               while ((ss < maxIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
-                       pPDADCValues[k++] = vpdTableI[i][ss++];
-               }
-
-               vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] -
-                                   vpdTableI[i][sizeCurrVpdTable - 2]);
-               vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
-
-               if (tgtIndex > maxIndex) {
-                       while ((ss <= tgtIndex) &&
-                              (k < (AR5416_NUM_PDADC_VALUES - 1))) {
-                               tmpVal = (int16_t)((vpdTableI[i][sizeCurrVpdTable - 1] +
-                                                   (ss - maxIndex + 1) * vpdStep));
-                               pPDADCValues[k++] = (u8)((tmpVal > 255) ?
-                                                        255 : tmpVal);
-                               ss++;
-                       }
-               }
-       }
-
-       while (i < AR5416_PD_GAINS_IN_MASK) {
-               pPdGainBoundaries[i] = pPdGainBoundaries[i - 1];
-               i++;
-       }
-
-       while (k < AR5416_NUM_PDADC_VALUES) {
-               pPDADCValues[k] = pPDADCValues[k - 1];
-               k++;
-       }
-
-       return;
-}
-
-static bool ath9k_hw_set_def_power_cal_table(struct ath_hw *ah,
-                                 struct ath9k_channel *chan,
-                                 int16_t *pTxPowerIndexOffset)
-{
-#define SM_PD_GAIN(x) SM(0x38, AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_##x)
-#define SM_PDGAIN_B(x, y) \
-               SM((gainBoundaries[x]), AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_##y)
-
-       struct ar5416_eeprom_def *pEepData = &ah->eeprom.def;
-       struct cal_data_per_freq *pRawDataset;
-       u8 *pCalBChans = NULL;
-       u16 pdGainOverlap_t2;
-       static u8 pdadcValues[AR5416_NUM_PDADC_VALUES];
-       u16 gainBoundaries[AR5416_PD_GAINS_IN_MASK];
-       u16 numPiers, i, j;
-       int16_t tMinCalPower;
-       u16 numXpdGain, xpdMask;
-       u16 xpdGainValues[AR5416_NUM_PD_GAINS] = { 0, 0, 0, 0 };
-       u32 reg32, regOffset, regChainOffset;
-       int16_t modalIdx;
-
-       modalIdx = IS_CHAN_2GHZ(chan) ? 1 : 0;
-       xpdMask = pEepData->modalHeader[modalIdx].xpdGain;
-
-       if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
-           AR5416_EEP_MINOR_VER_2) {
-               pdGainOverlap_t2 =
-                       pEepData->modalHeader[modalIdx].pdGainOverlap;
-       } else {
-               pdGainOverlap_t2 = (u16)(MS(REG_READ(ah, AR_PHY_TPCRG5),
-                                           AR_PHY_TPCRG5_PD_GAIN_OVERLAP));
-       }
-
-       if (IS_CHAN_2GHZ(chan)) {
-               pCalBChans = pEepData->calFreqPier2G;
-               numPiers = AR5416_NUM_2G_CAL_PIERS;
-       } else {
-               pCalBChans = pEepData->calFreqPier5G;
-               numPiers = AR5416_NUM_5G_CAL_PIERS;
-       }
-
-       if (OLC_FOR_AR9280_20_LATER && IS_CHAN_2GHZ(chan)) {
-               pRawDataset = pEepData->calPierData2G[0];
-               ah->initPDADC = ((struct calDataPerFreqOpLoop *)
-                                pRawDataset)->vpdPdg[0][0];
-       }
-
-       numXpdGain = 0;
-
-       for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) {
-               if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) {
-                       if (numXpdGain >= AR5416_NUM_PD_GAINS)
-                               break;
-                       xpdGainValues[numXpdGain] =
-                               (u16)(AR5416_PD_GAINS_IN_MASK - i);
-                       numXpdGain++;
-               }
-       }
-
-       REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN,
-                     (numXpdGain - 1) & 0x3);
-       REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1,
-                     xpdGainValues[0]);
-       REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2,
-                     xpdGainValues[1]);
-       REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3,
-                     xpdGainValues[2]);
-
-       for (i = 0; i < AR5416_MAX_CHAINS; i++) {
-               if (AR_SREV_5416_20_OR_LATER(ah) &&
-                   (ah->rxchainmask == 5 || ah->txchainmask == 5) &&
-                   (i != 0)) {
-                       regChainOffset = (i == 1) ? 0x2000 : 0x1000;
-               } else
-                       regChainOffset = i * 0x1000;
-
-               if (pEepData->baseEepHeader.txMask & (1 << i)) {
-                       if (IS_CHAN_2GHZ(chan))
-                               pRawDataset = pEepData->calPierData2G[i];
-                       else
-                               pRawDataset = pEepData->calPierData5G[i];
-
-
-                       if (OLC_FOR_AR9280_20_LATER) {
-                               u8 pcdacIdx;
-                               u8 txPower;
-
-                               ath9k_get_txgain_index(ah, chan,
-                               (struct calDataPerFreqOpLoop *)pRawDataset,
-                               pCalBChans, numPiers, &txPower, &pcdacIdx);
-                               ath9k_olc_get_pdadcs(ah, pcdacIdx,
-                                                    txPower/2, pdadcValues);
-                       } else {
-                               ath9k_hw_get_def_gain_boundaries_pdadcs(ah,
-                                                       chan, pRawDataset,
-                                                       pCalBChans, numPiers,
-                                                       pdGainOverlap_t2,
-                                                       &tMinCalPower,
-                                                       gainBoundaries,
-                                                       pdadcValues,
-                                                       numXpdGain);
-                       }
-
-                       if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah)) {
-                               if (OLC_FOR_AR9280_20_LATER) {
-                                       REG_WRITE(ah,
-                                               AR_PHY_TPCRG5 + regChainOffset,
-                                               SM(0x6,
-                                               AR_PHY_TPCRG5_PD_GAIN_OVERLAP) |
-                                               SM_PD_GAIN(1) | SM_PD_GAIN(2) |
-                                               SM_PD_GAIN(3) | SM_PD_GAIN(4));
-                               } else {
-                                       REG_WRITE(ah,
-                                               AR_PHY_TPCRG5 + regChainOffset,
-                                               SM(pdGainOverlap_t2,
-                                               AR_PHY_TPCRG5_PD_GAIN_OVERLAP)|
-                                               SM_PDGAIN_B(0, 1) |
-                                               SM_PDGAIN_B(1, 2) |
-                                               SM_PDGAIN_B(2, 3) |
-                                               SM_PDGAIN_B(3, 4));
-                               }
-                       }
-
-                       regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset;
-                       for (j = 0; j < 32; j++) {
-                               reg32 = ((pdadcValues[4 * j + 0] & 0xFF) << 0) |
-                                       ((pdadcValues[4 * j + 1] & 0xFF) << 8) |
-                                       ((pdadcValues[4 * j + 2] & 0xFF) << 16)|
-                                       ((pdadcValues[4 * j + 3] & 0xFF) << 24);
-                               REG_WRITE(ah, regOffset, reg32);
-
-                               DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
-                                       "PDADC (%d,%4x): %4.4x %8.8x\n",
-                                       i, regChainOffset, regOffset,
-                                       reg32);
-                               DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
-                                       "PDADC: Chain %d | PDADC %3d "
-                                       "Value %3d | PDADC %3d Value %3d | "
-                                       "PDADC %3d Value %3d | PDADC %3d "
-                                       "Value %3d |\n",
-                                       i, 4 * j, pdadcValues[4 * j],
-                                       4 * j + 1, pdadcValues[4 * j + 1],
-                                       4 * j + 2, pdadcValues[4 * j + 2],
-                                       4 * j + 3,
-                                       pdadcValues[4 * j + 3]);
-
-                               regOffset += 4;
-                       }
-               }
-       }
-
-       *pTxPowerIndexOffset = 0;
-
-       return true;
-#undef SM_PD_GAIN
-#undef SM_PDGAIN_B
-}
-
-static bool ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah,
-                                                 struct ath9k_channel *chan,
-                                                 int16_t *ratesArray,
-                                                 u16 cfgCtl,
-                                                 u16 AntennaReduction,
-                                                 u16 twiceMaxRegulatoryPower,
-                                                 u16 powerLimit)
-{
-#define REDUCE_SCALED_POWER_BY_TWO_CHAIN     6  /* 10*log10(2)*2 */
-#define REDUCE_SCALED_POWER_BY_THREE_CHAIN   10 /* 10*log10(3)*2 */
-
-       struct ar5416_eeprom_def *pEepData = &ah->eeprom.def;
-       u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
-       static const u16 tpScaleReductionTable[5] =
-               { 0, 3, 6, 9, AR5416_MAX_RATE_POWER };
-
-       int i;
-       int16_t twiceLargestAntenna;
-       struct cal_ctl_data *rep;
-       struct cal_target_power_leg targetPowerOfdm, targetPowerCck = {
-               0, { 0, 0, 0, 0}
-       };
-       struct cal_target_power_leg targetPowerOfdmExt = {
-               0, { 0, 0, 0, 0} }, targetPowerCckExt = {
-               0, { 0, 0, 0, 0 }
-       };
-       struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = {
-               0, {0, 0, 0, 0}
-       };
-       u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
-       u16 ctlModesFor11a[] =
-               { CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40 };
-       u16 ctlModesFor11g[] =
-               { CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT,
-                 CTL_2GHT40
-               };
-       u16 numCtlModes, *pCtlMode, ctlMode, freq;
-       struct chan_centers centers;
-       int tx_chainmask;
-       u16 twiceMinEdgePower;
-
-       tx_chainmask = ah->txchainmask;
-
-       ath9k_hw_get_channel_centers(ah, chan, &centers);
-
-       twiceLargestAntenna = max(
-               pEepData->modalHeader
-                       [IS_CHAN_2GHZ(chan)].antennaGainCh[0],
-               pEepData->modalHeader
-                       [IS_CHAN_2GHZ(chan)].antennaGainCh[1]);
-
-       twiceLargestAntenna = max((u8)twiceLargestAntenna,
-                                 pEepData->modalHeader
-                                 [IS_CHAN_2GHZ(chan)].antennaGainCh[2]);
-
-       twiceLargestAntenna = (int16_t)min(AntennaReduction -
-                                          twiceLargestAntenna, 0);
-
-       maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
-
-       if (ah->regulatory.tp_scale != ATH9K_TP_SCALE_MAX) {
-               maxRegAllowedPower -=
-                       (tpScaleReductionTable[(ah->regulatory.tp_scale)] * 2);
-       }
-
-       scaledPower = min(powerLimit, maxRegAllowedPower);
-
-       switch (ar5416_get_ntxchains(tx_chainmask)) {
-       case 1:
-               break;
-       case 2:
-               scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN;
-               break;
-       case 3:
-               scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN;
-               break;
-       }
-
-       scaledPower = max((u16)0, scaledPower);
-
-       if (IS_CHAN_2GHZ(chan)) {
-               numCtlModes = ARRAY_SIZE(ctlModesFor11g) -
-                       SUB_NUM_CTL_MODES_AT_2G_40;
-               pCtlMode = ctlModesFor11g;
-
-               ath9k_hw_get_legacy_target_powers(ah, chan,
-                       pEepData->calTargetPowerCck,
-                       AR5416_NUM_2G_CCK_TARGET_POWERS,
-                       &targetPowerCck, 4, false);
-               ath9k_hw_get_legacy_target_powers(ah, chan,
-                       pEepData->calTargetPower2G,
-                       AR5416_NUM_2G_20_TARGET_POWERS,
-                       &targetPowerOfdm, 4, false);
-               ath9k_hw_get_target_powers(ah, chan,
-                       pEepData->calTargetPower2GHT20,
-                       AR5416_NUM_2G_20_TARGET_POWERS,
-                       &targetPowerHt20, 8, false);
-
-               if (IS_CHAN_HT40(chan)) {
-                       numCtlModes = ARRAY_SIZE(ctlModesFor11g);
-                       ath9k_hw_get_target_powers(ah, chan,
-                               pEepData->calTargetPower2GHT40,
-                               AR5416_NUM_2G_40_TARGET_POWERS,
-                               &targetPowerHt40, 8, true);
-                       ath9k_hw_get_legacy_target_powers(ah, chan,
-                               pEepData->calTargetPowerCck,
-                               AR5416_NUM_2G_CCK_TARGET_POWERS,
-                               &targetPowerCckExt, 4, true);
-                       ath9k_hw_get_legacy_target_powers(ah, chan,
-                               pEepData->calTargetPower2G,
-                               AR5416_NUM_2G_20_TARGET_POWERS,
-                               &targetPowerOfdmExt, 4, true);
-               }
-       } else {
-               numCtlModes = ARRAY_SIZE(ctlModesFor11a) -
-                       SUB_NUM_CTL_MODES_AT_5G_40;
-               pCtlMode = ctlModesFor11a;
-
-               ath9k_hw_get_legacy_target_powers(ah, chan,
-                       pEepData->calTargetPower5G,
-                       AR5416_NUM_5G_20_TARGET_POWERS,
-                       &targetPowerOfdm, 4, false);
-               ath9k_hw_get_target_powers(ah, chan,
-                       pEepData->calTargetPower5GHT20,
-                       AR5416_NUM_5G_20_TARGET_POWERS,
-                       &targetPowerHt20, 8, false);
-
-               if (IS_CHAN_HT40(chan)) {
-                       numCtlModes = ARRAY_SIZE(ctlModesFor11a);
-                       ath9k_hw_get_target_powers(ah, chan,
-                               pEepData->calTargetPower5GHT40,
-                               AR5416_NUM_5G_40_TARGET_POWERS,
-                               &targetPowerHt40, 8, true);
-                       ath9k_hw_get_legacy_target_powers(ah, chan,
-                               pEepData->calTargetPower5G,
-                               AR5416_NUM_5G_20_TARGET_POWERS,
-                               &targetPowerOfdmExt, 4, true);
-               }
-       }
-
-       for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
-               bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) ||
-                       (pCtlMode[ctlMode] == CTL_2GHT40);
-               if (isHt40CtlMode)
-                       freq = centers.synth_center;
-               else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
-                       freq = centers.ext_center;
-               else
-                       freq = centers.ctl_center;
-
-               if (ah->eep_ops->get_eeprom_ver(ah) == 14 &&
-                   ah->eep_ops->get_eeprom_rev(ah) <= 2)
-                       twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
-
-               DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
-                       "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, "
-                       "EXT_ADDITIVE %d\n",
-                       ctlMode, numCtlModes, isHt40CtlMode,
-                       (pCtlMode[ctlMode] & EXT_ADDITIVE));
-
-               for (i = 0; (i < AR5416_NUM_CTLS) && pEepData->ctlIndex[i]; i++) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
-                               "  LOOP-Ctlidx %d: cfgCtl 0x%2.2x "
-                               "pCtlMode 0x%2.2x ctlIndex 0x%2.2x "
-                               "chan %d\n",
-                               i, cfgCtl, pCtlMode[ctlMode],
-                               pEepData->ctlIndex[i], chan->channel);
-
-                       if ((((cfgCtl & ~CTL_MODE_M) |
-                             (pCtlMode[ctlMode] & CTL_MODE_M)) ==
-                            pEepData->ctlIndex[i]) ||
-                           (((cfgCtl & ~CTL_MODE_M) |
-                             (pCtlMode[ctlMode] & CTL_MODE_M)) ==
-                            ((pEepData->ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL))) {
-                               rep = &(pEepData->ctlData[i]);
-
-                               twiceMinEdgePower = ath9k_hw_get_max_edge_power(freq,
-                               rep->ctlEdges[ar5416_get_ntxchains(tx_chainmask) - 1],
-                               IS_CHAN_2GHZ(chan), AR5416_NUM_BAND_EDGES);
-
-                               DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
-                                       "    MATCH-EE_IDX %d: ch %d is2 %d "
-                                       "2xMinEdge %d chainmask %d chains %d\n",
-                                       i, freq, IS_CHAN_2GHZ(chan),
-                                       twiceMinEdgePower, tx_chainmask,
-                                       ar5416_get_ntxchains
-                                       (tx_chainmask));
-                               if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) {
-                                       twiceMaxEdgePower = min(twiceMaxEdgePower,
-                                                               twiceMinEdgePower);
-                               } else {
-                                       twiceMaxEdgePower = twiceMinEdgePower;
-                                       break;
-                               }
-                       }
-               }
-
-               minCtlPower = min(twiceMaxEdgePower, scaledPower);
-
-               DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
-                       "    SEL-Min ctlMode %d pCtlMode %d "
-                       "2xMaxEdge %d sP %d minCtlPwr %d\n",
-                       ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower,
-                       scaledPower, minCtlPower);
-
-               switch (pCtlMode[ctlMode]) {
-               case CTL_11B:
-                       for (i = 0; i < ARRAY_SIZE(targetPowerCck.tPow2x); i++) {
-                               targetPowerCck.tPow2x[i] =
-                                       min((u16)targetPowerCck.tPow2x[i],
-                                           minCtlPower);
-                       }
-                       break;
-               case CTL_11A:
-               case CTL_11G:
-                       for (i = 0; i < ARRAY_SIZE(targetPowerOfdm.tPow2x); i++) {
-                               targetPowerOfdm.tPow2x[i] =
-                                       min((u16)targetPowerOfdm.tPow2x[i],
-                                           minCtlPower);
-                       }
-                       break;
-               case CTL_5GHT20:
-               case CTL_2GHT20:
-                       for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++) {
-                               targetPowerHt20.tPow2x[i] =
-                                       min((u16)targetPowerHt20.tPow2x[i],
-                                           minCtlPower);
-                       }
-                       break;
-               case CTL_11B_EXT:
-                       targetPowerCckExt.tPow2x[0] = min((u16)
-                                       targetPowerCckExt.tPow2x[0],
-                                       minCtlPower);
-                       break;
-               case CTL_11A_EXT:
-               case CTL_11G_EXT:
-                       targetPowerOfdmExt.tPow2x[0] = min((u16)
-                                       targetPowerOfdmExt.tPow2x[0],
-                                       minCtlPower);
-                       break;
-               case CTL_5GHT40:
-               case CTL_2GHT40:
-                       for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
-                               targetPowerHt40.tPow2x[i] =
-                                       min((u16)targetPowerHt40.tPow2x[i],
-                                           minCtlPower);
-                       }
-                       break;
-               default:
-                       break;
-               }
-       }
-
-       ratesArray[rate6mb] = ratesArray[rate9mb] = ratesArray[rate12mb] =
-               ratesArray[rate18mb] = ratesArray[rate24mb] =
-               targetPowerOfdm.tPow2x[0];
-       ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1];
-       ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2];
-       ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3];
-       ratesArray[rateXr] = targetPowerOfdm.tPow2x[0];
-
-       for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++)
-               ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i];
-
-       if (IS_CHAN_2GHZ(chan)) {
-               ratesArray[rate1l] = targetPowerCck.tPow2x[0];
-               ratesArray[rate2s] = ratesArray[rate2l] =
-                       targetPowerCck.tPow2x[1];
-               ratesArray[rate5_5s] = ratesArray[rate5_5l] =
-                       targetPowerCck.tPow2x[2];
-               ;
-               ratesArray[rate11s] = ratesArray[rate11l] =
-                       targetPowerCck.tPow2x[3];
-               ;
-       }
-       if (IS_CHAN_HT40(chan)) {
-               for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
-                       ratesArray[rateHt40_0 + i] =
-                               targetPowerHt40.tPow2x[i];
-               }
-               ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0];
-               ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0];
-               ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0];
-               if (IS_CHAN_2GHZ(chan)) {
-                       ratesArray[rateExtCck] =
-                               targetPowerCckExt.tPow2x[0];
-               }
-       }
-       return true;
-}
-
-static int ath9k_hw_def_set_txpower(struct ath_hw *ah,
-                                   struct ath9k_channel *chan,
-                                   u16 cfgCtl,
-                                   u8 twiceAntennaReduction,
-                                   u8 twiceMaxRegulatoryPower,
-                                   u8 powerLimit)
-{
-#define RT_AR_DELTA(x) (ratesArray[x] - cck_ofdm_delta)
-       struct ar5416_eeprom_def *pEepData = &ah->eeprom.def;
-       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;
-
-       memset(ratesArray, 0, sizeof(ratesArray));
-
-       if ((pEepData->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
-           AR5416_EEP_MINOR_VER_2) {
-               ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
-       }
-
-       if (!ath9k_hw_set_def_power_per_rate_table(ah, chan,
-                                              &ratesArray[0], cfgCtl,
-                                              twiceAntennaReduction,
-                                              twiceMaxRegulatoryPower,
-                                              powerLimit)) {
-               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-                       "ath9k_hw_set_txpower: unable to set "
-                       "tx power per rate table\n");
-               return -EIO;
-       }
-
-       if (!ath9k_hw_set_def_power_cal_table(ah, chan, &txPowerIndexOffset)) {
-               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-                        "ath9k_hw_set_txpower: unable to set power table\n");
-               return -EIO;
-       }
-
-       for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
-               ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]);
-               if (ratesArray[i] > AR5416_MAX_RATE_POWER)
-                       ratesArray[i] = AR5416_MAX_RATE_POWER;
-       }
-
-       if (AR_SREV_9280_10_OR_LATER(ah)) {
-               for (i = 0; i < Ar5416RateSize; i++)
-                       ratesArray[i] -= AR5416_PWR_TABLE_OFFSET * 2;
-       }
-
-       REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
-                 ATH9K_POW_SM(ratesArray[rate18mb], 24)
-                 | ATH9K_POW_SM(ratesArray[rate12mb], 16)
-                 | ATH9K_POW_SM(ratesArray[rate9mb], 8)
-                 | ATH9K_POW_SM(ratesArray[rate6mb], 0));
-       REG_WRITE(ah, AR_PHY_POWER_TX_RATE2,
-                 ATH9K_POW_SM(ratesArray[rate54mb], 24)
-                 | ATH9K_POW_SM(ratesArray[rate48mb], 16)
-                 | ATH9K_POW_SM(ratesArray[rate36mb], 8)
-                 | ATH9K_POW_SM(ratesArray[rate24mb], 0));
-
-       if (IS_CHAN_2GHZ(chan)) {
-               if (OLC_FOR_AR9280_20_LATER) {
-                       cck_ofdm_delta = 2;
-                       REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
-                               ATH9K_POW_SM(RT_AR_DELTA(rate2s), 24)
-                               | ATH9K_POW_SM(RT_AR_DELTA(rate2l), 16)
-                               | ATH9K_POW_SM(ratesArray[rateXr], 8)
-                               | ATH9K_POW_SM(RT_AR_DELTA(rate1l), 0));
-                       REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
-                               ATH9K_POW_SM(RT_AR_DELTA(rate11s), 24)
-                               | ATH9K_POW_SM(RT_AR_DELTA(rate11l), 16)
-                               | ATH9K_POW_SM(RT_AR_DELTA(rate5_5s), 8)
-                               | ATH9K_POW_SM(RT_AR_DELTA(rate5_5l), 0));
-               } else {
-                       REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
-                               ATH9K_POW_SM(ratesArray[rate2s], 24)
-                               | ATH9K_POW_SM(ratesArray[rate2l], 16)
-                               | ATH9K_POW_SM(ratesArray[rateXr], 8)
-                               | ATH9K_POW_SM(ratesArray[rate1l], 0));
-                       REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
-                               ATH9K_POW_SM(ratesArray[rate11s], 24)
-                               | ATH9K_POW_SM(ratesArray[rate11l], 16)
-                               | ATH9K_POW_SM(ratesArray[rate5_5s], 8)
-                               | ATH9K_POW_SM(ratesArray[rate5_5l], 0));
-               }
-       }
-
-       REG_WRITE(ah, AR_PHY_POWER_TX_RATE5,
-                 ATH9K_POW_SM(ratesArray[rateHt20_3], 24)
-                 | ATH9K_POW_SM(ratesArray[rateHt20_2], 16)
-                 | ATH9K_POW_SM(ratesArray[rateHt20_1], 8)
-                 | ATH9K_POW_SM(ratesArray[rateHt20_0], 0));
-       REG_WRITE(ah, AR_PHY_POWER_TX_RATE6,
-                 ATH9K_POW_SM(ratesArray[rateHt20_7], 24)
-                 | ATH9K_POW_SM(ratesArray[rateHt20_6], 16)
-                 | ATH9K_POW_SM(ratesArray[rateHt20_5], 8)
-                 | ATH9K_POW_SM(ratesArray[rateHt20_4], 0));
-
-       if (IS_CHAN_HT40(chan)) {
-               REG_WRITE(ah, AR_PHY_POWER_TX_RATE7,
-                         ATH9K_POW_SM(ratesArray[rateHt40_3] +
-                                      ht40PowerIncForPdadc, 24)
-                         | ATH9K_POW_SM(ratesArray[rateHt40_2] +
-                                        ht40PowerIncForPdadc, 16)
-                         | ATH9K_POW_SM(ratesArray[rateHt40_1] +
-                                        ht40PowerIncForPdadc, 8)
-                         | ATH9K_POW_SM(ratesArray[rateHt40_0] +
-                                        ht40PowerIncForPdadc, 0));
-               REG_WRITE(ah, AR_PHY_POWER_TX_RATE8,
-                         ATH9K_POW_SM(ratesArray[rateHt40_7] +
-                                      ht40PowerIncForPdadc, 24)
-                         | ATH9K_POW_SM(ratesArray[rateHt40_6] +
-                                        ht40PowerIncForPdadc, 16)
-                         | ATH9K_POW_SM(ratesArray[rateHt40_5] +
-                                        ht40PowerIncForPdadc, 8)
-                         | ATH9K_POW_SM(ratesArray[rateHt40_4] +
-                                        ht40PowerIncForPdadc, 0));
-               if (OLC_FOR_AR9280_20_LATER) {
-                       REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
-                               ATH9K_POW_SM(ratesArray[rateExtOfdm], 24)
-                               | ATH9K_POW_SM(RT_AR_DELTA(rateExtCck), 16)
-                               | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
-                               | ATH9K_POW_SM(RT_AR_DELTA(rateDupCck), 0));
-               } else {
-                       REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
-                               ATH9K_POW_SM(ratesArray[rateExtOfdm], 24)
-                               | ATH9K_POW_SM(ratesArray[rateExtCck], 16)
-                               | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
-                               | ATH9K_POW_SM(ratesArray[rateDupCck], 0));
-               }
-       }
-
-       REG_WRITE(ah, AR_PHY_POWER_TX_SUB,
-                 ATH9K_POW_SM(pModal->pwrDecreaseFor3Chain, 6)
-                 | ATH9K_POW_SM(pModal->pwrDecreaseFor2Chain, 0));
-
-       i = rate6mb;
-
-       if (IS_CHAN_HT40(chan))
-               i = rateHt40_0;
-       else if (IS_CHAN_HT20(chan))
-               i = rateHt20_0;
-
-       if (AR_SREV_9280_10_OR_LATER(ah))
-               ah->regulatory.max_power_level =
-                       ratesArray[i] + AR5416_PWR_TABLE_OFFSET * 2;
-       else
-               ah->regulatory.max_power_level = ratesArray[i];
-
-       switch(ar5416_get_ntxchains(ah->txchainmask)) {
-       case 1:
-               break;
-       case 2:
-               ah->regulatory.max_power_level += INCREASE_MAXPOW_BY_TWO_CHAIN;
-               break;
-       case 3:
-               ah->regulatory.max_power_level += INCREASE_MAXPOW_BY_THREE_CHAIN;
-               break;
-       default:
-               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-                       "Invalid chainmask configuration\n");
-               break;
-       }
-
-       return 0;
-}
-
-static u8 ath9k_hw_def_get_num_ant_config(struct ath_hw *ah,
-                                         enum ieee80211_band freq_band)
-{
-       struct ar5416_eeprom_def *eep = &ah->eeprom.def;
-       struct modal_eep_header *pModal =
-               &(eep->modalHeader[ATH9K_HAL_FREQ_BAND_2GHZ == freq_band]);
-       struct base_eep_header *pBase = &eep->baseEepHeader;
-       u8 num_ant_config;
-
-       num_ant_config = 1;
-
-       if (pBase->version >= 0x0E0D)
-               if (pModal->useAnt1)
-                       num_ant_config += 1;
-
-       return num_ant_config;
-}
-
-static u16 ath9k_hw_def_get_eeprom_antenna_cfg(struct ath_hw *ah,
-                                              struct ath9k_channel *chan)
-{
-       struct ar5416_eeprom_def *eep = &ah->eeprom.def;
-       struct modal_eep_header *pModal =
-               &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
-
-       return pModal->antCtrlCommon & 0xFFFF;
-}
-
-static u16 ath9k_hw_def_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz)
-{
-#define EEP_DEF_SPURCHAN \
-       (ah->eeprom.def.modalHeader[is2GHz].spurChans[i].spurChan)
-
-       u16 spur_val = AR_NO_SPUR;
-
-       DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-               "Getting spur idx %d is2Ghz. %d val %x\n",
-               i, is2GHz, ah->config.spurchans[i][is2GHz]);
-
-       switch (ah->config.spurmode) {
-       case SPUR_DISABLE:
-               break;
-       case SPUR_ENABLE_IOCTL:
-               spur_val = ah->config.spurchans[i][is2GHz];
-               DPRINTF(ah->ah_sc, ATH_DBG_ANI,
-                       "Getting spur val from new loc. %d\n", spur_val);
-               break;
-       case SPUR_ENABLE_EEPROM:
-               spur_val = EEP_DEF_SPURCHAN;
-               break;
-       }
-
-       return spur_val;
-
-#undef EEP_DEF_SPURCHAN
-}
-
-static 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,
-       .get_eeprom_ver         = ath9k_hw_def_get_eeprom_ver,
-       .get_eeprom_rev         = ath9k_hw_def_get_eeprom_rev,
-       .get_num_ant_config     = ath9k_hw_def_get_num_ant_config,
-       .get_eeprom_antenna_cfg = ath9k_hw_def_get_eeprom_antenna_cfg,
-       .set_board_values       = ath9k_hw_def_set_board_values,
-       .set_addac              = ath9k_hw_def_set_addac,
-       .set_txpower            = ath9k_hw_def_set_txpower,
-       .get_spur_channel       = ath9k_hw_def_get_spur_channel
-};
-
-int ath9k_hw_eeprom_attach(struct ath_hw *ah)
-{
-       int status;
-
-       if (AR_SREV_9285(ah)) {
-               ah->eep_map = EEP_MAP_4KBITS;
-               ah->eep_ops = &eep_4k_ops;
-       } else {
-               ah->eep_map = EEP_MAP_DEFAULT;
-               ah->eep_ops = &eep_def_ops;
-       }
-
-       if (!ah->eep_ops->fill_eeprom(ah))
-               return -EIO;
-
-       status = ah->eep_ops->check_eeprom(ah);
-
-       return status;
-}
diff --git a/drivers/net/wireless/ath9k/eeprom.h b/drivers/net/wireless/ath9k/eeprom.h
deleted file mode 100644 (file)
index 25b68c8..0000000
+++ /dev/null
@@ -1,507 +0,0 @@
-/*
- * Copyright (c) 2008-2009 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 EEPROM_H
-#define EEPROM_H
-
-#define AH_USE_EEPROM   0x1
-
-#ifdef __BIG_ENDIAN
-#define AR5416_EEPROM_MAGIC 0x5aa5
-#else
-#define AR5416_EEPROM_MAGIC 0xa55a
-#endif
-
-#define CTRY_DEBUG   0x1ff
-#define        CTRY_DEFAULT 0
-
-#define AR_EEPROM_EEPCAP_COMPRESS_DIS   0x0001
-#define AR_EEPROM_EEPCAP_AES_DIS        0x0002
-#define AR_EEPROM_EEPCAP_FASTFRAME_DIS  0x0004
-#define AR_EEPROM_EEPCAP_BURST_DIS      0x0008
-#define AR_EEPROM_EEPCAP_MAXQCU         0x01F0
-#define AR_EEPROM_EEPCAP_MAXQCU_S       4
-#define AR_EEPROM_EEPCAP_HEAVY_CLIP_EN  0x0200
-#define AR_EEPROM_EEPCAP_KC_ENTRIES     0xF000
-#define AR_EEPROM_EEPCAP_KC_ENTRIES_S   12
-
-#define AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND   0x0040
-#define AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN    0x0080
-#define AR_EEPROM_EEREGCAP_EN_KK_U2         0x0100
-#define AR_EEPROM_EEREGCAP_EN_KK_MIDBAND    0x0200
-#define AR_EEPROM_EEREGCAP_EN_KK_U1_ODD     0x0400
-#define AR_EEPROM_EEREGCAP_EN_KK_NEW_11A    0x0800
-
-#define AR_EEPROM_EEREGCAP_EN_KK_U1_ODD_PRE4_0  0x4000
-#define AR_EEPROM_EEREGCAP_EN_KK_NEW_11A_PRE4_0 0x8000
-
-#define AR5416_EEPROM_MAGIC_OFFSET  0x0
-#define AR5416_EEPROM_S             2
-#define AR5416_EEPROM_OFFSET        0x2000
-#define AR5416_EEPROM_MAX           0xae0
-
-#define AR5416_EEPROM_START_ADDR \
-       (AR_SREV_9100(ah)) ? 0x1fff1000 : 0x503f1200
-
-#define SD_NO_CTL               0xE0
-#define NO_CTL                  0xff
-#define CTL_MODE_M              7
-#define CTL_11A                 0
-#define CTL_11B                 1
-#define CTL_11G                 2
-#define CTL_2GHT20              5
-#define CTL_5GHT20              6
-#define CTL_2GHT40              7
-#define CTL_5GHT40              8
-
-#define EXT_ADDITIVE (0x8000)
-#define CTL_11A_EXT (CTL_11A | EXT_ADDITIVE)
-#define CTL_11G_EXT (CTL_11G | EXT_ADDITIVE)
-#define CTL_11B_EXT (CTL_11B | EXT_ADDITIVE)
-
-#define SUB_NUM_CTL_MODES_AT_5G_40 2
-#define SUB_NUM_CTL_MODES_AT_2G_40 3
-
-#define INCREASE_MAXPOW_BY_TWO_CHAIN     6  /* 10*log10(2)*2 */
-#define INCREASE_MAXPOW_BY_THREE_CHAIN   10 /* 10*log10(3)*2 */
-
-/*
- * For AR9285 and later chipsets, the following bits are not being programmed
- * in EEPROM and so need to be enabled always.
- *
- * Bit 0: en_fcc_mid
- * Bit 1: en_jap_mid
- * Bit 2: en_fcc_dfs_ht40
- * Bit 3: en_jap_ht40
- * Bit 4: en_jap_dfs_ht40
- */
-#define AR9285_RDEXT_DEFAULT    0x1F
-
-#define AR_EEPROM_MAC(i)       (0x1d+(i))
-#define ATH9K_POW_SM(_r, _s)   (((_r) & 0x3f) << (_s))
-#define FREQ2FBIN(x, y)                ((y) ? ((x) - 2300) : (((x) - 4800) / 5))
-#define ath9k_hw_use_flash(_ah)        (!(_ah->ah_flags & AH_USE_EEPROM))
-
-#define AR5416_VER_MASK (eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK)
-#define OLC_FOR_AR9280_20_LATER (AR_SREV_9280_20_OR_LATER(ah) && \
-                                ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL))
-
-#define AR_EEPROM_RFSILENT_GPIO_SEL     0x001c
-#define AR_EEPROM_RFSILENT_GPIO_SEL_S   2
-#define AR_EEPROM_RFSILENT_POLARITY     0x0002
-#define AR_EEPROM_RFSILENT_POLARITY_S   1
-
-#define EEP_RFSILENT_ENABLED        0x0001
-#define EEP_RFSILENT_ENABLED_S      0
-#define EEP_RFSILENT_POLARITY       0x0002
-#define EEP_RFSILENT_POLARITY_S     1
-#define EEP_RFSILENT_GPIO_SEL       0x001c
-#define EEP_RFSILENT_GPIO_SEL_S     2
-
-#define AR5416_OPFLAGS_11A           0x01
-#define AR5416_OPFLAGS_11G           0x02
-#define AR5416_OPFLAGS_N_5G_HT40     0x04
-#define AR5416_OPFLAGS_N_2G_HT40     0x08
-#define AR5416_OPFLAGS_N_5G_HT20     0x10
-#define AR5416_OPFLAGS_N_2G_HT20     0x20
-
-#define AR5416_EEP_NO_BACK_VER       0x1
-#define AR5416_EEP_VER               0xE
-#define AR5416_EEP_VER_MINOR_MASK    0x0FFF
-#define AR5416_EEP_MINOR_VER_2       0x2
-#define AR5416_EEP_MINOR_VER_3       0x3
-#define AR5416_EEP_MINOR_VER_7       0x7
-#define AR5416_EEP_MINOR_VER_9       0x9
-#define AR5416_EEP_MINOR_VER_16      0x10
-#define AR5416_EEP_MINOR_VER_17      0x11
-#define AR5416_EEP_MINOR_VER_19      0x13
-#define AR5416_EEP_MINOR_VER_20      0x14
-#define AR5416_EEP_MINOR_VER_22      0x16
-
-#define AR5416_NUM_5G_CAL_PIERS         8
-#define AR5416_NUM_2G_CAL_PIERS         4
-#define AR5416_NUM_5G_20_TARGET_POWERS  8
-#define AR5416_NUM_5G_40_TARGET_POWERS  8
-#define AR5416_NUM_2G_CCK_TARGET_POWERS 3
-#define AR5416_NUM_2G_20_TARGET_POWERS  4
-#define AR5416_NUM_2G_40_TARGET_POWERS  4
-#define AR5416_NUM_CTLS                 24
-#define AR5416_NUM_BAND_EDGES           8
-#define AR5416_NUM_PD_GAINS             4
-#define AR5416_PD_GAINS_IN_MASK         4
-#define AR5416_PD_GAIN_ICEPTS           5
-#define AR5416_EEPROM_MODAL_SPURS       5
-#define AR5416_MAX_RATE_POWER           63
-#define AR5416_NUM_PDADC_VALUES         128
-#define AR5416_BCHAN_UNUSED             0xFF
-#define AR5416_MAX_PWR_RANGE_IN_HALF_DB 64
-#define AR5416_MAX_CHAINS               3
-#define AR5416_PWR_TABLE_OFFSET         -5
-
-/* Rx gain type values */
-#define AR5416_EEP_RXGAIN_23DB_BACKOFF     0
-#define AR5416_EEP_RXGAIN_13DB_BACKOFF     1
-#define AR5416_EEP_RXGAIN_ORIG             2
-
-/* Tx gain type values */
-#define AR5416_EEP_TXGAIN_ORIGINAL         0
-#define AR5416_EEP_TXGAIN_HIGH_POWER       1
-
-#define AR5416_EEP4K_START_LOC                64
-#define AR5416_EEP4K_NUM_2G_CAL_PIERS         3
-#define AR5416_EEP4K_NUM_2G_CCK_TARGET_POWERS 3
-#define AR5416_EEP4K_NUM_2G_20_TARGET_POWERS  3
-#define AR5416_EEP4K_NUM_2G_40_TARGET_POWERS  3
-#define AR5416_EEP4K_NUM_CTLS                 12
-#define AR5416_EEP4K_NUM_BAND_EDGES           4
-#define AR5416_EEP4K_NUM_PD_GAINS             2
-#define AR5416_EEP4K_PD_GAINS_IN_MASK         4
-#define AR5416_EEP4K_PD_GAIN_ICEPTS           5
-#define AR5416_EEP4K_MAX_CHAINS               1
-
-#define AR9280_TX_GAIN_TABLE_SIZE 22
-
-enum eeprom_param {
-       EEP_NFTHRESH_5,
-       EEP_NFTHRESH_2,
-       EEP_MAC_MSW,
-       EEP_MAC_MID,
-       EEP_MAC_LSW,
-       EEP_REG_0,
-       EEP_REG_1,
-       EEP_OP_CAP,
-       EEP_OP_MODE,
-       EEP_RF_SILENT,
-       EEP_OB_5,
-       EEP_DB_5,
-       EEP_OB_2,
-       EEP_DB_2,
-       EEP_MINOR_REV,
-       EEP_TX_MASK,
-       EEP_RX_MASK,
-       EEP_RXGAIN_TYPE,
-       EEP_TXGAIN_TYPE,
-       EEP_OL_PWRCTRL,
-       EEP_RC_CHAIN_MASK,
-       EEP_DAC_HPWR_5G,
-       EEP_FRAC_N_5G
-};
-
-enum ar5416_rates {
-       rate6mb, rate9mb, rate12mb, rate18mb,
-       rate24mb, rate36mb, rate48mb, rate54mb,
-       rate1l, rate2l, rate2s, rate5_5l,
-       rate5_5s, rate11l, rate11s, rateXr,
-       rateHt20_0, rateHt20_1, rateHt20_2, rateHt20_3,
-       rateHt20_4, rateHt20_5, rateHt20_6, rateHt20_7,
-       rateHt40_0, rateHt40_1, rateHt40_2, rateHt40_3,
-       rateHt40_4, rateHt40_5, rateHt40_6, rateHt40_7,
-       rateDupCck, rateDupOfdm, rateExtCck, rateExtOfdm,
-       Ar5416RateSize
-};
-
-enum ath9k_hal_freq_band {
-       ATH9K_HAL_FREQ_BAND_5GHZ = 0,
-       ATH9K_HAL_FREQ_BAND_2GHZ = 1
-};
-
-struct base_eep_header {
-       u16 length;
-       u16 checksum;
-       u16 version;
-       u8 opCapFlags;
-       u8 eepMisc;
-       u16 regDmn[2];
-       u8 macAddr[6];
-       u8 rxMask;
-       u8 txMask;
-       u16 rfSilent;
-       u16 blueToothOptions;
-       u16 deviceCap;
-       u32 binBuildNumber;
-       u8 deviceType;
-       u8 pwdclkind;
-       u8 futureBase_1[2];
-       u8 rxGainType;
-       u8 dacHiPwrMode_5G;
-       u8 openLoopPwrCntl;
-       u8 dacLpMode;
-       u8 txGainType;
-       u8 rcChainMask;
-       u8 desiredScaleCCK;
-       u8 power_table_offset;
-       u8 frac_n_5g;
-       u8 futureBase_3[21];
-} __packed;
-
-struct base_eep_header_4k {
-       u16 length;
-       u16 checksum;
-       u16 version;
-       u8 opCapFlags;
-       u8 eepMisc;
-       u16 regDmn[2];
-       u8 macAddr[6];
-       u8 rxMask;
-       u8 txMask;
-       u16 rfSilent;
-       u16 blueToothOptions;
-       u16 deviceCap;
-       u32 binBuildNumber;
-       u8 deviceType;
-       u8 txGainType;
-} __packed;
-
-
-struct spur_chan {
-       u16 spurChan;
-       u8 spurRangeLow;
-       u8 spurRangeHigh;
-} __packed;
-
-struct modal_eep_header {
-       u32 antCtrlChain[AR5416_MAX_CHAINS];
-       u32 antCtrlCommon;
-       u8 antennaGainCh[AR5416_MAX_CHAINS];
-       u8 switchSettling;
-       u8 txRxAttenCh[AR5416_MAX_CHAINS];
-       u8 rxTxMarginCh[AR5416_MAX_CHAINS];
-       u8 adcDesiredSize;
-       u8 pgaDesiredSize;
-       u8 xlnaGainCh[AR5416_MAX_CHAINS];
-       u8 txEndToXpaOff;
-       u8 txEndToRxOn;
-       u8 txFrameToXpaOn;
-       u8 thresh62;
-       u8 noiseFloorThreshCh[AR5416_MAX_CHAINS];
-       u8 xpdGain;
-       u8 xpd;
-       u8 iqCalICh[AR5416_MAX_CHAINS];
-       u8 iqCalQCh[AR5416_MAX_CHAINS];
-       u8 pdGainOverlap;
-       u8 ob;
-       u8 db;
-       u8 xpaBiasLvl;
-       u8 pwrDecreaseFor2Chain;
-       u8 pwrDecreaseFor3Chain;
-       u8 txFrameToDataStart;
-       u8 txFrameToPaOn;
-       u8 ht40PowerIncForPdadc;
-       u8 bswAtten[AR5416_MAX_CHAINS];
-       u8 bswMargin[AR5416_MAX_CHAINS];
-       u8 swSettleHt40;
-       u8 xatten2Db[AR5416_MAX_CHAINS];
-       u8 xatten2Margin[AR5416_MAX_CHAINS];
-       u8 ob_ch1;
-       u8 db_ch1;
-       u8 useAnt1:1,
-           force_xpaon:1,
-           local_bias:1,
-           femBandSelectUsed:1, xlnabufin:1, xlnaisel:2, xlnabufmode:1;
-       u8 miscBits;
-       u16 xpaBiasLvlFreq[3];
-       u8 futureModal[6];
-
-       struct spur_chan spurChans[AR5416_EEPROM_MODAL_SPURS];
-} __packed;
-
-struct calDataPerFreqOpLoop {
-       u8 pwrPdg[2][5];
-       u8 vpdPdg[2][5];
-       u8 pcdac[2][5];
-       u8 empty[2][5];
-} __packed;
-
-struct modal_eep_4k_header {
-       u32  antCtrlChain[AR5416_EEP4K_MAX_CHAINS];
-       u32  antCtrlCommon;
-       u8   antennaGainCh[AR5416_EEP4K_MAX_CHAINS];
-       u8   switchSettling;
-       u8   txRxAttenCh[AR5416_EEP4K_MAX_CHAINS];
-       u8   rxTxMarginCh[AR5416_EEP4K_MAX_CHAINS];
-       u8   adcDesiredSize;
-       u8   pgaDesiredSize;
-       u8   xlnaGainCh[AR5416_EEP4K_MAX_CHAINS];
-       u8   txEndToXpaOff;
-       u8   txEndToRxOn;
-       u8   txFrameToXpaOn;
-       u8   thresh62;
-       u8   noiseFloorThreshCh[AR5416_EEP4K_MAX_CHAINS];
-       u8   xpdGain;
-       u8   xpd;
-       u8   iqCalICh[AR5416_EEP4K_MAX_CHAINS];
-       u8   iqCalQCh[AR5416_EEP4K_MAX_CHAINS];
-       u8   pdGainOverlap;
-       u8   ob_01;
-       u8   db1_01;
-       u8   xpaBiasLvl;
-       u8   txFrameToDataStart;
-       u8   txFrameToPaOn;
-       u8   ht40PowerIncForPdadc;
-       u8   bswAtten[AR5416_EEP4K_MAX_CHAINS];
-       u8   bswMargin[AR5416_EEP4K_MAX_CHAINS];
-       u8   swSettleHt40;
-       u8   xatten2Db[AR5416_EEP4K_MAX_CHAINS];
-       u8   xatten2Margin[AR5416_EEP4K_MAX_CHAINS];
-       u8   db2_01;
-       u8   version;
-       u16  ob_234;
-       u16  db1_234;
-       u16  db2_234;
-       u8   futureModal[4];
-
-       struct spur_chan spurChans[AR5416_EEPROM_MODAL_SPURS];
-} __packed;
-
-
-struct cal_data_per_freq {
-       u8 pwrPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
-       u8 vpdPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
-} __packed;
-
-struct cal_data_per_freq_4k {
-       u8 pwrPdg[AR5416_EEP4K_NUM_PD_GAINS][AR5416_EEP4K_PD_GAIN_ICEPTS];
-       u8 vpdPdg[AR5416_EEP4K_NUM_PD_GAINS][AR5416_EEP4K_PD_GAIN_ICEPTS];
-} __packed;
-
-struct cal_target_power_leg {
-       u8 bChannel;
-       u8 tPow2x[4];
-} __packed;
-
-struct cal_target_power_ht {
-       u8 bChannel;
-       u8 tPow2x[8];
-} __packed;
-
-
-#ifdef __BIG_ENDIAN_BITFIELD
-struct cal_ctl_edges {
-       u8 bChannel;
-       u8 flag:2, tPower:6;
-} __packed;
-#else
-struct cal_ctl_edges {
-       u8 bChannel;
-       u8 tPower:6, flag:2;
-} __packed;
-#endif
-
-struct cal_ctl_data {
-       struct cal_ctl_edges
-       ctlEdges[AR5416_MAX_CHAINS][AR5416_NUM_BAND_EDGES];
-} __packed;
-
-struct cal_ctl_data_4k {
-       struct cal_ctl_edges
-       ctlEdges[AR5416_EEP4K_MAX_CHAINS][AR5416_EEP4K_NUM_BAND_EDGES];
-} __packed;
-
-struct ar5416_eeprom_def {
-       struct base_eep_header baseEepHeader;
-       u8 custData[64];
-       struct modal_eep_header modalHeader[2];
-       u8 calFreqPier5G[AR5416_NUM_5G_CAL_PIERS];
-       u8 calFreqPier2G[AR5416_NUM_2G_CAL_PIERS];
-       struct cal_data_per_freq
-        calPierData5G[AR5416_MAX_CHAINS][AR5416_NUM_5G_CAL_PIERS];
-       struct cal_data_per_freq
-        calPierData2G[AR5416_MAX_CHAINS][AR5416_NUM_2G_CAL_PIERS];
-       struct cal_target_power_leg
-        calTargetPower5G[AR5416_NUM_5G_20_TARGET_POWERS];
-       struct cal_target_power_ht
-        calTargetPower5GHT20[AR5416_NUM_5G_20_TARGET_POWERS];
-       struct cal_target_power_ht
-        calTargetPower5GHT40[AR5416_NUM_5G_40_TARGET_POWERS];
-       struct cal_target_power_leg
-        calTargetPowerCck[AR5416_NUM_2G_CCK_TARGET_POWERS];
-       struct cal_target_power_leg
-        calTargetPower2G[AR5416_NUM_2G_20_TARGET_POWERS];
-       struct cal_target_power_ht
-        calTargetPower2GHT20[AR5416_NUM_2G_20_TARGET_POWERS];
-       struct cal_target_power_ht
-        calTargetPower2GHT40[AR5416_NUM_2G_40_TARGET_POWERS];
-       u8 ctlIndex[AR5416_NUM_CTLS];
-       struct cal_ctl_data ctlData[AR5416_NUM_CTLS];
-       u8 padding;
-} __packed;
-
-struct ar5416_eeprom_4k {
-       struct base_eep_header_4k baseEepHeader;
-       u8 custData[20];
-       struct modal_eep_4k_header modalHeader;
-       u8 calFreqPier2G[AR5416_EEP4K_NUM_2G_CAL_PIERS];
-       struct cal_data_per_freq_4k
-       calPierData2G[AR5416_EEP4K_MAX_CHAINS][AR5416_EEP4K_NUM_2G_CAL_PIERS];
-       struct cal_target_power_leg
-       calTargetPowerCck[AR5416_EEP4K_NUM_2G_CCK_TARGET_POWERS];
-       struct cal_target_power_leg
-       calTargetPower2G[AR5416_EEP4K_NUM_2G_20_TARGET_POWERS];
-       struct cal_target_power_ht
-       calTargetPower2GHT20[AR5416_EEP4K_NUM_2G_20_TARGET_POWERS];
-       struct cal_target_power_ht
-       calTargetPower2GHT40[AR5416_EEP4K_NUM_2G_40_TARGET_POWERS];
-       u8 ctlIndex[AR5416_EEP4K_NUM_CTLS];
-       struct cal_ctl_data_4k ctlData[AR5416_EEP4K_NUM_CTLS];
-       u8 padding;
-} __packed;
-
-enum reg_ext_bitmap {
-       REG_EXT_JAPAN_MIDBAND = 1,
-       REG_EXT_FCC_DFS_HT40 = 2,
-       REG_EXT_JAPAN_NONDFS_HT40 = 3,
-       REG_EXT_JAPAN_DFS_HT40 = 4
-};
-
-struct ath9k_country_entry {
-       u16 countryCode;
-       u16 regDmnEnum;
-       u16 regDmn5G;
-       u16 regDmn2G;
-       u8 isMultidomain;
-       u8 iso[3];
-};
-
-enum ath9k_eep_map {
-       EEP_MAP_DEFAULT = 0x0,
-       EEP_MAP_4KBITS,
-       EEP_MAP_MAX
-};
-
-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);
-       int (*get_eeprom_ver)(struct ath_hw *hw);
-       int (*get_eeprom_rev)(struct ath_hw *hw);
-       u8 (*get_num_ant_config)(struct ath_hw *hw, enum ieee80211_band band);
-       u16 (*get_eeprom_antenna_cfg)(struct ath_hw *hw,
-                                     struct ath9k_channel *chan);
-       void (*set_board_values)(struct ath_hw *hw, struct ath9k_channel *chan);
-       void (*set_addac)(struct ath_hw *hw, struct ath9k_channel *chan);
-       int (*set_txpower)(struct ath_hw *hw, struct ath9k_channel *chan,
-                          u16 cfgCtl, u8 twiceAntennaReduction,
-                          u8 twiceMaxRegulatoryPower, u8 powerLimit);
-       u16 (*get_spur_channel)(struct ath_hw *ah, u16 i, bool is2GHz);
-};
-
-#define ar5416_get_ntxchains(_txchainmask)                     \
-       (((_txchainmask >> 2) & 1) +                            \
-        ((_txchainmask >> 1) & 1) + (_txchainmask & 1))
-
-int ath9k_hw_eeprom_attach(struct ath_hw *ah);
-
-#endif /* EEPROM_H */
diff --git a/drivers/net/wireless/ath9k/hw.c b/drivers/net/wireless/ath9k/hw.c
deleted file mode 100644 (file)
index b15eaf8..0000000
+++ /dev/null
@@ -1,3898 +0,0 @@
-/*
- * Copyright (c) 2008-2009 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/io.h>
-#include <asm/unaligned.h>
-
-#include "ath9k.h"
-#include "initvals.h"
-
-static int btcoex_enable;
-module_param(btcoex_enable, bool, 0);
-MODULE_PARM_DESC(btcoex_enable, "Enable Bluetooth coexistence support");
-
-#define ATH9K_CLOCK_RATE_CCK           22
-#define ATH9K_CLOCK_RATE_5GHZ_OFDM     40
-#define ATH9K_CLOCK_RATE_2GHZ_OFDM     44
-
-static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type);
-static void ath9k_hw_set_regs(struct ath_hw *ah, struct ath9k_channel *chan,
-                             enum ath9k_ht_macmode macmode);
-static u32 ath9k_hw_ini_fixup(struct ath_hw *ah,
-                             struct ar5416_eeprom_def *pEepData,
-                             u32 reg, u32 value);
-static void ath9k_hw_9280_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan);
-static void ath9k_hw_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan);
-
-/********************/
-/* Helper Functions */
-/********************/
-
-static u32 ath9k_hw_mac_usec(struct ath_hw *ah, u32 clks)
-{
-       struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
-
-       if (!ah->curchan) /* should really check for CCK instead */
-               return clks / ATH9K_CLOCK_RATE_CCK;
-       if (conf->channel->band == IEEE80211_BAND_2GHZ)
-               return clks / ATH9K_CLOCK_RATE_2GHZ_OFDM;
-
-       return clks / ATH9K_CLOCK_RATE_5GHZ_OFDM;
-}
-
-static u32 ath9k_hw_mac_to_usec(struct ath_hw *ah, u32 clks)
-{
-       struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
-
-       if (conf_is_ht40(conf))
-               return ath9k_hw_mac_usec(ah, clks) / 2;
-       else
-               return ath9k_hw_mac_usec(ah, clks);
-}
-
-static u32 ath9k_hw_mac_clks(struct ath_hw *ah, u32 usecs)
-{
-       struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
-
-       if (!ah->curchan) /* should really check for CCK instead */
-               return usecs *ATH9K_CLOCK_RATE_CCK;
-       if (conf->channel->band == IEEE80211_BAND_2GHZ)
-               return usecs *ATH9K_CLOCK_RATE_2GHZ_OFDM;
-       return usecs *ATH9K_CLOCK_RATE_5GHZ_OFDM;
-}
-
-static u32 ath9k_hw_mac_to_clks(struct ath_hw *ah, u32 usecs)
-{
-       struct ieee80211_conf *conf = &ah->ah_sc->hw->conf;
-
-       if (conf_is_ht40(conf))
-               return ath9k_hw_mac_clks(ah, usecs) * 2;
-       else
-               return ath9k_hw_mac_clks(ah, usecs);
-}
-
-bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout)
-{
-       int i;
-
-       BUG_ON(timeout < AH_TIME_QUANTUM);
-
-       for (i = 0; i < (timeout / AH_TIME_QUANTUM); i++) {
-               if ((REG_READ(ah, reg) & mask) == val)
-                       return true;
-
-               udelay(AH_TIME_QUANTUM);
-       }
-
-       DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
-               "timeout (%d us) on reg 0x%x: 0x%08x & 0x%08x != 0x%08x\n",
-               timeout, reg, REG_READ(ah, reg), mask, val);
-
-       return false;
-}
-
-u32 ath9k_hw_reverse_bits(u32 val, u32 n)
-{
-       u32 retval;
-       int i;
-
-       for (i = 0, retval = 0; i < n; i++) {
-               retval = (retval << 1) | (val & 1);
-               val >>= 1;
-       }
-       return retval;
-}
-
-bool ath9k_get_channel_edges(struct ath_hw *ah,
-                            u16 flags, u16 *low,
-                            u16 *high)
-{
-       struct ath9k_hw_capabilities *pCap = &ah->caps;
-
-       if (flags & CHANNEL_5GHZ) {
-               *low = pCap->low_5ghz_chan;
-               *high = pCap->high_5ghz_chan;
-               return true;
-       }
-       if ((flags & CHANNEL_2GHZ)) {
-               *low = pCap->low_2ghz_chan;
-               *high = pCap->high_2ghz_chan;
-               return true;
-       }
-       return false;
-}
-
-u16 ath9k_hw_computetxtime(struct ath_hw *ah,
-                          struct ath_rate_table *rates,
-                          u32 frameLen, u16 rateix,
-                          bool shortPreamble)
-{
-       u32 bitsPerSymbol, numBits, numSymbols, phyTime, txTime;
-       u32 kbps;
-
-       kbps = rates->info[rateix].ratekbps;
-
-       if (kbps == 0)
-               return 0;
-
-       switch (rates->info[rateix].phy) {
-       case WLAN_RC_PHY_CCK:
-               phyTime = CCK_PREAMBLE_BITS + CCK_PLCP_BITS;
-               if (shortPreamble && rates->info[rateix].short_preamble)
-                       phyTime >>= 1;
-               numBits = frameLen << 3;
-               txTime = CCK_SIFS_TIME + phyTime + ((numBits * 1000) / kbps);
-               break;
-       case WLAN_RC_PHY_OFDM:
-               if (ah->curchan && IS_CHAN_QUARTER_RATE(ah->curchan)) {
-                       bitsPerSymbol = (kbps * OFDM_SYMBOL_TIME_QUARTER) / 1000;
-                       numBits = OFDM_PLCP_BITS + (frameLen << 3);
-                       numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol);
-                       txTime = OFDM_SIFS_TIME_QUARTER
-                               + OFDM_PREAMBLE_TIME_QUARTER
-                               + (numSymbols * OFDM_SYMBOL_TIME_QUARTER);
-               } else if (ah->curchan &&
-                          IS_CHAN_HALF_RATE(ah->curchan)) {
-                       bitsPerSymbol = (kbps * OFDM_SYMBOL_TIME_HALF) / 1000;
-                       numBits = OFDM_PLCP_BITS + (frameLen << 3);
-                       numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol);
-                       txTime = OFDM_SIFS_TIME_HALF +
-                               OFDM_PREAMBLE_TIME_HALF
-                               + (numSymbols * OFDM_SYMBOL_TIME_HALF);
-               } else {
-                       bitsPerSymbol = (kbps * OFDM_SYMBOL_TIME) / 1000;
-                       numBits = OFDM_PLCP_BITS + (frameLen << 3);
-                       numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol);
-                       txTime = OFDM_SIFS_TIME + OFDM_PREAMBLE_TIME
-                               + (numSymbols * OFDM_SYMBOL_TIME);
-               }
-               break;
-       default:
-               DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
-                       "Unknown phy %u (rate ix %u)\n",
-                       rates->info[rateix].phy, rateix);
-               txTime = 0;
-               break;
-       }
-
-       return txTime;
-}
-
-void ath9k_hw_get_channel_centers(struct ath_hw *ah,
-                                 struct ath9k_channel *chan,
-                                 struct chan_centers *centers)
-{
-       int8_t extoff;
-
-       if (!IS_CHAN_HT40(chan)) {
-               centers->ctl_center = centers->ext_center =
-                       centers->synth_center = chan->channel;
-               return;
-       }
-
-       if ((chan->chanmode == CHANNEL_A_HT40PLUS) ||
-           (chan->chanmode == CHANNEL_G_HT40PLUS)) {
-               centers->synth_center =
-                       chan->channel + HT40_CHANNEL_CENTER_SHIFT;
-               extoff = 1;
-       } else {
-               centers->synth_center =
-                       chan->channel - HT40_CHANNEL_CENTER_SHIFT;
-               extoff = -1;
-       }
-
-       centers->ctl_center =
-               centers->synth_center - (extoff * HT40_CHANNEL_CENTER_SHIFT);
-       centers->ext_center =
-               centers->synth_center + (extoff *
-                        ((ah->extprotspacing == ATH9K_HT_EXTPROTSPACING_20) ?
-                         HT40_CHANNEL_CENTER_SHIFT : 15));
-}
-
-/******************/
-/* Chip Revisions */
-/******************/
-
-static void ath9k_hw_read_revisions(struct ath_hw *ah)
-{
-       u32 val;
-
-       val = REG_READ(ah, AR_SREV) & AR_SREV_ID;
-
-       if (val == 0xFF) {
-               val = REG_READ(ah, AR_SREV);
-               ah->hw_version.macVersion =
-                       (val & AR_SREV_VERSION2) >> AR_SREV_TYPE2_S;
-               ah->hw_version.macRev = MS(val, AR_SREV_REVISION2);
-               ah->is_pciexpress = (val & AR_SREV_TYPE2_HOST_MODE) ? 0 : 1;
-       } else {
-               if (!AR_SREV_9100(ah))
-                       ah->hw_version.macVersion = MS(val, AR_SREV_VERSION);
-
-               ah->hw_version.macRev = val & AR_SREV_REVISION;
-
-               if (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCIE)
-                       ah->is_pciexpress = true;
-       }
-}
-
-static int ath9k_hw_get_radiorev(struct ath_hw *ah)
-{
-       u32 val;
-       int i;
-
-       REG_WRITE(ah, AR_PHY(0x36), 0x00007058);
-
-       for (i = 0; i < 8; i++)
-               REG_WRITE(ah, AR_PHY(0x20), 0x00010000);
-       val = (REG_READ(ah, AR_PHY(256)) >> 24) & 0xff;
-       val = ((val & 0xf0) >> 4) | ((val & 0x0f) << 4);
-
-       return ath9k_hw_reverse_bits(val, 8);
-}
-
-/************************************/
-/* HW Attach, Detach, Init Routines */
-/************************************/
-
-static void ath9k_hw_disablepcie(struct ath_hw *ah)
-{
-       if (AR_SREV_9100(ah))
-               return;
-
-       REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00);
-       REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
-       REG_WRITE(ah, AR_PCIE_SERDES, 0x28000029);
-       REG_WRITE(ah, AR_PCIE_SERDES, 0x57160824);
-       REG_WRITE(ah, AR_PCIE_SERDES, 0x25980579);
-       REG_WRITE(ah, AR_PCIE_SERDES, 0x00000000);
-       REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
-       REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
-       REG_WRITE(ah, AR_PCIE_SERDES, 0x000e1007);
-
-       REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
-}
-
-static bool ath9k_hw_chip_test(struct ath_hw *ah)
-{
-       u32 regAddr[2] = { AR_STA_ID0, AR_PHY_BASE + (8 << 2) };
-       u32 regHold[2];
-       u32 patternData[4] = { 0x55555555,
-                              0xaaaaaaaa,
-                              0x66666666,
-                              0x99999999 };
-       int i, j;
-
-       for (i = 0; i < 2; i++) {
-               u32 addr = regAddr[i];
-               u32 wrData, rdData;
-
-               regHold[i] = REG_READ(ah, addr);
-               for (j = 0; j < 0x100; j++) {
-                       wrData = (j << 16) | j;
-                       REG_WRITE(ah, addr, wrData);
-                       rdData = REG_READ(ah, addr);
-                       if (rdData != wrData) {
-                               DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
-                                       "address test failed "
-                                       "addr: 0x%08x - wr:0x%08x != rd:0x%08x\n",
-                                       addr, wrData, rdData);
-                               return false;
-                       }
-               }
-               for (j = 0; j < 4; j++) {
-                       wrData = patternData[j];
-                       REG_WRITE(ah, addr, wrData);
-                       rdData = REG_READ(ah, addr);
-                       if (wrData != rdData) {
-                               DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
-                                       "address test failed "
-                                       "addr: 0x%08x - wr:0x%08x != rd:0x%08x\n",
-                                       addr, wrData, rdData);
-                               return false;
-                       }
-               }
-               REG_WRITE(ah, regAddr[i], regHold[i]);
-       }
-       udelay(100);
-
-       return true;
-}
-
-static const char *ath9k_hw_devname(u16 devid)
-{
-       switch (devid) {
-       case AR5416_DEVID_PCI:
-               return "Atheros 5416";
-       case AR5416_DEVID_PCIE:
-               return "Atheros 5418";
-       case AR9160_DEVID_PCI:
-               return "Atheros 9160";
-       case AR5416_AR9100_DEVID:
-               return "Atheros 9100";
-       case AR9280_DEVID_PCI:
-       case AR9280_DEVID_PCIE:
-               return "Atheros 9280";
-       case AR9285_DEVID_PCIE:
-               return "Atheros 9285";
-       }
-
-       return NULL;
-}
-
-static void ath9k_hw_set_defaults(struct ath_hw *ah)
-{
-       int i;
-
-       ah->config.dma_beacon_response_time = 2;
-       ah->config.sw_beacon_response_time = 10;
-       ah->config.additional_swba_backoff = 0;
-       ah->config.ack_6mb = 0x0;
-       ah->config.cwm_ignore_extcca = 0;
-       ah->config.pcie_powersave_enable = 0;
-       ah->config.pcie_l1skp_enable = 0;
-       ah->config.pcie_clock_req = 0;
-       ah->config.pcie_power_reset = 0x100;
-       ah->config.pcie_restore = 0;
-       ah->config.pcie_waen = 0;
-       ah->config.analog_shiftreg = 1;
-       ah->config.ht_enable = 1;
-       ah->config.ofdm_trig_low = 200;
-       ah->config.ofdm_trig_high = 500;
-       ah->config.cck_trig_high = 200;
-       ah->config.cck_trig_low = 100;
-       ah->config.enable_ani = 1;
-       ah->config.noise_immunity_level = 4;
-       ah->config.ofdm_weaksignal_det = 1;
-       ah->config.cck_weaksignal_thr = 0;
-       ah->config.spur_immunity_level = 2;
-       ah->config.firstep_level = 0;
-       ah->config.rssi_thr_high = 40;
-       ah->config.rssi_thr_low = 7;
-       ah->config.diversity_control = 0;
-       ah->config.antenna_switch_swap = 0;
-
-       for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
-               ah->config.spurchans[i][0] = AR_NO_SPUR;
-               ah->config.spurchans[i][1] = AR_NO_SPUR;
-       }
-
-       ah->config.intr_mitigation = 1;
-
-       /*
-        * We need this for PCI devices only (Cardbus, PCI, miniPCI)
-        * _and_ if on non-uniprocessor systems (Multiprocessor/HT).
-        * This means we use it for all AR5416 devices, and the few
-        * minor PCI AR9280 devices out there.
-        *
-        * Serialization is required because these devices do not handle
-        * well the case of two concurrent reads/writes due to the latency
-        * involved. During one read/write another read/write can be issued
-        * on another CPU while the previous read/write may still be working
-        * on our hardware, if we hit this case the hardware poops in a loop.
-        * We prevent this by serializing reads and writes.
-        *
-        * This issue is not present on PCI-Express devices or pre-AR5416
-        * devices (legacy, 802.11abg).
-        */
-       if (num_possible_cpus() > 1)
-               ah->config.serialize_regmode = SER_REG_MODE_AUTO;
-}
-
-static struct ath_hw *ath9k_hw_newstate(u16 devid, struct ath_softc *sc,
-                                       int *status)
-{
-       struct ath_hw *ah;
-
-       ah = kzalloc(sizeof(struct ath_hw), GFP_KERNEL);
-       if (ah == NULL) {
-               DPRINTF(sc, ATH_DBG_FATAL,
-                       "Cannot allocate memory for state block\n");
-               *status = -ENOMEM;
-               return NULL;
-       }
-
-       ah->ah_sc = sc;
-       ah->hw_version.magic = AR5416_MAGIC;
-       ah->regulatory.country_code = CTRY_DEFAULT;
-       ah->hw_version.devid = devid;
-       ah->hw_version.subvendorid = 0;
-
-       ah->ah_flags = 0;
-       if ((devid == AR5416_AR9100_DEVID))
-               ah->hw_version.macVersion = AR_SREV_VERSION_9100;
-       if (!AR_SREV_9100(ah))
-               ah->ah_flags = AH_USE_EEPROM;
-
-       ah->regulatory.power_limit = MAX_RATE_POWER;
-       ah->regulatory.tp_scale = ATH9K_TP_SCALE_MAX;
-       ah->atim_window = 0;
-       ah->diversity_control = ah->config.diversity_control;
-       ah->antenna_switch_swap =
-               ah->config.antenna_switch_swap;
-       ah->sta_id1_defaults = AR_STA_ID1_CRPT_MIC_ENABLE;
-       ah->beacon_interval = 100;
-       ah->enable_32kHz_clock = DONT_USE_32KHZ;
-       ah->slottime = (u32) -1;
-       ah->acktimeout = (u32) -1;
-       ah->ctstimeout = (u32) -1;
-       ah->globaltxtimeout = (u32) -1;
-
-       ah->gbeacon_rate = 0;
-
-       return ah;
-}
-
-static int ath9k_hw_rfattach(struct ath_hw *ah)
-{
-       bool rfStatus = false;
-       int ecode = 0;
-
-       rfStatus = ath9k_hw_init_rf(ah, &ecode);
-       if (!rfStatus) {
-               DPRINTF(ah->ah_sc, ATH_DBG_RESET,
-                       "RF setup failed, status %u\n", ecode);
-               return ecode;
-       }
-
-       return 0;
-}
-
-static int ath9k_hw_rf_claim(struct ath_hw *ah)
-{
-       u32 val;
-
-       REG_WRITE(ah, AR_PHY(0), 0x00000007);
-
-       val = ath9k_hw_get_radiorev(ah);
-       switch (val & AR_RADIO_SREV_MAJOR) {
-       case 0:
-               val = AR_RAD5133_SREV_MAJOR;
-               break;
-       case AR_RAD5133_SREV_MAJOR:
-       case AR_RAD5122_SREV_MAJOR:
-       case AR_RAD2133_SREV_MAJOR:
-       case AR_RAD2122_SREV_MAJOR:
-               break;
-       default:
-               DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
-                       "5G Radio Chip Rev 0x%02X is not "
-                       "supported by this driver\n",
-                       ah->hw_version.analog5GhzRev);
-               return -EOPNOTSUPP;
-       }
-
-       ah->hw_version.analog5GhzRev = val;
-
-       return 0;
-}
-
-static int ath9k_hw_init_macaddr(struct ath_hw *ah)
-{
-       u32 sum;
-       int i;
-       u16 eeval;
-
-       sum = 0;
-       for (i = 0; i < 3; i++) {
-               eeval = ah->eep_ops->get_eeprom(ah, AR_EEPROM_MAC(i));
-               sum += eeval;
-               ah->macaddr[2 * i] = eeval >> 8;
-               ah->macaddr[2 * i + 1] = eeval & 0xff;
-       }
-       if (sum == 0 || sum == 0xffff * 3) {
-               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-                       "mac address read failed: %pM\n",
-                       ah->macaddr);
-               return -EADDRNOTAVAIL;
-       }
-
-       return 0;
-}
-
-static void ath9k_hw_init_rxgain_ini(struct ath_hw *ah)
-{
-       u32 rxgain_type;
-
-       if (ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV) >= AR5416_EEP_MINOR_VER_17) {
-               rxgain_type = ah->eep_ops->get_eeprom(ah, EEP_RXGAIN_TYPE);
-
-               if (rxgain_type == AR5416_EEP_RXGAIN_13DB_BACKOFF)
-                       INIT_INI_ARRAY(&ah->iniModesRxGain,
-                       ar9280Modes_backoff_13db_rxgain_9280_2,
-                       ARRAY_SIZE(ar9280Modes_backoff_13db_rxgain_9280_2), 6);
-               else if (rxgain_type == AR5416_EEP_RXGAIN_23DB_BACKOFF)
-                       INIT_INI_ARRAY(&ah->iniModesRxGain,
-                       ar9280Modes_backoff_23db_rxgain_9280_2,
-                       ARRAY_SIZE(ar9280Modes_backoff_23db_rxgain_9280_2), 6);
-               else
-                       INIT_INI_ARRAY(&ah->iniModesRxGain,
-                       ar9280Modes_original_rxgain_9280_2,
-                       ARRAY_SIZE(ar9280Modes_original_rxgain_9280_2), 6);
-       } else {
-               INIT_INI_ARRAY(&ah->iniModesRxGain,
-                       ar9280Modes_original_rxgain_9280_2,
-                       ARRAY_SIZE(ar9280Modes_original_rxgain_9280_2), 6);
-       }
-}
-
-static void ath9k_hw_init_txgain_ini(struct ath_hw *ah)
-{
-       u32 txgain_type;
-
-       if (ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV) >= AR5416_EEP_MINOR_VER_19) {
-               txgain_type = ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE);
-
-               if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER)
-                       INIT_INI_ARRAY(&ah->iniModesTxGain,
-                       ar9280Modes_high_power_tx_gain_9280_2,
-                       ARRAY_SIZE(ar9280Modes_high_power_tx_gain_9280_2), 6);
-               else
-                       INIT_INI_ARRAY(&ah->iniModesTxGain,
-                       ar9280Modes_original_tx_gain_9280_2,
-                       ARRAY_SIZE(ar9280Modes_original_tx_gain_9280_2), 6);
-       } else {
-               INIT_INI_ARRAY(&ah->iniModesTxGain,
-               ar9280Modes_original_tx_gain_9280_2,
-               ARRAY_SIZE(ar9280Modes_original_tx_gain_9280_2), 6);
-       }
-}
-
-static int ath9k_hw_post_attach(struct ath_hw *ah)
-{
-       int ecode;
-
-       if (!ath9k_hw_chip_test(ah)) {
-               DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
-                       "hardware self-test failed\n");
-               return -ENODEV;
-       }
-
-       ecode = ath9k_hw_rf_claim(ah);
-       if (ecode != 0)
-               return ecode;
-
-       ecode = ath9k_hw_eeprom_attach(ah);
-       if (ecode != 0)
-               return ecode;
-
-       DPRINTF(ah->ah_sc, ATH_DBG_CONFIG, "Eeprom VER: %d, REV: %d\n",
-               ah->eep_ops->get_eeprom_ver(ah), ah->eep_ops->get_eeprom_rev(ah));
-
-       ecode = ath9k_hw_rfattach(ah);
-       if (ecode != 0)
-               return ecode;
-
-       if (!AR_SREV_9100(ah)) {
-               ath9k_hw_ani_setup(ah);
-               ath9k_hw_ani_attach(ah);
-       }
-
-       return 0;
-}
-
-static struct ath_hw *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc,
-                                        int *status)
-{
-       struct ath_hw *ah;
-       int ecode;
-       u32 i, j;
-
-       ah = ath9k_hw_newstate(devid, sc, status);
-       if (ah == NULL)
-               return NULL;
-
-       ath9k_hw_set_defaults(ah);
-
-       if (ah->config.intr_mitigation != 0)
-               ah->intr_mitigation = true;
-
-       if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) {
-               DPRINTF(sc, ATH_DBG_RESET, "Couldn't reset chip\n");
-               ecode = -EIO;
-               goto bad;
-       }
-
-       if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) {
-               DPRINTF(sc, ATH_DBG_RESET, "Couldn't wakeup chip\n");
-               ecode = -EIO;
-               goto bad;
-       }
-
-       if (ah->config.serialize_regmode == SER_REG_MODE_AUTO) {
-               if (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCI ||
-                   (AR_SREV_9280(ah) && !ah->is_pciexpress)) {
-                       ah->config.serialize_regmode =
-                               SER_REG_MODE_ON;
-               } else {
-                       ah->config.serialize_regmode =
-                               SER_REG_MODE_OFF;
-               }
-       }
-
-       DPRINTF(sc, ATH_DBG_RESET, "serialize_regmode is %d\n",
-               ah->config.serialize_regmode);
-
-       if ((ah->hw_version.macVersion != AR_SREV_VERSION_5416_PCI) &&
-           (ah->hw_version.macVersion != AR_SREV_VERSION_5416_PCIE) &&
-           (ah->hw_version.macVersion != AR_SREV_VERSION_9160) &&
-           (!AR_SREV_9100(ah)) && (!AR_SREV_9280(ah)) && (!AR_SREV_9285(ah))) {
-               DPRINTF(sc, ATH_DBG_RESET,
-                       "Mac Chip Rev 0x%02x.%x is not supported by "
-                       "this driver\n", ah->hw_version.macVersion,
-                       ah->hw_version.macRev);
-               ecode = -EOPNOTSUPP;
-               goto bad;
-       }
-
-       if (AR_SREV_9100(ah)) {
-               ah->iq_caldata.calData = &iq_cal_multi_sample;
-               ah->supp_cals = IQ_MISMATCH_CAL;
-               ah->is_pciexpress = false;
-       }
-       ah->hw_version.phyRev = REG_READ(ah, AR_PHY_CHIP_ID);
-
-       if (AR_SREV_9160_10_OR_LATER(ah)) {
-               if (AR_SREV_9280_10_OR_LATER(ah)) {
-                       ah->iq_caldata.calData = &iq_cal_single_sample;
-                       ah->adcgain_caldata.calData =
-                               &adc_gain_cal_single_sample;
-                       ah->adcdc_caldata.calData =
-                               &adc_dc_cal_single_sample;
-                       ah->adcdc_calinitdata.calData =
-                               &adc_init_dc_cal;
-               } else {
-                       ah->iq_caldata.calData = &iq_cal_multi_sample;
-                       ah->adcgain_caldata.calData =
-                               &adc_gain_cal_multi_sample;
-                       ah->adcdc_caldata.calData =
-                               &adc_dc_cal_multi_sample;
-                       ah->adcdc_calinitdata.calData =
-                               &adc_init_dc_cal;
-               }
-               ah->supp_cals = ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL;
-       }
-
-       ah->ani_function = ATH9K_ANI_ALL;
-       if (AR_SREV_9280_10_OR_LATER(ah))
-               ah->ani_function &= ~ATH9K_ANI_NOISE_IMMUNITY_LEVEL;
-
-       DPRINTF(sc, ATH_DBG_RESET,
-               "This Mac Chip Rev 0x%02x.%x is \n",
-               ah->hw_version.macVersion, ah->hw_version.macRev);
-
-       if (AR_SREV_9285_12_OR_LATER(ah)) {
-
-               INIT_INI_ARRAY(&ah->iniModes, ar9285Modes_9285_1_2,
-                              ARRAY_SIZE(ar9285Modes_9285_1_2), 6);
-               INIT_INI_ARRAY(&ah->iniCommon, ar9285Common_9285_1_2,
-                              ARRAY_SIZE(ar9285Common_9285_1_2), 2);
-
-               if (ah->config.pcie_clock_req) {
-                       INIT_INI_ARRAY(&ah->iniPcieSerdes,
-                       ar9285PciePhy_clkreq_off_L1_9285_1_2,
-                       ARRAY_SIZE(ar9285PciePhy_clkreq_off_L1_9285_1_2), 2);
-               } else {
-                       INIT_INI_ARRAY(&ah->iniPcieSerdes,
-                       ar9285PciePhy_clkreq_always_on_L1_9285_1_2,
-                       ARRAY_SIZE(ar9285PciePhy_clkreq_always_on_L1_9285_1_2),
-                                 2);
-               }
-       } else if (AR_SREV_9285_10_OR_LATER(ah)) {
-               INIT_INI_ARRAY(&ah->iniModes, ar9285Modes_9285,
-                              ARRAY_SIZE(ar9285Modes_9285), 6);
-               INIT_INI_ARRAY(&ah->iniCommon, ar9285Common_9285,
-                              ARRAY_SIZE(ar9285Common_9285), 2);
-
-               if (ah->config.pcie_clock_req) {
-                       INIT_INI_ARRAY(&ah->iniPcieSerdes,
-                       ar9285PciePhy_clkreq_off_L1_9285,
-                       ARRAY_SIZE(ar9285PciePhy_clkreq_off_L1_9285), 2);
-               } else {
-                       INIT_INI_ARRAY(&ah->iniPcieSerdes,
-                       ar9285PciePhy_clkreq_always_on_L1_9285,
-                       ARRAY_SIZE(ar9285PciePhy_clkreq_always_on_L1_9285), 2);
-               }
-       } else if (AR_SREV_9280_20_OR_LATER(ah)) {
-               INIT_INI_ARRAY(&ah->iniModes, ar9280Modes_9280_2,
-                              ARRAY_SIZE(ar9280Modes_9280_2), 6);
-               INIT_INI_ARRAY(&ah->iniCommon, ar9280Common_9280_2,
-                              ARRAY_SIZE(ar9280Common_9280_2), 2);
-
-               if (ah->config.pcie_clock_req) {
-                       INIT_INI_ARRAY(&ah->iniPcieSerdes,
-                              ar9280PciePhy_clkreq_off_L1_9280,
-                              ARRAY_SIZE(ar9280PciePhy_clkreq_off_L1_9280),2);
-               } else {
-                       INIT_INI_ARRAY(&ah->iniPcieSerdes,
-                              ar9280PciePhy_clkreq_always_on_L1_9280,
-                              ARRAY_SIZE(ar9280PciePhy_clkreq_always_on_L1_9280), 2);
-               }
-               INIT_INI_ARRAY(&ah->iniModesAdditional,
-                              ar9280Modes_fast_clock_9280_2,
-                              ARRAY_SIZE(ar9280Modes_fast_clock_9280_2), 3);
-       } else if (AR_SREV_9280_10_OR_LATER(ah)) {
-               INIT_INI_ARRAY(&ah->iniModes, ar9280Modes_9280,
-                              ARRAY_SIZE(ar9280Modes_9280), 6);
-               INIT_INI_ARRAY(&ah->iniCommon, ar9280Common_9280,
-                              ARRAY_SIZE(ar9280Common_9280), 2);
-       } else if (AR_SREV_9160_10_OR_LATER(ah)) {
-               INIT_INI_ARRAY(&ah->iniModes, ar5416Modes_9160,
-                              ARRAY_SIZE(ar5416Modes_9160), 6);
-               INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9160,
-                              ARRAY_SIZE(ar5416Common_9160), 2);
-               INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0_9160,
-                              ARRAY_SIZE(ar5416Bank0_9160), 2);
-               INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain_9160,
-                              ARRAY_SIZE(ar5416BB_RfGain_9160), 3);
-               INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1_9160,
-                              ARRAY_SIZE(ar5416Bank1_9160), 2);
-               INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2_9160,
-                              ARRAY_SIZE(ar5416Bank2_9160), 2);
-               INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3_9160,
-                              ARRAY_SIZE(ar5416Bank3_9160), 3);
-               INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6_9160,
-                              ARRAY_SIZE(ar5416Bank6_9160), 3);
-               INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC_9160,
-                              ARRAY_SIZE(ar5416Bank6TPC_9160), 3);
-               INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7_9160,
-                              ARRAY_SIZE(ar5416Bank7_9160), 2);
-               if (AR_SREV_9160_11(ah)) {
-                       INIT_INI_ARRAY(&ah->iniAddac,
-                                      ar5416Addac_91601_1,
-                                      ARRAY_SIZE(ar5416Addac_91601_1), 2);
-               } else {
-                       INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac_9160,
-                                      ARRAY_SIZE(ar5416Addac_9160), 2);
-               }
-       } else if (AR_SREV_9100_OR_LATER(ah)) {
-               INIT_INI_ARRAY(&ah->iniModes, ar5416Modes_9100,
-                              ARRAY_SIZE(ar5416Modes_9100), 6);
-               INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9100,
-                              ARRAY_SIZE(ar5416Common_9100), 2);
-               INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0_9100,
-                              ARRAY_SIZE(ar5416Bank0_9100), 2);
-               INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain_9100,
-                              ARRAY_SIZE(ar5416BB_RfGain_9100), 3);
-               INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1_9100,
-                              ARRAY_SIZE(ar5416Bank1_9100), 2);
-               INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2_9100,
-                              ARRAY_SIZE(ar5416Bank2_9100), 2);
-               INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3_9100,
-                              ARRAY_SIZE(ar5416Bank3_9100), 3);
-               INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6_9100,
-                              ARRAY_SIZE(ar5416Bank6_9100), 3);
-               INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC_9100,
-                              ARRAY_SIZE(ar5416Bank6TPC_9100), 3);
-               INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7_9100,
-                              ARRAY_SIZE(ar5416Bank7_9100), 2);
-               INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac_9100,
-                              ARRAY_SIZE(ar5416Addac_9100), 2);
-       } else {
-               INIT_INI_ARRAY(&ah->iniModes, ar5416Modes,
-                              ARRAY_SIZE(ar5416Modes), 6);
-               INIT_INI_ARRAY(&ah->iniCommon, ar5416Common,
-                              ARRAY_SIZE(ar5416Common), 2);
-               INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0,
-                              ARRAY_SIZE(ar5416Bank0), 2);
-               INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain,
-                              ARRAY_SIZE(ar5416BB_RfGain), 3);
-               INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1,
-                              ARRAY_SIZE(ar5416Bank1), 2);
-               INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2,
-                              ARRAY_SIZE(ar5416Bank2), 2);
-               INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3,
-                              ARRAY_SIZE(ar5416Bank3), 3);
-               INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6,
-                              ARRAY_SIZE(ar5416Bank6), 3);
-               INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC,
-                              ARRAY_SIZE(ar5416Bank6TPC), 3);
-               INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7,
-                              ARRAY_SIZE(ar5416Bank7), 2);
-               INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac,
-                              ARRAY_SIZE(ar5416Addac), 2);
-       }
-
-       if (ah->is_pciexpress)
-               ath9k_hw_configpcipowersave(ah, 0);
-       else
-               ath9k_hw_disablepcie(ah);
-
-       ecode = ath9k_hw_post_attach(ah);
-       if (ecode != 0)
-               goto bad;
-
-       if (AR_SREV_9285_12_OR_LATER(ah)) {
-               u32 txgain_type = ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE);
-
-               /* txgain table */
-               if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER) {
-                       INIT_INI_ARRAY(&ah->iniModesTxGain,
-                       ar9285Modes_high_power_tx_gain_9285_1_2,
-                       ARRAY_SIZE(ar9285Modes_high_power_tx_gain_9285_1_2), 6);
-               } else {
-                       INIT_INI_ARRAY(&ah->iniModesTxGain,
-                       ar9285Modes_original_tx_gain_9285_1_2,
-                       ARRAY_SIZE(ar9285Modes_original_tx_gain_9285_1_2), 6);
-               }
-
-       }
-
-       /* rxgain table */
-       if (AR_SREV_9280_20(ah))
-               ath9k_hw_init_rxgain_ini(ah);
-
-       /* txgain table */
-       if (AR_SREV_9280_20(ah))
-               ath9k_hw_init_txgain_ini(ah);
-
-       if (!ath9k_hw_fill_cap_info(ah)) {
-               DPRINTF(sc, ATH_DBG_RESET, "failed ath9k_hw_fill_cap_info\n");
-               ecode = -EINVAL;
-               goto bad;
-       }
-
-       if ((ah->hw_version.devid == AR9280_DEVID_PCI) &&
-           test_bit(ATH9K_MODE_11A, ah->caps.wireless_modes)) {
-
-               /* EEPROM Fixup */
-               for (i = 0; i < ah->iniModes.ia_rows; i++) {
-                       u32 reg = INI_RA(&ah->iniModes, i, 0);
-
-                       for (j = 1; j < ah->iniModes.ia_columns; j++) {
-                               u32 val = INI_RA(&ah->iniModes, i, j);
-
-                               INI_RA(&ah->iniModes, i, j) =
-                                       ath9k_hw_ini_fixup(ah,
-                                                          &ah->eeprom.def,
-                                                          reg, val);
-                       }
-               }
-       }
-
-       ecode = ath9k_hw_init_macaddr(ah);
-       if (ecode != 0) {
-               DPRINTF(sc, ATH_DBG_RESET,
-                       "failed initializing mac address\n");
-               goto bad;
-       }
-
-       if (AR_SREV_9285(ah))
-               ah->tx_trig_level = (AR_FTRIG_256B >> AR_FTRIG_S);
-       else
-               ah->tx_trig_level = (AR_FTRIG_512B >> AR_FTRIG_S);
-
-       ath9k_init_nfcal_hist_buffer(ah);
-
-       return ah;
-bad:
-       if (ah)
-               ath9k_hw_detach(ah);
-       if (status)
-               *status = ecode;
-
-       return NULL;
-}
-
-static void ath9k_hw_init_bb(struct ath_hw *ah,
-                            struct ath9k_channel *chan)
-{
-       u32 synthDelay;
-
-       synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
-       if (IS_CHAN_B(chan))
-               synthDelay = (4 * synthDelay) / 22;
-       else
-               synthDelay /= 10;
-
-       REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
-
-       udelay(synthDelay + BASE_ACTIVATE_DELAY);
-}
-
-static void ath9k_hw_init_qos(struct ath_hw *ah)
-{
-       REG_WRITE(ah, AR_MIC_QOS_CONTROL, 0x100aa);
-       REG_WRITE(ah, AR_MIC_QOS_SELECT, 0x3210);
-
-       REG_WRITE(ah, AR_QOS_NO_ACK,
-                 SM(2, AR_QOS_NO_ACK_TWO_BIT) |
-                 SM(5, AR_QOS_NO_ACK_BIT_OFF) |
-                 SM(0, AR_QOS_NO_ACK_BYTE_OFF));
-
-       REG_WRITE(ah, AR_TXOP_X, AR_TXOP_X_VAL);
-       REG_WRITE(ah, AR_TXOP_0_3, 0xFFFFFFFF);
-       REG_WRITE(ah, AR_TXOP_4_7, 0xFFFFFFFF);
-       REG_WRITE(ah, AR_TXOP_8_11, 0xFFFFFFFF);
-       REG_WRITE(ah, AR_TXOP_12_15, 0xFFFFFFFF);
-}
-
-static void ath9k_hw_init_pll(struct ath_hw *ah,
-                             struct ath9k_channel *chan)
-{
-       u32 pll;
-
-       if (AR_SREV_9100(ah)) {
-               if (chan && IS_CHAN_5GHZ(chan))
-                       pll = 0x1450;
-               else
-                       pll = 0x1458;
-       } else {
-               if (AR_SREV_9280_10_OR_LATER(ah)) {
-                       pll = SM(0x5, AR_RTC_9160_PLL_REFDIV);
-
-                       if (chan && IS_CHAN_HALF_RATE(chan))
-                               pll |= SM(0x1, AR_RTC_9160_PLL_CLKSEL);
-                       else if (chan && IS_CHAN_QUARTER_RATE(chan))
-                               pll |= SM(0x2, AR_RTC_9160_PLL_CLKSEL);
-
-                       if (chan && IS_CHAN_5GHZ(chan)) {
-                               pll |= SM(0x28, AR_RTC_9160_PLL_DIV);
-
-
-                               if (AR_SREV_9280_20(ah)) {
-                                       if (((chan->channel % 20) == 0)
-                                           || ((chan->channel % 10) == 0))
-                                               pll = 0x2850;
-                                       else
-                                               pll = 0x142c;
-                               }
-                       } else {
-                               pll |= SM(0x2c, AR_RTC_9160_PLL_DIV);
-                       }
-
-               } else if (AR_SREV_9160_10_OR_LATER(ah)) {
-
-                       pll = SM(0x5, AR_RTC_9160_PLL_REFDIV);
-
-                       if (chan && IS_CHAN_HALF_RATE(chan))
-                               pll |= SM(0x1, AR_RTC_9160_PLL_CLKSEL);
-                       else if (chan && IS_CHAN_QUARTER_RATE(chan))
-                               pll |= SM(0x2, AR_RTC_9160_PLL_CLKSEL);
-
-                       if (chan && IS_CHAN_5GHZ(chan))
-                               pll |= SM(0x50, AR_RTC_9160_PLL_DIV);
-                       else
-                               pll |= SM(0x58, AR_RTC_9160_PLL_DIV);
-               } else {
-                       pll = AR_RTC_PLL_REFDIV_5 | AR_RTC_PLL_DIV2;
-
-                       if (chan && IS_CHAN_HALF_RATE(chan))
-                               pll |= SM(0x1, AR_RTC_PLL_CLKSEL);
-                       else if (chan && IS_CHAN_QUARTER_RATE(chan))
-                               pll |= SM(0x2, AR_RTC_PLL_CLKSEL);
-
-                       if (chan && IS_CHAN_5GHZ(chan))
-                               pll |= SM(0xa, AR_RTC_PLL_DIV);
-                       else
-                               pll |= SM(0xb, AR_RTC_PLL_DIV);
-               }
-       }
-       REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll);
-
-       udelay(RTC_PLL_SETTLE_DELAY);
-
-       REG_WRITE(ah, AR_RTC_SLEEP_CLK, AR_RTC_FORCE_DERIVED_CLK);
-}
-
-static void ath9k_hw_init_chain_masks(struct ath_hw *ah)
-{
-       int rx_chainmask, tx_chainmask;
-
-       rx_chainmask = ah->rxchainmask;
-       tx_chainmask = ah->txchainmask;
-
-       switch (rx_chainmask) {
-       case 0x5:
-               REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
-                           AR_PHY_SWAP_ALT_CHAIN);
-       case 0x3:
-               if (((ah)->hw_version.macVersion <= AR_SREV_VERSION_9160)) {
-                       REG_WRITE(ah, AR_PHY_RX_CHAINMASK, 0x7);
-                       REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, 0x7);
-                       break;
-               }
-       case 0x1:
-       case 0x2:
-       case 0x7:
-               REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
-               REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
-               break;
-       default:
-               break;
-       }
-
-       REG_WRITE(ah, AR_SELFGEN_MASK, tx_chainmask);
-       if (tx_chainmask == 0x5) {
-               REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
-                           AR_PHY_SWAP_ALT_CHAIN);
-       }
-       if (AR_SREV_9100(ah))
-               REG_WRITE(ah, AR_PHY_ANALOG_SWAP,
-                         REG_READ(ah, AR_PHY_ANALOG_SWAP) | 0x00000001);
-}
-
-static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah,
-                                         enum nl80211_iftype opmode)
-{
-       ah->mask_reg = AR_IMR_TXERR |
-               AR_IMR_TXURN |
-               AR_IMR_RXERR |
-               AR_IMR_RXORN |
-               AR_IMR_BCNMISC;
-
-       if (ah->intr_mitigation)
-               ah->mask_reg |= AR_IMR_RXINTM | AR_IMR_RXMINTR;
-       else
-               ah->mask_reg |= AR_IMR_RXOK;
-
-       ah->mask_reg |= AR_IMR_TXOK;
-
-       if (opmode == NL80211_IFTYPE_AP)
-               ah->mask_reg |= AR_IMR_MIB;
-
-       REG_WRITE(ah, AR_IMR, ah->mask_reg);
-       REG_WRITE(ah, AR_IMR_S2, REG_READ(ah, AR_IMR_S2) | AR_IMR_S2_GTT);
-
-       if (!AR_SREV_9100(ah)) {
-               REG_WRITE(ah, AR_INTR_SYNC_CAUSE, 0xFFFFFFFF);
-               REG_WRITE(ah, AR_INTR_SYNC_ENABLE, AR_INTR_SYNC_DEFAULT);
-               REG_WRITE(ah, AR_INTR_SYNC_MASK, 0);
-       }
-}
-
-static bool ath9k_hw_set_ack_timeout(struct ath_hw *ah, u32 us)
-{
-       if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_ACK))) {
-               DPRINTF(ah->ah_sc, ATH_DBG_RESET, "bad ack timeout %u\n", us);
-               ah->acktimeout = (u32) -1;
-               return false;
-       } else {
-               REG_RMW_FIELD(ah, AR_TIME_OUT,
-                             AR_TIME_OUT_ACK, ath9k_hw_mac_to_clks(ah, us));
-               ah->acktimeout = us;
-               return true;
-       }
-}
-
-static bool ath9k_hw_set_cts_timeout(struct ath_hw *ah, u32 us)
-{
-       if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_CTS))) {
-               DPRINTF(ah->ah_sc, ATH_DBG_RESET, "bad cts timeout %u\n", us);
-               ah->ctstimeout = (u32) -1;
-               return false;
-       } else {
-               REG_RMW_FIELD(ah, AR_TIME_OUT,
-                             AR_TIME_OUT_CTS, ath9k_hw_mac_to_clks(ah, us));
-               ah->ctstimeout = us;
-               return true;
-       }
-}
-
-static bool ath9k_hw_set_global_txtimeout(struct ath_hw *ah, u32 tu)
-{
-       if (tu > 0xFFFF) {
-               DPRINTF(ah->ah_sc, ATH_DBG_XMIT,
-                       "bad global tx timeout %u\n", tu);
-               ah->globaltxtimeout = (u32) -1;
-               return false;
-       } else {
-               REG_RMW_FIELD(ah, AR_GTXTO, AR_GTXTO_TIMEOUT_LIMIT, tu);
-               ah->globaltxtimeout = tu;
-               return true;
-       }
-}
-
-static void ath9k_hw_init_user_settings(struct ath_hw *ah)
-{
-       DPRINTF(ah->ah_sc, ATH_DBG_RESET, "ah->misc_mode 0x%x\n",
-               ah->misc_mode);
-
-       if (ah->misc_mode != 0)
-               REG_WRITE(ah, AR_PCU_MISC,
-                         REG_READ(ah, AR_PCU_MISC) | ah->misc_mode);
-       if (ah->slottime != (u32) -1)
-               ath9k_hw_setslottime(ah, ah->slottime);
-       if (ah->acktimeout != (u32) -1)
-               ath9k_hw_set_ack_timeout(ah, ah->acktimeout);
-       if (ah->ctstimeout != (u32) -1)
-               ath9k_hw_set_cts_timeout(ah, ah->ctstimeout);
-       if (ah->globaltxtimeout != (u32) -1)
-               ath9k_hw_set_global_txtimeout(ah, ah->globaltxtimeout);
-}
-
-const char *ath9k_hw_probe(u16 vendorid, u16 devid)
-{
-       return vendorid == ATHEROS_VENDOR_ID ?
-               ath9k_hw_devname(devid) : NULL;
-}
-
-void ath9k_hw_detach(struct ath_hw *ah)
-{
-       if (!AR_SREV_9100(ah))
-               ath9k_hw_ani_detach(ah);
-
-       ath9k_hw_rfdetach(ah);
-       ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP);
-       kfree(ah);
-}
-
-struct ath_hw *ath9k_hw_attach(u16 devid, struct ath_softc *sc, int *error)
-{
-       struct ath_hw *ah = NULL;
-
-       switch (devid) {
-       case AR5416_DEVID_PCI:
-       case AR5416_DEVID_PCIE:
-       case AR5416_AR9100_DEVID:
-       case AR9160_DEVID_PCI:
-       case AR9280_DEVID_PCI:
-       case AR9280_DEVID_PCIE:
-       case AR9285_DEVID_PCIE:
-               ah = ath9k_hw_do_attach(devid, sc, error);
-               break;
-       default:
-               *error = -ENXIO;
-               break;
-       }
-
-       return ah;
-}
-
-/*******/
-/* INI */
-/*******/
-
-static void ath9k_hw_override_ini(struct ath_hw *ah,
-                                 struct ath9k_channel *chan)
-{
-       /*
-        * Set the RX_ABORT and RX_DIS and clear if off only after
-        * RXE is set for MAC. This prevents frames with corrupted
-        * descriptor status.
-        */
-       REG_SET_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
-
-
-       if (!AR_SREV_5416_20_OR_LATER(ah) ||
-           AR_SREV_9280_10_OR_LATER(ah))
-               return;
-
-       REG_WRITE(ah, 0x9800 + (651 << 2), 0x11);
-}
-
-static u32 ath9k_hw_def_ini_fixup(struct ath_hw *ah,
-                             struct ar5416_eeprom_def *pEepData,
-                             u32 reg, u32 value)
-{
-       struct base_eep_header *pBase = &(pEepData->baseEepHeader);
-
-       switch (ah->hw_version.devid) {
-       case AR9280_DEVID_PCI:
-               if (reg == 0x7894) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_ANY,
-                               "ini VAL: %x  EEPROM: %x\n", value,
-                               (pBase->version & 0xff));
-
-                       if ((pBase->version & 0xff) > 0x0a) {
-                               DPRINTF(ah->ah_sc, ATH_DBG_ANY,
-                                       "PWDCLKIND: %d\n",
-                                       pBase->pwdclkind);
-                               value &= ~AR_AN_TOP2_PWDCLKIND;
-                               value |= AR_AN_TOP2_PWDCLKIND &
-                                       (pBase->pwdclkind << AR_AN_TOP2_PWDCLKIND_S);
-                       } else {
-                               DPRINTF(ah->ah_sc, ATH_DBG_ANY,
-                                       "PWDCLKIND Earlier Rev\n");
-                       }
-
-                       DPRINTF(ah->ah_sc, ATH_DBG_ANY,
-                               "final ini VAL: %x\n", value);
-               }
-               break;
-       }
-
-       return value;
-}
-
-static u32 ath9k_hw_ini_fixup(struct ath_hw *ah,
-                             struct ar5416_eeprom_def *pEepData,
-                             u32 reg, u32 value)
-{
-       if (ah->eep_map == EEP_MAP_4KBITS)
-               return value;
-       else
-               return ath9k_hw_def_ini_fixup(ah, pEepData, reg, value);
-}
-
-static void ath9k_olc_init(struct ath_hw *ah)
-{
-       u32 i;
-
-       for (i = 0; i < AR9280_TX_GAIN_TABLE_SIZE; i++)
-               ah->originalGain[i] =
-                       MS(REG_READ(ah, AR_PHY_TX_GAIN_TBL1 + i * 4),
-                                       AR_PHY_TX_GAIN);
-       ah->PDADCdelta = 0;
-}
-
-static int ath9k_hw_process_ini(struct ath_hw *ah,
-                               struct ath9k_channel *chan,
-                               enum ath9k_ht_macmode macmode)
-{
-       int i, regWrites = 0;
-       struct ieee80211_channel *channel = chan->chan;
-       u32 modesIndex, freqIndex;
-       int status;
-
-       switch (chan->chanmode) {
-       case CHANNEL_A:
-       case CHANNEL_A_HT20:
-               modesIndex = 1;
-               freqIndex = 1;
-               break;
-       case CHANNEL_A_HT40PLUS:
-       case CHANNEL_A_HT40MINUS:
-               modesIndex = 2;
-               freqIndex = 1;
-               break;
-       case CHANNEL_G:
-       case CHANNEL_G_HT20:
-       case CHANNEL_B:
-               modesIndex = 4;
-               freqIndex = 2;
-               break;
-       case CHANNEL_G_HT40PLUS:
-       case CHANNEL_G_HT40MINUS:
-               modesIndex = 3;
-               freqIndex = 2;
-               break;
-
-       default:
-               return -EINVAL;
-       }
-
-       REG_WRITE(ah, AR_PHY(0), 0x00000007);
-       REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_EXTERNAL_RADIO);
-       ah->eep_ops->set_addac(ah, chan);
-
-       if (AR_SREV_5416_22_OR_LATER(ah)) {
-               REG_WRITE_ARRAY(&ah->iniAddac, 1, regWrites);
-       } else {
-               struct ar5416IniArray temp;
-               u32 addacSize =
-                       sizeof(u32) * ah->iniAddac.ia_rows *
-                       ah->iniAddac.ia_columns;
-
-               memcpy(ah->addac5416_21,
-                      ah->iniAddac.ia_array, addacSize);
-
-               (ah->addac5416_21)[31 * ah->iniAddac.ia_columns + 1] = 0;
-
-               temp.ia_array = ah->addac5416_21;
-               temp.ia_columns = ah->iniAddac.ia_columns;
-               temp.ia_rows = ah->iniAddac.ia_rows;
-               REG_WRITE_ARRAY(&temp, 1, regWrites);
-       }
-
-       REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_INTERNAL_ADDAC);
-
-       for (i = 0; i < ah->iniModes.ia_rows; i++) {
-               u32 reg = INI_RA(&ah->iniModes, i, 0);
-               u32 val = INI_RA(&ah->iniModes, i, modesIndex);
-
-               REG_WRITE(ah, reg, val);
-
-               if (reg >= 0x7800 && reg < 0x78a0
-                   && ah->config.analog_shiftreg) {
-                       udelay(100);
-               }
-
-               DO_DELAY(regWrites);
-       }
-
-       if (AR_SREV_9280(ah))
-               REG_WRITE_ARRAY(&ah->iniModesRxGain, modesIndex, regWrites);
-
-       if (AR_SREV_9280(ah) || (AR_SREV_9285(ah) &&
-           AR_SREV_9285_12_OR_LATER(ah)))
-               REG_WRITE_ARRAY(&ah->iniModesTxGain, modesIndex, regWrites);
-
-       for (i = 0; i < ah->iniCommon.ia_rows; i++) {
-               u32 reg = INI_RA(&ah->iniCommon, i, 0);
-               u32 val = INI_RA(&ah->iniCommon, i, 1);
-
-               REG_WRITE(ah, reg, val);
-
-               if (reg >= 0x7800 && reg < 0x78a0
-                   && ah->config.analog_shiftreg) {
-                       udelay(100);
-               }
-
-               DO_DELAY(regWrites);
-       }
-
-       ath9k_hw_write_regs(ah, modesIndex, freqIndex, regWrites);
-
-       if (AR_SREV_9280_20(ah) && IS_CHAN_A_5MHZ_SPACED(chan)) {
-               REG_WRITE_ARRAY(&ah->iniModesAdditional, modesIndex,
-                               regWrites);
-       }
-
-       ath9k_hw_override_ini(ah, chan);
-       ath9k_hw_set_regs(ah, chan, macmode);
-       ath9k_hw_init_chain_masks(ah);
-
-       if (OLC_FOR_AR9280_20_LATER)
-               ath9k_olc_init(ah);
-
-       status = ah->eep_ops->set_txpower(ah, chan,
-                                 ath9k_regd_get_ctl(ah, chan),
-                                 channel->max_antenna_gain * 2,
-                                 channel->max_power * 2,
-                                 min((u32) MAX_RATE_POWER,
-                                     (u32) ah->regulatory.power_limit));
-       if (status != 0) {
-               DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
-                       "error init'ing transmit power\n");
-               return -EIO;
-       }
-
-       if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) {
-               DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
-                       "ar5416SetRfRegs failed\n");
-               return -EIO;
-       }
-
-       return 0;
-}
-
-/****************************************/
-/* Reset and Channel Switching Routines */
-/****************************************/
-
-static void ath9k_hw_set_rfmode(struct ath_hw *ah, struct ath9k_channel *chan)
-{
-       u32 rfMode = 0;
-
-       if (chan == NULL)
-               return;
-
-       rfMode |= (IS_CHAN_B(chan) || IS_CHAN_G(chan))
-               ? AR_PHY_MODE_DYNAMIC : AR_PHY_MODE_OFDM;
-
-       if (!AR_SREV_9280_10_OR_LATER(ah))
-               rfMode |= (IS_CHAN_5GHZ(chan)) ?
-                       AR_PHY_MODE_RF5GHZ : AR_PHY_MODE_RF2GHZ;
-
-       if (AR_SREV_9280_20(ah) && IS_CHAN_A_5MHZ_SPACED(chan))
-               rfMode |= (AR_PHY_MODE_DYNAMIC | AR_PHY_MODE_DYN_CCK_DISABLE);
-
-       REG_WRITE(ah, AR_PHY_MODE, rfMode);
-}
-
-static void ath9k_hw_mark_phy_inactive(struct ath_hw *ah)
-{
-       REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
-}
-
-static inline void ath9k_hw_set_dma(struct ath_hw *ah)
-{
-       u32 regval;
-
-       regval = REG_READ(ah, AR_AHB_MODE);
-       REG_WRITE(ah, AR_AHB_MODE, regval | AR_AHB_PREFETCH_RD_EN);
-
-       regval = REG_READ(ah, AR_TXCFG) & ~AR_TXCFG_DMASZ_MASK;
-       REG_WRITE(ah, AR_TXCFG, regval | AR_TXCFG_DMASZ_128B);
-
-       REG_RMW_FIELD(ah, AR_TXCFG, AR_FTRIG, ah->tx_trig_level);
-
-       regval = REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_DMASZ_MASK;
-       REG_WRITE(ah, AR_RXCFG, regval | AR_RXCFG_DMASZ_128B);
-
-       REG_WRITE(ah, AR_RXFIFO_CFG, 0x200);
-
-       if (AR_SREV_9285(ah)) {
-               REG_WRITE(ah, AR_PCU_TXBUF_CTRL,
-                         AR_9285_PCU_TXBUF_CTRL_USABLE_SIZE);
-       } else {
-               REG_WRITE(ah, AR_PCU_TXBUF_CTRL,
-                         AR_PCU_TXBUF_CTRL_USABLE_SIZE);
-       }
-}
-
-static void ath9k_hw_set_operating_mode(struct ath_hw *ah, int opmode)
-{
-       u32 val;
-
-       val = REG_READ(ah, AR_STA_ID1);
-       val &= ~(AR_STA_ID1_STA_AP | AR_STA_ID1_ADHOC);
-       switch (opmode) {
-       case NL80211_IFTYPE_AP:
-               REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_STA_AP
-                         | AR_STA_ID1_KSRCH_MODE);
-               REG_CLR_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);
-               break;
-       case NL80211_IFTYPE_ADHOC:
-       case NL80211_IFTYPE_MESH_POINT:
-               REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_ADHOC
-                         | AR_STA_ID1_KSRCH_MODE);
-               REG_SET_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);
-               break;
-       case NL80211_IFTYPE_STATION:
-       case NL80211_IFTYPE_MONITOR:
-               REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_KSRCH_MODE);
-               break;
-       }
-}
-
-static inline void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah,
-                                                u32 coef_scaled,
-                                                u32 *coef_mantissa,
-                                                u32 *coef_exponent)
-{
-       u32 coef_exp, coef_man;
-
-       for (coef_exp = 31; coef_exp > 0; coef_exp--)
-               if ((coef_scaled >> coef_exp) & 0x1)
-                       break;
-
-       coef_exp = 14 - (coef_exp - COEF_SCALE_S);
-
-       coef_man = coef_scaled + (1 << (COEF_SCALE_S - coef_exp - 1));
-
-       *coef_mantissa = coef_man >> (COEF_SCALE_S - coef_exp);
-       *coef_exponent = coef_exp - 16;
-}
-
-static void ath9k_hw_set_delta_slope(struct ath_hw *ah,
-                                    struct ath9k_channel *chan)
-{
-       u32 coef_scaled, ds_coef_exp, ds_coef_man;
-       u32 clockMhzScaled = 0x64000000;
-       struct chan_centers centers;
-
-       if (IS_CHAN_HALF_RATE(chan))
-               clockMhzScaled = clockMhzScaled >> 1;
-       else if (IS_CHAN_QUARTER_RATE(chan))
-               clockMhzScaled = clockMhzScaled >> 2;
-
-       ath9k_hw_get_channel_centers(ah, chan, &centers);
-       coef_scaled = clockMhzScaled / centers.synth_center;
-
-       ath9k_hw_get_delta_slope_vals(ah, coef_scaled, &ds_coef_man,
-                                     &ds_coef_exp);
-
-       REG_RMW_FIELD(ah, AR_PHY_TIMING3,
-                     AR_PHY_TIMING3_DSC_MAN, ds_coef_man);
-       REG_RMW_FIELD(ah, AR_PHY_TIMING3,
-                     AR_PHY_TIMING3_DSC_EXP, ds_coef_exp);
-
-       coef_scaled = (9 * coef_scaled) / 10;
-
-       ath9k_hw_get_delta_slope_vals(ah, coef_scaled, &ds_coef_man,
-                                     &ds_coef_exp);
-
-       REG_RMW_FIELD(ah, AR_PHY_HALFGI,
-                     AR_PHY_HALFGI_DSC_MAN, ds_coef_man);
-       REG_RMW_FIELD(ah, AR_PHY_HALFGI,
-                     AR_PHY_HALFGI_DSC_EXP, ds_coef_exp);
-}
-
-static bool ath9k_hw_set_reset(struct ath_hw *ah, int type)
-{
-       u32 rst_flags;
-       u32 tmpReg;
-
-       if (AR_SREV_9100(ah)) {
-               u32 val = REG_READ(ah, AR_RTC_DERIVED_CLK);
-               val &= ~AR_RTC_DERIVED_CLK_PERIOD;
-               val |= SM(1, AR_RTC_DERIVED_CLK_PERIOD);
-               REG_WRITE(ah, AR_RTC_DERIVED_CLK, val);
-               (void)REG_READ(ah, AR_RTC_DERIVED_CLK);
-       }
-
-       REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN |
-                 AR_RTC_FORCE_WAKE_ON_INT);
-
-       if (AR_SREV_9100(ah)) {
-               rst_flags = AR_RTC_RC_MAC_WARM | AR_RTC_RC_MAC_COLD |
-                       AR_RTC_RC_COLD_RESET | AR_RTC_RC_WARM_RESET;
-       } else {
-               tmpReg = REG_READ(ah, AR_INTR_SYNC_CAUSE);
-               if (tmpReg &
-                   (AR_INTR_SYNC_LOCAL_TIMEOUT |
-                    AR_INTR_SYNC_RADM_CPL_TIMEOUT)) {
-                       REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0);
-                       REG_WRITE(ah, AR_RC, AR_RC_AHB | AR_RC_HOSTIF);
-               } else {
-                       REG_WRITE(ah, AR_RC, AR_RC_AHB);
-               }
-
-               rst_flags = AR_RTC_RC_MAC_WARM;
-               if (type == ATH9K_RESET_COLD)
-                       rst_flags |= AR_RTC_RC_MAC_COLD;
-       }
-
-       REG_WRITE(ah, AR_RTC_RC, rst_flags);
-       udelay(50);
-
-       REG_WRITE(ah, AR_RTC_RC, 0);
-       if (!ath9k_hw_wait(ah, AR_RTC_RC, AR_RTC_RC_M, 0, AH_WAIT_TIMEOUT)) {
-               DPRINTF(ah->ah_sc, ATH_DBG_RESET,
-                       "RTC stuck in MAC reset\n");
-               return false;
-       }
-
-       if (!AR_SREV_9100(ah))
-               REG_WRITE(ah, AR_RC, 0);
-
-       ath9k_hw_init_pll(ah, NULL);
-
-       if (AR_SREV_9100(ah))
-               udelay(50);
-
-       return true;
-}
-
-static bool ath9k_hw_set_reset_power_on(struct ath_hw *ah)
-{
-       REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN |
-                 AR_RTC_FORCE_WAKE_ON_INT);
-
-       REG_WRITE(ah, AR_RTC_RESET, 0);
-       udelay(2);
-       REG_WRITE(ah, AR_RTC_RESET, 1);
-
-       if (!ath9k_hw_wait(ah,
-                          AR_RTC_STATUS,
-                          AR_RTC_STATUS_M,
-                          AR_RTC_STATUS_ON,
-                          AH_WAIT_TIMEOUT)) {
-               DPRINTF(ah->ah_sc, ATH_DBG_RESET, "RTC not waking up\n");
-               return false;
-       }
-
-       ath9k_hw_read_revisions(ah);
-
-       return ath9k_hw_set_reset(ah, ATH9K_RESET_WARM);
-}
-
-static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type)
-{
-       REG_WRITE(ah, AR_RTC_FORCE_WAKE,
-                 AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT);
-
-       switch (type) {
-       case ATH9K_RESET_POWER_ON:
-               return ath9k_hw_set_reset_power_on(ah);
-               break;
-       case ATH9K_RESET_WARM:
-       case ATH9K_RESET_COLD:
-               return ath9k_hw_set_reset(ah, type);
-               break;
-       default:
-               return false;
-       }
-}
-
-static void ath9k_hw_set_regs(struct ath_hw *ah, struct ath9k_channel *chan,
-                             enum ath9k_ht_macmode macmode)
-{
-       u32 phymode;
-       u32 enableDacFifo = 0;
-
-       if (AR_SREV_9285_10_OR_LATER(ah))
-               enableDacFifo = (REG_READ(ah, AR_PHY_TURBO) &
-                                        AR_PHY_FC_ENABLE_DAC_FIFO);
-
-       phymode = AR_PHY_FC_HT_EN | AR_PHY_FC_SHORT_GI_40
-               | AR_PHY_FC_SINGLE_HT_LTF1 | AR_PHY_FC_WALSH | enableDacFifo;
-
-       if (IS_CHAN_HT40(chan)) {
-               phymode |= AR_PHY_FC_DYN2040_EN;
-
-               if ((chan->chanmode == CHANNEL_A_HT40PLUS) ||
-                   (chan->chanmode == CHANNEL_G_HT40PLUS))
-                       phymode |= AR_PHY_FC_DYN2040_PRI_CH;
-
-               if (ah->extprotspacing == ATH9K_HT_EXTPROTSPACING_25)
-                       phymode |= AR_PHY_FC_DYN2040_EXT_CH;
-       }
-       REG_WRITE(ah, AR_PHY_TURBO, phymode);
-
-       ath9k_hw_set11nmac2040(ah, macmode);
-
-       REG_WRITE(ah, AR_GTXTO, 25 << AR_GTXTO_TIMEOUT_LIMIT_S);
-       REG_WRITE(ah, AR_CST, 0xF << AR_CST_TIMEOUT_LIMIT_S);
-}
-
-static bool ath9k_hw_chip_reset(struct ath_hw *ah,
-                               struct ath9k_channel *chan)
-{
-       if (OLC_FOR_AR9280_20_LATER) {
-               if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON))
-                       return false;
-       } else if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM))
-               return false;
-
-       if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
-               return false;
-
-       ah->chip_fullsleep = false;
-       ath9k_hw_init_pll(ah, chan);
-       ath9k_hw_set_rfmode(ah, chan);
-
-       return true;
-}
-
-static bool ath9k_hw_channel_change(struct ath_hw *ah,
-                                   struct ath9k_channel *chan,
-                                   enum ath9k_ht_macmode macmode)
-{
-       struct ieee80211_channel *channel = chan->chan;
-       u32 synthDelay, qnum;
-
-       for (qnum = 0; qnum < AR_NUM_QCU; qnum++) {
-               if (ath9k_hw_numtxpending(ah, qnum)) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
-                               "Transmit frames pending on queue %d\n", qnum);
-                       return false;
-               }
-       }
-
-       REG_WRITE(ah, AR_PHY_RFBUS_REQ, AR_PHY_RFBUS_REQ_EN);
-       if (!ath9k_hw_wait(ah, AR_PHY_RFBUS_GRANT, AR_PHY_RFBUS_GRANT_EN,
-                          AR_PHY_RFBUS_GRANT_EN, AH_WAIT_TIMEOUT)) {
-               DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
-                       "Could not kill baseband RX\n");
-               return false;
-       }
-
-       ath9k_hw_set_regs(ah, chan, macmode);
-
-       if (AR_SREV_9280_10_OR_LATER(ah)) {
-               if (!(ath9k_hw_ar9280_set_channel(ah, chan))) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
-                               "failed to set channel\n");
-                       return false;
-               }
-       } else {
-               if (!(ath9k_hw_set_channel(ah, chan))) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
-                               "failed to set channel\n");
-                       return false;
-               }
-       }
-
-       if (ah->eep_ops->set_txpower(ah, chan,
-                            ath9k_regd_get_ctl(ah, chan),
-                            channel->max_antenna_gain * 2,
-                            channel->max_power * 2,
-                            min((u32) MAX_RATE_POWER,
-                                (u32) ah->regulatory.power_limit)) != 0) {
-               DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
-                       "error init'ing transmit power\n");
-               return false;
-       }
-
-       synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
-       if (IS_CHAN_B(chan))
-               synthDelay = (4 * synthDelay) / 22;
-       else
-               synthDelay /= 10;
-
-       udelay(synthDelay + BASE_ACTIVATE_DELAY);
-
-       REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0);
-
-       if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan))
-               ath9k_hw_set_delta_slope(ah, chan);
-
-       if (AR_SREV_9280_10_OR_LATER(ah))
-               ath9k_hw_9280_spur_mitigate(ah, chan);
-       else
-               ath9k_hw_spur_mitigate(ah, chan);
-
-       if (!chan->oneTimeCalsDone)
-               chan->oneTimeCalsDone = true;
-
-       return true;
-}
-
-static void ath9k_hw_9280_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan)
-{
-       int bb_spur = AR_NO_SPUR;
-       int freq;
-       int bin, cur_bin;
-       int bb_spur_off, spur_subchannel_sd;
-       int spur_freq_sd;
-       int spur_delta_phase;
-       int denominator;
-       int upper, lower, cur_vit_mask;
-       int tmp, newVal;
-       int i;
-       int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8,
-                         AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60
-       };
-       int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10,
-                        AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60
-       };
-       int inc[4] = { 0, 100, 0, 0 };
-       struct chan_centers centers;
-
-       int8_t mask_m[123];
-       int8_t mask_p[123];
-       int8_t mask_amt;
-       int tmp_mask;
-       int cur_bb_spur;
-       bool is2GHz = IS_CHAN_2GHZ(chan);
-
-       memset(&mask_m, 0, sizeof(int8_t) * 123);
-       memset(&mask_p, 0, sizeof(int8_t) * 123);
-
-       ath9k_hw_get_channel_centers(ah, chan, &centers);
-       freq = centers.synth_center;
-
-       ah->config.spurmode = SPUR_ENABLE_EEPROM;
-       for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
-               cur_bb_spur = ah->eep_ops->get_spur_channel(ah, i, is2GHz);
-
-               if (is2GHz)
-                       cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_2GHZ;
-               else
-                       cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_5GHZ;
-
-               if (AR_NO_SPUR == cur_bb_spur)
-                       break;
-               cur_bb_spur = cur_bb_spur - freq;
-
-               if (IS_CHAN_HT40(chan)) {
-                       if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT40) &&
-                           (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT40)) {
-                               bb_spur = cur_bb_spur;
-                               break;
-                       }
-               } else if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT20) &&
-                          (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT20)) {
-                       bb_spur = cur_bb_spur;
-                       break;
-               }
-       }
-
-       if (AR_NO_SPUR == bb_spur) {
-               REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK,
-                           AR_PHY_FORCE_CLKEN_CCK_MRC_MUX);
-               return;
-       } else {
-               REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK,
-                           AR_PHY_FORCE_CLKEN_CCK_MRC_MUX);
-       }
-
-       bin = bb_spur * 320;
-
-       tmp = REG_READ(ah, AR_PHY_TIMING_CTRL4(0));
-
-       newVal = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI |
-                       AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER |
-                       AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK |
-                       AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK);
-       REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0), newVal);
-
-       newVal = (AR_PHY_SPUR_REG_MASK_RATE_CNTL |
-                 AR_PHY_SPUR_REG_ENABLE_MASK_PPM |
-                 AR_PHY_SPUR_REG_MASK_RATE_SELECT |
-                 AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI |
-                 SM(SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH));
-       REG_WRITE(ah, AR_PHY_SPUR_REG, newVal);
-
-       if (IS_CHAN_HT40(chan)) {
-               if (bb_spur < 0) {
-                       spur_subchannel_sd = 1;
-                       bb_spur_off = bb_spur + 10;
-               } else {
-                       spur_subchannel_sd = 0;
-                       bb_spur_off = bb_spur - 10;
-               }
-       } else {
-               spur_subchannel_sd = 0;
-               bb_spur_off = bb_spur;
-       }
-
-       if (IS_CHAN_HT40(chan))
-               spur_delta_phase =
-                       ((bb_spur * 262144) /
-                        10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE;
-       else
-               spur_delta_phase =
-                       ((bb_spur * 524288) /
-                        10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE;
-
-       denominator = IS_CHAN_2GHZ(chan) ? 44 : 40;
-       spur_freq_sd = ((bb_spur_off * 2048) / denominator) & 0x3ff;
-
-       newVal = (AR_PHY_TIMING11_USE_SPUR_IN_AGC |
-                 SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) |
-                 SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE));
-       REG_WRITE(ah, AR_PHY_TIMING11, newVal);
-
-       newVal = spur_subchannel_sd << AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S;
-       REG_WRITE(ah, AR_PHY_SFCORR_EXT, newVal);
-
-       cur_bin = -6000;
-       upper = bin + 100;
-       lower = bin - 100;
-
-       for (i = 0; i < 4; i++) {
-               int pilot_mask = 0;
-               int chan_mask = 0;
-               int bp = 0;
-               for (bp = 0; bp < 30; bp++) {
-                       if ((cur_bin > lower) && (cur_bin < upper)) {
-                               pilot_mask = pilot_mask | 0x1 << bp;
-                               chan_mask = chan_mask | 0x1 << bp;
-                       }
-                       cur_bin += 100;
-               }
-               cur_bin += inc[i];
-               REG_WRITE(ah, pilot_mask_reg[i], pilot_mask);
-               REG_WRITE(ah, chan_mask_reg[i], chan_mask);
-       }
-
-       cur_vit_mask = 6100;
-       upper = bin + 120;
-       lower = bin - 120;
-
-       for (i = 0; i < 123; i++) {
-               if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
-
-                       /* workaround for gcc bug #37014 */
-                       volatile int tmp_v = abs(cur_vit_mask - bin);
-
-                       if (tmp_v < 75)
-                               mask_amt = 1;
-                       else
-                               mask_amt = 0;
-                       if (cur_vit_mask < 0)
-                               mask_m[abs(cur_vit_mask / 100)] = mask_amt;
-                       else
-                               mask_p[cur_vit_mask / 100] = mask_amt;
-               }
-               cur_vit_mask -= 100;
-       }
-
-       tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28)
-               | (mask_m[48] << 26) | (mask_m[49] << 24)
-               | (mask_m[50] << 22) | (mask_m[51] << 20)
-               | (mask_m[52] << 18) | (mask_m[53] << 16)
-               | (mask_m[54] << 14) | (mask_m[55] << 12)
-               | (mask_m[56] << 10) | (mask_m[57] << 8)
-               | (mask_m[58] << 6) | (mask_m[59] << 4)
-               | (mask_m[60] << 2) | (mask_m[61] << 0);
-       REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask);
-       REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask);
-
-       tmp_mask = (mask_m[31] << 28)
-               | (mask_m[32] << 26) | (mask_m[33] << 24)
-               | (mask_m[34] << 22) | (mask_m[35] << 20)
-               | (mask_m[36] << 18) | (mask_m[37] << 16)
-               | (mask_m[48] << 14) | (mask_m[39] << 12)
-               | (mask_m[40] << 10) | (mask_m[41] << 8)
-               | (mask_m[42] << 6) | (mask_m[43] << 4)
-               | (mask_m[44] << 2) | (mask_m[45] << 0);
-       REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask);
-       REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask);
-
-       tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28)
-               | (mask_m[18] << 26) | (mask_m[18] << 24)
-               | (mask_m[20] << 22) | (mask_m[20] << 20)
-               | (mask_m[22] << 18) | (mask_m[22] << 16)
-               | (mask_m[24] << 14) | (mask_m[24] << 12)
-               | (mask_m[25] << 10) | (mask_m[26] << 8)
-               | (mask_m[27] << 6) | (mask_m[28] << 4)
-               | (mask_m[29] << 2) | (mask_m[30] << 0);
-       REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask);
-       REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask);
-
-       tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28)
-               | (mask_m[2] << 26) | (mask_m[3] << 24)
-               | (mask_m[4] << 22) | (mask_m[5] << 20)
-               | (mask_m[6] << 18) | (mask_m[7] << 16)
-               | (mask_m[8] << 14) | (mask_m[9] << 12)
-               | (mask_m[10] << 10) | (mask_m[11] << 8)
-               | (mask_m[12] << 6) | (mask_m[13] << 4)
-               | (mask_m[14] << 2) | (mask_m[15] << 0);
-       REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask);
-       REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask);
-
-       tmp_mask = (mask_p[15] << 28)
-               | (mask_p[14] << 26) | (mask_p[13] << 24)
-               | (mask_p[12] << 22) | (mask_p[11] << 20)
-               | (mask_p[10] << 18) | (mask_p[9] << 16)
-               | (mask_p[8] << 14) | (mask_p[7] << 12)
-               | (mask_p[6] << 10) | (mask_p[5] << 8)
-               | (mask_p[4] << 6) | (mask_p[3] << 4)
-               | (mask_p[2] << 2) | (mask_p[1] << 0);
-       REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask);
-       REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask);
-
-       tmp_mask = (mask_p[30] << 28)
-               | (mask_p[29] << 26) | (mask_p[28] << 24)
-               | (mask_p[27] << 22) | (mask_p[26] << 20)
-               | (mask_p[25] << 18) | (mask_p[24] << 16)
-               | (mask_p[23] << 14) | (mask_p[22] << 12)
-               | (mask_p[21] << 10) | (mask_p[20] << 8)
-               | (mask_p[19] << 6) | (mask_p[18] << 4)
-               | (mask_p[17] << 2) | (mask_p[16] << 0);
-       REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask);
-       REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask);
-
-       tmp_mask = (mask_p[45] << 28)
-               | (mask_p[44] << 26) | (mask_p[43] << 24)
-               | (mask_p[42] << 22) | (mask_p[41] << 20)
-               | (mask_p[40] << 18) | (mask_p[39] << 16)
-               | (mask_p[38] << 14) | (mask_p[37] << 12)
-               | (mask_p[36] << 10) | (mask_p[35] << 8)
-               | (mask_p[34] << 6) | (mask_p[33] << 4)
-               | (mask_p[32] << 2) | (mask_p[31] << 0);
-       REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask);
-       REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask);
-
-       tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28)
-               | (mask_p[59] << 26) | (mask_p[58] << 24)
-               | (mask_p[57] << 22) | (mask_p[56] << 20)
-               | (mask_p[55] << 18) | (mask_p[54] << 16)
-               | (mask_p[53] << 14) | (mask_p[52] << 12)
-               | (mask_p[51] << 10) | (mask_p[50] << 8)
-               | (mask_p[49] << 6) | (mask_p[48] << 4)
-               | (mask_p[47] << 2) | (mask_p[46] << 0);
-       REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask);
-       REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
-}
-
-static void ath9k_hw_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan)
-{
-       int bb_spur = AR_NO_SPUR;
-       int bin, cur_bin;
-       int spur_freq_sd;
-       int spur_delta_phase;
-       int denominator;
-       int upper, lower, cur_vit_mask;
-       int tmp, new;
-       int i;
-       int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8,
-                         AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60
-       };
-       int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10,
-                        AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60
-       };
-       int inc[4] = { 0, 100, 0, 0 };
-
-       int8_t mask_m[123];
-       int8_t mask_p[123];
-       int8_t mask_amt;
-       int tmp_mask;
-       int cur_bb_spur;
-       bool is2GHz = IS_CHAN_2GHZ(chan);
-
-       memset(&mask_m, 0, sizeof(int8_t) * 123);
-       memset(&mask_p, 0, sizeof(int8_t) * 123);
-
-       for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
-               cur_bb_spur = ah->eep_ops->get_spur_channel(ah, i, is2GHz);
-               if (AR_NO_SPUR == cur_bb_spur)
-                       break;
-               cur_bb_spur = cur_bb_spur - (chan->channel * 10);
-               if ((cur_bb_spur > -95) && (cur_bb_spur < 95)) {
-                       bb_spur = cur_bb_spur;
-                       break;
-               }
-       }
-
-       if (AR_NO_SPUR == bb_spur)
-               return;
-
-       bin = bb_spur * 32;
-
-       tmp = REG_READ(ah, AR_PHY_TIMING_CTRL4(0));
-       new = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI |
-                    AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER |
-                    AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK |
-                    AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK);
-
-       REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0), new);
-
-       new = (AR_PHY_SPUR_REG_MASK_RATE_CNTL |
-              AR_PHY_SPUR_REG_ENABLE_MASK_PPM |
-              AR_PHY_SPUR_REG_MASK_RATE_SELECT |
-              AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI |
-              SM(SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH));
-       REG_WRITE(ah, AR_PHY_SPUR_REG, new);
-
-       spur_delta_phase = ((bb_spur * 524288) / 100) &
-               AR_PHY_TIMING11_SPUR_DELTA_PHASE;
-
-       denominator = IS_CHAN_2GHZ(chan) ? 440 : 400;
-       spur_freq_sd = ((bb_spur * 2048) / denominator) & 0x3ff;
-
-       new = (AR_PHY_TIMING11_USE_SPUR_IN_AGC |
-              SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) |
-              SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE));
-       REG_WRITE(ah, AR_PHY_TIMING11, new);
-
-       cur_bin = -6000;
-       upper = bin + 100;
-       lower = bin - 100;
-
-       for (i = 0; i < 4; i++) {
-               int pilot_mask = 0;
-               int chan_mask = 0;
-               int bp = 0;
-               for (bp = 0; bp < 30; bp++) {
-                       if ((cur_bin > lower) && (cur_bin < upper)) {
-                               pilot_mask = pilot_mask | 0x1 << bp;
-                               chan_mask = chan_mask | 0x1 << bp;
-                       }
-                       cur_bin += 100;
-               }
-               cur_bin += inc[i];
-               REG_WRITE(ah, pilot_mask_reg[i], pilot_mask);
-               REG_WRITE(ah, chan_mask_reg[i], chan_mask);
-       }
-
-       cur_vit_mask = 6100;
-       upper = bin + 120;
-       lower = bin - 120;
-
-       for (i = 0; i < 123; i++) {
-               if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
-
-                       /* workaround for gcc bug #37014 */
-                       volatile int tmp_v = abs(cur_vit_mask - bin);
-
-                       if (tmp_v < 75)
-                               mask_amt = 1;
-                       else
-                               mask_amt = 0;
-                       if (cur_vit_mask < 0)
-                               mask_m[abs(cur_vit_mask / 100)] = mask_amt;
-                       else
-                               mask_p[cur_vit_mask / 100] = mask_amt;
-               }
-               cur_vit_mask -= 100;
-       }
-
-       tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28)
-               | (mask_m[48] << 26) | (mask_m[49] << 24)
-               | (mask_m[50] << 22) | (mask_m[51] << 20)
-               | (mask_m[52] << 18) | (mask_m[53] << 16)
-               | (mask_m[54] << 14) | (mask_m[55] << 12)
-               | (mask_m[56] << 10) | (mask_m[57] << 8)
-               | (mask_m[58] << 6) | (mask_m[59] << 4)
-               | (mask_m[60] << 2) | (mask_m[61] << 0);
-       REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask);
-       REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask);
-
-       tmp_mask = (mask_m[31] << 28)
-               | (mask_m[32] << 26) | (mask_m[33] << 24)
-               | (mask_m[34] << 22) | (mask_m[35] << 20)
-               | (mask_m[36] << 18) | (mask_m[37] << 16)
-               | (mask_m[48] << 14) | (mask_m[39] << 12)
-               | (mask_m[40] << 10) | (mask_m[41] << 8)
-               | (mask_m[42] << 6) | (mask_m[43] << 4)
-               | (mask_m[44] << 2) | (mask_m[45] << 0);
-       REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask);
-       REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask);
-
-       tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28)
-               | (mask_m[18] << 26) | (mask_m[18] << 24)
-               | (mask_m[20] << 22) | (mask_m[20] << 20)
-               | (mask_m[22] << 18) | (mask_m[22] << 16)
-               | (mask_m[24] << 14) | (mask_m[24] << 12)
-               | (mask_m[25] << 10) | (mask_m[26] << 8)
-               | (mask_m[27] << 6) | (mask_m[28] << 4)
-               | (mask_m[29] << 2) | (mask_m[30] << 0);
-       REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask);
-       REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask);
-
-       tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28)
-               | (mask_m[2] << 26) | (mask_m[3] << 24)
-               | (mask_m[4] << 22) | (mask_m[5] << 20)
-               | (mask_m[6] << 18) | (mask_m[7] << 16)
-               | (mask_m[8] << 14) | (mask_m[9] << 12)
-               | (mask_m[10] << 10) | (mask_m[11] << 8)
-               | (mask_m[12] << 6) | (mask_m[13] << 4)
-               | (mask_m[14] << 2) | (mask_m[15] << 0);
-       REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask);
-       REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask);
-
-       tmp_mask = (mask_p[15] << 28)
-               | (mask_p[14] << 26) | (mask_p[13] << 24)
-               | (mask_p[12] << 22) | (mask_p[11] << 20)
-               | (mask_p[10] << 18) | (mask_p[9] << 16)
-               | (mask_p[8] << 14) | (mask_p[7] << 12)
-               | (mask_p[6] << 10) | (mask_p[5] << 8)
-               | (mask_p[4] << 6) | (mask_p[3] << 4)
-               | (mask_p[2] << 2) | (mask_p[1] << 0);
-       REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask);
-       REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask);
-
-       tmp_mask = (mask_p[30] << 28)
-               | (mask_p[29] << 26) | (mask_p[28] << 24)
-               | (mask_p[27] << 22) | (mask_p[26] << 20)
-               | (mask_p[25] << 18) | (mask_p[24] << 16)
-               | (mask_p[23] << 14) | (mask_p[22] << 12)
-               | (mask_p[21] << 10) | (mask_p[20] << 8)
-               | (mask_p[19] << 6) | (mask_p[18] << 4)
-               | (mask_p[17] << 2) | (mask_p[16] << 0);
-       REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask);
-       REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask);
-
-       tmp_mask = (mask_p[45] << 28)
-               | (mask_p[44] << 26) | (mask_p[43] << 24)
-               | (mask_p[42] << 22) | (mask_p[41] << 20)
-               | (mask_p[40] << 18) | (mask_p[39] << 16)
-               | (mask_p[38] << 14) | (mask_p[37] << 12)
-               | (mask_p[36] << 10) | (mask_p[35] << 8)
-               | (mask_p[34] << 6) | (mask_p[33] << 4)
-               | (mask_p[32] << 2) | (mask_p[31] << 0);
-       REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask);
-       REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask);
-
-       tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28)
-               | (mask_p[59] << 26) | (mask_p[58] << 24)
-               | (mask_p[57] << 22) | (mask_p[56] << 20)
-               | (mask_p[55] << 18) | (mask_p[54] << 16)
-               | (mask_p[53] << 14) | (mask_p[52] << 12)
-               | (mask_p[51] << 10) | (mask_p[50] << 8)
-               | (mask_p[49] << 6) | (mask_p[48] << 4)
-               | (mask_p[47] << 2) | (mask_p[46] << 0);
-       REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask);
-       REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
-}
-
-int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
-                   bool bChannelChange)
-{
-       u32 saveLedState;
-       struct ath_softc *sc = ah->ah_sc;
-       struct ath9k_channel *curchan = ah->curchan;
-       u32 saveDefAntenna;
-       u32 macStaId1;
-       int i, rx_chainmask, r;
-
-       ah->extprotspacing = sc->ht_extprotspacing;
-       ah->txchainmask = sc->tx_chainmask;
-       ah->rxchainmask = sc->rx_chainmask;
-
-       if (AR_SREV_9285(ah)) {
-               ah->txchainmask &= 0x1;
-               ah->rxchainmask &= 0x1;
-       } else if (AR_SREV_9280(ah)) {
-               ah->txchainmask &= 0x3;
-               ah->rxchainmask &= 0x3;
-       }
-
-       if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
-               return -EIO;
-
-       if (curchan)
-               ath9k_hw_getnf(ah, curchan);
-
-       if (bChannelChange &&
-           (ah->chip_fullsleep != true) &&
-           (ah->curchan != NULL) &&
-           (chan->channel != ah->curchan->channel) &&
-           ((chan->channelFlags & CHANNEL_ALL) ==
-            (ah->curchan->channelFlags & CHANNEL_ALL)) &&
-           (!AR_SREV_9280(ah) || (!IS_CHAN_A_5MHZ_SPACED(chan) &&
-                                  !IS_CHAN_A_5MHZ_SPACED(ah->curchan)))) {
-
-               if (ath9k_hw_channel_change(ah, chan, sc->tx_chan_width)) {
-                       ath9k_hw_loadnf(ah, ah->curchan);
-                       ath9k_hw_start_nfcal(ah);
-                       return 0;
-               }
-       }
-
-       saveDefAntenna = REG_READ(ah, AR_DEF_ANTENNA);
-       if (saveDefAntenna == 0)
-               saveDefAntenna = 1;
-
-       macStaId1 = REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_BASE_RATE_11B;
-
-       saveLedState = REG_READ(ah, AR_CFG_LED) &
-               (AR_CFG_LED_ASSOC_CTL | AR_CFG_LED_MODE_SEL |
-                AR_CFG_LED_BLINK_THRESH_SEL | AR_CFG_LED_BLINK_SLOW);
-
-       ath9k_hw_mark_phy_inactive(ah);
-
-       if (!ath9k_hw_chip_reset(ah, chan)) {
-               DPRINTF(ah->ah_sc, ATH_DBG_RESET, "chip reset failed\n");
-               return -EINVAL;
-       }
-
-       if (AR_SREV_9280_10_OR_LATER(ah))
-               REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE);
-
-       r = ath9k_hw_process_ini(ah, chan, sc->tx_chan_width);
-       if (r)
-               return r;
-
-       /* Setup MFP options for CCMP */
-       if (AR_SREV_9280_20_OR_LATER(ah)) {
-               /* Mask Retry(b11), PwrMgt(b12), MoreData(b13) to 0 in mgmt
-                * frames when constructing CCMP AAD. */
-               REG_RMW_FIELD(ah, AR_AES_MUTE_MASK1, AR_AES_MUTE_MASK1_FC_MGMT,
-                             0xc7ff);
-               ah->sw_mgmt_crypto = false;
-       } else if (AR_SREV_9160_10_OR_LATER(ah)) {
-               /* Disable hardware crypto for management frames */
-               REG_CLR_BIT(ah, AR_PCU_MISC_MODE2,
-                           AR_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE);
-               REG_SET_BIT(ah, AR_PCU_MISC_MODE2,
-                           AR_PCU_MISC_MODE2_NO_CRYPTO_FOR_NON_DATA_PKT);
-               ah->sw_mgmt_crypto = true;
-       } else
-               ah->sw_mgmt_crypto = true;
-
-       if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan))
-               ath9k_hw_set_delta_slope(ah, chan);
-
-       if (AR_SREV_9280_10_OR_LATER(ah))
-               ath9k_hw_9280_spur_mitigate(ah, chan);
-       else
-               ath9k_hw_spur_mitigate(ah, chan);
-
-       ah->eep_ops->set_board_values(ah, chan);
-
-       ath9k_hw_decrease_chain_power(ah, chan);
-
-       REG_WRITE(ah, AR_STA_ID0, get_unaligned_le32(ah->macaddr));
-       REG_WRITE(ah, AR_STA_ID1, get_unaligned_le16(ah->macaddr + 4)
-                 | macStaId1
-                 | AR_STA_ID1_RTS_USE_DEF
-                 | (ah->config.
-                    ack_6mb ? AR_STA_ID1_ACKCTS_6MB : 0)
-                 | ah->sta_id1_defaults);
-       ath9k_hw_set_operating_mode(ah, ah->opmode);
-
-       REG_WRITE(ah, AR_BSSMSKL, get_unaligned_le32(sc->bssidmask));
-       REG_WRITE(ah, AR_BSSMSKU, get_unaligned_le16(sc->bssidmask + 4));
-
-       REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna);
-
-       REG_WRITE(ah, AR_BSS_ID0, get_unaligned_le32(sc->curbssid));
-       REG_WRITE(ah, AR_BSS_ID1, get_unaligned_le16(sc->curbssid + 4) |
-                 ((sc->curaid & 0x3fff) << AR_BSS_ID1_AID_S));
-
-       REG_WRITE(ah, AR_ISR, ~0);
-
-       REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR);
-
-       if (AR_SREV_9280_10_OR_LATER(ah)) {
-               if (!(ath9k_hw_ar9280_set_channel(ah, chan)))
-                       return -EIO;
-       } else {
-               if (!(ath9k_hw_set_channel(ah, chan)))
-                       return -EIO;
-       }
-
-       for (i = 0; i < AR_NUM_DCU; i++)
-               REG_WRITE(ah, AR_DQCUMASK(i), 1 << i);
-
-       ah->intr_txqs = 0;
-       for (i = 0; i < ah->caps.total_queues; i++)
-               ath9k_hw_resettxqueue(ah, i);
-
-       ath9k_hw_init_interrupt_masks(ah, ah->opmode);
-       ath9k_hw_init_qos(ah);
-
-#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
-       if (ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
-               ath9k_enable_rfkill(ah);
-#endif
-       ath9k_hw_init_user_settings(ah);
-
-       REG_WRITE(ah, AR_STA_ID1,
-                 REG_READ(ah, AR_STA_ID1) | AR_STA_ID1_PRESERVE_SEQNUM);
-
-       ath9k_hw_set_dma(ah);
-
-       REG_WRITE(ah, AR_OBS, 8);
-
-       if (ah->intr_mitigation) {
-
-               REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 500);
-               REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, 2000);
-       }
-
-       ath9k_hw_init_bb(ah, chan);
-
-       if (!ath9k_hw_init_cal(ah, chan))
-               return -EIO;;
-
-       rx_chainmask = ah->rxchainmask;
-       if ((rx_chainmask == 0x5) || (rx_chainmask == 0x3)) {
-               REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
-               REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
-       }
-
-       REG_WRITE(ah, AR_CFG_LED, saveLedState | AR_CFG_SCLK_32KHZ);
-
-       if (AR_SREV_9100(ah)) {
-               u32 mask;
-               mask = REG_READ(ah, AR_CFG);
-               if (mask & (AR_CFG_SWRB | AR_CFG_SWTB | AR_CFG_SWRG)) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_RESET,
-                               "CFG Byte Swap Set 0x%x\n", mask);
-               } else {
-                       mask =
-                               INIT_CONFIG_STATUS | AR_CFG_SWRB | AR_CFG_SWTB;
-                       REG_WRITE(ah, AR_CFG, mask);
-                       DPRINTF(ah->ah_sc, ATH_DBG_RESET,
-                               "Setting CFG 0x%x\n", REG_READ(ah, AR_CFG));
-               }
-       } else {
-#ifdef __BIG_ENDIAN
-               REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD);
-#endif
-       }
-
-       return 0;
-}
-
-/************************/
-/* Key Cache Management */
-/************************/
-
-bool ath9k_hw_keyreset(struct ath_hw *ah, u16 entry)
-{
-       u32 keyType;
-
-       if (entry >= ah->caps.keycache_size) {
-               DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
-                       "entry %u out of range\n", entry);
-               return false;
-       }
-
-       keyType = REG_READ(ah, AR_KEYTABLE_TYPE(entry));
-
-       REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), 0);
-       REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), 0);
-       REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), 0);
-       REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), 0);
-       REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), 0);
-       REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), AR_KEYTABLE_TYPE_CLR);
-       REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), 0);
-       REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), 0);
-
-       if (keyType == AR_KEYTABLE_TYPE_TKIP && ATH9K_IS_MIC_ENABLED(ah)) {
-               u16 micentry = entry + 64;
-
-               REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), 0);
-               REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
-               REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), 0);
-               REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0);
-
-       }
-
-       if (ah->curchan == NULL)
-               return true;
-
-       return true;
-}
-
-bool ath9k_hw_keysetmac(struct ath_hw *ah, u16 entry, const u8 *mac)
-{
-       u32 macHi, macLo;
-
-       if (entry >= ah->caps.keycache_size) {
-               DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
-                       "entry %u out of range\n", entry);
-               return false;
-       }
-
-       if (mac != NULL) {
-               macHi = (mac[5] << 8) | mac[4];
-               macLo = (mac[3] << 24) |
-                       (mac[2] << 16) |
-                       (mac[1] << 8) |
-                       mac[0];
-               macLo >>= 1;
-               macLo |= (macHi & 1) << 31;
-               macHi >>= 1;
-       } else {
-               macLo = macHi = 0;
-       }
-       REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), macLo);
-       REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), macHi | AR_KEYTABLE_VALID);
-
-       return true;
-}
-
-bool ath9k_hw_set_keycache_entry(struct ath_hw *ah, u16 entry,
-                                const struct ath9k_keyval *k,
-                                const u8 *mac)
-{
-       const struct ath9k_hw_capabilities *pCap = &ah->caps;
-       u32 key0, key1, key2, key3, key4;
-       u32 keyType;
-
-       if (entry >= pCap->keycache_size) {
-               DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
-                       "entry %u out of range\n", entry);
-               return false;
-       }
-
-       switch (k->kv_type) {
-       case ATH9K_CIPHER_AES_OCB:
-               keyType = AR_KEYTABLE_TYPE_AES;
-               break;
-       case ATH9K_CIPHER_AES_CCM:
-               if (!(pCap->hw_caps & ATH9K_HW_CAP_CIPHER_AESCCM)) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
-                               "AES-CCM not supported by mac rev 0x%x\n",
-                               ah->hw_version.macRev);
-                       return false;
-               }
-               keyType = AR_KEYTABLE_TYPE_CCM;
-               break;
-       case ATH9K_CIPHER_TKIP:
-               keyType = AR_KEYTABLE_TYPE_TKIP;
-               if (ATH9K_IS_MIC_ENABLED(ah)
-                   && entry + 64 >= pCap->keycache_size) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
-                               "entry %u inappropriate for TKIP\n", entry);
-                       return false;
-               }
-               break;
-       case ATH9K_CIPHER_WEP:
-               if (k->kv_len < LEN_WEP40) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
-                               "WEP key length %u too small\n", k->kv_len);
-                       return false;
-               }
-               if (k->kv_len <= LEN_WEP40)
-                       keyType = AR_KEYTABLE_TYPE_40;
-               else if (k->kv_len <= LEN_WEP104)
-                       keyType = AR_KEYTABLE_TYPE_104;
-               else
-                       keyType = AR_KEYTABLE_TYPE_128;
-               break;
-       case ATH9K_CIPHER_CLR:
-               keyType = AR_KEYTABLE_TYPE_CLR;
-               break;
-       default:
-               DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
-                       "cipher %u not supported\n", k->kv_type);
-               return false;
-       }
-
-       key0 = get_unaligned_le32(k->kv_val + 0);
-       key1 = get_unaligned_le16(k->kv_val + 4);
-       key2 = get_unaligned_le32(k->kv_val + 6);
-       key3 = get_unaligned_le16(k->kv_val + 10);
-       key4 = get_unaligned_le32(k->kv_val + 12);
-       if (k->kv_len <= LEN_WEP104)
-               key4 &= 0xff;
-
-       /*
-        * Note: Key cache registers access special memory area that requires
-        * two 32-bit writes to actually update the values in the internal
-        * memory. Consequently, the exact order and pairs used here must be
-        * maintained.
-        */
-
-       if (keyType == AR_KEYTABLE_TYPE_TKIP && ATH9K_IS_MIC_ENABLED(ah)) {
-               u16 micentry = entry + 64;
-
-               /*
-                * Write inverted key[47:0] first to avoid Michael MIC errors
-                * on frames that could be sent or received at the same time.
-                * The correct key will be written in the end once everything
-                * else is ready.
-                */
-               REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), ~key0);
-               REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), ~key1);
-
-               /* Write key[95:48] */
-               REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);
-               REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);
-
-               /* Write key[127:96] and key type */
-               REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
-               REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType);
-
-               /* Write MAC address for the entry */
-               (void) ath9k_hw_keysetmac(ah, entry, mac);
-
-               if (ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA) {
-                       /*
-                        * TKIP uses two key cache entries:
-                        * Michael MIC TX/RX keys in the same key cache entry
-                        * (idx = main index + 64):
-                        * key0 [31:0] = RX key [31:0]
-                        * key1 [15:0] = TX key [31:16]
-                        * key1 [31:16] = reserved
-                        * key2 [31:0] = RX key [63:32]
-                        * key3 [15:0] = TX key [15:0]
-                        * key3 [31:16] = reserved
-                        * key4 [31:0] = TX key [63:32]
-                        */
-                       u32 mic0, mic1, mic2, mic3, mic4;
-
-                       mic0 = get_unaligned_le32(k->kv_mic + 0);
-                       mic2 = get_unaligned_le32(k->kv_mic + 4);
-                       mic1 = get_unaligned_le16(k->kv_txmic + 2) & 0xffff;
-                       mic3 = get_unaligned_le16(k->kv_txmic + 0) & 0xffff;
-                       mic4 = get_unaligned_le32(k->kv_txmic + 4);
-
-                       /* Write RX[31:0] and TX[31:16] */
-                       REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
-                       REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), mic1);
-
-                       /* Write RX[63:32] and TX[15:0] */
-                       REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2);
-                       REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), mic3);
-
-                       /* Write TX[63:32] and keyType(reserved) */
-                       REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), mic4);
-                       REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
-                                 AR_KEYTABLE_TYPE_CLR);
-
-               } else {
-                       /*
-                        * TKIP uses four key cache entries (two for group
-                        * keys):
-                        * Michael MIC TX/RX keys are in different key cache
-                        * entries (idx = main index + 64 for TX and
-                        * main index + 32 + 96 for RX):
-                        * key0 [31:0] = TX/RX MIC key [31:0]
-                        * key1 [31:0] = reserved
-                        * key2 [31:0] = TX/RX MIC key [63:32]
-                        * key3 [31:0] = reserved
-                        * key4 [31:0] = reserved
-                        *
-                        * Upper layer code will call this function separately
-                        * for TX and RX keys when these registers offsets are
-                        * used.
-                        */
-                       u32 mic0, mic2;
-
-                       mic0 = get_unaligned_le32(k->kv_mic + 0);
-                       mic2 = get_unaligned_le32(k->kv_mic + 4);
-
-                       /* Write MIC key[31:0] */
-                       REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
-                       REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
-
-                       /* Write MIC key[63:32] */
-                       REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2);
-                       REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0);
-
-                       /* Write TX[63:32] and keyType(reserved) */
-                       REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), 0);
-                       REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
-                                 AR_KEYTABLE_TYPE_CLR);
-               }
-
-               /* MAC address registers are reserved for the MIC entry */
-               REG_WRITE(ah, AR_KEYTABLE_MAC0(micentry), 0);
-               REG_WRITE(ah, AR_KEYTABLE_MAC1(micentry), 0);
-
-               /*
-                * Write the correct (un-inverted) key[47:0] last to enable
-                * TKIP now that all other registers are set with correct
-                * values.
-                */
-               REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
-               REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
-       } else {
-               /* Write key[47:0] */
-               REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
-               REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
-
-               /* Write key[95:48] */
-               REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);
-               REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);
-
-               /* Write key[127:96] and key type */
-               REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
-               REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType);
-
-               /* Write MAC address for the entry */
-               (void) ath9k_hw_keysetmac(ah, entry, mac);
-       }
-
-       return true;
-}
-
-bool ath9k_hw_keyisvalid(struct ath_hw *ah, u16 entry)
-{
-       if (entry < ah->caps.keycache_size) {
-               u32 val = REG_READ(ah, AR_KEYTABLE_MAC1(entry));
-               if (val & AR_KEYTABLE_VALID)
-                       return true;
-       }
-       return false;
-}
-
-/******************************/
-/* Power Management (Chipset) */
-/******************************/
-
-static void ath9k_set_power_sleep(struct ath_hw *ah, int setChip)
-{
-       REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
-       if (setChip) {
-               REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE,
-                           AR_RTC_FORCE_WAKE_EN);
-               if (!AR_SREV_9100(ah))
-                       REG_WRITE(ah, AR_RC, AR_RC_AHB | AR_RC_HOSTIF);
-
-               REG_CLR_BIT(ah, (AR_RTC_RESET),
-                           AR_RTC_RESET_EN);
-       }
-}
-
-static void ath9k_set_power_network_sleep(struct ath_hw *ah, int setChip)
-{
-       REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
-       if (setChip) {
-               struct ath9k_hw_capabilities *pCap = &ah->caps;
-
-               if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
-                       REG_WRITE(ah, AR_RTC_FORCE_WAKE,
-                                 AR_RTC_FORCE_WAKE_ON_INT);
-               } else {
-                       REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE,
-                                   AR_RTC_FORCE_WAKE_EN);
-               }
-       }
-}
-
-static bool ath9k_hw_set_power_awake(struct ath_hw *ah, int setChip)
-{
-       u32 val;
-       int i;
-
-       if (setChip) {
-               if ((REG_READ(ah, AR_RTC_STATUS) &
-                    AR_RTC_STATUS_M) == AR_RTC_STATUS_SHUTDOWN) {
-                       if (ath9k_hw_set_reset_reg(ah,
-                                          ATH9K_RESET_POWER_ON) != true) {
-                               return false;
-                       }
-               }
-               if (AR_SREV_9100(ah))
-                       REG_SET_BIT(ah, AR_RTC_RESET,
-                                   AR_RTC_RESET_EN);
-
-               REG_SET_BIT(ah, AR_RTC_FORCE_WAKE,
-                           AR_RTC_FORCE_WAKE_EN);
-               udelay(50);
-
-               for (i = POWER_UP_TIME / 50; i > 0; i--) {
-                       val = REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M;
-                       if (val == AR_RTC_STATUS_ON)
-                               break;
-                       udelay(50);
-                       REG_SET_BIT(ah, AR_RTC_FORCE_WAKE,
-                                   AR_RTC_FORCE_WAKE_EN);
-               }
-               if (i == 0) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
-                               "Failed to wakeup in %uus\n", POWER_UP_TIME / 20);
-                       return false;
-               }
-       }
-
-       REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
-
-       return true;
-}
-
-bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode)
-{
-       int status = true, setChip = true;
-       static const char *modes[] = {
-               "AWAKE",
-               "FULL-SLEEP",
-               "NETWORK SLEEP",
-               "UNDEFINED"
-       };
-
-       DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT, "%s -> %s (%s)\n",
-               modes[ah->power_mode], modes[mode],
-               setChip ? "set chip " : "");
-
-       switch (mode) {
-       case ATH9K_PM_AWAKE:
-               status = ath9k_hw_set_power_awake(ah, setChip);
-               break;
-       case ATH9K_PM_FULL_SLEEP:
-               ath9k_set_power_sleep(ah, setChip);
-               ah->chip_fullsleep = true;
-               break;
-       case ATH9K_PM_NETWORK_SLEEP:
-               ath9k_set_power_network_sleep(ah, setChip);
-               break;
-       default:
-               DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
-                       "Unknown power mode %u\n", mode);
-               return false;
-       }
-       ah->power_mode = mode;
-
-       return status;
-}
-
-/*
- * Helper for ASPM support.
- *
- * Disable PLL when in L0s as well as receiver clock when in L1.
- * This power saving option must be enabled through the SerDes.
- *
- * Programming the SerDes must go through the same 288 bit serial shift
- * register as the other analog registers.  Hence the 9 writes.
- */
-void ath9k_hw_configpcipowersave(struct ath_hw *ah, int restore)
-{
-       u8 i;
-
-       if (ah->is_pciexpress != true)
-               return;
-
-       /* Do not touch SerDes registers */
-       if (ah->config.pcie_powersave_enable == 2)
-               return;
-
-       /* Nothing to do on restore for 11N */
-       if (restore)
-               return;
-
-       if (AR_SREV_9280_20_OR_LATER(ah)) {
-               /*
-                * AR9280 2.0 or later chips use SerDes values from the
-                * initvals.h initialized depending on chipset during
-                * ath9k_hw_do_attach()
-                */
-               for (i = 0; i < ah->iniPcieSerdes.ia_rows; i++) {
-                       REG_WRITE(ah, INI_RA(&ah->iniPcieSerdes, i, 0),
-                                 INI_RA(&ah->iniPcieSerdes, i, 1));
-               }
-       } else if (AR_SREV_9280(ah) &&
-                  (ah->hw_version.macRev == AR_SREV_REVISION_9280_10)) {
-               REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fd00);
-               REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
-
-               /* RX shut off when elecidle is asserted */
-               REG_WRITE(ah, AR_PCIE_SERDES, 0xa8000019);
-               REG_WRITE(ah, AR_PCIE_SERDES, 0x13160820);
-               REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980560);
-
-               /* Shut off CLKREQ active in L1 */
-               if (ah->config.pcie_clock_req)
-                       REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffc);
-               else
-                       REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffd);
-
-               REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
-               REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
-               REG_WRITE(ah, AR_PCIE_SERDES, 0x00043007);
-
-               /* Load the new settings */
-               REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
-
-       } else {
-               REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00);
-               REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
-
-               /* RX shut off when elecidle is asserted */
-               REG_WRITE(ah, AR_PCIE_SERDES, 0x28000039);
-               REG_WRITE(ah, AR_PCIE_SERDES, 0x53160824);
-               REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980579);
-
-               /*
-                * Ignore ah->ah_config.pcie_clock_req setting for
-                * pre-AR9280 11n
-                */
-               REG_WRITE(ah, AR_PCIE_SERDES, 0x001defff);
-
-               REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
-               REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
-               REG_WRITE(ah, AR_PCIE_SERDES, 0x000e3007);
-
-               /* Load the new settings */
-               REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
-       }
-
-       udelay(1000);
-
-       /* 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);
-
-       /* Several PCIe massages to ensure proper behaviour */
-       if (ah->config.pcie_waen) {
-               REG_WRITE(ah, AR_WA, ah->config.pcie_waen);
-       } else {
-               if (AR_SREV_9285(ah))
-                       REG_WRITE(ah, AR_WA, AR9285_WA_DEFAULT);
-               /*
-                * On AR9280 chips bit 22 of 0x4004 needs to be set to
-                * otherwise card may disappear.
-                */
-               else if (AR_SREV_9280(ah))
-                       REG_WRITE(ah, AR_WA, AR9280_WA_DEFAULT);
-               else
-                       REG_WRITE(ah, AR_WA, AR_WA_DEFAULT);
-       }
-}
-
-/**********************/
-/* Interrupt Handling */
-/**********************/
-
-bool ath9k_hw_intrpend(struct ath_hw *ah)
-{
-       u32 host_isr;
-
-       if (AR_SREV_9100(ah))
-               return true;
-
-       host_isr = REG_READ(ah, AR_INTR_ASYNC_CAUSE);
-       if ((host_isr & AR_INTR_MAC_IRQ) && (host_isr != AR_INTR_SPURIOUS))
-               return true;
-
-       host_isr = REG_READ(ah, AR_INTR_SYNC_CAUSE);
-       if ((host_isr & AR_INTR_SYNC_DEFAULT)
-           && (host_isr != AR_INTR_SPURIOUS))
-               return true;
-
-       return false;
-}
-
-bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked)
-{
-       u32 isr = 0;
-       u32 mask2 = 0;
-       struct ath9k_hw_capabilities *pCap = &ah->caps;
-       u32 sync_cause = 0;
-       bool fatal_int = false;
-
-       if (!AR_SREV_9100(ah)) {
-               if (REG_READ(ah, AR_INTR_ASYNC_CAUSE) & AR_INTR_MAC_IRQ) {
-                       if ((REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M)
-                           == AR_RTC_STATUS_ON) {
-                               isr = REG_READ(ah, AR_ISR);
-                       }
-               }
-
-               sync_cause = REG_READ(ah, AR_INTR_SYNC_CAUSE) &
-                       AR_INTR_SYNC_DEFAULT;
-
-               *masked = 0;
-
-               if (!isr && !sync_cause)
-                       return false;
-       } else {
-               *masked = 0;
-               isr = REG_READ(ah, AR_ISR);
-       }
-
-       if (isr) {
-               if (isr & AR_ISR_BCNMISC) {
-                       u32 isr2;
-                       isr2 = REG_READ(ah, AR_ISR_S2);
-                       if (isr2 & AR_ISR_S2_TIM)
-                               mask2 |= ATH9K_INT_TIM;
-                       if (isr2 & AR_ISR_S2_DTIM)
-                               mask2 |= ATH9K_INT_DTIM;
-                       if (isr2 & AR_ISR_S2_DTIMSYNC)
-                               mask2 |= ATH9K_INT_DTIMSYNC;
-                       if (isr2 & (AR_ISR_S2_CABEND))
-                               mask2 |= ATH9K_INT_CABEND;
-                       if (isr2 & AR_ISR_S2_GTT)
-                               mask2 |= ATH9K_INT_GTT;
-                       if (isr2 & AR_ISR_S2_CST)
-                               mask2 |= ATH9K_INT_CST;
-                       if (isr2 & AR_ISR_S2_TSFOOR)
-                               mask2 |= ATH9K_INT_TSFOOR;
-               }
-
-               isr = REG_READ(ah, AR_ISR_RAC);
-               if (isr == 0xffffffff) {
-                       *masked = 0;
-                       return false;
-               }
-
-               *masked = isr & ATH9K_INT_COMMON;
-
-               if (ah->intr_mitigation) {
-                       if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM))
-                               *masked |= ATH9K_INT_RX;
-               }
-
-               if (isr & (AR_ISR_RXOK | AR_ISR_RXERR))
-                       *masked |= ATH9K_INT_RX;
-               if (isr &
-                   (AR_ISR_TXOK | AR_ISR_TXDESC | AR_ISR_TXERR |
-                    AR_ISR_TXEOL)) {
-                       u32 s0_s, s1_s;
-
-                       *masked |= ATH9K_INT_TX;
-
-                       s0_s = REG_READ(ah, AR_ISR_S0_S);
-                       ah->intr_txqs |= MS(s0_s, AR_ISR_S0_QCU_TXOK);
-                       ah->intr_txqs |= MS(s0_s, AR_ISR_S0_QCU_TXDESC);
-
-                       s1_s = REG_READ(ah, AR_ISR_S1_S);
-                       ah->intr_txqs |= MS(s1_s, AR_ISR_S1_QCU_TXERR);
-                       ah->intr_txqs |= MS(s1_s, AR_ISR_S1_QCU_TXEOL);
-               }
-
-               if (isr & AR_ISR_RXORN) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
-                               "receive FIFO overrun interrupt\n");
-               }
-
-               if (!AR_SREV_9100(ah)) {
-                       if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
-                               u32 isr5 = REG_READ(ah, AR_ISR_S5_S);
-                               if (isr5 & AR_ISR_S5_TIM_TIMER)
-                                       *masked |= ATH9K_INT_TIM_TIMER;
-                       }
-               }
-
-               *masked |= mask2;
-       }
-
-       if (AR_SREV_9100(ah))
-               return true;
-
-       if (sync_cause) {
-               fatal_int =
-                       (sync_cause &
-                        (AR_INTR_SYNC_HOST1_FATAL | AR_INTR_SYNC_HOST1_PERR))
-                       ? true : false;
-
-               if (fatal_int) {
-                       if (sync_cause & AR_INTR_SYNC_HOST1_FATAL) {
-                               DPRINTF(ah->ah_sc, ATH_DBG_ANY,
-                                       "received PCI FATAL interrupt\n");
-                       }
-                       if (sync_cause & AR_INTR_SYNC_HOST1_PERR) {
-                               DPRINTF(ah->ah_sc, ATH_DBG_ANY,
-                                       "received PCI PERR interrupt\n");
-                       }
-               }
-               if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
-                               "AR_INTR_SYNC_RADM_CPL_TIMEOUT\n");
-                       REG_WRITE(ah, AR_RC, AR_RC_HOSTIF);
-                       REG_WRITE(ah, AR_RC, 0);
-                       *masked |= ATH9K_INT_FATAL;
-               }
-               if (sync_cause & AR_INTR_SYNC_LOCAL_TIMEOUT) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
-                               "AR_INTR_SYNC_LOCAL_TIMEOUT\n");
-               }
-
-               REG_WRITE(ah, AR_INTR_SYNC_CAUSE_CLR, sync_cause);
-               (void) REG_READ(ah, AR_INTR_SYNC_CAUSE_CLR);
-       }
-
-       return true;
-}
-
-enum ath9k_int ath9k_hw_intrget(struct ath_hw *ah)
-{
-       return ah->mask_reg;
-}
-
-enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints)
-{
-       u32 omask = ah->mask_reg;
-       u32 mask, mask2;
-       struct ath9k_hw_capabilities *pCap = &ah->caps;
-
-       DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "0x%x => 0x%x\n", omask, ints);
-
-       if (omask & ATH9K_INT_GLOBAL) {
-               DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "disable IER\n");
-               REG_WRITE(ah, AR_IER, AR_IER_DISABLE);
-               (void) REG_READ(ah, AR_IER);
-               if (!AR_SREV_9100(ah)) {
-                       REG_WRITE(ah, AR_INTR_ASYNC_ENABLE, 0);
-                       (void) REG_READ(ah, AR_INTR_ASYNC_ENABLE);
-
-                       REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0);
-                       (void) REG_READ(ah, AR_INTR_SYNC_ENABLE);
-               }
-       }
-
-       mask = ints & ATH9K_INT_COMMON;
-       mask2 = 0;
-
-       if (ints & ATH9K_INT_TX) {
-               if (ah->txok_interrupt_mask)
-                       mask |= AR_IMR_TXOK;
-               if (ah->txdesc_interrupt_mask)
-                       mask |= AR_IMR_TXDESC;
-               if (ah->txerr_interrupt_mask)
-                       mask |= AR_IMR_TXERR;
-               if (ah->txeol_interrupt_mask)
-                       mask |= AR_IMR_TXEOL;
-       }
-       if (ints & ATH9K_INT_RX) {
-               mask |= AR_IMR_RXERR;
-               if (ah->intr_mitigation)
-                       mask |= AR_IMR_RXMINTR | AR_IMR_RXINTM;
-               else
-                       mask |= AR_IMR_RXOK | AR_IMR_RXDESC;
-               if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
-                       mask |= AR_IMR_GENTMR;
-       }
-
-       if (ints & (ATH9K_INT_BMISC)) {
-               mask |= AR_IMR_BCNMISC;
-               if (ints & ATH9K_INT_TIM)
-                       mask2 |= AR_IMR_S2_TIM;
-               if (ints & ATH9K_INT_DTIM)
-                       mask2 |= AR_IMR_S2_DTIM;
-               if (ints & ATH9K_INT_DTIMSYNC)
-                       mask2 |= AR_IMR_S2_DTIMSYNC;
-               if (ints & ATH9K_INT_CABEND)
-                       mask2 |= AR_IMR_S2_CABEND;
-               if (ints & ATH9K_INT_TSFOOR)
-                       mask2 |= AR_IMR_S2_TSFOOR;
-       }
-
-       if (ints & (ATH9K_INT_GTT | ATH9K_INT_CST)) {
-               mask |= AR_IMR_BCNMISC;
-               if (ints & ATH9K_INT_GTT)
-                       mask2 |= AR_IMR_S2_GTT;
-               if (ints & ATH9K_INT_CST)
-                       mask2 |= AR_IMR_S2_CST;
-       }
-
-       DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "new IMR 0x%x\n", mask);
-       REG_WRITE(ah, AR_IMR, mask);
-       mask = REG_READ(ah, AR_IMR_S2) & ~(AR_IMR_S2_TIM |
-                                          AR_IMR_S2_DTIM |
-                                          AR_IMR_S2_DTIMSYNC |
-                                          AR_IMR_S2_CABEND |
-                                          AR_IMR_S2_CABTO |
-                                          AR_IMR_S2_TSFOOR |
-                                          AR_IMR_S2_GTT | AR_IMR_S2_CST);
-       REG_WRITE(ah, AR_IMR_S2, mask | mask2);
-       ah->mask_reg = ints;
-
-       if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
-               if (ints & ATH9K_INT_TIM_TIMER)
-                       REG_SET_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);
-               else
-                       REG_CLR_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);
-       }
-
-       if (ints & ATH9K_INT_GLOBAL) {
-               DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "enable IER\n");
-               REG_WRITE(ah, AR_IER, AR_IER_ENABLE);
-               if (!AR_SREV_9100(ah)) {
-                       REG_WRITE(ah, AR_INTR_ASYNC_ENABLE,
-                                 AR_INTR_MAC_IRQ);
-                       REG_WRITE(ah, AR_INTR_ASYNC_MASK, AR_INTR_MAC_IRQ);
-
-
-                       REG_WRITE(ah, AR_INTR_SYNC_ENABLE,
-                                 AR_INTR_SYNC_DEFAULT);
-                       REG_WRITE(ah, AR_INTR_SYNC_MASK,
-                                 AR_INTR_SYNC_DEFAULT);
-               }
-               DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "AR_IMR 0x%x IER 0x%x\n",
-                        REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER));
-       }
-
-       return omask;
-}
-
-/*******************/
-/* Beacon Handling */
-/*******************/
-
-void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period)
-{
-       int flags = 0;
-
-       ah->beacon_interval = beacon_period;
-
-       switch (ah->opmode) {
-       case NL80211_IFTYPE_STATION:
-       case NL80211_IFTYPE_MONITOR:
-               REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon));
-               REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, 0xffff);
-               REG_WRITE(ah, AR_NEXT_SWBA, 0x7ffff);
-               flags |= AR_TBTT_TIMER_EN;
-               break;
-       case NL80211_IFTYPE_ADHOC:
-       case NL80211_IFTYPE_MESH_POINT:
-               REG_SET_BIT(ah, AR_TXCFG,
-                           AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY);
-               REG_WRITE(ah, AR_NEXT_NDP_TIMER,
-                         TU_TO_USEC(next_beacon +
-                                    (ah->atim_window ? ah->
-                                     atim_window : 1)));
-               flags |= AR_NDP_TIMER_EN;
-       case NL80211_IFTYPE_AP:
-               REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon));
-               REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT,
-                         TU_TO_USEC(next_beacon -
-                                    ah->config.
-                                    dma_beacon_response_time));
-               REG_WRITE(ah, AR_NEXT_SWBA,
-                         TU_TO_USEC(next_beacon -
-                                    ah->config.
-                                    sw_beacon_response_time));
-               flags |=
-                       AR_TBTT_TIMER_EN | AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN;
-               break;
-       default:
-               DPRINTF(ah->ah_sc, ATH_DBG_BEACON,
-                       "%s: unsupported opmode: %d\n",
-                       __func__, ah->opmode);
-               return;
-               break;
-       }
-
-       REG_WRITE(ah, AR_BEACON_PERIOD, TU_TO_USEC(beacon_period));
-       REG_WRITE(ah, AR_DMA_BEACON_PERIOD, TU_TO_USEC(beacon_period));
-       REG_WRITE(ah, AR_SWBA_PERIOD, TU_TO_USEC(beacon_period));
-       REG_WRITE(ah, AR_NDP_PERIOD, TU_TO_USEC(beacon_period));
-
-       beacon_period &= ~ATH9K_BEACON_ENA;
-       if (beacon_period & ATH9K_BEACON_RESET_TSF) {
-               beacon_period &= ~ATH9K_BEACON_RESET_TSF;
-               ath9k_hw_reset_tsf(ah);
-       }
-
-       REG_SET_BIT(ah, AR_TIMER_MODE, flags);
-}
-
-void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
-                                   const struct ath9k_beacon_state *bs)
-{
-       u32 nextTbtt, beaconintval, dtimperiod, beacontimeout;
-       struct ath9k_hw_capabilities *pCap = &ah->caps;
-
-       REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(bs->bs_nexttbtt));
-
-       REG_WRITE(ah, AR_BEACON_PERIOD,
-                 TU_TO_USEC(bs->bs_intval & ATH9K_BEACON_PERIOD));
-       REG_WRITE(ah, AR_DMA_BEACON_PERIOD,
-                 TU_TO_USEC(bs->bs_intval & ATH9K_BEACON_PERIOD));
-
-       REG_RMW_FIELD(ah, AR_RSSI_THR,
-                     AR_RSSI_THR_BM_THR, bs->bs_bmissthreshold);
-
-       beaconintval = bs->bs_intval & ATH9K_BEACON_PERIOD;
-
-       if (bs->bs_sleepduration > beaconintval)
-               beaconintval = bs->bs_sleepduration;
-
-       dtimperiod = bs->bs_dtimperiod;
-       if (bs->bs_sleepduration > dtimperiod)
-               dtimperiod = bs->bs_sleepduration;
-
-       if (beaconintval == dtimperiod)
-               nextTbtt = bs->bs_nextdtim;
-       else
-               nextTbtt = bs->bs_nexttbtt;
-
-       DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "next DTIM %d\n", bs->bs_nextdtim);
-       DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "next beacon %d\n", nextTbtt);
-       DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "beacon period %d\n", beaconintval);
-       DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "DTIM period %d\n", dtimperiod);
-
-       REG_WRITE(ah, AR_NEXT_DTIM,
-                 TU_TO_USEC(bs->bs_nextdtim - SLEEP_SLOP));
-       REG_WRITE(ah, AR_NEXT_TIM, TU_TO_USEC(nextTbtt - SLEEP_SLOP));
-
-       REG_WRITE(ah, AR_SLEEP1,
-                 SM((CAB_TIMEOUT_VAL << 3), AR_SLEEP1_CAB_TIMEOUT)
-                 | AR_SLEEP1_ASSUME_DTIM);
-
-       if (pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)
-               beacontimeout = (BEACON_TIMEOUT_VAL << 3);
-       else
-               beacontimeout = MIN_BEACON_TIMEOUT_VAL;
-
-       REG_WRITE(ah, AR_SLEEP2,
-                 SM(beacontimeout, AR_SLEEP2_BEACON_TIMEOUT));
-
-       REG_WRITE(ah, AR_TIM_PERIOD, TU_TO_USEC(beaconintval));
-       REG_WRITE(ah, AR_DTIM_PERIOD, TU_TO_USEC(dtimperiod));
-
-       REG_SET_BIT(ah, AR_TIMER_MODE,
-                   AR_TBTT_TIMER_EN | AR_TIM_TIMER_EN |
-                   AR_DTIM_TIMER_EN);
-
-       /* TSF Out of Range Threshold */
-       REG_WRITE(ah, AR_TSFOOR_THRESHOLD, bs->bs_tsfoor_threshold);
-}
-
-/*******************/
-/* HW Capabilities */
-/*******************/
-
-bool ath9k_hw_fill_cap_info(struct ath_hw *ah)
-{
-       struct ath9k_hw_capabilities *pCap = &ah->caps;
-       u16 capField = 0, eeval;
-
-       eeval = ah->eep_ops->get_eeprom(ah, EEP_REG_0);
-       ah->regulatory.current_rd = eeval;
-
-       eeval = ah->eep_ops->get_eeprom(ah, EEP_REG_1);
-       if (AR_SREV_9285_10_OR_LATER(ah))
-               eeval |= AR9285_RDEXT_DEFAULT;
-       ah->regulatory.current_rd_ext = eeval;
-
-       capField = ah->eep_ops->get_eeprom(ah, EEP_OP_CAP);
-
-       if (ah->opmode != NL80211_IFTYPE_AP &&
-           ah->hw_version.subvendorid == AR_SUBVENDOR_ID_NEW_A) {
-               if (ah->regulatory.current_rd == 0x64 ||
-                   ah->regulatory.current_rd == 0x65)
-                       ah->regulatory.current_rd += 5;
-               else if (ah->regulatory.current_rd == 0x41)
-                       ah->regulatory.current_rd = 0x43;
-               DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
-                       "regdomain mapped to 0x%x\n", ah->regulatory.current_rd);
-       }
-
-       eeval = ah->eep_ops->get_eeprom(ah, EEP_OP_MODE);
-       bitmap_zero(pCap->wireless_modes, ATH9K_MODE_MAX);
-
-       if (eeval & AR5416_OPFLAGS_11A) {
-               set_bit(ATH9K_MODE_11A, pCap->wireless_modes);
-               if (ah->config.ht_enable) {
-                       if (!(eeval & AR5416_OPFLAGS_N_5G_HT20))
-                               set_bit(ATH9K_MODE_11NA_HT20,
-                                       pCap->wireless_modes);
-                       if (!(eeval & AR5416_OPFLAGS_N_5G_HT40)) {
-                               set_bit(ATH9K_MODE_11NA_HT40PLUS,
-                                       pCap->wireless_modes);
-                               set_bit(ATH9K_MODE_11NA_HT40MINUS,
-                                       pCap->wireless_modes);
-                       }
-               }
-       }
-
-       if (eeval & AR5416_OPFLAGS_11G) {
-               set_bit(ATH9K_MODE_11B, pCap->wireless_modes);
-               set_bit(ATH9K_MODE_11G, pCap->wireless_modes);
-               if (ah->config.ht_enable) {
-                       if (!(eeval & AR5416_OPFLAGS_N_2G_HT20))
-                               set_bit(ATH9K_MODE_11NG_HT20,
-                                       pCap->wireless_modes);
-                       if (!(eeval & AR5416_OPFLAGS_N_2G_HT40)) {
-                               set_bit(ATH9K_MODE_11NG_HT40PLUS,
-                                       pCap->wireless_modes);
-                               set_bit(ATH9K_MODE_11NG_HT40MINUS,
-                                       pCap->wireless_modes);
-                       }
-               }
-       }
-
-       pCap->tx_chainmask = ah->eep_ops->get_eeprom(ah, EEP_TX_MASK);
-       if ((ah->hw_version.devid == AR5416_DEVID_PCI) &&
-           !(eeval & AR5416_OPFLAGS_11A))
-               pCap->rx_chainmask = ath9k_hw_gpio_get(ah, 0) ? 0x5 : 0x7;
-       else
-               pCap->rx_chainmask = ah->eep_ops->get_eeprom(ah, EEP_RX_MASK);
-
-       if (!(AR_SREV_9280(ah) && (ah->hw_version.macRev == 0)))
-               ah->misc_mode |= AR_PCU_MIC_NEW_LOC_ENA;
-
-       pCap->low_2ghz_chan = 2312;
-       pCap->high_2ghz_chan = 2732;
-
-       pCap->low_5ghz_chan = 4920;
-       pCap->high_5ghz_chan = 6100;
-
-       pCap->hw_caps &= ~ATH9K_HW_CAP_CIPHER_CKIP;
-       pCap->hw_caps |= ATH9K_HW_CAP_CIPHER_TKIP;
-       pCap->hw_caps |= ATH9K_HW_CAP_CIPHER_AESCCM;
-
-       pCap->hw_caps &= ~ATH9K_HW_CAP_MIC_CKIP;
-       pCap->hw_caps |= ATH9K_HW_CAP_MIC_TKIP;
-       pCap->hw_caps |= ATH9K_HW_CAP_MIC_AESCCM;
-
-       pCap->hw_caps |= ATH9K_HW_CAP_CHAN_SPREAD;
-
-       if (ah->config.ht_enable)
-               pCap->hw_caps |= ATH9K_HW_CAP_HT;
-       else
-               pCap->hw_caps &= ~ATH9K_HW_CAP_HT;
-
-       pCap->hw_caps |= ATH9K_HW_CAP_GTT;
-       pCap->hw_caps |= ATH9K_HW_CAP_VEOL;
-       pCap->hw_caps |= ATH9K_HW_CAP_BSSIDMASK;
-       pCap->hw_caps &= ~ATH9K_HW_CAP_MCAST_KEYSEARCH;
-
-       if (capField & AR_EEPROM_EEPCAP_MAXQCU)
-               pCap->total_queues =
-                       MS(capField, AR_EEPROM_EEPCAP_MAXQCU);
-       else
-               pCap->total_queues = ATH9K_NUM_TX_QUEUES;
-
-       if (capField & AR_EEPROM_EEPCAP_KC_ENTRIES)
-               pCap->keycache_size =
-                       1 << MS(capField, AR_EEPROM_EEPCAP_KC_ENTRIES);
-       else
-               pCap->keycache_size = AR_KEYTABLE_SIZE;
-
-       pCap->hw_caps |= ATH9K_HW_CAP_FASTCC;
-       pCap->num_mr_retries = 4;
-       pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD;
-
-       if (AR_SREV_9285_10_OR_LATER(ah))
-               pCap->num_gpio_pins = AR9285_NUM_GPIO;
-       else if (AR_SREV_9280_10_OR_LATER(ah))
-               pCap->num_gpio_pins = AR928X_NUM_GPIO;
-       else
-               pCap->num_gpio_pins = AR_NUM_GPIO;
-
-       if (AR_SREV_9280_10_OR_LATER(ah)) {
-               pCap->hw_caps |= ATH9K_HW_CAP_WOW;
-               pCap->hw_caps |= ATH9K_HW_CAP_WOW_MATCHPATTERN_EXACT;
-       } else {
-               pCap->hw_caps &= ~ATH9K_HW_CAP_WOW;
-               pCap->hw_caps &= ~ATH9K_HW_CAP_WOW_MATCHPATTERN_EXACT;
-       }
-
-       if (AR_SREV_9160_10_OR_LATER(ah) || AR_SREV_9100(ah)) {
-               pCap->hw_caps |= ATH9K_HW_CAP_CST;
-               pCap->rts_aggr_limit = ATH_AMPDU_LIMIT_MAX;
-       } else {
-               pCap->rts_aggr_limit = (8 * 1024);
-       }
-
-       pCap->hw_caps |= ATH9K_HW_CAP_ENHANCEDPM;
-
-#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
-       ah->rfsilent = ah->eep_ops->get_eeprom(ah, EEP_RF_SILENT);
-       if (ah->rfsilent & EEP_RFSILENT_ENABLED) {
-               ah->rfkill_gpio =
-                       MS(ah->rfsilent, EEP_RFSILENT_GPIO_SEL);
-               ah->rfkill_polarity =
-                       MS(ah->rfsilent, EEP_RFSILENT_POLARITY);
-
-               pCap->hw_caps |= ATH9K_HW_CAP_RFSILENT;
-       }
-#endif
-
-       if ((ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) ||
-           (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCIE) ||
-           (ah->hw_version.macVersion == AR_SREV_VERSION_9160) ||
-           (ah->hw_version.macVersion == AR_SREV_VERSION_9100) ||
-           (ah->hw_version.macVersion == AR_SREV_VERSION_9280))
-               pCap->hw_caps &= ~ATH9K_HW_CAP_AUTOSLEEP;
-       else
-               pCap->hw_caps |= ATH9K_HW_CAP_AUTOSLEEP;
-
-       if (AR_SREV_9280(ah) || AR_SREV_9285(ah))
-               pCap->hw_caps &= ~ATH9K_HW_CAP_4KB_SPLITTRANS;
-       else
-               pCap->hw_caps |= ATH9K_HW_CAP_4KB_SPLITTRANS;
-
-       if (ah->regulatory.current_rd_ext & (1 << REG_EXT_JAPAN_MIDBAND)) {
-               pCap->reg_cap =
-                       AR_EEPROM_EEREGCAP_EN_KK_NEW_11A |
-                       AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN |
-                       AR_EEPROM_EEREGCAP_EN_KK_U2 |
-                       AR_EEPROM_EEREGCAP_EN_KK_MIDBAND;
-       } else {
-               pCap->reg_cap =
-                       AR_EEPROM_EEREGCAP_EN_KK_NEW_11A |
-                       AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN;
-       }
-
-       pCap->reg_cap |= AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND;
-
-       pCap->num_antcfg_5ghz =
-               ah->eep_ops->get_num_ant_config(ah, ATH9K_HAL_FREQ_BAND_5GHZ);
-       pCap->num_antcfg_2ghz =
-               ah->eep_ops->get_num_ant_config(ah, ATH9K_HAL_FREQ_BAND_2GHZ);
-
-       if (AR_SREV_9280_10_OR_LATER(ah) && btcoex_enable) {
-               pCap->hw_caps |= ATH9K_HW_CAP_BT_COEX;
-               ah->btactive_gpio = 6;
-               ah->wlanactive_gpio = 5;
-       }
-
-       return true;
-}
-
-bool ath9k_hw_getcapability(struct ath_hw *ah, enum ath9k_capability_type type,
-                           u32 capability, u32 *result)
-{
-       switch (type) {
-       case ATH9K_CAP_CIPHER:
-               switch (capability) {
-               case ATH9K_CIPHER_AES_CCM:
-               case ATH9K_CIPHER_AES_OCB:
-               case ATH9K_CIPHER_TKIP:
-               case ATH9K_CIPHER_WEP:
-               case ATH9K_CIPHER_MIC:
-               case ATH9K_CIPHER_CLR:
-                       return true;
-               default:
-                       return false;
-               }
-       case ATH9K_CAP_TKIP_MIC:
-               switch (capability) {
-               case 0:
-                       return true;
-               case 1:
-                       return (ah->sta_id1_defaults &
-                               AR_STA_ID1_CRPT_MIC_ENABLE) ? true :
-                       false;
-               }
-       case ATH9K_CAP_TKIP_SPLIT:
-               return (ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA) ?
-                       false : true;
-       case ATH9K_CAP_DIVERSITY:
-               return (REG_READ(ah, AR_PHY_CCK_DETECT) &
-                       AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV) ?
-                       true : false;
-       case ATH9K_CAP_MCAST_KEYSRCH:
-               switch (capability) {
-               case 0:
-                       return true;
-               case 1:
-                       if (REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_ADHOC) {
-                               return false;
-                       } else {
-                               return (ah->sta_id1_defaults &
-                                       AR_STA_ID1_MCAST_KSRCH) ? true :
-                                       false;
-                       }
-               }
-               return false;
-       case ATH9K_CAP_TXPOW:
-               switch (capability) {
-               case 0:
-                       return 0;
-               case 1:
-                       *result = ah->regulatory.power_limit;
-                       return 0;
-               case 2:
-                       *result = ah->regulatory.max_power_level;
-                       return 0;
-               case 3:
-                       *result = ah->regulatory.tp_scale;
-                       return 0;
-               }
-               return false;
-       case ATH9K_CAP_DS:
-               return (AR_SREV_9280_20_OR_LATER(ah) &&
-                       (ah->eep_ops->get_eeprom(ah, EEP_RC_CHAIN_MASK) == 1))
-                       ? false : true;
-       default:
-               return false;
-       }
-}
-
-bool ath9k_hw_setcapability(struct ath_hw *ah, enum ath9k_capability_type type,
-                           u32 capability, u32 setting, int *status)
-{
-       u32 v;
-
-       switch (type) {
-       case ATH9K_CAP_TKIP_MIC:
-               if (setting)
-                       ah->sta_id1_defaults |=
-                               AR_STA_ID1_CRPT_MIC_ENABLE;
-               else
-                       ah->sta_id1_defaults &=
-                               ~AR_STA_ID1_CRPT_MIC_ENABLE;
-               return true;
-       case ATH9K_CAP_DIVERSITY:
-               v = REG_READ(ah, AR_PHY_CCK_DETECT);
-               if (setting)
-                       v |= AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV;
-               else
-                       v &= ~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV;
-               REG_WRITE(ah, AR_PHY_CCK_DETECT, v);
-               return true;
-       case ATH9K_CAP_MCAST_KEYSRCH:
-               if (setting)
-                       ah->sta_id1_defaults |= AR_STA_ID1_MCAST_KSRCH;
-               else
-                       ah->sta_id1_defaults &= ~AR_STA_ID1_MCAST_KSRCH;
-               return true;
-       default:
-               return false;
-       }
-}
-
-/****************************/
-/* GPIO / RFKILL / Antennae */
-/****************************/
-
-static void ath9k_hw_gpio_cfg_output_mux(struct ath_hw *ah,
-                                        u32 gpio, u32 type)
-{
-       int addr;
-       u32 gpio_shift, tmp;
-
-       if (gpio > 11)
-               addr = AR_GPIO_OUTPUT_MUX3;
-       else if (gpio > 5)
-               addr = AR_GPIO_OUTPUT_MUX2;
-       else
-               addr = AR_GPIO_OUTPUT_MUX1;
-
-       gpio_shift = (gpio % 6) * 5;
-
-       if (AR_SREV_9280_20_OR_LATER(ah)
-           || (addr != AR_GPIO_OUTPUT_MUX1)) {
-               REG_RMW(ah, addr, (type << gpio_shift),
-                       (0x1f << gpio_shift));
-       } else {
-               tmp = REG_READ(ah, addr);
-               tmp = ((tmp & 0x1F0) << 1) | (tmp & ~0x1F0);
-               tmp &= ~(0x1f << gpio_shift);
-               tmp |= (type << gpio_shift);
-               REG_WRITE(ah, addr, tmp);
-       }
-}
-
-void ath9k_hw_cfg_gpio_input(struct ath_hw *ah, u32 gpio)
-{
-       u32 gpio_shift;
-
-       ASSERT(gpio < ah->caps.num_gpio_pins);
-
-       gpio_shift = gpio << 1;
-
-       REG_RMW(ah,
-               AR_GPIO_OE_OUT,
-               (AR_GPIO_OE_OUT_DRV_NO << gpio_shift),
-               (AR_GPIO_OE_OUT_DRV << gpio_shift));
-}
-
-u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio)
-{
-#define MS_REG_READ(x, y) \
-       (MS(REG_READ(ah, AR_GPIO_IN_OUT), x##_GPIO_IN_VAL) & (AR_GPIO_BIT(y)))
-
-       if (gpio >= ah->caps.num_gpio_pins)
-               return 0xffffffff;
-
-       if (AR_SREV_9285_10_OR_LATER(ah))
-               return MS_REG_READ(AR9285, gpio) != 0;
-       else if (AR_SREV_9280_10_OR_LATER(ah))
-               return MS_REG_READ(AR928X, gpio) != 0;
-       else
-               return MS_REG_READ(AR, gpio) != 0;
-}
-
-void ath9k_hw_cfg_output(struct ath_hw *ah, u32 gpio,
-                        u32 ah_signal_type)
-{
-       u32 gpio_shift;
-
-       ath9k_hw_gpio_cfg_output_mux(ah, gpio, ah_signal_type);
-
-       gpio_shift = 2 * gpio;
-
-       REG_RMW(ah,
-               AR_GPIO_OE_OUT,
-               (AR_GPIO_OE_OUT_DRV_ALL << gpio_shift),
-               (AR_GPIO_OE_OUT_DRV << gpio_shift));
-}
-
-void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val)
-{
-       REG_RMW(ah, AR_GPIO_IN_OUT, ((val & 1) << gpio),
-               AR_GPIO_BIT(gpio));
-}
-
-#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
-void ath9k_enable_rfkill(struct ath_hw *ah)
-{
-       REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
-                   AR_GPIO_INPUT_EN_VAL_RFSILENT_BB);
-
-       REG_CLR_BIT(ah, AR_GPIO_INPUT_MUX2,
-                   AR_GPIO_INPUT_MUX2_RFSILENT);
-
-       ath9k_hw_cfg_gpio_input(ah, ah->rfkill_gpio);
-       REG_SET_BIT(ah, AR_PHY_TEST, RFSILENT_BB);
-}
-#endif
-
-u32 ath9k_hw_getdefantenna(struct ath_hw *ah)
-{
-       return REG_READ(ah, AR_DEF_ANTENNA) & 0x7;
-}
-
-void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna)
-{
-       REG_WRITE(ah, AR_DEF_ANTENNA, (antenna & 0x7));
-}
-
-bool ath9k_hw_setantennaswitch(struct ath_hw *ah,
-                              enum ath9k_ant_setting settings,
-                              struct ath9k_channel *chan,
-                              u8 *tx_chainmask,
-                              u8 *rx_chainmask,
-                              u8 *antenna_cfgd)
-{
-       static u8 tx_chainmask_cfg, rx_chainmask_cfg;
-
-       if (AR_SREV_9280(ah)) {
-               if (!tx_chainmask_cfg) {
-
-                       tx_chainmask_cfg = *tx_chainmask;
-                       rx_chainmask_cfg = *rx_chainmask;
-               }
-
-               switch (settings) {
-               case ATH9K_ANT_FIXED_A:
-                       *tx_chainmask = ATH9K_ANTENNA0_CHAINMASK;
-                       *rx_chainmask = ATH9K_ANTENNA0_CHAINMASK;
-                       *antenna_cfgd = true;
-                       break;
-               case ATH9K_ANT_FIXED_B:
-                       if (ah->caps.tx_chainmask >
-                           ATH9K_ANTENNA1_CHAINMASK) {
-                               *tx_chainmask = ATH9K_ANTENNA1_CHAINMASK;
-                       }
-                       *rx_chainmask = ATH9K_ANTENNA1_CHAINMASK;
-                       *antenna_cfgd = true;
-                       break;
-               case ATH9K_ANT_VARIABLE:
-                       *tx_chainmask = tx_chainmask_cfg;
-                       *rx_chainmask = rx_chainmask_cfg;
-                       *antenna_cfgd = true;
-                       break;
-               default:
-                       break;
-               }
-       } else {
-               ah->diversity_control = settings;
-       }
-
-       return true;
-}
-
-/*********************/
-/* General Operation */
-/*********************/
-
-u32 ath9k_hw_getrxfilter(struct ath_hw *ah)
-{
-       u32 bits = REG_READ(ah, AR_RX_FILTER);
-       u32 phybits = REG_READ(ah, AR_PHY_ERR);
-
-       if (phybits & AR_PHY_ERR_RADAR)
-               bits |= ATH9K_RX_FILTER_PHYRADAR;
-       if (phybits & (AR_PHY_ERR_OFDM_TIMING | AR_PHY_ERR_CCK_TIMING))
-               bits |= ATH9K_RX_FILTER_PHYERR;
-
-       return bits;
-}
-
-void ath9k_hw_setrxfilter(struct ath_hw *ah, u32 bits)
-{
-       u32 phybits;
-
-       REG_WRITE(ah, AR_RX_FILTER, (bits & 0xffff) | AR_RX_COMPR_BAR);
-       phybits = 0;
-       if (bits & ATH9K_RX_FILTER_PHYRADAR)
-               phybits |= AR_PHY_ERR_RADAR;
-       if (bits & ATH9K_RX_FILTER_PHYERR)
-               phybits |= AR_PHY_ERR_OFDM_TIMING | AR_PHY_ERR_CCK_TIMING;
-       REG_WRITE(ah, AR_PHY_ERR, phybits);
-
-       if (phybits)
-               REG_WRITE(ah, AR_RXCFG,
-                         REG_READ(ah, AR_RXCFG) | AR_RXCFG_ZLFDMA);
-       else
-               REG_WRITE(ah, AR_RXCFG,
-                         REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_ZLFDMA);
-}
-
-bool ath9k_hw_phy_disable(struct ath_hw *ah)
-{
-       return ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM);
-}
-
-bool ath9k_hw_disable(struct ath_hw *ah)
-{
-       if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
-               return false;
-
-       return ath9k_hw_set_reset_reg(ah, ATH9K_RESET_COLD);
-}
-
-bool ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit)
-{
-       struct ath9k_channel *chan = ah->curchan;
-       struct ieee80211_channel *channel = chan->chan;
-
-       ah->regulatory.power_limit = min(limit, (u32) MAX_RATE_POWER);
-
-       if (ah->eep_ops->set_txpower(ah, chan,
-                            ath9k_regd_get_ctl(ah, chan),
-                            channel->max_antenna_gain * 2,
-                            channel->max_power * 2,
-                            min((u32) MAX_RATE_POWER,
-                                (u32) ah->regulatory.power_limit)) != 0)
-               return false;
-
-       return true;
-}
-
-void ath9k_hw_setmac(struct ath_hw *ah, const u8 *mac)
-{
-       memcpy(ah->macaddr, mac, ETH_ALEN);
-}
-
-void ath9k_hw_setopmode(struct ath_hw *ah)
-{
-       ath9k_hw_set_operating_mode(ah, ah->opmode);
-}
-
-void ath9k_hw_setmcastfilter(struct ath_hw *ah, u32 filter0, u32 filter1)
-{
-       REG_WRITE(ah, AR_MCAST_FIL0, filter0);
-       REG_WRITE(ah, AR_MCAST_FIL1, filter1);
-}
-
-void ath9k_hw_setbssidmask(struct ath_softc *sc)
-{
-       REG_WRITE(sc->sc_ah, AR_BSSMSKL, get_unaligned_le32(sc->bssidmask));
-       REG_WRITE(sc->sc_ah, AR_BSSMSKU, get_unaligned_le16(sc->bssidmask + 4));
-}
-
-void ath9k_hw_write_associd(struct ath_softc *sc)
-{
-       REG_WRITE(sc->sc_ah, AR_BSS_ID0, get_unaligned_le32(sc->curbssid));
-       REG_WRITE(sc->sc_ah, AR_BSS_ID1, get_unaligned_le16(sc->curbssid + 4) |
-                 ((sc->curaid & 0x3fff) << AR_BSS_ID1_AID_S));
-}
-
-u64 ath9k_hw_gettsf64(struct ath_hw *ah)
-{
-       u64 tsf;
-
-       tsf = REG_READ(ah, AR_TSF_U32);
-       tsf = (tsf << 32) | REG_READ(ah, AR_TSF_L32);
-
-       return tsf;
-}
-
-void ath9k_hw_settsf64(struct ath_hw *ah, u64 tsf64)
-{
-       REG_WRITE(ah, AR_TSF_L32, tsf64 & 0xffffffff);
-       REG_WRITE(ah, AR_TSF_U32, (tsf64 >> 32) & 0xffffffff);
-}
-
-void ath9k_hw_reset_tsf(struct ath_hw *ah)
-{
-       int count;
-
-       count = 0;
-       while (REG_READ(ah, AR_SLP32_MODE) & AR_SLP32_TSF_WRITE_STATUS) {
-               count++;
-               if (count > 10) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_RESET,
-                               "AR_SLP32_TSF_WRITE_STATUS limit exceeded\n");
-                       break;
-               }
-               udelay(10);
-       }
-       REG_WRITE(ah, AR_RESET_TSF, AR_RESET_TSF_ONCE);
-}
-
-bool ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting)
-{
-       if (setting)
-               ah->misc_mode |= AR_PCU_TX_ADD_TSF;
-       else
-               ah->misc_mode &= ~AR_PCU_TX_ADD_TSF;
-
-       return true;
-}
-
-bool ath9k_hw_setslottime(struct ath_hw *ah, u32 us)
-{
-       if (us < ATH9K_SLOT_TIME_9 || us > ath9k_hw_mac_to_usec(ah, 0xffff)) {
-               DPRINTF(ah->ah_sc, ATH_DBG_RESET, "bad slot time %u\n", us);
-               ah->slottime = (u32) -1;
-               return false;
-       } else {
-               REG_WRITE(ah, AR_D_GBL_IFS_SLOT, ath9k_hw_mac_to_clks(ah, us));
-               ah->slottime = us;
-               return true;
-       }
-}
-
-void ath9k_hw_set11nmac2040(struct ath_hw *ah, enum ath9k_ht_macmode mode)
-{
-       u32 macmode;
-
-       if (mode == ATH9K_HT_MACMODE_2040 &&
-           !ah->config.cwm_ignore_extcca)
-               macmode = AR_2040_JOINED_RX_CLEAR;
-       else
-               macmode = 0;
-
-       REG_WRITE(ah, AR_2040_MODE, macmode);
-}
-
-/***************************/
-/*  Bluetooth Coexistence  */
-/***************************/
-
-void ath9k_hw_btcoex_enable(struct ath_hw *ah)
-{
-       /* connect bt_active to baseband */
-       REG_CLR_BIT(ah, AR_GPIO_INPUT_EN_VAL,
-                       (AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_DEF |
-                        AR_GPIO_INPUT_EN_VAL_BT_FREQUENCY_DEF));
-
-       REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
-                       AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_BB);
-
-       /* Set input mux for bt_active to gpio pin */
-       REG_RMW_FIELD(ah, AR_GPIO_INPUT_MUX1,
-                       AR_GPIO_INPUT_MUX1_BT_ACTIVE,
-                       ah->btactive_gpio);
-
-       /* Configure the desired gpio port for input */
-       ath9k_hw_cfg_gpio_input(ah, ah->btactive_gpio);
-
-       /* Configure the desired GPIO port for TX_FRAME output */
-       ath9k_hw_cfg_output(ah, ah->wlanactive_gpio,
-                           AR_GPIO_OUTPUT_MUX_AS_TX_FRAME);
-}
diff --git a/drivers/net/wireless/ath9k/hw.h b/drivers/net/wireless/ath9k/hw.h
deleted file mode 100644 (file)
index 0b594e0..0000000
+++ /dev/null
@@ -1,647 +0,0 @@
-/*
- * Copyright (c) 2008-2009 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 HW_H
-#define HW_H
-
-#include <linux/if_ether.h>
-#include <linux/delay.h>
-#include <linux/io.h>
-
-#include "mac.h"
-#include "ani.h"
-#include "eeprom.h"
-#include "calib.h"
-#include "regd.h"
-#include "reg.h"
-#include "phy.h"
-
-#define ATHEROS_VENDOR_ID      0x168c
-#define AR5416_DEVID_PCI       0x0023
-#define AR5416_DEVID_PCIE      0x0024
-#define AR9160_DEVID_PCI       0x0027
-#define AR9280_DEVID_PCI       0x0029
-#define AR9280_DEVID_PCIE      0x002a
-#define AR9285_DEVID_PCIE      0x002b
-#define AR5416_AR9100_DEVID    0x000b
-#define        AR_SUBVENDOR_ID_NOG     0x0e11
-#define AR_SUBVENDOR_ID_NEW_A  0x7065
-#define AR5416_MAGIC           0x19641014
-
-/* Register read/write primitives */
-#define REG_WRITE(_ah, _reg, _val) ath9k_iowrite32((_ah), (_reg), (_val))
-#define REG_READ(_ah, _reg) ath9k_ioread32((_ah), (_reg))
-
-#define SM(_v, _f)  (((_v) << _f##_S) & _f)
-#define MS(_v, _f)  (((_v) & _f) >> _f##_S)
-#define REG_RMW(_a, _r, _set, _clr)    \
-       REG_WRITE(_a, _r, (REG_READ(_a, _r) & ~(_clr)) | (_set))
-#define REG_RMW_FIELD(_a, _r, _f, _v) \
-       REG_WRITE(_a, _r, \
-       (REG_READ(_a, _r) & ~_f) | (((_v) << _f##_S) & _f))
-#define REG_SET_BIT(_a, _r, _f) \
-       REG_WRITE(_a, _r, REG_READ(_a, _r) | _f)
-#define REG_CLR_BIT(_a, _r, _f) \
-       REG_WRITE(_a, _r, REG_READ(_a, _r) & ~_f)
-
-#define DO_DELAY(x) do {                       \
-               if ((++(x) % 64) == 0)          \
-                       udelay(1);              \
-       } while (0)
-
-#define REG_WRITE_ARRAY(iniarray, column, regWr) do {                   \
-               int r;                                                  \
-               for (r = 0; r < ((iniarray)->ia_rows); r++) {           \
-                       REG_WRITE(ah, INI_RA((iniarray), (r), 0),       \
-                                 INI_RA((iniarray), r, (column)));     \
-                       DO_DELAY(regWr);                                \
-               }                                                       \
-       } while (0)
-
-#define AR_GPIO_OUTPUT_MUX_AS_OUTPUT             0
-#define AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED 1
-#define AR_GPIO_OUTPUT_MUX_AS_PCIE_POWER_LED     2
-#define AR_GPIO_OUTPUT_MUX_AS_TX_FRAME           3
-#define AR_GPIO_OUTPUT_MUX_AS_MAC_NETWORK_LED    5
-#define AR_GPIO_OUTPUT_MUX_AS_MAC_POWER_LED      6
-
-#define AR_GPIOD_MASK               0x00001FFF
-#define AR_GPIO_BIT(_gpio)          (1 << (_gpio))
-
-#define BASE_ACTIVATE_DELAY         100
-#define RTC_PLL_SETTLE_DELAY        1000
-#define COEF_SCALE_S                24
-#define HT40_CHANNEL_CENTER_SHIFT   10
-
-#define ATH9K_ANTENNA0_CHAINMASK    0x1
-#define ATH9K_ANTENNA1_CHAINMASK    0x2
-
-#define ATH9K_NUM_DMA_DEBUG_REGS    8
-#define ATH9K_NUM_QUEUES            10
-
-#define MAX_RATE_POWER              63
-#define AH_WAIT_TIMEOUT             100000 /* (us) */
-#define AH_TIME_QUANTUM             10
-#define AR_KEYTABLE_SIZE            128
-#define POWER_UP_TIME               200000
-#define SPUR_RSSI_THRESH            40
-
-#define CAB_TIMEOUT_VAL             10
-#define BEACON_TIMEOUT_VAL          10
-#define MIN_BEACON_TIMEOUT_VAL      1
-#define SLEEP_SLOP                  3
-
-#define INIT_CONFIG_STATUS          0x00000000
-#define INIT_RSSI_THR               0x00000700
-#define INIT_BCON_CNTRL_REG         0x00000000
-
-#define TU_TO_USEC(_tu)             ((_tu) << 10)
-
-enum wireless_mode {
-       ATH9K_MODE_11A = 0,
-       ATH9K_MODE_11B = 2,
-       ATH9K_MODE_11G = 3,
-       ATH9K_MODE_11NA_HT20 = 6,
-       ATH9K_MODE_11NG_HT20 = 7,
-       ATH9K_MODE_11NA_HT40PLUS = 8,
-       ATH9K_MODE_11NA_HT40MINUS = 9,
-       ATH9K_MODE_11NG_HT40PLUS = 10,
-       ATH9K_MODE_11NG_HT40MINUS = 11,
-       ATH9K_MODE_MAX
-};
-
-enum ath9k_hw_caps {
-       ATH9K_HW_CAP_CHAN_SPREAD                = BIT(0),
-       ATH9K_HW_CAP_MIC_AESCCM                 = BIT(1),
-       ATH9K_HW_CAP_MIC_CKIP                   = BIT(2),
-       ATH9K_HW_CAP_MIC_TKIP                   = BIT(3),
-       ATH9K_HW_CAP_CIPHER_AESCCM              = BIT(4),
-       ATH9K_HW_CAP_CIPHER_CKIP                = BIT(5),
-       ATH9K_HW_CAP_CIPHER_TKIP                = BIT(6),
-       ATH9K_HW_CAP_VEOL                       = BIT(7),
-       ATH9K_HW_CAP_BSSIDMASK                  = BIT(8),
-       ATH9K_HW_CAP_MCAST_KEYSEARCH            = BIT(9),
-       ATH9K_HW_CAP_CHAN_HALFRATE              = BIT(10),
-       ATH9K_HW_CAP_CHAN_QUARTERRATE           = BIT(11),
-       ATH9K_HW_CAP_HT                         = BIT(12),
-       ATH9K_HW_CAP_GTT                        = BIT(13),
-       ATH9K_HW_CAP_FASTCC                     = BIT(14),
-       ATH9K_HW_CAP_RFSILENT                   = BIT(15),
-       ATH9K_HW_CAP_WOW                        = BIT(16),
-       ATH9K_HW_CAP_CST                        = BIT(17),
-       ATH9K_HW_CAP_ENHANCEDPM                 = BIT(18),
-       ATH9K_HW_CAP_AUTOSLEEP                  = BIT(19),
-       ATH9K_HW_CAP_4KB_SPLITTRANS             = BIT(20),
-       ATH9K_HW_CAP_WOW_MATCHPATTERN_EXACT     = BIT(21),
-       ATH9K_HW_CAP_BT_COEX                    = BIT(22)
-};
-
-enum ath9k_capability_type {
-       ATH9K_CAP_CIPHER = 0,
-       ATH9K_CAP_TKIP_MIC,
-       ATH9K_CAP_TKIP_SPLIT,
-       ATH9K_CAP_DIVERSITY,
-       ATH9K_CAP_TXPOW,
-       ATH9K_CAP_MCAST_KEYSRCH,
-       ATH9K_CAP_DS
-};
-
-struct ath9k_hw_capabilities {
-       u32 hw_caps; /* ATH9K_HW_CAP_* from ath9k_hw_caps */
-       DECLARE_BITMAP(wireless_modes, ATH9K_MODE_MAX); /* ATH9K_MODE_* */
-       u16 total_queues;
-       u16 keycache_size;
-       u16 low_5ghz_chan, high_5ghz_chan;
-       u16 low_2ghz_chan, high_2ghz_chan;
-       u16 num_mr_retries;
-       u16 rts_aggr_limit;
-       u8 tx_chainmask;
-       u8 rx_chainmask;
-       u16 tx_triglevel_max;
-       u16 reg_cap;
-       u8 num_gpio_pins;
-       u8 num_antcfg_2ghz;
-       u8 num_antcfg_5ghz;
-};
-
-struct ath9k_ops_config {
-       int dma_beacon_response_time;
-       int sw_beacon_response_time;
-       int additional_swba_backoff;
-       int ack_6mb;
-       int cwm_ignore_extcca;
-       u8 pcie_powersave_enable;
-       u8 pcie_l1skp_enable;
-       u8 pcie_clock_req;
-       u32 pcie_waen;
-       int pcie_power_reset;
-       u8 pcie_restore;
-       u8 analog_shiftreg;
-       u8 ht_enable;
-       u32 ofdm_trig_low;
-       u32 ofdm_trig_high;
-       u32 cck_trig_high;
-       u32 cck_trig_low;
-       u32 enable_ani;
-       u8 noise_immunity_level;
-       u32 ofdm_weaksignal_det;
-       u32 cck_weaksignal_thr;
-       u8 spur_immunity_level;
-       u8 firstep_level;
-       int8_t rssi_thr_high;
-       int8_t rssi_thr_low;
-       u16 diversity_control;
-       u16 antenna_switch_swap;
-       int serialize_regmode;
-       int intr_mitigation;
-#define SPUR_DISABLE           0
-#define SPUR_ENABLE_IOCTL      1
-#define SPUR_ENABLE_EEPROM     2
-#define AR_EEPROM_MODAL_SPURS   5
-#define AR_SPUR_5413_1         1640
-#define AR_SPUR_5413_2         1200
-#define AR_NO_SPUR             0x8000
-#define AR_BASE_FREQ_2GHZ      2300
-#define AR_BASE_FREQ_5GHZ      4900
-#define AR_SPUR_FEEQ_BOUND_HT40 19
-#define AR_SPUR_FEEQ_BOUND_HT20 10
-       int spurmode;
-       u16 spurchans[AR_EEPROM_MODAL_SPURS][2];
-};
-
-enum ath9k_int {
-       ATH9K_INT_RX = 0x00000001,
-       ATH9K_INT_RXDESC = 0x00000002,
-       ATH9K_INT_RXNOFRM = 0x00000008,
-       ATH9K_INT_RXEOL = 0x00000010,
-       ATH9K_INT_RXORN = 0x00000020,
-       ATH9K_INT_TX = 0x00000040,
-       ATH9K_INT_TXDESC = 0x00000080,
-       ATH9K_INT_TIM_TIMER = 0x00000100,
-       ATH9K_INT_TXURN = 0x00000800,
-       ATH9K_INT_MIB = 0x00001000,
-       ATH9K_INT_RXPHY = 0x00004000,
-       ATH9K_INT_RXKCM = 0x00008000,
-       ATH9K_INT_SWBA = 0x00010000,
-       ATH9K_INT_BMISS = 0x00040000,
-       ATH9K_INT_BNR = 0x00100000,
-       ATH9K_INT_TIM = 0x00200000,
-       ATH9K_INT_DTIM = 0x00400000,
-       ATH9K_INT_DTIMSYNC = 0x00800000,
-       ATH9K_INT_GPIO = 0x01000000,
-       ATH9K_INT_CABEND = 0x02000000,
-       ATH9K_INT_TSFOOR = 0x04000000,
-       ATH9K_INT_CST = 0x10000000,
-       ATH9K_INT_GTT = 0x20000000,
-       ATH9K_INT_FATAL = 0x40000000,
-       ATH9K_INT_GLOBAL = 0x80000000,
-       ATH9K_INT_BMISC = ATH9K_INT_TIM |
-               ATH9K_INT_DTIM |
-               ATH9K_INT_DTIMSYNC |
-               ATH9K_INT_TSFOOR |
-               ATH9K_INT_CABEND,
-       ATH9K_INT_COMMON = ATH9K_INT_RXNOFRM |
-               ATH9K_INT_RXDESC |
-               ATH9K_INT_RXEOL |
-               ATH9K_INT_RXORN |
-               ATH9K_INT_TXURN |
-               ATH9K_INT_TXDESC |
-               ATH9K_INT_MIB |
-               ATH9K_INT_RXPHY |
-               ATH9K_INT_RXKCM |
-               ATH9K_INT_SWBA |
-               ATH9K_INT_BMISS |
-               ATH9K_INT_GPIO,
-       ATH9K_INT_NOCARD = 0xffffffff
-};
-
-#define CHANNEL_CW_INT    0x00002
-#define CHANNEL_CCK       0x00020
-#define CHANNEL_OFDM      0x00040
-#define CHANNEL_2GHZ      0x00080
-#define CHANNEL_5GHZ      0x00100
-#define CHANNEL_PASSIVE   0x00200
-#define CHANNEL_DYN       0x00400
-#define CHANNEL_HALF      0x04000
-#define CHANNEL_QUARTER   0x08000
-#define CHANNEL_HT20      0x10000
-#define CHANNEL_HT40PLUS  0x20000
-#define CHANNEL_HT40MINUS 0x40000
-
-#define CHANNEL_INTERFERENCE    0x01
-#define CHANNEL_DFS             0x02
-#define CHANNEL_4MS_LIMIT       0x04
-#define CHANNEL_DFS_CLEAR       0x08
-#define CHANNEL_DISALLOW_ADHOC  0x10
-#define CHANNEL_PER_11D_ADHOC   0x20
-
-#define CHANNEL_A           (CHANNEL_5GHZ|CHANNEL_OFDM)
-#define CHANNEL_B           (CHANNEL_2GHZ|CHANNEL_CCK)
-#define CHANNEL_G           (CHANNEL_2GHZ|CHANNEL_OFDM)
-#define CHANNEL_G_HT20      (CHANNEL_2GHZ|CHANNEL_HT20)
-#define CHANNEL_A_HT20      (CHANNEL_5GHZ|CHANNEL_HT20)
-#define CHANNEL_G_HT40PLUS  (CHANNEL_2GHZ|CHANNEL_HT40PLUS)
-#define CHANNEL_G_HT40MINUS (CHANNEL_2GHZ|CHANNEL_HT40MINUS)
-#define CHANNEL_A_HT40PLUS  (CHANNEL_5GHZ|CHANNEL_HT40PLUS)
-#define CHANNEL_A_HT40MINUS (CHANNEL_5GHZ|CHANNEL_HT40MINUS)
-#define CHANNEL_ALL                            \
-       (CHANNEL_OFDM|                          \
-        CHANNEL_CCK|                           \
-        CHANNEL_2GHZ |                         \
-        CHANNEL_5GHZ |                         \
-        CHANNEL_HT20 |                         \
-        CHANNEL_HT40PLUS |                     \
-        CHANNEL_HT40MINUS)
-
-struct ath9k_channel {
-       struct ieee80211_channel *chan;
-       u16 channel;
-       u32 channelFlags;
-       u32 chanmode;
-       int32_t CalValid;
-       bool oneTimeCalsDone;
-       int8_t iCoff;
-       int8_t qCoff;
-       int16_t rawNoiseFloor;
-};
-
-#define IS_CHAN_A(_c) ((((_c)->channelFlags & CHANNEL_A) == CHANNEL_A) || \
-       (((_c)->channelFlags & CHANNEL_A_HT20) == CHANNEL_A_HT20) || \
-       (((_c)->channelFlags & CHANNEL_A_HT40PLUS) == CHANNEL_A_HT40PLUS) || \
-       (((_c)->channelFlags & CHANNEL_A_HT40MINUS) == CHANNEL_A_HT40MINUS))
-#define IS_CHAN_G(_c) ((((_c)->channelFlags & (CHANNEL_G)) == CHANNEL_G) || \
-       (((_c)->channelFlags & CHANNEL_G_HT20) == CHANNEL_G_HT20) || \
-       (((_c)->channelFlags & CHANNEL_G_HT40PLUS) == CHANNEL_G_HT40PLUS) || \
-       (((_c)->channelFlags & CHANNEL_G_HT40MINUS) == CHANNEL_G_HT40MINUS))
-#define IS_CHAN_OFDM(_c) (((_c)->channelFlags & CHANNEL_OFDM) != 0)
-#define IS_CHAN_5GHZ(_c) (((_c)->channelFlags & CHANNEL_5GHZ) != 0)
-#define IS_CHAN_2GHZ(_c) (((_c)->channelFlags & CHANNEL_2GHZ) != 0)
-#define IS_CHAN_PASSIVE(_c) (((_c)->channelFlags & CHANNEL_PASSIVE) != 0)
-#define IS_CHAN_HALF_RATE(_c) (((_c)->channelFlags & CHANNEL_HALF) != 0)
-#define IS_CHAN_QUARTER_RATE(_c) (((_c)->channelFlags & CHANNEL_QUARTER) != 0)
-#define IS_CHAN_A_5MHZ_SPACED(_c)                      \
-       ((((_c)->channelFlags & CHANNEL_5GHZ) != 0) &&  \
-        (((_c)->channel % 20) != 0) &&                 \
-        (((_c)->channel % 10) != 0))
-
-/* These macros check chanmode and not channelFlags */
-#define IS_CHAN_B(_c) ((_c)->chanmode == CHANNEL_B)
-#define IS_CHAN_HT20(_c) (((_c)->chanmode == CHANNEL_A_HT20) ||        \
-                         ((_c)->chanmode == CHANNEL_G_HT20))
-#define IS_CHAN_HT40(_c) (((_c)->chanmode == CHANNEL_A_HT40PLUS) ||    \
-                         ((_c)->chanmode == CHANNEL_A_HT40MINUS) ||    \
-                         ((_c)->chanmode == CHANNEL_G_HT40PLUS) ||     \
-                         ((_c)->chanmode == CHANNEL_G_HT40MINUS))
-#define IS_CHAN_HT(_c) (IS_CHAN_HT20((_c)) || IS_CHAN_HT40((_c)))
-
-enum ath9k_power_mode {
-       ATH9K_PM_AWAKE = 0,
-       ATH9K_PM_FULL_SLEEP,
-       ATH9K_PM_NETWORK_SLEEP,
-       ATH9K_PM_UNDEFINED
-};
-
-enum ath9k_ant_setting {
-       ATH9K_ANT_VARIABLE = 0,
-       ATH9K_ANT_FIXED_A,
-       ATH9K_ANT_FIXED_B
-};
-
-enum ath9k_tp_scale {
-       ATH9K_TP_SCALE_MAX = 0,
-       ATH9K_TP_SCALE_50,
-       ATH9K_TP_SCALE_25,
-       ATH9K_TP_SCALE_12,
-       ATH9K_TP_SCALE_MIN
-};
-
-enum ser_reg_mode {
-       SER_REG_MODE_OFF = 0,
-       SER_REG_MODE_ON = 1,
-       SER_REG_MODE_AUTO = 2,
-};
-
-struct ath9k_beacon_state {
-       u32 bs_nexttbtt;
-       u32 bs_nextdtim;
-       u32 bs_intval;
-#define ATH9K_BEACON_PERIOD       0x0000ffff
-#define ATH9K_BEACON_ENA          0x00800000
-#define ATH9K_BEACON_RESET_TSF    0x01000000
-#define ATH9K_TSFOOR_THRESHOLD    0x00004240 /* 16k us */
-       u32 bs_dtimperiod;
-       u16 bs_cfpperiod;
-       u16 bs_cfpmaxduration;
-       u32 bs_cfpnext;
-       u16 bs_timoffset;
-       u16 bs_bmissthreshold;
-       u32 bs_sleepduration;
-       u32 bs_tsfoor_threshold;
-};
-
-struct chan_centers {
-       u16 synth_center;
-       u16 ctl_center;
-       u16 ext_center;
-};
-
-enum {
-       ATH9K_RESET_POWER_ON,
-       ATH9K_RESET_WARM,
-       ATH9K_RESET_COLD,
-};
-
-struct ath9k_hw_version {
-       u32 magic;
-       u16 devid;
-       u16 subvendorid;
-       u32 macVersion;
-       u16 macRev;
-       u16 phyRev;
-       u16 analog5GhzRev;
-       u16 analog2GhzRev;
-};
-
-struct ath_hw {
-       struct ath_softc *ah_sc;
-       struct ath9k_hw_version hw_version;
-       struct ath9k_ops_config config;
-       struct ath9k_hw_capabilities caps;
-       struct ath9k_regulatory regulatory;
-       struct ath9k_channel channels[38];
-       struct ath9k_channel *curchan;
-
-       union {
-               struct ar5416_eeprom_def def;
-               struct ar5416_eeprom_4k map4k;
-       } eeprom;
-       const struct eeprom_ops *eep_ops;
-       enum ath9k_eep_map eep_map;
-
-       bool sw_mgmt_crypto;
-       bool is_pciexpress;
-       u8 macaddr[ETH_ALEN];
-       u16 tx_trig_level;
-       u16 rfsilent;
-       u32 rfkill_gpio;
-       u32 rfkill_polarity;
-       u32 btactive_gpio;
-       u32 wlanactive_gpio;
-       u32 ah_flags;
-
-       enum nl80211_iftype opmode;
-       enum ath9k_power_mode power_mode;
-       enum ath9k_power_mode restore_mode;
-
-       struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS];
-       struct ar5416Stats stats;
-       struct ath9k_tx_queue_info txq[ATH9K_NUM_TX_QUEUES];
-
-       int16_t curchan_rad_index;
-       u32 mask_reg;
-       u32 txok_interrupt_mask;
-       u32 txerr_interrupt_mask;
-       u32 txdesc_interrupt_mask;
-       u32 txeol_interrupt_mask;
-       u32 txurn_interrupt_mask;
-       bool chip_fullsleep;
-       u32 atim_window;
-       u16 antenna_switch_swap;
-       enum ath9k_ant_setting diversity_control;
-
-       /* Calibration */
-       enum hal_cal_types supp_cals;
-       struct hal_cal_list iq_caldata;
-       struct hal_cal_list adcgain_caldata;
-       struct hal_cal_list adcdc_calinitdata;
-       struct hal_cal_list adcdc_caldata;
-       struct hal_cal_list *cal_list;
-       struct hal_cal_list *cal_list_last;
-       struct hal_cal_list *cal_list_curr;
-#define totalPowerMeasI meas0.unsign
-#define totalPowerMeasQ meas1.unsign
-#define totalIqCorrMeas meas2.sign
-#define totalAdcIOddPhase  meas0.unsign
-#define totalAdcIEvenPhase meas1.unsign
-#define totalAdcQOddPhase  meas2.unsign
-#define totalAdcQEvenPhase meas3.unsign
-#define totalAdcDcOffsetIOddPhase  meas0.sign
-#define totalAdcDcOffsetIEvenPhase meas1.sign
-#define totalAdcDcOffsetQOddPhase  meas2.sign
-#define totalAdcDcOffsetQEvenPhase meas3.sign
-       union {
-               u32 unsign[AR5416_MAX_CHAINS];
-               int32_t sign[AR5416_MAX_CHAINS];
-       } meas0;
-       union {
-               u32 unsign[AR5416_MAX_CHAINS];
-               int32_t sign[AR5416_MAX_CHAINS];
-       } meas1;
-       union {
-               u32 unsign[AR5416_MAX_CHAINS];
-               int32_t sign[AR5416_MAX_CHAINS];
-       } meas2;
-       union {
-               u32 unsign[AR5416_MAX_CHAINS];
-               int32_t sign[AR5416_MAX_CHAINS];
-       } meas3;
-       u16 cal_samples;
-
-       u32 sta_id1_defaults;
-       u32 misc_mode;
-       enum {
-               AUTO_32KHZ,
-               USE_32KHZ,
-               DONT_USE_32KHZ,
-       } enable_32kHz_clock;
-
-       /* RF */
-       u32 *analogBank0Data;
-       u32 *analogBank1Data;
-       u32 *analogBank2Data;
-       u32 *analogBank3Data;
-       u32 *analogBank6Data;
-       u32 *analogBank6TPCData;
-       u32 *analogBank7Data;
-       u32 *addac5416_21;
-       u32 *bank6Temp;
-
-       int16_t txpower_indexoffset;
-       u32 beacon_interval;
-       u32 slottime;
-       u32 acktimeout;
-       u32 ctstimeout;
-       u32 globaltxtimeout;
-       u8 gbeacon_rate;
-
-       /* ANI */
-       u32 proc_phyerr;
-       bool has_hw_phycounters;
-       u32 aniperiod;
-       struct ar5416AniState *curani;
-       struct ar5416AniState ani[255];
-       int totalSizeDesired[5];
-       int coarse_high[5];
-       int coarse_low[5];
-       int firpwr[5];
-       enum ath9k_ani_cmd ani_function;
-
-       u32 intr_txqs;
-       bool intr_mitigation;
-       enum ath9k_ht_extprotspacing extprotspacing;
-       u8 txchainmask;
-       u8 rxchainmask;
-
-       u32 originalGain[22];
-       int initPDADC;
-       int PDADCdelta;
-
-       struct ar5416IniArray iniModes;
-       struct ar5416IniArray iniCommon;
-       struct ar5416IniArray iniBank0;
-       struct ar5416IniArray iniBB_RfGain;
-       struct ar5416IniArray iniBank1;
-       struct ar5416IniArray iniBank2;
-       struct ar5416IniArray iniBank3;
-       struct ar5416IniArray iniBank6;
-       struct ar5416IniArray iniBank6TPC;
-       struct ar5416IniArray iniBank7;
-       struct ar5416IniArray iniAddac;
-       struct ar5416IniArray iniPcieSerdes;
-       struct ar5416IniArray iniModesAdditional;
-       struct ar5416IniArray iniModesRxGain;
-       struct ar5416IniArray iniModesTxGain;
-};
-
-/* Attach, Detach, Reset */
-const char *ath9k_hw_probe(u16 vendorid, u16 devid);
-void ath9k_hw_detach(struct ath_hw *ah);
-struct ath_hw *ath9k_hw_attach(u16 devid, struct ath_softc *sc, int *error);
-void ath9k_hw_rfdetach(struct ath_hw *ah);
-int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
-                  bool bChannelChange);
-bool ath9k_hw_fill_cap_info(struct ath_hw *ah);
-bool ath9k_hw_getcapability(struct ath_hw *ah, enum ath9k_capability_type type,
-                           u32 capability, u32 *result);
-bool ath9k_hw_setcapability(struct ath_hw *ah, enum ath9k_capability_type type,
-                           u32 capability, u32 setting, int *status);
-
-/* Key Cache Management */
-bool ath9k_hw_keyreset(struct ath_hw *ah, u16 entry);
-bool ath9k_hw_keysetmac(struct ath_hw *ah, u16 entry, const u8 *mac);
-bool ath9k_hw_set_keycache_entry(struct ath_hw *ah, u16 entry,
-                                const struct ath9k_keyval *k,
-                                const u8 *mac);
-bool ath9k_hw_keyisvalid(struct ath_hw *ah, u16 entry);
-
-/* GPIO / RFKILL / Antennae */
-void ath9k_hw_cfg_gpio_input(struct ath_hw *ah, u32 gpio);
-u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio);
-void ath9k_hw_cfg_output(struct ath_hw *ah, u32 gpio,
-                        u32 ah_signal_type);
-void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val);
-#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
-void ath9k_enable_rfkill(struct ath_hw *ah);
-#endif
-u32 ath9k_hw_getdefantenna(struct ath_hw *ah);
-void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna);
-bool ath9k_hw_setantennaswitch(struct ath_hw *ah,
-                              enum ath9k_ant_setting settings,
-                              struct ath9k_channel *chan,
-                              u8 *tx_chainmask, u8 *rx_chainmask,
-                              u8 *antenna_cfgd);
-
-/* General Operation */
-bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout);
-u32 ath9k_hw_reverse_bits(u32 val, u32 n);
-bool ath9k_get_channel_edges(struct ath_hw *ah, u16 flags, u16 *low, u16 *high);
-u16 ath9k_hw_computetxtime(struct ath_hw *ah, struct ath_rate_table *rates,
-                          u32 frameLen, u16 rateix, bool shortPreamble);
-void ath9k_hw_get_channel_centers(struct ath_hw *ah,
-                                 struct ath9k_channel *chan,
-                                 struct chan_centers *centers);
-u32 ath9k_hw_getrxfilter(struct ath_hw *ah);
-void ath9k_hw_setrxfilter(struct ath_hw *ah, u32 bits);
-bool ath9k_hw_phy_disable(struct ath_hw *ah);
-bool ath9k_hw_disable(struct ath_hw *ah);
-bool ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit);
-void ath9k_hw_setmac(struct ath_hw *ah, const u8 *mac);
-void ath9k_hw_setopmode(struct ath_hw *ah);
-void ath9k_hw_setmcastfilter(struct ath_hw *ah, u32 filter0, u32 filter1);
-void ath9k_hw_setbssidmask(struct ath_softc *sc);
-void ath9k_hw_write_associd(struct ath_softc *sc);
-u64 ath9k_hw_gettsf64(struct ath_hw *ah);
-void ath9k_hw_settsf64(struct ath_hw *ah, u64 tsf64);
-void ath9k_hw_reset_tsf(struct ath_hw *ah);
-bool ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting);
-bool ath9k_hw_setslottime(struct ath_hw *ah, u32 us);
-void ath9k_hw_set11nmac2040(struct ath_hw *ah, enum ath9k_ht_macmode mode);
-void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period);
-void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
-                                   const struct ath9k_beacon_state *bs);
-bool ath9k_hw_setpower(struct ath_hw *ah,
-                      enum ath9k_power_mode mode);
-void ath9k_hw_configpcipowersave(struct ath_hw *ah, int restore);
-
-/* Interrupt Handling */
-bool ath9k_hw_intrpend(struct ath_hw *ah);
-bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked);
-enum ath9k_int ath9k_hw_intrget(struct ath_hw *ah);
-enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints);
-
-void ath9k_hw_btcoex_enable(struct ath_hw *ah);
-
-#endif
diff --git a/drivers/net/wireless/ath9k/initvals.h b/drivers/net/wireless/ath9k/initvals.h
deleted file mode 100644 (file)
index e2f0a34..0000000
+++ /dev/null
@@ -1,4848 +0,0 @@
-/*
- * Copyright (c) 2008-2009 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.
- */
-
-static const u32 ar5416Modes[][6] = {
-    { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
-    { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
-    { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
-    { 0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000, 0x00014008 },
-    { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 },
-    { 0x0000801c, 0x128d93a7, 0x128d93cf, 0x12e013d7, 0x12e013ab, 0x098813cf },
-    { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 },
-    { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 },
-    { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
-    { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 },
-    { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
-    { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 },
-    { 0x00009844, 0x1372161e, 0x1372161e, 0x137216a0, 0x137216a0, 0x137216a0 },
-    { 0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
-    { 0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
-    { 0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
-    { 0x00009850, 0x6c48b4e0, 0x6c48b4e0, 0x6c48b0de, 0x6c48b0de, 0x6c48b0de },
-    { 0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e },
-    { 0x0000985c, 0x31395d5e, 0x31395d5e, 0x31395d5e, 0x31395d5e, 0x31395d5e },
-    { 0x00009860, 0x00049d18, 0x00049d18, 0x00049d18, 0x00049d18, 0x00049d18 },
-    { 0x0000c864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 },
-    { 0x00009868, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190 },
-    { 0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 },
-    { 0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0 },
-    { 0x00009918, 0x000001b8, 0x00000370, 0x00000268, 0x00000134, 0x00000134 },
-    { 0x00009924, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b },
-    { 0x00009944, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020 },
-    { 0x00009960, 0x00000900, 0x00000900, 0x00012d80, 0x00012d80, 0x00012d80 },
-    { 0x0000a960, 0x00000900, 0x00000900, 0x00012d80, 0x00012d80, 0x00012d80 },
-    { 0x0000b960, 0x00000900, 0x00000900, 0x00012d80, 0x00012d80, 0x00012d80 },
-    { 0x00009964, 0x00000000, 0x00000000, 0x00001120, 0x00001120, 0x00001120 },
-    { 0x0000c9bc, 0x001a0a00, 0x001a0a00, 0x001a0a00, 0x001a0a00, 0x001a0a00 },
-    { 0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, 0x038919be },
-    { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 },
-    { 0x000099c8, 0x60f6532c, 0x60f6532c, 0x60f6532c, 0x60f6532c, 0x60f6532c },
-    { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 },
-    { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 },
-    { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x0000a204, 0x00000880, 0x00000880, 0x00000880, 0x00000880, 0x00000880 },
-    { 0x0000a208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, 0xd03e4788 },
-    { 0x0000a20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 },
-    { 0x0000b20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 },
-    { 0x0000c20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 },
-    { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a },
-    { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
-    { 0x0000a274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, 0x0a1a7caa },
-    { 0x0000a300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000 },
-    { 0x0000a304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, 0x2e032402 },
-    { 0x0000a308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, 0x4a0a3c06 },
-    { 0x0000a30c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, 0x621a540b },
-    { 0x0000a310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, 0x764f6c1b },
-    { 0x0000a314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, 0x845b7a5a },
-    { 0x0000a318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, 0x950f8ccf },
-    { 0x0000a31c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, 0xa5cf9b4f },
-    { 0x0000a320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, 0xbddfaf1f },
-    { 0x0000a324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, 0xd1ffc93f },
-    { 0x0000a328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x0000a32c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x0000a330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-};
-
-static const u32 ar5416Common[][2] = {
-    { 0x0000000c, 0x00000000 },
-    { 0x00000030, 0x00020015 },
-    { 0x00000034, 0x00000005 },
-    { 0x00000040, 0x00000000 },
-    { 0x00000044, 0x00000008 },
-    { 0x00000048, 0x00000008 },
-    { 0x0000004c, 0x00000010 },
-    { 0x00000050, 0x00000000 },
-    { 0x00000054, 0x0000001f },
-    { 0x00000800, 0x00000000 },
-    { 0x00000804, 0x00000000 },
-    { 0x00000808, 0x00000000 },
-    { 0x0000080c, 0x00000000 },
-    { 0x00000810, 0x00000000 },
-    { 0x00000814, 0x00000000 },
-    { 0x00000818, 0x00000000 },
-    { 0x0000081c, 0x00000000 },
-    { 0x00000820, 0x00000000 },
-    { 0x00000824, 0x00000000 },
-    { 0x00001040, 0x002ffc0f },
-    { 0x00001044, 0x002ffc0f },
-    { 0x00001048, 0x002ffc0f },
-    { 0x0000104c, 0x002ffc0f },
-    { 0x00001050, 0x002ffc0f },
-    { 0x00001054, 0x002ffc0f },
-    { 0x00001058, 0x002ffc0f },
-    { 0x0000105c, 0x002ffc0f },
-    { 0x00001060, 0x002ffc0f },
-    { 0x00001064, 0x002ffc0f },
-    { 0x00001230, 0x00000000 },
-    { 0x00001270, 0x00000000 },
-    { 0x00001038, 0x00000000 },
-    { 0x00001078, 0x00000000 },
-    { 0x000010b8, 0x00000000 },
-    { 0x000010f8, 0x00000000 },
-    { 0x00001138, 0x00000000 },
-    { 0x00001178, 0x00000000 },
-    { 0x000011b8, 0x00000000 },
-    { 0x000011f8, 0x00000000 },
-    { 0x00001238, 0x00000000 },
-    { 0x00001278, 0x00000000 },
-    { 0x000012b8, 0x00000000 },
-    { 0x000012f8, 0x00000000 },
-    { 0x00001338, 0x00000000 },
-    { 0x00001378, 0x00000000 },
-    { 0x000013b8, 0x00000000 },
-    { 0x000013f8, 0x00000000 },
-    { 0x00001438, 0x00000000 },
-    { 0x00001478, 0x00000000 },
-    { 0x000014b8, 0x00000000 },
-    { 0x000014f8, 0x00000000 },
-    { 0x00001538, 0x00000000 },
-    { 0x00001578, 0x00000000 },
-    { 0x000015b8, 0x00000000 },
-    { 0x000015f8, 0x00000000 },
-    { 0x00001638, 0x00000000 },
-    { 0x00001678, 0x00000000 },
-    { 0x000016b8, 0x00000000 },
-    { 0x000016f8, 0x00000000 },
-    { 0x00001738, 0x00000000 },
-    { 0x00001778, 0x00000000 },
-    { 0x000017b8, 0x00000000 },
-    { 0x000017f8, 0x00000000 },
-    { 0x0000103c, 0x00000000 },
-    { 0x0000107c, 0x00000000 },
-    { 0x000010bc, 0x00000000 },
-    { 0x000010fc, 0x00000000 },
-    { 0x0000113c, 0x00000000 },
-    { 0x0000117c, 0x00000000 },
-    { 0x000011bc, 0x00000000 },
-    { 0x000011fc, 0x00000000 },
-    { 0x0000123c, 0x00000000 },
-    { 0x0000127c, 0x00000000 },
-    { 0x000012bc, 0x00000000 },
-    { 0x000012fc, 0x00000000 },
-    { 0x0000133c, 0x00000000 },
-    { 0x0000137c, 0x00000000 },
-    { 0x000013bc, 0x00000000 },
-    { 0x000013fc, 0x00000000 },
-    { 0x0000143c, 0x00000000 },
-    { 0x0000147c, 0x00000000 },
-    { 0x00004030, 0x00000002 },
-    { 0x0000403c, 0x00000002 },
-    { 0x00007010, 0x00000000 },
-    { 0x00007038, 0x000004c2 },
-    { 0x00008004, 0x00000000 },
-    { 0x00008008, 0x00000000 },
-    { 0x0000800c, 0x00000000 },
-    { 0x00008018, 0x00000700 },
-    { 0x00008020, 0x00000000 },
-    { 0x00008038, 0x00000000 },
-    { 0x0000803c, 0x00000000 },
-    { 0x00008048, 0x40000000 },
-    { 0x00008054, 0x00000000 },
-    { 0x00008058, 0x00000000 },
-    { 0x0000805c, 0x000fc78f },
-    { 0x00008060, 0x0000000f },
-    { 0x00008064, 0x00000000 },
-    { 0x000080c0, 0x2a82301a },
-    { 0x000080c4, 0x05dc01e0 },
-    { 0x000080c8, 0x1f402710 },
-    { 0x000080cc, 0x01f40000 },
-    { 0x000080d0, 0x00001e00 },
-    { 0x000080d4, 0x00000000 },
-    { 0x000080d8, 0x00400000 },
-    { 0x000080e0, 0xffffffff },
-    { 0x000080e4, 0x0000ffff },
-    { 0x000080e8, 0x003f3f3f },
-    { 0x000080ec, 0x00000000 },
-    { 0x000080f0, 0x00000000 },
-    { 0x000080f4, 0x00000000 },
-    { 0x000080f8, 0x00000000 },
-    { 0x000080fc, 0x00020000 },
-    { 0x00008100, 0x00020000 },
-    { 0x00008104, 0x00000001 },
-    { 0x00008108, 0x00000052 },
-    { 0x0000810c, 0x00000000 },
-    { 0x00008110, 0x00000168 },
-    { 0x00008118, 0x000100aa },
-    { 0x0000811c, 0x00003210 },
-    { 0x00008120, 0x08f04800 },
-    { 0x00008124, 0x00000000 },
-    { 0x00008128, 0x00000000 },
-    { 0x0000812c, 0x00000000 },
-    { 0x00008130, 0x00000000 },
-    { 0x00008134, 0x00000000 },
-    { 0x00008138, 0x00000000 },
-    { 0x0000813c, 0x00000000 },
-    { 0x00008144, 0xffffffff },
-    { 0x00008168, 0x00000000 },
-    { 0x0000816c, 0x00000000 },
-    { 0x00008170, 0x32143320 },
-    { 0x00008174, 0xfaa4fa50 },
-    { 0x00008178, 0x00000100 },
-    { 0x0000817c, 0x00000000 },
-    { 0x000081c4, 0x00000000 },
-    { 0x000081d0, 0x00003210 },
-    { 0x000081ec, 0x00000000 },
-    { 0x000081f0, 0x00000000 },
-    { 0x000081f4, 0x00000000 },
-    { 0x000081f8, 0x00000000 },
-    { 0x000081fc, 0x00000000 },
-    { 0x00008200, 0x00000000 },
-    { 0x00008204, 0x00000000 },
-    { 0x00008208, 0x00000000 },
-    { 0x0000820c, 0x00000000 },
-    { 0x00008210, 0x00000000 },
-    { 0x00008214, 0x00000000 },
-    { 0x00008218, 0x00000000 },
-    { 0x0000821c, 0x00000000 },
-    { 0x00008220, 0x00000000 },
-    { 0x00008224, 0x00000000 },
-    { 0x00008228, 0x00000000 },
-    { 0x0000822c, 0x00000000 },
-    { 0x00008230, 0x00000000 },
-    { 0x00008234, 0x00000000 },
-    { 0x00008238, 0x00000000 },
-    { 0x0000823c, 0x00000000 },
-    { 0x00008240, 0x00100000 },
-    { 0x00008244, 0x0010f400 },
-    { 0x00008248, 0x00000100 },
-    { 0x0000824c, 0x0001e800 },
-    { 0x00008250, 0x00000000 },
-    { 0x00008254, 0x00000000 },
-    { 0x00008258, 0x00000000 },
-    { 0x0000825c, 0x400000ff },
-    { 0x00008260, 0x00080922 },
-    { 0x00008270, 0x00000000 },
-    { 0x00008274, 0x40000000 },
-    { 0x00008278, 0x003e4180 },
-    { 0x0000827c, 0x00000000 },
-    { 0x00008284, 0x0000002c },
-    { 0x00008288, 0x0000002c },
-    { 0x0000828c, 0x00000000 },
-    { 0x00008294, 0x00000000 },
-    { 0x00008298, 0x00000000 },
-    { 0x00008300, 0x00000000 },
-    { 0x00008304, 0x00000000 },
-    { 0x00008308, 0x00000000 },
-    { 0x0000830c, 0x00000000 },
-    { 0x00008310, 0x00000000 },
-    { 0x00008314, 0x00000000 },
-    { 0x00008318, 0x00000000 },
-    { 0x00008328, 0x00000000 },
-    { 0x0000832c, 0x00000007 },
-    { 0x00008330, 0x00000302 },
-    { 0x00008334, 0x00000e00 },
-    { 0x00008338, 0x00070000 },
-    { 0x0000833c, 0x00000000 },
-    { 0x00008340, 0x000107ff },
-    { 0x00009808, 0x00000000 },
-    { 0x0000980c, 0xad848e19 },
-    { 0x00009810, 0x7d14e000 },
-    { 0x00009814, 0x9c0a9f6b },
-    { 0x0000981c, 0x00000000 },
-    { 0x0000982c, 0x0000a000 },
-    { 0x00009830, 0x00000000 },
-    { 0x0000983c, 0x00200400 },
-    { 0x00009840, 0x206a002e },
-    { 0x0000984c, 0x1284233c },
-    { 0x00009854, 0x00000859 },
-    { 0x00009900, 0x00000000 },
-    { 0x00009904, 0x00000000 },
-    { 0x00009908, 0x00000000 },
-    { 0x0000990c, 0x00000000 },
-    { 0x0000991c, 0x10000fff },
-    { 0x00009920, 0x05100000 },
-    { 0x0000a920, 0x05100000 },
-    { 0x0000b920, 0x05100000 },
-    { 0x00009928, 0x00000001 },
-    { 0x0000992c, 0x00000004 },
-    { 0x00009934, 0x1e1f2022 },
-    { 0x00009938, 0x0a0b0c0d },
-    { 0x0000993c, 0x00000000 },
-    { 0x00009948, 0x9280b212 },
-    { 0x0000994c, 0x00020028 },
-    { 0x00009954, 0x5d50e188 },
-    { 0x00009958, 0x00081fff },
-    { 0x0000c95c, 0x004b6a8e },
-    { 0x0000c968, 0x000003ce },
-    { 0x00009970, 0x190fb515 },
-    { 0x00009974, 0x00000000 },
-    { 0x00009978, 0x00000001 },
-    { 0x0000997c, 0x00000000 },
-    { 0x00009980, 0x00000000 },
-    { 0x00009984, 0x00000000 },
-    { 0x00009988, 0x00000000 },
-    { 0x0000998c, 0x00000000 },
-    { 0x00009990, 0x00000000 },
-    { 0x00009994, 0x00000000 },
-    { 0x00009998, 0x00000000 },
-    { 0x0000999c, 0x00000000 },
-    { 0x000099a0, 0x00000000 },
-    { 0x000099a4, 0x00000001 },
-    { 0x000099a8, 0x001fff00 },
-    { 0x000099ac, 0x00000000 },
-    { 0x000099b0, 0x03051000 },
-    { 0x000099dc, 0x00000000 },
-    { 0x000099e0, 0x00000200 },
-    { 0x000099e4, 0xaaaaaaaa },
-    { 0x000099e8, 0x3c466478 },
-    { 0x000099ec, 0x000000aa },
-    { 0x000099fc, 0x00001042 },
-    { 0x00009b00, 0x00000000 },
-    { 0x00009b04, 0x00000001 },
-    { 0x00009b08, 0x00000002 },
-    { 0x00009b0c, 0x00000003 },
-    { 0x00009b10, 0x00000004 },
-    { 0x00009b14, 0x00000005 },
-    { 0x00009b18, 0x00000008 },
-    { 0x00009b1c, 0x00000009 },
-    { 0x00009b20, 0x0000000a },
-    { 0x00009b24, 0x0000000b },
-    { 0x00009b28, 0x0000000c },
-    { 0x00009b2c, 0x0000000d },
-    { 0x00009b30, 0x00000010 },
-    { 0x00009b34, 0x00000011 },
-    { 0x00009b38, 0x00000012 },
-    { 0x00009b3c, 0x00000013 },
-    { 0x00009b40, 0x00000014 },
-    { 0x00009b44, 0x00000015 },
-    { 0x00009b48, 0x00000018 },
-    { 0x00009b4c, 0x00000019 },
-    { 0x00009b50, 0x0000001a },
-    { 0x00009b54, 0x0000001b },
-    { 0x00009b58, 0x0000001c },
-    { 0x00009b5c, 0x0000001d },
-    { 0x00009b60, 0x00000020 },
-    { 0x00009b64, 0x00000021 },
-    { 0x00009b68, 0x00000022 },
-    { 0x00009b6c, 0x00000023 },
-    { 0x00009b70, 0x00000024 },
-    { 0x00009b74, 0x00000025 },
-    { 0x00009b78, 0x00000028 },
-    { 0x00009b7c, 0x00000029 },
-    { 0x00009b80, 0x0000002a },
-    { 0x00009b84, 0x0000002b },
-    { 0x00009b88, 0x0000002c },
-    { 0x00009b8c, 0x0000002d },
-    { 0x00009b90, 0x00000030 },
-    { 0x00009b94, 0x00000031 },
-    { 0x00009b98, 0x00000032 },
-    { 0x00009b9c, 0x00000033 },
-    { 0x00009ba0, 0x00000034 },
-    { 0x00009ba4, 0x00000035 },
-    { 0x00009ba8, 0x00000035 },
-    { 0x00009bac, 0x00000035 },
-    { 0x00009bb0, 0x00000035 },
-    { 0x00009bb4, 0x00000035 },
-    { 0x00009bb8, 0x00000035 },
-    { 0x00009bbc, 0x00000035 },
-    { 0x00009bc0, 0x00000035 },
-    { 0x00009bc4, 0x00000035 },
-    { 0x00009bc8, 0x00000035 },
-    { 0x00009bcc, 0x00000035 },
-    { 0x00009bd0, 0x00000035 },
-    { 0x00009bd4, 0x00000035 },
-    { 0x00009bd8, 0x00000035 },
-    { 0x00009bdc, 0x00000035 },
-    { 0x00009be0, 0x00000035 },
-    { 0x00009be4, 0x00000035 },
-    { 0x00009be8, 0x00000035 },
-    { 0x00009bec, 0x00000035 },
-    { 0x00009bf0, 0x00000035 },
-    { 0x00009bf4, 0x00000035 },
-    { 0x00009bf8, 0x00000010 },
-    { 0x00009bfc, 0x0000001a },
-    { 0x0000a210, 0x40806333 },
-    { 0x0000a214, 0x00106c10 },
-    { 0x0000a218, 0x009c4060 },
-    { 0x0000a220, 0x018830c6 },
-    { 0x0000a224, 0x00000400 },
-    { 0x0000a228, 0x00000bb5 },
-    { 0x0000a22c, 0x00000011 },
-    { 0x0000a234, 0x20202020 },
-    { 0x0000a238, 0x20202020 },
-    { 0x0000a23c, 0x13c889af },
-    { 0x0000a240, 0x38490a20 },
-    { 0x0000a244, 0x00007bb6 },
-    { 0x0000a248, 0x0fff3ffc },
-    { 0x0000a24c, 0x00000001 },
-    { 0x0000a250, 0x0000a000 },
-    { 0x0000a254, 0x00000000 },
-    { 0x0000a258, 0x0cc75380 },
-    { 0x0000a25c, 0x0f0f0f01 },
-    { 0x0000a260, 0xdfa91f01 },
-    { 0x0000a268, 0x00000000 },
-    { 0x0000a26c, 0x0ebae9c6 },
-    { 0x0000b26c, 0x0ebae9c6 },
-    { 0x0000c26c, 0x0ebae9c6 },
-    { 0x0000d270, 0x00820820 },
-    { 0x0000a278, 0x1ce739ce },
-    { 0x0000a27c, 0x051701ce },
-    { 0x0000a338, 0x00000000 },
-    { 0x0000a33c, 0x00000000 },
-    { 0x0000a340, 0x00000000 },
-    { 0x0000a344, 0x00000000 },
-    { 0x0000a348, 0x3fffffff },
-    { 0x0000a34c, 0x3fffffff },
-    { 0x0000a350, 0x3fffffff },
-    { 0x0000a354, 0x0003ffff },
-    { 0x0000a358, 0x79a8aa1f },
-    { 0x0000d35c, 0x07ffffef },
-    { 0x0000d360, 0x0fffffe7 },
-    { 0x0000d364, 0x17ffffe5 },
-    { 0x0000d368, 0x1fffffe4 },
-    { 0x0000d36c, 0x37ffffe3 },
-    { 0x0000d370, 0x3fffffe3 },
-    { 0x0000d374, 0x57ffffe3 },
-    { 0x0000d378, 0x5fffffe2 },
-    { 0x0000d37c, 0x7fffffe2 },
-    { 0x0000d380, 0x7f3c7bba },
-    { 0x0000d384, 0xf3307ff0 },
-    { 0x0000a388, 0x08000000 },
-    { 0x0000a38c, 0x20202020 },
-    { 0x0000a390, 0x20202020 },
-    { 0x0000a394, 0x1ce739ce },
-    { 0x0000a398, 0x000001ce },
-    { 0x0000a39c, 0x00000001 },
-    { 0x0000a3a0, 0x00000000 },
-    { 0x0000a3a4, 0x00000000 },
-    { 0x0000a3a8, 0x00000000 },
-    { 0x0000a3ac, 0x00000000 },
-    { 0x0000a3b0, 0x00000000 },
-    { 0x0000a3b4, 0x00000000 },
-    { 0x0000a3b8, 0x00000000 },
-    { 0x0000a3bc, 0x00000000 },
-    { 0x0000a3c0, 0x00000000 },
-    { 0x0000a3c4, 0x00000000 },
-    { 0x0000a3c8, 0x00000246 },
-    { 0x0000a3cc, 0x20202020 },
-    { 0x0000a3d0, 0x20202020 },
-    { 0x0000a3d4, 0x20202020 },
-    { 0x0000a3dc, 0x1ce739ce },
-    { 0x0000a3e0, 0x000001ce },
-};
-
-static const u32 ar5416Bank0[][2] = {
-    { 0x000098b0, 0x1e5795e5 },
-    { 0x000098e0, 0x02008020 },
-};
-
-static const u32 ar5416BB_RfGain[][3] = {
-    { 0x00009a00, 0x00000000, 0x00000000 },
-    { 0x00009a04, 0x00000040, 0x00000040 },
-    { 0x00009a08, 0x00000080, 0x00000080 },
-    { 0x00009a0c, 0x000001a1, 0x00000141 },
-    { 0x00009a10, 0x000001e1, 0x00000181 },
-    { 0x00009a14, 0x00000021, 0x000001c1 },
-    { 0x00009a18, 0x00000061, 0x00000001 },
-    { 0x00009a1c, 0x00000168, 0x00000041 },
-    { 0x00009a20, 0x000001a8, 0x000001a8 },
-    { 0x00009a24, 0x000001e8, 0x000001e8 },
-    { 0x00009a28, 0x00000028, 0x00000028 },
-    { 0x00009a2c, 0x00000068, 0x00000068 },
-    { 0x00009a30, 0x00000189, 0x000000a8 },
-    { 0x00009a34, 0x000001c9, 0x00000169 },
-    { 0x00009a38, 0x00000009, 0x000001a9 },
-    { 0x00009a3c, 0x00000049, 0x000001e9 },
-    { 0x00009a40, 0x00000089, 0x00000029 },
-    { 0x00009a44, 0x00000170, 0x00000069 },
-    { 0x00009a48, 0x000001b0, 0x00000190 },
-    { 0x00009a4c, 0x000001f0, 0x000001d0 },
-    { 0x00009a50, 0x00000030, 0x00000010 },
-    { 0x00009a54, 0x00000070, 0x00000050 },
-    { 0x00009a58, 0x00000191, 0x00000090 },
-    { 0x00009a5c, 0x000001d1, 0x00000151 },
-    { 0x00009a60, 0x00000011, 0x00000191 },
-    { 0x00009a64, 0x00000051, 0x000001d1 },
-    { 0x00009a68, 0x00000091, 0x00000011 },
-    { 0x00009a6c, 0x000001b8, 0x00000051 },
-    { 0x00009a70, 0x000001f8, 0x00000198 },
-    { 0x00009a74, 0x00000038, 0x000001d8 },
-    { 0x00009a78, 0x00000078, 0x00000018 },
-    { 0x00009a7c, 0x00000199, 0x00000058 },
-    { 0x00009a80, 0x000001d9, 0x00000098 },
-    { 0x00009a84, 0x00000019, 0x00000159 },
-    { 0x00009a88, 0x00000059, 0x00000199 },
-    { 0x00009a8c, 0x00000099, 0x000001d9 },
-    { 0x00009a90, 0x000000d9, 0x00000019 },
-    { 0x00009a94, 0x000000f9, 0x00000059 },
-    { 0x00009a98, 0x000000f9, 0x00000099 },
-    { 0x00009a9c, 0x000000f9, 0x000000d9 },
-    { 0x00009aa0, 0x000000f9, 0x000000f9 },
-    { 0x00009aa4, 0x000000f9, 0x000000f9 },
-    { 0x00009aa8, 0x000000f9, 0x000000f9 },
-    { 0x00009aac, 0x000000f9, 0x000000f9 },
-    { 0x00009ab0, 0x000000f9, 0x000000f9 },
-    { 0x00009ab4, 0x000000f9, 0x000000f9 },
-    { 0x00009ab8, 0x000000f9, 0x000000f9 },
-    { 0x00009abc, 0x000000f9, 0x000000f9 },
-    { 0x00009ac0, 0x000000f9, 0x000000f9 },
-    { 0x00009ac4, 0x000000f9, 0x000000f9 },
-    { 0x00009ac8, 0x000000f9, 0x000000f9 },
-    { 0x00009acc, 0x000000f9, 0x000000f9 },
-    { 0x00009ad0, 0x000000f9, 0x000000f9 },
-    { 0x00009ad4, 0x000000f9, 0x000000f9 },
-    { 0x00009ad8, 0x000000f9, 0x000000f9 },
-    { 0x00009adc, 0x000000f9, 0x000000f9 },
-    { 0x00009ae0, 0x000000f9, 0x000000f9 },
-    { 0x00009ae4, 0x000000f9, 0x000000f9 },
-    { 0x00009ae8, 0x000000f9, 0x000000f9 },
-    { 0x00009aec, 0x000000f9, 0x000000f9 },
-    { 0x00009af0, 0x000000f9, 0x000000f9 },
-    { 0x00009af4, 0x000000f9, 0x000000f9 },
-    { 0x00009af8, 0x000000f9, 0x000000f9 },
-    { 0x00009afc, 0x000000f9, 0x000000f9 },
-};
-
-static const u32 ar5416Bank1[][2] = {
-    { 0x000098b0, 0x02108421 },
-    { 0x000098ec, 0x00000008 },
-};
-
-static const u32 ar5416Bank2[][2] = {
-    { 0x000098b0, 0x0e73ff17 },
-    { 0x000098e0, 0x00000420 },
-};
-
-static const u32 ar5416Bank3[][3] = {
-    { 0x000098f0, 0x01400018, 0x01c00018 },
-};
-
-static const u32 ar5416Bank6[][3] = {
-
-    { 0x0000989c, 0x00000000, 0x00000000 },
-    { 0x0000989c, 0x00000000, 0x00000000 },
-    { 0x0000989c, 0x00000000, 0x00000000 },
-    { 0x0000989c, 0x00e00000, 0x00e00000 },
-    { 0x0000989c, 0x005e0000, 0x005e0000 },
-    { 0x0000989c, 0x00120000, 0x00120000 },
-    { 0x0000989c, 0x00620000, 0x00620000 },
-    { 0x0000989c, 0x00020000, 0x00020000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x40ff0000, 0x40ff0000 },
-    { 0x0000989c, 0x005f0000, 0x005f0000 },
-    { 0x0000989c, 0x00870000, 0x00870000 },
-    { 0x0000989c, 0x00f90000, 0x00f90000 },
-    { 0x0000989c, 0x007b0000, 0x007b0000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x00f50000, 0x00f50000 },
-    { 0x0000989c, 0x00dc0000, 0x00dc0000 },
-    { 0x0000989c, 0x00110000, 0x00110000 },
-    { 0x0000989c, 0x006100a8, 0x006100a8 },
-    { 0x0000989c, 0x004210a2, 0x004210a2 },
-    { 0x0000989c, 0x0014008f, 0x0014008f },
-    { 0x0000989c, 0x00c40003, 0x00c40003 },
-    { 0x0000989c, 0x003000f2, 0x003000f2 },
-    { 0x0000989c, 0x00440016, 0x00440016 },
-    { 0x0000989c, 0x00410040, 0x00410040 },
-    { 0x0000989c, 0x0001805e, 0x0001805e },
-    { 0x0000989c, 0x0000c0ab, 0x0000c0ab },
-    { 0x0000989c, 0x000000f1, 0x000000f1 },
-    { 0x0000989c, 0x00002081, 0x00002081 },
-    { 0x0000989c, 0x000000d4, 0x000000d4 },
-    { 0x000098d0, 0x0000000f, 0x0010000f },
-};
-
-static const u32 ar5416Bank6TPC[][3] = {
-    { 0x0000989c, 0x00000000, 0x00000000 },
-    { 0x0000989c, 0x00000000, 0x00000000 },
-    { 0x0000989c, 0x00000000, 0x00000000 },
-    { 0x0000989c, 0x00e00000, 0x00e00000 },
-    { 0x0000989c, 0x005e0000, 0x005e0000 },
-    { 0x0000989c, 0x00120000, 0x00120000 },
-    { 0x0000989c, 0x00620000, 0x00620000 },
-    { 0x0000989c, 0x00020000, 0x00020000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x40ff0000, 0x40ff0000 },
-    { 0x0000989c, 0x005f0000, 0x005f0000 },
-    { 0x0000989c, 0x00870000, 0x00870000 },
-    { 0x0000989c, 0x00f90000, 0x00f90000 },
-    { 0x0000989c, 0x007b0000, 0x007b0000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x00f50000, 0x00f50000 },
-    { 0x0000989c, 0x00dc0000, 0x00dc0000 },
-    { 0x0000989c, 0x00110000, 0x00110000 },
-    { 0x0000989c, 0x006100a8, 0x006100a8 },
-    { 0x0000989c, 0x00423022, 0x00423022 },
-    { 0x0000989c, 0x201400df, 0x201400df },
-    { 0x0000989c, 0x00c40002, 0x00c40002 },
-    { 0x0000989c, 0x003000f2, 0x003000f2 },
-    { 0x0000989c, 0x00440016, 0x00440016 },
-    { 0x0000989c, 0x00410040, 0x00410040 },
-    { 0x0000989c, 0x0001805e, 0x0001805e },
-    { 0x0000989c, 0x0000c0ab, 0x0000c0ab },
-    { 0x0000989c, 0x000000e1, 0x000000e1 },
-    { 0x0000989c, 0x00007081, 0x00007081 },
-    { 0x0000989c, 0x000000d4, 0x000000d4 },
-    { 0x000098d0, 0x0000000f, 0x0010000f },
-};
-
-static const u32 ar5416Bank7[][2] = {
-    { 0x0000989c, 0x00000500 },
-    { 0x0000989c, 0x00000800 },
-    { 0x000098cc, 0x0000000e },
-};
-
-static const u32 ar5416Addac[][2] = {
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000003 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x0000000c },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000030 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000060 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000058 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x000098cc,  0x00000000 },
-};
-
-static const u32 ar5416Modes_9100[][6] = {
-    { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
-    { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
-    { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
-    { 0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000, 0x00014008 },
-    { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 },
-    { 0x0000801c, 0x128d93a7, 0x128d93cf, 0x12e013d7, 0x12e013ab, 0x098813cf },
-    { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 },
-    { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 },
-    { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
-    { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 },
-    { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
-    { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 },
-    { 0x00009844, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0, 0x037216a0 },
-    { 0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
-    { 0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
-    { 0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
-    { 0x00009850, 0x6d48b4e2, 0x6d48b4e2, 0x6d48b0e2, 0x6d48b0e2, 0x6d48b0e2 },
-    { 0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec86d2e, 0x7ec84d2e, 0x7ec82d2e },
-    { 0x0000985c, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e },
-    { 0x00009860, 0x00048d18, 0x00048d18, 0x00048d20, 0x00048d20, 0x00048d18 },
-    { 0x0000c864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 },
-    { 0x00009868, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0 },
-    { 0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 },
-    { 0x00009914, 0x000007d0, 0x000007d0, 0x00000898, 0x00000898, 0x000007d0 },
-    { 0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016 },
-    { 0x00009924, 0xd00a8a07, 0xd00a8a07, 0xd00a8a11, 0xd00a8a0d, 0xd00a8a0d },
-    { 0x00009940, 0x00754604, 0x00754604, 0xfff81204, 0xfff81204, 0xfff81204 },
-    { 0x00009944, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020 },
-    { 0x00009954, 0x5f3ca3de, 0x5f3ca3de, 0xe250a51e, 0xe250a51e, 0xe250a51e },
-    { 0x00009958, 0x2108ecff, 0x2108ecff, 0x3388ffff, 0x3388ffff, 0x3388ffff },
-#ifdef TB243
-    { 0x00009960, 0x00000900, 0x00000900, 0x00009b40, 0x00009b40, 0x00012d80 },
-    { 0x0000a960, 0x00000900, 0x00000900, 0x00009b40, 0x00009b40, 0x00012d80 },
-    { 0x0000b960, 0x00000900, 0x00000900, 0x00009b40, 0x00009b40, 0x00012d80 },
-    { 0x00009964, 0x00000000, 0x00000000, 0x00002210, 0x00002210, 0x00001120 },
-#else
-    { 0x00009960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0 },
-    { 0x0000a960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0 },
-    { 0x0000b960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0 },
-    { 0x00009964, 0x00001120, 0x00001120, 0x00001120, 0x00001120, 0x00001120 },
-#endif
-    { 0x0000c9bc, 0x001a0600, 0x001a0600, 0x001a1000, 0x001a0c00, 0x001a0c00 },
-    { 0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, 0x038919be },
-    { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 },
-    { 0x000099c8, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329 },
-    { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 },
-    { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 },
-    { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x0000a204, 0x00000880, 0x00000880, 0x00000880, 0x00000880, 0x00000880 },
-    { 0x0000a208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, 0xd03e4788 },
-    { 0x0000a20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 },
-    { 0x0000b20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 },
-    { 0x0000c20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 },
-    { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a },
-    { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
-    { 0x0000a274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, 0x0a1a7caa },
-    { 0x0000a300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000 },
-    { 0x0000a304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, 0x2e032402 },
-    { 0x0000a308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, 0x4a0a3c06 },
-    { 0x0000a30c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, 0x621a540b },
-    { 0x0000a310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, 0x764f6c1b },
-    { 0x0000a314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, 0x845b7a5a },
-    { 0x0000a318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, 0x950f8ccf },
-    { 0x0000a31c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, 0xa5cf9b4f },
-    { 0x0000a320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, 0xbddfaf1f },
-    { 0x0000a324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, 0xd1ffc93f },
-    { 0x0000a328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x0000a32c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x0000a330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-};
-
-static const u32 ar5416Common_9100[][2] = {
-    { 0x0000000c, 0x00000000 },
-    { 0x00000030, 0x00020015 },
-    { 0x00000034, 0x00000005 },
-    { 0x00000040, 0x00000000 },
-    { 0x00000044, 0x00000008 },
-    { 0x00000048, 0x00000008 },
-    { 0x0000004c, 0x00000010 },
-    { 0x00000050, 0x00000000 },
-    { 0x00000054, 0x0000001f },
-    { 0x00000800, 0x00000000 },
-    { 0x00000804, 0x00000000 },
-    { 0x00000808, 0x00000000 },
-    { 0x0000080c, 0x00000000 },
-    { 0x00000810, 0x00000000 },
-    { 0x00000814, 0x00000000 },
-    { 0x00000818, 0x00000000 },
-    { 0x0000081c, 0x00000000 },
-    { 0x00000820, 0x00000000 },
-    { 0x00000824, 0x00000000 },
-    { 0x00001040, 0x002ffc0f },
-    { 0x00001044, 0x002ffc0f },
-    { 0x00001048, 0x002ffc0f },
-    { 0x0000104c, 0x002ffc0f },
-    { 0x00001050, 0x002ffc0f },
-    { 0x00001054, 0x002ffc0f },
-    { 0x00001058, 0x002ffc0f },
-    { 0x0000105c, 0x002ffc0f },
-    { 0x00001060, 0x002ffc0f },
-    { 0x00001064, 0x002ffc0f },
-    { 0x00001230, 0x00000000 },
-    { 0x00001270, 0x00000000 },
-    { 0x00001038, 0x00000000 },
-    { 0x00001078, 0x00000000 },
-    { 0x000010b8, 0x00000000 },
-    { 0x000010f8, 0x00000000 },
-    { 0x00001138, 0x00000000 },
-    { 0x00001178, 0x00000000 },
-    { 0x000011b8, 0x00000000 },
-    { 0x000011f8, 0x00000000 },
-    { 0x00001238, 0x00000000 },
-    { 0x00001278, 0x00000000 },
-    { 0x000012b8, 0x00000000 },
-    { 0x000012f8, 0x00000000 },
-    { 0x00001338, 0x00000000 },
-    { 0x00001378, 0x00000000 },
-    { 0x000013b8, 0x00000000 },
-    { 0x000013f8, 0x00000000 },
-    { 0x00001438, 0x00000000 },
-    { 0x00001478, 0x00000000 },
-    { 0x000014b8, 0x00000000 },
-    { 0x000014f8, 0x00000000 },
-    { 0x00001538, 0x00000000 },
-    { 0x00001578, 0x00000000 },
-    { 0x000015b8, 0x00000000 },
-    { 0x000015f8, 0x00000000 },
-    { 0x00001638, 0x00000000 },
-    { 0x00001678, 0x00000000 },
-    { 0x000016b8, 0x00000000 },
-    { 0x000016f8, 0x00000000 },
-    { 0x00001738, 0x00000000 },
-    { 0x00001778, 0x00000000 },
-    { 0x000017b8, 0x00000000 },
-    { 0x000017f8, 0x00000000 },
-    { 0x0000103c, 0x00000000 },
-    { 0x0000107c, 0x00000000 },
-    { 0x000010bc, 0x00000000 },
-    { 0x000010fc, 0x00000000 },
-    { 0x0000113c, 0x00000000 },
-    { 0x0000117c, 0x00000000 },
-    { 0x000011bc, 0x00000000 },
-    { 0x000011fc, 0x00000000 },
-    { 0x0000123c, 0x00000000 },
-    { 0x0000127c, 0x00000000 },
-    { 0x000012bc, 0x00000000 },
-    { 0x000012fc, 0x00000000 },
-    { 0x0000133c, 0x00000000 },
-    { 0x0000137c, 0x00000000 },
-    { 0x000013bc, 0x00000000 },
-    { 0x000013fc, 0x00000000 },
-    { 0x0000143c, 0x00000000 },
-    { 0x0000147c, 0x00000000 },
-    { 0x00020010, 0x00000003 },
-    { 0x00020038, 0x000004c2 },
-    { 0x00008004, 0x00000000 },
-    { 0x00008008, 0x00000000 },
-    { 0x0000800c, 0x00000000 },
-    { 0x00008018, 0x00000700 },
-    { 0x00008020, 0x00000000 },
-    { 0x00008038, 0x00000000 },
-    { 0x0000803c, 0x00000000 },
-    { 0x00008048, 0x40000000 },
-    { 0x00008054, 0x00004000 },
-    { 0x00008058, 0x00000000 },
-    { 0x0000805c, 0x000fc78f },
-    { 0x00008060, 0x0000000f },
-    { 0x00008064, 0x00000000 },
-    { 0x000080c0, 0x2a82301a },
-    { 0x000080c4, 0x05dc01e0 },
-    { 0x000080c8, 0x1f402710 },
-    { 0x000080cc, 0x01f40000 },
-    { 0x000080d0, 0x00001e00 },
-    { 0x000080d4, 0x00000000 },
-    { 0x000080d8, 0x00400000 },
-    { 0x000080e0, 0xffffffff },
-    { 0x000080e4, 0x0000ffff },
-    { 0x000080e8, 0x003f3f3f },
-    { 0x000080ec, 0x00000000 },
-    { 0x000080f0, 0x00000000 },
-    { 0x000080f4, 0x00000000 },
-    { 0x000080f8, 0x00000000 },
-    { 0x000080fc, 0x00020000 },
-    { 0x00008100, 0x00020000 },
-    { 0x00008104, 0x00000001 },
-    { 0x00008108, 0x00000052 },
-    { 0x0000810c, 0x00000000 },
-    { 0x00008110, 0x00000168 },
-    { 0x00008118, 0x000100aa },
-    { 0x0000811c, 0x00003210 },
-    { 0x00008120, 0x08f04800 },
-    { 0x00008124, 0x00000000 },
-    { 0x00008128, 0x00000000 },
-    { 0x0000812c, 0x00000000 },
-    { 0x00008130, 0x00000000 },
-    { 0x00008134, 0x00000000 },
-    { 0x00008138, 0x00000000 },
-    { 0x0000813c, 0x00000000 },
-    { 0x00008144, 0x00000000 },
-    { 0x00008168, 0x00000000 },
-    { 0x0000816c, 0x00000000 },
-    { 0x00008170, 0x32143320 },
-    { 0x00008174, 0xfaa4fa50 },
-    { 0x00008178, 0x00000100 },
-    { 0x0000817c, 0x00000000 },
-    { 0x000081c4, 0x00000000 },
-    { 0x000081d0, 0x00003210 },
-    { 0x000081ec, 0x00000000 },
-    { 0x000081f0, 0x00000000 },
-    { 0x000081f4, 0x00000000 },
-    { 0x000081f8, 0x00000000 },
-    { 0x000081fc, 0x00000000 },
-    { 0x00008200, 0x00000000 },
-    { 0x00008204, 0x00000000 },
-    { 0x00008208, 0x00000000 },
-    { 0x0000820c, 0x00000000 },
-    { 0x00008210, 0x00000000 },
-    { 0x00008214, 0x00000000 },
-    { 0x00008218, 0x00000000 },
-    { 0x0000821c, 0x00000000 },
-    { 0x00008220, 0x00000000 },
-    { 0x00008224, 0x00000000 },
-    { 0x00008228, 0x00000000 },
-    { 0x0000822c, 0x00000000 },
-    { 0x00008230, 0x00000000 },
-    { 0x00008234, 0x00000000 },
-    { 0x00008238, 0x00000000 },
-    { 0x0000823c, 0x00000000 },
-    { 0x00008240, 0x00100000 },
-    { 0x00008244, 0x0010f400 },
-    { 0x00008248, 0x00000100 },
-    { 0x0000824c, 0x0001e800 },
-    { 0x00008250, 0x00000000 },
-    { 0x00008254, 0x00000000 },
-    { 0x00008258, 0x00000000 },
-    { 0x0000825c, 0x400000ff },
-    { 0x00008260, 0x00080922 },
-    { 0x00008270, 0x00000000 },
-    { 0x00008274, 0x40000000 },
-    { 0x00008278, 0x003e4180 },
-    { 0x0000827c, 0x00000000 },
-    { 0x00008284, 0x0000002c },
-    { 0x00008288, 0x0000002c },
-    { 0x0000828c, 0x00000000 },
-    { 0x00008294, 0x00000000 },
-    { 0x00008298, 0x00000000 },
-    { 0x00008300, 0x00000000 },
-    { 0x00008304, 0x00000000 },
-    { 0x00008308, 0x00000000 },
-    { 0x0000830c, 0x00000000 },
-    { 0x00008310, 0x00000000 },
-    { 0x00008314, 0x00000000 },
-    { 0x00008318, 0x00000000 },
-    { 0x00008328, 0x00000000 },
-    { 0x0000832c, 0x00000007 },
-    { 0x00008330, 0x00000302 },
-    { 0x00008334, 0x00000e00 },
-    { 0x00008338, 0x00000000 },
-    { 0x0000833c, 0x00000000 },
-    { 0x00008340, 0x000107ff },
-    { 0x00009808, 0x00000000 },
-    { 0x0000980c, 0xad848e19 },
-    { 0x00009810, 0x7d14e000 },
-    { 0x00009814, 0x9c0a9f6b },
-    { 0x0000981c, 0x00000000 },
-    { 0x0000982c, 0x0000a000 },
-    { 0x00009830, 0x00000000 },
-    { 0x0000983c, 0x00200400 },
-    { 0x00009840, 0x206a01ae },
-    { 0x0000984c, 0x1284233c },
-    { 0x00009854, 0x00000859 },
-    { 0x00009900, 0x00000000 },
-    { 0x00009904, 0x00000000 },
-    { 0x00009908, 0x00000000 },
-    { 0x0000990c, 0x00000000 },
-    { 0x0000991c, 0x10000fff },
-    { 0x00009920, 0x05100000 },
-    { 0x0000a920, 0x05100000 },
-    { 0x0000b920, 0x05100000 },
-    { 0x00009928, 0x00000001 },
-    { 0x0000992c, 0x00000004 },
-    { 0x00009934, 0x1e1f2022 },
-    { 0x00009938, 0x0a0b0c0d },
-    { 0x0000993c, 0x00000000 },
-    { 0x00009948, 0x9280b212 },
-    { 0x0000994c, 0x00020028 },
-    { 0x0000c95c, 0x004b6a8e },
-    { 0x0000c968, 0x000003ce },
-    { 0x00009970, 0x190fb515 },
-    { 0x00009974, 0x00000000 },
-    { 0x00009978, 0x00000001 },
-    { 0x0000997c, 0x00000000 },
-    { 0x00009980, 0x00000000 },
-    { 0x00009984, 0x00000000 },
-    { 0x00009988, 0x00000000 },
-    { 0x0000998c, 0x00000000 },
-    { 0x00009990, 0x00000000 },
-    { 0x00009994, 0x00000000 },
-    { 0x00009998, 0x00000000 },
-    { 0x0000999c, 0x00000000 },
-    { 0x000099a0, 0x00000000 },
-    { 0x000099a4, 0x00000001 },
-    { 0x000099a8, 0x201fff00 },
-    { 0x000099ac, 0x006f0000 },
-    { 0x000099b0, 0x03051000 },
-    { 0x000099dc, 0x00000000 },
-    { 0x000099e0, 0x00000200 },
-    { 0x000099e4, 0xaaaaaaaa },
-    { 0x000099e8, 0x3c466478 },
-    { 0x000099ec, 0x0cc80caa },
-    { 0x000099fc, 0x00001042 },
-    { 0x00009b00, 0x00000000 },
-    { 0x00009b04, 0x00000001 },
-    { 0x00009b08, 0x00000002 },
-    { 0x00009b0c, 0x00000003 },
-    { 0x00009b10, 0x00000004 },
-    { 0x00009b14, 0x00000005 },
-    { 0x00009b18, 0x00000008 },
-    { 0x00009b1c, 0x00000009 },
-    { 0x00009b20, 0x0000000a },
-    { 0x00009b24, 0x0000000b },
-    { 0x00009b28, 0x0000000c },
-    { 0x00009b2c, 0x0000000d },
-    { 0x00009b30, 0x00000010 },
-    { 0x00009b34, 0x00000011 },
-    { 0x00009b38, 0x00000012 },
-    { 0x00009b3c, 0x00000013 },
-    { 0x00009b40, 0x00000014 },
-    { 0x00009b44, 0x00000015 },
-    { 0x00009b48, 0x00000018 },
-    { 0x00009b4c, 0x00000019 },
-    { 0x00009b50, 0x0000001a },
-    { 0x00009b54, 0x0000001b },
-    { 0x00009b58, 0x0000001c },
-    { 0x00009b5c, 0x0000001d },
-    { 0x00009b60, 0x00000020 },
-    { 0x00009b64, 0x00000021 },
-    { 0x00009b68, 0x00000022 },
-    { 0x00009b6c, 0x00000023 },
-    { 0x00009b70, 0x00000024 },
-    { 0x00009b74, 0x00000025 },
-    { 0x00009b78, 0x00000028 },
-    { 0x00009b7c, 0x00000029 },
-    { 0x00009b80, 0x0000002a },
-    { 0x00009b84, 0x0000002b },
-    { 0x00009b88, 0x0000002c },
-    { 0x00009b8c, 0x0000002d },
-    { 0x00009b90, 0x00000030 },
-    { 0x00009b94, 0x00000031 },
-    { 0x00009b98, 0x00000032 },
-    { 0x00009b9c, 0x00000033 },
-    { 0x00009ba0, 0x00000034 },
-    { 0x00009ba4, 0x00000035 },
-    { 0x00009ba8, 0x00000035 },
-    { 0x00009bac, 0x00000035 },
-    { 0x00009bb0, 0x00000035 },
-    { 0x00009bb4, 0x00000035 },
-    { 0x00009bb8, 0x00000035 },
-    { 0x00009bbc, 0x00000035 },
-    { 0x00009bc0, 0x00000035 },
-    { 0x00009bc4, 0x00000035 },
-    { 0x00009bc8, 0x00000035 },
-    { 0x00009bcc, 0x00000035 },
-    { 0x00009bd0, 0x00000035 },
-    { 0x00009bd4, 0x00000035 },
-    { 0x00009bd8, 0x00000035 },
-    { 0x00009bdc, 0x00000035 },
-    { 0x00009be0, 0x00000035 },
-    { 0x00009be4, 0x00000035 },
-    { 0x00009be8, 0x00000035 },
-    { 0x00009bec, 0x00000035 },
-    { 0x00009bf0, 0x00000035 },
-    { 0x00009bf4, 0x00000035 },
-    { 0x00009bf8, 0x00000010 },
-    { 0x00009bfc, 0x0000001a },
-    { 0x0000a210, 0x40806333 },
-    { 0x0000a214, 0x00106c10 },
-    { 0x0000a218, 0x009c4060 },
-    { 0x0000a220, 0x018830c6 },
-    { 0x0000a224, 0x00000400 },
-    { 0x0000a228, 0x001a0bb5 },
-    { 0x0000a22c, 0x00000000 },
-    { 0x0000a234, 0x20202020 },
-    { 0x0000a238, 0x20202020 },
-    { 0x0000a23c, 0x13c889ae },
-    { 0x0000a240, 0x38490a20 },
-    { 0x0000a244, 0x00007bb6 },
-    { 0x0000a248, 0x0fff3ffc },
-    { 0x0000a24c, 0x00000001 },
-    { 0x0000a250, 0x0000a000 },
-    { 0x0000a254, 0x00000000 },
-    { 0x0000a258, 0x0cc75380 },
-    { 0x0000a25c, 0x0f0f0f01 },
-    { 0x0000a260, 0xdfa91f01 },
-    { 0x0000a268, 0x00000001 },
-    { 0x0000a26c, 0x0ebae9c6 },
-    { 0x0000b26c, 0x0ebae9c6 },
-    { 0x0000c26c, 0x0ebae9c6 },
-    { 0x0000d270, 0x00820820 },
-    { 0x0000a278, 0x1ce739ce },
-    { 0x0000a27c, 0x050701ce },
-    { 0x0000a338, 0x00000000 },
-    { 0x0000a33c, 0x00000000 },
-    { 0x0000a340, 0x00000000 },
-    { 0x0000a344, 0x00000000 },
-    { 0x0000a348, 0x3fffffff },
-    { 0x0000a34c, 0x3fffffff },
-    { 0x0000a350, 0x3fffffff },
-    { 0x0000a354, 0x0003ffff },
-    { 0x0000a358, 0x79a8aa33 },
-    { 0x0000d35c, 0x07ffffef },
-    { 0x0000d360, 0x0fffffe7 },
-    { 0x0000d364, 0x17ffffe5 },
-    { 0x0000d368, 0x1fffffe4 },
-    { 0x0000d36c, 0x37ffffe3 },
-    { 0x0000d370, 0x3fffffe3 },
-    { 0x0000d374, 0x57ffffe3 },
-    { 0x0000d378, 0x5fffffe2 },
-    { 0x0000d37c, 0x7fffffe2 },
-    { 0x0000d380, 0x7f3c7bba },
-    { 0x0000d384, 0xf3307ff0 },
-    { 0x0000a388, 0x0c000000 },
-    { 0x0000a38c, 0x20202020 },
-    { 0x0000a390, 0x20202020 },
-    { 0x0000a394, 0x1ce739ce },
-    { 0x0000a398, 0x000001ce },
-    { 0x0000a39c, 0x00000001 },
-    { 0x0000a3a0, 0x00000000 },
-    { 0x0000a3a4, 0x00000000 },
-    { 0x0000a3a8, 0x00000000 },
-    { 0x0000a3ac, 0x00000000 },
-    { 0x0000a3b0, 0x00000000 },
-    { 0x0000a3b4, 0x00000000 },
-    { 0x0000a3b8, 0x00000000 },
-    { 0x0000a3bc, 0x00000000 },
-    { 0x0000a3c0, 0x00000000 },
-    { 0x0000a3c4, 0x00000000 },
-    { 0x0000a3c8, 0x00000246 },
-    { 0x0000a3cc, 0x20202020 },
-    { 0x0000a3d0, 0x20202020 },
-    { 0x0000a3d4, 0x20202020 },
-    { 0x0000a3dc, 0x1ce739ce },
-    { 0x0000a3e0, 0x000001ce },
-};
-
-static const u32 ar5416Bank0_9100[][2] = {
-    { 0x000098b0, 0x1e5795e5 },
-    { 0x000098e0, 0x02008020 },
-};
-
-static const u32 ar5416BB_RfGain_9100[][3] = {
-    { 0x00009a00, 0x00000000, 0x00000000 },
-    { 0x00009a04, 0x00000040, 0x00000040 },
-    { 0x00009a08, 0x00000080, 0x00000080 },
-    { 0x00009a0c, 0x000001a1, 0x00000141 },
-    { 0x00009a10, 0x000001e1, 0x00000181 },
-    { 0x00009a14, 0x00000021, 0x000001c1 },
-    { 0x00009a18, 0x00000061, 0x00000001 },
-    { 0x00009a1c, 0x00000168, 0x00000041 },
-    { 0x00009a20, 0x000001a8, 0x000001a8 },
-    { 0x00009a24, 0x000001e8, 0x000001e8 },
-    { 0x00009a28, 0x00000028, 0x00000028 },
-    { 0x00009a2c, 0x00000068, 0x00000068 },
-    { 0x00009a30, 0x00000189, 0x000000a8 },
-    { 0x00009a34, 0x000001c9, 0x00000169 },
-    { 0x00009a38, 0x00000009, 0x000001a9 },
-    { 0x00009a3c, 0x00000049, 0x000001e9 },
-    { 0x00009a40, 0x00000089, 0x00000029 },
-    { 0x00009a44, 0x00000170, 0x00000069 },
-    { 0x00009a48, 0x000001b0, 0x00000190 },
-    { 0x00009a4c, 0x000001f0, 0x000001d0 },
-    { 0x00009a50, 0x00000030, 0x00000010 },
-    { 0x00009a54, 0x00000070, 0x00000050 },
-    { 0x00009a58, 0x00000191, 0x00000090 },
-    { 0x00009a5c, 0x000001d1, 0x00000151 },
-    { 0x00009a60, 0x00000011, 0x00000191 },
-    { 0x00009a64, 0x00000051, 0x000001d1 },
-    { 0x00009a68, 0x00000091, 0x00000011 },
-    { 0x00009a6c, 0x000001b8, 0x00000051 },
-    { 0x00009a70, 0x000001f8, 0x00000198 },
-    { 0x00009a74, 0x00000038, 0x000001d8 },
-    { 0x00009a78, 0x00000078, 0x00000018 },
-    { 0x00009a7c, 0x00000199, 0x00000058 },
-    { 0x00009a80, 0x000001d9, 0x00000098 },
-    { 0x00009a84, 0x00000019, 0x00000159 },
-    { 0x00009a88, 0x00000059, 0x00000199 },
-    { 0x00009a8c, 0x00000099, 0x000001d9 },
-    { 0x00009a90, 0x000000d9, 0x00000019 },
-    { 0x00009a94, 0x000000f9, 0x00000059 },
-    { 0x00009a98, 0x000000f9, 0x00000099 },
-    { 0x00009a9c, 0x000000f9, 0x000000d9 },
-    { 0x00009aa0, 0x000000f9, 0x000000f9 },
-    { 0x00009aa4, 0x000000f9, 0x000000f9 },
-    { 0x00009aa8, 0x000000f9, 0x000000f9 },
-    { 0x00009aac, 0x000000f9, 0x000000f9 },
-    { 0x00009ab0, 0x000000f9, 0x000000f9 },
-    { 0x00009ab4, 0x000000f9, 0x000000f9 },
-    { 0x00009ab8, 0x000000f9, 0x000000f9 },
-    { 0x00009abc, 0x000000f9, 0x000000f9 },
-    { 0x00009ac0, 0x000000f9, 0x000000f9 },
-    { 0x00009ac4, 0x000000f9, 0x000000f9 },
-    { 0x00009ac8, 0x000000f9, 0x000000f9 },
-    { 0x00009acc, 0x000000f9, 0x000000f9 },
-    { 0x00009ad0, 0x000000f9, 0x000000f9 },
-    { 0x00009ad4, 0x000000f9, 0x000000f9 },
-    { 0x00009ad8, 0x000000f9, 0x000000f9 },
-    { 0x00009adc, 0x000000f9, 0x000000f9 },
-    { 0x00009ae0, 0x000000f9, 0x000000f9 },
-    { 0x00009ae4, 0x000000f9, 0x000000f9 },
-    { 0x00009ae8, 0x000000f9, 0x000000f9 },
-    { 0x00009aec, 0x000000f9, 0x000000f9 },
-    { 0x00009af0, 0x000000f9, 0x000000f9 },
-    { 0x00009af4, 0x000000f9, 0x000000f9 },
-    { 0x00009af8, 0x000000f9, 0x000000f9 },
-    { 0x00009afc, 0x000000f9, 0x000000f9 },
-};
-
-static const u32 ar5416Bank1_9100[][2] = {
-    { 0x000098b0, 0x02108421},
-    { 0x000098ec, 0x00000008},
-};
-
-static const u32 ar5416Bank2_9100[][2] = {
-    { 0x000098b0, 0x0e73ff17},
-    { 0x000098e0, 0x00000420},
-};
-
-static const u32 ar5416Bank3_9100[][3] = {
-    { 0x000098f0, 0x01400018, 0x01c00018 },
-};
-
-static const u32 ar5416Bank6_9100[][3] = {
-
-    { 0x0000989c, 0x00000000, 0x00000000 },
-    { 0x0000989c, 0x00000000, 0x00000000 },
-    { 0x0000989c, 0x00000000, 0x00000000 },
-    { 0x0000989c, 0x00e00000, 0x00e00000 },
-    { 0x0000989c, 0x005e0000, 0x005e0000 },
-    { 0x0000989c, 0x00120000, 0x00120000 },
-    { 0x0000989c, 0x00620000, 0x00620000 },
-    { 0x0000989c, 0x00020000, 0x00020000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x005f0000, 0x005f0000 },
-    { 0x0000989c, 0x00870000, 0x00870000 },
-    { 0x0000989c, 0x00f90000, 0x00f90000 },
-    { 0x0000989c, 0x007b0000, 0x007b0000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x00f50000, 0x00f50000 },
-    { 0x0000989c, 0x00dc0000, 0x00dc0000 },
-    { 0x0000989c, 0x00110000, 0x00110000 },
-    { 0x0000989c, 0x006100a8, 0x006100a8 },
-    { 0x0000989c, 0x004210a2, 0x004210a2 },
-    { 0x0000989c, 0x0014000f, 0x0014000f },
-    { 0x0000989c, 0x00c40002, 0x00c40002 },
-    { 0x0000989c, 0x003000f2, 0x003000f2 },
-    { 0x0000989c, 0x00440016, 0x00440016 },
-    { 0x0000989c, 0x00410040, 0x00410040 },
-    { 0x0000989c, 0x000180d6, 0x000180d6 },
-    { 0x0000989c, 0x0000c0aa, 0x0000c0aa },
-    { 0x0000989c, 0x000000b1, 0x000000b1 },
-    { 0x0000989c, 0x00002000, 0x00002000 },
-    { 0x0000989c, 0x000000d4, 0x000000d4 },
-    { 0x000098d0, 0x0000000f, 0x0010000f },
-};
-
-
-static const u32 ar5416Bank6TPC_9100[][3] = {
-
-    { 0x0000989c, 0x00000000, 0x00000000 },
-    { 0x0000989c, 0x00000000, 0x00000000 },
-    { 0x0000989c, 0x00000000, 0x00000000 },
-    { 0x0000989c, 0x00e00000, 0x00e00000 },
-    { 0x0000989c, 0x005e0000, 0x005e0000 },
-    { 0x0000989c, 0x00120000, 0x00120000 },
-    { 0x0000989c, 0x00620000, 0x00620000 },
-    { 0x0000989c, 0x00020000, 0x00020000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x40ff0000, 0x40ff0000 },
-    { 0x0000989c, 0x005f0000, 0x005f0000 },
-    { 0x0000989c, 0x00870000, 0x00870000 },
-    { 0x0000989c, 0x00f90000, 0x00f90000 },
-    { 0x0000989c, 0x007b0000, 0x007b0000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x00f50000, 0x00f50000 },
-    { 0x0000989c, 0x00dc0000, 0x00dc0000 },
-    { 0x0000989c, 0x00110000, 0x00110000 },
-    { 0x0000989c, 0x006100a8, 0x006100a8 },
-    { 0x0000989c, 0x00423022, 0x00423022 },
-    { 0x0000989c, 0x2014008f, 0x2014008f },
-    { 0x0000989c, 0x00c40002, 0x00c40002 },
-    { 0x0000989c, 0x003000f2, 0x003000f2 },
-    { 0x0000989c, 0x00440016, 0x00440016 },
-    { 0x0000989c, 0x00410040, 0x00410040 },
-    { 0x0000989c, 0x0001805e, 0x0001805e },
-    { 0x0000989c, 0x0000c0ab, 0x0000c0ab },
-    { 0x0000989c, 0x000000e1, 0x000000e1 },
-    { 0x0000989c, 0x00007080, 0x00007080 },
-    { 0x0000989c, 0x000000d4, 0x000000d4 },
-    { 0x000098d0, 0x0000000f, 0x0010000f },
-};
-
-static const u32 ar5416Bank7_9100[][2] = {
-    { 0x0000989c, 0x00000500 },
-    { 0x0000989c, 0x00000800 },
-    { 0x000098cc, 0x0000000e },
-};
-
-static const u32 ar5416Addac_9100[][2] = {
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000010 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x000000c0 },
-    {0x0000989c, 0x00000015 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x0000989c, 0x00000000 },
-    {0x000098cc, 0x00000000 },
-};
-
-static const u32 ar5416Modes_9160[][6] = {
-    { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
-    { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
-    { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
-    { 0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000, 0x00014008 },
-    { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 },
-    { 0x0000801c, 0x128d93a7, 0x128d93cf, 0x12e013d7, 0x12e013ab, 0x098813cf },
-    { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 },
-    { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 },
-    { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
-    { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 },
-    { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
-    { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 },
-    { 0x00009844, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0, 0x037216a0 },
-    { 0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
-    { 0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
-    { 0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
-    { 0x00009850, 0x6c48b4e2, 0x6c48b4e2, 0x6c48b0e2, 0x6c48b0e2, 0x6c48b0e2 },
-    { 0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e },
-    { 0x0000985c, 0x31395d5e, 0x31395d5e, 0x31395d5e, 0x31395d5e, 0x31395d5e },
-    { 0x00009860, 0x00048d18, 0x00048d18, 0x00048d20, 0x00048d20, 0x00048d18 },
-    { 0x0000c864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 },
-    { 0x00009868, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0 },
-    { 0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 },
-    { 0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0 },
-    { 0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016 },
-    { 0x00009924, 0xd00a8a07, 0xd00a8a07, 0xd00a8a0d, 0xd00a8a0d, 0xd00a8a0d },
-    { 0x00009944, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020 },
-    { 0x00009960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40 },
-    { 0x0000a960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40 },
-    { 0x0000b960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40 },
-    { 0x00009964, 0x00001120, 0x00001120, 0x00001120, 0x00001120, 0x00001120 },
-    { 0x0000c968, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce, 0x000003ce },
-    { 0x0000c9bc, 0x001a0600, 0x001a0600, 0x001a0c00, 0x001a0c00, 0x001a0c00 },
-    { 0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, 0x038919be },
-    { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 },
-    { 0x000099c8, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329 },
-    { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 },
-    { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 },
-    { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x0000a204, 0x00000880, 0x00000880, 0x00000880, 0x00000880, 0x00000880 },
-    { 0x0000a208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, 0xd03e4788 },
-    { 0x0000a20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 },
-    { 0x0000b20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 },
-    { 0x0000c20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 },
-    { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a },
-    { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
-    { 0x0000a274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, 0x0a1a7caa },
-    { 0x0000a300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000 },
-    { 0x0000a304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, 0x2e032402 },
-    { 0x0000a308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, 0x4a0a3c06 },
-    { 0x0000a30c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, 0x621a540b },
-    { 0x0000a310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, 0x764f6c1b },
-    { 0x0000a314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, 0x845b7a5a },
-    { 0x0000a318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, 0x950f8ccf },
-    { 0x0000a31c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, 0xa5cf9b4f },
-    { 0x0000a320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, 0xbddfaf1f },
-    { 0x0000a324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, 0xd1ffc93f },
-    { 0x0000a328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x0000a32c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x0000a330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-};
-
-static const u32 ar5416Common_9160[][2] = {
-    { 0x0000000c, 0x00000000 },
-    { 0x00000030, 0x00020015 },
-    { 0x00000034, 0x00000005 },
-    { 0x00000040, 0x00000000 },
-    { 0x00000044, 0x00000008 },
-    { 0x00000048, 0x00000008 },
-    { 0x0000004c, 0x00000010 },
-    { 0x00000050, 0x00000000 },
-    { 0x00000054, 0x0000001f },
-    { 0x00000800, 0x00000000 },
-    { 0x00000804, 0x00000000 },
-    { 0x00000808, 0x00000000 },
-    { 0x0000080c, 0x00000000 },
-    { 0x00000810, 0x00000000 },
-    { 0x00000814, 0x00000000 },
-    { 0x00000818, 0x00000000 },
-    { 0x0000081c, 0x00000000 },
-    { 0x00000820, 0x00000000 },
-    { 0x00000824, 0x00000000 },
-    { 0x00001040, 0x002ffc0f },
-    { 0x00001044, 0x002ffc0f },
-    { 0x00001048, 0x002ffc0f },
-    { 0x0000104c, 0x002ffc0f },
-    { 0x00001050, 0x002ffc0f },
-    { 0x00001054, 0x002ffc0f },
-    { 0x00001058, 0x002ffc0f },
-    { 0x0000105c, 0x002ffc0f },
-    { 0x00001060, 0x002ffc0f },
-    { 0x00001064, 0x002ffc0f },
-    { 0x00001230, 0x00000000 },
-    { 0x00001270, 0x00000000 },
-    { 0x00001038, 0x00000000 },
-    { 0x00001078, 0x00000000 },
-    { 0x000010b8, 0x00000000 },
-    { 0x000010f8, 0x00000000 },
-    { 0x00001138, 0x00000000 },
-    { 0x00001178, 0x00000000 },
-    { 0x000011b8, 0x00000000 },
-    { 0x000011f8, 0x00000000 },
-    { 0x00001238, 0x00000000 },
-    { 0x00001278, 0x00000000 },
-    { 0x000012b8, 0x00000000 },
-    { 0x000012f8, 0x00000000 },
-    { 0x00001338, 0x00000000 },
-    { 0x00001378, 0x00000000 },
-    { 0x000013b8, 0x00000000 },
-    { 0x000013f8, 0x00000000 },
-    { 0x00001438, 0x00000000 },
-    { 0x00001478, 0x00000000 },
-    { 0x000014b8, 0x00000000 },
-    { 0x000014f8, 0x00000000 },
-    { 0x00001538, 0x00000000 },
-    { 0x00001578, 0x00000000 },
-    { 0x000015b8, 0x00000000 },
-    { 0x000015f8, 0x00000000 },
-    { 0x00001638, 0x00000000 },
-    { 0x00001678, 0x00000000 },
-    { 0x000016b8, 0x00000000 },
-    { 0x000016f8, 0x00000000 },
-    { 0x00001738, 0x00000000 },
-    { 0x00001778, 0x00000000 },
-    { 0x000017b8, 0x00000000 },
-    { 0x000017f8, 0x00000000 },
-    { 0x0000103c, 0x00000000 },
-    { 0x0000107c, 0x00000000 },
-    { 0x000010bc, 0x00000000 },
-    { 0x000010fc, 0x00000000 },
-    { 0x0000113c, 0x00000000 },
-    { 0x0000117c, 0x00000000 },
-    { 0x000011bc, 0x00000000 },
-    { 0x000011fc, 0x00000000 },
-    { 0x0000123c, 0x00000000 },
-    { 0x0000127c, 0x00000000 },
-    { 0x000012bc, 0x00000000 },
-    { 0x000012fc, 0x00000000 },
-    { 0x0000133c, 0x00000000 },
-    { 0x0000137c, 0x00000000 },
-    { 0x000013bc, 0x00000000 },
-    { 0x000013fc, 0x00000000 },
-    { 0x0000143c, 0x00000000 },
-    { 0x0000147c, 0x00000000 },
-    { 0x00004030, 0x00000002 },
-    { 0x0000403c, 0x00000002 },
-    { 0x00007010, 0x00000020 },
-    { 0x00007038, 0x000004c2 },
-    { 0x00008004, 0x00000000 },
-    { 0x00008008, 0x00000000 },
-    { 0x0000800c, 0x00000000 },
-    { 0x00008018, 0x00000700 },
-    { 0x00008020, 0x00000000 },
-    { 0x00008038, 0x00000000 },
-    { 0x0000803c, 0x00000000 },
-    { 0x00008048, 0x40000000 },
-    { 0x00008054, 0x00000000 },
-    { 0x00008058, 0x00000000 },
-    { 0x0000805c, 0x000fc78f },
-    { 0x00008060, 0x0000000f },
-    { 0x00008064, 0x00000000 },
-    { 0x000080c0, 0x2a82301a },
-    { 0x000080c4, 0x05dc01e0 },
-    { 0x000080c8, 0x1f402710 },
-    { 0x000080cc, 0x01f40000 },
-    { 0x000080d0, 0x00001e00 },
-    { 0x000080d4, 0x00000000 },
-    { 0x000080d8, 0x00400000 },
-    { 0x000080e0, 0xffffffff },
-    { 0x000080e4, 0x0000ffff },
-    { 0x000080e8, 0x003f3f3f },
-    { 0x000080ec, 0x00000000 },
-    { 0x000080f0, 0x00000000 },
-    { 0x000080f4, 0x00000000 },
-    { 0x000080f8, 0x00000000 },
-    { 0x000080fc, 0x00020000 },
-    { 0x00008100, 0x00020000 },
-    { 0x00008104, 0x00000001 },
-    { 0x00008108, 0x00000052 },
-    { 0x0000810c, 0x00000000 },
-    { 0x00008110, 0x00000168 },
-    { 0x00008118, 0x000100aa },
-    { 0x0000811c, 0x00003210 },
-    { 0x00008120, 0x08f04800 },
-    { 0x00008124, 0x00000000 },
-    { 0x00008128, 0x00000000 },
-    { 0x0000812c, 0x00000000 },
-    { 0x00008130, 0x00000000 },
-    { 0x00008134, 0x00000000 },
-    { 0x00008138, 0x00000000 },
-    { 0x0000813c, 0x00000000 },
-    { 0x00008144, 0xffffffff },
-    { 0x00008168, 0x00000000 },
-    { 0x0000816c, 0x00000000 },
-    { 0x00008170, 0x32143320 },
-    { 0x00008174, 0xfaa4fa50 },
-    { 0x00008178, 0x00000100 },
-    { 0x0000817c, 0x00000000 },
-    { 0x000081c4, 0x00000000 },
-    { 0x000081d0, 0x00003210 },
-    { 0x000081ec, 0x00000000 },
-    { 0x000081f0, 0x00000000 },
-    { 0x000081f4, 0x00000000 },
-    { 0x000081f8, 0x00000000 },
-    { 0x000081fc, 0x00000000 },
-    { 0x00008200, 0x00000000 },
-    { 0x00008204, 0x00000000 },
-    { 0x00008208, 0x00000000 },
-    { 0x0000820c, 0x00000000 },
-    { 0x00008210, 0x00000000 },
-    { 0x00008214, 0x00000000 },
-    { 0x00008218, 0x00000000 },
-    { 0x0000821c, 0x00000000 },
-    { 0x00008220, 0x00000000 },
-    { 0x00008224, 0x00000000 },
-    { 0x00008228, 0x00000000 },
-    { 0x0000822c, 0x00000000 },
-    { 0x00008230, 0x00000000 },
-    { 0x00008234, 0x00000000 },
-    { 0x00008238, 0x00000000 },
-    { 0x0000823c, 0x00000000 },
-    { 0x00008240, 0x00100000 },
-    { 0x00008244, 0x0010f400 },
-    { 0x00008248, 0x00000100 },
-    { 0x0000824c, 0x0001e800 },
-    { 0x00008250, 0x00000000 },
-    { 0x00008254, 0x00000000 },
-    { 0x00008258, 0x00000000 },
-    { 0x0000825c, 0x400000ff },
-    { 0x00008260, 0x00080922 },
-    { 0x00008270, 0x00000000 },
-    { 0x00008274, 0x40000000 },
-    { 0x00008278, 0x003e4180 },
-    { 0x0000827c, 0x00000000 },
-    { 0x00008284, 0x0000002c },
-    { 0x00008288, 0x0000002c },
-    { 0x0000828c, 0x00000000 },
-    { 0x00008294, 0x00000000 },
-    { 0x00008298, 0x00000000 },
-    { 0x00008300, 0x00000000 },
-    { 0x00008304, 0x00000000 },
-    { 0x00008308, 0x00000000 },
-    { 0x0000830c, 0x00000000 },
-    { 0x00008310, 0x00000000 },
-    { 0x00008314, 0x00000000 },
-    { 0x00008318, 0x00000000 },
-    { 0x00008328, 0x00000000 },
-    { 0x0000832c, 0x00000007 },
-    { 0x00008330, 0x00000302 },
-    { 0x00008334, 0x00000e00 },
-    { 0x00008338, 0x00ff0000 },
-    { 0x0000833c, 0x00000000 },
-    { 0x00008340, 0x000107ff },
-    { 0x00009808, 0x00000000 },
-    { 0x0000980c, 0xad848e19 },
-    { 0x00009810, 0x7d14e000 },
-    { 0x00009814, 0x9c0a9f6b },
-    { 0x0000981c, 0x00000000 },
-    { 0x0000982c, 0x0000a000 },
-    { 0x00009830, 0x00000000 },
-    { 0x0000983c, 0x00200400 },
-    { 0x00009840, 0x206a01ae },
-    { 0x0000984c, 0x1284233c },
-    { 0x00009854, 0x00000859 },
-    { 0x00009900, 0x00000000 },
-    { 0x00009904, 0x00000000 },
-    { 0x00009908, 0x00000000 },
-    { 0x0000990c, 0x00000000 },
-    { 0x0000991c, 0x10000fff },
-    { 0x00009920, 0x05100000 },
-    { 0x0000a920, 0x05100000 },
-    { 0x0000b920, 0x05100000 },
-    { 0x00009928, 0x00000001 },
-    { 0x0000992c, 0x00000004 },
-    { 0x00009934, 0x1e1f2022 },
-    { 0x00009938, 0x0a0b0c0d },
-    { 0x0000993c, 0x00000000 },
-    { 0x00009948, 0x9280b212 },
-    { 0x0000994c, 0x00020028 },
-    { 0x00009954, 0x5f3ca3de },
-    { 0x00009958, 0x2108ecff },
-    { 0x00009940, 0x00750604 },
-    { 0x0000c95c, 0x004b6a8e },
-    { 0x00009970, 0x190fb515 },
-    { 0x00009974, 0x00000000 },
-    { 0x00009978, 0x00000001 },
-    { 0x0000997c, 0x00000000 },
-    { 0x00009980, 0x00000000 },
-    { 0x00009984, 0x00000000 },
-    { 0x00009988, 0x00000000 },
-    { 0x0000998c, 0x00000000 },
-    { 0x00009990, 0x00000000 },
-    { 0x00009994, 0x00000000 },
-    { 0x00009998, 0x00000000 },
-    { 0x0000999c, 0x00000000 },
-    { 0x000099a0, 0x00000000 },
-    { 0x000099a4, 0x00000001 },
-    { 0x000099a8, 0x201fff00 },
-    { 0x000099ac, 0x006f0000 },
-    { 0x000099b0, 0x03051000 },
-    { 0x000099dc, 0x00000000 },
-    { 0x000099e0, 0x00000200 },
-    { 0x000099e4, 0xaaaaaaaa },
-    { 0x000099e8, 0x3c466478 },
-    { 0x000099ec, 0x0cc80caa },
-    { 0x000099fc, 0x00001042 },
-    { 0x00009b00, 0x00000000 },
-    { 0x00009b04, 0x00000001 },
-    { 0x00009b08, 0x00000002 },
-    { 0x00009b0c, 0x00000003 },
-    { 0x00009b10, 0x00000004 },
-    { 0x00009b14, 0x00000005 },
-    { 0x00009b18, 0x00000008 },
-    { 0x00009b1c, 0x00000009 },
-    { 0x00009b20, 0x0000000a },
-    { 0x00009b24, 0x0000000b },
-    { 0x00009b28, 0x0000000c },
-    { 0x00009b2c, 0x0000000d },
-    { 0x00009b30, 0x00000010 },
-    { 0x00009b34, 0x00000011 },
-    { 0x00009b38, 0x00000012 },
-    { 0x00009b3c, 0x00000013 },
-    { 0x00009b40, 0x00000014 },
-    { 0x00009b44, 0x00000015 },
-    { 0x00009b48, 0x00000018 },
-    { 0x00009b4c, 0x00000019 },
-    { 0x00009b50, 0x0000001a },
-    { 0x00009b54, 0x0000001b },
-    { 0x00009b58, 0x0000001c },
-    { 0x00009b5c, 0x0000001d },
-    { 0x00009b60, 0x00000020 },
-    { 0x00009b64, 0x00000021 },
-    { 0x00009b68, 0x00000022 },
-    { 0x00009b6c, 0x00000023 },
-    { 0x00009b70, 0x00000024 },
-    { 0x00009b74, 0x00000025 },
-    { 0x00009b78, 0x00000028 },
-    { 0x00009b7c, 0x00000029 },
-    { 0x00009b80, 0x0000002a },
-    { 0x00009b84, 0x0000002b },
-    { 0x00009b88, 0x0000002c },
-    { 0x00009b8c, 0x0000002d },
-    { 0x00009b90, 0x00000030 },
-    { 0x00009b94, 0x00000031 },
-    { 0x00009b98, 0x00000032 },
-    { 0x00009b9c, 0x00000033 },
-    { 0x00009ba0, 0x00000034 },
-    { 0x00009ba4, 0x00000035 },
-    { 0x00009ba8, 0x00000035 },
-    { 0x00009bac, 0x00000035 },
-    { 0x00009bb0, 0x00000035 },
-    { 0x00009bb4, 0x00000035 },
-    { 0x00009bb8, 0x00000035 },
-    { 0x00009bbc, 0x00000035 },
-    { 0x00009bc0, 0x00000035 },
-    { 0x00009bc4, 0x00000035 },
-    { 0x00009bc8, 0x00000035 },
-    { 0x00009bcc, 0x00000035 },
-    { 0x00009bd0, 0x00000035 },
-    { 0x00009bd4, 0x00000035 },
-    { 0x00009bd8, 0x00000035 },
-    { 0x00009bdc, 0x00000035 },
-    { 0x00009be0, 0x00000035 },
-    { 0x00009be4, 0x00000035 },
-    { 0x00009be8, 0x00000035 },
-    { 0x00009bec, 0x00000035 },
-    { 0x00009bf0, 0x00000035 },
-    { 0x00009bf4, 0x00000035 },
-    { 0x00009bf8, 0x00000010 },
-    { 0x00009bfc, 0x0000001a },
-    { 0x0000a210, 0x40806333 },
-    { 0x0000a214, 0x00106c10 },
-    { 0x0000a218, 0x009c4060 },
-    { 0x0000a220, 0x018830c6 },
-    { 0x0000a224, 0x00000400 },
-    { 0x0000a228, 0x001a0bb5 },
-    { 0x0000a22c, 0x00000000 },
-    { 0x0000a234, 0x20202020 },
-    { 0x0000a238, 0x20202020 },
-    { 0x0000a23c, 0x13c889af },
-    { 0x0000a240, 0x38490a20 },
-    { 0x0000a244, 0x00007bb6 },
-    { 0x0000a248, 0x0fff3ffc },
-    { 0x0000a24c, 0x00000001 },
-    { 0x0000a250, 0x0000e000 },
-    { 0x0000a254, 0x00000000 },
-    { 0x0000a258, 0x0cc75380 },
-    { 0x0000a25c, 0x0f0f0f01 },
-    { 0x0000a260, 0xdfa91f01 },
-    { 0x0000a268, 0x00000001 },
-    { 0x0000a26c, 0x0ebae9c6 },
-    { 0x0000b26c, 0x0ebae9c6 },
-    { 0x0000c26c, 0x0ebae9c6 },
-    { 0x0000d270, 0x00820820 },
-    { 0x0000a278, 0x1ce739ce },
-    { 0x0000a27c, 0x050701ce },
-    { 0x0000a338, 0x00000000 },
-    { 0x0000a33c, 0x00000000 },
-    { 0x0000a340, 0x00000000 },
-    { 0x0000a344, 0x00000000 },
-    { 0x0000a348, 0x3fffffff },
-    { 0x0000a34c, 0x3fffffff },
-    { 0x0000a350, 0x3fffffff },
-    { 0x0000a354, 0x0003ffff },
-    { 0x0000a358, 0x79bfaa03 },
-    { 0x0000d35c, 0x07ffffef },
-    { 0x0000d360, 0x0fffffe7 },
-    { 0x0000d364, 0x17ffffe5 },
-    { 0x0000d368, 0x1fffffe4 },
-    { 0x0000d36c, 0x37ffffe3 },
-    { 0x0000d370, 0x3fffffe3 },
-    { 0x0000d374, 0x57ffffe3 },
-    { 0x0000d378, 0x5fffffe2 },
-    { 0x0000d37c, 0x7fffffe2 },
-    { 0x0000d380, 0x7f3c7bba },
-    { 0x0000d384, 0xf3307ff0 },
-    { 0x0000a388, 0x0c000000 },
-    { 0x0000a38c, 0x20202020 },
-    { 0x0000a390, 0x20202020 },
-    { 0x0000a394, 0x1ce739ce },
-    { 0x0000a398, 0x000001ce },
-    { 0x0000a39c, 0x00000001 },
-    { 0x0000a3a0, 0x00000000 },
-    { 0x0000a3a4, 0x00000000 },
-    { 0x0000a3a8, 0x00000000 },
-    { 0x0000a3ac, 0x00000000 },
-    { 0x0000a3b0, 0x00000000 },
-    { 0x0000a3b4, 0x00000000 },
-    { 0x0000a3b8, 0x00000000 },
-    { 0x0000a3bc, 0x00000000 },
-    { 0x0000a3c0, 0x00000000 },
-    { 0x0000a3c4, 0x00000000 },
-    { 0x0000a3c8, 0x00000246 },
-    { 0x0000a3cc, 0x20202020 },
-    { 0x0000a3d0, 0x20202020 },
-    { 0x0000a3d4, 0x20202020 },
-    { 0x0000a3dc, 0x1ce739ce },
-    { 0x0000a3e0, 0x000001ce },
-};
-
-static const u32 ar5416Bank0_9160[][2] = {
-    { 0x000098b0, 0x1e5795e5 },
-    { 0x000098e0, 0x02008020 },
-};
-
-static const u32 ar5416BB_RfGain_9160[][3] = {
-    { 0x00009a00, 0x00000000, 0x00000000 },
-    { 0x00009a04, 0x00000040, 0x00000040 },
-    { 0x00009a08, 0x00000080, 0x00000080 },
-    { 0x00009a0c, 0x000001a1, 0x00000141 },
-    { 0x00009a10, 0x000001e1, 0x00000181 },
-    { 0x00009a14, 0x00000021, 0x000001c1 },
-    { 0x00009a18, 0x00000061, 0x00000001 },
-    { 0x00009a1c, 0x00000168, 0x00000041 },
-    { 0x00009a20, 0x000001a8, 0x000001a8 },
-    { 0x00009a24, 0x000001e8, 0x000001e8 },
-    { 0x00009a28, 0x00000028, 0x00000028 },
-    { 0x00009a2c, 0x00000068, 0x00000068 },
-    { 0x00009a30, 0x00000189, 0x000000a8 },
-    { 0x00009a34, 0x000001c9, 0x00000169 },
-    { 0x00009a38, 0x00000009, 0x000001a9 },
-    { 0x00009a3c, 0x00000049, 0x000001e9 },
-    { 0x00009a40, 0x00000089, 0x00000029 },
-    { 0x00009a44, 0x00000170, 0x00000069 },
-    { 0x00009a48, 0x000001b0, 0x00000190 },
-    { 0x00009a4c, 0x000001f0, 0x000001d0 },
-    { 0x00009a50, 0x00000030, 0x00000010 },
-    { 0x00009a54, 0x00000070, 0x00000050 },
-    { 0x00009a58, 0x00000191, 0x00000090 },
-    { 0x00009a5c, 0x000001d1, 0x00000151 },
-    { 0x00009a60, 0x00000011, 0x00000191 },
-    { 0x00009a64, 0x00000051, 0x000001d1 },
-    { 0x00009a68, 0x00000091, 0x00000011 },
-    { 0x00009a6c, 0x000001b8, 0x00000051 },
-    { 0x00009a70, 0x000001f8, 0x00000198 },
-    { 0x00009a74, 0x00000038, 0x000001d8 },
-    { 0x00009a78, 0x00000078, 0x00000018 },
-    { 0x00009a7c, 0x00000199, 0x00000058 },
-    { 0x00009a80, 0x000001d9, 0x00000098 },
-    { 0x00009a84, 0x00000019, 0x00000159 },
-    { 0x00009a88, 0x00000059, 0x00000199 },
-    { 0x00009a8c, 0x00000099, 0x000001d9 },
-    { 0x00009a90, 0x000000d9, 0x00000019 },
-    { 0x00009a94, 0x000000f9, 0x00000059 },
-    { 0x00009a98, 0x000000f9, 0x00000099 },
-    { 0x00009a9c, 0x000000f9, 0x000000d9 },
-    { 0x00009aa0, 0x000000f9, 0x000000f9 },
-    { 0x00009aa4, 0x000000f9, 0x000000f9 },
-    { 0x00009aa8, 0x000000f9, 0x000000f9 },
-    { 0x00009aac, 0x000000f9, 0x000000f9 },
-    { 0x00009ab0, 0x000000f9, 0x000000f9 },
-    { 0x00009ab4, 0x000000f9, 0x000000f9 },
-    { 0x00009ab8, 0x000000f9, 0x000000f9 },
-    { 0x00009abc, 0x000000f9, 0x000000f9 },
-    { 0x00009ac0, 0x000000f9, 0x000000f9 },
-    { 0x00009ac4, 0x000000f9, 0x000000f9 },
-    { 0x00009ac8, 0x000000f9, 0x000000f9 },
-    { 0x00009acc, 0x000000f9, 0x000000f9 },
-    { 0x00009ad0, 0x000000f9, 0x000000f9 },
-    { 0x00009ad4, 0x000000f9, 0x000000f9 },
-    { 0x00009ad8, 0x000000f9, 0x000000f9 },
-    { 0x00009adc, 0x000000f9, 0x000000f9 },
-    { 0x00009ae0, 0x000000f9, 0x000000f9 },
-    { 0x00009ae4, 0x000000f9, 0x000000f9 },
-    { 0x00009ae8, 0x000000f9, 0x000000f9 },
-    { 0x00009aec, 0x000000f9, 0x000000f9 },
-    { 0x00009af0, 0x000000f9, 0x000000f9 },
-    { 0x00009af4, 0x000000f9, 0x000000f9 },
-    { 0x00009af8, 0x000000f9, 0x000000f9 },
-    { 0x00009afc, 0x000000f9, 0x000000f9 },
-};
-
-static const u32 ar5416Bank1_9160[][2] = {
-    { 0x000098b0, 0x02108421 },
-    { 0x000098ec, 0x00000008 },
-};
-
-static const u32 ar5416Bank2_9160[][2] = {
-    { 0x000098b0, 0x0e73ff17 },
-    { 0x000098e0, 0x00000420 },
-};
-
-static const u32 ar5416Bank3_9160[][3] = {
-    { 0x000098f0, 0x01400018, 0x01c00018 },
-};
-
-static const u32 ar5416Bank6_9160[][3] = {
-    { 0x0000989c, 0x00000000, 0x00000000 },
-    { 0x0000989c, 0x00000000, 0x00000000 },
-    { 0x0000989c, 0x00000000, 0x00000000 },
-    { 0x0000989c, 0x00e00000, 0x00e00000 },
-    { 0x0000989c, 0x005e0000, 0x005e0000 },
-    { 0x0000989c, 0x00120000, 0x00120000 },
-    { 0x0000989c, 0x00620000, 0x00620000 },
-    { 0x0000989c, 0x00020000, 0x00020000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x40ff0000, 0x40ff0000 },
-    { 0x0000989c, 0x005f0000, 0x005f0000 },
-    { 0x0000989c, 0x00870000, 0x00870000 },
-    { 0x0000989c, 0x00f90000, 0x00f90000 },
-    { 0x0000989c, 0x007b0000, 0x007b0000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x00f50000, 0x00f50000 },
-    { 0x0000989c, 0x00dc0000, 0x00dc0000 },
-    { 0x0000989c, 0x00110000, 0x00110000 },
-    { 0x0000989c, 0x006100a8, 0x006100a8 },
-    { 0x0000989c, 0x004210a2, 0x004210a2 },
-    { 0x0000989c, 0x0014008f, 0x0014008f },
-    { 0x0000989c, 0x00c40003, 0x00c40003 },
-    { 0x0000989c, 0x003000f2, 0x003000f2 },
-    { 0x0000989c, 0x00440016, 0x00440016 },
-    { 0x0000989c, 0x00410040, 0x00410040 },
-    { 0x0000989c, 0x0001805e, 0x0001805e },
-    { 0x0000989c, 0x0000c0ab, 0x0000c0ab },
-    { 0x0000989c, 0x000000f1, 0x000000f1 },
-    { 0x0000989c, 0x00002081, 0x00002081 },
-    { 0x0000989c, 0x000000d4, 0x000000d4 },
-    { 0x000098d0, 0x0000000f, 0x0010000f },
-};
-
-static const u32 ar5416Bank6TPC_9160[][3] = {
-    { 0x0000989c, 0x00000000, 0x00000000 },
-    { 0x0000989c, 0x00000000, 0x00000000 },
-    { 0x0000989c, 0x00000000, 0x00000000 },
-    { 0x0000989c, 0x00e00000, 0x00e00000 },
-    { 0x0000989c, 0x005e0000, 0x005e0000 },
-    { 0x0000989c, 0x00120000, 0x00120000 },
-    { 0x0000989c, 0x00620000, 0x00620000 },
-    { 0x0000989c, 0x00020000, 0x00020000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x40ff0000, 0x40ff0000 },
-    { 0x0000989c, 0x005f0000, 0x005f0000 },
-    { 0x0000989c, 0x00870000, 0x00870000 },
-    { 0x0000989c, 0x00f90000, 0x00f90000 },
-    { 0x0000989c, 0x007b0000, 0x007b0000 },
-    { 0x0000989c, 0x00ff0000, 0x00ff0000 },
-    { 0x0000989c, 0x00f50000, 0x00f50000 },
-    { 0x0000989c, 0x00dc0000, 0x00dc0000 },
-    { 0x0000989c, 0x00110000, 0x00110000 },
-    { 0x0000989c, 0x006100a8, 0x006100a8 },
-    { 0x0000989c, 0x00423022, 0x00423022 },
-    { 0x0000989c, 0x2014008f, 0x2014008f },
-    { 0x0000989c, 0x00c40002, 0x00c40002 },
-    { 0x0000989c, 0x003000f2, 0x003000f2 },
-    { 0x0000989c, 0x00440016, 0x00440016 },
-    { 0x0000989c, 0x00410040, 0x00410040 },
-    { 0x0000989c, 0x0001805e, 0x0001805e },
-    { 0x0000989c, 0x0000c0ab, 0x0000c0ab },
-    { 0x0000989c, 0x000000e1, 0x000000e1 },
-    { 0x0000989c, 0x00007080, 0x00007080 },
-    { 0x0000989c, 0x000000d4, 0x000000d4 },
-    { 0x000098d0, 0x0000000f, 0x0010000f },
-};
-
-static const u32 ar5416Bank7_9160[][2] = {
-    { 0x0000989c, 0x00000500 },
-    { 0x0000989c, 0x00000800 },
-    { 0x000098cc, 0x0000000e },
-};
-
-static u32 ar5416Addac_9160[][2] = {
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x000000c0 },
-    {0x0000989c,  0x00000018 },
-    {0x0000989c,  0x00000004 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x000000c0 },
-    {0x0000989c,  0x00000019 },
-    {0x0000989c,  0x00000004 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000004 },
-    {0x0000989c,  0x00000003 },
-    {0x0000989c,  0x00000008 },
-    {0x0000989c,  0x00000000 },
-    {0x000098cc,  0x00000000 },
-};
-
-static u32 ar5416Addac_91601_1[][2] = {
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x000000c0 },
-    {0x0000989c,  0x00000018 },
-    {0x0000989c,  0x00000004 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x000000c0 },
-    {0x0000989c,  0x00000019 },
-    {0x0000989c,  0x00000004 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x0000989c,  0x00000000 },
-    {0x000098cc,  0x00000000 },
-};
-
-/* XXX 9280 1 */
-static const u32 ar9280Modes_9280[][6] = {
-    { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
-    { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
-    { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
-    { 0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000, 0x00014008 },
-    { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801080, 0x08400840, 0x06e006e0 },
-    { 0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b, 0x0988004f },
-    { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 },
-    { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 },
-    { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
-    { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 },
-    { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
-    { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 },
-    { 0x00009844, 0x1372161e, 0x1372161e, 0x137216a0, 0x137216a0, 0x137216a0 },
-    { 0x00009848, 0x00028566, 0x00028566, 0x00028563, 0x00028563, 0x00028563 },
-    { 0x0000a848, 0x00028566, 0x00028566, 0x00028563, 0x00028563, 0x00028563 },
-    { 0x00009850, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2 },
-    { 0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e },
-    { 0x0000985c, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e },
-    { 0x00009860, 0x00049d18, 0x00049d18, 0x00049d20, 0x00049d20, 0x00049d18 },
-    { 0x0000c864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 },
-    { 0x00009868, 0x5ac64190, 0x5ac64190, 0x5ac64190, 0x5ac64190, 0x5ac64190 },
-    { 0x0000986c, 0x06903081, 0x06903081, 0x06903881, 0x06903881, 0x06903881 },
-    { 0x00009914, 0x000007d0, 0x000007d0, 0x00000898, 0x00000898, 0x000007d0 },
-    { 0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016 },
-    { 0x00009924, 0xd00a8a07, 0xd00a8a07, 0xd00a8a0d, 0xd00a8a0d, 0xd00a8a0d },
-    { 0x00009944, 0xdfbc1010, 0xdfbc1010, 0xdfbc1010, 0xdfbc1010, 0xdfbc1010 },
-    { 0x00009960, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010 },
-    { 0x0000a960, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010 },
-    { 0x00009964, 0x00000210, 0x00000210, 0x00000210, 0x00000210, 0x00000210 },
-    { 0x0000c9b8, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a },
-    { 0x0000c9bc, 0x00000600, 0x00000600, 0x00000c00, 0x00000c00, 0x00000c00 },
-    { 0x000099c0, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4 },
-    { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 },
-    { 0x000099c8, 0x60f6532c, 0x60f6532c, 0x60f6532c, 0x60f6532c, 0x60f6532c },
-    { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 },
-    { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 },
-    { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x00009a00, 0x00008184, 0x00008184, 0x00000214, 0x00000214, 0x00000214 },
-    { 0x00009a04, 0x00008188, 0x00008188, 0x00000218, 0x00000218, 0x00000218 },
-    { 0x00009a08, 0x0000818c, 0x0000818c, 0x00000224, 0x00000224, 0x00000224 },
-    { 0x00009a0c, 0x00008190, 0x00008190, 0x00000228, 0x00000228, 0x00000228 },
-    { 0x00009a10, 0x00008194, 0x00008194, 0x0000022c, 0x0000022c, 0x0000022c },
-    { 0x00009a14, 0x00008200, 0x00008200, 0x00000230, 0x00000230, 0x00000230 },
-    { 0x00009a18, 0x00008204, 0x00008204, 0x000002a4, 0x000002a4, 0x000002a4 },
-    { 0x00009a1c, 0x00008208, 0x00008208, 0x000002a8, 0x000002a8, 0x000002a8 },
-    { 0x00009a20, 0x0000820c, 0x0000820c, 0x000002ac, 0x000002ac, 0x000002ac },
-    { 0x00009a24, 0x00008210, 0x00008210, 0x000002b0, 0x000002b0, 0x000002b0 },
-    { 0x00009a28, 0x00008214, 0x00008214, 0x000002b4, 0x000002b4, 0x000002b4 },
-    { 0x00009a2c, 0x00008280, 0x00008280, 0x000002b8, 0x000002b8, 0x000002b8 },
-    { 0x00009a30, 0x00008284, 0x00008284, 0x00000390, 0x00000390, 0x00000390 },
-    { 0x00009a34, 0x00008288, 0x00008288, 0x00000394, 0x00000394, 0x00000394 },
-    { 0x00009a38, 0x0000828c, 0x0000828c, 0x00000398, 0x00000398, 0x00000398 },
-    { 0x00009a3c, 0x00008290, 0x00008290, 0x00000334, 0x00000334, 0x00000334 },
-    { 0x00009a40, 0x00008300, 0x00008300, 0x00000338, 0x00000338, 0x00000338 },
-    { 0x00009a44, 0x00008304, 0x00008304, 0x000003ac, 0x000003ac, 0x000003ac },
-    { 0x00009a48, 0x00008308, 0x00008308, 0x000003b0, 0x000003b0, 0x000003b0 },
-    { 0x00009a4c, 0x0000830c, 0x0000830c, 0x000003b4, 0x000003b4, 0x000003b4 },
-    { 0x00009a50, 0x00008310, 0x00008310, 0x000003b8, 0x000003b8, 0x000003b8 },
-    { 0x00009a54, 0x00008314, 0x00008314, 0x000003a5, 0x000003a5, 0x000003a5 },
-    { 0x00009a58, 0x00008380, 0x00008380, 0x000003a9, 0x000003a9, 0x000003a9 },
-    { 0x00009a5c, 0x00008384, 0x00008384, 0x000003ad, 0x000003ad, 0x000003ad },
-    { 0x00009a60, 0x00008388, 0x00008388, 0x00008194, 0x00008194, 0x00008194 },
-    { 0x00009a64, 0x0000838c, 0x0000838c, 0x000081a0, 0x000081a0, 0x000081a0 },
-    { 0x00009a68, 0x00008390, 0x00008390, 0x0000820c, 0x0000820c, 0x0000820c },
-    { 0x00009a6c, 0x00008394, 0x00008394, 0x000081a8, 0x000081a8, 0x000081a8 },
-    { 0x00009a70, 0x0000a380, 0x0000a380, 0x00008284, 0x00008284, 0x00008284 },
-    { 0x00009a74, 0x0000a384, 0x0000a384, 0x00008288, 0x00008288, 0x00008288 },
-    { 0x00009a78, 0x0000a388, 0x0000a388, 0x00008224, 0x00008224, 0x00008224 },
-    { 0x00009a7c, 0x0000a38c, 0x0000a38c, 0x00008290, 0x00008290, 0x00008290 },
-    { 0x00009a80, 0x0000a390, 0x0000a390, 0x00008300, 0x00008300, 0x00008300 },
-    { 0x00009a84, 0x0000a394, 0x0000a394, 0x00008304, 0x00008304, 0x00008304 },
-    { 0x00009a88, 0x0000a780, 0x0000a780, 0x00008308, 0x00008308, 0x00008308 },
-    { 0x00009a8c, 0x0000a784, 0x0000a784, 0x0000830c, 0x0000830c, 0x0000830c },
-    { 0x00009a90, 0x0000a788, 0x0000a788, 0x00008380, 0x00008380, 0x00008380 },
-    { 0x00009a94, 0x0000a78c, 0x0000a78c, 0x00008384, 0x00008384, 0x00008384 },
-    { 0x00009a98, 0x0000a790, 0x0000a790, 0x00008700, 0x00008700, 0x00008700 },
-    { 0x00009a9c, 0x0000a794, 0x0000a794, 0x00008704, 0x00008704, 0x00008704 },
-    { 0x00009aa0, 0x0000ab84, 0x0000ab84, 0x00008708, 0x00008708, 0x00008708 },
-    { 0x00009aa4, 0x0000ab88, 0x0000ab88, 0x0000870c, 0x0000870c, 0x0000870c },
-    { 0x00009aa8, 0x0000ab8c, 0x0000ab8c, 0x00008780, 0x00008780, 0x00008780 },
-    { 0x00009aac, 0x0000ab90, 0x0000ab90, 0x00008784, 0x00008784, 0x00008784 },
-    { 0x00009ab0, 0x0000ab94, 0x0000ab94, 0x00008b00, 0x00008b00, 0x00008b00 },
-    { 0x00009ab4, 0x0000af80, 0x0000af80, 0x00008b04, 0x00008b04, 0x00008b04 },
-    { 0x00009ab8, 0x0000af84, 0x0000af84, 0x00008b08, 0x00008b08, 0x00008b08 },
-    { 0x00009abc, 0x0000af88, 0x0000af88, 0x00008b0c, 0x00008b0c, 0x00008b0c },
-    { 0x00009ac0, 0x0000af8c, 0x0000af8c, 0x00008b80, 0x00008b80, 0x00008b80 },
-    { 0x00009ac4, 0x0000af90, 0x0000af90, 0x00008b84, 0x00008b84, 0x00008b84 },
-    { 0x00009ac8, 0x0000af94, 0x0000af94, 0x00008b88, 0x00008b88, 0x00008b88 },
-    { 0x00009acc, 0x0000b380, 0x0000b380, 0x00008b8c, 0x00008b8c, 0x00008b8c },
-    { 0x00009ad0, 0x0000b384, 0x0000b384, 0x00008b90, 0x00008b90, 0x00008b90 },
-    { 0x00009ad4, 0x0000b388, 0x0000b388, 0x00008f80, 0x00008f80, 0x00008f80 },
-    { 0x00009ad8, 0x0000b38c, 0x0000b38c, 0x00008f84, 0x00008f84, 0x00008f84 },
-    { 0x00009adc, 0x0000b390, 0x0000b390, 0x00008f88, 0x00008f88, 0x00008f88 },
-    { 0x00009ae0, 0x0000b394, 0x0000b394, 0x00008f8c, 0x00008f8c, 0x00008f8c },
-    { 0x00009ae4, 0x0000b398, 0x0000b398, 0x00008f90, 0x00008f90, 0x00008f90 },
-    { 0x00009ae8, 0x0000b780, 0x0000b780, 0x0000930c, 0x0000930c, 0x0000930c },
-    { 0x00009aec, 0x0000b784, 0x0000b784, 0x00009310, 0x00009310, 0x00009310 },
-    { 0x00009af0, 0x0000b788, 0x0000b788, 0x00009384, 0x00009384, 0x00009384 },
-    { 0x00009af4, 0x0000b78c, 0x0000b78c, 0x00009388, 0x00009388, 0x00009388 },
-    { 0x00009af8, 0x0000b790, 0x0000b790, 0x00009324, 0x00009324, 0x00009324 },
-    { 0x00009afc, 0x0000b794, 0x0000b794, 0x00009704, 0x00009704, 0x00009704 },
-    { 0x00009b00, 0x0000b798, 0x0000b798, 0x000096a4, 0x000096a4, 0x000096a4 },
-    { 0x00009b04, 0x0000d784, 0x0000d784, 0x000096a8, 0x000096a8, 0x000096a8 },
-    { 0x00009b08, 0x0000d788, 0x0000d788, 0x00009710, 0x00009710, 0x00009710 },
-    { 0x00009b0c, 0x0000d78c, 0x0000d78c, 0x00009714, 0x00009714, 0x00009714 },
-    { 0x00009b10, 0x0000d790, 0x0000d790, 0x00009720, 0x00009720, 0x00009720 },
-    { 0x00009b14, 0x0000f780, 0x0000f780, 0x00009724, 0x00009724, 0x00009724 },
-    { 0x00009b18, 0x0000f784, 0x0000f784, 0x00009728, 0x00009728, 0x00009728 },
-    { 0x00009b1c, 0x0000f788, 0x0000f788, 0x0000972c, 0x0000972c, 0x0000972c },
-    { 0x00009b20, 0x0000f78c, 0x0000f78c, 0x000097a0, 0x000097a0, 0x000097a0 },
-    { 0x00009b24, 0x0000f790, 0x0000f790, 0x000097a4, 0x000097a4, 0x000097a4 },
-    { 0x00009b28, 0x0000f794, 0x0000f794, 0x000097a8, 0x000097a8, 0x000097a8 },
-    { 0x00009b2c, 0x0000f7a4, 0x0000f7a4, 0x000097b0, 0x000097b0, 0x000097b0 },
-    { 0x00009b30, 0x0000f7a8, 0x0000f7a8, 0x000097b4, 0x000097b4, 0x000097b4 },
-    { 0x00009b34, 0x0000f7ac, 0x0000f7ac, 0x000097b8, 0x000097b8, 0x000097b8 },
-    { 0x00009b38, 0x0000f7b0, 0x0000f7b0, 0x000097a5, 0x000097a5, 0x000097a5 },
-    { 0x00009b3c, 0x0000f7b4, 0x0000f7b4, 0x000097a9, 0x000097a9, 0x000097a9 },
-    { 0x00009b40, 0x0000f7a1, 0x0000f7a1, 0x000097ad, 0x000097ad, 0x000097ad },
-    { 0x00009b44, 0x0000f7a5, 0x0000f7a5, 0x000097b1, 0x000097b1, 0x000097b1 },
-    { 0x00009b48, 0x0000f7a9, 0x0000f7a9, 0x000097b5, 0x000097b5, 0x000097b5 },
-    { 0x00009b4c, 0x0000f7ad, 0x0000f7ad, 0x000097b9, 0x000097b9, 0x000097b9 },
-    { 0x00009b50, 0x0000f7b1, 0x0000f7b1, 0x000097c5, 0x000097c5, 0x000097c5 },
-    { 0x00009b54, 0x0000f7b5, 0x0000f7b5, 0x000097c9, 0x000097c9, 0x000097c9 },
-    { 0x00009b58, 0x0000f7c5, 0x0000f7c5, 0x000097d1, 0x000097d1, 0x000097d1 },
-    { 0x00009b5c, 0x0000f7c9, 0x0000f7c9, 0x000097d5, 0x000097d5, 0x000097d5 },
-    { 0x00009b60, 0x0000f7cd, 0x0000f7cd, 0x000097d9, 0x000097d9, 0x000097d9 },
-    { 0x00009b64, 0x0000f7d1, 0x0000f7d1, 0x000097c6, 0x000097c6, 0x000097c6 },
-    { 0x00009b68, 0x0000f7d5, 0x0000f7d5, 0x000097ca, 0x000097ca, 0x000097ca },
-    { 0x00009b6c, 0x0000f7c2, 0x0000f7c2, 0x000097ce, 0x000097ce, 0x000097ce },
-    { 0x00009b70, 0x0000f7c6, 0x0000f7c6, 0x000097d2, 0x000097d2, 0x000097d2 },
-    { 0x00009b74, 0x0000f7ca, 0x0000f7ca, 0x000097d6, 0x000097d6, 0x000097d6 },
-    { 0x00009b78, 0x0000f7ce, 0x0000f7ce, 0x000097c3, 0x000097c3, 0x000097c3 },
-    { 0x00009b7c, 0x0000f7d2, 0x0000f7d2, 0x000097c7, 0x000097c7, 0x000097c7 },
-    { 0x00009b80, 0x0000f7d6, 0x0000f7d6, 0x000097cb, 0x000097cb, 0x000097cb },
-    { 0x00009b84, 0x0000f7c3, 0x0000f7c3, 0x000097cf, 0x000097cf, 0x000097cf },
-    { 0x00009b88, 0x0000f7c7, 0x0000f7c7, 0x000097d7, 0x000097d7, 0x000097d7 },
-    { 0x00009b8c, 0x0000f7cb, 0x0000f7cb, 0x000097db, 0x000097db, 0x000097db },
-    { 0x00009b90, 0x0000f7d3, 0x0000f7d3, 0x000097db, 0x000097db, 0x000097db },
-    { 0x00009b94, 0x0000f7d7, 0x0000f7d7, 0x000097db, 0x000097db, 0x000097db },
-    { 0x00009b98, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
-    { 0x00009b9c, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
-    { 0x00009ba0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
-    { 0x00009ba4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
-    { 0x00009ba8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
-    { 0x00009bac, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
-    { 0x00009bb0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
-    { 0x00009bb4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
-    { 0x00009bb8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
-    { 0x00009bbc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
-    { 0x00009bc0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
-    { 0x00009bc4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
-    { 0x00009bc8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
-    { 0x00009bcc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
-    { 0x00009bd0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
-    { 0x00009bd4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
-    { 0x00009bd8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
-    { 0x00009bdc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
-    { 0x00009be0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
-    { 0x00009be4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
-    { 0x00009be8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
-    { 0x00009bec, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
-    { 0x00009bf0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
-    { 0x00009bf4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
-    { 0x00009bf8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
-    { 0x00009bfc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
-    { 0x0000a204, 0x00000444, 0x00000444, 0x00000444, 0x00000444, 0x00000444 },
-    { 0x0000a208, 0x803e4788, 0x803e4788, 0x803e4788, 0x803e4788, 0x803e4788 },
-    { 0x0000a20c, 0x000c6019, 0x000c6019, 0x000c6019, 0x000c6019, 0x000c6019 },
-    { 0x0000b20c, 0x000c6019, 0x000c6019, 0x000c6019, 0x000c6019, 0x000c6019 },
-    { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a },
-    { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
-    { 0x0000a274, 0x0a19c652, 0x0a19c652, 0x0a1aa652, 0x0a1aa652, 0x0a1aa652 },
-    { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x0000a304, 0x00003002, 0x00003002, 0x00003002, 0x00003002, 0x00003002 },
-    { 0x0000a308, 0x00006004, 0x00006004, 0x00008009, 0x00008009, 0x00008009 },
-    { 0x0000a30c, 0x0000a006, 0x0000a006, 0x0000b00b, 0x0000b00b, 0x0000b00b },
-    { 0x0000a310, 0x0000e012, 0x0000e012, 0x0000e012, 0x0000e012, 0x0000e012 },
-    { 0x0000a314, 0x00011014, 0x00011014, 0x00012048, 0x00012048, 0x00012048 },
-    { 0x0000a318, 0x0001504a, 0x0001504a, 0x0001604a, 0x0001604a, 0x0001604a },
-    { 0x0000a31c, 0x0001904c, 0x0001904c, 0x0001a211, 0x0001a211, 0x0001a211 },
-    { 0x0000a320, 0x0001c04e, 0x0001c04e, 0x0001e213, 0x0001e213, 0x0001e213 },
-    { 0x0000a324, 0x00020092, 0x00020092, 0x0002121b, 0x0002121b, 0x0002121b },
-    { 0x0000a328, 0x0002410a, 0x0002410a, 0x00024412, 0x00024412, 0x00024412 },
-    { 0x0000a32c, 0x0002710c, 0x0002710c, 0x00028414, 0x00028414, 0x00028414 },
-    { 0x0000a330, 0x0002b18b, 0x0002b18b, 0x0002b44a, 0x0002b44a, 0x0002b44a },
-    { 0x0000a334, 0x0002e1cc, 0x0002e1cc, 0x00030649, 0x00030649, 0x00030649 },
-    { 0x0000a338, 0x000321ec, 0x000321ec, 0x0003364b, 0x0003364b, 0x0003364b },
-    { 0x0000a33c, 0x000321ec, 0x000321ec, 0x00038a49, 0x00038a49, 0x00038a49 },
-    { 0x0000a340, 0x000321ec, 0x000321ec, 0x0003be48, 0x0003be48, 0x0003be48 },
-    { 0x0000a344, 0x000321ec, 0x000321ec, 0x0003ee4a, 0x0003ee4a, 0x0003ee4a },
-    { 0x0000a348, 0x000321ec, 0x000321ec, 0x00042e88, 0x00042e88, 0x00042e88 },
-    { 0x0000a34c, 0x000321ec, 0x000321ec, 0x00046e8a, 0x00046e8a, 0x00046e8a },
-    { 0x0000a350, 0x000321ec, 0x000321ec, 0x00049ec9, 0x00049ec9, 0x00049ec9 },
-    { 0x0000a354, 0x000321ec, 0x000321ec, 0x0004bf42, 0x0004bf42, 0x0004bf42 },
-    { 0x0000784c, 0x0e4f048c, 0x0e4f048c, 0x0e4d048c, 0x0e4d048c, 0x0e4d048c },
-    { 0x00007854, 0x12031828, 0x12031828, 0x12035828, 0x12035828, 0x12035828 },
-    { 0x00007870, 0x807ec400, 0x807ec400, 0x807ec000, 0x807ec000, 0x807ec000 },
-    { 0x0000788c, 0x00010000, 0x00010000, 0x00110000, 0x00110000, 0x00110000 },
-};
-
-static const u32 ar9280Common_9280[][2] = {
-    { 0x0000000c, 0x00000000 },
-    { 0x00000030, 0x00020015 },
-    { 0x00000034, 0x00000005 },
-    { 0x00000040, 0x00000000 },
-    { 0x00000044, 0x00000008 },
-    { 0x00000048, 0x00000008 },
-    { 0x0000004c, 0x00000010 },
-    { 0x00000050, 0x00000000 },
-    { 0x00000054, 0x0000001f },
-    { 0x00000800, 0x00000000 },
-    { 0x00000804, 0x00000000 },
-    { 0x00000808, 0x00000000 },
-    { 0x0000080c, 0x00000000 },
-    { 0x00000810, 0x00000000 },
-    { 0x00000814, 0x00000000 },
-    { 0x00000818, 0x00000000 },
-    { 0x0000081c, 0x00000000 },
-    { 0x00000820, 0x00000000 },
-    { 0x00000824, 0x00000000 },
-    { 0x00001040, 0x002ffc0f },
-    { 0x00001044, 0x002ffc0f },
-    { 0x00001048, 0x002ffc0f },
-    { 0x0000104c, 0x002ffc0f },
-    { 0x00001050, 0x002ffc0f },
-    { 0x00001054, 0x002ffc0f },
-    { 0x00001058, 0x002ffc0f },
-    { 0x0000105c, 0x002ffc0f },
-    { 0x00001060, 0x002ffc0f },
-    { 0x00001064, 0x002ffc0f },
-    { 0x00001230, 0x00000000 },
-    { 0x00001270, 0x00000000 },
-    { 0x00001038, 0x00000000 },
-    { 0x00001078, 0x00000000 },
-    { 0x000010b8, 0x00000000 },
-    { 0x000010f8, 0x00000000 },
-    { 0x00001138, 0x00000000 },
-    { 0x00001178, 0x00000000 },
-    { 0x000011b8, 0x00000000 },
-    { 0x000011f8, 0x00000000 },
-    { 0x00001238, 0x00000000 },
-    { 0x00001278, 0x00000000 },
-    { 0x000012b8, 0x00000000 },
-    { 0x000012f8, 0x00000000 },
-    { 0x00001338, 0x00000000 },
-    { 0x00001378, 0x00000000 },
-    { 0x000013b8, 0x00000000 },
-    { 0x000013f8, 0x00000000 },
-    { 0x00001438, 0x00000000 },
-    { 0x00001478, 0x00000000 },
-    { 0x000014b8, 0x00000000 },
-    { 0x000014f8, 0x00000000 },
-    { 0x00001538, 0x00000000 },
-    { 0x00001578, 0x00000000 },
-    { 0x000015b8, 0x00000000 },
-    { 0x000015f8, 0x00000000 },
-    { 0x00001638, 0x00000000 },
-    { 0x00001678, 0x00000000 },
-    { 0x000016b8, 0x00000000 },
-    { 0x000016f8, 0x00000000 },
-    { 0x00001738, 0x00000000 },
-    { 0x00001778, 0x00000000 },
-    { 0x000017b8, 0x00000000 },
-    { 0x000017f8, 0x00000000 },
-    { 0x0000103c, 0x00000000 },
-    { 0x0000107c, 0x00000000 },
-    { 0x000010bc, 0x00000000 },
-    { 0x000010fc, 0x00000000 },
-    { 0x0000113c, 0x00000000 },
-    { 0x0000117c, 0x00000000 },
-    { 0x000011bc, 0x00000000 },
-    { 0x000011fc, 0x00000000 },
-    { 0x0000123c, 0x00000000 },
-    { 0x0000127c, 0x00000000 },
-    { 0x000012bc, 0x00000000 },
-    { 0x000012fc, 0x00000000 },
-    { 0x0000133c, 0x00000000 },
-    { 0x0000137c, 0x00000000 },
-    { 0x000013bc, 0x00000000 },
-    { 0x000013fc, 0x00000000 },
-    { 0x0000143c, 0x00000000 },
-    { 0x0000147c, 0x00000000 },
-    { 0x00004030, 0x00000002 },
-    { 0x0000403c, 0x00000002 },
-    { 0x00004024, 0x0000001f },
-    { 0x00007010, 0x00000033 },
-    { 0x00007038, 0x000004c2 },
-    { 0x00008004, 0x00000000 },
-    { 0x00008008, 0x00000000 },
-    { 0x0000800c, 0x00000000 },
-    { 0x00008018, 0x00000700 },
-    { 0x00008020, 0x00000000 },
-    { 0x00008038, 0x00000000 },
-    { 0x0000803c, 0x00000000 },
-    { 0x00008048, 0x40000000 },
-    { 0x00008054, 0x00000000 },
-    { 0x00008058, 0x00000000 },
-    { 0x0000805c, 0x000fc78f },
-    { 0x00008060, 0x0000000f },
-    { 0x00008064, 0x00000000 },
-    { 0x00008070, 0x00000000 },
-    { 0x000080c0, 0x2a82301a },
-    { 0x000080c4, 0x05dc01e0 },
-    { 0x000080c8, 0x1f402710 },
-    { 0x000080cc, 0x01f40000 },
-    { 0x000080d0, 0x00001e00 },
-    { 0x000080d4, 0x00000000 },
-    { 0x000080d8, 0x00400000 },
-    { 0x000080e0, 0xffffffff },
-    { 0x000080e4, 0x0000ffff },
-    { 0x000080e8, 0x003f3f3f },
-    { 0x000080ec, 0x00000000 },
-    { 0x000080f0, 0x00000000 },
-    { 0x000080f4, 0x00000000 },
-    { 0x000080f8, 0x00000000 },
-    { 0x000080fc, 0x00020000 },
-    { 0x00008100, 0x00020000 },
-    { 0x00008104, 0x00000001 },
-    { 0x00008108, 0x00000052 },
-    { 0x0000810c, 0x00000000 },
-    { 0x00008110, 0x00000168 },
-    { 0x00008118, 0x000100aa },
-    { 0x0000811c, 0x00003210 },
-    { 0x00008120, 0x08f04800 },
-    { 0x00008124, 0x00000000 },
-    { 0x00008128, 0x00000000 },
-    { 0x0000812c, 0x00000000 },
-    { 0x00008130, 0x00000000 },
-    { 0x00008134, 0x00000000 },
-    { 0x00008138, 0x00000000 },
-    { 0x0000813c, 0x00000000 },
-    { 0x00008144, 0x00000000 },
-    { 0x00008168, 0x00000000 },
-    { 0x0000816c, 0x00000000 },
-    { 0x00008170, 0x32143320 },
-    { 0x00008174, 0xfaa4fa50 },
-    { 0x00008178, 0x00000100 },
-    { 0x0000817c, 0x00000000 },
-    { 0x000081c4, 0x00000000 },
-    { 0x000081d0, 0x00003210 },
-    { 0x000081ec, 0x00000000 },
-    { 0x000081f0, 0x00000000 },
-    { 0x000081f4, 0x00000000 },
-    { 0x000081f8, 0x00000000 },
-    { 0x000081fc, 0x00000000 },
-    { 0x00008200, 0x00000000 },
-    { 0x00008204, 0x00000000 },
-    { 0x00008208, 0x00000000 },
-    { 0x0000820c, 0x00000000 },
-    { 0x00008210, 0x00000000 },
-    { 0x00008214, 0x00000000 },
-    { 0x00008218, 0x00000000 },
-    { 0x0000821c, 0x00000000 },
-    { 0x00008220, 0x00000000 },
-    { 0x00008224, 0x00000000 },
-    { 0x00008228, 0x00000000 },
-    { 0x0000822c, 0x00000000 },
-    { 0x00008230, 0x00000000 },
-    { 0x00008234, 0x00000000 },
-    { 0x00008238, 0x00000000 },
-    { 0x0000823c, 0x00000000 },
-    { 0x00008240, 0x00100000 },
-    { 0x00008244, 0x0010f400 },
-    { 0x00008248, 0x00000100 },
-    { 0x0000824c, 0x0001e800 },
-    { 0x00008250, 0x00000000 },
-    { 0x00008254, 0x00000000 },
-    { 0x00008258, 0x00000000 },
-    { 0x0000825c, 0x400000ff },
-    { 0x00008260, 0x00080922 },
-    { 0x00008270, 0x00000000 },
-    { 0x00008274, 0x40000000 },
-    { 0x00008278, 0x003e4180 },
-    { 0x0000827c, 0x00000000 },
-    { 0x00008284, 0x0000002c },
-    { 0x00008288, 0x0000002c },
-    { 0x0000828c, 0x00000000 },
-    { 0x00008294, 0x00000000 },
-    { 0x00008298, 0x00000000 },
-    { 0x00008300, 0x00000000 },
-    { 0x00008304, 0x00000000 },
-    { 0x00008308, 0x00000000 },
-    { 0x0000830c, 0x00000000 },
-    { 0x00008310, 0x00000000 },
-    { 0x00008314, 0x00000000 },
-    { 0x00008318, 0x00000000 },
-    { 0x00008328, 0x00000000 },
-    { 0x0000832c, 0x00000007 },
-    { 0x00008330, 0x00000302 },
-    { 0x00008334, 0x00000e00 },
-    { 0x00008338, 0x00000000 },
-    { 0x0000833c, 0x00000000 },
-    { 0x00008340, 0x000107ff },
-    { 0x00008344, 0x00000000 },
-    { 0x00009808, 0x00000000 },
-    { 0x0000980c, 0xaf268e30 },
-    { 0x00009810, 0xfd14e000 },
-    { 0x00009814, 0x9c0a9f6b },
-    { 0x0000981c, 0x00000000 },
-    { 0x0000982c, 0x0000a000 },
-    { 0x00009830, 0x00000000 },
-    { 0x0000983c, 0x00200400 },
-    { 0x00009840, 0x206a01ae },
-    { 0x0000984c, 0x0040233c },
-    { 0x0000a84c, 0x0040233c },
-    { 0x00009854, 0x00000044 },
-    { 0x00009900, 0x00000000 },
-    { 0x00009904, 0x00000000 },
-    { 0x00009908, 0x00000000 },
-    { 0x0000990c, 0x00000000 },
-    { 0x0000991c, 0x10000fff },
-    { 0x00009920, 0x04900000 },
-    { 0x0000a920, 0x04900000 },
-    { 0x00009928, 0x00000001 },
-    { 0x0000992c, 0x00000004 },
-    { 0x00009934, 0x1e1f2022 },
-    { 0x00009938, 0x0a0b0c0d },
-    { 0x0000993c, 0x00000000 },
-    { 0x00009948, 0x9280c00a },
-    { 0x0000994c, 0x00020028 },
-    { 0x00009954, 0xe250a51e },
-    { 0x00009958, 0x3388ffff },
-    { 0x00009940, 0x00781204 },
-    { 0x0000c95c, 0x004b6a8e },
-    { 0x0000c968, 0x000003ce },
-    { 0x00009970, 0x190fb514 },
-    { 0x00009974, 0x00000000 },
-    { 0x00009978, 0x00000001 },
-    { 0x0000997c, 0x00000000 },
-    { 0x00009980, 0x00000000 },
-    { 0x00009984, 0x00000000 },
-    { 0x00009988, 0x00000000 },
-    { 0x0000998c, 0x00000000 },
-    { 0x00009990, 0x00000000 },
-    { 0x00009994, 0x00000000 },
-    { 0x00009998, 0x00000000 },
-    { 0x0000999c, 0x00000000 },
-    { 0x000099a0, 0x00000000 },
-    { 0x000099a4, 0x00000001 },
-    { 0x000099a8, 0x201fff00 },
-    { 0x000099ac, 0x006f00c4 },
-    { 0x000099b0, 0x03051000 },
-    { 0x000099b4, 0x00000820 },
-    { 0x000099dc, 0x00000000 },
-    { 0x000099e0, 0x00000000 },
-    { 0x000099e4, 0xaaaaaaaa },
-    { 0x000099e8, 0x3c466478 },
-    { 0x000099ec, 0x0cc80caa },
-    { 0x000099fc, 0x00001042 },
-    { 0x0000a210, 0x4080a333 },
-    { 0x0000a214, 0x40206c10 },
-    { 0x0000a218, 0x009c4060 },
-    { 0x0000a220, 0x01834061 },
-    { 0x0000a224, 0x00000400 },
-    { 0x0000a228, 0x000003b5 },
-    { 0x0000a22c, 0x23277200 },
-    { 0x0000a234, 0x20202020 },
-    { 0x0000a238, 0x20202020 },
-    { 0x0000a23c, 0x13c889af },
-    { 0x0000a240, 0x38490a20 },
-    { 0x0000a244, 0x00007bb6 },
-    { 0x0000a248, 0x0fff3ffc },
-    { 0x0000a24c, 0x00000001 },
-    { 0x0000a250, 0x001da000 },
-    { 0x0000a254, 0x00000000 },
-    { 0x0000a258, 0x0cdbd380 },
-    { 0x0000a25c, 0x0f0f0f01 },
-    { 0x0000a260, 0xdfa91f01 },
-    { 0x0000a268, 0x00000000 },
-    { 0x0000a26c, 0x0ebae9c6 },
-    { 0x0000b26c, 0x0ebae9c6 },
-    { 0x0000d270, 0x00820820 },
-    { 0x0000a278, 0x1ce739ce },
-    { 0x0000a27c, 0x050701ce },
-    { 0x0000a358, 0x7999aa0f },
-    { 0x0000d35c, 0x07ffffef },
-    { 0x0000d360, 0x0fffffe7 },
-    { 0x0000d364, 0x17ffffe5 },
-    { 0x0000d368, 0x1fffffe4 },
-    { 0x0000d36c, 0x37ffffe3 },
-    { 0x0000d370, 0x3fffffe3 },
-    { 0x0000d374, 0x57ffffe3 },
-    { 0x0000d378, 0x5fffffe2 },
-    { 0x0000d37c, 0x7fffffe2 },
-    { 0x0000d380, 0x7f3c7bba },
-    { 0x0000d384, 0xf3307ff0 },
-    { 0x0000a388, 0x0c000000 },
-    { 0x0000a38c, 0x20202020 },
-    { 0x0000a390, 0x20202020 },
-    { 0x0000a394, 0x1ce739ce },
-    { 0x0000a398, 0x000001ce },
-    { 0x0000a39c, 0x00000001 },
-    { 0x0000a3a0, 0x00000000 },
-    { 0x0000a3a4, 0x00000000 },
-    { 0x0000a3a8, 0x00000000 },
-    { 0x0000a3ac, 0x00000000 },
-    { 0x0000a3b0, 0x00000000 },
-    { 0x0000a3b4, 0x00000000 },
-    { 0x0000a3b8, 0x00000000 },
-    { 0x0000a3bc, 0x00000000 },
-    { 0x0000a3c0, 0x00000000 },
-    { 0x0000a3c4, 0x00000000 },
-    { 0x0000a3c8, 0x00000246 },
-    { 0x0000a3cc, 0x20202020 },
-    { 0x0000a3d0, 0x20202020 },
-    { 0x0000a3d4, 0x20202020 },
-    { 0x0000a3dc, 0x1ce739ce },
-    { 0x0000a3e0, 0x000001ce },
-    { 0x0000a3e4, 0x00000000 },
-    { 0x0000a3e8, 0x18c43433 },
-    { 0x0000a3ec, 0x00f38081 },
-    { 0x00007800, 0x00040000 },
-    { 0x00007804, 0xdb005012 },
-    { 0x00007808, 0x04924914 },
-    { 0x0000780c, 0x21084210 },
-    { 0x00007810, 0x6d801300 },
-    { 0x00007814, 0x0019beff },
-    { 0x00007818, 0x07e40000 },
-    { 0x0000781c, 0x00492000 },
-    { 0x00007820, 0x92492480 },
-    { 0x00007824, 0x00040000 },
-    { 0x00007828, 0xdb005012 },
-    { 0x0000782c, 0x04924914 },
-    { 0x00007830, 0x21084210 },
-    { 0x00007834, 0x6d801300 },
-    { 0x00007838, 0x0019beff },
-    { 0x0000783c, 0x07e40000 },
-    { 0x00007840, 0x00492000 },
-    { 0x00007844, 0x92492480 },
-    { 0x00007848, 0x00120000 },
-    { 0x00007850, 0x54214514 },
-    { 0x00007858, 0x92592692 },
-    { 0x00007860, 0x52802000 },
-    { 0x00007864, 0x0a8e370e },
-    { 0x00007868, 0xc0102850 },
-    { 0x0000786c, 0x812d4000 },
-    { 0x00007874, 0x001b6db0 },
-    { 0x00007878, 0x00376b63 },
-    { 0x0000787c, 0x06db6db6 },
-    { 0x00007880, 0x006d8000 },
-    { 0x00007884, 0xffeffffe },
-    { 0x00007888, 0xffeffffe },
-    { 0x00007890, 0x00060aeb },
-    { 0x00007894, 0x5a108000 },
-    { 0x00007898, 0x2a850160 },
-};
-
-/* XXX 9280 2 */
-static const u32 ar9280Modes_9280_2[][6] = {
-    { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
-    { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
-    { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
-    { 0x000010f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008 },
-    { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 },
-    { 0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b, 0x0988004f },
-    { 0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810, 0x08f04810 },
-    { 0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a, 0x0000320a },
-    { 0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440, 0x00006880 },
-    { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 },
-    { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 },
-    { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
-    { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 },
-    { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
-    { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 },
-    { 0x00009840, 0x206a022e, 0x206a022e, 0x206a012e, 0x206a012e, 0x206a012e },
-    { 0x00009844, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0, 0x037216a0 },
-    { 0x00009850, 0x6c4000e2, 0x6c4000e2, 0x6d4000e2, 0x6c4000e2, 0x6c4000e2 },
-    { 0x00009858, 0x7ec88d2e, 0x7ec88d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e },
-    { 0x0000985c, 0x31395d5e, 0x31395d5e, 0x3139605e, 0x31395d5e, 0x31395d5e },
-    { 0x00009860, 0x00048d18, 0x00048d18, 0x00048d20, 0x00048d20, 0x00048d18 },
-    { 0x00009864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 },
-    { 0x00009868, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0 },
-    { 0x0000986c, 0x06903081, 0x06903081, 0x06903881, 0x06903881, 0x06903881 },
-    { 0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0 },
-    { 0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016 },
-    { 0x00009924, 0xd00a8a0b, 0xd00a8a0b, 0xd00a8a0d, 0xd00a8a0d, 0xd00a8a0d },
-    { 0x00009944, 0xffbc1010, 0xffbc1010, 0xffbc1010, 0xffbc1010, 0xffbc1010 },
-    { 0x00009960, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010 },
-    { 0x0000a960, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010 },
-    { 0x00009964, 0x00000210, 0x00000210, 0x00000210, 0x00000210, 0x00000210 },
-    { 0x000099b8, 0x0000001c, 0x0000001c, 0x0000001c, 0x0000001c, 0x0000001c },
-    { 0x000099bc, 0x00000a00, 0x00000a00, 0x00000c00, 0x00000c00, 0x00000c00 },
-    { 0x000099c0, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4 },
-    { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 },
-    { 0x000099c8, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329 },
-    { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 },
-    { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 },
-    { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x0000a204, 0x00000444, 0x00000444, 0x00000444, 0x00000444, 0x00000444 },
-    { 0x0000a20c, 0x00000014, 0x00000014, 0x0001f019, 0x0001f019, 0x0001f019 },
-    { 0x0000b20c, 0x00000014, 0x00000014, 0x0001f019, 0x0001f019, 0x0001f019 },
-    { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a },
-    { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
-    { 0x0000a250, 0x001ff000, 0x001ff000, 0x0004a000, 0x0004a000, 0x0004a000 },
-    { 0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e },
-    { 0x0000a3d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x00007894, 0x5a508000, 0x5a508000, 0x5a508000, 0x5a508000, 0x5a508000 },
-};
-
-static const u32 ar9280Common_9280_2[][2] = {
-    { 0x0000000c, 0x00000000 },
-    { 0x00000030, 0x00020015 },
-    { 0x00000034, 0x00000005 },
-    { 0x00000040, 0x00000000 },
-    { 0x00000044, 0x00000008 },
-    { 0x00000048, 0x00000008 },
-    { 0x0000004c, 0x00000010 },
-    { 0x00000050, 0x00000000 },
-    { 0x00000054, 0x0000001f },
-    { 0x00000800, 0x00000000 },
-    { 0x00000804, 0x00000000 },
-    { 0x00000808, 0x00000000 },
-    { 0x0000080c, 0x00000000 },
-    { 0x00000810, 0x00000000 },
-    { 0x00000814, 0x00000000 },
-    { 0x00000818, 0x00000000 },
-    { 0x0000081c, 0x00000000 },
-    { 0x00000820, 0x00000000 },
-    { 0x00000824, 0x00000000 },
-    { 0x00001040, 0x002ffc0f },
-    { 0x00001044, 0x002ffc0f },
-    { 0x00001048, 0x002ffc0f },
-    { 0x0000104c, 0x002ffc0f },
-    { 0x00001050, 0x002ffc0f },
-    { 0x00001054, 0x002ffc0f },
-    { 0x00001058, 0x002ffc0f },
-    { 0x0000105c, 0x002ffc0f },
-    { 0x00001060, 0x002ffc0f },
-    { 0x00001064, 0x002ffc0f },
-    { 0x00001230, 0x00000000 },
-    { 0x00001270, 0x00000000 },
-    { 0x00001038, 0x00000000 },
-    { 0x00001078, 0x00000000 },
-    { 0x000010b8, 0x00000000 },
-    { 0x000010f8, 0x00000000 },
-    { 0x00001138, 0x00000000 },
-    { 0x00001178, 0x00000000 },
-    { 0x000011b8, 0x00000000 },
-    { 0x000011f8, 0x00000000 },
-    { 0x00001238, 0x00000000 },
-    { 0x00001278, 0x00000000 },
-    { 0x000012b8, 0x00000000 },
-    { 0x000012f8, 0x00000000 },
-    { 0x00001338, 0x00000000 },
-    { 0x00001378, 0x00000000 },
-    { 0x000013b8, 0x00000000 },
-    { 0x000013f8, 0x00000000 },
-    { 0x00001438, 0x00000000 },
-    { 0x00001478, 0x00000000 },
-    { 0x000014b8, 0x00000000 },
-    { 0x000014f8, 0x00000000 },
-    { 0x00001538, 0x00000000 },
-    { 0x00001578, 0x00000000 },
-    { 0x000015b8, 0x00000000 },
-    { 0x000015f8, 0x00000000 },
-    { 0x00001638, 0x00000000 },
-    { 0x00001678, 0x00000000 },
-    { 0x000016b8, 0x00000000 },
-    { 0x000016f8, 0x00000000 },
-    { 0x00001738, 0x00000000 },
-    { 0x00001778, 0x00000000 },
-    { 0x000017b8, 0x00000000 },
-    { 0x000017f8, 0x00000000 },
-    { 0x0000103c, 0x00000000 },
-    { 0x0000107c, 0x00000000 },
-    { 0x000010bc, 0x00000000 },
-    { 0x000010fc, 0x00000000 },
-    { 0x0000113c, 0x00000000 },
-    { 0x0000117c, 0x00000000 },
-    { 0x000011bc, 0x00000000 },
-    { 0x000011fc, 0x00000000 },
-    { 0x0000123c, 0x00000000 },
-    { 0x0000127c, 0x00000000 },
-    { 0x000012bc, 0x00000000 },
-    { 0x000012fc, 0x00000000 },
-    { 0x0000133c, 0x00000000 },
-    { 0x0000137c, 0x00000000 },
-    { 0x000013bc, 0x00000000 },
-    { 0x000013fc, 0x00000000 },
-    { 0x0000143c, 0x00000000 },
-    { 0x0000147c, 0x00000000 },
-    { 0x00004030, 0x00000002 },
-    { 0x0000403c, 0x00000002 },
-    { 0x00004024, 0x0000001f },
-    { 0x00004060, 0x00000000 },
-    { 0x00004064, 0x00000000 },
-    { 0x00007010, 0x00000033 },
-    { 0x00007034, 0x00000002 },
-    { 0x00007038, 0x000004c2 },
-    { 0x00008004, 0x00000000 },
-    { 0x00008008, 0x00000000 },
-    { 0x0000800c, 0x00000000 },
-    { 0x00008018, 0x00000700 },
-    { 0x00008020, 0x00000000 },
-    { 0x00008038, 0x00000000 },
-    { 0x0000803c, 0x00000000 },
-    { 0x00008048, 0x40000000 },
-    { 0x00008054, 0x00000000 },
-    { 0x00008058, 0x00000000 },
-    { 0x0000805c, 0x000fc78f },
-    { 0x00008060, 0x0000000f },
-    { 0x00008064, 0x00000000 },
-    { 0x00008070, 0x00000000 },
-    { 0x000080c0, 0x2a80001a },
-    { 0x000080c4, 0x05dc01e0 },
-    { 0x000080c8, 0x1f402710 },
-    { 0x000080cc, 0x01f40000 },
-    { 0x000080d0, 0x00001e00 },
-    { 0x000080d4, 0x00000000 },
-    { 0x000080d8, 0x00400000 },
-    { 0x000080e0, 0xffffffff },
-    { 0x000080e4, 0x0000ffff },
-    { 0x000080e8, 0x003f3f3f },
-    { 0x000080ec, 0x00000000 },
-    { 0x000080f0, 0x00000000 },
-    { 0x000080f4, 0x00000000 },
-    { 0x000080f8, 0x00000000 },
-    { 0x000080fc, 0x00020000 },
-    { 0x00008100, 0x00020000 },
-    { 0x00008104, 0x00000001 },
-    { 0x00008108, 0x00000052 },
-    { 0x0000810c, 0x00000000 },
-    { 0x00008110, 0x00000168 },
-    { 0x00008118, 0x000100aa },
-    { 0x0000811c, 0x00003210 },
-    { 0x00008124, 0x00000000 },
-    { 0x00008128, 0x00000000 },
-    { 0x0000812c, 0x00000000 },
-    { 0x00008130, 0x00000000 },
-    { 0x00008134, 0x00000000 },
-    { 0x00008138, 0x00000000 },
-    { 0x0000813c, 0x00000000 },
-    { 0x00008144, 0xffffffff },
-    { 0x00008168, 0x00000000 },
-    { 0x0000816c, 0x00000000 },
-    { 0x00008170, 0x32143320 },
-    { 0x00008174, 0xfaa4fa50 },
-    { 0x00008178, 0x00000100 },
-    { 0x0000817c, 0x00000000 },
-    { 0x000081c0, 0x00000000 },
-    { 0x000081ec, 0x00000000 },
-    { 0x000081f0, 0x00000000 },
-    { 0x000081f4, 0x00000000 },
-    { 0x000081f8, 0x00000000 },
-    { 0x000081fc, 0x00000000 },
-    { 0x00008200, 0x00000000 },
-    { 0x00008204, 0x00000000 },
-    { 0x00008208, 0x00000000 },
-    { 0x0000820c, 0x00000000 },
-    { 0x00008210, 0x00000000 },
-    { 0x00008214, 0x00000000 },
-    { 0x00008218, 0x00000000 },
-    { 0x0000821c, 0x00000000 },
-    { 0x00008220, 0x00000000 },
-    { 0x00008224, 0x00000000 },
-    { 0x00008228, 0x00000000 },
-    { 0x0000822c, 0x00000000 },
-    { 0x00008230, 0x00000000 },
-    { 0x00008234, 0x00000000 },
-    { 0x00008238, 0x00000000 },
-    { 0x0000823c, 0x00000000 },
-    { 0x00008240, 0x00100000 },
-    { 0x00008244, 0x0010f400 },
-    { 0x00008248, 0x00000100 },
-    { 0x0000824c, 0x0001e800 },
-    { 0x00008250, 0x00000000 },
-    { 0x00008254, 0x00000000 },
-    { 0x00008258, 0x00000000 },
-    { 0x0000825c, 0x400000ff },
-    { 0x00008260, 0x00080922 },
-    { 0x00008264, 0xa8a00010 },
-    { 0x00008270, 0x00000000 },
-    { 0x00008274, 0x40000000 },
-    { 0x00008278, 0x003e4180 },
-    { 0x0000827c, 0x00000000 },
-    { 0x00008284, 0x0000002c },
-    { 0x00008288, 0x0000002c },
-    { 0x0000828c, 0x00000000 },
-    { 0x00008294, 0x00000000 },
-    { 0x00008298, 0x00000000 },
-    { 0x0000829c, 0x00000000 },
-    { 0x00008300, 0x00000040 },
-    { 0x00008314, 0x00000000 },
-    { 0x00008328, 0x00000000 },
-    { 0x0000832c, 0x00000007 },
-    { 0x00008330, 0x00000302 },
-    { 0x00008334, 0x00000e00 },
-    { 0x00008338, 0x00ff0000 },
-    { 0x0000833c, 0x00000000 },
-    { 0x00008340, 0x000107ff },
-    { 0x00008344, 0x00581043 },
-    { 0x00009808, 0x00000000 },
-    { 0x0000980c, 0xafa68e30 },
-    { 0x00009810, 0xfd14e000 },
-    { 0x00009814, 0x9c0a9f6b },
-    { 0x0000981c, 0x00000000 },
-    { 0x0000982c, 0x0000a000 },
-    { 0x00009830, 0x00000000 },
-    { 0x0000983c, 0x00200400 },
-    { 0x0000984c, 0x0040233c },
-    { 0x0000a84c, 0x0040233c },
-    { 0x00009854, 0x00000044 },
-    { 0x00009900, 0x00000000 },
-    { 0x00009904, 0x00000000 },
-    { 0x00009908, 0x00000000 },
-    { 0x0000990c, 0x00000000 },
-    { 0x00009910, 0x01002310 },
-    { 0x0000991c, 0x10000fff },
-    { 0x00009920, 0x04900000 },
-    { 0x0000a920, 0x04900000 },
-    { 0x00009928, 0x00000001 },
-    { 0x0000992c, 0x00000004 },
-    { 0x00009934, 0x1e1f2022 },
-    { 0x00009938, 0x0a0b0c0d },
-    { 0x0000993c, 0x00000000 },
-    { 0x00009948, 0x9280c00a },
-    { 0x0000994c, 0x00020028 },
-    { 0x00009954, 0x5f3ca3de },
-    { 0x00009958, 0x2108ecff },
-    { 0x00009940, 0x14750604 },
-    { 0x0000c95c, 0x004b6a8e },
-    { 0x0000c968, 0x000003ce },
-    { 0x00009970, 0x190fb515 },
-    { 0x00009974, 0x00000000 },
-    { 0x00009978, 0x00000001 },
-    { 0x0000997c, 0x00000000 },
-    { 0x00009980, 0x00000000 },
-    { 0x00009984, 0x00000000 },
-    { 0x00009988, 0x00000000 },
-    { 0x0000998c, 0x00000000 },
-    { 0x00009990, 0x00000000 },
-    { 0x00009994, 0x00000000 },
-    { 0x00009998, 0x00000000 },
-    { 0x0000999c, 0x00000000 },
-    { 0x000099a0, 0x00000000 },
-    { 0x000099a4, 0x00000001 },
-    { 0x000099a8, 0x201fff00 },
-    { 0x000099ac, 0x006f0000 },
-    { 0x000099b0, 0x03051000 },
-    { 0x000099b4, 0x00000820 },
-    { 0x000099dc, 0x00000000 },
-    { 0x000099e0, 0x00000000 },
-    { 0x000099e4, 0xaaaaaaaa },
-    { 0x000099e8, 0x3c466478 },
-    { 0x000099ec, 0x0cc80caa },
-    { 0x000099f0, 0x00000000 },
-    { 0x000099fc, 0x00001042 },
-    { 0x0000a208, 0x803e4788 },
-    { 0x0000a210, 0x4080a333 },
-    { 0x0000a214, 0x40206c10 },
-    { 0x0000a218, 0x009c4060 },
-    { 0x0000a220, 0x01834061 },
-    { 0x0000a224, 0x00000400 },
-    { 0x0000a228, 0x000003b5 },
-    { 0x0000a22c, 0x233f7180 },
-    { 0x0000a234, 0x20202020 },
-    { 0x0000a238, 0x20202020 },
-    { 0x0000a23c, 0x13c88000 },
-    { 0x0000a240, 0x38490a20 },
-    { 0x0000a244, 0x00007bb6 },
-    { 0x0000a248, 0x0fff3ffc },
-    { 0x0000a24c, 0x00000000 },
-    { 0x0000a254, 0x00000000 },
-    { 0x0000a258, 0x0cdbd380 },
-    { 0x0000a25c, 0x0f0f0f01 },
-    { 0x0000a260, 0xdfa91f01 },
-    { 0x0000a268, 0x00000000 },
-    { 0x0000a26c, 0x0ebae9c6 },
-    { 0x0000b26c, 0x0ebae9c6 },
-    { 0x0000d270, 0x00820820 },
-    { 0x0000a278, 0x1ce739ce },
-    { 0x0000d35c, 0x07ffffef },
-    { 0x0000d360, 0x0fffffe7 },
-    { 0x0000d364, 0x17ffffe5 },
-    { 0x0000d368, 0x1fffffe4 },
-    { 0x0000d36c, 0x37ffffe3 },
-    { 0x0000d370, 0x3fffffe3 },
-    { 0x0000d374, 0x57ffffe3 },
-    { 0x0000d378, 0x5fffffe2 },
-    { 0x0000d37c, 0x7fffffe2 },
-    { 0x0000d380, 0x7f3c7bba },
-    { 0x0000d384, 0xf3307ff0 },
-    { 0x0000a388, 0x0c000000 },
-    { 0x0000a38c, 0x20202020 },
-    { 0x0000a390, 0x20202020 },
-    { 0x0000a394, 0x1ce739ce },
-    { 0x0000a398, 0x000001ce },
-    { 0x0000a39c, 0x00000001 },
-    { 0x0000a3a0, 0x00000000 },
-    { 0x0000a3a4, 0x00000000 },
-    { 0x0000a3a8, 0x00000000 },
-    { 0x0000a3ac, 0x00000000 },
-    { 0x0000a3b0, 0x00000000 },
-    { 0x0000a3b4, 0x00000000 },
-    { 0x0000a3b8, 0x00000000 },
-    { 0x0000a3bc, 0x00000000 },
-    { 0x0000a3c0, 0x00000000 },
-    { 0x0000a3c4, 0x00000000 },
-    { 0x0000a3c8, 0x00000246 },
-    { 0x0000a3cc, 0x20202020 },
-    { 0x0000a3d0, 0x20202020 },
-    { 0x0000a3d4, 0x20202020 },
-    { 0x0000a3dc, 0x1ce739ce },
-    { 0x0000a3e0, 0x000001ce },
-    { 0x0000a3e4, 0x00000000 },
-    { 0x0000a3e8, 0x18c43433 },
-    { 0x0000a3ec, 0x00f70081 },
-    { 0x00007800, 0x00040000 },
-    { 0x00007804, 0xdb005012 },
-    { 0x00007808, 0x04924914 },
-    { 0x0000780c, 0x21084210 },
-    { 0x00007810, 0x6d801300 },
-    { 0x00007818, 0x07e41000 },
-    { 0x00007824, 0x00040000 },
-    { 0x00007828, 0xdb005012 },
-    { 0x0000782c, 0x04924914 },
-    { 0x00007830, 0x21084210 },
-    { 0x00007834, 0x6d801300 },
-    { 0x0000783c, 0x07e40000 },
-    { 0x00007848, 0x00100000 },
-    { 0x0000784c, 0x773f0567 },
-    { 0x00007850, 0x54214514 },
-    { 0x00007854, 0x12035828 },
-    { 0x00007858, 0x9259269a },
-    { 0x00007860, 0x52802000 },
-    { 0x00007864, 0x0a8e370e },
-    { 0x00007868, 0xc0102850 },
-    { 0x0000786c, 0x812d4000 },
-    { 0x00007870, 0x807ec400 },
-    { 0x00007874, 0x001b6db0 },
-    { 0x00007878, 0x00376b63 },
-    { 0x0000787c, 0x06db6db6 },
-    { 0x00007880, 0x006d8000 },
-    { 0x00007884, 0xffeffffe },
-    { 0x00007888, 0xffeffffe },
-    { 0x0000788c, 0x00010000 },
-    { 0x00007890, 0x02060aeb },
-    { 0x00007898, 0x2a850160 },
-};
-
-static const u32 ar9280Modes_fast_clock_9280_2[][3] = {
-    { 0x00001030, 0x00000268, 0x000004d0 },
-    { 0x00001070, 0x0000018c, 0x00000318 },
-    { 0x000010b0, 0x00000fd0, 0x00001fa0 },
-    { 0x00008014, 0x044c044c, 0x08980898 },
-    { 0x0000801c, 0x148ec02b, 0x148ec057 },
-    { 0x00008318, 0x000044c0, 0x00008980 },
-    { 0x00009820, 0x02020200, 0x02020200 },
-    { 0x00009824, 0x00000f0f, 0x00000f0f },
-    { 0x00009828, 0x0b020001, 0x0b020001 },
-    { 0x00009834, 0x00000f0f, 0x00000f0f },
-    { 0x00009844, 0x03721821, 0x03721821 },
-    { 0x00009914, 0x00000898, 0x00001130 },
-    { 0x00009918, 0x0000000b, 0x00000016 },
-};
-
-static const u32 ar9280Modes_backoff_23db_rxgain_9280_2[][6] = {
-    { 0x00009a00, 0x00008184, 0x00008184, 0x00000290, 0x00000290, 0x00000290 },
-    { 0x00009a04, 0x00008188, 0x00008188, 0x00000300, 0x00000300, 0x00000300 },
-    { 0x00009a08, 0x0000818c, 0x0000818c, 0x00000304, 0x00000304, 0x00000304 },
-    { 0x00009a0c, 0x00008190, 0x00008190, 0x00000308, 0x00000308, 0x00000308 },
-    { 0x00009a10, 0x00008194, 0x00008194, 0x0000030c, 0x0000030c, 0x0000030c },
-    { 0x00009a14, 0x00008200, 0x00008200, 0x00008000, 0x00008000, 0x00008000 },
-    { 0x00009a18, 0x00008204, 0x00008204, 0x00008004, 0x00008004, 0x00008004 },
-    { 0x00009a1c, 0x00008208, 0x00008208, 0x00008008, 0x00008008, 0x00008008 },
-    { 0x00009a20, 0x0000820c, 0x0000820c, 0x0000800c, 0x0000800c, 0x0000800c },
-    { 0x00009a24, 0x00008210, 0x00008210, 0x00008080, 0x00008080, 0x00008080 },
-    { 0x00009a28, 0x00008214, 0x00008214, 0x00008084, 0x00008084, 0x00008084 },
-    { 0x00009a2c, 0x00008280, 0x00008280, 0x00008088, 0x00008088, 0x00008088 },
-    { 0x00009a30, 0x00008284, 0x00008284, 0x0000808c, 0x0000808c, 0x0000808c },
-    { 0x00009a34, 0x00008288, 0x00008288, 0x00008100, 0x00008100, 0x00008100 },
-    { 0x00009a38, 0x0000828c, 0x0000828c, 0x00008104, 0x00008104, 0x00008104 },
-    { 0x00009a3c, 0x00008290, 0x00008290, 0x00008108, 0x00008108, 0x00008108 },
-    { 0x00009a40, 0x00008300, 0x00008300, 0x0000810c, 0x0000810c, 0x0000810c },
-    { 0x00009a44, 0x00008304, 0x00008304, 0x00008110, 0x00008110, 0x00008110 },
-    { 0x00009a48, 0x00008308, 0x00008308, 0x00008114, 0x00008114, 0x00008114 },
-    { 0x00009a4c, 0x0000830c, 0x0000830c, 0x00008180, 0x00008180, 0x00008180 },
-    { 0x00009a50, 0x00008310, 0x00008310, 0x00008184, 0x00008184, 0x00008184 },
-    { 0x00009a54, 0x00008314, 0x00008314, 0x00008188, 0x00008188, 0x00008188 },
-    { 0x00009a58, 0x00008380, 0x00008380, 0x0000818c, 0x0000818c, 0x0000818c },
-    { 0x00009a5c, 0x00008384, 0x00008384, 0x00008190, 0x00008190, 0x00008190 },
-    { 0x00009a60, 0x00008388, 0x00008388, 0x00008194, 0x00008194, 0x00008194 },
-    { 0x00009a64, 0x0000838c, 0x0000838c, 0x000081a0, 0x000081a0, 0x000081a0 },
-    { 0x00009a68, 0x00008390, 0x00008390, 0x0000820c, 0x0000820c, 0x0000820c },
-    { 0x00009a6c, 0x00008394, 0x00008394, 0x000081a8, 0x000081a8, 0x000081a8 },
-    { 0x00009a70, 0x0000a380, 0x0000a380, 0x00008284, 0x00008284, 0x00008284 },
-    { 0x00009a74, 0x0000a384, 0x0000a384, 0x00008288, 0x00008288, 0x00008288 },
-    { 0x00009a78, 0x0000a388, 0x0000a388, 0x00008224, 0x00008224, 0x00008224 },
-    { 0x00009a7c, 0x0000a38c, 0x0000a38c, 0x00008290, 0x00008290, 0x00008290 },
-    { 0x00009a80, 0x0000a390, 0x0000a390, 0x00008300, 0x00008300, 0x00008300 },
-    { 0x00009a84, 0x0000a394, 0x0000a394, 0x00008304, 0x00008304, 0x00008304 },
-    { 0x00009a88, 0x0000a780, 0x0000a780, 0x00008308, 0x00008308, 0x00008308 },
-    { 0x00009a8c, 0x0000a784, 0x0000a784, 0x0000830c, 0x0000830c, 0x0000830c },
-    { 0x00009a90, 0x0000a788, 0x0000a788, 0x00008380, 0x00008380, 0x00008380 },
-    { 0x00009a94, 0x0000a78c, 0x0000a78c, 0x00008384, 0x00008384, 0x00008384 },
-    { 0x00009a98, 0x0000a790, 0x0000a790, 0x00008700, 0x00008700, 0x00008700 },
-    { 0x00009a9c, 0x0000a794, 0x0000a794, 0x00008704, 0x00008704, 0x00008704 },
-    { 0x00009aa0, 0x0000ab84, 0x0000ab84, 0x00008708, 0x00008708, 0x00008708 },
-    { 0x00009aa4, 0x0000ab88, 0x0000ab88, 0x0000870c, 0x0000870c, 0x0000870c },
-    { 0x00009aa8, 0x0000ab8c, 0x0000ab8c, 0x00008780, 0x00008780, 0x00008780 },
-    { 0x00009aac, 0x0000ab90, 0x0000ab90, 0x00008784, 0x00008784, 0x00008784 },
-    { 0x00009ab0, 0x0000ab94, 0x0000ab94, 0x00008b00, 0x00008b00, 0x00008b00 },
-    { 0x00009ab4, 0x0000af80, 0x0000af80, 0x00008b04, 0x00008b04, 0x00008b04 },
-    { 0x00009ab8, 0x0000af84, 0x0000af84, 0x00008b08, 0x00008b08, 0x00008b08 },
-    { 0x00009abc, 0x0000af88, 0x0000af88, 0x00008b0c, 0x00008b0c, 0x00008b0c },
-    { 0x00009ac0, 0x0000af8c, 0x0000af8c, 0x00008b10, 0x00008b10, 0x00008b10 },
-    { 0x00009ac4, 0x0000af90, 0x0000af90, 0x00008b14, 0x00008b14, 0x00008b14 },
-    { 0x00009ac8, 0x0000af94, 0x0000af94, 0x00008b01, 0x00008b01, 0x00008b01 },
-    { 0x00009acc, 0x0000b380, 0x0000b380, 0x00008b05, 0x00008b05, 0x00008b05 },
-    { 0x00009ad0, 0x0000b384, 0x0000b384, 0x00008b09, 0x00008b09, 0x00008b09 },
-    { 0x00009ad4, 0x0000b388, 0x0000b388, 0x00008b0d, 0x00008b0d, 0x00008b0d },
-    { 0x00009ad8, 0x0000b38c, 0x0000b38c, 0x00008b11, 0x00008b11, 0x00008b11 },
-    { 0x00009adc, 0x0000b390, 0x0000b390, 0x00008b15, 0x00008b15, 0x00008b15 },
-    { 0x00009ae0, 0x0000b394, 0x0000b394, 0x00008b02, 0x00008b02, 0x00008b02 },
-    { 0x00009ae4, 0x0000b398, 0x0000b398, 0x00008b06, 0x00008b06, 0x00008b06 },
-    { 0x00009ae8, 0x0000b780, 0x0000b780, 0x00008b0a, 0x00008b0a, 0x00008b0a },
-    { 0x00009aec, 0x0000b784, 0x0000b784, 0x00008b0e, 0x00008b0e, 0x00008b0e },
-    { 0x00009af0, 0x0000b788, 0x0000b788, 0x00008b12, 0x00008b12, 0x00008b12 },
-    { 0x00009af4, 0x0000b78c, 0x0000b78c, 0x00008b16, 0x00008b16, 0x00008b16 },
-    { 0x00009af8, 0x0000b790, 0x0000b790, 0x00008b03, 0x00008b03, 0x00008b03 },
-    { 0x00009afc, 0x0000b794, 0x0000b794, 0x00008b07, 0x00008b07, 0x00008b07 },
-    { 0x00009b00, 0x0000b798, 0x0000b798, 0x00008b0b, 0x00008b0b, 0x00008b0b },
-    { 0x00009b04, 0x0000d784, 0x0000d784, 0x00008b0f, 0x00008b0f, 0x00008b0f },
-    { 0x00009b08, 0x0000d788, 0x0000d788, 0x00008b13, 0x00008b13, 0x00008b13 },
-    { 0x00009b0c, 0x0000d78c, 0x0000d78c, 0x00008b17, 0x00008b17, 0x00008b17 },
-    { 0x00009b10, 0x0000d790, 0x0000d790, 0x00008b23, 0x00008b23, 0x00008b23 },
-    { 0x00009b14, 0x0000f780, 0x0000f780, 0x00008b27, 0x00008b27, 0x00008b27 },
-    { 0x00009b18, 0x0000f784, 0x0000f784, 0x00008b2b, 0x00008b2b, 0x00008b2b },
-    { 0x00009b1c, 0x0000f788, 0x0000f788, 0x00008b2f, 0x00008b2f, 0x00008b2f },
-    { 0x00009b20, 0x0000f78c, 0x0000f78c, 0x00008b33, 0x00008b33, 0x00008b33 },
-    { 0x00009b24, 0x0000f790, 0x0000f790, 0x00008b37, 0x00008b37, 0x00008b37 },
-    { 0x00009b28, 0x0000f794, 0x0000f794, 0x00008b43, 0x00008b43, 0x00008b43 },
-    { 0x00009b2c, 0x0000f7a4, 0x0000f7a4, 0x00008b47, 0x00008b47, 0x00008b47 },
-    { 0x00009b30, 0x0000f7a8, 0x0000f7a8, 0x00008b4b, 0x00008b4b, 0x00008b4b },
-    { 0x00009b34, 0x0000f7ac, 0x0000f7ac, 0x00008b4f, 0x00008b4f, 0x00008b4f },
-    { 0x00009b38, 0x0000f7b0, 0x0000f7b0, 0x00008b53, 0x00008b53, 0x00008b53 },
-    { 0x00009b3c, 0x0000f7b4, 0x0000f7b4, 0x00008b57, 0x00008b57, 0x00008b57 },
-    { 0x00009b40, 0x0000f7a1, 0x0000f7a1, 0x00008b5b, 0x00008b5b, 0x00008b5b },
-    { 0x00009b44, 0x0000f7a5, 0x0000f7a5, 0x00008b5b, 0x00008b5b, 0x00008b5b },
-    { 0x00009b48, 0x0000f7a9, 0x0000f7a9, 0x00008b5b, 0x00008b5b, 0x00008b5b },
-    { 0x00009b4c, 0x0000f7ad, 0x0000f7ad, 0x00008b5b, 0x00008b5b, 0x00008b5b },
-    { 0x00009b50, 0x0000f7b1, 0x0000f7b1, 0x00008b5b, 0x00008b5b, 0x00008b5b },
-    { 0x00009b54, 0x0000f7b5, 0x0000f7b5, 0x00008b5b, 0x00008b5b, 0x00008b5b },
-    { 0x00009b58, 0x0000f7c5, 0x0000f7c5, 0x00008b5b, 0x00008b5b, 0x00008b5b },
-    { 0x00009b5c, 0x0000f7c9, 0x0000f7c9, 0x00008b5b, 0x00008b5b, 0x00008b5b },
-    { 0x00009b60, 0x0000f7cd, 0x0000f7cd, 0x00008b5b, 0x00008b5b, 0x00008b5b },
-    { 0x00009b64, 0x0000f7d1, 0x0000f7d1, 0x00008b5b, 0x00008b5b, 0x00008b5b },
-    { 0x00009b68, 0x0000f7d5, 0x0000f7d5, 0x00008b5b, 0x00008b5b, 0x00008b5b },
-    { 0x00009b6c, 0x0000f7c2, 0x0000f7c2, 0x00008b5b, 0x00008b5b, 0x00008b5b },
-    { 0x00009b70, 0x0000f7c6, 0x0000f7c6, 0x00008b5b, 0x00008b5b, 0x00008b5b },
-    { 0x00009b74, 0x0000f7ca, 0x0000f7ca, 0x00008b5b, 0x00008b5b, 0x00008b5b },
-    { 0x00009b78, 0x0000f7ce, 0x0000f7ce, 0x00008b5b, 0x00008b5b, 0x00008b5b },
-    { 0x00009b7c, 0x0000f7d2, 0x0000f7d2, 0x00008b5b, 0x00008b5b, 0x00008b5b },
-    { 0x00009b80, 0x0000f7d6, 0x0000f7d6, 0x00008b5b, 0x00008b5b, 0x00008b5b },
-    { 0x00009b84, 0x0000f7c3, 0x0000f7c3, 0x00008b5b, 0x00008b5b, 0x00008b5b },
-    { 0x00009b88, 0x0000f7c7, 0x0000f7c7, 0x00008b5b, 0x00008b5b, 0x00008b5b },
-    { 0x00009b8c, 0x0000f7cb, 0x0000f7cb, 0x00008b5b, 0x00008b5b, 0x00008b5b },
-    { 0x00009b90, 0x0000f7d3, 0x0000f7d3, 0x00008b5b, 0x00008b5b, 0x00008b5b },
-    { 0x00009b94, 0x0000f7d7, 0x0000f7d7, 0x00008b5b, 0x00008b5b, 0x00008b5b },
-    { 0x00009b98, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b },
-    { 0x00009b9c, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b },
-    { 0x00009ba0, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b },
-    { 0x00009ba4, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b },
-    { 0x00009ba8, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b },
-    { 0x00009bac, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b },
-    { 0x00009bb0, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b },
-    { 0x00009bb4, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b },
-    { 0x00009bb8, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b },
-    { 0x00009bbc, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b },
-    { 0x00009bc0, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b },
-    { 0x00009bc4, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b },
-    { 0x00009bc8, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b },
-    { 0x00009bcc, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b },
-    { 0x00009bd0, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b },
-    { 0x00009bd4, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b },
-    { 0x00009bd8, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b },
-    { 0x00009bdc, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b },
-    { 0x00009be0, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b },
-    { 0x00009be4, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b },
-    { 0x00009be8, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b },
-    { 0x00009bec, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b },
-    { 0x00009bf0, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b },
-    { 0x00009bf4, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b },
-    { 0x00009bf8, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b },
-    { 0x00009bfc, 0x0000f7db, 0x0000f7db, 0x00008b5b, 0x00008b5b, 0x00008b5b },
-    { 0x00009848, 0x00001066, 0x00001066, 0x00001050, 0x00001050, 0x00001050 },
-    { 0x0000a848, 0x00001066, 0x00001066, 0x00001050, 0x00001050, 0x00001050 },
-};
-
-static const u32 ar9280Modes_original_rxgain_9280_2[][6] = {
-    { 0x00009a00, 0x00008184, 0x00008184, 0x00000290, 0x00000290, 0x00000290 },
-    { 0x00009a04, 0x00008188, 0x00008188, 0x00000300, 0x00000300, 0x00000300 },
-    { 0x00009a08, 0x0000818c, 0x0000818c, 0x00000304, 0x00000304, 0x00000304 },
-    { 0x00009a0c, 0x00008190, 0x00008190, 0x00000308, 0x00000308, 0x00000308 },
-    { 0x00009a10, 0x00008194, 0x00008194, 0x0000030c, 0x0000030c, 0x0000030c },
-    { 0x00009a14, 0x00008200, 0x00008200, 0x00008000, 0x00008000, 0x00008000 },
-    { 0x00009a18, 0x00008204, 0x00008204, 0x00008004, 0x00008004, 0x00008004 },
-    { 0x00009a1c, 0x00008208, 0x00008208, 0x00008008, 0x00008008, 0x00008008 },
-    { 0x00009a20, 0x0000820c, 0x0000820c, 0x0000800c, 0x0000800c, 0x0000800c },
-    { 0x00009a24, 0x00008210, 0x00008210, 0x00008080, 0x00008080, 0x00008080 },
-    { 0x00009a28, 0x00008214, 0x00008214, 0x00008084, 0x00008084, 0x00008084 },
-    { 0x00009a2c, 0x00008280, 0x00008280, 0x00008088, 0x00008088, 0x00008088 },
-    { 0x00009a30, 0x00008284, 0x00008284, 0x0000808c, 0x0000808c, 0x0000808c },
-    { 0x00009a34, 0x00008288, 0x00008288, 0x00008100, 0x00008100, 0x00008100 },
-    { 0x00009a38, 0x0000828c, 0x0000828c, 0x00008104, 0x00008104, 0x00008104 },
-    { 0x00009a3c, 0x00008290, 0x00008290, 0x00008108, 0x00008108, 0x00008108 },
-    { 0x00009a40, 0x00008300, 0x00008300, 0x0000810c, 0x0000810c, 0x0000810c },
-    { 0x00009a44, 0x00008304, 0x00008304, 0x00008110, 0x00008110, 0x00008110 },
-    { 0x00009a48, 0x00008308, 0x00008308, 0x00008114, 0x00008114, 0x00008114 },
-    { 0x00009a4c, 0x0000830c, 0x0000830c, 0x00008180, 0x00008180, 0x00008180 },
-    { 0x00009a50, 0x00008310, 0x00008310, 0x00008184, 0x00008184, 0x00008184 },
-    { 0x00009a54, 0x00008314, 0x00008314, 0x00008188, 0x00008188, 0x00008188 },
-    { 0x00009a58, 0x00008380, 0x00008380, 0x0000818c, 0x0000818c, 0x0000818c },
-    { 0x00009a5c, 0x00008384, 0x00008384, 0x00008190, 0x00008190, 0x00008190 },
-    { 0x00009a60, 0x00008388, 0x00008388, 0x00008194, 0x00008194, 0x00008194 },
-    { 0x00009a64, 0x0000838c, 0x0000838c, 0x000081a0, 0x000081a0, 0x000081a0 },
-    { 0x00009a68, 0x00008390, 0x00008390, 0x0000820c, 0x0000820c, 0x0000820c },
-    { 0x00009a6c, 0x00008394, 0x00008394, 0x000081a8, 0x000081a8, 0x000081a8 },
-    { 0x00009a70, 0x0000a380, 0x0000a380, 0x00008284, 0x00008284, 0x00008284 },
-    { 0x00009a74, 0x0000a384, 0x0000a384, 0x00008288, 0x00008288, 0x00008288 },
-    { 0x00009a78, 0x0000a388, 0x0000a388, 0x00008224, 0x00008224, 0x00008224 },
-    { 0x00009a7c, 0x0000a38c, 0x0000a38c, 0x00008290, 0x00008290, 0x00008290 },
-    { 0x00009a80, 0x0000a390, 0x0000a390, 0x00008300, 0x00008300, 0x00008300 },
-    { 0x00009a84, 0x0000a394, 0x0000a394, 0x00008304, 0x00008304, 0x00008304 },
-    { 0x00009a88, 0x0000a780, 0x0000a780, 0x00008308, 0x00008308, 0x00008308 },
-    { 0x00009a8c, 0x0000a784, 0x0000a784, 0x0000830c, 0x0000830c, 0x0000830c },
-    { 0x00009a90, 0x0000a788, 0x0000a788, 0x00008380, 0x00008380, 0x00008380 },
-    { 0x00009a94, 0x0000a78c, 0x0000a78c, 0x00008384, 0x00008384, 0x00008384 },
-    { 0x00009a98, 0x0000a790, 0x0000a790, 0x00008700, 0x00008700, 0x00008700 },
-    { 0x00009a9c, 0x0000a794, 0x0000a794, 0x00008704, 0x00008704, 0x00008704 },
-    { 0x00009aa0, 0x0000ab84, 0x0000ab84, 0x00008708, 0x00008708, 0x00008708 },
-    { 0x00009aa4, 0x0000ab88, 0x0000ab88, 0x0000870c, 0x0000870c, 0x0000870c },
-    { 0x00009aa8, 0x0000ab8c, 0x0000ab8c, 0x00008780, 0x00008780, 0x00008780 },
-    { 0x00009aac, 0x0000ab90, 0x0000ab90, 0x00008784, 0x00008784, 0x00008784 },
-    { 0x00009ab0, 0x0000ab94, 0x0000ab94, 0x00008b00, 0x00008b00, 0x00008b00 },
-    { 0x00009ab4, 0x0000af80, 0x0000af80, 0x00008b04, 0x00008b04, 0x00008b04 },
-    { 0x00009ab8, 0x0000af84, 0x0000af84, 0x00008b08, 0x00008b08, 0x00008b08 },
-    { 0x00009abc, 0x0000af88, 0x0000af88, 0x00008b0c, 0x00008b0c, 0x00008b0c },
-    { 0x00009ac0, 0x0000af8c, 0x0000af8c, 0x00008b80, 0x00008b80, 0x00008b80 },
-    { 0x00009ac4, 0x0000af90, 0x0000af90, 0x00008b84, 0x00008b84, 0x00008b84 },
-    { 0x00009ac8, 0x0000af94, 0x0000af94, 0x00008b88, 0x00008b88, 0x00008b88 },
-    { 0x00009acc, 0x0000b380, 0x0000b380, 0x00008b8c, 0x00008b8c, 0x00008b8c },
-    { 0x00009ad0, 0x0000b384, 0x0000b384, 0x00008b90, 0x00008b90, 0x00008b90 },
-    { 0x00009ad4, 0x0000b388, 0x0000b388, 0x00008f80, 0x00008f80, 0x00008f80 },
-    { 0x00009ad8, 0x0000b38c, 0x0000b38c, 0x00008f84, 0x00008f84, 0x00008f84 },
-    { 0x00009adc, 0x0000b390, 0x0000b390, 0x00008f88, 0x00008f88, 0x00008f88 },
-    { 0x00009ae0, 0x0000b394, 0x0000b394, 0x00008f8c, 0x00008f8c, 0x00008f8c },
-    { 0x00009ae4, 0x0000b398, 0x0000b398, 0x00008f90, 0x00008f90, 0x00008f90 },
-    { 0x00009ae8, 0x0000b780, 0x0000b780, 0x0000930c, 0x0000930c, 0x0000930c },
-    { 0x00009aec, 0x0000b784, 0x0000b784, 0x00009310, 0x00009310, 0x00009310 },
-    { 0x00009af0, 0x0000b788, 0x0000b788, 0x00009384, 0x00009384, 0x00009384 },
-    { 0x00009af4, 0x0000b78c, 0x0000b78c, 0x00009388, 0x00009388, 0x00009388 },
-    { 0x00009af8, 0x0000b790, 0x0000b790, 0x00009324, 0x00009324, 0x00009324 },
-    { 0x00009afc, 0x0000b794, 0x0000b794, 0x00009704, 0x00009704, 0x00009704 },
-    { 0x00009b00, 0x0000b798, 0x0000b798, 0x000096a4, 0x000096a4, 0x000096a4 },
-    { 0x00009b04, 0x0000d784, 0x0000d784, 0x000096a8, 0x000096a8, 0x000096a8 },
-    { 0x00009b08, 0x0000d788, 0x0000d788, 0x00009710, 0x00009710, 0x00009710 },
-    { 0x00009b0c, 0x0000d78c, 0x0000d78c, 0x00009714, 0x00009714, 0x00009714 },
-    { 0x00009b10, 0x0000d790, 0x0000d790, 0x00009720, 0x00009720, 0x00009720 },
-    { 0x00009b14, 0x0000f780, 0x0000f780, 0x00009724, 0x00009724, 0x00009724 },
-    { 0x00009b18, 0x0000f784, 0x0000f784, 0x00009728, 0x00009728, 0x00009728 },
-    { 0x00009b1c, 0x0000f788, 0x0000f788, 0x0000972c, 0x0000972c, 0x0000972c },
-    { 0x00009b20, 0x0000f78c, 0x0000f78c, 0x000097a0, 0x000097a0, 0x000097a0 },
-    { 0x00009b24, 0x0000f790, 0x0000f790, 0x000097a4, 0x000097a4, 0x000097a4 },
-    { 0x00009b28, 0x0000f794, 0x0000f794, 0x000097a8, 0x000097a8, 0x000097a8 },
-    { 0x00009b2c, 0x0000f7a4, 0x0000f7a4, 0x000097b0, 0x000097b0, 0x000097b0 },
-    { 0x00009b30, 0x0000f7a8, 0x0000f7a8, 0x000097b4, 0x000097b4, 0x000097b4 },
-    { 0x00009b34, 0x0000f7ac, 0x0000f7ac, 0x000097b8, 0x000097b8, 0x000097b8 },
-    { 0x00009b38, 0x0000f7b0, 0x0000f7b0, 0x000097a5, 0x000097a5, 0x000097a5 },
-    { 0x00009b3c, 0x0000f7b4, 0x0000f7b4, 0x000097a9, 0x000097a9, 0x000097a9 },
-    { 0x00009b40, 0x0000f7a1, 0x0000f7a1, 0x000097ad, 0x000097ad, 0x000097ad },
-    { 0x00009b44, 0x0000f7a5, 0x0000f7a5, 0x000097b1, 0x000097b1, 0x000097b1 },
-    { 0x00009b48, 0x0000f7a9, 0x0000f7a9, 0x000097b5, 0x000097b5, 0x000097b5 },
-    { 0x00009b4c, 0x0000f7ad, 0x0000f7ad, 0x000097b9, 0x000097b9, 0x000097b9 },
-    { 0x00009b50, 0x0000f7b1, 0x0000f7b1, 0x000097c5, 0x000097c5, 0x000097c5 },
-    { 0x00009b54, 0x0000f7b5, 0x0000f7b5, 0x000097c9, 0x000097c9, 0x000097c9 },
-    { 0x00009b58, 0x0000f7c5, 0x0000f7c5, 0x000097d1, 0x000097d1, 0x000097d1 },
-    { 0x00009b5c, 0x0000f7c9, 0x0000f7c9, 0x000097d5, 0x000097d5, 0x000097d5 },
-    { 0x00009b60, 0x0000f7cd, 0x0000f7cd, 0x000097d9, 0x000097d9, 0x000097d9 },
-    { 0x00009b64, 0x0000f7d1, 0x0000f7d1, 0x000097c6, 0x000097c6, 0x000097c6 },
-    { 0x00009b68, 0x0000f7d5, 0x0000f7d5, 0x000097ca, 0x000097ca, 0x000097ca },
-    { 0x00009b6c, 0x0000f7c2, 0x0000f7c2, 0x000097ce, 0x000097ce, 0x000097ce },
-    { 0x00009b70, 0x0000f7c6, 0x0000f7c6, 0x000097d2, 0x000097d2, 0x000097d2 },
-    { 0x00009b74, 0x0000f7ca, 0x0000f7ca, 0x000097d6, 0x000097d6, 0x000097d6 },
-    { 0x00009b78, 0x0000f7ce, 0x0000f7ce, 0x000097c3, 0x000097c3, 0x000097c3 },
-    { 0x00009b7c, 0x0000f7d2, 0x0000f7d2, 0x000097c7, 0x000097c7, 0x000097c7 },
-    { 0x00009b80, 0x0000f7d6, 0x0000f7d6, 0x000097cb, 0x000097cb, 0x000097cb },
-    { 0x00009b84, 0x0000f7c3, 0x0000f7c3, 0x000097cf, 0x000097cf, 0x000097cf },
-    { 0x00009b88, 0x0000f7c7, 0x0000f7c7, 0x000097d7, 0x000097d7, 0x000097d7 },
-    { 0x00009b8c, 0x0000f7cb, 0x0000f7cb, 0x000097db, 0x000097db, 0x000097db },
-    { 0x00009b90, 0x0000f7d3, 0x0000f7d3, 0x000097db, 0x000097db, 0x000097db },
-    { 0x00009b94, 0x0000f7d7, 0x0000f7d7, 0x000097db, 0x000097db, 0x000097db },
-    { 0x00009b98, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
-    { 0x00009b9c, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
-    { 0x00009ba0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
-    { 0x00009ba4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
-    { 0x00009ba8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
-    { 0x00009bac, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
-    { 0x00009bb0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
-    { 0x00009bb4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
-    { 0x00009bb8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
-    { 0x00009bbc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
-    { 0x00009bc0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
-    { 0x00009bc4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
-    { 0x00009bc8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
-    { 0x00009bcc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
-    { 0x00009bd0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
-    { 0x00009bd4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
-    { 0x00009bd8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
-    { 0x00009bdc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
-    { 0x00009be0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
-    { 0x00009be4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
-    { 0x00009be8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
-    { 0x00009bec, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
-    { 0x00009bf0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
-    { 0x00009bf4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
-    { 0x00009bf8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
-    { 0x00009bfc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
-    { 0x00009848, 0x00001066, 0x00001066, 0x00001063, 0x00001063, 0x00001063 },
-    { 0x0000a848, 0x00001066, 0x00001066, 0x00001063, 0x00001063, 0x00001063 },
-};
-
-static const u32 ar9280Modes_backoff_13db_rxgain_9280_2[][6] = {
-    { 0x00009a00, 0x00008184, 0x00008184, 0x00000290, 0x00000290, 0x00000290 },
-    { 0x00009a04, 0x00008188, 0x00008188, 0x00000300, 0x00000300, 0x00000300 },
-    { 0x00009a08, 0x0000818c, 0x0000818c, 0x00000304, 0x00000304, 0x00000304 },
-    { 0x00009a0c, 0x00008190, 0x00008190, 0x00000308, 0x00000308, 0x00000308 },
-    { 0x00009a10, 0x00008194, 0x00008194, 0x0000030c, 0x0000030c, 0x0000030c },
-    { 0x00009a14, 0x00008200, 0x00008200, 0x00008000, 0x00008000, 0x00008000 },
-    { 0x00009a18, 0x00008204, 0x00008204, 0x00008004, 0x00008004, 0x00008004 },
-    { 0x00009a1c, 0x00008208, 0x00008208, 0x00008008, 0x00008008, 0x00008008 },
-    { 0x00009a20, 0x0000820c, 0x0000820c, 0x0000800c, 0x0000800c, 0x0000800c },
-    { 0x00009a24, 0x00008210, 0x00008210, 0x00008080, 0x00008080, 0x00008080 },
-    { 0x00009a28, 0x00008214, 0x00008214, 0x00008084, 0x00008084, 0x00008084 },
-    { 0x00009a2c, 0x00008280, 0x00008280, 0x00008088, 0x00008088, 0x00008088 },
-    { 0x00009a30, 0x00008284, 0x00008284, 0x0000808c, 0x0000808c, 0x0000808c },
-    { 0x00009a34, 0x00008288, 0x00008288, 0x00008100, 0x00008100, 0x00008100 },
-    { 0x00009a38, 0x0000828c, 0x0000828c, 0x00008104, 0x00008104, 0x00008104 },
-    { 0x00009a3c, 0x00008290, 0x00008290, 0x00008108, 0x00008108, 0x00008108 },
-    { 0x00009a40, 0x00008300, 0x00008300, 0x0000810c, 0x0000810c, 0x0000810c },
-    { 0x00009a44, 0x00008304, 0x00008304, 0x00008110, 0x00008110, 0x00008110 },
-    { 0x00009a48, 0x00008308, 0x00008308, 0x00008114, 0x00008114, 0x00008114 },
-    { 0x00009a4c, 0x0000830c, 0x0000830c, 0x00008180, 0x00008180, 0x00008180 },
-    { 0x00009a50, 0x00008310, 0x00008310, 0x00008184, 0x00008184, 0x00008184 },
-    { 0x00009a54, 0x00008314, 0x00008314, 0x00008188, 0x00008188, 0x00008188 },
-    { 0x00009a58, 0x00008380, 0x00008380, 0x0000818c, 0x0000818c, 0x0000818c },
-    { 0x00009a5c, 0x00008384, 0x00008384, 0x00008190, 0x00008190, 0x00008190 },
-    { 0x00009a60, 0x00008388, 0x00008388, 0x00008194, 0x00008194, 0x00008194 },
-    { 0x00009a64, 0x0000838c, 0x0000838c, 0x000081a0, 0x000081a0, 0x000081a0 },
-    { 0x00009a68, 0x00008390, 0x00008390, 0x0000820c, 0x0000820c, 0x0000820c },
-    { 0x00009a6c, 0x00008394, 0x00008394, 0x000081a8, 0x000081a8, 0x000081a8 },
-    { 0x00009a70, 0x0000a380, 0x0000a380, 0x00008284, 0x00008284, 0x00008284 },
-    { 0x00009a74, 0x0000a384, 0x0000a384, 0x00008288, 0x00008288, 0x00008288 },
-    { 0x00009a78, 0x0000a388, 0x0000a388, 0x00008224, 0x00008224, 0x00008224 },
-    { 0x00009a7c, 0x0000a38c, 0x0000a38c, 0x00008290, 0x00008290, 0x00008290 },
-    { 0x00009a80, 0x0000a390, 0x0000a390, 0x00008300, 0x00008300, 0x00008300 },
-    { 0x00009a84, 0x0000a394, 0x0000a394, 0x00008304, 0x00008304, 0x00008304 },
-    { 0x00009a88, 0x0000a780, 0x0000a780, 0x00008308, 0x00008308, 0x00008308 },
-    { 0x00009a8c, 0x0000a784, 0x0000a784, 0x0000830c, 0x0000830c, 0x0000830c },
-    { 0x00009a90, 0x0000a788, 0x0000a788, 0x00008380, 0x00008380, 0x00008380 },
-    { 0x00009a94, 0x0000a78c, 0x0000a78c, 0x00008384, 0x00008384, 0x00008384 },
-    { 0x00009a98, 0x0000a790, 0x0000a790, 0x00008700, 0x00008700, 0x00008700 },
-    { 0x00009a9c, 0x0000a794, 0x0000a794, 0x00008704, 0x00008704, 0x00008704 },
-    { 0x00009aa0, 0x0000ab84, 0x0000ab84, 0x00008708, 0x00008708, 0x00008708 },
-    { 0x00009aa4, 0x0000ab88, 0x0000ab88, 0x0000870c, 0x0000870c, 0x0000870c },
-    { 0x00009aa8, 0x0000ab8c, 0x0000ab8c, 0x00008780, 0x00008780, 0x00008780 },
-    { 0x00009aac, 0x0000ab90, 0x0000ab90, 0x00008784, 0x00008784, 0x00008784 },
-    { 0x00009ab0, 0x0000ab94, 0x0000ab94, 0x00008b00, 0x00008b00, 0x00008b00 },
-    { 0x00009ab4, 0x0000af80, 0x0000af80, 0x00008b04, 0x00008b04, 0x00008b04 },
-    { 0x00009ab8, 0x0000af84, 0x0000af84, 0x00008b08, 0x00008b08, 0x00008b08 },
-    { 0x00009abc, 0x0000af88, 0x0000af88, 0x00008b0c, 0x00008b0c, 0x00008b0c },
-    { 0x00009ac0, 0x0000af8c, 0x0000af8c, 0x00008b80, 0x00008b80, 0x00008b80 },
-    { 0x00009ac4, 0x0000af90, 0x0000af90, 0x00008b84, 0x00008b84, 0x00008b84 },
-    { 0x00009ac8, 0x0000af94, 0x0000af94, 0x00008b88, 0x00008b88, 0x00008b88 },
-    { 0x00009acc, 0x0000b380, 0x0000b380, 0x00008b8c, 0x00008b8c, 0x00008b8c },
-    { 0x00009ad0, 0x0000b384, 0x0000b384, 0x00008b90, 0x00008b90, 0x00008b90 },
-    { 0x00009ad4, 0x0000b388, 0x0000b388, 0x00008f80, 0x00008f80, 0x00008f80 },
-    { 0x00009ad8, 0x0000b38c, 0x0000b38c, 0x00008f84, 0x00008f84, 0x00008f84 },
-    { 0x00009adc, 0x0000b390, 0x0000b390, 0x00008f88, 0x00008f88, 0x00008f88 },
-    { 0x00009ae0, 0x0000b394, 0x0000b394, 0x00008f8c, 0x00008f8c, 0x00008f8c },
-    { 0x00009ae4, 0x0000b398, 0x0000b398, 0x00008f90, 0x00008f90, 0x00008f90 },
-    { 0x00009ae8, 0x0000b780, 0x0000b780, 0x00009310, 0x00009310, 0x00009310 },
-    { 0x00009aec, 0x0000b784, 0x0000b784, 0x00009314, 0x00009314, 0x00009314 },
-    { 0x00009af0, 0x0000b788, 0x0000b788, 0x00009320, 0x00009320, 0x00009320 },
-    { 0x00009af4, 0x0000b78c, 0x0000b78c, 0x00009324, 0x00009324, 0x00009324 },
-    { 0x00009af8, 0x0000b790, 0x0000b790, 0x00009328, 0x00009328, 0x00009328 },
-    { 0x00009afc, 0x0000b794, 0x0000b794, 0x0000932c, 0x0000932c, 0x0000932c },
-    { 0x00009b00, 0x0000b798, 0x0000b798, 0x00009330, 0x00009330, 0x00009330 },
-    { 0x00009b04, 0x0000d784, 0x0000d784, 0x00009334, 0x00009334, 0x00009334 },
-    { 0x00009b08, 0x0000d788, 0x0000d788, 0x00009321, 0x00009321, 0x00009321 },
-    { 0x00009b0c, 0x0000d78c, 0x0000d78c, 0x00009325, 0x00009325, 0x00009325 },
-    { 0x00009b10, 0x0000d790, 0x0000d790, 0x00009329, 0x00009329, 0x00009329 },
-    { 0x00009b14, 0x0000f780, 0x0000f780, 0x0000932d, 0x0000932d, 0x0000932d },
-    { 0x00009b18, 0x0000f784, 0x0000f784, 0x00009331, 0x00009331, 0x00009331 },
-    { 0x00009b1c, 0x0000f788, 0x0000f788, 0x00009335, 0x00009335, 0x00009335 },
-    { 0x00009b20, 0x0000f78c, 0x0000f78c, 0x00009322, 0x00009322, 0x00009322 },
-    { 0x00009b24, 0x0000f790, 0x0000f790, 0x00009326, 0x00009326, 0x00009326 },
-    { 0x00009b28, 0x0000f794, 0x0000f794, 0x0000932a, 0x0000932a, 0x0000932a },
-    { 0x00009b2c, 0x0000f7a4, 0x0000f7a4, 0x0000932e, 0x0000932e, 0x0000932e },
-    { 0x00009b30, 0x0000f7a8, 0x0000f7a8, 0x00009332, 0x00009332, 0x00009332 },
-    { 0x00009b34, 0x0000f7ac, 0x0000f7ac, 0x00009336, 0x00009336, 0x00009336 },
-    { 0x00009b38, 0x0000f7b0, 0x0000f7b0, 0x00009323, 0x00009323, 0x00009323 },
-    { 0x00009b3c, 0x0000f7b4, 0x0000f7b4, 0x00009327, 0x00009327, 0x00009327 },
-    { 0x00009b40, 0x0000f7a1, 0x0000f7a1, 0x0000932b, 0x0000932b, 0x0000932b },
-    { 0x00009b44, 0x0000f7a5, 0x0000f7a5, 0x0000932f, 0x0000932f, 0x0000932f },
-    { 0x00009b48, 0x0000f7a9, 0x0000f7a9, 0x00009333, 0x00009333, 0x00009333 },
-    { 0x00009b4c, 0x0000f7ad, 0x0000f7ad, 0x00009337, 0x00009337, 0x00009337 },
-    { 0x00009b50, 0x0000f7b1, 0x0000f7b1, 0x00009343, 0x00009343, 0x00009343 },
-    { 0x00009b54, 0x0000f7b5, 0x0000f7b5, 0x00009347, 0x00009347, 0x00009347 },
-    { 0x00009b58, 0x0000f7c5, 0x0000f7c5, 0x0000934b, 0x0000934b, 0x0000934b },
-    { 0x00009b5c, 0x0000f7c9, 0x0000f7c9, 0x0000934f, 0x0000934f, 0x0000934f },
-    { 0x00009b60, 0x0000f7cd, 0x0000f7cd, 0x00009353, 0x00009353, 0x00009353 },
-    { 0x00009b64, 0x0000f7d1, 0x0000f7d1, 0x00009357, 0x00009357, 0x00009357 },
-    { 0x00009b68, 0x0000f7d5, 0x0000f7d5, 0x0000935b, 0x0000935b, 0x0000935b },
-    { 0x00009b6c, 0x0000f7c2, 0x0000f7c2, 0x0000935b, 0x0000935b, 0x0000935b },
-    { 0x00009b70, 0x0000f7c6, 0x0000f7c6, 0x0000935b, 0x0000935b, 0x0000935b },
-    { 0x00009b74, 0x0000f7ca, 0x0000f7ca, 0x0000935b, 0x0000935b, 0x0000935b },
-    { 0x00009b78, 0x0000f7ce, 0x0000f7ce, 0x0000935b, 0x0000935b, 0x0000935b },
-    { 0x00009b7c, 0x0000f7d2, 0x0000f7d2, 0x0000935b, 0x0000935b, 0x0000935b },
-    { 0x00009b80, 0x0000f7d6, 0x0000f7d6, 0x0000935b, 0x0000935b, 0x0000935b },
-    { 0x00009b84, 0x0000f7c3, 0x0000f7c3, 0x0000935b, 0x0000935b, 0x0000935b },
-    { 0x00009b88, 0x0000f7c7, 0x0000f7c7, 0x0000935b, 0x0000935b, 0x0000935b },
-    { 0x00009b8c, 0x0000f7cb, 0x0000f7cb, 0x0000935b, 0x0000935b, 0x0000935b },
-    { 0x00009b90, 0x0000f7d3, 0x0000f7d3, 0x0000935b, 0x0000935b, 0x0000935b },
-    { 0x00009b94, 0x0000f7d7, 0x0000f7d7, 0x0000935b, 0x0000935b, 0x0000935b },
-    { 0x00009b98, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b },
-    { 0x00009b9c, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b },
-    { 0x00009ba0, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b },
-    { 0x00009ba4, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b },
-    { 0x00009ba8, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b },
-    { 0x00009bac, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b },
-    { 0x00009bb0, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b },
-    { 0x00009bb4, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b },
-    { 0x00009bb8, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b },
-    { 0x00009bbc, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b },
-    { 0x00009bc0, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b },
-    { 0x00009bc4, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b },
-    { 0x00009bc8, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b },
-    { 0x00009bcc, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b },
-    { 0x00009bd0, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b },
-    { 0x00009bd4, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b },
-    { 0x00009bd8, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b },
-    { 0x00009bdc, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b },
-    { 0x00009be0, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b },
-    { 0x00009be4, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b },
-    { 0x00009be8, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b },
-    { 0x00009bec, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b },
-    { 0x00009bf0, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b },
-    { 0x00009bf4, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b },
-    { 0x00009bf8, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b },
-    { 0x00009bfc, 0x0000f7db, 0x0000f7db, 0x0000935b, 0x0000935b, 0x0000935b },
-    { 0x00009848, 0x00001066, 0x00001066, 0x0000105a, 0x0000105a, 0x0000105a },
-    { 0x0000a848, 0x00001066, 0x00001066, 0x0000105a, 0x0000105a, 0x0000105a },
-};
-
-static const u32 ar9280Modes_high_power_tx_gain_9280_2[][6] = {
-    { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x0000a304, 0x00003002, 0x00003002, 0x00004002, 0x00004002, 0x00004002 },
-    { 0x0000a308, 0x00006004, 0x00006004, 0x00007008, 0x00007008, 0x00007008 },
-    { 0x0000a30c, 0x0000a006, 0x0000a006, 0x0000c010, 0x0000c010, 0x0000c010 },
-    { 0x0000a310, 0x0000e012, 0x0000e012, 0x00010012, 0x00010012, 0x00010012 },
-    { 0x0000a314, 0x00011014, 0x00011014, 0x00013014, 0x00013014, 0x00013014 },
-    { 0x0000a318, 0x0001504a, 0x0001504a, 0x0001820a, 0x0001820a, 0x0001820a },
-    { 0x0000a31c, 0x0001904c, 0x0001904c, 0x0001b211, 0x0001b211, 0x0001b211 },
-    { 0x0000a320, 0x0001c04e, 0x0001c04e, 0x0001e213, 0x0001e213, 0x0001e213 },
-    { 0x0000a324, 0x00021092, 0x00021092, 0x00022411, 0x00022411, 0x00022411 },
-    { 0x0000a328, 0x0002510a, 0x0002510a, 0x00025413, 0x00025413, 0x00025413 },
-    { 0x0000a32c, 0x0002910c, 0x0002910c, 0x00029811, 0x00029811, 0x00029811 },
-    { 0x0000a330, 0x0002c18b, 0x0002c18b, 0x0002c813, 0x0002c813, 0x0002c813 },
-    { 0x0000a334, 0x0002f1cc, 0x0002f1cc, 0x00030a14, 0x00030a14, 0x00030a14 },
-    { 0x0000a338, 0x000321eb, 0x000321eb, 0x00035a50, 0x00035a50, 0x00035a50 },
-    { 0x0000a33c, 0x000341ec, 0x000341ec, 0x00039c4c, 0x00039c4c, 0x00039c4c },
-    { 0x0000a340, 0x000341ec, 0x000341ec, 0x0003de8a, 0x0003de8a, 0x0003de8a },
-    { 0x0000a344, 0x000341ec, 0x000341ec, 0x00042e92, 0x00042e92, 0x00042e92 },
-    { 0x0000a348, 0x000341ec, 0x000341ec, 0x00046ed2, 0x00046ed2, 0x00046ed2 },
-    { 0x0000a34c, 0x000341ec, 0x000341ec, 0x0004bed5, 0x0004bed5, 0x0004bed5 },
-    { 0x0000a350, 0x000341ec, 0x000341ec, 0x0004ff54, 0x0004ff54, 0x0004ff54 },
-    { 0x0000a354, 0x000341ec, 0x000341ec, 0x00055fd5, 0x00055fd5, 0x00055fd5 },
-    { 0x00007814, 0x00198eff, 0x00198eff, 0x00198eff, 0x00198eff, 0x00198eff },
-    { 0x00007838, 0x00198eff, 0x00198eff, 0x00198eff, 0x00198eff, 0x00198eff },
-    { 0x0000781c, 0x00172000, 0x00172000, 0x00172000, 0x00172000, 0x00172000 },
-    { 0x00007840, 0x00172000, 0x00172000, 0x00172000, 0x00172000, 0x00172000 },
-    { 0x00007820, 0xf258a480, 0xf258a480, 0xf258a480, 0xf258a480, 0xf258a480 },
-    { 0x00007844, 0xf258a480, 0xf258a480, 0xf258a480, 0xf258a480, 0xf258a480 },
-    { 0x0000a274, 0x0a19e652, 0x0a19e652, 0x0a1aa652, 0x0a1aa652, 0x0a1aa652 },
-    { 0x0000a27c, 0x050739ce, 0x050739ce, 0x050739ce, 0x050739ce, 0x050739ce },
-};
-
-static const u32 ar9280Modes_original_tx_gain_9280_2[][6] = {
-    { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x0000a304, 0x00003002, 0x00003002, 0x00003002, 0x00003002, 0x00003002 },
-    { 0x0000a308, 0x00006004, 0x00006004, 0x00008009, 0x00008009, 0x00008009 },
-    { 0x0000a30c, 0x0000a006, 0x0000a006, 0x0000b00b, 0x0000b00b, 0x0000b00b },
-    { 0x0000a310, 0x0000e012, 0x0000e012, 0x0000e012, 0x0000e012, 0x0000e012 },
-    { 0x0000a314, 0x00011014, 0x00011014, 0x00012048, 0x00012048, 0x00012048 },
-    { 0x0000a318, 0x0001504a, 0x0001504a, 0x0001604a, 0x0001604a, 0x0001604a },
-    { 0x0000a31c, 0x0001904c, 0x0001904c, 0x0001a211, 0x0001a211, 0x0001a211 },
-    { 0x0000a320, 0x0001c04e, 0x0001c04e, 0x0001e213, 0x0001e213, 0x0001e213 },
-    { 0x0000a324, 0x00020092, 0x00020092, 0x0002121b, 0x0002121b, 0x0002121b },
-    { 0x0000a328, 0x0002410a, 0x0002410a, 0x00024412, 0x00024412, 0x00024412 },
-    { 0x0000a32c, 0x0002710c, 0x0002710c, 0x00028414, 0x00028414, 0x00028414 },
-    { 0x0000a330, 0x0002b18b, 0x0002b18b, 0x0002b44a, 0x0002b44a, 0x0002b44a },
-    { 0x0000a334, 0x0002e1cc, 0x0002e1cc, 0x00030649, 0x00030649, 0x00030649 },
-    { 0x0000a338, 0x000321ec, 0x000321ec, 0x0003364b, 0x0003364b, 0x0003364b },
-    { 0x0000a33c, 0x000321ec, 0x000321ec, 0x00038a49, 0x00038a49, 0x00038a49 },
-    { 0x0000a340, 0x000321ec, 0x000321ec, 0x0003be48, 0x0003be48, 0x0003be48 },
-    { 0x0000a344, 0x000321ec, 0x000321ec, 0x0003ee4a, 0x0003ee4a, 0x0003ee4a },
-    { 0x0000a348, 0x000321ec, 0x000321ec, 0x00042e88, 0x00042e88, 0x00042e88 },
-    { 0x0000a34c, 0x000321ec, 0x000321ec, 0x00046e8a, 0x00046e8a, 0x00046e8a },
-    { 0x0000a350, 0x000321ec, 0x000321ec, 0x00049ec9, 0x00049ec9, 0x00049ec9 },
-    { 0x0000a354, 0x000321ec, 0x000321ec, 0x0004bf42, 0x0004bf42, 0x0004bf42 },
-    { 0x00007814, 0x0019beff, 0x0019beff, 0x0019beff, 0x0019beff, 0x0019beff },
-    { 0x00007838, 0x0019beff, 0x0019beff, 0x0019beff, 0x0019beff, 0x0019beff },
-    { 0x0000781c, 0x00392000, 0x00392000, 0x00392000, 0x00392000, 0x00392000 },
-    { 0x00007840, 0x00392000, 0x00392000, 0x00392000, 0x00392000, 0x00392000 },
-    { 0x00007820, 0x92592480, 0x92592480, 0x92592480, 0x92592480, 0x92592480 },
-    { 0x00007844, 0x92592480, 0x92592480, 0x92592480, 0x92592480, 0x92592480 },
-    { 0x0000a274, 0x0a19c652, 0x0a19c652, 0x0a1aa652, 0x0a1aa652, 0x0a1aa652 },
-    { 0x0000a27c, 0x050701ce, 0x050701ce, 0x050701ce, 0x050701ce, 0x050701ce },
-};
-
-static const u32 ar9280PciePhy_clkreq_off_L1_9280[][2] = {
-    {0x00004040,  0x9248fd00 },
-    {0x00004040,  0x24924924 },
-    {0x00004040,  0xa8000019 },
-    {0x00004040,  0x13160820 },
-    {0x00004040,  0xe5980560 },
-    {0x00004040,  0xc01dcffc },
-    {0x00004040,  0x1aaabe41 },
-    {0x00004040,  0xbe105554 },
-    {0x00004040,  0x00043007 },
-    {0x00004044,  0x00000000 },
-};
-
-static const u32 ar9280PciePhy_clkreq_always_on_L1_9280[][2] = {
-    {0x00004040,  0x9248fd00 },
-    {0x00004040,  0x24924924 },
-    {0x00004040,  0xa8000019 },
-    {0x00004040,  0x13160820 },
-    {0x00004040,  0xe5980560 },
-    {0x00004040,  0xc01dcffd },
-    {0x00004040,  0x1aaabe41 },
-    {0x00004040,  0xbe105554 },
-    {0x00004040,  0x00043007 },
-    {0x00004044,  0x00000000 },
-};
-
-/* AR9285 */
-static const u_int32_t ar9285Modes_9285[][6] = {
-    { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
-    { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
-    { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
-    { 0x000010f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008 },
-    { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 },
-    { 0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b, 0x0988004f },
-    { 0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440, 0x00006880 },
-    { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 },
-    { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 },
-    { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
-    { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 },
-    { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
-    { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 },
-    { 0x00009840, 0x206a012e, 0x206a012e, 0x206a012e, 0x206a012e, 0x206a012e },
-    { 0x00009844, 0x0372161e, 0x0372161e, 0x03720020, 0x03720020, 0x037216a0 },
-    { 0x00009848, 0x00001066, 0x00001066, 0x0000004e, 0x0000004e, 0x00001059 },
-    { 0x00009850, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2 },
-    { 0x00009858, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e },
-    { 0x0000985c, 0x3139605e, 0x3139605e, 0x3136605e, 0x3136605e, 0x3139605e },
-    { 0x00009860, 0x00058d18, 0x00058d18, 0x00058d20, 0x00058d20, 0x00058d18 },
-    { 0x00009864, 0x0000fe00, 0x0000fe00, 0x0001ce00, 0x0001ce00, 0x0001ce00 },
-    { 0x00009868, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0 },
-    { 0x0000986c, 0x06903081, 0x06903081, 0x06903881, 0x06903881, 0x06903881 },
-    { 0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0 },
-    { 0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016 },
-    { 0x00009924, 0xd00a8007, 0xd00a8007, 0xd00a800d, 0xd00a800d, 0xd00a800d },
-    { 0x00009944, 0xdfbc1010, 0xdfbc1010, 0xdfbc1020, 0xdfbc1020, 0xdfbc1010 },
-    { 0x00009960, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x00009964, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x000099b8, 0x00cf4d1c, 0x00cf4d1c, 0x00cf4d1c, 0x00cf4d1c, 0x00cf4d1c },
-    { 0x000099bc, 0x00000600, 0x00000600, 0x00000c00, 0x00000c00, 0x00000c00 },
-    { 0x000099c0, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4 },
-    { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 },
-    { 0x000099c8, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329 },
-    { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 },
-    { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 },
-    { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x00009a00, 0x00000000, 0x00000000, 0x00068084, 0x00068084, 0x00000000 },
-    { 0x00009a04, 0x00000000, 0x00000000, 0x00068088, 0x00068088, 0x00000000 },
-    { 0x00009a08, 0x00000000, 0x00000000, 0x0006808c, 0x0006808c, 0x00000000 },
-    { 0x00009a0c, 0x00000000, 0x00000000, 0x00068100, 0x00068100, 0x00000000 },
-    { 0x00009a10, 0x00000000, 0x00000000, 0x00068104, 0x00068104, 0x00000000 },
-    { 0x00009a14, 0x00000000, 0x00000000, 0x00068108, 0x00068108, 0x00000000 },
-    { 0x00009a18, 0x00000000, 0x00000000, 0x0006810c, 0x0006810c, 0x00000000 },
-    { 0x00009a1c, 0x00000000, 0x00000000, 0x00068110, 0x00068110, 0x00000000 },
-    { 0x00009a20, 0x00000000, 0x00000000, 0x00068114, 0x00068114, 0x00000000 },
-    { 0x00009a24, 0x00000000, 0x00000000, 0x00068180, 0x00068180, 0x00000000 },
-    { 0x00009a28, 0x00000000, 0x00000000, 0x00068184, 0x00068184, 0x00000000 },
-    { 0x00009a2c, 0x00000000, 0x00000000, 0x00068188, 0x00068188, 0x00000000 },
-    { 0x00009a30, 0x00000000, 0x00000000, 0x0006818c, 0x0006818c, 0x00000000 },
-    { 0x00009a34, 0x00000000, 0x00000000, 0x00068190, 0x00068190, 0x00000000 },
-    { 0x00009a38, 0x00000000, 0x00000000, 0x00068194, 0x00068194, 0x00000000 },
-    { 0x00009a3c, 0x00000000, 0x00000000, 0x000681a0, 0x000681a0, 0x00000000 },
-    { 0x00009a40, 0x00000000, 0x00000000, 0x0006820c, 0x0006820c, 0x00000000 },
-    { 0x00009a44, 0x00000000, 0x00000000, 0x000681a8, 0x000681a8, 0x00000000 },
-    { 0x00009a48, 0x00000000, 0x00000000, 0x00068284, 0x00068284, 0x00000000 },
-    { 0x00009a4c, 0x00000000, 0x00000000, 0x00068288, 0x00068288, 0x00000000 },
-    { 0x00009a50, 0x00000000, 0x00000000, 0x00068220, 0x00068220, 0x00000000 },
-    { 0x00009a54, 0x00000000, 0x00000000, 0x00068290, 0x00068290, 0x00000000 },
-    { 0x00009a58, 0x00000000, 0x00000000, 0x00068300, 0x00068300, 0x00000000 },
-    { 0x00009a5c, 0x00000000, 0x00000000, 0x00068304, 0x00068304, 0x00000000 },
-    { 0x00009a60, 0x00000000, 0x00000000, 0x00068308, 0x00068308, 0x00000000 },
-    { 0x00009a64, 0x00000000, 0x00000000, 0x0006830c, 0x0006830c, 0x00000000 },
-    { 0x00009a68, 0x00000000, 0x00000000, 0x00068380, 0x00068380, 0x00000000 },
-    { 0x00009a6c, 0x00000000, 0x00000000, 0x00068384, 0x00068384, 0x00000000 },
-    { 0x00009a70, 0x00000000, 0x00000000, 0x00068700, 0x00068700, 0x00000000 },
-    { 0x00009a74, 0x00000000, 0x00000000, 0x00068704, 0x00068704, 0x00000000 },
-    { 0x00009a78, 0x00000000, 0x00000000, 0x00068708, 0x00068708, 0x00000000 },
-    { 0x00009a7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000 },
-    { 0x00009a80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000 },
-    { 0x00009a84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000 },
-    { 0x00009a88, 0x00000000, 0x00000000, 0x00068b04, 0x00068b04, 0x00000000 },
-    { 0x00009a8c, 0x00000000, 0x00000000, 0x00068b08, 0x00068b08, 0x00000000 },
-    { 0x00009a90, 0x00000000, 0x00000000, 0x00068b08, 0x00068b08, 0x00000000 },
-    { 0x00009a94, 0x00000000, 0x00000000, 0x00068b0c, 0x00068b0c, 0x00000000 },
-    { 0x00009a98, 0x00000000, 0x00000000, 0x00068b80, 0x00068b80, 0x00000000 },
-    { 0x00009a9c, 0x00000000, 0x00000000, 0x00068b84, 0x00068b84, 0x00000000 },
-    { 0x00009aa0, 0x00000000, 0x00000000, 0x00068b88, 0x00068b88, 0x00000000 },
-    { 0x00009aa4, 0x00000000, 0x00000000, 0x00068b8c, 0x00068b8c, 0x00000000 },
-    { 0x00009aa8, 0x00000000, 0x00000000, 0x000b8b90, 0x000b8b90, 0x00000000 },
-    { 0x00009aac, 0x00000000, 0x00000000, 0x000b8f80, 0x000b8f80, 0x00000000 },
-    { 0x00009ab0, 0x00000000, 0x00000000, 0x000b8f84, 0x000b8f84, 0x00000000 },
-    { 0x00009ab4, 0x00000000, 0x00000000, 0x000b8f88, 0x000b8f88, 0x00000000 },
-    { 0x00009ab8, 0x00000000, 0x00000000, 0x000b8f8c, 0x000b8f8c, 0x00000000 },
-    { 0x00009abc, 0x00000000, 0x00000000, 0x000b8f90, 0x000b8f90, 0x00000000 },
-    { 0x00009ac0, 0x00000000, 0x00000000, 0x000bb30c, 0x000bb30c, 0x00000000 },
-    { 0x00009ac4, 0x00000000, 0x00000000, 0x000bb310, 0x000bb310, 0x00000000 },
-    { 0x00009ac8, 0x00000000, 0x00000000, 0x000bb384, 0x000bb384, 0x00000000 },
-    { 0x00009acc, 0x00000000, 0x00000000, 0x000bb388, 0x000bb388, 0x00000000 },
-    { 0x00009ad0, 0x00000000, 0x00000000, 0x000bb324, 0x000bb324, 0x00000000 },
-    { 0x00009ad4, 0x00000000, 0x00000000, 0x000bb704, 0x000bb704, 0x00000000 },
-    { 0x00009ad8, 0x00000000, 0x00000000, 0x000f96a4, 0x000f96a4, 0x00000000 },
-    { 0x00009adc, 0x00000000, 0x00000000, 0x000f96a8, 0x000f96a8, 0x00000000 },
-    { 0x00009ae0, 0x00000000, 0x00000000, 0x000f9710, 0x000f9710, 0x00000000 },
-    { 0x00009ae4, 0x00000000, 0x00000000, 0x000f9714, 0x000f9714, 0x00000000 },
-    { 0x00009ae8, 0x00000000, 0x00000000, 0x000f9720, 0x000f9720, 0x00000000 },
-    { 0x00009aec, 0x00000000, 0x00000000, 0x000f9724, 0x000f9724, 0x00000000 },
-    { 0x00009af0, 0x00000000, 0x00000000, 0x000f9728, 0x000f9728, 0x00000000 },
-    { 0x00009af4, 0x00000000, 0x00000000, 0x000f972c, 0x000f972c, 0x00000000 },
-    { 0x00009af8, 0x00000000, 0x00000000, 0x000f97a0, 0x000f97a0, 0x00000000 },
-    { 0x00009afc, 0x00000000, 0x00000000, 0x000f97a4, 0x000f97a4, 0x00000000 },
-    { 0x00009b00, 0x00000000, 0x00000000, 0x000fb7a8, 0x000fb7a8, 0x00000000 },
-    { 0x00009b04, 0x00000000, 0x00000000, 0x000fb7b0, 0x000fb7b0, 0x00000000 },
-    { 0x00009b08, 0x00000000, 0x00000000, 0x000fb7b4, 0x000fb7b4, 0x00000000 },
-    { 0x00009b0c, 0x00000000, 0x00000000, 0x000fb7b8, 0x000fb7b8, 0x00000000 },
-    { 0x00009b10, 0x00000000, 0x00000000, 0x000fb7a5, 0x000fb7a5, 0x00000000 },
-    { 0x00009b14, 0x00000000, 0x00000000, 0x000fb7a9, 0x000fb7a9, 0x00000000 },
-    { 0x00009b18, 0x00000000, 0x00000000, 0x000fb7ad, 0x000fb7ad, 0x00000000 },
-    { 0x00009b1c, 0x00000000, 0x00000000, 0x000fb7b1, 0x000fb7b1, 0x00000000 },
-    { 0x00009b20, 0x00000000, 0x00000000, 0x000fb7b5, 0x000fb7b5, 0x00000000 },
-    { 0x00009b24, 0x00000000, 0x00000000, 0x000fb7b9, 0x000fb7b9, 0x00000000 },
-    { 0x00009b28, 0x00000000, 0x00000000, 0x000fb7c5, 0x000fb7c5, 0x00000000 },
-    { 0x00009b2c, 0x00000000, 0x00000000, 0x000fb7c9, 0x000fb7c9, 0x00000000 },
-    { 0x00009b30, 0x00000000, 0x00000000, 0x000fb7d1, 0x000fb7d1, 0x00000000 },
-    { 0x00009b34, 0x00000000, 0x00000000, 0x000fb7d5, 0x000fb7d5, 0x00000000 },
-    { 0x00009b38, 0x00000000, 0x00000000, 0x000fb7d9, 0x000fb7d9, 0x00000000 },
-    { 0x00009b3c, 0x00000000, 0x00000000, 0x000fb7c6, 0x000fb7c6, 0x00000000 },
-    { 0x00009b40, 0x00000000, 0x00000000, 0x000fb7ca, 0x000fb7ca, 0x00000000 },
-    { 0x00009b44, 0x00000000, 0x00000000, 0x000fb7ce, 0x000fb7ce, 0x00000000 },
-    { 0x00009b48, 0x00000000, 0x00000000, 0x000fb7d2, 0x000fb7d2, 0x00000000 },
-    { 0x00009b4c, 0x00000000, 0x00000000, 0x000fb7d6, 0x000fb7d6, 0x00000000 },
-    { 0x00009b50, 0x00000000, 0x00000000, 0x000fb7c3, 0x000fb7c3, 0x00000000 },
-    { 0x00009b54, 0x00000000, 0x00000000, 0x000fb7c7, 0x000fb7c7, 0x00000000 },
-    { 0x00009b58, 0x00000000, 0x00000000, 0x000fb7cb, 0x000fb7cb, 0x00000000 },
-    { 0x00009b5c, 0x00000000, 0x00000000, 0x000fb7cf, 0x000fb7cf, 0x00000000 },
-    { 0x00009b60, 0x00000000, 0x00000000, 0x000fb7d7, 0x000fb7d7, 0x00000000 },
-    { 0x00009b64, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009b68, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009b6c, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009b70, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009b74, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009b78, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009b7c, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009b80, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009b84, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009b88, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009b8c, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009b90, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009b94, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009b98, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009b9c, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009ba0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009ba4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009ba8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009bac, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009bb0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009bb4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009bb8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009bbc, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009bc0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009bc4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009bc8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009bcc, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009bd0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009bd4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009bd8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009bdc, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009be0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009be4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009be8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009bec, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009bf0, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009bf4, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009bf8, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x00009bfc, 0x00000000, 0x00000000, 0x000fb7db, 0x000fb7db, 0x00000000 },
-    { 0x0000aa00, 0x00000000, 0x00000000, 0x0006801c, 0x0006801c, 0x00000000 },
-    { 0x0000aa04, 0x00000000, 0x00000000, 0x00068080, 0x00068080, 0x00000000 },
-    { 0x0000aa08, 0x00000000, 0x00000000, 0x00068084, 0x00068084, 0x00000000 },
-    { 0x0000aa0c, 0x00000000, 0x00000000, 0x00068088, 0x00068088, 0x00000000 },
-    { 0x0000aa10, 0x00000000, 0x00000000, 0x0006808c, 0x0006808c, 0x00000000 },
-    { 0x0000aa14, 0x00000000, 0x00000000, 0x00068100, 0x00068100, 0x00000000 },
-    { 0x0000aa18, 0x00000000, 0x00000000, 0x00068104, 0x00068104, 0x00000000 },
-    { 0x0000aa1c, 0x00000000, 0x00000000, 0x00068108, 0x00068108, 0x00000000 },
-    { 0x0000aa20, 0x00000000, 0x00000000, 0x0006810c, 0x0006810c, 0x00000000 },
-    { 0x0000aa24, 0x00000000, 0x00000000, 0x00068110, 0x00068110, 0x00000000 },
-    { 0x0000aa28, 0x00000000, 0x00000000, 0x00068110, 0x00068110, 0x00000000 },
-    { 0x0000aa2c, 0x00000000, 0x00000000, 0x00068180, 0x00068180, 0x00000000 },
-    { 0x0000aa30, 0x00000000, 0x00000000, 0x00068184, 0x00068184, 0x00000000 },
-    { 0x0000aa34, 0x00000000, 0x00000000, 0x00068188, 0x00068188, 0x00000000 },
-    { 0x0000aa38, 0x00000000, 0x00000000, 0x0006818c, 0x0006818c, 0x00000000 },
-    { 0x0000aa3c, 0x00000000, 0x00000000, 0x00068190, 0x00068190, 0x00000000 },
-    { 0x0000aa40, 0x00000000, 0x00000000, 0x00068194, 0x00068194, 0x00000000 },
-    { 0x0000aa44, 0x00000000, 0x00000000, 0x000681a0, 0x000681a0, 0x00000000 },
-    { 0x0000aa48, 0x00000000, 0x00000000, 0x0006820c, 0x0006820c, 0x00000000 },
-    { 0x0000aa4c, 0x00000000, 0x00000000, 0x000681a8, 0x000681a8, 0x00000000 },
-    { 0x0000aa50, 0x00000000, 0x00000000, 0x000681ac, 0x000681ac, 0x00000000 },
-    { 0x0000aa54, 0x00000000, 0x00000000, 0x0006821c, 0x0006821c, 0x00000000 },
-    { 0x0000aa58, 0x00000000, 0x00000000, 0x00068224, 0x00068224, 0x00000000 },
-    { 0x0000aa5c, 0x00000000, 0x00000000, 0x00068290, 0x00068290, 0x00000000 },
-    { 0x0000aa60, 0x00000000, 0x00000000, 0x00068300, 0x00068300, 0x00000000 },
-    { 0x0000aa64, 0x00000000, 0x00000000, 0x00068308, 0x00068308, 0x00000000 },
-    { 0x0000aa68, 0x00000000, 0x00000000, 0x0006830c, 0x0006830c, 0x00000000 },
-    { 0x0000aa6c, 0x00000000, 0x00000000, 0x00068310, 0x00068310, 0x00000000 },
-    { 0x0000aa70, 0x00000000, 0x00000000, 0x00068788, 0x00068788, 0x00000000 },
-    { 0x0000aa74, 0x00000000, 0x00000000, 0x0006878c, 0x0006878c, 0x00000000 },
-    { 0x0000aa78, 0x00000000, 0x00000000, 0x00068790, 0x00068790, 0x00000000 },
-    { 0x0000aa7c, 0x00000000, 0x00000000, 0x00068794, 0x00068794, 0x00000000 },
-    { 0x0000aa80, 0x00000000, 0x00000000, 0x00068798, 0x00068798, 0x00000000 },
-    { 0x0000aa84, 0x00000000, 0x00000000, 0x0006879c, 0x0006879c, 0x00000000 },
-    { 0x0000aa88, 0x00000000, 0x00000000, 0x00068b89, 0x00068b89, 0x00000000 },
-    { 0x0000aa8c, 0x00000000, 0x00000000, 0x00068b8d, 0x00068b8d, 0x00000000 },
-    { 0x0000aa90, 0x00000000, 0x00000000, 0x00068b91, 0x00068b91, 0x00000000 },
-    { 0x0000aa94, 0x00000000, 0x00000000, 0x00068b95, 0x00068b95, 0x00000000 },
-    { 0x0000aa98, 0x00000000, 0x00000000, 0x00068b99, 0x00068b99, 0x00000000 },
-    { 0x0000aa9c, 0x00000000, 0x00000000, 0x00068ba5, 0x00068ba5, 0x00000000 },
-    { 0x0000aaa0, 0x00000000, 0x00000000, 0x00068ba9, 0x00068ba9, 0x00000000 },
-    { 0x0000aaa4, 0x00000000, 0x00000000, 0x00068bad, 0x00068bad, 0x00000000 },
-    { 0x0000aaa8, 0x00000000, 0x00000000, 0x000b8b0c, 0x000b8b0c, 0x00000000 },
-    { 0x0000aaac, 0x00000000, 0x00000000, 0x000b8f10, 0x000b8f10, 0x00000000 },
-    { 0x0000aab0, 0x00000000, 0x00000000, 0x000b8f14, 0x000b8f14, 0x00000000 },
-    { 0x0000aab4, 0x00000000, 0x00000000, 0x000b8f84, 0x000b8f84, 0x00000000 },
-    { 0x0000aab8, 0x00000000, 0x00000000, 0x000b8f84, 0x000b8f84, 0x00000000 },
-    { 0x0000aabc, 0x00000000, 0x00000000, 0x000b8f88, 0x000b8f88, 0x00000000 },
-    { 0x0000aac0, 0x00000000, 0x00000000, 0x000bb380, 0x000bb380, 0x00000000 },
-    { 0x0000aac4, 0x00000000, 0x00000000, 0x000bb384, 0x000bb384, 0x00000000 },
-    { 0x0000aac8, 0x00000000, 0x00000000, 0x000bb388, 0x000bb388, 0x00000000 },
-    { 0x0000aacc, 0x00000000, 0x00000000, 0x000bb38c, 0x000bb38c, 0x00000000 },
-    { 0x0000aad0, 0x00000000, 0x00000000, 0x000bb394, 0x000bb394, 0x00000000 },
-    { 0x0000aad4, 0x00000000, 0x00000000, 0x000bb798, 0x000bb798, 0x00000000 },
-    { 0x0000aad8, 0x00000000, 0x00000000, 0x000f970c, 0x000f970c, 0x00000000 },
-    { 0x0000aadc, 0x00000000, 0x00000000, 0x000f9710, 0x000f9710, 0x00000000 },
-    { 0x0000aae0, 0x00000000, 0x00000000, 0x000f9714, 0x000f9714, 0x00000000 },
-    { 0x0000aae4, 0x00000000, 0x00000000, 0x000f9718, 0x000f9718, 0x00000000 },
-    { 0x0000aae8, 0x00000000, 0x00000000, 0x000f9705, 0x000f9705, 0x00000000 },
-    { 0x0000aaec, 0x00000000, 0x00000000, 0x000f9709, 0x000f9709, 0x00000000 },
-    { 0x0000aaf0, 0x00000000, 0x00000000, 0x000f970d, 0x000f970d, 0x00000000 },
-    { 0x0000aaf4, 0x00000000, 0x00000000, 0x000f9711, 0x000f9711, 0x00000000 },
-    { 0x0000aaf8, 0x00000000, 0x00000000, 0x000f9715, 0x000f9715, 0x00000000 },
-    { 0x0000aafc, 0x00000000, 0x00000000, 0x000f9719, 0x000f9719, 0x00000000 },
-    { 0x0000ab00, 0x00000000, 0x00000000, 0x000fb7a4, 0x000fb7a4, 0x00000000 },
-    { 0x0000ab04, 0x00000000, 0x00000000, 0x000fb7a8, 0x000fb7a8, 0x00000000 },
-    { 0x0000ab08, 0x00000000, 0x00000000, 0x000fb7ac, 0x000fb7ac, 0x00000000 },
-    { 0x0000ab0c, 0x00000000, 0x00000000, 0x000fb7ac, 0x000fb7ac, 0x00000000 },
-    { 0x0000ab10, 0x00000000, 0x00000000, 0x000fb7b0, 0x000fb7b0, 0x00000000 },
-    { 0x0000ab14, 0x00000000, 0x00000000, 0x000fb7b8, 0x000fb7b8, 0x00000000 },
-    { 0x0000ab18, 0x00000000, 0x00000000, 0x000fb7bc, 0x000fb7bc, 0x00000000 },
-    { 0x0000ab1c, 0x00000000, 0x00000000, 0x000fb7a1, 0x000fb7a1, 0x00000000 },
-    { 0x0000ab20, 0x00000000, 0x00000000, 0x000fb7a5, 0x000fb7a5, 0x00000000 },
-    { 0x0000ab24, 0x00000000, 0x00000000, 0x000fb7a9, 0x000fb7a9, 0x00000000 },
-    { 0x0000ab28, 0x00000000, 0x00000000, 0x000fb7b1, 0x000fb7b1, 0x00000000 },
-    { 0x0000ab2c, 0x00000000, 0x00000000, 0x000fb7b5, 0x000fb7b5, 0x00000000 },
-    { 0x0000ab30, 0x00000000, 0x00000000, 0x000fb7bd, 0x000fb7bd, 0x00000000 },
-    { 0x0000ab34, 0x00000000, 0x00000000, 0x000fb7c9, 0x000fb7c9, 0x00000000 },
-    { 0x0000ab38, 0x00000000, 0x00000000, 0x000fb7cd, 0x000fb7cd, 0x00000000 },
-    { 0x0000ab3c, 0x00000000, 0x00000000, 0x000fb7d1, 0x000fb7d1, 0x00000000 },
-    { 0x0000ab40, 0x00000000, 0x00000000, 0x000fb7d9, 0x000fb7d9, 0x00000000 },
-    { 0x0000ab44, 0x00000000, 0x00000000, 0x000fb7c2, 0x000fb7c2, 0x00000000 },
-    { 0x0000ab48, 0x00000000, 0x00000000, 0x000fb7c6, 0x000fb7c6, 0x00000000 },
-    { 0x0000ab4c, 0x00000000, 0x00000000, 0x000fb7ca, 0x000fb7ca, 0x00000000 },
-    { 0x0000ab50, 0x00000000, 0x00000000, 0x000fb7ce, 0x000fb7ce, 0x00000000 },
-    { 0x0000ab54, 0x00000000, 0x00000000, 0x000fb7d2, 0x000fb7d2, 0x00000000 },
-    { 0x0000ab58, 0x00000000, 0x00000000, 0x000fb7d6, 0x000fb7d6, 0x00000000 },
-    { 0x0000ab5c, 0x00000000, 0x00000000, 0x000fb7c3, 0x000fb7c3, 0x00000000 },
-    { 0x0000ab60, 0x00000000, 0x00000000, 0x000fb7cb, 0x000fb7cb, 0x00000000 },
-    { 0x0000ab64, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000ab68, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000ab6c, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000ab70, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000ab74, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000ab78, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000ab7c, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000ab80, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000ab84, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000ab88, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000ab8c, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000ab90, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000ab94, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000ab98, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000ab9c, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000aba0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000aba4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000aba8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000abac, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000abb0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000abb4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000abb8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000abbc, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000abc0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000abc4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000abc8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000abcc, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000abd0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000abd4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000abd8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000abdc, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000abe0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000abe4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000abe8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000abec, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000abf0, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000abf4, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000abf8, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000abfc, 0x00000000, 0x00000000, 0x000fb7d3, 0x000fb7d3, 0x00000000 },
-    { 0x0000a204, 0x00000004, 0x00000004, 0x00000004, 0x00000004, 0x00000004 },
-    { 0x0000a20c, 0x00000014, 0x00000014, 0x00000000, 0x00000000, 0x0001f000 },
-    { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a },
-    { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
-    { 0x0000a250, 0x001ff000, 0x001ff000, 0x001ca000, 0x001ca000, 0x001da000 },
-    { 0x0000a274, 0x0a81c652, 0x0a81c652, 0x0a820652, 0x0a820652, 0x0a82a652 },
-    { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x0000a304, 0x00000000, 0x00000000, 0x00007201, 0x00007201, 0x00000000 },
-    { 0x0000a308, 0x00000000, 0x00000000, 0x00010408, 0x00010408, 0x00000000 },
-    { 0x0000a30c, 0x00000000, 0x00000000, 0x0001860a, 0x0001860a, 0x00000000 },
-    { 0x0000a310, 0x00000000, 0x00000000, 0x00020818, 0x00020818, 0x00000000 },
-    { 0x0000a314, 0x00000000, 0x00000000, 0x00024858, 0x00024858, 0x00000000 },
-    { 0x0000a318, 0x00000000, 0x00000000, 0x00026859, 0x00026859, 0x00000000 },
-    { 0x0000a31c, 0x00000000, 0x00000000, 0x0002985b, 0x0002985b, 0x00000000 },
-    { 0x0000a320, 0x00000000, 0x00000000, 0x0002c89a, 0x0002c89a, 0x00000000 },
-    { 0x0000a324, 0x00000000, 0x00000000, 0x0002e89b, 0x0002e89b, 0x00000000 },
-    { 0x0000a328, 0x00000000, 0x00000000, 0x0003089c, 0x0003089c, 0x00000000 },
-    { 0x0000a32c, 0x00000000, 0x00000000, 0x0003289d, 0x0003289d, 0x00000000 },
-    { 0x0000a330, 0x00000000, 0x00000000, 0x0003489e, 0x0003489e, 0x00000000 },
-    { 0x0000a334, 0x00000000, 0x00000000, 0x000388de, 0x000388de, 0x00000000 },
-    { 0x0000a338, 0x00000000, 0x00000000, 0x0003b91e, 0x0003b91e, 0x00000000 },
-    { 0x0000a33c, 0x00000000, 0x00000000, 0x0003d95e, 0x0003d95e, 0x00000000 },
-    { 0x0000a340, 0x00000000, 0x00000000, 0x000419df, 0x000419df, 0x00000000 },
-    { 0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
-    { 0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e },
-};
-
-static const u_int32_t ar9285Common_9285[][2] = {
-    { 0x0000000c, 0x00000000 },
-    { 0x00000030, 0x00020045 },
-    { 0x00000034, 0x00000005 },
-    { 0x00000040, 0x00000000 },
-    { 0x00000044, 0x00000008 },
-    { 0x00000048, 0x00000008 },
-    { 0x0000004c, 0x00000010 },
-    { 0x00000050, 0x00000000 },
-    { 0x00000054, 0x0000001f },
-    { 0x00000800, 0x00000000 },
-    { 0x00000804, 0x00000000 },
-    { 0x00000808, 0x00000000 },
-    { 0x0000080c, 0x00000000 },
-    { 0x00000810, 0x00000000 },
-    { 0x00000814, 0x00000000 },
-    { 0x00000818, 0x00000000 },
-    { 0x0000081c, 0x00000000 },
-    { 0x00000820, 0x00000000 },
-    { 0x00000824, 0x00000000 },
-    { 0x00001040, 0x002ffc0f },
-    { 0x00001044, 0x002ffc0f },
-    { 0x00001048, 0x002ffc0f },
-    { 0x0000104c, 0x002ffc0f },
-    { 0x00001050, 0x002ffc0f },
-    { 0x00001054, 0x002ffc0f },
-    { 0x00001058, 0x002ffc0f },
-    { 0x0000105c, 0x002ffc0f },
-    { 0x00001060, 0x002ffc0f },
-    { 0x00001064, 0x002ffc0f },
-    { 0x00001230, 0x00000000 },
-    { 0x00001270, 0x00000000 },
-    { 0x00001038, 0x00000000 },
-    { 0x00001078, 0x00000000 },
-    { 0x000010b8, 0x00000000 },
-    { 0x000010f8, 0x00000000 },
-    { 0x00001138, 0x00000000 },
-    { 0x00001178, 0x00000000 },
-    { 0x000011b8, 0x00000000 },
-    { 0x000011f8, 0x00000000 },
-    { 0x00001238, 0x00000000 },
-    { 0x00001278, 0x00000000 },
-    { 0x000012b8, 0x00000000 },
-    { 0x000012f8, 0x00000000 },
-    { 0x00001338, 0x00000000 },
-    { 0x00001378, 0x00000000 },
-    { 0x000013b8, 0x00000000 },
-    { 0x000013f8, 0x00000000 },
-    { 0x00001438, 0x00000000 },
-    { 0x00001478, 0x00000000 },
-    { 0x000014b8, 0x00000000 },
-    { 0x000014f8, 0x00000000 },
-    { 0x00001538, 0x00000000 },
-    { 0x00001578, 0x00000000 },
-    { 0x000015b8, 0x00000000 },
-    { 0x000015f8, 0x00000000 },
-    { 0x00001638, 0x00000000 },
-    { 0x00001678, 0x00000000 },
-    { 0x000016b8, 0x00000000 },
-    { 0x000016f8, 0x00000000 },
-    { 0x00001738, 0x00000000 },
-    { 0x00001778, 0x00000000 },
-    { 0x000017b8, 0x00000000 },
-    { 0x000017f8, 0x00000000 },
-    { 0x0000103c, 0x00000000 },
-    { 0x0000107c, 0x00000000 },
-    { 0x000010bc, 0x00000000 },
-    { 0x000010fc, 0x00000000 },
-    { 0x0000113c, 0x00000000 },
-    { 0x0000117c, 0x00000000 },
-    { 0x000011bc, 0x00000000 },
-    { 0x000011fc, 0x00000000 },
-    { 0x0000123c, 0x00000000 },
-    { 0x0000127c, 0x00000000 },
-    { 0x000012bc, 0x00000000 },
-    { 0x000012fc, 0x00000000 },
-    { 0x0000133c, 0x00000000 },
-    { 0x0000137c, 0x00000000 },
-    { 0x000013bc, 0x00000000 },
-    { 0x000013fc, 0x00000000 },
-    { 0x0000143c, 0x00000000 },
-    { 0x0000147c, 0x00000000 },
-    { 0x00004030, 0x00000002 },
-    { 0x0000403c, 0x00000002 },
-    { 0x00004024, 0x0000001f },
-    { 0x00004060, 0x00000000 },
-    { 0x00004064, 0x00000000 },
-    { 0x00007010, 0x00000031 },
-    { 0x00007034, 0x00000002 },
-    { 0x00007038, 0x000004c2 },
-    { 0x00008004, 0x00000000 },
-    { 0x00008008, 0x00000000 },
-    { 0x0000800c, 0x00000000 },
-    { 0x00008018, 0x00000700 },
-    { 0x00008020, 0x00000000 },
-    { 0x00008038, 0x00000000 },
-    { 0x0000803c, 0x00000000 },
-    { 0x00008048, 0x00000000 },
-    { 0x00008054, 0x00000000 },
-    { 0x00008058, 0x00000000 },
-    { 0x0000805c, 0x000fc78f },
-    { 0x00008060, 0x0000000f },
-    { 0x00008064, 0x00000000 },
-    { 0x00008070, 0x00000000 },
-    { 0x000080c0, 0x2a80001a },
-    { 0x000080c4, 0x05dc01e0 },
-    { 0x000080c8, 0x1f402710 },
-    { 0x000080cc, 0x01f40000 },
-    { 0x000080d0, 0x00001e00 },
-    { 0x000080d4, 0x00000000 },
-    { 0x000080d8, 0x00400000 },
-    { 0x000080e0, 0xffffffff },
-    { 0x000080e4, 0x0000ffff },
-    { 0x000080e8, 0x003f3f3f },
-    { 0x000080ec, 0x00000000 },
-    { 0x000080f0, 0x00000000 },
-    { 0x000080f4, 0x00000000 },
-    { 0x000080f8, 0x00000000 },
-    { 0x000080fc, 0x00020000 },
-    { 0x00008100, 0x00020000 },
-    { 0x00008104, 0x00000001 },
-    { 0x00008108, 0x00000052 },
-    { 0x0000810c, 0x00000000 },
-    { 0x00008110, 0x00000168 },
-    { 0x00008118, 0x000100aa },
-    { 0x0000811c, 0x00003210 },
-    { 0x00008120, 0x08f04800 },
-    { 0x00008124, 0x00000000 },
-    { 0x00008128, 0x00000000 },
-    { 0x0000812c, 0x00000000 },
-    { 0x00008130, 0x00000000 },
-    { 0x00008134, 0x00000000 },
-    { 0x00008138, 0x00000000 },
-    { 0x0000813c, 0x00000000 },
-    { 0x00008144, 0x00000000 },
-    { 0x00008168, 0x00000000 },
-    { 0x0000816c, 0x00000000 },
-    { 0x00008170, 0x32143320 },
-    { 0x00008174, 0xfaa4fa50 },
-    { 0x00008178, 0x00000100 },
-    { 0x0000817c, 0x00000000 },
-    { 0x000081c0, 0x00000000 },
-    { 0x000081d0, 0x00003210 },
-    { 0x000081ec, 0x00000000 },
-    { 0x000081f0, 0x00000000 },
-    { 0x000081f4, 0x00000000 },
-    { 0x000081f8, 0x00000000 },
-    { 0x000081fc, 0x00000000 },
-    { 0x00008200, 0x00000000 },
-    { 0x00008204, 0x00000000 },
-    { 0x00008208, 0x00000000 },
-    { 0x0000820c, 0x00000000 },
-    { 0x00008210, 0x00000000 },
-    { 0x00008214, 0x00000000 },
-    { 0x00008218, 0x00000000 },
-    { 0x0000821c, 0x00000000 },
-    { 0x00008220, 0x00000000 },
-    { 0x00008224, 0x00000000 },
-    { 0x00008228, 0x00000000 },
-    { 0x0000822c, 0x00000000 },
-    { 0x00008230, 0x00000000 },
-    { 0x00008234, 0x00000000 },
-    { 0x00008238, 0x00000000 },
-    { 0x0000823c, 0x00000000 },
-    { 0x00008240, 0x00100000 },
-    { 0x00008244, 0x0010f400 },
-    { 0x00008248, 0x00000100 },
-    { 0x0000824c, 0x0001e800 },
-    { 0x00008250, 0x00000000 },
-    { 0x00008254, 0x00000000 },
-    { 0x00008258, 0x00000000 },
-    { 0x0000825c, 0x400000ff },
-    { 0x00008260, 0x00080922 },
-    { 0x00008264, 0xa8a00010 },
-    { 0x00008270, 0x00000000 },
-    { 0x00008274, 0x40000000 },
-    { 0x00008278, 0x003e4180 },
-    { 0x0000827c, 0x00000000 },
-    { 0x00008284, 0x0000002c },
-    { 0x00008288, 0x0000002c },
-    { 0x0000828c, 0x00000000 },
-    { 0x00008294, 0x00000000 },
-    { 0x00008298, 0x00000000 },
-    { 0x0000829c, 0x00000000 },
-    { 0x00008300, 0x00000040 },
-    { 0x00008314, 0x00000000 },
-    { 0x00008328, 0x00000000 },
-    { 0x0000832c, 0x00000001 },
-    { 0x00008330, 0x00000302 },
-    { 0x00008334, 0x00000e00 },
-    { 0x00008338, 0x00000000 },
-    { 0x0000833c, 0x00000000 },
-    { 0x00008340, 0x00010380 },
-    { 0x00008344, 0x00581043 },
-    { 0x00009808, 0x00000000 },
-    { 0x0000980c, 0xafe68e30 },
-    { 0x00009810, 0xfd14e000 },
-    { 0x00009814, 0x9c0a9f6b },
-    { 0x0000981c, 0x00000000 },
-    { 0x0000982c, 0x0000a000 },
-    { 0x00009830, 0x00000000 },
-    { 0x0000983c, 0x00200400 },
-    { 0x0000984c, 0x0040233c },
-    { 0x00009854, 0x00000044 },
-    { 0x00009900, 0x00000000 },
-    { 0x00009904, 0x00000000 },
-    { 0x00009908, 0x00000000 },
-    { 0x0000990c, 0x00000000 },
-    { 0x00009910, 0x01002310 },
-    { 0x0000991c, 0x10000fff },
-    { 0x00009920, 0x04900000 },
-    { 0x00009928, 0x00000001 },
-    { 0x0000992c, 0x00000004 },
-    { 0x00009934, 0x1e1f2022 },
-    { 0x00009938, 0x0a0b0c0d },
-    { 0x0000993c, 0x00000000 },
-    { 0x00009940, 0x14750604 },
-    { 0x00009948, 0x9280c00a },
-    { 0x0000994c, 0x00020028 },
-    { 0x00009954, 0x5f3ca3de },
-    { 0x00009958, 0x2108ecff },
-    { 0x00009968, 0x000003ce },
-    { 0x00009970, 0x1927b515 },
-    { 0x00009974, 0x00000000 },
-    { 0x00009978, 0x00000001 },
-    { 0x0000997c, 0x00000000 },
-    { 0x00009980, 0x00000000 },
-    { 0x00009984, 0x00000000 },
-    { 0x00009988, 0x00000000 },
-    { 0x0000998c, 0x00000000 },
-    { 0x00009990, 0x00000000 },
-    { 0x00009994, 0x00000000 },
-    { 0x00009998, 0x00000000 },
-    { 0x0000999c, 0x00000000 },
-    { 0x000099a0, 0x00000000 },
-    { 0x000099a4, 0x00000001 },
-    { 0x000099a8, 0x201fff00 },
-    { 0x000099ac, 0x2def0a00 },
-    { 0x000099b0, 0x03051000 },
-    { 0x000099b4, 0x00000820 },
-    { 0x000099dc, 0x00000000 },
-    { 0x000099e0, 0x00000000 },
-    { 0x000099e4, 0xaaaaaaaa },
-    { 0x000099e8, 0x3c466478 },
-    { 0x000099ec, 0x0cc80caa },
-    { 0x000099f0, 0x00000000 },
-    { 0x0000a208, 0x803e6788 },
-    { 0x0000a210, 0x4080a333 },
-    { 0x0000a214, 0x00206c10 },
-    { 0x0000a218, 0x009c4060 },
-    { 0x0000a220, 0x01834061 },
-    { 0x0000a224, 0x00000400 },
-    { 0x0000a228, 0x000003b5 },
-    { 0x0000a22c, 0x00000000 },
-    { 0x0000a234, 0x20202020 },
-    { 0x0000a238, 0x20202020 },
-    { 0x0000a244, 0x00000000 },
-    { 0x0000a248, 0xfffffffc },
-    { 0x0000a24c, 0x00000000 },
-    { 0x0000a254, 0x00000000 },
-    { 0x0000a258, 0x0ccb5380 },
-    { 0x0000a25c, 0x15151501 },
-    { 0x0000a260, 0xdfa90f01 },
-    { 0x0000a268, 0x00000000 },
-    { 0x0000a26c, 0x0ebae9e6 },
-    { 0x0000d270, 0x0d820820 },
-    { 0x0000a278, 0x39ce739c },
-    { 0x0000a27c, 0x050e039c },
-    { 0x0000d35c, 0x07ffffef },
-    { 0x0000d360, 0x0fffffe7 },
-    { 0x0000d364, 0x17ffffe5 },
-    { 0x0000d368, 0x1fffffe4 },
-    { 0x0000d36c, 0x37ffffe3 },
-    { 0x0000d370, 0x3fffffe3 },
-    { 0x0000d374, 0x57ffffe3 },
-    { 0x0000d378, 0x5fffffe2 },
-    { 0x0000d37c, 0x7fffffe2 },
-    { 0x0000d380, 0x7f3c7bba },
-    { 0x0000d384, 0xf3307ff0 },
-    { 0x0000a388, 0x0c000000 },
-    { 0x0000a38c, 0x20202020 },
-    { 0x0000a390, 0x20202020 },
-    { 0x0000a394, 0x39ce739c },
-    { 0x0000a398, 0x0000039c },
-    { 0x0000a39c, 0x00000001 },
-    { 0x0000a3a0, 0x00000000 },
-    { 0x0000a3a4, 0x00000000 },
-    { 0x0000a3a8, 0x00000000 },
-    { 0x0000a3ac, 0x00000000 },
-    { 0x0000a3b0, 0x00000000 },
-    { 0x0000a3b4, 0x00000000 },
-    { 0x0000a3b8, 0x00000000 },
-    { 0x0000a3bc, 0x00000000 },
-    { 0x0000a3c0, 0x00000000 },
-    { 0x0000a3c4, 0x00000000 },
-    { 0x0000a3cc, 0x20202020 },
-    { 0x0000a3d0, 0x20202020 },
-    { 0x0000a3d4, 0x20202020 },
-    { 0x0000a3dc, 0x39ce739c },
-    { 0x0000a3e0, 0x0000039c },
-    { 0x0000a3e4, 0x00000000 },
-    { 0x0000a3e8, 0x18c43433 },
-    { 0x0000a3ec, 0x00f70081 },
-    { 0x00007800, 0x00140000 },
-    { 0x00007804, 0x0e4548d8 },
-    { 0x00007808, 0x54214514 },
-    { 0x0000780c, 0x02025820 },
-    { 0x00007810, 0x71c0d388 },
-    { 0x00007814, 0x924934a8 },
-    { 0x0000781c, 0x00000000 },
-    { 0x00007820, 0x00000c04 },
-    { 0x00007824, 0x00d86fff },
-    { 0x00007828, 0x26d2491b },
-    { 0x0000782c, 0x6e36d97b },
-    { 0x00007830, 0xedb6d96c },
-    { 0x00007834, 0x71400086 },
-    { 0x00007838, 0xfac68800 },
-    { 0x0000783c, 0x0001fffe },
-    { 0x00007840, 0xffeb1a20 },
-    { 0x00007844, 0x000c0db6 },
-    { 0x00007848, 0x6db61b6f },
-    { 0x0000784c, 0x6d9b66db },
-    { 0x00007850, 0x6d8c6dba },
-    { 0x00007854, 0x00040000 },
-    { 0x00007858, 0xdb003012 },
-    { 0x0000785c, 0x04924914 },
-    { 0x00007860, 0x21084210 },
-    { 0x00007864, 0xf7d7ffde },
-    { 0x00007868, 0xc2034080 },
-    { 0x0000786c, 0x48609eb4 },
-    { 0x00007870, 0x10142c00 },
-};
-
-static const u_int32_t ar9285PciePhy_clkreq_always_on_L1_9285[][2] = {
-    {0x00004040,  0x9248fd00 },
-    {0x00004040,  0x24924924 },
-    {0x00004040,  0xa8000019 },
-    {0x00004040,  0x13160820 },
-    {0x00004040,  0xe5980560 },
-    {0x00004040,  0xc01dcffd },
-    {0x00004040,  0x1aaabe41 },
-    {0x00004040,  0xbe105554 },
-    {0x00004040,  0x00043007 },
-    {0x00004044,  0x00000000 },
-};
-
-static const u_int32_t ar9285PciePhy_clkreq_off_L1_9285[][2] = {
-    {0x00004040,  0x9248fd00 },
-    {0x00004040,  0x24924924 },
-    {0x00004040,  0xa8000019 },
-    {0x00004040,  0x13160820 },
-    {0x00004040,  0xe5980560 },
-    {0x00004040,  0xc01dcffc },
-    {0x00004040,  0x1aaabe41 },
-    {0x00004040,  0xbe105554 },
-    {0x00004040,  0x00043007 },
-    {0x00004044,  0x00000000 },
-};
-
-/* AR9285 v1_2 PCI Register Writes.  Created: 03/04/09 */
-static const u_int32_t ar9285Modes_9285_1_2[][6] = {
-    { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
-    { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
-    { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
-    { 0x000010f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008 },
-    { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 },
-    { 0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b, 0x0988004f },
-    { 0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440, 0x00006880 },
-    { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 },
-    { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 },
-    { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
-    { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 },
-    { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
-    { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 },
-    { 0x00009840, 0x206a012e, 0x206a012e, 0x206a012e, 0x206a012e, 0x206a012e },
-    { 0x00009844, 0x0372161e, 0x0372161e, 0x03721620, 0x03721620, 0x037216a0 },
-    { 0x00009848, 0x00001066, 0x00001066, 0x00001053, 0x00001053, 0x00001059 },
-    { 0x00009850, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2 },
-    { 0x00009858, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e },
-    { 0x0000985c, 0x3139605e, 0x3139605e, 0x3137605e, 0x3137605e, 0x3139605e },
-    { 0x00009860, 0x00058d18, 0x00058d18, 0x00058d20, 0x00058d20, 0x00058d18 },
-    { 0x00009864, 0x0000fe00, 0x0000fe00, 0x0001ce00, 0x0001ce00, 0x0001ce00 },
-    { 0x00009868, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0 },
-    { 0x0000986c, 0x06903081, 0x06903081, 0x06903881, 0x06903881, 0x06903881 },
-    { 0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0 },
-    { 0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016 },
-    { 0x00009924, 0xd00a8007, 0xd00a8007, 0xd00a800d, 0xd00a800d, 0xd00a800d },
-    { 0x00009944, 0xffbc1010, 0xffbc1010, 0xffbc1020, 0xffbc1020, 0xffbc1010 },
-    { 0x00009960, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x00009964, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x000099b8, 0x0000421c, 0x0000421c, 0x0000421c, 0x0000421c, 0x0000421c },
-    { 0x000099bc, 0x00000600, 0x00000600, 0x00000c00, 0x00000c00, 0x00000c00 },
-    { 0x000099c0, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4 },
-    { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 },
-    { 0x000099c8, 0x6af65329, 0x6af65329, 0x6af65329, 0x6af65329, 0x6af65329 },
-    { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 },
-    { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 },
-    { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x00009a00, 0x00000000, 0x00000000, 0x00058084, 0x00058084, 0x00000000 },
-    { 0x00009a04, 0x00000000, 0x00000000, 0x00058088, 0x00058088, 0x00000000 },
-    { 0x00009a08, 0x00000000, 0x00000000, 0x0005808c, 0x0005808c, 0x00000000 },
-    { 0x00009a0c, 0x00000000, 0x00000000, 0x00058100, 0x00058100, 0x00000000 },
-    { 0x00009a10, 0x00000000, 0x00000000, 0x00058104, 0x00058104, 0x00000000 },
-    { 0x00009a14, 0x00000000, 0x00000000, 0x00058108, 0x00058108, 0x00000000 },
-    { 0x00009a18, 0x00000000, 0x00000000, 0x0005810c, 0x0005810c, 0x00000000 },
-    { 0x00009a1c, 0x00000000, 0x00000000, 0x00058110, 0x00058110, 0x00000000 },
-    { 0x00009a20, 0x00000000, 0x00000000, 0x00058114, 0x00058114, 0x00000000 },
-    { 0x00009a24, 0x00000000, 0x00000000, 0x00058180, 0x00058180, 0x00000000 },
-    { 0x00009a28, 0x00000000, 0x00000000, 0x00058184, 0x00058184, 0x00000000 },
-    { 0x00009a2c, 0x00000000, 0x00000000, 0x00058188, 0x00058188, 0x00000000 },
-    { 0x00009a30, 0x00000000, 0x00000000, 0x0005818c, 0x0005818c, 0x00000000 },
-    { 0x00009a34, 0x00000000, 0x00000000, 0x00058190, 0x00058190, 0x00000000 },
-    { 0x00009a38, 0x00000000, 0x00000000, 0x00058194, 0x00058194, 0x00000000 },
-    { 0x00009a3c, 0x00000000, 0x00000000, 0x000581a0, 0x000581a0, 0x00000000 },
-    { 0x00009a40, 0x00000000, 0x00000000, 0x0005820c, 0x0005820c, 0x00000000 },
-    { 0x00009a44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000 },
-    { 0x00009a48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000 },
-    { 0x00009a4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000 },
-    { 0x00009a50, 0x00000000, 0x00000000, 0x00058220, 0x00058220, 0x00000000 },
-    { 0x00009a54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000 },
-    { 0x00009a58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000 },
-    { 0x00009a5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000 },
-    { 0x00009a60, 0x00000000, 0x00000000, 0x00058308, 0x00058308, 0x00000000 },
-    { 0x00009a64, 0x00000000, 0x00000000, 0x0005830c, 0x0005830c, 0x00000000 },
-    { 0x00009a68, 0x00000000, 0x00000000, 0x00058380, 0x00058380, 0x00000000 },
-    { 0x00009a6c, 0x00000000, 0x00000000, 0x00058384, 0x00058384, 0x00000000 },
-    { 0x00009a70, 0x00000000, 0x00000000, 0x00068700, 0x00068700, 0x00000000 },
-    { 0x00009a74, 0x00000000, 0x00000000, 0x00068704, 0x00068704, 0x00000000 },
-    { 0x00009a78, 0x00000000, 0x00000000, 0x00068708, 0x00068708, 0x00000000 },
-    { 0x00009a7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000 },
-    { 0x00009a80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000 },
-    { 0x00009a84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000 },
-    { 0x00009a88, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000 },
-    { 0x00009a8c, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 },
-    { 0x00009a90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 },
-    { 0x00009a94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000 },
-    { 0x00009a98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000 },
-    { 0x00009a9c, 0x00000000, 0x00000000, 0x00078b84, 0x00078b84, 0x00000000 },
-    { 0x00009aa0, 0x00000000, 0x00000000, 0x00078b88, 0x00078b88, 0x00000000 },
-    { 0x00009aa4, 0x00000000, 0x00000000, 0x00078b8c, 0x00078b8c, 0x00000000 },
-    { 0x00009aa8, 0x00000000, 0x00000000, 0x00078b90, 0x00078b90, 0x00000000 },
-    { 0x00009aac, 0x00000000, 0x00000000, 0x000caf80, 0x000caf80, 0x00000000 },
-    { 0x00009ab0, 0x00000000, 0x00000000, 0x000caf84, 0x000caf84, 0x00000000 },
-    { 0x00009ab4, 0x00000000, 0x00000000, 0x000caf88, 0x000caf88, 0x00000000 },
-    { 0x00009ab8, 0x00000000, 0x00000000, 0x000caf8c, 0x000caf8c, 0x00000000 },
-    { 0x00009abc, 0x00000000, 0x00000000, 0x000caf90, 0x000caf90, 0x00000000 },
-    { 0x00009ac0, 0x00000000, 0x00000000, 0x000db30c, 0x000db30c, 0x00000000 },
-    { 0x00009ac4, 0x00000000, 0x00000000, 0x000db310, 0x000db310, 0x00000000 },
-    { 0x00009ac8, 0x00000000, 0x00000000, 0x000db384, 0x000db384, 0x00000000 },
-    { 0x00009acc, 0x00000000, 0x00000000, 0x000db388, 0x000db388, 0x00000000 },
-    { 0x00009ad0, 0x00000000, 0x00000000, 0x000db324, 0x000db324, 0x00000000 },
-    { 0x00009ad4, 0x00000000, 0x00000000, 0x000eb704, 0x000eb704, 0x00000000 },
-    { 0x00009ad8, 0x00000000, 0x00000000, 0x000eb6a4, 0x000eb6a4, 0x00000000 },
-    { 0x00009adc, 0x00000000, 0x00000000, 0x000eb6a8, 0x000eb6a8, 0x00000000 },
-    { 0x00009ae0, 0x00000000, 0x00000000, 0x000eb710, 0x000eb710, 0x00000000 },
-    { 0x00009ae4, 0x00000000, 0x00000000, 0x000eb714, 0x000eb714, 0x00000000 },
-    { 0x00009ae8, 0x00000000, 0x00000000, 0x000eb720, 0x000eb720, 0x00000000 },
-    { 0x00009aec, 0x00000000, 0x00000000, 0x000eb724, 0x000eb724, 0x00000000 },
-    { 0x00009af0, 0x00000000, 0x00000000, 0x000eb728, 0x000eb728, 0x00000000 },
-    { 0x00009af4, 0x00000000, 0x00000000, 0x000eb72c, 0x000eb72c, 0x00000000 },
-    { 0x00009af8, 0x00000000, 0x00000000, 0x000eb7a0, 0x000eb7a0, 0x00000000 },
-    { 0x00009afc, 0x00000000, 0x00000000, 0x000eb7a4, 0x000eb7a4, 0x00000000 },
-    { 0x00009b00, 0x00000000, 0x00000000, 0x000eb7a8, 0x000eb7a8, 0x00000000 },
-    { 0x00009b04, 0x00000000, 0x00000000, 0x000eb7b0, 0x000eb7b0, 0x00000000 },
-    { 0x00009b08, 0x00000000, 0x00000000, 0x000eb7b4, 0x000eb7b4, 0x00000000 },
-    { 0x00009b0c, 0x00000000, 0x00000000, 0x000eb7b8, 0x000eb7b8, 0x00000000 },
-    { 0x00009b10, 0x00000000, 0x00000000, 0x000eb7a5, 0x000eb7a5, 0x00000000 },
-    { 0x00009b14, 0x00000000, 0x00000000, 0x000eb7a9, 0x000eb7a9, 0x00000000 },
-    { 0x00009b18, 0x00000000, 0x00000000, 0x000eb7ad, 0x000eb7ad, 0x00000000 },
-    { 0x00009b1c, 0x00000000, 0x00000000, 0x000eb7b1, 0x000eb7b1, 0x00000000 },
-    { 0x00009b20, 0x00000000, 0x00000000, 0x000eb7b5, 0x000eb7b5, 0x00000000 },
-    { 0x00009b24, 0x00000000, 0x00000000, 0x000eb7b9, 0x000eb7b9, 0x00000000 },
-    { 0x00009b28, 0x00000000, 0x00000000, 0x000eb7c5, 0x000eb7c5, 0x00000000 },
-    { 0x00009b2c, 0x00000000, 0x00000000, 0x000eb7c9, 0x000eb7c9, 0x00000000 },
-    { 0x00009b30, 0x00000000, 0x00000000, 0x000eb7d1, 0x000eb7d1, 0x00000000 },
-    { 0x00009b34, 0x00000000, 0x00000000, 0x000eb7d5, 0x000eb7d5, 0x00000000 },
-    { 0x00009b38, 0x00000000, 0x00000000, 0x000eb7d9, 0x000eb7d9, 0x00000000 },
-    { 0x00009b3c, 0x00000000, 0x00000000, 0x000eb7c6, 0x000eb7c6, 0x00000000 },
-    { 0x00009b40, 0x00000000, 0x00000000, 0x000eb7ca, 0x000eb7ca, 0x00000000 },
-    { 0x00009b44, 0x00000000, 0x00000000, 0x000eb7ce, 0x000eb7ce, 0x00000000 },
-    { 0x00009b48, 0x00000000, 0x00000000, 0x000eb7d2, 0x000eb7d2, 0x00000000 },
-    { 0x00009b4c, 0x00000000, 0x00000000, 0x000eb7d6, 0x000eb7d6, 0x00000000 },
-    { 0x00009b50, 0x00000000, 0x00000000, 0x000eb7c3, 0x000eb7c3, 0x00000000 },
-    { 0x00009b54, 0x00000000, 0x00000000, 0x000eb7c7, 0x000eb7c7, 0x00000000 },
-    { 0x00009b58, 0x00000000, 0x00000000, 0x000eb7cb, 0x000eb7cb, 0x00000000 },
-    { 0x00009b5c, 0x00000000, 0x00000000, 0x000eb7cf, 0x000eb7cf, 0x00000000 },
-    { 0x00009b60, 0x00000000, 0x00000000, 0x000eb7d7, 0x000eb7d7, 0x00000000 },
-    { 0x00009b64, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009b68, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009b6c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009b70, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009b74, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009b78, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009b7c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009b80, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009b84, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009b88, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009b8c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009b90, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009b94, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009b98, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009b9c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009ba0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009ba4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009ba8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009bac, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009bb0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009bb4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009bb8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009bbc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009bc0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009bc4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009bc8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009bcc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009bd0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009bd4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009bd8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009bdc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009be0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009be4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009be8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009bec, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009bf0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009bf4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009bf8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x00009bfc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000aa00, 0x00000000, 0x00000000, 0x00058084, 0x00058084, 0x00000000 },
-    { 0x0000aa04, 0x00000000, 0x00000000, 0x00058088, 0x00058088, 0x00000000 },
-    { 0x0000aa08, 0x00000000, 0x00000000, 0x0005808c, 0x0005808c, 0x00000000 },
-    { 0x0000aa0c, 0x00000000, 0x00000000, 0x00058100, 0x00058100, 0x00000000 },
-    { 0x0000aa10, 0x00000000, 0x00000000, 0x00058104, 0x00058104, 0x00000000 },
-    { 0x0000aa14, 0x00000000, 0x00000000, 0x00058108, 0x00058108, 0x00000000 },
-    { 0x0000aa18, 0x00000000, 0x00000000, 0x0005810c, 0x0005810c, 0x00000000 },
-    { 0x0000aa1c, 0x00000000, 0x00000000, 0x00058110, 0x00058110, 0x00000000 },
-    { 0x0000aa20, 0x00000000, 0x00000000, 0x00058114, 0x00058114, 0x00000000 },
-    { 0x0000aa24, 0x00000000, 0x00000000, 0x00058180, 0x00058180, 0x00000000 },
-    { 0x0000aa28, 0x00000000, 0x00000000, 0x00058184, 0x00058184, 0x00000000 },
-    { 0x0000aa2c, 0x00000000, 0x00000000, 0x00058188, 0x00058188, 0x00000000 },
-    { 0x0000aa30, 0x00000000, 0x00000000, 0x0005818c, 0x0005818c, 0x00000000 },
-    { 0x0000aa34, 0x00000000, 0x00000000, 0x00058190, 0x00058190, 0x00000000 },
-    { 0x0000aa38, 0x00000000, 0x00000000, 0x00058194, 0x00058194, 0x00000000 },
-    { 0x0000aa3c, 0x00000000, 0x00000000, 0x000581a0, 0x000581a0, 0x00000000 },
-    { 0x0000aa40, 0x00000000, 0x00000000, 0x0005820c, 0x0005820c, 0x00000000 },
-    { 0x0000aa44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000 },
-    { 0x0000aa48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000 },
-    { 0x0000aa4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000 },
-    { 0x0000aa50, 0x00000000, 0x00000000, 0x00058220, 0x00058220, 0x00000000 },
-    { 0x0000aa54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000 },
-    { 0x0000aa58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000 },
-    { 0x0000aa5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000 },
-    { 0x0000aa60, 0x00000000, 0x00000000, 0x00058308, 0x00058308, 0x00000000 },
-    { 0x0000aa64, 0x00000000, 0x00000000, 0x0005830c, 0x0005830c, 0x00000000 },
-    { 0x0000aa68, 0x00000000, 0x00000000, 0x00058380, 0x00058380, 0x00000000 },
-    { 0x0000aa6c, 0x00000000, 0x00000000, 0x00058384, 0x00058384, 0x00000000 },
-    { 0x0000aa70, 0x00000000, 0x00000000, 0x00068700, 0x00068700, 0x00000000 },
-    { 0x0000aa74, 0x00000000, 0x00000000, 0x00068704, 0x00068704, 0x00000000 },
-    { 0x0000aa78, 0x00000000, 0x00000000, 0x00068708, 0x00068708, 0x00000000 },
-    { 0x0000aa7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000 },
-    { 0x0000aa80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000 },
-    { 0x0000aa84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000 },
-    { 0x0000aa88, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000 },
-    { 0x0000aa8c, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 },
-    { 0x0000aa90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 },
-    { 0x0000aa94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000 },
-    { 0x0000aa98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000 },
-    { 0x0000aa9c, 0x00000000, 0x00000000, 0x00078b84, 0x00078b84, 0x00000000 },
-    { 0x0000aaa0, 0x00000000, 0x00000000, 0x00078b88, 0x00078b88, 0x00000000 },
-    { 0x0000aaa4, 0x00000000, 0x00000000, 0x00078b8c, 0x00078b8c, 0x00000000 },
-    { 0x0000aaa8, 0x00000000, 0x00000000, 0x00078b90, 0x00078b90, 0x00000000 },
-    { 0x0000aaac, 0x00000000, 0x00000000, 0x000caf80, 0x000caf80, 0x00000000 },
-    { 0x0000aab0, 0x00000000, 0x00000000, 0x000caf84, 0x000caf84, 0x00000000 },
-    { 0x0000aab4, 0x00000000, 0x00000000, 0x000caf88, 0x000caf88, 0x00000000 },
-    { 0x0000aab8, 0x00000000, 0x00000000, 0x000caf8c, 0x000caf8c, 0x00000000 },
-    { 0x0000aabc, 0x00000000, 0x00000000, 0x000caf90, 0x000caf90, 0x00000000 },
-    { 0x0000aac0, 0x00000000, 0x00000000, 0x000db30c, 0x000db30c, 0x00000000 },
-    { 0x0000aac4, 0x00000000, 0x00000000, 0x000db310, 0x000db310, 0x00000000 },
-    { 0x0000aac8, 0x00000000, 0x00000000, 0x000db384, 0x000db384, 0x00000000 },
-    { 0x0000aacc, 0x00000000, 0x00000000, 0x000db388, 0x000db388, 0x00000000 },
-    { 0x0000aad0, 0x00000000, 0x00000000, 0x000db324, 0x000db324, 0x00000000 },
-    { 0x0000aad4, 0x00000000, 0x00000000, 0x000eb704, 0x000eb704, 0x00000000 },
-    { 0x0000aad8, 0x00000000, 0x00000000, 0x000eb6a4, 0x000eb6a4, 0x00000000 },
-    { 0x0000aadc, 0x00000000, 0x00000000, 0x000eb6a8, 0x000eb6a8, 0x00000000 },
-    { 0x0000aae0, 0x00000000, 0x00000000, 0x000eb710, 0x000eb710, 0x00000000 },
-    { 0x0000aae4, 0x00000000, 0x00000000, 0x000eb714, 0x000eb714, 0x00000000 },
-    { 0x0000aae8, 0x00000000, 0x00000000, 0x000eb720, 0x000eb720, 0x00000000 },
-    { 0x0000aaec, 0x00000000, 0x00000000, 0x000eb724, 0x000eb724, 0x00000000 },
-    { 0x0000aaf0, 0x00000000, 0x00000000, 0x000eb728, 0x000eb728, 0x00000000 },
-    { 0x0000aaf4, 0x00000000, 0x00000000, 0x000eb72c, 0x000eb72c, 0x00000000 },
-    { 0x0000aaf8, 0x00000000, 0x00000000, 0x000eb7a0, 0x000eb7a0, 0x00000000 },
-    { 0x0000aafc, 0x00000000, 0x00000000, 0x000eb7a4, 0x000eb7a4, 0x00000000 },
-    { 0x0000ab00, 0x00000000, 0x00000000, 0x000eb7a8, 0x000eb7a8, 0x00000000 },
-    { 0x0000ab04, 0x00000000, 0x00000000, 0x000eb7b0, 0x000eb7b0, 0x00000000 },
-    { 0x0000ab08, 0x00000000, 0x00000000, 0x000eb7b4, 0x000eb7b4, 0x00000000 },
-    { 0x0000ab0c, 0x00000000, 0x00000000, 0x000eb7b8, 0x000eb7b8, 0x00000000 },
-    { 0x0000ab10, 0x00000000, 0x00000000, 0x000eb7a5, 0x000eb7a5, 0x00000000 },
-    { 0x0000ab14, 0x00000000, 0x00000000, 0x000eb7a9, 0x000eb7a9, 0x00000000 },
-    { 0x0000ab18, 0x00000000, 0x00000000, 0x000eb7ad, 0x000eb7ad, 0x00000000 },
-    { 0x0000ab1c, 0x00000000, 0x00000000, 0x000eb7b1, 0x000eb7b1, 0x00000000 },
-    { 0x0000ab20, 0x00000000, 0x00000000, 0x000eb7b5, 0x000eb7b5, 0x00000000 },
-    { 0x0000ab24, 0x00000000, 0x00000000, 0x000eb7b9, 0x000eb7b9, 0x00000000 },
-    { 0x0000ab28, 0x00000000, 0x00000000, 0x000eb7c5, 0x000eb7c5, 0x00000000 },
-    { 0x0000ab2c, 0x00000000, 0x00000000, 0x000eb7c9, 0x000eb7c9, 0x00000000 },
-    { 0x0000ab30, 0x00000000, 0x00000000, 0x000eb7d1, 0x000eb7d1, 0x00000000 },
-    { 0x0000ab34, 0x00000000, 0x00000000, 0x000eb7d5, 0x000eb7d5, 0x00000000 },
-    { 0x0000ab38, 0x00000000, 0x00000000, 0x000eb7d9, 0x000eb7d9, 0x00000000 },
-    { 0x0000ab3c, 0x00000000, 0x00000000, 0x000eb7c6, 0x000eb7c6, 0x00000000 },
-    { 0x0000ab40, 0x00000000, 0x00000000, 0x000eb7ca, 0x000eb7ca, 0x00000000 },
-    { 0x0000ab44, 0x00000000, 0x00000000, 0x000eb7ce, 0x000eb7ce, 0x00000000 },
-    { 0x0000ab48, 0x00000000, 0x00000000, 0x000eb7d2, 0x000eb7d2, 0x00000000 },
-    { 0x0000ab4c, 0x00000000, 0x00000000, 0x000eb7d6, 0x000eb7d6, 0x00000000 },
-    { 0x0000ab50, 0x00000000, 0x00000000, 0x000eb7c3, 0x000eb7c3, 0x00000000 },
-    { 0x0000ab54, 0x00000000, 0x00000000, 0x000eb7c7, 0x000eb7c7, 0x00000000 },
-    { 0x0000ab58, 0x00000000, 0x00000000, 0x000eb7cb, 0x000eb7cb, 0x00000000 },
-    { 0x0000ab5c, 0x00000000, 0x00000000, 0x000eb7cf, 0x000eb7cf, 0x00000000 },
-    { 0x0000ab60, 0x00000000, 0x00000000, 0x000eb7d7, 0x000eb7d7, 0x00000000 },
-    { 0x0000ab64, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000ab68, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000ab6c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000ab70, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000ab74, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000ab78, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000ab7c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000ab80, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000ab84, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000ab88, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000ab8c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000ab90, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000ab94, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000ab98, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000ab9c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000aba0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000aba4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000aba8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000abac, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000abb0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000abb4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000abb8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000abbc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000abc0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000abc4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000abc8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000abcc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000abd0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000abd4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000abd8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000abdc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000abe0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000abe4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000abe8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000abec, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000abf0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000abf4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000abf8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000abfc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
-    { 0x0000a204, 0x00000004, 0x00000004, 0x00000004, 0x00000004, 0x00000004 },
-    { 0x0000a20c, 0x00000014, 0x00000014, 0x0001f000, 0x0001f000, 0x0001f000 },
-    { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a },
-    { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
-    { 0x0000a250, 0x0004f000, 0x0004f000, 0x0004a000, 0x0004a000, 0x0004a000 },
-    { 0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e },
-};
-
-static const u_int32_t ar9285Common_9285_1_2[][2] = {
-    { 0x0000000c, 0x00000000 },
-    { 0x00000030, 0x00020045 },
-    { 0x00000034, 0x00000005 },
-    { 0x00000040, 0x00000000 },
-    { 0x00000044, 0x00000008 },
-    { 0x00000048, 0x00000008 },
-    { 0x0000004c, 0x00000010 },
-    { 0x00000050, 0x00000000 },
-    { 0x00000054, 0x0000001f },
-    { 0x00000800, 0x00000000 },
-    { 0x00000804, 0x00000000 },
-    { 0x00000808, 0x00000000 },
-    { 0x0000080c, 0x00000000 },
-    { 0x00000810, 0x00000000 },
-    { 0x00000814, 0x00000000 },
-    { 0x00000818, 0x00000000 },
-    { 0x0000081c, 0x00000000 },
-    { 0x00000820, 0x00000000 },
-    { 0x00000824, 0x00000000 },
-    { 0x00001040, 0x002ffc0f },
-    { 0x00001044, 0x002ffc0f },
-    { 0x00001048, 0x002ffc0f },
-    { 0x0000104c, 0x002ffc0f },
-    { 0x00001050, 0x002ffc0f },
-    { 0x00001054, 0x002ffc0f },
-    { 0x00001058, 0x002ffc0f },
-    { 0x0000105c, 0x002ffc0f },
-    { 0x00001060, 0x002ffc0f },
-    { 0x00001064, 0x002ffc0f },
-    { 0x00001230, 0x00000000 },
-    { 0x00001270, 0x00000000 },
-    { 0x00001038, 0x00000000 },
-    { 0x00001078, 0x00000000 },
-    { 0x000010b8, 0x00000000 },
-    { 0x000010f8, 0x00000000 },
-    { 0x00001138, 0x00000000 },
-    { 0x00001178, 0x00000000 },
-    { 0x000011b8, 0x00000000 },
-    { 0x000011f8, 0x00000000 },
-    { 0x00001238, 0x00000000 },
-    { 0x00001278, 0x00000000 },
-    { 0x000012b8, 0x00000000 },
-    { 0x000012f8, 0x00000000 },
-    { 0x00001338, 0x00000000 },
-    { 0x00001378, 0x00000000 },
-    { 0x000013b8, 0x00000000 },
-    { 0x000013f8, 0x00000000 },
-    { 0x00001438, 0x00000000 },
-    { 0x00001478, 0x00000000 },
-    { 0x000014b8, 0x00000000 },
-    { 0x000014f8, 0x00000000 },
-    { 0x00001538, 0x00000000 },
-    { 0x00001578, 0x00000000 },
-    { 0x000015b8, 0x00000000 },
-    { 0x000015f8, 0x00000000 },
-    { 0x00001638, 0x00000000 },
-    { 0x00001678, 0x00000000 },
-    { 0x000016b8, 0x00000000 },
-    { 0x000016f8, 0x00000000 },
-    { 0x00001738, 0x00000000 },
-    { 0x00001778, 0x00000000 },
-    { 0x000017b8, 0x00000000 },
-    { 0x000017f8, 0x00000000 },
-    { 0x0000103c, 0x00000000 },
-    { 0x0000107c, 0x00000000 },
-    { 0x000010bc, 0x00000000 },
-    { 0x000010fc, 0x00000000 },
-    { 0x0000113c, 0x00000000 },
-    { 0x0000117c, 0x00000000 },
-    { 0x000011bc, 0x00000000 },
-    { 0x000011fc, 0x00000000 },
-    { 0x0000123c, 0x00000000 },
-    { 0x0000127c, 0x00000000 },
-    { 0x000012bc, 0x00000000 },
-    { 0x000012fc, 0x00000000 },
-    { 0x0000133c, 0x00000000 },
-    { 0x0000137c, 0x00000000 },
-    { 0x000013bc, 0x00000000 },
-    { 0x000013fc, 0x00000000 },
-    { 0x0000143c, 0x00000000 },
-    { 0x0000147c, 0x00000000 },
-    { 0x00004030, 0x00000002 },
-    { 0x0000403c, 0x00000002 },
-    { 0x00004024, 0x0000001f },
-    { 0x00004060, 0x00000000 },
-    { 0x00004064, 0x00000000 },
-    { 0x00007010, 0x00000031 },
-    { 0x00007034, 0x00000002 },
-    { 0x00007038, 0x000004c2 },
-    { 0x00008004, 0x00000000 },
-    { 0x00008008, 0x00000000 },
-    { 0x0000800c, 0x00000000 },
-    { 0x00008018, 0x00000700 },
-    { 0x00008020, 0x00000000 },
-    { 0x00008038, 0x00000000 },
-    { 0x0000803c, 0x00000000 },
-    { 0x00008048, 0x00000000 },
-    { 0x00008054, 0x00000000 },
-    { 0x00008058, 0x00000000 },
-    { 0x0000805c, 0x000fc78f },
-    { 0x00008060, 0x0000000f },
-    { 0x00008064, 0x00000000 },
-    { 0x00008070, 0x00000000 },
-    { 0x000080c0, 0x2a80001a },
-    { 0x000080c4, 0x05dc01e0 },
-    { 0x000080c8, 0x1f402710 },
-    { 0x000080cc, 0x01f40000 },
-    { 0x000080d0, 0x00001e00 },
-    { 0x000080d4, 0x00000000 },
-    { 0x000080d8, 0x00400000 },
-    { 0x000080e0, 0xffffffff },
-    { 0x000080e4, 0x0000ffff },
-    { 0x000080e8, 0x003f3f3f },
-    { 0x000080ec, 0x00000000 },
-    { 0x000080f0, 0x00000000 },
-    { 0x000080f4, 0x00000000 },
-    { 0x000080f8, 0x00000000 },
-    { 0x000080fc, 0x00020000 },
-    { 0x00008100, 0x00020000 },
-    { 0x00008104, 0x00000001 },
-    { 0x00008108, 0x00000052 },
-    { 0x0000810c, 0x00000000 },
-    { 0x00008110, 0x00000168 },
-    { 0x00008118, 0x000100aa },
-    { 0x0000811c, 0x00003210 },
-    { 0x00008120, 0x08f04810 },
-    { 0x00008124, 0x00000000 },
-    { 0x00008128, 0x00000000 },
-    { 0x0000812c, 0x00000000 },
-    { 0x00008130, 0x00000000 },
-    { 0x00008134, 0x00000000 },
-    { 0x00008138, 0x00000000 },
-    { 0x0000813c, 0x00000000 },
-    { 0x00008144, 0xffffffff },
-    { 0x00008168, 0x00000000 },
-    { 0x0000816c, 0x00000000 },
-    { 0x00008170, 0x32143320 },
-    { 0x00008174, 0xfaa4fa50 },
-    { 0x00008178, 0x00000100 },
-    { 0x0000817c, 0x00000000 },
-    { 0x000081c0, 0x00000000 },
-    { 0x000081d0, 0x0000320a },
-    { 0x000081ec, 0x00000000 },
-    { 0x000081f0, 0x00000000 },
-    { 0x000081f4, 0x00000000 },
-    { 0x000081f8, 0x00000000 },
-    { 0x000081fc, 0x00000000 },
-    { 0x00008200, 0x00000000 },
-    { 0x00008204, 0x00000000 },
-    { 0x00008208, 0x00000000 },
-    { 0x0000820c, 0x00000000 },
-    { 0x00008210, 0x00000000 },
-    { 0x00008214, 0x00000000 },
-    { 0x00008218, 0x00000000 },
-    { 0x0000821c, 0x00000000 },
-    { 0x00008220, 0x00000000 },
-    { 0x00008224, 0x00000000 },
-    { 0x00008228, 0x00000000 },
-    { 0x0000822c, 0x00000000 },
-    { 0x00008230, 0x00000000 },
-    { 0x00008234, 0x00000000 },
-    { 0x00008238, 0x00000000 },
-    { 0x0000823c, 0x00000000 },
-    { 0x00008240, 0x00100000 },
-    { 0x00008244, 0x0010f400 },
-    { 0x00008248, 0x00000100 },
-    { 0x0000824c, 0x0001e800 },
-    { 0x00008250, 0x00000000 },
-    { 0x00008254, 0x00000000 },
-    { 0x00008258, 0x00000000 },
-    { 0x0000825c, 0x400000ff },
-    { 0x00008260, 0x00080922 },
-    { 0x00008264, 0xa8a00010 },
-    { 0x00008270, 0x00000000 },
-    { 0x00008274, 0x40000000 },
-    { 0x00008278, 0x003e4180 },
-    { 0x0000827c, 0x00000000 },
-    { 0x00008284, 0x0000002c },
-    { 0x00008288, 0x0000002c },
-    { 0x0000828c, 0x00000000 },
-    { 0x00008294, 0x00000000 },
-    { 0x00008298, 0x00000000 },
-    { 0x0000829c, 0x00000000 },
-    { 0x00008300, 0x00000040 },
-    { 0x00008314, 0x00000000 },
-    { 0x00008328, 0x00000000 },
-    { 0x0000832c, 0x00000001 },
-    { 0x00008330, 0x00000302 },
-    { 0x00008334, 0x00000e00 },
-    { 0x00008338, 0x00ff0000 },
-    { 0x0000833c, 0x00000000 },
-    { 0x00008340, 0x00010380 },
-    { 0x00008344, 0x00581043 },
-    { 0x00009808, 0x00000000 },
-    { 0x0000980c, 0xafe68e30 },
-    { 0x00009810, 0xfd14e000 },
-    { 0x00009814, 0x9c0a9f6b },
-    { 0x0000981c, 0x00000000 },
-    { 0x0000982c, 0x0000a000 },
-    { 0x00009830, 0x00000000 },
-    { 0x0000983c, 0x00200400 },
-    { 0x0000984c, 0x0040233c },
-    { 0x00009854, 0x00000044 },
-    { 0x00009900, 0x00000000 },
-    { 0x00009904, 0x00000000 },
-    { 0x00009908, 0x00000000 },
-    { 0x0000990c, 0x00000000 },
-    { 0x00009910, 0x01002310 },
-    { 0x0000991c, 0x10000fff },
-    { 0x00009920, 0x04900000 },
-    { 0x00009928, 0x00000001 },
-    { 0x0000992c, 0x00000004 },
-    { 0x00009934, 0x1e1f2022 },
-    { 0x00009938, 0x0a0b0c0d },
-    { 0x0000993c, 0x00000000 },
-    { 0x00009940, 0x14750604 },
-    { 0x00009948, 0x9280c00a },
-    { 0x0000994c, 0x00020028 },
-    { 0x00009954, 0x5f3ca3de },
-    { 0x00009958, 0x2108ecff },
-    { 0x00009968, 0x000003ce },
-    { 0x00009970, 0x192bb515 },
-    { 0x00009974, 0x00000000 },
-    { 0x00009978, 0x00000001 },
-    { 0x0000997c, 0x00000000 },
-    { 0x00009980, 0x00000000 },
-    { 0x00009984, 0x00000000 },
-    { 0x00009988, 0x00000000 },
-    { 0x0000998c, 0x00000000 },
-    { 0x00009990, 0x00000000 },
-    { 0x00009994, 0x00000000 },
-    { 0x00009998, 0x00000000 },
-    { 0x0000999c, 0x00000000 },
-    { 0x000099a0, 0x00000000 },
-    { 0x000099a4, 0x00000001 },
-    { 0x000099a8, 0x201fff00 },
-    { 0x000099ac, 0x2def0400 },
-    { 0x000099b0, 0x03051000 },
-    { 0x000099b4, 0x00000820 },
-    { 0x000099dc, 0x00000000 },
-    { 0x000099e0, 0x00000000 },
-    { 0x000099e4, 0xaaaaaaaa },
-    { 0x000099e8, 0x3c466478 },
-    { 0x000099ec, 0x0cc80caa },
-    { 0x000099f0, 0x00000000 },
-    { 0x0000a208, 0x803e68c8 },
-    { 0x0000a210, 0x4080a333 },
-    { 0x0000a214, 0x00206c10 },
-    { 0x0000a218, 0x009c4060 },
-    { 0x0000a220, 0x01834061 },
-    { 0x0000a224, 0x00000400 },
-    { 0x0000a228, 0x000003b5 },
-    { 0x0000a22c, 0x00000000 },
-    { 0x0000a234, 0x20202020 },
-    { 0x0000a238, 0x20202020 },
-    { 0x0000a244, 0x00000000 },
-    { 0x0000a248, 0xfffffffc },
-    { 0x0000a24c, 0x00000000 },
-    { 0x0000a254, 0x00000000 },
-    { 0x0000a258, 0x0ccb5380 },
-    { 0x0000a25c, 0x15151501 },
-    { 0x0000a260, 0xdfa90f01 },
-    { 0x0000a268, 0x00000000 },
-    { 0x0000a26c, 0x0ebae9e6 },
-    { 0x0000d270, 0x0d820820 },
-    { 0x0000d35c, 0x07ffffef },
-    { 0x0000d360, 0x0fffffe7 },
-    { 0x0000d364, 0x17ffffe5 },
-    { 0x0000d368, 0x1fffffe4 },
-    { 0x0000d36c, 0x37ffffe3 },
-    { 0x0000d370, 0x3fffffe3 },
-    { 0x0000d374, 0x57ffffe3 },
-    { 0x0000d378, 0x5fffffe2 },
-    { 0x0000d37c, 0x7fffffe2 },
-    { 0x0000d380, 0x7f3c7bba },
-    { 0x0000d384, 0xf3307ff0 },
-    { 0x0000a388, 0x0c000000 },
-    { 0x0000a38c, 0x20202020 },
-    { 0x0000a390, 0x20202020 },
-    { 0x0000a39c, 0x00000001 },
-    { 0x0000a3a0, 0x00000000 },
-    { 0x0000a3a4, 0x00000000 },
-    { 0x0000a3a8, 0x00000000 },
-    { 0x0000a3ac, 0x00000000 },
-    { 0x0000a3b0, 0x00000000 },
-    { 0x0000a3b4, 0x00000000 },
-    { 0x0000a3b8, 0x00000000 },
-    { 0x0000a3bc, 0x00000000 },
-    { 0x0000a3c0, 0x00000000 },
-    { 0x0000a3c4, 0x00000000 },
-    { 0x0000a3cc, 0x20202020 },
-    { 0x0000a3d0, 0x20202020 },
-    { 0x0000a3d4, 0x20202020 },
-    { 0x0000a3e4, 0x00000000 },
-    { 0x0000a3e8, 0x18c43433 },
-    { 0x0000a3ec, 0x00f70081 },
-    { 0x00007800, 0x00140000 },
-    { 0x00007804, 0x0e4548d8 },
-    { 0x00007808, 0x54214514 },
-    { 0x0000780c, 0x02025820 },
-    { 0x00007810, 0x71c0d388 },
-    { 0x00007814, 0x924934a8 },
-    { 0x0000781c, 0x00000000 },
-    { 0x00007824, 0x00d86fff },
-    { 0x00007828, 0x26d2491b },
-    { 0x0000782c, 0x6e36d97b },
-    { 0x00007830, 0xedb6d96e },
-    { 0x00007834, 0x71400087 },
-    { 0x0000783c, 0x0001fffe },
-    { 0x00007840, 0xffeb1a20 },
-    { 0x00007844, 0x000c0db6 },
-    { 0x00007848, 0x6db61b6f },
-    { 0x0000784c, 0x6d9b66db },
-    { 0x00007850, 0x6d8c6dba },
-    { 0x00007854, 0x00040000 },
-    { 0x00007858, 0xdb003012 },
-    { 0x0000785c, 0x04924914 },
-    { 0x00007860, 0x21084210 },
-    { 0x00007864, 0xf7d7ffde },
-    { 0x00007868, 0xc2034080 },
-    { 0x00007870, 0x10142c00 },
-};
-
-static const u_int32_t ar9285Modes_high_power_tx_gain_9285_1_2[][6] = {
-    /* Address      5G-HT20     5G-HT40     2G-HT40     2G-HT20     Turbo   */
-    { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x0000a304, 0x00000000, 0x00000000, 0x00005200, 0x00005200, 0x00000000 },
-    { 0x0000a308, 0x00000000, 0x00000000, 0x00007201, 0x00007201, 0x00000000 },
-    { 0x0000a30c, 0x00000000, 0x00000000, 0x0000b240, 0x0000b240, 0x00000000 },
-    { 0x0000a310, 0x00000000, 0x00000000, 0x0000d241, 0x0000d241, 0x00000000 },
-    { 0x0000a314, 0x00000000, 0x00000000, 0x0000f440, 0x0000f440, 0x00000000 },
-    { 0x0000a318, 0x00000000, 0x00000000, 0x00014640, 0x00014640, 0x00000000 },
-    { 0x0000a31c, 0x00000000, 0x00000000, 0x00018680, 0x00018680, 0x00000000 },
-    { 0x0000a320, 0x00000000, 0x00000000, 0x00019841, 0x00019841, 0x00000000 },
-    { 0x0000a324, 0x00000000, 0x00000000, 0x0001ca40, 0x0001ca40, 0x00000000 },
-    { 0x0000a328, 0x00000000, 0x00000000, 0x0001fa80, 0x0001fa80, 0x00000000 },
-    { 0x0000a32c, 0x00000000, 0x00000000, 0x00023ac0, 0x00023ac0, 0x00000000 },
-    { 0x0000a330, 0x00000000, 0x00000000, 0x0002ab40, 0x0002ab40, 0x00000000 },
-    { 0x0000a334, 0x00000000, 0x00000000, 0x00033d82, 0x00033d82, 0x00000000 },
-    { 0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000 },
-    { 0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000 },
-    { 0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
-    { 0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
-    { 0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
-    { 0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
-    { 0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
-    { 0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
-    { 0x00007838, 0xfac68803, 0xfac68803, 0xfac68803, 0xfac68803, 0xfac68803 },
-    { 0x0000786c, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe },
-    { 0x00007820, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00 },
-    { 0x0000a274, 0x0a22a652, 0x0a22a652, 0x0a21a652, 0x0a21a652, 0x0a22a652 },
-    { 0x0000a278, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce },
-    { 0x0000a27c, 0x050701ce, 0x050701ce, 0x050701ce, 0x050701ce, 0x050701ce },
-    { 0x0000a394, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce },
-    { 0x0000a398, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce },
-    { 0x0000a3dc, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce },
-    { 0x0000a3e0, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce },
-};
-
-static const u_int32_t ar9285Modes_original_tx_gain_9285_1_2[][6] = {
-    /* Address      5G-HT20     5G-HT40     2G-HT40     2G-HT20     Turbo   */
-    { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
-    { 0x0000a304, 0x00000000, 0x00000000, 0x00009200, 0x00009200, 0x00000000 },
-    { 0x0000a308, 0x00000000, 0x00000000, 0x00010208, 0x00010208, 0x00000000 },
-    { 0x0000a30c, 0x00000000, 0x00000000, 0x00019608, 0x00019608, 0x00000000 },
-    { 0x0000a310, 0x00000000, 0x00000000, 0x00022618, 0x00022618, 0x00000000 },
-    { 0x0000a314, 0x00000000, 0x00000000, 0x0002a6c9, 0x0002a6c9, 0x00000000 },
-    { 0x0000a318, 0x00000000, 0x00000000, 0x00031710, 0x00031710, 0x00000000 },
-    { 0x0000a31c, 0x00000000, 0x00000000, 0x00035718, 0x00035718, 0x00000000 },
-    { 0x0000a320, 0x00000000, 0x00000000, 0x00038758, 0x00038758, 0x00000000 },
-    { 0x0000a324, 0x00000000, 0x00000000, 0x0003c75a, 0x0003c75a, 0x00000000 },
-    { 0x0000a328, 0x00000000, 0x00000000, 0x0004075c, 0x0004075c, 0x00000000 },
-    { 0x0000a32c, 0x00000000, 0x00000000, 0x0004475e, 0x0004475e, 0x00000000 },
-    { 0x0000a330, 0x00000000, 0x00000000, 0x0004679f, 0x0004679f, 0x00000000 },
-    { 0x0000a334, 0x00000000, 0x00000000, 0x000487df, 0x000487df, 0x00000000 },
-    { 0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000 },
-    { 0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000 },
-    { 0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
-    { 0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
-    { 0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
-    { 0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
-    { 0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
-    { 0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
-    { 0x00007838, 0xfac68801, 0xfac68801, 0xfac68801, 0xfac68801, 0xfac68801 },
-    { 0x0000786c, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4 },
-    { 0x00007820, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04 },
-    { 0x0000a274, 0x0a21c652, 0x0a21c652, 0x0a21a652, 0x0a21a652, 0x0a22a652 },
-    { 0x0000a278, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c },
-    { 0x0000a27c, 0x050e039c, 0x050e039c, 0x050e039c, 0x050e039c, 0x050e039c },
-    { 0x0000a394, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c },
-    { 0x0000a398, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c },
-    { 0x0000a3dc, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c },
-    { 0x0000a3e0, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c },
-};
-
-static const u_int32_t ar9285PciePhy_clkreq_always_on_L1_9285_1_2[][2] = {
-    {0x00004040,  0x9248fd00 },
-    {0x00004040,  0x24924924 },
-    {0x00004040,  0xa8000019 },
-    {0x00004040,  0x13160820 },
-    {0x00004040,  0xe5980560 },
-    {0x00004040,  0xc01dcffd },
-    {0x00004040,  0x1aaabe41 },
-    {0x00004040,  0xbe105554 },
-    {0x00004040,  0x00043007 },
-    {0x00004044,  0x00000000 },
-};
-
-static const u_int32_t ar9285PciePhy_clkreq_off_L1_9285_1_2[][2] = {
-    {0x00004040,  0x9248fd00 },
-    {0x00004040,  0x24924924 },
-    {0x00004040,  0xa8000019 },
-    {0x00004040,  0x13160820 },
-    {0x00004040,  0xe5980560 },
-    {0x00004040,  0xc01dcffc },
-    {0x00004040,  0x1aaabe41 },
-    {0x00004040,  0xbe105554 },
-    {0x00004040,  0x00043007 },
-    {0x00004044,  0x00000000 },
-};
diff --git a/drivers/net/wireless/ath9k/mac.c b/drivers/net/wireless/ath9k/mac.c
deleted file mode 100644 (file)
index e0a6dee..0000000
+++ /dev/null
@@ -1,965 +0,0 @@
-/*
- * Copyright (c) 2008-2009 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 "ath9k.h"
-
-static void ath9k_hw_set_txq_interrupts(struct ath_hw *ah,
-                                       struct ath9k_tx_queue_info *qi)
-{
-       DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
-               "tx ok 0x%x err 0x%x desc 0x%x eol 0x%x urn 0x%x\n",
-               ah->txok_interrupt_mask, ah->txerr_interrupt_mask,
-               ah->txdesc_interrupt_mask, ah->txeol_interrupt_mask,
-               ah->txurn_interrupt_mask);
-
-       REG_WRITE(ah, AR_IMR_S0,
-                 SM(ah->txok_interrupt_mask, AR_IMR_S0_QCU_TXOK)
-                 | SM(ah->txdesc_interrupt_mask, AR_IMR_S0_QCU_TXDESC));
-       REG_WRITE(ah, AR_IMR_S1,
-                 SM(ah->txerr_interrupt_mask, AR_IMR_S1_QCU_TXERR)
-                 | SM(ah->txeol_interrupt_mask, AR_IMR_S1_QCU_TXEOL));
-       REG_RMW_FIELD(ah, AR_IMR_S2,
-                     AR_IMR_S2_QCU_TXURN, ah->txurn_interrupt_mask);
-}
-
-u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q)
-{
-       return REG_READ(ah, AR_QTXDP(q));
-}
-
-bool ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp)
-{
-       REG_WRITE(ah, AR_QTXDP(q), txdp);
-
-       return true;
-}
-
-bool ath9k_hw_txstart(struct ath_hw *ah, u32 q)
-{
-       DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "queue %u\n", q);
-
-       REG_WRITE(ah, AR_Q_TXE, 1 << q);
-
-       return true;
-}
-
-u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q)
-{
-       u32 npend;
-
-       npend = REG_READ(ah, AR_QSTS(q)) & AR_Q_STS_PEND_FR_CNT;
-       if (npend == 0) {
-
-               if (REG_READ(ah, AR_Q_TXE) & (1 << q))
-                       npend = 1;
-       }
-
-       return npend;
-}
-
-bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel)
-{
-       u32 txcfg, curLevel, newLevel;
-       enum ath9k_int omask;
-
-       if (ah->tx_trig_level >= MAX_TX_FIFO_THRESHOLD)
-               return false;
-
-       omask = ath9k_hw_set_interrupts(ah, ah->mask_reg & ~ATH9K_INT_GLOBAL);
-
-       txcfg = REG_READ(ah, AR_TXCFG);
-       curLevel = MS(txcfg, AR_FTRIG);
-       newLevel = curLevel;
-       if (bIncTrigLevel) {
-               if (curLevel < MAX_TX_FIFO_THRESHOLD)
-                       newLevel++;
-       } else if (curLevel > MIN_TX_FIFO_THRESHOLD)
-               newLevel--;
-       if (newLevel != curLevel)
-               REG_WRITE(ah, AR_TXCFG,
-                         (txcfg & ~AR_FTRIG) | SM(newLevel, AR_FTRIG));
-
-       ath9k_hw_set_interrupts(ah, omask);
-
-       ah->tx_trig_level = newLevel;
-
-       return newLevel != curLevel;
-}
-
-bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q)
-{
-#define ATH9K_TX_STOP_DMA_TIMEOUT      4000    /* usec */
-#define ATH9K_TIME_QUANTUM             100     /* usec */
-
-       struct ath9k_hw_capabilities *pCap = &ah->caps;
-       struct ath9k_tx_queue_info *qi;
-       u32 tsfLow, j, wait;
-       u32 wait_time = ATH9K_TX_STOP_DMA_TIMEOUT / ATH9K_TIME_QUANTUM;
-
-       if (q >= pCap->total_queues) {
-               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "invalid queue num %u\n", q);
-               return false;
-       }
-
-       qi = &ah->txq[q];
-       if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
-               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "inactive queue\n");
-               return false;
-       }
-
-       REG_WRITE(ah, AR_Q_TXD, 1 << q);
-
-       for (wait = wait_time; wait != 0; wait--) {
-               if (ath9k_hw_numtxpending(ah, q) == 0)
-                       break;
-               udelay(ATH9K_TIME_QUANTUM);
-       }
-
-       if (ath9k_hw_numtxpending(ah, q)) {
-               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
-                       "%s: Num of pending TX Frames %d on Q %d\n",
-                       __func__, ath9k_hw_numtxpending(ah, q), q);
-
-               for (j = 0; j < 2; j++) {
-                       tsfLow = REG_READ(ah, AR_TSF_L32);
-                       REG_WRITE(ah, AR_QUIET2,
-                                 SM(10, AR_QUIET2_QUIET_DUR));
-                       REG_WRITE(ah, AR_QUIET_PERIOD, 100);
-                       REG_WRITE(ah, AR_NEXT_QUIET_TIMER, tsfLow >> 10);
-                       REG_SET_BIT(ah, AR_TIMER_MODE,
-                                      AR_QUIET_TIMER_EN);
-
-                       if ((REG_READ(ah, AR_TSF_L32) >> 10) == (tsfLow >> 10))
-                               break;
-
-                       DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
-                               "TSF have moved while trying to set "
-                               "quiet time TSF: 0x%08x\n", tsfLow);
-               }
-
-               REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
-
-               udelay(200);
-               REG_CLR_BIT(ah, AR_TIMER_MODE, AR_QUIET_TIMER_EN);
-
-               wait = wait_time;
-               while (ath9k_hw_numtxpending(ah, q)) {
-                       if ((--wait) == 0) {
-                               DPRINTF(ah->ah_sc, ATH_DBG_XMIT,
-                                       "Failed to stop Tx DMA in 100 "
-                                       "msec after killing last frame\n");
-                               break;
-                       }
-                       udelay(ATH9K_TIME_QUANTUM);
-               }
-
-               REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
-       }
-
-       REG_WRITE(ah, AR_Q_TXD, 0);
-       return wait != 0;
-
-#undef ATH9K_TX_STOP_DMA_TIMEOUT
-#undef ATH9K_TIME_QUANTUM
-}
-
-bool ath9k_hw_filltxdesc(struct ath_hw *ah, struct ath_desc *ds,
-                        u32 segLen, bool firstSeg,
-                        bool lastSeg, const struct ath_desc *ds0)
-{
-       struct ar5416_desc *ads = AR5416DESC(ds);
-
-       if (firstSeg) {
-               ads->ds_ctl1 |= segLen | (lastSeg ? 0 : AR_TxMore);
-       } else if (lastSeg) {
-               ads->ds_ctl0 = 0;
-               ads->ds_ctl1 = segLen;
-               ads->ds_ctl2 = AR5416DESC_CONST(ds0)->ds_ctl2;
-               ads->ds_ctl3 = AR5416DESC_CONST(ds0)->ds_ctl3;
-       } else {
-               ads->ds_ctl0 = 0;
-               ads->ds_ctl1 = segLen | AR_TxMore;
-               ads->ds_ctl2 = 0;
-               ads->ds_ctl3 = 0;
-       }
-       ads->ds_txstatus0 = ads->ds_txstatus1 = 0;
-       ads->ds_txstatus2 = ads->ds_txstatus3 = 0;
-       ads->ds_txstatus4 = ads->ds_txstatus5 = 0;
-       ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
-       ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
-
-       return true;
-}
-
-void ath9k_hw_cleartxdesc(struct ath_hw *ah, struct ath_desc *ds)
-{
-       struct ar5416_desc *ads = AR5416DESC(ds);
-
-       ads->ds_txstatus0 = ads->ds_txstatus1 = 0;
-       ads->ds_txstatus2 = ads->ds_txstatus3 = 0;
-       ads->ds_txstatus4 = ads->ds_txstatus5 = 0;
-       ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
-       ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
-}
-
-int ath9k_hw_txprocdesc(struct ath_hw *ah, struct ath_desc *ds)
-{
-       struct ar5416_desc *ads = AR5416DESC(ds);
-
-       if ((ads->ds_txstatus9 & AR_TxDone) == 0)
-               return -EINPROGRESS;
-
-       ds->ds_txstat.ts_seqnum = MS(ads->ds_txstatus9, AR_SeqNum);
-       ds->ds_txstat.ts_tstamp = ads->AR_SendTimestamp;
-       ds->ds_txstat.ts_status = 0;
-       ds->ds_txstat.ts_flags = 0;
-
-       if (ads->ds_txstatus1 & AR_ExcessiveRetries)
-               ds->ds_txstat.ts_status |= ATH9K_TXERR_XRETRY;
-       if (ads->ds_txstatus1 & AR_Filtered)
-               ds->ds_txstat.ts_status |= ATH9K_TXERR_FILT;
-       if (ads->ds_txstatus1 & AR_FIFOUnderrun) {
-               ds->ds_txstat.ts_status |= ATH9K_TXERR_FIFO;
-               ath9k_hw_updatetxtriglevel(ah, true);
-       }
-       if (ads->ds_txstatus9 & AR_TxOpExceeded)
-               ds->ds_txstat.ts_status |= ATH9K_TXERR_XTXOP;
-       if (ads->ds_txstatus1 & AR_TxTimerExpired)
-               ds->ds_txstat.ts_status |= ATH9K_TXERR_TIMER_EXPIRED;
-
-       if (ads->ds_txstatus1 & AR_DescCfgErr)
-               ds->ds_txstat.ts_flags |= ATH9K_TX_DESC_CFG_ERR;
-       if (ads->ds_txstatus1 & AR_TxDataUnderrun) {
-               ds->ds_txstat.ts_flags |= ATH9K_TX_DATA_UNDERRUN;
-               ath9k_hw_updatetxtriglevel(ah, true);
-       }
-       if (ads->ds_txstatus1 & AR_TxDelimUnderrun) {
-               ds->ds_txstat.ts_flags |= ATH9K_TX_DELIM_UNDERRUN;
-               ath9k_hw_updatetxtriglevel(ah, true);
-       }
-       if (ads->ds_txstatus0 & AR_TxBaStatus) {
-               ds->ds_txstat.ts_flags |= ATH9K_TX_BA;
-               ds->ds_txstat.ba_low = ads->AR_BaBitmapLow;
-               ds->ds_txstat.ba_high = ads->AR_BaBitmapHigh;
-       }
-
-       ds->ds_txstat.ts_rateindex = MS(ads->ds_txstatus9, AR_FinalTxIdx);
-       switch (ds->ds_txstat.ts_rateindex) {
-       case 0:
-               ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate0);
-               break;
-       case 1:
-               ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate1);
-               break;
-       case 2:
-               ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate2);
-               break;
-       case 3:
-               ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate3);
-               break;
-       }
-
-       ds->ds_txstat.ts_rssi = MS(ads->ds_txstatus5, AR_TxRSSICombined);
-       ds->ds_txstat.ts_rssi_ctl0 = MS(ads->ds_txstatus0, AR_TxRSSIAnt00);
-       ds->ds_txstat.ts_rssi_ctl1 = MS(ads->ds_txstatus0, AR_TxRSSIAnt01);
-       ds->ds_txstat.ts_rssi_ctl2 = MS(ads->ds_txstatus0, AR_TxRSSIAnt02);
-       ds->ds_txstat.ts_rssi_ext0 = MS(ads->ds_txstatus5, AR_TxRSSIAnt10);
-       ds->ds_txstat.ts_rssi_ext1 = MS(ads->ds_txstatus5, AR_TxRSSIAnt11);
-       ds->ds_txstat.ts_rssi_ext2 = MS(ads->ds_txstatus5, AR_TxRSSIAnt12);
-       ds->ds_txstat.evm0 = ads->AR_TxEVM0;
-       ds->ds_txstat.evm1 = ads->AR_TxEVM1;
-       ds->ds_txstat.evm2 = ads->AR_TxEVM2;
-       ds->ds_txstat.ts_shortretry = MS(ads->ds_txstatus1, AR_RTSFailCnt);
-       ds->ds_txstat.ts_longretry = MS(ads->ds_txstatus1, AR_DataFailCnt);
-       ds->ds_txstat.ts_virtcol = MS(ads->ds_txstatus1, AR_VirtRetryCnt);
-       ds->ds_txstat.ts_antenna = 0;
-
-       return 0;
-}
-
-void ath9k_hw_set11n_txdesc(struct ath_hw *ah, struct ath_desc *ds,
-                           u32 pktLen, enum ath9k_pkt_type type, u32 txPower,
-                           u32 keyIx, enum ath9k_key_type keyType, u32 flags)
-{
-       struct ar5416_desc *ads = AR5416DESC(ds);
-
-       txPower += ah->txpower_indexoffset;
-       if (txPower > 63)
-               txPower = 63;
-
-       ads->ds_ctl0 = (pktLen & AR_FrameLen)
-               | (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0)
-               | SM(txPower, AR_XmitPower)
-               | (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0)
-               | (flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0)
-               | (flags & ATH9K_TXDESC_INTREQ ? AR_TxIntrReq : 0)
-               | (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0);
-
-       ads->ds_ctl1 =
-               (keyIx != ATH9K_TXKEYIX_INVALID ? SM(keyIx, AR_DestIdx) : 0)
-               | SM(type, AR_FrameType)
-               | (flags & ATH9K_TXDESC_NOACK ? AR_NoAck : 0)
-               | (flags & ATH9K_TXDESC_EXT_ONLY ? AR_ExtOnly : 0)
-               | (flags & ATH9K_TXDESC_EXT_AND_CTL ? AR_ExtAndCtl : 0);
-
-       ads->ds_ctl6 = SM(keyType, AR_EncrType);
-
-       if (AR_SREV_9285(ah)) {
-               ads->ds_ctl8 = 0;
-               ads->ds_ctl9 = 0;
-               ads->ds_ctl10 = 0;
-               ads->ds_ctl11 = 0;
-       }
-}
-
-void ath9k_hw_set11n_ratescenario(struct ath_hw *ah, struct ath_desc *ds,
-                                 struct ath_desc *lastds,
-                                 u32 durUpdateEn, u32 rtsctsRate,
-                                 u32 rtsctsDuration,
-                                 struct ath9k_11n_rate_series series[],
-                                 u32 nseries, u32 flags)
-{
-       struct ar5416_desc *ads = AR5416DESC(ds);
-       struct ar5416_desc *last_ads = AR5416DESC(lastds);
-       u32 ds_ctl0;
-
-       if (flags & (ATH9K_TXDESC_RTSENA | ATH9K_TXDESC_CTSENA)) {
-               ds_ctl0 = ads->ds_ctl0;
-
-               if (flags & ATH9K_TXDESC_RTSENA) {
-                       ds_ctl0 &= ~AR_CTSEnable;
-                       ds_ctl0 |= AR_RTSEnable;
-               } else {
-                       ds_ctl0 &= ~AR_RTSEnable;
-                       ds_ctl0 |= AR_CTSEnable;
-               }
-
-               ads->ds_ctl0 = ds_ctl0;
-       } else {
-               ads->ds_ctl0 =
-                       (ads->ds_ctl0 & ~(AR_RTSEnable | AR_CTSEnable));
-       }
-
-       ads->ds_ctl2 = set11nTries(series, 0)
-               | set11nTries(series, 1)
-               | set11nTries(series, 2)
-               | set11nTries(series, 3)
-               | (durUpdateEn ? AR_DurUpdateEna : 0)
-               | SM(0, AR_BurstDur);
-
-       ads->ds_ctl3 = set11nRate(series, 0)
-               | set11nRate(series, 1)
-               | set11nRate(series, 2)
-               | set11nRate(series, 3);
-
-       ads->ds_ctl4 = set11nPktDurRTSCTS(series, 0)
-               | set11nPktDurRTSCTS(series, 1);
-
-       ads->ds_ctl5 = set11nPktDurRTSCTS(series, 2)
-               | set11nPktDurRTSCTS(series, 3);
-
-       ads->ds_ctl7 = set11nRateFlags(series, 0)
-               | set11nRateFlags(series, 1)
-               | set11nRateFlags(series, 2)
-               | set11nRateFlags(series, 3)
-               | SM(rtsctsRate, AR_RTSCTSRate);
-       last_ads->ds_ctl2 = ads->ds_ctl2;
-       last_ads->ds_ctl3 = ads->ds_ctl3;
-}
-
-void ath9k_hw_set11n_aggr_first(struct ath_hw *ah, struct ath_desc *ds,
-                               u32 aggrLen)
-{
-       struct ar5416_desc *ads = AR5416DESC(ds);
-
-       ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
-       ads->ds_ctl6 &= ~AR_AggrLen;
-       ads->ds_ctl6 |= SM(aggrLen, AR_AggrLen);
-}
-
-void ath9k_hw_set11n_aggr_middle(struct ath_hw *ah, struct ath_desc *ds,
-                                u32 numDelims)
-{
-       struct ar5416_desc *ads = AR5416DESC(ds);
-       unsigned int ctl6;
-
-       ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
-
-       ctl6 = ads->ds_ctl6;
-       ctl6 &= ~AR_PadDelim;
-       ctl6 |= SM(numDelims, AR_PadDelim);
-       ads->ds_ctl6 = ctl6;
-}
-
-void ath9k_hw_set11n_aggr_last(struct ath_hw *ah, struct ath_desc *ds)
-{
-       struct ar5416_desc *ads = AR5416DESC(ds);
-
-       ads->ds_ctl1 |= AR_IsAggr;
-       ads->ds_ctl1 &= ~AR_MoreAggr;
-       ads->ds_ctl6 &= ~AR_PadDelim;
-}
-
-void ath9k_hw_clr11n_aggr(struct ath_hw *ah, struct ath_desc *ds)
-{
-       struct ar5416_desc *ads = AR5416DESC(ds);
-
-       ads->ds_ctl1 &= (~AR_IsAggr & ~AR_MoreAggr);
-}
-
-void ath9k_hw_set11n_burstduration(struct ath_hw *ah, struct ath_desc *ds,
-                                  u32 burstDuration)
-{
-       struct ar5416_desc *ads = AR5416DESC(ds);
-
-       ads->ds_ctl2 &= ~AR_BurstDur;
-       ads->ds_ctl2 |= SM(burstDuration, AR_BurstDur);
-}
-
-void ath9k_hw_set11n_virtualmorefrag(struct ath_hw *ah, struct ath_desc *ds,
-                                    u32 vmf)
-{
-       struct ar5416_desc *ads = AR5416DESC(ds);
-
-       if (vmf)
-               ads->ds_ctl0 |= AR_VirtMoreFrag;
-       else
-               ads->ds_ctl0 &= ~AR_VirtMoreFrag;
-}
-
-void ath9k_hw_gettxintrtxqs(struct ath_hw *ah, u32 *txqs)
-{
-       *txqs &= ah->intr_txqs;
-       ah->intr_txqs &= ~(*txqs);
-}
-
-bool ath9k_hw_set_txq_props(struct ath_hw *ah, int q,
-                           const struct ath9k_tx_queue_info *qinfo)
-{
-       u32 cw;
-       struct ath9k_hw_capabilities *pCap = &ah->caps;
-       struct ath9k_tx_queue_info *qi;
-
-       if (q >= pCap->total_queues) {
-               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "invalid queue num %u\n", q);
-               return false;
-       }
-
-       qi = &ah->txq[q];
-       if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
-               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "inactive queue\n");
-               return false;
-       }
-
-       DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "queue %p\n", qi);
-
-       qi->tqi_ver = qinfo->tqi_ver;
-       qi->tqi_subtype = qinfo->tqi_subtype;
-       qi->tqi_qflags = qinfo->tqi_qflags;
-       qi->tqi_priority = qinfo->tqi_priority;
-       if (qinfo->tqi_aifs != ATH9K_TXQ_USEDEFAULT)
-               qi->tqi_aifs = min(qinfo->tqi_aifs, 255U);
-       else
-               qi->tqi_aifs = INIT_AIFS;
-       if (qinfo->tqi_cwmin != ATH9K_TXQ_USEDEFAULT) {
-               cw = min(qinfo->tqi_cwmin, 1024U);
-               qi->tqi_cwmin = 1;
-               while (qi->tqi_cwmin < cw)
-                       qi->tqi_cwmin = (qi->tqi_cwmin << 1) | 1;
-       } else
-               qi->tqi_cwmin = qinfo->tqi_cwmin;
-       if (qinfo->tqi_cwmax != ATH9K_TXQ_USEDEFAULT) {
-               cw = min(qinfo->tqi_cwmax, 1024U);
-               qi->tqi_cwmax = 1;
-               while (qi->tqi_cwmax < cw)
-                       qi->tqi_cwmax = (qi->tqi_cwmax << 1) | 1;
-       } else
-               qi->tqi_cwmax = INIT_CWMAX;
-
-       if (qinfo->tqi_shretry != 0)
-               qi->tqi_shretry = min((u32) qinfo->tqi_shretry, 15U);
-       else
-               qi->tqi_shretry = INIT_SH_RETRY;
-       if (qinfo->tqi_lgretry != 0)
-               qi->tqi_lgretry = min((u32) qinfo->tqi_lgretry, 15U);
-       else
-               qi->tqi_lgretry = INIT_LG_RETRY;
-       qi->tqi_cbrPeriod = qinfo->tqi_cbrPeriod;
-       qi->tqi_cbrOverflowLimit = qinfo->tqi_cbrOverflowLimit;
-       qi->tqi_burstTime = qinfo->tqi_burstTime;
-       qi->tqi_readyTime = qinfo->tqi_readyTime;
-
-       switch (qinfo->tqi_subtype) {
-       case ATH9K_WME_UPSD:
-               if (qi->tqi_type == ATH9K_TX_QUEUE_DATA)
-                       qi->tqi_intFlags = ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS;
-               break;
-       default:
-               break;
-       }
-
-       return true;
-}
-
-bool ath9k_hw_get_txq_props(struct ath_hw *ah, int q,
-                           struct ath9k_tx_queue_info *qinfo)
-{
-       struct ath9k_hw_capabilities *pCap = &ah->caps;
-       struct ath9k_tx_queue_info *qi;
-
-       if (q >= pCap->total_queues) {
-               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "invalid queue num %u\n", q);
-               return false;
-       }
-
-       qi = &ah->txq[q];
-       if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
-               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "inactive queue\n");
-               return false;
-       }
-
-       qinfo->tqi_qflags = qi->tqi_qflags;
-       qinfo->tqi_ver = qi->tqi_ver;
-       qinfo->tqi_subtype = qi->tqi_subtype;
-       qinfo->tqi_qflags = qi->tqi_qflags;
-       qinfo->tqi_priority = qi->tqi_priority;
-       qinfo->tqi_aifs = qi->tqi_aifs;
-       qinfo->tqi_cwmin = qi->tqi_cwmin;
-       qinfo->tqi_cwmax = qi->tqi_cwmax;
-       qinfo->tqi_shretry = qi->tqi_shretry;
-       qinfo->tqi_lgretry = qi->tqi_lgretry;
-       qinfo->tqi_cbrPeriod = qi->tqi_cbrPeriod;
-       qinfo->tqi_cbrOverflowLimit = qi->tqi_cbrOverflowLimit;
-       qinfo->tqi_burstTime = qi->tqi_burstTime;
-       qinfo->tqi_readyTime = qi->tqi_readyTime;
-
-       return true;
-}
-
-int ath9k_hw_setuptxqueue(struct ath_hw *ah, enum ath9k_tx_queue type,
-                         const struct ath9k_tx_queue_info *qinfo)
-{
-       struct ath9k_tx_queue_info *qi;
-       struct ath9k_hw_capabilities *pCap = &ah->caps;
-       int q;
-
-       switch (type) {
-       case ATH9K_TX_QUEUE_BEACON:
-               q = pCap->total_queues - 1;
-               break;
-       case ATH9K_TX_QUEUE_CAB:
-               q = pCap->total_queues - 2;
-               break;
-       case ATH9K_TX_QUEUE_PSPOLL:
-               q = 1;
-               break;
-       case ATH9K_TX_QUEUE_UAPSD:
-               q = pCap->total_queues - 3;
-               break;
-       case ATH9K_TX_QUEUE_DATA:
-               for (q = 0; q < pCap->total_queues; q++)
-                       if (ah->txq[q].tqi_type ==
-                           ATH9K_TX_QUEUE_INACTIVE)
-                               break;
-               if (q == pCap->total_queues) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
-                               "no available tx queue\n");
-                       return -1;
-               }
-               break;
-       default:
-               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "bad tx queue type %u\n", type);
-               return -1;
-       }
-
-       DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "queue %u\n", q);
-
-       qi = &ah->txq[q];
-       if (qi->tqi_type != ATH9K_TX_QUEUE_INACTIVE) {
-               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
-                       "tx queue %u already active\n", q);
-               return -1;
-       }
-       memset(qi, 0, sizeof(struct ath9k_tx_queue_info));
-       qi->tqi_type = type;
-       if (qinfo == NULL) {
-               qi->tqi_qflags =
-                       TXQ_FLAG_TXOKINT_ENABLE
-                       | TXQ_FLAG_TXERRINT_ENABLE
-                       | TXQ_FLAG_TXDESCINT_ENABLE | TXQ_FLAG_TXURNINT_ENABLE;
-               qi->tqi_aifs = INIT_AIFS;
-               qi->tqi_cwmin = ATH9K_TXQ_USEDEFAULT;
-               qi->tqi_cwmax = INIT_CWMAX;
-               qi->tqi_shretry = INIT_SH_RETRY;
-               qi->tqi_lgretry = INIT_LG_RETRY;
-               qi->tqi_physCompBuf = 0;
-       } else {
-               qi->tqi_physCompBuf = qinfo->tqi_physCompBuf;
-               (void) ath9k_hw_set_txq_props(ah, q, qinfo);
-       }
-
-       return q;
-}
-
-bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q)
-{
-       struct ath9k_hw_capabilities *pCap = &ah->caps;
-       struct ath9k_tx_queue_info *qi;
-
-       if (q >= pCap->total_queues) {
-               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "invalid queue num %u\n", q);
-               return false;
-       }
-       qi = &ah->txq[q];
-       if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
-               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "inactive queue %u\n", q);
-               return false;
-       }
-
-       DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "release queue %u\n", q);
-
-       qi->tqi_type = ATH9K_TX_QUEUE_INACTIVE;
-       ah->txok_interrupt_mask &= ~(1 << q);
-       ah->txerr_interrupt_mask &= ~(1 << q);
-       ah->txdesc_interrupt_mask &= ~(1 << q);
-       ah->txeol_interrupt_mask &= ~(1 << q);
-       ah->txurn_interrupt_mask &= ~(1 << q);
-       ath9k_hw_set_txq_interrupts(ah, qi);
-
-       return true;
-}
-
-bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
-{
-       struct ath9k_hw_capabilities *pCap = &ah->caps;
-       struct ath9k_channel *chan = ah->curchan;
-       struct ath9k_tx_queue_info *qi;
-       u32 cwMin, chanCwMin, value;
-
-       if (q >= pCap->total_queues) {
-               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "invalid queue num %u\n", q);
-               return false;
-       }
-
-       qi = &ah->txq[q];
-       if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
-               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "inactive queue %u\n", q);
-               return true;
-       }
-
-       DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "reset queue %u\n", q);
-
-       if (qi->tqi_cwmin == ATH9K_TXQ_USEDEFAULT) {
-               if (chan && IS_CHAN_B(chan))
-                       chanCwMin = INIT_CWMIN_11B;
-               else
-                       chanCwMin = INIT_CWMIN;
-
-               for (cwMin = 1; cwMin < chanCwMin; cwMin = (cwMin << 1) | 1);
-       } else
-               cwMin = qi->tqi_cwmin;
-
-       REG_WRITE(ah, AR_DLCL_IFS(q),
-                 SM(cwMin, AR_D_LCL_IFS_CWMIN) |
-                 SM(qi->tqi_cwmax, AR_D_LCL_IFS_CWMAX) |
-                 SM(qi->tqi_aifs, AR_D_LCL_IFS_AIFS));
-
-       REG_WRITE(ah, AR_DRETRY_LIMIT(q),
-                 SM(INIT_SSH_RETRY, AR_D_RETRY_LIMIT_STA_SH) |
-                 SM(INIT_SLG_RETRY, AR_D_RETRY_LIMIT_STA_LG) |
-                 SM(qi->tqi_shretry, AR_D_RETRY_LIMIT_FR_SH));
-
-       REG_WRITE(ah, AR_QMISC(q), AR_Q_MISC_DCU_EARLY_TERM_REQ);
-       REG_WRITE(ah, AR_DMISC(q),
-                 AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x2);
-
-       if (qi->tqi_cbrPeriod) {
-               REG_WRITE(ah, AR_QCBRCFG(q),
-                         SM(qi->tqi_cbrPeriod, AR_Q_CBRCFG_INTERVAL) |
-                         SM(qi->tqi_cbrOverflowLimit, AR_Q_CBRCFG_OVF_THRESH));
-               REG_WRITE(ah, AR_QMISC(q),
-                         REG_READ(ah, AR_QMISC(q)) | AR_Q_MISC_FSP_CBR |
-                         (qi->tqi_cbrOverflowLimit ?
-                          AR_Q_MISC_CBR_EXP_CNTR_LIMIT_EN : 0));
-       }
-       if (qi->tqi_readyTime && (qi->tqi_type != ATH9K_TX_QUEUE_CAB)) {
-               REG_WRITE(ah, AR_QRDYTIMECFG(q),
-                         SM(qi->tqi_readyTime, AR_Q_RDYTIMECFG_DURATION) |
-                         AR_Q_RDYTIMECFG_EN);
-       }
-
-       REG_WRITE(ah, AR_DCHNTIME(q),
-                 SM(qi->tqi_burstTime, AR_D_CHNTIME_DUR) |
-                 (qi->tqi_burstTime ? AR_D_CHNTIME_EN : 0));
-
-       if (qi->tqi_burstTime
-           && (qi->tqi_qflags & TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE)) {
-               REG_WRITE(ah, AR_QMISC(q),
-                         REG_READ(ah, AR_QMISC(q)) |
-                         AR_Q_MISC_RDYTIME_EXP_POLICY);
-
-       }
-
-       if (qi->tqi_qflags & TXQ_FLAG_BACKOFF_DISABLE) {
-               REG_WRITE(ah, AR_DMISC(q),
-                         REG_READ(ah, AR_DMISC(q)) |
-                         AR_D_MISC_POST_FR_BKOFF_DIS);
-       }
-       if (qi->tqi_qflags & TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE) {
-               REG_WRITE(ah, AR_DMISC(q),
-                         REG_READ(ah, AR_DMISC(q)) |
-                         AR_D_MISC_FRAG_BKOFF_EN);
-       }
-       switch (qi->tqi_type) {
-       case ATH9K_TX_QUEUE_BEACON:
-               REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q))
-                         | AR_Q_MISC_FSP_DBA_GATED
-                         | AR_Q_MISC_BEACON_USE
-                         | AR_Q_MISC_CBR_INCR_DIS1);
-
-               REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q))
-                         | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL <<
-                            AR_D_MISC_ARB_LOCKOUT_CNTRL_S)
-                         | AR_D_MISC_BEACON_USE
-                         | AR_D_MISC_POST_FR_BKOFF_DIS);
-               break;
-       case ATH9K_TX_QUEUE_CAB:
-               REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q))
-                         | AR_Q_MISC_FSP_DBA_GATED
-                         | AR_Q_MISC_CBR_INCR_DIS1
-                         | AR_Q_MISC_CBR_INCR_DIS0);
-               value = (qi->tqi_readyTime -
-                        (ah->config.sw_beacon_response_time -
-                         ah->config.dma_beacon_response_time) -
-                        ah->config.additional_swba_backoff) * 1024;
-               REG_WRITE(ah, AR_QRDYTIMECFG(q),
-                         value | AR_Q_RDYTIMECFG_EN);
-               REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q))
-                         | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL <<
-                            AR_D_MISC_ARB_LOCKOUT_CNTRL_S));
-               break;
-       case ATH9K_TX_QUEUE_PSPOLL:
-               REG_WRITE(ah, AR_QMISC(q),
-                         REG_READ(ah, AR_QMISC(q)) | AR_Q_MISC_CBR_INCR_DIS1);
-               break;
-       case ATH9K_TX_QUEUE_UAPSD:
-               REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q)) |
-                         AR_D_MISC_POST_FR_BKOFF_DIS);
-               break;
-       default:
-               break;
-       }
-
-       if (qi->tqi_intFlags & ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS) {
-               REG_WRITE(ah, AR_DMISC(q),
-                         REG_READ(ah, AR_DMISC(q)) |
-                         SM(AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL,
-                            AR_D_MISC_ARB_LOCKOUT_CNTRL) |
-                         AR_D_MISC_POST_FR_BKOFF_DIS);
-       }
-
-       if (qi->tqi_qflags & TXQ_FLAG_TXOKINT_ENABLE)
-               ah->txok_interrupt_mask |= 1 << q;
-       else
-               ah->txok_interrupt_mask &= ~(1 << q);
-       if (qi->tqi_qflags & TXQ_FLAG_TXERRINT_ENABLE)
-               ah->txerr_interrupt_mask |= 1 << q;
-       else
-               ah->txerr_interrupt_mask &= ~(1 << q);
-       if (qi->tqi_qflags & TXQ_FLAG_TXDESCINT_ENABLE)
-               ah->txdesc_interrupt_mask |= 1 << q;
-       else
-               ah->txdesc_interrupt_mask &= ~(1 << q);
-       if (qi->tqi_qflags & TXQ_FLAG_TXEOLINT_ENABLE)
-               ah->txeol_interrupt_mask |= 1 << q;
-       else
-               ah->txeol_interrupt_mask &= ~(1 << q);
-       if (qi->tqi_qflags & TXQ_FLAG_TXURNINT_ENABLE)
-               ah->txurn_interrupt_mask |= 1 << q;
-       else
-               ah->txurn_interrupt_mask &= ~(1 << q);
-       ath9k_hw_set_txq_interrupts(ah, qi);
-
-       return true;
-}
-
-int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
-                       u32 pa, struct ath_desc *nds, u64 tsf)
-{
-       struct ar5416_desc ads;
-       struct ar5416_desc *adsp = AR5416DESC(ds);
-       u32 phyerr;
-
-       if ((adsp->ds_rxstatus8 & AR_RxDone) == 0)
-               return -EINPROGRESS;
-
-       ads.u.rx = adsp->u.rx;
-
-       ds->ds_rxstat.rs_status = 0;
-       ds->ds_rxstat.rs_flags = 0;
-
-       ds->ds_rxstat.rs_datalen = ads.ds_rxstatus1 & AR_DataLen;
-       ds->ds_rxstat.rs_tstamp = ads.AR_RcvTimestamp;
-
-       ds->ds_rxstat.rs_rssi = MS(ads.ds_rxstatus4, AR_RxRSSICombined);
-       ds->ds_rxstat.rs_rssi_ctl0 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt00);
-       ds->ds_rxstat.rs_rssi_ctl1 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt01);
-       ds->ds_rxstat.rs_rssi_ctl2 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt02);
-       ds->ds_rxstat.rs_rssi_ext0 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt10);
-       ds->ds_rxstat.rs_rssi_ext1 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt11);
-       ds->ds_rxstat.rs_rssi_ext2 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt12);
-       if (ads.ds_rxstatus8 & AR_RxKeyIdxValid)
-               ds->ds_rxstat.rs_keyix = MS(ads.ds_rxstatus8, AR_KeyIdx);
-       else
-               ds->ds_rxstat.rs_keyix = ATH9K_RXKEYIX_INVALID;
-
-       ds->ds_rxstat.rs_rate = RXSTATUS_RATE(ah, (&ads));
-       ds->ds_rxstat.rs_more = (ads.ds_rxstatus1 & AR_RxMore) ? 1 : 0;
-
-       ds->ds_rxstat.rs_isaggr = (ads.ds_rxstatus8 & AR_RxAggr) ? 1 : 0;
-       ds->ds_rxstat.rs_moreaggr =
-               (ads.ds_rxstatus8 & AR_RxMoreAggr) ? 1 : 0;
-       ds->ds_rxstat.rs_antenna = MS(ads.ds_rxstatus3, AR_RxAntenna);
-       ds->ds_rxstat.rs_flags =
-               (ads.ds_rxstatus3 & AR_GI) ? ATH9K_RX_GI : 0;
-       ds->ds_rxstat.rs_flags |=
-               (ads.ds_rxstatus3 & AR_2040) ? ATH9K_RX_2040 : 0;
-
-       if (ads.ds_rxstatus8 & AR_PreDelimCRCErr)
-               ds->ds_rxstat.rs_flags |= ATH9K_RX_DELIM_CRC_PRE;
-       if (ads.ds_rxstatus8 & AR_PostDelimCRCErr)
-               ds->ds_rxstat.rs_flags |= ATH9K_RX_DELIM_CRC_POST;
-       if (ads.ds_rxstatus8 & AR_DecryptBusyErr)
-               ds->ds_rxstat.rs_flags |= ATH9K_RX_DECRYPT_BUSY;
-
-       if ((ads.ds_rxstatus8 & AR_RxFrameOK) == 0) {
-               if (ads.ds_rxstatus8 & AR_CRCErr)
-                       ds->ds_rxstat.rs_status |= ATH9K_RXERR_CRC;
-               else if (ads.ds_rxstatus8 & AR_PHYErr) {
-                       ds->ds_rxstat.rs_status |= ATH9K_RXERR_PHY;
-                       phyerr = MS(ads.ds_rxstatus8, AR_PHYErrCode);
-                       ds->ds_rxstat.rs_phyerr = phyerr;
-               } else if (ads.ds_rxstatus8 & AR_DecryptCRCErr)
-                       ds->ds_rxstat.rs_status |= ATH9K_RXERR_DECRYPT;
-               else if (ads.ds_rxstatus8 & AR_MichaelErr)
-                       ds->ds_rxstat.rs_status |= ATH9K_RXERR_MIC;
-       }
-
-       return 0;
-}
-
-bool ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds,
-                         u32 size, u32 flags)
-{
-       struct ar5416_desc *ads = AR5416DESC(ds);
-       struct ath9k_hw_capabilities *pCap = &ah->caps;
-
-       ads->ds_ctl1 = size & AR_BufLen;
-       if (flags & ATH9K_RXDESC_INTREQ)
-               ads->ds_ctl1 |= AR_RxIntrReq;
-
-       ads->ds_rxstatus8 &= ~AR_RxDone;
-       if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
-               memset(&(ads->u), 0, sizeof(ads->u));
-
-       return true;
-}
-
-bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set)
-{
-       u32 reg;
-
-       if (set) {
-               REG_SET_BIT(ah, AR_DIAG_SW,
-                           (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
-
-               if (!ath9k_hw_wait(ah, AR_OBS_BUS_1, AR_OBS_BUS_1_RX_STATE,
-                                  0, AH_WAIT_TIMEOUT)) {
-                       REG_CLR_BIT(ah, AR_DIAG_SW,
-                                   (AR_DIAG_RX_DIS |
-                                    AR_DIAG_RX_ABORT));
-
-                       reg = REG_READ(ah, AR_OBS_BUS_1);
-                       DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-                               "rx failed to go idle in 10 ms RXSM=0x%x\n", reg);
-
-                       return false;
-               }
-       } else {
-               REG_CLR_BIT(ah, AR_DIAG_SW,
-                           (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
-       }
-
-       return true;
-}
-
-void ath9k_hw_putrxbuf(struct ath_hw *ah, u32 rxdp)
-{
-       REG_WRITE(ah, AR_RXDP, rxdp);
-}
-
-void ath9k_hw_rxena(struct ath_hw *ah)
-{
-       REG_WRITE(ah, AR_CR, AR_CR_RXE);
-}
-
-void ath9k_hw_startpcureceive(struct ath_hw *ah)
-{
-       ath9k_enable_mib_counters(ah);
-
-       ath9k_ani_reset(ah);
-
-       REG_CLR_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
-}
-
-void ath9k_hw_stoppcurecv(struct ath_hw *ah)
-{
-       REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS);
-
-       ath9k_hw_disable_mib_counters(ah);
-}
-
-bool ath9k_hw_stopdmarecv(struct ath_hw *ah)
-{
-#define AH_RX_STOP_DMA_TIMEOUT 10000   /* usec */
-#define AH_RX_TIME_QUANTUM     100     /* usec */
-
-       int i;
-
-       REG_WRITE(ah, AR_CR, AR_CR_RXD);
-
-       /* Wait for rx enable bit to go low */
-       for (i = AH_RX_STOP_DMA_TIMEOUT / AH_TIME_QUANTUM; i != 0; i--) {
-               if ((REG_READ(ah, AR_CR) & AR_CR_RXE) == 0)
-                       break;
-               udelay(AH_TIME_QUANTUM);
-       }
-
-       if (i == 0) {
-               DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
-                       "dma failed to stop in %d ms "
-                       "AR_CR=0x%08x AR_DIAG_SW=0x%08x\n",
-                       AH_RX_STOP_DMA_TIMEOUT / 1000,
-                       REG_READ(ah, AR_CR),
-                       REG_READ(ah, AR_DIAG_SW));
-               return false;
-       } else {
-               return true;
-       }
-
-#undef AH_RX_TIME_QUANTUM
-#undef AH_RX_STOP_DMA_TIMEOUT
-}
diff --git a/drivers/net/wireless/ath9k/mac.h b/drivers/net/wireless/ath9k/mac.h
deleted file mode 100644 (file)
index 1176bce..0000000
+++ /dev/null
@@ -1,680 +0,0 @@
-/*
- * Copyright (c) 2008-2009 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 MAC_H
-#define MAC_H
-
-#define RXSTATUS_RATE(ah, ads) (AR_SREV_5416_20_OR_LATER(ah) ?         \
-                               MS(ads->ds_rxstatus0, AR_RxRate) :      \
-                               (ads->ds_rxstatus3 >> 2) & 0xFF)
-
-#define set11nTries(_series, _index) \
-       (SM((_series)[_index].Tries, AR_XmitDataTries##_index))
-
-#define set11nRate(_series, _index) \
-       (SM((_series)[_index].Rate, AR_XmitRate##_index))
-
-#define set11nPktDurRTSCTS(_series, _index)                            \
-       (SM((_series)[_index].PktDuration, AR_PacketDur##_index) |      \
-        ((_series)[_index].RateFlags & ATH9K_RATESERIES_RTS_CTS   ?    \
-         AR_RTSCTSQual##_index : 0))
-
-#define set11nRateFlags(_series, _index)                               \
-       (((_series)[_index].RateFlags & ATH9K_RATESERIES_2040 ?         \
-         AR_2040_##_index : 0)                                         \
-        |((_series)[_index].RateFlags & ATH9K_RATESERIES_HALFGI ?      \
-          AR_GI##_index : 0)                                           \
-        |SM((_series)[_index].ChSel, AR_ChainSel##_index))
-
-#define CCK_SIFS_TIME        10
-#define CCK_PREAMBLE_BITS   144
-#define CCK_PLCP_BITS        48
-
-#define OFDM_SIFS_TIME        16
-#define OFDM_PREAMBLE_TIME    20
-#define OFDM_PLCP_BITS        22
-#define OFDM_SYMBOL_TIME      4
-
-#define OFDM_SIFS_TIME_HALF     32
-#define OFDM_PREAMBLE_TIME_HALF 40
-#define OFDM_PLCP_BITS_HALF     22
-#define OFDM_SYMBOL_TIME_HALF   8
-
-#define OFDM_SIFS_TIME_QUARTER      64
-#define OFDM_PREAMBLE_TIME_QUARTER  80
-#define OFDM_PLCP_BITS_QUARTER      22
-#define OFDM_SYMBOL_TIME_QUARTER    16
-
-#define INIT_AIFS       2
-#define INIT_CWMIN      15
-#define INIT_CWMIN_11B  31
-#define INIT_CWMAX      1023
-#define INIT_SH_RETRY   10
-#define INIT_LG_RETRY   10
-#define INIT_SSH_RETRY  32
-#define INIT_SLG_RETRY  32
-
-#define ATH9K_SLOT_TIME_6 6
-#define ATH9K_SLOT_TIME_9 9
-#define ATH9K_SLOT_TIME_20 20
-
-#define ATH9K_TXERR_XRETRY         0x01
-#define ATH9K_TXERR_FILT           0x02
-#define ATH9K_TXERR_FIFO           0x04
-#define ATH9K_TXERR_XTXOP          0x08
-#define ATH9K_TXERR_TIMER_EXPIRED  0x10
-
-#define ATH9K_TX_BA                0x01
-#define ATH9K_TX_PWRMGMT           0x02
-#define ATH9K_TX_DESC_CFG_ERR      0x04
-#define ATH9K_TX_DATA_UNDERRUN     0x08
-#define ATH9K_TX_DELIM_UNDERRUN    0x10
-#define ATH9K_TX_SW_ABORTED        0x40
-#define ATH9K_TX_SW_FILTERED       0x80
-
-#define MIN_TX_FIFO_THRESHOLD   0x1
-#define MAX_TX_FIFO_THRESHOLD   ((4096 / 64) - 1)
-#define INIT_TX_FIFO_THRESHOLD  MIN_TX_FIFO_THRESHOLD
-
-struct ath_tx_status {
-       u32 ts_tstamp;
-       u16 ts_seqnum;
-       u8 ts_status;
-       u8 ts_ratecode;
-       u8 ts_rateindex;
-       int8_t ts_rssi;
-       u8 ts_shortretry;
-       u8 ts_longretry;
-       u8 ts_virtcol;
-       u8 ts_antenna;
-       u8 ts_flags;
-       int8_t ts_rssi_ctl0;
-       int8_t ts_rssi_ctl1;
-       int8_t ts_rssi_ctl2;
-       int8_t ts_rssi_ext0;
-       int8_t ts_rssi_ext1;
-       int8_t ts_rssi_ext2;
-       u8 pad[3];
-       u32 ba_low;
-       u32 ba_high;
-       u32 evm0;
-       u32 evm1;
-       u32 evm2;
-};
-
-struct ath_rx_status {
-       u32 rs_tstamp;
-       u16 rs_datalen;
-       u8 rs_status;
-       u8 rs_phyerr;
-       int8_t rs_rssi;
-       u8 rs_keyix;
-       u8 rs_rate;
-       u8 rs_antenna;
-       u8 rs_more;
-       int8_t rs_rssi_ctl0;
-       int8_t rs_rssi_ctl1;
-       int8_t rs_rssi_ctl2;
-       int8_t rs_rssi_ext0;
-       int8_t rs_rssi_ext1;
-       int8_t rs_rssi_ext2;
-       u8 rs_isaggr;
-       u8 rs_moreaggr;
-       u8 rs_num_delims;
-       u8 rs_flags;
-       u32 evm0;
-       u32 evm1;
-       u32 evm2;
-};
-
-#define ATH9K_RXERR_CRC           0x01
-#define ATH9K_RXERR_PHY           0x02
-#define ATH9K_RXERR_FIFO          0x04
-#define ATH9K_RXERR_DECRYPT       0x08
-#define ATH9K_RXERR_MIC           0x10
-
-#define ATH9K_RX_MORE             0x01
-#define ATH9K_RX_MORE_AGGR        0x02
-#define ATH9K_RX_GI               0x04
-#define ATH9K_RX_2040             0x08
-#define ATH9K_RX_DELIM_CRC_PRE    0x10
-#define ATH9K_RX_DELIM_CRC_POST   0x20
-#define ATH9K_RX_DECRYPT_BUSY     0x40
-
-#define ATH9K_RXKEYIX_INVALID  ((u8)-1)
-#define ATH9K_TXKEYIX_INVALID  ((u32)-1)
-
-struct ath_desc {
-       u32 ds_link;
-       u32 ds_data;
-       u32 ds_ctl0;
-       u32 ds_ctl1;
-       u32 ds_hw[20];
-       union {
-               struct ath_tx_status tx;
-               struct ath_rx_status rx;
-               void *stats;
-       } ds_us;
-       void *ds_vdata;
-} __packed;
-
-#define        ds_txstat       ds_us.tx
-#define        ds_rxstat       ds_us.rx
-#define ds_stat                ds_us.stats
-
-#define ATH9K_TXDESC_CLRDMASK          0x0001
-#define ATH9K_TXDESC_NOACK             0x0002
-#define ATH9K_TXDESC_RTSENA            0x0004
-#define ATH9K_TXDESC_CTSENA            0x0008
-/* ATH9K_TXDESC_INTREQ forces a tx interrupt to be generated for
- * the descriptor its marked on.  We take a tx interrupt to reap
- * descriptors when the h/w hits an EOL condition or
- * when the descriptor is specifically marked to generate
- * an interrupt with this flag. Descriptors should be
- * marked periodically to insure timely replenishing of the
- * supply needed for sending frames. Defering interrupts
- * reduces system load and potentially allows more concurrent
- * work to be done but if done to aggressively can cause
- * senders to backup. When the hardware queue is left too
- * large rate control information may also be too out of
- * date. An Alternative for this is TX interrupt mitigation
- * but this needs more testing. */
-#define ATH9K_TXDESC_INTREQ            0x0010
-#define ATH9K_TXDESC_VEOL              0x0020
-#define ATH9K_TXDESC_EXT_ONLY          0x0040
-#define ATH9K_TXDESC_EXT_AND_CTL       0x0080
-#define ATH9K_TXDESC_VMF               0x0100
-#define ATH9K_TXDESC_FRAG_IS_ON        0x0200
-#define ATH9K_TXDESC_CAB               0x0400
-
-#define ATH9K_RXDESC_INTREQ            0x0020
-
-struct ar5416_desc {
-       u32 ds_link;
-       u32 ds_data;
-       u32 ds_ctl0;
-       u32 ds_ctl1;
-       union {
-               struct {
-                       u32 ctl2;
-                       u32 ctl3;
-                       u32 ctl4;
-                       u32 ctl5;
-                       u32 ctl6;
-                       u32 ctl7;
-                       u32 ctl8;
-                       u32 ctl9;
-                       u32 ctl10;
-                       u32 ctl11;
-                       u32 status0;
-                       u32 status1;
-                       u32 status2;
-                       u32 status3;
-                       u32 status4;
-                       u32 status5;
-                       u32 status6;
-                       u32 status7;
-                       u32 status8;
-                       u32 status9;
-               } tx;
-               struct {
-                       u32 status0;
-                       u32 status1;
-                       u32 status2;
-                       u32 status3;
-                       u32 status4;
-                       u32 status5;
-                       u32 status6;
-                       u32 status7;
-                       u32 status8;
-               } rx;
-       } u;
-} __packed;
-
-#define AR5416DESC(_ds)         ((struct ar5416_desc *)(_ds))
-#define AR5416DESC_CONST(_ds)   ((const struct ar5416_desc *)(_ds))
-
-#define ds_ctl2     u.tx.ctl2
-#define ds_ctl3     u.tx.ctl3
-#define ds_ctl4     u.tx.ctl4
-#define ds_ctl5     u.tx.ctl5
-#define ds_ctl6     u.tx.ctl6
-#define ds_ctl7     u.tx.ctl7
-#define ds_ctl8     u.tx.ctl8
-#define ds_ctl9     u.tx.ctl9
-#define ds_ctl10    u.tx.ctl10
-#define ds_ctl11    u.tx.ctl11
-
-#define ds_txstatus0    u.tx.status0
-#define ds_txstatus1    u.tx.status1
-#define ds_txstatus2    u.tx.status2
-#define ds_txstatus3    u.tx.status3
-#define ds_txstatus4    u.tx.status4
-#define ds_txstatus5    u.tx.status5
-#define ds_txstatus6    u.tx.status6
-#define ds_txstatus7    u.tx.status7
-#define ds_txstatus8    u.tx.status8
-#define ds_txstatus9    u.tx.status9
-
-#define ds_rxstatus0    u.rx.status0
-#define ds_rxstatus1    u.rx.status1
-#define ds_rxstatus2    u.rx.status2
-#define ds_rxstatus3    u.rx.status3
-#define ds_rxstatus4    u.rx.status4
-#define ds_rxstatus5    u.rx.status5
-#define ds_rxstatus6    u.rx.status6
-#define ds_rxstatus7    u.rx.status7
-#define ds_rxstatus8    u.rx.status8
-
-#define AR_FrameLen         0x00000fff
-#define AR_VirtMoreFrag     0x00001000
-#define AR_TxCtlRsvd00      0x0000e000
-#define AR_XmitPower        0x003f0000
-#define AR_XmitPower_S      16
-#define AR_RTSEnable        0x00400000
-#define AR_VEOL             0x00800000
-#define AR_ClrDestMask      0x01000000
-#define AR_TxCtlRsvd01      0x1e000000
-#define AR_TxIntrReq        0x20000000
-#define AR_DestIdxValid     0x40000000
-#define AR_CTSEnable        0x80000000
-
-#define AR_BufLen           0x00000fff
-#define AR_TxMore           0x00001000
-#define AR_DestIdx          0x000fe000
-#define AR_DestIdx_S        13
-#define AR_FrameType        0x00f00000
-#define AR_FrameType_S      20
-#define AR_NoAck            0x01000000
-#define AR_InsertTS         0x02000000
-#define AR_CorruptFCS       0x04000000
-#define AR_ExtOnly          0x08000000
-#define AR_ExtAndCtl        0x10000000
-#define AR_MoreAggr         0x20000000
-#define AR_IsAggr           0x40000000
-
-#define AR_BurstDur         0x00007fff
-#define AR_BurstDur_S       0
-#define AR_DurUpdateEna     0x00008000
-#define AR_XmitDataTries0   0x000f0000
-#define AR_XmitDataTries0_S 16
-#define AR_XmitDataTries1   0x00f00000
-#define AR_XmitDataTries1_S 20
-#define AR_XmitDataTries2   0x0f000000
-#define AR_XmitDataTries2_S 24
-#define AR_XmitDataTries3   0xf0000000
-#define AR_XmitDataTries3_S 28
-
-#define AR_XmitRate0        0x000000ff
-#define AR_XmitRate0_S      0
-#define AR_XmitRate1        0x0000ff00
-#define AR_XmitRate1_S      8
-#define AR_XmitRate2        0x00ff0000
-#define AR_XmitRate2_S      16
-#define AR_XmitRate3        0xff000000
-#define AR_XmitRate3_S      24
-
-#define AR_PacketDur0       0x00007fff
-#define AR_PacketDur0_S     0
-#define AR_RTSCTSQual0      0x00008000
-#define AR_PacketDur1       0x7fff0000
-#define AR_PacketDur1_S     16
-#define AR_RTSCTSQual1      0x80000000
-
-#define AR_PacketDur2       0x00007fff
-#define AR_PacketDur2_S     0
-#define AR_RTSCTSQual2      0x00008000
-#define AR_PacketDur3       0x7fff0000
-#define AR_PacketDur3_S     16
-#define AR_RTSCTSQual3      0x80000000
-
-#define AR_AggrLen          0x0000ffff
-#define AR_AggrLen_S        0
-#define AR_TxCtlRsvd60      0x00030000
-#define AR_PadDelim         0x03fc0000
-#define AR_PadDelim_S       18
-#define AR_EncrType         0x0c000000
-#define AR_EncrType_S       26
-#define AR_TxCtlRsvd61      0xf0000000
-
-#define AR_2040_0           0x00000001
-#define AR_GI0              0x00000002
-#define AR_ChainSel0        0x0000001c
-#define AR_ChainSel0_S      2
-#define AR_2040_1           0x00000020
-#define AR_GI1              0x00000040
-#define AR_ChainSel1        0x00000380
-#define AR_ChainSel1_S      7
-#define AR_2040_2           0x00000400
-#define AR_GI2              0x00000800
-#define AR_ChainSel2        0x00007000
-#define AR_ChainSel2_S      12
-#define AR_2040_3           0x00008000
-#define AR_GI3              0x00010000
-#define AR_ChainSel3        0x000e0000
-#define AR_ChainSel3_S      17
-#define AR_RTSCTSRate       0x0ff00000
-#define AR_RTSCTSRate_S     20
-#define AR_TxCtlRsvd70      0xf0000000
-
-#define AR_TxRSSIAnt00      0x000000ff
-#define AR_TxRSSIAnt00_S    0
-#define AR_TxRSSIAnt01      0x0000ff00
-#define AR_TxRSSIAnt01_S    8
-#define AR_TxRSSIAnt02      0x00ff0000
-#define AR_TxRSSIAnt02_S    16
-#define AR_TxStatusRsvd00   0x3f000000
-#define AR_TxBaStatus       0x40000000
-#define AR_TxStatusRsvd01   0x80000000
-
-#define AR_FrmXmitOK            0x00000001
-#define AR_ExcessiveRetries     0x00000002
-#define AR_FIFOUnderrun         0x00000004
-#define AR_Filtered             0x00000008
-#define AR_RTSFailCnt           0x000000f0
-#define AR_RTSFailCnt_S         4
-#define AR_DataFailCnt          0x00000f00
-#define AR_DataFailCnt_S        8
-#define AR_VirtRetryCnt         0x0000f000
-#define AR_VirtRetryCnt_S       12
-#define AR_TxDelimUnderrun      0x00010000
-#define AR_TxDataUnderrun       0x00020000
-#define AR_DescCfgErr           0x00040000
-#define AR_TxTimerExpired       0x00080000
-#define AR_TxStatusRsvd10       0xfff00000
-
-#define AR_SendTimestamp    ds_txstatus2
-#define AR_BaBitmapLow      ds_txstatus3
-#define AR_BaBitmapHigh     ds_txstatus4
-
-#define AR_TxRSSIAnt10      0x000000ff
-#define AR_TxRSSIAnt10_S    0
-#define AR_TxRSSIAnt11      0x0000ff00
-#define AR_TxRSSIAnt11_S    8
-#define AR_TxRSSIAnt12      0x00ff0000
-#define AR_TxRSSIAnt12_S    16
-#define AR_TxRSSICombined   0xff000000
-#define AR_TxRSSICombined_S 24
-
-#define AR_TxEVM0           ds_txstatus5
-#define AR_TxEVM1           ds_txstatus6
-#define AR_TxEVM2           ds_txstatus7
-
-#define AR_TxDone           0x00000001
-#define AR_SeqNum           0x00001ffe
-#define AR_SeqNum_S         1
-#define AR_TxStatusRsvd80   0x0001e000
-#define AR_TxOpExceeded     0x00020000
-#define AR_TxStatusRsvd81   0x001c0000
-#define AR_FinalTxIdx       0x00600000
-#define AR_FinalTxIdx_S     21
-#define AR_TxStatusRsvd82   0x01800000
-#define AR_PowerMgmt        0x02000000
-#define AR_TxStatusRsvd83   0xfc000000
-
-#define AR_RxCTLRsvd00  0xffffffff
-
-#define AR_BufLen       0x00000fff
-#define AR_RxCtlRsvd00  0x00001000
-#define AR_RxIntrReq    0x00002000
-#define AR_RxCtlRsvd01  0xffffc000
-
-#define AR_RxRSSIAnt00      0x000000ff
-#define AR_RxRSSIAnt00_S    0
-#define AR_RxRSSIAnt01      0x0000ff00
-#define AR_RxRSSIAnt01_S    8
-#define AR_RxRSSIAnt02      0x00ff0000
-#define AR_RxRSSIAnt02_S    16
-#define AR_RxRate           0xff000000
-#define AR_RxRate_S         24
-#define AR_RxStatusRsvd00   0xff000000
-
-#define AR_DataLen          0x00000fff
-#define AR_RxMore           0x00001000
-#define AR_NumDelim         0x003fc000
-#define AR_NumDelim_S       14
-#define AR_RxStatusRsvd10   0xff800000
-
-#define AR_RcvTimestamp     ds_rxstatus2
-
-#define AR_GI               0x00000001
-#define AR_2040             0x00000002
-#define AR_Parallel40       0x00000004
-#define AR_Parallel40_S     2
-#define AR_RxStatusRsvd30   0x000000f8
-#define AR_RxAntenna       0xffffff00
-#define AR_RxAntenna_S     8
-
-#define AR_RxRSSIAnt10            0x000000ff
-#define AR_RxRSSIAnt10_S          0
-#define AR_RxRSSIAnt11            0x0000ff00
-#define AR_RxRSSIAnt11_S          8
-#define AR_RxRSSIAnt12            0x00ff0000
-#define AR_RxRSSIAnt12_S          16
-#define AR_RxRSSICombined         0xff000000
-#define AR_RxRSSICombined_S       24
-
-#define AR_RxEVM0           ds_rxstatus4
-#define AR_RxEVM1           ds_rxstatus5
-#define AR_RxEVM2           ds_rxstatus6
-
-#define AR_RxDone           0x00000001
-#define AR_RxFrameOK        0x00000002
-#define AR_CRCErr           0x00000004
-#define AR_DecryptCRCErr    0x00000008
-#define AR_PHYErr           0x00000010
-#define AR_MichaelErr       0x00000020
-#define AR_PreDelimCRCErr   0x00000040
-#define AR_RxStatusRsvd70   0x00000080
-#define AR_RxKeyIdxValid    0x00000100
-#define AR_KeyIdx           0x0000fe00
-#define AR_KeyIdx_S         9
-#define AR_PHYErrCode       0x0000ff00
-#define AR_PHYErrCode_S     8
-#define AR_RxMoreAggr       0x00010000
-#define AR_RxAggr           0x00020000
-#define AR_PostDelimCRCErr  0x00040000
-#define AR_RxStatusRsvd71   0x3ff80000
-#define AR_DecryptBusyErr   0x40000000
-#define AR_KeyMiss          0x80000000
-
-enum ath9k_tx_queue {
-       ATH9K_TX_QUEUE_INACTIVE = 0,
-       ATH9K_TX_QUEUE_DATA,
-       ATH9K_TX_QUEUE_BEACON,
-       ATH9K_TX_QUEUE_CAB,
-       ATH9K_TX_QUEUE_UAPSD,
-       ATH9K_TX_QUEUE_PSPOLL
-};
-
-#define        ATH9K_NUM_TX_QUEUES 10
-
-enum ath9k_tx_queue_subtype {
-       ATH9K_WME_AC_BK = 0,
-       ATH9K_WME_AC_BE,
-       ATH9K_WME_AC_VI,
-       ATH9K_WME_AC_VO,
-       ATH9K_WME_UPSD
-};
-
-enum ath9k_tx_queue_flags {
-       TXQ_FLAG_TXOKINT_ENABLE = 0x0001,
-       TXQ_FLAG_TXERRINT_ENABLE = 0x0001,
-       TXQ_FLAG_TXDESCINT_ENABLE = 0x0002,
-       TXQ_FLAG_TXEOLINT_ENABLE = 0x0004,
-       TXQ_FLAG_TXURNINT_ENABLE = 0x0008,
-       TXQ_FLAG_BACKOFF_DISABLE = 0x0010,
-       TXQ_FLAG_COMPRESSION_ENABLE = 0x0020,
-       TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE = 0x0040,
-       TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE = 0x0080,
-};
-
-#define ATH9K_TXQ_USEDEFAULT ((u32) -1)
-#define ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS 0x00000001
-
-#define ATH9K_DECOMP_MASK_SIZE     128
-#define ATH9K_READY_TIME_LO_BOUND  50
-#define ATH9K_READY_TIME_HI_BOUND  96
-
-enum ath9k_pkt_type {
-       ATH9K_PKT_TYPE_NORMAL = 0,
-       ATH9K_PKT_TYPE_ATIM,
-       ATH9K_PKT_TYPE_PSPOLL,
-       ATH9K_PKT_TYPE_BEACON,
-       ATH9K_PKT_TYPE_PROBE_RESP,
-       ATH9K_PKT_TYPE_CHIRP,
-       ATH9K_PKT_TYPE_GRP_POLL,
-};
-
-struct ath9k_tx_queue_info {
-       u32 tqi_ver;
-       enum ath9k_tx_queue tqi_type;
-       enum ath9k_tx_queue_subtype tqi_subtype;
-       enum ath9k_tx_queue_flags tqi_qflags;
-       u32 tqi_priority;
-       u32 tqi_aifs;
-       u32 tqi_cwmin;
-       u32 tqi_cwmax;
-       u16 tqi_shretry;
-       u16 tqi_lgretry;
-       u32 tqi_cbrPeriod;
-       u32 tqi_cbrOverflowLimit;
-       u32 tqi_burstTime;
-       u32 tqi_readyTime;
-       u32 tqi_physCompBuf;
-       u32 tqi_intFlags;
-};
-
-enum ath9k_rx_filter {
-       ATH9K_RX_FILTER_UCAST = 0x00000001,
-       ATH9K_RX_FILTER_MCAST = 0x00000002,
-       ATH9K_RX_FILTER_BCAST = 0x00000004,
-       ATH9K_RX_FILTER_CONTROL = 0x00000008,
-       ATH9K_RX_FILTER_BEACON = 0x00000010,
-       ATH9K_RX_FILTER_PROM = 0x00000020,
-       ATH9K_RX_FILTER_PROBEREQ = 0x00000080,
-       ATH9K_RX_FILTER_PHYERR = 0x00000100,
-       ATH9K_RX_FILTER_MYBEACON = 0x00000200,
-       ATH9K_RX_FILTER_PSPOLL = 0x00004000,
-       ATH9K_RX_FILTER_PHYRADAR = 0x00002000,
-       ATH9K_RX_FILTER_MCAST_BCAST_ALL = 0x00008000,
-};
-
-#define ATH9K_RATESERIES_RTS_CTS  0x0001
-#define ATH9K_RATESERIES_2040     0x0002
-#define ATH9K_RATESERIES_HALFGI   0x0004
-
-struct ath9k_11n_rate_series {
-       u32 Tries;
-       u32 Rate;
-       u32 PktDuration;
-       u32 ChSel;
-       u32 RateFlags;
-};
-
-struct ath9k_keyval {
-       u8 kv_type;
-       u8 kv_pad;
-       u16 kv_len;
-       u8 kv_val[16]; /* TK */
-       u8 kv_mic[8]; /* Michael MIC key */
-       u8 kv_txmic[8]; /* Michael MIC TX key (used only if the hardware
-                        * supports both MIC keys in the same key cache entry;
-                        * in that case, kv_mic is the RX key) */
-};
-
-enum ath9k_key_type {
-       ATH9K_KEY_TYPE_CLEAR,
-       ATH9K_KEY_TYPE_WEP,
-       ATH9K_KEY_TYPE_AES,
-       ATH9K_KEY_TYPE_TKIP,
-};
-
-enum ath9k_cipher {
-       ATH9K_CIPHER_WEP = 0,
-       ATH9K_CIPHER_AES_OCB = 1,
-       ATH9K_CIPHER_AES_CCM = 2,
-       ATH9K_CIPHER_CKIP = 3,
-       ATH9K_CIPHER_TKIP = 4,
-       ATH9K_CIPHER_CLR = 5,
-       ATH9K_CIPHER_MIC = 127
-};
-
-enum ath9k_ht_macmode {
-       ATH9K_HT_MACMODE_20 = 0,
-       ATH9K_HT_MACMODE_2040 = 1,
-};
-
-enum ath9k_ht_extprotspacing {
-       ATH9K_HT_EXTPROTSPACING_20 = 0,
-       ATH9K_HT_EXTPROTSPACING_25 = 1,
-};
-
-struct ath_hw;
-struct ath9k_channel;
-struct ath_rate_table;
-
-u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q);
-bool ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp);
-bool ath9k_hw_txstart(struct ath_hw *ah, u32 q);
-u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q);
-bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel);
-bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q);
-bool ath9k_hw_filltxdesc(struct ath_hw *ah, struct ath_desc *ds,
-                        u32 segLen, bool firstSeg,
-                        bool lastSeg, const struct ath_desc *ds0);
-void ath9k_hw_cleartxdesc(struct ath_hw *ah, struct ath_desc *ds);
-int ath9k_hw_txprocdesc(struct ath_hw *ah, struct ath_desc *ds);
-void ath9k_hw_set11n_txdesc(struct ath_hw *ah, struct ath_desc *ds,
-                           u32 pktLen, enum ath9k_pkt_type type, u32 txPower,
-                           u32 keyIx, enum ath9k_key_type keyType, u32 flags);
-void ath9k_hw_set11n_ratescenario(struct ath_hw *ah, struct ath_desc *ds,
-                                 struct ath_desc *lastds,
-                                 u32 durUpdateEn, u32 rtsctsRate,
-                                 u32 rtsctsDuration,
-                                 struct ath9k_11n_rate_series series[],
-                                 u32 nseries, u32 flags);
-void ath9k_hw_set11n_aggr_first(struct ath_hw *ah, struct ath_desc *ds,
-                               u32 aggrLen);
-void ath9k_hw_set11n_aggr_middle(struct ath_hw *ah, struct ath_desc *ds,
-                                u32 numDelims);
-void ath9k_hw_set11n_aggr_last(struct ath_hw *ah, struct ath_desc *ds);
-void ath9k_hw_clr11n_aggr(struct ath_hw *ah, struct ath_desc *ds);
-void ath9k_hw_set11n_burstduration(struct ath_hw *ah, struct ath_desc *ds,
-                                  u32 burstDuration);
-void ath9k_hw_set11n_virtualmorefrag(struct ath_hw *ah, struct ath_desc *ds,
-                                    u32 vmf);
-void ath9k_hw_gettxintrtxqs(struct ath_hw *ah, u32 *txqs);
-bool ath9k_hw_set_txq_props(struct ath_hw *ah, int q,
-                           const struct ath9k_tx_queue_info *qinfo);
-bool ath9k_hw_get_txq_props(struct ath_hw *ah, int q,
-                           struct ath9k_tx_queue_info *qinfo);
-int ath9k_hw_setuptxqueue(struct ath_hw *ah, enum ath9k_tx_queue type,
-                         const struct ath9k_tx_queue_info *qinfo);
-bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q);
-bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q);
-int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
-                       u32 pa, struct ath_desc *nds, u64 tsf);
-bool ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds,
-                         u32 size, u32 flags);
-bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set);
-void ath9k_hw_putrxbuf(struct ath_hw *ah, u32 rxdp);
-void ath9k_hw_rxena(struct ath_hw *ah);
-void ath9k_hw_startpcureceive(struct ath_hw *ah);
-void ath9k_hw_stoppcurecv(struct ath_hw *ah);
-bool ath9k_hw_stopdmarecv(struct ath_hw *ah);
-
-#endif /* MAC_H */
diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c
deleted file mode 100644 (file)
index 13d4e67..0000000
+++ /dev/null
@@ -1,2913 +0,0 @@
-/*
- * Copyright (c) 2008-2009 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/nl80211.h>
-#include "ath9k.h"
-
-#define ATH_PCI_VERSION "0.1"
-
-static char *dev_info = "ath9k";
-
-MODULE_AUTHOR("Atheros Communications");
-MODULE_DESCRIPTION("Support for Atheros 802.11n wireless LAN cards.");
-MODULE_SUPPORTED_DEVICE("Atheros 802.11n WLAN cards");
-MODULE_LICENSE("Dual BSD/GPL");
-
-static int modparam_nohwcrypt;
-module_param_named(nohwcrypt, modparam_nohwcrypt, int, 0444);
-MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption");
-
-/* We use the hw_value as an index into our private channel structure */
-
-#define CHAN2G(_freq, _idx)  { \
-       .center_freq = (_freq), \
-       .hw_value = (_idx), \
-       .max_power = 30, \
-}
-
-#define CHAN5G(_freq, _idx) { \
-       .band = IEEE80211_BAND_5GHZ, \
-       .center_freq = (_freq), \
-       .hw_value = (_idx), \
-       .max_power = 30, \
-}
-
-/* Some 2 GHz radios are actually tunable on 2312-2732
- * on 5 MHz steps, we support the channels which we know
- * we have calibration data for all cards though to make
- * this static */
-static struct ieee80211_channel ath9k_2ghz_chantable[] = {
-       CHAN2G(2412, 0), /* Channel 1 */
-       CHAN2G(2417, 1), /* Channel 2 */
-       CHAN2G(2422, 2), /* Channel 3 */
-       CHAN2G(2427, 3), /* Channel 4 */
-       CHAN2G(2432, 4), /* Channel 5 */
-       CHAN2G(2437, 5), /* Channel 6 */
-       CHAN2G(2442, 6), /* Channel 7 */
-       CHAN2G(2447, 7), /* Channel 8 */
-       CHAN2G(2452, 8), /* Channel 9 */
-       CHAN2G(2457, 9), /* Channel 10 */
-       CHAN2G(2462, 10), /* Channel 11 */
-       CHAN2G(2467, 11), /* Channel 12 */
-       CHAN2G(2472, 12), /* Channel 13 */
-       CHAN2G(2484, 13), /* Channel 14 */
-};
-
-/* Some 5 GHz radios are actually tunable on XXXX-YYYY
- * on 5 MHz steps, we support the channels which we know
- * we have calibration data for all cards though to make
- * this static */
-static struct ieee80211_channel ath9k_5ghz_chantable[] = {
-       /* _We_ call this UNII 1 */
-       CHAN5G(5180, 14), /* Channel 36 */
-       CHAN5G(5200, 15), /* Channel 40 */
-       CHAN5G(5220, 16), /* Channel 44 */
-       CHAN5G(5240, 17), /* Channel 48 */
-       /* _We_ call this UNII 2 */
-       CHAN5G(5260, 18), /* Channel 52 */
-       CHAN5G(5280, 19), /* Channel 56 */
-       CHAN5G(5300, 20), /* Channel 60 */
-       CHAN5G(5320, 21), /* Channel 64 */
-       /* _We_ call this "Middle band" */
-       CHAN5G(5500, 22), /* Channel 100 */
-       CHAN5G(5520, 23), /* Channel 104 */
-       CHAN5G(5540, 24), /* Channel 108 */
-       CHAN5G(5560, 25), /* Channel 112 */
-       CHAN5G(5580, 26), /* Channel 116 */
-       CHAN5G(5600, 27), /* Channel 120 */
-       CHAN5G(5620, 28), /* Channel 124 */
-       CHAN5G(5640, 29), /* Channel 128 */
-       CHAN5G(5660, 30), /* Channel 132 */
-       CHAN5G(5680, 31), /* Channel 136 */
-       CHAN5G(5700, 32), /* Channel 140 */
-       /* _We_ call this UNII 3 */
-       CHAN5G(5745, 33), /* Channel 149 */
-       CHAN5G(5765, 34), /* Channel 153 */
-       CHAN5G(5785, 35), /* Channel 157 */
-       CHAN5G(5805, 36), /* Channel 161 */
-       CHAN5G(5825, 37), /* Channel 165 */
-};
-
-static void ath_cache_conf_rate(struct ath_softc *sc,
-                               struct ieee80211_conf *conf)
-{
-       switch (conf->channel->band) {
-       case IEEE80211_BAND_2GHZ:
-               if (conf_is_ht20(conf))
-                       sc->cur_rate_table =
-                         sc->hw_rate_table[ATH9K_MODE_11NG_HT20];
-               else if (conf_is_ht40_minus(conf))
-                       sc->cur_rate_table =
-                         sc->hw_rate_table[ATH9K_MODE_11NG_HT40MINUS];
-               else if (conf_is_ht40_plus(conf))
-                       sc->cur_rate_table =
-                         sc->hw_rate_table[ATH9K_MODE_11NG_HT40PLUS];
-               else
-                       sc->cur_rate_table =
-                         sc->hw_rate_table[ATH9K_MODE_11G];
-               break;
-       case IEEE80211_BAND_5GHZ:
-               if (conf_is_ht20(conf))
-                       sc->cur_rate_table =
-                         sc->hw_rate_table[ATH9K_MODE_11NA_HT20];
-               else if (conf_is_ht40_minus(conf))
-                       sc->cur_rate_table =
-                         sc->hw_rate_table[ATH9K_MODE_11NA_HT40MINUS];
-               else if (conf_is_ht40_plus(conf))
-                       sc->cur_rate_table =
-                         sc->hw_rate_table[ATH9K_MODE_11NA_HT40PLUS];
-               else
-                       sc->cur_rate_table =
-                         sc->hw_rate_table[ATH9K_MODE_11A];
-               break;
-       default:
-               BUG_ON(1);
-               break;
-       }
-}
-
-static void ath_update_txpow(struct ath_softc *sc)
-{
-       struct ath_hw *ah = sc->sc_ah;
-       u32 txpow;
-
-       if (sc->curtxpow != sc->config.txpowlimit) {
-               ath9k_hw_set_txpowerlimit(ah, sc->config.txpowlimit);
-               /* read back in case value is clamped */
-               ath9k_hw_getcapability(ah, ATH9K_CAP_TXPOW, 1, &txpow);
-               sc->curtxpow = txpow;
-       }
-}
-
-static u8 parse_mpdudensity(u8 mpdudensity)
-{
-       /*
-        * 802.11n D2.0 defined values for "Minimum MPDU Start Spacing":
-        *   0 for no restriction
-        *   1 for 1/4 us
-        *   2 for 1/2 us
-        *   3 for 1 us
-        *   4 for 2 us
-        *   5 for 4 us
-        *   6 for 8 us
-        *   7 for 16 us
-        */
-       switch (mpdudensity) {
-       case 0:
-               return 0;
-       case 1:
-       case 2:
-       case 3:
-               /* Our lower layer calculations limit our precision to
-                  1 microsecond */
-               return 1;
-       case 4:
-               return 2;
-       case 5:
-               return 4;
-       case 6:
-               return 8;
-       case 7:
-               return 16;
-       default:
-               return 0;
-       }
-}
-
-static void ath_setup_rates(struct ath_softc *sc, enum ieee80211_band band)
-{
-       struct ath_rate_table *rate_table = NULL;
-       struct ieee80211_supported_band *sband;
-       struct ieee80211_rate *rate;
-       int i, maxrates;
-
-       switch (band) {
-       case IEEE80211_BAND_2GHZ:
-               rate_table = sc->hw_rate_table[ATH9K_MODE_11G];
-               break;
-       case IEEE80211_BAND_5GHZ:
-               rate_table = sc->hw_rate_table[ATH9K_MODE_11A];
-               break;
-       default:
-               break;
-       }
-
-       if (rate_table == NULL)
-               return;
-
-       sband = &sc->sbands[band];
-       rate = sc->rates[band];
-
-       if (rate_table->rate_cnt > ATH_RATE_MAX)
-               maxrates = ATH_RATE_MAX;
-       else
-               maxrates = rate_table->rate_cnt;
-
-       for (i = 0; i < maxrates; i++) {
-               rate[i].bitrate = rate_table->info[i].ratekbps / 100;
-               rate[i].hw_value = rate_table->info[i].ratecode;
-               if (rate_table->info[i].short_preamble) {
-                       rate[i].hw_value_short = rate_table->info[i].ratecode |
-                               rate_table->info[i].short_preamble;
-                       rate[i].flags = IEEE80211_RATE_SHORT_PREAMBLE;
-               }
-               sband->n_bitrates++;
-
-               DPRINTF(sc, ATH_DBG_CONFIG, "Rate: %2dMbps, ratecode: %2d\n",
-                       rate[i].bitrate / 10, rate[i].hw_value);
-       }
-}
-
-/*
- * Set/change channels.  If the channel is really being changed, it's done
- * by reseting the chip.  To accomplish this we must first cleanup any pending
- * DMA, then restart stuff.
-*/
-int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
-                   struct ath9k_channel *hchan)
-{
-       struct ath_hw *ah = sc->sc_ah;
-       bool fastcc = true, stopped;
-       struct ieee80211_channel *channel = hw->conf.channel;
-       int r;
-
-       if (sc->sc_flags & SC_OP_INVALID)
-               return -EIO;
-
-       ath9k_ps_wakeup(sc);
-
-       /*
-        * This is only performed if the channel settings have
-        * actually changed.
-        *
-        * To switch channels clear any pending DMA operations;
-        * wait long enough for the RX fifo to drain, reset the
-        * hardware at the new frequency, and then re-enable
-        * the relevant bits of the h/w.
-        */
-       ath9k_hw_set_interrupts(ah, 0);
-       ath_drain_all_txq(sc, false);
-       stopped = ath_stoprecv(sc);
-
-       /* XXX: do not flush receive queue here. We don't want
-        * to flush data frames already in queue because of
-        * changing channel. */
-
-       if (!stopped || (sc->sc_flags & SC_OP_FULL_RESET))
-               fastcc = false;
-
-       DPRINTF(sc, ATH_DBG_CONFIG,
-               "(%u MHz) -> (%u MHz), chanwidth: %d\n",
-               sc->sc_ah->curchan->channel,
-               channel->center_freq, sc->tx_chan_width);
-
-       spin_lock_bh(&sc->sc_resetlock);
-
-       r = ath9k_hw_reset(ah, hchan, fastcc);
-       if (r) {
-               DPRINTF(sc, ATH_DBG_FATAL,
-                       "Unable to reset channel (%u Mhz) "
-                       "reset status %u\n",
-                       channel->center_freq, r);
-               spin_unlock_bh(&sc->sc_resetlock);
-               return r;
-       }
-       spin_unlock_bh(&sc->sc_resetlock);
-
-       sc->sc_flags &= ~SC_OP_CHAINMASK_UPDATE;
-       sc->sc_flags &= ~SC_OP_FULL_RESET;
-
-       if (ath_startrecv(sc) != 0) {
-               DPRINTF(sc, ATH_DBG_FATAL,
-                       "Unable to restart recv logic\n");
-               return -EIO;
-       }
-
-       ath_cache_conf_rate(sc, &hw->conf);
-       ath_update_txpow(sc);
-       ath9k_hw_set_interrupts(ah, sc->imask);
-       ath9k_ps_restore(sc);
-       return 0;
-}
-
-/*
- *  This routine performs the periodic noise floor calibration function
- *  that is used to adjust and optimize the chip performance.  This
- *  takes environmental changes (location, temperature) into account.
- *  When the task is complete, it reschedules itself depending on the
- *  appropriate interval that was calculated.
- */
-static void ath_ani_calibrate(unsigned long data)
-{
-       struct ath_softc *sc = (struct ath_softc *)data;
-       struct ath_hw *ah = sc->sc_ah;
-       bool longcal = false;
-       bool shortcal = false;
-       bool aniflag = false;
-       unsigned int timestamp = jiffies_to_msecs(jiffies);
-       u32 cal_interval, short_cal_interval;
-
-       short_cal_interval = (ah->opmode == NL80211_IFTYPE_AP) ?
-               ATH_AP_SHORT_CALINTERVAL : ATH_STA_SHORT_CALINTERVAL;
-
-       /*
-       * don't calibrate when we're scanning.
-       * we are most likely not on our home channel.
-       */
-       if (sc->sc_flags & SC_OP_SCANNING)
-               goto set_timer;
-
-       /* Long calibration runs independently of short calibration. */
-       if ((timestamp - sc->ani.longcal_timer) >= ATH_LONG_CALINTERVAL) {
-               longcal = true;
-               DPRINTF(sc, ATH_DBG_ANI, "longcal @%lu\n", jiffies);
-               sc->ani.longcal_timer = timestamp;
-       }
-
-       /* Short calibration applies only while caldone is false */
-       if (!sc->ani.caldone) {
-               if ((timestamp - sc->ani.shortcal_timer) >= short_cal_interval) {
-                       shortcal = true;
-                       DPRINTF(sc, ATH_DBG_ANI, "shortcal @%lu\n", jiffies);
-                       sc->ani.shortcal_timer = timestamp;
-                       sc->ani.resetcal_timer = timestamp;
-               }
-       } else {
-               if ((timestamp - sc->ani.resetcal_timer) >=
-                   ATH_RESTART_CALINTERVAL) {
-                       sc->ani.caldone = ath9k_hw_reset_calvalid(ah);
-                       if (sc->ani.caldone)
-                               sc->ani.resetcal_timer = timestamp;
-               }
-       }
-
-       /* Verify whether we must check ANI */
-       if ((timestamp - sc->ani.checkani_timer) >= ATH_ANI_POLLINTERVAL) {
-               aniflag = true;
-               sc->ani.checkani_timer = timestamp;
-       }
-
-       /* Skip all processing if there's nothing to do. */
-       if (longcal || shortcal || aniflag) {
-               /* Call ANI routine if necessary */
-               if (aniflag)
-                       ath9k_hw_ani_monitor(ah, &sc->nodestats, ah->curchan);
-
-               /* Perform calibration if necessary */
-               if (longcal || shortcal) {
-                       bool iscaldone = false;
-
-                       if (ath9k_hw_calibrate(ah, ah->curchan,
-                                              sc->rx_chainmask, longcal,
-                                              &iscaldone)) {
-                               if (longcal)
-                                       sc->ani.noise_floor =
-                                               ath9k_hw_getchan_noise(ah,
-                                                              ah->curchan);
-
-                               DPRINTF(sc, ATH_DBG_ANI,
-                                       "calibrate chan %u/%x nf: %d\n",
-                                       ah->curchan->channel,
-                                       ah->curchan->channelFlags,
-                                       sc->ani.noise_floor);
-                       } else {
-                               DPRINTF(sc, ATH_DBG_ANY,
-                                       "calibrate chan %u/%x failed\n",
-                                       ah->curchan->channel,
-                                       ah->curchan->channelFlags);
-                       }
-                       sc->ani.caldone = iscaldone;
-               }
-       }
-
-set_timer:
-       /*
-       * Set timer interval based on previous results.
-       * The interval must be the shortest necessary to satisfy ANI,
-       * short calibration and long calibration.
-       */
-       cal_interval = ATH_LONG_CALINTERVAL;
-       if (sc->sc_ah->config.enable_ani)
-               cal_interval = min(cal_interval, (u32)ATH_ANI_POLLINTERVAL);
-       if (!sc->ani.caldone)
-               cal_interval = min(cal_interval, (u32)short_cal_interval);
-
-       mod_timer(&sc->ani.timer, jiffies + msecs_to_jiffies(cal_interval));
-}
-
-/*
- * Update tx/rx chainmask. For legacy association,
- * hard code chainmask to 1x1, for 11n association, use
- * the chainmask configuration, for bt coexistence, use
- * the chainmask configuration even in legacy mode.
- */
-void ath_update_chainmask(struct ath_softc *sc, int is_ht)
-{
-       sc->sc_flags |= SC_OP_CHAINMASK_UPDATE;
-       if (is_ht ||
-           (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_BT_COEX)) {
-               sc->tx_chainmask = sc->sc_ah->caps.tx_chainmask;
-               sc->rx_chainmask = sc->sc_ah->caps.rx_chainmask;
-       } else {
-               sc->tx_chainmask = 1;
-               sc->rx_chainmask = 1;
-       }
-
-       DPRINTF(sc, ATH_DBG_CONFIG, "tx chmask: %d, rx chmask: %d\n",
-               sc->tx_chainmask, sc->rx_chainmask);
-}
-
-static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta)
-{
-       struct ath_node *an;
-
-       an = (struct ath_node *)sta->drv_priv;
-
-       if (sc->sc_flags & SC_OP_TXAGGR)
-               ath_tx_node_init(sc, an);
-
-       an->maxampdu = 1 << (IEEE80211_HTCAP_MAXRXAMPDU_FACTOR +
-                            sta->ht_cap.ampdu_factor);
-       an->mpdudensity = parse_mpdudensity(sta->ht_cap.ampdu_density);
-}
-
-static void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta)
-{
-       struct ath_node *an = (struct ath_node *)sta->drv_priv;
-
-       if (sc->sc_flags & SC_OP_TXAGGR)
-               ath_tx_node_cleanup(sc, an);
-}
-
-static void ath9k_tasklet(unsigned long data)
-{
-       struct ath_softc *sc = (struct ath_softc *)data;
-       u32 status = sc->intrstatus;
-
-       if (status & ATH9K_INT_FATAL) {
-               /* need a chip reset */
-               ath_reset(sc, false);
-               return;
-       } else {
-
-               if (status &
-                   (ATH9K_INT_RX | ATH9K_INT_RXEOL | ATH9K_INT_RXORN)) {
-                       spin_lock_bh(&sc->rx.rxflushlock);
-                       ath_rx_tasklet(sc, 0);
-                       spin_unlock_bh(&sc->rx.rxflushlock);
-               }
-               /* XXX: optimize this */
-               if (status & ATH9K_INT_TX)
-                       ath_tx_tasklet(sc);
-       }
-
-       /* re-enable hardware interrupt */
-       ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
-}
-
-irqreturn_t ath_isr(int irq, void *dev)
-{
-       struct ath_softc *sc = dev;
-       struct ath_hw *ah = sc->sc_ah;
-       enum ath9k_int status;
-       bool sched = false;
-
-       do {
-               if (sc->sc_flags & SC_OP_INVALID) {
-                       /*
-                        * The hardware is not ready/present, don't
-                        * touch anything. Note this can happen early
-                        * on if the IRQ is shared.
-                        */
-                       return IRQ_NONE;
-               }
-               if (!ath9k_hw_intrpend(ah)) {   /* shared irq, not for us */
-                       return IRQ_NONE;
-               }
-
-               /*
-                * Figure out the reason(s) for the interrupt.  Note
-                * that the hal returns a pseudo-ISR that may include
-                * bits we haven't explicitly enabled so we mask the
-                * value to insure we only process bits we requested.
-                */
-               ath9k_hw_getisr(ah, &status);   /* NB: clears ISR too */
-
-               status &= sc->imask;    /* discard unasked-for bits */
-
-               /*
-                * If there are no status bits set, then this interrupt was not
-                * for me (should have been caught above).
-                */
-               if (!status)
-                       return IRQ_NONE;
-
-               sc->intrstatus = status;
-               ath9k_ps_wakeup(sc);
-
-               if (status & ATH9K_INT_FATAL) {
-                       /* need a chip reset */
-                       sched = true;
-               } else if (status & ATH9K_INT_RXORN) {
-                       /* need a chip reset */
-                       sched = true;
-               } else {
-                       if (status & ATH9K_INT_SWBA) {
-                               /* schedule a tasklet for beacon handling */
-                               tasklet_schedule(&sc->bcon_tasklet);
-                       }
-                       if (status & ATH9K_INT_RXEOL) {
-                               /*
-                                * NB: the hardware should re-read the link when
-                                *     RXE bit is written, but it doesn't work
-                                *     at least on older hardware revs.
-                                */
-                               sched = true;
-                       }
-
-                       if (status & ATH9K_INT_TXURN)
-                               /* bump tx trigger level */
-                               ath9k_hw_updatetxtriglevel(ah, true);
-                       /* XXX: optimize this */
-                       if (status & ATH9K_INT_RX)
-                               sched = true;
-                       if (status & ATH9K_INT_TX)
-                               sched = true;
-                       if (status & ATH9K_INT_BMISS)
-                               sched = true;
-                       /* carrier sense timeout */
-                       if (status & ATH9K_INT_CST)
-                               sched = true;
-                       if (status & ATH9K_INT_MIB) {
-                               /*
-                                * Disable interrupts until we service the MIB
-                                * interrupt; otherwise it will continue to
-                                * fire.
-                                */
-                               ath9k_hw_set_interrupts(ah, 0);
-                               /*
-                                * Let the hal handle the event. We assume
-                                * it will clear whatever condition caused
-                                * the interrupt.
-                                */
-                               ath9k_hw_procmibevent(ah, &sc->nodestats);
-                               ath9k_hw_set_interrupts(ah, sc->imask);
-                       }
-                       if (status & ATH9K_INT_TIM_TIMER) {
-                               if (!(ah->caps.hw_caps &
-                                     ATH9K_HW_CAP_AUTOSLEEP)) {
-                                       /* Clear RxAbort bit so that we can
-                                        * receive frames */
-                                       ath9k_hw_setpower(ah, ATH9K_PM_AWAKE);
-                                       ath9k_hw_setrxabort(ah, 0);
-                                       sched = true;
-                                       sc->sc_flags |= SC_OP_WAIT_FOR_BEACON;
-                               }
-                       }
-                       if (status & ATH9K_INT_TSFOOR) {
-                               /* FIXME: Handle this interrupt for power save */
-                               sched = true;
-                       }
-               }
-               ath9k_ps_restore(sc);
-       } while (0);
-
-       ath_debug_stat_interrupt(sc, status);
-
-       if (sched) {
-               /* turn off every interrupt except SWBA */
-               ath9k_hw_set_interrupts(ah, (sc->imask & ATH9K_INT_SWBA));
-               tasklet_schedule(&sc->intr_tq);
-       }
-
-       return IRQ_HANDLED;
-}
-
-static u32 ath_get_extchanmode(struct ath_softc *sc,
-                              struct ieee80211_channel *chan,
-                              enum nl80211_channel_type channel_type)
-{
-       u32 chanmode = 0;
-
-       switch (chan->band) {
-       case IEEE80211_BAND_2GHZ:
-               switch(channel_type) {
-               case NL80211_CHAN_NO_HT:
-               case NL80211_CHAN_HT20:
-                       chanmode = CHANNEL_G_HT20;
-                       break;
-               case NL80211_CHAN_HT40PLUS:
-                       chanmode = CHANNEL_G_HT40PLUS;
-                       break;
-               case NL80211_CHAN_HT40MINUS:
-                       chanmode = CHANNEL_G_HT40MINUS;
-                       break;
-               }
-               break;
-       case IEEE80211_BAND_5GHZ:
-               switch(channel_type) {
-               case NL80211_CHAN_NO_HT:
-               case NL80211_CHAN_HT20:
-                       chanmode = CHANNEL_A_HT20;
-                       break;
-               case NL80211_CHAN_HT40PLUS:
-                       chanmode = CHANNEL_A_HT40PLUS;
-                       break;
-               case NL80211_CHAN_HT40MINUS:
-                       chanmode = CHANNEL_A_HT40MINUS;
-                       break;
-               }
-               break;
-       default:
-               break;
-       }
-
-       return chanmode;
-}
-
-static int ath_setkey_tkip(struct ath_softc *sc, u16 keyix, const u8 *key,
-                          struct ath9k_keyval *hk, const u8 *addr,
-                          bool authenticator)
-{
-       const u8 *key_rxmic;
-       const u8 *key_txmic;
-
-       key_txmic = key + NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY;
-       key_rxmic = key + NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY;
-
-       if (addr == NULL) {
-               /*
-                * Group key installation - only two key cache entries are used
-                * regardless of splitmic capability since group key is only
-                * used either for TX or RX.
-                */
-               if (authenticator) {
-                       memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic));
-                       memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_mic));
-               } else {
-                       memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
-                       memcpy(hk->kv_txmic, key_rxmic, sizeof(hk->kv_mic));
-               }
-               return ath9k_hw_set_keycache_entry(sc->sc_ah, keyix, hk, addr);
-       }
-       if (!sc->splitmic) {
-               /* TX and RX keys share the same key cache entry. */
-               memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
-               memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_txmic));
-               return ath9k_hw_set_keycache_entry(sc->sc_ah, keyix, hk, addr);
-       }
-
-       /* Separate key cache entries for TX and RX */
-
-       /* TX key goes at first index, RX key at +32. */
-       memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic));
-       if (!ath9k_hw_set_keycache_entry(sc->sc_ah, keyix, hk, NULL)) {
-               /* TX MIC entry failed. No need to proceed further */
-               DPRINTF(sc, ATH_DBG_KEYCACHE,
-                       "Setting TX MIC Key Failed\n");
-               return 0;
-       }
-
-       memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
-       /* XXX delete tx key on failure? */
-       return ath9k_hw_set_keycache_entry(sc->sc_ah, keyix + 32, hk, addr);
-}
-
-static int ath_reserve_key_cache_slot_tkip(struct ath_softc *sc)
-{
-       int i;
-
-       for (i = IEEE80211_WEP_NKID; i < sc->keymax / 2; i++) {
-               if (test_bit(i, sc->keymap) ||
-                   test_bit(i + 64, sc->keymap))
-                       continue; /* At least one part of TKIP key allocated */
-               if (sc->splitmic &&
-                   (test_bit(i + 32, sc->keymap) ||
-                    test_bit(i + 64 + 32, sc->keymap)))
-                       continue; /* At least one part of TKIP key allocated */
-
-               /* Found a free slot for a TKIP key */
-               return i;
-       }
-       return -1;
-}
-
-static int ath_reserve_key_cache_slot(struct ath_softc *sc)
-{
-       int i;
-
-       /* First, try to find slots that would not be available for TKIP. */
-       if (sc->splitmic) {
-               for (i = IEEE80211_WEP_NKID; i < sc->keymax / 4; i++) {
-                       if (!test_bit(i, sc->keymap) &&
-                           (test_bit(i + 32, sc->keymap) ||
-                            test_bit(i + 64, sc->keymap) ||
-                            test_bit(i + 64 + 32, sc->keymap)))
-                               return i;
-                       if (!test_bit(i + 32, sc->keymap) &&
-                           (test_bit(i, sc->keymap) ||
-                            test_bit(i + 64, sc->keymap) ||
-                            test_bit(i + 64 + 32, sc->keymap)))
-                               return i + 32;
-                       if (!test_bit(i + 64, sc->keymap) &&
-                           (test_bit(i , sc->keymap) ||
-                            test_bit(i + 32, sc->keymap) ||
-                            test_bit(i + 64 + 32, sc->keymap)))
-                               return i + 64;
-                       if (!test_bit(i + 64 + 32, sc->keymap) &&
-                           (test_bit(i, sc->keymap) ||
-                            test_bit(i + 32, sc->keymap) ||
-                            test_bit(i + 64, sc->keymap)))
-                               return i + 64 + 32;
-               }
-       } else {
-               for (i = IEEE80211_WEP_NKID; i < sc->keymax / 2; i++) {
-                       if (!test_bit(i, sc->keymap) &&
-                           test_bit(i + 64, sc->keymap))
-                               return i;
-                       if (test_bit(i, sc->keymap) &&
-                           !test_bit(i + 64, sc->keymap))
-                               return i + 64;
-               }
-       }
-
-       /* No partially used TKIP slots, pick any available slot */
-       for (i = IEEE80211_WEP_NKID; i < sc->keymax; i++) {
-               /* Do not allow slots that could be needed for TKIP group keys
-                * to be used. This limitation could be removed if we know that
-                * TKIP will not be used. */
-               if (i >= 64 && i < 64 + IEEE80211_WEP_NKID)
-                       continue;
-               if (sc->splitmic) {
-                       if (i >= 32 && i < 32 + IEEE80211_WEP_NKID)
-                               continue;
-                       if (i >= 64 + 32 && i < 64 + 32 + IEEE80211_WEP_NKID)
-                               continue;
-               }
-
-               if (!test_bit(i, sc->keymap))
-                       return i; /* Found a free slot for a key */
-       }
-
-       /* No free slot found */
-       return -1;
-}
-
-static int ath_key_config(struct ath_softc *sc,
-                         struct ieee80211_vif *vif,
-                         struct ieee80211_sta *sta,
-                         struct ieee80211_key_conf *key)
-{
-       struct ath9k_keyval hk;
-       const u8 *mac = NULL;
-       int ret = 0;
-       int idx;
-
-       memset(&hk, 0, sizeof(hk));
-
-       switch (key->alg) {
-       case ALG_WEP:
-               hk.kv_type = ATH9K_CIPHER_WEP;
-               break;
-       case ALG_TKIP:
-               hk.kv_type = ATH9K_CIPHER_TKIP;
-               break;
-       case ALG_CCMP:
-               hk.kv_type = ATH9K_CIPHER_AES_CCM;
-               break;
-       default:
-               return -EOPNOTSUPP;
-       }
-
-       hk.kv_len = key->keylen;
-       memcpy(hk.kv_val, key->key, key->keylen);
-
-       if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) {
-               /* For now, use the default keys for broadcast keys. This may
-                * need to change with virtual interfaces. */
-               idx = key->keyidx;
-       } else if (key->keyidx) {
-               if (WARN_ON(!sta))
-                       return -EOPNOTSUPP;
-               mac = sta->addr;
-
-               if (vif->type != NL80211_IFTYPE_AP) {
-                       /* Only keyidx 0 should be used with unicast key, but
-                        * allow this for client mode for now. */
-                       idx = key->keyidx;
-               } else
-                       return -EIO;
-       } else {
-               if (WARN_ON(!sta))
-                       return -EOPNOTSUPP;
-               mac = sta->addr;
-
-               if (key->alg == ALG_TKIP)
-                       idx = ath_reserve_key_cache_slot_tkip(sc);
-               else
-                       idx = ath_reserve_key_cache_slot(sc);
-               if (idx < 0)
-                       return -ENOSPC; /* no free key cache entries */
-       }
-
-       if (key->alg == ALG_TKIP)
-               ret = ath_setkey_tkip(sc, idx, key->key, &hk, mac,
-                                     vif->type == NL80211_IFTYPE_AP);
-       else
-               ret = ath9k_hw_set_keycache_entry(sc->sc_ah, idx, &hk, mac);
-
-       if (!ret)
-               return -EIO;
-
-       set_bit(idx, sc->keymap);
-       if (key->alg == ALG_TKIP) {
-               set_bit(idx + 64, sc->keymap);
-               if (sc->splitmic) {
-                       set_bit(idx + 32, sc->keymap);
-                       set_bit(idx + 64 + 32, sc->keymap);
-               }
-       }
-
-       return idx;
-}
-
-static void ath_key_delete(struct ath_softc *sc, struct ieee80211_key_conf *key)
-{
-       ath9k_hw_keyreset(sc->sc_ah, key->hw_key_idx);
-       if (key->hw_key_idx < IEEE80211_WEP_NKID)
-               return;
-
-       clear_bit(key->hw_key_idx, sc->keymap);
-       if (key->alg != ALG_TKIP)
-               return;
-
-       clear_bit(key->hw_key_idx + 64, sc->keymap);
-       if (sc->splitmic) {
-               clear_bit(key->hw_key_idx + 32, sc->keymap);
-               clear_bit(key->hw_key_idx + 64 + 32, sc->keymap);
-       }
-}
-
-static void setup_ht_cap(struct ath_softc *sc,
-                        struct ieee80211_sta_ht_cap *ht_info)
-{
-#define        ATH9K_HT_CAP_MAXRXAMPDU_65536 0x3       /* 2 ^ 16 */
-#define        ATH9K_HT_CAP_MPDUDENSITY_8 0x6          /* 8 usec */
-
-       ht_info->ht_supported = true;
-       ht_info->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
-                      IEEE80211_HT_CAP_SM_PS |
-                      IEEE80211_HT_CAP_SGI_40 |
-                      IEEE80211_HT_CAP_DSSSCCK40;
-
-       ht_info->ampdu_factor = ATH9K_HT_CAP_MAXRXAMPDU_65536;
-       ht_info->ampdu_density = ATH9K_HT_CAP_MPDUDENSITY_8;
-
-       /* set up supported mcs set */
-       memset(&ht_info->mcs, 0, sizeof(ht_info->mcs));
-
-       switch(sc->rx_chainmask) {
-       case 1:
-               ht_info->mcs.rx_mask[0] = 0xff;
-               break;
-       case 3:
-       case 5:
-       case 7:
-       default:
-               ht_info->mcs.rx_mask[0] = 0xff;
-               ht_info->mcs.rx_mask[1] = 0xff;
-               break;
-       }
-
-       ht_info->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
-}
-
-static void ath9k_bss_assoc_info(struct ath_softc *sc,
-                                struct ieee80211_vif *vif,
-                                struct ieee80211_bss_conf *bss_conf)
-{
-       struct ath_vif *avp = (void *)vif->drv_priv;
-
-       if (bss_conf->assoc) {
-               DPRINTF(sc, ATH_DBG_CONFIG, "Bss Info ASSOC %d, bssid: %pM\n",
-                       bss_conf->aid, sc->curbssid);
-
-               /* New association, store aid */
-               if (avp->av_opmode == NL80211_IFTYPE_STATION) {
-                       sc->curaid = bss_conf->aid;
-                       ath9k_hw_write_associd(sc);
-               }
-
-               /* Configure the beacon */
-               ath_beacon_config(sc, vif);
-
-               /* Reset rssi stats */
-               sc->nodestats.ns_avgbrssi = ATH_RSSI_DUMMY_MARKER;
-               sc->nodestats.ns_avgrssi = ATH_RSSI_DUMMY_MARKER;
-               sc->nodestats.ns_avgtxrssi = ATH_RSSI_DUMMY_MARKER;
-               sc->nodestats.ns_avgtxrate = ATH_RATE_DUMMY_MARKER;
-
-               /* Start ANI */
-               mod_timer(&sc->ani.timer,
-                         jiffies + msecs_to_jiffies(ATH_ANI_POLLINTERVAL));
-       } else {
-               DPRINTF(sc, ATH_DBG_CONFIG, "Bss Info DISSOC\n");
-               sc->curaid = 0;
-       }
-}
-
-/********************************/
-/*      LED functions          */
-/********************************/
-
-static void ath_led_blink_work(struct work_struct *work)
-{
-       struct ath_softc *sc = container_of(work, struct ath_softc,
-                                           ath_led_blink_work.work);
-
-       if (!(sc->sc_flags & SC_OP_LED_ASSOCIATED))
-               return;
-
-       if ((sc->led_on_duration == ATH_LED_ON_DURATION_IDLE) ||
-           (sc->led_off_duration == ATH_LED_OFF_DURATION_IDLE))
-               ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 0);
-       else
-               ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN,
-                                 (sc->sc_flags & SC_OP_LED_ON) ? 1 : 0);
-
-       queue_delayed_work(sc->hw->workqueue, &sc->ath_led_blink_work,
-                          (sc->sc_flags & SC_OP_LED_ON) ?
-                          msecs_to_jiffies(sc->led_off_duration) :
-                          msecs_to_jiffies(sc->led_on_duration));
-
-       sc->led_on_duration = sc->led_on_cnt ?
-                       max((ATH_LED_ON_DURATION_IDLE - sc->led_on_cnt), 25) :
-                       ATH_LED_ON_DURATION_IDLE;
-       sc->led_off_duration = sc->led_off_cnt ?
-                       max((ATH_LED_OFF_DURATION_IDLE - sc->led_off_cnt), 10) :
-                       ATH_LED_OFF_DURATION_IDLE;
-       sc->led_on_cnt = sc->led_off_cnt = 0;
-       if (sc->sc_flags & SC_OP_LED_ON)
-               sc->sc_flags &= ~SC_OP_LED_ON;
-       else
-               sc->sc_flags |= SC_OP_LED_ON;
-}
-
-static void ath_led_brightness(struct led_classdev *led_cdev,
-                              enum led_brightness brightness)
-{
-       struct ath_led *led = container_of(led_cdev, struct ath_led, led_cdev);
-       struct ath_softc *sc = led->sc;
-
-       switch (brightness) {
-       case LED_OFF:
-               if (led->led_type == ATH_LED_ASSOC ||
-                   led->led_type == ATH_LED_RADIO) {
-                       ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN,
-                               (led->led_type == ATH_LED_RADIO));
-                       sc->sc_flags &= ~SC_OP_LED_ASSOCIATED;
-                       if (led->led_type == ATH_LED_RADIO)
-                               sc->sc_flags &= ~SC_OP_LED_ON;
-               } else {
-                       sc->led_off_cnt++;
-               }
-               break;
-       case LED_FULL:
-               if (led->led_type == ATH_LED_ASSOC) {
-                       sc->sc_flags |= SC_OP_LED_ASSOCIATED;
-                       queue_delayed_work(sc->hw->workqueue,
-                                          &sc->ath_led_blink_work, 0);
-               } else if (led->led_type == ATH_LED_RADIO) {
-                       ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 0);
-                       sc->sc_flags |= SC_OP_LED_ON;
-               } else {
-                       sc->led_on_cnt++;
-               }
-               break;
-       default:
-               break;
-       }
-}
-
-static int ath_register_led(struct ath_softc *sc, struct ath_led *led,
-                           char *trigger)
-{
-       int ret;
-
-       led->sc = sc;
-       led->led_cdev.name = led->name;
-       led->led_cdev.default_trigger = trigger;
-       led->led_cdev.brightness_set = ath_led_brightness;
-
-       ret = led_classdev_register(wiphy_dev(sc->hw->wiphy), &led->led_cdev);
-       if (ret)
-               DPRINTF(sc, ATH_DBG_FATAL,
-                       "Failed to register led:%s", led->name);
-       else
-               led->registered = 1;
-       return ret;
-}
-
-static void ath_unregister_led(struct ath_led *led)
-{
-       if (led->registered) {
-               led_classdev_unregister(&led->led_cdev);
-               led->registered = 0;
-       }
-}
-
-static void ath_deinit_leds(struct ath_softc *sc)
-{
-       cancel_delayed_work_sync(&sc->ath_led_blink_work);
-       ath_unregister_led(&sc->assoc_led);
-       sc->sc_flags &= ~SC_OP_LED_ASSOCIATED;
-       ath_unregister_led(&sc->tx_led);
-       ath_unregister_led(&sc->rx_led);
-       ath_unregister_led(&sc->radio_led);
-       ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1);
-}
-
-static void ath_init_leds(struct ath_softc *sc)
-{
-       char *trigger;
-       int ret;
-
-       /* Configure gpio 1 for output */
-       ath9k_hw_cfg_output(sc->sc_ah, ATH_LED_PIN,
-                           AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
-       /* LED off, active low */
-       ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1);
-
-       INIT_DELAYED_WORK(&sc->ath_led_blink_work, ath_led_blink_work);
-
-       trigger = ieee80211_get_radio_led_name(sc->hw);
-       snprintf(sc->radio_led.name, sizeof(sc->radio_led.name),
-               "ath9k-%s::radio", wiphy_name(sc->hw->wiphy));
-       ret = ath_register_led(sc, &sc->radio_led, trigger);
-       sc->radio_led.led_type = ATH_LED_RADIO;
-       if (ret)
-               goto fail;
-
-       trigger = ieee80211_get_assoc_led_name(sc->hw);
-       snprintf(sc->assoc_led.name, sizeof(sc->assoc_led.name),
-               "ath9k-%s::assoc", wiphy_name(sc->hw->wiphy));
-       ret = ath_register_led(sc, &sc->assoc_led, trigger);
-       sc->assoc_led.led_type = ATH_LED_ASSOC;
-       if (ret)
-               goto fail;
-
-       trigger = ieee80211_get_tx_led_name(sc->hw);
-       snprintf(sc->tx_led.name, sizeof(sc->tx_led.name),
-               "ath9k-%s::tx", wiphy_name(sc->hw->wiphy));
-       ret = ath_register_led(sc, &sc->tx_led, trigger);
-       sc->tx_led.led_type = ATH_LED_TX;
-       if (ret)
-               goto fail;
-
-       trigger = ieee80211_get_rx_led_name(sc->hw);
-       snprintf(sc->rx_led.name, sizeof(sc->rx_led.name),
-               "ath9k-%s::rx", wiphy_name(sc->hw->wiphy));
-       ret = ath_register_led(sc, &sc->rx_led, trigger);
-       sc->rx_led.led_type = ATH_LED_RX;
-       if (ret)
-               goto fail;
-
-       return;
-
-fail:
-       ath_deinit_leds(sc);
-}
-
-void ath_radio_enable(struct ath_softc *sc)
-{
-       struct ath_hw *ah = sc->sc_ah;
-       struct ieee80211_channel *channel = sc->hw->conf.channel;
-       int r;
-
-       ath9k_ps_wakeup(sc);
-       spin_lock_bh(&sc->sc_resetlock);
-
-       r = ath9k_hw_reset(ah, ah->curchan, false);
-
-       if (r) {
-               DPRINTF(sc, ATH_DBG_FATAL,
-                       "Unable to reset channel %u (%uMhz) ",
-                       "reset status %u\n",
-                       channel->center_freq, r);
-       }
-       spin_unlock_bh(&sc->sc_resetlock);
-
-       ath_update_txpow(sc);
-       if (ath_startrecv(sc) != 0) {
-               DPRINTF(sc, ATH_DBG_FATAL,
-                       "Unable to restart recv logic\n");
-               return;
-       }
-
-       if (sc->sc_flags & SC_OP_BEACONS)
-               ath_beacon_config(sc, NULL);    /* restart beacons */
-
-       /* Re-Enable  interrupts */
-       ath9k_hw_set_interrupts(ah, sc->imask);
-
-       /* Enable LED */
-       ath9k_hw_cfg_output(ah, ATH_LED_PIN,
-                           AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
-       ath9k_hw_set_gpio(ah, ATH_LED_PIN, 0);
-
-       ieee80211_wake_queues(sc->hw);
-       ath9k_ps_restore(sc);
-}
-
-void ath_radio_disable(struct ath_softc *sc)
-{
-       struct ath_hw *ah = sc->sc_ah;
-       struct ieee80211_channel *channel = sc->hw->conf.channel;
-       int r;
-
-       ath9k_ps_wakeup(sc);
-       ieee80211_stop_queues(sc->hw);
-
-       /* Disable LED */
-       ath9k_hw_set_gpio(ah, ATH_LED_PIN, 1);
-       ath9k_hw_cfg_gpio_input(ah, ATH_LED_PIN);
-
-       /* Disable interrupts */
-       ath9k_hw_set_interrupts(ah, 0);
-
-       ath_drain_all_txq(sc, false);   /* clear pending tx frames */
-       ath_stoprecv(sc);               /* turn off frame recv */
-       ath_flushrecv(sc);              /* flush recv queue */
-
-       spin_lock_bh(&sc->sc_resetlock);
-       r = ath9k_hw_reset(ah, ah->curchan, false);
-       if (r) {
-               DPRINTF(sc, ATH_DBG_FATAL,
-                       "Unable to reset channel %u (%uMhz) "
-                       "reset status %u\n",
-                       channel->center_freq, r);
-       }
-       spin_unlock_bh(&sc->sc_resetlock);
-
-       ath9k_hw_phy_disable(ah);
-       ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP);
-       ath9k_ps_restore(sc);
-}
-
-#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
-
-/*******************/
-/*     Rfkill     */
-/*******************/
-
-static bool ath_is_rfkill_set(struct ath_softc *sc)
-{
-       struct ath_hw *ah = sc->sc_ah;
-
-       return ath9k_hw_gpio_get(ah, ah->rfkill_gpio) ==
-                                 ah->rfkill_polarity;
-}
-
-/* h/w rfkill poll function */
-static void ath_rfkill_poll(struct work_struct *work)
-{
-       struct ath_softc *sc = container_of(work, struct ath_softc,
-                                           rf_kill.rfkill_poll.work);
-       bool radio_on;
-
-       if (sc->sc_flags & SC_OP_INVALID)
-               return;
-
-       radio_on = !ath_is_rfkill_set(sc);
-
-       /*
-        * enable/disable radio only when there is a
-        * state change in RF switch
-        */
-       if (radio_on == !!(sc->sc_flags & SC_OP_RFKILL_HW_BLOCKED)) {
-               enum rfkill_state state;
-
-               if (sc->sc_flags & SC_OP_RFKILL_SW_BLOCKED) {
-                       state = radio_on ? RFKILL_STATE_SOFT_BLOCKED
-                               : RFKILL_STATE_HARD_BLOCKED;
-               } else if (radio_on) {
-                       ath_radio_enable(sc);
-                       state = RFKILL_STATE_UNBLOCKED;
-               } else {
-                       ath_radio_disable(sc);
-                       state = RFKILL_STATE_HARD_BLOCKED;
-               }
-
-               if (state == RFKILL_STATE_HARD_BLOCKED)
-                       sc->sc_flags |= SC_OP_RFKILL_HW_BLOCKED;
-               else
-                       sc->sc_flags &= ~SC_OP_RFKILL_HW_BLOCKED;
-
-               rfkill_force_state(sc->rf_kill.rfkill, state);
-       }
-
-       queue_delayed_work(sc->hw->workqueue, &sc->rf_kill.rfkill_poll,
-                          msecs_to_jiffies(ATH_RFKILL_POLL_INTERVAL));
-}
-
-/* s/w rfkill handler */
-static int ath_sw_toggle_radio(void *data, enum rfkill_state state)
-{
-       struct ath_softc *sc = data;
-
-       switch (state) {
-       case RFKILL_STATE_SOFT_BLOCKED:
-               if (!(sc->sc_flags & (SC_OP_RFKILL_HW_BLOCKED |
-                   SC_OP_RFKILL_SW_BLOCKED)))
-                       ath_radio_disable(sc);
-               sc->sc_flags |= SC_OP_RFKILL_SW_BLOCKED;
-               return 0;
-       case RFKILL_STATE_UNBLOCKED:
-               if ((sc->sc_flags & SC_OP_RFKILL_SW_BLOCKED)) {
-                       sc->sc_flags &= ~SC_OP_RFKILL_SW_BLOCKED;
-                       if (sc->sc_flags & SC_OP_RFKILL_HW_BLOCKED) {
-                               DPRINTF(sc, ATH_DBG_FATAL, "Can't turn on the"
-                                       "radio as it is disabled by h/w\n");
-                               return -EPERM;
-                       }
-                       ath_radio_enable(sc);
-               }
-               return 0;
-       default:
-               return -EINVAL;
-       }
-}
-
-/* Init s/w rfkill */
-static int ath_init_sw_rfkill(struct ath_softc *sc)
-{
-       sc->rf_kill.rfkill = rfkill_allocate(wiphy_dev(sc->hw->wiphy),
-                                            RFKILL_TYPE_WLAN);
-       if (!sc->rf_kill.rfkill) {
-               DPRINTF(sc, ATH_DBG_FATAL, "Failed to allocate rfkill\n");
-               return -ENOMEM;
-       }
-
-       snprintf(sc->rf_kill.rfkill_name, sizeof(sc->rf_kill.rfkill_name),
-               "ath9k-%s::rfkill", wiphy_name(sc->hw->wiphy));
-       sc->rf_kill.rfkill->name = sc->rf_kill.rfkill_name;
-       sc->rf_kill.rfkill->data = sc;
-       sc->rf_kill.rfkill->toggle_radio = ath_sw_toggle_radio;
-       sc->rf_kill.rfkill->state = RFKILL_STATE_UNBLOCKED;
-       sc->rf_kill.rfkill->user_claim_unsupported = 1;
-
-       return 0;
-}
-
-/* Deinitialize rfkill */
-static void ath_deinit_rfkill(struct ath_softc *sc)
-{
-       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
-               cancel_delayed_work_sync(&sc->rf_kill.rfkill_poll);
-
-       if (sc->sc_flags & SC_OP_RFKILL_REGISTERED) {
-               rfkill_unregister(sc->rf_kill.rfkill);
-               sc->sc_flags &= ~SC_OP_RFKILL_REGISTERED;
-               sc->rf_kill.rfkill = NULL;
-       }
-}
-
-static int ath_start_rfkill_poll(struct ath_softc *sc)
-{
-       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
-               queue_delayed_work(sc->hw->workqueue,
-                                  &sc->rf_kill.rfkill_poll, 0);
-
-       if (!(sc->sc_flags & SC_OP_RFKILL_REGISTERED)) {
-               if (rfkill_register(sc->rf_kill.rfkill)) {
-                       DPRINTF(sc, ATH_DBG_FATAL,
-                               "Unable to register rfkill\n");
-                       rfkill_free(sc->rf_kill.rfkill);
-
-                       /* Deinitialize the device */
-                       ath_cleanup(sc);
-                       return -EIO;
-               } else {
-                       sc->sc_flags |= SC_OP_RFKILL_REGISTERED;
-               }
-       }
-
-       return 0;
-}
-#endif /* CONFIG_RFKILL */
-
-void ath_cleanup(struct ath_softc *sc)
-{
-       ath_detach(sc);
-       free_irq(sc->irq, sc);
-       ath_bus_cleanup(sc);
-       kfree(sc->sec_wiphy);
-       ieee80211_free_hw(sc->hw);
-}
-
-void ath_detach(struct ath_softc *sc)
-{
-       struct ieee80211_hw *hw = sc->hw;
-       int i = 0;
-
-       ath9k_ps_wakeup(sc);
-
-       DPRINTF(sc, ATH_DBG_CONFIG, "Detach ATH hw\n");
-
-#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
-       ath_deinit_rfkill(sc);
-#endif
-       ath_deinit_leds(sc);
-       cancel_work_sync(&sc->chan_work);
-       cancel_delayed_work_sync(&sc->wiphy_work);
-
-       for (i = 0; i < sc->num_sec_wiphy; i++) {
-               struct ath_wiphy *aphy = sc->sec_wiphy[i];
-               if (aphy == NULL)
-                       continue;
-               sc->sec_wiphy[i] = NULL;
-               ieee80211_unregister_hw(aphy->hw);
-               ieee80211_free_hw(aphy->hw);
-       }
-       ieee80211_unregister_hw(hw);
-       ath_rx_cleanup(sc);
-       ath_tx_cleanup(sc);
-
-       tasklet_kill(&sc->intr_tq);
-       tasklet_kill(&sc->bcon_tasklet);
-
-       if (!(sc->sc_flags & SC_OP_INVALID))
-               ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE);
-
-       /* cleanup tx queues */
-       for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
-               if (ATH_TXQ_SETUP(sc, i))
-                       ath_tx_cleanupq(sc, &sc->tx.txq[i]);
-
-       ath9k_hw_detach(sc->sc_ah);
-       ath9k_exit_debug(sc);
-       ath9k_ps_restore(sc);
-}
-
-static int ath_init(u16 devid, struct ath_softc *sc)
-{
-       struct ath_hw *ah = NULL;
-       int status;
-       int error = 0, i;
-       int csz = 0;
-
-       /* XXX: hardware will not be ready until ath_open() being called */
-       sc->sc_flags |= SC_OP_INVALID;
-
-       if (ath9k_init_debug(sc) < 0)
-               printk(KERN_ERR "Unable to create debugfs files\n");
-
-       spin_lock_init(&sc->wiphy_lock);
-       spin_lock_init(&sc->sc_resetlock);
-       spin_lock_init(&sc->sc_serial_rw);
-       mutex_init(&sc->mutex);
-       tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc);
-       tasklet_init(&sc->bcon_tasklet, ath_beacon_tasklet,
-                    (unsigned long)sc);
-
-       /*
-        * Cache line size is used to size and align various
-        * structures used to communicate with the hardware.
-        */
-       ath_read_cachesize(sc, &csz);
-       /* XXX assert csz is non-zero */
-       sc->cachelsz = csz << 2;        /* convert to bytes */
-
-       ah = ath9k_hw_attach(devid, sc, &status);
-       if (ah == NULL) {
-               DPRINTF(sc, ATH_DBG_FATAL,
-                       "Unable to attach hardware; HAL status %d\n", status);
-               error = -ENXIO;
-               goto bad;
-       }
-       sc->sc_ah = ah;
-
-       /* Get the hardware key cache size. */
-       sc->keymax = ah->caps.keycache_size;
-       if (sc->keymax > ATH_KEYMAX) {
-               DPRINTF(sc, ATH_DBG_KEYCACHE,
-                       "Warning, using only %u entries in %u key cache\n",
-                       ATH_KEYMAX, sc->keymax);
-               sc->keymax = ATH_KEYMAX;
-       }
-
-       /*
-        * Reset the key cache since some parts do not
-        * reset the contents on initial power up.
-        */
-       for (i = 0; i < sc->keymax; i++)
-               ath9k_hw_keyreset(ah, (u16) i);
-
-       if (ath9k_regd_init(sc->sc_ah))
-               goto bad;
-
-       /* default to MONITOR mode */
-       sc->sc_ah->opmode = NL80211_IFTYPE_MONITOR;
-
-       /* Setup rate tables */
-
-       ath_rate_attach(sc);
-       ath_setup_rates(sc, IEEE80211_BAND_2GHZ);
-       ath_setup_rates(sc, IEEE80211_BAND_5GHZ);
-
-       /*
-        * Allocate hardware transmit queues: one queue for
-        * beacon frames and one data queue for each QoS
-        * priority.  Note that the hal handles reseting
-        * these queues at the needed time.
-        */
-       sc->beacon.beaconq = ath_beaconq_setup(ah);
-       if (sc->beacon.beaconq == -1) {
-               DPRINTF(sc, ATH_DBG_FATAL,
-                       "Unable to setup a beacon xmit queue\n");
-               error = -EIO;
-               goto bad2;
-       }
-       sc->beacon.cabq = ath_txq_setup(sc, ATH9K_TX_QUEUE_CAB, 0);
-       if (sc->beacon.cabq == NULL) {
-               DPRINTF(sc, ATH_DBG_FATAL,
-                       "Unable to setup CAB xmit queue\n");
-               error = -EIO;
-               goto bad2;
-       }
-
-       sc->config.cabqReadytime = ATH_CABQ_READY_TIME;
-       ath_cabq_update(sc);
-
-       for (i = 0; i < ARRAY_SIZE(sc->tx.hwq_map); i++)
-               sc->tx.hwq_map[i] = -1;
-
-       /* Setup data queues */
-       /* NB: ensure BK queue is the lowest priority h/w queue */
-       if (!ath_tx_setup(sc, ATH9K_WME_AC_BK)) {
-               DPRINTF(sc, ATH_DBG_FATAL,
-                       "Unable to setup xmit queue for BK traffic\n");
-               error = -EIO;
-               goto bad2;
-       }
-
-       if (!ath_tx_setup(sc, ATH9K_WME_AC_BE)) {
-               DPRINTF(sc, ATH_DBG_FATAL,
-                       "Unable to setup xmit queue for BE traffic\n");
-               error = -EIO;
-               goto bad2;
-       }
-       if (!ath_tx_setup(sc, ATH9K_WME_AC_VI)) {
-               DPRINTF(sc, ATH_DBG_FATAL,
-                       "Unable to setup xmit queue for VI traffic\n");
-               error = -EIO;
-               goto bad2;
-       }
-       if (!ath_tx_setup(sc, ATH9K_WME_AC_VO)) {
-               DPRINTF(sc, ATH_DBG_FATAL,
-                       "Unable to setup xmit queue for VO traffic\n");
-               error = -EIO;
-               goto bad2;
-       }
-
-       /* Initializes the noise floor to a reasonable default value.
-        * Later on this will be updated during ANI processing. */
-
-       sc->ani.noise_floor = ATH_DEFAULT_NOISE_FLOOR;
-       setup_timer(&sc->ani.timer, ath_ani_calibrate, (unsigned long)sc);
-
-       if (ath9k_hw_getcapability(ah, ATH9K_CAP_CIPHER,
-                                  ATH9K_CIPHER_TKIP, NULL)) {
-               /*
-                * Whether we should enable h/w TKIP MIC.
-                * XXX: if we don't support WME TKIP MIC, then we wouldn't
-                * report WMM capable, so it's always safe to turn on
-                * TKIP MIC in this case.
-                */
-               ath9k_hw_setcapability(sc->sc_ah, ATH9K_CAP_TKIP_MIC,
-                                      0, 1, NULL);
-       }
-
-       /*
-        * Check whether the separate key cache entries
-        * are required to handle both tx+rx MIC keys.
-        * With split mic keys the number of stations is limited
-        * to 27 otherwise 59.
-        */
-       if (ath9k_hw_getcapability(ah, ATH9K_CAP_CIPHER,
-                                  ATH9K_CIPHER_TKIP, NULL)
-           && ath9k_hw_getcapability(ah, ATH9K_CAP_CIPHER,
-                                     ATH9K_CIPHER_MIC, NULL)
-           && ath9k_hw_getcapability(ah, ATH9K_CAP_TKIP_SPLIT,
-                                     0, NULL))
-               sc->splitmic = 1;
-
-       /* turn on mcast key search if possible */
-       if (!ath9k_hw_getcapability(ah, ATH9K_CAP_MCAST_KEYSRCH, 0, NULL))
-               (void)ath9k_hw_setcapability(ah, ATH9K_CAP_MCAST_KEYSRCH, 1,
-                                            1, NULL);
-
-       sc->config.txpowlimit = ATH_TXPOWER_MAX;
-
-       /* 11n Capabilities */
-       if (ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
-               sc->sc_flags |= SC_OP_TXAGGR;
-               sc->sc_flags |= SC_OP_RXAGGR;
-       }
-
-       sc->tx_chainmask = ah->caps.tx_chainmask;
-       sc->rx_chainmask = ah->caps.rx_chainmask;
-
-       ath9k_hw_setcapability(ah, ATH9K_CAP_DIVERSITY, 1, true, NULL);
-       sc->rx.defant = ath9k_hw_getdefantenna(ah);
-
-       if (ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK)
-               memcpy(sc->bssidmask, ath_bcast_mac, ETH_ALEN);
-
-       sc->beacon.slottime = ATH9K_SLOT_TIME_9;        /* default to short slot time */
-
-       /* initialize beacon slots */
-       for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) {
-               sc->beacon.bslot[i] = NULL;
-               sc->beacon.bslot_aphy[i] = NULL;
-       }
-
-       /* save MISC configurations */
-       sc->config.swBeaconProcess = 1;
-
-       /* setup channels and rates */
-
-       sc->sbands[IEEE80211_BAND_2GHZ].channels = ath9k_2ghz_chantable;
-       sc->sbands[IEEE80211_BAND_2GHZ].bitrates =
-               sc->rates[IEEE80211_BAND_2GHZ];
-       sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ;
-       sc->sbands[IEEE80211_BAND_2GHZ].n_channels =
-               ARRAY_SIZE(ath9k_2ghz_chantable);
-
-       if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes)) {
-               sc->sbands[IEEE80211_BAND_5GHZ].channels = ath9k_5ghz_chantable;
-               sc->sbands[IEEE80211_BAND_5GHZ].bitrates =
-                       sc->rates[IEEE80211_BAND_5GHZ];
-               sc->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ;
-               sc->sbands[IEEE80211_BAND_5GHZ].n_channels =
-                       ARRAY_SIZE(ath9k_5ghz_chantable);
-       }
-
-       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_BT_COEX)
-               ath9k_hw_btcoex_enable(sc->sc_ah);
-
-       return 0;
-bad2:
-       /* cleanup tx queues */
-       for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
-               if (ATH_TXQ_SETUP(sc, i))
-                       ath_tx_cleanupq(sc, &sc->tx.txq[i]);
-bad:
-       if (ah)
-               ath9k_hw_detach(ah);
-       ath9k_exit_debug(sc);
-
-       return error;
-}
-
-void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
-{
-       hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
-               IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
-               IEEE80211_HW_SIGNAL_DBM |
-               IEEE80211_HW_AMPDU_AGGREGATION |
-               IEEE80211_HW_SUPPORTS_PS |
-               IEEE80211_HW_PS_NULLFUNC_STACK |
-               IEEE80211_HW_SPECTRUM_MGMT;
-
-       if (AR_SREV_9160_10_OR_LATER(sc->sc_ah) || modparam_nohwcrypt)
-               hw->flags |= IEEE80211_HW_MFP_CAPABLE;
-
-       hw->wiphy->interface_modes =
-               BIT(NL80211_IFTYPE_AP) |
-               BIT(NL80211_IFTYPE_STATION) |
-               BIT(NL80211_IFTYPE_ADHOC) |
-               BIT(NL80211_IFTYPE_MESH_POINT);
-
-       hw->wiphy->reg_notifier = ath9k_reg_notifier;
-       hw->wiphy->strict_regulatory = true;
-
-       hw->queues = 4;
-       hw->max_rates = 4;
-       hw->channel_change_time = 5000;
-       hw->max_listen_interval = 10;
-       hw->max_rate_tries = ATH_11N_TXMAXTRY;
-       hw->sta_data_size = sizeof(struct ath_node);
-       hw->vif_data_size = sizeof(struct ath_vif);
-
-       hw->rate_control_algorithm = "ath9k_rate_control";
-
-       hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
-               &sc->sbands[IEEE80211_BAND_2GHZ];
-       if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes))
-               hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
-                       &sc->sbands[IEEE80211_BAND_5GHZ];
-}
-
-int ath_attach(u16 devid, struct ath_softc *sc)
-{
-       struct ieee80211_hw *hw = sc->hw;
-       const struct ieee80211_regdomain *regd;
-       int error = 0, i;
-
-       DPRINTF(sc, ATH_DBG_CONFIG, "Attach ATH hw\n");
-
-       error = ath_init(devid, sc);
-       if (error != 0)
-               return error;
-
-       /* get mac address from hardware and set in mac80211 */
-
-       SET_IEEE80211_PERM_ADDR(hw, sc->sc_ah->macaddr);
-
-       ath_set_hw_capab(sc, hw);
-
-       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
-               setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_2GHZ].ht_cap);
-               if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes))
-                       setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_5GHZ].ht_cap);
-       }
-
-       /* initialize tx/rx engine */
-       error = ath_tx_init(sc, ATH_TXBUF);
-       if (error != 0)
-               goto error_attach;
-
-       error = ath_rx_init(sc, ATH_RXBUF);
-       if (error != 0)
-               goto error_attach;
-
-#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
-       /* Initialze h/w Rfkill */
-       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
-               INIT_DELAYED_WORK(&sc->rf_kill.rfkill_poll, ath_rfkill_poll);
-
-       /* Initialize s/w rfkill */
-       error = ath_init_sw_rfkill(sc);
-       if (error)
-               goto error_attach;
-#endif
-
-       if (ath9k_is_world_regd(sc->sc_ah)) {
-               /* Anything applied here (prior to wiphy registration) gets
-                * saved on the wiphy orig_* parameters */
-               regd = ath9k_world_regdomain(sc->sc_ah);
-               hw->wiphy->custom_regulatory = true;
-               hw->wiphy->strict_regulatory = false;
-       } else {
-               /* This gets applied in the case of the absense of CRDA,
-                * it's our own custom world regulatory domain, similar to
-                * cfg80211's but we enable passive scanning */
-               regd = ath9k_default_world_regdomain();
-       }
-       wiphy_apply_custom_regulatory(hw->wiphy, regd);
-       ath9k_reg_apply_radar_flags(hw->wiphy);
-       ath9k_reg_apply_world_flags(hw->wiphy, NL80211_REGDOM_SET_BY_DRIVER);
-
-       INIT_WORK(&sc->chan_work, ath9k_wiphy_chan_work);
-       INIT_DELAYED_WORK(&sc->wiphy_work, ath9k_wiphy_work);
-       sc->wiphy_scheduler_int = msecs_to_jiffies(500);
-
-       error = ieee80211_register_hw(hw);
-
-       if (!ath9k_is_world_regd(sc->sc_ah)) {
-               error = regulatory_hint(hw->wiphy,
-                       sc->sc_ah->regulatory.alpha2);
-               if (error)
-                       goto error_attach;
-       }
-
-       /* Initialize LED control */
-       ath_init_leds(sc);
-
-
-       return 0;
-
-error_attach:
-       /* cleanup tx queues */
-       for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
-               if (ATH_TXQ_SETUP(sc, i))
-                       ath_tx_cleanupq(sc, &sc->tx.txq[i]);
-
-       ath9k_hw_detach(sc->sc_ah);
-       ath9k_exit_debug(sc);
-
-       return error;
-}
-
-int ath_reset(struct ath_softc *sc, bool retry_tx)
-{
-       struct ath_hw *ah = sc->sc_ah;
-       struct ieee80211_hw *hw = sc->hw;
-       int r;
-
-       ath9k_hw_set_interrupts(ah, 0);
-       ath_drain_all_txq(sc, retry_tx);
-       ath_stoprecv(sc);
-       ath_flushrecv(sc);
-
-       spin_lock_bh(&sc->sc_resetlock);
-       r = ath9k_hw_reset(ah, sc->sc_ah->curchan, false);
-       if (r)
-               DPRINTF(sc, ATH_DBG_FATAL,
-                       "Unable to reset hardware; reset status %u\n", r);
-       spin_unlock_bh(&sc->sc_resetlock);
-
-       if (ath_startrecv(sc) != 0)
-               DPRINTF(sc, ATH_DBG_FATAL, "Unable to start recv logic\n");
-
-       /*
-        * We may be doing a reset in response to a request
-        * that changes the channel so update any state that
-        * might change as a result.
-        */
-       ath_cache_conf_rate(sc, &hw->conf);
-
-       ath_update_txpow(sc);
-
-       if (sc->sc_flags & SC_OP_BEACONS)
-               ath_beacon_config(sc, NULL);    /* restart beacons */
-
-       ath9k_hw_set_interrupts(ah, sc->imask);
-
-       if (retry_tx) {
-               int i;
-               for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
-                       if (ATH_TXQ_SETUP(sc, i)) {
-                               spin_lock_bh(&sc->tx.txq[i].axq_lock);
-                               ath_txq_schedule(sc, &sc->tx.txq[i]);
-                               spin_unlock_bh(&sc->tx.txq[i].axq_lock);
-                       }
-               }
-       }
-
-       return r;
-}
-
-/*
- *  This function will allocate both the DMA descriptor structure, and the
- *  buffers it contains.  These are used to contain the descriptors used
- *  by the system.
-*/
-int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
-                     struct list_head *head, const char *name,
-                     int nbuf, int ndesc)
-{
-#define        DS2PHYS(_dd, _ds)                                               \
-       ((_dd)->dd_desc_paddr + ((caddr_t)(_ds) - (caddr_t)(_dd)->dd_desc))
-#define ATH_DESC_4KB_BOUND_CHECK(_daddr) ((((_daddr) & 0xFFF) > 0xF7F) ? 1 : 0)
-#define ATH_DESC_4KB_BOUND_NUM_SKIPPED(_len) ((_len) / 4096)
-
-       struct ath_desc *ds;
-       struct ath_buf *bf;
-       int i, bsize, error;
-
-       DPRINTF(sc, ATH_DBG_CONFIG, "%s DMA: %u buffers %u desc/buf\n",
-               name, nbuf, ndesc);
-
-       INIT_LIST_HEAD(head);
-       /* ath_desc must be a multiple of DWORDs */
-       if ((sizeof(struct ath_desc) % 4) != 0) {
-               DPRINTF(sc, ATH_DBG_FATAL, "ath_desc not DWORD aligned\n");
-               ASSERT((sizeof(struct ath_desc) % 4) == 0);
-               error = -ENOMEM;
-               goto fail;
-       }
-
-       dd->dd_name = name;
-       dd->dd_desc_len = sizeof(struct ath_desc) * nbuf * ndesc;
-
-       /*
-        * Need additional DMA memory because we can't use
-        * descriptors that cross the 4K page boundary. Assume
-        * one skipped descriptor per 4K page.
-        */
-       if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_4KB_SPLITTRANS)) {
-               u32 ndesc_skipped =
-                       ATH_DESC_4KB_BOUND_NUM_SKIPPED(dd->dd_desc_len);
-               u32 dma_len;
-
-               while (ndesc_skipped) {
-                       dma_len = ndesc_skipped * sizeof(struct ath_desc);
-                       dd->dd_desc_len += dma_len;
-
-                       ndesc_skipped = ATH_DESC_4KB_BOUND_NUM_SKIPPED(dma_len);
-               };
-       }
-
-       /* allocate descriptors */
-       dd->dd_desc = dma_alloc_coherent(sc->dev, dd->dd_desc_len,
-                                        &dd->dd_desc_paddr, GFP_KERNEL);
-       if (dd->dd_desc == NULL) {
-               error = -ENOMEM;
-               goto fail;
-       }
-       ds = dd->dd_desc;
-       DPRINTF(sc, ATH_DBG_CONFIG, "%s DMA map: %p (%u) -> %llx (%u)\n",
-               dd->dd_name, ds, (u32) dd->dd_desc_len,
-               ito64(dd->dd_desc_paddr), /*XXX*/(u32) dd->dd_desc_len);
-
-       /* allocate buffers */
-       bsize = sizeof(struct ath_buf) * nbuf;
-       bf = kzalloc(bsize, GFP_KERNEL);
-       if (bf == NULL) {
-               error = -ENOMEM;
-               goto fail2;
-       }
-       dd->dd_bufptr = bf;
-
-       for (i = 0; i < nbuf; i++, bf++, ds += ndesc) {
-               bf->bf_desc = ds;
-               bf->bf_daddr = DS2PHYS(dd, ds);
-
-               if (!(sc->sc_ah->caps.hw_caps &
-                     ATH9K_HW_CAP_4KB_SPLITTRANS)) {
-                       /*
-                        * Skip descriptor addresses which can cause 4KB
-                        * boundary crossing (addr + length) with a 32 dword
-                        * descriptor fetch.
-                        */
-                       while (ATH_DESC_4KB_BOUND_CHECK(bf->bf_daddr)) {
-                               ASSERT((caddr_t) bf->bf_desc <
-                                      ((caddr_t) dd->dd_desc +
-                                       dd->dd_desc_len));
-
-                               ds += ndesc;
-                               bf->bf_desc = ds;
-                               bf->bf_daddr = DS2PHYS(dd, ds);
-                       }
-               }
-               list_add_tail(&bf->list, head);
-       }
-       return 0;
-fail2:
-       dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc,
-                         dd->dd_desc_paddr);
-fail:
-       memset(dd, 0, sizeof(*dd));
-       return error;
-#undef ATH_DESC_4KB_BOUND_CHECK
-#undef ATH_DESC_4KB_BOUND_NUM_SKIPPED
-#undef DS2PHYS
-}
-
-void ath_descdma_cleanup(struct ath_softc *sc,
-                        struct ath_descdma *dd,
-                        struct list_head *head)
-{
-       dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc,
-                         dd->dd_desc_paddr);
-
-       INIT_LIST_HEAD(head);
-       kfree(dd->dd_bufptr);
-       memset(dd, 0, sizeof(*dd));
-}
-
-int ath_get_hal_qnum(u16 queue, struct ath_softc *sc)
-{
-       int qnum;
-
-       switch (queue) {
-       case 0:
-               qnum = sc->tx.hwq_map[ATH9K_WME_AC_VO];
-               break;
-       case 1:
-               qnum = sc->tx.hwq_map[ATH9K_WME_AC_VI];
-               break;
-       case 2:
-               qnum = sc->tx.hwq_map[ATH9K_WME_AC_BE];
-               break;
-       case 3:
-               qnum = sc->tx.hwq_map[ATH9K_WME_AC_BK];
-               break;
-       default:
-               qnum = sc->tx.hwq_map[ATH9K_WME_AC_BE];
-               break;
-       }
-
-       return qnum;
-}
-
-int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc)
-{
-       int qnum;
-
-       switch (queue) {
-       case ATH9K_WME_AC_VO:
-               qnum = 0;
-               break;
-       case ATH9K_WME_AC_VI:
-               qnum = 1;
-               break;
-       case ATH9K_WME_AC_BE:
-               qnum = 2;
-               break;
-       case ATH9K_WME_AC_BK:
-               qnum = 3;
-               break;
-       default:
-               qnum = -1;
-               break;
-       }
-
-       return qnum;
-}
-
-/* XXX: Remove me once we don't depend on ath9k_channel for all
- * this redundant data */
-void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw,
-                          struct ath9k_channel *ichan)
-{
-       struct ieee80211_channel *chan = hw->conf.channel;
-       struct ieee80211_conf *conf = &hw->conf;
-
-       ichan->channel = chan->center_freq;
-       ichan->chan = chan;
-
-       if (chan->band == IEEE80211_BAND_2GHZ) {
-               ichan->chanmode = CHANNEL_G;
-               ichan->channelFlags = CHANNEL_2GHZ | CHANNEL_OFDM;
-       } else {
-               ichan->chanmode = CHANNEL_A;
-               ichan->channelFlags = CHANNEL_5GHZ | CHANNEL_OFDM;
-       }
-
-       sc->tx_chan_width = ATH9K_HT_MACMODE_20;
-
-       if (conf_is_ht(conf)) {
-               if (conf_is_ht40(conf))
-                       sc->tx_chan_width = ATH9K_HT_MACMODE_2040;
-
-               ichan->chanmode = ath_get_extchanmode(sc, chan,
-                                           conf->channel_type);
-       }
-}
-
-/**********************/
-/* mac80211 callbacks */
-/**********************/
-
-static int ath9k_start(struct ieee80211_hw *hw)
-{
-       struct ath_wiphy *aphy = hw->priv;
-       struct ath_softc *sc = aphy->sc;
-       struct ieee80211_channel *curchan = hw->conf.channel;
-       struct ath9k_channel *init_channel;
-       int r, pos;
-
-       DPRINTF(sc, ATH_DBG_CONFIG, "Starting driver with "
-               "initial channel: %d MHz\n", curchan->center_freq);
-
-       mutex_lock(&sc->mutex);
-
-       if (ath9k_wiphy_started(sc)) {
-               if (sc->chan_idx == curchan->hw_value) {
-                       /*
-                        * Already on the operational channel, the new wiphy
-                        * can be marked active.
-                        */
-                       aphy->state = ATH_WIPHY_ACTIVE;
-                       ieee80211_wake_queues(hw);
-               } else {
-                       /*
-                        * Another wiphy is on another channel, start the new
-                        * wiphy in paused state.
-                        */
-                       aphy->state = ATH_WIPHY_PAUSED;
-                       ieee80211_stop_queues(hw);
-               }
-               mutex_unlock(&sc->mutex);
-               return 0;
-       }
-       aphy->state = ATH_WIPHY_ACTIVE;
-
-       /* setup initial channel */
-
-       pos = curchan->hw_value;
-
-       sc->chan_idx = pos;
-       init_channel = &sc->sc_ah->channels[pos];
-       ath9k_update_ichannel(sc, hw, init_channel);
-
-       /* Reset SERDES registers */
-       ath9k_hw_configpcipowersave(sc->sc_ah, 0);
-
-       /*
-        * The basic interface to setting the hardware in a good
-        * state is ``reset''.  On return the hardware is known to
-        * be powered up and with interrupts disabled.  This must
-        * be followed by initialization of the appropriate bits
-        * and then setup of the interrupt mask.
-        */
-       spin_lock_bh(&sc->sc_resetlock);
-       r = ath9k_hw_reset(sc->sc_ah, init_channel, false);
-       if (r) {
-               DPRINTF(sc, ATH_DBG_FATAL,
-                       "Unable to reset hardware; reset status %u "
-                       "(freq %u MHz)\n", r,
-                       curchan->center_freq);
-               spin_unlock_bh(&sc->sc_resetlock);
-               goto mutex_unlock;
-       }
-       spin_unlock_bh(&sc->sc_resetlock);
-
-       /*
-        * This is needed only to setup initial state
-        * but it's best done after a reset.
-        */
-       ath_update_txpow(sc);
-
-       /*
-        * Setup the hardware after reset:
-        * The receive engine is set going.
-        * Frame transmit is handled entirely
-        * in the frame output path; there's nothing to do
-        * here except setup the interrupt mask.
-        */
-       if (ath_startrecv(sc) != 0) {
-               DPRINTF(sc, ATH_DBG_FATAL,
-                       "Unable to start recv logic\n");
-               r = -EIO;
-               goto mutex_unlock;
-       }
-
-       /* Setup our intr mask. */
-       sc->imask = ATH9K_INT_RX | ATH9K_INT_TX
-               | ATH9K_INT_RXEOL | ATH9K_INT_RXORN
-               | ATH9K_INT_FATAL | ATH9K_INT_GLOBAL;
-
-       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_GTT)
-               sc->imask |= ATH9K_INT_GTT;
-
-       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT)
-               sc->imask |= ATH9K_INT_CST;
-
-       ath_cache_conf_rate(sc, &hw->conf);
-
-       sc->sc_flags &= ~SC_OP_INVALID;
-
-       /* Disable BMISS interrupt when we're not associated */
-       sc->imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS);
-       ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
-
-       ieee80211_wake_queues(hw);
-
-#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
-       r = ath_start_rfkill_poll(sc);
-#endif
-
-mutex_unlock:
-       mutex_unlock(&sc->mutex);
-
-       return r;
-}
-
-static int ath9k_tx(struct ieee80211_hw *hw,
-                   struct sk_buff *skb)
-{
-       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-       struct ath_wiphy *aphy = hw->priv;
-       struct ath_softc *sc = aphy->sc;
-       struct ath_tx_control txctl;
-       int hdrlen, padsize;
-
-       if (aphy->state != ATH_WIPHY_ACTIVE && aphy->state != ATH_WIPHY_SCAN) {
-               printk(KERN_DEBUG "ath9k: %s: TX in unexpected wiphy state "
-                      "%d\n", wiphy_name(hw->wiphy), aphy->state);
-               goto exit;
-       }
-
-       memset(&txctl, 0, sizeof(struct ath_tx_control));
-
-       /*
-        * As a temporary workaround, assign seq# here; this will likely need
-        * to be cleaned up to work better with Beacon transmission and virtual
-        * BSSes.
-        */
-       if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
-               struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
-               if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
-                       sc->tx.seq_no += 0x10;
-               hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
-               hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no);
-       }
-
-       /* Add the padding after the header if this is not already done */
-       hdrlen = ieee80211_get_hdrlen_from_skb(skb);
-       if (hdrlen & 3) {
-               padsize = hdrlen % 4;
-               if (skb_headroom(skb) < padsize)
-                       return -1;
-               skb_push(skb, padsize);
-               memmove(skb->data, skb->data + padsize, hdrlen);
-       }
-
-       /* Check if a tx queue is available */
-
-       txctl.txq = ath_test_get_txq(sc, skb);
-       if (!txctl.txq)
-               goto exit;
-
-       DPRINTF(sc, ATH_DBG_XMIT, "transmitting packet, skb: %p\n", skb);
-
-       if (ath_tx_start(hw, skb, &txctl) != 0) {
-               DPRINTF(sc, ATH_DBG_XMIT, "TX failed\n");
-               goto exit;
-       }
-
-       return 0;
-exit:
-       dev_kfree_skb_any(skb);
-       return 0;
-}
-
-static void ath9k_stop(struct ieee80211_hw *hw)
-{
-       struct ath_wiphy *aphy = hw->priv;
-       struct ath_softc *sc = aphy->sc;
-
-       aphy->state = ATH_WIPHY_INACTIVE;
-
-       if (sc->sc_flags & SC_OP_INVALID) {
-               DPRINTF(sc, ATH_DBG_ANY, "Device not present\n");
-               return;
-       }
-
-       mutex_lock(&sc->mutex);
-
-       ieee80211_stop_queues(hw);
-
-       if (ath9k_wiphy_started(sc)) {
-               mutex_unlock(&sc->mutex);
-               return; /* another wiphy still in use */
-       }
-
-       /* make sure h/w will not generate any interrupt
-        * before setting the invalid flag. */
-       ath9k_hw_set_interrupts(sc->sc_ah, 0);
-
-       if (!(sc->sc_flags & SC_OP_INVALID)) {
-               ath_drain_all_txq(sc, false);
-               ath_stoprecv(sc);
-               ath9k_hw_phy_disable(sc->sc_ah);
-       } else
-               sc->rx.rxlink = NULL;
-
-#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
-       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
-               cancel_delayed_work_sync(&sc->rf_kill.rfkill_poll);
-#endif
-       /* disable HAL and put h/w to sleep */
-       ath9k_hw_disable(sc->sc_ah);
-       ath9k_hw_configpcipowersave(sc->sc_ah, 1);
-
-       sc->sc_flags |= SC_OP_INVALID;
-
-       mutex_unlock(&sc->mutex);
-
-       DPRINTF(sc, ATH_DBG_CONFIG, "Driver halt\n");
-}
-
-static int ath9k_add_interface(struct ieee80211_hw *hw,
-                              struct ieee80211_if_init_conf *conf)
-{
-       struct ath_wiphy *aphy = hw->priv;
-       struct ath_softc *sc = aphy->sc;
-       struct ath_vif *avp = (void *)conf->vif->drv_priv;
-       enum nl80211_iftype ic_opmode = NL80211_IFTYPE_UNSPECIFIED;
-       int ret = 0;
-
-       mutex_lock(&sc->mutex);
-
-       if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) &&
-           sc->nvifs > 0) {
-               ret = -ENOBUFS;
-               goto out;
-       }
-
-       switch (conf->type) {
-       case NL80211_IFTYPE_STATION:
-               ic_opmode = NL80211_IFTYPE_STATION;
-               break;
-       case NL80211_IFTYPE_ADHOC:
-       case NL80211_IFTYPE_AP:
-       case NL80211_IFTYPE_MESH_POINT:
-               if (sc->nbcnvifs >= ATH_BCBUF) {
-                       ret = -ENOBUFS;
-                       goto out;
-               }
-               ic_opmode = conf->type;
-               break;
-       default:
-               DPRINTF(sc, ATH_DBG_FATAL,
-                       "Interface type %d not yet supported\n", conf->type);
-               ret = -EOPNOTSUPP;
-               goto out;
-       }
-
-       DPRINTF(sc, ATH_DBG_CONFIG, "Attach a VIF of type: %d\n", ic_opmode);
-
-       /* Set the VIF opmode */
-       avp->av_opmode = ic_opmode;
-       avp->av_bslot = -1;
-
-       sc->nvifs++;
-
-       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK)
-               ath9k_set_bssid_mask(hw);
-
-       if (sc->nvifs > 1)
-               goto out; /* skip global settings for secondary vif */
-
-       if (ic_opmode == NL80211_IFTYPE_AP) {
-               ath9k_hw_set_tsfadjust(sc->sc_ah, 1);
-               sc->sc_flags |= SC_OP_TSF_RESET;
-       }
-
-       /* Set the device opmode */
-       sc->sc_ah->opmode = ic_opmode;
-
-       /*
-        * Enable MIB interrupts when there are hardware phy counters.
-        * Note we only do this (at the moment) for station mode.
-        */
-       if ((conf->type == NL80211_IFTYPE_STATION) ||
-           (conf->type == NL80211_IFTYPE_ADHOC) ||
-           (conf->type == NL80211_IFTYPE_MESH_POINT)) {
-               if (ath9k_hw_phycounters(sc->sc_ah))
-                       sc->imask |= ATH9K_INT_MIB;
-               sc->imask |= ATH9K_INT_TSFOOR;
-       }
-
-       /*
-        * Some hardware processes the TIM IE and fires an
-        * interrupt when the TIM bit is set.  For hardware
-        * that does, if not overridden by configuration,
-        * enable the TIM interrupt when operating as station.
-        */
-       if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_ENHANCEDPM) &&
-           (conf->type == NL80211_IFTYPE_STATION) &&
-           !sc->config.swBeaconProcess)
-               sc->imask |= ATH9K_INT_TIM;
-
-       ath9k_hw_set_interrupts(sc->sc_ah, sc->imask);
-
-       if (conf->type == NL80211_IFTYPE_AP) {
-               /* TODO: is this a suitable place to start ANI for AP mode? */
-               /* Start ANI */
-               mod_timer(&sc->ani.timer,
-                         jiffies + msecs_to_jiffies(ATH_ANI_POLLINTERVAL));
-       }
-
-out:
-       mutex_unlock(&sc->mutex);
-       return ret;
-}
-
-static void ath9k_remove_interface(struct ieee80211_hw *hw,
-                                  struct ieee80211_if_init_conf *conf)
-{
-       struct ath_wiphy *aphy = hw->priv;
-       struct ath_softc *sc = aphy->sc;
-       struct ath_vif *avp = (void *)conf->vif->drv_priv;
-       int i;
-
-       DPRINTF(sc, ATH_DBG_CONFIG, "Detach Interface\n");
-
-       mutex_lock(&sc->mutex);
-
-       /* Stop ANI */
-       del_timer_sync(&sc->ani.timer);
-
-       /* Reclaim beacon resources */
-       if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) ||
-           (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) ||
-           (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) {
-               ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
-               ath_beacon_return(sc, avp);
-       }
-
-       sc->sc_flags &= ~SC_OP_BEACONS;
-
-       for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) {
-               if (sc->beacon.bslot[i] == conf->vif) {
-                       printk(KERN_DEBUG "%s: vif had allocated beacon "
-                              "slot\n", __func__);
-                       sc->beacon.bslot[i] = NULL;
-                       sc->beacon.bslot_aphy[i] = NULL;
-               }
-       }
-
-       sc->nvifs--;
-
-       mutex_unlock(&sc->mutex);
-}
-
-static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
-{
-       struct ath_wiphy *aphy = hw->priv;
-       struct ath_softc *sc = aphy->sc;
-       struct ieee80211_conf *conf = &hw->conf;
-
-       mutex_lock(&sc->mutex);
-
-       if (changed & IEEE80211_CONF_CHANGE_PS) {
-               if (conf->flags & IEEE80211_CONF_PS) {
-                       if ((sc->imask & ATH9K_INT_TIM_TIMER) == 0) {
-                               sc->imask |= ATH9K_INT_TIM_TIMER;
-                               ath9k_hw_set_interrupts(sc->sc_ah,
-                                               sc->imask);
-                       }
-                       ath9k_hw_setrxabort(sc->sc_ah, 1);
-                       ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_NETWORK_SLEEP);
-               } else {
-                       ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE);
-                       ath9k_hw_setrxabort(sc->sc_ah, 0);
-                       sc->sc_flags &= ~SC_OP_WAIT_FOR_BEACON;
-                       if (sc->imask & ATH9K_INT_TIM_TIMER) {
-                               sc->imask &= ~ATH9K_INT_TIM_TIMER;
-                               ath9k_hw_set_interrupts(sc->sc_ah,
-                                               sc->imask);
-                       }
-               }
-       }
-
-       if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
-               struct ieee80211_channel *curchan = hw->conf.channel;
-               int pos = curchan->hw_value;
-
-               aphy->chan_idx = pos;
-               aphy->chan_is_ht = conf_is_ht(conf);
-
-               if (aphy->state == ATH_WIPHY_SCAN ||
-                   aphy->state == ATH_WIPHY_ACTIVE)
-                       ath9k_wiphy_pause_all_forced(sc, aphy);
-               else {
-                       /*
-                        * Do not change operational channel based on a paused
-                        * wiphy changes.
-                        */
-                       goto skip_chan_change;
-               }
-
-               DPRINTF(sc, ATH_DBG_CONFIG, "Set channel: %d MHz\n",
-                       curchan->center_freq);
-
-               /* XXX: remove me eventualy */
-               ath9k_update_ichannel(sc, hw, &sc->sc_ah->channels[pos]);
-
-               ath_update_chainmask(sc, conf_is_ht(conf));
-
-               if (ath_set_channel(sc, hw, &sc->sc_ah->channels[pos]) < 0) {
-                       DPRINTF(sc, ATH_DBG_FATAL, "Unable to set channel\n");
-                       mutex_unlock(&sc->mutex);
-                       return -EINVAL;
-               }
-       }
-
-skip_chan_change:
-       if (changed & IEEE80211_CONF_CHANGE_POWER)
-               sc->config.txpowlimit = 2 * conf->power_level;
-
-       /*
-        * The HW TSF has to be reset when the beacon interval changes.
-        * We set the flag here, and ath_beacon_config_ap() would take this
-        * into account when it gets called through the subsequent
-        * config_interface() call - with IFCC_BEACON in the changed field.
-        */
-
-       if (changed & IEEE80211_CONF_CHANGE_BEACON_INTERVAL)
-               sc->sc_flags |= SC_OP_TSF_RESET;
-
-       mutex_unlock(&sc->mutex);
-
-       return 0;
-}
-
-static int ath9k_config_interface(struct ieee80211_hw *hw,
-                                 struct ieee80211_vif *vif,
-                                 struct ieee80211_if_conf *conf)
-{
-       struct ath_wiphy *aphy = hw->priv;
-       struct ath_softc *sc = aphy->sc;
-       struct ath_hw *ah = sc->sc_ah;
-       struct ath_vif *avp = (void *)vif->drv_priv;
-       u32 rfilt = 0;
-       int error, i;
-
-       mutex_lock(&sc->mutex);
-
-       /* TODO: Need to decide which hw opmode to use for multi-interface
-        * cases */
-       if (vif->type == NL80211_IFTYPE_AP &&
-           ah->opmode != NL80211_IFTYPE_AP) {
-               ah->opmode = NL80211_IFTYPE_STATION;
-               ath9k_hw_setopmode(ah);
-               memcpy(sc->curbssid, sc->sc_ah->macaddr, ETH_ALEN);
-               sc->curaid = 0;
-               ath9k_hw_write_associd(sc);
-               /* Request full reset to get hw opmode changed properly */
-               sc->sc_flags |= SC_OP_FULL_RESET;
-       }
-
-       if ((conf->changed & IEEE80211_IFCC_BSSID) &&
-           !is_zero_ether_addr(conf->bssid)) {
-               switch (vif->type) {
-               case NL80211_IFTYPE_STATION:
-               case NL80211_IFTYPE_ADHOC:
-               case NL80211_IFTYPE_MESH_POINT:
-                       /* Set BSSID */
-                       memcpy(sc->curbssid, conf->bssid, ETH_ALEN);
-                       memcpy(avp->bssid, conf->bssid, ETH_ALEN);
-                       sc->curaid = 0;
-                       ath9k_hw_write_associd(sc);
-
-                       /* Set aggregation protection mode parameters */
-                       sc->config.ath_aggr_prot = 0;
-
-                       DPRINTF(sc, ATH_DBG_CONFIG,
-                               "RX filter 0x%x bssid %pM aid 0x%x\n",
-                               rfilt, sc->curbssid, sc->curaid);
-
-                       /* need to reconfigure the beacon */
-                       sc->sc_flags &= ~SC_OP_BEACONS ;
-
-                       break;
-               default:
-                       break;
-               }
-       }
-
-       if ((vif->type == NL80211_IFTYPE_ADHOC) ||
-           (vif->type == NL80211_IFTYPE_AP) ||
-           (vif->type == NL80211_IFTYPE_MESH_POINT)) {
-               if ((conf->changed & IEEE80211_IFCC_BEACON) ||
-                   (conf->changed & IEEE80211_IFCC_BEACON_ENABLED &&
-                    conf->enable_beacon)) {
-                       /*
-                        * Allocate and setup the beacon frame.
-                        *
-                        * Stop any previous beacon DMA.  This may be
-                        * necessary, for example, when an ibss merge
-                        * causes reconfiguration; we may be called
-                        * with beacon transmission active.
-                        */
-                       ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
-
-                       error = ath_beacon_alloc(aphy, vif);
-                       if (error != 0) {
-                               mutex_unlock(&sc->mutex);
-                               return error;
-                       }
-
-                       ath_beacon_config(sc, vif);
-               }
-       }
-
-       /* Check for WLAN_CAPABILITY_PRIVACY ? */
-       if ((avp->av_opmode != NL80211_IFTYPE_STATION)) {
-               for (i = 0; i < IEEE80211_WEP_NKID; i++)
-                       if (ath9k_hw_keyisvalid(sc->sc_ah, (u16)i))
-                               ath9k_hw_keysetmac(sc->sc_ah,
-                                                  (u16)i,
-                                                  sc->curbssid);
-       }
-
-       /* Only legacy IBSS for now */
-       if (vif->type == NL80211_IFTYPE_ADHOC)
-               ath_update_chainmask(sc, 0);
-
-       mutex_unlock(&sc->mutex);
-
-       return 0;
-}
-
-#define SUPPORTED_FILTERS                      \
-       (FIF_PROMISC_IN_BSS |                   \
-       FIF_ALLMULTI |                          \
-       FIF_CONTROL |                           \
-       FIF_OTHER_BSS |                         \
-       FIF_BCN_PRBRESP_PROMISC |               \
-       FIF_FCSFAIL)
-
-/* FIXME: sc->sc_full_reset ? */
-static void ath9k_configure_filter(struct ieee80211_hw *hw,
-                                  unsigned int changed_flags,
-                                  unsigned int *total_flags,
-                                  int mc_count,
-                                  struct dev_mc_list *mclist)
-{
-       struct ath_wiphy *aphy = hw->priv;
-       struct ath_softc *sc = aphy->sc;
-       u32 rfilt;
-
-       changed_flags &= SUPPORTED_FILTERS;
-       *total_flags &= SUPPORTED_FILTERS;
-
-       sc->rx.rxfilter = *total_flags;
-       rfilt = ath_calcrxfilter(sc);
-       ath9k_hw_setrxfilter(sc->sc_ah, rfilt);
-
-       DPRINTF(sc, ATH_DBG_CONFIG, "Set HW RX filter: 0x%x\n", sc->rx.rxfilter);
-}
-
-static void ath9k_sta_notify(struct ieee80211_hw *hw,
-                            struct ieee80211_vif *vif,
-                            enum sta_notify_cmd cmd,
-                            struct ieee80211_sta *sta)
-{
-       struct ath_wiphy *aphy = hw->priv;
-       struct ath_softc *sc = aphy->sc;
-
-       switch (cmd) {
-       case STA_NOTIFY_ADD:
-               ath_node_attach(sc, sta);
-               break;
-       case STA_NOTIFY_REMOVE:
-               ath_node_detach(sc, sta);
-               break;
-       default:
-               break;
-       }
-}
-
-static int ath9k_conf_tx(struct ieee80211_hw *hw, u16 queue,
-                        const struct ieee80211_tx_queue_params *params)
-{
-       struct ath_wiphy *aphy = hw->priv;
-       struct ath_softc *sc = aphy->sc;
-       struct ath9k_tx_queue_info qi;
-       int ret = 0, qnum;
-
-       if (queue >= WME_NUM_AC)
-               return 0;
-
-       mutex_lock(&sc->mutex);
-
-       qi.tqi_aifs = params->aifs;
-       qi.tqi_cwmin = params->cw_min;
-       qi.tqi_cwmax = params->cw_max;
-       qi.tqi_burstTime = params->txop;
-       qnum = ath_get_hal_qnum(queue, sc);
-
-       DPRINTF(sc, ATH_DBG_CONFIG,
-               "Configure tx [queue/halq] [%d/%d],  "
-               "aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n",
-               queue, qnum, params->aifs, params->cw_min,
-               params->cw_max, params->txop);
-
-       ret = ath_txq_update(sc, qnum, &qi);
-       if (ret)
-               DPRINTF(sc, ATH_DBG_FATAL, "TXQ Update failed\n");
-
-       mutex_unlock(&sc->mutex);
-
-       return ret;
-}
-
-static int ath9k_set_key(struct ieee80211_hw *hw,
-                        enum set_key_cmd cmd,
-                        struct ieee80211_vif *vif,
-                        struct ieee80211_sta *sta,
-                        struct ieee80211_key_conf *key)
-{
-       struct ath_wiphy *aphy = hw->priv;
-       struct ath_softc *sc = aphy->sc;
-       int ret = 0;
-
-       if (modparam_nohwcrypt)
-               return -ENOSPC;
-
-       mutex_lock(&sc->mutex);
-       ath9k_ps_wakeup(sc);
-       DPRINTF(sc, ATH_DBG_KEYCACHE, "Set HW Key\n");
-
-       switch (cmd) {
-       case SET_KEY:
-               ret = ath_key_config(sc, vif, sta, key);
-               if (ret >= 0) {
-                       key->hw_key_idx = ret;
-                       /* push IV and Michael MIC generation to stack */
-                       key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
-                       if (key->alg == ALG_TKIP)
-                               key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
-                       if (sc->sc_ah->sw_mgmt_crypto && key->alg == ALG_CCMP)
-                               key->flags |= IEEE80211_KEY_FLAG_SW_MGMT;
-                       ret = 0;
-               }
-               break;
-       case DISABLE_KEY:
-               ath_key_delete(sc, key);
-               break;
-       default:
-               ret = -EINVAL;
-       }
-
-       ath9k_ps_restore(sc);
-       mutex_unlock(&sc->mutex);
-
-       return ret;
-}
-
-static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
-                                  struct ieee80211_vif *vif,
-                                  struct ieee80211_bss_conf *bss_conf,
-                                  u32 changed)
-{
-       struct ath_wiphy *aphy = hw->priv;
-       struct ath_softc *sc = aphy->sc;
-
-       mutex_lock(&sc->mutex);
-
-       if (changed & BSS_CHANGED_ERP_PREAMBLE) {
-               DPRINTF(sc, ATH_DBG_CONFIG, "BSS Changed PREAMBLE %d\n",
-                       bss_conf->use_short_preamble);
-               if (bss_conf->use_short_preamble)
-                       sc->sc_flags |= SC_OP_PREAMBLE_SHORT;
-               else
-                       sc->sc_flags &= ~SC_OP_PREAMBLE_SHORT;
-       }
-
-       if (changed & BSS_CHANGED_ERP_CTS_PROT) {
-               DPRINTF(sc, ATH_DBG_CONFIG, "BSS Changed CTS PROT %d\n",
-                       bss_conf->use_cts_prot);
-               if (bss_conf->use_cts_prot &&
-                   hw->conf.channel->band != IEEE80211_BAND_5GHZ)
-                       sc->sc_flags |= SC_OP_PROTECT_ENABLE;
-               else
-                       sc->sc_flags &= ~SC_OP_PROTECT_ENABLE;
-       }
-
-       if (changed & BSS_CHANGED_ASSOC) {
-               DPRINTF(sc, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n",
-                       bss_conf->assoc);
-               ath9k_bss_assoc_info(sc, vif, bss_conf);
-       }
-
-       mutex_unlock(&sc->mutex);
-}
-
-static u64 ath9k_get_tsf(struct ieee80211_hw *hw)
-{
-       u64 tsf;
-       struct ath_wiphy *aphy = hw->priv;
-       struct ath_softc *sc = aphy->sc;
-
-       mutex_lock(&sc->mutex);
-       tsf = ath9k_hw_gettsf64(sc->sc_ah);
-       mutex_unlock(&sc->mutex);
-
-       return tsf;
-}
-
-static void ath9k_set_tsf(struct ieee80211_hw *hw, u64 tsf)
-{
-       struct ath_wiphy *aphy = hw->priv;
-       struct ath_softc *sc = aphy->sc;
-
-       mutex_lock(&sc->mutex);
-       ath9k_hw_settsf64(sc->sc_ah, tsf);
-       mutex_unlock(&sc->mutex);
-}
-
-static void ath9k_reset_tsf(struct ieee80211_hw *hw)
-{
-       struct ath_wiphy *aphy = hw->priv;
-       struct ath_softc *sc = aphy->sc;
-
-       mutex_lock(&sc->mutex);
-       ath9k_hw_reset_tsf(sc->sc_ah);
-       mutex_unlock(&sc->mutex);
-}
-
-static int ath9k_ampdu_action(struct ieee80211_hw *hw,
-                             enum ieee80211_ampdu_mlme_action action,
-                             struct ieee80211_sta *sta,
-                             u16 tid, u16 *ssn)
-{
-       struct ath_wiphy *aphy = hw->priv;
-       struct ath_softc *sc = aphy->sc;
-       int ret = 0;
-
-       switch (action) {
-       case IEEE80211_AMPDU_RX_START:
-               if (!(sc->sc_flags & SC_OP_RXAGGR))
-                       ret = -ENOTSUPP;
-               break;
-       case IEEE80211_AMPDU_RX_STOP:
-               break;
-       case IEEE80211_AMPDU_TX_START:
-               ret = ath_tx_aggr_start(sc, sta, tid, ssn);
-               if (ret < 0)
-                       DPRINTF(sc, ATH_DBG_FATAL,
-                               "Unable to start TX aggregation\n");
-               else
-                       ieee80211_start_tx_ba_cb_irqsafe(hw, sta->addr, tid);
-               break;
-       case IEEE80211_AMPDU_TX_STOP:
-               ret = ath_tx_aggr_stop(sc, sta, tid);
-               if (ret < 0)
-                       DPRINTF(sc, ATH_DBG_FATAL,
-                               "Unable to stop TX aggregation\n");
-
-               ieee80211_stop_tx_ba_cb_irqsafe(hw, sta->addr, tid);
-               break;
-       case IEEE80211_AMPDU_TX_OPERATIONAL:
-               ath_tx_aggr_resume(sc, sta, tid);
-               break;
-       default:
-               DPRINTF(sc, ATH_DBG_FATAL, "Unknown AMPDU action\n");
-       }
-
-       return ret;
-}
-
-static void ath9k_sw_scan_start(struct ieee80211_hw *hw)
-{
-       struct ath_wiphy *aphy = hw->priv;
-       struct ath_softc *sc = aphy->sc;
-
-       if (ath9k_wiphy_scanning(sc)) {
-               printk(KERN_DEBUG "ath9k: Two wiphys trying to scan at the "
-                      "same time\n");
-               /*
-                * Do not allow the concurrent scanning state for now. This
-                * could be improved with scanning control moved into ath9k.
-                */
-               return;
-       }
-
-       aphy->state = ATH_WIPHY_SCAN;
-       ath9k_wiphy_pause_all_forced(sc, aphy);
-
-       mutex_lock(&sc->mutex);
-       sc->sc_flags |= SC_OP_SCANNING;
-       mutex_unlock(&sc->mutex);
-}
-
-static void ath9k_sw_scan_complete(struct ieee80211_hw *hw)
-{
-       struct ath_wiphy *aphy = hw->priv;
-       struct ath_softc *sc = aphy->sc;
-
-       mutex_lock(&sc->mutex);
-       aphy->state = ATH_WIPHY_ACTIVE;
-       sc->sc_flags &= ~SC_OP_SCANNING;
-       mutex_unlock(&sc->mutex);
-}
-
-struct ieee80211_ops ath9k_ops = {
-       .tx                 = ath9k_tx,
-       .start              = ath9k_start,
-       .stop               = ath9k_stop,
-       .add_interface      = ath9k_add_interface,
-       .remove_interface   = ath9k_remove_interface,
-       .config             = ath9k_config,
-       .config_interface   = ath9k_config_interface,
-       .configure_filter   = ath9k_configure_filter,
-       .sta_notify         = ath9k_sta_notify,
-       .conf_tx            = ath9k_conf_tx,
-       .bss_info_changed   = ath9k_bss_info_changed,
-       .set_key            = ath9k_set_key,
-       .get_tsf            = ath9k_get_tsf,
-       .set_tsf            = ath9k_set_tsf,
-       .reset_tsf          = ath9k_reset_tsf,
-       .ampdu_action       = ath9k_ampdu_action,
-       .sw_scan_start      = ath9k_sw_scan_start,
-       .sw_scan_complete   = ath9k_sw_scan_complete,
-};
-
-static struct {
-       u32 version;
-       const char * name;
-} ath_mac_bb_names[] = {
-       { AR_SREV_VERSION_5416_PCI,     "5416" },
-       { AR_SREV_VERSION_5416_PCIE,    "5418" },
-       { AR_SREV_VERSION_9100,         "9100" },
-       { AR_SREV_VERSION_9160,         "9160" },
-       { AR_SREV_VERSION_9280,         "9280" },
-       { AR_SREV_VERSION_9285,         "9285" }
-};
-
-static struct {
-       u16 version;
-       const char * name;
-} ath_rf_names[] = {
-       { 0,                            "5133" },
-       { AR_RAD5133_SREV_MAJOR,        "5133" },
-       { AR_RAD5122_SREV_MAJOR,        "5122" },
-       { AR_RAD2133_SREV_MAJOR,        "2133" },
-       { AR_RAD2122_SREV_MAJOR,        "2122" }
-};
-
-/*
- * Return the MAC/BB name. "????" is returned if the MAC/BB is unknown.
- */
-const char *
-ath_mac_bb_name(u32 mac_bb_version)
-{
-       int i;
-
-       for (i=0; i<ARRAY_SIZE(ath_mac_bb_names); i++) {
-               if (ath_mac_bb_names[i].version == mac_bb_version) {
-                       return ath_mac_bb_names[i].name;
-               }
-       }
-
-       return "????";
-}
-
-/*
- * Return the RF name. "????" is returned if the RF is unknown.
- */
-const char *
-ath_rf_name(u16 rf_version)
-{
-       int i;
-
-       for (i=0; i<ARRAY_SIZE(ath_rf_names); i++) {
-               if (ath_rf_names[i].version == rf_version) {
-                       return ath_rf_names[i].name;
-               }
-       }
-
-       return "????";
-}
-
-static int __init ath9k_init(void)
-{
-       int error;
-
-       /* Register rate control algorithm */
-       error = ath_rate_control_register();
-       if (error != 0) {
-               printk(KERN_ERR
-                       "ath9k: Unable to register rate control "
-                       "algorithm: %d\n",
-                       error);
-               goto err_out;
-       }
-
-       error = ath9k_debug_create_root();
-       if (error) {
-               printk(KERN_ERR
-                       "ath9k: Unable to create debugfs root: %d\n",
-                       error);
-               goto err_rate_unregister;
-       }
-
-       error = ath_pci_init();
-       if (error < 0) {
-               printk(KERN_ERR
-                       "ath9k: No PCI devices found, driver not installed.\n");
-               error = -ENODEV;
-               goto err_remove_root;
-       }
-
-       error = ath_ahb_init();
-       if (error < 0) {
-               error = -ENODEV;
-               goto err_pci_exit;
-       }
-
-       return 0;
-
- err_pci_exit:
-       ath_pci_exit();
-
- err_remove_root:
-       ath9k_debug_remove_root();
- err_rate_unregister:
-       ath_rate_control_unregister();
- err_out:
-       return error;
-}
-module_init(ath9k_init);
-
-static void __exit ath9k_exit(void)
-{
-       ath_ahb_exit();
-       ath_pci_exit();
-       ath9k_debug_remove_root();
-       ath_rate_control_unregister();
-       printk(KERN_INFO "%s: Driver unloaded\n", dev_info);
-}
-module_exit(ath9k_exit);
diff --git a/drivers/net/wireless/ath9k/pci.c b/drivers/net/wireless/ath9k/pci.c
deleted file mode 100644 (file)
index 168411d..0000000
+++ /dev/null
@@ -1,295 +0,0 @@
-/*
- * Copyright (c) 2008-2009 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/nl80211.h>
-#include <linux/pci.h>
-#include "ath9k.h"
-
-static struct pci_device_id ath_pci_id_table[] __devinitdata = {
-       { PCI_VDEVICE(ATHEROS, 0x0023) }, /* PCI   */
-       { PCI_VDEVICE(ATHEROS, 0x0024) }, /* PCI-E */
-       { PCI_VDEVICE(ATHEROS, 0x0027) }, /* PCI   */
-       { PCI_VDEVICE(ATHEROS, 0x0029) }, /* PCI   */
-       { PCI_VDEVICE(ATHEROS, 0x002A) }, /* PCI-E */
-       { PCI_VDEVICE(ATHEROS, 0x002B) }, /* PCI-E */
-       { 0 }
-};
-
-/* return bus cachesize in 4B word units */
-static void ath_pci_read_cachesize(struct ath_softc *sc, int *csz)
-{
-       u8 u8tmp;
-
-       pci_read_config_byte(to_pci_dev(sc->dev), PCI_CACHE_LINE_SIZE,
-                            (u8 *)&u8tmp);
-       *csz = (int)u8tmp;
-
-       /*
-        * This check was put in to avoid "unplesant" consequences if
-        * the bootrom has not fully initialized all PCI devices.
-        * Sometimes the cache line size register is not set
-        */
-
-       if (*csz == 0)
-               *csz = DEFAULT_CACHELINE >> 2;   /* Use the default size */
-}
-
-static void ath_pci_cleanup(struct ath_softc *sc)
-{
-       struct pci_dev *pdev = to_pci_dev(sc->dev);
-
-       pci_iounmap(pdev, sc->mem);
-       pci_disable_device(pdev);
-       pci_release_region(pdev, 0);
-}
-
-static bool ath_pci_eeprom_read(struct ath_hw *ah, u32 off, u16 *data)
-{
-       (void)REG_READ(ah, AR5416_EEPROM_OFFSET + (off << AR5416_EEPROM_S));
-
-       if (!ath9k_hw_wait(ah,
-                          AR_EEPROM_STATUS_DATA,
-                          AR_EEPROM_STATUS_DATA_BUSY |
-                          AR_EEPROM_STATUS_DATA_PROT_ACCESS, 0,
-                          AH_WAIT_TIMEOUT)) {
-               return false;
-       }
-
-       *data = MS(REG_READ(ah, AR_EEPROM_STATUS_DATA),
-                  AR_EEPROM_STATUS_DATA_VAL);
-
-       return true;
-}
-
-static struct ath_bus_ops ath_pci_bus_ops = {
-       .read_cachesize = ath_pci_read_cachesize,
-       .cleanup = ath_pci_cleanup,
-       .eeprom_read = ath_pci_eeprom_read,
-};
-
-static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
-{
-       void __iomem *mem;
-       struct ath_wiphy *aphy;
-       struct ath_softc *sc;
-       struct ieee80211_hw *hw;
-       u8 csz;
-       int ret = 0;
-       struct ath_hw *ah;
-
-       if (pci_enable_device(pdev))
-               return -EIO;
-
-       ret =  pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
-
-       if (ret) {
-               printk(KERN_ERR "ath9k: 32-bit DMA not available\n");
-               goto bad;
-       }
-
-       ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
-
-       if (ret) {
-               printk(KERN_ERR "ath9k: 32-bit DMA consistent "
-                       "DMA enable failed\n");
-               goto bad;
-       }
-
-       /*
-        * Cache line size is used to size and align various
-        * structures used to communicate with the hardware.
-        */
-       pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &csz);
-       if (csz == 0) {
-               /*
-                * Linux 2.4.18 (at least) writes the cache line size
-                * register as a 16-bit wide register which is wrong.
-                * We must have this setup properly for rx buffer
-                * DMA to work so force a reasonable value here if it
-                * comes up zero.
-                */
-               csz = L1_CACHE_BYTES / sizeof(u32);
-               pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz);
-       }
-       /*
-        * The default setting of latency timer yields poor results,
-        * set it to the value used by other systems. It may be worth
-        * tweaking this setting more.
-        */
-       pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xa8);
-
-       pci_set_master(pdev);
-
-       ret = pci_request_region(pdev, 0, "ath9k");
-       if (ret) {
-               dev_err(&pdev->dev, "PCI memory region reserve error\n");
-               ret = -ENODEV;
-               goto bad;
-       }
-
-       mem = pci_iomap(pdev, 0, 0);
-       if (!mem) {
-               printk(KERN_ERR "PCI memory map error\n") ;
-               ret = -EIO;
-               goto bad1;
-       }
-
-       hw = ieee80211_alloc_hw(sizeof(struct ath_wiphy) +
-                               sizeof(struct ath_softc), &ath9k_ops);
-       if (hw == NULL) {
-               printk(KERN_ERR "ath_pci: no memory for ieee80211_hw\n");
-               goto bad2;
-       }
-
-       SET_IEEE80211_DEV(hw, &pdev->dev);
-       pci_set_drvdata(pdev, hw);
-
-       aphy = hw->priv;
-       sc = (struct ath_softc *) (aphy + 1);
-       aphy->sc = sc;
-       aphy->hw = hw;
-       sc->pri_wiphy = aphy;
-       sc->hw = hw;
-       sc->dev = &pdev->dev;
-       sc->mem = mem;
-       sc->bus_ops = &ath_pci_bus_ops;
-
-       if (ath_attach(id->device, sc) != 0) {
-               ret = -ENODEV;
-               goto bad3;
-       }
-
-       /* setup interrupt service routine */
-
-       if (request_irq(pdev->irq, ath_isr, IRQF_SHARED, "ath", sc)) {
-               printk(KERN_ERR "%s: request_irq failed\n",
-                       wiphy_name(hw->wiphy));
-               ret = -EIO;
-               goto bad4;
-       }
-
-       sc->irq = pdev->irq;
-
-       ah = sc->sc_ah;
-       printk(KERN_INFO
-              "%s: Atheros AR%s MAC/BB Rev:%x "
-              "AR%s RF Rev:%x: mem=0x%lx, irq=%d\n",
-              wiphy_name(hw->wiphy),
-              ath_mac_bb_name(ah->hw_version.macVersion),
-              ah->hw_version.macRev,
-              ath_rf_name((ah->hw_version.analog5GhzRev & AR_RADIO_SREV_MAJOR)),
-              ah->hw_version.phyRev,
-              (unsigned long)mem, pdev->irq);
-
-       return 0;
-bad4:
-       ath_detach(sc);
-bad3:
-       ieee80211_free_hw(hw);
-bad2:
-       pci_iounmap(pdev, mem);
-bad1:
-       pci_release_region(pdev, 0);
-bad:
-       pci_disable_device(pdev);
-       return ret;
-}
-
-static void ath_pci_remove(struct pci_dev *pdev)
-{
-       struct ieee80211_hw *hw = pci_get_drvdata(pdev);
-       struct ath_wiphy *aphy = hw->priv;
-       struct ath_softc *sc = aphy->sc;
-
-       ath_cleanup(sc);
-}
-
-#ifdef CONFIG_PM
-
-static int ath_pci_suspend(struct pci_dev *pdev, pm_message_t state)
-{
-       struct ieee80211_hw *hw = pci_get_drvdata(pdev);
-       struct ath_wiphy *aphy = hw->priv;
-       struct ath_softc *sc = aphy->sc;
-
-       ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1);
-
-#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
-       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
-               cancel_delayed_work_sync(&sc->rf_kill.rfkill_poll);
-#endif
-
-       pci_save_state(pdev);
-       pci_disable_device(pdev);
-       pci_set_power_state(pdev, PCI_D3hot);
-
-       return 0;
-}
-
-static int ath_pci_resume(struct pci_dev *pdev)
-{
-       struct ieee80211_hw *hw = pci_get_drvdata(pdev);
-       struct ath_wiphy *aphy = hw->priv;
-       struct ath_softc *sc = aphy->sc;
-       int err;
-
-       err = pci_enable_device(pdev);
-       if (err)
-               return err;
-       pci_restore_state(pdev);
-
-       /* Enable LED */
-       ath9k_hw_cfg_output(sc->sc_ah, ATH_LED_PIN,
-                           AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
-       ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 1);
-
-#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
-       /*
-        * check the h/w rfkill state on resume
-        * and start the rfkill poll timer
-        */
-       if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
-               queue_delayed_work(sc->hw->workqueue,
-                                  &sc->rf_kill.rfkill_poll, 0);
-#endif
-
-       return 0;
-}
-
-#endif /* CONFIG_PM */
-
-MODULE_DEVICE_TABLE(pci, ath_pci_id_table);
-
-static struct pci_driver ath_pci_driver = {
-       .name       = "ath9k",
-       .id_table   = ath_pci_id_table,
-       .probe      = ath_pci_probe,
-       .remove     = ath_pci_remove,
-#ifdef CONFIG_PM
-       .suspend    = ath_pci_suspend,
-       .resume     = ath_pci_resume,
-#endif /* CONFIG_PM */
-};
-
-int ath_pci_init(void)
-{
-       return pci_register_driver(&ath_pci_driver);
-}
-
-void ath_pci_exit(void)
-{
-       pci_unregister_driver(&ath_pci_driver);
-}
diff --git a/drivers/net/wireless/ath9k/phy.c b/drivers/net/wireless/ath9k/phy.c
deleted file mode 100644 (file)
index 8bcba90..0000000
+++ /dev/null
@@ -1,424 +0,0 @@
-/*
- * Copyright (c) 2008-2009 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 "ath9k.h"
-
-void
-ath9k_hw_write_regs(struct ath_hw *ah, u32 modesIndex, u32 freqIndex,
-                   int regWrites)
-{
-       REG_WRITE_ARRAY(&ah->iniBB_RfGain, freqIndex, regWrites);
-}
-
-bool
-ath9k_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
-{
-       u32 channelSel = 0;
-       u32 bModeSynth = 0;
-       u32 aModeRefSel = 0;
-       u32 reg32 = 0;
-       u16 freq;
-       struct chan_centers centers;
-
-       ath9k_hw_get_channel_centers(ah, chan, &centers);
-       freq = centers.synth_center;
-
-       if (freq < 4800) {
-               u32 txctl;
-
-               if (((freq - 2192) % 5) == 0) {
-                       channelSel = ((freq - 672) * 2 - 3040) / 10;
-                       bModeSynth = 0;
-               } else if (((freq - 2224) % 5) == 0) {
-                       channelSel = ((freq - 704) * 2 - 3040) / 10;
-                       bModeSynth = 1;
-               } else {
-                       DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
-                               "Invalid channel %u MHz\n", freq);
-                       return false;
-               }
-
-               channelSel = (channelSel << 2) & 0xff;
-               channelSel = ath9k_hw_reverse_bits(channelSel, 8);
-
-               txctl = REG_READ(ah, AR_PHY_CCK_TX_CTRL);
-               if (freq == 2484) {
-
-                       REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
-                                 txctl | AR_PHY_CCK_TX_CTRL_JAPAN);
-               } else {
-                       REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
-                                 txctl & ~AR_PHY_CCK_TX_CTRL_JAPAN);
-               }
-
-       } else if ((freq % 20) == 0 && freq >= 5120) {
-               channelSel =
-                   ath9k_hw_reverse_bits(((freq - 4800) / 20 << 2), 8);
-               aModeRefSel = ath9k_hw_reverse_bits(1, 2);
-       } else if ((freq % 10) == 0) {
-               channelSel =
-                   ath9k_hw_reverse_bits(((freq - 4800) / 10 << 1), 8);
-               if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah))
-                       aModeRefSel = ath9k_hw_reverse_bits(2, 2);
-               else
-                       aModeRefSel = ath9k_hw_reverse_bits(1, 2);
-       } else if ((freq % 5) == 0) {
-               channelSel = ath9k_hw_reverse_bits((freq - 4800) / 5, 8);
-               aModeRefSel = ath9k_hw_reverse_bits(1, 2);
-       } else {
-               DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
-                       "Invalid channel %u MHz\n", freq);
-               return false;
-       }
-
-       reg32 =
-           (channelSel << 8) | (aModeRefSel << 2) | (bModeSynth << 1) |
-           (1 << 5) | 0x1;
-
-       REG_WRITE(ah, AR_PHY(0x37), reg32);
-
-       ah->curchan = chan;
-       ah->curchan_rad_index = -1;
-
-       return true;
-}
-
-bool
-ath9k_hw_ar9280_set_channel(struct ath_hw *ah,
-                           struct ath9k_channel *chan)
-{
-       u16 bMode, fracMode, aModeRefSel = 0;
-       u32 freq, ndiv, channelSel = 0, channelFrac = 0, reg32 = 0;
-       struct chan_centers centers;
-       u32 refDivA = 24;
-
-       ath9k_hw_get_channel_centers(ah, chan, &centers);
-       freq = centers.synth_center;
-
-       reg32 = REG_READ(ah, AR_PHY_SYNTH_CONTROL);
-       reg32 &= 0xc0000000;
-
-       if (freq < 4800) {
-               u32 txctl;
-
-               bMode = 1;
-               fracMode = 1;
-               aModeRefSel = 0;
-               channelSel = (freq * 0x10000) / 15;
-
-               txctl = REG_READ(ah, AR_PHY_CCK_TX_CTRL);
-               if (freq == 2484) {
-
-                       REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
-                                 txctl | AR_PHY_CCK_TX_CTRL_JAPAN);
-               } else {
-                       REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
-                                 txctl & ~AR_PHY_CCK_TX_CTRL_JAPAN);
-               }
-       } else {
-               bMode = 0;
-               fracMode = 0;
-
-               switch(ah->eep_ops->get_eeprom(ah, EEP_FRAC_N_5G)) {
-               case 0:
-                       if ((freq % 20) == 0) {
-                               aModeRefSel = 3;
-                       } else if ((freq % 10) == 0) {
-                               aModeRefSel = 2;
-                       }
-                       if (aModeRefSel)
-                               break;
-               case 1:
-               default:
-                       aModeRefSel = 0;
-                       fracMode = 1;
-                       refDivA = 1;
-                       channelSel = (freq * 0x8000) / 15;
-
-                       REG_RMW_FIELD(ah, AR_AN_SYNTH9,
-                                     AR_AN_SYNTH9_REFDIVA, refDivA);
-
-               }
-
-               if (!fracMode) {
-                       ndiv = (freq * (refDivA >> aModeRefSel)) / 60;
-                       channelSel = ndiv & 0x1ff;
-                       channelFrac = (ndiv & 0xfffffe00) * 2;
-                       channelSel = (channelSel << 17) | channelFrac;
-               }
-       }
-
-       reg32 = reg32 |
-           (bMode << 29) |
-           (fracMode << 28) | (aModeRefSel << 26) | (channelSel);
-
-       REG_WRITE(ah, AR_PHY_SYNTH_CONTROL, reg32);
-
-       ah->curchan = chan;
-       ah->curchan_rad_index = -1;
-
-       return true;
-}
-
-static void
-ath9k_phy_modify_rx_buffer(u32 *rfBuf, u32 reg32,
-                          u32 numBits, u32 firstBit,
-                          u32 column)
-{
-       u32 tmp32, mask, arrayEntry, lastBit;
-       int32_t bitPosition, bitsLeft;
-
-       tmp32 = ath9k_hw_reverse_bits(reg32, numBits);
-       arrayEntry = (firstBit - 1) / 8;
-       bitPosition = (firstBit - 1) % 8;
-       bitsLeft = numBits;
-       while (bitsLeft > 0) {
-               lastBit = (bitPosition + bitsLeft > 8) ?
-                   8 : bitPosition + bitsLeft;
-               mask = (((1 << lastBit) - 1) ^ ((1 << bitPosition) - 1)) <<
-                   (column * 8);
-               rfBuf[arrayEntry] &= ~mask;
-               rfBuf[arrayEntry] |= ((tmp32 << bitPosition) <<
-                                     (column * 8)) & mask;
-               bitsLeft -= 8 - bitPosition;
-               tmp32 = tmp32 >> (8 - bitPosition);
-               bitPosition = 0;
-               arrayEntry++;
-       }
-}
-
-bool
-ath9k_hw_set_rf_regs(struct ath_hw *ah, struct ath9k_channel *chan,
-                    u16 modesIndex)
-{
-       u32 eepMinorRev;
-       u32 ob5GHz = 0, db5GHz = 0;
-       u32 ob2GHz = 0, db2GHz = 0;
-       int regWrites = 0;
-
-       if (AR_SREV_9280_10_OR_LATER(ah))
-               return true;
-
-       eepMinorRev = ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV);
-
-       RF_BANK_SETUP(ah->analogBank0Data, &ah->iniBank0, 1);
-
-       RF_BANK_SETUP(ah->analogBank1Data, &ah->iniBank1, 1);
-
-       RF_BANK_SETUP(ah->analogBank2Data, &ah->iniBank2, 1);
-
-       RF_BANK_SETUP(ah->analogBank3Data, &ah->iniBank3,
-                     modesIndex);
-       {
-               int i;
-               for (i = 0; i < ah->iniBank6TPC.ia_rows; i++) {
-                       ah->analogBank6Data[i] =
-                           INI_RA(&ah->iniBank6TPC, i, modesIndex);
-               }
-       }
-
-       if (eepMinorRev >= 2) {
-               if (IS_CHAN_2GHZ(chan)) {
-                       ob2GHz = ah->eep_ops->get_eeprom(ah, EEP_OB_2);
-                       db2GHz = ah->eep_ops->get_eeprom(ah, EEP_DB_2);
-                       ath9k_phy_modify_rx_buffer(ah->analogBank6Data,
-                                                  ob2GHz, 3, 197, 0);
-                       ath9k_phy_modify_rx_buffer(ah->analogBank6Data,
-                                                  db2GHz, 3, 194, 0);
-               } else {
-                       ob5GHz = ah->eep_ops->get_eeprom(ah, EEP_OB_5);
-                       db5GHz = ah->eep_ops->get_eeprom(ah, EEP_DB_5);
-                       ath9k_phy_modify_rx_buffer(ah->analogBank6Data,
-                                                  ob5GHz, 3, 203, 0);
-                       ath9k_phy_modify_rx_buffer(ah->analogBank6Data,
-                                                  db5GHz, 3, 200, 0);
-               }
-       }
-
-       RF_BANK_SETUP(ah->analogBank7Data, &ah->iniBank7, 1);
-
-       REG_WRITE_RF_ARRAY(&ah->iniBank0, ah->analogBank0Data,
-                          regWrites);
-       REG_WRITE_RF_ARRAY(&ah->iniBank1, ah->analogBank1Data,
-                          regWrites);
-       REG_WRITE_RF_ARRAY(&ah->iniBank2, ah->analogBank2Data,
-                          regWrites);
-       REG_WRITE_RF_ARRAY(&ah->iniBank3, ah->analogBank3Data,
-                          regWrites);
-       REG_WRITE_RF_ARRAY(&ah->iniBank6TPC, ah->analogBank6Data,
-                          regWrites);
-       REG_WRITE_RF_ARRAY(&ah->iniBank7, ah->analogBank7Data,
-                          regWrites);
-
-       return true;
-}
-
-void
-ath9k_hw_rfdetach(struct ath_hw *ah)
-{
-       if (ah->analogBank0Data != NULL) {
-               kfree(ah->analogBank0Data);
-               ah->analogBank0Data = NULL;
-       }
-       if (ah->analogBank1Data != NULL) {
-               kfree(ah->analogBank1Data);
-               ah->analogBank1Data = NULL;
-       }
-       if (ah->analogBank2Data != NULL) {
-               kfree(ah->analogBank2Data);
-               ah->analogBank2Data = NULL;
-       }
-       if (ah->analogBank3Data != NULL) {
-               kfree(ah->analogBank3Data);
-               ah->analogBank3Data = NULL;
-       }
-       if (ah->analogBank6Data != NULL) {
-               kfree(ah->analogBank6Data);
-               ah->analogBank6Data = NULL;
-       }
-       if (ah->analogBank6TPCData != NULL) {
-               kfree(ah->analogBank6TPCData);
-               ah->analogBank6TPCData = NULL;
-       }
-       if (ah->analogBank7Data != NULL) {
-               kfree(ah->analogBank7Data);
-               ah->analogBank7Data = NULL;
-       }
-       if (ah->addac5416_21 != NULL) {
-               kfree(ah->addac5416_21);
-               ah->addac5416_21 = NULL;
-       }
-       if (ah->bank6Temp != NULL) {
-               kfree(ah->bank6Temp);
-               ah->bank6Temp = NULL;
-       }
-}
-
-bool ath9k_hw_init_rf(struct ath_hw *ah, int *status)
-{
-       if (!AR_SREV_9280_10_OR_LATER(ah)) {
-               ah->analogBank0Data =
-                   kzalloc((sizeof(u32) *
-                            ah->iniBank0.ia_rows), GFP_KERNEL);
-               ah->analogBank1Data =
-                   kzalloc((sizeof(u32) *
-                            ah->iniBank1.ia_rows), GFP_KERNEL);
-               ah->analogBank2Data =
-                   kzalloc((sizeof(u32) *
-                            ah->iniBank2.ia_rows), GFP_KERNEL);
-               ah->analogBank3Data =
-                   kzalloc((sizeof(u32) *
-                            ah->iniBank3.ia_rows), GFP_KERNEL);
-               ah->analogBank6Data =
-                   kzalloc((sizeof(u32) *
-                            ah->iniBank6.ia_rows), GFP_KERNEL);
-               ah->analogBank6TPCData =
-                   kzalloc((sizeof(u32) *
-                            ah->iniBank6TPC.ia_rows), GFP_KERNEL);
-               ah->analogBank7Data =
-                   kzalloc((sizeof(u32) *
-                            ah->iniBank7.ia_rows), GFP_KERNEL);
-
-               if (ah->analogBank0Data == NULL
-                   || ah->analogBank1Data == NULL
-                   || ah->analogBank2Data == NULL
-                   || ah->analogBank3Data == NULL
-                   || ah->analogBank6Data == NULL
-                   || ah->analogBank6TPCData == NULL
-                   || ah->analogBank7Data == NULL) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-                               "Cannot allocate RF banks\n");
-                       *status = -ENOMEM;
-                       return false;
-               }
-
-               ah->addac5416_21 =
-                   kzalloc((sizeof(u32) *
-                            ah->iniAddac.ia_rows *
-                            ah->iniAddac.ia_columns), GFP_KERNEL);
-               if (ah->addac5416_21 == NULL) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-                               "Cannot allocate addac5416_21\n");
-                       *status = -ENOMEM;
-                       return false;
-               }
-
-               ah->bank6Temp =
-                   kzalloc((sizeof(u32) *
-                            ah->iniBank6.ia_rows), GFP_KERNEL);
-               if (ah->bank6Temp == NULL) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-                               "Cannot allocate bank6Temp\n");
-                       *status = -ENOMEM;
-                       return false;
-               }
-       }
-
-       return true;
-}
-
-void
-ath9k_hw_decrease_chain_power(struct ath_hw *ah, struct ath9k_channel *chan)
-{
-       int i, regWrites = 0;
-       u32 bank6SelMask;
-       u32 *bank6Temp = ah->bank6Temp;
-
-       switch (ah->diversity_control) {
-       case ATH9K_ANT_FIXED_A:
-               bank6SelMask =
-                   (ah->
-                    antenna_switch_swap & ANTSWAP_AB) ? REDUCE_CHAIN_0 :
-                   REDUCE_CHAIN_1;
-               break;
-       case ATH9K_ANT_FIXED_B:
-               bank6SelMask =
-                   (ah->
-                    antenna_switch_swap & ANTSWAP_AB) ? REDUCE_CHAIN_1 :
-                   REDUCE_CHAIN_0;
-               break;
-       case ATH9K_ANT_VARIABLE:
-               return;
-               break;
-       default:
-               return;
-               break;
-       }
-
-       for (i = 0; i < ah->iniBank6.ia_rows; i++)
-               bank6Temp[i] = ah->analogBank6Data[i];
-
-       REG_WRITE(ah, AR_PHY_BASE + 0xD8, bank6SelMask);
-
-       ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 189, 0);
-       ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 190, 0);
-       ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 191, 0);
-       ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 192, 0);
-       ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 193, 0);
-       ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 222, 0);
-       ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 245, 0);
-       ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 246, 0);
-       ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 247, 0);
-
-       REG_WRITE_RF_ARRAY(&ah->iniBank6, bank6Temp, regWrites);
-
-       REG_WRITE(ah, AR_PHY_BASE + 0xD8, 0x00000053);
-#ifdef ALTER_SWITCH
-       REG_WRITE(ah, PHY_SWITCH_CHAIN_0,
-                 (REG_READ(ah, PHY_SWITCH_CHAIN_0) & ~0x38)
-                 | ((REG_READ(ah, PHY_SWITCH_CHAIN_0) >> 3) & 0x38));
-#endif
-}
diff --git a/drivers/net/wireless/ath9k/phy.h b/drivers/net/wireless/ath9k/phy.h
deleted file mode 100644 (file)
index 0f7f8e0..0000000
+++ /dev/null
@@ -1,579 +0,0 @@
-/*
- * Copyright (c) 2008-2009 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 PHY_H
-#define PHY_H
-
-bool ath9k_hw_ar9280_set_channel(struct ath_hw *ah,
-                                struct ath9k_channel
-                                *chan);
-bool ath9k_hw_set_channel(struct ath_hw *ah,
-                         struct ath9k_channel *chan);
-void ath9k_hw_write_regs(struct ath_hw *ah, u32 modesIndex,
-                        u32 freqIndex, int regWrites);
-bool ath9k_hw_set_rf_regs(struct ath_hw *ah,
-                         struct ath9k_channel *chan,
-                         u16 modesIndex);
-void ath9k_hw_decrease_chain_power(struct ath_hw *ah,
-                                  struct ath9k_channel *chan);
-bool ath9k_hw_init_rf(struct ath_hw *ah,
-                     int *status);
-
-#define AR_PHY_BASE     0x9800
-#define AR_PHY(_n)      (AR_PHY_BASE + ((_n)<<2))
-
-#define AR_PHY_TEST             0x9800
-#define PHY_AGC_CLR             0x10000000
-#define RFSILENT_BB             0x00002000
-
-#define AR_PHY_TURBO                0x9804
-#define AR_PHY_FC_TURBO_MODE        0x00000001
-#define AR_PHY_FC_TURBO_SHORT       0x00000002
-#define AR_PHY_FC_DYN2040_EN        0x00000004
-#define AR_PHY_FC_DYN2040_PRI_ONLY  0x00000008
-#define AR_PHY_FC_DYN2040_PRI_CH    0x00000010
-#define AR_PHY_FC_DYN2040_EXT_CH    0x00000020
-#define AR_PHY_FC_HT_EN             0x00000040
-#define AR_PHY_FC_SHORT_GI_40       0x00000080
-#define AR_PHY_FC_WALSH             0x00000100
-#define AR_PHY_FC_SINGLE_HT_LTF1    0x00000200
-#define AR_PHY_FC_ENABLE_DAC_FIFO   0x00000800
-
-#define AR_PHY_TEST2               0x9808
-
-#define AR_PHY_TIMING2           0x9810
-#define AR_PHY_TIMING3           0x9814
-#define AR_PHY_TIMING3_DSC_MAN   0xFFFE0000
-#define AR_PHY_TIMING3_DSC_MAN_S 17
-#define AR_PHY_TIMING3_DSC_EXP   0x0001E000
-#define AR_PHY_TIMING3_DSC_EXP_S 13
-
-#define AR_PHY_CHIP_ID            0x9818
-#define AR_PHY_CHIP_ID_REV_0      0x80
-#define AR_PHY_CHIP_ID_REV_1      0x81
-#define AR_PHY_CHIP_ID_9160_REV_0 0xb0
-
-#define AR_PHY_ACTIVE       0x981C
-#define AR_PHY_ACTIVE_EN    0x00000001
-#define AR_PHY_ACTIVE_DIS   0x00000000
-
-#define AR_PHY_RF_CTL2             0x9824
-#define AR_PHY_TX_END_DATA_START   0x000000FF
-#define AR_PHY_TX_END_DATA_START_S 0
-#define AR_PHY_TX_END_PA_ON        0x0000FF00
-#define AR_PHY_TX_END_PA_ON_S      8
-
-#define AR_PHY_RF_CTL3                  0x9828
-#define AR_PHY_TX_END_TO_A2_RX_ON       0x00FF0000
-#define AR_PHY_TX_END_TO_A2_RX_ON_S     16
-
-#define AR_PHY_ADC_CTL                  0x982C
-#define AR_PHY_ADC_CTL_OFF_INBUFGAIN    0x00000003
-#define AR_PHY_ADC_CTL_OFF_INBUFGAIN_S  0
-#define AR_PHY_ADC_CTL_OFF_PWDDAC       0x00002000
-#define AR_PHY_ADC_CTL_OFF_PWDBANDGAP   0x00004000
-#define AR_PHY_ADC_CTL_OFF_PWDADC       0x00008000
-#define AR_PHY_ADC_CTL_ON_INBUFGAIN     0x00030000
-#define AR_PHY_ADC_CTL_ON_INBUFGAIN_S   16
-
-#define AR_PHY_ADC_SERIAL_CTL       0x9830
-#define AR_PHY_SEL_INTERNAL_ADDAC   0x00000000
-#define AR_PHY_SEL_EXTERNAL_RADIO   0x00000001
-
-#define AR_PHY_RF_CTL4                    0x9834
-#define AR_PHY_RF_CTL4_TX_END_XPAB_OFF    0xFF000000
-#define AR_PHY_RF_CTL4_TX_END_XPAB_OFF_S  24
-#define AR_PHY_RF_CTL4_TX_END_XPAA_OFF    0x00FF0000
-#define AR_PHY_RF_CTL4_TX_END_XPAA_OFF_S  16
-#define AR_PHY_RF_CTL4_FRAME_XPAB_ON      0x0000FF00
-#define AR_PHY_RF_CTL4_FRAME_XPAB_ON_S    8
-#define AR_PHY_RF_CTL4_FRAME_XPAA_ON      0x000000FF
-#define AR_PHY_RF_CTL4_FRAME_XPAA_ON_S    0
-
-#define AR_PHY_TSTDAC_CONST               0x983c
-
-#define AR_PHY_SETTLING          0x9844
-#define AR_PHY_SETTLING_SWITCH   0x00003F80
-#define AR_PHY_SETTLING_SWITCH_S 7
-
-#define AR_PHY_RXGAIN                   0x9848
-#define AR_PHY_RXGAIN_TXRX_ATTEN        0x0003F000
-#define AR_PHY_RXGAIN_TXRX_ATTEN_S      12
-#define AR_PHY_RXGAIN_TXRX_RF_MAX       0x007C0000
-#define AR_PHY_RXGAIN_TXRX_RF_MAX_S     18
-#define AR9280_PHY_RXGAIN_TXRX_ATTEN    0x00003F80
-#define AR9280_PHY_RXGAIN_TXRX_ATTEN_S  7
-#define AR9280_PHY_RXGAIN_TXRX_MARGIN   0x001FC000
-#define AR9280_PHY_RXGAIN_TXRX_MARGIN_S 14
-
-#define AR_PHY_DESIRED_SZ           0x9850
-#define AR_PHY_DESIRED_SZ_ADC       0x000000FF
-#define AR_PHY_DESIRED_SZ_ADC_S     0
-#define AR_PHY_DESIRED_SZ_PGA       0x0000FF00
-#define AR_PHY_DESIRED_SZ_PGA_S     8
-#define AR_PHY_DESIRED_SZ_TOT_DES   0x0FF00000
-#define AR_PHY_DESIRED_SZ_TOT_DES_S 20
-
-#define AR_PHY_FIND_SIG           0x9858
-#define AR_PHY_FIND_SIG_FIRSTEP   0x0003F000
-#define AR_PHY_FIND_SIG_FIRSTEP_S 12
-#define AR_PHY_FIND_SIG_FIRPWR    0x03FC0000
-#define AR_PHY_FIND_SIG_FIRPWR_S  18
-
-#define AR_PHY_AGC_CTL1                  0x985C
-#define AR_PHY_AGC_CTL1_COARSE_LOW       0x00007F80
-#define AR_PHY_AGC_CTL1_COARSE_LOW_S     7
-#define AR_PHY_AGC_CTL1_COARSE_HIGH      0x003F8000
-#define AR_PHY_AGC_CTL1_COARSE_HIGH_S    15
-
-#define AR_PHY_AGC_CONTROL               0x9860
-#define AR_PHY_AGC_CONTROL_CAL           0x00000001
-#define AR_PHY_AGC_CONTROL_NF            0x00000002
-#define AR_PHY_AGC_CONTROL_ENABLE_NF     0x00008000
-#define AR_PHY_AGC_CONTROL_FLTR_CAL      0x00010000
-#define AR_PHY_AGC_CONTROL_NO_UPDATE_NF  0x00020000
-
-#define AR_PHY_CCA                  0x9864
-#define AR_PHY_MINCCA_PWR           0x0FF80000
-#define AR_PHY_MINCCA_PWR_S         19
-#define AR_PHY_CCA_THRESH62         0x0007F000
-#define AR_PHY_CCA_THRESH62_S       12
-#define AR9280_PHY_MINCCA_PWR       0x1FF00000
-#define AR9280_PHY_MINCCA_PWR_S     20
-#define AR9280_PHY_CCA_THRESH62     0x000FF000
-#define AR9280_PHY_CCA_THRESH62_S   12
-
-#define AR_PHY_SFCORR_LOW                    0x986C
-#define AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW  0x00000001
-#define AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW    0x00003F00
-#define AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW_S  8
-#define AR_PHY_SFCORR_LOW_M1_THRESH_LOW      0x001FC000
-#define AR_PHY_SFCORR_LOW_M1_THRESH_LOW_S    14
-#define AR_PHY_SFCORR_LOW_M2_THRESH_LOW      0x0FE00000
-#define AR_PHY_SFCORR_LOW_M2_THRESH_LOW_S    21
-
-#define AR_PHY_SFCORR                0x9868
-#define AR_PHY_SFCORR_M2COUNT_THR    0x0000001F
-#define AR_PHY_SFCORR_M2COUNT_THR_S  0
-#define AR_PHY_SFCORR_M1_THRESH      0x00FE0000
-#define AR_PHY_SFCORR_M1_THRESH_S    17
-#define AR_PHY_SFCORR_M2_THRESH      0x7F000000
-#define AR_PHY_SFCORR_M2_THRESH_S    24
-
-#define AR_PHY_SLEEP_CTR_CONTROL    0x9870
-#define AR_PHY_SLEEP_CTR_LIMIT      0x9874
-#define AR_PHY_SYNTH_CONTROL        0x9874
-#define AR_PHY_SLEEP_SCAL           0x9878
-
-#define AR_PHY_PLL_CTL          0x987c
-#define AR_PHY_PLL_CTL_40       0xaa
-#define AR_PHY_PLL_CTL_40_5413  0x04
-#define AR_PHY_PLL_CTL_44       0xab
-#define AR_PHY_PLL_CTL_44_2133  0xeb
-#define AR_PHY_PLL_CTL_40_2133  0xea
-
-#define AR_PHY_RX_DELAY           0x9914
-#define AR_PHY_SEARCH_START_DELAY 0x9918
-#define AR_PHY_RX_DELAY_DELAY     0x00003FFF
-
-#define AR_PHY_TIMING_CTRL4(_i)     (0x9920 + ((_i) << 12))
-#define AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF 0x01F
-#define AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF_S   0
-#define AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF 0x7E0
-#define AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF_S   5
-#define AR_PHY_TIMING_CTRL4_IQCORR_ENABLE   0x800
-#define AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX 0xF000
-#define AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX_S   12
-#define AR_PHY_TIMING_CTRL4_DO_CAL    0x10000
-
-#define AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI   0x80000000
-#define        AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER  0x40000000
-#define        AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK    0x20000000
-#define        AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK   0x10000000
-
-#define AR_PHY_TIMING5               0x9924
-#define AR_PHY_TIMING5_CYCPWR_THR1   0x000000FE
-#define AR_PHY_TIMING5_CYCPWR_THR1_S 1
-
-#define AR_PHY_POWER_TX_RATE1               0x9934
-#define AR_PHY_POWER_TX_RATE2               0x9938
-#define AR_PHY_POWER_TX_RATE_MAX            0x993c
-#define AR_PHY_POWER_TX_RATE_MAX_TPC_ENABLE 0x00000040
-
-#define AR_PHY_FRAME_CTL            0x9944
-#define AR_PHY_FRAME_CTL_TX_CLIP    0x00000038
-#define AR_PHY_FRAME_CTL_TX_CLIP_S  3
-
-#define AR_PHY_TXPWRADJ                   0x994C
-#define AR_PHY_TXPWRADJ_CCK_GAIN_DELTA    0x00000FC0
-#define AR_PHY_TXPWRADJ_CCK_GAIN_DELTA_S  6
-#define AR_PHY_TXPWRADJ_CCK_PCDAC_INDEX   0x00FC0000
-#define AR_PHY_TXPWRADJ_CCK_PCDAC_INDEX_S 18
-
-#define AR_PHY_RADAR_EXT      0x9940
-#define AR_PHY_RADAR_EXT_ENA  0x00004000
-
-#define AR_PHY_RADAR_0          0x9954
-#define AR_PHY_RADAR_0_ENA      0x00000001
-#define AR_PHY_RADAR_0_FFT_ENA  0x80000000
-#define AR_PHY_RADAR_0_INBAND   0x0000003e
-#define AR_PHY_RADAR_0_INBAND_S 1
-#define AR_PHY_RADAR_0_PRSSI    0x00000FC0
-#define AR_PHY_RADAR_0_PRSSI_S  6
-#define AR_PHY_RADAR_0_HEIGHT   0x0003F000
-#define AR_PHY_RADAR_0_HEIGHT_S 12
-#define AR_PHY_RADAR_0_RRSSI    0x00FC0000
-#define AR_PHY_RADAR_0_RRSSI_S  18
-#define AR_PHY_RADAR_0_FIRPWR   0x7F000000
-#define AR_PHY_RADAR_0_FIRPWR_S 24
-
-#define AR_PHY_RADAR_1                  0x9958
-#define AR_PHY_RADAR_1_RELPWR_ENA       0x00800000
-#define AR_PHY_RADAR_1_USE_FIR128       0x00400000
-#define AR_PHY_RADAR_1_RELPWR_THRESH    0x003F0000
-#define AR_PHY_RADAR_1_RELPWR_THRESH_S  16
-#define AR_PHY_RADAR_1_BLOCK_CHECK      0x00008000
-#define AR_PHY_RADAR_1_MAX_RRSSI        0x00004000
-#define AR_PHY_RADAR_1_RELSTEP_CHECK    0x00002000
-#define AR_PHY_RADAR_1_RELSTEP_THRESH   0x00001F00
-#define AR_PHY_RADAR_1_RELSTEP_THRESH_S 8
-#define AR_PHY_RADAR_1_MAXLEN           0x000000FF
-#define AR_PHY_RADAR_1_MAXLEN_S         0
-
-#define AR_PHY_SWITCH_CHAIN_0     0x9960
-#define AR_PHY_SWITCH_COM         0x9964
-
-#define AR_PHY_SIGMA_DELTA            0x996C
-#define AR_PHY_SIGMA_DELTA_ADC_SEL    0x00000003
-#define AR_PHY_SIGMA_DELTA_ADC_SEL_S  0
-#define AR_PHY_SIGMA_DELTA_FILT2      0x000000F8
-#define AR_PHY_SIGMA_DELTA_FILT2_S    3
-#define AR_PHY_SIGMA_DELTA_FILT1      0x00001F00
-#define AR_PHY_SIGMA_DELTA_FILT1_S    8
-#define AR_PHY_SIGMA_DELTA_ADC_CLIP   0x01FFE000
-#define AR_PHY_SIGMA_DELTA_ADC_CLIP_S 13
-
-#define AR_PHY_RESTART          0x9970
-#define AR_PHY_RESTART_DIV_GC   0x001C0000
-#define AR_PHY_RESTART_DIV_GC_S 18
-
-#define AR_PHY_RFBUS_REQ        0x997C
-#define AR_PHY_RFBUS_REQ_EN     0x00000001
-
-#define        AR_PHY_TIMING7                  0x9980
-#define        AR_PHY_TIMING8                  0x9984
-#define        AR_PHY_TIMING8_PILOT_MASK_2     0x000FFFFF
-#define        AR_PHY_TIMING8_PILOT_MASK_2_S   0
-
-#define        AR_PHY_BIN_MASK2_1      0x9988
-#define        AR_PHY_BIN_MASK2_2      0x998c
-#define        AR_PHY_BIN_MASK2_3      0x9990
-#define        AR_PHY_BIN_MASK2_4      0x9994
-
-#define        AR_PHY_BIN_MASK_1       0x9900
-#define        AR_PHY_BIN_MASK_2       0x9904
-#define        AR_PHY_BIN_MASK_3       0x9908
-
-#define        AR_PHY_MASK_CTL         0x990c
-
-#define        AR_PHY_BIN_MASK2_4_MASK_4       0x00003FFF
-#define        AR_PHY_BIN_MASK2_4_MASK_4_S     0
-
-#define        AR_PHY_TIMING9                  0x9998
-#define        AR_PHY_TIMING10                 0x999c
-#define        AR_PHY_TIMING10_PILOT_MASK_2    0x000FFFFF
-#define        AR_PHY_TIMING10_PILOT_MASK_2_S  0
-
-#define        AR_PHY_TIMING11                         0x99a0
-#define        AR_PHY_TIMING11_SPUR_DELTA_PHASE        0x000FFFFF
-#define        AR_PHY_TIMING11_SPUR_DELTA_PHASE_S      0
-#define        AR_PHY_TIMING11_SPUR_FREQ_SD            0x3FF00000
-#define        AR_PHY_TIMING11_SPUR_FREQ_SD_S          20
-#define AR_PHY_TIMING11_USE_SPUR_IN_AGC                0x40000000
-#define AR_PHY_TIMING11_USE_SPUR_IN_SELFCOR    0x80000000
-
-#define AR_PHY_RX_CHAINMASK     0x99a4
-#define AR_PHY_NEW_ADC_DC_GAIN_CORR(_i) (0x99b4 + ((_i) << 12))
-#define AR_PHY_NEW_ADC_GAIN_CORR_ENABLE 0x40000000
-#define AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE 0x80000000
-#define AR_PHY_MULTICHAIN_GAIN_CTL  0x99ac
-
-#define AR_PHY_EXT_CCA0             0x99b8
-#define AR_PHY_EXT_CCA0_THRESH62    0x000000FF
-#define AR_PHY_EXT_CCA0_THRESH62_S  0
-
-#define AR_PHY_EXT_CCA                  0x99bc
-#define AR_PHY_EXT_CCA_CYCPWR_THR1      0x0000FE00
-#define AR_PHY_EXT_CCA_CYCPWR_THR1_S    9
-#define AR_PHY_EXT_CCA_THRESH62         0x007F0000
-#define AR_PHY_EXT_CCA_THRESH62_S       16
-#define AR_PHY_EXT_MINCCA_PWR           0xFF800000
-#define AR_PHY_EXT_MINCCA_PWR_S         23
-#define AR9280_PHY_EXT_MINCCA_PWR       0x01FF0000
-#define AR9280_PHY_EXT_MINCCA_PWR_S     16
-
-#define AR_PHY_SFCORR_EXT                 0x99c0
-#define AR_PHY_SFCORR_EXT_M1_THRESH       0x0000007F
-#define AR_PHY_SFCORR_EXT_M1_THRESH_S     0
-#define AR_PHY_SFCORR_EXT_M2_THRESH       0x00003F80
-#define AR_PHY_SFCORR_EXT_M2_THRESH_S     7
-#define AR_PHY_SFCORR_EXT_M1_THRESH_LOW   0x001FC000
-#define AR_PHY_SFCORR_EXT_M1_THRESH_LOW_S 14
-#define AR_PHY_SFCORR_EXT_M2_THRESH_LOW   0x0FE00000
-#define AR_PHY_SFCORR_EXT_M2_THRESH_LOW_S 21
-#define AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S   28
-
-#define AR_PHY_HALFGI           0x99D0
-#define AR_PHY_HALFGI_DSC_MAN   0x0007FFF0
-#define AR_PHY_HALFGI_DSC_MAN_S 4
-#define AR_PHY_HALFGI_DSC_EXP   0x0000000F
-#define AR_PHY_HALFGI_DSC_EXP_S 0
-
-#define AR_PHY_CHAN_INFO_MEMORY               0x99DC
-#define AR_PHY_CHAN_INFO_MEMORY_CAPTURE_MASK  0x0001
-
-#define AR_PHY_HEAVY_CLIP_ENABLE         0x99E0
-
-#define AR_PHY_M_SLEEP      0x99f0
-#define AR_PHY_REFCLKDLY    0x99f4
-#define AR_PHY_REFCLKPD     0x99f8
-
-#define AR_PHY_CALMODE      0x99f0
-
-#define AR_PHY_CALMODE_IQ           0x00000000
-#define AR_PHY_CALMODE_ADC_GAIN     0x00000001
-#define AR_PHY_CALMODE_ADC_DC_PER   0x00000002
-#define AR_PHY_CALMODE_ADC_DC_INIT  0x00000003
-
-#define AR_PHY_CAL_MEAS_0(_i)     (0x9c10 + ((_i) << 12))
-#define AR_PHY_CAL_MEAS_1(_i)     (0x9c14 + ((_i) << 12))
-#define AR_PHY_CAL_MEAS_2(_i)     (0x9c18 + ((_i) << 12))
-#define AR_PHY_CAL_MEAS_3(_i)     (0x9c1c + ((_i) << 12))
-
-#define AR_PHY_CURRENT_RSSI 0x9c1c
-#define AR9280_PHY_CURRENT_RSSI 0x9c3c
-
-#define AR_PHY_RFBUS_GRANT       0x9C20
-#define AR_PHY_RFBUS_GRANT_EN    0x00000001
-
-#define AR_PHY_CHAN_INFO_GAIN_DIFF             0x9CF4
-#define AR_PHY_CHAN_INFO_GAIN_DIFF_UPPER_LIMIT 320
-
-#define AR_PHY_CHAN_INFO_GAIN          0x9CFC
-
-#define AR_PHY_MODE         0xA200
-#define AR_PHY_MODE_AR2133  0x08
-#define AR_PHY_MODE_AR5111  0x00
-#define AR_PHY_MODE_AR5112  0x08
-#define AR_PHY_MODE_DYNAMIC 0x04
-#define AR_PHY_MODE_RF2GHZ  0x02
-#define AR_PHY_MODE_RF5GHZ  0x00
-#define AR_PHY_MODE_CCK     0x01
-#define AR_PHY_MODE_OFDM    0x00
-#define AR_PHY_MODE_DYN_CCK_DISABLE 0x100
-
-#define AR_PHY_CCK_TX_CTRL       0xA204
-#define AR_PHY_CCK_TX_CTRL_JAPAN 0x00000010
-#define AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK         0x0000000C
-#define AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK_S       2
-
-#define AR_PHY_CCK_DETECT                           0xA208
-#define AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK          0x0000003F
-#define AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK_S        0
-/* [12:6] settling time for antenna switch */
-#define AR_PHY_CCK_DETECT_ANT_SWITCH_TIME           0x00001FC0
-#define AR_PHY_CCK_DETECT_ANT_SWITCH_TIME_S         6
-#define AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV    0x2000
-
-#define AR_PHY_GAIN_2GHZ                0xA20C
-#define AR_PHY_GAIN_2GHZ_RXTX_MARGIN    0x00FC0000
-#define AR_PHY_GAIN_2GHZ_RXTX_MARGIN_S  18
-#define AR_PHY_GAIN_2GHZ_BSW_MARGIN     0x00003C00
-#define AR_PHY_GAIN_2GHZ_BSW_MARGIN_S   10
-#define AR_PHY_GAIN_2GHZ_BSW_ATTEN      0x0000001F
-#define AR_PHY_GAIN_2GHZ_BSW_ATTEN_S    0
-
-#define AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN     0x003E0000
-#define AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN_S   17
-#define AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN     0x0001F000
-#define AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN_S   12
-#define AR_PHY_GAIN_2GHZ_XATTEN2_DB         0x00000FC0
-#define AR_PHY_GAIN_2GHZ_XATTEN2_DB_S       6
-#define AR_PHY_GAIN_2GHZ_XATTEN1_DB         0x0000003F
-#define AR_PHY_GAIN_2GHZ_XATTEN1_DB_S       0
-
-#define AR_PHY_CCK_RXCTRL4  0xA21C
-#define AR_PHY_CCK_RXCTRL4_FREQ_EST_SHORT   0x01F80000
-#define AR_PHY_CCK_RXCTRL4_FREQ_EST_SHORT_S 19
-
-#define AR_PHY_DAG_CTRLCCK  0xA228
-#define AR_PHY_DAG_CTRLCCK_EN_RSSI_THR  0x00000200
-#define AR_PHY_DAG_CTRLCCK_RSSI_THR     0x0001FC00
-#define AR_PHY_DAG_CTRLCCK_RSSI_THR_S   10
-
-#define AR_PHY_FORCE_CLKEN_CCK              0xA22C
-#define AR_PHY_FORCE_CLKEN_CCK_MRC_MUX      0x00000040
-
-#define AR_PHY_POWER_TX_RATE3   0xA234
-#define AR_PHY_POWER_TX_RATE4   0xA238
-
-#define AR_PHY_SCRM_SEQ_XR       0xA23C
-#define AR_PHY_HEADER_DETECT_XR  0xA240
-#define AR_PHY_CHIRP_DETECTED_XR 0xA244
-#define AR_PHY_BLUETOOTH         0xA254
-
-#define AR_PHY_TPCRG1   0xA258
-#define AR_PHY_TPCRG1_NUM_PD_GAIN   0x0000c000
-#define AR_PHY_TPCRG1_NUM_PD_GAIN_S 14
-
-#define AR_PHY_TPCRG1_PD_GAIN_1    0x00030000
-#define AR_PHY_TPCRG1_PD_GAIN_1_S  16
-#define AR_PHY_TPCRG1_PD_GAIN_2    0x000C0000
-#define AR_PHY_TPCRG1_PD_GAIN_2_S  18
-#define AR_PHY_TPCRG1_PD_GAIN_3    0x00300000
-#define AR_PHY_TPCRG1_PD_GAIN_3_S  20
-
-#define AR_PHY_TPCRG1_PD_CAL_ENABLE   0x00400000
-#define AR_PHY_TPCRG1_PD_CAL_ENABLE_S 22
-
-#define AR_PHY_TX_PWRCTRL4       0xa264
-#define AR_PHY_TX_PWRCTRL_PD_AVG_VALID     0x00000001
-#define AR_PHY_TX_PWRCTRL_PD_AVG_VALID_S   0
-#define AR_PHY_TX_PWRCTRL_PD_AVG_OUT       0x000001FE
-#define AR_PHY_TX_PWRCTRL_PD_AVG_OUT_S     1
-
-#define AR_PHY_TX_PWRCTRL6_0     0xa270
-#define AR_PHY_TX_PWRCTRL6_1     0xb270
-#define AR_PHY_TX_PWRCTRL_ERR_EST_MODE     0x03000000
-#define AR_PHY_TX_PWRCTRL_ERR_EST_MODE_S   24
-
-#define AR_PHY_TX_PWRCTRL7       0xa274
-#define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN     0x01F80000
-#define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN_S   19
-
-#define AR_PHY_TX_PWRCTRL9       0xa27C
-#define AR_PHY_TX_DESIRED_SCALE_CCK        0x00007C00
-#define AR_PHY_TX_DESIRED_SCALE_CCK_S      10
-
-#define AR_PHY_TX_GAIN_TBL1      0xa300
-#define AR_PHY_TX_GAIN                     0x0007F000
-#define AR_PHY_TX_GAIN_S                   12
-
-#define AR_PHY_VIT_MASK2_M_46_61 0xa3a0
-#define AR_PHY_MASK2_M_31_45     0xa3a4
-#define AR_PHY_MASK2_M_16_30     0xa3a8
-#define AR_PHY_MASK2_M_00_15     0xa3ac
-#define AR_PHY_MASK2_P_15_01     0xa3b8
-#define AR_PHY_MASK2_P_30_16     0xa3bc
-#define AR_PHY_MASK2_P_45_31     0xa3c0
-#define AR_PHY_MASK2_P_61_45     0xa3c4
-#define AR_PHY_SPUR_REG          0x994c
-
-#define AR_PHY_SPUR_REG_MASK_RATE_CNTL       (0xFF << 18)
-#define AR_PHY_SPUR_REG_MASK_RATE_CNTL_S     18
-
-#define AR_PHY_SPUR_REG_ENABLE_MASK_PPM      0x20000
-#define AR_PHY_SPUR_REG_MASK_RATE_SELECT     (0xFF << 9)
-#define AR_PHY_SPUR_REG_MASK_RATE_SELECT_S   9
-#define AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI 0x100
-#define AR_PHY_SPUR_REG_SPUR_RSSI_THRESH     0x7F
-#define AR_PHY_SPUR_REG_SPUR_RSSI_THRESH_S   0
-
-#define AR_PHY_PILOT_MASK_01_30   0xa3b0
-#define AR_PHY_PILOT_MASK_31_60   0xa3b4
-
-#define AR_PHY_CHANNEL_MASK_01_30 0x99d4
-#define AR_PHY_CHANNEL_MASK_31_60 0x99d8
-
-#define AR_PHY_ANALOG_SWAP      0xa268
-#define AR_PHY_SWAP_ALT_CHAIN   0x00000040
-
-#define AR_PHY_TPCRG5   0xA26C
-#define AR_PHY_TPCRG5_PD_GAIN_OVERLAP       0x0000000F
-#define AR_PHY_TPCRG5_PD_GAIN_OVERLAP_S     0
-#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1    0x000003F0
-#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1_S  4
-#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2    0x0000FC00
-#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2_S  10
-#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3    0x003F0000
-#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3_S  16
-#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4    0x0FC00000
-#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4_S  22
-
-/* Carrier leak calibration control, do it after AGC calibration */
-#define AR_PHY_CL_CAL_CTL       0xA358
-#define AR_PHY_CL_CAL_ENABLE    0x00000002
-#define AR_PHY_PARALLEL_CAL_ENABLE    0x00000001
-
-#define AR_PHY_POWER_TX_RATE5   0xA38C
-#define AR_PHY_POWER_TX_RATE6   0xA390
-
-#define AR_PHY_CAL_CHAINMASK    0xA39C
-
-#define AR_PHY_POWER_TX_SUB     0xA3C8
-#define AR_PHY_POWER_TX_RATE7   0xA3CC
-#define AR_PHY_POWER_TX_RATE8   0xA3D0
-#define AR_PHY_POWER_TX_RATE9   0xA3D4
-
-#define AR_PHY_XPA_CFG         0xA3D8
-#define AR_PHY_FORCE_XPA_CFG   0x000000001
-#define AR_PHY_FORCE_XPA_CFG_S 0
-
-#define AR_PHY_CH1_CCA          0xa864
-#define AR_PHY_CH1_MINCCA_PWR   0x0FF80000
-#define AR_PHY_CH1_MINCCA_PWR_S 19
-#define AR9280_PHY_CH1_MINCCA_PWR   0x1FF00000
-#define AR9280_PHY_CH1_MINCCA_PWR_S 20
-
-#define AR_PHY_CH2_CCA          0xb864
-#define AR_PHY_CH2_MINCCA_PWR   0x0FF80000
-#define AR_PHY_CH2_MINCCA_PWR_S 19
-
-#define AR_PHY_CH1_EXT_CCA          0xa9bc
-#define AR_PHY_CH1_EXT_MINCCA_PWR   0xFF800000
-#define AR_PHY_CH1_EXT_MINCCA_PWR_S 23
-#define AR9280_PHY_CH1_EXT_MINCCA_PWR   0x01FF0000
-#define AR9280_PHY_CH1_EXT_MINCCA_PWR_S 16
-
-#define AR_PHY_CH2_EXT_CCA          0xb9bc
-#define AR_PHY_CH2_EXT_MINCCA_PWR   0xFF800000
-#define AR_PHY_CH2_EXT_MINCCA_PWR_S 23
-
-#define REG_WRITE_RF_ARRAY(iniarray, regData, regWr) do {               \
-               int r;                                                  \
-               for (r = 0; r < ((iniarray)->ia_rows); r++) {           \
-                       REG_WRITE(ah, INI_RA((iniarray), r, 0), (regData)[r]); \
-                       DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, \
-                               "RF 0x%x V 0x%x\n", \
-                               INI_RA((iniarray), r, 0), (regData)[r]); \
-                       DO_DELAY(regWr);                                \
-               }                                                       \
-       } while (0)
-
-#define ATH9K_IS_MIC_ENABLED(ah)                                       \
-       ((ah)->sta_id1_defaults & AR_STA_ID1_CRPT_MIC_ENABLE)
-
-#define ANTSWAP_AB 0x0001
-#define REDUCE_CHAIN_0 0x00000050
-#define REDUCE_CHAIN_1 0x00000051
-
-#define RF_BANK_SETUP(_bank, _iniarray, _col) do {                     \
-               int i;                                                  \
-               for (i = 0; i < (_iniarray)->ia_rows; i++)              \
-                       (_bank)[i] = INI_RA((_iniarray), i, _col);;     \
-       } while (0)
-
-#endif
diff --git a/drivers/net/wireless/ath9k/rc.c b/drivers/net/wireless/ath9k/rc.c
deleted file mode 100644 (file)
index 824ccbb..0000000
+++ /dev/null
@@ -1,1756 +0,0 @@
-/*
- * Copyright (c) 2004 Video54 Technologies, Inc.
- * Copyright (c) 2004-2009 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 "ath9k.h"
-
-static struct ath_rate_table ar5416_11na_ratetable = {
-       42,
-       {
-               { VALID, VALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
-                       5400, 0x0b, 0x00, 12,
-                       0, 2, 1, 0, 0, 0, 0, 0 },
-               { VALID, VALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
-                       7800,  0x0f, 0x00, 18,
-                       0, 3, 1, 1, 1, 1, 1, 0 },
-               { VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
-                       10000, 0x0a, 0x00, 24,
-                       2, 4, 2, 2, 2, 2, 2, 0 },
-               { VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
-                       13900, 0x0e, 0x00, 36,
-                       2, 6,  2, 3, 3, 3, 3, 0 },
-               { VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
-                       17300, 0x09, 0x00, 48,
-                       4, 10, 3, 4, 4, 4, 4, 0 },
-               { VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
-                       23000, 0x0d, 0x00, 72,
-                       4, 14, 3, 5, 5, 5, 5, 0 },
-               { VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
-                       27400, 0x08, 0x00, 96,
-                       4, 20, 3, 6, 6, 6, 6, 0 },
-               { VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
-                       29300, 0x0c, 0x00, 108,
-                       4, 23, 3, 7, 7, 7, 7, 0 },
-               { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 6500, /* 6.5 Mb */
-                       6400, 0x80, 0x00, 0,
-                       0, 2, 3, 8, 24, 8, 24, 3216 },
-               { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 13000, /* 13 Mb */
-                       12700, 0x81, 0x00, 1,
-                       2, 4, 3, 9, 25, 9, 25, 6434 },
-               { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 19500, /* 19.5 Mb */
-                       18800, 0x82, 0x00, 2,
-                       2, 6, 3, 10, 26, 10, 26, 9650 },
-               { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 26000, /* 26 Mb */
-                       25000, 0x83, 0x00, 3,
-                       4, 10, 3, 11, 27, 11, 27, 12868 },
-               { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 39000, /* 39 Mb */
-                       36700, 0x84, 0x00, 4,
-                       4, 14, 3, 12, 28, 12, 28, 19304 },
-               { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 52000, /* 52 Mb */
-                       48100, 0x85, 0x00, 5,
-                       4, 20, 3, 13, 29, 13, 29, 25740 },
-               { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 58500, /* 58.5 Mb */
-                       53500, 0x86, 0x00, 6,
-                       4, 23, 3, 14, 30, 14, 30,  28956 },
-               { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 65000, /* 65 Mb */
-                       59000, 0x87, 0x00, 7,
-                       4, 25, 3, 15, 31, 15, 32, 32180 },
-               { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 13000, /* 13 Mb */
-                       12700, 0x88, 0x00,
-                       8, 0, 2, 3, 16, 33, 16, 33, 6430 },
-               { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 26000, /* 26 Mb */
-                       24800, 0x89, 0x00, 9,
-                       2, 4, 3, 17, 34, 17, 34, 12860 },
-               { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 39000, /* 39 Mb */
-                       36600, 0x8a, 0x00, 10,
-                       2, 6, 3, 18, 35, 18, 35, 19300 },
-               { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 52000, /* 52 Mb */
-                       48100, 0x8b, 0x00, 11,
-                       4, 10, 3, 19, 36, 19, 36, 25736 },
-               { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 78000, /* 78 Mb */
-                       69500, 0x8c, 0x00, 12,
-                       4, 14, 3, 20, 37, 20, 37, 38600 },
-               { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 104000, /* 104 Mb */
-                       89500, 0x8d, 0x00, 13,
-                       4, 20, 3, 21, 38, 21, 38, 51472 },
-               { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 117000, /* 117 Mb */
-                       98900, 0x8e, 0x00, 14,
-                       4, 23, 3, 22, 39, 22, 39, 57890 },
-               { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 130000, /* 130 Mb */
-                       108300, 0x8f, 0x00, 15,
-                       4, 25, 3, 23, 40, 23, 41, 64320 },
-               { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 13500, /* 13.5 Mb */
-                       13200, 0x80, 0x00, 0,
-                       0, 2, 3, 8, 24, 24, 24, 6684 },
-               { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 27500, /* 27.0 Mb */
-                       25900, 0x81, 0x00, 1,
-                       2, 4, 3, 9, 25, 25, 25, 13368 },
-               { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 40500, /* 40.5 Mb */
-                       38600, 0x82, 0x00, 2,
-                       2, 6, 3, 10, 26, 26, 26, 20052 },
-               { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 54000, /* 54 Mb */
-                       49800, 0x83, 0x00, 3,
-                       4, 10, 3, 11, 27, 27, 27, 26738 },
-               { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 81500, /* 81 Mb */
-                       72200, 0x84, 0x00, 4,
-                       4, 14, 3, 12, 28, 28, 28, 40104 },
-               { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 108000, /* 108 Mb */
-                       92900, 0x85, 0x00, 5,
-                       4, 20, 3, 13, 29, 29, 29, 53476 },
-               { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 121500, /* 121.5 Mb */
-                       102700, 0x86, 0x00, 6,
-                       4, 23, 3, 14, 30, 30, 30, 60156 },
-               { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 135000, /* 135 Mb */
-                       112000, 0x87, 0x00, 7,
-                       4, 25, 3, 15, 31, 32, 32, 66840 },
-               { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000, /* 150 Mb */
-                       122000, 0x87, 0x00, 7,
-                       4, 25, 3, 15, 31, 32, 32, 74200 },
-               { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 27000, /* 27 Mb */
-                       25800, 0x88, 0x00, 8,
-                       0, 2, 3, 16, 33, 33, 33, 13360 },
-               { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 54000, /* 54 Mb */
-                       49800, 0x89, 0x00, 9,
-                       2, 4, 3, 17, 34, 34, 34, 26720 },
-               { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 81000, /* 81 Mb */
-                       71900, 0x8a, 0x00, 10,
-                       2, 6, 3, 18, 35, 35, 35, 40080 },
-               { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 108000, /* 108 Mb */
-                       92500, 0x8b, 0x00, 11,
-                       4, 10, 3, 19, 36, 36, 36, 53440 },
-               { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 162000, /* 162 Mb */
-                       130300, 0x8c, 0x00, 12,
-                       4, 14, 3, 20, 37, 37, 37, 80160 },
-               { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 216000, /* 216 Mb */
-                       162800, 0x8d, 0x00, 13,
-                       4, 20, 3, 21, 38, 38, 38, 106880 },
-               { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 243000, /* 243 Mb */
-                       178200, 0x8e, 0x00, 14,
-                       4, 23, 3, 22, 39, 39, 39, 120240 },
-               { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 270000, /* 270 Mb */
-                       192100, 0x8f, 0x00, 15,
-                       4, 25, 3, 23, 40, 41, 41, 133600 },
-               { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS_HGI, 300000, /* 300 Mb */
-                       207000, 0x8f, 0x00, 15,
-                       4, 25, 3, 23, 40, 41, 41, 148400 },
-       },
-       50,  /* probe interval */
-       50,  /* rssi reduce interval */
-       WLAN_RC_HT_FLAG,  /* Phy rates allowed initially */
-};
-
-/* 4ms frame limit not used for NG mode.  The values filled
- * for HT are the 64K max aggregate limit */
-
-static struct ath_rate_table ar5416_11ng_ratetable = {
-       46,
-       {
-               { VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */
-                       900, 0x1b, 0x00, 2,
-                       0, 0, 1, 0, 0, 0, 0, 0 },
-               { VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */
-                       1900, 0x1a, 0x04, 4,
-                       1, 1, 1, 1, 1, 1, 1, 0 },
-               { VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */
-                       4900, 0x19, 0x04, 11,
-                       2, 2, 2, 2, 2, 2, 2, 0 },
-               { VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */
-                       8100, 0x18, 0x04, 22,
-                       3, 3, 2, 3, 3, 3, 3, 0 },
-               { INVALID, INVALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
-                       5400, 0x0b, 0x00, 12,
-                       4, 2, 1, 4, 4, 4, 4, 0 },
-               { INVALID, INVALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
-                       7800, 0x0f, 0x00, 18,
-                       4, 3, 1, 5, 5, 5, 5, 0 },
-               { VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
-                       10100, 0x0a, 0x00, 24,
-                       6, 4, 1, 6, 6, 6, 6, 0 },
-               { VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
-                       14100,  0x0e, 0x00, 36,
-                       6, 6, 2, 7, 7, 7, 7, 0 },
-               { VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
-                       17700, 0x09, 0x00, 48,
-                       8, 10, 3, 8, 8, 8, 8, 0 },
-               { VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
-                       23700, 0x0d, 0x00, 72,
-                       8, 14, 3, 9, 9, 9, 9, 0 },
-               { VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
-                       27400, 0x08, 0x00, 96,
-                       8, 20, 3, 10, 10, 10, 10, 0 },
-               { VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
-                       30900, 0x0c, 0x00, 108,
-                       8, 23, 3, 11, 11, 11, 11, 0 },
-               { INVALID, INVALID, WLAN_RC_PHY_HT_20_SS, 6500, /* 6.5 Mb */
-                       6400, 0x80, 0x00, 0,
-                       4, 2, 3, 12, 28, 12, 28, 3216 },
-               { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 13000, /* 13 Mb */
-                       12700, 0x81, 0x00, 1,
-                       6, 4, 3, 13, 29, 13, 29, 6434 },
-               { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 19500, /* 19.5 Mb */
-                       18800, 0x82, 0x00, 2,
-                       6, 6, 3, 14, 30, 14, 30, 9650 },
-               { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 26000, /* 26 Mb */
-                       25000, 0x83, 0x00, 3,
-                       8, 10, 3, 15, 31, 15, 31, 12868 },
-               { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 39000, /* 39 Mb */
-                       36700, 0x84, 0x00, 4,
-                       8, 14, 3, 16, 32, 16, 32, 19304 },
-               { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 52000, /* 52 Mb */
-                       48100, 0x85, 0x00, 5,
-                       8, 20, 3, 17, 33, 17, 33, 25740 },
-               { INVALID,  VALID_20, WLAN_RC_PHY_HT_20_SS, 58500, /* 58.5 Mb */
-                       53500, 0x86, 0x00, 6,
-                       8, 23, 3, 18, 34, 18, 34, 28956 },
-               { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 65000, /* 65 Mb */
-                       59000, 0x87, 0x00, 7,
-                       8, 25, 3, 19, 35, 19, 36, 32180 },
-               { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 13000, /* 13 Mb */
-                       12700, 0x88, 0x00, 8,
-                       4, 2, 3, 20, 37, 20, 37, 6430 },
-               { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 26000, /* 26 Mb */
-                       24800, 0x89, 0x00, 9,
-                       6, 4, 3, 21, 38, 21, 38, 12860 },
-               { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 39000, /* 39 Mb */
-                       36600, 0x8a, 0x00, 10,
-                       6, 6, 3, 22, 39, 22, 39, 19300 },
-               { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 52000, /* 52 Mb */
-                       48100, 0x8b, 0x00, 11,
-                       8, 10, 3, 23, 40, 23, 40, 25736 },
-               { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 78000, /* 78 Mb */
-                       69500, 0x8c, 0x00, 12,
-                       8, 14, 3, 24, 41, 24, 41, 38600 },
-               { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 104000, /* 104 Mb */
-                       89500, 0x8d, 0x00, 13,
-                       8, 20, 3, 25, 42, 25, 42, 51472 },
-               { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 117000, /* 117 Mb */
-                       98900, 0x8e, 0x00, 14,
-                       8, 23, 3, 26, 43, 26, 44, 57890 },
-               { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 130000, /* 130 Mb */
-                       108300, 0x8f, 0x00, 15,
-                       8, 25, 3, 27, 44, 27, 45, 64320 },
-               { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 13500, /* 13.5 Mb */
-                       13200, 0x80, 0x00, 0,
-                       8, 2, 3, 12, 28, 28, 28, 6684 },
-               { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 27500, /* 27.0 Mb */
-                       25900, 0x81, 0x00, 1,
-                       8, 4, 3, 13, 29, 29, 29, 13368 },
-               { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 40500, /* 40.5 Mb */
-                       38600, 0x82, 0x00, 2,
-                       8, 6, 3, 14, 30, 30, 30, 20052 },
-               { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 54000, /* 54 Mb */
-                       49800, 0x83, 0x00, 3,
-                       8, 10, 3, 15, 31, 31, 31, 26738 },
-               { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 81500, /* 81 Mb */
-                       72200, 0x84, 0x00, 4,
-                       8, 14, 3, 16, 32, 32, 32, 40104 },
-               { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 108000, /* 108 Mb */
-                       92900, 0x85, 0x00, 5,
-                       8, 20, 3, 17, 33, 33, 33, 53476 },
-               { INVALID,  VALID_40, WLAN_RC_PHY_HT_40_SS, 121500, /* 121.5 Mb */
-                       102700, 0x86, 0x00, 6,
-                       8, 23, 3, 18, 34, 34, 34, 60156 },
-               { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 135000, /* 135 Mb */
-                       112000, 0x87, 0x00, 7,
-                       8, 23, 3, 19, 35, 36, 36, 66840 },
-               { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000, /* 150 Mb */
-                       122000, 0x87, 0x00, 7,
-                       8, 25, 3, 19, 35, 36, 36, 74200 },
-               { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 27000, /* 27 Mb */
-                       25800, 0x88, 0x00, 8,
-                       8, 2, 3, 20, 37, 37, 37, 13360 },
-               { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 54000, /* 54 Mb */
-                       49800, 0x89, 0x00, 9,
-                       8, 4, 3, 21, 38, 38, 38, 26720 },
-               { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 81000, /* 81 Mb */
-                       71900, 0x8a, 0x00, 10,
-                       8, 6, 3, 22, 39, 39, 39, 40080 },
-               { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 108000, /* 108 Mb */
-                       92500, 0x8b, 0x00, 11,
-                       8, 10, 3, 23, 40, 40, 40, 53440 },
-               { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 162000, /* 162 Mb */
-                       130300, 0x8c, 0x00, 12,
-                       8, 14, 3, 24, 41, 41, 41, 80160 },
-               { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 216000, /* 216 Mb */
-                       162800, 0x8d, 0x00, 13,
-                       8, 20, 3, 25, 42, 42, 42, 106880 },
-               { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 243000, /* 243 Mb */
-                       178200, 0x8e, 0x00, 14,
-                       8, 23, 3, 26, 43, 43, 43, 120240 },
-               { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 270000, /* 270 Mb */
-                       192100, 0x8f, 0x00, 15,
-                       8, 23, 3, 27, 44, 45, 45, 133600 },
-               { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS_HGI, 300000, /* 300 Mb */
-                       207000, 0x8f, 0x00, 15,
-                       8, 25, 3, 27, 44, 45, 45, 148400 },
-               },
-       50,  /* probe interval */
-       50,  /* rssi reduce interval */
-       WLAN_RC_HT_FLAG,  /* Phy rates allowed initially */
-};
-
-static struct ath_rate_table ar5416_11a_ratetable = {
-       8,
-       {
-               { VALID, VALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
-                       5400, 0x0b, 0x00, (0x80|12),
-                       0, 2, 1, 0, 0 },
-               { VALID, VALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
-                       7800, 0x0f, 0x00, 18,
-                       0, 3, 1, 1, 0 },
-               { VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
-                       10000, 0x0a, 0x00, (0x80|24),
-                       2, 4, 2, 2, 0 },
-               { VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
-                       13900, 0x0e, 0x00, 36,
-                       2, 6, 2, 3, 0 },
-               { VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
-                       17300, 0x09, 0x00, (0x80|48),
-                       4, 10, 3, 4, 0 },
-               { VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
-                       23000, 0x0d, 0x00, 72,
-                       4, 14, 3, 5, 0 },
-               { VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
-                       27400, 0x08, 0x00, 96,
-                       4, 19, 3, 6, 0 },
-               { VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
-                       29300, 0x0c, 0x00, 108,
-                       4, 23, 3, 7, 0 },
-       },
-       50,  /* probe interval */
-       50,  /* rssi reduce interval */
-       0,   /* Phy rates allowed initially */
-};
-
-static struct ath_rate_table ar5416_11g_ratetable = {
-       12,
-       {
-               { VALID, VALID, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */
-                       900, 0x1b, 0x00, 2,
-                       0, 0, 1, 0, 0 },
-               { VALID, VALID, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */
-                       1900, 0x1a, 0x04, 4,
-                       1, 1, 1, 1, 0 },
-               { VALID, VALID, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */
-                       4900, 0x19, 0x04, 11,
-                       2, 2, 2, 2, 0 },
-               { VALID, VALID, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */
-                       8100, 0x18, 0x04, 22,
-                       3, 3, 2, 3, 0 },
-               { INVALID, INVALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
-                       5400, 0x0b, 0x00, 12,
-                       4, 2, 1, 4, 0 },
-               { INVALID, INVALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
-                       7800, 0x0f, 0x00, 18,
-                       4, 3, 1, 5, 0 },
-               { VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
-                       10000, 0x0a, 0x00, 24,
-                       6, 4, 1, 6, 0 },
-               { VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
-                       13900, 0x0e, 0x00, 36,
-                       6, 6, 2, 7, 0 },
-               { VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
-                       17300, 0x09, 0x00, 48,
-                       8, 10, 3, 8, 0 },
-               { VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
-                       23000, 0x0d, 0x00, 72,
-                       8, 14, 3, 9, 0 },
-               { VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
-                       27400, 0x08, 0x00, 96,
-                       8, 19, 3, 10, 0 },
-               { VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
-                       29300, 0x0c, 0x00, 108,
-                       8, 23, 3, 11, 0 },
-       },
-       50,  /* probe interval */
-       50,  /* rssi reduce interval */
-       0,   /* Phy rates allowed initially */
-};
-
-static struct ath_rate_table ar5416_11b_ratetable = {
-       4,
-       {
-               { VALID, VALID, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */
-                       900, 0x1b,  0x00, (0x80|2),
-                       0, 0, 1, 0, 0 },
-               { VALID, VALID, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */
-                       1800, 0x1a, 0x04, (0x80|4),
-                       1, 1, 1, 1, 0 },
-               { VALID, VALID, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */
-                       4300, 0x19, 0x04, (0x80|11),
-                       1, 2, 2, 2, 0 },
-               { VALID, VALID, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */
-                       7100, 0x18, 0x04, (0x80|22),
-                       1, 4, 100, 3, 0 },
-       },
-       100, /* probe interval */
-       100, /* rssi reduce interval */
-       0,   /* Phy rates allowed initially */
-};
-
-static inline int8_t median(int8_t a, int8_t b, int8_t c)
-{
-       if (a >= b) {
-               if (b >= c)
-                       return b;
-               else if (a > c)
-                       return c;
-               else
-                       return a;
-       } else {
-               if (a >= c)
-                       return a;
-               else if (b >= c)
-                       return c;
-               else
-                       return b;
-       }
-}
-
-static void ath_rc_sort_validrates(struct ath_rate_table *rate_table,
-                                  struct ath_rate_priv *ath_rc_priv)
-{
-       u8 i, j, idx, idx_next;
-
-       for (i = ath_rc_priv->max_valid_rate - 1; i > 0; i--) {
-               for (j = 0; j <= i-1; j++) {
-                       idx = ath_rc_priv->valid_rate_index[j];
-                       idx_next = ath_rc_priv->valid_rate_index[j+1];
-
-                       if (rate_table->info[idx].ratekbps >
-                               rate_table->info[idx_next].ratekbps) {
-                               ath_rc_priv->valid_rate_index[j] = idx_next;
-                               ath_rc_priv->valid_rate_index[j+1] = idx;
-                       }
-               }
-       }
-}
-
-static void ath_rc_init_valid_txmask(struct ath_rate_priv *ath_rc_priv)
-{
-       u8 i;
-
-       for (i = 0; i < ath_rc_priv->rate_table_size; i++)
-               ath_rc_priv->valid_rate_index[i] = 0;
-}
-
-static inline void ath_rc_set_valid_txmask(struct ath_rate_priv *ath_rc_priv,
-                                          u8 index, int valid_tx_rate)
-{
-       ASSERT(index <= ath_rc_priv->rate_table_size);
-       ath_rc_priv->valid_rate_index[index] = valid_tx_rate ? 1 : 0;
-}
-
-static inline int ath_rc_isvalid_txmask(struct ath_rate_priv *ath_rc_priv,
-                                       u8 index)
-{
-       ASSERT(index <= ath_rc_priv->rate_table_size);
-       return ath_rc_priv->valid_rate_index[index];
-}
-
-static inline int ath_rc_get_nextvalid_txrate(struct ath_rate_table *rate_table,
-                                             struct ath_rate_priv *ath_rc_priv,
-                                             u8 cur_valid_txrate,
-                                             u8 *next_idx)
-{
-       u8 i;
-
-       for (i = 0; i < ath_rc_priv->max_valid_rate - 1; i++) {
-               if (ath_rc_priv->valid_rate_index[i] == cur_valid_txrate) {
-                       *next_idx = ath_rc_priv->valid_rate_index[i+1];
-                       return 1;
-               }
-       }
-
-       /* No more valid rates */
-       *next_idx = 0;
-
-       return 0;
-}
-
-/* Return true only for single stream */
-
-static int ath_rc_valid_phyrate(u32 phy, u32 capflag, int ignore_cw)
-{
-       if (WLAN_RC_PHY_HT(phy) && !(capflag & WLAN_RC_HT_FLAG))
-               return 0;
-       if (WLAN_RC_PHY_DS(phy) && !(capflag & WLAN_RC_DS_FLAG))
-               return 0;
-       if (WLAN_RC_PHY_SGI(phy) && !(capflag & WLAN_RC_SGI_FLAG))
-               return 0;
-       if (!ignore_cw && WLAN_RC_PHY_HT(phy))
-               if (WLAN_RC_PHY_40(phy) && !(capflag & WLAN_RC_40_FLAG))
-                       return 0;
-               if (!WLAN_RC_PHY_40(phy) && (capflag & WLAN_RC_40_FLAG))
-                       return 0;
-       return 1;
-}
-
-static inline int
-ath_rc_get_nextlowervalid_txrate(struct ath_rate_table *rate_table,
-                                struct ath_rate_priv *ath_rc_priv,
-                                u8 cur_valid_txrate, u8 *next_idx)
-{
-       int8_t i;
-
-       for (i = 1; i < ath_rc_priv->max_valid_rate ; i++) {
-               if (ath_rc_priv->valid_rate_index[i] == cur_valid_txrate) {
-                       *next_idx = ath_rc_priv->valid_rate_index[i-1];
-                       return 1;
-               }
-       }
-
-       return 0;
-}
-
-static u8 ath_rc_init_validrates(struct ath_rate_priv *ath_rc_priv,
-                                struct ath_rate_table *rate_table,
-                                u32 capflag)
-{
-       u8 i, hi = 0;
-       u32 valid;
-
-       for (i = 0; i < rate_table->rate_cnt; i++) {
-               valid = (ath_rc_priv->single_stream ?
-                        rate_table->info[i].valid_single_stream :
-                        rate_table->info[i].valid);
-               if (valid == 1) {
-                       u32 phy = rate_table->info[i].phy;
-                       u8 valid_rate_count = 0;
-
-                       if (!ath_rc_valid_phyrate(phy, capflag, 0))
-                               continue;
-
-                       valid_rate_count = ath_rc_priv->valid_phy_ratecnt[phy];
-
-                       ath_rc_priv->valid_phy_rateidx[phy][valid_rate_count] = i;
-                       ath_rc_priv->valid_phy_ratecnt[phy] += 1;
-                       ath_rc_set_valid_txmask(ath_rc_priv, i, 1);
-                       hi = A_MAX(hi, i);
-               }
-       }
-
-       return hi;
-}
-
-static u8 ath_rc_setvalid_rates(struct ath_rate_priv *ath_rc_priv,
-                               struct ath_rate_table *rate_table,
-                               struct ath_rateset *rateset,
-                               u32 capflag)
-{
-       u8 i, j, hi = 0;
-
-       /* Use intersection of working rates and valid rates */
-       for (i = 0; i < rateset->rs_nrates; i++) {
-               for (j = 0; j < rate_table->rate_cnt; j++) {
-                       u32 phy = rate_table->info[j].phy;
-                       u32 valid = (ath_rc_priv->single_stream ?
-                               rate_table->info[j].valid_single_stream :
-                               rate_table->info[j].valid);
-                       u8 rate = rateset->rs_rates[i];
-                       u8 dot11rate = rate_table->info[j].dot11rate;
-
-                       /* We allow a rate only if its valid and the
-                        * capflag matches one of the validity
-                        * (VALID/VALID_20/VALID_40) flags */
-
-                       if (((rate & 0x7F) == (dot11rate & 0x7F)) &&
-                           ((valid & WLAN_RC_CAP_MODE(capflag)) ==
-                            WLAN_RC_CAP_MODE(capflag)) &&
-                           !WLAN_RC_PHY_HT(phy)) {
-                               u8 valid_rate_count = 0;
-
-                               if (!ath_rc_valid_phyrate(phy, capflag, 0))
-                                       continue;
-
-                               valid_rate_count =
-                                       ath_rc_priv->valid_phy_ratecnt[phy];
-
-                               ath_rc_priv->valid_phy_rateidx[phy]
-                                       [valid_rate_count] = j;
-                               ath_rc_priv->valid_phy_ratecnt[phy] += 1;
-                               ath_rc_set_valid_txmask(ath_rc_priv, j, 1);
-                               hi = A_MAX(hi, j);
-                       }
-               }
-       }
-
-       return hi;
-}
-
-static u8 ath_rc_setvalid_htrates(struct ath_rate_priv *ath_rc_priv,
-                                 struct ath_rate_table *rate_table,
-                                 u8 *mcs_set, u32 capflag)
-{
-       struct ath_rateset *rateset = (struct ath_rateset *)mcs_set;
-
-       u8 i, j, hi = 0;
-
-       /* Use intersection of working rates and valid rates */
-       for (i = 0; i < rateset->rs_nrates; i++) {
-               for (j = 0; j < rate_table->rate_cnt; j++) {
-                       u32 phy = rate_table->info[j].phy;
-                       u32 valid = (ath_rc_priv->single_stream ?
-                                    rate_table->info[j].valid_single_stream :
-                                    rate_table->info[j].valid);
-                       u8 rate = rateset->rs_rates[i];
-                       u8 dot11rate = rate_table->info[j].dot11rate;
-
-                       if (((rate & 0x7F) != (dot11rate & 0x7F)) ||
-                           !WLAN_RC_PHY_HT(phy) ||
-                           !WLAN_RC_PHY_HT_VALID(valid, capflag))
-                               continue;
-
-                       if (!ath_rc_valid_phyrate(phy, capflag, 0))
-                               continue;
-
-                       ath_rc_priv->valid_phy_rateidx[phy]
-                               [ath_rc_priv->valid_phy_ratecnt[phy]] = j;
-                       ath_rc_priv->valid_phy_ratecnt[phy] += 1;
-                       ath_rc_set_valid_txmask(ath_rc_priv, j, 1);
-                       hi = A_MAX(hi, j);
-               }
-       }
-
-       return hi;
-}
-
-static u8 ath_rc_ratefind_ht(struct ath_softc *sc,
-                            struct ath_rate_priv *ath_rc_priv,
-                            struct ath_rate_table *rate_table,
-                            int *is_probing)
-{
-       u32 dt, best_thruput, this_thruput, now_msec;
-       u8 rate, next_rate, best_rate, maxindex, minindex;
-       int8_t  rssi_last, rssi_reduce = 0, index = 0;
-
-       *is_probing = 0;
-
-       rssi_last = median(ath_rc_priv->rssi_last,
-                          ath_rc_priv->rssi_last_prev,
-                          ath_rc_priv->rssi_last_prev2);
-
-       /*
-        * Age (reduce) last ack rssi based on how old it is.
-        * The bizarre numbers are so the delta is 160msec,
-        * meaning we divide by 16.
-        *   0msec   <= dt <= 25msec:   don't derate
-        *   25msec  <= dt <= 185msec:  derate linearly from 0 to 10dB
-        *   185msec <= dt:             derate by 10dB
-        */
-
-       now_msec = jiffies_to_msecs(jiffies);
-       dt = now_msec - ath_rc_priv->rssi_time;
-
-       if (dt >= 185)
-               rssi_reduce = 10;
-       else if (dt >= 25)
-               rssi_reduce = (u8)((dt - 25) >> 4);
-
-       /* Now reduce rssi_last by rssi_reduce */
-       if (rssi_last < rssi_reduce)
-               rssi_last = 0;
-       else
-               rssi_last -= rssi_reduce;
-
-       /*
-        * Now look up the rate in the rssi table and return it.
-        * If no rates match then we return 0 (lowest rate)
-        */
-
-       best_thruput = 0;
-       maxindex = ath_rc_priv->max_valid_rate-1;
-
-       minindex = 0;
-       best_rate = minindex;
-
-       /*
-        * Try the higher rate first. It will reduce memory moving time
-        * if we have very good channel characteristics.
-        */
-       for (index = maxindex; index >= minindex ; index--) {
-               u8 per_thres;
-
-               rate = ath_rc_priv->valid_rate_index[index];
-               if (rate > ath_rc_priv->rate_max_phy)
-                       continue;
-
-               /*
-                * For TCP the average collision rate is around 11%,
-                * so we ignore PERs less than this.  This is to
-                * prevent the rate we are currently using (whose
-                * PER might be in the 10-15 range because of TCP
-                * collisions) looking worse than the next lower
-                * rate whose PER has decayed close to 0.  If we
-                * used to next lower rate, its PER would grow to
-                * 10-15 and we would be worse off then staying
-                * at the current rate.
-                */
-               per_thres = ath_rc_priv->state[rate].per;
-               if (per_thres < 12)
-                       per_thres = 12;
-
-               this_thruput = rate_table->info[rate].user_ratekbps *
-                       (100 - per_thres);
-
-               if (best_thruput <= this_thruput) {
-                       best_thruput = this_thruput;
-                       best_rate    = rate;
-               }
-       }
-
-       rate = best_rate;
-       ath_rc_priv->rssi_last_lookup = rssi_last;
-
-       /*
-        * Must check the actual rate (ratekbps) to account for
-        * non-monoticity of 11g's rate table
-        */
-
-       if (rate >= ath_rc_priv->rate_max_phy) {
-               rate = ath_rc_priv->rate_max_phy;
-
-               /* Probe the next allowed phy state */
-               if (ath_rc_get_nextvalid_txrate(rate_table,
-                                       ath_rc_priv, rate, &next_rate) &&
-                   (now_msec - ath_rc_priv->probe_time >
-                    rate_table->probe_interval) &&
-                   (ath_rc_priv->hw_maxretry_pktcnt >= 1)) {
-                       rate = next_rate;
-                       ath_rc_priv->probe_rate = rate;
-                       ath_rc_priv->probe_time = now_msec;
-                       ath_rc_priv->hw_maxretry_pktcnt = 0;
-                       *is_probing = 1;
-               }
-       }
-
-       if (rate > (ath_rc_priv->rate_table_size - 1))
-               rate = ath_rc_priv->rate_table_size - 1;
-
-       ASSERT((rate_table->info[rate].valid && !ath_rc_priv->single_stream) ||
-              (rate_table->info[rate].valid_single_stream &&
-               ath_rc_priv->single_stream));
-
-       return rate;
-}
-
-static void ath_rc_rate_set_series(struct ath_rate_table *rate_table,
-                                  struct ieee80211_tx_rate *rate,
-                                  struct ieee80211_tx_rate_control *txrc,
-                                  u8 tries, u8 rix, int rtsctsenable)
-{
-       rate->count = tries;
-       rate->idx = rix;
-
-       if (txrc->short_preamble)
-               rate->flags |= IEEE80211_TX_RC_USE_SHORT_PREAMBLE;
-       if (txrc->rts || rtsctsenable)
-               rate->flags |= IEEE80211_TX_RC_USE_RTS_CTS;
-       if (WLAN_RC_PHY_40(rate_table->info[rix].phy))
-               rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
-       if (WLAN_RC_PHY_SGI(rate_table->info[rix].phy))
-               rate->flags |= IEEE80211_TX_RC_SHORT_GI;
-       if (WLAN_RC_PHY_HT(rate_table->info[rix].phy))
-               rate->flags |= IEEE80211_TX_RC_MCS;
-}
-
-static void ath_rc_rate_set_rtscts(struct ath_softc *sc,
-                                  struct ath_rate_table *rate_table,
-                                  struct ieee80211_tx_info *tx_info)
-{
-       struct ieee80211_tx_rate *rates = tx_info->control.rates;
-       int i = 0, rix = 0, cix, enable_g_protection = 0;
-
-       /* get the cix for the lowest valid rix */
-       for (i = 3; i >= 0; i--) {
-               if (rates[i].count && (rates[i].idx >= 0)) {
-                       rix = rates[i].idx;
-                       break;
-               }
-       }
-       cix = rate_table->info[rix].ctrl_rate;
-
-       /* All protection frames are transmited at 2Mb/s for 802.11g,
-        * otherwise we transmit them at 1Mb/s */
-       if (sc->hw->conf.channel->band == IEEE80211_BAND_2GHZ &&
-           !conf_is_ht(&sc->hw->conf))
-               enable_g_protection = 1;
-
-       /*
-        * If 802.11g protection is enabled, determine whether to use RTS/CTS or
-        * just CTS.  Note that this is only done for OFDM/HT unicast frames.
-        */
-       if ((sc->sc_flags & SC_OP_PROTECT_ENABLE) &&
-           !(tx_info->flags & IEEE80211_TX_CTL_NO_ACK) &&
-           (rate_table->info[rix].phy == WLAN_RC_PHY_OFDM ||
-            WLAN_RC_PHY_HT(rate_table->info[rix].phy))) {
-               rates[0].flags |= IEEE80211_TX_RC_USE_CTS_PROTECT;
-               cix = rate_table->info[enable_g_protection].ctrl_rate;
-       }
-
-       tx_info->control.rts_cts_rate_idx = cix;
-}
-
-static u8 ath_rc_rate_getidx(struct ath_softc *sc,
-                            struct ath_rate_priv *ath_rc_priv,
-                            struct ath_rate_table *rate_table,
-                            u8 rix, u16 stepdown,
-                            u16 min_rate)
-{
-       u32 j;
-       u8 nextindex;
-
-       if (min_rate) {
-               for (j = RATE_TABLE_SIZE; j > 0; j--) {
-                       if (ath_rc_get_nextlowervalid_txrate(rate_table,
-                                               ath_rc_priv, rix, &nextindex))
-                               rix = nextindex;
-                       else
-                               break;
-               }
-       } else {
-               for (j = stepdown; j > 0; j--) {
-                       if (ath_rc_get_nextlowervalid_txrate(rate_table,
-                                               ath_rc_priv, rix, &nextindex))
-                               rix = nextindex;
-                       else
-                               break;
-               }
-       }
-       return rix;
-}
-
-static void ath_rc_ratefind(struct ath_softc *sc,
-                           struct ath_rate_priv *ath_rc_priv,
-                           struct ieee80211_tx_rate_control *txrc)
-{
-       struct ath_rate_table *rate_table;
-       struct sk_buff *skb = txrc->skb;
-       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
-       struct ieee80211_tx_rate *rates = tx_info->control.rates;
-       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-       __le16 fc = hdr->frame_control;
-       u8 try_per_rate = 0, i = 0, rix, nrix;
-       int is_probe = 0;
-
-       rate_table = sc->cur_rate_table;
-       rix = ath_rc_ratefind_ht(sc, ath_rc_priv, rate_table, &is_probe);
-       nrix = rix;
-
-       if (is_probe) {
-               /* set one try for probe rates. For the
-                * probes don't enable rts */
-               ath_rc_rate_set_series(rate_table, &rates[i++], txrc,
-                                      1, nrix, 0);
-
-               try_per_rate = (ATH_11N_TXMAXTRY/4);
-               /* Get the next tried/allowed rate. No RTS for the next series
-                * after the probe rate
-                */
-               nrix = ath_rc_rate_getidx(sc, ath_rc_priv,
-                                         rate_table, nrix, 1, 0);
-               ath_rc_rate_set_series(rate_table, &rates[i++], txrc,
-                                      try_per_rate, nrix, 0);
-
-               tx_info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE;
-       } else {
-               try_per_rate = (ATH_11N_TXMAXTRY/4);
-               /* Set the choosen rate. No RTS for first series entry. */
-               ath_rc_rate_set_series(rate_table, &rates[i++], txrc,
-                                      try_per_rate, nrix, 0);
-       }
-
-       /* Fill in the other rates for multirate retry */
-       for ( ; i < 4; i++) {
-               u8 try_num;
-               u8 min_rate;
-
-               try_num = ((i + 1) == 4) ?
-                       ATH_11N_TXMAXTRY - (try_per_rate * i) : try_per_rate ;
-               min_rate = (((i + 1) == 4) && 0);
-
-               nrix = ath_rc_rate_getidx(sc, ath_rc_priv,
-                                         rate_table, nrix, 1, min_rate);
-               /* All other rates in the series have RTS enabled */
-               ath_rc_rate_set_series(rate_table, &rates[i], txrc,
-                                      try_num, nrix, 1);
-       }
-
-       /*
-        * NB:Change rate series to enable aggregation when operating
-        * at lower MCS rates. When first rate in series is MCS2
-        * in HT40 @ 2.4GHz, series should look like:
-        *
-        * {MCS2, MCS1, MCS0, MCS0}.
-        *
-        * When first rate in series is MCS3 in HT20 @ 2.4GHz, series should
-        * look like:
-        *
-        * {MCS3, MCS2, MCS1, MCS1}
-        *
-        * So, set fourth rate in series to be same as third one for
-        * above conditions.
-        */
-       if ((sc->hw->conf.channel->band == IEEE80211_BAND_2GHZ) &&
-           (conf_is_ht(&sc->hw->conf))) {
-               u8 dot11rate = rate_table->info[rix].dot11rate;
-               u8 phy = rate_table->info[rix].phy;
-               if (i == 4 &&
-                   ((dot11rate == 2 && phy == WLAN_RC_PHY_HT_40_SS) ||
-                    (dot11rate == 3 && phy == WLAN_RC_PHY_HT_20_SS))) {
-                       rates[3].idx = rates[2].idx;
-                       rates[3].flags = rates[2].flags;
-               }
-       }
-
-       /*
-        * Force hardware to use computed duration for next
-        * fragment by disabling multi-rate retry, which
-        * updates duration based on the multi-rate duration table.
-        *
-        * FIXME: Fix duration
-        */
-       if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK) &&
-           (ieee80211_has_morefrags(fc) ||
-            (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG))) {
-               rates[1].count = rates[2].count = rates[3].count = 0;
-               rates[1].idx = rates[2].idx = rates[3].idx = 0;
-               rates[0].count = ATH_TXMAXTRY;
-       }
-
-       /* Setup RTS/CTS */
-       ath_rc_rate_set_rtscts(sc, rate_table, tx_info);
-}
-
-static bool ath_rc_update_per(struct ath_softc *sc,
-                             struct ath_rate_table *rate_table,
-                             struct ath_rate_priv *ath_rc_priv,
-                             struct ath_tx_info_priv *tx_info_priv,
-                             int tx_rate, int xretries, int retries,
-                             u32 now_msec)
-{
-       bool state_change = false;
-       int count;
-       u8 last_per;
-       static u32 nretry_to_per_lookup[10] = {
-               100 * 0 / 1,
-               100 * 1 / 4,
-               100 * 1 / 2,
-               100 * 3 / 4,
-               100 * 4 / 5,
-               100 * 5 / 6,
-               100 * 6 / 7,
-               100 * 7 / 8,
-               100 * 8 / 9,
-               100 * 9 / 10
-       };
-
-       last_per = ath_rc_priv->state[tx_rate].per;
-
-       if (xretries) {
-               if (xretries == 1) {
-                       ath_rc_priv->state[tx_rate].per += 30;
-                       if (ath_rc_priv->state[tx_rate].per > 100)
-                               ath_rc_priv->state[tx_rate].per = 100;
-               } else {
-                       /* xretries == 2 */
-                       count = ARRAY_SIZE(nretry_to_per_lookup);
-                       if (retries >= count)
-                               retries = count - 1;
-
-                       /* new_PER = 7/8*old_PER + 1/8*(currentPER) */
-                       ath_rc_priv->state[tx_rate].per =
-                               (u8)(last_per - (last_per >> 3) + (100 >> 3));
-               }
-
-               /* xretries == 1 or 2 */
-
-               if (ath_rc_priv->probe_rate == tx_rate)
-                       ath_rc_priv->probe_rate = 0;
-
-       } else { /* xretries == 0 */
-               count = ARRAY_SIZE(nretry_to_per_lookup);
-               if (retries >= count)
-                       retries = count - 1;
-
-               if (tx_info_priv->n_bad_frames) {
-                       /* new_PER = 7/8*old_PER + 1/8*(currentPER)
-                        * Assuming that n_frames is not 0.  The current PER
-                        * from the retries is 100 * retries / (retries+1),
-                        * since the first retries attempts failed, and the
-                        * next one worked.  For the one that worked,
-                        * n_bad_frames subframes out of n_frames wored,
-                        * so the PER for that part is
-                        * 100 * n_bad_frames / n_frames, and it contributes
-                        * 100 * n_bad_frames / (n_frames * (retries+1)) to
-                        * the above PER.  The expression below is a
-                        * simplified version of the sum of these two terms.
-                        */
-                       if (tx_info_priv->n_frames > 0) {
-                               int n_frames, n_bad_frames;
-                               u8 cur_per, new_per;
-
-                               n_bad_frames = retries * tx_info_priv->n_frames +
-                                       tx_info_priv->n_bad_frames;
-                               n_frames = tx_info_priv->n_frames * (retries + 1);
-                               cur_per = (100 * n_bad_frames / n_frames) >> 3;
-                               new_per = (u8)(last_per - (last_per >> 3) + cur_per);
-                               ath_rc_priv->state[tx_rate].per = new_per;
-                       }
-               } else {
-                       ath_rc_priv->state[tx_rate].per =
-                               (u8)(last_per - (last_per >> 3) +
-                                    (nretry_to_per_lookup[retries] >> 3));
-               }
-
-               ath_rc_priv->rssi_last_prev2 = ath_rc_priv->rssi_last_prev;
-               ath_rc_priv->rssi_last_prev  = ath_rc_priv->rssi_last;
-               ath_rc_priv->rssi_last = tx_info_priv->tx.ts_rssi;
-               ath_rc_priv->rssi_time = now_msec;
-
-               /*
-                * If we got at most one retry then increase the max rate if
-                * this was a probe.  Otherwise, ignore the probe.
-                */
-               if (ath_rc_priv->probe_rate && ath_rc_priv->probe_rate == tx_rate) {
-                       if (retries > 0 || 2 * tx_info_priv->n_bad_frames >
-                               tx_info_priv->n_frames) {
-                               /*
-                                * Since we probed with just a single attempt,
-                                * any retries means the probe failed.  Also,
-                                * if the attempt worked, but more than half
-                                * the subframes were bad then also consider
-                                * the probe a failure.
-                                */
-                               ath_rc_priv->probe_rate = 0;
-                       } else {
-                               u8 probe_rate = 0;
-
-                               ath_rc_priv->rate_max_phy =
-                                       ath_rc_priv->probe_rate;
-                               probe_rate = ath_rc_priv->probe_rate;
-
-                               if (ath_rc_priv->state[probe_rate].per > 30)
-                                       ath_rc_priv->state[probe_rate].per = 20;
-
-                               ath_rc_priv->probe_rate = 0;
-
-                               /*
-                                * Since this probe succeeded, we allow the next
-                                * probe twice as soon.  This allows the maxRate
-                                * to move up faster if the probes are
-                                * succesful.
-                                */
-                               ath_rc_priv->probe_time =
-                                       now_msec - rate_table->probe_interval / 2;
-                       }
-               }
-
-               if (retries > 0) {
-                       /*
-                        * Don't update anything.  We don't know if
-                        * this was because of collisions or poor signal.
-                        *
-                        * Later: if rssi_ack is close to
-                        * ath_rc_priv->state[txRate].rssi_thres and we see lots
-                        * of retries, then we could increase
-                        * ath_rc_priv->state[txRate].rssi_thres.
-                        */
-                       ath_rc_priv->hw_maxretry_pktcnt = 0;
-               } else {
-                       int32_t rssi_ackAvg;
-                       int8_t rssi_thres;
-                       int8_t rssi_ack_vmin;
-
-                       /*
-                        * It worked with no retries. First ignore bogus (small)
-                        * rssi_ack values.
-                        */
-                       if (tx_rate == ath_rc_priv->rate_max_phy &&
-                           ath_rc_priv->hw_maxretry_pktcnt < 255) {
-                               ath_rc_priv->hw_maxretry_pktcnt++;
-                       }
-
-                       if (tx_info_priv->tx.ts_rssi <
-                           rate_table->info[tx_rate].rssi_ack_validmin)
-                               goto exit;
-
-                       /* Average the rssi */
-                       if (tx_rate != ath_rc_priv->rssi_sum_rate) {
-                               ath_rc_priv->rssi_sum_rate = tx_rate;
-                               ath_rc_priv->rssi_sum =
-                                       ath_rc_priv->rssi_sum_cnt = 0;
-                       }
-
-                       ath_rc_priv->rssi_sum += tx_info_priv->tx.ts_rssi;
-                       ath_rc_priv->rssi_sum_cnt++;
-
-                       if (ath_rc_priv->rssi_sum_cnt < 4)
-                               goto exit;
-
-                       rssi_ackAvg =
-                               (ath_rc_priv->rssi_sum + 2) / 4;
-                       rssi_thres =
-                               ath_rc_priv->state[tx_rate].rssi_thres;
-                       rssi_ack_vmin =
-                               rate_table->info[tx_rate].rssi_ack_validmin;
-
-                       ath_rc_priv->rssi_sum =
-                               ath_rc_priv->rssi_sum_cnt = 0;
-
-                       /* Now reduce the current rssi threshold */
-                       if ((rssi_ackAvg < rssi_thres + 2) &&
-                           (rssi_thres > rssi_ack_vmin)) {
-                               ath_rc_priv->state[tx_rate].rssi_thres--;
-                       }
-
-                       state_change = true;
-               }
-       }
-exit:
-       return state_change;
-}
-
-/* Update PER, RSSI and whatever else that the code thinks it is doing.
-   If you can make sense of all this, you really need to go out more. */
-
-static void ath_rc_update_ht(struct ath_softc *sc,
-                            struct ath_rate_priv *ath_rc_priv,
-                            struct ath_tx_info_priv *tx_info_priv,
-                            int tx_rate, int xretries, int retries)
-{
-#define CHK_RSSI(rate)                                 \
-       ((ath_rc_priv->state[(rate)].rssi_thres +       \
-         rate_table->info[(rate)].rssi_ack_deltamin) > \
-        ath_rc_priv->state[(rate)+1].rssi_thres)
-
-       u32 now_msec = jiffies_to_msecs(jiffies);
-       int rate;
-       u8 last_per;
-       bool state_change = false;
-       struct ath_rate_table *rate_table = sc->cur_rate_table;
-       int size = ath_rc_priv->rate_table_size;
-
-       if ((tx_rate < 0) || (tx_rate > rate_table->rate_cnt))
-               return;
-
-       /* To compensate for some imbalance between ctrl and ext. channel */
-
-       if (WLAN_RC_PHY_40(rate_table->info[tx_rate].phy))
-               tx_info_priv->tx.ts_rssi =
-                       tx_info_priv->tx.ts_rssi < 3 ? 0 :
-                       tx_info_priv->tx.ts_rssi - 3;
-
-       last_per = ath_rc_priv->state[tx_rate].per;
-
-       /* Update PER first */
-       state_change = ath_rc_update_per(sc, rate_table, ath_rc_priv,
-                                        tx_info_priv, tx_rate, xretries,
-                                        retries, now_msec);
-
-       /*
-        * If this rate looks bad (high PER) then stop using it for
-        * a while (except if we are probing).
-        */
-       if (ath_rc_priv->state[tx_rate].per >= 55 && tx_rate > 0 &&
-           rate_table->info[tx_rate].ratekbps <=
-           rate_table->info[ath_rc_priv->rate_max_phy].ratekbps) {
-               ath_rc_get_nextlowervalid_txrate(rate_table, ath_rc_priv,
-                                (u8)tx_rate, &ath_rc_priv->rate_max_phy);
-
-               /* Don't probe for a little while. */
-               ath_rc_priv->probe_time = now_msec;
-       }
-
-       if (state_change) {
-               /*
-                * Make sure the rates above this have higher rssi thresholds.
-                * (Note:  Monotonicity is kept within the OFDM rates and
-                *         within the CCK rates. However, no adjustment is
-                *         made to keep the rssi thresholds monotonically
-                *         increasing between the CCK and OFDM rates.)
-                */
-               for (rate = tx_rate; rate < size - 1; rate++) {
-                       if (rate_table->info[rate+1].phy !=
-                           rate_table->info[tx_rate].phy)
-                               break;
-
-                       if (CHK_RSSI(rate)) {
-                               ath_rc_priv->state[rate+1].rssi_thres =
-                                       ath_rc_priv->state[rate].rssi_thres +
-                                       rate_table->info[rate].rssi_ack_deltamin;
-                       }
-               }
-
-               /* Make sure the rates below this have lower rssi thresholds. */
-               for (rate = tx_rate - 1; rate >= 0; rate--) {
-                       if (rate_table->info[rate].phy !=
-                           rate_table->info[tx_rate].phy)
-                               break;
-
-                       if (CHK_RSSI(rate)) {
-                               if (ath_rc_priv->state[rate+1].rssi_thres <
-                                   rate_table->info[rate].rssi_ack_deltamin)
-                                       ath_rc_priv->state[rate].rssi_thres = 0;
-                               else {
-                                       ath_rc_priv->state[rate].rssi_thres =
-                                       ath_rc_priv->state[rate+1].rssi_thres -
-                                       rate_table->info[rate].rssi_ack_deltamin;
-                               }
-
-                               if (ath_rc_priv->state[rate].rssi_thres <
-                                   rate_table->info[rate].rssi_ack_validmin) {
-                                       ath_rc_priv->state[rate].rssi_thres =
-                                       rate_table->info[rate].rssi_ack_validmin;
-                               }
-                       }
-               }
-       }
-
-       /* Make sure the rates below this have lower PER */
-       /* Monotonicity is kept only for rates below the current rate. */
-       if (ath_rc_priv->state[tx_rate].per < last_per) {
-               for (rate = tx_rate - 1; rate >= 0; rate--) {
-                       if (rate_table->info[rate].phy !=
-                           rate_table->info[tx_rate].phy)
-                               break;
-
-                       if (ath_rc_priv->state[rate].per >
-                           ath_rc_priv->state[rate+1].per) {
-                               ath_rc_priv->state[rate].per =
-                                       ath_rc_priv->state[rate+1].per;
-                       }
-               }
-       }
-
-       /* Maintain monotonicity for rates above the current rate */
-       for (rate = tx_rate; rate < size - 1; rate++) {
-               if (ath_rc_priv->state[rate+1].per <
-                   ath_rc_priv->state[rate].per)
-                       ath_rc_priv->state[rate+1].per =
-                               ath_rc_priv->state[rate].per;
-       }
-
-       /* Every so often, we reduce the thresholds and
-        * PER (different for CCK and OFDM). */
-       if (now_msec - ath_rc_priv->rssi_down_time >=
-           rate_table->rssi_reduce_interval) {
-
-               for (rate = 0; rate < size; rate++) {
-                       if (ath_rc_priv->state[rate].rssi_thres >
-                           rate_table->info[rate].rssi_ack_validmin)
-                               ath_rc_priv->state[rate].rssi_thres -= 1;
-               }
-               ath_rc_priv->rssi_down_time = now_msec;
-       }
-
-       /* Every so often, we reduce the thresholds
-        * and PER (different for CCK and OFDM). */
-       if (now_msec - ath_rc_priv->per_down_time >=
-           rate_table->rssi_reduce_interval) {
-               for (rate = 0; rate < size; rate++) {
-                       ath_rc_priv->state[rate].per =
-                               7 * ath_rc_priv->state[rate].per / 8;
-               }
-
-               ath_rc_priv->per_down_time = now_msec;
-       }
-
-       ath_debug_stat_retries(sc, tx_rate, xretries, retries,
-                              ath_rc_priv->state[tx_rate].per);
-
-#undef CHK_RSSI
-}
-
-static int ath_rc_get_rateindex(struct ath_rate_table *rate_table,
-                               struct ieee80211_tx_rate *rate)
-{
-       int rix;
-
-       if ((rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) &&
-           (rate->flags & IEEE80211_TX_RC_SHORT_GI))
-               rix = rate_table->info[rate->idx].ht_index;
-       else if (rate->flags & IEEE80211_TX_RC_SHORT_GI)
-               rix = rate_table->info[rate->idx].sgi_index;
-       else if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
-               rix = rate_table->info[rate->idx].cw40index;
-       else
-               rix = rate_table->info[rate->idx].base_index;
-
-       return rix;
-}
-
-static void ath_rc_tx_status(struct ath_softc *sc,
-                            struct ath_rate_priv *ath_rc_priv,
-                            struct ieee80211_tx_info *tx_info,
-                            int final_ts_idx, int xretries, int long_retry)
-{
-       struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
-       struct ath_rate_table *rate_table;
-       struct ieee80211_tx_rate *rates = tx_info->status.rates;
-       u8 flags;
-       u32 i = 0, rix;
-
-       rate_table = sc->cur_rate_table;
-
-       /*
-        * If the first rate is not the final index, there
-        * are intermediate rate failures to be processed.
-        */
-       if (final_ts_idx != 0) {
-               /* Process intermediate rates that failed.*/
-               for (i = 0; i < final_ts_idx ; i++) {
-                       if (rates[i].count != 0 && (rates[i].idx >= 0)) {
-                               flags = rates[i].flags;
-
-                               /* If HT40 and we have switched mode from
-                                * 40 to 20 => don't update */
-
-                               if ((flags & IEEE80211_TX_RC_40_MHZ_WIDTH) &&
-                                   (ath_rc_priv->rc_phy_mode != WLAN_RC_40_FLAG))
-                                       return;
-
-                               rix = ath_rc_get_rateindex(rate_table, &rates[i]);
-                               ath_rc_update_ht(sc, ath_rc_priv,
-                                               tx_info_priv, rix,
-                                               xretries ? 1 : 2,
-                                               rates[i].count);
-                       }
-               }
-       } else {
-               /*
-                * Handle the special case of MIMO PS burst, where the second
-                * aggregate is sent out with only one rate and one try.
-                * Treating it as an excessive retry penalizes the rate
-                * inordinately.
-                */
-               if (rates[0].count == 1 && xretries == 1)
-                       xretries = 2;
-       }
-
-       flags = rates[i].flags;
-
-       /* If HT40 and we have switched mode from 40 to 20 => don't update */
-       if ((flags & IEEE80211_TX_RC_40_MHZ_WIDTH) &&
-           (ath_rc_priv->rc_phy_mode != WLAN_RC_40_FLAG)) {
-               return;
-       }
-
-       rix = ath_rc_get_rateindex(rate_table, &rates[i]);
-       ath_rc_update_ht(sc, ath_rc_priv, tx_info_priv, rix,
-                        xretries, long_retry);
-}
-
-static struct ath_rate_table *ath_choose_rate_table(struct ath_softc *sc,
-                                                   enum ieee80211_band band,
-                                                   bool is_ht, bool is_cw_40)
-{
-       int mode = 0;
-
-       switch(band) {
-       case IEEE80211_BAND_2GHZ:
-               mode = ATH9K_MODE_11G;
-               if (is_ht)
-                       mode = ATH9K_MODE_11NG_HT20;
-               if (is_cw_40)
-                       mode = ATH9K_MODE_11NG_HT40PLUS;
-               break;
-       case IEEE80211_BAND_5GHZ:
-               mode = ATH9K_MODE_11A;
-               if (is_ht)
-                       mode = ATH9K_MODE_11NA_HT20;
-               if (is_cw_40)
-                       mode = ATH9K_MODE_11NA_HT40PLUS;
-               break;
-       default:
-               DPRINTF(sc, ATH_DBG_CONFIG, "Invalid band\n");
-               return NULL;
-       }
-
-       BUG_ON(mode >= ATH9K_MODE_MAX);
-
-       DPRINTF(sc, ATH_DBG_CONFIG, "Choosing rate table for mode: %d\n", mode);
-       return sc->hw_rate_table[mode];
-}
-
-static void ath_rc_init(struct ath_softc *sc,
-                       struct ath_rate_priv *ath_rc_priv,
-                       struct ieee80211_supported_band *sband,
-                       struct ieee80211_sta *sta,
-                       struct ath_rate_table *rate_table)
-{
-       struct ath_rateset *rateset = &ath_rc_priv->neg_rates;
-       u8 *ht_mcs = (u8 *)&ath_rc_priv->neg_ht_rates;
-       u8 i, j, k, hi = 0, hthi = 0;
-
-       if (!rate_table) {
-               DPRINTF(sc, ATH_DBG_FATAL, "Rate table not initialized\n");
-               return;
-       }
-
-       /* Initial rate table size. Will change depending
-        * on the working rate set */
-       ath_rc_priv->rate_table_size = RATE_TABLE_SIZE;
-
-       /* Initialize thresholds according to the global rate table */
-       for (i = 0 ; i < ath_rc_priv->rate_table_size; i++) {
-               ath_rc_priv->state[i].rssi_thres =
-                       rate_table->info[i].rssi_ack_validmin;
-               ath_rc_priv->state[i].per = 0;
-       }
-
-       /* Determine the valid rates */
-       ath_rc_init_valid_txmask(ath_rc_priv);
-
-       for (i = 0; i < WLAN_RC_PHY_MAX; i++) {
-               for (j = 0; j < MAX_TX_RATE_PHY; j++)
-                       ath_rc_priv->valid_phy_rateidx[i][j] = 0;
-               ath_rc_priv->valid_phy_ratecnt[i] = 0;
-       }
-       ath_rc_priv->rc_phy_mode = ath_rc_priv->ht_cap & WLAN_RC_40_FLAG;
-
-       /* Set stream capability */
-       ath_rc_priv->single_stream = (ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG) ? 0 : 1;
-
-       if (!rateset->rs_nrates) {
-               /* No working rate, just initialize valid rates */
-               hi = ath_rc_init_validrates(ath_rc_priv, rate_table,
-                                           ath_rc_priv->ht_cap);
-       } else {
-               /* Use intersection of working rates and valid rates */
-               hi = ath_rc_setvalid_rates(ath_rc_priv, rate_table,
-                                          rateset, ath_rc_priv->ht_cap);
-               if (ath_rc_priv->ht_cap & WLAN_RC_HT_FLAG) {
-                       hthi = ath_rc_setvalid_htrates(ath_rc_priv,
-                                                      rate_table,
-                                                      ht_mcs,
-                                                      ath_rc_priv->ht_cap);
-               }
-               hi = A_MAX(hi, hthi);
-       }
-
-       ath_rc_priv->rate_table_size = hi + 1;
-       ath_rc_priv->rate_max_phy = 0;
-       ASSERT(ath_rc_priv->rate_table_size <= RATE_TABLE_SIZE);
-
-       for (i = 0, k = 0; i < WLAN_RC_PHY_MAX; i++) {
-               for (j = 0; j < ath_rc_priv->valid_phy_ratecnt[i]; j++) {
-                       ath_rc_priv->valid_rate_index[k++] =
-                               ath_rc_priv->valid_phy_rateidx[i][j];
-               }
-
-               if (!ath_rc_valid_phyrate(i, rate_table->initial_ratemax, 1)
-                   || !ath_rc_priv->valid_phy_ratecnt[i])
-                       continue;
-
-               ath_rc_priv->rate_max_phy = ath_rc_priv->valid_phy_rateidx[i][j-1];
-       }
-       ASSERT(ath_rc_priv->rate_table_size <= RATE_TABLE_SIZE);
-       ASSERT(k <= RATE_TABLE_SIZE);
-
-       ath_rc_priv->max_valid_rate = k;
-       ath_rc_sort_validrates(rate_table, ath_rc_priv);
-       ath_rc_priv->rate_max_phy = ath_rc_priv->valid_rate_index[k-4];
-       sc->cur_rate_table = rate_table;
-
-       DPRINTF(sc, ATH_DBG_CONFIG, "RC Initialized with capabilities: 0x%x\n",
-               ath_rc_priv->ht_cap);
-}
-
-static u8 ath_rc_build_ht_caps(struct ath_softc *sc, struct ieee80211_sta *sta,
-                              bool is_cw40, bool is_sgi40)
-{
-       u8 caps = 0;
-
-       if (sta->ht_cap.ht_supported) {
-               caps = WLAN_RC_HT_FLAG;
-               if (sc->sc_ah->caps.tx_chainmask != 1 &&
-                   ath9k_hw_getcapability(sc->sc_ah, ATH9K_CAP_DS, 0, NULL)) {
-                       if (sta->ht_cap.mcs.rx_mask[1])
-                               caps |= WLAN_RC_DS_FLAG;
-               }
-               if (is_cw40)
-                       caps |= WLAN_RC_40_FLAG;
-               if (is_sgi40)
-                       caps |= WLAN_RC_SGI_FLAG;
-       }
-
-       return caps;
-}
-
-/***********************************/
-/* mac80211 Rate Control callbacks */
-/***********************************/
-
-static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
-                         struct ieee80211_sta *sta, void *priv_sta,
-                         struct sk_buff *skb)
-{
-       struct ath_softc *sc = priv;
-       struct ath_rate_priv *ath_rc_priv = priv_sta;
-       struct ath_tx_info_priv *tx_info_priv = NULL;
-       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
-       struct ieee80211_hdr *hdr;
-       int final_ts_idx, tx_status = 0, is_underrun = 0;
-       __le16 fc;
-
-       hdr = (struct ieee80211_hdr *)skb->data;
-       fc = hdr->frame_control;
-       tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
-       final_ts_idx = tx_info_priv->tx.ts_rateindex;
-
-       if (!priv_sta || !ieee80211_is_data(fc) ||
-           !tx_info_priv->update_rc)
-               goto exit;
-
-       if (tx_info_priv->tx.ts_status & ATH9K_TXERR_FILT)
-               goto exit;
-
-       /*
-        * If underrun error is seen assume it as an excessive retry only
-        * if prefetch trigger level have reached the max (0x3f for 5416)
-        * Adjust the long retry as if the frame was tried ATH_11N_TXMAXTRY
-        * times. This affects how ratectrl updates PER for the failed rate.
-        */
-       if (tx_info_priv->tx.ts_flags &
-           (ATH9K_TX_DATA_UNDERRUN | ATH9K_TX_DELIM_UNDERRUN) &&
-           ((sc->sc_ah->tx_trig_level) >= ath_rc_priv->tx_triglevel_max)) {
-               tx_status = 1;
-               is_underrun = 1;
-       }
-
-       if ((tx_info_priv->tx.ts_status & ATH9K_TXERR_XRETRY) ||
-           (tx_info_priv->tx.ts_status & ATH9K_TXERR_FIFO))
-               tx_status = 1;
-
-       ath_rc_tx_status(sc, ath_rc_priv, tx_info, final_ts_idx, tx_status,
-                        (is_underrun) ? ATH_11N_TXMAXTRY :
-                        tx_info_priv->tx.ts_longretry);
-
-       /* Check if aggregation has to be enabled for this tid */
-       if (conf_is_ht(&sc->hw->conf) &&
-           !(skb->protocol == cpu_to_be16(ETH_P_PAE))) {
-               if (ieee80211_is_data_qos(fc)) {
-                       u8 *qc, tid;
-                       struct ath_node *an;
-
-                       qc = ieee80211_get_qos_ctl(hdr);
-                       tid = qc[0] & 0xf;
-                       an = (struct ath_node *)sta->drv_priv;
-
-                       if(ath_tx_aggr_check(sc, an, tid))
-                               ieee80211_start_tx_ba_session(sc->hw, hdr->addr1, tid);
-               }
-       }
-
-       ath_debug_stat_rc(sc, skb);
-exit:
-       kfree(tx_info_priv);
-}
-
-static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
-                        struct ieee80211_tx_rate_control *txrc)
-{
-       struct ieee80211_supported_band *sband = txrc->sband;
-       struct sk_buff *skb = txrc->skb;
-       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
-       struct ath_softc *sc = priv;
-       struct ath_rate_priv *ath_rc_priv = priv_sta;
-       __le16 fc = hdr->frame_control;
-
-       /* lowest rate for management and multicast/broadcast frames */
-       if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1) ||
-           !sta) {
-               tx_info->control.rates[0].idx = rate_lowest_index(sband, sta);
-               tx_info->control.rates[0].count =
-                       is_multicast_ether_addr(hdr->addr1) ? 1 : ATH_MGT_TXMAXTRY;
-               return;
-       }
-
-       /* Find tx rate for unicast frames */
-       ath_rc_ratefind(sc, ath_rc_priv, txrc);
-}
-
-static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband,
-                          struct ieee80211_sta *sta, void *priv_sta)
-{
-       struct ath_softc *sc = priv;
-       struct ath_rate_priv *ath_rc_priv = priv_sta;
-       struct ath_rate_table *rate_table = NULL;
-       bool is_cw40, is_sgi40;
-       int i, j = 0;
-
-       for (i = 0; i < sband->n_bitrates; i++) {
-               if (sta->supp_rates[sband->band] & BIT(i)) {
-                       ath_rc_priv->neg_rates.rs_rates[j]
-                               = (sband->bitrates[i].bitrate * 2) / 10;
-                       j++;
-               }
-       }
-       ath_rc_priv->neg_rates.rs_nrates = j;
-
-       if (sta->ht_cap.ht_supported) {
-               for (i = 0, j = 0; i < 77; i++) {
-                       if (sta->ht_cap.mcs.rx_mask[i/8] & (1<<(i%8)))
-                               ath_rc_priv->neg_ht_rates.rs_rates[j++] = i;
-                       if (j == ATH_RATE_MAX)
-                               break;
-               }
-               ath_rc_priv->neg_ht_rates.rs_nrates = j;
-       }
-
-       is_cw40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40;
-       is_sgi40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40;
-
-       /* Choose rate table first */
-
-       if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) ||
-           (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT) ||
-           (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC)) {
-               rate_table = ath_choose_rate_table(sc, sband->band,
-                                                  sta->ht_cap.ht_supported,
-                                                  is_cw40);
-       } else if (sc->sc_ah->opmode == NL80211_IFTYPE_AP) {
-               /* cur_rate_table would be set on init through config() */
-               rate_table = sc->cur_rate_table;
-       }
-
-       ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc, sta, is_cw40, is_sgi40);
-       ath_rc_init(sc, priv_sta, sband, sta, rate_table);
-}
-
-static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband,
-                           struct ieee80211_sta *sta, void *priv_sta,
-                           u32 changed)
-{
-       struct ath_softc *sc = priv;
-       struct ath_rate_priv *ath_rc_priv = priv_sta;
-       struct ath_rate_table *rate_table = NULL;
-       bool oper_cw40 = false, oper_sgi40;
-       bool local_cw40 = (ath_rc_priv->ht_cap & WLAN_RC_40_FLAG) ?
-               true : false;
-       bool local_sgi40 = (ath_rc_priv->ht_cap & WLAN_RC_SGI_FLAG) ?
-               true : false;
-
-       /* FIXME: Handle AP mode later when we support CWM */
-
-       if (changed & IEEE80211_RC_HT_CHANGED) {
-               if (sc->sc_ah->opmode != NL80211_IFTYPE_STATION)
-                       return;
-
-               if (sc->hw->conf.channel_type == NL80211_CHAN_HT40MINUS ||
-                   sc->hw->conf.channel_type == NL80211_CHAN_HT40PLUS)
-                       oper_cw40 = true;
-
-               oper_sgi40 = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
-                       true : false;
-
-               if ((local_cw40 != oper_cw40) || (local_sgi40 != oper_sgi40)) {
-                       rate_table = ath_choose_rate_table(sc, sband->band,
-                                                  sta->ht_cap.ht_supported,
-                                                  oper_cw40);
-                       ath_rc_priv->ht_cap = ath_rc_build_ht_caps(sc, sta,
-                                                  oper_cw40, oper_sgi40);
-                       ath_rc_init(sc, priv_sta, sband, sta, rate_table);
-
-                       DPRINTF(sc, ATH_DBG_CONFIG,
-                               "Operating HT Bandwidth changed to: %d\n",
-                               sc->hw->conf.channel_type);
-               }
-       }
-}
-
-static void *ath_rate_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
-{
-       struct ath_wiphy *aphy = hw->priv;
-       return aphy->sc;
-}
-
-static void ath_rate_free(void *priv)
-{
-       return;
-}
-
-static void *ath_rate_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp)
-{
-       struct ath_softc *sc = priv;
-       struct ath_rate_priv *rate_priv;
-
-       rate_priv = kzalloc(sizeof(struct ath_rate_priv), gfp);
-       if (!rate_priv) {
-               DPRINTF(sc, ATH_DBG_FATAL,
-                       "Unable to allocate private rc structure\n");
-               return NULL;
-       }
-
-       rate_priv->rssi_down_time = jiffies_to_msecs(jiffies);
-       rate_priv->tx_triglevel_max = sc->sc_ah->caps.tx_triglevel_max;
-
-       return rate_priv;
-}
-
-static void ath_rate_free_sta(void *priv, struct ieee80211_sta *sta,
-                             void *priv_sta)
-{
-       struct ath_rate_priv *rate_priv = priv_sta;
-       kfree(rate_priv);
-}
-
-static struct rate_control_ops ath_rate_ops = {
-       .module = NULL,
-       .name = "ath9k_rate_control",
-       .tx_status = ath_tx_status,
-       .get_rate = ath_get_rate,
-       .rate_init = ath_rate_init,
-       .rate_update = ath_rate_update,
-       .alloc = ath_rate_alloc,
-       .free = ath_rate_free,
-       .alloc_sta = ath_rate_alloc_sta,
-       .free_sta = ath_rate_free_sta,
-};
-
-void ath_rate_attach(struct ath_softc *sc)
-{
-       sc->hw_rate_table[ATH9K_MODE_11B] =
-               &ar5416_11b_ratetable;
-       sc->hw_rate_table[ATH9K_MODE_11A] =
-               &ar5416_11a_ratetable;
-       sc->hw_rate_table[ATH9K_MODE_11G] =
-               &ar5416_11g_ratetable;
-       sc->hw_rate_table[ATH9K_MODE_11NA_HT20] =
-               &ar5416_11na_ratetable;
-       sc->hw_rate_table[ATH9K_MODE_11NG_HT20] =
-               &ar5416_11ng_ratetable;
-       sc->hw_rate_table[ATH9K_MODE_11NA_HT40PLUS] =
-               &ar5416_11na_ratetable;
-       sc->hw_rate_table[ATH9K_MODE_11NA_HT40MINUS] =
-               &ar5416_11na_ratetable;
-       sc->hw_rate_table[ATH9K_MODE_11NG_HT40PLUS] =
-               &ar5416_11ng_ratetable;
-       sc->hw_rate_table[ATH9K_MODE_11NG_HT40MINUS] =
-               &ar5416_11ng_ratetable;
-}
-
-int ath_rate_control_register(void)
-{
-       return ieee80211_rate_control_register(&ath_rate_ops);
-}
-
-void ath_rate_control_unregister(void)
-{
-       ieee80211_rate_control_unregister(&ath_rate_ops);
-}
diff --git a/drivers/net/wireless/ath9k/rc.h b/drivers/net/wireless/ath9k/rc.h
deleted file mode 100644 (file)
index 199a3ce..0000000
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * Copyright (c) 2004 Sam Leffler, Errno Consulting
- * Copyright (c) 2004 Video54 Technologies, Inc.
- * Copyright (c) 2008-2009 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 RC_H
-#define RC_H
-
-struct ath_softc;
-
-#define ATH_RATE_MAX     30
-#define RATE_TABLE_SIZE  64
-#define MAX_TX_RATE_PHY  48
-#define WLAN_CTRL_FRAME_SIZE (2+2+6+4)
-
-/* VALID_ALL - valid for 20/40/Legacy,
- * VALID - Legacy only,
- * VALID_20 - HT 20 only,
- * VALID_40 - HT 40 only */
-
-#define INVALID    0x0
-#define VALID      0x1
-#define VALID_20   0x2
-#define VALID_40   0x4
-#define VALID_2040 (VALID_20|VALID_40)
-#define VALID_ALL  (VALID_2040|VALID)
-
-enum {
-       WLAN_RC_PHY_OFDM,
-       WLAN_RC_PHY_CCK,
-       WLAN_RC_PHY_HT_20_SS,
-       WLAN_RC_PHY_HT_20_DS,
-       WLAN_RC_PHY_HT_40_SS,
-       WLAN_RC_PHY_HT_40_DS,
-       WLAN_RC_PHY_HT_20_SS_HGI,
-       WLAN_RC_PHY_HT_20_DS_HGI,
-       WLAN_RC_PHY_HT_40_SS_HGI,
-       WLAN_RC_PHY_HT_40_DS_HGI,
-       WLAN_RC_PHY_MAX
-};
-
-#define WLAN_RC_PHY_DS(_phy)   ((_phy == WLAN_RC_PHY_HT_20_DS)         \
-                               || (_phy == WLAN_RC_PHY_HT_40_DS)       \
-                               || (_phy == WLAN_RC_PHY_HT_20_DS_HGI)   \
-                               || (_phy == WLAN_RC_PHY_HT_40_DS_HGI))
-#define WLAN_RC_PHY_40(_phy)   ((_phy == WLAN_RC_PHY_HT_40_SS)         \
-                               || (_phy == WLAN_RC_PHY_HT_40_DS)       \
-                               || (_phy == WLAN_RC_PHY_HT_40_SS_HGI)   \
-                               || (_phy == WLAN_RC_PHY_HT_40_DS_HGI))
-#define WLAN_RC_PHY_SGI(_phy)  ((_phy == WLAN_RC_PHY_HT_20_SS_HGI)      \
-                               || (_phy == WLAN_RC_PHY_HT_20_DS_HGI)   \
-                               || (_phy == WLAN_RC_PHY_HT_40_SS_HGI)   \
-                               || (_phy == WLAN_RC_PHY_HT_40_DS_HGI))
-
-#define WLAN_RC_PHY_HT(_phy)    (_phy >= WLAN_RC_PHY_HT_20_SS)
-
-#define WLAN_RC_CAP_MODE(capflag) (((capflag & WLAN_RC_HT_FLAG) ?      \
-               (capflag & WLAN_RC_40_FLAG) ? VALID_40 : VALID_20 : VALID))
-
-/* Return TRUE if flag supports HT20 && client supports HT20 or
- * return TRUE if flag supports HT40 && client supports HT40.
- * This is used becos some rates overlap between HT20/HT40.
- */
-#define WLAN_RC_PHY_HT_VALID(flag, capflag)                    \
-       (((flag & VALID_20) && !(capflag & WLAN_RC_40_FLAG)) || \
-        ((flag & VALID_40) && (capflag & WLAN_RC_40_FLAG)))
-
-#define WLAN_RC_DS_FLAG         (0x01)
-#define WLAN_RC_40_FLAG         (0x02)
-#define WLAN_RC_SGI_FLAG        (0x04)
-#define WLAN_RC_HT_FLAG         (0x08)
-
-/**
- * struct ath_rate_table - Rate Control table
- * @valid: valid for use in rate control
- * @valid_single_stream: valid for use in rate control for
- *     single stream operation
- * @phy: CCK/OFDM
- * @ratekbps: rate in Kbits per second
- * @user_ratekbps: user rate in Kbits per second
- * @ratecode: rate that goes into HW descriptors
- * @short_preamble: Mask for enabling short preamble in ratecode for CCK
- * @dot11rate: value that goes into supported
- *     rates info element of MLME
- * @ctrl_rate: Index of next lower basic rate, used for duration computation
- * @max_4ms_framelen: maximum frame length(bytes) for tx duration
- * @probe_interval: interval for rate control to probe for other rates
- * @rssi_reduce_interval: interval for rate control to reduce rssi
- * @initial_ratemax: initial ratemax value
- */
-struct ath_rate_table {
-       int rate_cnt;
-       struct {
-               int valid;
-               int valid_single_stream;
-               u8 phy;
-               u32 ratekbps;
-               u32 user_ratekbps;
-               u8 ratecode;
-               u8 short_preamble;
-               u8 dot11rate;
-               u8 ctrl_rate;
-               int8_t rssi_ack_validmin;
-               int8_t rssi_ack_deltamin;
-               u8 base_index;
-               u8 cw40index;
-               u8 sgi_index;
-               u8 ht_index;
-               u32 max_4ms_framelen;
-       } info[RATE_TABLE_SIZE];
-       u32 probe_interval;
-       u32 rssi_reduce_interval;
-       u8 initial_ratemax;
-};
-
-struct ath_tx_ratectrl_state {
-       int8_t rssi_thres;      /* required rssi for this rate (dB) */
-       u8 per;                 /* recent estimate of packet error rate (%) */
-};
-
-struct ath_rateset {
-       u8 rs_nrates;
-       u8 rs_rates[ATH_RATE_MAX];
-};
-
-/**
- * struct ath_rate_priv - Rate Control priv data
- * @state: RC state
- * @rssi_last: last ACK rssi
- * @rssi_last_lookup: last ACK rssi used for lookup
- * @rssi_last_prev: previous last ACK rssi
- * @rssi_last_prev2: 2nd previous last ACK rssi
- * @rssi_sum_cnt: count of rssi_sum for averaging
- * @rssi_sum_rate: rate that we are averaging
- * @rssi_sum: running sum of rssi for averaging
- * @probe_rate: rate we are probing at
- * @rssi_time: msec timestamp for last ack rssi
- * @rssi_down_time: msec timestamp for last down step
- * @probe_time: msec timestamp for last probe
- * @hw_maxretry_pktcnt: num of packets since we got HW max retry error
- * @max_valid_rate: maximum number of valid rate
- * @per_down_time: msec timestamp for last PER down step
- * @valid_phy_ratecnt: valid rate count
- * @rate_max_phy: phy index for the max rate
- * @probe_interval: interval for ratectrl to probe for other rates
- * @prev_data_rix: rate idx of last data frame
- * @ht_cap: HT capabilities
- * @single_stream: When TRUE, only single TX stream possible
- * @neg_rates: Negotatied rates
- * @neg_ht_rates: Negotiated HT rates
- */
-struct ath_rate_priv {
-       int8_t rssi_last;
-       int8_t rssi_last_lookup;
-       int8_t rssi_last_prev;
-       int8_t rssi_last_prev2;
-       int32_t rssi_sum_cnt;
-       int32_t rssi_sum_rate;
-       int32_t rssi_sum;
-       u8 rate_table_size;
-       u8 probe_rate;
-       u8 hw_maxretry_pktcnt;
-       u8 max_valid_rate;
-       u8 valid_rate_index[RATE_TABLE_SIZE];
-       u8 ht_cap;
-       u8 single_stream;
-       u8 valid_phy_ratecnt[WLAN_RC_PHY_MAX];
-       u8 valid_phy_rateidx[WLAN_RC_PHY_MAX][RATE_TABLE_SIZE];
-       u8 rc_phy_mode;
-       u8 rate_max_phy;
-       u32 rssi_time;
-       u32 rssi_down_time;
-       u32 probe_time;
-       u32 per_down_time;
-       u32 probe_interval;
-       u32 prev_data_rix;
-       u32 tx_triglevel_max;
-       struct ath_tx_ratectrl_state state[RATE_TABLE_SIZE];
-       struct ath_rateset neg_rates;
-       struct ath_rateset neg_ht_rates;
-       struct ath_rate_softc *asc;
-};
-
-enum ath9k_internal_frame_type {
-       ATH9K_NOT_INTERNAL,
-       ATH9K_INT_PAUSE,
-       ATH9K_INT_UNPAUSE
-};
-
-struct ath_tx_info_priv {
-       struct ath_wiphy *aphy;
-       struct ath_tx_status tx;
-       int n_frames;
-       int n_bad_frames;
-       bool update_rc;
-       enum ath9k_internal_frame_type frame_type;
-};
-
-#define ATH_TX_INFO_PRIV(tx_info) \
-       ((struct ath_tx_info_priv *)((tx_info)->rate_driver_data[0]))
-
-void ath_rate_attach(struct ath_softc *sc);
-u8 ath_rate_findrateix(struct ath_softc *sc, u8 dot11_rate);
-int ath_rate_control_register(void);
-void ath_rate_control_unregister(void);
-
-#endif /* RC_H */
diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c
deleted file mode 100644 (file)
index dd1f301..0000000
+++ /dev/null
@@ -1,709 +0,0 @@
-/*
- * Copyright (c) 2008-2009 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 "ath9k.h"
-
-static struct ieee80211_hw * ath_get_virt_hw(struct ath_softc *sc,
-                                            struct ieee80211_hdr *hdr)
-{
-       struct ieee80211_hw *hw = sc->pri_wiphy->hw;
-       int i;
-
-       spin_lock_bh(&sc->wiphy_lock);
-       for (i = 0; i < sc->num_sec_wiphy; i++) {
-               struct ath_wiphy *aphy = sc->sec_wiphy[i];
-               if (aphy == NULL)
-                       continue;
-               if (compare_ether_addr(hdr->addr1, aphy->hw->wiphy->perm_addr)
-                   == 0) {
-                       hw = aphy->hw;
-                       break;
-               }
-       }
-       spin_unlock_bh(&sc->wiphy_lock);
-       return hw;
-}
-
-/*
- * Setup and link descriptors.
- *
- * 11N: we can no longer afford to self link the last descriptor.
- * MAC acknowledges BA status as long as it copies frames to host
- * buffer (or rx fifo). This can incorrectly acknowledge packets
- * to a sender if last desc is self-linked.
- */
-static void ath_rx_buf_link(struct ath_softc *sc, struct ath_buf *bf)
-{
-       struct ath_hw *ah = sc->sc_ah;
-       struct ath_desc *ds;
-       struct sk_buff *skb;
-
-       ATH_RXBUF_RESET(bf);
-
-       ds = bf->bf_desc;
-       ds->ds_link = 0; /* link to null */
-       ds->ds_data = bf->bf_buf_addr;
-
-       /* virtual addr of the beginning of the buffer. */
-       skb = bf->bf_mpdu;
-       ASSERT(skb != NULL);
-       ds->ds_vdata = skb->data;
-
-       /* setup rx descriptors. The rx.bufsize here tells the harware
-        * how much data it can DMA to us and that we are prepared
-        * to process */
-       ath9k_hw_setuprxdesc(ah, ds,
-                            sc->rx.bufsize,
-                            0);
-
-       if (sc->rx.rxlink == NULL)
-               ath9k_hw_putrxbuf(ah, bf->bf_daddr);
-       else
-               *sc->rx.rxlink = bf->bf_daddr;
-
-       sc->rx.rxlink = &ds->ds_link;
-       ath9k_hw_rxena(ah);
-}
-
-static void ath_setdefantenna(struct ath_softc *sc, u32 antenna)
-{
-       /* XXX block beacon interrupts */
-       ath9k_hw_setantenna(sc->sc_ah, antenna);
-       sc->rx.defant = antenna;
-       sc->rx.rxotherant = 0;
-}
-
-/*
- *  Extend 15-bit time stamp from rx descriptor to
- *  a full 64-bit TSF using the current h/w TSF.
-*/
-static u64 ath_extend_tsf(struct ath_softc *sc, u32 rstamp)
-{
-       u64 tsf;
-
-       tsf = ath9k_hw_gettsf64(sc->sc_ah);
-       if ((tsf & 0x7fff) < rstamp)
-               tsf -= 0x8000;
-       return (tsf & ~0x7fff) | rstamp;
-}
-
-static struct sk_buff *ath_rxbuf_alloc(struct ath_softc *sc, u32 len, gfp_t gfp_mask)
-{
-       struct sk_buff *skb;
-       u32 off;
-
-       /*
-        * Cache-line-align.  This is important (for the
-        * 5210 at least) as not doing so causes bogus data
-        * in rx'd frames.
-        */
-
-       /* Note: the kernel can allocate a value greater than
-        * what we ask it to give us. We really only need 4 KB as that
-        * is this hardware supports and in fact we need at least 3849
-        * as that is the MAX AMSDU size this hardware supports.
-        * Unfortunately this means we may get 8 KB here from the
-        * kernel... and that is actually what is observed on some
-        * systems :( */
-       skb = __dev_alloc_skb(len + sc->cachelsz - 1, gfp_mask);
-       if (skb != NULL) {
-               off = ((unsigned long) skb->data) % sc->cachelsz;
-               if (off != 0)
-                       skb_reserve(skb, sc->cachelsz - off);
-       } else {
-               DPRINTF(sc, ATH_DBG_FATAL,
-                       "skbuff alloc of size %u failed\n", len);
-               return NULL;
-       }
-
-       return skb;
-}
-
-/*
- * For Decrypt or Demic errors, we only mark packet status here and always push
- * up the frame up to let mac80211 handle the actual error case, be it no
- * decryption key or real decryption error. This let us keep statistics there.
- */
-static int ath_rx_prepare(struct sk_buff *skb, struct ath_desc *ds,
-                         struct ieee80211_rx_status *rx_status, bool *decrypt_error,
-                         struct ath_softc *sc)
-{
-       struct ieee80211_hdr *hdr;
-       u8 ratecode;
-       __le16 fc;
-       struct ieee80211_hw *hw;
-
-       hdr = (struct ieee80211_hdr *)skb->data;
-       fc = hdr->frame_control;
-       memset(rx_status, 0, sizeof(struct ieee80211_rx_status));
-       hw = ath_get_virt_hw(sc, hdr);
-
-       if (ds->ds_rxstat.rs_more) {
-               /*
-                * Frame spans multiple descriptors; this cannot happen yet
-                * as we don't support jumbograms. If not in monitor mode,
-                * discard the frame. Enable this if you want to see
-                * error frames in Monitor mode.
-                */
-               if (sc->sc_ah->opmode != NL80211_IFTYPE_MONITOR)
-                       goto rx_next;
-       } else if (ds->ds_rxstat.rs_status != 0) {
-               if (ds->ds_rxstat.rs_status & ATH9K_RXERR_CRC)
-                       rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
-               if (ds->ds_rxstat.rs_status & ATH9K_RXERR_PHY)
-                       goto rx_next;
-
-               if (ds->ds_rxstat.rs_status & ATH9K_RXERR_DECRYPT) {
-                       *decrypt_error = true;
-               } else if (ds->ds_rxstat.rs_status & ATH9K_RXERR_MIC) {
-                       if (ieee80211_is_ctl(fc))
-                               /*
-                                * Sometimes, we get invalid
-                                * MIC failures on valid control frames.
-                                * Remove these mic errors.
-                                */
-                               ds->ds_rxstat.rs_status &= ~ATH9K_RXERR_MIC;
-                       else
-                               rx_status->flag |= RX_FLAG_MMIC_ERROR;
-               }
-               /*
-                * Reject error frames with the exception of
-                * decryption and MIC failures. For monitor mode,
-                * we also ignore the CRC error.
-                */
-               if (sc->sc_ah->opmode == NL80211_IFTYPE_MONITOR) {
-                       if (ds->ds_rxstat.rs_status &
-                           ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC |
-                             ATH9K_RXERR_CRC))
-                               goto rx_next;
-               } else {
-                       if (ds->ds_rxstat.rs_status &
-                           ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC)) {
-                               goto rx_next;
-                       }
-               }
-       }
-
-       ratecode = ds->ds_rxstat.rs_rate;
-
-       if (ratecode & 0x80) {
-               /* HT rate */
-               rx_status->flag |= RX_FLAG_HT;
-               if (ds->ds_rxstat.rs_flags & ATH9K_RX_2040)
-                       rx_status->flag |= RX_FLAG_40MHZ;
-               if (ds->ds_rxstat.rs_flags & ATH9K_RX_GI)
-                       rx_status->flag |= RX_FLAG_SHORT_GI;
-               rx_status->rate_idx = ratecode & 0x7f;
-       } else {
-               int i = 0, cur_band, n_rates;
-
-               cur_band = hw->conf.channel->band;
-               n_rates = sc->sbands[cur_band].n_bitrates;
-
-               for (i = 0; i < n_rates; i++) {
-                       if (sc->sbands[cur_band].bitrates[i].hw_value ==
-                           ratecode) {
-                               rx_status->rate_idx = i;
-                               break;
-                       }
-
-                       if (sc->sbands[cur_band].bitrates[i].hw_value_short ==
-                           ratecode) {
-                               rx_status->rate_idx = i;
-                               rx_status->flag |= RX_FLAG_SHORTPRE;
-                               break;
-                       }
-               }
-       }
-
-       rx_status->mactime = ath_extend_tsf(sc, ds->ds_rxstat.rs_tstamp);
-       rx_status->band = hw->conf.channel->band;
-       rx_status->freq = hw->conf.channel->center_freq;
-       rx_status->noise = sc->ani.noise_floor;
-       rx_status->signal = rx_status->noise + ds->ds_rxstat.rs_rssi;
-       rx_status->antenna = ds->ds_rxstat.rs_antenna;
-
-       /* at 45 you will be able to use MCS 15 reliably. A more elaborate
-        * scheme can be used here but it requires tables of SNR/throughput for
-        * each possible mode used. */
-       rx_status->qual =  ds->ds_rxstat.rs_rssi * 100 / 45;
-
-       /* rssi can be more than 45 though, anything above that
-        * should be considered at 100% */
-       if (rx_status->qual > 100)
-               rx_status->qual = 100;
-
-       rx_status->flag |= RX_FLAG_TSFT;
-
-       return 1;
-rx_next:
-       return 0;
-}
-
-static void ath_opmode_init(struct ath_softc *sc)
-{
-       struct ath_hw *ah = sc->sc_ah;
-       u32 rfilt, mfilt[2];
-
-       /* configure rx filter */
-       rfilt = ath_calcrxfilter(sc);
-       ath9k_hw_setrxfilter(ah, rfilt);
-
-       /* configure bssid mask */
-       if (ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK)
-               ath9k_hw_setbssidmask(sc);
-
-       /* configure operational mode */
-       ath9k_hw_setopmode(ah);
-
-       /* Handle any link-level address change. */
-       ath9k_hw_setmac(ah, sc->sc_ah->macaddr);
-
-       /* calculate and install multicast filter */
-       mfilt[0] = mfilt[1] = ~0;
-       ath9k_hw_setmcastfilter(ah, mfilt[0], mfilt[1]);
-}
-
-int ath_rx_init(struct ath_softc *sc, int nbufs)
-{
-       struct sk_buff *skb;
-       struct ath_buf *bf;
-       int error = 0;
-
-       do {
-               spin_lock_init(&sc->rx.rxflushlock);
-               sc->sc_flags &= ~SC_OP_RXFLUSH;
-               spin_lock_init(&sc->rx.rxbuflock);
-
-               sc->rx.bufsize = roundup(IEEE80211_MAX_MPDU_LEN,
-                                          min(sc->cachelsz,
-                                              (u16)64));
-
-               DPRINTF(sc, ATH_DBG_CONFIG, "cachelsz %u rxbufsize %u\n",
-                       sc->cachelsz, sc->rx.bufsize);
-
-               /* Initialize rx descriptors */
-
-               error = ath_descdma_setup(sc, &sc->rx.rxdma, &sc->rx.rxbuf,
-                                         "rx", nbufs, 1);
-               if (error != 0) {
-                       DPRINTF(sc, ATH_DBG_FATAL,
-                               "failed to allocate rx descriptors: %d\n", error);
-                       break;
-               }
-
-               list_for_each_entry(bf, &sc->rx.rxbuf, list) {
-                       skb = ath_rxbuf_alloc(sc, sc->rx.bufsize, GFP_KERNEL);
-                       if (skb == NULL) {
-                               error = -ENOMEM;
-                               break;
-                       }
-
-                       bf->bf_mpdu = skb;
-                       bf->bf_buf_addr = dma_map_single(sc->dev, skb->data,
-                                                        sc->rx.bufsize,
-                                                        DMA_FROM_DEVICE);
-                       if (unlikely(dma_mapping_error(sc->dev,
-                                 bf->bf_buf_addr))) {
-                               dev_kfree_skb_any(skb);
-                               bf->bf_mpdu = NULL;
-                               DPRINTF(sc, ATH_DBG_CONFIG,
-                                       "dma_mapping_error() on RX init\n");
-                               error = -ENOMEM;
-                               break;
-                       }
-                       bf->bf_dmacontext = bf->bf_buf_addr;
-               }
-               sc->rx.rxlink = NULL;
-
-       } while (0);
-
-       if (error)
-               ath_rx_cleanup(sc);
-
-       return error;
-}
-
-void ath_rx_cleanup(struct ath_softc *sc)
-{
-       struct sk_buff *skb;
-       struct ath_buf *bf;
-
-       list_for_each_entry(bf, &sc->rx.rxbuf, list) {
-               skb = bf->bf_mpdu;
-               if (skb) {
-                       dma_unmap_single(sc->dev,
-                                        bf->bf_buf_addr,
-                                        sc->rx.bufsize,
-                                        DMA_FROM_DEVICE);
-                       dev_kfree_skb(skb);
-               }
-       }
-
-       if (sc->rx.rxdma.dd_desc_len != 0)
-               ath_descdma_cleanup(sc, &sc->rx.rxdma, &sc->rx.rxbuf);
-}
-
-/*
- * Calculate the receive filter according to the
- * operating mode and state:
- *
- * o always accept unicast, broadcast, and multicast traffic
- * o maintain current state of phy error reception (the hal
- *   may enable phy error frames for noise immunity work)
- * o probe request frames are accepted only when operating in
- *   hostap, adhoc, or monitor modes
- * o enable promiscuous mode according to the interface state
- * o accept beacons:
- *   - when operating in adhoc mode so the 802.11 layer creates
- *     node table entries for peers,
- *   - when operating in station mode for collecting rssi data when
- *     the station is otherwise quiet, or
- *   - when operating as a repeater so we see repeater-sta beacons
- *   - when scanning
- */
-
-u32 ath_calcrxfilter(struct ath_softc *sc)
-{
-#define        RX_FILTER_PRESERVE (ATH9K_RX_FILTER_PHYERR | ATH9K_RX_FILTER_PHYRADAR)
-
-       u32 rfilt;
-
-       rfilt = (ath9k_hw_getrxfilter(sc->sc_ah) & RX_FILTER_PRESERVE)
-               | ATH9K_RX_FILTER_UCAST | ATH9K_RX_FILTER_BCAST
-               | ATH9K_RX_FILTER_MCAST;
-
-       /* If not a STA, enable processing of Probe Requests */
-       if (sc->sc_ah->opmode != NL80211_IFTYPE_STATION)
-               rfilt |= ATH9K_RX_FILTER_PROBEREQ;
-
-       /*
-        * Set promiscuous mode when FIF_PROMISC_IN_BSS is enabled for station
-        * mode interface or when in monitor mode. AP mode does not need this
-        * since it receives all in-BSS frames anyway.
-        */
-       if (((sc->sc_ah->opmode != NL80211_IFTYPE_AP) &&
-            (sc->rx.rxfilter & FIF_PROMISC_IN_BSS)) ||
-           (sc->sc_ah->opmode == NL80211_IFTYPE_MONITOR))
-               rfilt |= ATH9K_RX_FILTER_PROM;
-
-       if (sc->rx.rxfilter & FIF_CONTROL)
-               rfilt |= ATH9K_RX_FILTER_CONTROL;
-
-       if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) &&
-           !(sc->rx.rxfilter & FIF_BCN_PRBRESP_PROMISC))
-               rfilt |= ATH9K_RX_FILTER_MYBEACON;
-       else
-               rfilt |= ATH9K_RX_FILTER_BEACON;
-
-       /* If in HOSTAP mode, want to enable reception of PSPOLL frames */
-       if (sc->sc_ah->opmode == NL80211_IFTYPE_AP)
-               rfilt |= ATH9K_RX_FILTER_PSPOLL;
-
-       if (sc->sec_wiphy) {
-               /* TODO: only needed if more than one BSSID is in use in
-                * station/adhoc mode */
-               /* TODO: for older chips, may need to add ATH9K_RX_FILTER_PROM
-                */
-               rfilt |= ATH9K_RX_FILTER_MCAST_BCAST_ALL;
-       }
-
-       return rfilt;
-
-#undef RX_FILTER_PRESERVE
-}
-
-int ath_startrecv(struct ath_softc *sc)
-{
-       struct ath_hw *ah = sc->sc_ah;
-       struct ath_buf *bf, *tbf;
-
-       spin_lock_bh(&sc->rx.rxbuflock);
-       if (list_empty(&sc->rx.rxbuf))
-               goto start_recv;
-
-       sc->rx.rxlink = NULL;
-       list_for_each_entry_safe(bf, tbf, &sc->rx.rxbuf, list) {
-               ath_rx_buf_link(sc, bf);
-       }
-
-       /* We could have deleted elements so the list may be empty now */
-       if (list_empty(&sc->rx.rxbuf))
-               goto start_recv;
-
-       bf = list_first_entry(&sc->rx.rxbuf, struct ath_buf, list);
-       ath9k_hw_putrxbuf(ah, bf->bf_daddr);
-       ath9k_hw_rxena(ah);
-
-start_recv:
-       spin_unlock_bh(&sc->rx.rxbuflock);
-       ath_opmode_init(sc);
-       ath9k_hw_startpcureceive(ah);
-
-       return 0;
-}
-
-bool ath_stoprecv(struct ath_softc *sc)
-{
-       struct ath_hw *ah = sc->sc_ah;
-       bool stopped;
-
-       ath9k_hw_stoppcurecv(ah);
-       ath9k_hw_setrxfilter(ah, 0);
-       stopped = ath9k_hw_stopdmarecv(ah);
-       sc->rx.rxlink = NULL;
-
-       return stopped;
-}
-
-void ath_flushrecv(struct ath_softc *sc)
-{
-       spin_lock_bh(&sc->rx.rxflushlock);
-       sc->sc_flags |= SC_OP_RXFLUSH;
-       ath_rx_tasklet(sc, 1);
-       sc->sc_flags &= ~SC_OP_RXFLUSH;
-       spin_unlock_bh(&sc->rx.rxflushlock);
-}
-
-int ath_rx_tasklet(struct ath_softc *sc, int flush)
-{
-#define PA2DESC(_sc, _pa)                                               \
-       ((struct ath_desc *)((caddr_t)(_sc)->rx.rxdma.dd_desc +         \
-                            ((_pa) - (_sc)->rx.rxdma.dd_desc_paddr)))
-
-       struct ath_buf *bf;
-       struct ath_desc *ds;
-       struct sk_buff *skb = NULL, *requeue_skb;
-       struct ieee80211_rx_status rx_status;
-       struct ath_hw *ah = sc->sc_ah;
-       struct ieee80211_hdr *hdr;
-       int hdrlen, padsize, retval;
-       bool decrypt_error = false;
-       u8 keyix;
-       __le16 fc;
-
-       spin_lock_bh(&sc->rx.rxbuflock);
-
-       do {
-               /* If handling rx interrupt and flush is in progress => exit */
-               if ((sc->sc_flags & SC_OP_RXFLUSH) && (flush == 0))
-                       break;
-
-               if (list_empty(&sc->rx.rxbuf)) {
-                       sc->rx.rxlink = NULL;
-                       break;
-               }
-
-               bf = list_first_entry(&sc->rx.rxbuf, struct ath_buf, list);
-               ds = bf->bf_desc;
-
-               /*
-                * Must provide the virtual address of the current
-                * descriptor, the physical address, and the virtual
-                * address of the next descriptor in the h/w chain.
-                * This allows the HAL to look ahead to see if the
-                * hardware is done with a descriptor by checking the
-                * done bit in the following descriptor and the address
-                * of the current descriptor the DMA engine is working
-                * on.  All this is necessary because of our use of
-                * a self-linked list to avoid rx overruns.
-                */
-               retval = ath9k_hw_rxprocdesc(ah, ds,
-                                            bf->bf_daddr,
-                                            PA2DESC(sc, ds->ds_link),
-                                            0);
-               if (retval == -EINPROGRESS) {
-                       struct ath_buf *tbf;
-                       struct ath_desc *tds;
-
-                       if (list_is_last(&bf->list, &sc->rx.rxbuf)) {
-                               sc->rx.rxlink = NULL;
-                               break;
-                       }
-
-                       tbf = list_entry(bf->list.next, struct ath_buf, list);
-
-                       /*
-                        * On some hardware the descriptor status words could
-                        * get corrupted, including the done bit. Because of
-                        * this, check if the next descriptor's done bit is
-                        * set or not.
-                        *
-                        * If the next descriptor's done bit is set, the current
-                        * descriptor has been corrupted. Force s/w to discard
-                        * this descriptor and continue...
-                        */
-
-                       tds = tbf->bf_desc;
-                       retval = ath9k_hw_rxprocdesc(ah, tds, tbf->bf_daddr,
-                                            PA2DESC(sc, tds->ds_link), 0);
-                       if (retval == -EINPROGRESS) {
-                               break;
-                       }
-               }
-
-               skb = bf->bf_mpdu;
-               if (!skb)
-                       continue;
-
-               /*
-                * Synchronize the DMA transfer with CPU before
-                * 1. accessing the frame
-                * 2. requeueing the same buffer to h/w
-                */
-               dma_sync_single_for_cpu(sc->dev, bf->bf_buf_addr,
-                               sc->rx.bufsize,
-                               DMA_FROM_DEVICE);
-
-               /*
-                * If we're asked to flush receive queue, directly
-                * chain it back at the queue without processing it.
-                */
-               if (flush)
-                       goto requeue;
-
-               if (!ds->ds_rxstat.rs_datalen)
-                       goto requeue;
-
-               /* The status portion of the descriptor could get corrupted. */
-               if (sc->rx.bufsize < ds->ds_rxstat.rs_datalen)
-                       goto requeue;
-
-               if (!ath_rx_prepare(skb, ds, &rx_status, &decrypt_error, sc))
-                       goto requeue;
-
-               /* Ensure we always have an skb to requeue once we are done
-                * processing the current buffer's skb */
-               requeue_skb = ath_rxbuf_alloc(sc, sc->rx.bufsize, GFP_ATOMIC);
-
-               /* If there is no memory we ignore the current RX'd frame,
-                * tell hardware it can give us a new frame using the old
-                * skb and put it at the tail of the sc->rx.rxbuf list for
-                * processing. */
-               if (!requeue_skb)
-                       goto requeue;
-
-               /* Unmap the frame */
-               dma_unmap_single(sc->dev, bf->bf_buf_addr,
-                                sc->rx.bufsize,
-                                DMA_FROM_DEVICE);
-
-               skb_put(skb, ds->ds_rxstat.rs_datalen);
-               skb->protocol = cpu_to_be16(ETH_P_CONTROL);
-
-               /* see if any padding is done by the hw and remove it */
-               hdr = (struct ieee80211_hdr *)skb->data;
-               hdrlen = ieee80211_get_hdrlen_from_skb(skb);
-               fc = hdr->frame_control;
-
-               /* The MAC header is padded to have 32-bit boundary if the
-                * packet payload is non-zero. The general calculation for
-                * padsize would take into account odd header lengths:
-                * padsize = (4 - hdrlen % 4) % 4; However, since only
-                * even-length headers are used, padding can only be 0 or 2
-                * bytes and we can optimize this a bit. In addition, we must
-                * not try to remove padding from short control frames that do
-                * not have payload. */
-               padsize = hdrlen & 3;
-               if (padsize && hdrlen >= 24) {
-                       memmove(skb->data + padsize, skb->data, hdrlen);
-                       skb_pull(skb, padsize);
-               }
-
-               keyix = ds->ds_rxstat.rs_keyix;
-
-               if (!(keyix == ATH9K_RXKEYIX_INVALID) && !decrypt_error) {
-                       rx_status.flag |= RX_FLAG_DECRYPTED;
-               } else if ((le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_PROTECTED)
-                          && !decrypt_error && skb->len >= hdrlen + 4) {
-                       keyix = skb->data[hdrlen + 3] >> 6;
-
-                       if (test_bit(keyix, sc->keymap))
-                               rx_status.flag |= RX_FLAG_DECRYPTED;
-               }
-               if (ah->sw_mgmt_crypto &&
-                   (rx_status.flag & RX_FLAG_DECRYPTED) &&
-                   ieee80211_is_mgmt(hdr->frame_control)) {
-                       /* Use software decrypt for management frames. */
-                       rx_status.flag &= ~RX_FLAG_DECRYPTED;
-               }
-
-               /* Send the frame to mac80211 */
-               if (hdr->addr1[5] & 0x01) {
-                       int i;
-                       /*
-                        * Deliver broadcast/multicast frames to all suitable
-                        * virtual wiphys.
-                        */
-                       /* TODO: filter based on channel configuration */
-                       for (i = 0; i < sc->num_sec_wiphy; i++) {
-                               struct ath_wiphy *aphy = sc->sec_wiphy[i];
-                               struct sk_buff *nskb;
-                               if (aphy == NULL)
-                                       continue;
-                               nskb = skb_copy(skb, GFP_ATOMIC);
-                               if (nskb)
-                                       __ieee80211_rx(aphy->hw, nskb,
-                                                      &rx_status);
-                       }
-                       __ieee80211_rx(sc->hw, skb, &rx_status);
-               } else {
-                       /* Deliver unicast frames based on receiver address */
-                       __ieee80211_rx(ath_get_virt_hw(sc, hdr), skb,
-                                      &rx_status);
-               }
-
-               /* We will now give hardware our shiny new allocated skb */
-               bf->bf_mpdu = requeue_skb;
-               bf->bf_buf_addr = dma_map_single(sc->dev, requeue_skb->data,
-                                        sc->rx.bufsize,
-                                        DMA_FROM_DEVICE);
-               if (unlikely(dma_mapping_error(sc->dev,
-                         bf->bf_buf_addr))) {
-                       dev_kfree_skb_any(requeue_skb);
-                       bf->bf_mpdu = NULL;
-                       DPRINTF(sc, ATH_DBG_CONFIG,
-                               "dma_mapping_error() on RX\n");
-                       break;
-               }
-               bf->bf_dmacontext = bf->bf_buf_addr;
-
-               /*
-                * change the default rx antenna if rx diversity chooses the
-                * other antenna 3 times in a row.
-                */
-               if (sc->rx.defant != ds->ds_rxstat.rs_antenna) {
-                       if (++sc->rx.rxotherant >= 3)
-                               ath_setdefantenna(sc, ds->ds_rxstat.rs_antenna);
-               } else {
-                       sc->rx.rxotherant = 0;
-               }
-
-               if (ieee80211_is_beacon(fc) &&
-                               (sc->sc_flags & SC_OP_WAIT_FOR_BEACON)) {
-                       sc->sc_flags &= ~SC_OP_WAIT_FOR_BEACON;
-                       ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_NETWORK_SLEEP);
-               }
-requeue:
-               list_move_tail(&bf->list, &sc->rx.rxbuf);
-               ath_rx_buf_link(sc, bf);
-       } while (1);
-
-       spin_unlock_bh(&sc->rx.rxbuflock);
-
-       return 0;
-#undef PA2DESC
-}
diff --git a/drivers/net/wireless/ath9k/reg.h b/drivers/net/wireless/ath9k/reg.h
deleted file mode 100644 (file)
index 5260524..0000000
+++ /dev/null
@@ -1,1511 +0,0 @@
-/*
- * Copyright (c) 2008-2009 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 REG_H
-#define REG_H
-
-#define AR_CR                0x0008
-#define AR_CR_RXE            0x00000004
-#define AR_CR_RXD            0x00000020
-#define AR_CR_SWI            0x00000040
-
-#define AR_RXDP              0x000C
-
-#define AR_CFG               0x0014
-#define AR_CFG_SWTD          0x00000001
-#define AR_CFG_SWTB          0x00000002
-#define AR_CFG_SWRD          0x00000004
-#define AR_CFG_SWRB          0x00000008
-#define AR_CFG_SWRG          0x00000010
-#define AR_CFG_AP_ADHOC_INDICATION 0x00000020
-#define AR_CFG_PHOK          0x00000100
-#define AR_CFG_CLK_GATE_DIS  0x00000400
-#define AR_CFG_EEBS          0x00000200
-#define AR_CFG_PCI_MASTER_REQ_Q_THRESH         0x00060000
-#define AR_CFG_PCI_MASTER_REQ_Q_THRESH_S       17
-
-#define AR_MIRT              0x0020
-#define AR_MIRT_VAL          0x0000ffff
-#define AR_MIRT_VAL_S        16
-
-#define AR_IER               0x0024
-#define AR_IER_ENABLE        0x00000001
-#define AR_IER_DISABLE       0x00000000
-
-#define AR_TIMT              0x0028
-#define AR_TIMT_LAST         0x0000ffff
-#define AR_TIMT_LAST_S       0
-#define AR_TIMT_FIRST        0xffff0000
-#define AR_TIMT_FIRST_S      16
-
-#define AR_RIMT              0x002C
-#define AR_RIMT_LAST         0x0000ffff
-#define AR_RIMT_LAST_S       0
-#define AR_RIMT_FIRST        0xffff0000
-#define AR_RIMT_FIRST_S      16
-
-#define AR_DMASIZE_4B        0x00000000
-#define AR_DMASIZE_8B        0x00000001
-#define AR_DMASIZE_16B       0x00000002
-#define AR_DMASIZE_32B       0x00000003
-#define AR_DMASIZE_64B       0x00000004
-#define AR_DMASIZE_128B      0x00000005
-#define AR_DMASIZE_256B      0x00000006
-#define AR_DMASIZE_512B      0x00000007
-
-#define AR_TXCFG             0x0030
-#define AR_TXCFG_DMASZ_MASK  0x00000007
-#define AR_TXCFG_DMASZ_4B    0
-#define AR_TXCFG_DMASZ_8B    1
-#define AR_TXCFG_DMASZ_16B   2
-#define AR_TXCFG_DMASZ_32B   3
-#define AR_TXCFG_DMASZ_64B   4
-#define AR_TXCFG_DMASZ_128B  5
-#define AR_TXCFG_DMASZ_256B  6
-#define AR_TXCFG_DMASZ_512B  7
-#define AR_FTRIG             0x000003F0
-#define AR_FTRIG_S           4
-#define AR_FTRIG_IMMED       0x00000000
-#define AR_FTRIG_64B         0x00000010
-#define AR_FTRIG_128B        0x00000020
-#define AR_FTRIG_192B        0x00000030
-#define AR_FTRIG_256B        0x00000040
-#define AR_FTRIG_512B        0x00000080
-#define AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY 0x00000800
-
-#define AR_RXCFG             0x0034
-#define AR_RXCFG_CHIRP       0x00000008
-#define AR_RXCFG_ZLFDMA      0x00000010
-#define AR_RXCFG_DMASZ_MASK  0x00000007
-#define AR_RXCFG_DMASZ_4B    0
-#define AR_RXCFG_DMASZ_8B    1
-#define AR_RXCFG_DMASZ_16B   2
-#define AR_RXCFG_DMASZ_32B   3
-#define AR_RXCFG_DMASZ_64B   4
-#define AR_RXCFG_DMASZ_128B  5
-#define AR_RXCFG_DMASZ_256B  6
-#define AR_RXCFG_DMASZ_512B  7
-
-#define AR_MIBC              0x0040
-#define AR_MIBC_COW          0x00000001
-#define AR_MIBC_FMC          0x00000002
-#define AR_MIBC_CMC          0x00000004
-#define AR_MIBC_MCS          0x00000008
-
-#define AR_TOPS              0x0044
-#define AR_TOPS_MASK         0x0000FFFF
-
-#define AR_RXNPTO            0x0048
-#define AR_RXNPTO_MASK       0x000003FF
-
-#define AR_TXNPTO            0x004C
-#define AR_TXNPTO_MASK       0x000003FF
-#define AR_TXNPTO_QCU_MASK   0x000FFC00
-
-#define AR_RPGTO             0x0050
-#define AR_RPGTO_MASK        0x000003FF
-
-#define AR_RPCNT             0x0054
-#define AR_RPCNT_MASK        0x0000001F
-
-#define AR_MACMISC           0x0058
-#define AR_MACMISC_PCI_EXT_FORCE        0x00000010
-#define AR_MACMISC_DMA_OBS              0x000001E0
-#define AR_MACMISC_DMA_OBS_S            5
-#define AR_MACMISC_DMA_OBS_LINE_0       0
-#define AR_MACMISC_DMA_OBS_LINE_1       1
-#define AR_MACMISC_DMA_OBS_LINE_2       2
-#define AR_MACMISC_DMA_OBS_LINE_3       3
-#define AR_MACMISC_DMA_OBS_LINE_4       4
-#define AR_MACMISC_DMA_OBS_LINE_5       5
-#define AR_MACMISC_DMA_OBS_LINE_6       6
-#define AR_MACMISC_DMA_OBS_LINE_7       7
-#define AR_MACMISC_DMA_OBS_LINE_8       8
-#define AR_MACMISC_MISC_OBS             0x00000E00
-#define AR_MACMISC_MISC_OBS_S           9
-#define AR_MACMISC_MISC_OBS_BUS_LSB     0x00007000
-#define AR_MACMISC_MISC_OBS_BUS_LSB_S   12
-#define AR_MACMISC_MISC_OBS_BUS_MSB     0x00038000
-#define AR_MACMISC_MISC_OBS_BUS_MSB_S   15
-#define AR_MACMISC_MISC_OBS_BUS_1       1
-
-#define AR_GTXTO    0x0064
-#define AR_GTXTO_TIMEOUT_COUNTER    0x0000FFFF
-#define AR_GTXTO_TIMEOUT_LIMIT      0xFFFF0000
-#define AR_GTXTO_TIMEOUT_LIMIT_S    16
-
-#define AR_GTTM     0x0068
-#define AR_GTTM_USEC          0x00000001
-#define AR_GTTM_IGNORE_IDLE   0x00000002
-#define AR_GTTM_RESET_IDLE    0x00000004
-#define AR_GTTM_CST_USEC      0x00000008
-
-#define AR_CST         0x006C
-#define AR_CST_TIMEOUT_COUNTER    0x0000FFFF
-#define AR_CST_TIMEOUT_LIMIT      0xFFFF0000
-#define AR_CST_TIMEOUT_LIMIT_S    16
-
-#define AR_ISR               0x0080
-#define AR_ISR_RXOK          0x00000001
-#define AR_ISR_RXDESC        0x00000002
-#define AR_ISR_RXERR         0x00000004
-#define AR_ISR_RXNOPKT       0x00000008
-#define AR_ISR_RXEOL         0x00000010
-#define AR_ISR_RXORN         0x00000020
-#define AR_ISR_TXOK          0x00000040
-#define AR_ISR_TXDESC        0x00000080
-#define AR_ISR_TXERR         0x00000100
-#define AR_ISR_TXNOPKT       0x00000200
-#define AR_ISR_TXEOL         0x00000400
-#define AR_ISR_TXURN         0x00000800
-#define AR_ISR_MIB           0x00001000
-#define AR_ISR_SWI           0x00002000
-#define AR_ISR_RXPHY         0x00004000
-#define AR_ISR_RXKCM         0x00008000
-#define AR_ISR_SWBA          0x00010000
-#define AR_ISR_BRSSI         0x00020000
-#define AR_ISR_BMISS         0x00040000
-#define AR_ISR_BNR           0x00100000
-#define AR_ISR_RXCHIRP       0x00200000
-#define AR_ISR_BCNMISC       0x00800000
-#define AR_ISR_TIM           0x00800000
-#define AR_ISR_QCBROVF       0x02000000
-#define AR_ISR_QCBRURN       0x04000000
-#define AR_ISR_QTRIG         0x08000000
-#define AR_ISR_GENTMR        0x10000000
-
-#define AR_ISR_TXMINTR       0x00080000
-#define AR_ISR_RXMINTR       0x01000000
-#define AR_ISR_TXINTM        0x40000000
-#define AR_ISR_RXINTM        0x80000000
-
-#define AR_ISR_S0               0x0084
-#define AR_ISR_S0_QCU_TXOK      0x000003FF
-#define AR_ISR_S0_QCU_TXOK_S    0
-#define AR_ISR_S0_QCU_TXDESC    0x03FF0000
-#define AR_ISR_S0_QCU_TXDESC_S  16
-
-#define AR_ISR_S1              0x0088
-#define AR_ISR_S1_QCU_TXERR    0x000003FF
-#define AR_ISR_S1_QCU_TXERR_S  0
-#define AR_ISR_S1_QCU_TXEOL    0x03FF0000
-#define AR_ISR_S1_QCU_TXEOL_S  16
-
-#define AR_ISR_S2              0x008c
-#define AR_ISR_S2_QCU_TXURN    0x000003FF
-#define AR_ISR_S2_CST          0x00400000
-#define AR_ISR_S2_GTT          0x00800000
-#define AR_ISR_S2_TIM          0x01000000
-#define AR_ISR_S2_CABEND       0x02000000
-#define AR_ISR_S2_DTIMSYNC     0x04000000
-#define AR_ISR_S2_BCNTO        0x08000000
-#define AR_ISR_S2_CABTO        0x10000000
-#define AR_ISR_S2_DTIM         0x20000000
-#define AR_ISR_S2_TSFOOR       0x40000000
-#define AR_ISR_S2_TBTT_TIME    0x80000000
-
-#define AR_ISR_S3             0x0090
-#define AR_ISR_S3_QCU_QCBROVF    0x000003FF
-#define AR_ISR_S3_QCU_QCBRURN    0x03FF0000
-
-#define AR_ISR_S4              0x0094
-#define AR_ISR_S4_QCU_QTRIG    0x000003FF
-#define AR_ISR_S4_RESV0        0xFFFFFC00
-
-#define AR_ISR_S5                   0x0098
-#define AR_ISR_S5_TIMER_TRIG        0x000000FF
-#define AR_ISR_S5_TIMER_THRESH      0x0007FE00
-#define AR_ISR_S5_TIM_TIMER         0x00000010
-#define AR_ISR_S5_DTIM_TIMER        0x00000020
-#define AR_ISR_S5_S                 0x00d8
-#define AR_IMR_S5                   0x00b8
-#define AR_IMR_S5_TIM_TIMER         0x00000010
-#define AR_IMR_S5_DTIM_TIMER        0x00000020
-
-
-#define AR_IMR               0x00a0
-#define AR_IMR_RXOK          0x00000001
-#define AR_IMR_RXDESC        0x00000002
-#define AR_IMR_RXERR         0x00000004
-#define AR_IMR_RXNOPKT       0x00000008
-#define AR_IMR_RXEOL         0x00000010
-#define AR_IMR_RXORN         0x00000020
-#define AR_IMR_TXOK          0x00000040
-#define AR_IMR_TXDESC        0x00000080
-#define AR_IMR_TXERR         0x00000100
-#define AR_IMR_TXNOPKT       0x00000200
-#define AR_IMR_TXEOL         0x00000400
-#define AR_IMR_TXURN         0x00000800
-#define AR_IMR_MIB           0x00001000
-#define AR_IMR_SWI           0x00002000
-#define AR_IMR_RXPHY         0x00004000
-#define AR_IMR_RXKCM         0x00008000
-#define AR_IMR_SWBA          0x00010000
-#define AR_IMR_BRSSI         0x00020000
-#define AR_IMR_BMISS         0x00040000
-#define AR_IMR_BNR           0x00100000
-#define AR_IMR_RXCHIRP       0x00200000
-#define AR_IMR_BCNMISC       0x00800000
-#define AR_IMR_TIM           0x00800000
-#define AR_IMR_QCBROVF       0x02000000
-#define AR_IMR_QCBRURN       0x04000000
-#define AR_IMR_QTRIG         0x08000000
-#define AR_IMR_GENTMR        0x10000000
-
-#define AR_IMR_TXMINTR       0x00080000
-#define AR_IMR_RXMINTR       0x01000000
-#define AR_IMR_TXINTM        0x40000000
-#define AR_IMR_RXINTM        0x80000000
-
-#define AR_IMR_S0               0x00a4
-#define AR_IMR_S0_QCU_TXOK      0x000003FF
-#define AR_IMR_S0_QCU_TXOK_S    0
-#define AR_IMR_S0_QCU_TXDESC    0x03FF0000
-#define AR_IMR_S0_QCU_TXDESC_S  16
-
-#define AR_IMR_S1              0x00a8
-#define AR_IMR_S1_QCU_TXERR    0x000003FF
-#define AR_IMR_S1_QCU_TXERR_S  0
-#define AR_IMR_S1_QCU_TXEOL    0x03FF0000
-#define AR_IMR_S1_QCU_TXEOL_S  16
-
-#define AR_IMR_S2              0x00ac
-#define AR_IMR_S2_QCU_TXURN    0x000003FF
-#define AR_IMR_S2_QCU_TXURN_S  0
-#define AR_IMR_S2_CST          0x00400000
-#define AR_IMR_S2_GTT          0x00800000
-#define AR_IMR_S2_TIM          0x01000000
-#define AR_IMR_S2_CABEND       0x02000000
-#define AR_IMR_S2_DTIMSYNC     0x04000000
-#define AR_IMR_S2_BCNTO        0x08000000
-#define AR_IMR_S2_CABTO        0x10000000
-#define AR_IMR_S2_DTIM         0x20000000
-#define AR_IMR_S2_TSFOOR       0x40000000
-
-#define AR_IMR_S3                0x00b0
-#define AR_IMR_S3_QCU_QCBROVF    0x000003FF
-#define AR_IMR_S3_QCU_QCBRURN    0x03FF0000
-#define AR_IMR_S3_QCU_QCBRURN_S  16
-
-#define AR_IMR_S4              0x00b4
-#define AR_IMR_S4_QCU_QTRIG    0x000003FF
-#define AR_IMR_S4_RESV0        0xFFFFFC00
-
-#define AR_IMR_S5              0x00b8
-#define AR_IMR_S5_TIMER_TRIG        0x000000FF
-#define AR_IMR_S5_TIMER_THRESH      0x0000FF00
-
-
-#define AR_ISR_RAC            0x00c0
-#define AR_ISR_S0_S           0x00c4
-#define AR_ISR_S0_QCU_TXOK      0x000003FF
-#define AR_ISR_S0_QCU_TXOK_S    0
-#define AR_ISR_S0_QCU_TXDESC    0x03FF0000
-#define AR_ISR_S0_QCU_TXDESC_S  16
-
-#define AR_ISR_S1_S           0x00c8
-#define AR_ISR_S1_QCU_TXERR    0x000003FF
-#define AR_ISR_S1_QCU_TXERR_S  0
-#define AR_ISR_S1_QCU_TXEOL    0x03FF0000
-#define AR_ISR_S1_QCU_TXEOL_S  16
-
-#define AR_ISR_S2_S           0x00cc
-#define AR_ISR_S3_S           0x00d0
-#define AR_ISR_S4_S           0x00d4
-#define AR_ISR_S5_S           0x00d8
-#define AR_DMADBG_0           0x00e0
-#define AR_DMADBG_1           0x00e4
-#define AR_DMADBG_2           0x00e8
-#define AR_DMADBG_3           0x00ec
-#define AR_DMADBG_4           0x00f0
-#define AR_DMADBG_5           0x00f4
-#define AR_DMADBG_6           0x00f8
-#define AR_DMADBG_7           0x00fc
-
-#define AR_NUM_QCU      10
-#define AR_QCU_0        0x0001
-#define AR_QCU_1        0x0002
-#define AR_QCU_2        0x0004
-#define AR_QCU_3        0x0008
-#define AR_QCU_4        0x0010
-#define AR_QCU_5        0x0020
-#define AR_QCU_6        0x0040
-#define AR_QCU_7        0x0080
-#define AR_QCU_8        0x0100
-#define AR_QCU_9        0x0200
-
-#define AR_Q0_TXDP           0x0800
-#define AR_Q1_TXDP           0x0804
-#define AR_Q2_TXDP           0x0808
-#define AR_Q3_TXDP           0x080c
-#define AR_Q4_TXDP           0x0810
-#define AR_Q5_TXDP           0x0814
-#define AR_Q6_TXDP           0x0818
-#define AR_Q7_TXDP           0x081c
-#define AR_Q8_TXDP           0x0820
-#define AR_Q9_TXDP           0x0824
-#define AR_QTXDP(_i)    (AR_Q0_TXDP + ((_i)<<2))
-
-#define AR_Q_TXE             0x0840
-#define AR_Q_TXE_M           0x000003FF
-
-#define AR_Q_TXD             0x0880
-#define AR_Q_TXD_M           0x000003FF
-
-#define AR_Q0_CBRCFG         0x08c0
-#define AR_Q1_CBRCFG         0x08c4
-#define AR_Q2_CBRCFG         0x08c8
-#define AR_Q3_CBRCFG         0x08cc
-#define AR_Q4_CBRCFG         0x08d0
-#define AR_Q5_CBRCFG         0x08d4
-#define AR_Q6_CBRCFG         0x08d8
-#define AR_Q7_CBRCFG         0x08dc
-#define AR_Q8_CBRCFG         0x08e0
-#define AR_Q9_CBRCFG         0x08e4
-#define AR_QCBRCFG(_i)      (AR_Q0_CBRCFG + ((_i)<<2))
-#define AR_Q_CBRCFG_INTERVAL     0x00FFFFFF
-#define AR_Q_CBRCFG_INTERVAL_S   0
-#define AR_Q_CBRCFG_OVF_THRESH   0xFF000000
-#define AR_Q_CBRCFG_OVF_THRESH_S 24
-
-#define AR_Q0_RDYTIMECFG         0x0900
-#define AR_Q1_RDYTIMECFG         0x0904
-#define AR_Q2_RDYTIMECFG         0x0908
-#define AR_Q3_RDYTIMECFG         0x090c
-#define AR_Q4_RDYTIMECFG         0x0910
-#define AR_Q5_RDYTIMECFG         0x0914
-#define AR_Q6_RDYTIMECFG         0x0918
-#define AR_Q7_RDYTIMECFG         0x091c
-#define AR_Q8_RDYTIMECFG         0x0920
-#define AR_Q9_RDYTIMECFG         0x0924
-#define AR_QRDYTIMECFG(_i)       (AR_Q0_RDYTIMECFG + ((_i)<<2))
-#define AR_Q_RDYTIMECFG_DURATION   0x00FFFFFF
-#define AR_Q_RDYTIMECFG_DURATION_S 0
-#define AR_Q_RDYTIMECFG_EN         0x01000000
-
-#define AR_Q_ONESHOTARM_SC       0x0940
-#define AR_Q_ONESHOTARM_SC_M     0x000003FF
-#define AR_Q_ONESHOTARM_SC_RESV0 0xFFFFFC00
-
-#define AR_Q_ONESHOTARM_CC       0x0980
-#define AR_Q_ONESHOTARM_CC_M     0x000003FF
-#define AR_Q_ONESHOTARM_CC_RESV0 0xFFFFFC00
-
-#define AR_Q0_MISC         0x09c0
-#define AR_Q1_MISC         0x09c4
-#define AR_Q2_MISC         0x09c8
-#define AR_Q3_MISC         0x09cc
-#define AR_Q4_MISC         0x09d0
-#define AR_Q5_MISC         0x09d4
-#define AR_Q6_MISC         0x09d8
-#define AR_Q7_MISC         0x09dc
-#define AR_Q8_MISC         0x09e0
-#define AR_Q9_MISC         0x09e4
-#define AR_QMISC(_i)       (AR_Q0_MISC + ((_i)<<2))
-#define AR_Q_MISC_FSP                     0x0000000F
-#define AR_Q_MISC_FSP_ASAP                0
-#define AR_Q_MISC_FSP_CBR                 1
-#define AR_Q_MISC_FSP_DBA_GATED           2
-#define AR_Q_MISC_FSP_TIM_GATED           3
-#define AR_Q_MISC_FSP_BEACON_SENT_GATED   4
-#define AR_Q_MISC_FSP_BEACON_RCVD_GATED   5
-#define AR_Q_MISC_ONE_SHOT_EN             0x00000010
-#define AR_Q_MISC_CBR_INCR_DIS1           0x00000020
-#define AR_Q_MISC_CBR_INCR_DIS0           0x00000040
-#define AR_Q_MISC_BEACON_USE              0x00000080
-#define AR_Q_MISC_CBR_EXP_CNTR_LIMIT_EN   0x00000100
-#define AR_Q_MISC_RDYTIME_EXP_POLICY      0x00000200
-#define AR_Q_MISC_RESET_CBR_EXP_CTR       0x00000400
-#define AR_Q_MISC_DCU_EARLY_TERM_REQ      0x00000800
-#define AR_Q_MISC_RESV0                   0xFFFFF000
-
-#define AR_Q0_STS         0x0a00
-#define AR_Q1_STS         0x0a04
-#define AR_Q2_STS         0x0a08
-#define AR_Q3_STS         0x0a0c
-#define AR_Q4_STS         0x0a10
-#define AR_Q5_STS         0x0a14
-#define AR_Q6_STS         0x0a18
-#define AR_Q7_STS         0x0a1c
-#define AR_Q8_STS         0x0a20
-#define AR_Q9_STS         0x0a24
-#define AR_QSTS(_i)       (AR_Q0_STS + ((_i)<<2))
-#define AR_Q_STS_PEND_FR_CNT          0x00000003
-#define AR_Q_STS_RESV0                0x000000FC
-#define AR_Q_STS_CBR_EXP_CNT          0x0000FF00
-#define AR_Q_STS_RESV1                0xFFFF0000
-
-#define AR_Q_RDYTIMESHDN    0x0a40
-#define AR_Q_RDYTIMESHDN_M  0x000003FF
-
-
-#define AR_NUM_DCU      10
-#define AR_DCU_0        0x0001
-#define AR_DCU_1        0x0002
-#define AR_DCU_2        0x0004
-#define AR_DCU_3        0x0008
-#define AR_DCU_4        0x0010
-#define AR_DCU_5        0x0020
-#define AR_DCU_6        0x0040
-#define AR_DCU_7        0x0080
-#define AR_DCU_8        0x0100
-#define AR_DCU_9        0x0200
-
-#define AR_D0_QCUMASK     0x1000
-#define AR_D1_QCUMASK     0x1004
-#define AR_D2_QCUMASK     0x1008
-#define AR_D3_QCUMASK     0x100c
-#define AR_D4_QCUMASK     0x1010
-#define AR_D5_QCUMASK     0x1014
-#define AR_D6_QCUMASK     0x1018
-#define AR_D7_QCUMASK     0x101c
-#define AR_D8_QCUMASK     0x1020
-#define AR_D9_QCUMASK     0x1024
-#define AR_DQCUMASK(_i)   (AR_D0_QCUMASK + ((_i)<<2))
-#define AR_D_QCUMASK         0x000003FF
-#define AR_D_QCUMASK_RESV0   0xFFFFFC00
-
-#define AR_D_TXBLK_CMD  0x1038
-#define AR_D_TXBLK_DATA(i) (AR_D_TXBLK_CMD+(i))
-
-#define AR_D0_LCL_IFS     0x1040
-#define AR_D1_LCL_IFS     0x1044
-#define AR_D2_LCL_IFS     0x1048
-#define AR_D3_LCL_IFS     0x104c
-#define AR_D4_LCL_IFS     0x1050
-#define AR_D5_LCL_IFS     0x1054
-#define AR_D6_LCL_IFS     0x1058
-#define AR_D7_LCL_IFS     0x105c
-#define AR_D8_LCL_IFS     0x1060
-#define AR_D9_LCL_IFS     0x1064
-#define AR_DLCL_IFS(_i)   (AR_D0_LCL_IFS + ((_i)<<2))
-#define AR_D_LCL_IFS_CWMIN       0x000003FF
-#define AR_D_LCL_IFS_CWMIN_S     0
-#define AR_D_LCL_IFS_CWMAX       0x000FFC00
-#define AR_D_LCL_IFS_CWMAX_S     10
-#define AR_D_LCL_IFS_AIFS        0x0FF00000
-#define AR_D_LCL_IFS_AIFS_S      20
-
-#define AR_D_LCL_IFS_RESV0    0xF0000000
-
-#define AR_D0_RETRY_LIMIT     0x1080
-#define AR_D1_RETRY_LIMIT     0x1084
-#define AR_D2_RETRY_LIMIT     0x1088
-#define AR_D3_RETRY_LIMIT     0x108c
-#define AR_D4_RETRY_LIMIT     0x1090
-#define AR_D5_RETRY_LIMIT     0x1094
-#define AR_D6_RETRY_LIMIT     0x1098
-#define AR_D7_RETRY_LIMIT     0x109c
-#define AR_D8_RETRY_LIMIT     0x10a0
-#define AR_D9_RETRY_LIMIT     0x10a4
-#define AR_DRETRY_LIMIT(_i)   (AR_D0_RETRY_LIMIT + ((_i)<<2))
-#define AR_D_RETRY_LIMIT_FR_SH       0x0000000F
-#define AR_D_RETRY_LIMIT_FR_SH_S     0
-#define AR_D_RETRY_LIMIT_STA_SH      0x00003F00
-#define AR_D_RETRY_LIMIT_STA_SH_S    8
-#define AR_D_RETRY_LIMIT_STA_LG      0x000FC000
-#define AR_D_RETRY_LIMIT_STA_LG_S    14
-#define AR_D_RETRY_LIMIT_RESV0       0xFFF00000
-
-#define AR_D0_CHNTIME     0x10c0
-#define AR_D1_CHNTIME     0x10c4
-#define AR_D2_CHNTIME     0x10c8
-#define AR_D3_CHNTIME     0x10cc
-#define AR_D4_CHNTIME     0x10d0
-#define AR_D5_CHNTIME     0x10d4
-#define AR_D6_CHNTIME     0x10d8
-#define AR_D7_CHNTIME     0x10dc
-#define AR_D8_CHNTIME     0x10e0
-#define AR_D9_CHNTIME     0x10e4
-#define AR_DCHNTIME(_i)   (AR_D0_CHNTIME + ((_i)<<2))
-#define AR_D_CHNTIME_DUR         0x000FFFFF
-#define AR_D_CHNTIME_DUR_S       0
-#define AR_D_CHNTIME_EN          0x00100000
-#define AR_D_CHNTIME_RESV0       0xFFE00000
-
-#define AR_D0_MISC        0x1100
-#define AR_D1_MISC        0x1104
-#define AR_D2_MISC        0x1108
-#define AR_D3_MISC        0x110c
-#define AR_D4_MISC        0x1110
-#define AR_D5_MISC        0x1114
-#define AR_D6_MISC        0x1118
-#define AR_D7_MISC        0x111c
-#define AR_D8_MISC        0x1120
-#define AR_D9_MISC        0x1124
-#define AR_DMISC(_i)      (AR_D0_MISC + ((_i)<<2))
-#define AR_D_MISC_BKOFF_THRESH        0x0000003F
-#define AR_D_MISC_RETRY_CNT_RESET_EN  0x00000040
-#define AR_D_MISC_CW_RESET_EN         0x00000080
-#define AR_D_MISC_FRAG_WAIT_EN        0x00000100
-#define AR_D_MISC_FRAG_BKOFF_EN       0x00000200
-#define AR_D_MISC_CW_BKOFF_EN         0x00001000
-#define AR_D_MISC_VIR_COL_HANDLING    0x0000C000
-#define AR_D_MISC_VIR_COL_HANDLING_S  14
-#define AR_D_MISC_VIR_COL_HANDLING_DEFAULT 0
-#define AR_D_MISC_VIR_COL_HANDLING_IGNORE  1
-#define AR_D_MISC_BEACON_USE          0x00010000
-#define AR_D_MISC_ARB_LOCKOUT_CNTRL   0x00060000
-#define AR_D_MISC_ARB_LOCKOUT_CNTRL_S 17
-#define AR_D_MISC_ARB_LOCKOUT_CNTRL_NONE     0
-#define AR_D_MISC_ARB_LOCKOUT_CNTRL_INTRA_FR 1
-#define AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL   2
-#define AR_D_MISC_ARB_LOCKOUT_IGNORE  0x00080000
-#define AR_D_MISC_SEQ_NUM_INCR_DIS    0x00100000
-#define AR_D_MISC_POST_FR_BKOFF_DIS   0x00200000
-#define AR_D_MISC_VIT_COL_CW_BKOFF_EN 0x00400000
-#define AR_D_MISC_BLOWN_IFS_RETRY_EN  0x00800000
-#define AR_D_MISC_RESV0               0xFF000000
-
-#define AR_D_SEQNUM      0x1140
-
-#define AR_D_GBL_IFS_SIFS         0x1030
-#define AR_D_GBL_IFS_SIFS_M       0x0000FFFF
-#define AR_D_GBL_IFS_SIFS_RESV0   0xFFFFFFFF
-
-#define AR_D_TXBLK_BASE            0x1038
-#define AR_D_TXBLK_WRITE_BITMASK    0x0000FFFF
-#define AR_D_TXBLK_WRITE_BITMASK_S  0
-#define AR_D_TXBLK_WRITE_SLICE      0x000F0000
-#define AR_D_TXBLK_WRITE_SLICE_S    16
-#define AR_D_TXBLK_WRITE_DCU        0x00F00000
-#define AR_D_TXBLK_WRITE_DCU_S      20
-#define AR_D_TXBLK_WRITE_COMMAND    0x0F000000
-#define AR_D_TXBLK_WRITE_COMMAND_S      24
-
-#define AR_D_GBL_IFS_SLOT         0x1070
-#define AR_D_GBL_IFS_SLOT_M       0x0000FFFF
-#define AR_D_GBL_IFS_SLOT_RESV0   0xFFFF0000
-
-#define AR_D_GBL_IFS_EIFS         0x10b0
-#define AR_D_GBL_IFS_EIFS_M       0x0000FFFF
-#define AR_D_GBL_IFS_EIFS_RESV0   0xFFFF0000
-
-#define AR_D_GBL_IFS_MISC        0x10f0
-#define AR_D_GBL_IFS_MISC_LFSR_SLICE_SEL        0x00000007
-#define AR_D_GBL_IFS_MISC_TURBO_MODE            0x00000008
-#define AR_D_GBL_IFS_MISC_USEC_DURATION         0x000FFC00
-#define AR_D_GBL_IFS_MISC_DCU_ARBITER_DLY       0x00300000
-#define AR_D_GBL_IFS_MISC_RANDOM_LFSR_SLICE_DIS 0x01000000
-#define AR_D_GBL_IFS_MISC_SLOT_XMIT_WIND_LEN    0x06000000
-#define AR_D_GBL_IFS_MISC_FORCE_XMIT_SLOT_BOUND 0x08000000
-#define AR_D_GBL_IFS_MISC_IGNORE_BACKOFF        0x10000000
-
-#define AR_D_FPCTL                  0x1230
-#define AR_D_FPCTL_DCU              0x0000000F
-#define AR_D_FPCTL_DCU_S            0
-#define AR_D_FPCTL_PREFETCH_EN      0x00000010
-#define AR_D_FPCTL_BURST_PREFETCH   0x00007FE0
-#define AR_D_FPCTL_BURST_PREFETCH_S 5
-
-#define AR_D_TXPSE                 0x1270
-#define AR_D_TXPSE_CTRL            0x000003FF
-#define AR_D_TXPSE_RESV0           0x0000FC00
-#define AR_D_TXPSE_STATUS          0x00010000
-#define AR_D_TXPSE_RESV1           0xFFFE0000
-
-#define AR_D_TXSLOTMASK            0x12f0
-#define AR_D_TXSLOTMASK_NUM        0x0000000F
-
-#define AR_CFG_LED                     0x1f04
-#define AR_CFG_SCLK_RATE_IND           0x00000003
-#define AR_CFG_SCLK_RATE_IND_S         0
-#define AR_CFG_SCLK_32MHZ              0x00000000
-#define AR_CFG_SCLK_4MHZ               0x00000001
-#define AR_CFG_SCLK_1MHZ               0x00000002
-#define AR_CFG_SCLK_32KHZ              0x00000003
-#define AR_CFG_LED_BLINK_SLOW          0x00000008
-#define AR_CFG_LED_BLINK_THRESH_SEL    0x00000070
-#define AR_CFG_LED_MODE_SEL            0x00000380
-#define AR_CFG_LED_MODE_SEL_S          7
-#define AR_CFG_LED_POWER               0x00000280
-#define AR_CFG_LED_POWER_S             7
-#define AR_CFG_LED_NETWORK             0x00000300
-#define AR_CFG_LED_NETWORK_S           7
-#define AR_CFG_LED_MODE_PROP           0x0
-#define AR_CFG_LED_MODE_RPROP          0x1
-#define AR_CFG_LED_MODE_SPLIT          0x2
-#define AR_CFG_LED_MODE_RAND           0x3
-#define AR_CFG_LED_MODE_POWER_OFF      0x4
-#define AR_CFG_LED_MODE_POWER_ON       0x5
-#define AR_CFG_LED_MODE_NETWORK_OFF    0x4
-#define AR_CFG_LED_MODE_NETWORK_ON     0x6
-#define AR_CFG_LED_ASSOC_CTL           0x00000c00
-#define AR_CFG_LED_ASSOC_CTL_S         10
-#define AR_CFG_LED_ASSOC_NONE          0x0
-#define AR_CFG_LED_ASSOC_ACTIVE        0x1
-#define AR_CFG_LED_ASSOC_PENDING       0x2
-
-#define AR_CFG_LED_BLINK_SLOW          0x00000008
-#define AR_CFG_LED_BLINK_SLOW_S        3
-
-#define AR_CFG_LED_BLINK_THRESH_SEL    0x00000070
-#define AR_CFG_LED_BLINK_THRESH_SEL_S  4
-
-#define AR_MAC_SLEEP                0x1f00
-#define AR_MAC_SLEEP_MAC_AWAKE      0x00000000
-#define AR_MAC_SLEEP_MAC_ASLEEP     0x00000001
-
-#define AR_RC                0x4000
-#define AR_RC_AHB            0x00000001
-#define AR_RC_APB            0x00000002
-#define AR_RC_HOSTIF         0x00000100
-
-#define AR_WA                          0x4004
-#define AR9285_WA_DEFAULT              0x004a05cb
-#define AR9280_WA_DEFAULT              0x0040073f
-#define AR_WA_DEFAULT                  0x0000073f
-
-
-#define AR_PM_STATE                 0x4008
-#define AR_PM_STATE_PME_D3COLD_VAUX 0x00100000
-
-#define AR_HOST_TIMEOUT             0x4018
-#define AR_HOST_TIMEOUT_APB_CNTR    0x0000FFFF
-#define AR_HOST_TIMEOUT_APB_CNTR_S  0
-#define AR_HOST_TIMEOUT_LCL_CNTR    0xFFFF0000
-#define AR_HOST_TIMEOUT_LCL_CNTR_S  16
-
-#define AR_EEPROM                0x401c
-#define AR_EEPROM_ABSENT         0x00000100
-#define AR_EEPROM_CORRUPT        0x00000200
-#define AR_EEPROM_PROT_MASK      0x03FFFC00
-#define AR_EEPROM_PROT_MASK_S    10
-
-#define EEPROM_PROTECT_RP_0_31        0x0001
-#define EEPROM_PROTECT_WP_0_31        0x0002
-#define EEPROM_PROTECT_RP_32_63       0x0004
-#define EEPROM_PROTECT_WP_32_63       0x0008
-#define EEPROM_PROTECT_RP_64_127      0x0010
-#define EEPROM_PROTECT_WP_64_127      0x0020
-#define EEPROM_PROTECT_RP_128_191     0x0040
-#define EEPROM_PROTECT_WP_128_191     0x0080
-#define EEPROM_PROTECT_RP_192_255     0x0100
-#define EEPROM_PROTECT_WP_192_255     0x0200
-#define EEPROM_PROTECT_RP_256_511     0x0400
-#define EEPROM_PROTECT_WP_256_511     0x0800
-#define EEPROM_PROTECT_RP_512_1023    0x1000
-#define EEPROM_PROTECT_WP_512_1023    0x2000
-#define EEPROM_PROTECT_RP_1024_2047   0x4000
-#define EEPROM_PROTECT_WP_1024_2047   0x8000
-
-#define AR_SREV \
-       ((AR_SREV_9100(ah)) ? 0x0600 : 0x4020)
-
-#define AR_SREV_ID \
-       ((AR_SREV_9100(ah)) ? 0x00000FFF : 0x000000FF)
-#define AR_SREV_VERSION                       0x000000F0
-#define AR_SREV_VERSION_S                     4
-#define AR_SREV_REVISION                      0x00000007
-
-#define AR_SREV_ID2                           0xFFFFFFFF
-#define AR_SREV_VERSION2                     0xFFFC0000
-#define AR_SREV_VERSION2_S                    18
-#define AR_SREV_TYPE2                        0x0003F000
-#define AR_SREV_TYPE2_S                       12
-#define AR_SREV_TYPE2_CHAIN                  0x00001000
-#define AR_SREV_TYPE2_HOST_MODE                      0x00002000
-#define AR_SREV_REVISION2                    0x00000F00
-#define AR_SREV_REVISION2_S                  8
-
-#define AR_SREV_VERSION_5416_PCI               0xD
-#define AR_SREV_VERSION_5416_PCIE              0xC
-#define AR_SREV_REVISION_5416_10               0
-#define AR_SREV_REVISION_5416_20               1
-#define AR_SREV_REVISION_5416_22               2
-#define AR_SREV_VERSION_9100                  0x14
-#define AR_SREV_VERSION_9160                 0x40
-#define AR_SREV_REVISION_9160_10             0
-#define AR_SREV_REVISION_9160_11             1
-#define AR_SREV_VERSION_9280                0x80
-#define AR_SREV_REVISION_9280_10            0
-#define AR_SREV_REVISION_9280_20            1
-#define AR_SREV_REVISION_9280_21            2
-#define AR_SREV_VERSION_9285                  0xC0
-#define AR_SREV_REVISION_9285_10              0
-#define AR_SREV_REVISION_9285_11              1
-#define AR_SREV_REVISION_9285_12              2
-
-#define AR_SREV_5416(_ah) \
-       (((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) || \
-        ((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCIE))
-#define AR_SREV_5416_20_OR_LATER(_ah) \
-       (((AR_SREV_5416(_ah)) && \
-        ((_ah)->hw_version.macRev >= AR_SREV_REVISION_5416_20)) || \
-        ((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9100))
-#define AR_SREV_5416_22_OR_LATER(_ah) \
-       (((AR_SREV_5416(_ah)) && \
-        ((_ah)->hw_version.macRev >= AR_SREV_REVISION_5416_22)) || \
-        ((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9100))
-
-#define AR_SREV_9100(ah) \
-       ((ah->hw_version.macVersion) == AR_SREV_VERSION_9100)
-#define AR_SREV_9100_OR_LATER(_ah) \
-       (((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9100))
-
-#define AR_SREV_9160(_ah) \
-       (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9160))
-#define AR_SREV_9160_10_OR_LATER(_ah) \
-       (((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9160))
-#define AR_SREV_9160_11(_ah) \
-       (AR_SREV_9160(_ah) && \
-        ((_ah)->hw_version.macRev == AR_SREV_REVISION_9160_11))
-#define AR_SREV_9280(_ah) \
-       (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9280))
-#define AR_SREV_9280_10_OR_LATER(_ah) \
-       (((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9280))
-#define AR_SREV_9280_20(_ah) \
-       (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9280) && \
-               ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9280_20))
-#define AR_SREV_9280_20_OR_LATER(_ah) \
-       (((_ah)->hw_version.macVersion > AR_SREV_VERSION_9280) || \
-       (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9280) && \
-       ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9280_20)))
-
-#define AR_SREV_9285(_ah) \
-       (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9285))
-#define AR_SREV_9285_10_OR_LATER(_ah) \
-       (((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9285))
-#define AR_SREV_9285_11(_ah) \
-       (AR_SREV_9285(ah) && \
-        ((_ah)->hw_version.macRev == AR_SREV_REVISION_9285_11))
-#define AR_SREV_9285_11_OR_LATER(_ah) \
-       (((_ah)->hw_version.macVersion > AR_SREV_VERSION_9285) || \
-        (AR_SREV_9285(ah) && ((_ah)->hw_version.macRev >= \
-                              AR_SREV_REVISION_9285_11)))
-#define AR_SREV_9285_12(_ah) \
-       (AR_SREV_9285(ah) && \
-        ((_ah)->hw_version.macRev == AR_SREV_REVISION_9285_12))
-#define AR_SREV_9285_12_OR_LATER(_ah) \
-       (((_ah)->hw_version.macVersion > AR_SREV_VERSION_9285) || \
-        (AR_SREV_9285(ah) && ((_ah)->hw_version.macRev >= \
-                              AR_SREV_REVISION_9285_12)))
-
-#define AR_RADIO_SREV_MAJOR                   0xf0
-#define AR_RAD5133_SREV_MAJOR                 0xc0
-#define AR_RAD2133_SREV_MAJOR                 0xd0
-#define AR_RAD5122_SREV_MAJOR                 0xe0
-#define AR_RAD2122_SREV_MAJOR                 0xf0
-
-#define AR_AHB_MODE                           0x4024
-#define AR_AHB_EXACT_WR_EN                    0x00000000
-#define AR_AHB_BUF_WR_EN                      0x00000001
-#define AR_AHB_EXACT_RD_EN                    0x00000000
-#define AR_AHB_CACHELINE_RD_EN                0x00000002
-#define AR_AHB_PREFETCH_RD_EN                 0x00000004
-#define AR_AHB_PAGE_SIZE_1K                   0x00000000
-#define AR_AHB_PAGE_SIZE_2K                   0x00000008
-#define AR_AHB_PAGE_SIZE_4K                   0x00000010
-
-#define AR_INTR_RTC_IRQ                       0x00000001
-#define AR_INTR_MAC_IRQ                       0x00000002
-#define AR_INTR_EEP_PROT_ACCESS               0x00000004
-#define AR_INTR_MAC_AWAKE                     0x00020000
-#define AR_INTR_MAC_ASLEEP                    0x00040000
-#define AR_INTR_SPURIOUS                      0xFFFFFFFF
-
-
-#define AR_INTR_SYNC_CAUSE_CLR                0x4028
-
-#define AR_INTR_SYNC_CAUSE                    0x4028
-
-#define AR_INTR_SYNC_ENABLE                   0x402c
-#define AR_INTR_SYNC_ENABLE_GPIO              0xFFFC0000
-#define AR_INTR_SYNC_ENABLE_GPIO_S            18
-
-enum {
-       AR_INTR_SYNC_RTC_IRQ = 0x00000001,
-       AR_INTR_SYNC_MAC_IRQ = 0x00000002,
-       AR_INTR_SYNC_EEPROM_ILLEGAL_ACCESS = 0x00000004,
-       AR_INTR_SYNC_APB_TIMEOUT = 0x00000008,
-       AR_INTR_SYNC_PCI_MODE_CONFLICT = 0x00000010,
-       AR_INTR_SYNC_HOST1_FATAL = 0x00000020,
-       AR_INTR_SYNC_HOST1_PERR = 0x00000040,
-       AR_INTR_SYNC_TRCV_FIFO_PERR = 0x00000080,
-       AR_INTR_SYNC_RADM_CPL_EP = 0x00000100,
-       AR_INTR_SYNC_RADM_CPL_DLLP_ABORT = 0x00000200,
-       AR_INTR_SYNC_RADM_CPL_TLP_ABORT = 0x00000400,
-       AR_INTR_SYNC_RADM_CPL_ECRC_ERR = 0x00000800,
-       AR_INTR_SYNC_RADM_CPL_TIMEOUT = 0x00001000,
-       AR_INTR_SYNC_LOCAL_TIMEOUT = 0x00002000,
-       AR_INTR_SYNC_PM_ACCESS = 0x00004000,
-       AR_INTR_SYNC_MAC_AWAKE = 0x00008000,
-       AR_INTR_SYNC_MAC_ASLEEP = 0x00010000,
-       AR_INTR_SYNC_MAC_SLEEP_ACCESS = 0x00020000,
-       AR_INTR_SYNC_ALL = 0x0003FFFF,
-
-
-       AR_INTR_SYNC_DEFAULT = (AR_INTR_SYNC_HOST1_FATAL |
-                               AR_INTR_SYNC_HOST1_PERR |
-                               AR_INTR_SYNC_RADM_CPL_EP |
-                               AR_INTR_SYNC_RADM_CPL_DLLP_ABORT |
-                               AR_INTR_SYNC_RADM_CPL_TLP_ABORT |
-                               AR_INTR_SYNC_RADM_CPL_ECRC_ERR |
-                               AR_INTR_SYNC_RADM_CPL_TIMEOUT |
-                               AR_INTR_SYNC_LOCAL_TIMEOUT |
-                               AR_INTR_SYNC_MAC_SLEEP_ACCESS),
-
-       AR_INTR_SYNC_SPURIOUS = 0xFFFFFFFF,
-
-};
-
-#define AR_INTR_ASYNC_MASK                       0x4030
-#define AR_INTR_ASYNC_MASK_GPIO                  0xFFFC0000
-#define AR_INTR_ASYNC_MASK_GPIO_S                18
-
-#define AR_INTR_SYNC_MASK                        0x4034
-#define AR_INTR_SYNC_MASK_GPIO                   0xFFFC0000
-#define AR_INTR_SYNC_MASK_GPIO_S                 18
-
-#define AR_INTR_ASYNC_CAUSE_CLR                  0x4038
-#define AR_INTR_ASYNC_CAUSE                      0x4038
-
-#define AR_INTR_ASYNC_ENABLE                     0x403c
-#define AR_INTR_ASYNC_ENABLE_GPIO                0xFFFC0000
-#define AR_INTR_ASYNC_ENABLE_GPIO_S              18
-
-#define AR_PCIE_SERDES                           0x4040
-#define AR_PCIE_SERDES2                          0x4044
-#define AR_PCIE_PM_CTRL                          0x4014
-#define AR_PCIE_PM_CTRL_ENA                      0x00080000
-
-#define AR_NUM_GPIO                              14
-#define AR928X_NUM_GPIO                          10
-#define AR9285_NUM_GPIO                          12
-
-#define AR_GPIO_IN_OUT                           0x4048
-#define AR_GPIO_IN_VAL                           0x0FFFC000
-#define AR_GPIO_IN_VAL_S                         14
-#define AR928X_GPIO_IN_VAL                       0x000FFC00
-#define AR928X_GPIO_IN_VAL_S                     10
-#define AR9285_GPIO_IN_VAL                       0x00FFF000
-#define AR9285_GPIO_IN_VAL_S                     12
-
-#define AR_GPIO_OE_OUT                           0x404c
-#define AR_GPIO_OE_OUT_DRV                       0x3
-#define AR_GPIO_OE_OUT_DRV_NO                    0x0
-#define AR_GPIO_OE_OUT_DRV_LOW                   0x1
-#define AR_GPIO_OE_OUT_DRV_HI                    0x2
-#define AR_GPIO_OE_OUT_DRV_ALL                   0x3
-
-#define AR_GPIO_INTR_POL                         0x4050
-#define AR_GPIO_INTR_POL_VAL                     0x00001FFF
-#define AR_GPIO_INTR_POL_VAL_S                   0
-
-#define AR_GPIO_INPUT_EN_VAL                     0x4054
-#define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_DEF     0x00000004
-#define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_S       2
-#define AR_GPIO_INPUT_EN_VAL_BT_FREQUENCY_DEF    0x00000008
-#define AR_GPIO_INPUT_EN_VAL_BT_FREQUENCY_S      3
-#define AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_DEF       0x00000010
-#define AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_S         4
-#define AR_GPIO_INPUT_EN_VAL_RFSILENT_DEF        0x00000080
-#define AR_GPIO_INPUT_EN_VAL_RFSILENT_DEF_S      7
-#define AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_BB        0x00001000
-#define AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_BB_S      12
-#define AR_GPIO_INPUT_EN_VAL_RFSILENT_BB         0x00008000
-#define AR_GPIO_INPUT_EN_VAL_RFSILENT_BB_S       15
-#define AR_GPIO_RTC_RESET_OVERRIDE_ENABLE        0x00010000
-#define AR_GPIO_JTAG_DISABLE                     0x00020000
-
-#define AR_GPIO_INPUT_MUX1                       0x4058
-#define AR_GPIO_INPUT_MUX1_BT_ACTIVE             0x000f0000
-#define AR_GPIO_INPUT_MUX1_BT_ACTIVE_S           16
-
-#define AR_GPIO_INPUT_MUX2                       0x405c
-#define AR_GPIO_INPUT_MUX2_CLK25                 0x0000000f
-#define AR_GPIO_INPUT_MUX2_CLK25_S               0
-#define AR_GPIO_INPUT_MUX2_RFSILENT              0x000000f0
-#define AR_GPIO_INPUT_MUX2_RFSILENT_S            4
-#define AR_GPIO_INPUT_MUX2_RTC_RESET             0x00000f00
-#define AR_GPIO_INPUT_MUX2_RTC_RESET_S           8
-
-#define AR_GPIO_OUTPUT_MUX1                      0x4060
-#define AR_GPIO_OUTPUT_MUX2                      0x4064
-#define AR_GPIO_OUTPUT_MUX3                      0x4068
-
-#define AR_INPUT_STATE                           0x406c
-
-#define AR_EEPROM_STATUS_DATA                    0x407c
-#define AR_EEPROM_STATUS_DATA_VAL                0x0000ffff
-#define AR_EEPROM_STATUS_DATA_VAL_S              0
-#define AR_EEPROM_STATUS_DATA_BUSY               0x00010000
-#define AR_EEPROM_STATUS_DATA_BUSY_ACCESS        0x00020000
-#define AR_EEPROM_STATUS_DATA_PROT_ACCESS        0x00040000
-#define AR_EEPROM_STATUS_DATA_ABSENT_ACCESS      0x00080000
-
-#define AR_OBS                  0x4080
-
-#define AR_PCIE_MSI                              0x4094
-#define AR_PCIE_MSI_ENABLE                       0x00000001
-
-
-#define AR_RTC_9160_PLL_DIV    0x000003ff
-#define AR_RTC_9160_PLL_DIV_S   0
-#define AR_RTC_9160_PLL_REFDIV  0x00003C00
-#define AR_RTC_9160_PLL_REFDIV_S 10
-#define AR_RTC_9160_PLL_CLKSEL 0x0000C000
-#define AR_RTC_9160_PLL_CLKSEL_S 14
-
-#define AR_RTC_BASE             0x00020000
-#define AR_RTC_RC \
-       ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0000) : 0x7000)
-#define AR_RTC_RC_M            0x00000003
-#define AR_RTC_RC_MAC_WARM      0x00000001
-#define AR_RTC_RC_MAC_COLD      0x00000002
-#define AR_RTC_RC_COLD_RESET    0x00000004
-#define AR_RTC_RC_WARM_RESET    0x00000008
-
-#define AR_RTC_PLL_CONTROL \
-       ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0014) : 0x7014)
-
-#define AR_RTC_PLL_DIV          0x0000001f
-#define AR_RTC_PLL_DIV_S        0
-#define AR_RTC_PLL_DIV2         0x00000020
-#define AR_RTC_PLL_REFDIV_5     0x000000c0
-#define AR_RTC_PLL_CLKSEL       0x00000300
-#define AR_RTC_PLL_CLKSEL_S     8
-
-#define AR_RTC_RESET \
-       ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0040) : 0x7040)
-#define AR_RTC_RESET_EN                (0x00000001)
-
-#define AR_RTC_STATUS \
-       ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0044) : 0x7044)
-
-#define AR_RTC_STATUS_M \
-       ((AR_SREV_9100(ah)) ? 0x0000003f : 0x0000000f)
-
-#define AR_RTC_PM_STATUS_M      0x0000000f
-
-#define AR_RTC_STATUS_SHUTDOWN  0x00000001
-#define AR_RTC_STATUS_ON        0x00000002
-#define AR_RTC_STATUS_SLEEP     0x00000004
-#define AR_RTC_STATUS_WAKEUP    0x00000008
-
-#define AR_RTC_SLEEP_CLK \
-       ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0048) : 0x7048)
-#define AR_RTC_FORCE_DERIVED_CLK    0x2
-
-#define AR_RTC_FORCE_WAKE \
-       ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x004c) : 0x704c)
-#define AR_RTC_FORCE_WAKE_EN        0x00000001
-#define AR_RTC_FORCE_WAKE_ON_INT    0x00000002
-
-
-#define AR_RTC_INTR_CAUSE \
-       ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0050) : 0x7050)
-
-#define AR_RTC_INTR_ENABLE \
-       ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0054) : 0x7054)
-
-#define AR_RTC_INTR_MASK \
-       ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0058) : 0x7058)
-
-/* RTC_DERIVED_* - only for AR9100 */
-
-#define AR_RTC_DERIVED_CLK           (AR_RTC_BASE + 0x0038)
-#define AR_RTC_DERIVED_CLK_PERIOD    0x0000fffe
-#define AR_RTC_DERIVED_CLK_PERIOD_S  1
-
-#define        AR_SEQ_MASK     0x8060
-
-#define AR_AN_RF2G1_CH0         0x7810
-#define AR_AN_RF2G1_CH0_OB      0x03800000
-#define AR_AN_RF2G1_CH0_OB_S    23
-#define AR_AN_RF2G1_CH0_DB      0x1C000000
-#define AR_AN_RF2G1_CH0_DB_S    26
-
-#define AR_AN_RF5G1_CH0         0x7818
-#define AR_AN_RF5G1_CH0_OB5     0x00070000
-#define AR_AN_RF5G1_CH0_OB5_S   16
-#define AR_AN_RF5G1_CH0_DB5     0x00380000
-#define AR_AN_RF5G1_CH0_DB5_S   19
-
-#define AR_AN_RF2G1_CH1         0x7834
-#define AR_AN_RF2G1_CH1_OB      0x03800000
-#define AR_AN_RF2G1_CH1_OB_S    23
-#define AR_AN_RF2G1_CH1_DB      0x1C000000
-#define AR_AN_RF2G1_CH1_DB_S    26
-
-#define AR_AN_RF5G1_CH1         0x783C
-#define AR_AN_RF5G1_CH1_OB5     0x00070000
-#define AR_AN_RF5G1_CH1_OB5_S   16
-#define AR_AN_RF5G1_CH1_DB5     0x00380000
-#define AR_AN_RF5G1_CH1_DB5_S   19
-
-#define AR_AN_TOP1                  0x7890
-#define AR_AN_TOP1_DACIPMODE       0x00040000
-#define AR_AN_TOP1_DACIPMODE_S     18
-
-#define AR_AN_TOP2                  0x7894
-#define AR_AN_TOP2_XPABIAS_LVL      0xC0000000
-#define AR_AN_TOP2_XPABIAS_LVL_S    30
-#define AR_AN_TOP2_LOCALBIAS        0x00200000
-#define AR_AN_TOP2_LOCALBIAS_S      21
-#define AR_AN_TOP2_PWDCLKIND        0x00400000
-#define AR_AN_TOP2_PWDCLKIND_S      22
-
-#define AR_AN_SYNTH9            0x7868
-#define AR_AN_SYNTH9_REFDIVA    0xf8000000
-#define AR_AN_SYNTH9_REFDIVA_S  27
-
-#define AR9285_AN_RF2G1              0x7820
-#define AR9285_AN_RF2G1_ENPACAL      0x00000800
-#define AR9285_AN_RF2G1_ENPACAL_S    11
-#define AR9285_AN_RF2G1_PDPADRV1     0x02000000
-#define AR9285_AN_RF2G1_PDPADRV1_S   25
-#define AR9285_AN_RF2G1_PDPADRV2     0x01000000
-#define AR9285_AN_RF2G1_PDPADRV2_S   24
-#define AR9285_AN_RF2G1_PDPAOUT      0x00800000
-#define AR9285_AN_RF2G1_PDPAOUT_S    23
-
-
-#define AR9285_AN_RF2G2              0x7824
-#define AR9285_AN_RF2G2_OFFCAL       0x00001000
-#define AR9285_AN_RF2G2_OFFCAL_S     12
-
-#define AR9285_AN_RF2G3             0x7828
-#define AR9285_AN_RF2G3_PDVCCOMP    0x02000000
-#define AR9285_AN_RF2G3_PDVCCOMP_S  25
-#define AR9285_AN_RF2G3_OB_0    0x00E00000
-#define AR9285_AN_RF2G3_OB_0_S    21
-#define AR9285_AN_RF2G3_OB_1    0x001C0000
-#define AR9285_AN_RF2G3_OB_1_S    18
-#define AR9285_AN_RF2G3_OB_2    0x00038000
-#define AR9285_AN_RF2G3_OB_2_S    15
-#define AR9285_AN_RF2G3_OB_3    0x00007000
-#define AR9285_AN_RF2G3_OB_3_S    12
-#define AR9285_AN_RF2G3_OB_4    0x00000E00
-#define AR9285_AN_RF2G3_OB_4_S    9
-
-#define AR9285_AN_RF2G3_DB1_0    0x000001C0
-#define AR9285_AN_RF2G3_DB1_0_S    6
-#define AR9285_AN_RF2G3_DB1_1    0x00000038
-#define AR9285_AN_RF2G3_DB1_1_S    3
-#define AR9285_AN_RF2G3_DB1_2    0x00000007
-#define AR9285_AN_RF2G3_DB1_2_S    0
-#define AR9285_AN_RF2G4         0x782C
-#define AR9285_AN_RF2G4_DB1_3    0xE0000000
-#define AR9285_AN_RF2G4_DB1_3_S    29
-#define AR9285_AN_RF2G4_DB1_4    0x1C000000
-#define AR9285_AN_RF2G4_DB1_4_S    26
-
-#define AR9285_AN_RF2G4_DB2_0    0x03800000
-#define AR9285_AN_RF2G4_DB2_0_S    23
-#define AR9285_AN_RF2G4_DB2_1    0x00700000
-#define AR9285_AN_RF2G4_DB2_1_S    20
-#define AR9285_AN_RF2G4_DB2_2    0x000E0000
-#define AR9285_AN_RF2G4_DB2_2_S    17
-#define AR9285_AN_RF2G4_DB2_3    0x0001C000
-#define AR9285_AN_RF2G4_DB2_3_S    14
-#define AR9285_AN_RF2G4_DB2_4    0x00003800
-#define AR9285_AN_RF2G4_DB2_4_S    11
-
-#define AR9285_AN_RF2G6                 0x7834
-#define AR9285_AN_RF2G6_CCOMP           0x00007800
-#define AR9285_AN_RF2G6_CCOMP_S         11
-#define AR9285_AN_RF2G6_OFFS            0x03f00000
-#define AR9285_AN_RF2G6_OFFS_S          20
-
-#define AR9285_AN_RF2G7                 0x7838
-#define AR9285_AN_RF2G7_PWDDB           0x00000002
-#define AR9285_AN_RF2G7_PWDDB_S         1
-#define AR9285_AN_RF2G7_PADRVGN2TAB0    0xE0000000
-#define AR9285_AN_RF2G7_PADRVGN2TAB0_S  29
-
-#define AR9285_AN_RF2G8                  0x783C
-#define AR9285_AN_RF2G8_PADRVGN2TAB0     0x0001C000
-#define AR9285_AN_RF2G8_PADRVGN2TAB0_S   14
-
-
-#define AR9285_AN_RF2G9          0x7840
-#define AR9285_AN_RXTXBB1              0x7854
-#define AR9285_AN_RXTXBB1_PDRXTXBB1    0x00000020
-#define AR9285_AN_RXTXBB1_PDRXTXBB1_S  5
-#define AR9285_AN_RXTXBB1_PDV2I        0x00000080
-#define AR9285_AN_RXTXBB1_PDV2I_S      7
-#define AR9285_AN_RXTXBB1_PDDACIF      0x00000100
-#define AR9285_AN_RXTXBB1_PDDACIF_S    8
-#define AR9285_AN_RXTXBB1_SPARE9       0x00000001
-#define AR9285_AN_RXTXBB1_SPARE9_S     0
-
-#define AR9285_AN_TOP2           0x7868
-
-#define AR9285_AN_TOP3                  0x786c
-#define AR9285_AN_TOP3_XPABIAS_LVL      0x0000000C
-#define AR9285_AN_TOP3_XPABIAS_LVL_S    2
-#define AR9285_AN_TOP3_PWDDAC           0x00800000
-#define AR9285_AN_TOP3_PWDDAC_S    23
-
-#define AR9285_AN_TOP4           0x7870
-#define AR9285_AN_TOP4_DEFAULT   0x10142c00
-
-#define AR_STA_ID0                 0x8000
-#define AR_STA_ID1                 0x8004
-#define AR_STA_ID1_SADH_MASK       0x0000FFFF
-#define AR_STA_ID1_STA_AP          0x00010000
-#define AR_STA_ID1_ADHOC           0x00020000
-#define AR_STA_ID1_PWR_SAV         0x00040000
-#define AR_STA_ID1_KSRCHDIS        0x00080000
-#define AR_STA_ID1_PCF             0x00100000
-#define AR_STA_ID1_USE_DEFANT      0x00200000
-#define AR_STA_ID1_DEFANT_UPDATE   0x00400000
-#define AR_STA_ID1_RTS_USE_DEF     0x00800000
-#define AR_STA_ID1_ACKCTS_6MB      0x01000000
-#define AR_STA_ID1_BASE_RATE_11B   0x02000000
-#define AR_STA_ID1_SECTOR_SELF_GEN 0x04000000
-#define AR_STA_ID1_CRPT_MIC_ENABLE 0x08000000
-#define AR_STA_ID1_KSRCH_MODE      0x10000000
-#define AR_STA_ID1_PRESERVE_SEQNUM 0x20000000
-#define AR_STA_ID1_CBCIV_ENDIAN    0x40000000
-#define AR_STA_ID1_MCAST_KSRCH     0x80000000
-
-#define AR_BSS_ID0          0x8008
-#define AR_BSS_ID1          0x800C
-#define AR_BSS_ID1_U16       0x0000FFFF
-#define AR_BSS_ID1_AID       0x07FF0000
-#define AR_BSS_ID1_AID_S     16
-
-#define AR_BCN_RSSI_AVE      0x8010
-#define AR_BCN_RSSI_AVE_MASK 0x00000FFF
-
-#define AR_TIME_OUT         0x8014
-#define AR_TIME_OUT_ACK      0x00003FFF
-#define AR_TIME_OUT_ACK_S    0
-#define AR_TIME_OUT_CTS      0x3FFF0000
-#define AR_TIME_OUT_CTS_S    16
-
-#define AR_RSSI_THR          0x8018
-#define AR_RSSI_THR_MASK     0x000000FF
-#define AR_RSSI_THR_BM_THR   0x0000FF00
-#define AR_RSSI_THR_BM_THR_S 8
-#define AR_RSSI_BCN_WEIGHT   0x1F000000
-#define AR_RSSI_BCN_WEIGHT_S 24
-#define AR_RSSI_BCN_RSSI_RST 0x20000000
-
-#define AR_USEC              0x801c
-#define AR_USEC_USEC         0x0000007F
-#define AR_USEC_TX_LAT       0x007FC000
-#define AR_USEC_TX_LAT_S     14
-#define AR_USEC_RX_LAT       0x1F800000
-#define AR_USEC_RX_LAT_S     23
-
-#define AR_RESET_TSF        0x8020
-#define AR_RESET_TSF_ONCE   0x01000000
-
-#define AR_MAX_CFP_DUR      0x8038
-#define AR_CFP_VAL          0x0000FFFF
-
-#define AR_RX_FILTER        0x803C
-#define AR_RX_COMPR_BAR     0x00000400
-
-#define AR_MCAST_FIL0       0x8040
-#define AR_MCAST_FIL1       0x8044
-
-#define AR_DIAG_SW                  0x8048
-#define AR_DIAG_CACHE_ACK           0x00000001
-#define AR_DIAG_ACK_DIS             0x00000002
-#define AR_DIAG_CTS_DIS             0x00000004
-#define AR_DIAG_ENCRYPT_DIS         0x00000008
-#define AR_DIAG_DECRYPT_DIS         0x00000010
-#define AR_DIAG_RX_DIS              0x00000020
-#define AR_DIAG_LOOP_BACK           0x00000040
-#define AR_DIAG_CORR_FCS            0x00000080
-#define AR_DIAG_CHAN_INFO           0x00000100
-#define AR_DIAG_SCRAM_SEED          0x0001FE00
-#define AR_DIAG_SCRAM_SEED_S        8
-#define AR_DIAG_FRAME_NV0           0x00020000
-#define AR_DIAG_OBS_PT_SEL1         0x000C0000
-#define AR_DIAG_OBS_PT_SEL1_S       18
-#define AR_DIAG_FORCE_RX_CLEAR      0x00100000
-#define AR_DIAG_IGNORE_VIRT_CS      0x00200000
-#define AR_DIAG_FORCE_CH_IDLE_HIGH  0x00400000
-#define AR_DIAG_EIFS_CTRL_ENA       0x00800000
-#define AR_DIAG_DUAL_CHAIN_INFO     0x01000000
-#define AR_DIAG_RX_ABORT            0x02000000
-#define AR_DIAG_SATURATE_CYCLE_CNT  0x04000000
-#define AR_DIAG_OBS_PT_SEL2         0x08000000
-#define AR_DIAG_RX_CLEAR_CTL_LOW    0x10000000
-#define AR_DIAG_RX_CLEAR_EXT_LOW    0x20000000
-
-#define AR_TSF_L32          0x804c
-#define AR_TSF_U32          0x8050
-
-#define AR_TST_ADDAC        0x8054
-#define AR_DEF_ANTENNA      0x8058
-
-#define AR_AES_MUTE_MASK0       0x805c
-#define AR_AES_MUTE_MASK0_FC    0x0000FFFF
-#define AR_AES_MUTE_MASK0_QOS   0xFFFF0000
-#define AR_AES_MUTE_MASK0_QOS_S 16
-
-#define AR_AES_MUTE_MASK1       0x8060
-#define AR_AES_MUTE_MASK1_SEQ   0x0000FFFF
-#define AR_AES_MUTE_MASK1_FC_MGMT 0xFFFF0000
-#define AR_AES_MUTE_MASK1_FC_MGMT_S 16
-
-#define AR_GATED_CLKS       0x8064
-#define AR_GATED_CLKS_TX    0x00000002
-#define AR_GATED_CLKS_RX    0x00000004
-#define AR_GATED_CLKS_REG   0x00000008
-
-#define AR_OBS_BUS_CTRL     0x8068
-#define AR_OBS_BUS_SEL_1    0x00040000
-#define AR_OBS_BUS_SEL_2    0x00080000
-#define AR_OBS_BUS_SEL_3    0x000C0000
-#define AR_OBS_BUS_SEL_4    0x08040000
-#define AR_OBS_BUS_SEL_5    0x08080000
-
-#define AR_OBS_BUS_1               0x806c
-#define AR_OBS_BUS_1_PCU           0x00000001
-#define AR_OBS_BUS_1_RX_END        0x00000002
-#define AR_OBS_BUS_1_RX_WEP        0x00000004
-#define AR_OBS_BUS_1_RX_BEACON     0x00000008
-#define AR_OBS_BUS_1_RX_FILTER     0x00000010
-#define AR_OBS_BUS_1_TX_HCF        0x00000020
-#define AR_OBS_BUS_1_QUIET_TIME    0x00000040
-#define AR_OBS_BUS_1_CHAN_IDLE     0x00000080
-#define AR_OBS_BUS_1_TX_HOLD       0x00000100
-#define AR_OBS_BUS_1_TX_FRAME      0x00000200
-#define AR_OBS_BUS_1_RX_FRAME      0x00000400
-#define AR_OBS_BUS_1_RX_CLEAR      0x00000800
-#define AR_OBS_BUS_1_WEP_STATE     0x0003F000
-#define AR_OBS_BUS_1_WEP_STATE_S   12
-#define AR_OBS_BUS_1_RX_STATE      0x01F00000
-#define AR_OBS_BUS_1_RX_STATE_S    20
-#define AR_OBS_BUS_1_TX_STATE      0x7E000000
-#define AR_OBS_BUS_1_TX_STATE_S    25
-
-#define AR_LAST_TSTP        0x8080
-#define AR_NAV              0x8084
-#define AR_RTS_OK           0x8088
-#define AR_RTS_FAIL         0x808c
-#define AR_ACK_FAIL         0x8090
-#define AR_FCS_FAIL         0x8094
-#define AR_BEACON_CNT       0x8098
-
-#define AR_SLEEP1               0x80d4
-#define AR_SLEEP1_ASSUME_DTIM   0x00080000
-#define AR_SLEEP1_CAB_TIMEOUT   0xFFE00000
-#define AR_SLEEP1_CAB_TIMEOUT_S 21
-
-#define AR_SLEEP2                   0x80d8
-#define AR_SLEEP2_BEACON_TIMEOUT    0xFFE00000
-#define AR_SLEEP2_BEACON_TIMEOUT_S  21
-
-#define AR_BSSMSKL            0x80e0
-#define AR_BSSMSKU            0x80e4
-
-#define AR_TPC                 0x80e8
-#define AR_TPC_ACK             0x0000003f
-#define AR_TPC_ACK_S           0x00
-#define AR_TPC_CTS             0x00003f00
-#define AR_TPC_CTS_S           0x08
-#define AR_TPC_CHIRP           0x003f0000
-#define AR_TPC_CHIRP_S         0x16
-
-#define AR_TFCNT           0x80ec
-#define AR_RFCNT           0x80f0
-#define AR_RCCNT           0x80f4
-#define AR_CCCNT           0x80f8
-
-#define AR_QUIET1          0x80fc
-#define AR_QUIET1_NEXT_QUIET_S         0
-#define AR_QUIET1_NEXT_QUIET_M         0x0000ffff
-#define AR_QUIET1_QUIET_ENABLE         0x00010000
-#define AR_QUIET1_QUIET_ACK_CTS_ENABLE 0x00020000
-#define AR_QUIET2          0x8100
-#define AR_QUIET2_QUIET_PERIOD_S       0
-#define AR_QUIET2_QUIET_PERIOD_M       0x0000ffff
-#define AR_QUIET2_QUIET_DUR_S     16
-#define AR_QUIET2_QUIET_DUR       0xffff0000
-
-#define AR_TSF_PARM        0x8104
-#define AR_TSF_INCREMENT_M     0x000000ff
-#define AR_TSF_INCREMENT_S     0x00
-
-#define AR_QOS_NO_ACK              0x8108
-#define AR_QOS_NO_ACK_TWO_BIT      0x0000000f
-#define AR_QOS_NO_ACK_TWO_BIT_S    0
-#define AR_QOS_NO_ACK_BIT_OFF      0x00000070
-#define AR_QOS_NO_ACK_BIT_OFF_S    4
-#define AR_QOS_NO_ACK_BYTE_OFF     0x00000180
-#define AR_QOS_NO_ACK_BYTE_OFF_S   7
-
-#define AR_PHY_ERR         0x810c
-
-#define AR_PHY_ERR_DCHIRP      0x00000008
-#define AR_PHY_ERR_RADAR       0x00000020
-#define AR_PHY_ERR_OFDM_TIMING 0x00020000
-#define AR_PHY_ERR_CCK_TIMING  0x02000000
-
-#define AR_RXFIFO_CFG          0x8114
-
-
-#define AR_MIC_QOS_CONTROL 0x8118
-#define AR_MIC_QOS_SELECT  0x811c
-
-#define AR_PCU_MISC                0x8120
-#define AR_PCU_FORCE_BSSID_MATCH   0x00000001
-#define AR_PCU_MIC_NEW_LOC_ENA     0x00000004
-#define AR_PCU_TX_ADD_TSF          0x00000008
-#define AR_PCU_CCK_SIFS_MODE       0x00000010
-#define AR_PCU_RX_ANT_UPDT         0x00000800
-#define AR_PCU_TXOP_TBTT_LIMIT_ENA 0x00001000
-#define AR_PCU_MISS_BCN_IN_SLEEP   0x00004000
-#define AR_PCU_BUG_12306_FIX_ENA   0x00020000
-#define AR_PCU_FORCE_QUIET_COLL    0x00040000
-#define AR_PCU_TBTT_PROTECT        0x00200000
-#define AR_PCU_CLEAR_VMF           0x01000000
-#define AR_PCU_CLEAR_BA_VALID      0x04000000
-
-
-#define AR_FILT_OFDM           0x8124
-#define AR_FILT_OFDM_COUNT     0x00FFFFFF
-
-#define AR_FILT_CCK            0x8128
-#define AR_FILT_CCK_COUNT      0x00FFFFFF
-
-#define AR_PHY_ERR_1           0x812c
-#define AR_PHY_ERR_1_COUNT     0x00FFFFFF
-#define AR_PHY_ERR_MASK_1      0x8130
-
-#define AR_PHY_ERR_2           0x8134
-#define AR_PHY_ERR_2_COUNT     0x00FFFFFF
-#define AR_PHY_ERR_MASK_2      0x8138
-
-#define AR_PHY_COUNTMAX        (3 << 22)
-#define AR_MIBCNT_INTRMASK     (3 << 22)
-
-#define AR_TSFOOR_THRESHOLD       0x813c
-#define AR_TSFOOR_THRESHOLD_VAL   0x0000FFFF
-
-#define AR_PHY_ERR_EIFS_MASK   8144
-
-#define AR_PHY_ERR_3           0x8168
-#define AR_PHY_ERR_3_COUNT     0x00FFFFFF
-#define AR_PHY_ERR_MASK_3      0x816c
-
-#define AR_TXSIFS              0x81d0
-#define AR_TXSIFS_TIME         0x000000FF
-#define AR_TXSIFS_TX_LATENCY   0x00000F00
-#define AR_TXSIFS_TX_LATENCY_S 8
-#define AR_TXSIFS_ACK_SHIFT    0x00007000
-#define AR_TXSIFS_ACK_SHIFT_S  12
-
-#define AR_TXOP_X          0x81ec
-#define AR_TXOP_X_VAL      0x000000FF
-
-
-#define AR_TXOP_0_3    0x81f0
-#define AR_TXOP_4_7    0x81f4
-#define AR_TXOP_8_11   0x81f8
-#define AR_TXOP_12_15  0x81fc
-
-
-#define AR_NEXT_TBTT_TIMER                  0x8200
-#define AR_NEXT_DMA_BEACON_ALERT            0x8204
-#define AR_NEXT_SWBA                        0x8208
-#define AR_NEXT_CFP                         0x8208
-#define AR_NEXT_HCF                         0x820C
-#define AR_NEXT_TIM                         0x8210
-#define AR_NEXT_DTIM                        0x8214
-#define AR_NEXT_QUIET_TIMER                 0x8218
-#define AR_NEXT_NDP_TIMER                   0x821C
-
-#define AR_BEACON_PERIOD                    0x8220
-#define AR_DMA_BEACON_PERIOD                0x8224
-#define AR_SWBA_PERIOD                      0x8228
-#define AR_HCF_PERIOD                       0x822C
-#define AR_TIM_PERIOD                       0x8230
-#define AR_DTIM_PERIOD                      0x8234
-#define AR_QUIET_PERIOD                     0x8238
-#define AR_NDP_PERIOD                       0x823C
-
-#define AR_TIMER_MODE                       0x8240
-#define AR_TBTT_TIMER_EN                    0x00000001
-#define AR_DBA_TIMER_EN                     0x00000002
-#define AR_SWBA_TIMER_EN                    0x00000004
-#define AR_HCF_TIMER_EN                     0x00000008
-#define AR_TIM_TIMER_EN                     0x00000010
-#define AR_DTIM_TIMER_EN                    0x00000020
-#define AR_QUIET_TIMER_EN                   0x00000040
-#define AR_NDP_TIMER_EN                     0x00000080
-#define AR_TIMER_OVERFLOW_INDEX             0x00000700
-#define AR_TIMER_OVERFLOW_INDEX_S           8
-#define AR_TIMER_THRESH                     0xFFFFF000
-#define AR_TIMER_THRESH_S                   12
-
-#define AR_SLP32_MODE                  0x8244
-#define AR_SLP32_HALF_CLK_LATENCY      0x000FFFFF
-#define AR_SLP32_ENA                   0x00100000
-#define AR_SLP32_TSF_WRITE_STATUS      0x00200000
-
-#define AR_SLP32_WAKE              0x8248
-#define AR_SLP32_WAKE_XTL_TIME     0x0000FFFF
-
-#define AR_SLP32_INC               0x824c
-#define AR_SLP32_TST_INC           0x000FFFFF
-
-#define AR_SLP_CNT         0x8250
-#define AR_SLP_CYCLE_CNT   0x8254
-
-#define AR_SLP_MIB_CTRL    0x8258
-#define AR_SLP_MIB_CLEAR   0x00000001
-#define AR_SLP_MIB_PENDING 0x00000002
-
-#define AR_2040_MODE                0x8318
-#define AR_2040_JOINED_RX_CLEAR 0x00000001
-
-
-#define AR_EXTRCCNT         0x8328
-
-#define AR_SELFGEN_MASK         0x832c
-
-#define AR_PCU_TXBUF_CTRL               0x8340
-#define AR_PCU_TXBUF_CTRL_SIZE_MASK     0x7FF
-#define AR_PCU_TXBUF_CTRL_USABLE_SIZE   0x700
-#define AR_9285_PCU_TXBUF_CTRL_USABLE_SIZE   0x380
-
-#define AR_PCU_MISC_MODE2               0x8344
-#define AR_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE           0x00000002
-#define AR_PCU_MISC_MODE2_NO_CRYPTO_FOR_NON_DATA_PKT   0x00000004
-
-#define AR_KEYTABLE_0           0x8800
-#define AR_KEYTABLE(_n)         (AR_KEYTABLE_0 + ((_n)*32))
-#define AR_KEY_CACHE_SIZE       128
-#define AR_RSVD_KEYTABLE_ENTRIES 4
-#define AR_KEY_TYPE             0x00000007
-#define AR_KEYTABLE_TYPE_40     0x00000000
-#define AR_KEYTABLE_TYPE_104    0x00000001
-#define AR_KEYTABLE_TYPE_128    0x00000003
-#define AR_KEYTABLE_TYPE_TKIP   0x00000004
-#define AR_KEYTABLE_TYPE_AES    0x00000005
-#define AR_KEYTABLE_TYPE_CCM    0x00000006
-#define AR_KEYTABLE_TYPE_CLR    0x00000007
-#define AR_KEYTABLE_ANT         0x00000008
-#define AR_KEYTABLE_VALID       0x00008000
-#define AR_KEYTABLE_KEY0(_n)    (AR_KEYTABLE(_n) + 0)
-#define AR_KEYTABLE_KEY1(_n)    (AR_KEYTABLE(_n) + 4)
-#define AR_KEYTABLE_KEY2(_n)    (AR_KEYTABLE(_n) + 8)
-#define AR_KEYTABLE_KEY3(_n)    (AR_KEYTABLE(_n) + 12)
-#define AR_KEYTABLE_KEY4(_n)    (AR_KEYTABLE(_n) + 16)
-#define AR_KEYTABLE_TYPE(_n)    (AR_KEYTABLE(_n) + 20)
-#define AR_KEYTABLE_MAC0(_n)    (AR_KEYTABLE(_n) + 24)
-#define AR_KEYTABLE_MAC1(_n)    (AR_KEYTABLE(_n) + 28)
-
-#endif
diff --git a/drivers/net/wireless/ath9k/regd.c b/drivers/net/wireless/ath9k/regd.c
deleted file mode 100644 (file)
index 4ca6251..0000000
+++ /dev/null
@@ -1,519 +0,0 @@
-/*
- * Copyright (c) 2008-2009 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/kernel.h>
-#include <linux/slab.h>
-#include "ath9k.h"
-#include "regd_common.h"
-
-/*
- * This is a set of common rules used by our world regulatory domains.
- * We have 12 world regulatory domains. To save space we consolidate
- * the regulatory domains in 5 structures by frequency and change
- * the flags on our reg_notifier() on a case by case basis.
- */
-
-/* Only these channels all allow active scan on all world regulatory domains */
-#define ATH9K_2GHZ_CH01_11     REG_RULE(2412-10, 2462+10, 40, 0, 20, 0)
-
-/* We enable active scan on these a case by case basis by regulatory domain */
-#define ATH9K_2GHZ_CH12_13     REG_RULE(2467-10, 2472+10, 40, 0, 20,\
-                                       NL80211_RRF_PASSIVE_SCAN)
-#define ATH9K_2GHZ_CH14                REG_RULE(2484-10, 2484+10, 40, 0, 20,\
-                               NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_OFDM)
-
-/* We allow IBSS on these on a case by case basis by regulatory domain */
-#define ATH9K_5GHZ_5150_5350   REG_RULE(5150-10, 5350+10, 40, 0, 30,\
-                               NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS)
-#define ATH9K_5GHZ_5470_5850   REG_RULE(5470-10, 5850+10, 40, 0, 30,\
-                               NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS)
-#define ATH9K_5GHZ_5725_5850   REG_RULE(5725-10, 5850+10, 40, 0, 30,\
-                               NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS)
-
-#define ATH9K_2GHZ_ALL         ATH9K_2GHZ_CH01_11, \
-                               ATH9K_2GHZ_CH12_13, \
-                               ATH9K_2GHZ_CH14
-
-#define ATH9K_5GHZ_ALL         ATH9K_5GHZ_5150_5350, \
-                               ATH9K_5GHZ_5470_5850
-/* This one skips what we call "mid band" */
-#define ATH9K_5GHZ_NO_MIDBAND  ATH9K_5GHZ_5150_5350, \
-                               ATH9K_5GHZ_5725_5850
-
-/* Can be used for:
- * 0x60, 0x61, 0x62 */
-static const struct ieee80211_regdomain ath9k_world_regdom_60_61_62 = {
-       .n_reg_rules = 5,
-       .alpha2 =  "99",
-       .reg_rules = {
-               ATH9K_2GHZ_ALL,
-               ATH9K_5GHZ_ALL,
-       }
-};
-
-/* Can be used by 0x63 and 0x65 */
-static const struct ieee80211_regdomain ath9k_world_regdom_63_65 = {
-       .n_reg_rules = 4,
-       .alpha2 =  "99",
-       .reg_rules = {
-               ATH9K_2GHZ_CH01_11,
-               ATH9K_2GHZ_CH12_13,
-               ATH9K_5GHZ_NO_MIDBAND,
-       }
-};
-
-/* Can be used by 0x64 only */
-static const struct ieee80211_regdomain ath9k_world_regdom_64 = {
-       .n_reg_rules = 3,
-       .alpha2 =  "99",
-       .reg_rules = {
-               ATH9K_2GHZ_CH01_11,
-               ATH9K_5GHZ_NO_MIDBAND,
-       }
-};
-
-/* Can be used by 0x66 and 0x69 */
-static const struct ieee80211_regdomain ath9k_world_regdom_66_69 = {
-       .n_reg_rules = 3,
-       .alpha2 =  "99",
-       .reg_rules = {
-               ATH9K_2GHZ_CH01_11,
-               ATH9K_5GHZ_ALL,
-       }
-};
-
-/* Can be used by 0x67, 0x6A and 0x68 */
-static const struct ieee80211_regdomain ath9k_world_regdom_67_68_6A = {
-       .n_reg_rules = 4,
-       .alpha2 =  "99",
-       .reg_rules = {
-               ATH9K_2GHZ_CH01_11,
-               ATH9K_2GHZ_CH12_13,
-               ATH9K_5GHZ_ALL,
-       }
-};
-
-static inline bool is_wwr_sku(u16 regd)
-{
-       return ((regd & WORLD_SKU_MASK) == WORLD_SKU_PREFIX) ||
-               (regd == WORLD);
-}
-
-static u16 ath9k_regd_get_eepromRD(struct ath_hw *ah)
-{
-       return ah->regulatory.current_rd & ~WORLDWIDE_ROAMING_FLAG;
-}
-
-bool ath9k_is_world_regd(struct ath_hw *ah)
-{
-       return is_wwr_sku(ath9k_regd_get_eepromRD(ah));
-}
-
-const struct ieee80211_regdomain *ath9k_default_world_regdomain(void)
-{
-       /* this is the most restrictive */
-       return &ath9k_world_regdom_64;
-}
-
-const struct ieee80211_regdomain *ath9k_world_regdomain(struct ath_hw *ah)
-{
-       switch (ah->regulatory.regpair->regDmnEnum) {
-       case 0x60:
-       case 0x61:
-       case 0x62:
-               return &ath9k_world_regdom_60_61_62;
-       case 0x63:
-       case 0x65:
-               return &ath9k_world_regdom_63_65;
-       case 0x64:
-               return &ath9k_world_regdom_64;
-       case 0x66:
-       case 0x69:
-               return &ath9k_world_regdom_66_69;
-       case 0x67:
-       case 0x68:
-       case 0x6A:
-               return &ath9k_world_regdom_67_68_6A;
-       default:
-               WARN_ON(1);
-               return ath9k_default_world_regdomain();
-       }
-}
-
-/* Frequency is one where radar detection is required */
-static bool ath9k_is_radar_freq(u16 center_freq)
-{
-       return (center_freq >= 5260 && center_freq <= 5700);
-}
-
-/*
- * N.B: These exception rules do not apply radar freqs.
- *
- * - We enable adhoc (or beaconing) if allowed by 11d
- * - We enable active scan if the channel is allowed by 11d
- * - If no country IE has been processed and a we determine we have
- *   received a beacon on a channel we can enable active scan and
- *   adhoc (or beaconing).
- */
-static void ath9k_reg_apply_beaconing_flags(
-       struct wiphy *wiphy,
-       enum nl80211_reg_initiator initiator)
-{
-       enum ieee80211_band band;
-       struct ieee80211_supported_band *sband;
-       const struct ieee80211_reg_rule *reg_rule;
-       struct ieee80211_channel *ch;
-       unsigned int i;
-       u32 bandwidth = 0;
-       int r;
-
-       for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
-
-               if (!wiphy->bands[band])
-                       continue;
-
-               sband = wiphy->bands[band];
-
-               for (i = 0; i < sband->n_channels; i++) {
-
-                       ch = &sband->channels[i];
-
-                       if (ath9k_is_radar_freq(ch->center_freq) ||
-                           (ch->flags & IEEE80211_CHAN_RADAR))
-                               continue;
-
-                       if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) {
-                               r = freq_reg_info(wiphy, ch->center_freq,
-                                       &bandwidth, &reg_rule);
-                               if (r)
-                                       continue;
-                               /*
-                                * If 11d had a rule for this channel ensure
-                                * we enable adhoc/beaconing if it allows us to
-                                * use it. Note that we would have disabled it
-                                * by applying our static world regdomain by
-                                * default during init, prior to calling our
-                                * regulatory_hint().
-                                */
-                               if (!(reg_rule->flags &
-                                   NL80211_RRF_NO_IBSS))
-                                       ch->flags &=
-                                         ~IEEE80211_CHAN_NO_IBSS;
-                               if (!(reg_rule->flags &
-                                   NL80211_RRF_PASSIVE_SCAN))
-                                       ch->flags &=
-                                         ~IEEE80211_CHAN_PASSIVE_SCAN;
-                       } else {
-                               if (ch->beacon_found)
-                                       ch->flags &= ~(IEEE80211_CHAN_NO_IBSS |
-                                         IEEE80211_CHAN_PASSIVE_SCAN);
-                       }
-               }
-       }
-
-}
-
-/* Allows active scan scan on Ch 12 and 13 */
-static void ath9k_reg_apply_active_scan_flags(
-       struct wiphy *wiphy,
-       enum nl80211_reg_initiator initiator)
-{
-       struct ieee80211_supported_band *sband;
-       struct ieee80211_channel *ch;
-       const struct ieee80211_reg_rule *reg_rule;
-       u32 bandwidth = 0;
-       int r;
-
-       sband = wiphy->bands[IEEE80211_BAND_2GHZ];
-
-       /*
-        * If no country IE has been received always enable active scan
-        * on these channels. This is only done for specific regulatory SKUs
-        */
-       if (initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE) {
-               ch = &sband->channels[11]; /* CH 12 */
-               if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
-                       ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
-               ch = &sband->channels[12]; /* CH 13 */
-               if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
-                       ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
-               return;
-       }
-
-       /*
-        * If a country IE has been recieved check its rule for this
-        * channel first before enabling active scan. The passive scan
-        * would have been enforced by the initial processing of our
-        * custom regulatory domain.
-        */
-
-       ch = &sband->channels[11]; /* CH 12 */
-       r = freq_reg_info(wiphy, ch->center_freq, &bandwidth, &reg_rule);
-       if (!r) {
-               if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN))
-                       if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
-                               ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
-       }
-
-       ch = &sband->channels[12]; /* CH 13 */
-       r = freq_reg_info(wiphy, ch->center_freq, &bandwidth, &reg_rule);
-       if (!r) {
-               if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN))
-                       if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
-                               ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
-       }
-}
-
-/* Always apply Radar/DFS rules on freq range 5260 MHz - 5700 MHz */
-void ath9k_reg_apply_radar_flags(struct wiphy *wiphy)
-{
-       struct ieee80211_supported_band *sband;
-       struct ieee80211_channel *ch;
-       unsigned int i;
-
-       if (!wiphy->bands[IEEE80211_BAND_5GHZ])
-               return;
-
-       sband = wiphy->bands[IEEE80211_BAND_5GHZ];
-
-       for (i = 0; i < sband->n_channels; i++) {
-               ch = &sband->channels[i];
-               if (!ath9k_is_radar_freq(ch->center_freq))
-                       continue;
-               /* We always enable radar detection/DFS on this
-                * frequency range. Additionally we also apply on
-                * this frequency range:
-                * - If STA mode does not yet have DFS supports disable
-                *   active scanning
-                * - If adhoc mode does not support DFS yet then
-                *   disable adhoc in the frequency.
-                * - If AP mode does not yet support radar detection/DFS
-                *   do not allow AP mode
-                */
-               if (!(ch->flags & IEEE80211_CHAN_DISABLED))
-                       ch->flags |= IEEE80211_CHAN_RADAR |
-                                    IEEE80211_CHAN_NO_IBSS |
-                                    IEEE80211_CHAN_PASSIVE_SCAN;
-       }
-}
-
-void ath9k_reg_apply_world_flags(struct wiphy *wiphy,
-                                enum nl80211_reg_initiator initiator)
-{
-       struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
-       struct ath_wiphy *aphy = hw->priv;
-       struct ath_softc *sc = aphy->sc;
-       struct ath_hw *ah = sc->sc_ah;
-
-       switch (ah->regulatory.regpair->regDmnEnum) {
-       case 0x60:
-       case 0x63:
-       case 0x66:
-       case 0x67:
-               ath9k_reg_apply_beaconing_flags(wiphy, initiator);
-               break;
-       case 0x68:
-               ath9k_reg_apply_beaconing_flags(wiphy, initiator);
-               ath9k_reg_apply_active_scan_flags(wiphy, initiator);
-               break;
-       }
-       return;
-}
-
-int ath9k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request)
-{
-       struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
-       struct ath_wiphy *aphy = hw->priv;
-       struct ath_softc *sc = aphy->sc;
-
-       /* We always apply this */
-       ath9k_reg_apply_radar_flags(wiphy);
-
-       switch (request->initiator) {
-       case NL80211_REGDOM_SET_BY_DRIVER:
-       case NL80211_REGDOM_SET_BY_CORE:
-       case NL80211_REGDOM_SET_BY_USER:
-               break;
-       case NL80211_REGDOM_SET_BY_COUNTRY_IE:
-               if (ath9k_is_world_regd(sc->sc_ah))
-                       ath9k_reg_apply_world_flags(wiphy, request->initiator);
-               break;
-       }
-
-       return 0;
-}
-
-bool ath9k_regd_is_eeprom_valid(struct ath_hw *ah)
-{
-       u16 rd = ath9k_regd_get_eepromRD(ah);
-       int i;
-
-       if (rd & COUNTRY_ERD_FLAG) {
-               /* EEPROM value is a country code */
-               u16 cc = rd & ~COUNTRY_ERD_FLAG;
-               for (i = 0; i < ARRAY_SIZE(allCountries); i++)
-                       if (allCountries[i].countryCode == cc)
-                               return true;
-       } else {
-               /* EEPROM value is a regpair value */
-               for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++)
-                       if (regDomainPairs[i].regDmnEnum == rd)
-                               return true;
-       }
-       DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
-                "invalid regulatory domain/country code 0x%x\n", rd);
-       return false;
-}
-
-/* EEPROM country code to regpair mapping */
-static struct country_code_to_enum_rd*
-ath9k_regd_find_country(u16 countryCode)
-{
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(allCountries); i++) {
-               if (allCountries[i].countryCode == countryCode)
-                       return &allCountries[i];
-       }
-       return NULL;
-}
-
-/* EEPROM rd code to regpair mapping */
-static struct country_code_to_enum_rd*
-ath9k_regd_find_country_by_rd(int regdmn)
-{
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(allCountries); i++) {
-               if (allCountries[i].regDmnEnum == regdmn)
-                       return &allCountries[i];
-       }
-       return NULL;
-}
-
-/* Returns the map of the EEPROM set RD to a country code */
-static u16 ath9k_regd_get_default_country(u16 rd)
-{
-       if (rd & COUNTRY_ERD_FLAG) {
-               struct country_code_to_enum_rd *country = NULL;
-               u16 cc = rd & ~COUNTRY_ERD_FLAG;
-
-               country = ath9k_regd_find_country(cc);
-               if (country != NULL)
-                       return cc;
-       }
-
-       return CTRY_DEFAULT;
-}
-
-static struct reg_dmn_pair_mapping*
-ath9k_get_regpair(int regdmn)
-{
-       int i;
-
-       if (regdmn == NO_ENUMRD)
-               return NULL;
-       for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++) {
-               if (regDomainPairs[i].regDmnEnum == regdmn)
-                       return &regDomainPairs[i];
-       }
-       return NULL;
-}
-
-int ath9k_regd_init(struct ath_hw *ah)
-{
-       struct country_code_to_enum_rd *country = NULL;
-       u16 regdmn;
-
-       if (!ath9k_regd_is_eeprom_valid(ah)) {
-               DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
-                       "Invalid EEPROM contents\n");
-               return -EINVAL;
-       }
-
-       regdmn = ath9k_regd_get_eepromRD(ah);
-       ah->regulatory.country_code = ath9k_regd_get_default_country(regdmn);
-
-       if (ah->regulatory.country_code == CTRY_DEFAULT &&
-           regdmn == CTRY_DEFAULT)
-               ah->regulatory.country_code = CTRY_UNITED_STATES;
-
-       if (ah->regulatory.country_code == CTRY_DEFAULT) {
-               country = NULL;
-       } else {
-               country = ath9k_regd_find_country(ah->regulatory.country_code);
-               if (country == NULL) {
-                       DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
-                               "Country is NULL!!!!, cc= %d\n",
-                               ah->regulatory.country_code);
-                       return -EINVAL;
-               } else
-                       regdmn = country->regDmnEnum;
-       }
-
-       ah->regulatory.regpair = ath9k_get_regpair(regdmn);
-
-       if (!ah->regulatory.regpair) {
-               DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
-                       "No regulatory domain pair found, cannot continue\n");
-               return -EINVAL;
-       }
-
-       if (!country)
-               country = ath9k_regd_find_country_by_rd(regdmn);
-
-       if (country) {
-               ah->regulatory.alpha2[0] = country->isoName[0];
-               ah->regulatory.alpha2[1] = country->isoName[1];
-       } else {
-               ah->regulatory.alpha2[0] = '0';
-               ah->regulatory.alpha2[1] = '0';
-       }
-
-       DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
-               "Country alpha2 being used: %c%c\n"
-               "Regulatory.Regpair detected: 0x%0x\n",
-               ah->regulatory.alpha2[0], ah->regulatory.alpha2[1],
-               ah->regulatory.regpair->regDmnEnum);
-
-       return 0;
-}
-
-u32 ath9k_regd_get_ctl(struct ath_hw *ah, struct ath9k_channel *chan)
-{
-       u32 ctl = NO_CTL;
-
-       if (!ah->regulatory.regpair ||
-           (ah->regulatory.country_code == CTRY_DEFAULT &&
-            is_wwr_sku(ath9k_regd_get_eepromRD(ah)))) {
-               if (IS_CHAN_B(chan))
-                       ctl = SD_NO_CTL | CTL_11B;
-               else if (IS_CHAN_G(chan))
-                       ctl = SD_NO_CTL | CTL_11G;
-               else
-                       ctl = SD_NO_CTL | CTL_11A;
-               return ctl;
-       }
-
-       if (IS_CHAN_B(chan))
-               ctl = ah->regulatory.regpair->reg_2ghz_ctl | CTL_11B;
-       else if (IS_CHAN_G(chan))
-               ctl = ah->regulatory.regpair->reg_2ghz_ctl | CTL_11G;
-       else
-               ctl = ah->regulatory.regpair->reg_5ghz_ctl | CTL_11A;
-
-       return ctl;
-}
diff --git a/drivers/net/wireless/ath9k/regd.h b/drivers/net/wireless/ath9k/regd.h
deleted file mode 100644 (file)
index 9f5fbd4..0000000
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- * Copyright (c) 2008-2009 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 REGD_H
-#define REGD_H
-
-#define COUNTRY_ERD_FLAG        0x8000
-#define WORLDWIDE_ROAMING_FLAG  0x4000
-
-#define MULTI_DOMAIN_MASK 0xFF00
-
-#define WORLD_SKU_MASK          0x00F0
-#define WORLD_SKU_PREFIX        0x0060
-
-#define CHANNEL_HALF_BW         10
-#define CHANNEL_QUARTER_BW      5
-
-struct reg_dmn_pair_mapping {
-       u16 regDmnEnum;
-       u16 reg_5ghz_ctl;
-       u16 reg_2ghz_ctl;
-};
-
-struct country_code_to_enum_rd {
-       u16 countryCode;
-       u16 regDmnEnum;
-       const char *isoName;
-};
-
-struct ath9k_regulatory {
-       char alpha2[2];
-       u16 country_code;
-       u16 max_power_level;
-       u32 tp_scale;
-       u16 current_rd;
-       u16 current_rd_ext;
-       int16_t power_limit;
-       struct reg_dmn_pair_mapping *regpair;
-};
-
-enum CountryCode {
-       CTRY_ALBANIA = 8,
-       CTRY_ALGERIA = 12,
-       CTRY_ARGENTINA = 32,
-       CTRY_ARMENIA = 51,
-       CTRY_AUSTRALIA = 36,
-       CTRY_AUSTRIA = 40,
-       CTRY_AZERBAIJAN = 31,
-       CTRY_BAHRAIN = 48,
-       CTRY_BELARUS = 112,
-       CTRY_BELGIUM = 56,
-       CTRY_BELIZE = 84,
-       CTRY_BOLIVIA = 68,
-       CTRY_BOSNIA_HERZ = 70,
-       CTRY_BRAZIL = 76,
-       CTRY_BRUNEI_DARUSSALAM = 96,
-       CTRY_BULGARIA = 100,
-       CTRY_CANADA = 124,
-       CTRY_CHILE = 152,
-       CTRY_CHINA = 156,
-       CTRY_COLOMBIA = 170,
-       CTRY_COSTA_RICA = 188,
-       CTRY_CROATIA = 191,
-       CTRY_CYPRUS = 196,
-       CTRY_CZECH = 203,
-       CTRY_DENMARK = 208,
-       CTRY_DOMINICAN_REPUBLIC = 214,
-       CTRY_ECUADOR = 218,
-       CTRY_EGYPT = 818,
-       CTRY_EL_SALVADOR = 222,
-       CTRY_ESTONIA = 233,
-       CTRY_FAEROE_ISLANDS = 234,
-       CTRY_FINLAND = 246,
-       CTRY_FRANCE = 250,
-       CTRY_GEORGIA = 268,
-       CTRY_GERMANY = 276,
-       CTRY_GREECE = 300,
-       CTRY_GUATEMALA = 320,
-       CTRY_HONDURAS = 340,
-       CTRY_HONG_KONG = 344,
-       CTRY_HUNGARY = 348,
-       CTRY_ICELAND = 352,
-       CTRY_INDIA = 356,
-       CTRY_INDONESIA = 360,
-       CTRY_IRAN = 364,
-       CTRY_IRAQ = 368,
-       CTRY_IRELAND = 372,
-       CTRY_ISRAEL = 376,
-       CTRY_ITALY = 380,
-       CTRY_JAMAICA = 388,
-       CTRY_JAPAN = 392,
-       CTRY_JORDAN = 400,
-       CTRY_KAZAKHSTAN = 398,
-       CTRY_KENYA = 404,
-       CTRY_KOREA_NORTH = 408,
-       CTRY_KOREA_ROC = 410,
-       CTRY_KOREA_ROC2 = 411,
-       CTRY_KOREA_ROC3 = 412,
-       CTRY_KUWAIT = 414,
-       CTRY_LATVIA = 428,
-       CTRY_LEBANON = 422,
-       CTRY_LIBYA = 434,
-       CTRY_LIECHTENSTEIN = 438,
-       CTRY_LITHUANIA = 440,
-       CTRY_LUXEMBOURG = 442,
-       CTRY_MACAU = 446,
-       CTRY_MACEDONIA = 807,
-       CTRY_MALAYSIA = 458,
-       CTRY_MALTA = 470,
-       CTRY_MEXICO = 484,
-       CTRY_MONACO = 492,
-       CTRY_MOROCCO = 504,
-       CTRY_NEPAL = 524,
-       CTRY_NETHERLANDS = 528,
-       CTRY_NETHERLANDS_ANTILLES = 530,
-       CTRY_NEW_ZEALAND = 554,
-       CTRY_NICARAGUA = 558,
-       CTRY_NORWAY = 578,
-       CTRY_OMAN = 512,
-       CTRY_PAKISTAN = 586,
-       CTRY_PANAMA = 591,
-       CTRY_PAPUA_NEW_GUINEA = 598,
-       CTRY_PARAGUAY = 600,
-       CTRY_PERU = 604,
-       CTRY_PHILIPPINES = 608,
-       CTRY_POLAND = 616,
-       CTRY_PORTUGAL = 620,
-       CTRY_PUERTO_RICO = 630,
-       CTRY_QATAR = 634,
-       CTRY_ROMANIA = 642,
-       CTRY_RUSSIA = 643,
-       CTRY_SAUDI_ARABIA = 682,
-       CTRY_SERBIA_MONTENEGRO = 891,
-       CTRY_SINGAPORE = 702,
-       CTRY_SLOVAKIA = 703,
-       CTRY_SLOVENIA = 705,
-       CTRY_SOUTH_AFRICA = 710,
-       CTRY_SPAIN = 724,
-       CTRY_SRI_LANKA = 144,
-       CTRY_SWEDEN = 752,
-       CTRY_SWITZERLAND = 756,
-       CTRY_SYRIA = 760,
-       CTRY_TAIWAN = 158,
-       CTRY_THAILAND = 764,
-       CTRY_TRINIDAD_Y_TOBAGO = 780,
-       CTRY_TUNISIA = 788,
-       CTRY_TURKEY = 792,
-       CTRY_UAE = 784,
-       CTRY_UKRAINE = 804,
-       CTRY_UNITED_KINGDOM = 826,
-       CTRY_UNITED_STATES = 840,
-       CTRY_UNITED_STATES_FCC49 = 842,
-       CTRY_URUGUAY = 858,
-       CTRY_UZBEKISTAN = 860,
-       CTRY_VENEZUELA = 862,
-       CTRY_VIET_NAM = 704,
-       CTRY_YEMEN = 887,
-       CTRY_ZIMBABWE = 716,
-       CTRY_JAPAN1 = 393,
-       CTRY_JAPAN2 = 394,
-       CTRY_JAPAN3 = 395,
-       CTRY_JAPAN4 = 396,
-       CTRY_JAPAN5 = 397,
-       CTRY_JAPAN6 = 4006,
-       CTRY_JAPAN7 = 4007,
-       CTRY_JAPAN8 = 4008,
-       CTRY_JAPAN9 = 4009,
-       CTRY_JAPAN10 = 4010,
-       CTRY_JAPAN11 = 4011,
-       CTRY_JAPAN12 = 4012,
-       CTRY_JAPAN13 = 4013,
-       CTRY_JAPAN14 = 4014,
-       CTRY_JAPAN15 = 4015,
-       CTRY_JAPAN16 = 4016,
-       CTRY_JAPAN17 = 4017,
-       CTRY_JAPAN18 = 4018,
-       CTRY_JAPAN19 = 4019,
-       CTRY_JAPAN20 = 4020,
-       CTRY_JAPAN21 = 4021,
-       CTRY_JAPAN22 = 4022,
-       CTRY_JAPAN23 = 4023,
-       CTRY_JAPAN24 = 4024,
-       CTRY_JAPAN25 = 4025,
-       CTRY_JAPAN26 = 4026,
-       CTRY_JAPAN27 = 4027,
-       CTRY_JAPAN28 = 4028,
-       CTRY_JAPAN29 = 4029,
-       CTRY_JAPAN30 = 4030,
-       CTRY_JAPAN31 = 4031,
-       CTRY_JAPAN32 = 4032,
-       CTRY_JAPAN33 = 4033,
-       CTRY_JAPAN34 = 4034,
-       CTRY_JAPAN35 = 4035,
-       CTRY_JAPAN36 = 4036,
-       CTRY_JAPAN37 = 4037,
-       CTRY_JAPAN38 = 4038,
-       CTRY_JAPAN39 = 4039,
-       CTRY_JAPAN40 = 4040,
-       CTRY_JAPAN41 = 4041,
-       CTRY_JAPAN42 = 4042,
-       CTRY_JAPAN43 = 4043,
-       CTRY_JAPAN44 = 4044,
-       CTRY_JAPAN45 = 4045,
-       CTRY_JAPAN46 = 4046,
-       CTRY_JAPAN47 = 4047,
-       CTRY_JAPAN48 = 4048,
-       CTRY_JAPAN49 = 4049,
-       CTRY_JAPAN50 = 4050,
-       CTRY_JAPAN51 = 4051,
-       CTRY_JAPAN52 = 4052,
-       CTRY_JAPAN53 = 4053,
-       CTRY_JAPAN54 = 4054,
-       CTRY_JAPAN55 = 4055,
-       CTRY_JAPAN56 = 4056,
-       CTRY_JAPAN57 = 4057,
-       CTRY_JAPAN58 = 4058,
-       CTRY_JAPAN59 = 4059,
-       CTRY_AUSTRALIA2 = 5000,
-       CTRY_CANADA2 = 5001,
-       CTRY_BELGIUM2 = 5002
-};
-
-bool ath9k_is_world_regd(struct ath_hw *ah);
-const struct ieee80211_regdomain *ath9k_world_regdomain(struct ath_hw *ah);
-const struct ieee80211_regdomain *ath9k_default_world_regdomain(void);
-void ath9k_reg_apply_world_flags(struct wiphy *wiphy,
-                                enum nl80211_reg_initiator initiator);
-void ath9k_reg_apply_radar_flags(struct wiphy *wiphy);
-int ath9k_regd_init(struct ath_hw *ah);
-bool ath9k_regd_is_eeprom_valid(struct ath_hw *ah);
-u32 ath9k_regd_get_ctl(struct ath_hw *ah, struct ath9k_channel *chan);
-int ath9k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request);
-
-#endif
diff --git a/drivers/net/wireless/ath9k/regd_common.h b/drivers/net/wireless/ath9k/regd_common.h
deleted file mode 100644 (file)
index 4d0e298..0000000
+++ /dev/null
@@ -1,473 +0,0 @@
-/*
- * Copyright (c) 2008-2009 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 REGD_COMMON_H
-#define REGD_COMMON_H
-
-enum EnumRd {
-       NO_ENUMRD = 0x00,
-       NULL1_WORLD = 0x03,
-       NULL1_ETSIB = 0x07,
-       NULL1_ETSIC = 0x08,
-       FCC1_FCCA = 0x10,
-       FCC1_WORLD = 0x11,
-       FCC4_FCCA = 0x12,
-       FCC5_FCCA = 0x13,
-       FCC6_FCCA = 0x14,
-
-       FCC2_FCCA = 0x20,
-       FCC2_WORLD = 0x21,
-       FCC2_ETSIC = 0x22,
-       FCC6_WORLD = 0x23,
-       FRANCE_RES = 0x31,
-       FCC3_FCCA = 0x3A,
-       FCC3_WORLD = 0x3B,
-
-       ETSI1_WORLD = 0x37,
-       ETSI3_ETSIA = 0x32,
-       ETSI2_WORLD = 0x35,
-       ETSI3_WORLD = 0x36,
-       ETSI4_WORLD = 0x30,
-       ETSI4_ETSIC = 0x38,
-       ETSI5_WORLD = 0x39,
-       ETSI6_WORLD = 0x34,
-       ETSI_RESERVED = 0x33,
-
-       MKK1_MKKA = 0x40,
-       MKK1_MKKB = 0x41,
-       APL4_WORLD = 0x42,
-       MKK2_MKKA = 0x43,
-       APL_RESERVED = 0x44,
-       APL2_WORLD = 0x45,
-       APL2_APLC = 0x46,
-       APL3_WORLD = 0x47,
-       MKK1_FCCA = 0x48,
-       APL2_APLD = 0x49,
-       MKK1_MKKA1 = 0x4A,
-       MKK1_MKKA2 = 0x4B,
-       MKK1_MKKC = 0x4C,
-
-       APL3_FCCA = 0x50,
-       APL1_WORLD = 0x52,
-       APL1_FCCA = 0x53,
-       APL1_APLA = 0x54,
-       APL1_ETSIC = 0x55,
-       APL2_ETSIC = 0x56,
-       APL5_WORLD = 0x58,
-       APL6_WORLD = 0x5B,
-       APL7_FCCA = 0x5C,
-       APL8_WORLD = 0x5D,
-       APL9_WORLD = 0x5E,
-
-       WOR0_WORLD = 0x60,
-       WOR1_WORLD = 0x61,
-       WOR2_WORLD = 0x62,
-       WOR3_WORLD = 0x63,
-       WOR4_WORLD = 0x64,
-       WOR5_ETSIC = 0x65,
-
-       WOR01_WORLD = 0x66,
-       WOR02_WORLD = 0x67,
-       EU1_WORLD = 0x68,
-
-       WOR9_WORLD = 0x69,
-       WORA_WORLD = 0x6A,
-       WORB_WORLD = 0x6B,
-
-       MKK3_MKKB = 0x80,
-       MKK3_MKKA2 = 0x81,
-       MKK3_MKKC = 0x82,
-
-       MKK4_MKKB = 0x83,
-       MKK4_MKKA2 = 0x84,
-       MKK4_MKKC = 0x85,
-
-       MKK5_MKKB = 0x86,
-       MKK5_MKKA2 = 0x87,
-       MKK5_MKKC = 0x88,
-
-       MKK6_MKKB = 0x89,
-       MKK6_MKKA2 = 0x8A,
-       MKK6_MKKC = 0x8B,
-
-       MKK7_MKKB = 0x8C,
-       MKK7_MKKA2 = 0x8D,
-       MKK7_MKKC = 0x8E,
-
-       MKK8_MKKB = 0x8F,
-       MKK8_MKKA2 = 0x90,
-       MKK8_MKKC = 0x91,
-
-       MKK14_MKKA1 = 0x92,
-       MKK15_MKKA1 = 0x93,
-
-       MKK10_FCCA = 0xD0,
-       MKK10_MKKA1 = 0xD1,
-       MKK10_MKKC = 0xD2,
-       MKK10_MKKA2 = 0xD3,
-
-       MKK11_MKKA = 0xD4,
-       MKK11_FCCA = 0xD5,
-       MKK11_MKKA1 = 0xD6,
-       MKK11_MKKC = 0xD7,
-       MKK11_MKKA2 = 0xD8,
-
-       MKK12_MKKA = 0xD9,
-       MKK12_FCCA = 0xDA,
-       MKK12_MKKA1 = 0xDB,
-       MKK12_MKKC = 0xDC,
-       MKK12_MKKA2 = 0xDD,
-
-       MKK13_MKKB = 0xDE,
-
-       MKK3_MKKA = 0xF0,
-       MKK3_MKKA1 = 0xF1,
-       MKK3_FCCA = 0xF2,
-       MKK4_MKKA = 0xF3,
-       MKK4_MKKA1 = 0xF4,
-       MKK4_FCCA = 0xF5,
-       MKK9_MKKA = 0xF6,
-       MKK10_MKKA = 0xF7,
-       MKK6_MKKA1 = 0xF8,
-       MKK6_FCCA = 0xF9,
-       MKK7_MKKA1 = 0xFA,
-       MKK7_FCCA = 0xFB,
-       MKK9_FCCA = 0xFC,
-       MKK9_MKKA1 = 0xFD,
-       MKK9_MKKC = 0xFE,
-       MKK9_MKKA2 = 0xFF,
-
-       WORLD = 0x0199,
-       DEBUG_REG_DMN = 0x01ff,
-};
-
-enum ctl_group {
-       CTL_FCC = 0x10,
-       CTL_MKK = 0x40,
-       CTL_ETSI = 0x30,
-};
-
-/* Regpair to CTL band mapping */
-static struct reg_dmn_pair_mapping regDomainPairs[] = {
-       /* regpair, 5 GHz CTL, 2 GHz CTL */
-       {NO_ENUMRD, DEBUG_REG_DMN, DEBUG_REG_DMN},
-       {NULL1_WORLD, NO_CTL, CTL_ETSI},
-       {NULL1_ETSIB, NO_CTL, CTL_ETSI},
-       {NULL1_ETSIC, NO_CTL, CTL_ETSI},
-
-       {FCC2_FCCA, CTL_FCC, CTL_FCC},
-       {FCC2_WORLD, CTL_FCC, CTL_ETSI},
-       {FCC2_ETSIC, CTL_FCC, CTL_ETSI},
-       {FCC3_FCCA, CTL_FCC, CTL_FCC},
-       {FCC3_WORLD, CTL_FCC, CTL_ETSI},
-       {FCC4_FCCA, CTL_FCC, CTL_FCC},
-       {FCC5_FCCA, CTL_FCC, CTL_FCC},
-       {FCC6_FCCA, CTL_FCC, CTL_FCC},
-       {FCC6_WORLD, CTL_FCC, CTL_ETSI},
-
-       {ETSI1_WORLD, CTL_ETSI, CTL_ETSI},
-       {ETSI2_WORLD, CTL_ETSI, CTL_ETSI},
-       {ETSI3_WORLD, CTL_ETSI, CTL_ETSI},
-       {ETSI4_WORLD, CTL_ETSI, CTL_ETSI},
-       {ETSI5_WORLD, CTL_ETSI, CTL_ETSI},
-       {ETSI6_WORLD, CTL_ETSI, CTL_ETSI},
-
-       /* XXX: For ETSI3_ETSIA, Was NO_CTL meant for the 2 GHz band ? */
-       {ETSI3_ETSIA, CTL_ETSI, CTL_ETSI},
-       {FRANCE_RES, CTL_ETSI, CTL_ETSI},
-
-       {FCC1_WORLD, CTL_FCC, CTL_ETSI},
-       {FCC1_FCCA, CTL_FCC, CTL_FCC},
-       {APL1_WORLD, CTL_FCC, CTL_ETSI},
-       {APL2_WORLD, CTL_FCC, CTL_ETSI},
-       {APL3_WORLD, CTL_FCC, CTL_ETSI},
-       {APL4_WORLD, CTL_FCC, CTL_ETSI},
-       {APL5_WORLD, CTL_FCC, CTL_ETSI},
-       {APL6_WORLD, CTL_ETSI, CTL_ETSI},
-       {APL8_WORLD, CTL_ETSI, CTL_ETSI},
-       {APL9_WORLD, CTL_ETSI, CTL_ETSI},
-
-       {APL3_FCCA, CTL_FCC, CTL_FCC},
-       {APL1_ETSIC, CTL_FCC, CTL_ETSI},
-       {APL2_ETSIC, CTL_FCC, CTL_ETSI},
-       {APL2_APLD, CTL_FCC, NO_CTL},
-
-       {MKK1_MKKA, CTL_MKK, CTL_MKK},
-       {MKK1_MKKB, CTL_MKK, CTL_MKK},
-       {MKK1_FCCA, CTL_MKK, CTL_FCC},
-       {MKK1_MKKA1, CTL_MKK, CTL_MKK},
-       {MKK1_MKKA2, CTL_MKK, CTL_MKK},
-       {MKK1_MKKC, CTL_MKK, CTL_MKK},
-
-       {MKK2_MKKA, CTL_MKK, CTL_MKK},
-       {MKK3_MKKA, CTL_MKK, CTL_MKK},
-       {MKK3_MKKB, CTL_MKK, CTL_MKK},
-       {MKK3_MKKA1, CTL_MKK, CTL_MKK},
-       {MKK3_MKKA2, CTL_MKK, CTL_MKK},
-       {MKK3_MKKC, CTL_MKK, CTL_MKK},
-       {MKK3_FCCA, CTL_MKK, CTL_FCC},
-
-       {MKK4_MKKA, CTL_MKK, CTL_MKK},
-       {MKK4_MKKB, CTL_MKK, CTL_MKK},
-       {MKK4_MKKA1, CTL_MKK, CTL_MKK},
-       {MKK4_MKKA2, CTL_MKK, CTL_MKK},
-       {MKK4_MKKC, CTL_MKK, CTL_MKK},
-       {MKK4_FCCA, CTL_MKK, CTL_FCC},
-
-       {MKK5_MKKB, CTL_MKK, CTL_MKK},
-       {MKK5_MKKA2, CTL_MKK, CTL_MKK},
-       {MKK5_MKKC, CTL_MKK, CTL_MKK},
-
-       {MKK6_MKKB, CTL_MKK, CTL_MKK},
-       {MKK6_MKKA1, CTL_MKK, CTL_MKK},
-       {MKK6_MKKA2, CTL_MKK, CTL_MKK},
-       {MKK6_MKKC, CTL_MKK, CTL_MKK},
-       {MKK6_FCCA, CTL_MKK, CTL_FCC},
-
-       {MKK7_MKKB, CTL_MKK, CTL_MKK},
-       {MKK7_MKKA1, CTL_MKK, CTL_MKK},
-       {MKK7_MKKA2, CTL_MKK, CTL_MKK},
-       {MKK7_MKKC, CTL_MKK, CTL_MKK},
-       {MKK7_FCCA, CTL_MKK, CTL_FCC},
-
-       {MKK8_MKKB, CTL_MKK, CTL_MKK},
-       {MKK8_MKKA2, CTL_MKK, CTL_MKK},
-       {MKK8_MKKC, CTL_MKK, CTL_MKK},
-
-       {MKK9_MKKA, CTL_MKK, CTL_MKK},
-       {MKK9_FCCA, CTL_MKK, CTL_FCC},
-       {MKK9_MKKA1, CTL_MKK, CTL_MKK},
-       {MKK9_MKKA2, CTL_MKK, CTL_MKK},
-       {MKK9_MKKC, CTL_MKK, CTL_MKK},
-
-       {MKK10_MKKA, CTL_MKK, CTL_MKK},
-       {MKK10_FCCA, CTL_MKK, CTL_FCC},
-       {MKK10_MKKA1, CTL_MKK, CTL_MKK},
-       {MKK10_MKKA2, CTL_MKK, CTL_MKK},
-       {MKK10_MKKC, CTL_MKK, CTL_MKK},
-
-       {MKK11_MKKA, CTL_MKK, CTL_MKK},
-       {MKK11_FCCA, CTL_MKK, CTL_FCC},
-       {MKK11_MKKA1, CTL_MKK, CTL_MKK},
-       {MKK11_MKKA2, CTL_MKK, CTL_MKK},
-       {MKK11_MKKC, CTL_MKK, CTL_MKK},
-
-       {MKK12_MKKA, CTL_MKK, CTL_MKK},
-       {MKK12_FCCA, CTL_MKK, CTL_FCC},
-       {MKK12_MKKA1, CTL_MKK, CTL_MKK},
-       {MKK12_MKKA2, CTL_MKK, CTL_MKK},
-       {MKK12_MKKC, CTL_MKK, CTL_MKK},
-
-       {MKK13_MKKB, CTL_MKK, CTL_MKK},
-       {MKK14_MKKA1, CTL_MKK, CTL_MKK},
-       {MKK15_MKKA1, CTL_MKK, CTL_MKK},
-
-       {WOR0_WORLD, NO_CTL, NO_CTL},
-       {WOR1_WORLD, NO_CTL, NO_CTL},
-       {WOR2_WORLD, NO_CTL, NO_CTL},
-       {WOR3_WORLD, NO_CTL, NO_CTL},
-       {WOR4_WORLD, NO_CTL, NO_CTL},
-       {WOR5_ETSIC, NO_CTL, NO_CTL},
-       {WOR01_WORLD, NO_CTL, NO_CTL},
-       {WOR02_WORLD, NO_CTL, NO_CTL},
-       {EU1_WORLD, NO_CTL, NO_CTL},
-       {WOR9_WORLD, NO_CTL, NO_CTL},
-       {WORA_WORLD, NO_CTL, NO_CTL},
-       {WORB_WORLD, NO_CTL, NO_CTL},
-};
-
-static struct country_code_to_enum_rd allCountries[] = {
-       {CTRY_DEBUG, NO_ENUMRD, "DB"},
-       {CTRY_DEFAULT, FCC1_FCCA, "CO"},
-       {CTRY_ALBANIA, NULL1_WORLD, "AL"},
-       {CTRY_ALGERIA, NULL1_WORLD, "DZ"},
-       {CTRY_ARGENTINA, APL3_WORLD, "AR"},
-       {CTRY_ARMENIA, ETSI4_WORLD, "AM"},
-       {CTRY_AUSTRALIA, FCC2_WORLD, "AU"},
-       {CTRY_AUSTRALIA2, FCC6_WORLD, "AU"},
-       {CTRY_AUSTRIA, ETSI1_WORLD, "AT"},
-       {CTRY_AZERBAIJAN, ETSI4_WORLD, "AZ"},
-       {CTRY_BAHRAIN, APL6_WORLD, "BH"},
-       {CTRY_BELARUS, ETSI1_WORLD, "BY"},
-       {CTRY_BELGIUM, ETSI1_WORLD, "BE"},
-       {CTRY_BELGIUM2, ETSI4_WORLD, "BL"},
-       {CTRY_BELIZE, APL1_ETSIC, "BZ"},
-       {CTRY_BOLIVIA, APL1_ETSIC, "BO"},
-       {CTRY_BOSNIA_HERZ, ETSI1_WORLD, "BA"},
-       {CTRY_BRAZIL, FCC3_WORLD, "BR"},
-       {CTRY_BRUNEI_DARUSSALAM, APL1_WORLD, "BN"},
-       {CTRY_BULGARIA, ETSI6_WORLD, "BG"},
-       {CTRY_CANADA, FCC2_FCCA, "CA"},
-       {CTRY_CANADA2, FCC6_FCCA, "CA"},
-       {CTRY_CHILE, APL6_WORLD, "CL"},
-       {CTRY_CHINA, APL1_WORLD, "CN"},
-       {CTRY_COLOMBIA, FCC1_FCCA, "CO"},
-       {CTRY_COSTA_RICA, FCC1_WORLD, "CR"},
-       {CTRY_CROATIA, ETSI3_WORLD, "HR"},
-       {CTRY_CYPRUS, ETSI1_WORLD, "CY"},
-       {CTRY_CZECH, ETSI3_WORLD, "CZ"},
-       {CTRY_DENMARK, ETSI1_WORLD, "DK"},
-       {CTRY_DOMINICAN_REPUBLIC, FCC1_FCCA, "DO"},
-       {CTRY_ECUADOR, FCC1_WORLD, "EC"},
-       {CTRY_EGYPT, ETSI3_WORLD, "EG"},
-       {CTRY_EL_SALVADOR, FCC1_WORLD, "SV"},
-       {CTRY_ESTONIA, ETSI1_WORLD, "EE"},
-       {CTRY_FINLAND, ETSI1_WORLD, "FI"},
-       {CTRY_FRANCE, ETSI1_WORLD, "FR"},
-       {CTRY_GEORGIA, ETSI4_WORLD, "GE"},
-       {CTRY_GERMANY, ETSI1_WORLD, "DE"},
-       {CTRY_GREECE, ETSI1_WORLD, "GR"},
-       {CTRY_GUATEMALA, FCC1_FCCA, "GT"},
-       {CTRY_HONDURAS, NULL1_WORLD, "HN"},
-       {CTRY_HONG_KONG, FCC2_WORLD, "HK"},
-       {CTRY_HUNGARY, ETSI1_WORLD, "HU"},
-       {CTRY_ICELAND, ETSI1_WORLD, "IS"},
-       {CTRY_INDIA, APL6_WORLD, "IN"},
-       {CTRY_INDONESIA, APL1_WORLD, "ID"},
-       {CTRY_IRAN, APL1_WORLD, "IR"},
-       {CTRY_IRELAND, ETSI1_WORLD, "IE"},
-       {CTRY_ISRAEL, NULL1_WORLD, "IL"},
-       {CTRY_ITALY, ETSI1_WORLD, "IT"},
-       {CTRY_JAMAICA, ETSI1_WORLD, "JM"},
-
-       {CTRY_JAPAN, MKK1_MKKA, "JP"},
-       {CTRY_JAPAN1, MKK1_MKKB, "JP"},
-       {CTRY_JAPAN2, MKK1_FCCA, "JP"},
-       {CTRY_JAPAN3, MKK2_MKKA, "JP"},
-       {CTRY_JAPAN4, MKK1_MKKA1, "JP"},
-       {CTRY_JAPAN5, MKK1_MKKA2, "JP"},
-       {CTRY_JAPAN6, MKK1_MKKC, "JP"},
-       {CTRY_JAPAN7, MKK3_MKKB, "JP"},
-       {CTRY_JAPAN8, MKK3_MKKA2, "JP"},
-       {CTRY_JAPAN9, MKK3_MKKC, "JP"},
-       {CTRY_JAPAN10, MKK4_MKKB, "JP"},
-       {CTRY_JAPAN11, MKK4_MKKA2, "JP"},
-       {CTRY_JAPAN12, MKK4_MKKC, "JP"},
-       {CTRY_JAPAN13, MKK5_MKKB, "JP"},
-       {CTRY_JAPAN14, MKK5_MKKA2, "JP"},
-       {CTRY_JAPAN15, MKK5_MKKC, "JP"},
-       {CTRY_JAPAN16, MKK6_MKKB, "JP"},
-       {CTRY_JAPAN17, MKK6_MKKA2, "JP"},
-       {CTRY_JAPAN18, MKK6_MKKC, "JP"},
-       {CTRY_JAPAN19, MKK7_MKKB, "JP"},
-       {CTRY_JAPAN20, MKK7_MKKA2, "JP"},
-       {CTRY_JAPAN21, MKK7_MKKC, "JP"},
-       {CTRY_JAPAN22, MKK8_MKKB, "JP"},
-       {CTRY_JAPAN23, MKK8_MKKA2, "JP"},
-       {CTRY_JAPAN24, MKK8_MKKC, "JP"},
-       {CTRY_JAPAN25, MKK3_MKKA, "JP"},
-       {CTRY_JAPAN26, MKK3_MKKA1, "JP"},
-       {CTRY_JAPAN27, MKK3_FCCA, "JP"},
-       {CTRY_JAPAN28, MKK4_MKKA1, "JP"},
-       {CTRY_JAPAN29, MKK4_FCCA, "JP"},
-       {CTRY_JAPAN30, MKK6_MKKA1, "JP"},
-       {CTRY_JAPAN31, MKK6_FCCA, "JP"},
-       {CTRY_JAPAN32, MKK7_MKKA1, "JP"},
-       {CTRY_JAPAN33, MKK7_FCCA, "JP"},
-       {CTRY_JAPAN34, MKK9_MKKA, "JP"},
-       {CTRY_JAPAN35, MKK10_MKKA, "JP"},
-       {CTRY_JAPAN36, MKK4_MKKA, "JP"},
-       {CTRY_JAPAN37, MKK9_FCCA, "JP"},
-       {CTRY_JAPAN38, MKK9_MKKA1, "JP"},
-       {CTRY_JAPAN39, MKK9_MKKC, "JP"},
-       {CTRY_JAPAN40, MKK9_MKKA2, "JP"},
-       {CTRY_JAPAN41, MKK10_FCCA, "JP"},
-       {CTRY_JAPAN42, MKK10_MKKA1, "JP"},
-       {CTRY_JAPAN43, MKK10_MKKC, "JP"},
-       {CTRY_JAPAN44, MKK10_MKKA2, "JP"},
-       {CTRY_JAPAN45, MKK11_MKKA, "JP"},
-       {CTRY_JAPAN46, MKK11_FCCA, "JP"},
-       {CTRY_JAPAN47, MKK11_MKKA1, "JP"},
-       {CTRY_JAPAN48, MKK11_MKKC, "JP"},
-       {CTRY_JAPAN49, MKK11_MKKA2, "JP"},
-       {CTRY_JAPAN50, MKK12_MKKA, "JP"},
-       {CTRY_JAPAN51, MKK12_FCCA, "JP"},
-       {CTRY_JAPAN52, MKK12_MKKA1, "JP"},
-       {CTRY_JAPAN53, MKK12_MKKC, "JP"},
-       {CTRY_JAPAN54, MKK12_MKKA2, "JP"},
-       {CTRY_JAPAN57, MKK13_MKKB, "JP"},
-       {CTRY_JAPAN58, MKK14_MKKA1, "JP"},
-       {CTRY_JAPAN59, MKK15_MKKA1, "JP"},
-
-       {CTRY_JORDAN, ETSI2_WORLD, "JO"},
-       {CTRY_KAZAKHSTAN, NULL1_WORLD, "KZ"},
-       {CTRY_KOREA_NORTH, APL9_WORLD, "KP"},
-       {CTRY_KOREA_ROC, APL9_WORLD, "KR"},
-       {CTRY_KOREA_ROC2, APL2_WORLD, "K2"},
-       {CTRY_KOREA_ROC3, APL9_WORLD, "K3"},
-       {CTRY_KUWAIT, NULL1_WORLD, "KW"},
-       {CTRY_LATVIA, ETSI1_WORLD, "LV"},
-       {CTRY_LEBANON, NULL1_WORLD, "LB"},
-       {CTRY_LIECHTENSTEIN, ETSI1_WORLD, "LI"},
-       {CTRY_LITHUANIA, ETSI1_WORLD, "LT"},
-       {CTRY_LUXEMBOURG, ETSI1_WORLD, "LU"},
-       {CTRY_MACAU, FCC2_WORLD, "MO"},
-       {CTRY_MACEDONIA, NULL1_WORLD, "MK"},
-       {CTRY_MALAYSIA, APL8_WORLD, "MY"},
-       {CTRY_MALTA, ETSI1_WORLD, "MT"},
-       {CTRY_MEXICO, FCC1_FCCA, "MX"},
-       {CTRY_MONACO, ETSI4_WORLD, "MC"},
-       {CTRY_MOROCCO, NULL1_WORLD, "MA"},
-       {CTRY_NEPAL, APL1_WORLD, "NP"},
-       {CTRY_NETHERLANDS, ETSI1_WORLD, "NL"},
-       {CTRY_NETHERLANDS_ANTILLES, ETSI1_WORLD, "AN"},
-       {CTRY_NEW_ZEALAND, FCC2_ETSIC, "NZ"},
-       {CTRY_NORWAY, ETSI1_WORLD, "NO"},
-       {CTRY_OMAN, APL6_WORLD, "OM"},
-       {CTRY_PAKISTAN, NULL1_WORLD, "PK"},
-       {CTRY_PANAMA, FCC1_FCCA, "PA"},
-       {CTRY_PAPUA_NEW_GUINEA, FCC1_WORLD, "PG"},
-       {CTRY_PERU, APL1_WORLD, "PE"},
-       {CTRY_PHILIPPINES, APL1_WORLD, "PH"},
-       {CTRY_POLAND, ETSI1_WORLD, "PL"},
-       {CTRY_PORTUGAL, ETSI1_WORLD, "PT"},
-       {CTRY_PUERTO_RICO, FCC1_FCCA, "PR"},
-       {CTRY_QATAR, NULL1_WORLD, "QA"},
-       {CTRY_ROMANIA, NULL1_WORLD, "RO"},
-       {CTRY_RUSSIA, NULL1_WORLD, "RU"},
-       {CTRY_SAUDI_ARABIA, NULL1_WORLD, "SA"},
-       {CTRY_SERBIA_MONTENEGRO, ETSI1_WORLD, "CS"},
-       {CTRY_SINGAPORE, APL6_WORLD, "SG"},
-       {CTRY_SLOVAKIA, ETSI1_WORLD, "SK"},
-       {CTRY_SLOVENIA, ETSI1_WORLD, "SI"},
-       {CTRY_SOUTH_AFRICA, FCC3_WORLD, "ZA"},
-       {CTRY_SPAIN, ETSI1_WORLD, "ES"},
-       {CTRY_SRI_LANKA, FCC3_WORLD, "LK"},
-       {CTRY_SWEDEN, ETSI1_WORLD, "SE"},
-       {CTRY_SWITZERLAND, ETSI1_WORLD, "CH"},
-       {CTRY_SYRIA, NULL1_WORLD, "SY"},
-       {CTRY_TAIWAN, APL3_FCCA, "TW"},
-       {CTRY_THAILAND, NULL1_WORLD, "TH"},
-       {CTRY_TRINIDAD_Y_TOBAGO, ETSI4_WORLD, "TT"},
-       {CTRY_TUNISIA, ETSI3_WORLD, "TN"},
-       {CTRY_TURKEY, ETSI3_WORLD, "TR"},
-       {CTRY_UKRAINE, NULL1_WORLD, "UA"},
-       {CTRY_UAE, NULL1_WORLD, "AE"},
-       {CTRY_UNITED_KINGDOM, ETSI1_WORLD, "GB"},
-       {CTRY_UNITED_STATES, FCC3_FCCA, "US"},
-       /* This "PS" is for US public safety actually... to support this we
-        * would need to assign new special alpha2 to CRDA db as with the world
-        * regdomain and use another alpha2 */
-       {CTRY_UNITED_STATES_FCC49, FCC4_FCCA, "PS"},
-       {CTRY_URUGUAY, APL2_WORLD, "UY"},
-       {CTRY_UZBEKISTAN, FCC3_FCCA, "UZ"},
-       {CTRY_VENEZUELA, APL2_ETSIC, "VE"},
-       {CTRY_VIET_NAM, NULL1_WORLD, "VN"},
-       {CTRY_YEMEN, NULL1_WORLD, "YE"},
-       {CTRY_ZIMBABWE, NULL1_WORLD, "ZW"},
-};
-
-#endif
diff --git a/drivers/net/wireless/ath9k/virtual.c b/drivers/net/wireless/ath9k/virtual.c
deleted file mode 100644 (file)
index 1ff429b..0000000
+++ /dev/null
@@ -1,662 +0,0 @@
-/*
- * Copyright (c) 2008-2009 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 "ath9k.h"
-
-struct ath9k_vif_iter_data {
-       int count;
-       u8 *addr;
-};
-
-static void ath9k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
-{
-       struct ath9k_vif_iter_data *iter_data = data;
-       u8 *nbuf;
-
-       nbuf = krealloc(iter_data->addr, (iter_data->count + 1) * ETH_ALEN,
-                       GFP_ATOMIC);
-       if (nbuf == NULL)
-               return;
-
-       memcpy(nbuf + iter_data->count * ETH_ALEN, mac, ETH_ALEN);
-       iter_data->addr = nbuf;
-       iter_data->count++;
-}
-
-void ath9k_set_bssid_mask(struct ieee80211_hw *hw)
-{
-       struct ath_wiphy *aphy = hw->priv;
-       struct ath_softc *sc = aphy->sc;
-       struct ath9k_vif_iter_data iter_data;
-       int i, j;
-       u8 mask[ETH_ALEN];
-
-       /*
-        * Add primary MAC address even if it is not in active use since it
-        * will be configured to the hardware as the starting point and the
-        * BSSID mask will need to be changed if another address is active.
-        */
-       iter_data.addr = kmalloc(ETH_ALEN, GFP_ATOMIC);
-       if (iter_data.addr) {
-               memcpy(iter_data.addr, sc->sc_ah->macaddr, ETH_ALEN);
-               iter_data.count = 1;
-       } else
-               iter_data.count = 0;
-
-       /* Get list of all active MAC addresses */
-       spin_lock_bh(&sc->wiphy_lock);
-       ieee80211_iterate_active_interfaces_atomic(sc->hw, ath9k_vif_iter,
-                                                  &iter_data);
-       for (i = 0; i < sc->num_sec_wiphy; i++) {
-               if (sc->sec_wiphy[i] == NULL)
-                       continue;
-               ieee80211_iterate_active_interfaces_atomic(
-                       sc->sec_wiphy[i]->hw, ath9k_vif_iter, &iter_data);
-       }
-       spin_unlock_bh(&sc->wiphy_lock);
-
-       /* Generate an address mask to cover all active addresses */
-       memset(mask, 0, ETH_ALEN);
-       for (i = 0; i < iter_data.count; i++) {
-               u8 *a1 = iter_data.addr + i * ETH_ALEN;
-               for (j = i + 1; j < iter_data.count; j++) {
-                       u8 *a2 = iter_data.addr + j * ETH_ALEN;
-                       mask[0] |= a1[0] ^ a2[0];
-                       mask[1] |= a1[1] ^ a2[1];
-                       mask[2] |= a1[2] ^ a2[2];
-                       mask[3] |= a1[3] ^ a2[3];
-                       mask[4] |= a1[4] ^ a2[4];
-                       mask[5] |= a1[5] ^ a2[5];
-               }
-       }
-
-       kfree(iter_data.addr);
-
-       /* Invert the mask and configure hardware */
-       sc->bssidmask[0] = ~mask[0];
-       sc->bssidmask[1] = ~mask[1];
-       sc->bssidmask[2] = ~mask[2];
-       sc->bssidmask[3] = ~mask[3];
-       sc->bssidmask[4] = ~mask[4];
-       sc->bssidmask[5] = ~mask[5];
-
-       ath9k_hw_setbssidmask(sc);
-}
-
-int ath9k_wiphy_add(struct ath_softc *sc)
-{
-       int i, error;
-       struct ath_wiphy *aphy;
-       struct ieee80211_hw *hw;
-       u8 addr[ETH_ALEN];
-
-       hw = ieee80211_alloc_hw(sizeof(struct ath_wiphy), &ath9k_ops);
-       if (hw == NULL)
-               return -ENOMEM;
-
-       spin_lock_bh(&sc->wiphy_lock);
-       for (i = 0; i < sc->num_sec_wiphy; i++) {
-               if (sc->sec_wiphy[i] == NULL)
-                       break;
-       }
-
-       if (i == sc->num_sec_wiphy) {
-               /* No empty slot available; increase array length */
-               struct ath_wiphy **n;
-               n = krealloc(sc->sec_wiphy,
-                            (sc->num_sec_wiphy + 1) *
-                            sizeof(struct ath_wiphy *),
-                            GFP_ATOMIC);
-               if (n == NULL) {
-                       spin_unlock_bh(&sc->wiphy_lock);
-                       ieee80211_free_hw(hw);
-                       return -ENOMEM;
-               }
-               n[i] = NULL;
-               sc->sec_wiphy = n;
-               sc->num_sec_wiphy++;
-       }
-
-       SET_IEEE80211_DEV(hw, sc->dev);
-
-       aphy = hw->priv;
-       aphy->sc = sc;
-       aphy->hw = hw;
-       sc->sec_wiphy[i] = aphy;
-       spin_unlock_bh(&sc->wiphy_lock);
-
-       memcpy(addr, sc->sc_ah->macaddr, ETH_ALEN);
-       addr[0] |= 0x02; /* Locally managed address */
-       /*
-        * XOR virtual wiphy index into the least significant bits to generate
-        * a different MAC address for each virtual wiphy.
-        */
-       addr[5] ^= i & 0xff;
-       addr[4] ^= (i & 0xff00) >> 8;
-       addr[3] ^= (i & 0xff0000) >> 16;
-
-       SET_IEEE80211_PERM_ADDR(hw, addr);
-
-       ath_set_hw_capab(sc, hw);
-
-       error = ieee80211_register_hw(hw);
-
-       if (error == 0) {
-               /* Make sure wiphy scheduler is started (if enabled) */
-               ath9k_wiphy_set_scheduler(sc, sc->wiphy_scheduler_int);
-       }
-
-       return error;
-}
-
-int ath9k_wiphy_del(struct ath_wiphy *aphy)
-{
-       struct ath_softc *sc = aphy->sc;
-       int i;
-
-       spin_lock_bh(&sc->wiphy_lock);
-       for (i = 0; i < sc->num_sec_wiphy; i++) {
-               if (aphy == sc->sec_wiphy[i]) {
-                       sc->sec_wiphy[i] = NULL;
-                       spin_unlock_bh(&sc->wiphy_lock);
-                       ieee80211_unregister_hw(aphy->hw);
-                       ieee80211_free_hw(aphy->hw);
-                       return 0;
-               }
-       }
-       spin_unlock_bh(&sc->wiphy_lock);
-       return -ENOENT;
-}
-
-static int ath9k_send_nullfunc(struct ath_wiphy *aphy,
-                              struct ieee80211_vif *vif, const u8 *bssid,
-                              int ps)
-{
-       struct ath_softc *sc = aphy->sc;
-       struct ath_tx_control txctl;
-       struct sk_buff *skb;
-       struct ieee80211_hdr *hdr;
-       __le16 fc;
-       struct ieee80211_tx_info *info;
-
-       skb = dev_alloc_skb(24);
-       if (skb == NULL)
-               return -ENOMEM;
-       hdr = (struct ieee80211_hdr *) skb_put(skb, 24);
-       memset(hdr, 0, 24);
-       fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC |
-                        IEEE80211_FCTL_TODS);
-       if (ps)
-               fc |= cpu_to_le16(IEEE80211_FCTL_PM);
-       hdr->frame_control = fc;
-       memcpy(hdr->addr1, bssid, ETH_ALEN);
-       memcpy(hdr->addr2, aphy->hw->wiphy->perm_addr, ETH_ALEN);
-       memcpy(hdr->addr3, bssid, ETH_ALEN);
-
-       info = IEEE80211_SKB_CB(skb);
-       memset(info, 0, sizeof(*info));
-       info->flags = IEEE80211_TX_CTL_REQ_TX_STATUS;
-       info->control.vif = vif;
-       info->control.rates[0].idx = 0;
-       info->control.rates[0].count = 4;
-       info->control.rates[1].idx = -1;
-
-       memset(&txctl, 0, sizeof(struct ath_tx_control));
-       txctl.txq = &sc->tx.txq[sc->tx.hwq_map[ATH9K_WME_AC_VO]];
-       txctl.frame_type = ps ? ATH9K_INT_PAUSE : ATH9K_INT_UNPAUSE;
-
-       if (ath_tx_start(aphy->hw, skb, &txctl) != 0)
-               goto exit;
-
-       return 0;
-exit:
-       dev_kfree_skb_any(skb);
-       return -1;
-}
-
-static bool __ath9k_wiphy_pausing(struct ath_softc *sc)
-{
-       int i;
-       if (sc->pri_wiphy->state == ATH_WIPHY_PAUSING)
-               return true;
-       for (i = 0; i < sc->num_sec_wiphy; i++) {
-               if (sc->sec_wiphy[i] &&
-                   sc->sec_wiphy[i]->state == ATH_WIPHY_PAUSING)
-                       return true;
-       }
-       return false;
-}
-
-static bool ath9k_wiphy_pausing(struct ath_softc *sc)
-{
-       bool ret;
-       spin_lock_bh(&sc->wiphy_lock);
-       ret = __ath9k_wiphy_pausing(sc);
-       spin_unlock_bh(&sc->wiphy_lock);
-       return ret;
-}
-
-static bool __ath9k_wiphy_scanning(struct ath_softc *sc)
-{
-       int i;
-       if (sc->pri_wiphy->state == ATH_WIPHY_SCAN)
-               return true;
-       for (i = 0; i < sc->num_sec_wiphy; i++) {
-               if (sc->sec_wiphy[i] &&
-                   sc->sec_wiphy[i]->state == ATH_WIPHY_SCAN)
-                       return true;
-       }
-       return false;
-}
-
-bool ath9k_wiphy_scanning(struct ath_softc *sc)
-{
-       bool ret;
-       spin_lock_bh(&sc->wiphy_lock);
-       ret = __ath9k_wiphy_scanning(sc);
-       spin_unlock_bh(&sc->wiphy_lock);
-       return ret;
-}
-
-static int __ath9k_wiphy_unpause(struct ath_wiphy *aphy);
-
-/* caller must hold wiphy_lock */
-static void __ath9k_wiphy_unpause_ch(struct ath_wiphy *aphy)
-{
-       if (aphy == NULL)
-               return;
-       if (aphy->chan_idx != aphy->sc->chan_idx)
-               return; /* wiphy not on the selected channel */
-       __ath9k_wiphy_unpause(aphy);
-}
-
-static void ath9k_wiphy_unpause_channel(struct ath_softc *sc)
-{
-       int i;
-       spin_lock_bh(&sc->wiphy_lock);
-       __ath9k_wiphy_unpause_ch(sc->pri_wiphy);
-       for (i = 0; i < sc->num_sec_wiphy; i++)
-               __ath9k_wiphy_unpause_ch(sc->sec_wiphy[i]);
-       spin_unlock_bh(&sc->wiphy_lock);
-}
-
-void ath9k_wiphy_chan_work(struct work_struct *work)
-{
-       struct ath_softc *sc = container_of(work, struct ath_softc, chan_work);
-       struct ath_wiphy *aphy = sc->next_wiphy;
-
-       if (aphy == NULL)
-               return;
-
-       /*
-        * All pending interfaces paused; ready to change
-        * channels.
-        */
-
-       /* Change channels */
-       mutex_lock(&sc->mutex);
-       /* XXX: remove me eventually */
-       ath9k_update_ichannel(sc, aphy->hw,
-                             &sc->sc_ah->channels[sc->chan_idx]);
-       ath_update_chainmask(sc, sc->chan_is_ht);
-       if (ath_set_channel(sc, aphy->hw,
-                           &sc->sc_ah->channels[sc->chan_idx]) < 0) {
-               printk(KERN_DEBUG "ath9k: Failed to set channel for new "
-                      "virtual wiphy\n");
-               mutex_unlock(&sc->mutex);
-               return;
-       }
-       mutex_unlock(&sc->mutex);
-
-       ath9k_wiphy_unpause_channel(sc);
-}
-
-/*
- * ath9k version of ieee80211_tx_status() for TX frames that are generated
- * internally in the driver.
- */
-void ath9k_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
-{
-       struct ath_wiphy *aphy = hw->priv;
-       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
-       struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
-
-       if (tx_info_priv && tx_info_priv->frame_type == ATH9K_INT_PAUSE &&
-           aphy->state == ATH_WIPHY_PAUSING) {
-               if (!(info->flags & IEEE80211_TX_STAT_ACK)) {
-                       printk(KERN_DEBUG "ath9k: %s: no ACK for pause "
-                              "frame\n", wiphy_name(hw->wiphy));
-                       /*
-                        * The AP did not reply; ignore this to allow us to
-                        * continue.
-                        */
-               }
-               aphy->state = ATH_WIPHY_PAUSED;
-               if (!ath9k_wiphy_pausing(aphy->sc)) {
-                       /*
-                        * Drop from tasklet to work to allow mutex for channel
-                        * change.
-                        */
-                       queue_work(aphy->sc->hw->workqueue,
-                                  &aphy->sc->chan_work);
-               }
-       }
-
-       kfree(tx_info_priv);
-       tx_info->rate_driver_data[0] = NULL;
-
-       dev_kfree_skb(skb);
-}
-
-static void ath9k_mark_paused(struct ath_wiphy *aphy)
-{
-       struct ath_softc *sc = aphy->sc;
-       aphy->state = ATH_WIPHY_PAUSED;
-       if (!__ath9k_wiphy_pausing(sc))
-               queue_work(sc->hw->workqueue, &sc->chan_work);
-}
-
-static void ath9k_pause_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
-{
-       struct ath_wiphy *aphy = data;
-       struct ath_vif *avp = (void *) vif->drv_priv;
-
-       switch (vif->type) {
-       case NL80211_IFTYPE_STATION:
-               if (!vif->bss_conf.assoc) {
-                       ath9k_mark_paused(aphy);
-                       break;
-               }
-               /* TODO: could avoid this if already in PS mode */
-               if (ath9k_send_nullfunc(aphy, vif, avp->bssid, 1)) {
-                       printk(KERN_DEBUG "%s: failed to send PS nullfunc\n",
-                              __func__);
-                       ath9k_mark_paused(aphy);
-               }
-               break;
-       case NL80211_IFTYPE_AP:
-               /* Beacon transmission is paused by aphy->state change */
-               ath9k_mark_paused(aphy);
-               break;
-       default:
-               break;
-       }
-}
-
-/* caller must hold wiphy_lock */
-static int __ath9k_wiphy_pause(struct ath_wiphy *aphy)
-{
-       ieee80211_stop_queues(aphy->hw);
-       aphy->state = ATH_WIPHY_PAUSING;
-       /*
-        * TODO: handle PAUSING->PAUSED for the case where there are multiple
-        * active vifs (now we do it on the first vif getting ready; should be
-        * on the last)
-        */
-       ieee80211_iterate_active_interfaces_atomic(aphy->hw, ath9k_pause_iter,
-                                                  aphy);
-       return 0;
-}
-
-int ath9k_wiphy_pause(struct ath_wiphy *aphy)
-{
-       int ret;
-       spin_lock_bh(&aphy->sc->wiphy_lock);
-       ret = __ath9k_wiphy_pause(aphy);
-       spin_unlock_bh(&aphy->sc->wiphy_lock);
-       return ret;
-}
-
-static void ath9k_unpause_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
-{
-       struct ath_wiphy *aphy = data;
-       struct ath_vif *avp = (void *) vif->drv_priv;
-
-       switch (vif->type) {
-       case NL80211_IFTYPE_STATION:
-               if (!vif->bss_conf.assoc)
-                       break;
-               ath9k_send_nullfunc(aphy, vif, avp->bssid, 0);
-               break;
-       case NL80211_IFTYPE_AP:
-               /* Beacon transmission is re-enabled by aphy->state change */
-               break;
-       default:
-               break;
-       }
-}
-
-/* caller must hold wiphy_lock */
-static int __ath9k_wiphy_unpause(struct ath_wiphy *aphy)
-{
-       ieee80211_iterate_active_interfaces_atomic(aphy->hw,
-                                                  ath9k_unpause_iter, aphy);
-       aphy->state = ATH_WIPHY_ACTIVE;
-       ieee80211_wake_queues(aphy->hw);
-       return 0;
-}
-
-int ath9k_wiphy_unpause(struct ath_wiphy *aphy)
-{
-       int ret;
-       spin_lock_bh(&aphy->sc->wiphy_lock);
-       ret = __ath9k_wiphy_unpause(aphy);
-       spin_unlock_bh(&aphy->sc->wiphy_lock);
-       return ret;
-}
-
-static void __ath9k_wiphy_mark_all_paused(struct ath_softc *sc)
-{
-       int i;
-       if (sc->pri_wiphy->state != ATH_WIPHY_INACTIVE)
-               sc->pri_wiphy->state = ATH_WIPHY_PAUSED;
-       for (i = 0; i < sc->num_sec_wiphy; i++) {
-               if (sc->sec_wiphy[i] &&
-                   sc->sec_wiphy[i]->state != ATH_WIPHY_INACTIVE)
-                       sc->sec_wiphy[i]->state = ATH_WIPHY_PAUSED;
-       }
-}
-
-/* caller must hold wiphy_lock */
-static void __ath9k_wiphy_pause_all(struct ath_softc *sc)
-{
-       int i;
-       if (sc->pri_wiphy->state == ATH_WIPHY_ACTIVE)
-               __ath9k_wiphy_pause(sc->pri_wiphy);
-       for (i = 0; i < sc->num_sec_wiphy; i++) {
-               if (sc->sec_wiphy[i] &&
-                   sc->sec_wiphy[i]->state == ATH_WIPHY_ACTIVE)
-                       __ath9k_wiphy_pause(sc->sec_wiphy[i]);
-       }
-}
-
-int ath9k_wiphy_select(struct ath_wiphy *aphy)
-{
-       struct ath_softc *sc = aphy->sc;
-       bool now;
-
-       spin_lock_bh(&sc->wiphy_lock);
-       if (__ath9k_wiphy_scanning(sc)) {
-               /*
-                * For now, we are using mac80211 sw scan and it expects to
-                * have full control over channel changes, so avoid wiphy
-                * scheduling during a scan. This could be optimized if the
-                * scanning control were moved into the driver.
-                */
-               spin_unlock_bh(&sc->wiphy_lock);
-               return -EBUSY;
-       }
-       if (__ath9k_wiphy_pausing(sc)) {
-               if (sc->wiphy_select_failures == 0)
-                       sc->wiphy_select_first_fail = jiffies;
-               sc->wiphy_select_failures++;
-               if (time_after(jiffies, sc->wiphy_select_first_fail + HZ / 2))
-               {
-                       printk(KERN_DEBUG "ath9k: Previous wiphy select timed "
-                              "out; disable/enable hw to recover\n");
-                       __ath9k_wiphy_mark_all_paused(sc);
-                       /*
-                        * TODO: this workaround to fix hardware is unlikely to
-                        * be specific to virtual wiphy changes. It can happen
-                        * on normal channel change, too, and as such, this
-                        * should really be made more generic. For example,
-                        * tricker radio disable/enable on GTT interrupt burst
-                        * (say, 10 GTT interrupts received without any TX
-                        * frame being completed)
-                        */
-                       spin_unlock_bh(&sc->wiphy_lock);
-                       ath_radio_disable(sc);
-                       ath_radio_enable(sc);
-                       queue_work(aphy->sc->hw->workqueue,
-                                  &aphy->sc->chan_work);
-                       return -EBUSY; /* previous select still in progress */
-               }
-               spin_unlock_bh(&sc->wiphy_lock);
-               return -EBUSY; /* previous select still in progress */
-       }
-       sc->wiphy_select_failures = 0;
-
-       /* Store the new channel */
-       sc->chan_idx = aphy->chan_idx;
-       sc->chan_is_ht = aphy->chan_is_ht;
-       sc->next_wiphy = aphy;
-
-       __ath9k_wiphy_pause_all(sc);
-       now = !__ath9k_wiphy_pausing(aphy->sc);
-       spin_unlock_bh(&sc->wiphy_lock);
-
-       if (now) {
-               /* Ready to request channel change immediately */
-               queue_work(aphy->sc->hw->workqueue, &aphy->sc->chan_work);
-       }
-
-       /*
-        * wiphys will be unpaused in ath9k_tx_status() once channel has been
-        * changed if any wiphy needs time to become paused.
-        */
-
-       return 0;
-}
-
-bool ath9k_wiphy_started(struct ath_softc *sc)
-{
-       int i;
-       spin_lock_bh(&sc->wiphy_lock);
-       if (sc->pri_wiphy->state != ATH_WIPHY_INACTIVE) {
-               spin_unlock_bh(&sc->wiphy_lock);
-               return true;
-       }
-       for (i = 0; i < sc->num_sec_wiphy; i++) {
-               if (sc->sec_wiphy[i] &&
-                   sc->sec_wiphy[i]->state != ATH_WIPHY_INACTIVE) {
-                       spin_unlock_bh(&sc->wiphy_lock);
-                       return true;
-               }
-       }
-       spin_unlock_bh(&sc->wiphy_lock);
-       return false;
-}
-
-static void ath9k_wiphy_pause_chan(struct ath_wiphy *aphy,
-                                  struct ath_wiphy *selected)
-{
-       if (selected->state == ATH_WIPHY_SCAN) {
-               if (aphy == selected)
-                       return;
-               /*
-                * Pause all other wiphys for the duration of the scan even if
-                * they are on the current channel now.
-                */
-       } else if (aphy->chan_idx == selected->chan_idx)
-               return;
-       aphy->state = ATH_WIPHY_PAUSED;
-       ieee80211_stop_queues(aphy->hw);
-}
-
-void ath9k_wiphy_pause_all_forced(struct ath_softc *sc,
-                                 struct ath_wiphy *selected)
-{
-       int i;
-       spin_lock_bh(&sc->wiphy_lock);
-       if (sc->pri_wiphy->state == ATH_WIPHY_ACTIVE)
-               ath9k_wiphy_pause_chan(sc->pri_wiphy, selected);
-       for (i = 0; i < sc->num_sec_wiphy; i++) {
-               if (sc->sec_wiphy[i] &&
-                   sc->sec_wiphy[i]->state == ATH_WIPHY_ACTIVE)
-                       ath9k_wiphy_pause_chan(sc->sec_wiphy[i], selected);
-       }
-       spin_unlock_bh(&sc->wiphy_lock);
-}
-
-void ath9k_wiphy_work(struct work_struct *work)
-{
-       struct ath_softc *sc = container_of(work, struct ath_softc,
-                                           wiphy_work.work);
-       struct ath_wiphy *aphy = NULL;
-       bool first = true;
-
-       spin_lock_bh(&sc->wiphy_lock);
-
-       if (sc->wiphy_scheduler_int == 0) {
-               /* wiphy scheduler is disabled */
-               spin_unlock_bh(&sc->wiphy_lock);
-               return;
-       }
-
-try_again:
-       sc->wiphy_scheduler_index++;
-       while (sc->wiphy_scheduler_index <= sc->num_sec_wiphy) {
-               aphy = sc->sec_wiphy[sc->wiphy_scheduler_index - 1];
-               if (aphy && aphy->state != ATH_WIPHY_INACTIVE)
-                       break;
-
-               sc->wiphy_scheduler_index++;
-               aphy = NULL;
-       }
-       if (aphy == NULL) {
-               sc->wiphy_scheduler_index = 0;
-               if (sc->pri_wiphy->state == ATH_WIPHY_INACTIVE) {
-                       if (first) {
-                               first = false;
-                               goto try_again;
-                       }
-                       /* No wiphy is ready to be scheduled */
-               } else
-                       aphy = sc->pri_wiphy;
-       }
-
-       spin_unlock_bh(&sc->wiphy_lock);
-
-       if (aphy &&
-           aphy->state != ATH_WIPHY_ACTIVE && aphy->state != ATH_WIPHY_SCAN &&
-           ath9k_wiphy_select(aphy)) {
-               printk(KERN_DEBUG "ath9k: Failed to schedule virtual wiphy "
-                      "change\n");
-       }
-
-       queue_delayed_work(sc->hw->workqueue, &sc->wiphy_work,
-                          sc->wiphy_scheduler_int);
-}
-
-void ath9k_wiphy_set_scheduler(struct ath_softc *sc, unsigned int msec_int)
-{
-       cancel_delayed_work_sync(&sc->wiphy_work);
-       sc->wiphy_scheduler_int = msecs_to_jiffies(msec_int);
-       if (sc->wiphy_scheduler_int)
-               queue_delayed_work(sc->hw->workqueue, &sc->wiphy_work,
-                                  sc->wiphy_scheduler_int);
-}
diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath9k/xmit.c
deleted file mode 100644 (file)
index 689bdbf..0000000
+++ /dev/null
@@ -1,2178 +0,0 @@
-/*
- * Copyright (c) 2008-2009 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 "ath9k.h"
-
-#define BITS_PER_BYTE           8
-#define OFDM_PLCP_BITS          22
-#define HT_RC_2_MCS(_rc)        ((_rc) & 0x0f)
-#define HT_RC_2_STREAMS(_rc)    ((((_rc) & 0x78) >> 3) + 1)
-#define L_STF                   8
-#define L_LTF                   8
-#define L_SIG                   4
-#define HT_SIG                  8
-#define HT_STF                  4
-#define HT_LTF(_ns)             (4 * (_ns))
-#define SYMBOL_TIME(_ns)        ((_ns) << 2) /* ns * 4 us */
-#define SYMBOL_TIME_HALFGI(_ns) (((_ns) * 18 + 4) / 5)  /* ns * 3.6 us */
-#define NUM_SYMBOLS_PER_USEC(_usec) (_usec >> 2)
-#define NUM_SYMBOLS_PER_USEC_HALFGI(_usec) (((_usec*5)-4)/18)
-
-#define OFDM_SIFS_TIME             16
-
-static u32 bits_per_symbol[][2] = {
-       /* 20MHz 40MHz */
-       {    26,   54 },     /*  0: BPSK */
-       {    52,  108 },     /*  1: QPSK 1/2 */
-       {    78,  162 },     /*  2: QPSK 3/4 */
-       {   104,  216 },     /*  3: 16-QAM 1/2 */
-       {   156,  324 },     /*  4: 16-QAM 3/4 */
-       {   208,  432 },     /*  5: 64-QAM 2/3 */
-       {   234,  486 },     /*  6: 64-QAM 3/4 */
-       {   260,  540 },     /*  7: 64-QAM 5/6 */
-       {    52,  108 },     /*  8: BPSK */
-       {   104,  216 },     /*  9: QPSK 1/2 */
-       {   156,  324 },     /* 10: QPSK 3/4 */
-       {   208,  432 },     /* 11: 16-QAM 1/2 */
-       {   312,  648 },     /* 12: 16-QAM 3/4 */
-       {   416,  864 },     /* 13: 64-QAM 2/3 */
-       {   468,  972 },     /* 14: 64-QAM 3/4 */
-       {   520, 1080 },     /* 15: 64-QAM 5/6 */
-};
-
-#define IS_HT_RATE(_rate)     ((_rate) & 0x80)
-
-static void ath_tx_send_ht_normal(struct ath_softc *sc, struct ath_txq *txq,
-                                 struct ath_atx_tid *tid,
-                                 struct list_head *bf_head);
-static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
-                               struct list_head *bf_q,
-                               int txok, int sendbar);
-static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
-                            struct list_head *head);
-static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf);
-static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf,
-                             int txok);
-static void ath_tx_rc_status(struct ath_buf *bf, struct ath_desc *ds,
-                            int nbad, int txok, bool update_rc);
-
-/*********************/
-/* Aggregation logic */
-/*********************/
-
-static int ath_aggr_query(struct ath_softc *sc, struct ath_node *an, u8 tidno)
-{
-       struct ath_atx_tid *tid;
-       tid = ATH_AN_2_TID(an, tidno);
-
-       if (tid->state & AGGR_ADDBA_COMPLETE ||
-           tid->state & AGGR_ADDBA_PROGRESS)
-               return 1;
-       else
-               return 0;
-}
-
-static void ath_tx_queue_tid(struct ath_txq *txq, struct ath_atx_tid *tid)
-{
-       struct ath_atx_ac *ac = tid->ac;
-
-       if (tid->paused)
-               return;
-
-       if (tid->sched)
-               return;
-
-       tid->sched = true;
-       list_add_tail(&tid->list, &ac->tid_q);
-
-       if (ac->sched)
-               return;
-
-       ac->sched = true;
-       list_add_tail(&ac->list, &txq->axq_acq);
-}
-
-static void ath_tx_pause_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
-{
-       struct ath_txq *txq = &sc->tx.txq[tid->ac->qnum];
-
-       spin_lock_bh(&txq->axq_lock);
-       tid->paused++;
-       spin_unlock_bh(&txq->axq_lock);
-}
-
-static void ath_tx_resume_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
-{
-       struct ath_txq *txq = &sc->tx.txq[tid->ac->qnum];
-
-       ASSERT(tid->paused > 0);
-       spin_lock_bh(&txq->axq_lock);
-
-       tid->paused--;
-
-       if (tid->paused > 0)
-               goto unlock;
-
-       if (list_empty(&tid->buf_q))
-               goto unlock;
-
-       ath_tx_queue_tid(txq, tid);
-       ath_txq_schedule(sc, txq);
-unlock:
-       spin_unlock_bh(&txq->axq_lock);
-}
-
-static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
-{
-       struct ath_txq *txq = &sc->tx.txq[tid->ac->qnum];
-       struct ath_buf *bf;
-       struct list_head bf_head;
-       INIT_LIST_HEAD(&bf_head);
-
-       ASSERT(tid->paused > 0);
-       spin_lock_bh(&txq->axq_lock);
-
-       tid->paused--;
-
-       if (tid->paused > 0) {
-               spin_unlock_bh(&txq->axq_lock);
-               return;
-       }
-
-       while (!list_empty(&tid->buf_q)) {
-               bf = list_first_entry(&tid->buf_q, struct ath_buf, list);
-               ASSERT(!bf_isretried(bf));
-               list_move_tail(&bf->list, &bf_head);
-               ath_tx_send_ht_normal(sc, txq, tid, &bf_head);
-       }
-
-       spin_unlock_bh(&txq->axq_lock);
-}
-
-static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid,
-                             int seqno)
-{
-       int index, cindex;
-
-       index  = ATH_BA_INDEX(tid->seq_start, seqno);
-       cindex = (tid->baw_head + index) & (ATH_TID_MAX_BUFS - 1);
-
-       tid->tx_buf[cindex] = NULL;
-
-       while (tid->baw_head != tid->baw_tail && !tid->tx_buf[tid->baw_head]) {
-               INCR(tid->seq_start, IEEE80211_SEQ_MAX);
-               INCR(tid->baw_head, ATH_TID_MAX_BUFS);
-       }
-}
-
-static void ath_tx_addto_baw(struct ath_softc *sc, struct ath_atx_tid *tid,
-                            struct ath_buf *bf)
-{
-       int index, cindex;
-
-       if (bf_isretried(bf))
-               return;
-
-       index  = ATH_BA_INDEX(tid->seq_start, bf->bf_seqno);
-       cindex = (tid->baw_head + index) & (ATH_TID_MAX_BUFS - 1);
-
-       ASSERT(tid->tx_buf[cindex] == NULL);
-       tid->tx_buf[cindex] = bf;
-
-       if (index >= ((tid->baw_tail - tid->baw_head) &
-               (ATH_TID_MAX_BUFS - 1))) {
-               tid->baw_tail = cindex;
-               INCR(tid->baw_tail, ATH_TID_MAX_BUFS);
-       }
-}
-
-/*
- * TODO: For frame(s) that are in the retry state, we will reuse the
- * sequence number(s) without setting the retry bit. The
- * alternative is to give up on these and BAR the receiver's window
- * forward.
- */
-static void ath_tid_drain(struct ath_softc *sc, struct ath_txq *txq,
-                         struct ath_atx_tid *tid)
-
-{
-       struct ath_buf *bf;
-       struct list_head bf_head;
-       INIT_LIST_HEAD(&bf_head);
-
-       for (;;) {
-               if (list_empty(&tid->buf_q))
-                       break;
-
-               bf = list_first_entry(&tid->buf_q, struct ath_buf, list);
-               list_move_tail(&bf->list, &bf_head);
-
-               if (bf_isretried(bf))
-                       ath_tx_update_baw(sc, tid, bf->bf_seqno);
-
-               spin_unlock(&txq->axq_lock);
-               ath_tx_complete_buf(sc, bf, &bf_head, 0, 0);
-               spin_lock(&txq->axq_lock);
-       }
-
-       tid->seq_next = tid->seq_start;
-       tid->baw_tail = tid->baw_head;
-}
-
-static void ath_tx_set_retry(struct ath_softc *sc, struct ath_buf *bf)
-{
-       struct sk_buff *skb;
-       struct ieee80211_hdr *hdr;
-
-       bf->bf_state.bf_type |= BUF_RETRY;
-       bf->bf_retries++;
-
-       skb = bf->bf_mpdu;
-       hdr = (struct ieee80211_hdr *)skb->data;
-       hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_RETRY);
-}
-
-static struct ath_buf* ath_clone_txbuf(struct ath_softc *sc, struct ath_buf *bf)
-{
-       struct ath_buf *tbf;
-
-       spin_lock_bh(&sc->tx.txbuflock);
-       ASSERT(!list_empty((&sc->tx.txbuf)));
-       tbf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list);
-       list_del(&tbf->list);
-       spin_unlock_bh(&sc->tx.txbuflock);
-
-       ATH_TXBUF_RESET(tbf);
-
-       tbf->bf_mpdu = bf->bf_mpdu;
-       tbf->bf_buf_addr = bf->bf_buf_addr;
-       *(tbf->bf_desc) = *(bf->bf_desc);
-       tbf->bf_state = bf->bf_state;
-       tbf->bf_dmacontext = bf->bf_dmacontext;
-
-       return tbf;
-}
-
-static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
-                                struct ath_buf *bf, struct list_head *bf_q,
-                                int txok)
-{
-       struct ath_node *an = NULL;
-       struct sk_buff *skb;
-       struct ieee80211_sta *sta;
-       struct ieee80211_hdr *hdr;
-       struct ath_atx_tid *tid = NULL;
-       struct ath_buf *bf_next, *bf_last = bf->bf_lastbf;
-       struct ath_desc *ds = bf_last->bf_desc;
-       struct list_head bf_head, bf_pending;
-       u16 seq_st = 0, acked_cnt = 0, txfail_cnt = 0;
-       u32 ba[WME_BA_BMP_SIZE >> 5];
-       int isaggr, txfail, txpending, sendbar = 0, needreset = 0, nbad = 0;
-       bool rc_update = true;
-
-       skb = (struct sk_buff *)bf->bf_mpdu;
-       hdr = (struct ieee80211_hdr *)skb->data;
-
-       rcu_read_lock();
-
-       sta = ieee80211_find_sta(sc->hw, hdr->addr1);
-       if (!sta) {
-               rcu_read_unlock();
-               return;
-       }
-
-       an = (struct ath_node *)sta->drv_priv;
-       tid = ATH_AN_2_TID(an, bf->bf_tidno);
-
-       isaggr = bf_isaggr(bf);
-       memset(ba, 0, WME_BA_BMP_SIZE >> 3);
-
-       if (isaggr && txok) {
-               if (ATH_DS_TX_BA(ds)) {
-                       seq_st = ATH_DS_BA_SEQ(ds);
-                       memcpy(ba, ATH_DS_BA_BITMAP(ds),
-                              WME_BA_BMP_SIZE >> 3);
-               } else {
-                       /*
-                        * AR5416 can become deaf/mute when BA
-                        * issue happens. Chip needs to be reset.
-                        * But AP code may have sychronization issues
-                        * when perform internal reset in this routine.
-                        * Only enable reset in STA mode for now.
-                        */
-                       if (sc->sc_ah->opmode == NL80211_IFTYPE_STATION)
-                               needreset = 1;
-               }
-       }
-
-       INIT_LIST_HEAD(&bf_pending);
-       INIT_LIST_HEAD(&bf_head);
-
-       nbad = ath_tx_num_badfrms(sc, bf, txok);
-       while (bf) {
-               txfail = txpending = 0;
-               bf_next = bf->bf_next;
-
-               if (ATH_BA_ISSET(ba, ATH_BA_INDEX(seq_st, bf->bf_seqno))) {
-                       /* transmit completion, subframe is
-                        * acked by block ack */
-                       acked_cnt++;
-               } else if (!isaggr && txok) {
-                       /* transmit completion */
-                       acked_cnt++;
-               } else {
-                       if (!(tid->state & AGGR_CLEANUP) &&
-                           ds->ds_txstat.ts_flags != ATH9K_TX_SW_ABORTED) {
-                               if (bf->bf_retries < ATH_MAX_SW_RETRIES) {
-                                       ath_tx_set_retry(sc, bf);
-                                       txpending = 1;
-                               } else {
-                                       bf->bf_state.bf_type |= BUF_XRETRY;
-                                       txfail = 1;
-                                       sendbar = 1;
-                                       txfail_cnt++;
-                               }
-                       } else {
-                               /*
-                                * cleanup in progress, just fail
-                                * the un-acked sub-frames
-                                */
-                               txfail = 1;
-                       }
-               }
-
-               if (bf_next == NULL) {
-                       INIT_LIST_HEAD(&bf_head);
-               } else {
-                       ASSERT(!list_empty(bf_q));
-                       list_move_tail(&bf->list, &bf_head);
-               }
-
-               if (!txpending) {
-                       /*
-                        * complete the acked-ones/xretried ones; update
-                        * block-ack window
-                        */
-                       spin_lock_bh(&txq->axq_lock);
-                       ath_tx_update_baw(sc, tid, bf->bf_seqno);
-                       spin_unlock_bh(&txq->axq_lock);
-
-                       if (rc_update && (acked_cnt == 1 || txfail_cnt == 1)) {
-                               ath_tx_rc_status(bf, ds, nbad, txok, true);
-                               rc_update = false;
-                       } else {
-                               ath_tx_rc_status(bf, ds, nbad, txok, false);
-                       }
-
-                       ath_tx_complete_buf(sc, bf, &bf_head, !txfail, sendbar);
-               } else {
-                       /* retry the un-acked ones */
-                       if (bf->bf_next == NULL &&
-                           bf_last->bf_status & ATH_BUFSTATUS_STALE) {
-                               struct ath_buf *tbf;
-
-                               tbf = ath_clone_txbuf(sc, bf_last);
-                               ath9k_hw_cleartxdesc(sc->sc_ah, tbf->bf_desc);
-                               list_add_tail(&tbf->list, &bf_head);
-                       } else {
-                               /*
-                                * Clear descriptor status words for
-                                * software retry
-                                */
-                               ath9k_hw_cleartxdesc(sc->sc_ah, bf->bf_desc);
-                       }
-
-                       /*
-                        * Put this buffer to the temporary pending
-                        * queue to retain ordering
-                        */
-                       list_splice_tail_init(&bf_head, &bf_pending);
-               }
-
-               bf = bf_next;
-       }
-
-       if (tid->state & AGGR_CLEANUP) {
-               if (tid->baw_head == tid->baw_tail) {
-                       tid->state &= ~AGGR_ADDBA_COMPLETE;
-                       tid->addba_exchangeattempts = 0;
-                       tid->state &= ~AGGR_CLEANUP;
-
-                       /* send buffered frames as singles */
-                       ath_tx_flush_tid(sc, tid);
-               }
-               rcu_read_unlock();
-               return;
-       }
-
-       /* prepend un-acked frames to the beginning of the pending frame queue */
-       if (!list_empty(&bf_pending)) {
-               spin_lock_bh(&txq->axq_lock);
-               list_splice(&bf_pending, &tid->buf_q);
-               ath_tx_queue_tid(txq, tid);
-               spin_unlock_bh(&txq->axq_lock);
-       }
-
-       rcu_read_unlock();
-
-       if (needreset)
-               ath_reset(sc, false);
-}
-
-static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf,
-                          struct ath_atx_tid *tid)
-{
-       struct ath_rate_table *rate_table = sc->cur_rate_table;
-       struct sk_buff *skb;
-       struct ieee80211_tx_info *tx_info;
-       struct ieee80211_tx_rate *rates;
-       struct ath_tx_info_priv *tx_info_priv;
-       u32 max_4ms_framelen, frmlen;
-       u16 aggr_limit, legacy = 0, maxampdu;
-       int i;
-
-       skb = (struct sk_buff *)bf->bf_mpdu;
-       tx_info = IEEE80211_SKB_CB(skb);
-       rates = tx_info->control.rates;
-       tx_info_priv = (struct ath_tx_info_priv *)tx_info->rate_driver_data[0];
-
-       /*
-        * Find the lowest frame length among the rate series that will have a
-        * 4ms transmit duration.
-        * TODO - TXOP limit needs to be considered.
-        */
-       max_4ms_framelen = ATH_AMPDU_LIMIT_MAX;
-
-       for (i = 0; i < 4; i++) {
-               if (rates[i].count) {
-                       if (!WLAN_RC_PHY_HT(rate_table->info[rates[i].idx].phy)) {
-                               legacy = 1;
-                               break;
-                       }
-
-                       frmlen = rate_table->info[rates[i].idx].max_4ms_framelen;
-                       max_4ms_framelen = min(max_4ms_framelen, frmlen);
-               }
-       }
-
-       /*
-        * limit aggregate size by the minimum rate if rate selected is
-        * not a probe rate, if rate selected is a probe rate then
-        * avoid aggregation of this packet.
-        */
-       if (tx_info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE || legacy)
-               return 0;
-
-       aggr_limit = min(max_4ms_framelen, (u32)ATH_AMPDU_LIMIT_DEFAULT);
-
-       /*
-        * h/w can accept aggregates upto 16 bit lengths (65535).
-        * The IE, however can hold upto 65536, which shows up here
-        * as zero. Ignore 65536 since we  are constrained by hw.
-        */
-       maxampdu = tid->an->maxampdu;
-       if (maxampdu)
-               aggr_limit = min(aggr_limit, maxampdu);
-
-       return aggr_limit;
-}
-
-/*
- * Returns the number of delimiters to be added to
- * meet the minimum required mpdudensity.
- * caller should make sure that the rate is HT rate .
- */
-static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid,
-                                 struct ath_buf *bf, u16 frmlen)
-{
-       struct ath_rate_table *rt = sc->cur_rate_table;
-       struct sk_buff *skb = bf->bf_mpdu;
-       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
-       u32 nsymbits, nsymbols, mpdudensity;
-       u16 minlen;
-       u8 rc, flags, rix;
-       int width, half_gi, ndelim, mindelim;
-
-       /* Select standard number of delimiters based on frame length alone */
-       ndelim = ATH_AGGR_GET_NDELIM(frmlen);
-
-       /*
-        * If encryption enabled, hardware requires some more padding between
-        * subframes.
-        * TODO - this could be improved to be dependent on the rate.
-        *      The hardware can keep up at lower rates, but not higher rates
-        */
-       if (bf->bf_keytype != ATH9K_KEY_TYPE_CLEAR)
-               ndelim += ATH_AGGR_ENCRYPTDELIM;
-
-       /*
-        * Convert desired mpdu density from microeconds to bytes based
-        * on highest rate in rate series (i.e. first rate) to determine
-        * required minimum length for subframe. Take into account
-        * whether high rate is 20 or 40Mhz and half or full GI.
-        */
-       mpdudensity = tid->an->mpdudensity;
-
-       /*
-        * If there is no mpdu density restriction, no further calculation
-        * is needed.
-        */
-       if (mpdudensity == 0)
-               return ndelim;
-
-       rix = tx_info->control.rates[0].idx;
-       flags = tx_info->control.rates[0].flags;
-       rc = rt->info[rix].ratecode;
-       width = (flags & IEEE80211_TX_RC_40_MHZ_WIDTH) ? 1 : 0;
-       half_gi = (flags & IEEE80211_TX_RC_SHORT_GI) ? 1 : 0;
-
-       if (half_gi)
-               nsymbols = NUM_SYMBOLS_PER_USEC_HALFGI(mpdudensity);
-       else
-               nsymbols = NUM_SYMBOLS_PER_USEC(mpdudensity);
-
-       if (nsymbols == 0)
-               nsymbols = 1;
-
-       nsymbits = bits_per_symbol[HT_RC_2_MCS(rc)][width];
-       minlen = (nsymbols * nsymbits) / BITS_PER_BYTE;
-
-       if (frmlen < minlen) {
-               mindelim = (minlen - frmlen) / ATH_AGGR_DELIM_SZ;
-               ndelim = max(mindelim, ndelim);
-       }
-
-       return ndelim;
-}
-
-static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
-                                            struct ath_atx_tid *tid,
-                                            struct list_head *bf_q)
-{
-#define PADBYTES(_len) ((4 - ((_len) % 4)) % 4)
-       struct ath_buf *bf, *bf_first, *bf_prev = NULL;
-       int rl = 0, nframes = 0, ndelim, prev_al = 0;
-       u16 aggr_limit = 0, al = 0, bpad = 0,
-               al_delta, h_baw = tid->baw_size / 2;
-       enum ATH_AGGR_STATUS status = ATH_AGGR_DONE;
-
-       bf_first = list_first_entry(&tid->buf_q, struct ath_buf, list);
-
-       do {
-               bf = list_first_entry(&tid->buf_q, struct ath_buf, list);
-
-               /* do not step over block-ack window */
-               if (!BAW_WITHIN(tid->seq_start, tid->baw_size, bf->bf_seqno)) {
-                       status = ATH_AGGR_BAW_CLOSED;
-                       break;
-               }
-
-               if (!rl) {
-                       aggr_limit = ath_lookup_rate(sc, bf, tid);
-                       rl = 1;
-               }
-
-               /* do not exceed aggregation limit */
-               al_delta = ATH_AGGR_DELIM_SZ + bf->bf_frmlen;
-
-               if (nframes &&
-                   (aggr_limit < (al + bpad + al_delta + prev_al))) {
-                       status = ATH_AGGR_LIMITED;
-                       break;
-               }
-
-               /* do not exceed subframe limit */
-               if (nframes >= min((int)h_baw, ATH_AMPDU_SUBFRAME_DEFAULT)) {
-                       status = ATH_AGGR_LIMITED;
-                       break;
-               }
-               nframes++;
-
-               /* add padding for previous frame to aggregation length */
-               al += bpad + al_delta;
-
-               /*
-                * Get the delimiters needed to meet the MPDU
-                * density for this node.
-                */
-               ndelim = ath_compute_num_delims(sc, tid, bf_first, bf->bf_frmlen);
-               bpad = PADBYTES(al_delta) + (ndelim << 2);
-
-               bf->bf_next = NULL;
-               bf->bf_desc->ds_link = 0;
-
-               /* link buffers of this frame to the aggregate */
-               ath_tx_addto_baw(sc, tid, bf);
-               ath9k_hw_set11n_aggr_middle(sc->sc_ah, bf->bf_desc, ndelim);
-               list_move_tail(&bf->list, bf_q);
-               if (bf_prev) {
-                       bf_prev->bf_next = bf;
-                       bf_prev->bf_desc->ds_link = bf->bf_daddr;
-               }
-               bf_prev = bf;
-       } while (!list_empty(&tid->buf_q));
-
-       bf_first->bf_al = al;
-       bf_first->bf_nframes = nframes;
-
-       return status;
-#undef PADBYTES
-}
-
-static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq,
-                             struct ath_atx_tid *tid)
-{
-       struct ath_buf *bf;
-       enum ATH_AGGR_STATUS status;
-       struct list_head bf_q;
-
-       do {
-               if (list_empty(&tid->buf_q))
-                       return;
-
-               INIT_LIST_HEAD(&bf_q);
-
-               status = ath_tx_form_aggr(sc, tid, &bf_q);
-
-               /*
-                * no frames picked up to be aggregated;
-                * block-ack window is not open.
-                */
-               if (list_empty(&bf_q))
-                       break;
-
-               bf = list_first_entry(&bf_q, struct ath_buf, list);
-               bf->bf_lastbf = list_entry(bf_q.prev, struct ath_buf, list);
-
-               /* if only one frame, send as non-aggregate */
-               if (bf->bf_nframes == 1) {
-                       bf->bf_state.bf_type &= ~BUF_AGGR;
-                       ath9k_hw_clr11n_aggr(sc->sc_ah, bf->bf_desc);
-                       ath_buf_set_rate(sc, bf);
-                       ath_tx_txqaddbuf(sc, txq, &bf_q);
-                       continue;
-               }
-
-               /* setup first desc of aggregate */
-               bf->bf_state.bf_type |= BUF_AGGR;
-               ath_buf_set_rate(sc, bf);
-               ath9k_hw_set11n_aggr_first(sc->sc_ah, bf->bf_desc, bf->bf_al);
-
-               /* anchor last desc of aggregate */
-               ath9k_hw_set11n_aggr_last(sc->sc_ah, bf->bf_lastbf->bf_desc);
-
-               txq->axq_aggr_depth++;
-               ath_tx_txqaddbuf(sc, txq, &bf_q);
-
-       } while (txq->axq_depth < ATH_AGGR_MIN_QDEPTH &&
-                status != ATH_AGGR_BAW_CLOSED);
-}
-
-int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
-                     u16 tid, u16 *ssn)
-{
-       struct ath_atx_tid *txtid;
-       struct ath_node *an;
-
-       an = (struct ath_node *)sta->drv_priv;
-
-       if (sc->sc_flags & SC_OP_TXAGGR) {
-               txtid = ATH_AN_2_TID(an, tid);
-               txtid->state |= AGGR_ADDBA_PROGRESS;
-               ath_tx_pause_tid(sc, txtid);
-               *ssn = txtid->seq_start;
-       }
-
-       return 0;
-}
-
-int ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
-{
-       struct ath_node *an = (struct ath_node *)sta->drv_priv;
-       struct ath_atx_tid *txtid = ATH_AN_2_TID(an, tid);
-       struct ath_txq *txq = &sc->tx.txq[txtid->ac->qnum];
-       struct ath_buf *bf;
-       struct list_head bf_head;
-       INIT_LIST_HEAD(&bf_head);
-
-       if (txtid->state & AGGR_CLEANUP)
-               return 0;
-
-       if (!(txtid->state & AGGR_ADDBA_COMPLETE)) {
-               txtid->addba_exchangeattempts = 0;
-               return 0;
-       }
-
-       ath_tx_pause_tid(sc, txtid);
-
-       /* drop all software retried frames and mark this TID */
-       spin_lock_bh(&txq->axq_lock);
-       while (!list_empty(&txtid->buf_q)) {
-               bf = list_first_entry(&txtid->buf_q, struct ath_buf, list);
-               if (!bf_isretried(bf)) {
-                       /*
-                        * NB: it's based on the assumption that
-                        * software retried frame will always stay
-                        * at the head of software queue.
-                        */
-                       break;
-               }
-               list_move_tail(&bf->list, &bf_head);
-               ath_tx_update_baw(sc, txtid, bf->bf_seqno);
-               ath_tx_complete_buf(sc, bf, &bf_head, 0, 0);
-       }
-       spin_unlock_bh(&txq->axq_lock);
-
-       if (txtid->baw_head != txtid->baw_tail) {
-               txtid->state |= AGGR_CLEANUP;
-       } else {
-               txtid->state &= ~AGGR_ADDBA_COMPLETE;
-               txtid->addba_exchangeattempts = 0;
-               ath_tx_flush_tid(sc, txtid);
-       }
-
-       return 0;
-}
-
-void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
-{
-       struct ath_atx_tid *txtid;
-       struct ath_node *an;
-
-       an = (struct ath_node *)sta->drv_priv;
-
-       if (sc->sc_flags & SC_OP_TXAGGR) {
-               txtid = ATH_AN_2_TID(an, tid);
-               txtid->baw_size =
-                       IEEE80211_MIN_AMPDU_BUF << sta->ht_cap.ampdu_factor;
-               txtid->state |= AGGR_ADDBA_COMPLETE;
-               txtid->state &= ~AGGR_ADDBA_PROGRESS;
-               ath_tx_resume_tid(sc, txtid);
-       }
-}
-
-bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, u8 tidno)
-{
-       struct ath_atx_tid *txtid;
-
-       if (!(sc->sc_flags & SC_OP_TXAGGR))
-               return false;
-
-       txtid = ATH_AN_2_TID(an, tidno);
-
-       if (!(txtid->state & AGGR_ADDBA_COMPLETE)) {
-               if (!(txtid->state & AGGR_ADDBA_PROGRESS) &&
-                   (txtid->addba_exchangeattempts < ADDBA_EXCHANGE_ATTEMPTS)) {
-                       txtid->addba_exchangeattempts++;
-                       return true;
-               }
-       }
-
-       return false;
-}
-
-/********************/
-/* Queue Management */
-/********************/
-
-static void ath_txq_drain_pending_buffers(struct ath_softc *sc,
-                                         struct ath_txq *txq)
-{
-       struct ath_atx_ac *ac, *ac_tmp;
-       struct ath_atx_tid *tid, *tid_tmp;
-
-       list_for_each_entry_safe(ac, ac_tmp, &txq->axq_acq, list) {
-               list_del(&ac->list);
-               ac->sched = false;
-               list_for_each_entry_safe(tid, tid_tmp, &ac->tid_q, list) {
-                       list_del(&tid->list);
-                       tid->sched = false;
-                       ath_tid_drain(sc, txq, tid);
-               }
-       }
-}
-
-struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
-{
-       struct ath_hw *ah = sc->sc_ah;
-       struct ath9k_tx_queue_info qi;
-       int qnum;
-
-       memset(&qi, 0, sizeof(qi));
-       qi.tqi_subtype = subtype;
-       qi.tqi_aifs = ATH9K_TXQ_USEDEFAULT;
-       qi.tqi_cwmin = ATH9K_TXQ_USEDEFAULT;
-       qi.tqi_cwmax = ATH9K_TXQ_USEDEFAULT;
-       qi.tqi_physCompBuf = 0;
-
-       /*
-        * Enable interrupts only for EOL and DESC conditions.
-        * We mark tx descriptors to receive a DESC interrupt
-        * when a tx queue gets deep; otherwise waiting for the
-        * EOL to reap descriptors.  Note that this is done to
-        * reduce interrupt load and this only defers reaping
-        * descriptors, never transmitting frames.  Aside from
-        * reducing interrupts this also permits more concurrency.
-        * The only potential downside is if the tx queue backs
-        * up in which case the top half of the kernel may backup
-        * due to a lack of tx descriptors.
-        *
-        * The UAPSD queue is an exception, since we take a desc-
-        * based intr on the EOSP frames.
-        */
-       if (qtype == ATH9K_TX_QUEUE_UAPSD)
-               qi.tqi_qflags = TXQ_FLAG_TXDESCINT_ENABLE;
-       else
-               qi.tqi_qflags = TXQ_FLAG_TXEOLINT_ENABLE |
-                       TXQ_FLAG_TXDESCINT_ENABLE;
-       qnum = ath9k_hw_setuptxqueue(ah, qtype, &qi);
-       if (qnum == -1) {
-               /*
-                * NB: don't print a message, this happens
-                * normally on parts with too few tx queues
-                */
-               return NULL;
-       }
-       if (qnum >= ARRAY_SIZE(sc->tx.txq)) {
-               DPRINTF(sc, ATH_DBG_FATAL,
-                       "qnum %u out of range, max %u!\n",
-                       qnum, (unsigned int)ARRAY_SIZE(sc->tx.txq));
-               ath9k_hw_releasetxqueue(ah, qnum);
-               return NULL;
-       }
-       if (!ATH_TXQ_SETUP(sc, qnum)) {
-               struct ath_txq *txq = &sc->tx.txq[qnum];
-
-               txq->axq_qnum = qnum;
-               txq->axq_link = NULL;
-               INIT_LIST_HEAD(&txq->axq_q);
-               INIT_LIST_HEAD(&txq->axq_acq);
-               spin_lock_init(&txq->axq_lock);
-               txq->axq_depth = 0;
-               txq->axq_aggr_depth = 0;
-               txq->axq_totalqueued = 0;
-               txq->axq_linkbuf = NULL;
-               sc->tx.txqsetup |= 1<<qnum;
-       }
-       return &sc->tx.txq[qnum];
-}
-
-static int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype)
-{
-       int qnum;
-
-       switch (qtype) {
-       case ATH9K_TX_QUEUE_DATA:
-               if (haltype >= ARRAY_SIZE(sc->tx.hwq_map)) {
-                       DPRINTF(sc, ATH_DBG_FATAL,
-                               "HAL AC %u out of range, max %zu!\n",
-                               haltype, ARRAY_SIZE(sc->tx.hwq_map));
-                       return -1;
-               }
-               qnum = sc->tx.hwq_map[haltype];
-               break;
-       case ATH9K_TX_QUEUE_BEACON:
-               qnum = sc->beacon.beaconq;
-               break;
-       case ATH9K_TX_QUEUE_CAB:
-               qnum = sc->beacon.cabq->axq_qnum;
-               break;
-       default:
-               qnum = -1;
-       }
-       return qnum;
-}
-
-struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb)
-{
-       struct ath_txq *txq = NULL;
-       int qnum;
-
-       qnum = ath_get_hal_qnum(skb_get_queue_mapping(skb), sc);
-       txq = &sc->tx.txq[qnum];
-
-       spin_lock_bh(&txq->axq_lock);
-
-       if (txq->axq_depth >= (ATH_TXBUF - 20)) {
-               DPRINTF(sc, ATH_DBG_XMIT,
-                       "TX queue: %d is full, depth: %d\n",
-                       qnum, txq->axq_depth);
-               ieee80211_stop_queue(sc->hw, skb_get_queue_mapping(skb));
-               txq->stopped = 1;
-               spin_unlock_bh(&txq->axq_lock);
-               return NULL;
-       }
-
-       spin_unlock_bh(&txq->axq_lock);
-
-       return txq;
-}
-
-int ath_txq_update(struct ath_softc *sc, int qnum,
-                  struct ath9k_tx_queue_info *qinfo)
-{
-       struct ath_hw *ah = sc->sc_ah;
-       int error = 0;
-       struct ath9k_tx_queue_info qi;
-
-       if (qnum == sc->beacon.beaconq) {
-               /*
-                * XXX: for beacon queue, we just save the parameter.
-                * It will be picked up by ath_beaconq_config when
-                * it's necessary.
-                */
-               sc->beacon.beacon_qi = *qinfo;
-               return 0;
-       }
-
-       ASSERT(sc->tx.txq[qnum].axq_qnum == qnum);
-
-       ath9k_hw_get_txq_props(ah, qnum, &qi);
-       qi.tqi_aifs = qinfo->tqi_aifs;
-       qi.tqi_cwmin = qinfo->tqi_cwmin;
-       qi.tqi_cwmax = qinfo->tqi_cwmax;
-       qi.tqi_burstTime = qinfo->tqi_burstTime;
-       qi.tqi_readyTime = qinfo->tqi_readyTime;
-
-       if (!ath9k_hw_set_txq_props(ah, qnum, &qi)) {
-               DPRINTF(sc, ATH_DBG_FATAL,
-                       "Unable to update hardware queue %u!\n", qnum);
-               error = -EIO;
-       } else {
-               ath9k_hw_resettxqueue(ah, qnum);
-       }
-
-       return error;
-}
-
-int ath_cabq_update(struct ath_softc *sc)
-{
-       struct ath9k_tx_queue_info qi;
-       int qnum = sc->beacon.cabq->axq_qnum;
-
-       ath9k_hw_get_txq_props(sc->sc_ah, qnum, &qi);
-       /*
-        * Ensure the readytime % is within the bounds.
-        */
-       if (sc->config.cabqReadytime < ATH9K_READY_TIME_LO_BOUND)
-               sc->config.cabqReadytime = ATH9K_READY_TIME_LO_BOUND;
-       else if (sc->config.cabqReadytime > ATH9K_READY_TIME_HI_BOUND)
-               sc->config.cabqReadytime = ATH9K_READY_TIME_HI_BOUND;
-
-       qi.tqi_readyTime = (sc->hw->conf.beacon_int *
-                           sc->config.cabqReadytime) / 100;
-       ath_txq_update(sc, qnum, &qi);
-
-       return 0;
-}
-
-/*
- * Drain a given TX queue (could be Beacon or Data)
- *
- * This assumes output has been stopped and
- * we do not need to block ath_tx_tasklet.
- */
-void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx)
-{
-       struct ath_buf *bf, *lastbf;
-       struct list_head bf_head;
-
-       INIT_LIST_HEAD(&bf_head);
-
-       for (;;) {
-               spin_lock_bh(&txq->axq_lock);
-
-               if (list_empty(&txq->axq_q)) {
-                       txq->axq_link = NULL;
-                       txq->axq_linkbuf = NULL;
-                       spin_unlock_bh(&txq->axq_lock);
-                       break;
-               }
-
-               bf = list_first_entry(&txq->axq_q, struct ath_buf, list);
-
-               if (bf->bf_status & ATH_BUFSTATUS_STALE) {
-                       list_del(&bf->list);
-                       spin_unlock_bh(&txq->axq_lock);
-
-                       spin_lock_bh(&sc->tx.txbuflock);
-                       list_add_tail(&bf->list, &sc->tx.txbuf);
-                       spin_unlock_bh(&sc->tx.txbuflock);
-                       continue;
-               }
-
-               lastbf = bf->bf_lastbf;
-               if (!retry_tx)
-                       lastbf->bf_desc->ds_txstat.ts_flags =
-                               ATH9K_TX_SW_ABORTED;
-
-               /* remove ath_buf's of the same mpdu from txq */
-               list_cut_position(&bf_head, &txq->axq_q, &lastbf->list);
-               txq->axq_depth--;
-
-               spin_unlock_bh(&txq->axq_lock);
-
-               if (bf_isampdu(bf))
-                       ath_tx_complete_aggr(sc, txq, bf, &bf_head, 0);
-               else
-                       ath_tx_complete_buf(sc, bf, &bf_head, 0, 0);
-       }
-
-       /* flush any pending frames if aggregation is enabled */
-       if (sc->sc_flags & SC_OP_TXAGGR) {
-               if (!retry_tx) {
-                       spin_lock_bh(&txq->axq_lock);
-                       ath_txq_drain_pending_buffers(sc, txq);
-                       spin_unlock_bh(&txq->axq_lock);
-               }
-       }
-}
-
-void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx)
-{
-       struct ath_hw *ah = sc->sc_ah;
-       struct ath_txq *txq;
-       int i, npend = 0;
-
-       if (sc->sc_flags & SC_OP_INVALID)
-               return;
-
-       /* Stop beacon queue */
-       ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
-
-       /* Stop data queues */
-       for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
-               if (ATH_TXQ_SETUP(sc, i)) {
-                       txq = &sc->tx.txq[i];
-                       ath9k_hw_stoptxdma(ah, txq->axq_qnum);
-                       npend += ath9k_hw_numtxpending(ah, txq->axq_qnum);
-               }
-       }
-
-       if (npend) {
-               int r;
-
-               DPRINTF(sc, ATH_DBG_XMIT, "Unable to stop TxDMA. Reset HAL!\n");
-
-               spin_lock_bh(&sc->sc_resetlock);
-               r = ath9k_hw_reset(ah, sc->sc_ah->curchan, true);
-               if (r)
-                       DPRINTF(sc, ATH_DBG_FATAL,
-                               "Unable to reset hardware; reset status %u\n",
-                               r);
-               spin_unlock_bh(&sc->sc_resetlock);
-       }
-
-       for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
-               if (ATH_TXQ_SETUP(sc, i))
-                       ath_draintxq(sc, &sc->tx.txq[i], retry_tx);
-       }
-}
-
-void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq)
-{
-       ath9k_hw_releasetxqueue(sc->sc_ah, txq->axq_qnum);
-       sc->tx.txqsetup &= ~(1<<txq->axq_qnum);
-}
-
-void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
-{
-       struct ath_atx_ac *ac;
-       struct ath_atx_tid *tid;
-
-       if (list_empty(&txq->axq_acq))
-               return;
-
-       ac = list_first_entry(&txq->axq_acq, struct ath_atx_ac, list);
-       list_del(&ac->list);
-       ac->sched = false;
-
-       do {
-               if (list_empty(&ac->tid_q))
-                       return;
-
-               tid = list_first_entry(&ac->tid_q, struct ath_atx_tid, list);
-               list_del(&tid->list);
-               tid->sched = false;
-
-               if (tid->paused)
-                       continue;
-
-               if ((txq->axq_depth % 2) == 0)
-                       ath_tx_sched_aggr(sc, txq, tid);
-
-               /*
-                * add tid to round-robin queue if more frames
-                * are pending for the tid
-                */
-               if (!list_empty(&tid->buf_q))
-                       ath_tx_queue_tid(txq, tid);
-
-               break;
-       } while (!list_empty(&ac->tid_q));
-
-       if (!list_empty(&ac->tid_q)) {
-               if (!ac->sched) {
-                       ac->sched = true;
-                       list_add_tail(&ac->list, &txq->axq_acq);
-               }
-       }
-}
-
-int ath_tx_setup(struct ath_softc *sc, int haltype)
-{
-       struct ath_txq *txq;
-
-       if (haltype >= ARRAY_SIZE(sc->tx.hwq_map)) {
-               DPRINTF(sc, ATH_DBG_FATAL,
-                       "HAL AC %u out of range, max %zu!\n",
-                        haltype, ARRAY_SIZE(sc->tx.hwq_map));
-               return 0;
-       }
-       txq = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, haltype);
-       if (txq != NULL) {
-               sc->tx.hwq_map[haltype] = txq->axq_qnum;
-               return 1;
-       } else
-               return 0;
-}
-
-/***********/
-/* TX, DMA */
-/***********/
-
-/*
- * Insert a chain of ath_buf (descriptors) on a txq and
- * assume the descriptors are already chained together by caller.
- */
-static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
-                            struct list_head *head)
-{
-       struct ath_hw *ah = sc->sc_ah;
-       struct ath_buf *bf;
-
-       /*
-        * Insert the frame on the outbound list and
-        * pass it on to the hardware.
-        */
-
-       if (list_empty(head))
-               return;
-
-       bf = list_first_entry(head, struct ath_buf, list);
-
-       list_splice_tail_init(head, &txq->axq_q);
-       txq->axq_depth++;
-       txq->axq_totalqueued++;
-       txq->axq_linkbuf = list_entry(txq->axq_q.prev, struct ath_buf, list);
-
-       DPRINTF(sc, ATH_DBG_QUEUE,
-               "qnum: %d, txq depth: %d\n", txq->axq_qnum, txq->axq_depth);
-
-       if (txq->axq_link == NULL) {
-               ath9k_hw_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr);
-               DPRINTF(sc, ATH_DBG_XMIT,
-                       "TXDP[%u] = %llx (%p)\n",
-                       txq->axq_qnum, ito64(bf->bf_daddr), bf->bf_desc);
-       } else {
-               *txq->axq_link = bf->bf_daddr;
-               DPRINTF(sc, ATH_DBG_XMIT, "link[%u] (%p)=%llx (%p)\n",
-                       txq->axq_qnum, txq->axq_link,
-                       ito64(bf->bf_daddr), bf->bf_desc);
-       }
-       txq->axq_link = &(bf->bf_lastbf->bf_desc->ds_link);
-       ath9k_hw_txstart(ah, txq->axq_qnum);
-}
-
-static struct ath_buf *ath_tx_get_buffer(struct ath_softc *sc)
-{
-       struct ath_buf *bf = NULL;
-
-       spin_lock_bh(&sc->tx.txbuflock);
-
-       if (unlikely(list_empty(&sc->tx.txbuf))) {
-               spin_unlock_bh(&sc->tx.txbuflock);
-               return NULL;
-       }
-
-       bf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list);
-       list_del(&bf->list);
-
-       spin_unlock_bh(&sc->tx.txbuflock);
-
-       return bf;
-}
-
-static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid,
-                             struct list_head *bf_head,
-                             struct ath_tx_control *txctl)
-{
-       struct ath_buf *bf;
-
-       bf = list_first_entry(bf_head, struct ath_buf, list);
-       bf->bf_state.bf_type |= BUF_AMPDU;
-
-       /*
-        * Do not queue to h/w when any of the following conditions is true:
-        * - there are pending frames in software queue
-        * - the TID is currently paused for ADDBA/BAR request
-        * - seqno is not within block-ack window
-        * - h/w queue depth exceeds low water mark
-        */
-       if (!list_empty(&tid->buf_q) || tid->paused ||
-           !BAW_WITHIN(tid->seq_start, tid->baw_size, bf->bf_seqno) ||
-           txctl->txq->axq_depth >= ATH_AGGR_MIN_QDEPTH) {
-               /*
-                * Add this frame to software queue for scheduling later
-                * for aggregation.
-                */
-               list_move_tail(&bf->list, &tid->buf_q);
-               ath_tx_queue_tid(txctl->txq, tid);
-               return;
-       }
-
-       /* Add sub-frame to BAW */
-       ath_tx_addto_baw(sc, tid, bf);
-
-       /* Queue to h/w without aggregation */
-       bf->bf_nframes = 1;
-       bf->bf_lastbf = bf;
-       ath_buf_set_rate(sc, bf);
-       ath_tx_txqaddbuf(sc, txctl->txq, bf_head);
-}
-
-static void ath_tx_send_ht_normal(struct ath_softc *sc, struct ath_txq *txq,
-                                 struct ath_atx_tid *tid,
-                                 struct list_head *bf_head)
-{
-       struct ath_buf *bf;
-
-       bf = list_first_entry(bf_head, struct ath_buf, list);
-       bf->bf_state.bf_type &= ~BUF_AMPDU;
-
-       /* update starting sequence number for subsequent ADDBA request */
-       INCR(tid->seq_start, IEEE80211_SEQ_MAX);
-
-       bf->bf_nframes = 1;
-       bf->bf_lastbf = bf;
-       ath_buf_set_rate(sc, bf);
-       ath_tx_txqaddbuf(sc, txq, bf_head);
-}
-
-static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq,
-                              struct list_head *bf_head)
-{
-       struct ath_buf *bf;
-
-       bf = list_first_entry(bf_head, struct ath_buf, list);
-
-       bf->bf_lastbf = bf;
-       bf->bf_nframes = 1;
-       ath_buf_set_rate(sc, bf);
-       ath_tx_txqaddbuf(sc, txq, bf_head);
-}
-
-static enum ath9k_pkt_type get_hw_packet_type(struct sk_buff *skb)
-{
-       struct ieee80211_hdr *hdr;
-       enum ath9k_pkt_type htype;
-       __le16 fc;
-
-       hdr = (struct ieee80211_hdr *)skb->data;
-       fc = hdr->frame_control;
-
-       if (ieee80211_is_beacon(fc))
-               htype = ATH9K_PKT_TYPE_BEACON;
-       else if (ieee80211_is_probe_resp(fc))
-               htype = ATH9K_PKT_TYPE_PROBE_RESP;
-       else if (ieee80211_is_atim(fc))
-               htype = ATH9K_PKT_TYPE_ATIM;
-       else if (ieee80211_is_pspoll(fc))
-               htype = ATH9K_PKT_TYPE_PSPOLL;
-       else
-               htype = ATH9K_PKT_TYPE_NORMAL;
-
-       return htype;
-}
-
-static bool is_pae(struct sk_buff *skb)
-{
-       struct ieee80211_hdr *hdr;
-       __le16 fc;
-
-       hdr = (struct ieee80211_hdr *)skb->data;
-       fc = hdr->frame_control;
-
-       if (ieee80211_is_data(fc)) {
-               if (ieee80211_is_nullfunc(fc) ||
-                   /* Port Access Entity (IEEE 802.1X) */
-                   (skb->protocol == cpu_to_be16(ETH_P_PAE))) {
-                       return true;
-               }
-       }
-
-       return false;
-}
-
-static int get_hw_crypto_keytype(struct sk_buff *skb)
-{
-       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
-
-       if (tx_info->control.hw_key) {
-               if (tx_info->control.hw_key->alg == ALG_WEP)
-                       return ATH9K_KEY_TYPE_WEP;
-               else if (tx_info->control.hw_key->alg == ALG_TKIP)
-                       return ATH9K_KEY_TYPE_TKIP;
-               else if (tx_info->control.hw_key->alg == ALG_CCMP)
-                       return ATH9K_KEY_TYPE_AES;
-       }
-
-       return ATH9K_KEY_TYPE_CLEAR;
-}
-
-static void assign_aggr_tid_seqno(struct sk_buff *skb,
-                                 struct ath_buf *bf)
-{
-       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
-       struct ieee80211_hdr *hdr;
-       struct ath_node *an;
-       struct ath_atx_tid *tid;
-       __le16 fc;
-       u8 *qc;
-
-       if (!tx_info->control.sta)
-               return;
-
-       an = (struct ath_node *)tx_info->control.sta->drv_priv;
-       hdr = (struct ieee80211_hdr *)skb->data;
-       fc = hdr->frame_control;
-
-       if (ieee80211_is_data_qos(fc)) {
-               qc = ieee80211_get_qos_ctl(hdr);
-               bf->bf_tidno = qc[0] & 0xf;
-       }
-
-       /*
-        * For HT capable stations, we save tidno for later use.
-        * We also override seqno set by upper layer with the one
-        * in tx aggregation state.
-        *
-        * If fragmentation is on, the sequence number is
-        * not overridden, since it has been
-        * incremented by the fragmentation routine.
-        *
-        * FIXME: check if the fragmentation threshold exceeds
-        * IEEE80211 max.
-        */
-       tid = ATH_AN_2_TID(an, bf->bf_tidno);
-       hdr->seq_ctrl = cpu_to_le16(tid->seq_next <<
-                       IEEE80211_SEQ_SEQ_SHIFT);
-       bf->bf_seqno = tid->seq_next;
-       INCR(tid->seq_next, IEEE80211_SEQ_MAX);
-}
-
-static int setup_tx_flags(struct ath_softc *sc, struct sk_buff *skb,
-                         struct ath_txq *txq)
-{
-       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
-       int flags = 0;
-
-       flags |= ATH9K_TXDESC_CLRDMASK; /* needed for crypto errors */
-       flags |= ATH9K_TXDESC_INTREQ;
-
-       if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK)
-               flags |= ATH9K_TXDESC_NOACK;
-
-       return flags;
-}
-
-/*
- * rix - rate index
- * pktlen - total bytes (delims + data + fcs + pads + pad delims)
- * width  - 0 for 20 MHz, 1 for 40 MHz
- * half_gi - to use 4us v/s 3.6 us for symbol time
- */
-static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, struct ath_buf *bf,
-                           int width, int half_gi, bool shortPreamble)
-{
-       struct ath_rate_table *rate_table = sc->cur_rate_table;
-       u32 nbits, nsymbits, duration, nsymbols;
-       u8 rc;
-       int streams, pktlen;
-
-       pktlen = bf_isaggr(bf) ? bf->bf_al : bf->bf_frmlen;
-       rc = rate_table->info[rix].ratecode;
-
-       /* for legacy rates, use old function to compute packet duration */
-       if (!IS_HT_RATE(rc))
-               return ath9k_hw_computetxtime(sc->sc_ah, rate_table, pktlen,
-                                             rix, shortPreamble);
-
-       /* find number of symbols: PLCP + data */
-       nbits = (pktlen << 3) + OFDM_PLCP_BITS;
-       nsymbits = bits_per_symbol[HT_RC_2_MCS(rc)][width];
-       nsymbols = (nbits + nsymbits - 1) / nsymbits;
-
-       if (!half_gi)
-               duration = SYMBOL_TIME(nsymbols);
-       else
-               duration = SYMBOL_TIME_HALFGI(nsymbols);
-
-       /* addup duration for legacy/ht training and signal fields */
-       streams = HT_RC_2_STREAMS(rc);
-       duration += L_STF + L_LTF + L_SIG + HT_SIG + HT_STF + HT_LTF(streams);
-
-       return duration;
-}
-
-static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
-{
-       struct ath_rate_table *rt = sc->cur_rate_table;
-       struct ath9k_11n_rate_series series[4];
-       struct sk_buff *skb;
-       struct ieee80211_tx_info *tx_info;
-       struct ieee80211_tx_rate *rates;
-       struct ieee80211_hdr *hdr;
-       int i, flags = 0;
-       u8 rix = 0, ctsrate = 0;
-       bool is_pspoll;
-
-       memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4);
-
-       skb = (struct sk_buff *)bf->bf_mpdu;
-       tx_info = IEEE80211_SKB_CB(skb);
-       rates = tx_info->control.rates;
-       hdr = (struct ieee80211_hdr *)skb->data;
-       is_pspoll = ieee80211_is_pspoll(hdr->frame_control);
-
-       /*
-        * We check if Short Preamble is needed for the CTS rate by
-        * checking the BSS's global flag.
-        * But for the rate series, IEEE80211_TX_RC_USE_SHORT_PREAMBLE is used.
-        */
-       if (sc->sc_flags & SC_OP_PREAMBLE_SHORT)
-               ctsrate = rt->info[tx_info->control.rts_cts_rate_idx].ratecode |
-                       rt->info[tx_info->control.rts_cts_rate_idx].short_preamble;
-       else
-               ctsrate = rt->info[tx_info->control.rts_cts_rate_idx].ratecode;
-
-       /*
-        * ATH9K_TXDESC_RTSENA and ATH9K_TXDESC_CTSENA are mutually exclusive.
-        * Check the first rate in the series to decide whether RTS/CTS
-        * or CTS-to-self has to be used.
-        */
-       if (rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
-               flags = ATH9K_TXDESC_CTSENA;
-       else if (rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS)
-               flags = ATH9K_TXDESC_RTSENA;
-
-       /* FIXME: Handle aggregation protection */
-       if (sc->config.ath_aggr_prot &&
-           (!bf_isaggr(bf) || (bf_isaggr(bf) && bf->bf_al < 8192))) {
-               flags = ATH9K_TXDESC_RTSENA;
-       }
-
-       /* For AR5416 - RTS cannot be followed by a frame larger than 8K */
-       if (bf_isaggr(bf) && (bf->bf_al > sc->sc_ah->caps.rts_aggr_limit))
-               flags &= ~(ATH9K_TXDESC_RTSENA);
-
-       for (i = 0; i < 4; i++) {
-               if (!rates[i].count || (rates[i].idx < 0))
-                       continue;
-
-               rix = rates[i].idx;
-               series[i].Tries = rates[i].count;
-               series[i].ChSel = sc->tx_chainmask;
-
-               if (rates[i].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
-                       series[i].Rate = rt->info[rix].ratecode |
-                               rt->info[rix].short_preamble;
-               else
-                       series[i].Rate = rt->info[rix].ratecode;
-
-               if (rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS)
-                       series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS;
-               if (rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
-                       series[i].RateFlags |= ATH9K_RATESERIES_2040;
-               if (rates[i].flags & IEEE80211_TX_RC_SHORT_GI)
-                       series[i].RateFlags |= ATH9K_RATESERIES_HALFGI;
-
-               series[i].PktDuration = ath_pkt_duration(sc, rix, bf,
-                        (rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH) != 0,
-                        (rates[i].flags & IEEE80211_TX_RC_SHORT_GI),
-                        (rates[i].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE));
-       }
-
-       /* set dur_update_en for l-sig computation except for PS-Poll frames */
-       ath9k_hw_set11n_ratescenario(sc->sc_ah, bf->bf_desc,
-                                    bf->bf_lastbf->bf_desc,
-                                    !is_pspoll, ctsrate,
-                                    0, series, 4, flags);
-
-       if (sc->config.ath_aggr_prot && flags)
-               ath9k_hw_set11n_burstduration(sc->sc_ah, bf->bf_desc, 8192);
-}
-
-static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf,
-                               struct sk_buff *skb,
-                               struct ath_tx_control *txctl)
-{
-       struct ath_wiphy *aphy = hw->priv;
-       struct ath_softc *sc = aphy->sc;
-       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
-       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-       struct ath_tx_info_priv *tx_info_priv;
-       int hdrlen;
-       __le16 fc;
-
-       tx_info_priv = kzalloc(sizeof(*tx_info_priv), GFP_ATOMIC);
-       if (unlikely(!tx_info_priv))
-               return -ENOMEM;
-       tx_info->rate_driver_data[0] = tx_info_priv;
-       tx_info_priv->aphy = aphy;
-       tx_info_priv->frame_type = txctl->frame_type;
-       hdrlen = ieee80211_get_hdrlen_from_skb(skb);
-       fc = hdr->frame_control;
-
-       ATH_TXBUF_RESET(bf);
-
-       bf->bf_frmlen = skb->len + FCS_LEN - (hdrlen & 3);
-
-       if (conf_is_ht(&sc->hw->conf) && !is_pae(skb))
-               bf->bf_state.bf_type |= BUF_HT;
-
-       bf->bf_flags = setup_tx_flags(sc, skb, txctl->txq);
-
-       bf->bf_keytype = get_hw_crypto_keytype(skb);
-       if (bf->bf_keytype != ATH9K_KEY_TYPE_CLEAR) {
-               bf->bf_frmlen += tx_info->control.hw_key->icv_len;
-               bf->bf_keyix = tx_info->control.hw_key->hw_key_idx;
-       } else {
-               bf->bf_keyix = ATH9K_TXKEYIX_INVALID;
-       }
-
-       if (ieee80211_is_data_qos(fc) && (sc->sc_flags & SC_OP_TXAGGR))
-               assign_aggr_tid_seqno(skb, bf);
-
-       bf->bf_mpdu = skb;
-
-       bf->bf_dmacontext = dma_map_single(sc->dev, skb->data,
-                                          skb->len, DMA_TO_DEVICE);
-       if (unlikely(dma_mapping_error(sc->dev, bf->bf_dmacontext))) {
-               bf->bf_mpdu = NULL;
-               DPRINTF(sc, ATH_DBG_CONFIG,
-                       "dma_mapping_error() on TX\n");
-               return -ENOMEM;
-       }
-
-       bf->bf_buf_addr = bf->bf_dmacontext;
-       return 0;
-}
-
-/* FIXME: tx power */
-static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf,
-                            struct ath_tx_control *txctl)
-{
-       struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu;
-       struct ieee80211_tx_info *tx_info =  IEEE80211_SKB_CB(skb);
-       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-       struct ath_node *an = NULL;
-       struct list_head bf_head;
-       struct ath_desc *ds;
-       struct ath_atx_tid *tid;
-       struct ath_hw *ah = sc->sc_ah;
-       int frm_type;
-       __le16 fc;
-
-       frm_type = get_hw_packet_type(skb);
-       fc = hdr->frame_control;
-
-       INIT_LIST_HEAD(&bf_head);
-       list_add_tail(&bf->list, &bf_head);
-
-       ds = bf->bf_desc;
-       ds->ds_link = 0;
-       ds->ds_data = bf->bf_buf_addr;
-
-       ath9k_hw_set11n_txdesc(ah, ds, bf->bf_frmlen, frm_type, MAX_RATE_POWER,
-                              bf->bf_keyix, bf->bf_keytype, bf->bf_flags);
-
-       ath9k_hw_filltxdesc(ah, ds,
-                           skb->len,   /* segment length */
-                           true,       /* first segment */
-                           true,       /* last segment */
-                           ds);        /* first descriptor */
-
-       spin_lock_bh(&txctl->txq->axq_lock);
-
-       if (bf_isht(bf) && (sc->sc_flags & SC_OP_TXAGGR) &&
-           tx_info->control.sta) {
-               an = (struct ath_node *)tx_info->control.sta->drv_priv;
-               tid = ATH_AN_2_TID(an, bf->bf_tidno);
-
-               if (!ieee80211_is_data_qos(fc)) {
-                       ath_tx_send_normal(sc, txctl->txq, &bf_head);
-                       goto tx_done;
-               }
-
-               if (ath_aggr_query(sc, an, bf->bf_tidno)) {
-                       /*
-                        * Try aggregation if it's a unicast data frame
-                        * and the destination is HT capable.
-                        */
-                       ath_tx_send_ampdu(sc, tid, &bf_head, txctl);
-               } else {
-                       /*
-                        * Send this frame as regular when ADDBA
-                        * exchange is neither complete nor pending.
-                        */
-                       ath_tx_send_ht_normal(sc, txctl->txq,
-                                             tid, &bf_head);
-               }
-       } else {
-               ath_tx_send_normal(sc, txctl->txq, &bf_head);
-       }
-
-tx_done:
-       spin_unlock_bh(&txctl->txq->axq_lock);
-}
-
-/* Upon failure caller should free skb */
-int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
-                struct ath_tx_control *txctl)
-{
-       struct ath_wiphy *aphy = hw->priv;
-       struct ath_softc *sc = aphy->sc;
-       struct ath_buf *bf;
-       int r;
-
-       bf = ath_tx_get_buffer(sc);
-       if (!bf) {
-               DPRINTF(sc, ATH_DBG_XMIT, "TX buffers are full\n");
-               return -1;
-       }
-
-       r = ath_tx_setup_buffer(hw, bf, skb, txctl);
-       if (unlikely(r)) {
-               struct ath_txq *txq = txctl->txq;
-
-               DPRINTF(sc, ATH_DBG_FATAL, "TX mem alloc failure\n");
-
-               /* upon ath_tx_processq() this TX queue will be resumed, we
-                * guarantee this will happen by knowing beforehand that
-                * we will at least have to run TX completionon one buffer
-                * on the queue */
-               spin_lock_bh(&txq->axq_lock);
-               if (sc->tx.txq[txq->axq_qnum].axq_depth > 1) {
-                       ieee80211_stop_queue(sc->hw,
-                               skb_get_queue_mapping(skb));
-                       txq->stopped = 1;
-               }
-               spin_unlock_bh(&txq->axq_lock);
-
-               spin_lock_bh(&sc->tx.txbuflock);
-               list_add_tail(&bf->list, &sc->tx.txbuf);
-               spin_unlock_bh(&sc->tx.txbuflock);
-
-               return r;
-       }
-
-       ath_tx_start_dma(sc, bf, txctl);
-
-       return 0;
-}
-
-void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb)
-{
-       struct ath_wiphy *aphy = hw->priv;
-       struct ath_softc *sc = aphy->sc;
-       int hdrlen, padsize;
-       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-       struct ath_tx_control txctl;
-
-       memset(&txctl, 0, sizeof(struct ath_tx_control));
-
-       /*
-        * As a temporary workaround, assign seq# here; this will likely need
-        * to be cleaned up to work better with Beacon transmission and virtual
-        * BSSes.
-        */
-       if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
-               struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
-               if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
-                       sc->tx.seq_no += 0x10;
-               hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
-               hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no);
-       }
-
-       /* Add the padding after the header if this is not already done */
-       hdrlen = ieee80211_get_hdrlen_from_skb(skb);
-       if (hdrlen & 3) {
-               padsize = hdrlen % 4;
-               if (skb_headroom(skb) < padsize) {
-                       DPRINTF(sc, ATH_DBG_XMIT, "TX CABQ padding failed\n");
-                       dev_kfree_skb_any(skb);
-                       return;
-               }
-               skb_push(skb, padsize);
-               memmove(skb->data, skb->data + padsize, hdrlen);
-       }
-
-       txctl.txq = sc->beacon.cabq;
-
-       DPRINTF(sc, ATH_DBG_XMIT, "transmitting CABQ packet, skb: %p\n", skb);
-
-       if (ath_tx_start(hw, skb, &txctl) != 0) {
-               DPRINTF(sc, ATH_DBG_XMIT, "CABQ TX failed\n");
-               goto exit;
-       }
-
-       return;
-exit:
-       dev_kfree_skb_any(skb);
-}
-
-/*****************/
-/* TX Completion */
-/*****************/
-
-static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
-                           int tx_flags)
-{
-       struct ieee80211_hw *hw = sc->hw;
-       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
-       struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
-       int hdrlen, padsize;
-       int frame_type = ATH9K_NOT_INTERNAL;
-
-       DPRINTF(sc, ATH_DBG_XMIT, "TX complete: skb: %p\n", skb);
-
-       if (tx_info_priv) {
-               hw = tx_info_priv->aphy->hw;
-               frame_type = tx_info_priv->frame_type;
-       }
-
-       if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK ||
-           tx_info->flags & IEEE80211_TX_STAT_TX_FILTERED) {
-               kfree(tx_info_priv);
-               tx_info->rate_driver_data[0] = NULL;
-       }
-
-       if (tx_flags & ATH_TX_BAR)
-               tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
-
-       if (!(tx_flags & (ATH_TX_ERROR | ATH_TX_XRETRY))) {
-               /* Frame was ACKed */
-               tx_info->flags |= IEEE80211_TX_STAT_ACK;
-       }
-
-       hdrlen = ieee80211_get_hdrlen_from_skb(skb);
-       padsize = hdrlen & 3;
-       if (padsize && hdrlen >= 24) {
-               /*
-                * Remove MAC header padding before giving the frame back to
-                * mac80211.
-                */
-               memmove(skb->data + padsize, skb->data, hdrlen);
-               skb_pull(skb, padsize);
-       }
-
-       if (frame_type == ATH9K_NOT_INTERNAL)
-               ieee80211_tx_status(hw, skb);
-       else
-               ath9k_tx_status(hw, skb);
-}
-
-static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
-                               struct list_head *bf_q,
-                               int txok, int sendbar)
-{
-       struct sk_buff *skb = bf->bf_mpdu;
-       unsigned long flags;
-       int tx_flags = 0;
-
-
-       if (sendbar)
-               tx_flags = ATH_TX_BAR;
-
-       if (!txok) {
-               tx_flags |= ATH_TX_ERROR;
-
-               if (bf_isxretried(bf))
-                       tx_flags |= ATH_TX_XRETRY;
-       }
-
-       dma_unmap_single(sc->dev, bf->bf_dmacontext, skb->len, DMA_TO_DEVICE);
-       ath_tx_complete(sc, skb, tx_flags);
-
-       /*
-        * Return the list of ath_buf of this mpdu to free queue
-        */
-       spin_lock_irqsave(&sc->tx.txbuflock, flags);
-       list_splice_tail_init(bf_q, &sc->tx.txbuf);
-       spin_unlock_irqrestore(&sc->tx.txbuflock, flags);
-}
-
-static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf,
-                             int txok)
-{
-       struct ath_buf *bf_last = bf->bf_lastbf;
-       struct ath_desc *ds = bf_last->bf_desc;
-       u16 seq_st = 0;
-       u32 ba[WME_BA_BMP_SIZE >> 5];
-       int ba_index;
-       int nbad = 0;
-       int isaggr = 0;
-
-       if (ds->ds_txstat.ts_flags == ATH9K_TX_SW_ABORTED)
-               return 0;
-
-       isaggr = bf_isaggr(bf);
-       if (isaggr) {
-               seq_st = ATH_DS_BA_SEQ(ds);
-               memcpy(ba, ATH_DS_BA_BITMAP(ds), WME_BA_BMP_SIZE >> 3);
-       }
-
-       while (bf) {
-               ba_index = ATH_BA_INDEX(seq_st, bf->bf_seqno);
-               if (!txok || (isaggr && !ATH_BA_ISSET(ba, ba_index)))
-                       nbad++;
-
-               bf = bf->bf_next;
-       }
-
-       return nbad;
-}
-
-static void ath_tx_rc_status(struct ath_buf *bf, struct ath_desc *ds,
-                            int nbad, int txok, bool update_rc)
-{
-       struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu;
-       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
-       struct ath_tx_info_priv *tx_info_priv = ATH_TX_INFO_PRIV(tx_info);
-       struct ieee80211_hw *hw = tx_info_priv->aphy->hw;
-       u8 i, tx_rateindex;
-
-       if (txok)
-               tx_info->status.ack_signal = ds->ds_txstat.ts_rssi;
-
-       tx_rateindex = ds->ds_txstat.ts_rateindex;
-       WARN_ON(tx_rateindex >= hw->max_rates);
-
-       tx_info_priv->update_rc = update_rc;
-       if (ds->ds_txstat.ts_status & ATH9K_TXERR_FILT)
-               tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
-
-       if ((ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) == 0 &&
-           (bf->bf_flags & ATH9K_TXDESC_NOACK) == 0 && update_rc) {
-               if (ieee80211_is_data(hdr->frame_control)) {
-                       memcpy(&tx_info_priv->tx, &ds->ds_txstat,
-                              sizeof(tx_info_priv->tx));
-                       tx_info_priv->n_frames = bf->bf_nframes;
-                       tx_info_priv->n_bad_frames = nbad;
-               }
-       }
-
-       for (i = tx_rateindex + 1; i < hw->max_rates; i++)
-               tx_info->status.rates[i].count = 0;
-
-       tx_info->status.rates[tx_rateindex].count = bf->bf_retries + 1;
-}
-
-static void ath_wake_mac80211_queue(struct ath_softc *sc, struct ath_txq *txq)
-{
-       int qnum;
-
-       spin_lock_bh(&txq->axq_lock);
-       if (txq->stopped &&
-           sc->tx.txq[txq->axq_qnum].axq_depth <= (ATH_TXBUF - 20)) {
-               qnum = ath_get_mac80211_qnum(txq->axq_qnum, sc);
-               if (qnum != -1) {
-                       ieee80211_wake_queue(sc->hw, qnum);
-                       txq->stopped = 0;
-               }
-       }
-       spin_unlock_bh(&txq->axq_lock);
-}
-
-static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
-{
-       struct ath_hw *ah = sc->sc_ah;
-       struct ath_buf *bf, *lastbf, *bf_held = NULL;
-       struct list_head bf_head;
-       struct ath_desc *ds;
-       int txok;
-       int status;
-
-       DPRINTF(sc, ATH_DBG_QUEUE, "tx queue %d (%x), link %p\n",
-               txq->axq_qnum, ath9k_hw_gettxbuf(sc->sc_ah, txq->axq_qnum),
-               txq->axq_link);
-
-       for (;;) {
-               spin_lock_bh(&txq->axq_lock);
-               if (list_empty(&txq->axq_q)) {
-                       txq->axq_link = NULL;
-                       txq->axq_linkbuf = NULL;
-                       spin_unlock_bh(&txq->axq_lock);
-                       break;
-               }
-               bf = list_first_entry(&txq->axq_q, struct ath_buf, list);
-
-               /*
-                * There is a race condition that a BH gets scheduled
-                * after sw writes TxE and before hw re-load the last
-                * descriptor to get the newly chained one.
-                * Software must keep the last DONE descriptor as a
-                * holding descriptor - software does so by marking
-                * it with the STALE flag.
-                */
-               bf_held = NULL;
-               if (bf->bf_status & ATH_BUFSTATUS_STALE) {
-                       bf_held = bf;
-                       if (list_is_last(&bf_held->list, &txq->axq_q)) {
-                               txq->axq_link = NULL;
-                               txq->axq_linkbuf = NULL;
-                               spin_unlock_bh(&txq->axq_lock);
-
-                               /*
-                                * The holding descriptor is the last
-                                * descriptor in queue. It's safe to remove
-                                * the last holding descriptor in BH context.
-                                */
-                               spin_lock_bh(&sc->tx.txbuflock);
-                               list_move_tail(&bf_held->list, &sc->tx.txbuf);
-                               spin_unlock_bh(&sc->tx.txbuflock);
-
-                               break;
-                       } else {
-                               bf = list_entry(bf_held->list.next,
-                                               struct ath_buf, list);
-                       }
-               }
-
-               lastbf = bf->bf_lastbf;
-               ds = lastbf->bf_desc;
-
-               status = ath9k_hw_txprocdesc(ah, ds);
-               if (status == -EINPROGRESS) {
-                       spin_unlock_bh(&txq->axq_lock);
-                       break;
-               }
-               if (bf->bf_desc == txq->axq_lastdsWithCTS)
-                       txq->axq_lastdsWithCTS = NULL;
-               if (ds == txq->axq_gatingds)
-                       txq->axq_gatingds = NULL;
-
-               /*
-                * Remove ath_buf's of the same transmit unit from txq,
-                * however leave the last descriptor back as the holding
-                * descriptor for hw.
-                */
-               lastbf->bf_status |= ATH_BUFSTATUS_STALE;
-               INIT_LIST_HEAD(&bf_head);
-               if (!list_is_singular(&lastbf->list))
-                       list_cut_position(&bf_head,
-                               &txq->axq_q, lastbf->list.prev);
-
-               txq->axq_depth--;
-               if (bf_isaggr(bf))
-                       txq->axq_aggr_depth--;
-
-               txok = (ds->ds_txstat.ts_status == 0);
-               spin_unlock_bh(&txq->axq_lock);
-
-               if (bf_held) {
-                       spin_lock_bh(&sc->tx.txbuflock);
-                       list_move_tail(&bf_held->list, &sc->tx.txbuf);
-                       spin_unlock_bh(&sc->tx.txbuflock);
-               }
-
-               if (!bf_isampdu(bf)) {
-                       /*
-                        * This frame is sent out as a single frame.
-                        * Use hardware retry status for this frame.
-                        */
-                       bf->bf_retries = ds->ds_txstat.ts_longretry;
-                       if (ds->ds_txstat.ts_status & ATH9K_TXERR_XRETRY)
-                               bf->bf_state.bf_type |= BUF_XRETRY;
-                       ath_tx_rc_status(bf, ds, 0, txok, true);
-               }
-
-               if (bf_isampdu(bf))
-                       ath_tx_complete_aggr(sc, txq, bf, &bf_head, txok);
-               else
-                       ath_tx_complete_buf(sc, bf, &bf_head, txok, 0);
-
-               ath_wake_mac80211_queue(sc, txq);
-
-               spin_lock_bh(&txq->axq_lock);
-               if (sc->sc_flags & SC_OP_TXAGGR)
-                       ath_txq_schedule(sc, txq);
-               spin_unlock_bh(&txq->axq_lock);
-       }
-}
-
-
-void ath_tx_tasklet(struct ath_softc *sc)
-{
-       int i;
-       u32 qcumask = ((1 << ATH9K_NUM_TX_QUEUES) - 1);
-
-       ath9k_hw_gettxintrtxqs(sc->sc_ah, &qcumask);
-
-       for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
-               if (ATH_TXQ_SETUP(sc, i) && (qcumask & (1 << i)))
-                       ath_tx_processq(sc, &sc->tx.txq[i]);
-       }
-}
-
-/*****************/
-/* Init, Cleanup */
-/*****************/
-
-int ath_tx_init(struct ath_softc *sc, int nbufs)
-{
-       int error = 0;
-
-       do {
-               spin_lock_init(&sc->tx.txbuflock);
-
-               error = ath_descdma_setup(sc, &sc->tx.txdma, &sc->tx.txbuf,
-                       "tx", nbufs, 1);
-               if (error != 0) {
-                       DPRINTF(sc, ATH_DBG_FATAL,
-                               "Failed to allocate tx descriptors: %d\n",
-                               error);
-                       break;
-               }
-
-               error = ath_descdma_setup(sc, &sc->beacon.bdma, &sc->beacon.bbuf,
-                                         "beacon", ATH_BCBUF, 1);
-               if (error != 0) {
-                       DPRINTF(sc, ATH_DBG_FATAL,
-                               "Failed to allocate beacon descriptors: %d\n",
-                               error);
-                       break;
-               }
-
-       } while (0);
-
-       if (error != 0)
-               ath_tx_cleanup(sc);
-
-       return error;
-}
-
-int ath_tx_cleanup(struct ath_softc *sc)
-{
-       if (sc->beacon.bdma.dd_desc_len != 0)
-               ath_descdma_cleanup(sc, &sc->beacon.bdma, &sc->beacon.bbuf);
-
-       if (sc->tx.txdma.dd_desc_len != 0)
-               ath_descdma_cleanup(sc, &sc->tx.txdma, &sc->tx.txbuf);
-
-       return 0;
-}
-
-void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an)
-{
-       struct ath_atx_tid *tid;
-       struct ath_atx_ac *ac;
-       int tidno, acno;
-
-       for (tidno = 0, tid = &an->tid[tidno];
-            tidno < WME_NUM_TID;
-            tidno++, tid++) {
-               tid->an        = an;
-               tid->tidno     = tidno;
-               tid->seq_start = tid->seq_next = 0;
-               tid->baw_size  = WME_MAX_BA;
-               tid->baw_head  = tid->baw_tail = 0;
-               tid->sched     = false;
-               tid->paused    = false;
-               tid->state &= ~AGGR_CLEANUP;
-               INIT_LIST_HEAD(&tid->buf_q);
-               acno = TID_TO_WME_AC(tidno);
-               tid->ac = &an->ac[acno];
-               tid->state &= ~AGGR_ADDBA_COMPLETE;
-               tid->state &= ~AGGR_ADDBA_PROGRESS;
-               tid->addba_exchangeattempts = 0;
-       }
-
-       for (acno = 0, ac = &an->ac[acno];
-            acno < WME_NUM_AC; acno++, ac++) {
-               ac->sched    = false;
-               INIT_LIST_HEAD(&ac->tid_q);
-
-               switch (acno) {
-               case WME_AC_BE:
-                       ac->qnum = ath_tx_get_qnum(sc,
-                                  ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_BE);
-                       break;
-               case WME_AC_BK:
-                       ac->qnum = ath_tx_get_qnum(sc,
-                                  ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_BK);
-                       break;
-               case WME_AC_VI:
-                       ac->qnum = ath_tx_get_qnum(sc,
-                                  ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_VI);
-                       break;
-               case WME_AC_VO:
-                       ac->qnum = ath_tx_get_qnum(sc,
-                                  ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_VO);
-                       break;
-               }
-       }
-}
-
-void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an)
-{
-       int i;
-       struct ath_atx_ac *ac, *ac_tmp;
-       struct ath_atx_tid *tid, *tid_tmp;
-       struct ath_txq *txq;
-
-       for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
-               if (ATH_TXQ_SETUP(sc, i)) {
-                       txq = &sc->tx.txq[i];
-
-                       spin_lock(&txq->axq_lock);
-
-                       list_for_each_entry_safe(ac,
-                                       ac_tmp, &txq->axq_acq, list) {
-                               tid = list_first_entry(&ac->tid_q,
-                                               struct ath_atx_tid, list);
-                               if (tid && tid->an != an)
-                                       continue;
-                               list_del(&ac->list);
-                               ac->sched = false;
-
-                               list_for_each_entry_safe(tid,
-                                               tid_tmp, &ac->tid_q, list) {
-                                       list_del(&tid->list);
-                                       tid->sched = false;
-                                       ath_tid_drain(sc, txq, tid);
-                                       tid->state &= ~AGGR_ADDBA_COMPLETE;
-                                       tid->addba_exchangeattempts = 0;
-                                       tid->state &= ~AGGR_CLEANUP;
-                               }
-                       }
-
-                       spin_unlock(&txq->axq_lock);
-               }
-       }
-}
index 27eef8fb7107b3e82b263caf0ea49423be9d2686..291a94bd46fdc8298b502b60fa7f5234e1c4a8cc 100644 (file)
@@ -818,7 +818,7 @@ static int start_tx(struct sk_buff *skb, struct net_device *dev)
                spin_unlock_irqrestore(&priv->irqlock, flags);
                spin_unlock_bh(&priv->timerlock);
                netif_stop_queue(dev);
-               return 1;
+               return NETDEV_TX_BUSY;
        }
 
        frame_ctl = IEEE80211_FTYPE_DATA;
index 77406245dc7b8fb171f82802bd8d4e494747f20e..ddaa859c3491d8209a5e834a1a4d1ec0c59ad05f 100644 (file)
@@ -279,7 +279,7 @@ static int atmel_config(struct pcmcia_device *link)
        struct pcmcia_device_id *did;
 
        dev = link->priv;
-       did = handle_to_dev(link).driver_data;
+       did = dev_get_drvdata(&handle_to_dev(link));
 
        DEBUG(0, "atmel_config(0x%p)\n", link);
 
index aab71a70ba788070b21a1452ba22478b0bbd5cd2..67f564e372250add1492af4149ebade112e60519 100644 (file)
@@ -3,7 +3,6 @@ config B43
        depends on SSB_POSSIBLE && MAC80211 && WLAN_80211 && HAS_DMA
        select SSB
        select FW_LOADER
-       select HW_RANDOM
        ---help---
          b43 is a driver for the Broadcom 43xx series wireless devices.
 
@@ -99,11 +98,11 @@ config B43_LEDS
        depends on B43 && MAC80211_LEDS && (LEDS_CLASS = y || LEDS_CLASS = B43)
        default y
 
-# This config option automatically enables b43 RFKILL support,
-# if it's possible.
-config B43_RFKILL
+# This config option automatically enables b43 HW-RNG support,
+# if the HW-RNG core is enabled.
+config B43_HWRNG
        bool
-       depends on B43 && (RFKILL = y || RFKILL = B43) && RFKILL_INPUT && (INPUT_POLLDEV = y || INPUT_POLLDEV = B43)
+       depends on B43 && (HW_RANDOM = y || HW_RANDOM = B43)
        default y
 
 config B43_DEBUG
index 281ef8310350e559752f0a44a6d9f0744cbd466c..da379f4b0c3a31f9bbfff19c4367b0ff2ff10a21 100644 (file)
@@ -13,7 +13,7 @@ b43-y                         += lo.o
 b43-y                          += wa.o
 b43-y                          += dma.o
 b43-$(CONFIG_B43_PIO)          += pio.o
-b43-$(CONFIG_B43_RFKILL)       += rfkill.o
+b43-y                          += rfkill.o
 b43-$(CONFIG_B43_LEDS)         += leds.o
 b43-$(CONFIG_B43_PCMCIA)       += pcmcia.o
 b43-$(CONFIG_B43_DEBUG)                += debugfs.o
index beaf18d6e8a7c95f5f41f902de405c242f3254a2..f580c2812d91846d611c552295e9722fe09aa06f 100644 (file)
@@ -163,6 +163,7 @@ enum {
 #define B43_SHM_SH_WLCOREREV           0x0016  /* 802.11 core revision */
 #define B43_SHM_SH_PCTLWDPOS           0x0008
 #define B43_SHM_SH_RXPADOFF            0x0034  /* RX Padding data offset (PIO only) */
+#define B43_SHM_SH_FWCAPA              0x0042  /* Firmware capabilities (Opensource firmware only) */
 #define B43_SHM_SH_PHYVER              0x0050  /* PHY version */
 #define B43_SHM_SH_PHYTYPE             0x0052  /* PHY type */
 #define B43_SHM_SH_ANTSWAP             0x005C  /* Antenna swap threshold */
@@ -297,6 +298,10 @@ enum {
 #define B43_HF_MLADVW          0x001000000000ULL /* N PHY ML ADV workaround (rev >= 13 only) */
 #define B43_HF_PR45960W                0x080000000000ULL /* PR 45960 workaround (rev >= 13 only) */
 
+/* Firmware capabilities field in SHM (Opensource firmware only) */
+#define B43_FWCAPA_HWCRYPTO    0x0001
+#define B43_FWCAPA_QOS         0x0002
+
 /* MacFilter offsets. */
 #define B43_MACFILTER_SELF             0x0000
 #define B43_MACFILTER_BSSID            0x0003
@@ -596,6 +601,13 @@ struct b43_wl {
        /* Pointer to the ieee80211 hardware data structure */
        struct ieee80211_hw *hw;
 
+       /* The number of queues that were registered with the mac80211 subsystem
+        * initially. This is a backup copy of hw->queues in case hw->queues has
+        * to be dynamically lowered at runtime (Firmware does not support QoS).
+        * hw->queues has to be restored to the original value before unregistering
+        * from the mac80211 subsystem. */
+       u16 mac80211_initially_registered_queues;
+
        struct mutex mutex;
        spinlock_t irq_lock;
        /* R/W lock for data transmission.
@@ -625,12 +637,11 @@ struct b43_wl {
        /* Stats about the wireless interface */
        struct ieee80211_low_level_stats ieee_stats;
 
+#ifdef CONFIG_B43_HWRNG
        struct hwrng rng;
-       u8 rng_initialized;
+       bool rng_initialized;
        char rng_name[30 + 1];
-
-       /* The RF-kill button */
-       struct b43_rfkill rfkill;
+#endif /* CONFIG_B43_HWRNG */
 
        /* List of all wireless devices on this chip */
        struct list_head devlist;
@@ -750,6 +761,8 @@ struct b43_wldev {
        bool dfq_valid;         /* Directed frame queue valid (IBSS PS mode, ATIM) */
        bool radio_hw_enable;   /* saved state of radio hardware enabled state */
        bool suspend_in_progress;       /* TRUE, if we are in a suspend/resume cycle */
+       bool qos_enabled;               /* TRUE, if QoS is used. */
+       bool hwcrypto_enabled;          /* TRUE, if HW crypto acceleration is enabled. */
 
        /* PHY/Radio device. */
        struct b43_phy phy;
@@ -776,8 +789,8 @@ struct b43_wldev {
        /* Reason code of the last interrupt. */
        u32 irq_reason;
        u32 dma_reason[6];
-       /* saved irq enable/disable state bitfield. */
-       u32 irq_savedstate;
+       /* The currently active generic-interrupt mask. */
+       u32 irq_mask;
        /* Link Quality calculation context. */
        struct b43_noise_calculation noisecalc;
        /* if > 0 MAC is suspended. if == 0 MAC is enabled. */
index eae680b530527f639fcce2f1568188540e69e3cd..7964cc32b258bb80599e54be2e1c6c478f356119 100644 (file)
@@ -1285,7 +1285,7 @@ static struct b43_dmaring *select_ring_by_priority(struct b43_wldev *dev,
 {
        struct b43_dmaring *ring;
 
-       if (b43_modparam_qos) {
+       if (dev->qos_enabled) {
                /* 0 = highest priority */
                switch (queue_prio) {
                default:
index 76f4c7bad8b83e52b30000ccc62f86a77113e45b..c8b317094c31b489dfbb9091bb7c648f3060d927 100644 (file)
@@ -28,6 +28,7 @@
 
 #include "b43.h"
 #include "leds.h"
+#include "rfkill.h"
 
 
 static void b43_led_turn_on(struct b43_wldev *dev, u8 led_index,
@@ -87,7 +88,7 @@ static void b43_led_brightness_set(struct led_classdev *led_dev,
 }
 
 static int b43_register_led(struct b43_wldev *dev, struct b43_led *led,
-                           const char *name, char *default_trigger,
+                           const char *name, const char *default_trigger,
                            u8 led_index, bool activelow)
 {
        int err;
@@ -164,10 +165,10 @@ static void b43_map_led(struct b43_wldev *dev,
                snprintf(name, sizeof(name),
                         "b43-%s::radio", wiphy_name(hw->wiphy));
                b43_register_led(dev, &dev->led_radio, name,
-                                b43_rfkill_led_name(dev),
+                                ieee80211_get_radio_led_name(hw),
                                 led_index, activelow);
-               /* Sync the RF-kill LED state with the switch state. */
-               if (dev->radio_hw_enable)
+               /* Sync the RF-kill LED state with radio and switch states. */
+               if (dev->phy.radio_on && b43_is_hw_radio_enabled(dev))
                        b43_led_turn_on(dev, led_index, activelow);
                break;
        case B43_LED_WEIRD:
index 79b685e300c7bff2a2221d882a260066d9fdd34e..6456afebdba10d3268d6184a76695f253bce135b 100644 (file)
@@ -80,8 +80,8 @@ static int modparam_nohwcrypt;
 module_param_named(nohwcrypt, modparam_nohwcrypt, int, 0444);
 MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
 
-int b43_modparam_qos = 1;
-module_param_named(qos, b43_modparam_qos, int, 0444);
+static int modparam_qos = 1;
+module_param_named(qos, modparam_qos, int, 0444);
 MODULE_PARM_DESC(qos, "Enable QOS support (default on)");
 
 static int modparam_btcoex = 1;
@@ -538,6 +538,13 @@ void b43_hf_write(struct b43_wldev *dev, u64 value)
        b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_HOSTFHI, hi);
 }
 
+/* Read the firmware capabilities bitmask (Opensource firmware only) */
+static u16 b43_fwcapa_read(struct b43_wldev *dev)
+{
+       B43_WARN_ON(!dev->fw.opensource);
+       return b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_FWCAPA);
+}
+
 void b43_tsf_read(struct b43_wldev *dev, u64 *tsf)
 {
        u32 low, high;
@@ -673,32 +680,6 @@ static void b43_short_slot_timing_disable(struct b43_wldev *dev)
        b43_set_slot_time(dev, 20);
 }
 
-/* Enable a Generic IRQ. "mask" is the mask of which IRQs to enable.
- * Returns the _previously_ enabled IRQ mask.
- */
-static inline u32 b43_interrupt_enable(struct b43_wldev *dev, u32 mask)
-{
-       u32 old_mask;
-
-       old_mask = b43_read32(dev, B43_MMIO_GEN_IRQ_MASK);
-       b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, old_mask | mask);
-
-       return old_mask;
-}
-
-/* Disable a Generic IRQ. "mask" is the mask of which IRQs to disable.
- * Returns the _previously_ enabled IRQ mask.
- */
-static inline u32 b43_interrupt_disable(struct b43_wldev *dev, u32 mask)
-{
-       u32 old_mask;
-
-       old_mask = b43_read32(dev, B43_MMIO_GEN_IRQ_MASK);
-       b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, old_mask & ~mask);
-
-       return old_mask;
-}
-
 /* Synchronize IRQ top- and bottom-half.
  * IRQs must be masked before calling this.
  * This must not be called with the irq_lock held.
@@ -1593,7 +1574,7 @@ static void handle_irq_beacon(struct b43_wldev *dev)
        /* This is the bottom half of the asynchronous beacon update. */
 
        /* Ignore interrupt in the future. */
-       dev->irq_savedstate &= ~B43_IRQ_BEACON;
+       dev->irq_mask &= ~B43_IRQ_BEACON;
 
        cmd = b43_read32(dev, B43_MMIO_MACCMD);
        beacon0_valid = (cmd & B43_MACCMD_BEACON0_VALID);
@@ -1602,7 +1583,7 @@ static void handle_irq_beacon(struct b43_wldev *dev)
        /* Schedule interrupt manually, if busy. */
        if (beacon0_valid && beacon1_valid) {
                b43_write32(dev, B43_MMIO_GEN_IRQ_REASON, B43_IRQ_BEACON);
-               dev->irq_savedstate |= B43_IRQ_BEACON;
+               dev->irq_mask |= B43_IRQ_BEACON;
                return;
        }
 
@@ -1641,11 +1622,9 @@ static void b43_beacon_update_trigger_work(struct work_struct *work)
        if (likely(dev && (b43_status(dev) >= B43_STAT_INITIALIZED))) {
                spin_lock_irq(&wl->irq_lock);
                /* update beacon right away or defer to irq */
-               dev->irq_savedstate = b43_read32(dev, B43_MMIO_GEN_IRQ_MASK);
                handle_irq_beacon(dev);
                /* The handler might have updated the IRQ mask. */
-               b43_write32(dev, B43_MMIO_GEN_IRQ_MASK,
-                           dev->irq_savedstate);
+               b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, dev->irq_mask);
                mmiowb();
                spin_unlock_irq(&wl->irq_lock);
        }
@@ -1879,7 +1858,7 @@ static void b43_interrupt_tasklet(struct b43_wldev *dev)
        if (reason & B43_IRQ_TX_OK)
                handle_irq_transmit_status(dev);
 
-       b43_interrupt_enable(dev, dev->irq_savedstate);
+       b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, dev->irq_mask);
        mmiowb();
        spin_unlock_irqrestore(&dev->wl->irq_lock, flags);
 }
@@ -1893,7 +1872,9 @@ static void b43_interrupt_ack(struct b43_wldev *dev, u32 reason)
        b43_write32(dev, B43_MMIO_DMA2_REASON, dev->dma_reason[2]);
        b43_write32(dev, B43_MMIO_DMA3_REASON, dev->dma_reason[3]);
        b43_write32(dev, B43_MMIO_DMA4_REASON, dev->dma_reason[4]);
+/* Unused ring
        b43_write32(dev, B43_MMIO_DMA5_REASON, dev->dma_reason[5]);
+*/
 }
 
 /* Interrupt handler top-half */
@@ -1903,18 +1884,19 @@ static irqreturn_t b43_interrupt_handler(int irq, void *dev_id)
        struct b43_wldev *dev = dev_id;
        u32 reason;
 
-       if (!dev)
-               return IRQ_NONE;
+       B43_WARN_ON(!dev);
 
        spin_lock(&dev->wl->irq_lock);
 
-       if (b43_status(dev) < B43_STAT_STARTED)
+       if (unlikely(b43_status(dev) < B43_STAT_STARTED)) {
+               /* This can only happen on shared IRQ lines. */
                goto out;
+       }
        reason = b43_read32(dev, B43_MMIO_GEN_IRQ_REASON);
        if (reason == 0xffffffff)       /* shared IRQ */
                goto out;
        ret = IRQ_HANDLED;
-       reason &= b43_read32(dev, B43_MMIO_GEN_IRQ_MASK);
+       reason &= dev->irq_mask;
        if (!reason)
                goto out;
 
@@ -1928,16 +1910,18 @@ static irqreturn_t b43_interrupt_handler(int irq, void *dev_id)
            & 0x0001DC00;
        dev->dma_reason[4] = b43_read32(dev, B43_MMIO_DMA4_REASON)
            & 0x0000DC00;
+/* Unused ring
        dev->dma_reason[5] = b43_read32(dev, B43_MMIO_DMA5_REASON)
            & 0x0000DC00;
+*/
 
        b43_interrupt_ack(dev, reason);
        /* disable all IRQs. They are enabled again in the bottom half. */
-       dev->irq_savedstate = b43_interrupt_disable(dev, B43_IRQ_ALL);
+       b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, 0);
        /* save the reason code and call our bottom half. */
        dev->irq_reason = reason;
        tasklet_schedule(&dev->isr_tasklet);
-      out:
+out:
        mmiowb();
        spin_unlock(&dev->wl->irq_lock);
 
@@ -2330,12 +2314,34 @@ static int b43_upload_microcode(struct b43_wldev *dev)
        dev->fw.patch = fwpatch;
        dev->fw.opensource = (fwdate == 0xFFFF);
 
+       /* Default to use-all-queues. */
+       dev->wl->hw->queues = dev->wl->mac80211_initially_registered_queues;
+       dev->qos_enabled = !!modparam_qos;
+       /* Default to firmware/hardware crypto acceleration. */
+       dev->hwcrypto_enabled = 1;
+
        if (dev->fw.opensource) {
+               u16 fwcapa;
+
                /* Patchlevel info is encoded in the "time" field. */
                dev->fw.patch = fwtime;
-               b43info(dev->wl, "Loading OpenSource firmware version %u.%u%s\n",
-                       dev->fw.rev, dev->fw.patch,
-                       dev->fw.pcm_request_failed ? " (Hardware crypto not supported)" : "");
+               b43info(dev->wl, "Loading OpenSource firmware version %u.%u\n",
+                       dev->fw.rev, dev->fw.patch);
+
+               fwcapa = b43_fwcapa_read(dev);
+               if (!(fwcapa & B43_FWCAPA_HWCRYPTO) || dev->fw.pcm_request_failed) {
+                       b43info(dev->wl, "Hardware crypto acceleration not supported by firmware\n");
+                       /* Disable hardware crypto and fall back to software crypto. */
+                       dev->hwcrypto_enabled = 0;
+               }
+               if (!(fwcapa & B43_FWCAPA_QOS)) {
+                       b43info(dev->wl, "QoS not supported by firmware\n");
+                       /* Disable QoS. Tweak hw->queues to 1. It will be restored before
+                        * ieee80211_unregister to make sure the networking core can
+                        * properly free possible resources. */
+                       dev->wl->hw->queues = 1;
+                       dev->qos_enabled = 0;
+               }
        } else {
                b43info(dev->wl, "Loading firmware version %u.%u "
                        "(20%.2i-%.2i-%.2i %.2i:%.2i:%.2i)\n",
@@ -2980,6 +2986,7 @@ static void b43_security_init(struct b43_wldev *dev)
        b43_clear_keys(dev);
 }
 
+#ifdef CONFIG_B43_HWRNG
 static int b43_rng_read(struct hwrng *rng, u32 *data)
 {
        struct b43_wl *wl = (struct b43_wl *)rng->priv;
@@ -2995,17 +3002,21 @@ static int b43_rng_read(struct hwrng *rng, u32 *data)
 
        return (sizeof(u16));
 }
+#endif /* CONFIG_B43_HWRNG */
 
 static void b43_rng_exit(struct b43_wl *wl)
 {
+#ifdef CONFIG_B43_HWRNG
        if (wl->rng_initialized)
                hwrng_unregister(&wl->rng);
+#endif /* CONFIG_B43_HWRNG */
 }
 
 static int b43_rng_init(struct b43_wl *wl)
 {
-       int err;
+       int err = 0;
 
+#ifdef CONFIG_B43_HWRNG
        snprintf(wl->rng_name, ARRAY_SIZE(wl->rng_name),
                 "%s_%s", KBUILD_MODNAME, wiphy_name(wl->hw->wiphy));
        wl->rng.name = wl->rng_name;
@@ -3018,6 +3029,7 @@ static int b43_rng_init(struct b43_wl *wl)
                b43err(wl, "Failed to register the random "
                       "number generator (%d)\n", err);
        }
+#endif /* CONFIG_B43_HWRNG */
 
        return err;
 }
@@ -3485,14 +3497,9 @@ static int b43_op_config(struct ieee80211_hw *hw, u32 changed)
        if (phy->ops->set_rx_antenna)
                phy->ops->set_rx_antenna(dev, antenna);
 
-       /* Update templates for AP/mesh mode. */
-       if (b43_is_mode(wl, NL80211_IFTYPE_AP) ||
-           b43_is_mode(wl, NL80211_IFTYPE_MESH_POINT))
-               b43_set_beacon_int(dev, conf->beacon_int);
-
        if (!!conf->radio_enabled != phy->radio_on) {
                if (conf->radio_enabled) {
-                       b43_software_rfkill(dev, RFKILL_STATE_UNBLOCKED);
+                       b43_software_rfkill(dev, false);
                        b43info(dev->wl, "Radio turned on by software\n");
                        if (!dev->radio_hw_enable) {
                                b43info(dev->wl, "The hardware RF-kill button "
@@ -3500,7 +3507,7 @@ static int b43_op_config(struct ieee80211_hw *hw, u32 changed)
                                        "Press the button to turn it on.\n");
                        }
                } else {
-                       b43_software_rfkill(dev, RFKILL_STATE_SOFT_BLOCKED);
+                       b43_software_rfkill(dev, true);
                        b43info(dev->wl, "Radio turned off by software\n");
                }
        }
@@ -3565,14 +3572,45 @@ static void b43_op_bss_info_changed(struct ieee80211_hw *hw,
 {
        struct b43_wl *wl = hw_to_b43_wl(hw);
        struct b43_wldev *dev;
+       unsigned long flags;
 
        mutex_lock(&wl->mutex);
 
        dev = wl->current_dev;
        if (!dev || b43_status(dev) < B43_STAT_STARTED)
                goto out_unlock_mutex;
+
+       B43_WARN_ON(wl->vif != vif);
+
+       spin_lock_irqsave(&wl->irq_lock, flags);
+       if (changed & BSS_CHANGED_BSSID) {
+               if (conf->bssid)
+                       memcpy(wl->bssid, conf->bssid, ETH_ALEN);
+               else
+                       memset(wl->bssid, 0, ETH_ALEN);
+       }
+
+       if (b43_status(dev) >= B43_STAT_INITIALIZED) {
+               if (changed & BSS_CHANGED_BEACON &&
+                   (b43_is_mode(wl, NL80211_IFTYPE_AP) ||
+                    b43_is_mode(wl, NL80211_IFTYPE_MESH_POINT) ||
+                    b43_is_mode(wl, NL80211_IFTYPE_ADHOC)))
+                       b43_update_templates(wl);
+
+               if (changed & BSS_CHANGED_BSSID)
+                       b43_write_mac_bssid_templates(dev);
+       }
+       spin_unlock_irqrestore(&wl->irq_lock, flags);
+
        b43_mac_suspend(dev);
 
+       /* Update templates for AP/mesh mode. */
+       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_set_beacon_int(dev, conf->beacon_int);
+
        if (changed & BSS_CHANGED_BASIC_RATES)
                b43_update_basic_rates(dev, conf->basic_rates);
 
@@ -3586,8 +3624,6 @@ static void b43_op_bss_info_changed(struct ieee80211_hw *hw,
        b43_mac_enable(dev);
 out_unlock_mutex:
        mutex_unlock(&wl->mutex);
-
-       return;
 }
 
 static int b43_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
@@ -3620,7 +3656,7 @@ static int b43_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
        if (!dev || b43_status(dev) < B43_STAT_INITIALIZED)
                goto out_unlock;
 
-       if (dev->fw.pcm_request_failed) {
+       if (dev->fw.pcm_request_failed || !dev->hwcrypto_enabled) {
                /* We don't have firmware for the crypto engine.
                 * Must use software-crypto. */
                err = -EOPNOTSUPP;
@@ -3630,7 +3666,7 @@ static int b43_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
        err = -EINVAL;
        switch (key->alg) {
        case ALG_WEP:
-               if (key->keylen == LEN_WEP40)
+               if (key->keylen == WLAN_KEY_LEN_WEP40)
                        algorithm = B43_SEC_ALGO_WEP40;
                else
                        algorithm = B43_SEC_ALGO_WEP104;
@@ -3745,41 +3781,6 @@ static void b43_op_configure_filter(struct ieee80211_hw *hw,
        spin_unlock_irqrestore(&wl->irq_lock, flags);
 }
 
-static int b43_op_config_interface(struct ieee80211_hw *hw,
-                                  struct ieee80211_vif *vif,
-                                  struct ieee80211_if_conf *conf)
-{
-       struct b43_wl *wl = hw_to_b43_wl(hw);
-       struct b43_wldev *dev = wl->current_dev;
-       unsigned long flags;
-
-       if (!dev)
-               return -ENODEV;
-       mutex_lock(&wl->mutex);
-       spin_lock_irqsave(&wl->irq_lock, flags);
-       B43_WARN_ON(wl->vif != vif);
-       if (conf->bssid)
-               memcpy(wl->bssid, conf->bssid, ETH_ALEN);
-       else
-               memset(wl->bssid, 0, ETH_ALEN);
-       if (b43_status(dev) >= B43_STAT_INITIALIZED) {
-               if (b43_is_mode(wl, NL80211_IFTYPE_AP) ||
-                   b43_is_mode(wl, NL80211_IFTYPE_MESH_POINT)) {
-                       B43_WARN_ON(vif->type != wl->if_type);
-                       if (conf->changed & IEEE80211_IFCC_BEACON)
-                               b43_update_templates(wl);
-               } else if (b43_is_mode(wl, NL80211_IFTYPE_ADHOC)) {
-                       if (conf->changed & IEEE80211_IFCC_BEACON)
-                               b43_update_templates(wl);
-               }
-               b43_write_mac_bssid_templates(dev);
-       }
-       spin_unlock_irqrestore(&wl->irq_lock, flags);
-       mutex_unlock(&wl->mutex);
-
-       return 0;
-}
-
 /* Locking: wl->mutex */
 static void b43_wireless_core_stop(struct b43_wldev *dev)
 {
@@ -3793,7 +3794,7 @@ static void b43_wireless_core_stop(struct b43_wldev *dev)
         * setting the status to INITIALIZED, as the interrupt handler
         * won't care about IRQs then. */
        spin_lock_irqsave(&wl->irq_lock, flags);
-       dev->irq_savedstate = b43_interrupt_disable(dev, B43_IRQ_ALL);
+       b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, 0);
        b43_read32(dev, B43_MMIO_GEN_IRQ_MASK); /* flush */
        spin_unlock_irqrestore(&wl->irq_lock, flags);
        b43_synchronize_irq(dev);
@@ -3834,7 +3835,7 @@ static int b43_wireless_core_start(struct b43_wldev *dev)
 
        /* Start data flow (TX/RX). */
        b43_mac_enable(dev);
-       b43_interrupt_enable(dev, dev->irq_savedstate);
+       b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, dev->irq_mask);
 
        /* Start maintainance work */
        b43_periodic_tasks_setup(dev);
@@ -3997,9 +3998,9 @@ static void setup_struct_wldev_for_init(struct b43_wldev *dev)
        /* IRQ related flags */
        dev->irq_reason = 0;
        memset(dev->dma_reason, 0, sizeof(dev->dma_reason));
-       dev->irq_savedstate = B43_IRQ_MASKTEMPLATE;
+       dev->irq_mask = B43_IRQ_MASKTEMPLATE;
        if (b43_modparam_verbose < B43_VERBOSITY_DEBUG)
-               dev->irq_savedstate &= ~B43_IRQ_PHY_TXERR;
+               dev->irq_mask &= ~B43_IRQ_PHY_TXERR;
 
        dev->mac_suspended = 1;
 
@@ -4326,7 +4327,6 @@ static int b43_op_start(struct ieee80211_hw *hw)
        struct b43_wldev *dev = wl->current_dev;
        int did_init = 0;
        int err = 0;
-       bool do_rfkill_exit = 0;
 
        /* Kill all old instance specific information to make sure
         * the card won't use it in the short timeframe between start
@@ -4340,18 +4340,12 @@ static int b43_op_start(struct ieee80211_hw *hw)
        wl->beacon1_uploaded = 0;
        wl->beacon_templates_virgin = 1;
 
-       /* First register RFkill.
-        * LEDs that are registered later depend on it. */
-       b43_rfkill_init(dev);
-
        mutex_lock(&wl->mutex);
 
        if (b43_status(dev) < B43_STAT_INITIALIZED) {
                err = b43_wireless_core_init(dev);
-               if (err) {
-                       do_rfkill_exit = 1;
+               if (err)
                        goto out_mutex_unlock;
-               }
                did_init = 1;
        }
 
@@ -4360,17 +4354,16 @@ static int b43_op_start(struct ieee80211_hw *hw)
                if (err) {
                        if (did_init)
                                b43_wireless_core_exit(dev);
-                       do_rfkill_exit = 1;
                        goto out_mutex_unlock;
                }
        }
 
+       /* XXX: only do if device doesn't support rfkill irq */
+       wiphy_rfkill_start_polling(hw->wiphy);
+
  out_mutex_unlock:
        mutex_unlock(&wl->mutex);
 
-       if (do_rfkill_exit)
-               b43_rfkill_exit(dev);
-
        return err;
 }
 
@@ -4379,7 +4372,6 @@ static void b43_op_stop(struct ieee80211_hw *hw)
        struct b43_wl *wl = hw_to_b43_wl(hw);
        struct b43_wldev *dev = wl->current_dev;
 
-       b43_rfkill_exit(dev);
        cancel_work_sync(&(wl->beacon_update_trigger));
 
        mutex_lock(&wl->mutex);
@@ -4449,7 +4441,6 @@ static const struct ieee80211_ops b43_hw_ops = {
        .remove_interface       = b43_op_remove_interface,
        .config                 = b43_op_config,
        .bss_info_changed       = b43_op_bss_info_changed,
-       .config_interface       = b43_op_config_interface,
        .configure_filter       = b43_op_configure_filter,
        .set_key                = b43_op_set_key,
        .get_stats              = b43_op_get_stats,
@@ -4462,6 +4453,7 @@ static const struct ieee80211_ops b43_hw_ops = {
        .sta_notify             = b43_op_sta_notify,
        .sw_scan_start          = b43_op_sw_scan_start_notifier,
        .sw_scan_complete       = b43_op_sw_scan_complete_notifier,
+       .rfkill_poll            = b43_rfkill_poll,
 };
 
 /* Hard-reset the chip. Do not call this directly.
@@ -4764,6 +4756,7 @@ static int b43_wireless_init(struct ssb_device *dev)
                b43err(NULL, "Could not allocate ieee80211 device\n");
                goto out;
        }
+       wl = hw_to_b43_wl(hw);
 
        /* fill hw info */
        hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
@@ -4777,7 +4770,8 @@ static int b43_wireless_init(struct ssb_device *dev)
                BIT(NL80211_IFTYPE_WDS) |
                BIT(NL80211_IFTYPE_ADHOC);
 
-       hw->queues = b43_modparam_qos ? 4 : 1;
+       hw->queues = modparam_qos ? 4 : 1;
+       wl->mac80211_initially_registered_queues = hw->queues;
        hw->max_rates = 2;
        SET_IEEE80211_DEV(hw, dev->dev);
        if (is_valid_ether_addr(sprom->et1mac))
@@ -4785,9 +4779,7 @@ static int b43_wireless_init(struct ssb_device *dev)
        else
                SET_IEEE80211_PERM_ADDR(hw, sprom->il0mac);
 
-       /* Get and initialize struct b43_wl */
-       wl = hw_to_b43_wl(hw);
-       memset(wl, 0, sizeof(*wl));
+       /* Initialize struct b43_wl */
        wl->hw = hw;
        spin_lock_init(&wl->irq_lock);
        rwlock_init(&wl->tx_lock);
@@ -4853,8 +4845,13 @@ static void b43_remove(struct ssb_device *dev)
        cancel_work_sync(&wldev->restart_work);
 
        B43_WARN_ON(!wl);
-       if (wl->current_dev == wldev)
+       if (wl->current_dev == wldev) {
+               /* Restore the queues count before unregistering, because firmware detect
+                * might have modified it. Restoring is important, so the networking
+                * stack can properly free resources. */
+               wl->hw->queues = wl->mac80211_initially_registered_queues;
                ieee80211_unregister_hw(wl->hw);
+       }
 
        b43_one_core_detach(dev);
 
@@ -4949,7 +4946,7 @@ static struct ssb_driver b43_ssb_driver = {
 static void b43_print_driverinfo(void)
 {
        const char *feat_pci = "", *feat_pcmcia = "", *feat_nphy = "",
-                  *feat_leds = "", *feat_rfkill = "";
+                  *feat_leds = "";
 
 #ifdef CONFIG_B43_PCI_AUTOSELECT
        feat_pci = "P";
@@ -4962,15 +4959,12 @@ static void b43_print_driverinfo(void)
 #endif
 #ifdef CONFIG_B43_LEDS
        feat_leds = "L";
-#endif
-#ifdef CONFIG_B43_RFKILL
-       feat_rfkill = "R";
 #endif
        printk(KERN_INFO "Broadcom 43xx driver loaded "
-              "[ Features: %s%s%s%s%s, Firmware-ID: "
+              "[ Features: %s%s%s%s, Firmware-ID: "
               B43_SUPPORTED_FIRMWARE_ID " ]\n",
               feat_pci, feat_pcmcia, feat_nphy,
-              feat_leds, feat_rfkill);
+              feat_leds);
 }
 
 static int __init b43_init(void)
index 40abcf5d1b4307d27fb0c6d8d48cb29fda85ee15..950fb1b0546d402ecd0674bf8815ee8340ed4a95 100644 (file)
@@ -39,7 +39,6 @@
 #define PAD_BYTES(nr_bytes)            P4D_BYTES( __LINE__ , (nr_bytes))
 
 
-extern int b43_modparam_qos;
 extern int b43_modparam_verbose;
 
 /* Logmessage verbosity levels. Update the b43_modparam_verbose helptext, if
index c836c077d51df3f61aa2438a8e8a14066f7c3c94..816e028a2620c9b43d06f8b615e11a7c518ddb8a 100644 (file)
@@ -480,11 +480,11 @@ static bool b43_aphy_op_supports_hwpctl(struct b43_wldev *dev)
 }
 
 static void b43_aphy_op_software_rfkill(struct b43_wldev *dev,
-                                       enum rfkill_state state)
+                                       bool blocked)
 {
        struct b43_phy *phy = &dev->phy;
 
-       if (state == RFKILL_STATE_UNBLOCKED) {
+       if (!blocked) {
                if (phy->radio_on)
                        return;
                b43_radio_write16(dev, 0x0004, 0x00C0);
index e176b6e0d9cf08f26dae49baa5b0d729ad13db1d..6d241622210e2d302574679fc656c1d9458973db 100644 (file)
@@ -84,7 +84,7 @@ int b43_phy_init(struct b43_wldev *dev)
 
        phy->channel = ops->get_default_chan(dev);
 
-       ops->software_rfkill(dev, RFKILL_STATE_UNBLOCKED);
+       ops->software_rfkill(dev, false);
        err = ops->init(dev);
        if (err) {
                b43err(dev->wl, "PHY init failed\n");
@@ -104,7 +104,7 @@ err_phy_exit:
        if (ops->exit)
                ops->exit(dev);
 err_block_rf:
-       ops->software_rfkill(dev, RFKILL_STATE_SOFT_BLOCKED);
+       ops->software_rfkill(dev, true);
 
        return err;
 }
@@ -113,7 +113,7 @@ void b43_phy_exit(struct b43_wldev *dev)
 {
        const struct b43_phy_operations *ops = dev->phy.ops;
 
-       ops->software_rfkill(dev, RFKILL_STATE_SOFT_BLOCKED);
+       ops->software_rfkill(dev, true);
        if (ops->exit)
                ops->exit(dev);
 }
@@ -295,18 +295,13 @@ err_restore_cookie:
        return err;
 }
 
-void b43_software_rfkill(struct b43_wldev *dev, enum rfkill_state state)
+void b43_software_rfkill(struct b43_wldev *dev, bool blocked)
 {
        struct b43_phy *phy = &dev->phy;
 
-       if (state == RFKILL_STATE_HARD_BLOCKED) {
-               /* We cannot hardware-block the device */
-               state = RFKILL_STATE_SOFT_BLOCKED;
-       }
-
        b43_mac_suspend(dev);
-       phy->ops->software_rfkill(dev, state);
-       phy->radio_on = (state == RFKILL_STATE_UNBLOCKED);
+       phy->ops->software_rfkill(dev, blocked);
+       phy->radio_on = !blocked;
        b43_mac_enable(dev);
 }
 
index b2d99101947be7062d31ecaffbbea4a3b7af9b5a..44cc918e4fc6ee097d4721b22ea18af32a3721a0 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef LINUX_B43_PHY_COMMON_H_
 #define LINUX_B43_PHY_COMMON_H_
 
-#include <linux/rfkill.h>
+#include <linux/types.h>
 
 struct b43_wldev;
 
@@ -159,7 +159,7 @@ struct b43_phy_operations {
 
        /* Radio */
        bool (*supports_hwpctl)(struct b43_wldev *dev);
-       void (*software_rfkill)(struct b43_wldev *dev, enum rfkill_state state);
+       void (*software_rfkill)(struct b43_wldev *dev, bool blocked);
        void (*switch_analog)(struct b43_wldev *dev, bool on);
        int (*switch_channel)(struct b43_wldev *dev, unsigned int new_channel);
        unsigned int (*get_default_chan)(struct b43_wldev *dev);
@@ -364,7 +364,7 @@ int b43_switch_channel(struct b43_wldev *dev, unsigned int new_channel);
 /**
  * b43_software_rfkill - Turn the radio ON or OFF in software.
  */
-void b43_software_rfkill(struct b43_wldev *dev, enum rfkill_state state);
+void b43_software_rfkill(struct b43_wldev *dev, bool blocked);
 
 /**
  * b43_phy_txpower_check - Check TX power output.
index e7b98f013b0fa87d571df9af42a1e2e4d48fd1a3..5300232449f689f2d958c614a5c3aa566ac6024d 100644 (file)
@@ -2592,7 +2592,7 @@ static bool b43_gphy_op_supports_hwpctl(struct b43_wldev *dev)
 }
 
 static void b43_gphy_op_software_rfkill(struct b43_wldev *dev,
-                                       enum rfkill_state state)
+                                       bool blocked)
 {
        struct b43_phy *phy = &dev->phy;
        struct b43_phy_g *gphy = phy->g;
@@ -2600,7 +2600,7 @@ static void b43_gphy_op_software_rfkill(struct b43_wldev *dev,
 
        might_sleep();
 
-       if (state == RFKILL_STATE_UNBLOCKED) {
+       if (!blocked) {
                /* Turn radio ON */
                if (phy->radio_on)
                        return;
index 58e319d6b1ed567c6846b6cd8430f999efd0e65f..ea0d3a3a6a647036222b6160a9f1ae91de4e9493 100644 (file)
@@ -488,7 +488,7 @@ static void b43_lpphy_op_radio_write(struct b43_wldev *dev, u16 reg, u16 value)
 }
 
 static void b43_lpphy_op_software_rfkill(struct b43_wldev *dev,
-                                        enum rfkill_state state)
+                                        bool blocked)
 {
        //TODO
 }
index 8bcfda5f3f0730e7691ed246041ef399fadb6e7d..be7b5604947b0d6b052c3486c559d7c84fc21fa4 100644 (file)
@@ -579,7 +579,7 @@ static void b43_nphy_op_radio_write(struct b43_wldev *dev, u16 reg, u16 value)
 }
 
 static void b43_nphy_op_software_rfkill(struct b43_wldev *dev,
-                                       enum rfkill_state state)
+                                       bool blocked)
 {//TODO
 }
 
index 8cd9776752e691407763318599cf1e38660c5f3c..69138e8c1db6778e0c8a2d9bd665b1a609f236e0 100644 (file)
@@ -313,7 +313,7 @@ static struct b43_pio_txqueue *select_queue_by_priority(struct b43_wldev *dev,
 {
        struct b43_pio_txqueue *q;
 
-       if (b43_modparam_qos) {
+       if (dev->qos_enabled) {
                /* 0 = highest priority */
                switch (queue_prio) {
                default:
index afad423586931ed618c6ea32445c4df17987b0e2..31e55999893f7084803221af05cb741e443ecf11 100644 (file)
 
 */
 
-#include "rfkill.h"
 #include "b43.h"
-#include "phy_common.h"
-
-#include <linux/kmod.h>
 
 
 /* Returns TRUE, if the radio is enabled in hardware. */
-static bool b43_is_hw_radio_enabled(struct b43_wldev *dev)
+bool b43_is_hw_radio_enabled(struct b43_wldev *dev)
 {
        if (dev->phy.rev >= 3) {
                if (!(b43_read32(dev, B43_MMIO_RADIO_HWENABLED_HI)
@@ -45,166 +41,39 @@ static bool b43_is_hw_radio_enabled(struct b43_wldev *dev)
 }
 
 /* The poll callback for the hardware button. */
-static void b43_rfkill_poll(struct input_polled_dev *poll_dev)
+void b43_rfkill_poll(struct ieee80211_hw *hw)
 {
-       struct b43_wldev *dev = poll_dev->private;
-       struct b43_wl *wl = dev->wl;
+       struct b43_wl *wl = hw_to_b43_wl(hw);
+       struct b43_wldev *dev = wl->current_dev;
+       struct ssb_bus *bus = dev->dev->bus;
        bool enabled;
-       bool report_change = 0;
+       bool brought_up = false;
 
        mutex_lock(&wl->mutex);
        if (unlikely(b43_status(dev) < B43_STAT_INITIALIZED)) {
-               mutex_unlock(&wl->mutex);
-               return;
+               if (ssb_bus_powerup(bus, 0)) {
+                       mutex_unlock(&wl->mutex);
+                       return;
+               }
+               ssb_device_enable(dev->dev, 0);
+               brought_up = true;
        }
+
        enabled = b43_is_hw_radio_enabled(dev);
+
        if (unlikely(enabled != dev->radio_hw_enable)) {
                dev->radio_hw_enable = enabled;
-               report_change = 1;
                b43info(wl, "Radio hardware status changed to %s\n",
                        enabled ? "ENABLED" : "DISABLED");
+               wiphy_rfkill_set_hw_state(hw->wiphy, !enabled);
+               if (enabled != dev->phy.radio_on)
+                       b43_software_rfkill(dev, !enabled);
        }
-       mutex_unlock(&wl->mutex);
 
-       /* send the radio switch event to the system - note both a key press
-        * and a release are required */
-       if (unlikely(report_change)) {
-               input_report_key(poll_dev->input, KEY_WLAN, 1);
-               input_report_key(poll_dev->input, KEY_WLAN, 0);
+       if (brought_up) {
+               ssb_device_disable(dev->dev, 0);
+               ssb_bus_may_powerdown(bus);
        }
-}
-
-/* Called when the RFKILL toggled in software. */
-static int b43_rfkill_soft_toggle(void *data, enum rfkill_state state)
-{
-       struct b43_wldev *dev = data;
-       struct b43_wl *wl = dev->wl;
-       int err = -EBUSY;
 
-       if (!wl->rfkill.registered)
-               return 0;
-
-       mutex_lock(&wl->mutex);
-       if (b43_status(dev) < B43_STAT_INITIALIZED)
-               goto out_unlock;
-       err = 0;
-       switch (state) {
-       case RFKILL_STATE_UNBLOCKED:
-               if (!dev->radio_hw_enable) {
-                       /* No luck. We can't toggle the hardware RF-kill
-                        * button from software. */
-                       err = -EBUSY;
-                       goto out_unlock;
-               }
-               if (!dev->phy.radio_on)
-                       b43_software_rfkill(dev, state);
-               break;
-       case RFKILL_STATE_SOFT_BLOCKED:
-               if (dev->phy.radio_on)
-                       b43_software_rfkill(dev, state);
-               break;
-       default:
-               b43warn(wl, "Received unexpected rfkill state %d.\n", state);
-               break;
-       }
-out_unlock:
        mutex_unlock(&wl->mutex);
-
-       return err;
-}
-
-char *b43_rfkill_led_name(struct b43_wldev *dev)
-{
-       struct b43_rfkill *rfk = &(dev->wl->rfkill);
-
-       if (!rfk->registered)
-               return NULL;
-       return rfkill_get_led_name(rfk->rfkill);
-}
-
-void b43_rfkill_init(struct b43_wldev *dev)
-{
-       struct b43_wl *wl = dev->wl;
-       struct b43_rfkill *rfk = &(wl->rfkill);
-       int err;
-
-       rfk->registered = 0;
-
-       rfk->rfkill = rfkill_allocate(dev->dev->dev, RFKILL_TYPE_WLAN);
-       if (!rfk->rfkill)
-               goto out_error;
-       snprintf(rfk->name, sizeof(rfk->name),
-                "b43-%s", wiphy_name(wl->hw->wiphy));
-       rfk->rfkill->name = rfk->name;
-       rfk->rfkill->state = RFKILL_STATE_UNBLOCKED;
-       rfk->rfkill->data = dev;
-       rfk->rfkill->toggle_radio = b43_rfkill_soft_toggle;
-       rfk->rfkill->user_claim_unsupported = 1;
-
-       rfk->poll_dev = input_allocate_polled_device();
-       if (!rfk->poll_dev) {
-               rfkill_free(rfk->rfkill);
-               goto err_freed_rfk;
-       }
-
-       rfk->poll_dev->private = dev;
-       rfk->poll_dev->poll = b43_rfkill_poll;
-       rfk->poll_dev->poll_interval = 1000; /* msecs */
-
-       rfk->poll_dev->input->name = rfk->name;
-       rfk->poll_dev->input->id.bustype = BUS_HOST;
-       rfk->poll_dev->input->id.vendor = dev->dev->bus->boardinfo.vendor;
-       rfk->poll_dev->input->evbit[0] = BIT(EV_KEY);
-       set_bit(KEY_WLAN, rfk->poll_dev->input->keybit);
-
-       err = rfkill_register(rfk->rfkill);
-       if (err)
-               goto err_free_polldev;
-
-#ifdef CONFIG_RFKILL_INPUT_MODULE
-       /* B43 RF-kill isn't useful without the rfkill-input subsystem.
-        * Try to load the module. */
-       err = request_module("rfkill-input");
-       if (err)
-               b43warn(wl, "Failed to load the rfkill-input module. "
-                       "The built-in radio LED will not work.\n");
-#endif /* CONFIG_RFKILL_INPUT */
-
-#if !defined(CONFIG_RFKILL_INPUT) && !defined(CONFIG_RFKILL_INPUT_MODULE)
-       b43warn(wl, "The rfkill-input subsystem is not available. "
-               "The built-in radio LED will not work.\n");
-#endif
-
-       err = input_register_polled_device(rfk->poll_dev);
-       if (err)
-               goto err_unreg_rfk;
-
-       rfk->registered = 1;
-
-       return;
-err_unreg_rfk:
-       rfkill_unregister(rfk->rfkill);
-err_free_polldev:
-       input_free_polled_device(rfk->poll_dev);
-       rfk->poll_dev = NULL;
-err_freed_rfk:
-       rfk->rfkill = NULL;
-out_error:
-       rfk->registered = 0;
-       b43warn(wl, "RF-kill button init failed\n");
-}
-
-void b43_rfkill_exit(struct b43_wldev *dev)
-{
-       struct b43_rfkill *rfk = &(dev->wl->rfkill);
-
-       if (!rfk->registered)
-               return;
-       rfk->registered = 0;
-
-       input_unregister_polled_device(rfk->poll_dev);
-       rfkill_unregister(rfk->rfkill);
-       input_free_polled_device(rfk->poll_dev);
-       rfk->poll_dev = NULL;
-       rfk->rfkill = NULL;
 }
index adacf936d815be2170b973da1cbb997fff7b974b..f046c3ca0519bde676955a74b4074c26e8a39caf 100644 (file)
@@ -1,52 +1,11 @@
 #ifndef B43_RFKILL_H_
 #define B43_RFKILL_H_
 
+struct ieee80211_hw;
 struct b43_wldev;
 
+void b43_rfkill_poll(struct ieee80211_hw *hw);
 
-#ifdef CONFIG_B43_RFKILL
-
-#include <linux/rfkill.h>
-#include <linux/input-polldev.h>
-
-
-struct b43_rfkill {
-       /* The RFKILL subsystem data structure */
-       struct rfkill *rfkill;
-       /* The poll device for the RFKILL input button */
-       struct input_polled_dev *poll_dev;
-       /* Did initialization succeed? Used for freeing. */
-       bool registered;
-       /* The unique name of this rfkill switch */
-       char name[sizeof("b43-phy4294967295")];
-};
-
-/* The init function returns void, because we are not interested
- * in failing the b43 init process when rfkill init failed. */
-void b43_rfkill_init(struct b43_wldev *dev);
-void b43_rfkill_exit(struct b43_wldev *dev);
-
-char * b43_rfkill_led_name(struct b43_wldev *dev);
-
-
-#else /* CONFIG_B43_RFKILL */
-/* No RFKILL support. */
-
-struct b43_rfkill {
-       /* empty */
-};
-
-static inline void b43_rfkill_init(struct b43_wldev *dev)
-{
-}
-static inline void b43_rfkill_exit(struct b43_wldev *dev)
-{
-}
-static inline char * b43_rfkill_led_name(struct b43_wldev *dev)
-{
-       return NULL;
-}
-
-#endif /* CONFIG_B43_RFKILL */
+bool b43_is_hw_radio_enabled(struct b43_wldev *dev);
 
 #endif /* B43_RFKILL_H_ */
index a63d88841df86034cf011f93c85a2acce02e3448..55f36a7254d98515b7d61b22152fe10c4a567255 100644 (file)
@@ -118,7 +118,6 @@ u8 b43_plcp_get_ratecode_ofdm(const u8 bitrate)
 void b43_generate_plcp_hdr(struct b43_plcp_hdr4 *plcp,
                           const u16 octets, const u8 bitrate)
 {
-       __le32 *data = &(plcp->data);
        __u8 *raw = plcp->raw;
 
        if (b43_is_ofdm_rate(bitrate)) {
@@ -127,7 +126,7 @@ void b43_generate_plcp_hdr(struct b43_plcp_hdr4 *plcp,
                d = b43_plcp_get_ratecode_ofdm(bitrate);
                B43_WARN_ON(octets & 0xF000);
                d |= (octets << 5);
-               *data = cpu_to_le32(d);
+               plcp->data = cpu_to_le32(d);
        } else {
                u32 plen;
 
@@ -141,7 +140,7 @@ void b43_generate_plcp_hdr(struct b43_plcp_hdr4 *plcp,
                                raw[1] = 0x04;
                } else
                        raw[1] = 0x04;
-               *data |= cpu_to_le32(plen << 16);
+               plcp->data |= cpu_to_le32(plen << 16);
                raw[0] = b43_plcp_get_ratecode_cck(bitrate);
        }
 }
index aef2298d37ac2e7678a700677716959e76915ab0..94a46347805370ccc99e51ea651f6999893c227a 100644 (file)
@@ -3,7 +3,6 @@ config B43LEGACY
        depends on SSB_POSSIBLE && MAC80211 && WLAN_80211 && HAS_DMA
        select SSB
        select FW_LOADER
-       select HW_RANDOM
        ---help---
          b43legacy is a driver for 802.11b devices from Broadcom (BCM4301 and
          BCM4303) and early model 802.11g chips (BCM4306 Ver. 2) used in the
@@ -43,12 +42,11 @@ config B43LEGACY_LEDS
        depends on B43LEGACY && MAC80211_LEDS && (LEDS_CLASS = y || LEDS_CLASS = B43LEGACY)
        default y
 
-# RFKILL support
-# This config option automatically enables b43legacy RFKILL support,
-# if it's possible.
-config B43LEGACY_RFKILL
+# This config option automatically enables b43 HW-RNG support,
+# if the HW-RNG core is enabled.
+config B43LEGACY_HWRNG
        bool
-       depends on B43LEGACY && (RFKILL = y || RFKILL = B43LEGACY) && RFKILL_INPUT && (INPUT_POLLDEV = y || INPUT_POLLDEV = B43LEGACY)
+       depends on B43LEGACY && (HW_RANDOM = y || HW_RANDOM = B43LEGACY)
        default y
 
 config B43LEGACY_DEBUG
index 80cdb73bd140c4b42a37d464ce8f676211c5f612..227a77e8436215944948079bb631311cfe5c41be 100644 (file)
@@ -6,7 +6,7 @@ b43legacy-y                             += radio.o
 b43legacy-y                            += sysfs.o
 b43legacy-y                            += xmit.o
 # b43 RFKILL button support
-b43legacy-$(CONFIG_B43LEGACY_RFKILL)   += rfkill.o
+b43legacy-y                            += rfkill.o
 # b43legacy LED support
 b43legacy-$(CONFIG_B43LEGACY_LEDS)     += leds.o
 # b43legacy debugging
index 97b0e06dfe219bf6a4614bcabed70efaa67521b4..77fda148ac4684b904e996095b1e7c68d3fa9469 100644 (file)
@@ -59,7 +59,8 @@
 #define B43legacy_MMIO_XMITSTAT_1              0x174
 #define B43legacy_MMIO_REV3PLUS_TSF_LOW        0x180 /* core rev >= 3 only */
 #define B43legacy_MMIO_REV3PLUS_TSF_HIGH       0x184 /* core rev >= 3 only */
-
+#define B43legacy_MMIO_TSF_CFP_REP     0x188
+#define B43legacy_MMIO_TSF_CFP_START   0x18C
 /* 32-bit DMA */
 #define B43legacy_MMIO_DMA32_BASE0     0x200
 #define B43legacy_MMIO_DMA32_BASE1     0x220
 
 #define B43legacy_IRQ_ALL              0xFFFFFFFF
 #define B43legacy_IRQ_MASKTEMPLATE     (B43legacy_IRQ_MAC_SUSPENDED |  \
-                                        B43legacy_IRQ_BEACON |         \
                                         B43legacy_IRQ_TBTT_INDI |      \
                                         B43legacy_IRQ_ATIM_END |       \
                                         B43legacy_IRQ_PMQ |            \
@@ -596,12 +596,11 @@ struct b43legacy_wl {
        /* Stats about the wireless interface */
        struct ieee80211_low_level_stats ieee_stats;
 
+#ifdef CONFIG_B43LEGACY_HWRNG
        struct hwrng rng;
        u8 rng_initialized;
        char rng_name[30 + 1];
-
-       /* The RF-kill button */
-       struct b43legacy_rfkill rfkill;
+#endif
 
        /* List of all wireless devices on this chip */
        struct list_head devlist;
@@ -614,6 +613,8 @@ struct b43legacy_wl {
        struct sk_buff *current_beacon;
        bool beacon0_uploaded;
        bool beacon1_uploaded;
+       bool beacon_templates_virgin; /* Never wrote the templates? */
+       struct work_struct beacon_update_trigger;
 };
 
 /* Pointers to the firmware data and meta information about it. */
@@ -690,8 +691,8 @@ struct b43legacy_wldev {
        /* Reason code of the last interrupt. */
        u32 irq_reason;
        u32 dma_reason[6];
-       /* saved irq enable/disable state bitfield. */
-       u32 irq_savedstate;
+       /* The currently active generic-interrupt mask. */
+       u32 irq_mask;
        /* Link Quality calculation context. */
        struct b43legacy_noise_calculation noisecalc;
        /* if > 0 MAC is suspended. if == 0 MAC is enabled. */
index 3ea55b18c7001d60518ad46b840faea9590d5ba5..37e9be893560a19e938ea026044d879f31932238 100644 (file)
@@ -28,6 +28,7 @@
 
 #include "b43legacy.h"
 #include "leds.h"
+#include "rfkill.h"
 
 
 static void b43legacy_led_turn_on(struct b43legacy_wldev *dev, u8 led_index,
@@ -86,7 +87,8 @@ static void b43legacy_led_brightness_set(struct led_classdev *led_dev,
 
 static int b43legacy_register_led(struct b43legacy_wldev *dev,
                                  struct b43legacy_led *led,
-                                 const char *name, char *default_trigger,
+                                 const char *name,
+                                 const char *default_trigger,
                                  u8 led_index, bool activelow)
 {
        int err;
@@ -163,10 +165,10 @@ static void b43legacy_map_led(struct b43legacy_wldev *dev,
                snprintf(name, sizeof(name),
                         "b43legacy-%s::radio", wiphy_name(hw->wiphy));
                b43legacy_register_led(dev, &dev->led_radio, name,
-                                b43legacy_rfkill_led_name(dev),
+                                ieee80211_get_radio_led_name(hw),
                                 led_index, activelow);
-               /* Sync the RF-kill LED state with the switch state. */
-               if (dev->radio_hw_enable)
+               /* Sync the RF-kill LED state with radio and switch states. */
+               if (dev->phy.radio_on && b43legacy_is_hw_radio_enabled(dev))
                        b43legacy_led_turn_on(dev, led_index, activelow);
                break;
        case B43legacy_LED_WEIRD:
index 879edc786713710fdde14c61257a61e5c4798645..e5136fb65dddb066f3d6ab65b0671bf8386c3b97 100644 (file)
@@ -583,35 +583,6 @@ static void b43legacy_short_slot_timing_disable(struct b43legacy_wldev *dev)
        b43legacy_set_slot_time(dev, 20);
 }
 
-/* Enable a Generic IRQ. "mask" is the mask of which IRQs to enable.
- * Returns the _previously_ enabled IRQ mask.
- */
-static inline u32 b43legacy_interrupt_enable(struct b43legacy_wldev *dev,
-                                            u32 mask)
-{
-       u32 old_mask;
-
-       old_mask = b43legacy_read32(dev, B43legacy_MMIO_GEN_IRQ_MASK);
-       b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_MASK, old_mask |
-                         mask);
-
-       return old_mask;
-}
-
-/* Disable a Generic IRQ. "mask" is the mask of which IRQs to disable.
- * Returns the _previously_ enabled IRQ mask.
- */
-static inline u32 b43legacy_interrupt_disable(struct b43legacy_wldev *dev,
-                                             u32 mask)
-{
-       u32 old_mask;
-
-       old_mask = b43legacy_read32(dev, B43legacy_MMIO_GEN_IRQ_MASK);
-       b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_MASK, old_mask & ~mask);
-
-       return old_mask;
-}
-
 /* Synchronize IRQ top- and bottom-half.
  * IRQs must be masked before calling this.
  * This must not be called with the irq_lock held.
@@ -955,23 +926,54 @@ static void b43legacy_write_template_common(struct b43legacy_wldev *dev,
                              size + sizeof(struct b43legacy_plcp_hdr6));
 }
 
+/* Convert a b43legacy antenna number value to the PHY TX control value. */
+static u16 b43legacy_antenna_to_phyctl(int antenna)
+{
+       switch (antenna) {
+       case B43legacy_ANTENNA0:
+               return B43legacy_TX4_PHY_ANT0;
+       case B43legacy_ANTENNA1:
+               return B43legacy_TX4_PHY_ANT1;
+       }
+       return B43legacy_TX4_PHY_ANTLAST;
+}
+
 static void b43legacy_write_beacon_template(struct b43legacy_wldev *dev,
                                            u16 ram_offset,
-                                           u16 shm_size_offset, u8 rate)
+                                           u16 shm_size_offset)
 {
 
        unsigned int i, len, variable_len;
        const struct ieee80211_mgmt *bcn;
        const u8 *ie;
        bool tim_found = 0;
+       unsigned int rate;
+       u16 ctl;
+       int antenna;
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(dev->wl->current_beacon);
 
        bcn = (const struct ieee80211_mgmt *)(dev->wl->current_beacon->data);
        len = min((size_t)dev->wl->current_beacon->len,
                  0x200 - sizeof(struct b43legacy_plcp_hdr6));
+       rate = ieee80211_get_tx_rate(dev->wl->hw, info)->hw_value;
 
        b43legacy_write_template_common(dev, (const u8 *)bcn, len, ram_offset,
                                        shm_size_offset, rate);
 
+       /* Write the PHY TX control parameters. */
+       antenna = B43legacy_ANTENNA_DEFAULT;
+       antenna = b43legacy_antenna_to_phyctl(antenna);
+       ctl = b43legacy_shm_read16(dev, B43legacy_SHM_SHARED,
+                                  B43legacy_SHM_SH_BEACPHYCTL);
+       /* We can't send beacons with short preamble. Would get PHY errors. */
+       ctl &= ~B43legacy_TX4_PHY_SHORTPRMBL;
+       ctl &= ~B43legacy_TX4_PHY_ANT;
+       ctl &= ~B43legacy_TX4_PHY_ENC;
+       ctl |= antenna;
+       ctl |= B43legacy_TX4_PHY_ENC_CCK;
+       b43legacy_shm_write16(dev, B43legacy_SHM_SHARED,
+                             B43legacy_SHM_SH_BEACPHYCTL, ctl);
+
        /* Find the position of the TIM and the DTIM_period value
         * and write them to SHM. */
        ie = bcn->u.beacon.variable;
@@ -1013,7 +1015,8 @@ static void b43legacy_write_beacon_template(struct b43legacy_wldev *dev,
                b43legacywarn(dev->wl, "Did not find a valid TIM IE in the "
                              "beacon template packet. AP or IBSS operation "
                              "may be broken.\n");
-       }
+       } else
+               b43legacydbg(dev->wl, "Updated beacon template\n");
 }
 
 static void b43legacy_write_probe_resp_plcp(struct b43legacy_wldev *dev,
@@ -1025,7 +1028,7 @@ static void b43legacy_write_probe_resp_plcp(struct b43legacy_wldev *dev,
        __le16 dur;
 
        plcp.data = 0;
-       b43legacy_generate_plcp_hdr(&plcp, size + FCS_LEN, rate->bitrate);
+       b43legacy_generate_plcp_hdr(&plcp, size + FCS_LEN, rate->hw_value);
        dur = ieee80211_generic_frame_duration(dev->wl->hw,
                                               dev->wl->vif,
                                               size,
@@ -1129,10 +1132,103 @@ static void b43legacy_write_probe_resp_template(struct b43legacy_wldev *dev,
                   0x200 - sizeof(struct b43legacy_plcp_hdr6));
        b43legacy_write_template_common(dev, probe_resp_data,
                                        size, ram_offset,
-                                       shm_size_offset, rate->bitrate);
+                                       shm_size_offset, rate->hw_value);
        kfree(probe_resp_data);
 }
 
+static void b43legacy_upload_beacon0(struct b43legacy_wldev *dev)
+{
+       struct b43legacy_wl *wl = dev->wl;
+
+       if (wl->beacon0_uploaded)
+               return;
+       b43legacy_write_beacon_template(dev, 0x68, 0x18);
+       /* FIXME: Probe resp upload doesn't really belong here,
+        *        but we don't use that feature anyway. */
+       b43legacy_write_probe_resp_template(dev, 0x268, 0x4A,
+                                     &__b43legacy_ratetable[3]);
+       wl->beacon0_uploaded = 1;
+}
+
+static void b43legacy_upload_beacon1(struct b43legacy_wldev *dev)
+{
+       struct b43legacy_wl *wl = dev->wl;
+
+       if (wl->beacon1_uploaded)
+               return;
+       b43legacy_write_beacon_template(dev, 0x468, 0x1A);
+       wl->beacon1_uploaded = 1;
+}
+
+static void handle_irq_beacon(struct b43legacy_wldev *dev)
+{
+       struct b43legacy_wl *wl = dev->wl;
+       u32 cmd, beacon0_valid, beacon1_valid;
+
+       if (!b43legacy_is_mode(wl, NL80211_IFTYPE_AP))
+               return;
+
+       /* This is the bottom half of the asynchronous beacon update. */
+
+       /* Ignore interrupt in the future. */
+       dev->irq_mask &= ~B43legacy_IRQ_BEACON;
+
+       cmd = b43legacy_read32(dev, B43legacy_MMIO_MACCMD);
+       beacon0_valid = (cmd & B43legacy_MACCMD_BEACON0_VALID);
+       beacon1_valid = (cmd & B43legacy_MACCMD_BEACON1_VALID);
+
+       /* Schedule interrupt manually, if busy. */
+       if (beacon0_valid && beacon1_valid) {
+               b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_REASON, B43legacy_IRQ_BEACON);
+               dev->irq_mask |= B43legacy_IRQ_BEACON;
+               return;
+       }
+
+       if (unlikely(wl->beacon_templates_virgin)) {
+               /* We never uploaded a beacon before.
+                * Upload both templates now, but only mark one valid. */
+               wl->beacon_templates_virgin = 0;
+               b43legacy_upload_beacon0(dev);
+               b43legacy_upload_beacon1(dev);
+               cmd = b43legacy_read32(dev, B43legacy_MMIO_MACCMD);
+               cmd |= B43legacy_MACCMD_BEACON0_VALID;
+               b43legacy_write32(dev, B43legacy_MMIO_MACCMD, cmd);
+       } else {
+               if (!beacon0_valid) {
+                       b43legacy_upload_beacon0(dev);
+                       cmd = b43legacy_read32(dev, B43legacy_MMIO_MACCMD);
+                       cmd |= B43legacy_MACCMD_BEACON0_VALID;
+                       b43legacy_write32(dev, B43legacy_MMIO_MACCMD, cmd);
+               } else if (!beacon1_valid) {
+                       b43legacy_upload_beacon1(dev);
+                       cmd = b43legacy_read32(dev, B43legacy_MMIO_MACCMD);
+                       cmd |= B43legacy_MACCMD_BEACON1_VALID;
+                       b43legacy_write32(dev, B43legacy_MMIO_MACCMD, cmd);
+               }
+       }
+}
+
+static void b43legacy_beacon_update_trigger_work(struct work_struct *work)
+{
+       struct b43legacy_wl *wl = container_of(work, struct b43legacy_wl,
+                                        beacon_update_trigger);
+       struct b43legacy_wldev *dev;
+
+       mutex_lock(&wl->mutex);
+       dev = wl->current_dev;
+       if (likely(dev && (b43legacy_status(dev) >= B43legacy_STAT_INITIALIZED))) {
+               spin_lock_irq(&wl->irq_lock);
+               /* Update beacon right away or defer to IRQ. */
+               handle_irq_beacon(dev);
+               /* The handler might have updated the IRQ mask. */
+               b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_MASK,
+                                 dev->irq_mask);
+               mmiowb();
+               spin_unlock_irq(&wl->irq_lock);
+       }
+       mutex_unlock(&wl->mutex);
+}
+
 /* Asynchronously update the packet templates in template RAM.
  * Locking: Requires wl->irq_lock to be locked. */
 static void b43legacy_update_templates(struct b43legacy_wl *wl)
@@ -1156,54 +1252,24 @@ static void b43legacy_update_templates(struct b43legacy_wl *wl)
        wl->current_beacon = beacon;
        wl->beacon0_uploaded = 0;
        wl->beacon1_uploaded = 0;
+       queue_work(wl->hw->workqueue, &wl->beacon_update_trigger);
 }
 
 static void b43legacy_set_beacon_int(struct b43legacy_wldev *dev,
                                     u16 beacon_int)
 {
        b43legacy_time_lock(dev);
-       if (dev->dev->id.revision >= 3)
-               b43legacy_write32(dev, 0x188, (beacon_int << 16));
-       else {
+       if (dev->dev->id.revision >= 3) {
+               b43legacy_write32(dev, B43legacy_MMIO_TSF_CFP_REP,
+                                (beacon_int << 16));
+               b43legacy_write32(dev, B43legacy_MMIO_TSF_CFP_START,
+                                (beacon_int << 10));
+       } else {
                b43legacy_write16(dev, 0x606, (beacon_int >> 6));
                b43legacy_write16(dev, 0x610, beacon_int);
        }
        b43legacy_time_unlock(dev);
-}
-
-static void handle_irq_beacon(struct b43legacy_wldev *dev)
-{
-       struct b43legacy_wl *wl = dev->wl;
-       u32 cmd;
-
-       if (!b43legacy_is_mode(wl, NL80211_IFTYPE_AP))
-               return;
-
-       /* This is the bottom half of the asynchronous beacon update. */
-
-       cmd = b43legacy_read32(dev, B43legacy_MMIO_MACCMD);
-       if (!(cmd & B43legacy_MACCMD_BEACON0_VALID)) {
-               if (!wl->beacon0_uploaded) {
-                       b43legacy_write_beacon_template(dev, 0x68,
-                                                       B43legacy_SHM_SH_BTL0,
-                                                       B43legacy_CCK_RATE_1MB);
-                       b43legacy_write_probe_resp_template(dev, 0x268,
-                                                           B43legacy_SHM_SH_PRTLEN,
-                                                           &__b43legacy_ratetable[3]);
-                       wl->beacon0_uploaded = 1;
-               }
-               cmd |= B43legacy_MACCMD_BEACON0_VALID;
-       }
-       if (!(cmd & B43legacy_MACCMD_BEACON1_VALID)) {
-               if (!wl->beacon1_uploaded) {
-                       b43legacy_write_beacon_template(dev, 0x468,
-                                                       B43legacy_SHM_SH_BTL1,
-                                                       B43legacy_CCK_RATE_1MB);
-                       wl->beacon1_uploaded = 1;
-               }
-               cmd |= B43legacy_MACCMD_BEACON1_VALID;
-       }
-       b43legacy_write32(dev, B43legacy_MMIO_MACCMD, cmd);
+       b43legacydbg(dev->wl, "Set beacon interval to %u\n", beacon_int);
 }
 
 static void handle_irq_ucode_debug(struct b43legacy_wldev *dev)
@@ -1302,7 +1368,7 @@ static void b43legacy_interrupt_tasklet(struct b43legacy_wldev *dev)
        if (reason & B43legacy_IRQ_TX_OK)
                handle_irq_transmit_status(dev);
 
-       b43legacy_interrupt_enable(dev, dev->irq_savedstate);
+       b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_MASK, dev->irq_mask);
        mmiowb();
        spin_unlock_irqrestore(&dev->wl->irq_lock, flags);
 }
@@ -1354,18 +1420,18 @@ static irqreturn_t b43legacy_interrupt_handler(int irq, void *dev_id)
        struct b43legacy_wldev *dev = dev_id;
        u32 reason;
 
-       if (!dev)
-               return IRQ_NONE;
+       B43legacy_WARN_ON(!dev);
 
        spin_lock(&dev->wl->irq_lock);
 
-       if (b43legacy_status(dev) < B43legacy_STAT_STARTED)
+       if (unlikely(b43legacy_status(dev) < B43legacy_STAT_STARTED))
+               /* This can only happen on shared IRQ lines. */
                goto out;
        reason = b43legacy_read32(dev, B43legacy_MMIO_GEN_IRQ_REASON);
        if (reason == 0xffffffff) /* shared IRQ */
                goto out;
        ret = IRQ_HANDLED;
-       reason &= b43legacy_read32(dev, B43legacy_MMIO_GEN_IRQ_MASK);
+       reason &= dev->irq_mask;
        if (!reason)
                goto out;
 
@@ -1389,10 +1455,9 @@ static irqreturn_t b43legacy_interrupt_handler(int irq, void *dev_id)
                                              & 0x0000DC00;
 
        b43legacy_interrupt_ack(dev, reason);
-       /* disable all IRQs. They are enabled again in the bottom half. */
-       dev->irq_savedstate = b43legacy_interrupt_disable(dev,
-                                                         B43legacy_IRQ_ALL);
-       /* save the reason code and call our bottom half. */
+       /* Disable all IRQs. They are enabled again in the bottom half. */
+       b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_MASK, 0);
+       /* Save the reason code and call our bottom half. */
        dev->irq_reason = reason;
        tasklet_schedule(&dev->isr_tasklet);
 out:
@@ -1852,7 +1917,8 @@ void b43legacy_mac_enable(struct b43legacy_wldev *dev)
 
                /* Re-enable IRQs. */
                spin_lock_irq(&dev->wl->irq_lock);
-               b43legacy_interrupt_enable(dev, dev->irq_savedstate);
+               b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_MASK,
+                                 dev->irq_mask);
                spin_unlock_irq(&dev->wl->irq_lock);
        }
 }
@@ -1871,10 +1937,9 @@ void b43legacy_mac_suspend(struct b43legacy_wldev *dev)
                /* Mask IRQs before suspending MAC. Otherwise
                 * the MAC stays busy and won't suspend. */
                spin_lock_irq(&dev->wl->irq_lock);
-               tmp = b43legacy_interrupt_disable(dev, B43legacy_IRQ_ALL);
+               b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_MASK, 0);
                spin_unlock_irq(&dev->wl->irq_lock);
                b43legacy_synchronize_irq(dev);
-               dev->irq_savedstate = tmp;
 
                b43legacy_power_saving_ctl_bits(dev, -1, 1);
                b43legacy_write32(dev, B43legacy_MMIO_MACCTL,
@@ -2297,6 +2362,7 @@ static void b43legacy_security_init(struct b43legacy_wldev *dev)
                                  dev->max_nr_keys - 8);
 }
 
+#ifdef CONFIG_B43LEGACY_HWRNG
 static int b43legacy_rng_read(struct hwrng *rng, u32 *data)
 {
        struct b43legacy_wl *wl = (struct b43legacy_wl *)rng->priv;
@@ -2312,17 +2378,21 @@ static int b43legacy_rng_read(struct hwrng *rng, u32 *data)
 
        return (sizeof(u16));
 }
+#endif
 
 static void b43legacy_rng_exit(struct b43legacy_wl *wl)
 {
+#ifdef CONFIG_B43LEGACY_HWRNG
        if (wl->rng_initialized)
                hwrng_unregister(&wl->rng);
+#endif
 }
 
 static int b43legacy_rng_init(struct b43legacy_wl *wl)
 {
-       int err;
+       int err = 0;
 
+#ifdef CONFIG_B43LEGACY_HWRNG
        snprintf(wl->rng_name, ARRAY_SIZE(wl->rng_name),
                 "%s_%s", KBUILD_MODNAME, wiphy_name(wl->hw->wiphy));
        wl->rng.name = wl->rng_name;
@@ -2336,6 +2406,7 @@ static int b43legacy_rng_init(struct b43legacy_wl *wl)
                       "number generator (%d)\n", err);
        }
 
+#endif
        return err;
 }
 
@@ -2557,7 +2628,6 @@ static int b43legacy_op_dev_config(struct ieee80211_hw *hw,
        int antenna_tx;
        int antenna_rx;
        int err = 0;
-       u32 savedirqs;
 
        antenna_tx = B43legacy_ANTENNA_DEFAULT;
        antenna_rx = B43legacy_ANTENNA_DEFAULT;
@@ -2597,7 +2667,7 @@ static int b43legacy_op_dev_config(struct ieee80211_hw *hw,
                spin_unlock_irqrestore(&wl->irq_lock, flags);
                goto out_unlock_mutex;
        }
-       savedirqs = b43legacy_interrupt_disable(dev, B43legacy_IRQ_ALL);
+       b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_MASK, 0);
        spin_unlock_irqrestore(&wl->irq_lock, flags);
        b43legacy_synchronize_irq(dev);
 
@@ -2619,11 +2689,6 @@ static int b43legacy_op_dev_config(struct ieee80211_hw *hw,
        /* Antennas for RX and management frame TX. */
        b43legacy_mgmtframe_txantenna(dev, antenna_tx);
 
-       /* Update templates for AP mode. */
-       if (b43legacy_is_mode(wl, NL80211_IFTYPE_AP))
-               b43legacy_set_beacon_int(dev, conf->beacon_int);
-
-
        if (!!conf->radio_enabled != phy->radio_on) {
                if (conf->radio_enabled) {
                        b43legacy_radio_turn_on(dev);
@@ -2641,7 +2706,7 @@ static int b43legacy_op_dev_config(struct ieee80211_hw *hw,
        }
 
        spin_lock_irqsave(&wl->irq_lock, flags);
-       b43legacy_interrupt_enable(dev, savedirqs);
+       b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_MASK, dev->irq_mask);
        mmiowb();
        spin_unlock_irqrestore(&wl->irq_lock, flags);
 out_unlock_mutex:
@@ -2704,9 +2769,9 @@ static void b43legacy_op_bss_info_changed(struct ieee80211_hw *hw,
        struct b43legacy_wldev *dev;
        struct b43legacy_phy *phy;
        unsigned long flags;
-       u32 savedirqs;
 
        mutex_lock(&wl->mutex);
+       B43legacy_WARN_ON(wl->vif != vif);
 
        dev = wl->current_dev;
        phy = &dev->phy;
@@ -2719,12 +2784,35 @@ static void b43legacy_op_bss_info_changed(struct ieee80211_hw *hw,
                spin_unlock_irqrestore(&wl->irq_lock, flags);
                goto out_unlock_mutex;
        }
-       savedirqs = b43legacy_interrupt_disable(dev, B43legacy_IRQ_ALL);
+       b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_MASK, 0);
+
+       if (changed & BSS_CHANGED_BSSID) {
+               b43legacy_synchronize_irq(dev);
+
+               if (conf->bssid)
+                       memcpy(wl->bssid, conf->bssid, ETH_ALEN);
+               else
+                       memset(wl->bssid, 0, ETH_ALEN);
+       }
+
+       if (b43legacy_status(dev) >= B43legacy_STAT_INITIALIZED) {
+               if (changed & BSS_CHANGED_BEACON &&
+                   (b43legacy_is_mode(wl, NL80211_IFTYPE_AP) ||
+                    b43legacy_is_mode(wl, NL80211_IFTYPE_ADHOC)))
+                       b43legacy_update_templates(wl);
+
+               if (changed & BSS_CHANGED_BSSID)
+                       b43legacy_write_mac_bssid_templates(dev);
+       }
        spin_unlock_irqrestore(&wl->irq_lock, flags);
-       b43legacy_synchronize_irq(dev);
 
        b43legacy_mac_suspend(dev);
 
+       if (changed & BSS_CHANGED_BEACON_INT &&
+           (b43legacy_is_mode(wl, NL80211_IFTYPE_AP) ||
+            b43legacy_is_mode(wl, NL80211_IFTYPE_ADHOC)))
+               b43legacy_set_beacon_int(dev, conf->beacon_int);
+
        if (changed & BSS_CHANGED_BASIC_RATES)
                b43legacy_update_basic_rates(dev, conf->basic_rates);
 
@@ -2738,14 +2826,12 @@ static void b43legacy_op_bss_info_changed(struct ieee80211_hw *hw,
        b43legacy_mac_enable(dev);
 
        spin_lock_irqsave(&wl->irq_lock, flags);
-       b43legacy_interrupt_enable(dev, savedirqs);
+       b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_MASK, dev->irq_mask);
        /* XXX: why? */
        mmiowb();
        spin_unlock_irqrestore(&wl->irq_lock, flags);
  out_unlock_mutex:
        mutex_unlock(&wl->mutex);
-
-       return;
 }
 
 static void b43legacy_op_configure_filter(struct ieee80211_hw *hw,
@@ -2787,40 +2873,6 @@ static void b43legacy_op_configure_filter(struct ieee80211_hw *hw,
        spin_unlock_irqrestore(&wl->irq_lock, flags);
 }
 
-static int b43legacy_op_config_interface(struct ieee80211_hw *hw,
-                                        struct ieee80211_vif *vif,
-                                        struct ieee80211_if_conf *conf)
-{
-       struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
-       struct b43legacy_wldev *dev = wl->current_dev;
-       unsigned long flags;
-
-       if (!dev)
-               return -ENODEV;
-       mutex_lock(&wl->mutex);
-       spin_lock_irqsave(&wl->irq_lock, flags);
-       B43legacy_WARN_ON(wl->vif != vif);
-       if (conf->bssid)
-               memcpy(wl->bssid, conf->bssid, ETH_ALEN);
-       else
-               memset(wl->bssid, 0, ETH_ALEN);
-       if (b43legacy_status(dev) >= B43legacy_STAT_INITIALIZED) {
-               if (b43legacy_is_mode(wl, NL80211_IFTYPE_AP)) {
-                       B43legacy_WARN_ON(vif->type != NL80211_IFTYPE_AP);
-                       if (conf->changed & IEEE80211_IFCC_BEACON)
-                               b43legacy_update_templates(wl);
-               } else if (b43legacy_is_mode(wl, NL80211_IFTYPE_ADHOC)) {
-                       if (conf->changed & IEEE80211_IFCC_BEACON)
-                               b43legacy_update_templates(wl);
-               }
-               b43legacy_write_mac_bssid_templates(dev);
-       }
-       spin_unlock_irqrestore(&wl->irq_lock, flags);
-       mutex_unlock(&wl->mutex);
-
-       return 0;
-}
-
 /* Locking: wl->mutex */
 static void b43legacy_wireless_core_stop(struct b43legacy_wldev *dev)
 {
@@ -2834,8 +2886,7 @@ static void b43legacy_wireless_core_stop(struct b43legacy_wldev *dev)
         * setting the status to INITIALIZED, as the interrupt handler
         * won't care about IRQs then. */
        spin_lock_irqsave(&wl->irq_lock, flags);
-       dev->irq_savedstate = b43legacy_interrupt_disable(dev,
-                                                         B43legacy_IRQ_ALL);
+       b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_MASK, 0);
        b43legacy_read32(dev, B43legacy_MMIO_GEN_IRQ_MASK); /* flush */
        spin_unlock_irqrestore(&wl->irq_lock, flags);
        b43legacy_synchronize_irq(dev);
@@ -2875,7 +2926,7 @@ static int b43legacy_wireless_core_start(struct b43legacy_wldev *dev)
 
        /* Start data flow (TX/RX) */
        b43legacy_mac_enable(dev);
-       b43legacy_interrupt_enable(dev, dev->irq_savedstate);
+       b43legacy_write32(dev, B43legacy_MMIO_GEN_IRQ_MASK, dev->irq_mask);
 
        /* Start maintenance work */
        b43legacy_periodic_tasks_setup(dev);
@@ -3038,7 +3089,7 @@ static void setup_struct_wldev_for_init(struct b43legacy_wldev *dev)
        /* IRQ related flags */
        dev->irq_reason = 0;
        memset(dev->dma_reason, 0, sizeof(dev->dma_reason));
-       dev->irq_savedstate = B43legacy_IRQ_MASKTEMPLATE;
+       dev->irq_mask = B43legacy_IRQ_MASKTEMPLATE;
 
        dev->mac_suspended = 1;
 
@@ -3380,11 +3431,6 @@ static int b43legacy_op_start(struct ieee80211_hw *hw)
        struct b43legacy_wldev *dev = wl->current_dev;
        int did_init = 0;
        int err = 0;
-       bool do_rfkill_exit = 0;
-
-       /* First register RFkill.
-        * LEDs that are registered later depend on it. */
-       b43legacy_rfkill_init(dev);
 
        /* Kill all old instance specific information to make sure
         * the card won't use it in the short timeframe between start
@@ -3392,15 +3438,16 @@ static int b43legacy_op_start(struct ieee80211_hw *hw)
        memset(wl->bssid, 0, ETH_ALEN);
        memset(wl->mac_addr, 0, ETH_ALEN);
        wl->filter_flags = 0;
+       wl->beacon0_uploaded = 0;
+       wl->beacon1_uploaded = 0;
+       wl->beacon_templates_virgin = 1;
 
        mutex_lock(&wl->mutex);
 
        if (b43legacy_status(dev) < B43legacy_STAT_INITIALIZED) {
                err = b43legacy_wireless_core_init(dev);
-               if (err) {
-                       do_rfkill_exit = 1;
+               if (err)
                        goto out_mutex_unlock;
-               }
                did_init = 1;
        }
 
@@ -3409,17 +3456,15 @@ static int b43legacy_op_start(struct ieee80211_hw *hw)
                if (err) {
                        if (did_init)
                                b43legacy_wireless_core_exit(dev);
-                       do_rfkill_exit = 1;
                        goto out_mutex_unlock;
                }
        }
 
+       wiphy_rfkill_start_polling(hw->wiphy);
+
 out_mutex_unlock:
        mutex_unlock(&wl->mutex);
 
-       if (do_rfkill_exit)
-               b43legacy_rfkill_exit(dev);
-
        return err;
 }
 
@@ -3428,7 +3473,7 @@ static void b43legacy_op_stop(struct ieee80211_hw *hw)
        struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
        struct b43legacy_wldev *dev = wl->current_dev;
 
-       b43legacy_rfkill_exit(dev);
+       cancel_work_sync(&(wl->beacon_update_trigger));
 
        mutex_lock(&wl->mutex);
        if (b43legacy_status(dev) >= B43legacy_STAT_STARTED)
@@ -3457,13 +3502,13 @@ static const struct ieee80211_ops b43legacy_hw_ops = {
        .remove_interface       = b43legacy_op_remove_interface,
        .config                 = b43legacy_op_dev_config,
        .bss_info_changed       = b43legacy_op_bss_info_changed,
-       .config_interface       = b43legacy_op_config_interface,
        .configure_filter       = b43legacy_op_configure_filter,
        .get_stats              = b43legacy_op_get_stats,
        .get_tx_stats           = b43legacy_op_get_tx_stats,
        .start                  = b43legacy_op_start,
        .stop                   = b43legacy_op_stop,
        .set_tim                = b43legacy_op_beacon_set_tim,
+       .rfkill_poll            = b43legacy_rfkill_poll,
 };
 
 /* Hard-reset the chip. Do not call this directly.
@@ -3760,6 +3805,7 @@ static int b43legacy_wireless_init(struct ssb_device *dev)
        spin_lock_init(&wl->leds_lock);
        mutex_init(&wl->mutex);
        INIT_LIST_HEAD(&wl->devlist);
+       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);
index 746d5361bba017b56838c6cf5b5c54add2cd0317..51866c9a2769108ad974e9a9bc60e015c7869a9a 100644 (file)
@@ -443,7 +443,7 @@ int b43legacy_pio_init(struct b43legacy_wldev *dev)
        pio->queue3 = queue;
 
        if (dev->dev->id.revision < 3)
-               dev->irq_savedstate |= B43legacy_IRQ_PIO_WORKAROUND;
+               dev->irq_mask |= B43legacy_IRQ_PIO_WORKAROUND;
 
        b43legacydbg(dev->wl, "PIO initialized\n");
        err = 0;
index b32bf6a94f19d7543525ed562a89683bf893d168..8783022db11e43e24ae12a641bd040a5aea38b07 100644 (file)
 
 */
 
-#include "rfkill.h"
 #include "radio.h"
 #include "b43legacy.h"
 
-#include <linux/kmod.h>
-
 
 /* Returns TRUE, if the radio is enabled in hardware. */
-static bool b43legacy_is_hw_radio_enabled(struct b43legacy_wldev *dev)
+bool b43legacy_is_hw_radio_enabled(struct b43legacy_wldev *dev)
 {
        if (dev->phy.rev >= 3) {
                if (!(b43legacy_read32(dev, B43legacy_MMIO_RADIO_HWENABLED_HI)
@@ -45,165 +42,43 @@ static bool b43legacy_is_hw_radio_enabled(struct b43legacy_wldev *dev)
 }
 
 /* The poll callback for the hardware button. */
-static void b43legacy_rfkill_poll(struct input_polled_dev *poll_dev)
+void b43legacy_rfkill_poll(struct ieee80211_hw *hw)
 {
-       struct b43legacy_wldev *dev = poll_dev->private;
-       struct b43legacy_wl *wl = dev->wl;
+       struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
+       struct b43legacy_wldev *dev = wl->current_dev;
+       struct ssb_bus *bus = dev->dev->bus;
        bool enabled;
-       bool report_change = 0;
+       bool brought_up = false;
 
        mutex_lock(&wl->mutex);
        if (unlikely(b43legacy_status(dev) < B43legacy_STAT_INITIALIZED)) {
-               mutex_unlock(&wl->mutex);
-               return;
+               if (ssb_bus_powerup(bus, 0)) {
+                       mutex_unlock(&wl->mutex);
+                       return;
+               }
+               ssb_device_enable(dev->dev, 0);
+               brought_up = true;
        }
+
        enabled = b43legacy_is_hw_radio_enabled(dev);
+
        if (unlikely(enabled != dev->radio_hw_enable)) {
                dev->radio_hw_enable = enabled;
-               report_change = 1;
                b43legacyinfo(wl, "Radio hardware status changed to %s\n",
                        enabled ? "ENABLED" : "DISABLED");
-       }
-       mutex_unlock(&wl->mutex);
-
-       /* send the radio switch event to the system - note both a key press
-        * and a release are required */
-       if (unlikely(report_change)) {
-               input_report_key(poll_dev->input, KEY_WLAN, 1);
-               input_report_key(poll_dev->input, KEY_WLAN, 0);
-       }
-}
-
-/* Called when the RFKILL toggled in software.
- * This is called without locking. */
-static int b43legacy_rfkill_soft_toggle(void *data, enum rfkill_state state)
-{
-       struct b43legacy_wldev *dev = data;
-       struct b43legacy_wl *wl = dev->wl;
-       int err = -EBUSY;
-
-       if (!wl->rfkill.registered)
-               return 0;
-
-       mutex_lock(&wl->mutex);
-       if (b43legacy_status(dev) < B43legacy_STAT_INITIALIZED)
-               goto out_unlock;
-       err = 0;
-       switch (state) {
-       case RFKILL_STATE_UNBLOCKED:
-               if (!dev->radio_hw_enable) {
-                       /* No luck. We can't toggle the hardware RF-kill
-                        * button from software. */
-                       err = -EBUSY;
-                       goto out_unlock;
+               wiphy_rfkill_set_hw_state(hw->wiphy, !enabled);
+               if (enabled != dev->phy.radio_on) {
+                       if (enabled)
+                               b43legacy_radio_turn_on(dev);
+                       else
+                               b43legacy_radio_turn_off(dev, 0);
                }
-               if (!dev->phy.radio_on)
-                       b43legacy_radio_turn_on(dev);
-               break;
-       case RFKILL_STATE_SOFT_BLOCKED:
-               if (dev->phy.radio_on)
-                       b43legacy_radio_turn_off(dev, 0);
-               break;
-       default:
-               b43legacywarn(wl, "Received unexpected rfkill state %d.\n",
-                             state);
-               break;
        }
 
-out_unlock:
-       mutex_unlock(&wl->mutex);
-
-       return err;
-}
-
-char *b43legacy_rfkill_led_name(struct b43legacy_wldev *dev)
-{
-       struct b43legacy_rfkill *rfk = &(dev->wl->rfkill);
-
-       if (!rfk->registered)
-               return NULL;
-       return rfkill_get_led_name(rfk->rfkill);
-}
-
-void b43legacy_rfkill_init(struct b43legacy_wldev *dev)
-{
-       struct b43legacy_wl *wl = dev->wl;
-       struct b43legacy_rfkill *rfk = &(wl->rfkill);
-       int err;
-
-       rfk->registered = 0;
-
-       rfk->rfkill = rfkill_allocate(dev->dev->dev, RFKILL_TYPE_WLAN);
-       if (!rfk->rfkill)
-               goto out_error;
-       snprintf(rfk->name, sizeof(rfk->name),
-                "b43legacy-%s", wiphy_name(wl->hw->wiphy));
-       rfk->rfkill->name = rfk->name;
-       rfk->rfkill->state = RFKILL_STATE_UNBLOCKED;
-       rfk->rfkill->data = dev;
-       rfk->rfkill->toggle_radio = b43legacy_rfkill_soft_toggle;
-       rfk->rfkill->user_claim_unsupported = 1;
-
-       rfk->poll_dev = input_allocate_polled_device();
-       if (!rfk->poll_dev) {
-               rfkill_free(rfk->rfkill);
-               goto err_freed_rfk;
+       if (brought_up) {
+               ssb_device_disable(dev->dev, 0);
+               ssb_bus_may_powerdown(bus);
        }
 
-       rfk->poll_dev->private = dev;
-       rfk->poll_dev->poll = b43legacy_rfkill_poll;
-       rfk->poll_dev->poll_interval = 1000; /* msecs */
-
-       rfk->poll_dev->input->name = rfk->name;
-       rfk->poll_dev->input->id.bustype = BUS_HOST;
-       rfk->poll_dev->input->id.vendor = dev->dev->bus->boardinfo.vendor;
-       rfk->poll_dev->input->evbit[0] = BIT(EV_KEY);
-       set_bit(KEY_WLAN, rfk->poll_dev->input->keybit);
-
-       err = rfkill_register(rfk->rfkill);
-       if (err)
-               goto err_free_polldev;
-
-#ifdef CONFIG_RFKILL_INPUT_MODULE
-       /* B43legacy RF-kill isn't useful without the rfkill-input subsystem.
-        * Try to load the module. */
-       err = request_module("rfkill-input");
-       if (err)
-               b43legacywarn(wl, "Failed to load the rfkill-input module."
-                       "The built-in radio LED will not work.\n");
-#endif /* CONFIG_RFKILL_INPUT */
-
-       err = input_register_polled_device(rfk->poll_dev);
-       if (err)
-               goto err_unreg_rfk;
-
-       rfk->registered = 1;
-
-       return;
-err_unreg_rfk:
-       rfkill_unregister(rfk->rfkill);
-err_free_polldev:
-       input_free_polled_device(rfk->poll_dev);
-       rfk->poll_dev = NULL;
-err_freed_rfk:
-       rfk->rfkill = NULL;
-out_error:
-       rfk->registered = 0;
-       b43legacywarn(wl, "RF-kill button init failed\n");
-}
-
-void b43legacy_rfkill_exit(struct b43legacy_wldev *dev)
-{
-       struct b43legacy_rfkill *rfk = &(dev->wl->rfkill);
-
-       if (!rfk->registered)
-               return;
-       rfk->registered = 0;
-
-       input_unregister_polled_device(rfk->poll_dev);
-       rfkill_unregister(rfk->rfkill);
-       input_free_polled_device(rfk->poll_dev);
-       rfk->poll_dev = NULL;
-       rfk->rfkill = NULL;
+       mutex_unlock(&wl->mutex);
 }
-
index 11150a8032f0704152f0b58eb8c0b3198afa669c..75585571c544872a3f476222aa16161879ad206d 100644 (file)
@@ -1,59 +1,11 @@
 #ifndef B43legacy_RFKILL_H_
 #define B43legacy_RFKILL_H_
 
+struct ieee80211_hw;
 struct b43legacy_wldev;
 
-#ifdef CONFIG_B43LEGACY_RFKILL
+void b43legacy_rfkill_poll(struct ieee80211_hw *hw);
 
-#include <linux/rfkill.h>
-#include <linux/workqueue.h>
-#include <linux/input-polldev.h>
-
-
-
-struct b43legacy_rfkill {
-       /* The RFKILL subsystem data structure */
-       struct rfkill *rfkill;
-       /* The poll device for the RFKILL input button */
-       struct input_polled_dev *poll_dev;
-       /* Did initialization succeed? Used for freeing. */
-       bool registered;
-       /* The unique name of this rfkill switch */
-       char name[sizeof("b43legacy-phy4294967295")];
-};
-
-/* The init function returns void, because we are not interested
- * in failing the b43 init process when rfkill init failed. */
-void b43legacy_rfkill_init(struct b43legacy_wldev *dev);
-void b43legacy_rfkill_exit(struct b43legacy_wldev *dev);
-
-char *b43legacy_rfkill_led_name(struct b43legacy_wldev *dev);
-
-
-#else /* CONFIG_B43LEGACY_RFKILL */
-/* No RFKILL support. */
-
-struct b43legacy_rfkill {
-       /* empty */
-};
-
-static inline void b43legacy_rfkill_alloc(struct b43legacy_wldev *dev)
-{
-}
-static inline void b43legacy_rfkill_free(struct b43legacy_wldev *dev)
-{
-}
-static inline void b43legacy_rfkill_init(struct b43legacy_wldev *dev)
-{
-}
-static inline void b43legacy_rfkill_exit(struct b43legacy_wldev *dev)
-{
-}
-static inline char *b43legacy_rfkill_led_name(struct b43legacy_wldev *dev)
-{
-       return NULL;
-}
-
-#endif /* CONFIG_B43LEGACY_RFKILL */
+bool b43legacy_is_hw_radio_enabled(struct b43legacy_wldev *dev);
 
 #endif /* B43legacy_RFKILL_H_ */
index 12fca99f7578d28744eb8a815fac0b7a2adcddcd..b8e39dd06e99d580829cc26b8c8513272d9a409d 100644 (file)
@@ -274,7 +274,7 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev,
 
        /* PHY TX Control word */
        if (rate_ofdm)
-               phy_ctl |= B43legacy_TX4_PHY_OFDM;
+               phy_ctl |= B43legacy_TX4_PHY_ENC_OFDM;
        if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
                phy_ctl |= B43legacy_TX4_PHY_SHORTPRMBL;
        switch (info->antenna_sel_tx) {
index 62e09d02788fb74648b13bfe324c35588ee50d87..91633087a20bfd28279a2972e3d4f8cc85d434ad 100644 (file)
@@ -67,7 +67,9 @@ struct b43legacy_txhdr_fw3 {
 #define B43legacy_TX4_EFT_RTSFBOFDM    0x0010 /* RTS/CTS fallback rate type */
 
 /* PHY TX control word */
-#define B43legacy_TX4_PHY_OFDM         0x0001 /* Data frame rate type */
+#define B43legacy_TX4_PHY_ENC          0x0003 /* Data frame encoding */
+#define B43legacy_TX4_PHY_ENC_CCK      0x0000 /* CCK */
+#define B43legacy_TX4_PHY_ENC_OFDM     0x0001 /* Data frame rate type */
 #define B43legacy_TX4_PHY_SHORTPRMBL   0x0010 /* Use short preamble */
 #define B43legacy_TX4_PHY_ANT          0x03C0 /* Antenna selection */
 #define  B43legacy_TX4_PHY_ANT0                0x0000 /* Use antenna 0 */
index 6693423f63feb3b032681276af06ed5666e89927..d313b005114e31b4db5496bd81c40865365c7306 100644 (file)
@@ -377,7 +377,7 @@ int hostap_master_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        struct hostap_interface *iface;
        local_info_t *local;
-       int ret = 1;
+       int ret = NETDEV_TX_BUSY;
        u16 fc;
        struct hostap_tx_data tx;
        ap_tx_ret tx_ret;
index 3dad1cf8f241f3fbbbefa2bbcf4643e257c1d2be..ff9b5c882184a00e58316166a62fd5514ead0ae6 100644 (file)
@@ -1423,7 +1423,7 @@ static int prism2_hw_init2(struct net_device *dev, int initial)
                prism2_check_sta_fw_version(local);
 
                if (hfa384x_get_rid(dev, HFA384X_RID_CNFOWNMACADDR,
-                                   &dev->dev_addr, 6, 1) < 0) {
+                                   dev->dev_addr, 6, 1) < 0) {
                        printk("%s: could not get own MAC address\n",
                               dev->name);
                }
index cbf15d703201f15dc323bffcd9461fd974fb4e1f..0e5d51086a444bbb366ba2a24951fd8b4b8f88d2 100644 (file)
@@ -435,7 +435,7 @@ static int prism2_plx_probe(struct pci_dev *pdev,
        unsigned long pccard_attr_mem;
        unsigned int pccard_attr_len;
        void __iomem *attr_mem = NULL;
-       unsigned int cor_offset, cor_index;
+       unsigned int cor_offset = 0, cor_index = 0;
        u32 reg;
        local_info_t *local = NULL;
        struct net_device *dev = NULL;
index 97e5647ff050d665fb7bd5c9f587d1b64f5be046..742432388ca30a11f528aa3cf761d1760c8f6139 100644 (file)
@@ -3488,7 +3488,7 @@ static DEVICE_ATTR(pci, S_IRUGO, show_pci, NULL);
 static ssize_t show_cfg(struct device *d, struct device_attribute *attr,
                        char *buf)
 {
-       struct ipw2100_priv *p = d->driver_data;
+       struct ipw2100_priv *p = dev_get_drvdata(d);
        return sprintf(buf, "0x%08x\n", (int)p->config);
 }
 
@@ -3497,7 +3497,7 @@ static DEVICE_ATTR(cfg, S_IRUGO, show_cfg, NULL);
 static ssize_t show_status(struct device *d, struct device_attribute *attr,
                           char *buf)
 {
-       struct ipw2100_priv *p = d->driver_data;
+       struct ipw2100_priv *p = dev_get_drvdata(d);
        return sprintf(buf, "0x%08x\n", (int)p->status);
 }
 
@@ -3506,7 +3506,7 @@ static DEVICE_ATTR(status, S_IRUGO, show_status, NULL);
 static ssize_t show_capability(struct device *d, struct device_attribute *attr,
                               char *buf)
 {
-       struct ipw2100_priv *p = d->driver_data;
+       struct ipw2100_priv *p = dev_get_drvdata(d);
        return sprintf(buf, "0x%08x\n", (int)p->capability);
 }
 
@@ -4224,7 +4224,7 @@ static ssize_t show_rf_kill(struct device *d, struct device_attribute *attr,
           1 - SW based RF kill active (sysfs)
           2 - HW based RF kill active
           3 - Both HW and SW baed RF kill active */
-       struct ipw2100_priv *priv = (struct ipw2100_priv *)d->driver_data;
+       struct ipw2100_priv *priv = dev_get_drvdata(d);
        int val = ((priv->status & STATUS_RF_KILL_SW) ? 0x1 : 0x0) |
            (rf_kill_active(priv) ? 0x2 : 0x0);
        return sprintf(buf, "%i\n", val);
index bd4dbcfe1bbe9c54b675b07a8a9ed74004894a8f..44c29b3f67285ab608d3bf254db3498be3854962 100644 (file)
@@ -1527,7 +1527,7 @@ static DEVICE_ATTR(led, S_IWUSR | S_IRUGO, show_led, store_led);
 static ssize_t show_status(struct device *d,
                           struct device_attribute *attr, char *buf)
 {
-       struct ipw_priv *p = d->driver_data;
+       struct ipw_priv *p = dev_get_drvdata(d);
        return sprintf(buf, "0x%08x\n", (int)p->status);
 }
 
@@ -1536,7 +1536,7 @@ static DEVICE_ATTR(status, S_IRUGO, show_status, NULL);
 static ssize_t show_cfg(struct device *d, struct device_attribute *attr,
                        char *buf)
 {
-       struct ipw_priv *p = d->driver_data;
+       struct ipw_priv *p = dev_get_drvdata(d);
        return sprintf(buf, "0x%08x\n", (int)p->config);
 }
 
@@ -1545,7 +1545,7 @@ static DEVICE_ATTR(cfg, S_IRUGO, show_cfg, NULL);
 static ssize_t show_nic_type(struct device *d,
                             struct device_attribute *attr, char *buf)
 {
-       struct ipw_priv *priv = d->driver_data;
+       struct ipw_priv *priv = dev_get_drvdata(d);
        return sprintf(buf, "TYPE: %d\n", priv->nic_type);
 }
 
@@ -1555,7 +1555,7 @@ static ssize_t show_ucode_version(struct device *d,
                                  struct device_attribute *attr, char *buf)
 {
        u32 len = sizeof(u32), tmp = 0;
-       struct ipw_priv *p = d->driver_data;
+       struct ipw_priv *p = dev_get_drvdata(d);
 
        if (ipw_get_ordinal(p, IPW_ORD_STAT_UCODE_VERSION, &tmp, &len))
                return 0;
@@ -1569,7 +1569,7 @@ static ssize_t show_rtc(struct device *d, struct device_attribute *attr,
                        char *buf)
 {
        u32 len = sizeof(u32), tmp = 0;
-       struct ipw_priv *p = d->driver_data;
+       struct ipw_priv *p = dev_get_drvdata(d);
 
        if (ipw_get_ordinal(p, IPW_ORD_STAT_RTC, &tmp, &len))
                return 0;
@@ -1586,14 +1586,15 @@ static DEVICE_ATTR(rtc, S_IWUSR | S_IRUGO, show_rtc, NULL);
 static ssize_t show_eeprom_delay(struct device *d,
                                 struct device_attribute *attr, char *buf)
 {
-       int n = ((struct ipw_priv *)d->driver_data)->eeprom_delay;
+       struct ipw_priv *p = dev_get_drvdata(d);
+       int n = p->eeprom_delay;
        return sprintf(buf, "%i\n", n);
 }
 static ssize_t store_eeprom_delay(struct device *d,
                                  struct device_attribute *attr,
                                  const char *buf, size_t count)
 {
-       struct ipw_priv *p = d->driver_data;
+       struct ipw_priv *p = dev_get_drvdata(d);
        sscanf(buf, "%i", &p->eeprom_delay);
        return strnlen(buf, count);
 }
@@ -1605,7 +1606,7 @@ static ssize_t show_command_event_reg(struct device *d,
                                      struct device_attribute *attr, char *buf)
 {
        u32 reg = 0;
-       struct ipw_priv *p = d->driver_data;
+       struct ipw_priv *p = dev_get_drvdata(d);
 
        reg = ipw_read_reg32(p, IPW_INTERNAL_CMD_EVENT);
        return sprintf(buf, "0x%08x\n", reg);
@@ -1615,7 +1616,7 @@ static ssize_t store_command_event_reg(struct device *d,
                                       const char *buf, size_t count)
 {
        u32 reg;
-       struct ipw_priv *p = d->driver_data;
+       struct ipw_priv *p = dev_get_drvdata(d);
 
        sscanf(buf, "%x", &reg);
        ipw_write_reg32(p, IPW_INTERNAL_CMD_EVENT, reg);
@@ -1629,7 +1630,7 @@ static ssize_t show_mem_gpio_reg(struct device *d,
                                 struct device_attribute *attr, char *buf)
 {
        u32 reg = 0;
-       struct ipw_priv *p = d->driver_data;
+       struct ipw_priv *p = dev_get_drvdata(d);
 
        reg = ipw_read_reg32(p, 0x301100);
        return sprintf(buf, "0x%08x\n", reg);
@@ -1639,7 +1640,7 @@ static ssize_t store_mem_gpio_reg(struct device *d,
                                  const char *buf, size_t count)
 {
        u32 reg;
-       struct ipw_priv *p = d->driver_data;
+       struct ipw_priv *p = dev_get_drvdata(d);
 
        sscanf(buf, "%x", &reg);
        ipw_write_reg32(p, 0x301100, reg);
@@ -1653,7 +1654,7 @@ static ssize_t show_indirect_dword(struct device *d,
                                   struct device_attribute *attr, char *buf)
 {
        u32 reg = 0;
-       struct ipw_priv *priv = d->driver_data;
+       struct ipw_priv *priv = dev_get_drvdata(d);
 
        if (priv->status & STATUS_INDIRECT_DWORD)
                reg = ipw_read_reg32(priv, priv->indirect_dword);
@@ -1666,7 +1667,7 @@ static ssize_t store_indirect_dword(struct device *d,
                                    struct device_attribute *attr,
                                    const char *buf, size_t count)
 {
-       struct ipw_priv *priv = d->driver_data;
+       struct ipw_priv *priv = dev_get_drvdata(d);
 
        sscanf(buf, "%x", &priv->indirect_dword);
        priv->status |= STATUS_INDIRECT_DWORD;
@@ -1680,7 +1681,7 @@ static ssize_t show_indirect_byte(struct device *d,
                                  struct device_attribute *attr, char *buf)
 {
        u8 reg = 0;
-       struct ipw_priv *priv = d->driver_data;
+       struct ipw_priv *priv = dev_get_drvdata(d);
 
        if (priv->status & STATUS_INDIRECT_BYTE)
                reg = ipw_read_reg8(priv, priv->indirect_byte);
@@ -1693,7 +1694,7 @@ static ssize_t store_indirect_byte(struct device *d,
                                   struct device_attribute *attr,
                                   const char *buf, size_t count)
 {
-       struct ipw_priv *priv = d->driver_data;
+       struct ipw_priv *priv = dev_get_drvdata(d);
 
        sscanf(buf, "%x", &priv->indirect_byte);
        priv->status |= STATUS_INDIRECT_BYTE;
@@ -1707,7 +1708,7 @@ static ssize_t show_direct_dword(struct device *d,
                                 struct device_attribute *attr, char *buf)
 {
        u32 reg = 0;
-       struct ipw_priv *priv = d->driver_data;
+       struct ipw_priv *priv = dev_get_drvdata(d);
 
        if (priv->status & STATUS_DIRECT_DWORD)
                reg = ipw_read32(priv, priv->direct_dword);
@@ -1720,7 +1721,7 @@ static ssize_t store_direct_dword(struct device *d,
                                  struct device_attribute *attr,
                                  const char *buf, size_t count)
 {
-       struct ipw_priv *priv = d->driver_data;
+       struct ipw_priv *priv = dev_get_drvdata(d);
 
        sscanf(buf, "%x", &priv->direct_dword);
        priv->status |= STATUS_DIRECT_DWORD;
@@ -1747,7 +1748,7 @@ static ssize_t show_rf_kill(struct device *d, struct device_attribute *attr,
           1 - SW based RF kill active (sysfs)
           2 - HW based RF kill active
           3 - Both HW and SW baed RF kill active */
-       struct ipw_priv *priv = d->driver_data;
+       struct ipw_priv *priv = dev_get_drvdata(d);
        int val = ((priv->status & STATUS_RF_KILL_SW) ? 0x1 : 0x0) |
            (rf_kill_active(priv) ? 0x2 : 0x0);
        return sprintf(buf, "%i\n", val);
@@ -1791,7 +1792,7 @@ static int ipw_radio_kill_sw(struct ipw_priv *priv, int disable_radio)
 static ssize_t store_rf_kill(struct device *d, struct device_attribute *attr,
                             const char *buf, size_t count)
 {
-       struct ipw_priv *priv = d->driver_data;
+       struct ipw_priv *priv = dev_get_drvdata(d);
 
        ipw_radio_kill_sw(priv, buf[0] == '1');
 
@@ -1803,7 +1804,7 @@ static DEVICE_ATTR(rf_kill, S_IWUSR | S_IRUGO, show_rf_kill, store_rf_kill);
 static ssize_t show_speed_scan(struct device *d, struct device_attribute *attr,
                               char *buf)
 {
-       struct ipw_priv *priv = (struct ipw_priv *)d->driver_data;
+       struct ipw_priv *priv = dev_get_drvdata(d);
        int pos = 0, len = 0;
        if (priv->config & CFG_SPEED_SCAN) {
                while (priv->speed_scan[pos] != 0)
@@ -1818,7 +1819,7 @@ static ssize_t show_speed_scan(struct device *d, struct device_attribute *attr,
 static ssize_t store_speed_scan(struct device *d, struct device_attribute *attr,
                                const char *buf, size_t count)
 {
-       struct ipw_priv *priv = (struct ipw_priv *)d->driver_data;
+       struct ipw_priv *priv = dev_get_drvdata(d);
        int channel, pos = 0;
        const char *p = buf;
 
@@ -1857,14 +1858,14 @@ static DEVICE_ATTR(speed_scan, S_IWUSR | S_IRUGO, show_speed_scan,
 static ssize_t show_net_stats(struct device *d, struct device_attribute *attr,
                              char *buf)
 {
-       struct ipw_priv *priv = (struct ipw_priv *)d->driver_data;
+       struct ipw_priv *priv = dev_get_drvdata(d);
        return sprintf(buf, "%c\n", (priv->config & CFG_NET_STATS) ? '1' : '0');
 }
 
 static ssize_t store_net_stats(struct device *d, struct device_attribute *attr,
                               const char *buf, size_t count)
 {
-       struct ipw_priv *priv = (struct ipw_priv *)d->driver_data;
+       struct ipw_priv *priv = dev_get_drvdata(d);
        if (buf[0] == '1')
                priv->config |= CFG_NET_STATS;
        else
@@ -3176,11 +3177,8 @@ static int ipw_load_firmware(struct ipw_priv *priv, u8 * data, size_t len)
        /* Start the Dma */
        rc = ipw_fw_dma_enable(priv);
 
-       if (priv->sram_desc.last_cb_index > 0) {
-               /* the DMA is already ready this would be a bug. */
-               BUG();
-               goto out;
-       }
+       /* the DMA is already ready this would be a bug. */
+       BUG_ON(priv->sram_desc.last_cb_index > 0);
 
        do {
                chunk = (struct fw_chunk *)(data + offset);
@@ -11526,7 +11524,8 @@ static int ipw_prom_stop(struct net_device *dev)
 static int ipw_prom_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        IPW_DEBUG_INFO("prom dev->xmit\n");
-       return -EOPNOTSUPP;
+       dev_kfree_skb(skb);
+       return NETDEV_TX_OK;
 }
 
 static const struct net_device_ops ipw_prom_netdev_ops = {
index 92a26922e792d73721a2e4ca0ed3c2c3a125fcb5..8ce6e961c5da08396a1805f5b46d428865b84924 100644 (file)
@@ -154,10 +154,6 @@ struct net_device *alloc_ieee80211(int sizeof_priv)
                goto failed;
        }
        ieee = netdev_priv(dev);
-#ifdef CONFIG_COMPAT_NET_DEV_OPS
-       dev->hard_start_xmit = ieee80211_xmit;
-       dev->change_mtu = ieee80211_change_mtu;
-#endif
 
        ieee->dev = dev;
 
index 65a8195b3d90c89fb8c3ace8954827c9a7f5908d..da2ad5437ce5b3f74db5c8230ed8f92430262d31 100644 (file)
@@ -539,7 +539,7 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
        spin_unlock_irqrestore(&ieee->lock, flags);
        netif_stop_queue(dev);
        dev->stats.tx_errors++;
-       return 1;
+       return NETDEV_TX_BUSY;
 }
 EXPORT_SYMBOL(ieee80211_xmit);
 
index 736162324ba4e8457bbaaabaa3176d9c697e8e9c..e092af09d6bfa46e9f5adaf95fcfdd75ab3a13b6 100644 (file)
@@ -5,16 +5,11 @@ config IWLWIFI
        select FW_LOADER
        select MAC80211_LEDS if IWLWIFI_LEDS
        select LEDS_CLASS if IWLWIFI_LEDS
-       select RFKILL if IWLWIFI_RFKILL
 
 config IWLWIFI_LEDS
        bool "Enable LED support in iwlagn and iwl3945 drivers"
        depends on IWLWIFI
 
-config IWLWIFI_RFKILL
-       bool "Enable RF kill support in iwlagn and iwl3945 drivers"
-       depends on IWLWIFI
-
 config IWLWIFI_SPECTRUM_MEASUREMENT
        bool "Enable Spectrum Measurement in iwlagn driver"
        depends on IWLWIFI
index d79d97ad61a56d490811231215ffe8f0144184d6..1d4e0a226fd4fd5fbf64a55504c09c33ca2e7554 100644 (file)
@@ -4,7 +4,6 @@ iwlcore-objs            += iwl-rx.o iwl-tx.o iwl-sta.o iwl-calib.o
 iwlcore-objs           += iwl-scan.o
 iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o
 iwlcore-$(CONFIG_IWLWIFI_LEDS) += iwl-led.o
-iwlcore-$(CONFIG_IWLWIFI_RFKILL) += iwl-rfkill.o
 iwlcore-$(CONFIG_IWLWIFI_SPECTRUM_MEASUREMENT) += iwl-spectrum.o
 
 obj-$(CONFIG_IWLAGN)   += iwlagn.o
index ac22f59be9efdbd3400f87c845c67175141d0391..225e5f889346806203e2eab6e2a985e6dd74fe4e 100644 (file)
 #include "iwl-core.h"
 #include "iwl-dev.h"
 
+#ifdef CONFIG_IWLWIFI_DEBUG
+static const char *led_type_str[] = {
+       __stringify(IWL_LED_TRG_TX),
+       __stringify(IWL_LED_TRG_RX),
+       __stringify(IWL_LED_TRG_ASSOC),
+       __stringify(IWL_LED_TRG_RADIO),
+       NULL
+};
+#endif /* CONFIG_IWLWIFI_DEBUG */
 
 static const struct {
        u16 brightness;
@@ -61,7 +70,7 @@ static const struct {
        {10, 110, 110},
        {5, 130, 130},
        {0, 167, 167},
-       /*SOLID_ON*/
+       /* SOLID_ON */
        {-1, IWL_LED_SOLID, 0}
 };
 
@@ -142,6 +151,26 @@ static int iwl3945_led_off(struct iwl_priv *priv, int led_id)
        return iwl_send_led_cmd(priv, &led_cmd);
 }
 
+/*
+ *  Set led on in case of association
+ *  */
+static int iwl3945_led_associate(struct iwl_priv *priv, int led_id)
+{
+       IWL_DEBUG_LED(priv, "Associated\n");
+
+       priv->allow_blinking = 1;
+       return iwl3945_led_on(priv, led_id);
+}
+/* Set Led off in case of disassociation */
+static int iwl3945_led_disassociate(struct iwl_priv *priv, int led_id)
+{
+       IWL_DEBUG_LED(priv, "Disassociated\n");
+
+       priv->allow_blinking = 0;
+
+       return 0;
+}
+
 /*
  * brightness call back function for Tx/Rx LED
  */
@@ -165,26 +194,21 @@ static void iwl3945_led_brightness_set(struct led_classdev *led_cdev,
                                enum led_brightness brightness)
 {
        struct iwl_led *led = container_of(led_cdev,
-                                              struct iwl_led, led_dev);
+                                          struct iwl_led, led_dev);
        struct iwl_priv *priv = led->priv;
 
        if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
 
+       IWL_DEBUG_LED(priv, "Led type = %s brightness = %d\n",
+                       led_type_str[led->type], brightness);
+
        switch (brightness) {
        case LED_FULL:
-               if (led->type == IWL_LED_TRG_ASSOC) {
-                       priv->allow_blinking = 1;
-                       IWL_DEBUG_LED(priv, "MAC is  associated\n");
-               }
                if (led->led_on)
                        led->led_on(priv, IWL_LED_LINK);
                break;
        case LED_OFF:
-               if (led->type == IWL_LED_TRG_ASSOC) {
-                       priv->allow_blinking = 0;
-                       IWL_DEBUG_LED(priv, "MAC is disassociated\n");
-               }
                if (led->led_off)
                        led->led_off(priv, IWL_LED_LINK);
                break;
@@ -197,8 +221,6 @@ static void iwl3945_led_brightness_set(struct led_classdev *led_cdev,
        }
 }
 
-
-
 /*
  * Register led class with the system
  */
@@ -237,12 +259,12 @@ static int iwl3945_led_register_led(struct iwl_priv *priv,
 static inline u8 get_blink_rate(struct iwl_priv *priv)
 {
        int index;
-       u64 current_tpt = priv->rxtxpackets;
-       s64 tpt = current_tpt - priv->led_tpt;
+       s64 tpt = priv->rxtxpackets;
 
        if (tpt < 0)
                tpt = -tpt;
-       priv->led_tpt = current_tpt;
+
+       IWL_DEBUG_LED(priv, "tpt %lld \n", (long long)tpt);
 
        if (!priv->allow_blinking)
                index = IWL_MAX_BLINK_TBL;
@@ -250,13 +272,9 @@ static inline u8 get_blink_rate(struct iwl_priv *priv)
                for (index = 0; index < IWL_MAX_BLINK_TBL; index++)
                        if (tpt > (blink_tbl[index].brightness * IWL_1MB_RATE))
                                break;
-       return index;
-}
 
-static inline int is_rf_kill(struct iwl_priv *priv)
-{
-       return test_bit(STATUS_RF_KILL_HW, &priv->status) ||
-               test_bit(STATUS_RF_KILL_SW, &priv->status);
+       IWL_DEBUG_LED(priv, "LED BLINK IDX=%d\n", index);
+       return index;
 }
 
 /*
@@ -272,7 +290,7 @@ void iwl3945_led_background(struct iwl_priv *priv)
                priv->last_blink_time = 0;
                return;
        }
-       if (is_rf_kill(priv)) {
+       if (iwl_is_rfkill(priv)) {
                priv->last_blink_time = 0;
                return;
        }
@@ -341,8 +359,8 @@ int iwl3945_led_register(struct iwl_priv *priv)
                                   IWL_LED_TRG_ASSOC, 0, trigger);
 
        /* for assoc always turn led on */
-       priv->led[IWL_LED_TRG_ASSOC].led_on = iwl3945_led_on;
-       priv->led[IWL_LED_TRG_ASSOC].led_off = iwl3945_led_on;
+       priv->led[IWL_LED_TRG_ASSOC].led_on = iwl3945_led_associate;
+       priv->led[IWL_LED_TRG_ASSOC].led_off = iwl3945_led_disassociate;
        priv->led[IWL_LED_TRG_ASSOC].led_pattern = NULL;
 
        if (ret)
index af6b9d4447782512a6fc020bf65c45a8a1ac5c7e..5eb538d18a80115fe3eeb2b4ca873a0139290dea 100644 (file)
@@ -38,6 +38,7 @@
 
 #include "iwl-commands.h"
 #include "iwl-3945.h"
+#include "iwl-sta.h"
 
 #define RS_NAME "iwl-3945-rs"
 
@@ -683,11 +684,10 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
        if (sta)
                rate_mask = sta->supp_rates[sband->band];
 
-       /* Send management frames and broadcast/multicast data using lowest
-        * rate. */
+       /* Send management frames and NO_ACK data using lowest rate. */
        fc = le16_to_cpu(hdr->frame_control);
        if ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA ||
-           is_multicast_ether_addr(hdr->addr1) ||
+           info->flags & IEEE80211_TX_CTL_NO_ACK ||
            !sta || !priv_sta) {
                IWL_DEBUG_RATE(priv, "leave: No STA priv data to update!\n");
                if (!rate_mask)
@@ -696,6 +696,8 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
                else
                        info->control.rates[0].idx =
                                        rate_lowest_index(sband, sta);
+               if (info->flags & IEEE80211_TX_CTL_NO_ACK)
+                       info->control.rates[0].count = 1;
                return;
        }
 
@@ -713,13 +715,13 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
 
        if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) &&
            !rs_sta->ibss_sta_added) {
-               u8 sta_id = iwl3945_hw_find_station(priv, hdr->addr1);
+               u8 sta_id = iwl_find_station(priv, hdr->addr1);
 
                if (sta_id == IWL_INVALID_STATION) {
                        IWL_DEBUG_RATE(priv, "LQ: ADD station %pm\n",
                                       hdr->addr1);
-                       sta_id = iwl3945_add_station(priv,
-                                   hdr->addr1, 0, CMD_ASYNC);
+                       sta_id = iwl_add_station(priv, hdr->addr1, false,
+                               CMD_ASYNC, NULL);
                }
                if (sta_id != IWL_INVALID_STATION)
                        rs_sta->ibss_sta_added = 1;
@@ -974,7 +976,7 @@ void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id)
 
        rcu_read_lock();
 
-       sta = ieee80211_find_sta(hw, priv->stations_39[sta_id].sta.sta.addr);
+       sta = ieee80211_find_sta(hw, priv->stations[sta_id].sta.sta.addr);
        if (!sta) {
                rcu_read_unlock();
                return;
index 527525cc0919e523dc1f813b54d68935224e0880..46288e724889b05e8e17cb506daf4b4ffad4774a 100644 (file)
@@ -98,7 +98,6 @@ const struct iwl3945_rate_info iwl3945_rates[IWL_RATE_COUNT_3945] = {
  *   ... and set IWL_EVT_DISABLE to 1. */
 void iwl3945_disable_events(struct iwl_priv *priv)
 {
-       int ret;
        int i;
        u32 base;               /* SRAM address of event log header */
        u32 disable_ptr;        /* SRAM address of event-disable bitmap array */
@@ -159,26 +158,17 @@ void iwl3945_disable_events(struct iwl_priv *priv)
                return;
        }
 
-       ret = iwl_grab_nic_access(priv);
-       if (ret) {
-               IWL_WARN(priv, "Can not read from adapter at this time.\n");
-               return;
-       }
-
        disable_ptr = iwl_read_targ_mem(priv, base + (4 * sizeof(u32)));
        array_size = iwl_read_targ_mem(priv, base + (5 * sizeof(u32)));
-       iwl_release_nic_access(priv);
 
        if (IWL_EVT_DISABLE && (array_size == IWL_EVT_DISABLE_SIZE)) {
                IWL_DEBUG_INFO(priv, "Disabling selected uCode log events at 0x%x\n",
                               disable_ptr);
-               ret = iwl_grab_nic_access(priv);
                for (i = 0; i < IWL_EVT_DISABLE_SIZE; i++)
                        iwl_write_targ_mem(priv,
                                           disable_ptr + (i * sizeof(u32)),
                                           evt_disable[i]);
 
-               iwl_release_nic_access(priv);
        } else {
                IWL_DEBUG_INFO(priv, "Selected uCode log events may be disabled\n");
                IWL_DEBUG_INFO(priv, "  by writing \"1\"s into disable bitmap\n");
@@ -779,35 +769,6 @@ void iwl3945_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq)
        return ;
 }
 
-u8 iwl3945_hw_find_station(struct iwl_priv *priv, const u8 *addr)
-{
-       int i, start = IWL_AP_ID;
-       int ret = IWL_INVALID_STATION;
-       unsigned long flags;
-
-       if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) ||
-           (priv->iw_mode == NL80211_IFTYPE_AP))
-               start = IWL_STA_ID;
-
-       if (is_broadcast_ether_addr(addr))
-               return priv->hw_params.bcast_sta_id;
-
-       spin_lock_irqsave(&priv->sta_lock, flags);
-       for (i = start; i < priv->hw_params.max_stations; i++)
-               if ((priv->stations_39[i].used) &&
-                   (!compare_ether_addr
-                    (priv->stations_39[i].sta.sta.addr, addr))) {
-                       ret = i;
-                       goto out;
-               }
-
-       IWL_DEBUG_INFO(priv, "can not find STA %pM (total %d)\n",
-                      addr, priv->num_stations);
- out:
-       spin_unlock_irqrestore(&priv->sta_lock, flags);
-       return ret;
-}
-
 /**
  * iwl3945_hw_build_tx_cmd_rate - Add rate portion to TX_CMD:
  *
@@ -885,13 +846,13 @@ void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv, struct iwl_cmd *cmd,
 u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id, u16 tx_rate, u8 flags)
 {
        unsigned long flags_spin;
-       struct iwl3945_station_entry *station;
+       struct iwl_station_entry *station;
 
        if (sta_id == IWL_INVALID_STATION)
                return IWL_INVALID_STATION;
 
        spin_lock_irqsave(&priv->sta_lock, flags_spin);
-       station = &priv->stations_39[sta_id];
+       station = &priv->stations[sta_id];
 
        station->sta.sta.modify_mask = STA_MODIFY_TX_RATE_MSK;
        station->sta.rate_n_flags = cpu_to_le16(tx_rate);
@@ -899,8 +860,7 @@ u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id, u16 tx_rate, u8 flags)
 
        spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
 
-       iwl_send_add_sta(priv,
-                        (struct iwl_addsta_cmd *)&station->sta, flags);
+       iwl_send_add_sta(priv, &station->sta, flags);
        IWL_DEBUG_RATE(priv, "SCALE sync station %d to rate %d\n",
                        sta_id, tx_rate);
        return sta_id;
@@ -908,55 +868,30 @@ u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id, u16 tx_rate, u8 flags)
 
 static int iwl3945_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src)
 {
-       int ret;
-       unsigned long flags;
-
-       spin_lock_irqsave(&priv->lock, flags);
-       ret = iwl_grab_nic_access(priv);
-       if (ret) {
-               spin_unlock_irqrestore(&priv->lock, flags);
-               return ret;
-       }
-
        if (src == IWL_PWR_SRC_VAUX) {
                if (pci_pme_capable(priv->pci_dev, PCI_D3cold)) {
                        iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
                                        APMG_PS_CTRL_VAL_PWR_SRC_VAUX,
                                        ~APMG_PS_CTRL_MSK_PWR_SRC);
-                       iwl_release_nic_access(priv);
 
                        iwl_poll_bit(priv, CSR_GPIO_IN,
                                     CSR_GPIO_IN_VAL_VAUX_PWR_SRC,
                                     CSR_GPIO_IN_BIT_AUX_POWER, 5000);
-               } else {
-                       iwl_release_nic_access(priv);
                }
        } else {
                iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
                                APMG_PS_CTRL_VAL_PWR_SRC_VMAIN,
                                ~APMG_PS_CTRL_MSK_PWR_SRC);
 
-               iwl_release_nic_access(priv);
                iwl_poll_bit(priv, CSR_GPIO_IN, CSR_GPIO_IN_VAL_VMAIN_PWR_SRC,
                             CSR_GPIO_IN_BIT_AUX_POWER, 5000);  /* uS */
        }
-       spin_unlock_irqrestore(&priv->lock, flags);
 
-       return ret;
+       return 0;
 }
 
 static int iwl3945_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
 {
-       int rc;
-       unsigned long flags;
-
-       spin_lock_irqsave(&priv->lock, flags);
-       rc = iwl_grab_nic_access(priv);
-       if (rc) {
-               spin_unlock_irqrestore(&priv->lock, flags);
-               return rc;
-       }
-
        iwl_write_direct32(priv, FH39_RCSR_RBD_BASE(0), rxq->dma_addr);
        iwl_write_direct32(priv, FH39_RCSR_RPTR_ADDR(0), rxq->rb_stts_dma);
        iwl_write_direct32(priv, FH39_RCSR_WPTR(0), 0);
@@ -973,23 +908,11 @@ static int iwl3945_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
        /* fake read to flush all prev I/O */
        iwl_read_direct32(priv, FH39_RSSR_CTRL);
 
-       iwl_release_nic_access(priv);
-       spin_unlock_irqrestore(&priv->lock, flags);
-
        return 0;
 }
 
 static int iwl3945_tx_reset(struct iwl_priv *priv)
 {
-       int rc;
-       unsigned long flags;
-
-       spin_lock_irqsave(&priv->lock, flags);
-       rc = iwl_grab_nic_access(priv);
-       if (rc) {
-               spin_unlock_irqrestore(&priv->lock, flags);
-               return rc;
-       }
 
        /* bypass mode */
        iwl_write_prph(priv, ALM_SCD_MODE_REG, 0x2);
@@ -1017,8 +940,6 @@ static int iwl3945_tx_reset(struct iwl_priv *priv)
                FH39_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RSP_WAIT_TH |
                FH39_TSSR_TX_MSG_CONFIG_REG_VAL_RSP_WAIT_TH);
 
-       iwl_release_nic_access(priv);
-       spin_unlock_irqrestore(&priv->lock, flags);
 
        return 0;
 }
@@ -1061,7 +982,7 @@ static int iwl3945_txq_ctx_reset(struct iwl_priv *priv)
 
 static int iwl3945_apm_init(struct iwl_priv *priv)
 {
-       int ret = 0;
+       int ret;
 
        iwl_power_initialize(priv);
 
@@ -1083,10 +1004,6 @@ static int iwl3945_apm_init(struct iwl_priv *priv)
                goto out;
        }
 
-       ret = iwl_grab_nic_access(priv);
-       if (ret)
-               goto out;
-
        /* enable DMA */
        iwl_write_prph(priv, APMG_CLK_CTRL_REG, APMG_CLK_VAL_DMA_CLK_RQT |
                                                APMG_CLK_VAL_BSM_CLK_RQT);
@@ -1097,7 +1014,6 @@ static int iwl3945_apm_init(struct iwl_priv *priv)
        iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG,
                          APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
 
-       iwl_release_nic_access(priv);
 out:
        return ret;
 }
@@ -1110,6 +1026,11 @@ static void iwl3945_nic_config(struct iwl_priv *priv)
 
        spin_lock_irqsave(&priv->lock, flags);
 
+       /* Determine HW type */
+       pci_read_config_byte(priv->pci_dev, PCI_REVISION_ID, &rev_id);
+
+       IWL_DEBUG_INFO(priv, "HW Revision ID = 0x%X\n", rev_id);
+
        if (rev_id & PCI_CFG_REV_ID_BIT_RTP)
                IWL_DEBUG_INFO(priv, "RTP type \n");
        else if (rev_id & PCI_CFG_REV_ID_BIT_BASIC_SKU) {
@@ -1163,7 +1084,6 @@ static void iwl3945_nic_config(struct iwl_priv *priv)
 
 int iwl3945_hw_nic_init(struct iwl_priv *priv)
 {
-       u8 rev_id;
        int rc;
        unsigned long flags;
        struct iwl_rx_queue *rxq = &priv->rxq;
@@ -1172,12 +1092,6 @@ int iwl3945_hw_nic_init(struct iwl_priv *priv)
        priv->cfg->ops->lib->apm_ops.init(priv);
        spin_unlock_irqrestore(&priv->lock, flags);
 
-       /* Determine HW type */
-       rc = pci_read_config_byte(priv->pci_dev, PCI_REVISION_ID, &rev_id);
-       if (rc)
-               return rc;
-       IWL_DEBUG_INFO(priv, "HW Revision ID = 0x%X\n", rev_id);
-
        rc = priv->cfg->ops->lib->apm_ops.set_pwr_src(priv, IWL_PWR_SRC_VMAIN);
        if (rc)
                return rc;
@@ -1198,22 +1112,13 @@ int iwl3945_hw_nic_init(struct iwl_priv *priv)
 
        iwl3945_rx_init(priv, rxq);
 
-       spin_lock_irqsave(&priv->lock, flags);
 
        /* Look at using this instead:
        rxq->need_update = 1;
        iwl_rx_queue_update_write_ptr(priv, rxq);
        */
 
-       rc = iwl_grab_nic_access(priv);
-       if (rc) {
-               spin_unlock_irqrestore(&priv->lock, flags);
-               return rc;
-       }
        iwl_write_direct32(priv, FH39_RCSR_WPTR(0), rxq->write & ~7);
-       iwl_release_nic_access(priv);
-
-       spin_unlock_irqrestore(&priv->lock, flags);
 
        rc = iwl3945_txq_ctx_reset(priv);
        if (rc)
@@ -1245,14 +1150,6 @@ void iwl3945_hw_txq_ctx_free(struct iwl_priv *priv)
 void iwl3945_hw_txq_ctx_stop(struct iwl_priv *priv)
 {
        int txq_id;
-       unsigned long flags;
-
-       spin_lock_irqsave(&priv->lock, flags);
-       if (iwl_grab_nic_access(priv)) {
-               spin_unlock_irqrestore(&priv->lock, flags);
-               iwl3945_hw_txq_ctx_free(priv);
-               return;
-       }
 
        /* stop SCD */
        iwl_write_prph(priv, ALM_SCD_MODE_REG, 0);
@@ -1265,9 +1162,6 @@ void iwl3945_hw_txq_ctx_stop(struct iwl_priv *priv)
                                1000);
        }
 
-       iwl_release_nic_access(priv);
-       spin_unlock_irqrestore(&priv->lock, flags);
-
        iwl3945_hw_txq_ctx_free(priv);
 }
 
@@ -1312,12 +1206,8 @@ static void iwl3945_apm_stop(struct iwl_priv *priv)
 
 static int iwl3945_apm_reset(struct iwl_priv *priv)
 {
-       int rc;
-       unsigned long flags;
-
        iwl3945_apm_stop_master(priv);
 
-       spin_lock_irqsave(&priv->lock, flags);
 
        iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
        udelay(10);
@@ -1327,36 +1217,31 @@ static int iwl3945_apm_reset(struct iwl_priv *priv)
        iwl_poll_direct_bit(priv, CSR_GP_CNTRL,
                         CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
 
-       rc = iwl_grab_nic_access(priv);
-       if (!rc) {
-               iwl_write_prph(priv, APMG_CLK_CTRL_REG,
-                                        APMG_CLK_VAL_BSM_CLK_RQT);
+       iwl_write_prph(priv, APMG_CLK_CTRL_REG,
+                               APMG_CLK_VAL_BSM_CLK_RQT);
 
-               iwl_write_prph(priv, APMG_RTC_INT_MSK_REG, 0x0);
-               iwl_write_prph(priv, APMG_RTC_INT_STT_REG,
+       iwl_write_prph(priv, APMG_RTC_INT_MSK_REG, 0x0);
+       iwl_write_prph(priv, APMG_RTC_INT_STT_REG,
                                        0xFFFFFFFF);
 
-               /* enable DMA */
-               iwl_write_prph(priv, APMG_CLK_EN_REG,
-                                        APMG_CLK_VAL_DMA_CLK_RQT |
-                                        APMG_CLK_VAL_BSM_CLK_RQT);
-               udelay(10);
+       /* enable DMA */
+       iwl_write_prph(priv, APMG_CLK_EN_REG,
+                               APMG_CLK_VAL_DMA_CLK_RQT |
+                               APMG_CLK_VAL_BSM_CLK_RQT);
+       udelay(10);
 
-               iwl_set_bits_prph(priv, APMG_PS_CTRL_REG,
+       iwl_set_bits_prph(priv, APMG_PS_CTRL_REG,
                                APMG_PS_CTRL_VAL_RESET_REQ);
-               udelay(5);
-               iwl_clear_bits_prph(priv, APMG_PS_CTRL_REG,
+       udelay(5);
+       iwl_clear_bits_prph(priv, APMG_PS_CTRL_REG,
                                APMG_PS_CTRL_VAL_RESET_REQ);
-               iwl_release_nic_access(priv);
-       }
 
        /* Clear the 'host command active' bit... */
        clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
 
        wake_up_interruptible(&priv->wait_command_queue);
-       spin_unlock_irqrestore(&priv->lock, flags);
 
-       return rc;
+       return 0;
 }
 
 /**
@@ -1964,6 +1849,193 @@ int iwl3945_hw_reg_set_txpower(struct iwl_priv *priv, s8 power)
        return 0;
 }
 
+static int iwl3945_send_rxon_assoc(struct iwl_priv *priv)
+{
+       int rc = 0;
+       struct iwl_rx_packet *res = NULL;
+       struct iwl3945_rxon_assoc_cmd rxon_assoc;
+       struct iwl_host_cmd cmd = {
+               .id = REPLY_RXON_ASSOC,
+               .len = sizeof(rxon_assoc),
+               .meta.flags = CMD_WANT_SKB,
+               .data = &rxon_assoc,
+       };
+       const struct iwl_rxon_cmd *rxon1 = &priv->staging_rxon;
+       const struct iwl_rxon_cmd *rxon2 = &priv->active_rxon;
+
+       if ((rxon1->flags == rxon2->flags) &&
+           (rxon1->filter_flags == rxon2->filter_flags) &&
+           (rxon1->cck_basic_rates == rxon2->cck_basic_rates) &&
+           (rxon1->ofdm_basic_rates == rxon2->ofdm_basic_rates)) {
+               IWL_DEBUG_INFO(priv, "Using current RXON_ASSOC.  Not resending.\n");
+               return 0;
+       }
+
+       rxon_assoc.flags = priv->staging_rxon.flags;
+       rxon_assoc.filter_flags = priv->staging_rxon.filter_flags;
+       rxon_assoc.ofdm_basic_rates = priv->staging_rxon.ofdm_basic_rates;
+       rxon_assoc.cck_basic_rates = priv->staging_rxon.cck_basic_rates;
+       rxon_assoc.reserved = 0;
+
+       rc = iwl_send_cmd_sync(priv, &cmd);
+       if (rc)
+               return rc;
+
+       res = (struct iwl_rx_packet *)cmd.meta.u.skb->data;
+       if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
+               IWL_ERR(priv, "Bad return from REPLY_RXON_ASSOC command\n");
+               rc = -EIO;
+       }
+
+       priv->alloc_rxb_skb--;
+       dev_kfree_skb_any(cmd.meta.u.skb);
+
+       return rc;
+}
+
+/**
+ * iwl3945_commit_rxon - commit staging_rxon to hardware
+ *
+ * The RXON command in staging_rxon is committed to the hardware and
+ * the active_rxon structure is updated with the new data.  This
+ * function correctly transitions out of the RXON_ASSOC_MSK state if
+ * a HW tune is required based on the RXON structure changes.
+ */
+static int iwl3945_commit_rxon(struct iwl_priv *priv)
+{
+       /* cast away the const for active_rxon in this function */
+       struct iwl3945_rxon_cmd *active_rxon = (void *)&priv->active_rxon;
+       struct iwl3945_rxon_cmd *staging_rxon = (void *)&priv->staging_rxon;
+       int rc = 0;
+       bool new_assoc =
+               !!(priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK);
+
+       if (!iwl_is_alive(priv))
+               return -1;
+
+       /* always get timestamp with Rx frame */
+       staging_rxon->flags |= RXON_FLG_TSF2HOST_MSK;
+
+       /* select antenna */
+       staging_rxon->flags &=
+           ~(RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_SEL_MSK);
+       staging_rxon->flags |= iwl3945_get_antenna_flags(priv);
+
+       rc = iwl_check_rxon_cmd(priv);
+       if (rc) {
+               IWL_ERR(priv, "Invalid RXON configuration.  Not committing.\n");
+               return -EINVAL;
+       }
+
+       /* If we don't need to send a full RXON, we can use
+        * iwl3945_rxon_assoc_cmd which is used to reconfigure filter
+        * and other flags for the current radio configuration. */
+       if (!iwl_full_rxon_required(priv)) {
+               rc = iwl_send_rxon_assoc(priv);
+               if (rc) {
+                       IWL_ERR(priv, "Error setting RXON_ASSOC "
+                                 "configuration (%d).\n", rc);
+                       return rc;
+               }
+
+               memcpy(active_rxon, staging_rxon, sizeof(*active_rxon));
+
+               return 0;
+       }
+
+       /* If we are currently associated and the new config requires
+        * an RXON_ASSOC and the new config wants the associated mask enabled,
+        * we must clear the associated from the active configuration
+        * before we apply the new config */
+       if (iwl_is_associated(priv) && new_assoc) {
+               IWL_DEBUG_INFO(priv, "Toggling associated bit on current RXON\n");
+               active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+
+               /*
+                * reserved4 and 5 could have been filled by the iwlcore code.
+                * Let's clear them before pushing to the 3945.
+                */
+               active_rxon->reserved4 = 0;
+               active_rxon->reserved5 = 0;
+               rc = iwl_send_cmd_pdu(priv, REPLY_RXON,
+                                     sizeof(struct iwl3945_rxon_cmd),
+                                     &priv->active_rxon);
+
+               /* If the mask clearing failed then we set
+                * active_rxon back to what it was previously */
+               if (rc) {
+                       active_rxon->filter_flags |= RXON_FILTER_ASSOC_MSK;
+                       IWL_ERR(priv, "Error clearing ASSOC_MSK on current "
+                                 "configuration (%d).\n", rc);
+                       return rc;
+               }
+       }
+
+       IWL_DEBUG_INFO(priv, "Sending RXON\n"
+                      "* with%s RXON_FILTER_ASSOC_MSK\n"
+                      "* channel = %d\n"
+                      "* bssid = %pM\n",
+                      (new_assoc ? "" : "out"),
+                      le16_to_cpu(staging_rxon->channel),
+                      staging_rxon->bssid_addr);
+
+       /*
+        * reserved4 and 5 could have been filled by the iwlcore code.
+        * Let's clear them before pushing to the 3945.
+        */
+       staging_rxon->reserved4 = 0;
+       staging_rxon->reserved5 = 0;
+
+       iwl_set_rxon_hwcrypto(priv, !priv->hw_params.sw_crypto);
+
+       /* Apply the new configuration */
+       rc = iwl_send_cmd_pdu(priv, REPLY_RXON,
+                             sizeof(struct iwl3945_rxon_cmd),
+                             staging_rxon);
+       if (rc) {
+               IWL_ERR(priv, "Error setting new configuration (%d).\n", rc);
+               return rc;
+       }
+
+       memcpy(active_rxon, staging_rxon, sizeof(*active_rxon));
+
+       iwl_clear_stations_table(priv);
+
+       /* If we issue a new RXON command which required a tune then we must
+        * send a new TXPOWER command or we won't be able to Tx any frames */
+       rc = priv->cfg->ops->lib->send_tx_power(priv);
+       if (rc) {
+               IWL_ERR(priv, "Error setting Tx power (%d).\n", rc);
+               return rc;
+       }
+
+       /* Add the broadcast address so we can send broadcast frames */
+       if (iwl_add_station(priv, iwl_bcast_addr, false, CMD_SYNC, NULL) ==
+           IWL_INVALID_STATION) {
+               IWL_ERR(priv, "Error adding BROADCAST address for transmit.\n");
+               return -EIO;
+       }
+
+       /* If we have set the ASSOC_MSK and we are in BSS mode then
+        * add the IWL_AP_ID to the station rate table */
+       if (iwl_is_associated(priv) &&
+           (priv->iw_mode == NL80211_IFTYPE_STATION))
+               if (iwl_add_station(priv, priv->active_rxon.bssid_addr,
+                               true, CMD_SYNC, NULL) == IWL_INVALID_STATION) {
+                       IWL_ERR(priv, "Error adding AP address for transmit\n");
+                       return -EIO;
+               }
+
+       /* Init the hardware's rate fallback order based on the band */
+       rc = iwl3945_init_hw_rate_table(priv);
+       if (rc) {
+               IWL_ERR(priv, "Error setting HW rate table: %02X\n", rc);
+               return -EIO;
+       }
+
+       return 0;
+}
+
 /* will add 3945 channel switch cmd handling later */
 int iwl3945_hw_channel_switch(struct iwl_priv *priv, u16 channel)
 {
@@ -2314,14 +2386,6 @@ int iwl3945_txpower_set_from_eeprom(struct iwl_priv *priv)
 int iwl3945_hw_rxq_stop(struct iwl_priv *priv)
 {
        int rc;
-       unsigned long flags;
-
-       spin_lock_irqsave(&priv->lock, flags);
-       rc = iwl_grab_nic_access(priv);
-       if (rc) {
-               spin_unlock_irqrestore(&priv->lock, flags);
-               return rc;
-       }
 
        iwl_write_direct32(priv, FH39_RCSR_CONFIG(0), 0);
        rc = iwl_poll_direct_bit(priv, FH39_RSSR_STATUS,
@@ -2329,28 +2393,17 @@ int iwl3945_hw_rxq_stop(struct iwl_priv *priv)
        if (rc < 0)
                IWL_ERR(priv, "Can't stop Rx DMA.\n");
 
-       iwl_release_nic_access(priv);
-       spin_unlock_irqrestore(&priv->lock, flags);
-
        return 0;
 }
 
 int iwl3945_hw_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq)
 {
-       int rc;
-       unsigned long flags;
        int txq_id = txq->q.id;
 
        struct iwl3945_shared *shared_data = priv->shared_virt;
 
        shared_data->tx_base_ptr[txq_id] = cpu_to_le32((u32)txq->q.dma_addr);
 
-       spin_lock_irqsave(&priv->lock, flags);
-       rc = iwl_grab_nic_access(priv);
-       if (rc) {
-               spin_unlock_irqrestore(&priv->lock, flags);
-               return rc;
-       }
        iwl_write_direct32(priv, FH39_CBCC_CTRL(txq_id), 0);
        iwl_write_direct32(priv, FH39_CBCC_BASE(txq_id), 0);
 
@@ -2360,11 +2413,9 @@ int iwl3945_hw_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq)
                FH39_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_IFTFD |
                FH39_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL |
                FH39_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE);
-       iwl_release_nic_access(priv);
 
        /* fake read to flush all prev. writes */
        iwl_read32(priv, FH39_TSSR_CBB_BASE);
-       spin_unlock_irqrestore(&priv->lock, flags);
 
        return 0;
 }
@@ -2384,13 +2435,25 @@ static u16 iwl3945_get_hcmd_size(u8 cmd_id, u16 len)
        }
 }
 
+
 static u16 iwl3945_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data)
 {
-       u16 size = (u16)sizeof(struct iwl3945_addsta_cmd);
-       memcpy(data, cmd, size);
-       return size;
+       struct iwl3945_addsta_cmd *addsta = (struct iwl3945_addsta_cmd *)data;
+       addsta->mode = cmd->mode;
+       memcpy(&addsta->sta, &cmd->sta, sizeof(struct sta_id_modify));
+       memcpy(&addsta->key, &cmd->key, sizeof(struct iwl4965_keyinfo));
+       addsta->station_flags = cmd->station_flags;
+       addsta->station_flags_msk = cmd->station_flags_msk;
+       addsta->tid_disable_tx = cpu_to_le16(0);
+       addsta->rate_n_flags = cmd->rate_n_flags;
+       addsta->add_immediate_ba_tid = cmd->add_immediate_ba_tid;
+       addsta->remove_immediate_ba_tid = cmd->remove_immediate_ba_tid;
+       addsta->add_immediate_ba_ssn = cmd->add_immediate_ba_ssn;
+
+       return (u16)sizeof(struct iwl3945_addsta_cmd);
 }
 
+
 /**
  * iwl3945_init_hw_rate_table - Initialize the hardware rate fallback table
  */
@@ -2672,10 +2735,6 @@ static int iwl3945_load_bsm(struct iwl_priv *priv)
        inst_len = priv->ucode_init.len;
        data_len = priv->ucode_init_data.len;
 
-       rc = iwl_grab_nic_access(priv);
-       if (rc)
-               return rc;
-
        iwl_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst);
        iwl_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata);
        iwl_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG, inst_len);
@@ -2689,10 +2748,8 @@ static int iwl3945_load_bsm(struct iwl_priv *priv)
                                          le32_to_cpu(*image));
 
        rc = iwl3945_verify_bsm(priv);
-       if (rc) {
-               iwl_release_nic_access(priv);
+       if (rc)
                return rc;
-       }
 
        /* Tell BSM to copy from BSM SRAM into instruction SRAM, when asked */
        iwl_write_prph(priv, BSM_WR_MEM_SRC_REG, 0x0);
@@ -2724,11 +2781,14 @@ static int iwl3945_load_bsm(struct iwl_priv *priv)
        iwl_write_prph(priv, BSM_WR_CTRL_REG,
                BSM_WR_CTRL_REG_BIT_START_EN);
 
-       iwl_release_nic_access(priv);
-
        return 0;
 }
 
+static struct iwl_hcmd_ops iwl3945_hcmd = {
+       .rxon_assoc = iwl3945_send_rxon_assoc,
+       .commit_rxon = iwl3945_commit_rxon,
+};
+
 static struct iwl_lib_ops iwl3945_lib = {
        .txq_attach_buf_to_tfd = iwl3945_hw_txq_attach_buf_to_tfd,
        .txq_free_tfd = iwl3945_hw_txq_free_tfd,
@@ -2758,6 +2818,9 @@ static struct iwl_lib_ops iwl3945_lib = {
        },
        .send_tx_power  = iwl3945_send_tx_power,
        .is_valid_rtc_data_addr = iwl3945_hw_valid_rtc_data_addr,
+       .post_associate = iwl3945_post_associate,
+       .isr = iwl_isr_legacy,
+       .config_ap = iwl3945_config_ap,
 };
 
 static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = {
@@ -2767,6 +2830,7 @@ static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = {
 
 static struct iwl_ops iwl3945_ops = {
        .lib = &iwl3945_lib,
+       .hcmd = &iwl3945_hcmd,
        .utils = &iwl3945_hcmd_utils,
 };
 
@@ -2779,7 +2843,8 @@ static struct iwl_cfg iwl3945_bg_cfg = {
        .eeprom_size = IWL3945_EEPROM_IMG_SIZE,
        .eeprom_ver = EEPROM_3945_EEPROM_VERSION,
        .ops = &iwl3945_ops,
-       .mod_params = &iwl3945_mod_params
+       .mod_params = &iwl3945_mod_params,
+       .use_isr_legacy = true
 };
 
 static struct iwl_cfg iwl3945_abg_cfg = {
@@ -2791,7 +2856,8 @@ static struct iwl_cfg iwl3945_abg_cfg = {
        .eeprom_size = IWL3945_EEPROM_IMG_SIZE,
        .eeprom_ver = EEPROM_3945_EEPROM_VERSION,
        .ops = &iwl3945_ops,
-       .mod_params = &iwl3945_mod_params
+       .mod_params = &iwl3945_mod_params,
+       .use_isr_legacy = true
 };
 
 struct pci_device_id iwl3945_hw_card_ids[] = {
index 55188844657b16c80cd22b1a509c3961c241a467..fbb3a573463e29c882d9576d442ae75dba1e4e93 100644 (file)
 #include <linux/kernel.h>
 #include <net/ieee80211_radiotap.h>
 
-/*used for rfkill*/
-#include <linux/rfkill.h>
-#include <linux/input.h>
-
 /* Hardware specific file defines the PCI IDs table for that hardware module */
 extern struct pci_device_id iwl3945_hw_card_ids[];
 
@@ -155,14 +151,12 @@ struct iwl3945_frame {
 #define STATUS_HCMD_SYNC_ACTIVE        1       /* sync host command in progress */
 #define STATUS_INT_ENABLED     2
 #define STATUS_RF_KILL_HW      3
-#define STATUS_RF_KILL_SW      4
 #define STATUS_INIT            5
 #define STATUS_ALIVE           6
 #define STATUS_READY           7
 #define STATUS_TEMPERATURE     8
 #define STATUS_GEO_CONFIGURED  9
 #define STATUS_EXIT_PENDING    10
-#define STATUS_IN_SUSPEND      11
 #define STATUS_STATISTICS      12
 #define STATUS_SCANNING                13
 #define STATUS_SCAN_ABORTING   14
@@ -203,11 +197,6 @@ struct iwl3945_ibss_seq {
  * for use by iwl-*.c
  *
  *****************************************************************************/
-struct iwl3945_addsta_cmd;
-extern int iwl3945_send_add_station(struct iwl_priv *priv,
-                               struct iwl3945_addsta_cmd *sta, u8 flags);
-extern u8 iwl3945_add_station(struct iwl_priv *priv, const u8 *bssid,
-                         int is_ap, u8 flags);
 extern int iwl3945_power_init_handle(struct iwl_priv *priv);
 extern int iwl3945_eeprom_init(struct iwl_priv *priv);
 extern int iwl3945_calc_db_from_ratio(int sig_ratio);
@@ -278,6 +267,8 @@ extern void iwl3945_hw_rx_statistics(struct iwl_priv *priv,
                                 struct iwl_rx_mem_buffer *rxb);
 extern void iwl3945_disable_events(struct iwl_priv *priv);
 extern int iwl4965_get_temperature(const struct iwl_priv *priv);
+extern void iwl3945_post_associate(struct iwl_priv *priv);
+extern void iwl3945_config_ap(struct iwl_priv *priv);
 
 /**
  * iwl3945_hw_find_station - Find station id for a given BSSID
index 847a6220c5e6b03c74c8693bade699a97056ba9d..8f3d4bc6a03fcbfa65b8cd712c1704ecf1c8cb42 100644 (file)
@@ -163,10 +163,6 @@ static int iwl4965_load_bsm(struct iwl_priv *priv)
        inst_len = priv->ucode_init.len;
        data_len = priv->ucode_init_data.len;
 
-       ret = iwl_grab_nic_access(priv);
-       if (ret)
-               return ret;
-
        iwl_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst);
        iwl_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata);
        iwl_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG, inst_len);
@@ -179,10 +175,8 @@ static int iwl4965_load_bsm(struct iwl_priv *priv)
                _iwl_write_prph(priv, reg_offset, le32_to_cpu(*image));
 
        ret = iwl4965_verify_bsm(priv);
-       if (ret) {
-               iwl_release_nic_access(priv);
+       if (ret)
                return ret;
-       }
 
        /* Tell BSM to copy from BSM SRAM into instruction SRAM, when asked */
        iwl_write_prph(priv, BSM_WR_MEM_SRC_REG, 0x0);
@@ -211,7 +205,6 @@ static int iwl4965_load_bsm(struct iwl_priv *priv)
         *   (e.g. when powering back up after power-save shutdown) */
        iwl_write_prph(priv, BSM_WR_CTRL_REG, BSM_WR_CTRL_REG_BIT_START_EN);
 
-       iwl_release_nic_access(priv);
 
        return 0;
 }
@@ -229,20 +222,12 @@ static int iwl4965_set_ucode_ptrs(struct iwl_priv *priv)
 {
        dma_addr_t pinst;
        dma_addr_t pdata;
-       unsigned long flags;
        int ret = 0;
 
        /* bits 35:4 for 4965 */
        pinst = priv->ucode_code.p_addr >> 4;
        pdata = priv->ucode_data_backup.p_addr >> 4;
 
-       spin_lock_irqsave(&priv->lock, flags);
-       ret = iwl_grab_nic_access(priv);
-       if (ret) {
-               spin_unlock_irqrestore(&priv->lock, flags);
-               return ret;
-       }
-
        /* Tell bootstrap uCode where to find image to load */
        iwl_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst);
        iwl_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata);
@@ -253,10 +238,6 @@ static int iwl4965_set_ucode_ptrs(struct iwl_priv *priv)
         *   that all new ptr/size info is in place */
        iwl_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG,
                                 priv->ucode_code.len | BSM_DRAM_INST_LOAD);
-       iwl_release_nic_access(priv);
-
-       spin_unlock_irqrestore(&priv->lock, flags);
-
        IWL_DEBUG_INFO(priv, "Runtime uCode pointers are set.\n");
 
        return ret;
@@ -312,10 +293,12 @@ restart:
        queue_work(priv->workqueue, &priv->restart);
 }
 
-static int is_fat_channel(__le32 rxon_flags)
+static bool is_fat_channel(__le32 rxon_flags)
 {
-       return (rxon_flags & RXON_FLG_CHANNEL_MODE_PURE_40_MSK) ||
-               (rxon_flags & RXON_FLG_CHANNEL_MODE_MIXED_MSK);
+       int chan_mod = le32_to_cpu(rxon_flags & RXON_FLG_CHANNEL_MODE_MSK)
+                                   >> RXON_FLG_CHANNEL_MODE_POS;
+       return ((chan_mod == CHANNEL_MODE_PURE_40) ||
+                 (chan_mod == CHANNEL_MODE_MIXED));
 }
 
 /*
@@ -358,10 +341,6 @@ static int iwl4965_apm_init(struct iwl_priv *priv)
                goto out;
        }
 
-       ret = iwl_grab_nic_access(priv);
-       if (ret)
-               goto out;
-
        /* enable DMA */
        iwl_write_prph(priv, APMG_CLK_CTRL_REG, APMG_CLK_VAL_DMA_CLK_RQT |
                                                APMG_CLK_VAL_BSM_CLK_RQT);
@@ -372,7 +351,6 @@ static int iwl4965_apm_init(struct iwl_priv *priv)
        iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG,
                          APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
 
-       iwl_release_nic_access(priv);
 out:
        return ret;
 }
@@ -454,11 +432,9 @@ static void iwl4965_apm_stop(struct iwl_priv *priv)
 static int iwl4965_apm_reset(struct iwl_priv *priv)
 {
        int ret = 0;
-       unsigned long flags;
 
        iwl4965_apm_stop_master(priv);
 
-       spin_lock_irqsave(&priv->lock, flags);
 
        iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
 
@@ -475,9 +451,6 @@ static int iwl4965_apm_reset(struct iwl_priv *priv)
 
        udelay(10);
 
-       ret = iwl_grab_nic_access(priv);
-       if (ret)
-               goto out;
        /* Enable DMA and BSM Clock */
        iwl_write_prph(priv, APMG_CLK_EN_REG, APMG_CLK_VAL_DMA_CLK_RQT |
                                              APMG_CLK_VAL_BSM_CLK_RQT);
@@ -488,14 +461,10 @@ static int iwl4965_apm_reset(struct iwl_priv *priv)
        iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG,
                          APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
 
-       iwl_release_nic_access(priv);
-
        clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
        wake_up_interruptible(&priv->wait_command_queue);
 
 out:
-       spin_unlock_irqrestore(&priv->lock, flags);
-
        return ret;
 }
 
@@ -681,18 +650,11 @@ static int iwl4965_alive_notify(struct iwl_priv *priv)
 {
        u32 a;
        unsigned long flags;
-       int ret;
        int i, chan;
        u32 reg_val;
 
        spin_lock_irqsave(&priv->lock, flags);
 
-       ret = iwl_grab_nic_access(priv);
-       if (ret) {
-               spin_unlock_irqrestore(&priv->lock, flags);
-               return ret;
-       }
-
        /* Clear 4965's internal Tx Scheduler data base */
        priv->scd_base_addr = iwl_read_prph(priv, IWL49_SCD_SRAM_BASE_ADDR);
        a = priv->scd_base_addr + IWL49_SCD_CONTEXT_DATA_OFFSET;
@@ -759,10 +721,9 @@ static int iwl4965_alive_notify(struct iwl_priv *priv)
                iwl4965_tx_queue_set_status(priv, &priv->txq[i], ac, 0);
        }
 
-       iwl_release_nic_access(priv);
        spin_unlock_irqrestore(&priv->lock, flags);
 
-       return ret;
+       return 0;
 }
 
 static struct iwl_sensitivity_ranges iwl4965_sensitivity = {
@@ -788,6 +749,12 @@ static struct iwl_sensitivity_ranges iwl4965_sensitivity = {
        .nrg_th_ofdm = 100,
 };
 
+static void iwl4965_set_ct_threshold(struct iwl_priv *priv)
+{
+       /* want Kelvin */
+       priv->hw_params.ct_kill_threshold = CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD);
+}
+
 /**
  * iwl4965_hw_set_hw_params
  *
@@ -822,7 +789,8 @@ static int iwl4965_hw_set_hw_params(struct iwl_priv *priv)
        priv->hw_params.rx_chains_num = 2;
        priv->hw_params.valid_tx_ant = ANT_A | ANT_B;
        priv->hw_params.valid_rx_ant = ANT_A | ANT_B;
-       priv->hw_params.ct_kill_threshold = CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD);
+       if (priv->cfg->ops->lib->temp_ops.set_ct_kill)
+               priv->cfg->ops->lib->temp_ops.set_ct_kill(priv);
 
        priv->hw_params.sens = &iwl4965_sensitivity;
 
@@ -1524,7 +1492,7 @@ static int iwl4965_send_tx_power(struct iwl_priv *priv)
        struct iwl4965_txpowertable_cmd cmd = { 0 };
        int ret;
        u8 band = 0;
-       u8 is_fat = 0;
+       bool is_fat = false;
        u8 ctrl_chan_high = 0;
 
        if (test_bit(STATUS_SCANNING, &priv->status)) {
@@ -1602,7 +1570,7 @@ static int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel)
 {
        int rc;
        u8 band = 0;
-       u8 is_fat = 0;
+       bool is_fat = false;
        u8 ctrl_chan_high = 0;
        struct iwl4965_channel_switch_cmd cmd = { 0 };
        const struct iwl_channel_info *ch_info;
@@ -1833,8 +1801,6 @@ static void iwl4965_tx_queue_stop_scheduler(struct iwl_priv *priv,
 static int iwl4965_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
                                   u16 ssn_idx, u8 tx_fifo)
 {
-       int ret = 0;
-
        if ((IWL49_FIRST_AMPDU_QUEUE > txq_id) ||
            (IWL49_FIRST_AMPDU_QUEUE + IWL49_NUM_AMPDU_QUEUES <= txq_id)) {
                IWL_WARN(priv,
@@ -1844,10 +1810,6 @@ static int iwl4965_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
                return -EINVAL;
        }
 
-       ret = iwl_grab_nic_access(priv);
-       if (ret)
-               return ret;
-
        iwl4965_tx_queue_stop_scheduler(priv, txq_id);
 
        iwl_clear_bits_prph(priv, IWL49_SCD_QUEUECHAIN_SEL, (1 << txq_id));
@@ -1861,8 +1823,6 @@ static int iwl4965_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
        iwl_txq_ctx_deactivate(priv, txq_id);
        iwl4965_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 0);
 
-       iwl_release_nic_access(priv);
-
        return 0;
 }
 
@@ -1904,7 +1864,6 @@ static int iwl4965_txq_agg_enable(struct iwl_priv *priv, int txq_id,
                                  int tx_fifo, int sta_id, int tid, u16 ssn_idx)
 {
        unsigned long flags;
-       int ret;
        u16 ra_tid;
 
        if ((IWL49_FIRST_AMPDU_QUEUE > txq_id) ||
@@ -1922,11 +1881,6 @@ static int iwl4965_txq_agg_enable(struct iwl_priv *priv, int txq_id,
        iwl_sta_tx_modify_enable_tid(priv, sta_id, tid);
 
        spin_lock_irqsave(&priv->lock, flags);
-       ret = iwl_grab_nic_access(priv);
-       if (ret) {
-               spin_unlock_irqrestore(&priv->lock, flags);
-               return ret;
-       }
 
        /* Stop this Tx queue before configuring it */
        iwl4965_tx_queue_stop_scheduler(priv, txq_id);
@@ -1959,7 +1913,6 @@ static int iwl4965_txq_agg_enable(struct iwl_priv *priv, int txq_id,
        /* Set up Status area in SRAM, map to Tx DMA/FIFO, activate the queue */
        iwl4965_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 1);
 
-       iwl_release_nic_access(priv);
        spin_unlock_irqrestore(&priv->lock, flags);
 
        return 0;
@@ -2268,9 +2221,10 @@ static void iwl4965_cancel_deferred_work(struct iwl_priv *priv)
        cancel_work_sync(&priv->txpower_work);
 }
 
-
 static struct iwl_hcmd_ops iwl4965_hcmd = {
        .rxon_assoc = iwl4965_send_rxon_assoc,
+       .commit_rxon = iwl_commit_rxon,
+       .set_rxon_chain = iwl_set_rxon_chain,
 };
 
 static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = {
@@ -2323,7 +2277,13 @@ static struct iwl_lib_ops iwl4965_lib = {
        },
        .send_tx_power  = iwl4965_send_tx_power,
        .update_chain_flags = iwl_update_chain_flags,
-       .temperature = iwl4965_temperature_calib,
+       .post_associate = iwl_post_associate,
+       .config_ap = iwl_config_ap,
+       .isr = iwl_isr_legacy,
+       .temp_ops = {
+               .temperature = iwl4965_temperature_calib,
+               .set_ct_kill = iwl4965_set_ct_threshold,
+       },
 };
 
 static struct iwl_ops iwl4965_ops = {
@@ -2343,6 +2303,7 @@ struct iwl_cfg iwl4965_agn_cfg = {
        .eeprom_calib_ver = EEPROM_4965_TX_POWER_VERSION,
        .ops = &iwl4965_ops,
        .mod_params = &iwl4965_mod_params,
+       .use_isr_legacy = true
 };
 
 /* Module firmware */
@@ -2350,8 +2311,6 @@ MODULE_FIRMWARE(IWL4965_MODULE_FIRMWARE(IWL4965_UCODE_API_MAX));
 
 module_param_named(antenna, iwl4965_mod_params.antenna, int, 0444);
 MODULE_PARM_DESC(antenna, "select antenna (1=Main, 2=Aux, default 0 [both])");
-module_param_named(disable, iwl4965_mod_params.disable, int, 0444);
-MODULE_PARM_DESC(disable, "manually disable the radio (default 0 [radio on])");
 module_param_named(swcrypto, iwl4965_mod_params.sw_crypto, int, 0444);
 MODULE_PARM_DESC(swcrypto, "using crypto in software (default 0 [hardware])");
 module_param_named(debug, iwl4965_mod_params.debug, uint, 0444);
index 15cac70e36e2d202d17419e36bc86414f8ace6e0..4ef6804a455af2e31259db3a048fe4360f20dfe1 100644 (file)
 #define IWL50_NUM_AMPDU_QUEUES           10
 #define IWL50_FIRST_AMPDU_QUEUE                  10
 
+/* 5150 only */
+#define IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF  (-5)
+
+static inline s32 iwl_temp_calib_to_offset(struct iwl_priv *priv)
+{
+       u16 *temp_calib = (u16 *)iwl_eeprom_query_addr(priv,
+                                                      EEPROM_5000_TEMPERATURE);
+       /* offset =  temperature -  voltage / coef */
+       s32 offset = (s32)(temp_calib[0] - temp_calib[1] / IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF);
+       return offset;
+}
+
 /* Fixed (non-configurable) rx data from phy */
 
 /**
index 9452461ce8645be87d9c3779e6388bb910d8ea63..b3c648ce8c7b0eb98ed84ddbcf45351de3c5f403 100644 (file)
@@ -124,10 +124,6 @@ static int iwl5000_apm_init(struct iwl_priv *priv)
                return ret;
        }
 
-       ret = iwl_grab_nic_access(priv);
-       if (ret)
-               return ret;
-
        /* enable DMA */
        iwl_write_prph(priv, APMG_CLK_EN_REG, APMG_CLK_VAL_DMA_CLK_RQT);
 
@@ -137,8 +133,6 @@ static int iwl5000_apm_init(struct iwl_priv *priv)
        iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG,
                          APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
 
-       iwl_release_nic_access(priv);
-
        return ret;
 }
 
@@ -165,12 +159,9 @@ static void iwl5000_apm_stop(struct iwl_priv *priv)
 static int iwl5000_apm_reset(struct iwl_priv *priv)
 {
        int ret = 0;
-       unsigned long flags;
 
        iwl5000_apm_stop_master(priv);
 
-       spin_lock_irqsave(&priv->lock, flags);
-
        iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
 
        udelay(10);
@@ -193,10 +184,6 @@ static int iwl5000_apm_reset(struct iwl_priv *priv)
                goto out;
        }
 
-       ret = iwl_grab_nic_access(priv);
-       if (ret)
-               goto out;
-
        /* enable DMA */
        iwl_write_prph(priv, APMG_CLK_EN_REG, APMG_CLK_VAL_DMA_CLK_RQT);
 
@@ -205,11 +192,7 @@ static int iwl5000_apm_reset(struct iwl_priv *priv)
        /* disable L1-Active */
        iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG,
                          APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
-
-       iwl_release_nic_access(priv);
-
 out:
-       spin_unlock_irqrestore(&priv->lock, flags);
 
        return ret;
 }
@@ -252,11 +235,9 @@ static void iwl5000_nic_config(struct iwl_priv *priv)
         * (PCIe power is lost before PERST# is asserted),
         * causing ME FW to lose ownership and not being able to obtain it back.
         */
-       iwl_grab_nic_access(priv);
        iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
                                APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS,
                                ~APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS);
-       iwl_release_nic_access(priv);
 
        spin_unlock_irqrestore(&priv->lock, flags);
 }
@@ -434,15 +415,19 @@ static const u8 *iwl5000_eeprom_query_addr(const struct iwl_priv *priv,
        return &priv->eeprom[address];
 }
 
-static s32 iwl5150_get_ct_threshold(struct iwl_priv *priv)
+static void iwl5150_set_ct_threshold(struct iwl_priv *priv)
 {
-       const s32 volt2temp_coef = -5;
-       u16 *temp_calib = (u16 *)iwl_eeprom_query_addr(priv,
-                                               EEPROM_5000_TEMPERATURE);
-       /* offset =  temperate -  voltage / coef */
-       s32 offset = temp_calib[0] - temp_calib[1] / volt2temp_coef;
-       s32 threshold = (s32)CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD) - offset;
-       return threshold * volt2temp_coef;
+       const s32 volt2temp_coef = IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF;
+       s32 threshold = (s32)CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD) -
+                       iwl_temp_calib_to_offset(priv);
+
+       priv->hw_params.ct_kill_threshold = threshold * volt2temp_coef;
+}
+
+static void iwl5000_set_ct_threshold(struct iwl_priv *priv)
+{
+       /* want Celsius */
+       priv->hw_params.ct_kill_threshold = CT_KILL_THRESHOLD;
 }
 
 /*
@@ -533,19 +518,9 @@ static int iwl5000_load_section(struct iwl_priv *priv,
                                struct fw_desc *image,
                                u32 dst_addr)
 {
-       int ret = 0;
-       unsigned long flags;
-
        dma_addr_t phy_addr = image->p_addr;
        u32 byte_cnt = image->len;
 
-       spin_lock_irqsave(&priv->lock, flags);
-       ret = iwl_grab_nic_access(priv);
-       if (ret) {
-               spin_unlock_irqrestore(&priv->lock, flags);
-               return ret;
-       }
-
        iwl_write_direct32(priv,
                FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL),
                FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE);
@@ -574,8 +549,6 @@ static int iwl5000_load_section(struct iwl_priv *priv,
                FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE    |
                FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD);
 
-       iwl_release_nic_access(priv);
-       spin_unlock_irqrestore(&priv->lock, flags);
        return 0;
 }
 
@@ -736,18 +709,11 @@ static int iwl5000_alive_notify(struct iwl_priv *priv)
 {
        u32 a;
        unsigned long flags;
-       int ret;
        int i, chan;
        u32 reg_val;
 
        spin_lock_irqsave(&priv->lock, flags);
 
-       ret = iwl_grab_nic_access(priv);
-       if (ret) {
-               spin_unlock_irqrestore(&priv->lock, flags);
-               return ret;
-       }
-
        priv->scd_base_addr = iwl_read_prph(priv, IWL50_SCD_SRAM_BASE_ADDR);
        a = priv->scd_base_addr + IWL50_SCD_CONTEXT_DATA_OFFSET;
        for (; a < priv->scd_base_addr + IWL50_SCD_TX_STTS_BITMAP_OFFSET;
@@ -815,7 +781,6 @@ static int iwl5000_alive_notify(struct iwl_priv *priv)
        iwl_txq_ctx_activate(priv, 8);
        iwl_txq_ctx_activate(priv, 9);
 
-       iwl_release_nic_access(priv);
        spin_unlock_irqrestore(&priv->lock, flags);
 
 
@@ -868,17 +833,8 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
        priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant;
        priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant;
 
-       switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) {
-       case CSR_HW_REV_TYPE_5150:
-               /* 5150 wants in Kelvin */
-               priv->hw_params.ct_kill_threshold =
-                               iwl5150_get_ct_threshold(priv);
-               break;
-       default:
-               /* all others want Celsius */
-               priv->hw_params.ct_kill_threshold = CT_KILL_THRESHOLD;
-               break;
-       }
+       if (priv->cfg->ops->lib->temp_ops.set_ct_kill)
+               priv->cfg->ops->lib->temp_ops.set_ct_kill(priv);
 
        /* Set initial calibration set */
        switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) {
@@ -900,7 +856,6 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
                break;
        }
 
-
        return 0;
 }
 
@@ -1006,7 +961,6 @@ static int iwl5000_txq_agg_enable(struct iwl_priv *priv, int txq_id,
                                  int tx_fifo, int sta_id, int tid, u16 ssn_idx)
 {
        unsigned long flags;
-       int ret;
        u16 ra_tid;
 
        if ((IWL50_FIRST_AMPDU_QUEUE > txq_id) ||
@@ -1024,11 +978,6 @@ static int iwl5000_txq_agg_enable(struct iwl_priv *priv, int txq_id,
        iwl_sta_tx_modify_enable_tid(priv, sta_id, tid);
 
        spin_lock_irqsave(&priv->lock, flags);
-       ret = iwl_grab_nic_access(priv);
-       if (ret) {
-               spin_unlock_irqrestore(&priv->lock, flags);
-               return ret;
-       }
 
        /* Stop this Tx queue before configuring it */
        iwl5000_tx_queue_stop_scheduler(priv, txq_id);
@@ -1064,7 +1013,6 @@ static int iwl5000_txq_agg_enable(struct iwl_priv *priv, int txq_id,
        /* Set up Status area in SRAM, map to Tx DMA/FIFO, activate the queue */
        iwl5000_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 1);
 
-       iwl_release_nic_access(priv);
        spin_unlock_irqrestore(&priv->lock, flags);
 
        return 0;
@@ -1073,8 +1021,6 @@ static int iwl5000_txq_agg_enable(struct iwl_priv *priv, int txq_id,
 static int iwl5000_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
                                   u16 ssn_idx, u8 tx_fifo)
 {
-       int ret;
-
        if ((IWL50_FIRST_AMPDU_QUEUE > txq_id) ||
            (IWL50_FIRST_AMPDU_QUEUE + IWL50_NUM_AMPDU_QUEUES <= txq_id)) {
                IWL_ERR(priv,
@@ -1084,10 +1030,6 @@ static int iwl5000_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
                return -EINVAL;
        }
 
-       ret = iwl_grab_nic_access(priv);
-       if (ret)
-               return ret;
-
        iwl5000_tx_queue_stop_scheduler(priv, txq_id);
 
        iwl_clear_bits_prph(priv, IWL50_SCD_AGGR_SEL, (1 << txq_id));
@@ -1101,15 +1043,16 @@ static int iwl5000_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
        iwl_txq_ctx_deactivate(priv, txq_id);
        iwl5000_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 0);
 
-       iwl_release_nic_access(priv);
-
        return 0;
 }
 
 u16 iwl5000_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data)
 {
        u16 size = (u16)sizeof(struct iwl_addsta_cmd);
-       memcpy(data, cmd, size);
+       struct iwl_addsta_cmd *addsta = (struct iwl_addsta_cmd *)data;
+       memcpy(addsta, cmd, size);
+       /* resrved in 5000 */
+       addsta->rate_n_flags = cpu_to_le16(0);
        return size;
 }
 
@@ -1434,6 +1377,17 @@ static void iwl5000_temperature(struct iwl_priv *priv)
        priv->temperature = le32_to_cpu(priv->statistics.general.temperature);
 }
 
+static void iwl5150_temperature(struct iwl_priv *priv)
+{
+       u32 vt = 0;
+       s32 offset =  iwl_temp_calib_to_offset(priv);
+
+       vt = le32_to_cpu(priv->statistics.general.temperature);
+       vt = vt / IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF + offset;
+       /* now vt hold the temperature in Kelvin */
+       priv->temperature = KELVIN_TO_CELSIUS(vt);
+}
+
 /* Calc max signal level (dBm) among 3 possible receivers */
 int iwl5000_calc_rssi(struct iwl_priv *priv,
                             struct iwl_rx_phy_res *rx_resp)
@@ -1474,6 +1428,8 @@ int iwl5000_calc_rssi(struct iwl_priv *priv,
 
 struct iwl_hcmd_ops iwl5000_hcmd = {
        .rxon_assoc = iwl5000_send_rxon_assoc,
+       .commit_rxon = iwl_commit_rxon,
+       .set_rxon_chain = iwl_set_rxon_chain,
 };
 
 struct iwl_hcmd_utils_ops iwl5000_hcmd_utils = {
@@ -1502,7 +1458,6 @@ struct iwl_lib_ops iwl5000_lib = {
        .init_alive_start = iwl5000_init_alive_start,
        .alive_notify = iwl5000_alive_notify,
        .send_tx_power = iwl5000_send_tx_power,
-       .temperature = iwl5000_temperature,
        .update_chain_flags = iwl_update_chain_flags,
        .apm_ops = {
                .init = iwl5000_apm_init,
@@ -1527,6 +1482,63 @@ struct iwl_lib_ops iwl5000_lib = {
                .calib_version  = iwl5000_eeprom_calib_version,
                .query_addr = iwl5000_eeprom_query_addr,
        },
+       .post_associate = iwl_post_associate,
+       .isr = iwl_isr_ict,
+       .config_ap = iwl_config_ap,
+       .temp_ops = {
+               .temperature = iwl5000_temperature,
+               .set_ct_kill = iwl5000_set_ct_threshold,
+        },
+};
+
+static struct iwl_lib_ops iwl5150_lib = {
+       .set_hw_params = iwl5000_hw_set_hw_params,
+       .txq_update_byte_cnt_tbl = iwl5000_txq_update_byte_cnt_tbl,
+       .txq_inval_byte_cnt_tbl = iwl5000_txq_inval_byte_cnt_tbl,
+       .txq_set_sched = iwl5000_txq_set_sched,
+       .txq_agg_enable = iwl5000_txq_agg_enable,
+       .txq_agg_disable = iwl5000_txq_agg_disable,
+       .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd,
+       .txq_free_tfd = iwl_hw_txq_free_tfd,
+       .txq_init = iwl_hw_tx_queue_init,
+       .rx_handler_setup = iwl5000_rx_handler_setup,
+       .setup_deferred_work = iwl5000_setup_deferred_work,
+       .is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr,
+       .load_ucode = iwl5000_load_ucode,
+       .init_alive_start = iwl5000_init_alive_start,
+       .alive_notify = iwl5000_alive_notify,
+       .send_tx_power = iwl5000_send_tx_power,
+       .update_chain_flags = iwl_update_chain_flags,
+       .apm_ops = {
+               .init = iwl5000_apm_init,
+               .reset = iwl5000_apm_reset,
+               .stop = iwl5000_apm_stop,
+               .config = iwl5000_nic_config,
+               .set_pwr_src = iwl_set_pwr_src,
+       },
+       .eeprom_ops = {
+               .regulatory_bands = {
+                       EEPROM_5000_REG_BAND_1_CHANNELS,
+                       EEPROM_5000_REG_BAND_2_CHANNELS,
+                       EEPROM_5000_REG_BAND_3_CHANNELS,
+                       EEPROM_5000_REG_BAND_4_CHANNELS,
+                       EEPROM_5000_REG_BAND_5_CHANNELS,
+                       EEPROM_5000_REG_BAND_24_FAT_CHANNELS,
+                       EEPROM_5000_REG_BAND_52_FAT_CHANNELS
+               },
+               .verify_signature  = iwlcore_eeprom_verify_signature,
+               .acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
+               .release_semaphore = iwlcore_eeprom_release_semaphore,
+               .calib_version  = iwl5000_eeprom_calib_version,
+               .query_addr = iwl5000_eeprom_query_addr,
+       },
+       .post_associate = iwl_post_associate,
+       .isr = iwl_isr_ict,
+       .config_ap = iwl_config_ap,
+       .temp_ops = {
+               .temperature = iwl5150_temperature,
+               .set_ct_kill = iwl5150_set_ct_threshold,
+        },
 };
 
 struct iwl_ops iwl5000_ops = {
@@ -1535,6 +1547,12 @@ struct iwl_ops iwl5000_ops = {
        .utils = &iwl5000_hcmd_utils,
 };
 
+static struct iwl_ops iwl5150_ops = {
+       .lib = &iwl5150_lib,
+       .hcmd = &iwl5000_hcmd,
+       .utils = &iwl5000_hcmd_utils,
+};
+
 struct iwl_mod_params iwl50_mod_params = {
        .num_of_queues = IWL50_NUM_QUEUES,
        .num_of_ampdu_queues = IWL50_NUM_AMPDU_QUEUES,
@@ -1630,7 +1648,7 @@ struct iwl_cfg iwl5150_agn_cfg = {
        .ucode_api_max = IWL5150_UCODE_API_MAX,
        .ucode_api_min = IWL5150_UCODE_API_MIN,
        .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
-       .ops = &iwl5000_ops,
+       .ops = &iwl5150_ops,
        .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
        .eeprom_ver = EEPROM_5050_EEPROM_VERSION,
        .eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,
@@ -1643,9 +1661,6 @@ struct iwl_cfg iwl5150_agn_cfg = {
 MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX));
 MODULE_FIRMWARE(IWL5150_MODULE_FIRMWARE(IWL5150_UCODE_API_MAX));
 
-module_param_named(disable50, iwl50_mod_params.disable, int, 0444);
-MODULE_PARM_DESC(disable50,
-                 "manually disable the 50XX radio (default 0 [radio on])");
 module_param_named(swcrypto50, iwl50_mod_params.sw_crypto, bool, 0444);
 MODULE_PARM_DESC(swcrypto50,
                  "using software crypto engine (default 0 [hardware])\n");
index cab7842a73aaed9cb44bdb536277389ea42e6e1f..ff20e5048a556311fd7550b1e244486e1807cb6f 100644 (file)
@@ -52,7 +52,7 @@
 /* max allowed rate miss before sync LQ cmd */
 #define IWL_MISSED_RATE_MAX            15
 /* max time to accum history 2 seconds */
-#define IWL_RATE_SCALE_FLUSH_INTVL   (2*HZ)
+#define IWL_RATE_SCALE_FLUSH_INTVL   (3*HZ)
 
 static u8 rs_ht_to_legacy[] = {
        IWL_RATE_6M_INDEX, IWL_RATE_6M_INDEX,
@@ -100,6 +100,7 @@ struct iwl_scale_tbl_info {
        u8 is_fat;      /* 1 = 40 MHz channel width */
        u8 is_dup;      /* 1 = duplicated data streams */
        u8 action;      /* change modulation; IWL_[LEGACY/SISO/MIMO]_SWITCH_* */
+       u8 max_search;  /* maximun number of tables we can search */
        s32 *expected_tpt;      /* throughput metrics; expected_tpt_G, etc. */
        u32 current_rate;  /* rate_n_flags, uCode API format */
        struct iwl_rate_scale_data win[IWL_RATE_COUNT]; /* rate histories */
@@ -135,7 +136,7 @@ struct iwl_lq_sta {
        u32 table_count;
        u32 total_failed;       /* total failed frames, any/all rates */
        u32 total_success;      /* total successful frames, any/all rates */
-       u32 flush_timer;        /* time staying in mode before new search */
+       u64 flush_timer;        /* time staying in mode before new search */
 
        u8 action_counter;      /* # mode-switch actions tried */
        u8 is_green;
@@ -160,6 +161,7 @@ struct iwl_lq_sta {
 #ifdef CONFIG_MAC80211_DEBUGFS
        struct dentry *rs_sta_dbgfs_scale_table_file;
        struct dentry *rs_sta_dbgfs_stats_table_file;
+       struct dentry *rs_sta_dbgfs_rate_scale_data_file;
        struct dentry *rs_sta_dbgfs_tx_agg_tid_en_file;
        u32 dbg_fixed_rate;
 #endif
@@ -167,10 +169,12 @@ struct iwl_lq_sta {
 
        /* used to be in sta_info */
        int last_txrate_idx;
+       /* last tx rate_n_flags */
+       u32 last_rate_n_flags;
 };
 
 static void rs_rate_scale_perform(struct iwl_priv *priv,
-                                  struct ieee80211_hdr *hdr,
+                                  struct sk_buff *skb,
                                   struct ieee80211_sta *sta,
                                   struct iwl_lq_sta *lq_sta);
 static void rs_fill_link_cmd(const struct iwl_priv *priv,
@@ -191,7 +195,7 @@ static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta,
  * 1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54, 60 MBits
  * "G" is the only table that supports CCK (the first 4 rates).
  */
-/*FIXME:RS:need to separate tables for MIMO2/MIMO3*/
+
 static s32 expected_tpt_A[IWL_RATE_COUNT] = {
        0, 0, 0, 0, 40, 57, 72, 98, 121, 154, 177, 186, 186
 };
@@ -208,11 +212,11 @@ static s32 expected_tpt_siso20MHzSGI[IWL_RATE_COUNT] = {
        0, 0, 0, 0, 46, 46, 82, 110, 132, 168, 192, 202, 211
 };
 
-static s32 expected_tpt_mimo20MHz[IWL_RATE_COUNT] = {
+static s32 expected_tpt_mimo2_20MHz[IWL_RATE_COUNT] = {
        0, 0, 0, 0, 74, 74, 123, 155, 179, 214, 236, 244, 251
 };
 
-static s32 expected_tpt_mimo20MHzSGI[IWL_RATE_COUNT] = {
+static s32 expected_tpt_mimo2_20MHzSGI[IWL_RATE_COUNT] = {
        0, 0, 0, 0, 81, 81, 131, 164, 188, 222, 243, 251, 257
 };
 
@@ -224,14 +228,50 @@ static s32 expected_tpt_siso40MHzSGI[IWL_RATE_COUNT] = {
        0, 0, 0, 0, 83, 83, 135, 169, 193, 229, 250, 257, 264
 };
 
-static s32 expected_tpt_mimo40MHz[IWL_RATE_COUNT] = {
+static s32 expected_tpt_mimo2_40MHz[IWL_RATE_COUNT] = {
        0, 0, 0, 0, 123, 123, 182, 214, 235, 264, 279, 285, 289
 };
 
-static s32 expected_tpt_mimo40MHzSGI[IWL_RATE_COUNT] = {
+static s32 expected_tpt_mimo2_40MHzSGI[IWL_RATE_COUNT] = {
        0, 0, 0, 0, 131, 131, 191, 222, 242, 270, 284, 289, 293
 };
 
+/* Expected throughput metric MIMO3 */
+static s32 expected_tpt_mimo3_20MHz[IWL_RATE_COUNT] = {
+       0, 0, 0, 0, 99, 99, 153, 186, 208, 239, 256, 263, 268
+};
+
+static s32 expected_tpt_mimo3_20MHzSGI[IWL_RATE_COUNT] = {
+       0, 0, 0, 0, 106, 106, 162, 194, 215, 246, 262, 268, 273
+};
+
+static s32 expected_tpt_mimo3_40MHz[IWL_RATE_COUNT] = {
+       0, 0, 0, 0, 152, 152, 211, 239, 255, 279, 290, 294, 297
+};
+
+static s32 expected_tpt_mimo3_40MHzSGI[IWL_RATE_COUNT] = {
+       0, 0, 0, 0, 160, 160, 219, 245, 261, 284, 294, 297, 300
+};
+
+/* mbps, mcs */
+const static struct iwl_rate_mcs_info iwl_rate_mcs[IWL_RATE_COUNT] = {
+  {"1", ""},
+  {"2", ""},
+  {"5.5", ""},
+  {"11", ""},
+  {"6", "BPSK 1/2"},
+  {"9", "BPSK 1/2"},
+  {"12", "QPSK 1/2"},
+  {"18", "QPSK 3/4"},
+  {"24", "16QAM 1/2"},
+  {"36", "16QAM 3/4"},
+  {"48", "64QAM 2/3"},
+  {"54", "64QAM 3/4"},
+  {"60", "64QAM 5/6"}
+};
+
+#define MCS_INDEX_PER_STREAM   (8)
+
 static inline u8 rs_extract_rate(u32 rate_n_flags)
 {
        return (u8)(rate_n_flags & 0xFF);
@@ -543,6 +583,7 @@ static int rs_get_tbl_info_from_mcs(const u32 rate_n_flags,
        tbl->is_dup = 0;
        tbl->ant_type = (ant_msk >> RATE_MCS_ANT_POS);
        tbl->lq_type = LQ_NONE;
+       tbl->max_search = IWL_MAX_SEARCH;
 
        /* legacy rate format */
        if (!(rate_n_flags & RATE_MCS_HT_MSK)) {
@@ -576,8 +617,10 @@ static int rs_get_tbl_info_from_mcs(const u32 rate_n_flags,
                                tbl->lq_type = LQ_MIMO2;
                /* MIMO3 */
                } else {
-                       if (num_of_ant == 3)
+                       if (num_of_ant == 3) {
+                               tbl->max_search = IWL_MAX_11N_MIMO3_SEARCH;
                                tbl->lq_type = LQ_MIMO3;
+                       }
                }
        }
        return 0;
@@ -611,19 +654,19 @@ static int rs_toggle_antenna(u32 valid_ant, u32 *rate_n_flags,
        return 1;
 }
 
-/* FIXME:RS: in 4965 we don't use greenfield at all */
-/* FIXME:RS: don't use greenfield for now in TX */
-#if 0
-static inline u8 rs_use_green(struct iwl_priv *priv, struct ieee80211_conf *conf)
+/* in 4965 we don't use greenfield at all */
+static inline u8 rs_use_green(struct iwl_priv *priv,
+                             struct ieee80211_conf *conf)
 {
-       return (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) &&
-               priv->current_ht_config.is_green_field &&
-               !priv->current_ht_config.non_GF_STA_present;
-}
-#endif
-static inline u8 rs_use_green(struct iwl_priv *priv, struct ieee80211_conf *conf)
-{
-       return 0;
+       u8 is_green;
+
+       if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965)
+               is_green = 0;
+       else
+               is_green = (conf_is_ht(conf) &&
+                          priv->current_ht_config.is_green_field &&
+                          !priv->current_ht_config.non_GF_STA_present);
+       return is_green;
 }
 
 /**
@@ -735,6 +778,7 @@ static u32 rs_get_lower_rate(struct iwl_lq_sta *lq_sta,
 
                tbl->is_fat = 0;
                tbl->is_SGI = 0;
+               tbl->max_search = IWL_MAX_SEARCH;
        }
 
        rate_mask = rs_get_supported_rates(lq_sta, NULL, tbl->lq_type);
@@ -793,7 +837,7 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
        IWL_DEBUG_RATE_LIMIT(priv, "get frame ack response, update rate scale window\n");
 
        if (!ieee80211_is_data(hdr->frame_control) ||
-           is_multicast_ether_addr(hdr->addr1))
+           info->flags & IEEE80211_TX_CTL_NO_ACK)
                return;
 
        /* This packet was aggregated but doesn't carry rate scale info */
@@ -902,6 +946,7 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
         * else look up the rate that was, finally, successful.
         */
        tx_rate = le32_to_cpu(table->rs_table[index].rate_n_flags);
+       lq_sta->last_rate_n_flags = tx_rate;
        rs_get_tbl_info_from_mcs(tx_rate, priv->band, &tbl_type, &rs_index);
 
        /* Update frame history window with "success" if Tx got ACKed ... */
@@ -958,7 +1003,7 @@ static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband,
 
        /* See if there's a better rate or modulation mode to try. */
        if (sta && sta->supp_rates[sband->band])
-               rs_rate_scale_perform(priv, hdr, sta, lq_sta);
+               rs_rate_scale_perform(priv, skb, sta, lq_sta);
 out:
        return;
 }
@@ -988,6 +1033,8 @@ static void rs_set_stay_in_table(struct iwl_priv *priv, u8 is_legacy,
        lq_sta->table_count = 0;
        lq_sta->total_failed = 0;
        lq_sta->total_success = 0;
+       lq_sta->flush_timer = jiffies;
+       lq_sta->action_counter = 0;
 }
 
 /*
@@ -1011,17 +1058,26 @@ static void rs_set_expected_tpt_table(struct iwl_lq_sta *lq_sta,
                        tbl->expected_tpt = expected_tpt_siso20MHzSGI;
                else
                        tbl->expected_tpt = expected_tpt_siso20MHz;
-
-       } else if (is_mimo(tbl->lq_type)) { /* FIXME:need to separate mimo2/3 */
+       } else if (is_mimo2(tbl->lq_type)) {
                if (tbl->is_fat && !lq_sta->is_dup)
                        if (tbl->is_SGI)
-                               tbl->expected_tpt = expected_tpt_mimo40MHzSGI;
+                               tbl->expected_tpt = expected_tpt_mimo2_40MHzSGI;
                        else
-                               tbl->expected_tpt = expected_tpt_mimo40MHz;
+                               tbl->expected_tpt = expected_tpt_mimo2_40MHz;
                else if (tbl->is_SGI)
-                       tbl->expected_tpt = expected_tpt_mimo20MHzSGI;
+                       tbl->expected_tpt = expected_tpt_mimo2_20MHzSGI;
                else
-                       tbl->expected_tpt = expected_tpt_mimo20MHz;
+                       tbl->expected_tpt = expected_tpt_mimo2_20MHz;
+       } else if (is_mimo3(tbl->lq_type)) {
+               if (tbl->is_fat && !lq_sta->is_dup)
+                       if (tbl->is_SGI)
+                               tbl->expected_tpt = expected_tpt_mimo3_40MHzSGI;
+                       else
+                               tbl->expected_tpt = expected_tpt_mimo3_40MHz;
+               else if (tbl->is_SGI)
+                       tbl->expected_tpt = expected_tpt_mimo3_20MHzSGI;
+               else
+                       tbl->expected_tpt = expected_tpt_mimo3_20MHz;
        } else
                tbl->expected_tpt = expected_tpt_G;
 }
@@ -1130,7 +1186,7 @@ static s32 rs_get_best_rate(struct iwl_priv *priv,
 }
 
 /*
- * Set up search table for MIMO
+ * Set up search table for MIMO2
  */
 static int rs_switch_to_mimo2(struct iwl_priv *priv,
                             struct iwl_lq_sta *lq_sta,
@@ -1158,10 +1214,10 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv,
        tbl->lq_type = LQ_MIMO2;
        tbl->is_dup = lq_sta->is_dup;
        tbl->action = 0;
+       tbl->max_search = IWL_MAX_SEARCH;
        rate_mask = lq_sta->active_mimo2_rate;
 
-       if (priv->current_ht_config.supported_chan_width
-                                       == IWL_CHANNEL_WIDTH_40MHZ)
+       if (iwl_is_fat_tx_allowed(priv, &sta->ht_cap))
                tbl->is_fat = 1;
        else
                tbl->is_fat = 0;
@@ -1183,7 +1239,73 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv,
        rate = rs_get_best_rate(priv, lq_sta, tbl, rate_mask, index);
 
        IWL_DEBUG_RATE(priv, "LQ: MIMO2 best rate %d mask %X\n", rate, rate_mask);
+       if ((rate == IWL_RATE_INVALID) || !((1 << rate) & rate_mask)) {
+               IWL_DEBUG_RATE(priv, "Can't switch with index %d rate mask %x\n",
+                                               rate, rate_mask);
+               return -1;
+       }
+       tbl->current_rate = rate_n_flags_from_tbl(priv, tbl, rate, is_green);
+
+       IWL_DEBUG_RATE(priv, "LQ: Switch to new mcs %X index is green %X\n",
+                    tbl->current_rate, is_green);
+       return 0;
+}
+
+/*
+ * Set up search table for MIMO3
+ */
+static int rs_switch_to_mimo3(struct iwl_priv *priv,
+                            struct iwl_lq_sta *lq_sta,
+                            struct ieee80211_conf *conf,
+                            struct ieee80211_sta *sta,
+                            struct iwl_scale_tbl_info *tbl, int index)
+{
+       u16 rate_mask;
+       s32 rate;
+       s8 is_green = lq_sta->is_green;
+
+       if (!conf_is_ht(conf) || !sta->ht_cap.ht_supported)
+               return -1;
+
+       if (((sta->ht_cap.cap & IEEE80211_HT_CAP_SM_PS) >> 2)
+                                               == WLAN_HT_CAP_SM_PS_STATIC)
+               return -1;
+
+       /* Need both Tx chains/antennas to support MIMO */
+       if (priv->hw_params.tx_chains_num < 3)
+               return -1;
+
+       IWL_DEBUG_RATE(priv, "LQ: try to switch to MIMO3\n");
+
+       tbl->lq_type = LQ_MIMO3;
+       tbl->is_dup = lq_sta->is_dup;
+       tbl->action = 0;
+       tbl->max_search = IWL_MAX_11N_MIMO3_SEARCH;
+       rate_mask = lq_sta->active_mimo3_rate;
+
+       if (iwl_is_fat_tx_allowed(priv, &sta->ht_cap))
+               tbl->is_fat = 1;
+       else
+               tbl->is_fat = 0;
 
+       /* FIXME: - don't toggle SGI here
+       if (tbl->is_fat) {
+               if (priv->current_ht_config.sgf & HT_SHORT_GI_40MHZ_ONLY)
+                       tbl->is_SGI = 1;
+               else
+                       tbl->is_SGI = 0;
+       } else if (priv->current_ht_config.sgf & HT_SHORT_GI_20MHZ_ONLY)
+               tbl->is_SGI = 1;
+       else
+               tbl->is_SGI = 0;
+       */
+
+       rs_set_expected_tpt_table(lq_sta, tbl);
+
+       rate = rs_get_best_rate(priv, lq_sta, tbl, rate_mask, index);
+
+       IWL_DEBUG_RATE(priv, "LQ: MIMO3 best rate %d mask %X\n",
+               rate, rate_mask);
        if ((rate == IWL_RATE_INVALID) || !((1 << rate) & rate_mask)) {
                IWL_DEBUG_RATE(priv, "Can't switch with index %d rate mask %x\n",
                                                rate, rate_mask);
@@ -1217,10 +1339,10 @@ static int rs_switch_to_siso(struct iwl_priv *priv,
        tbl->is_dup = lq_sta->is_dup;
        tbl->lq_type = LQ_SISO;
        tbl->action = 0;
+       tbl->max_search = IWL_MAX_SEARCH;
        rate_mask = lq_sta->active_siso_rate;
 
-       if (priv->current_ht_config.supported_chan_width
-           == IWL_CHANNEL_WIDTH_40MHZ)
+       if (iwl_is_fat_tx_allowed(priv, &sta->ht_cap))
                tbl->is_fat = 1;
        else
                tbl->is_fat = 0;
@@ -1274,15 +1396,15 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
        u8 valid_tx_ant = priv->hw_params.valid_tx_ant;
        u8 tx_chains_num = priv->hw_params.tx_chains_num;
        int ret = 0;
+       u8 update_search_tbl_counter = 0;
 
        for (; ;) {
+               lq_sta->action_counter++;
                switch (tbl->action) {
                case IWL_LEGACY_SWITCH_ANTENNA1:
                case IWL_LEGACY_SWITCH_ANTENNA2:
                        IWL_DEBUG_RATE(priv, "LQ: Legacy toggle Antenna\n");
 
-                       lq_sta->action_counter++;
-
                        if ((tbl->action == IWL_LEGACY_SWITCH_ANTENNA1 &&
                                                        tx_chains_num <= 1) ||
                            (tbl->action == IWL_LEGACY_SWITCH_ANTENNA2 &&
@@ -1298,6 +1420,7 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
 
                        if (rs_toggle_antenna(valid_tx_ant,
                                &search_tbl->current_rate, search_tbl)) {
+                               update_search_tbl_counter = 1;
                                rs_set_expected_tpt_table(lq_sta, search_tbl);
                                goto out;
                        }
@@ -1342,9 +1465,29 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
                                goto out;
                        }
                        break;
+
+               case IWL_LEGACY_SWITCH_MIMO3_ABC:
+                       IWL_DEBUG_RATE(priv, "LQ: Legacy switch to MIMO3\n");
+
+                       /* Set up search table to try MIMO3 */
+                       memcpy(search_tbl, tbl, sz);
+                       search_tbl->is_SGI = 0;
+
+                       search_tbl->ant_type = ANT_ABC;
+
+                       if (!rs_is_valid_ant(valid_tx_ant, search_tbl->ant_type))
+                               break;
+
+                       ret = rs_switch_to_mimo3(priv, lq_sta, conf, sta,
+                                                search_tbl, index);
+                       if (!ret) {
+                               lq_sta->action_counter = 0;
+                               goto out;
+                       }
+                       break;
                }
                tbl->action++;
-               if (tbl->action > IWL_LEGACY_SWITCH_MIMO2_BC)
+               if (tbl->action > IWL_LEGACY_SWITCH_MIMO3_ABC)
                        tbl->action = IWL_LEGACY_SWITCH_ANTENNA1;
 
                if (tbl->action == start_action)
@@ -1357,8 +1500,10 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
 out:
        lq_sta->search_better_tbl = 1;
        tbl->action++;
-       if (tbl->action > IWL_LEGACY_SWITCH_MIMO2_BC)
+       if (tbl->action > IWL_LEGACY_SWITCH_MIMO3_ABC)
                tbl->action = IWL_LEGACY_SWITCH_ANTENNA1;
+       if (update_search_tbl_counter)
+               search_tbl->action = tbl->action;
        return 0;
 
 }
@@ -1381,6 +1526,7 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
        u8 start_action = tbl->action;
        u8 valid_tx_ant = priv->hw_params.valid_tx_ant;
        u8 tx_chains_num = priv->hw_params.tx_chains_num;
+       u8 update_search_tbl_counter = 0;
        int ret;
 
        for (;;) {
@@ -1401,8 +1547,10 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
 
                        memcpy(search_tbl, tbl, sz);
                        if (rs_toggle_antenna(valid_tx_ant,
-                                      &search_tbl->current_rate, search_tbl))
+                                      &search_tbl->current_rate, search_tbl)) {
+                               update_search_tbl_counter = 1;
                                goto out;
+                       }
                        break;
                case IWL_SISO_SWITCH_MIMO2_AB:
                case IWL_SISO_SWITCH_MIMO2_AC:
@@ -1456,10 +1604,25 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
                        search_tbl->current_rate =
                                rate_n_flags_from_tbl(priv, search_tbl,
                                                      index, is_green);
+                       update_search_tbl_counter = 1;
                        goto out;
+               case IWL_SISO_SWITCH_MIMO3_ABC:
+                       IWL_DEBUG_RATE(priv, "LQ: SISO switch to MIMO3\n");
+                       memcpy(search_tbl, tbl, sz);
+                       search_tbl->is_SGI = 0;
+                       search_tbl->ant_type = ANT_ABC;
+
+                       if (!rs_is_valid_ant(valid_tx_ant, search_tbl->ant_type))
+                               break;
+
+                       ret = rs_switch_to_mimo3(priv, lq_sta, conf, sta,
+                                                search_tbl, index);
+                       if (!ret)
+                               goto out;
+                       break;
                }
                tbl->action++;
-               if (tbl->action > IWL_SISO_SWITCH_GI)
+               if (tbl->action > IWL_LEGACY_SWITCH_MIMO3_ABC)
                        tbl->action = IWL_SISO_SWITCH_ANTENNA1;
 
                if (tbl->action == start_action)
@@ -1471,15 +1634,18 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
  out:
        lq_sta->search_better_tbl = 1;
        tbl->action++;
-       if (tbl->action > IWL_SISO_SWITCH_GI)
+       if (tbl->action > IWL_SISO_SWITCH_MIMO3_ABC)
                tbl->action = IWL_SISO_SWITCH_ANTENNA1;
+       if (update_search_tbl_counter)
+               search_tbl->action = tbl->action;
+
        return 0;
 }
 
 /*
- * Try to switch to new modulation mode from MIMO
+ * Try to switch to new modulation mode from MIMO2
  */
-static int rs_move_mimo_to_other(struct iwl_priv *priv,
+static int rs_move_mimo2_to_other(struct iwl_priv *priv,
                                 struct iwl_lq_sta *lq_sta,
                                 struct ieee80211_conf *conf,
                                 struct ieee80211_sta *sta, int index)
@@ -1494,6 +1660,7 @@ static int rs_move_mimo_to_other(struct iwl_priv *priv,
        u8 start_action = tbl->action;
        u8 valid_tx_ant = priv->hw_params.valid_tx_ant;
        u8 tx_chains_num = priv->hw_params.tx_chains_num;
+       u8 update_search_tbl_counter = 0;
        int ret;
 
        for (;;) {
@@ -1501,7 +1668,7 @@ static int rs_move_mimo_to_other(struct iwl_priv *priv,
                switch (tbl->action) {
                case IWL_MIMO2_SWITCH_ANTENNA1:
                case IWL_MIMO2_SWITCH_ANTENNA2:
-                       IWL_DEBUG_RATE(priv, "LQ: MIMO toggle Antennas\n");
+                       IWL_DEBUG_RATE(priv, "LQ: MIMO2 toggle Antennas\n");
 
                        if (tx_chains_num <= 2)
                                break;
@@ -1511,8 +1678,10 @@ static int rs_move_mimo_to_other(struct iwl_priv *priv,
 
                        memcpy(search_tbl, tbl, sz);
                        if (rs_toggle_antenna(valid_tx_ant,
-                                      &search_tbl->current_rate, search_tbl))
+                                      &search_tbl->current_rate, search_tbl)) {
+                               update_search_tbl_counter = 1;
                                goto out;
+                       }
                        break;
                case IWL_MIMO2_SWITCH_SISO_A:
                case IWL_MIMO2_SWITCH_SISO_B:
@@ -1549,9 +1718,9 @@ static int rs_move_mimo_to_other(struct iwl_priv *priv,
                                                HT_SHORT_GI_40MHZ))
                                break;
 
-                       IWL_DEBUG_RATE(priv, "LQ: MIMO toggle SGI/NGI\n");
+                       IWL_DEBUG_RATE(priv, "LQ: MIMO2 toggle SGI/NGI\n");
 
-                       /* Set up new search table for MIMO */
+                       /* Set up new search table for MIMO2 */
                        memcpy(search_tbl, tbl, sz);
                        search_tbl->is_SGI = !tbl->is_SGI;
                        rs_set_expected_tpt_table(lq_sta, search_tbl);
@@ -1569,11 +1738,27 @@ static int rs_move_mimo_to_other(struct iwl_priv *priv,
                        search_tbl->current_rate =
                                rate_n_flags_from_tbl(priv, search_tbl,
                                                      index, is_green);
+                       update_search_tbl_counter = 1;
                        goto out;
 
+               case IWL_MIMO2_SWITCH_MIMO3_ABC:
+                       IWL_DEBUG_RATE(priv, "LQ: MIMO2 switch to MIMO3\n");
+                       memcpy(search_tbl, tbl, sz);
+                       search_tbl->is_SGI = 0;
+                       search_tbl->ant_type = ANT_ABC;
+
+                       if (!rs_is_valid_ant(valid_tx_ant, search_tbl->ant_type))
+                               break;
+
+                       ret = rs_switch_to_mimo3(priv, lq_sta, conf, sta,
+                                                search_tbl, index);
+                       if (!ret)
+                               goto out;
+
+                       break;
                }
                tbl->action++;
-               if (tbl->action > IWL_MIMO2_SWITCH_GI)
+               if (tbl->action > IWL_MIMO2_SWITCH_MIMO3_ABC)
                        tbl->action = IWL_MIMO2_SWITCH_ANTENNA1;
 
                if (tbl->action == start_action)
@@ -1584,8 +1769,153 @@ static int rs_move_mimo_to_other(struct iwl_priv *priv,
  out:
        lq_sta->search_better_tbl = 1;
        tbl->action++;
-       if (tbl->action > IWL_MIMO2_SWITCH_GI)
+       if (tbl->action > IWL_MIMO2_SWITCH_MIMO3_ABC)
                tbl->action = IWL_MIMO2_SWITCH_ANTENNA1;
+       if (update_search_tbl_counter)
+               search_tbl->action = tbl->action;
+
+       return 0;
+
+}
+
+/*
+ * Try to switch to new modulation mode from MIMO3
+ */
+static int rs_move_mimo3_to_other(struct iwl_priv *priv,
+                                struct iwl_lq_sta *lq_sta,
+                                struct ieee80211_conf *conf,
+                                struct ieee80211_sta *sta, int index)
+{
+       s8 is_green = lq_sta->is_green;
+       struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
+       struct iwl_scale_tbl_info *search_tbl =
+                               &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
+       struct iwl_rate_scale_data *window = &(tbl->win[index]);
+       u32 sz = (sizeof(struct iwl_scale_tbl_info) -
+                 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
+       u8 start_action = tbl->action;
+       u8 valid_tx_ant = priv->hw_params.valid_tx_ant;
+       u8 tx_chains_num = priv->hw_params.tx_chains_num;
+       int ret;
+       u8 update_search_tbl_counter = 0;
+
+       for (;;) {
+               lq_sta->action_counter++;
+               switch (tbl->action) {
+               case IWL_MIMO3_SWITCH_ANTENNA1:
+               case IWL_MIMO3_SWITCH_ANTENNA2:
+                       IWL_DEBUG_RATE(priv, "LQ: MIMO3 toggle Antennas\n");
+
+                       if (tx_chains_num <= 3)
+                               break;
+
+                       if (window->success_ratio >= IWL_RS_GOOD_RATIO)
+                               break;
+
+                       memcpy(search_tbl, tbl, sz);
+                       if (rs_toggle_antenna(valid_tx_ant,
+                                      &search_tbl->current_rate, search_tbl))
+                               goto out;
+                       break;
+               case IWL_MIMO3_SWITCH_SISO_A:
+               case IWL_MIMO3_SWITCH_SISO_B:
+               case IWL_MIMO3_SWITCH_SISO_C:
+                       IWL_DEBUG_RATE(priv, "LQ: MIMO3 switch to SISO\n");
+
+                       /* Set up new search table for SISO */
+                       memcpy(search_tbl, tbl, sz);
+
+                       if (tbl->action == IWL_MIMO3_SWITCH_SISO_A)
+                               search_tbl->ant_type = ANT_A;
+                       else if (tbl->action == IWL_MIMO3_SWITCH_SISO_B)
+                               search_tbl->ant_type = ANT_B;
+                       else
+                               search_tbl->ant_type = ANT_C;
+
+                       if (!rs_is_valid_ant(valid_tx_ant, search_tbl->ant_type))
+                               break;
+
+                       ret = rs_switch_to_siso(priv, lq_sta, conf, sta,
+                                                search_tbl, index);
+                       if (!ret)
+                               goto out;
+
+                       break;
+
+               case IWL_MIMO3_SWITCH_MIMO2_AB:
+               case IWL_MIMO3_SWITCH_MIMO2_AC:
+               case IWL_MIMO3_SWITCH_MIMO2_BC:
+                       IWL_DEBUG_RATE(priv, "LQ: MIMO3 switch to MIMO2\n");
+
+                       memcpy(search_tbl, tbl, sz);
+                       search_tbl->is_SGI = 0;
+                       if (tbl->action == IWL_MIMO3_SWITCH_MIMO2_AB)
+                               search_tbl->ant_type = ANT_AB;
+                       else if (tbl->action == IWL_MIMO3_SWITCH_MIMO2_AC)
+                               search_tbl->ant_type = ANT_AC;
+                       else
+                               search_tbl->ant_type = ANT_BC;
+
+                       if (!rs_is_valid_ant(valid_tx_ant, search_tbl->ant_type))
+                               break;
+
+                       ret = rs_switch_to_mimo2(priv, lq_sta, conf, sta,
+                                                search_tbl, index);
+                       if (!ret)
+                               goto out;
+
+                       break;
+
+               case IWL_MIMO3_SWITCH_GI:
+                       if (!tbl->is_fat &&
+                               !(priv->current_ht_config.sgf &
+                                               HT_SHORT_GI_20MHZ))
+                               break;
+                       if (tbl->is_fat &&
+                               !(priv->current_ht_config.sgf &
+                                               HT_SHORT_GI_40MHZ))
+                               break;
+
+                       IWL_DEBUG_RATE(priv, "LQ: MIMO3 toggle SGI/NGI\n");
+
+                       /* Set up new search table for MIMO */
+                       memcpy(search_tbl, tbl, sz);
+                       search_tbl->is_SGI = !tbl->is_SGI;
+                       rs_set_expected_tpt_table(lq_sta, search_tbl);
+                       /*
+                        * If active table already uses the fastest possible
+                        * modulation (dual stream with short guard interval),
+                        * and it's working well, there's no need to look
+                        * for a better type of modulation!
+                        */
+                       if (tbl->is_SGI) {
+                               s32 tpt = lq_sta->last_tpt / 100;
+                               if (tpt >= search_tbl->expected_tpt[index])
+                                       break;
+                       }
+                       search_tbl->current_rate =
+                               rate_n_flags_from_tbl(priv, search_tbl,
+                                                     index, is_green);
+                       update_search_tbl_counter = 1;
+                       goto out;
+               }
+               tbl->action++;
+               if (tbl->action > IWL_MIMO3_SWITCH_GI)
+                       tbl->action = IWL_MIMO3_SWITCH_ANTENNA1;
+
+               if (tbl->action == start_action)
+                       break;
+       }
+       search_tbl->lq_type = LQ_NONE;
+       return 0;
+ out:
+       lq_sta->search_better_tbl = 1;
+       tbl->action++;
+       if (tbl->action > IWL_MIMO3_SWITCH_GI)
+               tbl->action = IWL_MIMO3_SWITCH_ANTENNA1;
+       if (update_search_tbl_counter)
+               search_tbl->action = tbl->action;
+
        return 0;
 
 }
@@ -1616,8 +1946,8 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta)
                /* Elapsed time using current modulation mode */
                if (lq_sta->flush_timer)
                        flush_interval_passed =
-                           time_after(jiffies,
-                                      (unsigned long)(lq_sta->flush_timer +
+                       time_after(jiffies,
+                                       (unsigned long)(lq_sta->flush_timer +
                                        IWL_RATE_SCALE_FLUSH_INTVL));
 
                /*
@@ -1676,12 +2006,14 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta)
  * Do rate scaling and search for new modulation mode.
  */
 static void rs_rate_scale_perform(struct iwl_priv *priv,
-                                 struct ieee80211_hdr *hdr,
+                                 struct sk_buff *skb,
                                  struct ieee80211_sta *sta,
                                  struct iwl_lq_sta *lq_sta)
 {
        struct ieee80211_hw *hw = priv->hw;
        struct ieee80211_conf *conf = &hw->conf;
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
        int low = IWL_RATE_INVALID;
        int high = IWL_RATE_INVALID;
        int index;
@@ -1707,11 +2039,10 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
 
        IWL_DEBUG_RATE(priv, "rate scale calculate new rate for skb\n");
 
-       /* Send management frames and broadcast/multicast data using
-        * lowest rate. */
+       /* Send management frames and NO_ACK data using lowest rate. */
        /* TODO: this could probably be improved.. */
        if (!ieee80211_is_data(hdr->frame_control) ||
-           is_multicast_ether_addr(hdr->addr1))
+           info->flags & IEEE80211_TX_CTL_NO_ACK)
                return;
 
        if (!sta || !lq_sta)
@@ -1732,6 +2063,10 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
                active_tbl = 1 - lq_sta->active_tbl;
 
        tbl = &(lq_sta->lq_info[active_tbl]);
+       if (is_legacy(tbl->lq_type))
+               lq_sta->is_green = 0;
+       else
+               lq_sta->is_green = rs_use_green(priv, conf);
        is_green = lq_sta->is_green;
 
        /* current tx rate */
@@ -1951,6 +2286,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
                        update_lq = 1;
                        index = low;
                }
+
                break;
        case 1:
                /* Increase starting rate, update uCode's rate table */
@@ -1997,8 +2333,10 @@ lq_update:
                        rs_move_legacy_other(priv, lq_sta, conf, sta, index);
                else if (is_siso(tbl->lq_type))
                        rs_move_siso_to_other(priv, lq_sta, conf, sta, index);
+               else if (is_mimo2(tbl->lq_type))
+                       rs_move_mimo2_to_other(priv, lq_sta, conf, sta, index);
                else
-                       rs_move_mimo_to_other(priv, lq_sta, conf, sta, index);
+                       rs_move_mimo3_to_other(priv, lq_sta, conf, sta, index);
 
                /* If new "search" mode was selected, set up in uCode table */
                if (lq_sta->search_better_tbl) {
@@ -2014,8 +2352,11 @@ lq_update:
                                     tbl->current_rate, index);
                        rs_fill_link_cmd(priv, lq_sta, tbl->current_rate);
                        iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC);
-               }
+               } else
+                       done_search = 1;
+       }
 
+       if (done_search && !lq_sta->stay_in_tbl) {
                /* If the "active" (non-search) mode was legacy,
                 * and we've tried switching antennas,
                 * but we haven't been able to try HT modes (not available),
@@ -2023,8 +2364,7 @@ lq_update:
                 * before next round of mode comparisons. */
                tbl1 = &(lq_sta->lq_info[lq_sta->active_tbl]);
                if (is_legacy(tbl1->lq_type) && !conf_is_ht(conf) &&
-                   lq_sta->action_counter >= 1) {
-                       lq_sta->action_counter = 0;
+                   lq_sta->action_counter > tbl1->max_search) {
                        IWL_DEBUG_RATE(priv, "LQ: STAY in legacy table\n");
                        rs_set_stay_in_table(priv, 1, lq_sta);
                }
@@ -2033,7 +2373,7 @@ lq_update:
                 * have been tried and compared, stay in this best modulation
                 * mode for a while before next round of mode comparisons. */
                if (lq_sta->enable_counter &&
-                   (lq_sta->action_counter >= IWL_ACTION_LIMIT)) {
+                   (lq_sta->action_counter >= tbl1->max_search)) {
                        if ((lq_sta->last_tpt > IWL_AGG_TPT_THREHOLD) &&
                            (lq_sta->tx_agg_tid_en & (1 << tid)) &&
                            (tid != MAX_TID_COUNT)) {
@@ -2047,20 +2387,8 @@ lq_update:
                                                          lq_sta, sta);
                                }
                        }
-                       lq_sta->action_counter = 0;
                        rs_set_stay_in_table(priv, 0, lq_sta);
                }
-
-       /*
-        * Else, don't search for a new modulation mode.
-        * Put new timestamp in stay-in-modulation-mode flush timer if:
-        * 1)  Not changing rates right now
-        * 2)  Not just finishing up a search
-        * 3)  flush timer is empty
-        */
-       } else {
-               if ((!update_lq) && (!done_search) && (!lq_sta->flush_timer))
-                       lq_sta->flush_timer = jiffies;
        }
 
 out:
@@ -2156,16 +2484,17 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta,
        if (sta)
                mask_bit = sta->supp_rates[sband->band];
 
-       /* Send management frames and broadcast/multicast data using lowest
-        * rate. */
+       /* Send management frames and NO_ACK data using lowest rate. */
        if (!ieee80211_is_data(hdr->frame_control) ||
-           is_multicast_ether_addr(hdr->addr1) || !sta || !lq_sta) {
+           info->flags & IEEE80211_TX_CTL_NO_ACK || !sta || !lq_sta) {
                if (!mask_bit)
                        info->control.rates[0].idx =
                                        rate_lowest_index(sband, NULL);
                else
                        info->control.rates[0].idx =
                                        rate_lowest_index(sband, sta);
+               if (info->flags & IEEE80211_TX_CTL_NO_ACK)
+                       info->control.rates[0].count = 1;
                return;
        }
 
@@ -2178,8 +2507,8 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta,
                if (sta_id == IWL_INVALID_STATION) {
                        IWL_DEBUG_RATE(priv, "LQ: ADD station %pM\n",
                                       hdr->addr1);
-                       sta_id = iwl_add_station_flags(priv, hdr->addr1,
-                                                       0, CMD_ASYNC, NULL);
+                       sta_id = iwl_add_station(priv, hdr->addr1,
+                                               false, CMD_ASYNC, NULL);
                }
                if ((sta_id != IWL_INVALID_STATION)) {
                        lq_sta->lq.sta_id = sta_id;
@@ -2189,12 +2518,33 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta,
                }
        }
 
-       if (rate_idx < 0 || rate_idx > IWL_RATE_COUNT)
-               rate_idx = rate_lowest_index(sband, sta);
-       else if (sband->band == IEEE80211_BAND_5GHZ)
+       if (lq_sta->last_rate_n_flags & RATE_MCS_HT_MSK) {
                rate_idx -= IWL_FIRST_OFDM_RATE;
-
+               /* 6M and 9M shared same MCS index */
+               rate_idx = (rate_idx > 0) ? (rate_idx - 1) : 0;
+               if (rs_extract_rate(lq_sta->last_rate_n_flags) >=
+                   IWL_RATE_MIMO3_6M_PLCP)
+                       rate_idx = rate_idx + (2 * MCS_INDEX_PER_STREAM);
+               else if (rs_extract_rate(lq_sta->last_rate_n_flags) >=
+                        IWL_RATE_MIMO2_6M_PLCP)
+                       rate_idx = rate_idx + MCS_INDEX_PER_STREAM;
+               info->control.rates[0].flags = IEEE80211_TX_RC_MCS;
+               if (lq_sta->last_rate_n_flags & RATE_MCS_SGI_MSK)
+                       info->control.rates[0].flags |= IEEE80211_TX_RC_SHORT_GI;
+               if (lq_sta->last_rate_n_flags & RATE_MCS_DUP_MSK)
+                       info->control.rates[0].flags |= IEEE80211_TX_RC_DUP_DATA;
+               if (lq_sta->last_rate_n_flags & RATE_MCS_FAT_MSK)
+                       info->control.rates[0].flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
+               if (lq_sta->last_rate_n_flags & RATE_MCS_GF_MSK)
+                       info->control.rates[0].flags |= IEEE80211_TX_RC_GREEN_FIELD;
+       } else {
+               if (rate_idx < 0 || rate_idx > IWL_RATE_COUNT)
+                       rate_idx = rate_lowest_index(sband, sta);
+               else if (sband->band == IEEE80211_BAND_5GHZ)
+                       rate_idx -= IWL_FIRST_OFDM_RATE;
+       }
        info->control.rates[0].idx = rate_idx;
+
 }
 
 static void *rs_alloc_sta(void *priv_rate, struct ieee80211_sta *sta,
@@ -2246,15 +2596,16 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
 
        lq_sta->ibss_sta_added = 0;
        if (priv->iw_mode == NL80211_IFTYPE_AP) {
-               u8 sta_id = iwl_find_station(priv, sta->addr);
+               u8 sta_id = iwl_find_station(priv,
+                                                               sta->addr);
 
                /* for IBSS the call are from tasklet */
                IWL_DEBUG_RATE(priv, "LQ: ADD station %pM\n", sta->addr);
 
                if (sta_id == IWL_INVALID_STATION) {
                        IWL_DEBUG_RATE(priv, "LQ: ADD station %pM\n", sta->addr);
-                       sta_id = iwl_add_station_flags(priv, sta->addr,
-                                                       0, CMD_ASYNC, NULL);
+                       sta_id = iwl_add_station(priv, sta->addr, false,
+                                               CMD_ASYNC, NULL);
                }
                if ((sta_id != IWL_INVALID_STATION)) {
                        lq_sta->lq.sta_id = sta_id;
@@ -2436,9 +2787,10 @@ static void rs_fill_link_cmd(const struct iwl_priv *priv,
                repeat_rate--;
        }
 
-       lq_cmd->agg_params.agg_frame_cnt_limit = 64;
-       lq_cmd->agg_params.agg_dis_start_th = 3;
-       lq_cmd->agg_params.agg_time_limit = cpu_to_le16(4000);
+       lq_cmd->agg_params.agg_frame_cnt_limit = LINK_QUAL_AGG_FRAME_LIMIT_MAX;
+       lq_cmd->agg_params.agg_dis_start_th = LINK_QUAL_AGG_DISABLE_START_DEF;
+       lq_cmd->agg_params.agg_time_limit =
+               cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF);
 }
 
 static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
@@ -2539,6 +2891,7 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
        char *buff;
        int desc = 0;
        int i = 0;
+       int index = 0;
        ssize_t ret;
 
        struct iwl_lq_sta *lq_sta = file->private_data;
@@ -2568,8 +2921,11 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
                   ((is_mimo2(tbl->lq_type)) ? "MIMO2" : "MIMO3"));
                   desc += sprintf(buff+desc, " %s",
                   (tbl->is_fat) ? "40MHz" : "20MHz");
-               desc += sprintf(buff+desc, " %s\n", (tbl->is_SGI) ? "SGI" : "");
+                  desc += sprintf(buff+desc, " %s %s\n", (tbl->is_SGI) ? "SGI" : "",
+                  (lq_sta->is_green) ? "GF enabled" : "");
        }
+       desc += sprintf(buff+desc, "last tx rate=0x%X\n",
+               lq_sta->last_rate_n_flags);
        desc += sprintf(buff+desc, "general:"
                "flags=0x%X mimo-d=%d s-ant0x%x d-ant=0x%x\n",
                lq_sta->lq.general_params.flags,
@@ -2590,10 +2946,19 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
                        lq_sta->lq.general_params.start_rate_index[2],
                        lq_sta->lq.general_params.start_rate_index[3]);
 
-
-       for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++)
-               desc += sprintf(buff+desc, " rate[%d] 0x%X\n",
-                       i, le32_to_cpu(lq_sta->lq.rs_table[i].rate_n_flags));
+       for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) {
+               index = iwl_hwrate_to_plcp_idx(
+                       le32_to_cpu(lq_sta->lq.rs_table[i].rate_n_flags));
+               if (is_legacy(tbl->lq_type)) {
+                       desc += sprintf(buff+desc, " rate[%d] 0x%X %smbps\n",
+                               i, le32_to_cpu(lq_sta->lq.rs_table[i].rate_n_flags),
+                               iwl_rate_mcs[index].mbps);
+               } else {
+                       desc += sprintf(buff+desc, " rate[%d] 0x%X %smbps (%s)\n",
+                               i, le32_to_cpu(lq_sta->lq.rs_table[i].rate_n_flags),
+                               iwl_rate_mcs[index].mbps, iwl_rate_mcs[index].mcs);
+               }
+       }
 
        ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc);
        kfree(buff);
@@ -2620,13 +2985,14 @@ static ssize_t rs_sta_dbgfs_stats_table_read(struct file *file,
                return -ENOMEM;
 
        for (i = 0; i < LQ_SIZE; i++) {
-               desc += sprintf(buff+desc, "%s type=%d SGI=%d FAT=%d DUP=%d\n"
+               desc += sprintf(buff+desc, "%s type=%d SGI=%d FAT=%d DUP=%d GF=%d\n"
                                "rate=0x%X\n",
                                lq_sta->active_tbl == i ? "*" : "x",
                                lq_sta->lq_info[i].lq_type,
                                lq_sta->lq_info[i].is_SGI,
                                lq_sta->lq_info[i].is_fat,
                                lq_sta->lq_info[i].is_dup,
+                               lq_sta->is_green,
                                lq_sta->lq_info[i].current_rate);
                for (j = 0; j < IWL_RATE_COUNT; j++) {
                        desc += sprintf(buff+desc,
@@ -2646,6 +3012,43 @@ static const struct file_operations rs_sta_dbgfs_stats_table_ops = {
        .open = open_file_generic,
 };
 
+static ssize_t rs_sta_dbgfs_rate_scale_data_read(struct file *file,
+                       char __user *user_buf, size_t count, loff_t *ppos)
+{
+       char buff[120];
+       int desc = 0;
+       ssize_t ret;
+
+       struct iwl_lq_sta *lq_sta = file->private_data;
+       struct iwl_priv *priv;
+       struct iwl_scale_tbl_info *tbl = &lq_sta->lq_info[lq_sta->active_tbl];
+
+       priv = lq_sta->drv;
+
+       if (is_Ht(tbl->lq_type))
+               desc += sprintf(buff+desc,
+                               "Bit Rate= %d Mb/s\n",
+                               tbl->expected_tpt[lq_sta->last_txrate_idx]);
+       else
+               desc += sprintf(buff+desc,
+                               "Bit Rate= %d Mb/s\n",
+                               iwl_rates[lq_sta->last_txrate_idx].ieee >> 1);
+       desc += sprintf(buff+desc,
+                       "Signal Level= %d dBm\tNoise Level= %d dBm\n",
+                       priv->last_rx_rssi, priv->last_rx_noise);
+       desc += sprintf(buff+desc,
+                       "Tsf= 0x%llx\tBeacon time= 0x%08X\n",
+                       priv->last_tsf, priv->last_beacon_time);
+
+       ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc);
+       return ret;
+}
+
+static const struct file_operations rs_sta_dbgfs_rate_scale_data_ops = {
+       .read = rs_sta_dbgfs_rate_scale_data_read,
+       .open = open_file_generic,
+};
+
 static void rs_add_debugfs(void *priv, void *priv_sta,
                                        struct dentry *dir)
 {
@@ -2656,6 +3059,9 @@ static void rs_add_debugfs(void *priv, void *priv_sta,
        lq_sta->rs_sta_dbgfs_stats_table_file =
                debugfs_create_file("rate_stats_table", 0600, dir,
                        lq_sta, &rs_sta_dbgfs_stats_table_ops);
+       lq_sta->rs_sta_dbgfs_rate_scale_data_file =
+               debugfs_create_file("rate_scale_data", 0600, dir,
+                       lq_sta, &rs_sta_dbgfs_rate_scale_data_ops);
        lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file =
                debugfs_create_u8("tx_agg_tid_enable", 0600, dir,
                &lq_sta->tx_agg_tid_en);
@@ -2667,6 +3073,7 @@ static void rs_remove_debugfs(void *priv, void *priv_sta)
        struct iwl_lq_sta *lq_sta = priv_sta;
        debugfs_remove(lq_sta->rs_sta_dbgfs_scale_table_file);
        debugfs_remove(lq_sta->rs_sta_dbgfs_stats_table_file);
+       debugfs_remove(lq_sta->rs_sta_dbgfs_rate_scale_data_file);
        debugfs_remove(lq_sta->rs_sta_dbgfs_tx_agg_tid_en_file);
 }
 #endif
index ab59acc405d9426774f3e3cffad380be8affa542..25050bf315a2bfb92acd54bae3f904952fa90e5e 100644 (file)
@@ -241,6 +241,7 @@ enum {
 #define IWL_LEGACY_SWITCH_MIMO2_AB      3
 #define IWL_LEGACY_SWITCH_MIMO2_AC      4
 #define IWL_LEGACY_SWITCH_MIMO2_BC      5
+#define IWL_LEGACY_SWITCH_MIMO3_ABC     6
 
 /* possible actions when in siso mode */
 #define IWL_SISO_SWITCH_ANTENNA1        0
@@ -249,6 +250,8 @@ enum {
 #define IWL_SISO_SWITCH_MIMO2_AC        3
 #define IWL_SISO_SWITCH_MIMO2_BC        4
 #define IWL_SISO_SWITCH_GI              5
+#define IWL_SISO_SWITCH_MIMO3_ABC       6
+
 
 /* possible actions when in mimo mode */
 #define IWL_MIMO2_SWITCH_ANTENNA1       0
@@ -257,6 +260,23 @@ enum {
 #define IWL_MIMO2_SWITCH_SISO_B         3
 #define IWL_MIMO2_SWITCH_SISO_C         4
 #define IWL_MIMO2_SWITCH_GI             5
+#define IWL_MIMO2_SWITCH_MIMO3_ABC      6
+
+
+/* possible actions when in mimo3 mode */
+#define IWL_MIMO3_SWITCH_ANTENNA1       0
+#define IWL_MIMO3_SWITCH_ANTENNA2       1
+#define IWL_MIMO3_SWITCH_SISO_A         2
+#define IWL_MIMO3_SWITCH_SISO_B         3
+#define IWL_MIMO3_SWITCH_SISO_C         4
+#define IWL_MIMO3_SWITCH_MIMO2_AB       5
+#define IWL_MIMO3_SWITCH_MIMO2_AC       6
+#define IWL_MIMO3_SWITCH_MIMO2_BC       7
+#define IWL_MIMO3_SWITCH_GI             8
+
+
+#define IWL_MAX_11N_MIMO3_SEARCH IWL_MIMO3_SWITCH_GI
+#define IWL_MAX_SEARCH IWL_MIMO2_SWITCH_MIMO3_ABC
 
 /*FIXME:RS:add possible actions for MIMO3*/
 
@@ -307,6 +327,13 @@ enum iwl_table_type {
 #define ANT_BC         (ANT_B | ANT_C)
 #define ANT_ABC                (ANT_AB | ANT_C)
 
+#define IWL_MAX_MCS_DISPLAY_SIZE       12
+
+struct iwl_rate_mcs_info {
+       char    mbps[IWL_MAX_MCS_DISPLAY_SIZE];
+       char    mcs[IWL_MAX_MCS_DISPLAY_SIZE];
+};
+
 static inline u8 num_of_ant(u8 mask)
 {
        return  !!((mask) & ANT_A) +
index f46ba24757768226a842ef1f51bc0b61f53275cd..a5637c4aa85dc2936c129d37501560db2b13ec21 100644 (file)
@@ -102,7 +102,7 @@ MODULE_ALIAS("iwl4965");
  * function correctly transitions out of the RXON_ASSOC_MSK state if
  * a HW tune is required based on the RXON structure changes.
  */
-static int iwl_commit_rxon(struct iwl_priv *priv)
+int iwl_commit_rxon(struct iwl_priv *priv)
 {
        /* cast away the const for active_rxon in this function */
        struct iwl_rxon_cmd *active_rxon = (void *)&priv->active_rxon;
@@ -190,8 +190,7 @@ static int iwl_commit_rxon(struct iwl_priv *priv)
 
        iwl_clear_stations_table(priv);
 
-       if (!priv->error_recovering)
-               priv->start_calib = 0;
+       priv->start_calib = 0;
 
        /* Add the broadcast address so we can send broadcast frames */
        if (iwl_rxon_add_station(priv, iwl_bcast_addr, 0) ==
@@ -246,8 +245,9 @@ static int iwl_commit_rxon(struct iwl_priv *priv)
 void iwl_update_chain_flags(struct iwl_priv *priv)
 {
 
-       iwl_set_rxon_chain(priv);
-       iwl_commit_rxon(priv);
+       if (priv->cfg->ops->hcmd->set_rxon_chain)
+               priv->cfg->ops->hcmd->set_rxon_chain(priv);
+       iwlcore_commit_rxon(priv);
 }
 
 static void iwl_clear_free_frames(struct iwl_priv *priv)
@@ -503,24 +503,12 @@ int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv,
 int iwl_hw_tx_queue_init(struct iwl_priv *priv,
                         struct iwl_tx_queue *txq)
 {
-       int ret;
-       unsigned long flags;
        int txq_id = txq->q.id;
 
-       spin_lock_irqsave(&priv->lock, flags);
-       ret = iwl_grab_nic_access(priv);
-       if (ret) {
-               spin_unlock_irqrestore(&priv->lock, flags);
-               return ret;
-       }
-
        /* Circular buffer (TFD queue in DRAM) physical base address */
        iwl_write_direct32(priv, FH_MEM_CBBC_QUEUE(txq_id),
                             txq->q.dma_addr >> 8);
 
-       iwl_release_nic_access(priv);
-       spin_unlock_irqrestore(&priv->lock, flags);
-
        return 0;
 }
 
@@ -531,76 +519,6 @@ int iwl_hw_tx_queue_init(struct iwl_priv *priv,
  *
  ******************************************************************************/
 
-static void iwl_ht_conf(struct iwl_priv *priv,
-                           struct ieee80211_bss_conf *bss_conf)
-{
-       struct ieee80211_sta_ht_cap *ht_conf;
-       struct iwl_ht_info *iwl_conf = &priv->current_ht_config;
-       struct ieee80211_sta *sta;
-
-       IWL_DEBUG_MAC80211(priv, "enter: \n");
-
-       if (!iwl_conf->is_ht)
-               return;
-
-
-       /*
-        * It is totally wrong to base global information on something
-        * that is valid only when associated, alas, this driver works
-        * that way and I don't know how to fix it.
-        */
-
-       rcu_read_lock();
-       sta = ieee80211_find_sta(priv->hw, priv->bssid);
-       if (!sta) {
-               rcu_read_unlock();
-               return;
-       }
-       ht_conf = &sta->ht_cap;
-
-       if (ht_conf->cap & IEEE80211_HT_CAP_SGI_20)
-               iwl_conf->sgf |= HT_SHORT_GI_20MHZ;
-       if (ht_conf->cap & IEEE80211_HT_CAP_SGI_40)
-               iwl_conf->sgf |= HT_SHORT_GI_40MHZ;
-
-       iwl_conf->is_green_field = !!(ht_conf->cap & IEEE80211_HT_CAP_GRN_FLD);
-       iwl_conf->max_amsdu_size =
-               !!(ht_conf->cap & IEEE80211_HT_CAP_MAX_AMSDU);
-
-       iwl_conf->supported_chan_width =
-               !!(ht_conf->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40);
-
-       /*
-        * XXX: The HT configuration needs to be moved into iwl_mac_config()
-        *      to be done there correctly.
-        */
-
-       iwl_conf->extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_NONE;
-       if (conf_is_ht40_minus(&priv->hw->conf))
-               iwl_conf->extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_BELOW;
-       else if (conf_is_ht40_plus(&priv->hw->conf))
-               iwl_conf->extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
-
-       /* If no above or below channel supplied disable FAT channel */
-       if (iwl_conf->extension_chan_offset != IEEE80211_HT_PARAM_CHA_SEC_ABOVE &&
-           iwl_conf->extension_chan_offset != IEEE80211_HT_PARAM_CHA_SEC_BELOW)
-               iwl_conf->supported_chan_width = 0;
-
-       iwl_conf->sm_ps = (u8)((ht_conf->cap & IEEE80211_HT_CAP_SM_PS) >> 2);
-
-       memcpy(&iwl_conf->mcs, &ht_conf->mcs, 16);
-
-       iwl_conf->tx_chan_width = iwl_conf->supported_chan_width != 0;
-       iwl_conf->ht_protection =
-               bss_conf->ht.operation_mode & IEEE80211_HT_OP_MODE_PROTECTION;
-       iwl_conf->non_GF_STA_present =
-               !!(bss_conf->ht.operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
-
-       rcu_read_unlock();
-
-       IWL_DEBUG_MAC80211(priv, "leave\n");
-}
-
 #define MAX_UCODE_BEACON_INTERVAL      4096
 
 static u16 iwl_adjust_beacon_interval(u16 beacon_val)
@@ -636,7 +554,8 @@ static void iwl_setup_rxon_timing(struct iwl_priv *priv)
                beacon_int = iwl_adjust_beacon_interval(priv->beacon_int);
                priv->rxon_timing.atim_window = 0;
        } else {
-               beacon_int = iwl_adjust_beacon_interval(conf->beacon_int);
+               beacon_int = iwl_adjust_beacon_interval(
+                       priv->vif->bss_conf.beacon_int);
 
                /* TODO: we need to get atim_window from upper stack
                 * for now we set to 0 */
@@ -657,23 +576,6 @@ static void iwl_setup_rxon_timing(struct iwl_priv *priv)
                        le16_to_cpu(priv->rxon_timing.atim_window));
 }
 
-static int iwl_set_mode(struct iwl_priv *priv, int mode)
-{
-       iwl_connection_init_rx_config(priv, mode);
-       iwl_set_rxon_chain(priv);
-       memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN);
-
-       iwl_clear_stations_table(priv);
-
-       /* dont commit rxon if rf-kill is on*/
-       if (!iwl_is_ready_rf(priv))
-               return -EAGAIN;
-
-       iwl_commit_rxon(priv);
-
-       return 0;
-}
-
 /******************************************************************************
  *
  * Generic RX handler implementations
@@ -795,6 +697,7 @@ static void iwl_rx_card_state_notif(struct iwl_priv *priv,
        struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
        u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags);
        unsigned long status = priv->status;
+       unsigned long reg_flags;
 
        IWL_DEBUG_RF_KILL(priv, "Card state received: HW:%s SW:%s\n",
                          (flags & HW_CARD_DISABLED) ? "Kill" : "On",
@@ -806,32 +709,25 @@ static void iwl_rx_card_state_notif(struct iwl_priv *priv,
                iwl_write32(priv, CSR_UCODE_DRV_GP1_SET,
                            CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
 
-               if (!iwl_grab_nic_access(priv)) {
-                       iwl_write_direct32(
-                               priv, HBUS_TARG_MBX_C,
-                               HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED);
-
-                       iwl_release_nic_access(priv);
-               }
+               iwl_write_direct32(priv, HBUS_TARG_MBX_C,
+                                       HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED);
 
                if (!(flags & RXON_CARD_DISABLED)) {
                        iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR,
                                    CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
-                       if (!iwl_grab_nic_access(priv)) {
-                               iwl_write_direct32(
-                                       priv, HBUS_TARG_MBX_C,
+                       iwl_write_direct32(priv, HBUS_TARG_MBX_C,
                                        HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED);
 
-                               iwl_release_nic_access(priv);
-                       }
                }
 
                if (flags & RF_CARD_DISABLED) {
                        iwl_write32(priv, CSR_UCODE_DRV_GP1_SET,
                                    CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT);
                        iwl_read32(priv, CSR_UCODE_DRV_GP1);
+                       spin_lock_irqsave(&priv->reg_lock, reg_flags);
                        if (!iwl_grab_nic_access(priv))
                                iwl_release_nic_access(priv);
+                       spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
                }
        }
 
@@ -841,33 +737,19 @@ static void iwl_rx_card_state_notif(struct iwl_priv *priv,
                clear_bit(STATUS_RF_KILL_HW, &priv->status);
 
 
-       if (flags & SW_CARD_DISABLED)
-               set_bit(STATUS_RF_KILL_SW, &priv->status);
-       else
-               clear_bit(STATUS_RF_KILL_SW, &priv->status);
-
        if (!(flags & RXON_CARD_DISABLED))
                iwl_scan_cancel(priv);
 
        if ((test_bit(STATUS_RF_KILL_HW, &status) !=
-            test_bit(STATUS_RF_KILL_HW, &priv->status)) ||
-           (test_bit(STATUS_RF_KILL_SW, &status) !=
-            test_bit(STATUS_RF_KILL_SW, &priv->status)))
-               queue_work(priv->workqueue, &priv->rf_kill);
+            test_bit(STATUS_RF_KILL_HW, &priv->status)))
+               wiphy_rfkill_set_hw_state(priv->hw->wiphy,
+                       test_bit(STATUS_RF_KILL_HW, &priv->status));
        else
                wake_up_interruptible(&priv->wait_command_queue);
 }
 
 int iwl_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src)
 {
-       int ret;
-       unsigned long flags;
-
-       spin_lock_irqsave(&priv->lock, flags);
-       ret = iwl_grab_nic_access(priv);
-       if (ret)
-               goto err;
-
        if (src == IWL_PWR_SRC_VAUX) {
                if (pci_pme_capable(priv->pci_dev, PCI_D3cold))
                        iwl_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
@@ -879,10 +761,7 @@ int iwl_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src)
                                       ~APMG_PS_CTRL_MSK_PWR_SRC);
        }
 
-       iwl_release_nic_access(priv);
-err:
-       spin_unlock_irqrestore(&priv->lock, flags);
-       return ret;
+       return 0;
 }
 
 /**
@@ -946,6 +825,7 @@ void iwl_rx_handle(struct iwl_priv *priv)
        unsigned long flags;
        u8 fill_rx = 0;
        u32 count = 8;
+       int total_empty;
 
        /* uCode's read index (stored in shared DRAM) indicates the last Rx
         * buffer that the driver may process (last buffer filled by ucode). */
@@ -956,7 +836,12 @@ void iwl_rx_handle(struct iwl_priv *priv)
        if (i == r)
                IWL_DEBUG_RX(priv, "r = %d, i = %d\n", r, i);
 
-       if (iwl_rx_queue_space(rxq) > (RX_QUEUE_SIZE / 2))
+       /* calculate total frames need to be restock after handling RX */
+       total_empty = r - priv->rxq.write_actual;
+       if (total_empty < 0)
+               total_empty += RX_QUEUE_SIZE;
+
+       if (total_empty > (RX_QUEUE_SIZE / 2))
                fill_rx = 1;
 
        while (i != r) {
@@ -995,6 +880,7 @@ void iwl_rx_handle(struct iwl_priv *priv)
                        IWL_DEBUG_RX(priv, "r = %d, i = %d, %s, 0x%02x\n", r,
                                i, get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd);
                        priv->rx_handlers[pkt->hdr.cmd] (priv, rxb);
+                       priv->isr_stats.rx_handlers[pkt->hdr.cmd]++;
                } else {
                        /* No handling needed */
                        IWL_DEBUG_RX(priv,
@@ -1032,7 +918,7 @@ void iwl_rx_handle(struct iwl_priv *priv)
                        count++;
                        if (count >= 8) {
                                priv->rxq.read = i;
-                               iwl_rx_queue_restock(priv);
+                               iwl_rx_replenish_now(priv);
                                count = 0;
                        }
                }
@@ -1040,7 +926,10 @@ void iwl_rx_handle(struct iwl_priv *priv)
 
        /* Backtrack one entry */
        priv->rxq.read = i;
-       iwl_rx_queue_restock(priv);
+       if (fill_rx)
+               iwl_rx_replenish_now(priv);
+       else
+               iwl_rx_queue_restock(priv);
 }
 
 /* call this function to flush any scheduled tasklet */
@@ -1051,24 +940,7 @@ static inline void iwl_synchronize_irq(struct iwl_priv *priv)
        tasklet_kill(&priv->irq_tasklet);
 }
 
-static void iwl_error_recovery(struct iwl_priv *priv)
-{
-       unsigned long flags;
-
-       memcpy(&priv->staging_rxon, &priv->recovery_rxon,
-              sizeof(priv->staging_rxon));
-       priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
-       iwl_commit_rxon(priv);
-
-       iwl_rxon_add_station(priv, priv->bssid, 1);
-
-       spin_lock_irqsave(&priv->lock, flags);
-       priv->assoc_id = le16_to_cpu(priv->staging_rxon.assoc_id);
-       priv->error_recovering = 0;
-       spin_unlock_irqrestore(&priv->lock, flags);
-}
-
-static void iwl_irq_tasklet(struct iwl_priv *priv)
+static void iwl_irq_tasklet_legacy(struct iwl_priv *priv)
 {
        u32 inta, handled = 0;
        u32 inta_fh;
@@ -1116,6 +988,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
                /* Tell the device to stop sending interrupts */
                iwl_disable_interrupts(priv);
 
+               priv->isr_stats.hw++;
                iwl_irq_handle_error(priv);
 
                handled |= CSR_INT_BIT_HW_ERR;
@@ -1128,13 +1001,17 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
 #ifdef CONFIG_IWLWIFI_DEBUG
        if (priv->debug_level & (IWL_DL_ISR)) {
                /* NIC fires this, but we don't use it, redundant with WAKEUP */
-               if (inta & CSR_INT_BIT_SCD)
+               if (inta & CSR_INT_BIT_SCD) {
                        IWL_DEBUG_ISR(priv, "Scheduler finished to transmit "
                                      "the frame/frames.\n");
+                       priv->isr_stats.sch++;
+               }
 
                /* Alive notification via Rx interrupt will do the real work */
-               if (inta & CSR_INT_BIT_ALIVE)
+               if (inta & CSR_INT_BIT_ALIVE) {
                        IWL_DEBUG_ISR(priv, "Alive interrupt\n");
+                       priv->isr_stats.alive++;
+               }
        }
 #endif
        /* Safely ignore these bits for debug checks below */
@@ -1150,6 +1027,8 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
                IWL_DEBUG_RF_KILL(priv, "RF_KILL bit toggled to %s.\n",
                                hw_rf_kill ? "disable radio" : "enable radio");
 
+               priv->isr_stats.rfkill++;
+
                /* driver only loads ucode once setting the interface up.
                 * the driver allows loading the ucode even if the radio
                 * is killed. Hence update the killswitch state here. The
@@ -1160,7 +1039,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
                                set_bit(STATUS_RF_KILL_HW, &priv->status);
                        else
                                clear_bit(STATUS_RF_KILL_HW, &priv->status);
-                       queue_work(priv->workqueue, &priv->rf_kill);
+                       wiphy_rfkill_set_hw_state(priv->hw->wiphy, hw_rf_kill);
                }
 
                handled |= CSR_INT_BIT_RF_KILL;
@@ -1169,6 +1048,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
        /* Chip got too hot and stopped itself */
        if (inta & CSR_INT_BIT_CT_KILL) {
                IWL_ERR(priv, "Microcode CT kill error detected.\n");
+               priv->isr_stats.ctkill++;
                handled |= CSR_INT_BIT_CT_KILL;
        }
 
@@ -1176,6 +1056,8 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
        if (inta & CSR_INT_BIT_SW_ERR) {
                IWL_ERR(priv, "Microcode SW error detected. "
                        " Restarting 0x%X.\n", inta);
+               priv->isr_stats.sw++;
+               priv->isr_stats.sw_err = inta;
                iwl_irq_handle_error(priv);
                handled |= CSR_INT_BIT_SW_ERR;
        }
@@ -1191,6 +1073,8 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
                iwl_txq_update_write_ptr(priv, &priv->txq[4]);
                iwl_txq_update_write_ptr(priv, &priv->txq[5]);
 
+               priv->isr_stats.wakeup++;
+
                handled |= CSR_INT_BIT_WAKEUP;
        }
 
@@ -1199,23 +1083,27 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
         * notifications from uCode come through here*/
        if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) {
                iwl_rx_handle(priv);
+               priv->isr_stats.rx++;
                handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX);
        }
 
        if (inta & CSR_INT_BIT_FH_TX) {
                IWL_DEBUG_ISR(priv, "Tx interrupt\n");
+               priv->isr_stats.tx++;
                handled |= CSR_INT_BIT_FH_TX;
                /* FH finished to write, send event */
                priv->ucode_write_complete = 1;
                wake_up_interruptible(&priv->wait_command_queue);
        }
 
-       if (inta & ~handled)
+       if (inta & ~handled) {
                IWL_ERR(priv, "Unhandled INTA bits 0x%08x\n", inta & ~handled);
+               priv->isr_stats.unhandled++;
+       }
 
-       if (inta & ~CSR_INI_SET_MASK) {
+       if (inta & ~(priv->inta_mask)) {
                IWL_WARN(priv, "Disabled INTA bits 0x%08x were pending\n",
-                        inta & ~CSR_INI_SET_MASK);
+                        inta & ~priv->inta_mask);
                IWL_WARN(priv, "   with FH_INT = 0x%08x\n", inta_fh);
        }
 
@@ -1236,6 +1124,200 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
        spin_unlock_irqrestore(&priv->lock, flags);
 }
 
+/* tasklet for iwlagn interrupt */
+static void iwl_irq_tasklet(struct iwl_priv *priv)
+{
+       u32 inta = 0;
+       u32 handled = 0;
+       unsigned long flags;
+#ifdef CONFIG_IWLWIFI_DEBUG
+       u32 inta_mask;
+#endif
+
+       spin_lock_irqsave(&priv->lock, flags);
+
+       /* Ack/clear/reset pending uCode interrupts.
+        * Note:  Some bits in CSR_INT are "OR" of bits in CSR_FH_INT_STATUS,
+        */
+       iwl_write32(priv, CSR_INT, priv->inta);
+
+       inta = priv->inta;
+
+#ifdef CONFIG_IWLWIFI_DEBUG
+       if (priv->debug_level & IWL_DL_ISR) {
+               /* just for debug */
+               inta_mask = iwl_read32(priv, CSR_INT_MASK);
+               IWL_DEBUG_ISR(priv, "inta 0x%08x, enabled 0x%08x\n ",
+                               inta, inta_mask);
+       }
+#endif
+       /* saved interrupt in inta variable now we can reset priv->inta */
+       priv->inta = 0;
+
+       /* Now service all interrupt bits discovered above. */
+       if (inta & CSR_INT_BIT_HW_ERR) {
+               IWL_ERR(priv, "Microcode HW error detected.  Restarting.\n");
+
+               /* Tell the device to stop sending interrupts */
+               iwl_disable_interrupts(priv);
+
+               priv->isr_stats.hw++;
+               iwl_irq_handle_error(priv);
+
+               handled |= CSR_INT_BIT_HW_ERR;
+
+               spin_unlock_irqrestore(&priv->lock, flags);
+
+               return;
+       }
+
+#ifdef CONFIG_IWLWIFI_DEBUG
+       if (priv->debug_level & (IWL_DL_ISR)) {
+               /* NIC fires this, but we don't use it, redundant with WAKEUP */
+               if (inta & CSR_INT_BIT_SCD) {
+                       IWL_DEBUG_ISR(priv, "Scheduler finished to transmit "
+                                     "the frame/frames.\n");
+                       priv->isr_stats.sch++;
+               }
+
+               /* Alive notification via Rx interrupt will do the real work */
+               if (inta & CSR_INT_BIT_ALIVE) {
+                       IWL_DEBUG_ISR(priv, "Alive interrupt\n");
+                       priv->isr_stats.alive++;
+               }
+       }
+#endif
+       /* Safely ignore these bits for debug checks below */
+       inta &= ~(CSR_INT_BIT_SCD | CSR_INT_BIT_ALIVE);
+
+       /* HW RF KILL switch toggled */
+       if (inta & CSR_INT_BIT_RF_KILL) {
+               int hw_rf_kill = 0;
+               if (!(iwl_read32(priv, CSR_GP_CNTRL) &
+                               CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW))
+                       hw_rf_kill = 1;
+
+               IWL_DEBUG_RF_KILL(priv, "RF_KILL bit toggled to %s.\n",
+                               hw_rf_kill ? "disable radio" : "enable radio");
+
+               priv->isr_stats.rfkill++;
+
+               /* driver only loads ucode once setting the interface up.
+                * the driver allows loading the ucode even if the radio
+                * is killed. Hence update the killswitch state here. The
+                * rfkill handler will care about restarting if needed.
+                */
+               if (!test_bit(STATUS_ALIVE, &priv->status)) {
+                       if (hw_rf_kill)
+                               set_bit(STATUS_RF_KILL_HW, &priv->status);
+                       else
+                               clear_bit(STATUS_RF_KILL_HW, &priv->status);
+                       wiphy_rfkill_set_hw_state(priv->hw->wiphy, hw_rf_kill);
+               }
+
+               handled |= CSR_INT_BIT_RF_KILL;
+       }
+
+       /* Chip got too hot and stopped itself */
+       if (inta & CSR_INT_BIT_CT_KILL) {
+               IWL_ERR(priv, "Microcode CT kill error detected.\n");
+               priv->isr_stats.ctkill++;
+               handled |= CSR_INT_BIT_CT_KILL;
+       }
+
+       /* Error detected by uCode */
+       if (inta & CSR_INT_BIT_SW_ERR) {
+               IWL_ERR(priv, "Microcode SW error detected. "
+                       " Restarting 0x%X.\n", inta);
+               priv->isr_stats.sw++;
+               priv->isr_stats.sw_err = inta;
+               iwl_irq_handle_error(priv);
+               handled |= CSR_INT_BIT_SW_ERR;
+       }
+
+       /* uCode wakes up after power-down sleep */
+       if (inta & CSR_INT_BIT_WAKEUP) {
+               IWL_DEBUG_ISR(priv, "Wakeup interrupt\n");
+               iwl_rx_queue_update_write_ptr(priv, &priv->rxq);
+               iwl_txq_update_write_ptr(priv, &priv->txq[0]);
+               iwl_txq_update_write_ptr(priv, &priv->txq[1]);
+               iwl_txq_update_write_ptr(priv, &priv->txq[2]);
+               iwl_txq_update_write_ptr(priv, &priv->txq[3]);
+               iwl_txq_update_write_ptr(priv, &priv->txq[4]);
+               iwl_txq_update_write_ptr(priv, &priv->txq[5]);
+
+               priv->isr_stats.wakeup++;
+
+               handled |= CSR_INT_BIT_WAKEUP;
+       }
+
+       /* All uCode command responses, including Tx command responses,
+        * Rx "responses" (frame-received notification), and other
+        * notifications from uCode come through here*/
+       if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX |
+                       CSR_INT_BIT_RX_PERIODIC)) {
+               IWL_DEBUG_ISR(priv, "Rx interrupt\n");
+               if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) {
+                       handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX);
+                       iwl_write32(priv, CSR_FH_INT_STATUS,
+                                       CSR49_FH_INT_RX_MASK);
+               }
+               if (inta & CSR_INT_BIT_RX_PERIODIC) {
+                       handled |= CSR_INT_BIT_RX_PERIODIC;
+                       iwl_write32(priv, CSR_INT, CSR_INT_BIT_RX_PERIODIC);
+               }
+               /* Sending RX interrupt require many steps to be done in the
+                * the device:
+                * 1- write interrupt to current index in ICT table.
+                * 2- dma RX frame.
+                * 3- update RX shared data to indicate last write index.
+                * 4- send interrupt.
+                * This could lead to RX race, driver could receive RX interrupt
+                * but the shared data changes does not reflect this.
+                * this could lead to RX race, RX periodic will solve this race
+                */
+               iwl_write32(priv, CSR_INT_PERIODIC_REG,
+                           CSR_INT_PERIODIC_DIS);
+               iwl_rx_handle(priv);
+               /* Only set RX periodic if real RX is received. */
+               if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX))
+                       iwl_write32(priv, CSR_INT_PERIODIC_REG,
+                                   CSR_INT_PERIODIC_ENA);
+
+               priv->isr_stats.rx++;
+       }
+
+       if (inta & CSR_INT_BIT_FH_TX) {
+               iwl_write32(priv, CSR_FH_INT_STATUS, CSR49_FH_INT_TX_MASK);
+               IWL_DEBUG_ISR(priv, "Tx interrupt\n");
+               priv->isr_stats.tx++;
+               handled |= CSR_INT_BIT_FH_TX;
+               /* FH finished to write, send event */
+               priv->ucode_write_complete = 1;
+               wake_up_interruptible(&priv->wait_command_queue);
+       }
+
+       if (inta & ~handled) {
+               IWL_ERR(priv, "Unhandled INTA bits 0x%08x\n", inta & ~handled);
+               priv->isr_stats.unhandled++;
+       }
+
+       if (inta & ~(priv->inta_mask)) {
+               IWL_WARN(priv, "Disabled INTA bits 0x%08x were pending\n",
+                        inta & ~priv->inta_mask);
+       }
+
+
+       /* Re-enable all interrupts */
+       /* only Re-enable if diabled by irq */
+       if (test_bit(STATUS_INT_ENABLED, &priv->status))
+               iwl_enable_interrupts(priv);
+
+       spin_unlock_irqrestore(&priv->lock, flags);
+
+}
+
+
 /******************************************************************************
  *
  * uCode download functions
@@ -1501,10 +1583,6 @@ static int iwl_read_ucode(struct iwl_priv *priv)
        return ret;
 }
 
-/* temporary */
-static int iwl_mac_beacon_update(struct ieee80211_hw *hw,
-                                struct sk_buff *skb);
-
 /**
  * iwl_alive_start - called after REPLY_ALIVE notification received
  *                   from protocol/runtime uCode (initialization uCode's
@@ -1561,7 +1639,10 @@ static void iwl_alive_start(struct iwl_priv *priv)
        } else {
                /* Initialize our rx_config data */
                iwl_connection_init_rx_config(priv, priv->iw_mode);
-               iwl_set_rxon_chain(priv);
+
+               if (priv->cfg->ops->hcmd->set_rxon_chain)
+                       priv->cfg->ops->hcmd->set_rxon_chain(priv);
+
                memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN);
        }
 
@@ -1571,7 +1652,7 @@ static void iwl_alive_start(struct iwl_priv *priv)
        iwl_reset_run_time_calib(priv);
 
        /* Configure the adapter for unassociated operation */
-       iwl_commit_rxon(priv);
+       iwlcore_commit_rxon(priv);
 
        /* At this point, the NIC is initialized and operational */
        iwl_rf_kill_ct_config(priv);
@@ -1582,9 +1663,6 @@ static void iwl_alive_start(struct iwl_priv *priv)
        set_bit(STATUS_READY, &priv->status);
        wake_up_interruptible(&priv->wait_command_queue);
 
-       if (priv->error_recovering)
-               iwl_error_recovery(priv);
-
        iwl_power_update_mode(priv, 1);
 
        /* reassociate for ADHOC mode */
@@ -1642,36 +1720,30 @@ static void __iwl_down(struct iwl_priv *priv)
                ieee80211_stop_queues(priv->hw);
 
        /* If we have not previously called iwl_init() then
-        * clear all bits but the RF Kill and SUSPEND bits and return */
+        * clear all bits but the RF Kill bit and return */
        if (!iwl_is_init(priv)) {
                priv->status = test_bit(STATUS_RF_KILL_HW, &priv->status) <<
                                        STATUS_RF_KILL_HW |
-                              test_bit(STATUS_RF_KILL_SW, &priv->status) <<
-                                       STATUS_RF_KILL_SW |
                               test_bit(STATUS_GEO_CONFIGURED, &priv->status) <<
                                        STATUS_GEO_CONFIGURED |
-                              test_bit(STATUS_IN_SUSPEND, &priv->status) <<
-                                       STATUS_IN_SUSPEND |
                               test_bit(STATUS_EXIT_PENDING, &priv->status) <<
                                        STATUS_EXIT_PENDING;
                goto exit;
        }
 
-       /* ...otherwise clear out all the status bits but the RF Kill and
-        * SUSPEND bits and continue taking the NIC down. */
+       /* ...otherwise clear out all the status bits but the RF Kill
+        * bit and continue taking the NIC down. */
        priv->status &= test_bit(STATUS_RF_KILL_HW, &priv->status) <<
                                STATUS_RF_KILL_HW |
-                       test_bit(STATUS_RF_KILL_SW, &priv->status) <<
-                               STATUS_RF_KILL_SW |
                        test_bit(STATUS_GEO_CONFIGURED, &priv->status) <<
                                STATUS_GEO_CONFIGURED |
-                       test_bit(STATUS_IN_SUSPEND, &priv->status) <<
-                               STATUS_IN_SUSPEND |
                        test_bit(STATUS_FW_ERROR, &priv->status) <<
                                STATUS_FW_ERROR |
                       test_bit(STATUS_EXIT_PENDING, &priv->status) <<
                                STATUS_EXIT_PENDING;
 
+       /* device going down, Stop using ICT table */
+       iwl_disable_ict(priv);
        spin_lock_irqsave(&priv->lock, flags);
        iwl_clear_bit(priv, CSR_GP_CNTRL,
                         CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
@@ -1680,18 +1752,13 @@ static void __iwl_down(struct iwl_priv *priv)
        iwl_txq_ctx_stop(priv);
        iwl_rxq_stop(priv);
 
-       spin_lock_irqsave(&priv->lock, flags);
-       if (!iwl_grab_nic_access(priv)) {
-               iwl_write_prph(priv, APMG_CLK_DIS_REG,
-                                        APMG_CLK_VAL_DMA_CLK_RQT);
-               iwl_release_nic_access(priv);
-       }
-       spin_unlock_irqrestore(&priv->lock, flags);
+       iwl_write_prph(priv, APMG_CLK_DIS_REG,
+                               APMG_CLK_VAL_DMA_CLK_RQT);
 
        udelay(5);
 
        /* FIXME: apm_ops.suspend(priv) */
-       if (exit_pending || test_bit(STATUS_IN_SUSPEND, &priv->status))
+       if (exit_pending)
                priv->cfg->ops->lib->apm_ops.stop(priv);
        else
                priv->cfg->ops->lib->apm_ops.reset(priv);
@@ -1715,6 +1782,49 @@ static void iwl_down(struct iwl_priv *priv)
        iwl_cancel_deferred_work(priv);
 }
 
+#define HW_READY_TIMEOUT (50)
+
+static int iwl_set_hw_ready(struct iwl_priv *priv)
+{
+       int ret = 0;
+
+       iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
+               CSR_HW_IF_CONFIG_REG_BIT_NIC_READY);
+
+       /* See if we got it */
+       ret = iwl_poll_bit(priv, CSR_HW_IF_CONFIG_REG,
+                               CSR_HW_IF_CONFIG_REG_BIT_NIC_READY,
+                               CSR_HW_IF_CONFIG_REG_BIT_NIC_READY,
+                               HW_READY_TIMEOUT);
+       if (ret != -ETIMEDOUT)
+               priv->hw_ready = true;
+       else
+               priv->hw_ready = false;
+
+       IWL_DEBUG_INFO(priv, "hardware %s\n",
+                     (priv->hw_ready == 1) ? "ready" : "not ready");
+       return ret;
+}
+
+static int iwl_prepare_card_hw(struct iwl_priv *priv)
+{
+       int ret = 0;
+
+       IWL_DEBUG_INFO(priv, "iwl_prepare_card_hw enter \n");
+
+       iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
+                       CSR_HW_IF_CONFIG_REG_PREPARE);
+
+       ret = iwl_poll_bit(priv, CSR_HW_IF_CONFIG_REG,
+                       ~CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE,
+                       CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE, 150000);
+
+       if (ret != -ETIMEDOUT)
+               iwl_set_hw_ready(priv);
+
+       return ret;
+}
+
 #define MAX_HW_RESTARTS 5
 
 static int __iwl_up(struct iwl_priv *priv)
@@ -1732,6 +1842,13 @@ static int __iwl_up(struct iwl_priv *priv)
                return -EIO;
        }
 
+       iwl_prepare_card_hw(priv);
+
+       if (!priv->hw_ready) {
+               IWL_WARN(priv, "Exit HW not ready\n");
+               return -EIO;
+       }
+
        /* If platform's RF_KILL switch is NOT set to KILL */
        if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
                clear_bit(STATUS_RF_KILL_HW, &priv->status);
@@ -1739,9 +1856,10 @@ static int __iwl_up(struct iwl_priv *priv)
                set_bit(STATUS_RF_KILL_HW, &priv->status);
 
        if (iwl_is_rfkill(priv)) {
+               wiphy_rfkill_set_hw_state(priv->hw->wiphy, true);
+
                iwl_enable_interrupts(priv);
-               IWL_WARN(priv, "Radio disabled by %s RF Kill switch\n",
-                   test_bit(STATUS_RF_KILL_HW, &priv->status) ? "HW" : "SW");
+               IWL_WARN(priv, "Radio disabled by HW RF Kill switch\n");
                return 0;
        }
 
@@ -1787,9 +1905,6 @@ static int __iwl_up(struct iwl_priv *priv)
                        continue;
                }
 
-               /* Clear out the uCode error bit if it is set */
-               clear_bit(STATUS_FW_ERROR, &priv->status);
-
                /* start card; "initialize" will load runtime ucode */
                iwl_nic_start(priv);
 
@@ -1836,6 +1951,9 @@ static void iwl_bg_alive_start(struct work_struct *data)
        if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
 
+       /* enable dram interrupt */
+       iwl_reset_ict(priv);
+
        mutex_lock(&priv->mutex);
        iwl_alive_start(priv);
        mutex_unlock(&priv->mutex);
@@ -1874,7 +1992,6 @@ static void iwl_bg_up(struct work_struct *data)
        mutex_lock(&priv->mutex);
        __iwl_up(priv);
        mutex_unlock(&priv->mutex);
-       iwl_rfkill_set_hw_state(priv);
 }
 
 static void iwl_bg_restart(struct work_struct *data)
@@ -1884,8 +2001,17 @@ static void iwl_bg_restart(struct work_struct *data)
        if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
 
-       iwl_down(priv);
-       queue_work(priv->workqueue, &priv->up);
+       if (test_and_clear_bit(STATUS_FW_ERROR, &priv->status)) {
+               mutex_lock(&priv->mutex);
+               priv->vif = NULL;
+               priv->is_open = 0;
+               mutex_unlock(&priv->mutex);
+               iwl_down(priv);
+               ieee80211_restart_hw(priv->hw);
+       } else {
+               iwl_down(priv);
+               queue_work(priv->workqueue, &priv->up);
+       }
 }
 
 static void iwl_bg_rx_replenish(struct work_struct *data)
@@ -1903,7 +2029,7 @@ static void iwl_bg_rx_replenish(struct work_struct *data)
 
 #define IWL_DELAY_NEXT_SCAN (HZ*2)
 
-static void iwl_post_associate(struct iwl_priv *priv)
+void iwl_post_associate(struct iwl_priv *priv)
 {
        struct ieee80211_conf *conf = NULL;
        int ret = 0;
@@ -1925,13 +2051,12 @@ static void iwl_post_associate(struct iwl_priv *priv)
        if (!priv->vif || !priv->is_open)
                return;
 
-       iwl_power_cancel_timeout(priv);
        iwl_scan_cancel_timeout(priv, 200);
 
        conf = ieee80211_get_hw_conf(priv->hw);
 
        priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
-       iwl_commit_rxon(priv);
+       iwlcore_commit_rxon(priv);
 
        iwl_setup_rxon_timing(priv);
        ret = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING,
@@ -1944,7 +2069,9 @@ static void iwl_post_associate(struct iwl_priv *priv)
 
        iwl_set_rxon_ht(priv, &priv->current_ht_config);
 
-       iwl_set_rxon_chain(priv);
+       if (priv->cfg->ops->hcmd->set_rxon_chain)
+               priv->cfg->ops->hcmd->set_rxon_chain(priv);
+
        priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id);
 
        IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n",
@@ -1966,7 +2093,7 @@ static void iwl_post_associate(struct iwl_priv *priv)
 
        }
 
-       iwl_commit_rxon(priv);
+       iwlcore_commit_rxon(priv);
 
        switch (priv->iw_mode) {
        case NL80211_IFTYPE_STATION:
@@ -1999,7 +2126,7 @@ static void iwl_post_associate(struct iwl_priv *priv)
         * If chain noise has already been run, then we need to enable
         * power management here */
        if (priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE)
-               iwl_power_enable_management(priv);
+               iwl_power_update_mode(priv, 0);
 
        /* Enable Rx differential gain and sensitivity calibrations */
        iwl_chain_noise_reset(priv);
@@ -2042,8 +2169,6 @@ static int iwl_mac_start(struct ieee80211_hw *hw)
 
        mutex_unlock(&priv->mutex);
 
-       iwl_rfkill_set_hw_state(priv);
-
        if (ret)
                return ret;
 
@@ -2052,9 +2177,6 @@ static int iwl_mac_start(struct ieee80211_hw *hw)
 
        IWL_DEBUG_INFO(priv, "Start UP work done.\n");
 
-       if (test_bit(STATUS_IN_SUSPEND, &priv->status))
-               return 0;
-
        /* Wait for START_ALIVE from Run Time ucode. Otherwise callbacks from
         * mac80211 will not be run successfully. */
        ret = wait_event_interruptible_timeout(priv->wait_command_queue,
@@ -2080,10 +2202,8 @@ static void iwl_mac_stop(struct ieee80211_hw *hw)
 
        IWL_DEBUG_MAC80211(priv, "enter\n");
 
-       if (!priv->is_open) {
-               IWL_DEBUG_MAC80211(priv, "leave - skip\n");
+       if (!priv->is_open)
                return;
-       }
 
        priv->is_open = 0;
 
@@ -2123,175 +2243,7 @@ static int iwl_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
        return NETDEV_TX_OK;
 }
 
-static int iwl_mac_add_interface(struct ieee80211_hw *hw,
-                                struct ieee80211_if_init_conf *conf)
-{
-       struct iwl_priv *priv = hw->priv;
-       unsigned long flags;
-
-       IWL_DEBUG_MAC80211(priv, "enter: type %d\n", conf->type);
-
-       if (priv->vif) {
-               IWL_DEBUG_MAC80211(priv, "leave - vif != NULL\n");
-               return -EOPNOTSUPP;
-       }
-
-       spin_lock_irqsave(&priv->lock, flags);
-       priv->vif = conf->vif;
-       priv->iw_mode = conf->type;
-
-       spin_unlock_irqrestore(&priv->lock, flags);
-
-       mutex_lock(&priv->mutex);
-
-       if (conf->mac_addr) {
-               IWL_DEBUG_MAC80211(priv, "Set %pM\n", conf->mac_addr);
-               memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN);
-       }
-
-       if (iwl_set_mode(priv, conf->type) == -EAGAIN)
-               /* we are not ready, will run again when ready */
-               set_bit(STATUS_MODE_PENDING, &priv->status);
-
-       mutex_unlock(&priv->mutex);
-
-       IWL_DEBUG_MAC80211(priv, "leave\n");
-       return 0;
-}
-
-/**
- * iwl_mac_config - mac80211 config callback
- *
- * We ignore conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME since it seems to
- * be set inappropriately and the driver currently sets the hardware up to
- * use it whenever needed.
- */
-static int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
-{
-       struct iwl_priv *priv = hw->priv;
-       const struct iwl_channel_info *ch_info;
-       struct ieee80211_conf *conf = &hw->conf;
-       unsigned long flags = 0;
-       int ret = 0;
-       u16 ch;
-       int scan_active = 0;
-
-       mutex_lock(&priv->mutex);
-       IWL_DEBUG_MAC80211(priv, "enter to channel %d changed 0x%X\n",
-                                       conf->channel->hw_value, changed);
-
-       if (unlikely(!priv->cfg->mod_params->disable_hw_scan &&
-                       test_bit(STATUS_SCANNING, &priv->status))) {
-               scan_active = 1;
-               IWL_DEBUG_MAC80211(priv, "leave - scanning\n");
-       }
-
-
-       /* during scanning mac80211 will delay channel setting until
-        * scan finish with changed = 0
-        */
-       if (!changed || (changed & IEEE80211_CONF_CHANGE_CHANNEL)) {
-               if (scan_active)
-                       goto set_ch_out;
-
-               ch = ieee80211_frequency_to_channel(conf->channel->center_freq);
-               ch_info = iwl_get_channel_info(priv, conf->channel->band, ch);
-               if (!is_channel_valid(ch_info)) {
-                       IWL_DEBUG_MAC80211(priv, "leave - invalid channel\n");
-                       ret = -EINVAL;
-                       goto set_ch_out;
-               }
-
-               if (priv->iw_mode == NL80211_IFTYPE_ADHOC &&
-                       !is_channel_ibss(ch_info)) {
-                       IWL_ERR(priv, "channel %d in band %d not "
-                               "IBSS channel\n",
-                               conf->channel->hw_value, conf->channel->band);
-                       ret = -EINVAL;
-                       goto set_ch_out;
-               }
-
-               priv->current_ht_config.is_ht = conf_is_ht(conf);
-
-               spin_lock_irqsave(&priv->lock, flags);
-
-
-               /* if we are switching from ht to 2.4 clear flags
-                * from any ht related info since 2.4 does not
-                * support ht */
-               if ((le16_to_cpu(priv->staging_rxon.channel) != ch))
-                       priv->staging_rxon.flags = 0;
-
-               iwl_set_rxon_channel(priv, conf->channel);
-
-               iwl_set_flags_for_band(priv, conf->channel->band);
-               spin_unlock_irqrestore(&priv->lock, flags);
- set_ch_out:
-               /* The list of supported rates and rate mask can be different
-                * for each band; since the band may have changed, reset
-                * the rate mask to what mac80211 lists */
-               iwl_set_rate(priv);
-       }
-
-       if (changed & IEEE80211_CONF_CHANGE_PS) {
-               if (conf->flags & IEEE80211_CONF_PS)
-                       ret = iwl_power_set_user_mode(priv, IWL_POWER_INDEX_3);
-               else
-                       ret = iwl_power_set_user_mode(priv, IWL_POWER_MODE_CAM);
-               if (ret)
-                       IWL_DEBUG_MAC80211(priv, "Error setting power level\n");
-
-       }
-
-       if (changed & IEEE80211_CONF_CHANGE_POWER) {
-               IWL_DEBUG_MAC80211(priv, "TX Power old=%d new=%d\n",
-                       priv->tx_power_user_lmt, conf->power_level);
-
-               iwl_set_tx_power(priv, conf->power_level, false);
-       }
-
-       /* call to ensure that 4965 rx_chain is set properly in monitor mode */
-       iwl_set_rxon_chain(priv);
-
-       if (changed & IEEE80211_CONF_CHANGE_RADIO_ENABLED) {
-               if (conf->radio_enabled &&
-                       iwl_radio_kill_sw_enable_radio(priv)) {
-                       IWL_DEBUG_MAC80211(priv, "leave - RF-KILL - "
-                                               "waiting for uCode\n");
-                       goto out;
-               }
-
-               if (!conf->radio_enabled)
-                       iwl_radio_kill_sw_disable_radio(priv);
-       }
-
-       if (!conf->radio_enabled) {
-               IWL_DEBUG_MAC80211(priv, "leave - radio disabled\n");
-               goto out;
-       }
-
-       if (!iwl_is_ready(priv)) {
-               IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
-               goto out;
-       }
-
-       if (scan_active)
-               goto out;
-
-       if (memcmp(&priv->active_rxon,
-                  &priv->staging_rxon, sizeof(priv->staging_rxon)))
-               iwl_commit_rxon(priv);
-       else
-               IWL_DEBUG_INFO(priv, "No re-sending same RXON configuration.\n");
-
-
-out:
-       IWL_DEBUG_MAC80211(priv, "leave\n");
-       mutex_unlock(&priv->mutex);
-       return ret;
-}
-
-static void iwl_config_ap(struct iwl_priv *priv)
+void iwl_config_ap(struct iwl_priv *priv)
 {
        int ret = 0;
        unsigned long flags;
@@ -2304,7 +2256,7 @@ static void iwl_config_ap(struct iwl_priv *priv)
 
                /* RXON - unassoc (to set timing command) */
                priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
-               iwl_commit_rxon(priv);
+               iwlcore_commit_rxon(priv);
 
                /* RXON Timing */
                iwl_setup_rxon_timing(priv);
@@ -2314,7 +2266,8 @@ static void iwl_config_ap(struct iwl_priv *priv)
                        IWL_WARN(priv, "REPLY_RXON_TIMING failed - "
                                        "Attempting to continue.\n");
 
-               iwl_set_rxon_chain(priv);
+               if (priv->cfg->ops->hcmd->set_rxon_chain)
+                       priv->cfg->ops->hcmd->set_rxon_chain(priv);
 
                /* FIXME: what should be the assoc_id for AP? */
                priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id);
@@ -2340,7 +2293,7 @@ static void iwl_config_ap(struct iwl_priv *priv)
                }
                /* restore RXON assoc */
                priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
-               iwl_commit_rxon(priv);
+               iwlcore_commit_rxon(priv);
                spin_lock_irqsave(&priv->lock, flags);
                iwl_activate_qos(priv, 1);
                spin_unlock_irqrestore(&priv->lock, flags);
@@ -2353,194 +2306,6 @@ static void iwl_config_ap(struct iwl_priv *priv)
         * clear sta table, add BCAST sta... */
 }
 
-
-static int iwl_mac_config_interface(struct ieee80211_hw *hw,
-                                       struct ieee80211_vif *vif,
-                                   struct ieee80211_if_conf *conf)
-{
-       struct iwl_priv *priv = hw->priv;
-       int rc;
-
-       if (conf == NULL)
-               return -EIO;
-
-       if (priv->vif != vif) {
-               IWL_DEBUG_MAC80211(priv, "leave - priv->vif != vif\n");
-               return 0;
-       }
-
-       if (priv->iw_mode == NL80211_IFTYPE_ADHOC &&
-           conf->changed & IEEE80211_IFCC_BEACON) {
-               struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
-               if (!beacon)
-                       return -ENOMEM;
-               mutex_lock(&priv->mutex);
-               rc = iwl_mac_beacon_update(hw, beacon);
-               mutex_unlock(&priv->mutex);
-               if (rc)
-                       return rc;
-       }
-
-       if (!iwl_is_alive(priv))
-               return -EAGAIN;
-
-       mutex_lock(&priv->mutex);
-
-       if (conf->bssid)
-               IWL_DEBUG_MAC80211(priv, "bssid: %pM\n", conf->bssid);
-
-/*
- * very dubious code was here; the probe filtering flag is never set:
- *
-       if (unlikely(test_bit(STATUS_SCANNING, &priv->status)) &&
-           !(priv->hw->flags & IEEE80211_HW_NO_PROBE_FILTERING)) {
- */
-
-       if (priv->iw_mode == NL80211_IFTYPE_AP) {
-               if (!conf->bssid) {
-                       conf->bssid = priv->mac_addr;
-                       memcpy(priv->bssid, priv->mac_addr, ETH_ALEN);
-                       IWL_DEBUG_MAC80211(priv, "bssid was set to: %pM\n",
-                                          conf->bssid);
-               }
-               if (priv->ibss_beacon)
-                       dev_kfree_skb(priv->ibss_beacon);
-
-               priv->ibss_beacon = ieee80211_beacon_get(hw, vif);
-       }
-
-       if (iwl_is_rfkill(priv))
-               goto done;
-
-       if (conf->bssid && !is_zero_ether_addr(conf->bssid) &&
-           !is_multicast_ether_addr(conf->bssid)) {
-               /* If there is currently a HW scan going on in the background
-                * then we need to cancel it else the RXON below will fail. */
-               if (iwl_scan_cancel_timeout(priv, 100)) {
-                       IWL_WARN(priv, "Aborted scan still in progress "
-                                   "after 100ms\n");
-                       IWL_DEBUG_MAC80211(priv, "leaving - scan abort failed.\n");
-                       mutex_unlock(&priv->mutex);
-                       return -EAGAIN;
-               }
-               memcpy(priv->staging_rxon.bssid_addr, conf->bssid, ETH_ALEN);
-
-               /* TODO: Audit driver for usage of these members and see
-                * if mac80211 deprecates them (priv->bssid looks like it
-                * shouldn't be there, but I haven't scanned the IBSS code
-                * to verify) - jpk */
-               memcpy(priv->bssid, conf->bssid, ETH_ALEN);
-
-               if (priv->iw_mode == NL80211_IFTYPE_AP)
-                       iwl_config_ap(priv);
-               else {
-                       rc = iwl_commit_rxon(priv);
-                       if ((priv->iw_mode == NL80211_IFTYPE_STATION) && rc)
-                               iwl_rxon_add_station(
-                                       priv, priv->active_rxon.bssid_addr, 1);
-               }
-
-       } else {
-               iwl_scan_cancel_timeout(priv, 100);
-               priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
-               iwl_commit_rxon(priv);
-       }
-
- done:
-       IWL_DEBUG_MAC80211(priv, "leave\n");
-       mutex_unlock(&priv->mutex);
-
-       return 0;
-}
-
-static void iwl_mac_remove_interface(struct ieee80211_hw *hw,
-                                    struct ieee80211_if_init_conf *conf)
-{
-       struct iwl_priv *priv = hw->priv;
-
-       IWL_DEBUG_MAC80211(priv, "enter\n");
-
-       mutex_lock(&priv->mutex);
-
-       if (iwl_is_ready_rf(priv)) {
-               iwl_scan_cancel_timeout(priv, 100);
-               priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
-               iwl_commit_rxon(priv);
-       }
-       if (priv->vif == conf->vif) {
-               priv->vif = NULL;
-               memset(priv->bssid, 0, ETH_ALEN);
-       }
-       mutex_unlock(&priv->mutex);
-
-       IWL_DEBUG_MAC80211(priv, "leave\n");
-
-}
-
-#define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6)
-static void iwl_bss_info_changed(struct ieee80211_hw *hw,
-                                    struct ieee80211_vif *vif,
-                                    struct ieee80211_bss_conf *bss_conf,
-                                    u32 changes)
-{
-       struct iwl_priv *priv = hw->priv;
-
-       IWL_DEBUG_MAC80211(priv, "changes = 0x%X\n", changes);
-
-       if (changes & BSS_CHANGED_ERP_PREAMBLE) {
-               IWL_DEBUG_MAC80211(priv, "ERP_PREAMBLE %d\n",
-                                  bss_conf->use_short_preamble);
-               if (bss_conf->use_short_preamble)
-                       priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
-               else
-                       priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
-       }
-
-       if (changes & BSS_CHANGED_ERP_CTS_PROT) {
-               IWL_DEBUG_MAC80211(priv, "ERP_CTS %d\n", bss_conf->use_cts_prot);
-               if (bss_conf->use_cts_prot && (priv->band != IEEE80211_BAND_5GHZ))
-                       priv->staging_rxon.flags |= RXON_FLG_TGG_PROTECT_MSK;
-               else
-                       priv->staging_rxon.flags &= ~RXON_FLG_TGG_PROTECT_MSK;
-       }
-
-       if (changes & BSS_CHANGED_HT) {
-               iwl_ht_conf(priv, bss_conf);
-               iwl_set_rxon_chain(priv);
-       }
-
-       if (changes & BSS_CHANGED_ASSOC) {
-               IWL_DEBUG_MAC80211(priv, "ASSOC %d\n", bss_conf->assoc);
-               /* This should never happen as this function should
-                * never be called from interrupt context. */
-               if (WARN_ON_ONCE(in_interrupt()))
-                       return;
-               if (bss_conf->assoc) {
-                       priv->assoc_id = bss_conf->aid;
-                       priv->beacon_int = bss_conf->beacon_int;
-                       priv->power_data.dtim_period = bss_conf->dtim_period;
-                       priv->timestamp = bss_conf->timestamp;
-                       priv->assoc_capability = bss_conf->assoc_capability;
-
-                       /* we have just associated, don't start scan too early
-                        * leave time for EAPOL exchange to complete
-                        */
-                       priv->next_scan_jiffies = jiffies +
-                                       IWL_DELAY_NEXT_SCAN_AFTER_ASSOC;
-                       mutex_lock(&priv->mutex);
-                       iwl_post_associate(priv);
-                       mutex_unlock(&priv->mutex);
-               } else {
-                       priv->assoc_id = 0;
-                       IWL_DEBUG_MAC80211(priv, "DISASSOC %d\n", bss_conf->assoc);
-               }
-       } else if (changes && iwl_is_associated(priv) && priv->assoc_id) {
-                       IWL_DEBUG_MAC80211(priv, "Associated Changes %d\n", changes);
-                       iwl_send_rxon_assoc(priv);
-       }
-
-}
-
 static void iwl_mac_update_tkip_key(struct ieee80211_hw *hw,
                        struct ieee80211_key_conf *keyconf, const u8 *addr,
                        u32 iv32, u16 *phase1key)
@@ -2623,49 +2388,6 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
        return ret;
 }
 
-static int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
-                          const struct ieee80211_tx_queue_params *params)
-{
-       struct iwl_priv *priv = hw->priv;
-       unsigned long flags;
-       int q;
-
-       IWL_DEBUG_MAC80211(priv, "enter\n");
-
-       if (!iwl_is_ready_rf(priv)) {
-               IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
-               return -EIO;
-       }
-
-       if (queue >= AC_NUM) {
-               IWL_DEBUG_MAC80211(priv, "leave - queue >= AC_NUM %d\n", queue);
-               return 0;
-       }
-
-       q = AC_NUM - 1 - queue;
-
-       spin_lock_irqsave(&priv->lock, flags);
-
-       priv->qos_data.def_qos_parm.ac[q].cw_min = cpu_to_le16(params->cw_min);
-       priv->qos_data.def_qos_parm.ac[q].cw_max = cpu_to_le16(params->cw_max);
-       priv->qos_data.def_qos_parm.ac[q].aifsn = params->aifs;
-       priv->qos_data.def_qos_parm.ac[q].edca_txop =
-                       cpu_to_le16((params->txop * 32));
-
-       priv->qos_data.def_qos_parm.ac[q].reserved1 = 0;
-       priv->qos_data.qos_active = 1;
-
-       if (priv->iw_mode == NL80211_IFTYPE_AP)
-               iwl_activate_qos(priv, 1);
-       else if (priv->assoc_id && iwl_is_associated(priv))
-               iwl_activate_qos(priv, 0);
-
-       spin_unlock_irqrestore(&priv->lock, flags);
-
-       IWL_DEBUG_MAC80211(priv, "leave\n");
-       return 0;
-}
-
 static int iwl_mac_ampdu_action(struct ieee80211_hw *hw,
                             enum ieee80211_ampdu_mlme_action action,
                             struct ieee80211_sta *sta, u16 tid, u16 *ssn)
@@ -2708,41 +2430,6 @@ static int iwl_mac_ampdu_action(struct ieee80211_hw *hw,
        return 0;
 }
 
-static int iwl_mac_get_tx_stats(struct ieee80211_hw *hw,
-                               struct ieee80211_tx_queue_stats *stats)
-{
-       struct iwl_priv *priv = hw->priv;
-       int i, avail;
-       struct iwl_tx_queue *txq;
-       struct iwl_queue *q;
-       unsigned long flags;
-
-       IWL_DEBUG_MAC80211(priv, "enter\n");
-
-       if (!iwl_is_ready_rf(priv)) {
-               IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
-               return -EIO;
-       }
-
-       spin_lock_irqsave(&priv->lock, flags);
-
-       for (i = 0; i < AC_NUM; i++) {
-               txq = &priv->txq[i];
-               q = &txq->q;
-               avail = iwl_queue_space(q);
-
-               stats[i].len = q->n_window - avail;
-               stats[i].limit = q->n_window - q->high_mark;
-               stats[i].count = q->n_window;
-
-       }
-       spin_unlock_irqrestore(&priv->lock, flags);
-
-       IWL_DEBUG_MAC80211(priv, "leave\n");
-
-       return 0;
-}
-
 static int iwl_mac_get_stats(struct ieee80211_hw *hw,
                             struct ieee80211_low_level_stats *stats)
 {
@@ -2755,120 +2442,6 @@ static int iwl_mac_get_stats(struct ieee80211_hw *hw,
        return 0;
 }
 
-static void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
-{
-       struct iwl_priv *priv = hw->priv;
-       unsigned long flags;
-
-       mutex_lock(&priv->mutex);
-       IWL_DEBUG_MAC80211(priv, "enter\n");
-
-       spin_lock_irqsave(&priv->lock, flags);
-       memset(&priv->current_ht_config, 0, sizeof(struct iwl_ht_info));
-       spin_unlock_irqrestore(&priv->lock, flags);
-
-       iwl_reset_qos(priv);
-
-       spin_lock_irqsave(&priv->lock, flags);
-       priv->assoc_id = 0;
-       priv->assoc_capability = 0;
-       priv->assoc_station_added = 0;
-
-       /* new association get rid of ibss beacon skb */
-       if (priv->ibss_beacon)
-               dev_kfree_skb(priv->ibss_beacon);
-
-       priv->ibss_beacon = NULL;
-
-       priv->beacon_int = priv->hw->conf.beacon_int;
-       priv->timestamp = 0;
-       if ((priv->iw_mode == NL80211_IFTYPE_STATION))
-               priv->beacon_int = 0;
-
-       spin_unlock_irqrestore(&priv->lock, flags);
-
-       if (!iwl_is_ready_rf(priv)) {
-               IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
-               mutex_unlock(&priv->mutex);
-               return;
-       }
-
-       /* we are restarting association process
-        * clear RXON_FILTER_ASSOC_MSK bit
-        */
-       if (priv->iw_mode != NL80211_IFTYPE_AP) {
-               iwl_scan_cancel_timeout(priv, 100);
-               priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
-               iwl_commit_rxon(priv);
-       }
-
-       iwl_power_update_mode(priv, 0);
-
-       /* Per mac80211.h: This is only used in IBSS mode... */
-       if (priv->iw_mode != NL80211_IFTYPE_ADHOC) {
-
-               /* switch to CAM during association period.
-                * the ucode will block any association/authentication
-                * frome during assiciation period if it can not hear
-                * the AP because of PM. the timer enable PM back is
-                * association do not complete
-                */
-               if (priv->hw->conf.channel->flags & (IEEE80211_CHAN_PASSIVE_SCAN |
-                                                    IEEE80211_CHAN_RADAR))
-                               iwl_power_disable_management(priv, 3000);
-
-               IWL_DEBUG_MAC80211(priv, "leave - not in IBSS\n");
-               mutex_unlock(&priv->mutex);
-               return;
-       }
-
-       iwl_set_rate(priv);
-
-       mutex_unlock(&priv->mutex);
-
-       IWL_DEBUG_MAC80211(priv, "leave\n");
-}
-
-static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
-{
-       struct iwl_priv *priv = hw->priv;
-       unsigned long flags;
-       __le64 timestamp;
-
-       IWL_DEBUG_MAC80211(priv, "enter\n");
-
-       if (!iwl_is_ready_rf(priv)) {
-               IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
-               return -EIO;
-       }
-
-       if (priv->iw_mode != NL80211_IFTYPE_ADHOC) {
-               IWL_DEBUG_MAC80211(priv, "leave - not IBSS\n");
-               return -EIO;
-       }
-
-       spin_lock_irqsave(&priv->lock, flags);
-
-       if (priv->ibss_beacon)
-               dev_kfree_skb(priv->ibss_beacon);
-
-       priv->ibss_beacon = skb;
-
-       priv->assoc_id = 0;
-       timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp;
-       priv->timestamp = le64_to_cpu(timestamp);
-
-       IWL_DEBUG_MAC80211(priv, "leave\n");
-       spin_unlock_irqrestore(&priv->lock, flags);
-
-       iwl_reset_qos(priv);
-
-       iwl_post_associate(priv);
-
-
-       return 0;
-}
-
 /*****************************************************************************
  *
  * sysfs attributes
@@ -2888,7 +2461,7 @@ static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
 static ssize_t show_debug_level(struct device *d,
                                struct device_attribute *attr, char *buf)
 {
-       struct iwl_priv *priv = d->driver_data;
+       struct iwl_priv *priv = dev_get_drvdata(d);
 
        return sprintf(buf, "0x%08X\n", priv->debug_level);
 }
@@ -2896,7 +2469,7 @@ static ssize_t store_debug_level(struct device *d,
                                struct device_attribute *attr,
                                 const char *buf, size_t count)
 {
-       struct iwl_priv *priv = d->driver_data;
+       struct iwl_priv *priv = dev_get_drvdata(d);
        unsigned long val;
        int ret;
 
@@ -2919,7 +2492,7 @@ static DEVICE_ATTR(debug_level, S_IWUSR | S_IRUGO,
 static ssize_t show_version(struct device *d,
                                struct device_attribute *attr, char *buf)
 {
-       struct iwl_priv *priv = d->driver_data;
+       struct iwl_priv *priv = dev_get_drvdata(d);
        struct iwl_alive_resp *palive = &priv->card_alive;
        ssize_t pos = 0;
        u16 eeprom_ver;
@@ -2936,8 +2509,10 @@ static ssize_t show_version(struct device *d,
 
        if (priv->eeprom) {
                eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION);
-               pos += sprintf(buf + pos, "EEPROM version: 0x%x\n",
-                                eeprom_ver);
+               pos += sprintf(buf + pos, "NVM Type: %s, version: 0x%x\n",
+                              (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP)
+                              ? "OTP" : "EEPROM", eeprom_ver);
+
        } else {
                pos += sprintf(buf + pos, "EEPROM not initialzed\n");
        }
@@ -2950,7 +2525,7 @@ static DEVICE_ATTR(version, S_IWUSR | S_IRUGO, show_version, NULL);
 static ssize_t show_temperature(struct device *d,
                                struct device_attribute *attr, char *buf)
 {
-       struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+       struct iwl_priv *priv = dev_get_drvdata(d);
 
        if (!iwl_is_alive(priv))
                return -EAGAIN;
@@ -2963,7 +2538,7 @@ static DEVICE_ATTR(temperature, S_IRUGO, show_temperature, NULL);
 static ssize_t show_tx_power(struct device *d,
                             struct device_attribute *attr, char *buf)
 {
-       struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+       struct iwl_priv *priv = dev_get_drvdata(d);
 
        if (!iwl_is_ready_rf(priv))
                return sprintf(buf, "off\n");
@@ -2975,7 +2550,7 @@ static ssize_t store_tx_power(struct device *d,
                              struct device_attribute *attr,
                              const char *buf, size_t count)
 {
-       struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+       struct iwl_priv *priv = dev_get_drvdata(d);
        unsigned long val;
        int ret;
 
@@ -2993,7 +2568,7 @@ static DEVICE_ATTR(tx_power, S_IWUSR | S_IRUGO, show_tx_power, store_tx_power);
 static ssize_t show_flags(struct device *d,
                          struct device_attribute *attr, char *buf)
 {
-       struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+       struct iwl_priv *priv = dev_get_drvdata(d);
 
        return sprintf(buf, "0x%04X\n", priv->active_rxon.flags);
 }
@@ -3002,7 +2577,7 @@ static ssize_t store_flags(struct device *d,
                           struct device_attribute *attr,
                           const char *buf, size_t count)
 {
-       struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+       struct iwl_priv *priv = dev_get_drvdata(d);
        unsigned long val;
        u32 flags;
        int ret = strict_strtoul(buf, 0, &val);
@@ -3018,7 +2593,7 @@ static ssize_t store_flags(struct device *d,
                else {
                        IWL_DEBUG_INFO(priv, "Commit rxon.flags = 0x%04X\n", flags);
                        priv->staging_rxon.flags = cpu_to_le32(flags);
-                       iwl_commit_rxon(priv);
+                       iwlcore_commit_rxon(priv);
                }
        }
        mutex_unlock(&priv->mutex);
@@ -3031,7 +2606,7 @@ static DEVICE_ATTR(flags, S_IWUSR | S_IRUGO, show_flags, store_flags);
 static ssize_t show_filter_flags(struct device *d,
                                 struct device_attribute *attr, char *buf)
 {
-       struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+       struct iwl_priv *priv = dev_get_drvdata(d);
 
        return sprintf(buf, "0x%04X\n",
                le32_to_cpu(priv->active_rxon.filter_flags));
@@ -3041,7 +2616,7 @@ static ssize_t store_filter_flags(struct device *d,
                                  struct device_attribute *attr,
                                  const char *buf, size_t count)
 {
-       struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+       struct iwl_priv *priv = dev_get_drvdata(d);
        unsigned long val;
        u32 filter_flags;
        int ret = strict_strtoul(buf, 0, &val);
@@ -3059,7 +2634,7 @@ static ssize_t store_filter_flags(struct device *d,
                                       "0x%04X\n", filter_flags);
                        priv->staging_rxon.filter_flags =
                                cpu_to_le32(filter_flags);
-                       iwl_commit_rxon(priv);
+                       iwlcore_commit_rxon(priv);
                }
        }
        mutex_unlock(&priv->mutex);
@@ -3102,32 +2677,37 @@ static ssize_t show_power_level(struct device *d,
 {
        struct iwl_priv *priv = dev_get_drvdata(d);
        int mode = priv->power_data.user_power_setting;
-       int system = priv->power_data.system_power_setting;
        int level = priv->power_data.power_mode;
        char *p = buf;
 
-       switch (system) {
-       case IWL_POWER_SYS_AUTO:
-               p += sprintf(p, "SYSTEM:auto");
-               break;
-       case IWL_POWER_SYS_AC:
-               p += sprintf(p, "SYSTEM:ac");
-               break;
-       case IWL_POWER_SYS_BATTERY:
-               p += sprintf(p, "SYSTEM:battery");
-               break;
-       }
-
-       p += sprintf(p, "\tMODE:%s", (mode < IWL_POWER_AUTO) ?
-                       "fixed" : "auto");
-       p += sprintf(p, "\tINDEX:%d", level);
-       p += sprintf(p, "\n");
+       p += sprintf(p, "INDEX:%d\t", level);
+       p += sprintf(p, "USER:%d\n", mode);
        return p - buf + 1;
 }
 
 static DEVICE_ATTR(power_level, S_IWUSR | S_IRUSR, show_power_level,
                   store_power_level);
 
+static ssize_t show_qos(struct device *d,
+                               struct device_attribute *attr, char *buf)
+{
+       struct iwl_priv *priv = dev_get_drvdata(d);
+       char *p = buf;
+       int   q;
+
+       for (q = 0; q < AC_NUM; q++) {
+               p += sprintf(p, "\tcw_min\tcw_max\taifsn\ttxop\n");
+               p += sprintf(p, "AC[%d]\t%u\t%u\t%u\t%u\n", q,
+                            priv->qos_data.def_qos_parm.ac[q].cw_min,
+                            priv->qos_data.def_qos_parm.ac[q].cw_max,
+                            priv->qos_data.def_qos_parm.ac[q].aifsn,
+                            priv->qos_data.def_qos_parm.ac[q].edca_txop);
+       }
+
+       return p - buf + 1;
+}
+
+static DEVICE_ATTR(qos, S_IRUGO, show_qos, NULL);
 
 static ssize_t show_statistics(struct device *d,
                               struct device_attribute *attr, char *buf)
@@ -3183,14 +2763,12 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
        INIT_WORK(&priv->up, iwl_bg_up);
        INIT_WORK(&priv->restart, iwl_bg_restart);
        INIT_WORK(&priv->rx_replenish, iwl_bg_rx_replenish);
-       INIT_WORK(&priv->rf_kill, iwl_bg_rf_kill);
        INIT_WORK(&priv->beacon_update, iwl_bg_beacon_update);
        INIT_WORK(&priv->run_time_calib_work, iwl_bg_run_time_calib_work);
        INIT_DELAYED_WORK(&priv->init_alive_start, iwl_bg_init_alive_start);
        INIT_DELAYED_WORK(&priv->alive_start, iwl_bg_alive_start);
 
        iwl_setup_scan_deferred_work(priv);
-       iwl_setup_power_deferred_work(priv);
 
        if (priv->cfg->ops->lib->setup_deferred_work)
                priv->cfg->ops->lib->setup_deferred_work(priv);
@@ -3199,8 +2777,12 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
        priv->statistics_periodic.data = (unsigned long)priv;
        priv->statistics_periodic.function = iwl_bg_statistics_periodic;
 
-       tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
-                    iwl_irq_tasklet, (unsigned long)priv);
+       if (!priv->cfg->use_isr_legacy)
+               tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
+                       iwl_irq_tasklet, (unsigned long)priv);
+       else
+               tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
+                       iwl_irq_tasklet_legacy, (unsigned long)priv);
 }
 
 static void iwl_cancel_deferred_work(struct iwl_priv *priv)
@@ -3210,7 +2792,6 @@ static void iwl_cancel_deferred_work(struct iwl_priv *priv)
 
        cancel_delayed_work_sync(&priv->init_alive_start);
        cancel_delayed_work(&priv->scan_check);
-       cancel_delayed_work_sync(&priv->set_power_save);
        cancel_delayed_work(&priv->alive_start);
        cancel_work_sync(&priv->beacon_update);
        del_timer_sync(&priv->statistics_periodic);
@@ -3227,7 +2808,7 @@ static struct attribute *iwl_sysfs_entries[] = {
        &dev_attr_debug_level.attr,
 #endif
        &dev_attr_version.attr,
-
+       &dev_attr_qos.attr,
        NULL
 };
 
@@ -3243,7 +2824,6 @@ static struct ieee80211_ops iwl_hw_ops = {
        .add_interface = iwl_mac_add_interface,
        .remove_interface = iwl_mac_remove_interface,
        .config = iwl_mac_config,
-       .config_interface = iwl_mac_config_interface,
        .configure_filter = iwl_configure_filter,
        .set_key = iwl_mac_set_key,
        .update_tkip_key = iwl_mac_update_tkip_key,
@@ -3291,6 +2871,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        IWL_DEBUG_INFO(priv, "*** LOAD DRIVER ***\n");
        priv->cfg = cfg;
        priv->pci_dev = pdev;
+       priv->inta_mask = CSR_INI_SET_MASK;
 
 #ifdef CONFIG_IWLWIFI_DEBUG
        priv->debug_level = priv->cfg->mod_params->debug;
@@ -3341,6 +2922,10 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                (unsigned long long) pci_resource_len(pdev, 0));
        IWL_DEBUG_INFO(priv, "pci_resource_base = %p\n", priv->hw_base);
 
+       /* this spin lock will be used in apm_ops.init and EEPROM access
+        * we should init now
+        */
+       spin_lock_init(&priv->reg_lock);
        iwl_hw_detect(priv);
        IWL_INFO(priv, "Detected Intel Wireless WiFi Link %s REV=0x%X\n",
                priv->cfg->name, priv->hw_rev);
@@ -3349,6 +2934,12 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
         * PCI Tx retries from interfering with C3 CPU state */
        pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00);
 
+       iwl_prepare_card_hw(priv);
+       if (!priv->hw_ready) {
+               IWL_WARN(priv, "Failed, HW not ready\n");
+               goto out_iounmap;
+       }
+
        /* amp init */
        err = priv->cfg->ops->lib->apm_ops.init(priv);
        if (err < 0) {
@@ -3390,18 +2981,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
                goto out_free_eeprom;
        /* At this point both hw and priv are initialized. */
 
-       /**********************************
-        * 7. Initialize module parameters
-        **********************************/
-
-       /* Disable radio (SW RF KILL) via parameter when loading driver */
-       if (priv->cfg->mod_params->disable) {
-               set_bit(STATUS_RF_KILL_SW, &priv->status);
-               IWL_DEBUG_INFO(priv, "Radio disabled.\n");
-       }
-
        /********************
-        * 8. Setup services
+        * 7. Setup services
         ********************/
        spin_lock_irqsave(&priv->lock, flags);
        iwl_disable_interrupts(priv);
@@ -3409,8 +2990,9 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        pci_enable_msi(priv->pci_dev);
 
-       err = request_irq(priv->pci_dev->irq, iwl_isr, IRQF_SHARED,
-                         DRV_NAME, priv);
+       iwl_alloc_isr_ict(priv);
+       err = request_irq(priv->pci_dev->irq, priv->cfg->ops->lib->isr,
+                         IRQF_SHARED, DRV_NAME, priv);
        if (err) {
                IWL_ERR(priv, "Error allocating IRQ %d\n", priv->pci_dev->irq);
                goto out_disable_msi;
@@ -3425,7 +3007,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        iwl_setup_rx_handlers(priv);
 
        /**********************************
-        * 9. Setup and register mac80211
+        * 8. Setup and register mac80211
         **********************************/
 
        /* enable interrupts if needed: hw bug w/a */
@@ -3443,7 +3025,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        err = iwl_dbgfs_register(priv, DRV_NAME);
        if (err)
-               IWL_ERR(priv, "failed to create debugfs files\n");
+               IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err);
 
        /* If platform's RF_KILL switch is NOT set to KILL */
        if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
@@ -3451,12 +3033,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        else
                set_bit(STATUS_RF_KILL_HW, &priv->status);
 
-       err = iwl_rfkill_init(priv);
-       if (err)
-               IWL_ERR(priv, "Unable to initialize RFKILL system. "
-                                 "Ignoring error: %d\n", err);
-       else
-               iwl_rfkill_set_hw_state(priv);
+       wiphy_rfkill_set_hw_state(priv->hw->wiphy,
+               test_bit(STATUS_RF_KILL_HW, &priv->status));
 
        iwl_power_initialize(priv);
        return 0;
@@ -3467,6 +3045,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        sysfs_remove_group(&pdev->dev.kobj, &iwl_attribute_group);
  out_free_irq:
        free_irq(priv->pci_dev->irq, priv);
+       iwl_free_isr_ict(priv);
  out_disable_msi:
        pci_disable_msi(priv->pci_dev);
        iwl_uninit_drv(priv);
@@ -3519,7 +3098,6 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev)
 
        iwl_synchronize_irq(priv);
 
-       iwl_rfkill_unregister(priv);
        iwl_dealloc_ucode_pci(priv);
 
        if (priv->rxq.bd)
@@ -3548,51 +3126,14 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev)
 
        iwl_uninit_drv(priv);
 
+       iwl_free_isr_ict(priv);
+
        if (priv->ibss_beacon)
                dev_kfree_skb(priv->ibss_beacon);
 
        ieee80211_free_hw(priv->hw);
 }
 
-#ifdef CONFIG_PM
-
-static int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state)
-{
-       struct iwl_priv *priv = pci_get_drvdata(pdev);
-
-       if (priv->is_open) {
-               set_bit(STATUS_IN_SUSPEND, &priv->status);
-               iwl_mac_stop(priv->hw);
-               priv->is_open = 1;
-       }
-
-       pci_save_state(pdev);
-       pci_disable_device(pdev);
-       pci_set_power_state(pdev, PCI_D3hot);
-
-       return 0;
-}
-
-static int iwl_pci_resume(struct pci_dev *pdev)
-{
-       struct iwl_priv *priv = pci_get_drvdata(pdev);
-       int ret;
-
-       pci_set_power_state(pdev, PCI_D0);
-       ret = pci_enable_device(pdev);
-       if (ret)
-               return ret;
-       pci_restore_state(pdev);
-       iwl_enable_interrupts(priv);
-
-       if (priv->is_open)
-               iwl_mac_start(priv->hw);
-
-       clear_bit(STATUS_IN_SUSPEND, &priv->status);
-       return 0;
-}
-
-#endif /* CONFIG_PM */
 
 /*****************************************************************************
  *
index 735f3f19928cb87f9f975cd7c231ca96f100b290..a5d63672ad39cbcb997f3aae0cfdeb67b8041ee5 100644 (file)
@@ -857,7 +857,7 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv,
                priv->cfg->ops->lib->update_chain_flags(priv);
 
        data->state = IWL_CHAIN_NOISE_DONE;
-       iwl_power_enable_management(priv);
+       iwl_power_update_mode(priv, 0);
 }
 EXPORT_SYMBOL(iwl_chain_noise_calibration);
 
index 29d40746da6a3112c34cb3997d4788607a6b2744..c87033bf3ad2f95dbc19c2b5a6acacf865d9e283 100644 (file)
@@ -614,8 +614,18 @@ enum {
 
 #define RXON_FLG_CHANNEL_MODE_POS              (25)
 #define RXON_FLG_CHANNEL_MODE_MSK              cpu_to_le32(0x3 << 25)
-#define RXON_FLG_CHANNEL_MODE_PURE_40_MSK      cpu_to_le32(0x1 << 25)
-#define RXON_FLG_CHANNEL_MODE_MIXED_MSK                cpu_to_le32(0x2 << 25)
+
+/* channel mode */
+enum {
+       CHANNEL_MODE_LEGACY = 0,
+       CHANNEL_MODE_PURE_40 = 1,
+       CHANNEL_MODE_MIXED = 2,
+       CHANNEL_MODE_RESERVED = 3,
+};
+#define RXON_FLG_CHANNEL_MODE_LEGACY   cpu_to_le32(CHANNEL_MODE_LEGACY << RXON_FLG_CHANNEL_MODE_POS)
+#define RXON_FLG_CHANNEL_MODE_PURE_40  cpu_to_le32(CHANNEL_MODE_PURE_40 << RXON_FLG_CHANNEL_MODE_POS)
+#define RXON_FLG_CHANNEL_MODE_MIXED    cpu_to_le32(CHANNEL_MODE_MIXED << RXON_FLG_CHANNEL_MODE_POS)
+
 /* CTS to self (if spec allows) flag */
 #define RXON_FLG_SELF_CTS_EN                   cpu_to_le32(0x1<<30)
 
@@ -1057,7 +1067,7 @@ struct iwl_addsta_cmd {
         * Set modify_mask bit STA_MODIFY_TID_DISABLE_TX to use this field. */
        __le16 tid_disable_tx;
 
-       __le16  reserved1;
+       __le16  rate_n_flags;           /* 3945 only */
 
        /* TID for which to add block-ack support.
         * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */
@@ -1903,6 +1913,18 @@ struct iwl_link_qual_general_params {
        u8 start_rate_index[LINK_QUAL_AC_NUM];
 } __attribute__ ((packed));
 
+#define LINK_QUAL_AGG_TIME_LIMIT_DEF   (4000) /* 4 milliseconds */
+#define LINK_QUAL_AGG_TIME_LIMIT_MAX   (65535)
+#define LINK_QUAL_AGG_TIME_LIMIT_MIN   (0)
+
+#define LINK_QUAL_AGG_DISABLE_START_DEF        (3)
+#define LINK_QUAL_AGG_DISABLE_START_MAX        (255)
+#define LINK_QUAL_AGG_DISABLE_START_MIN        (0)
+
+#define LINK_QUAL_AGG_FRAME_LIMIT_DEF  (31)
+#define LINK_QUAL_AGG_FRAME_LIMIT_MAX  (64)
+#define LINK_QUAL_AGG_FRAME_LIMIT_MIN  (0)
+
 /**
  * struct iwl_link_qual_agg_params
  *
@@ -2469,11 +2491,12 @@ struct iwl_ssid_ie {
        u8 ssid[32];
 } __attribute__ ((packed));
 
-#define PROBE_OPTION_MAX_API1          0x4
-#define PROBE_OPTION_MAX               0x14
+#define PROBE_OPTION_MAX_3945          4
+#define PROBE_OPTION_MAX               20
 #define TX_CMD_LIFE_TIME_INFINITE      cpu_to_le32(0xFFFFFFFF)
 #define IWL_GOOD_CRC_TH                        cpu_to_le16(1)
 #define IWL_MAX_SCAN_SIZE 1024
+#define IWL_MAX_PROBE_REQUEST          200
 
 /*
  * REPLY_SCAN_CMD = 0x80 (command)
@@ -2552,7 +2575,7 @@ struct iwl3945_scan_cmd {
        struct iwl3945_tx_cmd tx_cmd;
 
        /* For directed active scans (set to all-0s otherwise) */
-       struct iwl_ssid_ie direct_scan[PROBE_OPTION_MAX_API1];
+       struct iwl_ssid_ie direct_scan[PROBE_OPTION_MAX_3945];
 
        /*
         * Probe request frame, followed by channel list.
index c54fb93e9d720e7c63d29692b5f16364b2666807..f9d16ca5b3d9b0a7f30903094e2f98d432973251 100644 (file)
@@ -36,9 +36,9 @@
 #include "iwl-debug.h"
 #include "iwl-core.h"
 #include "iwl-io.h"
-#include "iwl-rfkill.h"
 #include "iwl-power.h"
 #include "iwl-sta.h"
+#include "iwl-helpers.h"
 
 
 MODULE_DESCRIPTION("iwl core");
@@ -59,6 +59,8 @@ MODULE_LICENSE("GPL");
                                    IWL_RATE_##pp##M_INDEX,    \
                                    IWL_RATE_##np##M_INDEX }
 
+static irqreturn_t iwl_isr(int irq, void *data);
+
 /*
  * Parameter order:
  *   rate, ht rate, prev rate, next rate, prev tgg rate, next tgg rate
@@ -273,6 +275,14 @@ void iwl_activate_qos(struct iwl_priv *priv, u8 force)
 }
 EXPORT_SYMBOL(iwl_activate_qos);
 
+/*
+ * AC        CWmin         CW max      AIFSN      TXOP Limit    TXOP Limit
+ *                                              (802.11b)      (802.11a/g)
+ * AC_BK      15            1023        7           0               0
+ * AC_BE      15            1023        3           0               0
+ * AC_VI       7              15        2          6.016ms       3.008ms
+ * AC_VO       3               7        2          3.264ms       1.504ms
+ */
 void iwl_reset_qos(struct iwl_priv *priv)
 {
        u16 cw_min = 15;
@@ -304,6 +314,7 @@ void iwl_reset_qos(struct iwl_priv *priv)
        if (priv->qos_data.qos_active)
                aifs = 3;
 
+       /* AC_BE */
        priv->qos_data.def_qos_parm.ac[0].cw_min = cpu_to_le16(cw_min);
        priv->qos_data.def_qos_parm.ac[0].cw_max = cpu_to_le16(cw_max);
        priv->qos_data.def_qos_parm.ac[0].aifsn = aifs;
@@ -311,6 +322,7 @@ void iwl_reset_qos(struct iwl_priv *priv)
        priv->qos_data.def_qos_parm.ac[0].reserved1 = 0;
 
        if (priv->qos_data.qos_active) {
+               /* AC_BK */
                i = 1;
                priv->qos_data.def_qos_parm.ac[i].cw_min = cpu_to_le16(cw_min);
                priv->qos_data.def_qos_parm.ac[i].cw_max = cpu_to_le16(cw_max);
@@ -318,11 +330,12 @@ void iwl_reset_qos(struct iwl_priv *priv)
                priv->qos_data.def_qos_parm.ac[i].edca_txop = 0;
                priv->qos_data.def_qos_parm.ac[i].reserved1 = 0;
 
+               /* AC_VI */
                i = 2;
                priv->qos_data.def_qos_parm.ac[i].cw_min =
                        cpu_to_le16((cw_min + 1) / 2 - 1);
                priv->qos_data.def_qos_parm.ac[i].cw_max =
-                       cpu_to_le16(cw_max);
+                       cpu_to_le16(cw_min);
                priv->qos_data.def_qos_parm.ac[i].aifsn = 2;
                if (is_legacy)
                        priv->qos_data.def_qos_parm.ac[i].edca_txop =
@@ -332,11 +345,12 @@ void iwl_reset_qos(struct iwl_priv *priv)
                                cpu_to_le16(3008);
                priv->qos_data.def_qos_parm.ac[i].reserved1 = 0;
 
+               /* AC_VO */
                i = 3;
                priv->qos_data.def_qos_parm.ac[i].cw_min =
                        cpu_to_le16((cw_min + 1) / 4 - 1);
                priv->qos_data.def_qos_parm.ac[i].cw_max =
-                       cpu_to_le16((cw_max + 1) / 2 - 1);
+                       cpu_to_le16((cw_min + 1) / 2 - 1);
                priv->qos_data.def_qos_parm.ac[i].aifsn = 2;
                priv->qos_data.def_qos_parm.ac[i].reserved1 = 0;
                if (is_legacy)
@@ -591,10 +605,10 @@ static u8 iwl_is_channel_extension(struct iwl_priv *priv,
 
        if (extension_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_ABOVE)
                return !(ch_info->fat_extension_channel &
-                                       IEEE80211_CHAN_NO_FAT_ABOVE);
+                                       IEEE80211_CHAN_NO_HT40PLUS);
        else if (extension_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_BELOW)
                return !(ch_info->fat_extension_channel &
-                                       IEEE80211_CHAN_NO_FAT_BELOW);
+                                       IEEE80211_CHAN_NO_HT40MINUS);
 
        return 0;
 }
@@ -605,19 +619,23 @@ u8 iwl_is_fat_tx_allowed(struct iwl_priv *priv,
        struct iwl_ht_info *iwl_ht_conf = &priv->current_ht_config;
 
        if ((!iwl_ht_conf->is_ht) ||
-          (iwl_ht_conf->supported_chan_width != IWL_CHANNEL_WIDTH_40MHZ) ||
-          (iwl_ht_conf->extension_chan_offset == IEEE80211_HT_PARAM_CHA_SEC_NONE))
+           (iwl_ht_conf->supported_chan_width != IWL_CHANNEL_WIDTH_40MHZ))
                return 0;
 
+       /* We do not check for IEEE80211_HT_CAP_SUP_WIDTH_20_40
+        * the bit will not set if it is pure 40MHz case
+        */
        if (sta_ht_inf) {
-               if ((!sta_ht_inf->ht_supported) ||
-                  (!(sta_ht_inf->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)))
+               if (!sta_ht_inf->ht_supported)
                        return 0;
        }
 
-       return iwl_is_channel_extension(priv, priv->band,
-                                       le16_to_cpu(priv->staging_rxon.channel),
-                                       iwl_ht_conf->extension_chan_offset);
+       if (iwl_ht_conf->ht_protection & IEEE80211_HT_OP_MODE_PROTECTION_20MHZ)
+               return 1;
+       else
+               return iwl_is_channel_extension(priv, priv->band,
+                               le16_to_cpu(priv->staging_rxon.channel),
+                               iwl_ht_conf->extension_chan_offset);
 }
 EXPORT_SYMBOL(iwl_is_fat_tx_allowed);
 
@@ -735,6 +753,8 @@ int iwl_full_rxon_required(struct iwl_priv *priv)
             priv->active_rxon.ofdm_ht_single_stream_basic_rates) ||
            (priv->staging_rxon.ofdm_ht_dual_stream_basic_rates !=
             priv->active_rxon.ofdm_ht_dual_stream_basic_rates) ||
+           (priv->staging_rxon.ofdm_ht_triple_stream_basic_rates !=
+            priv->active_rxon.ofdm_ht_triple_stream_basic_rates) ||
            (priv->staging_rxon.assoc_id != priv->active_rxon.assoc_id))
                return 1;
 
@@ -785,43 +805,53 @@ EXPORT_SYMBOL(iwl_rate_get_lowest_plcp);
 void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info)
 {
        struct iwl_rxon_cmd *rxon = &priv->staging_rxon;
-       u32 val;
 
        if (!ht_info->is_ht) {
-               rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MIXED_MSK |
-                       RXON_FLG_CHANNEL_MODE_PURE_40_MSK |
+               rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MSK |
                        RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK |
                        RXON_FLG_FAT_PROT_MSK |
                        RXON_FLG_HT_PROT_MSK);
                return;
        }
 
-       /* Set up channel bandwidth:  20 MHz only, or 20/40 mixed if fat ok */
-       if (iwl_is_fat_tx_allowed(priv, NULL))
-               rxon->flags |= RXON_FLG_CHANNEL_MODE_MIXED_MSK;
-       else
-               rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MIXED_MSK |
-                                RXON_FLG_CHANNEL_MODE_PURE_40_MSK);
-
-       /* Note: control channel is opposite of extension channel */
-       switch (ht_info->extension_chan_offset) {
-       case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
-               rxon->flags &= ~(RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK);
-               break;
-       case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
-               rxon->flags |= RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK;
-               break;
-       case IEEE80211_HT_PARAM_CHA_SEC_NONE:
-       default:
-               rxon->flags &= ~RXON_FLG_CHANNEL_MODE_MIXED_MSK;
-               break;
+       /* FIXME: if the definition of ht_protection changed, the "translation"
+        * will be needed for rxon->flags
+        */
+       rxon->flags |= cpu_to_le32(ht_info->ht_protection << RXON_FLG_HT_OPERATING_MODE_POS);
+
+       /* Set up channel bandwidth:
+        * 20 MHz only, 20/40 mixed or pure 40 if fat ok */
+       /* clear the HT channel mode before set the mode */
+       rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MSK |
+                        RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK);
+       if (iwl_is_fat_tx_allowed(priv, NULL)) {
+               /* pure 40 fat */
+               if (rxon->flags & RXON_FLG_FAT_PROT_MSK)
+                       rxon->flags |= RXON_FLG_CHANNEL_MODE_PURE_40;
+               else {
+                       /* Note: control channel is opposite of extension channel */
+                       switch (ht_info->extension_chan_offset) {
+                       case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
+                               rxon->flags &= ~(RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK);
+                               rxon->flags |= RXON_FLG_CHANNEL_MODE_MIXED;
+                               break;
+                       case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
+                               rxon->flags |= RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK;
+                               rxon->flags |= RXON_FLG_CHANNEL_MODE_MIXED;
+                               break;
+                       case IEEE80211_HT_PARAM_CHA_SEC_NONE:
+                       default:
+                               /* channel location only valid if in Mixed mode */
+                               IWL_ERR(priv, "invalid extension channel offset\n");
+                               break;
+                       }
+               }
+       } else {
+               rxon->flags |= RXON_FLG_CHANNEL_MODE_LEGACY;
        }
 
-       val = ht_info->ht_protection;
-
-       rxon->flags |= cpu_to_le32(val << RXON_FLG_HT_OPERATING_MODE_POS);
-
-       iwl_set_rxon_chain(priv);
+       if (priv->cfg->ops->hcmd->set_rxon_chain)
+               priv->cfg->ops->hcmd->set_rxon_chain(priv);
 
        IWL_DEBUG_ASSOC(priv, "supported HT rate 0x%X 0x%X 0x%X "
                        "rxon flags 0x%X operation mode :0x%X "
@@ -901,10 +931,11 @@ static u8 iwl_count_chain_bitmap(u32 chain_bitmap)
  * never called for monitor mode. The only way mac80211 informs us about
  * monitor mode is through configuring filters (call to configure_filter).
  */
-static bool iwl_is_monitor_mode(struct iwl_priv *priv)
+bool iwl_is_monitor_mode(struct iwl_priv *priv)
 {
        return !!(priv->staging_rxon.filter_flags & RXON_FILTER_PROMISC_MSK);
 }
+EXPORT_SYMBOL(iwl_is_monitor_mode);
 
 /**
  * iwl_set_rxon_chain - Set up Rx chain usage in "staging" RXON image
@@ -956,10 +987,10 @@ void iwl_set_rxon_chain(struct iwl_priv *priv)
        if (iwl_is_monitor_mode(priv) &&
            !(priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) &&
            ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965)) {
-               rx_chain = 0x07 << RXON_RX_CHAIN_VALID_POS;
-               rx_chain |= 0x06 << RXON_RX_CHAIN_FORCE_SEL_POS;
-               rx_chain |= 0x07 << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS;
-               rx_chain |= 0x01 << RXON_RX_CHAIN_DRIVER_FORCE_POS;
+               rx_chain = ANT_ABC << RXON_RX_CHAIN_VALID_POS;
+               rx_chain |= ANT_BC << RXON_RX_CHAIN_FORCE_SEL_POS;
+               rx_chain |= ANT_ABC << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS;
+               rx_chain |= 0x1 << RXON_RX_CHAIN_DRIVER_FORCE_POS;
        }
 
        priv->staging_rxon.rx_chain = cpu_to_le16(rx_chain);
@@ -1068,11 +1099,6 @@ void iwl_connection_init_rx_config(struct iwl_priv *priv, int mode)
                                                  RXON_FILTER_ACCEPT_GRP_MSK;
                break;
 
-       case NL80211_IFTYPE_MONITOR:
-               priv->staging_rxon.dev_type = RXON_DEV_TYPE_SNIFFER;
-               priv->staging_rxon.filter_flags = RXON_FILTER_PROMISC_MSK |
-                   RXON_FILTER_CTL2HOST_MSK | RXON_FILTER_ACCEPT_GRP_MSK;
-               break;
        default:
                IWL_ERR(priv, "Unsupported interface type %d\n", mode);
                break;
@@ -1111,16 +1137,18 @@ void iwl_connection_init_rx_config(struct iwl_priv *priv, int mode)
        priv->staging_rxon.cck_basic_rates =
            (IWL_CCK_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF;
 
-       priv->staging_rxon.flags &= ~(RXON_FLG_CHANNEL_MODE_MIXED_MSK |
-                                       RXON_FLG_CHANNEL_MODE_PURE_40_MSK);
+       /* clear both MIX and PURE40 mode flag */
+       priv->staging_rxon.flags &= ~(RXON_FLG_CHANNEL_MODE_MIXED |
+                                       RXON_FLG_CHANNEL_MODE_PURE_40);
        memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN);
        memcpy(priv->staging_rxon.wlap_bssid_addr, priv->mac_addr, ETH_ALEN);
        priv->staging_rxon.ofdm_ht_single_stream_basic_rates = 0xff;
        priv->staging_rxon.ofdm_ht_dual_stream_basic_rates = 0xff;
+       priv->staging_rxon.ofdm_ht_triple_stream_basic_rates = 0xff;
 }
 EXPORT_SYMBOL(iwl_connection_init_rx_config);
 
-void iwl_set_rate(struct iwl_priv *priv)
+static void iwl_set_rate(struct iwl_priv *priv)
 {
        const struct ieee80211_supported_band *hw = NULL;
        struct ieee80211_rate *rate;
@@ -1166,7 +1194,6 @@ void iwl_set_rate(struct iwl_priv *priv)
                priv->staging_rxon.ofdm_basic_rates =
                   (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
 }
-EXPORT_SYMBOL(iwl_set_rate);
 
 void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
 {
@@ -1230,11 +1257,6 @@ void iwl_irq_handle_error(struct iwl_priv *priv)
                IWL_DEBUG(priv, IWL_DL_FW_ERRORS,
                          "Restarting adapter due to uCode error.\n");
 
-               if (iwl_is_associated(priv)) {
-                       memcpy(&priv->recovery_rxon, &priv->active_rxon,
-                              sizeof(priv->recovery_rxon));
-                       priv->error_recovering = 1;
-               }
                if (priv->cfg->mod_params->restart_fw)
                        queue_work(priv->workqueue, &priv->restart);
        }
@@ -1298,19 +1320,20 @@ int iwl_setup_mac(struct iwl_priv *priv)
        hw->flags = IEEE80211_HW_SIGNAL_DBM |
                    IEEE80211_HW_NOISE_DBM |
                    IEEE80211_HW_AMPDU_AGGREGATION |
-                   IEEE80211_HW_SPECTRUM_MGMT |
-                   IEEE80211_HW_SUPPORTS_PS;
+                   IEEE80211_HW_SPECTRUM_MGMT;
        hw->wiphy->interface_modes =
                BIT(NL80211_IFTYPE_STATION) |
                BIT(NL80211_IFTYPE_ADHOC);
 
        hw->wiphy->custom_regulatory = true;
-       hw->wiphy->max_scan_ssids = 1;
+
+       hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX;
+       /* we create the 802.11 header and a zero-length SSID element */
+       hw->wiphy->max_scan_ie_len = IWL_MAX_PROBE_REQUEST - 24 - 2;
 
        /* Default value; 4 EDCA QOS priorities */
        hw->queues = 4;
 
-       hw->conf.beacon_int = 100;
        hw->max_listen_interval = IWL_CONN_MAX_LISTEN_INTERVAL;
 
        if (priv->bands[IEEE80211_BAND_2GHZ].n_channels)
@@ -1357,7 +1380,6 @@ int iwl_init_drv(struct iwl_priv *priv)
        priv->ibss_beacon = NULL;
 
        spin_lock_init(&priv->lock);
-       spin_lock_init(&priv->power_data.lock);
        spin_lock_init(&priv->sta_lock);
        spin_lock_init(&priv->hcmd_lock);
 
@@ -1378,7 +1400,9 @@ int iwl_init_drv(struct iwl_priv *priv)
        priv->current_ht_config.sm_ps = WLAN_HT_CAP_SM_PS_DISABLED;
 
        /* Choose which receivers/antennas to use */
-       iwl_set_rxon_chain(priv);
+       if (priv->cfg->ops->hcmd->set_rxon_chain)
+               priv->cfg->ops->hcmd->set_rxon_chain(priv);
+
        iwl_init_scan_params(priv);
 
        iwl_reset_qos(priv);
@@ -1475,11 +1499,273 @@ void iwl_enable_interrupts(struct iwl_priv *priv)
 {
        IWL_DEBUG_ISR(priv, "Enabling interrupts\n");
        set_bit(STATUS_INT_ENABLED, &priv->status);
-       iwl_write32(priv, CSR_INT_MASK, CSR_INI_SET_MASK);
+       iwl_write32(priv, CSR_INT_MASK, priv->inta_mask);
 }
 EXPORT_SYMBOL(iwl_enable_interrupts);
 
-irqreturn_t iwl_isr(int irq, void *data)
+
+#define ICT_COUNT (PAGE_SIZE/sizeof(u32))
+
+/* Free dram table */
+void iwl_free_isr_ict(struct iwl_priv *priv)
+{
+       if (priv->ict_tbl_vir) {
+               pci_free_consistent(priv->pci_dev, (sizeof(u32) * ICT_COUNT) +
+                                       PAGE_SIZE, priv->ict_tbl_vir,
+                                       priv->ict_tbl_dma);
+               priv->ict_tbl_vir = NULL;
+       }
+}
+EXPORT_SYMBOL(iwl_free_isr_ict);
+
+
+/* allocate dram shared table it is a PAGE_SIZE aligned
+ * also reset all data related to ICT table interrupt.
+ */
+int iwl_alloc_isr_ict(struct iwl_priv *priv)
+{
+
+       if (priv->cfg->use_isr_legacy)
+               return 0;
+       /* allocate shrared data table */
+       priv->ict_tbl_vir = pci_alloc_consistent(priv->pci_dev, (sizeof(u32) *
+                                                 ICT_COUNT) + PAGE_SIZE,
+                                                 &priv->ict_tbl_dma);
+       if (!priv->ict_tbl_vir)
+               return -ENOMEM;
+
+       /* align table to PAGE_SIZE boundry */
+       priv->aligned_ict_tbl_dma = ALIGN(priv->ict_tbl_dma, PAGE_SIZE);
+
+       IWL_DEBUG_ISR(priv, "ict dma addr %Lx dma aligned %Lx diff %d\n",
+                            (unsigned long long)priv->ict_tbl_dma,
+                            (unsigned long long)priv->aligned_ict_tbl_dma,
+                       (int)(priv->aligned_ict_tbl_dma - priv->ict_tbl_dma));
+
+       priv->ict_tbl =  priv->ict_tbl_vir +
+                         (priv->aligned_ict_tbl_dma - priv->ict_tbl_dma);
+
+       IWL_DEBUG_ISR(priv, "ict vir addr %p vir aligned %p diff %d\n",
+                            priv->ict_tbl, priv->ict_tbl_vir,
+                       (int)(priv->aligned_ict_tbl_dma - priv->ict_tbl_dma));
+
+       /* reset table and index to all 0 */
+       memset(priv->ict_tbl_vir,0, (sizeof(u32) * ICT_COUNT) + PAGE_SIZE);
+       priv->ict_index = 0;
+
+       /* add periodic RX interrupt */
+       priv->inta_mask |= CSR_INT_BIT_RX_PERIODIC;
+       return 0;
+}
+EXPORT_SYMBOL(iwl_alloc_isr_ict);
+
+/* Device is going up inform it about using ICT interrupt table,
+ * also we need to tell the driver to start using ICT interrupt.
+ */
+int iwl_reset_ict(struct iwl_priv *priv)
+{
+       u32 val;
+       unsigned long flags;
+
+       if (!priv->ict_tbl_vir)
+               return 0;
+
+       spin_lock_irqsave(&priv->lock, flags);
+       iwl_disable_interrupts(priv);
+
+       memset(&priv->ict_tbl[0],0, sizeof(u32) * ICT_COUNT);
+
+       val = priv->aligned_ict_tbl_dma >> PAGE_SHIFT;
+
+       val |= CSR_DRAM_INT_TBL_ENABLE;
+       val |= CSR_DRAM_INIT_TBL_WRAP_CHECK;
+
+       IWL_DEBUG_ISR(priv, "CSR_DRAM_INT_TBL_REG =0x%X "
+                       "aligned dma address %Lx\n",
+                       val, (unsigned long long)priv->aligned_ict_tbl_dma);
+
+       iwl_write32(priv, CSR_DRAM_INT_TBL_REG, val);
+       priv->use_ict = true;
+       priv->ict_index = 0;
+       iwl_write32(priv, CSR_INT, priv->inta_mask);
+       iwl_enable_interrupts(priv);
+       spin_unlock_irqrestore(&priv->lock, flags);
+
+       return 0;
+}
+EXPORT_SYMBOL(iwl_reset_ict);
+
+/* Device is going down disable ict interrupt usage */
+void iwl_disable_ict(struct iwl_priv *priv)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&priv->lock, flags);
+       priv->use_ict = false;
+       spin_unlock_irqrestore(&priv->lock, flags);
+}
+EXPORT_SYMBOL(iwl_disable_ict);
+
+/* interrupt handler using ict table, with this interrupt driver will
+ * stop using INTA register to get device's interrupt, reading this register
+ * is expensive, device will write interrupts in ICT dram table, increment
+ * index then will fire interrupt to driver, driver will OR all ICT table
+ * entries from current index up to table entry with 0 value. the result is
+ * the interrupt we need to service, driver will set the entries back to 0 and
+ * set index.
+ */
+irqreturn_t iwl_isr_ict(int irq, void *data)
+{
+       struct iwl_priv *priv = data;
+       u32 inta, inta_mask;
+       u32 val = 0;
+
+       if (!priv)
+               return IRQ_NONE;
+
+       /* dram interrupt table not set yet,
+        * use legacy interrupt.
+        */
+       if (!priv->use_ict)
+               return iwl_isr(irq, data);
+
+       spin_lock(&priv->lock);
+
+       /* Disable (but don't clear!) interrupts here to avoid
+        * back-to-back ISRs and sporadic interrupts from our NIC.
+        * If we have something to service, the tasklet will re-enable ints.
+        * If we *don't* have something, we'll re-enable before leaving here.
+        */
+       inta_mask = iwl_read32(priv, CSR_INT_MASK);  /* just for debug */
+       iwl_write32(priv, CSR_INT_MASK, 0x00000000);
+
+
+       /* Ignore interrupt if there's nothing in NIC to service.
+        * This may be due to IRQ shared with another device,
+        * or due to sporadic interrupts thrown from our NIC. */
+       if (!priv->ict_tbl[priv->ict_index]) {
+               IWL_DEBUG_ISR(priv, "Ignore interrupt, inta == 0\n");
+               goto none;
+       }
+
+       /* read all entries that not 0 start with ict_index */
+       while (priv->ict_tbl[priv->ict_index]) {
+
+               val |= priv->ict_tbl[priv->ict_index];
+               IWL_DEBUG_ISR(priv, "ICT index %d value 0x%08X\n",
+                                       priv->ict_index,
+                                       priv->ict_tbl[priv->ict_index]);
+               priv->ict_tbl[priv->ict_index] = 0;
+               priv->ict_index = iwl_queue_inc_wrap(priv->ict_index,
+                                                               ICT_COUNT);
+
+       }
+
+       /* We should not get this value, just ignore it. */
+       if (val == 0xffffffff)
+               val = 0;
+
+       inta = (0xff & val) | ((0xff00 & val) << 16);
+       IWL_DEBUG_ISR(priv, "ISR inta 0x%08x, enabled 0x%08x ict 0x%08x\n",
+                       inta, inta_mask, val);
+
+       inta &= priv->inta_mask;
+       priv->inta |= inta;
+
+       /* iwl_irq_tasklet() will service interrupts and re-enable them */
+       if (likely(inta))
+               tasklet_schedule(&priv->irq_tasklet);
+       else if (test_bit(STATUS_INT_ENABLED, &priv->status) && !priv->inta) {
+               /* Allow interrupt if was disabled by this handler and
+                * no tasklet was schedules, We should not enable interrupt,
+                * tasklet will enable it.
+                */
+               iwl_enable_interrupts(priv);
+       }
+
+       spin_unlock(&priv->lock);
+       return IRQ_HANDLED;
+
+ none:
+       /* re-enable interrupts here since we don't have anything to service.
+        * only Re-enable if disabled by irq.
+        */
+       if (test_bit(STATUS_INT_ENABLED, &priv->status) && !priv->inta)
+               iwl_enable_interrupts(priv);
+
+       spin_unlock(&priv->lock);
+       return IRQ_NONE;
+}
+EXPORT_SYMBOL(iwl_isr_ict);
+
+
+static irqreturn_t iwl_isr(int irq, void *data)
+{
+       struct iwl_priv *priv = data;
+       u32 inta, inta_mask;
+#ifdef CONFIG_IWLWIFI_DEBUG
+       u32 inta_fh;
+#endif
+       if (!priv)
+               return IRQ_NONE;
+
+       spin_lock(&priv->lock);
+
+       /* Disable (but don't clear!) interrupts here to avoid
+        *    back-to-back ISRs and sporadic interrupts from our NIC.
+        * If we have something to service, the tasklet will re-enable ints.
+        * If we *don't* have something, we'll re-enable before leaving here. */
+       inta_mask = iwl_read32(priv, CSR_INT_MASK);  /* just for debug */
+       iwl_write32(priv, CSR_INT_MASK, 0x00000000);
+
+       /* Discover which interrupts are active/pending */
+       inta = iwl_read32(priv, CSR_INT);
+
+       /* Ignore interrupt if there's nothing in NIC to service.
+        * This may be due to IRQ shared with another device,
+        * or due to sporadic interrupts thrown from our NIC. */
+       if (!inta) {
+               IWL_DEBUG_ISR(priv, "Ignore interrupt, inta == 0\n");
+               goto none;
+       }
+
+       if ((inta == 0xFFFFFFFF) || ((inta & 0xFFFFFFF0) == 0xa5a5a5a0)) {
+               /* Hardware disappeared. It might have already raised
+                * an interrupt */
+               IWL_WARN(priv, "HARDWARE GONE?? INTA == 0x%08x\n", inta);
+               goto unplugged;
+       }
+
+#ifdef CONFIG_IWLWIFI_DEBUG
+       if (priv->debug_level & (IWL_DL_ISR)) {
+               inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS);
+               IWL_DEBUG_ISR(priv, "ISR inta 0x%08x, enabled 0x%08x, "
+                             "fh 0x%08x\n", inta, inta_mask, inta_fh);
+       }
+#endif
+
+       priv->inta |= inta;
+       /* iwl_irq_tasklet() will service interrupts and re-enable them */
+       if (likely(inta))
+               tasklet_schedule(&priv->irq_tasklet);
+       else if (test_bit(STATUS_INT_ENABLED, &priv->status) && !priv->inta)
+               iwl_enable_interrupts(priv);
+
+ unplugged:
+       spin_unlock(&priv->lock);
+       return IRQ_HANDLED;
+
+ none:
+       /* re-enable interrupts here since we don't have anything to service. */
+       /* only Re-enable if diabled by irq  and no schedules tasklet. */
+       if (test_bit(STATUS_INT_ENABLED, &priv->status) && !priv->inta)
+               iwl_enable_interrupts(priv);
+
+       spin_unlock(&priv->lock);
+       return IRQ_NONE;
+}
+
+irqreturn_t iwl_isr_legacy(int irq, void *data)
 {
        struct iwl_priv *priv = data;
        u32 inta, inta_mask;
@@ -1536,7 +1822,7 @@ irqreturn_t iwl_isr(int irq, void *data)
        spin_unlock(&priv->lock);
        return IRQ_NONE;
 }
-EXPORT_SYMBOL(iwl_isr);
+EXPORT_SYMBOL(iwl_isr_legacy);
 
 int iwl_send_bt_config(struct iwl_priv *priv)
 {
@@ -1580,10 +1866,6 @@ static int iwlcore_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32
 
        IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len);
 
-       ret = iwl_grab_nic_access(priv);
-       if (ret)
-               return ret;
-
        for (i = 0; i < len; i += 100, image += 100/sizeof(u32)) {
                /* read data comes through single port, auto-incr addr */
                /* NOTE: Use the debugless read so we don't flood kernel log
@@ -1599,8 +1881,6 @@ static int iwlcore_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32
                }
        }
 
-       iwl_release_nic_access(priv);
-
        return ret;
 }
 
@@ -1618,10 +1898,6 @@ static int iwl_verify_inst_full(struct iwl_priv *priv, __le32 *image,
 
        IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len);
 
-       ret = iwl_grab_nic_access(priv);
-       if (ret)
-               return ret;
-
        iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR,
                           IWL49_RTC_INST_LOWER_BOUND);
 
@@ -1642,8 +1918,6 @@ static int iwl_verify_inst_full(struct iwl_priv *priv, __le32 *image,
                }
        }
 
-       iwl_release_nic_access(priv);
-
        if (!errcnt)
                IWL_DEBUG_INFO(priv,
                    "ucode image in INSTRUCTION memory is good\n");
@@ -1752,7 +2026,6 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv)
        u32 data2, line;
        u32 desc, time, count, base, data1;
        u32 blink1, blink2, ilink1, ilink2;
-       int ret;
 
        if (priv->ucode_type == UCODE_INIT)
                base = le32_to_cpu(priv->card_alive_init.error_event_table_ptr);
@@ -1764,12 +2037,6 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv)
                return;
        }
 
-       ret = iwl_grab_nic_access(priv);
-       if (ret) {
-               IWL_WARN(priv, "Can not read from adapter at this time.\n");
-               return;
-       }
-
        count = iwl_read_targ_mem(priv, base);
 
        if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) {
@@ -1796,7 +2063,6 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv)
        IWL_ERR(priv, "0x%05X 0x%05X 0x%05X 0x%05X\n", blink1, blink2,
                ilink1, ilink2);
 
-       iwl_release_nic_access(priv);
 }
 EXPORT_SYMBOL(iwl_dump_nic_error_log);
 
@@ -1805,7 +2071,6 @@ EXPORT_SYMBOL(iwl_dump_nic_error_log);
 /**
  * iwl_print_event_log - Dump error event log to syslog
  *
- * NOTE: Must be called with iwl_grab_nic_access() already obtained!
  */
 static void iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
                                u32 num_events, u32 mode)
@@ -1851,7 +2116,6 @@ static void iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
 
 void iwl_dump_nic_event_log(struct iwl_priv *priv)
 {
-       int ret;
        u32 base;       /* SRAM byte address of event log header */
        u32 capacity;   /* event log capacity in # entries */
        u32 mode;       /* 0 - no timestamp, 1 - timestamp recorded */
@@ -1869,12 +2133,6 @@ void iwl_dump_nic_event_log(struct iwl_priv *priv)
                return;
        }
 
-       ret = iwl_grab_nic_access(priv);
-       if (ret) {
-               IWL_WARN(priv, "Can not read from adapter at this time.\n");
-               return;
-       }
-
        /* event log header */
        capacity = iwl_read_targ_mem(priv, base);
        mode = iwl_read_targ_mem(priv, base + (1 * sizeof(u32)));
@@ -1886,7 +2144,6 @@ void iwl_dump_nic_event_log(struct iwl_priv *priv)
        /* bail out if nothing in log */
        if (size == 0) {
                IWL_ERR(priv, "Start IWL Event Log Dump: nothing in log\n");
-               iwl_release_nic_access(priv);
                return;
        }
 
@@ -1901,7 +2158,6 @@ void iwl_dump_nic_event_log(struct iwl_priv *priv)
        /* (then/else) start at top of log */
        iwl_print_event_log(priv, 0, next_entry, mode);
 
-       iwl_release_nic_access(priv);
 }
 EXPORT_SYMBOL(iwl_dump_nic_event_log);
 
@@ -1954,161 +2210,680 @@ int iwl_send_card_state(struct iwl_priv *priv, u32 flags, u8 meta_flag)
 }
 EXPORT_SYMBOL(iwl_send_card_state);
 
-void iwl_radio_kill_sw_disable_radio(struct iwl_priv *priv)
+void iwl_rx_pm_sleep_notif(struct iwl_priv *priv,
+                          struct iwl_rx_mem_buffer *rxb)
 {
-       unsigned long flags;
+#ifdef CONFIG_IWLWIFI_DEBUG
+       struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
+       struct iwl_sleep_notification *sleep = &(pkt->u.sleep_notif);
+       IWL_DEBUG_RX(priv, "sleep mode: %d, src: %d\n",
+                    sleep->pm_sleep_mode, sleep->pm_wakeup_src);
+#endif
+}
+EXPORT_SYMBOL(iwl_rx_pm_sleep_notif);
 
-       if (test_bit(STATUS_RF_KILL_SW, &priv->status))
-               return;
+void iwl_rx_pm_debug_statistics_notif(struct iwl_priv *priv,
+                                     struct iwl_rx_mem_buffer *rxb)
+{
+       struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
+       IWL_DEBUG_RADIO(priv, "Dumping %d bytes of unhandled "
+                       "notification for %s:\n",
+                       le32_to_cpu(pkt->len), get_cmd_string(pkt->hdr.cmd));
+       iwl_print_hex_dump(priv, IWL_DL_RADIO, pkt->u.raw, le32_to_cpu(pkt->len));
+}
+EXPORT_SYMBOL(iwl_rx_pm_debug_statistics_notif);
 
-       IWL_DEBUG_RF_KILL(priv, "Manual SW RF KILL set to: RADIO OFF\n");
+void iwl_rx_reply_error(struct iwl_priv *priv,
+                       struct iwl_rx_mem_buffer *rxb)
+{
+       struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
 
-       iwl_scan_cancel(priv);
-       /* FIXME: This is a workaround for AP */
-       if (priv->iw_mode != NL80211_IFTYPE_AP) {
-               spin_lock_irqsave(&priv->lock, flags);
-               iwl_write32(priv, CSR_UCODE_DRV_GP1_SET,
-                           CSR_UCODE_SW_BIT_RFKILL);
-               spin_unlock_irqrestore(&priv->lock, flags);
-               /* call the host command only if no hw rf-kill set */
-               if (!test_bit(STATUS_RF_KILL_HW, &priv->status) &&
-                   iwl_is_ready(priv))
-                       iwl_send_card_state(priv,
-                               CARD_STATE_CMD_DISABLE, 0);
-               set_bit(STATUS_RF_KILL_SW, &priv->status);
-                       /* make sure mac80211 stop sending Tx frame */
-               if (priv->mac80211_registered)
-                       ieee80211_stop_queues(priv->hw);
-       }
+       IWL_ERR(priv, "Error Reply type 0x%08X cmd %s (0x%02X) "
+               "seq 0x%04X ser 0x%08X\n",
+               le32_to_cpu(pkt->u.err_resp.error_type),
+               get_cmd_string(pkt->u.err_resp.cmd_id),
+               pkt->u.err_resp.cmd_id,
+               le16_to_cpu(pkt->u.err_resp.bad_cmd_seq_num),
+               le32_to_cpu(pkt->u.err_resp.error_info));
 }
-EXPORT_SYMBOL(iwl_radio_kill_sw_disable_radio);
+EXPORT_SYMBOL(iwl_rx_reply_error);
+
+void iwl_clear_isr_stats(struct iwl_priv *priv)
+{
+       memset(&priv->isr_stats, 0, sizeof(priv->isr_stats));
+}
+EXPORT_SYMBOL(iwl_clear_isr_stats);
 
-int iwl_radio_kill_sw_enable_radio(struct iwl_priv *priv)
+int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
+                          const struct ieee80211_tx_queue_params *params)
 {
+       struct iwl_priv *priv = hw->priv;
        unsigned long flags;
+       int q;
+
+       IWL_DEBUG_MAC80211(priv, "enter\n");
+
+       if (!iwl_is_ready_rf(priv)) {
+               IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
+               return -EIO;
+       }
 
-       if (!test_bit(STATUS_RF_KILL_SW, &priv->status))
+       if (queue >= AC_NUM) {
+               IWL_DEBUG_MAC80211(priv, "leave - queue >= AC_NUM %d\n", queue);
                return 0;
+       }
 
-       IWL_DEBUG_RF_KILL(priv, "Manual SW RF KILL set to: RADIO ON\n");
+       q = AC_NUM - 1 - queue;
 
        spin_lock_irqsave(&priv->lock, flags);
-       iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
 
-       /* If the driver is up it will receive CARD_STATE_NOTIFICATION
-        * notification where it will clear SW rfkill status.
-        * Setting it here would break the handler. Only if the
-        * interface is down we can set here since we don't
-        * receive any further notification.
-        */
-       if (!priv->is_open)
-               clear_bit(STATUS_RF_KILL_SW, &priv->status);
-       spin_unlock_irqrestore(&priv->lock, flags);
+       priv->qos_data.def_qos_parm.ac[q].cw_min = cpu_to_le16(params->cw_min);
+       priv->qos_data.def_qos_parm.ac[q].cw_max = cpu_to_le16(params->cw_max);
+       priv->qos_data.def_qos_parm.ac[q].aifsn = params->aifs;
+       priv->qos_data.def_qos_parm.ac[q].edca_txop =
+                       cpu_to_le16((params->txop * 32));
 
-       /* wake up ucode */
-       msleep(10);
+       priv->qos_data.def_qos_parm.ac[q].reserved1 = 0;
+       priv->qos_data.qos_active = 1;
+
+       if (priv->iw_mode == NL80211_IFTYPE_AP)
+               iwl_activate_qos(priv, 1);
+       else if (priv->assoc_id && iwl_is_associated(priv))
+               iwl_activate_qos(priv, 0);
 
-       spin_lock_irqsave(&priv->lock, flags);
-       iwl_read32(priv, CSR_UCODE_DRV_GP1);
-       if (!iwl_grab_nic_access(priv))
-               iwl_release_nic_access(priv);
        spin_unlock_irqrestore(&priv->lock, flags);
 
-       if (test_bit(STATUS_RF_KILL_HW, &priv->status)) {
-               IWL_DEBUG_RF_KILL(priv, "Can not turn radio back on - "
-                                 "disabled by HW switch\n");
-               return 0;
-       }
+       IWL_DEBUG_MAC80211(priv, "leave\n");
+       return 0;
+}
+EXPORT_SYMBOL(iwl_mac_conf_tx);
+
+static void iwl_ht_conf(struct iwl_priv *priv,
+                           struct ieee80211_bss_conf *bss_conf)
+{
+       struct ieee80211_sta_ht_cap *ht_conf;
+       struct iwl_ht_info *iwl_conf = &priv->current_ht_config;
+       struct ieee80211_sta *sta;
+
+       IWL_DEBUG_MAC80211(priv, "enter: \n");
+
+       if (!iwl_conf->is_ht)
+               return;
+
 
-       /* when driver is up while rfkill is on, it wont receive
-        * any CARD_STATE_NOTIFICATION notifications so we have to
-        * restart it in here
+       /*
+        * It is totally wrong to base global information on something
+        * that is valid only when associated, alas, this driver works
+        * that way and I don't know how to fix it.
         */
-       if (priv->is_open && !test_bit(STATUS_ALIVE, &priv->status)) {
-               clear_bit(STATUS_RF_KILL_SW, &priv->status);
-               if (!iwl_is_rfkill(priv))
-                       queue_work(priv->workqueue, &priv->up);
+
+       rcu_read_lock();
+       sta = ieee80211_find_sta(priv->hw, priv->bssid);
+       if (!sta) {
+               rcu_read_unlock();
+               return;
        }
+       ht_conf = &sta->ht_cap;
+
+       if (ht_conf->cap & IEEE80211_HT_CAP_SGI_20)
+               iwl_conf->sgf |= HT_SHORT_GI_20MHZ;
+       if (ht_conf->cap & IEEE80211_HT_CAP_SGI_40)
+               iwl_conf->sgf |= HT_SHORT_GI_40MHZ;
 
-       /* If the driver is already loaded, it will receive
-        * CARD_STATE_NOTIFICATION notifications and the handler will
-        * call restart to reload the driver.
+       iwl_conf->is_green_field = !!(ht_conf->cap & IEEE80211_HT_CAP_GRN_FLD);
+       iwl_conf->max_amsdu_size =
+               !!(ht_conf->cap & IEEE80211_HT_CAP_MAX_AMSDU);
+
+       iwl_conf->supported_chan_width =
+               !!(ht_conf->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40);
+
+       /*
+        * XXX: The HT configuration needs to be moved into iwl_mac_config()
+        *      to be done there correctly.
         */
-       return 1;
+
+       iwl_conf->extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_NONE;
+       if (conf_is_ht40_minus(&priv->hw->conf))
+               iwl_conf->extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_BELOW;
+       else if (conf_is_ht40_plus(&priv->hw->conf))
+               iwl_conf->extension_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
+
+       /* If no above or below channel supplied disable FAT channel */
+       if (iwl_conf->extension_chan_offset != IEEE80211_HT_PARAM_CHA_SEC_ABOVE &&
+           iwl_conf->extension_chan_offset != IEEE80211_HT_PARAM_CHA_SEC_BELOW)
+               iwl_conf->supported_chan_width = 0;
+
+       iwl_conf->sm_ps = (u8)((ht_conf->cap & IEEE80211_HT_CAP_SM_PS) >> 2);
+
+       memcpy(&iwl_conf->mcs, &ht_conf->mcs, 16);
+
+       iwl_conf->tx_chan_width = iwl_conf->supported_chan_width != 0;
+       iwl_conf->ht_protection =
+               bss_conf->ht_operation_mode & IEEE80211_HT_OP_MODE_PROTECTION;
+       iwl_conf->non_GF_STA_present =
+               !!(bss_conf->ht_operation_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
+
+       rcu_read_unlock();
+
+       IWL_DEBUG_MAC80211(priv, "leave\n");
 }
-EXPORT_SYMBOL(iwl_radio_kill_sw_enable_radio);
 
-void iwl_bg_rf_kill(struct work_struct *work)
+#define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6)
+void iwl_bss_info_changed(struct ieee80211_hw *hw,
+                         struct ieee80211_vif *vif,
+                         struct ieee80211_bss_conf *bss_conf,
+                         u32 changes)
 {
-       struct iwl_priv *priv = container_of(work, struct iwl_priv, rf_kill);
+       struct iwl_priv *priv = hw->priv;
+       int ret;
 
-       wake_up_interruptible(&priv->wait_command_queue);
+       IWL_DEBUG_MAC80211(priv, "changes = 0x%X\n", changes);
 
-       if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+       if (!iwl_is_alive(priv))
                return;
 
        mutex_lock(&priv->mutex);
 
-       if (!iwl_is_rfkill(priv)) {
-               IWL_DEBUG_RF_KILL(priv,
-                         "HW and/or SW RF Kill no longer active, restarting "
-                         "device\n");
-               if (!test_bit(STATUS_EXIT_PENDING, &priv->status) &&
-                   test_bit(STATUS_ALIVE, &priv->status))
-                       queue_work(priv->workqueue, &priv->restart);
-       } else {
-               /* make sure mac80211 stop sending Tx frame */
-               if (priv->mac80211_registered)
-                       ieee80211_stop_queues(priv->hw);
+       if (changes & BSS_CHANGED_BEACON &&
+           priv->iw_mode == NL80211_IFTYPE_AP) {
+               dev_kfree_skb(priv->ibss_beacon);
+               priv->ibss_beacon = ieee80211_beacon_get(hw, vif);
+       }
+
+       if ((changes & BSS_CHANGED_BSSID) && !iwl_is_rfkill(priv)) {
+               /* If there is currently a HW scan going on in the background
+                * then we need to cancel it else the RXON below will fail. */
+               if (iwl_scan_cancel_timeout(priv, 100)) {
+                       IWL_WARN(priv, "Aborted scan still in progress "
+                                   "after 100ms\n");
+                       IWL_DEBUG_MAC80211(priv, "leaving - scan abort failed.\n");
+                       mutex_unlock(&priv->mutex);
+                       return;
+               }
+               memcpy(priv->staging_rxon.bssid_addr,
+                      bss_conf->bssid, ETH_ALEN);
+
+               /* TODO: Audit driver for usage of these members and see
+                * if mac80211 deprecates them (priv->bssid looks like it
+                * shouldn't be there, but I haven't scanned the IBSS code
+                * to verify) - jpk */
+               memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN);
+
+               if (priv->iw_mode == NL80211_IFTYPE_AP)
+                       iwlcore_config_ap(priv);
+               else {
+                       int rc = iwlcore_commit_rxon(priv);
+                       if ((priv->iw_mode == NL80211_IFTYPE_STATION) && rc)
+                               iwl_rxon_add_station(
+                                       priv, priv->active_rxon.bssid_addr, 1);
+               }
+       } else if (!iwl_is_rfkill(priv)) {
+               iwl_scan_cancel_timeout(priv, 100);
+               priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+               iwlcore_commit_rxon(priv);
+       }
+
+       if (priv->iw_mode == NL80211_IFTYPE_ADHOC &&
+           changes & BSS_CHANGED_BEACON) {
+               struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
+
+               if (beacon)
+                       iwl_mac_beacon_update(hw, beacon);
+       }
 
-               if (!test_bit(STATUS_RF_KILL_HW, &priv->status))
-                       IWL_DEBUG_RF_KILL(priv, "Can not turn radio back on - "
-                                         "disabled by SW switch\n");
+       mutex_unlock(&priv->mutex);
+
+       if (changes & BSS_CHANGED_ERP_PREAMBLE) {
+               IWL_DEBUG_MAC80211(priv, "ERP_PREAMBLE %d\n",
+                                  bss_conf->use_short_preamble);
+               if (bss_conf->use_short_preamble)
+                       priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
                else
-                       IWL_WARN(priv, "Radio Frequency Kill Switch is On:\n"
-                                   "Kill switch must be turned off for "
-                                   "wireless networking to work.\n");
+                       priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
+       }
+
+       if (changes & BSS_CHANGED_ERP_CTS_PROT) {
+               IWL_DEBUG_MAC80211(priv, "ERP_CTS %d\n", bss_conf->use_cts_prot);
+               if (bss_conf->use_cts_prot && (priv->band != IEEE80211_BAND_5GHZ))
+                       priv->staging_rxon.flags |= RXON_FLG_TGG_PROTECT_MSK;
+               else
+                       priv->staging_rxon.flags &= ~RXON_FLG_TGG_PROTECT_MSK;
+       }
+
+       if (changes & BSS_CHANGED_HT) {
+               iwl_ht_conf(priv, bss_conf);
+
+               if (priv->cfg->ops->hcmd->set_rxon_chain)
+                       priv->cfg->ops->hcmd->set_rxon_chain(priv);
+       }
+
+       if (changes & BSS_CHANGED_ASSOC) {
+               IWL_DEBUG_MAC80211(priv, "ASSOC %d\n", bss_conf->assoc);
+               /* This should never happen as this function should
+                * never be called from interrupt context. */
+               if (WARN_ON_ONCE(in_interrupt()))
+                       return;
+               if (bss_conf->assoc) {
+                       priv->assoc_id = bss_conf->aid;
+                       priv->beacon_int = bss_conf->beacon_int;
+                       priv->power_data.dtim_period = bss_conf->dtim_period;
+                       priv->timestamp = bss_conf->timestamp;
+                       priv->assoc_capability = bss_conf->assoc_capability;
+
+                       /* we have just associated, don't start scan too early
+                        * leave time for EAPOL exchange to complete
+                        */
+                       priv->next_scan_jiffies = jiffies +
+                                       IWL_DELAY_NEXT_SCAN_AFTER_ASSOC;
+                       mutex_lock(&priv->mutex);
+                       priv->cfg->ops->lib->post_associate(priv);
+                       mutex_unlock(&priv->mutex);
+               } else {
+                       priv->assoc_id = 0;
+                       IWL_DEBUG_MAC80211(priv, "DISASSOC %d\n", bss_conf->assoc);
+               }
+       } else if (changes && iwl_is_associated(priv) && priv->assoc_id) {
+                       IWL_DEBUG_MAC80211(priv, "Associated Changes %d\n", changes);
+                       ret = iwl_send_rxon_assoc(priv);
+                       if (!ret)
+                               /* Sync active_rxon with latest change. */
+                               memcpy((void *)&priv->active_rxon,
+                                       &priv->staging_rxon,
+                                       sizeof(struct iwl_rxon_cmd));
+       }
+       IWL_DEBUG_MAC80211(priv, "leave\n");
+}
+EXPORT_SYMBOL(iwl_bss_info_changed);
+
+int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
+{
+       struct iwl_priv *priv = hw->priv;
+       unsigned long flags;
+       __le64 timestamp;
+
+       IWL_DEBUG_MAC80211(priv, "enter\n");
+
+       if (!iwl_is_ready_rf(priv)) {
+               IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
+               return -EIO;
+       }
+
+       if (priv->iw_mode != NL80211_IFTYPE_ADHOC) {
+               IWL_DEBUG_MAC80211(priv, "leave - not IBSS\n");
+               return -EIO;
+       }
+
+       spin_lock_irqsave(&priv->lock, flags);
+
+       if (priv->ibss_beacon)
+               dev_kfree_skb(priv->ibss_beacon);
+
+       priv->ibss_beacon = skb;
+
+       priv->assoc_id = 0;
+       timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp;
+       priv->timestamp = le64_to_cpu(timestamp);
+
+       IWL_DEBUG_MAC80211(priv, "leave\n");
+       spin_unlock_irqrestore(&priv->lock, flags);
+
+       iwl_reset_qos(priv);
+
+       priv->cfg->ops->lib->post_associate(priv);
+
+
+       return 0;
+}
+EXPORT_SYMBOL(iwl_mac_beacon_update);
+
+int iwl_set_mode(struct iwl_priv *priv, int mode)
+{
+       if (mode == NL80211_IFTYPE_ADHOC) {
+               const struct iwl_channel_info *ch_info;
+
+               ch_info = iwl_get_channel_info(priv,
+                       priv->band,
+                       le16_to_cpu(priv->staging_rxon.channel));
+
+               if (!ch_info || !is_channel_ibss(ch_info)) {
+                       IWL_ERR(priv, "channel %d not IBSS channel\n",
+                                 le16_to_cpu(priv->staging_rxon.channel));
+                       return -EINVAL;
+               }
+       }
+
+       iwl_connection_init_rx_config(priv, mode);
+
+       if (priv->cfg->ops->hcmd->set_rxon_chain)
+               priv->cfg->ops->hcmd->set_rxon_chain(priv);
+
+       memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN);
+
+       iwl_clear_stations_table(priv);
+
+       /* dont commit rxon if rf-kill is on*/
+       if (!iwl_is_ready_rf(priv))
+               return -EAGAIN;
+
+       iwlcore_commit_rxon(priv);
+
+       return 0;
+}
+EXPORT_SYMBOL(iwl_set_mode);
+
+int iwl_mac_add_interface(struct ieee80211_hw *hw,
+                                struct ieee80211_if_init_conf *conf)
+{
+       struct iwl_priv *priv = hw->priv;
+       unsigned long flags;
+
+       IWL_DEBUG_MAC80211(priv, "enter: type %d\n", conf->type);
+
+       if (priv->vif) {
+               IWL_DEBUG_MAC80211(priv, "leave - vif != NULL\n");
+               return -EOPNOTSUPP;
        }
+
+       spin_lock_irqsave(&priv->lock, flags);
+       priv->vif = conf->vif;
+       priv->iw_mode = conf->type;
+
+       spin_unlock_irqrestore(&priv->lock, flags);
+
+       mutex_lock(&priv->mutex);
+
+       if (conf->mac_addr) {
+               IWL_DEBUG_MAC80211(priv, "Set %pM\n", conf->mac_addr);
+               memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN);
+       }
+
+       if (iwl_set_mode(priv, conf->type) == -EAGAIN)
+               /* we are not ready, will run again when ready */
+               set_bit(STATUS_MODE_PENDING, &priv->status);
+
        mutex_unlock(&priv->mutex);
-       iwl_rfkill_set_hw_state(priv);
+
+       IWL_DEBUG_MAC80211(priv, "leave\n");
+       return 0;
 }
-EXPORT_SYMBOL(iwl_bg_rf_kill);
+EXPORT_SYMBOL(iwl_mac_add_interface);
 
-void iwl_rx_pm_sleep_notif(struct iwl_priv *priv,
-                          struct iwl_rx_mem_buffer *rxb)
+void iwl_mac_remove_interface(struct ieee80211_hw *hw,
+                                    struct ieee80211_if_init_conf *conf)
 {
-#ifdef CONFIG_IWLWIFI_DEBUG
-       struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
-       struct iwl_sleep_notification *sleep = &(pkt->u.sleep_notif);
-       IWL_DEBUG_RX(priv, "sleep mode: %d, src: %d\n",
-                    sleep->pm_sleep_mode, sleep->pm_wakeup_src);
-#endif
+       struct iwl_priv *priv = hw->priv;
+
+       IWL_DEBUG_MAC80211(priv, "enter\n");
+
+       mutex_lock(&priv->mutex);
+
+       if (iwl_is_ready_rf(priv)) {
+               iwl_scan_cancel_timeout(priv, 100);
+               priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+               iwlcore_commit_rxon(priv);
+       }
+       if (priv->vif == conf->vif) {
+               priv->vif = NULL;
+               memset(priv->bssid, 0, ETH_ALEN);
+       }
+       mutex_unlock(&priv->mutex);
+
+       IWL_DEBUG_MAC80211(priv, "leave\n");
+
 }
-EXPORT_SYMBOL(iwl_rx_pm_sleep_notif);
+EXPORT_SYMBOL(iwl_mac_remove_interface);
 
-void iwl_rx_pm_debug_statistics_notif(struct iwl_priv *priv,
-                                     struct iwl_rx_mem_buffer *rxb)
+/**
+ * iwl_mac_config - mac80211 config callback
+ *
+ * We ignore conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME since it seems to
+ * be set inappropriately and the driver currently sets the hardware up to
+ * use it whenever needed.
+ */
+int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
 {
-       struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
-       IWL_DEBUG_RADIO(priv, "Dumping %d bytes of unhandled "
-                       "notification for %s:\n",
-                       le32_to_cpu(pkt->len), get_cmd_string(pkt->hdr.cmd));
-       iwl_print_hex_dump(priv, IWL_DL_RADIO, pkt->u.raw, le32_to_cpu(pkt->len));
+       struct iwl_priv *priv = hw->priv;
+       const struct iwl_channel_info *ch_info;
+       struct ieee80211_conf *conf = &hw->conf;
+       unsigned long flags = 0;
+       int ret = 0;
+       u16 ch;
+       int scan_active = 0;
+
+       mutex_lock(&priv->mutex);
+
+       IWL_DEBUG_MAC80211(priv, "enter to channel %d changed 0x%X\n",
+                                       conf->channel->hw_value, changed);
+
+       if (unlikely(!priv->cfg->mod_params->disable_hw_scan &&
+                       test_bit(STATUS_SCANNING, &priv->status))) {
+               scan_active = 1;
+               IWL_DEBUG_MAC80211(priv, "leave - scanning\n");
+       }
+
+
+       /* during scanning mac80211 will delay channel setting until
+        * scan finish with changed = 0
+        */
+       if (!changed || (changed & IEEE80211_CONF_CHANGE_CHANNEL)) {
+               if (scan_active)
+                       goto set_ch_out;
+
+               ch = ieee80211_frequency_to_channel(conf->channel->center_freq);
+               ch_info = iwl_get_channel_info(priv, conf->channel->band, ch);
+               if (!is_channel_valid(ch_info)) {
+                       IWL_DEBUG_MAC80211(priv, "leave - invalid channel\n");
+                       ret = -EINVAL;
+                       goto set_ch_out;
+               }
+
+               if (priv->iw_mode == NL80211_IFTYPE_ADHOC &&
+                       !is_channel_ibss(ch_info)) {
+                       IWL_ERR(priv, "channel %d in band %d not "
+                               "IBSS channel\n",
+                               conf->channel->hw_value, conf->channel->band);
+                       ret = -EINVAL;
+                       goto set_ch_out;
+               }
+
+               priv->current_ht_config.is_ht = conf_is_ht(conf);
+
+               spin_lock_irqsave(&priv->lock, flags);
+
+
+               /* if we are switching from ht to 2.4 clear flags
+                * from any ht related info since 2.4 does not
+                * support ht */
+               if ((le16_to_cpu(priv->staging_rxon.channel) != ch))
+                       priv->staging_rxon.flags = 0;
+
+               iwl_set_rxon_channel(priv, conf->channel);
+
+               iwl_set_flags_for_band(priv, conf->channel->band);
+               spin_unlock_irqrestore(&priv->lock, flags);
+ set_ch_out:
+               /* The list of supported rates and rate mask can be different
+                * for each band; since the band may have changed, reset
+                * the rate mask to what mac80211 lists */
+               iwl_set_rate(priv);
+       }
+
+       if (changed & IEEE80211_CONF_CHANGE_PS &&
+           priv->iw_mode == NL80211_IFTYPE_STATION) {
+               priv->power_data.power_disabled =
+                       !(conf->flags & IEEE80211_CONF_PS);
+               ret = iwl_power_update_mode(priv, 0);
+               if (ret)
+                       IWL_DEBUG_MAC80211(priv, "Error setting power level\n");
+       }
+
+       if (changed & IEEE80211_CONF_CHANGE_POWER) {
+               IWL_DEBUG_MAC80211(priv, "TX Power old=%d new=%d\n",
+                       priv->tx_power_user_lmt, conf->power_level);
+
+               iwl_set_tx_power(priv, conf->power_level, false);
+       }
+
+       /* call to ensure that 4965 rx_chain is set properly in monitor mode */
+       if (priv->cfg->ops->hcmd->set_rxon_chain)
+               priv->cfg->ops->hcmd->set_rxon_chain(priv);
+
+       if (!iwl_is_ready(priv)) {
+               IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
+               goto out;
+       }
+
+       if (scan_active)
+               goto out;
+
+       if (memcmp(&priv->active_rxon,
+                  &priv->staging_rxon, sizeof(priv->staging_rxon)))
+               iwlcore_commit_rxon(priv);
+       else
+               IWL_DEBUG_INFO(priv, "Not re-sending same RXON configuration.\n");
+
+
+out:
+       IWL_DEBUG_MAC80211(priv, "leave\n");
+       mutex_unlock(&priv->mutex);
+       return ret;
 }
-EXPORT_SYMBOL(iwl_rx_pm_debug_statistics_notif);
+EXPORT_SYMBOL(iwl_mac_config);
 
-void iwl_rx_reply_error(struct iwl_priv *priv,
-                       struct iwl_rx_mem_buffer *rxb)
+int iwl_mac_get_tx_stats(struct ieee80211_hw *hw,
+                        struct ieee80211_tx_queue_stats *stats)
 {
-       struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
+       struct iwl_priv *priv = hw->priv;
+       int i, avail;
+       struct iwl_tx_queue *txq;
+       struct iwl_queue *q;
+       unsigned long flags;
 
-       IWL_ERR(priv, "Error Reply type 0x%08X cmd %s (0x%02X) "
-               "seq 0x%04X ser 0x%08X\n",
-               le32_to_cpu(pkt->u.err_resp.error_type),
-               get_cmd_string(pkt->u.err_resp.cmd_id),
-               pkt->u.err_resp.cmd_id,
-               le16_to_cpu(pkt->u.err_resp.bad_cmd_seq_num),
-               le32_to_cpu(pkt->u.err_resp.error_info));
+       IWL_DEBUG_MAC80211(priv, "enter\n");
+
+       if (!iwl_is_ready_rf(priv)) {
+               IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
+               return -EIO;
+       }
+
+       spin_lock_irqsave(&priv->lock, flags);
+
+       for (i = 0; i < AC_NUM; i++) {
+               txq = &priv->txq[i];
+               q = &txq->q;
+               avail = iwl_queue_space(q);
+
+               stats[i].len = q->n_window - avail;
+               stats[i].limit = q->n_window - q->high_mark;
+               stats[i].count = q->n_window;
+
+       }
+       spin_unlock_irqrestore(&priv->lock, flags);
+
+       IWL_DEBUG_MAC80211(priv, "leave\n");
+
+       return 0;
 }
-EXPORT_SYMBOL(iwl_rx_reply_error);
+EXPORT_SYMBOL(iwl_mac_get_tx_stats);
+
+void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
+{
+       struct iwl_priv *priv = hw->priv;
+       unsigned long flags;
+
+       mutex_lock(&priv->mutex);
+       IWL_DEBUG_MAC80211(priv, "enter\n");
+
+       spin_lock_irqsave(&priv->lock, flags);
+       memset(&priv->current_ht_config, 0, sizeof(struct iwl_ht_info));
+       spin_unlock_irqrestore(&priv->lock, flags);
+
+       iwl_reset_qos(priv);
+
+       spin_lock_irqsave(&priv->lock, flags);
+       priv->assoc_id = 0;
+       priv->assoc_capability = 0;
+       priv->assoc_station_added = 0;
+
+       /* new association get rid of ibss beacon skb */
+       if (priv->ibss_beacon)
+               dev_kfree_skb(priv->ibss_beacon);
+
+       priv->ibss_beacon = NULL;
+
+       priv->beacon_int = priv->vif->bss_conf.beacon_int;
+       priv->timestamp = 0;
+       if ((priv->iw_mode == NL80211_IFTYPE_STATION))
+               priv->beacon_int = 0;
+
+       spin_unlock_irqrestore(&priv->lock, flags);
+
+       if (!iwl_is_ready_rf(priv)) {
+               IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
+               mutex_unlock(&priv->mutex);
+               return;
+       }
+
+       /* we are restarting association process
+        * clear RXON_FILTER_ASSOC_MSK bit
+        */
+       if (priv->iw_mode != NL80211_IFTYPE_AP) {
+               iwl_scan_cancel_timeout(priv, 100);
+               priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+               iwlcore_commit_rxon(priv);
+       }
+
+       if (priv->iw_mode != NL80211_IFTYPE_ADHOC) {
+               IWL_DEBUG_MAC80211(priv, "leave - not in IBSS\n");
+               mutex_unlock(&priv->mutex);
+               return;
+       }
+
+       iwl_set_rate(priv);
+
+       mutex_unlock(&priv->mutex);
+
+       IWL_DEBUG_MAC80211(priv, "leave\n");
+}
+EXPORT_SYMBOL(iwl_mac_reset_tsf);
+
+#ifdef CONFIG_PM
+
+int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+       struct iwl_priv *priv = pci_get_drvdata(pdev);
+
+       /*
+        * This function is called when system goes into suspend state
+        * mac80211 will call iwl_mac_stop() from the mac80211 suspend function
+        * first but since iwl_mac_stop() has no knowledge of who the caller is,
+        * it will not call apm_ops.stop() to stop the DMA operation.
+        * Calling apm_ops.stop here to make sure we stop the DMA.
+        */
+       priv->cfg->ops->lib->apm_ops.stop(priv);
+
+       pci_save_state(pdev);
+       pci_disable_device(pdev);
+       pci_set_power_state(pdev, PCI_D3hot);
+
+       return 0;
+}
+EXPORT_SYMBOL(iwl_pci_suspend);
+
+int iwl_pci_resume(struct pci_dev *pdev)
+{
+       struct iwl_priv *priv = pci_get_drvdata(pdev);
+       int ret;
+
+       pci_set_power_state(pdev, PCI_D0);
+       ret = pci_enable_device(pdev);
+       if (ret)
+               return ret;
+       pci_restore_state(pdev);
+       iwl_enable_interrupts(priv);
+
+       return 0;
+}
+EXPORT_SYMBOL(iwl_pci_resume);
 
+#endif /* CONFIG_PM */
index a8eac8c3c1fa8e89c68b6f19f996cc2f2b63444a..dabf663e36e54d90e30c9f3a8aa1886d9fcc2055 100644 (file)
@@ -85,7 +85,10 @@ struct iwl_cmd;
 
 struct iwl_hcmd_ops {
        int (*rxon_assoc)(struct iwl_priv *priv);
+       int (*commit_rxon)(struct iwl_priv *priv);
+       void (*set_rxon_chain)(struct iwl_priv *priv);
 };
+
 struct iwl_hcmd_utils_ops {
        u16 (*get_hcmd_size)(u8 cmd_id, u16 len);
        u16 (*build_addsta_hcmd)(const struct iwl_addsta_cmd *cmd, u8 *data);
@@ -100,6 +103,19 @@ struct iwl_hcmd_utils_ops {
                          struct iwl_rx_phy_res *rx_resp);
 };
 
+struct iwl_apm_ops {
+       int (*init)(struct iwl_priv *priv);
+       int (*reset)(struct iwl_priv *priv);
+       void (*stop)(struct iwl_priv *priv);
+       void (*config)(struct iwl_priv *priv);
+       int (*set_pwr_src)(struct iwl_priv *priv, enum iwl_pwr_src src);
+};
+
+struct iwl_temp_ops {
+       void (*temperature)(struct iwl_priv *priv);
+       void (*set_ct_kill)(struct iwl_priv *priv);
+};
+
 struct iwl_lib_ops {
        /* set hw dependent parameters */
        int (*set_hw_params)(struct iwl_priv *priv);
@@ -137,20 +153,21 @@ struct iwl_lib_ops {
        int (*is_valid_rtc_data_addr)(u32 addr);
        /* 1st ucode load */
        int (*load_ucode)(struct iwl_priv *priv);
-        /* power management */
-       struct {
-               int (*init)(struct iwl_priv *priv);
-               int (*reset)(struct iwl_priv *priv);
-               void (*stop)(struct iwl_priv *priv);
-               void (*config)(struct iwl_priv *priv);
-               int (*set_pwr_src)(struct iwl_priv *priv, enum iwl_pwr_src src);
-       } apm_ops;
+       /* power management */
+       struct iwl_apm_ops apm_ops;
+
        /* power */
        int (*send_tx_power) (struct iwl_priv *priv);
        void (*update_chain_flags)(struct iwl_priv *priv);
-       void (*temperature) (struct iwl_priv *priv);
+       void (*post_associate) (struct iwl_priv *priv);
+       void (*config_ap) (struct iwl_priv *priv);
+       irqreturn_t (*isr) (int irq, void *data);
+
        /* eeprom operations (as defined in iwl-eeprom.h) */
        struct iwl_eeprom_ops eeprom_ops;
+
+       /* temperature */
+       struct iwl_temp_ops temp_ops;
 };
 
 struct iwl_ops {
@@ -160,13 +177,12 @@ struct iwl_ops {
 };
 
 struct iwl_mod_params {
-       int disable;            /* def: 0 = enable radio */
        int sw_crypto;          /* def: 0 = using hardware encryption */
        u32 debug;              /* def: 0 = minimal debug log messages */
        int disable_hw_scan;    /* def: 0 = use h/w scan */
        int num_of_queues;      /* def: HW dependent */
        int num_of_ampdu_queues;/* def: HW dependent */
-       int disable_11n;        /* def: 0 = disable 11n capabilities */
+       int disable_11n;        /* def: 0 = 11n capabilities enabled */
        int amsdu_size_8K;      /* def: 1 = enable 8K amsdu size */
        int antenna;            /* def: 0 = both antennas (use diversity) */
        int restart_fw;         /* def: 1 = restart firmware */
@@ -214,6 +230,7 @@ struct iwl_cfg {
        u8   valid_tx_ant;
        u8   valid_rx_ant;
        bool need_pll_cfg;
+       bool use_isr_legacy;
 };
 
 /***************************
@@ -225,6 +242,8 @@ struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg,
 void iwl_hw_detect(struct iwl_priv *priv);
 void iwl_reset_qos(struct iwl_priv *priv);
 void iwl_activate_qos(struct iwl_priv *priv, u8 force);
+int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
+                   const struct ieee80211_tx_queue_params *params);
 void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, int hw_decrypt);
 int iwl_check_rxon_cmd(struct iwl_priv *priv);
 int iwl_full_rxon_required(struct iwl_priv *priv);
@@ -249,6 +268,24 @@ int iwl_setup_mac(struct iwl_priv *priv);
 int iwl_set_hw_params(struct iwl_priv *priv);
 int iwl_init_drv(struct iwl_priv *priv);
 void iwl_uninit_drv(struct iwl_priv *priv);
+bool iwl_is_monitor_mode(struct iwl_priv *priv);
+void iwl_post_associate(struct iwl_priv *priv);
+void iwl_bss_info_changed(struct ieee80211_hw *hw,
+                                    struct ieee80211_vif *vif,
+                                    struct ieee80211_bss_conf *bss_conf,
+                                    u32 changes);
+int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb);
+int iwl_commit_rxon(struct iwl_priv *priv);
+int iwl_set_mode(struct iwl_priv *priv, int mode);
+int iwl_mac_add_interface(struct ieee80211_hw *hw,
+                                struct ieee80211_if_init_conf *conf);
+void iwl_mac_remove_interface(struct ieee80211_hw *hw,
+                                struct ieee80211_if_init_conf *conf);
+int iwl_mac_config(struct ieee80211_hw *hw, u32 changed);
+void iwl_config_ap(struct iwl_priv *priv);
+int iwl_mac_get_tx_stats(struct ieee80211_hw *hw,
+                        struct ieee80211_tx_queue_stats *stats);
+void iwl_mac_reset_tsf(struct ieee80211_hw *hw);
 
 /*****************************************************
  * RX handlers.
@@ -271,10 +308,11 @@ int iwl_rx_queue_update_write_ptr(struct iwl_priv *priv,
                                  struct iwl_rx_queue *q);
 void iwl_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq);
 void iwl_rx_replenish(struct iwl_priv *priv);
+void iwl_rx_replenish_now(struct iwl_priv *priv);
 int iwl_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq);
 int iwl_rx_queue_restock(struct iwl_priv *priv);
 int iwl_rx_queue_space(const struct iwl_rx_queue *q);
-void iwl_rx_allocate(struct iwl_priv *priv);
+void iwl_rx_allocate(struct iwl_priv *priv, gfp_t priority);
 void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb);
 int iwl_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index);
 /* Handlers */
@@ -310,14 +348,6 @@ int iwl_txq_check_empty(struct iwl_priv *priv, int sta_id, u8 tid, int txq_id);
  ****************************************************/
 int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force);
 
-/*****************************************************
- * RF -Kill - here and not in iwl-rfkill.h to be available when
- * RF-kill subsystem is not compiled.
- ****************************************************/
-void iwl_bg_rf_kill(struct work_struct *work);
-void iwl_radio_kill_sw_disable_radio(struct iwl_priv *priv);
-int iwl_radio_kill_sw_enable_radio(struct iwl_priv *priv);
-
 /*******************************************************************************
  * Rate
  ******************************************************************************/
@@ -328,8 +358,6 @@ int iwl_hwrate_to_plcp_idx(u32 rate_n_flags);
 
 u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv);
 
-void iwl_set_rate(struct iwl_priv *priv);
-
 u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant_idx);
 
 static inline u32 iwl_ant_idx_to_flags(u8 ant_idx)
@@ -358,8 +386,8 @@ int iwl_scan_cancel(struct iwl_priv *priv);
 int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms);
 int iwl_scan_initiate(struct iwl_priv *priv);
 int iwl_mac_hw_scan(struct ieee80211_hw *hw, struct cfg80211_scan_request *req);
-u16 iwl_fill_probe_req(struct iwl_priv *priv, enum ieee80211_band band,
-                      struct ieee80211_mgmt *frame, int left);
+u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame,
+                      const u8 *ie, int ie_len, int left);
 void iwl_setup_rx_scan_handlers(struct iwl_priv *priv);
 u16 iwl_get_active_dwell_time(struct iwl_priv *priv,
                              enum ieee80211_band band,
@@ -423,7 +451,13 @@ int iwl_send_card_state(struct iwl_priv *priv, u32 flags,
  *****************************************************/
 void iwl_disable_interrupts(struct iwl_priv *priv);
 void iwl_enable_interrupts(struct iwl_priv *priv);
-irqreturn_t iwl_isr(int irq, void *data);
+irqreturn_t iwl_isr_legacy(int irq, void *data);
+int iwl_reset_ict(struct iwl_priv *priv);
+void iwl_disable_ict(struct iwl_priv *priv);
+int iwl_alloc_isr_ict(struct iwl_priv *priv);
+void iwl_free_isr_ict(struct iwl_priv *priv);
+irqreturn_t iwl_isr_ict(int irq, void *data);
+
 static inline u16 iwl_pcie_link_ctl(struct iwl_priv *priv)
 {
        int pos;
@@ -432,12 +466,17 @@ static inline u16 iwl_pcie_link_ctl(struct iwl_priv *priv)
        pci_read_config_word(priv->pci_dev, pos + PCI_EXP_LNKCTL, &pci_lnk_ctl);
        return pci_lnk_ctl;
 }
+#ifdef CONFIG_PM
+int iwl_pci_suspend(struct pci_dev *pdev, pm_message_t state);
+int iwl_pci_resume(struct pci_dev *pdev);
+#endif /* CONFIG_PM */
 
 /*****************************************************
 *  Error Handling Debugging
 ******************************************************/
 void iwl_dump_nic_error_log(struct iwl_priv *priv);
 void iwl_dump_nic_event_log(struct iwl_priv *priv);
+void iwl_clear_isr_stats(struct iwl_priv *priv);
 
 /*****************************************************
 *  GEOS
@@ -451,14 +490,12 @@ void iwlcore_free_geos(struct iwl_priv *priv);
 #define STATUS_HCMD_SYNC_ACTIVE        1       /* sync host command in progress */
 #define STATUS_INT_ENABLED     2
 #define STATUS_RF_KILL_HW      3
-#define STATUS_RF_KILL_SW      4
 #define STATUS_INIT            5
 #define STATUS_ALIVE           6
 #define STATUS_READY           7
 #define STATUS_TEMPERATURE     8
 #define STATUS_GEO_CONFIGURED  9
 #define STATUS_EXIT_PENDING    10
-#define STATUS_IN_SUSPEND      11
 #define STATUS_STATISTICS      12
 #define STATUS_SCANNING                13
 #define STATUS_SCAN_ABORTING   14
@@ -487,11 +524,6 @@ static inline int iwl_is_init(struct iwl_priv *priv)
        return test_bit(STATUS_INIT, &priv->status);
 }
 
-static inline int iwl_is_rfkill_sw(struct iwl_priv *priv)
-{
-       return test_bit(STATUS_RF_KILL_SW, &priv->status);
-}
-
 static inline int iwl_is_rfkill_hw(struct iwl_priv *priv)
 {
        return test_bit(STATUS_RF_KILL_HW, &priv->status);
@@ -499,7 +531,7 @@ static inline int iwl_is_rfkill_hw(struct iwl_priv *priv)
 
 static inline int iwl_is_rfkill(struct iwl_priv *priv)
 {
-       return iwl_is_rfkill_hw(priv) || iwl_is_rfkill_sw(priv);
+       return iwl_is_rfkill_hw(priv);
 }
 
 static inline int iwl_is_ready_rf(struct iwl_priv *priv)
@@ -528,7 +560,14 @@ static inline int iwl_send_rxon_assoc(struct iwl_priv *priv)
 {
        return priv->cfg->ops->hcmd->rxon_assoc(priv);
 }
-
+static inline int iwlcore_commit_rxon(struct iwl_priv *priv)
+{
+       return priv->cfg->ops->hcmd->commit_rxon(priv);
+}
+static inline void iwlcore_config_ap(struct iwl_priv *priv)
+{
+       priv->cfg->ops->lib->config_ap(priv);
+}
 static inline const struct ieee80211_supported_band *iwl_get_hw_mode(
                        struct iwl_priv *priv, enum ieee80211_band band)
 {
index 6e983149b83b1c9d1d924463d62890920217280e..f03dae1b2f367eefb6dccddf2d612384566cca42 100644 (file)
@@ -89,6 +89,7 @@
 /* EEPROM reads */
 #define CSR_EEPROM_REG          (CSR_BASE+0x02c)
 #define CSR_EEPROM_GP           (CSR_BASE+0x030)
+#define CSR_OTP_GP_REG         (CSR_BASE+0x034)
 #define CSR_GIO_REG            (CSR_BASE+0x03C)
 #define CSR_GP_UCODE           (CSR_BASE+0x044)
 #define CSR_UCODE_DRV_GP1       (CSR_BASE+0x054)
 #define CSR_UCODE_DRV_GP1_CLR   (CSR_BASE+0x05c)
 #define CSR_UCODE_DRV_GP2       (CSR_BASE+0x060)
 #define CSR_LED_REG             (CSR_BASE+0x094)
+#define CSR_DRAM_INT_TBL_REG   (CSR_BASE+0x0A0)
 #define CSR_GIO_CHICKEN_BITS    (CSR_BASE+0x100)
 
+#define CSR_INT_PERIODIC_REG   (CSR_BASE+0x005)
 /* Analog phase-lock-loop configuration  */
 #define CSR_ANA_PLL_CFG         (CSR_BASE+0x20c)
 /*
 
 #define CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A          (0x00080000)
 #define CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM                (0x00200000)
-#define CSR_HW_IF_CONFIG_REG_BIT_PCI_OWN_SEM           (0x00400000)
-#define CSR_HW_IF_CONFIG_REG_BIT_ME_OWN                        (0x02000000)
-#define CSR_HW_IF_CONFIG_REG_BIT_WAKE_ME               (0x08000000)
+#define CSR_HW_IF_CONFIG_REG_BIT_NIC_READY             (0x00400000)
+#define CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE      (0x02000000)
+#define CSR_HW_IF_CONFIG_REG_PREPARE                   (0x08000000)
 
+#define CSR_INT_PERIODIC_DIS                   (0x00)
+#define CSR_INT_PERIODIC_ENA                   (0xFF)
 
 /* interrupt flags in INTA, set by uCode or hardware (e.g. dma),
  * acknowledged (reset) by host writing "1" to flagged bits. */
 #define CSR_INT_BIT_FH_RX        (1 << 31) /* Rx DMA, cmd responses, FH_INT[17:16] */
 #define CSR_INT_BIT_HW_ERR       (1 << 29) /* DMA hardware error FH_INT[31] */
-#define CSR_INT_BIT_DNLD         (1 << 28) /* uCode Download */
+#define CSR_INT_BIT_RX_PERIODIC         (1 << 28) /* Rx periodic */
 #define CSR_INT_BIT_FH_TX        (1 << 27) /* Tx DMA FH_INT[1:0] */
 #define CSR_INT_BIT_SCD          (1 << 26) /* TXQ pointer advanced */
 #define CSR_INT_BIT_SW_ERR       (1 << 25) /* uCode error */
 #define CSR_EEPROM_GP_VALID_MSK                (0x00000007)
 #define CSR_EEPROM_GP_BAD_SIGNATURE    (0x00000000)
 #define CSR_EEPROM_GP_IF_OWNER_MSK     (0x00000180)
+#define CSR_OTP_GP_REG_DEVICE_SELECT   (0x00010000) /* 0 - EEPROM, 1 - OTP */
+#define CSR_OTP_GP_REG_OTP_ACCESS_MODE (0x00020000) /* 0 - absolute, 1 - relative */
+#define CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK          (0x00100000) /* bit 20 */
+#define CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK        (0x00200000) /* bit 21 */
 
 /* CSR GIO */
 #define CSR_GIO_REG_VAL_L0S_ENABLED    (0x00000002)
 
 /* HPET MEM debug */
 #define CSR_DBG_HPET_MEM_REG_VAL       (0xFFFF0000)
+
+/* DRAM INT TABLE */
+#define CSR_DRAM_INT_TBL_ENABLE                (1 << 31)
+#define CSR_DRAM_INIT_TBL_WRAP_CHECK   (1 << 27)
+
 /*=== HBUS (Host-side Bus) ===*/
 #define HBUS_BASE      (0x400)
 /*
index 65d1a7f2db9e73365199fc27e9a765b0fa7dd464..2cf014f523bee44ec608ee3372e0558a76cd095a 100644 (file)
@@ -68,13 +68,14 @@ struct iwl_debugfs {
        struct dentry *dir_rf;
        struct dir_data_files {
                struct dentry *file_sram;
-               struct dentry *file_eeprom;
+               struct dentry *file_nvm;
                struct dentry *file_stations;
                struct dentry *file_rx_statistics;
                struct dentry *file_tx_statistics;
                struct dentry *file_log_event;
                struct dentry *file_channels;
                struct dentry *file_status;
+               struct dentry *file_interrupt;
        } dbgfs_data_files;
        struct dir_rf_files {
                struct dentry *file_disable_sensitivity;
index 64eb585f1578a2d4e320d39ce9ba0fadfcb621f6..11e08c068917441bcdead648fe23ef1352def143 100644 (file)
@@ -172,7 +172,6 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file,
        struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
        const size_t bufsz = sizeof(buf);
 
-       iwl_grab_nic_access(priv);
        for (i = priv->dbgfs->sram_len; i > 0; i -= 4) {
                val = iwl_read_targ_mem(priv, priv->dbgfs->sram_offset + \
                                        priv->dbgfs->sram_len - i);
@@ -192,7 +191,6 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file,
                pos += scnprintf(buf + pos, bufsz - pos, "0x%08x ", val);
        }
        pos += scnprintf(buf + pos, bufsz - pos, "\n");
-       iwl_release_nic_access(priv);
 
        ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
        return ret;
@@ -292,7 +290,7 @@ static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf,
        return ret;
 }
 
-static ssize_t iwl_dbgfs_eeprom_read(struct file *file,
+static ssize_t iwl_dbgfs_nvm_read(struct file *file,
                                       char __user *user_buf,
                                       size_t count,
                                       loff_t *ppos)
@@ -306,7 +304,7 @@ static ssize_t iwl_dbgfs_eeprom_read(struct file *file,
        buf_size = 4 * eeprom_len + 256;
 
        if (eeprom_len % 16) {
-               IWL_ERR(priv, "EEPROM size is not multiple of 16.\n");
+               IWL_ERR(priv, "NVM size is not multiple of 16.\n");
                return -ENODATA;
        }
 
@@ -318,6 +316,13 @@ static ssize_t iwl_dbgfs_eeprom_read(struct file *file,
        }
 
        ptr = priv->eeprom;
+       if (!ptr) {
+               IWL_ERR(priv, "Invalid EEPROM/OTP memory\n");
+               return -ENOMEM;
+       }
+       pos += scnprintf(buf + pos, buf_size - pos, "NVM Type: %s\n",
+                       (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP)
+                       ? "OTP" : "EEPROM");
        for (ofs = 0 ; ofs < eeprom_len ; ofs += 16) {
                pos += scnprintf(buf + pos, buf_size - pos, "0x%.4x ", ofs);
                hex_dump_to_buffer(ptr + ofs, 16 , 16, 2, buf + pos,
@@ -375,51 +380,53 @@ static ssize_t iwl_dbgfs_channels_read(struct file *file, char __user *user_buf,
        }
 
        supp_band = iwl_get_hw_mode(priv, IEEE80211_BAND_2GHZ);
-       channels = supp_band->channels;
-
-       pos += scnprintf(buf + pos, bufsz - pos,
-                       "Displaying %d channels in 2.4GHz band 802.11bg):\n",
-                        supp_band->n_channels);
+       if (supp_band) {
+               channels = supp_band->channels;
 
-       for (i = 0; i < supp_band->n_channels; i++)
                pos += scnprintf(buf + pos, bufsz - pos,
-                               "%d: %ddBm: BSS%s%s, %s.\n",
-                               ieee80211_frequency_to_channel(
-                               channels[i].center_freq),
-                               channels[i].max_power,
-                               channels[i].flags & IEEE80211_CHAN_RADAR ?
-                               " (IEEE 802.11h required)" : "",
-                               (!(channels[i].flags & IEEE80211_CHAN_NO_IBSS)
-                               || (channels[i].flags &
-                               IEEE80211_CHAN_RADAR)) ? "" :
-                               ", IBSS",
-                               channels[i].flags &
-                               IEEE80211_CHAN_PASSIVE_SCAN ?
-                               "passive only" : "active/passive");
+                               "Displaying %d channels in 2.4GHz band 802.11bg):\n",
+                               supp_band->n_channels);
 
+               for (i = 0; i < supp_band->n_channels; i++)
+                       pos += scnprintf(buf + pos, bufsz - pos,
+                                       "%d: %ddBm: BSS%s%s, %s.\n",
+                                       ieee80211_frequency_to_channel(
+                                       channels[i].center_freq),
+                                       channels[i].max_power,
+                                       channels[i].flags & IEEE80211_CHAN_RADAR ?
+                                       " (IEEE 802.11h required)" : "",
+                                       ((channels[i].flags & IEEE80211_CHAN_NO_IBSS)
+                                       || (channels[i].flags &
+                                       IEEE80211_CHAN_RADAR)) ? "" :
+                                       ", IBSS",
+                                       channels[i].flags &
+                                       IEEE80211_CHAN_PASSIVE_SCAN ?
+                                       "passive only" : "active/passive");
+       }
        supp_band = iwl_get_hw_mode(priv, IEEE80211_BAND_5GHZ);
-       channels = supp_band->channels;
-
-       pos += scnprintf(buf + pos, bufsz - pos,
-                       "Displaying %d channels in 5.2GHz band (802.11a)\n",
-                       supp_band->n_channels);
+       if (supp_band) {
+               channels = supp_band->channels;
 
-       for (i = 0; i < supp_band->n_channels; i++)
                pos += scnprintf(buf + pos, bufsz - pos,
-                               "%d: %ddBm: BSS%s%s, %s.\n",
-                               ieee80211_frequency_to_channel(
-                               channels[i].center_freq),
-                               channels[i].max_power,
-                               channels[i].flags & IEEE80211_CHAN_RADAR ?
-                               " (IEEE 802.11h required)" : "",
-                               ((channels[i].flags & IEEE80211_CHAN_NO_IBSS)
-                               || (channels[i].flags &
-                               IEEE80211_CHAN_RADAR)) ? "" :
-                               ", IBSS",
-                               channels[i].flags &
-                               IEEE80211_CHAN_PASSIVE_SCAN ?
-                               "passive only" : "active/passive");
+                               "Displaying %d channels in 5.2GHz band (802.11a)\n",
+                               supp_band->n_channels);
 
+               for (i = 0; i < supp_band->n_channels; i++)
+                       pos += scnprintf(buf + pos, bufsz - pos,
+                                       "%d: %ddBm: BSS%s%s, %s.\n",
+                                       ieee80211_frequency_to_channel(
+                                       channels[i].center_freq),
+                                       channels[i].max_power,
+                                       channels[i].flags & IEEE80211_CHAN_RADAR ?
+                                       " (IEEE 802.11h required)" : "",
+                                       ((channels[i].flags & IEEE80211_CHAN_NO_IBSS)
+                                       || (channels[i].flags &
+                                       IEEE80211_CHAN_RADAR)) ? "" :
+                                       ", IBSS",
+                                       channels[i].flags &
+                                       IEEE80211_CHAN_PASSIVE_SCAN ?
+                                       "passive only" : "active/passive");
+       }
        ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
        kfree(buf);
        return ret;
@@ -442,8 +449,6 @@ static ssize_t iwl_dbgfs_status_read(struct file *file,
                test_bit(STATUS_INT_ENABLED, &priv->status));
        pos += scnprintf(buf + pos, bufsz - pos, "STATUS_RF_KILL_HW:\t %d\n",
                test_bit(STATUS_RF_KILL_HW, &priv->status));
-       pos += scnprintf(buf + pos, bufsz - pos, "STATUS_RF_KILL_SW:\t %d\n",
-               test_bit(STATUS_RF_KILL_SW, &priv->status));
        pos += scnprintf(buf + pos, bufsz - pos, "STATUS_INIT:\t\t %d\n",
                test_bit(STATUS_INIT, &priv->status));
        pos += scnprintf(buf + pos, bufsz - pos, "STATUS_ALIVE:\t\t %d\n",
@@ -456,8 +461,6 @@ static ssize_t iwl_dbgfs_status_read(struct file *file,
                test_bit(STATUS_GEO_CONFIGURED, &priv->status));
        pos += scnprintf(buf + pos, bufsz - pos, "STATUS_EXIT_PENDING:\t %d\n",
                test_bit(STATUS_EXIT_PENDING, &priv->status));
-       pos += scnprintf(buf + pos, bufsz - pos, "STATUS_IN_SUSPEND:\t %d\n",
-               test_bit(STATUS_IN_SUSPEND, &priv->status));
        pos += scnprintf(buf + pos, bufsz - pos, "STATUS_STATISTICS:\t %d\n",
                test_bit(STATUS_STATISTICS, &priv->status));
        pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCANNING:\t %d\n",
@@ -475,14 +478,104 @@ static ssize_t iwl_dbgfs_status_read(struct file *file,
        return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
 }
 
+static ssize_t iwl_dbgfs_interrupt_read(struct file *file,
+                                       char __user *user_buf,
+                                       size_t count, loff_t *ppos) {
+
+       struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
+       int pos = 0;
+       int cnt = 0;
+       char *buf;
+       int bufsz = 24 * 64; /* 24 items * 64 char per item */
+       ssize_t ret;
+
+       buf = kzalloc(bufsz, GFP_KERNEL);
+       if (!buf) {
+               IWL_ERR(priv, "Can not allocate Buffer\n");
+               return -ENOMEM;
+       }
+
+       pos += scnprintf(buf + pos, bufsz - pos,
+                       "Interrupt Statistics Report:\n");
+
+       pos += scnprintf(buf + pos, bufsz - pos, "HW Error:\t\t\t %u\n",
+               priv->isr_stats.hw);
+       pos += scnprintf(buf + pos, bufsz - pos, "SW Error:\t\t\t %u\n",
+               priv->isr_stats.sw);
+       if (priv->isr_stats.sw > 0) {
+               pos += scnprintf(buf + pos, bufsz - pos,
+                       "\tLast Restarting Code:  0x%X\n",
+                       priv->isr_stats.sw_err);
+       }
+#ifdef CONFIG_IWLWIFI_DEBUG
+       pos += scnprintf(buf + pos, bufsz - pos, "Frame transmitted:\t\t %u\n",
+               priv->isr_stats.sch);
+       pos += scnprintf(buf + pos, bufsz - pos, "Alive interrupt:\t\t %u\n",
+               priv->isr_stats.alive);
+#endif
+       pos += scnprintf(buf + pos, bufsz - pos,
+               "HW RF KILL switch toggled:\t %u\n",
+               priv->isr_stats.rfkill);
+
+       pos += scnprintf(buf + pos, bufsz - pos, "CT KILL:\t\t\t %u\n",
+               priv->isr_stats.ctkill);
+
+       pos += scnprintf(buf + pos, bufsz - pos, "Wakeup Interrupt:\t\t %u\n",
+               priv->isr_stats.wakeup);
+
+       pos += scnprintf(buf + pos, bufsz - pos,
+               "Rx command responses:\t\t %u\n",
+               priv->isr_stats.rx);
+       for (cnt = 0; cnt < REPLY_MAX; cnt++) {
+               if (priv->isr_stats.rx_handlers[cnt] > 0)
+                       pos += scnprintf(buf + pos, bufsz - pos,
+                               "\tRx handler[%36s]:\t\t %u\n",
+                               get_cmd_string(cnt),
+                               priv->isr_stats.rx_handlers[cnt]);
+       }
+
+       pos += scnprintf(buf + pos, bufsz - pos, "Tx/FH interrupt:\t\t %u\n",
+               priv->isr_stats.tx);
+
+       pos += scnprintf(buf + pos, bufsz - pos, "Unexpected INTA:\t\t %u\n",
+               priv->isr_stats.unhandled);
+
+       ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+       kfree(buf);
+       return ret;
+}
+
+static ssize_t iwl_dbgfs_interrupt_write(struct file *file,
+                                        const char __user *user_buf,
+                                        size_t count, loff_t *ppos)
+{
+       struct iwl_priv *priv = file->private_data;
+       char buf[8];
+       int buf_size;
+       u32 reset_flag;
+
+       memset(buf, 0, sizeof(buf));
+       buf_size = min(count, sizeof(buf) -  1);
+       if (copy_from_user(buf, user_buf, buf_size))
+               return -EFAULT;
+       if (sscanf(buf, "%x", &reset_flag) != 1)
+               return -EFAULT;
+       if (reset_flag == 0)
+               iwl_clear_isr_stats(priv);
+
+       return count;
+}
+
+
 DEBUGFS_READ_WRITE_FILE_OPS(sram);
 DEBUGFS_WRITE_FILE_OPS(log_event);
-DEBUGFS_READ_FILE_OPS(eeprom);
+DEBUGFS_READ_FILE_OPS(nvm);
 DEBUGFS_READ_FILE_OPS(stations);
 DEBUGFS_READ_FILE_OPS(rx_statistics);
 DEBUGFS_READ_FILE_OPS(tx_statistics);
 DEBUGFS_READ_FILE_OPS(channels);
 DEBUGFS_READ_FILE_OPS(status);
+DEBUGFS_READ_WRITE_FILE_OPS(interrupt);
 
 /*
  * Create the debugfs files and directories
@@ -510,7 +603,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
 
        DEBUGFS_ADD_DIR(data, dbgfs->dir_drv);
        DEBUGFS_ADD_DIR(rf, dbgfs->dir_drv);
-       DEBUGFS_ADD_FILE(eeprom, data);
+       DEBUGFS_ADD_FILE(nvm, data);
        DEBUGFS_ADD_FILE(sram, data);
        DEBUGFS_ADD_FILE(log_event, data);
        DEBUGFS_ADD_FILE(stations, data);
@@ -518,6 +611,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
        DEBUGFS_ADD_FILE(tx_statistics, data);
        DEBUGFS_ADD_FILE(channels, data);
        DEBUGFS_ADD_FILE(status, data);
+       DEBUGFS_ADD_FILE(interrupt, data);
        DEBUGFS_ADD_BOOL(disable_sensitivity, rf, &priv->disable_sens_cal);
        DEBUGFS_ADD_BOOL(disable_chain_noise, rf,
                         &priv->disable_chain_noise_cal);
@@ -540,7 +634,7 @@ void iwl_dbgfs_unregister(struct iwl_priv *priv)
        if (!priv->dbgfs)
                return;
 
-       DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_eeprom);
+       DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_nvm);
        DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_rx_statistics);
        DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_tx_statistics);
        DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_sram);
@@ -548,6 +642,7 @@ void iwl_dbgfs_unregister(struct iwl_priv *priv)
        DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_stations);
        DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_channels);
        DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_status);
+       DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_interrupt);
        DEBUGFS_REMOVE(priv->dbgfs->dir_data);
        DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_sensitivity);
        DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_chain_noise);
index cf7f0db58fcfc1541ba9a6279caf02a3a467b211..e2d620f0b6e866eb327ae531969b040c201d8b37 100644 (file)
@@ -41,7 +41,6 @@
 #include "iwl-prph.h"
 #include "iwl-fh.h"
 #include "iwl-debug.h"
-#include "iwl-rfkill.h"
 #include "iwl-4965-hw.h"
 #include "iwl-3945-hw.h"
 #include "iwl-3945-led.h"
@@ -289,11 +288,11 @@ struct iwl_frame {
 #define MAX_SN ((IEEE80211_SCTL_SEQ) >> 4)
 
 enum {
-       /* CMD_SIZE_NORMAL = 0, */
+       CMD_SYNC = 0,
+       CMD_SIZE_NORMAL = 0,
+       CMD_NO_SKB = 0,
        CMD_SIZE_HUGE = (1 << 0),
-       /* CMD_SYNC = 0, */
        CMD_ASYNC = (1 << 1),
-       /* CMD_NO_SKB = 0, */
        CMD_WANT_SKB = (1 << 2),
 };
 
@@ -381,6 +380,7 @@ struct iwl_rx_queue {
        u32 read;
        u32 write;
        u32 free_count;
+       u32 write_actual;
        struct list_head rx_free;
        struct list_head rx_used;
        int need_update;
@@ -498,22 +498,13 @@ struct iwl_qos_info {
 #define STA_PS_STATUS_WAKE             0
 #define STA_PS_STATUS_SLEEP            1
 
-struct iwl3945_tid_data {
-       u16 seq_number;
-};
-
-struct iwl3945_hw_key {
-       enum ieee80211_key_alg alg;
-       int keylen;
-       u8 key[32];
-};
 
 struct iwl3945_station_entry {
        struct iwl3945_addsta_cmd sta;
-       struct iwl3945_tid_data tid[MAX_TID_COUNT];
+       struct iwl_tid_data tid[MAX_TID_COUNT];
        u8 used;
        u8 ps_status;
-       struct iwl3945_hw_key keyinfo;
+       struct iwl_hw_key keyinfo;
 };
 
 struct iwl_station_entry {
@@ -822,6 +813,26 @@ enum {
        MEASUREMENT_ACTIVE = (1 << 1),
 };
 
+enum iwl_nvm_type {
+       NVM_DEVICE_TYPE_EEPROM = 0,
+       NVM_DEVICE_TYPE_OTP,
+};
+
+/* interrupt statistics */
+struct isr_statistics {
+       u32 hw;
+       u32 sw;
+       u32 sw_err;
+       u32 sch;
+       u32 alive;
+       u32 rfkill;
+       u32 ctkill;
+       u32 wakeup;
+       u32 rx;
+       u32 rx_handlers[REPLY_MAX];
+       u32 tx;
+       u32 unhandled;
+};
 
 #define IWL_MAX_NUM_QUEUES     20 /* FIXME: do dynamic allocation */
 
@@ -877,15 +888,14 @@ struct iwl_priv {
        unsigned long scan_start_tsf;
        void *scan;
        int scan_bands;
-       int one_direct_scan;
-       u8 direct_ssid_len;
-       u8 direct_ssid[IW_ESSID_MAX_SIZE];
+       struct cfg80211_scan_request *scan_request;
        u8 scan_tx_ant[IEEE80211_NUM_BANDS];
        u8 mgmt_tx_ant;
 
        /* spinlock */
        spinlock_t lock;        /* protect general shared data */
        spinlock_t hcmd_lock;   /* protect hcmd */
+       spinlock_t reg_lock;    /* protect hw register access */
        struct mutex mutex;
 
        /* basic pci-network driver stuff */
@@ -919,16 +929,12 @@ struct iwl_priv {
        const struct iwl_rxon_cmd active_rxon;
        struct iwl_rxon_cmd staging_rxon;
 
-       int error_recovering;
        struct iwl_rxon_cmd recovery_rxon;
 
        /* 1st responses from initialize and runtime uCode images.
         * 4965's initialize alive response contains some calibration data. */
        struct iwl_init_alive_resp card_alive_init;
        struct iwl_alive_resp card_alive;
-#if defined(CONFIG_IWLWIFI_RFKILL)
-       struct rfkill *rfkill;
-#endif
 
 #ifdef CONFIG_IWLWIFI_LEDS
        unsigned long last_blink_time;
@@ -978,6 +984,9 @@ struct iwl_priv {
                u64 bytes;
        } tx_stats[3], rx_stats[3];
 
+       /* counts interrupts */
+       struct isr_statistics isr_stats;
+
        struct iwl_power_mgr power_data;
 
        struct iwl_notif_statistics statistics;
@@ -1017,6 +1026,7 @@ struct iwl_priv {
 
        /* eeprom */
        u8 *eeprom;
+       int    nvm_device_type;
        struct iwl_eeprom_calib_info *calib_info;
 
        enum nl80211_iftype iw_mode;
@@ -1034,7 +1044,16 @@ struct iwl_priv {
        /*End*/
        struct iwl_hw_params hw_params;
 
+       /* INT ICT Table */
+       u32 *ict_tbl;
+       dma_addr_t ict_tbl_dma;
+       dma_addr_t aligned_ict_tbl_dma;
+       int ict_index;
+       void *ict_tbl_vir;
+       u32 inta;
+       bool use_ict;
 
+       u32 inta_mask;
        /* Current association information needed to configure the
         * hardware */
        u16 assoc_id;
@@ -1049,7 +1068,6 @@ struct iwl_priv {
        struct work_struct calibrated_work;
        struct work_struct scan_completed;
        struct work_struct rx_replenish;
-       struct work_struct rf_kill;
        struct work_struct abort_scan;
        struct work_struct update_link_led;
        struct work_struct auth_work;
@@ -1059,7 +1077,6 @@ struct iwl_priv {
 
        struct tasklet_struct irq_tasklet;
 
-       struct delayed_work set_power_save;
        struct delayed_work init_alive_start;
        struct delayed_work alive_start;
        struct delayed_work scan_check;
@@ -1090,14 +1107,12 @@ struct iwl_priv {
        u32 disable_tx_power_cal;
        struct work_struct run_time_calib_work;
        struct timer_list statistics_periodic;
-
+       bool hw_ready;
        /*For 3945*/
 #define IWL_DEFAULT_TX_POWER 0x0F
 
        struct iwl3945_notif_statistics statistics_39;
 
-       struct iwl3945_station_entry stations_39[IWL_STATION_COUNT];
-
        u32 sta_supp_rates;
 }; /*iwl_priv */
 
index 75517d05df0833fee49564672336785abaa2adf5..7d7554a2f341309d1e39d7ac80868cc9677e6fc1 100644 (file)
@@ -152,6 +152,32 @@ int iwlcore_eeprom_verify_signature(struct iwl_priv *priv)
 }
 EXPORT_SYMBOL(iwlcore_eeprom_verify_signature);
 
+static int iwlcore_get_nvm_type(struct iwl_priv *priv)
+{
+       u32 otpgp;
+       int nvm_type;
+
+       /* OTP only valid for CP/PP and after */
+       switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) {
+       case CSR_HW_REV_TYPE_3945:
+       case CSR_HW_REV_TYPE_4965:
+       case CSR_HW_REV_TYPE_5300:
+       case CSR_HW_REV_TYPE_5350:
+       case CSR_HW_REV_TYPE_5100:
+       case CSR_HW_REV_TYPE_5150:
+               nvm_type = NVM_DEVICE_TYPE_EEPROM;
+               break;
+       default:
+               otpgp = iwl_read32(priv, CSR_OTP_GP_REG);
+               if (otpgp & CSR_OTP_GP_REG_DEVICE_SELECT)
+                       nvm_type = NVM_DEVICE_TYPE_OTP;
+               else
+                       nvm_type = NVM_DEVICE_TYPE_EEPROM;
+               break;
+       }
+       return  nvm_type;
+}
+
 /*
  * The device's EEPROM semaphore prevents conflicts between driver and uCode
  * when accessing the EEPROM; each access is a series of pulses to/from the
@@ -198,6 +224,31 @@ const u8 *iwlcore_eeprom_query_addr(const struct iwl_priv *priv, size_t offset)
 }
 EXPORT_SYMBOL(iwlcore_eeprom_query_addr);
 
+static int iwl_init_otp_access(struct iwl_priv *priv)
+{
+       int ret;
+
+       /* Enable 40MHz radio clock */
+       _iwl_write32(priv, CSR_GP_CNTRL,
+                    _iwl_read32(priv, CSR_GP_CNTRL) |
+                    CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
+
+       /* wait for clock to be ready */
+       ret = iwl_poll_direct_bit(priv, CSR_GP_CNTRL,
+                                 CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
+                                 25000);
+       if (ret < 0)
+               IWL_ERR(priv, "Time out access OTP\n");
+       else {
+               iwl_set_bits_prph(priv, APMG_PS_CTRL_REG,
+                                 APMG_PS_CTRL_VAL_RESET_REQ);
+               udelay(5);
+               iwl_clear_bits_prph(priv, APMG_PS_CTRL_REG,
+                                   APMG_PS_CTRL_VAL_RESET_REQ);
+       }
+       return ret;
+}
+
 /**
  * iwl_eeprom_init - read EEPROM contents
  *
@@ -209,11 +260,18 @@ int iwl_eeprom_init(struct iwl_priv *priv)
 {
        u16 *e;
        u32 gp = iwl_read32(priv, CSR_EEPROM_GP);
-       int sz = priv->cfg->eeprom_size;
+       int sz;
        int ret;
        u16 addr;
+       u32 otpgp;
+
+       priv->nvm_device_type = iwlcore_get_nvm_type(priv);
 
        /* allocate eeprom */
+       if (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP)
+               priv->cfg->eeprom_size =
+                       OTP_BLOCK_SIZE * OTP_LOWER_BLOCKS_TOTAL;
+       sz = priv->cfg->eeprom_size;
        priv->eeprom = kzalloc(sz, GFP_KERNEL);
        if (!priv->eeprom) {
                ret = -ENOMEM;
@@ -235,30 +293,77 @@ int iwl_eeprom_init(struct iwl_priv *priv)
                ret = -ENOENT;
                goto err;
        }
-
-       /* eeprom is an array of 16bit values */
-       for (addr = 0; addr < sz; addr += sizeof(u16)) {
-               u32 r;
-
-               _iwl_write32(priv, CSR_EEPROM_REG,
-                            CSR_EEPROM_REG_MSK_ADDR & (addr << 1));
-
-               ret = iwl_poll_direct_bit(priv, CSR_EEPROM_REG,
-                                         CSR_EEPROM_REG_READ_VALID_MSK,
-                                         IWL_EEPROM_ACCESS_TIMEOUT);
-               if (ret < 0) {
-                       IWL_ERR(priv, "Time out reading EEPROM[%d]\n", addr);
-                       goto done;
+       if (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP) {
+               ret = iwl_init_otp_access(priv);
+               if (ret) {
+                       IWL_ERR(priv, "Failed to initialize OTP access.\n");
+                       ret = -ENOENT;
+                       goto err;
+               }
+               _iwl_write32(priv, CSR_EEPROM_GP,
+                            iwl_read32(priv, CSR_EEPROM_GP) &
+                            ~CSR_EEPROM_GP_IF_OWNER_MSK);
+               /* clear */
+               _iwl_write32(priv, CSR_OTP_GP_REG,
+                            iwl_read32(priv, CSR_OTP_GP_REG) |
+                            CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK |
+                            CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK);
+
+               for (addr = 0; addr < sz; addr += sizeof(u16)) {
+                       u32 r;
+
+                       _iwl_write32(priv, CSR_EEPROM_REG,
+                                    CSR_EEPROM_REG_MSK_ADDR & (addr << 1));
+
+                       ret = iwl_poll_direct_bit(priv, CSR_EEPROM_REG,
+                                                 CSR_EEPROM_REG_READ_VALID_MSK,
+                                                 IWL_EEPROM_ACCESS_TIMEOUT);
+                       if (ret < 0) {
+                               IWL_ERR(priv, "Time out reading OTP[%d]\n", addr);
+                               goto done;
+                       }
+                       r = _iwl_read_direct32(priv, CSR_EEPROM_REG);
+                       /* check for ECC errors: */
+                       otpgp = iwl_read32(priv, CSR_OTP_GP_REG);
+                       if (otpgp & CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK) {
+                               /* stop in this case */
+                               IWL_ERR(priv, "Uncorrectable OTP ECC error, Abort OTP read\n");
+                               goto done;
+                       }
+                       if (otpgp & CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK) {
+                               /* continue in this case */
+                               _iwl_write32(priv, CSR_OTP_GP_REG,
+                                            iwl_read32(priv, CSR_OTP_GP_REG) |
+                                            CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK);
+                               IWL_ERR(priv, "Correctable OTP ECC error, continue read\n");
+                       }
+                       e[addr / 2] = le16_to_cpu((__force __le16)(r >> 16));
+               }
+       } else {
+               /* eeprom is an array of 16bit values */
+               for (addr = 0; addr < sz; addr += sizeof(u16)) {
+                       u32 r;
+
+                       _iwl_write32(priv, CSR_EEPROM_REG,
+                                    CSR_EEPROM_REG_MSK_ADDR & (addr << 1));
+
+                       ret = iwl_poll_direct_bit(priv, CSR_EEPROM_REG,
+                                                 CSR_EEPROM_REG_READ_VALID_MSK,
+                                                 IWL_EEPROM_ACCESS_TIMEOUT);
+                       if (ret < 0) {
+                               IWL_ERR(priv, "Time out reading EEPROM[%d]\n", addr);
+                               goto done;
+                       }
+                       r = _iwl_read_direct32(priv, CSR_EEPROM_REG);
+                       e[addr / 2] = le16_to_cpu((__force __le16)(r >> 16));
                }
-               r = _iwl_read_direct32(priv, CSR_EEPROM_REG);
-               e[addr / 2] = le16_to_cpu((__force __le16)(r >> 16));
        }
        ret = 0;
 done:
        priv->cfg->ops->lib->eeprom_ops.release_semaphore(priv);
 err:
        if (ret)
-               kfree(priv->eeprom);
+               iwl_eeprom_free(priv);
 alloc_err:
        return ret;
 }
@@ -285,7 +390,7 @@ int iwl_eeprom_check_version(struct iwl_priv *priv)
 
        return 0;
 err:
-       IWL_ERR(priv, "Unsupported EEPROM VER=0x%x < 0x%x CALIB=0x%x < 0x%x\n",
+       IWL_ERR(priv, "Unsupported (too old) EEPROM VER=0x%x < 0x%x CALIB=0x%x < 0x%x\n",
                  eeprom_ver, priv->cfg->eeprom_ver,
                  calib_ver,  priv->cfg->eeprom_calib_ver);
        return -EINVAL;
@@ -301,6 +406,8 @@ EXPORT_SYMBOL(iwl_eeprom_query_addr);
 
 u16 iwl_eeprom_query16(const struct iwl_priv *priv, size_t offset)
 {
+       if (!priv->eeprom)
+               return 0;
        return (u16)priv->eeprom[offset] | ((u16)priv->eeprom[offset + 1] << 8);
 }
 EXPORT_SYMBOL(iwl_eeprom_query16);
@@ -481,8 +588,8 @@ int iwl_init_channel_map(struct iwl_priv *priv)
                        /* First write that fat is not enabled, and then enable
                         * one by one */
                        ch_info->fat_extension_channel =
-                               (IEEE80211_CHAN_NO_FAT_ABOVE |
-                                IEEE80211_CHAN_NO_FAT_BELOW);
+                               (IEEE80211_CHAN_NO_HT40PLUS |
+                                IEEE80211_CHAN_NO_HT40MINUS);
 
                        if (!(is_channel_valid(ch_info))) {
                                IWL_DEBUG_INFO(priv, "Ch. %d Flags %x [%sGHz] - "
@@ -561,7 +668,7 @@ int iwl_init_channel_map(struct iwl_priv *priv)
                                fat_extension_chan = 0;
                        else
                                fat_extension_chan =
-                                       IEEE80211_CHAN_NO_FAT_BELOW;
+                                       IEEE80211_CHAN_NO_HT40MINUS;
 
                        /* Set up driver's info for lower half */
                        iwl_set_fat_chan_info(priv, ieeeband,
@@ -573,7 +680,7 @@ int iwl_init_channel_map(struct iwl_priv *priv)
                        iwl_set_fat_chan_info(priv, ieeeband,
                                                (eeprom_ch_index[ch] + 4),
                                                &(eeprom_ch_info[ch]),
-                                               IEEE80211_CHAN_NO_FAT_ABOVE);
+                                               IEEE80211_CHAN_NO_HT40PLUS);
                }
        }
 
index 3479153d96ca1cd164855725292d6a2287cf6ba0..195b4ef12c27583de3c67ef73e5d1a7ba1300892 100644 (file)
@@ -179,6 +179,10 @@ struct iwl_eeprom_channel {
 #define EEPROM_5050_TX_POWER_VERSION    (4)
 #define EEPROM_5050_EEPROM_VERSION     (0x21E)
 
+/* OTP */
+#define OTP_LOWER_BLOCKS_TOTAL         (3)
+#define OTP_BLOCK_SIZE                 (0x400)
+
 /* 2.4 GHz */
 extern const u8 iwl_eeprom_band_1[14];
 
index 083ea1ffbe87296f8533a2e5ab55d7498d5e4290..d30cb0275d196f837a63da8993429cdaa11f569e 100644 (file)
@@ -131,9 +131,23 @@ static inline void __iwl_set_bit(const char *f, u32 l,
        IWL_DEBUG_IO(priv, "set_bit(0x%08X, 0x%08X) = 0x%08X\n", reg, mask, val);
        _iwl_write32(priv, reg, val);
 }
-#define iwl_set_bit(p, r, m) __iwl_set_bit(__FILE__, __LINE__, p, r, m)
+static inline void iwl_set_bit(struct iwl_priv *p, u32 r, u32 m)
+{
+       unsigned long reg_flags;
+
+       spin_lock_irqsave(&p->reg_lock, reg_flags);
+       __iwl_set_bit(__FILE__, __LINE__, p, r, m);
+       spin_unlock_irqrestore(&p->reg_lock, reg_flags);
+}
 #else
-#define iwl_set_bit(p, r, m) _iwl_set_bit(p, r, m)
+static inline void iwl_set_bit(struct iwl_priv *p, u32 r, u32 m)
+{
+       unsigned long reg_flags;
+
+       spin_lock_irqsave(&p->reg_lock, reg_flags);
+       _iwl_set_bit(p, r, m);
+       spin_unlock_irqrestore(&p->reg_lock, reg_flags);
+}
 #endif
 
 static inline void _iwl_clear_bit(struct iwl_priv *priv, u32 reg, u32 mask)
@@ -148,19 +162,30 @@ static inline void __iwl_clear_bit(const char *f, u32 l,
        IWL_DEBUG_IO(priv, "clear_bit(0x%08X, 0x%08X) = 0x%08X\n", reg, mask, val);
        _iwl_write32(priv, reg, val);
 }
-#define iwl_clear_bit(p, r, m) __iwl_clear_bit(__FILE__, __LINE__, p, r, m)
+static inline void iwl_clear_bit(struct iwl_priv *p, u32 r, u32 m)
+{
+       unsigned long reg_flags;
+
+       spin_lock_irqsave(&p->reg_lock, reg_flags);
+       __iwl_clear_bit(__FILE__, __LINE__, p, r, m);
+       spin_unlock_irqrestore(&p->reg_lock, reg_flags);
+}
 #else
-#define iwl_clear_bit(p, r, m) _iwl_clear_bit(p, r, m)
+static inline void iwl_clear_bit(struct iwl_priv *p, u32 r, u32 m)
+{
+       unsigned long reg_flags;
+
+       spin_lock_irqsave(&p->reg_lock, reg_flags);
+       _iwl_clear_bit(p, r, m);
+       spin_unlock_irqrestore(&p->reg_lock, reg_flags);
+}
 #endif
 
 static inline int _iwl_grab_nic_access(struct iwl_priv *priv)
 {
        int ret;
        u32 val;
-#ifdef CONFIG_IWLWIFI_DEBUG
-       if (atomic_read(&priv->restrict_refcnt))
-               return 0;
-#endif
+
        /* this bit wakes up the NIC */
        _iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
        ret = _iwl_poll_bit(priv, CSR_GP_CNTRL,
@@ -170,12 +195,10 @@ static inline int _iwl_grab_nic_access(struct iwl_priv *priv)
        if (ret < 0) {
                val = _iwl_read32(priv, CSR_GP_CNTRL);
                IWL_ERR(priv, "MAC is in deep sleep!.  CSR_GP_CNTRL = 0x%08X\n", val);
+               _iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_FORCE_NMI);
                return -EIO;
        }
 
-#ifdef CONFIG_IWLWIFI_DEBUG
-       atomic_inc(&priv->restrict_refcnt);
-#endif
        return 0;
 }
 
@@ -183,9 +206,6 @@ static inline int _iwl_grab_nic_access(struct iwl_priv *priv)
 static inline int __iwl_grab_nic_access(const char *f, u32 l,
                                               struct iwl_priv *priv)
 {
-       if (atomic_read(&priv->restrict_refcnt))
-               IWL_ERR(priv, "Grabbing access while already held %s %d.\n", f, l);
-
        IWL_DEBUG_IO(priv, "grabbing nic access - %s %d\n", f, l);
        return _iwl_grab_nic_access(priv);
 }
@@ -198,18 +218,13 @@ static inline int __iwl_grab_nic_access(const char *f, u32 l,
 
 static inline void _iwl_release_nic_access(struct iwl_priv *priv)
 {
-#ifdef CONFIG_IWLWIFI_DEBUG
-       if (atomic_dec_and_test(&priv->restrict_refcnt))
-#endif
-               _iwl_clear_bit(priv, CSR_GP_CNTRL,
-                              CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
+       _iwl_clear_bit(priv, CSR_GP_CNTRL,
+                       CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
 }
 #ifdef CONFIG_IWLWIFI_DEBUG
 static inline void __iwl_release_nic_access(const char *f, u32 l,
                                            struct iwl_priv *priv)
 {
-       if (atomic_read(&priv->restrict_refcnt) <= 0)
-               IWL_ERR(priv, "Release unheld nic access at line %s %d.\n", f, l);
 
        IWL_DEBUG_IO(priv, "releasing nic access - %s %d\n", f, l);
        _iwl_release_nic_access(priv);
@@ -230,16 +245,37 @@ static inline u32 __iwl_read_direct32(const char *f, u32 l,
                                        struct iwl_priv *priv, u32 reg)
 {
        u32 value = _iwl_read_direct32(priv, reg);
-       if (!atomic_read(&priv->restrict_refcnt))
-               IWL_ERR(priv, "Nic access not held from %s %d\n", f, l);
        IWL_DEBUG_IO(priv, "read_direct32(0x%4X) = 0x%08x - %s %d \n", reg, value,
                     f, l);
        return value;
 }
-#define iwl_read_direct32(priv, reg) \
-       __iwl_read_direct32(__FILE__, __LINE__, priv, reg)
+static inline u32 iwl_read_direct32(struct iwl_priv *priv, u32 reg)
+{
+       u32 value;
+       unsigned long reg_flags;
+
+       spin_lock_irqsave(&priv->reg_lock, reg_flags);
+       iwl_grab_nic_access(priv);
+       value = __iwl_read_direct32(__FILE__, __LINE__, priv, reg);
+       iwl_release_nic_access(priv);
+       spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
+       return value;
+}
+
 #else
-#define iwl_read_direct32 _iwl_read_direct32
+static inline u32 iwl_read_direct32(struct iwl_priv *priv, u32 reg)
+{
+       u32 value;
+       unsigned long reg_flags;
+
+       spin_lock_irqsave(&priv->reg_lock, reg_flags);
+       iwl_grab_nic_access(priv);
+       value = _iwl_read_direct32(priv, reg);
+       iwl_release_nic_access(priv);
+       spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
+       return value;
+
+}
 #endif
 
 static inline void _iwl_write_direct32(struct iwl_priv *priv,
@@ -247,19 +283,17 @@ static inline void _iwl_write_direct32(struct iwl_priv *priv,
 {
        _iwl_write32(priv, reg, value);
 }
-#ifdef CONFIG_IWLWIFI_DEBUG
-static void __iwl_write_direct32(const char *f , u32 line,
-                                  struct iwl_priv *priv, u32 reg, u32 value)
+static inline void iwl_write_direct32(struct iwl_priv *priv, u32 reg, u32 value)
 {
-       if (!atomic_read(&priv->restrict_refcnt))
-               IWL_ERR(priv, "Nic access not held from %s line %d\n", f, line);
-       _iwl_write_direct32(priv, reg, value);
+       unsigned long reg_flags;
+
+       spin_lock_irqsave(&priv->reg_lock, reg_flags);
+       if (!iwl_grab_nic_access(priv)) {
+               _iwl_write_direct32(priv, reg, value);
+               iwl_release_nic_access(priv);
+       }
+       spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
 }
-#define iwl_write_direct32(priv, reg, value) \
-       __iwl_write_direct32(__func__, __LINE__, priv, reg, value)
-#else
-#define iwl_write_direct32 _iwl_write_direct32
-#endif
 
 static inline void iwl_write_reg_buf(struct iwl_priv *priv,
                                               u32 reg, u32 len, u32 *values)
@@ -268,14 +302,23 @@ static inline void iwl_write_reg_buf(struct iwl_priv *priv,
 
        if ((priv != NULL) && (values != NULL)) {
                for (; 0 < len; len -= count, reg += count, values++)
-                       _iwl_write_direct32(priv, reg, *values);
+                       iwl_write_direct32(priv, reg, *values);
        }
 }
 
 static inline int _iwl_poll_direct_bit(struct iwl_priv *priv, u32 addr,
                                       u32 mask, int timeout)
 {
-       return _iwl_poll_bit(priv, addr, mask, mask, timeout);
+       int t = 0;
+
+       do {
+               if ((iwl_read_direct32(priv, addr) & mask) == mask)
+                       return t;
+               udelay(IWL_POLL_INTERVAL);
+               t += IWL_POLL_INTERVAL;
+       } while (t < timeout);
+
+       return -ETIMEDOUT;
 }
 
 #ifdef CONFIG_IWLWIFI_DEBUG
@@ -305,20 +348,18 @@ static inline u32 _iwl_read_prph(struct iwl_priv *priv, u32 reg)
        rmb();
        return _iwl_read_direct32(priv, HBUS_TARG_PRPH_RDAT);
 }
-#ifdef CONFIG_IWLWIFI_DEBUG
-static inline u32 __iwl_read_prph(const char *f, u32 line,
-                                 struct iwl_priv *priv, u32 reg)
+static inline u32 iwl_read_prph(struct iwl_priv *priv, u32 reg)
 {
-       if (!atomic_read(&priv->restrict_refcnt))
-               IWL_ERR(priv, "Nic access not held from %s line %d\n", f, line);
-       return _iwl_read_prph(priv, reg);
-}
+       unsigned long reg_flags;
+       u32 val;
 
-#define iwl_read_prph(priv, reg) \
-       __iwl_read_prph(__func__, __LINE__, priv, reg)
-#else
-#define iwl_read_prph _iwl_read_prph
-#endif
+       spin_lock_irqsave(&priv->reg_lock, reg_flags);
+       iwl_grab_nic_access(priv);
+       val = _iwl_read_prph(priv, reg);
+       iwl_release_nic_access(priv);
+       spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
+       return val;
+}
 
 static inline void _iwl_write_prph(struct iwl_priv *priv,
                                             u32 addr, u32 val)
@@ -328,83 +369,107 @@ static inline void _iwl_write_prph(struct iwl_priv *priv,
        wmb();
        _iwl_write_direct32(priv, HBUS_TARG_PRPH_WDAT, val);
 }
-#ifdef CONFIG_IWLWIFI_DEBUG
-static inline void __iwl_write_prph(const char *f, u32 line,
-                                   struct iwl_priv *priv, u32 addr, u32 val)
+
+static inline void iwl_write_prph(struct iwl_priv *priv, u32 addr, u32 val)
 {
-       if (!atomic_read(&priv->restrict_refcnt))
-               IWL_ERR(priv, "Nic access not held from %s line %d\n", f, line);
-       _iwl_write_prph(priv, addr, val);
-}
+       unsigned long reg_flags;
 
-#define iwl_write_prph(priv, addr, val) \
-       __iwl_write_prph(__func__, __LINE__, priv, addr, val);
-#else
-#define iwl_write_prph _iwl_write_prph
-#endif
+       spin_lock_irqsave(&priv->reg_lock, reg_flags);
+       if (!iwl_grab_nic_access(priv)) {
+               _iwl_write_prph(priv, addr, val);
+               iwl_release_nic_access(priv);
+       }
+       spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
+}
 
 #define _iwl_set_bits_prph(priv, reg, mask) \
        _iwl_write_prph(priv, reg, (_iwl_read_prph(priv, reg) | mask))
-#ifdef CONFIG_IWLWIFI_DEBUG
-static inline void __iwl_set_bits_prph(const char *f, u32 line,
-                                      struct iwl_priv *priv,
-                                      u32 reg, u32 mask)
+
+static inline void iwl_set_bits_prph(struct iwl_priv *priv, u32 reg, u32 mask)
 {
-       if (!atomic_read(&priv->restrict_refcnt))
-               IWL_ERR(priv, "Nic access not held from %s line %d\n", f, line);
+       unsigned long reg_flags;
 
+       spin_lock_irqsave(&priv->reg_lock, reg_flags);
+       iwl_grab_nic_access(priv);
        _iwl_set_bits_prph(priv, reg, mask);
+       iwl_release_nic_access(priv);
+       spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
 }
-#define iwl_set_bits_prph(priv, reg, mask) \
-       __iwl_set_bits_prph(__func__, __LINE__, priv, reg, mask)
-#else
-#define iwl_set_bits_prph _iwl_set_bits_prph
-#endif
 
 #define _iwl_set_bits_mask_prph(priv, reg, bits, mask) \
        _iwl_write_prph(priv, reg, ((_iwl_read_prph(priv, reg) & mask) | bits))
 
-#ifdef CONFIG_IWLWIFI_DEBUG
-static inline void __iwl_set_bits_mask_prph(const char *f, u32 line,
-               struct iwl_priv *priv, u32 reg, u32 bits, u32 mask)
+static inline void iwl_set_bits_mask_prph(struct iwl_priv *priv, u32 reg,
+                               u32 bits, u32 mask)
 {
-       if (!atomic_read(&priv->restrict_refcnt))
-               IWL_ERR(priv, "Nic access not held from %s line %d\n", f, line);
+       unsigned long reg_flags;
+
+       spin_lock_irqsave(&priv->reg_lock, reg_flags);
+       iwl_grab_nic_access(priv);
        _iwl_set_bits_mask_prph(priv, reg, bits, mask);
+       iwl_release_nic_access(priv);
+       spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
 }
-#define iwl_set_bits_mask_prph(priv, reg, bits, mask) \
-       __iwl_set_bits_mask_prph(__func__, __LINE__, priv, reg, bits, mask)
-#else
-#define iwl_set_bits_mask_prph _iwl_set_bits_mask_prph
-#endif
 
 static inline void iwl_clear_bits_prph(struct iwl_priv
                                                 *priv, u32 reg, u32 mask)
 {
-       u32 val = _iwl_read_prph(priv, reg);
+       unsigned long reg_flags;
+       u32 val;
+
+       spin_lock_irqsave(&priv->reg_lock, reg_flags);
+       iwl_grab_nic_access(priv);
+       val = _iwl_read_prph(priv, reg);
        _iwl_write_prph(priv, reg, (val & ~mask));
+       iwl_release_nic_access(priv);
+       spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
 }
 
 static inline u32 iwl_read_targ_mem(struct iwl_priv *priv, u32 addr)
 {
-       iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, addr);
+       unsigned long reg_flags;
+       u32 value;
+
+       spin_lock_irqsave(&priv->reg_lock, reg_flags);
+       iwl_grab_nic_access(priv);
+
+       _iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, addr);
        rmb();
-       return iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
+       value = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
+
+       iwl_release_nic_access(priv);
+       spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
+       return value;
 }
 
 static inline void iwl_write_targ_mem(struct iwl_priv *priv, u32 addr, u32 val)
 {
-       iwl_write_direct32(priv, HBUS_TARG_MEM_WADDR, addr);
-       wmb();
-       iwl_write_direct32(priv, HBUS_TARG_MEM_WDAT, val);
+       unsigned long reg_flags;
+
+       spin_lock_irqsave(&priv->reg_lock, reg_flags);
+       if (!iwl_grab_nic_access(priv)) {
+               _iwl_write_direct32(priv, HBUS_TARG_MEM_WADDR, addr);
+               wmb();
+               _iwl_write_direct32(priv, HBUS_TARG_MEM_WDAT, val);
+               iwl_release_nic_access(priv);
+       }
+       spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
 }
 
 static inline void iwl_write_targ_mem_buf(struct iwl_priv *priv, u32 addr,
                                          u32 len, u32 *values)
 {
-       iwl_write_direct32(priv, HBUS_TARG_MEM_WADDR, addr);
-       wmb();
-       for (; 0 < len; len -= sizeof(u32), values++)
-               iwl_write_direct32(priv, HBUS_TARG_MEM_WDAT, *values);
+       unsigned long reg_flags;
+
+       spin_lock_irqsave(&priv->reg_lock, reg_flags);
+       if (!iwl_grab_nic_access(priv)) {
+               _iwl_write_direct32(priv, HBUS_TARG_MEM_WADDR, addr);
+               wmb();
+               for (; 0 < len; len -= sizeof(u32), values++)
+                       _iwl_write_direct32(priv, HBUS_TARG_MEM_WDAT, *values);
+
+               iwl_release_nic_access(priv);
+       }
+       spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
 }
 #endif
index 19680f72087fc5d84bf100fce29365043689b754..5e64252f80f6f7059b258cd4abd0ef3c8a67c13e 100644 (file)
@@ -176,10 +176,6 @@ static int iwl_led_associate(struct iwl_priv *priv, int led_id)
 static int iwl_led_disassociate(struct iwl_priv *priv, int led_id)
 {
        priv->allow_blinking = 0;
-       if (iwl_is_rfkill(priv))
-               iwl4965_led_off_reg(priv, led_id);
-       else
-               iwl4965_led_on_reg(priv, led_id);
 
        return 0;
 }
index 47c894530eb583e978e17c2f1002a0871620def2..f2ea3f05f6e13f9caedf37b309c6229057847db0 100644 (file)
 #include "iwl-power.h"
 
 /*
- * Setting power level allow the card to go to sleep when not busy
- * there are three factor that decide the power level to go to, they
- * are list here with its priority
- *  1- critical_power_setting this will be set according to card temperature.
- *  2- system_power_setting this will be set by system PM manager.
- *  3- user_power_setting this will be set by user either by writing to sys or
- *     mac80211
+ * Setting power level allow the card to go to sleep when not busy.
  *
- * if system_power_setting and user_power_setting is set to auto
- * the power level will be decided according to association status and battery
- * status.
+ * The power level is set to INDEX_1 (the least deep state) by
+ * default, and will, in the future, be the deepest state unless
+ * otherwise required by pm_qos network latency requirements.
  *
+ * Using INDEX_1 without pm_qos is ok because mac80211 will disable
+ * PS when even checking every beacon for the TIM bit would exceed
+ * the required latency.
  */
 
-#define MSEC_TO_USEC 1024
 #define IWL_POWER_RANGE_0_MAX  (2)
 #define IWL_POWER_RANGE_1_MAX  (10)
 
 
-
-#define IWL_POWER_ON_BATTERY           IWL_POWER_INDEX_5
-#define IWL_POWER_ON_AC_DISASSOC       IWL_POWER_MODE_CAM
-#define IWL_POWER_ON_AC_ASSOC          IWL_POWER_MODE_CAM
-
-
-#define IWL_CT_KILL_TEMPERATURE                110
-#define IWL_MIN_POWER_TEMPERATURE      100
-#define IWL_REDUCED_POWER_TEMPERATURE  95
-
+#define NOSLP cpu_to_le16(0), 0, 0
+#define SLP IWL_POWER_DRIVER_ALLOW_SLEEP_MSK, 0, 0
+#define TU_TO_USEC 1024
+#define SLP_TOUT(T) cpu_to_le32((T) * TU_TO_USEC)
+#define SLP_VEC(X0, X1, X2, X3, X4) {cpu_to_le32(X0), \
+                                    cpu_to_le32(X1), \
+                                    cpu_to_le32(X2), \
+                                    cpu_to_le32(X3), \
+                                    cpu_to_le32(X4)}
 /* default power management (not Tx power) table values */
-/* for TIM  0-10 */
-static struct iwl_power_vec_entry range_0[IWL_POWER_MAX] = {
+/* for DTIM period 0 through IWL_POWER_RANGE_0_MAX */
+static const struct iwl_power_vec_entry range_0[IWL_POWER_NUM] = {
        {{NOSLP, SLP_TOUT(0), SLP_TOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0},
        {{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 2, 2, 0xFF)}, 0},
        {{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(1, 2, 2, 2, 0xFF)}, 0},
@@ -82,8 +77,8 @@ static struct iwl_power_vec_entry range_0[IWL_POWER_MAX] = {
 };
 
 
-/* for TIM = 3-10 */
-static struct iwl_power_vec_entry range_1[IWL_POWER_MAX] = {
+/* for DTIM period IWL_POWER_RANGE_0_MAX + 1 through IWL_POWER_RANGE_1_MAX */
+static const struct iwl_power_vec_entry range_1[IWL_POWER_NUM] = {
        {{NOSLP, SLP_TOUT(0), SLP_TOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0},
        {{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 3, 4, 4)}, 0},
        {{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(1, 2, 3, 4, 7)}, 0},
@@ -92,8 +87,8 @@ static struct iwl_power_vec_entry range_1[IWL_POWER_MAX] = {
        {{SLP, SLP_TOUT(25), SLP_TOUT(25), SLP_VEC(2, 4, 7, 10, 10)}, 2}
 };
 
-/* for TIM > 11 */
-static struct iwl_power_vec_entry range_2[IWL_POWER_MAX] = {
+/* for DTIM period > IWL_POWER_RANGE_1_MAX */
+static const struct iwl_power_vec_entry range_2[IWL_POWER_NUM] = {
        {{NOSLP, SLP_TOUT(0), SLP_TOUT(0), SLP_VEC(0, 0, 0, 0, 0)}, 0},
        {{SLP, SLP_TOUT(200), SLP_TOUT(500), SLP_VEC(1, 2, 3, 4, 0xFF)}, 0},
        {{SLP, SLP_TOUT(200), SLP_TOUT(300), SLP_VEC(2, 4, 6, 7, 0xFF)}, 0},
@@ -106,39 +101,15 @@ static struct iwl_power_vec_entry range_2[IWL_POWER_MAX] = {
 /* set card power command */
 static int iwl_set_power(struct iwl_priv *priv, void *cmd)
 {
-       return iwl_send_cmd_pdu_async(priv, POWER_TABLE_CMD,
-                                     sizeof(struct iwl_powertable_cmd),
-                                     cmd, NULL);
-}
-/* decide the right power level according to association status
- * and battery status
- */
-static u16 iwl_get_auto_power_mode(struct iwl_priv *priv)
-{
-       u16 mode;
-
-       switch (priv->power_data.user_power_setting) {
-       case IWL_POWER_AUTO:
-               /* if running on battery */
-               if (priv->power_data.is_battery_active)
-                       mode = IWL_POWER_ON_BATTERY;
-               else if (iwl_is_associated(priv))
-                       mode = IWL_POWER_ON_AC_ASSOC;
-               else
-                       mode = IWL_POWER_ON_AC_DISASSOC;
-               break;
-       default:
-               mode = priv->power_data.user_power_setting;
-               break;
-       }
-       return mode;
+       return iwl_send_cmd_pdu(priv, POWER_TABLE_CMD,
+                               sizeof(struct iwl_powertable_cmd), cmd);
 }
 
 /* initialize to default */
 static void iwl_power_init_handle(struct iwl_priv *priv)
 {
        struct iwl_power_mgr *pow_data;
-       int size = sizeof(struct iwl_power_vec_entry) * IWL_POWER_MAX;
+       int size = sizeof(struct iwl_power_vec_entry) * IWL_POWER_NUM;
        struct iwl_powertable_cmd *cmd;
        int i;
        u16 lctl;
@@ -157,7 +128,7 @@ static void iwl_power_init_handle(struct iwl_priv *priv)
 
        IWL_DEBUG_POWER(priv, "adjust power command flags\n");
 
-       for (i = 0; i < IWL_POWER_MAX; i++) {
+       for (i = 0; i < IWL_POWER_NUM; i++) {
                cmd = &pow_data->pwr_range_0[i].cmd;
 
                if (lctl & PCI_CFG_LINK_CTRL_VAL_L0S_EN)
@@ -247,33 +218,12 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force)
        update_chains = priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE ||
                        priv->chain_noise_data.state == IWL_CHAIN_NOISE_ALIVE;
 
-       /* If on battery, set to 3,
-        * if plugged into AC power, set to CAM ("continuously aware mode"),
-        * else user level */
-
-       switch (setting->system_power_setting) {
-       case IWL_POWER_SYS_AUTO:
-               final_mode = iwl_get_auto_power_mode(priv);
-               break;
-       case IWL_POWER_SYS_BATTERY:
-               final_mode = IWL_POWER_INDEX_3;
-               break;
-       case IWL_POWER_SYS_AC:
-               final_mode = IWL_POWER_MODE_CAM;
-               break;
-       default:
-               final_mode = IWL_POWER_INDEX_3;
-               WARN_ON(1);
-       }
-
-       if (setting->critical_power_setting > final_mode)
-               final_mode = setting->critical_power_setting;
+       final_mode = priv->power_data.user_power_setting;
 
-       /* driver only support CAM for non STA network */
-       if (priv->iw_mode != NL80211_IFTYPE_STATION)
+       if (setting->power_disabled)
                final_mode = IWL_POWER_MODE_CAM;
 
-       if (iwl_is_ready_rf(priv) && !setting->power_disabled &&
+       if (iwl_is_ready_rf(priv) &&
            ((setting->power_mode != final_mode) || force)) {
                struct iwl_powertable_cmd cmd;
 
@@ -290,8 +240,6 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force)
 
                if (final_mode == IWL_POWER_MODE_CAM)
                        clear_bit(STATUS_POWER_PMI, &priv->status);
-               else
-                       set_bit(STATUS_POWER_PMI, &priv->status);
 
                if (priv->cfg->ops->lib->update_chain_flags && update_chains)
                        priv->cfg->ops->lib->update_chain_flags(priv);
@@ -307,51 +255,10 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force)
 }
 EXPORT_SYMBOL(iwl_power_update_mode);
 
-/* Allow other iwl code to disable/enable power management active
- * this will be useful for rate scale to disable PM during heavy
- * Tx/Rx activities
- */
-int iwl_power_disable_management(struct iwl_priv *priv, u32 ms)
-{
-       u16 prev_mode;
-       int ret = 0;
-
-       if (priv->power_data.power_disabled)
-               return -EBUSY;
-
-       prev_mode = priv->power_data.user_power_setting;
-       priv->power_data.user_power_setting = IWL_POWER_MODE_CAM;
-       ret = iwl_power_update_mode(priv, 0);
-       priv->power_data.power_disabled = 1;
-       priv->power_data.user_power_setting = prev_mode;
-       cancel_delayed_work(&priv->set_power_save);
-       if (ms)
-               queue_delayed_work(priv->workqueue, &priv->set_power_save,
-                                  msecs_to_jiffies(ms));
-
-
-       return ret;
-}
-EXPORT_SYMBOL(iwl_power_disable_management);
-
-/* Allow other iwl code to disable/enable power management active
- * this will be useful for rate scale to disable PM during high
- * volume activities
- */
-int iwl_power_enable_management(struct iwl_priv *priv)
-{
-       int ret = 0;
-
-       priv->power_data.power_disabled = 0;
-       ret = iwl_power_update_mode(priv, 0);
-       return ret;
-}
-EXPORT_SYMBOL(iwl_power_enable_management);
-
 /* set user_power_setting */
 int iwl_power_set_user_mode(struct iwl_priv *priv, u16 mode)
 {
-       if (mode > IWL_POWER_MAX)
+       if (mode >= IWL_POWER_NUM)
                return -EINVAL;
 
        priv->power_data.user_power_setting = mode;
@@ -360,86 +267,12 @@ int iwl_power_set_user_mode(struct iwl_priv *priv, u16 mode)
 }
 EXPORT_SYMBOL(iwl_power_set_user_mode);
 
-/* set system_power_setting. This should be set by over all
- * PM application.
- */
-int iwl_power_set_system_mode(struct iwl_priv *priv, u16 mode)
-{
-       if (mode < IWL_POWER_SYS_MAX)
-               priv->power_data.system_power_setting = mode;
-       else
-               return -EINVAL;
-       return iwl_power_update_mode(priv, 0);
-}
-EXPORT_SYMBOL(iwl_power_set_system_mode);
-
 /* initialize to default */
 void iwl_power_initialize(struct iwl_priv *priv)
 {
        iwl_power_init_handle(priv);
-       priv->power_data.user_power_setting = IWL_POWER_AUTO;
-       priv->power_data.system_power_setting = IWL_POWER_SYS_AUTO;
-       priv->power_data.power_disabled = 0;
-       priv->power_data.is_battery_active = 0;
-       priv->power_data.critical_power_setting = 0;
+       priv->power_data.user_power_setting = IWL_POWER_INDEX_1;
+       /* default to disabled until mac80211 says otherwise */
+       priv->power_data.power_disabled = 1;
 }
 EXPORT_SYMBOL(iwl_power_initialize);
-
-/* set critical_power_setting according to temperature value */
-int iwl_power_temperature_change(struct iwl_priv *priv)
-{
-       int ret = 0;
-       s32 temperature = KELVIN_TO_CELSIUS(priv->last_temperature);
-       u16 new_critical = priv->power_data.critical_power_setting;
-
-       if (temperature > IWL_CT_KILL_TEMPERATURE)
-               return 0;
-       else if (temperature > IWL_MIN_POWER_TEMPERATURE)
-               new_critical = IWL_POWER_INDEX_5;
-       else if (temperature > IWL_REDUCED_POWER_TEMPERATURE)
-               new_critical = IWL_POWER_INDEX_3;
-       else
-               new_critical = IWL_POWER_MODE_CAM;
-
-       if (new_critical != priv->power_data.critical_power_setting)
-               priv->power_data.critical_power_setting = new_critical;
-
-       if (priv->power_data.critical_power_setting >
-                               priv->power_data.power_mode)
-               ret = iwl_power_update_mode(priv, 0);
-
-       return ret;
-}
-EXPORT_SYMBOL(iwl_power_temperature_change);
-
-static void iwl_bg_set_power_save(struct work_struct *work)
-{
-       struct iwl_priv *priv = container_of(work,
-                               struct iwl_priv, set_power_save.work);
-       IWL_DEBUG_POWER(priv, "update power\n");
-
-       if (test_bit(STATUS_EXIT_PENDING, &priv->status))
-               return;
-
-       mutex_lock(&priv->mutex);
-
-       /* on starting association we disable power management
-        * until association, if association failed then this
-        * timer will expire and enable PM again.
-        */
-       if (!iwl_is_associated(priv))
-               iwl_power_enable_management(priv);
-
-       mutex_unlock(&priv->mutex);
-}
-void iwl_setup_power_deferred_work(struct iwl_priv *priv)
-{
-       INIT_DELAYED_WORK(&priv->set_power_save, iwl_bg_set_power_save);
-}
-EXPORT_SYMBOL(iwl_setup_power_deferred_work);
-
-void iwl_power_cancel_timeout(struct iwl_priv *priv)
-{
-       cancel_delayed_work(&priv->set_power_save);
-}
-EXPORT_SYMBOL(iwl_power_cancel_timeout);
index 18963392121e9606b258d6764491e72282d1d2e5..37ba3bb7a25a1f353986235d9326f869c019dd54 100644 (file)
@@ -40,56 +40,29 @@ enum {
        IWL_POWER_INDEX_3,
        IWL_POWER_INDEX_4,
        IWL_POWER_INDEX_5,
-       IWL_POWER_AUTO,
-       IWL_POWER_MAX = IWL_POWER_AUTO,
+       IWL_POWER_NUM
 };
 
-enum {
-       IWL_POWER_SYS_AUTO,
-       IWL_POWER_SYS_AC,
-       IWL_POWER_SYS_BATTERY,
-       IWL_POWER_SYS_MAX,
-};
-
-
 /* Power management (not Tx power) structures */
 
-#define NOSLP cpu_to_le16(0), 0, 0
-#define SLP IWL_POWER_DRIVER_ALLOW_SLEEP_MSK, 0, 0
-#define SLP_TOUT(T) cpu_to_le32((T) * MSEC_TO_USEC)
-#define SLP_VEC(X0, X1, X2, X3, X4) {cpu_to_le32(X0), \
-                                    cpu_to_le32(X1), \
-                                    cpu_to_le32(X2), \
-                                    cpu_to_le32(X3), \
-                                    cpu_to_le32(X4)}
 struct iwl_power_vec_entry {
        struct iwl_powertable_cmd cmd;
        u8 no_dtim;
 };
 
 struct iwl_power_mgr {
-       spinlock_t lock;
-       struct iwl_power_vec_entry pwr_range_0[IWL_POWER_MAX];
-       struct iwl_power_vec_entry pwr_range_1[IWL_POWER_MAX];
-       struct iwl_power_vec_entry pwr_range_2[IWL_POWER_MAX];
+       struct iwl_power_vec_entry pwr_range_0[IWL_POWER_NUM];
+       struct iwl_power_vec_entry pwr_range_1[IWL_POWER_NUM];
+       struct iwl_power_vec_entry pwr_range_2[IWL_POWER_NUM];
        u32 dtim_period;
        /* final power level that used to calculate final power command */
        u8 power_mode;
-       u8 user_power_setting; /* set by user through mac80211 or sysfs */
-       u8 system_power_setting; /* set by kernel system tools */
-       u8 critical_power_setting; /* set if driver over heated */
-       u8 is_battery_active; /* DC/AC power */
-       u8 power_disabled; /* flag to disable using power saving level */
+       u8 user_power_setting; /* set by user through sysfs */
+       u8 power_disabled; /* set by mac80211's CONF_PS */
 };
 
-void iwl_setup_power_deferred_work(struct iwl_priv *priv);
-void iwl_power_cancel_timeout(struct iwl_priv *priv);
 int iwl_power_update_mode(struct iwl_priv *priv, bool force);
-int iwl_power_disable_management(struct iwl_priv *priv, u32 ms);
-int iwl_power_enable_management(struct iwl_priv *priv);
 int iwl_power_set_user_mode(struct iwl_priv *priv, u16 mode);
-int iwl_power_set_system_mode(struct iwl_priv *priv, u16 mode);
 void iwl_power_initialize(struct iwl_priv *priv);
-int iwl_power_temperature_change(struct iwl_priv *priv);
 
 #endif  /* __iwl_power_setting_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-rfkill.c b/drivers/net/wireless/iwlwifi/iwl-rfkill.c
deleted file mode 100644 (file)
index 2ad9faf..0000000
+++ /dev/null
@@ -1,145 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2003 - 2009 Intel Corporation. All rights reserved.
- *
- * Portions of this file are derived from the ipw3945 project, as well
- * as portions of the ieee80211 subsystem header files.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- * The full GNU General Public License is included in this distribution in the
- * file called LICENSE.
- *
- * Contact Information:
- *  Intel Linux Wireless <ilw@linux.intel.com>
- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
- *****************************************************************************/
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-
-#include <net/mac80211.h>
-
-#include "iwl-eeprom.h"
-#include "iwl-dev.h"
-#include "iwl-core.h"
-
-/* software rf-kill from user */
-static int iwl_rfkill_soft_rf_kill(void *data, enum rfkill_state state)
-{
-       struct iwl_priv *priv = data;
-       int err = 0;
-
-       if (!priv->rfkill)
-               return 0;
-
-       if (test_bit(STATUS_EXIT_PENDING, &priv->status))
-               return 0;
-
-       IWL_DEBUG_RF_KILL(priv, "we received soft RFKILL set to state %d\n", state);
-       mutex_lock(&priv->mutex);
-
-       switch (state) {
-       case RFKILL_STATE_UNBLOCKED:
-               if (iwl_is_rfkill_hw(priv)) {
-                       err = -EBUSY;
-                       goto out_unlock;
-               }
-               iwl_radio_kill_sw_enable_radio(priv);
-               break;
-       case RFKILL_STATE_SOFT_BLOCKED:
-               iwl_radio_kill_sw_disable_radio(priv);
-               break;
-       default:
-               IWL_WARN(priv, "we received unexpected RFKILL state %d\n",
-                       state);
-               break;
-       }
-out_unlock:
-       mutex_unlock(&priv->mutex);
-
-       return err;
-}
-
-int iwl_rfkill_init(struct iwl_priv *priv)
-{
-       struct device *device = wiphy_dev(priv->hw->wiphy);
-       int ret = 0;
-
-       BUG_ON(device == NULL);
-
-       IWL_DEBUG_RF_KILL(priv, "Initializing RFKILL.\n");
-       priv->rfkill = rfkill_allocate(device, RFKILL_TYPE_WLAN);
-       if (!priv->rfkill) {
-               IWL_ERR(priv, "Unable to allocate RFKILL device.\n");
-               ret = -ENOMEM;
-               goto error;
-       }
-
-       priv->rfkill->name = priv->cfg->name;
-       priv->rfkill->data = priv;
-       priv->rfkill->state = RFKILL_STATE_UNBLOCKED;
-       priv->rfkill->toggle_radio = iwl_rfkill_soft_rf_kill;
-       priv->rfkill->user_claim_unsupported = 1;
-
-       priv->rfkill->dev.class->suspend = NULL;
-       priv->rfkill->dev.class->resume = NULL;
-
-       ret = rfkill_register(priv->rfkill);
-       if (ret) {
-               IWL_ERR(priv, "Unable to register RFKILL: %d\n", ret);
-               goto free_rfkill;
-       }
-
-       IWL_DEBUG_RF_KILL(priv, "RFKILL initialization complete.\n");
-       return ret;
-
-free_rfkill:
-       if (priv->rfkill != NULL)
-               rfkill_free(priv->rfkill);
-       priv->rfkill = NULL;
-
-error:
-       IWL_DEBUG_RF_KILL(priv, "RFKILL initialization complete.\n");
-       return ret;
-}
-EXPORT_SYMBOL(iwl_rfkill_init);
-
-void iwl_rfkill_unregister(struct iwl_priv *priv)
-{
-
-       if (priv->rfkill)
-               rfkill_unregister(priv->rfkill);
-
-       priv->rfkill = NULL;
-}
-EXPORT_SYMBOL(iwl_rfkill_unregister);
-
-/* set RFKILL to the right state. */
-void iwl_rfkill_set_hw_state(struct iwl_priv *priv)
-{
-       if (!priv->rfkill)
-               return;
-
-       if (iwl_is_rfkill_hw(priv)) {
-               rfkill_force_state(priv->rfkill, RFKILL_STATE_HARD_BLOCKED);
-               return;
-       }
-
-       if (!iwl_is_rfkill_sw(priv))
-               rfkill_force_state(priv->rfkill, RFKILL_STATE_UNBLOCKED);
-       else
-               rfkill_force_state(priv->rfkill, RFKILL_STATE_SOFT_BLOCKED);
-}
-EXPORT_SYMBOL(iwl_rfkill_set_hw_state);
diff --git a/drivers/net/wireless/iwlwifi/iwl-rfkill.h b/drivers/net/wireless/iwlwifi/iwl-rfkill.h
deleted file mode 100644 (file)
index 633dafb..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2007 - 2009 Intel Corporation. All rights reserved.
- *
- * Portions of this file are derived from the ipw3945 project, as well
- * as portions of the ieee80211 subsystem header files.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License 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.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- * The full GNU General Public License is included in this distribution in the
- * file called LICENSE.
- *
- * Contact Information:
- *  Intel Linux Wireless <ilw@linux.intel.com>
- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
- *****************************************************************************/
-#ifndef __iwl_rf_kill_h__
-#define __iwl_rf_kill_h__
-
-struct iwl_priv;
-
-#include <linux/rfkill.h>
-
-#ifdef CONFIG_IWLWIFI_RFKILL
-
-void iwl_rfkill_set_hw_state(struct iwl_priv *priv);
-void iwl_rfkill_unregister(struct iwl_priv *priv);
-int iwl_rfkill_init(struct iwl_priv *priv);
-#else
-static inline void iwl_rfkill_set_hw_state(struct iwl_priv *priv) {}
-static inline void iwl_rfkill_unregister(struct iwl_priv *priv) {}
-static inline int iwl_rfkill_init(struct iwl_priv *priv) { return 0; }
-#endif
-
-
-
-#endif  /* __iwl_rf_kill_h__ */
index 8f65908f66f1498f4e1c1ca3b3414815b1e75e22..2b8d40b37a1c9e1be70e0989b4fc2820faf9290e 100644 (file)
@@ -145,18 +145,14 @@ int iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q)
                        goto exit_unlock;
                }
 
-               ret = iwl_grab_nic_access(priv);
-               if (ret)
-                       goto exit_unlock;
-
-               /* Device expects a multiple of 8 */
-               iwl_write_direct32(priv, rx_wrt_ptr_reg, q->write & ~0x7);
-               iwl_release_nic_access(priv);
+               q->write_actual = (q->write & ~0x7);
+               iwl_write_direct32(priv, rx_wrt_ptr_reg, q->write_actual);
 
        /* Else device is assumed to be awake */
        } else {
                /* Device expects a multiple of 8 */
-               iwl_write32(priv, rx_wrt_ptr_reg, q->write & ~0x7);
+               q->write_actual = (q->write & ~0x7);
+               iwl_write_direct32(priv, rx_wrt_ptr_reg, q->write_actual);
        }
 
        q->need_update = 0;
@@ -218,7 +214,7 @@ int iwl_rx_queue_restock(struct iwl_priv *priv)
 
        /* If we've added more space for the firmware to place data, tell it.
         * Increment device's write pointer in multiples of 8. */
-       if (write != (rxq->write & ~0x7)) {
+       if (rxq->write_actual != (rxq->write & ~0x7)) {
                spin_lock_irqsave(&rxq->lock, flags);
                rxq->need_update = 1;
                spin_unlock_irqrestore(&rxq->lock, flags);
@@ -238,7 +234,7 @@ EXPORT_SYMBOL(iwl_rx_queue_restock);
  * Also restock the Rx queue via iwl_rx_queue_restock.
  * This is called as a scheduled work item (except for during initialization)
  */
-void iwl_rx_allocate(struct iwl_priv *priv)
+void iwl_rx_allocate(struct iwl_priv *priv, gfp_t priority)
 {
        struct iwl_rx_queue *rxq = &priv->rxq;
        struct list_head *element;
@@ -260,7 +256,8 @@ void iwl_rx_allocate(struct iwl_priv *priv)
 
                /* Alloc a new receive buffer */
                rxb->skb = alloc_skb(priv->hw_params.rx_buf_size + 256,
-                                    GFP_KERNEL);
+                                               priority);
+
                if (!rxb->skb) {
                        IWL_CRIT(priv, "Can not allocate SKB buffers\n");
                        /* We don't reschedule replenish work here -- we will
@@ -295,7 +292,7 @@ void iwl_rx_replenish(struct iwl_priv *priv)
 {
        unsigned long flags;
 
-       iwl_rx_allocate(priv);
+       iwl_rx_allocate(priv, GFP_KERNEL);
 
        spin_lock_irqsave(&priv->lock, flags);
        iwl_rx_queue_restock(priv);
@@ -303,6 +300,14 @@ void iwl_rx_replenish(struct iwl_priv *priv)
 }
 EXPORT_SYMBOL(iwl_rx_replenish);
 
+void iwl_rx_replenish_now(struct iwl_priv *priv)
+{
+       iwl_rx_allocate(priv, GFP_ATOMIC);
+
+       iwl_rx_queue_restock(priv);
+}
+EXPORT_SYMBOL(iwl_rx_replenish_now);
+
 
 /* Assumes that the skb field of the buffers in 'pool' is kept accurate.
  * If an SKB has been detached, the POOL needs to have its SKB set to NULL
@@ -358,6 +363,7 @@ int iwl_rx_queue_alloc(struct iwl_priv *priv)
        /* Set us so that we have processed and used all buffers, but have
         * not restocked the Rx queue with fresh buffers */
        rxq->read = rxq->write = 0;
+       rxq->write_actual = 0;
        rxq->free_count = 0;
        rxq->need_update = 0;
        return 0;
@@ -396,6 +402,7 @@ void iwl_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
        /* Set us so that we have processed and used all buffers, but have
         * not restocked the Rx queue with fresh buffers */
        rxq->read = rxq->write = 0;
+       rxq->write_actual = 0;
        rxq->free_count = 0;
        spin_unlock_irqrestore(&rxq->lock, flags);
 }
@@ -403,18 +410,12 @@ EXPORT_SYMBOL(iwl_rx_queue_reset);
 
 int iwl_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
 {
-       int ret;
-       unsigned long flags;
        u32 rb_size;
        const u32 rfdnlog = RX_QUEUE_SIZE_LOG; /* 256 RBDs */
-       const u32 rb_timeout = 0; /* FIXME: RX_RB_TIMEOUT why this stalls RX */
+       u32 rb_timeout = 0; /* FIXME: RX_RB_TIMEOUT for all devices? */
 
-       spin_lock_irqsave(&priv->lock, flags);
-       ret = iwl_grab_nic_access(priv);
-       if (ret) {
-               spin_unlock_irqrestore(&priv->lock, flags);
-               return ret;
-       }
+       if (!priv->cfg->use_isr_legacy)
+               rb_timeout = RX_RB_TIMEOUT;
 
        if (priv->cfg->mod_params->amsdu_size_8K)
                rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_8K;
@@ -452,35 +453,19 @@ int iwl_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
                           (rb_timeout << FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_POS)|
                           (rfdnlog << FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS));
 
-       iwl_release_nic_access(priv);
-
        iwl_write32(priv, CSR_INT_COALESCING, 0x40);
 
-       spin_unlock_irqrestore(&priv->lock, flags);
-
        return 0;
 }
 
 int iwl_rxq_stop(struct iwl_priv *priv)
 {
-       int ret;
-       unsigned long flags;
-
-       spin_lock_irqsave(&priv->lock, flags);
-       ret = iwl_grab_nic_access(priv);
-       if (unlikely(ret)) {
-               spin_unlock_irqrestore(&priv->lock, flags);
-               return ret;
-       }
 
        /* stop Rx DMA */
        iwl_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0);
        iwl_poll_direct_bit(priv, FH_MEM_RSSR_RX_STATUS_REG,
                            FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000);
 
-       iwl_release_nic_access(priv);
-       spin_unlock_irqrestore(&priv->lock, flags);
-
        return 0;
 }
 EXPORT_SYMBOL(iwl_rxq_stop);
@@ -582,8 +567,8 @@ void iwl_rx_statistics(struct iwl_priv *priv,
 
        iwl_leds_background(priv);
 
-       if (priv->cfg->ops->lib->temperature && change)
-               priv->cfg->ops->lib->temperature(priv);
+       if (priv->cfg->ops->lib->temp_ops.temperature && change)
+               priv->cfg->ops->lib->temp_ops.temperature(priv);
 }
 EXPORT_SYMBOL(iwl_rx_statistics);
 
@@ -1102,13 +1087,6 @@ void iwl_rx_reply_rx(struct iwl_priv *priv,
        if (rx_start->phy_flags & RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK)
                rx_status.flag |= RX_FLAG_SHORTPRE;
 
-       /* Take shortcut when only in monitor mode */
-       if (priv->iw_mode == NL80211_IFTYPE_MONITOR) {
-               iwl_pass_packet_to_mac80211(priv, include_phy,
-                                                rxb, &rx_status);
-               return;
-       }
-
        network_packet = iwl_is_network_packet(priv, header);
        if (network_packet) {
                priv->last_rx_rssi = rx_status.signal;
index 6330b91e37ceab65eb776e4c336a91bf827b5607..e26875dbe8597b50b0f815739dcbaa9f9f385ee8 100644 (file)
@@ -445,13 +445,6 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw,
        unsigned long flags;
        struct iwl_priv *priv = hw->priv;
        int ret;
-       u8 *ssid = NULL;
-       size_t ssid_len = 0;
-
-       if (req->n_ssids) {
-               ssid = req->ssids[0].ssid;
-               ssid_len = req->ssids[0].ssid_len;
-       }
 
        IWL_DEBUG_MAC80211(priv, "enter\n");
 
@@ -485,13 +478,7 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw,
                goto out_unlock;
        }
 
-       if (ssid_len) {
-               priv->one_direct_scan = 1;
-               priv->direct_ssid_len =  ssid_len;
-               memcpy(priv->direct_ssid, ssid, priv->direct_ssid_len);
-       } else {
-               priv->one_direct_scan = 0;
-       }
+       priv->scan_request = req;
 
        ret = iwl_scan_initiate(priv);
 
@@ -529,74 +516,15 @@ void iwl_bg_scan_check(struct work_struct *data)
 }
 EXPORT_SYMBOL(iwl_bg_scan_check);
 
-/**
- * iwl_supported_rate_to_ie - fill in the supported rate in IE field
- *
- * return : set the bit for each supported rate insert in ie
- */
-static u16 iwl_supported_rate_to_ie(u8 *ie, u16 supported_rate,
-                                   u16 basic_rate, int *left)
-{
-       u16 ret_rates = 0, bit;
-       int i;
-       u8 *cnt = ie;
-       u8 *rates = ie + 1;
-
-       for (bit = 1, i = 0; i < IWL_RATE_COUNT; i++, bit <<= 1) {
-               if (bit & supported_rate) {
-                       ret_rates |= bit;
-                       rates[*cnt] = iwl_rates[i].ieee |
-                               ((bit & basic_rate) ? 0x80 : 0x00);
-                       (*cnt)++;
-                       (*left)--;
-                       if ((*left <= 0) ||
-                           (*cnt >= IWL_SUPPORTED_RATES_IE_LEN))
-                               break;
-               }
-       }
-
-       return ret_rates;
-}
-
-
-static void iwl_ht_cap_to_ie(const struct ieee80211_supported_band *sband,
-                            u8 *pos, int *left)
-{
-       struct ieee80211_ht_cap *ht_cap;
-
-       if (!sband || !sband->ht_cap.ht_supported)
-               return;
-
-       if (*left < sizeof(struct ieee80211_ht_cap))
-               return;
-
-       *pos++ = sizeof(struct ieee80211_ht_cap);
-       ht_cap = (struct ieee80211_ht_cap *) pos;
-
-       ht_cap->cap_info = cpu_to_le16(sband->ht_cap.cap);
-       memcpy(&ht_cap->mcs, &sband->ht_cap.mcs, 16);
-       ht_cap->ampdu_params_info =
-               (sband->ht_cap.ampdu_factor & IEEE80211_HT_AMPDU_PARM_FACTOR) |
-               ((sband->ht_cap.ampdu_density << 2) &
-                       IEEE80211_HT_AMPDU_PARM_DENSITY);
-       *left -= sizeof(struct ieee80211_ht_cap);
-}
-
 /**
  * iwl_fill_probe_req - fill in all required fields and IE for probe request
  */
 
-u16 iwl_fill_probe_req(struct iwl_priv *priv,
-                      enum ieee80211_band band,
-                      struct ieee80211_mgmt *frame,
-                      int left)
+u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame,
+                      const u8 *ies, int ie_len, int left)
 {
        int len = 0;
        u8 *pos = NULL;
-       u16 active_rates, ret_rates, cck_rates, active_rate_basic;
-       const struct ieee80211_supported_band *sband =
-                                               iwl_get_hw_mode(priv, band);
-
 
        /* Make sure there is enough space for the probe request,
         * two mandatory IEs and the data */
@@ -624,62 +552,12 @@ u16 iwl_fill_probe_req(struct iwl_priv *priv,
 
        len += 2;
 
-       /* fill in supported rate */
-       left -= 2;
-       if (left < 0)
-               return 0;
-
-       *pos++ = WLAN_EID_SUPP_RATES;
-       *pos = 0;
-
-       /* exclude 60M rate */
-       active_rates = priv->rates_mask;
-       active_rates &= ~IWL_RATE_60M_MASK;
-
-       active_rate_basic = active_rates & IWL_BASIC_RATES_MASK;
-
-       cck_rates = IWL_CCK_RATES_MASK & active_rates;
-       ret_rates = iwl_supported_rate_to_ie(pos, cck_rates,
-                                            active_rate_basic, &left);
-       active_rates &= ~ret_rates;
-
-       ret_rates = iwl_supported_rate_to_ie(pos, active_rates,
-                                            active_rate_basic, &left);
-       active_rates &= ~ret_rates;
-
-       len += 2 + *pos;
-       pos += (*pos) + 1;
+       if (WARN_ON(left < ie_len))
+               return len;
 
-       if (active_rates == 0)
-               goto fill_end;
-
-       /* fill in supported extended rate */
-       /* ...next IE... */
-       left -= 2;
-       if (left < 0)
-               return 0;
-       /* ... fill it in... */
-       *pos++ = WLAN_EID_EXT_SUPP_RATES;
-       *pos = 0;
-       iwl_supported_rate_to_ie(pos, active_rates, active_rate_basic, &left);
-       if (*pos > 0) {
-               len += 2 + *pos;
-               pos += (*pos) + 1;
-       } else {
-               pos--;
-       }
-
- fill_end:
-
-       left -= 2;
-       if (left < 0)
-               return 0;
-
-       *pos++ = WLAN_EID_HT_CAPABILITY;
-       *pos = 0;
-       iwl_ht_cap_to_ie(sband, pos, &left);
-       if (*pos > 0)
-               len += 2 + *pos;
+       memcpy(pos, ies, ie_len);
+       len += ie_len;
+       left -= ie_len;
 
        return (u16)len;
 }
@@ -699,11 +577,13 @@ static void iwl_bg_request_scan(struct work_struct *data)
        int ret = 0;
        u32 rate_flags = 0;
        u16 cmd_len;
+       u16 rx_chain = 0;
        enum ieee80211_band band;
-       u8 n_probes = 2;
-       u8 rx_chain = priv->hw_params.valid_rx_ant;
+       u8 n_probes = 0;
+       u8 rx_ant = priv->hw_params.valid_rx_ant;
        u8 rate;
-       DECLARE_SSID_BUF(ssid);
+       bool is_active = false;
+       int  chan_mod;
 
        conf = ieee80211_get_hw_conf(priv->hw);
 
@@ -795,19 +675,25 @@ static void iwl_bg_request_scan(struct work_struct *data)
                               scan_suspend_time, interval);
        }
 
-       /* We should add the ability for user to lock to PASSIVE ONLY */
-       if (priv->one_direct_scan) {
-               IWL_DEBUG_SCAN(priv, "Start direct scan for '%s'\n",
-                               print_ssid(ssid, priv->direct_ssid,
-                                          priv->direct_ssid_len));
-               scan->direct_scan[0].id = WLAN_EID_SSID;
-               scan->direct_scan[0].len = priv->direct_ssid_len;
-               memcpy(scan->direct_scan[0].ssid,
-                      priv->direct_ssid, priv->direct_ssid_len);
-               n_probes++;
-       } else {
-               IWL_DEBUG_SCAN(priv, "Start indirect scan.\n");
-       }
+       if (priv->scan_request->n_ssids) {
+               int i, p = 0;
+               IWL_DEBUG_SCAN(priv, "Kicking off active scan\n");
+               for (i = 0; i < priv->scan_request->n_ssids; i++) {
+                       /* always does wildcard anyway */
+                       if (!priv->scan_request->ssids[i].ssid_len)
+                               continue;
+                       scan->direct_scan[p].id = WLAN_EID_SSID;
+                       scan->direct_scan[p].len =
+                               priv->scan_request->ssids[i].ssid_len;
+                       memcpy(scan->direct_scan[p].ssid,
+                              priv->scan_request->ssids[i].ssid,
+                              priv->scan_request->ssids[i].ssid_len);
+                       n_probes++;
+                       p++;
+               }
+               is_active = true;
+       } else
+               IWL_DEBUG_SCAN(priv, "Start passive scan.\n");
 
        scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK;
        scan->tx_cmd.sta_id = priv->hw_params.bcast_sta_id;
@@ -817,7 +703,9 @@ static void iwl_bg_request_scan(struct work_struct *data)
        if (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ)) {
                band = IEEE80211_BAND_2GHZ;
                scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK;
-               if (priv->active_rxon.flags & RXON_FLG_CHANNEL_MODE_PURE_40_MSK) {
+               chan_mod = le32_to_cpu(priv->active_rxon.flags & RXON_FLG_CHANNEL_MODE_MSK)
+                                      >> RXON_FLG_CHANNEL_MODE_POS;
+               if (chan_mod == CHANNEL_MODE_PURE_40) {
                        rate = IWL_RATE_6M_PLCP;
                } else {
                        rate = IWL_RATE_1M_PLCP;
@@ -827,13 +715,18 @@ static void iwl_bg_request_scan(struct work_struct *data)
        } else if (priv->scan_bands & BIT(IEEE80211_BAND_5GHZ)) {
                band = IEEE80211_BAND_5GHZ;
                rate = IWL_RATE_6M_PLCP;
-               scan->good_CRC_th = IWL_GOOD_CRC_TH;
+               /*
+                * If active scaning is requested but a certain channel
+                * is marked passive, we can do active scanning if we
+                * detect transmissions.
+                */
+               scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH : 0;
 
                /* Force use of chains B and C (0x6) for scan Rx for 4965
                 * Avoid A (0x1) because of its off-channel reception on A-band.
                 */
                if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965)
-                       rx_chain = 0x6;
+                       rx_ant = ANT_BC;
        } else {
                IWL_WARN(priv, "Invalid scan band count\n");
                goto done;
@@ -845,26 +738,27 @@ static void iwl_bg_request_scan(struct work_struct *data)
        scan->tx_cmd.rate_n_flags = iwl_hw_set_rate_n_flags(rate, rate_flags);
 
        /* MIMO is not used here, but value is required */
-       scan->rx_chain = RXON_RX_CHAIN_DRIVER_FORCE_MSK |
-                               cpu_to_le16((0x7 << RXON_RX_CHAIN_VALID_POS) |
-                               (rx_chain << RXON_RX_CHAIN_FORCE_SEL_POS) |
-                               (0x7 << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS));
-
-       cmd_len = iwl_fill_probe_req(priv, band,
-                                    (struct ieee80211_mgmt *)scan->data,
-                                    IWL_MAX_SCAN_SIZE - sizeof(*scan));
+       rx_chain |= ANT_ABC << RXON_RX_CHAIN_VALID_POS;
+       rx_chain |= ANT_ABC << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS;
+       rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_SEL_POS;
+       rx_chain |= 0x1 << RXON_RX_CHAIN_DRIVER_FORCE_POS;
+       scan->rx_chain = cpu_to_le16(rx_chain);
+       cmd_len = iwl_fill_probe_req(priv,
+                               (struct ieee80211_mgmt *)scan->data,
+                               priv->scan_request->ie,
+                               priv->scan_request->ie_len,
+                               IWL_MAX_SCAN_SIZE - sizeof(*scan));
 
        scan->tx_cmd.len = cpu_to_le16(cmd_len);
 
-       if (priv->iw_mode == NL80211_IFTYPE_MONITOR)
+       if (iwl_is_monitor_mode(priv))
                scan->filter_flags = RXON_FILTER_PROMISC_MSK;
 
        scan->filter_flags |= (RXON_FILTER_ACCEPT_GRP_MSK |
                               RXON_FILTER_BCON_AWARE_MSK);
 
        scan->channel_count =
-               iwl_get_channels_for_scan(priv, band, 1, /* active */
-                       n_probes,
+               iwl_get_channels_for_scan(priv, band, is_active, n_probes,
                        (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]);
 
        if (scan->channel_count == 0) {
index 44ab03a12e40e353014fe56e67e0fd18f815585d..2addf735b1934e3ac3a34c34848b733e3f469fbd 100644 (file)
@@ -86,8 +86,7 @@ static void iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id)
 
        spin_lock_irqsave(&priv->sta_lock, flags);
 
-       if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE) &&
-           !(priv->stations_39[sta_id].used & IWL_STA_DRIVER_ACTIVE))
+       if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE))
                IWL_ERR(priv, "ACTIVATE a non DRIVER active station %d\n",
                        sta_id);
 
@@ -228,15 +227,16 @@ static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index,
 }
 
 /**
- * iwl_add_station_flags - Add station to tables in driver and device
+ * iwl_add_station - Add station to tables in driver and device
  */
-u8 iwl_add_station_flags(struct iwl_priv *priv, const u8 *addr, int is_ap,
-                        u8 flags, struct ieee80211_sta_ht_cap *ht_info)
+u8 iwl_add_station(struct iwl_priv *priv, const u8 *addr, bool is_ap, u8 flags,
+               struct ieee80211_sta_ht_cap *ht_info)
 {
-       int i;
-       int sta_id = IWL_INVALID_STATION;
        struct iwl_station_entry *station;
        unsigned long flags_spin;
+       int i;
+       int sta_id = IWL_INVALID_STATION;
+       u16 rate;
 
        spin_lock_irqsave(&priv->sta_lock, flags_spin);
        if (is_ap)
@@ -288,6 +288,12 @@ u8 iwl_add_station_flags(struct iwl_priv *priv, const u8 *addr, int is_ap,
            priv->iw_mode != NL80211_IFTYPE_ADHOC)
                iwl_set_ht_add_station(priv, sta_id, ht_info);
 
+       /* 3945 only */
+       rate = (priv->band == IEEE80211_BAND_5GHZ) ?
+               IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP;
+       /* Turn on both antennas for the station... */
+       station->sta.rate_n_flags = cpu_to_le16(rate | RATE_MCS_ANT_AB_MSK);
+
        spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
 
        /* Add station to device's station table */
@@ -295,7 +301,7 @@ u8 iwl_add_station_flags(struct iwl_priv *priv, const u8 *addr, int is_ap,
        return sta_id;
 
 }
-EXPORT_SYMBOL(iwl_add_station_flags);
+EXPORT_SYMBOL(iwl_add_station);
 
 static void iwl_sta_ucode_deactivate(struct iwl_priv *priv, const char *addr)
 {
@@ -408,7 +414,7 @@ static int iwl_send_remove_station(struct iwl_priv *priv, const u8 *addr,
 /**
  * iwl_remove_station - Remove driver's knowledge of station.
  */
-int iwl_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap)
+int iwl_remove_station(struct iwl_priv *priv, const u8 *addr, bool is_ap)
 {
        int sta_id = IWL_INVALID_STATION;
        int i, ret = -EINVAL;
@@ -490,7 +496,7 @@ void iwl_clear_stations_table(struct iwl_priv *priv)
        /* keep track of static keys */
        for (i = 0; i < WEP_KEYS_MAX ; i++) {
                if (priv->wep_keys[i].key_size)
-                       test_and_set_bit(i, &priv->ucode_key_table);
+                       set_bit(i, &priv->ucode_key_table);
        }
 
        spin_unlock_irqrestore(&priv->sta_lock, flags);
@@ -946,7 +952,7 @@ EXPORT_SYMBOL(iwl_send_lq_cmd);
  *       calling this function (which runs REPLY_TX_LINK_QUALITY_CMD,
  *       which requires station table entry to exist).
  */
-static void iwl_sta_init_lq(struct iwl_priv *priv, const u8 *addr, int is_ap)
+static void iwl_sta_init_lq(struct iwl_priv *priv, const u8 *addr, bool is_ap)
 {
        int i, r;
        struct iwl_link_quality_cmd link_cmd = {
@@ -979,8 +985,9 @@ static void iwl_sta_init_lq(struct iwl_priv *priv, const u8 *addr, int is_ap)
        link_cmd.general_params.single_stream_ant_msk =
                                first_antenna(priv->hw_params.valid_tx_ant);
        link_cmd.general_params.dual_stream_ant_msk = 3;
-       link_cmd.agg_params.agg_dis_start_th = 3;
-       link_cmd.agg_params.agg_time_limit = cpu_to_le16(4000);
+       link_cmd.agg_params.agg_dis_start_th = LINK_QUAL_AGG_DISABLE_START_DEF;
+       link_cmd.agg_params.agg_time_limit =
+               cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF);
 
        /* Update the rate scaling for control frame Tx to AP */
        link_cmd.sta_id = is_ap ? IWL_AP_ID : priv->hw_params.bcast_sta_id;
@@ -995,7 +1002,7 @@ static void iwl_sta_init_lq(struct iwl_priv *priv, const u8 *addr, int is_ap)
  * there is only one AP station with id= IWL_AP_ID
  * NOTE: mutex must be held before calling this function
  */
-int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap)
+int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, bool is_ap)
 {
        struct ieee80211_sta *sta;
        struct ieee80211_sta_ht_cap ht_config;
@@ -1020,8 +1027,7 @@ int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap)
                rcu_read_unlock();
        }
 
-       sta_id = iwl_add_station_flags(priv, addr, is_ap,
-                                      0, cur_ht_config);
+       sta_id = iwl_add_station(priv, addr, is_ap, CMD_SYNC, cur_ht_config);
 
        /* Set up default rate scaling table in device's station table */
        iwl_sta_init_lq(priv, addr, is_ap);
@@ -1067,8 +1073,8 @@ int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
                        return sta_id;
 
                /* Create new station table entry */
-               sta_id = iwl_add_station_flags(priv, hdr->addr1,
-                                                  0, CMD_ASYNC, NULL);
+               sta_id = iwl_add_station(priv, hdr->addr1, false,
+                                       CMD_ASYNC, NULL);
 
                if (sta_id != IWL_INVALID_STATION)
                        return sta_id;
@@ -1079,11 +1085,6 @@ int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
                iwl_print_hex_dump(priv, IWL_DL_DROP, (u8 *) hdr, sizeof(*hdr));
                return priv->hw_params.bcast_sta_id;
 
-       /* If we are in monitor mode, use BCAST. This is required for
-        * packet injection. */
-       case NL80211_IFTYPE_MONITOR:
-               return priv->hw_params.bcast_sta_id;
-
        default:
                IWL_WARN(priv, "Unknown mode of operation: %d\n",
                        priv->iw_mode);
index 59a586b6b56c5f8a40527a4b1f4dad5d68d49ad6..6deebade63613235df7ad3bbd05728d281f6febf 100644 (file)
@@ -51,16 +51,15 @@ void iwl_update_tkip_key(struct iwl_priv *priv,
                        struct ieee80211_key_conf *keyconf,
                        const u8 *addr, u32 iv32, u16 *phase1key);
 
-int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap);
-int iwl_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap);
+int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, bool is_ap);
+int iwl_remove_station(struct iwl_priv *priv, const u8 *addr, bool is_ap);
 void iwl_clear_stations_table(struct iwl_priv *priv);
 int iwl_get_free_ucode_key_index(struct iwl_priv *priv);
 int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr);
 int iwl_get_ra_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr);
 int iwl_send_add_sta(struct iwl_priv *priv,
                     struct iwl_addsta_cmd *sta, u8 flags);
-u8 iwl_add_station_flags(struct iwl_priv *priv, const u8 *addr,
-                       int is_ap, u8 flags,
+u8 iwl_add_station(struct iwl_priv *priv, const u8 *addr, bool is_ap, u8 flags,
                        struct ieee80211_sta_ht_cap *ht_info);
 void iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid);
 int iwl_sta_rx_agg_start(struct iwl_priv *priv,
index 71d5b8a1a73ea11f840b3ef8b9a7e9d1ed413095..85ae7a62109cd29475ce2b89e68468b05d25c484 100644 (file)
@@ -102,13 +102,8 @@ int iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq)
                        return ret;
                }
 
-               /* restore this queue's parameters in nic hardware. */
-               ret = iwl_grab_nic_access(priv);
-               if (ret)
-                       return ret;
                iwl_write_direct32(priv, HBUS_TARG_WRPTR,
                                     txq->q.write_ptr | (txq_id << 8));
-               iwl_release_nic_access(priv);
 
        /* else not in power-save mode, uCode will never sleep when we're
         * trying to tx (during RFKILL, we're not trying to tx). */
@@ -429,11 +424,6 @@ int iwl_txq_ctx_reset(struct iwl_priv *priv)
                goto error_kw;
        }
        spin_lock_irqsave(&priv->lock, flags);
-       ret = iwl_grab_nic_access(priv);
-       if (unlikely(ret)) {
-               spin_unlock_irqrestore(&priv->lock, flags);
-               goto error_reset;
-       }
 
        /* Turn off all Tx DMA fifos */
        priv->cfg->ops->lib->txq_set_sched(priv, 0);
@@ -441,7 +431,6 @@ int iwl_txq_ctx_reset(struct iwl_priv *priv)
        /* Tell NIC where to find the "keep warm" buffer */
        iwl_write_direct32(priv, FH_KW_MEM_ADDR_REG, priv->kw.dma >> 4);
 
-       iwl_release_nic_access(priv);
        spin_unlock_irqrestore(&priv->lock, flags);
 
        /* Alloc and init all Tx queues, including the command queue (#4) */
@@ -460,7 +449,6 @@ int iwl_txq_ctx_reset(struct iwl_priv *priv)
 
  error:
        iwl_hw_txq_ctx_free(priv);
- error_reset:
        iwl_free_dma_ptr(priv, &priv->kw);
  error_kw:
        iwl_free_dma_ptr(priv, &priv->scd_bc_tbls);
@@ -478,10 +466,6 @@ void iwl_txq_ctx_stop(struct iwl_priv *priv)
 
        /* Turn off all Tx DMA fifos */
        spin_lock_irqsave(&priv->lock, flags);
-       if (iwl_grab_nic_access(priv)) {
-               spin_unlock_irqrestore(&priv->lock, flags);
-               return;
-       }
 
        priv->cfg->ops->lib->txq_set_sched(priv, 0);
 
@@ -492,7 +476,6 @@ void iwl_txq_ctx_stop(struct iwl_priv *priv)
                                    FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch),
                                    1000);
        }
-       iwl_release_nic_access(priv);
        spin_unlock_irqrestore(&priv->lock, flags);
 
        /* Deallocate memory for all Tx queues */
@@ -728,7 +711,7 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
 
        /* drop all data frame if we are not associated */
        if (ieee80211_is_data(fc) &&
-           (priv->iw_mode != NL80211_IFTYPE_MONITOR ||
+           (!iwl_is_monitor_mode(priv) ||
            !(info->flags & IEEE80211_TX_CTL_INJECTED)) && /* packet injection */
            (!iwl_is_associated(priv) ||
             ((priv->iw_mode == NL80211_IFTYPE_STATION) && !priv->assoc_id) ||
@@ -1183,8 +1166,10 @@ int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn)
                        __func__, ra, tid);
 
        sta_id = iwl_find_station(priv, ra);
-       if (sta_id == IWL_INVALID_STATION)
+       if (sta_id == IWL_INVALID_STATION) {
+               IWL_ERR(priv, "Start AGG on invalid station\n");
                return -ENXIO;
+       }
 
        if (priv->stations[sta_id].tid[tid].agg.state != IWL_AGG_OFF) {
                IWL_ERR(priv, "Start AGG when state is not IWL_AGG_OFF !\n");
@@ -1192,8 +1177,10 @@ int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn)
        }
 
        txq_id = iwl_txq_ctx_activate_free(priv);
-       if (txq_id == -1)
+       if (txq_id == -1) {
+               IWL_ERR(priv, "No free aggregation queue available\n");
                return -ENXIO;
+       }
 
        spin_lock_irqsave(&priv->sta_lock, flags);
        tid_data = &priv->stations[sta_id].tid[tid];
@@ -1207,7 +1194,7 @@ int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn)
                return ret;
 
        if (tid_data->tfds_in_queue == 0) {
-               IWL_ERR(priv, "HW queue is empty\n");
+               IWL_DEBUG_HT(priv, "HW queue is empty\n");
                tid_data->agg.state = IWL_AGG_ON;
                ieee80211_start_tx_ba_cb_irqsafe(priv->hw, ra, tid);
        } else {
index ff4d0e41d7c492237d5740b423be5918b526bc3f..83d31606dd00dad721aec8003e85209214a3c24a 100644 (file)
@@ -95,188 +95,6 @@ struct iwl_mod_params iwl3945_mod_params = {
        /* the rest are 0 by default */
 };
 
-/*************** STATION TABLE MANAGEMENT ****
- * mac80211 should be examined to determine if sta_info is duplicating
- * the functionality provided here
- */
-
-/**************************************************************/
-#if 0 /* temporary disable till we add real remove station */
-/**
- * iwl3945_remove_station - Remove driver's knowledge of station.
- *
- * NOTE:  This does not remove station from device's station table.
- */
-static u8 iwl3945_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap)
-{
-       int index = IWL_INVALID_STATION;
-       int i;
-       unsigned long flags;
-
-       spin_lock_irqsave(&priv->sta_lock, flags);
-
-       if (is_ap)
-               index = IWL_AP_ID;
-       else if (is_broadcast_ether_addr(addr))
-               index = priv->hw_params.bcast_sta_id;
-       else
-               for (i = IWL_STA_ID; i < priv->hw_params.max_stations; i++)
-                       if (priv->stations_39[i].used &&
-                           !compare_ether_addr(priv->stations_39[i].sta.sta.addr,
-                                               addr)) {
-                               index = i;
-                               break;
-                       }
-
-       if (unlikely(index == IWL_INVALID_STATION))
-               goto out;
-
-       if (priv->stations_39[index].used) {
-               priv->stations_39[index].used = 0;
-               priv->num_stations--;
-       }
-
-       BUG_ON(priv->num_stations < 0);
-
-out:
-       spin_unlock_irqrestore(&priv->sta_lock, flags);
-       return 0;
-}
-#endif
-
-/**
- * iwl3945_clear_stations_table - Clear the driver's station table
- *
- * NOTE:  This does not clear or otherwise alter the device's station table.
- */
-static void iwl3945_clear_stations_table(struct iwl_priv *priv)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&priv->sta_lock, flags);
-
-       priv->num_stations = 0;
-       memset(priv->stations_39, 0, sizeof(priv->stations_39));
-
-       spin_unlock_irqrestore(&priv->sta_lock, flags);
-}
-
-/**
- * iwl3945_add_station - Add station to station tables in driver and device
- */
-u8 iwl3945_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap, u8 flags)
-{
-       int i;
-       int index = IWL_INVALID_STATION;
-       struct iwl3945_station_entry *station;
-       unsigned long flags_spin;
-       u8 rate;
-
-       spin_lock_irqsave(&priv->sta_lock, flags_spin);
-       if (is_ap)
-               index = IWL_AP_ID;
-       else if (is_broadcast_ether_addr(addr))
-               index = priv->hw_params.bcast_sta_id;
-       else
-               for (i = IWL_STA_ID; i < priv->hw_params.max_stations; i++) {
-                       if (!compare_ether_addr(priv->stations_39[i].sta.sta.addr,
-                                               addr)) {
-                               index = i;
-                               break;
-                       }
-
-                       if (!priv->stations_39[i].used &&
-                           index == IWL_INVALID_STATION)
-                               index = i;
-               }
-
-       /* These two conditions has the same outcome but keep them separate
-         since they have different meaning */
-       if (unlikely(index == IWL_INVALID_STATION)) {
-               spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
-               return index;
-       }
-
-       if (priv->stations_39[index].used &&
-          !compare_ether_addr(priv->stations_39[index].sta.sta.addr, addr)) {
-               spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
-               return index;
-       }
-
-       IWL_DEBUG_ASSOC(priv, "Add STA ID %d: %pM\n", index, addr);
-       station = &priv->stations_39[index];
-       station->used = 1;
-       priv->num_stations++;
-
-       /* Set up the REPLY_ADD_STA command to send to device */
-       memset(&station->sta, 0, sizeof(struct iwl3945_addsta_cmd));
-       memcpy(station->sta.sta.addr, addr, ETH_ALEN);
-       station->sta.mode = 0;
-       station->sta.sta.sta_id = index;
-       station->sta.station_flags = 0;
-
-       if (priv->band == IEEE80211_BAND_5GHZ)
-               rate = IWL_RATE_6M_PLCP;
-       else
-               rate =  IWL_RATE_1M_PLCP;
-
-       /* Turn on both antennas for the station... */
-       station->sta.rate_n_flags =
-                       iwl3945_hw_set_rate_n_flags(rate, RATE_MCS_ANT_AB_MSK);
-
-       spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
-
-       /* Add station to device's station table */
-       iwl_send_add_sta(priv,
-                        (struct iwl_addsta_cmd *)&station->sta, flags);
-       return index;
-
-}
-
-static int iwl3945_send_rxon_assoc(struct iwl_priv *priv)
-{
-       int rc = 0;
-       struct iwl_rx_packet *res = NULL;
-       struct iwl3945_rxon_assoc_cmd rxon_assoc;
-       struct iwl_host_cmd cmd = {
-               .id = REPLY_RXON_ASSOC,
-               .len = sizeof(rxon_assoc),
-               .meta.flags = CMD_WANT_SKB,
-               .data = &rxon_assoc,
-       };
-       const struct iwl_rxon_cmd *rxon1 = &priv->staging_rxon;
-       const struct iwl_rxon_cmd *rxon2 = &priv->active_rxon;
-
-       if ((rxon1->flags == rxon2->flags) &&
-           (rxon1->filter_flags == rxon2->filter_flags) &&
-           (rxon1->cck_basic_rates == rxon2->cck_basic_rates) &&
-           (rxon1->ofdm_basic_rates == rxon2->ofdm_basic_rates)) {
-               IWL_DEBUG_INFO(priv, "Using current RXON_ASSOC.  Not resending.\n");
-               return 0;
-       }
-
-       rxon_assoc.flags = priv->staging_rxon.flags;
-       rxon_assoc.filter_flags = priv->staging_rxon.filter_flags;
-       rxon_assoc.ofdm_basic_rates = priv->staging_rxon.ofdm_basic_rates;
-       rxon_assoc.cck_basic_rates = priv->staging_rxon.cck_basic_rates;
-       rxon_assoc.reserved = 0;
-
-       rc = iwl_send_cmd_sync(priv, &cmd);
-       if (rc)
-               return rc;
-
-       res = (struct iwl_rx_packet *)cmd.meta.u.skb->data;
-       if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
-               IWL_ERR(priv, "Bad return from REPLY_RXON_ASSOC command\n");
-               rc = -EIO;
-       }
-
-       priv->alloc_rxb_skb--;
-       dev_kfree_skb_any(cmd.meta.u.skb);
-
-       return rc;
-}
-
 /**
  * iwl3945_get_antenna_flags - Get antenna flags for RXON command
  * @priv: eeprom and antenna fields are used to determine antenna flags
@@ -314,150 +132,6 @@ __le32 iwl3945_get_antenna_flags(const struct iwl_priv *priv)
        return 0;               /* "diversity" is default if error */
 }
 
-/**
- * iwl3945_commit_rxon - commit staging_rxon to hardware
- *
- * The RXON command in staging_rxon is committed to the hardware and
- * the active_rxon structure is updated with the new data.  This
- * function correctly transitions out of the RXON_ASSOC_MSK state if
- * a HW tune is required based on the RXON structure changes.
- */
-static int iwl3945_commit_rxon(struct iwl_priv *priv)
-{
-       /* cast away the const for active_rxon in this function */
-       struct iwl3945_rxon_cmd *active_rxon = (void *)&priv->active_rxon;
-       struct iwl3945_rxon_cmd *staging_rxon = (void *)&priv->staging_rxon;
-       int rc = 0;
-       bool new_assoc =
-               !!(priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK);
-
-       if (!iwl_is_alive(priv))
-               return -1;
-
-       /* always get timestamp with Rx frame */
-       staging_rxon->flags |= RXON_FLG_TSF2HOST_MSK;
-
-       /* select antenna */
-       staging_rxon->flags &=
-           ~(RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_SEL_MSK);
-       staging_rxon->flags |= iwl3945_get_antenna_flags(priv);
-
-       rc = iwl_check_rxon_cmd(priv);
-       if (rc) {
-               IWL_ERR(priv, "Invalid RXON configuration.  Not committing.\n");
-               return -EINVAL;
-       }
-
-       /* If we don't need to send a full RXON, we can use
-        * iwl3945_rxon_assoc_cmd which is used to reconfigure filter
-        * and other flags for the current radio configuration. */
-       if (!iwl_full_rxon_required(priv)) {
-               rc = iwl3945_send_rxon_assoc(priv);
-               if (rc) {
-                       IWL_ERR(priv, "Error setting RXON_ASSOC "
-                                 "configuration (%d).\n", rc);
-                       return rc;
-               }
-
-               memcpy(active_rxon, staging_rxon, sizeof(*active_rxon));
-
-               return 0;
-       }
-
-       /* If we are currently associated and the new config requires
-        * an RXON_ASSOC and the new config wants the associated mask enabled,
-        * we must clear the associated from the active configuration
-        * before we apply the new config */
-       if (iwl_is_associated(priv) && new_assoc) {
-               IWL_DEBUG_INFO(priv, "Toggling associated bit on current RXON\n");
-               active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
-
-               /*
-                * reserved4 and 5 could have been filled by the iwlcore code.
-                * Let's clear them before pushing to the 3945.
-                */
-               active_rxon->reserved4 = 0;
-               active_rxon->reserved5 = 0;
-               rc = iwl_send_cmd_pdu(priv, REPLY_RXON,
-                                     sizeof(struct iwl3945_rxon_cmd),
-                                     &priv->active_rxon);
-
-               /* If the mask clearing failed then we set
-                * active_rxon back to what it was previously */
-               if (rc) {
-                       active_rxon->filter_flags |= RXON_FILTER_ASSOC_MSK;
-                       IWL_ERR(priv, "Error clearing ASSOC_MSK on current "
-                                 "configuration (%d).\n", rc);
-                       return rc;
-               }
-       }
-
-       IWL_DEBUG_INFO(priv, "Sending RXON\n"
-                      "* with%s RXON_FILTER_ASSOC_MSK\n"
-                      "* channel = %d\n"
-                      "* bssid = %pM\n",
-                      (new_assoc ? "" : "out"),
-                      le16_to_cpu(staging_rxon->channel),
-                      staging_rxon->bssid_addr);
-
-       /*
-        * reserved4 and 5 could have been filled by the iwlcore code.
-        * Let's clear them before pushing to the 3945.
-        */
-       staging_rxon->reserved4 = 0;
-       staging_rxon->reserved5 = 0;
-
-       iwl_set_rxon_hwcrypto(priv, !priv->hw_params.sw_crypto);
-
-       /* Apply the new configuration */
-       rc = iwl_send_cmd_pdu(priv, REPLY_RXON,
-                             sizeof(struct iwl3945_rxon_cmd),
-                             staging_rxon);
-       if (rc) {
-               IWL_ERR(priv, "Error setting new configuration (%d).\n", rc);
-               return rc;
-       }
-
-       memcpy(active_rxon, staging_rxon, sizeof(*active_rxon));
-
-       iwl3945_clear_stations_table(priv);
-
-       /* If we issue a new RXON command which required a tune then we must
-        * send a new TXPOWER command or we won't be able to Tx any frames */
-       rc = priv->cfg->ops->lib->send_tx_power(priv);
-       if (rc) {
-               IWL_ERR(priv, "Error setting Tx power (%d).\n", rc);
-               return rc;
-       }
-
-       /* Add the broadcast address so we can send broadcast frames */
-       if (iwl3945_add_station(priv, iwl_bcast_addr, 0, 0) ==
-           IWL_INVALID_STATION) {
-               IWL_ERR(priv, "Error adding BROADCAST address for transmit.\n");
-               return -EIO;
-       }
-
-       /* If we have set the ASSOC_MSK and we are in BSS mode then
-        * add the IWL_AP_ID to the station rate table */
-       if (iwl_is_associated(priv) &&
-           (priv->iw_mode == NL80211_IFTYPE_STATION))
-               if (iwl3945_add_station(priv, priv->active_rxon.bssid_addr,
-                                       1, 0)
-                   == IWL_INVALID_STATION) {
-                       IWL_ERR(priv, "Error adding AP address for transmit\n");
-                       return -EIO;
-               }
-
-       /* Init the hardware's rate fallback order based on the band */
-       rc = iwl3945_init_hw_rate_table(priv);
-       if (rc) {
-               IWL_ERR(priv, "Error setting HW rate table: %02X\n", rc);
-               return -EIO;
-       }
-
-       return 0;
-}
-
 static int iwl3945_set_ccmp_dynamic_key_info(struct iwl_priv *priv,
                                   struct ieee80211_key_conf *keyconf,
                                   u8 sta_id)
@@ -477,32 +151,31 @@ static int iwl3945_set_ccmp_dynamic_key_info(struct iwl_priv *priv,
        key_flags &= ~STA_KEY_FLG_INVALID;
 
        spin_lock_irqsave(&priv->sta_lock, flags);
-       priv->stations_39[sta_id].keyinfo.alg = keyconf->alg;
-       priv->stations_39[sta_id].keyinfo.keylen = keyconf->keylen;
-       memcpy(priv->stations_39[sta_id].keyinfo.key, keyconf->key,
+       priv->stations[sta_id].keyinfo.alg = keyconf->alg;
+       priv->stations[sta_id].keyinfo.keylen = keyconf->keylen;
+       memcpy(priv->stations[sta_id].keyinfo.key, keyconf->key,
               keyconf->keylen);
 
-       memcpy(priv->stations_39[sta_id].sta.key.key, keyconf->key,
+       memcpy(priv->stations[sta_id].sta.key.key, keyconf->key,
               keyconf->keylen);
 
-       if ((priv->stations_39[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK)
+       if ((priv->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK)
                        == STA_KEY_FLG_NO_ENC)
-               priv->stations_39[sta_id].sta.key.key_offset =
+               priv->stations[sta_id].sta.key.key_offset =
                                 iwl_get_free_ucode_key_index(priv);
        /* else, we are overriding an existing key => no need to allocated room
        * in uCode. */
 
-       WARN(priv->stations_39[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET,
+       WARN(priv->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET,
                "no space for a new key");
 
-       priv->stations_39[sta_id].sta.key.key_flags = key_flags;
-       priv->stations_39[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
-       priv->stations_39[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
+       priv->stations[sta_id].sta.key.key_flags = key_flags;
+       priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
+       priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
 
        IWL_DEBUG_INFO(priv, "hwcrypto: modify ucode station key info\n");
 
-       ret = iwl_send_add_sta(priv,
-               (struct iwl_addsta_cmd *)&priv->stations_39[sta_id].sta, CMD_ASYNC);
+       ret = iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
 
        spin_unlock_irqrestore(&priv->sta_lock, flags);
 
@@ -528,17 +201,16 @@ static int iwl3945_clear_sta_key_info(struct iwl_priv *priv, u8 sta_id)
        unsigned long flags;
 
        spin_lock_irqsave(&priv->sta_lock, flags);
-       memset(&priv->stations_39[sta_id].keyinfo, 0, sizeof(struct iwl3945_hw_key));
-       memset(&priv->stations_39[sta_id].sta.key, 0,
+       memset(&priv->stations[sta_id].keyinfo, 0, sizeof(struct iwl_hw_key));
+       memset(&priv->stations[sta_id].sta.key, 0,
                sizeof(struct iwl4965_keyinfo));
-       priv->stations_39[sta_id].sta.key.key_flags = STA_KEY_FLG_NO_ENC;
-       priv->stations_39[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
-       priv->stations_39[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
+       priv->stations[sta_id].sta.key.key_flags = STA_KEY_FLG_NO_ENC;
+       priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
+       priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
        spin_unlock_irqrestore(&priv->sta_lock, flags);
 
        IWL_DEBUG_INFO(priv, "hwcrypto: clear ucode station key info\n");
-       iwl_send_add_sta(priv,
-               (struct iwl_addsta_cmd *)&priv->stations_39[sta_id].sta, 0);
+       iwl_send_add_sta(priv, &priv->stations[sta_id].sta, 0);
        return 0;
 }
 
@@ -739,7 +411,8 @@ static void iwl3945_setup_rxon_timing(struct iwl_priv *priv)
                priv->rxon_timing.atim_window = 0;
        } else {
                priv->rxon_timing.beacon_interval =
-                       iwl3945_adjust_beacon_interval(conf->beacon_int);
+                       iwl3945_adjust_beacon_interval(
+                               priv->vif->bss_conf.beacon_int);
                /* TODO: we need to get atim_window from upper stack
                 * for now we set to 0 */
                priv->rxon_timing.atim_window = 0;
@@ -758,35 +431,6 @@ static void iwl3945_setup_rxon_timing(struct iwl_priv *priv)
                le16_to_cpu(priv->rxon_timing.atim_window));
 }
 
-static int iwl3945_set_mode(struct iwl_priv *priv, int mode)
-{
-       if (mode == NL80211_IFTYPE_ADHOC) {
-               const struct iwl_channel_info *ch_info;
-
-               ch_info = iwl_get_channel_info(priv,
-                       priv->band,
-                       le16_to_cpu(priv->staging_rxon.channel));
-
-               if (!ch_info || !is_channel_ibss(ch_info)) {
-                       IWL_ERR(priv, "channel %d not IBSS channel\n",
-                                 le16_to_cpu(priv->staging_rxon.channel));
-                       return -EINVAL;
-               }
-       }
-
-       iwl_connection_init_rx_config(priv, mode);
-
-       iwl3945_clear_stations_table(priv);
-
-       /* don't commit rxon if rf-kill is on*/
-       if (!iwl_is_ready_rf(priv))
-               return -EAGAIN;
-
-       iwl3945_commit_rxon(priv);
-
-       return 0;
-}
-
 static void iwl3945_build_tx_cmd_hwcrypto(struct iwl_priv *priv,
                                      struct ieee80211_tx_info *info,
                                      struct iwl_cmd *cmd,
@@ -794,8 +438,7 @@ static void iwl3945_build_tx_cmd_hwcrypto(struct iwl_priv *priv,
                                      int sta_id)
 {
        struct iwl3945_tx_cmd *tx = (struct iwl3945_tx_cmd *)cmd->cmd.payload;
-       struct iwl3945_hw_key *keyinfo =
-           &priv->stations_39[sta_id].keyinfo;
+       struct iwl_hw_key *keyinfo = &priv->stations[sta_id].keyinfo;
 
        switch (keyinfo->alg) {
        case ALG_CCMP:
@@ -893,64 +536,6 @@ static void iwl3945_build_tx_cmd_basic(struct iwl_priv *priv,
        tx->next_frame_len = 0;
 }
 
-/**
- * iwl3945_get_sta_id - Find station's index within station table
- */
-static int iwl3945_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
-{
-       int sta_id;
-       u16 fc = le16_to_cpu(hdr->frame_control);
-
-       /* If this frame is broadcast or management, use broadcast station id */
-       if (((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA) ||
-           is_multicast_ether_addr(hdr->addr1))
-               return priv->hw_params.bcast_sta_id;
-
-       switch (priv->iw_mode) {
-
-       /* If we are a client station in a BSS network, use the special
-        * AP station entry (that's the only station we communicate with) */
-       case NL80211_IFTYPE_STATION:
-               return IWL_AP_ID;
-
-       /* If we are an AP, then find the station, or use BCAST */
-       case NL80211_IFTYPE_AP:
-               sta_id = iwl3945_hw_find_station(priv, hdr->addr1);
-               if (sta_id != IWL_INVALID_STATION)
-                       return sta_id;
-               return priv->hw_params.bcast_sta_id;
-
-       /* If this frame is going out to an IBSS network, find the station,
-        * or create a new station table entry */
-       case NL80211_IFTYPE_ADHOC: {
-               /* Create new station table entry */
-               sta_id = iwl3945_hw_find_station(priv, hdr->addr1);
-               if (sta_id != IWL_INVALID_STATION)
-                       return sta_id;
-
-               sta_id = iwl3945_add_station(priv, hdr->addr1, 0, CMD_ASYNC);
-
-               if (sta_id != IWL_INVALID_STATION)
-                       return sta_id;
-
-               IWL_DEBUG_DROP(priv, "Station %pM not in station map. "
-                              "Defaulting to broadcast...\n",
-                              hdr->addr1);
-               iwl_print_hex_dump(priv, IWL_DL_DROP, (u8 *) hdr, sizeof(*hdr));
-               return priv->hw_params.bcast_sta_id;
-       }
-       /* If we are in monitor mode, use BCAST. This is required for
-        * packet injection. */
-       case NL80211_IFTYPE_MONITOR:
-               return priv->hw_params.bcast_sta_id;
-
-       default:
-               IWL_WARN(priv, "Unknown mode of operation: %d\n",
-                       priv->iw_mode);
-               return priv->hw_params.bcast_sta_id;
-       }
-}
-
 /*
  * start REPLY_TX command process
  */
@@ -1004,7 +589,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
 
        /* drop all data frame if we are not associated */
        if (ieee80211_is_data(fc) &&
-           (priv->iw_mode != NL80211_IFTYPE_MONITOR) && /* packet injection */
+           (!iwl_is_monitor_mode(priv)) && /* packet injection */
            (!iwl_is_associated(priv) ||
             ((priv->iw_mode == NL80211_IFTYPE_STATION) && !priv->assoc_id))) {
                IWL_DEBUG_DROP(priv, "Dropping - !iwl_is_associated\n");
@@ -1016,7 +601,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
        hdr_len = ieee80211_hdrlen(fc);
 
        /* Find (or create) index into station table for destination station */
-       sta_id = iwl3945_get_sta_id(priv, hdr);
+       sta_id = iwl_get_sta_id(priv, hdr);
        if (sta_id == IWL_INVALID_STATION) {
                IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n",
                               hdr->addr1);
@@ -1028,7 +613,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
        if (ieee80211_is_data_qos(fc)) {
                qc = ieee80211_get_qos_ctl(hdr);
                tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
-               seq_number = priv->stations_39[sta_id].tid[tid].seq_number &
+               seq_number = priv->stations[sta_id].tid[tid].seq_number &
                                IEEE80211_SCTL_SEQ;
                hdr->seq_ctrl = cpu_to_le16(seq_number) |
                        (hdr->seq_ctrl &
@@ -1088,7 +673,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
        if (!ieee80211_has_morefrags(hdr->frame_control)) {
                txq->need_update = 1;
                if (qc)
-                       priv->stations_39[sta_id].tid[tid].seq_number = seq_number;
+                       priv->stations[sta_id].tid[tid].seq_number = seq_number;
        } else {
                wait_write_ptr = 1;
                txq->need_update = 0;
@@ -1424,18 +1009,12 @@ static void iwl3945_rx_card_state_notif(struct iwl_priv *priv,
                clear_bit(STATUS_RF_KILL_HW, &priv->status);
 
 
-       if (flags & SW_CARD_DISABLED)
-               set_bit(STATUS_RF_KILL_SW, &priv->status);
-       else
-               clear_bit(STATUS_RF_KILL_SW, &priv->status);
-
        iwl_scan_cancel(priv);
 
        if ((test_bit(STATUS_RF_KILL_HW, &status) !=
-            test_bit(STATUS_RF_KILL_HW, &priv->status)) ||
-           (test_bit(STATUS_RF_KILL_SW, &status) !=
-            test_bit(STATUS_RF_KILL_SW, &priv->status)))
-               queue_work(priv->workqueue, &priv->rf_kill);
+            test_bit(STATUS_RF_KILL_HW, &priv->status)))
+               wiphy_rfkill_set_hw_state(priv->hw->wiphy,
+                               test_bit(STATUS_RF_KILL_HW, &priv->status));
        else
                wake_up_interruptible(&priv->wait_command_queue);
 }
@@ -1591,7 +1170,7 @@ static int iwl3945_rx_queue_restock(struct iwl_priv *priv)
 
        /* If we've added more space for the firmware to place data, tell it.
         * Increment device's write pointer in multiples of 8. */
-       if ((write != (rxq->write & ~0x7))
+       if ((rxq->write_actual != (rxq->write & ~0x7))
            || (abs(rxq->write - rxq->read) > 7)) {
                spin_lock_irqsave(&rxq->lock, flags);
                rxq->need_update = 1;
@@ -1612,21 +1191,30 @@ static int iwl3945_rx_queue_restock(struct iwl_priv *priv)
  * Also restock the Rx queue via iwl3945_rx_queue_restock.
  * This is called as a scheduled work item (except for during initialization)
  */
-static void iwl3945_rx_allocate(struct iwl_priv *priv)
+static void iwl3945_rx_allocate(struct iwl_priv *priv, gfp_t priority)
 {
        struct iwl_rx_queue *rxq = &priv->rxq;
        struct list_head *element;
        struct iwl_rx_mem_buffer *rxb;
        unsigned long flags;
-       spin_lock_irqsave(&rxq->lock, flags);
-       while (!list_empty(&rxq->rx_used)) {
+
+       while (1) {
+               spin_lock_irqsave(&rxq->lock, flags);
+
+               if (list_empty(&rxq->rx_used)) {
+                       spin_unlock_irqrestore(&rxq->lock, flags);
+                       return;
+               }
+
                element = rxq->rx_used.next;
                rxb = list_entry(element, struct iwl_rx_mem_buffer, list);
+               list_del(element);
+               spin_unlock_irqrestore(&rxq->lock, flags);
 
                /* Alloc a new receive buffer */
                rxb->skb =
                    alloc_skb(priv->hw_params.rx_buf_size,
-                               __GFP_NOWARN | GFP_ATOMIC);
+                               priority);
                if (!rxb->skb) {
                        if (net_ratelimit())
                                IWL_CRIT(priv, ": Can not allocate SKB buffers\n");
@@ -1644,18 +1232,18 @@ static void iwl3945_rx_allocate(struct iwl_priv *priv)
                 */
                skb_reserve(rxb->skb, 4);
 
-               priv->alloc_rxb_skb++;
-               list_del(element);
-
                /* Get physical address of RB/SKB */
                rxb->real_dma_addr = pci_map_single(priv->pci_dev,
                                                rxb->skb->data,
                                                priv->hw_params.rx_buf_size,
                                                PCI_DMA_FROMDEVICE);
+
+               spin_lock_irqsave(&rxq->lock, flags);
                list_add_tail(&rxb->list, &rxq->rx_free);
+               priv->alloc_rxb_skb++;
                rxq->free_count++;
+               spin_unlock_irqrestore(&rxq->lock, flags);
        }
-       spin_unlock_irqrestore(&rxq->lock, flags);
 }
 
 void iwl3945_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
@@ -1685,33 +1273,30 @@ void iwl3945_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
         * not restocked the Rx queue with fresh buffers */
        rxq->read = rxq->write = 0;
        rxq->free_count = 0;
+       rxq->write_actual = 0;
        spin_unlock_irqrestore(&rxq->lock, flags);
 }
 
-/*
- * this should be called while priv->lock is locked
- */
-static void __iwl3945_rx_replenish(void *data)
-{
-       struct iwl_priv *priv = data;
-
-       iwl3945_rx_allocate(priv);
-       iwl3945_rx_queue_restock(priv);
-}
-
-
 void iwl3945_rx_replenish(void *data)
 {
        struct iwl_priv *priv = data;
        unsigned long flags;
 
-       iwl3945_rx_allocate(priv);
+       iwl3945_rx_allocate(priv, GFP_KERNEL);
 
        spin_lock_irqsave(&priv->lock, flags);
        iwl3945_rx_queue_restock(priv);
        spin_unlock_irqrestore(&priv->lock, flags);
 }
 
+static void iwl3945_rx_replenish_now(struct iwl_priv *priv)
+{
+       iwl3945_rx_allocate(priv, GFP_ATOMIC);
+
+       iwl3945_rx_queue_restock(priv);
+}
+
+
 /* Assumes that the skb field of the buffers in 'pool' is kept accurate.
  * If an SKB has been detached, the POOL needs to have its SKB set to NULL
  * This free routine walks the list of POOL entries and if SKB is set to
@@ -1834,13 +1419,19 @@ static void iwl3945_rx_handle(struct iwl_priv *priv)
        unsigned long flags;
        u8 fill_rx = 0;
        u32 count = 8;
+       int total_empty = 0;
 
        /* uCode's read index (stored in shared DRAM) indicates the last Rx
         * buffer that the driver may process (last buffer filled by ucode). */
        r = le16_to_cpu(rxq->rb_stts->closed_rb_num) &  0x0FFF;
        i = rxq->read;
 
-       if (iwl_rx_queue_space(rxq) > (RX_QUEUE_SIZE / 2))
+       /* calculate total frames need to be restock after handling RX */
+       total_empty = r - priv->rxq.write_actual;
+       if (total_empty < 0)
+               total_empty += RX_QUEUE_SIZE;
+
+       if (total_empty > (RX_QUEUE_SIZE / 2))
                fill_rx = 1;
        /* Rx interrupt, but nothing sent from uCode */
        if (i == r)
@@ -1879,6 +1470,7 @@ static void iwl3945_rx_handle(struct iwl_priv *priv)
                                "r = %d, i = %d, %s, 0x%02x\n", r, i,
                                get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd);
                        priv->rx_handlers[pkt->hdr.cmd] (priv, rxb);
+                       priv->isr_stats.rx_handlers[pkt->hdr.cmd]++;
                } else {
                        /* No handling needed */
                        IWL_DEBUG(priv, IWL_DL_HCMD | IWL_DL_RX | IWL_DL_ISR,
@@ -1916,7 +1508,7 @@ static void iwl3945_rx_handle(struct iwl_priv *priv)
                        count++;
                        if (count >= 8) {
                                priv->rxq.read = i;
-                               __iwl3945_rx_replenish(priv);
+                               iwl3945_rx_replenish_now(priv);
                                count = 0;
                        }
                }
@@ -1924,7 +1516,10 @@ static void iwl3945_rx_handle(struct iwl_priv *priv)
 
        /* Backtrack one entry */
        priv->rxq.read = i;
-       iwl3945_rx_queue_restock(priv);
+       if (fill_rx)
+               iwl3945_rx_replenish_now(priv);
+       else
+               iwl3945_rx_queue_restock(priv);
 }
 
 /* call this function to flush any scheduled tasklet */
@@ -1963,7 +1558,6 @@ static void iwl3945_dump_nic_error_log(struct iwl_priv *priv)
        u32 i;
        u32 desc, time, count, base, data1;
        u32 blink1, blink2, ilink1, ilink2;
-       int rc;
 
        base = le32_to_cpu(priv->card_alive.error_event_table_ptr);
 
@@ -1972,11 +1566,6 @@ static void iwl3945_dump_nic_error_log(struct iwl_priv *priv)
                return;
        }
 
-       rc = iwl_grab_nic_access(priv);
-       if (rc) {
-               IWL_WARN(priv, "Can not read from adapter at this time.\n");
-               return;
-       }
 
        count = iwl_read_targ_mem(priv, base);
 
@@ -2011,8 +1600,6 @@ static void iwl3945_dump_nic_error_log(struct iwl_priv *priv)
                        ilink1, ilink2, data1);
        }
 
-       iwl_release_nic_access(priv);
-
 }
 
 #define EVENT_START_OFFSET  (6 * sizeof(u32))
@@ -2020,7 +1607,6 @@ static void iwl3945_dump_nic_error_log(struct iwl_priv *priv)
 /**
  * iwl3945_print_event_log - Dump error event log to syslog
  *
- * NOTE: Must be called with iwl_grab_nic_access() already obtained!
  */
 static void iwl3945_print_event_log(struct iwl_priv *priv, u32 start_idx,
                                u32 num_events, u32 mode)
@@ -2063,7 +1649,6 @@ static void iwl3945_print_event_log(struct iwl_priv *priv, u32 start_idx,
 
 static void iwl3945_dump_nic_event_log(struct iwl_priv *priv)
 {
-       int rc;
        u32 base;       /* SRAM byte address of event log header */
        u32 capacity;   /* event log capacity in # entries */
        u32 mode;       /* 0 - no timestamp, 1 - timestamp recorded */
@@ -2077,12 +1662,6 @@ static void iwl3945_dump_nic_event_log(struct iwl_priv *priv)
                return;
        }
 
-       rc = iwl_grab_nic_access(priv);
-       if (rc) {
-               IWL_WARN(priv, "Can not read from adapter at this time.\n");
-               return;
-       }
-
        /* event log header */
        capacity = iwl_read_targ_mem(priv, base);
        mode = iwl_read_targ_mem(priv, base + (1 * sizeof(u32)));
@@ -2094,7 +1673,6 @@ static void iwl3945_dump_nic_event_log(struct iwl_priv *priv)
        /* bail out if nothing in log */
        if (size == 0) {
                IWL_ERR(priv, "Start IWL Event Log Dump: nothing in log\n");
-               iwl_release_nic_access(priv);
                return;
        }
 
@@ -2110,24 +1688,6 @@ static void iwl3945_dump_nic_event_log(struct iwl_priv *priv)
        /* (then/else) start at top of log */
        iwl3945_print_event_log(priv, 0, next_entry, mode);
 
-       iwl_release_nic_access(priv);
-}
-
-static void iwl3945_error_recovery(struct iwl_priv *priv)
-{
-       unsigned long flags;
-
-       memcpy(&priv->staging_rxon, &priv->recovery_rxon,
-              sizeof(priv->staging_rxon));
-       priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
-       iwl3945_commit_rxon(priv);
-
-       iwl3945_add_station(priv, priv->bssid, 1, 0);
-
-       spin_lock_irqsave(&priv->lock, flags);
-       priv->assoc_id = le16_to_cpu(priv->staging_rxon.assoc_id);
-       priv->error_recovering = 0;
-       spin_unlock_irqrestore(&priv->lock, flags);
 }
 
 static void iwl3945_irq_tasklet(struct iwl_priv *priv)
@@ -2178,6 +1738,7 @@ static void iwl3945_irq_tasklet(struct iwl_priv *priv)
                /* Tell the device to stop sending interrupts */
                iwl_disable_interrupts(priv);
 
+               priv->isr_stats.hw++;
                iwl_irq_handle_error(priv);
 
                handled |= CSR_INT_BIT_HW_ERR;
@@ -2190,13 +1751,17 @@ static void iwl3945_irq_tasklet(struct iwl_priv *priv)
 #ifdef CONFIG_IWLWIFI_DEBUG
        if (priv->debug_level & (IWL_DL_ISR)) {
                /* NIC fires this, but we don't use it, redundant with WAKEUP */
-               if (inta & CSR_INT_BIT_SCD)
+               if (inta & CSR_INT_BIT_SCD) {
                        IWL_DEBUG_ISR(priv, "Scheduler finished to transmit "
                                      "the frame/frames.\n");
+                       priv->isr_stats.sch++;
+               }
 
                /* Alive notification via Rx interrupt will do the real work */
-               if (inta & CSR_INT_BIT_ALIVE)
+               if (inta & CSR_INT_BIT_ALIVE) {
                        IWL_DEBUG_ISR(priv, "Alive interrupt\n");
+                       priv->isr_stats.alive++;
+               }
        }
 #endif
        /* Safely ignore these bits for debug checks below */
@@ -2206,6 +1771,8 @@ static void iwl3945_irq_tasklet(struct iwl_priv *priv)
        if (inta & CSR_INT_BIT_SW_ERR) {
                IWL_ERR(priv, "Microcode SW error detected. "
                        "Restarting 0x%X.\n", inta);
+               priv->isr_stats.sw++;
+               priv->isr_stats.sw_err = inta;
                iwl_irq_handle_error(priv);
                handled |= CSR_INT_BIT_SW_ERR;
        }
@@ -2221,6 +1788,7 @@ static void iwl3945_irq_tasklet(struct iwl_priv *priv)
                iwl_txq_update_write_ptr(priv, &priv->txq[4]);
                iwl_txq_update_write_ptr(priv, &priv->txq[5]);
 
+               priv->isr_stats.wakeup++;
                handled |= CSR_INT_BIT_WAKEUP;
        }
 
@@ -2229,27 +1797,28 @@ static void iwl3945_irq_tasklet(struct iwl_priv *priv)
         * notifications from uCode come through here*/
        if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) {
                iwl3945_rx_handle(priv);
+               priv->isr_stats.rx++;
                handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX);
        }
 
        if (inta & CSR_INT_BIT_FH_TX) {
                IWL_DEBUG_ISR(priv, "Tx interrupt\n");
+               priv->isr_stats.tx++;
 
                iwl_write32(priv, CSR_FH_INT_STATUS, (1 << 6));
-               if (!iwl_grab_nic_access(priv)) {
-                       iwl_write_direct32(priv, FH39_TCSR_CREDIT
-                                            (FH39_SRVC_CHNL), 0x0);
-                       iwl_release_nic_access(priv);
-               }
+               iwl_write_direct32(priv, FH39_TCSR_CREDIT
+                                       (FH39_SRVC_CHNL), 0x0);
                handled |= CSR_INT_BIT_FH_TX;
        }
 
-       if (inta & ~handled)
+       if (inta & ~handled) {
                IWL_ERR(priv, "Unhandled INTA bits 0x%08x\n", inta & ~handled);
+               priv->isr_stats.unhandled++;
+       }
 
-       if (inta & ~CSR_INI_SET_MASK) {
+       if (inta & ~priv->inta_mask) {
                IWL_WARN(priv, "Disabled INTA bits 0x%08x were pending\n",
-                        inta & ~CSR_INI_SET_MASK);
+                        inta & ~priv->inta_mask);
                IWL_WARN(priv, "   with FH_INT = 0x%08x\n", inta_fh);
        }
 
@@ -2413,10 +1982,6 @@ static int iwl3945_verify_inst_full(struct iwl_priv *priv, __le32 *image, u32 le
 
        IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len);
 
-       rc = iwl_grab_nic_access(priv);
-       if (rc)
-               return rc;
-
        iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR,
                               IWL39_RTC_INST_LOWER_BOUND);
 
@@ -2437,7 +2002,6 @@ static int iwl3945_verify_inst_full(struct iwl_priv *priv, __le32 *image, u32 le
                }
        }
 
-       iwl_release_nic_access(priv);
 
        if (!errcnt)
                IWL_DEBUG_INFO(priv,
@@ -2461,10 +2025,6 @@ static int iwl3945_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32
 
        IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len);
 
-       rc = iwl_grab_nic_access(priv);
-       if (rc)
-               return rc;
-
        for (i = 0; i < len; i += 100, image += 100/sizeof(u32)) {
                /* read data comes through single port, auto-incr addr */
                /* NOTE: Use the debugless read so we don't flood kernel log
@@ -2485,8 +2045,6 @@ static int iwl3945_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32
                }
        }
 
-       iwl_release_nic_access(priv);
-
        return rc;
 }
 
@@ -2810,20 +2368,11 @@ static int iwl3945_set_ucode_ptrs(struct iwl_priv *priv)
 {
        dma_addr_t pinst;
        dma_addr_t pdata;
-       int rc = 0;
-       unsigned long flags;
 
        /* bits 31:0 for 3945 */
        pinst = priv->ucode_code.p_addr;
        pdata = priv->ucode_data_backup.p_addr;
 
-       spin_lock_irqsave(&priv->lock, flags);
-       rc = iwl_grab_nic_access(priv);
-       if (rc) {
-               spin_unlock_irqrestore(&priv->lock, flags);
-               return rc;
-       }
-
        /* Tell bootstrap uCode where to find image to load */
        iwl_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst);
        iwl_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata);
@@ -2835,13 +2384,9 @@ static int iwl3945_set_ucode_ptrs(struct iwl_priv *priv)
        iwl_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG,
                                 priv->ucode_code.len | BSM_DRAM_INST_LOAD);
 
-       iwl_release_nic_access(priv);
-
-       spin_unlock_irqrestore(&priv->lock, flags);
-
        IWL_DEBUG_INFO(priv, "Runtime uCode pointers are set.\n");
 
-       return rc;
+       return 0;
 }
 
 /**
@@ -2887,11 +2432,6 @@ static void iwl3945_init_alive_start(struct iwl_priv *priv)
        queue_work(priv->workqueue, &priv->restart);
 }
 
-
-/* temporary */
-static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw,
-                                    struct sk_buff *skb);
-
 /**
  * iwl3945_alive_start - called after REPLY_ALIVE notification received
  *                   from protocol/runtime uCode (initialization uCode's
@@ -2899,7 +2439,6 @@ static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw,
  */
 static void iwl3945_alive_start(struct iwl_priv *priv)
 {
-       int rc = 0;
        int thermal_spin = 0;
        u32 rfkill;
 
@@ -2922,17 +2461,10 @@ static void iwl3945_alive_start(struct iwl_priv *priv)
                goto restart;
        }
 
-       iwl3945_clear_stations_table(priv);
-
-       rc = iwl_grab_nic_access(priv);
-       if (rc) {
-               IWL_WARN(priv, "Can not read RFKILL status from adapter\n");
-               return;
-       }
+       iwl_clear_stations_table(priv);
 
        rfkill = iwl_read_prph(priv, APMG_RFKILL_REG);
        IWL_DEBUG_INFO(priv, "RFKILL status: 0x%x\n", rfkill);
-       iwl_release_nic_access(priv);
 
        if (rfkill & 0x1) {
                clear_bit(STATUS_RF_KILL_HW, &priv->status);
@@ -2952,9 +2484,6 @@ static void iwl3945_alive_start(struct iwl_priv *priv)
        /* After the ALIVE response, we can send commands to 3945 uCode */
        set_bit(STATUS_ALIVE, &priv->status);
 
-       /* Clear out the uCode error bit if it is set */
-       clear_bit(STATUS_FW_ERROR, &priv->status);
-
        if (iwl_is_rfkill(priv))
                return;
 
@@ -2981,7 +2510,7 @@ static void iwl3945_alive_start(struct iwl_priv *priv)
        iwl_send_bt_config(priv);
 
        /* Configure the adapter for unassociated operation */
-       iwl3945_commit_rxon(priv);
+       iwlcore_commit_rxon(priv);
 
        iwl3945_reg_txpower_periodic(priv);
 
@@ -2991,17 +2520,17 @@ static void iwl3945_alive_start(struct iwl_priv *priv)
        set_bit(STATUS_READY, &priv->status);
        wake_up_interruptible(&priv->wait_command_queue);
 
-       if (priv->error_recovering)
-               iwl3945_error_recovery(priv);
-
        /* reassociate for ADHOC mode */
        if (priv->vif && (priv->iw_mode == NL80211_IFTYPE_ADHOC)) {
                struct sk_buff *beacon = ieee80211_beacon_get(priv->hw,
                                                                priv->vif);
                if (beacon)
-                       iwl3945_mac_beacon_update(priv->hw, beacon);
+                       iwl_mac_beacon_update(priv->hw, beacon);
        }
 
+       if (test_and_clear_bit(STATUS_MODE_PENDING, &priv->status))
+               iwl_set_mode(priv, priv->iw_mode);
+
        return;
 
  restart:
@@ -3024,7 +2553,7 @@ static void __iwl3945_down(struct iwl_priv *priv)
                set_bit(STATUS_EXIT_PENDING, &priv->status);
 
        iwl3945_led_unregister(priv);
-       iwl3945_clear_stations_table(priv);
+       iwl_clear_stations_table(priv);
 
        /* Unblock any waiting calls */
        wake_up_interruptible_all(&priv->wait_command_queue);
@@ -3047,31 +2576,23 @@ static void __iwl3945_down(struct iwl_priv *priv)
                ieee80211_stop_queues(priv->hw);
 
        /* If we have not previously called iwl3945_init() then
-        * clear all bits but the RF Kill and SUSPEND bits and return */
+        * clear all bits but the RF Kill bits and return */
        if (!iwl_is_init(priv)) {
                priv->status = test_bit(STATUS_RF_KILL_HW, &priv->status) <<
                                        STATUS_RF_KILL_HW |
-                              test_bit(STATUS_RF_KILL_SW, &priv->status) <<
-                                       STATUS_RF_KILL_SW |
                               test_bit(STATUS_GEO_CONFIGURED, &priv->status) <<
                                        STATUS_GEO_CONFIGURED |
-                              test_bit(STATUS_IN_SUSPEND, &priv->status) <<
-                                       STATUS_IN_SUSPEND |
                                test_bit(STATUS_EXIT_PENDING, &priv->status) <<
                                        STATUS_EXIT_PENDING;
                goto exit;
        }
 
-       /* ...otherwise clear out all the status bits but the RF Kill and
-        * SUSPEND bits and continue taking the NIC down. */
+       /* ...otherwise clear out all the status bits but the RF Kill
+        * bit and continue taking the NIC down. */
        priv->status &= test_bit(STATUS_RF_KILL_HW, &priv->status) <<
                                STATUS_RF_KILL_HW |
-                       test_bit(STATUS_RF_KILL_SW, &priv->status) <<
-                               STATUS_RF_KILL_SW |
                        test_bit(STATUS_GEO_CONFIGURED, &priv->status) <<
                                STATUS_GEO_CONFIGURED |
-                       test_bit(STATUS_IN_SUSPEND, &priv->status) <<
-                               STATUS_IN_SUSPEND |
                        test_bit(STATUS_FW_ERROR, &priv->status) <<
                                STATUS_FW_ERROR |
                        test_bit(STATUS_EXIT_PENDING, &priv->status) <<
@@ -3085,17 +2606,12 @@ static void __iwl3945_down(struct iwl_priv *priv)
        iwl3945_hw_txq_ctx_stop(priv);
        iwl3945_hw_rxq_stop(priv);
 
-       spin_lock_irqsave(&priv->lock, flags);
-       if (!iwl_grab_nic_access(priv)) {
-               iwl_write_prph(priv, APMG_CLK_DIS_REG,
-                                        APMG_CLK_VAL_DMA_CLK_RQT);
-               iwl_release_nic_access(priv);
-       }
-       spin_unlock_irqrestore(&priv->lock, flags);
+       iwl_write_prph(priv, APMG_CLK_DIS_REG,
+                               APMG_CLK_VAL_DMA_CLK_RQT);
 
        udelay(5);
 
-       if (exit_pending || test_bit(STATUS_IN_SUSPEND, &priv->status))
+       if (exit_pending)
                priv->cfg->ops->lib->apm_ops.stop(priv);
        else
                priv->cfg->ops->lib->apm_ops.reset(priv);
@@ -3131,12 +2647,6 @@ static int __iwl3945_up(struct iwl_priv *priv)
                return -EIO;
        }
 
-       if (test_bit(STATUS_RF_KILL_SW, &priv->status)) {
-               IWL_WARN(priv, "Radio disabled by SW RF kill (module "
-                           "parameter)\n");
-               return -ENODEV;
-       }
-
        if (!priv->ucode_data_backup.v_addr || !priv->ucode_data.v_addr) {
                IWL_ERR(priv, "ucode not available for device bring up\n");
                return -EIO;
@@ -3148,10 +2658,8 @@ static int __iwl3945_up(struct iwl_priv *priv)
                clear_bit(STATUS_RF_KILL_HW, &priv->status);
        else {
                set_bit(STATUS_RF_KILL_HW, &priv->status);
-               if (!test_bit(STATUS_IN_SUSPEND, &priv->status)) {
-                       IWL_WARN(priv, "Radio disabled by HW RF Kill switch\n");
-                       return -ENODEV;
-               }
+               IWL_WARN(priv, "Radio disabled by HW RF Kill switch\n");
+               return -ENODEV;
        }
 
        iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
@@ -3187,7 +2695,7 @@ static int __iwl3945_up(struct iwl_priv *priv)
 
        for (i = 0; i < MAX_HW_RESTARTS; i++) {
 
-               iwl3945_clear_stations_table(priv);
+               iwl_clear_stations_table(priv);
 
                /* load bootstrap state machine,
                 * load bootstrap program into processor's memory,
@@ -3255,15 +2763,14 @@ static void iwl3945_rfkill_poll(struct work_struct *data)
 {
        struct iwl_priv *priv =
            container_of(data, struct iwl_priv, rfkill_poll.work);
-       unsigned long status = priv->status;
 
        if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
                clear_bit(STATUS_RF_KILL_HW, &priv->status);
        else
                set_bit(STATUS_RF_KILL_HW, &priv->status);
 
-       if (test_bit(STATUS_RF_KILL_HW, &status) != test_bit(STATUS_RF_KILL_HW, &priv->status))
-               queue_work(priv->workqueue, &priv->rf_kill);
+       wiphy_rfkill_set_hw_state(priv->hw->wiphy,
+                       test_bit(STATUS_RF_KILL_HW, &priv->status));
 
        queue_delayed_work(priv->workqueue, &priv->rfkill_poll,
                           round_jiffies_relative(2 * HZ));
@@ -3283,9 +2790,9 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
        int rc = 0;
        struct iwl3945_scan_cmd *scan;
        struct ieee80211_conf *conf = NULL;
-       u8 n_probes = 2;
+       u8 n_probes = 0;
        enum ieee80211_band band;
-       DECLARE_SSID_BUF(ssid);
+       bool is_active = false;
 
        conf = ieee80211_get_hw_conf(priv->hw);
 
@@ -3386,18 +2893,25 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
                               scan_suspend_time, interval);
        }
 
-       /* We should add the ability for user to lock to PASSIVE ONLY */
-       if (priv->one_direct_scan) {
-               IWL_DEBUG_SCAN(priv, "Kicking off one direct scan for '%s'\n",
-                               print_ssid(ssid, priv->direct_ssid,
-                               priv->direct_ssid_len));
-               scan->direct_scan[0].id = WLAN_EID_SSID;
-               scan->direct_scan[0].len = priv->direct_ssid_len;
-               memcpy(scan->direct_scan[0].ssid,
-                      priv->direct_ssid, priv->direct_ssid_len);
-               n_probes++;
+       if (priv->scan_request->n_ssids) {
+               int i, p = 0;
+               IWL_DEBUG_SCAN(priv, "Kicking off active scan\n");
+               for (i = 0; i < priv->scan_request->n_ssids; i++) {
+                       /* always does wildcard anyway */
+                       if (!priv->scan_request->ssids[i].ssid_len)
+                               continue;
+                       scan->direct_scan[p].id = WLAN_EID_SSID;
+                       scan->direct_scan[p].len =
+                               priv->scan_request->ssids[i].ssid_len;
+                       memcpy(scan->direct_scan[p].ssid,
+                              priv->scan_request->ssids[i].ssid,
+                              priv->scan_request->ssids[i].ssid_len);
+                       n_probes++;
+                       p++;
+               }
+               is_active = true;
        } else
-               IWL_DEBUG_SCAN(priv, "Kicking off one indirect scan.\n");
+               IWL_DEBUG_SCAN(priv, "Kicking off passive scan.\n");
 
        /* We don't build a direct scan probe request; the uCode will do
         * that based on the direct_mask added to each channel entry */
@@ -3414,7 +2928,12 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
                band = IEEE80211_BAND_2GHZ;
        } else if (priv->scan_bands & BIT(IEEE80211_BAND_5GHZ)) {
                scan->tx_cmd.rate = IWL_RATE_6M_PLCP;
-               scan->good_CRC_th = IWL_GOOD_CRC_TH;
+               /*
+                * If active scaning is requested but a certain channel
+                * is marked passive, we can do active scanning if we
+                * detect transmissions.
+                */
+               scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH : 0;
                band = IEEE80211_BAND_5GHZ;
        } else {
                IWL_WARN(priv, "Invalid scan band count\n");
@@ -3422,19 +2941,20 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
        }
 
        scan->tx_cmd.len = cpu_to_le16(
-               iwl_fill_probe_req(priv, band,
-                                  (struct ieee80211_mgmt *)scan->data,
-                                  IWL_MAX_SCAN_SIZE - sizeof(*scan)));
+                       iwl_fill_probe_req(priv,
+                               (struct ieee80211_mgmt *)scan->data,
+                               priv->scan_request->ie,
+                               priv->scan_request->ie_len,
+                               IWL_MAX_SCAN_SIZE - sizeof(*scan)));
 
        /* select Rx antennas */
        scan->flags |= iwl3945_get_antenna_flags(priv);
 
-       if (priv->iw_mode == NL80211_IFTYPE_MONITOR)
+       if (iwl_is_monitor_mode(priv))
                scan->filter_flags = RXON_FILTER_PROMISC_MSK;
 
        scan->channel_count =
-               iwl3945_get_channels_for_scan(priv, band, 1, /* active */
-                                             n_probes,
+               iwl3945_get_channels_for_scan(priv, band, is_active, n_probes,
                        (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]);
 
        if (scan->channel_count == 0) {
@@ -3482,7 +3002,6 @@ static void iwl3945_bg_up(struct work_struct *data)
        mutex_lock(&priv->mutex);
        __iwl3945_up(priv);
        mutex_unlock(&priv->mutex);
-       iwl_rfkill_set_hw_state(priv);
 }
 
 static void iwl3945_bg_restart(struct work_struct *data)
@@ -3492,8 +3011,17 @@ static void iwl3945_bg_restart(struct work_struct *data)
        if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
 
-       iwl3945_down(priv);
-       queue_work(priv->workqueue, &priv->up);
+       if (test_and_clear_bit(STATUS_FW_ERROR, &priv->status)) {
+               mutex_lock(&priv->mutex);
+               priv->vif = NULL;
+               priv->is_open = 0;
+               mutex_unlock(&priv->mutex);
+               iwl3945_down(priv);
+               ieee80211_restart_hw(priv->hw);
+       } else {
+               iwl3945_down(priv);
+               queue_work(priv->workqueue, &priv->up);
+       }
 }
 
 static void iwl3945_bg_rx_replenish(struct work_struct *data)
@@ -3511,7 +3039,7 @@ static void iwl3945_bg_rx_replenish(struct work_struct *data)
 
 #define IWL_DELAY_NEXT_SCAN (HZ*2)
 
-static void iwl3945_post_associate(struct iwl_priv *priv)
+void iwl3945_post_associate(struct iwl_priv *priv)
 {
        int rc = 0;
        struct ieee80211_conf *conf = NULL;
@@ -3536,7 +3064,7 @@ static void iwl3945_post_associate(struct iwl_priv *priv)
        conf = ieee80211_get_hw_conf(priv->hw);
 
        priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
-       iwl3945_commit_rxon(priv);
+       iwlcore_commit_rxon(priv);
 
        memset(&priv->rxon_timing, 0, sizeof(struct iwl_rxon_time_cmd));
        iwl3945_setup_rxon_timing(priv);
@@ -3569,7 +3097,7 @@ static void iwl3945_post_associate(struct iwl_priv *priv)
 
        }
 
-       iwl3945_commit_rxon(priv);
+       iwlcore_commit_rxon(priv);
 
        switch (priv->iw_mode) {
        case NL80211_IFTYPE_STATION:
@@ -3579,7 +3107,7 @@ static void iwl3945_post_associate(struct iwl_priv *priv)
        case NL80211_IFTYPE_ADHOC:
 
                priv->assoc_id = 1;
-               iwl3945_add_station(priv, priv->bssid, 0, 0);
+               iwl_add_station(priv, priv->bssid, 0, CMD_SYNC, NULL);
                iwl3945_sync_sta(priv, IWL_STA_ID,
                                 (priv->band == IEEE80211_BAND_5GHZ) ?
                                 IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP,
@@ -3601,8 +3129,6 @@ static void iwl3945_post_associate(struct iwl_priv *priv)
        priv->next_scan_jiffies = jiffies + IWL_DELAY_NEXT_SCAN;
 }
 
-static int iwl3945_mac_config(struct ieee80211_hw *hw, u32 changed);
-
 /*****************************************************************************
  *
  * mac80211 entry point functions
@@ -3638,16 +3164,11 @@ static int iwl3945_mac_start(struct ieee80211_hw *hw)
 
        mutex_unlock(&priv->mutex);
 
-       iwl_rfkill_set_hw_state(priv);
-
        if (ret)
                goto out_release_irq;
 
        IWL_DEBUG_INFO(priv, "Start UP work.\n");
 
-       if (test_bit(STATUS_IN_SUSPEND, &priv->status))
-               return 0;
-
        /* Wait for START_ALIVE from ucode. Otherwise callbacks from
         * mac80211 will not be run successfully. */
        ret = wait_event_interruptible_timeout(priv->wait_command_queue,
@@ -3726,144 +3247,7 @@ static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
        return NETDEV_TX_OK;
 }
 
-static int iwl3945_mac_add_interface(struct ieee80211_hw *hw,
-                                struct ieee80211_if_init_conf *conf)
-{
-       struct iwl_priv *priv = hw->priv;
-       unsigned long flags;
-
-       IWL_DEBUG_MAC80211(priv, "enter: type %d\n", conf->type);
-
-       if (priv->vif) {
-               IWL_DEBUG_MAC80211(priv, "leave - vif != NULL\n");
-               return -EOPNOTSUPP;
-       }
-
-       spin_lock_irqsave(&priv->lock, flags);
-       priv->vif = conf->vif;
-       priv->iw_mode = conf->type;
-
-       spin_unlock_irqrestore(&priv->lock, flags);
-
-       mutex_lock(&priv->mutex);
-
-       if (conf->mac_addr) {
-               IWL_DEBUG_MAC80211(priv, "Set: %pM\n", conf->mac_addr);
-               memcpy(priv->mac_addr, conf->mac_addr, ETH_ALEN);
-       }
-
-       if (iwl_is_ready(priv))
-               iwl3945_set_mode(priv, conf->type);
-
-       mutex_unlock(&priv->mutex);
-
-       IWL_DEBUG_MAC80211(priv, "leave\n");
-       return 0;
-}
-
-/**
- * iwl3945_mac_config - mac80211 config callback
- *
- * We ignore conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME since it seems to
- * be set inappropriately and the driver currently sets the hardware up to
- * use it whenever needed.
- */
-static int iwl3945_mac_config(struct ieee80211_hw *hw, u32 changed)
-{
-       struct iwl_priv *priv = hw->priv;
-       const struct iwl_channel_info *ch_info;
-       struct ieee80211_conf *conf = &hw->conf;
-       unsigned long flags;
-       int ret = 0;
-
-       mutex_lock(&priv->mutex);
-       IWL_DEBUG_MAC80211(priv, "enter to channel %d\n",
-                               conf->channel->hw_value);
-
-       if (!iwl_is_ready(priv)) {
-               IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
-               ret = -EIO;
-               goto out;
-       }
-
-       if (unlikely(!iwl3945_mod_params.disable_hw_scan &&
-                    test_bit(STATUS_SCANNING, &priv->status))) {
-               IWL_DEBUG_MAC80211(priv, "leave - scanning\n");
-               set_bit(STATUS_CONF_PENDING, &priv->status);
-               mutex_unlock(&priv->mutex);
-               return 0;
-       }
-
-       spin_lock_irqsave(&priv->lock, flags);
-
-       ch_info = iwl_get_channel_info(priv, conf->channel->band,
-                                      conf->channel->hw_value);
-       if (!is_channel_valid(ch_info)) {
-               IWL_DEBUG_SCAN(priv,
-                               "Channel %d [%d] is INVALID for this band.\n",
-                               conf->channel->hw_value, conf->channel->band);
-               IWL_DEBUG_MAC80211(priv, "leave - invalid channel\n");
-               spin_unlock_irqrestore(&priv->lock, flags);
-               ret = -EINVAL;
-               goto out;
-       }
-
-       iwl_set_rxon_channel(priv, conf->channel);
-
-       iwl_set_flags_for_band(priv, conf->channel->band);
-
-       /* The list of supported rates and rate mask can be different
-        * for each phymode; since the phymode may have changed, reset
-        * the rate mask to what mac80211 lists */
-       iwl_set_rate(priv);
-
-       spin_unlock_irqrestore(&priv->lock, flags);
-
-#ifdef IEEE80211_CONF_CHANNEL_SWITCH
-       if (conf->flags & IEEE80211_CONF_CHANNEL_SWITCH) {
-               iwl3945_hw_channel_switch(priv, conf->channel);
-               goto out;
-       }
-#endif
-
-       if (changed & IEEE80211_CONF_CHANGE_RADIO_ENABLED) {
-               if (conf->radio_enabled &&
-                   iwl_radio_kill_sw_enable_radio(priv)) {
-                       IWL_DEBUG_MAC80211(priv, "leave - RF-KILL - "
-                                                "waiting for uCode\n");
-                       goto out;
-               }
-
-               if (!conf->radio_enabled) {
-                       iwl_radio_kill_sw_disable_radio(priv);
-                       IWL_DEBUG_MAC80211(priv, "leave - radio disabled\n");
-                       goto out;
-               }
-       }
-
-       if (iwl_is_rfkill(priv)) {
-               IWL_DEBUG_MAC80211(priv, "leave - RF kill\n");
-               ret = -EIO;
-               goto out;
-       }
-
-       iwl_set_rate(priv);
-
-       if (memcmp(&priv->active_rxon,
-                  &priv->staging_rxon, sizeof(priv->staging_rxon)))
-               iwl3945_commit_rxon(priv);
-       else
-               IWL_DEBUG_INFO(priv, "Not re-sending same RXON configuration\n");
-
-       IWL_DEBUG_MAC80211(priv, "leave\n");
-
-out:
-       clear_bit(STATUS_CONF_PENDING, &priv->status);
-       mutex_unlock(&priv->mutex);
-       return ret;
-}
-
-static void iwl3945_config_ap(struct iwl_priv *priv)
+void iwl3945_config_ap(struct iwl_priv *priv)
 {
        int rc = 0;
 
@@ -3875,7 +3259,7 @@ static void iwl3945_config_ap(struct iwl_priv *priv)
 
                /* RXON - unassoc (to set timing command) */
                priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
-               iwl3945_commit_rxon(priv);
+               iwlcore_commit_rxon(priv);
 
                /* RXON Timing */
                memset(&priv->rxon_timing, 0, sizeof(struct iwl_rxon_time_cmd));
@@ -3911,8 +3295,8 @@ static void iwl3945_config_ap(struct iwl_priv *priv)
                }
                /* restore RXON assoc */
                priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
-               iwl3945_commit_rxon(priv);
-               iwl3945_add_station(priv, iwl_bcast_addr, 0, 0);
+               iwlcore_commit_rxon(priv);
+               iwl_add_station(priv, iwl_bcast_addr, 0, CMD_SYNC, NULL);
        }
        iwl3945_send_beacon_cmd(priv);
 
@@ -3921,189 +3305,6 @@ static void iwl3945_config_ap(struct iwl_priv *priv)
         * clear sta table, add BCAST sta... */
 }
 
-static int iwl3945_mac_config_interface(struct ieee80211_hw *hw,
-                                       struct ieee80211_vif *vif,
-                                       struct ieee80211_if_conf *conf)
-{
-       struct iwl_priv *priv = hw->priv;
-       int rc;
-
-       if (conf == NULL)
-               return -EIO;
-
-       if (priv->vif != vif) {
-               IWL_DEBUG_MAC80211(priv, "leave - priv->vif != vif\n");
-               return 0;
-       }
-
-       /* handle this temporarily here */
-       if (priv->iw_mode == NL80211_IFTYPE_ADHOC &&
-           conf->changed & IEEE80211_IFCC_BEACON) {
-               struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
-               if (!beacon)
-                       return -ENOMEM;
-               mutex_lock(&priv->mutex);
-               rc = iwl3945_mac_beacon_update(hw, beacon);
-               mutex_unlock(&priv->mutex);
-               if (rc)
-                       return rc;
-       }
-
-       if (!iwl_is_alive(priv))
-               return -EAGAIN;
-
-       mutex_lock(&priv->mutex);
-
-       if (conf->bssid)
-               IWL_DEBUG_MAC80211(priv, "bssid: %pM\n", conf->bssid);
-
-/*
- * very dubious code was here; the probe filtering flag is never set:
- *
-       if (unlikely(test_bit(STATUS_SCANNING, &priv->status)) &&
-           !(priv->hw->flags & IEEE80211_HW_NO_PROBE_FILTERING)) {
- */
-
-       if (priv->iw_mode == NL80211_IFTYPE_AP) {
-               if (!conf->bssid) {
-                       conf->bssid = priv->mac_addr;
-                       memcpy(priv->bssid, priv->mac_addr, ETH_ALEN);
-                       IWL_DEBUG_MAC80211(priv, "bssid was set to: %pM\n",
-                                          conf->bssid);
-               }
-               if (priv->ibss_beacon)
-                       dev_kfree_skb(priv->ibss_beacon);
-
-               priv->ibss_beacon = ieee80211_beacon_get(hw, vif);
-       }
-
-       if (iwl_is_rfkill(priv))
-               goto done;
-
-       if (conf->bssid && !is_zero_ether_addr(conf->bssid) &&
-           !is_multicast_ether_addr(conf->bssid)) {
-               /* If there is currently a HW scan going on in the background
-                * then we need to cancel it else the RXON below will fail. */
-               if (iwl_scan_cancel_timeout(priv, 100)) {
-                       IWL_WARN(priv, "Aborted scan still in progress "
-                                   "after 100ms\n");
-                       IWL_DEBUG_MAC80211(priv, "leaving:scan abort failed\n");
-                       mutex_unlock(&priv->mutex);
-                       return -EAGAIN;
-               }
-               memcpy(priv->staging_rxon.bssid_addr, conf->bssid, ETH_ALEN);
-
-               /* TODO: Audit driver for usage of these members and see
-                * if mac80211 deprecates them (priv->bssid looks like it
-                * shouldn't be there, but I haven't scanned the IBSS code
-                * to verify) - jpk */
-               memcpy(priv->bssid, conf->bssid, ETH_ALEN);
-
-               if (priv->iw_mode == NL80211_IFTYPE_AP)
-                       iwl3945_config_ap(priv);
-               else {
-                       rc = iwl3945_commit_rxon(priv);
-                       if ((priv->iw_mode == NL80211_IFTYPE_STATION) && rc)
-                               iwl3945_add_station(priv,
-                                       priv->active_rxon.bssid_addr, 1, 0);
-               }
-
-       } else {
-               iwl_scan_cancel_timeout(priv, 100);
-               priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
-               iwl3945_commit_rxon(priv);
-       }
-
- done:
-       IWL_DEBUG_MAC80211(priv, "leave\n");
-       mutex_unlock(&priv->mutex);
-
-       return 0;
-}
-
-static void iwl3945_mac_remove_interface(struct ieee80211_hw *hw,
-                                    struct ieee80211_if_init_conf *conf)
-{
-       struct iwl_priv *priv = hw->priv;
-
-       IWL_DEBUG_MAC80211(priv, "enter\n");
-
-       mutex_lock(&priv->mutex);
-
-       if (iwl_is_ready_rf(priv)) {
-               iwl_scan_cancel_timeout(priv, 100);
-               priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
-               iwl3945_commit_rxon(priv);
-       }
-       if (priv->vif == conf->vif) {
-               priv->vif = NULL;
-               memset(priv->bssid, 0, ETH_ALEN);
-       }
-       mutex_unlock(&priv->mutex);
-
-       IWL_DEBUG_MAC80211(priv, "leave\n");
-}
-
-#define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6)
-
-static void iwl3945_bss_info_changed(struct ieee80211_hw *hw,
-                                    struct ieee80211_vif *vif,
-                                    struct ieee80211_bss_conf *bss_conf,
-                                    u32 changes)
-{
-       struct iwl_priv *priv = hw->priv;
-
-       IWL_DEBUG_MAC80211(priv, "changes = 0x%X\n", changes);
-
-       if (changes & BSS_CHANGED_ERP_PREAMBLE) {
-               IWL_DEBUG_MAC80211(priv, "ERP_PREAMBLE %d\n",
-                                  bss_conf->use_short_preamble);
-               if (bss_conf->use_short_preamble)
-                       priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
-               else
-                       priv->staging_rxon.flags &=
-                               ~RXON_FLG_SHORT_PREAMBLE_MSK;
-       }
-
-       if (changes & BSS_CHANGED_ERP_CTS_PROT) {
-               IWL_DEBUG_MAC80211(priv, "ERP_CTS %d\n",
-                                  bss_conf->use_cts_prot);
-               if (bss_conf->use_cts_prot && (priv->band != IEEE80211_BAND_5GHZ))
-                       priv->staging_rxon.flags |= RXON_FLG_TGG_PROTECT_MSK;
-               else
-                       priv->staging_rxon.flags &= ~RXON_FLG_TGG_PROTECT_MSK;
-       }
-
-       if (changes & BSS_CHANGED_ASSOC) {
-               IWL_DEBUG_MAC80211(priv, "ASSOC %d\n", bss_conf->assoc);
-               /* This should never happen as this function should
-                * never be called from interrupt context. */
-               if (WARN_ON_ONCE(in_interrupt()))
-                       return;
-               if (bss_conf->assoc) {
-                       priv->assoc_id = bss_conf->aid;
-                       priv->beacon_int = bss_conf->beacon_int;
-                       priv->timestamp = bss_conf->timestamp;
-                       priv->assoc_capability = bss_conf->assoc_capability;
-                       priv->power_data.dtim_period = bss_conf->dtim_period;
-                       priv->next_scan_jiffies = jiffies +
-                                       IWL_DELAY_NEXT_SCAN_AFTER_ASSOC;
-                       mutex_lock(&priv->mutex);
-                       iwl3945_post_associate(priv);
-                       mutex_unlock(&priv->mutex);
-               } else {
-                       priv->assoc_id = 0;
-                       IWL_DEBUG_MAC80211(priv,
-                                       "DISASSOC %d\n", bss_conf->assoc);
-               }
-       } else if (changes && iwl_is_associated(priv) && priv->assoc_id) {
-                       IWL_DEBUG_MAC80211(priv,
-                                       "Associated Changes %d\n", changes);
-                       iwl3945_send_rxon_assoc(priv);
-       }
-
-}
-
 static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
                               struct ieee80211_vif *vif,
                               struct ieee80211_sta *sta,
@@ -4126,7 +3327,7 @@ static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
        static_key = !iwl_is_associated(priv);
 
        if (!static_key) {
-               sta_id = iwl3945_hw_find_station(priv, addr);
+               sta_id = iwl_find_station(priv, addr);
                if (sta_id == IWL_INVALID_STATION) {
                        IWL_DEBUG_MAC80211(priv, "leave - %pM not in station map.\n",
                                            addr);
@@ -4162,185 +3363,6 @@ static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
        return ret;
 }
 
-static int iwl3945_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
-                          const struct ieee80211_tx_queue_params *params)
-{
-       struct iwl_priv *priv = hw->priv;
-       unsigned long flags;
-       int q;
-
-       IWL_DEBUG_MAC80211(priv, "enter\n");
-
-       if (!iwl_is_ready_rf(priv)) {
-               IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
-               return -EIO;
-       }
-
-       if (queue >= AC_NUM) {
-               IWL_DEBUG_MAC80211(priv, "leave - queue >= AC_NUM %d\n", queue);
-               return 0;
-       }
-
-       q = AC_NUM - 1 - queue;
-
-       spin_lock_irqsave(&priv->lock, flags);
-
-       priv->qos_data.def_qos_parm.ac[q].cw_min = cpu_to_le16(params->cw_min);
-       priv->qos_data.def_qos_parm.ac[q].cw_max = cpu_to_le16(params->cw_max);
-       priv->qos_data.def_qos_parm.ac[q].aifsn = params->aifs;
-       priv->qos_data.def_qos_parm.ac[q].edca_txop =
-                       cpu_to_le16((params->txop * 32));
-
-       priv->qos_data.def_qos_parm.ac[q].reserved1 = 0;
-       priv->qos_data.qos_active = 1;
-
-       spin_unlock_irqrestore(&priv->lock, flags);
-
-       mutex_lock(&priv->mutex);
-       if (priv->iw_mode == NL80211_IFTYPE_AP)
-               iwl_activate_qos(priv, 1);
-       else if (priv->assoc_id && iwl_is_associated(priv))
-               iwl_activate_qos(priv, 0);
-
-       mutex_unlock(&priv->mutex);
-
-       IWL_DEBUG_MAC80211(priv, "leave\n");
-       return 0;
-}
-
-static int iwl3945_mac_get_tx_stats(struct ieee80211_hw *hw,
-                               struct ieee80211_tx_queue_stats *stats)
-{
-       struct iwl_priv *priv = hw->priv;
-       int i, avail;
-       struct iwl_tx_queue *txq;
-       struct iwl_queue *q;
-       unsigned long flags;
-
-       IWL_DEBUG_MAC80211(priv, "enter\n");
-
-       if (!iwl_is_ready_rf(priv)) {
-               IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
-               return -EIO;
-       }
-
-       spin_lock_irqsave(&priv->lock, flags);
-
-       for (i = 0; i < AC_NUM; i++) {
-               txq = &priv->txq[i];
-               q = &txq->q;
-               avail = iwl_queue_space(q);
-
-               stats[i].len = q->n_window - avail;
-               stats[i].limit = q->n_window - q->high_mark;
-               stats[i].count = q->n_window;
-
-       }
-       spin_unlock_irqrestore(&priv->lock, flags);
-
-       IWL_DEBUG_MAC80211(priv, "leave\n");
-
-       return 0;
-}
-
-static void iwl3945_mac_reset_tsf(struct ieee80211_hw *hw)
-{
-       struct iwl_priv *priv = hw->priv;
-       unsigned long flags;
-
-       mutex_lock(&priv->mutex);
-       IWL_DEBUG_MAC80211(priv, "enter\n");
-
-       iwl_reset_qos(priv);
-
-       spin_lock_irqsave(&priv->lock, flags);
-       priv->assoc_id = 0;
-       priv->assoc_capability = 0;
-
-       /* new association get rid of ibss beacon skb */
-       if (priv->ibss_beacon)
-               dev_kfree_skb(priv->ibss_beacon);
-
-       priv->ibss_beacon = NULL;
-
-       priv->beacon_int = priv->hw->conf.beacon_int;
-       priv->timestamp = 0;
-       if ((priv->iw_mode == NL80211_IFTYPE_STATION))
-               priv->beacon_int = 0;
-
-       spin_unlock_irqrestore(&priv->lock, flags);
-
-       if (!iwl_is_ready_rf(priv)) {
-               IWL_DEBUG_MAC80211(priv, "leave - not ready\n");
-               mutex_unlock(&priv->mutex);
-               return;
-       }
-
-       /* we are restarting association process
-        * clear RXON_FILTER_ASSOC_MSK bit
-       */
-       if (priv->iw_mode != NL80211_IFTYPE_AP) {
-               iwl_scan_cancel_timeout(priv, 100);
-               priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
-               iwl3945_commit_rxon(priv);
-       }
-
-       /* Per mac80211.h: This is only used in IBSS mode... */
-       if (priv->iw_mode != NL80211_IFTYPE_ADHOC) {
-
-               IWL_DEBUG_MAC80211(priv, "leave - not in IBSS\n");
-               mutex_unlock(&priv->mutex);
-               return;
-       }
-
-       iwl_set_rate(priv);
-
-       mutex_unlock(&priv->mutex);
-
-       IWL_DEBUG_MAC80211(priv, "leave\n");
-
-}
-
-static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
-{
-       struct iwl_priv *priv = hw->priv;
-       unsigned long flags;
-       __le64 timestamp;
-
-       IWL_DEBUG_MAC80211(priv, "enter\n");
-
-       if (!iwl_is_ready_rf(priv)) {
-               IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
-               return -EIO;
-       }
-
-       if (priv->iw_mode != NL80211_IFTYPE_ADHOC) {
-               IWL_DEBUG_MAC80211(priv, "leave - not IBSS\n");
-               return -EIO;
-       }
-
-       spin_lock_irqsave(&priv->lock, flags);
-
-       if (priv->ibss_beacon)
-               dev_kfree_skb(priv->ibss_beacon);
-
-       priv->ibss_beacon = skb;
-
-       priv->assoc_id = 0;
-       timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp;
-       priv->timestamp = le64_to_cpu(timestamp);
-
-       IWL_DEBUG_MAC80211(priv, "leave\n");
-       spin_unlock_irqrestore(&priv->lock, flags);
-
-       iwl_reset_qos(priv);
-
-       iwl3945_post_associate(priv);
-
-
-       return 0;
-}
-
 /*****************************************************************************
  *
  * sysfs attributes
@@ -4359,7 +3381,7 @@ static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk
 static ssize_t show_debug_level(struct device *d,
                                struct device_attribute *attr, char *buf)
 {
-       struct iwl_priv *priv = d->driver_data;
+       struct iwl_priv *priv = dev_get_drvdata(d);
 
        return sprintf(buf, "0x%08X\n", priv->debug_level);
 }
@@ -4367,7 +3389,7 @@ static ssize_t store_debug_level(struct device *d,
                                struct device_attribute *attr,
                                 const char *buf, size_t count)
 {
-       struct iwl_priv *priv = d->driver_data;
+       struct iwl_priv *priv = dev_get_drvdata(d);
        unsigned long val;
        int ret;
 
@@ -4388,7 +3410,7 @@ static DEVICE_ATTR(debug_level, S_IWUSR | S_IRUGO,
 static ssize_t show_temperature(struct device *d,
                                struct device_attribute *attr, char *buf)
 {
-       struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+       struct iwl_priv *priv = dev_get_drvdata(d);
 
        if (!iwl_is_alive(priv))
                return -EAGAIN;
@@ -4401,7 +3423,7 @@ static DEVICE_ATTR(temperature, S_IRUGO, show_temperature, NULL);
 static ssize_t show_tx_power(struct device *d,
                             struct device_attribute *attr, char *buf)
 {
-       struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+       struct iwl_priv *priv = dev_get_drvdata(d);
        return sprintf(buf, "%d\n", priv->tx_power_user_lmt);
 }
 
@@ -4409,7 +3431,7 @@ static ssize_t store_tx_power(struct device *d,
                              struct device_attribute *attr,
                              const char *buf, size_t count)
 {
-       struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+       struct iwl_priv *priv = dev_get_drvdata(d);
        char *p = (char *)buf;
        u32 val;
 
@@ -4427,7 +3449,7 @@ static DEVICE_ATTR(tx_power, S_IWUSR | S_IRUGO, show_tx_power, store_tx_power);
 static ssize_t show_flags(struct device *d,
                          struct device_attribute *attr, char *buf)
 {
-       struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+       struct iwl_priv *priv = dev_get_drvdata(d);
 
        return sprintf(buf, "0x%04X\n", priv->active_rxon.flags);
 }
@@ -4436,7 +3458,7 @@ static ssize_t store_flags(struct device *d,
                           struct device_attribute *attr,
                           const char *buf, size_t count)
 {
-       struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+       struct iwl_priv *priv = dev_get_drvdata(d);
        u32 flags = simple_strtoul(buf, NULL, 0);
 
        mutex_lock(&priv->mutex);
@@ -4448,7 +3470,7 @@ static ssize_t store_flags(struct device *d,
                        IWL_DEBUG_INFO(priv, "Committing rxon.flags = 0x%04X\n",
                                       flags);
                        priv->staging_rxon.flags = cpu_to_le32(flags);
-                       iwl3945_commit_rxon(priv);
+                       iwlcore_commit_rxon(priv);
                }
        }
        mutex_unlock(&priv->mutex);
@@ -4461,7 +3483,7 @@ static DEVICE_ATTR(flags, S_IWUSR | S_IRUGO, show_flags, store_flags);
 static ssize_t show_filter_flags(struct device *d,
                                 struct device_attribute *attr, char *buf)
 {
-       struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+       struct iwl_priv *priv = dev_get_drvdata(d);
 
        return sprintf(buf, "0x%04X\n",
                le32_to_cpu(priv->active_rxon.filter_flags));
@@ -4471,7 +3493,7 @@ static ssize_t store_filter_flags(struct device *d,
                                  struct device_attribute *attr,
                                  const char *buf, size_t count)
 {
-       struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+       struct iwl_priv *priv = dev_get_drvdata(d);
        u32 filter_flags = simple_strtoul(buf, NULL, 0);
 
        mutex_lock(&priv->mutex);
@@ -4484,7 +3506,7 @@ static ssize_t store_filter_flags(struct device *d,
                                       "0x%04X\n", filter_flags);
                        priv->staging_rxon.filter_flags =
                                cpu_to_le32(filter_flags);
-                       iwl3945_commit_rxon(priv);
+                       iwlcore_commit_rxon(priv);
                }
        }
        mutex_unlock(&priv->mutex);
@@ -4624,26 +3646,11 @@ static ssize_t show_power_level(struct device *d,
 {
        struct iwl_priv *priv = dev_get_drvdata(d);
        int mode = priv->power_data.user_power_setting;
-       int system = priv->power_data.system_power_setting;
        int level = priv->power_data.power_mode;
        char *p = buf;
 
-       switch (system) {
-       case IWL_POWER_SYS_AUTO:
-               p += sprintf(p, "SYSTEM:auto");
-               break;
-       case IWL_POWER_SYS_AC:
-               p += sprintf(p, "SYSTEM:ac");
-               break;
-       case IWL_POWER_SYS_BATTERY:
-               p += sprintf(p, "SYSTEM:battery");
-               break;
-       }
-
-       p += sprintf(p, "\tMODE:%s", (mode < IWL_POWER_AUTO) ?
-                       "fixed" : "auto");
-       p += sprintf(p, "\tINDEX:%d", level);
-       p += sprintf(p, "\n");
+       p += sprintf(p, "INDEX:%d\t", level);
+       p += sprintf(p, "USER:%d\n", mode);
        return p - buf + 1;
 }
 
@@ -4756,7 +3763,7 @@ static DEVICE_ATTR(antenna, S_IWUSR | S_IRUGO, show_antenna, store_antenna);
 static ssize_t show_status(struct device *d,
                           struct device_attribute *attr, char *buf)
 {
-       struct iwl_priv *priv = (struct iwl_priv *)d->driver_data;
+       struct iwl_priv *priv = dev_get_drvdata(d);
        if (!iwl_is_alive(priv))
                return -EAGAIN;
        return sprintf(buf, "0x%08x\n", (int)priv->status);
@@ -4768,10 +3775,11 @@ static ssize_t dump_error_log(struct device *d,
                              struct device_attribute *attr,
                              const char *buf, size_t count)
 {
+       struct iwl_priv *priv = dev_get_drvdata(d);
        char *p = (char *)buf;
 
        if (p[0] == '1')
-               iwl3945_dump_nic_error_log((struct iwl_priv *)d->driver_data);
+               iwl3945_dump_nic_error_log(priv);
 
        return strnlen(buf, count);
 }
@@ -4782,10 +3790,11 @@ static ssize_t dump_event_log(struct device *d,
                              struct device_attribute *attr,
                              const char *buf, size_t count)
 {
+       struct iwl_priv *priv = dev_get_drvdata(d);
        char *p = (char *)buf;
 
        if (p[0] == '1')
-               iwl3945_dump_nic_event_log((struct iwl_priv *)d->driver_data);
+               iwl3945_dump_nic_event_log(priv);
 
        return strnlen(buf, count);
 }
@@ -4807,7 +3816,6 @@ static void iwl3945_setup_deferred_work(struct iwl_priv *priv)
        INIT_WORK(&priv->up, iwl3945_bg_up);
        INIT_WORK(&priv->restart, iwl3945_bg_restart);
        INIT_WORK(&priv->rx_replenish, iwl3945_bg_rx_replenish);
-       INIT_WORK(&priv->rf_kill, iwl_bg_rf_kill);
        INIT_WORK(&priv->beacon_update, iwl3945_bg_beacon_update);
        INIT_DELAYED_WORK(&priv->init_alive_start, iwl3945_bg_init_alive_start);
        INIT_DELAYED_WORK(&priv->alive_start, iwl3945_bg_alive_start);
@@ -4864,16 +3872,15 @@ static struct ieee80211_ops iwl3945_hw_ops = {
        .tx = iwl3945_mac_tx,
        .start = iwl3945_mac_start,
        .stop = iwl3945_mac_stop,
-       .add_interface = iwl3945_mac_add_interface,
-       .remove_interface = iwl3945_mac_remove_interface,
-       .config = iwl3945_mac_config,
-       .config_interface = iwl3945_mac_config_interface,
+       .add_interface = iwl_mac_add_interface,
+       .remove_interface = iwl_mac_remove_interface,
+       .config = iwl_mac_config,
        .configure_filter = iwl_configure_filter,
        .set_key = iwl3945_mac_set_key,
-       .get_tx_stats = iwl3945_mac_get_tx_stats,
-       .conf_tx = iwl3945_mac_conf_tx,
-       .reset_tsf = iwl3945_mac_reset_tsf,
-       .bss_info_changed = iwl3945_bss_info_changed,
+       .get_tx_stats = iwl_mac_get_tx_stats,
+       .conf_tx = iwl_mac_conf_tx,
+       .reset_tsf = iwl_mac_reset_tsf,
+       .bss_info_changed = iwl_bss_info_changed,
        .hw_scan = iwl_mac_hw_scan
 };
 
@@ -4886,7 +3893,6 @@ static int iwl3945_init_drv(struct iwl_priv *priv)
        priv->ibss_beacon = NULL;
 
        spin_lock_init(&priv->lock);
-       spin_lock_init(&priv->power_data.lock);
        spin_lock_init(&priv->sta_lock);
        spin_lock_init(&priv->hcmd_lock);
 
@@ -4895,7 +3901,7 @@ static int iwl3945_init_drv(struct iwl_priv *priv)
        mutex_init(&priv->mutex);
 
        /* Clear the driver's (not device's) station table */
-       iwl3945_clear_stations_table(priv);
+       iwl_clear_stations_table(priv);
 
        priv->data_retry_limit = -1;
        priv->ieee_channels = NULL;
@@ -4966,13 +3972,13 @@ static int iwl3945_setup_mac(struct iwl_priv *priv)
 
        hw->wiphy->custom_regulatory = true;
 
-       hw->wiphy->max_scan_ssids = 1; /* WILL FIX */
+       hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX_3945;
+       /* we create the 802.11 header and a zero-length SSID element */
+       hw->wiphy->max_scan_ie_len = IWL_MAX_PROBE_REQUEST - 24 - 2;
 
        /* Default value; 4 EDCA QOS priorities */
        hw->queues = 4;
 
-       hw->conf.beacon_int = 100;
-
        if (priv->bands[IEEE80211_BAND_2GHZ].n_channels)
                priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
                        &priv->bands[IEEE80211_BAND_2GHZ];
@@ -5037,6 +4043,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
        IWL_DEBUG_INFO(priv, "*** LOAD DRIVER ***\n");
        priv->cfg = cfg;
        priv->pci_dev = pdev;
+       priv->inta_mask = CSR_INI_SET_MASK;
 
 #ifdef CONFIG_IWLWIFI_DEBUG
        priv->debug_level = iwl3945_mod_params.debug;
@@ -5083,6 +4090,11 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
         * PCI Tx retries from interfering with C3 CPU state */
        pci_write_config_byte(pdev, 0x41, 0x00);
 
+       /* this spin lock will be used in apm_ops.init and EEPROM access
+        * we should init now
+        */
+       spin_lock_init(&priv->reg_lock);
+
        /* amp init */
        err = priv->cfg->ops->lib->apm_ops.init(priv);
        if (err < 0) {
@@ -5128,20 +4140,8 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
        IWL_INFO(priv, "Detected Intel Wireless WiFi Link %s\n",
                priv->cfg->name);
 
-       /***********************************
-        * 7. Initialize Module Parameters
-        * **********************************/
-
-       /* Initialize module parameter values here */
-       /* Disable radio (SW RF KILL) via parameter when loading driver */
-       if (iwl3945_mod_params.disable) {
-               set_bit(STATUS_RF_KILL_SW, &priv->status);
-               IWL_DEBUG_INFO(priv, "Radio disabled.\n");
-       }
-
-
        /***********************
-        * 8. Setup Services
+        * 7. Setup Services
         * ********************/
 
        spin_lock_irqsave(&priv->lock, flags);
@@ -5150,8 +4150,8 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
 
        pci_enable_msi(priv->pci_dev);
 
-       err = request_irq(priv->pci_dev->irq, iwl_isr, IRQF_SHARED,
-                         DRV_NAME, priv);
+       err = request_irq(priv->pci_dev->irq, priv->cfg->ops->lib->isr,
+                         IRQF_SHARED, DRV_NAME, priv);
        if (err) {
                IWL_ERR(priv, "Error allocating IRQ %d\n", priv->pci_dev->irq);
                goto out_disable_msi;
@@ -5169,7 +4169,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
        iwl3945_setup_rx_handlers(priv);
 
        /*********************************
-        * 9. Setup and Register mac80211
+        * 8. Setup and Register mac80211
         * *******************************/
 
        iwl_enable_interrupts(priv);
@@ -5178,12 +4178,9 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
        if (err)
                goto  out_remove_sysfs;
 
-       err = iwl_rfkill_init(priv);
+       err = iwl_dbgfs_register(priv, DRV_NAME);
        if (err)
-               IWL_ERR(priv, "Unable to initialize RFKILL system. "
-                                 "Ignoring error: %d\n", err);
-       else
-               iwl_rfkill_set_hw_state(priv);
+               IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err);
 
        /* Start monitoring the killswitch */
        queue_delayed_work(priv->workqueue, &priv->rfkill_poll,
@@ -5228,6 +4225,8 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev)
 
        IWL_DEBUG_INFO(priv, "*** UNLOAD DRIVER ***\n");
 
+       iwl_dbgfs_unregister(priv);
+
        set_bit(STATUS_EXIT_PENDING, &priv->status);
 
        if (priv->mac80211_registered) {
@@ -5248,7 +4247,6 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev)
 
        sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group);
 
-       iwl_rfkill_unregister(priv);
        cancel_delayed_work_sync(&priv->rfkill_poll);
 
        iwl3945_dealloc_ucode_pci(priv);
@@ -5258,7 +4256,7 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev)
        iwl3945_hw_txq_ctx_free(priv);
 
        iwl3945_unset_hw_params(priv);
-       iwl3945_clear_stations_table(priv);
+       iwl_clear_stations_table(priv);
 
        /*netif_stop_queue(dev); */
        flush_workqueue(priv->workqueue);
@@ -5286,43 +4284,6 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev)
        ieee80211_free_hw(priv->hw);
 }
 
-#ifdef CONFIG_PM
-
-static int iwl3945_pci_suspend(struct pci_dev *pdev, pm_message_t state)
-{
-       struct iwl_priv *priv = pci_get_drvdata(pdev);
-
-       if (priv->is_open) {
-               set_bit(STATUS_IN_SUSPEND, &priv->status);
-               iwl3945_mac_stop(priv->hw);
-               priv->is_open = 1;
-       }
-       pci_save_state(pdev);
-       pci_disable_device(pdev);
-       pci_set_power_state(pdev, PCI_D3hot);
-
-       return 0;
-}
-
-static int iwl3945_pci_resume(struct pci_dev *pdev)
-{
-       struct iwl_priv *priv = pci_get_drvdata(pdev);
-       int ret;
-
-       pci_set_power_state(pdev, PCI_D0);
-       ret = pci_enable_device(pdev);
-       if (ret)
-               return ret;
-       pci_restore_state(pdev);
-
-       if (priv->is_open)
-               iwl3945_mac_start(priv->hw);
-
-       clear_bit(STATUS_IN_SUSPEND, &priv->status);
-       return 0;
-}
-
-#endif /* CONFIG_PM */
 
 /*****************************************************************************
  *
@@ -5336,8 +4297,8 @@ static struct pci_driver iwl3945_driver = {
        .probe = iwl3945_pci_probe,
        .remove = __devexit_p(iwl3945_pci_remove),
 #ifdef CONFIG_PM
-       .suspend = iwl3945_pci_suspend,
-       .resume = iwl3945_pci_resume,
+       .suspend = iwl_pci_suspend,
+       .resume = iwl_pci_resume,
 #endif
 };
 
@@ -5378,8 +4339,6 @@ MODULE_FIRMWARE(IWL3945_MODULE_FIRMWARE(IWL3945_UCODE_API_MAX));
 
 module_param_named(antenna, iwl3945_mod_params.antenna, int, 0444);
 MODULE_PARM_DESC(antenna, "select antenna (1=Main, 2=Aux, default 0 [both])");
-module_param_named(disable, iwl3945_mod_params.disable, int, 0444);
-MODULE_PARM_DESC(disable, "manually disable the radio (default 0 [radio on])");
 module_param_named(swcrypto, iwl3945_mod_params.sw_crypto, int, 0444);
 MODULE_PARM_DESC(swcrypto,
                 "using software crypto (default 1 [software])\n");
diff --git a/drivers/net/wireless/iwmc3200wifi/Kconfig b/drivers/net/wireless/iwmc3200wifi/Kconfig
new file mode 100644 (file)
index 0000000..1eccb6d
--- /dev/null
@@ -0,0 +1,23 @@
+config IWM
+       tristate "Intel Wireless Multicomm 3200 WiFi driver"
+       depends on MMC && WLAN_80211 && EXPERIMENTAL
+       depends on CFG80211
+       select WIRELESS_EXT
+       select FW_LOADER
+
+config IWM_DEBUG
+       bool "Enable full debugging output in iwmc3200wifi"
+       depends on IWM && DEBUG_FS
+       ---help---
+         This option will enable debug tracing and setting for iwm
+
+         You can set the debug level and module through debugfs. By
+         default all modules are set to the IWL_DL_ERR level.
+         To see the list of debug modules and levels, see iwm/debug.h
+
+         For example, if you want the full MLME debug output:
+         echo 0xff > /debug/iwm/phyN/debug/mlme
+
+         Or, if you want the full debug, for all modules:
+         echo 0xff > /debug/iwm/phyN/debug/level
+         echo 0xff > /debug/iwm/phyN/debug/modules
diff --git a/drivers/net/wireless/iwmc3200wifi/Makefile b/drivers/net/wireless/iwmc3200wifi/Makefile
new file mode 100644 (file)
index 0000000..927f022
--- /dev/null
@@ -0,0 +1,5 @@
+obj-$(CONFIG_IWM) := iwmc3200wifi.o
+iwmc3200wifi-objs += main.o netdev.o rx.o tx.o sdio.o hal.o fw.o
+iwmc3200wifi-objs += commands.o wext.o cfg80211.o eeprom.o
+
+iwmc3200wifi-$(CONFIG_IWM_DEBUG) += debugfs.o
diff --git a/drivers/net/wireless/iwmc3200wifi/bus.h b/drivers/net/wireless/iwmc3200wifi/bus.h
new file mode 100644 (file)
index 0000000..836663e
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Intel Wireless Multicomm 3200 WiFi driver
+ *
+ * Copyright (C) 2009 Intel Corporation <ilw@linux.intel.com>
+ * Samuel Ortiz <samuel.ortiz@intel.com>
+ * Zhu Yi <yi.zhu@intel.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., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ */
+
+#ifndef __IWM_BUS_H__
+#define __IWM_BUS_H__
+
+#include "iwm.h"
+
+struct iwm_if_ops {
+       int (*enable)(struct iwm_priv *iwm);
+       int (*disable)(struct iwm_priv *iwm);
+       int (*send_chunk)(struct iwm_priv *iwm, u8* buf, int count);
+
+       int (*debugfs_init)(struct iwm_priv *iwm, struct dentry *parent_dir);
+       void (*debugfs_exit)(struct iwm_priv *iwm);
+
+       const char *umac_name;
+       const char *calib_lmac_name;
+       const char *lmac_name;
+};
+
+static inline int iwm_bus_send_chunk(struct iwm_priv *iwm, u8 *buf, int count)
+{
+       return iwm->bus_ops->send_chunk(iwm, buf, count);
+}
+
+static inline int iwm_bus_enable(struct iwm_priv *iwm)
+{
+       return iwm->bus_ops->enable(iwm);
+}
+
+static inline int iwm_bus_disable(struct iwm_priv *iwm)
+{
+       return iwm->bus_ops->disable(iwm);
+}
+
+#endif
diff --git a/drivers/net/wireless/iwmc3200wifi/cfg80211.c b/drivers/net/wireless/iwmc3200wifi/cfg80211.c
new file mode 100644 (file)
index 0000000..96f714e
--- /dev/null
@@ -0,0 +1,409 @@
+/*
+ * Intel Wireless Multicomm 3200 WiFi driver
+ *
+ * Copyright (C) 2009 Intel Corporation <ilw@linux.intel.com>
+ * Samuel Ortiz <samuel.ortiz@intel.com>
+ * Zhu Yi <yi.zhu@intel.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., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <linux/wireless.h>
+#include <linux/ieee80211.h>
+#include <net/cfg80211.h>
+
+#include "iwm.h"
+#include "commands.h"
+#include "cfg80211.h"
+#include "debug.h"
+
+#define RATETAB_ENT(_rate, _rateid, _flags) \
+       {                                                               \
+               .bitrate        = (_rate),                              \
+               .hw_value       = (_rateid),                            \
+               .flags          = (_flags),                             \
+       }
+
+#define CHAN2G(_channel, _freq, _flags) {                      \
+       .band                   = IEEE80211_BAND_2GHZ,          \
+       .center_freq            = (_freq),                      \
+       .hw_value               = (_channel),                   \
+       .flags                  = (_flags),                     \
+       .max_antenna_gain       = 0,                            \
+       .max_power              = 30,                           \
+}
+
+#define CHAN5G(_channel, _flags) {                             \
+       .band                   = IEEE80211_BAND_5GHZ,          \
+       .center_freq            = 5000 + (5 * (_channel)),      \
+       .hw_value               = (_channel),                   \
+       .flags                  = (_flags),                     \
+       .max_antenna_gain       = 0,                            \
+       .max_power              = 30,                           \
+}
+
+static struct ieee80211_rate iwm_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 iwm_a_rates            (iwm_rates + 4)
+#define iwm_a_rates_size       8
+#define iwm_g_rates            (iwm_rates + 0)
+#define iwm_g_rates_size       12
+
+static struct ieee80211_channel iwm_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 iwm_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 iwm_band_2ghz = {
+       .channels = iwm_2ghz_channels,
+       .n_channels = ARRAY_SIZE(iwm_2ghz_channels),
+       .bitrates = iwm_g_rates,
+       .n_bitrates = iwm_g_rates_size,
+};
+
+static struct ieee80211_supported_band iwm_band_5ghz = {
+       .channels = iwm_5ghz_a_channels,
+       .n_channels = ARRAY_SIZE(iwm_5ghz_a_channels),
+       .bitrates = iwm_a_rates,
+       .n_bitrates = iwm_a_rates_size,
+};
+
+int iwm_cfg80211_inform_bss(struct iwm_priv *iwm)
+{
+       struct wiphy *wiphy = iwm_to_wiphy(iwm);
+       struct iwm_bss_info *bss, *next;
+       struct iwm_umac_notif_bss_info *umac_bss;
+       struct ieee80211_mgmt *mgmt;
+       struct ieee80211_channel *channel;
+       struct ieee80211_supported_band *band;
+       s32 signal;
+       int freq;
+
+       list_for_each_entry_safe(bss, next, &iwm->bss_list, node) {
+               umac_bss = bss->bss;
+               mgmt = (struct ieee80211_mgmt *)(umac_bss->frame_buf);
+
+               if (umac_bss->band == UMAC_BAND_2GHZ)
+                       band = wiphy->bands[IEEE80211_BAND_2GHZ];
+               else if (umac_bss->band == UMAC_BAND_5GHZ)
+                       band = wiphy->bands[IEEE80211_BAND_5GHZ];
+               else {
+                       IWM_ERR(iwm, "Invalid band: %d\n", umac_bss->band);
+                       return -EINVAL;
+               }
+
+               freq = ieee80211_channel_to_frequency(umac_bss->channel);
+               channel = ieee80211_get_channel(wiphy, freq);
+               signal = umac_bss->rssi * 100;
+
+               if (!cfg80211_inform_bss_frame(wiphy, channel, mgmt,
+                                              le16_to_cpu(umac_bss->frame_len),
+                                              signal, GFP_KERNEL))
+                       return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int iwm_cfg80211_change_iface(struct wiphy *wiphy, int ifindex,
+                                    enum nl80211_iftype type, u32 *flags,
+                                    struct vif_params *params)
+{
+       struct net_device *ndev;
+       struct wireless_dev *wdev;
+       struct iwm_priv *iwm;
+       u32 old_mode;
+
+       /* we're under RTNL */
+       ndev = __dev_get_by_index(&init_net, ifindex);
+       if (!ndev)
+               return -ENODEV;
+
+       wdev = ndev->ieee80211_ptr;
+       iwm = ndev_to_iwm(ndev);
+       old_mode = iwm->conf.mode;
+
+       switch (type) {
+       case NL80211_IFTYPE_STATION:
+               iwm->conf.mode = UMAC_MODE_BSS;
+               break;
+       case NL80211_IFTYPE_ADHOC:
+               iwm->conf.mode = UMAC_MODE_IBSS;
+               break;
+       default:
+               return -EOPNOTSUPP;
+       }
+
+       wdev->iftype = type;
+
+       if ((old_mode == iwm->conf.mode) || !iwm->umac_profile)
+               return 0;
+
+       iwm->umac_profile->mode = cpu_to_le32(iwm->conf.mode);
+
+       if (iwm->umac_profile_active) {
+               int ret = iwm_invalidate_mlme_profile(iwm);
+               if (ret < 0)
+                       IWM_ERR(iwm, "Couldn't invalidate profile\n");
+       }
+
+       return 0;
+}
+
+static int iwm_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
+                            struct cfg80211_scan_request *request)
+{
+       struct iwm_priv *iwm = ndev_to_iwm(ndev);
+       int ret;
+
+       if (!test_bit(IWM_STATUS_READY, &iwm->status)) {
+               IWM_ERR(iwm, "Scan while device is not ready\n");
+               return -EIO;
+       }
+
+       if (test_bit(IWM_STATUS_SCANNING, &iwm->status)) {
+               IWM_ERR(iwm, "Scanning already\n");
+               return -EAGAIN;
+       }
+
+       if (test_bit(IWM_STATUS_SCAN_ABORTING, &iwm->status)) {
+               IWM_ERR(iwm, "Scanning being aborted\n");
+               return -EAGAIN;
+       }
+
+       set_bit(IWM_STATUS_SCANNING, &iwm->status);
+
+       ret = iwm_scan_ssids(iwm, request->ssids, request->n_ssids);
+       if (ret) {
+               clear_bit(IWM_STATUS_SCANNING, &iwm->status);
+               return ret;
+       }
+
+       iwm->scan_request = request;
+       return 0;
+}
+
+static int iwm_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
+{
+       struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
+
+       if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
+           (iwm->conf.rts_threshold != wiphy->rts_threshold)) {
+               int ret;
+
+               iwm->conf.rts_threshold = wiphy->rts_threshold;
+
+               ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
+                                            CFG_RTS_THRESHOLD,
+                                            iwm->conf.rts_threshold);
+               if (ret < 0)
+                       return ret;
+       }
+
+       if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
+           (iwm->conf.frag_threshold != wiphy->frag_threshold)) {
+               int ret;
+
+               iwm->conf.frag_threshold = wiphy->frag_threshold;
+
+               ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_FA_CFG_FIX,
+                                            CFG_FRAG_THRESHOLD,
+                                            iwm->conf.frag_threshold);
+               if (ret < 0)
+                       return ret;
+       }
+
+       return 0;
+}
+
+static int iwm_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
+                                 struct cfg80211_ibss_params *params)
+{
+       struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
+       struct ieee80211_channel *chan = params->channel;
+       struct cfg80211_bss *bss;
+
+       if (!test_bit(IWM_STATUS_READY, &iwm->status))
+               return -EIO;
+
+       /* UMAC doesn't support creating IBSS network with specified bssid.
+        * This should be removed after we have join only mode supported. */
+       if (params->bssid)
+               return -EOPNOTSUPP;
+
+       bss = cfg80211_get_ibss(iwm_to_wiphy(iwm), NULL,
+                               params->ssid, params->ssid_len);
+       if (!bss) {
+               iwm_scan_one_ssid(iwm, params->ssid, params->ssid_len);
+               schedule_timeout_interruptible(2 * HZ);
+               bss = cfg80211_get_ibss(iwm_to_wiphy(iwm), NULL,
+                                       params->ssid, params->ssid_len);
+       }
+       /* IBSS join only mode is not supported by UMAC ATM */
+       if (bss) {
+               cfg80211_put_bss(bss);
+               return -EOPNOTSUPP;
+       }
+
+       iwm->channel = ieee80211_frequency_to_channel(chan->center_freq);
+       iwm->umac_profile->ibss.band = chan->band;
+       iwm->umac_profile->ibss.channel = iwm->channel;
+       iwm->umac_profile->ssid.ssid_len = params->ssid_len;
+       memcpy(iwm->umac_profile->ssid.ssid, params->ssid, params->ssid_len);
+
+       if (params->bssid)
+               memcpy(&iwm->umac_profile->bssid[0], params->bssid, ETH_ALEN);
+
+       return iwm_send_mlme_profile(iwm);
+}
+
+static int iwm_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
+{
+       struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
+
+       if (iwm->umac_profile_active)
+               return iwm_invalidate_mlme_profile(iwm);
+
+       return 0;
+}
+
+static struct cfg80211_ops iwm_cfg80211_ops = {
+       .change_virtual_intf = iwm_cfg80211_change_iface,
+       .scan = iwm_cfg80211_scan,
+       .set_wiphy_params = iwm_cfg80211_set_wiphy_params,
+       .join_ibss = iwm_cfg80211_join_ibss,
+       .leave_ibss = iwm_cfg80211_leave_ibss,
+};
+
+struct wireless_dev *iwm_wdev_alloc(int sizeof_bus, struct device *dev)
+{
+       int ret = 0;
+       struct wireless_dev *wdev;
+
+       /*
+        * We're trying to have the following memory
+        * layout:
+        *
+        * +-------------------------+
+        * | struct wiphy            |
+        * +-------------------------+
+        * | struct iwm_priv         |
+        * +-------------------------+
+        * | bus private data        |
+        * | (e.g. iwm_priv_sdio)    |
+        * +-------------------------+
+        *
+        */
+
+       wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
+       if (!wdev) {
+               dev_err(dev, "Couldn't allocate wireless device\n");
+               return ERR_PTR(-ENOMEM);
+       }
+
+       wdev->wiphy = wiphy_new(&iwm_cfg80211_ops,
+                               sizeof(struct iwm_priv) + sizeof_bus);
+       if (!wdev->wiphy) {
+               dev_err(dev, "Couldn't allocate wiphy device\n");
+               ret = -ENOMEM;
+               goto out_err_new;
+       }
+
+       set_wiphy_dev(wdev->wiphy, dev);
+       wdev->wiphy->max_scan_ssids = UMAC_WIFI_IF_PROBE_OPTION_MAX;
+       wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
+                                      BIT(NL80211_IFTYPE_ADHOC);
+       wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &iwm_band_2ghz;
+       wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &iwm_band_5ghz;
+       wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
+
+       ret = wiphy_register(wdev->wiphy);
+       if (ret < 0) {
+               dev_err(dev, "Couldn't register wiphy device\n");
+               goto out_err_register;
+       }
+
+       return wdev;
+
+ out_err_register:
+       wiphy_free(wdev->wiphy);
+
+ out_err_new:
+       kfree(wdev);
+
+       return ERR_PTR(ret);
+}
+
+void iwm_wdev_free(struct iwm_priv *iwm)
+{
+       struct wireless_dev *wdev = iwm_to_wdev(iwm);
+
+       if (!wdev)
+               return;
+
+       wiphy_unregister(wdev->wiphy);
+       wiphy_free(wdev->wiphy);
+       kfree(wdev);
+}
diff --git a/drivers/net/wireless/iwmc3200wifi/cfg80211.h b/drivers/net/wireless/iwmc3200wifi/cfg80211.h
new file mode 100644 (file)
index 0000000..56a3414
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Intel Wireless Multicomm 3200 WiFi driver
+ *
+ * Copyright (C) 2009 Intel Corporation <ilw@linux.intel.com>
+ * Samuel Ortiz <samuel.ortiz@intel.com>
+ * Zhu Yi <yi.zhu@intel.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., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ */
+
+#ifndef __IWM_CFG80211_H__
+#define __IWM_CFG80211_H__
+
+int iwm_cfg80211_inform_bss(struct iwm_priv *iwm);
+struct wireless_dev *iwm_wdev_alloc(int sizeof_bus, struct device *dev);
+void iwm_wdev_free(struct iwm_priv *iwm);
+
+#endif
diff --git a/drivers/net/wireless/iwmc3200wifi/commands.c b/drivers/net/wireless/iwmc3200wifi/commands.c
new file mode 100644 (file)
index 0000000..834a7f5
--- /dev/null
@@ -0,0 +1,920 @@
+/*
+ * Intel Wireless Multicomm 3200 WiFi driver
+ *
+ * Copyright (C) 2009 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in
+ *     the documentation and/or other materials provided with the
+ *     distribution.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * Intel Corporation <ilw@linux.intel.com>
+ * Samuel Ortiz <samuel.ortiz@intel.com>
+ * Zhu Yi <yi.zhu@intel.com>
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/wireless.h>
+#include <linux/etherdevice.h>
+#include <linux/ieee80211.h>
+
+#include "iwm.h"
+#include "bus.h"
+#include "hal.h"
+#include "umac.h"
+#include "commands.h"
+#include "debug.h"
+
+static int iwm_send_lmac_ptrough_cmd(struct iwm_priv *iwm,
+                                    u8 lmac_cmd_id,
+                                    const void *lmac_payload,
+                                    u16 lmac_payload_size,
+                                    u8 resp)
+{
+       struct iwm_udma_wifi_cmd udma_cmd = UDMA_LMAC_INIT;
+       struct iwm_umac_cmd umac_cmd;
+       struct iwm_lmac_cmd lmac_cmd;
+
+       lmac_cmd.id = lmac_cmd_id;
+
+       umac_cmd.id = UMAC_CMD_OPCODE_WIFI_PASS_THROUGH;
+       umac_cmd.resp = resp;
+
+       return iwm_hal_send_host_cmd(iwm, &udma_cmd, &umac_cmd, &lmac_cmd,
+                                    lmac_payload, lmac_payload_size);
+}
+
+int iwm_send_wifi_if_cmd(struct iwm_priv *iwm, void *payload, u16 payload_size,
+                        bool resp)
+{
+       struct iwm_udma_wifi_cmd udma_cmd = UDMA_UMAC_INIT;
+       struct iwm_umac_cmd umac_cmd;
+
+       umac_cmd.id = UMAC_CMD_OPCODE_WIFI_IF_WRAPPER;
+       umac_cmd.resp = resp;
+
+       return iwm_hal_send_umac_cmd(iwm, &udma_cmd, &umac_cmd,
+                                    payload, payload_size);
+}
+
+static struct coex_event iwm_sta_xor_prio_tbl[COEX_EVENTS_NUM] =
+{
+       {4, 3, 0, COEX_UNASSOC_IDLE_FLAGS},
+       {4, 3, 0, COEX_UNASSOC_MANUAL_SCAN_FLAGS},
+       {4, 3, 0, COEX_UNASSOC_AUTO_SCAN_FLAGS},
+       {4, 3, 0, COEX_CALIBRATION_FLAGS},
+       {4, 3, 0, COEX_PERIODIC_CALIBRATION_FLAGS},
+       {4, 3, 0, COEX_CONNECTION_ESTAB_FLAGS},
+       {4, 3, 0, COEX_ASSOCIATED_IDLE_FLAGS},
+       {4, 3, 0, COEX_ASSOC_MANUAL_SCAN_FLAGS},
+       {4, 3, 0, COEX_ASSOC_AUTO_SCAN_FLAGS},
+       {4, 3, 0, COEX_ASSOC_ACTIVE_LEVEL_FLAGS},
+       {6, 3, 0, COEX_XOR_RF_ON_FLAGS},
+       {4, 3, 0, COEX_RF_OFF_FLAGS},
+       {6, 6, 0, COEX_STAND_ALONE_DEBUG_FLAGS},
+       {4, 3, 0, COEX_IPAN_ASSOC_LEVEL_FLAGS},
+       {4, 3, 0, COEX_RSRVD1_FLAGS},
+       {4, 3, 0, COEX_RSRVD2_FLAGS}
+};
+
+static struct coex_event iwm_sta_cm_prio_tbl[COEX_EVENTS_NUM] =
+{
+       {1, 1, 0, COEX_UNASSOC_IDLE_FLAGS},
+       {4, 3, 0, COEX_UNASSOC_MANUAL_SCAN_FLAGS},
+       {3, 3, 0, COEX_UNASSOC_AUTO_SCAN_FLAGS},
+       {5, 5, 0, COEX_CALIBRATION_FLAGS},
+       {4, 4, 0, COEX_PERIODIC_CALIBRATION_FLAGS},
+       {5, 4, 0, COEX_CONNECTION_ESTAB_FLAGS},
+       {4, 4, 0, COEX_ASSOCIATED_IDLE_FLAGS},
+       {4, 4, 0, COEX_ASSOC_MANUAL_SCAN_FLAGS},
+       {4, 4, 0, COEX_ASSOC_AUTO_SCAN_FLAGS},
+       {4, 4, 0, COEX_ASSOC_ACTIVE_LEVEL_FLAGS},
+       {1, 1, 0, COEX_RF_ON_FLAGS},
+       {1, 1, 0, COEX_RF_OFF_FLAGS},
+       {6, 6, 0, COEX_STAND_ALONE_DEBUG_FLAGS},
+       {5, 4, 0, COEX_IPAN_ASSOC_LEVEL_FLAGS},
+       {1, 1, 0, COEX_RSRVD1_FLAGS},
+       {1, 1, 0, COEX_RSRVD2_FLAGS}
+};
+
+int iwm_send_prio_table(struct iwm_priv *iwm)
+{
+       struct iwm_coex_prio_table_cmd coex_table_cmd;
+       u32 coex_enabled, mode_enabled;
+
+       memset(&coex_table_cmd, 0, sizeof(struct iwm_coex_prio_table_cmd));
+
+       coex_table_cmd.flags = COEX_FLAGS_STA_TABLE_VALID_MSK;
+
+       switch (iwm->conf.coexist_mode) {
+       case COEX_MODE_XOR:
+       case COEX_MODE_CM:
+               coex_enabled = 1;
+               break;
+       default:
+               coex_enabled = 0;
+               break;
+       }
+
+       switch (iwm->conf.mode) {
+       case UMAC_MODE_BSS:
+       case UMAC_MODE_IBSS:
+               mode_enabled = 1;
+               break;
+       default:
+               mode_enabled = 0;
+               break;
+       }
+
+       if (coex_enabled && mode_enabled) {
+               coex_table_cmd.flags |= COEX_FLAGS_COEX_ENABLE_MSK |
+                                       COEX_FLAGS_ASSOC_WAKEUP_UMASK_MSK |
+                                       COEX_FLAGS_UNASSOC_WAKEUP_UMASK_MSK;
+
+               switch (iwm->conf.coexist_mode) {
+               case COEX_MODE_XOR:
+                       memcpy(coex_table_cmd.sta_prio, iwm_sta_xor_prio_tbl,
+                              sizeof(iwm_sta_xor_prio_tbl));
+                       break;
+               case COEX_MODE_CM:
+                       memcpy(coex_table_cmd.sta_prio, iwm_sta_cm_prio_tbl,
+                              sizeof(iwm_sta_cm_prio_tbl));
+                       break;
+               default:
+                       IWM_ERR(iwm, "Invalid coex_mode 0x%x\n",
+                               iwm->conf.coexist_mode);
+                       break;
+               }
+       } else
+               IWM_WARN(iwm, "coexistense disabled\n");
+
+       return iwm_send_lmac_ptrough_cmd(iwm, COEX_PRIORITY_TABLE_CMD,
+                               &coex_table_cmd,
+                               sizeof(struct iwm_coex_prio_table_cmd), 1);
+}
+
+int iwm_send_init_calib_cfg(struct iwm_priv *iwm, u8 calib_requested)
+{
+       struct iwm_lmac_cal_cfg_cmd cal_cfg_cmd;
+
+       memset(&cal_cfg_cmd, 0, sizeof(struct iwm_lmac_cal_cfg_cmd));
+
+       cal_cfg_cmd.ucode_cfg.init.enable = cpu_to_le32(calib_requested);
+       cal_cfg_cmd.ucode_cfg.init.start = cpu_to_le32(calib_requested);
+       cal_cfg_cmd.ucode_cfg.init.send_res = cpu_to_le32(calib_requested);
+       cal_cfg_cmd.ucode_cfg.flags =
+               cpu_to_le32(CALIB_CFG_FLAG_SEND_COMPLETE_NTFY_AFTER_MSK);
+
+       return iwm_send_lmac_ptrough_cmd(iwm, CALIBRATION_CFG_CMD, &cal_cfg_cmd,
+                               sizeof(struct iwm_lmac_cal_cfg_cmd), 1);
+}
+
+int iwm_send_periodic_calib_cfg(struct iwm_priv *iwm, u8 calib_requested)
+{
+       struct iwm_lmac_cal_cfg_cmd cal_cfg_cmd;
+
+       memset(&cal_cfg_cmd, 0, sizeof(struct iwm_lmac_cal_cfg_cmd));
+
+       cal_cfg_cmd.ucode_cfg.periodic.enable = cpu_to_le32(calib_requested);
+       cal_cfg_cmd.ucode_cfg.periodic.start = cpu_to_le32(calib_requested);
+
+       return iwm_send_lmac_ptrough_cmd(iwm, CALIBRATION_CFG_CMD, &cal_cfg_cmd,
+                               sizeof(struct iwm_lmac_cal_cfg_cmd), 0);
+}
+
+int iwm_store_rxiq_calib_result(struct iwm_priv *iwm)
+{
+       struct iwm_calib_rxiq *rxiq;
+       u8 *eeprom_rxiq = iwm_eeprom_access(iwm, IWM_EEPROM_CALIB_RXIQ);
+       int grplen = sizeof(struct iwm_calib_rxiq_group);
+
+       rxiq = kzalloc(sizeof(struct iwm_calib_rxiq), GFP_KERNEL);
+       if (!rxiq) {
+               IWM_ERR(iwm, "Couldn't alloc memory for RX IQ\n");
+               return -ENOMEM;
+       }
+
+       eeprom_rxiq = iwm_eeprom_access(iwm, IWM_EEPROM_CALIB_RXIQ);
+       if (IS_ERR(eeprom_rxiq)) {
+               IWM_ERR(iwm, "Couldn't access EEPROM RX IQ entry\n");
+               return PTR_ERR(eeprom_rxiq);
+       }
+
+       iwm->calib_res[SHILOH_PHY_CALIBRATE_RX_IQ_CMD].buf = (u8 *)rxiq;
+       iwm->calib_res[SHILOH_PHY_CALIBRATE_RX_IQ_CMD].size = sizeof(*rxiq);
+
+       rxiq->hdr.opcode = SHILOH_PHY_CALIBRATE_RX_IQ_CMD;
+       rxiq->hdr.first_grp = 0;
+       rxiq->hdr.grp_num = 1;
+       rxiq->hdr.all_data_valid = 1;
+
+       memcpy(&rxiq->group[0], eeprom_rxiq, 4 * grplen);
+       memcpy(&rxiq->group[4], eeprom_rxiq + 6 * grplen, grplen);
+
+       return 0;
+}
+
+int iwm_send_calib_results(struct iwm_priv *iwm)
+{
+       int i, ret = 0;
+
+       for (i = PHY_CALIBRATE_OPCODES_NUM; i < CALIBRATION_CMD_NUM; i++) {
+               if (test_bit(i - PHY_CALIBRATE_OPCODES_NUM,
+                            &iwm->calib_done_map)) {
+                       IWM_DBG_CMD(iwm, DBG,
+                                   "Send calibration %d result\n", i);
+                       ret |= iwm_send_lmac_ptrough_cmd(iwm,
+                                       REPLY_PHY_CALIBRATION_CMD,
+                                       iwm->calib_res[i].buf,
+                                       iwm->calib_res[i].size, 0);
+
+                       kfree(iwm->calib_res[i].buf);
+                       iwm->calib_res[i].buf = NULL;
+                       iwm->calib_res[i].size = 0;
+               }
+       }
+
+       return ret;
+}
+
+int iwm_send_umac_reset(struct iwm_priv *iwm, __le32 reset_flags, bool resp)
+{
+       struct iwm_udma_wifi_cmd udma_cmd = UDMA_UMAC_INIT;
+       struct iwm_umac_cmd umac_cmd;
+       struct iwm_umac_cmd_reset reset;
+
+       reset.flags = reset_flags;
+
+       umac_cmd.id = UMAC_CMD_OPCODE_RESET;
+       umac_cmd.resp = resp;
+
+       return iwm_hal_send_umac_cmd(iwm, &udma_cmd, &umac_cmd, &reset,
+                                    sizeof(struct iwm_umac_cmd_reset));
+}
+
+int iwm_umac_set_config_fix(struct iwm_priv *iwm, u16 tbl, u16 key, u32 value)
+{
+       struct iwm_udma_wifi_cmd udma_cmd = UDMA_UMAC_INIT;
+       struct iwm_umac_cmd umac_cmd;
+       struct iwm_umac_cmd_set_param_fix param;
+
+       if ((tbl != UMAC_PARAM_TBL_CFG_FIX) &&
+           (tbl != UMAC_PARAM_TBL_FA_CFG_FIX))
+               return -EINVAL;
+
+       umac_cmd.id = UMAC_CMD_OPCODE_SET_PARAM_FIX;
+       umac_cmd.resp = 0;
+
+       param.tbl = cpu_to_le16(tbl);
+       param.key = cpu_to_le16(key);
+       param.value = cpu_to_le32(value);
+
+       return iwm_hal_send_umac_cmd(iwm, &udma_cmd, &umac_cmd, &param,
+                                    sizeof(struct iwm_umac_cmd_set_param_fix));
+}
+
+int iwm_umac_set_config_var(struct iwm_priv *iwm, u16 key,
+                           void *payload, u16 payload_size)
+{
+       struct iwm_udma_wifi_cmd udma_cmd = UDMA_UMAC_INIT;
+       struct iwm_umac_cmd umac_cmd;
+       struct iwm_umac_cmd_set_param_var *param_hdr;
+       u8 *param;
+       int ret;
+
+       param = kzalloc(payload_size +
+                       sizeof(struct iwm_umac_cmd_set_param_var), GFP_KERNEL);
+       if (!param) {
+               IWM_ERR(iwm, "Couldn't allocate param\n");
+               return -ENOMEM;
+       }
+
+       param_hdr = (struct iwm_umac_cmd_set_param_var *)param;
+
+       umac_cmd.id = UMAC_CMD_OPCODE_SET_PARAM_VAR;
+       umac_cmd.resp = 0;
+
+       param_hdr->tbl = cpu_to_le16(UMAC_PARAM_TBL_CFG_VAR);
+       param_hdr->key = cpu_to_le16(key);
+       param_hdr->len = cpu_to_le16(payload_size);
+       memcpy(param + sizeof(struct iwm_umac_cmd_set_param_var),
+              payload, payload_size);
+
+       ret = iwm_hal_send_umac_cmd(iwm, &udma_cmd, &umac_cmd, param,
+                                   sizeof(struct iwm_umac_cmd_set_param_var) +
+                                   payload_size);
+       kfree(param);
+
+       return ret;
+}
+
+int iwm_send_umac_config(struct iwm_priv *iwm,
+                        __le32 reset_flags)
+{
+       int ret;
+
+       /* Use UMAC default values */
+       ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
+                                     CFG_POWER_INDEX, iwm->conf.power_index);
+       if (ret < 0)
+               return ret;
+
+       ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_FA_CFG_FIX,
+                                     CFG_FRAG_THRESHOLD,
+                                     iwm->conf.frag_threshold);
+       if (ret < 0)
+               return ret;
+
+       ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
+                                     CFG_RTS_THRESHOLD,
+                                     iwm->conf.rts_threshold);
+       if (ret < 0)
+               return ret;
+
+       ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
+                                     CFG_CTS_TO_SELF, iwm->conf.cts_to_self);
+       if (ret < 0)
+               return ret;
+
+       ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
+                                     CFG_COEX_MODE, iwm->conf.coexist_mode);
+       if (ret < 0)
+               return ret;
+
+       /*
+       ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
+                                     CFG_ASSOCIATION_TIMEOUT,
+                                     iwm->conf.assoc_timeout);
+       if (ret < 0)
+               return ret;
+
+       ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
+                                     CFG_ROAM_TIMEOUT,
+                                     iwm->conf.roam_timeout);
+       if (ret < 0)
+               return ret;
+
+       ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
+                                     CFG_WIRELESS_MODE,
+                                     WIRELESS_MODE_11A | WIRELESS_MODE_11G);
+       if (ret < 0)
+               return ret;
+       */
+
+       ret = iwm_umac_set_config_var(iwm, CFG_NET_ADDR,
+                                     iwm_to_ndev(iwm)->dev_addr, ETH_ALEN);
+       if (ret < 0)
+               return ret;
+
+       /* UMAC PM static configurations */
+       ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
+                                     CFG_PM_LEGACY_RX_TIMEOUT, 0x12C);
+       if (ret < 0)
+               return ret;
+
+       ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
+                                     CFG_PM_LEGACY_TX_TIMEOUT, 0x15E);
+       if (ret < 0)
+               return ret;
+
+       ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
+                                     CFG_PM_CTRL_FLAGS, 0x30001);
+       if (ret < 0)
+               return ret;
+
+       ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
+                                     CFG_PM_KEEP_ALIVE_IN_BEACONS, 0x80);
+       if (ret < 0)
+               return ret;
+
+       /* reset UMAC */
+       ret = iwm_send_umac_reset(iwm, reset_flags, 1);
+       if (ret < 0)
+               return ret;
+
+       ret = iwm_notif_handle(iwm, UMAC_CMD_OPCODE_RESET, IWM_SRC_UMAC,
+                              WAIT_NOTIF_TIMEOUT);
+       if (ret) {
+               IWM_ERR(iwm, "Wait for UMAC RESET timeout\n");
+               return ret;
+       }
+
+       return ret;
+}
+
+int iwm_send_packet(struct iwm_priv *iwm, struct sk_buff *skb, int pool_id)
+{
+       struct iwm_udma_wifi_cmd udma_cmd;
+       struct iwm_umac_cmd umac_cmd;
+       struct iwm_tx_info *tx_info = skb_to_tx_info(skb);
+
+       udma_cmd.eop = 1; /* always set eop for non-concatenated Tx */
+       udma_cmd.credit_group = pool_id;
+       udma_cmd.ra_tid = tx_info->sta << 4 | tx_info->tid;
+       udma_cmd.lmac_offset = 0;
+
+       umac_cmd.id = REPLY_TX;
+       umac_cmd.color = tx_info->color;
+       umac_cmd.resp = 0;
+
+       return iwm_hal_send_umac_cmd(iwm, &udma_cmd, &umac_cmd,
+                                    skb->data, skb->len);
+}
+
+static int iwm_target_read(struct iwm_priv *iwm, __le32 address,
+                          u8 *response, u32 resp_size)
+{
+       struct iwm_udma_nonwifi_cmd target_cmd;
+       struct iwm_nonwifi_cmd *cmd;
+       u16 seq_num;
+       int ret = 0;
+
+       target_cmd.opcode = UMAC_HDI_OUT_OPCODE_READ;
+       target_cmd.addr = address;
+       target_cmd.op1_sz = cpu_to_le32(resp_size);
+       target_cmd.op2 = 0;
+       target_cmd.handle_by_hw = 0;
+       target_cmd.resp = 1;
+       target_cmd.eop = 1;
+
+       ret = iwm_hal_send_target_cmd(iwm, &target_cmd, NULL);
+       if (ret < 0)
+               IWM_ERR(iwm, "Couldn't send READ command\n");
+
+       /* When succeding, the send_target routine returns the seq number */
+       seq_num = ret;
+
+       ret = wait_event_interruptible_timeout(iwm->nonwifi_queue,
+               (cmd = iwm_get_pending_nonwifi_cmd(iwm, seq_num,
+                                         UMAC_HDI_OUT_OPCODE_READ)) != NULL,
+                                              2 * HZ);
+
+       if (!ret) {
+               IWM_ERR(iwm, "Didn't receive a target READ answer\n");
+               return ret;
+       }
+
+       memcpy(response, cmd->buf.hdr + sizeof(struct iwm_udma_in_hdr),
+              resp_size);
+
+       kfree(cmd);
+
+       return ret;
+}
+
+int iwm_read_mac(struct iwm_priv *iwm, u8 *mac)
+{
+       int ret;
+       u8 mac_align[ALIGN(ETH_ALEN, 8)];
+
+       ret = iwm_target_read(iwm, cpu_to_le32(WICO_MAC_ADDRESS_ADDR),
+                             mac_align, sizeof(mac_align));
+       if (ret < 0)
+               return ret;
+
+       if (is_valid_ether_addr(mac_align))
+               memcpy(mac, mac_align, ETH_ALEN);
+       else {
+               IWM_ERR(iwm, "Invalid EEPROM MAC\n");
+               memcpy(mac, iwm->conf.mac_addr, ETH_ALEN);
+               get_random_bytes(&mac[3], 3);
+       }
+
+       return 0;
+}
+
+int iwm_set_tx_key(struct iwm_priv *iwm, u8 key_idx)
+{
+       struct iwm_umac_tx_key_id tx_key_id;
+
+       if (!iwm->default_key || !iwm->default_key->in_use)
+               return -EINVAL;
+
+       tx_key_id.hdr.oid = UMAC_WIFI_IF_CMD_GLOBAL_TX_KEY_ID;
+       tx_key_id.hdr.buf_size = cpu_to_le16(sizeof(struct iwm_umac_tx_key_id) -
+                                            sizeof(struct iwm_umac_wifi_if));
+
+       tx_key_id.key_idx = key_idx;
+
+       return iwm_send_wifi_if_cmd(iwm, &tx_key_id, sizeof(tx_key_id), 1);
+}
+
+static int iwm_check_profile(struct iwm_priv *iwm)
+{
+       if (!iwm->umac_profile_active)
+               return -EAGAIN;
+
+       if (iwm->umac_profile->sec.ucast_cipher != UMAC_CIPHER_TYPE_WEP_40 &&
+           iwm->umac_profile->sec.ucast_cipher != UMAC_CIPHER_TYPE_WEP_104 &&
+           iwm->umac_profile->sec.ucast_cipher != UMAC_CIPHER_TYPE_TKIP &&
+           iwm->umac_profile->sec.ucast_cipher != UMAC_CIPHER_TYPE_CCMP) {
+               IWM_ERR(iwm, "Wrong unicast cipher: 0x%x\n",
+                       iwm->umac_profile->sec.ucast_cipher);
+               return -EAGAIN;
+       }
+
+       if (iwm->umac_profile->sec.mcast_cipher != UMAC_CIPHER_TYPE_WEP_40 &&
+           iwm->umac_profile->sec.mcast_cipher != UMAC_CIPHER_TYPE_WEP_104 &&
+           iwm->umac_profile->sec.mcast_cipher != UMAC_CIPHER_TYPE_TKIP &&
+           iwm->umac_profile->sec.mcast_cipher != UMAC_CIPHER_TYPE_CCMP) {
+               IWM_ERR(iwm, "Wrong multicast cipher: 0x%x\n",
+                       iwm->umac_profile->sec.mcast_cipher);
+               return -EAGAIN;
+       }
+
+       if ((iwm->umac_profile->sec.ucast_cipher == UMAC_CIPHER_TYPE_WEP_40 ||
+            iwm->umac_profile->sec.ucast_cipher == UMAC_CIPHER_TYPE_WEP_104) &&
+           (iwm->umac_profile->sec.ucast_cipher !=
+            iwm->umac_profile->sec.mcast_cipher)) {
+               IWM_ERR(iwm, "Unicast and multicast ciphers differ for WEP\n");
+       }
+
+       return 0;
+}
+
+int iwm_set_key(struct iwm_priv *iwm, bool remove, bool set_tx_key,
+               struct iwm_key *key)
+{
+       int ret;
+       u8 cmd[64], *sta_addr, *key_data, key_len;
+       s8 key_idx;
+       u16 cmd_size = 0;
+       struct iwm_umac_key_hdr *key_hdr = &key->hdr;
+       struct iwm_umac_key_wep40 *wep40 = (struct iwm_umac_key_wep40 *)cmd;
+       struct iwm_umac_key_wep104 *wep104 = (struct iwm_umac_key_wep104 *)cmd;
+       struct iwm_umac_key_tkip *tkip = (struct iwm_umac_key_tkip *)cmd;
+       struct iwm_umac_key_ccmp *ccmp = (struct iwm_umac_key_ccmp *)cmd;
+
+       if (set_tx_key)
+               iwm->default_key = key;
+
+       /*
+        * We check if our current profile is valid.
+        * If not, we dont push the key, we just cache them,
+        * so that with the next siwsessid call, the keys
+        * will be actually pushed.
+        */
+       if (!remove) {
+               ret = iwm_check_profile(iwm);
+               if (ret < 0)
+                       return ret;
+       }
+
+       sta_addr = key->hdr.mac;
+       key_data = key->key;
+       key_len = key->key_len;
+       key_idx = key->hdr.key_idx;
+
+       if (!remove) {
+               IWM_DBG_WEXT(iwm, DBG, "key_idx:%d set tx key:%d\n",
+                            key_idx, set_tx_key);
+               IWM_DBG_WEXT(iwm, DBG, "key_len:%d\n", key_len);
+               IWM_DBG_WEXT(iwm, DBG, "MAC:%pM, idx:%d, multicast:%d\n",
+                      key_hdr->mac, key_hdr->key_idx, key_hdr->multicast);
+
+               IWM_DBG_WEXT(iwm, DBG, "profile: mcast:0x%x, ucast:0x%x\n",
+                            iwm->umac_profile->sec.mcast_cipher,
+                            iwm->umac_profile->sec.ucast_cipher);
+               IWM_DBG_WEXT(iwm, DBG, "profile: auth_type:0x%x, flags:0x%x\n",
+                            iwm->umac_profile->sec.auth_type,
+                            iwm->umac_profile->sec.flags);
+
+               switch (key->alg) {
+               case UMAC_CIPHER_TYPE_WEP_40:
+                       wep40->hdr.oid = UMAC_WIFI_IF_CMD_ADD_WEP40_KEY;
+                       wep40->hdr.buf_size =
+                               cpu_to_le16(sizeof(struct iwm_umac_key_wep40) -
+                                           sizeof(struct iwm_umac_wifi_if));
+
+                       memcpy(&wep40->key_hdr, key_hdr,
+                              sizeof(struct iwm_umac_key_hdr));
+                       memcpy(wep40->key, key_data, key_len);
+                       wep40->static_key = 1;
+
+                       cmd_size = sizeof(struct iwm_umac_key_wep40);
+                       break;
+
+               case UMAC_CIPHER_TYPE_WEP_104:
+                       wep104->hdr.oid = UMAC_WIFI_IF_CMD_ADD_WEP104_KEY;
+                       wep104->hdr.buf_size =
+                               cpu_to_le16(sizeof(struct iwm_umac_key_wep104) -
+                                           sizeof(struct iwm_umac_wifi_if));
+
+                       memcpy(&wep104->key_hdr, key_hdr,
+                              sizeof(struct iwm_umac_key_hdr));
+                       memcpy(wep104->key, key_data, key_len);
+                       wep104->static_key = 1;
+
+                       cmd_size = sizeof(struct iwm_umac_key_wep104);
+                       break;
+
+               case UMAC_CIPHER_TYPE_CCMP:
+                       key_hdr->key_idx++;
+                       ccmp->hdr.oid = UMAC_WIFI_IF_CMD_ADD_CCMP_KEY;
+                       ccmp->hdr.buf_size =
+                               cpu_to_le16(sizeof(struct iwm_umac_key_ccmp) -
+                                           sizeof(struct iwm_umac_wifi_if));
+
+                       memcpy(&ccmp->key_hdr, key_hdr,
+                              sizeof(struct iwm_umac_key_hdr));
+
+                       memcpy(ccmp->key, key_data, key_len);
+
+                       if (key->flags & IW_ENCODE_EXT_RX_SEQ_VALID)
+                               memcpy(ccmp->iv_count, key->rx_seq, 6);
+
+                       cmd_size = sizeof(struct iwm_umac_key_ccmp);
+                       break;
+
+               case UMAC_CIPHER_TYPE_TKIP:
+                       key_hdr->key_idx++;
+                       tkip->hdr.oid = UMAC_WIFI_IF_CMD_ADD_TKIP_KEY;
+                       tkip->hdr.buf_size =
+                               cpu_to_le16(sizeof(struct iwm_umac_key_tkip) -
+                                           sizeof(struct iwm_umac_wifi_if));
+
+                       memcpy(&tkip->key_hdr, key_hdr,
+                              sizeof(struct iwm_umac_key_hdr));
+
+                       memcpy(tkip->tkip_key, key_data, IWM_TKIP_KEY_SIZE);
+                       memcpy(tkip->mic_tx_key, key_data + IWM_TKIP_KEY_SIZE,
+                              IWM_TKIP_MIC_SIZE);
+                       memcpy(tkip->mic_rx_key,
+                              key_data + IWM_TKIP_KEY_SIZE + IWM_TKIP_MIC_SIZE,
+                              IWM_TKIP_MIC_SIZE);
+
+                       if (key->flags & IW_ENCODE_EXT_RX_SEQ_VALID)
+                               memcpy(ccmp->iv_count, key->rx_seq, 6);
+
+                       cmd_size = sizeof(struct iwm_umac_key_tkip);
+                       break;
+
+               default:
+                       return -ENOTSUPP;
+               }
+
+               if ((key->alg == UMAC_CIPHER_TYPE_CCMP) ||
+                   (key->alg == UMAC_CIPHER_TYPE_TKIP))
+                       /*
+                        * UGLY_UGLY_UGLY
+                        * Copied HACK from the MWG driver.
+                        * Without it, the key is set before the second
+                        * EAPOL frame is sent, and the latter is thus
+                        * encrypted.
+                        */
+                       schedule_timeout_interruptible(usecs_to_jiffies(300));
+
+               ret =  iwm_send_wifi_if_cmd(iwm, cmd, cmd_size, 1);
+               if (ret < 0)
+                       goto err;
+
+               /*
+                * We need a default key only if it is set and
+                * if we're doing WEP.
+                */
+               if (iwm->default_key == key &&
+                       ((key->alg == UMAC_CIPHER_TYPE_WEP_40) ||
+                        (key->alg == UMAC_CIPHER_TYPE_WEP_104))) {
+                       ret = iwm_set_tx_key(iwm, key_idx);
+                       if (ret < 0)
+                               goto err;
+               }
+       } else {
+               struct iwm_umac_key_remove key_remove;
+
+               key_remove.hdr.oid = UMAC_WIFI_IF_CMD_REMOVE_KEY;
+               key_remove.hdr.buf_size =
+                       cpu_to_le16(sizeof(struct iwm_umac_key_remove) -
+                                   sizeof(struct iwm_umac_wifi_if));
+               memcpy(&key_remove.key_hdr, key_hdr,
+                      sizeof(struct iwm_umac_key_hdr));
+
+               ret =  iwm_send_wifi_if_cmd(iwm, &key_remove,
+                                           sizeof(struct iwm_umac_key_remove),
+                                           1);
+               if (ret < 0)
+                       return ret;
+
+               iwm->keys[key_idx].in_use = 0;
+       }
+
+       return 0;
+
+ err:
+       kfree(key);
+       return ret;
+}
+
+
+int iwm_send_mlme_profile(struct iwm_priv *iwm)
+{
+       int ret, i;
+       struct iwm_umac_profile profile;
+
+       memcpy(&profile, iwm->umac_profile, sizeof(profile));
+
+       profile.hdr.oid = UMAC_WIFI_IF_CMD_SET_PROFILE;
+       profile.hdr.buf_size = cpu_to_le16(sizeof(struct iwm_umac_profile) -
+                                          sizeof(struct iwm_umac_wifi_if));
+
+       ret = iwm_send_wifi_if_cmd(iwm, &profile, sizeof(profile), 1);
+       if (ret < 0) {
+               IWM_ERR(iwm, "Send profile command failed\n");
+               return ret;
+       }
+
+       /* Wait for the profile to be active */
+       ret = wait_event_interruptible_timeout(iwm->mlme_queue,
+                                              iwm->umac_profile_active == 1,
+                                              3 * HZ);
+       if (!ret)
+               return -EBUSY;
+
+
+       for (i = 0; i < IWM_NUM_KEYS; i++)
+               if (iwm->keys[i].in_use) {
+                       int default_key = 0;
+                       struct iwm_key *key = &iwm->keys[i];
+
+                       if (key == iwm->default_key)
+                               default_key = 1;
+
+                       /* Wait for the profile before sending the keys */
+                       wait_event_interruptible_timeout(iwm->mlme_queue,
+                            (test_bit(IWM_STATUS_ASSOCIATING, &iwm->status) ||
+                             test_bit(IWM_STATUS_ASSOCIATED, &iwm->status)),
+                                                        3 * HZ);
+
+                       ret = iwm_set_key(iwm, 0, default_key, key);
+                       if (ret < 0)
+                               return ret;
+               }
+
+       return 0;
+}
+
+int iwm_invalidate_mlme_profile(struct iwm_priv *iwm)
+{
+       int ret;
+       struct iwm_umac_invalidate_profile invalid;
+
+       invalid.hdr.oid = UMAC_WIFI_IF_CMD_INVALIDATE_PROFILE;
+       invalid.hdr.buf_size =
+               cpu_to_le16(sizeof(struct iwm_umac_invalidate_profile) -
+                           sizeof(struct iwm_umac_wifi_if));
+
+       invalid.reason = WLAN_REASON_UNSPECIFIED;
+
+       ret = iwm_send_wifi_if_cmd(iwm, &invalid, sizeof(invalid), 1);
+       if (ret < 0)
+               return ret;
+
+       ret = wait_event_interruptible_timeout(iwm->mlme_queue,
+                                (iwm->umac_profile_active == 0),
+                                              2 * HZ);
+       if (!ret)
+               return -EBUSY;
+
+       return 0;
+}
+
+int iwm_send_umac_stats_req(struct iwm_priv *iwm, u32 flags)
+{
+       struct iwm_udma_wifi_cmd udma_cmd = UDMA_UMAC_INIT;
+       struct iwm_umac_cmd umac_cmd;
+       struct iwm_umac_cmd_stats_req stats_req;
+
+       stats_req.flags = cpu_to_le32(flags);
+
+       umac_cmd.id = UMAC_CMD_OPCODE_STATISTIC_REQUEST;
+       umac_cmd.resp = 0;
+
+       return iwm_hal_send_umac_cmd(iwm, &udma_cmd, &umac_cmd, &stats_req,
+                                    sizeof(struct iwm_umac_cmd_stats_req));
+}
+
+int iwm_send_umac_channel_list(struct iwm_priv *iwm)
+{
+       struct iwm_udma_wifi_cmd udma_cmd = UDMA_UMAC_INIT;
+       struct iwm_umac_cmd umac_cmd;
+       struct iwm_umac_cmd_get_channel_list *ch_list;
+       int size = sizeof(struct iwm_umac_cmd_get_channel_list) +
+                  sizeof(struct iwm_umac_channel_info) * 4;
+       int ret;
+
+       ch_list = kzalloc(size, GFP_KERNEL);
+       if (!ch_list) {
+               IWM_ERR(iwm, "Couldn't allocate channel list cmd\n");
+               return -ENOMEM;
+       }
+
+       ch_list->ch[0].band = UMAC_BAND_2GHZ;
+       ch_list->ch[0].type = UMAC_CHANNEL_WIDTH_20MHZ;
+       ch_list->ch[0].flags = UMAC_CHANNEL_FLAG_VALID;
+
+       ch_list->ch[1].band = UMAC_BAND_5GHZ;
+       ch_list->ch[1].type = UMAC_CHANNEL_WIDTH_20MHZ;
+       ch_list->ch[1].flags = UMAC_CHANNEL_FLAG_VALID;
+
+       ch_list->ch[2].band = UMAC_BAND_2GHZ;
+       ch_list->ch[2].type = UMAC_CHANNEL_WIDTH_20MHZ;
+       ch_list->ch[2].flags = UMAC_CHANNEL_FLAG_VALID | UMAC_CHANNEL_FLAG_IBSS;
+
+       ch_list->ch[3].band = UMAC_BAND_5GHZ;
+       ch_list->ch[3].type = UMAC_CHANNEL_WIDTH_20MHZ;
+       ch_list->ch[3].flags = UMAC_CHANNEL_FLAG_VALID | UMAC_CHANNEL_FLAG_IBSS;
+
+       ch_list->count = cpu_to_le16(4);
+
+       umac_cmd.id = UMAC_CMD_OPCODE_GET_CHAN_INFO_LIST;
+       umac_cmd.resp = 1;
+
+       ret = iwm_hal_send_umac_cmd(iwm, &udma_cmd, &umac_cmd, ch_list, size);
+
+       kfree(ch_list);
+
+       return ret;
+}
+
+int iwm_scan_ssids(struct iwm_priv *iwm, struct cfg80211_ssid *ssids,
+                  int ssid_num)
+{
+       struct iwm_umac_cmd_scan_request req;
+       int i, ret;
+
+       memset(&req, 0, sizeof(struct iwm_umac_cmd_scan_request));
+
+       req.hdr.oid = UMAC_WIFI_IF_CMD_SCAN_REQUEST;
+       req.hdr.buf_size = cpu_to_le16(sizeof(struct iwm_umac_cmd_scan_request)
+                                      - sizeof(struct iwm_umac_wifi_if));
+       req.type = UMAC_WIFI_IF_SCAN_TYPE_USER;
+       req.timeout = 2;
+       req.seq_num = iwm->scan_id;
+       req.ssid_num = min(ssid_num, UMAC_WIFI_IF_PROBE_OPTION_MAX);
+
+       for (i = 0; i < req.ssid_num; i++) {
+               memcpy(req.ssids[i].ssid, ssids[i].ssid, ssids[i].ssid_len);
+               req.ssids[i].ssid_len = ssids[i].ssid_len;
+       }
+
+       ret = iwm_send_wifi_if_cmd(iwm, &req, sizeof(req), 0);
+       if (ret < 0) {
+               IWM_ERR(iwm, "Couldn't send scan request\n");
+               return ret;
+       }
+
+       iwm->scan_id = iwm->scan_id++ % IWM_SCAN_ID_MAX;
+
+       return 0;
+}
+
+int iwm_scan_one_ssid(struct iwm_priv *iwm, u8 *ssid, int ssid_len)
+{
+       struct cfg80211_ssid one_ssid;
+
+       if (test_and_set_bit(IWM_STATUS_SCANNING, &iwm->status))
+               return 0;
+
+       one_ssid.ssid_len = min(ssid_len, IEEE80211_MAX_SSID_LEN);
+       memcpy(&one_ssid.ssid, ssid, one_ssid.ssid_len);
+
+       return iwm_scan_ssids(iwm, &one_ssid, 1);
+}
+
+int iwm_target_reset(struct iwm_priv *iwm)
+{
+       struct iwm_udma_nonwifi_cmd target_cmd;
+
+       target_cmd.opcode = UMAC_HDI_OUT_OPCODE_REBOOT;
+       target_cmd.addr = 0;
+       target_cmd.op1_sz = 0;
+       target_cmd.op2 = 0;
+       target_cmd.handle_by_hw = 0;
+       target_cmd.resp = 0;
+       target_cmd.eop = 1;
+
+       return iwm_hal_send_target_cmd(iwm, &target_cmd, NULL);
+}
diff --git a/drivers/net/wireless/iwmc3200wifi/commands.h b/drivers/net/wireless/iwmc3200wifi/commands.h
new file mode 100644 (file)
index 0000000..36b13a1
--- /dev/null
@@ -0,0 +1,419 @@
+/*
+ * Intel Wireless Multicomm 3200 WiFi driver
+ *
+ * Copyright (C) 2009 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in
+ *     the documentation and/or other materials provided with the
+ *     distribution.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * Intel Corporation <ilw@linux.intel.com>
+ * Samuel Ortiz <samuel.ortiz@intel.com>
+ * Zhu Yi <yi.zhu@intel.com>
+ *
+ */
+
+#ifndef __IWM_COMMANDS_H__
+#define __IWM_COMMANDS_H__
+
+#include <linux/ieee80211.h>
+
+#define IWM_BARKER_REBOOT_NOTIFICATION 0xF
+#define IWM_ACK_BARKER_NOTIFICATION    0x10
+
+/* UMAC commands */
+#define UMAC_RST_CTRL_FLG_LARC_CLK_EN  0x0001
+#define UMAC_RST_CTRL_FLG_LARC_RESET   0x0002
+#define UMAC_RST_CTRL_FLG_FUNC_RESET   0x0004
+#define UMAC_RST_CTRL_FLG_DEV_RESET    0x0008
+#define UMAC_RST_CTRL_FLG_WIFI_CORE_EN 0x0010
+#define UMAC_RST_CTRL_FLG_WIFI_LINK_EN 0x0040
+#define UMAC_RST_CTRL_FLG_WIFI_MLME_EN 0x0080
+#define UMAC_RST_CTRL_FLG_NVM_RELOAD   0x0100
+
+struct iwm_umac_cmd_reset {
+       __le32 flags;
+} __attribute__ ((packed));
+
+#define UMAC_PARAM_TBL_ORD_FIX    0x0
+#define UMAC_PARAM_TBL_ORD_VAR    0x1
+#define UMAC_PARAM_TBL_CFG_FIX    0x2
+#define UMAC_PARAM_TBL_CFG_VAR    0x3
+#define UMAC_PARAM_TBL_BSS_TRK    0x4
+#define UMAC_PARAM_TBL_FA_CFG_FIX 0x5
+#define UMAC_PARAM_TBL_STA        0x6
+#define UMAC_PARAM_TBL_CHN        0x7
+#define UMAC_PARAM_TBL_STATISTICS 0x8
+
+/* fast access table */
+enum {
+       CFG_FRAG_THRESHOLD = 0,
+       CFG_FRAME_RETRY_LIMIT,
+       CFG_OS_QUEUE_UTIL_TH,
+       CFG_RX_FILTER,
+       /* <-- LAST --> */
+       FAST_ACCESS_CFG_TBL_FIX_LAST
+};
+
+/* fixed size table */
+enum {
+       CFG_POWER_INDEX = 0,
+       CFG_PM_LEGACY_RX_TIMEOUT,
+       CFG_PM_LEGACY_TX_TIMEOUT,
+       CFG_PM_CTRL_FLAGS,
+       CFG_PM_KEEP_ALIVE_IN_BEACONS,
+       CFG_BT_ON_THRESHOLD,
+       CFG_RTS_THRESHOLD,
+       CFG_CTS_TO_SELF,
+       CFG_COEX_MODE,
+       CFG_WIRELESS_MODE,
+       CFG_ASSOCIATION_TIMEOUT,
+       CFG_ROAM_TIMEOUT,
+       CFG_CAPABILITY_SUPPORTED_RATES,
+       CFG_SCAN_ALLOWED_UNASSOC_FLAGS,
+       CFG_SCAN_ALLOWED_MAIN_ASSOC_FLAGS,
+       CFG_SCAN_ALLOWED_PAN_ASSOC_FLAGS,
+       CFG_SCAN_INTERNAL_PERIODIC_ENABLED,
+       CFG_SCAN_IMM_INTERNAL_PERIODIC_SCAN_ON_INIT,
+       CFG_SCAN_DEFAULT_PERIODIC_FREQ_SEC,
+       CFG_SCAN_NUM_PASSIVE_CHAN_PER_PARTIAL_SCAN,
+       CFG_TLC_SUPPORTED_TX_HT_RATES,
+       CFG_TLC_SUPPORTED_TX_RATES,
+       CFG_TLC_VALID_ANTENNA,
+       CFG_TLC_SPATIAL_STREAM_SUPPORTED,
+       CFG_TLC_RETRY_PER_RATE,
+       CFG_TLC_RETRY_PER_HT_RATE,
+       CFG_TLC_FIXED_RATE,
+       CFG_TLC_FIXED_RATE_FLAGS,
+       CFG_TLC_CONTROL_FLAGS,
+       CFG_TLC_SR_MIN_FAIL,
+       CFG_TLC_SR_MIN_PASS,
+       CFG_TLC_HT_STAY_IN_COL_PASS_THRESH,
+       CFG_TLC_HT_STAY_IN_COL_FAIL_THRESH,
+       CFG_TLC_LEGACY_STAY_IN_COL_PASS_THRESH,
+       CFG_TLC_LEGACY_STAY_IN_COL_FAIL_THRESH,
+       CFG_TLC_HT_FLUSH_STATS_PACKETS,
+       CFG_TLC_LEGACY_FLUSH_STATS_PACKETS,
+       CFG_TLC_LEGACY_FLUSH_STATS_MS,
+       CFG_TLC_HT_FLUSH_STATS_MS,
+       CFG_TLC_STAY_IN_COL_TIME_OUT,
+       CFG_TLC_AGG_SHORT_LIM,
+       CFG_TLC_AGG_LONG_LIM,
+       CFG_TLC_HT_SR_NO_DECREASE,
+       CFG_TLC_LEGACY_SR_NO_DECREASE,
+       CFG_TLC_SR_FORCE_DECREASE,
+       CFG_TLC_SR_ALLOW_INCREASE,
+       CFG_TLC_AGG_SET_LONG,
+       CFG_TLC_AUTO_AGGREGATION,
+       CFG_TLC_AGG_THRESHOLD,
+       CFG_TLC_TID_LOAD_THRESHOLD,
+       CFG_TLC_BLOCK_ACK_TIMEOUT,
+       CFG_TLC_NO_BA_COUNTED_AS_ONE,
+       CFG_TLC_NUM_BA_STREAMS_ALLOWED,
+       CFG_TLC_NUM_BA_STREAMS_PRESENT,
+       CFG_TLC_RENEW_ADDBA_DELAY,
+       CFG_TLC_NUM_OF_MULTISEC_TO_COUN_LOAD,
+       CFG_TLC_IS_STABLE_IN_HT,
+       CFG_RLC_CHAIN_CTRL,
+       CFG_TRK_TABLE_OP_MODE,
+       CFG_TRK_TABLE_RSSI_THRESHOLD,
+       CFG_TX_PWR_TARGET, /* Used By xVT */
+       CFG_TX_PWR_LIMIT_USR,
+       CFG_TX_PWR_LIMIT_BSS, /* 11d limit */
+       CFG_TX_PWR_LIMIT_BSS_CONSTRAINT, /* 11h constraint */
+       CFG_TX_PWR_MODE,
+       CFG_MLME_DBG_NOTIF_BLOCK,
+       CFG_BT_OFF_BECONS_INTERVALS,
+       CFG_BT_FRAG_DURATION,
+
+       /* <-- LAST --> */
+       CFG_TBL_FIX_LAST
+};
+
+/* variable size table */
+enum {
+       CFG_NET_ADDR = 0,
+       CFG_PROFILE,
+       /* <-- LAST --> */
+       CFG_TBL_VAR_LAST
+};
+
+struct iwm_umac_cmd_set_param_fix {
+       __le16 tbl;
+       __le16 key;
+       __le32 value;
+} __attribute__ ((packed));
+
+struct iwm_umac_cmd_set_param_var {
+       __le16 tbl;
+       __le16 key;
+       __le16 len;
+       __le16 reserved;
+} __attribute__ ((packed));
+
+struct iwm_umac_cmd_get_param {
+       __le16 tbl;
+       __le16 key;
+} __attribute__ ((packed));
+
+struct iwm_umac_cmd_get_param_resp {
+       __le16 tbl;
+       __le16 key;
+       __le16 len;
+       __le16 reserved;
+} __attribute__ ((packed));
+
+struct iwm_umac_cmd_eeprom_proxy_hdr {
+       __le32 type;
+       __le32 offset;
+       __le32 len;
+} __attribute__ ((packed));
+
+struct iwm_umac_cmd_eeprom_proxy {
+       struct iwm_umac_cmd_eeprom_proxy_hdr hdr;
+       u8 buf[0];
+} __attribute__ ((packed));
+
+#define IWM_UMAC_CMD_EEPROM_TYPE_READ       0x1
+#define IWM_UMAC_CMD_EEPROM_TYPE_WRITE      0x2
+
+#define UMAC_CHANNEL_FLAG_VALID                BIT(0)
+#define UMAC_CHANNEL_FLAG_IBSS         BIT(1)
+#define UMAC_CHANNEL_FLAG_ACTIVE       BIT(3)
+#define UMAC_CHANNEL_FLAG_RADAR                BIT(4)
+#define UMAC_CHANNEL_FLAG_DFS          BIT(7)
+
+struct iwm_umac_channel_info {
+       u8 band;
+       u8 type;
+       u8 reserved;
+       u8 flags;
+       __le32 channels_mask;
+} __attribute__ ((packed));
+
+struct iwm_umac_cmd_get_channel_list {
+       __le16 count;
+       __le16 reserved;
+       struct iwm_umac_channel_info ch[0];
+} __attribute__ ((packed));
+
+
+/* UMAC WiFi interface commands */
+
+/* Coexistence mode */
+#define COEX_MODE_SA  0x1
+#define COEX_MODE_XOR 0x2
+#define COEX_MODE_CM  0x3
+#define COEX_MODE_MAX 0x4
+
+/* Wireless mode */
+#define WIRELESS_MODE_11A  0x1
+#define WIRELESS_MODE_11G  0x2
+
+#define UMAC_PROFILE_EX_IE_REQUIRED    0x1
+#define UMAC_PROFILE_QOS_ALLOWED       0x2
+
+/* Scanning */
+#define UMAC_WIFI_IF_PROBE_OPTION_MAX        10
+
+#define UMAC_WIFI_IF_SCAN_TYPE_USER          0x0
+#define UMAC_WIFI_IF_SCAN_TYPE_UMAC_RESERVED 0x1
+#define UMAC_WIFI_IF_SCAN_TYPE_HOST_PERIODIC 0x2
+#define UMAC_WIFI_IF_SCAN_TYPE_MAX           0x3
+
+struct iwm_umac_ssid {
+       u8 ssid_len;
+       u8 ssid[IEEE80211_MAX_SSID_LEN];
+       u8 reserved[3];
+} __attribute__ ((packed));
+
+struct iwm_umac_cmd_scan_request {
+       struct iwm_umac_wifi_if hdr;
+       __le32 type; /* UMAC_WIFI_IF_SCAN_TYPE_* */
+       u8 ssid_num;
+       u8 seq_num;
+       u8 timeout; /* In seconds */
+       u8 reserved;
+       struct iwm_umac_ssid ssids[UMAC_WIFI_IF_PROBE_OPTION_MAX];
+} __attribute__ ((packed));
+
+#define UMAC_CIPHER_TYPE_NONE          0xFF
+#define UMAC_CIPHER_TYPE_USE_GROUPCAST 0x00
+#define UMAC_CIPHER_TYPE_WEP_40                0x01
+#define UMAC_CIPHER_TYPE_WEP_104       0x02
+#define UMAC_CIPHER_TYPE_TKIP          0x04
+#define UMAC_CIPHER_TYPE_CCMP          0x08
+
+/* Supported authentication types - bitmap */
+#define UMAC_AUTH_TYPE_OPEN            0x00
+#define UMAC_AUTH_TYPE_LEGACY_PSK      0x01
+#define UMAC_AUTH_TYPE_8021X           0x02
+#define UMAC_AUTH_TYPE_RSNA_PSK                0x04
+
+/* iwm_umac_security.flag is WPA supported -- bits[0:0] */
+#define UMAC_SEC_FLG_WPA_ON_POS                0
+#define UMAC_SEC_FLG_WPA_ON_SEED       1
+#define UMAC_SEC_FLG_WPA_ON_MSK (UMAC_SEC_FLG_WPA_ON_SEED << \
+                                UMAC_SEC_FLG_WPA_ON_POS)
+
+/* iwm_umac_security.flag is WPA2 supported -- bits [1:1] */
+#define UMAC_SEC_FLG_RSNA_ON_POS       1
+#define UMAC_SEC_FLG_RSNA_ON_SEED      1
+#define UMAC_SEC_FLG_RSNA_ON_MSK        (UMAC_SEC_FLG_RSNA_ON_SEED << \
+                                        UMAC_SEC_FLG_RSNA_ON_POS)
+
+/* iwm_umac_security.flag is WSC mode on -- bits [2:2] */
+#define UMAC_SEC_FLG_WSC_ON_POS                2
+#define UMAC_SEC_FLG_WSC_ON_SEED       1
+
+/* Legacy profile can use only WEP40 and WEP104 for encryption and
+ * OPEN or PSK for authentication */
+#define UMAC_SEC_FLG_LEGACY_PROFILE    0
+
+struct iwm_umac_security {
+       u8 auth_type;
+       u8 ucast_cipher;
+       u8 mcast_cipher;
+       u8 flags;
+} __attribute__ ((packed));
+
+struct iwm_umac_ibss {
+       u8 beacon_interval;     /* in millisecond */
+       u8 atim;                /* in millisecond */
+       s8 join_only;
+       u8 band;
+       u8 channel;
+       u8 reserved[3];
+} __attribute__ ((packed));
+
+#define UMAC_MODE_BSS  0
+#define UMAC_MODE_IBSS 1
+
+#define UMAC_BSSID_MAX 4
+
+struct iwm_umac_profile {
+       struct iwm_umac_wifi_if hdr;
+       __le32 mode;
+       struct iwm_umac_ssid ssid;
+       u8 bssid[UMAC_BSSID_MAX][ETH_ALEN];
+       struct iwm_umac_security sec;
+       struct iwm_umac_ibss ibss;
+       __le32 channel_2ghz;
+       __le32 channel_5ghz;
+       __le16 flags;
+       u8 wireless_mode;
+       u8 bss_num;
+} __attribute__ ((packed));
+
+struct iwm_umac_invalidate_profile {
+       struct iwm_umac_wifi_if hdr;
+       u8 reason;
+       u8 reserved[3];
+} __attribute__ ((packed));
+
+/* Encryption key commands */
+struct iwm_umac_key_wep40 {
+       struct iwm_umac_wifi_if hdr;
+       struct iwm_umac_key_hdr key_hdr;
+       u8 key[WLAN_KEY_LEN_WEP40];
+       u8 static_key;
+       u8 reserved[2];
+} __attribute__ ((packed));
+
+struct iwm_umac_key_wep104 {
+       struct iwm_umac_wifi_if hdr;
+       struct iwm_umac_key_hdr key_hdr;
+       u8 key[WLAN_KEY_LEN_WEP104];
+       u8 static_key;
+       u8 reserved[2];
+} __attribute__ ((packed));
+
+#define IWM_TKIP_KEY_SIZE 16
+#define IWM_TKIP_MIC_SIZE 8
+struct iwm_umac_key_tkip {
+       struct iwm_umac_wifi_if hdr;
+       struct iwm_umac_key_hdr key_hdr;
+       u8 iv_count[6];
+       u8 reserved[2];
+       u8 tkip_key[IWM_TKIP_KEY_SIZE];
+       u8 mic_rx_key[IWM_TKIP_MIC_SIZE];
+       u8 mic_tx_key[IWM_TKIP_MIC_SIZE];
+} __attribute__ ((packed));
+
+struct iwm_umac_key_ccmp {
+       struct iwm_umac_wifi_if hdr;
+       struct iwm_umac_key_hdr key_hdr;
+       u8 iv_count[6];
+       u8 reserved[2];
+       u8 key[WLAN_KEY_LEN_CCMP];
+} __attribute__ ((packed));
+
+struct iwm_umac_key_remove {
+       struct iwm_umac_wifi_if hdr;
+       struct iwm_umac_key_hdr key_hdr;
+} __attribute__ ((packed));
+
+struct iwm_umac_tx_key_id {
+       struct iwm_umac_wifi_if hdr;
+       u8 key_idx;
+       u8 reserved[3];
+} __attribute__ ((packed));
+
+struct iwm_umac_cmd_stats_req {
+       __le32 flags;
+} __attribute__ ((packed));
+
+/* LMAC commands */
+int iwm_read_mac(struct iwm_priv *iwm, u8 *mac);
+int iwm_send_prio_table(struct iwm_priv *iwm);
+int iwm_send_init_calib_cfg(struct iwm_priv *iwm, u8 calib_requested);
+int iwm_send_periodic_calib_cfg(struct iwm_priv *iwm, u8 calib_requested);
+int iwm_send_calib_results(struct iwm_priv *iwm);
+int iwm_store_rxiq_calib_result(struct iwm_priv *iwm);
+
+/* UMAC commands */
+int iwm_send_wifi_if_cmd(struct iwm_priv *iwm, void *payload, u16 payload_size,
+                        bool resp);
+int iwm_send_umac_reset(struct iwm_priv *iwm, __le32 reset_flags, bool resp);
+int iwm_umac_set_config_fix(struct iwm_priv *iwm, u16 tbl, u16 key, u32 value);
+int iwm_umac_set_config_var(struct iwm_priv *iwm, u16 key,
+                           void *payload, u16 payload_size);
+int iwm_send_umac_config(struct iwm_priv *iwm, __le32 reset_flags);
+int iwm_send_mlme_profile(struct iwm_priv *iwm);
+int iwm_invalidate_mlme_profile(struct iwm_priv *iwm);
+int iwm_send_packet(struct iwm_priv *iwm, struct sk_buff *skb, int pool_id);
+int iwm_set_tx_key(struct iwm_priv *iwm, u8 key_idx);
+int iwm_set_key(struct iwm_priv *iwm, bool remove, bool set_tx_key,
+               struct iwm_key *key);
+int iwm_send_umac_stats_req(struct iwm_priv *iwm, u32 flags);
+int iwm_send_umac_channel_list(struct iwm_priv *iwm);
+int iwm_scan_ssids(struct iwm_priv *iwm, struct cfg80211_ssid *ssids,
+                  int ssid_num);
+int iwm_scan_one_ssid(struct iwm_priv *iwm, u8 *ssid, int ssid_len);
+
+/* UDMA commands */
+int iwm_target_reset(struct iwm_priv *iwm);
+#endif
diff --git a/drivers/net/wireless/iwmc3200wifi/debug.h b/drivers/net/wireless/iwmc3200wifi/debug.h
new file mode 100644 (file)
index 0000000..8fbb42d
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ * Intel Wireless Multicomm 3200 WiFi driver
+ *
+ * Copyright (C) 2009 Intel Corporation <ilw@linux.intel.com>
+ * Samuel Ortiz <samuel.ortiz@intel.com>
+ * Zhu Yi <yi.zhu@intel.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., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ */
+
+#ifndef __IWM_DEBUG_H__
+#define __IWM_DEBUG_H__
+
+#define IWM_ERR(p, f, a...) dev_err(iwm_to_dev(p), f, ## a)
+#define IWM_WARN(p, f, a...) dev_warn(iwm_to_dev(p), f, ## a)
+#define IWM_INFO(p, f, a...) dev_info(iwm_to_dev(p), f, ## a)
+#define IWM_CRIT(p, f, a...) dev_crit(iwm_to_dev(p), f, ## a)
+
+#ifdef CONFIG_IWM_DEBUG
+
+#define IWM_DEBUG_MODULE(i, level, module, f, a...)                         \
+do {                                                                        \
+       if (unlikely(i->dbg.dbg_module[IWM_DM_##module] >= (IWM_DL_##level)))\
+               dev_printk(KERN_INFO, (iwm_to_dev(i)),               \
+                          "%s " f, __func__ , ## a);                        \
+} while (0)
+
+#define IWM_HEXDUMP(i, level, module, pref, buf, len)                       \
+do {                                                                        \
+       if (unlikely(i->dbg.dbg_module[IWM_DM_##module] >= (IWM_DL_##level)))\
+               print_hex_dump(KERN_INFO, pref, DUMP_PREFIX_OFFSET,          \
+                              16, 1, buf, len, 1);                          \
+} while (0)
+
+#else
+
+#define IWM_DEBUG_MODULE(i, level, module, f, a...)
+#define IWM_HEXDUMP(i, level, module, pref, buf, len)
+
+#endif /* CONFIG_IWM_DEBUG */
+
+/* Debug modules */
+enum iwm_debug_module_id {
+       IWM_DM_BOOT = 0,
+       IWM_DM_FW,
+       IWM_DM_SDIO,
+       IWM_DM_NTF,
+       IWM_DM_RX,
+       IWM_DM_TX,
+       IWM_DM_MLME,
+       IWM_DM_CMD,
+       IWM_DM_WEXT,
+       __IWM_DM_NR,
+};
+#define IWM_DM_DEFAULT 0
+
+#define IWM_DBG_BOOT(i, l, f, a...) IWM_DEBUG_MODULE(i, l, BOOT, f, ## a)
+#define IWM_DBG_FW(i, l, f, a...)   IWM_DEBUG_MODULE(i, l, FW, f, ## a)
+#define IWM_DBG_SDIO(i, l, f, a...) IWM_DEBUG_MODULE(i, l, SDIO, f, ## a)
+#define IWM_DBG_NTF(i, l, f, a...)  IWM_DEBUG_MODULE(i, l, NTF, f, ## a)
+#define IWM_DBG_RX(i, l, f, a...)   IWM_DEBUG_MODULE(i, l, RX, f, ## a)
+#define IWM_DBG_TX(i, l, f, a...)   IWM_DEBUG_MODULE(i, l, TX, f, ## a)
+#define IWM_DBG_MLME(i, l, f, a...) IWM_DEBUG_MODULE(i, l, MLME, f, ## a)
+#define IWM_DBG_CMD(i, l, f, a...)  IWM_DEBUG_MODULE(i, l, CMD, f, ## a)
+#define IWM_DBG_WEXT(i, l, f, a...) IWM_DEBUG_MODULE(i, l, WEXT, f, ## a)
+
+/* Debug levels */
+enum iwm_debug_level {
+       IWM_DL_NONE = 0,
+       IWM_DL_ERR,
+       IWM_DL_WARN,
+       IWM_DL_INFO,
+       IWM_DL_DBG,
+};
+#define IWM_DL_DEFAULT IWM_DL_ERR
+
+struct iwm_debugfs {
+       struct iwm_priv *iwm;
+       struct dentry *rootdir;
+       struct dentry *devdir;
+       struct dentry *dbgdir;
+       struct dentry *txdir;
+       struct dentry *rxdir;
+       struct dentry *busdir;
+
+       u32 dbg_level;
+       struct dentry *dbg_level_dentry;
+
+       unsigned long dbg_modules;
+       struct dentry *dbg_modules_dentry;
+
+       u8 dbg_module[__IWM_DM_NR];
+       struct dentry *dbg_module_dentries[__IWM_DM_NR];
+
+       struct dentry *txq_dentry;
+       struct dentry *tx_credit_dentry;
+       struct dentry *rx_ticket_dentry;
+};
+
+#ifdef CONFIG_IWM_DEBUG
+int iwm_debugfs_init(struct iwm_priv *iwm);
+void iwm_debugfs_exit(struct iwm_priv *iwm);
+#else
+static inline int iwm_debugfs_init(struct iwm_priv *iwm)
+{
+       return 0;
+}
+static inline void iwm_debugfs_exit(struct iwm_priv *iwm) {}
+#endif
+
+#endif
diff --git a/drivers/net/wireless/iwmc3200wifi/debugfs.c b/drivers/net/wireless/iwmc3200wifi/debugfs.c
new file mode 100644 (file)
index 0000000..0fa7b91
--- /dev/null
@@ -0,0 +1,453 @@
+/*
+ * Intel Wireless Multicomm 3200 WiFi driver
+ *
+ * Copyright (C) 2009 Intel Corporation <ilw@linux.intel.com>
+ * Samuel Ortiz <samuel.ortiz@intel.com>
+ * Zhu Yi <yi.zhu@intel.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., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/bitops.h>
+#include <linux/debugfs.h>
+
+#include "iwm.h"
+#include "bus.h"
+#include "rx.h"
+#include "debug.h"
+
+static struct {
+       u8 id;
+       char *name;
+} iwm_debug_module[__IWM_DM_NR] = {
+        {IWM_DM_BOOT, "boot"},
+        {IWM_DM_FW,   "fw"},
+        {IWM_DM_SDIO, "sdio"},
+        {IWM_DM_NTF,  "ntf"},
+        {IWM_DM_RX,   "rx"},
+        {IWM_DM_TX,   "tx"},
+        {IWM_DM_MLME, "mlme"},
+        {IWM_DM_CMD,  "cmd"},
+        {IWM_DM_WEXT,  "wext"},
+};
+
+#define add_dbg_module(dbg, name, id, initlevel)       \
+do {                                                   \
+       struct dentry *d;                               \
+       dbg.dbg_module[id] = (initlevel);               \
+       d = debugfs_create_x8(name, 0600, dbg.dbgdir,   \
+                            &(dbg.dbg_module[id]));    \
+       if (!IS_ERR(d))                                 \
+               dbg.dbg_module_dentries[id] = d;        \
+} while (0)
+
+static int iwm_debugfs_u32_read(void *data, u64 *val)
+{
+       struct iwm_priv *iwm = data;
+
+       *val = iwm->dbg.dbg_level;
+       return 0;
+}
+
+static int iwm_debugfs_dbg_level_write(void *data, u64 val)
+{
+       struct iwm_priv *iwm = data;
+       int i;
+
+       iwm->dbg.dbg_level = val;
+
+       for (i = 0; i < __IWM_DM_NR; i++)
+               iwm->dbg.dbg_module[i] = val;
+
+       return 0;
+}
+DEFINE_SIMPLE_ATTRIBUTE(fops_iwm_dbg_level,
+                       iwm_debugfs_u32_read, iwm_debugfs_dbg_level_write,
+                       "%llu\n");
+
+static int iwm_debugfs_dbg_modules_write(void *data, u64 val)
+{
+       struct iwm_priv *iwm = data;
+       int i, bit;
+
+       iwm->dbg.dbg_modules = val;
+
+       for (i = 0; i < __IWM_DM_NR; i++)
+               iwm->dbg.dbg_module[i] = 0;
+
+       for_each_bit(bit, &iwm->dbg.dbg_modules, __IWM_DM_NR)
+               iwm->dbg.dbg_module[bit] = iwm->dbg.dbg_level;
+
+       return 0;
+}
+DEFINE_SIMPLE_ATTRIBUTE(fops_iwm_dbg_modules,
+                       iwm_debugfs_u32_read, iwm_debugfs_dbg_modules_write,
+                       "%llu\n");
+
+static int iwm_txrx_open(struct inode *inode, struct file *filp)
+{
+       filp->private_data = inode->i_private;
+       return 0;
+}
+
+
+static ssize_t iwm_debugfs_txq_read(struct file *filp, char __user *buffer,
+                                  size_t count, loff_t *ppos)
+{
+       struct iwm_priv *iwm = filp->private_data;
+       char *buf;
+       int i, buf_len = 4096;
+       size_t len = 0;
+       ssize_t ret;
+
+       if (*ppos != 0)
+               return 0;
+       if (count < sizeof(buf))
+               return -ENOSPC;
+
+       buf = kzalloc(buf_len, GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
+
+       for (i = 0; i < IWM_TX_QUEUES; i++) {
+               struct iwm_tx_queue *txq = &iwm->txq[i];
+               struct sk_buff *skb;
+               int j;
+               unsigned long flags;
+
+               spin_lock_irqsave(&txq->queue.lock, flags);
+
+               skb = (struct sk_buff *)&txq->queue;
+
+               len += snprintf(buf + len, buf_len - len, "TXQ #%d\n", i);
+               len += snprintf(buf + len, buf_len - len, "\tStopped:     %d\n",
+                               __netif_subqueue_stopped(iwm_to_ndev(iwm),
+                                                        txq->id));
+               len += snprintf(buf + len, buf_len - len, "\tConcat count:%d\n",
+                               txq->concat_count);
+               len += snprintf(buf + len, buf_len - len, "\tQueue len:   %d\n",
+                               skb_queue_len(&txq->queue));
+               for (j = 0; j < skb_queue_len(&txq->queue); j++) {
+                       struct iwm_tx_info *tx_info;
+
+                       skb = skb->next;
+                       tx_info = skb_to_tx_info(skb);
+
+                       len += snprintf(buf + len, buf_len - len,
+                                       "\tSKB #%d\n", j);
+                       len += snprintf(buf + len, buf_len - len,
+                                       "\t\tsta:   %d\n", tx_info->sta);
+                       len += snprintf(buf + len, buf_len - len,
+                                       "\t\tcolor: %d\n", tx_info->color);
+                       len += snprintf(buf + len, buf_len - len,
+                                       "\t\ttid:   %d\n", tx_info->tid);
+               }
+
+               spin_unlock_irqrestore(&txq->queue.lock, flags);
+       }
+
+       ret = simple_read_from_buffer(buffer, len, ppos, buf, buf_len);
+       kfree(buf);
+
+       return ret;
+}
+
+static ssize_t iwm_debugfs_tx_credit_read(struct file *filp,
+                                         char __user *buffer,
+                                         size_t count, loff_t *ppos)
+{
+       struct iwm_priv *iwm = filp->private_data;
+       struct iwm_tx_credit *credit = &iwm->tx_credit;
+       char *buf;
+       int i, buf_len = 4096;
+       size_t len = 0;
+       ssize_t ret;
+
+       if (*ppos != 0)
+               return 0;
+       if (count < sizeof(buf))
+               return -ENOSPC;
+
+       buf = kzalloc(buf_len, GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
+
+       len += snprintf(buf + len, buf_len - len,
+                       "NR pools:  %d\n", credit->pool_nr);
+       len += snprintf(buf + len, buf_len - len,
+                       "pools map: 0x%lx\n", credit->full_pools_map);
+
+       len += snprintf(buf + len, buf_len - len, "\n### POOLS ###\n");
+       for (i = 0; i < IWM_MACS_OUT_GROUPS; i++) {
+               len += snprintf(buf + len, buf_len - len,
+                               "pools entry #%d\n", i);
+               len += snprintf(buf + len, buf_len - len,
+                               "\tid:          %d\n",
+                               credit->pools[i].id);
+               len += snprintf(buf + len, buf_len - len,
+                               "\tsid:         %d\n",
+                               credit->pools[i].sid);
+               len += snprintf(buf + len, buf_len - len,
+                               "\tmin_pages:   %d\n",
+                               credit->pools[i].min_pages);
+               len += snprintf(buf + len, buf_len - len,
+                               "\tmax_pages:   %d\n",
+                               credit->pools[i].max_pages);
+               len += snprintf(buf + len, buf_len - len,
+                               "\talloc_pages: %d\n",
+                               credit->pools[i].alloc_pages);
+               len += snprintf(buf + len, buf_len - len,
+                               "\tfreed_pages: %d\n",
+                               credit->pools[i].total_freed_pages);
+       }
+
+       len += snprintf(buf + len, buf_len - len, "\n### SPOOLS ###\n");
+       for (i = 0; i < IWM_MACS_OUT_SGROUPS; i++) {
+               len += snprintf(buf + len, buf_len - len,
+                               "spools entry #%d\n", i);
+               len += snprintf(buf + len, buf_len - len,
+                               "\tid:          %d\n",
+                               credit->spools[i].id);
+               len += snprintf(buf + len, buf_len - len,
+                               "\tmax_pages:   %d\n",
+                               credit->spools[i].max_pages);
+               len += snprintf(buf + len, buf_len - len,
+                               "\talloc_pages: %d\n",
+                               credit->spools[i].alloc_pages);
+
+       }
+
+       ret = simple_read_from_buffer(buffer, len, ppos, buf, buf_len);
+       kfree(buf);
+
+       return ret;
+}
+
+static ssize_t iwm_debugfs_rx_ticket_read(struct file *filp,
+                                         char __user *buffer,
+                                         size_t count, loff_t *ppos)
+{
+       struct iwm_priv *iwm = filp->private_data;
+       struct iwm_rx_ticket_node *ticket, *next;
+       char *buf;
+       int buf_len = 4096, i;
+       size_t len = 0;
+       ssize_t ret;
+
+       if (*ppos != 0)
+               return 0;
+       if (count < sizeof(buf))
+               return -ENOSPC;
+
+       buf = kzalloc(buf_len, GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
+
+       list_for_each_entry_safe(ticket, next, &iwm->rx_tickets, node) {
+               len += snprintf(buf + len, buf_len - len, "Ticket #%d\n",
+                               ticket->ticket->id);
+               len += snprintf(buf + len, buf_len - len, "\taction: 0x%x\n",
+                               ticket->ticket->action);
+               len += snprintf(buf + len, buf_len - len, "\tflags:  0x%x\n",
+                               ticket->ticket->flags);
+       }
+
+       for (i = 0; i < IWM_RX_ID_HASH; i++) {
+               struct iwm_rx_packet *packet, *nxt;
+               struct list_head *pkt_list = &iwm->rx_packets[i];
+               if (!list_empty(pkt_list)) {
+                       len += snprintf(buf + len, buf_len - len,
+                                       "Packet hash #%d\n", i);
+                       list_for_each_entry_safe(packet, nxt, pkt_list, node) {
+                               len += snprintf(buf + len, buf_len - len,
+                                               "\tPacket id:     %d\n",
+                                               packet->id);
+                               len += snprintf(buf + len, buf_len - len,
+                                               "\tPacket length: %lu\n",
+                                               packet->pkt_size);
+                       }
+               }
+       }
+
+       ret = simple_read_from_buffer(buffer, len, ppos, buf, buf_len);
+       kfree(buf);
+
+       return ret;
+}
+
+
+static const struct file_operations iwm_debugfs_txq_fops = {
+       .owner =        THIS_MODULE,
+       .open =         iwm_txrx_open,
+       .read =         iwm_debugfs_txq_read,
+};
+
+static const struct file_operations iwm_debugfs_tx_credit_fops = {
+       .owner =        THIS_MODULE,
+       .open =         iwm_txrx_open,
+       .read =         iwm_debugfs_tx_credit_read,
+};
+
+static const struct file_operations iwm_debugfs_rx_ticket_fops = {
+       .owner =        THIS_MODULE,
+       .open =         iwm_txrx_open,
+       .read =         iwm_debugfs_rx_ticket_read,
+};
+
+int iwm_debugfs_init(struct iwm_priv *iwm)
+{
+       int i, result;
+       char devdir[16];
+
+       iwm->dbg.rootdir = debugfs_create_dir(KBUILD_MODNAME, NULL);
+       result = PTR_ERR(iwm->dbg.rootdir);
+       if (!result || IS_ERR(iwm->dbg.rootdir)) {
+               if (result == -ENODEV) {
+                       IWM_ERR(iwm, "DebugFS (CONFIG_DEBUG_FS) not "
+                               "enabled in kernel config\n");
+                       result = 0;     /* No debugfs support */
+               }
+               IWM_ERR(iwm, "Couldn't create rootdir: %d\n", result);
+               goto error;
+       }
+
+       snprintf(devdir, sizeof(devdir), "%s", wiphy_name(iwm_to_wiphy(iwm)));
+
+       iwm->dbg.devdir = debugfs_create_dir(devdir, iwm->dbg.rootdir);
+       result = PTR_ERR(iwm->dbg.devdir);
+       if (IS_ERR(iwm->dbg.devdir) && (result != -ENODEV)) {
+               IWM_ERR(iwm, "Couldn't create devdir: %d\n", result);
+               goto error;
+       }
+
+       iwm->dbg.dbgdir = debugfs_create_dir("debug", iwm->dbg.devdir);
+       result = PTR_ERR(iwm->dbg.dbgdir);
+       if (IS_ERR(iwm->dbg.dbgdir) && (result != -ENODEV)) {
+               IWM_ERR(iwm, "Couldn't create dbgdir: %d\n", result);
+               goto error;
+       }
+
+       iwm->dbg.rxdir = debugfs_create_dir("rx", iwm->dbg.devdir);
+       result = PTR_ERR(iwm->dbg.rxdir);
+       if (IS_ERR(iwm->dbg.rxdir) && (result != -ENODEV)) {
+               IWM_ERR(iwm, "Couldn't create rx dir: %d\n", result);
+               goto error;
+       }
+
+       iwm->dbg.txdir = debugfs_create_dir("tx", iwm->dbg.devdir);
+       result = PTR_ERR(iwm->dbg.txdir);
+       if (IS_ERR(iwm->dbg.txdir) && (result != -ENODEV)) {
+               IWM_ERR(iwm, "Couldn't create tx dir: %d\n", result);
+               goto error;
+       }
+
+       iwm->dbg.busdir = debugfs_create_dir("bus", iwm->dbg.devdir);
+       result = PTR_ERR(iwm->dbg.busdir);
+       if (IS_ERR(iwm->dbg.busdir) && (result != -ENODEV)) {
+               IWM_ERR(iwm, "Couldn't create bus dir: %d\n", result);
+               goto error;
+       }
+
+       if (iwm->bus_ops->debugfs_init) {
+               result = iwm->bus_ops->debugfs_init(iwm, iwm->dbg.busdir);
+               if (result < 0) {
+                       IWM_ERR(iwm, "Couldn't create bus entry: %d\n", result);
+                       goto error;
+               }
+       }
+
+
+       iwm->dbg.dbg_level = IWM_DL_NONE;
+       iwm->dbg.dbg_level_dentry =
+               debugfs_create_file("level", 0200, iwm->dbg.dbgdir, iwm,
+                                   &fops_iwm_dbg_level);
+       result = PTR_ERR(iwm->dbg.dbg_level_dentry);
+       if (IS_ERR(iwm->dbg.dbg_level_dentry) && (result != -ENODEV)) {
+               IWM_ERR(iwm, "Couldn't create dbg_level: %d\n", result);
+               goto error;
+       }
+
+
+       iwm->dbg.dbg_modules = IWM_DM_DEFAULT;
+       iwm->dbg.dbg_modules_dentry =
+               debugfs_create_file("modules", 0200, iwm->dbg.dbgdir, iwm,
+                                   &fops_iwm_dbg_modules);
+       result = PTR_ERR(iwm->dbg.dbg_modules_dentry);
+       if (IS_ERR(iwm->dbg.dbg_modules_dentry) && (result != -ENODEV)) {
+               IWM_ERR(iwm, "Couldn't create dbg_modules: %d\n", result);
+               goto error;
+       }
+
+       for (i = 0; i < __IWM_DM_NR; i++)
+               add_dbg_module(iwm->dbg, iwm_debug_module[i].name,
+                              iwm_debug_module[i].id, IWM_DL_DEFAULT);
+
+       iwm->dbg.txq_dentry = debugfs_create_file("queues", 0200,
+                                                 iwm->dbg.txdir, iwm,
+                                                 &iwm_debugfs_txq_fops);
+       result = PTR_ERR(iwm->dbg.txq_dentry);
+       if (IS_ERR(iwm->dbg.txq_dentry) && (result != -ENODEV)) {
+               IWM_ERR(iwm, "Couldn't create tx queue: %d\n", result);
+               goto error;
+       }
+
+       iwm->dbg.tx_credit_dentry = debugfs_create_file("credits", 0200,
+                                                  iwm->dbg.txdir, iwm,
+                                                  &iwm_debugfs_tx_credit_fops);
+       result = PTR_ERR(iwm->dbg.tx_credit_dentry);
+       if (IS_ERR(iwm->dbg.tx_credit_dentry) && (result != -ENODEV)) {
+               IWM_ERR(iwm, "Couldn't create tx credit: %d\n", result);
+               goto error;
+       }
+
+       iwm->dbg.rx_ticket_dentry = debugfs_create_file("tickets", 0200,
+                                                 iwm->dbg.rxdir, iwm,
+                                                 &iwm_debugfs_rx_ticket_fops);
+       result = PTR_ERR(iwm->dbg.rx_ticket_dentry);
+       if (IS_ERR(iwm->dbg.rx_ticket_dentry) && (result != -ENODEV)) {
+               IWM_ERR(iwm, "Couldn't create rx ticket: %d\n", result);
+               goto error;
+       }
+
+       return 0;
+
+ error:
+       return result;
+}
+
+void iwm_debugfs_exit(struct iwm_priv *iwm)
+{
+       int i;
+
+       for (i = 0; i < __IWM_DM_NR; i++)
+               debugfs_remove(iwm->dbg.dbg_module_dentries[i]);
+
+       debugfs_remove(iwm->dbg.dbg_modules_dentry);
+       debugfs_remove(iwm->dbg.dbg_level_dentry);
+       debugfs_remove(iwm->dbg.txq_dentry);
+       debugfs_remove(iwm->dbg.tx_credit_dentry);
+       debugfs_remove(iwm->dbg.rx_ticket_dentry);
+       if (iwm->bus_ops->debugfs_exit)
+               iwm->bus_ops->debugfs_exit(iwm);
+
+       debugfs_remove(iwm->dbg.busdir);
+       debugfs_remove(iwm->dbg.dbgdir);
+       debugfs_remove(iwm->dbg.txdir);
+       debugfs_remove(iwm->dbg.rxdir);
+       debugfs_remove(iwm->dbg.devdir);
+       debugfs_remove(iwm->dbg.rootdir);
+}
diff --git a/drivers/net/wireless/iwmc3200wifi/eeprom.c b/drivers/net/wireless/iwmc3200wifi/eeprom.c
new file mode 100644 (file)
index 0000000..0f34b84
--- /dev/null
@@ -0,0 +1,187 @@
+/*
+ * Intel Wireless Multicomm 3200 WiFi driver
+ *
+ * Copyright (C) 2009 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in
+ *     the documentation and/or other materials provided with the
+ *     distribution.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * Intel Corporation <ilw@linux.intel.com>
+ * Samuel Ortiz <samuel.ortiz@intel.com>
+ * Zhu Yi <yi.zhu@intel.com>
+ *
+ */
+
+#include <linux/kernel.h>
+
+#include "iwm.h"
+#include "umac.h"
+#include "commands.h"
+#include "eeprom.h"
+
+static struct iwm_eeprom_entry eeprom_map[] = {
+       [IWM_EEPROM_SIG] =
+       {"Signature", IWM_EEPROM_SIG_OFF, IWM_EEPROM_SIG_LEN},
+
+       [IWM_EEPROM_VERSION] =
+       {"Version", IWM_EEPROM_VERSION_OFF, IWM_EEPROM_VERSION_LEN},
+
+       [IWM_EEPROM_OEM_HW_VERSION] =
+       {"OEM HW version", IWM_EEPROM_OEM_HW_VERSION_OFF,
+        IWM_EEPROM_OEM_HW_VERSION_LEN},
+
+       [IWM_EEPROM_MAC_VERSION] =
+       {"MAC version", IWM_EEPROM_MAC_VERSION_OFF, IWM_EEPROM_MAC_VERSION_LEN},
+
+       [IWM_EEPROM_CARD_ID] =
+       {"Card ID", IWM_EEPROM_CARD_ID_OFF, IWM_EEPROM_CARD_ID_LEN},
+
+       [IWM_EEPROM_RADIO_CONF] =
+       {"Radio config", IWM_EEPROM_RADIO_CONF_OFF, IWM_EEPROM_RADIO_CONF_LEN},
+
+       [IWM_EEPROM_SKU_CAP] =
+       {"SKU capabilities", IWM_EEPROM_SKU_CAP_OFF, IWM_EEPROM_SKU_CAP_LEN},
+
+       [IWM_EEPROM_CALIB_RXIQ_OFFSET] =
+       {"RX IQ offset", IWM_EEPROM_CALIB_RXIQ_OFF, IWM_EEPROM_INDIRECT_LEN},
+
+       [IWM_EEPROM_CALIB_RXIQ] =
+       {"Calib RX IQ", 0, IWM_EEPROM_CALIB_RXIQ_LEN},
+};
+
+
+static int iwm_eeprom_read(struct iwm_priv *iwm, u8 eeprom_id)
+{
+       int ret;
+       u32 entry_size, chunk_size, data_offset = 0, addr_offset = 0;
+       u32 addr;
+       struct iwm_udma_wifi_cmd udma_cmd;
+       struct iwm_umac_cmd umac_cmd;
+       struct iwm_umac_cmd_eeprom_proxy eeprom_cmd;
+
+       if (eeprom_id > (IWM_EEPROM_LAST - 1))
+               return -EINVAL;
+
+       entry_size = eeprom_map[eeprom_id].length;
+
+       if (eeprom_id >= IWM_EEPROM_INDIRECT_DATA) {
+               /* indirect data */
+               u32 off_id = eeprom_id - IWM_EEPROM_INDIRECT_DATA +
+                            IWM_EEPROM_INDIRECT_OFFSET;
+
+               eeprom_map[eeprom_id].offset =
+                       *(u16 *)(iwm->eeprom + eeprom_map[off_id].offset) << 1;
+       }
+
+       addr = eeprom_map[eeprom_id].offset;
+
+       udma_cmd.eop = 1;
+       udma_cmd.credit_group = 0x4;
+       udma_cmd.ra_tid = UMAC_HDI_ACT_TBL_IDX_HOST_CMD;
+       udma_cmd.lmac_offset = 0;
+
+       umac_cmd.id = UMAC_CMD_OPCODE_EEPROM_PROXY;
+       umac_cmd.resp = 1;
+
+       while (entry_size > 0) {
+               chunk_size = min_t(u32, entry_size, IWM_MAX_EEPROM_DATA_LEN);
+
+               eeprom_cmd.hdr.type =
+                       cpu_to_le32(IWM_UMAC_CMD_EEPROM_TYPE_READ);
+               eeprom_cmd.hdr.offset = cpu_to_le32(addr + addr_offset);
+               eeprom_cmd.hdr.len = cpu_to_le32(chunk_size);
+
+               ret = iwm_hal_send_umac_cmd(iwm, &udma_cmd,
+                                           &umac_cmd, &eeprom_cmd,
+                                    sizeof(struct iwm_umac_cmd_eeprom_proxy));
+               if (ret < 0) {
+                       IWM_ERR(iwm, "Couldn't read eeprom\n");
+                       return ret;
+               }
+
+               ret = iwm_notif_handle(iwm, UMAC_CMD_OPCODE_EEPROM_PROXY,
+                                      IWM_SRC_UMAC, 2*HZ);
+               if (ret < 0) {
+                       IWM_ERR(iwm, "Did not get any eeprom answer\n");
+                       return ret;
+               }
+
+               data_offset += chunk_size;
+               addr_offset += chunk_size;
+               entry_size -= chunk_size;
+       }
+
+       return 0;
+}
+
+u8 *iwm_eeprom_access(struct iwm_priv *iwm, u8 eeprom_id)
+{
+       if (!iwm->eeprom)
+               return ERR_PTR(-ENODEV);
+
+       return iwm->eeprom + eeprom_map[eeprom_id].offset;
+}
+
+int iwm_eeprom_init(struct iwm_priv *iwm)
+{
+       int i, ret = 0;
+       char name[32];
+
+       iwm->eeprom = kzalloc(IWM_EEPROM_LEN, GFP_KERNEL);
+       if (!iwm->eeprom)
+               return -ENOMEM;
+
+       for (i = IWM_EEPROM_FIRST; i < IWM_EEPROM_LAST; i++) {
+#ifdef CONFIG_IWM_B0_HW_SUPPORT
+               if (iwm->conf.hw_b0 && (i >= IWM_EEPROM_INDIRECT_OFFSET))
+                       break;
+#endif
+               ret = iwm_eeprom_read(iwm, i);
+               if (ret < 0) {
+                       IWM_ERR(iwm, "Couldn't read eeprom entry #%d: %s\n",
+                               i, eeprom_map[i].name);
+                       break;
+               }
+       }
+
+       IWM_DBG_BOOT(iwm, DBG, "EEPROM dump:\n");
+       for (i = IWM_EEPROM_FIRST; i < IWM_EEPROM_LAST; i++) {
+               memset(name, 0, 32);
+               sprintf(name, "%s: ", eeprom_map[i].name);
+
+               IWM_HEXDUMP(iwm, DBG, BOOT, name,
+                           iwm->eeprom + eeprom_map[i].offset,
+                           eeprom_map[i].length);
+       }
+
+       return ret;
+}
+
+void iwm_eeprom_exit(struct iwm_priv *iwm)
+{
+       kfree(iwm->eeprom);
+}
diff --git a/drivers/net/wireless/iwmc3200wifi/eeprom.h b/drivers/net/wireless/iwmc3200wifi/eeprom.h
new file mode 100644 (file)
index 0000000..cdb31a6
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * Intel Wireless Multicomm 3200 WiFi driver
+ *
+ * Copyright (C) 2009 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in
+ *     the documentation and/or other materials provided with the
+ *     distribution.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * Intel Corporation <ilw@linux.intel.com>
+ * Samuel Ortiz <samuel.ortiz@intel.com>
+ * Zhu Yi <yi.zhu@intel.com>
+ *
+ */
+
+#ifndef __IWM_EEPROM_H__
+#define __IWM_EEPROM_H__
+
+enum {
+       IWM_EEPROM_SIG = 0,
+       IWM_EEPROM_FIRST = IWM_EEPROM_SIG,
+       IWM_EEPROM_VERSION,
+       IWM_EEPROM_OEM_HW_VERSION,
+       IWM_EEPROM_MAC_VERSION,
+       IWM_EEPROM_CARD_ID,
+       IWM_EEPROM_RADIO_CONF,
+       IWM_EEPROM_SKU_CAP,
+
+       IWM_EEPROM_INDIRECT_OFFSET,
+       IWM_EEPROM_CALIB_RXIQ_OFFSET = IWM_EEPROM_INDIRECT_OFFSET,
+
+       IWM_EEPROM_INDIRECT_DATA,
+       IWM_EEPROM_CALIB_RXIQ = IWM_EEPROM_INDIRECT_DATA,
+
+       IWM_EEPROM_LAST,
+};
+
+#define IWM_EEPROM_SIG_OFF             0x00
+#define IWM_EEPROM_VERSION_OFF        (0x54 << 1)
+#define IWM_EEPROM_OEM_HW_VERSION_OFF (0x56 << 1)
+#define IWM_EEPROM_MAC_VERSION_OFF    (0x30 << 1)
+#define IWM_EEPROM_CARD_ID_OFF        (0x5d << 1)
+#define IWM_EEPROM_RADIO_CONF_OFF     (0x58 << 1)
+#define IWM_EEPROM_SKU_CAP_OFF        (0x55 << 1)
+#define IWM_EEPROM_CALIB_CONFIG_OFF   (0x7c << 1)
+
+#define IWM_EEPROM_SIG_LEN              4
+#define IWM_EEPROM_VERSION_LEN          2
+#define IWM_EEPROM_OEM_HW_VERSION_LEN   2
+#define IWM_EEPROM_MAC_VERSION_LEN      1
+#define IWM_EEPROM_CARD_ID_LEN          2
+#define IWM_EEPROM_RADIO_CONF_LEN       2
+#define IWM_EEPROM_SKU_CAP_LEN          2
+#define IWM_EEPROM_INDIRECT_LEN                2
+
+#define IWM_MAX_EEPROM_DATA_LEN         240
+#define IWM_EEPROM_LEN                  0x800
+
+#define IWM_EEPROM_MIN_ALLOWED_VERSION          0x0610
+#define IWM_EEPROM_MAX_ALLOWED_VERSION          0x0700
+#define IWM_EEPROM_CURRENT_VERSION              0x0612
+
+#define IWM_EEPROM_SKU_CAP_BAND_24GHZ           (1 << 4)
+#define IWM_EEPROM_SKU_CAP_BAND_52GHZ           (1 << 5)
+#define IWM_EEPROM_SKU_CAP_11N_ENABLE           (1 << 6)
+
+enum {
+       IWM_EEPROM_CALIB_CAL_HDR,
+       IWM_EEPROM_CALIB_TX_POWER,
+       IWM_EEPROM_CALIB_XTAL,
+       IWM_EEPROM_CALIB_TEMPERATURE,
+       IWM_EEPROM_CALIB_RX_BB_FILTER,
+       IWM_EEPROM_CALIB_RX_IQ,
+       IWM_EEPROM_CALIB_MAX,
+};
+
+#define IWM_EEPROM_CALIB_RXIQ_OFF      (IWM_EEPROM_CALIB_CONFIG_OFF + \
+                                        (IWM_EEPROM_CALIB_RX_IQ << 1))
+#define IWM_EEPROM_CALIB_RXIQ_LEN      sizeof(struct iwm_lmac_calib_rxiq)
+
+struct iwm_eeprom_entry {
+       char *name;
+       u32 offset;
+       u32 length;
+};
+
+int iwm_eeprom_init(struct iwm_priv *iwm);
+void iwm_eeprom_exit(struct iwm_priv *iwm);
+u8 *iwm_eeprom_access(struct iwm_priv *iwm, u8 eeprom_id);
+
+#endif
diff --git a/drivers/net/wireless/iwmc3200wifi/fw.c b/drivers/net/wireless/iwmc3200wifi/fw.c
new file mode 100644 (file)
index 0000000..ec1a15a
--- /dev/null
@@ -0,0 +1,388 @@
+/*
+ * Intel Wireless Multicomm 3200 WiFi driver
+ *
+ * Copyright (C) 2009 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in
+ *     the documentation and/or other materials provided with the
+ *     distribution.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * Intel Corporation <ilw@linux.intel.com>
+ * Samuel Ortiz <samuel.ortiz@intel.com>
+ * Zhu Yi <yi.zhu@intel.com>
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/firmware.h>
+
+#include "iwm.h"
+#include "bus.h"
+#include "hal.h"
+#include "umac.h"
+#include "debug.h"
+#include "fw.h"
+#include "commands.h"
+
+static const char fw_barker[] = "*WESTOPFORNOONE*";
+
+/*
+ * @op_code: Op code we're looking for.
+ * @index: There can be several instances of the same opcode within
+ *         the firmware. Index specifies which one we're looking for.
+ */
+static int iwm_fw_op_offset(struct iwm_priv *iwm, const struct firmware *fw,
+                           u16 op_code, u32 index)
+{
+       int offset = -EINVAL, fw_offset;
+       u32 op_index = 0;
+       const u8 *fw_ptr;
+       struct iwm_fw_hdr_rec *rec;
+
+       fw_offset = 0;
+       fw_ptr = fw->data;
+
+       /* We first need to look for the firmware barker */
+       if (memcmp(fw_ptr, fw_barker, IWM_HDR_BARKER_LEN)) {
+               IWM_ERR(iwm, "No barker string in this FW\n");
+               return -EINVAL;
+       }
+
+       if (fw->size < IWM_HDR_LEN) {
+               IWM_ERR(iwm, "FW is too small (%zu)\n", fw->size);
+               return -EINVAL;
+       }
+
+       fw_offset += IWM_HDR_BARKER_LEN;
+
+       while (fw_offset < fw->size) {
+               rec = (struct iwm_fw_hdr_rec *)(fw_ptr + fw_offset);
+
+               IWM_DBG_FW(iwm, DBG, "FW: op_code: 0x%x, len: %d @ 0x%x\n",
+                          rec->op_code, rec->len, fw_offset);
+
+               if (rec->op_code == IWM_HDR_REC_OP_INVALID) {
+                       IWM_DBG_FW(iwm, DBG, "Reached INVALID op code\n");
+                       break;
+               }
+
+               if (rec->op_code == op_code) {
+                       if (op_index == index) {
+                               fw_offset += sizeof(struct iwm_fw_hdr_rec);
+                               offset = fw_offset;
+                               goto out;
+                       }
+                       op_index++;
+               }
+
+               fw_offset += sizeof(struct iwm_fw_hdr_rec) + rec->len;
+       }
+
+ out:
+       return offset;
+}
+
+static int iwm_load_firmware_chunk(struct iwm_priv *iwm,
+                                  const struct firmware *fw,
+                                  struct iwm_fw_img_desc *img_desc)
+{
+       struct iwm_udma_nonwifi_cmd target_cmd;
+       u32 chunk_size;
+       const u8 *chunk_ptr;
+       int ret = 0;
+
+       IWM_DBG_FW(iwm, INFO, "Loading FW chunk: %d bytes @ 0x%x\n",
+                  img_desc->length, img_desc->address);
+
+       target_cmd.opcode = UMAC_HDI_OUT_OPCODE_WRITE;
+       target_cmd.handle_by_hw = 1;
+       target_cmd.op2 = 0;
+       target_cmd.resp = 0;
+       target_cmd.eop = 1;
+
+       chunk_size = img_desc->length;
+       chunk_ptr = fw->data + img_desc->offset;
+
+       while (chunk_size > 0) {
+               u32 tmp_chunk_size;
+
+               tmp_chunk_size = min_t(u32, chunk_size,
+                                      IWM_MAX_NONWIFI_CMD_BUFF_SIZE);
+
+               target_cmd.addr = cpu_to_le32(img_desc->address +
+                                   (chunk_ptr - fw->data - img_desc->offset));
+               target_cmd.op1_sz = cpu_to_le32(tmp_chunk_size);
+
+               IWM_DBG_FW(iwm, DBG, "\t%d bytes @ 0x%x\n",
+                          tmp_chunk_size, target_cmd.addr);
+
+               ret = iwm_hal_send_target_cmd(iwm, &target_cmd, chunk_ptr);
+               if (ret < 0) {
+                       IWM_ERR(iwm, "Couldn't load FW chunk\n");
+                       break;
+               }
+
+               chunk_size -= tmp_chunk_size;
+               chunk_ptr += tmp_chunk_size;
+       }
+
+       return ret;
+}
+/*
+ * To load a fw image to the target, we basically go through the
+ * fw, looking for OP_MEM_DESC records. Once we found one, we
+ * pass it to iwm_load_firmware_chunk().
+ * The OP_MEM_DESC records contain the actuall memory chunk to be
+ * sent, but also the destination address.
+ */
+static int iwm_load_img(struct iwm_priv *iwm, const char *img_name)
+{
+       const struct firmware *fw;
+       struct iwm_fw_img_desc *img_desc;
+       struct iwm_fw_img_ver *ver;
+       int ret = 0, fw_offset;
+       u32 opcode_idx = 0, build_date;
+       char *build_tag;
+
+       ret = request_firmware(&fw, img_name, iwm_to_dev(iwm));
+       if (ret) {
+               IWM_ERR(iwm, "Request firmware failed");
+               return ret;
+       }
+
+       IWM_DBG_FW(iwm, INFO, "Start to load FW %s\n", img_name);
+
+       while (1) {
+               fw_offset = iwm_fw_op_offset(iwm, fw,
+                                            IWM_HDR_REC_OP_MEM_DESC,
+                                            opcode_idx);
+               if (fw_offset < 0)
+                       break;
+
+               img_desc = (struct iwm_fw_img_desc *)(fw->data + fw_offset);
+               ret = iwm_load_firmware_chunk(iwm, fw, img_desc);
+               if (ret < 0)
+                       goto err_release_fw;
+               opcode_idx++;
+       };
+
+       /* Read firmware version */
+       fw_offset = iwm_fw_op_offset(iwm, fw, IWM_HDR_REC_OP_SW_VER, 0);
+       if (fw_offset < 0)
+               goto err_release_fw;
+
+       ver = (struct iwm_fw_img_ver *)(fw->data + fw_offset);
+
+       /* Read build tag */
+       fw_offset = iwm_fw_op_offset(iwm, fw, IWM_HDR_REC_OP_BUILD_TAG, 0);
+       if (fw_offset < 0)
+               goto err_release_fw;
+
+       build_tag = (char *)(fw->data + fw_offset);
+
+       /* Read build date */
+       fw_offset = iwm_fw_op_offset(iwm, fw, IWM_HDR_REC_OP_BUILD_DATE, 0);
+       if (fw_offset < 0)
+               goto err_release_fw;
+
+       build_date = *(u32 *)(fw->data + fw_offset);
+
+       IWM_INFO(iwm, "%s:\n", img_name);
+       IWM_INFO(iwm, "\tVersion:    %02X.%02X\n", ver->major, ver->minor);
+       IWM_INFO(iwm, "\tBuild tag:  %s\n", build_tag);
+       IWM_INFO(iwm, "\tBuild date: %x-%x-%x\n",
+                IWM_BUILD_YEAR(build_date), IWM_BUILD_MONTH(build_date),
+                IWM_BUILD_DAY(build_date));
+
+
+ err_release_fw:
+       release_firmware(fw);
+
+       return ret;
+}
+
+static int iwm_load_umac(struct iwm_priv *iwm)
+{
+       struct iwm_udma_nonwifi_cmd target_cmd;
+       int ret;
+
+       ret = iwm_load_img(iwm, iwm->bus_ops->umac_name);
+       if (ret < 0)
+               return ret;
+
+       /* We've loaded the UMAC, we can tell the target to jump there */
+       target_cmd.opcode = UMAC_HDI_OUT_OPCODE_JUMP;
+       target_cmd.addr = cpu_to_le32(UMAC_MU_FW_INST_DATA_12_ADDR);
+       target_cmd.op1_sz = 0;
+       target_cmd.op2 = 0;
+       target_cmd.handle_by_hw = 0;
+       target_cmd.resp = 1 ;
+       target_cmd.eop = 1;
+
+       ret = iwm_hal_send_target_cmd(iwm, &target_cmd, NULL);
+       if (ret < 0)
+               IWM_ERR(iwm, "Couldn't send JMP command\n");
+
+       return ret;
+}
+
+static int iwm_load_lmac(struct iwm_priv *iwm, const char *img_name)
+{
+       int ret;
+
+       ret = iwm_load_img(iwm, img_name);
+       if (ret < 0)
+               return ret;
+
+       return iwm_send_umac_reset(iwm,
+                       cpu_to_le32(UMAC_RST_CTRL_FLG_LARC_CLK_EN), 0);
+}
+
+/*
+ * We currently have to load 3 FWs:
+ * 1) The UMAC (Upper MAC).
+ * 2) The calibration LMAC (Lower MAC).
+ *    We then send the calibration init command, so that the device can
+ *    run a first calibration round.
+ * 3) The operational LMAC, which replaces the calibration one when it's
+ *    done with the first calibration round.
+ *
+ * Once those 3 FWs have been loaded, we send the periodic calibration
+ * command, and then the device is available for regular 802.11 operations.
+ */
+int iwm_load_fw(struct iwm_priv *iwm)
+{
+       int ret;
+
+       /* We first start downloading the UMAC */
+       ret = iwm_load_umac(iwm);
+       if (ret < 0) {
+               IWM_ERR(iwm, "UMAC loading failed\n");
+               return ret;
+       }
+
+       /* Handle UMAC_ALIVE notification */
+       ret = iwm_notif_handle(iwm, UMAC_NOTIFY_OPCODE_ALIVE, IWM_SRC_UMAC,
+                              WAIT_NOTIF_TIMEOUT);
+       if (ret) {
+               IWM_ERR(iwm, "Handle UMAC_ALIVE failed: %d\n", ret);
+               return ret;
+       }
+
+       /* UMAC is alive, we can download the calibration LMAC */
+       ret = iwm_load_lmac(iwm, iwm->bus_ops->calib_lmac_name);
+       if (ret) {
+               IWM_ERR(iwm, "Calibration LMAC loading failed\n");
+               return ret;
+       }
+
+       /* Handle UMAC_INIT_COMPLETE notification */
+       ret = iwm_notif_handle(iwm, UMAC_NOTIFY_OPCODE_INIT_COMPLETE,
+                              IWM_SRC_UMAC, WAIT_NOTIF_TIMEOUT);
+       if (ret) {
+               IWM_ERR(iwm, "Handle INIT_COMPLETE failed for calibration "
+                       "LMAC: %d\n", ret);
+               return ret;
+       }
+
+       /* Read EEPROM data */
+       ret = iwm_eeprom_init(iwm);
+       if (ret < 0) {
+               IWM_ERR(iwm, "Couldn't init eeprom array\n");
+               return ret;
+       }
+
+#ifdef CONFIG_IWM_B0_HW_SUPPORT
+       if (iwm->conf.hw_b0) {
+               clear_bit(PHY_CALIBRATE_RX_IQ_CMD, &iwm->conf.init_calib_map);
+               clear_bit(PHY_CALIBRATE_RX_IQ_CMD,
+                         &iwm->conf.periodic_calib_map);
+       }
+#endif
+       /* Read RX IQ calibration result from EEPROM */
+       if (test_bit(PHY_CALIBRATE_RX_IQ_CMD, &iwm->conf.init_calib_map)) {
+               iwm_store_rxiq_calib_result(iwm);
+               set_bit(PHY_CALIBRATE_RX_IQ_CMD, &iwm->calib_done_map);
+       }
+
+       iwm_send_prio_table(iwm);
+       iwm_send_init_calib_cfg(iwm, iwm->conf.init_calib_map);
+
+       while (iwm->calib_done_map != iwm->conf.init_calib_map) {
+               ret = iwm_notif_handle(iwm, CALIBRATION_RES_NOTIFICATION,
+                                      IWM_SRC_LMAC, WAIT_NOTIF_TIMEOUT);
+               if (ret) {
+                       IWM_ERR(iwm, "Wait for calibration result timeout\n");
+                       goto out;
+               }
+               IWM_DBG_FW(iwm, DBG, "Got calibration result. calib_done_map: "
+                          "0x%lx, requested calibrations: 0x%lx\n",
+                          iwm->calib_done_map, iwm->conf.init_calib_map);
+       }
+
+       /* Handle LMAC CALIBRATION_COMPLETE notification */
+       ret = iwm_notif_handle(iwm, CALIBRATION_COMPLETE_NOTIFICATION,
+                              IWM_SRC_LMAC, WAIT_NOTIF_TIMEOUT);
+       if (ret) {
+               IWM_ERR(iwm, "Wait for CALIBRATION_COMPLETE timeout\n");
+               goto out;
+       }
+
+       IWM_INFO(iwm, "LMAC calibration done: 0x%lx\n", iwm->calib_done_map);
+
+       iwm_send_umac_reset(iwm, cpu_to_le32(UMAC_RST_CTRL_FLG_LARC_RESET), 1);
+
+       ret = iwm_notif_handle(iwm, UMAC_CMD_OPCODE_RESET, IWM_SRC_UMAC,
+                              WAIT_NOTIF_TIMEOUT);
+       if (ret) {
+               IWM_ERR(iwm, "Wait for UMAC RESET timeout\n");
+               goto out;
+       }
+
+       /* Download the operational LMAC */
+       ret = iwm_load_lmac(iwm, iwm->bus_ops->lmac_name);
+       if (ret) {
+               IWM_ERR(iwm, "LMAC loading failed\n");
+               goto out;
+       }
+
+       ret = iwm_notif_handle(iwm, UMAC_NOTIFY_OPCODE_INIT_COMPLETE,
+                              IWM_SRC_UMAC, WAIT_NOTIF_TIMEOUT);
+       if (ret) {
+               IWM_ERR(iwm, "Handle INIT_COMPLETE failed for LMAC: %d\n", ret);
+               goto out;
+       }
+
+       iwm_send_prio_table(iwm);
+       iwm_send_calib_results(iwm);
+       iwm_send_periodic_calib_cfg(iwm, iwm->conf.periodic_calib_map);
+
+       return 0;
+
+ out:
+       iwm_eeprom_exit(iwm);
+       return ret;
+}
diff --git a/drivers/net/wireless/iwmc3200wifi/fw.h b/drivers/net/wireless/iwmc3200wifi/fw.h
new file mode 100644 (file)
index 0000000..c70a3b4
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * Intel Wireless Multicomm 3200 WiFi driver
+ *
+ * Copyright (C) 2009 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in
+ *     the documentation and/or other materials provided with the
+ *     distribution.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * Intel Corporation <ilw@linux.intel.com>
+ * Samuel Ortiz <samuel.ortiz@intel.com>
+ * Zhu Yi <yi.zhu@intel.com>
+ *
+ */
+
+#ifndef __IWM_FW_H__
+#define __IWM_FW_H__
+
+/**
+ * struct iwm_fw_hdr_rec - An iwm firmware image is a
+ * concatenation of various records. Each of them is
+ * defined by an ID (aka op code), a length, and the
+ * actual data.
+ * @op_code: The record ID, see IWM_HDR_REC_OP_*
+ *
+ * @len: The record payload length
+ *
+ * @buf: The record payload
+ */
+struct iwm_fw_hdr_rec {
+       u16 op_code;
+       u16 len;
+       u8 buf[0];
+};
+
+/* Header's definitions */
+#define IWM_HDR_LEN                          (512)
+#define IWM_HDR_BARKER_LEN                   (16)
+
+/* Header's opcodes */
+#define IWM_HDR_REC_OP_INVALID             (0x00)
+#define IWM_HDR_REC_OP_BUILD_DATE          (0x01)
+#define IWM_HDR_REC_OP_BUILD_TAG           (0x02)
+#define IWM_HDR_REC_OP_SW_VER              (0x03)
+#define IWM_HDR_REC_OP_HW_SKU              (0x04)
+#define IWM_HDR_REC_OP_BUILD_OPT           (0x05)
+#define IWM_HDR_REC_OP_MEM_DESC            (0x06)
+#define IWM_HDR_REC_USERDEFS               (0x07)
+
+/* Header's records length (in bytes) */
+#define IWM_HDR_REC_LEN_BUILD_DATE           (4)
+#define IWM_HDR_REC_LEN_BUILD_TAG            (64)
+#define IWM_HDR_REC_LEN_SW_VER               (4)
+#define IWM_HDR_REC_LEN_HW_SKU               (4)
+#define IWM_HDR_REC_LEN_BUILD_OPT            (4)
+#define IWM_HDR_REC_LEN_MEM_DESC             (12)
+#define IWM_HDR_REC_LEN_USERDEF              (64)
+
+#define IWM_BUILD_YEAR(date) ((date >> 16) & 0xffff)
+#define IWM_BUILD_MONTH(date) ((date >> 8) & 0xff)
+#define IWM_BUILD_DAY(date) (date & 0xff)
+
+struct iwm_fw_img_desc {
+       u32 offset;
+       u32 address;
+       u32 length;
+};
+
+struct iwm_fw_img_ver {
+       u8 minor;
+       u8 major;
+       u16 reserved;
+};
+
+int iwm_load_fw(struct iwm_priv *iwm);
+
+#endif
diff --git a/drivers/net/wireless/iwmc3200wifi/hal.c b/drivers/net/wireless/iwmc3200wifi/hal.c
new file mode 100644 (file)
index 0000000..ee127fe
--- /dev/null
@@ -0,0 +1,464 @@
+/*
+ * Intel Wireless Multicomm 3200 WiFi driver
+ *
+ * Copyright (C) 2009 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in
+ *     the documentation and/or other materials provided with the
+ *     distribution.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * Intel Corporation <ilw@linux.intel.com>
+ * Samuel Ortiz <samuel.ortiz@intel.com>
+ * Zhu Yi <yi.zhu@intel.com>
+ *
+ */
+
+/*
+ * Hardware Abstraction Layer for iwm.
+ *
+ * This file mostly defines an abstraction API for
+ * sending various commands to the target.
+ *
+ * We have 2 types of commands: wifi and non-wifi ones.
+ *
+ * - wifi commands:
+ *   They are used for sending LMAC and UMAC commands,
+ *   and thus are the most commonly used ones.
+ *   There are 2 different wifi command types, the regular
+ *   one and the LMAC one. The former is used to send
+ *   UMAC commands (see UMAC_CMD_OPCODE_* from umac.h)
+ *   while the latter is used for sending commands to the
+ *   LMAC. If you look at LMAC commands you'll se that they
+ *   are actually regular iwlwifi target commands encapsulated
+ *   into a special UMAC command called UMAC passthrough.
+ *   This is due to the fact the the host talks exclusively
+ *   to the UMAC and so there needs to be a special UMAC
+ *   command for talking to the LMAC.
+ *   This is how a wifi command is layed out:
+ *    ------------------------
+ *   | iwm_udma_out_wifi_hdr  |
+ *    ------------------------
+ *   | SW meta_data (32 bits) |
+ *    ------------------------
+ *   | iwm_dev_cmd_hdr        |
+ *    ------------------------
+ *   | payload                |
+ *   | ....                   |
+ *
+ * - non-wifi, or general commands:
+ *   Those commands are handled by the device's bootrom,
+ *   and are typically sent when the UMAC and the LMAC
+ *   are not yet available.
+ *    *   This is how a non-wifi command is layed out:
+ *    ---------------------------
+ *   | iwm_udma_out_nonwifi_hdr  |
+ *    ---------------------------
+ *   | payload                   |
+ *   | ....                      |
+
+ *
+ * All the commands start with a UDMA header, which is
+ * basically a 32 bits field. The 4 LSB there define
+ * an opcode that allows the target to differentiate
+ * between wifi (opcode is 0xf) and non-wifi commands
+ * (opcode is [0..0xe]).
+ *
+ * When a command (wifi or non-wifi) is supposed to receive
+ * an answer, we queue the command buffer. When we do receive
+ * a command response from the UMAC, we go through the list
+ * of pending command, and pass both the command and the answer
+ * to the rx handler. Each command is sent with a unique
+ * sequence id, and the answer is sent with the same one. This
+ * is how we're supposed to match an answer with its command.
+ * See rx.c:iwm_rx_handle_[non]wifi() and iwm_get_pending_[non]wifi()
+ * for the implementation details.
+ */
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+
+#include "iwm.h"
+#include "bus.h"
+#include "hal.h"
+#include "umac.h"
+#include "debug.h"
+
+static void iwm_nonwifi_cmd_init(struct iwm_priv *iwm,
+                                struct iwm_nonwifi_cmd *cmd,
+                                struct iwm_udma_nonwifi_cmd *udma_cmd)
+{
+       INIT_LIST_HEAD(&cmd->pending);
+
+       spin_lock(&iwm->cmd_lock);
+
+       cmd->resp_received = 0;
+
+       cmd->seq_num = iwm->nonwifi_seq_num;
+       udma_cmd->seq_num = cpu_to_le16(cmd->seq_num);
+
+       cmd->seq_num = iwm->nonwifi_seq_num++;
+       iwm->nonwifi_seq_num %= UMAC_NONWIFI_SEQ_NUM_MAX;
+
+       if (udma_cmd->resp)
+               list_add_tail(&cmd->pending, &iwm->nonwifi_pending_cmd);
+
+       spin_unlock(&iwm->cmd_lock);
+
+       cmd->buf.start = cmd->buf.payload;
+       cmd->buf.len = 0;
+
+       memcpy(&cmd->udma_cmd, udma_cmd, sizeof(*udma_cmd));
+}
+
+u16 iwm_alloc_wifi_cmd_seq(struct iwm_priv *iwm)
+{
+       u16 seq_num = iwm->wifi_seq_num;
+
+       iwm->wifi_seq_num++;
+       iwm->wifi_seq_num %= UMAC_WIFI_SEQ_NUM_MAX;
+
+       return seq_num;
+}
+
+static void iwm_wifi_cmd_init(struct iwm_priv *iwm,
+                             struct iwm_wifi_cmd *cmd,
+                             struct iwm_udma_wifi_cmd *udma_cmd,
+                             struct iwm_umac_cmd *umac_cmd,
+                             struct iwm_lmac_cmd *lmac_cmd,
+                             u16 payload_size)
+{
+       INIT_LIST_HEAD(&cmd->pending);
+
+       spin_lock(&iwm->cmd_lock);
+
+       cmd->seq_num = iwm_alloc_wifi_cmd_seq(iwm);
+       umac_cmd->seq_num = cpu_to_le16(cmd->seq_num);
+
+       if (umac_cmd->resp)
+               list_add_tail(&cmd->pending, &iwm->wifi_pending_cmd);
+
+       spin_unlock(&iwm->cmd_lock);
+
+       cmd->buf.start = cmd->buf.payload;
+       cmd->buf.len = 0;
+
+       if (lmac_cmd) {
+               cmd->buf.start -= sizeof(struct iwm_lmac_hdr);
+
+               lmac_cmd->seq_num = cpu_to_le16(cmd->seq_num);
+               lmac_cmd->count = cpu_to_le16(payload_size);
+
+               memcpy(&cmd->lmac_cmd, lmac_cmd, sizeof(*lmac_cmd));
+
+               umac_cmd->count = cpu_to_le16(sizeof(struct iwm_lmac_hdr));
+       } else
+               umac_cmd->count = 0;
+
+       umac_cmd->count = cpu_to_le16(payload_size +
+                                     le16_to_cpu(umac_cmd->count));
+       udma_cmd->count = cpu_to_le16(sizeof(struct iwm_umac_fw_cmd_hdr) +
+                                     le16_to_cpu(umac_cmd->count));
+
+       memcpy(&cmd->udma_cmd, udma_cmd, sizeof(*udma_cmd));
+       memcpy(&cmd->umac_cmd, umac_cmd, sizeof(*umac_cmd));
+}
+
+void iwm_cmd_flush(struct iwm_priv *iwm)
+{
+       struct iwm_wifi_cmd *wcmd, *wnext;
+       struct iwm_nonwifi_cmd *nwcmd, *nwnext;
+
+       list_for_each_entry_safe(wcmd, wnext, &iwm->wifi_pending_cmd, pending) {
+               list_del(&wcmd->pending);
+               kfree(wcmd);
+       }
+
+       list_for_each_entry_safe(nwcmd, nwnext, &iwm->nonwifi_pending_cmd,
+                                pending) {
+               list_del(&nwcmd->pending);
+               kfree(nwcmd);
+       }
+}
+
+struct iwm_wifi_cmd *iwm_get_pending_wifi_cmd(struct iwm_priv *iwm, u16 seq_num)
+{
+       struct iwm_wifi_cmd *cmd, *next;
+
+       list_for_each_entry_safe(cmd, next, &iwm->wifi_pending_cmd, pending)
+               if (cmd->seq_num == seq_num) {
+                       list_del(&cmd->pending);
+                       return cmd;
+               }
+
+       return NULL;
+}
+
+struct iwm_nonwifi_cmd *
+iwm_get_pending_nonwifi_cmd(struct iwm_priv *iwm, u8 seq_num, u8 cmd_opcode)
+{
+       struct iwm_nonwifi_cmd *cmd, *next;
+
+       list_for_each_entry_safe(cmd, next, &iwm->nonwifi_pending_cmd, pending)
+               if ((cmd->seq_num == seq_num) &&
+                   (cmd->udma_cmd.opcode == cmd_opcode) &&
+                   (cmd->resp_received)) {
+                       list_del(&cmd->pending);
+                       return cmd;
+               }
+
+       return NULL;
+}
+
+static void iwm_build_udma_nonwifi_hdr(struct iwm_priv *iwm,
+                                      struct iwm_udma_out_nonwifi_hdr *hdr,
+                                      struct iwm_udma_nonwifi_cmd *cmd)
+{
+       memset(hdr, 0, sizeof(*hdr));
+
+       SET_VAL32(hdr->cmd, UMAC_HDI_OUT_CMD_OPCODE, cmd->opcode);
+       SET_VAL32(hdr->cmd, UDMA_HDI_OUT_NW_CMD_RESP, cmd->resp);
+       SET_VAL32(hdr->cmd, UMAC_HDI_OUT_CMD_EOT, 1);
+       SET_VAL32(hdr->cmd, UDMA_HDI_OUT_NW_CMD_HANDLE_BY_HW,
+                 cmd->handle_by_hw);
+       SET_VAL32(hdr->cmd, UMAC_HDI_OUT_CMD_SIGNATURE, UMAC_HDI_OUT_SIGNATURE);
+       SET_VAL32(hdr->cmd, UDMA_HDI_OUT_CMD_NON_WIFI_HW_SEQ_NUM,
+                 le16_to_cpu(cmd->seq_num));
+
+       hdr->addr = cmd->addr;
+       hdr->op1_sz = cmd->op1_sz;
+       hdr->op2 = cmd->op2;
+}
+
+static int iwm_send_udma_nonwifi_cmd(struct iwm_priv *iwm,
+                                    struct iwm_nonwifi_cmd *cmd)
+{
+       struct iwm_udma_out_nonwifi_hdr *udma_hdr;
+       struct iwm_nonwifi_cmd_buff *buf;
+       struct iwm_udma_nonwifi_cmd *udma_cmd = &cmd->udma_cmd;
+
+       buf = &cmd->buf;
+
+       buf->start -= sizeof(struct iwm_umac_nonwifi_out_hdr);
+       buf->len += sizeof(struct iwm_umac_nonwifi_out_hdr);
+
+       udma_hdr = (struct iwm_udma_out_nonwifi_hdr *)(buf->start);
+
+       iwm_build_udma_nonwifi_hdr(iwm, udma_hdr, udma_cmd);
+
+       IWM_DBG_CMD(iwm, DBG,
+                   "Send UDMA nonwifi cmd: opcode = 0x%x, resp = 0x%x, "
+                   "hw = 0x%x, seqnum = %d, addr = 0x%x, op1_sz = 0x%x, "
+                   "op2 = 0x%x\n", udma_cmd->opcode, udma_cmd->resp,
+                   udma_cmd->handle_by_hw, cmd->seq_num, udma_cmd->addr,
+                   udma_cmd->op1_sz, udma_cmd->op2);
+
+       return iwm_bus_send_chunk(iwm, buf->start, buf->len);
+}
+
+void iwm_udma_wifi_hdr_set_eop(struct iwm_priv *iwm, u8 *buf, u8 eop)
+{
+       struct iwm_udma_out_wifi_hdr *hdr = (struct iwm_udma_out_wifi_hdr *)buf;
+
+       SET_VAL32(hdr->cmd, UMAC_HDI_OUT_CMD_EOT, eop);
+}
+
+void iwm_build_udma_wifi_hdr(struct iwm_priv *iwm,
+                            struct iwm_udma_out_wifi_hdr *hdr,
+                            struct iwm_udma_wifi_cmd *cmd)
+{
+       memset(hdr, 0, sizeof(*hdr));
+
+       SET_VAL32(hdr->cmd, UMAC_HDI_OUT_CMD_OPCODE, UMAC_HDI_OUT_OPCODE_WIFI);
+       SET_VAL32(hdr->cmd, UMAC_HDI_OUT_CMD_EOT, cmd->eop);
+       SET_VAL32(hdr->cmd, UMAC_HDI_OUT_CMD_SIGNATURE, UMAC_HDI_OUT_SIGNATURE);
+
+       SET_VAL32(hdr->meta_data, UMAC_HDI_OUT_BYTE_COUNT,
+                 le16_to_cpu(cmd->count));
+       SET_VAL32(hdr->meta_data, UMAC_HDI_OUT_CREDIT_GRP, cmd->credit_group);
+       SET_VAL32(hdr->meta_data, UMAC_HDI_OUT_RATID, cmd->ra_tid);
+       SET_VAL32(hdr->meta_data, UMAC_HDI_OUT_LMAC_OFFSET, cmd->lmac_offset);
+}
+
+void iwm_build_umac_hdr(struct iwm_priv *iwm,
+                       struct iwm_umac_fw_cmd_hdr *hdr,
+                       struct iwm_umac_cmd *cmd)
+{
+       memset(hdr, 0, sizeof(*hdr));
+
+       SET_VAL32(hdr->meta_data, UMAC_FW_CMD_BYTE_COUNT,
+                 le16_to_cpu(cmd->count));
+       SET_VAL32(hdr->meta_data, UMAC_FW_CMD_TX_STA_COLOR, cmd->color);
+       SET_VAL8(hdr->cmd.flags, UMAC_DEV_CMD_FLAGS_RESP_REQ, cmd->resp);
+
+       hdr->cmd.cmd = cmd->id;
+       hdr->cmd.seq_num = cmd->seq_num;
+}
+
+static int iwm_send_udma_wifi_cmd(struct iwm_priv *iwm,
+                                 struct iwm_wifi_cmd *cmd)
+{
+       struct iwm_umac_wifi_out_hdr *umac_hdr;
+       struct iwm_wifi_cmd_buff *buf;
+       struct iwm_udma_wifi_cmd *udma_cmd = &cmd->udma_cmd;
+       struct iwm_umac_cmd *umac_cmd = &cmd->umac_cmd;
+       int ret;
+
+       buf = &cmd->buf;
+
+       buf->start -= sizeof(struct iwm_umac_wifi_out_hdr);
+       buf->len += sizeof(struct iwm_umac_wifi_out_hdr);
+
+       umac_hdr = (struct iwm_umac_wifi_out_hdr *)(buf->start);
+
+       iwm_build_udma_wifi_hdr(iwm, &umac_hdr->hw_hdr, udma_cmd);
+       iwm_build_umac_hdr(iwm, &umac_hdr->sw_hdr, umac_cmd);
+
+       IWM_DBG_CMD(iwm, DBG,
+                   "Send UDMA wifi cmd: opcode = 0x%x, UMAC opcode = 0x%x, "
+                   "eop = 0x%x, count = 0x%x, credit_group = 0x%x, "
+                   "ra_tid = 0x%x, lmac_offset = 0x%x, seqnum = %d\n",
+                   UMAC_HDI_OUT_OPCODE_WIFI, umac_cmd->id,
+                   udma_cmd->eop, udma_cmd->count, udma_cmd->credit_group,
+                   udma_cmd->ra_tid, udma_cmd->lmac_offset, cmd->seq_num);
+
+       if (umac_cmd->id == UMAC_CMD_OPCODE_WIFI_PASS_THROUGH)
+               IWM_DBG_CMD(iwm, DBG, "\tLMAC opcode: 0x%x\n",
+                           cmd->lmac_cmd.id);
+
+       ret = iwm_tx_credit_alloc(iwm, udma_cmd->credit_group, buf->len);
+
+       /* We keep sending UMAC reset regardless of the command credits.
+        * The UMAC is supposed to be reset anyway and the Tx credits are
+        * reinitialized afterwards. If we are lucky, the reset could
+        * still be done even though we have run out of credits for the
+        * command pool at this moment.*/
+       if (ret && (umac_cmd->id != UMAC_CMD_OPCODE_RESET)) {
+               IWM_DBG_TX(iwm, DBG, "Failed to alloc tx credit for cmd %d\n",
+                          umac_cmd->id);
+               return ret;
+       }
+
+       return iwm_bus_send_chunk(iwm, buf->start, buf->len);
+}
+
+/* target_cmd a.k.a udma_nonwifi_cmd can be sent when UMAC is not available */
+int iwm_hal_send_target_cmd(struct iwm_priv *iwm,
+                           struct iwm_udma_nonwifi_cmd *udma_cmd,
+                           const void *payload)
+{
+       struct iwm_nonwifi_cmd *cmd;
+       int ret;
+
+       cmd = kzalloc(sizeof(struct iwm_nonwifi_cmd), GFP_KERNEL);
+       if (!cmd) {
+               IWM_ERR(iwm, "Couldn't alloc memory for hal cmd\n");
+               return -ENOMEM;
+       }
+
+       iwm_nonwifi_cmd_init(iwm, cmd, udma_cmd);
+
+       if (cmd->udma_cmd.opcode == UMAC_HDI_OUT_OPCODE_WRITE ||
+           cmd->udma_cmd.opcode == UMAC_HDI_OUT_OPCODE_WRITE_PERSISTENT) {
+               cmd->buf.len = le32_to_cpu(cmd->udma_cmd.op1_sz);
+               memcpy(&cmd->buf.payload, payload, cmd->buf.len);
+       }
+
+       ret = iwm_send_udma_nonwifi_cmd(iwm, cmd);
+
+       if (!udma_cmd->resp)
+               kfree(cmd);
+
+       if (ret < 0)
+               return ret;
+
+       return cmd->seq_num;
+}
+
+static void iwm_build_lmac_hdr(struct iwm_priv *iwm, struct iwm_lmac_hdr *hdr,
+                              struct iwm_lmac_cmd *cmd)
+{
+       memset(hdr, 0, sizeof(*hdr));
+
+       hdr->id = cmd->id;
+       hdr->flags = 0; /* Is this ever used? */
+       hdr->seq_num = cmd->seq_num;
+}
+
+/*
+ * iwm_hal_send_host_cmd(): sends commands to the UMAC or the LMAC.
+ * Sending command to the LMAC is equivalent to sending a
+ * regular UMAC command with the LMAC passtrough or the LMAC
+ * wrapper UMAC command IDs.
+ */
+int iwm_hal_send_host_cmd(struct iwm_priv *iwm,
+                         struct iwm_udma_wifi_cmd *udma_cmd,
+                         struct iwm_umac_cmd *umac_cmd,
+                         struct iwm_lmac_cmd *lmac_cmd,
+                         const void *payload, u16 payload_size)
+{
+       struct iwm_wifi_cmd *cmd;
+       struct iwm_lmac_hdr *hdr;
+       int lmac_hdr_len = 0;
+       int ret;
+
+       cmd = kzalloc(sizeof(struct iwm_wifi_cmd), GFP_KERNEL);
+       if (!cmd) {
+               IWM_ERR(iwm, "Couldn't alloc memory for wifi hal cmd\n");
+               return -ENOMEM;
+       }
+
+       iwm_wifi_cmd_init(iwm, cmd, udma_cmd, umac_cmd, lmac_cmd, payload_size);
+
+       if (lmac_cmd) {
+               hdr = (struct iwm_lmac_hdr *)(cmd->buf.start);
+
+               iwm_build_lmac_hdr(iwm, hdr, &cmd->lmac_cmd);
+               lmac_hdr_len = sizeof(struct iwm_lmac_hdr);
+       }
+
+       memcpy(cmd->buf.payload, payload, payload_size);
+       cmd->buf.len = le16_to_cpu(umac_cmd->count);
+
+       ret = iwm_send_udma_wifi_cmd(iwm, cmd);
+
+       /* We free the cmd if we're not expecting any response */
+       if (!umac_cmd->resp)
+               kfree(cmd);
+       return ret;
+}
+
+/*
+ * iwm_hal_send_umac_cmd(): This is a special case for
+ * iwm_hal_send_host_cmd() to send direct UMAC cmd (without
+ * LMAC involved).
+ */
+int iwm_hal_send_umac_cmd(struct iwm_priv *iwm,
+                         struct iwm_udma_wifi_cmd *udma_cmd,
+                         struct iwm_umac_cmd *umac_cmd,
+                         const void *payload, u16 payload_size)
+{
+       return iwm_hal_send_host_cmd(iwm, udma_cmd, umac_cmd, NULL,
+                                    payload, payload_size);
+}
diff --git a/drivers/net/wireless/iwmc3200wifi/hal.h b/drivers/net/wireless/iwmc3200wifi/hal.h
new file mode 100644 (file)
index 0000000..0adfdc8
--- /dev/null
@@ -0,0 +1,236 @@
+/*
+ * Intel Wireless Multicomm 3200 WiFi driver
+ *
+ * Copyright (C) 2009 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in
+ *     the documentation and/or other materials provided with the
+ *     distribution.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * Intel Corporation <ilw@linux.intel.com>
+ * Samuel Ortiz <samuel.ortiz@intel.com>
+ * Zhu Yi <yi.zhu@intel.com>
+ *
+ */
+
+#ifndef _IWM_HAL_H_
+#define _IWM_HAL_H_
+
+#include "umac.h"
+
+#define GET_VAL8(s, name)      ((s >> name##_POS) & name##_SEED)
+#define GET_VAL16(s, name)     ((le16_to_cpu(s) >> name##_POS) & name##_SEED)
+#define GET_VAL32(s, name)     ((le32_to_cpu(s) >> name##_POS) & name##_SEED)
+
+#define SET_VAL8(s, name, val)                                           \
+do {                                                                     \
+       s = (s & ~(name##_SEED << name##_POS)) |                          \
+           ((val & name##_SEED) << name##_POS);                          \
+} while (0)
+
+#define SET_VAL16(s, name, val)                                                  \
+do {                                                                     \
+       s = cpu_to_le16((le16_to_cpu(s) & ~(name##_SEED << name##_POS)) | \
+                       ((val & name##_SEED) << name##_POS));             \
+} while (0)
+
+#define SET_VAL32(s, name, val)                                                  \
+do {                                                                     \
+       s = cpu_to_le32((le32_to_cpu(s) & ~(name##_SEED << name##_POS)) | \
+                       ((val & name##_SEED) << name##_POS));             \
+} while (0)
+
+
+#define UDMA_UMAC_INIT {       .eop = 1,                                 \
+                               .credit_group = 0x4,                      \
+                               .ra_tid = UMAC_HDI_ACT_TBL_IDX_HOST_CMD,  \
+                               .lmac_offset = 0 }
+#define UDMA_LMAC_INIT {       .eop = 1,                                 \
+                               .credit_group = 0x4,                      \
+                               .ra_tid = UMAC_HDI_ACT_TBL_IDX_HOST_CMD,  \
+                               .lmac_offset = 4 }
+
+
+/* UDMA IN OP CODE -- cmd bits [3:0] */
+#define UDMA_IN_OPCODE_MASK                    0xF
+
+#define UDMA_IN_OPCODE_GENERAL_RESP            0x0
+#define UDMA_IN_OPCODE_READ_RESP               0x1
+#define UDMA_IN_OPCODE_WRITE_RESP              0x2
+#define UDMA_IN_OPCODE_PERS_WRITE_RESP         0x5
+#define UDMA_IN_OPCODE_PERS_READ_RESP          0x6
+#define UDMA_IN_OPCODE_RD_MDFY_WR_RESP         0x7
+#define UDMA_IN_OPCODE_EP_MNGMT_MSG            0x8
+#define UDMA_IN_OPCODE_CRDT_CHNG_MSG           0x9
+#define UDMA_IN_OPCODE_CNTRL_DATABASE_MSG      0xA
+#define UDMA_IN_OPCODE_SW_MSG                  0xB
+#define UDMA_IN_OPCODE_WIFI                    0xF
+#define UDMA_IN_OPCODE_WIFI_LMAC               0x1F
+#define UDMA_IN_OPCODE_WIFI_UMAC               0x2F
+
+/* HW API: udma_hdi_nonwifi API (OUT and IN) */
+
+/* iwm_udma_nonwifi_cmd request response -- bits [9:9] */
+#define UDMA_HDI_OUT_NW_CMD_RESP_POS           9
+#define UDMA_HDI_OUT_NW_CMD_RESP_SEED          0x1
+
+/* iwm_udma_nonwifi_cmd handle by HW -- bits [11:11] */
+#define UDMA_HDI_OUT_NW_CMD_HANDLE_BY_HW_POS   11
+#define UDMA_HDI_OUT_NW_CMD_HANDLE_BY_HW_SEED  0x1
+
+/* iwm_udma_nonwifi_cmd sequence-number -- bits [12:15] */
+#define UDMA_HDI_OUT_NW_CMD_SEQ_NUM_POS                12
+#define UDMA_HDI_OUT_NW_CMD_SEQ_NUM_SEED       0xF
+
+/* UDMA IN Non-WIFI HW sequence number -- bits [12:15] */
+#define UDMA_IN_NW_HW_SEQ_NUM_POS              12
+#define UDMA_IN_NW_HW_SEQ_NUM_SEED             0xF
+
+/* UDMA IN Non-WIFI HW signature -- bits [16:31] */
+#define UDMA_IN_NW_HW_SIG_POS                  16
+#define UDMA_IN_NW_HW_SIG_SEED                 0xFFFF
+
+/* fixed signature */
+#define UDMA_IN_NW_HW_SIG                      0xCBBC
+
+/* UDMA IN Non-WIFI HW block length -- bits [32:35] */
+#define UDMA_IN_NW_HW_LENGTH_SEED              0xF
+#define UDMA_IN_NW_HW_LENGTH_POS               32
+
+/* End of HW API: udma_hdi_nonwifi API (OUT and IN) */
+
+#define IWM_SDIO_FW_MAX_CHUNK_SIZE     2032
+#define IWM_MAX_WIFI_HEADERS_SIZE      32
+#define IWM_MAX_NONWIFI_HEADERS_SIZE   16
+#define IWM_MAX_NONWIFI_CMD_BUFF_SIZE  (IWM_SDIO_FW_MAX_CHUNK_SIZE - \
+                                        IWM_MAX_NONWIFI_HEADERS_SIZE)
+#define IWM_MAX_WIFI_CMD_BUFF_SIZE     (IWM_SDIO_FW_MAX_CHUNK_SIZE - \
+                                        IWM_MAX_WIFI_HEADERS_SIZE)
+
+#define IWM_HAL_CONCATENATE_BUF_SIZE   8192
+
+struct iwm_wifi_cmd_buff {
+       u16 len;
+       u8 *start;
+       u8 hdr[IWM_MAX_WIFI_HEADERS_SIZE];
+       u8 payload[IWM_MAX_WIFI_CMD_BUFF_SIZE];
+};
+
+struct iwm_nonwifi_cmd_buff {
+       u16 len;
+       u8 *start;
+       u8 hdr[IWM_MAX_NONWIFI_HEADERS_SIZE];
+       u8 payload[IWM_MAX_NONWIFI_CMD_BUFF_SIZE];
+};
+
+struct iwm_udma_nonwifi_cmd {
+       u8 opcode;
+       u8 eop;
+       u8 resp;
+       u8 handle_by_hw;
+       __le32 addr;
+       __le32 op1_sz;
+       __le32 op2;
+       __le16 seq_num;
+};
+
+struct iwm_udma_wifi_cmd {
+       __le16 count;
+       u8 eop;
+       u8 credit_group;
+       u8 ra_tid;
+       u8 lmac_offset;
+};
+
+struct iwm_umac_cmd {
+       u8 id;
+       __le16 count;
+       u8 resp;
+       __le16 seq_num;
+       u8 color;
+};
+
+struct iwm_lmac_cmd {
+       u8 id;
+       __le16 count;
+       u8 resp;
+       __le16 seq_num;
+};
+
+struct iwm_nonwifi_cmd {
+       u16 seq_num;
+       bool resp_received;
+       struct list_head pending;
+       struct iwm_udma_nonwifi_cmd udma_cmd;
+       struct iwm_umac_cmd umac_cmd;
+       struct iwm_lmac_cmd lmac_cmd;
+       struct iwm_nonwifi_cmd_buff buf;
+       u32 flags;
+};
+
+struct iwm_wifi_cmd {
+       u16 seq_num;
+       struct list_head pending;
+       struct iwm_udma_wifi_cmd udma_cmd;
+       struct iwm_umac_cmd umac_cmd;
+       struct iwm_lmac_cmd lmac_cmd;
+       struct iwm_wifi_cmd_buff buf;
+       u32 flags;
+};
+
+void iwm_cmd_flush(struct iwm_priv *iwm);
+
+struct iwm_wifi_cmd *iwm_get_pending_wifi_cmd(struct iwm_priv *iwm,
+                                             u16 seq_num);
+struct iwm_nonwifi_cmd *iwm_get_pending_nonwifi_cmd(struct iwm_priv *iwm,
+                                                   u8 seq_num, u8 cmd_opcode);
+
+
+int iwm_hal_send_target_cmd(struct iwm_priv *iwm,
+                           struct iwm_udma_nonwifi_cmd *ucmd,
+                           const void *payload);
+
+int iwm_hal_send_host_cmd(struct iwm_priv *iwm,
+                         struct iwm_udma_wifi_cmd *udma_cmd,
+                         struct iwm_umac_cmd *umac_cmd,
+                         struct iwm_lmac_cmd *lmac_cmd,
+                         const void *payload, u16 payload_size);
+
+int iwm_hal_send_umac_cmd(struct iwm_priv *iwm,
+                         struct iwm_udma_wifi_cmd *udma_cmd,
+                         struct iwm_umac_cmd *umac_cmd,
+                         const void *payload, u16 payload_size);
+
+u16 iwm_alloc_wifi_cmd_seq(struct iwm_priv *iwm);
+
+void iwm_udma_wifi_hdr_set_eop(struct iwm_priv *iwm, u8 *buf, u8 eop);
+void iwm_build_udma_wifi_hdr(struct iwm_priv *iwm,
+                            struct iwm_udma_out_wifi_hdr *hdr,
+                            struct iwm_udma_wifi_cmd *cmd);
+void iwm_build_umac_hdr(struct iwm_priv *iwm,
+                       struct iwm_umac_fw_cmd_hdr *hdr,
+                       struct iwm_umac_cmd *cmd);
+#endif /* _IWM_HAL_H_ */
diff --git a/drivers/net/wireless/iwmc3200wifi/iwm.h b/drivers/net/wireless/iwmc3200wifi/iwm.h
new file mode 100644 (file)
index 0000000..635c16e
--- /dev/null
@@ -0,0 +1,346 @@
+/*
+ * Intel Wireless Multicomm 3200 WiFi driver
+ *
+ * Copyright (C) 2009 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in
+ *     the documentation and/or other materials provided with the
+ *     distribution.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * Intel Corporation <ilw@linux.intel.com>
+ * Samuel Ortiz <samuel.ortiz@intel.com>
+ * Zhu Yi <yi.zhu@intel.com>
+ *
+ */
+
+#ifndef __IWM_H__
+#define __IWM_H__
+
+#include <linux/netdevice.h>
+#include <linux/wireless.h>
+#include <net/cfg80211.h>
+
+#include "debug.h"
+#include "hal.h"
+#include "umac.h"
+#include "lmac.h"
+#include "eeprom.h"
+
+#define IWM_COPYRIGHT "Copyright(c) 2009 Intel Corporation"
+#define IWM_AUTHOR "<ilw@linux.intel.com>"
+
+#define CONFIG_IWM_B0_HW_SUPPORT       1
+
+#define IWM_SRC_LMAC   UMAC_HDI_IN_SOURCE_FHRX
+#define IWM_SRC_UDMA   UMAC_HDI_IN_SOURCE_UDMA
+#define IWM_SRC_UMAC   UMAC_HDI_IN_SOURCE_FW
+#define IWM_SRC_NUM    3
+
+#define IWM_POWER_INDEX_MIN    0
+#define IWM_POWER_INDEX_MAX    5
+#define IWM_POWER_INDEX_DEFAULT        3
+
+struct iwm_conf {
+       u32 sdio_ior_timeout;
+       unsigned long init_calib_map;
+       unsigned long periodic_calib_map;
+       bool reset_on_fatal_err;
+       bool auto_connect;
+       bool wimax_not_present;
+       bool enable_qos;
+       u32 mode;
+
+       u32 power_index;
+       u32 frag_threshold;
+       u32 rts_threshold;
+       bool cts_to_self;
+
+       u32 assoc_timeout;
+       u32 roam_timeout;
+       u32 wireless_mode;
+       u32 coexist_mode;
+
+       u8 ibss_band;
+       u8 ibss_channel;
+
+       u8 mac_addr[ETH_ALEN];
+#ifdef CONFIG_IWM_B0_HW_SUPPORT
+       bool hw_b0;
+#endif
+};
+
+enum {
+       COEX_MODE_SA = 1,
+       COEX_MODE_XOR,
+       COEX_MODE_CM,
+       COEX_MODE_MAX,
+};
+
+struct iwm_if_ops;
+struct iwm_wifi_cmd;
+
+struct pool_entry {
+       int id;         /* group id */
+       int sid;        /* super group id */
+       int min_pages;  /* min capacity in pages */
+       int max_pages;  /* max capacity in pages */
+       int alloc_pages;        /* allocated # of pages. incresed by driver */
+       int total_freed_pages;  /* total freed # of pages. incresed by UMAC */
+};
+
+struct spool_entry {
+       int id;
+       int max_pages;
+       int alloc_pages;
+};
+
+struct iwm_tx_credit {
+       spinlock_t lock;
+       int pool_nr;
+       unsigned long full_pools_map; /* bitmap for # of filled tx pools */
+       struct pool_entry pools[IWM_MACS_OUT_GROUPS];
+       struct spool_entry spools[IWM_MACS_OUT_SGROUPS];
+};
+
+struct iwm_notif {
+       struct list_head pending;
+       u32 cmd_id;
+       void *cmd;
+       u8 src;
+       void *buf;
+       unsigned long buf_size;
+};
+
+struct iwm_sta_info {
+       u8 addr[ETH_ALEN];
+       bool valid;
+       bool qos;
+       u8 color;
+};
+
+struct iwm_tx_info {
+       u8 sta;
+       u8 color;
+       u8 tid;
+};
+
+struct iwm_rx_info {
+       unsigned long rx_size;
+       unsigned long rx_buf_size;
+};
+
+#define IWM_NUM_KEYS 4
+
+struct iwm_umac_key_hdr {
+       u8 mac[ETH_ALEN];
+       u8 key_idx;
+       u8 multicast; /* BCast encrypt & BCast decrypt of frames FROM mac */
+} __attribute__ ((packed));
+
+struct iwm_key {
+       struct iwm_umac_key_hdr hdr;
+       u8 in_use;
+       u8 alg;
+       u32 flags;
+       u8 tx_seq[IW_ENCODE_SEQ_MAX_SIZE];
+       u8 rx_seq[IW_ENCODE_SEQ_MAX_SIZE];
+       u8 key_len;
+       u8 key[32];
+};
+
+#define IWM_RX_ID_HASH  0xff
+#define IWM_RX_ID_GET_HASH(id) ((id) % IWM_RX_ID_HASH)
+
+#define IWM_STA_TABLE_NUM      16
+#define IWM_TX_LIST_SIZE       64
+#define IWM_RX_LIST_SIZE        256
+
+#define IWM_SCAN_ID_MAX 0xff
+
+#define IWM_STATUS_READY               0
+#define IWM_STATUS_SCANNING            1
+#define IWM_STATUS_SCAN_ABORTING       2
+#define IWM_STATUS_ASSOCIATING         3
+#define IWM_STATUS_ASSOCIATED          4
+
+#define IWM_RADIO_RFKILL_OFF           0
+#define IWM_RADIO_RFKILL_HW            1
+#define IWM_RADIO_RFKILL_SW            2
+
+struct iwm_tx_queue {
+       int id;
+       struct sk_buff_head queue;
+       struct workqueue_struct *wq;
+       struct work_struct worker;
+       u8 concat_buf[IWM_HAL_CONCATENATE_BUF_SIZE];
+       int concat_count;
+       u8 *concat_ptr;
+};
+
+/* Queues 0 ~ 3 for AC data, 5 for iPAN */
+#define IWM_TX_QUEUES          5
+#define IWM_TX_DATA_QUEUES     4
+#define IWM_TX_CMD_QUEUE       4
+
+struct iwm_bss_info {
+       struct list_head node;
+       struct cfg80211_bss *cfg_bss;
+       struct iwm_umac_notif_bss_info *bss;
+};
+
+typedef int (*iwm_handler)(struct iwm_priv *priv, u8 *buf,
+                          unsigned long buf_size, struct iwm_wifi_cmd *cmd);
+
+#define IWM_WATCHDOG_PERIOD    (6 * HZ)
+
+struct iwm_priv {
+       struct wireless_dev *wdev;
+       struct iwm_if_ops *bus_ops;
+
+       struct iwm_conf conf;
+
+       unsigned long status;
+       unsigned long radio;
+
+       struct list_head pending_notif;
+       wait_queue_head_t notif_queue;
+
+       wait_queue_head_t nonwifi_queue;
+
+       unsigned long calib_done_map;
+       struct {
+               u8 *buf;
+               u32 size;
+       } calib_res[CALIBRATION_CMD_NUM];
+
+       struct iwm_umac_profile *umac_profile;
+       bool umac_profile_active;
+
+       u8 bssid[ETH_ALEN];
+       u8 channel;
+       u16 rate;
+
+       struct iwm_sta_info sta_table[IWM_STA_TABLE_NUM];
+       struct list_head bss_list;
+
+       void (*nonwifi_rx_handlers[UMAC_HDI_IN_OPCODE_NONWIFI_MAX])
+       (struct iwm_priv *priv, u8 *buf, unsigned long buf_size);
+
+       const iwm_handler *umac_handlers;
+       const iwm_handler *lmac_handlers;
+       DECLARE_BITMAP(lmac_handler_map, LMAC_COMMAND_ID_NUM);
+       DECLARE_BITMAP(umac_handler_map, LMAC_COMMAND_ID_NUM);
+       DECLARE_BITMAP(udma_handler_map, LMAC_COMMAND_ID_NUM);
+
+       struct list_head wifi_pending_cmd;
+       struct list_head nonwifi_pending_cmd;
+       u16 wifi_seq_num;
+       u8 nonwifi_seq_num;
+       spinlock_t cmd_lock;
+
+       u32 core_enabled;
+
+       u8 scan_id;
+       struct cfg80211_scan_request *scan_request;
+
+       struct sk_buff_head rx_list;
+       struct list_head rx_tickets;
+       struct list_head rx_packets[IWM_RX_ID_HASH];
+       struct workqueue_struct *rx_wq;
+       struct work_struct rx_worker;
+
+       struct iwm_tx_credit tx_credit;
+       struct iwm_tx_queue txq[IWM_TX_QUEUES];
+
+       struct iwm_key keys[IWM_NUM_KEYS];
+       struct iwm_key *default_key;
+
+       wait_queue_head_t mlme_queue;
+
+       struct iw_statistics wstats;
+       struct delayed_work stats_request;
+
+       struct iwm_debugfs dbg;
+
+       u8 *eeprom;
+       struct timer_list watchdog;
+       struct work_struct reset_worker;
+       struct rfkill *rfkill;
+
+       char private[0] __attribute__((__aligned__(NETDEV_ALIGN)));
+};
+
+static inline void *iwm_private(struct iwm_priv *iwm)
+{
+       BUG_ON(!iwm);
+       return &iwm->private;
+}
+
+#define hw_to_iwm(h) (h->iwm)
+#define iwm_to_dev(i) (wiphy_dev(i->wdev->wiphy))
+#define iwm_to_wiphy(i) (i->wdev->wiphy)
+#define wiphy_to_iwm(w) (struct iwm_priv *)(wiphy_priv(w))
+#define iwm_to_wdev(i) (i->wdev)
+#define wdev_to_iwm(w) (struct iwm_priv *)(wdev_priv(w))
+#define iwm_to_ndev(i) (i->wdev->netdev)
+#define ndev_to_iwm(n) (wdev_to_iwm(n->ieee80211_ptr))
+#define skb_to_rx_info(s) ((struct iwm_rx_info *)(s->cb))
+#define skb_to_tx_info(s) ((struct iwm_tx_info *)s->cb)
+
+extern const struct iw_handler_def iwm_iw_handler_def;
+
+void *iwm_if_alloc(int sizeof_bus, struct device *dev,
+                  struct iwm_if_ops *if_ops);
+void iwm_if_free(struct iwm_priv *iwm);
+int iwm_mode_to_nl80211_iftype(int mode);
+int iwm_priv_init(struct iwm_priv *iwm);
+void iwm_reset(struct iwm_priv *iwm);
+void iwm_tx_credit_init_pools(struct iwm_priv *iwm,
+                             struct iwm_umac_notif_alive *alive);
+int iwm_tx_credit_alloc(struct iwm_priv *iwm, int id, int nb);
+int iwm_notif_send(struct iwm_priv *iwm, struct iwm_wifi_cmd *cmd,
+                  u8 cmd_id, u8 source, u8 *buf, unsigned long buf_size);
+int iwm_notif_handle(struct iwm_priv *iwm, u32 cmd, u8 source, long timeout);
+void iwm_init_default_profile(struct iwm_priv *iwm,
+                             struct iwm_umac_profile *profile);
+void iwm_link_on(struct iwm_priv *iwm);
+void iwm_link_off(struct iwm_priv *iwm);
+int iwm_up(struct iwm_priv *iwm);
+int iwm_down(struct iwm_priv *iwm);
+
+/* TX API */
+void iwm_tx_credit_inc(struct iwm_priv *iwm, int id, int total_freed_pages);
+void iwm_tx_worker(struct work_struct *work);
+int iwm_xmit_frame(struct sk_buff *skb, struct net_device *netdev);
+
+/* RX API */
+void iwm_rx_setup_handlers(struct iwm_priv *iwm);
+int iwm_rx_handle(struct iwm_priv *iwm, u8 *buf, unsigned long buf_size);
+int iwm_rx_handle_resp(struct iwm_priv *iwm, u8 *buf, unsigned long buf_size,
+                      struct iwm_wifi_cmd *cmd);
+void iwm_rx_free(struct iwm_priv *iwm);
+
+#endif
diff --git a/drivers/net/wireless/iwmc3200wifi/lmac.h b/drivers/net/wireless/iwmc3200wifi/lmac.h
new file mode 100644 (file)
index 0000000..db2e5ee
--- /dev/null
@@ -0,0 +1,457 @@
+/*
+ * Intel Wireless Multicomm 3200 WiFi driver
+ *
+ * Copyright (C) 2009 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in
+ *     the documentation and/or other materials provided with the
+ *     distribution.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * Intel Corporation <ilw@linux.intel.com>
+ * Samuel Ortiz <samuel.ortiz@intel.com>
+ * Zhu Yi <yi.zhu@intel.com>
+ *
+ */
+
+#ifndef __IWM_LMAC_H__
+#define __IWM_LMAC_H__
+
+struct iwm_lmac_hdr {
+       u8 id;
+       u8 flags;
+       __le16 seq_num;
+} __attribute__ ((packed));
+
+/* LMAC commands */
+#define CALIB_CFG_FLAG_SEND_COMPLETE_NTFY_AFTER_MSK  0x1
+
+struct iwm_lmac_cal_cfg_elt {
+       __le32 enable; /* 1 means LMAC needs to do something */
+       __le32 start;  /* 1 to start calibration, 0 to stop */
+       __le32 send_res; /* 1 for sending back results */
+       __le32 apply_res; /* 1 for applying calibration results to HW */
+       __le32 reserved;
+} __attribute__ ((packed));
+
+struct iwm_lmac_cal_cfg_status {
+       struct iwm_lmac_cal_cfg_elt init;
+       struct iwm_lmac_cal_cfg_elt periodic;
+       __le32 flags; /* CALIB_CFG_FLAG_SEND_COMPLETE_NTFY_AFTER_MSK */
+} __attribute__ ((packed));
+
+struct iwm_lmac_cal_cfg_cmd {
+       struct iwm_lmac_cal_cfg_status ucode_cfg;
+       struct iwm_lmac_cal_cfg_status driver_cfg;
+       __le32 reserved;
+} __attribute__ ((packed));
+
+struct iwm_lmac_cal_cfg_resp {
+       __le32 status;
+} __attribute__ ((packed));
+
+#define IWM_CARD_STATE_SW_HW_ENABLED   0x00
+#define IWM_CARD_STATE_HW_DISABLED     0x01
+#define IWM_CARD_STATE_SW_DISABLED     0x02
+#define IWM_CARD_STATE_CTKILL_DISABLED 0x04
+#define IWM_CARD_STATE_IS_RXON         0x10
+
+struct iwm_lmac_card_state {
+       __le32 flags;
+} __attribute__ ((packed));
+
+/**
+ * COEX_PRIORITY_TABLE_CMD
+ *
+ * Priority entry for each state
+ * Will keep two tables, for STA and WIPAN
+ */
+enum {
+       /* UN-ASSOCIATION PART */
+       COEX_UNASSOC_IDLE = 0,
+       COEX_UNASSOC_MANUAL_SCAN,
+       COEX_UNASSOC_AUTO_SCAN,
+
+       /* CALIBRATION */
+       COEX_CALIBRATION,
+       COEX_PERIODIC_CALIBRATION,
+
+       /* CONNECTION */
+       COEX_CONNECTION_ESTAB,
+
+       /* ASSOCIATION PART */
+       COEX_ASSOCIATED_IDLE,
+       COEX_ASSOC_MANUAL_SCAN,
+       COEX_ASSOC_AUTO_SCAN,
+       COEX_ASSOC_ACTIVE_LEVEL,
+
+       /* RF ON/OFF */
+       COEX_RF_ON,
+       COEX_RF_OFF,
+       COEX_STAND_ALONE_DEBUG,
+
+       /* IPNN */
+       COEX_IPAN_ASSOC_LEVEL,
+
+       /* RESERVED */
+       COEX_RSRVD1,
+       COEX_RSRVD2,
+
+       COEX_EVENTS_NUM
+};
+
+#define COEX_EVT_FLAG_MEDIUM_FREE_NTFY_MSK     0x1
+#define COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_MSK     0x2
+#define COEX_EVT_FLAG_DELAY_MEDIUM_FREE_NTFY_MSK       0x4
+
+struct coex_event {
+       u8 req_prio;
+       u8 win_med_prio;
+       u8 reserved;
+       u8 flags;
+} __attribute__ ((packed));
+
+#define COEX_FLAGS_STA_TABLE_VALID_MSK         0x1
+#define COEX_FLAGS_UNASSOC_WAKEUP_UMASK_MSK    0x4
+#define COEX_FLAGS_ASSOC_WAKEUP_UMASK_MSK      0x8
+#define COEX_FLAGS_COEX_ENABLE_MSK             0x80
+
+struct iwm_coex_prio_table_cmd {
+       u8 flags;
+       u8 reserved[3];
+       struct coex_event sta_prio[COEX_EVENTS_NUM];
+} __attribute__ ((packed));
+
+/* Coexistence definitions
+ *
+ * Constants to fill in the Priorities' Tables
+ * RP - Requested Priority
+ * WP - Win Medium Priority: priority assigned when the contention has been won
+ * FLAGS - Combination of COEX_EVT_FLAG_MEDIUM_FREE_NTFY_MSK and
+ *        COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_MSK
+ */
+
+#define COEX_UNASSOC_IDLE_FLAGS                0
+#define COEX_UNASSOC_MANUAL_SCAN_FLAGS (COEX_EVT_FLAG_MEDIUM_FREE_NTFY_MSK | \
+                                        COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_MSK)
+#define COEX_UNASSOC_AUTO_SCAN_FLAGS   (COEX_EVT_FLAG_MEDIUM_FREE_NTFY_MSK | \
+                                        COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_MSK)
+#define COEX_CALIBRATION_FLAGS         (COEX_EVT_FLAG_MEDIUM_FREE_NTFY_MSK | \
+                                        COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_MSK)
+#define COEX_PERIODIC_CALIBRATION_FLAGS        0
+/* COEX_CONNECTION_ESTAB: we need DELAY_MEDIUM_FREE_NTFY to let WiMAX
+ * disconnect from network. */
+#define COEX_CONNECTION_ESTAB_FLAGS (COEX_EVT_FLAG_MEDIUM_FREE_NTFY_MSK | \
+                                    COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_MSK | \
+                                    COEX_EVT_FLAG_DELAY_MEDIUM_FREE_NTFY_MSK)
+#define COEX_ASSOCIATED_IDLE_FLAGS     0
+#define COEX_ASSOC_MANUAL_SCAN_FLAGS   (COEX_EVT_FLAG_MEDIUM_FREE_NTFY_MSK | \
+                                        COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_MSK)
+#define COEX_ASSOC_AUTO_SCAN_FLAGS     (COEX_EVT_FLAG_MEDIUM_FREE_NTFY_MSK | \
+                                        COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_MSK)
+#define COEX_ASSOC_ACTIVE_LEVEL_FLAGS  0
+#define COEX_RF_ON_FLAGS               0
+#define COEX_RF_OFF_FLAGS              0
+#define COEX_STAND_ALONE_DEBUG_FLAGS   (COEX_EVT_FLAG_MEDIUM_FREE_NTFY_MSK | \
+                                        COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_MSK)
+#define COEX_IPAN_ASSOC_LEVEL_FLAGS (COEX_EVT_FLAG_MEDIUM_FREE_NTFY_MSK | \
+                                    COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_MSK | \
+                                    COEX_EVT_FLAG_DELAY_MEDIUM_FREE_NTFY_MSK)
+#define COEX_RSRVD1_FLAGS              0
+#define COEX_RSRVD2_FLAGS              0
+/* XOR_RF_ON is the event wrapping all radio ownership. We need
+ * DELAY_MEDIUM_FREE_NTFY to let WiMAX disconnect from network. */
+#define COEX_XOR_RF_ON_FLAGS       (COEX_EVT_FLAG_MEDIUM_FREE_NTFY_MSK | \
+                                    COEX_EVT_FLAG_MEDIUM_ACTV_NTFY_MSK | \
+                                    COEX_EVT_FLAG_DELAY_MEDIUM_FREE_NTFY_MSK)
+
+/* LMAC OP CODES */
+#define REPLY_PAD                      0x0
+#define REPLY_ALIVE                    0x1
+#define REPLY_ERROR                    0x2
+#define REPLY_ECHO                     0x3
+#define REPLY_HALT                     0x6
+
+/* RXON state commands */
+#define REPLY_RX_ON                    0x10
+#define REPLY_RX_ON_ASSOC              0x11
+#define REPLY_RX_OFF                   0x12
+#define REPLY_QOS_PARAM                        0x13
+#define REPLY_RX_ON_TIMING             0x14
+#define REPLY_INTERNAL_QOS_PARAM       0x15
+#define REPLY_RX_INT_TIMEOUT_CNFG      0x16
+#define REPLY_NULL                     0x17
+
+/* Multi-Station support */
+#define REPLY_ADD_STA                  0x18
+#define REPLY_REMOVE_STA               0x19
+#define REPLY_RESET_ALL_STA            0x1a
+
+/* RX, TX */
+#define REPLY_ALM_RX                   0x1b
+#define REPLY_TX                       0x1c
+#define REPLY_TXFIFO_FLUSH             0x1e
+
+/* MISC commands */
+#define REPLY_MGMT_MCAST_KEY           0x1f
+#define REPLY_WEPKEY                   0x20
+#define REPLY_INIT_IV                  0x21
+#define REPLY_WRITE_MIB                        0x22
+#define REPLY_READ_MIB                 0x23
+#define REPLY_RADIO_FE                 0x24
+#define REPLY_TXFIFO_CFG               0x25
+#define REPLY_WRITE_READ               0x26
+#define REPLY_INSTALL_SEC_KEY          0x27
+
+
+#define REPLY_RATE_SCALE               0x47
+#define REPLY_LEDS_CMD                 0x48
+#define REPLY_TX_LINK_QUALITY_CMD      0x4e
+#define REPLY_ANA_MIB_OVERRIDE_CMD     0x4f
+#define REPLY_WRITE2REG_CMD            0x50
+
+/* winfi-wifi coexistence */
+#define COEX_PRIORITY_TABLE_CMD                0x5a
+#define COEX_MEDIUM_NOTIFICATION       0x5b
+#define COEX_EVENT_CMD                 0x5c
+
+/* more Protocol and Protocol-test commands */
+#define REPLY_MAX_SLEEP_TIME_CMD       0x61
+#define CALIBRATION_CFG_CMD            0x65
+#define CALIBRATION_RES_NOTIFICATION   0x66
+#define CALIBRATION_COMPLETE_NOTIFICATION      0x67
+
+/* Measurements */
+#define REPLY_QUIET_CMD                        0x71
+#define REPLY_CHANNEL_SWITCH           0x72
+#define CHANNEL_SWITCH_NOTIFICATION    0x73
+
+#define REPLY_SPECTRUM_MEASUREMENT_CMD 0x74
+#define SPECTRUM_MEASURE_NOTIFICATION  0x75
+#define REPLY_MEASUREMENT_ABORT_CMD    0x76
+
+/* Power Management */
+#define POWER_TABLE_CMD                        0x77
+#define SAVE_RESTORE_ADRESS_CMD                0x78
+#define REPLY_WATERMARK_CMD            0x79
+#define PM_DEBUG_STATISTIC_NOTIFIC     0x7B
+#define PD_FLUSH_N_NOTIFICATION                0x7C
+
+/* Scan commands and notifications */
+#define REPLY_SCAN_REQUEST_CMD         0x80
+#define REPLY_SCAN_ABORT_CMD           0x81
+#define SCAN_START_NOTIFICATION                0x82
+#define SCAN_RESULTS_NOTIFICATION      0x83
+#define SCAN_COMPLETE_NOTIFICATION     0x84
+
+/* Continuous TX commands */
+#define REPLY_CONT_TX_CMD              0x85
+#define END_OF_CONT_TX_NOTIFICATION    0x86
+
+/* Timer/Eeprom commands */
+#define TIMER_CMD                      0x87
+#define EEPROM_WRITE_CMD               0x88
+
+/* PAPD commands */
+#define FEEDBACK_REQUEST_NOTIFICATION  0x8b
+#define REPLY_CW_CMD                   0x8c
+
+/* IBSS/AP commands Continue */
+#define BEACON_NOTIFICATION            0x90
+#define REPLY_TX_BEACON                        0x91
+#define REPLY_REQUEST_ATIM             0x93
+#define WHO_IS_AWAKE_NOTIFICATION      0x94
+#define TX_PWR_DBM_LIMIT_CMD           0x95
+#define QUIET_NOTIFICATION             0x96
+#define TX_PWR_TABLE_CMD               0x97
+#define TX_ANT_CONFIGURATION_CMD       0x98
+#define MEASURE_ABORT_NOTIFICATION     0x99
+#define REPLY_CALIBRATION_TUNE         0x9a
+
+/* bt config command */
+#define REPLY_BT_CONFIG                        0x9b
+#define REPLY_STATISTICS_CMD           0x9c
+#define STATISTICS_NOTIFICATION                0x9d
+
+/* RF-KILL commands and notifications */
+#define REPLY_CARD_STATE_CMD           0xa0
+#define CARD_STATE_NOTIFICATION                0xa1
+
+/* Missed beacons notification */
+#define MISSED_BEACONS_NOTIFICATION    0xa2
+#define MISSED_BEACONS_NOTIFICATION_TH_CMD     0xa3
+
+#define REPLY_CT_KILL_CONFIG_CMD       0xa4
+
+/* HD commands and notifications */
+#define REPLY_HD_PARAMS_CMD            0xa6
+#define HD_PARAMS_NOTIFICATION         0xa7
+#define SENSITIVITY_CMD                        0xa8
+#define U_APSD_PARAMS_CMD              0xa9
+#define NOISY_PLATFORM_CMD             0xaa
+#define ILLEGAL_CMD                    0xac
+#define REPLY_PHY_CALIBRATION_CMD      0xb0
+#define REPLAY_RX_GAIN_CALIB_CMD       0xb1
+
+/* WiPAN commands */
+#define REPLY_WIPAN_PARAMS_CMD         0xb2
+#define REPLY_WIPAN_RX_ON_CMD          0xb3
+#define REPLY_WIPAN_RX_ON_TIMING       0xb4
+#define REPLY_WIPAN_TX_PWR_TABLE_CMD   0xb5
+#define REPLY_WIPAN_RXON_ASSOC_CMD     0xb6
+#define REPLY_WIPAN_QOS_PARAM          0xb7
+#define WIPAN_REPLY_WEPKEY             0xb8
+
+/* BeamForming commands */
+#define BEAMFORMER_CFG_CMD             0xba
+#define BEAMFORMEE_NOTIFICATION                0xbb
+
+/* TGn new Commands */
+#define REPLY_RX_PHY_CMD               0xc0
+#define REPLY_RX_MPDU_CMD              0xc1
+#define REPLY_MULTICAST_HASH           0xc2
+#define REPLY_KDR_RX                   0xc3
+#define REPLY_RX_DSP_EXT_INFO          0xc4
+#define REPLY_COMPRESSED_BA            0xc5
+
+/* PNC commands */
+#define PNC_CONFIG_CMD                 0xc8
+#define PNC_UPDATE_TABLE_CMD           0xc9
+#define XVT_GENERAL_CTRL_CMD           0xca
+#define REPLY_LEGACY_RADIO_FE          0xdd
+
+/* WoWLAN commands */
+#define WOWLAN_PATTERNS                        0xe0
+#define WOWLAN_WAKEUP_FILTER           0xe1
+#define WOWLAN_TSC_RSC_PARAM           0xe2
+#define WOWLAN_TKIP_PARAM              0xe3
+#define WOWLAN_KEK_KCK_MATERIAL                0xe4
+#define WOWLAN_GET_STATUSES            0xe5
+#define WOWLAN_TX_POWER_PER_DB         0xe6
+#define REPLY_WOWLAN_GET_STATUSES       WOWLAN_GET_STATUSES
+
+#define REPLY_DEBUG_CMD                        0xf0
+#define REPLY_DSP_DEBUG_CMD            0xf1
+#define REPLY_DEBUG_MONITOR_CMD                0xf2
+#define REPLY_DEBUG_XVT_CMD            0xf3
+#define REPLY_DEBUG_DC_CALIB           0xf4
+#define REPLY_DYNAMIC_BP               0xf5
+
+/* General purpose Commands */
+#define REPLY_GP1_CMD                  0xfa
+#define REPLY_GP2_CMD                  0xfb
+#define REPLY_GP3_CMD                  0xfc
+#define REPLY_GP4_CMD                  0xfd
+#define REPLY_REPLAY_WRAPPER           0xfe
+#define REPLY_FRAME_DURATION_CALC_CMD  0xff
+
+#define LMAC_COMMAND_ID_MAX            0xff
+#define LMAC_COMMAND_ID_NUM            (LMAC_COMMAND_ID_MAX + 1)
+
+
+/* Calibration */
+
+enum {
+       PHY_CALIBRATE_DC_CMD                    = 0,
+       PHY_CALIBRATE_LO_CMD                    = 1,
+       PHY_CALIBRATE_RX_BB_CMD                 = 2,
+       PHY_CALIBRATE_TX_IQ_CMD                 = 3,
+       PHY_CALIBRATE_RX_IQ_CMD                 = 4,
+       PHY_CALIBRATION_NOISE_CMD               = 5,
+       PHY_CALIBRATE_AGC_TABLE_CMD             = 6,
+       PHY_CALIBRATE_CRYSTAL_FRQ_CMD           = 7,
+       PHY_CALIBRATE_OPCODES_NUM,
+       SHILOH_PHY_CALIBRATE_DC_CMD             = 8,
+       SHILOH_PHY_CALIBRATE_LO_CMD             = 9,
+       SHILOH_PHY_CALIBRATE_RX_BB_CMD          = 10,
+       SHILOH_PHY_CALIBRATE_TX_IQ_CMD          = 11,
+       SHILOH_PHY_CALIBRATE_RX_IQ_CMD          = 12,
+       SHILOH_PHY_CALIBRATION_NOISE_CMD        = 13,
+       SHILOH_PHY_CALIBRATE_AGC_TABLE_CMD      = 14,
+       SHILOH_PHY_CALIBRATE_CRYSTAL_FRQ_CMD    = 15,
+       SHILOH_PHY_CALIBRATE_BASE_BAND_CMD      = 16,
+       SHILOH_PHY_CALIBRATE_TXIQ_PERIODIC_CMD  = 17,
+       CALIBRATION_CMD_NUM,
+};
+
+struct iwm_lmac_calib_hdr {
+       u8 opcode;
+       u8 first_grp;
+       u8 grp_num;
+       u8 all_data_valid;
+} __attribute__ ((packed));
+
+#define IWM_LMAC_CALIB_FREQ_GROUPS_NR  7
+#define IWM_CALIB_FREQ_GROUPS_NR       5
+#define IWM_CALIB_DC_MODES_NR          12
+
+struct iwm_calib_rxiq_entry {
+       u16 ptam_postdist_ars;
+       u16 ptam_postdist_arc;
+} __attribute__ ((packed));
+
+struct iwm_calib_rxiq_group {
+       struct iwm_calib_rxiq_entry mode[IWM_CALIB_DC_MODES_NR];
+} __attribute__ ((packed));
+
+struct iwm_lmac_calib_rxiq {
+       struct iwm_calib_rxiq_group group[IWM_LMAC_CALIB_FREQ_GROUPS_NR];
+} __attribute__ ((packed));
+
+struct iwm_calib_rxiq {
+       struct iwm_lmac_calib_hdr hdr;
+       struct iwm_calib_rxiq_group group[IWM_CALIB_FREQ_GROUPS_NR];
+} __attribute__ ((packed));
+
+#define LMAC_STA_ID_SEED       0x0f
+#define LMAC_STA_ID_POS                0
+
+#define LMAC_STA_COLOR_SEED    0x7
+#define LMAC_STA_COLOR_POS     4
+
+struct iwm_lmac_power_report {
+       u8 pa_status;
+       u8 pa_integ_res_A[3];
+       u8 pa_integ_res_B[3];
+       u8 pa_integ_res_C[3];
+} __attribute__ ((packed));
+
+struct iwm_lmac_tx_resp {
+       u8 frame_cnt; /* 1-no aggregation, greater then 1 - aggregation */
+       u8 bt_kill_cnt;
+       __le16 retry_cnt;
+       __le32 initial_tx_rate;
+       __le16 wireless_media_time;
+       struct iwm_lmac_power_report power_report;
+       __le32 tfd_info;
+       __le16 seq_ctl;
+       __le16 byte_cnt;
+       u8 tlc_rate_info;
+       u8 ra_tid;
+       __le16 frame_ctl;
+       __le32 status;
+} __attribute__ ((packed));
+
+#endif
diff --git a/drivers/net/wireless/iwmc3200wifi/main.c b/drivers/net/wireless/iwmc3200wifi/main.c
new file mode 100644 (file)
index 0000000..6a2640f
--- /dev/null
@@ -0,0 +1,680 @@
+/*
+ * Intel Wireless Multicomm 3200 WiFi driver
+ *
+ * Copyright (C) 2009 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in
+ *     the documentation and/or other materials provided with the
+ *     distribution.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * Intel Corporation <ilw@linux.intel.com>
+ * Samuel Ortiz <samuel.ortiz@intel.com>
+ * Zhu Yi <yi.zhu@intel.com>
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <linux/ieee80211.h>
+#include <linux/wireless.h>
+
+#include "iwm.h"
+#include "debug.h"
+#include "bus.h"
+#include "umac.h"
+#include "commands.h"
+#include "hal.h"
+#include "fw.h"
+#include "rx.h"
+
+static struct iwm_conf def_iwm_conf = {
+
+       .sdio_ior_timeout       = 5000,
+       .init_calib_map         = BIT(PHY_CALIBRATE_DC_CMD)     |
+                                 BIT(PHY_CALIBRATE_LO_CMD)     |
+                                 BIT(PHY_CALIBRATE_TX_IQ_CMD)  |
+                                 BIT(PHY_CALIBRATE_RX_IQ_CMD),
+       .periodic_calib_map     = BIT(PHY_CALIBRATE_DC_CMD)     |
+                                 BIT(PHY_CALIBRATE_LO_CMD)     |
+                                 BIT(PHY_CALIBRATE_TX_IQ_CMD)  |
+                                 BIT(PHY_CALIBRATE_RX_IQ_CMD)  |
+                                 BIT(SHILOH_PHY_CALIBRATE_BASE_BAND_CMD),
+       .reset_on_fatal_err     = 1,
+       .auto_connect           = 1,
+       .wimax_not_present      = 0,
+       .enable_qos             = 1,
+       .mode                   = UMAC_MODE_BSS,
+
+       /* UMAC configuration */
+       .power_index            = 0,
+       .frag_threshold         = IEEE80211_MAX_FRAG_THRESHOLD,
+       .rts_threshold          = IEEE80211_MAX_RTS_THRESHOLD,
+       .cts_to_self            = 0,
+
+       .assoc_timeout          = 2,
+       .roam_timeout           = 10,
+       .wireless_mode          = WIRELESS_MODE_11A | WIRELESS_MODE_11G,
+       .coexist_mode           = COEX_MODE_CM,
+
+       /* IBSS */
+       .ibss_band              = UMAC_BAND_2GHZ,
+       .ibss_channel           = 1,
+
+       .mac_addr               = {0x00, 0x02, 0xb3, 0x01, 0x02, 0x03},
+};
+
+static int modparam_reset;
+module_param_named(reset, modparam_reset, bool, 0644);
+MODULE_PARM_DESC(reset, "reset on firmware errors (default 0 [not reset])");
+
+int iwm_mode_to_nl80211_iftype(int mode)
+{
+       switch (mode) {
+       case UMAC_MODE_BSS:
+               return NL80211_IFTYPE_STATION;
+       case UMAC_MODE_IBSS:
+               return NL80211_IFTYPE_ADHOC;
+       default:
+               return NL80211_IFTYPE_UNSPECIFIED;
+       }
+
+       return 0;
+}
+
+static void iwm_statistics_request(struct work_struct *work)
+{
+       struct iwm_priv *iwm =
+               container_of(work, struct iwm_priv, stats_request.work);
+
+       iwm_send_umac_stats_req(iwm, 0);
+}
+
+static void iwm_reset_worker(struct work_struct *work)
+{
+       struct iwm_priv *iwm;
+       struct iwm_umac_profile *profile = NULL;
+       int uninitialized_var(ret), retry = 0;
+
+       iwm = container_of(work, struct iwm_priv, reset_worker);
+
+       if (iwm->umac_profile_active) {
+               profile = kmalloc(sizeof(struct iwm_umac_profile), GFP_KERNEL);
+               if (profile)
+                       memcpy(profile, iwm->umac_profile, sizeof(*profile));
+               else
+                       IWM_ERR(iwm, "Couldn't alloc memory for profile\n");
+       }
+
+       iwm_down(iwm);
+
+       while (retry++ < 3) {
+               ret = iwm_up(iwm);
+               if (!ret)
+                       break;
+
+               schedule_timeout_uninterruptible(10 * HZ);
+       }
+
+       if (ret) {
+               IWM_WARN(iwm, "iwm_up() failed: %d\n", ret);
+
+               kfree(profile);
+               return;
+       }
+
+       if (profile) {
+               IWM_DBG_MLME(iwm, DBG, "Resend UMAC profile\n");
+               memcpy(iwm->umac_profile, profile, sizeof(*profile));
+               iwm_send_mlme_profile(iwm);
+               kfree(profile);
+       }
+}
+
+static void iwm_watchdog(unsigned long data)
+{
+       struct iwm_priv *iwm = (struct iwm_priv *)data;
+
+       IWM_WARN(iwm, "Watchdog expired: UMAC stalls!\n");
+
+       if (modparam_reset)
+               schedule_work(&iwm->reset_worker);
+}
+
+int iwm_priv_init(struct iwm_priv *iwm)
+{
+       int i;
+       char name[32];
+
+       iwm->status = 0;
+       INIT_LIST_HEAD(&iwm->pending_notif);
+       init_waitqueue_head(&iwm->notif_queue);
+       init_waitqueue_head(&iwm->nonwifi_queue);
+       init_waitqueue_head(&iwm->mlme_queue);
+       memcpy(&iwm->conf, &def_iwm_conf, sizeof(struct iwm_conf));
+       spin_lock_init(&iwm->tx_credit.lock);
+       INIT_LIST_HEAD(&iwm->wifi_pending_cmd);
+       INIT_LIST_HEAD(&iwm->nonwifi_pending_cmd);
+       iwm->wifi_seq_num = UMAC_WIFI_SEQ_NUM_BASE;
+       iwm->nonwifi_seq_num = UMAC_NONWIFI_SEQ_NUM_BASE;
+       spin_lock_init(&iwm->cmd_lock);
+       iwm->scan_id = 1;
+       INIT_DELAYED_WORK(&iwm->stats_request, iwm_statistics_request);
+       INIT_WORK(&iwm->reset_worker, iwm_reset_worker);
+       INIT_LIST_HEAD(&iwm->bss_list);
+
+       skb_queue_head_init(&iwm->rx_list);
+       INIT_LIST_HEAD(&iwm->rx_tickets);
+       for (i = 0; i < IWM_RX_ID_HASH; i++)
+               INIT_LIST_HEAD(&iwm->rx_packets[i]);
+
+       INIT_WORK(&iwm->rx_worker, iwm_rx_worker);
+
+       iwm->rx_wq = create_singlethread_workqueue(KBUILD_MODNAME "_rx");
+       if (!iwm->rx_wq)
+               return -EAGAIN;
+
+       for (i = 0; i < IWM_TX_QUEUES; i++) {
+               INIT_WORK(&iwm->txq[i].worker, iwm_tx_worker);
+               snprintf(name, 32, KBUILD_MODNAME "_tx_%d", i);
+               iwm->txq[i].id = i;
+               iwm->txq[i].wq = create_singlethread_workqueue(name);
+               if (!iwm->txq[i].wq)
+                       return -EAGAIN;
+
+               skb_queue_head_init(&iwm->txq[i].queue);
+       }
+
+       for (i = 0; i < IWM_NUM_KEYS; i++)
+               memset(&iwm->keys[i], 0, sizeof(struct iwm_key));
+
+       iwm->default_key = NULL;
+
+       init_timer(&iwm->watchdog);
+       iwm->watchdog.function = iwm_watchdog;
+       iwm->watchdog.data = (unsigned long)iwm;
+
+       return 0;
+}
+
+/*
+ * We reset all the structures, and we reset the UMAC.
+ * After calling this routine, you're expected to reload
+ * the firmware.
+ */
+void iwm_reset(struct iwm_priv *iwm)
+{
+       struct iwm_notif *notif, *next;
+
+       if (test_bit(IWM_STATUS_READY, &iwm->status))
+               iwm_target_reset(iwm);
+
+       iwm->status = 0;
+       iwm->scan_id = 1;
+
+       list_for_each_entry_safe(notif, next, &iwm->pending_notif, pending) {
+               list_del(&notif->pending);
+               kfree(notif->buf);
+               kfree(notif);
+       }
+
+       iwm_cmd_flush(iwm);
+
+       flush_workqueue(iwm->rx_wq);
+
+       iwm_link_off(iwm);
+}
+
+/*
+ * Notification code:
+ *
+ * We're faced with the following issue: Any host command can
+ * have an answer or not, and if there's an answer to expect,
+ * it can be treated synchronously or asynchronously.
+ * To work around the synchronous answer case, we implemented
+ * our notification mechanism.
+ * When a code path needs to wait for a command response
+ * synchronously, it calls notif_handle(), which waits for the
+ * right notification to show up, and then process it. Before
+ * starting to wait, it registered as a waiter for this specific
+ * answer (by toggling a bit in on of the handler_map), so that
+ * the rx code knows that it needs to send a notification to the
+ * waiting processes. It does so by calling iwm_notif_send(),
+ * which adds the notification to the pending notifications list,
+ * and then wakes the waiting processes up.
+ */
+int iwm_notif_send(struct iwm_priv *iwm, struct iwm_wifi_cmd *cmd,
+                  u8 cmd_id, u8 source, u8 *buf, unsigned long buf_size)
+{
+       struct iwm_notif *notif;
+
+       notif = kzalloc(sizeof(struct iwm_notif), GFP_KERNEL);
+       if (!notif) {
+               IWM_ERR(iwm, "Couldn't alloc memory for notification\n");
+               return -ENOMEM;
+       }
+
+       INIT_LIST_HEAD(&notif->pending);
+       notif->cmd = cmd;
+       notif->cmd_id = cmd_id;
+       notif->src = source;
+       notif->buf = kzalloc(buf_size, GFP_KERNEL);
+       if (!notif->buf) {
+               IWM_ERR(iwm, "Couldn't alloc notification buffer\n");
+               kfree(notif);
+               return -ENOMEM;
+       }
+       notif->buf_size = buf_size;
+       memcpy(notif->buf, buf, buf_size);
+       list_add_tail(&notif->pending, &iwm->pending_notif);
+
+       wake_up_interruptible(&iwm->notif_queue);
+
+       return 0;
+}
+
+static struct iwm_notif *iwm_notif_find(struct iwm_priv *iwm, u32 cmd,
+                                       u8 source)
+{
+       struct iwm_notif *notif, *next;
+
+       list_for_each_entry_safe(notif, next, &iwm->pending_notif, pending) {
+               if ((notif->cmd_id == cmd) && (notif->src == source)) {
+                       list_del(&notif->pending);
+                       return notif;
+               }
+       }
+
+       return NULL;
+}
+
+static struct iwm_notif *iwm_notif_wait(struct iwm_priv *iwm, u32 cmd,
+                                       u8 source, long timeout)
+{
+       int ret;
+       struct iwm_notif *notif;
+       unsigned long *map = NULL;
+
+       switch (source) {
+       case IWM_SRC_LMAC:
+               map = &iwm->lmac_handler_map[0];
+               break;
+       case IWM_SRC_UMAC:
+               map = &iwm->umac_handler_map[0];
+               break;
+       case IWM_SRC_UDMA:
+               map = &iwm->udma_handler_map[0];
+               break;
+       }
+
+       set_bit(cmd, map);
+
+       ret = wait_event_interruptible_timeout(iwm->notif_queue,
+                        ((notif = iwm_notif_find(iwm, cmd, source)) != NULL),
+                                              timeout);
+       clear_bit(cmd, map);
+
+       if (!ret)
+               return NULL;
+
+       return notif;
+}
+
+int iwm_notif_handle(struct iwm_priv *iwm, u32 cmd, u8 source, long timeout)
+{
+       int ret;
+       struct iwm_notif *notif;
+
+       notif = iwm_notif_wait(iwm, cmd, source, timeout);
+       if (!notif)
+               return -ETIME;
+
+       ret = iwm_rx_handle_resp(iwm, notif->buf, notif->buf_size, notif->cmd);
+       kfree(notif->buf);
+       kfree(notif);
+
+       return ret;
+}
+
+static int iwm_config_boot_params(struct iwm_priv *iwm)
+{
+       struct iwm_udma_nonwifi_cmd target_cmd;
+       int ret;
+
+       /* check Wimax is off and config debug monitor */
+       if (iwm->conf.wimax_not_present) {
+               u32 data1 = 0x1f;
+               u32 addr1 = 0x606BE258;
+
+               u32 data2_set = 0x0;
+               u32 data2_clr = 0x1;
+               u32 addr2 = 0x606BE100;
+
+               u32 data3 = 0x1;
+               u32 addr3 = 0x606BEC00;
+
+               target_cmd.resp = 0;
+               target_cmd.handle_by_hw = 0;
+               target_cmd.eop = 1;
+
+               target_cmd.opcode = UMAC_HDI_OUT_OPCODE_WRITE;
+               target_cmd.addr = cpu_to_le32(addr1);
+               target_cmd.op1_sz = cpu_to_le32(sizeof(u32));
+               target_cmd.op2 = 0;
+
+               ret = iwm_hal_send_target_cmd(iwm, &target_cmd, &data1);
+               if (ret < 0) {
+                       IWM_ERR(iwm, "iwm_hal_send_target_cmd failed\n");
+                       return ret;
+               }
+
+               target_cmd.opcode = UMAC_HDI_OUT_OPCODE_READ_MODIFY_WRITE;
+               target_cmd.addr = cpu_to_le32(addr2);
+               target_cmd.op1_sz = cpu_to_le32(data2_set);
+               target_cmd.op2 = cpu_to_le32(data2_clr);
+
+               ret = iwm_hal_send_target_cmd(iwm, &target_cmd, &data1);
+               if (ret < 0) {
+                       IWM_ERR(iwm, "iwm_hal_send_target_cmd failed\n");
+                       return ret;
+               }
+
+               target_cmd.opcode = UMAC_HDI_OUT_OPCODE_WRITE;
+               target_cmd.addr = cpu_to_le32(addr3);
+               target_cmd.op1_sz = cpu_to_le32(sizeof(u32));
+               target_cmd.op2 = 0;
+
+               ret = iwm_hal_send_target_cmd(iwm, &target_cmd, &data3);
+               if (ret < 0) {
+                       IWM_ERR(iwm, "iwm_hal_send_target_cmd failed\n");
+                       return ret;
+               }
+       }
+
+       return 0;
+}
+
+void iwm_init_default_profile(struct iwm_priv *iwm,
+                             struct iwm_umac_profile *profile)
+{
+       memset(profile, 0, sizeof(struct iwm_umac_profile));
+
+       profile->sec.auth_type = UMAC_AUTH_TYPE_OPEN;
+       profile->sec.flags = UMAC_SEC_FLG_LEGACY_PROFILE;
+       profile->sec.ucast_cipher = UMAC_CIPHER_TYPE_NONE;
+       profile->sec.mcast_cipher = UMAC_CIPHER_TYPE_NONE;
+
+       if (iwm->conf.enable_qos)
+               profile->flags |= cpu_to_le16(UMAC_PROFILE_QOS_ALLOWED);
+
+       profile->wireless_mode = iwm->conf.wireless_mode;
+       profile->mode = cpu_to_le32(iwm->conf.mode);
+
+       profile->ibss.atim = 0;
+       profile->ibss.beacon_interval = 100;
+       profile->ibss.join_only = 0;
+       profile->ibss.band = iwm->conf.ibss_band;
+       profile->ibss.channel = iwm->conf.ibss_channel;
+}
+
+void iwm_link_on(struct iwm_priv *iwm)
+{
+       netif_carrier_on(iwm_to_ndev(iwm));
+       netif_tx_wake_all_queues(iwm_to_ndev(iwm));
+
+       iwm_send_umac_stats_req(iwm, 0);
+}
+
+void iwm_link_off(struct iwm_priv *iwm)
+{
+       struct iw_statistics *wstats = &iwm->wstats;
+       int i;
+
+       netif_tx_stop_all_queues(iwm_to_ndev(iwm));
+       netif_carrier_off(iwm_to_ndev(iwm));
+
+       for (i = 0; i < IWM_TX_QUEUES; i++) {
+               skb_queue_purge(&iwm->txq[i].queue);
+
+               iwm->txq[i].concat_count = 0;
+               iwm->txq[i].concat_ptr = iwm->txq[i].concat_buf;
+
+               flush_workqueue(iwm->txq[i].wq);
+       }
+
+       iwm_rx_free(iwm);
+
+       cancel_delayed_work(&iwm->stats_request);
+       memset(wstats, 0, sizeof(struct iw_statistics));
+       wstats->qual.updated = IW_QUAL_ALL_INVALID;
+
+       del_timer_sync(&iwm->watchdog);
+}
+
+static void iwm_bss_list_clean(struct iwm_priv *iwm)
+{
+       struct iwm_bss_info *bss, *next;
+
+       list_for_each_entry_safe(bss, next, &iwm->bss_list, node) {
+               list_del(&bss->node);
+               kfree(bss->bss);
+               kfree(bss);
+       }
+}
+
+static int iwm_channels_init(struct iwm_priv *iwm)
+{
+       int ret;
+
+#ifdef CONFIG_IWM_B0_HW_SUPPORT
+       if (iwm->conf.hw_b0) {
+               IWM_INFO(iwm, "Workaround EEPROM channels for B0 hardware\n");
+               return 0;
+       }
+#endif
+
+       ret = iwm_send_umac_channel_list(iwm);
+       if (ret) {
+               IWM_ERR(iwm, "Send channel list failed\n");
+               return ret;
+       }
+
+       ret = iwm_notif_handle(iwm, UMAC_CMD_OPCODE_GET_CHAN_INFO_LIST,
+                              IWM_SRC_UMAC, WAIT_NOTIF_TIMEOUT);
+       if (ret) {
+               IWM_ERR(iwm, "Didn't get a channel list notification\n");
+               return ret;
+       }
+
+       return 0;
+}
+
+int iwm_up(struct iwm_priv *iwm)
+{
+       int ret;
+       struct iwm_notif *notif_reboot, *notif_ack = NULL;
+
+       ret = iwm_bus_enable(iwm);
+       if (ret) {
+               IWM_ERR(iwm, "Couldn't enable function\n");
+               return ret;
+       }
+
+       iwm_rx_setup_handlers(iwm);
+
+       /* Wait for initial BARKER_REBOOT from hardware */
+       notif_reboot = iwm_notif_wait(iwm, IWM_BARKER_REBOOT_NOTIFICATION,
+                                     IWM_SRC_UDMA, 2 * HZ);
+       if (!notif_reboot) {
+               IWM_ERR(iwm, "Wait for REBOOT_BARKER timeout\n");
+               goto err_disable;
+       }
+
+       /* We send the barker back */
+       ret = iwm_bus_send_chunk(iwm, notif_reboot->buf, 16);
+       if (ret) {
+               IWM_ERR(iwm, "REBOOT barker response failed\n");
+               kfree(notif_reboot);
+               goto err_disable;
+       }
+
+       kfree(notif_reboot->buf);
+       kfree(notif_reboot);
+
+       /* Wait for ACK_BARKER from hardware */
+       notif_ack = iwm_notif_wait(iwm, IWM_ACK_BARKER_NOTIFICATION,
+                                  IWM_SRC_UDMA, 2 * HZ);
+       if (!notif_ack) {
+               IWM_ERR(iwm, "Wait for ACK_BARKER timeout\n");
+               goto err_disable;
+       }
+
+       kfree(notif_ack->buf);
+       kfree(notif_ack);
+
+       /* We start to config static boot parameters */
+       ret = iwm_config_boot_params(iwm);
+       if (ret) {
+               IWM_ERR(iwm, "Config boot parameters failed\n");
+               goto err_disable;
+       }
+
+       ret = iwm_read_mac(iwm, iwm_to_ndev(iwm)->dev_addr);
+       if (ret) {
+               IWM_ERR(iwm, "MAC reading failed\n");
+               goto err_disable;
+       }
+
+       /* We can load the FWs */
+       ret = iwm_load_fw(iwm);
+       if (ret) {
+               IWM_ERR(iwm, "FW loading failed\n");
+               goto err_disable;
+       }
+
+       /* We configure the UMAC and enable the wifi module */
+       ret = iwm_send_umac_config(iwm,
+                       cpu_to_le32(UMAC_RST_CTRL_FLG_WIFI_CORE_EN) |
+                       cpu_to_le32(UMAC_RST_CTRL_FLG_WIFI_LINK_EN) |
+                       cpu_to_le32(UMAC_RST_CTRL_FLG_WIFI_MLME_EN));
+       if (ret) {
+               IWM_ERR(iwm, "UMAC config failed\n");
+               goto err_fw;
+       }
+
+       ret = iwm_notif_handle(iwm, UMAC_NOTIFY_OPCODE_WIFI_CORE_STATUS,
+                              IWM_SRC_UMAC, WAIT_NOTIF_TIMEOUT);
+       if (ret) {
+               IWM_ERR(iwm, "Didn't get a wifi core status notification\n");
+               goto err_fw;
+       }
+
+       if (iwm->core_enabled != (UMAC_NTFY_WIFI_CORE_STATUS_LINK_EN |
+                                 UMAC_NTFY_WIFI_CORE_STATUS_MLME_EN)) {
+               IWM_DBG_BOOT(iwm, DBG, "Not all cores enabled:0x%x\n",
+                            iwm->core_enabled);
+               ret = iwm_notif_handle(iwm, UMAC_NOTIFY_OPCODE_WIFI_CORE_STATUS,
+                              IWM_SRC_UMAC, WAIT_NOTIF_TIMEOUT);
+               if (ret) {
+                       IWM_ERR(iwm, "Didn't get a core status notification\n");
+                       goto err_fw;
+               }
+
+               if (iwm->core_enabled != (UMAC_NTFY_WIFI_CORE_STATUS_LINK_EN |
+                                         UMAC_NTFY_WIFI_CORE_STATUS_MLME_EN)) {
+                       IWM_ERR(iwm, "Not all cores enabled: 0x%x\n",
+                               iwm->core_enabled);
+                       goto err_fw;
+               } else {
+                       IWM_INFO(iwm, "All cores enabled\n");
+               }
+       }
+
+       iwm->umac_profile = kmalloc(sizeof(struct iwm_umac_profile),
+                                   GFP_KERNEL);
+       if (!iwm->umac_profile) {
+               IWM_ERR(iwm, "Couldn't alloc memory for profile\n");
+               goto err_fw;
+       }
+
+       iwm_init_default_profile(iwm, iwm->umac_profile);
+
+       ret = iwm_channels_init(iwm);
+       if (ret < 0) {
+               IWM_ERR(iwm, "Couldn't init channels\n");
+               goto err_profile;
+       }
+
+       /* Set the READY bit to indicate interface is brought up successfully */
+       set_bit(IWM_STATUS_READY, &iwm->status);
+
+       return 0;
+
+ err_profile:
+       kfree(iwm->umac_profile);
+       iwm->umac_profile = NULL;
+
+ err_fw:
+       iwm_eeprom_exit(iwm);
+
+ err_disable:
+       ret = iwm_bus_disable(iwm);
+       if (ret < 0)
+               IWM_ERR(iwm, "Couldn't disable function\n");
+
+       return -EIO;
+}
+
+int iwm_down(struct iwm_priv *iwm)
+{
+       int ret;
+
+       /* The interface is already down */
+       if (!test_bit(IWM_STATUS_READY, &iwm->status))
+               return 0;
+
+       if (iwm->scan_request) {
+               cfg80211_scan_done(iwm->scan_request, true);
+               iwm->scan_request = NULL;
+       }
+
+       clear_bit(IWM_STATUS_READY, &iwm->status);
+
+       iwm_eeprom_exit(iwm);
+       kfree(iwm->umac_profile);
+       iwm->umac_profile = NULL;
+       iwm_bss_list_clean(iwm);
+
+       iwm->default_key = NULL;
+       iwm->core_enabled = 0;
+
+       ret = iwm_bus_disable(iwm);
+       if (ret < 0) {
+               IWM_ERR(iwm, "Couldn't disable function\n");
+               return ret;
+       }
+
+       return 0;
+}
diff --git a/drivers/net/wireless/iwmc3200wifi/netdev.c b/drivers/net/wireless/iwmc3200wifi/netdev.c
new file mode 100644 (file)
index 0000000..68e2c3b
--- /dev/null
@@ -0,0 +1,162 @@
+/*
+ * Intel Wireless Multicomm 3200 WiFi driver
+ *
+ * Copyright (C) 2009 Intel Corporation <ilw@linux.intel.com>
+ * Samuel Ortiz <samuel.ortiz@intel.com>
+ * Zhu Yi <yi.zhu@intel.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., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ */
+
+/*
+ * This is the netdev related hooks for iwm.
+ *
+ * Some interesting code paths:
+ *
+ * iwm_open() (Called at netdev interface bringup time)
+ *  -> iwm_up() (main.c)
+ *      -> iwm_bus_enable()
+ *          -> if_sdio_enable() (In case of an SDIO bus)
+ *              -> sdio_enable_func()
+ *      -> iwm_notif_wait(BARKER_REBOOT) (wait for reboot barker)
+ *      -> iwm_notif_wait(ACK_BARKER) (wait for ACK barker)
+ *      -> iwm_load_fw() (fw.c)
+ *          -> iwm_load_umac()
+ *          -> iwm_load_lmac() (Calibration LMAC)
+ *          -> iwm_load_lmac() (Operational LMAC)
+ *      -> iwm_send_umac_config()
+ *
+ * iwm_stop() (Called at netdev interface bringdown time)
+ *  -> iwm_down()
+ *      -> iwm_bus_disable()
+ *          -> if_sdio_disable() (In case of an SDIO bus)
+ *              -> sdio_disable_func()
+ */
+#include <linux/netdevice.h>
+
+#include "iwm.h"
+#include "cfg80211.h"
+#include "debug.h"
+
+static int iwm_open(struct net_device *ndev)
+{
+       struct iwm_priv *iwm = ndev_to_iwm(ndev);
+       int ret = 0;
+
+       if (!test_bit(IWM_RADIO_RFKILL_SW, &iwm->radio))
+               ret = iwm_up(iwm);
+
+       return ret;
+}
+
+static int iwm_stop(struct net_device *ndev)
+{
+       struct iwm_priv *iwm = ndev_to_iwm(ndev);
+       int ret = 0;
+
+       if (!test_bit(IWM_RADIO_RFKILL_SW, &iwm->radio))
+               ret = iwm_down(iwm);
+
+       return ret;
+}
+
+/*
+ * iwm AC to queue mapping
+ *
+ * AC_VO -> queue 3
+ * AC_VI -> queue 2
+ * AC_BE -> queue 1
+ * AC_BK -> queue 0
+ */
+static const u16 iwm_1d_to_queue[8] = { 1, 0, 0, 1, 2, 2, 3, 3 };
+
+static u16 iwm_select_queue(struct net_device *dev, struct sk_buff *skb)
+{
+       skb->priority = cfg80211_classify8021d(skb);
+
+       return iwm_1d_to_queue[skb->priority];
+}
+
+static const struct net_device_ops iwm_netdev_ops = {
+       .ndo_open               = iwm_open,
+       .ndo_stop               = iwm_stop,
+       .ndo_start_xmit         = iwm_xmit_frame,
+       .ndo_select_queue       = iwm_select_queue,
+};
+
+void *iwm_if_alloc(int sizeof_bus, struct device *dev,
+                  struct iwm_if_ops *if_ops)
+{
+       struct net_device *ndev;
+       struct wireless_dev *wdev;
+       struct iwm_priv *iwm;
+       int ret = 0;
+
+       wdev = iwm_wdev_alloc(sizeof_bus, dev);
+       if (!wdev) {
+               dev_err(dev, "no memory for wireless device instance\n");
+               return ERR_PTR(-ENOMEM);
+       }
+
+       iwm = wdev_to_iwm(wdev);
+       iwm->bus_ops = if_ops;
+       iwm->wdev = wdev;
+       iwm_priv_init(iwm);
+       wdev->iftype = iwm_mode_to_nl80211_iftype(iwm->conf.mode);
+
+       ndev = alloc_netdev_mq(0, "wlan%d", ether_setup,
+                              IWM_TX_QUEUES);
+       if (!ndev) {
+               dev_err(dev, "no memory for network device instance\n");
+               goto out_wdev;
+       }
+
+       ndev->netdev_ops = &iwm_netdev_ops;
+       ndev->wireless_handlers = &iwm_iw_handler_def;
+       ndev->ieee80211_ptr = wdev;
+       SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
+       ret = register_netdev(ndev);
+       if (ret < 0) {
+               dev_err(dev, "Failed to register netdev: %d\n", ret);
+               goto out_ndev;
+       }
+
+       wdev->netdev = ndev;
+
+       return iwm;
+
+ out_ndev:
+       free_netdev(ndev);
+
+ out_wdev:
+       iwm_wdev_free(iwm);
+       return ERR_PTR(ret);
+}
+
+void iwm_if_free(struct iwm_priv *iwm)
+{
+       int i;
+
+       if (!iwm_to_ndev(iwm))
+               return;
+
+       unregister_netdev(iwm_to_ndev(iwm));
+       free_netdev(iwm_to_ndev(iwm));
+       iwm_wdev_free(iwm);
+       destroy_workqueue(iwm->rx_wq);
+       for (i = 0; i < IWM_TX_QUEUES; i++)
+               destroy_workqueue(iwm->txq[i].wq);
+}
diff --git a/drivers/net/wireless/iwmc3200wifi/rx.c b/drivers/net/wireless/iwmc3200wifi/rx.c
new file mode 100644 (file)
index 0000000..d73cf96
--- /dev/null
@@ -0,0 +1,1431 @@
+/*
+ * Intel Wireless Multicomm 3200 WiFi driver
+ *
+ * Copyright (C) 2009 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in
+ *     the documentation and/or other materials provided with the
+ *     distribution.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * Intel Corporation <ilw@linux.intel.com>
+ * Samuel Ortiz <samuel.ortiz@intel.com>
+ * Zhu Yi <yi.zhu@intel.com>
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/wireless.h>
+#include <linux/ieee80211.h>
+#include <linux/if_arp.h>
+#include <linux/list.h>
+#include <net/iw_handler.h>
+
+#include "iwm.h"
+#include "debug.h"
+#include "hal.h"
+#include "umac.h"
+#include "lmac.h"
+#include "commands.h"
+#include "rx.h"
+#include "cfg80211.h"
+#include "eeprom.h"
+
+static int iwm_rx_check_udma_hdr(struct iwm_udma_in_hdr *hdr)
+{
+       if ((le32_to_cpu(hdr->cmd) == UMAC_PAD_TERMINAL) ||
+           (le32_to_cpu(hdr->size) == UMAC_PAD_TERMINAL))
+               return -EINVAL;
+
+       return 0;
+}
+
+static inline int iwm_rx_resp_size(struct iwm_udma_in_hdr *hdr)
+{
+       return ALIGN(le32_to_cpu(hdr->size) + sizeof(struct iwm_udma_in_hdr),
+                    16);
+}
+
+/*
+ * Notification handlers:
+ *
+ * For every possible notification we can receive from the
+ * target, we have a handler.
+ * When we get a target notification, and there is no one
+ * waiting for it, it's just processed through the rx code
+ * path:
+ *
+ * iwm_rx_handle()
+ *  -> iwm_rx_handle_umac()
+ *      -> iwm_rx_handle_wifi()
+ *          -> iwm_rx_handle_resp()
+ *              -> iwm_ntf_*()
+ *
+ *      OR
+ *
+ *      -> iwm_rx_handle_non_wifi()
+ *
+ * If there are processes waiting for this notification, then
+ * iwm_rx_handle_wifi() just wakes those processes up and they
+ * grab the pending notification.
+ */
+static int iwm_ntf_error(struct iwm_priv *iwm, u8 *buf,
+                        unsigned long buf_size, struct iwm_wifi_cmd *cmd)
+{
+       struct iwm_umac_notif_error *error;
+       struct iwm_fw_error_hdr *fw_err;
+
+       error = (struct iwm_umac_notif_error *)buf;
+       fw_err = &error->err;
+
+
+       IWM_ERR(iwm, "%cMAC FW ERROR:\n",
+        (le32_to_cpu(fw_err->category) == UMAC_SYS_ERR_CAT_LMAC) ? 'L' : 'U');
+       IWM_ERR(iwm, "\tCategory:    %d\n", le32_to_cpu(fw_err->category));
+       IWM_ERR(iwm, "\tStatus:      0x%x\n", le32_to_cpu(fw_err->status));
+       IWM_ERR(iwm, "\tPC:          0x%x\n", le32_to_cpu(fw_err->pc));
+       IWM_ERR(iwm, "\tblink1:      %d\n", le32_to_cpu(fw_err->blink1));
+       IWM_ERR(iwm, "\tblink2:      %d\n", le32_to_cpu(fw_err->blink2));
+       IWM_ERR(iwm, "\tilink1:      %d\n", le32_to_cpu(fw_err->ilink1));
+       IWM_ERR(iwm, "\tilink2:      %d\n", le32_to_cpu(fw_err->ilink2));
+       IWM_ERR(iwm, "\tData1:       0x%x\n", le32_to_cpu(fw_err->data1));
+       IWM_ERR(iwm, "\tData2:       0x%x\n", le32_to_cpu(fw_err->data2));
+       IWM_ERR(iwm, "\tLine number: %d\n", le32_to_cpu(fw_err->line_num));
+       IWM_ERR(iwm, "\tUMAC status: 0x%x\n", le32_to_cpu(fw_err->umac_status));
+       IWM_ERR(iwm, "\tLMAC status: 0x%x\n", le32_to_cpu(fw_err->lmac_status));
+       IWM_ERR(iwm, "\tSDIO status: 0x%x\n", le32_to_cpu(fw_err->sdio_status));
+
+       return 0;
+}
+
+static int iwm_ntf_umac_alive(struct iwm_priv *iwm, u8 *buf,
+                             unsigned long buf_size, struct iwm_wifi_cmd *cmd)
+{
+       struct iwm_umac_notif_alive *alive_resp =
+                       (struct iwm_umac_notif_alive *)(buf);
+       u16 status = le16_to_cpu(alive_resp->status);
+
+       if (status == UMAC_NTFY_ALIVE_STATUS_ERR) {
+               IWM_ERR(iwm, "Receive error UMAC_ALIVE\n");
+               return -EIO;
+       }
+
+       iwm_tx_credit_init_pools(iwm, alive_resp);
+
+       return 0;
+}
+
+static int iwm_ntf_init_complete(struct iwm_priv *iwm, u8 *buf,
+                                unsigned long buf_size,
+                                struct iwm_wifi_cmd *cmd)
+{
+       struct iwm_umac_notif_init_complete *init_complete =
+                       (struct iwm_umac_notif_init_complete *)(buf);
+       u16 status = le16_to_cpu(init_complete->status);
+
+       if (status == UMAC_NTFY_INIT_COMPLETE_STATUS_ERR) {
+               IWM_DBG_NTF(iwm, DBG, "Hardware rf kill is on (radio off)\n");
+               set_bit(IWM_RADIO_RFKILL_HW, &iwm->radio);
+       } else {
+               IWM_DBG_NTF(iwm, DBG, "Hardware rf kill is off (radio on)\n");
+               clear_bit(IWM_RADIO_RFKILL_HW, &iwm->radio);
+       }
+
+       return 0;
+}
+
+static int iwm_ntf_tx_credit_update(struct iwm_priv *iwm, u8 *buf,
+                                   unsigned long buf_size,
+                                   struct iwm_wifi_cmd *cmd)
+{
+       int pool_nr, total_freed_pages;
+       unsigned long pool_map;
+       int i, id;
+       struct iwm_umac_notif_page_dealloc *dealloc =
+                       (struct iwm_umac_notif_page_dealloc *)buf;
+
+       pool_nr = GET_VAL32(dealloc->changes, UMAC_DEALLOC_NTFY_CHANGES_CNT);
+       pool_map = GET_VAL32(dealloc->changes, UMAC_DEALLOC_NTFY_CHANGES_MSK);
+
+       IWM_DBG_TX(iwm, DBG, "UMAC dealloc notification: pool nr %d, "
+                  "update map 0x%lx\n", pool_nr, pool_map);
+
+       spin_lock(&iwm->tx_credit.lock);
+
+       for (i = 0; i < pool_nr; i++) {
+               id = GET_VAL32(dealloc->grp_info[i],
+                              UMAC_DEALLOC_NTFY_GROUP_NUM);
+               if (test_bit(id, &pool_map)) {
+                       total_freed_pages = GET_VAL32(dealloc->grp_info[i],
+                                             UMAC_DEALLOC_NTFY_PAGE_CNT);
+                       iwm_tx_credit_inc(iwm, id, total_freed_pages);
+               }
+       }
+
+       spin_unlock(&iwm->tx_credit.lock);
+
+       return 0;
+}
+
+static int iwm_ntf_umac_reset(struct iwm_priv *iwm, u8 *buf,
+                             unsigned long buf_size, struct iwm_wifi_cmd *cmd)
+{
+       IWM_DBG_NTF(iwm, DBG, "UMAC RESET done\n");
+
+       return 0;
+}
+
+static int iwm_ntf_lmac_version(struct iwm_priv *iwm, u8 *buf,
+                               unsigned long buf_size,
+                               struct iwm_wifi_cmd *cmd)
+{
+       IWM_DBG_NTF(iwm, INFO, "LMAC Version: %x.%x\n", buf[9], buf[8]);
+
+       return 0;
+}
+
+static int iwm_ntf_tx(struct iwm_priv *iwm, u8 *buf,
+                     unsigned long buf_size, struct iwm_wifi_cmd *cmd)
+{
+       struct iwm_lmac_tx_resp *tx_resp;
+       struct iwm_umac_wifi_in_hdr *hdr;
+
+       tx_resp = (struct iwm_lmac_tx_resp *)
+               (buf + sizeof(struct iwm_umac_wifi_in_hdr));
+       hdr = (struct iwm_umac_wifi_in_hdr *)buf;
+
+       IWM_DBG_NTF(iwm, DBG, "REPLY_TX, buf size: %lu\n", buf_size);
+
+       IWM_DBG_NTF(iwm, DBG, "Seqnum: %d\n",
+                   le16_to_cpu(hdr->sw_hdr.cmd.seq_num));
+       IWM_DBG_NTF(iwm, DBG, "\tFrame cnt: %d\n", tx_resp->frame_cnt);
+       IWM_DBG_NTF(iwm, DBG, "\tRetry cnt: %d\n",
+                   le16_to_cpu(tx_resp->retry_cnt));
+       IWM_DBG_NTF(iwm, DBG, "\tSeq ctl: %d\n", le16_to_cpu(tx_resp->seq_ctl));
+       IWM_DBG_NTF(iwm, DBG, "\tByte cnt: %d\n",
+                   le16_to_cpu(tx_resp->byte_cnt));
+       IWM_DBG_NTF(iwm, DBG, "\tStatus: 0x%x\n", le32_to_cpu(tx_resp->status));
+
+       return 0;
+}
+
+
+static int iwm_ntf_calib_res(struct iwm_priv *iwm, u8 *buf,
+                            unsigned long buf_size, struct iwm_wifi_cmd *cmd)
+{
+       u8 opcode;
+       u8 *calib_buf;
+       struct iwm_lmac_calib_hdr *hdr = (struct iwm_lmac_calib_hdr *)
+                               (buf + sizeof(struct iwm_umac_wifi_in_hdr));
+
+       opcode = hdr->opcode;
+
+       BUG_ON(opcode >= CALIBRATION_CMD_NUM ||
+              opcode < PHY_CALIBRATE_OPCODES_NUM);
+
+       IWM_DBG_NTF(iwm, DBG, "Store calibration result for opcode: %d\n",
+                   opcode);
+
+       buf_size -= sizeof(struct iwm_umac_wifi_in_hdr);
+       calib_buf = iwm->calib_res[opcode].buf;
+
+       if (!calib_buf || (iwm->calib_res[opcode].size < buf_size)) {
+               kfree(calib_buf);
+               calib_buf = kzalloc(buf_size, GFP_KERNEL);
+               if (!calib_buf) {
+                       IWM_ERR(iwm, "Memory allocation failed: calib_res\n");
+                       return -ENOMEM;
+               }
+               iwm->calib_res[opcode].buf = calib_buf;
+               iwm->calib_res[opcode].size = buf_size;
+       }
+
+       memcpy(calib_buf, hdr, buf_size);
+       set_bit(opcode - PHY_CALIBRATE_OPCODES_NUM, &iwm->calib_done_map);
+
+       return 0;
+}
+
+static int iwm_ntf_calib_complete(struct iwm_priv *iwm, u8 *buf,
+                                 unsigned long buf_size,
+                                 struct iwm_wifi_cmd *cmd)
+{
+       IWM_DBG_NTF(iwm, DBG, "Calibration completed\n");
+
+       return 0;
+}
+
+static int iwm_ntf_calib_cfg(struct iwm_priv *iwm, u8 *buf,
+                            unsigned long buf_size, struct iwm_wifi_cmd *cmd)
+{
+       struct iwm_lmac_cal_cfg_resp *cal_resp;
+
+       cal_resp = (struct iwm_lmac_cal_cfg_resp *)
+                       (buf + sizeof(struct iwm_umac_wifi_in_hdr));
+
+       IWM_DBG_NTF(iwm, DBG, "Calibration CFG command status: %d\n",
+                   le32_to_cpu(cal_resp->status));
+
+       return 0;
+}
+
+static int iwm_ntf_wifi_status(struct iwm_priv *iwm, u8 *buf,
+                              unsigned long buf_size, struct iwm_wifi_cmd *cmd)
+{
+       struct iwm_umac_notif_wifi_status *status =
+               (struct iwm_umac_notif_wifi_status *)buf;
+
+       iwm->core_enabled |= le16_to_cpu(status->status);
+
+       return 0;
+}
+
+static struct iwm_rx_ticket_node *
+iwm_rx_ticket_node_alloc(struct iwm_priv *iwm, struct iwm_rx_ticket *ticket)
+{
+       struct iwm_rx_ticket_node *ticket_node;
+
+       ticket_node = kzalloc(sizeof(struct iwm_rx_ticket_node), GFP_KERNEL);
+       if (!ticket_node) {
+               IWM_ERR(iwm, "Couldn't allocate ticket node\n");
+               return ERR_PTR(-ENOMEM);
+       }
+
+       ticket_node->ticket = kzalloc(sizeof(struct iwm_rx_ticket), GFP_KERNEL);
+       if (!ticket_node->ticket) {
+               IWM_ERR(iwm, "Couldn't allocate RX ticket\n");
+               kfree(ticket_node);
+               return ERR_PTR(-ENOMEM);
+       }
+
+       memcpy(ticket_node->ticket, ticket, sizeof(struct iwm_rx_ticket));
+       INIT_LIST_HEAD(&ticket_node->node);
+
+       return ticket_node;
+}
+
+static void iwm_rx_ticket_node_free(struct iwm_rx_ticket_node *ticket_node)
+{
+       kfree(ticket_node->ticket);
+       kfree(ticket_node);
+}
+
+static struct iwm_rx_packet *iwm_rx_packet_get(struct iwm_priv *iwm, u16 id)
+{
+       u8 id_hash = IWM_RX_ID_GET_HASH(id);
+       struct list_head *packet_list;
+       struct iwm_rx_packet *packet, *next;
+
+       packet_list = &iwm->rx_packets[id_hash];
+
+       list_for_each_entry_safe(packet, next, packet_list, node)
+               if (packet->id == id)
+                       return packet;
+
+       return NULL;
+}
+
+static struct iwm_rx_packet *iwm_rx_packet_alloc(struct iwm_priv *iwm, u8 *buf,
+                                                u32 size, u16 id)
+{
+       struct iwm_rx_packet *packet;
+
+       packet = kzalloc(sizeof(struct iwm_rx_packet), GFP_KERNEL);
+       if (!packet) {
+               IWM_ERR(iwm, "Couldn't allocate packet\n");
+               return ERR_PTR(-ENOMEM);
+       }
+
+       packet->skb = dev_alloc_skb(size);
+       if (!packet->skb) {
+               IWM_ERR(iwm, "Couldn't allocate packet SKB\n");
+               kfree(packet);
+               return ERR_PTR(-ENOMEM);
+       }
+
+       packet->pkt_size = size;
+
+       skb_put(packet->skb, size);
+       memcpy(packet->skb->data, buf, size);
+       INIT_LIST_HEAD(&packet->node);
+       packet->id = id;
+
+       return packet;
+}
+
+void iwm_rx_free(struct iwm_priv *iwm)
+{
+       struct iwm_rx_ticket_node *ticket, *nt;
+       struct iwm_rx_packet *packet, *np;
+       int i;
+
+       list_for_each_entry_safe(ticket, nt, &iwm->rx_tickets, node) {
+               list_del(&ticket->node);
+               iwm_rx_ticket_node_free(ticket);
+       }
+
+       for (i = 0; i < IWM_RX_ID_HASH; i++) {
+               list_for_each_entry_safe(packet, np, &iwm->rx_packets[i],
+                                        node) {
+                       list_del(&packet->node);
+                       kfree_skb(packet->skb);
+                       kfree(packet);
+               }
+       }
+}
+
+static int iwm_ntf_rx_ticket(struct iwm_priv *iwm, u8 *buf,
+                            unsigned long buf_size, struct iwm_wifi_cmd *cmd)
+{
+       struct iwm_umac_notif_rx_ticket *ntf_rx_ticket =
+               (struct iwm_umac_notif_rx_ticket *)buf;
+       struct iwm_rx_ticket *ticket =
+               (struct iwm_rx_ticket *)ntf_rx_ticket->tickets;
+       int i, schedule_rx = 0;
+
+       for (i = 0; i < ntf_rx_ticket->num_tickets; i++) {
+               struct iwm_rx_ticket_node *ticket_node;
+
+               switch (le16_to_cpu(ticket->action)) {
+               case IWM_RX_TICKET_RELEASE:
+               case IWM_RX_TICKET_DROP:
+                       /* We can push the packet to the stack */
+                       ticket_node = iwm_rx_ticket_node_alloc(iwm, ticket);
+                       if (IS_ERR(ticket_node))
+                               return PTR_ERR(ticket_node);
+
+                       IWM_DBG_NTF(iwm, DBG, "TICKET RELEASE(%d)\n",
+                                   ticket->id);
+                       list_add_tail(&ticket_node->node, &iwm->rx_tickets);
+
+                       /*
+                        * We received an Rx ticket, most likely there's
+                        * a packet pending for it, it's not worth going
+                        * through the packet hash list to double check.
+                        * Let's just fire the rx worker..
+                        */
+                       schedule_rx = 1;
+
+                       break;
+
+               default:
+                       IWM_ERR(iwm, "Invalid RX ticket action: 0x%x\n",
+                               ticket->action);
+               }
+
+               ticket++;
+       }
+
+       if (schedule_rx)
+               queue_work(iwm->rx_wq, &iwm->rx_worker);
+
+       return 0;
+}
+
+static int iwm_ntf_rx_packet(struct iwm_priv *iwm, u8 *buf,
+                            unsigned long buf_size, struct iwm_wifi_cmd *cmd)
+{
+       struct iwm_umac_wifi_in_hdr *wifi_hdr;
+       struct iwm_rx_packet *packet;
+       u16 id, buf_offset;
+       u32 packet_size;
+
+       IWM_DBG_NTF(iwm, DBG, "\n");
+
+       wifi_hdr = (struct iwm_umac_wifi_in_hdr *)buf;
+       id = le16_to_cpu(wifi_hdr->sw_hdr.cmd.seq_num);
+       buf_offset = sizeof(struct iwm_umac_wifi_in_hdr);
+       packet_size = buf_size - sizeof(struct iwm_umac_wifi_in_hdr);
+
+       IWM_DBG_NTF(iwm, DBG, "CMD:0x%x, seqnum: %d, packet size: %d\n",
+                   wifi_hdr->sw_hdr.cmd.cmd, id, packet_size);
+       IWM_DBG_RX(iwm, DBG, "Packet id: %d\n", id);
+       IWM_HEXDUMP(iwm, DBG, RX, "PACKET: ", buf + buf_offset, packet_size);
+
+       packet = iwm_rx_packet_alloc(iwm, buf + buf_offset, packet_size, id);
+       if (IS_ERR(packet))
+               return PTR_ERR(packet);
+
+       list_add_tail(&packet->node, &iwm->rx_packets[IWM_RX_ID_GET_HASH(id)]);
+
+       /* We might (unlikely) have received the packet _after_ the ticket */
+       queue_work(iwm->rx_wq, &iwm->rx_worker);
+
+       return 0;
+}
+
+/* MLME handlers */
+static int iwm_mlme_assoc_start(struct iwm_priv *iwm, u8 *buf,
+                               unsigned long buf_size,
+                               struct iwm_wifi_cmd *cmd)
+{
+       struct iwm_umac_notif_assoc_start *start;
+
+       start = (struct iwm_umac_notif_assoc_start *)buf;
+
+       set_bit(IWM_STATUS_ASSOCIATING, &iwm->status);
+
+       IWM_DBG_MLME(iwm, INFO, "Association with %pM Started, reason: %d\n",
+                    start->bssid, le32_to_cpu(start->roam_reason));
+
+       wake_up_interruptible(&iwm->mlme_queue);
+
+       return 0;
+}
+
+static int iwm_mlme_assoc_complete(struct iwm_priv *iwm, u8 *buf,
+                                  unsigned long buf_size,
+                                  struct iwm_wifi_cmd *cmd)
+{
+       struct iwm_umac_notif_assoc_complete *complete =
+               (struct iwm_umac_notif_assoc_complete *)buf;
+       union iwreq_data wrqu;
+
+       IWM_DBG_MLME(iwm, INFO, "Association with %pM completed, status: %d\n",
+                    complete->bssid, complete->status);
+
+       memset(&wrqu, 0, sizeof(wrqu));
+
+       clear_bit(IWM_STATUS_ASSOCIATING, &iwm->status);
+
+       switch (le32_to_cpu(complete->status)) {
+       case UMAC_ASSOC_COMPLETE_SUCCESS:
+               set_bit(IWM_STATUS_ASSOCIATED, &iwm->status);
+               memcpy(iwm->bssid, complete->bssid, ETH_ALEN);
+               iwm->channel = complete->channel;
+
+               iwm_link_on(iwm);
+
+               memcpy(wrqu.ap_addr.sa_data, complete->bssid, ETH_ALEN);
+               break;
+       case UMAC_ASSOC_COMPLETE_FAILURE:
+               clear_bit(IWM_STATUS_ASSOCIATED, &iwm->status);
+               memset(iwm->bssid, 0, ETH_ALEN);
+               iwm->channel = 0;
+
+               iwm_link_off(iwm);
+       default:
+               break;
+       }
+
+       if (iwm->conf.mode == UMAC_MODE_IBSS) {
+               cfg80211_ibss_joined(iwm_to_ndev(iwm), iwm->bssid, GFP_KERNEL);
+               return 0;
+       }
+
+       wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+       wireless_send_event(iwm_to_ndev(iwm), SIOCGIWAP, &wrqu, NULL);
+
+       return 0;
+}
+
+static int iwm_mlme_profile_invalidate(struct iwm_priv *iwm, u8 *buf,
+                                      unsigned long buf_size,
+                                      struct iwm_wifi_cmd *cmd)
+{
+       struct iwm_umac_notif_profile_invalidate *invalid;
+
+       invalid = (struct iwm_umac_notif_profile_invalidate *)buf;
+
+       IWM_DBG_MLME(iwm, INFO, "Profile Invalidated. Reason: %d\n",
+                    le32_to_cpu(invalid->reason));
+
+       clear_bit(IWM_STATUS_ASSOCIATING, &iwm->status);
+       clear_bit(IWM_STATUS_ASSOCIATED, &iwm->status);
+
+       iwm->umac_profile_active = 0;
+       memset(iwm->bssid, 0, ETH_ALEN);
+       iwm->channel = 0;
+
+       iwm_link_off(iwm);
+
+       wake_up_interruptible(&iwm->mlme_queue);
+
+       return 0;
+}
+
+static int iwm_mlme_scan_complete(struct iwm_priv *iwm, u8 *buf,
+                                 unsigned long buf_size,
+                                 struct iwm_wifi_cmd *cmd)
+{
+       int ret;
+       struct iwm_umac_notif_scan_complete *scan_complete =
+               (struct iwm_umac_notif_scan_complete *)buf;
+       u32 result = le32_to_cpu(scan_complete->result);
+
+       IWM_DBG_MLME(iwm, INFO, "type:0x%x result:0x%x seq:%d\n",
+                    le32_to_cpu(scan_complete->type),
+                    le32_to_cpu(scan_complete->result),
+                    scan_complete->seq_num);
+
+       if (!test_and_clear_bit(IWM_STATUS_SCANNING, &iwm->status)) {
+               IWM_ERR(iwm, "Scan complete while device not scanning\n");
+               return -EIO;
+       }
+       if (!iwm->scan_request)
+               return 0;
+
+       ret = iwm_cfg80211_inform_bss(iwm);
+
+       cfg80211_scan_done(iwm->scan_request,
+                          (result & UMAC_SCAN_RESULT_ABORTED) ? 1 : !!ret);
+       iwm->scan_request = NULL;
+
+       return ret;
+}
+
+static int iwm_mlme_update_sta_table(struct iwm_priv *iwm, u8 *buf,
+                                    unsigned long buf_size,
+                                    struct iwm_wifi_cmd *cmd)
+{
+       struct iwm_umac_notif_sta_info *umac_sta =
+                       (struct iwm_umac_notif_sta_info *)buf;
+       struct iwm_sta_info *sta;
+       int i;
+
+       switch (le32_to_cpu(umac_sta->opcode)) {
+       case UMAC_OPCODE_ADD_MODIFY:
+               sta = &iwm->sta_table[GET_VAL8(umac_sta->sta_id, LMAC_STA_ID)];
+
+               IWM_DBG_MLME(iwm, INFO, "%s STA: ID = %d, Color = %d, "
+                            "addr = %pM, qos = %d\n",
+                            sta->valid ? "Modify" : "Add",
+                            GET_VAL8(umac_sta->sta_id, LMAC_STA_ID),
+                            GET_VAL8(umac_sta->sta_id, LMAC_STA_COLOR),
+                            umac_sta->mac_addr,
+                            umac_sta->flags & UMAC_STA_FLAG_QOS);
+
+               sta->valid = 1;
+               sta->qos = umac_sta->flags & UMAC_STA_FLAG_QOS;
+               sta->color = GET_VAL8(umac_sta->sta_id, LMAC_STA_COLOR);
+               memcpy(sta->addr, umac_sta->mac_addr, ETH_ALEN);
+               break;
+       case UMAC_OPCODE_REMOVE:
+               IWM_DBG_MLME(iwm, INFO, "Remove STA: ID = %d, Color = %d, "
+                            "addr = %pM\n",
+                            GET_VAL8(umac_sta->sta_id, LMAC_STA_ID),
+                            GET_VAL8(umac_sta->sta_id, LMAC_STA_COLOR),
+                            umac_sta->mac_addr);
+
+               sta = &iwm->sta_table[GET_VAL8(umac_sta->sta_id, LMAC_STA_ID)];
+
+               if (!memcmp(sta->addr, umac_sta->mac_addr, ETH_ALEN))
+                       sta->valid = 0;
+
+               break;
+       case UMAC_OPCODE_CLEAR_ALL:
+               for (i = 0; i < IWM_STA_TABLE_NUM; i++)
+                       iwm->sta_table[i].valid = 0;
+
+               break;
+       default:
+               break;
+       }
+
+       return 0;
+}
+
+static int iwm_mlme_update_bss_table(struct iwm_priv *iwm, u8 *buf,
+                                    unsigned long buf_size,
+                                    struct iwm_wifi_cmd *cmd)
+{
+       struct wiphy *wiphy = iwm_to_wiphy(iwm);
+       struct ieee80211_mgmt *mgmt;
+       struct iwm_umac_notif_bss_info *umac_bss =
+                       (struct iwm_umac_notif_bss_info *)buf;
+       struct ieee80211_channel *channel;
+       struct ieee80211_supported_band *band;
+       struct iwm_bss_info *bss, *next;
+       s32 signal;
+       int freq;
+       u16 frame_len = le16_to_cpu(umac_bss->frame_len);
+       size_t bss_len = sizeof(struct iwm_umac_notif_bss_info) + frame_len;
+
+       mgmt = (struct ieee80211_mgmt *)(umac_bss->frame_buf);
+
+       IWM_DBG_MLME(iwm, DBG, "New BSS info entry: %pM\n", mgmt->bssid);
+       IWM_DBG_MLME(iwm, DBG, "\tType: 0x%x\n", le32_to_cpu(umac_bss->type));
+       IWM_DBG_MLME(iwm, DBG, "\tTimestamp: %d\n",
+                    le32_to_cpu(umac_bss->timestamp));
+       IWM_DBG_MLME(iwm, DBG, "\tTable Index: %d\n",
+                    le16_to_cpu(umac_bss->table_idx));
+       IWM_DBG_MLME(iwm, DBG, "\tBand: %d\n", umac_bss->band);
+       IWM_DBG_MLME(iwm, DBG, "\tChannel: %d\n", umac_bss->channel);
+       IWM_DBG_MLME(iwm, DBG, "\tRSSI: %d\n", umac_bss->rssi);
+       IWM_DBG_MLME(iwm, DBG, "\tFrame Length: %d\n", frame_len);
+
+       list_for_each_entry_safe(bss, next, &iwm->bss_list, node)
+               if (bss->bss->table_idx == umac_bss->table_idx)
+                       break;
+
+       if (&bss->node != &iwm->bss_list) {
+               /* Remove the old BSS entry, we will add it back later. */
+               list_del(&bss->node);
+               kfree(bss->bss);
+       } else {
+               /* New BSS entry */
+
+               bss = kzalloc(sizeof(struct iwm_bss_info), GFP_KERNEL);
+               if (!bss) {
+                       IWM_ERR(iwm, "Couldn't allocate bss_info\n");
+                       return -ENOMEM;
+               }
+       }
+
+       bss->bss = kzalloc(bss_len, GFP_KERNEL);
+       if (!bss) {
+               kfree(bss);
+               IWM_ERR(iwm, "Couldn't allocate bss\n");
+               return -ENOMEM;
+       }
+
+       INIT_LIST_HEAD(&bss->node);
+       memcpy(bss->bss, umac_bss, bss_len);
+
+       if (umac_bss->band == UMAC_BAND_2GHZ)
+               band = wiphy->bands[IEEE80211_BAND_2GHZ];
+       else if (umac_bss->band == UMAC_BAND_5GHZ)
+               band = wiphy->bands[IEEE80211_BAND_5GHZ];
+       else {
+               IWM_ERR(iwm, "Invalid band: %d\n", umac_bss->band);
+               goto err;
+       }
+
+       freq = ieee80211_channel_to_frequency(umac_bss->channel);
+       channel = ieee80211_get_channel(wiphy, freq);
+       signal = umac_bss->rssi * 100;
+
+       bss->cfg_bss = cfg80211_inform_bss_frame(wiphy, channel,
+                                                mgmt, frame_len,
+                                                signal, GFP_KERNEL);
+       if (!bss->cfg_bss)
+               goto err;
+
+       list_add_tail(&bss->node, &iwm->bss_list);
+
+       return 0;
+ err:
+       kfree(bss->bss);
+       kfree(bss);
+
+       return -EINVAL;
+}
+
+static int iwm_mlme_remove_bss(struct iwm_priv *iwm, u8 *buf,
+                              unsigned long buf_size, struct iwm_wifi_cmd *cmd)
+{
+       struct iwm_umac_notif_bss_removed *bss_rm =
+               (struct iwm_umac_notif_bss_removed *)buf;
+       struct iwm_bss_info *bss, *next;
+       u16 table_idx;
+       int i;
+
+       for (i = 0; i < le32_to_cpu(bss_rm->count); i++) {
+               table_idx = (le16_to_cpu(bss_rm->entries[i])
+                            & IWM_BSS_REMOVE_INDEX_MSK);
+               list_for_each_entry_safe(bss, next, &iwm->bss_list, node)
+                       if (bss->bss->table_idx == cpu_to_le16(table_idx)) {
+                               struct ieee80211_mgmt *mgmt;
+
+                               mgmt = (struct ieee80211_mgmt *)
+                                       (bss->bss->frame_buf);
+                               IWM_DBG_MLME(iwm, ERR,
+                                            "BSS removed: %pM\n",
+                                            mgmt->bssid);
+                               list_del(&bss->node);
+                               kfree(bss->bss);
+                               kfree(bss);
+                       }
+       }
+
+       return 0;
+}
+
+static int iwm_mlme_mgt_frame(struct iwm_priv *iwm, u8 *buf,
+                             unsigned long buf_size, struct iwm_wifi_cmd *cmd)
+{
+       struct iwm_umac_notif_mgt_frame *mgt_frame =
+       (struct iwm_umac_notif_mgt_frame *)buf;
+       struct ieee80211_mgmt *mgt = (struct ieee80211_mgmt *)mgt_frame->frame;
+       u8 *ie;
+       unsigned int event;
+       union iwreq_data wrqu;
+
+       IWM_HEXDUMP(iwm, DBG, MLME, "MGT: ", mgt_frame->frame,
+                   le16_to_cpu(mgt_frame->len));
+
+       if (ieee80211_is_assoc_req(mgt->frame_control)) {
+               ie = mgt->u.assoc_req.variable;;
+               event = IWEVASSOCREQIE;
+       } else if (ieee80211_is_reassoc_req(mgt->frame_control)) {
+               ie = mgt->u.reassoc_req.variable;;
+               event = IWEVASSOCREQIE;
+       } else if (ieee80211_is_assoc_resp(mgt->frame_control)) {
+               ie = mgt->u.assoc_resp.variable;;
+               event = IWEVASSOCRESPIE;
+       } else if (ieee80211_is_reassoc_resp(mgt->frame_control)) {
+               ie = mgt->u.reassoc_resp.variable;;
+               event = IWEVASSOCRESPIE;
+       } else {
+               IWM_ERR(iwm, "Unsupported management frame");
+               return 0;
+       }
+
+       wrqu.data.length = le16_to_cpu(mgt_frame->len) - (ie - (u8 *)mgt);
+
+       IWM_HEXDUMP(iwm, DBG, MLME, "EVT: ", ie, wrqu.data.length);
+       wireless_send_event(iwm_to_ndev(iwm), event, &wrqu, ie);
+
+       return 0;
+}
+
+static int iwm_ntf_mlme(struct iwm_priv *iwm, u8 *buf,
+                       unsigned long buf_size, struct iwm_wifi_cmd *cmd)
+{
+       struct iwm_umac_notif_wifi_if *notif =
+               (struct iwm_umac_notif_wifi_if *)buf;
+
+       switch (notif->status) {
+       case WIFI_IF_NTFY_ASSOC_START:
+               return iwm_mlme_assoc_start(iwm, buf, buf_size, cmd);
+       case WIFI_IF_NTFY_ASSOC_COMPLETE:
+               return iwm_mlme_assoc_complete(iwm, buf, buf_size, cmd);
+       case WIFI_IF_NTFY_PROFILE_INVALIDATE_COMPLETE:
+               return iwm_mlme_profile_invalidate(iwm, buf, buf_size, cmd);
+       case WIFI_IF_NTFY_CONNECTION_TERMINATED:
+               IWM_DBG_MLME(iwm, DBG, "Connection terminated\n");
+               break;
+       case WIFI_IF_NTFY_SCAN_COMPLETE:
+               return iwm_mlme_scan_complete(iwm, buf, buf_size, cmd);
+       case WIFI_IF_NTFY_STA_TABLE_CHANGE:
+               return iwm_mlme_update_sta_table(iwm, buf, buf_size, cmd);
+       case WIFI_IF_NTFY_EXTENDED_IE_REQUIRED:
+               IWM_DBG_MLME(iwm, DBG, "Extended IE required\n");
+               break;
+       case WIFI_IF_NTFY_BSS_TRK_TABLE_CHANGED:
+               return iwm_mlme_update_bss_table(iwm, buf, buf_size, cmd);
+       case WIFI_IF_NTFY_BSS_TRK_ENTRIES_REMOVED:
+               return iwm_mlme_remove_bss(iwm, buf, buf_size, cmd);
+               break;
+       case WIFI_IF_NTFY_MGMT_FRAME:
+               return iwm_mlme_mgt_frame(iwm, buf, buf_size, cmd);
+       case WIFI_DBG_IF_NTFY_SCAN_SUPER_JOB_START:
+       case WIFI_DBG_IF_NTFY_SCAN_SUPER_JOB_COMPLETE:
+       case WIFI_DBG_IF_NTFY_SCAN_CHANNEL_START:
+       case WIFI_DBG_IF_NTFY_SCAN_CHANNEL_RESULT:
+       case WIFI_DBG_IF_NTFY_SCAN_MINI_JOB_START:
+       case WIFI_DBG_IF_NTFY_SCAN_MINI_JOB_COMPLETE:
+       case WIFI_DBG_IF_NTFY_CNCT_ATC_START:
+       case WIFI_DBG_IF_NTFY_COEX_NOTIFICATION:
+       case WIFI_DBG_IF_NTFY_COEX_HANDLE_ENVELOP:
+       case WIFI_DBG_IF_NTFY_COEX_HANDLE_RELEASE_ENVELOP:
+               IWM_DBG_MLME(iwm, DBG, "MLME debug notification: 0x%x\n",
+                            notif->status);
+               break;
+       default:
+               IWM_ERR(iwm, "Unhandled notification: 0x%x\n", notif->status);
+               break;
+       }
+
+       return 0;
+}
+
+#define IWM_STATS_UPDATE_INTERVAL              (2 * HZ)
+
+static int iwm_ntf_statistics(struct iwm_priv *iwm, u8 *buf,
+                             unsigned long buf_size, struct iwm_wifi_cmd *cmd)
+{
+       struct iwm_umac_notif_stats *stats = (struct iwm_umac_notif_stats *)buf;
+       struct iw_statistics *wstats = &iwm->wstats;
+       u16 max_rate = 0;
+       int i;
+
+       IWM_DBG_MLME(iwm, DBG, "Statistics notification received\n");
+
+       if (test_bit(IWM_STATUS_ASSOCIATED, &iwm->status)) {
+               for (i = 0; i < UMAC_NTF_RATE_SAMPLE_NR; i++) {
+                       max_rate = max_t(u16, max_rate,
+                                        max(le16_to_cpu(stats->tx_rate[i]),
+                                            le16_to_cpu(stats->rx_rate[i])));
+               }
+               /* UMAC passes rate info multiplies by 2 */
+               iwm->rate = max_rate >> 1;
+       }
+
+       wstats->status = 0;
+
+       wstats->discard.nwid = le32_to_cpu(stats->rx_drop_other_bssid);
+       wstats->discard.code = le32_to_cpu(stats->rx_drop_decode);
+       wstats->discard.fragment = le32_to_cpu(stats->rx_drop_reassembly);
+       wstats->discard.retries = le32_to_cpu(stats->tx_drop_max_retry);
+
+       wstats->miss.beacon = le32_to_cpu(stats->missed_beacons);
+
+       /* according to cfg80211 */
+       if (stats->rssi_dbm < -110)
+               wstats->qual.qual = 0;
+       else if (stats->rssi_dbm > -40)
+               wstats->qual.qual = 70;
+       else
+               wstats->qual.qual = stats->rssi_dbm + 110;
+
+       wstats->qual.level = stats->rssi_dbm;
+       wstats->qual.noise = stats->noise_dbm;
+       wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
+
+       schedule_delayed_work(&iwm->stats_request, IWM_STATS_UPDATE_INTERVAL);
+
+       mod_timer(&iwm->watchdog, round_jiffies(jiffies + IWM_WATCHDOG_PERIOD));
+
+       return 0;
+}
+
+static int iwm_ntf_eeprom_proxy(struct iwm_priv *iwm, u8 *buf,
+                               unsigned long buf_size,
+                               struct iwm_wifi_cmd *cmd)
+{
+       struct iwm_umac_cmd_eeprom_proxy *eeprom_proxy =
+               (struct iwm_umac_cmd_eeprom_proxy *)
+               (buf + sizeof(struct iwm_umac_wifi_in_hdr));
+       struct iwm_umac_cmd_eeprom_proxy_hdr *hdr = &eeprom_proxy->hdr;
+       u32 hdr_offset = le32_to_cpu(hdr->offset);
+       u32 hdr_len = le32_to_cpu(hdr->len);
+       u32 hdr_type = le32_to_cpu(hdr->type);
+
+       IWM_DBG_NTF(iwm, DBG, "type: 0x%x, len: %d, offset: 0x%x\n",
+                   hdr_type, hdr_len, hdr_offset);
+
+       if ((hdr_offset + hdr_len) > IWM_EEPROM_LEN)
+               return -EINVAL;
+
+#ifdef CONFIG_IWM_B0_HW_SUPPORT
+       if (hdr_offset == IWM_EEPROM_SKU_CAP_OFF) {
+               if (eeprom_proxy->buf[0] == 0xff)
+                       iwm->conf.hw_b0 = 1;
+       }
+#endif
+
+       switch (hdr_type) {
+       case IWM_UMAC_CMD_EEPROM_TYPE_READ:
+               memcpy(iwm->eeprom + hdr_offset, eeprom_proxy->buf, hdr_len);
+               break;
+       case IWM_UMAC_CMD_EEPROM_TYPE_WRITE:
+       default:
+               return -ENOTSUPP;
+       }
+
+       return 0;
+}
+
+static int iwm_ntf_channel_info_list(struct iwm_priv *iwm, u8 *buf,
+                                    unsigned long buf_size,
+                                    struct iwm_wifi_cmd *cmd)
+{
+       struct iwm_umac_cmd_get_channel_list *ch_list =
+                       (struct iwm_umac_cmd_get_channel_list *)
+                       (buf + sizeof(struct iwm_umac_wifi_in_hdr));
+       struct wiphy *wiphy = iwm_to_wiphy(iwm);
+       struct ieee80211_supported_band *band;
+       int i;
+
+       band = wiphy->bands[IEEE80211_BAND_2GHZ];
+
+       for (i = 0; i < band->n_channels; i++) {
+               unsigned long ch_mask_0 =
+                       le32_to_cpu(ch_list->ch[0].channels_mask);
+               unsigned long ch_mask_2 =
+                       le32_to_cpu(ch_list->ch[2].channels_mask);
+
+               if (!test_bit(i, &ch_mask_0))
+                       band->channels[i].flags |= IEEE80211_CHAN_DISABLED;
+
+               if (!test_bit(i, &ch_mask_2))
+                       band->channels[i].flags |= IEEE80211_CHAN_NO_IBSS;
+       }
+
+       band = wiphy->bands[IEEE80211_BAND_5GHZ];
+
+       for (i = 0; i < min(band->n_channels, 32); i++) {
+               unsigned long ch_mask_1 =
+                       le32_to_cpu(ch_list->ch[1].channels_mask);
+               unsigned long ch_mask_3 =
+                       le32_to_cpu(ch_list->ch[3].channels_mask);
+
+               if (!test_bit(i, &ch_mask_1))
+                       band->channels[i].flags |= IEEE80211_CHAN_DISABLED;
+
+               if (!test_bit(i, &ch_mask_3))
+                       band->channels[i].flags |= IEEE80211_CHAN_NO_IBSS;
+       }
+
+       return 0;
+}
+
+static int iwm_ntf_wifi_if_wrapper(struct iwm_priv *iwm, u8 *buf,
+                                  unsigned long buf_size,
+                                  struct iwm_wifi_cmd *cmd)
+{
+       struct iwm_umac_wifi_if *hdr =
+                       (struct iwm_umac_wifi_if *)cmd->buf.payload;
+
+       IWM_DBG_NTF(iwm, DBG, "WIFI_IF_WRAPPER cmd is delivered to UMAC: "
+                   "oid is %d\n", hdr->oid);
+
+       switch (hdr->oid) {
+       case UMAC_WIFI_IF_CMD_SET_PROFILE:
+               iwm->umac_profile_active = 1;
+               wake_up_interruptible(&iwm->mlme_queue);
+               break;
+       default:
+               break;
+       }
+
+       return 0;
+}
+
+static int iwm_ntf_card_state(struct iwm_priv *iwm, u8 *buf,
+                             unsigned long buf_size, struct iwm_wifi_cmd *cmd)
+{
+       struct iwm_lmac_card_state *state = (struct iwm_lmac_card_state *)
+                               (buf + sizeof(struct iwm_umac_wifi_in_hdr));
+       u32 flags = le32_to_cpu(state->flags);
+
+       IWM_INFO(iwm, "HW RF Kill %s, CT Kill %s\n",
+                flags & IWM_CARD_STATE_HW_DISABLED ? "ON" : "OFF",
+                flags & IWM_CARD_STATE_CTKILL_DISABLED ? "ON" : "OFF");
+
+       if (flags & IWM_CARD_STATE_HW_DISABLED)
+               set_bit(IWM_RADIO_RFKILL_HW, &iwm->radio);
+       else
+               clear_bit(IWM_RADIO_RFKILL_HW, &iwm->radio);
+
+       return 0;
+}
+
+static int iwm_rx_handle_wifi(struct iwm_priv *iwm, u8 *buf,
+                             unsigned long buf_size)
+{
+       struct iwm_umac_wifi_in_hdr *wifi_hdr;
+       struct iwm_wifi_cmd *cmd;
+       u8 source, cmd_id;
+       u16 seq_num;
+       u32 count;
+       u8 resp;
+
+       wifi_hdr = (struct iwm_umac_wifi_in_hdr *)buf;
+       cmd_id = wifi_hdr->sw_hdr.cmd.cmd;
+
+       source = GET_VAL32(wifi_hdr->hw_hdr.cmd, UMAC_HDI_IN_CMD_SOURCE);
+       if (source >= IWM_SRC_NUM) {
+               IWM_CRIT(iwm, "invalid source %d\n", source);
+               return -EINVAL;
+       }
+
+       count = (GET_VAL32(wifi_hdr->sw_hdr.meta_data, UMAC_FW_CMD_BYTE_COUNT));
+       count += sizeof(struct iwm_umac_wifi_in_hdr) -
+                sizeof(struct iwm_dev_cmd_hdr);
+       if (count > buf_size) {
+               IWM_CRIT(iwm, "count %d, buf size:%ld\n", count, buf_size);
+               return -EINVAL;
+       }
+
+       resp = GET_VAL32(wifi_hdr->sw_hdr.meta_data, UMAC_FW_CMD_STATUS);
+
+       seq_num = le16_to_cpu(wifi_hdr->sw_hdr.cmd.seq_num);
+
+       IWM_DBG_RX(iwm, DBG, "CMD:0x%x, source: 0x%x, seqnum: %d\n",
+                  cmd_id, source, seq_num);
+
+       /*
+        * If this is a response to a previously sent command, there must
+        * be a pending command for this sequence number.
+        */
+       cmd = iwm_get_pending_wifi_cmd(iwm, seq_num);
+
+       /* Notify the caller only for sync commands. */
+       switch (source) {
+       case UMAC_HDI_IN_SOURCE_FHRX:
+               if (iwm->lmac_handlers[cmd_id] &&
+                   test_bit(cmd_id, &iwm->lmac_handler_map[0]))
+                       return iwm_notif_send(iwm, cmd, cmd_id, source,
+                                             buf, count);
+               break;
+       case UMAC_HDI_IN_SOURCE_FW:
+               if (iwm->umac_handlers[cmd_id] &&
+                   test_bit(cmd_id, &iwm->umac_handler_map[0]))
+                       return iwm_notif_send(iwm, cmd, cmd_id, source,
+                                             buf, count);
+               break;
+       case UMAC_HDI_IN_SOURCE_UDMA:
+               break;
+       }
+
+       return iwm_rx_handle_resp(iwm, buf, count, cmd);
+}
+
+int iwm_rx_handle_resp(struct iwm_priv *iwm, u8 *buf, unsigned long buf_size,
+                      struct iwm_wifi_cmd *cmd)
+{
+       u8 source, cmd_id;
+       struct iwm_umac_wifi_in_hdr *wifi_hdr;
+       int ret = 0;
+
+       wifi_hdr = (struct iwm_umac_wifi_in_hdr *)buf;
+       cmd_id = wifi_hdr->sw_hdr.cmd.cmd;
+
+       source = GET_VAL32(wifi_hdr->hw_hdr.cmd, UMAC_HDI_IN_CMD_SOURCE);
+
+       IWM_DBG_RX(iwm, DBG, "CMD:0x%x, source: 0x%x\n", cmd_id, source);
+
+       switch (source) {
+       case UMAC_HDI_IN_SOURCE_FHRX:
+               if (iwm->lmac_handlers[cmd_id])
+                       ret = iwm->lmac_handlers[cmd_id]
+                                       (iwm, buf, buf_size, cmd);
+               break;
+       case UMAC_HDI_IN_SOURCE_FW:
+               if (iwm->umac_handlers[cmd_id])
+                       ret = iwm->umac_handlers[cmd_id]
+                                       (iwm, buf, buf_size, cmd);
+               break;
+       case UMAC_HDI_IN_SOURCE_UDMA:
+               ret = -EINVAL;
+               break;
+       }
+
+       kfree(cmd);
+
+       return ret;
+}
+
+static int iwm_rx_handle_nonwifi(struct iwm_priv *iwm, u8 *buf,
+                                unsigned long buf_size)
+{
+       u8 seq_num;
+       struct iwm_udma_in_hdr *hdr = (struct iwm_udma_in_hdr *)buf;
+       struct iwm_nonwifi_cmd *cmd, *next;
+
+       seq_num = GET_VAL32(hdr->cmd, UDMA_HDI_IN_CMD_NON_WIFI_HW_SEQ_NUM);
+
+       /*
+        * We received a non wifi answer.
+        * Let's check if there's a pending command for it, and if so
+        * replace the command payload with the buffer, and then wake the
+        * callers up.
+        * That means we only support synchronised non wifi command response
+        * schemes.
+        */
+       list_for_each_entry_safe(cmd, next, &iwm->nonwifi_pending_cmd, pending)
+               if (cmd->seq_num == seq_num) {
+                       cmd->resp_received = 1;
+                       cmd->buf.len = buf_size;
+                       memcpy(cmd->buf.hdr, buf, buf_size);
+                       wake_up_interruptible(&iwm->nonwifi_queue);
+               }
+
+       return 0;
+}
+
+static int iwm_rx_handle_umac(struct iwm_priv *iwm, u8 *buf,
+                             unsigned long buf_size)
+{
+       int ret = 0;
+       u8 op_code;
+       unsigned long buf_offset = 0;
+       struct iwm_udma_in_hdr *hdr;
+
+       /*
+        * To allow for a more efficient bus usage, UMAC
+        * messages are encapsulated into UDMA ones. This
+        * way we can have several UMAC messages in one bus
+        * transfer.
+        * A UDMA frame size is always aligned on 16 bytes,
+        * and a UDMA frame must not start with a UMAC_PAD_TERMINAL
+        * word. This is how we parse a bus frame into several
+        * UDMA ones.
+        */
+       while (buf_offset < buf_size) {
+
+               hdr = (struct iwm_udma_in_hdr *)(buf + buf_offset);
+
+               if (iwm_rx_check_udma_hdr(hdr) < 0) {
+                       IWM_DBG_RX(iwm, DBG, "End of frame\n");
+                       break;
+               }
+
+               op_code = GET_VAL32(hdr->cmd, UMAC_HDI_IN_CMD_OPCODE);
+
+               IWM_DBG_RX(iwm, DBG, "Op code: 0x%x\n", op_code);
+
+               if (op_code == UMAC_HDI_IN_OPCODE_WIFI) {
+                       ret |= iwm_rx_handle_wifi(iwm, buf + buf_offset,
+                                                 buf_size - buf_offset);
+               } else if (op_code < UMAC_HDI_IN_OPCODE_NONWIFI_MAX) {
+                       if (GET_VAL32(hdr->cmd,
+                                     UDMA_HDI_IN_CMD_NON_WIFI_HW_SIG) !=
+                           UDMA_HDI_IN_CMD_NON_WIFI_HW_SIG) {
+                               IWM_ERR(iwm, "Incorrect hw signature\n");
+                               return -EINVAL;
+                       }
+                       ret |= iwm_rx_handle_nonwifi(iwm, buf + buf_offset,
+                                                    buf_size - buf_offset);
+               } else {
+                       IWM_ERR(iwm, "Invalid RX opcode: 0x%x\n", op_code);
+                       ret |= -EINVAL;
+               }
+
+               buf_offset += iwm_rx_resp_size(hdr);
+       }
+
+       return ret;
+}
+
+int iwm_rx_handle(struct iwm_priv *iwm, u8 *buf, unsigned long buf_size)
+{
+       struct iwm_udma_in_hdr *hdr;
+
+       hdr = (struct iwm_udma_in_hdr *)buf;
+
+       switch (le32_to_cpu(hdr->cmd)) {
+       case UMAC_REBOOT_BARKER:
+               return iwm_notif_send(iwm, NULL, IWM_BARKER_REBOOT_NOTIFICATION,
+                                     IWM_SRC_UDMA, buf, buf_size);
+       case UMAC_ACK_BARKER:
+               return iwm_notif_send(iwm, NULL, IWM_ACK_BARKER_NOTIFICATION,
+                                     IWM_SRC_UDMA, NULL, 0);
+       default:
+               IWM_DBG_RX(iwm, DBG, "Received cmd: 0x%x\n", hdr->cmd);
+               return iwm_rx_handle_umac(iwm, buf, buf_size);
+       }
+
+       return 0;
+}
+
+static const iwm_handler iwm_umac_handlers[] =
+{
+       [UMAC_NOTIFY_OPCODE_ERROR]              = iwm_ntf_error,
+       [UMAC_NOTIFY_OPCODE_ALIVE]              = iwm_ntf_umac_alive,
+       [UMAC_NOTIFY_OPCODE_INIT_COMPLETE]      = iwm_ntf_init_complete,
+       [UMAC_NOTIFY_OPCODE_WIFI_CORE_STATUS]   = iwm_ntf_wifi_status,
+       [UMAC_NOTIFY_OPCODE_WIFI_IF_WRAPPER]    = iwm_ntf_mlme,
+       [UMAC_NOTIFY_OPCODE_PAGE_DEALLOC]       = iwm_ntf_tx_credit_update,
+       [UMAC_NOTIFY_OPCODE_RX_TICKET]          = iwm_ntf_rx_ticket,
+       [UMAC_CMD_OPCODE_RESET]                 = iwm_ntf_umac_reset,
+       [UMAC_NOTIFY_OPCODE_STATS]              = iwm_ntf_statistics,
+       [UMAC_CMD_OPCODE_EEPROM_PROXY]          = iwm_ntf_eeprom_proxy,
+       [UMAC_CMD_OPCODE_GET_CHAN_INFO_LIST]    = iwm_ntf_channel_info_list,
+       [REPLY_RX_MPDU_CMD]                     = iwm_ntf_rx_packet,
+       [UMAC_CMD_OPCODE_WIFI_IF_WRAPPER]       = iwm_ntf_wifi_if_wrapper,
+};
+
+static const iwm_handler iwm_lmac_handlers[] =
+{
+       [REPLY_TX]                              = iwm_ntf_tx,
+       [REPLY_ALIVE]                           = iwm_ntf_lmac_version,
+       [CALIBRATION_RES_NOTIFICATION]          = iwm_ntf_calib_res,
+       [CALIBRATION_COMPLETE_NOTIFICATION]     = iwm_ntf_calib_complete,
+       [CALIBRATION_CFG_CMD]                   = iwm_ntf_calib_cfg,
+       [REPLY_RX_MPDU_CMD]                     = iwm_ntf_rx_packet,
+       [CARD_STATE_NOTIFICATION]               = iwm_ntf_card_state,
+};
+
+void iwm_rx_setup_handlers(struct iwm_priv *iwm)
+{
+       iwm->umac_handlers = (iwm_handler *) iwm_umac_handlers;
+       iwm->lmac_handlers = (iwm_handler *) iwm_lmac_handlers;
+}
+
+static void iwm_remove_iv(struct sk_buff *skb, u32 hdr_total_len)
+{
+       struct ieee80211_hdr *hdr;
+       unsigned int hdr_len;
+
+       hdr = (struct ieee80211_hdr *)skb->data;
+
+       if (!ieee80211_has_protected(hdr->frame_control))
+               return;
+
+       hdr_len = ieee80211_hdrlen(hdr->frame_control);
+       if (hdr_total_len <= hdr_len)
+               return;
+
+       memmove(skb->data + (hdr_total_len - hdr_len), skb->data, hdr_len);
+       skb_pull(skb, (hdr_total_len - hdr_len));
+}
+
+static void iwm_rx_adjust_packet(struct iwm_priv *iwm,
+                                struct iwm_rx_packet *packet,
+                                struct iwm_rx_ticket_node *ticket_node)
+{
+       u32 payload_offset = 0, payload_len;
+       struct iwm_rx_ticket *ticket = ticket_node->ticket;
+       struct iwm_rx_mpdu_hdr *mpdu_hdr;
+       struct ieee80211_hdr *hdr;
+
+       mpdu_hdr = (struct iwm_rx_mpdu_hdr *)packet->skb->data;
+       payload_offset += sizeof(struct iwm_rx_mpdu_hdr);
+       /* Padding is 0 or 2 bytes */
+       payload_len = le16_to_cpu(mpdu_hdr->len) +
+               (le16_to_cpu(ticket->flags) & IWM_RX_TICKET_PAD_SIZE_MSK);
+       payload_len -= ticket->tail_len;
+
+       IWM_DBG_RX(iwm, DBG, "Packet adjusted, len:%d, offset:%d, "
+                  "ticket offset:%d ticket tail len:%d\n",
+                  payload_len, payload_offset, ticket->payload_offset,
+                  ticket->tail_len);
+
+       IWM_HEXDUMP(iwm, DBG, RX, "RAW: ", packet->skb->data, packet->skb->len);
+
+       skb_pull(packet->skb, payload_offset);
+       skb_trim(packet->skb, payload_len);
+
+       iwm_remove_iv(packet->skb, ticket->payload_offset);
+
+       hdr = (struct ieee80211_hdr *) packet->skb->data;
+       if (ieee80211_is_data_qos(hdr->frame_control)) {
+               /* UMAC handed QOS_DATA frame with 2 padding bytes appended
+                * to the qos_ctl field in IEEE 802.11 headers. */
+               memmove(packet->skb->data + IEEE80211_QOS_CTL_LEN + 2,
+                       packet->skb->data,
+                       ieee80211_hdrlen(hdr->frame_control) -
+                       IEEE80211_QOS_CTL_LEN);
+               hdr = (struct ieee80211_hdr *) skb_pull(packet->skb,
+                               IEEE80211_QOS_CTL_LEN + 2);
+               hdr->frame_control &= ~cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
+       }
+
+       IWM_HEXDUMP(iwm, DBG, RX, "ADJUSTED: ",
+                   packet->skb->data, packet->skb->len);
+}
+
+static void classify8023(struct sk_buff *skb)
+{
+       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+
+       if (ieee80211_is_data_qos(hdr->frame_control)) {
+               u8 *qc = ieee80211_get_qos_ctl(hdr);
+               /* frame has qos control */
+               skb->priority = *qc & IEEE80211_QOS_CTL_TID_MASK;
+       } else {
+               skb->priority = 0;
+       }
+}
+
+static void iwm_rx_process_packet(struct iwm_priv *iwm,
+                                 struct iwm_rx_packet *packet,
+                                 struct iwm_rx_ticket_node *ticket_node)
+{
+       int ret;
+       struct sk_buff *skb = packet->skb;
+       struct wireless_dev *wdev = iwm_to_wdev(iwm);
+       struct net_device *ndev = iwm_to_ndev(iwm);
+
+       IWM_DBG_RX(iwm, DBG, "Processing packet ID %d\n", packet->id);
+
+       switch (le16_to_cpu(ticket_node->ticket->action)) {
+       case IWM_RX_TICKET_RELEASE:
+               IWM_DBG_RX(iwm, DBG, "RELEASE packet\n");
+               classify8023(skb);
+               iwm_rx_adjust_packet(iwm, packet, ticket_node);
+               ret = ieee80211_data_to_8023(skb, ndev->dev_addr, wdev->iftype);
+               if (ret < 0) {
+                       IWM_DBG_RX(iwm, DBG, "Couldn't convert 802.11 header - "
+                                  "%d\n", ret);
+                       break;
+               }
+
+               IWM_HEXDUMP(iwm, DBG, RX, "802.3: ", skb->data, skb->len);
+
+               skb->dev = iwm_to_ndev(iwm);
+               skb->protocol = eth_type_trans(skb, ndev);
+               skb->ip_summed = CHECKSUM_UNNECESSARY;
+               memset(skb->cb, 0, sizeof(skb->cb));
+
+               ndev->stats.rx_packets++;
+               ndev->stats.rx_bytes += skb->len;
+
+               if (netif_rx(skb) == NET_RX_DROP) {
+                       IWM_ERR(iwm, "Packet dropped\n");
+                       ndev->stats.rx_dropped++;
+               }
+               break;
+       case IWM_RX_TICKET_DROP:
+               IWM_DBG_RX(iwm, DBG, "DROP packet\n");
+               kfree_skb(packet->skb);
+               break;
+       default:
+               IWM_ERR(iwm, "Unknow ticket action: %d\n",
+                       le16_to_cpu(ticket_node->ticket->action));
+               kfree_skb(packet->skb);
+       }
+
+       kfree(packet);
+       iwm_rx_ticket_node_free(ticket_node);
+}
+
+/*
+ * Rx data processing:
+ *
+ * We're receiving Rx packet from the LMAC, and Rx ticket from
+ * the UMAC.
+ * To forward a target data packet upstream (i.e. to the
+ * kernel network stack), we must have received an Rx ticket
+ * that tells us we're allowed to release this packet (ticket
+ * action is IWM_RX_TICKET_RELEASE). The Rx ticket also indicates,
+ * among other things, where valid data actually starts in the Rx
+ * packet.
+ */
+void iwm_rx_worker(struct work_struct *work)
+{
+       struct iwm_priv *iwm;
+       struct iwm_rx_ticket_node *ticket, *next;
+
+       iwm = container_of(work, struct iwm_priv, rx_worker);
+
+       /*
+        * We go through the tickets list and if there is a pending
+        * packet for it, we push it upstream.
+        * We stop whenever a ticket is missing its packet, as we're
+        * supposed to send the packets in order.
+        */
+       list_for_each_entry_safe(ticket, next, &iwm->rx_tickets, node) {
+               struct iwm_rx_packet *packet =
+                       iwm_rx_packet_get(iwm, le16_to_cpu(ticket->ticket->id));
+
+               if (!packet) {
+                       IWM_DBG_RX(iwm, DBG, "Skip rx_work: Wait for ticket %d "
+                                  "to be handled first\n",
+                                  le16_to_cpu(ticket->ticket->id));
+                       return;
+               }
+
+               list_del(&ticket->node);
+               list_del(&packet->node);
+               iwm_rx_process_packet(iwm, packet, ticket);
+       }
+}
+
diff --git a/drivers/net/wireless/iwmc3200wifi/rx.h b/drivers/net/wireless/iwmc3200wifi/rx.h
new file mode 100644 (file)
index 0000000..da0db91
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Intel Wireless Multicomm 3200 WiFi driver
+ *
+ * Copyright (C) 2009 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in
+ *     the documentation and/or other materials provided with the
+ *     distribution.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * Intel Corporation <ilw@linux.intel.com>
+ * Samuel Ortiz <samuel.ortiz@intel.com>
+ * Zhu Yi <yi.zhu@intel.com>
+ *
+ */
+
+#ifndef __IWM_RX_H__
+#define __IWM_RX_H__
+
+#include <linux/skbuff.h>
+
+#include "umac.h"
+
+struct iwm_rx_ticket_node {
+       struct list_head node;
+       struct iwm_rx_ticket *ticket;
+};
+
+struct iwm_rx_packet {
+       struct list_head node;
+       u16 id;
+       struct sk_buff *skb;
+       unsigned long pkt_size;
+};
+
+void iwm_rx_worker(struct work_struct *work);
+
+#endif
diff --git a/drivers/net/wireless/iwmc3200wifi/sdio.c b/drivers/net/wireless/iwmc3200wifi/sdio.c
new file mode 100644 (file)
index 0000000..b54da67
--- /dev/null
@@ -0,0 +1,516 @@
+/*
+ * Intel Wireless Multicomm 3200 WiFi driver
+ *
+ * Copyright (C) 2009 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in
+ *     the documentation and/or other materials provided with the
+ *     distribution.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * Intel Corporation <ilw@linux.intel.com>
+ * Samuel Ortiz <samuel.ortiz@intel.com>
+ * Zhu Yi <yi.zhu@intel.com>
+ *
+ */
+
+/*
+ * This is the SDIO bus specific hooks for iwm.
+ * It also is the module's entry point.
+ *
+ * Interesting code paths:
+ * iwm_sdio_probe() (Called by an SDIO bus scan)
+ *  -> iwm_if_alloc() (netdev.c)
+ *      -> iwm_wdev_alloc() (cfg80211.c, allocates and register our wiphy)
+ *          -> wiphy_new()
+ *          -> wiphy_register()
+ *      -> alloc_netdev_mq()
+ *      -> register_netdev()
+ *
+ * iwm_sdio_remove()
+ *  -> iwm_if_free() (netdev.c)
+ *      -> unregister_netdev()
+ *      -> iwm_wdev_free() (cfg80211.c)
+ *          -> wiphy_unregister()
+ *          -> wiphy_free()
+ *
+ * iwm_sdio_isr() (called in process context from the SDIO core code)
+ *  -> queue_work(.., isr_worker)
+ *      -- [async] --> iwm_sdio_isr_worker()
+ *                      -> iwm_rx_handle()
+ */
+
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <linux/debugfs.h>
+#include <linux/mmc/sdio.h>
+#include <linux/mmc/sdio_func.h>
+
+#include "iwm.h"
+#include "debug.h"
+#include "bus.h"
+#include "sdio.h"
+
+static void iwm_sdio_isr_worker(struct work_struct *work)
+{
+       struct iwm_sdio_priv *hw;
+       struct iwm_priv *iwm;
+       struct iwm_rx_info *rx_info;
+       struct sk_buff *skb;
+       u8 *rx_buf;
+       unsigned long rx_size;
+
+       hw = container_of(work, struct iwm_sdio_priv, isr_worker);
+       iwm = hw_to_iwm(hw);
+
+       while (!skb_queue_empty(&iwm->rx_list)) {
+               skb = skb_dequeue(&iwm->rx_list);
+               rx_info = skb_to_rx_info(skb);
+               rx_size = rx_info->rx_size;
+               rx_buf = skb->data;
+
+               IWM_HEXDUMP(iwm, DBG, SDIO, "RX: ", rx_buf, rx_size);
+               if (iwm_rx_handle(iwm, rx_buf, rx_size) < 0)
+                       IWM_WARN(iwm, "RX error\n");
+
+               kfree_skb(skb);
+       }
+}
+
+static void iwm_sdio_isr(struct sdio_func *func)
+{
+       struct iwm_priv *iwm;
+       struct iwm_sdio_priv *hw;
+       struct iwm_rx_info *rx_info;
+       struct sk_buff *skb;
+       unsigned long buf_size, read_size;
+       int ret;
+       u8 val;
+
+       hw = sdio_get_drvdata(func);
+       iwm = hw_to_iwm(hw);
+
+       buf_size = hw->blk_size;
+
+       /* We're checking the status */
+       val = sdio_readb(func, IWM_SDIO_INTR_STATUS_ADDR, &ret);
+       if (val == 0 || ret < 0) {
+               IWM_ERR(iwm, "Wrong INTR_STATUS\n");
+               return;
+       }
+
+       /* See if we have free buffers */
+       if (skb_queue_len(&iwm->rx_list) > IWM_RX_LIST_SIZE) {
+               IWM_ERR(iwm, "No buffer for more Rx frames\n");
+               return;
+       }
+
+       /* We first read the transaction size */
+       read_size = sdio_readb(func, IWM_SDIO_INTR_GET_SIZE_ADDR + 1, &ret);
+       read_size = read_size << 8;
+
+       if (ret < 0) {
+               IWM_ERR(iwm, "Couldn't read the xfer size\n");
+               return;
+       }
+
+       /* We need to clear the INT register */
+       sdio_writeb(func, 1, IWM_SDIO_INTR_CLEAR_ADDR, &ret);
+       if (ret < 0) {
+               IWM_ERR(iwm, "Couldn't clear the INT register\n");
+               return;
+       }
+
+       while (buf_size < read_size)
+               buf_size <<= 1;
+
+       skb = dev_alloc_skb(buf_size);
+       if (!skb) {
+               IWM_ERR(iwm, "Couldn't alloc RX skb\n");
+               return;
+       }
+       rx_info = skb_to_rx_info(skb);
+       rx_info->rx_size = read_size;
+       rx_info->rx_buf_size = buf_size;
+
+       /* Now we can read the actual buffer */
+       ret = sdio_memcpy_fromio(func, skb_put(skb, read_size),
+                                IWM_SDIO_DATA_ADDR, read_size);
+
+       /* The skb is put on a driver's specific Rx SKB list */
+       skb_queue_tail(&iwm->rx_list, skb);
+
+       /* We can now schedule the actual worker */
+       queue_work(hw->isr_wq, &hw->isr_worker);
+}
+
+static void iwm_sdio_rx_free(struct iwm_sdio_priv *hw)
+{
+       struct iwm_priv *iwm = hw_to_iwm(hw);
+
+       flush_workqueue(hw->isr_wq);
+
+       skb_queue_purge(&iwm->rx_list);
+}
+
+/* Bus ops */
+static int if_sdio_enable(struct iwm_priv *iwm)
+{
+       struct iwm_sdio_priv *hw = iwm_to_if_sdio(iwm);
+       int ret;
+
+       sdio_claim_host(hw->func);
+
+       ret = sdio_enable_func(hw->func);
+       if (ret) {
+               IWM_ERR(iwm, "Couldn't enable the device: is TOP driver "
+                       "loaded and functional?\n");
+               goto release_host;
+       }
+
+       iwm_reset(iwm);
+
+       ret = sdio_claim_irq(hw->func, iwm_sdio_isr);
+       if (ret) {
+               IWM_ERR(iwm, "Failed to claim irq: %d\n", ret);
+               goto release_host;
+       }
+
+       sdio_writeb(hw->func, 1, IWM_SDIO_INTR_ENABLE_ADDR, &ret);
+       if (ret < 0) {
+               IWM_ERR(iwm, "Couldn't enable INTR: %d\n", ret);
+               goto release_irq;
+       }
+
+       sdio_release_host(hw->func);
+
+       IWM_DBG_SDIO(iwm, INFO, "IWM SDIO enable\n");
+
+       return 0;
+
+ release_irq:
+       sdio_release_irq(hw->func);
+ release_host:
+       sdio_release_host(hw->func);
+
+       return ret;
+}
+
+static int if_sdio_disable(struct iwm_priv *iwm)
+{
+       struct iwm_sdio_priv *hw = iwm_to_if_sdio(iwm);
+       int ret;
+
+       iwm_reset(iwm);
+
+       sdio_claim_host(hw->func);
+       sdio_writeb(hw->func, 0, IWM_SDIO_INTR_ENABLE_ADDR, &ret);
+       if (ret < 0)
+               IWM_WARN(iwm, "Couldn't disable INTR: %d\n", ret);
+
+       sdio_release_irq(hw->func);
+       sdio_disable_func(hw->func);
+       sdio_release_host(hw->func);
+
+       iwm_sdio_rx_free(hw);
+
+       IWM_DBG_SDIO(iwm, INFO, "IWM SDIO disable\n");
+
+       return 0;
+}
+
+static int if_sdio_send_chunk(struct iwm_priv *iwm, u8 *buf, int count)
+{
+       struct iwm_sdio_priv *hw = iwm_to_if_sdio(iwm);
+       int aligned_count = ALIGN(count, hw->blk_size);
+       int ret;
+
+       if ((unsigned long)buf & 0x3) {
+               IWM_ERR(iwm, "buf <%p> is not dword aligned\n", buf);
+               /* TODO: Is this a hardware limitation? use get_unligned */
+               return -EINVAL;
+       }
+
+       sdio_claim_host(hw->func);
+       ret = sdio_memcpy_toio(hw->func, IWM_SDIO_DATA_ADDR, buf,
+                              aligned_count);
+       sdio_release_host(hw->func);
+
+       return ret;
+}
+
+/* debugfs hooks */
+static int iwm_debugfs_sdio_open(struct inode *inode, struct file *filp)
+{
+       filp->private_data = inode->i_private;
+       return 0;
+}
+
+static ssize_t iwm_debugfs_sdio_read(struct file *filp, char __user *buffer,
+                                    size_t count, loff_t *ppos)
+{
+       struct iwm_priv *iwm = filp->private_data;
+       struct iwm_sdio_priv *hw = iwm_to_if_sdio(iwm);
+       char *buf;
+       u8 cccr;
+       int buf_len = 4096, ret;
+       size_t len = 0;
+
+       if (*ppos != 0)
+               return 0;
+       if (count < sizeof(buf))
+               return -ENOSPC;
+
+       buf = kzalloc(buf_len, GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
+
+       sdio_claim_host(hw->func);
+
+       cccr =  sdio_f0_readb(hw->func, SDIO_CCCR_IOEx, &ret);
+       if (ret) {
+               IWM_ERR(iwm, "Could not read SDIO_CCCR_IOEx\n");
+               goto err;
+       }
+       len += snprintf(buf + len, buf_len - len, "CCCR_IOEx:  0x%x\n", cccr);
+
+       cccr =  sdio_f0_readb(hw->func, SDIO_CCCR_IORx, &ret);
+       if (ret) {
+               IWM_ERR(iwm, "Could not read SDIO_CCCR_IORx\n");
+               goto err;
+       }
+       len += snprintf(buf + len, buf_len - len, "CCCR_IORx:  0x%x\n", cccr);
+
+
+       cccr =  sdio_f0_readb(hw->func, SDIO_CCCR_IENx, &ret);
+       if (ret) {
+               IWM_ERR(iwm, "Could not read SDIO_CCCR_IENx\n");
+               goto err;
+       }
+       len += snprintf(buf + len, buf_len - len, "CCCR_IENx:  0x%x\n", cccr);
+
+
+       cccr =  sdio_f0_readb(hw->func, SDIO_CCCR_INTx, &ret);
+       if (ret) {
+               IWM_ERR(iwm, "Could not read SDIO_CCCR_INTx\n");
+               goto err;
+       }
+       len += snprintf(buf + len, buf_len - len, "CCCR_INTx:  0x%x\n", cccr);
+
+
+       cccr =  sdio_f0_readb(hw->func, SDIO_CCCR_ABORT, &ret);
+       if (ret) {
+               IWM_ERR(iwm, "Could not read SDIO_CCCR_ABORTx\n");
+               goto err;
+       }
+       len += snprintf(buf + len, buf_len - len, "CCCR_ABORT: 0x%x\n", cccr);
+
+       cccr =  sdio_f0_readb(hw->func, SDIO_CCCR_IF, &ret);
+       if (ret) {
+               IWM_ERR(iwm, "Could not read SDIO_CCCR_IF\n");
+               goto err;
+       }
+       len += snprintf(buf + len, buf_len - len, "CCCR_IF:    0x%x\n", cccr);
+
+
+       cccr =  sdio_f0_readb(hw->func, SDIO_CCCR_CAPS, &ret);
+       if (ret) {
+               IWM_ERR(iwm, "Could not read SDIO_CCCR_CAPS\n");
+               goto err;
+       }
+       len += snprintf(buf + len, buf_len - len, "CCCR_CAPS:  0x%x\n", cccr);
+
+       cccr =  sdio_f0_readb(hw->func, SDIO_CCCR_CIS, &ret);
+       if (ret) {
+               IWM_ERR(iwm, "Could not read SDIO_CCCR_CIS\n");
+               goto err;
+       }
+       len += snprintf(buf + len, buf_len - len, "CCCR_CIS:   0x%x\n", cccr);
+
+       ret = simple_read_from_buffer(buffer, len, ppos, buf, buf_len);
+err:
+       sdio_release_host(hw->func);
+
+       kfree(buf);
+
+       return ret;
+}
+
+static const struct file_operations iwm_debugfs_sdio_fops = {
+       .owner =        THIS_MODULE,
+       .open =         iwm_debugfs_sdio_open,
+       .read =         iwm_debugfs_sdio_read,
+};
+
+static int if_sdio_debugfs_init(struct iwm_priv *iwm, struct dentry *parent_dir)
+{
+       int result;
+       struct iwm_sdio_priv *hw = iwm_to_if_sdio(iwm);
+
+       hw->cccr_dentry = debugfs_create_file("cccr", 0200,
+                                             parent_dir, iwm,
+                                             &iwm_debugfs_sdio_fops);
+       result = PTR_ERR(hw->cccr_dentry);
+       if (IS_ERR(hw->cccr_dentry) && (result != -ENODEV)) {
+               IWM_ERR(iwm, "Couldn't create CCCR entry: %d\n", result);
+               return result;
+       }
+
+       return 0;
+}
+
+static void if_sdio_debugfs_exit(struct iwm_priv *iwm)
+{
+       struct iwm_sdio_priv *hw = iwm_to_if_sdio(iwm);
+
+       debugfs_remove(hw->cccr_dentry);
+}
+
+static struct iwm_if_ops if_sdio_ops = {
+       .enable = if_sdio_enable,
+       .disable = if_sdio_disable,
+       .send_chunk = if_sdio_send_chunk,
+       .debugfs_init = if_sdio_debugfs_init,
+       .debugfs_exit = if_sdio_debugfs_exit,
+       .umac_name = "iwmc3200wifi-umac-sdio.bin",
+       .calib_lmac_name = "iwmc3200wifi-calib-sdio.bin",
+       .lmac_name = "iwmc3200wifi-lmac-sdio.bin",
+};
+
+static int iwm_sdio_probe(struct sdio_func *func,
+                         const struct sdio_device_id *id)
+{
+       struct iwm_priv *iwm;
+       struct iwm_sdio_priv *hw;
+       struct device *dev = &func->dev;
+       int ret;
+
+       /* check if TOP has already initialized the card */
+       sdio_claim_host(func);
+       ret = sdio_enable_func(func);
+       if (ret) {
+               dev_err(dev, "wait for TOP to enable the device\n");
+               sdio_release_host(func);
+               return ret;
+       }
+
+       ret = sdio_set_block_size(func, IWM_SDIO_BLK_SIZE);
+
+       sdio_disable_func(func);
+       sdio_release_host(func);
+
+       if (ret < 0) {
+               dev_err(dev, "Failed to set block size: %d\n", ret);
+               return ret;
+       }
+
+       iwm = iwm_if_alloc(sizeof(struct iwm_sdio_priv), dev, &if_sdio_ops);
+       if (IS_ERR(iwm)) {
+               dev_err(dev, "allocate SDIO interface failed\n");
+               return PTR_ERR(iwm);
+       }
+
+       hw = iwm_private(iwm);
+       hw->iwm = iwm;
+
+       ret = iwm_debugfs_init(iwm);
+       if (ret < 0) {
+               IWM_ERR(iwm, "Debugfs registration failed\n");
+               goto if_free;
+       }
+
+       sdio_set_drvdata(func, hw);
+
+       hw->func = func;
+       hw->blk_size = IWM_SDIO_BLK_SIZE;
+
+       hw->isr_wq = create_singlethread_workqueue(KBUILD_MODNAME "_sdio");
+       if (!hw->isr_wq) {
+               ret = -ENOMEM;
+               goto debugfs_exit;
+       }
+
+       INIT_WORK(&hw->isr_worker, iwm_sdio_isr_worker);
+
+       dev_info(dev, "IWM SDIO probe\n");
+
+       return 0;
+
+ debugfs_exit:
+       iwm_debugfs_exit(iwm);
+ if_free:
+       iwm_if_free(iwm);
+       return ret;
+}
+
+static void iwm_sdio_remove(struct sdio_func *func)
+{
+       struct iwm_sdio_priv *hw = sdio_get_drvdata(func);
+       struct iwm_priv *iwm = hw_to_iwm(hw);
+       struct device *dev = &func->dev;
+
+       iwm_debugfs_exit(iwm);
+       iwm_if_free(iwm);
+       destroy_workqueue(hw->isr_wq);
+
+       sdio_set_drvdata(func, NULL);
+
+       dev_info(dev, "IWM SDIO remove\n");
+
+       return;
+}
+
+static const struct sdio_device_id iwm_sdio_ids[] = {
+       { SDIO_DEVICE(SDIO_VENDOR_ID_INTEL, SDIO_DEVICE_ID_IWM) },
+       { /* end: all zeroes */ },
+};
+MODULE_DEVICE_TABLE(sdio, iwm_sdio_ids);
+
+static struct sdio_driver iwm_sdio_driver = {
+       .name           = "iwm_sdio",
+       .id_table       = iwm_sdio_ids,
+       .probe          = iwm_sdio_probe,
+       .remove         = iwm_sdio_remove,
+};
+
+static int __init iwm_sdio_init_module(void)
+{
+       int ret;
+
+       ret = sdio_register_driver(&iwm_sdio_driver);
+
+       return ret;
+}
+
+static void __exit iwm_sdio_exit_module(void)
+{
+       sdio_unregister_driver(&iwm_sdio_driver);
+}
+
+module_init(iwm_sdio_init_module);
+module_exit(iwm_sdio_exit_module);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR(IWM_COPYRIGHT " " IWM_AUTHOR);
diff --git a/drivers/net/wireless/iwmc3200wifi/sdio.h b/drivers/net/wireless/iwmc3200wifi/sdio.h
new file mode 100644 (file)
index 0000000..b3c156b
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Intel Wireless Multicomm 3200 WiFi driver
+ *
+ * Copyright (C) 2009 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in
+ *     the documentation and/or other materials provided with the
+ *     distribution.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * Intel Corporation <ilw@linux.intel.com>
+ * Samuel Ortiz <samuel.ortiz@intel.com>
+ * Zhu Yi <yi.zhu@intel.com>
+ *
+ */
+
+#ifndef __IWM_SDIO_H__
+#define __IWM_SDIO_H__
+
+#define SDIO_VENDOR_ID_INTEL 0x89
+#define SDIO_DEVICE_ID_IWM   0x1403
+
+#define IWM_SDIO_DATA_ADDR           0x0
+#define IWM_SDIO_INTR_ENABLE_ADDR    0x14
+#define IWM_SDIO_INTR_STATUS_ADDR    0x13
+#define IWM_SDIO_INTR_CLEAR_ADDR     0x13
+#define IWM_SDIO_INTR_GET_SIZE_ADDR  0x2C
+
+#define IWM_SDIO_BLK_SIZE       256
+
+#define iwm_to_if_sdio(i) (struct iwm_sdio_priv *)(iwm->private)
+
+struct iwm_sdio_priv {
+       struct sdio_func *func;
+       struct iwm_priv *iwm;
+
+       struct workqueue_struct *isr_wq;
+       struct work_struct isr_worker;
+
+       struct dentry *cccr_dentry;
+
+       unsigned int blk_size;
+};
+
+#endif
diff --git a/drivers/net/wireless/iwmc3200wifi/tx.c b/drivers/net/wireless/iwmc3200wifi/tx.c
new file mode 100644 (file)
index 0000000..e3b4f79
--- /dev/null
@@ -0,0 +1,492 @@
+/*
+ * Intel Wireless Multicomm 3200 WiFi driver
+ *
+ * Copyright (C) 2009 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in
+ *     the documentation and/or other materials provided with the
+ *     distribution.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * Intel Corporation <ilw@linux.intel.com>
+ * Samuel Ortiz <samuel.ortiz@intel.com>
+ * Zhu Yi <yi.zhu@intel.com>
+ *
+ */
+
+/*
+ * iwm Tx theory of operation:
+ *
+ * 1) We receive a 802.3 frame from the stack
+ * 2) We convert it to a 802.11 frame [iwm_xmit_frame]
+ * 3) We queue it to its corresponding tx queue [iwm_xmit_frame]
+ * 4) We schedule the tx worker. There is one worker per tx
+ *    queue. [iwm_xmit_frame]
+ * 5) The tx worker is scheduled
+ * 6) We go through every queued skb on the tx queue, and for each
+ *    and every one of them: [iwm_tx_worker]
+ *    a) We check if we have enough Tx credits (see below for a Tx
+ *       credits description) for the frame length. [iwm_tx_worker]
+ *    b) If we do, we aggregate the Tx frame into a UDMA one, by
+ *       concatenating one REPLY_TX command per Tx frame. [iwm_tx_worker]
+ *    c) When we run out of credits, or when we reach the maximum
+ *       concatenation size, we actually send the concatenated UDMA
+ *       frame. [iwm_tx_worker]
+ *
+ * When we run out of Tx credits, the skbs are filling the tx queue,
+ * and eventually we will stop the netdev queue. [iwm_tx_worker]
+ * The tx queue is emptied as we're getting new tx credits, by
+ * scheduling the tx_worker. [iwm_tx_credit_inc]
+ * The netdev queue is started again when we have enough tx credits,
+ * and when our tx queue has some reasonable amout of space available
+ * (i.e. half of the max size). [iwm_tx_worker]
+ */
+
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/ieee80211.h>
+
+#include "iwm.h"
+#include "debug.h"
+#include "commands.h"
+#include "hal.h"
+#include "umac.h"
+#include "bus.h"
+
+#define IWM_UMAC_PAGE_ALLOC_WRAP 0xffff
+
+#define BYTES_TO_PAGES(n)       (1 + ((n) >> ilog2(IWM_UMAC_PAGE_SIZE)) - \
+                                (((n) & (IWM_UMAC_PAGE_SIZE - 1)) == 0))
+
+#define pool_id_to_queue(id)    ((id < IWM_TX_CMD_QUEUE) ? id : id - 1)
+#define queue_to_pool_id(q)     ((q < IWM_TX_CMD_QUEUE) ? q : q + 1)
+
+/* require to hold tx_credit lock */
+static int iwm_tx_credit_get(struct iwm_tx_credit *tx_credit, int id)
+{
+       struct pool_entry *pool = &tx_credit->pools[id];
+       struct spool_entry *spool = &tx_credit->spools[pool->sid];
+       int spool_pages;
+
+       /* number of pages can be taken from spool by this pool */
+       spool_pages = spool->max_pages - spool->alloc_pages +
+                     max(pool->min_pages - pool->alloc_pages, 0);
+
+       return min(pool->max_pages - pool->alloc_pages, spool_pages);
+}
+
+static bool iwm_tx_credit_ok(struct iwm_priv *iwm, int id, int nb)
+{
+       u32 npages = BYTES_TO_PAGES(nb);
+
+       if (npages <= iwm_tx_credit_get(&iwm->tx_credit, id))
+               return 1;
+
+       set_bit(id, &iwm->tx_credit.full_pools_map);
+
+       IWM_DBG_TX(iwm, DBG, "LINK: stop txq[%d], available credit: %d\n",
+                  pool_id_to_queue(id),
+                  iwm_tx_credit_get(&iwm->tx_credit, id));
+
+       return 0;
+}
+
+void iwm_tx_credit_inc(struct iwm_priv *iwm, int id, int total_freed_pages)
+{
+       struct pool_entry *pool;
+       struct spool_entry *spool;
+       int freed_pages;
+       int queue;
+
+       BUG_ON(id >= IWM_MACS_OUT_GROUPS);
+
+       pool = &iwm->tx_credit.pools[id];
+       spool = &iwm->tx_credit.spools[pool->sid];
+
+       freed_pages = total_freed_pages - pool->total_freed_pages;
+       IWM_DBG_TX(iwm, DBG, "Free %d pages for pool[%d]\n", freed_pages, id);
+
+       if (!freed_pages) {
+               IWM_DBG_TX(iwm, DBG, "No pages are freed by UMAC\n");
+               return;
+       } else if (freed_pages < 0)
+               freed_pages += IWM_UMAC_PAGE_ALLOC_WRAP + 1;
+
+       if (pool->alloc_pages > pool->min_pages) {
+               int spool_pages = pool->alloc_pages - pool->min_pages;
+               spool_pages = min(spool_pages, freed_pages);
+               spool->alloc_pages -= spool_pages;
+       }
+
+       pool->alloc_pages -= freed_pages;
+       pool->total_freed_pages = total_freed_pages;
+
+       IWM_DBG_TX(iwm, DBG, "Pool[%d] pages alloc: %d, total_freed: %d, "
+                  "Spool[%d] pages alloc: %d\n", id, pool->alloc_pages,
+                  pool->total_freed_pages, pool->sid, spool->alloc_pages);
+
+       if (test_bit(id, &iwm->tx_credit.full_pools_map) &&
+           (pool->alloc_pages < pool->max_pages / 2)) {
+               clear_bit(id, &iwm->tx_credit.full_pools_map);
+
+               queue = pool_id_to_queue(id);
+
+               IWM_DBG_TX(iwm, DBG, "LINK: start txq[%d], available "
+                          "credit: %d\n", queue,
+                          iwm_tx_credit_get(&iwm->tx_credit, id));
+               queue_work(iwm->txq[queue].wq, &iwm->txq[queue].worker);
+       }
+}
+
+static void iwm_tx_credit_dec(struct iwm_priv *iwm, int id, int alloc_pages)
+{
+       struct pool_entry *pool;
+       struct spool_entry *spool;
+       int spool_pages;
+
+       IWM_DBG_TX(iwm, DBG, "Allocate %d pages for pool[%d]\n",
+                  alloc_pages, id);
+
+       BUG_ON(id >= IWM_MACS_OUT_GROUPS);
+
+       pool = &iwm->tx_credit.pools[id];
+       spool = &iwm->tx_credit.spools[pool->sid];
+
+       spool_pages = pool->alloc_pages + alloc_pages - pool->min_pages;
+
+       if (pool->alloc_pages >= pool->min_pages)
+               spool->alloc_pages += alloc_pages;
+       else if (spool_pages > 0)
+               spool->alloc_pages += spool_pages;
+
+       pool->alloc_pages += alloc_pages;
+
+       IWM_DBG_TX(iwm, DBG, "Pool[%d] pages alloc: %d, total_freed: %d, "
+                  "Spool[%d] pages alloc: %d\n", id, pool->alloc_pages,
+                  pool->total_freed_pages, pool->sid, spool->alloc_pages);
+}
+
+int iwm_tx_credit_alloc(struct iwm_priv *iwm, int id, int nb)
+{
+       u32 npages = BYTES_TO_PAGES(nb);
+       int ret = 0;
+
+       spin_lock(&iwm->tx_credit.lock);
+
+       if (!iwm_tx_credit_ok(iwm, id, nb)) {
+               IWM_DBG_TX(iwm, DBG, "No credit avaliable for pool[%d]\n", id);
+               ret = -ENOSPC;
+               goto out;
+       }
+
+       iwm_tx_credit_dec(iwm, id, npages);
+
+ out:
+       spin_unlock(&iwm->tx_credit.lock);
+       return ret;
+}
+
+/*
+ * Since we're on an SDIO or USB bus, we are not sharing memory
+ * for storing to be transmitted frames. The host needs to push
+ * them upstream. As a consequence there needs to be a way for
+ * the target to let us know if it can actually take more TX frames
+ * or not. This is what Tx credits are for.
+ *
+ * For each Tx HW queue, we have a Tx pool, and then we have one
+ * unique super pool (spool), which is actually a global pool of
+ * all the UMAC pages.
+ * For each Tx pool we have a min_pages, a max_pages fields, and a
+ * alloc_pages fields. The alloc_pages tracks the number of pages
+ * currently allocated from the tx pool.
+ * Here are the rules to check if given a tx frame we have enough
+ * tx credits for it:
+ * 1) We translate the frame length into a number of UMAC pages.
+ *    Let's call them n_pages.
+ * 2) For the corresponding tx pool, we check if n_pages +
+ *    pool->alloc_pages is higher than pool->min_pages. min_pages
+ *    represent a set of pre-allocated pages on the tx pool. If
+ *    that's the case, then we need to allocate those pages from
+ *    the spool. We can do so until we reach spool->max_pages.
+ * 3) Each tx pool is not allowed to allocate more than pool->max_pages
+ *    from the spool, so once we're over min_pages, we can allocate
+ *    pages from the spool, but not more than max_pages.
+ *
+ * When the tx code path needs to send a tx frame, it checks first
+ * if it has enough tx credits, following those rules. [iwm_tx_credit_get]
+ * If it does, it then updates the pool and spool counters and
+ * then send the frame. [iwm_tx_credit_alloc and iwm_tx_credit_dec]
+ * On the other side, when the UMAC is done transmitting frames, it
+ * will send a credit update notification to the host. This is when
+ * the pool and spool counters gets to be decreased. [iwm_tx_credit_inc,
+ * called from rx.c:iwm_ntf_tx_credit_update]
+ *
+ */
+void iwm_tx_credit_init_pools(struct iwm_priv *iwm,
+                             struct iwm_umac_notif_alive *alive)
+{
+       int i, sid, pool_pages;
+
+       spin_lock(&iwm->tx_credit.lock);
+
+       iwm->tx_credit.pool_nr = le16_to_cpu(alive->page_grp_count);
+       iwm->tx_credit.full_pools_map = 0;
+       memset(&iwm->tx_credit.spools[0], 0, sizeof(struct spool_entry));
+
+       IWM_DBG_TX(iwm, DBG, "Pools number is %d\n", iwm->tx_credit.pool_nr);
+
+       for (i = 0; i < iwm->tx_credit.pool_nr; i++) {
+               __le32 page_grp_state = alive->page_grp_state[i];
+
+               iwm->tx_credit.pools[i].id = GET_VAL32(page_grp_state,
+                               UMAC_ALIVE_PAGE_STS_GRP_NUM);
+               iwm->tx_credit.pools[i].sid = GET_VAL32(page_grp_state,
+                               UMAC_ALIVE_PAGE_STS_SGRP_NUM);
+               iwm->tx_credit.pools[i].min_pages = GET_VAL32(page_grp_state,
+                               UMAC_ALIVE_PAGE_STS_GRP_MIN_SIZE);
+               iwm->tx_credit.pools[i].max_pages = GET_VAL32(page_grp_state,
+                               UMAC_ALIVE_PAGE_STS_GRP_MAX_SIZE);
+               iwm->tx_credit.pools[i].alloc_pages = 0;
+               iwm->tx_credit.pools[i].total_freed_pages = 0;
+
+               sid = iwm->tx_credit.pools[i].sid;
+               pool_pages = iwm->tx_credit.pools[i].min_pages;
+
+               if (iwm->tx_credit.spools[sid].max_pages == 0) {
+                       iwm->tx_credit.spools[sid].id = sid;
+                       iwm->tx_credit.spools[sid].max_pages =
+                               GET_VAL32(page_grp_state,
+                                         UMAC_ALIVE_PAGE_STS_SGRP_MAX_SIZE);
+                       iwm->tx_credit.spools[sid].alloc_pages = 0;
+               }
+
+               iwm->tx_credit.spools[sid].alloc_pages += pool_pages;
+
+               IWM_DBG_TX(iwm, DBG, "Pool idx: %d, id: %d, sid: %d, capacity "
+                          "min: %d, max: %d, pool alloc: %d, total_free: %d, "
+                          "super poll alloc: %d\n",
+                          i, iwm->tx_credit.pools[i].id,
+                          iwm->tx_credit.pools[i].sid,
+                          iwm->tx_credit.pools[i].min_pages,
+                          iwm->tx_credit.pools[i].max_pages,
+                          iwm->tx_credit.pools[i].alloc_pages,
+                          iwm->tx_credit.pools[i].total_freed_pages,
+                          iwm->tx_credit.spools[sid].alloc_pages);
+       }
+
+       spin_unlock(&iwm->tx_credit.lock);
+}
+
+#define IWM_UDMA_HDR_LEN       sizeof(struct iwm_umac_wifi_out_hdr)
+
+static int iwm_tx_build_packet(struct iwm_priv *iwm, struct sk_buff *skb,
+                              int pool_id, u8 *buf)
+{
+       struct iwm_umac_wifi_out_hdr *hdr = (struct iwm_umac_wifi_out_hdr *)buf;
+       struct iwm_udma_wifi_cmd udma_cmd;
+       struct iwm_umac_cmd umac_cmd;
+       struct iwm_tx_info *tx_info = skb_to_tx_info(skb);
+
+       udma_cmd.count = cpu_to_le16(skb->len +
+                                    sizeof(struct iwm_umac_fw_cmd_hdr));
+       /* set EOP to 0 here. iwm_udma_wifi_hdr_set_eop() will be
+        * called later to set EOP for the last packet. */
+       udma_cmd.eop = 0;
+       udma_cmd.credit_group = pool_id;
+       udma_cmd.ra_tid = tx_info->sta << 4 | tx_info->tid;
+       udma_cmd.lmac_offset = 0;
+
+       umac_cmd.id = REPLY_TX;
+       umac_cmd.count = cpu_to_le16(skb->len);
+       umac_cmd.color = tx_info->color;
+       umac_cmd.resp = 0;
+       umac_cmd.seq_num = cpu_to_le16(iwm_alloc_wifi_cmd_seq(iwm));
+
+       iwm_build_udma_wifi_hdr(iwm, &hdr->hw_hdr, &udma_cmd);
+       iwm_build_umac_hdr(iwm, &hdr->sw_hdr, &umac_cmd);
+
+       memcpy(buf + sizeof(*hdr), skb->data, skb->len);
+
+       return 0;
+}
+
+static int iwm_tx_send_concat_packets(struct iwm_priv *iwm,
+                                     struct iwm_tx_queue *txq)
+{
+       int ret;
+
+       if (!txq->concat_count)
+               return 0;
+
+       IWM_DBG_TX(iwm, DBG, "Send concatenated Tx: queue %d, %d bytes\n",
+                  txq->id, txq->concat_count);
+
+       /* mark EOP for the last packet */
+       iwm_udma_wifi_hdr_set_eop(iwm, txq->concat_ptr, 1);
+
+       ret = iwm_bus_send_chunk(iwm, txq->concat_buf, txq->concat_count);
+
+       txq->concat_count = 0;
+       txq->concat_ptr = txq->concat_buf;
+
+       return ret;
+}
+
+#define CONFIG_IWM_TX_CONCATENATED 1
+
+void iwm_tx_worker(struct work_struct *work)
+{
+       struct iwm_priv *iwm;
+       struct iwm_tx_info *tx_info = NULL;
+       struct sk_buff *skb;
+       int cmdlen, ret;
+       struct iwm_tx_queue *txq;
+       int pool_id;
+
+       txq = container_of(work, struct iwm_tx_queue, worker);
+       iwm = container_of(txq, struct iwm_priv, txq[txq->id]);
+
+       pool_id = queue_to_pool_id(txq->id);
+
+       while (!test_bit(pool_id, &iwm->tx_credit.full_pools_map) &&
+              !skb_queue_empty(&txq->queue)) {
+
+               skb = skb_dequeue(&txq->queue);
+               tx_info = skb_to_tx_info(skb);
+               cmdlen = IWM_UDMA_HDR_LEN + skb->len;
+
+               IWM_DBG_TX(iwm, DBG, "Tx frame on queue %d: skb: 0x%p, sta: "
+                          "%d, color: %d\n", txq->id, skb, tx_info->sta,
+                          tx_info->color);
+
+#if !CONFIG_IWM_TX_CONCATENATED
+               /* temporarily keep this to comparing the performance */
+               ret = iwm_send_packet(iwm, skb, pool_id);
+#else
+
+               if (txq->concat_count + cmdlen > IWM_HAL_CONCATENATE_BUF_SIZE)
+                       iwm_tx_send_concat_packets(iwm, txq);
+
+               ret = iwm_tx_credit_alloc(iwm, pool_id, cmdlen);
+               if (ret) {
+                       IWM_DBG_TX(iwm, DBG, "not enough tx_credit for queue "
+                                  "%d, Tx worker stopped\n", txq->id);
+                       skb_queue_head(&txq->queue, skb);
+                       break;
+               }
+
+               txq->concat_ptr = txq->concat_buf + txq->concat_count;
+               iwm_tx_build_packet(iwm, skb, pool_id, txq->concat_ptr);
+               txq->concat_count += ALIGN(cmdlen, 16);
+#endif
+               kfree_skb(skb);
+       }
+
+       iwm_tx_send_concat_packets(iwm, txq);
+
+       if (__netif_subqueue_stopped(iwm_to_ndev(iwm), txq->id) &&
+           !test_bit(pool_id, &iwm->tx_credit.full_pools_map) &&
+           (skb_queue_len(&txq->queue) < IWM_TX_LIST_SIZE / 2)) {
+               IWM_DBG_TX(iwm, DBG, "LINK: start netif_subqueue[%d]", txq->id);
+               netif_wake_subqueue(iwm_to_ndev(iwm), txq->id);
+       }
+}
+
+int iwm_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
+{
+       struct iwm_priv *iwm = ndev_to_iwm(netdev);
+       struct net_device *ndev = iwm_to_ndev(iwm);
+       struct wireless_dev *wdev = iwm_to_wdev(iwm);
+       u8 *dst_addr;
+       struct iwm_tx_info *tx_info;
+       struct iwm_tx_queue *txq;
+       struct iwm_sta_info *sta_info;
+       u8 sta_id;
+       u16 queue;
+       int ret;
+
+       if (!test_bit(IWM_STATUS_ASSOCIATED, &iwm->status)) {
+               IWM_DBG_TX(iwm, DBG, "LINK: stop netif_all_queues: "
+                          "not associated\n");
+               netif_tx_stop_all_queues(netdev);
+               goto drop;
+       }
+
+       queue = skb_get_queue_mapping(skb);
+       BUG_ON(queue >= IWM_TX_DATA_QUEUES); /* no iPAN yet */
+
+       txq = &iwm->txq[queue];
+
+       /* No free space for Tx, tx_worker is too slow */
+       if (skb_queue_len(&txq->queue) > IWM_TX_LIST_SIZE) {
+               IWM_DBG_TX(iwm, DBG, "LINK: stop netif_subqueue[%d]\n", queue);
+               netif_stop_subqueue(netdev, queue);
+               return NETDEV_TX_BUSY;
+       }
+
+       ret = ieee80211_data_from_8023(skb, netdev->dev_addr, wdev->iftype,
+                                      iwm->bssid, 0);
+       if (ret) {
+               IWM_ERR(iwm, "build wifi header failed\n");
+               goto drop;
+       }
+
+       dst_addr = ((struct ieee80211_hdr *)(skb->data))->addr1;
+
+       for (sta_id = 0; sta_id < IWM_STA_TABLE_NUM; sta_id++) {
+               sta_info = &iwm->sta_table[sta_id];
+               if (sta_info->valid &&
+                   !memcmp(dst_addr, sta_info->addr, ETH_ALEN))
+                       break;
+       }
+
+       if (sta_id == IWM_STA_TABLE_NUM) {
+               IWM_ERR(iwm, "STA %pM not found in sta_table, Tx ignored\n",
+                       dst_addr);
+               goto drop;
+       }
+
+       tx_info = skb_to_tx_info(skb);
+       tx_info->sta = sta_id;
+       tx_info->color = sta_info->color;
+       /* UMAC uses TID 8 (vs. 0) for non QoS packets */
+       if (sta_info->qos)
+               tx_info->tid = skb->priority;
+       else
+               tx_info->tid = IWM_UMAC_MGMT_TID;
+
+       skb_queue_tail(&iwm->txq[queue].queue, skb);
+
+       queue_work(iwm->txq[queue].wq, &iwm->txq[queue].worker);
+
+       ndev->stats.tx_packets++;
+       ndev->stats.tx_bytes += skb->len;
+       return NETDEV_TX_OK;
+
+ drop:
+       ndev->stats.tx_dropped++;
+       dev_kfree_skb_any(skb);
+       return NETDEV_TX_OK;
+}
diff --git a/drivers/net/wireless/iwmc3200wifi/umac.h b/drivers/net/wireless/iwmc3200wifi/umac.h
new file mode 100644 (file)
index 0000000..4a95cce
--- /dev/null
@@ -0,0 +1,744 @@
+/*
+ * Intel Wireless Multicomm 3200 WiFi driver
+ *
+ * Copyright (C) 2009 Intel Corporation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in
+ *     the documentation and/or other materials provided with the
+ *     distribution.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * Intel Corporation <ilw@linux.intel.com>
+ * Samuel Ortiz <samuel.ortiz@intel.com>
+ * Zhu Yi <yi.zhu@intel.com>
+ *
+ */
+
+#ifndef __IWM_UMAC_H__
+#define __IWM_UMAC_H__
+
+struct iwm_udma_in_hdr {
+       __le32 cmd;
+       __le32 size;
+} __attribute__ ((packed));
+
+struct iwm_udma_out_nonwifi_hdr {
+       __le32 cmd;
+       __le32 addr;
+       __le32 op1_sz;
+       __le32 op2;
+} __attribute__ ((packed));
+
+struct iwm_udma_out_wifi_hdr {
+       __le32 cmd;
+       __le32 meta_data;
+} __attribute__ ((packed));
+
+/* Sequence numbering */
+#define UMAC_WIFI_SEQ_NUM_BASE         1
+#define UMAC_WIFI_SEQ_NUM_MAX          0x4000
+#define UMAC_NONWIFI_SEQ_NUM_BASE      1
+#define UMAC_NONWIFI_SEQ_NUM_MAX       0x10
+
+/* MAC address address */
+#define WICO_MAC_ADDRESS_ADDR               0x604008F8
+
+/* RA / TID */
+#define UMAC_HDI_ACT_TBL_IDX_TID_POS                  0
+#define UMAC_HDI_ACT_TBL_IDX_TID_SEED                 0xF
+
+#define UMAC_HDI_ACT_TBL_IDX_RA_POS                   4
+#define UMAC_HDI_ACT_TBL_IDX_RA_SEED                  0xF
+
+#define UMAC_HDI_ACT_TBL_IDX_RA_UMAC                  0xF
+#define UMAC_HDI_ACT_TBL_IDX_TID_UMAC                 0x9
+#define UMAC_HDI_ACT_TBL_IDX_TID_LMAC                 0xA
+
+#define UMAC_HDI_ACT_TBL_IDX_HOST_CMD \
+       ((UMAC_HDI_ACT_TBL_IDX_RA_UMAC << UMAC_HDI_ACT_TBL_IDX_RA_POS) |\
+        (UMAC_HDI_ACT_TBL_IDX_TID_UMAC << UMAC_HDI_ACT_TBL_IDX_TID_POS))
+#define UMAC_HDI_ACT_TBL_IDX_UMAC_CMD \
+       ((UMAC_HDI_ACT_TBL_IDX_RA_UMAC << UMAC_HDI_ACT_TBL_IDX_RA_POS) |\
+       (UMAC_HDI_ACT_TBL_IDX_TID_LMAC << UMAC_HDI_ACT_TBL_IDX_TID_POS))
+
+/* iwm_umac_notif_alive.page_grp_state Group number -- bits [3:0] */
+#define UMAC_ALIVE_PAGE_STS_GRP_NUM_POS                0
+#define UMAC_ALIVE_PAGE_STS_GRP_NUM_SEED       0xF
+
+/* iwm_umac_notif_alive.page_grp_state Super group number -- bits [7:4] */
+#define UMAC_ALIVE_PAGE_STS_SGRP_NUM_POS       4
+#define UMAC_ALIVE_PAGE_STS_SGRP_NUM_SEED      0xF
+
+/* iwm_umac_notif_alive.page_grp_state Group min size -- bits [15:8] */
+#define UMAC_ALIVE_PAGE_STS_GRP_MIN_SIZE_POS   8
+#define UMAC_ALIVE_PAGE_STS_GRP_MIN_SIZE_SEED  0xFF
+
+/* iwm_umac_notif_alive.page_grp_state Group max size -- bits [23:16] */
+#define UMAC_ALIVE_PAGE_STS_GRP_MAX_SIZE_POS   16
+#define UMAC_ALIVE_PAGE_STS_GRP_MAX_SIZE_SEED  0xFF
+
+/* iwm_umac_notif_alive.page_grp_state Super group max size -- bits [31:24] */
+#define UMAC_ALIVE_PAGE_STS_SGRP_MAX_SIZE_POS  24
+#define UMAC_ALIVE_PAGE_STS_SGRP_MAX_SIZE_SEED 0xFF
+
+/* Barkers */
+#define UMAC_REBOOT_BARKER             0xdeadbeef
+#define UMAC_ACK_BARKER                        0xfeedbabe
+#define UMAC_PAD_TERMINAL              0xadadadad
+
+/* UMAC JMP address */
+#define UMAC_MU_FW_INST_DATA_12_ADDR    0xBF0000
+
+/* iwm_umac_hdi_out_hdr.cmd OP code -- bits [3:0] */
+#define UMAC_HDI_OUT_CMD_OPCODE_POS    0
+#define UMAC_HDI_OUT_CMD_OPCODE_SEED   0xF
+
+/* iwm_umac_hdi_out_hdr.cmd End-Of-Transfer -- bits [10:10] */
+#define UMAC_HDI_OUT_CMD_EOT_POS       10
+#define UMAC_HDI_OUT_CMD_EOT_SEED      0x1
+
+/* iwm_umac_hdi_out_hdr.cmd UTFD only usage -- bits [11:11] */
+#define UMAC_HDI_OUT_CMD_UTFD_ONLY_POS 11
+#define UMAC_HDI_OUT_CMD_UTFD_ONLY_SEED        0x1
+
+/* iwm_umac_hdi_out_hdr.cmd Non-WiFi HW sequence number -- bits [12:15] */
+#define UDMA_HDI_OUT_CMD_NON_WIFI_HW_SEQ_NUM_POS   12
+#define UDMA_HDI_OUT_CMD_NON_WIFI_HW_SEQ_NUM_SEED  0xF
+
+/* iwm_umac_hdi_out_hdr.cmd Signature -- bits [31:16] */
+#define UMAC_HDI_OUT_CMD_SIGNATURE_POS 16
+#define UMAC_HDI_OUT_CMD_SIGNATURE_SEED        0xFFFF
+
+/* iwm_umac_hdi_out_hdr.meta_data Byte count -- bits [11:0] */
+#define UMAC_HDI_OUT_BYTE_COUNT_POS    0
+#define UMAC_HDI_OUT_BYTE_COUNT_SEED   0xFFF
+
+/* iwm_umac_hdi_out_hdr.meta_data Credit group -- bits [15:12] */
+#define UMAC_HDI_OUT_CREDIT_GRP_POS    12
+#define UMAC_HDI_OUT_CREDIT_GRP_SEED   0xF
+
+/* iwm_umac_hdi_out_hdr.meta_data RA/TID -- bits [23:16] */
+#define UMAC_HDI_OUT_RATID_POS         16
+#define UMAC_HDI_OUT_RATID_SEED                0xFF
+
+/* iwm_umac_hdi_out_hdr.meta_data LMAC offset -- bits [31:24] */
+#define UMAC_HDI_OUT_LMAC_OFFSET_POS   24
+#define UMAC_HDI_OUT_LMAC_OFFSET_SEED  0xFF
+
+/* Signature */
+#define UMAC_HDI_OUT_SIGNATURE         0xCBBC
+
+/* buffer alignment */
+#define UMAC_HDI_BUF_ALIGN_MSK         0xF
+
+/*  iwm_umac_hdi_in_hdr.cmd OP code -- bits [3:0] */
+#define UMAC_HDI_IN_CMD_OPCODE_POS                0
+#define UMAC_HDI_IN_CMD_OPCODE_SEED               0xF
+
+/*  iwm_umac_hdi_in_hdr.cmd Non-WiFi API response -- bits [6:4] */
+#define UMAC_HDI_IN_CMD_NON_WIFI_RESP_POS         4
+#define UMAC_HDI_IN_CMD_NON_WIFI_RESP_SEED        0x7
+
+/* iwm_umac_hdi_in_hdr.cmd WiFi API source -- bits [5:4] */
+#define UMAC_HDI_IN_CMD_SOURCE_POS                4
+#define UMAC_HDI_IN_CMD_SOURCE_SEED               0x3
+
+/* iwm_umac_hdi_in_hdr.cmd WiFi API EOT -- bits [6:6] */
+#define UMAC_HDI_IN_CMD_EOT_POS                   6
+#define UMAC_HDI_IN_CMD_EOT_SEED                  0x1
+
+/* iwm_umac_hdi_in_hdr.cmd timestamp present -- bits [7:7] */
+#define UMAC_HDI_IN_CMD_TIME_STAMP_PRESENT_POS    7
+#define UMAC_HDI_IN_CMD_TIME_STAMP_PRESENT_SEED   0x1
+
+/* iwm_umac_hdi_in_hdr.cmd WiFi Non-last AMSDU -- bits [8:8] */
+#define UMAC_HDI_IN_CMD_NON_LAST_AMSDU_POS        8
+#define UMAC_HDI_IN_CMD_NON_LAST_AMSDU_SEED       0x1
+
+/* iwm_umac_hdi_in_hdr.cmd WiFi HW sequence number -- bits [31:9] */
+#define UMAC_HDI_IN_CMD_HW_SEQ_NUM_POS            9
+#define UMAC_HDI_IN_CMD_HW_SEQ_NUM_SEED           0x7FFFFF
+
+/* iwm_umac_hdi_in_hdr.cmd Non-WiFi HW sequence number -- bits [12:15] */
+#define UDMA_HDI_IN_CMD_NON_WIFI_HW_SEQ_NUM_POS   12
+#define UDMA_HDI_IN_CMD_NON_WIFI_HW_SEQ_NUM_SEED  0xF
+
+/* iwm_umac_hdi_in_hdr.cmd Non-WiFi HW signature -- bits [16:31] */
+#define UDMA_HDI_IN_CMD_NON_WIFI_HW_SIG_POS       16
+#define UDMA_HDI_IN_CMD_NON_WIFI_HW_SIG_SEED      0xFFFF
+
+/* Fixed Non-WiFi signature */
+#define UDMA_HDI_IN_CMD_NON_WIFI_HW_SIG           0xCBBC
+
+/* IN NTFY op-codes */
+#define UMAC_NOTIFY_OPCODE_ALIVE               0xA1
+#define UMAC_NOTIFY_OPCODE_INIT_COMPLETE       0xA2
+#define UMAC_NOTIFY_OPCODE_WIFI_CORE_STATUS    0xA3
+#define UMAC_NOTIFY_OPCODE_ERROR               0xA4
+#define UMAC_NOTIFY_OPCODE_DEBUG               0xA5
+#define UMAC_NOTIFY_OPCODE_WIFI_IF_WRAPPER     0xB0
+#define UMAC_NOTIFY_OPCODE_STATS               0xB1
+#define UMAC_NOTIFY_OPCODE_PAGE_DEALLOC                0xB3
+#define UMAC_NOTIFY_OPCODE_RX_TICKET           0xB4
+#define UMAC_NOTIFY_OPCODE_MAX                 (UMAC_NOTIFY_OPCODE_RX_TICKET -\
+                                               UMAC_NOTIFY_OPCODE_ALIVE + 1)
+#define UMAC_NOTIFY_OPCODE_FIRST               (UMAC_NOTIFY_OPCODE_ALIVE)
+
+/* HDI OUT OP CODE */
+#define UMAC_HDI_OUT_OPCODE_PING               0x0
+#define UMAC_HDI_OUT_OPCODE_READ               0x1
+#define UMAC_HDI_OUT_OPCODE_WRITE              0x2
+#define UMAC_HDI_OUT_OPCODE_JUMP               0x3
+#define UMAC_HDI_OUT_OPCODE_REBOOT             0x4
+#define UMAC_HDI_OUT_OPCODE_WRITE_PERSISTENT   0x5
+#define UMAC_HDI_OUT_OPCODE_READ_PERSISTENT    0x6
+#define UMAC_HDI_OUT_OPCODE_READ_MODIFY_WRITE  0x7
+/* #define UMAC_HDI_OUT_OPCODE_RESERVED                0x8..0xA */
+#define UMAC_HDI_OUT_OPCODE_WRITE_AUX_REG      0xB
+#define UMAC_HDI_OUT_OPCODE_WIFI               0xF
+
+/* HDI IN OP CODE -- Non WiFi*/
+#define UMAC_HDI_IN_OPCODE_PING                        0x0
+#define UMAC_HDI_IN_OPCODE_READ                        0x1
+#define UMAC_HDI_IN_OPCODE_WRITE               0x2
+#define UMAC_HDI_IN_OPCODE_WRITE_PERSISTENT    0x5
+#define UMAC_HDI_IN_OPCODE_READ_PERSISTENT     0x6
+#define UMAC_HDI_IN_OPCODE_READ_MODIFY_WRITE   0x7
+#define UMAC_HDI_IN_OPCODE_EP_MGMT             0x8
+#define UMAC_HDI_IN_OPCODE_CREDIT_CHANGE       0x9
+#define UMAC_HDI_IN_OPCODE_CTRL_DATABASE       0xA
+#define UMAC_HDI_IN_OPCODE_WRITE_AUX_REG       0xB
+#define UMAC_HDI_IN_OPCODE_NONWIFI_MAX \
+               (UMAC_HDI_IN_OPCODE_WRITE_AUX_REG + 1)
+#define UMAC_HDI_IN_OPCODE_WIFI                        0xF
+
+/* HDI IN SOURCE */
+#define UMAC_HDI_IN_SOURCE_FHRX                        0x0
+#define UMAC_HDI_IN_SOURCE_UDMA                        0x1
+#define UMAC_HDI_IN_SOURCE_FW                  0x2
+#define UMAC_HDI_IN_SOURCE_RESERVED            0x3
+
+/* OUT CMD op-codes */
+#define UMAC_CMD_OPCODE_ECHO                    0x01
+#define UMAC_CMD_OPCODE_HALT                    0x02
+#define UMAC_CMD_OPCODE_RESET                   0x03
+#define UMAC_CMD_OPCODE_BULK_EP_INACT_TIMEOUT   0x09
+#define UMAC_CMD_OPCODE_URB_CANCEL_ACK          0x0A
+#define UMAC_CMD_OPCODE_DCACHE_FLUSH            0x0B
+#define UMAC_CMD_OPCODE_EEPROM_PROXY            0x0C
+#define UMAC_CMD_OPCODE_TX_ECHO                 0x0D
+#define UMAC_CMD_OPCODE_DBG_MON                 0x0E
+#define UMAC_CMD_OPCODE_INTERNAL_TX             0x0F
+#define UMAC_CMD_OPCODE_SET_PARAM_FIX           0x10
+#define UMAC_CMD_OPCODE_SET_PARAM_VAR           0x11
+#define UMAC_CMD_OPCODE_GET_PARAM               0x12
+#define UMAC_CMD_OPCODE_DBG_EVENT_WRAPPER       0x13
+#define UMAC_CMD_OPCODE_TARGET                  0x14
+#define UMAC_CMD_OPCODE_STATISTIC_REQUEST       0x15
+#define UMAC_CMD_OPCODE_GET_CHAN_INFO_LIST     0x16
+#define UMAC_CMD_OPCODE_SET_PARAM_LIST         0x17
+#define UMAC_CMD_OPCODE_GET_PARAM_LIST         0x18
+#define UMAC_CMD_OPCODE_BASE_WRAPPER            0xFA
+#define UMAC_CMD_OPCODE_LMAC_WRAPPER            0xFB
+#define UMAC_CMD_OPCODE_HW_TEST_WRAPPER         0xFC
+#define UMAC_CMD_OPCODE_WIFI_IF_WRAPPER         0xFD
+#define UMAC_CMD_OPCODE_WIFI_WRAPPER            0xFE
+#define UMAC_CMD_OPCODE_WIFI_PASS_THROUGH       0xFF
+
+/* UMAC WiFi interface op-codes */
+#define UMAC_WIFI_IF_CMD_SET_PROFILE                     0x11
+#define UMAC_WIFI_IF_CMD_INVALIDATE_PROFILE              0x12
+#define UMAC_WIFI_IF_CMD_SET_EXCLUDE_LIST                0x13
+#define UMAC_WIFI_IF_CMD_SCAN_REQUEST                    0x14
+#define UMAC_WIFI_IF_CMD_SCAN_CONFIG                     0x15
+#define UMAC_WIFI_IF_CMD_ADD_WEP40_KEY                   0x16
+#define UMAC_WIFI_IF_CMD_ADD_WEP104_KEY                  0x17
+#define UMAC_WIFI_IF_CMD_ADD_TKIP_KEY                    0x18
+#define UMAC_WIFI_IF_CMD_ADD_CCMP_KEY                    0x19
+#define UMAC_WIFI_IF_CMD_REMOVE_KEY                      0x1A
+#define UMAC_WIFI_IF_CMD_GLOBAL_TX_KEY_ID                0x1B
+#define UMAC_WIFI_IF_CMD_SET_HOST_EXTENDED_IE            0x1C
+#define UMAC_WIFI_IF_CMD_GET_SUPPORTED_CHANNELS          0x1E
+#define UMAC_WIFI_IF_CMD_TX_PWR_TRIGGER                  0x20
+
+/* UMAC WiFi interface ports */
+#define UMAC_WIFI_IF_FLG_PORT_DEF                        0x00
+#define UMAC_WIFI_IF_FLG_PORT_PAN                        0x01
+#define UMAC_WIFI_IF_FLG_PORT_PAN_INVALID                WIFI_IF_FLG_PORT_DEF
+
+/* UMAC WiFi interface actions */
+#define UMAC_WIFI_IF_FLG_ACT_GET                         0x10
+#define UMAC_WIFI_IF_FLG_ACT_SET                         0x20
+
+/* iwm_umac_fw_cmd_hdr.meta_data byte count -- bits [11:0] */
+#define UMAC_FW_CMD_BYTE_COUNT_POS            0
+#define UMAC_FW_CMD_BYTE_COUNT_SEED           0xFFF
+
+/* iwm_umac_fw_cmd_hdr.meta_data status -- bits [15:12] */
+#define UMAC_FW_CMD_STATUS_POS                12
+#define UMAC_FW_CMD_STATUS_SEED               0xF
+
+/* iwm_umac_fw_cmd_hdr.meta_data full TX command by Driver -- bits [16:16] */
+#define UMAC_FW_CMD_TX_DRV_FULL_CMD_POS       16
+#define UMAC_FW_CMD_TX_DRV_FULL_CMD_SEED      0x1
+
+/* iwm_umac_fw_cmd_hdr.meta_data TX command by FW -- bits [17:17] */
+#define UMAC_FW_CMD_TX_FW_CMD_POS             17
+#define UMAC_FW_CMD_TX_FW_CMD_SEED            0x1
+
+/* iwm_umac_fw_cmd_hdr.meta_data TX plaintext mode -- bits [18:18] */
+#define UMAC_FW_CMD_TX_PLAINTEXT_POS          18
+#define UMAC_FW_CMD_TX_PLAINTEXT_SEED         0x1
+
+/* iwm_umac_fw_cmd_hdr.meta_data STA color -- bits [22:20] */
+#define UMAC_FW_CMD_TX_STA_COLOR_POS          20
+#define UMAC_FW_CMD_TX_STA_COLOR_SEED         0x7
+
+/* iwm_umac_fw_cmd_hdr.meta_data TX life time (TU) -- bits [31:24] */
+#define UMAC_FW_CMD_TX_LIFETIME_TU_POS        24
+#define UMAC_FW_CMD_TX_LIFETIME_TU_SEED       0xFF
+
+/* iwm_dev_cmd_hdr.flags Response required -- bits [5:5] */
+#define UMAC_DEV_CMD_FLAGS_RESP_REQ_POS                5
+#define UMAC_DEV_CMD_FLAGS_RESP_REQ_SEED       0x1
+
+/* iwm_dev_cmd_hdr.flags Aborted command -- bits [6:6] */
+#define UMAC_DEV_CMD_FLAGS_ABORT_POS           6
+#define UMAC_DEV_CMD_FLAGS_ABORT_SEED          0x1
+
+/* iwm_dev_cmd_hdr.flags Internal command -- bits [7:7] */
+#define DEV_CMD_FLAGS_FLD_INTERNAL_POS         7
+#define DEV_CMD_FLAGS_FLD_INTERNAL_SEED                0x1
+
+/* Rx */
+/* Rx actions */
+#define IWM_RX_TICKET_DROP           0x0
+#define IWM_RX_TICKET_RELEASE        0x1
+#define IWM_RX_TICKET_SNIFFER        0x2
+#define IWM_RX_TICKET_ENQUEUE        0x3
+
+/* Rx flags */
+#define IWM_RX_TICKET_PAD_SIZE_MSK        0x2
+#define IWM_RX_TICKET_SPECIAL_SNAP_MSK    0x4
+#define IWM_RX_TICKET_AMSDU_MSK           0x8
+#define IWM_RX_TICKET_DROP_REASON_POS       4
+#define IWM_RX_TICKET_DROP_REASON_MSK (0x1F << RX_TICKET_FLAGS_DROP_REASON_POS)
+
+#define IWM_RX_DROP_NO_DROP                          0x0
+#define IWM_RX_DROP_BAD_CRC                          0x1
+/* L2P no address match */
+#define IWM_RX_DROP_LMAC_ADDR_FILTER                 0x2
+/* Multicast address not in list */
+#define IWM_RX_DROP_MCAST_ADDR_FILTER                0x3
+/* Control frames are not sent to the driver */
+#define IWM_RX_DROP_CTL_FRAME                        0x4
+/* Our frame is back */
+#define IWM_RX_DROP_OUR_TX                           0x5
+/* Association class filtering */
+#define IWM_RX_DROP_CLASS_FILTER                     0x6
+/* Duplicated frame */
+#define IWM_RX_DROP_DUPLICATE_FILTER                 0x7
+/* Decryption error */
+#define IWM_RX_DROP_SEC_ERR                          0x8
+/* Unencrypted frame while encryption is on */
+#define IWM_RX_DROP_SEC_NO_ENCRYPTION                0x9
+/* Replay check failure */
+#define IWM_RX_DROP_SEC_REPLAY_ERR                   0xa
+/* uCode and FW key color mismatch, check before replay */
+#define IWM_RX_DROP_SEC_KEY_COLOR_MISMATCH           0xb
+#define IWM_RX_DROP_SEC_TKIP_COUNTER_MEASURE         0xc
+/* No fragmentations Db is found */
+#define IWM_RX_DROP_FRAG_NO_RESOURCE                 0xd
+/* Fragmention Db has seqCtl mismatch Vs. non-1st frag */
+#define IWM_RX_DROP_FRAG_ERR                         0xe
+#define IWM_RX_DROP_FRAG_LOST                        0xf
+#define IWM_RX_DROP_FRAG_COMPLETE                    0x10
+/* Should be handled by UMAC */
+#define IWM_RX_DROP_MANAGEMENT                       0x11
+/* STA not found by UMAC */
+#define IWM_RX_DROP_NO_STATION                       0x12
+/* NULL or QoS NULL */
+#define IWM_RX_DROP_NULL_DATA                        0x13
+#define IWM_RX_DROP_BA_REORDER_OLD_SEQCTL            0x14
+#define IWM_RX_DROP_BA_REORDER_DUPLICATE             0x15
+
+struct iwm_rx_ticket {
+       __le16 action;
+       __le16 id;
+       __le16 flags;
+       u8 payload_offset; /* includes: MAC header, pad, IV */
+       u8 tail_len; /* includes: MIC, ICV, CRC (w/o STATUS) */
+} __attribute__ ((packed));
+
+struct iwm_rx_mpdu_hdr {
+       __le16 len;
+       __le16 reserved;
+} __attribute__ ((packed));
+
+/* UMAC SW WIFI API */
+
+struct iwm_dev_cmd_hdr {
+       u8 cmd;
+       u8 flags;
+       __le16 seq_num;
+} __attribute__ ((packed));
+
+struct iwm_umac_fw_cmd_hdr {
+       __le32 meta_data;
+       struct iwm_dev_cmd_hdr cmd;
+} __attribute__ ((packed));
+
+struct iwm_umac_wifi_out_hdr {
+       struct iwm_udma_out_wifi_hdr hw_hdr;
+       struct iwm_umac_fw_cmd_hdr sw_hdr;
+} __attribute__ ((packed));
+
+struct iwm_umac_nonwifi_out_hdr {
+       struct iwm_udma_out_nonwifi_hdr hw_hdr;
+} __attribute__ ((packed));
+
+struct iwm_umac_wifi_in_hdr {
+       struct iwm_udma_in_hdr hw_hdr;
+       struct iwm_umac_fw_cmd_hdr sw_hdr;
+} __attribute__ ((packed));
+
+struct iwm_umac_nonwifi_in_hdr {
+       struct iwm_udma_in_hdr hw_hdr;
+       __le32 time_stamp;
+} __attribute__ ((packed));
+
+#define IWM_UMAC_PAGE_SIZE     0x200
+
+/* Notify structures */
+struct iwm_fw_version {
+       u8 minor;
+       u8 major;
+       __le16 id;
+};
+
+struct iwm_fw_build {
+       u8 type;
+       u8 subtype;
+       u8 platform;
+       u8 opt;
+};
+
+struct iwm_fw_alive_hdr {
+       struct iwm_fw_version ver;
+       struct iwm_fw_build build;
+       __le32 os_build;
+       __le32 log_hdr_addr;
+       __le32 log_buf_addr;
+       __le32 sys_timer_addr;
+};
+
+#define WAIT_NOTIF_TIMEOUT     (2 * HZ)
+#define SCAN_COMPLETE_TIMEOUT  (3 * HZ)
+
+#define UMAC_NTFY_ALIVE_STATUS_ERR             0xDEAD
+#define UMAC_NTFY_ALIVE_STATUS_OK              0xCAFE
+
+#define UMAC_NTFY_INIT_COMPLETE_STATUS_ERR     0xDEAD
+#define UMAC_NTFY_INIT_COMPLETE_STATUS_OK      0xCAFE
+
+#define UMAC_NTFY_WIFI_CORE_STATUS_LINK_EN      0x40
+#define UMAC_NTFY_WIFI_CORE_STATUS_MLME_EN      0x80
+
+#define IWM_MACS_OUT_GROUPS    6
+#define IWM_MACS_OUT_SGROUPS   1
+
+
+#define WIFI_IF_NTFY_ASSOC_START                       0x80
+#define WIFI_IF_NTFY_ASSOC_COMPLETE                    0x81
+#define WIFI_IF_NTFY_PROFILE_INVALIDATE_COMPLETE       0x82
+#define WIFI_IF_NTFY_CONNECTION_TERMINATED             0x83
+#define WIFI_IF_NTFY_SCAN_COMPLETE                     0x84
+#define WIFI_IF_NTFY_STA_TABLE_CHANGE                  0x85
+#define WIFI_IF_NTFY_EXTENDED_IE_REQUIRED              0x86
+#define WIFI_IF_NTFY_RADIO_PREEMPTION                  0x87
+#define WIFI_IF_NTFY_BSS_TRK_TABLE_CHANGED             0x88
+#define WIFI_IF_NTFY_BSS_TRK_ENTRIES_REMOVED           0x89
+#define WIFI_IF_NTFY_LINK_QUALITY_STATISTICS           0x8A
+#define WIFI_IF_NTFY_MGMT_FRAME                                0x8B
+
+/* DEBUG INDICATIONS */
+#define WIFI_DBG_IF_NTFY_SCAN_SUPER_JOB_START          0xE0
+#define WIFI_DBG_IF_NTFY_SCAN_SUPER_JOB_COMPLETE       0xE1
+#define WIFI_DBG_IF_NTFY_SCAN_CHANNEL_START            0xE2
+#define WIFI_DBG_IF_NTFY_SCAN_CHANNEL_RESULT           0xE3
+#define WIFI_DBG_IF_NTFY_SCAN_MINI_JOB_START           0xE4
+#define WIFI_DBG_IF_NTFY_SCAN_MINI_JOB_COMPLETE                0xE5
+#define WIFI_DBG_IF_NTFY_CNCT_ATC_START                        0xE6
+#define WIFI_DBG_IF_NTFY_COEX_NOTIFICATION             0xE7
+#define WIFI_DBG_IF_NTFY_COEX_HANDLE_ENVELOP           0xE8
+#define WIFI_DBG_IF_NTFY_COEX_HANDLE_RELEASE_ENVELOP   0xE9
+
+/* Notification structures */
+struct iwm_umac_notif_wifi_if {
+       struct iwm_umac_wifi_in_hdr hdr;
+       u8 status;
+       u8 flags;
+       __le16 buf_size;
+} __attribute__ ((packed));
+
+#define UMAC_ROAM_REASON_FIRST_SELECTION       0x1
+#define UMAC_ROAM_REASON_AP_DEAUTH             0x2
+#define UMAC_ROAM_REASON_AP_CONNECT_LOST       0x3
+#define UMAC_ROAM_REASON_RSSI                  0x4
+#define UMAC_ROAM_REASON_AP_ASSISTED_ROAM      0x5
+#define UMAC_ROAM_REASON_IBSS_COALESCING       0x6
+
+struct iwm_umac_notif_assoc_start {
+       struct iwm_umac_notif_wifi_if mlme_hdr;
+       __le32 roam_reason;
+       u8 bssid[ETH_ALEN];
+       u8 reserved[2];
+} __attribute__ ((packed));
+
+#define UMAC_ASSOC_COMPLETE_SUCCESS            0x0
+#define UMAC_ASSOC_COMPLETE_FAILURE            0x1
+
+struct iwm_umac_notif_assoc_complete {
+       struct iwm_umac_notif_wifi_if mlme_hdr;
+       __le32 status;
+       u8 bssid[ETH_ALEN];
+       u8 band;
+       u8 channel;
+} __attribute__ ((packed));
+
+#define UMAC_PROFILE_INVALID_ASSOC_TIMEOUT     0x0
+#define UMAC_PROFILE_INVALID_ROAM_TIMEOUT      0x1
+#define UMAC_PROFILE_INVALID_REQUEST           0x2
+#define UMAC_PROFILE_INVALID_RF_PREEMPTED      0x3
+
+struct iwm_umac_notif_profile_invalidate {
+       struct iwm_umac_notif_wifi_if mlme_hdr;
+       __le32 reason;
+} __attribute__ ((packed));
+
+#define UMAC_SCAN_RESULT_SUCCESS  0x0
+#define UMAC_SCAN_RESULT_ABORTED  0x1
+#define UMAC_SCAN_RESULT_REJECTED 0x2
+#define UMAC_SCAN_RESULT_FAILED   0x3
+
+struct iwm_umac_notif_scan_complete {
+       struct iwm_umac_notif_wifi_if mlme_hdr;
+       __le32 type;
+       __le32 result;
+       u8 seq_num;
+} __attribute__ ((packed));
+
+#define UMAC_OPCODE_ADD_MODIFY 0x0
+#define UMAC_OPCODE_REMOVE     0x1
+#define UMAC_OPCODE_CLEAR_ALL  0x2
+
+#define UMAC_STA_FLAG_QOS      0x1
+
+struct iwm_umac_notif_sta_info {
+       struct iwm_umac_notif_wifi_if mlme_hdr;
+       __le32 opcode;
+       u8 mac_addr[ETH_ALEN];
+       u8 sta_id; /* bits 0-3: station ID, bits 4-7: station color */
+       u8 flags;
+} __attribute__ ((packed));
+
+#define UMAC_BAND_2GHZ 0
+#define UMAC_BAND_5GHZ 1
+
+#define UMAC_CHANNEL_WIDTH_20MHZ 0
+#define UMAC_CHANNEL_WIDTH_40MHZ 1
+
+struct iwm_umac_notif_bss_info {
+       struct iwm_umac_notif_wifi_if mlme_hdr;
+       __le32 type;
+       __le32 timestamp;
+       __le16 table_idx;
+       __le16 frame_len;
+       u8 band;
+       u8 channel;
+       s8 rssi;
+       u8 reserved;
+       u8 frame_buf[1];
+} __attribute__ ((packed));
+
+#define IWM_BSS_REMOVE_INDEX_MSK           0x0fff
+#define IWM_BSS_REMOVE_FLAGS_MSK           0xfc00
+
+#define IWM_BSS_REMOVE_FLG_AGE             0x1000
+#define IWM_BSS_REMOVE_FLG_TIMEOUT         0x2000
+#define IWM_BSS_REMOVE_FLG_TABLE_FULL      0x4000
+
+struct iwm_umac_notif_bss_removed {
+       struct iwm_umac_notif_wifi_if mlme_hdr;
+       __le32 count;
+       __le16 entries[0];
+} __attribute__ ((packed));
+
+struct iwm_umac_notif_mgt_frame {
+       struct iwm_umac_notif_wifi_if mlme_hdr;
+       __le16 len;
+       u8 frame[1];
+} __attribute__ ((packed));
+
+struct iwm_umac_notif_alive {
+       struct iwm_umac_wifi_in_hdr hdr;
+       __le16 status;
+       __le16 reserved1;
+       struct iwm_fw_alive_hdr alive_data;
+       __le16 reserved2;
+       __le16 page_grp_count;
+       __le32 page_grp_state[IWM_MACS_OUT_GROUPS];
+} __attribute__ ((packed));
+
+struct iwm_umac_notif_init_complete {
+       __le16 status;
+       __le16 reserved;
+} __attribute__ ((packed));
+
+/* error categories */
+enum {
+       UMAC_SYS_ERR_CAT_NONE = 0,
+       UMAC_SYS_ERR_CAT_BOOT,
+       UMAC_SYS_ERR_CAT_UMAC,
+       UMAC_SYS_ERR_CAT_UAXM,
+       UMAC_SYS_ERR_CAT_LMAC,
+       UMAC_SYS_ERR_CAT_MAX
+};
+
+struct iwm_fw_error_hdr {
+       __le32 category;
+       __le32 status;
+       __le32 pc;
+       __le32 blink1;
+       __le32 blink2;
+       __le32 ilink1;
+       __le32 ilink2;
+       __le32 data1;
+       __le32 data2;
+       __le32 line_num;
+       __le32 umac_status;
+       __le32 lmac_status;
+       __le32 sdio_status;
+} __attribute__ ((packed));
+
+struct iwm_umac_notif_error {
+       struct iwm_umac_wifi_in_hdr hdr;
+       struct iwm_fw_error_hdr err;
+} __attribute__ ((packed));
+
+#define UMAC_DEALLOC_NTFY_CHANGES_CNT_POS      0
+#define UMAC_DEALLOC_NTFY_CHANGES_CNT_SEED     0xff
+#define UMAC_DEALLOC_NTFY_CHANGES_MSK_POS      8
+#define UMAC_DEALLOC_NTFY_CHANGES_MSK_SEED     0xffffff
+#define UMAC_DEALLOC_NTFY_PAGE_CNT_POS         0
+#define UMAC_DEALLOC_NTFY_PAGE_CNT_SEED                0xffffff
+#define UMAC_DEALLOC_NTFY_GROUP_NUM_POS                24
+#define UMAC_DEALLOC_NTFY_GROUP_NUM_SEED       0xf
+
+struct iwm_umac_notif_page_dealloc {
+       struct iwm_umac_wifi_in_hdr hdr;
+       __le32 changes;
+       __le32 grp_info[IWM_MACS_OUT_GROUPS];
+} __attribute__ ((packed));
+
+struct iwm_umac_notif_wifi_status {
+       struct iwm_umac_wifi_in_hdr hdr;
+       __le16 status;
+       __le16 reserved;
+} __attribute__ ((packed));
+
+struct iwm_umac_notif_rx_ticket {
+       struct iwm_umac_wifi_in_hdr hdr;
+       u8 num_tickets;
+       u8 reserved[3];
+       struct iwm_rx_ticket tickets[1];
+} __attribute__ ((packed));
+
+/* Tx/Rx rates window (number of max of last update window per second) */
+#define UMAC_NTF_RATE_SAMPLE_NR        4
+
+#define IWM_UMAC_MGMT_TID      8
+#define IWM_UMAC_TID_NR                8
+
+struct iwm_umac_notif_stats {
+       struct iwm_umac_wifi_in_hdr hdr;
+       __le32 flags;
+       __le32 timestamp;
+       __le16 tid_load[IWM_UMAC_TID_NR + 2]; /* 1 non-QoS + 1 dword align */
+       __le16 tx_rate[UMAC_NTF_RATE_SAMPLE_NR];
+       __le16 rx_rate[UMAC_NTF_RATE_SAMPLE_NR];
+       s32 rssi_dbm;
+       s32 noise_dbm;
+       __le32 supp_rates;
+       __le32 missed_beacons;
+       __le32 rx_beacons;
+       __le32 rx_dir_pkts;
+       __le32 rx_nondir_pkts;
+       __le32 rx_multicast;
+       __le32 rx_errors;
+       __le32 rx_drop_other_bssid;
+       __le32 rx_drop_decode;
+       __le32 rx_drop_reassembly;
+       __le32 rx_drop_bad_len;
+       __le32 rx_drop_overflow;
+       __le32 rx_drop_crc;
+       __le32 rx_drop_missed;
+       __le32 tx_dir_pkts;
+       __le32 tx_nondir_pkts;
+       __le32 tx_failure;
+       __le32 tx_errors;
+       __le32 tx_drop_max_retry;
+       __le32 tx_err_abort;
+       __le32 tx_err_carrier;
+       __le32 rx_bytes;
+       __le32 tx_bytes;
+       __le32 tx_power;
+       __le32 tx_max_power;
+       __le32 roam_threshold;
+       __le32 ap_assoc_nr;
+       __le32 scan_full;
+       __le32 scan_abort;
+       __le32 ap_nr;
+       __le32 roam_nr;
+       __le32 roam_missed_beacons;
+       __le32 roam_rssi;
+       __le32 roam_unassoc;
+       __le32 roam_deauth;
+       __le32 roam_ap_loadblance;
+} __attribute__ ((packed));
+
+/* WiFi interface wrapper header */
+struct iwm_umac_wifi_if {
+       u8 oid;
+       u8 flags;
+       __le16 buf_size;
+} __attribute__ ((packed));
+
+#define IWM_SEQ_NUM_HOST_MSK   0x0000
+#define IWM_SEQ_NUM_UMAC_MSK   0x4000
+#define IWM_SEQ_NUM_LMAC_MSK   0x8000
+#define IWM_SEQ_NUM_MSK                0xC000
+
+#endif
diff --git a/drivers/net/wireless/iwmc3200wifi/wext.c b/drivers/net/wireless/iwmc3200wifi/wext.c
new file mode 100644 (file)
index 0000000..584c94d
--- /dev/null
@@ -0,0 +1,723 @@
+/*
+ * Intel Wireless Multicomm 3200 WiFi driver
+ *
+ * Copyright (C) 2009 Intel Corporation <ilw@linux.intel.com>
+ * Samuel Ortiz <samuel.ortiz@intel.com>
+ * Zhu Yi <yi.zhu@intel.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., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <linux/wireless.h>
+#include <linux/if_arp.h>
+#include <linux/etherdevice.h>
+#include <net/cfg80211.h>
+#include <net/iw_handler.h>
+
+#include "iwm.h"
+#include "umac.h"
+#include "commands.h"
+#include "debug.h"
+
+static struct iw_statistics *iwm_get_wireless_stats(struct net_device *dev)
+{
+       struct iwm_priv *iwm = ndev_to_iwm(dev);
+       struct iw_statistics *wstats = &iwm->wstats;
+
+       if (!test_bit(IWM_STATUS_ASSOCIATED, &iwm->status)) {
+               memset(wstats, 0, sizeof(struct iw_statistics));
+               wstats->qual.updated = IW_QUAL_ALL_INVALID;
+       }
+
+       return wstats;
+}
+
+static int iwm_wext_siwfreq(struct net_device *dev,
+                           struct iw_request_info *info,
+                           struct iw_freq *freq, char *extra)
+{
+       struct iwm_priv *iwm = ndev_to_iwm(dev);
+
+       if (freq->flags == IW_FREQ_AUTO)
+               return 0;
+
+       /* frequency/channel can only be set in IBSS mode */
+       if (iwm->conf.mode != UMAC_MODE_IBSS)
+               return -EOPNOTSUPP;
+
+       return cfg80211_ibss_wext_siwfreq(dev, info, freq, extra);
+}
+
+static int iwm_wext_giwfreq(struct net_device *dev,
+                           struct iw_request_info *info,
+                           struct iw_freq *freq, char *extra)
+{
+       struct iwm_priv *iwm = ndev_to_iwm(dev);
+
+       if (iwm->conf.mode == UMAC_MODE_IBSS)
+               return cfg80211_ibss_wext_giwfreq(dev, info, freq, extra);
+
+       freq->e = 0;
+       freq->m = iwm->channel;
+
+       return 0;
+}
+
+static int iwm_wext_siwap(struct net_device *dev, struct iw_request_info *info,
+                         struct sockaddr *ap_addr, char *extra)
+{
+       struct iwm_priv *iwm = ndev_to_iwm(dev);
+
+       if (iwm->conf.mode == UMAC_MODE_IBSS)
+               return cfg80211_ibss_wext_siwap(dev, info, ap_addr, extra);
+
+       if (!test_bit(IWM_STATUS_READY, &iwm->status))
+               return -EIO;
+
+       if (is_zero_ether_addr(ap_addr->sa_data) ||
+           is_broadcast_ether_addr(ap_addr->sa_data)) {
+               IWM_DBG_WEXT(iwm, DBG, "clear mandatory bssid %pM\n",
+                            iwm->umac_profile->bssid[0]);
+               memset(&iwm->umac_profile->bssid[0], 0, ETH_ALEN);
+               iwm->umac_profile->bss_num = 0;
+       } else {
+               IWM_DBG_WEXT(iwm, DBG, "add mandatory bssid %pM\n",
+                            ap_addr->sa_data);
+               memcpy(&iwm->umac_profile->bssid[0], ap_addr->sa_data,
+                      ETH_ALEN);
+               iwm->umac_profile->bss_num = 1;
+       }
+
+       if (iwm->umac_profile_active) {
+               if (!memcmp(&iwm->umac_profile->bssid[0], iwm->bssid, ETH_ALEN))
+                       return 0;
+
+               iwm_invalidate_mlme_profile(iwm);
+       }
+
+       if (iwm->umac_profile->ssid.ssid_len)
+               return iwm_send_mlme_profile(iwm);
+
+       return 0;
+}
+
+static int iwm_wext_giwap(struct net_device *dev, struct iw_request_info *info,
+                         struct sockaddr *ap_addr, char *extra)
+{
+       struct iwm_priv *iwm = ndev_to_iwm(dev);
+
+       switch (iwm->conf.mode) {
+       case UMAC_MODE_IBSS:
+               return cfg80211_ibss_wext_giwap(dev, info, ap_addr, extra);
+       case UMAC_MODE_BSS:
+               if (test_bit(IWM_STATUS_ASSOCIATED, &iwm->status)) {
+                       ap_addr->sa_family = ARPHRD_ETHER;
+                       memcpy(&ap_addr->sa_data, iwm->bssid, ETH_ALEN);
+               } else
+                       memset(&ap_addr->sa_data, 0, ETH_ALEN);
+               break;
+       default:
+               return -EOPNOTSUPP;
+       }
+
+       return 0;
+}
+
+static int iwm_wext_siwessid(struct net_device *dev,
+                            struct iw_request_info *info,
+                            struct iw_point *data, char *ssid)
+{
+       struct iwm_priv *iwm = ndev_to_iwm(dev);
+       size_t len = data->length;
+       int ret;
+
+       if (iwm->conf.mode == UMAC_MODE_IBSS)
+               return cfg80211_ibss_wext_siwessid(dev, info, data, ssid);
+
+       if (!test_bit(IWM_STATUS_READY, &iwm->status))
+               return -EIO;
+
+       if (len > 0 && ssid[len - 1] == '\0')
+               len--;
+
+       if (iwm->umac_profile_active) {
+               if (iwm->umac_profile->ssid.ssid_len == len &&
+                   !memcmp(iwm->umac_profile->ssid.ssid, ssid, len))
+                       return 0;
+
+               ret = iwm_invalidate_mlme_profile(iwm);
+               if (ret < 0) {
+                       IWM_ERR(iwm, "Couldn't invalidate profile\n");
+                       return ret;
+               }
+       }
+
+       iwm->umac_profile->ssid.ssid_len = len;
+       memcpy(iwm->umac_profile->ssid.ssid, ssid, len);
+
+       return iwm_send_mlme_profile(iwm);
+}
+
+static int iwm_wext_giwessid(struct net_device *dev,
+                            struct iw_request_info *info,
+                            struct iw_point *data, char *ssid)
+{
+       struct iwm_priv *iwm = ndev_to_iwm(dev);
+
+       if (iwm->conf.mode == UMAC_MODE_IBSS)
+               return cfg80211_ibss_wext_giwessid(dev, info, data, ssid);
+
+       if (!test_bit(IWM_STATUS_READY, &iwm->status))
+               return -EIO;
+
+       data->length = iwm->umac_profile->ssid.ssid_len;
+       if (data->length) {
+               memcpy(ssid, iwm->umac_profile->ssid.ssid, data->length);
+               data->flags = 1;
+       } else
+               data->flags = 0;
+
+       return 0;
+}
+
+static struct iwm_key *
+iwm_key_init(struct iwm_priv *iwm, u8 key_idx, bool in_use,
+            struct iw_encode_ext *ext, u8 alg)
+{
+       struct iwm_key *key = &iwm->keys[key_idx];
+
+       memset(key, 0, sizeof(struct iwm_key));
+       memcpy(key->hdr.mac, ext->addr.sa_data, ETH_ALEN);
+       key->hdr.key_idx = key_idx;
+       if (is_broadcast_ether_addr(ext->addr.sa_data))
+               key->hdr.multicast = 1;
+
+       key->in_use = in_use;
+       key->flags = ext->ext_flags;
+       key->alg = alg;
+       key->key_len = ext->key_len;
+       memcpy(key->key, ext->key, ext->key_len);
+
+       return key;
+}
+
+static int iwm_wext_giwrate(struct net_device *dev,
+                           struct iw_request_info *info,
+                           struct iw_param *rate, char *extra)
+{
+       struct iwm_priv *iwm = ndev_to_iwm(dev);
+
+       rate->value = iwm->rate * 1000000;
+
+       return 0;
+}
+
+static int iwm_wext_siwencode(struct net_device *dev,
+                             struct iw_request_info *info,
+                             struct iw_point *erq, char *key_buf)
+{
+       struct iwm_priv *iwm = ndev_to_iwm(dev);
+       struct iwm_key *uninitialized_var(key);
+       int idx, i, uninitialized_var(alg), remove = 0, ret;
+
+       IWM_DBG_WEXT(iwm, DBG, "key len: %d\n", erq->length);
+       IWM_DBG_WEXT(iwm, DBG, "flags: 0x%x\n", erq->flags);
+
+       if (!iwm->umac_profile) {
+               IWM_ERR(iwm, "UMAC profile not allocated yet\n");
+               return -ENODEV;
+       }
+
+       if (erq->length == WLAN_KEY_LEN_WEP40) {
+               alg = UMAC_CIPHER_TYPE_WEP_40;
+               iwm->umac_profile->sec.ucast_cipher = UMAC_CIPHER_TYPE_WEP_40;
+               iwm->umac_profile->sec.mcast_cipher = UMAC_CIPHER_TYPE_WEP_40;
+       } else if (erq->length == WLAN_KEY_LEN_WEP104) {
+               alg = UMAC_CIPHER_TYPE_WEP_104;
+               iwm->umac_profile->sec.ucast_cipher = UMAC_CIPHER_TYPE_WEP_104;
+               iwm->umac_profile->sec.mcast_cipher = UMAC_CIPHER_TYPE_WEP_104;
+       }
+
+       if (erq->flags & IW_ENCODE_RESTRICTED)
+               iwm->umac_profile->sec.auth_type = UMAC_AUTH_TYPE_LEGACY_PSK;
+       else
+               iwm->umac_profile->sec.auth_type = UMAC_AUTH_TYPE_OPEN;
+
+       idx = erq->flags & IW_ENCODE_INDEX;
+       if (idx == 0) {
+               if (iwm->default_key)
+                       for (i = 0; i < IWM_NUM_KEYS; i++) {
+                               if (iwm->default_key == &iwm->keys[i]) {
+                                       idx = i;
+                                       break;
+                               }
+                       }
+               else
+                       iwm->default_key = &iwm->keys[idx];
+       } else if (idx < 1 || idx > 4) {
+               return -EINVAL;
+       } else
+               idx--;
+
+       if (erq->flags & IW_ENCODE_DISABLED)
+               remove = 1;
+       else if (erq->length == 0) {
+               if (!iwm->keys[idx].in_use)
+                       return -EINVAL;
+               iwm->default_key = &iwm->keys[idx];
+       }
+
+       if (erq->length) {
+               key = &iwm->keys[idx];
+               memset(key, 0, sizeof(struct iwm_key));
+               memset(key->hdr.mac, 0xff, ETH_ALEN);
+               key->hdr.key_idx = idx;
+               key->hdr.multicast = 1;
+               key->in_use = !remove;
+               key->alg = alg;
+               key->key_len = erq->length;
+               memcpy(key->key, key_buf, erq->length);
+
+               IWM_DBG_WEXT(iwm, DBG, "Setting key %d, default: %d\n",
+                            idx, !!iwm->default_key);
+       }
+
+       if (remove) {
+               if ((erq->flags & IW_ENCODE_NOKEY) || (erq->length == 0)) {
+                       int j;
+                       for (j = 0; j < IWM_NUM_KEYS; j++)
+                               if (iwm->keys[j].in_use) {
+                                       struct iwm_key *k = &iwm->keys[j];
+
+                                       k->in_use = 0;
+                                       ret = iwm_set_key(iwm, remove, 0, k);
+                                       if (ret < 0)
+                                               return ret;
+                               }
+
+                       iwm->umac_profile->sec.ucast_cipher =
+                                                       UMAC_CIPHER_TYPE_NONE;
+                       iwm->umac_profile->sec.mcast_cipher =
+                                                       UMAC_CIPHER_TYPE_NONE;
+                       iwm->umac_profile->sec.auth_type =
+                                                       UMAC_AUTH_TYPE_OPEN;
+
+                       return 0;
+               } else {
+                       key->in_use = 0;
+                       return iwm_set_key(iwm, remove, 0, key);
+               }
+       }
+
+       /*
+        * If we havent set a profile yet, we cant set keys.
+        * Keys will be pushed after we're associated.
+        */
+       if (!iwm->umac_profile_active)
+               return 0;
+
+       /*
+        * If there is a current active profile, but no
+        * default key, it's not worth trying to associate again.
+        */
+       if (!iwm->default_key)
+               return 0;
+
+       /*
+        * Here we have an active profile, but a key setting changed.
+        * We thus have to invalidate the current profile, and push the
+        * new one. Keys will be pushed when association takes place.
+        */
+       ret = iwm_invalidate_mlme_profile(iwm);
+       if (ret < 0) {
+               IWM_ERR(iwm, "Couldn't invalidate profile\n");
+               return ret;
+       }
+
+       return iwm_send_mlme_profile(iwm);
+}
+
+static int iwm_wext_giwencode(struct net_device *dev,
+                             struct iw_request_info *info,
+                             struct iw_point *erq, char *key)
+{
+       struct iwm_priv *iwm = ndev_to_iwm(dev);
+       int idx, i;
+
+       idx = erq->flags & IW_ENCODE_INDEX;
+       if (idx < 1 || idx > 4) {
+               idx = -1;
+               if (!iwm->default_key) {
+                       erq->length = 0;
+                       erq->flags |= IW_ENCODE_NOKEY;
+                       return 0;
+               } else
+                       for (i = 0; i < IWM_NUM_KEYS; i++) {
+                               if (iwm->default_key == &iwm->keys[i]) {
+                                       idx = i;
+                                       break;
+                               }
+                       }
+               if (idx < 0)
+                       return -EINVAL;
+       } else
+               idx--;
+
+       erq->flags = idx + 1;
+
+       if (!iwm->keys[idx].in_use) {
+               erq->length = 0;
+               erq->flags |= IW_ENCODE_DISABLED;
+               return 0;
+       }
+
+       memcpy(key, iwm->keys[idx].key,
+              min_t(int, erq->length, iwm->keys[idx].key_len));
+       erq->length = iwm->keys[idx].key_len;
+       erq->flags |= IW_ENCODE_ENABLED;
+
+       if (iwm->umac_profile->mode == UMAC_MODE_BSS) {
+               switch (iwm->umac_profile->sec.auth_type) {
+               case UMAC_AUTH_TYPE_OPEN:
+                       erq->flags |= IW_ENCODE_OPEN;
+                       break;
+               default:
+                       erq->flags |= IW_ENCODE_RESTRICTED;
+                       break;
+               }
+       }
+
+       return 0;
+}
+
+static int iwm_set_wpa_version(struct iwm_priv *iwm, u8 wpa_version)
+{
+       if (wpa_version & IW_AUTH_WPA_VERSION_WPA2)
+               iwm->umac_profile->sec.flags = UMAC_SEC_FLG_RSNA_ON_MSK;
+       else if (wpa_version & IW_AUTH_WPA_VERSION_WPA)
+               iwm->umac_profile->sec.flags = UMAC_SEC_FLG_WPA_ON_MSK;
+       else
+               iwm->umac_profile->sec.flags = UMAC_SEC_FLG_LEGACY_PROFILE;
+
+       return 0;
+}
+
+static int iwm_wext_siwpower(struct net_device *dev,
+                            struct iw_request_info *info,
+                            struct iw_param *wrq, char *extra)
+{
+       struct iwm_priv *iwm = ndev_to_iwm(dev);
+       u32 power_index;
+
+       if (wrq->disabled) {
+               power_index = IWM_POWER_INDEX_MIN;
+               goto set;
+       } else
+               power_index = IWM_POWER_INDEX_DEFAULT;
+
+       switch (wrq->flags & IW_POWER_MODE) {
+       case IW_POWER_ON:
+       case IW_POWER_MODE:
+       case IW_POWER_ALL_R:
+               break;
+       default:
+               return -EINVAL;
+       }
+
+ set:
+       if (power_index == iwm->conf.power_index)
+               return 0;
+
+       iwm->conf.power_index = power_index;
+
+       return iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
+                                      CFG_POWER_INDEX, iwm->conf.power_index);
+}
+
+static int iwm_wext_giwpower(struct net_device *dev,
+                            struct iw_request_info *info,
+                            union iwreq_data *wrqu, char *extra)
+{
+       struct iwm_priv *iwm = ndev_to_iwm(dev);
+
+       wrqu->power.disabled = (iwm->conf.power_index == IWM_POWER_INDEX_MIN);
+
+       return 0;
+}
+
+static int iwm_set_key_mgt(struct iwm_priv *iwm, u8 key_mgt)
+{
+       u8 *auth_type = &iwm->umac_profile->sec.auth_type;
+
+       if (key_mgt == IW_AUTH_KEY_MGMT_802_1X)
+               *auth_type = UMAC_AUTH_TYPE_8021X;
+       else if (key_mgt == IW_AUTH_KEY_MGMT_PSK) {
+               if (iwm->umac_profile->sec.flags &
+                   (UMAC_SEC_FLG_WPA_ON_MSK | UMAC_SEC_FLG_RSNA_ON_MSK))
+                       *auth_type = UMAC_AUTH_TYPE_RSNA_PSK;
+               else
+                       *auth_type = UMAC_AUTH_TYPE_LEGACY_PSK;
+       } else {
+               IWM_ERR(iwm, "Invalid key mgt: 0x%x\n", key_mgt);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int iwm_set_cipher(struct iwm_priv *iwm, u8 cipher, u8 ucast)
+{
+       u8 *profile_cipher = ucast ? &iwm->umac_profile->sec.ucast_cipher :
+               &iwm->umac_profile->sec.mcast_cipher;
+
+       switch (cipher) {
+       case IW_AUTH_CIPHER_NONE:
+               *profile_cipher = UMAC_CIPHER_TYPE_NONE;
+               break;
+       case IW_AUTH_CIPHER_WEP40:
+               *profile_cipher = UMAC_CIPHER_TYPE_WEP_40;
+               break;
+       case IW_AUTH_CIPHER_TKIP:
+               *profile_cipher = UMAC_CIPHER_TYPE_TKIP;
+               break;
+       case IW_AUTH_CIPHER_CCMP:
+               *profile_cipher = UMAC_CIPHER_TYPE_CCMP;
+               break;
+       case IW_AUTH_CIPHER_WEP104:
+               *profile_cipher = UMAC_CIPHER_TYPE_WEP_104;
+               break;
+       default:
+               IWM_ERR(iwm, "Unsupported cipher: 0x%x\n", cipher);
+               return -ENOTSUPP;
+       }
+
+       return 0;
+}
+
+static int iwm_set_auth_alg(struct iwm_priv *iwm, u8 auth_alg)
+{
+       u8 *auth_type = &iwm->umac_profile->sec.auth_type;
+
+       switch (auth_alg) {
+       case IW_AUTH_ALG_OPEN_SYSTEM:
+               *auth_type = UMAC_AUTH_TYPE_OPEN;
+               break;
+       case IW_AUTH_ALG_SHARED_KEY:
+               if (iwm->umac_profile->sec.flags &
+                   (UMAC_SEC_FLG_WPA_ON_MSK | UMAC_SEC_FLG_RSNA_ON_MSK)) {
+                       if (*auth_type == UMAC_AUTH_TYPE_8021X)
+                               return -EINVAL;
+                       *auth_type = UMAC_AUTH_TYPE_RSNA_PSK;
+               } else {
+                       *auth_type = UMAC_AUTH_TYPE_LEGACY_PSK;
+               }
+               break;
+       case IW_AUTH_ALG_LEAP:
+       default:
+               IWM_ERR(iwm, "Unsupported auth alg: 0x%x\n", auth_alg);
+               return -ENOTSUPP;
+       }
+
+       return 0;
+}
+
+static int iwm_wext_siwauth(struct net_device *dev,
+                           struct iw_request_info *info,
+                           struct iw_param *data, char *extra)
+{
+       struct iwm_priv *iwm = ndev_to_iwm(dev);
+       int ret;
+
+       if ((data->flags) &
+           (IW_AUTH_WPA_VERSION | IW_AUTH_KEY_MGMT |
+            IW_AUTH_WPA_ENABLED | IW_AUTH_80211_AUTH_ALG)) {
+               /* We need to invalidate the current profile */
+               if (iwm->umac_profile_active) {
+                       ret = iwm_invalidate_mlme_profile(iwm);
+                       if (ret < 0) {
+                               IWM_ERR(iwm, "Couldn't invalidate profile\n");
+                               return ret;
+                       }
+               }
+       }
+
+       switch (data->flags & IW_AUTH_INDEX) {
+       case IW_AUTH_WPA_VERSION:
+               return iwm_set_wpa_version(iwm, data->value);
+               break;
+       case IW_AUTH_CIPHER_PAIRWISE:
+               return iwm_set_cipher(iwm, data->value, 1);
+               break;
+       case IW_AUTH_CIPHER_GROUP:
+               return iwm_set_cipher(iwm, data->value, 0);
+               break;
+       case IW_AUTH_KEY_MGMT:
+               return iwm_set_key_mgt(iwm, data->value);
+               break;
+       case IW_AUTH_80211_AUTH_ALG:
+               return iwm_set_auth_alg(iwm, data->value);
+               break;
+       default:
+               return -ENOTSUPP;
+       }
+
+       return 0;
+}
+
+static int iwm_wext_giwauth(struct net_device *dev,
+                           struct iw_request_info *info,
+                           struct iw_param *data, char *extra)
+{
+       return 0;
+}
+
+static int iwm_wext_siwencodeext(struct net_device *dev,
+                                struct iw_request_info *info,
+                                struct iw_point *erq, char *extra)
+{
+       struct iwm_priv *iwm = ndev_to_iwm(dev);
+       struct iwm_key *key;
+       struct iw_encode_ext *ext = (struct iw_encode_ext *) extra;
+       int uninitialized_var(alg), idx, i, remove = 0;
+
+       IWM_DBG_WEXT(iwm, DBG, "alg: 0x%x\n", ext->alg);
+       IWM_DBG_WEXT(iwm, DBG, "key len: %d\n", ext->key_len);
+       IWM_DBG_WEXT(iwm, DBG, "ext_flags: 0x%x\n", ext->ext_flags);
+       IWM_DBG_WEXT(iwm, DBG, "flags: 0x%x\n", erq->flags);
+       IWM_DBG_WEXT(iwm, DBG, "length: 0x%x\n", erq->length);
+
+       switch (ext->alg) {
+       case IW_ENCODE_ALG_NONE:
+               remove = 1;
+               break;
+       case IW_ENCODE_ALG_WEP:
+               if (ext->key_len == WLAN_KEY_LEN_WEP40)
+                       alg = UMAC_CIPHER_TYPE_WEP_40;
+               else if (ext->key_len == WLAN_KEY_LEN_WEP104)
+                       alg = UMAC_CIPHER_TYPE_WEP_104;
+               else {
+                       IWM_ERR(iwm, "Invalid key length: %d\n", ext->key_len);
+                       return -EINVAL;
+               }
+
+               break;
+       case IW_ENCODE_ALG_TKIP:
+               alg = UMAC_CIPHER_TYPE_TKIP;
+               break;
+       case IW_ENCODE_ALG_CCMP:
+               alg = UMAC_CIPHER_TYPE_CCMP;
+               break;
+       default:
+               return -EOPNOTSUPP;
+       }
+
+       idx = erq->flags & IW_ENCODE_INDEX;
+
+       if (idx == 0) {
+               if (iwm->default_key)
+                       for (i = 0; i < IWM_NUM_KEYS; i++) {
+                               if (iwm->default_key == &iwm->keys[i]) {
+                                       idx = i;
+                                       break;
+                               }
+                       }
+       } else if (idx < 1 || idx > 4) {
+               return -EINVAL;
+       } else
+               idx--;
+
+       if (erq->flags & IW_ENCODE_DISABLED)
+               remove = 1;
+       else if ((erq->length == 0) ||
+                (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)) {
+               iwm->default_key = &iwm->keys[idx];
+               if (iwm->umac_profile_active && ext->alg == IW_ENCODE_ALG_WEP)
+                       return iwm_set_tx_key(iwm, idx);
+       }
+
+       key = iwm_key_init(iwm, idx, !remove, ext, alg);
+
+       return iwm_set_key(iwm, remove, !iwm->default_key, key);
+}
+
+static const iw_handler iwm_handlers[] =
+{
+       (iw_handler) NULL,                              /* SIOCSIWCOMMIT */
+       (iw_handler) cfg80211_wext_giwname,             /* SIOCGIWNAME */
+       (iw_handler) NULL,                              /* SIOCSIWNWID */
+       (iw_handler) NULL,                              /* SIOCGIWNWID */
+       (iw_handler) iwm_wext_siwfreq,                  /* SIOCSIWFREQ */
+       (iw_handler) iwm_wext_giwfreq,                  /* SIOCGIWFREQ */
+       (iw_handler) cfg80211_wext_siwmode,             /* SIOCSIWMODE */
+       (iw_handler) cfg80211_wext_giwmode,             /* SIOCGIWMODE */
+       (iw_handler) NULL,                              /* SIOCSIWSENS */
+       (iw_handler) NULL,                              /* SIOCGIWSENS */
+       (iw_handler) NULL /* not used */,               /* SIOCSIWRANGE */
+       (iw_handler) cfg80211_wext_giwrange,            /* SIOCGIWRANGE */
+       (iw_handler) NULL /* not used */,               /* SIOCSIWPRIV */
+       (iw_handler) NULL /* kernel code */,            /* SIOCGIWPRIV */
+       (iw_handler) NULL /* not used */,               /* SIOCSIWSTATS */
+       (iw_handler) NULL /* kernel code */,            /* SIOCGIWSTATS */
+       (iw_handler) NULL,                              /* SIOCSIWSPY */
+       (iw_handler) NULL,                              /* SIOCGIWSPY */
+       (iw_handler) NULL,                              /* SIOCSIWTHRSPY */
+       (iw_handler) NULL,                              /* SIOCGIWTHRSPY */
+       (iw_handler) iwm_wext_siwap,                    /* SIOCSIWAP */
+       (iw_handler) iwm_wext_giwap,                    /* SIOCGIWAP */
+       (iw_handler) NULL,                              /* SIOCSIWMLME */
+       (iw_handler) NULL,                              /* SIOCGIWAPLIST */
+       (iw_handler) cfg80211_wext_siwscan,             /* SIOCSIWSCAN */
+       (iw_handler) cfg80211_wext_giwscan,             /* SIOCGIWSCAN */
+       (iw_handler) iwm_wext_siwessid,                 /* SIOCSIWESSID */
+       (iw_handler) iwm_wext_giwessid,                 /* SIOCGIWESSID */
+       (iw_handler) NULL,                              /* SIOCSIWNICKN */
+       (iw_handler) NULL,                              /* SIOCGIWNICKN */
+       (iw_handler) NULL,                              /* -- hole -- */
+       (iw_handler) NULL,                              /* -- hole -- */
+       (iw_handler) NULL,                              /* SIOCSIWRATE */
+       (iw_handler) iwm_wext_giwrate,                  /* SIOCGIWRATE */
+       (iw_handler) cfg80211_wext_siwrts,              /* SIOCSIWRTS */
+       (iw_handler) cfg80211_wext_giwrts,              /* SIOCGIWRTS */
+       (iw_handler) cfg80211_wext_siwfrag,             /* SIOCSIWFRAG */
+       (iw_handler) cfg80211_wext_giwfrag,             /* SIOCGIWFRAG */
+       (iw_handler) NULL,                              /* SIOCSIWTXPOW */
+       (iw_handler) NULL,                              /* SIOCGIWTXPOW */
+       (iw_handler) NULL,                              /* SIOCSIWRETRY */
+       (iw_handler) NULL,                              /* SIOCGIWRETRY */
+       (iw_handler) iwm_wext_siwencode,                /* SIOCSIWENCODE */
+       (iw_handler) iwm_wext_giwencode,                /* SIOCGIWENCODE */
+       (iw_handler) iwm_wext_siwpower,                 /* SIOCSIWPOWER */
+       (iw_handler) iwm_wext_giwpower,                 /* SIOCGIWPOWER */
+       (iw_handler) NULL,                              /* -- hole -- */
+       (iw_handler) NULL,                              /* -- hole -- */
+       (iw_handler) NULL,                              /* SIOCSIWGENIE */
+       (iw_handler) NULL,                              /* SIOCGIWGENIE */
+       (iw_handler) iwm_wext_siwauth,                  /* SIOCSIWAUTH */
+       (iw_handler) iwm_wext_giwauth,                  /* SIOCGIWAUTH */
+       (iw_handler) iwm_wext_siwencodeext,             /* SIOCSIWENCODEEXT */
+       (iw_handler) NULL,                              /* SIOCGIWENCODEEXT */
+       (iw_handler) NULL,                              /* SIOCSIWPMKSA */
+       (iw_handler) NULL,                              /* -- hole -- */
+};
+
+const struct iw_handler_def iwm_iw_handler_def = {
+       .num_standard   = ARRAY_SIZE(iwm_handlers),
+       .standard       = (iw_handler *) iwm_handlers,
+       .get_wireless_stats = iwm_get_wireless_stats,
+};
+
index 4bc46a60ae2fd6bd9ec1d30ded33e9f2f3244108..9a5408e7d94a1a3949fc35a5a12b0e206631d28d 100644 (file)
@@ -207,7 +207,7 @@ static int generate_domain_info_11d(struct parsed_region_chan_11d
        lbs_deb_11d("nr_subband=%x\n", domaininfo->nr_subband);
        lbs_deb_hex(LBS_DEB_11D, "domaininfo", (char *)domaininfo,
                COUNTRY_CODE_LEN + 1 +
-               sizeof(struct ieeetypes_subbandset) * nr_subband);
+               sizeof(struct ieee_subbandset) * nr_subband);
        return 0;
 }
 
@@ -302,11 +302,9 @@ done:
  *  @param parsed_region_chan   pointer to parsed_region_chan_11d
  *  @return                    0
 */
-static int parse_domain_info_11d(struct ieeetypes_countryinfofullset*
-                                countryinfo,
+static int parse_domain_info_11d(struct ieee_ie_country_info_full_set *countryinfo,
                                 u8 band,
-                                struct parsed_region_chan_11d *
-                                parsed_region_chan)
+                                struct parsed_region_chan_11d *parsed_region_chan)
 {
        u8 nr_subband, nrchan;
        u8 lastchan, firstchan;
@@ -331,7 +329,7 @@ static int parse_domain_info_11d(struct ieeetypes_countryinfofullset*
        lbs_deb_hex(LBS_DEB_11D, "countryinfo", (u8 *) countryinfo, 30);
 
        if ((*(countryinfo->countrycode)) == 0
-           || (countryinfo->len <= COUNTRY_CODE_LEN)) {
+           || (countryinfo->header.len <= COUNTRY_CODE_LEN)) {
                /* No region Info or Wrong region info: treat as No 11D info */
                goto done;
        }
@@ -349,8 +347,8 @@ static int parse_domain_info_11d(struct ieeetypes_countryinfofullset*
        memcpy(parsed_region_chan->countrycode, countryinfo->countrycode,
               COUNTRY_CODE_LEN);
 
-       nr_subband = (countryinfo->len - COUNTRY_CODE_LEN) /
-           sizeof(struct ieeetypes_subbandset);
+       nr_subband = (countryinfo->header.len - COUNTRY_CODE_LEN) /
+           sizeof(struct ieee_subbandset);
 
        for (j = 0, lastchan = 0; j < nr_subband; j++) {
 
@@ -502,7 +500,7 @@ int lbs_cmd_802_11d_domain_info(struct lbs_private *priv,
 {
        struct cmd_ds_802_11d_domain_info *pdomaininfo =
            &cmd->params.domaininfo;
-       struct mrvlietypes_domainparamset *domain = &pdomaininfo->domain;
+       struct mrvl_ie_domain_param_set *domain = &pdomaininfo->domain;
        u8 nr_subband = priv->domainreg.nr_subband;
 
        lbs_deb_enter(LBS_DEB_11D);
@@ -524,16 +522,16 @@ int lbs_cmd_802_11d_domain_info(struct lbs_private *priv,
               sizeof(domain->countrycode));
 
        domain->header.len =
-           cpu_to_le16(nr_subband * sizeof(struct ieeetypes_subbandset) +
+           cpu_to_le16(nr_subband * sizeof(struct ieee_subbandset) +
                             sizeof(domain->countrycode));
 
        if (nr_subband) {
                memcpy(domain->subband, priv->domainreg.subband,
-                      nr_subband * sizeof(struct ieeetypes_subbandset));
+                      nr_subband * sizeof(struct ieee_subbandset));
 
                cmd->size = cpu_to_le16(sizeof(pdomaininfo->action) +
                                             le16_to_cpu(domain->header.len) +
-                                            sizeof(struct mrvlietypesheader) +
+                                            sizeof(struct mrvl_ie_header) +
                                             S_DS_GEN);
        } else {
                cmd->size =
@@ -556,7 +554,7 @@ done:
 int lbs_ret_802_11d_domain_info(struct cmd_ds_command *resp)
 {
        struct cmd_ds_802_11d_domain_info *domaininfo = &resp->params.domaininforesp;
-       struct mrvlietypes_domainparamset *domain = &domaininfo->domain;
+       struct mrvl_ie_domain_param_set *domain = &domaininfo->domain;
        u16 action = le16_to_cpu(domaininfo->action);
        s16 ret = 0;
        u8 nr_subband = 0;
@@ -567,7 +565,7 @@ int lbs_ret_802_11d_domain_info(struct cmd_ds_command *resp)
                (int)le16_to_cpu(resp->size));
 
        nr_subband = (le16_to_cpu(domain->header.len) - COUNTRY_CODE_LEN) /
-                     sizeof(struct ieeetypes_subbandset);
+                     sizeof(struct ieee_subbandset);
 
        lbs_deb_11d("domain info resp: nr_subband %d\n", nr_subband);
 
index 4f4f47f0f8781987ef483a6c73b37b18504475f7..fb75d3e321a05a64fcd5c7e0736a562f47c83fd1 100644 (file)
 struct cmd_ds_command;
 
 /** Data structure for Country IE*/
-struct ieeetypes_subbandset {
+struct ieee_subbandset {
        u8 firstchan;
        u8 nrchan;
        u8 maxtxpwr;
 } __attribute__ ((packed));
 
-struct ieeetypes_countryinfoset {
-       u8 element_id;
-       u8 len;
+struct ieee_ie_country_info_set {
+       struct ieee_ie_header header;
+
        u8 countrycode[COUNTRY_CODE_LEN];
-       struct ieeetypes_subbandset subband[1];
+       struct ieee_subbandset subband[1];
 };
 
-struct ieeetypes_countryinfofullset {
-       u8 element_id;
-       u8 len;
+struct ieee_ie_country_info_full_set {
+       struct ieee_ie_header header;
+
        u8 countrycode[COUNTRY_CODE_LEN];
-       struct ieeetypes_subbandset subband[MRVDRV_MAX_SUBBAND_802_11D];
+       struct ieee_subbandset subband[MRVDRV_MAX_SUBBAND_802_11D];
 } __attribute__ ((packed));
 
-struct mrvlietypes_domainparamset {
-       struct mrvlietypesheader header;
+struct mrvl_ie_domain_param_set {
+       struct mrvl_ie_header header;
+
        u8 countrycode[COUNTRY_CODE_LEN];
-       struct ieeetypes_subbandset subband[1];
+       struct ieee_subbandset subband[1];
 } __attribute__ ((packed));
 
 struct cmd_ds_802_11d_domain_info {
        __le16 action;
-       struct mrvlietypes_domainparamset domain;
+       struct mrvl_ie_domain_param_set domain;
 } __attribute__ ((packed));
 
 /** domain regulatory information */
@@ -57,7 +58,7 @@ struct lbs_802_11d_domain_reg {
        u8 countrycode[COUNTRY_CODE_LEN];
        /** No. of subband*/
        u8 nr_subband;
-       struct ieeetypes_subbandset subband[MRVDRV_MAX_SUBBAND_802_11D];
+       struct ieee_subbandset subband[MRVDRV_MAX_SUBBAND_802_11D];
 };
 
 struct chan_power_11d {
index a0e440cd8967ec55c53ae17b948d678d6c5b7959..b9b374119033f7fa92f04a0bfa7b6e8cf7e737ac 100644 (file)
 #include "scan.h"
 #include "cmd.h"
 
-static int lbs_adhoc_post(struct lbs_private *priv, struct cmd_header *resp);
-
 static const u8 bssid_any[ETH_ALEN]  __attribute__ ((aligned (2))) =
        { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
 static const u8 bssid_off[ETH_ALEN]  __attribute__ ((aligned (2))) =
        { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
 
-/* The firmware needs certain bits masked out of the beacon-derviced capability
- * field when associating/joining to BSSs.
+/* The firmware needs the following bits masked out of the beacon-derived
+ * capability field when associating/joining to a BSS:
+ *  9 (QoS), 11 (APSD), 12 (unused), 14 (unused), 15 (unused)
  */
 #define CAPINFO_MASK   (~(0xda00))
 
@@ -102,6 +101,295 @@ static void lbs_set_basic_rate_flags(u8 *rates, size_t len)
 }
 
 
+static u8 iw_auth_to_ieee_auth(u8 auth)
+{
+       if (auth == IW_AUTH_ALG_OPEN_SYSTEM)
+               return 0x00;
+       else if (auth == IW_AUTH_ALG_SHARED_KEY)
+               return 0x01;
+       else if (auth == IW_AUTH_ALG_LEAP)
+               return 0x80;
+
+       lbs_deb_join("%s: invalid auth alg 0x%X\n", __func__, auth);
+       return 0;
+}
+
+/**
+ *  @brief This function prepares the authenticate command.  AUTHENTICATE only
+ *  sets the authentication suite for future associations, as the firmware
+ *  handles authentication internally during the ASSOCIATE command.
+ *
+ *  @param priv      A pointer to struct lbs_private structure
+ *  @param bssid     The peer BSSID with which to authenticate
+ *  @param auth      The authentication mode to use (from wireless.h)
+ *
+ *  @return         0 or -1
+ */
+static int lbs_set_authentication(struct lbs_private *priv, u8 bssid[6], u8 auth)
+{
+       struct cmd_ds_802_11_authenticate cmd;
+       int ret = -1;
+       DECLARE_MAC_BUF(mac);
+
+       lbs_deb_enter(LBS_DEB_JOIN);
+
+       cmd.hdr.size = cpu_to_le16(sizeof(cmd));
+       memcpy(cmd.bssid, bssid, ETH_ALEN);
+
+       cmd.authtype = iw_auth_to_ieee_auth(auth);
+
+       lbs_deb_join("AUTH_CMD: BSSID %s, auth 0x%x\n",
+               print_mac(mac, bssid), cmd.authtype);
+
+       ret = lbs_cmd_with_response(priv, CMD_802_11_AUTHENTICATE, &cmd);
+
+       lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret);
+       return ret;
+}
+
+
+static int lbs_assoc_post(struct lbs_private *priv,
+                         struct cmd_ds_802_11_associate_response *resp)
+{
+       int ret = 0;
+       union iwreq_data wrqu;
+       struct bss_descriptor *bss;
+       u16 status_code;
+
+       lbs_deb_enter(LBS_DEB_ASSOC);
+
+       if (!priv->in_progress_assoc_req) {
+               lbs_deb_assoc("ASSOC_RESP: no in-progress assoc request\n");
+               ret = -1;
+               goto done;
+       }
+       bss = &priv->in_progress_assoc_req->bss;
+
+       /*
+        * Older FW versions map the IEEE 802.11 Status Code in the association
+        * response to the following values returned in resp->statuscode:
+        *
+        *    IEEE Status Code                Marvell Status Code
+        *    0                       ->      0x0000 ASSOC_RESULT_SUCCESS
+        *    13                      ->      0x0004 ASSOC_RESULT_AUTH_REFUSED
+        *    14                      ->      0x0004 ASSOC_RESULT_AUTH_REFUSED
+        *    15                      ->      0x0004 ASSOC_RESULT_AUTH_REFUSED
+        *    16                      ->      0x0004 ASSOC_RESULT_AUTH_REFUSED
+        *    others                  ->      0x0003 ASSOC_RESULT_REFUSED
+        *
+        * Other response codes:
+        *    0x0001 -> ASSOC_RESULT_INVALID_PARAMETERS (unused)
+        *    0x0002 -> ASSOC_RESULT_TIMEOUT (internal timer expired waiting for
+        *                                    association response from the AP)
+        */
+
+       status_code = le16_to_cpu(resp->statuscode);
+       if (priv->fwrelease < 0x09000000) {
+               switch (status_code) {
+               case 0x00:
+                       break;
+               case 0x01:
+                       lbs_deb_assoc("ASSOC_RESP: invalid parameters\n");
+                       break;
+               case 0x02:
+                       lbs_deb_assoc("ASSOC_RESP: internal timer "
+                               "expired while waiting for the AP\n");
+                       break;
+               case 0x03:
+                       lbs_deb_assoc("ASSOC_RESP: association "
+                               "refused by AP\n");
+                       break;
+               case 0x04:
+                       lbs_deb_assoc("ASSOC_RESP: authentication "
+                               "refused by AP\n");
+                       break;
+               default:
+                       lbs_deb_assoc("ASSOC_RESP: failure reason 0x%02x "
+                               " unknown\n", status_code);
+                       break;
+               }
+       } else {
+               /* v9+ returns the AP's association response */
+               lbs_deb_assoc("ASSOC_RESP: failure reason 0x%02x\n", status_code);
+       }
+
+       if (status_code) {
+               lbs_mac_event_disconnected(priv);
+               ret = -1;
+               goto done;
+       }
+
+       lbs_deb_hex(LBS_DEB_ASSOC, "ASSOC_RESP",
+                   (void *) (resp + sizeof (resp->hdr)),
+                   le16_to_cpu(resp->hdr.size) - sizeof (resp->hdr));
+
+       /* Send a Media Connected event, according to the Spec */
+       priv->connect_status = LBS_CONNECTED;
+
+       /* Update current SSID and BSSID */
+       memcpy(&priv->curbssparams.ssid, &bss->ssid, IW_ESSID_MAX_SIZE);
+       priv->curbssparams.ssid_len = bss->ssid_len;
+       memcpy(priv->curbssparams.bssid, bss->bssid, ETH_ALEN);
+
+       priv->SNR[TYPE_RXPD][TYPE_AVG] = 0;
+       priv->NF[TYPE_RXPD][TYPE_AVG] = 0;
+
+       memset(priv->rawSNR, 0x00, sizeof(priv->rawSNR));
+       memset(priv->rawNF, 0x00, sizeof(priv->rawNF));
+       priv->nextSNRNF = 0;
+       priv->numSNRNF = 0;
+
+       netif_carrier_on(priv->dev);
+       if (!priv->tx_pending_len)
+               netif_wake_queue(priv->dev);
+
+       memcpy(wrqu.ap_addr.sa_data, priv->curbssparams.bssid, ETH_ALEN);
+       wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+       wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
+
+done:
+       lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
+       return ret;
+}
+
+/**
+ *  @brief This function prepares an association-class command.
+ *
+ *  @param priv      A pointer to struct lbs_private structure
+ *  @param assoc_req The association request describing the BSS to associate
+ *                   or reassociate with
+ *  @param command   The actual command, either CMD_802_11_ASSOCIATE or
+ *                   CMD_802_11_REASSOCIATE
+ *
+ *  @return         0 or -1
+ */
+static int lbs_associate(struct lbs_private *priv,
+                        struct assoc_request *assoc_req,
+                        u16 command)
+{
+       struct cmd_ds_802_11_associate cmd;
+       int ret = 0;
+       struct bss_descriptor *bss = &assoc_req->bss;
+       u8 *pos = &(cmd.iebuf[0]);
+       u16 tmpcap, tmplen, tmpauth;
+       struct mrvl_ie_ssid_param_set *ssid;
+       struct mrvl_ie_ds_param_set *ds;
+       struct mrvl_ie_cf_param_set *cf;
+       struct mrvl_ie_rates_param_set *rates;
+       struct mrvl_ie_rsn_param_set *rsn;
+       struct mrvl_ie_auth_type *auth;
+
+       lbs_deb_enter(LBS_DEB_ASSOC);
+
+       BUG_ON((command != CMD_802_11_ASSOCIATE) &&
+               (command != CMD_802_11_REASSOCIATE));
+
+       memset(&cmd, 0, sizeof(cmd));
+       cmd.hdr.command = cpu_to_le16(command);
+
+       /* Fill in static fields */
+       memcpy(cmd.bssid, bss->bssid, ETH_ALEN);
+       cmd.listeninterval = cpu_to_le16(MRVDRV_DEFAULT_LISTEN_INTERVAL);
+
+       /* Capability info */
+       tmpcap = (bss->capability & CAPINFO_MASK);
+       if (bss->mode == IW_MODE_INFRA)
+               tmpcap |= WLAN_CAPABILITY_ESS;
+       cmd.capability = cpu_to_le16(tmpcap);
+       lbs_deb_assoc("ASSOC_CMD: capability 0x%04x\n", tmpcap);
+
+       /* SSID */
+       ssid = (struct mrvl_ie_ssid_param_set *) pos;
+       ssid->header.type = cpu_to_le16(TLV_TYPE_SSID);
+       tmplen = bss->ssid_len;
+       ssid->header.len = cpu_to_le16(tmplen);
+       memcpy(ssid->ssid, bss->ssid, tmplen);
+       pos += sizeof(ssid->header) + tmplen;
+
+       ds = (struct mrvl_ie_ds_param_set *) pos;
+       ds->header.type = cpu_to_le16(TLV_TYPE_PHY_DS);
+       ds->header.len = cpu_to_le16(1);
+       ds->channel = bss->phy.ds.channel;
+       pos += sizeof(ds->header) + 1;
+
+       cf = (struct mrvl_ie_cf_param_set *) pos;
+       cf->header.type = cpu_to_le16(TLV_TYPE_CF);
+       tmplen = sizeof(*cf) - sizeof (cf->header);
+       cf->header.len = cpu_to_le16(tmplen);
+       /* IE payload should be zeroed, firmware fills it in for us */
+       pos += sizeof(*cf);
+
+       rates = (struct mrvl_ie_rates_param_set *) pos;
+       rates->header.type = cpu_to_le16(TLV_TYPE_RATES);
+       memcpy(&rates->rates, &bss->rates, MAX_RATES);
+       tmplen = MAX_RATES;
+       if (get_common_rates(priv, rates->rates, &tmplen)) {
+               ret = -1;
+               goto done;
+       }
+       pos += sizeof(rates->header) + tmplen;
+       rates->header.len = cpu_to_le16(tmplen);
+       lbs_deb_assoc("ASSOC_CMD: num rates %u\n", tmplen);
+
+       /* Copy the infra. association rates into Current BSS state structure */
+       memset(&priv->curbssparams.rates, 0, sizeof(priv->curbssparams.rates));
+       memcpy(&priv->curbssparams.rates, &rates->rates, tmplen);
+
+       /* Set MSB on basic rates as the firmware requires, but _after_
+        * copying to current bss rates.
+        */
+       lbs_set_basic_rate_flags(rates->rates, tmplen);
+
+       /* Firmware v9+ indicate authentication suites as a TLV */
+       if (priv->fwrelease >= 0x09000000) {
+               DECLARE_MAC_BUF(mac);
+
+               auth = (struct mrvl_ie_auth_type *) pos;
+               auth->header.type = cpu_to_le16(TLV_TYPE_AUTH_TYPE);
+               auth->header.len = cpu_to_le16(2);
+               tmpauth = iw_auth_to_ieee_auth(priv->secinfo.auth_mode);
+               auth->auth = cpu_to_le16(tmpauth);
+               pos += sizeof(auth->header) + 2;
+
+               lbs_deb_join("AUTH_CMD: BSSID %s, auth 0x%x\n",
+                       print_mac(mac, bss->bssid), priv->secinfo.auth_mode);
+       }
+
+       /* WPA/WPA2 IEs */
+       if (assoc_req->secinfo.WPAenabled || assoc_req->secinfo.WPA2enabled) {
+               rsn = (struct mrvl_ie_rsn_param_set *) pos;
+               /* WPA_IE or WPA2_IE */
+               rsn->header.type = cpu_to_le16((u16) assoc_req->wpa_ie[0]);
+               tmplen = (u16) assoc_req->wpa_ie[1];
+               rsn->header.len = cpu_to_le16(tmplen);
+               memcpy(rsn->rsnie, &assoc_req->wpa_ie[2], tmplen);
+               lbs_deb_hex(LBS_DEB_JOIN, "ASSOC_CMD: WPA/RSN IE", (u8 *) rsn,
+                       sizeof(rsn->header) + tmplen);
+               pos += sizeof(rsn->header) + tmplen;
+       }
+
+       cmd.hdr.size = cpu_to_le16((sizeof(cmd) - sizeof(cmd.iebuf)) +
+                                  (u16)(pos - (u8 *) &cmd.iebuf));
+
+       /* update curbssparams */
+       priv->curbssparams.channel = bss->phy.ds.channel;
+
+       if (lbs_parse_dnld_countryinfo_11d(priv, bss)) {
+               ret = -1;
+               goto done;
+       }
+
+       ret = lbs_cmd_with_response(priv, command, &cmd);
+       if (ret == 0) {
+               ret = lbs_assoc_post(priv,
+                       (struct cmd_ds_802_11_associate_response *) &cmd);
+       }
+
+done:
+       lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
+       return ret;
+}
+
 /**
  *  @brief Associate to a specific BSS discovered in a scan
  *
@@ -110,7 +398,7 @@ static void lbs_set_basic_rate_flags(u8 *rates, size_t len)
  *
  *  @return          0-success, otherwise fail
  */
-static int lbs_associate(struct lbs_private *priv,
+static int lbs_try_associate(struct lbs_private *priv,
        struct assoc_request *assoc_req)
 {
        int ret;
@@ -118,11 +406,15 @@ static int lbs_associate(struct lbs_private *priv,
 
        lbs_deb_enter(LBS_DEB_ASSOC);
 
-       ret = lbs_prepare_and_send_command(priv, CMD_802_11_AUTHENTICATE,
-                                   0, CMD_OPTION_WAITFORRSP,
-                                   0, assoc_req->bss.bssid);
-       if (ret)
-               goto out;
+       /* FW v9 and higher indicate authentication suites as a TLV in the
+        * association command, not as a separate authentication command.
+        */
+       if (priv->fwrelease < 0x09000000) {
+               ret = lbs_set_authentication(priv, assoc_req->bss.bssid,
+                                            priv->secinfo.auth_mode);
+               if (ret)
+                       goto out;
+       }
 
        /* Use short preamble only when both the BSS and firmware support it */
        if ((priv->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) &&
@@ -133,14 +425,78 @@ static int lbs_associate(struct lbs_private *priv,
        if (ret)
                goto out;
 
-       ret = lbs_prepare_and_send_command(priv, CMD_802_11_ASSOCIATE,
-                                   0, CMD_OPTION_WAITFORRSP, 0, assoc_req);
+       ret = lbs_associate(priv, assoc_req, CMD_802_11_ASSOCIATE);
 
 out:
        lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
        return ret;
 }
 
+static int lbs_adhoc_post(struct lbs_private *priv,
+                         struct cmd_ds_802_11_ad_hoc_result *resp)
+{
+       int ret = 0;
+       u16 command = le16_to_cpu(resp->hdr.command);
+       u16 result = le16_to_cpu(resp->hdr.result);
+       union iwreq_data wrqu;
+       struct bss_descriptor *bss;
+       DECLARE_SSID_BUF(ssid);
+
+       lbs_deb_enter(LBS_DEB_JOIN);
+
+       if (!priv->in_progress_assoc_req) {
+               lbs_deb_join("ADHOC_RESP: no in-progress association "
+                       "request\n");
+               ret = -1;
+               goto done;
+       }
+       bss = &priv->in_progress_assoc_req->bss;
+
+       /*
+        * Join result code 0 --> SUCCESS
+        */
+       if (result) {
+               lbs_deb_join("ADHOC_RESP: failed (result 0x%X)\n", result);
+               if (priv->connect_status == LBS_CONNECTED)
+                       lbs_mac_event_disconnected(priv);
+               ret = -1;
+               goto done;
+       }
+
+       /* Send a Media Connected event, according to the Spec */
+       priv->connect_status = LBS_CONNECTED;
+
+       if (command == CMD_RET(CMD_802_11_AD_HOC_START)) {
+               /* Update the created network descriptor with the new BSSID */
+               memcpy(bss->bssid, resp->bssid, ETH_ALEN);
+       }
+
+       /* Set the BSSID from the joined/started descriptor */
+       memcpy(&priv->curbssparams.bssid, bss->bssid, ETH_ALEN);
+
+       /* Set the new SSID to current SSID */
+       memcpy(&priv->curbssparams.ssid, &bss->ssid, IW_ESSID_MAX_SIZE);
+       priv->curbssparams.ssid_len = bss->ssid_len;
+
+       netif_carrier_on(priv->dev);
+       if (!priv->tx_pending_len)
+               netif_wake_queue(priv->dev);
+
+       memset(&wrqu, 0, sizeof(wrqu));
+       memcpy(wrqu.ap_addr.sa_data, priv->curbssparams.bssid, ETH_ALEN);
+       wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+       wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
+
+       lbs_deb_join("ADHOC_RESP: Joined/started '%s', BSSID %pM, channel %d\n",
+                    print_ssid(ssid, bss->ssid, bss->ssid_len),
+                    priv->curbssparams.bssid,
+                    priv->curbssparams.channel);
+
+done:
+       lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret);
+       return ret;
+}
+
 /**
  *  @brief Join an adhoc network found in a previous scan
  *
@@ -219,11 +575,10 @@ static int lbs_adhoc_join(struct lbs_private *priv,
        memcpy(&cmd.bss.bssid, &bss->bssid, ETH_ALEN);
        memcpy(&cmd.bss.ssid, &bss->ssid, bss->ssid_len);
 
-       memcpy(&cmd.bss.phyparamset, &bss->phyparamset,
-              sizeof(union ieeetypes_phyparamset));
+       memcpy(&cmd.bss.ds, &bss->phy.ds, sizeof(struct ieee_ie_ds_param_set));
 
-       memcpy(&cmd.bss.ssparamset, &bss->ssparamset,
-              sizeof(union IEEEtypes_ssparamset));
+       memcpy(&cmd.bss.ibss, &bss->ss.ibss,
+              sizeof(struct ieee_ie_ibss_param_set));
 
        cmd.bss.capability = cpu_to_le16(bss->capability & CAPINFO_MASK);
        lbs_deb_join("ADHOC_J_CMD: tmpcap=%4X CAPINFO_MASK=%4X\n",
@@ -260,7 +615,7 @@ static int lbs_adhoc_join(struct lbs_private *priv,
         */
        lbs_set_basic_rate_flags(cmd.bss.rates, ratesize);
 
-       cmd.bss.ssparamset.ibssparamset.atimwindow = cpu_to_le16(bss->atimwindow);
+       cmd.bss.ibss.atimwindow = bss->atimwindow;
 
        if (assoc_req->secinfo.wep_enabled) {
                u16 tmp = le16_to_cpu(cmd.bss.capability);
@@ -287,8 +642,10 @@ static int lbs_adhoc_join(struct lbs_private *priv,
        }
 
        ret = lbs_cmd_with_response(priv, CMD_802_11_AD_HOC_JOIN, &cmd);
-       if (ret == 0)
-               ret = lbs_adhoc_post(priv, (struct cmd_header *) &cmd);
+       if (ret == 0) {
+               ret = lbs_adhoc_post(priv,
+                                    (struct cmd_ds_802_11_ad_hoc_result *)&cmd);
+       }
 
 out:
        lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
@@ -343,22 +700,24 @@ static int lbs_adhoc_start(struct lbs_private *priv,
        WARN_ON(!assoc_req->channel);
 
        /* set Physical parameter set */
-       cmd.phyparamset.dsparamset.elementid = WLAN_EID_DS_PARAMS;
-       cmd.phyparamset.dsparamset.len = 1;
-       cmd.phyparamset.dsparamset.currentchan = assoc_req->channel;
+       cmd.ds.header.id = WLAN_EID_DS_PARAMS;
+       cmd.ds.header.len = 1;
+       cmd.ds.channel = assoc_req->channel;
 
        /* set IBSS parameter set */
-       cmd.ssparamset.ibssparamset.elementid = WLAN_EID_IBSS_PARAMS;
-       cmd.ssparamset.ibssparamset.len = 2;
-       cmd.ssparamset.ibssparamset.atimwindow = 0;
+       cmd.ibss.header.id = WLAN_EID_IBSS_PARAMS;
+       cmd.ibss.header.len = 2;
+       cmd.ibss.atimwindow = cpu_to_le16(0);
 
        /* set capability info */
        tmpcap = WLAN_CAPABILITY_IBSS;
-       if (assoc_req->secinfo.wep_enabled) {
-               lbs_deb_join("ADHOC_START: WEP enabled, setting privacy on\n");
+       if (assoc_req->secinfo.wep_enabled ||
+           assoc_req->secinfo.WPAenabled ||
+           assoc_req->secinfo.WPA2enabled) {
+               lbs_deb_join("ADHOC_START: WEP/WPA enabled, privacy on\n");
                tmpcap |= WLAN_CAPABILITY_PRIVACY;
        } else
-               lbs_deb_join("ADHOC_START: WEP disabled, setting privacy off\n");
+               lbs_deb_join("ADHOC_START: WEP disabled, privacy off\n");
 
        cmd.capability = cpu_to_le16(tmpcap);
 
@@ -395,7 +754,8 @@ static int lbs_adhoc_start(struct lbs_private *priv,
 
        ret = lbs_cmd_with_response(priv, CMD_802_11_AD_HOC_START, &cmd);
        if (ret == 0)
-               ret = lbs_adhoc_post(priv, (struct cmd_header *) &cmd);
+               ret = lbs_adhoc_post(priv,
+                                    (struct cmd_ds_802_11_ad_hoc_result *)&cmd);
 
 out:
        lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
@@ -720,7 +1080,7 @@ static int assoc_helper_essid(struct lbs_private *priv,
                                assoc_req->ssid_len, NULL, IW_MODE_INFRA, channel);
                if (bss != NULL) {
                        memcpy(&assoc_req->bss, bss, sizeof(struct bss_descriptor));
-                       ret = lbs_associate(priv, assoc_req);
+                       ret = lbs_try_associate(priv, assoc_req);
                } else {
                        lbs_deb_assoc("SSID not found; cannot associate\n");
                }
@@ -772,8 +1132,9 @@ static int assoc_helper_bssid(struct lbs_private *priv,
 
        memcpy(&assoc_req->bss, bss, sizeof(struct bss_descriptor));
        if (assoc_req->mode == IW_MODE_INFRA) {
-               ret = lbs_associate(priv, assoc_req);
-               lbs_deb_assoc("ASSOC: lbs_associate(bssid) returned %d\n", ret);
+               ret = lbs_try_associate(priv, assoc_req);
+               lbs_deb_assoc("ASSOC: lbs_try_associate(bssid) returned %d\n",
+                             ret);
        } else if (assoc_req->mode == IW_MODE_ADHOC) {
                lbs_adhoc_join(priv, assoc_req);
        }
@@ -1466,57 +1827,6 @@ struct assoc_request *lbs_get_association_request(struct lbs_private *priv)
 }
 
 
-/**
- *  @brief This function prepares command of authenticate.
- *
- *  @param priv      A pointer to struct lbs_private structure
- *  @param cmd       A pointer to cmd_ds_command structure
- *  @param pdata_buf Void cast of pointer to a BSSID to authenticate with
- *
- *  @return         0 or -1
- */
-int lbs_cmd_80211_authenticate(struct lbs_private *priv,
-                                struct cmd_ds_command *cmd,
-                                void *pdata_buf)
-{
-       struct cmd_ds_802_11_authenticate *pauthenticate = &cmd->params.auth;
-       int ret = -1;
-       u8 *bssid = pdata_buf;
-
-       lbs_deb_enter(LBS_DEB_JOIN);
-
-       cmd->command = cpu_to_le16(CMD_802_11_AUTHENTICATE);
-       cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_authenticate)
-                       + S_DS_GEN);
-
-       /* translate auth mode to 802.11 defined wire value */
-       switch (priv->secinfo.auth_mode) {
-       case IW_AUTH_ALG_OPEN_SYSTEM:
-               pauthenticate->authtype = 0x00;
-               break;
-       case IW_AUTH_ALG_SHARED_KEY:
-               pauthenticate->authtype = 0x01;
-               break;
-       case IW_AUTH_ALG_LEAP:
-               pauthenticate->authtype = 0x80;
-               break;
-       default:
-               lbs_deb_join("AUTH_CMD: invalid auth alg 0x%X\n",
-                       priv->secinfo.auth_mode);
-               goto out;
-       }
-
-       memcpy(pauthenticate->macaddr, bssid, ETH_ALEN);
-
-       lbs_deb_join("AUTH_CMD: BSSID %pM, auth 0x%x\n",
-               bssid, pauthenticate->authtype);
-       ret = 0;
-
-out:
-       lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret);
-       return ret;
-}
-
 /**
  *  @brief Deauthenticate from a specific BSS
  *
@@ -1550,285 +1860,3 @@ int lbs_cmd_80211_deauthenticate(struct lbs_private *priv, u8 bssid[ETH_ALEN],
        return ret;
 }
 
-int lbs_cmd_80211_associate(struct lbs_private *priv,
-                             struct cmd_ds_command *cmd, void *pdata_buf)
-{
-       struct cmd_ds_802_11_associate *passo = &cmd->params.associate;
-       int ret = 0;
-       struct assoc_request *assoc_req = pdata_buf;
-       struct bss_descriptor *bss = &assoc_req->bss;
-       u8 *pos;
-       u16 tmpcap, tmplen;
-       struct mrvlietypes_ssidparamset *ssid;
-       struct mrvlietypes_phyparamset *phy;
-       struct mrvlietypes_ssparamset *ss;
-       struct mrvlietypes_ratesparamset *rates;
-       struct mrvlietypes_rsnparamset *rsn;
-
-       lbs_deb_enter(LBS_DEB_ASSOC);
-
-       pos = (u8 *) passo;
-
-       if (!priv) {
-               ret = -1;
-               goto done;
-       }
-
-       cmd->command = cpu_to_le16(CMD_802_11_ASSOCIATE);
-
-       memcpy(passo->peerstaaddr, bss->bssid, sizeof(passo->peerstaaddr));
-       pos += sizeof(passo->peerstaaddr);
-
-       /* set the listen interval */
-       passo->listeninterval = cpu_to_le16(MRVDRV_DEFAULT_LISTEN_INTERVAL);
-
-       pos += sizeof(passo->capability);
-       pos += sizeof(passo->listeninterval);
-       pos += sizeof(passo->bcnperiod);
-       pos += sizeof(passo->dtimperiod);
-
-       ssid = (struct mrvlietypes_ssidparamset *) pos;
-       ssid->header.type = cpu_to_le16(TLV_TYPE_SSID);
-       tmplen = bss->ssid_len;
-       ssid->header.len = cpu_to_le16(tmplen);
-       memcpy(ssid->ssid, bss->ssid, tmplen);
-       pos += sizeof(ssid->header) + tmplen;
-
-       phy = (struct mrvlietypes_phyparamset *) pos;
-       phy->header.type = cpu_to_le16(TLV_TYPE_PHY_DS);
-       tmplen = sizeof(phy->fh_ds.dsparamset);
-       phy->header.len = cpu_to_le16(tmplen);
-       memcpy(&phy->fh_ds.dsparamset,
-              &bss->phyparamset.dsparamset.currentchan,
-              tmplen);
-       pos += sizeof(phy->header) + tmplen;
-
-       ss = (struct mrvlietypes_ssparamset *) pos;
-       ss->header.type = cpu_to_le16(TLV_TYPE_CF);
-       tmplen = sizeof(ss->cf_ibss.cfparamset);
-       ss->header.len = cpu_to_le16(tmplen);
-       pos += sizeof(ss->header) + tmplen;
-
-       rates = (struct mrvlietypes_ratesparamset *) pos;
-       rates->header.type = cpu_to_le16(TLV_TYPE_RATES);
-       memcpy(&rates->rates, &bss->rates, MAX_RATES);
-       tmplen = MAX_RATES;
-       if (get_common_rates(priv, rates->rates, &tmplen)) {
-               ret = -1;
-               goto done;
-       }
-       pos += sizeof(rates->header) + tmplen;
-       rates->header.len = cpu_to_le16(tmplen);
-       lbs_deb_assoc("ASSOC_CMD: num rates %u\n", tmplen);
-
-       /* Copy the infra. association rates into Current BSS state structure */
-       memset(&priv->curbssparams.rates, 0, sizeof(priv->curbssparams.rates));
-       memcpy(&priv->curbssparams.rates, &rates->rates, tmplen);
-
-       /* Set MSB on basic rates as the firmware requires, but _after_
-        * copying to current bss rates.
-        */
-       lbs_set_basic_rate_flags(rates->rates, tmplen);
-
-       if (assoc_req->secinfo.WPAenabled || assoc_req->secinfo.WPA2enabled) {
-               rsn = (struct mrvlietypes_rsnparamset *) pos;
-               /* WPA_IE or WPA2_IE */
-               rsn->header.type = cpu_to_le16((u16) assoc_req->wpa_ie[0]);
-               tmplen = (u16) assoc_req->wpa_ie[1];
-               rsn->header.len = cpu_to_le16(tmplen);
-               memcpy(rsn->rsnie, &assoc_req->wpa_ie[2], tmplen);
-               lbs_deb_hex(LBS_DEB_JOIN, "ASSOC_CMD: RSN IE", (u8 *) rsn,
-                       sizeof(rsn->header) + tmplen);
-               pos += sizeof(rsn->header) + tmplen;
-       }
-
-       /* update curbssparams */
-       priv->curbssparams.channel = bss->phyparamset.dsparamset.currentchan;
-
-       if (lbs_parse_dnld_countryinfo_11d(priv, bss)) {
-               ret = -1;
-               goto done;
-       }
-
-       cmd->size = cpu_to_le16((u16) (pos - (u8 *) passo) + S_DS_GEN);
-
-       /* set the capability info */
-       tmpcap = (bss->capability & CAPINFO_MASK);
-       if (bss->mode == IW_MODE_INFRA)
-               tmpcap |= WLAN_CAPABILITY_ESS;
-       passo->capability = cpu_to_le16(tmpcap);
-       lbs_deb_assoc("ASSOC_CMD: capability 0x%04x\n", tmpcap);
-
-done:
-       lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
-       return ret;
-}
-
-int lbs_ret_80211_associate(struct lbs_private *priv,
-                             struct cmd_ds_command *resp)
-{
-       int ret = 0;
-       union iwreq_data wrqu;
-       struct ieeetypes_assocrsp *passocrsp;
-       struct bss_descriptor *bss;
-       u16 status_code;
-
-       lbs_deb_enter(LBS_DEB_ASSOC);
-
-       if (!priv->in_progress_assoc_req) {
-               lbs_deb_assoc("ASSOC_RESP: no in-progress assoc request\n");
-               ret = -1;
-               goto done;
-       }
-       bss = &priv->in_progress_assoc_req->bss;
-
-       passocrsp = (struct ieeetypes_assocrsp *) &resp->params;
-
-       /*
-        * Older FW versions map the IEEE 802.11 Status Code in the association
-        * response to the following values returned in passocrsp->statuscode:
-        *
-        *    IEEE Status Code                Marvell Status Code
-        *    0                       ->      0x0000 ASSOC_RESULT_SUCCESS
-        *    13                      ->      0x0004 ASSOC_RESULT_AUTH_REFUSED
-        *    14                      ->      0x0004 ASSOC_RESULT_AUTH_REFUSED
-        *    15                      ->      0x0004 ASSOC_RESULT_AUTH_REFUSED
-        *    16                      ->      0x0004 ASSOC_RESULT_AUTH_REFUSED
-        *    others                  ->      0x0003 ASSOC_RESULT_REFUSED
-        *
-        * Other response codes:
-        *    0x0001 -> ASSOC_RESULT_INVALID_PARAMETERS (unused)
-        *    0x0002 -> ASSOC_RESULT_TIMEOUT (internal timer expired waiting for
-        *                                    association response from the AP)
-        */
-
-       status_code = le16_to_cpu(passocrsp->statuscode);
-       switch (status_code) {
-       case 0x00:
-               break;
-       case 0x01:
-               lbs_deb_assoc("ASSOC_RESP: invalid parameters\n");
-               break;
-       case 0x02:
-               lbs_deb_assoc("ASSOC_RESP: internal timer "
-                       "expired while waiting for the AP\n");
-               break;
-       case 0x03:
-               lbs_deb_assoc("ASSOC_RESP: association "
-                       "refused by AP\n");
-               break;
-       case 0x04:
-               lbs_deb_assoc("ASSOC_RESP: authentication "
-                       "refused by AP\n");
-               break;
-       default:
-               lbs_deb_assoc("ASSOC_RESP: failure reason 0x%02x "
-                       " unknown\n", status_code);
-               break;
-       }
-
-       if (status_code) {
-               lbs_mac_event_disconnected(priv);
-               ret = -1;
-               goto done;
-       }
-
-       lbs_deb_hex(LBS_DEB_ASSOC, "ASSOC_RESP", (void *)&resp->params,
-               le16_to_cpu(resp->size) - S_DS_GEN);
-
-       /* Send a Media Connected event, according to the Spec */
-       priv->connect_status = LBS_CONNECTED;
-
-       /* Update current SSID and BSSID */
-       memcpy(&priv->curbssparams.ssid, &bss->ssid, IW_ESSID_MAX_SIZE);
-       priv->curbssparams.ssid_len = bss->ssid_len;
-       memcpy(priv->curbssparams.bssid, bss->bssid, ETH_ALEN);
-
-       priv->SNR[TYPE_RXPD][TYPE_AVG] = 0;
-       priv->NF[TYPE_RXPD][TYPE_AVG] = 0;
-
-       memset(priv->rawSNR, 0x00, sizeof(priv->rawSNR));
-       memset(priv->rawNF, 0x00, sizeof(priv->rawNF));
-       priv->nextSNRNF = 0;
-       priv->numSNRNF = 0;
-
-       netif_carrier_on(priv->dev);
-       if (!priv->tx_pending_len)
-               netif_wake_queue(priv->dev);
-
-       memcpy(wrqu.ap_addr.sa_data, priv->curbssparams.bssid, ETH_ALEN);
-       wrqu.ap_addr.sa_family = ARPHRD_ETHER;
-       wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
-
-done:
-       lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
-       return ret;
-}
-
-static int lbs_adhoc_post(struct lbs_private *priv, struct cmd_header *resp)
-{
-       int ret = 0;
-       u16 command = le16_to_cpu(resp->command);
-       u16 result = le16_to_cpu(resp->result);
-       struct cmd_ds_802_11_ad_hoc_result *adhoc_resp;
-       union iwreq_data wrqu;
-       struct bss_descriptor *bss;
-       DECLARE_SSID_BUF(ssid);
-
-       lbs_deb_enter(LBS_DEB_JOIN);
-
-       adhoc_resp = (struct cmd_ds_802_11_ad_hoc_result *) resp;
-
-       if (!priv->in_progress_assoc_req) {
-               lbs_deb_join("ADHOC_RESP: no in-progress association "
-                       "request\n");
-               ret = -1;
-               goto done;
-       }
-       bss = &priv->in_progress_assoc_req->bss;
-
-       /*
-        * Join result code 0 --> SUCCESS
-        */
-       if (result) {
-               lbs_deb_join("ADHOC_RESP: failed (result 0x%X)\n", result);
-               if (priv->connect_status == LBS_CONNECTED)
-                       lbs_mac_event_disconnected(priv);
-               ret = -1;
-               goto done;
-       }
-
-       /* Send a Media Connected event, according to the Spec */
-       priv->connect_status = LBS_CONNECTED;
-
-       if (command == CMD_RET(CMD_802_11_AD_HOC_START)) {
-               /* Update the created network descriptor with the new BSSID */
-               memcpy(bss->bssid, adhoc_resp->bssid, ETH_ALEN);
-       }
-
-       /* Set the BSSID from the joined/started descriptor */
-       memcpy(&priv->curbssparams.bssid, bss->bssid, ETH_ALEN);
-
-       /* Set the new SSID to current SSID */
-       memcpy(&priv->curbssparams.ssid, &bss->ssid, IW_ESSID_MAX_SIZE);
-       priv->curbssparams.ssid_len = bss->ssid_len;
-
-       netif_carrier_on(priv->dev);
-       if (!priv->tx_pending_len)
-               netif_wake_queue(priv->dev);
-
-       memset(&wrqu, 0, sizeof(wrqu));
-       memcpy(wrqu.ap_addr.sa_data, priv->curbssparams.bssid, ETH_ALEN);
-       wrqu.ap_addr.sa_family = ARPHRD_ETHER;
-       wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
-
-       lbs_deb_join("ADHOC_RESP: Joined/started '%s', BSSID %pM, channel %d\n",
-                    print_ssid(ssid, bss->ssid, bss->ssid_len),
-                    priv->curbssparams.bssid,
-                    priv->curbssparams.channel);
-
-done:
-       lbs_deb_leave_args(LBS_DEB_JOIN, "ret %d", ret);
-       return ret;
-}
-
index 8b7336dd02a3339d3efb3ba0bdd6800fff5d35cd..6e765e9f91a38ec47bc7e256d2d54d6a5dd6916c 100644 (file)
@@ -8,22 +8,9 @@
 void lbs_association_worker(struct work_struct *work);
 struct assoc_request *lbs_get_association_request(struct lbs_private *priv);
 
-struct cmd_ds_command;
-int lbs_cmd_80211_authenticate(struct lbs_private *priv,
-                                       struct cmd_ds_command *cmd,
-                                       void *pdata_buf);
-
 int lbs_adhoc_stop(struct lbs_private *priv);
 
 int lbs_cmd_80211_deauthenticate(struct lbs_private *priv,
                                 u8 bssid[ETH_ALEN], u16 reason);
-int lbs_cmd_80211_associate(struct lbs_private *priv,
-                                    struct cmd_ds_command *cmd,
-                                    void *pdata_buf);
-
-int lbs_ret_80211_ad_hoc_start(struct lbs_private *priv,
-                                       struct cmd_ds_command *resp);
-int lbs_ret_80211_associate(struct lbs_private *priv,
-                                    struct cmd_ds_command *resp);
 
 #endif /* _LBS_ASSOC_H */
index 8c3605cdc64c090de61dd4fdd98e3cb23b9c4d6a..01db705a38ec6da97629512949cec0b584c11b64 100644 (file)
@@ -119,6 +119,19 @@ int lbs_update_hw_spec(struct lbs_private *priv)
        lbs_deb_cmd("GET_HW_SPEC: hardware interface 0x%x, hardware spec 0x%04x\n",
                    cmd.hwifversion, cmd.version);
 
+       /* Determine mesh_fw_ver from fwrelease and fwcapinfo */
+       /* 5.0.16p0 9.0.0.p0 is known to NOT support any mesh */
+       /* 5.110.22 have mesh command with 0xa3 command id */
+       /* 10.0.0.p0 FW brings in mesh config command with different id */
+       /* Check FW version MSB and initialize mesh_fw_ver */
+       if (MRVL_FW_MAJOR_REV(priv->fwrelease) == MRVL_FW_V5)
+               priv->mesh_fw_ver = MESH_FW_OLD;
+       else if ((MRVL_FW_MAJOR_REV(priv->fwrelease) >= MRVL_FW_V10) &&
+               (priv->fwcapinfo & MESH_CAPINFO_ENABLE_MASK))
+               priv->mesh_fw_ver = MESH_FW_NEW;
+       else
+               priv->mesh_fw_ver = MESH_NONE;
+
        /* Clamp region code to 8-bit since FW spec indicates that it should
         * only ever be 8-bit, even though the field size is 16-bit.  Some firmware
         * returns non-zero high 8 bits here.
@@ -1036,17 +1049,26 @@ static int __lbs_mesh_config_send(struct lbs_private *priv,
                                  uint16_t action, uint16_t type)
 {
        int ret;
+       u16 command = CMD_MESH_CONFIG_OLD;
 
        lbs_deb_enter(LBS_DEB_CMD);
 
-       cmd->hdr.command = cpu_to_le16(CMD_MESH_CONFIG);
+       /*
+        * Command id is 0xac for v10 FW along with mesh interface
+        * id in bits 14-13-12.
+        */
+       if (priv->mesh_fw_ver == MESH_FW_NEW)
+               command = CMD_MESH_CONFIG |
+                         (MESH_IFACE_ID << MESH_IFACE_BIT_OFFSET);
+
+       cmd->hdr.command = cpu_to_le16(command);
        cmd->hdr.size = cpu_to_le16(sizeof(struct cmd_ds_mesh_config));
        cmd->hdr.result = 0;
 
        cmd->type = cpu_to_le16(type);
        cmd->action = cpu_to_le16(action);
 
-       ret = lbs_cmd_with_response(priv, CMD_MESH_CONFIG, cmd);
+       ret = lbs_cmd_with_response(priv, command, cmd);
 
        lbs_deb_leave(LBS_DEB_CMD);
        return ret;
@@ -1198,8 +1220,7 @@ static void lbs_submit_command(struct lbs_private *priv,
        command = le16_to_cpu(cmd->command);
 
        /* These commands take longer */
-       if (command == CMD_802_11_SCAN || command == CMD_802_11_ASSOCIATE ||
-           command == CMD_802_11_AUTHENTICATE)
+       if (command == CMD_802_11_SCAN || command == CMD_802_11_ASSOCIATE)
                timeo = 5 * HZ;
 
        lbs_deb_cmd("DNLD_CMD: command 0x%04x, seq %d, size %d\n",
@@ -1393,15 +1414,6 @@ int lbs_prepare_and_send_command(struct lbs_private *priv,
                ret = lbs_cmd_802_11_ps_mode(cmdptr, cmd_action);
                break;
 
-       case CMD_802_11_ASSOCIATE:
-       case CMD_802_11_REASSOCIATE:
-               ret = lbs_cmd_80211_associate(priv, cmdptr, pdata_buf);
-               break;
-
-       case CMD_802_11_AUTHENTICATE:
-               ret = lbs_cmd_80211_authenticate(priv, cmdptr, pdata_buf);
-               break;
-
        case CMD_MAC_REG_ACCESS:
        case CMD_BBP_REG_ACCESS:
        case CMD_RF_REG_ACCESS:
@@ -1448,8 +1460,8 @@ int lbs_prepare_and_send_command(struct lbs_private *priv,
                break;
        case CMD_802_11_LED_GPIO_CTRL:
                {
-                       struct mrvlietypes_ledgpio *gpio =
-                           (struct mrvlietypes_ledgpio*)
+                       struct mrvl_ie_ledgpio *gpio =
+                           (struct mrvl_ie_ledgpio*)
                            cmdptr->params.ledgpio.data;
 
                        memmove(&cmdptr->params.ledgpio,
index bcf2a9756fb6942660ab647ac466494d481980aa..c42d3faa2660208c556cc66adabff7071b206782 100644 (file)
@@ -5,7 +5,7 @@
 #include <linux/delay.h>
 #include <linux/if_arp.h>
 #include <linux/netdevice.h>
-
+#include <asm/unaligned.h>
 #include <net/iw_handler.h>
 
 #include "host.h"
@@ -154,11 +154,11 @@ static int lbs_ret_802_11_rssi(struct lbs_private *priv,
        lbs_deb_enter(LBS_DEB_CMD);
 
        /* store the non average value */
-       priv->SNR[TYPE_BEACON][TYPE_NOAVG] = le16_to_cpu(rssirsp->SNR);
-       priv->NF[TYPE_BEACON][TYPE_NOAVG] = le16_to_cpu(rssirsp->noisefloor);
+       priv->SNR[TYPE_BEACON][TYPE_NOAVG] = get_unaligned_le16(&rssirsp->SNR);
+       priv->NF[TYPE_BEACON][TYPE_NOAVG] = get_unaligned_le16(&rssirsp->noisefloor);
 
-       priv->SNR[TYPE_BEACON][TYPE_AVG] = le16_to_cpu(rssirsp->avgSNR);
-       priv->NF[TYPE_BEACON][TYPE_AVG] = le16_to_cpu(rssirsp->avgnoisefloor);
+       priv->SNR[TYPE_BEACON][TYPE_AVG] = get_unaligned_le16(&rssirsp->avgSNR);
+       priv->NF[TYPE_BEACON][TYPE_AVG] = get_unaligned_le16(&rssirsp->avgnoisefloor);
 
        priv->RSSI[TYPE_BEACON][TYPE_NOAVG] =
            CAL_RSSI(priv->SNR[TYPE_BEACON][TYPE_NOAVG],
@@ -210,12 +210,6 @@ static inline int handle_cmd_response(struct lbs_private *priv,
                ret = lbs_ret_reg_access(priv, respcmd, resp);
                break;
 
-       case CMD_RET_802_11_ASSOCIATE:
-       case CMD_RET(CMD_802_11_ASSOCIATE):
-       case CMD_RET(CMD_802_11_REASSOCIATE):
-               ret = lbs_ret_80211_associate(priv, resp);
-               break;
-
        case CMD_RET(CMD_802_11_SET_AFC):
        case CMD_RET(CMD_802_11_GET_AFC):
                spin_lock_irqsave(&priv->driver_lock, flags);
@@ -225,7 +219,6 @@ static inline int handle_cmd_response(struct lbs_private *priv,
 
                break;
 
-       case CMD_RET(CMD_802_11_AUTHENTICATE):
        case CMD_RET(CMD_802_11_BEACON_STOP):
                break;
 
index 50e28a0cdfeeb0fc60397a146a14c2edad97f1f9..811ffc3ef414b063ee78ad594bfa5056fc64ab6a 100644 (file)
@@ -183,12 +183,12 @@ out_unlock:
  */
 static void *lbs_tlv_find(uint16_t tlv_type, const uint8_t *tlv, uint16_t size)
 {
-       struct mrvlietypesheader *tlv_h;
+       struct mrvl_ie_header *tlv_h;
        uint16_t length;
        ssize_t pos = 0;
 
        while (pos < size) {
-               tlv_h = (struct mrvlietypesheader *) tlv;
+               tlv_h = (struct mrvl_ie_header *) tlv;
                if (!tlv_h->len)
                        return NULL;
                if (tlv_h->type == cpu_to_le16(tlv_type))
@@ -206,7 +206,7 @@ static ssize_t lbs_threshold_read(uint16_t tlv_type, uint16_t event_mask,
                                  size_t count, loff_t *ppos)
 {
        struct cmd_ds_802_11_subscribe_event *subscribed;
-       struct mrvlietypes_thresholds *got;
+       struct mrvl_ie_thresholds *got;
        struct lbs_private *priv = file->private_data;
        ssize_t ret = 0;
        size_t pos = 0;
@@ -259,7 +259,7 @@ static ssize_t lbs_threshold_write(uint16_t tlv_type, uint16_t event_mask,
                                   loff_t *ppos)
 {
        struct cmd_ds_802_11_subscribe_event *events;
-       struct mrvlietypes_thresholds *tlv;
+       struct mrvl_ie_thresholds *tlv;
        struct lbs_private *priv = file->private_data;
        ssize_t buf_size;
        int value, freq, new_mask;
index e8dfde39abfc1ccedf841bfb6b5783c730e229f2..48da157d6cdab3141ad95c3a2ae842ae3c2cae74 100644 (file)
@@ -227,6 +227,20 @@ static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, in
 #define TxPD_CONTROL_WDS_FRAME (1<<17)
 #define TxPD_MESH_FRAME TxPD_CONTROL_WDS_FRAME
 
+/** Mesh interface ID */
+#define MESH_IFACE_ID                                  0x0001
+/** Mesh id should be in bits 14-13-12 */
+#define MESH_IFACE_BIT_OFFSET                          0x000c
+/** Mesh enable bit in FW capability */
+#define MESH_CAPINFO_ENABLE_MASK                       (1<<16)
+
+/** FW definition from Marvell v5 */
+#define MRVL_FW_V5                                     (0x05)
+/** FW definition from Marvell v10 */
+#define MRVL_FW_V10                                    (0x0a)
+/** FW major revision definition */
+#define MRVL_FW_MAJOR_REV(x)                           ((x)>>24)
+
 /** RxPD status */
 
 #define MRVDRV_RXPD_STATUS_OK                0x0001
@@ -380,6 +394,13 @@ enum KEY_INFO_WPA {
        KEY_INFO_WPA_ENABLED = 0x04
 };
 
+/** mesh_fw_ver */
+enum _mesh_fw_ver {
+       MESH_NONE = 0, /* MESH is not supported */
+       MESH_FW_OLD,   /* MESH is supported in FW V5 */
+       MESH_FW_NEW,   /* MESH is supported in FW V10 and newer */
+};
+
 /* Default values for fwt commands. */
 #define FWT_DEFAULT_METRIC 0
 #define FWT_DEFAULT_DIR 1
index 27e81fd97c949c66ad93cb59784be75e7a6342ef..f9ec69e047340578a82f0967ced3f84d8a6512c2 100644 (file)
@@ -101,6 +101,7 @@ struct lbs_mesh_stats {
 /** Private structure for the MV device */
 struct lbs_private {
        int mesh_open;
+       int mesh_fw_ver;
        int infra_open;
        int mesh_autostart_enabled;
 
@@ -337,7 +338,7 @@ struct bss_descriptor {
        u32 rssi;
        u32 channel;
        u16 beaconperiod;
-       u32 atimwindow;
+       __le16 atimwindow;
 
        /* IW_MODE_AUTO, IW_MODE_ADHOC, IW_MODE_INFRA */
        u8 mode;
@@ -347,10 +348,10 @@ struct bss_descriptor {
 
        unsigned long last_scanned;
 
-       union ieeetypes_phyparamset phyparamset;
-       union IEEEtypes_ssparamset ssparamset;
+       union ieee_phy_param_set phy;
+       union ieee_ss_param_set ss;
 
-       struct ieeetypes_countryinfofullset countryinfo;
+       struct ieee_ie_country_info_full_set countryinfo;
 
        u8 wpa_ie[MAX_WPA_IE_LEN];
        size_t wpa_ie_len;
index d4457ef808a647c8c174de7d015b27ec01622127..fe8f0cb737bcf80740e83c45608de3eb0e1df72e 100644 (file)
 #define CMD_FWT_ACCESS                         0x0095
 #define CMD_802_11_MONITOR_MODE                        0x0098
 #define CMD_MESH_ACCESS                                0x009b
-#define CMD_MESH_CONFIG                                0x00a3
+#define CMD_MESH_CONFIG_OLD                    0x00a3
+#define CMD_MESH_CONFIG                                0x00ac
 #define        CMD_SET_BOOT2_VER                       0x00a5
+#define        CMD_FUNC_INIT                           0x00a9
+#define        CMD_FUNC_SHUTDOWN                       0x00aa
 #define CMD_802_11_BEACON_CTRL                 0x00b0
 
 /* For the IEEE Power Save */
index a899aeb676bbbeb744dadb0bc313fe427611fd86..0a2e29140addb5ba9375259573912f22cc34e054 100644 (file)
 
 /* TxPD descriptor */
 struct txpd {
-       /* Current Tx packet status */
-       __le32 tx_status;
+       /* union to cope up with later FW revisions */
+       union {
+               /* Current Tx packet status */
+               __le32 tx_status;
+               struct {
+                       /* BSS type: client, AP, etc. */
+                       u8 bss_type;
+                       /* BSS number */
+                       u8 bss_num;
+                       /* Reserved */
+                       __le16 reserved;
+               } bss;
+       } u;
        /* Tx control */
        __le32 tx_control;
        __le32 tx_packet_location;
@@ -36,8 +47,17 @@ struct txpd {
 
 /* RxPD Descriptor */
 struct rxpd {
-       /* Current Rx packet status */
-       __le16 status;
+       /* union to cope up with later FW revisions */
+       union {
+               /* Current Rx packet status */
+               __le16 status;
+               struct {
+                       /* BSS type: client, AP, etc. */
+                       u8 bss_type;
+                       /* BSS number */
+                       u8 bss_num;
+               } bss;
+       } u;
 
        /* SNR */
        u8 snr;
@@ -230,7 +250,9 @@ struct cmd_ds_gspi_bus_config {
 } __attribute__ ((packed));
 
 struct cmd_ds_802_11_authenticate {
-       u8 macaddr[ETH_ALEN];
+       struct cmd_header hdr;
+
+       u8 bssid[ETH_ALEN];
        u8 authtype;
        u8 reserved[10];
 } __attribute__ ((packed));
@@ -243,22 +265,23 @@ struct cmd_ds_802_11_deauthenticate {
 } __attribute__ ((packed));
 
 struct cmd_ds_802_11_associate {
-       u8 peerstaaddr[6];
+       struct cmd_header hdr;
+
+       u8 bssid[6];
        __le16 capability;
        __le16 listeninterval;
        __le16 bcnperiod;
        u8 dtimperiod;
-
-#if 0
-       mrvlietypes_ssidparamset_t ssidParamSet;
-       mrvlietypes_phyparamset_t phyparamset;
-       mrvlietypes_ssparamset_t ssparamset;
-       mrvlietypes_ratesparamset_t ratesParamSet;
-#endif
+       u8 iebuf[512];    /* Enough for required and most optional IEs */
 } __attribute__ ((packed));
 
-struct cmd_ds_802_11_associate_rsp {
-       struct ieeetypes_assocrsp assocRsp;
+struct cmd_ds_802_11_associate_response {
+       struct cmd_header hdr;
+
+       __le16 capability;
+       __le16 statuscode;
+       __le16 aid;
+       u8 iebuf[512];
 } __attribute__ ((packed));
 
 struct cmd_ds_802_11_set_wep {
@@ -515,9 +538,11 @@ struct cmd_ds_802_11_ad_hoc_start {
        u8 bsstype;
        __le16 beaconperiod;
        u8 dtimperiod;   /* Reserved on v9 and later */
-       union IEEEtypes_ssparamset ssparamset;
-       union ieeetypes_phyparamset phyparamset;
-       __le16 probedelay;
+       struct ieee_ie_ibss_param_set ibss;
+       u8 reserved1[4];
+       struct ieee_ie_ds_param_set ds;
+       u8 reserved2[4];
+       __le16 probedelay;  /* Reserved on v9 and later */
        __le16 capability;
        u8 rates[MAX_RATES];
        u8 tlv_memory_size_pad[100];
@@ -538,8 +563,10 @@ struct adhoc_bssdesc {
        u8 dtimperiod;
        __le64 timestamp;
        __le64 localtime;
-       union ieeetypes_phyparamset phyparamset;
-       union IEEEtypes_ssparamset ssparamset;
+       struct ieee_ie_ds_param_set ds;
+       u8 reserved1[4];
+       struct ieee_ie_ibss_param_set ibss;
+       u8 reserved2[4];
        __le16 capability;
        u8 rates[MAX_RATES];
 
@@ -745,8 +772,6 @@ struct cmd_ds_command {
        /* command Body */
        union {
                struct cmd_ds_802_11_ps_mode psmode;
-               struct cmd_ds_802_11_associate associate;
-               struct cmd_ds_802_11_authenticate auth;
                struct cmd_ds_802_11_get_stat gstat;
                struct cmd_ds_802_3_get_stat gstat_8023;
                struct cmd_ds_802_11_rf_antenna rant;
index cedeac6322feb8063ebc921e5bd1407a93287f36..2a5b083bf9bd5824af70cd7cf3a4f60cfda02ff9 100644 (file)
@@ -273,7 +273,28 @@ static int if_cs_poll_while_fw_download(struct if_cs_card *card, uint addr, u8 r
  */
 #define IF_CS_PRODUCT_ID               0x0000001C
 #define IF_CS_CF8385_B1_REV            0x12
+#define IF_CS_CF8381_B3_REV            0x04
 
+/*
+ * Used to detect other cards than CF8385 since their revisions of silicon
+ * doesn't match those from CF8385, eg. CF8381 B3 works with this driver.
+ */
+#define CF8381_MANFID          0x02db
+#define CF8381_CARDID          0x6064
+#define CF8385_MANFID          0x02df
+#define CF8385_CARDID          0x8103
+
+static inline int if_cs_hw_is_cf8381(struct pcmcia_device *p_dev)
+{
+       return (p_dev->manf_id == CF8381_MANFID &&
+               p_dev->card_id == CF8381_CARDID);
+}
+
+static inline int if_cs_hw_is_cf8385(struct pcmcia_device *p_dev)
+{
+       return (p_dev->manf_id == CF8385_MANFID &&
+               p_dev->card_id == CF8385_CARDID);
+}
 
 /********************************************************************/
 /* I/O and interrupt handling                                       */
@@ -757,6 +778,7 @@ static void if_cs_release(struct pcmcia_device *p_dev)
 static int if_cs_probe(struct pcmcia_device *p_dev)
 {
        int ret = -ENOMEM;
+       unsigned int prod_id;
        struct lbs_private *priv;
        struct if_cs_card *card;
        /* CIS parsing */
@@ -859,7 +881,14 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
               p_dev->io.BasePort1 + p_dev->io.NumPorts1 - 1);
 
        /* Check if we have a current silicon */
-       if (if_cs_read8(card, IF_CS_PRODUCT_ID) < IF_CS_CF8385_B1_REV) {
+       prod_id = if_cs_read8(card, IF_CS_PRODUCT_ID);
+       if (if_cs_hw_is_cf8381(p_dev) && prod_id < IF_CS_CF8381_B3_REV) {
+               lbs_pr_err("old chips like 8381 rev B3 aren't supported\n");
+               ret = -ENODEV;
+               goto out2;
+       }
+
+       if (if_cs_hw_is_cf8385(p_dev) && prod_id < IF_CS_CF8385_B1_REV) {
                lbs_pr_err("old chips like 8385 rev B1 aren't supported\n");
                ret = -ENODEV;
                goto out2;
@@ -950,7 +979,8 @@ static void if_cs_detach(struct pcmcia_device *p_dev)
 /********************************************************************/
 
 static struct pcmcia_device_id if_cs_ids[] = {
-       PCMCIA_DEVICE_MANF_CARD(0x02df, 0x8103),
+       PCMCIA_DEVICE_MANF_CARD(CF8381_MANFID, CF8381_CARDID),
+       PCMCIA_DEVICE_MANF_CARD(CF8385_MANFID, CF8385_CARDID),
        PCMCIA_DEVICE_NULL,
 };
 MODULE_DEVICE_TABLE(pcmcia, if_cs_ids);
index 76f4c653d6419782caf65902ffed19b3a5153f03..8cdb88c6ca282f91c49b1cb9aeed91021dc005ab 100644 (file)
 #include "decl.h"
 #include "defs.h"
 #include "dev.h"
+#include "cmd.h"
 #include "if_sdio.h"
 
+/* 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
+ * differently for SD8688 combo chip.
+ * If the user is removing the module, the FUNC_SHUTDOWN
+ * command for SD8688 is sent to the firmware.
+ * If the card is removed, there is no need to send this command.
+ *
+ * The variable 'user_rmmod' is used to distinguish these two
+ * scenarios. This flag is initialized as FALSE in case the card
+ * is removed, and will be set to TRUE for module removal when
+ * module_exit function is called.
+ */
+static u8 user_rmmod;
+
 static char *lbs_helper_name = NULL;
 module_param_named(helper_name, lbs_helper_name, charp, 0644);
 
@@ -48,8 +64,11 @@ static char *lbs_fw_name = NULL;
 module_param_named(fw_name, lbs_fw_name, charp, 0644);
 
 static const struct sdio_device_id if_sdio_ids[] = {
-       { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_LIBERTAS) },
-       { /* end: all zeroes */                                         },
+       { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL,
+                       SDIO_DEVICE_ID_MARVELL_LIBERTAS) },
+       { SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL,
+                       SDIO_DEVICE_ID_MARVELL_8688WLAN) },
+       { /* end: all zeroes */                         },
 };
 
 MODULE_DEVICE_TABLE(sdio, if_sdio_ids);
@@ -63,16 +82,22 @@ struct if_sdio_model {
 static struct if_sdio_model if_sdio_models[] = {
        {
                /* 8385 */
-               .model = 0x04,
+               .model = IF_SDIO_MODEL_8385,
                .helper = "sd8385_helper.bin",
                .firmware = "sd8385.bin",
        },
        {
                /* 8686 */
-               .model = 0x0B,
+               .model = IF_SDIO_MODEL_8686,
                .helper = "sd8686_helper.bin",
                .firmware = "sd8686.bin",
        },
+       {
+               /* 8688 */
+               .model = IF_SDIO_MODEL_8688,
+               .helper = "sd8688_helper.bin",
+               .firmware = "sd8688.bin",
+       },
 };
 
 struct if_sdio_packet {
@@ -87,6 +112,7 @@ struct if_sdio_card {
 
        int                     model;
        unsigned long           ioport;
+       unsigned int            scratch_reg;
 
        const char              *helper;
        const char              *firmware;
@@ -98,25 +124,29 @@ struct if_sdio_card {
 
        struct workqueue_struct *workqueue;
        struct work_struct      packet_worker;
+
+       u8                      rx_unit;
 };
 
 /********************************************************************/
 /* I/O                                                              */
 /********************************************************************/
 
+/*
+ *  For SD8385/SD8686, this function reads firmware status after
+ *  the image is downloaded, or reads RX packet length when
+ *  interrupt (with IF_SDIO_H_INT_UPLD bit set) is received.
+ *  For SD8688, this function reads firmware status only.
+ */
 static u16 if_sdio_read_scratch(struct if_sdio_card *card, int *err)
 {
-       int ret, reg;
+       int ret;
        u16 scratch;
 
-       if (card->model == 0x04)
-               reg = IF_SDIO_SCRATCH_OLD;
-       else
-               reg = IF_SDIO_SCRATCH;
-
-       scratch = sdio_readb(card->func, reg, &ret);
+       scratch = sdio_readb(card->func, card->scratch_reg, &ret);
        if (!ret)
-               scratch |= sdio_readb(card->func, reg + 1, &ret) << 8;
+               scratch |= sdio_readb(card->func, card->scratch_reg + 1,
+                                       &ret) << 8;
 
        if (err)
                *err = ret;
@@ -127,6 +157,46 @@ static u16 if_sdio_read_scratch(struct if_sdio_card *card, int *err)
        return scratch;
 }
 
+static u8 if_sdio_read_rx_unit(struct if_sdio_card *card)
+{
+       int ret;
+       u8 rx_unit;
+
+       rx_unit = sdio_readb(card->func, IF_SDIO_RX_UNIT, &ret);
+
+       if (ret)
+               rx_unit = 0;
+
+       return rx_unit;
+}
+
+static u16 if_sdio_read_rx_len(struct if_sdio_card *card, int *err)
+{
+       int ret;
+       u16 rx_len;
+
+       switch (card->model) {
+       case IF_SDIO_MODEL_8385:
+       case IF_SDIO_MODEL_8686:
+               rx_len = if_sdio_read_scratch(card, &ret);
+               break;
+       case IF_SDIO_MODEL_8688:
+       default: /* for newer chipsets */
+               rx_len = sdio_readb(card->func, IF_SDIO_RX_LEN, &ret);
+               if (!ret)
+                       rx_len <<= card->rx_unit;
+               else
+                       rx_len = 0xffff;        /* invalid length */
+
+               break;
+       }
+
+       if (err)
+               *err = ret;
+
+       return rx_len;
+}
+
 static int if_sdio_handle_cmd(struct if_sdio_card *card,
                u8 *buffer, unsigned size)
 {
@@ -207,7 +277,7 @@ static int if_sdio_handle_event(struct if_sdio_card *card,
 
        lbs_deb_enter(LBS_DEB_SDIO);
 
-       if (card->model == 0x04) {
+       if (card->model == IF_SDIO_MODEL_8385) {
                event = sdio_readb(card->func, IF_SDIO_EVENT, &ret);
                if (ret)
                        goto out;
@@ -245,7 +315,7 @@ static int if_sdio_card_to_host(struct if_sdio_card *card)
 
        lbs_deb_enter(LBS_DEB_SDIO);
 
-       size = if_sdio_read_scratch(card, &ret);
+       size = if_sdio_read_rx_len(card, &ret);
        if (ret)
                goto out;
 
@@ -488,7 +558,6 @@ static int if_sdio_prog_helper(struct if_sdio_card *card)
        ret = 0;
 
 release:
-       sdio_set_block_size(card->func, 0);
        sdio_release_host(card->func);
        kfree(chunk_buffer);
 release_fw:
@@ -624,7 +693,6 @@ static int if_sdio_prog_real(struct if_sdio_card *card)
        ret = 0;
 
 release:
-       sdio_set_block_size(card->func, 0);
        sdio_release_host(card->func);
        kfree(chunk_buffer);
 release_fw:
@@ -653,6 +721,8 @@ static int if_sdio_prog_firmware(struct if_sdio_card *card)
        if (ret)
                goto out;
 
+       lbs_deb_sdio("firmware status = %#x\n", scratch);
+
        if (scratch == IF_SDIO_FIRMWARE_OK) {
                lbs_deb_sdio("firmware already loaded\n");
                goto success;
@@ -667,6 +737,9 @@ static int if_sdio_prog_firmware(struct if_sdio_card *card)
                goto out;
 
 success:
+       sdio_claim_host(card->func);
+       sdio_set_block_size(card->func, IF_SDIO_BLOCK_SIZE);
+       sdio_release_host(card->func);
        ret = 0;
 
 out:
@@ -820,10 +893,10 @@ static int if_sdio_probe(struct sdio_func *func,
                if (sscanf(func->card->info[i],
                                "ID: %x", &model) == 1)
                        break;
-               if (!strcmp(func->card->info[i], "IBIS Wireless SDIO Card")) {
-                       model = 4;
-                       break;
-               }
+               if (!strcmp(func->card->info[i], "IBIS Wireless SDIO Card")) {
+                       model = IF_SDIO_MODEL_8385;
+                       break;
+               }
        }
 
        if (i == func->card->num_info) {
@@ -837,6 +910,20 @@ static int if_sdio_probe(struct sdio_func *func,
 
        card->func = func;
        card->model = model;
+
+       switch (card->model) {
+       case IF_SDIO_MODEL_8385:
+               card->scratch_reg = IF_SDIO_SCRATCH_OLD;
+               break;
+       case IF_SDIO_MODEL_8686:
+               card->scratch_reg = IF_SDIO_SCRATCH;
+               break;
+       case IF_SDIO_MODEL_8688:
+       default: /* for newer chipsets */
+               card->scratch_reg = IF_SDIO_FW_STATUS;
+               break;
+       }
+
        spin_lock_init(&card->lock);
        card->workqueue = create_workqueue("libertas_sdio");
        INIT_WORK(&card->packet_worker, if_sdio_host_to_card_worker);
@@ -914,15 +1001,40 @@ static int if_sdio_probe(struct sdio_func *func,
 
        priv->fw_ready = 1;
 
+       sdio_claim_host(func);
+
+       /*
+        * Get rx_unit if the chip is SD8688 or newer.
+        * SD8385 & SD8686 do not have rx_unit.
+        */
+       if ((card->model != IF_SDIO_MODEL_8385)
+                       && (card->model != IF_SDIO_MODEL_8686))
+               card->rx_unit = if_sdio_read_rx_unit(card);
+       else
+               card->rx_unit = 0;
+
        /*
         * Enable interrupts now that everything is set up
         */
-       sdio_claim_host(func);
        sdio_writeb(func, 0x0f, IF_SDIO_H_INT_MASK, &ret);
        sdio_release_host(func);
        if (ret)
                goto reclaim;
 
+       /*
+        * FUNC_INIT is required for SD8688 WLAN/BT multiple functions
+        */
+       if (card->model == IF_SDIO_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))
+                       lbs_pr_alert("CMD_FUNC_INIT cmd failed\n");
+       }
+
        ret = lbs_start_card(priv);
        if (ret)
                goto err_activate_card;
@@ -968,6 +1080,22 @@ static void if_sdio_remove(struct sdio_func *func)
 
        card = sdio_get_drvdata(func);
 
+       if (user_rmmod && (card->model == IF_SDIO_MODEL_8688)) {
+               /*
+                * FUNC_SHUTDOWN is required for SD8688 WLAN/BT
+                * multiple functions
+                */
+               struct cmd_header cmd;
+
+               memset(&cmd, 0, sizeof(cmd));
+
+               lbs_deb_sdio("send function SHUTDOWN command\n");
+               if (__lbs_cmd(card->priv, CMD_FUNC_SHUTDOWN,
+                               &cmd, sizeof(cmd), lbs_cmd_copyback,
+                               (unsigned long) &cmd))
+                       lbs_pr_alert("CMD_FUNC_SHUTDOWN cmd failed\n");
+       }
+
        card->priv->surpriseremoved = 1;
 
        lbs_deb_sdio("call remove card\n");
@@ -1015,6 +1143,9 @@ static int __init if_sdio_init_module(void)
 
        ret = sdio_register_driver(&if_sdio_driver);
 
+       /* Clear the flag in case user removes the card. */
+       user_rmmod = 0;
+
        lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
 
        return ret;
@@ -1024,6 +1155,9 @@ static void __exit if_sdio_exit_module(void)
 {
        lbs_deb_enter(LBS_DEB_SDIO);
 
+       /* Set the flag as user is removing this module. */
+       user_rmmod = 1;
+
        sdio_unregister_driver(&if_sdio_driver);
 
        lbs_deb_leave(LBS_DEB_SDIO);
index 533bdfbf5d2af794570e1232e6e23a3052f9d7bc..60c9b2fcef0308ff83e633f43438b9f43fe0a3b4 100644 (file)
 #ifndef _LBS_IF_SDIO_H
 #define _LBS_IF_SDIO_H
 
+#define IF_SDIO_MODEL_8385     0x04
+#define IF_SDIO_MODEL_8686     0x0b
+#define IF_SDIO_MODEL_8688     0x10
+
 #define IF_SDIO_IOPORT         0x00
 
 #define IF_SDIO_H_INT_MASK     0x04
 
 #define IF_SDIO_SCRATCH                0x34
 #define IF_SDIO_SCRATCH_OLD    0x80fe
+#define IF_SDIO_FW_STATUS      0x40
 #define   IF_SDIO_FIRMWARE_OK  0xfedc
 
+#define IF_SDIO_RX_LEN         0x42
+#define IF_SDIO_RX_UNIT                0x43
+
 #define IF_SDIO_EVENT           0x80fc
 
+#define IF_SDIO_BLOCK_SIZE     256
+
 #endif
index 07311e71af926cad9d80156c700d4810b2cc713a..f8c2898d82b05b305e69c566e52e8291b5118348 100644 (file)
@@ -19,7 +19,6 @@
 
 #include <linux/moduleparam.h>
 #include <linux/firmware.h>
-#include <linux/gpio.h>
 #include <linux/jiffies.h>
 #include <linux/kthread.h>
 #include <linux/list.h>
@@ -51,13 +50,6 @@ struct if_spi_card {
        u16                             card_id;
        u8                              card_rev;
 
-       /* Pin number for our GPIO chip-select. */
-       /* TODO: Once the generic SPI layer has some additional features, we
-        * should take this out and use the normal chip select here.
-        * We need support for chip select delays, and not dropping chipselect
-        * after each word. */
-       int                             gpio_cs;
-
        /* The last time that we initiated an SPU operation */
        unsigned long                   prev_xfer_time;
 
@@ -119,9 +111,6 @@ static struct chip_ident chip_id_to_device_name[] = {
  * First we have to put a SPU register name on the bus. Then we can
  * either read from or write to that register.
  *
- * For 16-bit transactions, byte order on the bus is big-endian.
- * We don't have to worry about that here, though.
- * The translation takes place in the SPI routines.
  */
 
 static void spu_transaction_init(struct if_spi_card *card)
@@ -133,12 +122,10 @@ static void spu_transaction_init(struct if_spi_card *card)
                 * If not, we have to busy-wait to be on the safe side. */
                ndelay(400);
        }
-       gpio_set_value(card->gpio_cs, 0); /* assert CS */
 }
 
 static void spu_transaction_finish(struct if_spi_card *card)
 {
-       gpio_set_value(card->gpio_cs, 1); /* drop CS */
        card->prev_xfer_time = jiffies;
 }
 
@@ -147,7 +134,14 @@ static void spu_transaction_finish(struct if_spi_card *card)
 static int spu_write(struct if_spi_card *card, u16 reg, const u8 *buf, int len)
 {
        int err = 0;
-       u16 reg_out = reg | IF_SPI_WRITE_OPERATION_MASK;
+       u16 reg_out = cpu_to_le16(reg | IF_SPI_WRITE_OPERATION_MASK);
+       struct spi_message m;
+       struct spi_transfer reg_trans;
+       struct spi_transfer data_trans;
+
+       spi_message_init(&m);
+       memset(&reg_trans, 0, sizeof(reg_trans));
+       memset(&data_trans, 0, sizeof(data_trans));
 
        /* You must give an even number of bytes to the SPU, even if it
         * doesn't care about the last one.  */
@@ -156,29 +150,26 @@ static int spu_write(struct if_spi_card *card, u16 reg, const u8 *buf, int len)
        spu_transaction_init(card);
 
        /* write SPU register index */
-       err = spi_write(card->spi, (u8 *)&reg_out, sizeof(u16));
-       if (err)
-               goto out;
+       reg_trans.tx_buf = &reg_out;
+       reg_trans.len = sizeof(reg_out);
 
-       err = spi_write(card->spi, buf, len);
+       data_trans.tx_buf = buf;
+       data_trans.len = len;
 
-out:
+       spi_message_add_tail(&reg_trans, &m);
+       spi_message_add_tail(&data_trans, &m);
+
+       err = spi_sync(card->spi, &m);
        spu_transaction_finish(card);
        return err;
 }
 
 static inline int spu_write_u16(struct if_spi_card *card, u16 reg, u16 val)
 {
-       return spu_write(card, reg, (u8 *)&val, sizeof(u16));
-}
+       u16 buff;
 
-static inline int spu_write_u32(struct if_spi_card *card, u16 reg, u32 val)
-{
-       /* The lower 16 bits are written first. */
-       u16 out[2];
-       out[0] = val & 0xffff;
-       out[1] = (val & 0xffff0000) >> 16;
-       return spu_write(card, reg, (u8 *)&out, sizeof(u32));
+       buff = cpu_to_le16(val);
+       return spu_write(card, reg, (u8 *)&buff, sizeof(u16));
 }
 
 static inline int spu_reg_is_port_reg(u16 reg)
@@ -195,10 +186,13 @@ static inline int spu_reg_is_port_reg(u16 reg)
 
 static int spu_read(struct if_spi_card *card, u16 reg, u8 *buf, int len)
 {
-       unsigned int i, delay;
+       unsigned int delay;
        int err = 0;
-       u16 zero = 0;
-       u16 reg_out = reg | IF_SPI_READ_OPERATION_MASK;
+       u16 reg_out = cpu_to_le16(reg | IF_SPI_READ_OPERATION_MASK);
+       struct spi_message m;
+       struct spi_transfer reg_trans;
+       struct spi_transfer dummy_trans;
+       struct spi_transfer data_trans;
 
        /* You must take an even number of bytes from the SPU, even if you
         * don't care about the last one.  */
@@ -206,29 +200,34 @@ static int spu_read(struct if_spi_card *card, u16 reg, u8 *buf, int len)
 
        spu_transaction_init(card);
 
+       spi_message_init(&m);
+       memset(&reg_trans, 0, sizeof(reg_trans));
+       memset(&dummy_trans, 0, sizeof(dummy_trans));
+       memset(&data_trans, 0, sizeof(data_trans));
+
        /* write SPU register index */
-       err = spi_write(card->spi, (u8 *)&reg_out, sizeof(u16));
-       if (err)
-               goto out;
+       reg_trans.tx_buf = &reg_out;
+       reg_trans.len = sizeof(reg_out);
+       spi_message_add_tail(&reg_trans, &m);
 
        delay = spu_reg_is_port_reg(reg) ? card->spu_port_delay :
                                                card->spu_reg_delay;
        if (card->use_dummy_writes) {
                /* Clock in dummy cycles while the SPU fills the FIFO */
-               for (i = 0; i < delay / 16; ++i) {
-                       err = spi_write(card->spi, (u8 *)&zero, sizeof(u16));
-                       if (err)
-                               return err;
-               }
+               dummy_trans.len = delay / 8;
+               spi_message_add_tail(&dummy_trans, &m);
        } else {
                /* Busy-wait while the SPU fills the FIFO */
-               ndelay(100 + (delay * 10));
+               reg_trans.delay_usecs =
+                       DIV_ROUND_UP((100 + (delay * 10)), 1000);
        }
 
        /* read in data */
-       err = spi_read(card->spi, buf, len);
+       data_trans.rx_buf = buf;
+       data_trans.len = len;
+       spi_message_add_tail(&data_trans, &m);
 
-out:
+       err = spi_sync(card->spi, &m);
        spu_transaction_finish(card);
        return err;
 }
@@ -236,18 +235,25 @@ out:
 /* Read 16 bits from an SPI register */
 static inline int spu_read_u16(struct if_spi_card *card, u16 reg, u16 *val)
 {
-       return spu_read(card, reg, (u8 *)val, sizeof(u16));
+       u16 buf;
+       int ret;
+
+       ret = spu_read(card, reg, (u8 *)&buf, sizeof(buf));
+       if (ret == 0)
+               *val = le16_to_cpup(&buf);
+       return ret;
 }
 
 /* Read 32 bits from an SPI register.
  * The low 16 bits are read first. */
 static int spu_read_u32(struct if_spi_card *card, u16 reg, u32 *val)
 {
-       u16 buf[2];
+       u32 buf;
        int err;
-       err = spu_read(card, reg, (u8 *)buf, sizeof(u32));
+
+       err = spu_read(card, reg, (u8 *)&buf, sizeof(buf));
        if (!err)
-               *val = buf[0] | (buf[1] << 16);
+               *val = le32_to_cpup(&buf);
        return err;
 }
 
@@ -731,7 +737,7 @@ static int if_spi_c2h_data(struct if_spi_card *card)
                goto out;
        } else if (len > MRVDRV_ETH_RX_PACKET_BUFFER_SIZE) {
                lbs_pr_err("%s: error: card has %d bytes of data, but "
-                          "our maximum skb size is %u\n",
+                          "our maximum skb size is %lu\n",
                           __func__, len, MRVDRV_ETH_RX_PACKET_BUFFER_SIZE);
                err = -EINVAL;
                goto out;
@@ -814,6 +820,13 @@ static void if_spi_e2h(struct if_spi_card *card)
        if (err)
                goto out;
 
+       /* re-enable the card event interrupt */
+       spu_write_u16(card, IF_SPI_HOST_INT_STATUS_REG,
+                       ~IF_SPI_HICU_CARD_EVENT);
+
+       /* generate a card interrupt */
+       spu_write_u16(card, IF_SPI_CARD_INT_CAUSE_REG, IF_SPI_CIC_HOST_EVENT);
+
        spin_lock_irqsave(&priv->driver_lock, flags);
        lbs_queue_event(priv, cause & 0xff);
        spin_unlock_irqrestore(&priv->driver_lock, flags);
@@ -1020,6 +1033,7 @@ static int __devinit if_spi_probe(struct spi_device *spi)
        struct libertas_spi_platform_data *pdata = spi->dev.platform_data;
        int err = 0;
        u32 scratch;
+       struct sched_param param = { .sched_priority = 1 };
 
        lbs_deb_enter(LBS_DEB_SPI);
 
@@ -1043,7 +1057,6 @@ static int __devinit if_spi_probe(struct spi_device *spi)
        spi_set_drvdata(spi, card);
        card->pdata = pdata;
        card->spi = spi;
-       card->gpio_cs = pdata->gpio_cs;
        card->prev_xfer_time = jiffies;
 
        sema_init(&card->spi_ready, 0);
@@ -1052,26 +1065,18 @@ static int __devinit if_spi_probe(struct spi_device *spi)
        INIT_LIST_HEAD(&card->data_packet_list);
        spin_lock_init(&card->buffer_lock);
 
-       /* set up GPIO CS line. TODO: use  regular CS line */
-       err = gpio_request(card->gpio_cs, "if_spi_gpio_chip_select");
-       if (err)
-               goto free_card;
-       err = gpio_direction_output(card->gpio_cs, 1);
-       if (err)
-               goto free_gpio;
-
        /* Initialize the SPI Interface Unit */
        err = spu_init(card, pdata->use_dummy_writes);
        if (err)
-               goto free_gpio;
+               goto free_card;
        err = spu_get_chip_revision(card, &card->card_id, &card->card_rev);
        if (err)
-               goto free_gpio;
+               goto free_card;
 
        /* Firmware load */
        err = spu_read_u32(card, IF_SPI_SCRATCH_4_REG, &scratch);
        if (err)
-               goto free_gpio;
+               goto free_card;
        if (scratch == SUCCESSFUL_FW_DOWNLOAD_MAGIC)
                lbs_deb_spi("Firmware is already loaded for "
                            "Marvell WLAN 802.11 adapter\n");
@@ -1079,7 +1084,7 @@ static int __devinit if_spi_probe(struct spi_device *spi)
                err = if_spi_calculate_fw_names(card->card_id,
                                card->helper_fw_name, card->main_fw_name);
                if (err)
-                       goto free_gpio;
+                       goto free_card;
 
                lbs_deb_spi("Initializing FW for Marvell WLAN 802.11 adapter "
                                "(chip_id = 0x%04x, chip_rev = 0x%02x) "
@@ -1090,23 +1095,23 @@ static int __devinit if_spi_probe(struct spi_device *spi)
                                spi->max_speed_hz);
                err = if_spi_prog_helper_firmware(card);
                if (err)
-                       goto free_gpio;
+                       goto free_card;
                err = if_spi_prog_main_firmware(card);
                if (err)
-                       goto free_gpio;
+                       goto free_card;
                lbs_deb_spi("loaded FW for Marvell WLAN 802.11 adapter\n");
        }
 
        err = spu_set_interrupt_mode(card, 0, 1);
        if (err)
-               goto free_gpio;
+               goto free_card;
 
        /* Register our card with libertas.
         * This will call alloc_etherdev */
        priv = lbs_add_card(card, &spi->dev);
        if (!priv) {
                err = -ENOMEM;
-               goto free_gpio;
+               goto free_card;
        }
        card->priv = priv;
        priv->card = card;
@@ -1123,6 +1128,9 @@ static int __devinit if_spi_probe(struct spi_device *spi)
                lbs_pr_err("error creating SPI thread: err=%d\n", err);
                goto remove_card;
        }
+       if (sched_setscheduler(card->spi_thread, SCHED_FIFO, &param))
+               lbs_pr_err("Error setting scheduler, using default.\n");
+
        err = request_irq(spi->irq, if_spi_host_interrupt,
                        IRQF_TRIGGER_FALLING, "libertas_spi", card);
        if (err) {
@@ -1148,8 +1156,6 @@ terminate_thread:
        if_spi_terminate_spi_thread(card);
 remove_card:
        lbs_remove_card(priv); /* will call free_netdev */
-free_gpio:
-       gpio_free(card->gpio_cs);
 free_card:
        free_if_spi_card(card);
 out:
@@ -1170,7 +1176,6 @@ static int __devexit libertas_spi_remove(struct spi_device *spi)
        free_irq(spi->irq, card);
        if_spi_terminate_spi_thread(card);
        lbs_remove_card(priv); /* will call free_netdev */
-       gpio_free(card->gpio_cs);
        if (card->pdata->teardown)
                card->pdata->teardown(spi);
        free_if_spi_card(card);
index ea3dc038be76e3c88d89abb9e75328b993501b77..d649caebf08a1e93ffd9a136f7682340fe380f33 100644 (file)
@@ -686,8 +686,7 @@ static inline void process_cmdrequest(int recvlength, uint8_t *recvbuff,
                return;
        }
 
-       if (!in_interrupt())
-               BUG();
+       BUG_ON(!in_interrupt());
 
        spin_lock(&priv->driver_lock);
 
index 8ae935ac32f177ea990c67cb547eb231afa3aeb6..89575e448015d38884e76083d3d508cd9228b4b2 100644 (file)
@@ -1307,8 +1307,10 @@ int lbs_start_card(struct lbs_private *priv)
 
        lbs_update_channel(priv);
 
-       /* 5.0.16p0 is known to NOT support any mesh */
-       if (priv->fwrelease > 0x05001000) {
+       /* Check mesh FW version and appropriately send the mesh start
+        * command
+        */
+       if (priv->mesh_fw_ver == MESH_FW_OLD) {
                /* Enable mesh, if supported, and work out which TLV it uses.
                   0x100 + 291 is an unofficial value used in 5.110.20.pXX
                   0x100 + 37 is the official value used in 5.110.21.pXX
@@ -1322,27 +1324,35 @@ int lbs_start_card(struct lbs_private *priv)
                   It's just that 5.110.20.pXX will not have done anything
                   useful */
 
-               priv->mesh_tlv = 0x100 + 291;
+               priv->mesh_tlv = TLV_TYPE_OLD_MESH_ID;
                if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START,
                                    priv->curbssparams.channel)) {
-                       priv->mesh_tlv = 0x100 + 37;
+                       priv->mesh_tlv = TLV_TYPE_MESH_ID;
                        if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START,
                                            priv->curbssparams.channel))
                                priv->mesh_tlv = 0;
                }
-               if (priv->mesh_tlv) {
-                       lbs_add_mesh(priv);
-
-                       if (device_create_file(&dev->dev, &dev_attr_lbs_mesh))
-                               lbs_pr_err("cannot register lbs_mesh attribute\n");
-
-                       /* While rtap isn't related to mesh, only mesh-enabled
-                        * firmware implements the rtap functionality via
-                        * CMD_802_11_MONITOR_MODE.
-                        */
-                       if (device_create_file(&dev->dev, &dev_attr_lbs_rtap))
-                               lbs_pr_err("cannot register lbs_rtap attribute\n");
-               }
+       } else if (priv->mesh_fw_ver == MESH_FW_NEW) {
+               /* 10.0.0.pXX new firmwares should succeed with TLV
+                * 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->curbssparams.channel))
+                       priv->mesh_tlv = 0;
+       }
+       if (priv->mesh_tlv) {
+               lbs_add_mesh(priv);
+
+               if (device_create_file(&dev->dev, &dev_attr_lbs_mesh))
+                       lbs_pr_err("cannot register lbs_mesh attribute\n");
+
+               /* While rtap isn't related to mesh, only mesh-enabled
+                * firmware implements the rtap functionality via
+                * CMD_802_11_MONITOR_MODE.
+                */
+               if (device_create_file(&dev->dev, &dev_attr_lbs_rtap))
+                       lbs_pr_err("cannot register lbs_rtap attribute\n");
        }
 
        lbs_debugfs_init_one(priv, dev);
index 8e669775cb5d8d822fee69ca8dc73afbe162d4b5..65f02cc6752fe05bbf0b81da42f22024fd13d149 100644 (file)
@@ -25,7 +25,6 @@ struct rfc1042hdr {
 } __attribute__ ((packed));
 
 struct rxpackethdr {
-       struct rxpd rx_pd;
        struct eth803hdr eth803_hdr;
        struct rfc1042hdr rfc1042_hdr;
 } __attribute__ ((packed));
@@ -158,10 +157,18 @@ int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb)
        if (priv->monitormode)
                return process_rxed_802_11_packet(priv, skb);
 
-       p_rx_pkt = (struct rxpackethdr *) skb->data;
-       p_rx_pd = &p_rx_pkt->rx_pd;
-       if (priv->mesh_dev && (p_rx_pd->rx_control & RxPD_MESH_FRAME))
-               dev = priv->mesh_dev;
+       p_rx_pd = (struct rxpd *) skb->data;
+       p_rx_pkt = (struct rxpackethdr *) ((u8 *)p_rx_pd +
+               le32_to_cpu(p_rx_pd->pkt_ptr));
+       if (priv->mesh_dev) {
+               if (priv->mesh_fw_ver == MESH_FW_OLD) {
+                       if (p_rx_pd->rx_control & RxPD_MESH_FRAME)
+                               dev = priv->mesh_dev;
+               } else if (priv->mesh_fw_ver == MESH_FW_NEW) {
+                       if (p_rx_pd->u.bss.bss_num == MESH_IFACE_ID)
+                               dev = priv->mesh_dev;
+               }
+       }
 
        lbs_deb_hex(LBS_DEB_RX, "RX Data: Before chop rxpd", skb->data,
                 min_t(unsigned int, skb->len, 100));
@@ -174,20 +181,9 @@ int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb)
                goto done;
        }
 
-       /*
-        * Check rxpd status and update 802.3 stat,
-        */
-       if (!(p_rx_pd->status & cpu_to_le16(MRVDRV_RXPD_STATUS_OK))) {
-               lbs_deb_rx("rx err: frame received with bad status\n");
-               lbs_pr_alert("rxpd not ok\n");
-               dev->stats.rx_errors++;
-               ret = 0;
-               dev_kfree_skb(skb);
-               goto done;
-       }
-
-       lbs_deb_rx("rx data: skb->len-sizeof(RxPd) = %d-%zd = %zd\n",
-              skb->len, sizeof(struct rxpd), skb->len - sizeof(struct rxpd));
+       lbs_deb_rx("rx data: skb->len - pkt_ptr = %d-%zd = %zd\n",
+               skb->len, (size_t)le32_to_cpu(p_rx_pd->pkt_ptr),
+               skb->len - (size_t)le32_to_cpu(p_rx_pd->pkt_ptr));
 
        lbs_deb_hex(LBS_DEB_RX, "RX Data: Dest", p_rx_pkt->eth803_hdr.dest_addr,
                sizeof(p_rx_pkt->eth803_hdr.dest_addr));
@@ -221,14 +217,14 @@ int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb)
                /* Chop off the rxpd + the excess memory from the 802.2/llc/snap header
                 *   that was removed
                 */
-               hdrchop = (u8 *) p_ethhdr - (u8 *) p_rx_pkt;
+               hdrchop = (u8 *)p_ethhdr - (u8 *)p_rx_pd;
        } else {
                lbs_deb_hex(LBS_DEB_RX, "RX Data: LLC/SNAP",
                        (u8 *) & p_rx_pkt->rfc1042_hdr,
                        sizeof(p_rx_pkt->rfc1042_hdr));
 
                /* Chop off the rxpd */
-               hdrchop = (u8 *) & p_rx_pkt->eth803_hdr - (u8 *) p_rx_pkt;
+               hdrchop = (u8 *)&p_rx_pkt->eth803_hdr - (u8 *)p_rx_pd;
        }
 
        /* Chop off the leading header bytes so the skb points to the start of
@@ -334,14 +330,6 @@ static int process_rxed_802_11_packet(struct lbs_private *priv,
                goto done;
        }
 
-       /*
-        * Check rxpd status and update 802.3 stat,
-        */
-       if (!(prxpd->status & cpu_to_le16(MRVDRV_RXPD_STATUS_OK))) {
-               //lbs_deb_rx("rx err: frame received with bad status\n");
-               dev->stats.rx_errors++;
-       }
-
        lbs_deb_rx("rx data: skb->len-sizeof(RxPd) = %d-%zd = %zd\n",
               skb->len, sizeof(struct rxpd), skb->len - sizeof(struct rxpd));
 
@@ -353,8 +341,6 @@ static int process_rxed_802_11_packet(struct lbs_private *priv,
        radiotap_hdr.hdr.it_pad = 0;
        radiotap_hdr.hdr.it_len = cpu_to_le16 (sizeof(struct rx_radiotap_hdr));
        radiotap_hdr.hdr.it_present = cpu_to_le32 (RX_RADIOTAP_PRESENT);
-       if (!(prxpd->status & cpu_to_le16(MRVDRV_RXPD_STATUS_OK)))
-               radiotap_hdr.flags |= IEEE80211_RADIOTAP_F_BADFCS;
        radiotap_hdr.rate = convert_mv_rate_to_radiotap(prxpd->rx_rate);
        /* XXX must check no carryout */
        radiotap_hdr.antsignal = prxpd->snr + prxpd->nf;
index 8124db36aaff4445ddfd6e1564897b56efb95455..601b54249677412cd5f797be38311dbfcfdf20b4 100644 (file)
                              + 40)     /* 40 for WPAIE */
 
 //! Memory needed to store a max sized channel List TLV for a firmware scan
-#define CHAN_TLV_MAX_SIZE  (sizeof(struct mrvlietypesheader)    \
+#define CHAN_TLV_MAX_SIZE  (sizeof(struct mrvl_ie_header)    \
                             + (MRVDRV_MAX_CHANNELS_PER_SCAN     \
                                * sizeof(struct chanscanparamset)))
 
 //! Memory needed to store a max number/size SSID TLV for a firmware scan
-#define SSID_TLV_MAX_SIZE  (1 * sizeof(struct mrvlietypes_ssidparamset))
+#define SSID_TLV_MAX_SIZE  (1 * sizeof(struct mrvl_ie_ssid_param_set))
 
 //! Maximum memory needed for a cmd_ds_802_11_scan with all TLVs at max
 #define MAX_SCAN_CFG_ALLOC (sizeof(struct cmd_ds_802_11_scan)  \
@@ -211,7 +211,7 @@ static int lbs_scan_create_channel_list(struct lbs_private *priv,
  */
 static int lbs_scan_add_ssid_tlv(struct lbs_private *priv, u8 *tlv)
 {
-       struct mrvlietypes_ssidparamset *ssid_tlv = (void *)tlv;
+       struct mrvl_ie_ssid_param_set *ssid_tlv = (void *)tlv;
 
        ssid_tlv->header.type = cpu_to_le16(TLV_TYPE_SSID);
        ssid_tlv->header.len = cpu_to_le16(priv->scan_ssid_len);
@@ -249,7 +249,7 @@ static int lbs_scan_add_chanlist_tlv(uint8_t *tlv,
                                     int chan_count)
 {
        size_t size = sizeof(struct chanscanparamset) *chan_count;
-       struct mrvlietypes_chanlistparamset *chan_tlv = (void *)tlv;
+       struct mrvl_ie_chanlist_param_set *chan_tlv = (void *)tlv;
 
        chan_tlv->header.type = cpu_to_le16(TLV_TYPE_CHANLIST);
        memcpy(chan_tlv->chanscanparam, chan_list, size);
@@ -270,7 +270,7 @@ static int lbs_scan_add_chanlist_tlv(uint8_t *tlv,
 static int lbs_scan_add_rates_tlv(uint8_t *tlv)
 {
        int i;
-       struct mrvlietypes_ratesparamset *rate_tlv = (void *)tlv;
+       struct mrvl_ie_rates_param_set *rate_tlv = (void *)tlv;
 
        rate_tlv->header.type = cpu_to_le16(TLV_TYPE_RATES);
        tlv += sizeof(rate_tlv->header);
@@ -513,12 +513,12 @@ void lbs_scan_worker(struct work_struct *work)
 static int lbs_process_bss(struct bss_descriptor *bss,
                           uint8_t **pbeaconinfo, int *bytesleft)
 {
-       struct ieeetypes_fhparamset *pFH;
-       struct ieeetypes_dsparamset *pDS;
-       struct ieeetypes_cfparamset *pCF;
-       struct ieeetypes_ibssparamset *pibss;
+       struct ieee_ie_fh_param_set *fh;
+       struct ieee_ie_ds_param_set *ds;
+       struct ieee_ie_cf_param_set *cf;
+       struct ieee_ie_ibss_param_set *ibss;
        DECLARE_SSID_BUF(ssid);
-       struct ieeetypes_countryinfoset *pcountryinfo;
+       struct ieee_ie_country_info_set *pcountryinfo;
        uint8_t *pos, *end, *p;
        uint8_t n_ex_rates = 0, got_basic_rates = 0, n_basic_rates = 0;
        uint16_t beaconsize = 0;
@@ -616,50 +616,49 @@ static int lbs_process_bss(struct bss_descriptor *bss,
                        break;
 
                case WLAN_EID_FH_PARAMS:
-                       pFH = (struct ieeetypes_fhparamset *) pos;
-                       memmove(&bss->phyparamset.fhparamset, pFH,
-                               sizeof(struct ieeetypes_fhparamset));
+                       fh = (struct ieee_ie_fh_param_set *) pos;
+                       memcpy(&bss->phy.fh, fh, sizeof(*fh));
                        lbs_deb_scan("got FH IE\n");
                        break;
 
                case WLAN_EID_DS_PARAMS:
-                       pDS = (struct ieeetypes_dsparamset *) pos;
-                       bss->channel = pDS->currentchan;
-                       memcpy(&bss->phyparamset.dsparamset, pDS,
-                              sizeof(struct ieeetypes_dsparamset));
+                       ds = (struct ieee_ie_ds_param_set *) pos;
+                       bss->channel = ds->channel;
+                       memcpy(&bss->phy.ds, ds, sizeof(*ds));
                        lbs_deb_scan("got DS IE, channel %d\n", bss->channel);
                        break;
 
                case WLAN_EID_CF_PARAMS:
-                       pCF = (struct ieeetypes_cfparamset *) pos;
-                       memcpy(&bss->ssparamset.cfparamset, pCF,
-                              sizeof(struct ieeetypes_cfparamset));
+                       cf = (struct ieee_ie_cf_param_set *) pos;
+                       memcpy(&bss->ss.cf, cf, sizeof(*cf));
                        lbs_deb_scan("got CF IE\n");
                        break;
 
                case WLAN_EID_IBSS_PARAMS:
-                       pibss = (struct ieeetypes_ibssparamset *) pos;
-                       bss->atimwindow = le16_to_cpu(pibss->atimwindow);
-                       memmove(&bss->ssparamset.ibssparamset, pibss,
-                               sizeof(struct ieeetypes_ibssparamset));
+                       ibss = (struct ieee_ie_ibss_param_set *) pos;
+                       bss->atimwindow = ibss->atimwindow;
+                       memcpy(&bss->ss.ibss, ibss, sizeof(*ibss));
                        lbs_deb_scan("got IBSS IE\n");
                        break;
 
                case WLAN_EID_COUNTRY:
-                       pcountryinfo = (struct ieeetypes_countryinfoset *) pos;
+                       pcountryinfo = (struct ieee_ie_country_info_set *) pos;
                        lbs_deb_scan("got COUNTRY IE\n");
-                       if (pcountryinfo->len < sizeof(pcountryinfo->countrycode)
-                           || pcountryinfo->len > 254) {
-                               lbs_deb_scan("process_bss: 11D- Err CountryInfo len %d, min %zd, max 254\n",
-                                            pcountryinfo->len, sizeof(pcountryinfo->countrycode));
+                       if (pcountryinfo->header.len < sizeof(pcountryinfo->countrycode)
+                           || pcountryinfo->header.len > 254) {
+                               lbs_deb_scan("%s: 11D- Err CountryInfo len %d, min %zd, max 254\n",
+                                            __func__,
+                                            pcountryinfo->header.len,
+                                            sizeof(pcountryinfo->countrycode));
                                ret = -1;
                                goto done;
                        }
 
-                       memcpy(&bss->countryinfo, pcountryinfo, pcountryinfo->len + 2);
+                       memcpy(&bss->countryinfo, pcountryinfo,
+                               pcountryinfo->header.len + 2);
                        lbs_deb_hex(LBS_DEB_SCAN, "process_bss: 11d countryinfo",
                                    (uint8_t *) pcountryinfo,
-                                   (int) (pcountryinfo->len + 2));
+                                   (int) (pcountryinfo->header.len + 2));
                        break;
 
                case WLAN_EID_EXT_SUPP_RATES:
@@ -1130,7 +1129,7 @@ static int lbs_ret_80211_scan(struct lbs_private *priv, unsigned long dummy,
                goto done;
        }
 
-       bytesleft = le16_to_cpu(scanresp->bssdescriptsize);
+       bytesleft = get_unaligned_le16(&scanresp->bssdescriptsize);
        lbs_deb_scan("SCAN_RESP: bssdescriptsize %d\n", bytesleft);
 
        scanrespsize = le16_to_cpu(resp->size);
index f10aa39a6b68e6abe650934ccc4957f653869a98..160cfd8311c08ad5225b418d33e37ce5dd9fd6fa 100644 (file)
@@ -132,8 +132,12 @@ int lbs_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
        txpd->tx_packet_length = cpu_to_le16(pkt_len);
        txpd->tx_packet_location = cpu_to_le32(sizeof(struct txpd));
 
-       if (dev == priv->mesh_dev)
-               txpd->tx_control |= cpu_to_le32(TxPD_MESH_FRAME);
+       if (dev == priv->mesh_dev) {
+               if (priv->mesh_fw_ver == MESH_FW_OLD)
+                       txpd->tx_control |= cpu_to_le32(TxPD_MESH_FRAME);
+               else if (priv->mesh_fw_ver == MESH_FW_NEW)
+                       txpd->u.bss.bss_num = MESH_IFACE_ID;
+       }
 
        lbs_deb_hex(LBS_DEB_TX, "txpd", (u8 *) &txpd, sizeof(struct txpd));
 
index fb7a2d1a2525e5efae1d78c9dcf0edec7ab1a76c..99905df65b2579466a4caeadba4e49036d24ddfa 100644 (file)
@@ -8,9 +8,14 @@
 #include <asm/byteorder.h>
 #include <linux/wireless.h>
 
-struct ieeetypes_cfparamset {
-       u8 elementid;
+struct ieee_ie_header {
+       u8 id;
        u8 len;
+} __attribute__ ((packed));
+
+struct ieee_ie_cf_param_set {
+       struct ieee_ie_header header;
+
        u8 cfpcnt;
        u8 cfpperiod;
        __le16 cfpmaxduration;
@@ -18,42 +23,35 @@ struct ieeetypes_cfparamset {
 } __attribute__ ((packed));
 
 
-struct ieeetypes_ibssparamset {
-       u8 elementid;
-       u8 len;
+struct ieee_ie_ibss_param_set {
+       struct ieee_ie_header header;
+
        __le16 atimwindow;
 } __attribute__ ((packed));
 
-union IEEEtypes_ssparamset {
-       struct ieeetypes_cfparamset cfparamset;
-       struct ieeetypes_ibssparamset ibssparamset;
+union ieee_ss_param_set {
+       struct ieee_ie_cf_param_set cf;
+       struct ieee_ie_ibss_param_set ibss;
 } __attribute__ ((packed));
 
-struct ieeetypes_fhparamset {
-       u8 elementid;
-       u8 len;
+struct ieee_ie_fh_param_set {
+       struct ieee_ie_header header;
+
        __le16 dwelltime;
        u8 hopset;
        u8 hoppattern;
        u8 hopindex;
 } __attribute__ ((packed));
 
-struct ieeetypes_dsparamset {
-       u8 elementid;
-       u8 len;
-       u8 currentchan;
-} __attribute__ ((packed));
+struct ieee_ie_ds_param_set {
+       struct ieee_ie_header header;
 
-union ieeetypes_phyparamset {
-       struct ieeetypes_fhparamset fhparamset;
-       struct ieeetypes_dsparamset dsparamset;
+       u8 channel;
 } __attribute__ ((packed));
 
-struct ieeetypes_assocrsp {
-       __le16 capability;
-       __le16 statuscode;
-       __le16 aid;
-       u8 iebuffer[1];
+union ieee_phy_param_set {
+       struct ieee_ie_fh_param_set fh;
+       struct ieee_ie_ds_param_set ds;
 } __attribute__ ((packed));
 
 /** TLV  type ID definition */
@@ -94,30 +92,33 @@ struct ieeetypes_assocrsp {
 #define TLV_TYPE_TSFTIMESTAMP      (PROPRIETARY_TLV_BASE_ID + 19)
 #define TLV_TYPE_RSSI_HIGH          (PROPRIETARY_TLV_BASE_ID + 22)
 #define TLV_TYPE_SNR_HIGH           (PROPRIETARY_TLV_BASE_ID + 23)
+#define TLV_TYPE_AUTH_TYPE          (PROPRIETARY_TLV_BASE_ID + 31)
+#define TLV_TYPE_MESH_ID            (PROPRIETARY_TLV_BASE_ID + 37)
+#define TLV_TYPE_OLD_MESH_ID        (PROPRIETARY_TLV_BASE_ID + 291)
 
 /** TLV related data structures*/
-struct mrvlietypesheader {
+struct mrvl_ie_header {
        __le16 type;
        __le16 len;
 } __attribute__ ((packed));
 
-struct mrvlietypes_data {
-       struct mrvlietypesheader header;
+struct mrvl_ie_data {
+       struct mrvl_ie_header header;
        u8 Data[1];
 } __attribute__ ((packed));
 
-struct mrvlietypes_ratesparamset {
-       struct mrvlietypesheader header;
+struct mrvl_ie_rates_param_set {
+       struct mrvl_ie_header header;
        u8 rates[1];
 } __attribute__ ((packed));
 
-struct mrvlietypes_ssidparamset {
-       struct mrvlietypesheader header;
+struct mrvl_ie_ssid_param_set {
+       struct mrvl_ie_header header;
        u8 ssid[1];
 } __attribute__ ((packed));
 
-struct mrvlietypes_wildcardssidparamset {
-       struct mrvlietypesheader header;
+struct mrvl_ie_wildcard_ssid_param_set {
+       struct mrvl_ie_header header;
        u8 MaxSsidlength;
        u8 ssid[1];
 } __attribute__ ((packed));
@@ -142,91 +143,72 @@ struct chanscanparamset {
        __le16 maxscantime;
 } __attribute__ ((packed));
 
-struct mrvlietypes_chanlistparamset {
-       struct mrvlietypesheader header;
+struct mrvl_ie_chanlist_param_set {
+       struct mrvl_ie_header header;
        struct chanscanparamset chanscanparam[1];
 } __attribute__ ((packed));
 
-struct cfparamset {
+struct mrvl_ie_cf_param_set {
+       struct mrvl_ie_header header;
        u8 cfpcnt;
        u8 cfpperiod;
        __le16 cfpmaxduration;
        __le16 cfpdurationremaining;
 } __attribute__ ((packed));
 
-struct ibssparamset {
-       __le16 atimwindow;
-} __attribute__ ((packed));
-
-struct mrvlietypes_ssparamset {
-       struct mrvlietypesheader header;
-       union {
-               struct cfparamset cfparamset[1];
-               struct ibssparamset ibssparamset[1];
-       } cf_ibss;
+struct mrvl_ie_ds_param_set {
+       struct mrvl_ie_header header;
+       u8 channel;
 } __attribute__ ((packed));
 
-struct fhparamset {
-       __le16 dwelltime;
-       u8 hopset;
-       u8 hoppattern;
-       u8 hopindex;
-} __attribute__ ((packed));
-
-struct dsparamset {
-       u8 currentchan;
-} __attribute__ ((packed));
-
-struct mrvlietypes_phyparamset {
-       struct mrvlietypesheader header;
-       union {
-               struct fhparamset fhparamset[1];
-               struct dsparamset dsparamset[1];
-       } fh_ds;
-} __attribute__ ((packed));
-
-struct mrvlietypes_rsnparamset {
-       struct mrvlietypesheader header;
+struct mrvl_ie_rsn_param_set {
+       struct mrvl_ie_header header;
        u8 rsnie[1];
 } __attribute__ ((packed));
 
-struct mrvlietypes_tsftimestamp {
-       struct mrvlietypesheader header;
+struct mrvl_ie_tsf_timestamp {
+       struct mrvl_ie_header header;
        __le64 tsftable[1];
 } __attribute__ ((packed));
 
+/* v9 and later firmware only */
+struct mrvl_ie_auth_type {
+       struct mrvl_ie_header header;
+       __le16 auth;
+} __attribute__ ((packed));
+
 /**  Local Power capability */
-struct mrvlietypes_powercapability {
-       struct mrvlietypesheader header;
+struct mrvl_ie_power_capability {
+       struct mrvl_ie_header header;
        s8 minpower;
        s8 maxpower;
 } __attribute__ ((packed));
 
 /* used in CMD_802_11_SUBSCRIBE_EVENT for SNR, RSSI and Failure */
-struct mrvlietypes_thresholds {
-       struct mrvlietypesheader header;
+struct mrvl_ie_thresholds {
+       struct mrvl_ie_header header;
        u8 value;
        u8 freq;
 } __attribute__ ((packed));
 
-struct mrvlietypes_beaconsmissed {
-       struct mrvlietypesheader header;
+struct mrvl_ie_beacons_missed {
+       struct mrvl_ie_header header;
        u8 beaconmissed;
        u8 reserved;
 } __attribute__ ((packed));
 
-struct mrvlietypes_numprobes {
-       struct mrvlietypesheader header;
+struct mrvl_ie_num_probes {
+       struct mrvl_ie_header header;
        __le16 numprobes;
 } __attribute__ ((packed));
 
-struct mrvlietypes_bcastprobe {
-       struct mrvlietypesheader header;
+struct mrvl_ie_bcast_probe {
+       struct mrvl_ie_header header;
        __le16 bcastprobe;
 } __attribute__ ((packed));
 
-struct mrvlietypes_numssidprobe {
-       struct mrvlietypesheader header;
+struct mrvl_ie_num_ssid_probe {
+       struct mrvl_ie_header header;
        __le16 numssidprobe;
 } __attribute__ ((packed));
 
@@ -235,8 +217,8 @@ struct led_pin {
        u8 pin;
 } __attribute__ ((packed));
 
-struct mrvlietypes_ledgpio {
-       struct mrvlietypesheader header;
+struct mrvl_ie_ledgpio {
+       struct mrvl_ie_header header;
        struct led_pin ledpin[1];
 } __attribute__ ((packed));
 
@@ -248,8 +230,8 @@ struct led_bhv {
 } __attribute__ ((packed));
 
 
-struct mrvlietypes_ledbhv {
-       struct mrvlietypesheader header;
+struct mrvl_ie_ledbhv {
+       struct mrvl_ie_header header;
        struct led_bhv ledbhv[1];
 } __attribute__ ((packed));
 
index 59634c33b1f9194f4e10ed8fc36e2d9aed30ef4e..392337b37b1ddcc728365eec9848cfc329e9d0f5 100644 (file)
@@ -461,8 +461,7 @@ static inline void process_cmdrequest(int recvlength, uint8_t *recvbuff,
                return;
        }
 
-       if (!in_interrupt())
-               BUG();
+       BUG_ON(!in_interrupt());
 
        spin_lock(&priv->driver_lock);
        memcpy(priv->cmd_resp_buff, recvbuff + MESSAGE_HEADER_LEN,
index e7289e2e7f16fb87e3a96113f4efe1e43433dbe6..10a99e26d392ea4e67e5fe82396a86e748e1046e 100644 (file)
@@ -366,36 +366,6 @@ static int lbtf_op_config(struct ieee80211_hw *hw, u32 changed)
        return 0;
 }
 
-static int lbtf_op_config_interface(struct ieee80211_hw *hw,
-                       struct ieee80211_vif *vif,
-                       struct ieee80211_if_conf *conf)
-{
-       struct lbtf_private *priv = hw->priv;
-       struct sk_buff *beacon;
-
-       switch (priv->vif->type) {
-       case NL80211_IFTYPE_AP:
-       case NL80211_IFTYPE_MESH_POINT:
-               beacon = ieee80211_beacon_get(hw, vif);
-               if (beacon) {
-                       lbtf_beacon_set(priv, beacon);
-                       kfree_skb(beacon);
-                       lbtf_beacon_ctrl(priv, 1, hw->conf.beacon_int);
-               }
-               break;
-       default:
-               break;
-       }
-
-       if (conf->bssid) {
-               u8 null_bssid[ETH_ALEN] = {0};
-               bool activate = compare_ether_addr(conf->bssid, null_bssid);
-               lbtf_set_bssid(priv, activate, conf->bssid);
-       }
-
-       return 0;
-}
-
 #define SUPPORTED_FIF_FLAGS  (FIF_PROMISC_IN_BSS | FIF_ALLMULTI)
 static void lbtf_op_configure_filter(struct ieee80211_hw *hw,
                        unsigned int changed_flags,
@@ -451,6 +421,29 @@ static void lbtf_op_bss_info_changed(struct ieee80211_hw *hw,
                        u32 changes)
 {
        struct lbtf_private *priv = hw->priv;
+       struct sk_buff *beacon;
+
+       if (changes & (BSS_CHANGED_BEACON | BSS_CHANGED_BEACON_INT)) {
+               switch (priv->vif->type) {
+               case NL80211_IFTYPE_AP:
+               case NL80211_IFTYPE_MESH_POINT:
+                       beacon = ieee80211_beacon_get(hw, vif);
+                       if (beacon) {
+                               lbtf_beacon_set(priv, beacon);
+                               kfree_skb(beacon);
+                               lbtf_beacon_ctrl(priv, 1,
+                                                bss_conf->beacon_int);
+                       }
+                       break;
+               default:
+                       break;
+               }
+       }
+
+       if (changes & BSS_CHANGED_BSSID) {
+               bool activate = !is_zero_ether_addr(bss_conf->bssid);
+               lbtf_set_bssid(priv, activate, bss_conf->bssid);
+       }
 
        if (changes & BSS_CHANGED_ERP_PREAMBLE) {
                if (bss_conf->use_short_preamble)
@@ -459,8 +452,6 @@ static void lbtf_op_bss_info_changed(struct ieee80211_hw *hw,
                        priv->preamble = CMD_TYPE_LONG_PREAMBLE;
                lbtf_set_radio_control(priv);
        }
-
-       return;
 }
 
 static const struct ieee80211_ops lbtf_ops = {
@@ -470,7 +461,6 @@ static const struct ieee80211_ops lbtf_ops = {
        .add_interface          = lbtf_op_add_interface,
        .remove_interface       = lbtf_op_remove_interface,
        .config                 = lbtf_op_config,
-       .config_interface       = lbtf_op_config_interface,
        .configure_filter       = lbtf_op_configure_filter,
        .bss_info_changed       = lbtf_op_bss_info_changed,
 };
index d4fdc8b7d7d8c7ff3c0321c9e4d60ba3d35f7147..e789c6e9938cb60e62a918b2f5e2083af7251591 100644 (file)
@@ -280,7 +280,6 @@ struct mac80211_hwsim_data {
        struct ieee80211_rate rates[ARRAY_SIZE(hwsim_rates)];
 
        struct ieee80211_channel *channel;
-       int radio_enabled;
        unsigned long beacon_int; /* in jiffies unit */
        unsigned int rx_filter;
        int started;
@@ -291,6 +290,14 @@ struct mac80211_hwsim_data {
        bool ps_poll_pending;
        struct dentry *debugfs;
        struct dentry *debugfs_ps;
+
+       /*
+        * Only radios in the same group can communicate together (the
+        * channel has to match too). Each bit represents a group. A
+        * radio can be in more then one group.
+        */
+       u64 group;
+       struct dentry *debugfs_group;
 };
 
 
@@ -410,9 +417,9 @@ static bool mac80211_hwsim_tx_frame(struct ieee80211_hw *hw,
                if (data == data2)
                        continue;
 
-               if (!data2->started || !data2->radio_enabled ||
-                   !hwsim_ps_rx_ok(data2, skb) ||
-                   data->channel->center_freq != data2->channel->center_freq)
+               if (!data2->started || !hwsim_ps_rx_ok(data2, skb) ||
+                   data->channel->center_freq != data2->channel->center_freq ||
+                   !(data->group & data2->group))
                        continue;
 
                nskb = skb_copy(skb, GFP_ATOMIC);
@@ -432,7 +439,6 @@ static bool mac80211_hwsim_tx_frame(struct ieee80211_hw *hw,
 
 static int mac80211_hwsim_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
 {
-       struct mac80211_hwsim_data *data = hw->priv;
        bool ack;
        struct ieee80211_tx_info *txi;
 
@@ -444,13 +450,6 @@ static int mac80211_hwsim_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
                return NETDEV_TX_OK;
        }
 
-       if (!data->radio_enabled) {
-               printk(KERN_DEBUG "%s: dropped TX frame since radio "
-                      "disabled\n", wiphy_name(hw->wiphy));
-               dev_kfree_skb(skb);
-               return NETDEV_TX_OK;
-       }
-
        ack = mac80211_hwsim_tx_frame(hw, skb);
 
        txi = IEEE80211_SKB_CB(skb);
@@ -537,7 +536,7 @@ static void mac80211_hwsim_beacon(unsigned long arg)
        struct ieee80211_hw *hw = (struct ieee80211_hw *) arg;
        struct mac80211_hwsim_data *data = hw->priv;
 
-       if (!data->started || !data->radio_enabled)
+       if (!data->started)
                return;
 
        ieee80211_iterate_active_interfaces_atomic(
@@ -553,18 +552,14 @@ static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed)
        struct mac80211_hwsim_data *data = hw->priv;
        struct ieee80211_conf *conf = &hw->conf;
 
-       printk(KERN_DEBUG "%s:%s (freq=%d radio_enabled=%d beacon_int=%d)\n",
+       printk(KERN_DEBUG "%s:%s (freq=%d idle=%d ps=%d)\n",
               wiphy_name(hw->wiphy), __func__,
-              conf->channel->center_freq, conf->radio_enabled,
-              conf->beacon_int);
+              conf->channel->center_freq,
+              !!(conf->flags & IEEE80211_CONF_IDLE),
+              !!(conf->flags & IEEE80211_CONF_PS));
 
        data->channel = conf->channel;
-       data->radio_enabled = conf->radio_enabled;
-       data->beacon_int = 1024 * conf->beacon_int / 1000 * HZ / 1000;
-       if (data->beacon_int < 1)
-               data->beacon_int = 1;
-
-       if (!data->started || !data->radio_enabled)
+       if (!data->started || !data->beacon_int)
                del_timer(&data->beacon_timer);
        else
                mod_timer(&data->beacon_timer, jiffies + data->beacon_int);
@@ -592,35 +587,26 @@ static void mac80211_hwsim_configure_filter(struct ieee80211_hw *hw,
        *total_flags = data->rx_filter;
 }
 
-static int mac80211_hwsim_config_interface(struct ieee80211_hw *hw,
-                                          struct ieee80211_vif *vif,
-                                          struct ieee80211_if_conf *conf)
-{
-       struct hwsim_vif_priv *vp = (void *)vif->drv_priv;
-
-       hwsim_check_magic(vif);
-       if (conf->changed & IEEE80211_IFCC_BSSID) {
-               DECLARE_MAC_BUF(mac);
-               printk(KERN_DEBUG "%s:%s: BSSID changed: %pM\n",
-                      wiphy_name(hw->wiphy), __func__,
-                      conf->bssid);
-               memcpy(vp->bssid, conf->bssid, ETH_ALEN);
-       }
-       return 0;
-}
-
 static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw,
                                            struct ieee80211_vif *vif,
                                            struct ieee80211_bss_conf *info,
                                            u32 changed)
 {
        struct hwsim_vif_priv *vp = (void *)vif->drv_priv;
+       struct mac80211_hwsim_data *data = hw->priv;
 
        hwsim_check_magic(vif);
 
        printk(KERN_DEBUG "%s:%s(changed=0x%x)\n",
               wiphy_name(hw->wiphy), __func__, changed);
 
+       if (changed & BSS_CHANGED_BSSID) {
+               printk(KERN_DEBUG "%s:%s: BSSID changed: %pM\n",
+                      wiphy_name(hw->wiphy), __func__,
+                      info->bssid);
+               memcpy(vp->bssid, info->bssid, ETH_ALEN);
+       }
+
        if (changed & BSS_CHANGED_ASSOC) {
                printk(KERN_DEBUG "  %s: ASSOC: assoc=%d aid=%d\n",
                       wiphy_name(hw->wiphy), info->assoc, info->aid);
@@ -628,6 +614,14 @@ static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw,
                vp->aid = info->aid;
        }
 
+       if (changed & BSS_CHANGED_BEACON_INT) {
+               printk(KERN_DEBUG "  %s: BCNINT: %d\n",
+                      wiphy_name(hw->wiphy), info->beacon_int);
+               data->beacon_int = 1024 * info->beacon_int / 1000 * HZ / 1000;
+               if (WARN_ON(!data->beacon_int))
+                       data->beacon_int = 1;
+       }
+
        if (changed & BSS_CHANGED_ERP_CTS_PROT) {
                printk(KERN_DEBUG "  %s: ERP_CTS_PROT: %d\n",
                       wiphy_name(hw->wiphy), info->use_cts_prot);
@@ -646,7 +640,7 @@ static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw,
        if (changed & BSS_CHANGED_HT) {
                printk(KERN_DEBUG "  %s: HT: op_mode=0x%x\n",
                       wiphy_name(hw->wiphy),
-                      info->ht.operation_mode);
+                      info->ht_operation_mode);
        }
 
        if (changed & BSS_CHANGED_BASIC_RATES) {
@@ -704,7 +698,6 @@ static const struct ieee80211_ops mac80211_hwsim_ops =
        .remove_interface = mac80211_hwsim_remove_interface,
        .config = mac80211_hwsim_config,
        .configure_filter = mac80211_hwsim_configure_filter,
-       .config_interface = mac80211_hwsim_config_interface,
        .bss_info_changed = mac80211_hwsim_bss_info_changed,
        .sta_notify = mac80211_hwsim_sta_notify,
        .set_tim = mac80211_hwsim_set_tim,
@@ -725,6 +718,7 @@ static void mac80211_hwsim_free(void)
        spin_unlock_bh(&hwsim_radio_lock);
 
        list_for_each_entry(data, &tmplist, list) {
+               debugfs_remove(data->debugfs_group);
                debugfs_remove(data->debugfs_ps);
                debugfs_remove(data->debugfs);
                ieee80211_unregister_hw(data->hw);
@@ -782,8 +776,7 @@ static void hwsim_send_ps_poll(void *dat, u8 *mac, struct ieee80211_vif *vif)
        pspoll->aid = cpu_to_le16(0xc000 | vp->aid);
        memcpy(pspoll->bssid, vp->bssid, ETH_ALEN);
        memcpy(pspoll->ta, mac, ETH_ALEN);
-       if (data->radio_enabled &&
-           !mac80211_hwsim_tx_frame(data->hw, skb))
+       if (!mac80211_hwsim_tx_frame(data->hw, skb))
                printk(KERN_DEBUG "%s: PS-Poll frame not ack'ed\n", __func__);
        dev_kfree_skb(skb);
 }
@@ -814,8 +807,7 @@ static void hwsim_send_nullfunc(struct mac80211_hwsim_data *data, u8 *mac,
        memcpy(hdr->addr1, vp->bssid, ETH_ALEN);
        memcpy(hdr->addr2, mac, ETH_ALEN);
        memcpy(hdr->addr3, vp->bssid, ETH_ALEN);
-       if (data->radio_enabled &&
-           !mac80211_hwsim_tx_frame(data->hw, skb))
+       if (!mac80211_hwsim_tx_frame(data->hw, skb))
                printk(KERN_DEBUG "%s: nullfunc frame not ack'ed\n", __func__);
        dev_kfree_skb(skb);
 }
@@ -877,6 +869,24 @@ DEFINE_SIMPLE_ATTRIBUTE(hwsim_fops_ps, hwsim_fops_ps_read, hwsim_fops_ps_write,
                        "%llu\n");
 
 
+static int hwsim_fops_group_read(void *dat, u64 *val)
+{
+       struct mac80211_hwsim_data *data = dat;
+       *val = data->group;
+       return 0;
+}
+
+static int hwsim_fops_group_write(void *dat, u64 val)
+{
+       struct mac80211_hwsim_data *data = dat;
+       data->group = val;
+       return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(hwsim_fops_group,
+                       hwsim_fops_group_read, hwsim_fops_group_write,
+                       "%llx\n");
+
 static int __init init_mac80211_hwsim(void)
 {
        int i, err = 0;
@@ -981,6 +991,8 @@ static int __init init_mac80211_hwsim(void)
 
                        hw->wiphy->bands[band] = sband;
                }
+               /* By default all radios are belonging to the first group */
+               data->group = 1;
 
                /* Work to be done prior to ieee80211_register_hw() */
                switch (regtest) {
@@ -1105,6 +1117,9 @@ static int __init init_mac80211_hwsim(void)
                data->debugfs_ps = debugfs_create_file("ps", 0666,
                                                       data->debugfs, data,
                                                       &hwsim_fops_ps);
+               data->debugfs_group = debugfs_create_file("group", 0666,
+                                                       data->debugfs, data,
+                                                       &hwsim_fops_group);
 
                setup_timer(&data->beacon_timer, mac80211_hwsim_beacon,
                            (unsigned long) hw);
index a9a970469c2add1cd5b098c04409723c52089902..a263d5c84c0874857b8ee02243cff89bc9e8eee6 100644 (file)
@@ -2369,7 +2369,7 @@ static int mwl8k_cmd_set_aid(struct ieee80211_hw *hw,
        if (info->use_cts_prot) {
                prot_mode = MWL8K_FRAME_PROT_11G;
        } else {
-               switch (info->ht.operation_mode &
+               switch (info->ht_operation_mode &
                        IEEE80211_HT_OP_MODE_PROTECTION) {
                case IEEE80211_HT_OP_MODE_PROTECTION_20MHZ:
                        prot_mode = MWL8K_FRAME_PROT_11N_HT_40MHZ_ONLY;
@@ -3089,19 +3089,6 @@ static int mwl8k_config(struct ieee80211_hw *hw, u32 changed)
        return rc ? -EINVAL : 0;
 }
 
-static int mwl8k_config_interface(struct ieee80211_hw *hw,
-                                 struct ieee80211_vif *vif,
-                                 struct ieee80211_if_conf *conf)
-{
-       struct mwl8k_vif *mv_vif = MWL8K_VIF(vif);
-       u32 changed = conf->changed;
-
-       if (changed & IEEE80211_IFCC_BSSID)
-               memcpy(mv_vif->bssid, conf->bssid, IEEE80211_ADDR_LEN);
-
-       return 0;
-}
-
 struct mwl8k_bss_info_changed_worker {
        struct mwl8k_work_struct header;
        struct ieee80211_vif *vif;
@@ -3183,8 +3170,12 @@ static void mwl8k_bss_info_changed(struct ieee80211_hw *hw,
 {
        struct mwl8k_bss_info_changed_worker *worker;
        struct mwl8k_priv *priv = hw->priv;
+       struct mwl8k_vif *mv_vif = MWL8K_VIF(vif);
        int rc;
 
+       if (changed & BSS_CHANGED_BSSID)
+               memcpy(mv_vif->bssid, info->bssid, IEEE80211_ADDR_LEN);
+
        if ((changed & BSS_CHANGED_ASSOC) == 0)
                return;
 
@@ -3442,7 +3433,6 @@ static const struct ieee80211_ops mwl8k_ops = {
        .add_interface          = mwl8k_add_interface,
        .remove_interface       = mwl8k_remove_interface,
        .config                 = mwl8k_config,
-       .config_interface       = mwl8k_config_interface,
        .bss_info_changed       = mwl8k_bss_info_changed,
        .configure_filter       = mwl8k_configure_filter,
        .set_rts_threshold      = mwl8k_set_rts_threshold,
index ecf8b6ed5a471fd707e63c9e07c6625fc36101a9..db3df947d8ed45b2c2c623e8dd918b691bc8436d 100644 (file)
@@ -125,6 +125,7 @@ struct p54_led_dev {
        struct led_classdev led_dev;
        char name[P54_LED_MAX_NAME_LEN + 1];
 
+       unsigned int toggled;
        unsigned int index;
        unsigned int registered;
 };
@@ -133,55 +134,74 @@ struct p54_led_dev {
 
 struct p54_common {
        struct ieee80211_hw *hw;
-       u32 rx_start;
-       u32 rx_end;
-       struct sk_buff_head tx_queue;
+       struct ieee80211_vif *vif;
        void (*tx)(struct ieee80211_hw *dev, struct sk_buff *skb);
        int (*open)(struct ieee80211_hw *dev);
        void (*stop)(struct ieee80211_hw *dev);
-       int mode;
+       struct sk_buff_head tx_queue;
+       struct mutex conf_mutex;
+
+       /* memory management (as seen by the firmware) */
+       u32 rx_start;
+       u32 rx_end;
        u16 rx_mtu;
        u8 headroom;
        u8 tailroom;
-       struct mutex conf_mutex;
-       u8 mac_addr[ETH_ALEN];
-       u8 bssid[ETH_ALEN];
+
+       /* firmware/hardware info */
+       unsigned int tx_hdr_len;
+       unsigned int fw_var;
+       unsigned int fw_interface;
+       u8 version;
+
+       /* (e)DCF / QOS state */
+       bool use_short_slot;
+       struct ieee80211_tx_queue_stats tx_stats[8];
+       struct p54_edcf_queue_param qos_params[8];
+
+       /* Radio data */
+       u16 rxhw;
        u8 rx_diversity_mask;
        u8 tx_diversity_mask;
+       unsigned int output_power;
+       int noise;
+       /* calibration, output power limit and rssi<->dBm conversation data */
        struct pda_iq_autocal_entry *iq_autocal;
        unsigned int iq_autocal_len;
-       struct p54_cal_database *output_limit;
        struct p54_cal_database *curve_data;
+       struct p54_cal_database *output_limit;
        struct p54_rssi_linear_approximation rssical_db[IEEE80211_NUM_BANDS];
+
+       /* BBP/MAC state */
+       u8 mac_addr[ETH_ALEN];
+       u8 bssid[ETH_ALEN];
+       u16 wakeup_timer;
        unsigned int filter_flags;
-       bool use_short_slot;
-       u16 rxhw;
-       u8 version;
-       unsigned int tx_hdr_len;
-       unsigned int fw_var;
-       unsigned int fw_interface;
-       unsigned int output_power;
-       u32 tsf_low32;
-       u32 tsf_high32;
+       int mode;
+       u32 tsf_low32, tsf_high32;
        u32 basic_rate_mask;
-       u16 wakeup_timer;
        u16 aid;
-       struct ieee80211_tx_queue_stats tx_stats[8];
-       struct p54_edcf_queue_param qos_params[8];
-       struct ieee80211_low_level_stats stats;
-       struct delayed_work work;
        struct sk_buff *cached_beacon;
-       int noise;
-       void *eeprom;
-       struct completion eeprom_comp;
+
+       /* cryptographic engine information */
        u8 privacy_caps;
        u8 rx_keycache_size;
+       unsigned long *used_rxkeys;
+
        /* LED management */
 #ifdef CONFIG_P54_LEDS
-       struct p54_led_dev assoc_led;
-       struct p54_led_dev tx_led;
+       struct p54_led_dev leds[4];
+       struct delayed_work led_work;
 #endif /* CONFIG_P54_LEDS */
        u16 softled_state;              /* bit field of glowing LEDs */
+
+       /* statistics */
+       struct ieee80211_low_level_stats stats;
+       struct delayed_work work;
+
+       /* eeprom handling */
+       void *eeprom;
+       struct completion eeprom_comp;
 };
 
 int p54_rx(struct ieee80211_hw *dev, struct sk_buff *skb);
index c8f0232ee5e09db6e268385a3493c79d7de69144..b618bd14583f9489143de1e1654dad3a290c2598 100644 (file)
@@ -249,7 +249,7 @@ int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw)
                dev->queues = P54_QUEUE_AC_NUM;
        }
 
-       if (!modparam_nohwcrypt)
+       if (!modparam_nohwcrypt) {
                printk(KERN_INFO "%s: cryptographic accelerator "
                                 "WEP:%s, TKIP:%s, CCMP:%s\n",
                        wiphy_name(dev->wiphy),
@@ -259,6 +259,26 @@ int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw)
                        (priv->privacy_caps & BR_DESC_PRIV_CAP_AESCCMP) ?
                        "YES" : "no");
 
+               if (priv->rx_keycache_size) {
+                       /*
+                        * NOTE:
+                        *
+                        * The firmware provides at most 255 (0 - 254) slots
+                        * for keys which are then used to offload decryption.
+                        * As a result the 255 entry (aka 0xff) can be used
+                        * safely by the driver to mark keys that didn't fit
+                        * into the full cache. This trick saves us from
+                        * keeping a extra list for uploaded keys.
+                        */
+
+                       priv->used_rxkeys = kzalloc(BITS_TO_LONGS(
+                               priv->rx_keycache_size), GFP_KERNEL);
+
+                       if (!priv->used_rxkeys)
+                               return -ENOMEM;
+               }
+       }
+
        return 0;
 }
 EXPORT_SYMBOL_GPL(p54_parse_firmware);
@@ -749,8 +769,6 @@ static int p54_rx_data(struct ieee80211_hw *dev, struct sk_buff *skb)
 
        rx_status.signal = p54_rssi_to_dbm(dev, hdr->rssi);
        rx_status.noise = priv->noise;
-       /* XX correct? */
-       rx_status.qual = (100 * hdr->rssi) / 127;
        if (hdr->rate & 0x10)
                rx_status.flag |= RX_FLAG_SHORTPRE;
        if (dev->conf.channel->band == IEEE80211_BAND_5GHZ)
@@ -804,44 +822,37 @@ void p54_free_skb(struct ieee80211_hw *dev, struct sk_buff *skb)
        struct ieee80211_tx_info *info;
        struct p54_tx_info *range;
        unsigned long flags;
-       u32 freed = 0, last_addr = priv->rx_start;
 
-       if (unlikely(!skb || !dev || !skb_queue_len(&priv->tx_queue)))
+       if (unlikely(!skb || !dev || skb_queue_empty(&priv->tx_queue)))
                return;
 
-       /*
-        * don't try to free an already unlinked skb
+       /* There used to be a check here to see if the SKB was on the
+        * TX queue or not.  This can never happen because all SKBs we
+        * see here successfully went through p54_assign_address()
+        * which means the SKB is on the ->tx_queue.
         */
-       if (unlikely((!skb->next) || (!skb->prev)))
-               return;
 
        spin_lock_irqsave(&priv->tx_queue.lock, flags);
        info = IEEE80211_SKB_CB(skb);
        range = (void *)info->rate_driver_data;
-       if (skb->prev != (struct sk_buff *)&priv->tx_queue) {
+       if (!skb_queue_is_first(&priv->tx_queue, skb)) {
                struct ieee80211_tx_info *ni;
                struct p54_tx_info *mr;
 
-               ni = IEEE80211_SKB_CB(skb->prev);
+               ni = IEEE80211_SKB_CB(skb_queue_prev(&priv->tx_queue, skb));
                mr = (struct p54_tx_info *)ni->rate_driver_data;
-               last_addr = mr->end_addr;
        }
-       if (skb->next != (struct sk_buff *)&priv->tx_queue) {
+       if (!skb_queue_is_last(&priv->tx_queue, skb)) {
                struct ieee80211_tx_info *ni;
                struct p54_tx_info *mr;
 
-               ni = IEEE80211_SKB_CB(skb->next);
+               ni = IEEE80211_SKB_CB(skb_queue_next(&priv->tx_queue, skb));
                mr = (struct p54_tx_info *)ni->rate_driver_data;
-               freed = mr->start_addr - last_addr;
-       } else
-               freed = priv->rx_end - last_addr;
+       }
        __skb_unlink(skb, &priv->tx_queue);
        spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
        dev_kfree_skb_any(skb);
-
-       if (freed >= priv->headroom + sizeof(struct p54_hdr) + 48 +
-                    IEEE80211_MAX_RTS_THRESHOLD + priv->tailroom)
-               p54_wake_free_queues(dev);
+       p54_wake_free_queues(dev);
 }
 EXPORT_SYMBOL_GPL(p54_free_skb);
 
@@ -853,15 +864,13 @@ static struct sk_buff *p54_find_tx_entry(struct ieee80211_hw *dev,
        unsigned long flags;
 
        spin_lock_irqsave(&priv->tx_queue.lock, flags);
-       entry = priv->tx_queue.next;
-       while (entry != (struct sk_buff *)&priv->tx_queue) {
+       skb_queue_walk(&priv->tx_queue, entry) {
                struct p54_hdr *hdr = (struct p54_hdr *) entry->data;
 
                if (hdr->req_id == req_id) {
                        spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
                        return entry;
                }
-               entry = entry->next;
        }
        spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
        return NULL;
@@ -875,37 +884,29 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb)
        struct sk_buff *entry;
        u32 addr = le32_to_cpu(hdr->req_id) - priv->headroom;
        struct p54_tx_info *range = NULL;
-       u32 freed = 0;
-       u32 last_addr = priv->rx_start;
        unsigned long flags;
        int count, idx;
 
        spin_lock_irqsave(&priv->tx_queue.lock, flags);
-       entry = (struct sk_buff *) priv->tx_queue.next;
-       while (entry != (struct sk_buff *)&priv->tx_queue) {
+       skb_queue_walk(&priv->tx_queue, entry) {
                struct ieee80211_tx_info *info = IEEE80211_SKB_CB(entry);
                struct p54_hdr *entry_hdr;
                struct p54_tx_data *entry_data;
                unsigned int pad = 0, frame_len;
 
                range = (void *)info->rate_driver_data;
-               if (range->start_addr != addr) {
-                       last_addr = range->end_addr;
-                       entry = entry->next;
+               if (range->start_addr != addr)
                        continue;
-               }
 
-               if (entry->next != (struct sk_buff *)&priv->tx_queue) {
+               if (!skb_queue_is_last(&priv->tx_queue, entry)) {
                        struct ieee80211_tx_info *ni;
                        struct p54_tx_info *mr;
 
-                       ni = IEEE80211_SKB_CB(entry->next);
+                       ni = IEEE80211_SKB_CB(skb_queue_next(&priv->tx_queue,
+                                                            entry));
                        mr = (struct p54_tx_info *)ni->rate_driver_data;
-                       freed = mr->start_addr - last_addr;
-               } else
-                       freed = priv->rx_end - last_addr;
+               }
 
-               last_addr = range->end_addr;
                __skb_unlink(entry, &priv->tx_queue);
                spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
 
@@ -992,9 +993,7 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb)
        spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
 
 out:
-       if (freed >= priv->headroom + sizeof(struct p54_hdr) + 48 +
-                    IEEE80211_MAX_RTS_THRESHOLD + priv->tailroom)
-               p54_wake_free_queues(dev);
+       p54_wake_free_queues(dev);
 }
 
 static void p54_rx_eeprom_readback(struct ieee80211_hw *dev,
@@ -1044,6 +1043,7 @@ static void p54_rx_stats(struct ieee80211_hw *dev, struct sk_buff *skb)
 
 static void p54_rx_trap(struct ieee80211_hw *dev, struct sk_buff *skb)
 {
+       struct p54_common *priv = dev->priv;
        struct p54_hdr *hdr = (struct p54_hdr *) skb->data;
        struct p54_trap *trap = (struct p54_trap *) hdr->data;
        u16 event = le16_to_cpu(trap->event);
@@ -1057,6 +1057,8 @@ static void p54_rx_trap(struct ieee80211_hw *dev, struct sk_buff *skb)
                        wiphy_name(dev->wiphy), freq);
                break;
        case P54_TRAP_NO_BEACON:
+               if (priv->vif)
+                       ieee80211_beacon_loss(priv->vif);
                break;
        case P54_TRAP_SCAN:
                break;
@@ -1162,23 +1164,21 @@ static int p54_assign_address(struct ieee80211_hw *dev, struct sk_buff *skb,
                }
        }
 
-       entry = priv->tx_queue.next;
-       while (left--) {
+       skb_queue_walk(&priv->tx_queue, entry) {
                u32 hole_size;
                info = IEEE80211_SKB_CB(entry);
                range = (void *)info->rate_driver_data;
                hole_size = range->start_addr - last_addr;
                if (!target_skb && hole_size >= len) {
-                       target_skb = entry->prev;
+                       target_skb = skb_queue_prev(&priv->tx_queue, entry);
                        hole_size -= len;
                        target_addr = last_addr;
                }
                largest_hole = max(largest_hole, hole_size);
                last_addr = range->end_addr;
-               entry = entry->next;
        }
        if (!target_skb && priv->rx_end - last_addr >= len) {
-               target_skb = priv->tx_queue.prev;
+               target_skb = skb_peek_tail(&priv->tx_queue);
                largest_hole = max(largest_hole, priv->rx_end - last_addr - len);
                if (!skb_queue_empty(&priv->tx_queue)) {
                        info = IEEE80211_SKB_CB(target_skb);
@@ -1452,7 +1452,8 @@ static int p54_tx_fill(struct ieee80211_hw *dev, struct sk_buff *skb,
 
                if (info->control.sta)
                        *aid = info->control.sta->aid;
-               else
+
+               if (info->flags & IEEE80211_TX_CTL_CLEAR_PS_FILT)
                        *flags |= P54_HDR_FLAG_DATA_OUT_NOCANCEL;
                break;
        }
@@ -1939,7 +1940,8 @@ static int p54_set_ps(struct ieee80211_hw *dev)
        int i;
 
        if (dev->conf.flags & IEEE80211_CONF_PS)
-               mode = P54_PSM | P54_PSM_DTIM | P54_PSM_MCBC;
+               mode = P54_PSM | P54_PSM_BEACON_TIMEOUT | P54_PSM_DTIM |
+                      P54_PSM_CHECKSUM | P54_PSM_MCBC;
        else
                mode = P54_PSM_CAM;
 
@@ -1957,9 +1959,10 @@ static int p54_set_ps(struct ieee80211_hw *dev)
                psm->intervals[i].periods = cpu_to_le16(1);
        }
 
-       psm->beacon_rssi_skip_max = 60;
+       psm->beacon_rssi_skip_max = 200;
        psm->rssi_delta_threshold = 0;
-       psm->nr = 0;
+       psm->nr = 10;
+       psm->exclude[0] = 0;
 
        priv->tx(dev, skb);
 
@@ -2081,20 +2084,21 @@ out:
 static void p54_stop(struct ieee80211_hw *dev)
 {
        struct p54_common *priv = dev->priv;
-       struct sk_buff *skb;
 
        mutex_lock(&priv->conf_mutex);
        priv->mode = NL80211_IFTYPE_UNSPECIFIED;
        priv->softled_state = 0;
        p54_set_leds(dev);
 
+#ifdef CONFIG_P54_LEDS
+       cancel_delayed_work_sync(&priv->led_work);
+#endif /* CONFIG_P54_LEDS */
        cancel_delayed_work_sync(&priv->work);
        if (priv->cached_beacon)
                p54_tx_cancel(dev, priv->cached_beacon);
 
        priv->stop(dev);
-       while ((skb = skb_dequeue(&priv->tx_queue)))
-               kfree_skb(skb);
+       skb_queue_purge(&priv->tx_queue);
        priv->cached_beacon = NULL;
        priv->tsf_high32 = priv->tsf_low32 = 0;
        mutex_unlock(&priv->conf_mutex);
@@ -2111,6 +2115,8 @@ static int p54_add_interface(struct ieee80211_hw *dev,
                return -EOPNOTSUPP;
        }
 
+       priv->vif = conf->vif;
+
        switch (conf->type) {
        case NL80211_IFTYPE_STATION:
        case NL80211_IFTYPE_ADHOC:
@@ -2135,6 +2141,7 @@ static void p54_remove_interface(struct ieee80211_hw *dev,
        struct p54_common *priv = dev->priv;
 
        mutex_lock(&priv->conf_mutex);
+       priv->vif = NULL;
        if (priv->cached_beacon)
                p54_tx_cancel(dev, priv->cached_beacon);
        priv->mode = NL80211_IFTYPE_MONITOR;
@@ -2174,41 +2181,6 @@ out:
        return ret;
 }
 
-static int p54_config_interface(struct ieee80211_hw *dev,
-                               struct ieee80211_vif *vif,
-                               struct ieee80211_if_conf *conf)
-{
-       struct p54_common *priv = dev->priv;
-       int ret = 0;
-
-       mutex_lock(&priv->conf_mutex);
-       if (conf->changed & IEEE80211_IFCC_BSSID) {
-               memcpy(priv->bssid, conf->bssid, ETH_ALEN);
-               ret = p54_setup_mac(dev);
-               if (ret)
-                       goto out;
-       }
-
-       if (conf->changed & IEEE80211_IFCC_BEACON) {
-               ret = p54_scan(dev, P54_SCAN_EXIT, 0);
-               if (ret)
-                       goto out;
-               ret = p54_setup_mac(dev);
-               if (ret)
-                       goto out;
-               ret = p54_beacon_update(dev, vif);
-               if (ret)
-                       goto out;
-               ret = p54_set_edcf(dev);
-               if (ret)
-                       goto out;
-       }
-
-out:
-       mutex_unlock(&priv->conf_mutex);
-       return ret;
-}
-
 static void p54_configure_filter(struct ieee80211_hw *dev,
                                 unsigned int changed_flags,
                                 unsigned int *total_flags,
@@ -2312,8 +2284,32 @@ static void p54_bss_info_changed(struct ieee80211_hw *dev,
                                 u32 changed)
 {
        struct p54_common *priv = dev->priv;
+       int ret;
+
+       mutex_lock(&priv->conf_mutex);
+       if (changed & BSS_CHANGED_BSSID) {
+               memcpy(priv->bssid, info->bssid, ETH_ALEN);
+               ret = p54_setup_mac(dev);
+               if (ret)
+                       goto out;
+       }
+
+       if (changed & BSS_CHANGED_BEACON) {
+               ret = p54_scan(dev, P54_SCAN_EXIT, 0);
+               if (ret)
+                       goto out;
+               ret = p54_setup_mac(dev);
+               if (ret)
+                       goto out;
+               ret = p54_beacon_update(dev, vif);
+               if (ret)
+                       goto out;
+       }
+       /* XXX: this mimics having two callbacks... clean up */
+ out:
+       mutex_unlock(&priv->conf_mutex);
 
-       if (changed & BSS_CHANGED_ERP_SLOT) {
+       if (changed & (BSS_CHANGED_ERP_SLOT | BSS_CHANGED_BEACON)) {
                priv->use_short_slot = info->use_short_slot;
                p54_set_edcf(dev);
        }
@@ -2334,7 +2330,6 @@ static void p54_bss_info_changed(struct ieee80211_hw *dev,
                        p54_setup_mac(dev);
                }
        }
-
 }
 
 static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd,
@@ -2344,61 +2339,84 @@ static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd,
        struct p54_common *priv = dev->priv;
        struct sk_buff *skb;
        struct p54_keycache *rxkey;
+       int slot, ret = 0;
        u8 algo = 0;
 
        if (modparam_nohwcrypt)
                return -EOPNOTSUPP;
 
-       if (cmd == DISABLE_KEY)
-               algo = 0;
-       else {
+       mutex_lock(&priv->conf_mutex);
+       if (cmd == SET_KEY) {
                switch (key->alg) {
                case ALG_TKIP:
                        if (!(priv->privacy_caps & (BR_DESC_PRIV_CAP_MICHAEL |
-                             BR_DESC_PRIV_CAP_TKIP)))
-                               return -EOPNOTSUPP;
+                             BR_DESC_PRIV_CAP_TKIP))) {
+                               ret = -EOPNOTSUPP;
+                               goto out_unlock;
+                       }
                        key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
                        algo = P54_CRYPTO_TKIPMICHAEL;
                        break;
                case ALG_WEP:
-                       if (!(priv->privacy_caps & BR_DESC_PRIV_CAP_WEP))
-                               return -EOPNOTSUPP;
+                       if (!(priv->privacy_caps & BR_DESC_PRIV_CAP_WEP)) {
+                               ret = -EOPNOTSUPP;
+                               goto out_unlock;
+                       }
                        key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
                        algo = P54_CRYPTO_WEP;
                        break;
                case ALG_CCMP:
-                       if (!(priv->privacy_caps & BR_DESC_PRIV_CAP_AESCCMP))
-                               return -EOPNOTSUPP;
+                       if (!(priv->privacy_caps & BR_DESC_PRIV_CAP_AESCCMP)) {
+                               ret = -EOPNOTSUPP;
+                               goto out_unlock;
+                       }
                        key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
                        algo = P54_CRYPTO_AESCCMP;
                        break;
                default:
-                       return -EOPNOTSUPP;
+                       ret = -EOPNOTSUPP;
+                       goto out_unlock;
                }
-       }
+               slot = bitmap_find_free_region(priv->used_rxkeys,
+                                              priv->rx_keycache_size, 0);
 
-       if (key->keyidx > priv->rx_keycache_size) {
-               /*
-                * The device supports the choosen algorithm, but the firmware
-                * does not provide enough key slots to store all of them.
-                * So, incoming frames have to be decoded by the mac80211 stack,
-                * but we can still offload encryption for outgoing frames.
-                */
+               if (slot < 0) {
+                       /*
+                        * The device supports the choosen algorithm, but the
+                        * firmware does not provide enough key slots to store
+                        * all of them.
+                        * But encryption offload for outgoing frames is always
+                        * possible, so we just pretend that the upload was
+                        * successful and do the decryption in software.
+                        */
 
-               return 0;
+                       /* mark the key as invalid. */
+                       key->hw_key_idx = 0xff;
+                       goto out_unlock;
+               }
+       } else {
+               slot = key->hw_key_idx;
+
+               if (slot == 0xff) {
+                       /* This key was not uploaded into the rx key cache. */
+
+                       goto out_unlock;
+               }
+
+               bitmap_release_region(priv->used_rxkeys, slot, 0);
+               algo = 0;
        }
 
-       mutex_lock(&priv->conf_mutex);
        skb = p54_alloc_skb(dev, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*rxkey),
-                           P54_CONTROL_TYPE_RX_KEYCACHE, GFP_ATOMIC);
+                           P54_CONTROL_TYPE_RX_KEYCACHE, GFP_KERNEL);
        if (!skb) {
-               mutex_unlock(&priv->conf_mutex);
-               return -ENOMEM;
+               bitmap_release_region(priv->used_rxkeys, slot, 0);
+               ret = -ENOSPC;
+               goto out_unlock;
        }
 
-       /* TODO: some devices have 4 more free slots for rx keys */
        rxkey = (struct p54_keycache *)skb_put(skb, sizeof(*rxkey));
-       rxkey->entry = key->keyidx;
+       rxkey->entry = slot;
        rxkey->key_id = key->keyidx;
        rxkey->key_type = algo;
        if (sta)
@@ -2416,11 +2434,51 @@ static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd,
        }
 
        priv->tx(dev, skb);
+       key->hw_key_idx = slot;
+
+out_unlock:
        mutex_unlock(&priv->conf_mutex);
-       return 0;
+       return ret;
 }
 
 #ifdef CONFIG_P54_LEDS
+static void p54_update_leds(struct work_struct *work)
+{
+       struct p54_common *priv = container_of(work, struct p54_common,
+                                              led_work.work);
+       int err, i, tmp, blink_delay = 400;
+       bool rerun = false;
+
+       /* Don't toggle the LED, when the device is down. */
+       if (priv->mode == NL80211_IFTYPE_UNSPECIFIED)
+               return ;
+
+       for (i = 0; i < ARRAY_SIZE(priv->leds); i++)
+               if (priv->leds[i].toggled) {
+                       priv->softled_state |= BIT(i);
+
+                       tmp = 70 + 200 / (priv->leds[i].toggled);
+                       if (tmp < blink_delay)
+                               blink_delay = tmp;
+
+                       if (priv->leds[i].led_dev.brightness == LED_OFF)
+                               rerun = true;
+
+                       priv->leds[i].toggled =
+                               !!priv->leds[i].led_dev.brightness;
+               } else
+                       priv->softled_state &= ~BIT(i);
+
+       err = p54_set_leds(priv->hw);
+       if (err && net_ratelimit())
+               printk(KERN_ERR "%s: failed to update LEDs.\n",
+                       wiphy_name(priv->hw->wiphy));
+
+       if (rerun)
+               queue_delayed_work(priv->hw->workqueue, &priv->led_work,
+                       msecs_to_jiffies(blink_delay));
+}
+
 static void p54_led_brightness_set(struct led_classdev *led_dev,
                                   enum led_brightness brightness)
 {
@@ -2428,28 +2486,23 @@ static void p54_led_brightness_set(struct led_classdev *led_dev,
                                               led_dev);
        struct ieee80211_hw *dev = led->hw_dev;
        struct p54_common *priv = dev->priv;
-       int err;
 
-       /* Don't toggle the LED, when the device is down. */
        if (priv->mode == NL80211_IFTYPE_UNSPECIFIED)
                return ;
 
-       if (brightness != LED_OFF)
-               priv->softled_state |= BIT(led->index);
-       else
-               priv->softled_state &= ~BIT(led->index);
-
-       err = p54_set_leds(dev);
-       if (err && net_ratelimit())
-               printk(KERN_ERR "%s: failed to update %s LED.\n",
-                       wiphy_name(dev->wiphy), led_dev->name);
+       if (brightness) {
+               led->toggled++;
+               queue_delayed_work(priv->hw->workqueue, &priv->led_work,
+                                  HZ/10);
+       }
 }
 
 static int p54_register_led(struct ieee80211_hw *dev,
-                           struct p54_led_dev *led,
                            unsigned int led_index,
                            char *name, char *trigger)
 {
+       struct p54_common *priv = dev->priv;
+       struct p54_led_dev *led = &priv->leds[led_index];
        int err;
 
        if (led->registered)
@@ -2482,19 +2535,30 @@ static int p54_init_leds(struct ieee80211_hw *dev)
         * TODO:
         * Figure out if the EEPROM contains some hints about the number
         * of available/programmable LEDs of the device.
-        * But for now, we can assume that we have two programmable LEDs.
         */
 
-       err = p54_register_led(dev, &priv->assoc_led, 0, "assoc",
+       INIT_DELAYED_WORK(&priv->led_work, p54_update_leds);
+
+       err = p54_register_led(dev, 0, "assoc",
                               ieee80211_get_assoc_led_name(dev));
        if (err)
                return err;
 
-       err = p54_register_led(dev, &priv->tx_led, 1, "tx",
+       err = p54_register_led(dev, 1, "tx",
                               ieee80211_get_tx_led_name(dev));
        if (err)
                return err;
 
+       err = p54_register_led(dev, 2, "rx",
+                              ieee80211_get_rx_led_name(dev));
+       if (err)
+               return err;
+
+       err = p54_register_led(dev, 3, "radio",
+                              ieee80211_get_radio_led_name(dev));
+       if (err)
+               return err;
+
        err = p54_set_leds(dev);
        return err;
 }
@@ -2502,11 +2566,11 @@ static int p54_init_leds(struct ieee80211_hw *dev)
 static void p54_unregister_leds(struct ieee80211_hw *dev)
 {
        struct p54_common *priv = dev->priv;
+       int i;
 
-       if (priv->tx_led.registered)
-               led_classdev_unregister(&priv->tx_led.led_dev);
-       if (priv->assoc_led.registered)
-               led_classdev_unregister(&priv->assoc_led.led_dev);
+       for (i = 0; i < ARRAY_SIZE(priv->leds); i++)
+               if (priv->leds[i].registered)
+                       led_classdev_unregister(&priv->leds[i].led_dev);
 }
 #endif /* CONFIG_P54_LEDS */
 
@@ -2520,7 +2584,6 @@ static const struct ieee80211_ops p54_ops = {
        .sta_notify             = p54_sta_notify,
        .set_key                = p54_set_key,
        .config                 = p54_config,
-       .config_interface       = p54_config_interface,
        .bss_info_changed       = p54_bss_info_changed,
        .configure_filter       = p54_configure_filter,
        .conf_tx                = p54_conf_tx,
@@ -2607,21 +2670,10 @@ void p54_free_common(struct ieee80211_hw *dev)
        kfree(priv->iq_autocal);
        kfree(priv->output_limit);
        kfree(priv->curve_data);
+       kfree(priv->used_rxkeys);
 
 #ifdef CONFIG_P54_LEDS
        p54_unregister_leds(dev);
 #endif /* CONFIG_P54_LEDS */
 }
 EXPORT_SYMBOL_GPL(p54_free_common);
-
-static int __init p54_init(void)
-{
-       return 0;
-}
-
-static void __exit p54_exit(void)
-{
-}
-
-module_init(p54_init);
-module_exit(p54_exit);
index d1fe577de3d4de3b8694a6f9002452a0e9da0e57..83116baeb110082b2f94e3bb40186f8e98f97ad8 100644 (file)
@@ -96,7 +96,7 @@ static void p54spi_spi_write(struct p54s_priv *priv, u8 address,
        spi_message_add_tail(&t[0], &m);
 
        t[1].tx_buf = buf;
-       t[1].len = len;
+       t[1].len = len & ~1;
        spi_message_add_tail(&t[1], &m);
 
        if (len % 2) {
@@ -167,15 +167,31 @@ static const struct p54spi_spi_reg p54spi_registers_array[] =
 static int p54spi_wait_bit(struct p54s_priv *priv, u16 reg, __le32 bits)
 {
        int i;
-       __le32 buffer;
 
        for (i = 0; i < 2000; i++) {
-               p54spi_spi_read(priv, reg, &buffer, sizeof(buffer));
-               if (buffer == bits)
+               __le32 buffer = p54spi_read32(priv, reg);
+               if ((buffer & bits) == bits)
                        return 1;
+       }
+       return 0;
+}
 
-               msleep(1);
+static int p54spi_spi_write_dma(struct p54s_priv *priv, __le32 base,
+                               const void *buf, size_t len)
+{
+       if (!p54spi_wait_bit(priv, SPI_ADRS_DMA_WRITE_CTRL,
+                            cpu_to_le32(HOST_ALLOWED))) {
+               dev_err(&priv->spi->dev, "spi_write_dma not allowed "
+                       "to DMA write.\n");
+               return -EAGAIN;
        }
+
+       p54spi_write16(priv, SPI_ADRS_DMA_WRITE_CTRL,
+                      cpu_to_le16(SPI_DMA_WRITE_CTRL_ENABLE));
+
+       p54spi_write16(priv, SPI_ADRS_DMA_WRITE_LEN, cpu_to_le16(len));
+       p54spi_write32(priv, SPI_ADRS_DMA_WRITE_BASE, base);
+       p54spi_spi_write(priv, SPI_ADRS_DMA_DATA, buf, len);
        return 0;
 }
 
@@ -228,8 +244,15 @@ static int p54spi_request_eeprom(struct ieee80211_hw *dev)
 static int p54spi_upload_firmware(struct ieee80211_hw *dev)
 {
        struct p54s_priv *priv = dev->priv;
-       unsigned long fw_len, fw_addr;
-       long _fw_len;
+       unsigned long fw_len, _fw_len;
+       unsigned int offset = 0;
+       int err = 0;
+       u8 *fw;
+
+       fw_len = priv->firmware->size;
+       fw = kmemdup(priv->firmware->data, fw_len, GFP_KERNEL);
+       if (!fw)
+               return -ENOMEM;
 
        /* stop the device */
        p54spi_write16(priv, SPI_ADRS_DEV_CTRL_STAT, cpu_to_le16(
@@ -244,36 +267,17 @@ static int p54spi_upload_firmware(struct ieee80211_hw *dev)
 
        msleep(TARGET_BOOT_SLEEP);
 
-       fw_addr = ISL38XX_DEV_FIRMWARE_ADDR;
-       fw_len = priv->firmware->size;
-
        while (fw_len > 0) {
                _fw_len = min_t(long, fw_len, SPI_MAX_PACKET_SIZE);
 
-               p54spi_write16(priv, SPI_ADRS_DMA_WRITE_CTRL,
-                              cpu_to_le16(SPI_DMA_WRITE_CTRL_ENABLE));
-
-               if (p54spi_wait_bit(priv, SPI_ADRS_DMA_WRITE_CTRL,
-                                   cpu_to_le32(HOST_ALLOWED)) == 0) {
-                       dev_err(&priv->spi->dev, "fw_upload not allowed "
-                               "to DMA write.");
-                       return -EAGAIN;
-               }
-
-               p54spi_write16(priv, SPI_ADRS_DMA_WRITE_LEN,
-                              cpu_to_le16(_fw_len));
-               p54spi_write32(priv, SPI_ADRS_DMA_WRITE_BASE,
-                              cpu_to_le32(fw_addr));
-
-               p54spi_spi_write(priv, SPI_ADRS_DMA_DATA,
-                                &priv->firmware->data, _fw_len);
+               err = p54spi_spi_write_dma(priv, cpu_to_le32(
+                                          ISL38XX_DEV_FIRMWARE_ADDR + offset),
+                                          (fw + offset), _fw_len);
+               if (err < 0)
+                       goto out;
 
                fw_len -= _fw_len;
-               fw_addr += _fw_len;
-
-               /* FIXME: I think this doesn't work if firmware is large,
-                * this loop goes to second round. fw->data is not
-                * increased at all! */
+               offset += _fw_len;
        }
 
        BUG_ON(fw_len != 0);
@@ -292,7 +296,10 @@ static int p54spi_upload_firmware(struct ieee80211_hw *dev)
        p54spi_write16(priv, SPI_ADRS_DEV_CTRL_STAT, cpu_to_le16(
                       SPI_CTRL_STAT_HOST_OVERRIDE | SPI_CTRL_STAT_RAM_BOOT));
        msleep(TARGET_BOOT_SLEEP);
-       return 0;
+
+out:
+       kfree(fw);
+       return err;
 }
 
 static void p54spi_power_off(struct p54s_priv *priv)
@@ -318,29 +325,21 @@ static inline void p54spi_int_ack(struct p54s_priv *priv, u32 val)
        p54spi_write32(priv, SPI_ADRS_HOST_INT_ACK, cpu_to_le32(val));
 }
 
-static void p54spi_wakeup(struct p54s_priv *priv)
+static int p54spi_wakeup(struct p54s_priv *priv)
 {
-       unsigned long timeout;
-       u32 ints;
-
        /* wake the chip */
        p54spi_write32(priv, SPI_ADRS_ARM_INTERRUPTS,
                       cpu_to_le32(SPI_TARGET_INT_WAKEUP));
 
        /* And wait for the READY interrupt */
-       timeout = jiffies + HZ;
-
-       ints =  p54spi_read32(priv, SPI_ADRS_HOST_INTERRUPTS);
-       while (!(ints & SPI_HOST_INT_READY)) {
-               if (time_after(jiffies, timeout))
-                               goto out;
-               ints = p54spi_read32(priv, SPI_ADRS_HOST_INTERRUPTS);
+       if (!p54spi_wait_bit(priv, SPI_ADRS_HOST_INTERRUPTS,
+                            cpu_to_le32(SPI_HOST_INT_READY))) {
+               dev_err(&priv->spi->dev, "INT_READY timeout\n");
+               return -EBUSY;
        }
 
        p54spi_int_ack(priv, SPI_HOST_INT_READY);
-
-out:
-       return;
+       return 0;
 }
 
 static inline void p54spi_sleep(struct p54s_priv *priv)
@@ -372,27 +371,48 @@ static int p54spi_rx(struct p54s_priv *priv)
 {
        struct sk_buff *skb;
        u16 len;
+       u16 rx_head[2];
+#define READAHEAD_SZ (sizeof(rx_head)-sizeof(u16))
 
-       p54spi_wakeup(priv);
-
-       /* dummy read to flush SPI DMA controller bug */
-       p54spi_read16(priv, SPI_ADRS_GEN_PURP_1);
+       if (p54spi_wakeup(priv) < 0)
+               return -EBUSY;
 
-       len = p54spi_read16(priv, SPI_ADRS_DMA_DATA);
+       /* Read data size and first data word in one SPI transaction
+        * This is workaround for firmware/DMA bug,
+        * when first data word gets lost under high load.
+        */
+       p54spi_spi_read(priv, SPI_ADRS_DMA_DATA, rx_head, sizeof(rx_head));
+       len = rx_head[0];
 
        if (len == 0) {
-               dev_err(&priv->spi->dev, "rx request of zero bytes");
+               p54spi_sleep(priv);
+               dev_err(&priv->spi->dev, "rx request of zero bytes\n");
                return 0;
        }
 
-       skb = dev_alloc_skb(len);
+       /* Firmware may insert up to 4 padding bytes after the lmac header,
+        * but it does not amend the size of SPI data transfer.
+        * Such packets has correct data size in header, thus referencing
+        * past the end of allocated skb. Reserve extra 4 bytes for this case */
+       skb = dev_alloc_skb(len + 4);
        if (!skb) {
+               p54spi_sleep(priv);
                dev_err(&priv->spi->dev, "could not alloc skb");
-               return 0;
+               return -ENOMEM;
        }
 
-       p54spi_spi_read(priv, SPI_ADRS_DMA_DATA, skb_put(skb, len), len);
+       if (len <= READAHEAD_SZ) {
+               memcpy(skb_put(skb, len), rx_head + 1, len);
+       } else {
+               memcpy(skb_put(skb, READAHEAD_SZ), rx_head + 1, READAHEAD_SZ);
+               p54spi_spi_read(priv, SPI_ADRS_DMA_DATA,
+                               skb_put(skb, len - READAHEAD_SZ),
+                               len - READAHEAD_SZ);
+       }
        p54spi_sleep(priv);
+       /* Put additional bytes to compensate for the possible
+        * alignment-caused truncation */
+       skb_put(skb, 4);
 
        if (p54_rx(priv->hw, skb) == 0)
                dev_kfree_skb(skb);
@@ -414,39 +434,28 @@ static irqreturn_t p54spi_interrupt(int irq, void *config)
 static int p54spi_tx_frame(struct p54s_priv *priv, struct sk_buff *skb)
 {
        struct p54_hdr *hdr = (struct p54_hdr *) skb->data;
-       struct p54s_dma_regs dma_regs;
-       unsigned long timeout;
        int ret = 0;
-       u32 ints;
-
-       p54spi_wakeup(priv);
 
-       dma_regs.cmd = cpu_to_le16(SPI_DMA_WRITE_CTRL_ENABLE);
-       dma_regs.len = cpu_to_le16(skb->len);
-       dma_regs.addr = hdr->req_id;
+       if (p54spi_wakeup(priv) < 0)
+               return -EBUSY;
 
-       p54spi_spi_write(priv, SPI_ADRS_DMA_WRITE_CTRL, &dma_regs,
-                          sizeof(dma_regs));
-
-       p54spi_spi_write(priv, SPI_ADRS_DMA_DATA, skb->data, skb->len);
+       ret = p54spi_spi_write_dma(priv, hdr->req_id, skb->data, skb->len);
+       if (ret < 0)
+               goto out;
 
-       timeout = jiffies + 2 * HZ;
-       ints = p54spi_read32(priv, SPI_ADRS_HOST_INTERRUPTS);
-       while (!(ints & SPI_HOST_INT_WR_READY)) {
-               if (time_after(jiffies, timeout)) {
-                       dev_err(&priv->spi->dev, "WR_READY timeout");
-                       ret = -1;
-                       goto out;
-               }
-               ints = p54spi_read32(priv, SPI_ADRS_HOST_INTERRUPTS);
+       if (!p54spi_wait_bit(priv, SPI_ADRS_HOST_INTERRUPTS,
+                            cpu_to_le32(SPI_HOST_INT_WR_READY))) {
+               dev_err(&priv->spi->dev, "WR_READY timeout\n");
+               ret = -EAGAIN;
+               goto out;
        }
 
        p54spi_int_ack(priv, SPI_HOST_INT_WR_READY);
-       p54spi_sleep(priv);
 
-out:
        if (FREE_AFTER_TX(skb))
                p54_free_skb(priv->hw, skb);
+out:
+       p54spi_sleep(priv);
        return ret;
 }
 
@@ -516,8 +525,7 @@ static void p54spi_work(struct work_struct *work)
 
        mutex_lock(&priv->mutex);
 
-       if (priv->fw_state == FW_STATE_OFF &&
-           priv->fw_state == FW_STATE_RESET)
+       if (priv->fw_state == FW_STATE_OFF)
                goto out;
 
        ints = p54spi_read32(priv, SPI_ADRS_HOST_INTERRUPTS);
@@ -544,11 +552,6 @@ static void p54spi_work(struct work_struct *work)
        }
 
        ret = p54spi_wq_tx(priv);
-       if (ret < 0)
-               goto out;
-
-       ints = p54spi_read32(priv, SPI_ADRS_HOST_INTERRUPTS);
-
 out:
        mutex_unlock(&priv->mutex);
 }
index 6cc6cbc9234fb52439a8dd8c044516e4d50f5585..0e877a104a89f0f92955567b1be1688fbeca569d 100644 (file)
@@ -81,6 +81,29 @@ static struct usb_device_id p54u_table[] __devinitdata = {
 
 MODULE_DEVICE_TABLE(usb, p54u_table);
 
+static const struct {
+       u32 intf;
+       enum p54u_hw_type type;
+       const char *fw;
+       const char *fw_legacy;
+       char hw[20];
+} p54u_fwlist[__NUM_P54U_HWTYPES] = {
+       {
+               .type = P54U_NET2280,
+               .intf = FW_LM86,
+               .fw = "isl3886usb",
+               .fw_legacy = "isl3890usb",
+               .hw = "ISL3886 + net2280",
+       },
+       {
+               .type = P54U_3887,
+               .intf = FW_LM87,
+               .fw = "isl3887usb",
+               .fw_legacy = "isl3887usb_bare",
+               .hw = "ISL3887",
+       },
+};
+
 static void p54u_rx_cb(struct urb *urb)
 {
        struct sk_buff *skb = (struct sk_buff *) urb->context;
@@ -125,11 +148,7 @@ static void p54u_rx_cb(struct urb *urb)
                }
                skb_reset_tail_pointer(skb);
                skb_trim(skb, 0);
-               if (urb->transfer_buffer != skb_tail_pointer(skb)) {
-                       /* this should not happen */
-                       WARN_ON(1);
-                       urb->transfer_buffer = skb_tail_pointer(skb);
-               }
+               urb->transfer_buffer = skb_tail_pointer(skb);
        }
        skb_queue_tail(&priv->rx_queue, skb);
        usb_anchor_urb(urb, &priv->submitted);
@@ -206,53 +225,6 @@ static int p54u_init_urbs(struct ieee80211_hw *dev)
        return ret;
 }
 
-static void p54u_tx_3887(struct ieee80211_hw *dev, struct sk_buff *skb)
-{
-       struct p54u_priv *priv = dev->priv;
-       struct urb *addr_urb, *data_urb;
-       int err = 0;
-
-       addr_urb = usb_alloc_urb(0, GFP_ATOMIC);
-       if (!addr_urb)
-               return;
-
-       data_urb = usb_alloc_urb(0, GFP_ATOMIC);
-       if (!data_urb) {
-               usb_free_urb(addr_urb);
-               return;
-       }
-
-       usb_fill_bulk_urb(addr_urb, priv->udev,
-                         usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA),
-                         &((struct p54_hdr *)skb->data)->req_id, 4,
-                         p54u_tx_dummy_cb, dev);
-       usb_fill_bulk_urb(data_urb, priv->udev,
-                         usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA),
-                         skb->data, skb->len, FREE_AFTER_TX(skb) ?
-                         p54u_tx_cb : p54u_tx_dummy_cb, skb);
-       addr_urb->transfer_flags |= URB_ZERO_PACKET;
-       data_urb->transfer_flags |= URB_ZERO_PACKET;
-
-       usb_anchor_urb(addr_urb, &priv->submitted);
-       err = usb_submit_urb(addr_urb, GFP_ATOMIC);
-       if (err) {
-               usb_unanchor_urb(addr_urb);
-               goto out;
-       }
-
-       usb_anchor_urb(data_urb, &priv->submitted);
-       err = usb_submit_urb(data_urb, GFP_ATOMIC);
-       if (err)
-               usb_unanchor_urb(data_urb);
-
- out:
-       usb_free_urb(addr_urb);
-       usb_free_urb(data_urb);
-
-       if (err)
-               p54_free_skb(dev, skb);
-}
-
 static __le32 p54u_lm87_chksum(const __le32 *data, size_t length)
 {
        u32 chk = 0;
@@ -425,20 +397,16 @@ static int p54u_bulk_msg(struct p54u_priv *priv, unsigned int ep,
                            data, len, &alen, 2000);
 }
 
-static const char p54u_romboot_3887[] = "~~~~";
-static const char p54u_firmware_upload_3887[] = "<\r";
-
-static int p54u_device_reset_3887(struct ieee80211_hw *dev)
+static int p54u_device_reset(struct ieee80211_hw *dev)
 {
        struct p54u_priv *priv = dev->priv;
        int ret, lock = (priv->intf->condition != USB_INTERFACE_BINDING);
-       u8 buf[4];
 
        if (lock) {
                ret = usb_lock_device_for_reset(priv->udev, priv->intf);
                if (ret < 0) {
                        dev_err(&priv->udev->dev, "(p54usb) unable to lock "
-                               " device for reset: %d\n", ret);
+                               "device for reset (%d)!\n", ret);
                        return ret;
                }
        }
@@ -447,26 +415,34 @@ static int p54u_device_reset_3887(struct ieee80211_hw *dev)
        if (lock)
                usb_unlock_device(priv->udev);
 
-       if (ret) {
+       if (ret)
                dev_err(&priv->udev->dev, "(p54usb) unable to reset "
-                       "device: %d\n", ret);
-               return ret;
-       }
+                       "device (%d)!\n", ret);
+
+       return ret;
+}
+
+static const char p54u_romboot_3887[] = "~~~~";
+static int p54u_firmware_reset_3887(struct ieee80211_hw *dev)
+{
+       struct p54u_priv *priv = dev->priv;
+       u8 buf[4];
+       int ret;
 
        memcpy(&buf, p54u_romboot_3887, sizeof(buf));
        ret = p54u_bulk_msg(priv, P54U_PIPE_DATA,
                            buf, sizeof(buf));
        if (ret)
                dev_err(&priv->udev->dev, "(p54usb) unable to jump to "
-                       "boot ROM: %d\n", ret);
+                       "boot ROM (%d)!\n", ret);
 
        return ret;
 }
 
+static const char p54u_firmware_upload_3887[] = "<\r";
 static int p54u_upload_firmware_3887(struct ieee80211_hw *dev)
 {
        struct p54u_priv *priv = dev->priv;
-       const struct firmware *fw_entry = NULL;
        int err, alen;
        u8 carry = 0;
        u8 *buf, *tmp;
@@ -475,51 +451,29 @@ static int p54u_upload_firmware_3887(struct ieee80211_hw *dev)
        struct x2_header *hdr;
        unsigned long timeout;
 
+       err = p54u_firmware_reset_3887(dev);
+       if (err)
+               return err;
+
        tmp = buf = kmalloc(P54U_FW_BLOCK, GFP_KERNEL);
        if (!buf) {
                dev_err(&priv->udev->dev, "(p54usb) cannot allocate firmware"
                                          "upload buffer!\n");
-               err = -ENOMEM;
-               goto err_bufalloc;
-       }
-
-       err = p54u_device_reset_3887(dev);
-       if (err)
-               goto err_reset;
-
-       err = request_firmware(&fw_entry, "isl3887usb", &priv->udev->dev);
-       if (err) {
-               dev_err(&priv->udev->dev, "p54usb: cannot find firmware "
-                                         "(isl3887usb)\n");
-               err = request_firmware(&fw_entry, "isl3887usb_bare",
-                       &priv->udev->dev);
-               if (err)
-                       goto err_req_fw_failed;
-       }
-
-       err = p54_parse_firmware(dev, fw_entry);
-       if (err)
-               goto err_upload_failed;
-
-       if (priv->common.fw_interface != FW_LM87) {
-               dev_err(&priv->udev->dev, "wrong firmware, "
-                       "please get a LM87 firmware and try again.\n");
-               err = -EINVAL;
-               goto err_upload_failed;
+               return -ENOMEM;
        }
 
-       left = block_size = min((size_t)P54U_FW_BLOCK, fw_entry->size);
+       left = block_size = min((size_t)P54U_FW_BLOCK, priv->fw->size);
        strcpy(buf, p54u_firmware_upload_3887);
        left -= strlen(p54u_firmware_upload_3887);
        tmp += strlen(p54u_firmware_upload_3887);
 
-       data = fw_entry->data;
-       remains = fw_entry->size;
+       data = priv->fw->data;
+       remains = priv->fw->size;
 
        hdr = (struct x2_header *)(buf + strlen(p54u_firmware_upload_3887));
        memcpy(hdr->signature, X2_SIGNATURE, X2_SIGNATURE_SIZE);
        hdr->fw_load_addr = cpu_to_le32(ISL38XX_DEV_FIRMWARE_ADDR);
-       hdr->fw_length = cpu_to_le32(fw_entry->size);
+       hdr->fw_length = cpu_to_le32(priv->fw->size);
        hdr->crc = cpu_to_le32(~crc32_le(~0, (void *)&hdr->fw_load_addr,
                                         sizeof(u32)*2));
        left -= sizeof(*hdr);
@@ -561,7 +515,8 @@ static int p54u_upload_firmware_3887(struct ieee80211_hw *dev)
                left = block_size = min((unsigned int)P54U_FW_BLOCK, remains);
        }
 
-       *((__le32 *)buf) = cpu_to_le32(~crc32_le(~0, fw_entry->data, fw_entry->size));
+       *((__le32 *)buf) = cpu_to_le32(~crc32_le(~0, priv->fw->data,
+                                                priv->fw->size));
        err = p54u_bulk_msg(priv, P54U_PIPE_DATA, buf, sizeof(u32));
        if (err) {
                dev_err(&priv->udev->dev, "(p54usb) firmware upload failed!\n");
@@ -612,19 +567,14 @@ static int p54u_upload_firmware_3887(struct ieee80211_hw *dev)
        if (err)
                goto err_upload_failed;
 
-  err_upload_failed:
-       release_firmware(fw_entry);
-  err_req_fw_failed:
-  err_reset:
+err_upload_failed:
        kfree(buf);
-  err_bufalloc:
        return err;
 }
 
 static int p54u_upload_firmware_net2280(struct ieee80211_hw *dev)
 {
        struct p54u_priv *priv = dev->priv;
-       const struct firmware *fw_entry = NULL;
        const struct p54p_csr *devreg = (const struct p54p_csr *) P54U_DEV_BASE;
        int err, alen;
        void *buf;
@@ -639,33 +589,6 @@ static int p54u_upload_firmware_net2280(struct ieee80211_hw *dev)
                return -ENOMEM;
        }
 
-       err = request_firmware(&fw_entry, "isl3886usb", &priv->udev->dev);
-       if (err) {
-               dev_err(&priv->udev->dev, "(p54usb) cannot find firmware "
-                                         "(isl3886usb)\n");
-               err = request_firmware(&fw_entry, "isl3890usb",
-                       &priv->udev->dev);
-               if (err) {
-                       kfree(buf);
-                       return err;
-                       }
-       }
-
-       err = p54_parse_firmware(dev, fw_entry);
-       if (err) {
-               kfree(buf);
-               release_firmware(fw_entry);
-               return err;
-       }
-
-       if (priv->common.fw_interface != FW_LM86) {
-               dev_err(&priv->udev->dev, "wrong firmware, "
-                       "please get a LM86(USB) firmware and try again.\n");
-               kfree(buf);
-               release_firmware(fw_entry);
-               return -EINVAL;
-       }
-
 #define P54U_WRITE(type, addr, data) \
        do {\
                err = p54u_write(priv, buf, type,\
@@ -765,8 +688,8 @@ static int p54u_upload_firmware_net2280(struct ieee80211_hw *dev)
        P54U_WRITE(NET2280_DEV_U32, &devreg->int_ack, reg);
 
        /* finally, we can upload firmware now! */
-       remains = fw_entry->size;
-       data = fw_entry->data;
+       remains = priv->fw->size;
+       data = priv->fw->data;
        offset = ISL38XX_DEV_FIRMWARE_ADDR;
 
        while (remains) {
@@ -875,12 +798,54 @@ static int p54u_upload_firmware_net2280(struct ieee80211_hw *dev)
 #undef P54U_WRITE
 #undef P54U_READ
 
- fail:
-       release_firmware(fw_entry);
+fail:
        kfree(buf);
        return err;
 }
 
+static int p54u_load_firmware(struct ieee80211_hw *dev)
+{
+       struct p54u_priv *priv = dev->priv;
+       int err, i;
+
+       BUILD_BUG_ON(ARRAY_SIZE(p54u_fwlist) != __NUM_P54U_HWTYPES);
+
+       for (i = 0; i < __NUM_P54U_HWTYPES; i++)
+               if (p54u_fwlist[i].type == priv->hw_type)
+                       break;
+
+       if (i == __NUM_P54U_HWTYPES)
+               return -EOPNOTSUPP;
+
+       err = request_firmware(&priv->fw, p54u_fwlist[i].fw, &priv->udev->dev);
+       if (err) {
+               dev_err(&priv->udev->dev, "(p54usb) cannot load firmware %s "
+                                         "(%d)!\n", p54u_fwlist[i].fw, err);
+
+               err = request_firmware(&priv->fw, p54u_fwlist[i].fw_legacy,
+                                      &priv->udev->dev);
+               if (err)
+                       return err;
+       }
+
+       err = p54_parse_firmware(dev, priv->fw);
+       if (err)
+               goto out;
+
+       if (priv->common.fw_interface != p54u_fwlist[i].intf) {
+               dev_err(&priv->udev->dev, "wrong firmware, please get "
+                       "a firmware for \"%s\" and try again.\n",
+                       p54u_fwlist[i].hw);
+               err = -EINVAL;
+       }
+
+out:
+       if (err)
+               release_firmware(priv->fw);
+
+       return err;
+}
+
 static int p54u_open(struct ieee80211_hw *dev)
 {
        struct p54u_priv *priv = dev->priv;
@@ -922,6 +887,7 @@ static int __devinit p54u_probe(struct usb_interface *intf,
        }
 
        priv = dev->priv;
+       priv->hw_type = P54U_INVALID_HW;
 
        SET_IEEE80211_DEV(dev, &intf->dev);
        usb_set_intfdata(intf, dev);
@@ -953,37 +919,48 @@ static int __devinit p54u_probe(struct usb_interface *intf,
        priv->common.open = p54u_open;
        priv->common.stop = p54u_stop;
        if (recognized_pipes < P54U_PIPE_NUMBER) {
+#ifdef CONFIG_PM
+               /* ISL3887 needs a full reset on resume */
+               udev->reset_resume = 1;
+               err = p54u_device_reset(dev);
+#endif
+
                priv->hw_type = P54U_3887;
-               err = p54u_upload_firmware_3887(dev);
-               if (priv->common.fw_interface == FW_LM87) {
-                       dev->extra_tx_headroom += sizeof(struct lm87_tx_hdr);
-                       priv->common.tx_hdr_len = sizeof(struct lm87_tx_hdr);
-                       priv->common.tx = p54u_tx_lm87;
-               } else
-                       priv->common.tx = p54u_tx_3887;
+               dev->extra_tx_headroom += sizeof(struct lm87_tx_hdr);
+               priv->common.tx_hdr_len = sizeof(struct lm87_tx_hdr);
+               priv->common.tx = p54u_tx_lm87;
+               priv->upload_fw = p54u_upload_firmware_3887;
        } else {
                priv->hw_type = P54U_NET2280;
                dev->extra_tx_headroom += sizeof(struct net2280_tx_hdr);
                priv->common.tx_hdr_len = sizeof(struct net2280_tx_hdr);
                priv->common.tx = p54u_tx_net2280;
-               err = p54u_upload_firmware_net2280(dev);
+               priv->upload_fw = p54u_upload_firmware_net2280;
        }
+       err = p54u_load_firmware(dev);
        if (err)
                goto err_free_dev;
 
+       err = priv->upload_fw(dev);
+       if (err)
+               goto err_free_fw;
+
        p54u_open(dev);
        err = p54_read_eeprom(dev);
        p54u_stop(dev);
        if (err)
-               goto err_free_dev;
+               goto err_free_fw;
 
        err = p54_register_common(dev, &udev->dev);
        if (err)
-               goto err_free_dev;
+               goto err_free_fw;
 
        return 0;
 
- err_free_dev:
+err_free_fw:
+       release_firmware(priv->fw);
+
+err_free_dev:
        ieee80211_free_hw(dev);
        usb_set_intfdata(intf, NULL);
        usb_put_dev(udev);
@@ -1002,20 +979,64 @@ static void __devexit p54u_disconnect(struct usb_interface *intf)
 
        priv = dev->priv;
        usb_put_dev(interface_to_usbdev(intf));
+       release_firmware(priv->fw);
        p54_free_common(dev);
        ieee80211_free_hw(dev);
 }
 
 static int p54u_pre_reset(struct usb_interface *intf)
 {
+       struct ieee80211_hw *dev = usb_get_intfdata(intf);
+
+       if (!dev)
+               return -ENODEV;
+
+       p54u_stop(dev);
        return 0;
 }
 
+static int p54u_resume(struct usb_interface *intf)
+{
+       struct ieee80211_hw *dev = usb_get_intfdata(intf);
+       struct p54u_priv *priv;
+
+       if (!dev)
+               return -ENODEV;
+
+       priv = dev->priv;
+       if (unlikely(!(priv->upload_fw && priv->fw)))
+               return 0;
+
+       return priv->upload_fw(dev);
+}
+
 static int p54u_post_reset(struct usb_interface *intf)
 {
+       struct ieee80211_hw *dev = usb_get_intfdata(intf);
+       struct p54u_priv *priv;
+       int err;
+
+       err = p54u_resume(intf);
+       if (err)
+               return err;
+
+       /* reinitialize old device state */
+       priv = dev->priv;
+       if (priv->common.mode != NL80211_IFTYPE_UNSPECIFIED)
+               ieee80211_restart_hw(dev);
+
        return 0;
 }
 
+#ifdef CONFIG_PM
+
+static int p54u_suspend(struct usb_interface *intf, pm_message_t message)
+{
+       return p54u_pre_reset(intf);
+}
+
+#endif /* CONFIG_PM */
+
 static struct usb_driver p54u_driver = {
        .name   = "p54usb",
        .id_table = p54u_table,
@@ -1023,6 +1044,11 @@ static struct usb_driver p54u_driver = {
        .disconnect = p54u_disconnect,
        .pre_reset = p54u_pre_reset,
        .post_reset = p54u_post_reset,
+#ifdef CONFIG_PM
+       .suspend = p54u_suspend,
+       .resume = p54u_resume,
+       .reset_resume = p54u_resume,
+#endif /* CONFIG_PM */
        .soft_unbind = 1,
 };
 
index 8bc58982d8dd703ea3478882920dd1adcae68d71..e935b79f7f7569cb1b33399acc9822dd6ff31a2c 100644 (file)
@@ -123,18 +123,26 @@ struct p54u_rx_info {
        struct ieee80211_hw *dev;
 };
 
+enum p54u_hw_type {
+       P54U_INVALID_HW,
+       P54U_NET2280,
+       P54U_3887,
+
+       /* keep last */
+       __NUM_P54U_HWTYPES,
+};
+
 struct p54u_priv {
        struct p54_common common;
        struct usb_device *udev;
        struct usb_interface *intf;
-       enum {
-               P54U_NET2280 = 0,
-               P54U_3887
-       } hw_type;
+       int (*upload_fw)(struct ieee80211_hw *dev);
 
+       enum p54u_hw_type hw_type;
        spinlock_t lock;
        struct sk_buff_head rx_queue;
        struct usb_anchor submitted;
+       const struct firmware *fw;
 };
 
 #endif /* P54USB_H */
index ef3ef4551b31af3c797b54dcfa4906f5bb722f9b..8f6210993448db6d69b26b02bd5100dd52a73a12 100644 (file)
@@ -87,7 +87,6 @@ islpci_eth_transmit(struct sk_buff *skb, struct net_device *ndev)
        unsigned long flags;
        unsigned char wds_mac[6];
        u32 curr_frag;
-       int err = 0;
 
 #if VERBOSE > SHOW_ERROR_MESSAGES
        DEBUG(SHOW_FUNCTION_CALLS, "islpci_eth_transmit \n");
@@ -107,8 +106,6 @@ islpci_eth_transmit(struct sk_buff *skb, struct net_device *ndev)
                isl38xx_w32_flush(priv->device_base, ISL38XX_DEV_INT_UPDATE,
                                  ISL38XX_DEV_INT_REG);
                udelay(ISL38XX_WRITEIO_DELAY);
-
-               err = -EBUSY;
                goto drop_free;
        }
        /* Check alignment and WDS frame formatting. The start of the packet should
@@ -152,7 +149,6 @@ islpci_eth_transmit(struct sk_buff *skb, struct net_device *ndev)
                        if (unlikely(newskb == NULL)) {
                                printk(KERN_ERR "%s: Cannot allocate skb\n",
                                       ndev->name);
-                               err = -ENOMEM;
                                goto drop_free;
                        }
                        newskb_offset = (4 - (long) newskb->data) & 0x03;
@@ -197,8 +193,6 @@ islpci_eth_transmit(struct sk_buff *skb, struct net_device *ndev)
        if (unlikely(pci_map_address == 0)) {
                printk(KERN_WARNING "%s: cannot map buffer to PCI\n",
                       ndev->name);
-
-               err = -EIO;
                goto drop_free;
        }
        /* Place the fragment in the control block structure. */
@@ -246,7 +240,7 @@ islpci_eth_transmit(struct sk_buff *skb, struct net_device *ndev)
        ndev->stats.tx_dropped++;
        spin_unlock_irqrestore(&priv->slock, flags);
        dev_kfree_skb(skb);
-       return err;
+       return NETDEV_TX_OK;
 }
 
 static inline int
index fa90d1d8d82ee08331d416882b9a21f0bbe071af..b10b0383dfa5ecaa9b6970fc51f36e80bb0a57be 100644 (file)
@@ -892,7 +892,7 @@ static int ray_dev_init(struct net_device *dev)
 #endif /* RAY_IMMEDIATE_INIT */
 
        /* copy mac and broadcast addresses to linux device */
-       memcpy(&dev->dev_addr, &local->sparm.b4.a_mac_addr, ADDRLEN);
+       memcpy(dev->dev_addr, &local->sparm.b4.a_mac_addr, ADDRLEN);
        memset(dev->broadcast, 0xff, ETH_ALEN);
 
        DEBUG(2, "ray_dev_init ending\n");
@@ -923,7 +923,7 @@ static int ray_dev_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
        if (!(pcmcia_dev_present(link))) {
                DEBUG(2, "ray_dev_start_xmit - device not present\n");
-               return -1;
+               return NETDEV_TX_LOCKED;
        }
        DEBUG(3, "ray_dev_start_xmit(skb=%p, dev=%p)\n", skb, dev);
        if (local->authentication_state == NEED_TO_AUTH) {
@@ -931,7 +931,7 @@ static int ray_dev_start_xmit(struct sk_buff *skb, struct net_device *dev)
                if (!build_auth_frame(local, local->auth_id, OPEN_AUTH_REQUEST)) {
                        local->authentication_state = AUTHENTICATED;
                        netif_stop_queue(dev);
-                       return 1;
+                       return NETDEV_TX_BUSY;
                }
        }
 
@@ -944,7 +944,7 @@ static int ray_dev_start_xmit(struct sk_buff *skb, struct net_device *dev)
        case XMIT_NO_CCS:
        case XMIT_NEED_AUTH:
                netif_stop_queue(dev);
-               return 1;
+               return NETDEV_TX_BUSY;
        case XMIT_NO_INTR:
        case XMIT_MSG_BAD:
        case XMIT_OK:
index ff0042ffe3e9d84820311decf72aa9ddd9a7cb21..3bec3dbd3450cf105e91fbc72c062da7b16e21e7 100644 (file)
@@ -2,7 +2,7 @@
  * Driver for RNDIS based wireless USB devices.
  *
  * Copyright (C) 2007 by Bjorge Dijkstra <bjd@jooz.net>
- * Copyright (C) 2008 by Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
+ * Copyright (C) 2008-2009 by Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
  *
  * 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
@@ -42,6 +42,7 @@
 #include <linux/ctype.h>
 #include <linux/spinlock.h>
 #include <net/iw_handler.h>
+#include <net/cfg80211.h>
 #include <linux/usb/usbnet.h>
 #include <linux/usb/rndis_host.h>
 
@@ -156,43 +157,55 @@ MODULE_PARM_DESC(workaround_interval,
 #define NDIS_802_11_LENGTH_RATES_EX 16
 
 enum ndis_80211_net_type {
-       ndis_80211_type_freq_hop,
-       ndis_80211_type_direct_seq,
-       ndis_80211_type_ofdm_a,
-       ndis_80211_type_ofdm_g
+       NDIS_80211_TYPE_FREQ_HOP,
+       NDIS_80211_TYPE_DIRECT_SEQ,
+       NDIS_80211_TYPE_OFDM_A,
+       NDIS_80211_TYPE_OFDM_G
 };
 
 enum ndis_80211_net_infra {
-       ndis_80211_infra_adhoc,
-       ndis_80211_infra_infra,
-       ndis_80211_infra_auto_unknown
+       NDIS_80211_INFRA_ADHOC,
+       NDIS_80211_INFRA_INFRA,
+       NDIS_80211_INFRA_AUTO_UNKNOWN
 };
 
 enum ndis_80211_auth_mode {
-       ndis_80211_auth_open,
-       ndis_80211_auth_shared,
-       ndis_80211_auth_auto_switch,
-       ndis_80211_auth_wpa,
-       ndis_80211_auth_wpa_psk,
-       ndis_80211_auth_wpa_none,
-       ndis_80211_auth_wpa2,
-       ndis_80211_auth_wpa2_psk
+       NDIS_80211_AUTH_OPEN,
+       NDIS_80211_AUTH_SHARED,
+       NDIS_80211_AUTH_AUTO_SWITCH,
+       NDIS_80211_AUTH_WPA,
+       NDIS_80211_AUTH_WPA_PSK,
+       NDIS_80211_AUTH_WPA_NONE,
+       NDIS_80211_AUTH_WPA2,
+       NDIS_80211_AUTH_WPA2_PSK
 };
 
 enum ndis_80211_encr_status {
-       ndis_80211_encr_wep_enabled,
-       ndis_80211_encr_disabled,
-       ndis_80211_encr_wep_key_absent,
-       ndis_80211_encr_not_supported,
-       ndis_80211_encr_tkip_enabled,
-       ndis_80211_encr_tkip_key_absent,
-       ndis_80211_encr_ccmp_enabled,
-       ndis_80211_encr_ccmp_key_absent
+       NDIS_80211_ENCR_WEP_ENABLED,
+       NDIS_80211_ENCR_DISABLED,
+       NDIS_80211_ENCR_WEP_KEY_ABSENT,
+       NDIS_80211_ENCR_NOT_SUPPORTED,
+       NDIS_80211_ENCR_TKIP_ENABLED,
+       NDIS_80211_ENCR_TKIP_KEY_ABSENT,
+       NDIS_80211_ENCR_CCMP_ENABLED,
+       NDIS_80211_ENCR_CCMP_KEY_ABSENT
 };
 
 enum ndis_80211_priv_filter {
-       ndis_80211_priv_accept_all,
-       ndis_80211_priv_8021x_wep
+       NDIS_80211_PRIV_ACCEPT_ALL,
+       NDIS_80211_PRIV_8021X_WEP
+};
+
+enum ndis_80211_addkey_bits {
+       NDIS_80211_ADDKEY_8021X_AUTH = cpu_to_le32(1 << 28),
+       NDIS_80211_ADDKEY_SET_INIT_RECV_SEQ = cpu_to_le32(1 << 29),
+       NDIS_80211_ADDKEY_PAIRWISE_KEY = cpu_to_le32(1 << 30),
+       NDIS_80211_ADDKEY_TRANSMIT_KEY = cpu_to_le32(1 << 31)
+};
+
+enum ndis_80211_addwep_bits {
+       NDIS_80211_ADDWEP_PERCLIENT_KEY = cpu_to_le32(1 << 30),
+       NDIS_80211_ADDWEP_TRANSMIT_KEY = cpu_to_le32(1 << 31)
 };
 
 struct ndis_80211_ssid {
@@ -308,7 +321,6 @@ enum wpa_key_mgmt { KEY_MGMT_802_1X, KEY_MGMT_PSK, KEY_MGMT_NONE,
 #define CAP_MODE_80211B                2
 #define CAP_MODE_80211G                4
 #define CAP_MODE_MASK          7
-#define CAP_SUPPORT_TXPOWER    8
 
 #define WORK_LINK_UP           (1<<0)
 #define WORK_LINK_DOWN         (1<<1)
@@ -316,25 +328,61 @@ enum wpa_key_mgmt { KEY_MGMT_802_1X, KEY_MGMT_PSK, KEY_MGMT_NONE,
 
 #define COMMAND_BUFFER_SIZE    (CONTROL_BUFFER_SIZE + sizeof(struct rndis_set))
 
-/* RNDIS device private data */
-struct rndis_wext_private {
-       char name[32];
+static const struct ieee80211_channel rndis_channels[] = {
+       { .center_freq = 2412 },
+       { .center_freq = 2417 },
+       { .center_freq = 2422 },
+       { .center_freq = 2427 },
+       { .center_freq = 2432 },
+       { .center_freq = 2437 },
+       { .center_freq = 2442 },
+       { .center_freq = 2447 },
+       { .center_freq = 2452 },
+       { .center_freq = 2457 },
+       { .center_freq = 2462 },
+       { .center_freq = 2467 },
+       { .center_freq = 2472 },
+       { .center_freq = 2484 },
+};
 
+static const struct ieee80211_rate rndis_rates[] = {
+       { .bitrate = 10 },
+       { .bitrate = 20, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
+       { .bitrate = 55, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
+       { .bitrate = 110, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
+       { .bitrate = 60 },
+       { .bitrate = 90 },
+       { .bitrate = 120 },
+       { .bitrate = 180 },
+       { .bitrate = 240 },
+       { .bitrate = 360 },
+       { .bitrate = 480 },
+       { .bitrate = 540 }
+};
+
+/* RNDIS device private data */
+struct rndis_wlan_private {
        struct usbnet *usbdev;
 
+       struct wireless_dev wdev;
+
+       struct cfg80211_scan_request *scan_request;
+
        struct workqueue_struct *workqueue;
        struct delayed_work stats_work;
+       struct delayed_work scan_work;
        struct work_struct work;
        struct mutex command_lock;
        spinlock_t stats_lock;
        unsigned long work_pending;
 
+       struct ieee80211_supported_band band;
+       struct ieee80211_channel channels[ARRAY_SIZE(rndis_channels)];
+       struct ieee80211_rate rates[ARRAY_SIZE(rndis_rates)];
+
        struct iw_statistics iwstats;
        struct iw_statistics privstats;
 
-       int  nick_len;
-       char nick[32];
-
        int caps;
        int multicast_size;
 
@@ -357,6 +405,7 @@ struct rndis_wext_private {
        int  encr_tx_key_index;
        char encr_keys[4][32];
        int  encr_key_len[4];
+       char encr_key_wpa[4];
        int  wpa_version;
        int  wpa_keymgmt;
        int  wpa_authalg;
@@ -368,8 +417,22 @@ struct rndis_wext_private {
        u8 command_buffer[COMMAND_BUFFER_SIZE];
 };
 
+/*
+ * cfg80211 ops
+ */
+static int rndis_change_virtual_intf(struct wiphy *wiphy, int ifindex,
+                                       enum nl80211_iftype type, u32 *flags,
+                                       struct vif_params *params);
+
+static int rndis_scan(struct wiphy *wiphy, struct net_device *dev,
+                       struct cfg80211_scan_request *request);
 
-static const int rates_80211g[8] = { 6, 9, 12, 18, 24, 36, 48, 54 };
+static struct cfg80211_ops rndis_config_ops = {
+       .change_virtual_intf = rndis_change_virtual_intf,
+       .scan = rndis_scan,
+};
+
+static void *rndis_wiphy_privid = &rndis_wiphy_privid;
 
 static const int bcm4320_power_output[4] = { 25, 50, 75, 100 };
 
@@ -378,13 +441,13 @@ static const unsigned char ffff_bssid[ETH_ALEN] = { 0xff, 0xff, 0xff,
                                                        0xff, 0xff, 0xff };
 
 
-static struct rndis_wext_private *get_rndis_wext_priv(struct usbnet *dev)
+static struct rndis_wlan_private *get_rndis_wlan_priv(struct usbnet *dev)
 {
-       return (struct rndis_wext_private *)dev->driver_priv;
+       return (struct rndis_wlan_private *)dev->driver_priv;
 }
 
 
-static u32 get_bcm4320_power(struct rndis_wext_private *priv)
+static u32 get_bcm4320_power(struct rndis_wlan_private *priv)
 {
        return BCM4320_DEFAULT_TXPOWER *
                bcm4320_power_output[priv->param_power_output] / 100;
@@ -417,7 +480,7 @@ static int rndis_error_status(__le32 rndis_status)
 
 static int rndis_query_oid(struct usbnet *dev, __le32 oid, void *data, int *len)
 {
-       struct rndis_wext_private *priv = get_rndis_wext_priv(dev);
+       struct rndis_wlan_private *priv = get_rndis_wlan_priv(dev);
        union {
                void                    *buf;
                struct rndis_msg_hdr    *header;
@@ -463,7 +526,7 @@ static int rndis_query_oid(struct usbnet *dev, __le32 oid, void *data, int *len)
 
 static int rndis_set_oid(struct usbnet *dev, __le32 oid, void *data, int len)
 {
-       struct rndis_wext_private *priv = get_rndis_wext_priv(dev);
+       struct rndis_wlan_private *priv = get_rndis_wlan_priv(dev);
        union {
                void                    *buf;
                struct rndis_msg_hdr    *header;
@@ -684,7 +747,7 @@ static int get_essid(struct usbnet *usbdev, struct ndis_80211_ssid *ssid)
 
 static int set_essid(struct usbnet *usbdev, struct ndis_80211_ssid *ssid)
 {
-       struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+       struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
        int ret;
 
        ret = rndis_set_oid(usbdev, OID_802_11_SSID, ssid, sizeof(*ssid));
@@ -731,7 +794,7 @@ static int is_associated(struct usbnet *usbdev)
 
 static int disassociate(struct usbnet *usbdev, int reset_ssid)
 {
-       struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+       struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
        struct ndis_80211_ssid ssid;
        int i, ret = 0;
 
@@ -763,7 +826,7 @@ static int disassociate(struct usbnet *usbdev, int reset_ssid)
 
 static int set_auth_mode(struct usbnet *usbdev, int wpa_version, int authalg)
 {
-       struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+       struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
        __le32 tmp;
        int auth_mode, ret;
 
@@ -772,23 +835,23 @@ static int set_auth_mode(struct usbnet *usbdev, int wpa_version, int authalg)
 
        if (wpa_version & IW_AUTH_WPA_VERSION_WPA2) {
                if (priv->wpa_keymgmt & IW_AUTH_KEY_MGMT_802_1X)
-                       auth_mode = ndis_80211_auth_wpa2;
+                       auth_mode = NDIS_80211_AUTH_WPA2;
                else
-                       auth_mode = ndis_80211_auth_wpa2_psk;
+                       auth_mode = NDIS_80211_AUTH_WPA2_PSK;
        } else if (wpa_version & IW_AUTH_WPA_VERSION_WPA) {
                if (priv->wpa_keymgmt & IW_AUTH_KEY_MGMT_802_1X)
-                       auth_mode = ndis_80211_auth_wpa;
+                       auth_mode = NDIS_80211_AUTH_WPA;
                else if (priv->wpa_keymgmt & IW_AUTH_KEY_MGMT_PSK)
-                       auth_mode = ndis_80211_auth_wpa_psk;
+                       auth_mode = NDIS_80211_AUTH_WPA_PSK;
                else
-                       auth_mode = ndis_80211_auth_wpa_none;
+                       auth_mode = NDIS_80211_AUTH_WPA_NONE;
        } else if (authalg & IW_AUTH_ALG_SHARED_KEY) {
                if (authalg & IW_AUTH_ALG_OPEN_SYSTEM)
-                       auth_mode = ndis_80211_auth_auto_switch;
+                       auth_mode = NDIS_80211_AUTH_AUTO_SWITCH;
                else
-                       auth_mode = ndis_80211_auth_shared;
+                       auth_mode = NDIS_80211_AUTH_SHARED;
        } else
-               auth_mode = ndis_80211_auth_open;
+               auth_mode = NDIS_80211_AUTH_OPEN;
 
        tmp = cpu_to_le32(auth_mode);
        ret = rndis_set_oid(usbdev, OID_802_11_AUTHENTICATION_MODE, &tmp,
@@ -806,16 +869,16 @@ static int set_auth_mode(struct usbnet *usbdev, int wpa_version, int authalg)
 
 static int set_priv_filter(struct usbnet *usbdev)
 {
-       struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+       struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
        __le32 tmp;
 
        devdbg(usbdev, "set_priv_filter: wpa_version=0x%x", priv->wpa_version);
 
        if (priv->wpa_version & IW_AUTH_WPA_VERSION_WPA2 ||
            priv->wpa_version & IW_AUTH_WPA_VERSION_WPA)
-               tmp = cpu_to_le32(ndis_80211_priv_8021x_wep);
+               tmp = cpu_to_le32(NDIS_80211_PRIV_8021X_WEP);
        else
-               tmp = cpu_to_le32(ndis_80211_priv_accept_all);
+               tmp = cpu_to_le32(NDIS_80211_PRIV_ACCEPT_ALL);
 
        return rndis_set_oid(usbdev, OID_802_11_PRIVACY_FILTER, &tmp,
                                                                sizeof(tmp));
@@ -824,7 +887,7 @@ static int set_priv_filter(struct usbnet *usbdev)
 
 static int set_encr_mode(struct usbnet *usbdev, int pairwise, int groupwise)
 {
-       struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+       struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
        __le32 tmp;
        int encr_mode, ret;
 
@@ -833,18 +896,18 @@ static int set_encr_mode(struct usbnet *usbdev, int pairwise, int groupwise)
                groupwise);
 
        if (pairwise & IW_AUTH_CIPHER_CCMP)
-               encr_mode = ndis_80211_encr_ccmp_enabled;
+               encr_mode = NDIS_80211_ENCR_CCMP_ENABLED;
        else if (pairwise & IW_AUTH_CIPHER_TKIP)
-               encr_mode = ndis_80211_encr_tkip_enabled;
+               encr_mode = NDIS_80211_ENCR_TKIP_ENABLED;
        else if (pairwise &
                 (IW_AUTH_CIPHER_WEP40 | IW_AUTH_CIPHER_WEP104))
-               encr_mode = ndis_80211_encr_wep_enabled;
+               encr_mode = NDIS_80211_ENCR_WEP_ENABLED;
        else if (groupwise & IW_AUTH_CIPHER_CCMP)
-               encr_mode = ndis_80211_encr_ccmp_enabled;
+               encr_mode = NDIS_80211_ENCR_CCMP_ENABLED;
        else if (groupwise & IW_AUTH_CIPHER_TKIP)
-               encr_mode = ndis_80211_encr_tkip_enabled;
+               encr_mode = NDIS_80211_ENCR_TKIP_ENABLED;
        else
-               encr_mode = ndis_80211_encr_disabled;
+               encr_mode = NDIS_80211_ENCR_DISABLED;
 
        tmp = cpu_to_le32(encr_mode);
        ret = rndis_set_oid(usbdev, OID_802_11_ENCRYPTION_STATUS, &tmp,
@@ -862,7 +925,7 @@ static int set_encr_mode(struct usbnet *usbdev, int pairwise, int groupwise)
 
 static int set_assoc_params(struct usbnet *usbdev)
 {
-       struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+       struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
 
        set_auth_mode(usbdev, priv->wpa_version, priv->wpa_authalg);
        set_priv_filter(usbdev);
@@ -874,7 +937,7 @@ static int set_assoc_params(struct usbnet *usbdev)
 
 static int set_infra_mode(struct usbnet *usbdev, int mode)
 {
-       struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+       struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
        __le32 tmp;
        int ret, i;
 
@@ -894,7 +957,7 @@ static int set_infra_mode(struct usbnet *usbdev, int mode)
        if (priv->wpa_keymgmt == 0 ||
                priv->wpa_keymgmt == IW_AUTH_KEY_MGMT_802_1X) {
                for (i = 0; i < 4; i++) {
-                       if (priv->encr_key_len[i] > 0)
+                       if (priv->encr_key_len[i] > 0 && !priv->encr_key_wpa[i])
                                add_wep_key(usbdev, priv->encr_keys[i],
                                                priv->encr_key_len[i], i);
                }
@@ -907,12 +970,12 @@ static int set_infra_mode(struct usbnet *usbdev, int mode)
 
 static void set_default_iw_params(struct usbnet *usbdev)
 {
-       struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+       struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
 
        priv->wpa_keymgmt = 0;
        priv->wpa_version = 0;
 
-       set_infra_mode(usbdev, ndis_80211_infra_infra);
+       set_infra_mode(usbdev, NDIS_80211_INFRA_INFRA);
        set_auth_mode(usbdev, IW_AUTH_WPA_VERSION_DISABLED,
                                IW_AUTH_ALG_OPEN_SYSTEM);
        set_priv_filter(usbdev);
@@ -933,7 +996,7 @@ static int deauthenticate(struct usbnet *usbdev)
 /* index must be 0 - N, as per NDIS  */
 static int add_wep_key(struct usbnet *usbdev, char *key, int key_len, int index)
 {
-       struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+       struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
        struct ndis_80211_wep_key ndis_key;
        int ret;
 
@@ -948,7 +1011,7 @@ static int add_wep_key(struct usbnet *usbdev, char *key, int key_len, int index)
        memcpy(&ndis_key.material, key, key_len);
 
        if (index == priv->encr_tx_key_index) {
-               ndis_key.index |= cpu_to_le32(1 << 31);
+               ndis_key.index |= NDIS_80211_ADDWEP_TRANSMIT_KEY;
                ret = set_encr_mode(usbdev, IW_AUTH_CIPHER_WEP104,
                                                IW_AUTH_CIPHER_NONE);
                if (ret)
@@ -965,16 +1028,85 @@ static int add_wep_key(struct usbnet *usbdev, char *key, int key_len, int index)
        }
 
        priv->encr_key_len[index] = key_len;
+       priv->encr_key_wpa[index] = 0;
        memcpy(&priv->encr_keys[index], key, key_len);
 
        return 0;
 }
 
 
+static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len,
+                       int index, const struct sockaddr *addr,
+                       const u8 *rx_seq, int alg, int flags)
+{
+       struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
+       struct ndis_80211_key ndis_key;
+       int ret;
+
+       if (index < 0 || index >= 4)
+               return -EINVAL;
+       if (key_len > sizeof(ndis_key.material) || key_len < 0)
+               return -EINVAL;
+       if ((flags & NDIS_80211_ADDKEY_SET_INIT_RECV_SEQ) && !rx_seq)
+               return -EINVAL;
+       if ((flags & NDIS_80211_ADDKEY_PAIRWISE_KEY) && !addr)
+               return -EINVAL;
+
+       devdbg(usbdev, "add_wpa_key(%i): flags:%i%i%i", index,
+                       !!(flags & NDIS_80211_ADDKEY_TRANSMIT_KEY),
+                       !!(flags & NDIS_80211_ADDKEY_PAIRWISE_KEY),
+                       !!(flags & NDIS_80211_ADDKEY_SET_INIT_RECV_SEQ));
+
+       memset(&ndis_key, 0, sizeof(ndis_key));
+
+       ndis_key.size = cpu_to_le32(sizeof(ndis_key) -
+                               sizeof(ndis_key.material) + key_len);
+       ndis_key.length = cpu_to_le32(key_len);
+       ndis_key.index = cpu_to_le32(index) | flags;
+
+       if (alg == IW_ENCODE_ALG_TKIP && key_len == 32) {
+               /* wpa_supplicant gives us the Michael MIC RX/TX keys in
+                * different order than NDIS spec, so swap the order here. */
+               memcpy(ndis_key.material, key, 16);
+               memcpy(ndis_key.material + 16, key + 24, 8);
+               memcpy(ndis_key.material + 24, key + 16, 8);
+       } else
+               memcpy(ndis_key.material, key, key_len);
+
+       if (flags & NDIS_80211_ADDKEY_SET_INIT_RECV_SEQ)
+               memcpy(ndis_key.rsc, rx_seq, 6);
+
+       if (flags & NDIS_80211_ADDKEY_PAIRWISE_KEY) {
+               /* pairwise key */
+               memcpy(ndis_key.bssid, addr->sa_data, ETH_ALEN);
+       } else {
+               /* group key */
+               if (priv->infra_mode == NDIS_80211_INFRA_ADHOC)
+                       memset(ndis_key.bssid, 0xff, ETH_ALEN);
+               else
+                       get_bssid(usbdev, ndis_key.bssid);
+       }
+
+       ret = rndis_set_oid(usbdev, OID_802_11_ADD_KEY, &ndis_key,
+                                       le32_to_cpu(ndis_key.size));
+       devdbg(usbdev, "add_wpa_key: OID_802_11_ADD_KEY -> %08X", ret);
+       if (ret != 0)
+               return ret;
+
+       priv->encr_key_len[index] = key_len;
+       priv->encr_key_wpa[index] = 1;
+
+       if (flags & NDIS_80211_ADDKEY_TRANSMIT_KEY)
+               priv->encr_tx_key_index = index;
+
+       return 0;
+}
+
+
 /* remove_key is for both wep and wpa */
 static int remove_key(struct usbnet *usbdev, int index, u8 bssid[ETH_ALEN])
 {
-       struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+       struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
        struct ndis_80211_remove_key remove_key;
        __le32 keyindex;
        int ret;
@@ -983,6 +1115,7 @@ static int remove_key(struct usbnet *usbdev, int index, u8 bssid[ETH_ALEN])
                return 0;
 
        priv->encr_key_len[index] = 0;
+       priv->encr_key_wpa[index] = 0;
        memset(&priv->encr_keys[index], 0, sizeof(priv->encr_keys[index]));
 
        if (priv->wpa_cipher_pair == IW_AUTH_CIPHER_TKIP ||
@@ -994,7 +1127,8 @@ static int remove_key(struct usbnet *usbdev, int index, u8 bssid[ETH_ALEN])
                if (bssid) {
                        /* pairwise key */
                        if (memcmp(bssid, ffff_bssid, ETH_ALEN) != 0)
-                               remove_key.index |= cpu_to_le32(1 << 30);
+                               remove_key.index |=
+                                       NDIS_80211_ADDKEY_PAIRWISE_KEY;
                        memcpy(remove_key.bssid, bssid,
                                        sizeof(remove_key.bssid));
                } else
@@ -1027,7 +1161,7 @@ static int remove_key(struct usbnet *usbdev, int index, u8 bssid[ETH_ALEN])
 
 static void set_multicast_list(struct usbnet *usbdev)
 {
-       struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+       struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
        struct dev_mc_list *mclist;
        __le32 filter;
        int ret, i, size;
@@ -1086,131 +1220,180 @@ static void set_multicast_list(struct usbnet *usbdev)
 
 
 /*
- * wireless extension handlers
+ * cfg80211 ops
  */
-
-static int rndis_iw_commit(struct net_device *dev,
-    struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+static int rndis_change_virtual_intf(struct wiphy *wiphy, int ifindex,
+                                       enum nl80211_iftype type, u32 *flags,
+                                       struct vif_params *params)
 {
-       /* dummy op */
-       return 0;
+       struct net_device *dev;
+       struct usbnet *usbdev;
+       int mode;
+
+       /* we're under RTNL */
+       dev = __dev_get_by_index(&init_net, ifindex);
+       if (!dev)
+               return -ENODEV;
+       usbdev = netdev_priv(dev);
+
+       switch (type) {
+       case NL80211_IFTYPE_ADHOC:
+               mode = NDIS_80211_INFRA_ADHOC;
+               break;
+       case NL80211_IFTYPE_STATION:
+               mode = NDIS_80211_INFRA_INFRA;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return set_infra_mode(usbdev, mode);
 }
 
 
-static int rndis_iw_get_range(struct net_device *dev,
-    struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
+#define SCAN_DELAY_JIFFIES (HZ)
+static int rndis_scan(struct wiphy *wiphy, struct net_device *dev,
+                       struct cfg80211_scan_request *request)
 {
-       struct iw_range *range = (struct iw_range *)extra;
        struct usbnet *usbdev = netdev_priv(dev);
-       struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
-       int len, ret, i, j, num, has_80211g_rates;
-       u8 rates[8];
-       __le32 tx_power;
+       struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
+       int ret;
+       __le32 tmp;
+
+       devdbg(usbdev, "cfg80211.scan");
 
-       devdbg(usbdev, "SIOCGIWRANGE");
+       if (!request)
+               return -EINVAL;
 
-       /* clear iw_range struct */
-       memset(range, 0, sizeof(*range));
-       wrqu->data.length = sizeof(*range);
+       if (priv->scan_request && priv->scan_request != request)
+               return -EBUSY;
 
-       range->txpower_capa = IW_TXPOW_MWATT;
-       range->num_txpower = 1;
-       if (priv->caps & CAP_SUPPORT_TXPOWER) {
-               len = sizeof(tx_power);
-               ret = rndis_query_oid(usbdev, OID_802_11_TX_POWER_LEVEL,
-                                               &tx_power, &len);
-               if (ret == 0 && le32_to_cpu(tx_power) != 0xFF)
-                       range->txpower[0] = le32_to_cpu(tx_power);
-               else
-                       range->txpower[0] = get_bcm4320_power(priv);
-       } else
-               range->txpower[0] = get_bcm4320_power(priv);
+       priv->scan_request = request;
 
-       len = sizeof(rates);
-       ret = rndis_query_oid(usbdev, OID_802_11_SUPPORTED_RATES, &rates,
-                                                               &len);
-       has_80211g_rates = 0;
+       tmp = cpu_to_le32(1);
+       ret = rndis_set_oid(usbdev, OID_802_11_BSSID_LIST_SCAN, &tmp,
+                                                       sizeof(tmp));
        if (ret == 0) {
-               j = 0;
-               for (i = 0; i < len; i++) {
-                       if (rates[i] == 0)
-                               break;
-                       range->bitrate[j] = (rates[i] & 0x7f) * 500000;
-                       /* check for non 802.11b rates */
-                       if (range->bitrate[j] == 6000000 ||
-                               range->bitrate[j] == 9000000 ||
-                               (range->bitrate[j] >= 12000000 &&
-                               range->bitrate[j] != 22000000))
-                               has_80211g_rates = 1;
-                       j++;
-               }
-               range->num_bitrates = j;
-       } else
-               range->num_bitrates = 0;
-
-       /* fill in 802.11g rates */
-       if (has_80211g_rates) {
-               num = range->num_bitrates;
-               for (i = 0; i < ARRAY_SIZE(rates_80211g); i++) {
-                       for (j = 0; j < num; j++) {
-                               if (range->bitrate[j] ==
-                                       rates_80211g[i] * 1000000)
-                                       break;
-                       }
-                       if (j == num)
-                               range->bitrate[range->num_bitrates++] =
-                                       rates_80211g[i] * 1000000;
-                       if (range->num_bitrates == IW_MAX_BITRATES)
-                               break;
-               }
+               /* Wait before retrieving scan results from device */
+               queue_delayed_work(priv->workqueue, &priv->scan_work,
+                       SCAN_DELAY_JIFFIES);
+       }
 
-               /* estimated max real througput in bps */
-               range->throughput = 54 * 1000 * 1000 / 2;
+       return ret;
+}
 
-               /* ~35% more with afterburner */
-               if (priv->param_afterburner)
-                       range->throughput = range->throughput / 100 * 135;
-       } else {
-               /* estimated max real througput in bps */
-               range->throughput = 11 * 1000 * 1000 / 2;
+
+static struct cfg80211_bss *rndis_bss_info_update(struct usbnet *usbdev,
+                                       struct ndis_80211_bssid_ex *bssid)
+{
+       struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
+       struct ieee80211_channel *channel;
+       s32 signal;
+       u64 timestamp;
+       u16 capability;
+       u16 beacon_interval;
+       struct ndis_80211_fixed_ies *fixed;
+       int ie_len, bssid_len;
+       u8 *ie;
+
+       /* parse bssid structure */
+       bssid_len = le32_to_cpu(bssid->length);
+
+       if (bssid_len < sizeof(struct ndis_80211_bssid_ex) +
+                       sizeof(struct ndis_80211_fixed_ies))
+               return NULL;
+
+       fixed = (struct ndis_80211_fixed_ies *)bssid->ies;
+
+       ie = (void *)(bssid->ies + sizeof(struct ndis_80211_fixed_ies));
+       ie_len = min(bssid_len - (int)sizeof(*bssid),
+                                       (int)le32_to_cpu(bssid->ie_length));
+       ie_len -= sizeof(struct ndis_80211_fixed_ies);
+       if (ie_len < 0)
+               return NULL;
+
+       /* extract data for cfg80211_inform_bss */
+       channel = ieee80211_get_channel(priv->wdev.wiphy,
+                       KHZ_TO_MHZ(le32_to_cpu(bssid->config.ds_config)));
+       if (!channel)
+               return NULL;
+
+       signal = level_to_qual(le32_to_cpu(bssid->rssi));
+       timestamp = le64_to_cpu(*(__le64 *)fixed->timestamp);
+       capability = le16_to_cpu(fixed->capabilities);
+       beacon_interval = le16_to_cpu(fixed->beacon_interval);
+
+       return cfg80211_inform_bss(priv->wdev.wiphy, channel, bssid->mac,
+               timestamp, capability, beacon_interval, ie, ie_len, signal,
+               GFP_KERNEL);
+}
+
+
+static int rndis_check_bssid_list(struct usbnet *usbdev)
+{
+       void *buf = NULL;
+       struct ndis_80211_bssid_list_ex *bssid_list;
+       struct ndis_80211_bssid_ex *bssid;
+       int ret = -EINVAL, len, count, bssid_len;
+
+       devdbg(usbdev, "check_bssid_list");
+
+       len = CONTROL_BUFFER_SIZE;
+       buf = kmalloc(len, GFP_KERNEL);
+       if (!buf) {
+               ret = -ENOMEM;
+               goto out;
        }
 
-       range->num_channels = 14;
+       ret = rndis_query_oid(usbdev, OID_802_11_BSSID_LIST, buf, &len);
+       if (ret != 0)
+               goto out;
 
-       for (i = 0; (i < 14) && (i < IW_MAX_FREQUENCIES); i++) {
-               range->freq[i].i = i + 1;
-               range->freq[i].m = ieee80211_dsss_chan_to_freq(i + 1) * 100000;
-               range->freq[i].e = 1;
+       bssid_list = buf;
+       bssid = bssid_list->bssid;
+       bssid_len = le32_to_cpu(bssid->length);
+       count = le32_to_cpu(bssid_list->num_items);
+       devdbg(usbdev, "check_bssid_list: %d BSSIDs found", count);
+
+       while (count && ((void *)bssid + bssid_len) <= (buf + len)) {
+               rndis_bss_info_update(usbdev, bssid);
+
+               bssid = (void *)bssid + bssid_len;
+               bssid_len = le32_to_cpu(bssid->length);
+               count--;
        }
-       range->num_frequency = i;
 
-       range->min_rts = 0;
-       range->max_rts = 2347;
-       range->min_frag = 256;
-       range->max_frag = 2346;
+out:
+       kfree(buf);
+       return ret;
+}
 
-       range->max_qual.qual = 100;
-       range->max_qual.level = 154;
-       range->max_qual.updated = IW_QUAL_QUAL_UPDATED
-                               | IW_QUAL_LEVEL_UPDATED
-                               | IW_QUAL_NOISE_INVALID;
 
-       range->we_version_compiled = WIRELESS_EXT;
-       range->we_version_source = WIRELESS_EXT;
+static void rndis_get_scan_results(struct work_struct *work)
+{
+       struct rndis_wlan_private *priv =
+               container_of(work, struct rndis_wlan_private, scan_work.work);
+       struct usbnet *usbdev = priv->usbdev;
+       int ret;
+
+       devdbg(usbdev, "get_scan_results");
 
-       range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
-                       IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
-       return 0;
+       ret = rndis_check_bssid_list(usbdev);
+
+       cfg80211_scan_done(priv->scan_request, ret < 0);
+
+       priv->scan_request = NULL;
 }
 
 
-static int rndis_iw_get_name(struct net_device *dev,
+/*
+ * wireless extension handlers
+ */
+
+static int rndis_iw_commit(struct net_device *dev,
     struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
 {
-       struct usbnet *usbdev = netdev_priv(dev);
-       struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
-
-       strcpy(wrqu->name, priv->name);
+       /* dummy op */
        return 0;
 }
 
@@ -1314,7 +1497,7 @@ static int rndis_iw_set_auth(struct net_device *dev,
 {
        struct iw_param *p = &wrqu->param;
        struct usbnet *usbdev = netdev_priv(dev);
-       struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+       struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
        int ret = -ENOTSUPP;
 
        switch (p->flags & IW_AUTH_INDEX) {
@@ -1395,7 +1578,7 @@ static int rndis_iw_get_auth(struct net_device *dev,
 {
        struct iw_param *p = &wrqu->param;
        struct usbnet *usbdev = netdev_priv(dev);
-       struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+       struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
 
        switch (p->flags & IW_AUTH_INDEX) {
        case IW_AUTH_WPA_VERSION:
@@ -1422,60 +1605,11 @@ static int rndis_iw_get_auth(struct net_device *dev,
 }
 
 
-static int rndis_iw_get_mode(struct net_device *dev,
-                               struct iw_request_info *info,
-                               union iwreq_data *wrqu, char *extra)
-{
-       struct usbnet *usbdev = netdev_priv(dev);
-       struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
-
-       switch (priv->infra_mode) {
-       case ndis_80211_infra_adhoc:
-               wrqu->mode = IW_MODE_ADHOC;
-               break;
-       case ndis_80211_infra_infra:
-               wrqu->mode = IW_MODE_INFRA;
-               break;
-       /*case ndis_80211_infra_auto_unknown:*/
-       default:
-               wrqu->mode = IW_MODE_AUTO;
-               break;
-       }
-       devdbg(usbdev, "SIOCGIWMODE: %08x", wrqu->mode);
-       return 0;
-}
-
-
-static int rndis_iw_set_mode(struct net_device *dev,
-    struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
-{
-       struct usbnet *usbdev = netdev_priv(dev);
-       int mode;
-
-       devdbg(usbdev, "SIOCSIWMODE: %08x", wrqu->mode);
-
-       switch (wrqu->mode) {
-       case IW_MODE_ADHOC:
-               mode = ndis_80211_infra_adhoc;
-               break;
-       case IW_MODE_INFRA:
-               mode = ndis_80211_infra_infra;
-               break;
-       /*case IW_MODE_AUTO:*/
-       default:
-               mode = ndis_80211_infra_auto_unknown;
-               break;
-       }
-
-       return set_infra_mode(usbdev, mode);
-}
-
-
 static int rndis_iw_set_encode(struct net_device *dev,
     struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
 {
        struct usbnet *usbdev = netdev_priv(dev);
-       struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+       struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
        int ret, index, key_len;
        u8 *key;
 
@@ -1538,10 +1672,8 @@ static int rndis_iw_set_encode_ext(struct net_device *dev,
 {
        struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
        struct usbnet *usbdev = netdev_priv(dev);
-       struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
-       struct ndis_80211_key ndis_key;
-       int keyidx, ret;
-       u8 *addr;
+       struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
+       int keyidx, flags;
 
        keyidx = wrqu->encoding.flags & IW_ENCODE_INDEX;
 
@@ -1564,250 +1696,16 @@ static int rndis_iw_set_encode_ext(struct net_device *dev,
            ext->alg == IW_ENCODE_ALG_NONE || ext->key_len == 0)
                return remove_key(usbdev, keyidx, NULL);
 
-       if (ext->key_len > sizeof(ndis_key.material))
-               return -1;
-
-       memset(&ndis_key, 0, sizeof(ndis_key));
-
-       ndis_key.size = cpu_to_le32(sizeof(ndis_key) -
-                               sizeof(ndis_key.material) + ext->key_len);
-       ndis_key.length = cpu_to_le32(ext->key_len);
-       ndis_key.index = cpu_to_le32(keyidx);
-
-       if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) {
-               memcpy(ndis_key.rsc, ext->rx_seq, 6);
-               ndis_key.index |= cpu_to_le32(1 << 29);
-       }
-
-       addr = ext->addr.sa_data;
-       if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
-               /* group key */
-               if (priv->infra_mode == ndis_80211_infra_adhoc)
-                       memset(ndis_key.bssid, 0xff, ETH_ALEN);
-               else
-                       get_bssid(usbdev, ndis_key.bssid);
-       } else {
-               /* pairwise key */
-               ndis_key.index |= cpu_to_le32(1 << 30);
-               memcpy(ndis_key.bssid, addr, ETH_ALEN);
-       }
-
-       if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
-               ndis_key.index |= cpu_to_le32(1 << 31);
-
-       if (ext->alg == IW_ENCODE_ALG_TKIP && ext->key_len == 32) {
-               /* wpa_supplicant gives us the Michael MIC RX/TX keys in
-                * different order than NDIS spec, so swap the order here. */
-               memcpy(ndis_key.material, ext->key, 16);
-               memcpy(ndis_key.material + 16, ext->key + 24, 8);
-               memcpy(ndis_key.material + 24, ext->key + 16, 8);
-       } else
-               memcpy(ndis_key.material, ext->key, ext->key_len);
-
-       ret = rndis_set_oid(usbdev, OID_802_11_ADD_KEY, &ndis_key,
-                                       le32_to_cpu(ndis_key.size));
-       devdbg(usbdev, "SIOCSIWENCODEEXT: OID_802_11_ADD_KEY -> %08X", ret);
-       if (ret != 0)
-               return ret;
-
-       priv->encr_key_len[keyidx] = ext->key_len;
-       memcpy(&priv->encr_keys[keyidx], ndis_key.material, ext->key_len);
+       flags = 0;
+       if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID)
+               flags |= NDIS_80211_ADDKEY_SET_INIT_RECV_SEQ;
+       if (!(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY))
+               flags |= NDIS_80211_ADDKEY_PAIRWISE_KEY;
        if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
-               priv->encr_tx_key_index = keyidx;
-
-       return 0;
-}
-
-
-static int rndis_iw_set_scan(struct net_device *dev,
-    struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
-{
-       struct usbnet *usbdev = netdev_priv(dev);
-       union iwreq_data evt;
-       int ret = -EINVAL;
-       __le32 tmp;
-
-       devdbg(usbdev, "SIOCSIWSCAN");
-
-       if (wrqu->data.flags == 0) {
-               tmp = cpu_to_le32(1);
-               ret = rndis_set_oid(usbdev, OID_802_11_BSSID_LIST_SCAN, &tmp,
-                                                               sizeof(tmp));
-               evt.data.flags = 0;
-               evt.data.length = 0;
-               wireless_send_event(dev, SIOCGIWSCAN, &evt, NULL);
-       }
-       return ret;
-}
-
-
-static char *rndis_translate_scan(struct net_device *dev,
-                                 struct iw_request_info *info, char *cev,
-                                 char *end_buf,
-                                 struct ndis_80211_bssid_ex *bssid)
-{
-       struct usbnet *usbdev = netdev_priv(dev);
-       u8 *ie;
-       char *current_val;
-       int bssid_len, ie_len, i;
-       u32 beacon, atim;
-       struct iw_event iwe;
-       unsigned char sbuf[32];
-
-       bssid_len = le32_to_cpu(bssid->length);
-
-       devdbg(usbdev, "BSSID %pM", bssid->mac);
-       iwe.cmd = SIOCGIWAP;
-       iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
-       memcpy(iwe.u.ap_addr.sa_data, bssid->mac, ETH_ALEN);
-       cev = iwe_stream_add_event(info, cev, end_buf, &iwe, IW_EV_ADDR_LEN);
-
-       devdbg(usbdev, "SSID(%d) %s", le32_to_cpu(bssid->ssid.length),
-                                               bssid->ssid.essid);
-       iwe.cmd = SIOCGIWESSID;
-       iwe.u.essid.length = le32_to_cpu(bssid->ssid.length);
-       iwe.u.essid.flags = 1;
-       cev = iwe_stream_add_point(info, cev, end_buf, &iwe, bssid->ssid.essid);
-
-       devdbg(usbdev, "MODE %d", le32_to_cpu(bssid->net_infra));
-       iwe.cmd = SIOCGIWMODE;
-       switch (le32_to_cpu(bssid->net_infra)) {
-       case ndis_80211_infra_adhoc:
-               iwe.u.mode = IW_MODE_ADHOC;
-               break;
-       case ndis_80211_infra_infra:
-               iwe.u.mode = IW_MODE_INFRA;
-               break;
-       /*case ndis_80211_infra_auto_unknown:*/
-       default:
-               iwe.u.mode = IW_MODE_AUTO;
-               break;
-       }
-       cev = iwe_stream_add_event(info, cev, end_buf, &iwe, IW_EV_UINT_LEN);
-
-       devdbg(usbdev, "FREQ %d kHz", le32_to_cpu(bssid->config.ds_config));
-       iwe.cmd = SIOCGIWFREQ;
-       dsconfig_to_freq(le32_to_cpu(bssid->config.ds_config), &iwe.u.freq);
-       cev = iwe_stream_add_event(info, cev, end_buf, &iwe, IW_EV_FREQ_LEN);
-
-       devdbg(usbdev, "QUAL %d", le32_to_cpu(bssid->rssi));
-       iwe.cmd = IWEVQUAL;
-       iwe.u.qual.qual  = level_to_qual(le32_to_cpu(bssid->rssi));
-       iwe.u.qual.level = le32_to_cpu(bssid->rssi);
-       iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED
-                       | IW_QUAL_LEVEL_UPDATED
-                       | IW_QUAL_NOISE_INVALID;
-       cev = iwe_stream_add_event(info, cev, end_buf, &iwe, IW_EV_QUAL_LEN);
-
-       devdbg(usbdev, "ENCODE %d", le32_to_cpu(bssid->privacy));
-       iwe.cmd = SIOCGIWENCODE;
-       iwe.u.data.length = 0;
-       if (le32_to_cpu(bssid->privacy) == ndis_80211_priv_accept_all)
-               iwe.u.data.flags = IW_ENCODE_DISABLED;
-       else
-               iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
-
-       cev = iwe_stream_add_point(info, cev, end_buf, &iwe, NULL);
-
-       devdbg(usbdev, "RATES:");
-       current_val = cev + iwe_stream_lcp_len(info);
-       iwe.cmd = SIOCGIWRATE;
-       for (i = 0; i < sizeof(bssid->rates); i++) {
-               if (bssid->rates[i] & 0x7f) {
-                       iwe.u.bitrate.value =
-                               ((bssid->rates[i] & 0x7f) *
-                               500000);
-                       devdbg(usbdev, " %d", iwe.u.bitrate.value);
-                       current_val = iwe_stream_add_value(info, cev,
-                               current_val, end_buf, &iwe,
-                               IW_EV_PARAM_LEN);
-               }
-       }
-
-       if ((current_val - cev) > iwe_stream_lcp_len(info))
-               cev = current_val;
-
-       beacon = le32_to_cpu(bssid->config.beacon_period);
-       devdbg(usbdev, "BCN_INT %d", beacon);
-       iwe.cmd = IWEVCUSTOM;
-       snprintf(sbuf, sizeof(sbuf), "bcn_int=%d", beacon);
-       iwe.u.data.length = strlen(sbuf);
-       cev = iwe_stream_add_point(info, cev, end_buf, &iwe, sbuf);
-
-       atim = le32_to_cpu(bssid->config.atim_window);
-       devdbg(usbdev, "ATIM %d", atim);
-       iwe.cmd = IWEVCUSTOM;
-       snprintf(sbuf, sizeof(sbuf), "atim=%u", atim);
-       iwe.u.data.length = strlen(sbuf);
-       cev = iwe_stream_add_point(info, cev, end_buf, &iwe, sbuf);
-
-       ie = (void *)(bssid->ies + sizeof(struct ndis_80211_fixed_ies));
-       ie_len = min(bssid_len - (int)sizeof(*bssid),
-                                       (int)le32_to_cpu(bssid->ie_length));
-       ie_len -= sizeof(struct ndis_80211_fixed_ies);
-       while (ie_len >= 2 && 2 + ie[1] <= ie_len) {
-               if ((ie[0] == WLAN_EID_GENERIC && ie[1] >= 4 &&
-                    memcmp(ie + 2, "\x00\x50\xf2\x01", 4) == 0) ||
-                   ie[0] == WLAN_EID_RSN) {
-                       devdbg(usbdev, "IE: WPA%d",
-                                       (ie[0] == WLAN_EID_RSN) ? 2 : 1);
-                       iwe.cmd = IWEVGENIE;
-                       /* arbitrary cut-off at 64 */
-                       iwe.u.data.length = min(ie[1] + 2, 64);
-                       cev = iwe_stream_add_point(info, cev, end_buf, &iwe, ie);
-               }
-
-               ie_len -= 2 + ie[1];
-               ie += 2 + ie[1];
-       }
-
-       return cev;
-}
-
-
-static int rndis_iw_get_scan(struct net_device *dev,
-    struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
-{
-       struct usbnet *usbdev = netdev_priv(dev);
-       void *buf = NULL;
-       char *cev = extra;
-       struct ndis_80211_bssid_list_ex *bssid_list;
-       struct ndis_80211_bssid_ex *bssid;
-       int ret = -EINVAL, len, count, bssid_len;
-
-       devdbg(usbdev, "SIOCGIWSCAN");
+               flags |= NDIS_80211_ADDKEY_TRANSMIT_KEY;
 
-       len = CONTROL_BUFFER_SIZE;
-       buf = kmalloc(len, GFP_KERNEL);
-       if (!buf) {
-               ret = -ENOMEM;
-               goto out;
-       }
-
-       ret = rndis_query_oid(usbdev, OID_802_11_BSSID_LIST, buf, &len);
-
-       if (ret != 0)
-               goto out;
-
-       bssid_list = buf;
-       bssid = bssid_list->bssid;
-       bssid_len = le32_to_cpu(bssid->length);
-       count = le32_to_cpu(bssid_list->num_items);
-       devdbg(usbdev, "SIOCGIWSCAN: %d BSSIDs found", count);
-
-       while (count && ((void *)bssid + bssid_len) <= (buf + len)) {
-               cev = rndis_translate_scan(dev, info, cev,
-                                          extra + IW_SCAN_MAX_DATA, bssid);
-               bssid = (void *)bssid + bssid_len;
-               bssid_len = le32_to_cpu(bssid->length);
-               count--;
-       }
-
-out:
-       wrqu->data.length = cev - extra;
-       wrqu->data.flags = 0;
-       kfree(buf);
-       return ret;
+       return add_wpa_key(usbdev, ext->key, ext->key_len, keyidx, &ext->addr,
+                               ext->rx_seq, ext->alg, flags);
 }
 
 
@@ -1815,7 +1713,7 @@ static int rndis_iw_set_genie(struct net_device *dev,
     struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
 {
        struct usbnet *usbdev = netdev_priv(dev);
-       struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+       struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
        int ret = 0;
 
 #ifdef DEBUG
@@ -1849,7 +1747,7 @@ static int rndis_iw_get_genie(struct net_device *dev,
     struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
 {
        struct usbnet *usbdev = netdev_priv(dev);
-       struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+       struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
 
        devdbg(usbdev, "SIOCGIWGENIE");
 
@@ -1936,39 +1834,6 @@ static int rndis_iw_get_frag(struct net_device *dev,
 }
 
 
-static int rndis_iw_set_nick(struct net_device *dev,
-    struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
-{
-       struct usbnet *usbdev = netdev_priv(dev);
-       struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
-
-       devdbg(usbdev, "SIOCSIWNICK");
-
-       priv->nick_len = wrqu->data.length;
-       if (priv->nick_len > 32)
-               priv->nick_len = 32;
-
-       memcpy(priv->nick, extra, priv->nick_len);
-       return 0;
-}
-
-
-static int rndis_iw_get_nick(struct net_device *dev,
-    struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
-{
-       struct usbnet *usbdev = netdev_priv(dev);
-       struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
-
-       wrqu->data.flags = 1;
-       wrqu->data.length = priv->nick_len;
-       memcpy(extra, priv->nick, priv->nick_len);
-
-       devdbg(usbdev, "SIOCGIWNICK: '%s'", priv->nick);
-
-       return 0;
-}
-
-
 static int rndis_iw_set_freq(struct net_device *dev,
     struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
 {
@@ -2021,20 +1886,12 @@ static int rndis_iw_get_txpower(struct net_device *dev,
     struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
 {
        struct usbnet *usbdev = netdev_priv(dev);
-       struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+       struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
        __le32 tx_power;
-       int ret = 0, len;
 
        if (priv->radio_on) {
-               if (priv->caps & CAP_SUPPORT_TXPOWER) {
-                       len = sizeof(tx_power);
-                       ret = rndis_query_oid(usbdev, OID_802_11_TX_POWER_LEVEL,
-                                                       &tx_power, &len);
-                       if (ret != 0)
-                               return ret;
-               } else
-                       /* fake incase not supported */
-                       tx_power = cpu_to_le32(get_bcm4320_power(priv));
+               /* fake since changing tx_power (by userlevel) not supported */
+               tx_power = cpu_to_le32(get_bcm4320_power(priv));
 
                wrqu->txpower.flags = IW_TXPOW_MWATT;
                wrqu->txpower.value = le32_to_cpu(tx_power);
@@ -2047,7 +1904,7 @@ static int rndis_iw_get_txpower(struct net_device *dev,
 
        devdbg(usbdev, "SIOCGIWTXPOW: %d", wrqu->txpower.value);
 
-       return ret;
+       return 0;
 }
 
 
@@ -2055,9 +1912,8 @@ static int rndis_iw_set_txpower(struct net_device *dev,
     struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
 {
        struct usbnet *usbdev = netdev_priv(dev);
-       struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+       struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
        __le32 tx_power = 0;
-       int ret = 0;
 
        if (!wrqu->txpower.disabled) {
                if (wrqu->txpower.flags == IW_TXPOW_MWATT)
@@ -2080,22 +1936,10 @@ static int rndis_iw_set_txpower(struct net_device *dev,
        devdbg(usbdev, "SIOCSIWTXPOW: %d", le32_to_cpu(tx_power));
 
        if (le32_to_cpu(tx_power) != 0) {
-               if (priv->caps & CAP_SUPPORT_TXPOWER) {
-                       /* turn radio on first */
-                       if (!priv->radio_on)
-                               disassociate(usbdev, 1);
-
-                       ret = rndis_set_oid(usbdev, OID_802_11_TX_POWER_LEVEL,
-                                               &tx_power, sizeof(tx_power));
-                       if (ret != 0)
-                               ret = -EOPNOTSUPP;
-                       return ret;
-               } else {
-                       /* txpower unsupported, just turn radio on */
-                       if (!priv->radio_on)
-                               return disassociate(usbdev, 1);
-                       return 0; /* all ready on */
-               }
+               /* txpower unsupported, just turn radio on */
+               if (!priv->radio_on)
+                       return disassociate(usbdev, 1);
+               return 0; /* all ready on */
        }
 
        /* tx_power == 0, turn off radio */
@@ -2125,7 +1969,7 @@ static int rndis_iw_set_mlme(struct net_device *dev,
     struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
 {
        struct usbnet *usbdev = netdev_priv(dev);
-       struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+       struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
        struct iw_mlme *mlme = (struct iw_mlme *)extra;
        unsigned char bssid[ETH_ALEN];
 
@@ -2150,7 +1994,7 @@ static int rndis_iw_set_mlme(struct net_device *dev,
 static struct iw_statistics *rndis_get_wireless_stats(struct net_device *dev)
 {
        struct usbnet *usbdev = netdev_priv(dev);
-       struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+       struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
        unsigned long flags;
 
        spin_lock_irqsave(&priv->stats_lock, flags);
@@ -2165,20 +2009,18 @@ static struct iw_statistics *rndis_get_wireless_stats(struct net_device *dev)
 static const iw_handler rndis_iw_handler[] =
 {
        IW_IOCTL(SIOCSIWCOMMIT)    = rndis_iw_commit,
-       IW_IOCTL(SIOCGIWNAME)      = rndis_iw_get_name,
+       IW_IOCTL(SIOCGIWNAME)      = (iw_handler) cfg80211_wext_giwname,
        IW_IOCTL(SIOCSIWFREQ)      = rndis_iw_set_freq,
        IW_IOCTL(SIOCGIWFREQ)      = rndis_iw_get_freq,
-       IW_IOCTL(SIOCSIWMODE)      = rndis_iw_set_mode,
-       IW_IOCTL(SIOCGIWMODE)      = rndis_iw_get_mode,
-       IW_IOCTL(SIOCGIWRANGE)     = rndis_iw_get_range,
+       IW_IOCTL(SIOCSIWMODE)      = (iw_handler) cfg80211_wext_siwmode,
+       IW_IOCTL(SIOCGIWMODE)      = (iw_handler) cfg80211_wext_giwmode,
+       IW_IOCTL(SIOCGIWRANGE)     = (iw_handler) cfg80211_wext_giwrange,
        IW_IOCTL(SIOCSIWAP)        = rndis_iw_set_bssid,
        IW_IOCTL(SIOCGIWAP)        = rndis_iw_get_bssid,
-       IW_IOCTL(SIOCSIWSCAN)      = rndis_iw_set_scan,
-       IW_IOCTL(SIOCGIWSCAN)      = rndis_iw_get_scan,
+       IW_IOCTL(SIOCSIWSCAN)      = (iw_handler) cfg80211_wext_siwscan,
+       IW_IOCTL(SIOCGIWSCAN)      = (iw_handler) cfg80211_wext_giwscan,
        IW_IOCTL(SIOCSIWESSID)     = rndis_iw_set_essid,
        IW_IOCTL(SIOCGIWESSID)     = rndis_iw_get_essid,
-       IW_IOCTL(SIOCSIWNICKN)     = rndis_iw_set_nick,
-       IW_IOCTL(SIOCGIWNICKN)     = rndis_iw_get_nick,
        IW_IOCTL(SIOCGIWRATE)      = rndis_iw_get_rate,
        IW_IOCTL(SIOCSIWRTS)       = rndis_iw_set_rts,
        IW_IOCTL(SIOCGIWRTS)       = rndis_iw_get_rts,
@@ -2195,28 +2037,28 @@ static const iw_handler rndis_iw_handler[] =
        IW_IOCTL(SIOCSIWMLME)      = rndis_iw_set_mlme,
 };
 
-static const iw_handler rndis_wext_private_handler[] = {
+static const iw_handler rndis_wlan_private_handler[] = {
 };
 
-static const struct iw_priv_args rndis_wext_private_args[] = {
+static const struct iw_priv_args rndis_wlan_private_args[] = {
 };
 
 
 static const struct iw_handler_def rndis_iw_handlers = {
        .num_standard = ARRAY_SIZE(rndis_iw_handler),
-       .num_private  = ARRAY_SIZE(rndis_wext_private_handler),
-       .num_private_args = ARRAY_SIZE(rndis_wext_private_args),
+       .num_private  = ARRAY_SIZE(rndis_wlan_private_handler),
+       .num_private_args = ARRAY_SIZE(rndis_wlan_private_args),
        .standard = (iw_handler *)rndis_iw_handler,
-       .private  = (iw_handler *)rndis_wext_private_handler,
-       .private_args = (struct iw_priv_args *)rndis_wext_private_args,
+       .private  = (iw_handler *)rndis_wlan_private_handler,
+       .private_args = (struct iw_priv_args *)rndis_wlan_private_args,
        .get_wireless_stats = rndis_get_wireless_stats,
 };
 
 
-static void rndis_wext_worker(struct work_struct *work)
+static void rndis_wlan_worker(struct work_struct *work)
 {
-       struct rndis_wext_private *priv =
-               container_of(work, struct rndis_wext_private, work);
+       struct rndis_wlan_private *priv =
+               container_of(work, struct rndis_wlan_private, work);
        struct usbnet *usbdev = priv->usbdev;
        union iwreq_data evt;
        unsigned char bssid[ETH_ALEN];
@@ -2277,10 +2119,10 @@ get_bssid:
                set_multicast_list(usbdev);
 }
 
-static void rndis_wext_set_multicast_list(struct net_device *dev)
+static void rndis_wlan_set_multicast_list(struct net_device *dev)
 {
        struct usbnet *usbdev = netdev_priv(dev);
-       struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+       struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
 
        if (test_bit(WORK_SET_MULTICAST_LIST, &priv->work_pending))
                return;
@@ -2289,9 +2131,9 @@ static void rndis_wext_set_multicast_list(struct net_device *dev)
        queue_work(priv->workqueue, &priv->work);
 }
 
-static void rndis_wext_link_change(struct usbnet *usbdev, int state)
+static void rndis_wlan_link_change(struct usbnet *usbdev, int state)
 {
-       struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+       struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
 
        /* queue work to avoid recursive calls into rndis_command */
        set_bit(state ? WORK_LINK_UP : WORK_LINK_DOWN, &priv->work_pending);
@@ -2299,22 +2141,14 @@ static void rndis_wext_link_change(struct usbnet *usbdev, int state)
 }
 
 
-static int rndis_wext_get_caps(struct usbnet *usbdev)
+static int rndis_wlan_get_caps(struct usbnet *usbdev)
 {
        struct {
                __le32  num_items;
                __le32  items[8];
        } networks_supported;
        int len, retval, i, n;
-       __le32 tx_power;
-       struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
-
-       /* determine if supports setting txpower */
-       len = sizeof(tx_power);
-       retval = rndis_query_oid(usbdev, OID_802_11_TX_POWER_LEVEL, &tx_power,
-                                                                       &len);
-       if (retval == 0 && le32_to_cpu(tx_power) != 0xFF)
-               priv->caps |= CAP_SUPPORT_TXPOWER;
+       struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
 
        /* determine supported modes */
        len = sizeof(networks_supported);
@@ -2326,24 +2160,18 @@ static int rndis_wext_get_caps(struct usbnet *usbdev)
                        n = 8;
                for (i = 0; i < n; i++) {
                        switch (le32_to_cpu(networks_supported.items[i])) {
-                       case ndis_80211_type_freq_hop:
-                       case ndis_80211_type_direct_seq:
+                       case NDIS_80211_TYPE_FREQ_HOP:
+                       case NDIS_80211_TYPE_DIRECT_SEQ:
                                priv->caps |= CAP_MODE_80211B;
                                break;
-                       case ndis_80211_type_ofdm_a:
+                       case NDIS_80211_TYPE_OFDM_A:
                                priv->caps |= CAP_MODE_80211A;
                                break;
-                       case ndis_80211_type_ofdm_g:
+                       case NDIS_80211_TYPE_OFDM_G:
                                priv->caps |= CAP_MODE_80211G;
                                break;
                        }
                }
-               if (priv->caps & CAP_MODE_80211A)
-                       strcat(priv->name, "a");
-               if (priv->caps & CAP_MODE_80211B)
-                       strcat(priv->name, "b");
-               if (priv->caps & CAP_MODE_80211G)
-                       strcat(priv->name, "g");
        }
 
        return retval;
@@ -2353,8 +2181,8 @@ static int rndis_wext_get_caps(struct usbnet *usbdev)
 #define STATS_UPDATE_JIFFIES (HZ)
 static void rndis_update_wireless_stats(struct work_struct *work)
 {
-       struct rndis_wext_private *priv =
-               container_of(work, struct rndis_wext_private, stats_work.work);
+       struct rndis_wlan_private *priv =
+               container_of(work, struct rndis_wlan_private, stats_work.work);
        struct usbnet *usbdev = priv->usbdev;
        struct iw_statistics iwstats;
        __le32 rssi, tmp;
@@ -2387,7 +2215,7 @@ static void rndis_update_wireless_stats(struct work_struct *work)
        if (ret == 0) {
                memset(&iwstats.qual, 0, sizeof(iwstats.qual));
                iwstats.qual.qual  = level_to_qual(le32_to_cpu(rssi));
-               iwstats.qual.level = le32_to_cpu(rssi);
+               iwstats.qual.level = level_to_qual(le32_to_cpu(rssi));
                iwstats.qual.updated = IW_QUAL_QUAL_UPDATED
                                | IW_QUAL_LEVEL_UPDATED
                                | IW_QUAL_NOISE_INVALID;
@@ -2457,9 +2285,19 @@ end:
 }
 
 
-static int bcm4320_early_init(struct usbnet *usbdev)
+static int bcm4320a_early_init(struct usbnet *usbdev)
 {
-       struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+       /* bcm4320a doesn't handle configuration parameters well. Try
+        * set any and you get partially zeroed mac and broken device.
+        */
+
+       return 0;
+}
+
+
+static int bcm4320b_early_init(struct usbnet *usbdev)
+{
+       struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
        char buf[8];
 
        /* Early initialization settings, setting these won't have effect
@@ -2525,33 +2363,41 @@ static int bcm4320_early_init(struct usbnet *usbdev)
 }
 
 /* same as rndis_netdev_ops but with local multicast handler */
-static const struct net_device_ops rndis_wext_netdev_ops = {
+static const struct net_device_ops rndis_wlan_netdev_ops = {
        .ndo_open               = usbnet_open,
        .ndo_stop               = usbnet_stop,
        .ndo_start_xmit         = usbnet_start_xmit,
        .ndo_tx_timeout         = usbnet_tx_timeout,
        .ndo_set_mac_address    = eth_mac_addr,
        .ndo_validate_addr      = eth_validate_addr,
-       .ndo_set_multicast_list = rndis_wext_set_multicast_list,
+       .ndo_set_multicast_list = rndis_wlan_set_multicast_list,
 };
 
 
-static int rndis_wext_bind(struct usbnet *usbdev, struct usb_interface *intf)
+static int rndis_wlan_bind(struct usbnet *usbdev, struct usb_interface *intf)
 {
-       struct rndis_wext_private *priv;
+       struct wiphy *wiphy;
+       struct rndis_wlan_private *priv;
        int retval, len;
        __le32 tmp;
 
-       /* allocate rndis private data */
-       priv = kzalloc(sizeof(struct rndis_wext_private), GFP_KERNEL);
-       if (!priv)
+       /* allocate wiphy and rndis private data
+        * NOTE: We only support a single virtual interface, so wiphy
+        * and wireless_dev are somewhat synonymous for this device.
+        */
+       wiphy = wiphy_new(&rndis_config_ops, sizeof(struct rndis_wlan_private));
+       if (!wiphy)
                return -ENOMEM;
 
+       priv = wiphy_priv(wiphy);
+       usbdev->net->ieee80211_ptr = &priv->wdev;
+       priv->wdev.wiphy = wiphy;
+       priv->wdev.iftype = NL80211_IFTYPE_STATION;
+
        /* These have to be initialized before calling generic_rndis_bind().
-        * Otherwise we'll be in big trouble in rndis_wext_early_init().
+        * Otherwise we'll be in big trouble in rndis_wlan_early_init().
         */
        usbdev->driver_priv = priv;
-       strcpy(priv->name, "IEEE802.11");
        usbdev->net->wireless_handlers = &rndis_iw_handlers;
        priv->usbdev = usbdev;
 
@@ -2560,8 +2406,9 @@ static int rndis_wext_bind(struct usbnet *usbdev, struct usb_interface *intf)
 
        /* because rndis_command() sleeps we need to use workqueue */
        priv->workqueue = create_singlethread_workqueue("rndis_wlan");
-       INIT_WORK(&priv->work, rndis_wext_worker);
+       INIT_WORK(&priv->work, rndis_wlan_worker);
        INIT_DELAYED_WORK(&priv->stats_work, rndis_update_wireless_stats);
+       INIT_DELAYED_WORK(&priv->scan_work, rndis_get_scan_results);
 
        /* try bind rndis_host */
        retval = generic_rndis_bind(usbdev, intf, FLAG_RNDIS_PHYM_WIRELESS);
@@ -2573,9 +2420,9 @@ static int rndis_wext_bind(struct usbnet *usbdev, struct usb_interface *intf)
         * picks up rssi to closest station instead of to access point).
         *
         * rndis_host wants to avoid all OID as much as possible
-        * so do promisc/multicast handling in rndis_wext.
+        * so do promisc/multicast handling in rndis_wlan.
         */
-       usbdev->net->netdev_ops = &rndis_wext_netdev_ops;
+       usbdev->net->netdev_ops = &rndis_wlan_netdev_ops;
 
        tmp = RNDIS_PACKET_TYPE_DIRECTED | RNDIS_PACKET_TYPE_BROADCAST;
        retval = rndis_set_oid(usbdev, OID_GEN_CURRENT_PACKET_FILTER, &tmp,
@@ -2600,7 +2447,32 @@ static int rndis_wext_bind(struct usbnet *usbdev, struct usb_interface *intf)
                                        | IW_QUAL_QUAL_INVALID
                                        | IW_QUAL_LEVEL_INVALID;
 
-       rndis_wext_get_caps(usbdev);
+       /* fill-out wiphy structure and register w/ cfg80211 */
+       memcpy(wiphy->perm_addr, usbdev->net->dev_addr, ETH_ALEN);
+       wiphy->privid = rndis_wiphy_privid;
+       wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
+                                       | BIT(NL80211_IFTYPE_ADHOC);
+       wiphy->max_scan_ssids = 1;
+
+       /* TODO: fill-out band information based on priv->caps */
+       rndis_wlan_get_caps(usbdev);
+
+       memcpy(priv->channels, rndis_channels, sizeof(rndis_channels));
+       memcpy(priv->rates, rndis_rates, sizeof(rndis_rates));
+       priv->band.channels = priv->channels;
+       priv->band.n_channels = ARRAY_SIZE(rndis_channels);
+       priv->band.bitrates = priv->rates;
+       priv->band.n_bitrates = ARRAY_SIZE(rndis_rates);
+       wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band;
+       wiphy->signal_type = CFG80211_SIGNAL_TYPE_UNSPEC;
+
+       set_wiphy_dev(wiphy, &usbdev->udev->dev);
+
+       if (wiphy_register(wiphy)) {
+               retval = -ENODEV;
+               goto fail;
+       }
+
        set_default_iw_params(usbdev);
 
        /* turn radio on */
@@ -2615,36 +2487,40 @@ static int rndis_wext_bind(struct usbnet *usbdev, struct usb_interface *intf)
 
 fail:
        cancel_delayed_work_sync(&priv->stats_work);
+       cancel_delayed_work_sync(&priv->scan_work);
        cancel_work_sync(&priv->work);
        flush_workqueue(priv->workqueue);
        destroy_workqueue(priv->workqueue);
 
-       kfree(priv);
+       wiphy_free(wiphy);
        return retval;
 }
 
 
-static void rndis_wext_unbind(struct usbnet *usbdev, struct usb_interface *intf)
+static void rndis_wlan_unbind(struct usbnet *usbdev, struct usb_interface *intf)
 {
-       struct rndis_wext_private *priv = get_rndis_wext_priv(usbdev);
+       struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
 
        /* turn radio off */
        disassociate(usbdev, 0);
 
        cancel_delayed_work_sync(&priv->stats_work);
+       cancel_delayed_work_sync(&priv->scan_work);
        cancel_work_sync(&priv->work);
        flush_workqueue(priv->workqueue);
        destroy_workqueue(priv->workqueue);
 
        if (priv && priv->wpa_ie_len)
                kfree(priv->wpa_ie);
-       kfree(priv);
 
        rndis_unbind(usbdev, intf);
+
+       wiphy_unregister(priv->wdev.wiphy);
+       wiphy_free(priv->wdev.wiphy);
 }
 
 
-static int rndis_wext_reset(struct usbnet *usbdev)
+static int rndis_wlan_reset(struct usbnet *usbdev)
 {
        return deauthenticate(usbdev);
 }
@@ -2653,40 +2529,40 @@ static int rndis_wext_reset(struct usbnet *usbdev)
 static const struct driver_info        bcm4320b_info = {
        .description =  "Wireless RNDIS device, BCM4320b based",
        .flags =        FLAG_WLAN | FLAG_FRAMING_RN | FLAG_NO_SETINT,
-       .bind =         rndis_wext_bind,
-       .unbind =       rndis_wext_unbind,
+       .bind =         rndis_wlan_bind,
+       .unbind =       rndis_wlan_unbind,
        .status =       rndis_status,
        .rx_fixup =     rndis_rx_fixup,
        .tx_fixup =     rndis_tx_fixup,
-       .reset =        rndis_wext_reset,
-       .early_init =   bcm4320_early_init,
-       .link_change =  rndis_wext_link_change,
+       .reset =        rndis_wlan_reset,
+       .early_init =   bcm4320b_early_init,
+       .link_change =  rndis_wlan_link_change,
 };
 
 static const struct driver_info        bcm4320a_info = {
        .description =  "Wireless RNDIS device, BCM4320a based",
        .flags =        FLAG_WLAN | FLAG_FRAMING_RN | FLAG_NO_SETINT,
-       .bind =         rndis_wext_bind,
-       .unbind =       rndis_wext_unbind,
+       .bind =         rndis_wlan_bind,
+       .unbind =       rndis_wlan_unbind,
        .status =       rndis_status,
        .rx_fixup =     rndis_rx_fixup,
        .tx_fixup =     rndis_tx_fixup,
-       .reset =        rndis_wext_reset,
-       .early_init =   bcm4320_early_init,
-       .link_change =  rndis_wext_link_change,
+       .reset =        rndis_wlan_reset,
+       .early_init =   bcm4320a_early_init,
+       .link_change =  rndis_wlan_link_change,
 };
 
-static const struct driver_info rndis_wext_info = {
+static const struct driver_info rndis_wlan_info = {
        .description =  "Wireless RNDIS device",
        .flags =        FLAG_WLAN | FLAG_FRAMING_RN | FLAG_NO_SETINT,
-       .bind =         rndis_wext_bind,
-       .unbind =       rndis_wext_unbind,
+       .bind =         rndis_wlan_bind,
+       .unbind =       rndis_wlan_unbind,
        .status =       rndis_status,
        .rx_fixup =     rndis_rx_fixup,
        .tx_fixup =     rndis_tx_fixup,
-       .reset =        rndis_wext_reset,
-       .early_init =   bcm4320_early_init,
-       .link_change =  rndis_wext_link_change,
+       .reset =        rndis_wlan_reset,
+       .early_init =   bcm4320a_early_init,
+       .link_change =  rndis_wlan_link_change,
 };
 
 /*-------------------------------------------------------------------------*/
@@ -2796,11 +2672,11 @@ static const struct usb_device_id products [] = {
 {
        /* RNDIS is MSFT's un-official variant of CDC ACM */
        USB_INTERFACE_INFO(USB_CLASS_COMM, 2 /* ACM */, 0x0ff),
-       .driver_info = (unsigned long) &rndis_wext_info,
+       .driver_info = (unsigned long) &rndis_wlan_info,
 }, {
        /* "ActiveSync" is an undocumented variant of RNDIS, used in WM5 */
        USB_INTERFACE_INFO(USB_CLASS_MISC, 1, 1),
-       .driver_info = (unsigned long) &rndis_wext_info,
+       .driver_info = (unsigned long) &rndis_wlan_info,
 },
        { },            // END
 };
index 1ae11c7f17affe210ed50782611c15f6db99796d..8aab3e6754bdae25d331ca1b0f627d96d6622820 100644 (file)
@@ -77,6 +77,20 @@ config RT73USB
 
          When compiled as a module, this driver will be called rt73usb.
 
+config RT2800USB
+       tristate "Ralink rt2800 (USB) support"
+       depends on USB
+       select RT2X00_LIB_USB
+       select RT2X00_LIB_HT
+       select RT2X00_LIB_FIRMWARE
+       select RT2X00_LIB_CRYPTO
+       select CRC_CCITT
+       ---help---
+         This adds support for rt2800 wireless chipset family.
+         Supported chips: RT2770, RT2870 & RT3070.
+
+         When compiled as a module, this driver will be called "rt2800usb.ko".
+
 config RT2X00_LIB_PCI
        tristate
        select RT2X00_LIB
@@ -88,6 +102,9 @@ config RT2X00_LIB_USB
 config RT2X00_LIB
        tristate
 
+config RT2X00_LIB_HT
+       boolean
+
 config RT2X00_LIB_FIRMWARE
        boolean
        select FW_LOADER
index f22d808d8c511bb8958d1f52268b0db02af3f823..bfc7226f0afe2da6bb8b92b3e20d04ba5e0d93b3 100644 (file)
@@ -8,6 +8,7 @@ rt2x00lib-$(CONFIG_RT2X00_LIB_CRYPTO)   += rt2x00crypto.o
 rt2x00lib-$(CONFIG_RT2X00_LIB_RFKILL)  += rt2x00rfkill.o
 rt2x00lib-$(CONFIG_RT2X00_LIB_FIRMWARE)        += rt2x00firmware.o
 rt2x00lib-$(CONFIG_RT2X00_LIB_LEDS)    += rt2x00leds.o
+rt2x00lib-$(CONFIG_RT2X00_LIB_HT)      += rt2x00ht.o
 
 obj-$(CONFIG_RT2X00_LIB)               += rt2x00lib.o
 obj-$(CONFIG_RT2X00_LIB_PCI)           += rt2x00pci.o
@@ -17,3 +18,4 @@ obj-$(CONFIG_RT2500PCI)                       += rt2500pci.o
 obj-$(CONFIG_RT61PCI)                  += rt61pci.o
 obj-$(CONFIG_RT2500USB)                        += rt2500usb.o
 obj-$(CONFIG_RT73USB)                  += rt73usb.o
+obj-$(CONFIG_RT2800USB)                        += rt2800usb.o
index 0f08773328c6b8f182936fbb9dc2e95f58401226..435f945fe64dff87cf602250adbcbc512ed98667 100644 (file)
@@ -335,10 +335,11 @@ static void rt2400pci_config_erp(struct rt2x00_dev *rt2x00dev,
        preamble_mask = erp->short_preamble << 3;
 
        rt2x00pci_register_read(rt2x00dev, TXCSR1, &reg);
-       rt2x00_set_field32(&reg, TXCSR1_ACK_TIMEOUT,
-                          erp->ack_timeout);
+       rt2x00_set_field32(&reg, TXCSR1_ACK_TIMEOUT, erp->ack_timeout);
        rt2x00_set_field32(&reg, TXCSR1_ACK_CONSUME_TIME,
                           erp->ack_consume_time);
+       rt2x00_set_field32(&reg, TXCSR1_TSF_OFFSET, IEEE80211_HEADER);
+       rt2x00_set_field32(&reg, TXCSR1_AUTORESPONDER, 1);
        rt2x00pci_register_write(rt2x00dev, TXCSR1, reg);
 
        rt2x00pci_register_read(rt2x00dev, ARCSR2, &reg);
@@ -371,6 +372,11 @@ static void rt2400pci_config_erp(struct rt2x00_dev *rt2x00dev,
        rt2x00_set_field32(&reg, CSR11_SLOT_TIME, erp->slot_time);
        rt2x00pci_register_write(rt2x00dev, CSR11, reg);
 
+       rt2x00pci_register_read(rt2x00dev, CSR12, &reg);
+       rt2x00_set_field32(&reg, CSR12_BEACON_INTERVAL, erp->beacon_int * 16);
+       rt2x00_set_field32(&reg, CSR12_CFP_MAX_DURATION, erp->beacon_int * 16);
+       rt2x00pci_register_write(rt2x00dev, CSR12, reg);
+
        rt2x00pci_register_read(rt2x00dev, CSR18, &reg);
        rt2x00_set_field32(&reg, CSR18_SIFS, erp->sifs);
        rt2x00_set_field32(&reg, CSR18_PIFS, erp->pifs);
@@ -503,24 +509,6 @@ static void rt2400pci_config_retry_limit(struct rt2x00_dev *rt2x00dev,
        rt2x00pci_register_write(rt2x00dev, CSR11, reg);
 }
 
-static void rt2400pci_config_duration(struct rt2x00_dev *rt2x00dev,
-                                     struct rt2x00lib_conf *libconf)
-{
-       u32 reg;
-
-       rt2x00pci_register_read(rt2x00dev, TXCSR1, &reg);
-       rt2x00_set_field32(&reg, TXCSR1_TSF_OFFSET, IEEE80211_HEADER);
-       rt2x00_set_field32(&reg, TXCSR1_AUTORESPONDER, 1);
-       rt2x00pci_register_write(rt2x00dev, TXCSR1, reg);
-
-       rt2x00pci_register_read(rt2x00dev, CSR12, &reg);
-       rt2x00_set_field32(&reg, CSR12_BEACON_INTERVAL,
-                          libconf->conf->beacon_int * 16);
-       rt2x00_set_field32(&reg, CSR12_CFP_MAX_DURATION,
-                          libconf->conf->beacon_int * 16);
-       rt2x00pci_register_write(rt2x00dev, CSR12, reg);
-}
-
 static void rt2400pci_config_ps(struct rt2x00_dev *rt2x00dev,
                                struct rt2x00lib_conf *libconf)
 {
@@ -532,7 +520,7 @@ static void rt2400pci_config_ps(struct rt2x00_dev *rt2x00dev,
        if (state == STATE_SLEEP) {
                rt2x00pci_register_read(rt2x00dev, CSR20, &reg);
                rt2x00_set_field32(&reg, CSR20_DELAY_AFTER_TBCN,
-                                  (libconf->conf->beacon_int - 20) * 16);
+                                  (rt2x00dev->beacon_int - 20) * 16);
                rt2x00_set_field32(&reg, CSR20_TBCN_BEFORE_WAKEUP,
                                   libconf->conf->listen_interval - 1);
 
@@ -558,8 +546,6 @@ static void rt2400pci_config(struct rt2x00_dev *rt2x00dev,
                                         libconf->conf->power_level);
        if (flags & IEEE80211_CONF_CHANGE_RETRY_LIMITS)
                rt2400pci_config_retry_limit(rt2x00dev, libconf);
-       if (flags & IEEE80211_CONF_CHANGE_BEACON_INTERVAL)
-               rt2400pci_config_duration(rt2x00dev, libconf);
        if (flags & IEEE80211_CONF_CHANGE_PS)
                rt2400pci_config_ps(rt2x00dev, libconf);
 }
@@ -1361,7 +1347,7 @@ static int rt2400pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
         */
        value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE);
        rt2x00pci_register_read(rt2x00dev, CSR0, &reg);
-       rt2x00_set_chip(rt2x00dev, RT2460, value, reg);
+       rt2x00_set_chip_rf(rt2x00dev, value, reg);
 
        if (!rt2x00_rf(&rt2x00dev->chip, RF2420) &&
            !rt2x00_rf(&rt2x00dev->chip, RF2421)) {
@@ -1580,7 +1566,6 @@ static const struct ieee80211_ops rt2400pci_mac80211_ops = {
        .add_interface          = rt2x00mac_add_interface,
        .remove_interface       = rt2x00mac_remove_interface,
        .config                 = rt2x00mac_config,
-       .config_interface       = rt2x00mac_config_interface,
        .configure_filter       = rt2x00mac_configure_filter,
        .get_stats              = rt2x00mac_get_stats,
        .bss_info_changed       = rt2x00mac_bss_info_changed,
index 276a8232aaa084583a5b4b97897c4a8207b25f7b..08b30d01e67d8d378b91c90dd7d04027f79e3b21 100644 (file)
@@ -341,10 +341,11 @@ static void rt2500pci_config_erp(struct rt2x00_dev *rt2x00dev,
        preamble_mask = erp->short_preamble << 3;
 
        rt2x00pci_register_read(rt2x00dev, TXCSR1, &reg);
-       rt2x00_set_field32(&reg, TXCSR1_ACK_TIMEOUT,
-                          erp->ack_timeout);
+       rt2x00_set_field32(&reg, TXCSR1_ACK_TIMEOUT, erp->ack_timeout);
        rt2x00_set_field32(&reg, TXCSR1_ACK_CONSUME_TIME,
                           erp->ack_consume_time);
+       rt2x00_set_field32(&reg, TXCSR1_TSF_OFFSET, IEEE80211_HEADER);
+       rt2x00_set_field32(&reg, TXCSR1_AUTORESPONDER, 1);
        rt2x00pci_register_write(rt2x00dev, TXCSR1, reg);
 
        rt2x00pci_register_read(rt2x00dev, ARCSR2, &reg);
@@ -377,6 +378,11 @@ static void rt2500pci_config_erp(struct rt2x00_dev *rt2x00dev,
        rt2x00_set_field32(&reg, CSR11_SLOT_TIME, erp->slot_time);
        rt2x00pci_register_write(rt2x00dev, CSR11, reg);
 
+       rt2x00pci_register_read(rt2x00dev, CSR12, &reg);
+       rt2x00_set_field32(&reg, CSR12_BEACON_INTERVAL, erp->beacon_int * 16);
+       rt2x00_set_field32(&reg, CSR12_CFP_MAX_DURATION, erp->beacon_int * 16);
+       rt2x00pci_register_write(rt2x00dev, CSR12, reg);
+
        rt2x00pci_register_read(rt2x00dev, CSR18, &reg);
        rt2x00_set_field32(&reg, CSR18_SIFS, erp->sifs);
        rt2x00_set_field32(&reg, CSR18_PIFS, erp->pifs);
@@ -552,24 +558,6 @@ static void rt2500pci_config_retry_limit(struct rt2x00_dev *rt2x00dev,
        rt2x00pci_register_write(rt2x00dev, CSR11, reg);
 }
 
-static void rt2500pci_config_duration(struct rt2x00_dev *rt2x00dev,
-                                     struct rt2x00lib_conf *libconf)
-{
-       u32 reg;
-
-       rt2x00pci_register_read(rt2x00dev, TXCSR1, &reg);
-       rt2x00_set_field32(&reg, TXCSR1_TSF_OFFSET, IEEE80211_HEADER);
-       rt2x00_set_field32(&reg, TXCSR1_AUTORESPONDER, 1);
-       rt2x00pci_register_write(rt2x00dev, TXCSR1, reg);
-
-       rt2x00pci_register_read(rt2x00dev, CSR12, &reg);
-       rt2x00_set_field32(&reg, CSR12_BEACON_INTERVAL,
-                          libconf->conf->beacon_int * 16);
-       rt2x00_set_field32(&reg, CSR12_CFP_MAX_DURATION,
-                          libconf->conf->beacon_int * 16);
-       rt2x00pci_register_write(rt2x00dev, CSR12, reg);
-}
-
 static void rt2500pci_config_ps(struct rt2x00_dev *rt2x00dev,
                                struct rt2x00lib_conf *libconf)
 {
@@ -581,7 +569,7 @@ static void rt2500pci_config_ps(struct rt2x00_dev *rt2x00dev,
        if (state == STATE_SLEEP) {
                rt2x00pci_register_read(rt2x00dev, CSR20, &reg);
                rt2x00_set_field32(&reg, CSR20_DELAY_AFTER_TBCN,
-                                  (libconf->conf->beacon_int - 20) * 16);
+                                  (rt2x00dev->beacon_int - 20) * 16);
                rt2x00_set_field32(&reg, CSR20_TBCN_BEFORE_WAKEUP,
                                   libconf->conf->listen_interval - 1);
 
@@ -609,8 +597,6 @@ static void rt2500pci_config(struct rt2x00_dev *rt2x00dev,
                                         libconf->conf->power_level);
        if (flags & IEEE80211_CONF_CHANGE_RETRY_LIMITS)
                rt2500pci_config_retry_limit(rt2x00dev, libconf);
-       if (flags & IEEE80211_CONF_CHANGE_BEACON_INTERVAL)
-               rt2500pci_config_duration(rt2x00dev, libconf);
        if (flags & IEEE80211_CONF_CHANGE_PS)
                rt2500pci_config_ps(rt2x00dev, libconf);
 }
@@ -1525,7 +1511,7 @@ static int rt2500pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
         */
        value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE);
        rt2x00pci_register_read(rt2x00dev, CSR0, &reg);
-       rt2x00_set_chip(rt2x00dev, RT2560, value, reg);
+       rt2x00_set_chip_rf(rt2x00dev, value, reg);
 
        if (!rt2x00_rf(&rt2x00dev->chip, RF2522) &&
            !rt2x00_rf(&rt2x00dev->chip, RF2523) &&
@@ -1879,7 +1865,6 @@ static const struct ieee80211_ops rt2500pci_mac80211_ops = {
        .add_interface          = rt2x00mac_add_interface,
        .remove_interface       = rt2x00mac_remove_interface,
        .config                 = rt2x00mac_config,
-       .config_interface       = rt2x00mac_config_interface,
        .configure_filter       = rt2x00mac_configure_filter,
        .get_stats              = rt2x00mac_get_stats,
        .bss_info_changed       = rt2x00mac_bss_info_changed,
index 9e630e70fc976d9d6da06c42ab80bf6970a81778..66daf68ff0ee9e35de4d0933413198432381cfbf 100644 (file)
@@ -503,6 +503,10 @@ static void rt2500usb_config_erp(struct rt2x00_dev *rt2x00dev,
 
        rt2500usb_register_write(rt2x00dev, TXRX_CSR11, erp->basic_rates);
 
+       rt2500usb_register_read(rt2x00dev, TXRX_CSR18, &reg);
+       rt2x00_set_field16(&reg, TXRX_CSR18_INTERVAL, erp->beacon_int * 4);
+       rt2500usb_register_write(rt2x00dev, TXRX_CSR18, reg);
+
        rt2500usb_register_write(rt2x00dev, MAC_CSR10, erp->slot_time);
        rt2500usb_register_write(rt2x00dev, MAC_CSR11, erp->sifs);
        rt2500usb_register_write(rt2x00dev, MAC_CSR12, erp->eifs);
@@ -632,17 +636,6 @@ static void rt2500usb_config_txpower(struct rt2x00_dev *rt2x00dev,
        rt2500usb_rf_write(rt2x00dev, 3, rf3);
 }
 
-static void rt2500usb_config_duration(struct rt2x00_dev *rt2x00dev,
-                                     struct rt2x00lib_conf *libconf)
-{
-       u16 reg;
-
-       rt2500usb_register_read(rt2x00dev, TXRX_CSR18, &reg);
-       rt2x00_set_field16(&reg, TXRX_CSR18_INTERVAL,
-                          libconf->conf->beacon_int * 4);
-       rt2500usb_register_write(rt2x00dev, TXRX_CSR18, reg);
-}
-
 static void rt2500usb_config_ps(struct rt2x00_dev *rt2x00dev,
                                struct rt2x00lib_conf *libconf)
 {
@@ -654,7 +647,7 @@ static void rt2500usb_config_ps(struct rt2x00_dev *rt2x00dev,
        if (state == STATE_SLEEP) {
                rt2500usb_register_read(rt2x00dev, MAC_CSR18, &reg);
                rt2x00_set_field16(&reg, MAC_CSR18_DELAY_AFTER_BEACON,
-                                  libconf->conf->beacon_int - 20);
+                                  rt2x00dev->beacon_int - 20);
                rt2x00_set_field16(&reg, MAC_CSR18_BEACONS_BEFORE_WAKEUP,
                                   libconf->conf->listen_interval - 1);
 
@@ -680,8 +673,6 @@ static void rt2500usb_config(struct rt2x00_dev *rt2x00dev,
            !(flags & IEEE80211_CONF_CHANGE_CHANNEL))
                rt2500usb_config_txpower(rt2x00dev,
                                         libconf->conf->power_level);
-       if (flags & IEEE80211_CONF_CHANGE_BEACON_INTERVAL)
-               rt2500usb_config_duration(rt2x00dev, libconf);
        if (flags & IEEE80211_CONF_CHANGE_PS)
                rt2500usb_config_ps(rt2x00dev, libconf);
 }
@@ -1559,7 +1550,7 @@ static int rt2500usb_init_eeprom(struct rt2x00_dev *rt2x00dev)
        rt2500usb_register_read(rt2x00dev, MAC_CSR0, &reg);
        rt2x00_set_chip(rt2x00dev, RT2570, value, reg);
 
-       if (!rt2x00_check_rev(&rt2x00dev->chip, 0)) {
+       if (!rt2x00_check_rev(&rt2x00dev->chip, 0x000ffff0, 0)) {
                ERROR(rt2x00dev, "Invalid RT chipset detected.\n");
                return -ENODEV;
        }
@@ -1908,7 +1899,6 @@ static const struct ieee80211_ops rt2500usb_mac80211_ops = {
        .add_interface          = rt2x00mac_add_interface,
        .remove_interface       = rt2x00mac_remove_interface,
        .config                 = rt2x00mac_config,
-       .config_interface       = rt2x00mac_config_interface,
        .configure_filter       = rt2x00mac_configure_filter,
        .set_key                = rt2x00mac_set_key,
        .get_stats              = rt2x00mac_get_stats,
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
new file mode 100644 (file)
index 0000000..3756166
--- /dev/null
@@ -0,0 +1,3078 @@
+/*
+       Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
+       <http://rt2x00.serialmonkey.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.
+
+       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.
+ */
+
+/*
+       Module: rt2800usb
+       Abstract: rt2800usb device specific routines.
+       Supported chipsets: RT2800U.
+ */
+
+#include <linux/crc-ccitt.h>
+#include <linux/delay.h>
+#include <linux/etherdevice.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+
+#include "rt2x00.h"
+#include "rt2x00usb.h"
+#include "rt2800usb.h"
+
+/*
+ * Allow hardware encryption to be disabled.
+ */
+static int modparam_nohwcrypt = 1;
+module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
+MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
+
+/*
+ * Register access.
+ * All access to the CSR registers will go through the methods
+ * rt2x00usb_register_read and rt2x00usb_register_write.
+ * BBP and RF register require indirect register access,
+ * and use the CSR registers BBPCSR and RFCSR to achieve this.
+ * These indirect registers work with busy bits,
+ * and we will try maximal REGISTER_BUSY_COUNT times to access
+ * the register while taking a REGISTER_BUSY_DELAY us delay
+ * between each attampt. When the busy bit is still set at that time,
+ * the access attempt is considered to have failed,
+ * and we will print an error.
+ * The _lock versions must be used if you already hold the csr_mutex
+ */
+#define WAIT_FOR_BBP(__dev, __reg) \
+       rt2x00usb_regbusy_read((__dev), BBP_CSR_CFG, BBP_CSR_CFG_BUSY, (__reg))
+#define WAIT_FOR_RFCSR(__dev, __reg) \
+       rt2x00usb_regbusy_read((__dev), RF_CSR_CFG, RF_CSR_CFG_BUSY, (__reg))
+#define WAIT_FOR_RF(__dev, __reg) \
+       rt2x00usb_regbusy_read((__dev), RF_CSR_CFG0, RF_CSR_CFG0_BUSY, (__reg))
+#define WAIT_FOR_MCU(__dev, __reg) \
+       rt2x00usb_regbusy_read((__dev), H2M_MAILBOX_CSR, \
+                              H2M_MAILBOX_CSR_OWNER, (__reg))
+
+static void rt2800usb_bbp_write(struct rt2x00_dev *rt2x00dev,
+                               const unsigned int word, const u8 value)
+{
+       u32 reg;
+
+       mutex_lock(&rt2x00dev->csr_mutex);
+
+       /*
+        * Wait until the BBP becomes available, afterwards we
+        * can safely write the new data into the register.
+        */
+       if (WAIT_FOR_BBP(rt2x00dev, &reg)) {
+               reg = 0;
+               rt2x00_set_field32(&reg, BBP_CSR_CFG_VALUE, value);
+               rt2x00_set_field32(&reg, BBP_CSR_CFG_REGNUM, word);
+               rt2x00_set_field32(&reg, BBP_CSR_CFG_BUSY, 1);
+               rt2x00_set_field32(&reg, BBP_CSR_CFG_READ_CONTROL, 0);
+
+               rt2x00usb_register_write_lock(rt2x00dev, BBP_CSR_CFG, reg);
+       }
+
+       mutex_unlock(&rt2x00dev->csr_mutex);
+}
+
+static void rt2800usb_bbp_read(struct rt2x00_dev *rt2x00dev,
+                              const unsigned int word, u8 *value)
+{
+       u32 reg;
+
+       mutex_lock(&rt2x00dev->csr_mutex);
+
+       /*
+        * Wait until the BBP becomes available, afterwards we
+        * can safely write the read request into the register.
+        * After the data has been written, we wait until hardware
+        * returns the correct value, if at any time the register
+        * doesn't become available in time, reg will be 0xffffffff
+        * which means we return 0xff to the caller.
+        */
+       if (WAIT_FOR_BBP(rt2x00dev, &reg)) {
+               reg = 0;
+               rt2x00_set_field32(&reg, BBP_CSR_CFG_REGNUM, word);
+               rt2x00_set_field32(&reg, BBP_CSR_CFG_BUSY, 1);
+               rt2x00_set_field32(&reg, BBP_CSR_CFG_READ_CONTROL, 1);
+
+               rt2x00usb_register_write_lock(rt2x00dev, BBP_CSR_CFG, reg);
+
+               WAIT_FOR_BBP(rt2x00dev, &reg);
+       }
+
+       *value = rt2x00_get_field32(reg, BBP_CSR_CFG_VALUE);
+
+       mutex_unlock(&rt2x00dev->csr_mutex);
+}
+
+static void rt2800usb_rfcsr_write(struct rt2x00_dev *rt2x00dev,
+                                 const unsigned int word, const u8 value)
+{
+       u32 reg;
+
+       mutex_lock(&rt2x00dev->csr_mutex);
+
+       /*
+        * Wait until the RFCSR becomes available, afterwards we
+        * can safely write the new data into the register.
+        */
+       if (WAIT_FOR_RFCSR(rt2x00dev, &reg)) {
+               reg = 0;
+               rt2x00_set_field32(&reg, RF_CSR_CFG_DATA, value);
+               rt2x00_set_field32(&reg, RF_CSR_CFG_REGNUM, word);
+               rt2x00_set_field32(&reg, RF_CSR_CFG_WRITE, 1);
+               rt2x00_set_field32(&reg, RF_CSR_CFG_BUSY, 1);
+
+               rt2x00usb_register_write_lock(rt2x00dev, RF_CSR_CFG, reg);
+       }
+
+       mutex_unlock(&rt2x00dev->csr_mutex);
+}
+
+static void rt2800usb_rfcsr_read(struct rt2x00_dev *rt2x00dev,
+                                const unsigned int word, u8 *value)
+{
+       u32 reg;
+
+       mutex_lock(&rt2x00dev->csr_mutex);
+
+       /*
+        * Wait until the RFCSR becomes available, afterwards we
+        * can safely write the read request into the register.
+        * After the data has been written, we wait until hardware
+        * returns the correct value, if at any time the register
+        * doesn't become available in time, reg will be 0xffffffff
+        * which means we return 0xff to the caller.
+        */
+       if (WAIT_FOR_RFCSR(rt2x00dev, &reg)) {
+               reg = 0;
+               rt2x00_set_field32(&reg, RF_CSR_CFG_REGNUM, word);
+               rt2x00_set_field32(&reg, RF_CSR_CFG_WRITE, 0);
+               rt2x00_set_field32(&reg, RF_CSR_CFG_BUSY, 1);
+
+               rt2x00usb_register_write_lock(rt2x00dev, BBP_CSR_CFG, reg);
+
+               WAIT_FOR_RFCSR(rt2x00dev, &reg);
+       }
+
+       *value = rt2x00_get_field32(reg, RF_CSR_CFG_DATA);
+
+       mutex_unlock(&rt2x00dev->csr_mutex);
+}
+
+static void rt2800usb_rf_write(struct rt2x00_dev *rt2x00dev,
+                              const unsigned int word, const u32 value)
+{
+       u32 reg;
+
+       mutex_lock(&rt2x00dev->csr_mutex);
+
+       /*
+        * Wait until the RF becomes available, afterwards we
+        * can safely write the new data into the register.
+        */
+       if (WAIT_FOR_RF(rt2x00dev, &reg)) {
+               reg = 0;
+               rt2x00_set_field32(&reg, RF_CSR_CFG0_REG_VALUE_BW, value);
+               rt2x00_set_field32(&reg, RF_CSR_CFG0_STANDBYMODE, 0);
+               rt2x00_set_field32(&reg, RF_CSR_CFG0_SEL, 0);
+               rt2x00_set_field32(&reg, RF_CSR_CFG0_BUSY, 1);
+
+               rt2x00usb_register_write_lock(rt2x00dev, RF_CSR_CFG0, reg);
+               rt2x00_rf_write(rt2x00dev, word, value);
+       }
+
+       mutex_unlock(&rt2x00dev->csr_mutex);
+}
+
+static void rt2800usb_mcu_request(struct rt2x00_dev *rt2x00dev,
+                                 const u8 command, const u8 token,
+                                 const u8 arg0, const u8 arg1)
+{
+       u32 reg;
+
+       mutex_lock(&rt2x00dev->csr_mutex);
+
+       /*
+        * Wait until the MCU becomes available, afterwards we
+        * can safely write the new data into the register.
+        */
+       if (WAIT_FOR_MCU(rt2x00dev, &reg)) {
+               rt2x00_set_field32(&reg, H2M_MAILBOX_CSR_OWNER, 1);
+               rt2x00_set_field32(&reg, H2M_MAILBOX_CSR_CMD_TOKEN, token);
+               rt2x00_set_field32(&reg, H2M_MAILBOX_CSR_ARG0, arg0);
+               rt2x00_set_field32(&reg, H2M_MAILBOX_CSR_ARG1, arg1);
+               rt2x00usb_register_write_lock(rt2x00dev, H2M_MAILBOX_CSR, reg);
+
+               reg = 0;
+               rt2x00_set_field32(&reg, HOST_CMD_CSR_HOST_COMMAND, command);
+               rt2x00usb_register_write_lock(rt2x00dev, HOST_CMD_CSR, reg);
+       }
+
+       mutex_unlock(&rt2x00dev->csr_mutex);
+}
+
+#ifdef CONFIG_RT2X00_LIB_DEBUGFS
+static const struct rt2x00debug rt2800usb_rt2x00debug = {
+       .owner  = THIS_MODULE,
+       .csr    = {
+               .read           = rt2x00usb_register_read,
+               .write          = rt2x00usb_register_write,
+               .flags          = RT2X00DEBUGFS_OFFSET,
+               .word_base      = CSR_REG_BASE,
+               .word_size      = sizeof(u32),
+               .word_count     = CSR_REG_SIZE / sizeof(u32),
+       },
+       .eeprom = {
+               .read           = rt2x00_eeprom_read,
+               .write          = rt2x00_eeprom_write,
+               .word_base      = EEPROM_BASE,
+               .word_size      = sizeof(u16),
+               .word_count     = EEPROM_SIZE / sizeof(u16),
+       },
+       .bbp    = {
+               .read           = rt2800usb_bbp_read,
+               .write          = rt2800usb_bbp_write,
+               .word_base      = BBP_BASE,
+               .word_size      = sizeof(u8),
+               .word_count     = BBP_SIZE / sizeof(u8),
+       },
+       .rf     = {
+               .read           = rt2x00_rf_read,
+               .write          = rt2800usb_rf_write,
+               .word_base      = RF_BASE,
+               .word_size      = sizeof(u32),
+               .word_count     = RF_SIZE / sizeof(u32),
+       },
+};
+#endif /* CONFIG_RT2X00_LIB_DEBUGFS */
+
+#ifdef CONFIG_RT2X00_LIB_RFKILL
+static int rt2800usb_rfkill_poll(struct rt2x00_dev *rt2x00dev)
+{
+       u32 reg;
+
+       rt2x00usb_register_read(rt2x00dev, GPIO_CTRL_CFG, &reg);
+       return rt2x00_get_field32(reg, GPIO_CTRL_CFG_BIT2);
+}
+#else
+#define rt2800usb_rfkill_poll  NULL
+#endif /* CONFIG_RT2X00_LIB_RFKILL */
+
+#ifdef CONFIG_RT2X00_LIB_LEDS
+static void rt2800usb_brightness_set(struct led_classdev *led_cdev,
+                                    enum led_brightness brightness)
+{
+       struct rt2x00_led *led =
+           container_of(led_cdev, struct rt2x00_led, led_dev);
+       unsigned int enabled = brightness != LED_OFF;
+       unsigned int bg_mode =
+           (enabled && led->rt2x00dev->curr_band == IEEE80211_BAND_2GHZ);
+       unsigned int polarity =
+               rt2x00_get_field16(led->rt2x00dev->led_mcu_reg,
+                                  EEPROM_FREQ_LED_POLARITY);
+       unsigned int ledmode =
+               rt2x00_get_field16(led->rt2x00dev->led_mcu_reg,
+                                  EEPROM_FREQ_LED_MODE);
+
+       if (led->type == LED_TYPE_RADIO) {
+               rt2800usb_mcu_request(led->rt2x00dev, MCU_LED, 0xff, ledmode,
+                                     enabled ? 0x20 : 0);
+       } else if (led->type == LED_TYPE_ASSOC) {
+               rt2800usb_mcu_request(led->rt2x00dev, MCU_LED, 0xff, ledmode,
+                                     enabled ? (bg_mode ? 0x60 : 0xa0) : 0x20);
+       } else if (led->type == LED_TYPE_QUALITY) {
+               /*
+                * The brightness is divided into 6 levels (0 - 5),
+                * The specs tell us the following levels:
+                *      0, 1 ,3, 7, 15, 31
+                * to determine the level in a simple way we can simply
+                * work with bitshifting:
+                *      (1 << level) - 1
+                */
+               rt2800usb_mcu_request(led->rt2x00dev, MCU_LED_STRENGTH, 0xff,
+                                     (1 << brightness / (LED_FULL / 6)) - 1,
+                                     polarity);
+       }
+}
+
+static int rt2800usb_blink_set(struct led_classdev *led_cdev,
+                              unsigned long *delay_on,
+                              unsigned long *delay_off)
+{
+       struct rt2x00_led *led =
+           container_of(led_cdev, struct rt2x00_led, led_dev);
+       u32 reg;
+
+       rt2x00usb_register_read(led->rt2x00dev, LED_CFG, &reg);
+       rt2x00_set_field32(&reg, LED_CFG_ON_PERIOD, *delay_on);
+       rt2x00_set_field32(&reg, LED_CFG_OFF_PERIOD, *delay_off);
+       rt2x00_set_field32(&reg, LED_CFG_SLOW_BLINK_PERIOD, 3);
+       rt2x00_set_field32(&reg, LED_CFG_R_LED_MODE, 3);
+       rt2x00_set_field32(&reg, LED_CFG_G_LED_MODE, 12);
+       rt2x00_set_field32(&reg, LED_CFG_Y_LED_MODE, 3);
+       rt2x00_set_field32(&reg, LED_CFG_LED_POLAR, 1);
+       rt2x00usb_register_write(led->rt2x00dev, LED_CFG, reg);
+
+       return 0;
+}
+
+static void rt2800usb_init_led(struct rt2x00_dev *rt2x00dev,
+                              struct rt2x00_led *led,
+                              enum led_type type)
+{
+       led->rt2x00dev = rt2x00dev;
+       led->type = type;
+       led->led_dev.brightness_set = rt2800usb_brightness_set;
+       led->led_dev.blink_set = rt2800usb_blink_set;
+       led->flags = LED_INITIALIZED;
+}
+#endif /* CONFIG_RT2X00_LIB_LEDS */
+
+/*
+ * Configuration handlers.
+ */
+static void rt2800usb_config_wcid_attr(struct rt2x00_dev *rt2x00dev,
+                                      struct rt2x00lib_crypto *crypto,
+                                      struct ieee80211_key_conf *key)
+{
+       struct mac_wcid_entry wcid_entry;
+       struct mac_iveiv_entry iveiv_entry;
+       u32 offset;
+       u32 reg;
+
+       offset = MAC_WCID_ATTR_ENTRY(key->hw_key_idx);
+
+       rt2x00usb_register_read(rt2x00dev, offset, &reg);
+       rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_KEYTAB,
+                          !!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE));
+       rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_CIPHER,
+                          (crypto->cmd == SET_KEY) * crypto->cipher);
+       rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_BSS_IDX,
+                          (crypto->cmd == SET_KEY) * crypto->bssidx);
+       rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_RX_WIUDF, crypto->cipher);
+       rt2x00usb_register_write(rt2x00dev, offset, reg);
+
+       offset = MAC_IVEIV_ENTRY(key->hw_key_idx);
+
+       memset(&iveiv_entry, 0, sizeof(iveiv_entry));
+       if ((crypto->cipher == CIPHER_TKIP) ||
+           (crypto->cipher == CIPHER_TKIP_NO_MIC) ||
+           (crypto->cipher == CIPHER_AES))
+               iveiv_entry.iv[3] |= 0x20;
+       iveiv_entry.iv[3] |= key->keyidx << 6;
+       rt2x00usb_register_multiwrite(rt2x00dev, offset,
+                                     &iveiv_entry, sizeof(iveiv_entry));
+
+       offset = MAC_WCID_ENTRY(key->hw_key_idx);
+
+       memset(&wcid_entry, 0, sizeof(wcid_entry));
+       if (crypto->cmd == SET_KEY)
+               memcpy(&wcid_entry, crypto->address, ETH_ALEN);
+       rt2x00usb_register_multiwrite(rt2x00dev, offset,
+                                     &wcid_entry, sizeof(wcid_entry));
+}
+
+static int rt2800usb_config_shared_key(struct rt2x00_dev *rt2x00dev,
+                                      struct rt2x00lib_crypto *crypto,
+                                      struct ieee80211_key_conf *key)
+{
+       struct hw_key_entry key_entry;
+       struct rt2x00_field32 field;
+       int timeout;
+       u32 offset;
+       u32 reg;
+
+       if (crypto->cmd == SET_KEY) {
+               key->hw_key_idx = (4 * crypto->bssidx) + key->keyidx;
+
+               memcpy(key_entry.key, crypto->key,
+                      sizeof(key_entry.key));
+               memcpy(key_entry.tx_mic, crypto->tx_mic,
+                      sizeof(key_entry.tx_mic));
+               memcpy(key_entry.rx_mic, crypto->rx_mic,
+                      sizeof(key_entry.rx_mic));
+
+               offset = SHARED_KEY_ENTRY(key->hw_key_idx);
+               timeout = REGISTER_TIMEOUT32(sizeof(key_entry));
+               rt2x00usb_vendor_request_large_buff(rt2x00dev, USB_MULTI_WRITE,
+                                                   USB_VENDOR_REQUEST_OUT,
+                                                   offset, &key_entry,
+                                                   sizeof(key_entry),
+                                                   timeout);
+       }
+
+       /*
+        * The cipher types are stored over multiple registers
+        * starting with SHARED_KEY_MODE_BASE each word will have
+        * 32 bits and contains the cipher types for 2 bssidx each.
+        * Using the correct defines correctly will cause overhead,
+        * so just calculate the correct offset.
+        */
+       field.bit_offset = 4 * (key->hw_key_idx % 8);
+       field.bit_mask = 0x7 << field.bit_offset;
+
+       offset = SHARED_KEY_MODE_ENTRY(key->hw_key_idx / 8);
+
+       rt2x00usb_register_read(rt2x00dev, offset, &reg);
+       rt2x00_set_field32(&reg, field,
+                          (crypto->cmd == SET_KEY) * crypto->cipher);
+       rt2x00usb_register_write(rt2x00dev, offset, reg);
+
+       /*
+        * Update WCID information
+        */
+       rt2800usb_config_wcid_attr(rt2x00dev, crypto, key);
+
+       return 0;
+}
+
+static int rt2800usb_config_pairwise_key(struct rt2x00_dev *rt2x00dev,
+                                        struct rt2x00lib_crypto *crypto,
+                                        struct ieee80211_key_conf *key)
+{
+       struct hw_key_entry key_entry;
+       int timeout;
+       u32 offset;
+
+       if (crypto->cmd == SET_KEY) {
+               /*
+                * 1 pairwise key is possible per AID, this means that the AID
+                * equals our hw_key_idx. Make sure the WCID starts _after_ the
+                * last possible shared key entry.
+                */
+               if (crypto->aid > (256 - 32))
+                       return -ENOSPC;
+
+               key->hw_key_idx = 32 + crypto->aid;
+
+               memcpy(key_entry.key, crypto->key,
+                      sizeof(key_entry.key));
+               memcpy(key_entry.tx_mic, crypto->tx_mic,
+                      sizeof(key_entry.tx_mic));
+               memcpy(key_entry.rx_mic, crypto->rx_mic,
+                      sizeof(key_entry.rx_mic));
+
+               offset = PAIRWISE_KEY_ENTRY(key->hw_key_idx);
+               timeout = REGISTER_TIMEOUT32(sizeof(key_entry));
+               rt2x00usb_vendor_request_large_buff(rt2x00dev, USB_MULTI_WRITE,
+                                                   USB_VENDOR_REQUEST_OUT,
+                                                   offset, &key_entry,
+                                                   sizeof(key_entry),
+                                                   timeout);
+       }
+
+       /*
+        * Update WCID information
+        */
+       rt2800usb_config_wcid_attr(rt2x00dev, crypto, key);
+
+       return 0;
+}
+
+static void rt2800usb_config_filter(struct rt2x00_dev *rt2x00dev,
+                                   const unsigned int filter_flags)
+{
+       u32 reg;
+
+       /*
+        * Start configuration steps.
+        * Note that the version error will always be dropped
+        * and broadcast frames will always be accepted since
+        * there is no filter for it at this time.
+        */
+       rt2x00usb_register_read(rt2x00dev, RX_FILTER_CFG, &reg);
+       rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_CRC_ERROR,
+                          !(filter_flags & FIF_FCSFAIL));
+       rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_PHY_ERROR,
+                          !(filter_flags & FIF_PLCPFAIL));
+       rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_NOT_TO_ME,
+                          !(filter_flags & FIF_PROMISC_IN_BSS));
+       rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_NOT_MY_BSSD, 0);
+       rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_VER_ERROR, 1);
+       rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_MULTICAST,
+                          !(filter_flags & FIF_ALLMULTI));
+       rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_BROADCAST, 0);
+       rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_DUPLICATE, 1);
+       rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_CF_END_ACK,
+                          !(filter_flags & FIF_CONTROL));
+       rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_CF_END,
+                          !(filter_flags & FIF_CONTROL));
+       rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_ACK,
+                          !(filter_flags & FIF_CONTROL));
+       rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_CTS,
+                          !(filter_flags & FIF_CONTROL));
+       rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_RTS,
+                          !(filter_flags & FIF_CONTROL));
+       rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_PSPOLL,
+                          !(filter_flags & FIF_CONTROL));
+       rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_BA, 1);
+       rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_BAR, 0);
+       rt2x00_set_field32(&reg, RX_FILTER_CFG_DROP_CNTL,
+                          !(filter_flags & FIF_CONTROL));
+       rt2x00usb_register_write(rt2x00dev, RX_FILTER_CFG, reg);
+}
+
+static void rt2800usb_config_intf(struct rt2x00_dev *rt2x00dev,
+                                 struct rt2x00_intf *intf,
+                                 struct rt2x00intf_conf *conf,
+                                 const unsigned int flags)
+{
+       unsigned int beacon_base;
+       u32 reg;
+
+       if (flags & CONFIG_UPDATE_TYPE) {
+               /*
+                * Clear current synchronisation setup.
+                * For the Beacon base registers we only need to clear
+                * the first byte since that byte contains the VALID and OWNER
+                * bits which (when set to 0) will invalidate the entire beacon.
+                */
+               beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx);
+               rt2x00usb_register_write(rt2x00dev, beacon_base, 0);
+
+               /*
+                * Enable synchronisation.
+                */
+               rt2x00usb_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
+               rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_TICKING, 1);
+               rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_SYNC, conf->sync);
+               rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE, 1);
+               rt2x00usb_register_write(rt2x00dev, BCN_TIME_CFG, reg);
+       }
+
+       if (flags & CONFIG_UPDATE_MAC) {
+               reg = le32_to_cpu(conf->mac[1]);
+               rt2x00_set_field32(&reg, MAC_ADDR_DW1_UNICAST_TO_ME_MASK, 0xff);
+               conf->mac[1] = cpu_to_le32(reg);
+
+               rt2x00usb_register_multiwrite(rt2x00dev, MAC_ADDR_DW0,
+                                             conf->mac, sizeof(conf->mac));
+       }
+
+       if (flags & CONFIG_UPDATE_BSSID) {
+               reg = le32_to_cpu(conf->bssid[1]);
+               rt2x00_set_field32(&reg, MAC_BSSID_DW1_BSS_ID_MASK, 0);
+               rt2x00_set_field32(&reg, MAC_BSSID_DW1_BSS_BCN_NUM, 0);
+               conf->bssid[1] = cpu_to_le32(reg);
+
+               rt2x00usb_register_multiwrite(rt2x00dev, MAC_BSSID_DW0,
+                                             conf->bssid, sizeof(conf->bssid));
+       }
+}
+
+static void rt2800usb_config_erp(struct rt2x00_dev *rt2x00dev,
+                                struct rt2x00lib_erp *erp)
+{
+       u32 reg;
+
+       rt2x00usb_register_read(rt2x00dev, TX_TIMEOUT_CFG, &reg);
+       rt2x00_set_field32(&reg, TX_TIMEOUT_CFG_RX_ACK_TIMEOUT,
+                          DIV_ROUND_UP(erp->ack_timeout, erp->slot_time));
+       rt2x00usb_register_write(rt2x00dev, TX_TIMEOUT_CFG, reg);
+
+       rt2x00usb_register_read(rt2x00dev, AUTO_RSP_CFG, &reg);
+       rt2x00_set_field32(&reg, AUTO_RSP_CFG_BAC_ACK_POLICY,
+                          !!erp->short_preamble);
+       rt2x00_set_field32(&reg, AUTO_RSP_CFG_AR_PREAMBLE,
+                          !!erp->short_preamble);
+       rt2x00usb_register_write(rt2x00dev, AUTO_RSP_CFG, reg);
+
+       rt2x00usb_register_read(rt2x00dev, OFDM_PROT_CFG, &reg);
+       rt2x00_set_field32(&reg, OFDM_PROT_CFG_PROTECT_CTRL,
+                          erp->cts_protection ? 2 : 0);
+       rt2x00usb_register_write(rt2x00dev, OFDM_PROT_CFG, reg);
+
+       rt2x00usb_register_write(rt2x00dev, LEGACY_BASIC_RATE,
+                                erp->basic_rates);
+       rt2x00usb_register_write(rt2x00dev, HT_BASIC_RATE, 0x00008003);
+
+       rt2x00usb_register_read(rt2x00dev, BKOFF_SLOT_CFG, &reg);
+       rt2x00_set_field32(&reg, BKOFF_SLOT_CFG_SLOT_TIME, erp->slot_time);
+       rt2x00_set_field32(&reg, BKOFF_SLOT_CFG_CC_DELAY_TIME, 2);
+       rt2x00usb_register_write(rt2x00dev, BKOFF_SLOT_CFG, reg);
+
+       rt2x00usb_register_read(rt2x00dev, XIFS_TIME_CFG, &reg);
+       rt2x00_set_field32(&reg, XIFS_TIME_CFG_CCKM_SIFS_TIME, erp->sifs);
+       rt2x00_set_field32(&reg, XIFS_TIME_CFG_OFDM_SIFS_TIME, erp->sifs);
+       rt2x00_set_field32(&reg, XIFS_TIME_CFG_OFDM_XIFS_TIME, 4);
+       rt2x00_set_field32(&reg, XIFS_TIME_CFG_EIFS, erp->eifs);
+       rt2x00_set_field32(&reg, XIFS_TIME_CFG_BB_RXEND_ENABLE, 1);
+       rt2x00usb_register_write(rt2x00dev, XIFS_TIME_CFG, reg);
+
+       rt2x00usb_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
+       rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_INTERVAL,
+                          erp->beacon_int * 16);
+       rt2x00usb_register_write(rt2x00dev, BCN_TIME_CFG, reg);
+}
+
+static void rt2800usb_config_ant(struct rt2x00_dev *rt2x00dev,
+                                struct antenna_setup *ant)
+{
+       u8 r1;
+       u8 r3;
+
+       rt2800usb_bbp_read(rt2x00dev, 1, &r1);
+       rt2800usb_bbp_read(rt2x00dev, 3, &r3);
+
+       /*
+        * Configure the TX antenna.
+        */
+       switch ((int)ant->tx) {
+       case 1:
+               rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 0);
+               break;
+       case 2:
+               rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 2);
+               break;
+       case 3:
+               /* Do nothing */
+               break;
+       }
+
+       /*
+        * Configure the RX antenna.
+        */
+       switch ((int)ant->rx) {
+       case 1:
+               rt2x00_set_field8(&r3, BBP3_RX_ANTENNA, 0);
+               break;
+       case 2:
+               rt2x00_set_field8(&r3, BBP3_RX_ANTENNA, 1);
+               break;
+       case 3:
+               rt2x00_set_field8(&r3, BBP3_RX_ANTENNA, 2);
+               break;
+       }
+
+       rt2800usb_bbp_write(rt2x00dev, 3, r3);
+       rt2800usb_bbp_write(rt2x00dev, 1, r1);
+}
+
+static void rt2800usb_config_lna_gain(struct rt2x00_dev *rt2x00dev,
+                                     struct rt2x00lib_conf *libconf)
+{
+       u16 eeprom;
+       short lna_gain;
+
+       if (libconf->rf.channel <= 14) {
+               rt2x00_eeprom_read(rt2x00dev, EEPROM_LNA, &eeprom);
+               lna_gain = rt2x00_get_field16(eeprom, EEPROM_LNA_BG);
+       } else if (libconf->rf.channel <= 64) {
+               rt2x00_eeprom_read(rt2x00dev, EEPROM_LNA, &eeprom);
+               lna_gain = rt2x00_get_field16(eeprom, EEPROM_LNA_A0);
+       } else if (libconf->rf.channel <= 128) {
+               rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_BG2, &eeprom);
+               lna_gain = rt2x00_get_field16(eeprom, EEPROM_RSSI_BG2_LNA_A1);
+       } else {
+               rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_A2, &eeprom);
+               lna_gain = rt2x00_get_field16(eeprom, EEPROM_RSSI_A2_LNA_A2);
+       }
+
+       rt2x00dev->lna_gain = lna_gain;
+}
+
+static void rt2800usb_config_channel_rt2x(struct rt2x00_dev *rt2x00dev,
+                                         struct ieee80211_conf *conf,
+                                         struct rf_channel *rf,
+                                         struct channel_info *info)
+{
+       rt2x00_set_field32(&rf->rf4, RF4_FREQ_OFFSET, rt2x00dev->freq_offset);
+
+       if (rt2x00dev->default_ant.tx == 1)
+               rt2x00_set_field32(&rf->rf2, RF2_ANTENNA_TX1, 1);
+
+       if (rt2x00dev->default_ant.rx == 1) {
+               rt2x00_set_field32(&rf->rf2, RF2_ANTENNA_RX1, 1);
+               rt2x00_set_field32(&rf->rf2, RF2_ANTENNA_RX2, 1);
+       } else if (rt2x00dev->default_ant.rx == 2)
+               rt2x00_set_field32(&rf->rf2, RF2_ANTENNA_RX2, 1);
+
+       if (rf->channel > 14) {
+               /*
+                * When TX power is below 0, we should increase it by 7 to
+                * make it a positive value (Minumum value is -7).
+                * However this means that values between 0 and 7 have
+                * double meaning, and we should set a 7DBm boost flag.
+                */
+               rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_A_7DBM_BOOST,
+                                  (info->tx_power1 >= 0));
+
+               if (info->tx_power1 < 0)
+                       info->tx_power1 += 7;
+
+               rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_A,
+                                  TXPOWER_A_TO_DEV(info->tx_power1));
+
+               rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_A_7DBM_BOOST,
+                                  (info->tx_power2 >= 0));
+
+               if (info->tx_power2 < 0)
+                       info->tx_power2 += 7;
+
+               rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_A,
+                                  TXPOWER_A_TO_DEV(info->tx_power2));
+       } else {
+               rt2x00_set_field32(&rf->rf3, RF3_TXPOWER_G,
+                                  TXPOWER_G_TO_DEV(info->tx_power1));
+               rt2x00_set_field32(&rf->rf4, RF4_TXPOWER_G,
+                                  TXPOWER_G_TO_DEV(info->tx_power2));
+       }
+
+       rt2x00_set_field32(&rf->rf4, RF4_HT40, conf_is_ht40(conf));
+
+       rt2800usb_rf_write(rt2x00dev, 1, rf->rf1);
+       rt2800usb_rf_write(rt2x00dev, 2, rf->rf2);
+       rt2800usb_rf_write(rt2x00dev, 3, rf->rf3 & ~0x00000004);
+       rt2800usb_rf_write(rt2x00dev, 4, rf->rf4);
+
+       udelay(200);
+
+       rt2800usb_rf_write(rt2x00dev, 1, rf->rf1);
+       rt2800usb_rf_write(rt2x00dev, 2, rf->rf2);
+       rt2800usb_rf_write(rt2x00dev, 3, rf->rf3 | 0x00000004);
+       rt2800usb_rf_write(rt2x00dev, 4, rf->rf4);
+
+       udelay(200);
+
+       rt2800usb_rf_write(rt2x00dev, 1, rf->rf1);
+       rt2800usb_rf_write(rt2x00dev, 2, rf->rf2);
+       rt2800usb_rf_write(rt2x00dev, 3, rf->rf3 & ~0x00000004);
+       rt2800usb_rf_write(rt2x00dev, 4, rf->rf4);
+}
+
+static void rt2800usb_config_channel_rt3x(struct rt2x00_dev *rt2x00dev,
+                                         struct ieee80211_conf *conf,
+                                         struct rf_channel *rf,
+                                         struct channel_info *info)
+{
+       u8 rfcsr;
+
+       rt2800usb_rfcsr_write(rt2x00dev, 2, rf->rf1);
+       rt2800usb_rfcsr_write(rt2x00dev, 2, rf->rf3);
+
+       rt2800usb_rfcsr_read(rt2x00dev, 6, &rfcsr);
+       rt2x00_set_field8(&rfcsr, RFCSR6_R, rf->rf2);
+       rt2800usb_rfcsr_write(rt2x00dev, 6, rfcsr);
+
+       rt2800usb_rfcsr_read(rt2x00dev, 12, &rfcsr);
+       rt2x00_set_field8(&rfcsr, RFCSR12_TX_POWER,
+                         TXPOWER_G_TO_DEV(info->tx_power1));
+       rt2800usb_rfcsr_write(rt2x00dev, 12, rfcsr);
+
+       rt2800usb_rfcsr_read(rt2x00dev, 23, &rfcsr);
+       rt2x00_set_field8(&rfcsr, RFCSR23_FREQ_OFFSET, rt2x00dev->freq_offset);
+       rt2800usb_rfcsr_write(rt2x00dev, 23, rfcsr);
+
+       rt2800usb_rfcsr_write(rt2x00dev, 24,
+                             rt2x00dev->calibration[conf_is_ht40(conf)]);
+
+       rt2800usb_rfcsr_read(rt2x00dev, 23, &rfcsr);
+       rt2x00_set_field8(&rfcsr, RFCSR7_RF_TUNING, 1);
+       rt2800usb_rfcsr_write(rt2x00dev, 23, rfcsr);
+}
+
+static void rt2800usb_config_channel(struct rt2x00_dev *rt2x00dev,
+                                    struct ieee80211_conf *conf,
+                                    struct rf_channel *rf,
+                                    struct channel_info *info)
+{
+       u32 reg;
+       unsigned int tx_pin;
+       u8 bbp;
+
+       if (rt2x00_rev(&rt2x00dev->chip) != RT3070_VERSION)
+               rt2800usb_config_channel_rt2x(rt2x00dev, conf, rf, info);
+       else
+               rt2800usb_config_channel_rt3x(rt2x00dev, conf, rf, info);
+
+       /*
+        * Change BBP settings
+        */
+       rt2800usb_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain);
+       rt2800usb_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain);
+       rt2800usb_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain);
+       rt2800usb_bbp_write(rt2x00dev, 86, 0);
+
+       if (rf->channel <= 14) {
+               if (test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags)) {
+                       rt2800usb_bbp_write(rt2x00dev, 82, 0x62);
+                       rt2800usb_bbp_write(rt2x00dev, 75, 0x46);
+               } else {
+                       rt2800usb_bbp_write(rt2x00dev, 82, 0x84);
+                       rt2800usb_bbp_write(rt2x00dev, 75, 0x50);
+               }
+       } else {
+               rt2800usb_bbp_write(rt2x00dev, 82, 0xf2);
+
+               if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags))
+                       rt2800usb_bbp_write(rt2x00dev, 75, 0x46);
+               else
+                       rt2800usb_bbp_write(rt2x00dev, 75, 0x50);
+       }
+
+       rt2x00usb_register_read(rt2x00dev, TX_BAND_CFG, &reg);
+       rt2x00_set_field32(&reg, TX_BAND_CFG_HT40_PLUS, conf_is_ht40_plus(conf));
+       rt2x00_set_field32(&reg, TX_BAND_CFG_A, rf->channel > 14);
+       rt2x00_set_field32(&reg, TX_BAND_CFG_BG, rf->channel <= 14);
+       rt2x00usb_register_write(rt2x00dev, TX_BAND_CFG, reg);
+
+       tx_pin = 0;
+
+       /* Turn on unused PA or LNA when not using 1T or 1R */
+       if (rt2x00dev->default_ant.tx != 1) {
+               rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A1_EN, 1);
+               rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G1_EN, 1);
+       }
+
+       /* Turn on unused PA or LNA when not using 1T or 1R */
+       if (rt2x00dev->default_ant.rx != 1) {
+               rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A1_EN, 1);
+               rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G1_EN, 1);
+       }
+
+       rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A0_EN, 1);
+       rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G0_EN, 1);
+       rt2x00_set_field32(&tx_pin, TX_PIN_CFG_RFTR_EN, 1);
+       rt2x00_set_field32(&tx_pin, TX_PIN_CFG_TRSW_EN, 1);
+       rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G0_EN, rf->channel <= 14);
+       rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A0_EN, rf->channel > 14);
+
+       rt2x00usb_register_write(rt2x00dev, TX_PIN_CFG, tx_pin);
+
+       rt2800usb_bbp_read(rt2x00dev, 4, &bbp);
+       rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 2 * conf_is_ht40(conf));
+       rt2800usb_bbp_write(rt2x00dev, 4, bbp);
+
+       rt2800usb_bbp_read(rt2x00dev, 3, &bbp);
+       rt2x00_set_field8(&bbp, BBP3_HT40_PLUS, conf_is_ht40_plus(conf));
+       rt2800usb_bbp_write(rt2x00dev, 3, bbp);
+
+       if (rt2x00_rev(&rt2x00dev->chip) == RT2860C_VERSION) {
+               if (conf_is_ht40(conf)) {
+                       rt2800usb_bbp_write(rt2x00dev, 69, 0x1a);
+                       rt2800usb_bbp_write(rt2x00dev, 70, 0x0a);
+                       rt2800usb_bbp_write(rt2x00dev, 73, 0x16);
+               } else {
+                       rt2800usb_bbp_write(rt2x00dev, 69, 0x16);
+                       rt2800usb_bbp_write(rt2x00dev, 70, 0x08);
+                       rt2800usb_bbp_write(rt2x00dev, 73, 0x11);
+               }
+       }
+
+       msleep(1);
+}
+
+static void rt2800usb_config_txpower(struct rt2x00_dev *rt2x00dev,
+                                    const int txpower)
+{
+       u32 reg;
+       u32 value = TXPOWER_G_TO_DEV(txpower);
+       u8 r1;
+
+       rt2800usb_bbp_read(rt2x00dev, 1, &r1);
+       rt2x00_set_field8(&reg, BBP1_TX_POWER, 0);
+       rt2800usb_bbp_write(rt2x00dev, 1, r1);
+
+       rt2x00usb_register_read(rt2x00dev, TX_PWR_CFG_0, &reg);
+       rt2x00_set_field32(&reg, TX_PWR_CFG_0_1MBS, value);
+       rt2x00_set_field32(&reg, TX_PWR_CFG_0_2MBS, value);
+       rt2x00_set_field32(&reg, TX_PWR_CFG_0_55MBS, value);
+       rt2x00_set_field32(&reg, TX_PWR_CFG_0_11MBS, value);
+       rt2x00_set_field32(&reg, TX_PWR_CFG_0_6MBS, value);
+       rt2x00_set_field32(&reg, TX_PWR_CFG_0_9MBS, value);
+       rt2x00_set_field32(&reg, TX_PWR_CFG_0_12MBS, value);
+       rt2x00_set_field32(&reg, TX_PWR_CFG_0_18MBS, value);
+       rt2x00usb_register_write(rt2x00dev, TX_PWR_CFG_0, reg);
+
+       rt2x00usb_register_read(rt2x00dev, TX_PWR_CFG_1, &reg);
+       rt2x00_set_field32(&reg, TX_PWR_CFG_1_24MBS, value);
+       rt2x00_set_field32(&reg, TX_PWR_CFG_1_36MBS, value);
+       rt2x00_set_field32(&reg, TX_PWR_CFG_1_48MBS, value);
+       rt2x00_set_field32(&reg, TX_PWR_CFG_1_54MBS, value);
+       rt2x00_set_field32(&reg, TX_PWR_CFG_1_MCS0, value);
+       rt2x00_set_field32(&reg, TX_PWR_CFG_1_MCS1, value);
+       rt2x00_set_field32(&reg, TX_PWR_CFG_1_MCS2, value);
+       rt2x00_set_field32(&reg, TX_PWR_CFG_1_MCS3, value);
+       rt2x00usb_register_write(rt2x00dev, TX_PWR_CFG_1, reg);
+
+       rt2x00usb_register_read(rt2x00dev, TX_PWR_CFG_2, &reg);
+       rt2x00_set_field32(&reg, TX_PWR_CFG_2_MCS4, value);
+       rt2x00_set_field32(&reg, TX_PWR_CFG_2_MCS5, value);
+       rt2x00_set_field32(&reg, TX_PWR_CFG_2_MCS6, value);
+       rt2x00_set_field32(&reg, TX_PWR_CFG_2_MCS7, value);
+       rt2x00_set_field32(&reg, TX_PWR_CFG_2_MCS8, value);
+       rt2x00_set_field32(&reg, TX_PWR_CFG_2_MCS9, value);
+       rt2x00_set_field32(&reg, TX_PWR_CFG_2_MCS10, value);
+       rt2x00_set_field32(&reg, TX_PWR_CFG_2_MCS11, value);
+       rt2x00usb_register_write(rt2x00dev, TX_PWR_CFG_2, reg);
+
+       rt2x00usb_register_read(rt2x00dev, TX_PWR_CFG_3, &reg);
+       rt2x00_set_field32(&reg, TX_PWR_CFG_3_MCS12, value);
+       rt2x00_set_field32(&reg, TX_PWR_CFG_3_MCS13, value);
+       rt2x00_set_field32(&reg, TX_PWR_CFG_3_MCS14, value);
+       rt2x00_set_field32(&reg, TX_PWR_CFG_3_MCS15, value);
+       rt2x00_set_field32(&reg, TX_PWR_CFG_3_UKNOWN1, value);
+       rt2x00_set_field32(&reg, TX_PWR_CFG_3_UKNOWN2, value);
+       rt2x00_set_field32(&reg, TX_PWR_CFG_3_UKNOWN3, value);
+       rt2x00_set_field32(&reg, TX_PWR_CFG_3_UKNOWN4, value);
+       rt2x00usb_register_write(rt2x00dev, TX_PWR_CFG_3, reg);
+
+       rt2x00usb_register_read(rt2x00dev, TX_PWR_CFG_4, &reg);
+       rt2x00_set_field32(&reg, TX_PWR_CFG_4_UKNOWN5, value);
+       rt2x00_set_field32(&reg, TX_PWR_CFG_4_UKNOWN6, value);
+       rt2x00_set_field32(&reg, TX_PWR_CFG_4_UKNOWN7, value);
+       rt2x00_set_field32(&reg, TX_PWR_CFG_4_UKNOWN8, value);
+       rt2x00usb_register_write(rt2x00dev, TX_PWR_CFG_4, reg);
+}
+
+static void rt2800usb_config_retry_limit(struct rt2x00_dev *rt2x00dev,
+                                        struct rt2x00lib_conf *libconf)
+{
+       u32 reg;
+
+       rt2x00usb_register_read(rt2x00dev, TX_RTY_CFG, &reg);
+       rt2x00_set_field32(&reg, TX_RTY_CFG_SHORT_RTY_LIMIT,
+                          libconf->conf->short_frame_max_tx_count);
+       rt2x00_set_field32(&reg, TX_RTY_CFG_LONG_RTY_LIMIT,
+                          libconf->conf->long_frame_max_tx_count);
+       rt2x00_set_field32(&reg, TX_RTY_CFG_LONG_RTY_THRE, 2000);
+       rt2x00_set_field32(&reg, TX_RTY_CFG_NON_AGG_RTY_MODE, 0);
+       rt2x00_set_field32(&reg, TX_RTY_CFG_AGG_RTY_MODE, 0);
+       rt2x00_set_field32(&reg, TX_RTY_CFG_TX_AUTO_FB_ENABLE, 1);
+       rt2x00usb_register_write(rt2x00dev, TX_RTY_CFG, reg);
+}
+
+static void rt2800usb_config_ps(struct rt2x00_dev *rt2x00dev,
+                               struct rt2x00lib_conf *libconf)
+{
+       enum dev_state state =
+           (libconf->conf->flags & IEEE80211_CONF_PS) ?
+               STATE_SLEEP : STATE_AWAKE;
+       u32 reg;
+
+       if (state == STATE_SLEEP) {
+               rt2x00usb_register_write(rt2x00dev, AUTOWAKEUP_CFG, 0);
+
+               rt2x00usb_register_read(rt2x00dev, AUTOWAKEUP_CFG, &reg);
+               rt2x00_set_field32(&reg, AUTOWAKEUP_CFG_AUTO_LEAD_TIME, 5);
+               rt2x00_set_field32(&reg, AUTOWAKEUP_CFG_TBCN_BEFORE_WAKE,
+                                  libconf->conf->listen_interval - 1);
+               rt2x00_set_field32(&reg, AUTOWAKEUP_CFG_AUTOWAKE, 1);
+               rt2x00usb_register_write(rt2x00dev, AUTOWAKEUP_CFG, reg);
+
+               rt2x00dev->ops->lib->set_device_state(rt2x00dev, state);
+       } else {
+               rt2x00dev->ops->lib->set_device_state(rt2x00dev, state);
+
+               rt2x00usb_register_read(rt2x00dev, AUTOWAKEUP_CFG, &reg);
+               rt2x00_set_field32(&reg, AUTOWAKEUP_CFG_AUTO_LEAD_TIME, 0);
+               rt2x00_set_field32(&reg, AUTOWAKEUP_CFG_TBCN_BEFORE_WAKE, 0);
+               rt2x00_set_field32(&reg, AUTOWAKEUP_CFG_AUTOWAKE, 0);
+               rt2x00usb_register_write(rt2x00dev, AUTOWAKEUP_CFG, reg);
+       }
+}
+
+static void rt2800usb_config(struct rt2x00_dev *rt2x00dev,
+                            struct rt2x00lib_conf *libconf,
+                            const unsigned int flags)
+{
+       /* Always recalculate LNA gain before changing configuration */
+       rt2800usb_config_lna_gain(rt2x00dev, libconf);
+
+       if (flags & IEEE80211_CONF_CHANGE_CHANNEL)
+               rt2800usb_config_channel(rt2x00dev, libconf->conf,
+                                        &libconf->rf, &libconf->channel);
+       if (flags & IEEE80211_CONF_CHANGE_POWER)
+               rt2800usb_config_txpower(rt2x00dev, libconf->conf->power_level);
+       if (flags & IEEE80211_CONF_CHANGE_RETRY_LIMITS)
+               rt2800usb_config_retry_limit(rt2x00dev, libconf);
+       if (flags & IEEE80211_CONF_CHANGE_PS)
+               rt2800usb_config_ps(rt2x00dev, libconf);
+}
+
+/*
+ * Link tuning
+ */
+static void rt2800usb_link_stats(struct rt2x00_dev *rt2x00dev,
+                                struct link_qual *qual)
+{
+       u32 reg;
+
+       /*
+        * Update FCS error count from register.
+        */
+       rt2x00usb_register_read(rt2x00dev, RX_STA_CNT0, &reg);
+       qual->rx_failed = rt2x00_get_field32(reg, RX_STA_CNT0_CRC_ERR);
+}
+
+static u8 rt2800usb_get_default_vgc(struct rt2x00_dev *rt2x00dev)
+{
+       if (rt2x00dev->curr_band == IEEE80211_BAND_2GHZ) {
+               if (rt2x00_rev(&rt2x00dev->chip) == RT3070_VERSION)
+                       return 0x1c + (2 * rt2x00dev->lna_gain);
+               else
+                       return 0x2e + rt2x00dev->lna_gain;
+       }
+
+       if (!test_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags))
+               return 0x32 + (rt2x00dev->lna_gain * 5) / 3;
+       else
+               return 0x3a + (rt2x00dev->lna_gain * 5) / 3;
+}
+
+static inline void rt2800usb_set_vgc(struct rt2x00_dev *rt2x00dev,
+                                    struct link_qual *qual, u8 vgc_level)
+{
+       if (qual->vgc_level != vgc_level) {
+               rt2800usb_bbp_write(rt2x00dev, 66, vgc_level);
+               qual->vgc_level = vgc_level;
+               qual->vgc_level_reg = vgc_level;
+       }
+}
+
+static void rt2800usb_reset_tuner(struct rt2x00_dev *rt2x00dev,
+                                 struct link_qual *qual)
+{
+       rt2800usb_set_vgc(rt2x00dev, qual,
+                         rt2800usb_get_default_vgc(rt2x00dev));
+}
+
+static void rt2800usb_link_tuner(struct rt2x00_dev *rt2x00dev,
+                                struct link_qual *qual, const u32 count)
+{
+       if (rt2x00_rev(&rt2x00dev->chip) == RT2860C_VERSION)
+               return;
+
+       /*
+        * When RSSI is better then -80 increase VGC level with 0x10
+        */
+       rt2800usb_set_vgc(rt2x00dev, qual,
+                         rt2800usb_get_default_vgc(rt2x00dev) +
+                         ((qual->rssi > -80) * 0x10));
+}
+
+/*
+ * Firmware functions
+ */
+static char *rt2800usb_get_firmware_name(struct rt2x00_dev *rt2x00dev)
+{
+       return FIRMWARE_RT2870;
+}
+
+static bool rt2800usb_check_crc(const u8 *data, const size_t len)
+{
+       u16 fw_crc;
+       u16 crc;
+
+       /*
+        * The last 2 bytes in the firmware array are the crc checksum itself,
+        * this means that we should never pass those 2 bytes to the crc
+        * algorithm.
+        */
+       fw_crc = (data[len - 2] << 8 | data[len - 1]);
+
+       /*
+        * Use the crc ccitt algorithm.
+        * This will return the same value as the legacy driver which
+        * used bit ordering reversion on the both the firmware bytes
+        * before input input as well as on the final output.
+        * Obviously using crc ccitt directly is much more efficient.
+        */
+       crc = crc_ccitt(~0, data, len - 2);
+
+       /*
+        * There is a small difference between the crc-itu-t + bitrev and
+        * the crc-ccitt crc calculation. In the latter method the 2 bytes
+        * will be swapped, use swab16 to convert the crc to the correct
+        * value.
+        */
+       crc = swab16(crc);
+
+       return fw_crc == crc;
+}
+
+static int rt2800usb_check_firmware(struct rt2x00_dev *rt2x00dev,
+                                   const u8 *data, const size_t len)
+{
+       u16 chipset = (rt2x00_rev(&rt2x00dev->chip) >> 16) & 0xffff;
+       size_t offset = 0;
+
+       /*
+        * Firmware files:
+        * There are 2 variations of the rt2870 firmware.
+        * a) size: 4kb
+        * b) size: 8kb
+        * Note that (b) contains 2 seperate firmware blobs of 4k
+        * within the file. The first blob is the same firmware as (a),
+        * but the second blob is for the additional chipsets.
+        */
+       if (len != 4096 && len != 8192)
+               return FW_BAD_LENGTH;
+
+       /*
+        * Check if we need the upper 4kb firmware data or not.
+        */
+       if ((len == 4096) &&
+           (chipset != 0x2860) &&
+           (chipset != 0x2872) &&
+           (chipset != 0x3070))
+               return FW_BAD_VERSION;
+
+       /*
+        * 8kb firmware files must be checked as if it were
+        * 2 seperate firmware files.
+        */
+       while (offset < len) {
+               if (!rt2800usb_check_crc(data + offset, 4096))
+                       return FW_BAD_CRC;
+
+               offset += 4096;
+       }
+
+       return FW_OK;
+}
+
+static int rt2800usb_load_firmware(struct rt2x00_dev *rt2x00dev,
+                                  const u8 *data, const size_t len)
+{
+       unsigned int i;
+       int status;
+       u32 reg;
+       u32 offset;
+       u32 length;
+       u16 chipset = (rt2x00_rev(&rt2x00dev->chip) >> 16) & 0xffff;
+
+       /*
+        * Check which section of the firmware we need.
+        */
+       if ((chipset == 0x2860) ||
+           (chipset == 0x2872) ||
+           (chipset == 0x3070)) {
+               offset = 0;
+               length = 4096;
+       } else {
+               offset = 4096;
+               length = 4096;
+       }
+
+       /*
+        * Wait for stable hardware.
+        */
+       for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
+               rt2x00usb_register_read(rt2x00dev, MAC_CSR0, &reg);
+               if (reg && reg != ~0)
+                       break;
+               msleep(1);
+       }
+
+       if (i == REGISTER_BUSY_COUNT) {
+               ERROR(rt2x00dev, "Unstable hardware.\n");
+               return -EBUSY;
+       }
+
+       /*
+        * Write firmware to device.
+        */
+       rt2x00usb_vendor_request_large_buff(rt2x00dev, USB_MULTI_WRITE,
+                                           USB_VENDOR_REQUEST_OUT,
+                                           FIRMWARE_IMAGE_BASE,
+                                           data + offset, length,
+                                           REGISTER_TIMEOUT32(length));
+
+       rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
+       rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0);
+
+       /*
+        * Send firmware request to device to load firmware,
+        * we need to specify a long timeout time.
+        */
+       status = rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE,
+                                            0, USB_MODE_FIRMWARE,
+                                            REGISTER_TIMEOUT_FIRMWARE);
+       if (status < 0) {
+               ERROR(rt2x00dev, "Failed to write Firmware to device.\n");
+               return status;
+       }
+
+       msleep(10);
+       rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
+
+       /*
+        * Send signal to firmware during boot time.
+        */
+       rt2800usb_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0xff, 0, 0);
+
+       if ((chipset == 0x3070) ||
+           (chipset == 0x3071) ||
+           (chipset == 0x3572)) {
+               udelay(200);
+               rt2800usb_mcu_request(rt2x00dev, MCU_CURRENT, 0, 0, 0);
+               udelay(10);
+       }
+
+       /*
+        * Wait for device to stabilize.
+        */
+       for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
+               rt2x00usb_register_read(rt2x00dev, PBF_SYS_CTRL, &reg);
+               if (rt2x00_get_field32(reg, PBF_SYS_CTRL_READY))
+                       break;
+               msleep(1);
+       }
+
+       if (i == REGISTER_BUSY_COUNT) {
+               ERROR(rt2x00dev, "PBF system register not ready.\n");
+               return -EBUSY;
+       }
+
+       /*
+        * Initialize firmware.
+        */
+       rt2x00usb_register_write(rt2x00dev, H2M_BBP_AGENT, 0);
+       rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
+       msleep(1);
+
+       return 0;
+}
+
+/*
+ * Initialization functions.
+ */
+static int rt2800usb_init_registers(struct rt2x00_dev *rt2x00dev)
+{
+       u32 reg;
+       unsigned int i;
+
+       /*
+        * Wait untill BBP and RF are ready.
+        */
+       for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
+               rt2x00usb_register_read(rt2x00dev, MAC_CSR0, &reg);
+               if (reg && reg != ~0)
+                       break;
+               msleep(1);
+       }
+
+       if (i == REGISTER_BUSY_COUNT) {
+               ERROR(rt2x00dev, "Unstable hardware.\n");
+               return -EBUSY;
+       }
+
+       rt2x00usb_register_read(rt2x00dev, PBF_SYS_CTRL, &reg);
+       rt2x00usb_register_write(rt2x00dev, PBF_SYS_CTRL, reg & ~0x00002000);
+
+       rt2x00usb_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
+       rt2x00_set_field32(&reg, MAC_SYS_CTRL_RESET_CSR, 1);
+       rt2x00_set_field32(&reg, MAC_SYS_CTRL_RESET_BBP, 1);
+       rt2x00usb_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
+
+       rt2x00usb_register_write(rt2x00dev, USB_DMA_CFG, 0x00000000);
+
+       rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE, 0,
+                                   USB_MODE_RESET, REGISTER_TIMEOUT);
+
+       rt2x00usb_register_write(rt2x00dev, MAC_SYS_CTRL, 0x00000000);
+
+       rt2x00usb_register_read(rt2x00dev, BCN_OFFSET0, &reg);
+       rt2x00_set_field32(&reg, BCN_OFFSET0_BCN0, 0xe0); /* 0x3800 */
+       rt2x00_set_field32(&reg, BCN_OFFSET0_BCN1, 0xe8); /* 0x3a00 */
+       rt2x00_set_field32(&reg, BCN_OFFSET0_BCN2, 0xf0); /* 0x3c00 */
+       rt2x00_set_field32(&reg, BCN_OFFSET0_BCN3, 0xf8); /* 0x3e00 */
+       rt2x00usb_register_write(rt2x00dev, BCN_OFFSET0, reg);
+
+       rt2x00usb_register_read(rt2x00dev, BCN_OFFSET1, &reg);
+       rt2x00_set_field32(&reg, BCN_OFFSET1_BCN4, 0xc8); /* 0x3200 */
+       rt2x00_set_field32(&reg, BCN_OFFSET1_BCN5, 0xd0); /* 0x3400 */
+       rt2x00_set_field32(&reg, BCN_OFFSET1_BCN6, 0x77); /* 0x1dc0 */
+       rt2x00_set_field32(&reg, BCN_OFFSET1_BCN7, 0x6f); /* 0x1bc0 */
+       rt2x00usb_register_write(rt2x00dev, BCN_OFFSET1, reg);
+
+       rt2x00usb_register_write(rt2x00dev, LEGACY_BASIC_RATE, 0x0000013f);
+       rt2x00usb_register_write(rt2x00dev, HT_BASIC_RATE, 0x00008003);
+
+       rt2x00usb_register_write(rt2x00dev, MAC_SYS_CTRL, 0x00000000);
+
+       rt2x00usb_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
+       rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_INTERVAL, 0);
+       rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_TICKING, 0);
+       rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_SYNC, 0);
+       rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE, 0);
+       rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 0);
+       rt2x00_set_field32(&reg, BCN_TIME_CFG_TX_TIME_COMPENSATE, 0);
+       rt2x00usb_register_write(rt2x00dev, BCN_TIME_CFG, reg);
+
+       if (rt2x00_rev(&rt2x00dev->chip) == RT3070_VERSION) {
+               rt2x00usb_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400);
+               rt2x00usb_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000);
+               rt2x00usb_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000);
+       } else {
+               rt2x00usb_register_write(rt2x00dev, TX_SW_CFG0, 0x00000000);
+               rt2x00usb_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606);
+       }
+
+       rt2x00usb_register_read(rt2x00dev, TX_LINK_CFG, &reg);
+       rt2x00_set_field32(&reg, TX_LINK_CFG_REMOTE_MFB_LIFETIME, 32);
+       rt2x00_set_field32(&reg, TX_LINK_CFG_MFB_ENABLE, 0);
+       rt2x00_set_field32(&reg, TX_LINK_CFG_REMOTE_UMFS_ENABLE, 0);
+       rt2x00_set_field32(&reg, TX_LINK_CFG_TX_MRQ_EN, 0);
+       rt2x00_set_field32(&reg, TX_LINK_CFG_TX_RDG_EN, 0);
+       rt2x00_set_field32(&reg, TX_LINK_CFG_TX_CF_ACK_EN, 1);
+       rt2x00_set_field32(&reg, TX_LINK_CFG_REMOTE_MFB, 0);
+       rt2x00_set_field32(&reg, TX_LINK_CFG_REMOTE_MFS, 0);
+       rt2x00usb_register_write(rt2x00dev, TX_LINK_CFG, reg);
+
+       rt2x00usb_register_read(rt2x00dev, TX_TIMEOUT_CFG, &reg);
+       rt2x00_set_field32(&reg, TX_TIMEOUT_CFG_MPDU_LIFETIME, 9);
+       rt2x00_set_field32(&reg, TX_TIMEOUT_CFG_TX_OP_TIMEOUT, 10);
+       rt2x00usb_register_write(rt2x00dev, TX_TIMEOUT_CFG, reg);
+
+       rt2x00usb_register_read(rt2x00dev, MAX_LEN_CFG, &reg);
+       rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_MPDU, AGGREGATION_SIZE);
+       if (rt2x00_rev(&rt2x00dev->chip) >= RT2880E_VERSION &&
+           rt2x00_rev(&rt2x00dev->chip) < RT3070_VERSION)
+               rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_PSDU, 2);
+       else
+               rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_PSDU, 1);
+       rt2x00_set_field32(&reg, MAX_LEN_CFG_MIN_PSDU, 0);
+       rt2x00_set_field32(&reg, MAX_LEN_CFG_MIN_MPDU, 0);
+       rt2x00usb_register_write(rt2x00dev, MAX_LEN_CFG, reg);
+
+       rt2x00usb_register_write(rt2x00dev, PBF_MAX_PCNT, 0x1f3fbf9f);
+
+       rt2x00usb_register_read(rt2x00dev, AUTO_RSP_CFG, &reg);
+       rt2x00_set_field32(&reg, AUTO_RSP_CFG_AUTORESPONDER, 1);
+       rt2x00_set_field32(&reg, AUTO_RSP_CFG_CTS_40_MMODE, 0);
+       rt2x00_set_field32(&reg, AUTO_RSP_CFG_CTS_40_MREF, 0);
+       rt2x00_set_field32(&reg, AUTO_RSP_CFG_DUAL_CTS_EN, 0);
+       rt2x00_set_field32(&reg, AUTO_RSP_CFG_ACK_CTS_PSM_BIT, 0);
+       rt2x00usb_register_write(rt2x00dev, AUTO_RSP_CFG, reg);
+
+       rt2x00usb_register_read(rt2x00dev, CCK_PROT_CFG, &reg);
+       rt2x00_set_field32(&reg, CCK_PROT_CFG_PROTECT_RATE, 8);
+       rt2x00_set_field32(&reg, CCK_PROT_CFG_PROTECT_CTRL, 0);
+       rt2x00_set_field32(&reg, CCK_PROT_CFG_PROTECT_NAV, 1);
+       rt2x00_set_field32(&reg, CCK_PROT_CFG_TX_OP_ALLOW_CCK, 1);
+       rt2x00_set_field32(&reg, CCK_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
+       rt2x00_set_field32(&reg, CCK_PROT_CFG_TX_OP_ALLOW_MM20, 1);
+       rt2x00_set_field32(&reg, CCK_PROT_CFG_TX_OP_ALLOW_MM40, 1);
+       rt2x00_set_field32(&reg, CCK_PROT_CFG_TX_OP_ALLOW_GF20, 1);
+       rt2x00_set_field32(&reg, CCK_PROT_CFG_TX_OP_ALLOW_GF40, 1);
+       rt2x00usb_register_write(rt2x00dev, CCK_PROT_CFG, reg);
+
+       rt2x00usb_register_read(rt2x00dev, OFDM_PROT_CFG, &reg);
+       rt2x00_set_field32(&reg, OFDM_PROT_CFG_PROTECT_RATE, 8);
+       rt2x00_set_field32(&reg, OFDM_PROT_CFG_PROTECT_CTRL, 0);
+       rt2x00_set_field32(&reg, OFDM_PROT_CFG_PROTECT_NAV, 1);
+       rt2x00_set_field32(&reg, OFDM_PROT_CFG_TX_OP_ALLOW_CCK, 1);
+       rt2x00_set_field32(&reg, OFDM_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
+       rt2x00_set_field32(&reg, OFDM_PROT_CFG_TX_OP_ALLOW_MM20, 1);
+       rt2x00_set_field32(&reg, OFDM_PROT_CFG_TX_OP_ALLOW_MM40, 1);
+       rt2x00_set_field32(&reg, OFDM_PROT_CFG_TX_OP_ALLOW_GF20, 1);
+       rt2x00_set_field32(&reg, OFDM_PROT_CFG_TX_OP_ALLOW_GF40, 1);
+       rt2x00usb_register_write(rt2x00dev, OFDM_PROT_CFG, reg);
+
+       rt2x00usb_register_read(rt2x00dev, MM20_PROT_CFG, &reg);
+       rt2x00_set_field32(&reg, MM20_PROT_CFG_PROTECT_RATE, 0x4004);
+       rt2x00_set_field32(&reg, MM20_PROT_CFG_PROTECT_CTRL, 0);
+       rt2x00_set_field32(&reg, MM20_PROT_CFG_PROTECT_NAV, 1);
+       rt2x00_set_field32(&reg, MM20_PROT_CFG_TX_OP_ALLOW_CCK, 1);
+       rt2x00_set_field32(&reg, MM20_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
+       rt2x00_set_field32(&reg, MM20_PROT_CFG_TX_OP_ALLOW_MM20, 1);
+       rt2x00_set_field32(&reg, MM20_PROT_CFG_TX_OP_ALLOW_MM40, 0);
+       rt2x00_set_field32(&reg, MM20_PROT_CFG_TX_OP_ALLOW_GF20, 1);
+       rt2x00_set_field32(&reg, MM20_PROT_CFG_TX_OP_ALLOW_GF40, 0);
+       rt2x00usb_register_write(rt2x00dev, MM20_PROT_CFG, reg);
+
+       rt2x00usb_register_read(rt2x00dev, MM40_PROT_CFG, &reg);
+       rt2x00_set_field32(&reg, MM40_PROT_CFG_PROTECT_RATE, 0x4084);
+       rt2x00_set_field32(&reg, MM40_PROT_CFG_PROTECT_CTRL, 0);
+       rt2x00_set_field32(&reg, MM40_PROT_CFG_PROTECT_NAV, 1);
+       rt2x00_set_field32(&reg, MM40_PROT_CFG_TX_OP_ALLOW_CCK, 1);
+       rt2x00_set_field32(&reg, MM40_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
+       rt2x00_set_field32(&reg, MM40_PROT_CFG_TX_OP_ALLOW_MM20, 1);
+       rt2x00_set_field32(&reg, MM40_PROT_CFG_TX_OP_ALLOW_MM40, 1);
+       rt2x00_set_field32(&reg, MM40_PROT_CFG_TX_OP_ALLOW_GF20, 1);
+       rt2x00_set_field32(&reg, MM40_PROT_CFG_TX_OP_ALLOW_GF40, 1);
+       rt2x00usb_register_write(rt2x00dev, MM40_PROT_CFG, reg);
+
+       rt2x00usb_register_read(rt2x00dev, GF20_PROT_CFG, &reg);
+       rt2x00_set_field32(&reg, GF20_PROT_CFG_PROTECT_RATE, 0x4004);
+       rt2x00_set_field32(&reg, GF20_PROT_CFG_PROTECT_CTRL, 0);
+       rt2x00_set_field32(&reg, GF20_PROT_CFG_PROTECT_NAV, 1);
+       rt2x00_set_field32(&reg, GF20_PROT_CFG_TX_OP_ALLOW_CCK, 1);
+       rt2x00_set_field32(&reg, GF20_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
+       rt2x00_set_field32(&reg, GF20_PROT_CFG_TX_OP_ALLOW_MM20, 1);
+       rt2x00_set_field32(&reg, GF20_PROT_CFG_TX_OP_ALLOW_MM40, 0);
+       rt2x00_set_field32(&reg, GF20_PROT_CFG_TX_OP_ALLOW_GF20, 1);
+       rt2x00_set_field32(&reg, GF20_PROT_CFG_TX_OP_ALLOW_GF40, 0);
+       rt2x00usb_register_write(rt2x00dev, GF20_PROT_CFG, reg);
+
+       rt2x00usb_register_read(rt2x00dev, GF40_PROT_CFG, &reg);
+       rt2x00_set_field32(&reg, GF40_PROT_CFG_PROTECT_RATE, 0x4084);
+       rt2x00_set_field32(&reg, GF40_PROT_CFG_PROTECT_CTRL, 0);
+       rt2x00_set_field32(&reg, GF40_PROT_CFG_PROTECT_NAV, 1);
+       rt2x00_set_field32(&reg, GF40_PROT_CFG_TX_OP_ALLOW_CCK, 1);
+       rt2x00_set_field32(&reg, GF40_PROT_CFG_TX_OP_ALLOW_OFDM, 1);
+       rt2x00_set_field32(&reg, GF40_PROT_CFG_TX_OP_ALLOW_MM20, 1);
+       rt2x00_set_field32(&reg, GF40_PROT_CFG_TX_OP_ALLOW_MM40, 1);
+       rt2x00_set_field32(&reg, GF40_PROT_CFG_TX_OP_ALLOW_GF20, 1);
+       rt2x00_set_field32(&reg, GF40_PROT_CFG_TX_OP_ALLOW_GF40, 1);
+       rt2x00usb_register_write(rt2x00dev, GF40_PROT_CFG, reg);
+
+       rt2x00usb_register_write(rt2x00dev, PBF_CFG, 0xf40006);
+
+       rt2x00usb_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
+       rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0);
+       rt2x00_set_field32(&reg, WPDMA_GLO_CFG_TX_DMA_BUSY, 0);
+       rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0);
+       rt2x00_set_field32(&reg, WPDMA_GLO_CFG_RX_DMA_BUSY, 0);
+       rt2x00_set_field32(&reg, WPDMA_GLO_CFG_WP_DMA_BURST_SIZE, 3);
+       rt2x00_set_field32(&reg, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 0);
+       rt2x00_set_field32(&reg, WPDMA_GLO_CFG_BIG_ENDIAN, 0);
+       rt2x00_set_field32(&reg, WPDMA_GLO_CFG_RX_HDR_SCATTER, 0);
+       rt2x00_set_field32(&reg, WPDMA_GLO_CFG_HDR_SEG_LEN, 0);
+       rt2x00usb_register_write(rt2x00dev, WPDMA_GLO_CFG, reg);
+
+       rt2x00usb_register_write(rt2x00dev, TXOP_CTRL_CFG, 0x0000583f);
+       rt2x00usb_register_write(rt2x00dev, TXOP_HLDR_ET, 0x00000002);
+
+       rt2x00usb_register_read(rt2x00dev, TX_RTS_CFG, &reg);
+       rt2x00_set_field32(&reg, TX_RTS_CFG_AUTO_RTS_RETRY_LIMIT, 32);
+       rt2x00_set_field32(&reg, TX_RTS_CFG_RTS_THRES,
+                          IEEE80211_MAX_RTS_THRESHOLD);
+       rt2x00_set_field32(&reg, TX_RTS_CFG_RTS_FBK_EN, 0);
+       rt2x00usb_register_write(rt2x00dev, TX_RTS_CFG, reg);
+
+       rt2x00usb_register_write(rt2x00dev, EXP_ACK_TIME, 0x002400ca);
+       rt2x00usb_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003);
+
+       /*
+        * ASIC will keep garbage value after boot, clear encryption keys.
+        */
+       for (i = 0; i < 256; i++) {
+               u32 wcid[2] = { 0xffffffff, 0x00ffffff };
+               rt2x00usb_register_multiwrite(rt2x00dev, MAC_WCID_ENTRY(i),
+                                             wcid, sizeof(wcid));
+
+               rt2x00usb_register_write(rt2x00dev, MAC_WCID_ATTR_ENTRY(i), 1);
+               rt2x00usb_register_write(rt2x00dev, MAC_IVEIV_ENTRY(i), 0);
+       }
+
+       for (i = 0; i < 16; i++)
+               rt2x00usb_register_write(rt2x00dev,
+                                        SHARED_KEY_MODE_ENTRY(i), 0);
+
+       /*
+        * Clear all beacons
+        * For the Beacon base registers we only need to clear
+        * the first byte since that byte contains the VALID and OWNER
+        * bits which (when set to 0) will invalidate the entire beacon.
+        */
+       rt2x00usb_register_write(rt2x00dev, HW_BEACON_BASE0, 0);
+       rt2x00usb_register_write(rt2x00dev, HW_BEACON_BASE1, 0);
+       rt2x00usb_register_write(rt2x00dev, HW_BEACON_BASE2, 0);
+       rt2x00usb_register_write(rt2x00dev, HW_BEACON_BASE3, 0);
+       rt2x00usb_register_write(rt2x00dev, HW_BEACON_BASE4, 0);
+       rt2x00usb_register_write(rt2x00dev, HW_BEACON_BASE5, 0);
+       rt2x00usb_register_write(rt2x00dev, HW_BEACON_BASE6, 0);
+       rt2x00usb_register_write(rt2x00dev, HW_BEACON_BASE7, 0);
+
+       rt2x00usb_register_read(rt2x00dev, USB_CYC_CFG, &reg);
+       rt2x00_set_field32(&reg, USB_CYC_CFG_CLOCK_CYCLE, 30);
+       rt2x00usb_register_write(rt2x00dev, USB_CYC_CFG, reg);
+
+       rt2x00usb_register_read(rt2x00dev, HT_FBK_CFG0, &reg);
+       rt2x00_set_field32(&reg, HT_FBK_CFG0_HTMCS0FBK, 0);
+       rt2x00_set_field32(&reg, HT_FBK_CFG0_HTMCS1FBK, 0);
+       rt2x00_set_field32(&reg, HT_FBK_CFG0_HTMCS2FBK, 1);
+       rt2x00_set_field32(&reg, HT_FBK_CFG0_HTMCS3FBK, 2);
+       rt2x00_set_field32(&reg, HT_FBK_CFG0_HTMCS4FBK, 3);
+       rt2x00_set_field32(&reg, HT_FBK_CFG0_HTMCS5FBK, 4);
+       rt2x00_set_field32(&reg, HT_FBK_CFG0_HTMCS6FBK, 5);
+       rt2x00_set_field32(&reg, HT_FBK_CFG0_HTMCS7FBK, 6);
+       rt2x00usb_register_write(rt2x00dev, HT_FBK_CFG0, reg);
+
+       rt2x00usb_register_read(rt2x00dev, HT_FBK_CFG1, &reg);
+       rt2x00_set_field32(&reg, HT_FBK_CFG1_HTMCS8FBK, 8);
+       rt2x00_set_field32(&reg, HT_FBK_CFG1_HTMCS9FBK, 8);
+       rt2x00_set_field32(&reg, HT_FBK_CFG1_HTMCS10FBK, 9);
+       rt2x00_set_field32(&reg, HT_FBK_CFG1_HTMCS11FBK, 10);
+       rt2x00_set_field32(&reg, HT_FBK_CFG1_HTMCS12FBK, 11);
+       rt2x00_set_field32(&reg, HT_FBK_CFG1_HTMCS13FBK, 12);
+       rt2x00_set_field32(&reg, HT_FBK_CFG1_HTMCS14FBK, 13);
+       rt2x00_set_field32(&reg, HT_FBK_CFG1_HTMCS15FBK, 14);
+       rt2x00usb_register_write(rt2x00dev, HT_FBK_CFG1, reg);
+
+       rt2x00usb_register_read(rt2x00dev, LG_FBK_CFG0, &reg);
+       rt2x00_set_field32(&reg, LG_FBK_CFG0_OFDMMCS0FBK, 8);
+       rt2x00_set_field32(&reg, LG_FBK_CFG0_OFDMMCS1FBK, 8);
+       rt2x00_set_field32(&reg, LG_FBK_CFG0_OFDMMCS2FBK, 3);
+       rt2x00_set_field32(&reg, LG_FBK_CFG0_OFDMMCS3FBK, 10);
+       rt2x00_set_field32(&reg, LG_FBK_CFG0_OFDMMCS4FBK, 11);
+       rt2x00_set_field32(&reg, LG_FBK_CFG0_OFDMMCS5FBK, 12);
+       rt2x00_set_field32(&reg, LG_FBK_CFG0_OFDMMCS6FBK, 13);
+       rt2x00_set_field32(&reg, LG_FBK_CFG0_OFDMMCS7FBK, 14);
+       rt2x00usb_register_write(rt2x00dev, LG_FBK_CFG0, reg);
+
+       rt2x00usb_register_read(rt2x00dev, LG_FBK_CFG1, &reg);
+       rt2x00_set_field32(&reg, LG_FBK_CFG0_CCKMCS0FBK, 0);
+       rt2x00_set_field32(&reg, LG_FBK_CFG0_CCKMCS1FBK, 0);
+       rt2x00_set_field32(&reg, LG_FBK_CFG0_CCKMCS2FBK, 1);
+       rt2x00_set_field32(&reg, LG_FBK_CFG0_CCKMCS3FBK, 2);
+       rt2x00usb_register_write(rt2x00dev, LG_FBK_CFG1, reg);
+
+       /*
+        * We must clear the error counters.
+        * These registers are cleared on read,
+        * so we may pass a useless variable to store the value.
+        */
+       rt2x00usb_register_read(rt2x00dev, RX_STA_CNT0, &reg);
+       rt2x00usb_register_read(rt2x00dev, RX_STA_CNT1, &reg);
+       rt2x00usb_register_read(rt2x00dev, RX_STA_CNT2, &reg);
+       rt2x00usb_register_read(rt2x00dev, TX_STA_CNT0, &reg);
+       rt2x00usb_register_read(rt2x00dev, TX_STA_CNT1, &reg);
+       rt2x00usb_register_read(rt2x00dev, TX_STA_CNT2, &reg);
+
+       return 0;
+}
+
+static int rt2800usb_wait_bbp_rf_ready(struct rt2x00_dev *rt2x00dev)
+{
+       unsigned int i;
+       u32 reg;
+
+       for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
+               rt2x00usb_register_read(rt2x00dev, MAC_STATUS_CFG, &reg);
+               if (!rt2x00_get_field32(reg, MAC_STATUS_CFG_BBP_RF_BUSY))
+                       return 0;
+
+               udelay(REGISTER_BUSY_DELAY);
+       }
+
+       ERROR(rt2x00dev, "BBP/RF register access failed, aborting.\n");
+       return -EACCES;
+}
+
+static int rt2800usb_wait_bbp_ready(struct rt2x00_dev *rt2x00dev)
+{
+       unsigned int i;
+       u8 value;
+
+       /*
+        * BBP was enabled after firmware was loaded,
+        * but we need to reactivate it now.
+        */
+       rt2x00usb_register_write(rt2x00dev, H2M_BBP_AGENT, 0);
+       rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
+       msleep(1);
+
+       for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
+               rt2800usb_bbp_read(rt2x00dev, 0, &value);
+               if ((value != 0xff) && (value != 0x00))
+                       return 0;
+               udelay(REGISTER_BUSY_DELAY);
+       }
+
+       ERROR(rt2x00dev, "BBP register access failed, aborting.\n");
+       return -EACCES;
+}
+
+static int rt2800usb_init_bbp(struct rt2x00_dev *rt2x00dev)
+{
+       unsigned int i;
+       u16 eeprom;
+       u8 reg_id;
+       u8 value;
+
+       if (unlikely(rt2800usb_wait_bbp_rf_ready(rt2x00dev) ||
+                    rt2800usb_wait_bbp_ready(rt2x00dev)))
+               return -EACCES;
+
+       rt2800usb_bbp_write(rt2x00dev, 65, 0x2c);
+       rt2800usb_bbp_write(rt2x00dev, 66, 0x38);
+       rt2800usb_bbp_write(rt2x00dev, 69, 0x12);
+       rt2800usb_bbp_write(rt2x00dev, 70, 0x0a);
+       rt2800usb_bbp_write(rt2x00dev, 73, 0x10);
+       rt2800usb_bbp_write(rt2x00dev, 81, 0x37);
+       rt2800usb_bbp_write(rt2x00dev, 82, 0x62);
+       rt2800usb_bbp_write(rt2x00dev, 83, 0x6a);
+       rt2800usb_bbp_write(rt2x00dev, 84, 0x99);
+       rt2800usb_bbp_write(rt2x00dev, 86, 0x00);
+       rt2800usb_bbp_write(rt2x00dev, 91, 0x04);
+       rt2800usb_bbp_write(rt2x00dev, 92, 0x00);
+       rt2800usb_bbp_write(rt2x00dev, 103, 0x00);
+       rt2800usb_bbp_write(rt2x00dev, 105, 0x05);
+
+       if (rt2x00_rev(&rt2x00dev->chip) == RT2860C_VERSION) {
+               rt2800usb_bbp_write(rt2x00dev, 69, 0x16);
+               rt2800usb_bbp_write(rt2x00dev, 73, 0x12);
+       }
+
+       if (rt2x00_rev(&rt2x00dev->chip) > RT2860D_VERSION) {
+               rt2800usb_bbp_write(rt2x00dev, 84, 0x19);
+       }
+
+       if (rt2x00_rev(&rt2x00dev->chip) == RT3070_VERSION) {
+               rt2800usb_bbp_write(rt2x00dev, 70, 0x0a);
+               rt2800usb_bbp_write(rt2x00dev, 84, 0x99);
+               rt2800usb_bbp_write(rt2x00dev, 105, 0x05);
+       }
+
+       for (i = 0; i < EEPROM_BBP_SIZE; i++) {
+               rt2x00_eeprom_read(rt2x00dev, EEPROM_BBP_START + i, &eeprom);
+
+               if (eeprom != 0xffff && eeprom != 0x0000) {
+                       reg_id = rt2x00_get_field16(eeprom, EEPROM_BBP_REG_ID);
+                       value = rt2x00_get_field16(eeprom, EEPROM_BBP_VALUE);
+                       rt2800usb_bbp_write(rt2x00dev, reg_id, value);
+               }
+       }
+
+       return 0;
+}
+
+static u8 rt2800usb_init_rx_filter(struct rt2x00_dev *rt2x00dev,
+                                  bool bw40, u8 rfcsr24, u8 filter_target)
+{
+       unsigned int i;
+       u8 bbp;
+       u8 rfcsr;
+       u8 passband;
+       u8 stopband;
+       u8 overtuned = 0;
+
+       rt2800usb_rfcsr_write(rt2x00dev, 24, rfcsr24);
+
+       rt2800usb_bbp_read(rt2x00dev, 4, &bbp);
+       rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 2 * bw40);
+       rt2800usb_bbp_write(rt2x00dev, 4, bbp);
+
+       rt2800usb_rfcsr_read(rt2x00dev, 22, &rfcsr);
+       rt2x00_set_field8(&rfcsr, RFCSR22_BASEBAND_LOOPBACK, 1);
+       rt2800usb_rfcsr_write(rt2x00dev, 22, rfcsr);
+
+       /*
+        * Set power & frequency of passband test tone
+        */
+       rt2800usb_bbp_write(rt2x00dev, 24, 0);
+
+       for (i = 0; i < 100; i++) {
+               rt2800usb_bbp_write(rt2x00dev, 25, 0x90);
+               msleep(1);
+
+               rt2800usb_bbp_read(rt2x00dev, 55, &passband);
+               if (passband)
+                       break;
+       }
+
+       /*
+        * Set power & frequency of stopband test tone
+        */
+       rt2800usb_bbp_write(rt2x00dev, 24, 0x06);
+
+       for (i = 0; i < 100; i++) {
+               rt2800usb_bbp_write(rt2x00dev, 25, 0x90);
+               msleep(1);
+
+               rt2800usb_bbp_read(rt2x00dev, 55, &stopband);
+
+               if ((passband - stopband) <= filter_target) {
+                       rfcsr24++;
+                       overtuned += ((passband - stopband) == filter_target);
+               } else
+                       break;
+
+               rt2800usb_rfcsr_write(rt2x00dev, 24, rfcsr24);
+       }
+
+       rfcsr24 -= !!overtuned;
+
+       rt2800usb_rfcsr_write(rt2x00dev, 24, rfcsr24);
+       return rfcsr24;
+}
+
+static int rt2800usb_init_rfcsr(struct rt2x00_dev *rt2x00dev)
+{
+       u8 rfcsr;
+       u8 bbp;
+
+       if (rt2x00_rev(&rt2x00dev->chip) != RT3070_VERSION)
+               return 0;
+
+       /*
+        * Init RF calibration.
+        */
+       rt2800usb_rfcsr_read(rt2x00dev, 30, &rfcsr);
+       rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 1);
+       rt2800usb_rfcsr_write(rt2x00dev, 30, rfcsr);
+       msleep(1);
+       rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 0);
+       rt2800usb_rfcsr_write(rt2x00dev, 30, rfcsr);
+
+       rt2800usb_rfcsr_write(rt2x00dev, 4, 0x40);
+       rt2800usb_rfcsr_write(rt2x00dev, 5, 0x03);
+       rt2800usb_rfcsr_write(rt2x00dev, 6, 0x02);
+       rt2800usb_rfcsr_write(rt2x00dev, 7, 0x70);
+       rt2800usb_rfcsr_write(rt2x00dev, 9, 0x0f);
+       rt2800usb_rfcsr_write(rt2x00dev, 10, 0x71);
+       rt2800usb_rfcsr_write(rt2x00dev, 11, 0x21);
+       rt2800usb_rfcsr_write(rt2x00dev, 12, 0x7b);
+       rt2800usb_rfcsr_write(rt2x00dev, 14, 0x90);
+       rt2800usb_rfcsr_write(rt2x00dev, 15, 0x58);
+       rt2800usb_rfcsr_write(rt2x00dev, 16, 0xb3);
+       rt2800usb_rfcsr_write(rt2x00dev, 17, 0x92);
+       rt2800usb_rfcsr_write(rt2x00dev, 18, 0x2c);
+       rt2800usb_rfcsr_write(rt2x00dev, 19, 0x02);
+       rt2800usb_rfcsr_write(rt2x00dev, 20, 0xba);
+       rt2800usb_rfcsr_write(rt2x00dev, 21, 0xdb);
+       rt2800usb_rfcsr_write(rt2x00dev, 24, 0x16);
+       rt2800usb_rfcsr_write(rt2x00dev, 25, 0x01);
+       rt2800usb_rfcsr_write(rt2x00dev, 27, 0x03);
+       rt2800usb_rfcsr_write(rt2x00dev, 29, 0x1f);
+
+       /*
+        * Set RX Filter calibration for 20MHz and 40MHz
+        */
+       rt2x00dev->calibration[0] =
+           rt2800usb_init_rx_filter(rt2x00dev, false, 0x07, 0x16);
+       rt2x00dev->calibration[1] =
+           rt2800usb_init_rx_filter(rt2x00dev, true, 0x27, 0x19);
+
+       /*
+        * Set back to initial state
+        */
+       rt2800usb_bbp_write(rt2x00dev, 24, 0);
+
+       rt2800usb_rfcsr_read(rt2x00dev, 22, &rfcsr);
+       rt2x00_set_field8(&rfcsr, RFCSR22_BASEBAND_LOOPBACK, 0);
+       rt2800usb_rfcsr_write(rt2x00dev, 22, rfcsr);
+
+       /*
+        * set BBP back to BW20
+        */
+       rt2800usb_bbp_read(rt2x00dev, 4, &bbp);
+       rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 0);
+       rt2800usb_bbp_write(rt2x00dev, 4, bbp);
+
+       return 0;
+}
+
+/*
+ * Device state switch handlers.
+ */
+static void rt2800usb_toggle_rx(struct rt2x00_dev *rt2x00dev,
+                               enum dev_state state)
+{
+       u32 reg;
+
+       rt2x00usb_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
+       rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_RX,
+                          (state == STATE_RADIO_RX_ON) ||
+                          (state == STATE_RADIO_RX_ON_LINK));
+       rt2x00usb_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
+}
+
+static int rt2800usb_wait_wpdma_ready(struct rt2x00_dev *rt2x00dev)
+{
+       unsigned int i;
+       u32 reg;
+
+       for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
+               rt2x00usb_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
+               if (!rt2x00_get_field32(reg, WPDMA_GLO_CFG_TX_DMA_BUSY) &&
+                   !rt2x00_get_field32(reg, WPDMA_GLO_CFG_RX_DMA_BUSY))
+                       return 0;
+
+               msleep(1);
+       }
+
+       ERROR(rt2x00dev, "WPDMA TX/RX busy, aborting.\n");
+       return -EACCES;
+}
+
+static int rt2800usb_enable_radio(struct rt2x00_dev *rt2x00dev)
+{
+       u32 reg;
+       u16 word;
+
+       /*
+        * Initialize all registers.
+        */
+       if (unlikely(rt2800usb_wait_wpdma_ready(rt2x00dev) ||
+                    rt2800usb_init_registers(rt2x00dev) ||
+                    rt2800usb_init_bbp(rt2x00dev) ||
+                    rt2800usb_init_rfcsr(rt2x00dev)))
+               return -EIO;
+
+       rt2x00usb_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
+       rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_TX, 1);
+       rt2x00usb_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
+
+       udelay(50);
+
+       rt2x00usb_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
+       rt2x00_set_field32(&reg, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1);
+       rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_RX_DMA, 1);
+       rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_TX_DMA, 1);
+       rt2x00usb_register_write(rt2x00dev, WPDMA_GLO_CFG, reg);
+
+
+       rt2x00usb_register_read(rt2x00dev, USB_DMA_CFG, &reg);
+       rt2x00_set_field32(&reg, USB_DMA_CFG_PHY_CLEAR, 0);
+       /* Don't use bulk in aggregation when working with USB 1.1 */
+       rt2x00_set_field32(&reg, USB_DMA_CFG_RX_BULK_AGG_EN,
+                          (rt2x00dev->rx->usb_maxpacket == 512));
+       rt2x00_set_field32(&reg, USB_DMA_CFG_RX_BULK_AGG_TIMEOUT, 128);
+       /*
+        * Total room for RX frames in kilobytes, PBF might still exceed
+        * this limit so reduce the number to prevent errors.
+        */
+       rt2x00_set_field32(&reg, USB_DMA_CFG_RX_BULK_AGG_LIMIT,
+                          ((RX_ENTRIES * DATA_FRAME_SIZE) / 1024) - 3);
+       rt2x00_set_field32(&reg, USB_DMA_CFG_RX_BULK_EN, 1);
+       rt2x00_set_field32(&reg, USB_DMA_CFG_TX_BULK_EN, 1);
+       rt2x00usb_register_write(rt2x00dev, USB_DMA_CFG, reg);
+
+       rt2x00usb_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
+       rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_TX, 1);
+       rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_RX, 1);
+       rt2x00usb_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
+
+       /*
+        * Initialize LED control
+        */
+       rt2x00_eeprom_read(rt2x00dev, EEPROM_LED1, &word);
+       rt2800usb_mcu_request(rt2x00dev, MCU_LED_1, 0xff,
+                             word & 0xff, (word >> 8) & 0xff);
+
+       rt2x00_eeprom_read(rt2x00dev, EEPROM_LED2, &word);
+       rt2800usb_mcu_request(rt2x00dev, MCU_LED_2, 0xff,
+                             word & 0xff, (word >> 8) & 0xff);
+
+       rt2x00_eeprom_read(rt2x00dev, EEPROM_LED3, &word);
+       rt2800usb_mcu_request(rt2x00dev, MCU_LED_3, 0xff,
+                             word & 0xff, (word >> 8) & 0xff);
+
+       return 0;
+}
+
+static void rt2800usb_disable_radio(struct rt2x00_dev *rt2x00dev)
+{
+       u32 reg;
+
+       rt2x00usb_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
+       rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0);
+       rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0);
+       rt2x00usb_register_write(rt2x00dev, WPDMA_GLO_CFG, reg);
+
+       rt2x00usb_register_write(rt2x00dev, MAC_SYS_CTRL, 0);
+       rt2x00usb_register_write(rt2x00dev, PWR_PIN_CFG, 0);
+       rt2x00usb_register_write(rt2x00dev, TX_PIN_CFG, 0);
+
+       /* Wait for DMA, ignore error */
+       rt2800usb_wait_wpdma_ready(rt2x00dev);
+
+       rt2x00usb_disable_radio(rt2x00dev);
+}
+
+static int rt2800usb_set_state(struct rt2x00_dev *rt2x00dev,
+                              enum dev_state state)
+{
+       if (state == STATE_AWAKE)
+               rt2800usb_mcu_request(rt2x00dev, MCU_WAKEUP, 0xff, 0, 0);
+       else
+               rt2800usb_mcu_request(rt2x00dev, MCU_SLEEP, 0xff, 0, 2);
+
+       return 0;
+}
+
+static int rt2800usb_set_device_state(struct rt2x00_dev *rt2x00dev,
+                                     enum dev_state state)
+{
+       int retval = 0;
+
+       switch (state) {
+       case STATE_RADIO_ON:
+               /*
+                * Before the radio can be enabled, the device first has
+                * to be woken up. After that it needs a bit of time
+                * to be fully awake and the radio can be enabled.
+                */
+               rt2800usb_set_state(rt2x00dev, STATE_AWAKE);
+               msleep(1);
+               retval = rt2800usb_enable_radio(rt2x00dev);
+               break;
+       case STATE_RADIO_OFF:
+               /*
+                * After the radio has been disablee, the device should
+                * be put to sleep for powersaving.
+                */
+               rt2800usb_disable_radio(rt2x00dev);
+               rt2800usb_set_state(rt2x00dev, STATE_SLEEP);
+               break;
+       case STATE_RADIO_RX_ON:
+       case STATE_RADIO_RX_ON_LINK:
+       case STATE_RADIO_RX_OFF:
+       case STATE_RADIO_RX_OFF_LINK:
+               rt2800usb_toggle_rx(rt2x00dev, state);
+               break;
+       case STATE_RADIO_IRQ_ON:
+       case STATE_RADIO_IRQ_OFF:
+               /* No support, but no error either */
+               break;
+       case STATE_DEEP_SLEEP:
+       case STATE_SLEEP:
+       case STATE_STANDBY:
+       case STATE_AWAKE:
+               retval = rt2800usb_set_state(rt2x00dev, state);
+               break;
+       default:
+               retval = -ENOTSUPP;
+               break;
+       }
+
+       if (unlikely(retval))
+               ERROR(rt2x00dev, "Device failed to enter state %d (%d).\n",
+                     state, retval);
+
+       return retval;
+}
+
+/*
+ * TX descriptor initialization
+ */
+static void rt2800usb_write_tx_desc(struct rt2x00_dev *rt2x00dev,
+                                   struct sk_buff *skb,
+                                   struct txentry_desc *txdesc)
+{
+       struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
+       __le32 *txi = skbdesc->desc;
+       __le32 *txwi = &txi[TXINFO_DESC_SIZE / sizeof(__le32)];
+       u32 word;
+
+       /*
+        * Initialize TX Info descriptor
+        */
+       rt2x00_desc_read(txwi, 0, &word);
+       rt2x00_set_field32(&word, TXWI_W0_FRAG,
+                          test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags));
+       rt2x00_set_field32(&word, TXWI_W0_MIMO_PS, 0);
+       rt2x00_set_field32(&word, TXWI_W0_CF_ACK, 0);
+       rt2x00_set_field32(&word, TXWI_W0_TS,
+                          test_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags));
+       rt2x00_set_field32(&word, TXWI_W0_AMPDU,
+                          test_bit(ENTRY_TXD_HT_AMPDU, &txdesc->flags));
+       rt2x00_set_field32(&word, TXWI_W0_MPDU_DENSITY, txdesc->mpdu_density);
+       rt2x00_set_field32(&word, TXWI_W0_TX_OP, txdesc->ifs);
+       rt2x00_set_field32(&word, TXWI_W0_MCS, txdesc->mcs);
+       rt2x00_set_field32(&word, TXWI_W0_BW,
+                          test_bit(ENTRY_TXD_HT_BW_40, &txdesc->flags));
+       rt2x00_set_field32(&word, TXWI_W0_SHORT_GI,
+                          test_bit(ENTRY_TXD_HT_SHORT_GI, &txdesc->flags));
+       rt2x00_set_field32(&word, TXWI_W0_STBC, txdesc->stbc);
+       rt2x00_set_field32(&word, TXWI_W0_PHYMODE, txdesc->rate_mode);
+       rt2x00_desc_write(txwi, 0, word);
+
+       rt2x00_desc_read(txwi, 1, &word);
+       rt2x00_set_field32(&word, TXWI_W1_ACK,
+                          test_bit(ENTRY_TXD_ACK, &txdesc->flags));
+       rt2x00_set_field32(&word, TXWI_W1_NSEQ,
+                          test_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags));
+       rt2x00_set_field32(&word, TXWI_W1_BW_WIN_SIZE, txdesc->ba_size);
+       rt2x00_set_field32(&word, TXWI_W1_WIRELESS_CLI_ID,
+                          test_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags) ?
+                              txdesc->key_idx : 0xff);
+       rt2x00_set_field32(&word, TXWI_W1_MPDU_TOTAL_BYTE_COUNT,
+                          skb->len - txdesc->l2pad);
+       rt2x00_set_field32(&word, TXWI_W1_PACKETID,
+                          skbdesc->entry->entry_idx);
+       rt2x00_desc_write(txwi, 1, word);
+
+       /*
+        * Always write 0 to IV/EIV fields, hardware will insert the IV
+        * from the IVEIV register when TXINFO_W0_WIV is set to 0.
+        * When TXINFO_W0_WIV is set to 1 it will use the IV data
+        * from the descriptor. The TXWI_W1_WIRELESS_CLI_ID indicates which
+        * crypto entry in the registers should be used to encrypt the frame.
+        */
+       _rt2x00_desc_write(txwi, 2, 0 /* skbdesc->iv[0] */);
+       _rt2x00_desc_write(txwi, 3, 0 /* skbdesc->iv[1] */);
+
+       /*
+        * Initialize TX descriptor
+        */
+       rt2x00_desc_read(txi, 0, &word);
+       rt2x00_set_field32(&word, TXINFO_W0_USB_DMA_TX_PKT_LEN,
+                          skb->len + TXWI_DESC_SIZE);
+       rt2x00_set_field32(&word, TXINFO_W0_WIV,
+                          !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc->flags));
+       rt2x00_set_field32(&word, TXINFO_W0_QSEL, 2);
+       rt2x00_set_field32(&word, TXINFO_W0_SW_USE_LAST_ROUND, 0);
+       rt2x00_set_field32(&word, TXINFO_W0_USB_DMA_NEXT_VALID, 0);
+       rt2x00_set_field32(&word, TXINFO_W0_USB_DMA_TX_BURST,
+                          test_bit(ENTRY_TXD_BURST, &txdesc->flags));
+       rt2x00_desc_write(txi, 0, word);
+}
+
+/*
+ * TX data initialization
+ */
+static void rt2800usb_write_beacon(struct queue_entry *entry)
+{
+       struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
+       struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
+       unsigned int beacon_base;
+       u32 reg;
+
+       /*
+        * Add the descriptor in front of the skb.
+        */
+       skb_push(entry->skb, entry->queue->desc_size);
+       memcpy(entry->skb->data, skbdesc->desc, skbdesc->desc_len);
+       skbdesc->desc = entry->skb->data;
+
+       /*
+        * Disable beaconing while we are reloading the beacon data,
+        * otherwise we might be sending out invalid data.
+        */
+       rt2x00usb_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
+       rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_TICKING, 0);
+       rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE, 0);
+       rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 0);
+       rt2x00usb_register_write(rt2x00dev, BCN_TIME_CFG, reg);
+
+       /*
+        * Write entire beacon with descriptor to register.
+        */
+       beacon_base = HW_BEACON_OFFSET(entry->entry_idx);
+       rt2x00usb_vendor_request_large_buff(rt2x00dev, USB_MULTI_WRITE,
+                                           USB_VENDOR_REQUEST_OUT, beacon_base,
+                                           entry->skb->data, entry->skb->len,
+                                           REGISTER_TIMEOUT32(entry->skb->len));
+
+       /*
+        * Clean up the beacon skb.
+        */
+       dev_kfree_skb(entry->skb);
+       entry->skb = NULL;
+}
+
+static int rt2800usb_get_tx_data_len(struct queue_entry *entry)
+{
+       int length;
+
+       /*
+        * The length _must_ include 4 bytes padding,
+        * it should always be multiple of 4,
+        * but it must _not_ be a multiple of the USB packet size.
+        */
+       length = roundup(entry->skb->len + 4, 4);
+       length += (4 * !(length % entry->queue->usb_maxpacket));
+
+       return length;
+}
+
+static void rt2800usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev,
+                                   const enum data_queue_qid queue)
+{
+       u32 reg;
+
+       if (queue != QID_BEACON) {
+               rt2x00usb_kick_tx_queue(rt2x00dev, queue);
+               return;
+       }
+
+       rt2x00usb_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
+       if (!rt2x00_get_field32(reg, BCN_TIME_CFG_BEACON_GEN)) {
+               rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_TICKING, 1);
+               rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE, 1);
+               rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 1);
+               rt2x00usb_register_write(rt2x00dev, BCN_TIME_CFG, reg);
+       }
+}
+
+/*
+ * RX control handlers
+ */
+static void rt2800usb_fill_rxdone(struct queue_entry *entry,
+                                 struct rxdone_entry_desc *rxdesc)
+{
+       struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
+       struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
+       __le32 *rxd = (__le32 *)entry->skb->data;
+       __le32 *rxwi;
+       u32 rxd0;
+       u32 rxwi0;
+       u32 rxwi1;
+       u32 rxwi2;
+       u32 rxwi3;
+
+       /*
+        * Copy descriptor to the skbdesc->desc buffer, making it safe from
+        * moving of frame data in rt2x00usb.
+        */
+       memcpy(skbdesc->desc, rxd, skbdesc->desc_len);
+       rxd = (__le32 *)skbdesc->desc;
+       rxwi = &rxd[RXD_DESC_SIZE / sizeof(__le32)];
+
+       /*
+        * It is now safe to read the descriptor on all architectures.
+        */
+       rt2x00_desc_read(rxd, 0, &rxd0);
+       rt2x00_desc_read(rxwi, 0, &rxwi0);
+       rt2x00_desc_read(rxwi, 1, &rxwi1);
+       rt2x00_desc_read(rxwi, 2, &rxwi2);
+       rt2x00_desc_read(rxwi, 3, &rxwi3);
+
+       if (rt2x00_get_field32(rxd0, RXD_W0_CRC_ERROR))
+               rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC;
+
+       if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags)) {
+               rxdesc->cipher = rt2x00_get_field32(rxwi0, RXWI_W0_UDF);
+               rxdesc->cipher_status =
+                   rt2x00_get_field32(rxd0, RXD_W0_CIPHER_ERROR);
+       }
+
+       if (rt2x00_get_field32(rxd0, RXD_W0_DECRYPTED)) {
+               /*
+                * Hardware has stripped IV/EIV data from 802.11 frame during
+                * decryption. Unfortunately the descriptor doesn't contain
+                * any fields with the EIV/IV data either, so they can't
+                * be restored by rt2x00lib.
+                */
+               rxdesc->flags |= RX_FLAG_IV_STRIPPED;
+
+               if (rxdesc->cipher_status == RX_CRYPTO_SUCCESS)
+                       rxdesc->flags |= RX_FLAG_DECRYPTED;
+               else if (rxdesc->cipher_status == RX_CRYPTO_FAIL_MIC)
+                       rxdesc->flags |= RX_FLAG_MMIC_ERROR;
+       }
+
+       if (rt2x00_get_field32(rxd0, RXD_W0_MY_BSS))
+               rxdesc->dev_flags |= RXDONE_MY_BSS;
+
+       if (rt2x00_get_field32(rxd0, RXD_W0_L2PAD))
+               rxdesc->dev_flags |= RXDONE_L2PAD;
+
+       if (rt2x00_get_field32(rxwi1, RXWI_W1_SHORT_GI))
+               rxdesc->flags |= RX_FLAG_SHORT_GI;
+
+       if (rt2x00_get_field32(rxwi1, RXWI_W1_BW))
+               rxdesc->flags |= RX_FLAG_40MHZ;
+
+       /*
+        * Detect RX rate, always use MCS as signal type.
+        */
+       rxdesc->dev_flags |= RXDONE_SIGNAL_MCS;
+       rxdesc->rate_mode = rt2x00_get_field32(rxwi1, RXWI_W1_PHYMODE);
+       rxdesc->signal = rt2x00_get_field32(rxwi1, RXWI_W1_MCS);
+
+       /*
+        * Mask of 0x8 bit to remove the short preamble flag.
+        */
+       if (rxdesc->rate_mode == RATE_MODE_CCK)
+               rxdesc->signal &= ~0x8;
+
+       rxdesc->rssi =
+           (rt2x00_get_field32(rxwi2, RXWI_W2_RSSI0) +
+            rt2x00_get_field32(rxwi2, RXWI_W2_RSSI1)) / 2;
+
+       rxdesc->noise =
+           (rt2x00_get_field32(rxwi3, RXWI_W3_SNR0) +
+            rt2x00_get_field32(rxwi3, RXWI_W3_SNR1)) / 2;
+
+       rxdesc->size = rt2x00_get_field32(rxwi0, RXWI_W0_MPDU_TOTAL_BYTE_COUNT);
+
+       /*
+        * Remove RXWI descriptor from start of buffer.
+        */
+       skb_pull(entry->skb, skbdesc->desc_len);
+       skb_trim(entry->skb, rxdesc->size);
+}
+
+/*
+ * Device probe functions.
+ */
+static int rt2800usb_validate_eeprom(struct rt2x00_dev *rt2x00dev)
+{
+       u16 word;
+       u8 *mac;
+       u8 default_lna_gain;
+
+       rt2x00usb_eeprom_read(rt2x00dev, rt2x00dev->eeprom, EEPROM_SIZE);
+
+       /*
+        * Start validation of the data that has been read.
+        */
+       mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0);
+       if (!is_valid_ether_addr(mac)) {
+               DECLARE_MAC_BUF(macbuf);
+
+               random_ether_addr(mac);
+               EEPROM(rt2x00dev, "MAC: %s\n", print_mac(macbuf, mac));
+       }
+
+       rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word);
+       if (word == 0xffff) {
+               rt2x00_set_field16(&word, EEPROM_ANTENNA_RXPATH, 2);
+               rt2x00_set_field16(&word, EEPROM_ANTENNA_TXPATH, 1);
+               rt2x00_set_field16(&word, EEPROM_ANTENNA_RF_TYPE, RF2820);
+               rt2x00_eeprom_write(rt2x00dev, EEPROM_ANTENNA, word);
+               EEPROM(rt2x00dev, "Antenna: 0x%04x\n", word);
+       } else if (rt2x00_rev(&rt2x00dev->chip) < RT2883_VERSION) {
+               /*
+                * There is a max of 2 RX streams for RT2870 series
+                */
+               if (rt2x00_get_field16(word, EEPROM_ANTENNA_RXPATH) > 2)
+                       rt2x00_set_field16(&word, EEPROM_ANTENNA_RXPATH, 2);
+               rt2x00_eeprom_write(rt2x00dev, EEPROM_ANTENNA, word);
+       }
+
+       rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &word);
+       if (word == 0xffff) {
+               rt2x00_set_field16(&word, EEPROM_NIC_HW_RADIO, 0);
+               rt2x00_set_field16(&word, EEPROM_NIC_DYNAMIC_TX_AGC, 0);
+               rt2x00_set_field16(&word, EEPROM_NIC_EXTERNAL_LNA_BG, 0);
+               rt2x00_set_field16(&word, EEPROM_NIC_EXTERNAL_LNA_A, 0);
+               rt2x00_set_field16(&word, EEPROM_NIC_CARDBUS_ACCEL, 0);
+               rt2x00_set_field16(&word, EEPROM_NIC_BW40M_SB_BG, 0);
+               rt2x00_set_field16(&word, EEPROM_NIC_BW40M_SB_A, 0);
+               rt2x00_set_field16(&word, EEPROM_NIC_WPS_PBC, 0);
+               rt2x00_set_field16(&word, EEPROM_NIC_BW40M_BG, 0);
+               rt2x00_set_field16(&word, EEPROM_NIC_BW40M_A, 0);
+               rt2x00_eeprom_write(rt2x00dev, EEPROM_NIC, word);
+               EEPROM(rt2x00dev, "NIC: 0x%04x\n", word);
+       }
+
+       rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &word);
+       if ((word & 0x00ff) == 0x00ff) {
+               rt2x00_set_field16(&word, EEPROM_FREQ_OFFSET, 0);
+               rt2x00_set_field16(&word, EEPROM_FREQ_LED_MODE,
+                                  LED_MODE_TXRX_ACTIVITY);
+               rt2x00_set_field16(&word, EEPROM_FREQ_LED_POLARITY, 0);
+               rt2x00_eeprom_write(rt2x00dev, EEPROM_FREQ, word);
+               rt2x00_eeprom_write(rt2x00dev, EEPROM_LED1, 0x5555);
+               rt2x00_eeprom_write(rt2x00dev, EEPROM_LED2, 0x2221);
+               rt2x00_eeprom_write(rt2x00dev, EEPROM_LED3, 0xa9f8);
+               EEPROM(rt2x00dev, "Freq: 0x%04x\n", word);
+       }
+
+       /*
+        * During the LNA validation we are going to use
+        * lna0 as correct value. Note that EEPROM_LNA
+        * is never validated.
+        */
+       rt2x00_eeprom_read(rt2x00dev, EEPROM_LNA, &word);
+       default_lna_gain = rt2x00_get_field16(word, EEPROM_LNA_A0);
+
+       rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_BG, &word);
+       if (abs(rt2x00_get_field16(word, EEPROM_RSSI_BG_OFFSET0)) > 10)
+               rt2x00_set_field16(&word, EEPROM_RSSI_BG_OFFSET0, 0);
+       if (abs(rt2x00_get_field16(word, EEPROM_RSSI_BG_OFFSET1)) > 10)
+               rt2x00_set_field16(&word, EEPROM_RSSI_BG_OFFSET1, 0);
+       rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_BG, word);
+
+       rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_BG2, &word);
+       if (abs(rt2x00_get_field16(word, EEPROM_RSSI_BG2_OFFSET2)) > 10)
+               rt2x00_set_field16(&word, EEPROM_RSSI_BG2_OFFSET2, 0);
+       if (rt2x00_get_field16(word, EEPROM_RSSI_BG2_LNA_A1) == 0x00 ||
+           rt2x00_get_field16(word, EEPROM_RSSI_BG2_LNA_A1) == 0xff)
+               rt2x00_set_field16(&word, EEPROM_RSSI_BG2_LNA_A1,
+                                  default_lna_gain);
+       rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_BG2, word);
+
+       rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_A, &word);
+       if (abs(rt2x00_get_field16(word, EEPROM_RSSI_A_OFFSET0)) > 10)
+               rt2x00_set_field16(&word, EEPROM_RSSI_A_OFFSET0, 0);
+       if (abs(rt2x00_get_field16(word, EEPROM_RSSI_A_OFFSET1)) > 10)
+               rt2x00_set_field16(&word, EEPROM_RSSI_A_OFFSET1, 0);
+       rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_A, word);
+
+       rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_A2, &word);
+       if (abs(rt2x00_get_field16(word, EEPROM_RSSI_A2_OFFSET2)) > 10)
+               rt2x00_set_field16(&word, EEPROM_RSSI_A2_OFFSET2, 0);
+       if (rt2x00_get_field16(word, EEPROM_RSSI_A2_LNA_A2) == 0x00 ||
+           rt2x00_get_field16(word, EEPROM_RSSI_A2_LNA_A2) == 0xff)
+               rt2x00_set_field16(&word, EEPROM_RSSI_A2_LNA_A2,
+                                  default_lna_gain);
+       rt2x00_eeprom_write(rt2x00dev, EEPROM_RSSI_A2, word);
+
+       return 0;
+}
+
+static int rt2800usb_init_eeprom(struct rt2x00_dev *rt2x00dev)
+{
+       u32 reg;
+       u16 value;
+       u16 eeprom;
+
+       /*
+        * Read EEPROM word for configuration.
+        */
+       rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom);
+
+       /*
+        * Identify RF chipset.
+        */
+       value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE);
+       rt2x00usb_register_read(rt2x00dev, MAC_CSR0, &reg);
+       rt2x00_set_chip(rt2x00dev, RT2870, value, reg);
+
+       /*
+        * The check for rt2860 is not a typo, some rt2870 hardware
+        * identifies itself as rt2860 in the CSR register.
+        */
+       if (!rt2x00_check_rev(&rt2x00dev->chip, 0xfff00000, 0x28600000) &&
+           !rt2x00_check_rev(&rt2x00dev->chip, 0xfff00000, 0x28700000) &&
+           !rt2x00_check_rev(&rt2x00dev->chip, 0xfff00000, 0x28800000) &&
+           !rt2x00_check_rev(&rt2x00dev->chip, 0xffff0000, 0x30700000)) {
+               ERROR(rt2x00dev, "Invalid RT chipset detected.\n");
+               return -ENODEV;
+       }
+
+       if (!rt2x00_rf(&rt2x00dev->chip, RF2820) &&
+           !rt2x00_rf(&rt2x00dev->chip, RF2850) &&
+           !rt2x00_rf(&rt2x00dev->chip, RF2720) &&
+           !rt2x00_rf(&rt2x00dev->chip, RF2750) &&
+           !rt2x00_rf(&rt2x00dev->chip, RF3020) &&
+           !rt2x00_rf(&rt2x00dev->chip, RF2020)) {
+               ERROR(rt2x00dev, "Invalid RF chipset detected.\n");
+               return -ENODEV;
+       }
+
+       /*
+        * Identify default antenna configuration.
+        */
+       rt2x00dev->default_ant.tx =
+           rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TXPATH);
+       rt2x00dev->default_ant.rx =
+           rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RXPATH);
+
+       /*
+        * Read frequency offset and RF programming sequence.
+        */
+       rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &eeprom);
+       rt2x00dev->freq_offset = rt2x00_get_field16(eeprom, EEPROM_FREQ_OFFSET);
+
+       /*
+        * Read external LNA informations.
+        */
+       rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom);
+
+       if (rt2x00_get_field16(eeprom, EEPROM_NIC_EXTERNAL_LNA_A))
+               __set_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags);
+       if (rt2x00_get_field16(eeprom, EEPROM_NIC_EXTERNAL_LNA_BG))
+               __set_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags);
+
+       /*
+        * Detect if this device has an hardware controlled radio.
+        */
+#ifdef CONFIG_RT2X00_LIB_RFKILL
+       if (rt2x00_get_field16(eeprom, EEPROM_NIC_HW_RADIO))
+               __set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags);
+#endif /* CONFIG_RT2X00_LIB_RFKILL */
+
+       /*
+        * Store led settings, for correct led behaviour.
+        */
+#ifdef CONFIG_RT2X00_LIB_LEDS
+       rt2800usb_init_led(rt2x00dev, &rt2x00dev->led_radio, LED_TYPE_RADIO);
+       rt2800usb_init_led(rt2x00dev, &rt2x00dev->led_assoc, LED_TYPE_ASSOC);
+       rt2800usb_init_led(rt2x00dev, &rt2x00dev->led_qual, LED_TYPE_QUALITY);
+
+       rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ,
+                          &rt2x00dev->led_mcu_reg);
+#endif /* CONFIG_RT2X00_LIB_LEDS */
+
+       return 0;
+}
+
+/*
+ * RF value list for rt2870
+ * Supports: 2.4 GHz (all) & 5.2 GHz (RF2850 & RF2750)
+ */
+static const struct rf_channel rf_vals[] = {
+       { 1,  0x18402ecc, 0x184c0786, 0x1816b455, 0x1800510b },
+       { 2,  0x18402ecc, 0x184c0786, 0x18168a55, 0x1800519f },
+       { 3,  0x18402ecc, 0x184c078a, 0x18168a55, 0x1800518b },
+       { 4,  0x18402ecc, 0x184c078a, 0x18168a55, 0x1800519f },
+       { 5,  0x18402ecc, 0x184c078e, 0x18168a55, 0x1800518b },
+       { 6,  0x18402ecc, 0x184c078e, 0x18168a55, 0x1800519f },
+       { 7,  0x18402ecc, 0x184c0792, 0x18168a55, 0x1800518b },
+       { 8,  0x18402ecc, 0x184c0792, 0x18168a55, 0x1800519f },
+       { 9,  0x18402ecc, 0x184c0796, 0x18168a55, 0x1800518b },
+       { 10, 0x18402ecc, 0x184c0796, 0x18168a55, 0x1800519f },
+       { 11, 0x18402ecc, 0x184c079a, 0x18168a55, 0x1800518b },
+       { 12, 0x18402ecc, 0x184c079a, 0x18168a55, 0x1800519f },
+       { 13, 0x18402ecc, 0x184c079e, 0x18168a55, 0x1800518b },
+       { 14, 0x18402ecc, 0x184c07a2, 0x18168a55, 0x18005193 },
+
+       /* 802.11 UNI / HyperLan 2 */
+       { 36, 0x18402ecc, 0x184c099a, 0x18158a55, 0x180ed1a3 },
+       { 38, 0x18402ecc, 0x184c099e, 0x18158a55, 0x180ed193 },
+       { 40, 0x18402ec8, 0x184c0682, 0x18158a55, 0x180ed183 },
+       { 44, 0x18402ec8, 0x184c0682, 0x18158a55, 0x180ed1a3 },
+       { 46, 0x18402ec8, 0x184c0686, 0x18158a55, 0x180ed18b },
+       { 48, 0x18402ec8, 0x184c0686, 0x18158a55, 0x180ed19b },
+       { 52, 0x18402ec8, 0x184c068a, 0x18158a55, 0x180ed193 },
+       { 54, 0x18402ec8, 0x184c068a, 0x18158a55, 0x180ed1a3 },
+       { 56, 0x18402ec8, 0x184c068e, 0x18158a55, 0x180ed18b },
+       { 60, 0x18402ec8, 0x184c0692, 0x18158a55, 0x180ed183 },
+       { 62, 0x18402ec8, 0x184c0692, 0x18158a55, 0x180ed193 },
+       { 64, 0x18402ec8, 0x184c0692, 0x18158a55, 0x180ed1a3 },
+
+       /* 802.11 HyperLan 2 */
+       { 100, 0x18402ec8, 0x184c06b2, 0x18178a55, 0x180ed783 },
+       { 102, 0x18402ec8, 0x184c06b2, 0x18578a55, 0x180ed793 },
+       { 104, 0x18402ec8, 0x185c06b2, 0x18578a55, 0x180ed1a3 },
+       { 108, 0x18402ecc, 0x185c0a32, 0x18578a55, 0x180ed193 },
+       { 110, 0x18402ecc, 0x184c0a36, 0x18178a55, 0x180ed183 },
+       { 112, 0x18402ecc, 0x184c0a36, 0x18178a55, 0x180ed19b },
+       { 116, 0x18402ecc, 0x184c0a3a, 0x18178a55, 0x180ed1a3 },
+       { 118, 0x18402ecc, 0x184c0a3e, 0x18178a55, 0x180ed193 },
+       { 120, 0x18402ec4, 0x184c0382, 0x18178a55, 0x180ed183 },
+       { 124, 0x18402ec4, 0x184c0382, 0x18178a55, 0x180ed193 },
+       { 126, 0x18402ec4, 0x184c0382, 0x18178a55, 0x180ed15b },
+       { 128, 0x18402ec4, 0x184c0382, 0x18178a55, 0x180ed1a3 },
+       { 132, 0x18402ec4, 0x184c0386, 0x18178a55, 0x180ed18b },
+       { 134, 0x18402ec4, 0x184c0386, 0x18178a55, 0x180ed193 },
+       { 136, 0x18402ec4, 0x184c0386, 0x18178a55, 0x180ed19b },
+       { 140, 0x18402ec4, 0x184c038a, 0x18178a55, 0x180ed183 },
+
+       /* 802.11 UNII */
+       { 149, 0x18402ec4, 0x184c038a, 0x18178a55, 0x180ed1a7 },
+       { 151, 0x18402ec4, 0x184c038e, 0x18178a55, 0x180ed187 },
+       { 153, 0x18402ec4, 0x184c038e, 0x18178a55, 0x180ed18f },
+       { 157, 0x18402ec4, 0x184c038e, 0x18178a55, 0x180ed19f },
+       { 159, 0x18402ec4, 0x184c038e, 0x18178a55, 0x180ed1a7 },
+       { 161, 0x18402ec4, 0x184c0392, 0x18178a55, 0x180ed187 },
+       { 165, 0x18402ec4, 0x184c0392, 0x18178a55, 0x180ed197 },
+       { 167, 0x18402ec4, 0x184c03d2, 0x18179855, 0x1815531f },
+       { 169, 0x18402ec4, 0x184c03d2, 0x18179855, 0x18155327 },
+       { 171, 0x18402ec4, 0x184c03d6, 0x18179855, 0x18155307 },
+       { 173, 0x18402ec4, 0x184c03d6, 0x18179855, 0x1815530f },
+
+       /* 802.11 Japan */
+       { 184, 0x15002ccc, 0x1500491e, 0x1509be55, 0x150c0a0b },
+       { 188, 0x15002ccc, 0x15004922, 0x1509be55, 0x150c0a13 },
+       { 192, 0x15002ccc, 0x15004926, 0x1509be55, 0x150c0a1b },
+       { 196, 0x15002ccc, 0x1500492a, 0x1509be55, 0x150c0a23 },
+       { 208, 0x15002ccc, 0x1500493a, 0x1509be55, 0x150c0a13 },
+       { 212, 0x15002ccc, 0x1500493e, 0x1509be55, 0x150c0a1b },
+       { 216, 0x15002ccc, 0x15004982, 0x1509be55, 0x150c0a23 },
+};
+
+/*
+ * RF value list for rt3070
+ * Supports: 2.4 GHz
+ */
+static const struct rf_channel rf_vals_3070[] = {
+       {1,  241, 2, 2 },
+       {2,  241, 2, 7 },
+       {3,  242, 2, 2 },
+       {4,  242, 2, 7 },
+       {5,  243, 2, 2 },
+       {6,  243, 2, 7 },
+       {7,  244, 2, 2 },
+       {8,  244, 2, 7 },
+       {9,  245, 2, 2 },
+       {10, 245, 2, 7 },
+       {11, 246, 2, 2 },
+       {12, 246, 2, 7 },
+       {13, 247, 2, 2 },
+       {14, 248, 2, 4 },
+};
+
+static int rt2800usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
+{
+       struct hw_mode_spec *spec = &rt2x00dev->spec;
+       struct channel_info *info;
+       char *tx_power1;
+       char *tx_power2;
+       unsigned int i;
+       u16 eeprom;
+
+       /*
+        * Initialize all hw fields.
+        */
+       rt2x00dev->hw->flags =
+           IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
+           IEEE80211_HW_SIGNAL_DBM |
+           IEEE80211_HW_SUPPORTS_PS |
+           IEEE80211_HW_PS_NULLFUNC_STACK;
+       rt2x00dev->hw->extra_tx_headroom = TXINFO_DESC_SIZE + TXWI_DESC_SIZE;
+
+       SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev);
+       SET_IEEE80211_PERM_ADDR(rt2x00dev->hw,
+                               rt2x00_eeprom_addr(rt2x00dev,
+                                                  EEPROM_MAC_ADDR_0));
+
+       rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &eeprom);
+
+       /*
+        * Initialize HT information.
+        */
+       spec->ht.ht_supported = true;
+       spec->ht.cap =
+           IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
+           IEEE80211_HT_CAP_GRN_FLD |
+           IEEE80211_HT_CAP_SGI_20 |
+           IEEE80211_HT_CAP_SGI_40 |
+           IEEE80211_HT_CAP_TX_STBC |
+           IEEE80211_HT_CAP_RX_STBC |
+           IEEE80211_HT_CAP_PSMP_SUPPORT;
+       spec->ht.ampdu_factor = 3;
+       spec->ht.ampdu_density = 4;
+       spec->ht.mcs.tx_params =
+           IEEE80211_HT_MCS_TX_DEFINED |
+           IEEE80211_HT_MCS_TX_RX_DIFF |
+           ((rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TXPATH) - 1) <<
+               IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT);
+
+       switch (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RXPATH)) {
+       case 3:
+               spec->ht.mcs.rx_mask[2] = 0xff;
+       case 2:
+               spec->ht.mcs.rx_mask[1] = 0xff;
+       case 1:
+               spec->ht.mcs.rx_mask[0] = 0xff;
+               spec->ht.mcs.rx_mask[4] = 0x1; /* MCS32 */
+               break;
+       }
+
+       /*
+        * Initialize hw_mode information.
+        */
+       spec->supported_bands = SUPPORT_BAND_2GHZ;
+       spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM;
+
+       if (rt2x00_rf(&rt2x00dev->chip, RF2820) ||
+           rt2x00_rf(&rt2x00dev->chip, RF2720)) {
+               spec->num_channels = 14;
+               spec->channels = rf_vals;
+       } else if (rt2x00_rf(&rt2x00dev->chip, RF2850) ||
+                  rt2x00_rf(&rt2x00dev->chip, RF2750)) {
+               spec->supported_bands |= SUPPORT_BAND_5GHZ;
+               spec->num_channels = ARRAY_SIZE(rf_vals);
+               spec->channels = rf_vals;
+       } else if (rt2x00_rf(&rt2x00dev->chip, RF3020) ||
+                  rt2x00_rf(&rt2x00dev->chip, RF2020)) {
+               spec->num_channels = ARRAY_SIZE(rf_vals_3070);
+               spec->channels = rf_vals_3070;
+       }
+
+       /*
+        * Create channel information array
+        */
+       info = kzalloc(spec->num_channels * sizeof(*info), GFP_KERNEL);
+       if (!info)
+               return -ENOMEM;
+
+       spec->channels_info = info;
+
+       tx_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG1);
+       tx_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_BG2);
+
+       for (i = 0; i < 14; i++) {
+               info[i].tx_power1 = TXPOWER_G_FROM_DEV(tx_power1[i]);
+               info[i].tx_power2 = TXPOWER_G_FROM_DEV(tx_power2[i]);
+       }
+
+       if (spec->num_channels > 14) {
+               tx_power1 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A1);
+               tx_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A2);
+
+               for (i = 14; i < spec->num_channels; i++) {
+                       info[i].tx_power1 = TXPOWER_A_FROM_DEV(tx_power1[i]);
+                       info[i].tx_power2 = TXPOWER_A_FROM_DEV(tx_power2[i]);
+               }
+       }
+
+       return 0;
+}
+
+static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev)
+{
+       int retval;
+
+       /*
+        * Allocate eeprom data.
+        */
+       retval = rt2800usb_validate_eeprom(rt2x00dev);
+       if (retval)
+               return retval;
+
+       retval = rt2800usb_init_eeprom(rt2x00dev);
+       if (retval)
+               return retval;
+
+       /*
+        * Initialize hw specifications.
+        */
+       retval = rt2800usb_probe_hw_mode(rt2x00dev);
+       if (retval)
+               return retval;
+
+       /*
+        * This device requires firmware.
+        */
+       __set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags);
+       __set_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags);
+       __set_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags);
+       if (!modparam_nohwcrypt)
+               __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags);
+
+       /*
+        * Set the rssi offset.
+        */
+       rt2x00dev->rssi_offset = DEFAULT_RSSI_OFFSET;
+
+       return 0;
+}
+
+/*
+ * IEEE80211 stack callback functions.
+ */
+static void rt2800usb_get_tkip_seq(struct ieee80211_hw *hw, u8 hw_key_idx,
+                                  u32 *iv32, u16 *iv16)
+{
+       struct rt2x00_dev *rt2x00dev = hw->priv;
+       struct mac_iveiv_entry iveiv_entry;
+       u32 offset;
+
+       offset = MAC_IVEIV_ENTRY(hw_key_idx);
+       rt2x00usb_register_multiread(rt2x00dev, offset,
+                                     &iveiv_entry, sizeof(iveiv_entry));
+
+       memcpy(&iveiv_entry.iv[0], iv16, sizeof(iv16));
+       memcpy(&iveiv_entry.iv[4], iv32, sizeof(iv32));
+}
+
+static int rt2800usb_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
+{
+       struct rt2x00_dev *rt2x00dev = hw->priv;
+       u32 reg;
+       bool enabled = (value < IEEE80211_MAX_RTS_THRESHOLD);
+
+       rt2x00usb_register_read(rt2x00dev, TX_RTS_CFG, &reg);
+       rt2x00_set_field32(&reg, TX_RTS_CFG_RTS_THRES, value);
+       rt2x00usb_register_write(rt2x00dev, TX_RTS_CFG, reg);
+
+       rt2x00usb_register_read(rt2x00dev, CCK_PROT_CFG, &reg);
+       rt2x00_set_field32(&reg, CCK_PROT_CFG_RTS_TH_EN, enabled);
+       rt2x00usb_register_write(rt2x00dev, CCK_PROT_CFG, reg);
+
+       rt2x00usb_register_read(rt2x00dev, OFDM_PROT_CFG, &reg);
+       rt2x00_set_field32(&reg, OFDM_PROT_CFG_RTS_TH_EN, enabled);
+       rt2x00usb_register_write(rt2x00dev, OFDM_PROT_CFG, reg);
+
+       rt2x00usb_register_read(rt2x00dev, MM20_PROT_CFG, &reg);
+       rt2x00_set_field32(&reg, MM20_PROT_CFG_RTS_TH_EN, enabled);
+       rt2x00usb_register_write(rt2x00dev, MM20_PROT_CFG, reg);
+
+       rt2x00usb_register_read(rt2x00dev, MM40_PROT_CFG, &reg);
+       rt2x00_set_field32(&reg, MM40_PROT_CFG_RTS_TH_EN, enabled);
+       rt2x00usb_register_write(rt2x00dev, MM40_PROT_CFG, reg);
+
+       rt2x00usb_register_read(rt2x00dev, GF20_PROT_CFG, &reg);
+       rt2x00_set_field32(&reg, GF20_PROT_CFG_RTS_TH_EN, enabled);
+       rt2x00usb_register_write(rt2x00dev, GF20_PROT_CFG, reg);
+
+       rt2x00usb_register_read(rt2x00dev, GF40_PROT_CFG, &reg);
+       rt2x00_set_field32(&reg, GF40_PROT_CFG_RTS_TH_EN, enabled);
+       rt2x00usb_register_write(rt2x00dev, GF40_PROT_CFG, reg);
+
+       return 0;
+}
+
+static int rt2800usb_conf_tx(struct ieee80211_hw *hw, u16 queue_idx,
+                            const struct ieee80211_tx_queue_params *params)
+{
+       struct rt2x00_dev *rt2x00dev = hw->priv;
+       struct data_queue *queue;
+       struct rt2x00_field32 field;
+       int retval;
+       u32 reg;
+       u32 offset;
+
+       /*
+        * First pass the configuration through rt2x00lib, that will
+        * update the queue settings and validate the input. After that
+        * we are free to update the registers based on the value
+        * in the queue parameter.
+        */
+       retval = rt2x00mac_conf_tx(hw, queue_idx, params);
+       if (retval)
+               return retval;
+
+       /*
+        * We only need to perform additional register initialization
+        * for WMM queues/
+        */
+       if (queue_idx >= 4)
+               return 0;
+
+       queue = rt2x00queue_get_queue(rt2x00dev, queue_idx);
+
+       /* Update WMM TXOP register */
+       offset = WMM_TXOP0_CFG + (sizeof(u32) * (!!(queue_idx & 2)));
+       field.bit_offset = (queue_idx & 1) * 16;
+       field.bit_mask = 0xffff << field.bit_offset;
+
+       rt2x00usb_register_read(rt2x00dev, offset, &reg);
+       rt2x00_set_field32(&reg, field, queue->txop);
+       rt2x00usb_register_write(rt2x00dev, offset, reg);
+
+       /* Update WMM registers */
+       field.bit_offset = queue_idx * 4;
+       field.bit_mask = 0xf << field.bit_offset;
+
+       rt2x00usb_register_read(rt2x00dev, WMM_AIFSN_CFG, &reg);
+       rt2x00_set_field32(&reg, field, queue->aifs);
+       rt2x00usb_register_write(rt2x00dev, WMM_AIFSN_CFG, reg);
+
+       rt2x00usb_register_read(rt2x00dev, WMM_CWMIN_CFG, &reg);
+       rt2x00_set_field32(&reg, field, queue->cw_min);
+       rt2x00usb_register_write(rt2x00dev, WMM_CWMIN_CFG, reg);
+
+       rt2x00usb_register_read(rt2x00dev, WMM_CWMAX_CFG, &reg);
+       rt2x00_set_field32(&reg, field, queue->cw_max);
+       rt2x00usb_register_write(rt2x00dev, WMM_CWMAX_CFG, reg);
+
+       /* Update EDCA registers */
+       offset = EDCA_AC0_CFG + (sizeof(u32) * queue_idx);
+
+       rt2x00usb_register_read(rt2x00dev, offset, &reg);
+       rt2x00_set_field32(&reg, EDCA_AC0_CFG_TX_OP, queue->txop);
+       rt2x00_set_field32(&reg, EDCA_AC0_CFG_AIFSN, queue->aifs);
+       rt2x00_set_field32(&reg, EDCA_AC0_CFG_CWMIN, queue->cw_min);
+       rt2x00_set_field32(&reg, EDCA_AC0_CFG_CWMAX, queue->cw_max);
+       rt2x00usb_register_write(rt2x00dev, offset, reg);
+
+       return 0;
+}
+
+static u64 rt2800usb_get_tsf(struct ieee80211_hw *hw)
+{
+       struct rt2x00_dev *rt2x00dev = hw->priv;
+       u64 tsf;
+       u32 reg;
+
+       rt2x00usb_register_read(rt2x00dev, TSF_TIMER_DW1, &reg);
+       tsf = (u64) rt2x00_get_field32(reg, TSF_TIMER_DW1_HIGH_WORD) << 32;
+       rt2x00usb_register_read(rt2x00dev, TSF_TIMER_DW0, &reg);
+       tsf |= rt2x00_get_field32(reg, TSF_TIMER_DW0_LOW_WORD);
+
+       return tsf;
+}
+
+static const struct ieee80211_ops rt2800usb_mac80211_ops = {
+       .tx                     = rt2x00mac_tx,
+       .start                  = rt2x00mac_start,
+       .stop                   = rt2x00mac_stop,
+       .add_interface          = rt2x00mac_add_interface,
+       .remove_interface       = rt2x00mac_remove_interface,
+       .config                 = rt2x00mac_config,
+       .configure_filter       = rt2x00mac_configure_filter,
+       .set_key                = rt2x00mac_set_key,
+       .get_stats              = rt2x00mac_get_stats,
+       .get_tkip_seq           = rt2800usb_get_tkip_seq,
+       .set_rts_threshold      = rt2800usb_set_rts_threshold,
+       .bss_info_changed       = rt2x00mac_bss_info_changed,
+       .conf_tx                = rt2800usb_conf_tx,
+       .get_tx_stats           = rt2x00mac_get_tx_stats,
+       .get_tsf                = rt2800usb_get_tsf,
+};
+
+static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = {
+       .probe_hw               = rt2800usb_probe_hw,
+       .get_firmware_name      = rt2800usb_get_firmware_name,
+       .check_firmware         = rt2800usb_check_firmware,
+       .load_firmware          = rt2800usb_load_firmware,
+       .initialize             = rt2x00usb_initialize,
+       .uninitialize           = rt2x00usb_uninitialize,
+       .clear_entry            = rt2x00usb_clear_entry,
+       .set_device_state       = rt2800usb_set_device_state,
+       .rfkill_poll            = rt2800usb_rfkill_poll,
+       .link_stats             = rt2800usb_link_stats,
+       .reset_tuner            = rt2800usb_reset_tuner,
+       .link_tuner             = rt2800usb_link_tuner,
+       .write_tx_desc          = rt2800usb_write_tx_desc,
+       .write_tx_data          = rt2x00usb_write_tx_data,
+       .write_beacon           = rt2800usb_write_beacon,
+       .get_tx_data_len        = rt2800usb_get_tx_data_len,
+       .kick_tx_queue          = rt2800usb_kick_tx_queue,
+       .kill_tx_queue          = rt2x00usb_kill_tx_queue,
+       .fill_rxdone            = rt2800usb_fill_rxdone,
+       .config_shared_key      = rt2800usb_config_shared_key,
+       .config_pairwise_key    = rt2800usb_config_pairwise_key,
+       .config_filter          = rt2800usb_config_filter,
+       .config_intf            = rt2800usb_config_intf,
+       .config_erp             = rt2800usb_config_erp,
+       .config_ant             = rt2800usb_config_ant,
+       .config                 = rt2800usb_config,
+};
+
+static const struct data_queue_desc rt2800usb_queue_rx = {
+       .entry_num              = RX_ENTRIES,
+       .data_size              = AGGREGATION_SIZE,
+       .desc_size              = RXD_DESC_SIZE + RXWI_DESC_SIZE,
+       .priv_size              = sizeof(struct queue_entry_priv_usb),
+};
+
+static const struct data_queue_desc rt2800usb_queue_tx = {
+       .entry_num              = TX_ENTRIES,
+       .data_size              = AGGREGATION_SIZE,
+       .desc_size              = TXINFO_DESC_SIZE + TXWI_DESC_SIZE,
+       .priv_size              = sizeof(struct queue_entry_priv_usb),
+};
+
+static const struct data_queue_desc rt2800usb_queue_bcn = {
+       .entry_num              = 8 * BEACON_ENTRIES,
+       .data_size              = MGMT_FRAME_SIZE,
+       .desc_size              = TXINFO_DESC_SIZE + TXWI_DESC_SIZE,
+       .priv_size              = sizeof(struct queue_entry_priv_usb),
+};
+
+static const struct rt2x00_ops rt2800usb_ops = {
+       .name           = KBUILD_MODNAME,
+       .max_sta_intf   = 1,
+       .max_ap_intf    = 8,
+       .eeprom_size    = EEPROM_SIZE,
+       .rf_size        = RF_SIZE,
+       .tx_queues      = NUM_TX_QUEUES,
+       .rx             = &rt2800usb_queue_rx,
+       .tx             = &rt2800usb_queue_tx,
+       .bcn            = &rt2800usb_queue_bcn,
+       .lib            = &rt2800usb_rt2x00_ops,
+       .hw             = &rt2800usb_mac80211_ops,
+#ifdef CONFIG_RT2X00_LIB_DEBUGFS
+       .debugfs        = &rt2800usb_rt2x00debug,
+#endif /* CONFIG_RT2X00_LIB_DEBUGFS */
+};
+
+/*
+ * rt2800usb module information.
+ */
+static struct usb_device_id rt2800usb_device_table[] = {
+       /* Abocom */
+       { USB_DEVICE(0x07b8, 0x2870), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x07b8, 0x2770), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x07b8, 0x3070), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x07b8, 0x3071), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x07b8, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x1482, 0x3c09), USB_DEVICE_DATA(&rt2800usb_ops) },
+       /* AirTies */
+       { USB_DEVICE(0x1eda, 0x2310), USB_DEVICE_DATA(&rt2800usb_ops) },
+       /* Amigo */
+       { USB_DEVICE(0x0e0b, 0x9031), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x0e0b, 0x9041), USB_DEVICE_DATA(&rt2800usb_ops) },
+       /* Amit */
+       { USB_DEVICE(0x15c5, 0x0008), USB_DEVICE_DATA(&rt2800usb_ops) },
+       /* ASUS */
+       { USB_DEVICE(0x0b05, 0x1731), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x0b05, 0x1732), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x0b05, 0x1742), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x0b05, 0x1760), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x0b05, 0x1761), USB_DEVICE_DATA(&rt2800usb_ops) },
+       /* AzureWave */
+       { USB_DEVICE(0x13d3, 0x3247), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x13d3, 0x3262), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x13d3, 0x3273), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x13d3, 0x3284), USB_DEVICE_DATA(&rt2800usb_ops) },
+       /* Belkin */
+       { USB_DEVICE(0x050d, 0x8053), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x050d, 0x805c), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x050d, 0x815c), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x050d, 0x825a), USB_DEVICE_DATA(&rt2800usb_ops) },
+       /* Buffalo */
+       { USB_DEVICE(0x0411, 0x00e8), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x0411, 0x012e), USB_DEVICE_DATA(&rt2800usb_ops) },
+       /* Conceptronic */
+       { USB_DEVICE(0x14b2, 0x3c06), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x14b2, 0x3c07), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x14b2, 0x3c08), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x14b2, 0x3c09), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x14b2, 0x3c11), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x14b2, 0x3c12), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x14b2, 0x3c23), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x14b2, 0x3c25), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x14b2, 0x3c27), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x14b2, 0x3c28), USB_DEVICE_DATA(&rt2800usb_ops) },
+       /* Corega */
+       { USB_DEVICE(0x07aa, 0x002f), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x07aa, 0x003c), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x07aa, 0x003f), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x18c5, 0x0008), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x18c5, 0x0012), USB_DEVICE_DATA(&rt2800usb_ops) },
+       /* D-Link */
+       { USB_DEVICE(0x07d1, 0x3c09), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x07d1, 0x3c0a), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x07d1, 0x3c0b), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x07d1, 0x3c0d), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x07d1, 0x3c0e), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x07d1, 0x3c0f), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x07d1, 0x3c11), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x07d1, 0x3c13), USB_DEVICE_DATA(&rt2800usb_ops) },
+       /* Edimax */
+       { USB_DEVICE(0x7392, 0x7711), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x7392, 0x7717), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x7392, 0x7718), USB_DEVICE_DATA(&rt2800usb_ops) },
+       /* Encore */
+       { USB_DEVICE(0x203d, 0x1480), USB_DEVICE_DATA(&rt2800usb_ops) },
+       /* EnGenius */
+       { USB_DEVICE(0X1740, 0x9701), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x1740, 0x9702), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x1740, 0x9703), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x1740, 0x9705), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x1740, 0x9706), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x1740, 0x9801), USB_DEVICE_DATA(&rt2800usb_ops) },
+       /* Gemtek */
+       { USB_DEVICE(0x15a9, 0x0010), USB_DEVICE_DATA(&rt2800usb_ops) },
+       /* Gigabyte */
+       { USB_DEVICE(0x1044, 0x800b), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x1044, 0x800c), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x1044, 0x800d), USB_DEVICE_DATA(&rt2800usb_ops) },
+       /* Hawking */
+       { USB_DEVICE(0x0e66, 0x0001), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x0e66, 0x0003), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x0e66, 0x0009), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x0e66, 0x000b), USB_DEVICE_DATA(&rt2800usb_ops) },
+       /* I-O DATA */
+       { USB_DEVICE(0x04bb, 0x0945), USB_DEVICE_DATA(&rt2800usb_ops) },
+       /* LevelOne */
+       { USB_DEVICE(0x1740, 0x0605), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x1740, 0x0615), USB_DEVICE_DATA(&rt2800usb_ops) },
+       /* Linksys */
+       { USB_DEVICE(0x1737, 0x0070), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x1737, 0x0071), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x1737, 0x0077), USB_DEVICE_DATA(&rt2800usb_ops) },
+       /* Logitec */
+       { USB_DEVICE(0x0789, 0x0162), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x0789, 0x0163), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x0789, 0x0164), USB_DEVICE_DATA(&rt2800usb_ops) },
+       /* Motorola */
+       { USB_DEVICE(0x100d, 0x9031), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x100d, 0x9032), USB_DEVICE_DATA(&rt2800usb_ops) },
+       /* Ovislink */
+       { USB_DEVICE(0x1b75, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) },
+       /* Pegatron */
+       { USB_DEVICE(0x1d4d, 0x0002), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x1d4d, 0x000c), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x1d4d, 0x000e), USB_DEVICE_DATA(&rt2800usb_ops) },
+       /* Philips */
+       { USB_DEVICE(0x0471, 0x200f), USB_DEVICE_DATA(&rt2800usb_ops) },
+       /* Planex */
+       { USB_DEVICE(0x2019, 0xed06), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x2019, 0xab24), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x2019, 0xab25), USB_DEVICE_DATA(&rt2800usb_ops) },
+       /* Qcom */
+       { USB_DEVICE(0x18e8, 0x6259), USB_DEVICE_DATA(&rt2800usb_ops) },
+       /* Quanta */
+       { USB_DEVICE(0x1a32, 0x0304), USB_DEVICE_DATA(&rt2800usb_ops) },
+       /* Ralink */
+       { USB_DEVICE(0x0db0, 0x3820), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x0db0, 0x6899), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x148f, 0x2070), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x148f, 0x2770), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x148f, 0x2870), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x148f, 0x3070), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x148f, 0x3071), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x148f, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x148f, 0x3572), USB_DEVICE_DATA(&rt2800usb_ops) },
+       /* Samsung */
+       { USB_DEVICE(0x04e8, 0x2018), USB_DEVICE_DATA(&rt2800usb_ops) },
+       /* Siemens */
+       { USB_DEVICE(0x129b, 0x1828), USB_DEVICE_DATA(&rt2800usb_ops) },
+       /* Sitecom */
+       { USB_DEVICE(0x0df6, 0x0017), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x0df6, 0x002b), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x0df6, 0x002c), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x0df6, 0x002d), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x0df6, 0x0039), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x0df6, 0x003b), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x0df6, 0x003c), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x0df6, 0x003d), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x0df6, 0x003e), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x0df6, 0x003f), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x0df6, 0x0040), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x0df6, 0x0042), USB_DEVICE_DATA(&rt2800usb_ops) },
+       /* SMC */
+       { USB_DEVICE(0x083a, 0x6618), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x083a, 0x7511), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x083a, 0x7512), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x083a, 0x7522), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x083a, 0x8522), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x083a, 0xa512), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x083a, 0xa618), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x083a, 0xb522), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x083a, 0xc522), USB_DEVICE_DATA(&rt2800usb_ops) },
+       /* Sparklan */
+       { USB_DEVICE(0x15a9, 0x0006), USB_DEVICE_DATA(&rt2800usb_ops) },
+       /* Sweex */
+       { USB_DEVICE(0x177f, 0x0153), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x177f, 0x0302), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x177f, 0x0313), USB_DEVICE_DATA(&rt2800usb_ops) },
+       /* U-Media*/
+       { USB_DEVICE(0x157e, 0x300e), USB_DEVICE_DATA(&rt2800usb_ops) },
+       /* ZCOM */
+       { USB_DEVICE(0x0cde, 0x0022), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x0cde, 0x0025), USB_DEVICE_DATA(&rt2800usb_ops) },
+       /* Zinwell */
+       { USB_DEVICE(0x5a57, 0x0280), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x5a57, 0x0282), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x5a57, 0x0283), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x5a57, 0x5257), USB_DEVICE_DATA(&rt2800usb_ops) },
+       /* Zyxel */
+       { USB_DEVICE(0x0586, 0x3416), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { USB_DEVICE(0x0586, 0x341a), USB_DEVICE_DATA(&rt2800usb_ops) },
+       { 0, }
+};
+
+MODULE_AUTHOR(DRV_PROJECT);
+MODULE_VERSION(DRV_VERSION);
+MODULE_DESCRIPTION("Ralink RT2800 USB Wireless LAN driver.");
+MODULE_SUPPORTED_DEVICE("Ralink RT2870 USB chipset based cards");
+MODULE_DEVICE_TABLE(usb, rt2800usb_device_table);
+MODULE_FIRMWARE(FIRMWARE_RT2870);
+MODULE_LICENSE("GPL");
+
+static struct usb_driver rt2800usb_driver = {
+       .name           = KBUILD_MODNAME,
+       .id_table       = rt2800usb_device_table,
+       .probe          = rt2x00usb_probe,
+       .disconnect     = rt2x00usb_disconnect,
+       .suspend        = rt2x00usb_suspend,
+       .resume         = rt2x00usb_resume,
+};
+
+static int __init rt2800usb_init(void)
+{
+       return usb_register(&rt2800usb_driver);
+}
+
+static void __exit rt2800usb_exit(void)
+{
+       usb_deregister(&rt2800usb_driver);
+}
+
+module_init(rt2800usb_init);
+module_exit(rt2800usb_exit);
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.h b/drivers/net/wireless/rt2x00/rt2800usb.h
new file mode 100644 (file)
index 0000000..61a8be6
--- /dev/null
@@ -0,0 +1,1945 @@
+/*
+       Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
+       <http://rt2x00.serialmonkey.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.
+
+       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.
+ */
+
+/*
+       Module: rt2800usb
+       Abstract: Data structures and registers for the rt2800usb module.
+       Supported chipsets: RT2800U.
+ */
+
+#ifndef RT2800USB_H
+#define RT2800USB_H
+
+/*
+ * RF chip defines.
+ *
+ * RF2820 2.4G 2T3R
+ * RF2850 2.4G/5G 2T3R
+ * RF2720 2.4G 1T2R
+ * RF2750 2.4G/5G 1T2R
+ * RF3020 2.4G 1T1R
+ * RF2020 2.4G B/G
+ */
+#define RF2820                         0x0001
+#define RF2850                         0x0002
+#define RF2720                         0x0003
+#define RF2750                         0x0004
+#define RF3020                         0x0005
+#define RF2020                         0x0006
+
+/*
+ * RT2870 version
+ */
+#define RT2860C_VERSION                        0x28600100
+#define RT2860D_VERSION                        0x28600101
+#define RT2880E_VERSION                        0x28720200
+#define RT2883_VERSION                 0x28830300
+#define RT3070_VERSION                 0x30700200
+
+/*
+ * Signal information.
+ * Defaul offset is required for RSSI <-> dBm conversion.
+ */
+#define DEFAULT_RSSI_OFFSET            120 /* FIXME */
+
+/*
+ * Register layout information.
+ */
+#define CSR_REG_BASE                   0x1000
+#define CSR_REG_SIZE                   0x0800
+#define EEPROM_BASE                    0x0000
+#define EEPROM_SIZE                    0x0110
+#define BBP_BASE                       0x0000
+#define BBP_SIZE                       0x0080
+#define RF_BASE                                0x0004
+#define RF_SIZE                                0x0010
+
+/*
+ * Number of TX queues.
+ */
+#define NUM_TX_QUEUES                  4
+
+/*
+ * USB registers.
+ */
+
+/*
+ * HOST-MCU shared memory
+ */
+#define HOST_CMD_CSR                   0x0404
+#define HOST_CMD_CSR_HOST_COMMAND      FIELD32(0x000000ff)
+
+/*
+ * INT_SOURCE_CSR: Interrupt source register.
+ * Write one to clear corresponding bit.
+ * TX_FIFO_STATUS: FIFO Statistics is full, sw should read 0x171c
+ */
+#define INT_SOURCE_CSR                 0x0200
+#define INT_SOURCE_CSR_RXDELAYINT      FIELD32(0x00000001)
+#define INT_SOURCE_CSR_TXDELAYINT      FIELD32(0x00000002)
+#define INT_SOURCE_CSR_RX_DONE         FIELD32(0x00000004)
+#define INT_SOURCE_CSR_AC0_DMA_DONE    FIELD32(0x00000008)
+#define INT_SOURCE_CSR_AC1_DMA_DONE    FIELD32(0x00000010)
+#define INT_SOURCE_CSR_AC2_DMA_DONE    FIELD32(0x00000020)
+#define INT_SOURCE_CSR_AC3_DMA_DONE    FIELD32(0x00000040)
+#define INT_SOURCE_CSR_HCCA_DMA_DONE   FIELD32(0x00000080)
+#define INT_SOURCE_CSR_MGMT_DMA_DONE   FIELD32(0x00000100)
+#define INT_SOURCE_CSR_MCU_COMMAND     FIELD32(0x00000200)
+#define INT_SOURCE_CSR_RXTX_COHERENT   FIELD32(0x00000400)
+#define INT_SOURCE_CSR_TBTT            FIELD32(0x00000800)
+#define INT_SOURCE_CSR_PRE_TBTT                FIELD32(0x00001000)
+#define INT_SOURCE_CSR_TX_FIFO_STATUS  FIELD32(0x00002000)
+#define INT_SOURCE_CSR_AUTO_WAKEUP     FIELD32(0x00004000)
+#define INT_SOURCE_CSR_GPTIMER         FIELD32(0x00008000)
+#define INT_SOURCE_CSR_RX_COHERENT     FIELD32(0x00010000)
+#define INT_SOURCE_CSR_TX_COHERENT     FIELD32(0x00020000)
+
+/*
+ * INT_MASK_CSR: Interrupt MASK register. 1: the interrupt is mask OFF.
+ */
+#define INT_MASK_CSR                   0x0204
+#define INT_MASK_CSR_RXDELAYINT                FIELD32(0x00000001)
+#define INT_MASK_CSR_TXDELAYINT                FIELD32(0x00000002)
+#define INT_MASK_CSR_RX_DONE           FIELD32(0x00000004)
+#define INT_MASK_CSR_AC0_DMA_DONE      FIELD32(0x00000008)
+#define INT_MASK_CSR_AC1_DMA_DONE      FIELD32(0x00000010)
+#define INT_MASK_CSR_AC2_DMA_DONE      FIELD32(0x00000020)
+#define INT_MASK_CSR_AC3_DMA_DONE      FIELD32(0x00000040)
+#define INT_MASK_CSR_HCCA_DMA_DONE     FIELD32(0x00000080)
+#define INT_MASK_CSR_MGMT_DMA_DONE     FIELD32(0x00000100)
+#define INT_MASK_CSR_MCU_COMMAND       FIELD32(0x00000200)
+#define INT_MASK_CSR_RXTX_COHERENT     FIELD32(0x00000400)
+#define INT_MASK_CSR_TBTT              FIELD32(0x00000800)
+#define INT_MASK_CSR_PRE_TBTT          FIELD32(0x00001000)
+#define INT_MASK_CSR_TX_FIFO_STATUS    FIELD32(0x00002000)
+#define INT_MASK_CSR_AUTO_WAKEUP       FIELD32(0x00004000)
+#define INT_MASK_CSR_GPTIMER           FIELD32(0x00008000)
+#define INT_MASK_CSR_RX_COHERENT       FIELD32(0x00010000)
+#define INT_MASK_CSR_TX_COHERENT       FIELD32(0x00020000)
+
+/*
+ * WPDMA_GLO_CFG
+ */
+#define WPDMA_GLO_CFG                  0x0208
+#define WPDMA_GLO_CFG_ENABLE_TX_DMA    FIELD32(0x00000001)
+#define WPDMA_GLO_CFG_TX_DMA_BUSY      FIELD32(0x00000002)
+#define WPDMA_GLO_CFG_ENABLE_RX_DMA    FIELD32(0x00000004)
+#define WPDMA_GLO_CFG_RX_DMA_BUSY      FIELD32(0x00000008)
+#define WPDMA_GLO_CFG_WP_DMA_BURST_SIZE        FIELD32(0x00000030)
+#define WPDMA_GLO_CFG_TX_WRITEBACK_DONE        FIELD32(0x00000040)
+#define WPDMA_GLO_CFG_BIG_ENDIAN       FIELD32(0x00000080)
+#define WPDMA_GLO_CFG_RX_HDR_SCATTER   FIELD32(0x0000ff00)
+#define WPDMA_GLO_CFG_HDR_SEG_LEN      FIELD32(0xffff0000)
+
+/*
+ * WPDMA_RST_IDX
+ */
+#define WPDMA_RST_IDX                  0x020c
+#define WPDMA_RST_IDX_DTX_IDX0         FIELD32(0x00000001)
+#define WPDMA_RST_IDX_DTX_IDX1         FIELD32(0x00000002)
+#define WPDMA_RST_IDX_DTX_IDX2         FIELD32(0x00000004)
+#define WPDMA_RST_IDX_DTX_IDX3         FIELD32(0x00000008)
+#define WPDMA_RST_IDX_DTX_IDX4         FIELD32(0x00000010)
+#define WPDMA_RST_IDX_DTX_IDX5         FIELD32(0x00000020)
+#define WPDMA_RST_IDX_DRX_IDX0         FIELD32(0x00010000)
+
+/*
+ * DELAY_INT_CFG
+ */
+#define DELAY_INT_CFG                  0x0210
+#define DELAY_INT_CFG_RXMAX_PTIME      FIELD32(0x000000ff)
+#define DELAY_INT_CFG_RXMAX_PINT       FIELD32(0x00007f00)
+#define DELAY_INT_CFG_RXDLY_INT_EN     FIELD32(0x00008000)
+#define DELAY_INT_CFG_TXMAX_PTIME      FIELD32(0x00ff0000)
+#define DELAY_INT_CFG_TXMAX_PINT       FIELD32(0x7f000000)
+#define DELAY_INT_CFG_TXDLY_INT_EN     FIELD32(0x80000000)
+
+/*
+ * WMM_AIFSN_CFG: Aifsn for each EDCA AC
+ * AIFSN0: AC_BE
+ * AIFSN1: AC_BK
+ * AIFSN1: AC_VI
+ * AIFSN1: AC_VO
+ */
+#define WMM_AIFSN_CFG                  0x0214
+#define WMM_AIFSN_CFG_AIFSN0           FIELD32(0x0000000f)
+#define WMM_AIFSN_CFG_AIFSN1           FIELD32(0x000000f0)
+#define WMM_AIFSN_CFG_AIFSN2           FIELD32(0x00000f00)
+#define WMM_AIFSN_CFG_AIFSN3           FIELD32(0x0000f000)
+
+/*
+ * WMM_CWMIN_CSR: CWmin for each EDCA AC
+ * CWMIN0: AC_BE
+ * CWMIN1: AC_BK
+ * CWMIN1: AC_VI
+ * CWMIN1: AC_VO
+ */
+#define WMM_CWMIN_CFG                  0x0218
+#define WMM_CWMIN_CFG_CWMIN0           FIELD32(0x0000000f)
+#define WMM_CWMIN_CFG_CWMIN1           FIELD32(0x000000f0)
+#define WMM_CWMIN_CFG_CWMIN2           FIELD32(0x00000f00)
+#define WMM_CWMIN_CFG_CWMIN3           FIELD32(0x0000f000)
+
+/*
+ * WMM_CWMAX_CSR: CWmax for each EDCA AC
+ * CWMAX0: AC_BE
+ * CWMAX1: AC_BK
+ * CWMAX1: AC_VI
+ * CWMAX1: AC_VO
+ */
+#define WMM_CWMAX_CFG                  0x021c
+#define WMM_CWMAX_CFG_CWMAX0           FIELD32(0x0000000f)
+#define WMM_CWMAX_CFG_CWMAX1           FIELD32(0x000000f0)
+#define WMM_CWMAX_CFG_CWMAX2           FIELD32(0x00000f00)
+#define WMM_CWMAX_CFG_CWMAX3           FIELD32(0x0000f000)
+
+/*
+ * AC_TXOP0: AC_BK/AC_BE TXOP register
+ * AC0TXOP: AC_BK in unit of 32us
+ * AC1TXOP: AC_BE in unit of 32us
+ */
+#define WMM_TXOP0_CFG                  0x0220
+#define WMM_TXOP0_CFG_AC0TXOP          FIELD32(0x0000ffff)
+#define WMM_TXOP0_CFG_AC1TXOP          FIELD32(0xffff0000)
+
+/*
+ * AC_TXOP1: AC_VO/AC_VI TXOP register
+ * AC2TXOP: AC_VI in unit of 32us
+ * AC3TXOP: AC_VO in unit of 32us
+ */
+#define WMM_TXOP1_CFG                  0x0224
+#define WMM_TXOP1_CFG_AC2TXOP          FIELD32(0x0000ffff)
+#define WMM_TXOP1_CFG_AC3TXOP          FIELD32(0xffff0000)
+
+/*
+ * GPIO_CTRL_CFG:
+ */
+#define GPIO_CTRL_CFG                  0x0228
+#define GPIO_CTRL_CFG_BIT0             FIELD32(0x00000001)
+#define GPIO_CTRL_CFG_BIT1             FIELD32(0x00000002)
+#define GPIO_CTRL_CFG_BIT2             FIELD32(0x00000004)
+#define GPIO_CTRL_CFG_BIT3             FIELD32(0x00000008)
+#define GPIO_CTRL_CFG_BIT4             FIELD32(0x00000010)
+#define GPIO_CTRL_CFG_BIT5             FIELD32(0x00000020)
+#define GPIO_CTRL_CFG_BIT6             FIELD32(0x00000040)
+#define GPIO_CTRL_CFG_BIT7             FIELD32(0x00000080)
+#define GPIO_CTRL_CFG_BIT8             FIELD32(0x00000100)
+
+/*
+ * MCU_CMD_CFG
+ */
+#define MCU_CMD_CFG                    0x022c
+
+/*
+ * AC_BK register offsets
+ */
+#define TX_BASE_PTR0                   0x0230
+#define TX_MAX_CNT0                    0x0234
+#define TX_CTX_IDX0                    0x0238
+#define TX_DTX_IDX0                    0x023c
+
+/*
+ * AC_BE register offsets
+ */
+#define TX_BASE_PTR1                   0x0240
+#define TX_MAX_CNT1                    0x0244
+#define TX_CTX_IDX1                    0x0248
+#define TX_DTX_IDX1                    0x024c
+
+/*
+ * AC_VI register offsets
+ */
+#define TX_BASE_PTR2                   0x0250
+#define TX_MAX_CNT2                    0x0254
+#define TX_CTX_IDX2                    0x0258
+#define TX_DTX_IDX2                    0x025c
+
+/*
+ * AC_VO register offsets
+ */
+#define TX_BASE_PTR3                   0x0260
+#define TX_MAX_CNT3                    0x0264
+#define TX_CTX_IDX3                    0x0268
+#define TX_DTX_IDX3                    0x026c
+
+/*
+ * HCCA register offsets
+ */
+#define TX_BASE_PTR4                   0x0270
+#define TX_MAX_CNT4                    0x0274
+#define TX_CTX_IDX4                    0x0278
+#define TX_DTX_IDX4                    0x027c
+
+/*
+ * MGMT register offsets
+ */
+#define TX_BASE_PTR5                   0x0280
+#define TX_MAX_CNT5                    0x0284
+#define TX_CTX_IDX5                    0x0288
+#define TX_DTX_IDX5                    0x028c
+
+/*
+ * RX register offsets
+ */
+#define RX_BASE_PTR                    0x0290
+#define RX_MAX_CNT                     0x0294
+#define RX_CRX_IDX                     0x0298
+#define RX_DRX_IDX                     0x029c
+
+/*
+ * USB_DMA_CFG
+ * RX_BULK_AGG_TIMEOUT: Rx Bulk Aggregation TimeOut in unit of 33ns.
+ * RX_BULK_AGG_LIMIT: Rx Bulk Aggregation Limit in unit of 256 bytes.
+ * PHY_CLEAR: phy watch dog enable.
+ * TX_CLEAR: Clear USB DMA TX path.
+ * TXOP_HALT: Halt TXOP count down when TX buffer is full.
+ * RX_BULK_AGG_EN: Enable Rx Bulk Aggregation.
+ * RX_BULK_EN: Enable USB DMA Rx.
+ * TX_BULK_EN: Enable USB DMA Tx.
+ * EP_OUT_VALID: OUT endpoint data valid.
+ * RX_BUSY: USB DMA RX FSM busy.
+ * TX_BUSY: USB DMA TX FSM busy.
+ */
+#define USB_DMA_CFG                    0x02a0
+#define USB_DMA_CFG_RX_BULK_AGG_TIMEOUT        FIELD32(0x000000ff)
+#define USB_DMA_CFG_RX_BULK_AGG_LIMIT  FIELD32(0x0000ff00)
+#define USB_DMA_CFG_PHY_CLEAR          FIELD32(0x00010000)
+#define USB_DMA_CFG_TX_CLEAR           FIELD32(0x00080000)
+#define USB_DMA_CFG_TXOP_HALT          FIELD32(0x00100000)
+#define USB_DMA_CFG_RX_BULK_AGG_EN     FIELD32(0x00200000)
+#define USB_DMA_CFG_RX_BULK_EN         FIELD32(0x00400000)
+#define USB_DMA_CFG_TX_BULK_EN         FIELD32(0x00800000)
+#define USB_DMA_CFG_EP_OUT_VALID       FIELD32(0x3f000000)
+#define USB_DMA_CFG_RX_BUSY            FIELD32(0x40000000)
+#define USB_DMA_CFG_TX_BUSY            FIELD32(0x80000000)
+
+/*
+ * USB_CYC_CFG
+ */
+#define USB_CYC_CFG                    0x02a4
+#define USB_CYC_CFG_CLOCK_CYCLE                FIELD32(0x000000ff)
+
+/*
+ * PBF_SYS_CTRL
+ * HOST_RAM_WRITE: enable Host program ram write selection
+ */
+#define PBF_SYS_CTRL                   0x0400
+#define PBF_SYS_CTRL_READY             FIELD32(0x00000080)
+#define PBF_SYS_CTRL_HOST_RAM_WRITE    FIELD32(0x00010000)
+
+/*
+ * PBF registers
+ * Most are for debug. Driver doesn't touch PBF register.
+ */
+#define PBF_CFG                                0x0408
+#define PBF_MAX_PCNT                   0x040c
+#define PBF_CTRL                       0x0410
+#define PBF_INT_STA                    0x0414
+#define PBF_INT_ENA                    0x0418
+
+/*
+ * BCN_OFFSET0:
+ */
+#define BCN_OFFSET0                    0x042c
+#define BCN_OFFSET0_BCN0               FIELD32(0x000000ff)
+#define BCN_OFFSET0_BCN1               FIELD32(0x0000ff00)
+#define BCN_OFFSET0_BCN2               FIELD32(0x00ff0000)
+#define BCN_OFFSET0_BCN3               FIELD32(0xff000000)
+
+/*
+ * BCN_OFFSET1:
+ */
+#define BCN_OFFSET1                    0x0430
+#define BCN_OFFSET1_BCN4               FIELD32(0x000000ff)
+#define BCN_OFFSET1_BCN5               FIELD32(0x0000ff00)
+#define BCN_OFFSET1_BCN6               FIELD32(0x00ff0000)
+#define BCN_OFFSET1_BCN7               FIELD32(0xff000000)
+
+/*
+ * PBF registers
+ * Most are for debug. Driver doesn't touch PBF register.
+ */
+#define TXRXQ_PCNT                     0x0438
+#define PBF_DBG                                0x043c
+
+/*
+ * RF registers
+ */
+#define        RF_CSR_CFG                      0x0500
+#define RF_CSR_CFG_DATA                        FIELD32(0x000000ff)
+#define RF_CSR_CFG_REGNUM              FIELD32(0x00001f00)
+#define RF_CSR_CFG_WRITE               FIELD32(0x00010000)
+#define RF_CSR_CFG_BUSY                        FIELD32(0x00020000)
+
+/*
+ * MAC Control/Status Registers(CSR).
+ * Some values are set in TU, whereas 1 TU == 1024 us.
+ */
+
+/*
+ * MAC_CSR0: ASIC revision number.
+ * ASIC_REV: 0
+ * ASIC_VER: 2870
+ */
+#define MAC_CSR0                       0x1000
+#define MAC_CSR0_ASIC_REV              FIELD32(0x0000ffff)
+#define MAC_CSR0_ASIC_VER              FIELD32(0xffff0000)
+
+/*
+ * MAC_SYS_CTRL:
+ */
+#define MAC_SYS_CTRL                   0x1004
+#define MAC_SYS_CTRL_RESET_CSR         FIELD32(0x00000001)
+#define MAC_SYS_CTRL_RESET_BBP         FIELD32(0x00000002)
+#define MAC_SYS_CTRL_ENABLE_TX         FIELD32(0x00000004)
+#define MAC_SYS_CTRL_ENABLE_RX         FIELD32(0x00000008)
+#define MAC_SYS_CTRL_CONTINUOUS_TX     FIELD32(0x00000010)
+#define MAC_SYS_CTRL_LOOPBACK          FIELD32(0x00000020)
+#define MAC_SYS_CTRL_WLAN_HALT         FIELD32(0x00000040)
+#define MAC_SYS_CTRL_RX_TIMESTAMP      FIELD32(0x00000080)
+
+/*
+ * MAC_ADDR_DW0: STA MAC register 0
+ */
+#define MAC_ADDR_DW0                   0x1008
+#define MAC_ADDR_DW0_BYTE0             FIELD32(0x000000ff)
+#define MAC_ADDR_DW0_BYTE1             FIELD32(0x0000ff00)
+#define MAC_ADDR_DW0_BYTE2             FIELD32(0x00ff0000)
+#define MAC_ADDR_DW0_BYTE3             FIELD32(0xff000000)
+
+/*
+ * MAC_ADDR_DW1: STA MAC register 1
+ * UNICAST_TO_ME_MASK:
+ * Used to mask off bits from byte 5 of the MAC address
+ * to determine the UNICAST_TO_ME bit for RX frames.
+ * The full mask is complemented by BSS_ID_MASK:
+ *    MASK = BSS_ID_MASK & UNICAST_TO_ME_MASK
+ */
+#define MAC_ADDR_DW1                   0x100c
+#define MAC_ADDR_DW1_BYTE4             FIELD32(0x000000ff)
+#define MAC_ADDR_DW1_BYTE5             FIELD32(0x0000ff00)
+#define MAC_ADDR_DW1_UNICAST_TO_ME_MASK        FIELD32(0x00ff0000)
+
+/*
+ * MAC_BSSID_DW0: BSSID register 0
+ */
+#define MAC_BSSID_DW0                  0x1010
+#define MAC_BSSID_DW0_BYTE0            FIELD32(0x000000ff)
+#define MAC_BSSID_DW0_BYTE1            FIELD32(0x0000ff00)
+#define MAC_BSSID_DW0_BYTE2            FIELD32(0x00ff0000)
+#define MAC_BSSID_DW0_BYTE3            FIELD32(0xff000000)
+
+/*
+ * MAC_BSSID_DW1: BSSID register 1
+ * BSS_ID_MASK:
+ *     0: 1-BSSID mode (BSS index = 0)
+ *     1: 2-BSSID mode (BSS index: Byte5, bit 0)
+ *     2: 4-BSSID mode (BSS index: byte5, bit 0 - 1)
+ *     3: 8-BSSID mode (BSS index: byte5, bit 0 - 2)
+ * This mask is used to mask off bits 0, 1 and 2 of byte 5 of the
+ * BSSID. This will make sure that those bits will be ignored
+ * when determining the MY_BSS of RX frames.
+ */
+#define MAC_BSSID_DW1                  0x1014
+#define MAC_BSSID_DW1_BYTE4            FIELD32(0x000000ff)
+#define MAC_BSSID_DW1_BYTE5            FIELD32(0x0000ff00)
+#define MAC_BSSID_DW1_BSS_ID_MASK      FIELD32(0x00030000)
+#define MAC_BSSID_DW1_BSS_BCN_NUM      FIELD32(0x001c0000)
+
+/*
+ * MAX_LEN_CFG: Maximum frame length register.
+ * MAX_MPDU: rt2860b max 16k bytes
+ * MAX_PSDU: Maximum PSDU length
+ *     (power factor) 0:2^13, 1:2^14, 2:2^15, 3:2^16
+ */
+#define MAX_LEN_CFG                    0x1018
+#define MAX_LEN_CFG_MAX_MPDU           FIELD32(0x00000fff)
+#define MAX_LEN_CFG_MAX_PSDU           FIELD32(0x00003000)
+#define MAX_LEN_CFG_MIN_PSDU           FIELD32(0x0000c000)
+#define MAX_LEN_CFG_MIN_MPDU           FIELD32(0x000f0000)
+
+/*
+ * BBP_CSR_CFG: BBP serial control register
+ * VALUE: Register value to program into BBP
+ * REG_NUM: Selected BBP register
+ * READ_CONTROL: 0 write BBP, 1 read BBP
+ * BUSY: ASIC is busy executing BBP commands
+ * BBP_PAR_DUR: 0 4 MAC clocks, 1 8 MAC clocks
+ * BBP_RW_MODE: 0 serial, 1 paralell
+ */
+#define BBP_CSR_CFG                    0x101c
+#define BBP_CSR_CFG_VALUE              FIELD32(0x000000ff)
+#define BBP_CSR_CFG_REGNUM             FIELD32(0x0000ff00)
+#define BBP_CSR_CFG_READ_CONTROL       FIELD32(0x00010000)
+#define BBP_CSR_CFG_BUSY               FIELD32(0x00020000)
+#define BBP_CSR_CFG_BBP_PAR_DUR                FIELD32(0x00040000)
+#define BBP_CSR_CFG_BBP_RW_MODE                FIELD32(0x00080000)
+
+/*
+ * RF_CSR_CFG0: RF control register
+ * REGID_AND_VALUE: Register value to program into RF
+ * BITWIDTH: Selected RF register
+ * STANDBYMODE: 0 high when standby, 1 low when standby
+ * SEL: 0 RF_LE0 activate, 1 RF_LE1 activate
+ * BUSY: ASIC is busy executing RF commands
+ */
+#define RF_CSR_CFG0                    0x1020
+#define RF_CSR_CFG0_REGID_AND_VALUE    FIELD32(0x00ffffff)
+#define RF_CSR_CFG0_BITWIDTH           FIELD32(0x1f000000)
+#define RF_CSR_CFG0_REG_VALUE_BW       FIELD32(0x1fffffff)
+#define RF_CSR_CFG0_STANDBYMODE                FIELD32(0x20000000)
+#define RF_CSR_CFG0_SEL                        FIELD32(0x40000000)
+#define RF_CSR_CFG0_BUSY               FIELD32(0x80000000)
+
+/*
+ * RF_CSR_CFG1: RF control register
+ * REGID_AND_VALUE: Register value to program into RF
+ * RFGAP: Gap between BB_CONTROL_RF and RF_LE
+ *        0: 3 system clock cycle (37.5usec)
+ *        1: 5 system clock cycle (62.5usec)
+ */
+#define RF_CSR_CFG1                    0x1024
+#define RF_CSR_CFG1_REGID_AND_VALUE    FIELD32(0x00ffffff)
+#define RF_CSR_CFG1_RFGAP              FIELD32(0x1f000000)
+
+/*
+ * RF_CSR_CFG2: RF control register
+ * VALUE: Register value to program into RF
+ * RFGAP: Gap between BB_CONTROL_RF and RF_LE
+ *        0: 3 system clock cycle (37.5usec)
+ *        1: 5 system clock cycle (62.5usec)
+ */
+#define RF_CSR_CFG2                    0x1028
+#define RF_CSR_CFG2_VALUE              FIELD32(0x00ffffff)
+
+/*
+ * LED_CFG: LED control
+ * color LED's:
+ *   0: off
+ *   1: blinking upon TX2
+ *   2: periodic slow blinking
+ *   3: always on
+ * LED polarity:
+ *   0: active low
+ *   1: active high
+ */
+#define LED_CFG                                0x102c
+#define LED_CFG_ON_PERIOD              FIELD32(0x000000ff)
+#define LED_CFG_OFF_PERIOD             FIELD32(0x0000ff00)
+#define LED_CFG_SLOW_BLINK_PERIOD      FIELD32(0x003f0000)
+#define LED_CFG_R_LED_MODE             FIELD32(0x03000000)
+#define LED_CFG_G_LED_MODE             FIELD32(0x0c000000)
+#define LED_CFG_Y_LED_MODE             FIELD32(0x30000000)
+#define LED_CFG_LED_POLAR              FIELD32(0x40000000)
+
+/*
+ * XIFS_TIME_CFG: MAC timing
+ * CCKM_SIFS_TIME: unit 1us. Applied after CCK RX/TX
+ * OFDM_SIFS_TIME: unit 1us. Applied after OFDM RX/TX
+ * OFDM_XIFS_TIME: unit 1us. Applied after OFDM RX
+ *     when MAC doesn't reference BBP signal BBRXEND
+ * EIFS: unit 1us
+ * BB_RXEND_ENABLE: reference RXEND signal to begin XIFS defer
+ *
+ */
+#define XIFS_TIME_CFG                  0x1100
+#define XIFS_TIME_CFG_CCKM_SIFS_TIME   FIELD32(0x000000ff)
+#define XIFS_TIME_CFG_OFDM_SIFS_TIME   FIELD32(0x0000ff00)
+#define XIFS_TIME_CFG_OFDM_XIFS_TIME   FIELD32(0x000f0000)
+#define XIFS_TIME_CFG_EIFS             FIELD32(0x1ff00000)
+#define XIFS_TIME_CFG_BB_RXEND_ENABLE  FIELD32(0x20000000)
+
+/*
+ * BKOFF_SLOT_CFG:
+ */
+#define BKOFF_SLOT_CFG                 0x1104
+#define BKOFF_SLOT_CFG_SLOT_TIME       FIELD32(0x000000ff)
+#define BKOFF_SLOT_CFG_CC_DELAY_TIME   FIELD32(0x0000ff00)
+
+/*
+ * NAV_TIME_CFG:
+ */
+#define NAV_TIME_CFG                   0x1108
+#define NAV_TIME_CFG_SIFS              FIELD32(0x000000ff)
+#define NAV_TIME_CFG_SLOT_TIME         FIELD32(0x0000ff00)
+#define NAV_TIME_CFG_EIFS              FIELD32(0x01ff0000)
+#define NAV_TIME_ZERO_SIFS             FIELD32(0x02000000)
+
+/*
+ * CH_TIME_CFG: count as channel busy
+ */
+#define CH_TIME_CFG                    0x110c
+
+/*
+ * PBF_LIFE_TIMER: TX/RX MPDU timestamp timer (free run) Unit: 1us
+ */
+#define PBF_LIFE_TIMER                 0x1110
+
+/*
+ * BCN_TIME_CFG:
+ * BEACON_INTERVAL: in unit of 1/16 TU
+ * TSF_TICKING: Enable TSF auto counting
+ * TSF_SYNC: Enable TSF sync, 00: disable, 01: infra mode, 10: ad-hoc mode
+ * BEACON_GEN: Enable beacon generator
+ */
+#define BCN_TIME_CFG                   0x1114
+#define BCN_TIME_CFG_BEACON_INTERVAL   FIELD32(0x0000ffff)
+#define BCN_TIME_CFG_TSF_TICKING       FIELD32(0x00010000)
+#define BCN_TIME_CFG_TSF_SYNC          FIELD32(0x00060000)
+#define BCN_TIME_CFG_TBTT_ENABLE       FIELD32(0x00080000)
+#define BCN_TIME_CFG_BEACON_GEN                FIELD32(0x00100000)
+#define BCN_TIME_CFG_TX_TIME_COMPENSATE        FIELD32(0xf0000000)
+
+/*
+ * TBTT_SYNC_CFG:
+ */
+#define TBTT_SYNC_CFG                  0x1118
+
+/*
+ * TSF_TIMER_DW0: Local lsb TSF timer, read-only
+ */
+#define TSF_TIMER_DW0                  0x111c
+#define TSF_TIMER_DW0_LOW_WORD         FIELD32(0xffffffff)
+
+/*
+ * TSF_TIMER_DW1: Local msb TSF timer, read-only
+ */
+#define TSF_TIMER_DW1                  0x1120
+#define TSF_TIMER_DW1_HIGH_WORD                FIELD32(0xffffffff)
+
+/*
+ * TBTT_TIMER: TImer remains till next TBTT, read-only
+ */
+#define TBTT_TIMER                     0x1124
+
+/*
+ * INT_TIMER_CFG:
+ */
+#define INT_TIMER_CFG                  0x1128
+
+/*
+ * INT_TIMER_EN: GP-timer and pre-tbtt Int enable
+ */
+#define INT_TIMER_EN                   0x112c
+
+/*
+ * CH_IDLE_STA: channel idle time
+ */
+#define CH_IDLE_STA                    0x1130
+
+/*
+ * CH_BUSY_STA: channel busy time
+ */
+#define CH_BUSY_STA                    0x1134
+
+/*
+ * MAC_STATUS_CFG:
+ * BBP_RF_BUSY: When set to 0, BBP and RF are stable.
+ *     if 1 or higher one of the 2 registers is busy.
+ */
+#define MAC_STATUS_CFG                 0x1200
+#define MAC_STATUS_CFG_BBP_RF_BUSY     FIELD32(0x00000003)
+
+/*
+ * PWR_PIN_CFG:
+ */
+#define PWR_PIN_CFG                    0x1204
+
+/*
+ * AUTOWAKEUP_CFG: Manual power control / status register
+ * TBCN_BEFORE_WAKE: ForceWake has high privilege than PutToSleep when both set
+ * AUTOWAKE: 0:sleep, 1:awake
+ */
+#define AUTOWAKEUP_CFG                 0x1208
+#define AUTOWAKEUP_CFG_AUTO_LEAD_TIME  FIELD32(0x000000ff)
+#define AUTOWAKEUP_CFG_TBCN_BEFORE_WAKE        FIELD32(0x00007f00)
+#define AUTOWAKEUP_CFG_AUTOWAKE                FIELD32(0x00008000)
+
+/*
+ * EDCA_AC0_CFG:
+ */
+#define EDCA_AC0_CFG                   0x1300
+#define EDCA_AC0_CFG_TX_OP             FIELD32(0x000000ff)
+#define EDCA_AC0_CFG_AIFSN             FIELD32(0x00000f00)
+#define EDCA_AC0_CFG_CWMIN             FIELD32(0x0000f000)
+#define EDCA_AC0_CFG_CWMAX             FIELD32(0x000f0000)
+
+/*
+ * EDCA_AC1_CFG:
+ */
+#define EDCA_AC1_CFG                   0x1304
+#define EDCA_AC1_CFG_TX_OP             FIELD32(0x000000ff)
+#define EDCA_AC1_CFG_AIFSN             FIELD32(0x00000f00)
+#define EDCA_AC1_CFG_CWMIN             FIELD32(0x0000f000)
+#define EDCA_AC1_CFG_CWMAX             FIELD32(0x000f0000)
+
+/*
+ * EDCA_AC2_CFG:
+ */
+#define EDCA_AC2_CFG                   0x1308
+#define EDCA_AC2_CFG_TX_OP             FIELD32(0x000000ff)
+#define EDCA_AC2_CFG_AIFSN             FIELD32(0x00000f00)
+#define EDCA_AC2_CFG_CWMIN             FIELD32(0x0000f000)
+#define EDCA_AC2_CFG_CWMAX             FIELD32(0x000f0000)
+
+/*
+ * EDCA_AC3_CFG:
+ */
+#define EDCA_AC3_CFG                   0x130c
+#define EDCA_AC3_CFG_TX_OP             FIELD32(0x000000ff)
+#define EDCA_AC3_CFG_AIFSN             FIELD32(0x00000f00)
+#define EDCA_AC3_CFG_CWMIN             FIELD32(0x0000f000)
+#define EDCA_AC3_CFG_CWMAX             FIELD32(0x000f0000)
+
+/*
+ * EDCA_TID_AC_MAP:
+ */
+#define EDCA_TID_AC_MAP                        0x1310
+
+/*
+ * TX_PWR_CFG_0:
+ */
+#define TX_PWR_CFG_0                   0x1314
+#define TX_PWR_CFG_0_1MBS              FIELD32(0x0000000f)
+#define TX_PWR_CFG_0_2MBS              FIELD32(0x000000f0)
+#define TX_PWR_CFG_0_55MBS             FIELD32(0x00000f00)
+#define TX_PWR_CFG_0_11MBS             FIELD32(0x0000f000)
+#define TX_PWR_CFG_0_6MBS              FIELD32(0x000f0000)
+#define TX_PWR_CFG_0_9MBS              FIELD32(0x00f00000)
+#define TX_PWR_CFG_0_12MBS             FIELD32(0x0f000000)
+#define TX_PWR_CFG_0_18MBS             FIELD32(0xf0000000)
+
+/*
+ * TX_PWR_CFG_1:
+ */
+#define TX_PWR_CFG_1                   0x1318
+#define TX_PWR_CFG_1_24MBS             FIELD32(0x0000000f)
+#define TX_PWR_CFG_1_36MBS             FIELD32(0x000000f0)
+#define TX_PWR_CFG_1_48MBS             FIELD32(0x00000f00)
+#define TX_PWR_CFG_1_54MBS             FIELD32(0x0000f000)
+#define TX_PWR_CFG_1_MCS0              FIELD32(0x000f0000)
+#define TX_PWR_CFG_1_MCS1              FIELD32(0x00f00000)
+#define TX_PWR_CFG_1_MCS2              FIELD32(0x0f000000)
+#define TX_PWR_CFG_1_MCS3              FIELD32(0xf0000000)
+
+/*
+ * TX_PWR_CFG_2:
+ */
+#define TX_PWR_CFG_2                   0x131c
+#define TX_PWR_CFG_2_MCS4              FIELD32(0x0000000f)
+#define TX_PWR_CFG_2_MCS5              FIELD32(0x000000f0)
+#define TX_PWR_CFG_2_MCS6              FIELD32(0x00000f00)
+#define TX_PWR_CFG_2_MCS7              FIELD32(0x0000f000)
+#define TX_PWR_CFG_2_MCS8              FIELD32(0x000f0000)
+#define TX_PWR_CFG_2_MCS9              FIELD32(0x00f00000)
+#define TX_PWR_CFG_2_MCS10             FIELD32(0x0f000000)
+#define TX_PWR_CFG_2_MCS11             FIELD32(0xf0000000)
+
+/*
+ * TX_PWR_CFG_3:
+ */
+#define TX_PWR_CFG_3                   0x1320
+#define TX_PWR_CFG_3_MCS12             FIELD32(0x0000000f)
+#define TX_PWR_CFG_3_MCS13             FIELD32(0x000000f0)
+#define TX_PWR_CFG_3_MCS14             FIELD32(0x00000f00)
+#define TX_PWR_CFG_3_MCS15             FIELD32(0x0000f000)
+#define TX_PWR_CFG_3_UKNOWN1           FIELD32(0x000f0000)
+#define TX_PWR_CFG_3_UKNOWN2           FIELD32(0x00f00000)
+#define TX_PWR_CFG_3_UKNOWN3           FIELD32(0x0f000000)
+#define TX_PWR_CFG_3_UKNOWN4           FIELD32(0xf0000000)
+
+/*
+ * TX_PWR_CFG_4:
+ */
+#define TX_PWR_CFG_4                   0x1324
+#define TX_PWR_CFG_4_UKNOWN5           FIELD32(0x0000000f)
+#define TX_PWR_CFG_4_UKNOWN6           FIELD32(0x000000f0)
+#define TX_PWR_CFG_4_UKNOWN7           FIELD32(0x00000f00)
+#define TX_PWR_CFG_4_UKNOWN8           FIELD32(0x0000f000)
+
+/*
+ * TX_PIN_CFG:
+ */
+#define TX_PIN_CFG                     0x1328
+#define TX_PIN_CFG_PA_PE_A0_EN         FIELD32(0x00000001)
+#define TX_PIN_CFG_PA_PE_G0_EN         FIELD32(0x00000002)
+#define TX_PIN_CFG_PA_PE_A1_EN         FIELD32(0x00000004)
+#define TX_PIN_CFG_PA_PE_G1_EN         FIELD32(0x00000008)
+#define TX_PIN_CFG_PA_PE_A0_POL                FIELD32(0x00000010)
+#define TX_PIN_CFG_PA_PE_G0_POL                FIELD32(0x00000020)
+#define TX_PIN_CFG_PA_PE_A1_POL                FIELD32(0x00000040)
+#define TX_PIN_CFG_PA_PE_G1_POL                FIELD32(0x00000080)
+#define TX_PIN_CFG_LNA_PE_A0_EN                FIELD32(0x00000100)
+#define TX_PIN_CFG_LNA_PE_G0_EN                FIELD32(0x00000200)
+#define TX_PIN_CFG_LNA_PE_A1_EN                FIELD32(0x00000400)
+#define TX_PIN_CFG_LNA_PE_G1_EN                FIELD32(0x00000800)
+#define TX_PIN_CFG_LNA_PE_A0_POL       FIELD32(0x00001000)
+#define TX_PIN_CFG_LNA_PE_G0_POL       FIELD32(0x00002000)
+#define TX_PIN_CFG_LNA_PE_A1_POL       FIELD32(0x00004000)
+#define TX_PIN_CFG_LNA_PE_G1_POL       FIELD32(0x00008000)
+#define TX_PIN_CFG_RFTR_EN             FIELD32(0x00010000)
+#define TX_PIN_CFG_RFTR_POL            FIELD32(0x00020000)
+#define TX_PIN_CFG_TRSW_EN             FIELD32(0x00040000)
+#define TX_PIN_CFG_TRSW_POL            FIELD32(0x00080000)
+
+/*
+ * TX_BAND_CFG: 0x1 use upper 20MHz, 0x0 use lower 20MHz
+ */
+#define TX_BAND_CFG                    0x132c
+#define TX_BAND_CFG_HT40_PLUS          FIELD32(0x00000001)
+#define TX_BAND_CFG_A                  FIELD32(0x00000002)
+#define TX_BAND_CFG_BG                 FIELD32(0x00000004)
+
+/*
+ * TX_SW_CFG0:
+ */
+#define TX_SW_CFG0                     0x1330
+
+/*
+ * TX_SW_CFG1:
+ */
+#define TX_SW_CFG1                     0x1334
+
+/*
+ * TX_SW_CFG2:
+ */
+#define TX_SW_CFG2                     0x1338
+
+/*
+ * TXOP_THRES_CFG:
+ */
+#define TXOP_THRES_CFG                 0x133c
+
+/*
+ * TXOP_CTRL_CFG:
+ */
+#define TXOP_CTRL_CFG                  0x1340
+
+/*
+ * TX_RTS_CFG:
+ * RTS_THRES: unit:byte
+ * RTS_FBK_EN: enable rts rate fallback
+ */
+#define TX_RTS_CFG                     0x1344
+#define TX_RTS_CFG_AUTO_RTS_RETRY_LIMIT        FIELD32(0x000000ff)
+#define TX_RTS_CFG_RTS_THRES           FIELD32(0x00ffff00)
+#define TX_RTS_CFG_RTS_FBK_EN          FIELD32(0x01000000)
+
+/*
+ * TX_TIMEOUT_CFG:
+ * MPDU_LIFETIME: expiration time = 2^(9+MPDU LIFE TIME) us
+ * RX_ACK_TIMEOUT: unit:slot. Used for TX procedure
+ * TX_OP_TIMEOUT: TXOP timeout value for TXOP truncation.
+ *                it is recommended that:
+ *                (SLOT_TIME) > (TX_OP_TIMEOUT) > (RX_ACK_TIMEOUT)
+ */
+#define TX_TIMEOUT_CFG                 0x1348
+#define TX_TIMEOUT_CFG_MPDU_LIFETIME   FIELD32(0x000000f0)
+#define TX_TIMEOUT_CFG_RX_ACK_TIMEOUT  FIELD32(0x0000ff00)
+#define TX_TIMEOUT_CFG_TX_OP_TIMEOUT   FIELD32(0x00ff0000)
+
+/*
+ * TX_RTY_CFG:
+ * SHORT_RTY_LIMIT: short retry limit
+ * LONG_RTY_LIMIT: long retry limit
+ * LONG_RTY_THRE: Long retry threshoold
+ * NON_AGG_RTY_MODE: Non-Aggregate MPDU retry mode
+ *                   0:expired by retry limit, 1: expired by mpdu life timer
+ * AGG_RTY_MODE: Aggregate MPDU retry mode
+ *               0:expired by retry limit, 1: expired by mpdu life timer
+ * TX_AUTO_FB_ENABLE: Tx retry PHY rate auto fallback enable
+ */
+#define TX_RTY_CFG                     0x134c
+#define TX_RTY_CFG_SHORT_RTY_LIMIT     FIELD32(0x000000ff)
+#define TX_RTY_CFG_LONG_RTY_LIMIT      FIELD32(0x0000ff00)
+#define TX_RTY_CFG_LONG_RTY_THRE       FIELD32(0x0fff0000)
+#define TX_RTY_CFG_NON_AGG_RTY_MODE    FIELD32(0x10000000)
+#define TX_RTY_CFG_AGG_RTY_MODE                FIELD32(0x20000000)
+#define TX_RTY_CFG_TX_AUTO_FB_ENABLE   FIELD32(0x40000000)
+
+/*
+ * TX_LINK_CFG:
+ * REMOTE_MFB_LIFETIME: remote MFB life time. unit: 32us
+ * MFB_ENABLE: TX apply remote MFB 1:enable
+ * REMOTE_UMFS_ENABLE: remote unsolicit  MFB enable
+ *                     0: not apply remote remote unsolicit (MFS=7)
+ * TX_MRQ_EN: MCS request TX enable
+ * TX_RDG_EN: RDG TX enable
+ * TX_CF_ACK_EN: Piggyback CF-ACK enable
+ * REMOTE_MFB: remote MCS feedback
+ * REMOTE_MFS: remote MCS feedback sequence number
+ */
+#define TX_LINK_CFG                    0x1350
+#define TX_LINK_CFG_REMOTE_MFB_LIFETIME        FIELD32(0x000000ff)
+#define TX_LINK_CFG_MFB_ENABLE         FIELD32(0x00000100)
+#define TX_LINK_CFG_REMOTE_UMFS_ENABLE FIELD32(0x00000200)
+#define TX_LINK_CFG_TX_MRQ_EN          FIELD32(0x00000400)
+#define TX_LINK_CFG_TX_RDG_EN          FIELD32(0x00000800)
+#define TX_LINK_CFG_TX_CF_ACK_EN       FIELD32(0x00001000)
+#define TX_LINK_CFG_REMOTE_MFB         FIELD32(0x00ff0000)
+#define TX_LINK_CFG_REMOTE_MFS         FIELD32(0xff000000)
+
+/*
+ * HT_FBK_CFG0:
+ */
+#define HT_FBK_CFG0                    0x1354
+#define HT_FBK_CFG0_HTMCS0FBK          FIELD32(0x0000000f)
+#define HT_FBK_CFG0_HTMCS1FBK          FIELD32(0x000000f0)
+#define HT_FBK_CFG0_HTMCS2FBK          FIELD32(0x00000f00)
+#define HT_FBK_CFG0_HTMCS3FBK          FIELD32(0x0000f000)
+#define HT_FBK_CFG0_HTMCS4FBK          FIELD32(0x000f0000)
+#define HT_FBK_CFG0_HTMCS5FBK          FIELD32(0x00f00000)
+#define HT_FBK_CFG0_HTMCS6FBK          FIELD32(0x0f000000)
+#define HT_FBK_CFG0_HTMCS7FBK          FIELD32(0xf0000000)
+
+/*
+ * HT_FBK_CFG1:
+ */
+#define HT_FBK_CFG1                    0x1358
+#define HT_FBK_CFG1_HTMCS8FBK          FIELD32(0x0000000f)
+#define HT_FBK_CFG1_HTMCS9FBK          FIELD32(0x000000f0)
+#define HT_FBK_CFG1_HTMCS10FBK         FIELD32(0x00000f00)
+#define HT_FBK_CFG1_HTMCS11FBK         FIELD32(0x0000f000)
+#define HT_FBK_CFG1_HTMCS12FBK         FIELD32(0x000f0000)
+#define HT_FBK_CFG1_HTMCS13FBK         FIELD32(0x00f00000)
+#define HT_FBK_CFG1_HTMCS14FBK         FIELD32(0x0f000000)
+#define HT_FBK_CFG1_HTMCS15FBK         FIELD32(0xf0000000)
+
+/*
+ * LG_FBK_CFG0:
+ */
+#define LG_FBK_CFG0                    0x135c
+#define LG_FBK_CFG0_OFDMMCS0FBK                FIELD32(0x0000000f)
+#define LG_FBK_CFG0_OFDMMCS1FBK                FIELD32(0x000000f0)
+#define LG_FBK_CFG0_OFDMMCS2FBK                FIELD32(0x00000f00)
+#define LG_FBK_CFG0_OFDMMCS3FBK                FIELD32(0x0000f000)
+#define LG_FBK_CFG0_OFDMMCS4FBK                FIELD32(0x000f0000)
+#define LG_FBK_CFG0_OFDMMCS5FBK                FIELD32(0x00f00000)
+#define LG_FBK_CFG0_OFDMMCS6FBK                FIELD32(0x0f000000)
+#define LG_FBK_CFG0_OFDMMCS7FBK                FIELD32(0xf0000000)
+
+/*
+ * LG_FBK_CFG1:
+ */
+#define LG_FBK_CFG1                    0x1360
+#define LG_FBK_CFG0_CCKMCS0FBK         FIELD32(0x0000000f)
+#define LG_FBK_CFG0_CCKMCS1FBK         FIELD32(0x000000f0)
+#define LG_FBK_CFG0_CCKMCS2FBK         FIELD32(0x00000f00)
+#define LG_FBK_CFG0_CCKMCS3FBK         FIELD32(0x0000f000)
+
+/*
+ * CCK_PROT_CFG: CCK Protection
+ * PROTECT_RATE: Protection control frame rate for CCK TX(RTS/CTS/CFEnd)
+ * PROTECT_CTRL: Protection control frame type for CCK TX
+ *               0:none, 1:RTS/CTS, 2:CTS-to-self
+ * PROTECT_NAV: TXOP protection type for CCK TX
+ *              0:none, 1:ShortNAVprotect, 2:LongNAVProtect
+ * TX_OP_ALLOW_CCK: CCK TXOP allowance, 0:disallow
+ * TX_OP_ALLOW_OFDM: CCK TXOP allowance, 0:disallow
+ * TX_OP_ALLOW_MM20: CCK TXOP allowance, 0:disallow
+ * TX_OP_ALLOW_MM40: CCK TXOP allowance, 0:disallow
+ * TX_OP_ALLOW_GF20: CCK TXOP allowance, 0:disallow
+ * TX_OP_ALLOW_GF40: CCK TXOP allowance, 0:disallow
+ * RTS_TH_EN: RTS threshold enable on CCK TX
+ */
+#define CCK_PROT_CFG                   0x1364
+#define CCK_PROT_CFG_PROTECT_RATE      FIELD32(0x0000ffff)
+#define CCK_PROT_CFG_PROTECT_CTRL      FIELD32(0x00030000)
+#define CCK_PROT_CFG_PROTECT_NAV       FIELD32(0x000c0000)
+#define CCK_PROT_CFG_TX_OP_ALLOW_CCK   FIELD32(0x00100000)
+#define CCK_PROT_CFG_TX_OP_ALLOW_OFDM  FIELD32(0x00200000)
+#define CCK_PROT_CFG_TX_OP_ALLOW_MM20  FIELD32(0x00400000)
+#define CCK_PROT_CFG_TX_OP_ALLOW_MM40  FIELD32(0x00800000)
+#define CCK_PROT_CFG_TX_OP_ALLOW_GF20  FIELD32(0x01000000)
+#define CCK_PROT_CFG_TX_OP_ALLOW_GF40  FIELD32(0x02000000)
+#define CCK_PROT_CFG_RTS_TH_EN         FIELD32(0x04000000)
+
+/*
+ * OFDM_PROT_CFG: OFDM Protection
+ */
+#define OFDM_PROT_CFG                  0x1368
+#define OFDM_PROT_CFG_PROTECT_RATE     FIELD32(0x0000ffff)
+#define OFDM_PROT_CFG_PROTECT_CTRL     FIELD32(0x00030000)
+#define OFDM_PROT_CFG_PROTECT_NAV      FIELD32(0x000c0000)
+#define OFDM_PROT_CFG_TX_OP_ALLOW_CCK  FIELD32(0x00100000)
+#define OFDM_PROT_CFG_TX_OP_ALLOW_OFDM FIELD32(0x00200000)
+#define OFDM_PROT_CFG_TX_OP_ALLOW_MM20 FIELD32(0x00400000)
+#define OFDM_PROT_CFG_TX_OP_ALLOW_MM40 FIELD32(0x00800000)
+#define OFDM_PROT_CFG_TX_OP_ALLOW_GF20 FIELD32(0x01000000)
+#define OFDM_PROT_CFG_TX_OP_ALLOW_GF40 FIELD32(0x02000000)
+#define OFDM_PROT_CFG_RTS_TH_EN                FIELD32(0x04000000)
+
+/*
+ * MM20_PROT_CFG: MM20 Protection
+ */
+#define MM20_PROT_CFG                  0x136c
+#define MM20_PROT_CFG_PROTECT_RATE     FIELD32(0x0000ffff)
+#define MM20_PROT_CFG_PROTECT_CTRL     FIELD32(0x00030000)
+#define MM20_PROT_CFG_PROTECT_NAV      FIELD32(0x000c0000)
+#define MM20_PROT_CFG_TX_OP_ALLOW_CCK  FIELD32(0x00100000)
+#define MM20_PROT_CFG_TX_OP_ALLOW_OFDM FIELD32(0x00200000)
+#define MM20_PROT_CFG_TX_OP_ALLOW_MM20 FIELD32(0x00400000)
+#define MM20_PROT_CFG_TX_OP_ALLOW_MM40 FIELD32(0x00800000)
+#define MM20_PROT_CFG_TX_OP_ALLOW_GF20 FIELD32(0x01000000)
+#define MM20_PROT_CFG_TX_OP_ALLOW_GF40 FIELD32(0x02000000)
+#define MM20_PROT_CFG_RTS_TH_EN                FIELD32(0x04000000)
+
+/*
+ * MM40_PROT_CFG: MM40 Protection
+ */
+#define MM40_PROT_CFG                  0x1370
+#define MM40_PROT_CFG_PROTECT_RATE     FIELD32(0x0000ffff)
+#define MM40_PROT_CFG_PROTECT_CTRL     FIELD32(0x00030000)
+#define MM40_PROT_CFG_PROTECT_NAV      FIELD32(0x000c0000)
+#define MM40_PROT_CFG_TX_OP_ALLOW_CCK  FIELD32(0x00100000)
+#define MM40_PROT_CFG_TX_OP_ALLOW_OFDM FIELD32(0x00200000)
+#define MM40_PROT_CFG_TX_OP_ALLOW_MM20 FIELD32(0x00400000)
+#define MM40_PROT_CFG_TX_OP_ALLOW_MM40 FIELD32(0x00800000)
+#define MM40_PROT_CFG_TX_OP_ALLOW_GF20 FIELD32(0x01000000)
+#define MM40_PROT_CFG_TX_OP_ALLOW_GF40 FIELD32(0x02000000)
+#define MM40_PROT_CFG_RTS_TH_EN                FIELD32(0x04000000)
+
+/*
+ * GF20_PROT_CFG: GF20 Protection
+ */
+#define GF20_PROT_CFG                  0x1374
+#define GF20_PROT_CFG_PROTECT_RATE     FIELD32(0x0000ffff)
+#define GF20_PROT_CFG_PROTECT_CTRL     FIELD32(0x00030000)
+#define GF20_PROT_CFG_PROTECT_NAV      FIELD32(0x000c0000)
+#define GF20_PROT_CFG_TX_OP_ALLOW_CCK  FIELD32(0x00100000)
+#define GF20_PROT_CFG_TX_OP_ALLOW_OFDM FIELD32(0x00200000)
+#define GF20_PROT_CFG_TX_OP_ALLOW_MM20 FIELD32(0x00400000)
+#define GF20_PROT_CFG_TX_OP_ALLOW_MM40 FIELD32(0x00800000)
+#define GF20_PROT_CFG_TX_OP_ALLOW_GF20 FIELD32(0x01000000)
+#define GF20_PROT_CFG_TX_OP_ALLOW_GF40 FIELD32(0x02000000)
+#define GF20_PROT_CFG_RTS_TH_EN                FIELD32(0x04000000)
+
+/*
+ * GF40_PROT_CFG: GF40 Protection
+ */
+#define GF40_PROT_CFG                  0x1378
+#define GF40_PROT_CFG_PROTECT_RATE     FIELD32(0x0000ffff)
+#define GF40_PROT_CFG_PROTECT_CTRL     FIELD32(0x00030000)
+#define GF40_PROT_CFG_PROTECT_NAV      FIELD32(0x000c0000)
+#define GF40_PROT_CFG_TX_OP_ALLOW_CCK  FIELD32(0x00100000)
+#define GF40_PROT_CFG_TX_OP_ALLOW_OFDM FIELD32(0x00200000)
+#define GF40_PROT_CFG_TX_OP_ALLOW_MM20 FIELD32(0x00400000)
+#define GF40_PROT_CFG_TX_OP_ALLOW_MM40 FIELD32(0x00800000)
+#define GF40_PROT_CFG_TX_OP_ALLOW_GF20 FIELD32(0x01000000)
+#define GF40_PROT_CFG_TX_OP_ALLOW_GF40 FIELD32(0x02000000)
+#define GF40_PROT_CFG_RTS_TH_EN                FIELD32(0x04000000)
+
+/*
+ * EXP_CTS_TIME:
+ */
+#define EXP_CTS_TIME                   0x137c
+
+/*
+ * EXP_ACK_TIME:
+ */
+#define EXP_ACK_TIME                   0x1380
+
+/*
+ * RX_FILTER_CFG: RX configuration register.
+ */
+#define RX_FILTER_CFG                  0x1400
+#define RX_FILTER_CFG_DROP_CRC_ERROR   FIELD32(0x00000001)
+#define RX_FILTER_CFG_DROP_PHY_ERROR   FIELD32(0x00000002)
+#define RX_FILTER_CFG_DROP_NOT_TO_ME   FIELD32(0x00000004)
+#define RX_FILTER_CFG_DROP_NOT_MY_BSSD FIELD32(0x00000008)
+#define RX_FILTER_CFG_DROP_VER_ERROR   FIELD32(0x00000010)
+#define RX_FILTER_CFG_DROP_MULTICAST   FIELD32(0x00000020)
+#define RX_FILTER_CFG_DROP_BROADCAST   FIELD32(0x00000040)
+#define RX_FILTER_CFG_DROP_DUPLICATE   FIELD32(0x00000080)
+#define RX_FILTER_CFG_DROP_CF_END_ACK  FIELD32(0x00000100)
+#define RX_FILTER_CFG_DROP_CF_END      FIELD32(0x00000200)
+#define RX_FILTER_CFG_DROP_ACK         FIELD32(0x00000400)
+#define RX_FILTER_CFG_DROP_CTS         FIELD32(0x00000800)
+#define RX_FILTER_CFG_DROP_RTS         FIELD32(0x00001000)
+#define RX_FILTER_CFG_DROP_PSPOLL      FIELD32(0x00002000)
+#define RX_FILTER_CFG_DROP_BA          FIELD32(0x00004000)
+#define RX_FILTER_CFG_DROP_BAR         FIELD32(0x00008000)
+#define RX_FILTER_CFG_DROP_CNTL                FIELD32(0x00010000)
+
+/*
+ * AUTO_RSP_CFG:
+ * AUTORESPONDER: 0: disable, 1: enable
+ * BAC_ACK_POLICY: 0:long, 1:short preamble
+ * CTS_40_MMODE: Response CTS 40MHz duplicate mode
+ * CTS_40_MREF: Response CTS 40MHz duplicate mode
+ * AR_PREAMBLE: Auto responder preamble 0:long, 1:short preamble
+ * DUAL_CTS_EN: Power bit value in control frame
+ * ACK_CTS_PSM_BIT:Power bit value in control frame
+ */
+#define AUTO_RSP_CFG                   0x1404
+#define AUTO_RSP_CFG_AUTORESPONDER     FIELD32(0x00000001)
+#define AUTO_RSP_CFG_BAC_ACK_POLICY    FIELD32(0x00000002)
+#define AUTO_RSP_CFG_CTS_40_MMODE      FIELD32(0x00000004)
+#define AUTO_RSP_CFG_CTS_40_MREF       FIELD32(0x00000008)
+#define AUTO_RSP_CFG_AR_PREAMBLE       FIELD32(0x00000010)
+#define AUTO_RSP_CFG_DUAL_CTS_EN       FIELD32(0x00000040)
+#define AUTO_RSP_CFG_ACK_CTS_PSM_BIT   FIELD32(0x00000080)
+
+/*
+ * LEGACY_BASIC_RATE:
+ */
+#define LEGACY_BASIC_RATE              0x1408
+
+/*
+ * HT_BASIC_RATE:
+ */
+#define HT_BASIC_RATE                  0x140c
+
+/*
+ * HT_CTRL_CFG:
+ */
+#define HT_CTRL_CFG                    0x1410
+
+/*
+ * SIFS_COST_CFG:
+ */
+#define SIFS_COST_CFG                  0x1414
+
+/*
+ * RX_PARSER_CFG:
+ * Set NAV for all received frames
+ */
+#define RX_PARSER_CFG                  0x1418
+
+/*
+ * TX_SEC_CNT0:
+ */
+#define TX_SEC_CNT0                    0x1500
+
+/*
+ * RX_SEC_CNT0:
+ */
+#define RX_SEC_CNT0                    0x1504
+
+/*
+ * CCMP_FC_MUTE:
+ */
+#define CCMP_FC_MUTE                   0x1508
+
+/*
+ * TXOP_HLDR_ADDR0:
+ */
+#define TXOP_HLDR_ADDR0                        0x1600
+
+/*
+ * TXOP_HLDR_ADDR1:
+ */
+#define TXOP_HLDR_ADDR1                        0x1604
+
+/*
+ * TXOP_HLDR_ET:
+ */
+#define TXOP_HLDR_ET                   0x1608
+
+/*
+ * QOS_CFPOLL_RA_DW0:
+ */
+#define QOS_CFPOLL_RA_DW0              0x160c
+
+/*
+ * QOS_CFPOLL_RA_DW1:
+ */
+#define QOS_CFPOLL_RA_DW1              0x1610
+
+/*
+ * QOS_CFPOLL_QC:
+ */
+#define QOS_CFPOLL_QC                  0x1614
+
+/*
+ * RX_STA_CNT0: RX PLCP error count & RX CRC error count
+ */
+#define RX_STA_CNT0                    0x1700
+#define RX_STA_CNT0_CRC_ERR            FIELD32(0x0000ffff)
+#define RX_STA_CNT0_PHY_ERR            FIELD32(0xffff0000)
+
+/*
+ * RX_STA_CNT1: RX False CCA count & RX LONG frame count
+ */
+#define RX_STA_CNT1                    0x1704
+#define RX_STA_CNT1_FALSE_CCA          FIELD32(0x0000ffff)
+#define RX_STA_CNT1_PLCP_ERR           FIELD32(0xffff0000)
+
+/*
+ * RX_STA_CNT2:
+ */
+#define RX_STA_CNT2                    0x1708
+#define RX_STA_CNT2_RX_DUPLI_COUNT     FIELD32(0x0000ffff)
+#define RX_STA_CNT2_RX_FIFO_OVERFLOW   FIELD32(0xffff0000)
+
+/*
+ * TX_STA_CNT0: TX Beacon count
+ */
+#define TX_STA_CNT0                    0x170c
+#define TX_STA_CNT0_TX_FAIL_COUNT      FIELD32(0x0000ffff)
+#define TX_STA_CNT0_TX_BEACON_COUNT    FIELD32(0xffff0000)
+
+/*
+ * TX_STA_CNT1: TX tx count
+ */
+#define TX_STA_CNT1                    0x1710
+#define TX_STA_CNT1_TX_SUCCESS         FIELD32(0x0000ffff)
+#define TX_STA_CNT1_TX_RETRANSMIT      FIELD32(0xffff0000)
+
+/*
+ * TX_STA_CNT2: TX tx count
+ */
+#define TX_STA_CNT2                    0x1714
+#define TX_STA_CNT2_TX_ZERO_LEN_COUNT  FIELD32(0x0000ffff)
+#define TX_STA_CNT2_TX_UNDER_FLOW_COUNT        FIELD32(0xffff0000)
+
+/*
+ * TX_STA_FIFO: TX Result for specific PID status fifo register
+ */
+#define TX_STA_FIFO                    0x1718
+#define TX_STA_FIFO_VALID              FIELD32(0x00000001)
+#define TX_STA_FIFO_PID_TYPE           FIELD32(0x0000001e)
+#define TX_STA_FIFO_TX_SUCCESS         FIELD32(0x00000020)
+#define TX_STA_FIFO_TX_AGGRE           FIELD32(0x00000040)
+#define TX_STA_FIFO_TX_ACK_REQUIRED    FIELD32(0x00000080)
+#define TX_STA_FIFO_WCID               FIELD32(0x0000ff00)
+#define TX_STA_FIFO_SUCCESS_RATE       FIELD32(0xffff0000)
+
+/*
+ * TX_AGG_CNT: Debug counter
+ */
+#define TX_AGG_CNT                     0x171c
+#define TX_AGG_CNT_NON_AGG_TX_COUNT    FIELD32(0x0000ffff)
+#define TX_AGG_CNT_AGG_TX_COUNT                FIELD32(0xffff0000)
+
+/*
+ * TX_AGG_CNT0:
+ */
+#define TX_AGG_CNT0                    0x1720
+#define TX_AGG_CNT0_AGG_SIZE_1_COUNT   FIELD32(0x0000ffff)
+#define TX_AGG_CNT0_AGG_SIZE_2_COUNT   FIELD32(0xffff0000)
+
+/*
+ * TX_AGG_CNT1:
+ */
+#define TX_AGG_CNT1                    0x1724
+#define TX_AGG_CNT1_AGG_SIZE_3_COUNT   FIELD32(0x0000ffff)
+#define TX_AGG_CNT1_AGG_SIZE_4_COUNT   FIELD32(0xffff0000)
+
+/*
+ * TX_AGG_CNT2:
+ */
+#define TX_AGG_CNT2                    0x1728
+#define TX_AGG_CNT2_AGG_SIZE_5_COUNT   FIELD32(0x0000ffff)
+#define TX_AGG_CNT2_AGG_SIZE_6_COUNT   FIELD32(0xffff0000)
+
+/*
+ * TX_AGG_CNT3:
+ */
+#define TX_AGG_CNT3                    0x172c
+#define TX_AGG_CNT3_AGG_SIZE_7_COUNT   FIELD32(0x0000ffff)
+#define TX_AGG_CNT3_AGG_SIZE_8_COUNT   FIELD32(0xffff0000)
+
+/*
+ * TX_AGG_CNT4:
+ */
+#define TX_AGG_CNT4                    0x1730
+#define TX_AGG_CNT4_AGG_SIZE_9_COUNT   FIELD32(0x0000ffff)
+#define TX_AGG_CNT4_AGG_SIZE_10_COUNT  FIELD32(0xffff0000)
+
+/*
+ * TX_AGG_CNT5:
+ */
+#define TX_AGG_CNT5                    0x1734
+#define TX_AGG_CNT5_AGG_SIZE_11_COUNT  FIELD32(0x0000ffff)
+#define TX_AGG_CNT5_AGG_SIZE_12_COUNT  FIELD32(0xffff0000)
+
+/*
+ * TX_AGG_CNT6:
+ */
+#define TX_AGG_CNT6                    0x1738
+#define TX_AGG_CNT6_AGG_SIZE_13_COUNT  FIELD32(0x0000ffff)
+#define TX_AGG_CNT6_AGG_SIZE_14_COUNT  FIELD32(0xffff0000)
+
+/*
+ * TX_AGG_CNT7:
+ */
+#define TX_AGG_CNT7                    0x173c
+#define TX_AGG_CNT7_AGG_SIZE_15_COUNT  FIELD32(0x0000ffff)
+#define TX_AGG_CNT7_AGG_SIZE_16_COUNT  FIELD32(0xffff0000)
+
+/*
+ * MPDU_DENSITY_CNT:
+ * TX_ZERO_DEL: TX zero length delimiter count
+ * RX_ZERO_DEL: RX zero length delimiter count
+ */
+#define MPDU_DENSITY_CNT               0x1740
+#define MPDU_DENSITY_CNT_TX_ZERO_DEL   FIELD32(0x0000ffff)
+#define MPDU_DENSITY_CNT_RX_ZERO_DEL   FIELD32(0xffff0000)
+
+/*
+ * Security key table memory.
+ * MAC_WCID_BASE: 8-bytes (use only 6 bytes) * 256 entry
+ * PAIRWISE_KEY_TABLE_BASE: 32-byte * 256 entry
+ * MAC_IVEIV_TABLE_BASE: 8-byte * 256-entry
+ * MAC_WCID_ATTRIBUTE_BASE: 4-byte * 256-entry
+ * SHARED_KEY_TABLE_BASE: 32-byte * 16-entry
+ * SHARED_KEY_MODE_BASE: 4-byte * 16-entry
+ */
+#define MAC_WCID_BASE                  0x1800
+#define PAIRWISE_KEY_TABLE_BASE                0x4000
+#define MAC_IVEIV_TABLE_BASE           0x6000
+#define MAC_WCID_ATTRIBUTE_BASE                0x6800
+#define SHARED_KEY_TABLE_BASE          0x6c00
+#define SHARED_KEY_MODE_BASE           0x7000
+
+#define MAC_WCID_ENTRY(__idx) \
+       ( MAC_WCID_BASE + ((__idx) * sizeof(struct mac_wcid_entry)) )
+#define PAIRWISE_KEY_ENTRY(__idx) \
+       ( PAIRWISE_KEY_TABLE_BASE + ((__idx) * sizeof(struct hw_key_entry)) )
+#define MAC_IVEIV_ENTRY(__idx) \
+       ( MAC_IVEIV_TABLE_BASE + ((__idx) & sizeof(struct mac_iveiv_entry)) )
+#define MAC_WCID_ATTR_ENTRY(__idx) \
+       ( MAC_WCID_ATTRIBUTE_BASE + ((__idx) * sizeof(u32)) )
+#define SHARED_KEY_ENTRY(__idx) \
+       ( SHARED_KEY_TABLE_BASE + ((__idx) * sizeof(struct hw_key_entry)) )
+#define SHARED_KEY_MODE_ENTRY(__idx) \
+       ( SHARED_KEY_MODE_BASE + ((__idx) * sizeof(u32)) )
+
+struct mac_wcid_entry {
+       u8 mac[6];
+       u8 reserved[2];
+} __attribute__ ((packed));
+
+struct hw_key_entry {
+       u8 key[16];
+       u8 tx_mic[8];
+       u8 rx_mic[8];
+} __attribute__ ((packed));
+
+struct mac_iveiv_entry {
+       u8 iv[8];
+} __attribute__ ((packed));
+
+/*
+ * MAC_WCID_ATTRIBUTE:
+ */
+#define MAC_WCID_ATTRIBUTE_KEYTAB      FIELD32(0x00000001)
+#define MAC_WCID_ATTRIBUTE_CIPHER      FIELD32(0x0000000e)
+#define MAC_WCID_ATTRIBUTE_BSS_IDX     FIELD32(0x00000070)
+#define MAC_WCID_ATTRIBUTE_RX_WIUDF    FIELD32(0x00000380)
+
+/*
+ * SHARED_KEY_MODE:
+ */
+#define SHARED_KEY_MODE_BSS0_KEY0      FIELD32(0x00000007)
+#define SHARED_KEY_MODE_BSS0_KEY1      FIELD32(0x00000070)
+#define SHARED_KEY_MODE_BSS0_KEY2      FIELD32(0x00000700)
+#define SHARED_KEY_MODE_BSS0_KEY3      FIELD32(0x00007000)
+#define SHARED_KEY_MODE_BSS1_KEY0      FIELD32(0x00070000)
+#define SHARED_KEY_MODE_BSS1_KEY1      FIELD32(0x00700000)
+#define SHARED_KEY_MODE_BSS1_KEY2      FIELD32(0x07000000)
+#define SHARED_KEY_MODE_BSS1_KEY3      FIELD32(0x70000000)
+
+/*
+ * HOST-MCU communication
+ */
+
+/*
+ * H2M_MAILBOX_CSR: Host-to-MCU Mailbox.
+ */
+#define H2M_MAILBOX_CSR                        0x7010
+#define H2M_MAILBOX_CSR_ARG0           FIELD32(0x000000ff)
+#define H2M_MAILBOX_CSR_ARG1           FIELD32(0x0000ff00)
+#define H2M_MAILBOX_CSR_CMD_TOKEN      FIELD32(0x00ff0000)
+#define H2M_MAILBOX_CSR_OWNER          FIELD32(0xff000000)
+
+/*
+ * H2M_MAILBOX_CID:
+ */
+#define H2M_MAILBOX_CID                        0x7014
+#define H2M_MAILBOX_CID_CMD0           FIELD32(0x000000ff)
+#define H2M_MAILBOX_CID_CMD1           FIELD32(0x0000ff00)
+#define H2M_MAILBOX_CID_CMD2           FIELD32(0x00ff0000)
+#define H2M_MAILBOX_CID_CMD3           FIELD32(0xff000000)
+
+/*
+ * H2M_MAILBOX_STATUS:
+ */
+#define H2M_MAILBOX_STATUS             0x701c
+
+/*
+ * H2M_INT_SRC:
+ */
+#define H2M_INT_SRC                    0x7024
+
+/*
+ * H2M_BBP_AGENT:
+ */
+#define H2M_BBP_AGENT                  0x7028
+
+/*
+ * MCU_LEDCS: LED control for MCU Mailbox.
+ */
+#define MCU_LEDCS_LED_MODE             FIELD8(0x1f)
+#define MCU_LEDCS_POLARITY             FIELD8(0x01)
+
+/*
+ * HW_CS_CTS_BASE:
+ * Carrier-sense CTS frame base address.
+ * It's where mac stores carrier-sense frame for carrier-sense function.
+ */
+#define HW_CS_CTS_BASE                 0x7700
+
+/*
+ * HW_DFS_CTS_BASE:
+ * FS CTS frame base address. It's where mac stores CTS frame for DFS.
+ */
+#define HW_DFS_CTS_BASE                        0x7780
+
+/*
+ * TXRX control registers - base address 0x3000
+ */
+
+/*
+ * TXRX_CSR1:
+ * rt2860b  UNKNOWN reg use R/O Reg Addr 0x77d0 first..
+ */
+#define TXRX_CSR1                      0x77d0
+
+/*
+ * HW_DEBUG_SETTING_BASE:
+ * since NULL frame won't be that long (256 byte)
+ * We steal 16 tail bytes to save debugging settings
+ */
+#define HW_DEBUG_SETTING_BASE          0x77f0
+#define HW_DEBUG_SETTING_BASE2         0x7770
+
+/*
+ * HW_BEACON_BASE
+ * In order to support maximum 8 MBSS and its maximum length
+ * is 512 bytes for each beacon
+ * Three section discontinue memory segments will be used.
+ * 1. The original region for BCN 0~3
+ * 2. Extract memory from FCE table for BCN 4~5
+ * 3. Extract memory from Pair-wise key table for BCN 6~7
+ *    It occupied those memory of wcid 238~253 for BCN 6
+ *    and wcid 222~237 for BCN 7
+ *
+ * IMPORTANT NOTE: Not sure why legacy driver does this,
+ * but HW_BEACON_BASE7 is 0x0200 bytes below HW_BEACON_BASE6.
+ */
+#define HW_BEACON_BASE0                        0x7800
+#define HW_BEACON_BASE1                        0x7a00
+#define HW_BEACON_BASE2                        0x7c00
+#define HW_BEACON_BASE3                        0x7e00
+#define HW_BEACON_BASE4                        0x7200
+#define HW_BEACON_BASE5                        0x7400
+#define HW_BEACON_BASE6                        0x5dc0
+#define HW_BEACON_BASE7                        0x5bc0
+
+#define HW_BEACON_OFFSET(__index) \
+       ( ((__index) < 4) ? ( HW_BEACON_BASE0 + (__index * 0x0200) ) : \
+         (((__index) < 6) ? ( HW_BEACON_BASE4 + ((__index - 4) * 0x0200) ) : \
+         (HW_BEACON_BASE6 - ((__index - 6) * 0x0200))) )
+
+/*
+ * 8051 firmware image.
+ */
+#define FIRMWARE_RT2870                        "rt2870.bin"
+#define FIRMWARE_IMAGE_BASE            0x3000
+
+/*
+ * BBP registers.
+ * The wordsize of the BBP is 8 bits.
+ */
+
+/*
+ * BBP 1: TX Antenna
+ */
+#define BBP1_TX_POWER                  FIELD8(0x07)
+#define BBP1_TX_ANTENNA                        FIELD8(0x18)
+
+/*
+ * BBP 3: RX Antenna
+ */
+#define BBP3_RX_ANTENNA                        FIELD8(0x18)
+#define BBP3_HT40_PLUS                 FIELD8(0x20)
+
+/*
+ * BBP 4: Bandwidth
+ */
+#define BBP4_TX_BF                     FIELD8(0x01)
+#define BBP4_BANDWIDTH                 FIELD8(0x18)
+
+/*
+ * RFCSR registers
+ * The wordsize of the RFCSR is 8 bits.
+ */
+
+/*
+ * RFCSR 6:
+ */
+#define RFCSR6_R                       FIELD8(0x03)
+
+/*
+ * RFCSR 7:
+ */
+#define RFCSR7_RF_TUNING               FIELD8(0x01)
+
+/*
+ * RFCSR 12:
+ */
+#define RFCSR12_TX_POWER               FIELD8(0x1f)
+
+/*
+ * RFCSR 22:
+ */
+#define RFCSR22_BASEBAND_LOOPBACK      FIELD8(0x01)
+
+/*
+ * RFCSR 23:
+ */
+#define RFCSR23_FREQ_OFFSET            FIELD8(0x7f)
+
+/*
+ * RFCSR 30:
+ */
+#define RFCSR30_RF_CALIBRATION         FIELD8(0x80)
+
+/*
+ * RF registers
+ */
+
+/*
+ * RF 2
+ */
+#define RF2_ANTENNA_RX2                        FIELD32(0x00000040)
+#define RF2_ANTENNA_TX1                        FIELD32(0x00004000)
+#define RF2_ANTENNA_RX1                        FIELD32(0x00020000)
+
+/*
+ * RF 3
+ */
+#define RF3_TXPOWER_G                  FIELD32(0x00003e00)
+#define RF3_TXPOWER_A_7DBM_BOOST       FIELD32(0x00000200)
+#define RF3_TXPOWER_A                  FIELD32(0x00003c00)
+
+/*
+ * RF 4
+ */
+#define RF4_TXPOWER_G                  FIELD32(0x000007c0)
+#define RF4_TXPOWER_A_7DBM_BOOST       FIELD32(0x00000040)
+#define RF4_TXPOWER_A                  FIELD32(0x00000780)
+#define RF4_FREQ_OFFSET                        FIELD32(0x001f8000)
+#define RF4_HT40                       FIELD32(0x00200000)
+
+/*
+ * EEPROM content.
+ * The wordsize of the EEPROM is 16 bits.
+ */
+
+/*
+ * EEPROM Version
+ */
+#define EEPROM_VERSION                 0x0001
+#define EEPROM_VERSION_FAE             FIELD16(0x00ff)
+#define EEPROM_VERSION_VERSION         FIELD16(0xff00)
+
+/*
+ * HW MAC address.
+ */
+#define EEPROM_MAC_ADDR_0              0x0002
+#define EEPROM_MAC_ADDR_BYTE0          FIELD16(0x00ff)
+#define EEPROM_MAC_ADDR_BYTE1          FIELD16(0xff00)
+#define EEPROM_MAC_ADDR_1              0x0003
+#define EEPROM_MAC_ADDR_BYTE2          FIELD16(0x00ff)
+#define EEPROM_MAC_ADDR_BYTE3          FIELD16(0xff00)
+#define EEPROM_MAC_ADDR_2              0x0004
+#define EEPROM_MAC_ADDR_BYTE4          FIELD16(0x00ff)
+#define EEPROM_MAC_ADDR_BYTE5          FIELD16(0xff00)
+
+/*
+ * EEPROM ANTENNA config
+ * RXPATH: 1: 1R, 2: 2R, 3: 3R
+ * TXPATH: 1: 1T, 2: 2T
+ */
+#define        EEPROM_ANTENNA                  0x001a
+#define EEPROM_ANTENNA_RXPATH          FIELD16(0x000f)
+#define EEPROM_ANTENNA_TXPATH          FIELD16(0x00f0)
+#define EEPROM_ANTENNA_RF_TYPE         FIELD16(0x0f00)
+
+/*
+ * EEPROM NIC config
+ * CARDBUS_ACCEL: 0 - enable, 1 - disable
+ */
+#define        EEPROM_NIC                      0x001b
+#define EEPROM_NIC_HW_RADIO            FIELD16(0x0001)
+#define EEPROM_NIC_DYNAMIC_TX_AGC      FIELD16(0x0002)
+#define EEPROM_NIC_EXTERNAL_LNA_BG     FIELD16(0x0004)
+#define EEPROM_NIC_EXTERNAL_LNA_A      FIELD16(0x0008)
+#define EEPROM_NIC_CARDBUS_ACCEL       FIELD16(0x0010)
+#define EEPROM_NIC_BW40M_SB_BG         FIELD16(0x0020)
+#define EEPROM_NIC_BW40M_SB_A          FIELD16(0x0040)
+#define EEPROM_NIC_WPS_PBC             FIELD16(0x0080)
+#define EEPROM_NIC_BW40M_BG            FIELD16(0x0100)
+#define EEPROM_NIC_BW40M_A             FIELD16(0x0200)
+
+/*
+ * EEPROM frequency
+ */
+#define        EEPROM_FREQ                     0x001d
+#define EEPROM_FREQ_OFFSET             FIELD16(0x00ff)
+#define EEPROM_FREQ_LED_MODE           FIELD16(0x7f00)
+#define EEPROM_FREQ_LED_POLARITY       FIELD16(0x1000)
+
+/*
+ * EEPROM LED
+ * POLARITY_RDY_G: Polarity RDY_G setting.
+ * POLARITY_RDY_A: Polarity RDY_A setting.
+ * POLARITY_ACT: Polarity ACT setting.
+ * POLARITY_GPIO_0: Polarity GPIO0 setting.
+ * POLARITY_GPIO_1: Polarity GPIO1 setting.
+ * POLARITY_GPIO_2: Polarity GPIO2 setting.
+ * POLARITY_GPIO_3: Polarity GPIO3 setting.
+ * POLARITY_GPIO_4: Polarity GPIO4 setting.
+ * LED_MODE: Led mode.
+ */
+#define EEPROM_LED1                    0x001e
+#define EEPROM_LED2                    0x001f
+#define EEPROM_LED3                    0x0020
+#define EEPROM_LED_POLARITY_RDY_BG     FIELD16(0x0001)
+#define EEPROM_LED_POLARITY_RDY_A      FIELD16(0x0002)
+#define EEPROM_LED_POLARITY_ACT                FIELD16(0x0004)
+#define EEPROM_LED_POLARITY_GPIO_0     FIELD16(0x0008)
+#define EEPROM_LED_POLARITY_GPIO_1     FIELD16(0x0010)
+#define EEPROM_LED_POLARITY_GPIO_2     FIELD16(0x0020)
+#define EEPROM_LED_POLARITY_GPIO_3     FIELD16(0x0040)
+#define EEPROM_LED_POLARITY_GPIO_4     FIELD16(0x0080)
+#define EEPROM_LED_LED_MODE            FIELD16(0x1f00)
+
+/*
+ * EEPROM LNA
+ */
+#define EEPROM_LNA                     0x0022
+#define EEPROM_LNA_BG                  FIELD16(0x00ff)
+#define EEPROM_LNA_A0                  FIELD16(0xff00)
+
+/*
+ * EEPROM RSSI BG offset
+ */
+#define EEPROM_RSSI_BG                 0x0023
+#define EEPROM_RSSI_BG_OFFSET0         FIELD16(0x00ff)
+#define EEPROM_RSSI_BG_OFFSET1         FIELD16(0xff00)
+
+/*
+ * EEPROM RSSI BG2 offset
+ */
+#define EEPROM_RSSI_BG2                        0x0024
+#define EEPROM_RSSI_BG2_OFFSET2                FIELD16(0x00ff)
+#define EEPROM_RSSI_BG2_LNA_A1         FIELD16(0xff00)
+
+/*
+ * EEPROM RSSI A offset
+ */
+#define EEPROM_RSSI_A                  0x0025
+#define EEPROM_RSSI_A_OFFSET0          FIELD16(0x00ff)
+#define EEPROM_RSSI_A_OFFSET1          FIELD16(0xff00)
+
+/*
+ * EEPROM RSSI A2 offset
+ */
+#define EEPROM_RSSI_A2                 0x0026
+#define EEPROM_RSSI_A2_OFFSET2         FIELD16(0x00ff)
+#define EEPROM_RSSI_A2_LNA_A2          FIELD16(0xff00)
+
+/*
+ * EEPROM TXpower delta: 20MHZ AND 40 MHZ use different power.
+ *     This is delta in 40MHZ.
+ * VALUE: Tx Power dalta value (MAX=4)
+ * TYPE: 1: Plus the delta value, 0: minus the delta value
+ * TXPOWER: Enable:
+ */
+#define EEPROM_TXPOWER_DELTA           0x0028
+#define EEPROM_TXPOWER_DELTA_VALUE     FIELD16(0x003f)
+#define EEPROM_TXPOWER_DELTA_TYPE      FIELD16(0x0040)
+#define EEPROM_TXPOWER_DELTA_TXPOWER   FIELD16(0x0080)
+
+/*
+ * EEPROM TXPOWER 802.11BG
+ */
+#define        EEPROM_TXPOWER_BG1              0x0029
+#define        EEPROM_TXPOWER_BG2              0x0030
+#define EEPROM_TXPOWER_BG_SIZE         7
+#define EEPROM_TXPOWER_BG_1            FIELD16(0x00ff)
+#define EEPROM_TXPOWER_BG_2            FIELD16(0xff00)
+
+/*
+ * EEPROM TXPOWER 802.11A
+ */
+#define EEPROM_TXPOWER_A1              0x003c
+#define EEPROM_TXPOWER_A2              0x0053
+#define EEPROM_TXPOWER_A_SIZE          6
+#define EEPROM_TXPOWER_A_1             FIELD16(0x00ff)
+#define EEPROM_TXPOWER_A_2             FIELD16(0xff00)
+
+/*
+ * EEPROM TXpower byrate: 20MHZ power
+ */
+#define EEPROM_TXPOWER_BYRATE          0x006f
+
+/*
+ * EEPROM BBP.
+ */
+#define        EEPROM_BBP_START                0x0078
+#define EEPROM_BBP_SIZE                        16
+#define EEPROM_BBP_VALUE               FIELD16(0x00ff)
+#define EEPROM_BBP_REG_ID              FIELD16(0xff00)
+
+/*
+ * MCU mailbox commands.
+ */
+#define MCU_SLEEP                      0x30
+#define MCU_WAKEUP                     0x31
+#define MCU_RADIO_OFF                  0x35
+#define MCU_CURRENT                    0x36
+#define MCU_LED                                0x50
+#define MCU_LED_STRENGTH               0x51
+#define MCU_LED_1                      0x52
+#define MCU_LED_2                      0x53
+#define MCU_LED_3                      0x54
+#define MCU_RADAR                      0x60
+#define MCU_BOOT_SIGNAL                        0x72
+#define MCU_BBP_SIGNAL                 0x80
+#define MCU_POWER_SAVE                 0x83
+
+/*
+ * MCU mailbox tokens
+ */
+#define TOKEN_WAKUP                    3
+
+/*
+ * DMA descriptor defines.
+ */
+#define TXD_DESC_SIZE                  ( 4 * sizeof(__le32) )
+#define TXINFO_DESC_SIZE               ( 1 * sizeof(__le32) )
+#define TXWI_DESC_SIZE                 ( 4 * sizeof(__le32) )
+#define RXD_DESC_SIZE                  ( 1 * sizeof(__le32) )
+#define RXWI_DESC_SIZE                 ( 4 * sizeof(__le32) )
+
+/*
+ * TX descriptor format for TX, PRIO and Beacon Ring.
+ */
+
+/*
+ * Word0
+ */
+#define TXD_W0_SD_PTR0                 FIELD32(0xffffffff)
+
+/*
+ * Word1
+ */
+#define TXD_W1_SD_LEN1                 FIELD32(0x00003fff)
+#define TXD_W1_LAST_SEC1               FIELD32(0x00004000)
+#define TXD_W1_BURST                   FIELD32(0x00008000)
+#define TXD_W1_SD_LEN0                 FIELD32(0x3fff0000)
+#define TXD_W1_LAST_SEC0               FIELD32(0x40000000)
+#define TXD_W1_DMA_DONE                        FIELD32(0x80000000)
+
+/*
+ * Word2
+ */
+#define TXD_W2_SD_PTR1                 FIELD32(0xffffffff)
+
+/*
+ * Word3
+ * WIV: Wireless Info Valid. 1: Driver filled WI,  0: DMA needs to copy WI
+ * QSEL: Select on-chip FIFO ID for 2nd-stage output scheduler.
+ *       0:MGMT, 1:HCCA 2:EDCA
+ */
+#define TXD_W3_WIV                     FIELD32(0x01000000)
+#define TXD_W3_QSEL                    FIELD32(0x06000000)
+#define TXD_W3_TCO                     FIELD32(0x20000000)
+#define TXD_W3_UCO                     FIELD32(0x40000000)
+#define TXD_W3_ICO                     FIELD32(0x80000000)
+
+/*
+ * TX Info structure
+ */
+
+/*
+ * Word0
+ * WIV: Wireless Info Valid. 1: Driver filled WI,  0: DMA needs to copy WI
+ * QSEL: Select on-chip FIFO ID for 2nd-stage output scheduler.
+ *       0:MGMT, 1:HCCA 2:EDCA
+ * USB_DMA_NEXT_VALID: Used ONLY in USB bulk Aggregation, NextValid
+ * DMA_TX_BURST: used ONLY in USB bulk Aggregation.
+ *               Force USB DMA transmit frame from current selected endpoint
+ */
+#define TXINFO_W0_USB_DMA_TX_PKT_LEN   FIELD32(0x0000ffff)
+#define TXINFO_W0_WIV                  FIELD32(0x01000000)
+#define TXINFO_W0_QSEL                 FIELD32(0x06000000)
+#define TXINFO_W0_SW_USE_LAST_ROUND    FIELD32(0x08000000)
+#define TXINFO_W0_USB_DMA_NEXT_VALID   FIELD32(0x40000000)
+#define TXINFO_W0_USB_DMA_TX_BURST     FIELD32(0x80000000)
+
+/*
+ * TX WI structure
+ */
+
+/*
+ * Word0
+ * FRAG: 1 To inform TKIP engine this is a fragment.
+ * MIMO_PS: The remote peer is in dynamic MIMO-PS mode
+ * TX_OP: 0:HT TXOP rule , 1:PIFS TX ,2:Backoff, 3:sifs
+ * BW: Channel bandwidth 20MHz or 40 MHz
+ * STBC: 1: STBC support MCS =0-7, 2,3 : RESERVED
+ */
+#define TXWI_W0_FRAG                   FIELD32(0x00000001)
+#define TXWI_W0_MIMO_PS                        FIELD32(0x00000002)
+#define TXWI_W0_CF_ACK                 FIELD32(0x00000004)
+#define TXWI_W0_TS                     FIELD32(0x00000008)
+#define TXWI_W0_AMPDU                  FIELD32(0x00000010)
+#define TXWI_W0_MPDU_DENSITY           FIELD32(0x000000e0)
+#define TXWI_W0_TX_OP                  FIELD32(0x00000300)
+#define TXWI_W0_MCS                    FIELD32(0x007f0000)
+#define TXWI_W0_BW                     FIELD32(0x00800000)
+#define TXWI_W0_SHORT_GI               FIELD32(0x01000000)
+#define TXWI_W0_STBC                   FIELD32(0x06000000)
+#define TXWI_W0_IFS                    FIELD32(0x08000000)
+#define TXWI_W0_PHYMODE                        FIELD32(0xc0000000)
+
+/*
+ * Word1
+ */
+#define TXWI_W1_ACK                    FIELD32(0x00000001)
+#define TXWI_W1_NSEQ                   FIELD32(0x00000002)
+#define TXWI_W1_BW_WIN_SIZE            FIELD32(0x000000fc)
+#define TXWI_W1_WIRELESS_CLI_ID                FIELD32(0x0000ff00)
+#define TXWI_W1_MPDU_TOTAL_BYTE_COUNT  FIELD32(0x0fff0000)
+#define TXWI_W1_PACKETID               FIELD32(0xf0000000)
+
+/*
+ * Word2
+ */
+#define TXWI_W2_IV                     FIELD32(0xffffffff)
+
+/*
+ * Word3
+ */
+#define TXWI_W3_EIV                    FIELD32(0xffffffff)
+
+/*
+ * RX descriptor format for RX Ring.
+ */
+
+/*
+ * Word0
+ * UNICAST_TO_ME: This RX frame is unicast to me.
+ * MULTICAST: This is a multicast frame.
+ * BROADCAST: This is a broadcast frame.
+ * MY_BSS: this frame belongs to the same BSSID.
+ * CRC_ERROR: CRC error.
+ * CIPHER_ERROR: 0: decryption okay, 1:ICV error, 2:MIC error, 3:KEY not valid.
+ * AMSDU: rx with 802.3 header, not 802.11 header.
+ */
+
+#define RXD_W0_BA                      FIELD32(0x00000001)
+#define RXD_W0_DATA                    FIELD32(0x00000002)
+#define RXD_W0_NULLDATA                        FIELD32(0x00000004)
+#define RXD_W0_FRAG                    FIELD32(0x00000008)
+#define RXD_W0_UNICAST_TO_ME           FIELD32(0x00000010)
+#define RXD_W0_MULTICAST               FIELD32(0x00000020)
+#define RXD_W0_BROADCAST               FIELD32(0x00000040)
+#define RXD_W0_MY_BSS                  FIELD32(0x00000080)
+#define RXD_W0_CRC_ERROR               FIELD32(0x00000100)
+#define RXD_W0_CIPHER_ERROR            FIELD32(0x00000600)
+#define RXD_W0_AMSDU                   FIELD32(0x00000800)
+#define RXD_W0_HTC                     FIELD32(0x00001000)
+#define RXD_W0_RSSI                    FIELD32(0x00002000)
+#define RXD_W0_L2PAD                   FIELD32(0x00004000)
+#define RXD_W0_AMPDU                   FIELD32(0x00008000)
+#define RXD_W0_DECRYPTED               FIELD32(0x00010000)
+#define RXD_W0_PLCP_RSSI               FIELD32(0x00020000)
+#define RXD_W0_CIPHER_ALG              FIELD32(0x00040000)
+#define RXD_W0_LAST_AMSDU              FIELD32(0x00080000)
+#define RXD_W0_PLCP_SIGNAL             FIELD32(0xfff00000)
+
+/*
+ * RX WI structure
+ */
+
+/*
+ * Word0
+ */
+#define RXWI_W0_WIRELESS_CLI_ID                FIELD32(0x000000ff)
+#define RXWI_W0_KEY_INDEX              FIELD32(0x00000300)
+#define RXWI_W0_BSSID                  FIELD32(0x00001c00)
+#define RXWI_W0_UDF                    FIELD32(0x0000e000)
+#define RXWI_W0_MPDU_TOTAL_BYTE_COUNT  FIELD32(0x0fff0000)
+#define RXWI_W0_TID                    FIELD32(0xf0000000)
+
+/*
+ * Word1
+ */
+#define RXWI_W1_FRAG                   FIELD32(0x0000000f)
+#define RXWI_W1_SEQUENCE               FIELD32(0x0000fff0)
+#define RXWI_W1_MCS                    FIELD32(0x007f0000)
+#define RXWI_W1_BW                     FIELD32(0x00800000)
+#define RXWI_W1_SHORT_GI               FIELD32(0x01000000)
+#define RXWI_W1_STBC                   FIELD32(0x06000000)
+#define RXWI_W1_PHYMODE                        FIELD32(0xc0000000)
+
+/*
+ * Word2
+ */
+#define RXWI_W2_RSSI0                  FIELD32(0x000000ff)
+#define RXWI_W2_RSSI1                  FIELD32(0x0000ff00)
+#define RXWI_W2_RSSI2                  FIELD32(0x00ff0000)
+
+/*
+ * Word3
+ */
+#define RXWI_W3_SNR0                   FIELD32(0x000000ff)
+#define RXWI_W3_SNR1                   FIELD32(0x0000ff00)
+
+/*
+ * Macro's for converting txpower from EEPROM to mac80211 value
+ * and from mac80211 value to register value.
+ */
+#define MIN_G_TXPOWER  0
+#define MIN_A_TXPOWER  -7
+#define MAX_G_TXPOWER  31
+#define MAX_A_TXPOWER  15
+#define DEFAULT_TXPOWER        5
+
+#define TXPOWER_G_FROM_DEV(__txpower) \
+       ((__txpower) > MAX_G_TXPOWER) ? DEFAULT_TXPOWER : (__txpower)
+
+#define TXPOWER_G_TO_DEV(__txpower) \
+       clamp_t(char, __txpower, MIN_G_TXPOWER, MAX_G_TXPOWER)
+
+#define TXPOWER_A_FROM_DEV(__txpower) \
+       ((__txpower) > MAX_A_TXPOWER) ? DEFAULT_TXPOWER : (__txpower)
+
+#define TXPOWER_A_TO_DEV(__txpower) \
+       clamp_t(char, __txpower, MIN_A_TXPOWER, MAX_A_TXPOWER)
+
+#endif /* RT2800USB_H */
index 84bd6f19acb0749be1dd6200a99fbe595ca8da49..a498dde024e1b58c55555e00d349a5cc28846218 100644 (file)
 #define GET_DURATION(__size, __rate)   (((__size) * 8 * 10) / (__rate))
 #define GET_DURATION_RES(__size, __rate)(((__size) * 8 * 10) % (__rate))
 
+/*
+ * Determine the alignment requirement,
+ * to make sure the 802.11 payload is padded to a 4-byte boundrary
+ * we must determine the address of the payload and calculate the
+ * amount of bytes needed to move the data.
+ */
+#define ALIGN_SIZE(__skb, __header) \
+       (  ((unsigned long)((__skb)->data + (__header))) & 3 )
+
 /*
  * Standard timing and size defines.
  * These values should follow the ieee80211 specifications.
@@ -138,6 +147,7 @@ struct rt2x00_chip {
 #define RT2561         0x0302
 #define RT2661         0x0401
 #define RT2571         0x1300
+#define RT2870         0x1600
 
        u16 rf;
        u32 rev;
@@ -357,6 +367,7 @@ static inline struct rt2x00_intf* vif_to_intf(struct ieee80211_vif *vif)
  *     for @tx_power_a, @tx_power_bg and @channels.
  * @channels: Device/chipset specific channel values (See &struct rf_channel).
  * @channels_info: Additional information for channels (See &struct channel_info).
+ * @ht: Driver HT Capabilities (See &ieee80211_sta_ht_cap).
  */
 struct hw_mode_spec {
        unsigned int supported_bands;
@@ -370,6 +381,8 @@ struct hw_mode_spec {
        unsigned int num_channels;
        const struct rf_channel *channels;
        const struct channel_info *channels_info;
+
+       struct ieee80211_sta_ht_cap ht;
 };
 
 /*
@@ -404,6 +417,8 @@ struct rt2x00lib_erp {
        short pifs;
        short difs;
        short eifs;
+
+       u16 beacon_int;
 };
 
 /*
@@ -590,6 +605,7 @@ enum rt2x00_flags {
        DRIVER_REQUIRE_SCHEDULED,
        DRIVER_REQUIRE_DMA,
        DRIVER_REQUIRE_COPY_IV,
+       DRIVER_REQUIRE_L2PAD,
 
        /*
         * Driver features
@@ -606,6 +622,7 @@ enum rt2x00_flags {
        CONFIG_EXTERNAL_LNA_BG,
        CONFIG_DOUBLE_ANTENNA,
        CONFIG_DISABLE_LINK_TUNING,
+       CONFIG_CHANNEL_HT40,
 };
 
 /*
@@ -671,6 +688,12 @@ struct rt2x00_dev {
         */
        unsigned long flags;
 
+       /*
+        * Device information, Bus IRQ and name (PCI, SoC)
+        */
+       int irq;
+       const char *name;
+
        /*
         * Chipset identification.
         */
@@ -771,6 +794,18 @@ struct rt2x00_dev {
         */
        u8 freq_offset;
 
+       /*
+        * Calibration information (for rt2800usb & rt2800pci).
+        * [0] -> BW20
+        * [1] -> BW40
+        */
+       u8 calibration[2];
+
+       /*
+        * Beacon interval.
+        */
+       u16 beacon_int;
+
        /*
         * Low level statistics which will have
         * to be kept up to date while device is running.
@@ -860,6 +895,18 @@ static inline void rt2x00_set_chip(struct rt2x00_dev *rt2x00dev,
        rt2x00dev->chip.rev = rev;
 }
 
+static inline void rt2x00_set_chip_rt(struct rt2x00_dev *rt2x00dev,
+                                     const u16 rt)
+{
+       rt2x00dev->chip.rt = rt;
+}
+
+static inline void rt2x00_set_chip_rf(struct rt2x00_dev *rt2x00dev,
+                                     const u16 rf, const u32 rev)
+{
+       rt2x00_set_chip(rt2x00dev, rt2x00dev->chip.rt, rf, rev);
+}
+
 static inline char rt2x00_rt(const struct rt2x00_chip *chipset, const u16 chip)
 {
        return (chipset->rt == chip);
@@ -875,11 +922,10 @@ static inline u32 rt2x00_rev(const struct rt2x00_chip *chipset)
        return chipset->rev;
 }
 
-static inline u16 rt2x00_check_rev(const struct rt2x00_chip *chipset,
-                                  const u32 rev)
+static inline bool rt2x00_check_rev(const struct rt2x00_chip *chipset,
+                                   const u32 mask, const u32 rev)
 {
-       return (((chipset->rev & 0xffff0) == rev) &&
-               !!(chipset->rev & 0x0000f));
+       return ((chipset->rev & mask) == rev);
 }
 
 /**
@@ -925,9 +971,6 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw,
 void rt2x00mac_remove_interface(struct ieee80211_hw *hw,
                                struct ieee80211_if_init_conf *conf);
 int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed);
-int rt2x00mac_config_interface(struct ieee80211_hw *hw,
-                              struct ieee80211_vif *vif,
-                              struct ieee80211_if_conf *conf);
 void rt2x00mac_configure_filter(struct ieee80211_hw *hw,
                                unsigned int changed_flags,
                                unsigned int *total_flags,
index 9c2f5517af2a453784dc8cd6e96a92279ff6311d..3e019a12df2e092ec783630df7f457556768887f 100644 (file)
@@ -106,6 +106,10 @@ void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev,
        }
 
        erp.basic_rates = bss_conf->basic_rates;
+       erp.beacon_int = bss_conf->beacon_int;
+
+       /* Update global beacon interval time, this is needed for PS support */
+       rt2x00dev->beacon_int = bss_conf->beacon_int;
 
        rt2x00dev->ops->lib->config_erp(rt2x00dev, &erp);
 }
@@ -173,6 +177,11 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
        libconf.conf = conf;
 
        if (ieee80211_flags & IEEE80211_CONF_CHANGE_CHANNEL) {
+               if (conf_is_ht40(conf))
+                       __set_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags);
+               else
+                       __clear_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags);
+
                memcpy(&libconf.rf,
                       &rt2x00dev->spec.channels[conf->channel->hw_value],
                       sizeof(libconf.rf));
index 0b41845d9543a1653d3893e22d7f4c56d1719c35..bc4e81e21841f4dce988fff13f30d1063312de5d 100644 (file)
@@ -33,7 +33,7 @@ enum cipher rt2x00crypto_key_to_cipher(struct ieee80211_key_conf *key)
 {
        switch (key->alg) {
        case ALG_WEP:
-               if (key->keylen == LEN_WEP40)
+               if (key->keylen == WLAN_KEY_LEN_WEP40)
                        return CIPHER_WEP64;
                else
                        return CIPHER_WEP128;
@@ -65,7 +65,8 @@ void rt2x00crypto_create_tx_descriptor(struct queue_entry *entry,
                __set_bit(ENTRY_TXD_ENCRYPT_PAIRWISE, &txdesc->flags);
 
        txdesc->key_idx = hw_key->hw_key_idx;
-       txdesc->iv_offset = ieee80211_get_hdrlen_from_skb(entry->skb);
+       txdesc->iv_offset = txdesc->header_length;
+       txdesc->iv_len = hw_key->iv_len;
 
        if (!(hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV))
                __set_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc->flags);
@@ -103,47 +104,44 @@ unsigned int rt2x00crypto_tx_overhead(struct rt2x00_dev *rt2x00dev,
        return overhead;
 }
 
-void rt2x00crypto_tx_copy_iv(struct sk_buff *skb, unsigned int iv_len)
+void rt2x00crypto_tx_copy_iv(struct sk_buff *skb, struct txentry_desc *txdesc)
 {
        struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
-       unsigned int header_length = ieee80211_get_hdrlen_from_skb(skb);
 
-       if (unlikely(!iv_len))
+       if (unlikely(!txdesc->iv_len))
                return;
 
        /* Copy IV/EIV data */
-       memcpy(skbdesc->iv, skb->data + header_length, iv_len);
+       memcpy(skbdesc->iv, skb->data + txdesc->iv_offset, txdesc->iv_len);
 }
 
-void rt2x00crypto_tx_remove_iv(struct sk_buff *skb, unsigned int iv_len)
+void rt2x00crypto_tx_remove_iv(struct sk_buff *skb, struct txentry_desc *txdesc)
 {
        struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
-       unsigned int header_length = ieee80211_get_hdrlen_from_skb(skb);
 
-       if (unlikely(!iv_len))
+       if (unlikely(!txdesc->iv_len))
                return;
 
        /* Copy IV/EIV data */
-       memcpy(skbdesc->iv, skb->data + header_length, iv_len);
+       memcpy(skbdesc->iv, skb->data + txdesc->iv_offset, txdesc->iv_len);
 
        /* Move ieee80211 header */
-       memmove(skb->data + iv_len, skb->data, header_length);
+       memmove(skb->data + txdesc->iv_len, skb->data, txdesc->iv_offset);
 
        /* Pull buffer to correct size */
-       skb_pull(skb, iv_len);
+       skb_pull(skb, txdesc->iv_len);
 
        /* IV/EIV data has officially be stripped */
-       skbdesc->flags |= FRAME_DESC_IV_STRIPPED;
+       skbdesc->flags |= SKBDESC_IV_STRIPPED;
 }
 
-void rt2x00crypto_tx_insert_iv(struct sk_buff *skb)
+void rt2x00crypto_tx_insert_iv(struct sk_buff *skb, unsigned int header_length)
 {
        struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
-       unsigned int header_length = ieee80211_get_hdrlen_from_skb(skb);
        const unsigned int iv_len =
            ((!!(skbdesc->iv[0])) * 4) + ((!!(skbdesc->iv[1])) * 4);
 
-       if (!(skbdesc->flags & FRAME_DESC_IV_STRIPPED))
+       if (!(skbdesc->flags & SKBDESC_IV_STRIPPED))
                return;
 
        skb_push(skb, iv_len);
@@ -155,14 +153,15 @@ void rt2x00crypto_tx_insert_iv(struct sk_buff *skb)
        memcpy(skb->data + header_length, skbdesc->iv, iv_len);
 
        /* IV/EIV data has returned into the frame */
-       skbdesc->flags &= ~FRAME_DESC_IV_STRIPPED;
+       skbdesc->flags &= ~SKBDESC_IV_STRIPPED;
 }
 
-void rt2x00crypto_rx_insert_iv(struct sk_buff *skb, unsigned int align,
+void rt2x00crypto_rx_insert_iv(struct sk_buff *skb, bool l2pad,
                               unsigned int header_length,
                               struct rxdone_entry_desc *rxdesc)
 {
        unsigned int payload_len = rxdesc->size - header_length;
+       unsigned int align = ALIGN_SIZE(skb, header_length);
        unsigned int iv_len;
        unsigned int icv_len;
        unsigned int transfer = 0;
@@ -192,32 +191,48 @@ void rt2x00crypto_rx_insert_iv(struct sk_buff *skb, unsigned int align,
        }
 
        /*
-        * Make room for new data, note that we increase both
-        * headsize and tailsize when required. The tailsize is
-        * only needed when ICV data needs to be inserted and
-        * the padding is smaller than the ICV data.
-        * When alignment requirements is greater than the
-        * ICV data we must trim the skb to the correct size
-        * because we need to remove the extra bytes.
+        * Make room for new data. There are 2 possibilities
+        * either the alignment is already present between
+        * the 802.11 header and payload. In that case we
+        * we have to move the header less then the iv_len
+        * since we can use the already available l2pad bytes
+        * for the iv data.
+        * When the alignment must be added manually we must
+        * move the header more then iv_len since we must
+        * make room for the payload move as well.
         */
-       skb_push(skb, iv_len + align);
-       if (align < icv_len)
-               skb_put(skb, icv_len - align);
-       else if (align > icv_len)
-               skb_trim(skb, rxdesc->size + iv_len + icv_len);
+       if (l2pad) {
+               skb_push(skb, iv_len - align);
+               skb_put(skb, icv_len);
 
-       /* Move ieee80211 header */
-       memmove(skb->data + transfer,
-               skb->data + transfer + iv_len + align,
-               header_length);
-       transfer += header_length;
+               /* Move ieee80211 header */
+               memmove(skb->data + transfer,
+                       skb->data + transfer + (iv_len - align),
+                       header_length);
+               transfer += header_length;
+       } else {
+               skb_push(skb, iv_len + align);
+               if (align < icv_len)
+                       skb_put(skb, icv_len - align);
+               else if (align > icv_len)
+                       skb_trim(skb, rxdesc->size + iv_len + icv_len);
+
+               /* Move ieee80211 header */
+               memmove(skb->data + transfer,
+                       skb->data + transfer + iv_len + align,
+                       header_length);
+               transfer += header_length;
+       }
 
        /* Copy IV/EIV data */
        memcpy(skb->data + transfer, rxdesc->iv, iv_len);
        transfer += iv_len;
 
-       /* Move payload */
-       if (align) {
+       /*
+        * Move payload for alignment purposes. Note that
+        * this is only needed when no l2 padding is present.
+        */
+       if (!l2pad) {
                memmove(skb->data + transfer,
                        skb->data + transfer + align,
                        payload_len);
index 5752aaae906bbca29ffd81514c897abedc93fc29..57813e72c80875feda793d915c4709f05753b359 100644 (file)
@@ -227,6 +227,7 @@ void rt2x00lib_txdone(struct queue_entry *entry,
        struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
        struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
        enum data_queue_qid qid = skb_get_queue_mapping(entry->skb);
+       unsigned int header_length = ieee80211_get_hdrlen_from_skb(entry->skb);
        u8 rate_idx, rate_flags;
 
        /*
@@ -234,6 +235,12 @@ void rt2x00lib_txdone(struct queue_entry *entry,
         */
        rt2x00queue_unmap_skb(rt2x00dev, entry->skb);
 
+       /*
+        * Remove L2 padding which was added during
+        */
+       if (test_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags))
+               rt2x00queue_payload_align(entry->skb, true, header_length);
+
        /*
         * If the IV/EIV data was stripped from the frame before it was
         * passed to the hardware, we should now reinsert it again because
@@ -241,7 +248,7 @@ void rt2x00lib_txdone(struct queue_entry *entry,
         * frame as it was passed to us.
         */
        if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags))
-               rt2x00crypto_tx_insert_iv(entry->skb);
+               rt2x00crypto_tx_insert_iv(entry->skb, header_length);
 
        /*
         * Send frame to debugfs immediately, after this call is completed
@@ -253,7 +260,8 @@ void rt2x00lib_txdone(struct queue_entry *entry,
         * Update TX statistics.
         */
        rt2x00dev->link.qual.tx_success +=
-           test_bit(TXDONE_SUCCESS, &txdesc->flags);
+           test_bit(TXDONE_SUCCESS, &txdesc->flags) ||
+           test_bit(TXDONE_UNKNOWN, &txdesc->flags);
        rt2x00dev->link.qual.tx_failed +=
            test_bit(TXDONE_FAILURE, &txdesc->flags);
 
@@ -271,14 +279,16 @@ void rt2x00lib_txdone(struct queue_entry *entry,
        tx_info->status.rates[1].idx = -1; /* terminate */
 
        if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK)) {
-               if (test_bit(TXDONE_SUCCESS, &txdesc->flags))
+               if (test_bit(TXDONE_SUCCESS, &txdesc->flags) ||
+                               test_bit(TXDONE_UNKNOWN, &txdesc->flags))
                        tx_info->flags |= IEEE80211_TX_STAT_ACK;
                else if (test_bit(TXDONE_FAILURE, &txdesc->flags))
                        rt2x00dev->low_level_stats.dot11ACKFailureCount++;
        }
 
        if (rate_flags & IEEE80211_TX_RC_USE_RTS_CTS) {
-               if (test_bit(TXDONE_SUCCESS, &txdesc->flags))
+               if (test_bit(TXDONE_SUCCESS, &txdesc->flags) ||
+                               test_bit(TXDONE_UNKNOWN, &txdesc->flags))
                        rt2x00dev->low_level_stats.dot11RTSSuccessCount++;
                else if (test_bit(TXDONE_FAILURE, &txdesc->flags))
                        rt2x00dev->low_level_stats.dot11RTSFailureCount++;
@@ -316,19 +326,54 @@ void rt2x00lib_txdone(struct queue_entry *entry,
 }
 EXPORT_SYMBOL_GPL(rt2x00lib_txdone);
 
+static int rt2x00lib_rxdone_read_signal(struct rt2x00_dev *rt2x00dev,
+                                       struct rxdone_entry_desc *rxdesc)
+{
+       struct ieee80211_supported_band *sband;
+       const struct rt2x00_rate *rate;
+       unsigned int i;
+       int signal;
+       int type;
+
+       /*
+        * For non-HT rates the MCS value needs to contain the
+        * actually used rate modulation (CCK or OFDM).
+        */
+       if (rxdesc->dev_flags & RXDONE_SIGNAL_MCS)
+               signal = RATE_MCS(rxdesc->rate_mode, rxdesc->signal);
+       else
+               signal = rxdesc->signal;
+
+       type = (rxdesc->dev_flags & RXDONE_SIGNAL_MASK);
+
+       sband = &rt2x00dev->bands[rt2x00dev->curr_band];
+       for (i = 0; i < sband->n_bitrates; i++) {
+               rate = rt2x00_get_rate(sband->bitrates[i].hw_value);
+
+               if (((type == RXDONE_SIGNAL_PLCP) &&
+                    (rate->plcp == signal)) ||
+                   ((type == RXDONE_SIGNAL_BITRATE) &&
+                     (rate->bitrate == signal)) ||
+                   ((type == RXDONE_SIGNAL_MCS) &&
+                     (rate->mcs == signal))) {
+                       return i;
+               }
+       }
+
+       WARNING(rt2x00dev, "Frame received with unrecognized signal, "
+               "signal=0x%.4x, type=%d.\n", signal, type);
+       return 0;
+}
+
 void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
                      struct queue_entry *entry)
 {
        struct rxdone_entry_desc rxdesc;
        struct sk_buff *skb;
        struct ieee80211_rx_status *rx_status = &rt2x00dev->rx_status;
-       struct ieee80211_supported_band *sband;
-       const struct rt2x00_rate *rate;
        unsigned int header_length;
-       unsigned int align;
-       unsigned int i;
-       int idx = -1;
-
+       bool l2pad;
+       int rate_idx;
        /*
         * Allocate a new sk_buffer. If no new buffer available, drop the
         * received frame and reuse the existing buffer.
@@ -348,12 +393,15 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
        memset(&rxdesc, 0, sizeof(rxdesc));
        rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc);
 
+       /* Trim buffer to correct size */
+       skb_trim(entry->skb, rxdesc.size);
+
        /*
         * The data behind the ieee80211 header must be
         * aligned on a 4 byte boundary.
         */
        header_length = ieee80211_get_hdrlen_from_skb(entry->skb);
-       align = ((unsigned long)(entry->skb->data + header_length)) & 3;
+       l2pad = !!(rxdesc.dev_flags & RXDONE_L2PAD);
 
        /*
         * Hardware might have stripped the IV/EIV/ICV data,
@@ -362,40 +410,24 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
         * in which case we should reinsert the data into the frame.
         */
        if ((rxdesc.dev_flags & RXDONE_CRYPTO_IV) &&
-           (rxdesc.flags & RX_FLAG_IV_STRIPPED)) {
-               rt2x00crypto_rx_insert_iv(entry->skb, align,
-                                         header_length, &rxdesc);
-       } else if (align) {
-               skb_push(entry->skb, align);
-               /* Move entire frame in 1 command */
-               memmove(entry->skb->data, entry->skb->data + align,
-                       rxdesc.size);
-       }
-
-       /* Update data pointers, trim buffer to correct size */
-       skb_trim(entry->skb, rxdesc.size);
+           (rxdesc.flags & RX_FLAG_IV_STRIPPED))
+               rt2x00crypto_rx_insert_iv(entry->skb, l2pad, header_length,
+                                         &rxdesc);
+       else
+               rt2x00queue_payload_align(entry->skb, l2pad, header_length);
 
        /*
-        * Update RX statistics.
+        * Check if the frame was received using HT. In that case,
+        * the rate is the MCS index and should be passed to mac80211
+        * directly. Otherwise we need to translate the signal to
+        * the correct bitrate index.
         */
-       sband = &rt2x00dev->bands[rt2x00dev->curr_band];
-       for (i = 0; i < sband->n_bitrates; i++) {
-               rate = rt2x00_get_rate(sband->bitrates[i].hw_value);
-
-               if (((rxdesc.dev_flags & RXDONE_SIGNAL_PLCP) &&
-                    (rate->plcp == rxdesc.signal)) ||
-                   ((rxdesc.dev_flags & RXDONE_SIGNAL_BITRATE) &&
-                     (rate->bitrate == rxdesc.signal))) {
-                       idx = i;
-                       break;
-               }
-       }
-
-       if (idx < 0) {
-               WARNING(rt2x00dev, "Frame received with unrecognized signal,"
-                       "signal=0x%.2x, type=%d.\n", rxdesc.signal,
-                       (rxdesc.dev_flags & RXDONE_SIGNAL_MASK));
-               idx = 0;
+       if (rxdesc.rate_mode == RATE_MODE_CCK ||
+           rxdesc.rate_mode == RATE_MODE_OFDM) {
+               rate_idx = rt2x00lib_rxdone_read_signal(rt2x00dev, &rxdesc);
+       } else {
+               rxdesc.flags |= RX_FLAG_HT;
+               rate_idx = rxdesc.signal;
        }
 
        /*
@@ -405,7 +437,7 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
        rt2x00debug_update_crypto(rt2x00dev, &rxdesc);
 
        rx_status->mactime = rxdesc.timestamp;
-       rx_status->rate_idx = idx;
+       rx_status->rate_idx = rate_idx;
        rx_status->qual = rt2x00link_calculate_signal(rt2x00dev, rxdesc.rssi);
        rx_status->signal = rxdesc.rssi;
        rx_status->noise = rxdesc.noise;
@@ -440,72 +472,84 @@ const struct rt2x00_rate rt2x00_supported_rates[12] = {
                .bitrate = 10,
                .ratemask = BIT(0),
                .plcp = 0x00,
+               .mcs = RATE_MCS(RATE_MODE_CCK, 0),
        },
        {
                .flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE,
                .bitrate = 20,
                .ratemask = BIT(1),
                .plcp = 0x01,
+               .mcs = RATE_MCS(RATE_MODE_CCK, 1),
        },
        {
                .flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE,
                .bitrate = 55,
                .ratemask = BIT(2),
                .plcp = 0x02,
+               .mcs = RATE_MCS(RATE_MODE_CCK, 2),
        },
        {
                .flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE,
                .bitrate = 110,
                .ratemask = BIT(3),
                .plcp = 0x03,
+               .mcs = RATE_MCS(RATE_MODE_CCK, 3),
        },
        {
                .flags = DEV_RATE_OFDM,
                .bitrate = 60,
                .ratemask = BIT(4),
                .plcp = 0x0b,
+               .mcs = RATE_MCS(RATE_MODE_OFDM, 0),
        },
        {
                .flags = DEV_RATE_OFDM,
                .bitrate = 90,
                .ratemask = BIT(5),
                .plcp = 0x0f,
+               .mcs = RATE_MCS(RATE_MODE_OFDM, 1),
        },
        {
                .flags = DEV_RATE_OFDM,
                .bitrate = 120,
                .ratemask = BIT(6),
                .plcp = 0x0a,
+               .mcs = RATE_MCS(RATE_MODE_OFDM, 2),
        },
        {
                .flags = DEV_RATE_OFDM,
                .bitrate = 180,
                .ratemask = BIT(7),
                .plcp = 0x0e,
+               .mcs = RATE_MCS(RATE_MODE_OFDM, 3),
        },
        {
                .flags = DEV_RATE_OFDM,
                .bitrate = 240,
                .ratemask = BIT(8),
                .plcp = 0x09,
+               .mcs = RATE_MCS(RATE_MODE_OFDM, 4),
        },
        {
                .flags = DEV_RATE_OFDM,
                .bitrate = 360,
                .ratemask = BIT(9),
                .plcp = 0x0d,
+               .mcs = RATE_MCS(RATE_MODE_OFDM, 5),
        },
        {
                .flags = DEV_RATE_OFDM,
                .bitrate = 480,
                .ratemask = BIT(10),
                .plcp = 0x08,
+               .mcs = RATE_MCS(RATE_MODE_OFDM, 6),
        },
        {
                .flags = DEV_RATE_OFDM,
                .bitrate = 540,
                .ratemask = BIT(11),
                .plcp = 0x0c,
+               .mcs = RATE_MCS(RATE_MODE_OFDM, 7),
        },
 };
 
@@ -581,6 +625,8 @@ static int rt2x00lib_probe_hw_modes(struct rt2x00_dev *rt2x00dev,
                rt2x00dev->bands[IEEE80211_BAND_2GHZ].bitrates = rates;
                hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
                    &rt2x00dev->bands[IEEE80211_BAND_2GHZ];
+               memcpy(&rt2x00dev->bands[IEEE80211_BAND_2GHZ].ht_cap,
+                      &spec->ht, sizeof(spec->ht));
        }
 
        /*
@@ -597,6 +643,8 @@ static int rt2x00lib_probe_hw_modes(struct rt2x00_dev *rt2x00dev,
                rt2x00dev->bands[IEEE80211_BAND_5GHZ].bitrates = &rates[4];
                hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
                    &rt2x00dev->bands[IEEE80211_BAND_5GHZ];
+               memcpy(&rt2x00dev->bands[IEEE80211_BAND_5GHZ].ht_cap,
+                      &spec->ht, sizeof(spec->ht));
        }
 
        return 0;
diff --git a/drivers/net/wireless/rt2x00/rt2x00ht.c b/drivers/net/wireless/rt2x00/rt2x00ht.c
new file mode 100644 (file)
index 0000000..e3cec83
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+       Copyright (C) 2004 - 2009 rt2x00 SourceForge Project
+       <http://rt2x00.serialmonkey.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.
+
+       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.
+ */
+
+/*
+       Module: rt2x00lib
+       Abstract: rt2x00 HT specific routines.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include "rt2x00.h"
+#include "rt2x00lib.h"
+
+void rt2x00ht_create_tx_descriptor(struct queue_entry *entry,
+                                  struct txentry_desc *txdesc,
+                                  const struct rt2x00_rate *hwrate)
+{
+       struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
+       struct ieee80211_tx_rate *txrate = &tx_info->control.rates[0];
+
+       if (tx_info->control.sta)
+               txdesc->mpdu_density =
+                   tx_info->control.sta->ht_cap.ampdu_density;
+       else
+               txdesc->mpdu_density = 0;
+
+       txdesc->ba_size = 7;    /* FIXME: What value is needed? */
+       txdesc->stbc = 0;       /* FIXME: What value is needed? */
+
+       txdesc->mcs = rt2x00_get_rate_mcs(hwrate->mcs);
+       if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
+               txdesc->mcs |= 0x08;
+
+       /*
+        * Convert flags
+        */
+       if (tx_info->flags & IEEE80211_TX_CTL_AMPDU)
+               __set_bit(ENTRY_TXD_HT_AMPDU, &txdesc->flags);
+
+       /*
+        * Determine HT Mix/Greenfield rate mode
+        */
+       if (txrate->flags & IEEE80211_TX_RC_MCS)
+               txdesc->rate_mode = RATE_MODE_HT_MIX;
+       if (txrate->flags & IEEE80211_TX_RC_GREEN_FIELD)
+               txdesc->rate_mode = RATE_MODE_HT_GREENFIELD;
+       if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
+               __set_bit(ENTRY_TXD_HT_BW_40, &txdesc->flags);
+       if (txrate->flags & IEEE80211_TX_RC_SHORT_GI)
+               __set_bit(ENTRY_TXD_HT_SHORT_GI, &txdesc->flags);
+}
index d83e3794d340fd3d6a78abdf24c67128b596e51b..0bf2715fa93a7bc59bf437ffad5237ccb686bdfc 100644 (file)
@@ -32,8 +32,8 @@
  * Interval defines
  * Both the link tuner as the rfkill will be called once per second.
  */
-#define LINK_TUNE_INTERVAL     ( round_jiffies_relative(HZ) )
-#define RFKILL_POLL_INTERVAL   ( 1000 )
+#define LINK_TUNE_INTERVAL     round_jiffies_relative(HZ)
+#define RFKILL_POLL_INTERVAL   1000
 
 /*
  * rt2x00_rate: Per rate device information
@@ -48,6 +48,7 @@ struct rt2x00_rate {
        unsigned short ratemask;
 
        unsigned short plcp;
+       unsigned short mcs;
 };
 
 extern const struct rt2x00_rate rt2x00_supported_rates[12];
@@ -57,6 +58,14 @@ static inline const struct rt2x00_rate *rt2x00_get_rate(const u16 hw_value)
        return &rt2x00_supported_rates[hw_value & 0xff];
 }
 
+#define RATE_MCS(__mode, __mcs) \
+       ( (((__mode) & 0x00ff) << 8) | ((__mcs) & 0x00ff) )
+
+static inline int rt2x00_get_rate_mcs(const u16 mcs_value)
+{
+       return (mcs_value & 0x00ff);
+}
+
 /*
  * Radio control handlers.
  */
@@ -112,6 +121,23 @@ void rt2x00queue_unmap_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb);
  */
 void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb);
 
+/**
+ * rt2x00queue_payload_align - Align 802.11 payload to 4-byte boundary
+ * @skb: The skb to align
+ * @l2pad: Should L2 padding be used
+ * @header_length: Length of 802.11 header
+ *
+ * This function prepares the @skb to be send to the device or mac80211.
+ * If @l2pad is set to true padding will occur between the 802.11 header
+ * and payload. Otherwise the padding will be done in front of the 802.11
+ * header.
+ * When @l2pad is set the function will check for the &SKBDESC_L2_PADDED
+ * flag in &skb_frame_desc. If that flag is set, the padding is removed
+ * and the flag cleared. Otherwise the padding is added and the flag is set.
+ */
+void rt2x00queue_payload_align(struct sk_buff *skb,
+                              bool l2pad, unsigned int header_length);
+
 /**
  * rt2x00queue_write_tx_frame - Write TX frame to hardware
  * @queue: Queue over which the frame should be send
@@ -295,10 +321,12 @@ void rt2x00crypto_create_tx_descriptor(struct queue_entry *entry,
                                       struct txentry_desc *txdesc);
 unsigned int rt2x00crypto_tx_overhead(struct rt2x00_dev *rt2x00dev,
                                      struct sk_buff *skb);
-void rt2x00crypto_tx_copy_iv(struct sk_buff *skb, unsigned int iv_len);
-void rt2x00crypto_tx_remove_iv(struct sk_buff *skb, unsigned int iv_len);
-void rt2x00crypto_tx_insert_iv(struct sk_buff *skb);
-void rt2x00crypto_rx_insert_iv(struct sk_buff *skb, unsigned int align,
+void rt2x00crypto_tx_copy_iv(struct sk_buff *skb,
+                            struct txentry_desc *txdesc);
+void rt2x00crypto_tx_remove_iv(struct sk_buff *skb,
+                              struct txentry_desc *txdesc);
+void rt2x00crypto_tx_insert_iv(struct sk_buff *skb, unsigned int header_length);
+void rt2x00crypto_rx_insert_iv(struct sk_buff *skb, bool l2pad,
                               unsigned int header_length,
                               struct rxdone_entry_desc *rxdesc);
 #else
@@ -319,27 +347,42 @@ static inline unsigned int rt2x00crypto_tx_overhead(struct rt2x00_dev *rt2x00dev
 }
 
 static inline void rt2x00crypto_tx_copy_iv(struct sk_buff *skb,
-                                          unsigned int iv_len)
+                                          struct txentry_desc *txdesc)
 {
 }
 
 static inline void rt2x00crypto_tx_remove_iv(struct sk_buff *skb,
-                                            unsigned int iv_len)
+                                            struct txentry_desc *txdesc)
 {
 }
 
-static inline void rt2x00crypto_tx_insert_iv(struct sk_buff *skb)
+static inline void rt2x00crypto_tx_insert_iv(struct sk_buff *skb,
+                                            unsigned int header_length)
 {
 }
 
-static inline void rt2x00crypto_rx_insert_iv(struct sk_buff *skb,
-                                            unsigned int align,
+static inline void rt2x00crypto_rx_insert_iv(struct sk_buff *skb, bool l2pad,
                                             unsigned int header_length,
                                             struct rxdone_entry_desc *rxdesc)
 {
 }
 #endif /* CONFIG_RT2X00_LIB_CRYPTO */
 
+/*
+ * HT handlers.
+ */
+#ifdef CONFIG_RT2X00_LIB_HT
+void rt2x00ht_create_tx_descriptor(struct queue_entry *entry,
+                                  struct txentry_desc *txdesc,
+                                  const struct rt2x00_rate *hwrate);
+#else
+static inline void rt2x00ht_create_tx_descriptor(struct queue_entry *entry,
+                                                struct txentry_desc *txdesc,
+                                                const struct rt2x00_rate *hwrate)
+{
+}
+#endif /* CONFIG_RT2X00_LIB_HT */
+
 /*
  * RFkill handlers.
  */
index 7eb5cd7e5f32424ea97474b57e009374a212da29..eb9b981b9139f2ff976a47095a2a7202d8ab2aa5 100644 (file)
@@ -387,7 +387,7 @@ void rt2x00link_reset_tuner(struct rt2x00_dev *rt2x00dev, bool antenna)
                rt2x00link_antenna_reset(rt2x00dev);
 }
 
-void rt2x00link_reset_qual(struct rt2x00_dev *rt2x00dev)
+static void rt2x00link_reset_qual(struct rt2x00_dev *rt2x00dev)
 {
        struct link_qual *qual = &rt2x00dev->link.qual;
 
index c41a0b9e473dc90e95a597a8a8d7ee404a64001c..c4c06b4e1f086ee1d0d30c482231526f4f5b0a71 100644 (file)
@@ -390,56 +390,6 @@ int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed)
 }
 EXPORT_SYMBOL_GPL(rt2x00mac_config);
 
-int rt2x00mac_config_interface(struct ieee80211_hw *hw,
-                              struct ieee80211_vif *vif,
-                              struct ieee80211_if_conf *conf)
-{
-       struct rt2x00_dev *rt2x00dev = hw->priv;
-       struct rt2x00_intf *intf = vif_to_intf(vif);
-       int update_bssid = 0;
-       int status = 0;
-
-       /*
-        * Mac80211 might be calling this function while we are trying
-        * to remove the device or perhaps suspending it.
-        */
-       if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
-               return 0;
-
-       spin_lock(&intf->lock);
-
-       /*
-        * conf->bssid can be NULL if coming from the internal
-        * beacon update routine.
-        */
-       if (conf->changed & IEEE80211_IFCC_BSSID && conf->bssid) {
-               update_bssid = 1;
-               memcpy(&intf->bssid, conf->bssid, ETH_ALEN);
-       }
-
-       spin_unlock(&intf->lock);
-
-       /*
-        * Call rt2x00_config_intf() outside of the spinlock context since
-        * the call will sleep for USB drivers. By using the ieee80211_if_conf
-        * values as arguments we make keep access to rt2x00_intf thread safe
-        * even without the lock.
-        */
-       rt2x00lib_config_intf(rt2x00dev, intf, vif->type, NULL,
-                             update_bssid ? conf->bssid : NULL);
-
-       /*
-        * Update the beacon.
-        */
-       if (conf->changed & (IEEE80211_IFCC_BEACON |
-                            IEEE80211_IFCC_BEACON_ENABLED))
-               status = rt2x00queue_update_beacon(rt2x00dev, vif,
-                                                  conf->enable_beacon);
-
-       return status;
-}
-EXPORT_SYMBOL_GPL(rt2x00mac_config_interface);
-
 void rt2x00mac_configure_filter(struct ieee80211_hw *hw,
                                unsigned int changed_flags,
                                unsigned int *total_flags,
@@ -623,6 +573,44 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
        struct rt2x00_dev *rt2x00dev = hw->priv;
        struct rt2x00_intf *intf = vif_to_intf(vif);
        unsigned int delayed = 0;
+       int update_bssid = 0;
+
+       /*
+        * Mac80211 might be calling this function while we are trying
+        * to remove the device or perhaps suspending it.
+        */
+       if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
+               return;
+
+       spin_lock(&intf->lock);
+
+       /*
+        * conf->bssid can be NULL if coming from the internal
+        * beacon update routine.
+        */
+       if (changes & BSS_CHANGED_BSSID) {
+               update_bssid = 1;
+               memcpy(&intf->bssid, bss_conf->bssid, ETH_ALEN);
+       }
+
+       spin_unlock(&intf->lock);
+
+       /*
+        * Call rt2x00_config_intf() outside of the spinlock context since
+        * the call will sleep for USB drivers. By using the ieee80211_if_conf
+        * values as arguments we make keep access to rt2x00_intf thread safe
+        * even without the lock.
+        */
+       if (changes & BSS_CHANGED_BSSID)
+               rt2x00lib_config_intf(rt2x00dev, intf, vif->type, NULL,
+                                     update_bssid ? bss_conf->bssid : NULL);
+
+       /*
+        * Update the beacon.
+        */
+       if (changes & (BSS_CHANGED_BEACON | BSS_CHANGED_BEACON_ENABLED))
+               rt2x00queue_update_beacon(rt2x00dev, vif,
+                                         bss_conf->enable_beacon);
 
        /*
         * When the association status has changed we must reset the link
index 9730b4f8fd268d029756a56de15774e224102fc9..cdd5154bd4c05faa5065d3ff286ad6cfa93bd642 100644 (file)
@@ -170,7 +170,6 @@ static void rt2x00pci_free_queue_dma(struct rt2x00_dev *rt2x00dev,
 
 int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev)
 {
-       struct pci_dev *pci_dev = to_pci_dev(rt2x00dev->dev);
        struct data_queue *queue;
        int status;
 
@@ -186,11 +185,11 @@ int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev)
        /*
         * Register interrupt handler.
         */
-       status = request_irq(pci_dev->irq, rt2x00dev->ops->lib->irq_handler,
-                            IRQF_SHARED, pci_name(pci_dev), rt2x00dev);
+       status = request_irq(rt2x00dev->irq, rt2x00dev->ops->lib->irq_handler,
+                            IRQF_SHARED, rt2x00dev->name, rt2x00dev);
        if (status) {
                ERROR(rt2x00dev, "IRQ %d allocation failed (error %d).\n",
-                     pci_dev->irq, status);
+                     rt2x00dev->irq, status);
                goto exit;
        }
 
@@ -270,6 +269,7 @@ int rt2x00pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *id)
        struct ieee80211_hw *hw;
        struct rt2x00_dev *rt2x00dev;
        int retval;
+       u16 chip;
 
        retval = pci_request_regions(pci_dev, pci_name(pci_dev));
        if (retval) {
@@ -307,6 +307,14 @@ int rt2x00pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *id)
        rt2x00dev->dev = &pci_dev->dev;
        rt2x00dev->ops = ops;
        rt2x00dev->hw = hw;
+       rt2x00dev->irq = pci_dev->irq;
+       rt2x00dev->name = pci_name(pci_dev);
+
+       /*
+        * Determine RT chipset by reading PCI header.
+        */
+       pci_read_config_word(pci_dev, PCI_DEVICE_ID, &chip);
+       rt2x00_set_chip_rt(rt2x00dev, chip);
 
        retval = rt2x00pci_alloc_reg(rt2x00dev);
        if (retval)
index a5664bd8493e878062e32bd4e0ec055800faad79..44e5b3279ca76e4e515eb7926f65562e29ad8bbb 100644 (file)
@@ -148,6 +148,35 @@ void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb)
        dev_kfree_skb_any(skb);
 }
 
+void rt2x00queue_payload_align(struct sk_buff *skb,
+                              bool l2pad, unsigned int header_length)
+{
+       struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
+       unsigned int frame_length = skb->len;
+       unsigned int align = ALIGN_SIZE(skb, header_length);
+
+       if (!align)
+               return;
+
+       if (l2pad) {
+               if (skbdesc->flags & SKBDESC_L2_PADDED) {
+                       /* Remove L2 padding */
+                       memmove(skb->data + align, skb->data, header_length);
+                       skb_pull(skb, align);
+                       skbdesc->flags &= ~SKBDESC_L2_PADDED;
+               } else {
+                       /* Add L2 padding */
+                       skb_push(skb, align);
+                       memmove(skb->data, skb->data + align, header_length);
+                       skbdesc->flags |= SKBDESC_L2_PADDED;
+               }
+       } else {
+               /* Generic payload alignment to 4-byte boundary */
+               skb_push(skb, align);
+               memmove(skb->data, skb->data + align, frame_length);
+       }
+}
+
 static void rt2x00queue_create_tx_descriptor_seq(struct queue_entry *entry,
                                                 struct txentry_desc *txdesc)
 {
@@ -258,6 +287,12 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
        txdesc->cw_max = entry->queue->cw_max;
        txdesc->aifs = entry->queue->aifs;
 
+       /*
+        * Header and alignment information.
+        */
+       txdesc->header_length = ieee80211_get_hdrlen_from_skb(entry->skb);
+       txdesc->l2pad = ALIGN_SIZE(entry->skb, txdesc->header_length);
+
        /*
         * Check whether this frame is to be acked.
         */
@@ -326,6 +361,7 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
         * Apply TX descriptor handling by components
         */
        rt2x00crypto_create_tx_descriptor(entry, txdesc);
+       rt2x00ht_create_tx_descriptor(entry, txdesc, hwrate);
        rt2x00queue_create_tx_descriptor_seq(entry, txdesc);
        rt2x00queue_create_tx_descriptor_plcp(entry, txdesc, hwrate);
 }
@@ -368,7 +404,6 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb)
        struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX);
        struct txentry_desc txdesc;
        struct skb_frame_desc *skbdesc;
-       unsigned int iv_len = 0;
        u8 rate_idx, rate_flags;
 
        if (unlikely(rt2x00queue_full(queue)))
@@ -390,9 +425,6 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb)
        entry->skb = skb;
        rt2x00queue_create_tx_descriptor(entry, &txdesc);
 
-       if (IEEE80211_SKB_CB(skb)->control.hw_key != NULL)
-               iv_len = IEEE80211_SKB_CB(skb)->control.hw_key->iv_len;
-
        /*
         * All information is retrieved from the skb->cb array,
         * now we should claim ownership of the driver part of that
@@ -415,11 +447,15 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb)
        if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc.flags) &&
            !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc.flags)) {
                if (test_bit(DRIVER_REQUIRE_COPY_IV, &queue->rt2x00dev->flags))
-                       rt2x00crypto_tx_copy_iv(skb, iv_len);
+                       rt2x00crypto_tx_copy_iv(skb, &txdesc);
                else
-                       rt2x00crypto_tx_remove_iv(skb, iv_len);
+                       rt2x00crypto_tx_remove_iv(skb, &txdesc);
        }
 
+       if (test_bit(DRIVER_REQUIRE_L2PAD, &queue->rt2x00dev->flags))
+               rt2x00queue_payload_align(entry->skb, true,
+                                         txdesc.header_length);
+
        /*
         * It could be possible that the queue was corrupted and this
         * call failed. Since we always return NETDEV_TX_OK to mac80211,
index 97e2ab08f080153bf1576d14701d4b18e1650437..b5e06347c8a7cc699b2b7c44ae2548def3ff7641 100644 (file)
  * for USB devices this restriction does not apply, but the value of
  * 2432 makes sense since it is big enough to contain the maximum fragment
  * size according to the ieee802.11 specs.
+ * The aggregation size depends on support from the driver, but should
+ * be something around 3840 bytes.
  */
-#define DATA_FRAME_SIZE        2432
-#define MGMT_FRAME_SIZE        256
+#define DATA_FRAME_SIZE                2432
+#define MGMT_FRAME_SIZE                256
+#define AGGREGATION_SIZE       3840
 
 /**
  * DOC: Number of entries per queue
@@ -87,13 +90,16 @@ enum data_queue_qid {
  *
  * @SKBDESC_DMA_MAPPED_RX: &skb_dma field has been mapped for RX
  * @SKBDESC_DMA_MAPPED_TX: &skb_dma field has been mapped for TX
- * @FRAME_DESC_IV_STRIPPED: Frame contained a IV/EIV provided by
+ * @SKBDESC_IV_STRIPPED: Frame contained a IV/EIV provided by
  *     mac80211 but was stripped for processing by the driver.
+ * @SKBDESC_L2_PADDED: Payload has been padded for 4-byte alignment,
+ *     the padded bytes are located between header and payload.
  */
 enum skb_frame_desc_flags {
        SKBDESC_DMA_MAPPED_RX = 1 << 0,
        SKBDESC_DMA_MAPPED_TX = 1 << 1,
-       FRAME_DESC_IV_STRIPPED = 1 << 2,
+       SKBDESC_IV_STRIPPED = 1 << 2,
+       SKBDESC_L2_PADDED = 1 << 3
 };
 
 /**
@@ -145,16 +151,20 @@ static inline struct skb_frame_desc* get_skb_frame_desc(struct sk_buff *skb)
  *
  * @RXDONE_SIGNAL_PLCP: Signal field contains the plcp value.
  * @RXDONE_SIGNAL_BITRATE: Signal field contains the bitrate value.
+ * @RXDONE_SIGNAL_MCS: Signal field contains the mcs value.
  * @RXDONE_MY_BSS: Does this frame originate from device's BSS.
  * @RXDONE_CRYPTO_IV: Driver provided IV/EIV data.
  * @RXDONE_CRYPTO_ICV: Driver provided ICV data.
+ * @RXDONE_L2PAD: 802.11 payload has been padded to 4-byte boundary.
  */
 enum rxdone_entry_desc_flags {
-       RXDONE_SIGNAL_PLCP = 1 << 0,
-       RXDONE_SIGNAL_BITRATE = 1 << 1,
-       RXDONE_MY_BSS = 1 << 2,
-       RXDONE_CRYPTO_IV = 1 << 3,
-       RXDONE_CRYPTO_ICV = 1 << 4,
+       RXDONE_SIGNAL_PLCP = BIT(0),
+       RXDONE_SIGNAL_BITRATE = BIT(1),
+       RXDONE_SIGNAL_MCS = BIT(2),
+       RXDONE_MY_BSS = BIT(3),
+       RXDONE_CRYPTO_IV = BIT(4),
+       RXDONE_CRYPTO_ICV = BIT(5),
+       RXDONE_L2PAD = BIT(6),
 };
 
 /**
@@ -163,7 +173,7 @@ enum rxdone_entry_desc_flags {
  * from &rxdone_entry_desc to a signal value type.
  */
 #define RXDONE_SIGNAL_MASK \
-       ( RXDONE_SIGNAL_PLCP | RXDONE_SIGNAL_BITRATE )
+       ( RXDONE_SIGNAL_PLCP | RXDONE_SIGNAL_BITRATE | RXDONE_SIGNAL_MCS )
 
 /**
  * struct rxdone_entry_desc: RX Entry descriptor
@@ -177,6 +187,7 @@ enum rxdone_entry_desc_flags {
  * @size: Data size of the received frame.
  * @flags: MAC80211 receive flags (See &enum mac80211_rx_flags).
  * @dev_flags: Ralink receive flags (See &enum rxdone_entry_desc_flags).
+ * @rate_mode: Rate mode (See @enum rate_modulation).
  * @cipher: Cipher type used during decryption.
  * @cipher_status: Decryption status.
  * @iv: IV/EIV data used during decryption.
@@ -190,6 +201,7 @@ struct rxdone_entry_desc {
        int size;
        int flags;
        int dev_flags;
+       u16 rate_mode;
        u8 cipher;
        u8 cipher_status;
 
@@ -243,6 +255,9 @@ struct txdone_entry_desc {
  * @ENTRY_TXD_ENCRYPT_PAIRWISE: Use pairwise key table (instead of shared).
  * @ENTRY_TXD_ENCRYPT_IV: Generate IV/EIV in hardware.
  * @ENTRY_TXD_ENCRYPT_MMIC: Generate MIC in hardware.
+ * @ENTRY_TXD_HT_AMPDU: This frame is part of an AMPDU.
+ * @ENTRY_TXD_HT_BW_40: Use 40MHz Bandwidth.
+ * @ENTRY_TXD_HT_SHORT_GI: Use short GI.
  */
 enum txentry_desc_flags {
        ENTRY_TXD_RTS_FRAME,
@@ -258,6 +273,9 @@ enum txentry_desc_flags {
        ENTRY_TXD_ENCRYPT_PAIRWISE,
        ENTRY_TXD_ENCRYPT_IV,
        ENTRY_TXD_ENCRYPT_MMIC,
+       ENTRY_TXD_HT_AMPDU,
+       ENTRY_TXD_HT_BW_40,
+       ENTRY_TXD_HT_SHORT_GI,
 };
 
 /**
@@ -267,11 +285,17 @@ enum txentry_desc_flags {
  *
  * @flags: Descriptor flags (See &enum queue_entry_flags).
  * @queue: Queue identification (See &enum data_queue_qid).
+ * @header_length: Length of 802.11 header.
+ * @l2pad: Amount of padding to align 802.11 payload to 4-byte boundrary.
  * @length_high: PLCP length high word.
  * @length_low: PLCP length low word.
  * @signal: PLCP signal.
  * @service: PLCP service.
+ * @msc: MCS.
+ * @stbc: STBC.
+ * @ba_size: BA size.
  * @rate_mode: Rate mode (See @enum rate_modulation).
+ * @mpdu_density: MDPU density.
  * @retry_limit: Max number of retries.
  * @aifs: AIFS value.
  * @ifs: IFS value.
@@ -280,18 +304,26 @@ enum txentry_desc_flags {
  * @cipher: Cipher type used for encryption.
  * @key_idx: Key index used for encryption.
  * @iv_offset: Position where IV should be inserted by hardware.
+ * @iv_len: Length of IV data.
  */
 struct txentry_desc {
        unsigned long flags;
 
        enum data_queue_qid queue;
 
+       u16 header_length;
+       u16 l2pad;
+
        u16 length_high;
        u16 length_low;
        u16 signal;
        u16 service;
 
+       u16 mcs;
+       u16 stbc;
+       u16 ba_size;
        u16 rate_mode;
+       u16 mpdu_density;
 
        short retry_limit;
        short aifs;
@@ -302,6 +334,7 @@ struct txentry_desc {
        enum cipher cipher;
        u16 key_idx;
        u16 iv_offset;
+       u16 iv_len;
 };
 
 /**
index 2ca8b7a9722c96f8dfd6b7ad0689d1738d143145..49b29ff90c47acdf70dfaf06c01f02036d6916d3 100644 (file)
@@ -603,15 +603,22 @@ static void rt61pci_config_erp(struct rt2x00_dev *rt2x00dev,
 
        rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, &reg);
        rt2x00_set_field32(&reg, TXRX_CSR0_RX_ACK_TIMEOUT, erp->ack_timeout);
+       rt2x00_set_field32(&reg, TXRX_CSR0_TSF_OFFSET, IEEE80211_HEADER);
        rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg);
 
        rt2x00pci_register_read(rt2x00dev, TXRX_CSR4, &reg);
+       rt2x00_set_field32(&reg, TXRX_CSR4_AUTORESPOND_ENABLE, 1);
        rt2x00_set_field32(&reg, TXRX_CSR4_AUTORESPOND_PREAMBLE,
                           !!erp->short_preamble);
        rt2x00pci_register_write(rt2x00dev, TXRX_CSR4, reg);
 
        rt2x00pci_register_write(rt2x00dev, TXRX_CSR5, erp->basic_rates);
 
+       rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, &reg);
+       rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_INTERVAL,
+                          erp->beacon_int * 16);
+       rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg);
+
        rt2x00pci_register_read(rt2x00dev, MAC_CSR9, &reg);
        rt2x00_set_field32(&reg, MAC_CSR9_SLOT_TIME, erp->slot_time);
        rt2x00pci_register_write(rt2x00dev, MAC_CSR9, reg);
@@ -938,25 +945,6 @@ static void rt61pci_config_retry_limit(struct rt2x00_dev *rt2x00dev,
        rt2x00pci_register_write(rt2x00dev, TXRX_CSR4, reg);
 }
 
-static void rt61pci_config_duration(struct rt2x00_dev *rt2x00dev,
-                                   struct rt2x00lib_conf *libconf)
-{
-       u32 reg;
-
-       rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, &reg);
-       rt2x00_set_field32(&reg, TXRX_CSR0_TSF_OFFSET, IEEE80211_HEADER);
-       rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg);
-
-       rt2x00pci_register_read(rt2x00dev, TXRX_CSR4, &reg);
-       rt2x00_set_field32(&reg, TXRX_CSR4_AUTORESPOND_ENABLE, 1);
-       rt2x00pci_register_write(rt2x00dev, TXRX_CSR4, reg);
-
-       rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, &reg);
-       rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_INTERVAL,
-                          libconf->conf->beacon_int * 16);
-       rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg);
-}
-
 static void rt61pci_config_ps(struct rt2x00_dev *rt2x00dev,
                                struct rt2x00lib_conf *libconf)
 {
@@ -968,7 +956,7 @@ static void rt61pci_config_ps(struct rt2x00_dev *rt2x00dev,
        if (state == STATE_SLEEP) {
                rt2x00pci_register_read(rt2x00dev, MAC_CSR11, &reg);
                rt2x00_set_field32(&reg, MAC_CSR11_DELAY_AFTER_TBCN,
-                                  libconf->conf->beacon_int - 10);
+                                  rt2x00dev->beacon_int - 10);
                rt2x00_set_field32(&reg, MAC_CSR11_TBCN_BEFORE_WAKEUP,
                                   libconf->conf->listen_interval - 1);
                rt2x00_set_field32(&reg, MAC_CSR11_WAKEUP_LATENCY, 5);
@@ -1016,8 +1004,6 @@ static void rt61pci_config(struct rt2x00_dev *rt2x00dev,
                rt61pci_config_txpower(rt2x00dev, libconf->conf->power_level);
        if (flags & IEEE80211_CONF_CHANGE_RETRY_LIMITS)
                rt61pci_config_retry_limit(rt2x00dev, libconf);
-       if (flags & IEEE80211_CONF_CHANGE_BEACON_INTERVAL)
-               rt61pci_config_duration(rt2x00dev, libconf);
        if (flags & IEEE80211_CONF_CHANGE_PS)
                rt61pci_config_ps(rt2x00dev, libconf);
 }
@@ -2308,7 +2294,6 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
        u32 reg;
        u16 value;
        u16 eeprom;
-       u16 device;
 
        /*
         * Read EEPROM word for configuration.
@@ -2317,14 +2302,10 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
 
        /*
         * Identify RF chipset.
-        * To determine the RT chip we have to read the
-        * PCI header of the device.
         */
-       pci_read_config_word(to_pci_dev(rt2x00dev->dev),
-                            PCI_CONFIG_HEADER_DEVICE, &device);
        value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE);
        rt2x00pci_register_read(rt2x00dev, MAC_CSR0, &reg);
-       rt2x00_set_chip(rt2x00dev, device, value, reg);
+       rt2x00_set_chip_rf(rt2x00dev, value, reg);
 
        if (!rt2x00_rf(&rt2x00dev->chip, RF5225) &&
            !rt2x00_rf(&rt2x00dev->chip, RF5325) &&
@@ -2740,7 +2721,6 @@ static const struct ieee80211_ops rt61pci_mac80211_ops = {
        .add_interface          = rt2x00mac_add_interface,
        .remove_interface       = rt2x00mac_remove_interface,
        .config                 = rt2x00mac_config,
-       .config_interface       = rt2x00mac_config_interface,
        .configure_filter       = rt2x00mac_configure_filter,
        .set_key                = rt2x00mac_set_key,
        .get_stats              = rt2x00mac_get_stats,
index 41e8959919f6dd897dc49133ab51027e9f0192f6..6c71f77c8165803b90033e77addde041367c9fee 100644 (file)
  * PCI registers.
  */
 
-/*
- * PCI Configuration Header
- */
-#define PCI_CONFIG_HEADER_VENDOR       0x0000
-#define PCI_CONFIG_HEADER_DEVICE       0x0002
-
 /*
  * HOST_CMD_CSR: For HOST to interrupt embedded processor
  */
index 853b2b279b647bf4112fffdeb50e60a5d569ae28..c18848836f2dac86e9abb0289175bfcb0712cbc6 100644 (file)
@@ -566,15 +566,22 @@ static void rt73usb_config_erp(struct rt2x00_dev *rt2x00dev,
 
        rt2x00usb_register_read(rt2x00dev, TXRX_CSR0, &reg);
        rt2x00_set_field32(&reg, TXRX_CSR0_RX_ACK_TIMEOUT, erp->ack_timeout);
+       rt2x00_set_field32(&reg, TXRX_CSR0_TSF_OFFSET, IEEE80211_HEADER);
        rt2x00usb_register_write(rt2x00dev, TXRX_CSR0, reg);
 
        rt2x00usb_register_read(rt2x00dev, TXRX_CSR4, &reg);
+       rt2x00_set_field32(&reg, TXRX_CSR4_AUTORESPOND_ENABLE, 1);
        rt2x00_set_field32(&reg, TXRX_CSR4_AUTORESPOND_PREAMBLE,
                           !!erp->short_preamble);
        rt2x00usb_register_write(rt2x00dev, TXRX_CSR4, reg);
 
        rt2x00usb_register_write(rt2x00dev, TXRX_CSR5, erp->basic_rates);
 
+       rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, &reg);
+       rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_INTERVAL,
+                          erp->beacon_int * 16);
+       rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg);
+
        rt2x00usb_register_read(rt2x00dev, MAC_CSR9, &reg);
        rt2x00_set_field32(&reg, MAC_CSR9_SLOT_TIME, erp->slot_time);
        rt2x00usb_register_write(rt2x00dev, MAC_CSR9, reg);
@@ -834,25 +841,6 @@ static void rt73usb_config_retry_limit(struct rt2x00_dev *rt2x00dev,
        rt2x00usb_register_write(rt2x00dev, TXRX_CSR4, reg);
 }
 
-static void rt73usb_config_duration(struct rt2x00_dev *rt2x00dev,
-                                   struct rt2x00lib_conf *libconf)
-{
-       u32 reg;
-
-       rt2x00usb_register_read(rt2x00dev, TXRX_CSR0, &reg);
-       rt2x00_set_field32(&reg, TXRX_CSR0_TSF_OFFSET, IEEE80211_HEADER);
-       rt2x00usb_register_write(rt2x00dev, TXRX_CSR0, reg);
-
-       rt2x00usb_register_read(rt2x00dev, TXRX_CSR4, &reg);
-       rt2x00_set_field32(&reg, TXRX_CSR4_AUTORESPOND_ENABLE, 1);
-       rt2x00usb_register_write(rt2x00dev, TXRX_CSR4, reg);
-
-       rt2x00usb_register_read(rt2x00dev, TXRX_CSR9, &reg);
-       rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_INTERVAL,
-                          libconf->conf->beacon_int * 16);
-       rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg);
-}
-
 static void rt73usb_config_ps(struct rt2x00_dev *rt2x00dev,
                                struct rt2x00lib_conf *libconf)
 {
@@ -864,7 +852,7 @@ static void rt73usb_config_ps(struct rt2x00_dev *rt2x00dev,
        if (state == STATE_SLEEP) {
                rt2x00usb_register_read(rt2x00dev, MAC_CSR11, &reg);
                rt2x00_set_field32(&reg, MAC_CSR11_DELAY_AFTER_TBCN,
-                                  libconf->conf->beacon_int - 10);
+                                  rt2x00dev->beacon_int - 10);
                rt2x00_set_field32(&reg, MAC_CSR11_TBCN_BEFORE_WAKEUP,
                                   libconf->conf->listen_interval - 1);
                rt2x00_set_field32(&reg, MAC_CSR11_WAKEUP_LATENCY, 5);
@@ -906,8 +894,6 @@ static void rt73usb_config(struct rt2x00_dev *rt2x00dev,
                rt73usb_config_txpower(rt2x00dev, libconf->conf->power_level);
        if (flags & IEEE80211_CONF_CHANGE_RETRY_LIMITS)
                rt73usb_config_retry_limit(rt2x00dev, libconf);
-       if (flags & IEEE80211_CONF_CHANGE_BEACON_INTERVAL)
-               rt73usb_config_duration(rt2x00dev, libconf);
        if (flags & IEEE80211_CONF_CHANGE_PS)
                rt73usb_config_ps(rt2x00dev, libconf);
 }
@@ -1846,7 +1832,8 @@ static int rt73usb_init_eeprom(struct rt2x00_dev *rt2x00dev)
        rt2x00usb_register_read(rt2x00dev, MAC_CSR0, &reg);
        rt2x00_set_chip(rt2x00dev, RT2571, value, reg);
 
-       if (!rt2x00_check_rev(&rt2x00dev->chip, 0x25730)) {
+       if (!rt2x00_check_rev(&rt2x00dev->chip, 0x000ffff0, 0x25730) ||
+           rt2x00_check_rev(&rt2x00dev->chip, 0x0000000f, 0)) {
                ERROR(rt2x00dev, "Invalid RT chipset detected.\n");
                return -ENODEV;
        }
@@ -2259,7 +2246,6 @@ static const struct ieee80211_ops rt73usb_mac80211_ops = {
        .add_interface          = rt2x00mac_add_interface,
        .remove_interface       = rt2x00mac_remove_interface,
        .config                 = rt2x00mac_config,
-       .config_interface       = rt2x00mac_config_interface,
        .configure_filter       = rt2x00mac_configure_filter,
        .set_key                = rt2x00mac_set_key,
        .get_stats              = rt2x00mac_get_stats,
index c113b3e690467fccfa266f92ab42da8a0e3275fb..37e3d4db0c40cda78c0dd82cda08d9d74c918b80 100644 (file)
@@ -1,5 +1,5 @@
 rtl8180-objs           := rtl8180_dev.o rtl8180_rtl8225.o rtl8180_sa2400.o rtl8180_max2820.o rtl8180_grf5101.o
-rtl8187-objs           := rtl8187_dev.o rtl8187_rtl8225.o
+rtl8187-objs           := rtl8187_dev.o rtl8187_rtl8225.o rtl8187_leds.o
 
 obj-$(CONFIG_RTL8180)  += rtl8180.o
 obj-$(CONFIG_RTL8187)  += rtl8187.o
index 387c133ec0f2629413da721c09fdc3253326c359..7e65d7c31802097ff7194430589e6b10e0705e46 100644 (file)
@@ -702,30 +702,26 @@ static int rtl8180_config(struct ieee80211_hw *dev, u32 changed)
        return 0;
 }
 
-static int rtl8180_config_interface(struct ieee80211_hw *dev,
-                                   struct ieee80211_vif *vif,
-                                   struct ieee80211_if_conf *conf)
-{
-       struct rtl8180_priv *priv = dev->priv;
-       int i;
-
-       for (i = 0; i < ETH_ALEN; i++)
-               rtl818x_iowrite8(priv, &priv->map->BSSID[i], conf->bssid[i]);
-
-       if (is_valid_ether_addr(conf->bssid))
-               rtl818x_iowrite8(priv, &priv->map->MSR, RTL818X_MSR_INFRA);
-       else
-               rtl818x_iowrite8(priv, &priv->map->MSR, RTL818X_MSR_NO_LINK);
-
-       return 0;
-}
-
 static void rtl8180_bss_info_changed(struct ieee80211_hw *dev,
                                     struct ieee80211_vif *vif,
                                     struct ieee80211_bss_conf *info,
                                     u32 changed)
 {
        struct rtl8180_priv *priv = dev->priv;
+       int i;
+
+       if (changed & BSS_CHANGED_BSSID) {
+               for (i = 0; i < ETH_ALEN; i++)
+                       rtl818x_iowrite8(priv, &priv->map->BSSID[i],
+                                        info->bssid[i]);
+
+               if (is_valid_ether_addr(info->bssid))
+                       rtl818x_iowrite8(priv, &priv->map->MSR,
+                                        RTL818X_MSR_INFRA);
+               else
+                       rtl818x_iowrite8(priv, &priv->map->MSR,
+                                        RTL818X_MSR_NO_LINK);
+       }
 
        if (changed & BSS_CHANGED_ERP_SLOT && priv->rf->conf_erp)
                priv->rf->conf_erp(dev, info);
@@ -770,7 +766,6 @@ static const struct ieee80211_ops rtl8180_ops = {
        .add_interface          = rtl8180_add_interface,
        .remove_interface       = rtl8180_remove_interface,
        .config                 = rtl8180_config,
-       .config_interface       = rtl8180_config_interface,
        .bss_info_changed       = rtl8180_bss_info_changed,
        .configure_filter       = rtl8180_configure_filter,
 };
index edeff82a4d0670e6305f26d6bca85d26533c44c9..c09bfefc70f366acdd1b53c76b92024574b7b6d4 100644 (file)
@@ -16,6 +16,7 @@
 #define RTL8187_H
 
 #include "rtl818x.h"
+#include "rtl8187_leds.h"
 
 #define RTL8187_EEPROM_TXPWR_BASE      0x05
 #define RTL8187_EEPROM_MAC_ADDR                0x07
@@ -102,6 +103,12 @@ struct rtl8187_priv {
        struct usb_anchor anchored;
        struct delayed_work work;
        struct ieee80211_hw *dev;
+#ifdef CONFIG_RTL8187_LEDS
+       struct rtl8187_led led_tx;
+       struct rtl8187_led led_rx;
+       struct delayed_work led_on;
+       struct delayed_work led_off;
+#endif
        u16 txpwr_base;
        u8 asic_rev;
        u8 is_rtl8187b;
index d51ba0a88c237cbf830e2d46806180d83361ae57..294250e294dd548bb295c620e6d52c799f03021f 100644 (file)
@@ -29,6 +29,9 @@
 
 #include "rtl8187.h"
 #include "rtl8187_rtl8225.h"
+#ifdef CONFIG_RTL8187_LEDS
+#include "rtl8187_leds.h"
+#endif
 
 MODULE_AUTHOR("Michael Wu <flamingice@sourmilk.net>");
 MODULE_AUTHOR("Andrea Merello <andreamrl@tiscali.it>");
@@ -320,12 +323,7 @@ static void rtl8187_rx_cb(struct urb *urb)
        unsigned long f;
 
        spin_lock_irqsave(&priv->rx_queue.lock, f);
-       if (skb->next)
-               __skb_unlink(skb, &priv->rx_queue);
-       else {
-               spin_unlock_irqrestore(&priv->rx_queue.lock, f);
-               return;
-       }
+       __skb_unlink(skb, &priv->rx_queue);
        spin_unlock_irqrestore(&priv->rx_queue.lock, f);
        skb_put(skb, urb->actual_length);
 
@@ -736,10 +734,10 @@ static const u8 rtl8187b_reg_table[][3] = {
        {0x85, 0x24, 0}, {0x88, 0x54, 0}, {0x8B, 0xB8, 0}, {0x8C, 0x07, 0},
        {0x8D, 0x00, 0}, {0x94, 0x1B, 0}, {0x95, 0x12, 0}, {0x96, 0x00, 0},
        {0x97, 0x06, 0}, {0x9D, 0x1A, 0}, {0x9F, 0x10, 0}, {0xB4, 0x22, 0},
-       {0xBE, 0x80, 0}, {0xDB, 0x00, 0}, {0xEE, 0x00, 0}, {0x91, 0x03, 0},
+       {0xBE, 0x80, 0}, {0xDB, 0x00, 0}, {0xEE, 0x00, 0}, {0x4C, 0x00, 2},
 
-       {0x4C, 0x00, 2}, {0x9F, 0x00, 3}, {0x8C, 0x01, 0}, {0x8D, 0x10, 0},
-       {0x8E, 0x08, 0}, {0x8F, 0x00, 0}
+       {0x9F, 0x00, 3}, {0x8C, 0x01, 0}, {0x8D, 0x10, 0}, {0x8E, 0x08, 0},
+       {0x8F, 0x00, 0}
 };
 
 static int rtl8187b_init_hw(struct ieee80211_hw *dev)
@@ -1089,32 +1087,6 @@ static int rtl8187_config(struct ieee80211_hw *dev, u32 changed)
        return 0;
 }
 
-static int rtl8187_config_interface(struct ieee80211_hw *dev,
-                                   struct ieee80211_vif *vif,
-                                   struct ieee80211_if_conf *conf)
-{
-       struct rtl8187_priv *priv = dev->priv;
-       int i;
-       u8 reg;
-
-       mutex_lock(&priv->conf_mutex);
-       for (i = 0; i < ETH_ALEN; i++)
-               rtl818x_iowrite8(priv, &priv->map->BSSID[i], conf->bssid[i]);
-
-       if (is_valid_ether_addr(conf->bssid)) {
-               reg = RTL818X_MSR_INFRA;
-               if (priv->is_rtl8187b)
-                       reg |= RTL818X_MSR_ENEDCA;
-               rtl818x_iowrite8(priv, &priv->map->MSR, reg);
-       } else {
-               reg = RTL818X_MSR_NO_LINK;
-               rtl818x_iowrite8(priv, &priv->map->MSR, reg);
-       }
-
-       mutex_unlock(&priv->conf_mutex);
-       return 0;
-}
-
 /*
  * With 8187B, AC_*_PARAM clashes with FEMR definition in struct rtl818x_csr for
  * example. Thus we have to use raw values for AC_*_PARAM register addresses.
@@ -1192,6 +1164,27 @@ static void rtl8187_bss_info_changed(struct ieee80211_hw *dev,
                                     u32 changed)
 {
        struct rtl8187_priv *priv = dev->priv;
+       int i;
+       u8 reg;
+
+       if (changed & BSS_CHANGED_BSSID) {
+               mutex_lock(&priv->conf_mutex);
+               for (i = 0; i < ETH_ALEN; i++)
+                       rtl818x_iowrite8(priv, &priv->map->BSSID[i],
+                                        info->bssid[i]);
+
+               if (is_valid_ether_addr(info->bssid)) {
+                       reg = RTL818X_MSR_INFRA;
+                       if (priv->is_rtl8187b)
+                               reg |= RTL818X_MSR_ENEDCA;
+                       rtl818x_iowrite8(priv, &priv->map->MSR, reg);
+               } else {
+                       reg = RTL818X_MSR_NO_LINK;
+                       rtl818x_iowrite8(priv, &priv->map->MSR, reg);
+               }
+
+               mutex_unlock(&priv->conf_mutex);
+       }
 
        if (changed & (BSS_CHANGED_ERP_SLOT | BSS_CHANGED_ERP_PREAMBLE))
                rtl8187_conf_erp(priv, info->use_short_slot,
@@ -1273,7 +1266,6 @@ static const struct ieee80211_ops rtl8187_ops = {
        .add_interface          = rtl8187_add_interface,
        .remove_interface       = rtl8187_remove_interface,
        .config                 = rtl8187_config,
-       .config_interface       = rtl8187_config_interface,
        .bss_info_changed       = rtl8187_bss_info_changed,
        .configure_filter       = rtl8187_configure_filter,
        .conf_tx                = rtl8187_conf_tx
@@ -1480,9 +1472,6 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
                (*channel++).hw_value = txpwr >> 8;
        }
 
-       if (priv->is_rtl8187b)
-               printk(KERN_WARNING "rtl8187: 8187B chip detected.\n");
-
        /*
         * XXX: Once this driver supports anything that requires
         *      beacons it must implement IEEE80211_TX_CTL_ASSIGN_SEQ.
@@ -1514,6 +1503,12 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
               wiphy_name(dev->wiphy), dev->wiphy->perm_addr,
               chip_name, priv->asic_rev, priv->rf->name);
 
+#ifdef CONFIG_RTL8187_LEDS
+       eeprom_93cx6_read(&eeprom, 0x3F, &reg);
+       reg &= 0xFF;
+       rtl8187_leds_init(dev, reg);
+#endif
+
        return 0;
 
  err_free_dmabuf:
@@ -1533,6 +1528,9 @@ static void __devexit rtl8187_disconnect(struct usb_interface *intf)
        if (!dev)
                return;
 
+#ifdef CONFIG_RTL8187_LEDS
+       rtl8187_leds_exit(dev);
+#endif
        ieee80211_unregister_hw(dev);
 
        priv = dev->priv;
diff --git a/drivers/net/wireless/rtl818x/rtl8187_leds.c b/drivers/net/wireless/rtl818x/rtl8187_leds.c
new file mode 100644 (file)
index 0000000..b442535
--- /dev/null
@@ -0,0 +1,218 @@
+/*
+ * Linux LED driver for RTL8187
+ *
+ * Copyright 2009 Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ * Based on the LED handling in the r8187 driver, which is:
+ * Copyright (c) Realtek Semiconductor Corp. All rights reserved.
+ *
+ * Thanks to Realtek for their support!
+ *
+ * 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.
+ */
+
+#ifdef CONFIG_RTL8187_LEDS
+
+#include <net/mac80211.h>
+#include <linux/usb.h>
+#include <linux/eeprom_93cx6.h>
+
+#include "rtl8187.h"
+#include "rtl8187_leds.h"
+
+static void led_turn_on(struct work_struct *work)
+{
+       /* As this routine does read/write operations on the hardware, it must
+        * be run from a work queue.
+        */
+       u8 reg;
+       struct rtl8187_priv *priv = container_of(work, struct rtl8187_priv,
+                                   led_on.work);
+       struct rtl8187_led *led = &priv->led_tx;
+
+       /* Don't change the LED, when the device is down. */
+       if (priv->mode == NL80211_IFTYPE_UNSPECIFIED)
+               return ;
+
+       /* Skip if the LED is not registered. */
+       if (!led->dev)
+               return;
+       mutex_lock(&priv->conf_mutex);
+       switch (led->ledpin) {
+       case LED_PIN_GPIO0:
+               rtl818x_iowrite8(priv, &priv->map->GPIO, 0x01);
+               rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0x00);
+               break;
+       case LED_PIN_LED0:
+               reg = rtl818x_ioread8(priv, &priv->map->PGSELECT) & ~(1 << 4);
+               rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg);
+               break;
+       case LED_PIN_LED1:
+               reg = rtl818x_ioread8(priv, &priv->map->PGSELECT) & ~(1 << 5);
+               rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg);
+               break;
+       case LED_PIN_HW:
+       default:
+               break;
+       }
+       mutex_unlock(&priv->conf_mutex);
+}
+
+static void led_turn_off(struct work_struct *work)
+{
+       /* As this routine does read/write operations on the hardware, it must
+        * be run from a work queue.
+        */
+       u8 reg;
+       struct rtl8187_priv *priv = container_of(work, struct rtl8187_priv,
+                                   led_off.work);
+       struct rtl8187_led *led = &priv->led_tx;
+
+       /* Don't change the LED, when the device is down. */
+       if (priv->mode == NL80211_IFTYPE_UNSPECIFIED)
+               return ;
+
+       /* Skip if the LED is not registered. */
+       if (!led->dev)
+               return;
+       mutex_lock(&priv->conf_mutex);
+       switch (led->ledpin) {
+       case LED_PIN_GPIO0:
+               rtl818x_iowrite8(priv, &priv->map->GPIO, 0x01);
+               rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0x01);
+               break;
+       case LED_PIN_LED0:
+               reg = rtl818x_ioread8(priv, &priv->map->PGSELECT) | (1 << 4);
+               rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg);
+               break;
+       case LED_PIN_LED1:
+               reg = rtl818x_ioread8(priv, &priv->map->PGSELECT) | (1 << 5);
+               rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg);
+               break;
+       case LED_PIN_HW:
+       default:
+               break;
+       }
+       mutex_unlock(&priv->conf_mutex);
+}
+
+/* Callback from the LED subsystem. */
+static void rtl8187_led_brightness_set(struct led_classdev *led_dev,
+                                  enum led_brightness brightness)
+{
+       struct rtl8187_led *led = container_of(led_dev, struct rtl8187_led,
+                                              led_dev);
+       struct ieee80211_hw *hw = led->dev;
+       struct rtl8187_priv *priv = hw->priv;
+
+       if (brightness == LED_OFF) {
+               queue_delayed_work(hw->workqueue, &priv->led_off, 0);
+               /* The LED is off for 1/20 sec so that it just blinks. */
+               queue_delayed_work(hw->workqueue, &priv->led_on, HZ / 20);
+       } else
+               queue_delayed_work(hw->workqueue, &priv->led_on, 0);
+}
+
+static int rtl8187_register_led(struct ieee80211_hw *dev,
+                               struct rtl8187_led *led, const char *name,
+                               const char *default_trigger, u8 ledpin)
+{
+       int err;
+       struct rtl8187_priv *priv = dev->priv;
+
+       if (led->dev)
+               return -EEXIST;
+       if (!default_trigger)
+               return -EINVAL;
+       led->dev = dev;
+       led->ledpin = ledpin;
+       strncpy(led->name, name, sizeof(led->name));
+
+       led->led_dev.name = led->name;
+       led->led_dev.default_trigger = default_trigger;
+       led->led_dev.brightness_set = rtl8187_led_brightness_set;
+
+       err = led_classdev_register(&priv->udev->dev, &led->led_dev);
+       if (err) {
+               printk(KERN_INFO "LEDs: Failed to register %s\n", name);
+               led->dev = NULL;
+               return err;
+       }
+       return 0;
+}
+
+static void rtl8187_unregister_led(struct rtl8187_led *led)
+{
+       led_classdev_unregister(&led->led_dev);
+       led->dev = NULL;
+}
+
+void rtl8187_leds_init(struct ieee80211_hw *dev, u16 custid)
+{
+       struct rtl8187_priv *priv = dev->priv;
+       char name[RTL8187_LED_MAX_NAME_LEN + 1];
+       u8 ledpin;
+       int err;
+
+       /* According to the vendor driver, the LED operation depends on the
+        * customer ID encoded in the EEPROM
+        */
+       printk(KERN_INFO "rtl8187: Customer ID is 0x%02X\n", custid);
+       switch (custid) {
+       case EEPROM_CID_RSVD0:
+       case EEPROM_CID_RSVD1:
+       case EEPROM_CID_SERCOMM_PS:
+       case EEPROM_CID_QMI:
+       case EEPROM_CID_DELL:
+       case EEPROM_CID_TOSHIBA:
+               ledpin = LED_PIN_GPIO0;
+               break;
+       case EEPROM_CID_ALPHA0:
+               ledpin = LED_PIN_LED0;
+               break;
+       case EEPROM_CID_HW:
+               ledpin = LED_PIN_HW;
+               break;
+       default:
+               ledpin = LED_PIN_GPIO0;
+       }
+
+       INIT_DELAYED_WORK(&priv->led_on, led_turn_on);
+       INIT_DELAYED_WORK(&priv->led_off, led_turn_off);
+
+       snprintf(name, sizeof(name),
+                "rtl8187-%s::tx", wiphy_name(dev->wiphy));
+       err = rtl8187_register_led(dev, &priv->led_tx, name,
+                        ieee80211_get_tx_led_name(dev), ledpin);
+       if (err)
+               goto error;
+       snprintf(name, sizeof(name),
+                "rtl8187-%s::rx", wiphy_name(dev->wiphy));
+       err = rtl8187_register_led(dev, &priv->led_rx, name,
+                        ieee80211_get_rx_led_name(dev), ledpin);
+       if (!err) {
+               queue_delayed_work(dev->workqueue, &priv->led_on, 0);
+               return;
+       }
+       /* registration of RX LED failed - unregister TX */
+       rtl8187_unregister_led(&priv->led_tx);
+error:
+       /* If registration of either failed, cancel delayed work */
+       cancel_delayed_work_sync(&priv->led_off);
+       cancel_delayed_work_sync(&priv->led_on);
+}
+
+void rtl8187_leds_exit(struct ieee80211_hw *dev)
+{
+       struct rtl8187_priv *priv = dev->priv;
+
+       rtl8187_unregister_led(&priv->led_tx);
+       /* turn the LED off before exiting */
+       queue_delayed_work(dev->workqueue, &priv->led_off, 0);
+       cancel_delayed_work_sync(&priv->led_off);
+       rtl8187_unregister_led(&priv->led_rx);
+}
+#endif /* def CONFIG_RTL8187_LED */
+
diff --git a/drivers/net/wireless/rtl818x/rtl8187_leds.h b/drivers/net/wireless/rtl818x/rtl8187_leds.h
new file mode 100644 (file)
index 0000000..a033202
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Definitions for RTL8187 leds
+ *
+ * Copyright 2009 Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ * Based on the LED handling in the r8187 driver, which is:
+ * Copyright (c) Realtek Semiconductor Corp. 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 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef RTL8187_LED_H
+#define RTL8187_LED_H
+
+#ifdef CONFIG_RTL8187_LEDS
+
+#define RTL8187_LED_MAX_NAME_LEN       21
+
+#include <linux/leds.h>
+#include <linux/types.h>
+
+enum {
+       LED_PIN_LED0,
+       LED_PIN_LED1,
+       LED_PIN_GPIO0,
+       LED_PIN_HW
+};
+
+enum {
+       EEPROM_CID_RSVD0 = 0x00,
+       EEPROM_CID_RSVD1 = 0xFF,
+       EEPROM_CID_ALPHA0 = 0x01,
+       EEPROM_CID_SERCOMM_PS = 0x02,
+       EEPROM_CID_HW = 0x03,
+       EEPROM_CID_TOSHIBA = 0x04,
+       EEPROM_CID_QMI = 0x07,
+       EEPROM_CID_DELL = 0x08
+};
+
+struct rtl8187_led {
+       struct ieee80211_hw *dev;
+       /* The LED class device */
+       struct led_classdev led_dev;
+       /* The pin/method used to control the led */
+       u8 ledpin;
+       /* The unique name string for this LED device. */
+       char name[RTL8187_LED_MAX_NAME_LEN + 1];
+};
+
+void rtl8187_leds_init(struct ieee80211_hw *dev, u16 code);
+void rtl8187_leds_exit(struct ieee80211_hw *dev);
+
+#endif /* def CONFIG_RTL8187_LED */
+
+#endif /* RTL8187_LED_H */
index f9520463269074eee8fb724ddc75b002de86103e..38366a56b71fa6588d197ea79268d509c9a9629a 100644 (file)
@@ -1540,7 +1540,7 @@ static int strip_xmit(struct sk_buff *skb, struct net_device *dev)
        if (!netif_running(dev)) {
                printk(KERN_ERR "%s: xmit call when iface is down\n",
                       dev->name);
-               return (1);
+               return NETDEV_TX_BUSY;
        }
 
        netif_stop_queue(dev);
@@ -2509,7 +2509,7 @@ static void strip_dev_setup(struct net_device *dev)
         *  netdev_priv(dev) Already holds a pointer to our struct strip
         */
 
-       *(MetricomAddress *) & dev->broadcast = broadcast_address;
+       *(MetricomAddress *)dev->broadcast = broadcast_address;
        dev->dev_addr[0] = 0;
        dev->addr_len = sizeof(MetricomAddress);
 
index 3ab3eb95718928c53425b29dcc3b1c5eccb43b1a..ab7fc5c0c8b4e46a64f71083ebdbffbe141593fc 100644 (file)
@@ -2867,12 +2867,8 @@ static int wavelan_packet_xmit(struct sk_buff *skb, struct net_device * dev)
                spin_unlock_irqrestore(&lp->spinlock, flags);
                /* Check that we can continue */
                if (lp->tx_n_in_use == (NTXBLOCKS - 1))
-                       return 1;
+                       return NETDEV_TX_BUSY;
        }
-#ifdef DEBUG_TX_ERROR
-       if (skb->next)
-               printk(KERN_INFO "skb has next\n");
-#endif
 
        /* Do we need some padding? */
        /* Note : on wireless the propagation time is in the order of 1us,
@@ -2884,10 +2880,10 @@ static int wavelan_packet_xmit(struct sk_buff *skb, struct net_device * dev)
                skb_copy_from_linear_data(skb, data, skb->len);
                /* Write packet on the card */
                if(wv_packet_write(dev, data, ETH_ZLEN))
-                       return 1;       /* We failed */
+                       return NETDEV_TX_BUSY;  /* We failed */
        }
        else if(wv_packet_write(dev, skb->data, skb->len))
-               return 1;       /* We failed */
+               return NETDEV_TX_BUSY;  /* We failed */
 
 
        dev_kfree_skb(skb);
index fa2821be44c2d43e83bfbfb375ed1453788c2e8f..6af706408ac08bf252a4a97105af0379734db621 100644 (file)
@@ -3107,11 +3107,6 @@ wavelan_packet_xmit(struct sk_buff *     skb,
        * so the Tx buffer is now free */
     }
 
-#ifdef DEBUG_TX_ERROR
-       if (skb->next)
-               printk(KERN_INFO "skb has next\n");
-#endif
-
        /* Check if we need some padding */
        /* Note : on wireless the propagation time is in the order of 1us,
         * and we don't have the Ethernet specific requirement of beeing
diff --git a/drivers/net/wireless/wl12xx/Kconfig b/drivers/net/wireless/wl12xx/Kconfig
new file mode 100644 (file)
index 0000000..a82c4cd
--- /dev/null
@@ -0,0 +1,11 @@
+config WL12XX
+       tristate "TI wl1251/wl1271 support"
+       depends on MAC80211 && WLAN_80211 && SPI_MASTER && GENERIC_HARDIRQS && EXPERIMENTAL
+       select FW_LOADER
+       select CRC7
+       ---help---
+         This module adds support for wireless adapters based on
+         TI wl1251/wl1271 chipsets.
+
+         If you choose to build a module, it'll be called wl12xx. Say N if
+         unsure.
diff --git a/drivers/net/wireless/wl12xx/Makefile b/drivers/net/wireless/wl12xx/Makefile
new file mode 100644 (file)
index 0000000..d43de27
--- /dev/null
@@ -0,0 +1,4 @@
+wl12xx-objs            = main.o spi.o event.o tx.o rx.o \
+                         ps.o cmd.o acx.o boot.o init.o wl1251.o \
+                         debugfs.o
+obj-$(CONFIG_WL12XX)   += wl12xx.o
diff --git a/drivers/net/wireless/wl12xx/acx.c b/drivers/net/wireless/wl12xx/acx.c
new file mode 100644 (file)
index 0000000..1cfd458
--- /dev/null
@@ -0,0 +1,689 @@
+#include "acx.h"
+
+#include <linux/module.h>
+#include <linux/crc7.h>
+#include <linux/spi/spi.h>
+
+#include "wl12xx.h"
+#include "wl12xx_80211.h"
+#include "reg.h"
+#include "spi.h"
+#include "ps.h"
+
+int wl12xx_acx_frame_rates(struct wl12xx *wl, u8 ctrl_rate, u8 ctrl_mod,
+                          u8 mgt_rate, u8 mgt_mod)
+{
+       int ret;
+       struct acx_fw_gen_frame_rates rates;
+
+       wl12xx_debug(DEBUG_ACX, "acx frame rates");
+
+       rates.header.id = ACX_FW_GEN_FRAME_RATES;
+       rates.header.len = sizeof(struct acx_fw_gen_frame_rates) -
+               sizeof(struct acx_header);
+
+       rates.tx_ctrl_frame_rate = ctrl_rate;
+       rates.tx_ctrl_frame_mod = ctrl_mod;
+       rates.tx_mgt_frame_rate = mgt_rate;
+       rates.tx_mgt_frame_mod = mgt_mod;
+
+       ret = wl12xx_cmd_configure(wl, &rates, sizeof(rates));
+       if (ret < 0) {
+               wl12xx_error("Failed to set FW rates and modulation");
+               return ret;
+       }
+
+       return 0;
+}
+
+
+int wl12xx_acx_station_id(struct wl12xx *wl)
+{
+       int ret, i;
+       struct dot11_station_id mac;
+
+       wl12xx_debug(DEBUG_ACX, "acx dot11_station_id");
+
+       mac.header.id = DOT11_STATION_ID;
+       mac.header.len = sizeof(mac) - sizeof(struct acx_header);
+
+       for (i = 0; i < ETH_ALEN; i++)
+               mac.mac[i] = wl->mac_addr[ETH_ALEN - 1 - i];
+
+       ret = wl12xx_cmd_configure(wl, &mac, sizeof(mac));
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+
+int wl12xx_acx_default_key(struct wl12xx *wl, u8 key_id)
+{
+       struct acx_dot11_default_key default_key;
+       int ret;
+
+       wl12xx_debug(DEBUG_ACX, "acx dot11_default_key (%d)", key_id);
+
+       default_key.header.id = DOT11_DEFAULT_KEY;
+       default_key.header.len = sizeof(default_key) -
+               sizeof(struct acx_header);
+
+       default_key.id = key_id;
+
+       ret = wl12xx_cmd_configure(wl, &default_key, sizeof(default_key));
+       if (ret < 0) {
+               wl12xx_error("Couldnt set default key");
+               return ret;
+       }
+
+       wl->default_key = key_id;
+
+       return 0;
+}
+
+int wl12xx_acx_wake_up_conditions(struct wl12xx *wl, u8 listen_interval)
+{
+       struct acx_wake_up_condition wake_up;
+
+       wl12xx_debug(DEBUG_ACX, "acx wake up conditions");
+
+       wake_up.header.id = ACX_WAKE_UP_CONDITIONS;
+       wake_up.header.len = sizeof(wake_up) - sizeof(struct acx_header);
+
+       wake_up.wake_up_event = WAKE_UP_EVENT_DTIM_BITMAP;
+       wake_up.listen_interval = listen_interval;
+
+       return wl12xx_cmd_configure(wl, &wake_up, sizeof(wake_up));
+}
+
+int wl12xx_acx_sleep_auth(struct wl12xx *wl, u8 sleep_auth)
+{
+       int ret;
+       struct acx_sleep_auth auth;
+
+       wl12xx_debug(DEBUG_ACX, "acx sleep auth");
+
+       auth.header.id = ACX_SLEEP_AUTH;
+       auth.header.len = sizeof(auth) - sizeof(struct acx_header);
+
+       auth.sleep_auth = sleep_auth;
+
+       ret = wl12xx_cmd_configure(wl, &auth, sizeof(auth));
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+
+int wl12xx_acx_fw_version(struct wl12xx *wl, char *buf, size_t len)
+{
+       struct wl12xx_command cmd;
+       struct acx_revision *rev;
+       int ret;
+
+       wl12xx_debug(DEBUG_ACX, "acx fw rev");
+
+       memset(&cmd, 0, sizeof(cmd));
+
+       ret = wl12xx_cmd_interrogate(wl, ACX_FW_REV, sizeof(*rev), &cmd);
+       if (ret < 0) {
+               wl12xx_warning("ACX_FW_REV interrogate failed");
+               return ret;
+       }
+
+       rev = (struct acx_revision *) &cmd.parameters;
+
+       /* be careful with the buffer sizes */
+       strncpy(buf, rev->fw_version, min(len, sizeof(rev->fw_version)));
+
+       /*
+        * if the firmware version string is exactly
+        * sizeof(rev->fw_version) long or fw_len is less than
+        * sizeof(rev->fw_version) it won't be null terminated
+        */
+       buf[min(len, sizeof(rev->fw_version)) - 1] = '\0';
+
+       return 0;
+}
+
+int wl12xx_acx_tx_power(struct wl12xx *wl, int power)
+{
+       struct acx_current_tx_power ie;
+       int ret;
+
+       wl12xx_debug(DEBUG_ACX, "acx dot11_cur_tx_pwr");
+
+       if (power < 0 || power > 25)
+               return -EINVAL;
+
+       memset(&ie, 0, sizeof(ie));
+
+       ie.header.id = DOT11_CUR_TX_PWR;
+       ie.header.len = sizeof(ie) - sizeof(struct acx_header);
+       ie.current_tx_power = power * 10;
+
+       ret = wl12xx_cmd_configure(wl, &ie, sizeof(ie));
+       if (ret < 0) {
+               wl12xx_warning("configure of tx power failed: %d", ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+int wl12xx_acx_feature_cfg(struct wl12xx *wl)
+{
+       struct acx_feature_config feature;
+       int ret;
+
+       wl12xx_debug(DEBUG_ACX, "acx feature cfg");
+
+       memset(&feature, 0, sizeof(feature));
+
+       feature.header.id = ACX_FEATURE_CFG;
+       feature.header.len = sizeof(feature) - sizeof(struct acx_header);
+
+       /* DF_ENCRYPTION_DISABLE and DF_SNIFF_MODE_ENABLE are disabled */
+       feature.data_flow_options = 0;
+       feature.options = 0;
+
+       ret = wl12xx_cmd_configure(wl, &feature, sizeof(feature));
+       if (ret < 0)
+               wl12xx_error("Couldnt set HW encryption");
+
+       return ret;
+}
+
+int wl12xx_acx_mem_map(struct wl12xx *wl, void *mem_map, size_t len)
+{
+       struct wl12xx_command cmd;
+       int ret;
+
+       wl12xx_debug(DEBUG_ACX, "acx mem map");
+
+       ret = wl12xx_cmd_interrogate(wl, ACX_MEM_MAP, len, &cmd);
+       if (ret < 0)
+               return ret;
+       else if (cmd.status != CMD_STATUS_SUCCESS)
+               return -EIO;
+
+       memcpy(mem_map, &cmd.parameters, len);
+
+       return 0;
+}
+
+int wl12xx_acx_data_path_params(struct wl12xx *wl,
+                               struct acx_data_path_params_resp *data_path)
+{
+       struct acx_data_path_params params;
+       struct wl12xx_command cmd;
+       int ret;
+
+       wl12xx_debug(DEBUG_ACX, "acx data path params");
+
+       params.rx_packet_ring_chunk_size = DP_RX_PACKET_RING_CHUNK_SIZE;
+       params.tx_packet_ring_chunk_size = DP_TX_PACKET_RING_CHUNK_SIZE;
+
+       params.rx_packet_ring_chunk_num = DP_RX_PACKET_RING_CHUNK_NUM;
+       params.tx_packet_ring_chunk_num = DP_TX_PACKET_RING_CHUNK_NUM;
+
+       params.tx_complete_threshold = 1;
+
+       params.tx_complete_ring_depth = FW_TX_CMPLT_BLOCK_SIZE;
+
+       params.tx_complete_timeout = DP_TX_COMPLETE_TIME_OUT;
+
+       params.header.id = ACX_DATA_PATH_PARAMS;
+       params.header.len = sizeof(params) - sizeof(struct acx_header);
+
+       ret = wl12xx_cmd_configure(wl, &params, sizeof(params));
+       if (ret < 0)
+               return ret;
+
+
+       ret = wl12xx_cmd_interrogate(wl, ACX_DATA_PATH_PARAMS,
+                                    sizeof(struct acx_data_path_params_resp),
+                                    &cmd);
+
+       if (ret < 0) {
+               wl12xx_warning("failed to read data path parameters: %d", ret);
+               return ret;
+       } else if (cmd.status != CMD_STATUS_SUCCESS) {
+               wl12xx_warning("data path parameter acx status failed");
+               return -EIO;
+       }
+
+       memcpy(data_path, &cmd.parameters, sizeof(*data_path));
+
+       return 0;
+}
+
+int wl12xx_acx_rx_msdu_life_time(struct wl12xx *wl, u32 life_time)
+{
+       struct rx_msdu_lifetime msdu_lifetime;
+       int ret;
+
+       wl12xx_debug(DEBUG_ACX, "acx rx msdu life time");
+
+       msdu_lifetime.header.id = DOT11_RX_MSDU_LIFE_TIME;
+       msdu_lifetime.header.len = sizeof(msdu_lifetime) -
+               sizeof(struct acx_header);
+       msdu_lifetime.lifetime = life_time;
+
+       ret = wl12xx_cmd_configure(wl, &msdu_lifetime, sizeof(msdu_lifetime));
+       if (ret < 0) {
+               wl12xx_warning("failed to set rx msdu life time: %d", ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+int wl12xx_acx_rx_config(struct wl12xx *wl, u32 config, u32 filter)
+{
+       struct acx_rx_config rx_config;
+       int ret;
+
+       wl12xx_debug(DEBUG_ACX, "acx rx config");
+
+       rx_config.header.id = ACX_RX_CFG;
+       rx_config.header.len = sizeof(rx_config) - sizeof(struct acx_header);
+       rx_config.config_options = config;
+       rx_config.filter_options = filter;
+
+       ret = wl12xx_cmd_configure(wl, &rx_config, sizeof(rx_config));
+       if (ret < 0) {
+               wl12xx_warning("failed to set rx config: %d", ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+int wl12xx_acx_pd_threshold(struct wl12xx *wl)
+{
+       struct acx_packet_detection packet_detection;
+       int ret;
+
+       wl12xx_debug(DEBUG_ACX, "acx data pd threshold");
+
+       /* FIXME: threshold value not set */
+       packet_detection.header.id = ACX_PD_THRESHOLD;
+       packet_detection.header.len = sizeof(packet_detection) -
+               sizeof(struct acx_header);
+
+       ret = wl12xx_cmd_configure(wl, &packet_detection,
+                                  sizeof(packet_detection));
+       if (ret < 0) {
+               wl12xx_warning("failed to set pd threshold: %d", ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+int wl12xx_acx_slot(struct wl12xx *wl, enum acx_slot_type slot_time)
+{
+       struct acx_slot slot;
+       int ret;
+
+       wl12xx_debug(DEBUG_ACX, "acx slot");
+
+       slot.header.id = ACX_SLOT;
+       slot.header.len = sizeof(slot) - sizeof(struct acx_header);
+
+       slot.wone_index = STATION_WONE_INDEX;
+       slot.slot_time = slot_time;
+
+       ret = wl12xx_cmd_configure(wl, &slot, sizeof(slot));
+       if (ret < 0) {
+               wl12xx_warning("failed to set slot time: %d", ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+int wl12xx_acx_group_address_tbl(struct wl12xx *wl)
+{
+       struct multicast_grp_addr_start multicast;
+       int ret;
+
+       wl12xx_debug(DEBUG_ACX, "acx group address tbl");
+
+       /* MAC filtering */
+       multicast.header.id = DOT11_GROUP_ADDRESS_TBL;
+       multicast.header.len = sizeof(multicast) - sizeof(struct acx_header);
+
+       multicast.enabled = 0;
+       multicast.num_groups = 0;
+       memset(multicast.mac_table, 0, ADDRESS_GROUP_MAX_LEN);
+
+       ret = wl12xx_cmd_configure(wl, &multicast, sizeof(multicast));
+       if (ret < 0) {
+               wl12xx_warning("failed to set group addr table: %d", ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+int wl12xx_acx_service_period_timeout(struct wl12xx *wl)
+{
+       struct acx_rx_timeout rx_timeout;
+       int ret;
+
+       wl12xx_debug(DEBUG_ACX, "acx service period timeout");
+
+       /* RX timeout */
+       rx_timeout.header.id = ACX_SERVICE_PERIOD_TIMEOUT;
+       rx_timeout.header.len = sizeof(rx_timeout) - sizeof(struct acx_header);
+
+       rx_timeout.ps_poll_timeout = RX_TIMEOUT_PS_POLL_DEF;
+       rx_timeout.upsd_timeout = RX_TIMEOUT_UPSD_DEF;
+
+       ret = wl12xx_cmd_configure(wl, &rx_timeout, sizeof(rx_timeout));
+       if (ret < 0) {
+               wl12xx_warning("failed to set service period timeout: %d",
+                              ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+int wl12xx_acx_rts_threshold(struct wl12xx *wl, u16 rts_threshold)
+{
+       struct acx_rts_threshold rts;
+       int ret;
+
+       wl12xx_debug(DEBUG_ACX, "acx rts threshold");
+
+       rts.header.id = DOT11_RTS_THRESHOLD;
+       rts.header.len = sizeof(rts) - sizeof(struct acx_header);
+
+       rts.threshold = rts_threshold;
+
+       ret = wl12xx_cmd_configure(wl, &rts, sizeof(rts));
+       if (ret < 0) {
+               wl12xx_warning("failed to set rts threshold: %d", ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+int wl12xx_acx_beacon_filter_opt(struct wl12xx *wl)
+{
+       struct acx_beacon_filter_option beacon_filter;
+       int ret;
+
+       wl12xx_debug(DEBUG_ACX, "acx beacon filter opt");
+
+       beacon_filter.header.id = ACX_BEACON_FILTER_OPT;
+       beacon_filter.header.len = sizeof(beacon_filter) -
+               sizeof(struct acx_header);
+
+       beacon_filter.enable = 0;
+       beacon_filter.max_num_beacons = 0;
+
+       ret = wl12xx_cmd_configure(wl, &beacon_filter, sizeof(beacon_filter));
+       if (ret < 0) {
+               wl12xx_warning("failed to set beacon filter opt: %d", ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+int wl12xx_acx_beacon_filter_table(struct wl12xx *wl)
+{
+       struct acx_beacon_filter_ie_table ie_table;
+       int ret;
+
+       wl12xx_debug(DEBUG_ACX, "acx beacon filter table");
+
+       ie_table.header.id = ACX_BEACON_FILTER_TABLE;
+       ie_table.header.len = sizeof(ie_table) - sizeof(struct acx_header);
+
+       ie_table.num_ie = 0;
+       memset(ie_table.table, 0, BEACON_FILTER_TABLE_MAX_SIZE);
+
+       ret = wl12xx_cmd_configure(wl, &ie_table, sizeof(ie_table));
+       if (ret < 0) {
+               wl12xx_warning("failed to set beacon filter table: %d", ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+int wl12xx_acx_sg_enable(struct wl12xx *wl)
+{
+       struct acx_bt_wlan_coex pta;
+       int ret;
+
+       wl12xx_debug(DEBUG_ACX, "acx sg enable");
+
+       pta.header.id = ACX_SG_ENABLE;
+       pta.header.len = sizeof(pta) - sizeof(struct acx_header);
+
+       pta.enable = SG_ENABLE;
+
+       ret = wl12xx_cmd_configure(wl, &pta, sizeof(pta));
+       if (ret < 0) {
+               wl12xx_warning("failed to set softgemini enable: %d", ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+int wl12xx_acx_sg_cfg(struct wl12xx *wl)
+{
+       struct acx_bt_wlan_coex_param param;
+       int ret;
+
+       wl12xx_debug(DEBUG_ACX, "acx sg cfg");
+
+       /* BT-WLAN coext parameters */
+       param.header.id = ACX_SG_CFG;
+       param.header.len = sizeof(param) - sizeof(struct acx_header);
+
+       param.min_rate = RATE_INDEX_24MBPS;
+       param.bt_hp_max_time = PTA_BT_HP_MAXTIME_DEF;
+       param.wlan_hp_max_time = PTA_WLAN_HP_MAX_TIME_DEF;
+       param.sense_disable_timer = PTA_SENSE_DISABLE_TIMER_DEF;
+       param.rx_time_bt_hp = PTA_PROTECTIVE_RX_TIME_DEF;
+       param.tx_time_bt_hp = PTA_PROTECTIVE_TX_TIME_DEF;
+       param.rx_time_bt_hp_fast = PTA_PROTECTIVE_RX_TIME_FAST_DEF;
+       param.tx_time_bt_hp_fast = PTA_PROTECTIVE_TX_TIME_FAST_DEF;
+       param.wlan_cycle_fast = PTA_CYCLE_TIME_FAST_DEF;
+       param.bt_anti_starvation_period = PTA_ANTI_STARVE_PERIOD_DEF;
+       param.next_bt_lp_packet = PTA_TIMEOUT_NEXT_BT_LP_PACKET_DEF;
+       param.wake_up_beacon = PTA_TIME_BEFORE_BEACON_DEF;
+       param.hp_dm_max_guard_time = PTA_HPDM_MAX_TIME_DEF;
+       param.next_wlan_packet = PTA_TIME_OUT_NEXT_WLAN_DEF;
+       param.antenna_type = PTA_ANTENNA_TYPE_DEF;
+       param.signal_type = PTA_SIGNALING_TYPE_DEF;
+       param.afh_leverage_on = PTA_AFH_LEVERAGE_ON_DEF;
+       param.quiet_cycle_num = PTA_NUMBER_QUIET_CYCLE_DEF;
+       param.max_cts = PTA_MAX_NUM_CTS_DEF;
+       param.wlan_packets_num = PTA_NUMBER_OF_WLAN_PACKETS_DEF;
+       param.bt_packets_num = PTA_NUMBER_OF_BT_PACKETS_DEF;
+       param.missed_rx_avalanche = PTA_RX_FOR_AVALANCHE_DEF;
+       param.wlan_elp_hp = PTA_ELP_HP_DEF;
+       param.bt_anti_starvation_cycles = PTA_ANTI_STARVE_NUM_CYCLE_DEF;
+       param.ack_mode_dual_ant = PTA_ACK_MODE_DEF;
+       param.pa_sd_enable = PTA_ALLOW_PA_SD_DEF;
+       param.pta_auto_mode_enable = PTA_AUTO_MODE_NO_CTS_DEF;
+       param.bt_hp_respected_num = PTA_BT_HP_RESPECTED_DEF;
+
+       ret = wl12xx_cmd_configure(wl, &param, sizeof(param));
+       if (ret < 0) {
+               wl12xx_warning("failed to set sg config: %d", ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+int wl12xx_acx_cca_threshold(struct wl12xx *wl)
+{
+       struct acx_energy_detection detection;
+       int ret;
+
+       wl12xx_debug(DEBUG_ACX, "acx cca threshold");
+
+       detection.header.id = ACX_CCA_THRESHOLD;
+       detection.header.len = sizeof(detection) - sizeof(struct acx_header);
+
+       detection.rx_cca_threshold = CCA_THRSH_DISABLE_ENERGY_D;
+       detection.tx_energy_detection = 0;
+
+       ret = wl12xx_cmd_configure(wl, &detection, sizeof(detection));
+       if (ret < 0) {
+               wl12xx_warning("failed to set cca threshold: %d", ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+int wl12xx_acx_bcn_dtim_options(struct wl12xx *wl)
+{
+       struct acx_beacon_broadcast bb;
+       int ret;
+
+       wl12xx_debug(DEBUG_ACX, "acx bcn dtim options");
+
+       bb.header.id = ACX_BCN_DTIM_OPTIONS;
+       bb.header.len = sizeof(bb) - sizeof(struct acx_header);
+
+       bb.beacon_rx_timeout = BCN_RX_TIMEOUT_DEF_VALUE;
+       bb.broadcast_timeout = BROADCAST_RX_TIMEOUT_DEF_VALUE;
+       bb.rx_broadcast_in_ps = RX_BROADCAST_IN_PS_DEF_VALUE;
+       bb.ps_poll_threshold = CONSECUTIVE_PS_POLL_FAILURE_DEF;
+
+       ret = wl12xx_cmd_configure(wl, &bb, sizeof(bb));
+       if (ret < 0) {
+               wl12xx_warning("failed to set rx config: %d", ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+int wl12xx_acx_aid(struct wl12xx *wl, u16 aid)
+{
+       struct acx_aid acx_aid;
+       int ret;
+
+       wl12xx_debug(DEBUG_ACX, "acx aid");
+
+       acx_aid.header.id = ACX_AID;
+       acx_aid.header.len = sizeof(acx_aid) - sizeof(struct acx_header);
+
+       acx_aid.aid = aid;
+
+       ret = wl12xx_cmd_configure(wl, &acx_aid, sizeof(acx_aid));
+       if (ret < 0) {
+               wl12xx_warning("failed to set aid: %d", ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+int wl12xx_acx_event_mbox_mask(struct wl12xx *wl, u32 event_mask)
+{
+       struct acx_event_mask mask;
+       int ret;
+
+       wl12xx_debug(DEBUG_ACX, "acx event mbox mask");
+
+       mask.header.id = ACX_EVENT_MBOX_MASK;
+       mask.header.len = sizeof(mask) - sizeof(struct acx_header);
+
+       /* high event mask is unused */
+       mask.high_event_mask = 0xffffffff;
+
+       mask.event_mask = event_mask;
+
+       ret = wl12xx_cmd_configure(wl, &mask, sizeof(mask));
+       if (ret < 0) {
+               wl12xx_warning("failed to set aid: %d", ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+int wl12xx_acx_set_preamble(struct wl12xx *wl, enum acx_preamble_type preamble)
+{
+       struct acx_preamble ie;
+       int ret;
+
+       wl12xx_debug(DEBUG_ACX, "acx_set_preamble");
+
+       memset(&ie, 0, sizeof(ie));
+
+       ie.header.id = ACX_PREAMBLE_TYPE;
+       ie.header.len = sizeof(ie) - sizeof(struct acx_header);
+       ie.preamble = preamble;
+       ret = wl12xx_cmd_configure(wl, &ie, sizeof(ie));
+       if (ret < 0) {
+               wl12xx_warning("Setting of preamble failed: %d", ret);
+               return ret;
+       }
+       return 0;
+}
+
+int wl12xx_acx_cts_protect(struct wl12xx *wl,
+                          enum acx_ctsprotect_type ctsprotect)
+{
+       struct acx_ctsprotect ie;
+       int ret;
+
+       wl12xx_debug(DEBUG_ACX, "acx_set_ctsprotect");
+
+       memset(&ie, 0, sizeof(ie));
+
+       ie.header.id = ACX_CTS_PROTECTION;
+       ie.header.len = sizeof(ie) - sizeof(struct acx_header);
+       ie.ctsprotect = ctsprotect;
+       ret = wl12xx_cmd_configure(wl, &ie, sizeof(ie));
+       if (ret < 0) {
+               wl12xx_warning("Setting of ctsprotect failed: %d", ret);
+               return ret;
+       }
+       return 0;
+}
+
+int wl12xx_acx_statistics(struct wl12xx *wl, struct acx_statistics *stats)
+{
+       struct wl12xx_command *answer;
+       int ret;
+
+       wl12xx_debug(DEBUG_ACX, "acx statistics");
+
+       answer = kmalloc(sizeof(*answer), GFP_KERNEL);
+       if (!answer) {
+               wl12xx_warning("could not allocate memory for acx statistics");
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       ret = wl12xx_cmd_interrogate(wl, ACX_STATISTICS, sizeof(*answer),
+                                    answer);
+       if (ret < 0) {
+               wl12xx_warning("acx statistics failed: %d", ret);
+               goto out;
+       }
+
+       memcpy(stats, answer->parameters, sizeof(*stats));
+
+out:
+       kfree(answer);
+       return ret;
+}
diff --git a/drivers/net/wireless/wl12xx/acx.h b/drivers/net/wireless/wl12xx/acx.h
new file mode 100644 (file)
index 0000000..fb2d234
--- /dev/null
@@ -0,0 +1,1245 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (c) 1998-2007 Texas Instruments Incorporated
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __WL12XX_ACX_H__
+#define __WL12XX_ACX_H__
+
+#include "wl12xx.h"
+
+/* Target's information element */
+struct acx_header {
+       u16 id;
+       u16 len;
+};
+
+struct acx_error_counter {
+       struct acx_header header;
+
+       /* The number of PLCP errors since the last time this */
+       /* information element was interrogated. This field is */
+       /* automatically cleared when it is interrogated.*/
+       u32 PLCP_error;
+
+       /* The number of FCS errors since the last time this */
+       /* information element was interrogated. This field is */
+       /* automatically cleared when it is interrogated.*/
+       u32 FCS_error;
+
+       /* The number of MPDUs without PLCP header errors received*/
+       /* since the last time this information element was interrogated. */
+       /* This field is automatically cleared when it is interrogated.*/
+       u32 valid_frame;
+
+       /* the number of missed sequence numbers in the squentially */
+       /* values of frames seq numbers */
+       u32 seq_num_miss;
+} __attribute__ ((packed));
+
+struct acx_revision {
+       struct acx_header header;
+
+       /*
+        * The WiLink firmware version, an ASCII string x.x.x.x,
+        * that uniquely identifies the current firmware.
+        * The left most digit is incremented each time a
+        * significant change is made to the firmware, such as
+        * code redesign or new platform support.
+        * The second digit is incremented when major enhancements
+        * are added or major fixes are made.
+        * The third digit is incremented for each GA release.
+        * The fourth digit is incremented for each build.
+        * The first two digits identify a firmware release version,
+        * in other words, a unique set of features.
+        * The first three digits identify a GA release.
+        */
+       char fw_version[20];
+
+       /*
+        * This 4 byte field specifies the WiLink hardware version.
+        * bits 0  - 15: Reserved.
+        * bits 16 - 23: Version ID - The WiLink version ID
+        *              (1 = first spin, 2 = second spin, and so on).
+        * bits 24 - 31: Chip ID - The WiLink chip ID.
+        */
+       u32 hw_version;
+} __attribute__ ((packed));
+
+enum wl12xx_psm_mode {
+       /* Active mode */
+       WL12XX_PSM_CAM = 0,
+
+       /* Power save mode */
+       WL12XX_PSM_PS = 1,
+
+       /* Extreme low power */
+       WL12XX_PSM_ELP = 2,
+};
+
+struct acx_sleep_auth {
+       struct acx_header header;
+
+       /* The sleep level authorization of the device. */
+       /* 0 - Always active*/
+       /* 1 - Power down mode: light / fast sleep*/
+       /* 2 - ELP mode: Deep / Max sleep*/
+       u8  sleep_auth;
+       u8  padding[3];
+} __attribute__ ((packed));
+
+#define TIM_ELE_ID    5
+#define PARTIAL_VBM_MAX    251
+
+struct tim {
+       u8 identity;
+       u8 length;
+       u8 dtim_count;
+       u8 dtim_period;
+       u8 bitmap_ctrl;
+       u8 pvb_field[PARTIAL_VBM_MAX]; /* Partial Virtual Bitmap */
+} __attribute__ ((packed));
+
+/* Virtual Bit Map update */
+struct vbm_update_request {
+       __le16 len;
+       u8  padding[2];
+       struct tim tim;
+} __attribute__ ((packed));
+
+enum {
+       HOSTIF_PCI_MASTER_HOST_INDIRECT,
+       HOSTIF_PCI_MASTER_HOST_DIRECT,
+       HOSTIF_SLAVE,
+       HOSTIF_PKT_RING,
+       HOSTIF_DONTCARE = 0xFF
+};
+
+#define DEFAULT_UCAST_PRIORITY          0
+#define DEFAULT_RX_Q_PRIORITY           0
+#define DEFAULT_NUM_STATIONS            1
+#define DEFAULT_RXQ_PRIORITY            0 /* low 0 .. 15 high  */
+#define DEFAULT_RXQ_TYPE                0x07    /* All frames, Data/Ctrl/Mgmt */
+#define TRACE_BUFFER_MAX_SIZE           256
+
+#define  DP_RX_PACKET_RING_CHUNK_SIZE 1600
+#define  DP_TX_PACKET_RING_CHUNK_SIZE 1600
+#define  DP_RX_PACKET_RING_CHUNK_NUM 2
+#define  DP_TX_PACKET_RING_CHUNK_NUM 2
+#define  DP_TX_COMPLETE_TIME_OUT 20
+#define  FW_TX_CMPLT_BLOCK_SIZE 16
+
+struct acx_data_path_params {
+       struct acx_header header;
+
+       u16 rx_packet_ring_chunk_size;
+       u16 tx_packet_ring_chunk_size;
+
+       u8 rx_packet_ring_chunk_num;
+       u8 tx_packet_ring_chunk_num;
+
+       /*
+        * Maximum number of packets that can be gathered
+        * in the TX complete ring before an interrupt
+        * is generated.
+        */
+       u8 tx_complete_threshold;
+
+       /* Number of pending TX complete entries in cyclic ring.*/
+       u8 tx_complete_ring_depth;
+
+       /*
+        * Max num microseconds since a packet enters the TX
+        * complete ring until an interrupt is generated.
+        */
+       u32 tx_complete_timeout;
+} __attribute__ ((packed));
+
+
+struct acx_data_path_params_resp {
+       struct acx_header header;
+
+       u16 rx_packet_ring_chunk_size;
+       u16 tx_packet_ring_chunk_size;
+
+       u8 rx_packet_ring_chunk_num;
+       u8 tx_packet_ring_chunk_num;
+
+       u8 pad[2];
+
+       u32 rx_packet_ring_addr;
+       u32 tx_packet_ring_addr;
+
+       u32 rx_control_addr;
+       u32 tx_control_addr;
+
+       u32 tx_complete_addr;
+} __attribute__ ((packed));
+
+#define TX_MSDU_LIFETIME_MIN       0
+#define TX_MSDU_LIFETIME_MAX       3000
+#define TX_MSDU_LIFETIME_DEF       512
+#define RX_MSDU_LIFETIME_MIN       0
+#define RX_MSDU_LIFETIME_MAX       0xFFFFFFFF
+#define RX_MSDU_LIFETIME_DEF       512000
+
+struct rx_msdu_lifetime {
+       struct acx_header header;
+
+       /*
+        * The maximum amount of time, in TU, before the
+        * firmware discards the MSDU.
+        */
+       u32 lifetime;
+} __attribute__ ((packed));
+
+/*
+ * RX Config Options Table
+ * Bit         Definition
+ * ===         ==========
+ * 31:14               Reserved
+ * 13          Copy RX Status - when set, write three receive status words
+ *             to top of rx'd MPDUs.
+ *             When cleared, do not write three status words (added rev 1.5)
+ * 12          Reserved
+ * 11          RX Complete upon FCS error - when set, give rx complete
+ *             interrupt for FCS errors, after the rx filtering, e.g. unicast
+ *             frames not to us with FCS error will not generate an interrupt.
+ * 10          SSID Filter Enable - When set, the WiLink discards all beacon,
+ *             probe request, and probe response frames with an SSID that does
+ *             not match the SSID specified by the host in the START/JOIN
+ *             command.
+ *             When clear, the WiLink receives frames with any SSID.
+ * 9           Broadcast Filter Enable - When set, the WiLink discards all
+ *             broadcast frames. When clear, the WiLink receives all received
+ *             broadcast frames.
+ * 8:6         Reserved
+ * 5           BSSID Filter Enable - When set, the WiLink discards any frames
+ *             with a BSSID that does not match the BSSID specified by the
+ *             host.
+ *             When clear, the WiLink receives frames from any BSSID.
+ * 4           MAC Addr Filter - When set, the WiLink discards any frames
+ *             with a destination address that does not match the MAC address
+ *             of the adaptor.
+ *             When clear, the WiLink receives frames destined to any MAC
+ *             address.
+ * 3           Promiscuous - When set, the WiLink receives all valid frames
+ *             (i.e., all frames that pass the FCS check).
+ *             When clear, only frames that pass the other filters specified
+ *             are received.
+ * 2           FCS - When set, the WiLink includes the FCS with the received
+ *             frame.
+ *             When cleared, the FCS is discarded.
+ * 1           PLCP header - When set, write all data from baseband to frame
+ *             buffer including PHY header.
+ * 0           Reserved - Always equal to 0.
+ *
+ * RX Filter Options Table
+ * Bit         Definition
+ * ===         ==========
+ * 31:12               Reserved - Always equal to 0.
+ * 11          Association - When set, the WiLink receives all association
+ *             related frames (association request/response, reassocation
+ *             request/response, and disassociation). When clear, these frames
+ *             are discarded.
+ * 10          Auth/De auth - When set, the WiLink receives all authentication
+ *             and de-authentication frames. When clear, these frames are
+ *             discarded.
+ * 9           Beacon - When set, the WiLink receives all beacon frames.
+ *             When clear, these frames are discarded.
+ * 8           Contention Free - When set, the WiLink receives all contention
+ *             free frames.
+ *             When clear, these frames are discarded.
+ * 7           Control - When set, the WiLink receives all control frames.
+ *             When clear, these frames are discarded.
+ * 6           Data - When set, the WiLink receives all data frames.
+ *             When clear, these frames are discarded.
+ * 5           FCS Error - When set, the WiLink receives frames that have FCS
+ *             errors.
+ *             When clear, these frames are discarded.
+ * 4           Management - When set, the WiLink receives all management
+ *             frames.
+ *             When clear, these frames are discarded.
+ * 3           Probe Request - When set, the WiLink receives all probe request
+ *             frames.
+ *             When clear, these frames are discarded.
+ * 2           Probe Response - When set, the WiLink receives all probe
+ *             response frames.
+ *             When clear, these frames are discarded.
+ * 1           RTS/CTS/ACK - When set, the WiLink receives all RTS, CTS and ACK
+ *             frames.
+ *             When clear, these frames are discarded.
+ * 0           Rsvd Type/Sub Type - When set, the WiLink receives all frames
+ *             that have reserved frame types and sub types as defined by the
+ *             802.11 specification.
+ *             When clear, these frames are discarded.
+ */
+struct acx_rx_config {
+       struct acx_header header;
+
+       u32 config_options;
+       u32 filter_options;
+} __attribute__ ((packed));
+
+enum {
+       QOS_AC_BE = 0,
+       QOS_AC_BK,
+       QOS_AC_VI,
+       QOS_AC_VO,
+       QOS_HIGHEST_AC_INDEX = QOS_AC_VO,
+};
+
+#define MAX_NUM_OF_AC             (QOS_HIGHEST_AC_INDEX+1)
+#define FIRST_AC_INDEX            QOS_AC_BE
+#define MAX_NUM_OF_802_1d_TAGS    8
+#define AC_PARAMS_MAX_TSID        15
+#define MAX_APSD_CONF             0xffff
+
+#define  QOS_TX_HIGH_MIN      (0)
+#define  QOS_TX_HIGH_MAX      (100)
+
+#define  QOS_TX_HIGH_BK_DEF   (25)
+#define  QOS_TX_HIGH_BE_DEF   (35)
+#define  QOS_TX_HIGH_VI_DEF   (35)
+#define  QOS_TX_HIGH_VO_DEF   (35)
+
+#define  QOS_TX_LOW_BK_DEF    (15)
+#define  QOS_TX_LOW_BE_DEF    (25)
+#define  QOS_TX_LOW_VI_DEF    (25)
+#define  QOS_TX_LOW_VO_DEF    (25)
+
+struct acx_tx_queue_qos_config {
+       struct acx_header header;
+
+       u8 qid;
+       u8 pad[3];
+
+       /* Max number of blocks allowd in the queue */
+       u16 high_threshold;
+
+       /* Lowest memory blocks guaranteed for this queue */
+       u16 low_threshold;
+} __attribute__ ((packed));
+
+struct acx_packet_detection {
+       struct acx_header header;
+
+       u32 threshold;
+} __attribute__ ((packed));
+
+
+enum acx_slot_type {
+       SLOT_TIME_LONG = 0,
+       SLOT_TIME_SHORT = 1,
+       DEFAULT_SLOT_TIME = SLOT_TIME_SHORT,
+       MAX_SLOT_TIMES = 0xFF
+};
+
+#define STATION_WONE_INDEX 0
+
+struct acx_slot {
+       struct acx_header header;
+
+       u8 wone_index; /* Reserved */
+       u8 slot_time;
+       u8 reserved[6];
+} __attribute__ ((packed));
+
+
+#define ADDRESS_GROUP_MAX      (8)
+#define ADDRESS_GROUP_MAX_LEN  (ETH_ALEN * ADDRESS_GROUP_MAX)
+
+struct multicast_grp_addr_start {
+       struct acx_header header;
+
+       u8 enabled;
+       u8 num_groups;
+       u8 pad[2];
+       u8 mac_table[ADDRESS_GROUP_MAX_LEN];
+} __attribute__ ((packed));
+
+
+#define  RX_TIMEOUT_PS_POLL_MIN    0
+#define  RX_TIMEOUT_PS_POLL_MAX    (200000)
+#define  RX_TIMEOUT_PS_POLL_DEF    (15)
+#define  RX_TIMEOUT_UPSD_MIN       0
+#define  RX_TIMEOUT_UPSD_MAX       (200000)
+#define  RX_TIMEOUT_UPSD_DEF       (15)
+
+struct acx_rx_timeout {
+       struct acx_header header;
+
+       /*
+        * The longest time the STA will wait to receive
+        * traffic from the AP after a PS-poll has been
+        * transmitted.
+        */
+       u16 ps_poll_timeout;
+
+       /*
+        * The longest time the STA will wait to receive
+        * traffic from the AP after a frame has been sent
+        * from an UPSD enabled queue.
+        */
+       u16 upsd_timeout;
+} __attribute__ ((packed));
+
+#define RTS_THRESHOLD_MIN              0
+#define RTS_THRESHOLD_MAX              4096
+#define RTS_THRESHOLD_DEF              2347
+
+struct acx_rts_threshold {
+       struct acx_header header;
+
+       u16 threshold;
+       u8 pad[2];
+} __attribute__ ((packed));
+
+struct acx_beacon_filter_option {
+       struct acx_header header;
+
+       u8 enable;
+
+       /*
+        * The number of beacons without the unicast TIM
+        * bit set that the firmware buffers before
+        * signaling the host about ready frames.
+        * When set to 0 and the filter is enabled, beacons
+        * without the unicast TIM bit set are dropped.
+        */
+       u8 max_num_beacons;
+       u8 pad[2];
+} __attribute__ ((packed));
+
+/*
+ * ACXBeaconFilterEntry (not 221)
+ * Byte Offset     Size (Bytes)    Definition
+ * ===========     ============    ==========
+ * 0                           1               IE identifier
+ * 1               1               Treatment bit mask
+ *
+ * ACXBeaconFilterEntry (221)
+ * Byte Offset     Size (Bytes)    Definition
+ * ===========     ============    ==========
+ * 0               1               IE identifier
+ * 1               1               Treatment bit mask
+ * 2               3               OUI
+ * 5               1               Type
+ * 6               2               Version
+ *
+ *
+ * Treatment bit mask - The information element handling:
+ * bit 0 - The information element is compared and transferred
+ * in case of change.
+ * bit 1 - The information element is transferred to the host
+ * with each appearance or disappearance.
+ * Note that both bits can be set at the same time.
+ */
+#define        BEACON_FILTER_TABLE_MAX_IE_NUM                 (32)
+#define BEACON_FILTER_TABLE_MAX_VENDOR_SPECIFIC_IE_NUM (6)
+#define BEACON_FILTER_TABLE_IE_ENTRY_SIZE             (2)
+#define BEACON_FILTER_TABLE_EXTRA_VENDOR_SPECIFIC_IE_SIZE (6)
+#define BEACON_FILTER_TABLE_MAX_SIZE ((BEACON_FILTER_TABLE_MAX_IE_NUM * \
+                           BEACON_FILTER_TABLE_IE_ENTRY_SIZE) + \
+                          (BEACON_FILTER_TABLE_MAX_VENDOR_SPECIFIC_IE_NUM * \
+                           BEACON_FILTER_TABLE_EXTRA_VENDOR_SPECIFIC_IE_SIZE))
+
+struct acx_beacon_filter_ie_table {
+       struct acx_header header;
+
+       u8 num_ie;
+       u8 table[BEACON_FILTER_TABLE_MAX_SIZE];
+       u8 pad[3];
+} __attribute__ ((packed));
+
+enum {
+       SG_ENABLE = 0,
+       SG_DISABLE,
+       SG_SENSE_NO_ACTIVITY,
+       SG_SENSE_ACTIVE
+};
+
+struct acx_bt_wlan_coex {
+       struct acx_header header;
+
+       /*
+        * 0 -> PTA enabled
+        * 1 -> PTA disabled
+        * 2 -> sense no active mode, i.e.
+        *      an interrupt is sent upon
+        *      BT activity.
+        * 3 -> PTA is switched on in response
+        *      to the interrupt sending.
+        */
+       u8 enable;
+       u8 pad[3];
+} __attribute__ ((packed));
+
+#define PTA_ANTENNA_TYPE_DEF             (0)
+#define PTA_BT_HP_MAXTIME_DEF            (2000)
+#define PTA_WLAN_HP_MAX_TIME_DEF         (5000)
+#define PTA_SENSE_DISABLE_TIMER_DEF      (1350)
+#define PTA_PROTECTIVE_RX_TIME_DEF       (1500)
+#define PTA_PROTECTIVE_TX_TIME_DEF       (1500)
+#define PTA_TIMEOUT_NEXT_BT_LP_PACKET_DEF (3000)
+#define PTA_SIGNALING_TYPE_DEF           (1)
+#define PTA_AFH_LEVERAGE_ON_DEF                  (0)
+#define PTA_NUMBER_QUIET_CYCLE_DEF       (0)
+#define PTA_MAX_NUM_CTS_DEF              (3)
+#define PTA_NUMBER_OF_WLAN_PACKETS_DEF   (2)
+#define PTA_NUMBER_OF_BT_PACKETS_DEF     (2)
+#define PTA_PROTECTIVE_RX_TIME_FAST_DEF          (1500)
+#define PTA_PROTECTIVE_TX_TIME_FAST_DEF          (3000)
+#define PTA_CYCLE_TIME_FAST_DEF                  (8700)
+#define PTA_RX_FOR_AVALANCHE_DEF         (5)
+#define PTA_ELP_HP_DEF                   (0)
+#define PTA_ANTI_STARVE_PERIOD_DEF       (500)
+#define PTA_ANTI_STARVE_NUM_CYCLE_DEF    (4)
+#define PTA_ALLOW_PA_SD_DEF              (1)
+#define PTA_TIME_BEFORE_BEACON_DEF       (6300)
+#define PTA_HPDM_MAX_TIME_DEF            (1600)
+#define PTA_TIME_OUT_NEXT_WLAN_DEF       (2550)
+#define PTA_AUTO_MODE_NO_CTS_DEF         (0)
+#define PTA_BT_HP_RESPECTED_DEF                  (3)
+#define PTA_WLAN_RX_MIN_RATE_DEF         (24)
+#define PTA_ACK_MODE_DEF                 (1)
+
+struct acx_bt_wlan_coex_param {
+       struct acx_header header;
+
+       /*
+        * The minimum rate of a received WLAN packet in the STA,
+        * during protective mode, of which a new BT-HP request
+        * during this Rx will always be respected and gain the antenna.
+        */
+       u32 min_rate;
+
+       /* Max time the BT HP will be respected. */
+       u16 bt_hp_max_time;
+
+       /* Max time the WLAN HP will be respected. */
+       u16 wlan_hp_max_time;
+
+       /*
+        * The time between the last BT activity
+        * and the moment when the sense mode returns
+        * to SENSE_INACTIVE.
+        */
+       u16 sense_disable_timer;
+
+       /* Time before the next BT HP instance */
+       u16 rx_time_bt_hp;
+       u16 tx_time_bt_hp;
+
+       /* range: 10-20000    default: 1500 */
+       u16 rx_time_bt_hp_fast;
+       u16 tx_time_bt_hp_fast;
+
+       /* range: 2000-65535  default: 8700 */
+       u16 wlan_cycle_fast;
+
+       /* range: 0 - 15000 (Msec) default: 1000 */
+       u16 bt_anti_starvation_period;
+
+       /* range 400-10000(Usec) default: 3000 */
+       u16 next_bt_lp_packet;
+
+       /* Deafult: worst case for BT DH5 traffic */
+       u16 wake_up_beacon;
+
+       /* range: 0-50000(Usec) default: 1050 */
+       u16 hp_dm_max_guard_time;
+
+       /*
+        * This is to prevent both BT & WLAN antenna
+        * starvation.
+        * Range: 100-50000(Usec) default:2550
+        */
+       u16 next_wlan_packet;
+
+       /* 0 -> shared antenna */
+       u8 antenna_type;
+
+       /*
+        * 0 -> TI legacy
+        * 1 -> Palau
+        */
+       u8 signal_type;
+
+       /*
+        * BT AFH status
+        * 0 -> no AFH
+        * 1 -> from dedicated GPIO
+        * 2 -> AFH on (from host)
+        */
+       u8 afh_leverage_on;
+
+       /*
+        * The number of cycles during which no
+        * TX will be sent after 1 cycle of RX
+        * transaction in protective mode
+        */
+       u8 quiet_cycle_num;
+
+       /*
+        * The maximum number of CTSs that will
+        * be sent for receiving RX packet in
+        * protective mode
+        */
+       u8 max_cts;
+
+       /*
+        * The number of WLAN packets
+        * transferred in common mode before
+        * switching to BT.
+        */
+       u8 wlan_packets_num;
+
+       /*
+        * The number of BT packets
+        * transferred in common mode before
+        * switching to WLAN.
+        */
+       u8 bt_packets_num;
+
+       /* range: 1-255  default: 5 */
+       u8 missed_rx_avalanche;
+
+       /* range: 0-1    default: 1 */
+       u8 wlan_elp_hp;
+
+       /* range: 0 - 15  default: 4 */
+       u8 bt_anti_starvation_cycles;
+
+       u8 ack_mode_dual_ant;
+
+       /*
+        * Allow PA_SD assertion/de-assertion
+        * during enabled BT activity.
+        */
+       u8 pa_sd_enable;
+
+       /*
+        * Enable/Disable PTA in auto mode:
+        * Support Both Active & P.S modes
+        */
+       u8 pta_auto_mode_enable;
+
+       /* range: 0 - 20  default: 1 */
+       u8 bt_hp_respected_num;
+} __attribute__ ((packed));
+
+#define CCA_THRSH_ENABLE_ENERGY_D       0x140A
+#define CCA_THRSH_DISABLE_ENERGY_D      0xFFEF
+
+struct acx_energy_detection {
+       struct acx_header header;
+
+       /* The RX Clear Channel Assessment threshold in the PHY */
+       u16 rx_cca_threshold;
+       u8 tx_energy_detection;
+       u8 pad;
+} __attribute__ ((packed));
+
+#define BCN_RX_TIMEOUT_DEF_VALUE        10000
+#define BROADCAST_RX_TIMEOUT_DEF_VALUE  20000
+#define RX_BROADCAST_IN_PS_DEF_VALUE    1
+#define CONSECUTIVE_PS_POLL_FAILURE_DEF 4
+
+struct acx_beacon_broadcast {
+       struct acx_header header;
+
+       u16 beacon_rx_timeout;
+       u16 broadcast_timeout;
+
+       /* Enables receiving of broadcast packets in PS mode */
+       u8 rx_broadcast_in_ps;
+
+       /* Consecutive PS Poll failures before updating the host */
+       u8 ps_poll_threshold;
+       u8 pad[2];
+} __attribute__ ((packed));
+
+struct acx_event_mask {
+       struct acx_header header;
+
+       u32 event_mask;
+       u32 high_event_mask; /* Unused */
+} __attribute__ ((packed));
+
+#define CFG_RX_FCS             BIT(2)
+#define CFG_RX_ALL_GOOD                BIT(3)
+#define CFG_UNI_FILTER_EN      BIT(4)
+#define CFG_BSSID_FILTER_EN    BIT(5)
+#define CFG_MC_FILTER_EN       BIT(6)
+#define CFG_MC_ADDR0_EN                BIT(7)
+#define CFG_MC_ADDR1_EN                BIT(8)
+#define CFG_BC_REJECT_EN       BIT(9)
+#define CFG_SSID_FILTER_EN     BIT(10)
+#define CFG_RX_INT_FCS_ERROR   BIT(11)
+#define CFG_RX_INT_ENCRYPTED   BIT(12)
+#define CFG_RX_WR_RX_STATUS    BIT(13)
+#define CFG_RX_FILTER_NULTI    BIT(14)
+#define CFG_RX_RESERVE         BIT(15)
+#define CFG_RX_TIMESTAMP_TSF   BIT(16)
+
+#define CFG_RX_RSV_EN          BIT(0)
+#define CFG_RX_RCTS_ACK                BIT(1)
+#define CFG_RX_PRSP_EN         BIT(2)
+#define CFG_RX_PREQ_EN         BIT(3)
+#define CFG_RX_MGMT_EN         BIT(4)
+#define CFG_RX_FCS_ERROR       BIT(5)
+#define CFG_RX_DATA_EN         BIT(6)
+#define CFG_RX_CTL_EN          BIT(7)
+#define CFG_RX_CF_EN           BIT(8)
+#define CFG_RX_BCN_EN          BIT(9)
+#define CFG_RX_AUTH_EN         BIT(10)
+#define CFG_RX_ASSOC_EN                BIT(11)
+
+#define SCAN_PASSIVE           BIT(0)
+#define SCAN_5GHZ_BAND         BIT(1)
+#define SCAN_TRIGGERED         BIT(2)
+#define SCAN_PRIORITY_HIGH     BIT(3)
+
+struct acx_fw_gen_frame_rates {
+       struct acx_header header;
+
+       u8 tx_ctrl_frame_rate; /* RATE_* */
+       u8 tx_ctrl_frame_mod; /* CCK_* or PBCC_* */
+       u8 tx_mgt_frame_rate;
+       u8 tx_mgt_frame_mod;
+} __attribute__ ((packed));
+
+/* STA MAC */
+struct dot11_station_id {
+       struct acx_header header;
+
+       u8 mac[ETH_ALEN];
+       u8 pad[2];
+} __attribute__ ((packed));
+
+/* HW encryption keys */
+#define NUM_ACCESS_CATEGORIES_COPY 4
+#define MAX_KEY_SIZE 32
+
+/* When set, disable HW encryption */
+#define DF_ENCRYPTION_DISABLE      0x01
+/* When set, disable HW decryption */
+#define DF_SNIFF_MODE_ENABLE       0x80
+
+struct acx_feature_config {
+       struct acx_header header;
+
+       u32 options;
+       u32 data_flow_options;
+} __attribute__ ((packed));
+
+enum acx_key_action {
+       KEY_ADD_OR_REPLACE = 1,
+       KEY_REMOVE         = 2,
+       KEY_SET_ID         = 3,
+       MAX_KEY_ACTION     = 0xffff,
+};
+
+enum acx_key_type {
+       KEY_WEP_DEFAULT       = 0,
+       KEY_WEP_ADDR          = 1,
+       KEY_AES_GROUP         = 4,
+       KEY_AES_PAIRWISE      = 5,
+       KEY_WEP_GROUP         = 6,
+       KEY_TKIP_MIC_GROUP    = 10,
+       KEY_TKIP_MIC_PAIRWISE = 11,
+};
+
+/*
+ *
+ * key_type_e   key size    key format
+ * ----------   ---------   ----------
+ * 0x00         5, 13, 29   Key data
+ * 0x01         5, 13, 29   Key data
+ * 0x04         16          16 bytes of key data
+ * 0x05         16          16 bytes of key data
+ * 0x0a         32          16 bytes of TKIP key data
+ *                          8 bytes of RX MIC key data
+ *                          8 bytes of TX MIC key data
+ * 0x0b         32          16 bytes of TKIP key data
+ *                          8 bytes of RX MIC key data
+ *                          8 bytes of TX MIC key data
+ *
+ */
+
+struct acx_set_key {
+       /* Ignored for default WEP key */
+       u8 addr[ETH_ALEN];
+
+       /* key_action_e */
+       u16 key_action;
+
+       u16 reserved_1;
+
+       /* key size in bytes */
+       u8 key_size;
+
+       /* key_type_e */
+       u8 key_type;
+       u8 ssid_profile;
+
+       /*
+        * TKIP, AES: frame's key id field.
+        * For WEP default key: key id;
+        */
+       u8 id;
+       u8 reserved_2[6];
+       u8 key[MAX_KEY_SIZE];
+       u16 ac_seq_num16[NUM_ACCESS_CATEGORIES_COPY];
+       u32 ac_seq_num32[NUM_ACCESS_CATEGORIES_COPY];
+} __attribute__ ((packed));
+
+struct acx_current_tx_power {
+       struct acx_header header;
+
+       u8  current_tx_power;
+       u8  padding[3];
+} __attribute__ ((packed));
+
+struct acx_dot11_default_key {
+       struct acx_header header;
+
+       u8 id;
+       u8 pad[3];
+} __attribute__ ((packed));
+
+struct acx_tsf_info {
+       struct acx_header header;
+
+       u32 current_tsf_msb;
+       u32 current_tsf_lsb;
+       u32 last_TBTT_msb;
+       u32 last_TBTT_lsb;
+       u8 last_dtim_count;
+       u8 pad[3];
+} __attribute__ ((packed));
+
+/* 802.11 PS */
+enum acx_ps_mode {
+       STATION_ACTIVE_MODE,
+       STATION_POWER_SAVE_MODE
+};
+
+struct acx_ps_params {
+       u8 ps_mode; /* STATION_* */
+       u8 send_null_data; /* Do we have to send NULL data packet ? */
+       u8 retries; /* Number of retires for the initial NULL data packet */
+
+        /*
+         * TUs during which the target stays awake after switching
+         * to power save mode.
+         */
+       u8 hang_over_period;
+       u16 null_data_rate;
+       u8 pad[2];
+} __attribute__ ((packed));
+
+enum acx_wake_up_event {
+       WAKE_UP_EVENT_BEACON_BITMAP     = 0x01, /* Wake on every Beacon*/
+       WAKE_UP_EVENT_DTIM_BITMAP       = 0x02, /* Wake on every DTIM*/
+       WAKE_UP_EVENT_N_DTIM_BITMAP     = 0x04, /* Wake on every Nth DTIM */
+       WAKE_UP_EVENT_N_BEACONS_BITMAP  = 0x08, /* Wake on every Nth Beacon */
+       WAKE_UP_EVENT_BITS_MASK         = 0x0F
+};
+
+struct acx_wake_up_condition {
+       struct acx_header header;
+
+       u8 wake_up_event; /* Only one bit can be set */
+       u8 listen_interval;
+       u8 pad[2];
+} __attribute__ ((packed));
+
+struct acx_aid {
+       struct acx_header header;
+
+       /*
+        * To be set when associated with an AP.
+        */
+       u16 aid;
+       u8 pad[2];
+} __attribute__ ((packed));
+
+enum acx_preamble_type {
+       ACX_PREAMBLE_LONG = 0,
+       ACX_PREAMBLE_SHORT = 1
+};
+
+struct acx_preamble {
+       struct acx_header header;
+       /*
+        * When set, the WiLink transmits the frames with a short preamble and
+        * when cleared, the WiLink transmits the frames with a long preamble.
+        */
+       u8 preamble;
+       u8 padding[3];
+} __attribute__ ((packed));
+
+enum acx_ctsprotect_type {
+       CTSPROTECT_DISABLE = 0,
+       CTSPROTECT_ENABLE = 1
+};
+
+struct acx_ctsprotect {
+       struct acx_header header;
+       u8 ctsprotect;
+       u8 padding[3];
+} __attribute__ ((packed));
+
+struct acx_tx_statistics {
+       u32 internal_desc_overflow;
+}  __attribute__ ((packed));
+
+struct acx_rx_statistics {
+       u32 out_of_mem;
+       u32 hdr_overflow;
+       u32 hw_stuck;
+       u32 dropped;
+       u32 fcs_err;
+       u32 xfr_hint_trig;
+       u32 path_reset;
+       u32 reset_counter;
+} __attribute__ ((packed));
+
+struct acx_dma_statistics {
+       u32 rx_requested;
+       u32 rx_errors;
+       u32 tx_requested;
+       u32 tx_errors;
+}  __attribute__ ((packed));
+
+struct acx_isr_statistics {
+       /* host command complete */
+       u32 cmd_cmplt;
+
+       /* fiqisr() */
+       u32 fiqs;
+
+       /* (INT_STS_ND & INT_TRIG_RX_HEADER) */
+       u32 rx_headers;
+
+       /* (INT_STS_ND & INT_TRIG_RX_CMPLT) */
+       u32 rx_completes;
+
+       /* (INT_STS_ND & INT_TRIG_NO_RX_BUF) */
+       u32 rx_mem_overflow;
+
+       /* (INT_STS_ND & INT_TRIG_S_RX_RDY) */
+       u32 rx_rdys;
+
+       /* irqisr() */
+       u32 irqs;
+
+       /* (INT_STS_ND & INT_TRIG_TX_PROC) */
+       u32 tx_procs;
+
+       /* (INT_STS_ND & INT_TRIG_DECRYPT_DONE) */
+       u32 decrypt_done;
+
+       /* (INT_STS_ND & INT_TRIG_DMA0) */
+       u32 dma0_done;
+
+       /* (INT_STS_ND & INT_TRIG_DMA1) */
+       u32 dma1_done;
+
+       /* (INT_STS_ND & INT_TRIG_TX_EXC_CMPLT) */
+       u32 tx_exch_complete;
+
+       /* (INT_STS_ND & INT_TRIG_COMMAND) */
+       u32 commands;
+
+       /* (INT_STS_ND & INT_TRIG_RX_PROC) */
+       u32 rx_procs;
+
+       /* (INT_STS_ND & INT_TRIG_PM_802) */
+       u32 hw_pm_mode_changes;
+
+       /* (INT_STS_ND & INT_TRIG_ACKNOWLEDGE) */
+       u32 host_acknowledges;
+
+       /* (INT_STS_ND & INT_TRIG_PM_PCI) */
+       u32 pci_pm;
+
+       /* (INT_STS_ND & INT_TRIG_ACM_WAKEUP) */
+       u32 wakeups;
+
+       /* (INT_STS_ND & INT_TRIG_LOW_RSSI) */
+       u32 low_rssi;
+} __attribute__ ((packed));
+
+struct acx_wep_statistics {
+       /* WEP address keys configured */
+       u32 addr_key_count;
+
+       /* default keys configured */
+       u32 default_key_count;
+
+       u32 reserved;
+
+       /* number of times that WEP key not found on lookup */
+       u32 key_not_found;
+
+       /* number of times that WEP key decryption failed */
+       u32 decrypt_fail;
+
+       /* WEP packets decrypted */
+       u32 packets;
+
+       /* WEP decrypt interrupts */
+       u32 interrupt;
+} __attribute__ ((packed));
+
+#define ACX_MISSED_BEACONS_SPREAD 10
+
+struct acx_pwr_statistics {
+       /* the amount of enters into power save mode (both PD & ELP) */
+       u32 ps_enter;
+
+       /* the amount of enters into ELP mode */
+       u32 elp_enter;
+
+       /* the amount of missing beacon interrupts to the host */
+       u32 missing_bcns;
+
+       /* the amount of wake on host-access times */
+       u32 wake_on_host;
+
+       /* the amount of wake on timer-expire */
+       u32 wake_on_timer_exp;
+
+       /* the number of packets that were transmitted with PS bit set */
+       u32 tx_with_ps;
+
+       /* the number of packets that were transmitted with PS bit clear */
+       u32 tx_without_ps;
+
+       /* the number of received beacons */
+       u32 rcvd_beacons;
+
+       /* the number of entering into PowerOn (power save off) */
+       u32 power_save_off;
+
+       /* the number of entries into power save mode */
+       u16 enable_ps;
+
+       /*
+        * the number of exits from power save, not including failed PS
+        * transitions
+        */
+       u16 disable_ps;
+
+       /*
+        * the number of times the TSF counter was adjusted because
+        * of drift
+        */
+       u32 fix_tsf_ps;
+
+       /* Gives statistics about the spread continuous missed beacons.
+        * The 16 LSB are dedicated for the PS mode.
+        * The 16 MSB are dedicated for the PS mode.
+        * cont_miss_bcns_spread[0] - single missed beacon.
+        * cont_miss_bcns_spread[1] - two continuous missed beacons.
+        * cont_miss_bcns_spread[2] - three continuous missed beacons.
+        * ...
+        * cont_miss_bcns_spread[9] - ten and more continuous missed beacons.
+       */
+       u32 cont_miss_bcns_spread[ACX_MISSED_BEACONS_SPREAD];
+
+       /* the number of beacons in awake mode */
+       u32 rcvd_awake_beacons;
+} __attribute__ ((packed));
+
+struct acx_mic_statistics {
+       u32 rx_pkts;
+       u32 calc_failure;
+} __attribute__ ((packed));
+
+struct acx_aes_statistics {
+       u32 encrypt_fail;
+       u32 decrypt_fail;
+       u32 encrypt_packets;
+       u32 decrypt_packets;
+       u32 encrypt_interrupt;
+       u32 decrypt_interrupt;
+} __attribute__ ((packed));
+
+struct acx_event_statistics {
+       u32 heart_beat;
+       u32 calibration;
+       u32 rx_mismatch;
+       u32 rx_mem_empty;
+       u32 rx_pool;
+       u32 oom_late;
+       u32 phy_transmit_error;
+       u32 tx_stuck;
+} __attribute__ ((packed));
+
+struct acx_ps_statistics {
+       u32 pspoll_timeouts;
+       u32 upsd_timeouts;
+       u32 upsd_max_sptime;
+       u32 upsd_max_apturn;
+       u32 pspoll_max_apturn;
+       u32 pspoll_utilization;
+       u32 upsd_utilization;
+} __attribute__ ((packed));
+
+struct acx_rxpipe_statistics {
+       u32 rx_prep_beacon_drop;
+       u32 descr_host_int_trig_rx_data;
+       u32 beacon_buffer_thres_host_int_trig_rx_data;
+       u32 missed_beacon_host_int_trig_rx_data;
+       u32 tx_xfr_host_int_trig_rx_data;
+} __attribute__ ((packed));
+
+struct acx_statistics {
+       struct acx_header header;
+
+       struct acx_tx_statistics tx;
+       struct acx_rx_statistics rx;
+       struct acx_dma_statistics dma;
+       struct acx_isr_statistics isr;
+       struct acx_wep_statistics wep;
+       struct acx_pwr_statistics pwr;
+       struct acx_aes_statistics aes;
+       struct acx_mic_statistics mic;
+       struct acx_event_statistics event;
+       struct acx_ps_statistics ps;
+       struct acx_rxpipe_statistics rxpipe;
+} __attribute__ ((packed));
+
+enum {
+       ACX_WAKE_UP_CONDITIONS      = 0x0002,
+       ACX_MEM_CFG                 = 0x0003,
+       ACX_SLOT                    = 0x0004,
+       ACX_QUEUE_HEAD              = 0x0005, /* for MASTER mode only */
+       ACX_AC_CFG                  = 0x0007,
+       ACX_MEM_MAP                 = 0x0008,
+       ACX_AID                     = 0x000A,
+       ACX_RADIO_PARAM             = 0x000B, /* Not used */
+       ACX_CFG                     = 0x000C, /* Not used */
+       ACX_FW_REV                  = 0x000D,
+       ACX_MEDIUM_USAGE            = 0x000F,
+       ACX_RX_CFG                  = 0x0010,
+       ACX_TX_QUEUE_CFG            = 0x0011, /* FIXME: only used by wl1251 */
+       ACX_BSS_IN_PS               = 0x0012, /* for AP only */
+       ACX_STATISTICS              = 0x0013, /* Debug API */
+       ACX_FEATURE_CFG             = 0x0015,
+       ACX_MISC_CFG                = 0x0017, /* Not used */
+       ACX_TID_CFG                 = 0x001A,
+       ACX_BEACON_FILTER_OPT       = 0x001F,
+       ACX_LOW_RSSI                = 0x0020,
+       ACX_NOISE_HIST              = 0x0021,
+       ACX_HDK_VERSION             = 0x0022, /* ??? */
+       ACX_PD_THRESHOLD            = 0x0023,
+       ACX_DATA_PATH_PARAMS        = 0x0024, /* WO */
+       ACX_DATA_PATH_RESP_PARAMS   = 0x0024, /* RO */
+       ACX_CCA_THRESHOLD           = 0x0025,
+       ACX_EVENT_MBOX_MASK         = 0x0026,
+#ifdef FW_RUNNING_AS_AP
+       ACX_DTIM_PERIOD             = 0x0027, /* for AP only */
+#else
+       ACX_WR_TBTT_AND_DTIM        = 0x0027, /* STA only */
+#endif
+       ACX_ACI_OPTION_CFG          = 0x0029, /* OBSOLETE (for 1251)*/
+       ACX_GPIO_CFG                = 0x002A, /* Not used */
+       ACX_GPIO_SET                = 0x002B, /* Not used */
+       ACX_PM_CFG                  = 0x002C, /* To Be Documented */
+       ACX_CONN_MONIT_PARAMS       = 0x002D,
+       ACX_AVERAGE_RSSI            = 0x002E, /* Not used */
+       ACX_CONS_TX_FAILURE         = 0x002F,
+       ACX_BCN_DTIM_OPTIONS        = 0x0031,
+       ACX_SG_ENABLE               = 0x0032,
+       ACX_SG_CFG                  = 0x0033,
+       ACX_ANTENNA_DIVERSITY_CFG   = 0x0035, /* To Be Documented */
+       ACX_LOW_SNR                 = 0x0037, /* To Be Documented */
+       ACX_BEACON_FILTER_TABLE     = 0x0038,
+       ACX_ARP_IP_FILTER           = 0x0039,
+       ACX_ROAMING_STATISTICS_TBL  = 0x003B,
+       ACX_RATE_POLICY             = 0x003D,
+       ACX_CTS_PROTECTION          = 0x003E,
+       ACX_SLEEP_AUTH              = 0x003F,
+       ACX_PREAMBLE_TYPE           = 0x0040,
+       ACX_ERROR_CNT               = 0x0041,
+       ACX_FW_GEN_FRAME_RATES      = 0x0042,
+       ACX_IBSS_FILTER             = 0x0044,
+       ACX_SERVICE_PERIOD_TIMEOUT  = 0x0045,
+       ACX_TSF_INFO                = 0x0046,
+       ACX_CONFIG_PS_WMM           = 0x0049,
+       ACX_ENABLE_RX_DATA_FILTER   = 0x004A,
+       ACX_SET_RX_DATA_FILTER      = 0x004B,
+       ACX_GET_DATA_FILTER_STATISTICS = 0x004C,
+       ACX_POWER_LEVEL_TABLE       = 0x004D,
+       ACX_BET_ENABLE              = 0x0050,
+       DOT11_STATION_ID            = 0x1001,
+       DOT11_RX_MSDU_LIFE_TIME     = 0x1004,
+       DOT11_CUR_TX_PWR            = 0x100D,
+       DOT11_DEFAULT_KEY           = 0x1010,
+       DOT11_RX_DOT11_MODE         = 0x1012,
+       DOT11_RTS_THRESHOLD         = 0x1013,
+       DOT11_GROUP_ADDRESS_TBL     = 0x1014,
+
+       MAX_DOT11_IE = DOT11_GROUP_ADDRESS_TBL,
+
+       MAX_IE = 0xFFFF
+};
+
+
+int wl12xx_acx_frame_rates(struct wl12xx *wl, u8 ctrl_rate, u8 ctrl_mod,
+                          u8 mgt_rate, u8 mgt_mod);
+int wl12xx_acx_station_id(struct wl12xx *wl);
+int wl12xx_acx_default_key(struct wl12xx *wl, u8 key_id);
+int wl12xx_acx_wake_up_conditions(struct wl12xx *wl, u8 listen_interval);
+int wl12xx_acx_sleep_auth(struct wl12xx *wl, u8 sleep_auth);
+int wl12xx_acx_fw_version(struct wl12xx *wl, char *buf, size_t len);
+int wl12xx_acx_tx_power(struct wl12xx *wl, int power);
+int wl12xx_acx_feature_cfg(struct wl12xx *wl);
+int wl12xx_acx_mem_map(struct wl12xx *wl, void *mem_map, size_t len);
+int wl12xx_acx_data_path_params(struct wl12xx *wl,
+                               struct acx_data_path_params_resp *data_path);
+int wl12xx_acx_rx_msdu_life_time(struct wl12xx *wl, u32 life_time);
+int wl12xx_acx_rx_config(struct wl12xx *wl, u32 config, u32 filter);
+int wl12xx_acx_pd_threshold(struct wl12xx *wl);
+int wl12xx_acx_slot(struct wl12xx *wl, enum acx_slot_type slot_time);
+int wl12xx_acx_group_address_tbl(struct wl12xx *wl);
+int wl12xx_acx_service_period_timeout(struct wl12xx *wl);
+int wl12xx_acx_rts_threshold(struct wl12xx *wl, u16 rts_threshold);
+int wl12xx_acx_beacon_filter_opt(struct wl12xx *wl);
+int wl12xx_acx_beacon_filter_table(struct wl12xx *wl);
+int wl12xx_acx_sg_enable(struct wl12xx *wl);
+int wl12xx_acx_sg_cfg(struct wl12xx *wl);
+int wl12xx_acx_cca_threshold(struct wl12xx *wl);
+int wl12xx_acx_bcn_dtim_options(struct wl12xx *wl);
+int wl12xx_acx_aid(struct wl12xx *wl, u16 aid);
+int wl12xx_acx_event_mbox_mask(struct wl12xx *wl, u32 event_mask);
+int wl12xx_acx_set_preamble(struct wl12xx *wl, enum acx_preamble_type preamble);
+int wl12xx_acx_cts_protect(struct wl12xx *wl,
+                           enum acx_ctsprotect_type ctsprotect);
+int wl12xx_acx_statistics(struct wl12xx *wl, struct acx_statistics *stats);
+
+#endif /* __WL12XX_ACX_H__ */
diff --git a/drivers/net/wireless/wl12xx/boot.c b/drivers/net/wireless/wl12xx/boot.c
new file mode 100644 (file)
index 0000000..48ac08c
--- /dev/null
@@ -0,0 +1,295 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/gpio.h>
+
+#include "reg.h"
+#include "boot.h"
+#include "spi.h"
+#include "event.h"
+
+static void wl12xx_boot_enable_interrupts(struct wl12xx *wl)
+{
+       enable_irq(wl->irq);
+}
+
+void wl12xx_boot_target_enable_interrupts(struct wl12xx *wl)
+{
+       wl12xx_reg_write32(wl, ACX_REG_INTERRUPT_MASK, ~(wl->intr_mask));
+       wl12xx_reg_write32(wl, HI_CFG, HI_CFG_DEF_VAL);
+}
+
+int wl12xx_boot_soft_reset(struct wl12xx *wl)
+{
+       unsigned long timeout;
+       u32 boot_data;
+
+       /* perform soft reset */
+       wl12xx_reg_write32(wl, ACX_REG_SLV_SOFT_RESET, ACX_SLV_SOFT_RESET_BIT);
+
+       /* SOFT_RESET is self clearing */
+       timeout = jiffies + usecs_to_jiffies(SOFT_RESET_MAX_TIME);
+       while (1) {
+               boot_data = wl12xx_reg_read32(wl, ACX_REG_SLV_SOFT_RESET);
+               wl12xx_debug(DEBUG_BOOT, "soft reset bootdata 0x%x", boot_data);
+               if ((boot_data & ACX_SLV_SOFT_RESET_BIT) == 0)
+                       break;
+
+               if (time_after(jiffies, timeout)) {
+                       /* 1.2 check pWhalBus->uSelfClearTime if the
+                        * timeout was reached */
+                       wl12xx_error("soft reset timeout");
+                       return -1;
+               }
+
+               udelay(SOFT_RESET_STALL_TIME);
+       }
+
+       /* disable Rx/Tx */
+       wl12xx_reg_write32(wl, ENABLE, 0x0);
+
+       /* disable auto calibration on start*/
+       wl12xx_reg_write32(wl, SPARE_A2, 0xffff);
+
+       return 0;
+}
+
+int wl12xx_boot_init_seq(struct wl12xx *wl)
+{
+       u32 scr_pad6, init_data, tmp, elp_cmd, ref_freq;
+
+       /*
+        * col #1: INTEGER_DIVIDER
+        * col #2: FRACTIONAL_DIVIDER
+        * col #3: ATTN_BB
+        * col #4: ALPHA_BB
+        * col #5: STOP_TIME_BB
+        * col #6: BB_PLL_LOOP_FILTER
+        */
+       static const u32 LUT[REF_FREQ_NUM][LUT_PARAM_NUM] = {
+
+               {   83, 87381,  0xB, 5, 0xF00,  3}, /* REF_FREQ_19_2*/
+               {   61, 141154, 0xB, 5, 0x1450, 2}, /* REF_FREQ_26_0*/
+               {   41, 174763, 0xC, 6, 0x2D00, 1}, /* REF_FREQ_38_4*/
+               {   40, 0,      0xC, 6, 0x2EE0, 1}, /* REF_FREQ_40_0*/
+               {   47, 162280, 0xC, 6, 0x2760, 1}  /* REF_FREQ_33_6        */
+       };
+
+       /* read NVS params */
+       scr_pad6 = wl12xx_reg_read32(wl, SCR_PAD6);
+       wl12xx_debug(DEBUG_BOOT, "scr_pad6 0x%x", scr_pad6);
+
+       /* read ELP_CMD */
+       elp_cmd = wl12xx_reg_read32(wl, ELP_CMD);
+       wl12xx_debug(DEBUG_BOOT, "elp_cmd 0x%x", elp_cmd);
+
+       /* set the BB calibration time to be 300 usec (PLL_CAL_TIME) */
+       ref_freq = scr_pad6 & 0x000000FF;
+       wl12xx_debug(DEBUG_BOOT, "ref_freq 0x%x", ref_freq);
+
+       wl12xx_reg_write32(wl, PLL_CAL_TIME, 0x9);
+
+       /*
+        * PG 1.2: set the clock buffer time to be 210 usec (CLK_BUF_TIME)
+        */
+       wl12xx_reg_write32(wl, CLK_BUF_TIME, 0x6);
+
+       /*
+        * set the clock detect feature to work in the restart wu procedure
+        * (ELP_CFG_MODE[14]) and Select the clock source type
+        * (ELP_CFG_MODE[13:12])
+        */
+       tmp = ((scr_pad6 & 0x0000FF00) << 4) | 0x00004000;
+       wl12xx_reg_write32(wl, ELP_CFG_MODE, tmp);
+
+       /* PG 1.2: enable the BB PLL fix. Enable the PLL_LIMP_CLK_EN_CMD */
+       elp_cmd |= 0x00000040;
+       wl12xx_reg_write32(wl, ELP_CMD, elp_cmd);
+
+       /* PG 1.2: Set the BB PLL stable time to be 1000usec
+        * (PLL_STABLE_TIME) */
+       wl12xx_reg_write32(wl, CFG_PLL_SYNC_CNT, 0x20);
+
+       /* PG 1.2: read clock request time */
+       init_data = wl12xx_reg_read32(wl, CLK_REQ_TIME);
+
+       /*
+        * PG 1.2: set the clock request time to be ref_clk_settling_time -
+        * 1ms = 4ms
+        */
+       if (init_data > 0x21)
+               tmp = init_data - 0x21;
+       else
+               tmp = 0;
+       wl12xx_reg_write32(wl, CLK_REQ_TIME, tmp);
+
+       /* set BB PLL configurations in RF AFE */
+       wl12xx_reg_write32(wl, 0x003058cc, 0x4B5);
+
+       /* set RF_AFE_REG_5 */
+       wl12xx_reg_write32(wl, 0x003058d4, 0x50);
+
+       /* set RF_AFE_CTRL_REG_2 */
+       wl12xx_reg_write32(wl, 0x00305948, 0x11c001);
+
+       /*
+        * change RF PLL and BB PLL divider for VCO clock and adjust VCO
+        * bais current(RF_AFE_REG_13)
+        */
+       wl12xx_reg_write32(wl, 0x003058f4, 0x1e);
+
+       /* set BB PLL configurations */
+       tmp = LUT[ref_freq][LUT_PARAM_INTEGER_DIVIDER] | 0x00017000;
+       wl12xx_reg_write32(wl, 0x00305840, tmp);
+
+       /* set fractional divider according to Appendix C-BB PLL
+        * Calculations
+        */
+       tmp = LUT[ref_freq][LUT_PARAM_FRACTIONAL_DIVIDER];
+       wl12xx_reg_write32(wl, 0x00305844, tmp);
+
+       /* set the initial data for the sigma delta */
+       wl12xx_reg_write32(wl, 0x00305848, 0x3039);
+
+       /*
+        * set the accumulator attenuation value, calibration loop1
+        * (alpha), calibration loop2 (beta), calibration loop3 (gamma) and
+        * the VCO gain
+        */
+       tmp = (LUT[ref_freq][LUT_PARAM_ATTN_BB] << 16) |
+               (LUT[ref_freq][LUT_PARAM_ALPHA_BB] << 12) | 0x1;
+       wl12xx_reg_write32(wl, 0x00305854, tmp);
+
+       /*
+        * set the calibration stop time after holdoff time expires and set
+        * settling time HOLD_OFF_TIME_BB
+        */
+       tmp = LUT[ref_freq][LUT_PARAM_STOP_TIME_BB] | 0x000A0000;
+       wl12xx_reg_write32(wl, 0x00305858, tmp);
+
+       /*
+        * set BB PLL Loop filter capacitor3- BB_C3[2:0] and set BB PLL
+        * constant leakage current to linearize PFD to 0uA -
+        * BB_ILOOPF[7:3]
+        */
+       tmp = LUT[ref_freq][LUT_PARAM_BB_PLL_LOOP_FILTER] | 0x00000030;
+       wl12xx_reg_write32(wl, 0x003058f8, tmp);
+
+       /*
+        * set regulator output voltage for n divider to
+        * 1.35-BB_REFDIV[1:0], set charge pump current- BB_CPGAIN[4:2],
+        * set BB PLL Loop filter capacitor2- BB_C2[7:5], set gain of BB
+        * PLL auto-call to normal mode- BB_CALGAIN_3DB[8]
+        */
+       wl12xx_reg_write32(wl, 0x003058f0, 0x29);
+
+       /* enable restart wakeup sequence (ELP_CMD[0]) */
+       wl12xx_reg_write32(wl, ELP_CMD, elp_cmd | 0x1);
+
+       /* restart sequence completed */
+       udelay(2000);
+
+       return 0;
+}
+
+int wl12xx_boot_run_firmware(struct wl12xx *wl)
+{
+       int loop, ret;
+       u32 chip_id, interrupt;
+
+       wl->chip.op_set_ecpu_ctrl(wl, ECPU_CONTROL_HALT);
+
+       chip_id = wl12xx_reg_read32(wl, CHIP_ID_B);
+
+       wl12xx_debug(DEBUG_BOOT, "chip id after firmware boot: 0x%x", chip_id);
+
+       if (chip_id != wl->chip.id) {
+               wl12xx_error("chip id doesn't match after firmware boot");
+               return -EIO;
+       }
+
+       /* wait for init to complete */
+       loop = 0;
+       while (loop++ < INIT_LOOP) {
+               udelay(INIT_LOOP_DELAY);
+               interrupt = wl12xx_reg_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR);
+
+               if (interrupt == 0xffffffff) {
+                       wl12xx_error("error reading hardware complete "
+                                    "init indication");
+                       return -EIO;
+               }
+               /* check that ACX_INTR_INIT_COMPLETE is enabled */
+               else if (interrupt & wl->chip.intr_init_complete) {
+                       wl12xx_reg_write32(wl, ACX_REG_INTERRUPT_ACK,
+                                          wl->chip.intr_init_complete);
+                       break;
+               }
+       }
+
+       if (loop >= INIT_LOOP) {
+               wl12xx_error("timeout waiting for the hardware to "
+                            "complete initialization");
+               return -EIO;
+       }
+
+       /* get hardware config command mail box */
+       wl->cmd_box_addr = wl12xx_reg_read32(wl, REG_COMMAND_MAILBOX_PTR);
+
+       /* get hardware config event mail box */
+       wl->event_box_addr = wl12xx_reg_read32(wl, REG_EVENT_MAILBOX_PTR);
+
+       /* set the working partition to its "running" mode offset */
+       wl12xx_set_partition(wl,
+                            wl->chip.p_table[PART_WORK].mem.start,
+                            wl->chip.p_table[PART_WORK].mem.size,
+                            wl->chip.p_table[PART_WORK].reg.start,
+                            wl->chip.p_table[PART_WORK].reg.size);
+
+       wl12xx_debug(DEBUG_MAILBOX, "cmd_box_addr 0x%x event_box_addr 0x%x",
+                    wl->cmd_box_addr, wl->event_box_addr);
+
+       /*
+        * in case of full asynchronous mode the firmware event must be
+        * ready to receive event from the command mailbox
+        */
+
+       /* enable gpio interrupts */
+       wl12xx_boot_enable_interrupts(wl);
+
+       wl->chip.op_target_enable_interrupts(wl);
+
+       /* unmask all mbox events  */
+       wl->event_mask = 0xffffffff;
+
+       ret = wl12xx_event_unmask(wl);
+       if (ret < 0) {
+               wl12xx_error("EVENT mask setting failed");
+               return ret;
+       }
+
+       wl12xx_event_mbox_config(wl);
+
+       /* firmware startup completed */
+       return 0;
+}
diff --git a/drivers/net/wireless/wl12xx/boot.h b/drivers/net/wireless/wl12xx/boot.h
new file mode 100644 (file)
index 0000000..4fa7313
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __BOOT_H__
+#define __BOOT_H__
+
+#include "wl12xx.h"
+
+int wl12xx_boot_soft_reset(struct wl12xx *wl);
+int wl12xx_boot_init_seq(struct wl12xx *wl);
+int wl12xx_boot_run_firmware(struct wl12xx *wl);
+void wl12xx_boot_target_enable_interrupts(struct wl12xx *wl);
+
+/* number of times we try to read the INIT interrupt */
+#define INIT_LOOP 20000
+
+/* delay between retries */
+#define INIT_LOOP_DELAY 50
+
+#endif
diff --git a/drivers/net/wireless/wl12xx/cmd.c b/drivers/net/wireless/wl12xx/cmd.c
new file mode 100644 (file)
index 0000000..f73ab60
--- /dev/null
@@ -0,0 +1,353 @@
+#include "cmd.h"
+
+#include <linux/module.h>
+#include <linux/crc7.h>
+#include <linux/spi/spi.h>
+
+#include "wl12xx.h"
+#include "wl12xx_80211.h"
+#include "reg.h"
+#include "spi.h"
+#include "ps.h"
+
+int wl12xx_cmd_send(struct wl12xx *wl, u16 type, void *buf, size_t buf_len)
+{
+       struct wl12xx_command cmd;
+       unsigned long timeout;
+       size_t cmd_len;
+       u32 intr;
+       int ret = 0;
+
+       memset(&cmd, 0, sizeof(cmd));
+       cmd.id = type;
+       cmd.status = 0;
+       memcpy(cmd.parameters, buf, buf_len);
+       cmd_len = ALIGN(buf_len, 4) + CMDMBOX_HEADER_LEN;
+
+       wl12xx_ps_elp_wakeup(wl);
+
+       wl12xx_spi_mem_write(wl, wl->cmd_box_addr, &cmd, cmd_len);
+
+       wl12xx_reg_write32(wl, ACX_REG_INTERRUPT_TRIG, INTR_TRIG_CMD);
+
+       timeout = jiffies + msecs_to_jiffies(WL12XX_COMMAND_TIMEOUT);
+
+       intr = wl12xx_reg_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR);
+       while (!(intr & wl->chip.intr_cmd_complete)) {
+               if (time_after(jiffies, timeout)) {
+                       wl12xx_error("command complete timeout");
+                       ret = -ETIMEDOUT;
+                       goto out;
+               }
+
+               msleep(1);
+
+               intr = wl12xx_reg_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR);
+       }
+
+       wl12xx_reg_write32(wl, ACX_REG_INTERRUPT_ACK,
+                          wl->chip.intr_cmd_complete);
+
+out:
+       wl12xx_ps_elp_sleep(wl);
+
+       return ret;
+}
+
+int wl12xx_cmd_test(struct wl12xx *wl, void *buf, size_t buf_len, u8 answer)
+{
+       int ret;
+
+       wl12xx_debug(DEBUG_CMD, "cmd test");
+
+       ret = wl12xx_cmd_send(wl, CMD_TEST, buf, buf_len);
+       if (ret < 0) {
+               wl12xx_warning("TEST command failed");
+               return ret;
+       }
+
+       if (answer) {
+               struct wl12xx_command *cmd_answer;
+
+               /*
+                * The test command got in, we can read the answer.
+                * The answer would be a wl12xx_command, where the
+                * parameter array contains the actual answer.
+                */
+
+               wl12xx_ps_elp_wakeup(wl);
+
+               wl12xx_spi_mem_read(wl, wl->cmd_box_addr, buf, buf_len);
+
+               wl12xx_ps_elp_sleep(wl);
+
+               cmd_answer = buf;
+               if (cmd_answer->status != CMD_STATUS_SUCCESS)
+                       wl12xx_error("TEST command answer error: %d",
+                                    cmd_answer->status);
+       }
+
+       return 0;
+}
+
+
+int wl12xx_cmd_interrogate(struct wl12xx *wl, u16 ie_id, u16 ie_len,
+                          void *answer)
+{
+       struct wl12xx_command *cmd;
+       struct acx_header header;
+       int ret;
+
+       wl12xx_debug(DEBUG_CMD, "cmd interrogate");
+
+       header.id = ie_id;
+       header.len = ie_len - sizeof(header);
+
+       ret = wl12xx_cmd_send(wl, CMD_INTERROGATE, &header, sizeof(header));
+       if (ret < 0) {
+               wl12xx_error("INTERROGATE command failed");
+               return ret;
+       }
+
+       wl12xx_ps_elp_wakeup(wl);
+
+       /* the interrogate command got in, we can read the answer */
+       wl12xx_spi_mem_read(wl, wl->cmd_box_addr, answer,
+                           CMDMBOX_HEADER_LEN + ie_len);
+
+       wl12xx_ps_elp_sleep(wl);
+
+       cmd = answer;
+       if (cmd->status != CMD_STATUS_SUCCESS)
+               wl12xx_error("INTERROGATE command error: %d",
+                            cmd->status);
+
+       return 0;
+
+}
+
+int wl12xx_cmd_configure(struct wl12xx *wl, void *ie, int ie_len)
+{
+       int ret;
+
+       wl12xx_debug(DEBUG_CMD, "cmd configure");
+
+       ret = wl12xx_cmd_send(wl, CMD_CONFIGURE, ie,
+                             ie_len);
+       if (ret < 0) {
+               wl12xx_warning("CONFIGURE command NOK");
+               return ret;
+       }
+
+       return 0;
+
+}
+
+int wl12xx_cmd_vbm(struct wl12xx *wl, u8 identity,
+                  void *bitmap, u16 bitmap_len, u8 bitmap_control)
+{
+       struct vbm_update_request vbm;
+       int ret;
+
+       wl12xx_debug(DEBUG_CMD, "cmd vbm");
+
+       /* Count and period will be filled by the target */
+       vbm.tim.bitmap_ctrl = bitmap_control;
+       if (bitmap_len > PARTIAL_VBM_MAX) {
+               wl12xx_warning("cmd vbm len is %d B, truncating to %d",
+                              bitmap_len, PARTIAL_VBM_MAX);
+               bitmap_len = PARTIAL_VBM_MAX;
+       }
+       memcpy(vbm.tim.pvb_field, bitmap, bitmap_len);
+       vbm.tim.identity = identity;
+       vbm.tim.length = bitmap_len + 3;
+
+       vbm.len = cpu_to_le16(bitmap_len + 5);
+
+       ret = wl12xx_cmd_send(wl, CMD_VBM, &vbm, sizeof(vbm));
+       if (ret < 0) {
+               wl12xx_error("VBM command failed");
+               return ret;
+       }
+
+       return 0;
+}
+
+int wl12xx_cmd_data_path(struct wl12xx *wl, u8 channel, u8 enable)
+{
+       int ret;
+       u16 cmd_rx, cmd_tx;
+
+       wl12xx_debug(DEBUG_CMD, "cmd data path");
+
+       if (enable) {
+               cmd_rx = CMD_ENABLE_RX;
+               cmd_tx = CMD_ENABLE_TX;
+       } else {
+               cmd_rx = CMD_DISABLE_RX;
+               cmd_tx = CMD_DISABLE_TX;
+       }
+
+       ret = wl12xx_cmd_send(wl, cmd_rx, &channel, sizeof(channel));
+       if (ret < 0) {
+               wl12xx_error("rx %s cmd for channel %d failed",
+                            enable ? "start" : "stop", channel);
+               return ret;
+       }
+
+       wl12xx_debug(DEBUG_BOOT, "rx %s cmd channel %d",
+                    enable ? "start" : "stop", channel);
+
+       ret = wl12xx_cmd_send(wl, cmd_tx, &channel, sizeof(channel));
+       if (ret < 0) {
+               wl12xx_error("tx %s cmd for channel %d failed",
+                            enable ? "start" : "stop", channel);
+               return ret;
+       }
+
+       wl12xx_debug(DEBUG_BOOT, "tx %s cmd channel %d",
+                    enable ? "start" : "stop", channel);
+
+       return 0;
+}
+
+int wl12xx_cmd_join(struct wl12xx *wl, u8 bss_type, u8 dtim_interval,
+                   u16 beacon_interval, u8 wait)
+{
+       unsigned long timeout;
+       struct cmd_join join = {};
+       int ret, i;
+       u8 *bssid;
+
+       /* FIXME: this should be in main.c */
+       ret = wl12xx_acx_frame_rates(wl, DEFAULT_HW_GEN_TX_RATE,
+                                    DEFAULT_HW_GEN_MODULATION_TYPE,
+                                    wl->tx_mgmt_frm_rate,
+                                    wl->tx_mgmt_frm_mod);
+       if (ret < 0)
+               return ret;
+
+       wl12xx_debug(DEBUG_CMD, "cmd join");
+
+       /* Reverse order BSSID */
+       bssid = (u8 *)&join.bssid_lsb;
+       for (i = 0; i < ETH_ALEN; i++)
+               bssid[i] = wl->bssid[ETH_ALEN - i - 1];
+
+       join.rx_config_options = wl->rx_config;
+       join.rx_filter_options = wl->rx_filter;
+
+       join.basic_rate_set = RATE_MASK_1MBPS | RATE_MASK_2MBPS |
+               RATE_MASK_5_5MBPS | RATE_MASK_11MBPS;
+
+       join.beacon_interval = beacon_interval;
+       join.dtim_interval = dtim_interval;
+       join.bss_type = bss_type;
+       join.channel = wl->channel;
+       join.ctrl = JOIN_CMD_CTRL_TX_FLUSH;
+
+       ret = wl12xx_cmd_send(wl, CMD_START_JOIN, &join, sizeof(join));
+       if (ret < 0) {
+               wl12xx_error("failed to initiate cmd join");
+               return ret;
+       }
+
+       timeout = msecs_to_jiffies(JOIN_TIMEOUT);
+
+       /*
+        * ugly hack: we should wait for JOIN_EVENT_COMPLETE_ID but to
+        * simplify locking we just sleep instead, for now
+        */
+       if (wait)
+               msleep(10);
+
+       return 0;
+}
+
+int wl12xx_cmd_ps_mode(struct wl12xx *wl, u8 ps_mode)
+{
+       int ret;
+       struct acx_ps_params ps_params;
+
+       /* FIXME: this should be in ps.c */
+       ret = wl12xx_acx_wake_up_conditions(wl, wl->listen_int);
+       if (ret < 0) {
+               wl12xx_error("Couldnt set wake up conditions");
+               return ret;
+       }
+
+       wl12xx_debug(DEBUG_CMD, "cmd set ps mode");
+
+       ps_params.ps_mode = ps_mode;
+       ps_params.send_null_data = 1;
+       ps_params.retries = 5;
+       ps_params.hang_over_period = 128;
+       ps_params.null_data_rate = 1; /* 1 Mbps */
+
+       ret = wl12xx_cmd_send(wl, CMD_SET_PS_MODE, &ps_params,
+                             sizeof(ps_params));
+       if (ret < 0) {
+               wl12xx_error("cmd set_ps_mode failed");
+               return ret;
+       }
+
+       return 0;
+}
+
+int wl12xx_cmd_read_memory(struct wl12xx *wl, u32 addr, u32 len, void *answer)
+{
+       struct cmd_read_write_memory mem_cmd, *mem_answer;
+       struct wl12xx_command cmd;
+       int ret;
+
+       wl12xx_debug(DEBUG_CMD, "cmd read memory");
+
+       memset(&mem_cmd, 0, sizeof(mem_cmd));
+       mem_cmd.addr = addr;
+       mem_cmd.size = len;
+
+       ret = wl12xx_cmd_send(wl, CMD_READ_MEMORY, &mem_cmd, sizeof(mem_cmd));
+       if (ret < 0) {
+               wl12xx_error("read memory command failed: %d", ret);
+               return ret;
+       }
+
+       /* the read command got in, we can now read the answer */
+       wl12xx_spi_mem_read(wl, wl->cmd_box_addr, &cmd,
+                           CMDMBOX_HEADER_LEN + sizeof(mem_cmd));
+
+       if (cmd.status != CMD_STATUS_SUCCESS)
+               wl12xx_error("error in read command result: %d", cmd.status);
+
+       mem_answer = (struct cmd_read_write_memory *) cmd.parameters;
+       memcpy(answer, mem_answer->value, len);
+
+       return 0;
+}
+
+int wl12xx_cmd_template_set(struct wl12xx *wl, u16 cmd_id,
+                           void *buf, size_t buf_len)
+{
+       struct wl12xx_cmd_packet_template template;
+       int ret;
+
+       wl12xx_debug(DEBUG_CMD, "cmd template %d", cmd_id);
+
+       memset(&template, 0, sizeof(template));
+
+       WARN_ON(buf_len > WL12XX_MAX_TEMPLATE_SIZE);
+       buf_len = min_t(size_t, buf_len, WL12XX_MAX_TEMPLATE_SIZE);
+       template.size = cpu_to_le16(buf_len);
+
+       if (buf)
+               memcpy(template.template, buf, buf_len);
+
+       ret = wl12xx_cmd_send(wl, cmd_id, &template,
+                             sizeof(template.size) + buf_len);
+       if (ret < 0) {
+               wl12xx_warning("cmd set_template failed: %d", ret);
+               return ret;
+       }
+
+       return 0;
+}
diff --git a/drivers/net/wireless/wl12xx/cmd.h b/drivers/net/wireless/wl12xx/cmd.h
new file mode 100644 (file)
index 0000000..aa307dc
--- /dev/null
@@ -0,0 +1,265 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (c) 1998-2007 Texas Instruments Incorporated
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __WL12XX_CMD_H__
+#define __WL12XX_CMD_H__
+
+#include "wl12xx.h"
+
+int wl12xx_cmd_send(struct wl12xx *wl, u16 type, void *buf, size_t buf_len);
+int wl12xx_cmd_test(struct wl12xx *wl, void *buf, size_t buf_len, u8 answer);
+int wl12xx_cmd_interrogate(struct wl12xx *wl, u16 ie_id, u16 ie_len,
+                          void *answer);
+int wl12xx_cmd_configure(struct wl12xx *wl, void *ie, int ie_len);
+int wl12xx_cmd_vbm(struct wl12xx *wl, u8 identity,
+                  void *bitmap, u16 bitmap_len, u8 bitmap_control);
+int wl12xx_cmd_data_path(struct wl12xx *wl, u8 channel, u8 enable);
+int wl12xx_cmd_join(struct wl12xx *wl, u8 bss_type, u8 dtim_interval,
+                   u16 beacon_interval, u8 wait);
+int wl12xx_cmd_ps_mode(struct wl12xx *wl, u8 ps_mode);
+int wl12xx_cmd_read_memory(struct wl12xx *wl, u32 addr, u32 len, void *answer);
+int wl12xx_cmd_template_set(struct wl12xx *wl, u16 cmd_id,
+                           void *buf, size_t buf_len);
+
+/* unit ms */
+#define WL12XX_COMMAND_TIMEOUT 2000
+
+#define WL12XX_MAX_TEMPLATE_SIZE 300
+
+struct wl12xx_cmd_packet_template {
+       __le16 size;
+       u8 template[WL12XX_MAX_TEMPLATE_SIZE];
+} __attribute__ ((packed));
+
+enum wl12xx_commands {
+       CMD_RESET           = 0,
+       CMD_INTERROGATE     = 1,    /*use this to read information elements*/
+       CMD_CONFIGURE       = 2,    /*use this to write information elements*/
+       CMD_ENABLE_RX       = 3,
+       CMD_ENABLE_TX       = 4,
+       CMD_DISABLE_RX      = 5,
+       CMD_DISABLE_TX      = 6,
+       CMD_SCAN            = 8,
+       CMD_STOP_SCAN       = 9,
+       CMD_VBM             = 10,
+       CMD_START_JOIN      = 11,
+       CMD_SET_KEYS        = 12,
+       CMD_READ_MEMORY     = 13,
+       CMD_WRITE_MEMORY    = 14,
+       CMD_BEACON          = 19,
+       CMD_PROBE_RESP      = 20,
+       CMD_NULL_DATA       = 21,
+       CMD_PROBE_REQ       = 22,
+       CMD_TEST            = 23,
+       CMD_RADIO_CALIBRATE     = 25,   /* OBSOLETE */
+       CMD_ENABLE_RX_PATH      = 27,   /* OBSOLETE */
+       CMD_NOISE_HIST      = 28,
+       CMD_RX_RESET        = 29,
+       CMD_PS_POLL         = 30,
+       CMD_QOS_NULL_DATA   = 31,
+       CMD_LNA_CONTROL     = 32,
+       CMD_SET_BCN_MODE    = 33,
+       CMD_MEASUREMENT      = 34,
+       CMD_STOP_MEASUREMENT = 35,
+       CMD_DISCONNECT       = 36,
+       CMD_SET_PS_MODE      = 37,
+       CMD_CHANNEL_SWITCH   = 38,
+       CMD_STOP_CHANNEL_SWICTH = 39,
+       CMD_AP_DISCOVERY     = 40,
+       CMD_STOP_AP_DISCOVERY = 41,
+       CMD_SPS_SCAN = 42,
+       CMD_STOP_SPS_SCAN = 43,
+       CMD_HEALTH_CHECK     = 45,
+       CMD_DEBUG            = 46,
+       CMD_TRIGGER_SCAN_TO  = 47,
+
+       NUM_COMMANDS,
+       MAX_COMMAND_ID = 0xFFFF,
+};
+
+#define MAX_CMD_PARAMS 572
+
+struct  wl12xx_command {
+       u16 id;
+       u16 status;
+       u8  parameters[MAX_CMD_PARAMS];
+};
+
+enum {
+       CMD_MAILBOX_IDLE                        =  0,
+       CMD_STATUS_SUCCESS                      =  1,
+       CMD_STATUS_UNKNOWN_CMD                  =  2,
+       CMD_STATUS_UNKNOWN_IE                   =  3,
+       CMD_STATUS_REJECT_MEAS_SG_ACTIVE        = 11,
+       CMD_STATUS_RX_BUSY                      = 13,
+       CMD_STATUS_INVALID_PARAM                = 14,
+       CMD_STATUS_TEMPLATE_TOO_LARGE           = 15,
+       CMD_STATUS_OUT_OF_MEMORY                = 16,
+       CMD_STATUS_STA_TABLE_FULL               = 17,
+       CMD_STATUS_RADIO_ERROR                  = 18,
+       CMD_STATUS_WRONG_NESTING                = 19,
+       CMD_STATUS_TIMEOUT                      = 21, /* Driver internal use.*/
+       CMD_STATUS_FW_RESET                     = 22, /* Driver internal use.*/
+       MAX_COMMAND_STATUS                      = 0xff
+};
+
+
+/*
+ * CMD_READ_MEMORY
+ *
+ * The host issues this command to read the WiLink device memory/registers.
+ *
+ * Note: The Base Band address has special handling (16 bits registers and
+ * addresses). For more information, see the hardware specification.
+ */
+/*
+ * CMD_WRITE_MEMORY
+ *
+ * The host issues this command to write the WiLink device memory/registers.
+ *
+ * The Base Band address has special handling (16 bits registers and
+ * addresses). For more information, see the hardware specification.
+ */
+#define MAX_READ_SIZE 256
+
+struct cmd_read_write_memory {
+       /* The address of the memory to read from or write to.*/
+       u32 addr;
+
+       /* The amount of data in bytes to read from or write to the WiLink
+        * device.*/
+       u32 size;
+
+       /* The actual value read from or written to the Wilink. The source
+          of this field is the Host in WRITE command or the Wilink in READ
+          command. */
+       u8 value[MAX_READ_SIZE];
+};
+
+#define CMDMBOX_HEADER_LEN 4
+#define CMDMBOX_INFO_ELEM_HEADER_LEN 4
+
+
+struct basic_scan_parameters {
+       u32 rx_config_options;
+       u32 rx_filter_options;
+
+       /*
+        * Scan options:
+        * bit 0: When this bit is set, passive scan.
+        * bit 1: Band, when this bit is set we scan
+        * in the 5Ghz band.
+        * bit 2: voice mode, 0 for normal scan.
+        * bit 3: scan priority, 1 for high priority.
+        */
+       u16 scan_options;
+
+       /* Number of channels to scan */
+       u8 num_channels;
+
+       /* Number opf probe requests to send, per channel */
+       u8 num_probe_requests;
+
+       /* Rate and modulation for probe requests */
+       u16 tx_rate;
+
+       u8 tid_trigger;
+       u8 ssid_len;
+       u32 ssid[8];
+
+} __attribute__ ((packed));
+
+struct basic_scan_channel_parameters {
+       u32 min_duration; /* in TU */
+       u32 max_duration; /* in TU */
+       u32 bssid_lsb;
+       u16 bssid_msb;
+
+       /*
+        * bits 0-3: Early termination count.
+        * bits 4-5: Early termination condition.
+        */
+       u8 early_termination;
+
+       u8 tx_power_att;
+       u8 channel;
+       u8 pad[3];
+} __attribute__ ((packed));
+
+/* SCAN parameters */
+#define SCAN_MAX_NUM_OF_CHANNELS 16
+
+struct cmd_scan {
+       struct basic_scan_parameters params;
+       struct basic_scan_channel_parameters channels[SCAN_MAX_NUM_OF_CHANNELS];
+} __attribute__ ((packed));
+
+enum {
+       BSS_TYPE_IBSS = 0,
+       BSS_TYPE_STA_BSS = 2,
+       BSS_TYPE_AP_BSS = 3,
+       MAX_BSS_TYPE = 0xFF
+};
+
+#define JOIN_CMD_CTRL_TX_FLUSH             0x80 /* Firmware flushes all Tx */
+#define JOIN_CMD_CTRL_EARLY_WAKEUP_ENABLE  0x01 /* Early wakeup time */
+
+
+struct cmd_join {
+       u32 bssid_lsb;
+       u16 bssid_msb;
+       u16 beacon_interval; /* in TBTTs */
+       u32 rx_config_options;
+       u32 rx_filter_options;
+
+       /*
+        * The target uses this field to determine the rate at
+        * which to transmit control frame responses (such as
+        * ACK or CTS frames).
+        */
+       u16 basic_rate_set;
+       u8 dtim_interval;
+       u8 tx_ctrl_frame_rate; /* OBSOLETE */
+       u8 tx_ctrl_frame_mod;  /* OBSOLETE */
+       /*
+        * bits 0-2: This bitwise field specifies the type
+        * of BSS to start or join (BSS_TYPE_*).
+        * bit 4: Band - The radio band in which to join
+        * or start.
+        *  0 - 2.4GHz band
+        *  1 - 5GHz band
+        * bits 3, 5-7: Reserved
+        */
+       u8 bss_type;
+       u8 channel;
+       u8 ssid_len;
+       u8 ssid[IW_ESSID_MAX_SIZE];
+       u8 ctrl; /* JOIN_CMD_CTRL_* */
+       u8 tx_mgt_frame_rate; /* OBSOLETE */
+       u8 tx_mgt_frame_mod;  /* OBSOLETE */
+       u8 reserved;
+} __attribute__ ((packed));
+
+
+#endif /* __WL12XX_CMD_H__ */
diff --git a/drivers/net/wireless/wl12xx/debugfs.c b/drivers/net/wireless/wl12xx/debugfs.c
new file mode 100644 (file)
index 0000000..cdb368c
--- /dev/null
@@ -0,0 +1,508 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include "debugfs.h"
+
+#include <linux/skbuff.h>
+
+#include "wl12xx.h"
+#include "acx.h"
+
+/* ms */
+#define WL12XX_DEBUGFS_STATS_LIFETIME 1000
+
+/* debugfs macros idea from mac80211 */
+
+#define DEBUGFS_READONLY_FILE(name, buflen, fmt, value...)             \
+static ssize_t name## _read(struct file *file, char __user *userbuf,   \
+                           size_t count, loff_t *ppos)                 \
+{                                                                      \
+       struct wl12xx *wl = file->private_data;                         \
+       char buf[buflen];                                               \
+       int res;                                                        \
+                                                                       \
+       res = scnprintf(buf, buflen, fmt "\n", ##value);                \
+       return simple_read_from_buffer(userbuf, count, ppos, buf, res); \
+}                                                                      \
+                                                                       \
+static const struct file_operations name## _ops = {                    \
+       .read = name## _read,                                           \
+       .open = wl12xx_open_file_generic,                               \
+};
+
+#define DEBUGFS_ADD(name, parent)                                      \
+       wl->debugfs.name = debugfs_create_file(#name, 0400, parent,     \
+                                              wl, &name## _ops);       \
+       if (IS_ERR(wl->debugfs.name)) {                                 \
+               ret = PTR_ERR(wl->debugfs.name);                        \
+               wl->debugfs.name = NULL;                                \
+               goto out;                                               \
+       }
+
+#define DEBUGFS_DEL(name)                                              \
+       do {                                                            \
+               debugfs_remove(wl->debugfs.name);                       \
+               wl->debugfs.name = NULL;                                \
+       } while (0)
+
+#define DEBUGFS_FWSTATS_FILE(sub, name, buflen, fmt)                   \
+static ssize_t sub## _ ##name## _read(struct file *file,               \
+                                     char __user *userbuf,             \
+                                     size_t count, loff_t *ppos)       \
+{                                                                      \
+       struct wl12xx *wl = file->private_data;                         \
+       char buf[buflen];                                               \
+       int res;                                                        \
+                                                                       \
+       wl12xx_debugfs_update_stats(wl);                                \
+                                                                       \
+       res = scnprintf(buf, buflen, fmt "\n",                          \
+                       wl->stats.fw_stats->sub.name);                  \
+       return simple_read_from_buffer(userbuf, count, ppos, buf, res); \
+}                                                                      \
+                                                                       \
+static const struct file_operations sub## _ ##name## _ops = {          \
+       .read = sub## _ ##name## _read,                                 \
+       .open = wl12xx_open_file_generic,                               \
+};
+
+#define DEBUGFS_FWSTATS_ADD(sub, name)                         \
+       DEBUGFS_ADD(sub## _ ##name, wl->debugfs.fw_statistics)
+
+#define DEBUGFS_FWSTATS_DEL(sub, name)                         \
+       DEBUGFS_DEL(sub## _ ##name)
+
+static void wl12xx_debugfs_update_stats(struct wl12xx *wl)
+{
+       mutex_lock(&wl->mutex);
+
+       if (wl->state == WL12XX_STATE_ON &&
+           time_after(jiffies, wl->stats.fw_stats_update +
+                      msecs_to_jiffies(WL12XX_DEBUGFS_STATS_LIFETIME))) {
+               wl12xx_acx_statistics(wl, wl->stats.fw_stats);
+               wl->stats.fw_stats_update = jiffies;
+       }
+
+       mutex_unlock(&wl->mutex);
+}
+
+static int wl12xx_open_file_generic(struct inode *inode, struct file *file)
+{
+       file->private_data = inode->i_private;
+       return 0;
+}
+
+DEBUGFS_FWSTATS_FILE(tx, internal_desc_overflow, 20, "%u");
+
+DEBUGFS_FWSTATS_FILE(rx, out_of_mem, 20, "%u");
+DEBUGFS_FWSTATS_FILE(rx, hdr_overflow, 20, "%u");
+DEBUGFS_FWSTATS_FILE(rx, hw_stuck, 20, "%u");
+DEBUGFS_FWSTATS_FILE(rx, dropped, 20, "%u");
+DEBUGFS_FWSTATS_FILE(rx, fcs_err, 20, "%u");
+DEBUGFS_FWSTATS_FILE(rx, xfr_hint_trig, 20, "%u");
+DEBUGFS_FWSTATS_FILE(rx, path_reset, 20, "%u");
+DEBUGFS_FWSTATS_FILE(rx, reset_counter, 20, "%u");
+
+DEBUGFS_FWSTATS_FILE(dma, rx_requested, 20, "%u");
+DEBUGFS_FWSTATS_FILE(dma, rx_errors, 20, "%u");
+DEBUGFS_FWSTATS_FILE(dma, tx_requested, 20, "%u");
+DEBUGFS_FWSTATS_FILE(dma, tx_errors, 20, "%u");
+
+DEBUGFS_FWSTATS_FILE(isr, cmd_cmplt, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, fiqs, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, rx_headers, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, rx_mem_overflow, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, rx_rdys, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, irqs, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, tx_procs, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, decrypt_done, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, dma0_done, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, dma1_done, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, tx_exch_complete, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, commands, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, rx_procs, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, hw_pm_mode_changes, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, host_acknowledges, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, pci_pm, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, wakeups, 20, "%u");
+DEBUGFS_FWSTATS_FILE(isr, low_rssi, 20, "%u");
+
+DEBUGFS_FWSTATS_FILE(wep, addr_key_count, 20, "%u");
+DEBUGFS_FWSTATS_FILE(wep, default_key_count, 20, "%u");
+/* skipping wep.reserved */
+DEBUGFS_FWSTATS_FILE(wep, key_not_found, 20, "%u");
+DEBUGFS_FWSTATS_FILE(wep, decrypt_fail, 20, "%u");
+DEBUGFS_FWSTATS_FILE(wep, packets, 20, "%u");
+DEBUGFS_FWSTATS_FILE(wep, interrupt, 20, "%u");
+
+DEBUGFS_FWSTATS_FILE(pwr, ps_enter, 20, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, elp_enter, 20, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, missing_bcns, 20, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, wake_on_host, 20, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, wake_on_timer_exp, 20, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, tx_with_ps, 20, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, tx_without_ps, 20, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, rcvd_beacons, 20, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, power_save_off, 20, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, enable_ps, 20, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, disable_ps, 20, "%u");
+DEBUGFS_FWSTATS_FILE(pwr, fix_tsf_ps, 20, "%u");
+/* skipping cont_miss_bcns_spread for now */
+DEBUGFS_FWSTATS_FILE(pwr, rcvd_awake_beacons, 20, "%u");
+
+DEBUGFS_FWSTATS_FILE(mic, rx_pkts, 20, "%u");
+DEBUGFS_FWSTATS_FILE(mic, calc_failure, 20, "%u");
+
+DEBUGFS_FWSTATS_FILE(aes, encrypt_fail, 20, "%u");
+DEBUGFS_FWSTATS_FILE(aes, decrypt_fail, 20, "%u");
+DEBUGFS_FWSTATS_FILE(aes, encrypt_packets, 20, "%u");
+DEBUGFS_FWSTATS_FILE(aes, decrypt_packets, 20, "%u");
+DEBUGFS_FWSTATS_FILE(aes, encrypt_interrupt, 20, "%u");
+DEBUGFS_FWSTATS_FILE(aes, decrypt_interrupt, 20, "%u");
+
+DEBUGFS_FWSTATS_FILE(event, heart_beat, 20, "%u");
+DEBUGFS_FWSTATS_FILE(event, calibration, 20, "%u");
+DEBUGFS_FWSTATS_FILE(event, rx_mismatch, 20, "%u");
+DEBUGFS_FWSTATS_FILE(event, rx_mem_empty, 20, "%u");
+DEBUGFS_FWSTATS_FILE(event, rx_pool, 20, "%u");
+DEBUGFS_FWSTATS_FILE(event, oom_late, 20, "%u");
+DEBUGFS_FWSTATS_FILE(event, phy_transmit_error, 20, "%u");
+DEBUGFS_FWSTATS_FILE(event, tx_stuck, 20, "%u");
+
+DEBUGFS_FWSTATS_FILE(ps, pspoll_timeouts, 20, "%u");
+DEBUGFS_FWSTATS_FILE(ps, upsd_timeouts, 20, "%u");
+DEBUGFS_FWSTATS_FILE(ps, upsd_max_sptime, 20, "%u");
+DEBUGFS_FWSTATS_FILE(ps, upsd_max_apturn, 20, "%u");
+DEBUGFS_FWSTATS_FILE(ps, pspoll_max_apturn, 20, "%u");
+DEBUGFS_FWSTATS_FILE(ps, pspoll_utilization, 20, "%u");
+DEBUGFS_FWSTATS_FILE(ps, upsd_utilization, 20, "%u");
+
+DEBUGFS_FWSTATS_FILE(rxpipe, rx_prep_beacon_drop, 20, "%u");
+DEBUGFS_FWSTATS_FILE(rxpipe, descr_host_int_trig_rx_data, 20, "%u");
+DEBUGFS_FWSTATS_FILE(rxpipe, beacon_buffer_thres_host_int_trig_rx_data,
+                    20, "%u");
+DEBUGFS_FWSTATS_FILE(rxpipe, missed_beacon_host_int_trig_rx_data, 20, "%u");
+DEBUGFS_FWSTATS_FILE(rxpipe, tx_xfr_host_int_trig_rx_data, 20, "%u");
+
+DEBUGFS_READONLY_FILE(retry_count, 20, "%u", wl->stats.retry_count);
+DEBUGFS_READONLY_FILE(excessive_retries, 20, "%u",
+                     wl->stats.excessive_retries);
+
+static ssize_t tx_queue_len_read(struct file *file, char __user *userbuf,
+                                size_t count, loff_t *ppos)
+{
+       struct wl12xx *wl = file->private_data;
+       u32 queue_len;
+       char buf[20];
+       int res;
+
+       queue_len = skb_queue_len(&wl->tx_queue);
+
+       res = scnprintf(buf, sizeof(buf), "%u\n", queue_len);
+       return simple_read_from_buffer(userbuf, count, ppos, buf, res);
+}
+
+static const struct file_operations tx_queue_len_ops = {
+       .read = tx_queue_len_read,
+       .open = wl12xx_open_file_generic,
+};
+
+static void wl12xx_debugfs_delete_files(struct wl12xx *wl)
+{
+       DEBUGFS_FWSTATS_DEL(tx, internal_desc_overflow);
+
+       DEBUGFS_FWSTATS_DEL(rx, out_of_mem);
+       DEBUGFS_FWSTATS_DEL(rx, hdr_overflow);
+       DEBUGFS_FWSTATS_DEL(rx, hw_stuck);
+       DEBUGFS_FWSTATS_DEL(rx, dropped);
+       DEBUGFS_FWSTATS_DEL(rx, fcs_err);
+       DEBUGFS_FWSTATS_DEL(rx, xfr_hint_trig);
+       DEBUGFS_FWSTATS_DEL(rx, path_reset);
+       DEBUGFS_FWSTATS_DEL(rx, reset_counter);
+
+       DEBUGFS_FWSTATS_DEL(dma, rx_requested);
+       DEBUGFS_FWSTATS_DEL(dma, rx_errors);
+       DEBUGFS_FWSTATS_DEL(dma, tx_requested);
+       DEBUGFS_FWSTATS_DEL(dma, tx_errors);
+
+       DEBUGFS_FWSTATS_DEL(isr, cmd_cmplt);
+       DEBUGFS_FWSTATS_DEL(isr, fiqs);
+       DEBUGFS_FWSTATS_DEL(isr, rx_headers);
+       DEBUGFS_FWSTATS_DEL(isr, rx_mem_overflow);
+       DEBUGFS_FWSTATS_DEL(isr, rx_rdys);
+       DEBUGFS_FWSTATS_DEL(isr, irqs);
+       DEBUGFS_FWSTATS_DEL(isr, tx_procs);
+       DEBUGFS_FWSTATS_DEL(isr, decrypt_done);
+       DEBUGFS_FWSTATS_DEL(isr, dma0_done);
+       DEBUGFS_FWSTATS_DEL(isr, dma1_done);
+       DEBUGFS_FWSTATS_DEL(isr, tx_exch_complete);
+       DEBUGFS_FWSTATS_DEL(isr, commands);
+       DEBUGFS_FWSTATS_DEL(isr, rx_procs);
+       DEBUGFS_FWSTATS_DEL(isr, hw_pm_mode_changes);
+       DEBUGFS_FWSTATS_DEL(isr, host_acknowledges);
+       DEBUGFS_FWSTATS_DEL(isr, pci_pm);
+       DEBUGFS_FWSTATS_DEL(isr, wakeups);
+       DEBUGFS_FWSTATS_DEL(isr, low_rssi);
+
+       DEBUGFS_FWSTATS_DEL(wep, addr_key_count);
+       DEBUGFS_FWSTATS_DEL(wep, default_key_count);
+       /* skipping wep.reserved */
+       DEBUGFS_FWSTATS_DEL(wep, key_not_found);
+       DEBUGFS_FWSTATS_DEL(wep, decrypt_fail);
+       DEBUGFS_FWSTATS_DEL(wep, packets);
+       DEBUGFS_FWSTATS_DEL(wep, interrupt);
+
+       DEBUGFS_FWSTATS_DEL(pwr, ps_enter);
+       DEBUGFS_FWSTATS_DEL(pwr, elp_enter);
+       DEBUGFS_FWSTATS_DEL(pwr, missing_bcns);
+       DEBUGFS_FWSTATS_DEL(pwr, wake_on_host);
+       DEBUGFS_FWSTATS_DEL(pwr, wake_on_timer_exp);
+       DEBUGFS_FWSTATS_DEL(pwr, tx_with_ps);
+       DEBUGFS_FWSTATS_DEL(pwr, tx_without_ps);
+       DEBUGFS_FWSTATS_DEL(pwr, rcvd_beacons);
+       DEBUGFS_FWSTATS_DEL(pwr, power_save_off);
+       DEBUGFS_FWSTATS_DEL(pwr, enable_ps);
+       DEBUGFS_FWSTATS_DEL(pwr, disable_ps);
+       DEBUGFS_FWSTATS_DEL(pwr, fix_tsf_ps);
+       /* skipping cont_miss_bcns_spread for now */
+       DEBUGFS_FWSTATS_DEL(pwr, rcvd_awake_beacons);
+
+       DEBUGFS_FWSTATS_DEL(mic, rx_pkts);
+       DEBUGFS_FWSTATS_DEL(mic, calc_failure);
+
+       DEBUGFS_FWSTATS_DEL(aes, encrypt_fail);
+       DEBUGFS_FWSTATS_DEL(aes, decrypt_fail);
+       DEBUGFS_FWSTATS_DEL(aes, encrypt_packets);
+       DEBUGFS_FWSTATS_DEL(aes, decrypt_packets);
+       DEBUGFS_FWSTATS_DEL(aes, encrypt_interrupt);
+       DEBUGFS_FWSTATS_DEL(aes, decrypt_interrupt);
+
+       DEBUGFS_FWSTATS_DEL(event, heart_beat);
+       DEBUGFS_FWSTATS_DEL(event, calibration);
+       DEBUGFS_FWSTATS_DEL(event, rx_mismatch);
+       DEBUGFS_FWSTATS_DEL(event, rx_mem_empty);
+       DEBUGFS_FWSTATS_DEL(event, rx_pool);
+       DEBUGFS_FWSTATS_DEL(event, oom_late);
+       DEBUGFS_FWSTATS_DEL(event, phy_transmit_error);
+       DEBUGFS_FWSTATS_DEL(event, tx_stuck);
+
+       DEBUGFS_FWSTATS_DEL(ps, pspoll_timeouts);
+       DEBUGFS_FWSTATS_DEL(ps, upsd_timeouts);
+       DEBUGFS_FWSTATS_DEL(ps, upsd_max_sptime);
+       DEBUGFS_FWSTATS_DEL(ps, upsd_max_apturn);
+       DEBUGFS_FWSTATS_DEL(ps, pspoll_max_apturn);
+       DEBUGFS_FWSTATS_DEL(ps, pspoll_utilization);
+       DEBUGFS_FWSTATS_DEL(ps, upsd_utilization);
+
+       DEBUGFS_FWSTATS_DEL(rxpipe, rx_prep_beacon_drop);
+       DEBUGFS_FWSTATS_DEL(rxpipe, descr_host_int_trig_rx_data);
+       DEBUGFS_FWSTATS_DEL(rxpipe, beacon_buffer_thres_host_int_trig_rx_data);
+       DEBUGFS_FWSTATS_DEL(rxpipe, missed_beacon_host_int_trig_rx_data);
+       DEBUGFS_FWSTATS_DEL(rxpipe, tx_xfr_host_int_trig_rx_data);
+
+       DEBUGFS_DEL(tx_queue_len);
+       DEBUGFS_DEL(retry_count);
+       DEBUGFS_DEL(excessive_retries);
+}
+
+static int wl12xx_debugfs_add_files(struct wl12xx *wl)
+{
+       int ret = 0;
+
+       DEBUGFS_FWSTATS_ADD(tx, internal_desc_overflow);
+
+       DEBUGFS_FWSTATS_ADD(rx, out_of_mem);
+       DEBUGFS_FWSTATS_ADD(rx, hdr_overflow);
+       DEBUGFS_FWSTATS_ADD(rx, hw_stuck);
+       DEBUGFS_FWSTATS_ADD(rx, dropped);
+       DEBUGFS_FWSTATS_ADD(rx, fcs_err);
+       DEBUGFS_FWSTATS_ADD(rx, xfr_hint_trig);
+       DEBUGFS_FWSTATS_ADD(rx, path_reset);
+       DEBUGFS_FWSTATS_ADD(rx, reset_counter);
+
+       DEBUGFS_FWSTATS_ADD(dma, rx_requested);
+       DEBUGFS_FWSTATS_ADD(dma, rx_errors);
+       DEBUGFS_FWSTATS_ADD(dma, tx_requested);
+       DEBUGFS_FWSTATS_ADD(dma, tx_errors);
+
+       DEBUGFS_FWSTATS_ADD(isr, cmd_cmplt);
+       DEBUGFS_FWSTATS_ADD(isr, fiqs);
+       DEBUGFS_FWSTATS_ADD(isr, rx_headers);
+       DEBUGFS_FWSTATS_ADD(isr, rx_mem_overflow);
+       DEBUGFS_FWSTATS_ADD(isr, rx_rdys);
+       DEBUGFS_FWSTATS_ADD(isr, irqs);
+       DEBUGFS_FWSTATS_ADD(isr, tx_procs);
+       DEBUGFS_FWSTATS_ADD(isr, decrypt_done);
+       DEBUGFS_FWSTATS_ADD(isr, dma0_done);
+       DEBUGFS_FWSTATS_ADD(isr, dma1_done);
+       DEBUGFS_FWSTATS_ADD(isr, tx_exch_complete);
+       DEBUGFS_FWSTATS_ADD(isr, commands);
+       DEBUGFS_FWSTATS_ADD(isr, rx_procs);
+       DEBUGFS_FWSTATS_ADD(isr, hw_pm_mode_changes);
+       DEBUGFS_FWSTATS_ADD(isr, host_acknowledges);
+       DEBUGFS_FWSTATS_ADD(isr, pci_pm);
+       DEBUGFS_FWSTATS_ADD(isr, wakeups);
+       DEBUGFS_FWSTATS_ADD(isr, low_rssi);
+
+       DEBUGFS_FWSTATS_ADD(wep, addr_key_count);
+       DEBUGFS_FWSTATS_ADD(wep, default_key_count);
+       /* skipping wep.reserved */
+       DEBUGFS_FWSTATS_ADD(wep, key_not_found);
+       DEBUGFS_FWSTATS_ADD(wep, decrypt_fail);
+       DEBUGFS_FWSTATS_ADD(wep, packets);
+       DEBUGFS_FWSTATS_ADD(wep, interrupt);
+
+       DEBUGFS_FWSTATS_ADD(pwr, ps_enter);
+       DEBUGFS_FWSTATS_ADD(pwr, elp_enter);
+       DEBUGFS_FWSTATS_ADD(pwr, missing_bcns);
+       DEBUGFS_FWSTATS_ADD(pwr, wake_on_host);
+       DEBUGFS_FWSTATS_ADD(pwr, wake_on_timer_exp);
+       DEBUGFS_FWSTATS_ADD(pwr, tx_with_ps);
+       DEBUGFS_FWSTATS_ADD(pwr, tx_without_ps);
+       DEBUGFS_FWSTATS_ADD(pwr, rcvd_beacons);
+       DEBUGFS_FWSTATS_ADD(pwr, power_save_off);
+       DEBUGFS_FWSTATS_ADD(pwr, enable_ps);
+       DEBUGFS_FWSTATS_ADD(pwr, disable_ps);
+       DEBUGFS_FWSTATS_ADD(pwr, fix_tsf_ps);
+       /* skipping cont_miss_bcns_spread for now */
+       DEBUGFS_FWSTATS_ADD(pwr, rcvd_awake_beacons);
+
+       DEBUGFS_FWSTATS_ADD(mic, rx_pkts);
+       DEBUGFS_FWSTATS_ADD(mic, calc_failure);
+
+       DEBUGFS_FWSTATS_ADD(aes, encrypt_fail);
+       DEBUGFS_FWSTATS_ADD(aes, decrypt_fail);
+       DEBUGFS_FWSTATS_ADD(aes, encrypt_packets);
+       DEBUGFS_FWSTATS_ADD(aes, decrypt_packets);
+       DEBUGFS_FWSTATS_ADD(aes, encrypt_interrupt);
+       DEBUGFS_FWSTATS_ADD(aes, decrypt_interrupt);
+
+       DEBUGFS_FWSTATS_ADD(event, heart_beat);
+       DEBUGFS_FWSTATS_ADD(event, calibration);
+       DEBUGFS_FWSTATS_ADD(event, rx_mismatch);
+       DEBUGFS_FWSTATS_ADD(event, rx_mem_empty);
+       DEBUGFS_FWSTATS_ADD(event, rx_pool);
+       DEBUGFS_FWSTATS_ADD(event, oom_late);
+       DEBUGFS_FWSTATS_ADD(event, phy_transmit_error);
+       DEBUGFS_FWSTATS_ADD(event, tx_stuck);
+
+       DEBUGFS_FWSTATS_ADD(ps, pspoll_timeouts);
+       DEBUGFS_FWSTATS_ADD(ps, upsd_timeouts);
+       DEBUGFS_FWSTATS_ADD(ps, upsd_max_sptime);
+       DEBUGFS_FWSTATS_ADD(ps, upsd_max_apturn);
+       DEBUGFS_FWSTATS_ADD(ps, pspoll_max_apturn);
+       DEBUGFS_FWSTATS_ADD(ps, pspoll_utilization);
+       DEBUGFS_FWSTATS_ADD(ps, upsd_utilization);
+
+       DEBUGFS_FWSTATS_ADD(rxpipe, rx_prep_beacon_drop);
+       DEBUGFS_FWSTATS_ADD(rxpipe, descr_host_int_trig_rx_data);
+       DEBUGFS_FWSTATS_ADD(rxpipe, beacon_buffer_thres_host_int_trig_rx_data);
+       DEBUGFS_FWSTATS_ADD(rxpipe, missed_beacon_host_int_trig_rx_data);
+       DEBUGFS_FWSTATS_ADD(rxpipe, tx_xfr_host_int_trig_rx_data);
+
+       DEBUGFS_ADD(tx_queue_len, wl->debugfs.rootdir);
+       DEBUGFS_ADD(retry_count, wl->debugfs.rootdir);
+       DEBUGFS_ADD(excessive_retries, wl->debugfs.rootdir);
+
+out:
+       if (ret < 0)
+               wl12xx_debugfs_delete_files(wl);
+
+       return ret;
+}
+
+void wl12xx_debugfs_reset(struct wl12xx *wl)
+{
+       memset(wl->stats.fw_stats, 0, sizeof(*wl->stats.fw_stats));
+       wl->stats.retry_count = 0;
+       wl->stats.excessive_retries = 0;
+}
+
+int wl12xx_debugfs_init(struct wl12xx *wl)
+{
+       int ret;
+
+       wl->debugfs.rootdir = debugfs_create_dir(KBUILD_MODNAME, NULL);
+
+       if (IS_ERR(wl->debugfs.rootdir)) {
+               ret = PTR_ERR(wl->debugfs.rootdir);
+               wl->debugfs.rootdir = NULL;
+               goto err;
+       }
+
+       wl->debugfs.fw_statistics = debugfs_create_dir("fw-statistics",
+                                                      wl->debugfs.rootdir);
+
+       if (IS_ERR(wl->debugfs.fw_statistics)) {
+               ret = PTR_ERR(wl->debugfs.fw_statistics);
+               wl->debugfs.fw_statistics = NULL;
+               goto err_root;
+       }
+
+       wl->stats.fw_stats = kzalloc(sizeof(*wl->stats.fw_stats),
+                                     GFP_KERNEL);
+
+       if (!wl->stats.fw_stats) {
+               ret = -ENOMEM;
+               goto err_fw;
+       }
+
+       wl->stats.fw_stats_update = jiffies;
+
+       ret = wl12xx_debugfs_add_files(wl);
+
+       if (ret < 0)
+               goto err_file;
+
+       return 0;
+
+err_file:
+       kfree(wl->stats.fw_stats);
+       wl->stats.fw_stats = NULL;
+
+err_fw:
+       debugfs_remove(wl->debugfs.fw_statistics);
+       wl->debugfs.fw_statistics = NULL;
+
+err_root:
+       debugfs_remove(wl->debugfs.rootdir);
+       wl->debugfs.rootdir = NULL;
+
+err:
+       return ret;
+}
+
+void wl12xx_debugfs_exit(struct wl12xx *wl)
+{
+       wl12xx_debugfs_delete_files(wl);
+
+       kfree(wl->stats.fw_stats);
+       wl->stats.fw_stats = NULL;
+
+       debugfs_remove(wl->debugfs.fw_statistics);
+       wl->debugfs.fw_statistics = NULL;
+
+       debugfs_remove(wl->debugfs.rootdir);
+       wl->debugfs.rootdir = NULL;
+
+}
diff --git a/drivers/net/wireless/wl12xx/debugfs.h b/drivers/net/wireless/wl12xx/debugfs.h
new file mode 100644 (file)
index 0000000..562cdcb
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef WL12XX_DEBUGFS_H
+#define WL12XX_DEBUGFS_H
+
+#include "wl12xx.h"
+
+int wl12xx_debugfs_init(struct wl12xx *wl);
+void wl12xx_debugfs_exit(struct wl12xx *wl);
+void wl12xx_debugfs_reset(struct wl12xx *wl);
+
+#endif /* WL12XX_DEBUGFS_H */
diff --git a/drivers/net/wireless/wl12xx/event.c b/drivers/net/wireless/wl12xx/event.c
new file mode 100644 (file)
index 0000000..99529ca
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (c) 1998-2007 Texas Instruments Incorporated
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include "wl12xx.h"
+#include "reg.h"
+#include "spi.h"
+#include "event.h"
+#include "ps.h"
+
+static int wl12xx_event_scan_complete(struct wl12xx *wl,
+                                     struct event_mailbox *mbox)
+{
+       wl12xx_debug(DEBUG_EVENT, "status: 0x%x, channels: %d",
+                    mbox->scheduled_scan_status,
+                    mbox->scheduled_scan_channels);
+
+       if (wl->scanning) {
+               mutex_unlock(&wl->mutex);
+               ieee80211_scan_completed(wl->hw, false);
+               mutex_lock(&wl->mutex);
+               wl->scanning = false;
+       }
+
+       return 0;
+}
+
+static void wl12xx_event_mbox_dump(struct event_mailbox *mbox)
+{
+       wl12xx_debug(DEBUG_EVENT, "MBOX DUMP:");
+       wl12xx_debug(DEBUG_EVENT, "\tvector: 0x%x", mbox->events_vector);
+       wl12xx_debug(DEBUG_EVENT, "\tmask: 0x%x", mbox->events_mask);
+}
+
+static int wl12xx_event_process(struct wl12xx *wl, struct event_mailbox *mbox)
+{
+       int ret;
+       u32 vector;
+
+       wl12xx_event_mbox_dump(mbox);
+
+       vector = mbox->events_vector & ~(mbox->events_mask);
+       wl12xx_debug(DEBUG_EVENT, "vector: 0x%x", vector);
+
+       if (vector & SCAN_COMPLETE_EVENT_ID) {
+               ret = wl12xx_event_scan_complete(wl, mbox);
+               if (ret < 0)
+                       return ret;
+       }
+
+       if (vector & BSS_LOSE_EVENT_ID) {
+               wl12xx_debug(DEBUG_EVENT, "BSS_LOSE_EVENT");
+
+               if (wl->psm_requested && wl->psm) {
+                       ret = wl12xx_ps_set_mode(wl, STATION_ACTIVE_MODE);
+                       if (ret < 0)
+                               return ret;
+               }
+       }
+
+       return 0;
+}
+
+int wl12xx_event_unmask(struct wl12xx *wl)
+{
+       int ret;
+
+       ret = wl12xx_acx_event_mbox_mask(wl, ~(wl->event_mask));
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+
+void wl12xx_event_mbox_config(struct wl12xx *wl)
+{
+       wl->mbox_ptr[0] = wl12xx_reg_read32(wl, REG_EVENT_MAILBOX_PTR);
+       wl->mbox_ptr[1] = wl->mbox_ptr[0] + sizeof(struct event_mailbox);
+
+       wl12xx_debug(DEBUG_EVENT, "MBOX ptrs: 0x%x 0x%x",
+                    wl->mbox_ptr[0], wl->mbox_ptr[1]);
+}
+
+int wl12xx_event_handle(struct wl12xx *wl, u8 mbox_num)
+{
+       struct event_mailbox mbox;
+       int ret;
+
+       wl12xx_debug(DEBUG_EVENT, "EVENT on mbox %d", mbox_num);
+
+       if (mbox_num > 1)
+               return -EINVAL;
+
+       /* first we read the mbox descriptor */
+       wl12xx_spi_mem_read(wl, wl->mbox_ptr[mbox_num], &mbox,
+                           sizeof(struct event_mailbox));
+
+       /* process the descriptor */
+       ret = wl12xx_event_process(wl, &mbox);
+       if (ret < 0)
+               return ret;
+
+       /* then we let the firmware know it can go on...*/
+       wl12xx_reg_write32(wl, ACX_REG_INTERRUPT_TRIG, INTR_TRIG_EVENT_ACK);
+
+       return 0;
+}
diff --git a/drivers/net/wireless/wl12xx/event.h b/drivers/net/wireless/wl12xx/event.h
new file mode 100644 (file)
index 0000000..1f4c2f7
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (c) 1998-2007 Texas Instruments Incorporated
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __WL12XX_EVENT_H__
+#define __WL12XX_EVENT_H__
+
+/*
+ * Mbox events
+ *
+ * The event mechanism is based on a pair of event buffers (buffers A and
+ * B) at fixed locations in the target's memory. The host processes one
+ * buffer while the other buffer continues to collect events. If the host
+ * is not processing events, an interrupt is issued to signal that a buffer
+ * is ready. Once the host is done with processing events from one buffer,
+ * it signals the target (with an ACK interrupt) that the event buffer is
+ * free.
+ */
+
+enum {
+       RESERVED1_EVENT_ID                       = BIT(0),
+       RESERVED2_EVENT_ID                       = BIT(1),
+       MEASUREMENT_START_EVENT_ID               = BIT(2),
+       SCAN_COMPLETE_EVENT_ID                   = BIT(3),
+       CALIBRATION_COMPLETE_EVENT_ID            = BIT(4),
+       ROAMING_TRIGGER_LOW_RSSI_EVENT_ID        = BIT(5),
+       PS_REPORT_EVENT_ID                       = BIT(6),
+       SYNCHRONIZATION_TIMEOUT_EVENT_ID         = BIT(7),
+       HEALTH_REPORT_EVENT_ID                   = BIT(8),
+       ACI_DETECTION_EVENT_ID                   = BIT(9),
+       DEBUG_REPORT_EVENT_ID                    = BIT(10),
+       MAC_STATUS_EVENT_ID                      = BIT(11),
+       DISCONNECT_EVENT_COMPLETE_ID             = BIT(12),
+       JOIN_EVENT_COMPLETE_ID                   = BIT(13),
+       CHANNEL_SWITCH_COMPLETE_EVENT_ID         = BIT(14),
+       BSS_LOSE_EVENT_ID                        = BIT(15),
+       ROAMING_TRIGGER_MAX_TX_RETRY_EVENT_ID    = BIT(16),
+       MEASUREMENT_COMPLETE_EVENT_ID            = BIT(17),
+       AP_DISCOVERY_COMPLETE_EVENT_ID           = BIT(18),
+       SCHEDULED_SCAN_COMPLETE_EVENT_ID         = BIT(19),
+       PSPOLL_DELIVERY_FAILURE_EVENT_ID         = BIT(20),
+       RESET_BSS_EVENT_ID                       = BIT(21),
+       REGAINED_BSS_EVENT_ID                    = BIT(22),
+       ROAMING_TRIGGER_REGAINED_RSSI_EVENT_ID   = BIT(23),
+       ROAMING_TRIGGER_LOW_SNR_EVENT_ID         = BIT(24),
+       ROAMING_TRIGGER_REGAINED_SNR_EVENT_ID    = BIT(25),
+
+       DBG_EVENT_ID                             = BIT(26),
+       BT_PTA_SENSE_EVENT_ID                    = BIT(27),
+       BT_PTA_PREDICTION_EVENT_ID               = BIT(28),
+       BT_PTA_AVALANCHE_EVENT_ID                = BIT(29),
+
+       PLT_RX_CALIBRATION_COMPLETE_EVENT_ID     = BIT(30),
+
+       EVENT_MBOX_ALL_EVENT_ID                  = 0x7fffffff,
+};
+
+struct event_debug_report {
+       u8 debug_event_id;
+       u8 num_params;
+       u16 pad;
+       u32 report_1;
+       u32 report_2;
+       u32 report_3;
+} __attribute__ ((packed));
+
+struct event_mailbox {
+       u32 events_vector;
+       u32 events_mask;
+       u32 reserved_1;
+       u32 reserved_2;
+
+       char average_rssi_level;
+       u8 ps_status;
+       u8 channel_switch_status;
+       u8 scheduled_scan_status;
+
+       /* Channels scanned by the scheduled scan */
+       u16 scheduled_scan_channels;
+
+       /* If bit 0 is set -> target's fatal error */
+       u16 health_report;
+       u16 bad_fft_counter;
+       u8 bt_pta_sense_info;
+       u8 bt_pta_protective_info;
+       u32 reserved;
+       u32 debug_report[2];
+
+       /* Number of FCS errors since last event */
+       u32 fcs_err_counter;
+
+       struct event_debug_report report;
+       u8 average_snr_level;
+       u8 padding[19];
+} __attribute__ ((packed));
+
+int wl12xx_event_unmask(struct wl12xx *wl);
+void wl12xx_event_mbox_config(struct wl12xx *wl);
+int wl12xx_event_handle(struct wl12xx *wl, u8 mbox);
+
+#endif
diff --git a/drivers/net/wireless/wl12xx/init.c b/drivers/net/wireless/wl12xx/init.c
new file mode 100644 (file)
index 0000000..2a573a6
--- /dev/null
@@ -0,0 +1,200 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include "init.h"
+#include "wl12xx_80211.h"
+#include "acx.h"
+#include "cmd.h"
+
+int wl12xx_hw_init_hwenc_config(struct wl12xx *wl)
+{
+       int ret;
+
+       ret = wl12xx_acx_feature_cfg(wl);
+       if (ret < 0) {
+               wl12xx_warning("couldn't set feature config");
+               return ret;
+       }
+
+       ret = wl12xx_acx_default_key(wl, wl->default_key);
+       if (ret < 0) {
+               wl12xx_warning("couldn't set default key");
+               return ret;
+       }
+
+       return 0;
+}
+
+int wl12xx_hw_init_templates_config(struct wl12xx *wl)
+{
+       int ret;
+       u8 partial_vbm[PARTIAL_VBM_MAX];
+
+       /* send empty templates for fw memory reservation */
+       ret = wl12xx_cmd_template_set(wl, CMD_PROBE_REQ, NULL,
+                                     sizeof(struct wl12xx_probe_req_template));
+       if (ret < 0)
+               return ret;
+
+       ret = wl12xx_cmd_template_set(wl, CMD_NULL_DATA, NULL,
+                                     sizeof(struct wl12xx_null_data_template));
+       if (ret < 0)
+               return ret;
+
+       ret = wl12xx_cmd_template_set(wl, CMD_PS_POLL, NULL,
+                                     sizeof(struct wl12xx_ps_poll_template));
+       if (ret < 0)
+               return ret;
+
+       ret = wl12xx_cmd_template_set(wl, CMD_QOS_NULL_DATA, NULL,
+                                     sizeof
+                                     (struct wl12xx_qos_null_data_template));
+       if (ret < 0)
+               return ret;
+
+       ret = wl12xx_cmd_template_set(wl, CMD_PROBE_RESP, NULL,
+                                     sizeof
+                                     (struct wl12xx_probe_resp_template));
+       if (ret < 0)
+               return ret;
+
+       ret = wl12xx_cmd_template_set(wl, CMD_BEACON, NULL,
+                                     sizeof
+                                     (struct wl12xx_beacon_template));
+       if (ret < 0)
+               return ret;
+
+       /* tim templates, first reserve space then allocate an empty one */
+       memset(partial_vbm, 0, PARTIAL_VBM_MAX);
+       ret = wl12xx_cmd_vbm(wl, TIM_ELE_ID, partial_vbm, PARTIAL_VBM_MAX, 0);
+       if (ret < 0)
+               return ret;
+
+       ret = wl12xx_cmd_vbm(wl, TIM_ELE_ID, partial_vbm, 1, 0);
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+
+int wl12xx_hw_init_rx_config(struct wl12xx *wl, u32 config, u32 filter)
+{
+       int ret;
+
+       ret = wl12xx_acx_rx_msdu_life_time(wl, RX_MSDU_LIFETIME_DEF);
+       if (ret < 0)
+               return ret;
+
+       ret = wl12xx_acx_rx_config(wl, config, filter);
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+
+int wl12xx_hw_init_phy_config(struct wl12xx *wl)
+{
+       int ret;
+
+       ret = wl12xx_acx_pd_threshold(wl);
+       if (ret < 0)
+               return ret;
+
+       ret = wl12xx_acx_slot(wl, DEFAULT_SLOT_TIME);
+       if (ret < 0)
+               return ret;
+
+       ret = wl12xx_acx_group_address_tbl(wl);
+       if (ret < 0)
+               return ret;
+
+       ret = wl12xx_acx_service_period_timeout(wl);
+       if (ret < 0)
+               return ret;
+
+       ret = wl12xx_acx_rts_threshold(wl, RTS_THRESHOLD_DEF);
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+
+int wl12xx_hw_init_beacon_filter(struct wl12xx *wl)
+{
+       int ret;
+
+       ret = wl12xx_acx_beacon_filter_opt(wl);
+       if (ret < 0)
+               return ret;
+
+       ret = wl12xx_acx_beacon_filter_table(wl);
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+
+int wl12xx_hw_init_pta(struct wl12xx *wl)
+{
+       int ret;
+
+       ret = wl12xx_acx_sg_enable(wl);
+       if (ret < 0)
+               return ret;
+
+       ret = wl12xx_acx_sg_cfg(wl);
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+
+int wl12xx_hw_init_energy_detection(struct wl12xx *wl)
+{
+       int ret;
+
+       ret = wl12xx_acx_cca_threshold(wl);
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+
+int wl12xx_hw_init_beacon_broadcast(struct wl12xx *wl)
+{
+       int ret;
+
+       ret = wl12xx_acx_bcn_dtim_options(wl);
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+
+int wl12xx_hw_init_power_auth(struct wl12xx *wl)
+{
+       return wl12xx_acx_sleep_auth(wl, WL12XX_PSM_CAM);
+}
diff --git a/drivers/net/wireless/wl12xx/init.h b/drivers/net/wireless/wl12xx/init.h
new file mode 100644 (file)
index 0000000..c8b6cd0
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __WL12XX_INIT_H__
+#define __WL12XX_INIT_H__
+
+#include "wl12xx.h"
+
+int wl12xx_hw_init_hwenc_config(struct wl12xx *wl);
+int wl12xx_hw_init_templates_config(struct wl12xx *wl);
+int wl12xx_hw_init_mem_config(struct wl12xx *wl);
+int wl12xx_hw_init_rx_config(struct wl12xx *wl, u32 config, u32 filter);
+int wl12xx_hw_init_phy_config(struct wl12xx *wl);
+int wl12xx_hw_init_beacon_filter(struct wl12xx *wl);
+int wl12xx_hw_init_pta(struct wl12xx *wl);
+int wl12xx_hw_init_energy_detection(struct wl12xx *wl);
+int wl12xx_hw_init_beacon_broadcast(struct wl12xx *wl);
+int wl12xx_hw_init_power_auth(struct wl12xx *wl);
+
+#endif
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
new file mode 100644 (file)
index 0000000..603d611
--- /dev/null
@@ -0,0 +1,1358 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (C) 2008-2009 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/firmware.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/spi/spi.h>
+#include <linux/crc32.h>
+#include <linux/etherdevice.h>
+#include <linux/spi/wl12xx.h>
+
+#include "wl12xx.h"
+#include "wl12xx_80211.h"
+#include "reg.h"
+#include "wl1251.h"
+#include "spi.h"
+#include "event.h"
+#include "tx.h"
+#include "rx.h"
+#include "ps.h"
+#include "init.h"
+#include "debugfs.h"
+
+static void wl12xx_disable_interrupts(struct wl12xx *wl)
+{
+       disable_irq(wl->irq);
+}
+
+static void wl12xx_power_off(struct wl12xx *wl)
+{
+       wl->set_power(false);
+}
+
+static void wl12xx_power_on(struct wl12xx *wl)
+{
+       wl->set_power(true);
+}
+
+static irqreturn_t wl12xx_irq(int irq, void *cookie)
+{
+       struct wl12xx *wl;
+
+       wl12xx_debug(DEBUG_IRQ, "IRQ");
+
+       wl = cookie;
+
+       schedule_work(&wl->irq_work);
+
+       return IRQ_HANDLED;
+}
+
+static int wl12xx_fetch_firmware(struct wl12xx *wl)
+{
+       const struct firmware *fw;
+       int ret;
+
+       ret = request_firmware(&fw, wl->chip.fw_filename, &wl->spi->dev);
+
+       if (ret < 0) {
+               wl12xx_error("could not get firmware: %d", ret);
+               return ret;
+       }
+
+       if (fw->size % 4) {
+               wl12xx_error("firmware size is not multiple of 32 bits: %zu",
+                            fw->size);
+               ret = -EILSEQ;
+               goto out;
+       }
+
+       wl->fw_len = fw->size;
+       wl->fw = kmalloc(wl->fw_len, GFP_KERNEL);
+
+       if (!wl->fw) {
+               wl12xx_error("could not allocate memory for the firmware");
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       memcpy(wl->fw, fw->data, wl->fw_len);
+
+       ret = 0;
+
+out:
+       release_firmware(fw);
+
+       return ret;
+}
+
+static int wl12xx_fetch_nvs(struct wl12xx *wl)
+{
+       const struct firmware *fw;
+       int ret;
+
+       ret = request_firmware(&fw, wl->chip.nvs_filename, &wl->spi->dev);
+
+       if (ret < 0) {
+               wl12xx_error("could not get nvs file: %d", ret);
+               return ret;
+       }
+
+       if (fw->size % 4) {
+               wl12xx_error("nvs size is not multiple of 32 bits: %zu",
+                            fw->size);
+               ret = -EILSEQ;
+               goto out;
+       }
+
+       wl->nvs_len = fw->size;
+       wl->nvs = kmalloc(wl->nvs_len, GFP_KERNEL);
+
+       if (!wl->nvs) {
+               wl12xx_error("could not allocate memory for the nvs file");
+               ret = -ENOMEM;
+               goto out;
+       }
+
+       memcpy(wl->nvs, fw->data, wl->nvs_len);
+
+       ret = 0;
+
+out:
+       release_firmware(fw);
+
+       return ret;
+}
+
+static void wl12xx_fw_wakeup(struct wl12xx *wl)
+{
+       u32 elp_reg;
+
+       elp_reg = ELPCTRL_WAKE_UP;
+       wl12xx_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, elp_reg);
+       elp_reg = wl12xx_read32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR);
+
+       if (!(elp_reg & ELPCTRL_WLAN_READY)) {
+               wl12xx_warning("WLAN not ready");
+               elp_reg = ELPCTRL_WAKE_UP_WLAN_READY;
+               wl12xx_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, elp_reg);
+       }
+}
+
+static int wl12xx_chip_wakeup(struct wl12xx *wl)
+{
+       int ret = 0;
+
+       wl12xx_power_on(wl);
+       msleep(wl->chip.power_on_sleep);
+       wl12xx_spi_reset(wl);
+       wl12xx_spi_init(wl);
+
+       /* We don't need a real memory partition here, because we only want
+        * to use the registers at this point. */
+       wl12xx_set_partition(wl,
+                            0x00000000,
+                            0x00000000,
+                            REGISTERS_BASE,
+                            REGISTERS_DOWN_SIZE);
+
+       /* ELP module wake up */
+       wl12xx_fw_wakeup(wl);
+
+       /* whal_FwCtrl_BootSm() */
+
+       /* 0. read chip id from CHIP_ID */
+       wl->chip.id = wl12xx_reg_read32(wl, CHIP_ID_B);
+
+       /* 1. check if chip id is valid */
+
+       switch (wl->chip.id) {
+       case CHIP_ID_1251_PG12:
+               wl12xx_debug(DEBUG_BOOT, "chip id 0x%x (1251 PG12)",
+                            wl->chip.id);
+
+               wl1251_setup(wl);
+
+               break;
+       case CHIP_ID_1271_PG10:
+       case CHIP_ID_1251_PG10:
+       case CHIP_ID_1251_PG11:
+       default:
+               wl12xx_error("unsupported chip id: 0x%x", wl->chip.id);
+               ret = -ENODEV;
+               goto out;
+       }
+
+       if (wl->fw == NULL) {
+               ret = wl12xx_fetch_firmware(wl);
+               if (ret < 0)
+                       goto out;
+       }
+
+       /* No NVS from netlink, try to get it from the filesystem */
+       if (wl->nvs == NULL) {
+               ret = wl12xx_fetch_nvs(wl);
+               if (ret < 0)
+                       goto out;
+       }
+
+out:
+       return ret;
+}
+
+static void wl12xx_filter_work(struct work_struct *work)
+{
+       struct wl12xx *wl =
+               container_of(work, struct wl12xx, filter_work);
+       int ret;
+
+       mutex_lock(&wl->mutex);
+
+       if (wl->state == WL12XX_STATE_OFF)
+               goto out;
+
+       ret = wl12xx_cmd_join(wl, wl->bss_type, 1, 100, 0);
+       if (ret < 0)
+               goto out;
+
+out:
+       mutex_unlock(&wl->mutex);
+}
+
+int wl12xx_plt_start(struct wl12xx *wl)
+{
+       int ret;
+
+       wl12xx_notice("power up");
+
+       if (wl->state != WL12XX_STATE_OFF) {
+               wl12xx_error("cannot go into PLT state because not "
+                            "in off state: %d", wl->state);
+               return -EBUSY;
+       }
+
+       wl->state = WL12XX_STATE_PLT;
+
+       ret = wl12xx_chip_wakeup(wl);
+       if (ret < 0)
+               return ret;
+
+       ret = wl->chip.op_boot(wl);
+       if (ret < 0)
+               return ret;
+
+       wl12xx_notice("firmware booted in PLT mode (%s)", wl->chip.fw_ver);
+
+       ret = wl->chip.op_plt_init(wl);
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+
+int wl12xx_plt_stop(struct wl12xx *wl)
+{
+       wl12xx_notice("power down");
+
+       if (wl->state != WL12XX_STATE_PLT) {
+               wl12xx_error("cannot power down because not in PLT "
+                            "state: %d", wl->state);
+               return -EBUSY;
+       }
+
+       wl12xx_disable_interrupts(wl);
+       wl12xx_power_off(wl);
+
+       wl->state = WL12XX_STATE_OFF;
+
+       return 0;
+}
+
+
+static int wl12xx_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
+{
+       struct wl12xx *wl = hw->priv;
+
+       skb_queue_tail(&wl->tx_queue, skb);
+
+       schedule_work(&wl->tx_work);
+
+       /*
+        * The workqueue is slow to process the tx_queue and we need stop
+        * the queue here, otherwise the queue will get too long.
+        */
+       if (skb_queue_len(&wl->tx_queue) >= WL12XX_TX_QUEUE_MAX_LENGTH) {
+               ieee80211_stop_queues(wl->hw);
+
+               /*
+                * FIXME: this is racy, the variable is not properly
+                * protected. Maybe fix this by removing the stupid
+                * variable altogether and checking the real queue state?
+                */
+               wl->tx_queue_stopped = true;
+       }
+
+       return NETDEV_TX_OK;
+}
+
+static int wl12xx_op_start(struct ieee80211_hw *hw)
+{
+       struct wl12xx *wl = hw->priv;
+       int ret = 0;
+
+       wl12xx_debug(DEBUG_MAC80211, "mac80211 start");
+
+       mutex_lock(&wl->mutex);
+
+       if (wl->state != WL12XX_STATE_OFF) {
+               wl12xx_error("cannot start because not in off state: %d",
+                            wl->state);
+               ret = -EBUSY;
+               goto out;
+       }
+
+       ret = wl12xx_chip_wakeup(wl);
+       if (ret < 0)
+               return ret;
+
+       ret = wl->chip.op_boot(wl);
+       if (ret < 0)
+               goto out;
+
+       ret = wl->chip.op_hw_init(wl);
+       if (ret < 0)
+               goto out;
+
+       ret = wl12xx_acx_station_id(wl);
+       if (ret < 0)
+               goto out;
+
+       wl->state = WL12XX_STATE_ON;
+
+       wl12xx_info("firmware booted (%s)", wl->chip.fw_ver);
+
+out:
+       if (ret < 0)
+               wl12xx_power_off(wl);
+
+       mutex_unlock(&wl->mutex);
+
+       return ret;
+}
+
+static void wl12xx_op_stop(struct ieee80211_hw *hw)
+{
+       struct wl12xx *wl = hw->priv;
+
+       wl12xx_info("down");
+
+       wl12xx_debug(DEBUG_MAC80211, "mac80211 stop");
+
+       mutex_lock(&wl->mutex);
+
+       WARN_ON(wl->state != WL12XX_STATE_ON);
+
+       if (wl->scanning) {
+               mutex_unlock(&wl->mutex);
+               ieee80211_scan_completed(wl->hw, true);
+               mutex_lock(&wl->mutex);
+               wl->scanning = false;
+       }
+
+       wl->state = WL12XX_STATE_OFF;
+
+       wl12xx_disable_interrupts(wl);
+
+       mutex_unlock(&wl->mutex);
+
+       cancel_work_sync(&wl->irq_work);
+       cancel_work_sync(&wl->tx_work);
+       cancel_work_sync(&wl->filter_work);
+
+       mutex_lock(&wl->mutex);
+
+       /* let's notify MAC80211 about the remaining pending TX frames */
+       wl12xx_tx_flush(wl);
+
+       wl12xx_power_off(wl);
+
+       memset(wl->bssid, 0, ETH_ALEN);
+       wl->listen_int = 1;
+       wl->bss_type = MAX_BSS_TYPE;
+
+       wl->data_in_count = 0;
+       wl->rx_counter = 0;
+       wl->rx_handled = 0;
+       wl->rx_current_buffer = 0;
+       wl->rx_last_id = 0;
+       wl->next_tx_complete = 0;
+       wl->elp = false;
+       wl->psm = 0;
+       wl->tx_queue_stopped = false;
+       wl->power_level = WL12XX_DEFAULT_POWER_LEVEL;
+
+       wl12xx_debugfs_reset(wl);
+
+       mutex_unlock(&wl->mutex);
+}
+
+static int wl12xx_op_add_interface(struct ieee80211_hw *hw,
+                                  struct ieee80211_if_init_conf *conf)
+{
+       struct wl12xx *wl = hw->priv;
+       DECLARE_MAC_BUF(mac);
+       int ret = 0;
+
+       wl12xx_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %s",
+                    conf->type, print_mac(mac, conf->mac_addr));
+
+       mutex_lock(&wl->mutex);
+
+       switch (conf->type) {
+       case NL80211_IFTYPE_STATION:
+               wl->bss_type = BSS_TYPE_STA_BSS;
+               break;
+       case NL80211_IFTYPE_ADHOC:
+               wl->bss_type = BSS_TYPE_IBSS;
+               break;
+       default:
+               ret = -EOPNOTSUPP;
+               goto out;
+       }
+
+       if (memcmp(wl->mac_addr, conf->mac_addr, ETH_ALEN)) {
+               memcpy(wl->mac_addr, conf->mac_addr, ETH_ALEN);
+               SET_IEEE80211_PERM_ADDR(wl->hw, wl->mac_addr);
+               ret = wl12xx_acx_station_id(wl);
+               if (ret < 0)
+                       goto out;
+       }
+
+out:
+       mutex_unlock(&wl->mutex);
+       return ret;
+}
+
+static void wl12xx_op_remove_interface(struct ieee80211_hw *hw,
+                                        struct ieee80211_if_init_conf *conf)
+{
+       wl12xx_debug(DEBUG_MAC80211, "mac80211 remove interface");
+}
+
+static int wl12xx_build_null_data(struct wl12xx *wl)
+{
+       struct wl12xx_null_data_template template;
+
+       if (!is_zero_ether_addr(wl->bssid)) {
+               memcpy(template.header.da, wl->bssid, ETH_ALEN);
+               memcpy(template.header.bssid, wl->bssid, ETH_ALEN);
+       } else {
+               memset(template.header.da, 0xff, ETH_ALEN);
+               memset(template.header.bssid, 0xff, ETH_ALEN);
+       }
+
+       memcpy(template.header.sa, wl->mac_addr, ETH_ALEN);
+       template.header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_DATA |
+                                               IEEE80211_STYPE_NULLFUNC);
+
+       return wl12xx_cmd_template_set(wl, CMD_NULL_DATA, &template,
+                                      sizeof(template));
+
+}
+
+static int wl12xx_build_ps_poll(struct wl12xx *wl, u16 aid)
+{
+       struct wl12xx_ps_poll_template template;
+
+       memcpy(template.bssid, wl->bssid, ETH_ALEN);
+       memcpy(template.ta, wl->mac_addr, ETH_ALEN);
+       template.aid = aid;
+       template.fc = cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_PSPOLL);
+
+       return wl12xx_cmd_template_set(wl, CMD_PS_POLL, &template,
+                                      sizeof(template));
+
+}
+
+static int wl12xx_op_config(struct ieee80211_hw *hw, u32 changed)
+{
+       struct wl12xx *wl = hw->priv;
+       struct ieee80211_conf *conf = &hw->conf;
+       int channel, ret = 0;
+
+       channel = ieee80211_frequency_to_channel(conf->channel->center_freq);
+
+       wl12xx_debug(DEBUG_MAC80211, "mac80211 config ch %d psm %s power %d",
+                    channel,
+                    conf->flags & IEEE80211_CONF_PS ? "on" : "off",
+                    conf->power_level);
+
+       mutex_lock(&wl->mutex);
+
+       if (channel != wl->channel) {
+               /* FIXME: use beacon interval provided by mac80211 */
+               ret = wl12xx_cmd_join(wl, wl->bss_type, 1, 100, 0);
+               if (ret < 0)
+                       goto out;
+
+               wl->channel = channel;
+       }
+
+       ret = wl12xx_build_null_data(wl);
+       if (ret < 0)
+               goto out;
+
+       if (conf->flags & IEEE80211_CONF_PS && !wl->psm_requested) {
+               wl12xx_info("psm enabled");
+
+               wl->psm_requested = true;
+
+               /*
+                * We enter PSM only if we're already associated.
+                * If we're not, we'll enter it when joining an SSID,
+                * through the bss_info_changed() hook.
+                */
+               ret = wl12xx_ps_set_mode(wl, STATION_POWER_SAVE_MODE);
+       } else if (!(conf->flags & IEEE80211_CONF_PS) &&
+                  wl->psm_requested) {
+               wl12xx_info("psm disabled");
+
+               wl->psm_requested = false;
+
+               if (wl->psm)
+                       ret = wl12xx_ps_set_mode(wl, STATION_ACTIVE_MODE);
+       }
+
+       if (conf->power_level != wl->power_level) {
+               ret = wl12xx_acx_tx_power(wl, conf->power_level);
+               if (ret < 0)
+                       goto out;
+
+               wl->power_level = conf->power_level;
+       }
+
+out:
+       mutex_unlock(&wl->mutex);
+       return ret;
+}
+
+#define WL12XX_SUPPORTED_FILTERS (FIF_PROMISC_IN_BSS | \
+                                 FIF_ALLMULTI | \
+                                 FIF_FCSFAIL | \
+                                 FIF_BCN_PRBRESP_PROMISC | \
+                                 FIF_CONTROL | \
+                                 FIF_OTHER_BSS)
+
+static void wl12xx_op_configure_filter(struct ieee80211_hw *hw,
+                                      unsigned int changed,
+                                      unsigned int *total,
+                                      int mc_count,
+                                      struct dev_addr_list *mc_list)
+{
+       struct wl12xx *wl = hw->priv;
+
+       wl12xx_debug(DEBUG_MAC80211, "mac80211 configure filter");
+
+       *total &= WL12XX_SUPPORTED_FILTERS;
+       changed &= WL12XX_SUPPORTED_FILTERS;
+
+       if (changed == 0)
+               /* no filters which we support changed */
+               return;
+
+       /* FIXME: wl->rx_config and wl->rx_filter are not protected */
+
+       wl->rx_config = WL12XX_DEFAULT_RX_CONFIG;
+       wl->rx_filter = WL12XX_DEFAULT_RX_FILTER;
+
+       if (*total & FIF_PROMISC_IN_BSS) {
+               wl->rx_config |= CFG_BSSID_FILTER_EN;
+               wl->rx_config |= CFG_RX_ALL_GOOD;
+       }
+       if (*total & FIF_ALLMULTI)
+               /*
+                * CFG_MC_FILTER_EN in rx_config needs to be 0 to receive
+                * all multicast frames
+                */
+               wl->rx_config &= ~CFG_MC_FILTER_EN;
+       if (*total & FIF_FCSFAIL)
+               wl->rx_filter |= CFG_RX_FCS_ERROR;
+       if (*total & FIF_BCN_PRBRESP_PROMISC) {
+               wl->rx_config &= ~CFG_BSSID_FILTER_EN;
+               wl->rx_config &= ~CFG_SSID_FILTER_EN;
+       }
+       if (*total & FIF_CONTROL)
+               wl->rx_filter |= CFG_RX_CTL_EN;
+       if (*total & FIF_OTHER_BSS)
+               wl->rx_filter &= ~CFG_BSSID_FILTER_EN;
+
+       /*
+        * FIXME: workqueues need to be properly cancelled on stop(), for
+        * now let's just disable changing the filter settings. They will
+        * be updated any on config().
+        */
+       /* schedule_work(&wl->filter_work); */
+}
+
+/* HW encryption */
+static int wl12xx_set_key_type(struct wl12xx *wl, struct acx_set_key *key,
+                              enum set_key_cmd cmd,
+                              struct ieee80211_key_conf *mac80211_key,
+                              const u8 *addr)
+{
+       switch (mac80211_key->alg) {
+       case ALG_WEP:
+               if (is_broadcast_ether_addr(addr))
+                       key->key_type = KEY_WEP_DEFAULT;
+               else
+                       key->key_type = KEY_WEP_ADDR;
+
+               mac80211_key->hw_key_idx = mac80211_key->keyidx;
+               break;
+       case ALG_TKIP:
+               if (is_broadcast_ether_addr(addr))
+                       key->key_type = KEY_TKIP_MIC_GROUP;
+               else
+                       key->key_type = KEY_TKIP_MIC_PAIRWISE;
+
+               mac80211_key->hw_key_idx = mac80211_key->keyidx;
+               break;
+       case ALG_CCMP:
+               if (is_broadcast_ether_addr(addr))
+                       key->key_type = KEY_AES_GROUP;
+               else
+                       key->key_type = KEY_AES_PAIRWISE;
+               mac80211_key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
+               break;
+       default:
+               wl12xx_error("Unknown key algo 0x%x", mac80211_key->alg);
+               return -EOPNOTSUPP;
+       }
+
+       return 0;
+}
+
+static int wl12xx_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
+                            struct ieee80211_vif *vif,
+                            struct ieee80211_sta *sta,
+                            struct ieee80211_key_conf *key)
+{
+       struct wl12xx *wl = hw->priv;
+       struct acx_set_key wl_key;
+       const u8 *addr;
+       int ret;
+
+       static const u8 bcast_addr[ETH_ALEN] =
+               { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+
+       wl12xx_debug(DEBUG_MAC80211, "mac80211 set key");
+
+       memset(&wl_key, 0, sizeof(wl_key));
+
+       addr = sta ? sta->addr : bcast_addr;
+
+       wl12xx_debug(DEBUG_CRYPT, "CMD: 0x%x", cmd);
+       wl12xx_dump(DEBUG_CRYPT, "ADDR: ", addr, ETH_ALEN);
+       wl12xx_debug(DEBUG_CRYPT, "Key: algo:0x%x, id:%d, len:%d flags 0x%x",
+                    key->alg, key->keyidx, key->keylen, key->flags);
+       wl12xx_dump(DEBUG_CRYPT, "KEY: ", key->key, key->keylen);
+
+       mutex_lock(&wl->mutex);
+
+       switch (cmd) {
+       case SET_KEY:
+               wl_key.key_action = KEY_ADD_OR_REPLACE;
+               break;
+       case DISABLE_KEY:
+               wl_key.key_action = KEY_REMOVE;
+               break;
+       default:
+               wl12xx_error("Unsupported key cmd 0x%x", cmd);
+               break;
+       }
+
+       ret = wl12xx_set_key_type(wl, &wl_key, cmd, key, addr);
+       if (ret < 0) {
+               wl12xx_error("Set KEY type failed");
+               goto out;
+       }
+
+       if (wl_key.key_type != KEY_WEP_DEFAULT)
+               memcpy(wl_key.addr, addr, ETH_ALEN);
+
+       if ((wl_key.key_type == KEY_TKIP_MIC_GROUP) ||
+           (wl_key.key_type == KEY_TKIP_MIC_PAIRWISE)) {
+               /*
+                * We get the key in the following form:
+                * TKIP (16 bytes) - TX MIC (8 bytes) - RX MIC (8 bytes)
+                * but the target is expecting:
+                * TKIP - RX MIC - TX MIC
+                */
+               memcpy(wl_key.key, key->key, 16);
+               memcpy(wl_key.key + 16, key->key + 24, 8);
+               memcpy(wl_key.key + 24, key->key + 16, 8);
+
+       } else {
+               memcpy(wl_key.key, key->key, key->keylen);
+       }
+       wl_key.key_size = key->keylen;
+
+       wl_key.id = key->keyidx;
+       wl_key.ssid_profile = 0;
+
+       wl12xx_dump(DEBUG_CRYPT, "TARGET KEY: ", &wl_key, sizeof(wl_key));
+
+       if (wl12xx_cmd_send(wl, CMD_SET_KEYS, &wl_key, sizeof(wl_key)) < 0) {
+               wl12xx_error("Set KEY failed");
+               ret = -EOPNOTSUPP;
+               goto out;
+       }
+
+out:
+       mutex_unlock(&wl->mutex);
+       return ret;
+}
+
+static int wl12xx_build_basic_rates(char *rates)
+{
+       u8 index = 0;
+
+       rates[index++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
+       rates[index++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
+       rates[index++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
+       rates[index++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;
+
+       return index;
+}
+
+static int wl12xx_build_extended_rates(char *rates)
+{
+       u8 index = 0;
+
+       rates[index++] = IEEE80211_OFDM_RATE_6MB;
+       rates[index++] = IEEE80211_OFDM_RATE_9MB;
+       rates[index++] = IEEE80211_OFDM_RATE_12MB;
+       rates[index++] = IEEE80211_OFDM_RATE_18MB;
+       rates[index++] = IEEE80211_OFDM_RATE_24MB;
+       rates[index++] = IEEE80211_OFDM_RATE_36MB;
+       rates[index++] = IEEE80211_OFDM_RATE_48MB;
+       rates[index++] = IEEE80211_OFDM_RATE_54MB;
+
+       return index;
+}
+
+
+static int wl12xx_build_probe_req(struct wl12xx *wl, u8 *ssid, size_t ssid_len)
+{
+       struct wl12xx_probe_req_template template;
+       struct wl12xx_ie_rates *rates;
+       char *ptr;
+       u16 size;
+
+       ptr = (char *)&template;
+       size = sizeof(struct ieee80211_header);
+
+       memset(template.header.da, 0xff, ETH_ALEN);
+       memset(template.header.bssid, 0xff, ETH_ALEN);
+       memcpy(template.header.sa, wl->mac_addr, ETH_ALEN);
+       template.header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
+
+       /* IEs */
+       /* SSID */
+       template.ssid.header.id = WLAN_EID_SSID;
+       template.ssid.header.len = ssid_len;
+       if (ssid_len && ssid)
+               memcpy(template.ssid.ssid, ssid, ssid_len);
+       size += sizeof(struct wl12xx_ie_header) + ssid_len;
+       ptr += size;
+
+       /* Basic Rates */
+       rates = (struct wl12xx_ie_rates *)ptr;
+       rates->header.id = WLAN_EID_SUPP_RATES;
+       rates->header.len = wl12xx_build_basic_rates(rates->rates);
+       size += sizeof(struct wl12xx_ie_header) + rates->header.len;
+       ptr += sizeof(struct wl12xx_ie_header) + rates->header.len;
+
+       /* Extended rates */
+       rates = (struct wl12xx_ie_rates *)ptr;
+       rates->header.id = WLAN_EID_EXT_SUPP_RATES;
+       rates->header.len = wl12xx_build_extended_rates(rates->rates);
+       size += sizeof(struct wl12xx_ie_header) + rates->header.len;
+
+       wl12xx_dump(DEBUG_SCAN, "PROBE REQ: ", &template, size);
+
+       return wl12xx_cmd_template_set(wl, CMD_PROBE_REQ, &template,
+                                     size);
+}
+
+static int wl12xx_hw_scan(struct wl12xx *wl, u8 *ssid, size_t len,
+                         u8 active_scan, u8 high_prio, u8 num_channels,
+                         u8 probe_requests)
+{
+       int i, ret;
+       u32 split_scan = 0;
+       u16 scan_options = 0;
+       struct cmd_scan *params;
+       struct wl12xx_command *cmd_answer;
+
+       if (wl->scanning)
+               return -EINVAL;
+
+       params = kzalloc(sizeof(*params), GFP_KERNEL);
+       if (!params)
+               return -ENOMEM;
+
+       params->params.rx_config_options = cpu_to_le32(CFG_RX_ALL_GOOD);
+       params->params.rx_filter_options =
+               cpu_to_le32(CFG_RX_PRSP_EN | CFG_RX_MGMT_EN | CFG_RX_BCN_EN);
+
+       /* High priority scan */
+       if (!active_scan)
+               scan_options |= SCAN_PASSIVE;
+       if (high_prio)
+               scan_options |= SCAN_PRIORITY_HIGH;
+       params->params.scan_options = scan_options;
+
+       params->params.num_channels = num_channels;
+       params->params.num_probe_requests = probe_requests;
+       params->params.tx_rate = cpu_to_le16(1 << 1); /* 2 Mbps */
+       params->params.tid_trigger = 0;
+
+       for (i = 0; i < num_channels; i++) {
+               params->channels[i].min_duration = cpu_to_le32(30000);
+               params->channels[i].max_duration = cpu_to_le32(60000);
+               memset(&params->channels[i].bssid_lsb, 0xff, 4);
+               memset(&params->channels[i].bssid_msb, 0xff, 2);
+               params->channels[i].early_termination = 0;
+               params->channels[i].tx_power_att = 0;
+               params->channels[i].channel = i + 1;
+               memset(params->channels[i].pad, 0, 3);
+       }
+
+       for (i = num_channels; i < SCAN_MAX_NUM_OF_CHANNELS; i++)
+               memset(&params->channels[i], 0,
+                      sizeof(struct basic_scan_channel_parameters));
+
+       if (len && ssid) {
+               params->params.ssid_len = len;
+               memcpy(params->params.ssid, ssid, len);
+       } else {
+               params->params.ssid_len = 0;
+               memset(params->params.ssid, 0, 32);
+       }
+
+       ret = wl12xx_build_probe_req(wl, ssid, len);
+       if (ret < 0) {
+               wl12xx_error("PROBE request template failed");
+               goto out;
+       }
+
+       ret = wl12xx_cmd_send(wl, CMD_TRIGGER_SCAN_TO, &split_scan,
+                             sizeof(u32));
+       if (ret < 0) {
+               wl12xx_error("Split SCAN failed");
+               goto out;
+       }
+
+       wl12xx_dump(DEBUG_SCAN, "SCAN: ", params, sizeof(*params));
+
+       wl->scanning = true;
+
+       ret = wl12xx_cmd_send(wl, CMD_SCAN, params, sizeof(*params));
+       if (ret < 0)
+               wl12xx_error("SCAN failed");
+
+       wl12xx_spi_mem_read(wl, wl->cmd_box_addr, params, sizeof(*params));
+
+       cmd_answer = (struct wl12xx_command *) params;
+       if (cmd_answer->status != CMD_STATUS_SUCCESS) {
+               wl12xx_error("TEST command answer error: %d",
+                            cmd_answer->status);
+               wl->scanning = false;
+               ret = -EIO;
+               goto out;
+       }
+
+out:
+       kfree(params);
+       return ret;
+
+}
+
+static int wl12xx_op_hw_scan(struct ieee80211_hw *hw,
+                            struct cfg80211_scan_request *req)
+{
+       struct wl12xx *wl = hw->priv;
+       int ret;
+       u8 *ssid = NULL;
+       size_t ssid_len = 0;
+
+       wl12xx_debug(DEBUG_MAC80211, "mac80211 hw scan");
+
+       if (req->n_ssids) {
+               ssid = req->ssids[0].ssid;
+               ssid_len = req->ssids[0].ssid_len;
+       }
+
+       mutex_lock(&wl->mutex);
+       ret = wl12xx_hw_scan(hw->priv, ssid, ssid_len, 1, 0, 13, 3);
+       mutex_unlock(&wl->mutex);
+
+       return ret;
+}
+
+static int wl12xx_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
+{
+       struct wl12xx *wl = hw->priv;
+       int ret;
+
+       ret = wl12xx_acx_rts_threshold(wl, (u16) value);
+
+       if (ret < 0)
+               wl12xx_warning("wl12xx_op_set_rts_threshold failed: %d", ret);
+
+       return ret;
+}
+
+static void wl12xx_op_bss_info_changed(struct ieee80211_hw *hw,
+                                      struct ieee80211_vif *vif,
+                                      struct ieee80211_bss_conf *bss_conf,
+                                      u32 changed)
+{
+       enum acx_ps_mode mode;
+       struct wl12xx *wl = hw->priv;
+       struct sk_buff *beacon;
+       int ret;
+
+       wl12xx_debug(DEBUG_MAC80211, "mac80211 bss info changed");
+
+       mutex_lock(&wl->mutex);
+
+       if (changed & BSS_CHANGED_ASSOC) {
+               if (bss_conf->assoc) {
+                       wl->aid = bss_conf->aid;
+
+                       ret = wl12xx_build_ps_poll(wl, wl->aid);
+                       if (ret < 0)
+                               goto out;
+
+                       ret = wl12xx_acx_aid(wl, wl->aid);
+                       if (ret < 0)
+                               goto out;
+
+                       /* If we want to go in PSM but we're not there yet */
+                       if (wl->psm_requested && !wl->psm) {
+                               mode = STATION_POWER_SAVE_MODE;
+                               ret = wl12xx_ps_set_mode(wl, mode);
+                               if (ret < 0)
+                                       goto out;
+                       }
+               }
+       }
+       if (changed & BSS_CHANGED_ERP_SLOT) {
+               if (bss_conf->use_short_slot)
+                       ret = wl12xx_acx_slot(wl, SLOT_TIME_SHORT);
+               else
+                       ret = wl12xx_acx_slot(wl, SLOT_TIME_LONG);
+               if (ret < 0) {
+                       wl12xx_warning("Set slot time failed %d", ret);
+                       goto out;
+               }
+       }
+
+       if (changed & BSS_CHANGED_ERP_PREAMBLE) {
+               if (bss_conf->use_short_preamble)
+                       wl12xx_acx_set_preamble(wl, ACX_PREAMBLE_SHORT);
+               else
+                       wl12xx_acx_set_preamble(wl, ACX_PREAMBLE_LONG);
+       }
+
+       if (changed & BSS_CHANGED_ERP_CTS_PROT) {
+               if (bss_conf->use_cts_prot)
+                       ret = wl12xx_acx_cts_protect(wl, CTSPROTECT_ENABLE);
+               else
+                       ret = wl12xx_acx_cts_protect(wl, CTSPROTECT_DISABLE);
+               if (ret < 0) {
+                       wl12xx_warning("Set ctsprotect failed %d", ret);
+                       goto out;
+               }
+       }
+
+       if (changed & BSS_CHANGED_BSSID) {
+               memcpy(wl->bssid, bss_conf->bssid, ETH_ALEN);
+
+               ret = wl12xx_build_null_data(wl);
+               if (ret < 0)
+                       goto out;
+
+               if (wl->bss_type != BSS_TYPE_IBSS) {
+                       ret = wl12xx_cmd_join(wl, wl->bss_type, 5, 100, 1);
+                       if (ret < 0)
+                               goto out;
+               }
+       }
+
+       if (changed & BSS_CHANGED_BEACON) {
+               beacon = ieee80211_beacon_get(hw, vif);
+               ret = wl12xx_cmd_template_set(wl, CMD_BEACON, beacon->data,
+                                             beacon->len);
+
+               if (ret < 0) {
+                       dev_kfree_skb(beacon);
+                       goto out;
+               }
+
+               ret = wl12xx_cmd_template_set(wl, CMD_PROBE_RESP, beacon->data,
+                                             beacon->len);
+
+               dev_kfree_skb(beacon);
+
+               if (ret < 0)
+                       goto out;
+
+               ret = wl12xx_cmd_join(wl, wl->bss_type, 1, 100, 0);
+
+               if (ret < 0)
+                       goto out;
+       }
+
+out:
+       mutex_unlock(&wl->mutex);
+}
+
+
+/* can't be const, mac80211 writes to this */
+static struct ieee80211_rate wl12xx_rates[] = {
+       { .bitrate = 10,
+         .hw_value = 0x1,
+         .hw_value_short = 0x1, },
+       { .bitrate = 20,
+         .hw_value = 0x2,
+         .hw_value_short = 0x2,
+         .flags = IEEE80211_RATE_SHORT_PREAMBLE },
+       { .bitrate = 55,
+         .hw_value = 0x4,
+         .hw_value_short = 0x4,
+         .flags = IEEE80211_RATE_SHORT_PREAMBLE },
+       { .bitrate = 110,
+         .hw_value = 0x20,
+         .hw_value_short = 0x20,
+         .flags = IEEE80211_RATE_SHORT_PREAMBLE },
+       { .bitrate = 60,
+         .hw_value = 0x8,
+         .hw_value_short = 0x8, },
+       { .bitrate = 90,
+         .hw_value = 0x10,
+         .hw_value_short = 0x10, },
+       { .bitrate = 120,
+         .hw_value = 0x40,
+         .hw_value_short = 0x40, },
+       { .bitrate = 180,
+         .hw_value = 0x80,
+         .hw_value_short = 0x80, },
+       { .bitrate = 240,
+         .hw_value = 0x200,
+         .hw_value_short = 0x200, },
+       { .bitrate = 360,
+        .hw_value = 0x400,
+        .hw_value_short = 0x400, },
+       { .bitrate = 480,
+         .hw_value = 0x800,
+         .hw_value_short = 0x800, },
+       { .bitrate = 540,
+         .hw_value = 0x1000,
+         .hw_value_short = 0x1000, },
+};
+
+/* can't be const, mac80211 writes to this */
+static struct ieee80211_channel wl12xx_channels[] = {
+       { .hw_value = 1, .center_freq = 2412},
+       { .hw_value = 2, .center_freq = 2417},
+       { .hw_value = 3, .center_freq = 2422},
+       { .hw_value = 4, .center_freq = 2427},
+       { .hw_value = 5, .center_freq = 2432},
+       { .hw_value = 6, .center_freq = 2437},
+       { .hw_value = 7, .center_freq = 2442},
+       { .hw_value = 8, .center_freq = 2447},
+       { .hw_value = 9, .center_freq = 2452},
+       { .hw_value = 10, .center_freq = 2457},
+       { .hw_value = 11, .center_freq = 2462},
+       { .hw_value = 12, .center_freq = 2467},
+       { .hw_value = 13, .center_freq = 2472},
+};
+
+/* can't be const, mac80211 writes to this */
+static struct ieee80211_supported_band wl12xx_band_2ghz = {
+       .channels = wl12xx_channels,
+       .n_channels = ARRAY_SIZE(wl12xx_channels),
+       .bitrates = wl12xx_rates,
+       .n_bitrates = ARRAY_SIZE(wl12xx_rates),
+};
+
+static const struct ieee80211_ops wl12xx_ops = {
+       .start = wl12xx_op_start,
+       .stop = wl12xx_op_stop,
+       .add_interface = wl12xx_op_add_interface,
+       .remove_interface = wl12xx_op_remove_interface,
+       .config = wl12xx_op_config,
+       .configure_filter = wl12xx_op_configure_filter,
+       .tx = wl12xx_op_tx,
+       .set_key = wl12xx_op_set_key,
+       .hw_scan = wl12xx_op_hw_scan,
+       .bss_info_changed = wl12xx_op_bss_info_changed,
+       .set_rts_threshold = wl12xx_op_set_rts_threshold,
+};
+
+static int wl12xx_register_hw(struct wl12xx *wl)
+{
+       int ret;
+
+       if (wl->mac80211_registered)
+               return 0;
+
+       SET_IEEE80211_PERM_ADDR(wl->hw, wl->mac_addr);
+
+       ret = ieee80211_register_hw(wl->hw);
+       if (ret < 0) {
+               wl12xx_error("unable to register mac80211 hw: %d", ret);
+               return ret;
+       }
+
+       wl->mac80211_registered = true;
+
+       wl12xx_notice("loaded");
+
+       return 0;
+}
+
+static int wl12xx_init_ieee80211(struct wl12xx *wl)
+{
+       /* The tx descriptor buffer and the TKIP space */
+       wl->hw->extra_tx_headroom = sizeof(struct tx_double_buffer_desc)
+               + WL12XX_TKIP_IV_SPACE;
+
+       /* unit us */
+       /* FIXME: find a proper value */
+       wl->hw->channel_change_time = 10000;
+
+       wl->hw->flags = IEEE80211_HW_SIGNAL_DBM |
+               IEEE80211_HW_NOISE_DBM;
+
+       wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
+       wl->hw->wiphy->max_scan_ssids = 1;
+       wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &wl12xx_band_2ghz;
+
+       SET_IEEE80211_DEV(wl->hw, &wl->spi->dev);
+
+       return 0;
+}
+
+#define WL12XX_DEFAULT_CHANNEL 1
+static int __devinit wl12xx_probe(struct spi_device *spi)
+{
+       struct wl12xx_platform_data *pdata;
+       struct ieee80211_hw *hw;
+       struct wl12xx *wl;
+       int ret, i;
+       static const u8 nokia_oui[3] = {0x00, 0x1f, 0xdf};
+
+       pdata = spi->dev.platform_data;
+       if (!pdata) {
+               wl12xx_error("no platform data");
+               return -ENODEV;
+       }
+
+       hw = ieee80211_alloc_hw(sizeof(*wl), &wl12xx_ops);
+       if (!hw) {
+               wl12xx_error("could not alloc ieee80211_hw");
+               return -ENOMEM;
+       }
+
+       wl = hw->priv;
+       memset(wl, 0, sizeof(*wl));
+
+       wl->hw = hw;
+       dev_set_drvdata(&spi->dev, wl);
+       wl->spi = spi;
+
+       wl->data_in_count = 0;
+
+       skb_queue_head_init(&wl->tx_queue);
+
+       INIT_WORK(&wl->tx_work, wl12xx_tx_work);
+       INIT_WORK(&wl->filter_work, wl12xx_filter_work);
+       wl->channel = WL12XX_DEFAULT_CHANNEL;
+       wl->scanning = false;
+       wl->default_key = 0;
+       wl->listen_int = 1;
+       wl->rx_counter = 0;
+       wl->rx_handled = 0;
+       wl->rx_current_buffer = 0;
+       wl->rx_last_id = 0;
+       wl->rx_config = WL12XX_DEFAULT_RX_CONFIG;
+       wl->rx_filter = WL12XX_DEFAULT_RX_FILTER;
+       wl->elp = false;
+       wl->psm = 0;
+       wl->psm_requested = false;
+       wl->tx_queue_stopped = false;
+       wl->power_level = WL12XX_DEFAULT_POWER_LEVEL;
+
+       /* We use the default power on sleep time until we know which chip
+        * we're using */
+       wl->chip.power_on_sleep = WL12XX_DEFAULT_POWER_ON_SLEEP;
+
+       for (i = 0; i < FW_TX_CMPLT_BLOCK_SIZE; i++)
+               wl->tx_frames[i] = NULL;
+
+       wl->next_tx_complete = 0;
+
+       /*
+        * In case our MAC address is not correctly set,
+        * we use a random but Nokia MAC.
+        */
+       memcpy(wl->mac_addr, nokia_oui, 3);
+       get_random_bytes(wl->mac_addr + 3, 3);
+
+       wl->state = WL12XX_STATE_OFF;
+       mutex_init(&wl->mutex);
+
+       wl->tx_mgmt_frm_rate = DEFAULT_HW_GEN_TX_RATE;
+       wl->tx_mgmt_frm_mod = DEFAULT_HW_GEN_MODULATION_TYPE;
+
+       /* This is the only SPI value that we need to set here, the rest
+        * comes from the board-peripherals file */
+       spi->bits_per_word = 32;
+
+       ret = spi_setup(spi);
+       if (ret < 0) {
+               wl12xx_error("spi_setup failed");
+               goto out_free;
+       }
+
+       wl->set_power = pdata->set_power;
+       if (!wl->set_power) {
+               wl12xx_error("set power function missing in platform data");
+               return -ENODEV;
+       }
+
+       wl->irq = spi->irq;
+       if (wl->irq < 0) {
+               wl12xx_error("irq missing in platform data");
+               return -ENODEV;
+       }
+
+       ret = request_irq(wl->irq, wl12xx_irq, 0, DRIVER_NAME, wl);
+       if (ret < 0) {
+               wl12xx_error("request_irq() failed: %d", ret);
+               goto out_free;
+       }
+
+       set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING);
+
+       disable_irq(wl->irq);
+
+       ret = wl12xx_init_ieee80211(wl);
+       if (ret)
+               goto out_irq;
+
+       ret = wl12xx_register_hw(wl);
+       if (ret)
+               goto out_irq;
+
+       wl12xx_debugfs_init(wl);
+
+       wl12xx_notice("initialized");
+
+       return 0;
+
+ out_irq:
+       free_irq(wl->irq, wl);
+
+ out_free:
+       ieee80211_free_hw(hw);
+
+       return ret;
+}
+
+static int __devexit wl12xx_remove(struct spi_device *spi)
+{
+       struct wl12xx *wl = dev_get_drvdata(&spi->dev);
+
+       ieee80211_unregister_hw(wl->hw);
+
+       wl12xx_debugfs_exit(wl);
+
+       free_irq(wl->irq, wl);
+       kfree(wl->target_mem_map);
+       kfree(wl->data_path);
+       kfree(wl->fw);
+       wl->fw = NULL;
+       kfree(wl->nvs);
+       wl->nvs = NULL;
+       ieee80211_free_hw(wl->hw);
+
+       return 0;
+}
+
+
+static struct spi_driver wl12xx_spi_driver = {
+       .driver = {
+               .name           = "wl12xx",
+               .bus            = &spi_bus_type,
+               .owner          = THIS_MODULE,
+       },
+
+       .probe          = wl12xx_probe,
+       .remove         = __devexit_p(wl12xx_remove),
+};
+
+static int __init wl12xx_init(void)
+{
+       int ret;
+
+       ret = spi_register_driver(&wl12xx_spi_driver);
+       if (ret < 0) {
+               wl12xx_error("failed to register spi driver: %d", ret);
+               goto out;
+       }
+
+out:
+       return ret;
+}
+
+static void __exit wl12xx_exit(void)
+{
+       spi_unregister_driver(&wl12xx_spi_driver);
+
+       wl12xx_notice("unloaded");
+}
+
+module_init(wl12xx_init);
+module_exit(wl12xx_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Kalle Valo <Kalle.Valo@nokia.com>, "
+               "Luciano Coelho <luciano.coelho@nokia.com>");
diff --git a/drivers/net/wireless/wl12xx/ps.c b/drivers/net/wireless/wl12xx/ps.c
new file mode 100644 (file)
index 0000000..83a1011
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include "reg.h"
+#include "ps.h"
+#include "spi.h"
+
+#define WL12XX_WAKEUP_TIMEOUT 2000
+
+/* Routines to toggle sleep mode while in ELP */
+void wl12xx_ps_elp_sleep(struct wl12xx *wl)
+{
+       if (wl->elp || !wl->psm)
+               return;
+
+       wl12xx_debug(DEBUG_PSM, "chip to elp");
+
+       wl12xx_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_SLEEP);
+
+       wl->elp = true;
+}
+
+int wl12xx_ps_elp_wakeup(struct wl12xx *wl)
+{
+       unsigned long timeout;
+       u32 elp_reg;
+
+       if (!wl->elp)
+               return 0;
+
+       wl12xx_debug(DEBUG_PSM, "waking up chip from elp");
+
+       timeout = jiffies + msecs_to_jiffies(WL12XX_WAKEUP_TIMEOUT);
+
+       wl12xx_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_WAKE_UP);
+
+       elp_reg = wl12xx_read32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR);
+
+       /*
+        * FIXME: we should wait for irq from chip but, as a temporary
+        * solution to simplify locking, let's poll instead
+        */
+       while (!(elp_reg & ELPCTRL_WLAN_READY)) {
+               if (time_after(jiffies, timeout)) {
+                       wl12xx_error("elp wakeup timeout");
+                       return -ETIMEDOUT;
+               }
+               msleep(1);
+               elp_reg = wl12xx_read32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR);
+       }
+
+       wl12xx_debug(DEBUG_PSM, "wakeup time: %u ms",
+                    jiffies_to_msecs(jiffies) -
+                    (jiffies_to_msecs(timeout) - WL12XX_WAKEUP_TIMEOUT));
+
+       wl->elp = false;
+
+       return 0;
+}
+
+static int wl12xx_ps_set_elp(struct wl12xx *wl, bool enable)
+{
+       int ret;
+
+       if (enable) {
+               wl12xx_debug(DEBUG_PSM, "sleep auth psm/elp");
+
+               /*
+                * FIXME: we should PSM_ELP, but because of firmware wakeup
+                * problems let's use only PSM_PS
+                */
+               ret = wl12xx_acx_sleep_auth(wl, WL12XX_PSM_PS);
+               if (ret < 0)
+                       return ret;
+
+               wl12xx_ps_elp_sleep(wl);
+       } else {
+               wl12xx_debug(DEBUG_PSM, "sleep auth cam");
+
+               /*
+                * When the target is in ELP, we can only
+                * access the ELP control register. Thus,
+                * we have to wake the target up before
+                * changing the power authorization.
+                */
+
+               wl12xx_ps_elp_wakeup(wl);
+
+               ret = wl12xx_acx_sleep_auth(wl, WL12XX_PSM_CAM);
+               if (ret < 0)
+                       return ret;
+       }
+
+       return 0;
+}
+
+int wl12xx_ps_set_mode(struct wl12xx *wl, enum acx_ps_mode mode)
+{
+       int ret;
+
+       switch (mode) {
+       case STATION_POWER_SAVE_MODE:
+               wl12xx_debug(DEBUG_PSM, "entering psm");
+               ret = wl12xx_cmd_ps_mode(wl, STATION_POWER_SAVE_MODE);
+               if (ret < 0)
+                       return ret;
+
+               ret = wl12xx_ps_set_elp(wl, true);
+               if (ret < 0)
+                       return ret;
+
+               wl->psm = 1;
+               break;
+       case STATION_ACTIVE_MODE:
+       default:
+               wl12xx_debug(DEBUG_PSM, "leaving psm");
+               ret = wl12xx_ps_set_elp(wl, false);
+               if (ret < 0)
+                       return ret;
+
+               ret = wl12xx_cmd_ps_mode(wl, STATION_ACTIVE_MODE);
+               if (ret < 0)
+                       return ret;
+
+               wl->psm = 0;
+               break;
+       }
+
+       return ret;
+}
+
diff --git a/drivers/net/wireless/wl12xx/ps.h b/drivers/net/wireless/wl12xx/ps.h
new file mode 100644 (file)
index 0000000..5d7c525
--- /dev/null
@@ -0,0 +1,36 @@
+#ifndef __WL12XX_PS_H__
+#define __WL12XX_PS_H__
+
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (c) 1998-2007 Texas Instruments Incorporated
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include "wl12xx.h"
+#include "acx.h"
+
+int wl12xx_ps_set_mode(struct wl12xx *wl, enum acx_ps_mode mode);
+void wl12xx_ps_elp_sleep(struct wl12xx *wl);
+int wl12xx_ps_elp_wakeup(struct wl12xx *wl);
+
+
+#endif /* __WL12XX_PS_H__ */
diff --git a/drivers/net/wireless/wl12xx/reg.h b/drivers/net/wireless/wl12xx/reg.h
new file mode 100644 (file)
index 0000000..e421643
--- /dev/null
@@ -0,0 +1,745 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (c) 1998-2007 Texas Instruments Incorporated
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __REG_H__
+#define __REG_H__
+
+#include <linux/bitops.h>
+#include "wl12xx.h"
+
+#define REGISTERS_BASE 0x00300000
+#define DRPW_BASE      0x00310000
+
+#define REGISTERS_DOWN_SIZE 0x00008800
+#define REGISTERS_WORK_SIZE 0x0000b000
+
+#define HW_ACCESS_ELP_CTRL_REG_ADDR         0x1FFFC
+
+/* ELP register commands */
+#define ELPCTRL_WAKE_UP             0x1
+#define ELPCTRL_WAKE_UP_WLAN_READY  0x5
+#define ELPCTRL_SLEEP               0x0
+/* ELP WLAN_READY bit */
+#define ELPCTRL_WLAN_READY          0x2
+
+/*
+ * Interrupt registers.
+ * 64 bit interrupt sources registers ws ced.
+ * sme interupts were removed and new ones were added.
+ * Order was changed.
+ */
+#define FIQ_MASK                       (REGISTERS_BASE + 0x0400)
+#define FIQ_MASK_L                     (REGISTERS_BASE + 0x0400)
+#define FIQ_MASK_H                     (REGISTERS_BASE + 0x0404)
+#define FIQ_MASK_SET                   (REGISTERS_BASE + 0x0408)
+#define FIQ_MASK_SET_L                 (REGISTERS_BASE + 0x0408)
+#define FIQ_MASK_SET_H                 (REGISTERS_BASE + 0x040C)
+#define FIQ_MASK_CLR                   (REGISTERS_BASE + 0x0410)
+#define FIQ_MASK_CLR_L                 (REGISTERS_BASE + 0x0410)
+#define FIQ_MASK_CLR_H                 (REGISTERS_BASE + 0x0414)
+#define IRQ_MASK                       (REGISTERS_BASE + 0x0418)
+#define IRQ_MASK_L                     (REGISTERS_BASE + 0x0418)
+#define IRQ_MASK_H                     (REGISTERS_BASE + 0x041C)
+#define IRQ_MASK_SET                   (REGISTERS_BASE + 0x0420)
+#define IRQ_MASK_SET_L                 (REGISTERS_BASE + 0x0420)
+#define IRQ_MASK_SET_H                 (REGISTERS_BASE + 0x0424)
+#define IRQ_MASK_CLR                   (REGISTERS_BASE + 0x0428)
+#define IRQ_MASK_CLR_L                 (REGISTERS_BASE + 0x0428)
+#define IRQ_MASK_CLR_H                 (REGISTERS_BASE + 0x042C)
+#define ECPU_MASK                      (REGISTERS_BASE + 0x0448)
+#define FIQ_STS_L                      (REGISTERS_BASE + 0x044C)
+#define FIQ_STS_H                      (REGISTERS_BASE + 0x0450)
+#define IRQ_STS_L                      (REGISTERS_BASE + 0x0454)
+#define IRQ_STS_H                      (REGISTERS_BASE + 0x0458)
+#define INT_STS_ND                     (REGISTERS_BASE + 0x0464)
+#define INT_STS_RAW_L                  (REGISTERS_BASE + 0x0464)
+#define INT_STS_RAW_H                  (REGISTERS_BASE + 0x0468)
+#define INT_STS_CLR                    (REGISTERS_BASE + 0x04B4)
+#define INT_STS_CLR_L                  (REGISTERS_BASE + 0x04B4)
+#define INT_STS_CLR_H                  (REGISTERS_BASE + 0x04B8)
+#define INT_ACK                        (REGISTERS_BASE + 0x046C)
+#define INT_ACK_L                      (REGISTERS_BASE + 0x046C)
+#define INT_ACK_H                      (REGISTERS_BASE + 0x0470)
+#define INT_TRIG                       (REGISTERS_BASE + 0x0474)
+#define INT_TRIG_L                     (REGISTERS_BASE + 0x0474)
+#define INT_TRIG_H                     (REGISTERS_BASE + 0x0478)
+#define HOST_STS_L                     (REGISTERS_BASE + 0x045C)
+#define HOST_STS_H                     (REGISTERS_BASE + 0x0460)
+#define HOST_MASK                      (REGISTERS_BASE + 0x0430)
+#define HOST_MASK_L                    (REGISTERS_BASE + 0x0430)
+#define HOST_MASK_H                    (REGISTERS_BASE + 0x0434)
+#define HOST_MASK_SET                  (REGISTERS_BASE + 0x0438)
+#define HOST_MASK_SET_L                (REGISTERS_BASE + 0x0438)
+#define HOST_MASK_SET_H                (REGISTERS_BASE + 0x043C)
+#define HOST_MASK_CLR                  (REGISTERS_BASE + 0x0440)
+#define HOST_MASK_CLR_L                (REGISTERS_BASE + 0x0440)
+#define HOST_MASK_CLR_H                (REGISTERS_BASE + 0x0444)
+
+/* Host Interrupts*/
+#define HINT_MASK                      (REGISTERS_BASE + 0x0494)
+#define HINT_MASK_SET                  (REGISTERS_BASE + 0x0498)
+#define HINT_MASK_CLR                  (REGISTERS_BASE + 0x049C)
+#define HINT_STS_ND_MASKED             (REGISTERS_BASE + 0x04A0)
+/*1150 spec calls this HINT_STS_RAW*/
+#define HINT_STS_ND                   (REGISTERS_BASE + 0x04B0)
+#define HINT_STS_CLR                   (REGISTERS_BASE + 0x04A4)
+#define HINT_ACK                       (REGISTERS_BASE + 0x04A8)
+#define HINT_TRIG                      (REGISTERS_BASE + 0x04AC)
+
+/* Device Configuration registers*/
+#define SOR_CFG                        (REGISTERS_BASE + 0x0800)
+#define ECPU_CTRL                      (REGISTERS_BASE + 0x0804)
+#define HI_CFG                         (REGISTERS_BASE + 0x0808)
+#define EE_START                       (REGISTERS_BASE + 0x080C)
+
+#define CHIP_ID_B                      (REGISTERS_BASE + 0x5674)
+
+#define CHIP_ID_1251_PG10                 (0x7010101)
+#define CHIP_ID_1251_PG11                 (0x7020101)
+#define CHIP_ID_1251_PG12                 (0x7030101)
+
+#define ENABLE                         (REGISTERS_BASE + 0x5450)
+
+/* Power Management registers */
+#define ELP_CFG_MODE                   (REGISTERS_BASE + 0x5804)
+#define ELP_CMD                        (REGISTERS_BASE + 0x5808)
+#define PLL_CAL_TIME                   (REGISTERS_BASE + 0x5810)
+#define CLK_REQ_TIME                   (REGISTERS_BASE + 0x5814)
+#define CLK_BUF_TIME                   (REGISTERS_BASE + 0x5818)
+
+#define CFG_PLL_SYNC_CNT               (REGISTERS_BASE + 0x5820)
+
+/* Scratch Pad registers*/
+#define SCR_PAD0                       (REGISTERS_BASE + 0x5608)
+#define SCR_PAD1                       (REGISTERS_BASE + 0x560C)
+#define SCR_PAD2                       (REGISTERS_BASE + 0x5610)
+#define SCR_PAD3                       (REGISTERS_BASE + 0x5614)
+#define SCR_PAD4                       (REGISTERS_BASE + 0x5618)
+#define SCR_PAD4_SET                   (REGISTERS_BASE + 0x561C)
+#define SCR_PAD4_CLR                   (REGISTERS_BASE + 0x5620)
+#define SCR_PAD5                       (REGISTERS_BASE + 0x5624)
+#define SCR_PAD5_SET                   (REGISTERS_BASE + 0x5628)
+#define SCR_PAD5_CLR                   (REGISTERS_BASE + 0x562C)
+#define SCR_PAD6                       (REGISTERS_BASE + 0x5630)
+#define SCR_PAD7                       (REGISTERS_BASE + 0x5634)
+#define SCR_PAD8                       (REGISTERS_BASE + 0x5638)
+#define SCR_PAD9                       (REGISTERS_BASE + 0x563C)
+
+/* Spare registers*/
+#define SPARE_A1                       (REGISTERS_BASE + 0x0994)
+#define SPARE_A2                       (REGISTERS_BASE + 0x0998)
+#define SPARE_A3                       (REGISTERS_BASE + 0x099C)
+#define SPARE_A4                       (REGISTERS_BASE + 0x09A0)
+#define SPARE_A5                       (REGISTERS_BASE + 0x09A4)
+#define SPARE_A6                       (REGISTERS_BASE + 0x09A8)
+#define SPARE_A7                       (REGISTERS_BASE + 0x09AC)
+#define SPARE_A8                       (REGISTERS_BASE + 0x09B0)
+#define SPARE_B1                       (REGISTERS_BASE + 0x5420)
+#define SPARE_B2                       (REGISTERS_BASE + 0x5424)
+#define SPARE_B3                       (REGISTERS_BASE + 0x5428)
+#define SPARE_B4                       (REGISTERS_BASE + 0x542C)
+#define SPARE_B5                       (REGISTERS_BASE + 0x5430)
+#define SPARE_B6                       (REGISTERS_BASE + 0x5434)
+#define SPARE_B7                       (REGISTERS_BASE + 0x5438)
+#define SPARE_B8                       (REGISTERS_BASE + 0x543C)
+
+enum wl12xx_acx_int_reg {
+       ACX_REG_INTERRUPT_TRIG,
+       ACX_REG_INTERRUPT_TRIG_H,
+
+/*=============================================
+  Host Interrupt Mask Register - 32bit (RW)
+  ------------------------------------------
+  Setting a bit in this register masks the
+  corresponding interrupt to the host.
+  0 - RX0              - Rx first dubble buffer Data Interrupt
+  1 - TXD              - Tx Data Interrupt
+  2 - TXXFR            - Tx Transfer Interrupt
+  3 - RX1              - Rx second dubble buffer Data Interrupt
+  4 - RXXFR            - Rx Transfer Interrupt
+  5 - EVENT_A  - Event Mailbox interrupt
+  6 - EVENT_B  - Event Mailbox interrupt
+  7 - WNONHST  - Wake On Host Interrupt
+  8 - TRACE_A  - Debug Trace interrupt
+  9 - TRACE_B  - Debug Trace interrupt
+ 10 - CDCMP            - Command Complete Interrupt
+ 11 -
+ 12 -
+ 13 -
+ 14 - ICOMP            - Initialization Complete Interrupt
+ 16 - SG SE            - Soft Gemini - Sense enable interrupt
+ 17 - SG SD            - Soft Gemini - Sense disable interrupt
+ 18 -                  -
+ 19 -                  -
+ 20 -                  -
+ 21-                   -
+ Default: 0x0001
+*==============================================*/
+       ACX_REG_INTERRUPT_MASK,
+
+/*=============================================
+  Host Interrupt Mask Set 16bit, (Write only)
+  ------------------------------------------
+ Setting a bit in this register sets
+ the corresponding bin in ACX_HINT_MASK register
+ without effecting the mask
+ state of other bits (0 = no effect).
+==============================================*/
+       ACX_REG_HINT_MASK_SET,
+
+/*=============================================
+  Host Interrupt Mask Clear 16bit,(Write only)
+  ------------------------------------------
+ Setting a bit in this register clears
+ the corresponding bin in ACX_HINT_MASK register
+ without effecting the mask
+ state of other bits (0 = no effect).
+=============================================*/
+       ACX_REG_HINT_MASK_CLR,
+
+/*=============================================
+  Host Interrupt Status Nondestructive Read
+  16bit,(Read only)
+  ------------------------------------------
+ The host can read this register to determine
+ which interrupts are active.
+ Reading this register doesn't
+ effect its content.
+=============================================*/
+       ACX_REG_INTERRUPT_NO_CLEAR,
+
+/*=============================================
+  Host Interrupt Status Clear on Read  Register
+  16bit,(Read only)
+  ------------------------------------------
+ The host can read this register to determine
+ which interrupts are active.
+ Reading this register clears it,
+ thus making all interrupts inactive.
+==============================================*/
+       ACX_REG_INTERRUPT_CLEAR,
+
+/*=============================================
+  Host Interrupt Acknowledge Register
+  16bit,(Write only)
+  ------------------------------------------
+ The host can set individual bits in this
+ register to clear (acknowledge) the corresp.
+ interrupt status bits in the HINT_STS_CLR and
+ HINT_STS_ND registers, thus making the
+ assotiated interrupt inactive. (0-no effect)
+==============================================*/
+       ACX_REG_INTERRUPT_ACK,
+
+/*===============================================
+   Host Software Reset - 32bit RW
+ ------------------------------------------
+    [31:1] Reserved
+    0  SOFT_RESET Soft Reset  - When this bit is set,
+    it holds the Wlan hardware in a soft reset state.
+    This reset disables all MAC and baseband processor
+    clocks except the CardBus/PCI interface clock.
+    It also initializes all MAC state machines except
+    the host interface. It does not reload the
+    contents of the EEPROM. When this bit is cleared
+    (not self-clearing), the Wlan hardware
+    exits the software reset state.
+===============================================*/
+       ACX_REG_SLV_SOFT_RESET,
+
+/*===============================================
+ EEPROM Burst Read Start  - 32bit RW
+ ------------------------------------------
+ [31:1] Reserved
+ 0  ACX_EE_START -  EEPROM Burst Read Start 0
+ Setting this bit starts a burst read from
+ the external EEPROM.
+ If this bit is set (after reset) before an EEPROM read/write,
+ the burst read starts at EEPROM address 0.
+ Otherwise, it starts at the address
+ following the address of the previous access.
+ TheWlan hardware hardware clears this bit automatically.
+
+ Default: 0x00000000
+*================================================*/
+       ACX_REG_EE_START,
+
+/* Embedded ARM CPU Control */
+
+/*===============================================
+ Halt eCPU   - 32bit RW
+ ------------------------------------------
+ 0 HALT_ECPU Halt Embedded CPU - This bit is the
+ compliment of bit 1 (MDATA2) in the SOR_CFG register.
+ During a hardware reset, this bit holds
+ the inverse of MDATA2.
+ When downloading firmware from the host,
+ set this bit (pull down MDATA2).
+ The host clears this bit after downloading the firmware into
+ zero-wait-state SSRAM.
+ When loading firmware from Flash, clear this bit (pull up MDATA2)
+ so that the eCPU can run the bootloader code in Flash
+ HALT_ECPU eCPU State
+ --------------------
+ 1 halt eCPU
+ 0 enable eCPU
+ ===============================================*/
+       ACX_REG_ECPU_CONTROL,
+
+       ACX_REG_TABLE_LEN
+};
+
+#define ACX_SLV_SOFT_RESET_BIT   BIT(1)
+#define ACX_REG_EEPROM_START_BIT BIT(1)
+
+/* Command/Information Mailbox Pointers */
+
+/*===============================================
+  Command Mailbox Pointer - 32bit RW
+ ------------------------------------------
+ This register holds the start address of
+ the command mailbox located in the Wlan hardware memory.
+ The host must read this pointer after a reset to
+ find the location of the command mailbox.
+ The Wlan hardware initializes the command mailbox
+ pointer with the default address of the command mailbox.
+ The command mailbox pointer is not valid until after
+ the host receives the Init Complete interrupt from
+ the Wlan hardware.
+ ===============================================*/
+#define REG_COMMAND_MAILBOX_PTR                                (SCR_PAD0)
+
+/*===============================================
+  Information Mailbox Pointer - 32bit RW
+ ------------------------------------------
+ This register holds the start address of
+ the information mailbox located in the Wlan hardware memory.
+ The host must read this pointer after a reset to find
+ the location of the information mailbox.
+ The Wlan hardware initializes the information mailbox pointer
+ with the default address of the information mailbox.
+ The information mailbox pointer is not valid
+ until after the host receives the Init Complete interrupt from
+ the Wlan hardware.
+ ===============================================*/
+#define REG_EVENT_MAILBOX_PTR                          (SCR_PAD1)
+
+
+/* Misc */
+
+#define REG_ENABLE_TX_RX                               (ENABLE)
+/*
+ * Rx configuration (filter) information element
+ * ---------------------------------------------
+ */
+#define REG_RX_CONFIG                          (RX_CFG)
+#define REG_RX_FILTER                          (RX_FILTER_CFG)
+
+
+#define RX_CFG_ENABLE_PHY_HEADER_PLCP   0x0002
+
+/* promiscuous - receives all valid frames */
+#define RX_CFG_PROMISCUOUS              0x0008
+
+/* receives frames from any BSSID */
+#define RX_CFG_BSSID                    0x0020
+
+/* receives frames destined to any MAC address */
+#define RX_CFG_MAC                      0x0010
+
+#define RX_CFG_ENABLE_ONLY_MY_DEST_MAC  0x0010
+#define RX_CFG_ENABLE_ANY_DEST_MAC      0x0000
+#define RX_CFG_ENABLE_ONLY_MY_BSSID     0x0020
+#define RX_CFG_ENABLE_ANY_BSSID                 0x0000
+
+/* discards all broadcast frames */
+#define RX_CFG_DISABLE_BCAST            0x0200
+
+#define RX_CFG_ENABLE_ONLY_MY_SSID      0x0400
+#define RX_CFG_ENABLE_RX_CMPLT_FCS_ERROR 0x0800
+#define RX_CFG_COPY_RX_STATUS           0x2000
+#define RX_CFG_TSF                      0x10000
+
+#define RX_CONFIG_OPTION_ANY_DST_MY_BSS         (RX_CFG_ENABLE_ANY_DEST_MAC | \
+                                         RX_CFG_ENABLE_ONLY_MY_BSSID)
+
+#define RX_CONFIG_OPTION_MY_DST_ANY_BSS         (RX_CFG_ENABLE_ONLY_MY_DEST_MAC\
+                                         | RX_CFG_ENABLE_ANY_BSSID)
+
+#define RX_CONFIG_OPTION_ANY_DST_ANY_BSS (RX_CFG_ENABLE_ANY_DEST_MAC | \
+                                         RX_CFG_ENABLE_ANY_BSSID)
+
+#define RX_CONFIG_OPTION_MY_DST_MY_BSS  (RX_CFG_ENABLE_ONLY_MY_DEST_MAC\
+                                         | RX_CFG_ENABLE_ONLY_MY_BSSID)
+
+#define RX_CONFIG_OPTION_FOR_SCAN  (RX_CFG_ENABLE_PHY_HEADER_PLCP \
+                                   | RX_CFG_ENABLE_RX_CMPLT_FCS_ERROR \
+                                   | RX_CFG_COPY_RX_STATUS | RX_CFG_TSF)
+
+#define RX_CONFIG_OPTION_FOR_MEASUREMENT (RX_CFG_ENABLE_ANY_DEST_MAC)
+
+#define RX_CONFIG_OPTION_FOR_JOIN       (RX_CFG_ENABLE_ONLY_MY_BSSID | \
+                                         RX_CFG_ENABLE_ONLY_MY_DEST_MAC)
+
+#define RX_CONFIG_OPTION_FOR_IBSS_JOIN   (RX_CFG_ENABLE_ONLY_MY_SSID | \
+                                         RX_CFG_ENABLE_ONLY_MY_DEST_MAC)
+
+#define RX_FILTER_OPTION_DEF         (CFG_RX_MGMT_EN | CFG_RX_DATA_EN\
+                                      | CFG_RX_CTL_EN | CFG_RX_BCN_EN\
+                                      | CFG_RX_AUTH_EN | CFG_RX_ASSOC_EN)
+
+#define RX_FILTER_OPTION_FILTER_ALL     0
+
+#define RX_FILTER_OPTION_DEF_PRSP_BCN  (CFG_RX_PRSP_EN | CFG_RX_MGMT_EN\
+                                       | CFG_RX_RCTS_ACK | CFG_RX_BCN_EN)
+
+#define RX_FILTER_OPTION_JOIN       (CFG_RX_MGMT_EN | CFG_RX_DATA_EN\
+                                     | CFG_RX_BCN_EN | CFG_RX_AUTH_EN\
+                                     | CFG_RX_ASSOC_EN | CFG_RX_RCTS_ACK\
+                                     | CFG_RX_PRSP_EN)
+
+
+/*===============================================
+  Phy regs
+ ===============================================*/
+#define ACX_PHY_ADDR_REG                SBB_ADDR
+#define ACX_PHY_DATA_REG                SBB_DATA
+#define ACX_PHY_CTRL_REG                SBB_CTL
+#define ACX_PHY_REG_WR_MASK             0x00000001ul
+#define ACX_PHY_REG_RD_MASK             0x00000002ul
+
+
+/*===============================================
+ EEPROM Read/Write Request 32bit RW
+ ------------------------------------------
+ 1 EE_READ - EEPROM Read Request 1 - Setting this bit
+ loads a single byte of data into the EE_DATA
+ register from the EEPROM location specified in
+ the EE_ADDR register.
+ The Wlan hardware hardware clears this bit automatically.
+ EE_DATA is valid when this bit is cleared.
+
+ 0 EE_WRITE  - EEPROM Write Request  - Setting this bit
+ writes a single byte of data from the EE_DATA register into the
+ EEPROM location specified in the EE_ADDR register.
+ The Wlan hardware hardware clears this bit automatically.
+*===============================================*/
+#define ACX_EE_CTL_REG                      EE_CTL
+#define EE_WRITE                            0x00000001ul
+#define EE_READ                             0x00000002ul
+
+/*===============================================
+  EEPROM Address  - 32bit RW
+  ------------------------------------------
+  This register specifies the address
+  within the EEPROM from/to which to read/write data.
+  ===============================================*/
+#define ACX_EE_ADDR_REG                     EE_ADDR
+
+/*===============================================
+  EEPROM Data  - 32bit RW
+  ------------------------------------------
+  This register either holds the read 8 bits of
+  data from the EEPROM or the write data
+  to be written to the EEPROM.
+  ===============================================*/
+#define ACX_EE_DATA_REG                     EE_DATA
+
+/*===============================================
+  EEPROM Base Address  - 32bit RW
+  ------------------------------------------
+  This register holds the upper nine bits
+  [23:15] of the 24-bit Wlan hardware memory
+  address for burst reads from EEPROM accesses.
+  The EEPROM provides the lower 15 bits of this address.
+  The MSB of the address from the EEPROM is ignored.
+  ===============================================*/
+#define ACX_EE_CFG                          EE_CFG
+
+/*===============================================
+  GPIO Output Values  -32bit, RW
+  ------------------------------------------
+  [31:16]  Reserved
+  [15: 0]  Specify the output values (at the output driver inputs) for
+  GPIO[15:0], respectively.
+  ===============================================*/
+#define ACX_GPIO_OUT_REG            GPIO_OUT
+#define ACX_MAX_GPIO_LINES          15
+
+/*===============================================
+  Contention window  -32bit, RW
+  ------------------------------------------
+  [31:26]  Reserved
+  [25:16]  Max (0x3ff)
+  [15:07]  Reserved
+  [06:00]  Current contention window value - default is 0x1F
+  ===============================================*/
+#define ACX_CONT_WIND_CFG_REG    CONT_WIND_CFG
+#define ACX_CONT_WIND_MIN_MASK   0x0000007f
+#define ACX_CONT_WIND_MAX        0x03ff0000
+
+/*
+ * Indirect slave register/memory registers
+ * ----------------------------------------
+ */
+#define HW_SLAVE_REG_ADDR_REG          0x00000004
+#define HW_SLAVE_REG_DATA_REG          0x00000008
+#define HW_SLAVE_REG_CTRL_REG          0x0000000c
+
+#define SLAVE_AUTO_INC                         0x00010000
+#define SLAVE_NO_AUTO_INC                      0x00000000
+#define SLAVE_HOST_LITTLE_ENDIAN       0x00000000
+
+#define HW_SLAVE_MEM_ADDR_REG          SLV_MEM_ADDR
+#define HW_SLAVE_MEM_DATA_REG          SLV_MEM_DATA
+#define HW_SLAVE_MEM_CTRL_REG          SLV_MEM_CTL
+#define HW_SLAVE_MEM_ENDIAN_REG                SLV_END_CTL
+
+#define HW_FUNC_EVENT_INT_EN           0x8000
+#define HW_FUNC_EVENT_MASK_REG         0x00000034
+
+#define ACX_MAC_TIMESTAMP_REG  (MAC_TIMESTAMP)
+
+/*===============================================
+  HI_CFG Interface Configuration Register Values
+  ------------------------------------------
+  ===============================================*/
+#define HI_CFG_UART_ENABLE          0x00000004
+#define HI_CFG_RST232_ENABLE        0x00000008
+#define HI_CFG_CLOCK_REQ_SELECT     0x00000010
+#define HI_CFG_HOST_INT_ENABLE      0x00000020
+#define HI_CFG_VLYNQ_OUTPUT_ENABLE  0x00000040
+#define HI_CFG_HOST_INT_ACTIVE_LOW  0x00000080
+#define HI_CFG_UART_TX_OUT_GPIO_15  0x00000100
+#define HI_CFG_UART_TX_OUT_GPIO_14  0x00000200
+#define HI_CFG_UART_TX_OUT_GPIO_7   0x00000400
+
+/*
+ * NOTE: USE_ACTIVE_HIGH compilation flag should be defined in makefile
+ *       for platforms using active high interrupt level
+ */
+#ifdef USE_ACTIVE_HIGH
+#define HI_CFG_DEF_VAL              \
+       (HI_CFG_UART_ENABLE |        \
+       HI_CFG_RST232_ENABLE |      \
+       HI_CFG_CLOCK_REQ_SELECT |   \
+       HI_CFG_HOST_INT_ENABLE)
+#else
+#define HI_CFG_DEF_VAL              \
+       (HI_CFG_UART_ENABLE |        \
+       HI_CFG_RST232_ENABLE |      \
+       HI_CFG_CLOCK_REQ_SELECT |   \
+       HI_CFG_HOST_INT_ENABLE)
+
+#endif
+
+#define REF_FREQ_19_2                       0
+#define REF_FREQ_26_0                       1
+#define REF_FREQ_38_4                       2
+#define REF_FREQ_40_0                       3
+#define REF_FREQ_33_6                       4
+#define REF_FREQ_NUM                        5
+
+#define LUT_PARAM_INTEGER_DIVIDER           0
+#define LUT_PARAM_FRACTIONAL_DIVIDER        1
+#define LUT_PARAM_ATTN_BB                   2
+#define LUT_PARAM_ALPHA_BB                  3
+#define LUT_PARAM_STOP_TIME_BB              4
+#define LUT_PARAM_BB_PLL_LOOP_FILTER        5
+#define LUT_PARAM_NUM                       6
+
+#define ACX_EEPROMLESS_IND_REG              (SCR_PAD4)
+#define USE_EEPROM                          0
+#define SOFT_RESET_MAX_TIME                 1000000
+#define SOFT_RESET_STALL_TIME               1000
+#define NVS_DATA_BUNDARY_ALIGNMENT          4
+
+
+/* Firmware image load chunk size */
+#define CHUNK_SIZE          512
+
+/* Firmware image header size */
+#define FW_HDR_SIZE 8
+
+#define ECPU_CONTROL_HALT                                      0x00000101
+
+
+/******************************************************************************
+
+    CHANNELS, BAND & REG DOMAINS definitions
+
+******************************************************************************/
+
+
+enum {
+       RADIO_BAND_2_4GHZ = 0,  /* 2.4 Ghz band */
+       RADIO_BAND_5GHZ = 1,    /* 5 Ghz band */
+       RADIO_BAND_JAPAN_4_9_GHZ = 2,
+       DEFAULT_BAND = RADIO_BAND_2_4GHZ,
+       INVALID_BAND = 0xFE,
+       MAX_RADIO_BANDS = 0xFF
+};
+
+enum {
+       NO_RATE      = 0,
+       RATE_1MBPS   = 0x0A,
+       RATE_2MBPS   = 0x14,
+       RATE_5_5MBPS = 0x37,
+       RATE_6MBPS   = 0x0B,
+       RATE_9MBPS   = 0x0F,
+       RATE_11MBPS  = 0x6E,
+       RATE_12MBPS  = 0x0A,
+       RATE_18MBPS  = 0x0E,
+       RATE_22MBPS  = 0xDC,
+       RATE_24MBPS  = 0x09,
+       RATE_36MBPS  = 0x0D,
+       RATE_48MBPS  = 0x08,
+       RATE_54MBPS  = 0x0C
+};
+
+enum {
+       RATE_INDEX_1MBPS   =  0,
+       RATE_INDEX_2MBPS   =  1,
+       RATE_INDEX_5_5MBPS =  2,
+       RATE_INDEX_6MBPS   =  3,
+       RATE_INDEX_9MBPS   =  4,
+       RATE_INDEX_11MBPS  =  5,
+       RATE_INDEX_12MBPS  =  6,
+       RATE_INDEX_18MBPS  =  7,
+       RATE_INDEX_22MBPS  =  8,
+       RATE_INDEX_24MBPS  =  9,
+       RATE_INDEX_36MBPS  =  10,
+       RATE_INDEX_48MBPS  =  11,
+       RATE_INDEX_54MBPS  =  12,
+       RATE_INDEX_MAX     =  RATE_INDEX_54MBPS,
+       MAX_RATE_INDEX,
+       INVALID_RATE_INDEX = MAX_RATE_INDEX,
+       RATE_INDEX_ENUM_MAX_SIZE = 0x7FFFFFFF
+};
+
+enum {
+       RATE_MASK_1MBPS = 0x1,
+       RATE_MASK_2MBPS = 0x2,
+       RATE_MASK_5_5MBPS = 0x4,
+       RATE_MASK_11MBPS = 0x20,
+};
+
+#define SHORT_PREAMBLE_BIT   BIT(0) /* CCK or Barker depending on the rate */
+#define OFDM_RATE_BIT        BIT(6)
+#define PBCC_RATE_BIT        BIT(7)
+
+enum {
+       CCK_LONG = 0,
+       CCK_SHORT = SHORT_PREAMBLE_BIT,
+       PBCC_LONG = PBCC_RATE_BIT,
+       PBCC_SHORT = PBCC_RATE_BIT | SHORT_PREAMBLE_BIT,
+       OFDM = OFDM_RATE_BIT
+};
+
+/******************************************************************************
+
+Transmit-Descriptor RATE-SET field definitions...
+
+Define a new "Rate-Set" for TX path that incorporates the
+Rate & Modulation info into a single 16-bit field.
+
+TxdRateSet_t:
+b15   - Indicates Preamble type (1=SHORT, 0=LONG).
+       Notes:
+       Must be LONG (0) for 1Mbps rate.
+       Does not apply (set to 0) for RevG-OFDM rates.
+b14   - Indicates PBCC encoding (1=PBCC, 0=not).
+       Notes:
+       Does not apply (set to 0) for rates 1 and 2 Mbps.
+       Does not apply (set to 0) for RevG-OFDM rates.
+b13    - Unused (set to 0).
+b12-b0 - Supported Rate indicator bits as defined below.
+
+******************************************************************************/
+
+
+#define TNETW1251_CHIP_ID_PG1_0         0x07010101
+#define TNETW1251_CHIP_ID_PG1_1         0x07020101
+#define TNETW1251_CHIP_ID_PG1_2                0x07030101
+
+/*************************************************************************
+
+    Interrupt Trigger Register (Host -> WiLink)
+
+**************************************************************************/
+
+/* Hardware to Embedded CPU Interrupts - first 32-bit register set */
+
+/*
+ * Host Command Interrupt. Setting this bit masks
+ * the interrupt that the host issues to inform
+ * the FW that it has sent a command
+ * to the Wlan hardware Command Mailbox.
+ */
+#define INTR_TRIG_CMD       BIT(0)
+
+/*
+ * Host Event Acknowlegde Interrupt. The host
+ * sets this bit to acknowledge that it received
+ * the unsolicited information from the event
+ * mailbox.
+ */
+#define INTR_TRIG_EVENT_ACK BIT(1)
+
+/*
+ * The host sets this bit to inform the Wlan
+ * FW that a TX packet is in the XFER
+ * Buffer #0.
+ */
+#define INTR_TRIG_TX_PROC0 BIT(2)
+
+/*
+ * The host sets this bit to inform the FW
+ * that it read a packet from RX XFER
+ * Buffer #0.
+ */
+#define INTR_TRIG_RX_PROC0 BIT(3)
+
+#define INTR_TRIG_DEBUG_ACK BIT(4)
+
+#define INTR_TRIG_STATE_CHANGED BIT(5)
+
+
+/* Hardware to Embedded CPU Interrupts - second 32-bit register set */
+
+/*
+ * The host sets this bit to inform the FW
+ * that it read a packet from RX XFER
+ * Buffer #1.
+ */
+#define INTR_TRIG_RX_PROC1 BIT(17)
+
+/*
+ * The host sets this bit to inform the Wlan
+ * hardware that a TX packet is in the XFER
+ * Buffer #1.
+ */
+#define INTR_TRIG_TX_PROC1 BIT(18)
+
+#endif
diff --git a/drivers/net/wireless/wl12xx/rx.c b/drivers/net/wireless/wl12xx/rx.c
new file mode 100644 (file)
index 0000000..981ea25
--- /dev/null
@@ -0,0 +1,208 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (c) 1998-2007 Texas Instruments Incorporated
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/skbuff.h>
+#include <net/mac80211.h>
+
+#include "wl12xx.h"
+#include "reg.h"
+#include "spi.h"
+#include "rx.h"
+
+static void wl12xx_rx_header(struct wl12xx *wl,
+                            struct wl12xx_rx_descriptor *desc)
+{
+       u32 rx_packet_ring_addr;
+
+       rx_packet_ring_addr = wl->data_path->rx_packet_ring_addr;
+       if (wl->rx_current_buffer)
+               rx_packet_ring_addr += wl->data_path->rx_packet_ring_chunk_size;
+
+       wl12xx_spi_mem_read(wl, rx_packet_ring_addr, desc,
+                           sizeof(struct wl12xx_rx_descriptor));
+}
+
+static void wl12xx_rx_status(struct wl12xx *wl,
+                            struct wl12xx_rx_descriptor *desc,
+                            struct ieee80211_rx_status *status,
+                            u8 beacon)
+{
+       memset(status, 0, sizeof(struct ieee80211_rx_status));
+
+       status->band = IEEE80211_BAND_2GHZ;
+       status->mactime = desc->timestamp;
+
+       /*
+        * The rx status timestamp is a 32 bits value while the TSF is a
+        * 64 bits one.
+        * For IBSS merging, TSF is mandatory, so we have to get it
+        * somehow, so we ask for ACX_TSF_INFO.
+        * That could be moved to the get_tsf() hook, but unfortunately,
+        * this one must be atomic, while our SPI routines can sleep.
+        */
+       if ((wl->bss_type == BSS_TYPE_IBSS) && beacon) {
+               u64 mactime;
+               int ret;
+               struct wl12xx_command cmd;
+               struct acx_tsf_info *tsf_info;
+
+               memset(&cmd, 0, sizeof(cmd));
+
+               ret = wl12xx_cmd_interrogate(wl, ACX_TSF_INFO,
+                                            sizeof(struct acx_tsf_info),
+                                            &cmd);
+               if (ret < 0) {
+                       wl12xx_warning("ACX_FW_REV interrogate failed");
+                       return;
+               }
+
+               tsf_info = (struct acx_tsf_info *)&(cmd.parameters);
+
+               mactime = tsf_info->current_tsf_lsb |
+                       (tsf_info->current_tsf_msb << 31);
+
+               status->mactime = mactime;
+       }
+
+       status->signal = desc->rssi;
+       status->qual = (desc->rssi - WL12XX_RX_MIN_RSSI) * 100 /
+               (WL12XX_RX_MAX_RSSI - WL12XX_RX_MIN_RSSI);
+       status->qual = min(status->qual, 100);
+       status->qual = max(status->qual, 0);
+
+       /*
+        * FIXME: guessing that snr needs to be divided by two, otherwise
+        * the values don't make any sense
+        */
+       status->noise = desc->rssi - desc->snr / 2;
+
+       status->freq = ieee80211_channel_to_frequency(desc->channel);
+
+       status->flag |= RX_FLAG_TSFT;
+
+       if (desc->flags & RX_DESC_ENCRYPTION_MASK) {
+               status->flag |= RX_FLAG_IV_STRIPPED | RX_FLAG_MMIC_STRIPPED;
+
+               if (likely(!(desc->flags & RX_DESC_DECRYPT_FAIL)))
+                       status->flag |= RX_FLAG_DECRYPTED;
+
+               if (unlikely(desc->flags & RX_DESC_MIC_FAIL))
+                       status->flag |= RX_FLAG_MMIC_ERROR;
+       }
+
+       if (unlikely(!(desc->flags & RX_DESC_VALID_FCS)))
+               status->flag |= RX_FLAG_FAILED_FCS_CRC;
+
+
+       /* FIXME: set status->rate_idx */
+}
+
+static void wl12xx_rx_body(struct wl12xx *wl,
+                          struct wl12xx_rx_descriptor *desc)
+{
+       struct sk_buff *skb;
+       struct ieee80211_rx_status status;
+       u8 *rx_buffer, beacon = 0;
+       u16 length, *fc;
+       u32 curr_id, last_id_inc, rx_packet_ring_addr;
+
+       length = WL12XX_RX_ALIGN(desc->length  - PLCP_HEADER_LENGTH);
+       curr_id = (desc->flags & RX_DESC_SEQNUM_MASK) >> RX_DESC_PACKETID_SHIFT;
+       last_id_inc = (wl->rx_last_id + 1) % (RX_MAX_PACKET_ID + 1);
+
+       if (last_id_inc != curr_id) {
+               wl12xx_warning("curr ID:%d, last ID inc:%d",
+                              curr_id, last_id_inc);
+               wl->rx_last_id = curr_id;
+       } else {
+               wl->rx_last_id = last_id_inc;
+       }
+
+       rx_packet_ring_addr = wl->data_path->rx_packet_ring_addr +
+               sizeof(struct wl12xx_rx_descriptor) + 20;
+       if (wl->rx_current_buffer)
+               rx_packet_ring_addr += wl->data_path->rx_packet_ring_chunk_size;
+
+       skb = dev_alloc_skb(length);
+       if (!skb) {
+               wl12xx_error("Couldn't allocate RX frame");
+               return;
+       }
+
+       rx_buffer = skb_put(skb, length);
+       wl12xx_spi_mem_read(wl, rx_packet_ring_addr, rx_buffer, length);
+
+       /* The actual lenght doesn't include the target's alignment */
+       skb->len = desc->length  - PLCP_HEADER_LENGTH;
+
+       fc = (u16 *)skb->data;
+
+       if ((*fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BEACON)
+               beacon = 1;
+
+       wl12xx_rx_status(wl, desc, &status, beacon);
+
+       wl12xx_debug(DEBUG_RX, "rx skb 0x%p: %d B %s", skb, skb->len,
+                    beacon ? "beacon" : "");
+
+       ieee80211_rx(wl->hw, skb, &status);
+}
+
+static void wl12xx_rx_ack(struct wl12xx *wl)
+{
+       u32 data, addr;
+
+       if (wl->rx_current_buffer) {
+               addr = ACX_REG_INTERRUPT_TRIG_H;
+               data = INTR_TRIG_RX_PROC1;
+       } else {
+               addr = ACX_REG_INTERRUPT_TRIG;
+               data = INTR_TRIG_RX_PROC0;
+       }
+
+       wl12xx_reg_write32(wl, addr, data);
+
+       /* Toggle buffer ring */
+       wl->rx_current_buffer = !wl->rx_current_buffer;
+}
+
+
+void wl12xx_rx(struct wl12xx *wl)
+{
+       struct wl12xx_rx_descriptor rx_desc;
+
+       if (wl->state != WL12XX_STATE_ON)
+               return;
+
+       /* We first read the frame's header */
+       wl12xx_rx_header(wl, &rx_desc);
+
+       /* Now we can read the body */
+       wl12xx_rx_body(wl, &rx_desc);
+
+       /* Finally, we need to ACK the RX */
+       wl12xx_rx_ack(wl);
+
+       return;
+}
diff --git a/drivers/net/wireless/wl12xx/rx.h b/drivers/net/wireless/wl12xx/rx.h
new file mode 100644 (file)
index 0000000..8a23fde
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (c) 1998-2007 Texas Instruments Incorporated
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __WL12XX_RX_H__
+#define __WL12XX_RX_H__
+
+#include <linux/bitops.h>
+
+/*
+ * RX PATH
+ *
+ * The Rx path uses a double buffer and an rx_contro structure, each located
+ * at a fixed address in the device memory. The host keeps track of which
+ * buffer is available and alternates between them on a per packet basis.
+ * The size of each of the two buffers is large enough to hold the longest
+ * 802.3 packet.
+ * The RX path goes like that:
+ * 1) The target generates an interrupt each time a new packet is received.
+ *   There are 2 RX interrupts, one for each buffer.
+ * 2) The host reads the received packet from one of the double buffers.
+ * 3) The host triggers a target interrupt.
+ * 4) The target prepares the next RX packet.
+ */
+
+#define WL12XX_RX_MAX_RSSI -30
+#define WL12XX_RX_MIN_RSSI -95
+
+#define WL12XX_RX_ALIGN_TO 4
+#define WL12XX_RX_ALIGN(len) (((len) + WL12XX_RX_ALIGN_TO - 1) & \
+                            ~(WL12XX_RX_ALIGN_TO - 1))
+
+#define SHORT_PREAMBLE_BIT   BIT(0)
+#define OFDM_RATE_BIT        BIT(6)
+#define PBCC_RATE_BIT        BIT(7)
+
+#define PLCP_HEADER_LENGTH 8
+#define RX_DESC_PACKETID_SHIFT 11
+#define RX_MAX_PACKET_ID 3
+
+#define RX_DESC_VALID_FCS         0x0001
+#define RX_DESC_MATCH_RXADDR1     0x0002
+#define RX_DESC_MCAST             0x0004
+#define RX_DESC_STAINTIM          0x0008
+#define RX_DESC_VIRTUAL_BM        0x0010
+#define RX_DESC_BCAST             0x0020
+#define RX_DESC_MATCH_SSID        0x0040
+#define RX_DESC_MATCH_BSSID       0x0080
+#define RX_DESC_ENCRYPTION_MASK   0x0300
+#define RX_DESC_MEASURMENT        0x0400
+#define RX_DESC_SEQNUM_MASK       0x1800
+#define        RX_DESC_MIC_FAIL          0x2000
+#define        RX_DESC_DECRYPT_FAIL      0x4000
+
+struct wl12xx_rx_descriptor {
+       u32 timestamp; /* In microseconds */
+       u16 length; /* Paylod length, including headers */
+       u16 flags;
+
+       /*
+        * 0 - 802.11
+        * 1 - 802.3
+        * 2 - IP
+        * 3 - Raw Codec
+        */
+       u8 type;
+
+       /*
+        * Recevied Rate:
+        * 0x0A - 1MBPS
+        * 0x14 - 2MBPS
+        * 0x37 - 5_5MBPS
+        * 0x0B - 6MBPS
+        * 0x0F - 9MBPS
+        * 0x6E - 11MBPS
+        * 0x0A - 12MBPS
+        * 0x0E - 18MBPS
+        * 0xDC - 22MBPS
+        * 0x09 - 24MBPS
+        * 0x0D - 36MBPS
+        * 0x08 - 48MBPS
+        * 0x0C - 54MBPS
+        */
+       u8 rate;
+
+       u8 mod_pre; /* Modulation and preamble */
+       u8 channel;
+
+       /*
+        * 0 - 2.4 Ghz
+        * 1 - 5 Ghz
+        */
+       u8 band;
+
+       s8 rssi; /* in dB */
+       u8 rcpi; /* in dB */
+       u8 snr; /* in dB */
+} __attribute__ ((packed));
+
+void wl12xx_rx(struct wl12xx *wl);
+
+#endif
diff --git a/drivers/net/wireless/wl12xx/spi.c b/drivers/net/wireless/wl12xx/spi.c
new file mode 100644 (file)
index 0000000..abdf171
--- /dev/null
@@ -0,0 +1,358 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/crc7.h>
+#include <linux/spi/spi.h>
+
+#include "wl12xx.h"
+#include "wl12xx_80211.h"
+#include "reg.h"
+#include "spi.h"
+#include "ps.h"
+
+static int wl12xx_translate_reg_addr(struct wl12xx *wl, int addr)
+{
+       /* If the address is lower than REGISTERS_BASE, it means that this is
+        * a chip-specific register address, so look it up in the registers
+        * table */
+       if (addr < REGISTERS_BASE) {
+               /* Make sure we don't go over the table */
+               if (addr >= ACX_REG_TABLE_LEN) {
+                       wl12xx_error("address out of range (%d)", addr);
+                       return -EINVAL;
+               }
+               addr = wl->chip.acx_reg_table[addr];
+       }
+
+       return addr - wl->physical_reg_addr + wl->virtual_reg_addr;
+}
+
+static int wl12xx_translate_mem_addr(struct wl12xx *wl, int addr)
+{
+       return addr - wl->physical_mem_addr + wl->virtual_mem_addr;
+}
+
+
+void wl12xx_spi_reset(struct wl12xx *wl)
+{
+       u8 *cmd;
+       struct spi_transfer t;
+       struct spi_message m;
+
+       cmd = kzalloc(WSPI_INIT_CMD_LEN, GFP_KERNEL);
+       if (!cmd) {
+               wl12xx_error("could not allocate cmd for spi reset");
+               return;
+       }
+
+       memset(&t, 0, sizeof(t));
+       spi_message_init(&m);
+
+       memset(cmd, 0xff, WSPI_INIT_CMD_LEN);
+
+       t.tx_buf = cmd;
+       t.len = WSPI_INIT_CMD_LEN;
+       spi_message_add_tail(&t, &m);
+
+       spi_sync(wl->spi, &m);
+
+       wl12xx_dump(DEBUG_SPI, "spi reset -> ", cmd, WSPI_INIT_CMD_LEN);
+}
+
+void wl12xx_spi_init(struct wl12xx *wl)
+{
+       u8 crc[WSPI_INIT_CMD_CRC_LEN], *cmd;
+       struct spi_transfer t;
+       struct spi_message m;
+
+       cmd = kzalloc(WSPI_INIT_CMD_LEN, GFP_KERNEL);
+       if (!cmd) {
+               wl12xx_error("could not allocate cmd for spi init");
+               return;
+       }
+
+       memset(crc, 0, sizeof(crc));
+       memset(&t, 0, sizeof(t));
+       spi_message_init(&m);
+
+       /*
+        * Set WSPI_INIT_COMMAND
+        * the data is being send from the MSB to LSB
+        */
+       cmd[2] = 0xff;
+       cmd[3] = 0xff;
+       cmd[1] = WSPI_INIT_CMD_START | WSPI_INIT_CMD_TX;
+       cmd[0] = 0;
+       cmd[7] = 0;
+       cmd[6] |= HW_ACCESS_WSPI_INIT_CMD_MASK << 3;
+       cmd[6] |= HW_ACCESS_WSPI_FIXED_BUSY_LEN & WSPI_INIT_CMD_FIXEDBUSY_LEN;
+
+       if (HW_ACCESS_WSPI_FIXED_BUSY_LEN == 0)
+               cmd[5] |=  WSPI_INIT_CMD_DIS_FIXEDBUSY;
+       else
+               cmd[5] |= WSPI_INIT_CMD_EN_FIXEDBUSY;
+
+       cmd[5] |= WSPI_INIT_CMD_IOD | WSPI_INIT_CMD_IP | WSPI_INIT_CMD_CS
+               | WSPI_INIT_CMD_WSPI | WSPI_INIT_CMD_WS;
+
+       crc[0] = cmd[1];
+       crc[1] = cmd[0];
+       crc[2] = cmd[7];
+       crc[3] = cmd[6];
+       crc[4] = cmd[5];
+
+       cmd[4] |= crc7(0, crc, WSPI_INIT_CMD_CRC_LEN) << 1;
+       cmd[4] |= WSPI_INIT_CMD_END;
+
+       t.tx_buf = cmd;
+       t.len = WSPI_INIT_CMD_LEN;
+       spi_message_add_tail(&t, &m);
+
+       spi_sync(wl->spi, &m);
+
+       wl12xx_dump(DEBUG_SPI, "spi init -> ", cmd, WSPI_INIT_CMD_LEN);
+}
+
+/* Set the SPI partitions to access the chip addresses
+ *
+ * There are two VIRTUAL (SPI) partitions (the memory partition and the
+ * registers partition), which are mapped to two different areas of the
+ * PHYSICAL (hardware) memory.  This function also makes other checks to
+ * ensure that the partitions are not overlapping.  In the diagram below, the
+ * memory partition comes before the register partition, but the opposite is
+ * also supported.
+ *
+ *                               PHYSICAL address
+ *                                     space
+ *
+ *                                    |    |
+ *                                 ...+----+--> mem_start
+ *          VIRTUAL address     ...   |    |
+ *               space       ...      |    | [PART_0]
+ *                        ...         |    |
+ * 0x00000000 <--+----+...         ...+----+--> mem_start + mem_size
+ *               |    |         ...   |    |
+ *               |MEM |      ...      |    |
+ *               |    |   ...         |    |
+ *  part_size <--+----+...            |    | {unused area)
+ *               |    |   ...         |    |
+ *               |REG |      ...      |    |
+ *  part_size    |    |         ...   |    |
+ *      +     <--+----+...         ...+----+--> reg_start
+ *  reg_size              ...         |    |
+ *                           ...      |    | [PART_1]
+ *                              ...   |    |
+ *                                 ...+----+--> reg_start + reg_size
+ *                                    |    |
+ *
+ */
+void wl12xx_set_partition(struct wl12xx *wl,
+                         u32 mem_start, u32 mem_size,
+                         u32 reg_start, u32 reg_size)
+{
+       u8 tx_buf[sizeof(u32) + 2 * sizeof(struct wl12xx_partition)];
+       struct wl12xx_partition *partition;
+       struct spi_transfer t;
+       struct spi_message m;
+       u32 *cmd;
+       size_t len;
+       int addr;
+
+       spi_message_init(&m);
+       memset(&t, 0, sizeof(t));
+       memset(tx_buf, 0, sizeof(tx_buf));
+
+       cmd = (u32 *) tx_buf;
+       partition = (struct wl12xx_partition *) (tx_buf + sizeof(u32));
+       addr = HW_ACCESS_PART0_SIZE_ADDR;
+       len = 2 * sizeof(struct wl12xx_partition);
+
+       *cmd |= WSPI_CMD_WRITE;
+       *cmd |= (len << WSPI_CMD_BYTE_LENGTH_OFFSET) & WSPI_CMD_BYTE_LENGTH;
+       *cmd |= addr & WSPI_CMD_BYTE_ADDR;
+
+       wl12xx_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
+                    mem_start, mem_size);
+       wl12xx_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
+                    reg_start, reg_size);
+
+       /* Make sure that the two partitions together don't exceed the
+        * address range */
+       if ((mem_size + reg_size) > HW_ACCESS_MEMORY_MAX_RANGE) {
+               wl12xx_debug(DEBUG_SPI, "Total size exceeds maximum virtual"
+                            " address range.  Truncating partition[0].");
+               mem_size = HW_ACCESS_MEMORY_MAX_RANGE - reg_size;
+               wl12xx_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
+                            mem_start, mem_size);
+               wl12xx_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
+                            reg_start, reg_size);
+       }
+
+       if ((mem_start < reg_start) &&
+           ((mem_start + mem_size) > reg_start)) {
+               /* Guarantee that the memory partition doesn't overlap the
+                * registers partition */
+               wl12xx_debug(DEBUG_SPI, "End of partition[0] is "
+                            "overlapping partition[1].  Adjusted.");
+               mem_size = reg_start - mem_start;
+               wl12xx_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
+                            mem_start, mem_size);
+               wl12xx_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
+                            reg_start, reg_size);
+       } else if ((reg_start < mem_start) &&
+                  ((reg_start + reg_size) > mem_start)) {
+               /* Guarantee that the register partition doesn't overlap the
+                * memory partition */
+               wl12xx_debug(DEBUG_SPI, "End of partition[1] is"
+                            " overlapping partition[0].  Adjusted.");
+               reg_size = mem_start - reg_start;
+               wl12xx_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",
+                            mem_start, mem_size);
+               wl12xx_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",
+                            reg_start, reg_size);
+       }
+
+       partition[0].start = mem_start;
+       partition[0].size  = mem_size;
+       partition[1].start = reg_start;
+       partition[1].size  = reg_size;
+
+       wl->physical_mem_addr = mem_start;
+       wl->physical_reg_addr = reg_start;
+
+       wl->virtual_mem_addr = 0;
+       wl->virtual_reg_addr = mem_size;
+
+       t.tx_buf = tx_buf;
+       t.len = sizeof(tx_buf);
+       spi_message_add_tail(&t, &m);
+
+       spi_sync(wl->spi, &m);
+}
+
+void wl12xx_spi_read(struct wl12xx *wl, int addr, void *buf,
+                    size_t len)
+{
+       struct spi_transfer t[3];
+       struct spi_message m;
+       char busy_buf[TNETWIF_READ_OFFSET_BYTES];
+       u32 cmd;
+
+       cmd = 0;
+       cmd |= WSPI_CMD_READ;
+       cmd |= (len << WSPI_CMD_BYTE_LENGTH_OFFSET) & WSPI_CMD_BYTE_LENGTH;
+       cmd |= addr & WSPI_CMD_BYTE_ADDR;
+
+       spi_message_init(&m);
+       memset(t, 0, sizeof(t));
+
+       t[0].tx_buf = &cmd;
+       t[0].len = 4;
+       spi_message_add_tail(&t[0], &m);
+
+       /* Busy and non busy words read */
+       t[1].rx_buf = busy_buf;
+       t[1].len = TNETWIF_READ_OFFSET_BYTES;
+       spi_message_add_tail(&t[1], &m);
+
+       t[2].rx_buf = buf;
+       t[2].len = len;
+       spi_message_add_tail(&t[2], &m);
+
+       spi_sync(wl->spi, &m);
+
+       /* FIXME: check busy words */
+
+       wl12xx_dump(DEBUG_SPI, "spi_read cmd -> ", &cmd, sizeof(cmd));
+       wl12xx_dump(DEBUG_SPI, "spi_read buf <- ", buf, len);
+}
+
+void wl12xx_spi_write(struct wl12xx *wl, int addr, void *buf,
+                     size_t len)
+{
+       struct spi_transfer t[2];
+       struct spi_message m;
+       u32 cmd;
+
+       cmd = 0;
+       cmd |= WSPI_CMD_WRITE;
+       cmd |= (len << WSPI_CMD_BYTE_LENGTH_OFFSET) & WSPI_CMD_BYTE_LENGTH;
+       cmd |= addr & WSPI_CMD_BYTE_ADDR;
+
+       spi_message_init(&m);
+       memset(t, 0, sizeof(t));
+
+       t[0].tx_buf = &cmd;
+       t[0].len = sizeof(cmd);
+       spi_message_add_tail(&t[0], &m);
+
+       t[1].tx_buf = buf;
+       t[1].len = len;
+       spi_message_add_tail(&t[1], &m);
+
+       spi_sync(wl->spi, &m);
+
+       wl12xx_dump(DEBUG_SPI, "spi_write cmd -> ", &cmd, sizeof(cmd));
+       wl12xx_dump(DEBUG_SPI, "spi_write buf -> ", buf, len);
+}
+
+void wl12xx_spi_mem_read(struct wl12xx *wl, int addr, void *buf,
+                        size_t len)
+{
+       int physical;
+
+       physical = wl12xx_translate_mem_addr(wl, addr);
+
+       wl12xx_spi_read(wl, physical, buf, len);
+}
+
+void wl12xx_spi_mem_write(struct wl12xx *wl, int addr, void *buf,
+                         size_t len)
+{
+       int physical;
+
+       physical = wl12xx_translate_mem_addr(wl, addr);
+
+       wl12xx_spi_write(wl, physical, buf, len);
+}
+
+u32 wl12xx_mem_read32(struct wl12xx *wl, int addr)
+{
+       return wl12xx_read32(wl, wl12xx_translate_mem_addr(wl, addr));
+}
+
+void wl12xx_mem_write32(struct wl12xx *wl, int addr, u32 val)
+{
+       wl12xx_write32(wl, wl12xx_translate_mem_addr(wl, addr), val);
+}
+
+u32 wl12xx_reg_read32(struct wl12xx *wl, int addr)
+{
+       return wl12xx_read32(wl, wl12xx_translate_reg_addr(wl, addr));
+}
+
+void wl12xx_reg_write32(struct wl12xx *wl, int addr, u32 val)
+{
+       wl12xx_write32(wl, wl12xx_translate_reg_addr(wl, addr), val);
+}
diff --git a/drivers/net/wireless/wl12xx/spi.h b/drivers/net/wireless/wl12xx/spi.h
new file mode 100644 (file)
index 0000000..fd3227e
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (c) 1998-2007 Texas Instruments Incorporated
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __WL12XX_SPI_H__
+#define __WL12XX_SPI_H__
+
+#include "cmd.h"
+#include "acx.h"
+#include "reg.h"
+
+#define HW_ACCESS_MEMORY_MAX_RANGE             0x1FFC0
+
+#define HW_ACCESS_PART0_SIZE_ADDR           0x1FFC0
+#define HW_ACCESS_PART0_START_ADDR          0x1FFC4
+#define HW_ACCESS_PART1_SIZE_ADDR           0x1FFC8
+#define HW_ACCESS_PART1_START_ADDR          0x1FFCC
+
+#define HW_ACCESS_REGISTER_SIZE             4
+
+#define HW_ACCESS_PRAM_MAX_RANGE               0x3c000
+
+#define WSPI_CMD_READ                 0x40000000
+#define WSPI_CMD_WRITE                0x00000000
+#define WSPI_CMD_FIXED                0x20000000
+#define WSPI_CMD_BYTE_LENGTH          0x1FFE0000
+#define WSPI_CMD_BYTE_LENGTH_OFFSET   17
+#define WSPI_CMD_BYTE_ADDR            0x0001FFFF
+
+#define WSPI_INIT_CMD_CRC_LEN       5
+
+#define WSPI_INIT_CMD_START         0x00
+#define WSPI_INIT_CMD_TX            0x40
+/* the extra bypass bit is sampled by the TNET as '1' */
+#define WSPI_INIT_CMD_BYPASS_BIT    0x80
+#define WSPI_INIT_CMD_FIXEDBUSY_LEN 0x07
+#define WSPI_INIT_CMD_EN_FIXEDBUSY  0x80
+#define WSPI_INIT_CMD_DIS_FIXEDBUSY 0x00
+#define WSPI_INIT_CMD_IOD           0x40
+#define WSPI_INIT_CMD_IP            0x20
+#define WSPI_INIT_CMD_CS            0x10
+#define WSPI_INIT_CMD_WS            0x08
+#define WSPI_INIT_CMD_WSPI          0x01
+#define WSPI_INIT_CMD_END           0x01
+
+#define WSPI_INIT_CMD_LEN           8
+
+#define TNETWIF_READ_OFFSET_BYTES  8
+#define HW_ACCESS_WSPI_FIXED_BUSY_LEN \
+               ((TNETWIF_READ_OFFSET_BYTES - 4) / sizeof(u32))
+#define HW_ACCESS_WSPI_INIT_CMD_MASK  0
+
+
+/* Raw target IO, address is not translated */
+void wl12xx_spi_read(struct wl12xx *wl, int addr, void *buf, size_t len);
+void wl12xx_spi_write(struct wl12xx *wl, int addr, void *buf, size_t len);
+
+/* Memory target IO, address is tranlated to partition 0 */
+void wl12xx_spi_mem_read(struct wl12xx *wl, int addr, void *buf, size_t len);
+void wl12xx_spi_mem_write(struct wl12xx *wl, int addr, void *buf, size_t len);
+u32 wl12xx_mem_read32(struct wl12xx *wl, int addr);
+void wl12xx_mem_write32(struct wl12xx *wl, int addr, u32 val);
+
+/* Registers IO */
+u32 wl12xx_reg_read32(struct wl12xx *wl, int addr);
+void wl12xx_reg_write32(struct wl12xx *wl, int addr, u32 val);
+
+/* INIT and RESET words */
+void wl12xx_spi_reset(struct wl12xx *wl);
+void wl12xx_spi_init(struct wl12xx *wl);
+void wl12xx_set_partition(struct wl12xx *wl,
+                         u32 part_start, u32 part_size,
+                         u32 reg_start,  u32 reg_size);
+
+static inline u32 wl12xx_read32(struct wl12xx *wl, int addr)
+{
+       u32 response;
+
+       wl12xx_spi_read(wl, addr, &response, sizeof(u32));
+
+       return response;
+}
+
+static inline void wl12xx_write32(struct wl12xx *wl, int addr, u32 val)
+{
+       wl12xx_spi_write(wl, addr, &val, sizeof(u32));
+}
+
+#endif /* __WL12XX_SPI_H__ */
diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c
new file mode 100644 (file)
index 0000000..62145e2
--- /dev/null
@@ -0,0 +1,557 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (c) 1998-2007 Texas Instruments Incorporated
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include "wl12xx.h"
+#include "reg.h"
+#include "spi.h"
+#include "tx.h"
+#include "ps.h"
+
+static bool wl12xx_tx_double_buffer_busy(struct wl12xx *wl, u32 data_out_count)
+{
+       int used, data_in_count;
+
+       data_in_count = wl->data_in_count;
+
+       if (data_in_count < data_out_count)
+               /* data_in_count has wrapped */
+               data_in_count += TX_STATUS_DATA_OUT_COUNT_MASK + 1;
+
+       used = data_in_count - data_out_count;
+
+       WARN_ON(used < 0);
+       WARN_ON(used > DP_TX_PACKET_RING_CHUNK_NUM);
+
+       if (used >= DP_TX_PACKET_RING_CHUNK_NUM)
+               return true;
+       else
+               return false;
+}
+
+static int wl12xx_tx_path_status(struct wl12xx *wl)
+{
+       u32 status, addr, data_out_count;
+       bool busy;
+
+       addr = wl->data_path->tx_control_addr;
+       status = wl12xx_mem_read32(wl, addr);
+       data_out_count = status & TX_STATUS_DATA_OUT_COUNT_MASK;
+       busy = wl12xx_tx_double_buffer_busy(wl, data_out_count);
+
+       if (busy)
+               return -EBUSY;
+
+       return 0;
+}
+
+static int wl12xx_tx_id(struct wl12xx *wl, struct sk_buff *skb)
+{
+       int i;
+
+       for (i = 0; i < FW_TX_CMPLT_BLOCK_SIZE; i++)
+               if (wl->tx_frames[i] == NULL) {
+                       wl->tx_frames[i] = skb;
+                       return i;
+               }
+
+       return -EBUSY;
+}
+
+static void wl12xx_tx_control(struct tx_double_buffer_desc *tx_hdr,
+                             struct ieee80211_tx_info *control, u16 fc)
+{
+       *(u16 *)&tx_hdr->control = 0;
+
+       tx_hdr->control.rate_policy = 0;
+
+       /* 802.11 packets */
+       tx_hdr->control.packet_type = 0;
+
+       if (control->flags & IEEE80211_TX_CTL_NO_ACK)
+               tx_hdr->control.ack_policy = 1;
+
+       tx_hdr->control.tx_complete = 1;
+
+       if ((fc & IEEE80211_FTYPE_DATA) &&
+           ((fc & IEEE80211_STYPE_QOS_DATA) ||
+            (fc & IEEE80211_STYPE_QOS_NULLFUNC)))
+               tx_hdr->control.qos = 1;
+}
+
+/* RSN + MIC = 8 + 8 = 16 bytes (worst case - AES). */
+#define MAX_MSDU_SECURITY_LENGTH      16
+#define MAX_MPDU_SECURITY_LENGTH      16
+#define WLAN_QOS_HDR_LEN              26
+#define MAX_MPDU_HEADER_AND_SECURITY  (MAX_MPDU_SECURITY_LENGTH + \
+                                      WLAN_QOS_HDR_LEN)
+#define HW_BLOCK_SIZE                 252
+static void wl12xx_tx_frag_block_num(struct tx_double_buffer_desc *tx_hdr)
+{
+       u16 payload_len, frag_threshold, mem_blocks;
+       u16 num_mpdus, mem_blocks_per_frag;
+
+       frag_threshold = IEEE80211_MAX_FRAG_THRESHOLD;
+       tx_hdr->frag_threshold = cpu_to_le16(frag_threshold);
+
+       payload_len = tx_hdr->length + MAX_MSDU_SECURITY_LENGTH;
+
+       if (payload_len > frag_threshold) {
+               mem_blocks_per_frag =
+                       ((frag_threshold + MAX_MPDU_HEADER_AND_SECURITY) /
+                        HW_BLOCK_SIZE) + 1;
+               num_mpdus = payload_len / frag_threshold;
+               mem_blocks = num_mpdus * mem_blocks_per_frag;
+               payload_len -= num_mpdus * frag_threshold;
+               num_mpdus++;
+
+       } else {
+               mem_blocks_per_frag = 0;
+               mem_blocks = 0;
+               num_mpdus = 1;
+       }
+
+       mem_blocks += (payload_len / HW_BLOCK_SIZE) + 1;
+
+       if (num_mpdus > 1)
+               mem_blocks += min(num_mpdus, mem_blocks_per_frag);
+
+       tx_hdr->num_mem_blocks = mem_blocks;
+}
+
+static int wl12xx_tx_fill_hdr(struct wl12xx *wl, struct sk_buff *skb,
+                             struct ieee80211_tx_info *control)
+{
+       struct tx_double_buffer_desc *tx_hdr;
+       struct ieee80211_rate *rate;
+       int id;
+       u16 fc;
+
+       if (!skb)
+               return -EINVAL;
+
+       id = wl12xx_tx_id(wl, skb);
+       if (id < 0)
+               return id;
+
+       fc = *(u16 *)skb->data;
+       tx_hdr = (struct tx_double_buffer_desc *) skb_push(skb,
+                                                          sizeof(*tx_hdr));
+
+       tx_hdr->length = cpu_to_le16(skb->len - sizeof(*tx_hdr));
+       rate = ieee80211_get_tx_rate(wl->hw, control);
+       tx_hdr->rate = cpu_to_le16(rate->hw_value);
+       tx_hdr->expiry_time = cpu_to_le32(1 << 16);
+       tx_hdr->id = id;
+
+       /* FIXME: how to get the correct queue id? */
+       tx_hdr->xmit_queue = 0;
+
+       wl12xx_tx_control(tx_hdr, control, fc);
+       wl12xx_tx_frag_block_num(tx_hdr);
+
+       return 0;
+}
+
+/* We copy the packet to the target */
+static int wl12xx_tx_send_packet(struct wl12xx *wl, struct sk_buff *skb,
+                                struct ieee80211_tx_info *control)
+{
+       struct tx_double_buffer_desc *tx_hdr;
+       int len;
+       u32 addr;
+
+       if (!skb)
+               return -EINVAL;
+
+       tx_hdr = (struct tx_double_buffer_desc *) skb->data;
+
+       if (control->control.hw_key &&
+           control->control.hw_key->alg == ALG_TKIP) {
+               int hdrlen;
+               u16 fc;
+               u8 *pos;
+
+               fc = *(u16 *)(skb->data + sizeof(*tx_hdr));
+               tx_hdr->length += WL12XX_TKIP_IV_SPACE;
+
+               hdrlen = ieee80211_hdrlen(fc);
+
+               pos = skb_push(skb, WL12XX_TKIP_IV_SPACE);
+               memmove(pos, pos + WL12XX_TKIP_IV_SPACE,
+                       sizeof(*tx_hdr) + hdrlen);
+       }
+
+       /* Revisit. This is a workaround for getting non-aligned packets.
+          This happens at least with EAPOL packets from the user space.
+          Our DMA requires packets to be aligned on a 4-byte boundary.
+       */
+       if (unlikely((long)skb->data & 0x03)) {
+               int offset = (4 - (long)skb->data) & 0x03;
+               wl12xx_debug(DEBUG_TX, "skb offset %d", offset);
+
+               /* check whether the current skb can be used */
+               if (!skb_cloned(skb) && (skb_tailroom(skb) >= offset)) {
+                       unsigned char *src = skb->data;
+
+                       /* align the buffer on a 4-byte boundary */
+                       skb_reserve(skb, offset);
+                       memmove(skb->data, src, skb->len);
+               } else {
+                       wl12xx_info("No handler, fixme!");
+                       return -EINVAL;
+               }
+       }
+
+       /* Our skb->data at this point includes the HW header */
+       len = WL12XX_TX_ALIGN(skb->len);
+
+       if (wl->data_in_count & 0x1)
+               addr = wl->data_path->tx_packet_ring_addr +
+                       wl->data_path->tx_packet_ring_chunk_size;
+       else
+               addr = wl->data_path->tx_packet_ring_addr;
+
+       wl12xx_spi_mem_write(wl, addr, skb->data, len);
+
+       wl12xx_debug(DEBUG_TX, "tx id %u skb 0x%p payload %u rate 0x%x",
+                    tx_hdr->id, skb, tx_hdr->length, tx_hdr->rate);
+
+       return 0;
+}
+
+static void wl12xx_tx_trigger(struct wl12xx *wl)
+{
+       u32 data, addr;
+
+       if (wl->data_in_count & 0x1) {
+               addr = ACX_REG_INTERRUPT_TRIG_H;
+               data = INTR_TRIG_TX_PROC1;
+       } else {
+               addr = ACX_REG_INTERRUPT_TRIG;
+               data = INTR_TRIG_TX_PROC0;
+       }
+
+       wl12xx_reg_write32(wl, addr, data);
+
+       /* Bumping data in */
+       wl->data_in_count = (wl->data_in_count + 1) &
+               TX_STATUS_DATA_OUT_COUNT_MASK;
+}
+
+/* caller must hold wl->mutex */
+static int wl12xx_tx_frame(struct wl12xx *wl, struct sk_buff *skb)
+{
+       struct ieee80211_tx_info *info;
+       int ret = 0;
+       u8 idx;
+
+       info = IEEE80211_SKB_CB(skb);
+
+       if (info->control.hw_key) {
+               idx = info->control.hw_key->hw_key_idx;
+               if (unlikely(wl->default_key != idx)) {
+                       ret = wl12xx_acx_default_key(wl, idx);
+                       if (ret < 0)
+                               return ret;
+               }
+       }
+
+       ret = wl12xx_tx_path_status(wl);
+       if (ret < 0)
+               return ret;
+
+       ret = wl12xx_tx_fill_hdr(wl, skb, info);
+       if (ret < 0)
+               return ret;
+
+       ret = wl12xx_tx_send_packet(wl, skb, info);
+       if (ret < 0)
+               return ret;
+
+       wl12xx_tx_trigger(wl);
+
+       return ret;
+}
+
+void wl12xx_tx_work(struct work_struct *work)
+{
+       struct wl12xx *wl = container_of(work, struct wl12xx, tx_work);
+       struct sk_buff *skb;
+       bool woken_up = false;
+       int ret;
+
+       mutex_lock(&wl->mutex);
+
+       if (unlikely(wl->state == WL12XX_STATE_OFF))
+               goto out;
+
+       while ((skb = skb_dequeue(&wl->tx_queue))) {
+               if (!woken_up) {
+                       wl12xx_ps_elp_wakeup(wl);
+                       woken_up = true;
+               }
+
+               ret = wl12xx_tx_frame(wl, skb);
+               if (ret == -EBUSY) {
+                       /* firmware buffer is full, stop queues */
+                       wl12xx_debug(DEBUG_TX, "tx_work: fw buffer full, "
+                                    "stop queues");
+                       ieee80211_stop_queues(wl->hw);
+                       wl->tx_queue_stopped = true;
+                       skb_queue_head(&wl->tx_queue, skb);
+                       goto out;
+               } else if (ret < 0) {
+                       dev_kfree_skb(skb);
+                       goto out;
+               }
+       }
+
+out:
+       if (woken_up)
+               wl12xx_ps_elp_sleep(wl);
+
+       mutex_unlock(&wl->mutex);
+}
+
+static const char *wl12xx_tx_parse_status(u8 status)
+{
+       /* 8 bit status field, one character per bit plus null */
+       static char buf[9];
+       int i = 0;
+
+       memset(buf, 0, sizeof(buf));
+
+       if (status & TX_DMA_ERROR)
+               buf[i++] = 'm';
+       if (status & TX_DISABLED)
+               buf[i++] = 'd';
+       if (status & TX_RETRY_EXCEEDED)
+               buf[i++] = 'r';
+       if (status & TX_TIMEOUT)
+               buf[i++] = 't';
+       if (status & TX_KEY_NOT_FOUND)
+               buf[i++] = 'k';
+       if (status & TX_ENCRYPT_FAIL)
+               buf[i++] = 'e';
+       if (status & TX_UNAVAILABLE_PRIORITY)
+               buf[i++] = 'p';
+
+       /* bit 0 is unused apparently */
+
+       return buf;
+}
+
+static void wl12xx_tx_packet_cb(struct wl12xx *wl,
+                               struct tx_result *result)
+{
+       struct ieee80211_tx_info *info;
+       struct sk_buff *skb;
+       int hdrlen, ret;
+       u8 *frame;
+
+       skb = wl->tx_frames[result->id];
+       if (skb == NULL) {
+               wl12xx_error("SKB for packet %d is NULL", result->id);
+               return;
+       }
+
+       info = IEEE80211_SKB_CB(skb);
+
+       if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) &&
+           (result->status == TX_SUCCESS))
+               info->flags |= IEEE80211_TX_STAT_ACK;
+
+       info->status.rates[0].count = result->ack_failures + 1;
+       wl->stats.retry_count += result->ack_failures;
+
+       /*
+        * We have to remove our private TX header before pushing
+        * the skb back to mac80211.
+        */
+       frame = skb_pull(skb, sizeof(struct tx_double_buffer_desc));
+       if (info->control.hw_key &&
+           info->control.hw_key->alg == ALG_TKIP) {
+               hdrlen = ieee80211_get_hdrlen_from_skb(skb);
+               memmove(frame + WL12XX_TKIP_IV_SPACE, frame, hdrlen);
+               skb_pull(skb, WL12XX_TKIP_IV_SPACE);
+       }
+
+       wl12xx_debug(DEBUG_TX, "tx status id %u skb 0x%p failures %u rate 0x%x"
+                    " status 0x%x (%s)",
+                    result->id, skb, result->ack_failures, result->rate,
+                    result->status, wl12xx_tx_parse_status(result->status));
+
+
+       ieee80211_tx_status(wl->hw, skb);
+
+       wl->tx_frames[result->id] = NULL;
+
+       if (wl->tx_queue_stopped) {
+               wl12xx_debug(DEBUG_TX, "cb: queue was stopped");
+
+               skb = skb_dequeue(&wl->tx_queue);
+
+               /* The skb can be NULL because tx_work might have been
+                  scheduled before the queue was stopped making the
+                  queue empty */
+
+               if (skb) {
+                       ret = wl12xx_tx_frame(wl, skb);
+                       if (ret == -EBUSY) {
+                               /* firmware buffer is still full */
+                               wl12xx_debug(DEBUG_TX, "cb: fw buffer "
+                                            "still full");
+                               skb_queue_head(&wl->tx_queue, skb);
+                               return;
+                       } else if (ret < 0) {
+                               dev_kfree_skb(skb);
+                               return;
+                       }
+               }
+
+               wl12xx_debug(DEBUG_TX, "cb: waking queues");
+               ieee80211_wake_queues(wl->hw);
+               wl->tx_queue_stopped = false;
+       }
+}
+
+/* Called upon reception of a TX complete interrupt */
+void wl12xx_tx_complete(struct wl12xx *wl)
+{
+       int i, result_index, num_complete = 0;
+       struct tx_result result[FW_TX_CMPLT_BLOCK_SIZE], *result_ptr;
+
+       if (unlikely(wl->state != WL12XX_STATE_ON))
+               return;
+
+       /* First we read the result */
+       wl12xx_spi_mem_read(wl, wl->data_path->tx_complete_addr,
+                           result, sizeof(result));
+
+       result_index = wl->next_tx_complete;
+
+       for (i = 0; i < ARRAY_SIZE(result); i++) {
+               result_ptr = &result[result_index];
+
+               if (result_ptr->done_1 == 1 &&
+                   result_ptr->done_2 == 1) {
+                       wl12xx_tx_packet_cb(wl, result_ptr);
+
+                       result_ptr->done_1 = 0;
+                       result_ptr->done_2 = 0;
+
+                       result_index = (result_index + 1) &
+                               (FW_TX_CMPLT_BLOCK_SIZE - 1);
+                       num_complete++;
+               } else {
+                       break;
+               }
+       }
+
+       /* Every completed frame needs to be acknowledged */
+       if (num_complete) {
+               /*
+                * If we've wrapped, we have to clear
+                * the results in 2 steps.
+                */
+               if (result_index > wl->next_tx_complete) {
+                       /* Only 1 write is needed */
+                       wl12xx_spi_mem_write(wl,
+                                            wl->data_path->tx_complete_addr +
+                                            (wl->next_tx_complete *
+                                             sizeof(struct tx_result)),
+                                            &result[wl->next_tx_complete],
+                                            num_complete *
+                                            sizeof(struct tx_result));
+
+
+               } else if (result_index < wl->next_tx_complete) {
+                       /* 2 writes are needed */
+                       wl12xx_spi_mem_write(wl,
+                                            wl->data_path->tx_complete_addr +
+                                            (wl->next_tx_complete *
+                                             sizeof(struct tx_result)),
+                                            &result[wl->next_tx_complete],
+                                            (FW_TX_CMPLT_BLOCK_SIZE -
+                                             wl->next_tx_complete) *
+                                            sizeof(struct tx_result));
+
+                       wl12xx_spi_mem_write(wl,
+                                            wl->data_path->tx_complete_addr,
+                                            result,
+                                            (num_complete -
+                                             FW_TX_CMPLT_BLOCK_SIZE +
+                                             wl->next_tx_complete) *
+                                            sizeof(struct tx_result));
+
+               } else {
+                       /* We have to write the whole array */
+                       wl12xx_spi_mem_write(wl,
+                                            wl->data_path->tx_complete_addr,
+                                            result,
+                                            FW_TX_CMPLT_BLOCK_SIZE *
+                                            sizeof(struct tx_result));
+               }
+
+       }
+
+       wl->next_tx_complete = result_index;
+}
+
+/* caller must hold wl->mutex */
+void wl12xx_tx_flush(struct wl12xx *wl)
+{
+       int i;
+       struct sk_buff *skb;
+       struct ieee80211_tx_info *info;
+
+       /* TX failure */
+/*     control->flags = 0; FIXME */
+
+       while ((skb = skb_dequeue(&wl->tx_queue))) {
+               info = IEEE80211_SKB_CB(skb);
+
+               wl12xx_debug(DEBUG_TX, "flushing skb 0x%p", skb);
+
+               if (!(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS))
+                               continue;
+
+               ieee80211_tx_status(wl->hw, skb);
+       }
+
+       for (i = 0; i < FW_TX_CMPLT_BLOCK_SIZE; i++)
+               if (wl->tx_frames[i] != NULL) {
+                       skb = wl->tx_frames[i];
+                       info = IEEE80211_SKB_CB(skb);
+
+                       if (!(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS))
+                               continue;
+
+                       ieee80211_tx_status(wl->hw, skb);
+                       wl->tx_frames[i] = NULL;
+               }
+}
diff --git a/drivers/net/wireless/wl12xx/tx.h b/drivers/net/wireless/wl12xx/tx.h
new file mode 100644 (file)
index 0000000..dc82691
--- /dev/null
@@ -0,0 +1,215 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (c) 1998-2007 Texas Instruments Incorporated
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __WL12XX_TX_H__
+#define __WL12XX_TX_H__
+
+#include <linux/bitops.h>
+
+/*
+ *
+ * TX PATH
+ *
+ * The Tx path uses a double buffer and a tx_control structure, each located
+ * at a fixed address in the device's memory. On startup, the host retrieves
+ * the pointers to these addresses. A double buffer allows for continuous data
+ * flow towards the device. The host keeps track of which buffer is available
+ * and alternates between these two buffers on a per packet basis.
+ *
+ * The size of each of the two buffers is large enough to hold the longest
+ * 802.3 packet - maximum size Ethernet packet + header + descriptor.
+ * TX complete indication will be received a-synchronously in a TX done cyclic
+ * buffer which is composed of 16 tx_result descriptors structures and is used
+ * in a cyclic manner.
+ *
+ * The TX (HOST) procedure is as follows:
+ * 1. Read the Tx path status, that will give the data_out_count.
+ * 2. goto 1, if not possible.
+ *    i.e. if data_in_count - data_out_count >= HwBuffer size (2 for double
+ *    buffer).
+ * 3. Copy the packet (preceded by double_buffer_desc), if possible.
+ *    i.e. if data_in_count - data_out_count < HwBuffer size (2 for double
+ *    buffer).
+ * 4. increment data_in_count.
+ * 5. Inform the firmware by generating a firmware internal interrupt.
+ * 6. FW will increment data_out_count after it reads the buffer.
+ *
+ * The TX Complete procedure:
+ * 1. To get a TX complete indication the host enables the tx_complete flag in
+ *    the TX descriptor Structure.
+ * 2. For each packet with a Tx Complete field set, the firmware adds the
+ *    transmit results to the cyclic buffer (txDoneRing) and sets both done_1
+ *    and done_2 to 1 to indicate driver ownership.
+ * 3. The firmware sends a Tx Complete interrupt to the host to trigger the
+ *    host to process the new data. Note: interrupt will be send per packet if
+ *    TX complete indication was requested in tx_control or per crossing
+ *    aggregation threshold.
+ * 4. After receiving the Tx Complete interrupt, the host reads the
+ *    TxDescriptorDone information in a cyclic manner and clears both done_1
+ *    and done_2 fields.
+ *
+ */
+
+#define TX_COMPLETE_REQUIRED_BIT       0x80
+#define TX_STATUS_DATA_OUT_COUNT_MASK   0xf
+#define WL12XX_TX_ALIGN_TO 4
+#define WL12XX_TX_ALIGN(len) (((len) + WL12XX_TX_ALIGN_TO - 1) & \
+                            ~(WL12XX_TX_ALIGN_TO - 1))
+#define WL12XX_TKIP_IV_SPACE 4
+
+struct tx_control {
+       /* Rate Policy (class) index */
+       unsigned rate_policy:3;
+
+       /* When set, no ack policy is expected */
+       unsigned ack_policy:1;
+
+       /*
+        * Packet type:
+        * 0 -> 802.11
+        * 1 -> 802.3
+        * 2 -> IP
+        * 3 -> raw codec
+        */
+       unsigned packet_type:2;
+
+       /* If set, this is a QoS-Null or QoS-Data frame */
+       unsigned qos:1;
+
+       /*
+        * If set, the target triggers the tx complete INT
+        * upon frame sending completion.
+        */
+       unsigned tx_complete:1;
+
+       /* 2 bytes padding before packet header */
+       unsigned xfer_pad:1;
+
+       unsigned reserved:7;
+} __attribute__ ((packed));
+
+
+struct tx_double_buffer_desc {
+       /* Length of payload, including headers. */
+       u16 length;
+
+       /*
+        * A bit mask that specifies the initial rate to be used
+        * Possible values are:
+        * 0x0001 - 1Mbits
+        * 0x0002 - 2Mbits
+        * 0x0004 - 5.5Mbits
+        * 0x0008 - 6Mbits
+        * 0x0010 - 9Mbits
+        * 0x0020 - 11Mbits
+        * 0x0040 - 12Mbits
+        * 0x0080 - 18Mbits
+        * 0x0100 - 22Mbits
+        * 0x0200 - 24Mbits
+        * 0x0400 - 36Mbits
+        * 0x0800 - 48Mbits
+        * 0x1000 - 54Mbits
+        */
+       u16 rate;
+
+       /* Time in us that a packet can spend in the target */
+       u32 expiry_time;
+
+       /* index of the TX queue used for this packet */
+       u8 xmit_queue;
+
+       /* Used to identify a packet */
+       u8 id;
+
+       struct tx_control control;
+
+       /*
+        * The FW should cut the packet into fragments
+        * of this size.
+        */
+       u16 frag_threshold;
+
+       /* Numbers of HW queue blocks to be allocated */
+       u8 num_mem_blocks;
+
+       u8 reserved;
+} __attribute__ ((packed));
+
+enum {
+       TX_SUCCESS              = 0,
+       TX_DMA_ERROR            = BIT(7),
+       TX_DISABLED             = BIT(6),
+       TX_RETRY_EXCEEDED       = BIT(5),
+       TX_TIMEOUT              = BIT(4),
+       TX_KEY_NOT_FOUND        = BIT(3),
+       TX_ENCRYPT_FAIL         = BIT(2),
+       TX_UNAVAILABLE_PRIORITY = BIT(1),
+};
+
+struct tx_result {
+       /*
+        * Ownership synchronization between the host and
+        * the firmware. If done_1 and done_2 are cleared,
+        * owned by the FW (no info ready).
+        */
+       u8 done_1;
+
+       /* same as double_buffer_desc->id */
+       u8 id;
+
+       /*
+        * Total air access duration consumed by this
+        * packet, including all retries and overheads.
+        */
+       u16 medium_usage;
+
+       /* Total media delay (from 1st EDCA AIFS counter until TX Complete). */
+       u32 medium_delay;
+
+       /* Time between host xfer and tx complete */
+       u32 fw_hnadling_time;
+
+       /* The LS-byte of the last TKIP sequence number. */
+       u8 lsb_seq_num;
+
+       /* Retry count */
+       u8 ack_failures;
+
+       /* At which rate we got a ACK */
+       u16 rate;
+
+       u16 reserved;
+
+       /* TX_* */
+       u8 status;
+
+       /* See done_1 */
+       u8 done_2;
+} __attribute__ ((packed));
+
+void wl12xx_tx_work(struct work_struct *work);
+void wl12xx_tx_complete(struct wl12xx *wl);
+void wl12xx_tx_flush(struct wl12xx *wl);
+
+#endif
diff --git a/drivers/net/wireless/wl12xx/wl1251.c b/drivers/net/wireless/wl12xx/wl1251.c
new file mode 100644 (file)
index 0000000..ce1561a
--- /dev/null
@@ -0,0 +1,709 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (C) 2008-2009 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include "wl1251.h"
+#include "reg.h"
+#include "spi.h"
+#include "boot.h"
+#include "event.h"
+#include "acx.h"
+#include "tx.h"
+#include "rx.h"
+#include "ps.h"
+#include "init.h"
+
+static struct wl12xx_partition_set wl1251_part_table[PART_TABLE_LEN] = {
+       [PART_DOWN] = {
+               .mem = {
+                       .start = 0x00000000,
+                       .size  = 0x00016800
+               },
+               .reg = {
+                       .start = REGISTERS_BASE,
+                       .size  = REGISTERS_DOWN_SIZE
+               },
+       },
+
+       [PART_WORK] = {
+               .mem = {
+                       .start = 0x00028000,
+                       .size  = 0x00014000
+               },
+               .reg = {
+                       .start = REGISTERS_BASE,
+                       .size  = REGISTERS_WORK_SIZE
+               },
+       },
+
+       /* WL1251 doesn't use the DRPW partition, so we don't set it here */
+};
+
+static enum wl12xx_acx_int_reg wl1251_acx_reg_table[ACX_REG_TABLE_LEN] = {
+       [ACX_REG_INTERRUPT_TRIG]     = (REGISTERS_BASE + 0x0474),
+       [ACX_REG_INTERRUPT_TRIG_H]   = (REGISTERS_BASE + 0x0478),
+       [ACX_REG_INTERRUPT_MASK]     = (REGISTERS_BASE + 0x0494),
+       [ACX_REG_HINT_MASK_SET]      = (REGISTERS_BASE + 0x0498),
+       [ACX_REG_HINT_MASK_CLR]      = (REGISTERS_BASE + 0x049C),
+       [ACX_REG_INTERRUPT_NO_CLEAR] = (REGISTERS_BASE + 0x04B0),
+       [ACX_REG_INTERRUPT_CLEAR]    = (REGISTERS_BASE + 0x04A4),
+       [ACX_REG_INTERRUPT_ACK]      = (REGISTERS_BASE + 0x04A8),
+       [ACX_REG_SLV_SOFT_RESET]     = (REGISTERS_BASE + 0x0000),
+       [ACX_REG_EE_START]           = (REGISTERS_BASE + 0x080C),
+       [ACX_REG_ECPU_CONTROL]       = (REGISTERS_BASE + 0x0804)
+};
+
+static int wl1251_upload_firmware(struct wl12xx *wl)
+{
+       struct wl12xx_partition_set *p_table = wl->chip.p_table;
+       int addr, chunk_num, partition_limit;
+       size_t fw_data_len;
+       u8 *p;
+
+       /* whal_FwCtrl_LoadFwImageSm() */
+
+       wl12xx_debug(DEBUG_BOOT, "chip id before fw upload: 0x%x",
+                    wl12xx_reg_read32(wl, CHIP_ID_B));
+
+       /* 10.0 check firmware length and set partition */
+       fw_data_len =  (wl->fw[4] << 24) | (wl->fw[5] << 16) |
+               (wl->fw[6] << 8) | (wl->fw[7]);
+
+       wl12xx_debug(DEBUG_BOOT, "fw_data_len %zu chunk_size %d", fw_data_len,
+               CHUNK_SIZE);
+
+       if ((fw_data_len % 4) != 0) {
+               wl12xx_error("firmware length not multiple of four");
+               return -EIO;
+       }
+
+       wl12xx_set_partition(wl,
+                            p_table[PART_DOWN].mem.start,
+                            p_table[PART_DOWN].mem.size,
+                            p_table[PART_DOWN].reg.start,
+                            p_table[PART_DOWN].reg.size);
+
+       /* 10.1 set partition limit and chunk num */
+       chunk_num = 0;
+       partition_limit = p_table[PART_DOWN].mem.size;
+
+       while (chunk_num < fw_data_len / CHUNK_SIZE) {
+               /* 10.2 update partition, if needed */
+               addr = p_table[PART_DOWN].mem.start +
+                       (chunk_num + 2) * CHUNK_SIZE;
+               if (addr > partition_limit) {
+                       addr = p_table[PART_DOWN].mem.start +
+                               chunk_num * CHUNK_SIZE;
+                       partition_limit = chunk_num * CHUNK_SIZE +
+                               p_table[PART_DOWN].mem.size;
+                       wl12xx_set_partition(wl,
+                                            addr,
+                                            p_table[PART_DOWN].mem.size,
+                                            p_table[PART_DOWN].reg.start,
+                                            p_table[PART_DOWN].reg.size);
+               }
+
+               /* 10.3 upload the chunk */
+               addr = p_table[PART_DOWN].mem.start + chunk_num * CHUNK_SIZE;
+               p = wl->fw + FW_HDR_SIZE + chunk_num * CHUNK_SIZE;
+               wl12xx_debug(DEBUG_BOOT, "uploading fw chunk 0x%p to 0x%x",
+                            p, addr);
+               wl12xx_spi_mem_write(wl, addr, p, CHUNK_SIZE);
+
+               chunk_num++;
+       }
+
+       /* 10.4 upload the last chunk */
+       addr = p_table[PART_DOWN].mem.start + chunk_num * CHUNK_SIZE;
+       p = wl->fw + FW_HDR_SIZE + chunk_num * CHUNK_SIZE;
+       wl12xx_debug(DEBUG_BOOT, "uploading fw last chunk (%zu B) 0x%p to 0x%x",
+                    fw_data_len % CHUNK_SIZE, p, addr);
+       wl12xx_spi_mem_write(wl, addr, p, fw_data_len % CHUNK_SIZE);
+
+       return 0;
+}
+
+static int wl1251_upload_nvs(struct wl12xx *wl)
+{
+       size_t nvs_len, nvs_bytes_written, burst_len;
+       int nvs_start, i;
+       u32 dest_addr, val;
+       u8 *nvs_ptr, *nvs;
+
+       nvs = wl->nvs;
+       if (nvs == NULL)
+               return -ENODEV;
+
+       nvs_ptr = nvs;
+
+       nvs_len = wl->nvs_len;
+       nvs_start = wl->fw_len;
+
+       /*
+        * Layout before the actual NVS tables:
+        * 1 byte : burst length.
+        * 2 bytes: destination address.
+        * n bytes: data to burst copy.
+        *
+        * This is ended by a 0 length, then the NVS tables.
+        */
+
+       while (nvs_ptr[0]) {
+               burst_len = nvs_ptr[0];
+               dest_addr = (nvs_ptr[1] & 0xfe) | ((u32)(nvs_ptr[2] << 8));
+
+               /* We move our pointer to the data */
+               nvs_ptr += 3;
+
+               for (i = 0; i < burst_len; i++) {
+                       val = (nvs_ptr[0] | (nvs_ptr[1] << 8)
+                              | (nvs_ptr[2] << 16) | (nvs_ptr[3] << 24));
+
+                       wl12xx_debug(DEBUG_BOOT,
+                                    "nvs burst write 0x%x: 0x%x",
+                                    dest_addr, val);
+                       wl12xx_mem_write32(wl, dest_addr, val);
+
+                       nvs_ptr += 4;
+                       dest_addr += 4;
+               }
+       }
+
+       /*
+        * We've reached the first zero length, the first NVS table
+        * is 7 bytes further.
+        */
+       nvs_ptr += 7;
+       nvs_len -= nvs_ptr - nvs;
+       nvs_len = ALIGN(nvs_len, 4);
+
+       /* Now we must set the partition correctly */
+       wl12xx_set_partition(wl, nvs_start,
+                            wl->chip.p_table[PART_DOWN].mem.size,
+                            wl->chip.p_table[PART_DOWN].reg.start,
+                            wl->chip.p_table[PART_DOWN].reg.size);
+
+       /* And finally we upload the NVS tables */
+       nvs_bytes_written = 0;
+       while (nvs_bytes_written < nvs_len) {
+               val = (nvs_ptr[0] | (nvs_ptr[1] << 8)
+                      | (nvs_ptr[2] << 16) | (nvs_ptr[3] << 24));
+
+               val = cpu_to_le32(val);
+
+               wl12xx_debug(DEBUG_BOOT,
+                            "nvs write table 0x%x: 0x%x",
+                            nvs_start, val);
+               wl12xx_mem_write32(wl, nvs_start, val);
+
+               nvs_ptr += 4;
+               nvs_bytes_written += 4;
+               nvs_start += 4;
+       }
+
+       return 0;
+}
+
+static int wl1251_boot(struct wl12xx *wl)
+{
+       int ret = 0, minor_minor_e2_ver;
+       u32 tmp, boot_data;
+
+       ret = wl12xx_boot_soft_reset(wl);
+       if (ret < 0)
+               goto out;
+
+       /* 2. start processing NVS file */
+       ret = wl->chip.op_upload_nvs(wl);
+       if (ret < 0)
+               goto out;
+
+       /* write firmware's last address (ie. it's length) to
+        * ACX_EEPROMLESS_IND_REG */
+       wl12xx_reg_write32(wl, ACX_EEPROMLESS_IND_REG, wl->fw_len);
+
+       /* 6. read the EEPROM parameters */
+       tmp = wl12xx_reg_read32(wl, SCR_PAD2);
+
+       /* 7. read bootdata */
+       wl->boot_attr.radio_type = (tmp & 0x0000FF00) >> 8;
+       wl->boot_attr.major = (tmp & 0x00FF0000) >> 16;
+       tmp = wl12xx_reg_read32(wl, SCR_PAD3);
+
+       /* 8. check bootdata and call restart sequence */
+       wl->boot_attr.minor = (tmp & 0x00FF0000) >> 16;
+       minor_minor_e2_ver = (tmp & 0xFF000000) >> 24;
+
+       wl12xx_debug(DEBUG_BOOT, "radioType 0x%x majorE2Ver 0x%x "
+                    "minorE2Ver 0x%x minor_minor_e2_ver 0x%x",
+                    wl->boot_attr.radio_type, wl->boot_attr.major,
+                    wl->boot_attr.minor, minor_minor_e2_ver);
+
+       ret = wl12xx_boot_init_seq(wl);
+       if (ret < 0)
+               goto out;
+
+       /* 9. NVS processing done */
+       boot_data = wl12xx_reg_read32(wl, ACX_REG_ECPU_CONTROL);
+
+       wl12xx_debug(DEBUG_BOOT, "halt boot_data 0x%x", boot_data);
+
+       /* 10. check that ECPU_CONTROL_HALT bits are set in
+        * pWhalBus->uBootData and start uploading firmware
+        */
+       if ((boot_data & ECPU_CONTROL_HALT) == 0) {
+               wl12xx_error("boot failed, ECPU_CONTROL_HALT not set");
+               ret = -EIO;
+               goto out;
+       }
+
+       ret = wl->chip.op_upload_fw(wl);
+       if (ret < 0)
+               goto out;
+
+       /* 10.5 start firmware */
+       ret = wl12xx_boot_run_firmware(wl);
+       if (ret < 0)
+               goto out;
+
+       /* Get and save the firmware version */
+       wl12xx_acx_fw_version(wl, wl->chip.fw_ver, sizeof(wl->chip.fw_ver));
+
+out:
+       return ret;
+}
+
+static int wl1251_mem_cfg(struct wl12xx *wl)
+{
+       struct wl1251_acx_config_memory mem_conf;
+       int ret, i;
+
+       wl12xx_debug(DEBUG_ACX, "wl1251 mem cfg");
+
+       /* memory config */
+       mem_conf.mem_config.num_stations = cpu_to_le16(DEFAULT_NUM_STATIONS);
+       mem_conf.mem_config.rx_mem_block_num = 35;
+       mem_conf.mem_config.tx_min_mem_block_num = 64;
+       mem_conf.mem_config.num_tx_queues = MAX_TX_QUEUES;
+       mem_conf.mem_config.host_if_options = HOSTIF_PKT_RING;
+       mem_conf.mem_config.num_ssid_profiles = 1;
+       mem_conf.mem_config.debug_buffer_size =
+               cpu_to_le16(TRACE_BUFFER_MAX_SIZE);
+
+       /* RX queue config */
+       mem_conf.rx_queue_config.dma_address = 0;
+       mem_conf.rx_queue_config.num_descs = ACX_RX_DESC_DEF;
+       mem_conf.rx_queue_config.priority = DEFAULT_RXQ_PRIORITY;
+       mem_conf.rx_queue_config.type = DEFAULT_RXQ_TYPE;
+
+       /* TX queue config */
+       for (i = 0; i < MAX_TX_QUEUES; i++) {
+               mem_conf.tx_queue_config[i].num_descs = ACX_TX_DESC_DEF;
+               mem_conf.tx_queue_config[i].attributes = i;
+       }
+
+       mem_conf.header.id = ACX_MEM_CFG;
+       mem_conf.header.len = sizeof(struct wl1251_acx_config_memory) -
+               sizeof(struct acx_header);
+       mem_conf.header.len -=
+               (MAX_TX_QUEUE_CONFIGS - mem_conf.mem_config.num_tx_queues) *
+               sizeof(struct wl1251_acx_tx_queue_config);
+
+       ret = wl12xx_cmd_configure(wl, &mem_conf,
+                                  sizeof(struct wl1251_acx_config_memory));
+       if (ret < 0)
+               wl12xx_warning("wl1251 mem config failed: %d", ret);
+
+       return ret;
+}
+
+static int wl1251_hw_init_mem_config(struct wl12xx *wl)
+{
+       int ret;
+
+       ret = wl1251_mem_cfg(wl);
+       if (ret < 0)
+               return ret;
+
+       wl->target_mem_map = kzalloc(sizeof(struct wl1251_acx_mem_map),
+                                         GFP_KERNEL);
+       if (!wl->target_mem_map) {
+               wl12xx_error("couldn't allocate target memory map");
+               return -ENOMEM;
+       }
+
+       /* we now ask for the firmware built memory map */
+       ret = wl12xx_acx_mem_map(wl, wl->target_mem_map,
+                                sizeof(struct wl1251_acx_mem_map));
+       if (ret < 0) {
+               wl12xx_error("couldn't retrieve firmware memory map");
+               kfree(wl->target_mem_map);
+               wl->target_mem_map = NULL;
+               return ret;
+       }
+
+       return 0;
+}
+
+static void wl1251_set_ecpu_ctrl(struct wl12xx *wl, u32 flag)
+{
+       u32 cpu_ctrl;
+
+       /* 10.5.0 run the firmware (I) */
+       cpu_ctrl = wl12xx_reg_read32(wl, ACX_REG_ECPU_CONTROL);
+
+       /* 10.5.1 run the firmware (II) */
+       cpu_ctrl &= ~flag;
+       wl12xx_reg_write32(wl, ACX_REG_ECPU_CONTROL, cpu_ctrl);
+}
+
+static void wl1251_target_enable_interrupts(struct wl12xx *wl)
+{
+       /* Enable target's interrupts */
+       wl->intr_mask = WL1251_ACX_INTR_RX0_DATA |
+               WL1251_ACX_INTR_RX1_DATA |
+               WL1251_ACX_INTR_TX_RESULT |
+               WL1251_ACX_INTR_EVENT_A |
+               WL1251_ACX_INTR_EVENT_B |
+               WL1251_ACX_INTR_INIT_COMPLETE;
+       wl12xx_boot_target_enable_interrupts(wl);
+}
+
+static void wl1251_irq_work(struct work_struct *work)
+{
+       u32 intr;
+       struct wl12xx *wl =
+               container_of(work, struct wl12xx, irq_work);
+
+       mutex_lock(&wl->mutex);
+
+       wl12xx_debug(DEBUG_IRQ, "IRQ work");
+
+       if (wl->state == WL12XX_STATE_OFF)
+               goto out;
+
+       wl12xx_ps_elp_wakeup(wl);
+
+       wl12xx_reg_write32(wl, ACX_REG_INTERRUPT_MASK, WL1251_ACX_INTR_ALL);
+
+       intr = wl12xx_reg_read32(wl, ACX_REG_INTERRUPT_CLEAR);
+       wl12xx_debug(DEBUG_IRQ, "intr: 0x%x", intr);
+
+       if (wl->data_path) {
+               wl12xx_spi_mem_read(wl, wl->data_path->rx_control_addr,
+                                   &wl->rx_counter, sizeof(u32));
+
+               /* We handle a frmware bug here */
+               switch ((wl->rx_counter - wl->rx_handled) & 0xf) {
+               case 0:
+                       wl12xx_debug(DEBUG_IRQ, "RX: FW and host in sync");
+                       intr &= ~WL1251_ACX_INTR_RX0_DATA;
+                       intr &= ~WL1251_ACX_INTR_RX1_DATA;
+                       break;
+               case 1:
+                       wl12xx_debug(DEBUG_IRQ, "RX: FW +1");
+                       intr |= WL1251_ACX_INTR_RX0_DATA;
+                       intr &= ~WL1251_ACX_INTR_RX1_DATA;
+                       break;
+               case 2:
+                       wl12xx_debug(DEBUG_IRQ, "RX: FW +2");
+                       intr |= WL1251_ACX_INTR_RX0_DATA;
+                       intr |= WL1251_ACX_INTR_RX1_DATA;
+                       break;
+               default:
+                       wl12xx_warning("RX: FW and host out of sync: %d",
+                                      wl->rx_counter - wl->rx_handled);
+                       break;
+               }
+
+               wl->rx_handled = wl->rx_counter;
+
+
+               wl12xx_debug(DEBUG_IRQ, "RX counter: %d", wl->rx_counter);
+       }
+
+       intr &= wl->intr_mask;
+
+       if (intr == 0) {
+               wl12xx_debug(DEBUG_IRQ, "INTR is 0");
+               wl12xx_reg_write32(wl, ACX_REG_INTERRUPT_MASK,
+                                  ~(wl->intr_mask));
+
+               goto out_sleep;
+       }
+
+       if (intr & WL1251_ACX_INTR_RX0_DATA) {
+               wl12xx_debug(DEBUG_IRQ, "WL1251_ACX_INTR_RX0_DATA");
+               wl12xx_rx(wl);
+       }
+
+       if (intr & WL1251_ACX_INTR_RX1_DATA) {
+               wl12xx_debug(DEBUG_IRQ, "WL1251_ACX_INTR_RX1_DATA");
+               wl12xx_rx(wl);
+       }
+
+       if (intr & WL1251_ACX_INTR_TX_RESULT) {
+               wl12xx_debug(DEBUG_IRQ, "WL1251_ACX_INTR_TX_RESULT");
+               wl12xx_tx_complete(wl);
+       }
+
+       if (intr & (WL1251_ACX_INTR_EVENT_A | WL1251_ACX_INTR_EVENT_B)) {
+               wl12xx_debug(DEBUG_IRQ, "WL1251_ACX_INTR_EVENT (0x%x)", intr);
+               if (intr & WL1251_ACX_INTR_EVENT_A)
+                       wl12xx_event_handle(wl, 0);
+               else
+                       wl12xx_event_handle(wl, 1);
+       }
+
+       if (intr & WL1251_ACX_INTR_INIT_COMPLETE)
+               wl12xx_debug(DEBUG_IRQ, "WL1251_ACX_INTR_INIT_COMPLETE");
+
+       wl12xx_reg_write32(wl, ACX_REG_INTERRUPT_MASK, ~(wl->intr_mask));
+
+out_sleep:
+       wl12xx_ps_elp_sleep(wl);
+out:
+       mutex_unlock(&wl->mutex);
+}
+
+static int wl1251_hw_init_txq_fill(u8 qid,
+                                  struct acx_tx_queue_qos_config *config,
+                                  u32 num_blocks)
+{
+       config->qid = qid;
+
+       switch (qid) {
+       case QOS_AC_BE:
+               config->high_threshold =
+                       (QOS_TX_HIGH_BE_DEF * num_blocks) / 100;
+               config->low_threshold =
+                       (QOS_TX_LOW_BE_DEF * num_blocks) / 100;
+               break;
+       case QOS_AC_BK:
+               config->high_threshold =
+                       (QOS_TX_HIGH_BK_DEF * num_blocks) / 100;
+               config->low_threshold =
+                       (QOS_TX_LOW_BK_DEF * num_blocks) / 100;
+               break;
+       case QOS_AC_VI:
+               config->high_threshold =
+                       (QOS_TX_HIGH_VI_DEF * num_blocks) / 100;
+               config->low_threshold =
+                       (QOS_TX_LOW_VI_DEF * num_blocks) / 100;
+               break;
+       case QOS_AC_VO:
+               config->high_threshold =
+                       (QOS_TX_HIGH_VO_DEF * num_blocks) / 100;
+               config->low_threshold =
+                       (QOS_TX_LOW_VO_DEF * num_blocks) / 100;
+               break;
+       default:
+               wl12xx_error("Invalid TX queue id: %d", qid);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int wl1251_hw_init_tx_queue_config(struct wl12xx *wl)
+{
+       struct acx_tx_queue_qos_config config;
+       struct wl1251_acx_mem_map *wl_mem_map = wl->target_mem_map;
+       int ret, i;
+
+       wl12xx_debug(DEBUG_ACX, "acx tx queue config");
+
+       config.header.id = ACX_TX_QUEUE_CFG;
+       config.header.len = sizeof(struct acx_tx_queue_qos_config) -
+               sizeof(struct acx_header);
+
+       for (i = 0; i < MAX_NUM_OF_AC; i++) {
+               ret = wl1251_hw_init_txq_fill(i, &config,
+                                             wl_mem_map->num_tx_mem_blocks);
+               if (ret < 0)
+                       return ret;
+
+               ret = wl12xx_cmd_configure(wl, &config, sizeof(config));
+               if (ret < 0)
+                       return ret;
+       }
+
+       return 0;
+}
+
+static int wl1251_hw_init_data_path_config(struct wl12xx *wl)
+{
+       int ret;
+
+       /* asking for the data path parameters */
+       wl->data_path = kzalloc(sizeof(struct acx_data_path_params_resp),
+                               GFP_KERNEL);
+       if (!wl->data_path) {
+               wl12xx_error("Couldnt allocate data path parameters");
+               return -ENOMEM;
+       }
+
+       ret = wl12xx_acx_data_path_params(wl, wl->data_path);
+       if (ret < 0) {
+               kfree(wl->data_path);
+               wl->data_path = NULL;
+               return ret;
+       }
+
+       return 0;
+}
+
+static int wl1251_hw_init(struct wl12xx *wl)
+{
+       struct wl1251_acx_mem_map *wl_mem_map;
+       int ret;
+
+       ret = wl12xx_hw_init_hwenc_config(wl);
+       if (ret < 0)
+               return ret;
+
+       /* Template settings */
+       ret = wl12xx_hw_init_templates_config(wl);
+       if (ret < 0)
+               return ret;
+
+       /* Default memory configuration */
+       ret = wl1251_hw_init_mem_config(wl);
+       if (ret < 0)
+               return ret;
+
+       /* Default data path configuration  */
+       ret = wl1251_hw_init_data_path_config(wl);
+       if (ret < 0)
+               goto out_free_memmap;
+
+       /* RX config */
+       ret = wl12xx_hw_init_rx_config(wl,
+                                      RX_CFG_PROMISCUOUS | RX_CFG_TSF,
+                                      RX_FILTER_OPTION_DEF);
+       /* RX_CONFIG_OPTION_ANY_DST_ANY_BSS,
+          RX_FILTER_OPTION_FILTER_ALL); */
+       if (ret < 0)
+               goto out_free_data_path;
+
+       /* TX queues config */
+       ret = wl1251_hw_init_tx_queue_config(wl);
+       if (ret < 0)
+               goto out_free_data_path;
+
+       /* PHY layer config */
+       ret = wl12xx_hw_init_phy_config(wl);
+       if (ret < 0)
+               goto out_free_data_path;
+
+       /* Beacon filtering */
+       ret = wl12xx_hw_init_beacon_filter(wl);
+       if (ret < 0)
+               goto out_free_data_path;
+
+       /* Bluetooth WLAN coexistence */
+       ret = wl12xx_hw_init_pta(wl);
+       if (ret < 0)
+               goto out_free_data_path;
+
+       /* Energy detection */
+       ret = wl12xx_hw_init_energy_detection(wl);
+       if (ret < 0)
+               goto out_free_data_path;
+
+       /* Beacons and boradcast settings */
+       ret = wl12xx_hw_init_beacon_broadcast(wl);
+       if (ret < 0)
+               goto out_free_data_path;
+
+       /* Enable data path */
+       ret = wl12xx_cmd_data_path(wl, wl->channel, 1);
+       if (ret < 0)
+               goto out_free_data_path;
+
+       /* Default power state */
+       ret = wl12xx_hw_init_power_auth(wl);
+       if (ret < 0)
+               goto out_free_data_path;
+
+       wl_mem_map = wl->target_mem_map;
+       wl12xx_info("%d tx blocks at 0x%x, %d rx blocks at 0x%x",
+                   wl_mem_map->num_tx_mem_blocks,
+                   wl->data_path->tx_control_addr,
+                   wl_mem_map->num_rx_mem_blocks,
+                   wl->data_path->rx_control_addr);
+
+       return 0;
+
+ out_free_data_path:
+       kfree(wl->data_path);
+
+ out_free_memmap:
+       kfree(wl->target_mem_map);
+
+       return ret;
+}
+
+static int wl1251_plt_init(struct wl12xx *wl)
+{
+       int ret;
+
+       ret = wl1251_hw_init_mem_config(wl);
+       if (ret < 0)
+               return ret;
+
+       ret = wl12xx_cmd_data_path(wl, wl->channel, 1);
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+
+void wl1251_setup(struct wl12xx *wl)
+{
+       /* FIXME: Is it better to use strncpy here or is this ok? */
+       wl->chip.fw_filename = WL1251_FW_NAME;
+       wl->chip.nvs_filename = WL1251_NVS_NAME;
+
+       /* Now we know what chip we're using, so adjust the power on sleep
+        * time accordingly */
+       wl->chip.power_on_sleep = WL1251_POWER_ON_SLEEP;
+
+       wl->chip.intr_cmd_complete = WL1251_ACX_INTR_CMD_COMPLETE;
+       wl->chip.intr_init_complete = WL1251_ACX_INTR_INIT_COMPLETE;
+
+       wl->chip.op_upload_nvs = wl1251_upload_nvs;
+       wl->chip.op_upload_fw = wl1251_upload_firmware;
+       wl->chip.op_boot = wl1251_boot;
+       wl->chip.op_set_ecpu_ctrl = wl1251_set_ecpu_ctrl;
+       wl->chip.op_target_enable_interrupts = wl1251_target_enable_interrupts;
+       wl->chip.op_hw_init = wl1251_hw_init;
+       wl->chip.op_plt_init = wl1251_plt_init;
+
+       wl->chip.p_table = wl1251_part_table;
+       wl->chip.acx_reg_table = wl1251_acx_reg_table;
+
+       INIT_WORK(&wl->irq_work, wl1251_irq_work);
+}
diff --git a/drivers/net/wireless/wl12xx/wl1251.h b/drivers/net/wireless/wl12xx/wl1251.h
new file mode 100644 (file)
index 0000000..1f4a443
--- /dev/null
@@ -0,0 +1,165 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __WL1251_H__
+#define __WL1251_H__
+
+#include <linux/bitops.h>
+
+#include "wl12xx.h"
+#include "acx.h"
+
+#define WL1251_FW_NAME "wl1251-fw.bin"
+#define WL1251_NVS_NAME "wl1251-nvs.bin"
+
+#define WL1251_POWER_ON_SLEEP 10 /* in miliseconds */
+
+void wl1251_setup(struct wl12xx *wl);
+
+
+struct wl1251_acx_memory {
+       __le16 num_stations; /* number of STAs to be supported. */
+       u16 reserved_1;
+
+       /*
+        * Nmber of memory buffers for the RX mem pool.
+        * The actual number may be less if there are
+        * not enough blocks left for the minimum num
+        * of TX ones.
+        */
+       u8 rx_mem_block_num;
+       u8 reserved_2;
+       u8 num_tx_queues; /* From 1 to 16 */
+       u8 host_if_options; /* HOST_IF* */
+       u8 tx_min_mem_block_num;
+       u8 num_ssid_profiles;
+       __le16 debug_buffer_size;
+} __attribute__ ((packed));
+
+
+#define ACX_RX_DESC_MIN                1
+#define ACX_RX_DESC_MAX                127
+#define ACX_RX_DESC_DEF                32
+struct wl1251_acx_rx_queue_config {
+       u8 num_descs;
+       u8 pad;
+       u8 type;
+       u8 priority;
+       __le32 dma_address;
+} __attribute__ ((packed));
+
+#define ACX_TX_DESC_MIN                1
+#define ACX_TX_DESC_MAX                127
+#define ACX_TX_DESC_DEF                16
+struct wl1251_acx_tx_queue_config {
+    u8 num_descs;
+    u8 pad[2];
+    u8 attributes;
+} __attribute__ ((packed));
+
+#define MAX_TX_QUEUE_CONFIGS 5
+#define MAX_TX_QUEUES 4
+struct wl1251_acx_config_memory {
+       struct acx_header header;
+
+       struct wl1251_acx_memory mem_config;
+       struct wl1251_acx_rx_queue_config rx_queue_config;
+       struct wl1251_acx_tx_queue_config tx_queue_config[MAX_TX_QUEUE_CONFIGS];
+} __attribute__ ((packed));
+
+struct wl1251_acx_mem_map {
+       struct acx_header header;
+
+       void *code_start;
+       void *code_end;
+
+       void *wep_defkey_start;
+       void *wep_defkey_end;
+
+       void *sta_table_start;
+       void *sta_table_end;
+
+       void *packet_template_start;
+       void *packet_template_end;
+
+       void *queue_memory_start;
+       void *queue_memory_end;
+
+       void *packet_memory_pool_start;
+       void *packet_memory_pool_end;
+
+       void *debug_buffer1_start;
+       void *debug_buffer1_end;
+
+       void *debug_buffer2_start;
+       void *debug_buffer2_end;
+
+       /* Number of blocks FW allocated for TX packets */
+       u32 num_tx_mem_blocks;
+
+       /* Number of blocks FW allocated for RX packets */
+       u32 num_rx_mem_blocks;
+} __attribute__ ((packed));
+
+/*************************************************************************
+
+    Host Interrupt Register (WiLink -> Host)
+
+**************************************************************************/
+
+/* RX packet is ready in Xfer buffer #0 */
+#define WL1251_ACX_INTR_RX0_DATA      BIT(0)
+
+/* TX result(s) are in the TX complete buffer */
+#define WL1251_ACX_INTR_TX_RESULT      BIT(1)
+
+/* OBSOLETE */
+#define WL1251_ACX_INTR_TX_XFR         BIT(2)
+
+/* RX packet is ready in Xfer buffer #1 */
+#define WL1251_ACX_INTR_RX1_DATA       BIT(3)
+
+/* Event was entered to Event MBOX #A */
+#define WL1251_ACX_INTR_EVENT_A                BIT(4)
+
+/* Event was entered to Event MBOX #B */
+#define WL1251_ACX_INTR_EVENT_B                BIT(5)
+
+/* OBSOLETE */
+#define WL1251_ACX_INTR_WAKE_ON_HOST   BIT(6)
+
+/* Trace meassge on MBOX #A */
+#define WL1251_ACX_INTR_TRACE_A                BIT(7)
+
+/* Trace meassge on MBOX #B */
+#define WL1251_ACX_INTR_TRACE_B                BIT(8)
+
+/* Command processing completion */
+#define WL1251_ACX_INTR_CMD_COMPLETE   BIT(9)
+
+/* Init sequence is done */
+#define WL1251_ACX_INTR_INIT_COMPLETE  BIT(14)
+
+#define WL1251_ACX_INTR_ALL           0xFFFFFFFF
+
+#endif
diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h
new file mode 100644 (file)
index 0000000..4864143
--- /dev/null
@@ -0,0 +1,409 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (c) 1998-2007 Texas Instruments Incorporated
+ * Copyright (C) 2008-2009 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __WL12XX_H__
+#define __WL12XX_H__
+
+#include <linux/mutex.h>
+#include <linux/list.h>
+#include <linux/bitops.h>
+#include <net/mac80211.h>
+
+#define DRIVER_NAME "wl12xx"
+#define DRIVER_PREFIX DRIVER_NAME ": "
+
+enum {
+       DEBUG_NONE      = 0,
+       DEBUG_IRQ       = BIT(0),
+       DEBUG_SPI       = BIT(1),
+       DEBUG_BOOT      = BIT(2),
+       DEBUG_MAILBOX   = BIT(3),
+       DEBUG_NETLINK   = BIT(4),
+       DEBUG_EVENT     = BIT(5),
+       DEBUG_TX        = BIT(6),
+       DEBUG_RX        = BIT(7),
+       DEBUG_SCAN      = BIT(8),
+       DEBUG_CRYPT     = BIT(9),
+       DEBUG_PSM       = BIT(10),
+       DEBUG_MAC80211  = BIT(11),
+       DEBUG_CMD       = BIT(12),
+       DEBUG_ACX       = BIT(13),
+       DEBUG_ALL       = ~0,
+};
+
+#define DEBUG_LEVEL (DEBUG_NONE)
+
+#define DEBUG_DUMP_LIMIT 1024
+
+#define wl12xx_error(fmt, arg...) \
+       printk(KERN_ERR DRIVER_PREFIX "ERROR " fmt "\n", ##arg)
+
+#define wl12xx_warning(fmt, arg...) \
+       printk(KERN_WARNING DRIVER_PREFIX "WARNING " fmt "\n", ##arg)
+
+#define wl12xx_notice(fmt, arg...) \
+       printk(KERN_INFO DRIVER_PREFIX fmt "\n", ##arg)
+
+#define wl12xx_info(fmt, arg...) \
+       printk(KERN_DEBUG DRIVER_PREFIX fmt "\n", ##arg)
+
+#define wl12xx_debug(level, fmt, arg...) \
+       do { \
+               if (level & DEBUG_LEVEL) \
+                       printk(KERN_DEBUG DRIVER_PREFIX fmt "\n", ##arg); \
+       } while (0)
+
+#define wl12xx_dump(level, prefix, buf, len)   \
+       do { \
+               if (level & DEBUG_LEVEL) \
+                       print_hex_dump(KERN_DEBUG, DRIVER_PREFIX prefix, \
+                                      DUMP_PREFIX_OFFSET, 16, 1,       \
+                                      buf,                             \
+                                      min_t(size_t, len, DEBUG_DUMP_LIMIT), \
+                                      0);                              \
+       } while (0)
+
+#define wl12xx_dump_ascii(level, prefix, buf, len)     \
+       do { \
+               if (level & DEBUG_LEVEL) \
+                       print_hex_dump(KERN_DEBUG, DRIVER_PREFIX prefix, \
+                                      DUMP_PREFIX_OFFSET, 16, 1,       \
+                                      buf,                             \
+                                      min_t(size_t, len, DEBUG_DUMP_LIMIT), \
+                                      true);                           \
+       } while (0)
+
+#define WL12XX_DEFAULT_RX_CONFIG (CFG_UNI_FILTER_EN |  \
+                                 CFG_BSSID_FILTER_EN)
+
+#define WL12XX_DEFAULT_RX_FILTER (CFG_RX_PRSP_EN |  \
+                                 CFG_RX_MGMT_EN |  \
+                                 CFG_RX_DATA_EN |  \
+                                 CFG_RX_CTL_EN |   \
+                                 CFG_RX_BCN_EN |   \
+                                 CFG_RX_AUTH_EN |  \
+                                 CFG_RX_ASSOC_EN)
+
+
+struct boot_attr {
+       u32 radio_type;
+       u8 mac_clock;
+       u8 arm_clock;
+       int firmware_debug;
+       u32 minor;
+       u32 major;
+       u32 bugfix;
+};
+
+enum wl12xx_state {
+       WL12XX_STATE_OFF,
+       WL12XX_STATE_ON,
+       WL12XX_STATE_PLT,
+};
+
+enum wl12xx_partition_type {
+       PART_DOWN,
+       PART_WORK,
+       PART_DRPW,
+
+       PART_TABLE_LEN
+};
+
+struct wl12xx_partition {
+       u32 size;
+       u32 start;
+};
+
+struct wl12xx_partition_set {
+       struct wl12xx_partition mem;
+       struct wl12xx_partition reg;
+};
+
+struct wl12xx;
+
+/* FIXME: I'm not sure about this structure name */
+struct wl12xx_chip {
+       u32 id;
+
+       const char *fw_filename;
+       const char *nvs_filename;
+
+       char fw_ver[21];
+
+       unsigned int power_on_sleep;
+       int intr_cmd_complete;
+       int intr_init_complete;
+
+       int (*op_upload_fw)(struct wl12xx *wl);
+       int (*op_upload_nvs)(struct wl12xx *wl);
+       int (*op_boot)(struct wl12xx *wl);
+       void (*op_set_ecpu_ctrl)(struct wl12xx *wl, u32 flag);
+       void (*op_target_enable_interrupts)(struct wl12xx *wl);
+       int (*op_hw_init)(struct wl12xx *wl);
+       int (*op_plt_init)(struct wl12xx *wl);
+
+       struct wl12xx_partition_set *p_table;
+       enum wl12xx_acx_int_reg *acx_reg_table;
+};
+
+struct wl12xx_stats {
+       struct acx_statistics *fw_stats;
+       unsigned long fw_stats_update;
+
+       unsigned int retry_count;
+       unsigned int excessive_retries;
+};
+
+struct wl12xx_debugfs {
+       struct dentry *rootdir;
+       struct dentry *fw_statistics;
+
+       struct dentry *tx_internal_desc_overflow;
+
+       struct dentry *rx_out_of_mem;
+       struct dentry *rx_hdr_overflow;
+       struct dentry *rx_hw_stuck;
+       struct dentry *rx_dropped;
+       struct dentry *rx_fcs_err;
+       struct dentry *rx_xfr_hint_trig;
+       struct dentry *rx_path_reset;
+       struct dentry *rx_reset_counter;
+
+       struct dentry *dma_rx_requested;
+       struct dentry *dma_rx_errors;
+       struct dentry *dma_tx_requested;
+       struct dentry *dma_tx_errors;
+
+       struct dentry *isr_cmd_cmplt;
+       struct dentry *isr_fiqs;
+       struct dentry *isr_rx_headers;
+       struct dentry *isr_rx_mem_overflow;
+       struct dentry *isr_rx_rdys;
+       struct dentry *isr_irqs;
+       struct dentry *isr_tx_procs;
+       struct dentry *isr_decrypt_done;
+       struct dentry *isr_dma0_done;
+       struct dentry *isr_dma1_done;
+       struct dentry *isr_tx_exch_complete;
+       struct dentry *isr_commands;
+       struct dentry *isr_rx_procs;
+       struct dentry *isr_hw_pm_mode_changes;
+       struct dentry *isr_host_acknowledges;
+       struct dentry *isr_pci_pm;
+       struct dentry *isr_wakeups;
+       struct dentry *isr_low_rssi;
+
+       struct dentry *wep_addr_key_count;
+       struct dentry *wep_default_key_count;
+       /* skipping wep.reserved */
+       struct dentry *wep_key_not_found;
+       struct dentry *wep_decrypt_fail;
+       struct dentry *wep_packets;
+       struct dentry *wep_interrupt;
+
+       struct dentry *pwr_ps_enter;
+       struct dentry *pwr_elp_enter;
+       struct dentry *pwr_missing_bcns;
+       struct dentry *pwr_wake_on_host;
+       struct dentry *pwr_wake_on_timer_exp;
+       struct dentry *pwr_tx_with_ps;
+       struct dentry *pwr_tx_without_ps;
+       struct dentry *pwr_rcvd_beacons;
+       struct dentry *pwr_power_save_off;
+       struct dentry *pwr_enable_ps;
+       struct dentry *pwr_disable_ps;
+       struct dentry *pwr_fix_tsf_ps;
+       /* skipping cont_miss_bcns_spread for now */
+       struct dentry *pwr_rcvd_awake_beacons;
+
+       struct dentry *mic_rx_pkts;
+       struct dentry *mic_calc_failure;
+
+       struct dentry *aes_encrypt_fail;
+       struct dentry *aes_decrypt_fail;
+       struct dentry *aes_encrypt_packets;
+       struct dentry *aes_decrypt_packets;
+       struct dentry *aes_encrypt_interrupt;
+       struct dentry *aes_decrypt_interrupt;
+
+       struct dentry *event_heart_beat;
+       struct dentry *event_calibration;
+       struct dentry *event_rx_mismatch;
+       struct dentry *event_rx_mem_empty;
+       struct dentry *event_rx_pool;
+       struct dentry *event_oom_late;
+       struct dentry *event_phy_transmit_error;
+       struct dentry *event_tx_stuck;
+
+       struct dentry *ps_pspoll_timeouts;
+       struct dentry *ps_upsd_timeouts;
+       struct dentry *ps_upsd_max_sptime;
+       struct dentry *ps_upsd_max_apturn;
+       struct dentry *ps_pspoll_max_apturn;
+       struct dentry *ps_pspoll_utilization;
+       struct dentry *ps_upsd_utilization;
+
+       struct dentry *rxpipe_rx_prep_beacon_drop;
+       struct dentry *rxpipe_descr_host_int_trig_rx_data;
+       struct dentry *rxpipe_beacon_buffer_thres_host_int_trig_rx_data;
+       struct dentry *rxpipe_missed_beacon_host_int_trig_rx_data;
+       struct dentry *rxpipe_tx_xfr_host_int_trig_rx_data;
+
+       struct dentry *tx_queue_len;
+
+       struct dentry *retry_count;
+       struct dentry *excessive_retries;
+};
+
+struct wl12xx {
+       struct ieee80211_hw *hw;
+       bool mac80211_registered;
+
+       struct spi_device *spi;
+
+       void (*set_power)(bool enable);
+       int irq;
+
+       enum wl12xx_state state;
+       struct mutex mutex;
+
+       int physical_mem_addr;
+       int physical_reg_addr;
+       int virtual_mem_addr;
+       int virtual_reg_addr;
+
+       struct wl12xx_chip chip;
+
+       int cmd_box_addr;
+       int event_box_addr;
+       struct boot_attr boot_attr;
+
+       u8 *fw;
+       size_t fw_len;
+       u8 *nvs;
+       size_t nvs_len;
+
+       u8 bssid[ETH_ALEN];
+       u8 mac_addr[ETH_ALEN];
+       u8 bss_type;
+       u8 listen_int;
+       int channel;
+
+       void *target_mem_map;
+       struct acx_data_path_params_resp *data_path;
+
+       /* Number of TX packets transferred to the FW, modulo 16 */
+       u32 data_in_count;
+
+       /* Frames scheduled for transmission, not handled yet */
+       struct sk_buff_head tx_queue;
+       bool tx_queue_stopped;
+
+       struct work_struct tx_work;
+       struct work_struct filter_work;
+
+       /* Pending TX frames */
+       struct sk_buff *tx_frames[16];
+
+       /*
+        * Index pointing to the next TX complete entry
+        * in the cyclic XT complete array we get from
+        * the FW.
+        */
+       u32 next_tx_complete;
+
+       /* FW Rx counter */
+       u32 rx_counter;
+
+       /* Rx frames handled */
+       u32 rx_handled;
+
+       /* Current double buffer */
+       u32 rx_current_buffer;
+       u32 rx_last_id;
+
+       /* The target interrupt mask */
+       u32 intr_mask;
+       struct work_struct irq_work;
+
+       /* The mbox event mask */
+       u32 event_mask;
+
+       /* Mailbox pointers */
+       u32 mbox_ptr[2];
+
+       /* Are we currently scanning */
+       bool scanning;
+
+       /* Our association ID */
+       u16 aid;
+
+       /* Default key (for WEP) */
+       u32 default_key;
+
+       unsigned int tx_mgmt_frm_rate;
+       unsigned int tx_mgmt_frm_mod;
+
+       unsigned int rx_config;
+       unsigned int rx_filter;
+
+       /* is firmware in elp mode */
+       bool elp;
+
+       /* we can be in psm, but not in elp, we have to differentiate */
+       bool psm;
+
+       /* PSM mode requested */
+       bool psm_requested;
+
+       /* in dBm */
+       int power_level;
+
+       struct wl12xx_stats stats;
+       struct wl12xx_debugfs debugfs;
+};
+
+int wl12xx_plt_start(struct wl12xx *wl);
+int wl12xx_plt_stop(struct wl12xx *wl);
+
+#define DEFAULT_HW_GEN_MODULATION_TYPE    CCK_LONG /* Long Preamble */
+#define DEFAULT_HW_GEN_TX_RATE          RATE_2MBPS
+#define JOIN_TIMEOUT 5000 /* 5000 milliseconds to join */
+
+#define WL12XX_DEFAULT_POWER_LEVEL 20
+
+#define WL12XX_TX_QUEUE_MAX_LENGTH 20
+
+/* Different chips need different sleep times after power on.  WL1271 needs
+ * 200ms, WL1251 needs only 10ms.  By default we use 200ms, but as soon as we
+ * know the chip ID, we change the sleep value in the wl12xx chip structure,
+ * so in subsequent power ons, we don't waste more time then needed.  */
+#define WL12XX_DEFAULT_POWER_ON_SLEEP 200
+
+#define CHIP_ID_1251_PG10                 (0x7010101)
+#define CHIP_ID_1251_PG11                 (0x7020101)
+#define CHIP_ID_1251_PG12                 (0x7030101)
+#define CHIP_ID_1271_PG10                 (0x4030101)
+
+#endif
diff --git a/drivers/net/wireless/wl12xx/wl12xx_80211.h b/drivers/net/wireless/wl12xx/wl12xx_80211.h
new file mode 100644 (file)
index 0000000..657c2db
--- /dev/null
@@ -0,0 +1,156 @@
+#ifndef __WL12XX_80211_H__
+#define __WL12XX_80211_H__
+
+#include <linux/if_ether.h>    /* ETH_ALEN */
+
+/* RATES */
+#define IEEE80211_CCK_RATE_1MB                 0x02
+#define IEEE80211_CCK_RATE_2MB                 0x04
+#define IEEE80211_CCK_RATE_5MB                 0x0B
+#define IEEE80211_CCK_RATE_11MB                        0x16
+#define IEEE80211_OFDM_RATE_6MB                        0x0C
+#define IEEE80211_OFDM_RATE_9MB                        0x12
+#define IEEE80211_OFDM_RATE_12MB               0x18
+#define IEEE80211_OFDM_RATE_18MB               0x24
+#define IEEE80211_OFDM_RATE_24MB               0x30
+#define IEEE80211_OFDM_RATE_36MB               0x48
+#define IEEE80211_OFDM_RATE_48MB               0x60
+#define IEEE80211_OFDM_RATE_54MB               0x6C
+#define IEEE80211_BASIC_RATE_MASK              0x80
+
+#define IEEE80211_CCK_RATE_1MB_MASK            (1<<0)
+#define IEEE80211_CCK_RATE_2MB_MASK            (1<<1)
+#define IEEE80211_CCK_RATE_5MB_MASK            (1<<2)
+#define IEEE80211_CCK_RATE_11MB_MASK           (1<<3)
+#define IEEE80211_OFDM_RATE_6MB_MASK           (1<<4)
+#define IEEE80211_OFDM_RATE_9MB_MASK           (1<<5)
+#define IEEE80211_OFDM_RATE_12MB_MASK          (1<<6)
+#define IEEE80211_OFDM_RATE_18MB_MASK          (1<<7)
+#define IEEE80211_OFDM_RATE_24MB_MASK          (1<<8)
+#define IEEE80211_OFDM_RATE_36MB_MASK          (1<<9)
+#define IEEE80211_OFDM_RATE_48MB_MASK          (1<<10)
+#define IEEE80211_OFDM_RATE_54MB_MASK          (1<<11)
+
+#define IEEE80211_CCK_RATES_MASK         0x0000000F
+#define IEEE80211_CCK_BASIC_RATES_MASK  (IEEE80211_CCK_RATE_1MB_MASK | \
+       IEEE80211_CCK_RATE_2MB_MASK)
+#define IEEE80211_CCK_DEFAULT_RATES_MASK (IEEE80211_CCK_BASIC_RATES_MASK | \
+       IEEE80211_CCK_RATE_5MB_MASK | \
+       IEEE80211_CCK_RATE_11MB_MASK)
+
+#define IEEE80211_OFDM_RATES_MASK        0x00000FF0
+#define IEEE80211_OFDM_BASIC_RATES_MASK          (IEEE80211_OFDM_RATE_6MB_MASK | \
+       IEEE80211_OFDM_RATE_12MB_MASK | \
+       IEEE80211_OFDM_RATE_24MB_MASK)
+#define IEEE80211_OFDM_DEFAULT_RATES_MASK (IEEE80211_OFDM_BASIC_RATES_MASK | \
+       IEEE80211_OFDM_RATE_9MB_MASK  | \
+       IEEE80211_OFDM_RATE_18MB_MASK | \
+       IEEE80211_OFDM_RATE_36MB_MASK | \
+       IEEE80211_OFDM_RATE_48MB_MASK | \
+       IEEE80211_OFDM_RATE_54MB_MASK)
+#define IEEE80211_DEFAULT_RATES_MASK (IEEE80211_OFDM_DEFAULT_RATES_MASK | \
+                                     IEEE80211_CCK_DEFAULT_RATES_MASK)
+
+
+/* This really should be 8, but not for our firmware */
+#define MAX_SUPPORTED_RATES 32
+#define COUNTRY_STRING_LEN 3
+#define MAX_COUNTRY_TRIPLETS 32
+
+/* Headers */
+struct ieee80211_header {
+       __le16 frame_ctl;
+       __le16 duration_id;
+       u8 da[ETH_ALEN];
+       u8 sa[ETH_ALEN];
+       u8 bssid[ETH_ALEN];
+       __le16 seq_ctl;
+       u8 payload[0];
+} __attribute__ ((packed));
+
+struct wl12xx_ie_header {
+       u8 id;
+       u8 len;
+} __attribute__ ((packed));
+
+/* IEs */
+
+struct wl12xx_ie_ssid {
+       struct wl12xx_ie_header header;
+       char ssid[IW_ESSID_MAX_SIZE];
+} __attribute__ ((packed));
+
+struct wl12xx_ie_rates {
+       struct wl12xx_ie_header header;
+       u8 rates[MAX_SUPPORTED_RATES];
+} __attribute__ ((packed));
+
+struct wl12xx_ie_ds_params {
+       struct wl12xx_ie_header header;
+       u8 channel;
+} __attribute__ ((packed));
+
+struct country_triplet {
+       u8 channel;
+       u8 num_channels;
+       u8 max_tx_power;
+} __attribute__ ((packed));
+
+struct wl12xx_ie_country {
+       struct wl12xx_ie_header header;
+       u8 country_string[COUNTRY_STRING_LEN];
+       struct country_triplet triplets[MAX_COUNTRY_TRIPLETS];
+} __attribute__ ((packed));
+
+
+/* Templates */
+
+struct wl12xx_beacon_template {
+       struct ieee80211_header header;
+       __le32 time_stamp[2];
+       __le16 beacon_interval;
+       __le16 capability;
+       struct wl12xx_ie_ssid ssid;
+       struct wl12xx_ie_rates rates;
+       struct wl12xx_ie_rates ext_rates;
+       struct wl12xx_ie_ds_params ds_params;
+       struct wl12xx_ie_country country;
+} __attribute__ ((packed));
+
+struct wl12xx_null_data_template {
+       struct ieee80211_header header;
+} __attribute__ ((packed));
+
+struct wl12xx_ps_poll_template {
+       u16 fc;
+       u16 aid;
+       u8 bssid[ETH_ALEN];
+       u8 ta[ETH_ALEN];
+} __attribute__ ((packed));
+
+struct wl12xx_qos_null_data_template {
+       struct ieee80211_header header;
+       __le16 qos_ctl;
+} __attribute__ ((packed));
+
+struct wl12xx_probe_req_template {
+       struct ieee80211_header header;
+       struct wl12xx_ie_ssid ssid;
+       struct wl12xx_ie_rates rates;
+       struct wl12xx_ie_rates ext_rates;
+} __attribute__ ((packed));
+
+
+struct wl12xx_probe_resp_template {
+       struct ieee80211_header header;
+       __le32 time_stamp[2];
+       __le16 beacon_interval;
+       __le16 capability;
+       struct wl12xx_ie_ssid ssid;
+       struct wl12xx_ie_rates rates;
+       struct wl12xx_ie_rates ext_rates;
+       struct wl12xx_ie_ds_params ds_params;
+       struct wl12xx_ie_country country;
+} __attribute__ ((packed));
+
+#endif
index 1f64d6033ab534509052854ea48845f202b52f06..e3e96bb2c246bed6905bf9a0d48835668a6fdab8 100644 (file)
@@ -1348,6 +1348,7 @@ static int wl3501_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
        if (rc) {
                ++dev->stats.tx_dropped;
                netif_stop_queue(dev);
+               rc = NETDEV_TX_OK;
        } else {
                ++dev->stats.tx_packets;
                dev->stats.tx_bytes += skb->len;
index 5fabd9c0f07a791483b01728e599b14a4a38ad3b..4430b8d92e21756dd29decca6db8df06a5b33403 100644 (file)
@@ -819,11 +819,11 @@ static int zd1201_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
        if (err) {
                dev->stats.tx_errors++;
                netif_start_queue(dev);
-               return err;
+       } else {
+               dev->stats.tx_packets++;
+               dev->stats.tx_bytes += skb->len;
+               dev->trans_start = jiffies;
        }
-       dev->stats.tx_packets++;
-       dev->stats.tx_bytes += skb->len;
-       dev->trans_start = jiffies;
        kfree_skb(skb);
 
        return 0;
index c3a51266de209c7ad6c47e559f54612ee5dc6d2e..40b07b988224a4eee002a91c970fe1b5500f8ce2 100644 (file)
@@ -420,9 +420,9 @@ static void cs_set_control(struct zd_mac *mac, struct zd_ctrlset *cs,
        if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
                cs->control |= ZD_CS_NEED_RANDOM_BACKOFF;
 
-       /* Multicast */
-       if (is_multicast_ether_addr(header->addr1))
-               cs->control |= ZD_CS_MULTICAST;
+       /* No ACK expected (multicast, etc.) */
+       if (info->flags & IEEE80211_TX_CTL_NO_ACK)
+               cs->control |= ZD_CS_NO_ACK;
 
        /* PS-POLL */
        if (ieee80211_is_pspoll(header->frame_control))
@@ -755,52 +755,6 @@ static int zd_op_config(struct ieee80211_hw *hw, u32 changed)
        return zd_chip_set_channel(&mac->chip, conf->channel->hw_value);
 }
 
-static int zd_op_config_interface(struct ieee80211_hw *hw,
-                                 struct ieee80211_vif *vif,
-                                  struct ieee80211_if_conf *conf)
-{
-       struct zd_mac *mac = zd_hw_mac(hw);
-       int associated;
-       int r;
-
-       if (mac->type == NL80211_IFTYPE_MESH_POINT ||
-           mac->type == NL80211_IFTYPE_ADHOC) {
-               associated = true;
-               if (conf->changed & IEEE80211_IFCC_BEACON) {
-                       struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
-
-                       if (!beacon)
-                               return -ENOMEM;
-                       r = zd_mac_config_beacon(hw, beacon);
-                       kfree_skb(beacon);
-
-                       if (r < 0)
-                               return r;
-               }
-
-               if (conf->changed & IEEE80211_IFCC_BEACON_ENABLED) {
-                       u32 interval;
-
-                       if (conf->enable_beacon)
-                               interval = BCN_MODE_IBSS | hw->conf.beacon_int;
-                       else
-                               interval = 0;
-
-                       r = zd_set_beacon_interval(&mac->chip, interval);
-                       if (r < 0)
-                               return r;
-               }
-       } else
-               associated = is_valid_ether_addr(conf->bssid);
-
-       spin_lock_irq(&mac->lock);
-       mac->associated = associated;
-       spin_unlock_irq(&mac->lock);
-
-       /* TODO: do hardware bssid filtering */
-       return 0;
-}
-
 static void zd_process_intr(struct work_struct *work)
 {
        u16 int_status;
@@ -923,9 +877,42 @@ static void zd_op_bss_info_changed(struct ieee80211_hw *hw,
 {
        struct zd_mac *mac = zd_hw_mac(hw);
        unsigned long flags;
+       int associated;
 
        dev_dbg_f(zd_mac_dev(mac), "changes: %x\n", changes);
 
+       if (mac->type == NL80211_IFTYPE_MESH_POINT ||
+           mac->type == NL80211_IFTYPE_ADHOC) {
+               associated = true;
+               if (changes & BSS_CHANGED_BEACON) {
+                       struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);
+
+                       if (beacon) {
+                               zd_mac_config_beacon(hw, beacon);
+                               kfree_skb(beacon);
+                       }
+               }
+
+               if (changes & BSS_CHANGED_BEACON_ENABLED) {
+                       u32 interval;
+
+                       if (bss_conf->enable_beacon)
+                               interval = BCN_MODE_IBSS |
+                                               bss_conf->beacon_int;
+                       else
+                               interval = 0;
+
+                       zd_set_beacon_interval(&mac->chip, interval);
+               }
+       } else
+               associated = is_valid_ether_addr(bss_conf->bssid);
+
+       spin_lock_irq(&mac->lock);
+       mac->associated = associated;
+       spin_unlock_irq(&mac->lock);
+
+       /* TODO: do hardware bssid filtering */
+
        if (changes & BSS_CHANGED_ERP_PREAMBLE) {
                spin_lock_irqsave(&mac->lock, flags);
                mac->short_preamble = bss_conf->use_short_preamble;
@@ -952,7 +939,6 @@ static const struct ieee80211_ops zd_ops = {
        .add_interface          = zd_op_add_interface,
        .remove_interface       = zd_op_remove_interface,
        .config                 = zd_op_config,
-       .config_interface       = zd_op_config_interface,
        .configure_filter       = zd_op_configure_filter,
        .bss_info_changed       = zd_op_bss_info_changed,
        .get_tsf                = zd_op_get_tsf,
index 4c05d3ee4c37a1c84bcc88098edf0c077eef41d8..7c2759118d13377afd5431b4f770567a3c24553a 100644 (file)
@@ -87,7 +87,7 @@ struct zd_ctrlset {
 
 /* zd_ctrlset control field */
 #define ZD_CS_NEED_RANDOM_BACKOFF      0x01
-#define ZD_CS_MULTICAST                        0x02
+#define ZD_CS_NO_ACK                   0x02
 
 #define ZD_CS_FRAME_TYPE_MASK          0x0c
 #define ZD_CS_DATA_FRAME               0x00
index 7477ffdcddb45923e0b74cda2fbd8a876c84c94d..3c7a5053f1da7ec054c81b9169ceb8109b7a19a1 100644 (file)
@@ -717,7 +717,7 @@ static void yellowfin_tx_timeout(struct net_device *dev)
        if (yp->cur_tx - yp->dirty_tx < TX_QUEUE_SIZE)
                netif_wake_queue (dev);         /* Typical path */
 
-       dev->trans_start = jiffies;
+       dev->trans_start = jiffies; /* prevent tx timeout */
        dev->stats.tx_errors++;
 }
 
@@ -876,7 +876,6 @@ static int yellowfin_start_xmit(struct sk_buff *skb, struct net_device *dev)
                netif_start_queue (dev);                /* Typical path */
        else
                yp->tx_full = 1;
-       dev->trans_start = jiffies;
 
        if (yellowfin_debug > 4) {
                printk(KERN_DEBUG "%s: Yellowfin transmit frame #%d queued in slot %d.\n",
index 27f3b81333dec00bf0c5c212b2f0162261a40564..d2fa27c5c1b28e444748214e363bb3c462a43f0e 100644 (file)
@@ -19,3 +19,9 @@ config OF_SPI
        depends on OF && (PPC_OF || MICROBLAZE) && SPI
        help
          OpenFirmware SPI accessors
+
+config OF_MDIO
+       def_tristate PHYLIB
+       depends on OF && PHYLIB
+       help
+         OpenFirmware MDIO bus (Ethernet PHY) accessors
index 4c3c6f8e36f51577281f881f6edf464834847111..bdfb5f5d4b06d46d6e05ff2e219cf712328945ef 100644 (file)
@@ -3,3 +3,4 @@ obj-$(CONFIG_OF_DEVICE) += device.o platform.o
 obj-$(CONFIG_OF_GPIO)   += gpio.o
 obj-$(CONFIG_OF_I2C)   += of_i2c.o
 obj-$(CONFIG_OF_SPI)   += of_spi.o
+obj-$(CONFIG_OF_MDIO)  += of_mdio.o
index 41c5dfd853586704d0ac75fee8b23068466fa9d8..69f85c07d17fc24718861b41618c6a8c0c493183 100644 (file)
@@ -447,6 +447,7 @@ struct of_modalias_table {
 static struct of_modalias_table of_modalias_table[] = {
        { "fsl,mcu-mpc8349emitx", "mcu-mpc8349emitx" },
        { "mmc-spi-slot", "mmc_spi" },
+       { "stm,m25p40", "m25p80" },
 };
 
 /**
@@ -494,6 +495,30 @@ int of_modalias_node(struct device_node *node, char *modalias, int len)
 }
 EXPORT_SYMBOL_GPL(of_modalias_node);
 
+/**
+ * of_parse_phandle - Resolve a phandle property to a device_node pointer
+ * @np: Pointer to device node holding phandle property
+ * @phandle_name: Name of property holding a phandle value
+ * @index: For properties holding a table of phandles, this is the index into
+ *         the table
+ *
+ * Returns the device_node pointer with refcount incremented.  Use
+ * of_node_put() on it when done.
+ */
+struct device_node *
+of_parse_phandle(struct device_node *np, const char *phandle_name, int index)
+{
+       const phandle *phandle;
+       int size;
+
+       phandle = of_get_property(np, phandle_name, &size);
+       if ((!phandle) || (size < sizeof(*phandle) * (index + 1)))
+               return NULL;
+
+       return of_find_node_by_phandle(phandle[index]);
+}
+EXPORT_SYMBOL(of_parse_phandle);
+
 /**
  * of_parse_phandles_with_args - Find a node pointed by phandle in a list
  * @np:                pointer to a device tree node containing a list
diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c
new file mode 100644 (file)
index 0000000..aee967d
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+ * OF helpers for the MDIO (Ethernet PHY) API
+ *
+ * Copyright (c) 2009 Secret Lab Technologies, Ltd.
+ *
+ * This file is released under the GPLv2
+ *
+ * This file provides helper functions for extracting PHY device information
+ * out of the OpenFirmware device tree and using it to populate an mii_bus.
+ */
+
+#include <linux/phy.h>
+#include <linux/of.h>
+#include <linux/of_mdio.h>
+#include <linux/module.h>
+
+MODULE_AUTHOR("Grant Likely <grant.likely@secretlab.ca>");
+MODULE_LICENSE("GPL");
+
+/**
+ * of_mdiobus_register - Register mii_bus and create PHYs from the device tree
+ * @mdio: pointer to mii_bus structure
+ * @np: pointer to device_node of MDIO bus.
+ *
+ * This function registers the mii_bus structure and registers a phy_device
+ * for each child node of @np.
+ */
+int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np)
+{
+       struct phy_device *phy;
+       struct device_node *child;
+       int rc, i;
+
+       /* Mask out all PHYs from auto probing.  Instead the PHYs listed in
+        * the device tree are populated after the bus has been registered */
+       mdio->phy_mask = ~0;
+
+       /* Clear all the IRQ properties */
+       if (mdio->irq)
+               for (i=0; i<PHY_MAX_ADDR; i++)
+                       mdio->irq[i] = PHY_POLL;
+
+       /* Register the MDIO bus */
+       rc = mdiobus_register(mdio);
+       if (rc)
+               return rc;
+
+       /* Loop over the child nodes and register a phy_device for each one */
+       for_each_child_of_node(np, child) {
+               const u32 *addr;
+               int len;
+
+               /* A PHY must have a reg property in the range [0-31] */
+               addr = of_get_property(child, "reg", &len);
+               if (!addr || len < sizeof(*addr) || *addr >= 32 || *addr < 0) {
+                       dev_err(&mdio->dev, "%s has invalid PHY address\n",
+                               child->full_name);
+                       continue;
+               }
+
+               if (mdio->irq) {
+                       mdio->irq[*addr] = irq_of_parse_and_map(child, 0);
+                       if (!mdio->irq[*addr])
+                               mdio->irq[*addr] = PHY_POLL;
+               }
+
+               phy = get_phy_device(mdio, *addr);
+               if (!phy) {
+                       dev_err(&mdio->dev, "error probing PHY at address %i\n",
+                               *addr);
+                       continue;
+               }
+               phy_scan_fixups(phy);
+
+               /* Associate the OF node with the device structure so it
+                * can be looked up later */
+               of_node_get(child);
+               dev_archdata_set_node(&phy->dev.archdata, child);
+
+               /* All data is now stored in the phy struct; register it */
+               rc = phy_device_register(phy);
+               if (rc) {
+                       phy_device_free(phy);
+                       of_node_put(child);
+                       continue;
+               }
+
+               dev_dbg(&mdio->dev, "registered phy %s at address %i\n",
+                       child->name, *addr);
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL(of_mdiobus_register);
+
+/**
+ * of_phy_find_device - Give a PHY node, find the phy_device
+ * @phy_np: Pointer to the phy's device tree node
+ *
+ * Returns a pointer to the phy_device.
+ */
+struct phy_device *of_phy_find_device(struct device_node *phy_np)
+{
+       struct device *d;
+       int match(struct device *dev, void *phy_np)
+       {
+               return dev_archdata_get_node(&dev->archdata) == phy_np;
+       }
+
+       if (!phy_np)
+               return NULL;
+
+       d = bus_find_device(&mdio_bus_type, NULL, phy_np, match);
+       return d ? to_phy_device(d) : NULL;
+}
+EXPORT_SYMBOL(of_phy_find_device);
+
+/**
+ * of_phy_connect - Connect to the phy described in the device tree
+ * @dev: pointer to net_device claiming the phy
+ * @phy_np: Pointer to device tree node for the PHY
+ * @hndlr: Link state callback for the network device
+ * @iface: PHY data interface type
+ *
+ * Returns a pointer to the phy_device if successfull.  NULL otherwise
+ */
+struct phy_device *of_phy_connect(struct net_device *dev,
+                                 struct device_node *phy_np,
+                                 void (*hndlr)(struct net_device *), u32 flags,
+                                 phy_interface_t iface)
+{
+       struct phy_device *phy = of_phy_find_device(phy_np);
+
+       if (!phy)
+               return NULL;
+
+       return phy_connect_direct(dev, phy, hndlr, flags, iface) ? NULL : phy;
+}
+EXPORT_SYMBOL(of_phy_connect);
index ba6af162fd39a259663c53c0269cf98f380499cc..b77ae679427503447b26c228d7356b5d1bb9070e 100644 (file)
@@ -39,7 +39,6 @@ obj-$(CONFIG_ALPHA) += setup-bus.o setup-irq.o
 obj-$(CONFIG_ARM) += setup-bus.o setup-irq.o
 obj-$(CONFIG_PARISC) += setup-bus.o
 obj-$(CONFIG_SUPERH) += setup-bus.o setup-irq.o
-obj-$(CONFIG_PPC32) += setup-irq.o
 obj-$(CONFIG_PPC) += setup-bus.o
 obj-$(CONFIG_MIPS) += setup-bus.o setup-irq.o
 obj-$(CONFIG_X86_VISWS) += setup-irq.o
index 3067673d54f69cadf896e19f7aee1d3ed11e9117..bd4253f93d5a1f273e7cd947a693e2ef099029dd 100644 (file)
@@ -2461,6 +2461,8 @@ static void __devinit quirk_i82576_sriov(struct pci_dev *dev)
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10c9, quirk_i82576_sriov);
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10e6, quirk_i82576_sriov);
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10e7, quirk_i82576_sriov);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x10e8, quirk_i82576_sriov);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x150a, quirk_i82576_sriov);
 
 #endif /* CONFIG_PCI_IOV */
 
index 284ebaca6e454797622c136213a7e05b48e1d46e..c682ac53641554a82c3b47ef91a71204530d393e 100644 (file)
@@ -21,7 +21,7 @@ config ACER_WMI
        depends on NEW_LEDS
        depends on BACKLIGHT_CLASS_DEVICE
        depends on SERIO_I8042
-       depends on RFKILL
+       depends on RFKILL || RFKILL = n
        select ACPI_WMI
        ---help---
          This is a driver for newer Acer (and Wistron) laptops. It adds
@@ -60,7 +60,7 @@ config DELL_LAPTOP
        depends on DCDBAS
        depends on EXPERIMENTAL
        depends on BACKLIGHT_CLASS_DEVICE
-       depends on RFKILL
+       depends on RFKILL || RFKILL = n
        depends on POWER_SUPPLY
        default n
        ---help---
@@ -117,7 +117,7 @@ config HP_WMI
        tristate "HP WMI extras"
        depends on ACPI_WMI
        depends on INPUT
-       depends on RFKILL
+       depends on RFKILL || RFKILL = n
        help
         Say Y here if you want to support WMI-based hotkeys on HP laptops and
         to read data from WMI such as docking or ambient light sensor state.
@@ -196,14 +196,13 @@ config THINKPAD_ACPI
        tristate "ThinkPad ACPI Laptop Extras"
        depends on ACPI
        depends on INPUT
+       depends on RFKILL || RFKILL = n
        select BACKLIGHT_LCD_SUPPORT
        select BACKLIGHT_CLASS_DEVICE
        select HWMON
        select NVRAM
        select NEW_LEDS
        select LEDS_CLASS
-       select NET
-       select RFKILL
        ---help---
          This is a driver for the IBM and Lenovo ThinkPad laptops. It adds
          support for Fn-Fx key combinations, Bluetooth control, video
@@ -338,9 +337,9 @@ config EEEPC_LAPTOP
        depends on ACPI
        depends on INPUT
        depends on EXPERIMENTAL
+       depends on RFKILL || RFKILL = n
        select BACKLIGHT_CLASS_DEVICE
        select HWMON
-       select RFKILL
        ---help---
          This driver supports the Fn-Fx keys on Eee PC laptops.
          It also adds the ability to switch camera/wlan on/off.
@@ -405,9 +404,8 @@ config ACPI_TOSHIBA
        tristate "Toshiba Laptop Extras"
        depends on ACPI
        depends on INPUT
+       depends on RFKILL || RFKILL = n
        select INPUT_POLLDEV
-       select NET
-       select RFKILL
        select BACKLIGHT_CLASS_DEVICE
        ---help---
          This driver adds support for access to certain system settings
index 0f6e43bf4fc211804272790d409e18daeba128fa..09a503e5da6a13a3f3c0138dabbe33ec5cdc691a 100644 (file)
@@ -958,59 +958,47 @@ static void acer_rfkill_update(struct work_struct *ignored)
 
        status = get_u32(&state, ACER_CAP_WIRELESS);
        if (ACPI_SUCCESS(status))
-               rfkill_force_state(wireless_rfkill, state ?
-                       RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED);
+               rfkill_set_sw_state(wireless_rfkill, !!state);
 
        if (has_cap(ACER_CAP_BLUETOOTH)) {
                status = get_u32(&state, ACER_CAP_BLUETOOTH);
                if (ACPI_SUCCESS(status))
-                       rfkill_force_state(bluetooth_rfkill, state ?
-                               RFKILL_STATE_UNBLOCKED :
-                               RFKILL_STATE_SOFT_BLOCKED);
+                       rfkill_set_sw_state(bluetooth_rfkill, !!state);
        }
 
        schedule_delayed_work(&acer_rfkill_work, round_jiffies_relative(HZ));
 }
 
-static int acer_rfkill_set(void *data, enum rfkill_state state)
+static int acer_rfkill_set(void *data, bool blocked)
 {
        acpi_status status;
-       u32 *cap = data;
-       status = set_u32((u32) (state == RFKILL_STATE_UNBLOCKED), *cap);
+       u32 cap = (unsigned long)data;
+       status = set_u32(!!blocked, cap);
        if (ACPI_FAILURE(status))
                return -ENODEV;
        return 0;
 }
 
-static struct rfkill * acer_rfkill_register(struct device *dev,
-enum rfkill_type type, char *name, u32 cap)
+static const struct rfkill_ops acer_rfkill_ops = {
+       .set_block = acer_rfkill_set,
+};
+
+static struct rfkill *acer_rfkill_register(struct device *dev,
+                                          enum rfkill_type type,
+                                          char *name, u32 cap)
 {
        int err;
-       u32 state;
-       u32 *data;
        struct rfkill *rfkill_dev;
 
-       rfkill_dev = rfkill_allocate(dev, type);
+       rfkill_dev = rfkill_alloc(name, dev, type,
+                                 &acer_rfkill_ops,
+                                 (void *)(unsigned long)cap);
        if (!rfkill_dev)
                return ERR_PTR(-ENOMEM);
-       rfkill_dev->name = name;
-       get_u32(&state, cap);
-       rfkill_dev->state = state ? RFKILL_STATE_UNBLOCKED :
-               RFKILL_STATE_SOFT_BLOCKED;
-       data = kzalloc(sizeof(u32), GFP_KERNEL);
-       if (!data) {
-               rfkill_free(rfkill_dev);
-               return ERR_PTR(-ENOMEM);
-       }
-       *data = cap;
-       rfkill_dev->data = data;
-       rfkill_dev->toggle_radio = acer_rfkill_set;
-       rfkill_dev->user_claim_unsupported = 1;
 
        err = rfkill_register(rfkill_dev);
        if (err) {
-               kfree(rfkill_dev->data);
-               rfkill_free(rfkill_dev);
+               rfkill_destroy(rfkill_dev);
                return ERR_PTR(err);
        }
        return rfkill_dev;
@@ -1028,8 +1016,8 @@ static int acer_rfkill_init(struct device *dev)
                        RFKILL_TYPE_BLUETOOTH, "acer-bluetooth",
                        ACER_CAP_BLUETOOTH);
                if (IS_ERR(bluetooth_rfkill)) {
-                       kfree(wireless_rfkill->data);
                        rfkill_unregister(wireless_rfkill);
+                       rfkill_destroy(wireless_rfkill);
                        return PTR_ERR(bluetooth_rfkill);
                }
        }
@@ -1042,11 +1030,13 @@ static int acer_rfkill_init(struct device *dev)
 static void acer_rfkill_exit(void)
 {
        cancel_delayed_work_sync(&acer_rfkill_work);
-       kfree(wireless_rfkill->data);
+
        rfkill_unregister(wireless_rfkill);
+       rfkill_destroy(wireless_rfkill);
+
        if (has_cap(ACER_CAP_BLUETOOTH)) {
-               kfree(bluetooth_rfkill->data);
                rfkill_unregister(bluetooth_rfkill);
+               rfkill_destroy(bluetooth_rfkill);
        }
        return;
 }
index af9f430211722d71f85a79c762adb35ccda50b35..2faf0e14f05a68e1e7f2467367cee88a8ff2285e 100644 (file)
@@ -174,10 +174,11 @@ dell_send_request(struct calling_interface_buffer *buffer, int class,
    result[3]: NVRAM format version number
 */
 
-static int dell_rfkill_set(int radio, enum rfkill_state state)
+static int dell_rfkill_set(void *data, bool blocked)
 {
        struct calling_interface_buffer buffer;
-       int disable = (state == RFKILL_STATE_UNBLOCKED) ? 0 : 1;
+       int disable = blocked ? 0 : 1;
+       unsigned long radio = (unsigned long)data;
 
        memset(&buffer, 0, sizeof(struct calling_interface_buffer));
        buffer.input[0] = (1 | (radio<<8) | (disable << 16));
@@ -186,56 +187,24 @@ static int dell_rfkill_set(int radio, enum rfkill_state state)
        return 0;
 }
 
-static int dell_wifi_set(void *data, enum rfkill_state state)
-{
-       return dell_rfkill_set(1, state);
-}
-
-static int dell_bluetooth_set(void *data, enum rfkill_state state)
-{
-       return dell_rfkill_set(2, state);
-}
-
-static int dell_wwan_set(void *data, enum rfkill_state state)
-{
-       return dell_rfkill_set(3, state);
-}
-
-static int dell_rfkill_get(int bit, enum rfkill_state *state)
+static void dell_rfkill_query(struct rfkill *rfkill, void *data)
 {
        struct calling_interface_buffer buffer;
        int status;
-       int new_state = RFKILL_STATE_HARD_BLOCKED;
+       int bit = (unsigned long)data + 16;
 
        memset(&buffer, 0, sizeof(struct calling_interface_buffer));
        dell_send_request(&buffer, 17, 11);
        status = buffer.output[1];
 
-       if (status & (1<<16))
-               new_state = RFKILL_STATE_SOFT_BLOCKED;
-
-       if (status & (1<<bit))
-               *state = new_state;
-       else
-               *state = RFKILL_STATE_UNBLOCKED;
-
-       return 0;
-}
-
-static int dell_wifi_get(void *data, enum rfkill_state *state)
-{
-       return dell_rfkill_get(17, state);
-}
-
-static int dell_bluetooth_get(void *data, enum rfkill_state *state)
-{
-       return dell_rfkill_get(18, state);
+       if (status & BIT(bit))
+               rfkill_set_hw_state(rfkill, !!(status & BIT(16)));
 }
 
-static int dell_wwan_get(void *data, enum rfkill_state *state)
-{
-       return dell_rfkill_get(19, state);
-}
+static const struct rfkill_ops dell_rfkill_ops = {
+       .set_block = dell_rfkill_set,
+       .query = dell_rfkill_query,
+};
 
 static int dell_setup_rfkill(void)
 {
@@ -248,36 +217,37 @@ static int dell_setup_rfkill(void)
        status = buffer.output[1];
 
        if ((status & (1<<2|1<<8)) == (1<<2|1<<8)) {
-               wifi_rfkill = rfkill_allocate(NULL, RFKILL_TYPE_WLAN);
-               if (!wifi_rfkill)
+               wifi_rfkill = rfkill_alloc("dell-wifi", NULL, RFKILL_TYPE_WLAN,
+                                          &dell_rfkill_ops, (void *) 1);
+               if (!wifi_rfkill) {
+                       ret = -ENOMEM;
                        goto err_wifi;
-               wifi_rfkill->name = "dell-wifi";
-               wifi_rfkill->toggle_radio = dell_wifi_set;
-               wifi_rfkill->get_state = dell_wifi_get;
+               }
                ret = rfkill_register(wifi_rfkill);
                if (ret)
                        goto err_wifi;
        }
 
        if ((status & (1<<3|1<<9)) == (1<<3|1<<9)) {
-               bluetooth_rfkill = rfkill_allocate(NULL, RFKILL_TYPE_BLUETOOTH);
-               if (!bluetooth_rfkill)
+               bluetooth_rfkill = rfkill_alloc("dell-bluetooth", NULL,
+                                               RFKILL_TYPE_BLUETOOTH,
+                                               &dell_rfkill_ops, (void *) 2);
+               if (!bluetooth_rfkill) {
+                       ret = -ENOMEM;
                        goto err_bluetooth;
-               bluetooth_rfkill->name = "dell-bluetooth";
-               bluetooth_rfkill->toggle_radio = dell_bluetooth_set;
-               bluetooth_rfkill->get_state = dell_bluetooth_get;
+               }
                ret = rfkill_register(bluetooth_rfkill);
                if (ret)
                        goto err_bluetooth;
        }
 
        if ((status & (1<<4|1<<10)) == (1<<4|1<<10)) {
-               wwan_rfkill = rfkill_allocate(NULL, RFKILL_TYPE_WWAN);
-               if (!wwan_rfkill)
+               wwan_rfkill = rfkill_alloc("dell-wwan", NULL, RFKILL_TYPE_WWAN,
+                                          &dell_rfkill_ops, (void *) 3);
+               if (!wwan_rfkill) {
+                       ret = -ENOMEM;
                        goto err_wwan;
-               wwan_rfkill->name = "dell-wwan";
-               wwan_rfkill->toggle_radio = dell_wwan_set;
-               wwan_rfkill->get_state = dell_wwan_get;
+               }
                ret = rfkill_register(wwan_rfkill);
                if (ret)
                        goto err_wwan;
@@ -285,22 +255,15 @@ static int dell_setup_rfkill(void)
 
        return 0;
 err_wwan:
-       if (wwan_rfkill)
-               rfkill_free(wwan_rfkill);
-       if (bluetooth_rfkill) {
+       rfkill_destroy(wwan_rfkill);
+       if (bluetooth_rfkill)
                rfkill_unregister(bluetooth_rfkill);
-               bluetooth_rfkill = NULL;
-       }
 err_bluetooth:
-       if (bluetooth_rfkill)
-               rfkill_free(bluetooth_rfkill);
-       if (wifi_rfkill) {
+       rfkill_destroy(bluetooth_rfkill);
+       if (wifi_rfkill)
                rfkill_unregister(wifi_rfkill);
-               wifi_rfkill = NULL;
-       }
 err_wifi:
-       if (wifi_rfkill)
-               rfkill_free(wifi_rfkill);
+       rfkill_destroy(wifi_rfkill);
 
        return ret;
 }
index 353a898c3693facba59683b1f792150e3538d9cf..03bf522bd7abc40b7db141f34864b2674f0e59ef 100644 (file)
@@ -299,39 +299,22 @@ static int update_bl_status(struct backlight_device *bd)
  * Rfkill helpers
  */
 
-static int eeepc_wlan_rfkill_set(void *data, enum rfkill_state state)
-{
-       if (state == RFKILL_STATE_SOFT_BLOCKED)
-               return set_acpi(CM_ASL_WLAN, 0);
-       else
-               return set_acpi(CM_ASL_WLAN, 1);
-}
-
-static int eeepc_wlan_rfkill_state(void *data, enum rfkill_state *state)
+static bool eeepc_wlan_rfkill_blocked(void)
 {
        if (get_acpi(CM_ASL_WLAN) == 1)
-               *state = RFKILL_STATE_UNBLOCKED;
-       else
-               *state = RFKILL_STATE_SOFT_BLOCKED;
-       return 0;
+               return false;
+       return true;
 }
 
-static int eeepc_bluetooth_rfkill_set(void *data, enum rfkill_state state)
+static int eeepc_rfkill_set(void *data, bool blocked)
 {
-       if (state == RFKILL_STATE_SOFT_BLOCKED)
-               return set_acpi(CM_ASL_BLUETOOTH, 0);
-       else
-               return set_acpi(CM_ASL_BLUETOOTH, 1);
+       unsigned long asl = (unsigned long)data;
+       return set_acpi(asl, !blocked);
 }
 
-static int eeepc_bluetooth_rfkill_state(void *data, enum rfkill_state *state)
-{
-       if (get_acpi(CM_ASL_BLUETOOTH) == 1)
-               *state = RFKILL_STATE_UNBLOCKED;
-       else
-               *state = RFKILL_STATE_SOFT_BLOCKED;
-       return 0;
-}
+static const struct rfkill_ops eeepc_rfkill_ops = {
+       .set_block = eeepc_rfkill_set,
+};
 
 /*
  * Sys helpers
@@ -531,9 +514,9 @@ static int notify_brn(void)
 
 static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
 {
-       enum rfkill_state state;
        struct pci_dev *dev;
        struct pci_bus *bus = pci_find_bus(0, 1);
+       bool blocked;
 
        if (event != ACPI_NOTIFY_BUS_CHECK)
                return;
@@ -543,9 +526,8 @@ static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
                return;
        }
 
-       eeepc_wlan_rfkill_state(ehotk->eeepc_wlan_rfkill, &state);
-
-       if (state == RFKILL_STATE_UNBLOCKED) {
+       blocked = eeepc_wlan_rfkill_blocked();
+       if (!blocked) {
                dev = pci_get_slot(bus, 0);
                if (dev) {
                        /* Device already present */
@@ -566,7 +548,7 @@ static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data)
                }
        }
 
-       rfkill_force_state(ehotk->eeepc_wlan_rfkill, state);
+       rfkill_set_sw_state(ehotk->eeepc_wlan_rfkill, blocked);
 }
 
 static void eeepc_hotk_notify(acpi_handle handle, u32 event, void *data)
@@ -684,26 +666,17 @@ static int eeepc_hotk_add(struct acpi_device *device)
        eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7");
 
        if (get_acpi(CM_ASL_WLAN) != -1) {
-               ehotk->eeepc_wlan_rfkill = rfkill_allocate(&device->dev,
-                                                          RFKILL_TYPE_WLAN);
+               ehotk->eeepc_wlan_rfkill = rfkill_alloc("eeepc-wlan",
+                                                       &device->dev,
+                                                       RFKILL_TYPE_WLAN,
+                                                       &eeepc_rfkill_ops,
+                                                       (void *)CM_ASL_WLAN);
 
                if (!ehotk->eeepc_wlan_rfkill)
                        goto wlan_fail;
 
-               ehotk->eeepc_wlan_rfkill->name = "eeepc-wlan";
-               ehotk->eeepc_wlan_rfkill->toggle_radio = eeepc_wlan_rfkill_set;
-               ehotk->eeepc_wlan_rfkill->get_state = eeepc_wlan_rfkill_state;
-               if (get_acpi(CM_ASL_WLAN) == 1) {
-                       ehotk->eeepc_wlan_rfkill->state =
-                               RFKILL_STATE_UNBLOCKED;
-                       rfkill_set_default(RFKILL_TYPE_WLAN,
-                                          RFKILL_STATE_UNBLOCKED);
-               } else {
-                       ehotk->eeepc_wlan_rfkill->state =
-                               RFKILL_STATE_SOFT_BLOCKED;
-                       rfkill_set_default(RFKILL_TYPE_WLAN,
-                                          RFKILL_STATE_SOFT_BLOCKED);
-               }
+               rfkill_set_sw_state(ehotk->eeepc_wlan_rfkill,
+                                   get_acpi(CM_ASL_WLAN) != 1);
                result = rfkill_register(ehotk->eeepc_wlan_rfkill);
                if (result)
                        goto wlan_fail;
@@ -711,28 +684,17 @@ static int eeepc_hotk_add(struct acpi_device *device)
 
        if (get_acpi(CM_ASL_BLUETOOTH) != -1) {
                ehotk->eeepc_bluetooth_rfkill =
-                       rfkill_allocate(&device->dev, RFKILL_TYPE_BLUETOOTH);
+                       rfkill_alloc("eeepc-bluetooth",
+                                    &device->dev,
+                                    RFKILL_TYPE_BLUETOOTH,
+                                    &eeepc_rfkill_ops,
+                                    (void *)CM_ASL_BLUETOOTH);
 
                if (!ehotk->eeepc_bluetooth_rfkill)
                        goto bluetooth_fail;
 
-               ehotk->eeepc_bluetooth_rfkill->name = "eeepc-bluetooth";
-               ehotk->eeepc_bluetooth_rfkill->toggle_radio =
-                       eeepc_bluetooth_rfkill_set;
-               ehotk->eeepc_bluetooth_rfkill->get_state =
-                       eeepc_bluetooth_rfkill_state;
-               if (get_acpi(CM_ASL_BLUETOOTH) == 1) {
-                       ehotk->eeepc_bluetooth_rfkill->state =
-                               RFKILL_STATE_UNBLOCKED;
-                       rfkill_set_default(RFKILL_TYPE_BLUETOOTH,
-                                          RFKILL_STATE_UNBLOCKED);
-               } else {
-                       ehotk->eeepc_bluetooth_rfkill->state =
-                               RFKILL_STATE_SOFT_BLOCKED;
-                       rfkill_set_default(RFKILL_TYPE_BLUETOOTH,
-                                          RFKILL_STATE_SOFT_BLOCKED);
-               }
-
+               rfkill_set_sw_state(ehotk->eeepc_bluetooth_rfkill,
+                                   get_acpi(CM_ASL_BLUETOOTH) != 1);
                result = rfkill_register(ehotk->eeepc_bluetooth_rfkill);
                if (result)
                        goto bluetooth_fail;
@@ -741,13 +703,10 @@ static int eeepc_hotk_add(struct acpi_device *device)
        return 0;
 
  bluetooth_fail:
-       if (ehotk->eeepc_bluetooth_rfkill)
-               rfkill_free(ehotk->eeepc_bluetooth_rfkill);
+       rfkill_destroy(ehotk->eeepc_bluetooth_rfkill);
        rfkill_unregister(ehotk->eeepc_wlan_rfkill);
-       ehotk->eeepc_wlan_rfkill = NULL;
  wlan_fail:
-       if (ehotk->eeepc_wlan_rfkill)
-               rfkill_free(ehotk->eeepc_wlan_rfkill);
+       rfkill_destroy(ehotk->eeepc_wlan_rfkill);
        eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6");
        eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7");
  ehotk_fail:
index 50d9019de2be2b33beae302ef0d99480073c0b52..16fffe44e3335ee34b4053e7b309b6e4dd3a631b 100644 (file)
@@ -154,58 +154,46 @@ static int hp_wmi_dock_state(void)
        return hp_wmi_perform_query(HPWMI_DOCK_QUERY, 0, 0);
 }
 
-static int hp_wmi_wifi_set(void *data, enum rfkill_state state)
+static int hp_wmi_set_block(void *data, bool blocked)
 {
-       if (state)
-               return hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 1, 0x101);
-       else
-               return hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 1, 0x100);
-}
+       unsigned long b = (unsigned long) data;
+       int query = BIT(b + 8) | ((!!blocked) << b);
 
-static int hp_wmi_bluetooth_set(void *data, enum rfkill_state state)
-{
-       if (state)
-               return hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 1, 0x202);
-       else
-               return hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 1, 0x200);
+       return hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 1, query);
 }
 
-static int hp_wmi_wwan_set(void *data, enum rfkill_state state)
-{
-       if (state)
-               return hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 1, 0x404);
-       else
-               return hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 1, 0x400);
-}
+static const struct rfkill_ops hp_wmi_rfkill_ops = {
+       .set_block = hp_wmi_set_block,
+};
 
-static int hp_wmi_wifi_state(void)
+static bool hp_wmi_wifi_state(void)
 {
        int wireless = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, 0);
 
        if (wireless & 0x100)
-               return RFKILL_STATE_UNBLOCKED;
+               return false;
        else
-               return RFKILL_STATE_SOFT_BLOCKED;
+               return true;
 }
 
-static int hp_wmi_bluetooth_state(void)
+static bool hp_wmi_bluetooth_state(void)
 {
        int wireless = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, 0);
 
        if (wireless & 0x10000)
-               return RFKILL_STATE_UNBLOCKED;
+               return false;
        else
-               return RFKILL_STATE_SOFT_BLOCKED;
+               return true;
 }
 
-static int hp_wmi_wwan_state(void)
+static bool hp_wmi_wwan_state(void)
 {
        int wireless = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, 0);
 
        if (wireless & 0x1000000)
-               return RFKILL_STATE_UNBLOCKED;
+               return false;
        else
-               return RFKILL_STATE_SOFT_BLOCKED;
+               return true;
 }
 
 static ssize_t show_display(struct device *dev, struct device_attribute *attr,
@@ -347,14 +335,14 @@ static void hp_wmi_notify(u32 value, void *context)
                        }
                } else if (eventcode == 0x5) {
                        if (wifi_rfkill)
-                               rfkill_force_state(wifi_rfkill,
-                                                  hp_wmi_wifi_state());
+                               rfkill_set_sw_state(wifi_rfkill,
+                                                   hp_wmi_wifi_state());
                        if (bluetooth_rfkill)
-                               rfkill_force_state(bluetooth_rfkill,
-                                                  hp_wmi_bluetooth_state());
+                               rfkill_set_sw_state(bluetooth_rfkill,
+                                                   hp_wmi_bluetooth_state());
                        if (wwan_rfkill)
-                               rfkill_force_state(wwan_rfkill,
-                                                  hp_wmi_wwan_state());
+                               rfkill_set_sw_state(wwan_rfkill,
+                                                   hp_wmi_wwan_state());
                } else
                        printk(KERN_INFO "HP WMI: Unknown key pressed - %x\n",
                               eventcode);
@@ -430,34 +418,30 @@ static int __init hp_wmi_bios_setup(struct platform_device *device)
                goto add_sysfs_error;
 
        if (wireless & 0x1) {
-               wifi_rfkill = rfkill_allocate(&device->dev, RFKILL_TYPE_WLAN);
-               wifi_rfkill->name = "hp-wifi";
-               wifi_rfkill->state = hp_wmi_wifi_state();
-               wifi_rfkill->toggle_radio = hp_wmi_wifi_set;
-               wifi_rfkill->user_claim_unsupported = 1;
+               wifi_rfkill = rfkill_alloc("hp-wifi", &device->dev,
+                                          RFKILL_TYPE_WLAN,
+                                          &hp_wmi_rfkill_ops,
+                                          (void *) 0);
                err = rfkill_register(wifi_rfkill);
                if (err)
-                       goto add_sysfs_error;
+                       goto register_wifi_error;
        }
 
        if (wireless & 0x2) {
-               bluetooth_rfkill = rfkill_allocate(&device->dev,
-                                                  RFKILL_TYPE_BLUETOOTH);
-               bluetooth_rfkill->name = "hp-bluetooth";
-               bluetooth_rfkill->state = hp_wmi_bluetooth_state();
-               bluetooth_rfkill->toggle_radio = hp_wmi_bluetooth_set;
-               bluetooth_rfkill->user_claim_unsupported = 1;
+               bluetooth_rfkill = rfkill_alloc("hp-bluetooth", &device->dev,
+                                               RFKILL_TYPE_BLUETOOTH,
+                                               &hp_wmi_rfkill_ops,
+                                               (void *) 1);
                err = rfkill_register(bluetooth_rfkill);
                if (err)
                        goto register_bluetooth_error;
        }
 
        if (wireless & 0x4) {
-               wwan_rfkill = rfkill_allocate(&device->dev, RFKILL_TYPE_WWAN);
-               wwan_rfkill->name = "hp-wwan";
-               wwan_rfkill->state = hp_wmi_wwan_state();
-               wwan_rfkill->toggle_radio = hp_wmi_wwan_set;
-               wwan_rfkill->user_claim_unsupported = 1;
+               wwan_rfkill = rfkill_alloc("hp-wwan", &device->dev,
+                                          RFKILL_TYPE_WWAN,
+                                          &hp_wmi_rfkill_ops,
+                                          (void *) 2);
                err = rfkill_register(wwan_rfkill);
                if (err)
                        goto register_wwan_err;
@@ -465,11 +449,15 @@ static int __init hp_wmi_bios_setup(struct platform_device *device)
 
        return 0;
 register_wwan_err:
+       rfkill_destroy(wwan_rfkill);
        if (bluetooth_rfkill)
                rfkill_unregister(bluetooth_rfkill);
 register_bluetooth_error:
+       rfkill_destroy(bluetooth_rfkill);
        if (wifi_rfkill)
                rfkill_unregister(wifi_rfkill);
+register_wifi_error:
+       rfkill_destroy(wifi_rfkill);
 add_sysfs_error:
        cleanup_sysfs(device);
        return err;
@@ -479,12 +467,18 @@ static int __exit hp_wmi_bios_remove(struct platform_device *device)
 {
        cleanup_sysfs(device);
 
-       if (wifi_rfkill)
+       if (wifi_rfkill) {
                rfkill_unregister(wifi_rfkill);
-       if (bluetooth_rfkill)
+               rfkill_destroy(wifi_rfkill);
+       }
+       if (bluetooth_rfkill) {
                rfkill_unregister(bluetooth_rfkill);
-       if (wwan_rfkill)
+               rfkill_destroy(wifi_rfkill);
+       }
+       if (wwan_rfkill) {
                rfkill_unregister(wwan_rfkill);
+               rfkill_destroy(wwan_rfkill);
+       }
 
        return 0;
 }
index 552958545f94fc03e83975012f5196e16794c6fa..e48d9a4506ff118eb7904e94be3638717b987fae 100644 (file)
@@ -128,11 +128,11 @@ enum sony_nc_rfkill {
        SONY_BLUETOOTH,
        SONY_WWAN,
        SONY_WIMAX,
-       SONY_RFKILL_MAX,
+       N_SONY_RFKILL,
 };
 
-static struct rfkill *sony_rfkill_devices[SONY_RFKILL_MAX];
-static int sony_rfkill_address[SONY_RFKILL_MAX] = {0x300, 0x500, 0x700, 0x900};
+static struct rfkill *sony_rfkill_devices[N_SONY_RFKILL];
+static int sony_rfkill_address[N_SONY_RFKILL] = {0x300, 0x500, 0x700, 0x900};
 static void sony_nc_rfkill_update(void);
 
 /*********** Input Devices ***********/
@@ -1051,151 +1051,96 @@ static void sony_nc_rfkill_cleanup(void)
 {
        int i;
 
-       for (i = 0; i < SONY_RFKILL_MAX; i++) {
-               if (sony_rfkill_devices[i])
+       for (i = 0; i < N_SONY_RFKILL; i++) {
+               if (sony_rfkill_devices[i]) {
                        rfkill_unregister(sony_rfkill_devices[i]);
+                       rfkill_destroy(sony_rfkill_devices[i]);
+               }
        }
 }
 
-static int sony_nc_rfkill_get(void *data, enum rfkill_state *state)
-{
-       int result;
-       int argument = sony_rfkill_address[(long) data];
-
-       sony_call_snc_handle(0x124, 0x200, &result);
-       if (result & 0x1) {
-               sony_call_snc_handle(0x124, argument, &result);
-               if (result & 0xf)
-                       *state = RFKILL_STATE_UNBLOCKED;
-               else
-                       *state = RFKILL_STATE_SOFT_BLOCKED;
-       } else {
-               *state = RFKILL_STATE_HARD_BLOCKED;
-       }
-
-       return 0;
-}
-
-static int sony_nc_rfkill_set(void *data, enum rfkill_state state)
+static int sony_nc_rfkill_set(void *data, bool blocked)
 {
        int result;
        int argument = sony_rfkill_address[(long) data] + 0x100;
 
-       if (state == RFKILL_STATE_UNBLOCKED)
+       if (!blocked)
                argument |= 0xff0000;
 
        return sony_call_snc_handle(0x124, argument, &result);
 }
 
-static int sony_nc_setup_wifi_rfkill(struct acpi_device *device)
-{
-       int err = 0;
-       struct rfkill *sony_wifi_rfkill;
-
-       sony_wifi_rfkill = rfkill_allocate(&device->dev, RFKILL_TYPE_WLAN);
-       if (!sony_wifi_rfkill)
-               return -1;
-       sony_wifi_rfkill->name = "sony-wifi";
-       sony_wifi_rfkill->toggle_radio = sony_nc_rfkill_set;
-       sony_wifi_rfkill->get_state = sony_nc_rfkill_get;
-       sony_wifi_rfkill->user_claim_unsupported = 1;
-       sony_wifi_rfkill->data = (void *)SONY_WIFI;
-       err = rfkill_register(sony_wifi_rfkill);
-       if (err)
-               rfkill_free(sony_wifi_rfkill);
-       else {
-               sony_rfkill_devices[SONY_WIFI] = sony_wifi_rfkill;
-               sony_nc_rfkill_set(sony_wifi_rfkill->data,
-                               RFKILL_STATE_UNBLOCKED);
-       }
-       return err;
-}
+static const struct rfkill_ops sony_rfkill_ops = {
+       .set_block = sony_nc_rfkill_set,
+};
 
-static int sony_nc_setup_bluetooth_rfkill(struct acpi_device *device)
+static int sony_nc_setup_rfkill(struct acpi_device *device,
+                               enum sony_nc_rfkill nc_type)
 {
        int err = 0;
-       struct rfkill *sony_bluetooth_rfkill;
-
-       sony_bluetooth_rfkill = rfkill_allocate(&device->dev,
-                                               RFKILL_TYPE_BLUETOOTH);
-       if (!sony_bluetooth_rfkill)
-               return -1;
-       sony_bluetooth_rfkill->name = "sony-bluetooth";
-       sony_bluetooth_rfkill->toggle_radio = sony_nc_rfkill_set;
-       sony_bluetooth_rfkill->get_state = sony_nc_rfkill_get;
-       sony_bluetooth_rfkill->user_claim_unsupported = 1;
-       sony_bluetooth_rfkill->data = (void *)SONY_BLUETOOTH;
-       err = rfkill_register(sony_bluetooth_rfkill);
-       if (err)
-               rfkill_free(sony_bluetooth_rfkill);
-       else {
-               sony_rfkill_devices[SONY_BLUETOOTH] = sony_bluetooth_rfkill;
-               sony_nc_rfkill_set(sony_bluetooth_rfkill->data,
-                               RFKILL_STATE_UNBLOCKED);
+       struct rfkill *rfk;
+       enum rfkill_type type;
+       const char *name;
+
+       switch (nc_type) {
+       case SONY_WIFI:
+               type = RFKILL_TYPE_WLAN;
+               name = "sony-wifi";
+               break;
+       case SONY_BLUETOOTH:
+               type = RFKILL_TYPE_BLUETOOTH;
+               name = "sony-bluetooth";
+               break;
+       case SONY_WWAN:
+               type = RFKILL_TYPE_WWAN;
+               name = "sony-wwan";
+               break;
+       case SONY_WIMAX:
+               type = RFKILL_TYPE_WIMAX;
+               name = "sony-wimax";
+               break;
+       default:
+               return -EINVAL;
        }
-       return err;
-}
 
-static int sony_nc_setup_wwan_rfkill(struct acpi_device *device)
-{
-       int err = 0;
-       struct rfkill *sony_wwan_rfkill;
+       rfk = rfkill_alloc(name, &device->dev, type,
+                          &sony_rfkill_ops, (void *)nc_type);
+       if (!rfk)
+               return -ENOMEM;
 
-       sony_wwan_rfkill = rfkill_allocate(&device->dev, RFKILL_TYPE_WWAN);
-       if (!sony_wwan_rfkill)
-               return -1;
-       sony_wwan_rfkill->name = "sony-wwan";
-       sony_wwan_rfkill->toggle_radio = sony_nc_rfkill_set;
-       sony_wwan_rfkill->get_state = sony_nc_rfkill_get;
-       sony_wwan_rfkill->user_claim_unsupported = 1;
-       sony_wwan_rfkill->data = (void *)SONY_WWAN;
-       err = rfkill_register(sony_wwan_rfkill);
-       if (err)
-               rfkill_free(sony_wwan_rfkill);
-       else {
-               sony_rfkill_devices[SONY_WWAN] = sony_wwan_rfkill;
-               sony_nc_rfkill_set(sony_wwan_rfkill->data,
-                               RFKILL_STATE_UNBLOCKED);
+       err = rfkill_register(rfk);
+       if (err) {
+               rfkill_destroy(rfk);
+               return err;
        }
+       sony_rfkill_devices[nc_type] = rfk;
        return err;
 }
 
-static int sony_nc_setup_wimax_rfkill(struct acpi_device *device)
+static void sony_nc_rfkill_update()
 {
-       int err = 0;
-       struct rfkill *sony_wimax_rfkill;
+       enum sony_nc_rfkill i;
+       int result;
+       bool hwblock;
 
-       sony_wimax_rfkill = rfkill_allocate(&device->dev, RFKILL_TYPE_WIMAX);
-       if (!sony_wimax_rfkill)
-               return -1;
-       sony_wimax_rfkill->name = "sony-wimax";
-       sony_wimax_rfkill->toggle_radio = sony_nc_rfkill_set;
-       sony_wimax_rfkill->get_state = sony_nc_rfkill_get;
-       sony_wimax_rfkill->user_claim_unsupported = 1;
-       sony_wimax_rfkill->data = (void *)SONY_WIMAX;
-       err = rfkill_register(sony_wimax_rfkill);
-       if (err)
-               rfkill_free(sony_wimax_rfkill);
-       else {
-               sony_rfkill_devices[SONY_WIMAX] = sony_wimax_rfkill;
-               sony_nc_rfkill_set(sony_wimax_rfkill->data,
-                               RFKILL_STATE_UNBLOCKED);
-       }
-       return err;
-}
+       sony_call_snc_handle(0x124, 0x200, &result);
+       hwblock = !(result & 0x1);
 
-static void sony_nc_rfkill_update()
-{
-       int i;
-       enum rfkill_state state;
+       for (i = 0; i < N_SONY_RFKILL; i++) {
+               int argument = sony_rfkill_address[i];
 
-       for (i = 0; i < SONY_RFKILL_MAX; i++) {
-               if (sony_rfkill_devices[i]) {
-                       sony_rfkill_devices[i]->
-                               get_state(sony_rfkill_devices[i]->data,
-                                         &state);
-                       rfkill_force_state(sony_rfkill_devices[i], state);
+               if (!sony_rfkill_devices[i])
+                       continue;
+
+               if (hwblock) {
+                       if (rfkill_set_hw_state(sony_rfkill_devices[i], true))
+                               sony_nc_rfkill_set((void *)i, true);
+                       continue;
                }
+
+               sony_call_snc_handle(0x124, argument, &result);
+               rfkill_set_states(sony_rfkill_devices[i],
+                                 !(result & 0xf), false);
        }
 }
 
@@ -1214,13 +1159,13 @@ static int sony_nc_rfkill_setup(struct acpi_device *device)
        }
 
        if (result & 0x1)
-               sony_nc_setup_wifi_rfkill(device);
+               sony_nc_setup_rfkill(device, SONY_WIFI);
        if (result & 0x2)
-               sony_nc_setup_bluetooth_rfkill(device);
+               sony_nc_setup_rfkill(device, SONY_BLUETOOTH);
        if (result & 0x1c)
-               sony_nc_setup_wwan_rfkill(device);
+               sony_nc_setup_rfkill(device, SONY_WWAN);
        if (result & 0x20)
-               sony_nc_setup_wimax_rfkill(device);
+               sony_nc_setup_rfkill(device, SONY_WIMAX);
 
        return 0;
 }
index 912be65b62619570d3521dd0b83664ce16582278..86e958539f46143af18d1522c52fc4d2d41b6cd4 100644 (file)
@@ -166,13 +166,6 @@ enum {
 
 #define TPACPI_MAX_ACPI_ARGS 3
 
-/* rfkill switches */
-enum {
-       TPACPI_RFK_BLUETOOTH_SW_ID = 0,
-       TPACPI_RFK_WWAN_SW_ID,
-       TPACPI_RFK_UWB_SW_ID,
-};
-
 /* printk headers */
 #define TPACPI_LOG TPACPI_FILE ": "
 #define TPACPI_EMERG   KERN_EMERG      TPACPI_LOG
@@ -1005,67 +998,234 @@ static int __init tpacpi_check_std_acpi_brightness_support(void)
        return 0;
 }
 
-static int __init tpacpi_new_rfkill(const unsigned int id,
-                       struct rfkill **rfk,
+static void printk_deprecated_attribute(const char * const what,
+                                       const char * const details)
+{
+       tpacpi_log_usertask("deprecated sysfs attribute");
+       printk(TPACPI_WARN "WARNING: sysfs attribute %s is deprecated and "
+               "will be removed. %s\n",
+               what, details);
+}
+
+/*************************************************************************
+ * rfkill and radio control support helpers
+ */
+
+/*
+ * ThinkPad-ACPI firmware handling model:
+ *
+ * WLSW (master wireless switch) is event-driven, and is common to all
+ * firmware-controlled radios.  It cannot be controlled, just monitored,
+ * as expected.  It overrides all radio state in firmware
+ *
+ * The kernel, a masked-off hotkey, and WLSW can change the radio state
+ * (TODO: verify how WLSW interacts with the returned radio state).
+ *
+ * The only time there are shadow radio state changes, is when
+ * masked-off hotkeys are used.
+ */
+
+/*
+ * Internal driver API for radio state:
+ *
+ * int: < 0 = error, otherwise enum tpacpi_rfkill_state
+ * bool: true means radio blocked (off)
+ */
+enum tpacpi_rfkill_state {
+       TPACPI_RFK_RADIO_OFF = 0,
+       TPACPI_RFK_RADIO_ON
+};
+
+/* rfkill switches */
+enum tpacpi_rfk_id {
+       TPACPI_RFK_BLUETOOTH_SW_ID = 0,
+       TPACPI_RFK_WWAN_SW_ID,
+       TPACPI_RFK_UWB_SW_ID,
+       TPACPI_RFK_SW_MAX
+};
+
+static const char *tpacpi_rfkill_names[] = {
+       [TPACPI_RFK_BLUETOOTH_SW_ID] = "bluetooth",
+       [TPACPI_RFK_WWAN_SW_ID] = "wwan",
+       [TPACPI_RFK_UWB_SW_ID] = "uwb",
+       [TPACPI_RFK_SW_MAX] = NULL
+};
+
+/* ThinkPad-ACPI rfkill subdriver */
+struct tpacpi_rfk {
+       struct rfkill *rfkill;
+       enum tpacpi_rfk_id id;
+       const struct tpacpi_rfk_ops *ops;
+};
+
+struct tpacpi_rfk_ops {
+       /* firmware interface */
+       int (*get_status)(void);
+       int (*set_status)(const enum tpacpi_rfkill_state);
+};
+
+static struct tpacpi_rfk *tpacpi_rfkill_switches[TPACPI_RFK_SW_MAX];
+
+/* Query FW and update rfkill sw state for a given rfkill switch */
+static int tpacpi_rfk_update_swstate(const struct tpacpi_rfk *tp_rfk)
+{
+       int status;
+
+       if (!tp_rfk)
+               return -ENODEV;
+
+       status = (tp_rfk->ops->get_status)();
+       if (status < 0)
+               return status;
+
+       rfkill_set_sw_state(tp_rfk->rfkill,
+                           (status == TPACPI_RFK_RADIO_OFF));
+
+       return status;
+}
+
+/* Query FW and update rfkill sw state for all rfkill switches */
+static void tpacpi_rfk_update_swstate_all(void)
+{
+       unsigned int i;
+
+       for (i = 0; i < TPACPI_RFK_SW_MAX; i++)
+               tpacpi_rfk_update_swstate(tpacpi_rfkill_switches[i]);
+}
+
+/*
+ * Sync the HW-blocking state of all rfkill switches,
+ * do notice it causes the rfkill core to schedule uevents
+ */
+static void tpacpi_rfk_update_hwblock_state(bool blocked)
+{
+       unsigned int i;
+       struct tpacpi_rfk *tp_rfk;
+
+       for (i = 0; i < TPACPI_RFK_SW_MAX; i++) {
+               tp_rfk = tpacpi_rfkill_switches[i];
+               if (tp_rfk) {
+                       if (rfkill_set_hw_state(tp_rfk->rfkill,
+                                               blocked)) {
+                               /* ignore -- we track sw block */
+                       }
+               }
+       }
+}
+
+/* Call to get the WLSW state from the firmware */
+static int hotkey_get_wlsw(void);
+
+/* Call to query WLSW state and update all rfkill switches */
+static bool tpacpi_rfk_check_hwblock_state(void)
+{
+       int res = hotkey_get_wlsw();
+       int hw_blocked;
+
+       /* When unknown or unsupported, we have to assume it is unblocked */
+       if (res < 0)
+               return false;
+
+       hw_blocked = (res == TPACPI_RFK_RADIO_OFF);
+       tpacpi_rfk_update_hwblock_state(hw_blocked);
+
+       return hw_blocked;
+}
+
+static int tpacpi_rfk_hook_set_block(void *data, bool blocked)
+{
+       struct tpacpi_rfk *tp_rfk = data;
+       int res;
+
+       dbg_printk(TPACPI_DBG_RFKILL,
+                  "request to change radio state to %s\n",
+                  blocked ? "blocked" : "unblocked");
+
+       /* try to set radio state */
+       res = (tp_rfk->ops->set_status)(blocked ?
+                               TPACPI_RFK_RADIO_OFF : TPACPI_RFK_RADIO_ON);
+
+       /* and update the rfkill core with whatever the FW really did */
+       tpacpi_rfk_update_swstate(tp_rfk);
+
+       return (res < 0) ? res : 0;
+}
+
+static const struct rfkill_ops tpacpi_rfk_rfkill_ops = {
+       .set_block = tpacpi_rfk_hook_set_block,
+};
+
+static int __init tpacpi_new_rfkill(const enum tpacpi_rfk_id id,
+                       const struct tpacpi_rfk_ops *tp_rfkops,
                        const enum rfkill_type rfktype,
                        const char *name,
-                       const bool set_default,
-                       int (*toggle_radio)(void *, enum rfkill_state),
-                       int (*get_state)(void *, enum rfkill_state *))
+                       const bool set_default)
 {
+       struct tpacpi_rfk *atp_rfk;
        int res;
-       enum rfkill_state initial_state = RFKILL_STATE_SOFT_BLOCKED;
-
-       res = get_state(NULL, &initial_state);
-       if (res < 0) {
-               printk(TPACPI_ERR
-                       "failed to read initial state for %s, error %d; "
-                       "will turn radio off\n", name, res);
-       } else if (set_default) {
-               /* try to set the initial state as the default for the rfkill
-                * type, since we ask the firmware to preserve it across S5 in
-                * NVRAM */
-               if (rfkill_set_default(rfktype,
-                               (initial_state == RFKILL_STATE_UNBLOCKED) ?
-                                       RFKILL_STATE_UNBLOCKED :
-                                       RFKILL_STATE_SOFT_BLOCKED) == -EPERM)
-                       vdbg_printk(TPACPI_DBG_RFKILL,
-                                   "Default state for %s cannot be changed\n",
-                                   name);
-       }
-
-       *rfk = rfkill_allocate(&tpacpi_pdev->dev, rfktype);
-       if (!*rfk) {
+       bool initial_sw_state = false;
+       int initial_sw_status;
+
+       BUG_ON(id >= TPACPI_RFK_SW_MAX || tpacpi_rfkill_switches[id]);
+
+       atp_rfk = kzalloc(sizeof(struct tpacpi_rfk), GFP_KERNEL);
+       if (atp_rfk)
+               atp_rfk->rfkill = rfkill_alloc(name,
+                                               &tpacpi_pdev->dev,
+                                               rfktype,
+                                               &tpacpi_rfk_rfkill_ops,
+                                               atp_rfk);
+       if (!atp_rfk || !atp_rfk->rfkill) {
                printk(TPACPI_ERR
                        "failed to allocate memory for rfkill class\n");
+               kfree(atp_rfk);
                return -ENOMEM;
        }
 
-       (*rfk)->name = name;
-       (*rfk)->get_state = get_state;
-       (*rfk)->toggle_radio = toggle_radio;
-       (*rfk)->state = initial_state;
+       atp_rfk->id = id;
+       atp_rfk->ops = tp_rfkops;
+
+       initial_sw_status = (tp_rfkops->get_status)();
+       if (initial_sw_status < 0) {
+               printk(TPACPI_ERR
+                       "failed to read initial state for %s, error %d\n",
+                       name, initial_sw_status);
+       } else {
+               initial_sw_state = (initial_sw_status == TPACPI_RFK_RADIO_OFF);
+               if (set_default) {
+                       /* try to keep the initial state, since we ask the
+                        * firmware to preserve it across S5 in NVRAM */
+                       rfkill_set_sw_state(atp_rfk->rfkill, initial_sw_state);
+               }
+       }
+       rfkill_set_hw_state(atp_rfk->rfkill, tpacpi_rfk_check_hwblock_state());
 
-       res = rfkill_register(*rfk);
+       res = rfkill_register(atp_rfk->rfkill);
        if (res < 0) {
                printk(TPACPI_ERR
                        "failed to register %s rfkill switch: %d\n",
                        name, res);
-               rfkill_free(*rfk);
-               *rfk = NULL;
+               rfkill_destroy(atp_rfk->rfkill);
+               kfree(atp_rfk);
                return res;
        }
 
+       tpacpi_rfkill_switches[id] = atp_rfk;
        return 0;
 }
 
-static void printk_deprecated_attribute(const char * const what,
-                                       const char * const details)
+static void tpacpi_destroy_rfkill(const enum tpacpi_rfk_id id)
 {
-       tpacpi_log_usertask("deprecated sysfs attribute");
-       printk(TPACPI_WARN "WARNING: sysfs attribute %s is deprecated and "
-               "will be removed. %s\n",
-               what, details);
+       struct tpacpi_rfk *tp_rfk;
+
+       BUG_ON(id >= TPACPI_RFK_SW_MAX);
+
+       tp_rfk = tpacpi_rfkill_switches[id];
+       if (tp_rfk) {
+               rfkill_unregister(tp_rfk->rfkill);
+               tpacpi_rfkill_switches[id] = NULL;
+               kfree(tp_rfk);
+       }
 }
 
 static void printk_deprecated_rfkill_attribute(const char * const what)
@@ -1074,6 +1234,112 @@ static void printk_deprecated_rfkill_attribute(const char * const what)
                        "Please switch to generic rfkill before year 2010");
 }
 
+/* sysfs <radio> enable ------------------------------------------------ */
+static ssize_t tpacpi_rfk_sysfs_enable_show(const enum tpacpi_rfk_id id,
+                                           struct device_attribute *attr,
+                                           char *buf)
+{
+       int status;
+
+       printk_deprecated_rfkill_attribute(attr->attr.name);
+
+       /* This is in the ABI... */
+       if (tpacpi_rfk_check_hwblock_state()) {
+               status = TPACPI_RFK_RADIO_OFF;
+       } else {
+               status = tpacpi_rfk_update_swstate(tpacpi_rfkill_switches[id]);
+               if (status < 0)
+                       return status;
+       }
+
+       return snprintf(buf, PAGE_SIZE, "%d\n",
+                       (status == TPACPI_RFK_RADIO_ON) ? 1 : 0);
+}
+
+static ssize_t tpacpi_rfk_sysfs_enable_store(const enum tpacpi_rfk_id id,
+                           struct device_attribute *attr,
+                           const char *buf, size_t count)
+{
+       unsigned long t;
+       int res;
+
+       printk_deprecated_rfkill_attribute(attr->attr.name);
+
+       if (parse_strtoul(buf, 1, &t))
+               return -EINVAL;
+
+       tpacpi_disclose_usertask(attr->attr.name, "set to %ld\n", t);
+
+       /* This is in the ABI... */
+       if (tpacpi_rfk_check_hwblock_state() && !!t)
+               return -EPERM;
+
+       res = tpacpi_rfkill_switches[id]->ops->set_status((!!t) ?
+                               TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF);
+       tpacpi_rfk_update_swstate(tpacpi_rfkill_switches[id]);
+
+       return (res < 0) ? res : count;
+}
+
+/* procfs -------------------------------------------------------------- */
+static int tpacpi_rfk_procfs_read(const enum tpacpi_rfk_id id, char *p)
+{
+       int len = 0;
+
+       if (id >= TPACPI_RFK_SW_MAX)
+               len += sprintf(p + len, "status:\t\tnot supported\n");
+       else {
+               int status;
+
+               /* This is in the ABI... */
+               if (tpacpi_rfk_check_hwblock_state()) {
+                       status = TPACPI_RFK_RADIO_OFF;
+               } else {
+                       status = tpacpi_rfk_update_swstate(
+                                               tpacpi_rfkill_switches[id]);
+                       if (status < 0)
+                               return status;
+               }
+
+               len += sprintf(p + len, "status:\t\t%s\n",
+                               (status == TPACPI_RFK_RADIO_ON) ?
+                                       "enabled" : "disabled");
+               len += sprintf(p + len, "commands:\tenable, disable\n");
+       }
+
+       return len;
+}
+
+static int tpacpi_rfk_procfs_write(const enum tpacpi_rfk_id id, char *buf)
+{
+       char *cmd;
+       int status = -1;
+       int res = 0;
+
+       if (id >= TPACPI_RFK_SW_MAX)
+               return -ENODEV;
+
+       while ((cmd = next_cmd(&buf))) {
+               if (strlencmp(cmd, "enable") == 0)
+                       status = TPACPI_RFK_RADIO_ON;
+               else if (strlencmp(cmd, "disable") == 0)
+                       status = TPACPI_RFK_RADIO_OFF;
+               else
+                       return -EINVAL;
+       }
+
+       if (status != -1) {
+               tpacpi_disclose_usertask("procfs", "attempt to %s %s\n",
+                               (status == TPACPI_RFK_RADIO_ON) ?
+                                               "enable" : "disable",
+                               tpacpi_rfkill_names[id]);
+               res = (tpacpi_rfkill_switches[id]->ops->set_status)(status);
+               tpacpi_rfk_update_swstate(tpacpi_rfkill_switches[id]);
+       }
+
+       return res;
+}
+
 /*************************************************************************
  * thinkpad-acpi driver attributes
  */
@@ -1127,8 +1393,6 @@ static DRIVER_ATTR(version, S_IRUGO,
 
 #ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
 
-static void tpacpi_send_radiosw_update(void);
-
 /* wlsw_emulstate ------------------------------------------------------ */
 static ssize_t tpacpi_driver_wlsw_emulstate_show(struct device_driver *drv,
                                                char *buf)
@@ -1144,11 +1408,10 @@ static ssize_t tpacpi_driver_wlsw_emulstate_store(struct device_driver *drv,
        if (parse_strtoul(buf, 1, &t))
                return -EINVAL;
 
-       if (tpacpi_wlsw_emulstate != t) {
-               tpacpi_wlsw_emulstate = !!t;
-               tpacpi_send_radiosw_update();
-       } else
+       if (tpacpi_wlsw_emulstate != !!t) {
                tpacpi_wlsw_emulstate = !!t;
+               tpacpi_rfk_update_hwblock_state(!t);    /* negative logic */
+       }
 
        return count;
 }
@@ -1463,17 +1726,23 @@ static struct attribute_set *hotkey_dev_attributes;
 /* HKEY.MHKG() return bits */
 #define TP_HOTKEY_TABLET_MASK (1 << 3)
 
-static int hotkey_get_wlsw(int *status)
+static int hotkey_get_wlsw(void)
 {
+       int status;
+
+       if (!tp_features.hotkey_wlsw)
+               return -ENODEV;
+
 #ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
-       if (dbg_wlswemul) {
-               *status = !!tpacpi_wlsw_emulstate;
-               return 0;
-       }
+       if (dbg_wlswemul)
+               return (tpacpi_wlsw_emulstate) ?
+                               TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF;
 #endif
-       if (!acpi_evalf(hkey_handle, status, "WLSW", "d"))
+
+       if (!acpi_evalf(hkey_handle, &status, "WLSW", "d"))
                return -EIO;
-       return 0;
+
+       return (status) ? TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF;
 }
 
 static int hotkey_get_tablet_mode(int *status)
@@ -2107,12 +2376,16 @@ static ssize_t hotkey_radio_sw_show(struct device *dev,
                           struct device_attribute *attr,
                           char *buf)
 {
-       int res, s;
-       res = hotkey_get_wlsw(&s);
+       int res;
+       res = hotkey_get_wlsw();
        if (res < 0)
                return res;
 
-       return snprintf(buf, PAGE_SIZE, "%d\n", !!s);
+       /* Opportunistic update */
+       tpacpi_rfk_update_hwblock_state((res == TPACPI_RFK_RADIO_OFF));
+
+       return snprintf(buf, PAGE_SIZE, "%d\n",
+                       (res == TPACPI_RFK_RADIO_OFF) ? 0 : 1);
 }
 
 static struct device_attribute dev_attr_hotkey_radio_sw =
@@ -2223,30 +2496,52 @@ static struct attribute *hotkey_mask_attributes[] __initdata = {
        &dev_attr_hotkey_wakeup_hotunplug_complete.attr,
 };
 
-static void bluetooth_update_rfk(void);
-static void wan_update_rfk(void);
-static void uwb_update_rfk(void);
+/*
+ * Sync both the hw and sw blocking state of all switches
+ */
 static void tpacpi_send_radiosw_update(void)
 {
        int wlsw;
 
-       /* Sync these BEFORE sending any rfkill events */
-       if (tp_features.bluetooth)
-               bluetooth_update_rfk();
-       if (tp_features.wan)
-               wan_update_rfk();
-       if (tp_features.uwb)
-               uwb_update_rfk();
+       /*
+        * We must sync all rfkill controllers *before* issuing any
+        * rfkill input events, or we will race the rfkill core input
+        * handler.
+        *
+        * tpacpi_inputdev_send_mutex works as a syncronization point
+        * for the above.
+        *
+        * We optimize to avoid numerous calls to hotkey_get_wlsw.
+        */
+
+       wlsw = hotkey_get_wlsw();
+
+       /* Sync hw blocking state first if it is hw-blocked */
+       if (wlsw == TPACPI_RFK_RADIO_OFF)
+               tpacpi_rfk_update_hwblock_state(true);
 
-       if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&wlsw)) {
+       /* Sync sw blocking state */
+       tpacpi_rfk_update_swstate_all();
+
+       /* Sync hw blocking state last if it is hw-unblocked */
+       if (wlsw == TPACPI_RFK_RADIO_ON)
+               tpacpi_rfk_update_hwblock_state(false);
+
+       /* Issue rfkill input event for WLSW switch */
+       if (!(wlsw < 0)) {
                mutex_lock(&tpacpi_inputdev_send_mutex);
 
                input_report_switch(tpacpi_inputdev,
-                                   SW_RFKILL_ALL, !!wlsw);
+                                   SW_RFKILL_ALL, (wlsw > 0));
                input_sync(tpacpi_inputdev);
 
                mutex_unlock(&tpacpi_inputdev_send_mutex);
        }
+
+       /*
+        * this can be unconditional, as we will poll state again
+        * if userspace uses the notify to read data
+        */
        hotkey_radio_sw_notify_change();
 }
 
@@ -3056,8 +3351,6 @@ enum {
 
 #define TPACPI_RFK_BLUETOOTH_SW_NAME   "tpacpi_bluetooth_sw"
 
-static struct rfkill *tpacpi_bluetooth_rfkill;
-
 static void bluetooth_suspend(pm_message_t state)
 {
        /* Try to make sure radio will resume powered off */
@@ -3067,83 +3360,47 @@ static void bluetooth_suspend(pm_message_t state)
                        "bluetooth power down on resume request failed\n");
 }
 
-static int bluetooth_get_radiosw(void)
+static int bluetooth_get_status(void)
 {
        int status;
 
-       if (!tp_features.bluetooth)
-               return -ENODEV;
-
-       /* WLSW overrides bluetooth in firmware/hardware, reflect that */
-       if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&status) && !status)
-               return RFKILL_STATE_HARD_BLOCKED;
-
 #ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
        if (dbg_bluetoothemul)
                return (tpacpi_bluetooth_emulstate) ?
-                       RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED;
+                      TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF;
 #endif
 
        if (!acpi_evalf(hkey_handle, &status, "GBDC", "d"))
                return -EIO;
 
        return ((status & TP_ACPI_BLUETOOTH_RADIOSSW) != 0) ?
-               RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED;
-}
-
-static void bluetooth_update_rfk(void)
-{
-       int status;
-
-       if (!tpacpi_bluetooth_rfkill)
-               return;
-
-       status = bluetooth_get_radiosw();
-       if (status < 0)
-               return;
-       rfkill_force_state(tpacpi_bluetooth_rfkill, status);
-
-       vdbg_printk(TPACPI_DBG_RFKILL,
-               "forced rfkill state to %d\n",
-               status);
+                       TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF;
 }
 
-static int bluetooth_set_radiosw(int radio_on, int update_rfk)
+static int bluetooth_set_status(enum tpacpi_rfkill_state state)
 {
        int status;
 
-       if (!tp_features.bluetooth)
-               return -ENODEV;
-
-       /* WLSW overrides bluetooth in firmware/hardware, but there is no
-        * reason to risk weird behaviour. */
-       if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&status) && !status
-           && radio_on)
-               return -EPERM;
-
        vdbg_printk(TPACPI_DBG_RFKILL,
-               "will %s bluetooth\n", radio_on ? "enable" : "disable");
+               "will attempt to %s bluetooth\n",
+               (state == TPACPI_RFK_RADIO_ON) ? "enable" : "disable");
 
 #ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
        if (dbg_bluetoothemul) {
-               tpacpi_bluetooth_emulstate = !!radio_on;
-               if (update_rfk)
-                       bluetooth_update_rfk();
+               tpacpi_bluetooth_emulstate = (state == TPACPI_RFK_RADIO_ON);
                return 0;
        }
 #endif
 
        /* We make sure to keep TP_ACPI_BLUETOOTH_RESUMECTRL off */
-       if (radio_on)
+       if (state == TPACPI_RFK_RADIO_ON)
                status = TP_ACPI_BLUETOOTH_RADIOSSW;
        else
                status = 0;
+
        if (!acpi_evalf(hkey_handle, NULL, "SBDC", "vd", status))
                return -EIO;
 
-       if (update_rfk)
-               bluetooth_update_rfk();
-
        return 0;
 }
 
@@ -3152,35 +3409,16 @@ static ssize_t bluetooth_enable_show(struct device *dev,
                           struct device_attribute *attr,
                           char *buf)
 {
-       int status;
-
-       printk_deprecated_rfkill_attribute("bluetooth_enable");
-
-       status = bluetooth_get_radiosw();
-       if (status < 0)
-               return status;
-
-       return snprintf(buf, PAGE_SIZE, "%d\n",
-                       (status == RFKILL_STATE_UNBLOCKED) ? 1 : 0);
+       return tpacpi_rfk_sysfs_enable_show(TPACPI_RFK_BLUETOOTH_SW_ID,
+                       attr, buf);
 }
 
 static ssize_t bluetooth_enable_store(struct device *dev,
                            struct device_attribute *attr,
                            const char *buf, size_t count)
 {
-       unsigned long t;
-       int res;
-
-       printk_deprecated_rfkill_attribute("bluetooth_enable");
-
-       if (parse_strtoul(buf, 1, &t))
-               return -EINVAL;
-
-       tpacpi_disclose_usertask("bluetooth_enable", "set to %ld\n", t);
-
-       res = bluetooth_set_radiosw(t, 1);
-
-       return (res) ? res : count;
+       return tpacpi_rfk_sysfs_enable_store(TPACPI_RFK_BLUETOOTH_SW_ID,
+                               attr, buf, count);
 }
 
 static struct device_attribute dev_attr_bluetooth_enable =
@@ -3198,23 +3436,10 @@ static const struct attribute_group bluetooth_attr_group = {
        .attrs = bluetooth_attributes,
 };
 
-static int tpacpi_bluetooth_rfk_get(void *data, enum rfkill_state *state)
-{
-       int bts = bluetooth_get_radiosw();
-
-       if (bts < 0)
-               return bts;
-
-       *state = bts;
-       return 0;
-}
-
-static int tpacpi_bluetooth_rfk_set(void *data, enum rfkill_state state)
-{
-       dbg_printk(TPACPI_DBG_RFKILL,
-                  "request to change radio state to %d\n", state);
-       return bluetooth_set_radiosw((state == RFKILL_STATE_UNBLOCKED), 0);
-}
+static const struct tpacpi_rfk_ops bluetooth_tprfk_ops = {
+       .get_status = bluetooth_get_status,
+       .set_status = bluetooth_set_status,
+};
 
 static void bluetooth_shutdown(void)
 {
@@ -3230,13 +3455,12 @@ static void bluetooth_shutdown(void)
 
 static void bluetooth_exit(void)
 {
-       bluetooth_shutdown();
-
-       if (tpacpi_bluetooth_rfkill)
-               rfkill_unregister(tpacpi_bluetooth_rfkill);
-
        sysfs_remove_group(&tpacpi_pdev->dev.kobj,
                        &bluetooth_attr_group);
+
+       tpacpi_destroy_rfkill(TPACPI_RFK_BLUETOOTH_SW_ID);
+
+       bluetooth_shutdown();
 }
 
 static int __init bluetooth_init(struct ibm_init_struct *iibm)
@@ -3277,20 +3501,18 @@ static int __init bluetooth_init(struct ibm_init_struct *iibm)
        if (!tp_features.bluetooth)
                return 1;
 
-       res = sysfs_create_group(&tpacpi_pdev->dev.kobj,
-                               &bluetooth_attr_group);
-       if (res)
-               return res;
-
        res = tpacpi_new_rfkill(TPACPI_RFK_BLUETOOTH_SW_ID,
-                               &tpacpi_bluetooth_rfkill,
+                               &bluetooth_tprfk_ops,
                                RFKILL_TYPE_BLUETOOTH,
                                TPACPI_RFK_BLUETOOTH_SW_NAME,
-                               true,
-                               tpacpi_bluetooth_rfk_set,
-                               tpacpi_bluetooth_rfk_get);
+                               true);
+       if (res)
+               return res;
+
+       res = sysfs_create_group(&tpacpi_pdev->dev.kobj,
+                               &bluetooth_attr_group);
        if (res) {
-               bluetooth_exit();
+               tpacpi_destroy_rfkill(TPACPI_RFK_BLUETOOTH_SW_ID);
                return res;
        }
 
@@ -3300,46 +3522,12 @@ static int __init bluetooth_init(struct ibm_init_struct *iibm)
 /* procfs -------------------------------------------------------------- */
 static int bluetooth_read(char *p)
 {
-       int len = 0;
-       int status = bluetooth_get_radiosw();
-
-       if (!tp_features.bluetooth)
-               len += sprintf(p + len, "status:\t\tnot supported\n");
-       else {
-               len += sprintf(p + len, "status:\t\t%s\n",
-                               (status == RFKILL_STATE_UNBLOCKED) ?
-                                       "enabled" : "disabled");
-               len += sprintf(p + len, "commands:\tenable, disable\n");
-       }
-
-       return len;
+       return tpacpi_rfk_procfs_read(TPACPI_RFK_BLUETOOTH_SW_ID, p);
 }
 
 static int bluetooth_write(char *buf)
 {
-       char *cmd;
-       int state = -1;
-
-       if (!tp_features.bluetooth)
-               return -ENODEV;
-
-       while ((cmd = next_cmd(&buf))) {
-               if (strlencmp(cmd, "enable") == 0) {
-                       state = 1;
-               } else if (strlencmp(cmd, "disable") == 0) {
-                       state = 0;
-               } else
-                       return -EINVAL;
-       }
-
-       if (state != -1) {
-               tpacpi_disclose_usertask("procfs bluetooth",
-                       "attempt to %s\n",
-                       state ? "enable" : "disable");
-               bluetooth_set_radiosw(state, 1);
-       }
-
-       return 0;
+       return tpacpi_rfk_procfs_write(TPACPI_RFK_BLUETOOTH_SW_ID, buf);
 }
 
 static struct ibm_struct bluetooth_driver_data = {
@@ -3365,8 +3553,6 @@ enum {
 
 #define TPACPI_RFK_WWAN_SW_NAME                "tpacpi_wwan_sw"
 
-static struct rfkill *tpacpi_wan_rfkill;
-
 static void wan_suspend(pm_message_t state)
 {
        /* Try to make sure radio will resume powered off */
@@ -3376,83 +3562,47 @@ static void wan_suspend(pm_message_t state)
                        "WWAN power down on resume request failed\n");
 }
 
-static int wan_get_radiosw(void)
+static int wan_get_status(void)
 {
        int status;
 
-       if (!tp_features.wan)
-               return -ENODEV;
-
-       /* WLSW overrides WWAN in firmware/hardware, reflect that */
-       if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&status) && !status)
-               return RFKILL_STATE_HARD_BLOCKED;
-
 #ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
        if (dbg_wwanemul)
                return (tpacpi_wwan_emulstate) ?
-                       RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED;
+                      TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF;
 #endif
 
        if (!acpi_evalf(hkey_handle, &status, "GWAN", "d"))
                return -EIO;
 
        return ((status & TP_ACPI_WANCARD_RADIOSSW) != 0) ?
-               RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED;
-}
-
-static void wan_update_rfk(void)
-{
-       int status;
-
-       if (!tpacpi_wan_rfkill)
-               return;
-
-       status = wan_get_radiosw();
-       if (status < 0)
-               return;
-       rfkill_force_state(tpacpi_wan_rfkill, status);
-
-       vdbg_printk(TPACPI_DBG_RFKILL,
-               "forced rfkill state to %d\n",
-               status);
+                       TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF;
 }
 
-static int wan_set_radiosw(int radio_on, int update_rfk)
+static int wan_set_status(enum tpacpi_rfkill_state state)
 {
        int status;
 
-       if (!tp_features.wan)
-               return -ENODEV;
-
-       /* WLSW overrides bluetooth in firmware/hardware, but there is no
-        * reason to risk weird behaviour. */
-       if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&status) && !status
-           && radio_on)
-               return -EPERM;
-
        vdbg_printk(TPACPI_DBG_RFKILL,
-               "will %s WWAN\n", radio_on ? "enable" : "disable");
+               "will attempt to %s wwan\n",
+               (state == TPACPI_RFK_RADIO_ON) ? "enable" : "disable");
 
 #ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
        if (dbg_wwanemul) {
-               tpacpi_wwan_emulstate = !!radio_on;
-               if (update_rfk)
-                       wan_update_rfk();
+               tpacpi_wwan_emulstate = (state == TPACPI_RFK_RADIO_ON);
                return 0;
        }
 #endif
 
        /* We make sure to keep TP_ACPI_WANCARD_RESUMECTRL off */
-       if (radio_on)
+       if (state == TPACPI_RFK_RADIO_ON)
                status = TP_ACPI_WANCARD_RADIOSSW;
        else
                status = 0;
+
        if (!acpi_evalf(hkey_handle, NULL, "SWAN", "vd", status))
                return -EIO;
 
-       if (update_rfk)
-               wan_update_rfk();
-
        return 0;
 }
 
@@ -3461,35 +3611,16 @@ static ssize_t wan_enable_show(struct device *dev,
                           struct device_attribute *attr,
                           char *buf)
 {
-       int status;
-
-       printk_deprecated_rfkill_attribute("wwan_enable");
-
-       status = wan_get_radiosw();
-       if (status < 0)
-               return status;
-
-       return snprintf(buf, PAGE_SIZE, "%d\n",
-                       (status == RFKILL_STATE_UNBLOCKED) ? 1 : 0);
+       return tpacpi_rfk_sysfs_enable_show(TPACPI_RFK_WWAN_SW_ID,
+                       attr, buf);
 }
 
 static ssize_t wan_enable_store(struct device *dev,
                            struct device_attribute *attr,
                            const char *buf, size_t count)
 {
-       unsigned long t;
-       int res;
-
-       printk_deprecated_rfkill_attribute("wwan_enable");
-
-       if (parse_strtoul(buf, 1, &t))
-               return -EINVAL;
-
-       tpacpi_disclose_usertask("wwan_enable", "set to %ld\n", t);
-
-       res = wan_set_radiosw(t, 1);
-
-       return (res) ? res : count;
+       return tpacpi_rfk_sysfs_enable_store(TPACPI_RFK_WWAN_SW_ID,
+                       attr, buf, count);
 }
 
 static struct device_attribute dev_attr_wan_enable =
@@ -3507,23 +3638,10 @@ static const struct attribute_group wan_attr_group = {
        .attrs = wan_attributes,
 };
 
-static int tpacpi_wan_rfk_get(void *data, enum rfkill_state *state)
-{
-       int wans = wan_get_radiosw();
-
-       if (wans < 0)
-               return wans;
-
-       *state = wans;
-       return 0;
-}
-
-static int tpacpi_wan_rfk_set(void *data, enum rfkill_state state)
-{
-       dbg_printk(TPACPI_DBG_RFKILL,
-                  "request to change radio state to %d\n", state);
-       return wan_set_radiosw((state == RFKILL_STATE_UNBLOCKED), 0);
-}
+static const struct tpacpi_rfk_ops wan_tprfk_ops = {
+       .get_status = wan_get_status,
+       .set_status = wan_set_status,
+};
 
 static void wan_shutdown(void)
 {
@@ -3539,13 +3657,12 @@ static void wan_shutdown(void)
 
 static void wan_exit(void)
 {
-       wan_shutdown();
-
-       if (tpacpi_wan_rfkill)
-               rfkill_unregister(tpacpi_wan_rfkill);
-
        sysfs_remove_group(&tpacpi_pdev->dev.kobj,
                &wan_attr_group);
+
+       tpacpi_destroy_rfkill(TPACPI_RFK_WWAN_SW_ID);
+
+       wan_shutdown();
 }
 
 static int __init wan_init(struct ibm_init_struct *iibm)
@@ -3584,20 +3701,19 @@ static int __init wan_init(struct ibm_init_struct *iibm)
        if (!tp_features.wan)
                return 1;
 
-       res = sysfs_create_group(&tpacpi_pdev->dev.kobj,
-                               &wan_attr_group);
-       if (res)
-               return res;
-
        res = tpacpi_new_rfkill(TPACPI_RFK_WWAN_SW_ID,
-                               &tpacpi_wan_rfkill,
+                               &wan_tprfk_ops,
                                RFKILL_TYPE_WWAN,
                                TPACPI_RFK_WWAN_SW_NAME,
-                               true,
-                               tpacpi_wan_rfk_set,
-                               tpacpi_wan_rfk_get);
+                               true);
+       if (res)
+               return res;
+
+       res = sysfs_create_group(&tpacpi_pdev->dev.kobj,
+                               &wan_attr_group);
+
        if (res) {
-               wan_exit();
+               tpacpi_destroy_rfkill(TPACPI_RFK_WWAN_SW_ID);
                return res;
        }
 
@@ -3607,48 +3723,12 @@ static int __init wan_init(struct ibm_init_struct *iibm)
 /* procfs -------------------------------------------------------------- */
 static int wan_read(char *p)
 {
-       int len = 0;
-       int status = wan_get_radiosw();
-
-       tpacpi_disclose_usertask("procfs wan", "read");
-
-       if (!tp_features.wan)
-               len += sprintf(p + len, "status:\t\tnot supported\n");
-       else {
-               len += sprintf(p + len, "status:\t\t%s\n",
-                               (status == RFKILL_STATE_UNBLOCKED) ?
-                                       "enabled" : "disabled");
-               len += sprintf(p + len, "commands:\tenable, disable\n");
-       }
-
-       return len;
+       return tpacpi_rfk_procfs_read(TPACPI_RFK_WWAN_SW_ID, p);
 }
 
 static int wan_write(char *buf)
 {
-       char *cmd;
-       int state = -1;
-
-       if (!tp_features.wan)
-               return -ENODEV;
-
-       while ((cmd = next_cmd(&buf))) {
-               if (strlencmp(cmd, "enable") == 0) {
-                       state = 1;
-               } else if (strlencmp(cmd, "disable") == 0) {
-                       state = 0;
-               } else
-                       return -EINVAL;
-       }
-
-       if (state != -1) {
-               tpacpi_disclose_usertask("procfs wan",
-                       "attempt to %s\n",
-                       state ? "enable" : "disable");
-               wan_set_radiosw(state, 1);
-       }
-
-       return 0;
+       return tpacpi_rfk_procfs_write(TPACPI_RFK_WWAN_SW_ID, buf);
 }
 
 static struct ibm_struct wan_driver_data = {
@@ -3672,108 +3752,59 @@ enum {
 
 #define TPACPI_RFK_UWB_SW_NAME "tpacpi_uwb_sw"
 
-static struct rfkill *tpacpi_uwb_rfkill;
-
-static int uwb_get_radiosw(void)
+static int uwb_get_status(void)
 {
        int status;
 
-       if (!tp_features.uwb)
-               return -ENODEV;
-
-       /* WLSW overrides UWB in firmware/hardware, reflect that */
-       if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&status) && !status)
-               return RFKILL_STATE_HARD_BLOCKED;
-
 #ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
        if (dbg_uwbemul)
                return (tpacpi_uwb_emulstate) ?
-                       RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED;
+                      TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF;
 #endif
 
        if (!acpi_evalf(hkey_handle, &status, "GUWB", "d"))
                return -EIO;
 
        return ((status & TP_ACPI_UWB_RADIOSSW) != 0) ?
-               RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED;
+                       TPACPI_RFK_RADIO_ON : TPACPI_RFK_RADIO_OFF;
 }
 
-static void uwb_update_rfk(void)
+static int uwb_set_status(enum tpacpi_rfkill_state state)
 {
        int status;
 
-       if (!tpacpi_uwb_rfkill)
-               return;
-
-       status = uwb_get_radiosw();
-       if (status < 0)
-               return;
-       rfkill_force_state(tpacpi_uwb_rfkill, status);
-
        vdbg_printk(TPACPI_DBG_RFKILL,
-               "forced rfkill state to %d\n",
-               status);
-}
-
-static int uwb_set_radiosw(int radio_on, int update_rfk)
-{
-       int status;
-
-       if (!tp_features.uwb)
-               return -ENODEV;
-
-       /* WLSW overrides UWB in firmware/hardware, but there is no
-        * reason to risk weird behaviour. */
-       if (tp_features.hotkey_wlsw && !hotkey_get_wlsw(&status) && !status
-           && radio_on)
-               return -EPERM;
-
-       vdbg_printk(TPACPI_DBG_RFKILL,
-                       "will %s UWB\n", radio_on ? "enable" : "disable");
+               "will attempt to %s UWB\n",
+               (state == TPACPI_RFK_RADIO_ON) ? "enable" : "disable");
 
 #ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
        if (dbg_uwbemul) {
-               tpacpi_uwb_emulstate = !!radio_on;
-               if (update_rfk)
-                       uwb_update_rfk();
+               tpacpi_uwb_emulstate = (state == TPACPI_RFK_RADIO_ON);
                return 0;
        }
 #endif
 
-       status = (radio_on) ? TP_ACPI_UWB_RADIOSSW : 0;
+       if (state == TPACPI_RFK_RADIO_ON)
+               status = TP_ACPI_UWB_RADIOSSW;
+       else
+               status = 0;
+
        if (!acpi_evalf(hkey_handle, NULL, "SUWB", "vd", status))
                return -EIO;
 
-       if (update_rfk)
-               uwb_update_rfk();
-
        return 0;
 }
 
 /* --------------------------------------------------------------------- */
 
-static int tpacpi_uwb_rfk_get(void *data, enum rfkill_state *state)
-{
-       int uwbs = uwb_get_radiosw();
-
-       if (uwbs < 0)
-               return uwbs;
-
-       *state = uwbs;
-       return 0;
-}
-
-static int tpacpi_uwb_rfk_set(void *data, enum rfkill_state state)
-{
-       dbg_printk(TPACPI_DBG_RFKILL,
-                  "request to change radio state to %d\n", state);
-       return uwb_set_radiosw((state == RFKILL_STATE_UNBLOCKED), 0);
-}
+static const struct tpacpi_rfk_ops uwb_tprfk_ops = {
+       .get_status = uwb_get_status,
+       .set_status = uwb_set_status,
+};
 
 static void uwb_exit(void)
 {
-       if (tpacpi_uwb_rfkill)
-               rfkill_unregister(tpacpi_uwb_rfkill);
+       tpacpi_destroy_rfkill(TPACPI_RFK_UWB_SW_ID);
 }
 
 static int __init uwb_init(struct ibm_init_struct *iibm)
@@ -3813,13 +3844,10 @@ static int __init uwb_init(struct ibm_init_struct *iibm)
                return 1;
 
        res = tpacpi_new_rfkill(TPACPI_RFK_UWB_SW_ID,
-                               &tpacpi_uwb_rfkill,
+                               &uwb_tprfk_ops,
                                RFKILL_TYPE_UWB,
                                TPACPI_RFK_UWB_SW_NAME,
-                               false,
-                               tpacpi_uwb_rfk_set,
-                               tpacpi_uwb_rfk_get);
-
+                               false);
        return res;
 }
 
index 9f187265db8e260d201b167bc0095e8bd4757765..81d31ea507d116e3186384d7a0a394d00dc0e3ae 100644 (file)
@@ -45,7 +45,6 @@
 #include <linux/backlight.h>
 #include <linux/platform_device.h>
 #include <linux/rfkill.h>
-#include <linux/input-polldev.h>
 
 #include <asm/uaccess.h>
 
@@ -250,21 +249,15 @@ static acpi_status hci_read2(u32 reg, u32 *out1, u32 *out2, u32 *result)
 
 struct toshiba_acpi_dev {
        struct platform_device *p_dev;
-       struct rfkill *rfk_dev;
-       struct input_polled_dev *poll_dev;
+       struct rfkill *bt_rfk;
 
        const char *bt_name;
-       const char *rfk_name;
-
-       bool last_rfk_state;
 
        struct mutex mutex;
 };
 
 static struct toshiba_acpi_dev toshiba_acpi = {
        .bt_name = "Toshiba Bluetooth",
-       .rfk_name = "Toshiba RFKill Switch",
-       .last_rfk_state = false,
 };
 
 /* Bluetooth rfkill handlers */
@@ -283,21 +276,6 @@ static u32 hci_get_bt_present(bool *present)
        return hci_result;
 }
 
-static u32 hci_get_bt_on(bool *on)
-{
-       u32 hci_result;
-       u32 value, value2;
-
-       value = 0;
-       value2 = 0x0001;
-       hci_read2(HCI_WIRELESS, &value, &value2, &hci_result);
-       if (hci_result == HCI_SUCCESS)
-               *on = (value & HCI_WIRELESS_BT_POWER) &&
-                     (value & HCI_WIRELESS_BT_ATTACH);
-
-       return hci_result;
-}
-
 static u32 hci_get_radio_state(bool *radio_state)
 {
        u32 hci_result;
@@ -311,70 +289,67 @@ static u32 hci_get_radio_state(bool *radio_state)
        return hci_result;
 }
 
-static int bt_rfkill_toggle_radio(void *data, enum rfkill_state state)
+static int bt_rfkill_set_block(void *data, bool blocked)
 {
+       struct toshiba_acpi_dev *dev = data;
        u32 result1, result2;
        u32 value;
+       int err;
        bool radio_state;
-       struct toshiba_acpi_dev *dev = data;
 
-       value = (state == RFKILL_STATE_UNBLOCKED);
+       value = (blocked == false);
 
-       if (hci_get_radio_state(&radio_state) != HCI_SUCCESS)
-               return -EFAULT;
+       mutex_lock(&dev->mutex);
+       if (hci_get_radio_state(&radio_state) != HCI_SUCCESS) {
+               err = -EBUSY;
+               goto out;
+       }
 
-       switch (state) {
-       case RFKILL_STATE_UNBLOCKED:
-               if (!radio_state)
-                       return -EPERM;
-               break;
-       case RFKILL_STATE_SOFT_BLOCKED:
-               break;
-       default:
-               return -EINVAL;
+       if (!radio_state) {
+               err = 0;
+               goto out;
        }
 
-       mutex_lock(&dev->mutex);
        hci_write2(HCI_WIRELESS, value, HCI_WIRELESS_BT_POWER, &result1);
        hci_write2(HCI_WIRELESS, value, HCI_WIRELESS_BT_ATTACH, &result2);
-       mutex_unlock(&dev->mutex);
 
        if (result1 != HCI_SUCCESS || result2 != HCI_SUCCESS)
-               return -EFAULT;
-
-       return 0;
+               err = -EBUSY;
+       else
+               err = 0;
+ out:
+       mutex_unlock(&dev->mutex);
+       return err;
 }
 
-static void bt_poll_rfkill(struct input_polled_dev *poll_dev)
+static void bt_rfkill_poll(struct rfkill *rfkill, void *data)
 {
-       bool state_changed;
        bool new_rfk_state;
        bool value;
        u32 hci_result;
-       struct toshiba_acpi_dev *dev = poll_dev->private;
+       struct toshiba_acpi_dev *dev = data;
+
+       mutex_lock(&dev->mutex);
 
        hci_result = hci_get_radio_state(&value);
-       if (hci_result != HCI_SUCCESS)
-               return; /* Can't do anything useful */
+       if (hci_result != HCI_SUCCESS) {
+               /* Can't do anything useful */
+               mutex_unlock(&dev->mutex);
+       }
 
        new_rfk_state = value;
 
-       mutex_lock(&dev->mutex);
-       state_changed = new_rfk_state != dev->last_rfk_state;
-       dev->last_rfk_state = new_rfk_state;
        mutex_unlock(&dev->mutex);
 
-       if (unlikely(state_changed)) {
-               rfkill_force_state(dev->rfk_dev,
-                                  new_rfk_state ?
-                                  RFKILL_STATE_SOFT_BLOCKED :
-                                  RFKILL_STATE_HARD_BLOCKED);
-               input_report_switch(poll_dev->input, SW_RFKILL_ALL,
-                                   new_rfk_state);
-               input_sync(poll_dev->input);
-       }
+       if (rfkill_set_hw_state(rfkill, !new_rfk_state))
+               bt_rfkill_set_block(data, true);
 }
 
+static const struct rfkill_ops toshiba_rfk_ops = {
+       .set_block = bt_rfkill_set_block,
+       .poll = bt_rfkill_poll,
+};
+
 static struct proc_dir_entry *toshiba_proc_dir /*= 0*/ ;
 static struct backlight_device *toshiba_backlight_device;
 static int force_fan;
@@ -702,14 +677,11 @@ static struct backlight_ops toshiba_backlight_data = {
 
 static void toshiba_acpi_exit(void)
 {
-       if (toshiba_acpi.poll_dev) {
-               input_unregister_polled_device(toshiba_acpi.poll_dev);
-               input_free_polled_device(toshiba_acpi.poll_dev);
+       if (toshiba_acpi.bt_rfk) {
+               rfkill_unregister(toshiba_acpi.bt_rfk);
+               rfkill_destroy(toshiba_acpi.bt_rfk);
        }
 
-       if (toshiba_acpi.rfk_dev)
-               rfkill_unregister(toshiba_acpi.rfk_dev);
-
        if (toshiba_backlight_device)
                backlight_device_unregister(toshiba_backlight_device);
 
@@ -728,8 +700,6 @@ static int __init toshiba_acpi_init(void)
        acpi_status status = AE_OK;
        u32 hci_result;
        bool bt_present;
-       bool bt_on;
-       bool radio_on;
        int ret = 0;
 
        if (acpi_disabled)
@@ -793,61 +763,21 @@ static int __init toshiba_acpi_init(void)
 
        /* Register rfkill switch for Bluetooth */
        if (hci_get_bt_present(&bt_present) == HCI_SUCCESS && bt_present) {
-               toshiba_acpi.rfk_dev = rfkill_allocate(&toshiba_acpi.p_dev->dev,
-                                                       RFKILL_TYPE_BLUETOOTH);
-               if (!toshiba_acpi.rfk_dev) {
+               toshiba_acpi.bt_rfk = rfkill_alloc(toshiba_acpi.bt_name,
+                                                  &toshiba_acpi.p_dev->dev,
+                                                  RFKILL_TYPE_BLUETOOTH,
+                                                  &toshiba_rfk_ops,
+                                                  &toshiba_acpi);
+               if (!toshiba_acpi.bt_rfk) {
                        printk(MY_ERR "unable to allocate rfkill device\n");
                        toshiba_acpi_exit();
                        return -ENOMEM;
                }
 
-               toshiba_acpi.rfk_dev->name = toshiba_acpi.bt_name;
-               toshiba_acpi.rfk_dev->toggle_radio = bt_rfkill_toggle_radio;
-               toshiba_acpi.rfk_dev->user_claim_unsupported = 1;
-               toshiba_acpi.rfk_dev->data = &toshiba_acpi;
-
-               if (hci_get_bt_on(&bt_on) == HCI_SUCCESS && bt_on) {
-                       toshiba_acpi.rfk_dev->state = RFKILL_STATE_UNBLOCKED;
-               } else if (hci_get_radio_state(&radio_on) == HCI_SUCCESS &&
-                          radio_on) {
-                       toshiba_acpi.rfk_dev->state = RFKILL_STATE_SOFT_BLOCKED;
-               } else {
-                       toshiba_acpi.rfk_dev->state = RFKILL_STATE_HARD_BLOCKED;
-               }
-
-               ret = rfkill_register(toshiba_acpi.rfk_dev);
+               ret = rfkill_register(toshiba_acpi.bt_rfk);
                if (ret) {
                        printk(MY_ERR "unable to register rfkill device\n");
-                       toshiba_acpi_exit();
-                       return -ENOMEM;
-               }
-
-               /* Register input device for kill switch */
-               toshiba_acpi.poll_dev = input_allocate_polled_device();
-               if (!toshiba_acpi.poll_dev) {
-                       printk(MY_ERR
-                              "unable to allocate kill-switch input device\n");
-                       toshiba_acpi_exit();
-                       return -ENOMEM;
-               }
-               toshiba_acpi.poll_dev->private = &toshiba_acpi;
-               toshiba_acpi.poll_dev->poll = bt_poll_rfkill;
-               toshiba_acpi.poll_dev->poll_interval = 1000; /* msecs */
-
-               toshiba_acpi.poll_dev->input->name = toshiba_acpi.rfk_name;
-               toshiba_acpi.poll_dev->input->id.bustype = BUS_HOST;
-               /* Toshiba USB ID */
-               toshiba_acpi.poll_dev->input->id.vendor = 0x0930;
-               set_bit(EV_SW, toshiba_acpi.poll_dev->input->evbit);
-               set_bit(SW_RFKILL_ALL, toshiba_acpi.poll_dev->input->swbit);
-               input_report_switch(toshiba_acpi.poll_dev->input,
-                                   SW_RFKILL_ALL, TRUE);
-               input_sync(toshiba_acpi.poll_dev->input);
-
-               ret = input_register_polled_device(toshiba_acpi.poll_dev);
-               if (ret) {
-                       printk(MY_ERR
-                              "unable to register kill-switch input device\n");
+                       rfkill_destroy(toshiba_acpi.bt_rfk);
                        toshiba_acpi_exit();
                        return ret;
                }
index 74d0bfa3f3108c020ed9c7b59a0262e8549188df..3b78540288c773dd4f4e9669904475cba81acb0a 100644 (file)
@@ -290,7 +290,7 @@ static void __devinit rio_add_device(struct rio_dev *rdev)
  * to a RIO device on success or NULL on failure.
  *
  */
-static struct rio_dev *rio_setup_device(struct rio_net *net,
+static struct rio_dev __devinit *rio_setup_device(struct rio_net *net,
                                        struct rio_mport *port, u16 destid,
                                        u8 hopcount, int do_enum)
 {
@@ -559,7 +559,7 @@ static void rio_net_add_mport(struct rio_net *net, struct rio_mport *port)
  * Recursively enumerates a RIO network.  Transactions are sent via the
  * master port passed in @port.
  */
-static int rio_enum_peer(struct rio_net *net, struct rio_mport *port,
+static int __devinit rio_enum_peer(struct rio_net *net, struct rio_mport *port,
                         u8 hopcount)
 {
        int port_num;
@@ -718,7 +718,7 @@ static int rio_enum_complete(struct rio_mport *port)
  * Recursively discovers a RIO network.  Transactions are sent via the
  * master port passed in @port.
  */
-static int
+static int __devinit
 rio_disc_peer(struct rio_net *net, struct rio_mport *port, u16 destid,
              u8 hopcount)
 {
index e58c0ce65aa6d4f6cf750feba06591df4d4ca33c..f4317798e47ccdab3c09cfead840ccebc93fc771 100644 (file)
@@ -47,6 +47,16 @@ config REGULATOR_VIRTUAL_CONSUMER
 
           If unsure, say no.
 
+config REGULATOR_USERSPACE_CONSUMER
+       tristate "Userspace regulator consumer support"
+       default n
+       help
+         There are some classes of devices that are controlled entirely
+         from user space. Usersapce consumer driver provides ability to
+         control power supplies for such devices.
+
+          If unsure, say no.
+
 config REGULATOR_BQ24022
        tristate "TI bq24022 Dual Input 1-Cell Li-Ion Charger IC"
        default n
@@ -56,6 +66,15 @@ config REGULATOR_BQ24022
          charging select between 100 mA and 500 mA charging current
          limit.
 
+config REGULATOR_MAX1586
+       tristate "Maxim 1586/1587 voltage regulator"
+       depends on I2C
+       default n
+       help
+         This driver controls a Maxim 1586 or 1587 voltage output
+         regulator via I2C bus. The provided regulator is suitable
+         for PXA27x chips to control VCC_CORE and VCC_USIM voltages.
+
 config REGULATOR_TWL4030
        bool "TI TWL4030/TWL5030/TPS695x0 PMIC"
        depends on TWL4030_CORE
@@ -91,4 +110,11 @@ config REGULATOR_PCF50633
         Say Y here to support the voltage regulators and convertors
         on PCF50633
 
+config REGULATOR_LP3971
+       tristate "National Semiconductors LP3971 PMIC regulator driver"
+       depends on I2C
+       help
+        Say Y here to support the voltage regulators and convertors
+        on National Semiconductors LP3971 PMIC
+
 endif
index bac133afc061473f8cd74662fe9a7af091bba239..4d762c4cccfdf4c26e530ee381a4414e4b2b27e6 100644 (file)
@@ -6,8 +6,11 @@
 obj-$(CONFIG_REGULATOR) += core.o
 obj-$(CONFIG_REGULATOR_FIXED_VOLTAGE) += fixed.o
 obj-$(CONFIG_REGULATOR_VIRTUAL_CONSUMER) += virtual.o
+obj-$(CONFIG_REGULATOR_USERSPACE_CONSUMER) += userspace-consumer.o
 
 obj-$(CONFIG_REGULATOR_BQ24022) += bq24022.o
+obj-$(CONFIG_REGULATOR_LP3971) += lp3971.o
+obj-$(CONFIG_REGULATOR_MAX1586) += max1586.o
 obj-$(CONFIG_REGULATOR_TWL4030) += twl4030-regulator.o
 obj-$(CONFIG_REGULATOR_WM8350) += wm8350-regulator.o
 obj-$(CONFIG_REGULATOR_WM8400) += wm8400-regulator.o
index c6628f5a0af7b337fa2ad1426a81e0468a7f1ddc..b8b89ef10a84abdbc44573e30f0fb7c7d545b16d 100644 (file)
@@ -504,7 +504,7 @@ static int __init da903x_regulator_init(void)
 {
        return platform_driver_register(&da903x_regulator_driver);
 }
-module_init(da903x_regulator_init);
+subsys_initcall(da903x_regulator_init);
 
 static void __exit da903x_regulator_exit(void)
 {
index 23d554628a76128e6786bb9666a67c0179e4ec32..cdc674fb46c3371192c7b2975df97ac9794a3e0d 100644 (file)
@@ -44,10 +44,22 @@ static int fixed_voltage_get_voltage(struct regulator_dev *dev)
        return data->microvolts;
 }
 
+static int fixed_voltage_list_voltage(struct regulator_dev *dev,
+                                     unsigned selector)
+{
+       struct fixed_voltage_data *data = rdev_get_drvdata(dev);
+
+       if (selector != 0)
+               return -EINVAL;
+
+       return data->microvolts;
+}
+
 static struct regulator_ops fixed_voltage_ops = {
        .is_enabled = fixed_voltage_is_enabled,
        .enable = fixed_voltage_enable,
        .get_voltage = fixed_voltage_get_voltage,
+       .list_voltage = fixed_voltage_list_voltage,
 };
 
 static int regulator_fixed_voltage_probe(struct platform_device *pdev)
@@ -69,7 +81,8 @@ static int regulator_fixed_voltage_probe(struct platform_device *pdev)
        }
        drvdata->desc.type = REGULATOR_VOLTAGE;
        drvdata->desc.owner = THIS_MODULE;
-       drvdata->desc.ops = &fixed_voltage_ops,
+       drvdata->desc.ops = &fixed_voltage_ops;
+       drvdata->desc.n_voltages = 1;
 
        drvdata->microvolts = config->microvolts;
 
@@ -117,7 +130,7 @@ static int __init regulator_fixed_voltage_init(void)
 {
        return platform_driver_register(&regulator_fixed_voltage_driver);
 }
-module_init(regulator_fixed_voltage_init);
+subsys_initcall(regulator_fixed_voltage_init);
 
 static void __exit regulator_fixed_voltage_exit(void)
 {
@@ -128,3 +141,4 @@ module_exit(regulator_fixed_voltage_exit);
 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
 MODULE_DESCRIPTION("Fixed voltage regulator");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:reg-fixed-voltage");
diff --git a/drivers/regulator/lp3971.c b/drivers/regulator/lp3971.c
new file mode 100644 (file)
index 0000000..a61018a
--- /dev/null
@@ -0,0 +1,562 @@
+/*
+ * Regulator driver for National Semiconductors LP3971 PMIC chip
+ *
+ *  Copyright (C) 2009 Samsung Electronics
+ *  Author: Marek Szyprowski <m.szyprowski@samsung.com>
+ *
+ * Based on wm8350.c
+ *
+ * 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/err.h>
+#include <linux/i2c.h>
+#include <linux/kernel.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/lp3971.h>
+
+struct lp3971 {
+       struct device *dev;
+       struct mutex io_lock;
+       struct i2c_client *i2c;
+       int num_regulators;
+       struct regulator_dev **rdev;
+};
+
+static u8 lp3971_reg_read(struct lp3971 *lp3971, u8 reg);
+static int lp3971_set_bits(struct lp3971 *lp3971, u8 reg, u16 mask, u16 val);
+
+#define LP3971_SYS_CONTROL1_REG 0x07
+
+/* System control register 1 initial value,
+   bits 4 and 5 are EPROM programmable */
+#define SYS_CONTROL1_INIT_VAL 0x40
+#define SYS_CONTROL1_INIT_MASK 0xCF
+
+#define LP3971_BUCK_VOL_ENABLE_REG 0x10
+#define LP3971_BUCK_VOL_CHANGE_REG 0x20
+
+/*     Voltage control registers shift:
+       LP3971_BUCK1 -> 0
+       LP3971_BUCK2 -> 4
+       LP3971_BUCK3 -> 6
+*/
+#define BUCK_VOL_CHANGE_SHIFT(x) (((1 << x) & ~0x01) << 1)
+#define BUCK_VOL_CHANGE_FLAG_GO 0x01
+#define BUCK_VOL_CHANGE_FLAG_TARGET 0x02
+#define BUCK_VOL_CHANGE_FLAG_MASK 0x03
+
+#define LP3971_BUCK1_BASE 0x23
+#define LP3971_BUCK2_BASE 0x29
+#define LP3971_BUCK3_BASE 0x32
+
+const static int buck_base_addr[] = {
+       LP3971_BUCK1_BASE,
+       LP3971_BUCK2_BASE,
+       LP3971_BUCK3_BASE,
+};
+
+#define LP3971_BUCK_TARGET_VOL1_REG(x) (buck_base_addr[x])
+#define LP3971_BUCK_TARGET_VOL2_REG(x) (buck_base_addr[x]+1)
+
+const static int buck_voltage_map[] = {
+          0,  800,  850,  900,  950, 1000, 1050, 1100,
+       1150, 1200, 1250, 1300, 1350, 1400, 1450, 1500,
+       1550, 1600, 1650, 1700, 1800, 1900, 2500, 2800,
+       3000, 3300,
+};
+
+#define BUCK_TARGET_VOL_MASK 0x3f
+#define BUCK_TARGET_VOL_MIN_IDX 0x01
+#define BUCK_TARGET_VOL_MAX_IDX 0x19
+
+#define LP3971_BUCK_RAMP_REG(x)        (buck_base_addr[x]+2)
+
+#define LP3971_LDO_ENABLE_REG 0x12
+#define LP3971_LDO_VOL_CONTR_BASE 0x39
+
+/*     Voltage control registers:
+       LP3971_LDO1 -> LP3971_LDO_VOL_CONTR_BASE + 0
+       LP3971_LDO2 -> LP3971_LDO_VOL_CONTR_BASE + 0
+       LP3971_LDO3 -> LP3971_LDO_VOL_CONTR_BASE + 1
+       LP3971_LDO4 -> LP3971_LDO_VOL_CONTR_BASE + 1
+       LP3971_LDO5 -> LP3971_LDO_VOL_CONTR_BASE + 2
+*/
+#define LP3971_LDO_VOL_CONTR_REG(x)    (LP3971_LDO_VOL_CONTR_BASE + (x >> 1))
+
+/*     Voltage control registers shift:
+       LP3971_LDO1 -> 0, LP3971_LDO2 -> 4
+       LP3971_LDO3 -> 0, LP3971_LDO4 -> 4
+       LP3971_LDO5 -> 0
+*/
+#define LDO_VOL_CONTR_SHIFT(x) ((x & 1) << 2)
+#define LDO_VOL_CONTR_MASK 0x0f
+
+const static int ldo45_voltage_map[] = {
+       1000, 1050, 1100, 1150, 1200, 1250, 1300, 1350,
+       1400, 1500, 1800, 1900, 2500, 2800, 3000, 3300,
+};
+
+const static int ldo123_voltage_map[] = {
+       1800, 1900, 2000, 2100, 2200, 2300, 2400, 2500,
+       2600, 2700, 2800, 2900, 3000, 3100, 3200, 3300,
+};
+
+const static int *ldo_voltage_map[] = {
+       ldo123_voltage_map, /* LDO1 */
+       ldo123_voltage_map, /* LDO2 */
+       ldo123_voltage_map, /* LDO3 */
+       ldo45_voltage_map, /* LDO4 */
+       ldo45_voltage_map, /* LDO5 */
+};
+
+#define LDO_VOL_VALUE_MAP(x) (ldo_voltage_map[(x - LP3971_LDO1)])
+
+#define LDO_VOL_MIN_IDX 0x00
+#define LDO_VOL_MAX_IDX 0x0f
+
+static int lp3971_ldo_list_voltage(struct regulator_dev *dev, unsigned index)
+{
+       int ldo = rdev_get_id(dev) - LP3971_LDO1;
+       return 1000 * LDO_VOL_VALUE_MAP(ldo)[index];
+}
+
+static int lp3971_ldo_is_enabled(struct regulator_dev *dev)
+{
+       struct lp3971 *lp3971 = rdev_get_drvdata(dev);
+       int ldo = rdev_get_id(dev) - LP3971_LDO1;
+       u16 mask = 1 << (1 + ldo);
+       u16 val;
+
+       val = lp3971_reg_read(lp3971, LP3971_LDO_ENABLE_REG);
+       return (val & mask) != 0;
+}
+
+static int lp3971_ldo_enable(struct regulator_dev *dev)
+{
+       struct lp3971 *lp3971 = rdev_get_drvdata(dev);
+       int ldo = rdev_get_id(dev) - LP3971_LDO1;
+       u16 mask = 1 << (1 + ldo);
+
+       return lp3971_set_bits(lp3971, LP3971_LDO_ENABLE_REG, mask, mask);
+}
+
+static int lp3971_ldo_disable(struct regulator_dev *dev)
+{
+       struct lp3971 *lp3971 = rdev_get_drvdata(dev);
+       int ldo = rdev_get_id(dev) - LP3971_LDO1;
+       u16 mask = 1 << (1 + ldo);
+
+       return lp3971_set_bits(lp3971, LP3971_LDO_ENABLE_REG, mask, 0);
+}
+
+static int lp3971_ldo_get_voltage(struct regulator_dev *dev)
+{
+       struct lp3971 *lp3971 = rdev_get_drvdata(dev);
+       int ldo = rdev_get_id(dev) - LP3971_LDO1;
+       u16 val, reg;
+
+       reg = lp3971_reg_read(lp3971, LP3971_LDO_VOL_CONTR_REG(ldo));
+       val = (reg >> LDO_VOL_CONTR_SHIFT(ldo)) & LDO_VOL_CONTR_MASK;
+
+       return 1000 * LDO_VOL_VALUE_MAP(ldo)[val];
+}
+
+static int lp3971_ldo_set_voltage(struct regulator_dev *dev,
+                                 int min_uV, int max_uV)
+{
+       struct lp3971 *lp3971 = rdev_get_drvdata(dev);
+       int ldo = rdev_get_id(dev) - LP3971_LDO1;
+       int min_vol = min_uV / 1000, max_vol = max_uV / 1000;
+       const int *vol_map = LDO_VOL_VALUE_MAP(ldo);
+       u16 val;
+
+       if (min_vol < vol_map[LDO_VOL_MIN_IDX] ||
+           min_vol > vol_map[LDO_VOL_MAX_IDX])
+               return -EINVAL;
+
+       for (val = LDO_VOL_MIN_IDX; val <= LDO_VOL_MAX_IDX; val++)
+               if (vol_map[val] >= min_vol)
+                       break;
+
+       if (vol_map[val] > max_vol)
+               return -EINVAL;
+
+       return lp3971_set_bits(lp3971, LP3971_LDO_VOL_CONTR_REG(ldo),
+               LDO_VOL_CONTR_MASK << LDO_VOL_CONTR_SHIFT(ldo), val);
+}
+
+static struct regulator_ops lp3971_ldo_ops = {
+       .list_voltage = lp3971_ldo_list_voltage,
+       .is_enabled = lp3971_ldo_is_enabled,
+       .enable = lp3971_ldo_enable,
+       .disable = lp3971_ldo_disable,
+       .get_voltage = lp3971_ldo_get_voltage,
+       .set_voltage = lp3971_ldo_set_voltage,
+};
+
+static int lp3971_dcdc_list_voltage(struct regulator_dev *dev, unsigned index)
+{
+       return 1000 * buck_voltage_map[index];
+}
+
+static int lp3971_dcdc_is_enabled(struct regulator_dev *dev)
+{
+       struct lp3971 *lp3971 = rdev_get_drvdata(dev);
+       int buck = rdev_get_id(dev) - LP3971_DCDC1;
+       u16 mask = 1 << (buck * 2);
+       u16 val;
+
+       val = lp3971_reg_read(lp3971, LP3971_BUCK_VOL_ENABLE_REG);
+       return (val & mask) != 0;
+}
+
+static int lp3971_dcdc_enable(struct regulator_dev *dev)
+{
+       struct lp3971 *lp3971 = rdev_get_drvdata(dev);
+       int buck = rdev_get_id(dev) - LP3971_DCDC1;
+       u16 mask = 1 << (buck * 2);
+
+       return lp3971_set_bits(lp3971, LP3971_BUCK_VOL_ENABLE_REG, mask, mask);
+}
+
+static int lp3971_dcdc_disable(struct regulator_dev *dev)
+{
+       struct lp3971 *lp3971 = rdev_get_drvdata(dev);
+       int buck = rdev_get_id(dev) - LP3971_DCDC1;
+       u16 mask = 1 << (buck * 2);
+
+       return lp3971_set_bits(lp3971, LP3971_BUCK_VOL_ENABLE_REG, mask, 0);
+}
+
+static int lp3971_dcdc_get_voltage(struct regulator_dev *dev)
+{
+       struct lp3971 *lp3971 = rdev_get_drvdata(dev);
+       int buck = rdev_get_id(dev) - LP3971_DCDC1;
+       u16 reg;
+       int val;
+
+       reg = lp3971_reg_read(lp3971, LP3971_BUCK_TARGET_VOL1_REG(buck));
+       reg &= BUCK_TARGET_VOL_MASK;
+
+       if (reg <= BUCK_TARGET_VOL_MAX_IDX)
+               val = 1000 * buck_voltage_map[reg];
+       else {
+               val = 0;
+               dev_warn(&dev->dev, "chip reported incorrect voltage value.\n");
+       }
+
+       return val;
+}
+
+static int lp3971_dcdc_set_voltage(struct regulator_dev *dev,
+                                 int min_uV, int max_uV)
+{
+       struct lp3971 *lp3971 = rdev_get_drvdata(dev);
+       int buck = rdev_get_id(dev) - LP3971_DCDC1;
+       int min_vol = min_uV / 1000, max_vol = max_uV / 1000;
+       const int *vol_map = buck_voltage_map;
+       u16 val;
+       int ret;
+
+       if (min_vol < vol_map[BUCK_TARGET_VOL_MIN_IDX] ||
+           min_vol > vol_map[BUCK_TARGET_VOL_MAX_IDX])
+               return -EINVAL;
+
+       for (val = BUCK_TARGET_VOL_MIN_IDX; val <= BUCK_TARGET_VOL_MAX_IDX;
+            val++)
+               if (vol_map[val] >= min_vol)
+                       break;
+
+       if (vol_map[val] > max_vol)
+               return -EINVAL;
+
+       ret = lp3971_set_bits(lp3971, LP3971_BUCK_TARGET_VOL1_REG(buck),
+              BUCK_TARGET_VOL_MASK, val);
+       if (ret)
+               return ret;
+
+       ret = lp3971_set_bits(lp3971, LP3971_BUCK_VOL_CHANGE_REG,
+              BUCK_VOL_CHANGE_FLAG_MASK << BUCK_VOL_CHANGE_SHIFT(buck),
+              BUCK_VOL_CHANGE_FLAG_GO << BUCK_VOL_CHANGE_SHIFT(buck));
+       if (ret)
+               return ret;
+
+       return lp3971_set_bits(lp3971, LP3971_BUCK_VOL_CHANGE_REG,
+              BUCK_VOL_CHANGE_FLAG_MASK << BUCK_VOL_CHANGE_SHIFT(buck),
+              0 << BUCK_VOL_CHANGE_SHIFT(buck));
+}
+
+static struct regulator_ops lp3971_dcdc_ops = {
+       .list_voltage = lp3971_dcdc_list_voltage,
+       .is_enabled = lp3971_dcdc_is_enabled,
+       .enable = lp3971_dcdc_enable,
+       .disable = lp3971_dcdc_disable,
+       .get_voltage = lp3971_dcdc_get_voltage,
+       .set_voltage = lp3971_dcdc_set_voltage,
+};
+
+static struct regulator_desc regulators[] = {
+       {
+               .name = "LDO1",
+               .id = LP3971_LDO1,
+               .ops = &lp3971_ldo_ops,
+               .n_voltages = ARRAY_SIZE(ldo123_voltage_map),
+               .type = REGULATOR_VOLTAGE,
+               .owner = THIS_MODULE,
+       },
+       {
+               .name = "LDO2",
+               .id = LP3971_LDO2,
+               .ops = &lp3971_ldo_ops,
+               .n_voltages = ARRAY_SIZE(ldo123_voltage_map),
+               .type = REGULATOR_VOLTAGE,
+               .owner = THIS_MODULE,
+       },
+       {
+               .name = "LDO3",
+               .id = LP3971_LDO3,
+               .ops = &lp3971_ldo_ops,
+               .n_voltages = ARRAY_SIZE(ldo123_voltage_map),
+               .type = REGULATOR_VOLTAGE,
+               .owner = THIS_MODULE,
+       },
+       {
+               .name = "LDO4",
+               .id = LP3971_LDO4,
+               .ops = &lp3971_ldo_ops,
+               .n_voltages = ARRAY_SIZE(ldo45_voltage_map),
+               .type = REGULATOR_VOLTAGE,
+               .owner = THIS_MODULE,
+       },
+       {
+               .name = "LDO5",
+               .id = LP3971_LDO5,
+               .ops = &lp3971_ldo_ops,
+               .n_voltages = ARRAY_SIZE(ldo45_voltage_map),
+               .type = REGULATOR_VOLTAGE,
+               .owner = THIS_MODULE,
+       },
+       {
+               .name = "DCDC1",
+               .id = LP3971_DCDC1,
+               .ops = &lp3971_dcdc_ops,
+               .n_voltages = ARRAY_SIZE(buck_voltage_map),
+               .type = REGULATOR_VOLTAGE,
+               .owner = THIS_MODULE,
+       },
+       {
+               .name = "DCDC2",
+               .id = LP3971_DCDC2,
+               .ops = &lp3971_dcdc_ops,
+               .n_voltages = ARRAY_SIZE(buck_voltage_map),
+               .type = REGULATOR_VOLTAGE,
+               .owner = THIS_MODULE,
+       },
+       {
+               .name = "DCDC3",
+               .id = LP3971_DCDC3,
+               .ops = &lp3971_dcdc_ops,
+               .n_voltages = ARRAY_SIZE(buck_voltage_map),
+               .type = REGULATOR_VOLTAGE,
+               .owner = THIS_MODULE,
+       },
+};
+
+static int lp3971_i2c_read(struct i2c_client *i2c, char reg, int count,
+       u16 *dest)
+{
+       int ret;
+
+       if (count != 1)
+               return -EIO;
+       ret = i2c_smbus_read_byte_data(i2c, reg);
+       if (ret < 0 || count != 1)
+               return -EIO;
+
+       *dest = ret;
+       return 0;
+}
+
+static int lp3971_i2c_write(struct i2c_client *i2c, char reg, int count,
+       const u16 *src)
+{
+       int ret;
+
+       if (count != 1)
+               return -EIO;
+       ret = i2c_smbus_write_byte_data(i2c, reg, *src);
+       if (ret >= 0)
+               return 0;
+
+       return ret;
+}
+
+static u8 lp3971_reg_read(struct lp3971 *lp3971, u8 reg)
+{
+       u16 val = 0;
+
+       mutex_lock(&lp3971->io_lock);
+
+       lp3971_i2c_read(lp3971->i2c, reg, 1, &val);
+
+       dev_dbg(lp3971->dev, "reg read 0x%02x -> 0x%02x\n", (int)reg,
+               (unsigned)val&0xff);
+
+       mutex_unlock(&lp3971->io_lock);
+
+       return val & 0xff;
+}
+
+static int lp3971_set_bits(struct lp3971 *lp3971, u8 reg, u16 mask, u16 val)
+{
+       u16 tmp;
+       int ret;
+
+       mutex_lock(&lp3971->io_lock);
+
+       ret = lp3971_i2c_read(lp3971->i2c, reg, 1, &tmp);
+       tmp = (tmp & ~mask) | val;
+       if (ret == 0) {
+               ret = lp3971_i2c_write(lp3971->i2c, reg, 1, &tmp);
+               dev_dbg(lp3971->dev, "reg write 0x%02x -> 0x%02x\n", (int)reg,
+                       (unsigned)val&0xff);
+       }
+       mutex_unlock(&lp3971->io_lock);
+
+       return ret;
+}
+
+static int setup_regulators(struct lp3971 *lp3971,
+       struct lp3971_platform_data *pdata)
+{
+       int i, err;
+       int num_regulators = pdata->num_regulators;
+       lp3971->num_regulators = num_regulators;
+       lp3971->rdev = kzalloc(sizeof(struct regulator_dev *) * num_regulators,
+               GFP_KERNEL);
+
+       /* Instantiate the regulators */
+       for (i = 0; i < num_regulators; i++) {
+               int id = pdata->regulators[i].id;
+               lp3971->rdev[i] = regulator_register(&regulators[id],
+                       lp3971->dev, pdata->regulators[i].initdata, lp3971);
+
+               err = IS_ERR(lp3971->rdev[i]);
+               if (err) {
+                       dev_err(lp3971->dev, "regulator init failed: %d\n",
+                               err);
+                       goto error;
+               }
+       }
+
+       return 0;
+error:
+       for (i = 0; i < num_regulators; i++)
+               if (lp3971->rdev[i])
+                       regulator_unregister(lp3971->rdev[i]);
+       kfree(lp3971->rdev);
+       lp3971->rdev = NULL;
+       return err;
+}
+
+static int __devinit lp3971_i2c_probe(struct i2c_client *i2c,
+                           const struct i2c_device_id *id)
+{
+       struct lp3971 *lp3971;
+       struct lp3971_platform_data *pdata = i2c->dev.platform_data;
+       int ret;
+       u16 val;
+
+       lp3971 = kzalloc(sizeof(struct lp3971), GFP_KERNEL);
+       if (lp3971 == NULL) {
+               ret = -ENOMEM;
+               goto err;
+       }
+
+       lp3971->i2c = i2c;
+       lp3971->dev = &i2c->dev;
+       i2c_set_clientdata(i2c, lp3971);
+
+       mutex_init(&lp3971->io_lock);
+
+       /* Detect LP3971 */
+       ret = lp3971_i2c_read(i2c, LP3971_SYS_CONTROL1_REG, 1, &val);
+       if (ret == 0 && (val & SYS_CONTROL1_INIT_MASK) != SYS_CONTROL1_INIT_VAL)
+               ret = -ENODEV;
+       if (ret < 0) {
+               dev_err(&i2c->dev, "failed to detect device\n");
+               goto err_detect;
+       }
+
+       if (pdata) {
+               ret = setup_regulators(lp3971, pdata);
+               if (ret < 0)
+                       goto err_detect;
+       } else
+               dev_warn(lp3971->dev, "No platform init data supplied\n");
+
+       return 0;
+
+err_detect:
+       i2c_set_clientdata(i2c, NULL);
+       kfree(lp3971);
+err:
+       return ret;
+}
+
+static int __devexit lp3971_i2c_remove(struct i2c_client *i2c)
+{
+       struct lp3971 *lp3971 = i2c_get_clientdata(i2c);
+       int i;
+       for (i = 0; i < lp3971->num_regulators; i++)
+               if (lp3971->rdev[i])
+                       regulator_unregister(lp3971->rdev[i]);
+       kfree(lp3971->rdev);
+       i2c_set_clientdata(i2c, NULL);
+       kfree(lp3971);
+
+       return 0;
+}
+
+static const struct i2c_device_id lp3971_i2c_id[] = {
+       { "lp3971", 0 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, lp3971_i2c_id);
+
+static struct i2c_driver lp3971_i2c_driver = {
+       .driver = {
+               .name = "LP3971",
+               .owner = THIS_MODULE,
+       },
+       .probe    = lp3971_i2c_probe,
+       .remove   = __devexit_p(lp3971_i2c_remove),
+       .id_table = lp3971_i2c_id,
+};
+
+static int __init lp3971_module_init(void)
+{
+       int ret = -ENODEV;
+
+       ret = i2c_add_driver(&lp3971_i2c_driver);
+       if (ret != 0)
+               pr_err("Failed to register I2C driver: %d\n", ret);
+
+       return ret;
+}
+module_init(lp3971_module_init);
+
+static void __exit lp3971_module_exit(void)
+{
+       i2c_del_driver(&lp3971_i2c_driver);
+}
+module_exit(lp3971_module_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Marek Szyprowski <m.szyprowski@samsung.com>");
+MODULE_DESCRIPTION("LP3971 PMIC driver");
diff --git a/drivers/regulator/max1586.c b/drivers/regulator/max1586.c
new file mode 100644 (file)
index 0000000..2c082d3
--- /dev/null
@@ -0,0 +1,282 @@
+/*
+ * max1586.c  --  Voltage and current regulation for the Maxim 1586
+ *
+ * Copyright (C) 2008 Robert Jarzmik
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/max1586.h>
+
+#define MAX1586_V3_MAX_VSEL 31
+#define MAX1586_V6_MAX_VSEL 3
+
+#define MAX1586_V3_MIN_UV   700000
+#define MAX1586_V3_MAX_UV  1475000
+
+#define MAX1586_V6_MIN_UV        0
+#define MAX1586_V6_MAX_UV  3000000
+
+#define I2C_V3_SELECT (0 << 5)
+#define I2C_V6_SELECT (1 << 5)
+
+struct max1586_data {
+       struct i2c_client *client;
+
+       /* min/max V3 voltage */
+       unsigned int min_uV;
+       unsigned int max_uV;
+
+       struct regulator_dev *rdev[0];
+};
+
+/*
+ * V3 voltage
+ * On I2C bus, sending a "x" byte to the max1586 means :
+ *   set V3 to 0.700V + (x & 0x1f) * 0.025V
+ * This voltage can be increased by external resistors
+ * R24 and R25=100kOhm as described in the data sheet.
+ * The gain is approximately: 1 + R24/R25 + R24/185.5kOhm
+ */
+static int max1586_v3_calc_voltage(struct max1586_data *max1586,
+       unsigned selector)
+{
+       unsigned range_uV = max1586->max_uV - max1586->min_uV;
+
+       return max1586->min_uV + (selector * range_uV / MAX1586_V3_MAX_VSEL);
+}
+
+static int max1586_v3_set(struct regulator_dev *rdev, int min_uV, int max_uV)
+{
+       struct max1586_data *max1586 = rdev_get_drvdata(rdev);
+       struct i2c_client *client = max1586->client;
+       unsigned range_uV = max1586->max_uV - max1586->min_uV;
+       unsigned selector;
+       u8 v3_prog;
+
+       if (min_uV > max1586->max_uV || max_uV < max1586->min_uV)
+               return -EINVAL;
+       if (min_uV < max1586->min_uV)
+               min_uV = max1586->min_uV;
+
+       selector = ((min_uV - max1586->min_uV) * MAX1586_V3_MAX_VSEL +
+                       range_uV - 1) / range_uV;
+       if (max1586_v3_calc_voltage(max1586, selector) > max_uV)
+               return -EINVAL;
+
+       dev_dbg(&client->dev, "changing voltage v3 to %dmv\n",
+               max1586_v3_calc_voltage(max1586, selector) / 1000);
+
+       v3_prog = I2C_V3_SELECT | (u8) selector;
+       return i2c_smbus_write_byte(client, v3_prog);
+}
+
+static int max1586_v3_list(struct regulator_dev *rdev, unsigned selector)
+{
+       struct max1586_data *max1586 = rdev_get_drvdata(rdev);
+
+       if (selector > MAX1586_V3_MAX_VSEL)
+               return -EINVAL;
+       return max1586_v3_calc_voltage(max1586, selector);
+}
+
+/*
+ * V6 voltage
+ * On I2C bus, sending a "x" byte to the max1586 means :
+ *   set V6 to either 0V, 1.8V, 2.5V, 3V depending on (x & 0x3)
+ * As regulator framework doesn't accept voltages to be 0V, we use 1uV.
+ */
+static int max1586_v6_calc_voltage(unsigned selector)
+{
+       static int voltages_uv[] = { 1, 1800000, 2500000, 3000000 };
+
+       return voltages_uv[selector];
+}
+
+static int max1586_v6_set(struct regulator_dev *rdev, int min_uV, int max_uV)
+{
+       struct i2c_client *client = rdev_get_drvdata(rdev);
+       unsigned selector;
+       u8 v6_prog;
+
+       if (min_uV < MAX1586_V6_MIN_UV || min_uV > MAX1586_V6_MAX_UV)
+               return -EINVAL;
+       if (max_uV < MAX1586_V6_MIN_UV || max_uV > MAX1586_V6_MAX_UV)
+               return -EINVAL;
+
+       if (min_uV >= 3000000)
+               selector = 3;
+       if (min_uV < 3000000)
+               selector = 2;
+       if (min_uV < 2500000)
+               selector = 1;
+       if (min_uV < 1800000)
+               selector = 0;
+
+       if (max1586_v6_calc_voltage(selector) > max_uV)
+               return -EINVAL;
+
+       dev_dbg(&client->dev, "changing voltage v6 to %dmv\n",
+               max1586_v6_calc_voltage(selector) / 1000);
+
+       v6_prog = I2C_V6_SELECT | (u8) selector;
+       return i2c_smbus_write_byte(client, v6_prog);
+}
+
+static int max1586_v6_list(struct regulator_dev *rdev, unsigned selector)
+{
+       if (selector > MAX1586_V6_MAX_VSEL)
+               return -EINVAL;
+       return max1586_v6_calc_voltage(selector);
+}
+
+/*
+ * The Maxim 1586 controls V3 and V6 voltages, but offers no way of reading back
+ * the set up value.
+ */
+static struct regulator_ops max1586_v3_ops = {
+       .set_voltage = max1586_v3_set,
+       .list_voltage = max1586_v3_list,
+};
+
+static struct regulator_ops max1586_v6_ops = {
+       .set_voltage = max1586_v6_set,
+       .list_voltage = max1586_v6_list,
+};
+
+static struct regulator_desc max1586_reg[] = {
+       {
+               .name = "Output_V3",
+               .id = MAX1586_V3,
+               .ops = &max1586_v3_ops,
+               .type = REGULATOR_VOLTAGE,
+               .n_voltages = MAX1586_V3_MAX_VSEL + 1,
+               .owner = THIS_MODULE,
+       },
+       {
+               .name = "Output_V6",
+               .id = MAX1586_V6,
+               .ops = &max1586_v6_ops,
+               .type = REGULATOR_VOLTAGE,
+               .n_voltages = MAX1586_V6_MAX_VSEL + 1,
+               .owner = THIS_MODULE,
+       },
+};
+
+static int max1586_pmic_probe(struct i2c_client *client,
+                             const struct i2c_device_id *i2c_id)
+{
+       struct regulator_dev **rdev;
+       struct max1586_platform_data *pdata = client->dev.platform_data;
+       struct max1586_data *max1586;
+       int i, id, ret = -ENOMEM;
+
+       max1586 = kzalloc(sizeof(struct max1586_data) +
+                       sizeof(struct regulator_dev *) * (MAX1586_V6 + 1),
+                       GFP_KERNEL);
+       if (!max1586)
+               goto out;
+
+       max1586->client = client;
+
+       if (!pdata->v3_gain) {
+               ret = -EINVAL;
+               goto out_unmap;
+       }
+       max1586->min_uV = MAX1586_V3_MIN_UV / 1000 * pdata->v3_gain / 1000;
+       max1586->max_uV = MAX1586_V3_MAX_UV / 1000 * pdata->v3_gain / 1000;
+
+       rdev = max1586->rdev;
+       for (i = 0; i < pdata->num_subdevs && i <= MAX1586_V6; i++) {
+               id = pdata->subdevs[i].id;
+               if (!pdata->subdevs[i].platform_data)
+                       continue;
+               if (id < MAX1586_V3 || id > MAX1586_V6) {
+                       dev_err(&client->dev, "invalid regulator id %d\n", id);
+                       goto err;
+               }
+               rdev[i] = regulator_register(&max1586_reg[id], &client->dev,
+                                            pdata->subdevs[i].platform_data,
+                                            max1586);
+               if (IS_ERR(rdev[i])) {
+                       ret = PTR_ERR(rdev[i]);
+                       dev_err(&client->dev, "failed to register %s\n",
+                               max1586_reg[id].name);
+                       goto err;
+               }
+       }
+
+       i2c_set_clientdata(client, rdev);
+       dev_info(&client->dev, "Maxim 1586 regulator driver loaded\n");
+       return 0;
+
+err:
+       while (--i >= 0)
+               regulator_unregister(rdev[i]);
+out_unmap:
+       kfree(max1586);
+out:
+       return ret;
+}
+
+static int max1586_pmic_remove(struct i2c_client *client)
+{
+       struct regulator_dev **rdev = i2c_get_clientdata(client);
+       int i;
+
+       for (i = 0; i <= MAX1586_V6; i++)
+               if (rdev[i])
+                       regulator_unregister(rdev[i]);
+       kfree(rdev);
+       i2c_set_clientdata(client, NULL);
+
+       return 0;
+}
+
+static const struct i2c_device_id max1586_id[] = {
+       { "max1586", 0 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, max1586_id);
+
+static struct i2c_driver max1586_pmic_driver = {
+       .probe = max1586_pmic_probe,
+       .remove = max1586_pmic_remove,
+       .driver         = {
+               .name   = "max1586",
+       },
+       .id_table       = max1586_id,
+};
+
+static int __init max1586_pmic_init(void)
+{
+       return i2c_add_driver(&max1586_pmic_driver);
+}
+subsys_initcall(max1586_pmic_init);
+
+static void __exit max1586_pmic_exit(void)
+{
+       i2c_del_driver(&max1586_pmic_driver);
+}
+module_exit(max1586_pmic_exit);
+
+/* Module information */
+MODULE_DESCRIPTION("MAXIM 1586 voltage regulator driver");
+MODULE_AUTHOR("Robert Jarzmik");
+MODULE_LICENSE("GPL");
index cd761d85c8fdbc39e42a6cf3d67864744c64c76b..8e14900eb686f3a3b2d75dab42b72dac0e2cc8bf 100644 (file)
@@ -316,7 +316,7 @@ static int __init pcf50633_regulator_init(void)
 {
        return platform_driver_register(&pcf50633_regulator_driver);
 }
-module_init(pcf50633_regulator_init);
+subsys_initcall(pcf50633_regulator_init);
 
 static void __exit pcf50633_regulator_exit(void)
 {
diff --git a/drivers/regulator/userspace-consumer.c b/drivers/regulator/userspace-consumer.c
new file mode 100644 (file)
index 0000000..06d2fa9
--- /dev/null
@@ -0,0 +1,200 @@
+/*
+ * userspace-consumer.c
+ *
+ * Copyright 2009 CompuLab, Ltd.
+ *
+ * Author: Mike Rapoport <mike@compulab.co.il>
+ *
+ * Based of virtual consumer driver:
+ *   Copyright 2008 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 as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ */
+
+#include <linux/err.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+#include <linux/regulator/userspace-consumer.h>
+
+struct userspace_consumer_data {
+       const char *name;
+
+       struct mutex lock;
+       bool enabled;
+
+       int num_supplies;
+       struct regulator_bulk_data *supplies;
+};
+
+static ssize_t reg_show_name(struct device *dev,
+                         struct device_attribute *attr, char *buf)
+{
+       struct userspace_consumer_data *data = dev_get_drvdata(dev);
+
+       return sprintf(buf, "%s\n", data->name);
+}
+
+static ssize_t reg_show_state(struct device *dev,
+                         struct device_attribute *attr, char *buf)
+{
+       struct userspace_consumer_data *data = dev_get_drvdata(dev);
+
+       if (data->enabled)
+               return sprintf(buf, "enabled\n");
+
+       return sprintf(buf, "disabled\n");
+}
+
+static ssize_t reg_set_state(struct device *dev, struct device_attribute *attr,
+                        const char *buf, size_t count)
+{
+       struct userspace_consumer_data *data = dev_get_drvdata(dev);
+       bool enabled;
+       int ret;
+
+       /*
+        * sysfs_streq() doesn't need the \n's, but we add them so the strings
+        * will be shared with show_state(), above.
+        */
+       if (sysfs_streq(buf, "enabled\n") || sysfs_streq(buf, "1"))
+               enabled = true;
+       else if (sysfs_streq(buf, "disabled\n") || sysfs_streq(buf, "0"))
+               enabled = false;
+       else {
+               dev_err(dev, "Configuring invalid mode\n");
+               return count;
+       }
+
+       mutex_lock(&data->lock);
+       if (enabled != data->enabled) {
+               if (enabled)
+                       ret = regulator_bulk_enable(data->num_supplies,
+                                                   data->supplies);
+               else
+                       ret = regulator_bulk_disable(data->num_supplies,
+                                                    data->supplies);
+
+               if (ret == 0)
+                       data->enabled = enabled;
+               else
+                       dev_err(dev, "Failed to configure state: %d\n", ret);
+       }
+       mutex_unlock(&data->lock);
+
+       return count;
+}
+
+static DEVICE_ATTR(name, 0444, reg_show_name, NULL);
+static DEVICE_ATTR(state, 0644, reg_show_state, reg_set_state);
+
+static struct device_attribute *attributes[] = {
+       &dev_attr_name,
+       &dev_attr_state,
+};
+
+static int regulator_userspace_consumer_probe(struct platform_device *pdev)
+{
+       struct regulator_userspace_consumer_data *pdata;
+       struct userspace_consumer_data *drvdata;
+       int ret, i;
+
+       pdata = pdev->dev.platform_data;
+       if (!pdata)
+               return -EINVAL;
+
+       drvdata = kzalloc(sizeof(struct userspace_consumer_data), GFP_KERNEL);
+       if (drvdata == NULL)
+               return -ENOMEM;
+
+       drvdata->name = pdata->name;
+       drvdata->num_supplies = pdata->num_supplies;
+       drvdata->supplies = pdata->supplies;
+
+       mutex_init(&drvdata->lock);
+
+       ret = regulator_bulk_get(&pdev->dev, drvdata->num_supplies,
+                                drvdata->supplies);
+       if (ret) {
+               dev_err(&pdev->dev, "Failed to get supplies: %d\n", ret);
+               goto err_alloc_supplies;
+       }
+
+       for (i = 0; i < ARRAY_SIZE(attributes); i++) {
+               ret = device_create_file(&pdev->dev, attributes[i]);
+               if (ret != 0)
+                       goto err_create_attrs;
+       }
+
+       if (pdata->init_on)
+               ret = regulator_bulk_enable(drvdata->num_supplies,
+                                           drvdata->supplies);
+
+       drvdata->enabled = pdata->init_on;
+
+       if (ret) {
+               dev_err(&pdev->dev, "Failed to set initial state: %d\n", ret);
+               goto err_create_attrs;
+       }
+
+       platform_set_drvdata(pdev, drvdata);
+
+       return 0;
+
+err_create_attrs:
+       for (i = 0; i < ARRAY_SIZE(attributes); i++)
+               device_remove_file(&pdev->dev, attributes[i]);
+
+       regulator_bulk_free(drvdata->num_supplies, drvdata->supplies);
+
+err_alloc_supplies:
+       kfree(drvdata);
+       return ret;
+}
+
+static int regulator_userspace_consumer_remove(struct platform_device *pdev)
+{
+       struct userspace_consumer_data *data = platform_get_drvdata(pdev);
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(attributes); i++)
+               device_remove_file(&pdev->dev, attributes[i]);
+
+       if (data->enabled)
+               regulator_bulk_disable(data->num_supplies, data->supplies);
+
+       regulator_bulk_free(data->num_supplies, data->supplies);
+       kfree(data);
+
+       return 0;
+}
+
+static struct platform_driver regulator_userspace_consumer_driver = {
+       .probe          = regulator_userspace_consumer_probe,
+       .remove         = regulator_userspace_consumer_remove,
+       .driver         = {
+               .name           = "reg-userspace-consumer",
+       },
+};
+
+
+static int __init regulator_userspace_consumer_init(void)
+{
+       return platform_driver_register(&regulator_userspace_consumer_driver);
+}
+module_init(regulator_userspace_consumer_init);
+
+static void __exit regulator_userspace_consumer_exit(void)
+{
+       platform_driver_unregister(&regulator_userspace_consumer_driver);
+}
+module_exit(regulator_userspace_consumer_exit);
+
+MODULE_AUTHOR("Mike Rapoport <mike@compulab.co.il>");
+MODULE_DESCRIPTION("Userspace consumer for voltage and current regulators");
+MODULE_LICENSE("GPL");
index 71403fa3ffa1e04aa2bffe69403480b1bb5623f4..e7db5664722e962f1e7c60c2bea1c6f8910b5aeb 100644 (file)
@@ -347,3 +347,4 @@ module_exit(regulator_virtual_consumer_exit);
 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
 MODULE_DESCRIPTION("Virtual regulator consumer");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:reg-virt-consumer");
index 771eca1066b5916378c0620387b3ecf8dae3342a..17a00b0fafd11f6e311c4091da1db38387d37535 100644 (file)
@@ -1570,3 +1570,4 @@ module_exit(wm8350_regulator_exit);
 MODULE_AUTHOR("Liam Girdwood");
 MODULE_DESCRIPTION("WM8350 voltage and current regulator driver");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:wm8350-regulator");
index 157426029071fd72e5506c34dbeaecaf9ca9b619..d9a2c988c6e7b4b8d4369713a6bf05107536da3a 100644 (file)
@@ -320,7 +320,7 @@ static int __devinit wm8400_regulator_probe(struct platform_device *pdev)
        struct regulator_dev *rdev;
 
        rdev = regulator_register(&regulators[pdev->id], &pdev->dev,
-               pdev->dev.platform_data, pdev->dev.driver_data);
+               pdev->dev.platform_data, dev_get_drvdata(&pdev->dev));
 
        if (IS_ERR(rdev))
                return PTR_ERR(rdev);
@@ -359,7 +359,7 @@ static struct platform_driver wm8400_regulator_driver = {
 int wm8400_register_regulator(struct device *dev, int reg,
                              struct regulator_init_data *initdata)
 {
-       struct wm8400 *wm8400 = dev->driver_data;
+       struct wm8400 *wm8400 = dev_get_drvdata(dev);
 
        if (wm8400->regulators[reg].name)
                return -EBUSY;
@@ -369,8 +369,8 @@ int wm8400_register_regulator(struct device *dev, int reg,
        wm8400->regulators[reg].name = "wm8400-regulator";
        wm8400->regulators[reg].id = reg;
        wm8400->regulators[reg].dev.parent = dev;
-       wm8400->regulators[reg].dev.driver_data = wm8400;
        wm8400->regulators[reg].dev.platform_data = initdata;
+       dev_set_drvdata(&wm8400->regulators[reg].dev, wm8400);
 
        return platform_device_register(&wm8400->regulators[reg]);
 }
@@ -380,7 +380,7 @@ static int __init wm8400_regulator_init(void)
 {
        return platform_driver_register(&wm8400_regulator_driver);
 }
-module_init(wm8400_regulator_init);
+subsys_initcall(wm8400_regulator_init);
 
 static void __exit wm8400_regulator_exit(void)
 {
index 30a43cc79e7657c585ecbe1d34f82756fb7f3af5..7b6f46ddf3c304146b5b7e0afd34233f34b01b42 100644 (file)
@@ -338,12 +338,6 @@ claw_tx(struct sk_buff *skb, struct net_device *dev)
 
        CLAW_DBF_TEXT(4, trace, "claw_tx");
         p_ch=&privptr->channel[WRITE];
-        if (skb == NULL) {
-                privptr->stats.tx_dropped++;
-               privptr->stats.tx_errors++;
-               CLAW_DBF_TEXT_(2, trace, "clawtx%d", -EIO);
-                return -EIO;
-        }
         spin_lock_irqsave(get_ccwdev_lock(p_ch->cdev), saveflags);
         rc=claw_hw_tx( skb, dev, 1 );
         spin_unlock_irqrestore(get_ccwdev_lock(p_ch->cdev), saveflags);
index 77f4033a0f4fe0b651ed11464241aaab5ce15191..54c4649a493bd27399f107032926662a79370d15 100644 (file)
@@ -1677,10 +1677,8 @@ static void ctcm_remove_device(struct ccwgroup_device *cgdev)
        BUG_ON(priv == NULL);
 
        CTCM_DBF_TEXT_(SETUP, CTC_DBF_INFO,
-                       "removing device %s, r/w = %s/%s, proto : %d",
-                       priv->channel[READ]->netdev->name,
-                       priv->channel[READ]->id, priv->channel[WRITE]->id,
-                       priv->protocol);
+                       "removing device %p, proto : %d",
+                       cgdev, priv->protocol);
 
        if (cgdev->state == CCWGROUP_ONLINE)
                ctcm_shutdown_device(cgdev);
index be716e45f7acddcddae29f694252177a89c2eb9b..aec9e5d3cf4b72ef7830435fccf8c3c708df31b5 100644 (file)
@@ -1315,9 +1315,9 @@ static int netiucv_tx(struct sk_buff *skb, struct net_device *dev)
                return NETDEV_TX_BUSY;
        }
        dev->trans_start = jiffies;
-       rc = netiucv_transmit_skb(privptr->conn, skb) != 0;
+       rc = netiucv_transmit_skb(privptr->conn, skb);
        netiucv_clear_busy(dev);
-       return rc;
+       return rc ? NETDEV_TX_BUSY : NETDEV_TX_OK;
 }
 
 /**
index c827d69b5a912c83244afd3cdd1eeb98b630b7e9..74c49d9a8dba2b76932b5f143bb8e66fb9458068 100644 (file)
@@ -952,6 +952,7 @@ static void qeth_clear_output_buffer(struct qeth_qdio_out_q *queue,
                buf->buffer->element[i].addr = NULL;
                buf->buffer->element[i].flags = 0;
        }
+       buf->buffer->element[15].flags = 0;
        buf->next_element_to_fill = 0;
        atomic_set(&buf->state, QETH_QDIO_BUF_EMPTY);
 }
@@ -1140,6 +1141,8 @@ static int qeth_setup_card(struct qeth_card *card)
        card->ipato.enabled = 0;
        card->ipato.invert4 = 0;
        card->ipato.invert6 = 0;
+       if (card->info.type == QETH_CARD_TYPE_IQD)
+               card->options.checksum_type = NO_CHECKSUMMING;
        /* init QDIO stuff */
        qeth_init_qdio_info(card);
        return 0;
@@ -2934,8 +2937,8 @@ int qeth_get_cast_type(struct qeth_card *card, struct sk_buff *skb)
        if (card->info.type == QETH_CARD_TYPE_OSN)
                return cast_type;
 
-       if (skb->dst && skb->dst->neighbour) {
-               cast_type = skb->dst->neighbour->type;
+       if (skb_dst(skb) && skb_dst(skb)->neighbour) {
+               cast_type = skb_dst(skb)->neighbour->type;
                if ((cast_type == RTN_BROADCAST) ||
                    (cast_type == RTN_MULTICAST) ||
                    (cast_type == RTN_ANYCAST))
index 06f4de1f05075ae9bb4bf03af007cf778da14b97..ec24901c802c565231f27a9b369c3fb19950ca9b 100644 (file)
@@ -181,6 +181,8 @@ static struct ipa_rc_msg qeth_ipa_rc_msg[] = {
        {IPA_RC_L2_ADDR_TABLE_FULL,     "Layer2 address table full"},
        {IPA_RC_L2_DUP_LAYER3_MAC,      "Duplicate with layer 3 MAC"},
        {IPA_RC_L2_GMAC_NOT_FOUND,      "GMAC not found"},
+       {IPA_RC_L2_MAC_NOT_AUTH_BY_HYP, "L2 mac not authorized by hypervisor"},
+       {IPA_RC_L2_MAC_NOT_AUTH_BY_ADP, "L2 mac not authorized by adapter"},
        {IPA_RC_L2_MAC_NOT_FOUND,       "L2 mac address not found"},
        {IPA_RC_L2_INVALID_VLAN_ID,     "L2 invalid vlan id"},
        {IPA_RC_L2_DUP_VLAN_ID,         "L2 duplicate vlan id"},
index 18548822e37c8f38db671ca66928f5564bb6f507..eecb2ee62e851bf57b86569dd27b3b6c2a7e9951 100644 (file)
@@ -168,6 +168,8 @@ enum qeth_ipa_return_codes {
        IPA_RC_L2_ADDR_TABLE_FULL       = 0x2006,
        IPA_RC_L2_DUP_LAYER3_MAC        = 0x200a,
        IPA_RC_L2_GMAC_NOT_FOUND        = 0x200b,
+       IPA_RC_L2_MAC_NOT_AUTH_BY_HYP   = 0x200c,
+       IPA_RC_L2_MAC_NOT_AUTH_BY_ADP   = 0x200d,
        IPA_RC_L2_MAC_NOT_FOUND         = 0x2010,
        IPA_RC_L2_INVALID_VLAN_ID       = 0x2015,
        IPA_RC_L2_DUP_VLAN_ID           = 0x2016,
index 172031baedc1aef4d44f4c03663612e56b76c646..ecd3d06c0d5cc464b7c3ac90197e05a1bc3c17ce 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/etherdevice.h>
 #include <linux/mii.h>
 #include <linux/ip.h>
+#include <linux/list.h>
 
 #include "qeth_core.h"
 
@@ -130,7 +131,7 @@ static int qeth_l2_send_setgroupmac_cb(struct qeth_card *card,
        cmd = (struct qeth_ipa_cmd *) data;
        mac = &cmd->data.setdelmac.mac[0];
        /* MAC already registered, needed in couple/uncouple case */
-       if (cmd->hdr.return_code == 0x2005) {
+       if (cmd->hdr.return_code ==  IPA_RC_L2_DUP_MAC) {
                QETH_DBF_MESSAGE(2, "Group MAC %pM already existing on %s \n",
                          mac, QETH_CARD_IFNAME(card));
                cmd->hdr.return_code = 0;
@@ -502,6 +503,30 @@ static int qeth_l2_send_setmac_cb(struct qeth_card *card,
        if (cmd->hdr.return_code) {
                QETH_DBF_TEXT_(TRACE, 2, "L2er%x", cmd->hdr.return_code);
                card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED;
+               switch (cmd->hdr.return_code) {
+               case IPA_RC_L2_DUP_MAC:
+               case IPA_RC_L2_DUP_LAYER3_MAC:
+                       dev_warn(&card->gdev->dev,
+                               "MAC address "
+                               "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x "
+                               "already exists\n",
+                               card->dev->dev_addr[0], card->dev->dev_addr[1],
+                               card->dev->dev_addr[2], card->dev->dev_addr[3],
+                               card->dev->dev_addr[4], card->dev->dev_addr[5]);
+                       break;
+               case IPA_RC_L2_MAC_NOT_AUTH_BY_HYP:
+               case IPA_RC_L2_MAC_NOT_AUTH_BY_ADP:
+                       dev_warn(&card->gdev->dev,
+                               "MAC address "
+                               "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x "
+                               "is not authorized\n",
+                               card->dev->dev_addr[0], card->dev->dev_addr[1],
+                               card->dev->dev_addr[2], card->dev->dev_addr[3],
+                               card->dev->dev_addr[4], card->dev->dev_addr[5]);
+                       break;
+               default:
+                       break;
+               }
                cmd->hdr.return_code = -EIO;
        } else {
                card->info.mac_bits |= QETH_LAYER2_MAC_REGISTERED;
@@ -616,6 +641,7 @@ static void qeth_l2_set_multicast_list(struct net_device *dev)
 {
        struct qeth_card *card = dev->ml_priv;
        struct dev_addr_list *dm;
+       struct netdev_hw_addr *ha;
 
        if (card->info.type == QETH_CARD_TYPE_OSN)
                return ;
@@ -629,8 +655,8 @@ static void qeth_l2_set_multicast_list(struct net_device *dev)
        for (dm = dev->mc_list; dm; dm = dm->next)
                qeth_l2_add_mc(card, dm->da_addr, 0);
 
-       for (dm = dev->uc_list; dm; dm = dm->next)
-               qeth_l2_add_mc(card, dm->da_addr, 1);
+       list_for_each_entry(ha, &dev->uc_list, list)
+               qeth_l2_add_mc(card, ha->addr, 1);
 
        spin_unlock_bh(&card->mclock);
        if (!qeth_adp_supported(card, IPA_SETADP_SET_PROMISC_MODE))
@@ -839,6 +865,7 @@ static void qeth_l2_remove_device(struct ccwgroup_device *cgdev)
 {
        struct qeth_card *card = dev_get_drvdata(&cgdev->dev);
 
+       qeth_set_allowed_threads(card, 0, 1);
        wait_event(card->wait_q, qeth_threads_running(card, 0xffffffff) == 0);
 
        if (cgdev->state == CCWGROUP_ONLINE) {
@@ -974,8 +1001,9 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode)
                        dev_warn(&card->gdev->dev,
                                "The LAN is offline\n");
                        card->lan_online = 0;
+                       return 0;
                }
-               return rc;
+               goto out_remove;
        } else
                card->lan_online = 1;
 
index 0ba3817cb6a76584704e5252834ee1fbd59b1ceb..6f2386e9d6e2b2c8466da5e99c23496430cd8f65 100644 (file)
@@ -1920,16 +1920,22 @@ static inline __u16 qeth_l3_rebuild_skb(struct qeth_card *card,
                 hdr->hdr.l3.vlan_id : *((u16 *)&hdr->hdr.l3.dest_addr[12]);
        }
 
-       skb->ip_summed = card->options.checksum_type;
-       if (card->options.checksum_type == HW_CHECKSUMMING) {
+       switch (card->options.checksum_type) {
+       case SW_CHECKSUMMING:
+               skb->ip_summed = CHECKSUM_NONE;
+               break;
+       case NO_CHECKSUMMING:
+               skb->ip_summed = CHECKSUM_UNNECESSARY;
+               break;
+       case HW_CHECKSUMMING:
                if ((hdr->hdr.l3.ext_flags &
-                     (QETH_HDR_EXT_CSUM_HDR_REQ |
-                      QETH_HDR_EXT_CSUM_TRANSP_REQ)) ==
-                    (QETH_HDR_EXT_CSUM_HDR_REQ |
-                     QETH_HDR_EXT_CSUM_TRANSP_REQ))
+                   (QETH_HDR_EXT_CSUM_HDR_REQ |
+                    QETH_HDR_EXT_CSUM_TRANSP_REQ)) ==
+                   (QETH_HDR_EXT_CSUM_HDR_REQ |
+                    QETH_HDR_EXT_CSUM_TRANSP_REQ))
                        skb->ip_summed = CHECKSUM_UNNECESSARY;
                else
-                       skb->ip_summed = SW_CHECKSUMMING;
+                       skb->ip_summed = CHECKSUM_NONE;
        }
 
        return vlan_id;
@@ -2543,9 +2549,9 @@ static void qeth_l3_fill_header(struct qeth_card *card, struct qeth_hdr *hdr,
                /* IPv4 */
                hdr->hdr.l3.flags = qeth_l3_get_qeth_hdr_flags4(cast_type);
                memset(hdr->hdr.l3.dest_addr, 0, 12);
-               if ((skb->dst) && (skb->dst->neighbour)) {
+               if ((skb_dst(skb)) && (skb_dst(skb)->neighbour)) {
                        *((u32 *) (&hdr->hdr.l3.dest_addr[12])) =
-                           *((u32 *) skb->dst->neighbour->primary_key);
+                           *((u32 *) skb_dst(skb)->neighbour->primary_key);
                } else {
                        /* fill in destination address used in ip header */
                        *((u32 *) (&hdr->hdr.l3.dest_addr[12])) =
@@ -2556,9 +2562,9 @@ static void qeth_l3_fill_header(struct qeth_card *card, struct qeth_hdr *hdr,
                hdr->hdr.l3.flags = qeth_l3_get_qeth_hdr_flags6(cast_type);
                if (card->info.type == QETH_CARD_TYPE_IQD)
                        hdr->hdr.l3.flags &= ~QETH_HDR_PASSTHRU;
-               if ((skb->dst) && (skb->dst->neighbour)) {
+               if ((skb_dst(skb)) && (skb_dst(skb)->neighbour)) {
                        memcpy(hdr->hdr.l3.dest_addr,
-                              skb->dst->neighbour->primary_key, 16);
+                              skb_dst(skb)->neighbour->primary_key, 16);
                } else {
                        /* fill in destination address used in ip header */
                        memcpy(hdr->hdr.l3.dest_addr,
@@ -3006,6 +3012,7 @@ static int qeth_l3_setup_netdev(struct qeth_card *card)
        card->dev->features |=  NETIF_F_HW_VLAN_TX |
                                NETIF_F_HW_VLAN_RX |
                                NETIF_F_HW_VLAN_FILTER;
+       card->dev->priv_flags &= ~IFF_XMIT_DST_RELEASE;
 
        SET_NETDEV_DEV(card->dev, &card->gdev->dev);
        return register_netdev(card->dev);
@@ -3070,6 +3077,7 @@ static void qeth_l3_remove_device(struct ccwgroup_device *cgdev)
 {
        struct qeth_card *card = dev_get_drvdata(&cgdev->dev);
 
+       qeth_set_allowed_threads(card, 0, 1);
        wait_event(card->wait_q, qeth_threads_running(card, 0xffffffff) == 0);
 
        if (cgdev->state == CCWGROUP_ONLINE) {
@@ -3141,8 +3149,9 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode)
                        dev_warn(&card->gdev->dev,
                                "The LAN is offline\n");
                        card->lan_online = 0;
+                       return 0;
                }
-               return rc;
+               goto out_remove;
        } else
                card->lan_online = 1;
        qeth_set_large_send(card, card->options.large_send);
index e606b4829d4430684a973c743d721bf81ba66d1f..c15878e881570e6ae6344b92869b1457840e7f69 100644 (file)
@@ -134,6 +134,58 @@ static struct scsi_host_template fcoe_shost_template = {
        .max_sectors = 0xffff,
 };
 
+/**
+ * fcoe_fip_recv - handle a received FIP frame.
+ * @skb: the receive skb
+ * @dev: associated &net_device
+ * @ptype: the &packet_type structure which was used to register this handler.
+ * @orig_dev: original receive &net_device, in case @dev is a bond.
+ *
+ * Returns: 0 for success
+ */
+static int fcoe_fip_recv(struct sk_buff *skb, struct net_device *dev,
+                        struct packet_type *ptype,
+                        struct net_device *orig_dev)
+{
+       struct fcoe_softc *fc;
+
+       fc = container_of(ptype, struct fcoe_softc, fip_packet_type);
+       fcoe_ctlr_recv(&fc->ctlr, skb);
+       return 0;
+}
+
+/**
+ * fcoe_fip_send() - send an Ethernet-encapsulated FIP frame.
+ * @fip: FCoE controller.
+ * @skb: FIP Packet.
+ */
+static void fcoe_fip_send(struct fcoe_ctlr *fip, struct sk_buff *skb)
+{
+       skb->dev = fcoe_from_ctlr(fip)->real_dev;
+       dev_queue_xmit(skb);
+}
+
+/**
+ * fcoe_update_src_mac() - Update Ethernet MAC filters.
+ * @fip: FCoE controller.
+ * @old: Unicast MAC address to delete if the MAC is non-zero.
+ * @new: Unicast MAC address to add.
+ *
+ * Remove any previously-set unicast MAC filter.
+ * Add secondary FCoE MAC address filter for our OUI.
+ */
+static void fcoe_update_src_mac(struct fcoe_ctlr *fip, u8 *old, u8 *new)
+{
+       struct fcoe_softc *fc;
+
+       fc = fcoe_from_ctlr(fip);
+       rtnl_lock();
+       if (!is_zero_ether_addr(old))
+               dev_unicast_delete(fc->real_dev, old);
+       dev_unicast_add(fc->real_dev, new);
+       rtnl_unlock();
+}
+
 /**
  * fcoe_lport_config() - sets up the fc_lport
  * @lp: ptr to the fc_lport
@@ -166,6 +218,30 @@ static int fcoe_lport_config(struct fc_lport *lp)
        return 0;
 }
 
+/**
+ * fcoe_netdev_cleanup() - clean up netdev configurations
+ * @fc: ptr to the fcoe_softc
+ */
+void fcoe_netdev_cleanup(struct fcoe_softc *fc)
+{
+       u8 flogi_maddr[ETH_ALEN];
+
+       /* Don't listen for Ethernet packets anymore */
+       dev_remove_pack(&fc->fcoe_packet_type);
+       dev_remove_pack(&fc->fip_packet_type);
+
+       /* Delete secondary MAC addresses */
+       rtnl_lock();
+       memcpy(flogi_maddr, (u8[6]) FC_FCOE_FLOGI_MAC, ETH_ALEN);
+       dev_unicast_delete(fc->real_dev, flogi_maddr);
+       if (!is_zero_ether_addr(fc->ctlr.data_src_addr))
+               dev_unicast_delete(fc->real_dev, fc->ctlr.data_src_addr);
+       if (fc->ctlr.spma)
+               dev_unicast_delete(fc->real_dev, fc->ctlr.ctl_src_addr);
+       dev_mc_delete(fc->real_dev, FIP_ALL_ENODE_MACS, ETH_ALEN, 0);
+       rtnl_unlock();
+}
+
 /**
  * fcoe_queue_timer() - fcoe queue timer
  * @lp: the fc_lport pointer
@@ -193,6 +269,7 @@ static int fcoe_netdev_config(struct fc_lport *lp, struct net_device *netdev)
        u64 wwnn, wwpn;
        struct fcoe_softc *fc;
        u8 flogi_maddr[ETH_ALEN];
+       struct netdev_hw_addr *ha;
 
        /* Setup lport private data to point to fcoe softc */
        fc = lport_priv(lp);
@@ -250,9 +327,23 @@ static int fcoe_netdev_config(struct fc_lport *lp, struct net_device *netdev)
        fc->fcoe_pending_queue_active = 0;
        setup_timer(&fc->timer, fcoe_queue_timer, (unsigned long)lp);
 
+       /* look for SAN MAC address, if multiple SAN MACs exist, only
+        * use the first one for SPMA */
+       rcu_read_lock();
+       for_each_dev_addr(netdev, ha) {
+               if ((ha->type == NETDEV_HW_ADDR_T_SAN) &&
+                   (is_valid_ether_addr(fc->ctlr.ctl_src_addr))) {
+                       memcpy(fc->ctlr.ctl_src_addr, ha->addr, ETH_ALEN);
+                       fc->ctlr.spma = 1;
+                       break;
+               }
+       }
+       rcu_read_unlock();
+
        /* setup Source Mac Address */
-       memcpy(fc->ctlr.ctl_src_addr, fc->real_dev->dev_addr,
-              fc->real_dev->addr_len);
+       if (!fc->ctlr.spma)
+               memcpy(fc->ctlr.ctl_src_addr, fc->real_dev->dev_addr,
+                      fc->real_dev->addr_len);
 
        wwnn = fcoe_wwn_from_mac(fc->real_dev->dev_addr, 1, 0);
        fc_set_wwnn(lp, wwnn);
@@ -267,7 +358,9 @@ static int fcoe_netdev_config(struct fc_lport *lp, struct net_device *netdev)
         */
        rtnl_lock();
        memcpy(flogi_maddr, (u8[6]) FC_FCOE_FLOGI_MAC, ETH_ALEN);
-       dev_unicast_add(fc->real_dev, flogi_maddr, ETH_ALEN);
+       dev_unicast_add(fc->real_dev, flogi_maddr);
+       if (fc->ctlr.spma)
+               dev_unicast_add(fc->real_dev, fc->ctlr.ctl_src_addr);
        dev_mc_add(fc->real_dev, FIP_ALL_ENODE_MACS, ETH_ALEN, 0);
        rtnl_unlock();
 
@@ -280,6 +373,11 @@ static int fcoe_netdev_config(struct fc_lport *lp, struct net_device *netdev)
        fc->fcoe_packet_type.dev = fc->real_dev;
        dev_add_pack(&fc->fcoe_packet_type);
 
+       fc->fip_packet_type.func = fcoe_fip_recv;
+       fc->fip_packet_type.type = htons(ETH_P_FIP);
+       fc->fip_packet_type.dev = fc->real_dev;
+       dev_add_pack(&fc->fip_packet_type);
+
        return 0;
 }
 
@@ -347,7 +445,6 @@ static int fcoe_if_destroy(struct net_device *netdev)
 {
        struct fc_lport *lp = NULL;
        struct fcoe_softc *fc;
-       u8 flogi_maddr[ETH_ALEN];
 
        BUG_ON(!netdev);
 
@@ -366,9 +463,10 @@ static int fcoe_if_destroy(struct net_device *netdev)
        /* Remove the instance from fcoe's list */
        fcoe_hostlist_remove(lp);
 
-       /* Don't listen for Ethernet packets anymore */
-       dev_remove_pack(&fc->fcoe_packet_type);
-       dev_remove_pack(&fc->fip_packet_type);
+       /* clean up netdev configurations */
+       fcoe_netdev_cleanup(fc);
+
+       /* tear-down the FCoE controller */
        fcoe_ctlr_destroy(&fc->ctlr);
 
        /* Cleanup the fc_lport */
@@ -383,16 +481,6 @@ static int fcoe_if_destroy(struct net_device *netdev)
        if (lp->emp)
                fc_exch_mgr_free(lp->emp);
 
-       /* Delete secondary MAC addresses */
-       rtnl_lock();
-       memcpy(flogi_maddr, (u8[6]) FC_FCOE_FLOGI_MAC, ETH_ALEN);
-       dev_unicast_delete(fc->real_dev, flogi_maddr, ETH_ALEN);
-       if (!is_zero_ether_addr(fc->ctlr.data_src_addr))
-               dev_unicast_delete(fc->real_dev,
-                                  fc->ctlr.data_src_addr, ETH_ALEN);
-       dev_mc_delete(fc->real_dev, FIP_ALL_ENODE_MACS, ETH_ALEN, 0);
-       rtnl_unlock();
-
        /* Free the per-CPU receive threads */
        fcoe_percpu_clean(lp);
 
@@ -454,58 +542,6 @@ static struct libfc_function_template fcoe_libfc_fcn_templ = {
        .ddp_done = fcoe_ddp_done,
 };
 
-/**
- * fcoe_fip_recv - handle a received FIP frame.
- * @skb: the receive skb
- * @dev: associated &net_device
- * @ptype: the &packet_type structure which was used to register this handler.
- * @orig_dev: original receive &net_device, in case @dev is a bond.
- *
- * Returns: 0 for success
- */
-static int fcoe_fip_recv(struct sk_buff *skb, struct net_device *dev,
-                        struct packet_type *ptype,
-                        struct net_device *orig_dev)
-{
-       struct fcoe_softc *fc;
-
-       fc = container_of(ptype, struct fcoe_softc, fip_packet_type);
-       fcoe_ctlr_recv(&fc->ctlr, skb);
-       return 0;
-}
-
-/**
- * fcoe_fip_send() - send an Ethernet-encapsulated FIP frame.
- * @fip: FCoE controller.
- * @skb: FIP Packet.
- */
-static void fcoe_fip_send(struct fcoe_ctlr *fip, struct sk_buff *skb)
-{
-       skb->dev = fcoe_from_ctlr(fip)->real_dev;
-       dev_queue_xmit(skb);
-}
-
-/**
- * fcoe_update_src_mac() - Update Ethernet MAC filters.
- * @fip: FCoE controller.
- * @old: Unicast MAC address to delete if the MAC is non-zero.
- * @new: Unicast MAC address to add.
- *
- * Remove any previously-set unicast MAC filter.
- * Add secondary FCoE MAC address filter for our OUI.
- */
-static void fcoe_update_src_mac(struct fcoe_ctlr *fip, u8 *old, u8 *new)
-{
-       struct fcoe_softc *fc;
-
-       fc = fcoe_from_ctlr(fip);
-       rtnl_lock();
-       if (!is_zero_ether_addr(old))
-               dev_unicast_delete(fc->real_dev, old, ETH_ALEN);
-       dev_unicast_add(fc->real_dev, new, ETH_ALEN);
-       rtnl_unlock();
-}
-
 /**
  * fcoe_if_create() - this function creates the fcoe interface
  * @netdev: pointer the associated netdevice
@@ -547,13 +583,6 @@ static int fcoe_if_create(struct net_device *netdev)
                goto out_host_put;
        }
 
-       /* configure lport network properties */
-       rc = fcoe_netdev_config(lp, netdev);
-       if (rc) {
-               FC_DBG("Could not configure netdev for lport\n");
-               goto out_host_put;
-       }
-
        /*
         * Initialize FIP.
         */
@@ -561,23 +590,25 @@ static int fcoe_if_create(struct net_device *netdev)
        fc->ctlr.send = fcoe_fip_send;
        fc->ctlr.update_mac = fcoe_update_src_mac;
 
-       fc->fip_packet_type.func = fcoe_fip_recv;
-       fc->fip_packet_type.type = htons(ETH_P_FIP);
-       fc->fip_packet_type.dev = fc->real_dev;
-       dev_add_pack(&fc->fip_packet_type);
+       /* configure lport network properties */
+       rc = fcoe_netdev_config(lp, netdev);
+       if (rc) {
+               FC_DBG("Could not configure netdev for the interface\n");
+               goto out_netdev_cleanup;
+       }
 
        /* configure lport scsi host properties */
        rc = fcoe_shost_config(lp, shost, &netdev->dev);
        if (rc) {
                FC_DBG("Could not configure shost for lport\n");
-               goto out_host_put;
+               goto out_netdev_cleanup;
        }
 
        /* lport exch manager allocation */
        rc = fcoe_em_config(lp);
        if (rc) {
                FC_DBG("Could not configure em for lport\n");
-               goto out_host_put;
+               goto out_netdev_cleanup;
        }
 
        /* Initialize the library */
@@ -603,6 +634,8 @@ static int fcoe_if_create(struct net_device *netdev)
 
 out_lp_destroy:
        fc_exch_mgr_free(lp->emp); /* Free the EM */
+out_netdev_cleanup:
+       fcoe_netdev_cleanup(fc);
 out_host_put:
        scsi_host_put(lp->host);
        return rc;
index 929411880e4b16c010ca7ca3d7369fddec6abd88..2f5bc7fd3fa90c5c3834fef6a377e025feb70f9f 100644 (file)
@@ -198,6 +198,8 @@ static void fcoe_ctlr_solicit(struct fcoe_ctlr *fip, struct fcoe_fcf *fcf)
        sol->fip.fip_subcode = FIP_SC_SOL;
        sol->fip.fip_dl_len = htons(sizeof(sol->desc) / FIP_BPW);
        sol->fip.fip_flags = htons(FIP_FL_FPMA);
+       if (fip->spma)
+               sol->fip.fip_flags |= htons(FIP_FL_SPMA);
 
        sol->desc.mac.fd_desc.fip_dtype = FIP_DT_MAC;
        sol->desc.mac.fd_desc.fip_dlen = sizeof(sol->desc.mac) / FIP_BPW;
@@ -350,6 +352,8 @@ static void fcoe_ctlr_send_keep_alive(struct fcoe_ctlr *fip, int ports, u8 *sa)
        kal->fip.fip_dl_len = htons((sizeof(kal->mac) +
                                    ports * sizeof(*vn)) / FIP_BPW);
        kal->fip.fip_flags = htons(FIP_FL_FPMA);
+       if (fip->spma)
+               kal->fip.fip_flags |= htons(FIP_FL_SPMA);
 
        kal->mac.fd_desc.fip_dtype = FIP_DT_MAC;
        kal->mac.fd_desc.fip_dlen = sizeof(kal->mac) / FIP_BPW;
@@ -413,6 +417,8 @@ static int fcoe_ctlr_encaps(struct fcoe_ctlr *fip,
        cap->fip.fip_subcode = FIP_SC_REQ;
        cap->fip.fip_dl_len = htons((dlen + sizeof(*mac)) / FIP_BPW);
        cap->fip.fip_flags = htons(FIP_FL_FPMA);
+       if (fip->spma)
+               cap->fip.fip_flags |= htons(FIP_FL_SPMA);
 
        cap->encaps.fd_desc.fip_dtype = dtype;
        cap->encaps.fd_desc.fip_dlen = dlen / FIP_BPW;
@@ -421,8 +427,10 @@ static int fcoe_ctlr_encaps(struct fcoe_ctlr *fip,
        memset(mac, 0, sizeof(mac));
        mac->fd_desc.fip_dtype = FIP_DT_MAC;
        mac->fd_desc.fip_dlen = sizeof(*mac) / FIP_BPW;
-       if (dtype != ELS_FLOGI)
+       if (dtype != FIP_DT_FLOGI)
                memcpy(mac->fd_mac, fip->data_src_addr, ETH_ALEN);
+       else if (fip->spma)
+               memcpy(mac->fd_mac, fip->ctl_src_addr, ETH_ALEN);
 
        skb->protocol = htons(ETH_P_FIP);
        skb_reset_mac_header(skb);
index 7546aa887fa7565417fe3a9f14956f5e9e314e40..79c9c5f5cdbae6995774d88b22fa61b370bc4eb3 100644 (file)
@@ -681,7 +681,7 @@ static int serial_config(struct pcmcia_device * link)
        u_char *buf;
        cisparse_t *parse;
        cistpl_cftable_entry_t *cf;
-       int i;
+       int i, last_ret, last_fn;
 
        DEBUG(0, "serial_config(0x%p)\n", link);
 
@@ -699,6 +699,16 @@ static int serial_config(struct pcmcia_device * link)
        tuple->TupleDataMax = 255;
        tuple->Attributes = 0;
 
+       /* Get configuration register information */
+       tuple->DesiredTuple = CISTPL_CONFIG;
+       last_ret = first_tuple(link, tuple, parse);
+       if (last_ret != 0) {
+               last_fn = ParseTuple;
+               goto cs_failed;
+       }
+       link->conf.ConfigBase = parse->config.base;
+       link->conf.Present = parse->config.rmask[0];
+
        /* Is this a compliant multifunction card? */
        tuple->DesiredTuple = CISTPL_LONGLINK_MFC;
        tuple->Attributes = TUPLE_RETURN_COMMON | TUPLE_RETURN_LINK;
@@ -761,7 +771,9 @@ static int serial_config(struct pcmcia_device * link)
        kfree(cfg_mem);
        return 0;
 
- failed:
+cs_failed:
+       cs_error(link, last_fn, last_ret);
+failed:
        serial_remove(link);
        kfree(cfg_mem);
        return -ENODEV;
@@ -863,10 +875,10 @@ static struct pcmcia_device_id serial_ids[] = {
        PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "LINKSYS", "PCMLM28", 0xf7cb0b07, 0x66881874, "PCMLM28.cis"),
        PCMCIA_MFC_DEVICE_CIS_PROD_ID12(1, "DAYNA COMMUNICATIONS", "LAN AND MODEM MULTIFUNCTION", 0x8fdf8f89, 0xdd5ed9e8, "DP83903.cis"),
        PCMCIA_MFC_DEVICE_CIS_PROD_ID4(1, "NSC MF LAN/Modem", 0x58fc6056, "DP83903.cis"),
-       PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0556, "3CCFEM556.cis"),
+       PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0556, "cis/3CCFEM556.cis"),
        PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0175, 0x0000, "DP83903.cis"),
-       PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0035, "3CXEM556.cis"),
-       PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x003d, "3CXEM556.cis"),
+       PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0035, "cis/3CXEM556.cis"),
+       PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x003d, "cis/3CXEM556.cis"),
        PCMCIA_DEVICE_CIS_PROD_ID12("Sierra Wireless", "AC850", 0xd85f6206, 0x42a2c018, "SW_8xx_SER.cis"),  /* Sierra Wireless AC850 3G Network Adapter R1 */
        PCMCIA_DEVICE_CIS_MANF_CARD(0x0192, 0x0710, "SW_7xx_SER.cis"),  /* Sierra Wireless AC710/AC750 GPRS Network Adapter R1 */
        PCMCIA_DEVICE_CIS_MANF_CARD(0x0192, 0xa555, "SW_555_SER.cis"),  /* Sierra Aircard 555 CDMA 1xrtt Modem -- pre update */
index 25c0ffd2faa00bd73cf6642abeade61292f4d6e6..43b3fe35261605d353c3c454c397fb271be92e15 100644 (file)
@@ -303,14 +303,18 @@ static int agnx_config(struct ieee80211_hw *dev, u32 changed)
        return 0;
 }
 
-static int agnx_config_interface(struct ieee80211_hw *dev,
-                                struct ieee80211_vif *vif,
-                                struct ieee80211_if_conf *conf)
+static void agnx_bss_info_changed(struct ieee80211_hw *dev,
+                                 struct ieee80211_vif *vif,
+                                 struct ieee80211_bss_conf *conf,
+                                 u32 changed)
 {
        struct agnx_priv *priv = dev->priv;
        void __iomem *ctl = priv->ctl;
        AGNX_TRACE;
 
+       if (!(changed & BSS_CHANGED_BSSID))
+               return;
+
        spin_lock(&priv->lock);
 
        if (memcmp(conf->bssid, priv->bssid, ETH_ALEN)) {
@@ -323,8 +327,7 @@ static int agnx_config_interface(struct ieee80211_hw *dev,
                agnx_write32(ctl, AGNX_BM_MTSM, 0xff & ~0x1);
        }
        spin_unlock(&priv->lock);
-       return 0;
-} /* agnx_config_interface */
+} /* agnx_bss_info_changed */
 
 
 static void agnx_configure_filter(struct ieee80211_hw *dev,
@@ -422,7 +425,7 @@ static struct ieee80211_ops agnx_ops = {
        .add_interface          = agnx_add_interface,
        .remove_interface       = agnx_remove_interface,
        .config                 = agnx_config,
-       .config_interface       = agnx_config_interface,
+       .bss_info_changed       = agnx_bss_info_changed,
        .configure_filter       = agnx_configure_filter,
        .get_stats              = agnx_get_stats,
        .get_tx_stats           = agnx_get_tx_stats,
index c8af9a868d6219bcf140b389c43d0b690338163e..3f303ae97b43daf902f9c666556bd521d9404be5 100644 (file)
@@ -3242,12 +3242,11 @@ static int at76_tx(struct sk_buff *skb, struct net_device *netdev)
                               "%s: -EINVAL: tx urb %p hcpriv %p complete %p\n",
                               priv->netdev->name, priv->tx_urb,
                               priv->tx_urb->hcpriv, priv->tx_urb->complete);
-       } else {
+       } else
                stats->tx_bytes += skb->len;
-               dev_kfree_skb(skb);
-       }
 
-       return ret;
+       dev_kfree_skb(skb);
+       return NETDEV_TX_OK;
 }
 
 static void at76_tx_timeout(struct net_device *netdev)
index 951c73d5db20529e0ef23ceae53e249b4c310651..59e99cc7786b11daefe0e84c30bac3b09dce6bc3 100644 (file)
@@ -585,11 +585,11 @@ int et131x_tx(struct sk_buff *skb, struct net_device *netdev)
                         * available
                         */
                        netif_stop_queue(netdev);
-                       status = 1;
+                       status = NETDEV_TX_BUSY;
                } else {
                        DBG_WARNING(et131x_dbginfo,
                                    "Misc error; drop packet\n");
-                       status = 0;
+                       status = NETDEV_TX_OK;
                }
        }
 
index 33a0687252afa4973000226f388bff2b3d179e55..1294e05fcf1356670eef223e55fc8da94c025f8b 100644 (file)
@@ -814,7 +814,7 @@ int ieee80211_xmit(struct sk_buff *skb,
        spin_unlock_irqrestore(&ieee->lock, flags);
        netif_stop_queue(dev);
        stats->tx_errors++;
-       return 1;
+       return NETDEV_TX_BUSY;
 
 }
 
index 393e4df70dfd87522898a7f998d6a5d8b2290966..bc0d764d851a1375e588f177fe5a3c2f2a33eb41 100644 (file)
@@ -432,21 +432,21 @@ static int p80211knetdev_hard_start_xmit(struct sk_buff *skb,
                /* success and more buf */
                /* avail, re: hw_txdata */
                netif_wake_queue(wlandev->netdev);
-               result = 0;
+               result = NETDEV_TX_OK;
        } else if (txresult == 1) {
                /* success, no more avail */
                pr_debug("txframe success, no more bufs\n");
                /* netdev->tbusy = 1;  don't set here, irqhdlr */
                /*   may have already cleared it */
-               result = 0;
+               result = NETDEV_TX_OK;
        } else if (txresult == 2) {
                /* alloc failure, drop frame */
                pr_debug("txframe returned alloc_fail\n");
-               result = 1;
+               result = NETDEV_TX_BUSY;
        } else {
                /* buffer full or queue busy, drop frame. */
                pr_debug("txframe returned full or busy\n");
-               result = 1;
+               result = NETDEV_TX_BUSY;
        }
 
 failed:
index c1abeb89b413f101d38174726f713c666581600b..96fb118355b0492d8350ff8524760290a4441de1 100644 (file)
@@ -188,8 +188,7 @@ static struct usb_descriptor_header *hs_pn_function[] = {
 
 static int pn_net_open(struct net_device *dev)
 {
-       if (netif_carrier_ok(dev))
-               netif_wake_queue(dev);
+       netif_wake_queue(dev);
        return 0;
 }
 
@@ -219,8 +218,7 @@ static void pn_tx_complete(struct usb_ep *ep, struct usb_request *req)
        }
 
        dev_kfree_skb_any(skb);
-       if (netif_carrier_ok(dev))
-               netif_wake_queue(dev);
+       netif_wake_queue(dev);
 }
 
 static int pn_net_xmit(struct sk_buff *skb, struct net_device *dev)
@@ -255,7 +253,7 @@ out_unlock:
        spin_unlock_irqrestore(&port->lock, flags);
 out:
        if (unlikely(skb)) {
-               dev_kfree_skb_any(skb);
+               dev_kfree_skb(skb);
                dev->stats.tx_dropped++;
        }
        return 0;
@@ -383,7 +381,6 @@ static void __pn_reset(struct usb_function *f)
        struct phonet_port *port = netdev_priv(dev);
 
        netif_carrier_off(dev);
-       netif_stop_queue(dev);
        port->usb = NULL;
 
        usb_ep_disable(fp->out_ep);
@@ -427,8 +424,6 @@ static int pn_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
                        fp->in_ep->driver_data = fp;
 
                        netif_carrier_on(dev);
-                       if (netif_running(dev))
-                               netif_wake_queue(dev);
                        for (i = 0; i < phonet_rxq_size; i++)
                                pn_rx_submit(fp, fp->out_reqv[i], GFP_ATOMIC);
                }
@@ -574,9 +569,10 @@ static struct net_device *dev;
 int __init phonet_bind_config(struct usb_configuration *c)
 {
        struct f_phonet *fp;
-       int err;
+       int err, size;
 
-       fp = kzalloc(sizeof(*fp), GFP_KERNEL);
+       size = sizeof(*fp) + (phonet_rxq_size * sizeof(struct usb_request *));
+       fp = kzalloc(size, GFP_KERNEL);
        if (!fp)
                return -ENOMEM;
 
@@ -601,16 +597,13 @@ int __init gphonet_setup(struct usb_gadget *gadget)
 
        /* Create net device */
        BUG_ON(dev);
-       dev = alloc_netdev(sizeof(*port)
-               + (phonet_rxq_size * sizeof(struct usb_request *)),
-                               "upnlink%d", pn_net_setup);
+       dev = alloc_netdev(sizeof(*port), "upnlink%d", pn_net_setup);
        if (!dev)
                return -ENOMEM;
 
        port = netdev_priv(dev);
        spin_lock_init(&port->lock);
        netif_carrier_off(dev);
-       netif_stop_queue(dev);
        SET_NETDEV_DEV(dev, &gadget->dev);
 
        err = register_netdev(dev);
index 4007770f7ed2230f52aded7917c7bae27d67a45d..016f63b39028abd2045dfd297285026d4801d6de 100644 (file)
@@ -520,7 +520,7 @@ static int eth_start_xmit(struct sk_buff *skb, struct net_device *net)
         */
        if (list_empty(&dev->tx_reqs)) {
                spin_unlock_irqrestore(&dev->req_lock, flags);
-               return 1;
+               return NETDEV_TX_BUSY;
        }
 
        req = container_of(dev->tx_reqs.next, struct usb_request, list);
index 40a3a2afbfe7588faed06e975be5fa0c82a21127..7a868bd16e0e2d35bff8b7842a7ceb6f9ef3f5c2 100644 (file)
@@ -1,13 +1,12 @@
 /*
- * xilinxfb.c
- *
- * Xilinx TFT LCD frame buffer driver
+ * Xilinx TFT frame buffer driver
  *
  * Author: MontaVista Software, Inc.
  *         source@mvista.com
  *
  * 2002-2007 (c) MontaVista Software, Inc.
  * 2007 (c) Secret Lab Technologies, Ltd.
+ * 2009 (c) Xilinx 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
 #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>
 #include <linux/fb.h>
 #include <linux/init.h>
 #include <linux/dma-mapping.h>
-#include <linux/platform_device.h>
-#if defined(CONFIG_OF)
 #include <linux/of_device.h>
 #include <linux/of_platform.h>
-#endif
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/xilinxfb.h>
+#include <asm/dcr.h>
 
 #define DRIVER_NAME            "xilinxfb"
-#define DRIVER_DESCRIPTION     "Xilinx TFT LCD frame buffer driver"
+
 
 /*
  * Xilinx calls it "PLB TFT LCD Controller" though it can also be used for
- * the VGA port on the Xilinx ML40x board. This is a hardware display controller
- * for a 640x480 resolution TFT or VGA screen.
+ * the VGA port on the Xilinx ML40x board. This is a hardware display
+ * controller for a 640x480 resolution TFT or VGA screen.
  *
  * The interface to the framebuffer is nice and simple.  There are two
  * control registers.  The first tells the LCD interface where in memory
  * the frame buffer is (only the 11 most significant bits are used, so
  * don't start thinking about scrolling).  The second allows the LCD to
  * be turned on or off as well as rotated 180 degrees.
+ *
+ * In case of direct PLB access the second control register will be at
+ * an offset of 4 as compared to the DCR access where the offset is 1
+ * i.e. REG_CTRL. So this is taken care in the function
+ * xilinx_fb_out_be32 where it left shifts the offset 2 times in case of
+ * direct PLB access.
  */
 #define NUM_REGS       2
 #define REG_FB_ADDR    0
@@ -107,17 +111,28 @@ static struct fb_var_screeninfo xilinx_fb_var = {
        .activate =     FB_ACTIVATE_NOW
 };
 
+
+#define PLB_ACCESS_FLAG        0x1             /* 1 = PLB, 0 = DCR */
+
 struct xilinxfb_drvdata {
 
        struct fb_info  info;           /* FB driver info record */
 
-       u32             regs_phys;      /* phys. address of the control registers */
-       u32 __iomem     *regs;          /* virt. address of the control registers */
+       phys_addr_t     regs_phys;      /* phys. address of the control
+                                               registers */
+       void __iomem    *regs;          /* virt. address of the control
+                                               registers */
+
+       dcr_host_t      dcr_host;
+       unsigned int    dcr_start;
+       unsigned int    dcr_len;
 
        void            *fb_virt;       /* virt. address of the frame buffer */
        dma_addr_t      fb_phys;        /* phys. address of the frame buffer */
        int             fb_alloced;     /* Flag, was the fb memory alloced? */
 
+       u8              flags;          /* features of the driver */
+
        u32             reg_ctrl_default;
 
        u32             pseudo_palette[PALETTE_ENTRIES_NO];
@@ -128,14 +143,19 @@ struct xilinxfb_drvdata {
        container_of(_info, struct xilinxfb_drvdata, info)
 
 /*
- * The LCD controller has DCR interface to its registers, but all
- * the boards and configurations the driver has been tested with
- * use opb2dcr bridge. So the registers are seen as memory mapped.
- * This macro is to make it simple to add the direct DCR access
- * when it's needed.
+ * The XPS TFT Controller can be accessed through PLB or DCR interface.
+ * To perform the read/write on the registers we need to check on
+ * which bus its connected and call the appropriate write API.
  */
-#define xilinx_fb_out_be32(driverdata, offset, val) \
-       out_be32(driverdata->regs + offset, val)
+static void xilinx_fb_out_be32(struct xilinxfb_drvdata *drvdata, u32 offset,
+                               u32 val)
+{
+       if (drvdata->flags & PLB_ACCESS_FLAG)
+               out_be32(drvdata->regs + (offset << 2), val);
+       else
+               dcr_write(drvdata->dcr_host, offset, val);
+
+}
 
 static int
 xilinx_fb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue,
@@ -203,35 +223,34 @@ static struct fb_ops xilinxfb_ops =
  * Bus independent setup/teardown
  */
 
-static int xilinxfb_assign(struct device *dev, unsigned long physaddr,
+static int xilinxfb_assign(struct device *dev,
+                          struct xilinxfb_drvdata *drvdata,
+                          unsigned long physaddr,
                           struct xilinxfb_platform_data *pdata)
 {
-       struct xilinxfb_drvdata *drvdata;
        int rc;
        int fbsize = pdata->xvirt * pdata->yvirt * BYTES_PER_PIXEL;
 
-       /* Allocate the driver data region */
-       drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL);
-       if (!drvdata) {
-               dev_err(dev, "Couldn't allocate device private record\n");
-               return -ENOMEM;
-       }
-       dev_set_drvdata(dev, drvdata);
-
-       /* Map the control registers in */
-       if (!request_mem_region(physaddr, 8, DRIVER_NAME)) {
-               dev_err(dev, "Couldn't lock memory region at 0x%08lX\n",
-                       physaddr);
-               rc = -ENODEV;
-               goto err_region;
-       }
-       drvdata->regs_phys = physaddr;
-       drvdata->regs = ioremap(physaddr, 8);
-       if (!drvdata->regs) {
-               dev_err(dev, "Couldn't lock memory region at 0x%08lX\n",
-                       physaddr);
-               rc = -ENODEV;
-               goto err_map;
+       if (drvdata->flags & PLB_ACCESS_FLAG) {
+               /*
+                * Map the control registers in if the controller
+                * is on direct PLB interface.
+                */
+               if (!request_mem_region(physaddr, 8, DRIVER_NAME)) {
+                       dev_err(dev, "Couldn't lock memory region at 0x%08lX\n",
+                               physaddr);
+                       rc = -ENODEV;
+                       goto err_region;
+               }
+
+               drvdata->regs_phys = physaddr;
+               drvdata->regs = ioremap(physaddr, 8);
+               if (!drvdata->regs) {
+                       dev_err(dev, "Couldn't lock memory region at 0x%08lX\n",
+                               physaddr);
+                       rc = -ENODEV;
+                       goto err_map;
+               }
        }
 
        /* Allocate the framebuffer memory */
@@ -247,7 +266,10 @@ static int xilinxfb_assign(struct device *dev, unsigned long physaddr,
        if (!drvdata->fb_virt) {
                dev_err(dev, "Could not allocate frame buffer memory\n");
                rc = -ENOMEM;
-               goto err_fbmem;
+               if (drvdata->flags & PLB_ACCESS_FLAG)
+                       goto err_fbmem;
+               else
+                       goto err_region;
        }
 
        /* Clear (turn to black) the framebuffer */
@@ -260,7 +282,8 @@ static int xilinxfb_assign(struct device *dev, unsigned long physaddr,
        drvdata->reg_ctrl_default = REG_CTRL_ENABLE;
        if (pdata->rotate_screen)
                drvdata->reg_ctrl_default |= REG_CTRL_ROTATE;
-       xilinx_fb_out_be32(drvdata, REG_CTRL, drvdata->reg_ctrl_default);
+       xilinx_fb_out_be32(drvdata, REG_CTRL,
+                                       drvdata->reg_ctrl_default);
 
        /* Fill struct fb_info */
        drvdata->info.device = dev;
@@ -296,11 +319,14 @@ static int xilinxfb_assign(struct device *dev, unsigned long physaddr,
                goto err_regfb;
        }
 
+       if (drvdata->flags & PLB_ACCESS_FLAG) {
+               /* Put a banner in the log (for DEBUG) */
+               dev_dbg(dev, "regs: phys=%lx, virt=%p\n", physaddr,
+                                       drvdata->regs);
+       }
        /* Put a banner in the log (for DEBUG) */
-       dev_dbg(dev, "regs: phys=%lx, virt=%p\n", physaddr, drvdata->regs);
-       dev_dbg(dev, "fb: phys=%llx, virt=%p, size=%x\n",
-               (unsigned long long) drvdata->fb_phys, drvdata->fb_virt,
-               fbsize);
+       dev_dbg(dev, "fb: phys=%p, virt=%p, size=%x\n",
+               (void *)drvdata->fb_phys, drvdata->fb_virt, fbsize);
 
        return 0;       /* success */
 
@@ -311,14 +337,19 @@ err_cmap:
        if (drvdata->fb_alloced)
                dma_free_coherent(dev, PAGE_ALIGN(fbsize), drvdata->fb_virt,
                        drvdata->fb_phys);
+       else
+               iounmap(drvdata->fb_virt);
+
        /* Turn off the display */
        xilinx_fb_out_be32(drvdata, REG_CTRL, 0);
 
 err_fbmem:
-       iounmap(drvdata->regs);
+       if (drvdata->flags & PLB_ACCESS_FLAG)
+               iounmap(drvdata->regs);
 
 err_map:
-       release_mem_region(physaddr, 8);
+       if (drvdata->flags & PLB_ACCESS_FLAG)
+               release_mem_region(physaddr, 8);
 
 err_region:
        kfree(drvdata);
@@ -342,12 +373,18 @@ static int xilinxfb_release(struct device *dev)
        if (drvdata->fb_alloced)
                dma_free_coherent(dev, PAGE_ALIGN(drvdata->info.fix.smem_len),
                                  drvdata->fb_virt, drvdata->fb_phys);
+       else
+               iounmap(drvdata->fb_virt);
 
        /* Turn off the display */
        xilinx_fb_out_be32(drvdata, REG_CTRL, 0);
-       iounmap(drvdata->regs);
 
-       release_mem_region(drvdata->regs_phys, 8);
+       /* Release the resources, as allocated based on interface */
+       if (drvdata->flags & PLB_ACCESS_FLAG) {
+               iounmap(drvdata->regs);
+               release_mem_region(drvdata->regs_phys, 8);
+       } else
+               dcr_unmap(drvdata->dcr_host, drvdata->dcr_len);
 
        kfree(drvdata);
        dev_set_drvdata(dev, NULL);
@@ -355,78 +392,58 @@ static int xilinxfb_release(struct device *dev)
        return 0;
 }
 
-/* ---------------------------------------------------------------------
- * Platform bus binding
- */
-
-static int
-xilinxfb_platform_probe(struct platform_device *pdev)
-{
-       struct xilinxfb_platform_data *pdata;
-       struct resource *res;
-
-       /* Find the registers address */
-       res = platform_get_resource(pdev, IORESOURCE_IO, 0);
-       if (!res) {
-               dev_err(&pdev->dev, "Couldn't get registers resource\n");
-               return -ENODEV;
-       }
-
-       /* If a pdata structure is provided, then extract the parameters */
-       pdata = &xilinx_fb_default_pdata;
-       if (pdev->dev.platform_data) {
-               pdata = pdev->dev.platform_data;
-               if (!pdata->xres)
-                       pdata->xres = xilinx_fb_default_pdata.xres;
-               if (!pdata->yres)
-                       pdata->yres = xilinx_fb_default_pdata.yres;
-               if (!pdata->xvirt)
-                       pdata->xvirt = xilinx_fb_default_pdata.xvirt;
-               if (!pdata->yvirt)
-                       pdata->yvirt = xilinx_fb_default_pdata.yvirt;
-       }
-
-       return xilinxfb_assign(&pdev->dev, res->start, pdata);
-}
-
-static int
-xilinxfb_platform_remove(struct platform_device *pdev)
-{
-       return xilinxfb_release(&pdev->dev);
-}
-
-
-static struct platform_driver xilinxfb_platform_driver = {
-       .probe          = xilinxfb_platform_probe,
-       .remove         = xilinxfb_platform_remove,
-       .driver = {
-               .owner = THIS_MODULE,
-               .name = DRIVER_NAME,
-       },
-};
-
 /* ---------------------------------------------------------------------
  * OF bus binding
  */
 
-#if defined(CONFIG_OF)
 static int __devinit
 xilinxfb_of_probe(struct of_device *op, const struct of_device_id *match)
 {
-       struct resource res;
        const u32 *prop;
+       u32 *p;
+       u32 tft_access;
        struct xilinxfb_platform_data pdata;
+       struct resource res;
        int size, rc;
+       int start = 0, len = 0;
+       dcr_host_t dcr_host;
+       struct xilinxfb_drvdata *drvdata;
 
        /* Copy with the default pdata (not a ptr reference!) */
        pdata = xilinx_fb_default_pdata;
 
        dev_dbg(&op->dev, "xilinxfb_of_probe(%p, %p)\n", op, match);
 
-       rc = of_address_to_resource(op->node, 0, &res);
-       if (rc) {
-               dev_err(&op->dev, "invalid address\n");
-               return rc;
+       /*
+        * To check whether the core is connected directly to DCR or PLB
+        * interface and initialize the tft_access accordingly.
+        */
+       p = (u32 *)of_get_property(op->node, "xlnx,dcr-splb-slave-if", NULL);
+
+       if (p)
+               tft_access = *p;
+       else
+               tft_access = 0;         /* For backward compatibility */
+
+       /*
+        * Fill the resource structure if its direct PLB interface
+        * otherwise fill the dcr_host structure.
+        */
+       if (tft_access) {
+               rc = of_address_to_resource(op->node, 0, &res);
+               if (rc) {
+                       dev_err(&op->dev, "invalid address\n");
+                       return -ENODEV;
+               }
+
+       } else {
+               start = dcr_resource_start(op->node, 0);
+               len = dcr_resource_len(op->node, 0);
+               dcr_host = dcr_map(op->node, start, len);
+               if (!DCR_MAP_OK(dcr_host)) {
+                       dev_err(&op->dev, "invalid address\n");
+                       return -ENODEV;
+               }
        }
 
        prop = of_get_property(op->node, "phys-size", &size);
@@ -450,7 +467,26 @@ xilinxfb_of_probe(struct of_device *op, const struct of_device_id *match)
        if (of_find_property(op->node, "rotate-display", NULL))
                pdata.rotate_screen = 1;
 
-       return xilinxfb_assign(&op->dev, res.start, &pdata);
+       /* Allocate the driver data region */
+       drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL);
+       if (!drvdata) {
+               dev_err(&op->dev, "Couldn't allocate device private record\n");
+               return -ENOMEM;
+       }
+       dev_set_drvdata(&op->dev, drvdata);
+
+       if (tft_access)
+               drvdata->flags |= PLB_ACCESS_FLAG;
+
+       /* Arguments are passed based on the interface */
+       if (drvdata->flags & PLB_ACCESS_FLAG) {
+               return xilinxfb_assign(&op->dev, drvdata, res.start, &pdata);
+       } else {
+               drvdata->dcr_start = start;
+               drvdata->dcr_len = len;
+               drvdata->dcr_host = dcr_host;
+               return xilinxfb_assign(&op->dev, drvdata, 0, &pdata);
+       }
 }
 
 static int __devexit xilinxfb_of_remove(struct of_device *op)
@@ -460,7 +496,9 @@ static int __devexit xilinxfb_of_remove(struct of_device *op)
 
 /* Match table for of_platform binding */
 static struct of_device_id xilinxfb_of_match[] __devinitdata = {
+       { .compatible = "xlnx,xps-tft-1.00.a", },
        { .compatible = "xlnx,plb-tft-cntlr-ref-1.00.a", },
+       { .compatible = "xlnx,plb-dvi-cntlr-ref-1.00.c", },
        {},
 };
 MODULE_DEVICE_TABLE(of, xilinxfb_of_match);
@@ -476,22 +514,6 @@ static struct of_platform_driver xilinxfb_of_driver = {
        },
 };
 
-/* Registration helpers to keep the number of #ifdefs to a minimum */
-static inline int __init xilinxfb_of_register(void)
-{
-       pr_debug("xilinxfb: calling of_register_platform_driver()\n");
-       return of_register_platform_driver(&xilinxfb_of_driver);
-}
-
-static inline void __exit xilinxfb_of_unregister(void)
-{
-       of_unregister_platform_driver(&xilinxfb_of_driver);
-}
-#else /* CONFIG_OF */
-/* CONFIG_OF not enabled; do nothing helpers */
-static inline int __init xilinxfb_of_register(void) { return 0; }
-static inline void __exit xilinxfb_of_unregister(void) { }
-#endif /* CONFIG_OF */
 
 /* ---------------------------------------------------------------------
  * Module setup and teardown
@@ -500,28 +522,18 @@ static inline void __exit xilinxfb_of_unregister(void) { }
 static int __init
 xilinxfb_init(void)
 {
-       int rc;
-       rc = xilinxfb_of_register();
-       if (rc)
-               return rc;
-
-       rc = platform_driver_register(&xilinxfb_platform_driver);
-       if (rc)
-               xilinxfb_of_unregister();
-
-       return rc;
+       return of_register_platform_driver(&xilinxfb_of_driver);
 }
 
 static void __exit
 xilinxfb_cleanup(void)
 {
-       platform_driver_unregister(&xilinxfb_platform_driver);
-       xilinxfb_of_unregister();
+       of_unregister_platform_driver(&xilinxfb_of_driver);
 }
 
 module_init(xilinxfb_init);
 module_exit(xilinxfb_cleanup);
 
 MODULE_AUTHOR("MontaVista Software, Inc. <source@mvista.com>");
-MODULE_DESCRIPTION(DRIVER_DESCRIPTION);
+MODULE_DESCRIPTION("Xilinx TFT frame buffer driver");
 MODULE_LICENSE("GPL");
index 25200d106ee8b762a1eec464d4e0cf4699e08061..621de8e952f7cc3e9c94aaa7f18d9095bcf9fc69 100644 (file)
@@ -32,6 +32,7 @@ fw-shipped-$(CONFIG_ADAPTEC_STARFIRE) += adaptec/starfire_rx.bin \
                                         adaptec/starfire_tx.bin
 fw-shipped-$(CONFIG_ATARI_DSP56K) += dsp56k/bootstrap.bin
 fw-shipped-$(CONFIG_ATM_AMBASSADOR) += atmsar11.fw
+fw-shipped-$(CONFIG_BNX2X) += bnx2x-e1-4.8.53.0.fw bnx2x-e1h-4.8.53.0.fw
 fw-shipped-$(CONFIG_BNX2) += bnx2/bnx2-mips-09-4.6.17.fw \
                             bnx2/bnx2-rv2p-09-4.6.15.fw \
                             bnx2/bnx2-mips-06-4.6.16.fw \
@@ -40,13 +41,15 @@ fw-shipped-$(CONFIG_CASSINI) += sun/cassini.bin
 fw-shipped-$(CONFIG_COMPUTONE) += intelliport2.bin
 fw-shipped-$(CONFIG_CHELSIO_T3) += cxgb3/t3b_psram-1.1.0.bin \
                                   cxgb3/t3c_psram-1.1.0.bin \
-                                  cxgb3/t3fw-7.1.0.bin
+                                  cxgb3/t3fw-7.4.0.bin
 fw-shipped-$(CONFIG_DVB_AV7110) += av7110/bootcode.bin
 fw-shipped-$(CONFIG_DVB_TTUSB_BUDGET) += ttusb-budget/dspbootcode.bin
 fw-shipped-$(CONFIG_E100) += e100/d101m_ucode.bin e100/d101s_ucode.bin \
                             e100/d102e_ucode.bin
 fw-shipped-$(CONFIG_MYRI_SBUS) += myricom/lanai.bin
 fw-shipped-$(CONFIG_PCMCIA_PCNET) += cis/LA-PCM.cis
+fw-shipped-$(CONFIG_PCMCIA_3C589) += cis/3CXEM556.cis
+fw-shipped-$(CONFIG_PCMCIA_3C574) += cis/3CCFEM556.cis
 fw-shipped-$(CONFIG_PCMCIA_SMC91C92) += ositech/Xilinx7OD.bin
 fw-shipped-$(CONFIG_SCSI_ADVANSYS) += advansys/mcode.bin advansys/38C1600.bin \
                                      advansys/3550.bin advansys/38C0800.bin
index 4c52984a8319608aada4666325e3d3497f92643b..0f5649a08c0c0d5b2802c10c94e769a4b34043be 100644 (file)
@@ -412,7 +412,7 @@ Driver: cxgb3 - Chelsio Terminator 3 1G/10G Ethernet adapter
 
 File: cxgb3/t3b_psram-1.1.0.bin.ihex
 File: cxgb3/t3c_psram-1.1.0.bin.ihex
-file: cxgb3/t3fw-7.1.0.bin.ihex
+file: cxgb3/t3fw-7.4.0.bin.ihex
 
 License: GPLv2 or OpenIB.org BSD license, no source visible
 
@@ -586,6 +586,26 @@ Originally developed by the pcmcia-cs project
 
 --------------------------------------------------------------------------
 
+Driver: PCMCIA_3C589 - 3Com PCMCIA adapter
+
+File: cis/3CXEM556.cis
+
+Licence: GPL
+
+Originally developed by the pcmcia-cs project
+
+--------------------------------------------------------------------------
+
+Driver: PCMCIA_3C574 - 3Com PCMCIA adapter
+
+File: cis/3CCFEM556.cis
+
+Licence: GPL
+
+Originally developed by the pcmcia-cs project
+
+--------------------------------------------------------------------------
+
 Driver: PCMCIA_SMC91C92 - SMC 91Cxx PCMCIA
 
 File: ositech/Xilinx7OD.bin
@@ -614,6 +634,26 @@ File: myricom/lanai.bin
 
 Licence: Unknown
 
+Found in hex form in kernel source.
+
+--------------------------------------------------------------------------
+
+Driver: bnx2x: Broadcom Everest
+
+File: bnx2x-e1-4.8.53.0.fw.ihex
+File: bnx2x-e1h-4.8.53.0.fw.ihex
+
+License:
+  Copyright (c) 2007-2009 Broadcom Corporation
+
+  This file contains firmware data derived from proprietary unpublished
+  source code, Copyright (c) 2007-2009 Broadcom Corporation.
+
+  Permission is hereby granted for the distribution of this firmware data
+  in hexadecimal or equivalent format, provided this copyright notice is
+  accompanying it.
+
+
 Found in hex form in kernel source.
 
 --------------------------------------------------------------------------
diff --git a/firmware/bnx2x-e1-4.8.53.0.fw.ihex b/firmware/bnx2x-e1-4.8.53.0.fw.ihex
new file mode 100644 (file)
index 0000000..f1edb1e
--- /dev/null
@@ -0,0 +1,10364 @@
+:10000000000028600000006000000630000028C8E2
+:100010000000160800002F000000009400004510AA
+:10002000000073C8000045A8000000C40000B978B3
+:100030000000A4680000BA400000007400015EB037
+:100040000000559000015F28000000B80001B4C016
+:100050000000D1F80001B580000000040002878094
+:10006000020400480000000F020400540000004594
+:1000700002040058000000840204005C0000000636
+:100080000204007000000004020400780000000078
+:100090000204007C121700000204008022170000F6
+:1000A00002040084321700000604008800000005E6
+:1000B0000204009C12150000020400A0221500009A
+:1000C000020400A432150000060400A80000000489
+:1000D000020400B802100000020400BC001000007E
+:1000E000020400C010100000020400C42010000030
+:1000F000020400C830100000060400CC0000000418
+:10010000020400DC00100000020400E012140000F1
+:10011000020400E422140000020400E8321400008B
+:10012000060400EC000000040104012400000000AB
+:1001300001040128000000000104012C000000005F
+:10014000010401300000000002040004000000FF70
+:1001500002040008000000FF0204000C000000FF81
+:1001600002040010000000FF02040014000000FF61
+:1001700002040018000000FF0204001C000000FF41
+:1001800002040020000000FF020400240000003EE2
+:1001900002040028000000000204002C0000003FC0
+:1001A000020400300000003F020400340000003F61
+:1001B00002040038000000000204003C0000003F80
+:1001C000020400400000003F020400440000003F21
+:1001D00002042008000004110204200C00000400A6
+:1001E000020420100000040402042014000004197A
+:1001F0000204201C0000FFFF020420200000FFFF7B
+:10020000020420240000FFFF020420280000FFFF5A
+:1002100006042038000000020204204000000034E0
+:100220000204204400000035060420480000007C41
+:100230000204223807FFFFFF0204223C0000003FB7
+:100240000204224007FFFFFF020422440000000FC7
+:1002500001042248000000000104224C00000000BC
+:10026000010422500000000001042254000000009C
+:1002700001042258000000000104225C000000007C
+:10028000010422600000000001042264000000005C
+:1002900001042268000000000104226C000000003C
+:1002A000010422700000000001042274000000001C
+:1002B00001042278000000000104227C00000000FC
+:1002C000020424BC000000010C042000000003E82C
+:1002D0000A042000000000010B0420000000000AB6
+:1002E0000205004400000020020500480000003222
+:1002F000020500900215002002050094021500205E
+:1003000002050098000000300205009C0810000063
+:10031000020500A000000033020500A40000003028
+:10032000020500A800000031020500AC0000000238
+:10033000020500B000000005020500B40000000640
+:10034000020500B800000002020500BC0000000227
+:10035000020500C000000000020500C40000000506
+:10036000020500C800000002020500CC00000002E7
+:10037000020500D000000002020500D400000001C8
+:1003800002050114000000010205011C000000012B
+:100390000205012000000002020502040000000125
+:1003A0000205020C0000004002050210000000409F
+:1003B0000205021C000000200205022000000013BC
+:1003C0000205022400000020060502400000000A89
+:1003D0000405028000200000020500500000000714
+:1003E0000205005400000007020500580000000844
+:1003F0000205005C00000008060500600000000423
+:10040000020500D800000006020500E00000000D13
+:10041000020500E40000002D020500E800000007CE
+:10042000020500EC00000027020500F000000007B4
+:10043000020500F400000027020500F80000000794
+:10044000020500FC00000027020500040000000176
+:1004500002050008000000010205000C0000000178
+:100460000205001000000001020500140000000158
+:1004700002050018000000010205001C0000000138
+:100480000205002000000001020500240000000118
+:1004900002050028000000010205002C00000001F8
+:1004A00002050030000000010205003400000001D8
+:1004B00002050038000000010205003C00000001B8
+:1004C00002050040000000010406100002000020A8
+:1004D000020600DC00000001010600D80000000058
+:1004E0000406020000030220020600DC00000000F7
+:1004F00002060068000000B802060078000001143F
+:10050000010600B800000000010600C8000000005D
+:100510000206006C000000B80206007C0000011416
+:10052000010600BC00000000010600CC0000000035
+:100530000718040000930000081807600014022345
+:10054000071C0000324F0000071C800033250C946C
+:10055000071D00000E4D195E081D1E005C4002259F
+:100560000118000000000000011800040000000055
+:1005700001180008000000000118000C0000000035
+:100580000118001000000000011800140000000015
+:1005900002180020000000010218002400000002E0
+:1005A00002180028000000030218002C00000000C0
+:1005B000021800300000000402180034000000019E
+:1005C00002180038000000000218003C0000000182
+:1005D000021800400000000402180044000000005F
+:1005E00002180048000000010218004C000000033F
+:1005F0000218005000000000021800540000000122
+:1006000002180058000000040218005C00000000FE
+:1006100002180060000000010218006400000003DE
+:1006200002180068000000000218006C00000001C1
+:10063000021800700000000402180074000000009E
+:1006400002180078000000040218007C000000037B
+:100650000618008000000002021800A400003FFFFE
+:10066000021800A8000003FF021802240000000086
+:1006700002180234000000000218024C00000000C2
+:10068000021802E4000000FF061810000000040039
+:10069000021B8BC000000001021B80000000003420
+:1006A000021B804000000018021B80800000000C2C
+:1006B000021B80C0000000200C1B83000007A1204B
+:1006C0000A1B8300000001380B1B83000000138805
+:1006D000021B83C0000001F4061A2000000000B2D3
+:1006E000061A23C8000000C1041A26CC0001022704
+:1006F000061A1020000000C8061A100000000002B0
+:10070000061A1C1800000004061A1C100000000243
+:10071000061A080000000002061A0808000000027D
+:10072000061A081000000004041A1FB00004022872
+:10073000041A4CB00008022C061A22C8000000203F
+:10074000061A40000000016C021A4B600000000015
+:10075000061A14000000000A061A145000000006D1
+:10076000061A150000000002041A150800050234DC
+:10077000061A151C00000007061A1570000000126A
+:10078000061A09C00000004C061A0800000000020A
+:10079000061A08200000000E041A1FB000020239D9
+:1007A000061A290800000002061A2348000000204B
+:1007B000061A45B00000016C021A4B6400000000EC
+:1007C000061A14280000000A061A14680000000621
+:1007D000061A153800000002041A15400005023BF5
+:1007E000061A155400000007061A15B8000000127A
+:1007F000061A0AF00000004C061A08080000000261
+:10080000061A08580000000E041A1FB80002024021
+:10081000061A2910000000020200A2800000000158
+:100820000200A294071D29110200A29800000000F6
+:100830000200A29C009C04240200A2A00000000070
+:100840000200A2A4000002090200A4FCFF000000B4
+:10085000020100B400000001020100B80000000124
+:10086000020100DC000000010201010000000001A3
+:1008700002010104000000010201007C00300000C0
+:1008800002010084000000280201008C000000002A
+:1008900002010130000000040201025C00000001BE
+:1008A000020103280000000002010554000000308E
+:1008B000020100C400000001020100CC00000001A0
+:1008C000020100F800000001020100F00000000138
+:1008D00002010080003000000201008800000028B2
+:1008E0000201009000000000020101340000000439
+:1008F000020102DC000000010201032C00000000E4
+:100900000201056400000030020100C8000000017F
+:10091000020100D000000001020100FC0000000103
+:10092000020100F400000001020C10000000002091
+:10093000020C200800000A11020C200C00000A0022
+:10094000020C201000000A04020C201C0000FFFF13
+:10095000020C20200000FFFF020C20240000FFFFFB
+:10096000020C20280000FFFF020C2038000000C607
+:10097000020C203C00000000020C2040000000346B
+:10098000020C204400000035060C20480000001C2A
+:10099000020C20B800000001060C20BC0000005F23
+:1009A000020C223807FFFFFF020C223C0000003F30
+:1009B000020C224007FFFFFF020C22440000000F40
+:1009C000010C224800000000010C224C0000000035
+:1009D000010C225000000000010C22540000000015
+:1009E000010C225800000000010C225C00000000F5
+:1009F000010C226000000000010C226400000000D5
+:100A0000010C226800000000010C226C00000000B4
+:100A1000010C227000000000010C22740000000094
+:100A2000010C227800000000010C227C0000000074
+:100A3000020C24BC000000010C0C2000000003E8A4
+:100A40000A0C2000000000010B0C20000000000A2E
+:100A5000020C400800000A11020C400C00000A00C1
+:100A6000020C401000000A04020C401400000A218D
+:100A7000020C401C0000FFFF020C40200000FFFFA2
+:100A8000020C40240000FFFF020C40280000FFFF82
+:100A9000020C403800000046020C403C00000005FB
+:100AA000020C404000000034020C404400000035BD
+:100AB000060C40480000005C020C41B80000000138
+:100AC000060C41BC0000001F020C423807FFFFFF6C
+:100AD000020C423C0000003F020C424007FFFFFFB7
+:100AE000020C42440000000F010C424800000000CC
+:100AF000010C424C00000000010C425000000000BC
+:100B0000010C425400000000010C4258000000009B
+:100B1000010C425C00000000010C4260000000007B
+:100B2000010C426400000000010C4268000000005B
+:100B3000010C426C00000000010C4270000000003B
+:100B4000010C427400000000010C4278000000001B
+:100B5000010C427C00000000010C428000000000FB
+:100B6000020C44C0000000010C0C4000000003E82F
+:100B70000A0C4000000000010B0C40000000000ABD
+:100B8000020D004400000032020D008C021500200E
+:100B9000020D009002150020020D009408100000C4
+:100BA000020D009800000033020D009C00000002BE
+:100BB000020D00A000000000020D00A400000005CE
+:100BC000020D00A800000005060D00AC00000002A8
+:100BD000020D00B400000002020D00B80000000386
+:100BE000020D00BC00000002020D00C00000000168
+:100BF000020D00C800000002020D00CC000000023F
+:100C0000020D010800000001020D015C000000015E
+:100C1000020D016400000001020D016800000002E5
+:100C2000020D020400000001020D020C0000002071
+:100C3000020D021000000040020D021400000040EE
+:100C4000020D022000000003020D02240000001823
+:100C5000060D028000000012040D03000024024271
+:100C6000020D004C00000001020D005000000002C7
+:100C7000020D005400000008020D0058000000089A
+:100C8000060D005C00000004020D00C4000000041A
+:100C9000020D011400000009020D011800000029D6
+:100CA000020D011C0000000A020D01200000002AB4
+:100CB000020D012400000007020D0128000000279A
+:100CC000020D012C00000007020D0130000000277A
+:100CD000020D01340000000C020D01380000002C50
+:100CE000020D013C0000000C020D01400000002C30
+:100CF000020D01440000000C020D01480000002C10
+:100D0000020D000400000001020D000800000001B7
+:100D1000020D000C00000001020D00100000000197
+:100D2000020D001400000001020D00180000000177
+:100D3000020D001C00000001020D00200000000157
+:100D4000020D002400000001020D00280000000137
+:100D5000020D002C00000001020D00300000000117
+:100D6000020D003400000001020D003800000001F7
+:100D7000020D003C00000001020E004C0000003299
+:100D8000020E009402150020020E009802150020A9
+:100D9000020E009C00000030020E00A008100000AF
+:100DA000020E00A400000033020E00A80000003074
+:100DB000020E00AC00000031020E00B00000000284
+:100DC000020E00B400000004020E00B80000000093
+:100DD000020E00BC00000002020E00C00000000273
+:100DE000020E00C400000000020E00C80000000255
+:100DF000020E00CC00000007020E00D0000000022E
+:100E0000020E00D400000002020E00D80000000113
+:100E1000020E00E400000001020E01440000000187
+:100E2000020E014C00000001020E01500000000201
+:100E3000020E020400000001020E020C000000403D
+:100E4000020E021000000040020E021C000000040E
+:100E5000020E022000000020020E02240000000EFC
+:100E6000020E02280000001B060E03000000001204
+:100E7000040E0280001B0266020E005400000010E7
+:100E8000020E005800000007020E005C0000000F78
+:100E9000020E006000000010060E00640000000456
+:100EA000020E00DC00000003020E01100000000F23
+:100EB000020E01140000002F020E01180000000EA7
+:100EC000020E011C0000002E020E000400000001B2
+:100ED000020E000800000001020E000C00000001DC
+:100EE000020E001000000001020E001400000001BC
+:100EF000020E001800000001020E001C000000019C
+:100F0000020E002000000001020E0024000000017B
+:100F1000020E002800000001020E002C000000015B
+:100F2000020E003000000001020E0034000000013B
+:100F3000020E003800000001020E003C000000011B
+:100F4000020E004000000001020E004400000001FB
+:100F50000730040000C30000083007680013028156
+:100F600007340000314C00000734800035EF0C548A
+:100F700007350000361319D00735800007112755B3
+:100F800008358EE04E24028301300000000000008E
+:100F900001300004000000000130000800000000E3
+:100FA0000130000C000000000130001000000000C3
+:100FB0000130001400000000023000200000000199
+:100FC000023000240000000202300028000000036C
+:100FD0000230002C0000000002300030000000044D
+:100FE0000230003400000001023000380000000030
+:100FF0000230003C0000000102300040000000040C
+:1010000002300044000000000230004800000001EF
+:101010000230004C000000030230005000000000CD
+:1010200002300054000000010230005800000004AB
+:101030000230005C0000000002300060000000018F
+:10104000023000640000000302300068000000006D
+:101050000230006C0000000102300070000000044B
+:10106000023000740000000002300078000000042C
+:101070000230007C00000003063000800000000207
+:10108000023000A400003FFF023000A8000003FF70
+:101090000230022400000000023002340000000090
+:1010A0000230024C00000000023002E40000FFFFAA
+:1010B000063020000000080002338BC00000000151
+:1010C000023380000000001A023380400000004E0E
+:1010D0000233808000000010023380C00000002036
+:1010E0000C3383000007A1200A338300000001387D
+:1010F0000B33830000001388023383C0000001F427
+:101100000C3383801DCD65000A3383800004C4B492
+:101110000B338380004C4B4006325000000000C26D
+:1011200006321020000000C8063210000000000245
+:101130000632464000000040063257F0000000042E
+:10114000063257D800000005043257EC0001028532
+:1011500006321C60000000200432283000020286A3
+:10116000023308000100000004330C000010028864
+:10117000023308000000000004330C400010029805
+:1011800006321400000000A0063219000000001012
+:10119000063219800000003006324740000000B4DB
+:1011A00002321D900000000006321B4000000004C7
+:1011B00006321B6000000020063253180000009821
+:1011C00006321680000000A0063219400000001010
+:1011D00006321A400000003006324A10000000B407
+:1011E00002321D940000000006321B500000000473
+:1011F00006321BE0000000200632557800000098FF
+:10120000072004000071000008200780001002A8D9
+:1012100007240000322900000724800023630C8B80
+:101220000824C930654002AA012000000000000027
+:101230000120000400000000012000080000000060
+:101240000120000C00000000012000100000000040
+:101250000120001400000000022000200000000116
+:1012600002200024000000020220002800000003E9
+:101270000220002C000000000220003000000004CA
+:1012800002200034000000010220003800000000AD
+:101290000220003C00000001022000400000000489
+:1012A000022000440000000002200048000000016D
+:1012B0000220004C0000000302200050000000004B
+:1012C0000220005400000001022000580000000429
+:1012D0000220005C0000000002200060000000010D
+:1012E00002200064000000030220006800000000EB
+:1012F0000220006C000000010220007000000004C9
+:1013000002200074000000000220007800000004A9
+:101310000220007C00000003062000800000000284
+:10132000022000A400003FFF022000A8000003FFED
+:10133000022002240000000002200234000000000D
+:101340000220024C00000000022002E40000FFFF27
+:10135000062020000000080002238BC000000001CE
+:1013600002238000000000100223804000000012D1
+:101370000223808000000030022380C00000000EA5
+:10138000022383C0000001F4062250000000004246
+:1013900006221020000000C80622100000000002F3
+:1013A00006222000000000C00622307000000080ED
+:1013B0000622428000000004062225C000000240F0
+:1013C00004222EC8000802AC02230800013FFFFFE0
+:1013D00004230C00001002B40223080000000000E7
+:1013E00004230C40001002C406221400000000A0D8
+:1013F00006221900000000100622198000000030AB
+:101400000222511800000000062223000000000EF6
+:1014100006223040000000060622241000000030A2
+:1014200006221680000000A00622194000000010CD
+:1014300006221A40000000300222511C0000000069
+:10144000062223380000000E062230580000000655
+:10145000062224D0000000300216100000000020F8
+:1014600002170008000000020217002C0000000311
+:101470000217003C000000040217004400000008AE
+:1014800002170048000000020217004C0000009004
+:1014900002170050000000900217005400800090D6
+:1014A0000217005808140000021700600000008AAC
+:1014B000021700640000008002170068000000901E
+:1014C0000217006C00000080021700700000000688
+:1014D00002170078000007D00217007C0000076C9C
+:1014E00002170038007C1004021700040000000FEF
+:1014F0000616402400000002021640700000001C86
+:10150000021642080000000102164210000000010D
+:1015100002164220000000010216422800000001CD
+:10152000021642300000000102164238000000019D
+:1015300002164260000000010C16401C0003D0900F
+:101540000A16401C0000009C0B16401C000009C439
+:101550000216403000000008021640340000000C63
+:10156000021640380000001002164044000000201F
+:101570000216400000000001021640D800000001E1
+:1015800002164008000000010216400C0000000195
+:101590000216401000000001021642400000000048
+:1015A00002164248000000000616427000000002C9
+:1015B00002164250000000000216425800000000CF
+:1015C00006164280000000020216600800000614A1
+:1015D0000216600C000006000216601000000604EF
+:1015E0000216601C0000FFFF021660200000FFFFD3
+:1015F000021660240000FFFF021660280000FFFFB3
+:1016000002166038000000200216603C0000002036
+:1016100002166040000000340216604400000035ED
+:1016200002166048000000230216604C00000024EF
+:1016300002166050000000250216605400000026CB
+:1016400002166058000000270216605C00000029A6
+:10165000021660600000002A021660640000002B81
+:10166000021660680000002C0216606C0000002D5D
+:101670000616607000000052021661B800000001FA
+:10168000061661BC0000001F0216623807FFFFFF4C
+:101690000216623C0000003F0216624007FFFFFF97
+:1016A000021662440000000F0116624800000000AC
+:1016B0000116624C0000000001166250000000009C
+:1016C000011662540000000001166258000000007C
+:1016D0000116625C0000000001166260000000005C
+:1016E000011662640000000001166268000000003C
+:1016F0000116626C0000000001166270000000001C
+:1017000001166274000000000116627800000000FB
+:101710000116627C00000000021664BC000000019B
+:101720000C166000000003E80A16600000000001CB
+:101730000B1660000000000A021680400000000640
+:101740000216804400000005021680480000000ACE
+:101750000216804C000000050216805400000002B2
+:10176000021680CC00000004021680D000000004A5
+:10177000021680D400000004021680D80000000485
+:10178000021680DC00000004021680E00000000465
+:10179000021680E400000004021680E80000000445
+:1017A0000216880400000004021680300000007C4D
+:1017B000021680340000003D021680380000003F11
+:1017C0000216803C0000009C021680F0000000071A
+:1017D000061680F4000000050216880C01010101C4
+:1017E00002168108000000000216810C00000004AF
+:1017F000021681100000000402168114000000028D
+:101800000216881008012004021681180000000545
+:101810000216811C00000005021681200000000550
+:1018200002168124000000050216882C20081001F1
+:1018300002168128000000080216812C0000000614
+:1018400002168130000000070216813400000000FB
+:1018500002168830010101200616813800000004BC
+:1018600002168834010101010616814800000004B7
+:101870000216883801010101061681580000000493
+:101880000216883C01010101061681680000000370
+:101890000216817400000001021688400101010156
+:1018A00002168178000000010216817C0000000110
+:1018B00002168180000000010216818400000001F0
+:1018C000021688440101010102168188000000010E
+:1018D0000216818C000000040216819000000004B2
+:1018E00002168194000000020216884808012004B4
+:1018F00002168198000000050216819C0000000578
+:10190000021681A000000005021681A40000000557
+:101910000216881420081001021681A80000000891
+:10192000021681AC00000006021681B0000000071C
+:10193000021681B40000000102168818010101207E
+:10194000021681B800000001021681BC00000001EF
+:10195000021681C000000001021681C400000001CF
+:101960000216881C01010101021681C80000000155
+:10197000021681CC00000001021681D00000000197
+:10198000021681D400000001021688200101010125
+:10199000021681D800000001021681DC000000015F
+:1019A000021681E000000001021681E4000000013F
+:1019B0000216882401010101021681E800000001DD
+:1019C000021681EC00000001021681F00000000107
+:1019D000021688280101010102168240FFFF003F24
+:1019E00006168244000000020216824CFFFF003FF0
+:1019F000021682500000010002168254000001000D
+:101A0000061682580000000202168260000000C024
+:101A100002168264000000C00216826800001E00E8
+:101A20000216826C00001E00021682700000400048
+:101A300002168274000040000216827800008000C6
+:101A40000216827C000080000216828000002000C6
+:101A5000021682840000200006168288000000071B
+:101A6000021682A400000001061682A80000000AE7
+:101A7000021681F400000C08021681F800000040F4
+:101A8000021681FC00000100021682000000002006
+:101A9000021682040000001702168208000000806F
+:101AA0000216820C000002000216821000000000E4
+:101AB00002168218FFFF01FF02168214FFFF01FFCA
+:101AC0000216823C00000013021680900000013FC5
+:101AD0000216806000000140021680640000014090
+:101AE000061680680000000202168070000000C028
+:101AF00006168074000000070216809C0000004853
+:101B0000021680A000000048061680A40000000213
+:101B1000021680AC00000048061680B000000007E6
+:101B2000021682380000800002168234000025E48C
+:101B30000216809400007FFF02168220000000073A
+:101B40000216821C00000007021682280000000016
+:101B500002168224FFFFFFFF021682300000000001
+:101B60000216822CFFFFFFFF021680EC000000FF30
+:101B700002140000000000010214000C000000012B
+:101B800002140040000000010214004400007FFF26
+:101B90000214000C0000000002140000000000000D
+:101BA0000214006C00000000021400040000000198
+:101BB00002140030000000010214000400000000C4
+:101BC0000214005C00000000021400080000000184
+:101BD000021400340000000102140008000000009C
+:101BE00002140060000000000202005800000032F1
+:101BF000020200A003150020020200A40315002029
+:101C0000020200A801000030020200AC081000002F
+:101C1000020200B000000033020200B400000030F5
+:101C2000020200B800000031020200BC0000000304
+:101C3000020200C000000006020200C4000000030F
+:101C4000020200C800000003020200CC00000002F3
+:101C5000020200D000000000020200D400000002D6
+:101C6000020200DC00000000020200E000000006AA
+:101C7000020200E400000004020200E8000000028A
+:101C8000020200EC00000002020200F0000000016D
+:101C9000020200FC00000006020201200000000019
+:101CA0000202013400000002020201B00000000143
+:101CB0000202020C000000010202021400000001F6
+:101CC00002020218000000020202040400000001E7
+:101CD0000202040C00000040020204100000004058
+:101CE0000202041C00000004020204200000002084
+:101CF0000202042400000002020204280000001F67
+:101D0000060205000000001204020480001F02D435
+:101D1000020200600000000F0202006400000007E1
+:101D2000020200680000000B0202006C0000000EBE
+:101D30000602007000000004020200F4000000042B
+:101D4000020200040000000102020008000000017D
+:101D50000202000C0000000102020010000000015D
+:101D6000020200140000000102020018000000013D
+:101D70000202001C0000000102020020000000011D
+:101D800002020024000000010202002800000001FD
+:101D90000202002C000000010202003000000001DD
+:101DA00002020034000000010202003800000001BD
+:101DB0000202003C0000000102020040000000019D
+:101DC000020200440000000102020048000000017D
+:101DD0000202004C0000000102020050000000015D
+:101DE00002020108000000C80202011800000002FF
+:101DF000020201C400000000020201CC0000000049
+:101E0000020201D400000002020201DC0000000214
+:101E1000020201E4000000FF020201EC000000FFEA
+:101E20000202010C000000C80202011C00000002B6
+:101E3000020201C800000000020201D00000000000
+:101E4000020201D800000002020201E000000002CC
+:101E5000020201E8000000FF020201F0000000FFA2
+:101E60000728040000B5000008280768001302F3E3
+:101E7000072C000033660000072C800038B30CDA12
+:101E8000072D00003BB11B07072D80002A2629F4EF
+:101E9000082DD6C0452802F50128000000000000EA
+:101EA00001280004000000000128000800000000D4
+:101EB0000128000C000000000128001000000000B4
+:101EC000012800140000000002280020000000018A
+:101ED000022800240000000202280028000000035D
+:101EE0000228002C0000000002280030000000043E
+:101EF0000228003400000001022800380000000021
+:101F00000228003C000000010228004000000004FC
+:101F100002280044000000000228004800000001E0
+:101F20000228004C000000030228005000000000BE
+:101F3000022800540000000102280058000000049C
+:101F40000228005C00000000022800600000000180
+:101F5000022800640000000302280068000000005E
+:101F60000228006C0000000102280070000000043C
+:101F7000022800740000000002280078000000041D
+:101F80000228007C000000030628008000000002F8
+:101F9000022800A400003FFF022800A8000003FF61
+:101FA0000228022400000000022802340000000081
+:101FB0000228024C00000000022802E40000FFFF9B
+:101FC0000628200000000800022B8BC00000000142
+:101FD000022B800000000000022B8040000000184F
+:101FE000022B80800000000C022B80C000000066E5
+:101FF0000C2B83000007A1200A2B8300000001386E
+:102000000B2B830000001388022B83C0000001F417
+:102010000C2B8340000001F40A2B834000000000D9
+:102020000B2B8340000000050A2B83800004C4B4FE
+:102030000C2B83801DCD65000B2B8380004C4B4007
+:10204000062A3D6000000004042A3D70000202F7E9
+:10205000062A300000000048062A1020000000C8B0
+:10206000062A100000000002062A31280000008E17
+:10207000022A336800000000042A3370000202F9CB
+:10208000042A3B90000402FB042A3E20000202FFC7
+:10209000022A151800000001022A18300000000072
+:1020A000022A183800000000042A18200002030148
+:1020B000062A4AC000000002062A4B000000000465
+:1020C000042A1F4800020303022B0800000000003E
+:1020D000042B0C0000100305022B08000100000077
+:1020E000042B0C4000080315022B0800020000001E
+:1020F000042B0C600008031D062A3BA000000014FE
+:10210000062A3C4000000024062A14000000000AB1
+:10211000062A145000000006062A3378000000FC4E
+:10212000022A3B5800000000042A3D7800020325E3
+:10213000042A3D8800100327022A15000000000031
+:10214000022A150800000001062A502000000002A3
+:10215000062A503000000002062A5000000000024B
+:10216000062A501000000002022A50400000000021
+:10217000062A50480000000E022A50B80000000154
+:10218000042A4AC800020337062A4B100000004206
+:10219000062A4D2000000004062A3BF0000000142F
+:1021A000062A3CD000000024062A14280000000A59
+:1021B000062A146800000006062A3768000000FCA2
+:1021C000022A3B5C00000000042A3D800002033923
+:1021D000042A3DC80010033B022A15040000000039
+:1021E000022A150C00000001062A502800000002F7
+:1021F000062A503800000002062A5008000000029B
+:10220000062A501800000002022A50440000000074
+:10221000062A50800000000E022A50BC0000000177
+:10222000042A4AD00002034B062A4C180000004240
+:10223000062A4D30000000040210100800000001C2
+:10224000021010000003D000021010040000003D36
+:10225000091018000200034D091011000020054D5F
+:102260000610118000000002091011880006056D9B
+:10227000061011A00000001806102400000000E065
+:102280000210201C000000000210202000000001AD
+:10229000021020C000000001021020040000000114
+:1022A000021020080000000109103C000005057321
+:1022B00009103C2000050578091038000005057D4F
+:1022C00002104028000000100210404400003FFFB0
+:1022D0000210405800280000021040840084924AF6
+:1022E0000210405800000000061080680000000442
+:1022F00002108000000010800610802800000002FC
+:102300000210803800000010021080400000FFFF23
+:10231000021080440000FFFF021080500000000007
+:102320000210810000000000061081200000000261
+:1023300002108008000002B50210801000000000AA
+:10234000061082000000004A021081080001FFFF11
+:1023500006108140000000020210800000001A8078
+:102360000610900000000024061091200000004A92
+:10237000061093700000004A061095C00000004A45
+:10238000021080040000108006108030000000025F
+:102390000210803C00000010021080480000FFFF87
+:1023A0000210804C0000FFFF02108054000000006B
+:1023B00002108104000000000610812800000002C5
+:1023C0000210800C000002B5021080140000000012
+:1023D000061084000000004A0210810C0001FFFF7B
+:1023E00006108148000000020210800400001A80DC
+:1023F0000610909000000024061092480000004A49
+:10240000061094980000004A061096E80000004A62
+:102410000212049000E383400212051400003C10F5
+:1024200002120494FFFFFFFF02120498FFFFFFFF58
+:102430000212049CFFFFFFFF021204A0FFFFFFFF38
+:10244000021204A4FFFFFFFF021204A8FFFFFFFF18
+:10245000021204ACFFFFFFFF021204B0FFFFFFFFF8
+:10246000021204B8FFFFFFFF021204BCFFFFFFFFD0
+:10247000021204C0FFFFFFFF021204C4FFFFFFFFB0
+:10248000021204C8FFFFFFFF021204CCFFFFFFFF90
+:10249000021204D0FFFFFFFF021204DCFFFFFFFF68
+:1024A000021204E0FFFFFFFF021204E4FFFFFFFF40
+:1024B000021204E8FFFFFFFF021204ECFFFFFFFF20
+:1024C000021204F0FFFFFFFF021204F4FFFFFFFF00
+:1024D000021204F8FFFFFFFF021204FCFFFFFFFFE0
+:1024E00002120500FFFFFFFF02120504FFFFFFFFBE
+:1024F00002120508FFFFFFFF0212050CFFFFFFFF9E
+:1025000002120510FFFFFFFF021204D4FFFF333059
+:10251000021204D8FFFF3340021204B4F00030006E
+:1025200002120390000000080212039C0000000841
+:10253000021203A000000008021203A4000000021F
+:10254000021203BC00000004021203C000000005D8
+:10255000021203C400000004021203D000000000B5
+:102560000212036C00000001021203680000003F29
+:10257000021201BC00000040021201C00000180855
+:10258000021201C400000803021201C8000008037F
+:10259000021201CC00000040021201D00000000332
+:1025A000021201D400000803021201D8000008033F
+:1025B000021201DC00000803021201E00001000326
+:1025C000021201E400000803021201E800000803FF
+:1025D000021201EC00000003021201F000000003EF
+:1025E000021201F400000003021201F800000003CF
+:1025F000021201FC000000030212020000000003AE
+:10260000021202040000000302120208000000038C
+:102610000212020C0000000302120210000000036C
+:10262000021202140000000302120218000000034C
+:102630000212021C0000000302120220000000032C
+:1026400002120224000000030212022800002403E8
+:102650000212022C0000002F0212023000000009BA
+:102660000212023400000019021202380000018434
+:102670000212023C00000183021202400000030625
+:102680000212024400000019021202480000000673
+:102690000212024C00000306021202500000030660
+:1026A00002120254000003060212025800000C86B7
+:1026B0000212025C00000306021202600000030620
+:1026C0000212026400000006021202680000000606
+:1026D0000212026C000000060212027000000006E6
+:1026E00002120274000000060212027800000006C6
+:1026F0000212027C000000060212028000000006A6
+:102700000212028400000006021202880000000685
+:102710000212028C00000006021202900000000665
+:102720000212029400000006021202980000000645
+:102730000212029C00000006021202A00000030622
+:10274000021202A400000013021202A800000006F8
+:10275000021202B000001004021202B400001004C1
+:102760000212032400106440021203280010644087
+:10277000021201B0000000010600A00000000016D7
+:102780000200A06CBF5C00000200A070FFF51FEF0C
+:102790000200A0740000FFFF0200A078500003E0D8
+:1027A0000200A07C000000000200A0800000A00049
+:1027B0000600A084000000050200A0980FE00000C1
+:1027C0000600A09C000000140200A0EC555400007C
+:1027D0000200A0F0555555550200A0F400005555D3
+:1027E0000200A0F8000000000200A0FC5554000008
+:1027F0000200A100555555550200A1040000555591
+:102800000200A108000000000200A22C000000004D
+:102810000600A230000000030200A06000000007D4
+:102820000200A10CBF5C00000200A110FFF51FEF29
+:102830000200A1140000FFFF0200A118500003E0F5
+:102840000200A11C000000000200A1200000A00066
+:102850000600A124000000050200A1380FE00000DE
+:102860000600A13C000000140200A18C5554000099
+:102870000200A190555555550200A19400005555F0
+:102880000200A198000000000200A19C5554000025
+:102890000200A1A0555555550200A1A400005555B0
+:1028A0000200A1A8000000000200A23C00000000FD
+:1028B0000600A240000000030200A0640000000720
+:1028C00000000000000000000000002E00000000DA
+:1028D00000000000000000000000000000000000F8
+:1028E00000000000000000000000000000000000E8
+:1028F00000000000000000000000000000000000D8
+:1029000000000000000000000000000000000000C7
+:1029100000000000000000000000000000000000B7
+:10292000002E005000000000000000000000000029
+:102930000000000000000000000000000000000097
+:102940000000000000000000000000000050008DAA
+:102950000000000000000000000000000000000077
+:102960000000000000000000000000000000000067
+:102970000000000000000000008D00920092009610
+:102980000096009A00000000000000000000000017
+:102990000000000000000000000000000000000037
+:1029A00000000000009A00DB00DB00E900E900F70E
+:1029B0000000000000000000000000000000000017
+:1029C0000000000000000000000000000000000007
+:1029D00000000000000000000000000000000000F7
+:1029E00000000000000000000000000000000000E7
+:1029F00000000000000000000000000000000000D7
+:102A000000000000000000000000000000000000C6
+:102A100000000000000000000000000000000000B6
+:102A200000000000000000000000000000000000A6
+:102A30000000000000000000000000000000000096
+:102A40000000000000000000000000000000000086
+:102A50000000000000000000000000000000000076
+:102A60000000000000000000000000000000000066
+:102A70000000000000000000000000000000000056
+:102A800000F700FE00000000000000000000000051
+:102A90000000000000000000000000000000000036
+:102AA0000000000000000000000000000000000026
+:102AB0000000000000000000000000000000000016
+:102AC0000000000000000000000000000000000006
+:102AD000000000000000000000FE01030103010EE1
+:102AE000010E0119000000000000000000000000BD
+:102AF00000000000000000000000000000000000D6
+:102B000000000000000000000000000000000000C5
+:102B100000000000000000000000000000000000B5
+:102B200000000000000000000000000000000000A5
+:102B30000119011A00000000000000000000000060
+:102B40000000000000000000000000000000000085
+:102B5000000000000000000000000000011A013E1B
+:102B60000000000000000000000000000000000065
+:102B70000000000000000000000000000000000055
+:102B80000000000000000000013E016400000000A1
+:102B90000000000000000000000000000000000035
+:102BA0000000000000000000000000000000000025
+:102BB00000000000016401A300000000000000000C
+:102BC0000000000000000000000000000000000005
+:102BD00000000000000000000000000000000000F5
+:102BE00001A301DE00000000000000000000000062
+:102BF00000000000000000000000000000000000D5
+:102C000000000000000000000000000001DE0224BF
+:102C10000224022C022C02340000000000000000FC
+:102C200000000000000000000000000000000000A4
+:102C300000000000000000000234027102710278FE
+:102C40000278027F00000000000000000000000089
+:102C50000000000000000000000000000000000074
+:102C600000000000027F0280000000000000000061
+:102C70000000000000000000000000000000000054
+:102C80000000000000000000000000000000000044
+:102C9000028002920000000000000000000000001E
+:102CA0000000000000000000000000000000000024
+:102CB000000000000000000000000000029202A7D7
+:102CC00002A702AA02AA02AD000000000000000054
+:102CD00000000000000000000000000000000000F4
+:102CE000000000000000000002AD02DB0000000058
+:102CF00000000000000000000000000000000000D4
+:102D000000000000000000000000000000000000C3
+:102D10000000000002DB0362000000000000000071
+:102D200000000000000000000000000000000000A3
+:102D30000000000000000000000000000000000093
+:102D4000036203690369036D036D037100000000F2
+:102D50000000000000000000000000000000000073
+:102D6000000000000000000000000000037103B03C
+:102D700003B003B803B803C0000000000000000067
+:102D80000000000000000000000000000000000043
+:102D9000000000000000000003C004130413042717
+:102DA0000427043B000000000000000000000000B9
+:102DB0000000000000000000000000000000000013
+:102DC00000000000043B044300000000000000007D
+:102DD00000000000000000000000000000000000F3
+:102DE00000000000000000000000000000000000E3
+:102DF000044304490000000000000000000000003F
+:102E000000000000000000000000000000000000C2
+:102E10000000000000000000000000000449044C15
+:102E200000000000000000000000000000000000A2
+:102E30000000000000000000000000000000000092
+:102E40000000000000000000044C045100000000DD
+:102E50000000000000000000000000000000000072
+:102E60000000000000000000000000000000000062
+:102E70000000000004510452045204640464047607
+:102E80000000000000000000000000000000000042
+:102E90000000000000000000000000000000000032
+:102EA000047604E3000000000000000000000000C1
+:102EB0000000000000000000000000000000000012
+:102EC00000000000000000000000000004E304E433
+:102ED00004E404F804F8050C000000000000000001
+:102EE00000000000000000000000000000000000E2
+:102EF00000000000000000000000000000000000D2
+:102F000000010000000204C00003098000040E401C
+:102F100000051300000617C000071C8000082140B0
+:102F200000092600000A2AC0000B2F80000C344044
+:102F3000000D3900000E3DC0000F428000104740D8
+:102F400000114C00001250C00013558000145A406C
+:102F500000155F00001663C00017688000186D4000
+:102F600000197200001A76C0001B7B80001C804094
+:102F7000001D8500001E89C0001F8E800020934028
+:102F80000000200000004000000060000000800001
+:102F90000000A0000000C0000000E00000010000F0
+:102FA00000012000000140000001600000018000DD
+:102FB0000001A0000001C0000001E00000020000CC
+:102FC00000022000000240000002600000028000B9
+:102FD0000002A0000002C0000002E00000030000A8
+:102FE0000003200000034000000360000003800095
+:102FF0000003A0000003C0000003E0000004000084
+:103000000004200000044000000460000004800070
+:103010000004A0000004C0000004E000000500005F
+:10302000000520000005400000056000000580004C
+:103030000005A0000005C0000005E000000600003B
+:103040000006200000064000000660000006800028
+:103050000006A0000006C0000006E0000007000017
+:103060000007200000074000000760000007800004
+:103070000007A0000007C0000007E00000080000F3
+:1030800000082000000840000008600000088000E0
+:103090000008A0000008C0000008E00000090000CF
+:1030A00000092000000940000009600000098000BC
+:1030B0000009A0000009C0000009E000000A0000AB
+:1030C000000A2000000A4000000A6000000A800098
+:1030D000000AA000000AC000000AE000000B000087
+:1030E000000B2000000B4000000B6000000B800074
+:1030F000000BA000000BC000000BE000000C000063
+:10310000000C2000000C4000000C6000000C80004F
+:10311000000CA000000CC000000CE000000D00003E
+:10312000000D2000000D4000000D6000000D80002B
+:10313000000DA000000DC000000DE000000E00001A
+:10314000000E2000000E4000000E6000000E800007
+:10315000000EA000000EC000000EE000000F0000F6
+:10316000000F2000000F4000000F6000000F8000E3
+:10317000000FA000000FC000000FE00000100000D2
+:1031800000102000001040000010600000108000BF
+:103190000010A0000010C0000010E00000110000AE
+:1031A000001120000011400000116000001180009B
+:1031B0000011A0000011C0000011E000001200008A
+:1031C0000012200000124000001260000012800077
+:1031D0000012A0000012C0000012E0000013000066
+:1031E0000013200000134000001360000013800053
+:1031F0000013A0000013C0000013E0000014000042
+:10320000001420000014400000146000001480002E
+:103210000014A0000014C0000014E000001500001D
+:10322000001520000015400000156000001580000A
+:103230000015A0000015C0000015E00000160000F9
+:1032400000162000001640000016600000168000E6
+:103250000016A0000016C0000016E00000170000D5
+:1032600000172000001740000017600000178000C2
+:103270000017A0000017C0000017E00000180000B1
+:10328000001820000018400000186000001880009E
+:103290000018A0000018C0000018E000001900008D
+:1032A000001920000019400000196000001980007A
+:1032B0000019A0000019C0000019E000001A000069
+:1032C000001A2000001A4000001A6000001A800056
+:1032D000001AA000001AC000001AE000001B000045
+:1032E000001B2000001B4000001B6000001B800032
+:1032F000001BA000001BC000001BE000001C000021
+:10330000001C2000001C4000001C6000001C80000D
+:10331000001CA000001CC000001CE000001D0000FC
+:10332000001D2000001D4000001D6000001D8000E9
+:10333000001DA000001DC000001DE000001E0000D8
+:10334000001E2000001E4000001E6000001E8000C5
+:10335000001EA000001EC000001EE000001F0000B4
+:10336000001F2000001F4000001F6000001F8000A1
+:10337000001FA000001FC000001FE0000020000090
+:10338000002020000020400000206000002080007D
+:103390000020A0000020C0000020E000002100006C
+:1033A0000021200000214000002160000021800059
+:1033B0000021A0000021C0000021E0000022000048
+:1033C0000022200000224000002260000022800035
+:1033D0000022A0000022C0000022E0000023000024
+:1033E0000023200000234000002360000023800011
+:1033F0000023A0000023C0000023E0000024000000
+:1034000000242000002440000024600000248000EC
+:103410000024A0000024C0000024E00000250000DB
+:1034200000252000002540000025600000258000C8
+:103430000025A0000025C0000025E00000260000B7
+:1034400000262000002640000026600000268000A4
+:103450000026A0000026C0000026E0000027000093
+:103460000027200000274000002760000027800080
+:103470000027A0000027C0000027E000002800006F
+:10348000002820000028400000286000002880005C
+:103490000028A0000028C0000028E000002900004B
+:1034A0000029200000294000002960000029800038
+:1034B0000029A0000029C0000029E000002A000027
+:1034C000002A2000002A4000002A6000002A800014
+:1034D000002AA000002AC000002AE000002B000003
+:1034E000002B2000002B4000002B6000002B8000F0
+:1034F000002BA000002BC000002BE000002C0000DF
+:10350000002C2000002C4000002C6000002C8000CB
+:10351000002CA000002CC000002CE000002D0000BA
+:10352000002D2000002D4000002D6000002D8000A7
+:10353000002DA000002DC000002DE000002E000096
+:10354000002E2000002E4000002E6000002E800083
+:10355000002EA000002EC000002EE000002F000072
+:10356000002F2000002F4000002F6000002F80005F
+:10357000002FA000002FC000002FE000003000004E
+:10358000003020000030400000306000003080003B
+:103590000030A0000030C0000030E000003100002A
+:1035A0000031200000314000003160000031800017
+:1035B0000031A0000031C0000031E0000032000006
+:1035C00000322000003240000032600000328000F3
+:1035D0000032A0000032C0000032E00000330000E2
+:1035E00000332000003340000033600000338000CF
+:1035F0000033A0000033C0000033E00000340000BE
+:1036000000342000003440000034600000348000AA
+:103610000034A0000034C0000034E0000035000099
+:103620000035200000354000003560000035800086
+:103630000035A0000035C0000035E0000036000075
+:103640000036200000364000003660000036800062
+:103650000036A0000036C0000036E0000037000051
+:10366000003720000037400000376000003780003E
+:103670000037A0000037C0000037E000003800002D
+:10368000003820000038400000386000003880001A
+:103690000038A0000038C0000038E0000039000009
+:1036A00000392000003940000039600000398000F6
+:1036B0000039A0000039C0000039E000003A0000E5
+:1036C000003A2000003A4000003A6000003A8000D2
+:1036D000003AA000003AC000003AE000003B0000C1
+:1036E000003B2000003B4000003B6000003B8000AE
+:1036F000003BA000003BC000003BE000003C00009D
+:10370000003C2000003C4000003C6000003C800089
+:10371000003CA000003CC000003CE000003D000078
+:10372000003D2000003D4000003D6000003D800065
+:10373000003DA000003DC000003DE000003E000054
+:10374000003E2000003E4000003E6000003E800041
+:10375000003EA000003EC000003EE000003F000030
+:10376000003F2000003F4000003F6000003F80001D
+:10377000003FA000003FC000003FE000003FE0012C
+:1037800000000000000001FF0000020000007FF8C0
+:1037900000007FF8000002920000350000000001E8
+:1037A0000000000300BEBC200000000300BEBC20DF
+:1037B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF19
+:1037C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF09
+:1037D000FFFFFFFF00000000FFFFFFFF00000000F1
+:1037E000FFFFFFFF0000000300BEBC20FFFFFFFF44
+:1037F00000000000FFFFFFFF00000000FFFFFFFFD1
+:103800000000000300BEBC2000002000000040C0FB
+:1038100000006180000082400000A3000000C3C0DF
+:103820000000E4800001054000012600000146C0C0
+:1038300000016780000188400001A9000001C9C0A3
+:103840000001EA8000020B4000022C0000024CC084
+:1038500000026D8000028E400002AF000002CFC067
+:103860000002F0800003114000033200000352C048
+:1038700000037380000394400003B5000003D5C02B
+:103880000003F6800004174000043800000458C00C
+:103890000004798000049A40000080000001038049
+:1038A0000001870000020A8000028E0000031180E0
+:1038B000000395000004188000049C0000051F8090
+:1038C0000005A300000626800006AA0000072D8040
+:1038D0000007B100000834800008B80000093B80F0
+:1038E0000009BF00000A4280000AC600000B4980A0
+:1038F000000BCD00000C5080000CD400000D578050
+:10390000000DDB0000007FF800007FF8000003E5F9
+:10391000000015000000190000000000FFFFFFFF7D
+:103920004000000040000000400000004000000097
+:103930004000000040000000400000004000000087
+:103940004000000040000000400000004000000077
+:103950004000000040000000400000004000000067
+:103960004000000040000000400000004000000057
+:103970004000000040000000400000004000000047
+:103980004000000040000000400000004000000037
+:103990004000000040000000400000004000000027
+:1039A00000007FF800007FF8000003C80000150049
+:1039B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF17
+:1039C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF07
+:1039D00040000000400000004000000040000000E7
+:1039E00040000000400000004000000040000000D7
+:1039F00040000000400000004000000040000000C7
+:103A000040000000400000004000000040000000B6
+:103A100040000000400000004000000040000000A6
+:103A20004000000040000000400000004000000096
+:103A30004000000040000000400000004000000086
+:103A40004000000040000000400000004000000076
+:103A500000001000000020800000310000004180C4
+:103A600000005200000062800000730000008380AC
+:103A7000000094000000A4800000B5000000C58094
+:103A80000000D6000000E6800000F700000107807B
+:103A90000001180000012880000139000001498060
+:103AA00000015A0000016A8000017B0000018B8048
+:103AB00000019C000001AC800001BD000001CD8030
+:103AC0000001DE000001EE800001FF0000007FF831
+:103AD00000007FF800000207000035001000000021
+:103AE000000028AD000000000001000100350804BE
+:103AF000CCCCCCC1FFFFFFFFFFFFFFFF7058103C95
+:103B000000000000CCCC0201CCCCCCCC00000000EA
+:103B1000FFFFFFFF400000004000000040000000E9
+:103B20004000000040000000400000004000000095
+:103B30004000000040000000400000004000000085
+:103B40004000000040000000400000004000000075
+:103B50004000000040000000400000004000000065
+:103B60004000000040000000400000004000000055
+:103B70004000000040000000400000004000000045
+:103B80004000000040000000400000004000000035
+:103B900040000000000E01B7011600D60000FFFF34
+:103BA000000000000000FFFF000000000000FFFF19
+:103BB000000000000000FFFF000000000000FFFF09
+:103BC000000000000000FFFF000000000000FFFFF9
+:103BD000000000000000FFFF0000000000100000D7
+:103BE00000000000007201BB012300F30000FFFF92
+:103BF000000000000000FFFF000000000000FFFFC9
+:103C0000000000000000FFFF000000000000FFFFB8
+:103C1000000000000000FFFF000000000000FFFFA8
+:103C2000000000000000FFFF000000000010000086
+:103C300000000000FFFFFFF3320FFFFF0C30C30C4A
+:103C4000C30C30C3CF3CF300F3CF3CF30000CF3CB8
+:103C5000CDCDCDCDFFFFFFF130EFFFFF0C30C30C1A
+:103C6000C30C30C3CF3CF300F3CF3CF30001CF3C97
+:103C7000CDCDCDCDFFFFFFF6305FFFFF0C30C30C85
+:103C8000C30C30C3CF3CF300F3CF3CF30002CF3C76
+:103C9000CDCDCDCDFFFFF4061CBFFFFF0C30C3051B
+:103CA000C30C30C3CF300014F3CF3CF30004CF3C3F
+:103CB000CDCDCDCDFFFFFFF2304FFFFF0C30C30C59
+:103CC000C30C30C3CF3CF300F3CF3CF30008CF3C30
+:103CD000CDCDCDCDFFFFFFFA302FFFFF0C30C30C51
+:103CE000C30C30C3CF3CF300F3CF3CF30010CF3C08
+:103CF000CDCDCDCDFFFFFFF731EFFFFF0C30C30C73
+:103D0000C30C30C3CF3CF300F3CF3CF30020CF3CD7
+:103D1000CDCDCDCDFFFFFFF5302FFFFF0C30C30C15
+:103D2000C30C30C3CF3CF300F3CF3CF30040CF3C97
+:103D3000CDCDCDCDFFFFFFF3310FFFFF0C30C30C16
+:103D4000C30C30C3CF3CF300F3CF3CF30000CF3CB7
+:103D5000CDCDCDCDFFFFFFF1310FFFFF0C30C30CF8
+:103D6000C30C30C3CF3CF300F3CF3CF30001CF3C96
+:103D7000CDCDCDCDFFFFFFF6305FFFFF0C30C30C84
+:103D8000C30C30C3CF3CF300F3CF3CF30002CF3C75
+:103D9000CDCDCDCDFFFFF4061CBFFFFF0C30C3051A
+:103DA000C30C30C3CF300014F3CF3CF30004CF3C3E
+:103DB000CDCDCDCDFFFFFFF2304FFFFF0C30C30C58
+:103DC000C30C30C3CF3CF300F3CF3CF30008CF3C2F
+:103DD000CDCDCDCDFFFFFFFA302FFFFF0C30C30C50
+:103DE000C30C30C3CF3CF300F3CF3CF30010CF3C07
+:103DF000CDCDCDCDFFFFFFF730EFFFFF0C30C30C73
+:103E0000C30C30C3CF3CF300F3CF3CF30020CF3CD6
+:103E1000CDCDCDCDFFFFFFF5304FFFFF0C30C30CF4
+:103E2000C30C30C3CF3CF300F3CF3CF30040CF3C96
+:103E3000CDCDCDCDFFFFFFF331EFFFFF0C30C30C35
+:103E4000C30C30C3CF3CF300F3CF3CF30000CF3CB6
+:103E5000CDCDCDCDFFFFFFF1310FFFFF0C30C30CF7
+:103E6000C30C30C3CF3CF300F3CF3CF30001CF3C95
+:103E7000CDCDCDCDFFFFFFF6305FFFFF0C30C30C83
+:103E8000C30C30C3CF3CF300F3CF3CF30002CF3C74
+:103E9000CDCDCDCDFFFFF4061CBFFFFF0C30C30519
+:103EA000C30C30C3CF300014F3CF3CF30004CF3C3D
+:103EB000CDCDCDCDFFFFFFF2304FFFFF0C30C30C57
+:103EC000C30C30C3CF3CF300F3CF3CF30008CF3C2E
+:103ED000CDCDCDCDFFFFFFFA302FFFFF0C30C30C4F
+:103EE000C30C30C3CF3CF300F3CF3CF30010CF3C06
+:103EF000CDCDCDCDFFFFFF97056FFFFF0C30C30C7D
+:103F0000C30C30C3CF3CC000F3CF3CF30020CF3C08
+:103F1000CDCDCDCDFFFFFFF5310FFFFF0C30C30C32
+:103F2000C30C30C3CF3CF300F3CF3CF30040CF3C95
+:103F3000CDCDCDCDFFFFFFF3320FFFFF0C30C30C13
+:103F4000C30C30C3CF3CF300F3CF3CF30000CF3CB5
+:103F5000CDCDCDCDFFFFFFF1310FFFFF0C30C30CF6
+:103F6000C30C30C3CF3CF300F3CF3CF30001CF3C94
+:103F7000CDCDCDCDFFFFFFF6305FFFFF0C30C30C82
+:103F8000C30C30C3CF3CF300F3CF3CF30002CF3C73
+:103F9000CDCDCDCDFFFFF4061CBFFFFF0C30C30518
+:103FA000C30C30C3CF300014F3CF3CF30004CF3C3C
+:103FB000CDCDCDCDFFFFFFF2304FFFFF0C30C30C56
+:103FC000C30C30C3CF3CF300F3CF3CF30008CF3C2D
+:103FD000CDCDCDCDFFFFFF8A042FFFFF0C30C30CEA
+:103FE000C30C30C3CF3CC000F3CF3CF30010CF3C38
+:103FF000CDCDCDCDFFFFFF9705CFFFFF0C30C30C1C
+:10400000C30C30C3CF3CC000F3CF3CF30020CF3C07
+:10401000CDCDCDCDFFFFFFF5310FFFFF0C30C30C31
+:10402000C30C30C3CF3CF300F3CF3CF30040CF3C94
+:10403000CDCDCDCDFFFFFFF3300FFFFF0C30C30C14
+:10404000C30C30C3CF3CF300F3CF3CF30000CF3CB4
+:10405000CDCDCDCDFFFFFFF1300FFFFF0C30C30CF6
+:10406000C30C30C3CF3CF300F3CF3CF30001CF3C93
+:10407000CDCDCDCDFFFFFFF6305FFFFF0C30C30C81
+:10408000C30C30C3CF3CF300F3CF3CF30002CF3C72
+:10409000CDCDCDCDFFFFF4061CBFFFFF0C30C30517
+:1040A000C30C30C3CF300014F3CF3CF30004CF3C3B
+:1040B000CDCDCDCDFFFFFFF2304FFFFF0C30C30C55
+:1040C000C30C30C3CF3CF300F3CF3CF30008CF3C2C
+:1040D000CDCDCDCDFFFFFFFA302FFFFF0C30C30C4D
+:1040E000C30C30C3CF3CF300F3CF3CF30010CF3C04
+:1040F000CDCDCDCDFFFFFF97040FFFFF0C30C30CDC
+:10410000C30C30C3CF3CC000F3CF3CF30020CF3C06
+:10411000CDCDCDCDFFFFFFF5300FFFFF0C30C30C31
+:10412000C30C30C3CF3CF300F3CF3CF30040CF3C93
+:10413000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C47
+:10414000C30C30C3CF3CF3CCF3CF3CF30000CF3CE7
+:10415000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C27
+:10416000C30C30C3CF3CF3CCF3CF3CF30001CF3CC6
+:10417000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C07
+:10418000C30C30C3CF3CF3CCF3CF3CF30002CF3CA5
+:10419000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CE7
+:1041A000C30C30C3CF3CF3CCF3CF3CF30004CF3C83
+:1041B000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CC7
+:1041C000C30C30C3CF3CF3CCF3CF3CF30008CF3C5F
+:1041D000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CA7
+:1041E000C30C30C3CF3CF3CCF3CF3CF30010CF3C37
+:1041F000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C87
+:10420000C30C30C3CF3CF3CCF3CF3CF30020CF3C06
+:10421000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C66
+:10422000C30C30C3CF3CF3CCF3CF3CF30040CF3CC6
+:10423000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C46
+:10424000C30C30C3CF3CF3CCF3CF3CF30000CF3CE6
+:10425000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C26
+:10426000C30C30C3CF3CF3CCF3CF3CF30001CF3CC5
+:10427000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C06
+:10428000C30C30C3CF3CF3CCF3CF3CF30002CF3CA4
+:10429000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CE6
+:1042A000C30C30C3CF3CF3CCF3CF3CF30004CF3C82
+:1042B000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CC6
+:1042C000C30C30C3CF3CF3CCF3CF3CF30008CF3C5E
+:1042D000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CA6
+:1042E000C30C30C3CF3CF3CCF3CF3CF30010CF3C36
+:1042F000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C86
+:10430000C30C30C3CF3CF3CCF3CF3CF30020CF3C05
+:10431000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C65
+:10432000C30C30C3CF3CF3CCF3CF3CF30040CF3CC5
+:10433000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C45
+:10434000C30C30C3CF3CF3CCF3CF3CF30000CF3CE5
+:10435000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C25
+:10436000C30C30C3CF3CF3CCF3CF3CF30001CF3CC4
+:10437000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C05
+:10438000C30C30C3CF3CF3CCF3CF3CF30002CF3CA3
+:10439000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CE5
+:1043A000C30C30C3CF3CF3CCF3CF3CF30004CF3C81
+:1043B000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CC5
+:1043C000C30C30C3CF3CF3CCF3CF3CF30008CF3C5D
+:1043D000CDCDCDCDFFFFFFFF30CFFFFF0C30C30CA5
+:1043E000C30C30C3CF3CF3CCF3CF3CF30010CF3C35
+:1043F000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C85
+:10440000C30C30C3CF3CF3CCF3CF3CF30020CF3C04
+:10441000CDCDCDCDFFFFFFFF30CFFFFF0C30C30C64
+:10442000C30C30C3CF3CF3CCF3CF3CF30040CF3CC4
+:10443000CDCDCDCD0010000000070100000281703D
+:10444000000B81980002025000010270000F0280F0
+:1044500000010370000800000008008000028100D5
+:10446000000B8128000201E0000102000007021099
+:1044700000020280000F0000000800F000028170BE
+:10448000000B81980002025000010270000B828034
+:1044900000080338001000000008010000028180BD
+:1044A000000B81A80002026000018280000E829849
+:1044B0000008038000028000000B8028000200E05A
+:1044C000000101000000811000000118CCCCCCCC10
+:1044D000CCCCCCCCCCCCCCCCCCCCCCCC000020002C
+:1044E000CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC0C
+:1044F00000002000CCCCCCCCCCCCCCCCCCCCCCCC0C
+:10450000CCCCCCCC0000200000000000000000005B
+:104510001F8B08000000000000FFFB51CFC0F0031C
+:104520008A45D91918FC3811FCA18059981918D856
+:10453000809803883D80B8819181A1919178FDDABE
+:10454000620876BF3003C36E20E611029A23821000
+:104550009F0254F306C85F0F15B312656038263A00
+:10456000F07EA706DE2A8D29364512C1DE86451E5D
+:10457000196F4793FF2289CADF4140FF40632965D5
+:1045800054BE9D22845EA604A1A5D1E4EDA1F2D77C
+:10459000A1FE9251C66EEE0DA83C00F85C49656024
+:1045A00003000000000000001F8B08000000000056
+:1045B00000FFED7D0B7854D5B5F03E73CE9C994944
+:1045C000CE4C4E4212F2224C1288A0210CAF808AAF
+:1045D0007F270122F539202858D40142087983D455
+:1045E0004BAFEDCD8424101135F447058B76885000
+:1045F000D1A20D34D260C10E20147B6D6FF0FAC0D1
+:10460000EAF50B4841312FB1207EC5CBBFD6DAE7A2
+:1046100064E64C2680D8DBAFFFFFFDB4B8D9E7ECE9
+:10462000B3F7DAEBB5D75A7BED3D92750293BFC76E
+:10463000D845FC03E54F4D8CB109C1F26766F680A1
+:104640002787B1C9BDFE3A473C63556D193BA29D12
+:104650008C25EC9921142850FED5232C5082DFBFE5
+:1046600065C397F0FFB619423E7C97D0E911E6C3C7
+:10467000FBE4D5026B873A939C310CEA8CB9194B59
+:10468000642C6B12A33F224B8D82FFE07325398F80
+:10469000B134FC2774754661AEC078C6321E535CD7
+:1046A000D4D0A93815783F847FC6D2BC25B731074E
+:1046B00063CF03BCC971F0BC5A3ADE61E5EF2EC28C
+:1046C000DFA1F33A6ACD58AE303E7732A789654113
+:1046D000BF3EE3F3AC46633D9BD9E34F46C33FEC9B
+:1046E000CC7E518C308F13B18C013CCB540E2F6398
+:1046F000BDB26754101F9B6A58A2322C580F2F85E9
+:1047000065873356035E97ED165C16F8FE396C2FFD
+:1047100031E6D7BE6BD6EA153E5962A3A10404B5B3
+:10472000E4F4EF6711CBBF11F1FE302BA0B24AEADF
+:10473000955580AFAA5A76FB95FEED673389E8540C
+:1047400029B9F65B61FCDE5AE66A86F19799D502D3
+:10475000AC2FFB91D3E5837A6663472183FAD03689
+:10476000818919C1EFAF009EDB917F001E2A2BA526
+:10477000DE420674ECDD2BB0E60C1C87F7BB6C77D1
+:1047800006F3650C0CE758662638E732413A89741F
+:10479000713007D2C1BC24F38942A8CE54DCF3B0F7
+:1047A0007F9FE29D87EDF4E7490BE638BD0057F2A5
+:1047B0005066A057B1B53A9D653256EA692944BEA4
+:1047C00038B5EC8D5558029E1324C0F77C8BA70892
+:1047D000FBA998579DCD80A7E659188D3FB42DFFB2
+:1047E0003309F80CBAF3C5C4213F31763C844FF04D
+:1047F000CFF1115A5D1C98DE972B8BB01F09F10584
+:104800007217011F3F42A026E0284D543A57FC2959
+:104810006BD8A0D0FA5B59C3C66900E511BC0C3F48
+:1048200061AC4308E54BBD1CBA3BFFB0943B303C48
+:10483000FFD3F30474127EAB00B7C81F1576D9BF3F
+:1048400012F861CAABE6C0F7803F2A360B7E0BD464
+:104850004DAFDBE87DF7265E0FD86537F24FD716F0
+:10486000A80BF0BDA5FDF11B91BF5E155933763B3A
+:1048700022CA84FAE5A4063B1B0F75C047B18D57C9
+:104880002B36EFBB1FBF2F69B3301BF457B17BF141
+:104890001D37427DF16133C326155B6BE514A82FEC
+:1048A000F10B2D58EF29E0F0F97689FEADD0BEC7A7
+:1048B000D19E381BE873BAC6CA9C326375F6F6C43B
+:1048C00059C067A5FE1D85F85DE976C185689FF230
+:1048D000EAD643C938AF17B97C976D8B664E1D7FFA
+:1048E000F0F764AB18F81EBC5F06F364D0EF62D635
+:1048F00054887AB062EB3AD9690FE2EB748D4AE3DF
+:10490000F4C9DF8B300E7C57F98AE0C229569A9899
+:1049100017E5B07BB76DCEF30ACEAF56CEB6E3BC8B
+:1049200056CBD86EB17FFE2E54CDA5FECD7221BCE4
+:104930002FDDB4592E0E91DBB26D838C706DC81AC9
+:10494000EC8D20D7417880D7B283F552D403A80FDD
+:1049500025BF3C2384CF2A8558E2CBB26D22731A3F
+:10496000F888D3DDF72EFC13F0E5DB6B27BCEA7487
+:10497000EBD3A71ADDCEA81A1DA5DEBC1911F8F8D5
+:1049800071A403C0D384788272AD069F6332CB9743
+:10499000A07F879BA902BB3C5F3699D97C0663F553
+:1049A000B007DDD2F55097D952E682F550FAB17BC7
+:1049B0002AD49304EF67389F7AC15BC2D7AB9624A1
+:1049C0000FE07995C0E6E0FC8F21D030AF55C9C02B
+:1049D0009F80F7A66979CF8B82067B3CD68B7FB10F
+:1049E0002683FA3943FD98A19FACCBF7A3164E322C
+:1049F000F4A31696E8FDFC8DFAB15D593F4D85375D
+:104A000018E1292CD5FB910468576FBFB279A937FB
+:104A10004F36C2737339F5133BD5C5BC0AAEE71ADE
+:104A20003FB076B708EF95EDB163D7B050BE2850D0
+:104A30000580DB0E5212CA173193A20C7C18EB8E44
+:104A400033D4A127F5E47541FD138895697C394578
+:104A500026BD909F62A5FA43290AE985876EF05E1C
+:104A600083EB208ECD92A12E7B47AB11F81AE01478
+:104A7000581296601724F57FBFDACCF150907A2156
+:104A8000FB187C5F65EACD8E85FA35A6FC6B116F4D
+:104A90002E81EBE528915563BB280B23FDB43A2307
+:104AA000EF795F089E1A8700FD8560BF8D666F12E3
+:104AB000F2D7F8DA677C12C0B76A08CC2705BA12B9
+:104AC0009E09F8603D5A3DA43809F1699141BE4301
+:104AD000C79761FC1C1AFF06C4A31BC74FE83FBE63
+:104AE000257392617C6B7A89617CAB0CE303BF4FC9
+:104AF000AD6DD6C607FCDDC0D834A199C6B7A49762
+:104B0000D0F8AB655662183FAA6FFC5B70FE9E81C1
+:104B1000E69F798371FEE9A5C6F9CB7CFEB36A5F97
+:104B2000D2C68FA2F9CF165EE2F34F2FE5F3B7F0AE
+:104B30007EFBC677F4E1FF5E9CBF7780F12D599331
+:104B40008DF31F5A6E9CBF858F5F54BB531B5FA1B3
+:104B5000F117093BF9FC8796D3F8B2C5EB423E92B8
+:104B600053A3AAFD684FA481400C261DE5A672043C
+:104B70001805A01F860A9904C743519CEFCE450132
+:104B8000BF29417DC7FC2051A0CF2A359E2FDB9E37
+:104B90002FA39EA5F7896837F13F456D22AD376C8D
+:104BA000BDC53F1CE0ED6E137D582F5A7F935FA467
+:104BB000F58EDBE560C605F0F95F9E1CD51C3AAFAB
+:104BC000F0725193F96487418E383CBE0236A21AC6
+:104BD000E06B47269810AC9F043D0AC62F3B0E7A27
+:104BE00014CB53666E8F9C003DCBE450B9A9E5F61B
+:104BF000888FBD9303F3BA5B83FFA4C4F17D72B9C0
+:104C0000E047FC9F5BB75446FDB4A8098CE91079D6
+:104C1000AFD2E8D4BBDBE26F16089F4EC4CF3D2471
+:104C20008A8CFD9766D72FDE30C8F0DD3CE66F48F2
+:104C300082F60BD7CE1FA2C2FC7F30C73216ED53CF
+:104C400090845413C9314B35816F31A7759D391547
+:104C50002AF7CC311BECFAB95E63FD0725C67AB79B
+:104C6000D96F36A1BDB144609BA1DFFBAA8DEFF5E2
+:104C7000713609719CAEDA7877277278EFC3722C9F
+:104C80003E5689AEF7ABFC5B1D9EAA87CD2C40EB50
+:104C9000654702433AFA12C85EF3AA7CDEE1F0DE11
+:104CA0006FB6BA3D00CFFD3F12099FE1F077BC1E01
+:104CB000ED36811DD7B1E14B33DAB7E1F30987FF58
+:104CC0008115E1F35165D4F7F37DE1CF399F84F38A
+:104CD00053555BFEA01321ED2A5ABE3FE844087FDE
+:104CE000956D9B61A82FF1CF35B45FBC61BEE1FD2E
+:104CF000A2A62586F70B1B971AEAF37D3F32B47FF5
+:104D00006045ADE1FD7DD58F18DEFFA0649DA13E1D
+:104D1000D7BBD1D0FE9E399B0DEF4DAF8FBC13E5B5
+:104D2000A8EE5D91E1BA715639F938DA836715C991
+:104D300085F4F8B42689E4E0748D93CAEEB6715612
+:104D40002FD783C50C4C9C5EE19CAF7132EA65465F
+:104D5000FAF3AFC2059F0FEA7F139C843F7183CCA7
+:104D600002C0C2028BEBE3E35E31E47DC765DE6F18
+:104D700000411FD7FFBDD811F97955F3FCA16A0492
+:104D8000FF2128B72C15D7B91E6D7D0F7F5F2E3000
+:104D90004FE873C656929CD769EB4CB9CCF541F9F4
+:104DA000CEE402F4BFCBE54076F5A5C66B01A4A224
+:104DB0009E44EB3C01F901A4C0C02F5906F9EEDC7A
+:104DC00027125C95A81340AFAE639EC126D43381F1
+:104DD00003E9778D4238DC49546F4BA075BDB3664B
+:104DE000FAA01312D2C743E5A73573A83C59E3A52F
+:104DF000F2444D0995C76BAAA9ECA85941E5C735FE
+:104E00003E2A3FAA69A4F2CF354D541EADD940E5E4
+:104E10007B357E2ABB6BDC54F6F92BBAFE8DD7ECC2
+:104E200055CDAF809587EA67B4B9D443DB769273EA
+:104E30005712CAF919E55C36DAE3678E8263993155
+:104E400030BEC2F96D603ABAC95E29F603FDC7F5F6
+:104E50007F6F8BE274B299D87470A6D923C37FE1B7
+:104E60005A9043750959061624D70C7B847E61ED50
+:104E7000437A5D8E4ECCDD9B3B13E871F299BFE522
+:104E800061BF75DAFA177540A47598059E7721BD44
+:104E900042F046EB5AEFAB9ABEBF0CFEBAFAF0D71F
+:104EA0009E8EFEFB4141A5FECFB45A988478DC1358
+:104EB000ED07E667670E3FEF40795C9664524F441A
+:104EC000C0835E56B464A84AE8FAD366AC9F691200
+:104ED000A6B7D07AEC8C99350AF94A554F0C43FAAB
+:104EE0002751A9F7B32C49564F80BC9EDE9615C3B7
+:104EF000D76F3F5F07B7C712BF825F48EDFFDEF095
+:104F00000CD48F0E0F63ADEC132BEA037897F5EDFD
+:104F1000FD7226FD95E2576C8FF91CDA0B16F87BB3
+:104F200091E20712D5F57EAB5A449F65343EDF6EA1
+:104F3000180FBE73EA3EF7C5CC4BF1ADC44E86C424
+:104F400011D669F1C6B26D36D5B8AEC41AEA556D40
+:104F5000C9AA619DC17F80FCB36A4142BE29D7B80E
+:104F6000A847521A0580AFDCE4A47EAB04DEAEC2D3
+:104F7000DA217BE151572BA7DB40F09DAE39EC9451
+:104F800040DE4BACE001027C252D23A7A29EEB6AFC
+:104F9000AD4B447BB04C3CF39027C2F73B4D028DA8
+:104FA000B7C46FEE35AEA31A7F30E8577F4E7E163A
+:104FB000534E86D43B4DDCCE0EEFF780D6EFE5F0B6
+:104FC00053B9FD48E18DCEFE78AA6CFB42F6921CE7
+:104FD000C1FFF28278D2F1576EF21C407D5ABAEDD1
+:104FE00018D9A39F9A7DD90F5F423FF59F9F9244A6
+:104FF00071527D5E3E3029619C055A7C17F8F79E00
+:105000000F613DFDECDFCD6C0DC0C72E402B786FDE
+:10501000D65F331333417DA1565BD05A4671DDCF45
+:105020004CDC8E2A621E07D18135E5A11DD9C54C05
+:10503000D3114F5DEC6DC7B8103A9C32C9A4671606
+:10504000361AED18B07F0DF5C51B8CF5623633119D
+:10505000F549F17A33F30B343FC3FBF74D2AE17F77
+:1050600031AB5E85EBAAA4F9230B5426A5027C156F
+:10507000BF79366F3EC65F4CDC0FD1E3234BE2387D
+:10508000FCA5F17ED90DEF3F691D77F78D48068BA2
+:105090007F15C689580C736D65FDF1FB6DE10F87B7
+:1050A000575FAFFBC5693438C46D82DB1F817F2F2A
+:1050B000687CA6EBEB5B44D5E017DC8DF510BF21D7
+:1050C00046D4E2B2221391EE5DAAD5678AA1F71405
+:1050D000B7F7EDB4B8EA80DE3F3779068913C84EDA
+:1050E000C86521ED7E6EF2D2F34EE1AD62B45B99FC
+:1050F00014C8453B14D618E25359E30731CA918BC3
+:10510000F1663B837514E86F41F8A09F55F692DB7A
+:10511000582EC6BB41DEA1BFC71C858705A8DB94FE
+:105120005686FD59928CF17C9BD358AFC27F201DCF
+:1051300046308A3F458F90C2F01860A80FED2EE3ED
+:10514000F351E88491DD1F203E76108B43695502B0
+:10515000228CCF26499D7DFE5626FA7B1C7E8A2F07
+:1051600040FBE52A6F5FA9C5CF977F503038EE121C
+:10517000FAA8EA3C68904121753DBE7F5E62FE71EF
+:10518000DF416F3A61550DD19B734DDE69480FD4F5
+:1051900093089F00E3780D76609A1A2AE70BC2F80D
+:1051A000E3AAE1886706FD5D6EF2DE2D26F487E353
+:1051B000AAFB4FEAD7FF8248F3BCEAFE87F5EBBFB4
+:1051C0003252FF15BF7979970FF8A9F4574F3A80FB
+:1051D00099D9675253A20BE85EBEB5C18172F9A995
+:1051E000E473205D3FF38BD323C9E71651974FB784
+:1051F00022E411FF101F9D7EE9D13BD0AE3AB7D516
+:10520000AC527C609B256001A6AC6C5DC2E5639BE3
+:10521000E518AFAFFE02F9B3AACDA82F4A5F7832E6
+:1052200011E3CD4049CD7F0E907F50B9E52F8568C1
+:105230007755B15ED27BE1DFE1F8E7E3C81E982F36
+:10524000C7F47FAFEFF3556978A96A7DF40B9184B9
+:10525000A583FCCDF0F6259ABDFFA4688FA738DFA3
+:10526000443611F94CC707F3737BBFEEC5A7738FA4
+:10527000013C9D5BFEDD21E484F227D77B675A1653
+:10528000FEFC35E7C0F2D40D7A31D4AED6D76767CD
+:105290009BE6A7ECE165B939E0403FB07CB3D9E5C6
+:1052A00043BABEFCFC2F9EC1B8CC0716D770E8BF2E
+:1052B000ECE583EFDD00F5B21DE6F8DBF8341421F0
+:1052C0003148972AF8BB626C900EA5BF3E283B4739
+:1052D000F1E73F8E0BD2A36CC73E998DEA8F8F29E1
+:1052E0002DFBE40E25025D5A8E15A23F51F7E257C1
+:1052F00032EAAFCF5E17D8E08C08F8DC7C90EC6225
+:10530000C413D151A3531FDDC2DA57015D50BFEA68
+:10531000740A7FFF2F9AFEC7FE9C39C4CFAFBC86AC
+:10532000FB287FB6B870FE25AF3CE8C0799C92AAF6
+:10533000395F3FDB90E886714BCCBE44954AFEBC9A
+:10534000E4B91F12BF2D3EF2C3448A7F3077B28981
+:105350006C055F32CE6FD1A6D934BF62E625BE2B75
+:105360007956F4E0FEE059894DDF11412E5224AE0A
+:105370008F4F355B704D65A770E1C07D85B745FFE8
+:10538000568AFF2DA5F8CA0FF5FD20B68CEA67AD49
+:105390009C4E5F88FABE1AAC3CA1FCBA65753BD244
+:1053A000E7F410F7608C1B5731C9A7E143B808FD3B
+:1053B0008A47A60DE6F4614E294FFB0EF4FD147CDE
+:1053C0008EEDDBCD6E5BAEE13B76312338FE726D48
+:1053D0007C803B0AEDD5538960FF45985FA1A4AF5F
+:1053E00037605785F057887C7379DFF208976F5DD7
+:1053F000DEFD33A6E3FBBFBEC3E507BF437B05E08D
+:105400000A0CA6F7FB6609A40F2C2C1049AEB7981E
+:1054100035B936BED7F904E09670DDEDE317EC3F01
+:105420008EF04F766CF17AF82E445F56E1788EFE5E
+:10543000FDE972BB5893FF04C928FF6C1397FB81E9
+:10544000FD091F8F4B98FDBF7806E515E413F7AFF4
+:10545000CB5F367B70DE9F6F3FF0DEBD20A79FB72E
+:10546000E8726AD49FE1725AB273028B24A79F63D9
+:105470001A42243985E711E554E9203EFE47E94FF9
+:105480001D7F3785E14FD78703E1315C1FFE5974DB
+:1054900046D487F0E71D96D79FFF74BED3F9ADF4CD
+:1054A000971543293EA6F3A5CE777D7CA9F35DBF72
+:1054B00078A3017FE1EF2D188301B83CBBCD1447E1
+:1054C00028DFC3F77FE1BB43A9E3094F6E5AC658F3
+:1054D000D3A1D4F8D0BA3FACDE12D6DE1D56F78485
+:1054E000B5F786D5AB0DEDCBDB0EC83CAF256068BC
+:1054F00027AE78867D322812BFFAB95FDAFA85ECDA
+:1055000043BE507AE97BF34AE6B3633C7CAF48F193
+:10551000911EC0F12A18A7677B861FF3241A6C3CE2
+:10552000EED4A3F63AD05E6C88E5F5DE047915EA90
+:105530003DFD79AF8DC7F57A3CBD8ED810FBEDD817
+:105540001E91F476879F4D8FE467C28A4272D4C160
+:10555000067ACFE3FDD344257D05C65F9A441786BE
+:10556000748A6AEF71609E41CF9EAC3BE7C0F34501
+:105570006F8AB48DD883767B0C92C72D2587F877F8
+:105580009F32DF5393317EBF87FB79456BC3EC11AC
+:10559000B696F8A958592EA33E05BFECB871FF8204
+:1055A000CB45A9D65FC926E37BFD7BDCC145FBBDAE
+:1055B000748BF1BD578B0734EB7232868DD1FC7141
+:1055C0001E8FD2F4F23431E7CE39408F9EC322C30E
+:1055D000FDFB337B44A2C799ED7CBF9EE2F6D72347
+:1055E0007FF7923ED4F1D489F2240FACAF3A5FFD3D
+:1055F000AFBC87916F767D98FB33283B777D90FD1C
+:105600005BACFFE6FDF40F59FFF6535EB7D13E49A0
+:10561000CFEB76E2F79EBD7F4C7F18EBBB2D149F3E
+:10562000EE79FDAB5CE49F9E959612D4773D438066
+:10563000FE681FECFD2AB783D6D77AA2DB1F259917
+:10564000DB477BFEF6B1108F25CC0AED86D7A34948
+:105650009EAA5EB3513CAD67EF5779A176FF779D67
+:105660004FA5B67FD963677376227CB17CDFA7EA4A
+:10567000B7D73F5F8BF917ADFBE485F07ECAEFBE6D
+:10568000C9453DDAB393DB43DDE68EE7707FEE6814
+:10569000FDDC9566C073370A550AAC9B0DCF14A08C
+:1056A000DCF4C7CB371427BC527CF4FC5F830FC1FA
+:1056B000CDF59DDD6F1570DE5F7FFC21EA85D72D6E
+:1056C000C497FA7C3F6FA9257BE572F37698799CA5
+:1056D000E4FF9D790B812B99F728F33F37BD7F2D90
+:1056E00039892EE172D09FCFF73E44F597ED2E8297
+:1056F000F70AF9FDF67FF2F97F6BBAEF04BA3B2E99
+:105700003FEFF27FF2790F4CF737EFD7E8AE627ECA
+:105710004BD5EFBE21F8BEAD9E5BFB4F2EEF03CD08
+:105720005FB7EBD7985C4D99189F43AF01D669C519
+:105730003EB311C3856B46CC54D1CE14C3F62BF5C2
+:1057400072AF99FB4D22EE5B629C6F088FF331CDF7
+:105750008FA22D3D185A528AC98E959455DCBE965B
+:105760005CED6EC0CB9A6B17B82877888D3DEAC583
+:105770007ADA6417C5AFC3FCC97A81B905B06FA5E1
+:105780006B6F398CFE8D79842960C9A5F21896ABB0
+:10579000B5B8A459950D7E8F9263ACDB9CC6BA4513
+:1057A000EBCFCA38FCD624E6C7F8B43872BF8A7982
+:1057B0006DE218890950B7B1261FFA179624E3F74E
+:1057C0001B31C01E12CFBD5A3CF6F6E1716CBB1BFB
+:1057D000F138D244716B4A2E25BCB8FC6B789E8D93
+:1057E000D588D755ED884F09FD5F6E7F91DFCC34AA
+:1057F0007F59D2BA904698DC36633BCD4FBE2C9D84
+:10580000385DD2CB353A2D33D045A74304FA18E89A
+:10581000A2E3F9DBD2279C2EE1F8DF6F7612FE07B8
+:10582000A2974E9734C5CD505ECD9ABF3015FD4935
+:10583000ACA77918ED336BFE8214EF663EA493EAB1
+:1058400062482FF4DB02E0B7FD7EFBF31427EA7A0F
+:10585000E9D81D084FD96F456605FC756FB7B300D1
+:105860007E2FF965F4434B5B458AFB3329907757CC
+:10587000C8BEAF6EF797FDCA4EF329DD69F1DF06AA
+:10588000DF97EEFA2497ECB095BDE4D7F85E1238B6
+:10589000DD7D1DB9B8AF5B2A71FF239C5F62659EF9
+:1058A00027D0B93B7A0EC66D846D3CDFB6B4E51ED9
+:1058B000B3C5907F66D6DB915EF0BD2850BE13C2A3
+:1058C000179AE7A9FB1D9D2F0A1CBE36B31FF3765E
+:1058D0004BB7EDE8C6F853E9518B0BC3D255DBBE8D
+:1058E000A0FD8D29BF7AD9D141FEB668883FF4F377
+:1058F000FBB789C41F95AD15E487409DF8A2B2257A
+:1059000072FCEB72FE69D9AFF6EEF2010ACB7EFDB6
+:105910008203E35BA7DBB73AC8FFDF76E9B85B3FFA
+:105920003FBFE5914BFAF9A7F11FE0BFDC2087C527
+:1059300049B60D227F04E0CB8B94EFADF35BD9CB5E
+:10594000679FC33874E7CECF9F4378CBFFFBCBE78D
+:10595000D09F60AFDBD4AD889797DEA5389EFEDD83
+:105960002C99C79DBB5F7C81E29FDD1F80DF017F9B
+:10597000BAF79E4A477FB27BC7D789182F59BE779F
+:10598000DA609CEFF257A70C6611F4885E22DFFA0A
+:10599000AF20FE1A4EAF03AD07C8EFE9027AA3DFCE
+:1059A000D917B769A9E07130A716AFD91E39CEDD76
+:1059B0002F3ED37AD79D378DC7D2EC72B22B88D3C6
+:1059C000BC03741C7D05F4DBFE88E67F46A65F17EA
+:1059D000FE03E8B42C8C7E675B17FDFC197CD73A7C
+:1059E00068C0384DE00AF0A6C7D1BF27BB7F22A30D
+:1059F0007CEDFC25C5C5906EB7C144BB5F3E9B8E58
+:105A0000FB0F9F9A7BEFE7E7322C2AC61B4AF7BEB3
+:105A10004FF2D3FDEA118A53332D9EDDCDFAFEF00D
+:105A2000F8A3965359B5C5CEE33B1AFE31FEE37495
+:105A3000D0732DCEC3F9588FFF0C14F7699579DE1A
+:105A4000881EDFAFD8F2A1164F09D24B9884743A62
+:105A500076C9FD081D0F2AE26162681C33727CADB5
+:105A60002FDEADD10BE987F1CBBE3825D4D3306E14
+:105A7000E517DE6711F441F7661EFFEC3647CEA34B
+:105A8000D2E39ABF0A9753FF95C5332F07FFB7C5D7
+:105A90008F5F7652BFE178EABC10598FBF2DF37546
+:105AA000FFAAF7C5CA0543BE41B9C97B04F9B1A233
+:105AB000F598CCCFA5F0F352FA7C3BB5BCD1CE978C
+:105AC000448A77AD6A39407A3C5C5FE8FBA6E1F036
+:105AD0009ED0E0AD6CE3EB44E74EBB5F817E3AF7CE
+:105AE000EF267EAEDC7E8CE26D87B6FD5AEE08595D
+:105AF00057719DF087C0DFF9CABE5C1EB7E579EC2F
+:105B0000E1E39CD1F461D59EC8E3546DFFC2304EF1
+:105B100099AF45E6EBFDA5C73B2DB9EFC1FE4EB7EA
+:105B20009B19E6799E6E11A7473A17F5AEB66EEA55
+:105B3000E77E70BDA47CFD23FC5CCCF8B7A3281FD6
+:105B40007EF991E91FC6C463098487FE5A6B399FA9
+:105B5000B6FEC49D8AF46E3D72AF88EBD42EC46F3E
+:105B6000889D9FF74EF5143BE885BC8F3CE3915D23
+:105B7000C3F5CDC4A32603FC30CE605C07EAA11FA9
+:105B80003CA782F96E088FE8289C8EF088AA49B558
+:105B900009FDE761563C745E40EFD7AC1ACF03B005
+:105BA0000BE39CD84FD24C1E474CBE8B973EFD3C1E
+:105BB0004E7194BF0EE659A078D32CF07D927D7D76
+:105BC000C64186E7BF2651DE7696C5786EAC4B554A
+:105BD0007C26D0DFCFE46C5937D949F907D7584232
+:105BE000F30F582017F9516FD7EF7D587E421A7E78
+:105BF00002FD881A7C595A7EC210D621A07DBDC9EB
+:105C0000CECF270E55E24DF8FDF39ABDA99F3FEC8C
+:105C1000775E31EC9CE2E5CE27C64FC95F3AD405EA
+:105C2000FCB47ACF14CC5F8FBF277F47AA8A791242
+:105C30007F9E82E757E25FC81F930CF513AB1F9C52
+:105C40004AF5FFC81F930EF56F1AFF8DD7CB04CA14
+:105C5000572D583D7A2AF2EB55CBF92CC08851CEFE
+:105C6000EF40BC75793EBA7B9113F31F7A658E5F66
+:105C7000E6C176432671BCA5291FED403C0D357564
+:105C8000D4227FFE7CEF57B1A8179C4C25FCA8AC12
+:105C90005E45FAC1A349172F9147179E4FA6EB9374
+:105CA000CD8AF70184E391F923E85CE0332533AD35
+:105CB0003C5FCF98C7C0D478A26791464F84D31A6F
+:105CC000928FBF58F4C9FC5C4C93A6AFA6AA389E2D
+:105CD000E02B172F5EF7EDE17A50E74BED5C69C8DA
+:105CE00079C687105E9FE27DC892D0FF3CE31D1607
+:105CF000CF0A7C9F5C7C3E1DF95B3F9F187ECE9156
+:105D000049BDA648F65FB376CE7120783D56EF2A9E
+:105D10001C37F377CE9D8741BE4617C92E4CCD1C4C
+:105D2000BD627C82C4CF15529E439546BF24139713
+:105D300043F610A37DD61E8BE046BFB9E74195F42C
+:105D4000775AD16DE457F54467B4603E50CFC3FC39
+:105D50005C29664CA31C0DD9131340BF0FE4E05C13
+:105D6000981C9C33AE73C6717B2E3ADB3AA83F5524
+:105D7000EB0F0CB0C4E0B9E01E91EBE59E1A27C111
+:105D80003184F9F6E1FA7EA5E36DB518CFFD02DEA8
+:105D90005F40BCE878FFE5C0F47B45A3DF2B91E8CA
+:105DA000177EFE74BEC5FB6B6C7FAAF8D02A7415F3
+:105DB000C3CF9D86D3B54A6ADA88AE78E29E2F6853
+:105DC0009DD1E9367A852B411A64A0E3EBD8EFE840
+:105DD0003D5F98105E9D7E4F0F90EFFD070B5FCFEC
+:105DE000C2C74B9CD391E28DB4FE60102E2158CFD8
+:105DF000B5E6D1F8834D3CDED3BFBD10713ED07FF8
+:105E0000E6A5F2307355DE2FE0FFFD50BEFF10F126
+:105E10003F2222FE3F46BC03FE3FC6F65780FF4F9F
+:105E20002E857FDDAE2FD3F44219EE2B01FFFCC58A
+:105E300039333113C62D1415E2FF255B456D1FD292
+:105E40007D5B7262508F2CB9BE7A9F19F870C9B30E
+:105E500002F16991765EFD73ED5C4B785E5FF11C3B
+:105E60001FE9C9CBE7F7F9490F956D333EBF10E441
+:105E7000DB74CAC7F5F1F393A22617E1F83FA368D4
+:105E8000FAA228D6D02E9C0E43AA4D863CF0E429D7
+:105E90007DFD909F976472BE4FF1B53F9819C6077C
+:105EA000DC52FCF800E263BC3015FBCDD7E456EFC2
+:105EB0006FE80AE33A9FE1339EFBCB6A349EFB1BFB
+:105EC000DE9462687FCD864CC3FB91FE6B0DEFAF15
+:105ED000DB36D6501FD57283A1FDE8B602437D4C58
+:105EE000E01643FB7187671AEA13DAEF35B49F783F
+:105EF0007481E1FDF51DA586F7377EBACC50BFA9A8
+:105F0000F75F0DED038BB85EDC5F939486E70A7450
+:105F1000BCEC5F2A9B547CBE34DBA4E6863E4F7407
+:105F20003B73B1CC73A37F3590BC4CB126A785AE33
+:105F3000CFF9CC6CD06B53ACC67A8155E39774E043
+:105F40001720FECD56A35CA556CF6B02B39BA52CA4
+:105F50001946F9D2205FB758B97EBBC57A65FAED0C
+:105F60004E6C7FAA3240E7ECC3E54B44F9CAA2D29B
+:105F700047FBA9CC45F9961B6D463E4D1A40AFCC68
+:105F8000B31ACFC38BEA619B649013FDF9F9A8D0D3
+:105F9000E7C2E2DB286F67A07EE5A405B76E017D4E
+:105FA00029277BA9D49FAF9A638A9897F790F53BEE
+:105FB000FA491BFAD94F0F217EBB92DE7E0AF3CC41
+:105FC0002AE7F592BF946C31E22558770DE67954B3
+:105FD0004E7E8E50E5FFDC54D3782BAEF7FA3C179B
+:105FE0007D303311F303D206F09F5ED5E6F15C4DB0
+:105FF000C9AD45C3B03FD5147ABF457AA0AA10FDFC
+:1060000098A15A1EF453A6C8F94A3FD5FA198C0A2A
+:1060100014ED035521FBA0ABF8238704F3F8779325
+:10602000F7A7C8170B46B7E7F173CB6ED74CB2ABE7
+:1060300054825FD743E98AE729D42BE94912736672
+:10604000F48767F03C6F6306BCAF8F33B914AAF7CF
+:106050000A389EE5C78C0D82F1EAFF5B24F8EAF767
+:106060005F4FF93C16A59AE2A7FA3C99B6DFAFC795
+:106070008BCF26CD8A413CD65FDB776E8761FDAC46
+:10608000E26DC77ECFAE37D3B8F50582E1BD3E6F76
+:1060900069C31D741E2B5DE1F32E867923DC9634D3
+:1060A0000E57FD73024B23B8FEF7D243E8BFEC8ACC
+:1060B0007661BC0DF0B189E8EDCE3867D2270FF3D9
+:1060C000AA18A434AF21FB25B21FFA9695AFDB4C7A
+:1060D0009D9588F654F23546B8C5F566F20717C5A2
+:1060E0002A94AFE0AF59A1D1D538EF554933EF9C91
+:1060F0000BF0D4BD23324CFD7176342D3D04DF15F9
+:10610000B746BBFCCEFE78EF72723801EEB7106E68
+:10611000714321CD9BDA21DC3F17D83319C877DED4
+:10612000E944FF1413C37D9770F8FFD3CAE3C4EFAB
+:1061300058559A879C547CEB9641581691DC1DB5B6
+:106140000EB8CE7F68E5EBFC87D608EBFCE5EEFDEC
+:10615000289FD37E084BD16DD2ECDAEAEC507B1944
+:10616000F4D649EC57AF8B313FCEC57E07B6CB3C5A
+:106170004DD91997B7CBD01E43FED3EDB1BF5A8D81
+:106180007664889EFD4AD3B35F5DA19EBD80ED4ECF
+:10619000DD1B8868C724C891F5DC381BC77F952AAA
+:1061A00033CAE31B209E9F6D8B6C1F0EB40E5DCE19
+:1061B000CFC88CD6F954D7EFDCDF60C532ED2F9C09
+:1061C000D9E07F241BF729E38751DEED40FDA4AE23
+:1061D000F8830DF1ABE36D88CD884FC0A3D3C6F92A
+:1061E000C4698B640F96031E4D063C0EC7F603D997
+:1061F0008357ADDF4B8CE76EBA357C839E9771BCBD
+:10620000AEBB3ECEC3B845E5EC73A4E7AF7A9C398C
+:10621000C67544F7BF611C01E7DF7DD77F6B71B79F
+:106220000E8A17D5BD7A4D0CC6A72A0AFAF48695B0
+:10623000DB8599A407BB7659DC0867571CCFE7ECD0
+:10624000DA35F110C6393EAF399C2985D82D5DAFBE
+:106250001CC933437F5D3B8FE4499420E7277ED1FF
+:10626000DF575CFCCF3C8F123C27D0C76F56BE0E69
+:10627000ADB7F1F8C9D398C7369AB1F7A363F9FA65
+:1062800091687A1C9F47BFE3F3A17E7F5470E5C7F6
+:10629000002B26DD554C66ABE58DA600968F0A6E69
+:1062A00011E355BE91FC3C4D52161B9101FD284750
+:1062B000DB03088EA3A3D78DDB29EAA7EA3E2C0BCC
+:1062C00014EF02C47B5CAF2B097DFC37878DB3A133
+:1062D0005F214DE17AB7777E941FEF294A34B98F59
+:1062E00080AA67670E2F8CC5F77F8BE6F2F258D233
+:1062F00089265C8E7039A038D49B665ADF960D7162
+:10630000272F82EF974D88E77EE905987DC839965B
+:10631000C7E367091407B9007881E714FA023EB5AC
+:106320004BCC173316F4B089B955F00BEC9342EE11
+:10633000D9C1FF6876FC604DFFF6384D3E33E0452D
+:106340007619DBD509EE0C5C4F7781FC0D03FAB4AE
+:10635000D558A97CAD464D1806F2B8A72689EAAFF4
+:10636000D738A90CD48CA0E7FB6B5C548F36B5A74B
+:10637000D37A2C55AF9B87FEF5FD120BBDB723BC1E
+:10638000C47B568E87C8F9972EE69300AE2F353D15
+:1063900052FBD638E2AFA7C600D431FDBFFFD98A81
+:1063A0003F644D053D98FAA3C35953418E9F12781F
+:1063B000FE021E188E742E552F9F32B7C4A2A9F06C
+:1063C0006B1BF34D4DC2BCC8DE3F158E61CCF6E8A9
+:1063D0009FA64E1D09F3C7FDFE14C6F6DADEABC755
+:1063E00073D8A9FB3FAB8B81F9C86DFC3E9F8982B6
+:1063F000A756407D339BF30B933CB598CFD97337A9
+:1064000073E2FEBE3ECE5E1BB71376DBB89D3951FC
+:10641000E0FCC1E6CA5A1E416F6EE8BA11DE3EEFDB
+:10642000C0D7748F0F8CB72FD5305E2FC51107FAE8
+:106430002E75FFD7B48E5CE9773D1F49FC7C84C480
+:10644000F32BBAE6266EA6FD78681FBA8FDA2347CB
+:10645000B6D7DED2D68106EDBEB79F65F07283A6B1
+:106460005724C6F5FF6BD105BF47B961DE38DA5F47
+:10647000AAD3E209933A7AE5F9767E2F5C3ED413EB
+:106480004E78043C0FD7A5D13355601ECCFF486031
+:1064900033840228DD36CFDBD84FD2C24DBE97D130
+:1064A0005ED86571A2D9A3E3ABEE03D98AFA216164
+:1064B000CF31DA8FAA133A64A4F7978F7C4D71CB52
+:1064C0003A737532D56D171BB0FEB4BD7A23D699D9
+:1064D000EFEBA96F003F0CD6CEE1E313D463BB9082
+:1064E000E829583B57EF067ED865E6F52F1F394B54
+:1064F000FCB1CB5C3D9F8DE1F57A98EFAE586FAA69
+:1065000009549052FB65FDE19BB0AEB7FF92DA777C
+:10651000DB546E3F2ADE0CA47F5F5D85BA3DA42E5E
+:10652000F13AB3F2529F5FC581AF297FB8720FE78E
+:1065300047C41BCE13EFCDC375E98C7AD451EBA4BD
+:10654000B87336D7D701039FE9E753B798BC2C2A15
+:1065500044CF5E085BFF42CED9B1A88490FEB43828
+:10656000763A03BB342B186FCD642E2A87310F95F2
+:10657000D9DB96EE47B42DBBAFD5897A2B3ED7FA3F
+:106580008097E868F41F9ED0F4E2FAE8FC1BA301B0
+:106590009EF582778D887AF165B34AE72F3A24B267
+:1065A000373BB5358CAD3053BD5C3BF76D5EE95D77
+:1065B0003312F5EE2293AB19D7B30C4FBE19BE2F91
+:1065C000DB9DE1AA65C1BCE7B2D896C4B14A30EF01
+:1065D00059AF3FAAF1D946B5C986F7D2E8FB439532
+:1065E0006DEBD2717FFBB37D1F903CBD1F95417C4D
+:1065F0005CD17A44F6DA69BF4CC6F3299FD9FAD642
+:106600003F5AF7BE6C19740BEAF52FEB4D74B8794D
+:10661000203DF406E83F3738C8876AAC54FEC25DB7
+:106620007D2D9ADE055129D36C60B4BF90E9569157
+:106630008FE6ADB9A6C10A7CF482AC8E443E9B17AE
+:10664000954B7C5B162B72BE64B907DD92B6CF0DFD
+:10665000F5D43565D3BE533CBEC8686F546D5288BF
+:106660000FC00EC8473EA8DC60F2E17EA2C9DA4E38
+:10667000E77DE74531CD8F369E4F5CAFE93BDF6C60
+:106680001EDFBDDC39C592F351741E51AFBF1FE54B
+:1066900024BE28917CB4FF5572DE41E718BFFB3859
+:1066A00056C379C8FEE32804873E4E79701CD25742
+:1066B000E51FEC273FF88D6B757BD64D71ACE53B44
+:1066C000B4FC059B7B30F6F3B4A62718FAB18077AB
+:1066D00029A3AFEE9340CF1CECD333F90D53D390E5
+:1066E000BEC1F76C92410FB925A0D3C128ADEEFB16
+:1066F0007EE4F65161ED33F5FACC86A993FBC3F342
+:10670000B42D58B7427BE91B4B5F1DE1A373F5A184
+:10671000FDC5E9E3DF4BFDE9FC971AB5F0A00FF8E2
+:10672000EF60AC271FF37C7A673327CAE166498D97
+:106730007285D021358AAF3725E7AF35E03F88F73E
+:106740005C03FD4FD5380DFB8A8B8B96D17998541D
+:106750009D5ECCC7CF776DCA32EC27FE7F38AE1670
+:106760000EF700704CFD07C331C2305E108E1C0363
+:106770007C570B87183B6B7A06DA6B8F98280F28AB
+:10678000D1E4B366A25DF66F268AA70C673C0F883A
+:1067900029E30DFBB4997B2CF331FE9E29B1C3D2C2
+:1067A000589427B7B316D7A99F48645FC173AB3914
+:1067B0000E876E72E3FD4F2095D45F66B9B7821FD6
+:1067C000F2E6FB82FA3ED37095E5E3BDA09BA3E71A
+:1067D000DF188DFB66731EAAC23C98E795F12F3532
+:1067E0003083BC921DD2202C253BE3ABA8871B70C5
+:1067F000BF767014B75B04F670C3E1E448EFB9BC30
+:106800009E5BF3F0348C1B34AF745E8BFE53B3CDC0
+:10681000DFB21FF3761E53E8DED6AC47FD8D9950EC
+:1068200017D79968BD1463FDDB9A71DFFDC96C173A
+:10683000DA11CD68BF60FB4714F26B56D538D3F040
+:106840007E923A6D1DD8B276B28A79C1F58A1487E4
+:10685000EBDD2A73F55C3C7731EED18D0DD6EB5133
+:106860008FB91A07A9BC9E948CEB9A33D33A467B16
+:106870000FC868AE75A6A8B1C1FAF06FC0FA203D86
+:10688000B3B1C19D86FD2E2BD5FA3B88718A17E2E4
+:1068900034BC68EF33FBF4D2C606CCCB126B83F565
+:1068A000A930DFADCF723D3518FA47FB0BE6E3C3E5
+:1068B0007B057B874B744ECA06633B607EB691991D
+:1068C000B4DFD70C7A11EF2BEE1DC9DFEBFB34F2EE
+:1068D0007013EDD3607B5C6F6CC9BCBD3C83DF572C
+:1068E00020DB158A37C07A3015F39E14A6FF71F3AA
+:1068F000B8A4B68F1185F70184F0A375ED323AF78D
+:10690000691D66DC9F97D38C75897916A0BF27AA6D
+:10691000C6E737466BF94183580ADA6DC34D3E131B
+:10692000B61BC9FC545EC702648F8D621D541F8D57
+:106930005E63161E5B72D241AB71CC2DF238AA4752
+:10694000443B3171AE1E47F24E41BE74476B7661D7
+:106950000AEF3F7EC62CCAF7F569EFCD33863D318D
+:106960000DE6B57EC6DDCE50FB4E5F2F75FBAD4804
+:1069700083F9CB6821A2BDA0DB7545365E4F98E553
+:106980007E7A14C611DBCD26BC9FAD588B63166F83
+:10699000C84F44BBAC68DF5CB287D74473BB6CD1D3
+:1069A000FA19B277149EF79A4F767FFEBA0931181A
+:1069B000A76FB0B962AE47FEFD23BFDFF54AEDB168
+:1069C000E6C46B0A501E9BC1AFC6FB8F0E9ADDCA90
+:1069D00018E48B75C3C8CE6C8EF2D6C742BFCDFF0C
+:1069E000EA74D541FD6736F7F823384E43147F8F9C
+:1069F000F726216FF6EDF73F2F5C8C1E78FCF0FD3B
+:106A0000FE83B191EFF1BD43C35FD0FEF090DDD9BD
+:106A100060F6C4DC87F0BDCBE779D6EA89512F1147
+:106A200067FBB486E70376D6B85840E6F7D162BD77
+:106A3000A4683FDDAF5CD22250DC7C096B223D3A7A
+:106A40004C89D5EEA731E6C59616BD4DED4B5B7969
+:106A5000FB32D642ED757AE1BDB501831D3ACEF029
+:106A6000FD1DD1DC6FDDAC781F43FBFF9119D9C44C
+:106A70004FC06711F32DE207D877B9319AAF1F37AE
+:106A800062DBC8F628F163B87DB85CE0E7B307C203
+:106A900053D57993613D0ADE9F21D37AD4ADF9496C
+:106AA00087937CEB6F84F97F9FF54A24A7DABD2397
+:106AB00075825F42F9FABE33ECDE1B2D0F68BAA671
+:106AC00025FE43CBEFF93E6B79C30DFDDCCE02F41E
+:106AD000DD61ED9E1214A4487919D0AF411FDC3A54
+:106AE000C258BFDD65ACDF3929F23D7D6B6BD4B494
+:106AF000D07BAAD60E708EF32D8D5E577FDF120BE2
+:106B0000CFEB7B0BE95E81F994B47FC1F3FA141BE0
+:106B1000F3A01ED9BFCF46FB21558ABC1943165599
+:106B2000E0EFE2BDF08A9D9F3740FF17E3058A99A9
+:106B3000B70FDE97C4F751123C495A3CC3953463F2
+:106B4000D4B7871BFD2ACA0B96D846DC770DE627FB
+:106B50001AEFEDE88AFE380FFD6398CF6C8C4FE892
+:106B6000715A7D3EFF287F2C5ABBCF399C6E6B3407
+:106B7000F9A80BA3733DD23907DF73B9F952BB876C
+:106B8000FF29C143796889261E17ACB3B98E529C80
+:106B900044F30FEAB4B806F37D5DEF56C2EC9510EE
+:106BA000FF227DEDD7F5F539E477F338882D6A15A6
+:106BB000AEC30D36BD6EA6FAD3E6A600F9FDAF5AF8
+:106BC0009C181F83EFDD1867F3CD1D417E5D5D06C8
+:106BD0004BC17B0EDEB0CBB4FED6BD6A69C6F5D81C
+:106BE0006DF376DB42F249BAECEFD1F9A608FDF974
+:106BF0000CFD0DF976FDC1F8AD8877FDFD1BF6A7FC
+:106C00000222FFCE49F91B69ED1F7BA19EB8CB4242
+:106C1000714FFDF70FCACFE7D1FD8C7A7F13144E69
+:106C200087CE1AD5908F5D8E7A3707E5A09DF467E1
+:106C300045CB2083DED4F569C5F91B68BF2C4857C6
+:106C40002D2E21B5935EAA38FFBF68BC3B909E34C1
+:106C50004E12E9F781C74935E8E3E038930C70F745
+:106C60001F6732C1A18FC3DAA20CE79FEBCC3CAE09
+:106C7000726698332636821ED14B7183C970FF60CD
+:106C80009DE4B262FF75CA4E35347F287C5F00EF09
+:106C9000C56421F0D5C17A86C1720BF3525E403DC6
+:106CA000F6132207A2D9A562BF62C2F8E9F92EC67F
+:106CB000FE45B9BD107D7233F22DD88B3F583B7E17
+:106CC000950FEC49C9EC6947BA4A769313F3686BA0
+:106CD0001513C545EB92AC64FFAD12CA559473BD54
+:106CE0005FA9432238F47D8F81E6299F77D03CC38A
+:106CF000EF3BFB9F1B4FA176FDEE573B30D7930F29
+:106D0000FD5B54930B455D4E53D82721F40FEF479D
+:106D1000DA2045EC27BC9D8EFF01E96CEE70203D2A
+:106D2000BAE3A58879101B95EF9807312F4C1F27E0
+:106D30001CCD0EE0F74287232383F4E54605F5A535
+:106D4000FDCC9FDC4ED2CBB4EFADAF7FE684A9562D
+:106D50009E4F6CBC576F20FED3F1627DF341C6F3AA
+:106D600053BD947F72393C4882CB43FB007629E2C5
+:106D7000BE36584286FC384931E64F35481EE2633C
+:106D8000F34DD556DA27495B69C57D92D592330616
+:106D9000FDD8DE37C1FE83F9353A79BE6A78FF6BDC
+:106DA000F01E66B4731553C4FB79A306B0AFBA34B2
+:106DB000FAACD97769FE01F5E1C175372A4E5271F7
+:106DC000DD359B39BC03AD4B7ABF03E1EBD17DFCD4
+:106DD000F71B2C39563FAEFFE1E3354A1E4F3EBC50
+:106DE0006F047870DFAC31CD4DF86D542515FDD5AD
+:106DF000E81151CC1AEA6F65CCA2F767E2E3F1CC57
+:106E0000226B8C8F9C97A3E369B7F21DED1D6F1861
+:106E10005F0E7F8FE2E8217CD9A94CE8CF97BB9128
+:106E2000171338FCA1F7A65A338645BC7FB21F7FE3
+:106E300086F14DDE6446E7F70643B919FA6ED5EEE2
+:106E400043AAC0B50BFCF4F27B14A6C2FAE677E4C1
+:106E50005F4039C96BDFCFCFD1B426F07B1EB5EFD1
+:106E6000C3C75D62E7FEC812BB4A65CC51F72FF17C
+:106E7000F7375ADBA39C785EB1352EB21F9363D7E8
+:106E8000F3689AB473081DB44FA1B7CF9BC7DCCD8C
+:106E90000AC53D1BADE07F25F4B5FFA9B63F0282D0
+:106EA0000BE3DCF9DBEB9AF9F9513E7F8CAB62FB2B
+:106EB000C4C48E5C41FC0E74DBC60CF7DB55583B3A
+:106EC000B251CEE79ABC997618A7EA684722D65BFA
+:106ED000DF3E9D4E7E6F1DB7377B774753DCA03F6B
+:106EE0007D6AF979F2F329CC37A83FDDCAA500AD58
+:106EF000ABE5E7D3996F1CCDDB678D0BBEBFD3C26B
+:106F0000D8A4B1C8001C4F889F48F430DB4D067AE6
+:106F1000803C5E67D7E88178EAA3B776EF4BA77627
+:106F2000BFE071CD5F612AF7D7F5FBA58E67F7E566
+:106F30005BD07D5BE536F713784F0B3B2252BEE604
+:106F4000C229FCFEC48516770CDA570BFF53146A6E
+:106F5000697F93F3FD220D7F9DCC45F70EF8D6DABD
+:106F6000F8BE4E987F96F154FEB83FC2F78BDA44D4
+:106F7000CA1B5F3045F161BF79ED05BFC4FDF9E281
+:106F8000C6683A77BEF07BAE9368D72D7CC2E6C464
+:106F9000DF7B59FE41667E32F4BBFCC90CD507DFAE
+:106FA00045AFF024595DA0271FDB53887E45833011
+:106FB0007FBE3006FCCAC70EACC2B898F4CD94CFE1
+:106FC0006D507FF4B1775661BCE9B718E7263BF600
+:106FD000DD42B4635F42D0F4FD3FC0C14B874D5AE0
+:106FE000FDC4AAA9A0F2AF4D6835292AFA65275633
+:106FF000E139D9C438F718138CF78EFDB342EC6F22
+:10700000C113A3CE6D80F7E7ED17C8BE003A69DF64
+:107010000B374F01BBBB78B25E972D588F8F6686BA
+:1070200038BE3933383EDAD9AD7A7C8B45DD8C7188
+:10703000F7E305D55324E83FC3A1AECE19C9D8C4A0
+:10704000F5F9AA1BC6CF76C4DD8CF198D6BE7D8338
+:10705000F8D5181F6B65DE0366787FD3E3436EB601
+:107060000262E30779C6A830FF41D629ABA7DFF457
+:107070001DE46344BFF3590DF60492934388D2F4A0
+:1070800015FCDEC23EF94EE37CDB571FD1C1CFC3F6
+:10709000E8F5245E6F5D19595FDC12C3F9BA352A31
+:1070A000F2FB664D3F00BE03147F6D8BF60FCF08D9
+:1070B000EA0F901FEB2492A7755C7F801CCDB493E0
+:1070C000DC46ECEFDBCA6BAB76AF79ABE48EC6F88F
+:1070D00082AEC7308286E3CCB53B0DFA39AF7D0175
+:1070E000E9D751312A87C7C9F19330C5A84798B568
+:1070F0003D3B74DFFE77DA3C33AED3E33F013974B6
+:10710000DF69F98EFC4B9E9F2DC7387F88BD1D9C83
+:10711000C7548A67F4EB17FA736AFDBB72AE045F5B
+:10712000EA65F0154FF8BADC3C83FD19E32FFDFB4F
+:1071300093B57DC126E33A224786F3A4CE27807F0C
+:107140005388FE2CD6F4A99E07D1BD6B24E54F06CB
+:10715000C7E5E73181BEBFC4DF5DF2813E453D96A4
+:1071600027B96FC5F679ED712ADAEFC06FF51ABF4E
+:1071700049C86F3A9D5BE3AAF369BEEB04B24BFAD0
+:10718000D941DA3A9AD724D0EF990D9EE715E787CF
+:10719000C0A7EB7BE8BF55EB7F3CE7E767FBF8F95F
+:1071A0003E941FCD9F67AE0EBA5F3D1CFE852873CF
+:1071B0000921EBD5AB368AEBEB78BB5AFED7ED85D0
+:1071C000F201D725077D37F868C0E184768B511E20
+:1071D000505FB57C42F764B6B6890C7FB200E78D8C
+:1071E0007A234FD793BE95870A24B25B827AD94916
+:1071F000F68BAE3703566BB0FDB9B52B0BEB51AF29
+:107200006AF7ECC78BA0C5C706E1487370BB7792DD
+:107210009745FCDDB81CBB5DD723348F8D2B0AE866
+:107220005E852A6D3D9DD4E1A3785334E27142100E
+:107230001FFA7A7DA7A5E315EDBC97811FF53AD813
+:107240002595A6AC60FFF87E6608DFE739381F8415
+:10725000D3E7BBEA27C0830FF1F0430DEF0950C716
+:107260007B2D9804EB17E6FDCC505C6B3242E05668
+:10727000B83E4E104D5C8F5D462EE20731EDF7585B
+:10728000EC24CF417C70BBE5018716E7D5EE293FA2
+:10729000680239A17D363ECFEE5DC9D4EF6CADDD1D
+:1072A000DF4B2F6FD6F296747BB1E2B5D4CD46F8A2
+:1072B000797FBB1C1C2F7947DD63D08E19EE515CA2
+:1072C000E81FE4B5CFDC8FF924D97BF00704827C7A
+:1072D0009EDDC2E514B84BC3CB9BDB43FBAD74D83A
+:1072E0007539FBBBCC23FB28E757A4CB7D21725A11
+:1072F000E35038BE607E16C4A764D4A37AF9F7833E
+:10730000C3B31FCF2595033E506DEB786B6D99BFCE
+:10731000D286727C94B9508EBB5BE69B46215D3170
+:1073200011CC19A21FD6F379E87628F0650BF2E5A7
+:107330003AC7101A6FF85177740EBC1F8E7613C6B9
+:107340007D5BEC7EF423FC0EEF2E07E27356EF1408
+:10735000DC4FAD8CAEAEB5853CEF6BDF06ED898FB3
+:10736000BD22EE1F953FC0F8BDF1DA7CA0A9CF0287
+:10737000E355C820A759540F20DE5A65DEBEF73EFC
+:10738000FAA5115629F27BF960FDBE95F8F36D530D
+:107390001CD217FD24B493CB454F1AEE7BB2C11615
+:1073A00017AE03E07710BF1FB431C906FDFF1E4AB8
+:1073B000D4D3D3C4A5748E6B5A9640FB44BA7F8F46
+:1073C0007A0BFDA43BBF174DFCC82E3C380CE3D311
+:1073D00009D19C4ED08F55EBC76A1D1B94BFFF4847
+:1073E0001F49FE8EBEBE1D1404EAE7E04DD735D717
+:1073F00085F841D81FEAFF83C28CB4A5C8FF9A1F45
+:1074000047F6617C70DD457B65AC21CEE6D3E0EBD1
+:1074100048473E0AB547D13EEDB3677DF357DF0CD1
+:107420007A76E2F496005E715FCB8A6EFE17E86FA3
+:107430001AD8B336C0C33E8D2F0E66F844DC4F3DDC
+:10744000385CA0FBDC0F457973AA95E038895A5C5B
+:107450002051CB334F8CE2E50F62B81EFC3C86AF67
+:10746000D737A8BC9EE8881C4798ADBDFFA989EB1B
+:10747000F735F991F3D14F68FAF5AAEDDE1C21FC3E
+:10748000BEEE138E09DA7DDD946FC7E3FD0B34FE8B
+:10749000063B87E814B4ABF87E9D6E879E6D9F4DCA
+:1074A000F51382F7BD7B042C3D4F909FF4AE48F15D
+:1074B000A1E2586F22E6A55544458ECB0CD2F0F4DC
+:1074C000590DA338EF29DCCFCBE6BFB785F5251BD7
+:1074D0009EA47B1D4A999FE2BD451B1A68BFAEC89A
+:1074E0002F30A780FE9987C781353A946E110D71B0
+:1074F000E7C552B51C9B13E45BFC1DAED0F7259B82
+:10750000C619EA576F971618F23B827AA790ECBF1C
+:10751000F07E753E0FB74F8FD7380DF1EE051B8605
+:1075200017F2CD78DE7E2173D17C17366619EF1104
+:107530006E4CB8B27B82C11EF545845326FDA83F30
+:107540003F0EF8F785C4F7177C3A8CE0F88BC37BC5
+:107550005D8C018E68E633C4CF26F3DF29B4F1F8E1
+:1075600023F08FEF5276407ECC77F507AE1DC01F1B
+:10757000C8FD87FA037993B9FE654D02E5E04C9C9E
+:107580006AB4CF66C7F0756E764CB4C13E2B9A676D
+:107590006C37576B37576B77B9384AA85D2664A1AB
+:1075A0003EE3FDE9BF1F9571FA6DCAFFDC10C3ED24
+:1075B000D79FAA6E6F0CF4BB563B77D06FDEDAEF25
+:1075C0004AAD35F7E585525EE0E66F1EACC3DF09D4
+:1075D000E9DD01F63FE8C1FC67DFA07BBAF4EF6E9E
+:1075E0005FD132B408F054A9C973B98BCFAFDC15A1
+:1075F0009087413F29E51CAEB4967D8214F25D5A16
+:10760000096FB722C66CF02F7FA2D5FF35C649653A
+:107610005A49401806ED52366D1124EC0F7F570B76
+:10762000E049A966FED0DF934A19CFED9ADBC76F18
+:107630001616E604F1D0689A91A3625C3531DA85BA
+:10764000EBCC47AAB70EF150FE5180CE494CFCA8B6
+:107650005D42BBBD5B75D7237FEB78708A6A0AAE4B
+:10766000A3D11F71389BFAFC62BEBE30F6A86647F4
+:1076700037EB76E961C6ED425AA712578E30FC3ED1
+:1076800061629CB64E2432EF4E85DA3732A227A3D0
+:10769000F924AECC6EE6762CA7F7B42CCF167C3E40
+:1076A0006DF0C8B178DF47D6DA8084BF3BFEDA26BA
+:1076B00053C4FB519A35FCC33C9EC5F9E9F3B89C11
+:1076C0005ED0DB9907884FE8F2103D3DB2DFC1D8AC
+:1076D000E3F43EFFD9F87BE9FECA7A997E4F4EC7A4
+:1076E0007FB7EA6941BCA6B46C160837DA787ADC51
+:1076F0000E9FA35C1E978DE73A0794FB153B8716F8
+:1077000085CA7DBD4CF4D91C96E7AFDBF77F88E1D5
+:10771000EBEA9058CF3EC44B65DB3A8AEF2CD9C2D6
+:107720007FF76740FC5C21FE8412EE0794CFE1FBFB
+:107730005EF9CF4A44FFB27AFEFBACE5DB77F0B8E6
+:10774000CE8F990BF54379CB0EA128077F0773875E
+:10775000B028049FA9E57ECA83BFC6AECB1FD75B06
+:10776000E1FC8E7162B4530ED9B87EE8CC577CB878
+:107770001FDC69F69663BBCEE46817E677E9F8FF8D
+:10778000FD8E9BE9DCB57DA7258065A3A939C98A53
+:10779000FB0ED7CA2EE4AB6ED57B12E91327795ABC
+:1077A000F1FBD878BBAB16BE755AD85855B9723CA8
+:1077B0004C0CE38F893FE67293A43AF4BC86B12463
+:1077C00037AA9DEB2D13D76787CC7C1E3B1987F713
+:1077D0000731EEB3248787E368DC94F2009D1FCA6B
+:1077E00038BDD370CE30C85FEEBF7D1B7EFF3F2C0F
+:1077F000A14B2800800000001F8B08000000000043
+:1078000000FFD57D7B7C54C5F5F8DCBDFB0AD90DA6
+:107810009BF73BDC100C28246C9E0401D924848740
+:10782000206E0228C86B7947926C02D2FED0FA6DA6
+:10783000168331E56B6BD41645A92E8896B65A830C
+:10784000A2060DB82822D64723A58A2DDAA5202224
+:1078500084641BFBC056CB6FCE9999ECDE9B0D0F59
+:107860006BFBF97CE18FC9DC799F73E69C33E79C65
+:10787000991D33B5CDA88C22A4A69A38BC342DFD11
+:10788000E90EE98485900BF06F2221836C3221F19F
+:1078900084A43CBD4D522C58BE7F5A1CD6272605C9
+:1078A000BE4BD8AE8696AFA0A95B22848C25E4A0FF
+:1078B0008178CC3184B4E82A47D968FD9684487B26
+:1078C000132D3B667345DB687F96639D07ACB4EA76
+:1078D00098633EA38BF64BDAE9C76442DE3012129E
+:1078E00041DB1D8C60EDD36D74902242261B89070D
+:1078F000BF1B3D2314DADFC1A183B0BF97B7EAA64F
+:107900007A697BC320B2D81932EF749B0EDBA56C69
+:10791000DD21E9E8F7B8485A1E323F51EF015B59C3
+:1079200026CC67CCD44E8443DD563DAEA7C2E81CBE
+:10793000B66654B0DE68E88FD67BEDE64F8C7EFAF3
+:10794000FDC72FBD6F2450BF5572B4C1FC5BDF373C
+:10795000CEC9A1A9E7E7324920643A61FF36BFF0FA
+:10796000BE51A1DFA7EFA670A2F5EA76EFD22FA352
+:107970006957A9C5238D2624F3CC6B8B4821FDDEE6
+:10798000662211746EDD3657918DCEFBCD5D530EA0
+:10799000495184589F33F92015F021C49FE1B40662
+:1079A000E725523A30CE2F722AFDB310B246EF557A
+:1079B00099F0DD955945EBB7C630F8CC1FCCE042C5
+:1079C0002CEC7B155F97800B1D7F0A8C5F91E5DCAB
+:1079D00001FD542446D89B32619EF9AF9929DCEB16
+:1079E000EC923D82568D2B67F00C9D57654EB87911
+:1079F0006DC0F1E263D9F844EFCF807109F1B2EFC5
+:107A0000326921F9C1F67338BEE9771FFB4E863A19
+:107A10007382F3D7E26F834DC2FA61E86C11ACA3B5
+:107A2000F698CFC7E8AC530F749679E630E243D0AE
+:107A3000CDCFB6EA3115FDD5D98CD85F9D4D8F706D
+:107A4000D90C781A4C53032C9AA61BCC5E0F85C711
+:107A50009BF3261F9272297E6E31FA207D43B7B4C4
+:107A600016CADF4861E3B7E8746B21DF729785348B
+:107A7000215E1D6E98CF6B3747217E6AE71ABD26BF
+:107A8000DACF8F9F9758DE63F112FA67AD6BF6720B
+:107A90006847E222EC4F02FE5C078C73ACFDE94ABA
+:107AA000796EBF51A1DFA7B7B1FD27F050DBC6E863
+:107AB0004BEC0701D7203CBDAAFD24F0317FB08DEF
+:107AC000D105A5178077CDCE08DB49331BEB02012A
+:107AD000FA8C56E5EBDB936D274704F335F007D0BE
+:107AE000C10E628179D6F279CED3B9EE83FD5567A6
+:107AF000F61F3450D4161F0DE07E1F887E6BD6FF14
+:107B00003AFB640121AB930E612AF6AD61A87A7F3E
+:107B10006FE5786F8294B67B82D34D4D611BEECBBF
+:107B20009A930DB89F2D53195FB31C238E503C13AD
+:107B3000F243BEDE7BB17D4564DB6499C2BDE27178
+:107B4000C9D644FACF4FA4AB24E26CA3FD7DB6F5B1
+:107B5000F5A82500DFAF2EC8A498AE3782AD7737E1
+:107B6000E73B5D3B29C091DE1B8C24CC7A2FB73FCD
+:107B7000E23B22013C6B38ECBB9E2E1FFB29A51774
+:107B8000CFCEC1F6ABE892CF3E3DEBF64FE9BCBBA2
+:107B9000764CB4CB40364D4EA49F407C847D3BA5B3
+:107BA0009F38994C9528DE37B4BD1E358EB6FBFC48
+:107BB00097A3F3816FBFCDF7FD99E7E5F50097BB7C
+:107BC0007EF6EC75505EE395624D30CECEC7FF95E4
+:107BD00042FBA9DE510F10264DBF7CD5E8A7F574F6
+:107BE000DE6DECFBCEC136A8F7F913F75F07F06E38
+:107BF0006A6BC2F2334F6CC3FC6B3F7B76DF3F682E
+:107C0000BD5A67941DEA9D797E3FE2A5D6A577C04F
+:107C10007A07A2EBCDBBF6337ED926E17E2373191A
+:107C20001F13742DE8F7F39F2D1E1B2A37C4F71678
+:107C300023973B83981C39CBF76F4D99A505D2B399
+:107C4000CF44CC85F5BA8DFEEC6898CF2846171F37
+:107C50007178D4B6AD31B82DD81EFBF980EE7B48D3
+:107C600073287D9EA2F44E6BEDB85000E3FD0AEB45
+:107C7000D37A251114BE372F382EC17C22473518F0
+:107C80006A709EBF64E574D5A1E5C5EB183D6AE94D
+:107C9000E00B9B05EB8B7D90B2BB324D413E60B259
+:107CA000333ECED69752ED6AB2D2EFD7AF73D965D5
+:107CB0008AC7974F1F9E9C4AF33F1B211520FE65E4
+:107CC00089C9398F05C7A95B5F464ED0F9EAA2D9A9
+:107CD0007E49B011FDB5C807B631BAD713BD05F25C
+:107CE000FA00F289BA162E0777B0791273206396DC
+:107CF00015DB59AE8D09CE83B6B358301FC8B829ED
+:107D000007E48E672ECA1DC588F33D23F801F1E410
+:107D10002ECC09EEB7041D7101FE138C34B5307EF4
+:107D20005349FB4F8F2E4D8A2E0AA6098358B91648
+:107D30004EB7F0F21F453B92A2015E3B6355F260E5
+:107D400020BEF2DACDDD4C6EBF721CE9D00D740896
+:107D5000E3BB4EAAE4F67264AE940EF71C473A5C9D
+:107D6000DECEF8ABBBBDD4B88CA69B253217E6EFB0
+:107D7000E6F4047464A7F99BA2A3717DEEEBFCD931
+:107D8000C0A7BA39DD75EF61F4F6864EE701F8BC9D
+:107D9000B17DE43690075AF928553B11DF6E8A6FA2
+:107DA00093047AD6BAC3A067D555133BEC57F76E48
+:107DB000BE1F1A08EE07777BE572E82F356E9A5DD5
+:107DC00096502F999C4AF3EE5A5204FB2D656BD9BD
+:107DD0001EA00BD22E91AB205FEDDC0DEDAF8FAB73
+:107DE000B3CB9920F7B6279969FDEB471463FBCD18
+:107DF000E94A29F4E7A920B627216F70A13CDB9C52
+:107E00003CD20EF2CEEDDA887A175106D9A19CB891
+:107E1000F46BA1BEDBB3806C92C2ECE33D9203CB6A
+:107E2000BD91DE08DA7E7A3BD37FDCED6C1F9F13B9
+:107E3000F011A9A173118CD7FD828978A4209DBD72
+:107E4000B9670A93B32F9A50CE9E6D749013543431
+:107E50008F8C5610AF028E35AD993AA05B42669971
+:107E6000601ECBF83C5A0D4C6E44733990752F9BB5
+:107E7000C772BE1F9647EB786AE4FBAF95C9059BB6
+:107E80002717E4E0393E1E924502977374E8BAE57D
+:107E90003EDC27B54FB3FEE24C8EBCDB42E855E832
+:107EA000475A7A6CE2E3A66C3D20013349D95AA5C2
+:107EB000DAE7D757135F3D5DE7F55B75BE89B9A873
+:107EC00037DD82FC7C83916C97FAF7774F34E35B64
+:107ED00015B1CE3C09E4D7CD16D43FFAF6E9208798
+:107EE0002E02F4B87CC9DE84AB7016EA68BDD309F3
+:107EF000563BE0ED471C8E5A7DABAFBD460F9CD183
+:107F0000EAC9254369E9864173019E545FB798A188
+:107F10009D8DB6A7F512B68F7B6213F2AB26ECF7F8
+:107F2000F6681BEB27D659D8002C2ECBB98EC92763
+:107F3000AB3DDC7AD2A3859EBD284F07F433DB82AC
+:107F4000FBE1C7AF484B19BD514128013DB2FD418E
+:107F5000E8FE7852417A443DCADDE0F486A747B690
+:107F60005FDC54AF023D9BD2E35AA6275B08DB4F90
+:107F70008C2E23A73279007C2B549F15FB54BBEF2A
+:107F800005FDF6EDFBCBDCEFDD06B61FBB291C8043
+:107F9000DEFBE8FC6546E79B36D0FD48CB37D1FDDC
+:107FA000D814C2FFB5E71F98279C0704BF3D66732E
+:107FB00076005F746F7FAB19C996F347F7CB3FC864
+:107FC000BE98DE6586CAB45F33DDAFA1F463A6E078
+:107FD000B6E663EA013911B95EAD4789F4836826D4
+:107FE000BFBEB1DE3842D2A3DEC3F155AB737D0014
+:107FF0007C1EF4464A1124633DD31B1340E600DE89
+:10800000B6477A413F4E4820AEE7C2CC673FDF67B4
+:10801000029FE2FC9010C5EAF7F27DFF29AFF74F0F
+:108020009E869C4B703F283AD771220F2C8F443B81
+:108030003A2F2C17F3E93BD798D97C13EECADEBE52
+:1080400029048FC17D75753EE037EB5E9F7EA925C3
+:10805000388E908B5ABA81F983FC81F5548E1AB808
+:108060005EEB7E7E3ED3D07104DF5F7BA8B882B426
+:10807000D5E0FB2BEEC7355602FA222507472C9D8B
+:1080800057FDBEE16C1F8D086443FBEA58D74D31A4
+:10809000B4DF3193F8FEA0DFABE09CA0271E530CA9
+:1080A000E0DDE0F587E0F9D318D67F8FD5EC91E9D4
+:1080B000FEB823D6150DED3D65C4EE03397307E513
+:1080C00027B06F89AF08F84D3DF147019CC7585D57
+:1080D000F13140BF726736C9A2FC57F2E7C2F763BD
+:1080E0001151B984F6F371FB6F9F7985B65AF8CABE
+:1080F000B985DF03FA7A312203E8E218D5973B51BC
+:10810000DF560683BEDD4B94C1B630FC57A40BCCC2
+:108110003AB3BE20983F66559F2F447A4D0CC36FEB
+:10812000FDF914E28985FE099EBF7B6214F65D1F8E
+:108130003082EA567F3E8378687F1FEB48755B98F4
+:108140007137C5307ADB4DC8D470E5F7F171760F21
+:1081500065FB30B04DF2027FAC5EBFE1CF32E50788
+:10816000D5EBAC3E4C6931E86FD5368F4F47F3C73E
+:108170000C8C1FD17FB3CDC541B947EBE9C7030EC6
+:108180003CF4204BF9E0522EB79635BCF925D813B4
+:10819000AAF5C43C9EF6B3DCEC3C984A8B3EB32C6B
+:1081A0008F02B6BFF23BB725805C4A5CD0CAEC3286
+:1081B00064920DF45EC93143BE1079313D4B8FFAA4
+:1081C00031E29FE2EB8B18E74CC0F782C104F580E7
+:1081D00005B7457A3D217CD0CCE1A1A59B4FB87E67
+:1081E000A5ED7F766C1981FE3AA29C73813E16DC68
+:1081F000764EC5CFBA25FF538F025DADB1DA9F64CD
+:10820000DD653843E8FE3B62BCF33AC4534F5E671A
+:10821000F6FA4CA0DF40C68760CFEA30D93C0A941A
+:108220001B11CFA2DD9F1A29E3CB0EE6979E1E36C7
+:1082300019E86B19B13703DE97B544124F083F03B5
+:108240000518E8C37D9E603F4B3BDE3C0AFCDCAD7D
+:10825000F7239D2C355B108FEEF37A9C0769317400
+:10826000F9457B8AFB23518EDB607D9E7BC6479F51
+:108270001A493F26D2EFB87ED7EDF0FDA1C828E21B
+:1082800000FA784BF60EA7F3EF352B836328BCEA90
+:108290008D940E4663374E7388FE43D2AC6AFC77EA
+:1082A000BCF525CC67B9D9650439BEC241CFA73228
+:1082B000E0C957641B158AEFF1F28591978FEF455E
+:1082C0007CBF7F6CA4F41F661FDDC7E1DF23EAA536
+:1082D000B07DF27106A97E0ED26B684ADB7D3C94BC
+:1082E000E7F3793E9BD74B60F91D7C9F7C9CCBEAE2
+:1082F00069C7F1C530FE363BD6B115E045DBF98CD8
+:108300004017FB22BCA8B716527E07FC6D6D3AEAF7
+:10831000AD94AFEDC07AD9C4178DF54C28574803FA
+:10832000E57BB0CF8B1484CFA6524A27B43CB0D79C
+:1083300064DBAE04F12AF0A9C5637B8CF4EFC9C3FA
+:1083400051923ED48E42E5617B0CB3A318617FD27B
+:108350009918999E360CF18574225F3EBE6E8C6032
+:1083600078A0FBF4B518D47B7D39A1FBE504C79751
+:10837000E0671F0F52E3B58AE3E16D5E6F518C8DAC
+:10838000C94F7B00F7DDC731AC7E5C169343420FCB
+:10839000FF0387CB4D9A54C8953153D5FAC54D1C70
+:1083A0009F37C54409BC7E08F315F288F2175F3485
+:1083B000DD0F0B5E35217F211B03D9B0FF68BD6344
+:1083C000586E0A2C8AA572E426AADF18F3B1DD22C2
+:1083D00068DFEF3C3F4AD08595809C3E25D65318F8
+:1083E000407E4FE51DAE6B29A17C43BA34FE37D0E9
+:1083F0003AC994D6870C56D8F94EA60302ED8F20C1
+:108400000AF447E1FEE750B86BC73BC6E9E09F318D
+:10841000921EF19647F2709FBDFF857521EDF29C8B
+:10842000CDECD151BEFFB8CE7501FAE9BAFD2DD41D
+:10843000CB8F197DD9AD9630E546DF630F49C1F288
+:10844000C53F973D46CA2F767776FDE466BAEEA51E
+:108450009DB21D865C7AE75FDF1D037A75A7C10EAA
+:10846000E7462ADFEFD5C3BC1B981E794CA7A6832D
+:10847000B3DF559F73D26219BEA8DE83FA9CE03B3E
+:10848000427EDF4A7C57815C5F461C4648FFB466EB
+:10849000D50C42E1B7C2B20EF9D1E76BA7A11EBC61
+:1084A0009278B07C598BE14FA1F26145AB3ABFEABB
+:1084B0006175FE56AF3ADF677F2E0F2FDFA7C732F9
+:1084C0003A3E4BD93EE03FB0C1E4053D485BAF9832
+:1084D000D7CBA43CB113F82495FB60475817E1486B
+:1084E00004BEBE6E6F69E2C5EC7CF5E7AF21DE101D
+:1084F0007D23A837E4126F6CFF7ECB63158423F4D1
+:10850000ABF071E0BC71B62CFC3A26C60A3D651092
+:10851000F627BE8B7E82E345E13CEACF9B07988F2E
+:1085200005DB9F5D197E9C1BFAC6B1A9E464B07D92
+:108530001C936BFC1C2DE8A3FE7C127E1779A1070F
+:1085400007DBA531FD8AA4D94E4506F994B0638BAB
+:10855000FD704222E664B43BDDCFCFEBF65CB05F4A
+:108560009F003D08F6E314659F9F4E71D9F7C666DC
+:10857000EB8706F78B761D94AECEF843F8EEB25833
+:108580006B1C8E6B27761857D0FBA2DB2B06BBE843
+:108590007CFF786779A26B54283FF530BF8951E89A
+:1085A0005F16959C251A39BCACFD2DD4BBA8BE9591
+:1085B0000D4CE7D3BDB723BDAF24CE04A0F39EBDC1
+:1085C000C3335CFF86FC15F399E559622098A79B9D
+:1085D00098EEBF2A3E9F591D4CEFD3991D061CC72C
+:1085E00041145B021EA5D97C29F3D4D3FC84BEF9C7
+:1085F00083918E90F17CFE12B4A7F09DC053B2D44B
+:108600009504F336C1B874BC08E24D82B469AC5D20
+:108610008174A2E4D4B379303C4F260D69505F6772
+:10862000F6CB6C9D740609D0BE0F5E98B7F2FCC6FF
+:10863000D9BD8B56C0778B15F98891CF63472CE550
+:108640008766E42F6658B7C9E2FB1CFD643CF594CD
+:1086500029B88F3D4309DA3B06913602E35A2CE7ED
+:108660003CB0581BB149908FB0F5FAE0FC70CE6673
+:10867000F1E846239FDC190B7C527A6725E085F2EE
+:108680006566FF19A85CEFC373B7E073317C7E4D5C
+:108690009CCF2513068758E2C0F11EB0AE9C414026
+:1086A0008459D649D07E4BD454F4EF2500E0697943
+:1086B000EC54BD8A6FC53BD5F9C4B9EA7CB24B9D79
+:1086C00037D3933FE88B92CF99742116CF5923C0AB
+:1086D000DE62E0FCA299CFEB08A4743DEF713EFD91
+:1086E0008DF513BBFABCEE8E3112B4E32598CDD0D4
+:1086F0003FD557DE8B65FACA271E289703C8CFF3EC
+:1087000026B6F9C0AED37C8364BF8B7E6FB62A1BBE
+:10871000F494543DD32466C7D1DB4AF5B47C5B8620
+:10872000CDBE89E6EBC17E1D0BF3B7D53C8DF64976
+:1087300013AB4702CDE08FDCB6C966837A71E58161
+:10874000C946D08B5710DB761286BEBFA2FB86CE01
+:10875000F709C853BC489C5E220F29F3710DBC7CFD
+:1087600007FC9DC5F2138BE15CCAFE6575E4753AA2
+:10877000C0EEE090512ED677E4BD6EA1E365CDCE7C
+:10878000433BBCB39CF97309DFF76334FB6A5C902D
+:10879000CEB13C8FE7877570BB6E9C89F96B6D74A9
+:1087A00088626636C0FA718CFEED44FC63FBF25AB7
+:1087B00012FC07FD9507FB473E3429581CDC677403
+:1087C000A87CB3BDA996D61BA3F7ED877D3C8EA7E9
+:1087D000793C7DA3F40694BF9D3A8B62D4B17D6D44
+:1087E000CE0213865306B814DB7ED004FD4C907C79
+:1087F00098664CBDBF09A65FC5ED47D14946EF0657
+:10880000BA8EA6128A67B477FCF920D8A5E5074985
+:1088100001E0E98841C839079ED3157A1CFB1A3A52
+:10882000986C40FDFC2F932AF03B01D58CCEBBD237
+:10883000C61621BE0F2C5F75283F6AE364E437B388
+:10884000A632BF6AFD5CB3579240CE10E677D2BB2A
+:10885000326F0AB197083FC4FB0632775798F3444A
+:108860006D1CD34FAB66303B6FFD46A3CA7F531DD3
+:10887000C7EC5E33E3268F8C4379C4FCA779715C27
+:108880006F1B4146009F0AE1234550AFABF4ED81D9
+:10889000F88CBA9CF399398E0203EAFD9CDF08BE7E
+:1088A000EE1CC4F6F33C42D281AE679306E4FF8728
+:1088B0004B6F457E7313F118006F1F95B17802312D
+:1088C000EF5953D57AD21CA73A7FF35CAD1EC5F0A1
+:1088D00021C69DE7529757093D78AA5A0F5EF0FFCF
+:1088E000BE8A46B99AF854DD8521E0E760F600C0FB
+:1088F0000BF373E8916EDC1B993FBCBE3DEF8D38E6
+:10890000D8677712BECF7649CBD1FFB24B5A1182CE
+:10891000FFD45AAF047264B855D87D98DEE4347938
+:10892000F783DFC359831291BCCEE3490E403C4923
+:108930007E90BEAD65561657411CB5309F345BA482
+:108940001DF4FE165D3EDA655BA2AC2A3BFAA60D6D
+:108950004A05D413F658C544F26D9C6EC29D77D774
+:10896000C531FEBA59627671CF3C339E2BE3B39C7E
+:108970002A3F41BC4C8E829D70649C22EAA3FD6319
+:10898000B3C1955C4053AF44971117D25E261BD1FB
+:10899000AEA8E14FF1B176B4EBC70FCE413BFD9CE1
+:1089A0008E3CB42F124B84FD2A29D8FF9CD9DBF4CE
+:1089B00010A753DFB14DBFDC12A4BB7BE2B85C8DC6
+:1089C000249140AF7D76BAE74C68A77B5CE7FC5FFB
+:1089D000A0CB5AA30FED7121F48ADF07928BAB383D
+:1089E000BD18CA9CF356D0F9F5BC6BB4C3F9191D78
+:1089F0006DB4FFE7F744A39D515F45503E6D2C6574
+:108A00007CA407EC5F741D9F4557E3F960A3D48AEB
+:108A1000F2A33B6632D2F16ACB013C07576FA574D3
+:108A200018229F56EF50E76B48279EDF6B9FEE475B
+:108A3000CFC817051F76EF56B723C3D47C378FCB2B
+:108A40008B7CA77D56054C7DAE3D8B9DC3E9418651
+:108A5000AEA3E81D23B7EF2EB09D8A0056FB947499
+:108A600031FDADC77A5A66FB9FC983223E8E566E92
+:108A70001571BDED3ACABFE0FC2AF4B022C2F2077C
+:108A8000741D72922E38DF42DE4EE87F424E087C23
+:108A90009596105242F743A7E04F43C950C037EDB7
+:108AA0001FF78904914331D8BF07CE7DE3F878944E
+:108AB0001E3C20B73D3AB317E8AB596A4039690606
+:108AC0003D9FA69B2417CA8397AA3D32C07B2C6981
+:108AD000983583D61B6FEE8C0438513A39124A3FD1
+:108AE0004DC497B14B52D111967745BF1D968E84D8
+:108AF0003CF37DC4F498E974C5D04F05387E687A9C
+:108B00004062E7C829961FEBA1FDDBBA69482753ED
+:108B100089570FF3ABB0A9F13F25499D9FA6F4A358
+:108B20000F8CC37070784E1FA12E77087E47D4FC3F
+:108B30002E937C857A18F9C1C1EF805D21723D19B1
+:108B400001FA0DD544711F6AE9E0EBB86FDD6FF2F1
+:108B5000755C18BF490FB7135F4BFC2B9F96FAD378
+:108B600059F71BEBE5A4107A14FBE265038B7F90A9
+:108B70005E65FEA9123319E503FA2A647645B13F12
+:108B8000AE05FA8C09D25D31FF9E11CFE96C081950
+:108B9000027436A13DC22753BCE4F1FEAE05BACB48
+:108BA0000FEA23E25CD154D28FBE32A52CD45F7081
+:108BB000DF097DA4406A6BD267021FB9A709E61BD3
+:108BC000424F43E38B802F517AC27DDA4FCEAACB3E
+:108BD00035F426F02EF4E552D28074365BA760EAB5
+:108BE000AB5C85F2B5DC325B0FEDDFAC62F43609CD
+:108BF000E8310BEAABE9A5DCACCE6BE9918EA80BB2
+:108C00001D574B9F03D1DB10A037215F632F4D6FA2
+:108C1000D3E3BF757A9B1E7F117AD3D299E05FBBF5
+:108C2000226CE5A03FD7574B280F0ADE1DD604F96A
+:108C3000E17599A84FEF8AB6A37E5DDFC0CA0B3BF2
+:108C40001D32C4BD64ADE3E599CE72C8D7AFA7E5C8
+:108C5000B4EBA2232C2E66D89DAC3CEFAE86D7ADEC
+:108C6000A0677858FB973F6F96A368B9B799B72F5D
+:108C70006D2D877C7D0B6BFF19F8A946437C9AB755
+:108C800009BE5F7D6FA69D1DAB99FE3E91AF7797A4
+:108C9000F4DCEBD8AE95B55B75D03C88E0F99FE984
+:108CA000E5D7F1754EDCCAD61977E2FAA90AA58B89
+:108CB00015010FEA6FA774B5C5C8DF06383F974A9C
+:108CC000AD69904EA1EC175287D9DE220F657ECC9C
+:108CD000ED74887BE299FD45F8FF20CEA032449FD9
+:108CE000B8279ED96345BD84188A01A08747ACA8E0
+:108CF0005F0BFFA4EF212281BC8735723D24ACBFFE
+:108D0000724A5603EA115386083FA55FBF948E9BB3
+:108D100077E18BC9E1EC433FE2E39EE671137D7A94
+:108D2000B237530774B10B88240580F4DEAF417F5E
+:108D3000DB057E4826A43CA404F0CAF25BE37FBDB9
+:108D4000A9653C85AFAE41EF01A1962161DCC9CC9C
+:108D50004EE21B1CD57FFE53F4C467C4382636FF91
+:108D6000954D541E23D1317E3687E38F8CBF0AE99F
+:108D70007736C7D3CF057F2A2005C09FE670BCDDBC
+:108D800064A67A34F2C35683866F3C130F726ACBA3
+:108D900080FABBBA5CC357AAF9B82BB9DE7E2B099F
+:108DA000A07E724AF2627A7A0BD3DB6B2C4750BFFB
+:108DB000E97984E9EDB5C48FFA8FD6BE59B3539DD6
+:108DC000AF6B53E7EBDBD5F99E1C0F8ED3B3A5AE8B
+:108DD00018EC8AD50FBF8B76EC6AC15FBC6AFE4285
+:108DE0001571C65F1EBA06ED51DF986F3C4D4F6F8F
+:108DF000C5AAB8D0DF029CFAEC352FB2F81437615F
+:108E000076821EEB88F9704E251A79A4E527799CA5
+:108E10009F08FB86E02F7984C9237A8E7DD7418213
+:108E20007C5CABD7F5C473BD979FD384FE9307FAE0
+:108E30000FD0D3350D48644139647FDB2487C89F48
+:108E4000798566C073BE99EE6780976CC971595475
+:108E5000F4F005CA9981CF7BEA720DBD88F3D62D57
+:108E60009C5E668127858EFF7BC981E7BAC3B732D6
+:108E70007A99635987F4FAD16A462FE2DC77E5E7FD
+:108E80003C87FC4DCE797D741241F55E9A1E4917E0
+:108E9000E77CE68FAF97181DD4557DF818E8CF8290
+:108EA0002F1C6E24F1FA103ED134CD64063B4A9358
+:108EB000819D83AAA67F5CBC3484CF38224A1313D9
+:108EC0004059EE8847FB6C5DA47A9C66A9F3BB7F92
+:108ED00080F3D24F23D14ED4FB304195A477EB7071
+:108EE0008CDB3E6B607E52319F550777EEF3C37E7D
+:108EF0005CFFEB083D959F3592F7C55A5AB6C4E41E
+:108F0000CA86716A743E23B36376A25F578C3BB006
+:108F10005DD683F2D5F81A93C3016910C6E1D2EF8A
+:108F2000D9A1FEB5D1898C4FDF11EB2A48880FCA31
+:108F30004B613FA45296A4C604FD26C1F8066637CD
+:108F4000F90B715C32BE6163887D9EB60F1B8F5634
+:108F500096C0F8F5F729CE61DE07A31DE5309FD353
+:108F6000DC8F7B9AFBFD4E47313FE0CCBEFA2C757F
+:108F7000F1F434F7139E8E51FB8744BDA509CC8EC6
+:108F800072B2D16CDEA807BF3A316F1C4649EC21A2
+:108F90005303C6932C6078EAD913BD6D5388FFA59F
+:108FA0002EA1F4FB309F7FD89C3743BABCF5B83173
+:108FB000D40EDF23B1F3770FA7979E08968A71EB43
+:108FC000122ABF0F78EC99E7473CF6E5C78ABC1335
+:108FD000FBEF99C0F86B5FFE3B2C4FB8DD43D8F533
+:108FE00007F2F769FD7B54D0B0734004B3CF6BFD3B
+:108FF000F30B053FE3FEF9059C1F2DEC607E8245D7
+:1090000066D29C4ACB177724B2736E94275BE59F98
+:10901000F7445E513C86A0CB9EF4CE3E7FF62321E2
+:10902000FEEC3AEECFAC13EBDBAD5EDF0309DFBA4B
+:109030003FFB818430FE6C6DDCC38BA0470C0BE2E0
+:1090400061AD8DC1AD42AE2D077B6FEF728271E8CD
+:109050006BDF5AD604F6E0B53F000B2AF231D4A7F5
+:10906000EB389C075A57BC534714959D7D105142CD
+:10907000E69FEC8A51E551430F89034DAD4E51B542
+:109080004F6F18AAAA3F64FD35AAF24C4FBE2A9F23
+:10909000D572ADAAFE55AD65AAFCF087AF57D5CF06
+:1090A000234307A3FDEC900CB62172B5B74A553E99
+:1090B00072E72DAAF69F9186CDE369BDDD42FE7968
+:1090C0001C9DA38A8371CE396D4B55ED9BA4B6626E
+:1090D0001FF0469FE49368BD151C5FCB3B99FF6270
+:1090E00074FB6A55FF67A3D83D18AD5F96762EA333
+:1090F0001ED62E9147A4FE7EDAEA8EFB9B21EEA8B7
+:10910000BFBF96F24DDA6E353DBF80FEA6D56F8E9D
+:1091100026703F5D0A496174ADA50B0BEA7FBD5B0C
+:1091200065B427E691EC87C623BC0CC4ABF4C75FDB
+:109130002F6176AEDEA7AD7688FF59F5D632A4470B
+:1091400053929A2E2214355D448E50D385D5AEA607
+:1091500083C1256A3AD0C23DDAA1A60BE2A7FF433C
+:10916000E02DE02AE01E3B554D375A78E79300DAB0
+:10917000D9DD5EC9EE2361FCE2EDDB705D97D21FA5
+:10918000F5896AF8161C703459106E2CBE4CE861D3
+:1091900026AEFF68FD1342AF894BE47A15EF47F81E
+:1091A000179A250FEA517DFEC2125F862F13F4A78E
+:1091B00006C2EC44CEA4C4F07646FC3E909D51C05D
+:1091C00075F620262F6B8803EDE12B880BF9DDC99E
+:1091D000CA5BD13EB4CAF263F4BB9EAD627A52352B
+:1091E000F1229FBFE2B802AA879210FBAB168E5203
+:1091F00087E4B302BFE1F22085740879E0C27813F6
+:109200004A86E662951F47ADE782DF30847F09BD5D
+:10921000578C27E029F89A18CF441AE424D8171A53
+:109220003E474668FD486A3B8DB0F3E06021FE2270
+:10923000AD5D26440F6E91E938F290CC2642F1578D
+:109240006073A0DDAF8874CE87EF25E6B626BDC279
+:10925000ED1357933EFBC480F2EA12FEE8591EC993
+:10926000FF68667F3FB4F06BD3E59FF8036D3C5E0B
+:109270005210EF552F0F8F077AEA6FA7B41F7D8525
+:10928000F623EB02B1A1F6C3BEFB06921FD7731300
+:1092900071DC4D42F41037699B3C3F13ECC4544ED3
+:1092A0004641CAEC58A45DAB07EBD18EACA32B01B1
+:1092B000BAAF21217EDACC6039E6E5FE7911377448
+:1092C000297DE242A28DC73FB07827C2F9A0385F5E
+:1092D0000E749E13711470CF16FC21224EA8399182
+:1092E0009F8373492EF44FF7DBA644B41FD0FD29AA
+:1092F00085EEC7BEB8222CEFB71F35EB177114B23D
+:10930000B510ED42CB42D77B19F0107ACB6FA83E57
+:1093100080F7341215A6D70D3AF681038A0B3B5518
+:10932000719EF5467A80017BC18B3C8EAF4DADAF0F
+:109330003F9BC8E393F839E752F01A181F3CEE4EF2
+:10934000E0E332F530117727E0F8427FB8EF51C102
+:10935000B5EFBCD807F73DE1E02EE072AEA8F329E7
+:10936000C0976C3D9200F0EE8872EE83FAE947FDFB
+:10937000A7245D705E157217C6CBF6B6CB783FCFCB
+:109380003D81C55BB9F7C8C81ABA3B4CE837AD6E2A
+:109390007F1DF5C2AE46CA68A91E76A6910EA9BF6A
+:1093A00088BD4003EF81CE47623D1F68D62FE2752E
+:1093B000E83A7F7F0938FC3E1C1C2AE45183E19E79
+:1093C000575F9C913E905115421FDA756CE6F4B0E0
+:1093D00056EF3C01FD1DEF4CDB0CFD55C81D07533E
+:1093E000003EEB24BC7F35D1C4EECB26F3FB7425C5
+:1093F000FE063BDC374E4AB3E0FDA9E1DF919DE07C
+:1094000017FE78DD6D31704F4CF43F5CD2E1FD4EBC
+:10941000429EFBE48E42F0572EB06FA2B98526160D
+:109420009791F9DD485F16E523AF1A8919F6A36114
+:109430006803DE6B0944CB68B78C93C924A03B3129
+:109440006F711F567C87FBFA70EF527C9FD81428EF
+:10945000584BD30E4E0F62DD13CB03050D9620FC47
+:10946000455CA6163E5B383CDCF1C666D017BBCD2A
+:10947000E2FCC95262D3239F596766FBE6D855E2E6
+:10948000FCEDB3C2B9D41DE1183C06F6DFFB32791E
+:1094900092267FB1390647E3FA15D4C7D7D958BB0E
+:1094A0006E1E07BFEEA3B244885F8E6F0A1F6FA6C1
+:1094B00024B1735C2DF7EF8BEFB57A1FC68DD542C3
+:1094C000BC7641F0FB95C66B8B78FC01E110AD27B3
+:1094D000FAD178EFDC79B17AAFFC4B0E7BBEBE3EA1
+:1094E0004927E20FD1EF4DCF5B61E30B4B93D8F9E6
+:1094F0002A1807E8C77BC37DF1857B4A13C945CE8F
+:10950000FBEEF30E55DC9F8837779F9F84717EFDBD
+:10951000FAA5FD2996605CE140F0DF92C8E6E58699
+:1095200078BF82D0EF0AFBDE374E1C8FDFF347C1D6
+:109530003EFD45BB8CF7EA7F714837757B9879D73C
+:109540002731B85D13AFC77D33D2471CDBC28C2FE8
+:10955000EA89FB35E29EAA767EBBCBFC8B60FE10CF
+:10956000471C6EBCA59C8EC4BC77C7307CB8F799ED
+:10957000F09E05ED17E3BD77C7F857E2BEB0A9F13D
+:109580007C3BB7D7ECBEDE9F81F7BCA6313BC34026
+:10959000F4E08D72FD04F5D89B69654A3FC5FA0673
+:1095A000C916B2FF2E450F41B8EB5478ED0F772363
+:1095B000E257F4FBF961BE4F89C302E7B7255CBEF1
+:1095C0002DD95183FAAF381F7DFEB08CF1179F1350
+:1095D000E627F9BC55C2F3CF521721EB291F5AF9E0
+:1095E00064413388B92549845C17C3BEDF09E94665
+:1095F000B59F7CF9BDFDEC872454AEAE200D2857F5
+:1096000056FE58DDAE9ADCFB67D09FB4FEFBE1DC72
+:109610002E27D6B139899E4740EF2926C5201FD66F
+:109620003EF985314A19781F9CA67C77981EF8AFC1
+:1096300019D3AE461BA6BF48723C9644F1B727C962
+:10964000B50DD29EF759FFBDB5BD4C7E6C8D43B9AB
+:10965000D564FD2EF2757908E3EBF7C03B09141EC3
+:109660002613D39712740D7214EA2D5EA487E3F1CA
+:109670006BAA6662DE9E04741FF7CB295331CEEFCE
+:1096800097910E80F7A652471ED8253655B27B9982
+:109690006613F3B37B7F31F63570830C6BBBBF0C65
+:1096A000CEC1B68EFD3EB0F7B4E8FE7C10E2575A4C
+:1096B000AE63F18B093AFFFED490F1E223BD49E09D
+:1096C000878F1F69C4388F38B934AF21245ECACD63
+:1096D00071D1DB9E8576C21E83B01BB645E0BDA866
+:1096E000DAA183818F5C43189E45DC1BCC2154DFBB
+:1096F000EDA27084A04B91BFA64DF219A2F0FD120D
+:10970000F4E3D4DEE54B980F72EAE77AF48389F943
+:10971000C5BD9A5C06FE2E219FE64B366647E3FAEE
+:10972000FC3C22FE317FD95C4E27F3B81E3F3F92AE
+:10973000C17B29B16740BB5BCC244A47B7D4FCF25C
+:10974000B6225C678D211AF405E1F71958CF086F2E
+:10975000FF723F6565F78DA54036747286C2E76279
+:10976000FB30C0F9B23B9BDDBB23C38803FC8CEE0E
+:109770007DC3B7817DC23488F9AF297F3297E4A3D6
+:109780005E6D8673D4ADAF44F0F8222FBF4FECC8A6
+:1097900083F89CFAAAB47C8C13391AC07737BA0DB7
+:1097A000FE0CDCC794EF4854360EDAF2FD197AB895
+:1097B000AF9942F5359A2FD9722FCB0FF5AFD4D18F
+:1097C000FC922D4FCDD0D3FDE1BEC67F0AF2355BB2
+:1097D00076B17CBE7FA54CF3CD5B5E65F5E160495B
+:1097E00009ECC12D07677868FF67A2B9BCB7FBF128
+:1097F0009EB5FBE5E1BA503B6B6332E35B67B89D16
+:10980000F84C26595C05F01E11BEFEB2641D0F5ABD
+:1098100069C554AC57B42749E1DB25F3716EE5F710
+:10982000A32746929608E6B7F344513C1CE8188EED
+:109830007EC7AF9362989E6EF3E3FB38A21F014F81
+:10984000D19F187735C867E0CB9A78ACEC64863F37
+:109850003ACE461C679883DD2BAE4ACB03FC51BC45
+:10986000E939DEF4ECFCBB8DCD8FF61B9D8B72A02D
+:1098700000ECF807BEA2F53383F3D6D24941329308
+:109880002FB736317F6B203A0BE96962247F67A5D9
+:1098900050BD8E660E87C6E4687E6F46C02B51C2EF
+:1098A000719A381CD3FC78CFF24AD75DF11F5A77F2
+:1098B00008BE1CF05ECA81F6ABB7B3F5C4F07BCD31
+:1098C000FE8C18D4F7EE57F5776683A67D09C1B8EC
+:1098D00036774C16B6BF278298F13BD9DED72E33A8
+:1098E00097E9ADA0CF8A772C88E73A12EA47EC7B5C
+:1098F000AFA28DC56706D739A390AFD3C6D769632A
+:10990000EBF4AAE8951C0964CCB6F6A7E33EF8F799
+:10991000F5372A9FF7A7DAE7E1FA837D3D105ED697
+:10992000733AF9D6F022E6A981671F9C35F313F04C
+:1099300084FD8DED46A9E952CCB326599C9335FBA5
+:109940003BF31B8E57CADAD5DDCEE2B989A2A6EB6E
+:10995000BADD993A882B10ED6AC127101FB4FF3D7C
+:109960009ACCED8969246D80F8C4C7938BC2DA0D57
+:10997000F1BBF69CD813CDE2D5B5F68A9E787B274D
+:10998000DCAFF49C63EF0A8CD3D86FC0CFF49C2576
+:10999000D82E285FD4F9739C3FF6B73F0532607E1E
+:1099A00085A6B2E7153BD547B61C437E5D38B8ECBB
+:1099B000B64C9A7F35F98FC8CF0B53CBBEC8A4FCE9
+:1099C0007C7FB29FE547967D3114F25BFCACFE4490
+:1099D000C7F3C0EF89C73F63527250AF782D59412A
+:1099E000B8C9E53A027464022586AEC7F4AA09E351
+:1099F000F6045C074A0B4DBA8670F76FDFEEA307DB
+:109A0000E65729813F15B0F3713B805FAFB203F495
+:109A100044B17BDF3D7BFF8EF75D3E487675021ECD
+:109A2000EA23BB1665D2FC5D919FA01F4F72D03D0B
+:109A300001F615C54616D0F94A5D9B9CA03F91D50D
+:109A400076B31EE1CAED5E748D1728FC5ED9F7F37C
+:109A5000EFA5B2619C308FB19C0FD4EFFBF26FE0A9
+:109A6000F7AD3F63B183F97A6CC796DB40FF1ADB31
+:109A7000F1F6974C0EB3FB3962DE63C1AE49BF9776
+:109A8000B49B70FE633BAE5E01F5C7FDB6230BE8E9
+:109A900064C2315F13B0859EBD2FA5AAEEE590CFBD
+:109AA0002E1AD739A0DF4DC0E353AA540D4678F4DF
+:109AB00032787C85F167DDF1879BFD68FC54DF7FA0
+:109AC000A2FA3AFA917BC9203BF833C47D7AADBD46
+:109AD000F468255D1FFD3E21406710A24F4F3C6F8B
+:109AE000A68C24982F25D1AA7CB9395955BFC29686
+:109AF000A92A9F9274B5AA7C9A92A7CA4F1F315681
+:109B000055FF067BA92A7F63C93455FD4A47A52A1C
+:109B10009FE76B53D52F38D4AE2E3F4264C043FE2F
+:109B200051FBEB90169D74A0D9B5F874C3EB908EE1
+:109B3000FD0B0387D65E7CEDF9B6D7E1BBB0176BA2
+:109B4000EF3309FBF1CDB2C56B0C6F274ED2670521
+:109B5000DF1F9075EC3ED318ABEBEA94A2E07DA634
+:109B600089602FA648A8587CEE47E3004F0B983D2C
+:109B7000ED282006E3BEAD68873C6A6878E60F2CC6
+:109B80000E201DF8DE84C05CD5BA279E77A9D65D6D
+:109B90004A6ED5E0698D2A5F61BB5D557F4AD2066A
+:109BA00055F934E5071A3CDDAFCADF60DFA2C1D347
+:109BB000360D9E7EAE2A17F4DDC1ED5AFBC01E4560
+:109BC000D3F1FECE72C0C375A703888F92CED67232
+:109BD000C0D3B547DB105F853E6739B0CBE2430D9C
+:109BE000AF43EAA3E73168F75A6312A6071A15B420
+:109BF0006B1D6C1C81E9A1463B7EFF756309A6EFD6
+:109C0000343A307DAF712AA69D8D4E4CDB1ADBB005
+:109C1000FE738DEDCC2E16DBF7DE453AD807BA750C
+:109C20007E377882173F927703F0CBEE41FE6EC805
+:109C3000DF45EC374CA2F925C044E8BEFC294F377C
+:109C4000A43A028057371CCA8A82F1186D3A471E1F
+:109C5000E8E177A44CF8A13E9D90BB3738936CD1D6
+:109C60002C6FA6794436C6B34DF8A18312D73320A2
+:109C70004AD0A933E106C8F744B07277CA841B40C2
+:109C80000FFFC6FE73473FFFF91D2961FCE7CF9C1C
+:109C900056AC60D739FCD5702BC0E330B76F39486C
+:109CA0009E61094D4BF5790690B34707B8B7F08030
+:109CB000AEB409E0D0A6B3CFC178EFEB0D04E8B79E
+:109CC0004A62E75F51CF95CAE441CF0D263C4F1D54
+:109CD000D13956605C9914780CE0BC3DA512E1DEE8
+:109CE000630D6400FCBC294E968F0F3C26D943F2CD
+:109CF00006069F07526EFCB6E1F35838F83C9162B5
+:109D000063FAB6CF910E7A80C81FA974D4C17E3E83
+:109D100052EAB80AEFCF384D6CFF3AADDEABD03E19
+:109D2000E4289A1362E719926A60F7D1E16222D8B7
+:109D30003B6F91719F6BE1392195E97B482770CE8C
+:109D40009C1789E782233AF69E81B6FE020ED7B3AE
+:109D500083C2DBE316A632BDA26C56DD332FD0FEE4
+:109D60007AD64560D73DCEE1A88FF53450E82A3445
+:109D70003DDD708E959BEC1C24E8BF9D0F7FD1F2DA
+:109D8000673A6EFBEBEF68FD4FD645DA5186D8AEE9
+:109D900041F8DDC22B2F8C35A3FEB4B02ABD0CE4F4
+:109DA000E27CEE075C64D527A03B501F6D8427172B
+:109DB000975BF29A2904C9CAB84A233C25559DB637
+:109DC000A619D2D5C3EE37C21329B5A37635831AA7
+:109DD0005B47B77011F23FFFBB8D745E8BD7CB0A28
+:109DE0003BCF89FBAE355714CF22E8F7088F3BA253
+:109DF00040C0F3EA220E6FD16E1187D78914AE3FAF
+:109E0000E6909C0B6A3FD66740EF5D0BDFCD1EC02E
+:109E1000CFA02EE7FAE3074636AEF6FD1231EEE2AA
+:109E20005476FE3A62A49409FAE42D4C0EE4CEFD79
+:109E3000E2AE22BAFEDC0E9B0EE31516D7BD00780B
+:109E4000E86DE778349076D84FB33C4B3EF91D224D
+:109E5000264E758FF752F2D2DE692B0F9597857ECD
+:109E60006779A8BC2C09B496835C14F251F84F7D35
+:109E70008DD59C2F37203F3DD0B81EF3071B3D9852
+:109E80001E6A6CE17CB915CBDF697C98F3652FE71E
+:109E9000CB3BF17B47E35C4CF735BA583ECA19958A
+:109EA0000AFBC4ECC2F8C437B69808F8E77A3B4C12
+:109EB000189F4177C4638FC641FC9109EF716AE333
+:109EC00090B47CBE8F1E76F77B372505C6E98B1FC5
+:109ED000027D71C8C0F474982856E04BF98FFEE4F7
+:109EE00006D0AF0F2B8A15F4E982D4CD2CEF50ACFD
+:109EF000069A2F7C94E75D8AD504AC22F521E45BB9
+:109F0000873D8A3582E68B1F7D88957B093AF3C7AA
+:109F10003DBAF5060FF059221D80FD516ECE9C44CE
+:109F2000C50595D7A507605F4C495A3209F6C5CEDD
+:109F30001405E9639AB2E100E4A78FD8A687ABFACB
+:109F40000E4BDE4668571657A9877693D2D66C8497
+:109F5000769387DDAF0F6D3775D4AE8D909F61DF3F
+:109F6000A607FD7427F0B1F8603F222FCA059F169F
+:109F70007172A33B9C280F72DB9D280F045CCA669C
+:109F800057DE0DF6CFFA76C926C13C664B7D410AF5
+:109F90001093E886F74929BFBE3EF597D60DB45D0C
+:109FA0003DE4AFC5FC0F377CBBFCFBA6D430FCFB0B
+:109FB00043BEDF41DE43DCFB8746F60ECC331C2E6E
+:109FC000F51D4BACF88E2A715941CF7A9ECBF39791
+:109FD00020A5E59FF1B48B7F7F40E770C138AB527D
+:109FE000B91FB23F7FA84965FB5F738F648072CE53
+:109FF0001FEA526DAAF73CEA08BBBF76A9383B6D51
+:10A000009CB836EE6435693BE8C8EC1F6F520BF71D
+:10A01000DCB2FAC77F8B786A6D1C78DFB96A10E30F
+:10A02000A77381D750BA6E491D904FDE7B0938DC8B
+:10A030001B0E0EFDD643589C7BBF38241EEFAE5D31
+:10A040001771C5B3778D79FCBB767D822EFAAFAFE1
+:10A0500095C15FCFE04FF5BBC7607E158BAD04ECBB
+:10A0600056A1FCE77717E13F5A7EF66DF1C99B17C1
+:10A07000D7E1BB6561F8D8F3E1F898B8CFAF4D856B
+:10A080009E0AF7F3201E12DE3982737E65A26B1FD3
+:10A09000F4D35316F89B0ECEA171ECDDF083D1AE54
+:10A0A000FDF05D32B2B80611977C5AE7F915E86DFC
+:10A0B000EF3DFA19F2B36E1016748FBC41F3A097FE
+:10A0C000FDC3E67C13E04746F88DA1EF8F0F147FA8
+:10A0D000FB1B2EFFFAA76CDF8938D49E6D5F66A04C
+:10A0E000FDEE12FB62207854C8E3FD703FA4B72454
+:10A0F00012E56797447CF0DE71576902EA2D5DE94D
+:10A10000463DA4DFF6B9B82B3D1BFBD79E8FBB9213
+:10A110004BCC6CDCC953217D2FF95421C8BDDFF035
+:10A12000F8CB76A3A7E03DB00F8F8D40FFFE8D9258
+:10A13000BF10E0A03D5777BDB5A04CC9ED7FBEA6CE
+:10A14000EB9B04EBAB3DAEBB1BBE5DE979BB76FD83
+:10A15000DF08C4B98F5BFF1581F7EFAEFCFCDD199A
+:10A1600093AB805EE16A021219D345F5099ABF5498
+:10A17000FCD639899ED33343CEE5256FB3382E9E66
+:10A180006ACFE7FDDE095CED51C70D96FA8A305EB5
+:10A1900045F647E1BD601D7B6F43C473BDC9CFF376
+:10A1A000F4BC3E240DED709D19AAF3FA1D1F2DFA83
+:10A1B0001EF281088CEF78A6FD443CCCF58F9DF112
+:10A1C0003F794509D277BDED6F24F49DC0DAF5BD26
+:10A1D000AA7CD786E0FB56701FABF65F32CA252AF1
+:10A1E000C75A104FE435E3DA10F94ADAFEDC07EF1C
+:10A1F000D194DF5502C050BE36CF74D07695FC3C6A
+:10A200004448E48D0EDAAE929F1F8967252B8FE7B5
+:10A21000F53D9FB07CBA28FFE34CAC7F95E86F1CFE
+:10A220002B4F1679DEDFD5229F782396678AF62595
+:10A230002C9F23C6AF64EDADACFEE4ADFF9C097A64
+:10A240008DE0F733D2B89CE0EF5251FEEF4C2BBAC1
+:10A2500068BC8EBA9CCB07F10E55C51DD322DF8595
+:10A260007DDC2661EC61ED9D06B4E79F8D69CB0D29
+:10A27000BD2F2FE27A9CE5568CF3AA7B71F8769974
+:10A28000C73B811EB39CFBE92B640BFA617AEF6537
+:10A290007C7E203D70E5FA9755F8EC57CEDFD3462B
+:10A2A00047251DEFDC0F13F17E0219D689F102EE6E
+:10A2B0003449C427E0BD6A11571797451C707E8E3C
+:10A2C0007B2982BDA77AB213F9EFCA97987DBB6E3E
+:10A2D000CBEB28EF96CA0ADA97BE1EEA5A07F0E9D6
+:10A2E000B6B2772F57AEDF87FBF431C5C6FD60816C
+:10A2F00051A1F0BCB33FFC3D69F11785BFBAFC3FEB
+:10A300000C7FAD5D5DDCD75F7D85F17FDD56E607B7
+:10A31000B6733CFD49A71473783D02F03AB7A233F7
+:10A320003B5A8620EE4E8C77AB90DF2982F3566F36
+:10A33000839500DEBBA5CEDC0FC3E05F7BAE389F0C
+:10A34000415471693BFBC3F7E94BD0F7D3FF4DFA9A
+:10A350004ED4FB8D76F01B1F65EFE51577FEC9180F
+:10A360001A1FF44E1A3B070F6E677E311117172C18
+:10A37000B7323C71FF535DD53BE3C1FF24F6C3C444
+:10A3800048D206FE044AD7764ED776A06B41BF412D
+:10A390003F146D1706BE41FA252C2E91C3E9B7FD77
+:10A3A000E1FAE125E0FAE17F13AEBBA93E8CFEDBCA
+:10A3B0001722D04EA385F33F385C05BC23D32F0E64
+:10A3C000E7C8F4FF0C9C23D315959D43C07B20F96F
+:10A3D000A4C58F9877987D5AF44DF6E923199C4FC0
+:10A3E000E9FD188FABC57B4C7A3FBC27A45F1CEFFF
+:10A3F000EAF2FF30DEB570D3A6B5DC9FABFD5E9808
+:10A400003E20BFFB56E0F87FCD4FB0B061BFAA7CC5
+:10A41000F1FAB754E54B3CEF5F965F41D8FBFF5B29
+:10A42000FE05E15798F9FC2A1DF81FB5F24137C423
+:10A43000F923A0C71B5FFE7AD48730F9EA6C8CB78A
+:10A44000BA8DAFE58BF17FFFE47B94BEBE6860F60A
+:10A45000D663FB3F372839FDE965E1791D7184D06A
+:10A46000D9C2F5EF1B40CF5A48D8FB54DAFA0FA6F1
+:10A47000337B30C64951BE30D74C0C71941FCC9DF4
+:10A48000CBEE4BCF0507630CA63E172D9FA9273EA9
+:10A49000788FBBD2A2F799D0EFA9BEFF6EE2EF751D
+:10A4A00093B858D53D78D921639CDF9C12E62FBD27
+:10A4B000C5D286F787E71DBAEBDCF7602F6FF4147F
+:10A4C000B1B87771FFF0F7BA2BF1833E087A2A9C76
+:10A4D000FB24EE5F5F6340FFBAB6DD2ABE9F66CA0B
+:10A4E000128BA3D9C3E233C5FEA4EB3B64CA67F762
+:10A4F00060E0F7482A1B0CBEE1B9A067EF473DBBFF
+:10A50000BE64432EE0AF7E9274DC941B3CEFD4AF6C
+:10A51000FF0BB6D7F2676D7AB9F6D54F1A0F21BD8A
+:10A520008873D1B1461FE6B5F6D60513FF17FD9324
+:10A5300063FFE26D8274DC578E0FC7D075FB1B3B47
+:10A54000FF2D7B82B02308BB82D64E21F88878BFCE
+:10A55000D2976EE3EFB296A2DF83E8592AF8EDC1F5
+:10A56000FEFCF9D7E917D727D5E5FF61FE7CB9F4E2
+:10A570005F9BC4E4AA96EE8F56FD0CEDCF82BEB56C
+:10A58000F4BF006252E8F80BEA25BC273E7755ABD2
+:10A59000619CF4CDE97DB5E56406839B462E5CB1F4
+:10A5A0003C50783C878CE70B93BCC60E760F8187B6
+:10A5B000AFD3D5EF0353BC48191797ABEAF2FFFAB4
+:10A5C00039E0E4A26F2617894A9F48CBE8B76EE5C9
+:10A5D00012EB56FE9BEB0EB9A7B448D605EFE3404D
+:10A5E000FC35C481F678D9FDD4EACC56FCDD0352A3
+:10A5F0001288027E77EB5E99FD9E8EDEA14F0E796A
+:10A600003FAD8BF83E007A5C359EBD3BA48D9B76BA
+:10A61000F378EAD596DD78BF51FB0E9A88CB76F3B6
+:10A62000FEB4EFA189F6E29D03ED7B685332781CFE
+:10A63000763EC967712917E7A3DD20CF43FC35DDDE
+:10A640005F35A25DE1C6C74AEEF3A405F13227A348
+:10A650001FDF99977171BEA32EFF2FD3AF6CDD81E1
+:10A66000F7D8AE947E47643ADC407F822FF7F19BA7
+:10A67000574CC86FC43BF33D6B9EC1F7877ABE242D
+:10A68000E897BDD43BE313BBD835C40927BD4D566D
+:10A690008AD771C73C68AF1B7BC485F776C7BCE31C
+:10A6A00080887F9277C029C3BC853E23F49B20FF1E
+:10A6B000E2F7D9789CD5E5F2B92BF537FEA7FC8CEB
+:10A6C000E25E5DB7C15704BFE7E0D91381BF03A1C4
+:10A6D0009DFF9319BA8BBE93DC11E57A12F0348B8F
+:10A6E000CB09F15E7285CCDE49EFED94D15EB8EE18
+:10A6F0007F7EFBAB47954BDB15EA6DBD61CF6522D5
+:10A70000ADD7B17B2DF9E50AC649C2790DEC87C2F8
+:10A710009EA8AD7F4A297B2903ED5BE3F13DDADE9C
+:10A7200087D97C06C257FDFA008E3F60391FBF7E75
+:10A730006F912DF49D95F3197DE743DB297310DFAD
+:10A74000974B17FFD7CE2D3365E291A87CCD91BCF6
+:10A750004CEF254CFF5D403A315D440298BA08BB8E
+:10A76000CFB094D8315D4E9C98AE555C5D191837CA
+:10A770001448C0F8D317FF390AE8E6DC75E35A211C
+:10A7800046F1DBF22369F5BE9E3C85BD97F4C23FDE
+:10A790007F07F4D9F33F86CBE21B47A21C6448181D
+:10A7A0003FD37BA532BBD754F25DDC17E2FD5D32AF
+:10A7B00089F9E1962766E2FE09F2CDC46D826F82C7
+:10A7C0003F39E7B88EC5C3DC2AE17BC6ED7E1D6E3E
+:10A7D000B19C15995EF8DDB9F6DDAC3CA72EDA2BFD
+:10A7E000D17CCED80856BE26DA0BF74F16123FEEB4
+:10A7F000CBC570FB4486FB4B8C2F8ADF0BA02782D6
+:10A80000A1126DBFA2C3CCEE5110FF30E0FFB970B2
+:10A810007E0A174F3384F1F1D14319BF1F5DA6B6ED
+:10A82000870CE5E5F72965DF0778B40C71640D81C5
+:10A83000FA319D9B1E2C043B908E809FE6B3B1B7EE
+:10A84000A35F53B47B51291B01F59F9558BCBF678B
+:10A850002FBF6F4C0209A1FEB1B54A792ED42B1A35
+:10A86000C2F8D3407085DF517486392F8AF8D1D170
+:10A87000706643BB3CC177D29E95587EF2E35B6F16
+:10A88000DC68415F8207F4E31715D744186FB49171
+:10A89000100BCCFFA7FC7E1B69C800BBE8AAC74C05
+:10A8A0003AD02F3EA2E218EEF7FC819EB721FD9828
+:10A8B0009E9B21FD233D37437A9C9E9B213D41CFAA
+:10A8C000CD90AE386F87C7CCC989218EB9D0BFF083
+:10A8D000F769E75B3984F1D7BEF1F71A71FCFB1415
+:10A8E00017C2B70FDF7B08FEDEEDB3D18194988BE2
+:10A8F000D05BCFDEBFA39F7420B808FFA3B67C0A4D
+:10A90000C76BEE6E3DCAFFDC767FD4CA907A2B8788
+:10A9100018B17DCE0B27A3A0FF6E5B1F7C1D125DBF
+:10A92000F24C1DCBAF7CFCB91B378E82F93BBE0FBE
+:10A930007441F7F96A4873DB7FFB00FC5E2AED1F68
+:10A94000E3247AA4C0663C2F68D6A1858358D7B388
+:10A95000D19D9BA0FDB32F0C859550BE43D8BE0161
+:10A960003A92C2AD7703AEE74653A010EE0BDD7806
+:10A97000410E1BA77D9F528A704E067A43FEDDCAA8
+:10A9800053465F026FDF747F6BFB23E2FD15E0A58A
+:10A990000AC8A5AFA2402FACE4F104EDBB87FD06C9
+:10A9A000D6E9392413F8BDDAD131EAFDB78BE34992
+:10A9B000A4397B8D4EC0D7B37B4F0D83F789297E99
+:10A9C00086C17BC5DB865C45427FEF3167EC978FA4
+:10A9D0003C1887F5F1F769E7916D15103733DFBC47
+:10A9E000FF0D58D242DBF10A889B599C241D8474C8
+:10A9F00089923919E265C47D8365234A0FC2969A0C
+:10AA000061AF447DAE14984C887C283747F247D814
+:10AA1000853C8A55E5A724A5AAEA4F53B254E5D34D
+:10AA2000478C54958B7167D80B54F546C70486C282
+:10AA3000798EAE83BD03FFA48CF186392F1CB97EBD
+:10AA400024CDCF7C6A0EBE43F92C2F9FF95CB91739
+:10AA5000F0D143E169A40AD5E9921F6C7E103AD384
+:10AA60009C176AF73E71D0A15CC679E112E7848138
+:10AA7000DE4F16EDB5E704CA371F00BE39FAC5D957
+:10AA800036F0DB3E3BF6CB148847FDCD10FEAE0C16
+:10AA90003F3F0C44377DFB435218DDBC259327C351
+:10AAA000D00D44F2323A64E9CCC3EC7EDE95F2B5C7
+:10AAB0004F81AFA1BDC043427F7F576BDF1B6DB499
+:10AAC000FFE636B047BD2BC30DA5BE7B932BE16FD0
+:10AAD0003948EF64F9B6BB93E3F0BB07F46137B7CD
+:10AAE000F70D52B83E55BBFFEEE4C2603959775CB2
+:10AAF000559FDC2935ABF21B33D5F97B4B9B43DBF0
+:10AB00000FA48FAD7C7889D19503F76EA5B0BF37C0
+:10AB10002CE6F3FF010980D5200080000000000032
+:10AB20001F8B08000000000000FFB5190B5454658E
+:10AB3000FABBF7CE0B1960782810427798440A8444
+:10AB4000895728B08DA01ED7DA1A4C8F545693E53A
+:10AB500003794DE0B6F4D8E318AD8FB6076D5B69A5
+:10AB60006B355696E7E439B144462536AE5B49EB82
+:10AB7000D654A266E499D8424C70267A6D9D5AF755
+:10AB8000FBFEFF5E672E605B9DD64EE79FEFFFFFEB
+:10AB9000FB7FEF279014CA70CE0008F6ACCC7099FA
+:10ABA0000106F7D61AE41880D3F4EFE2F0DAB8F928
+:10ABB0007A8303CF5700383ACCE3CF01D601140390
+:10ABC0005C29817BA2F3145960E760FF65F1BD2F1A
+:10ABD000010849009E178DDEED5684E35C06676E22
+:10ABE000F89E8DF04E0618D972FFEFBF2AC2F525E8
+:10ABF000B0E30E8CC4430DBD9BD7755C1471CD9F23
+:10AC000004D7D17779968098806B7055B407E200AD
+:10AC10009A6A633C623E9E67860E992E04C8F1A62E
+:10AC2000B59B52018E8A22C039440778A014EFE305
+:10AC30001B045F24A739EFA4DFB9C867CC2FC7E78F
+:10AC40004532B035BF3294E9C67BD77E87E71CBF5B
+:10AC500003A291CE3F804A8F034C5C2E04BBBD19EA
+:10AC6000FE3F233F4DBD1218909F61F01DBA5A6000
+:10AC7000D7CCA925002BE9A74CFB1D0690D86F194E
+:10AC8000707F95B2BFB27CE5A5108BF056FD4020D9
+:10AC90009BBD0FA7F1FFD57F6F3798F17CF553DA95
+:10ACA0007D420F53902FE5FB3AF0B377EB77E23D0F
+:10ACB00053F85E23DCFD9984EF367669BF5F24C7C5
+:10ACC000240DE6E08F0228382DB16D91DE6B36F150
+:10ACD000F7E64ADFBD7B09EAB1E925C96EC4ADD10B
+:10ACE000DDD3E200F98339A8E4D4F1F26BDA8C7A8F
+:10ACF0002A0CC3A7764BF3BD745F17CAA89E315EBA
+:10AD0000CE60C9E2F82C1C5F73C5D70B01F135F793
+:10AD1000E8D0D07E00CF4611E4083CCFED31AEF252
+:10AD20009AC3F4072D9CC7FC9E2F1366E7F2751D8E
+:10AD3000D101ED1C2F70BF9821803E09F141B56013
+:10AD4000DF8E4B5F4F7225C9BF4F009F5CC09E587E
+:10AD50006442FD5CC19FA37D3324E08F946C1DE1B0
+:10AD600059A8C8FD8AD27F7C23E0778B7B164F439E
+:10AD70000AE050D7B23ED40C6C906D0CDF12F0E8B4
+:10AD8000492F7DF1CEF416A4F3324960F6DF171F88
+:10AD90001A16107F5F45B4D026B0F7EFA4F755BE62
+:10ADA000FAF4CE7437E36B8E6510F526382E904E8C
+:10ADB000478F974758AE3A1854F52B7177217F9CEF
+:10ADC0002BDD3EFB12F4DBD1A5603122BD974B6831
+:10ADD0003808C3ABDC8FAB49D63351AE823F81E834
+:10ADE0006C96176E91F1BBE4D67B41971821371D05
+:10ADF000F733552FAA1CC7D3A1E22DF73B90BFD143
+:10AE00001D02B39F46BBCCECB3B1FCE4834B107F77
+:10AE1000A35FB20B48CFB2EEBD47487E1D6B3B40EF
+:10AE2000771E40E7DA6EB62E33997D521EE38BD93A
+:10AE3000AD8846417CAD5660C6A7357C1EE67B0CCE
+:10AE4000BC513F7C06CE043818EB7C9EF85BF3FBCC
+:10AE5000CFFB9610B51BCAE3991F90AD9D1BA63F73
+:10AE6000DF006046FA43DBA3BD4F303C68AF25618D
+:10AE70007B3DB127EB700B9E9F7853CFCC755FC5A0
+:10AE8000C3A76E4178CDF66826E71309E049A5F31C
+:10AE900027A67B3D7861A518EA6F21B977C6D8B798
+:10AEA000E3F9F147A73FBB13E1DA67A7D9894CF271
+:10AEB0001F19E57D3C1D01DA7F3E957D07291CEFBA
+:10AEC0000AC52FA56766DC574EE7CF24DA098FAA9B
+:10AED000BFA147A31C80F2FA127C791634BD93827D
+:10AEE0006750C487EBC49DC704B4CBDB0CAE83C4EE
+:10AEF000F7EA47FE7AA80CF9A97AE6370FCF44FAA9
+:10AF00006ADF9B0CF44E58AFE3E2406C2097FCDF05
+:10AF1000C6FD5F914FDD8E28CBC71171A6A1235EC0
+:10AF2000033775A75A3E8E883775C0650CF5828E3B
+:10AF3000F8A957FCAA5E741D25BA1A20C0E3228422
+:10AF40000C64570592E0A07810BAC7C8E43FD6CE8B
+:10AF5000466591D1512F828BE27941229852C86F78
+:10AF60005D5C7EC17BA63F7117CA66923541F5FBD9
+:10AF7000AC853322EDB3BFF115B2CFCD46669FC38A
+:10AF8000513C2F8DC5F31F399E7DBFC2F405F38759
+:10AF900033F9A4F5DF5A38171C14EF0ADAE4C29B20
+:10AFA000706D51F4722CC5295849EE1DF7EF3AC067
+:10AFB000E4B9F5E6A38477BF99E90F0E70B90705E8
+:10AFC0009E27D5F7569842A02B247AB7317AD5FD23
+:10AFD000C12D87F35CF8FEE00B397980F6BC4CF2AA
+:10AFE0000FFE05E5732AC67FEC365C3BF7BF3B8559
+:10AFF000F2E0587AEB5B47D97B2A3C2CF038544F6F
+:10B000007CE0FEF799CE64A213C3088B0F0377CDC3
+:10B0100060F29B2BE5C691FE8327B4F48DA5537D8A
+:10B020005FA54F7D5FBD37CD2A32398E18FC7994EC
+:10B03000F75FCC90357C8DC4FAF3E2CDB46FE17547
+:10B040004402C211F656433F51BF35268CDB485FA0
+:10B050004D8D606F03B6EFA1B889ABCF85E7F529B9
+:10B060002F2B7203A709ED78B162679094C8EC6E3C
+:10B070001170BB5EACC4EDABA0430FE82F47C475A5
+:10B08000BF35A0FD0D773CA07745C65DCF51F1746B
+:10B09000CE4F8FBB9E4AC8A6F83D6231B3BA669EBA
+:10B0A00055D0B17BE9904EF7F0DCEE433BF0741ADB
+:10B0B000ED6D48CFE3A2738115E5536FF0E5911F65
+:10B0C000A8DF3D2EBAD8FEB0706005E91B74BE3C07
+:10B0D00056EFC41B40C03A2338D9EE77505DF625B1
+:10B0E000B0B812D4434D27E22DAA12DD9DE6703C84
+:10B0F00054E367510EEEA35C2B685FF557B49BA237
+:10B100007CEDFD303F5AF8B895FB5D51A2E8EE9812
+:10B11000C05F6E57F4DC061D12F7679E47CB14B96B
+:10B1200063DD2245D62D8D4A9C0FC69A3C12F25300
+:10B13000B61BF5827099CEB797568C02D08AFA9DCD
+:10B14000053EFE5EB7369E530E59CAF2720ECBCB49
+:10B15000B31475AF17DC407A3551FEC2F52EC12FFE
+:10B16000D1FA2B08B1D501161DADA806B6CE012720
+:10B170005BE7819BADF3A19DAD0BA083AD97829F53
+:10B18000AD7081AF0D583EB8DD3288F9187EBD52E2
+:10B19000A4BC5CB464E27AFC71455E67970746F92B
+:10B1A000929F2F8F79E04A61749D4D2E53B399DDA4
+:10B1B000AB7231927DE27751E04DA1B50202EC9D78
+:10B1C0008BC990F19DD920EB08AE020783E7FE48BA
+:10B1D0007994065C3A57EE0472A99AD84E7628768E
+:10B1E000524C365D1CD6D787561E1754BD01D24926
+:10B1F000F960BC3E2183E82C8AAEFC5CC690F1DA93
+:10B20000B6F79D3A8CA34585952D36840F593FE5B9
+:10B210007059E5F399081FD976D2A99B49765E59F2
+:10B22000A8B76315BA6ED83907CF4D18FCA3504E96
+:10B23000924D82525C5D51B179807E6794ACEB7423
+:10B24000E857C6DB80C5195714809FD5B36865E4FD
+:10B250002735BC7E5D63E17ADB6B70BD4A7EDA60C8
+:10B26000F2C5CAC8D39A757393295F6E30F0F73F61
+:10B270009A2CE7BC827232223E5341984F3CF744ED
+:10B28000211C10E496566B18FF8FC0F7CF1FC277B2
+:10B290006B8AEB5D16CF4D5940FA4F53F2796767D1
+:10B2A000598A5D24FC16863F1093D5D28A470752EF
+:10B2B0009C1FD27BC1186E771F5AB95ECEB69A32E8
+:10B2C0001D1F5827D80FAEFB7A978FE2D02748086A
+:10B2D000BEF399D53540743489818C42D4D71DD1C1
+:10B2E000C70C6427AA1D0BA8BCA5C87F9B03BC067E
+:10B2F000E61FE59633F5982DEC07C1E5F81ECAA5C3
+:10B30000C8E9ACD2E371498D7B1FADA5AEF62A3CEE
+:10B31000213C41A2A7490AAD20BB3815FF9EE1138D
+:10B32000E6A753B93D2AF1AB674FEF6D691C744234
+:10B33000841F36EDF9E6AB0F50DF4DA3663B5D0F82
+:10B34000FBDF9616EA0BB01AD4C417D52F67751B0E
+:10B350007DD45F95ED3E7F39DDAB78AFDF4671FA86
+:10B36000E2FE401B95CBC19EC369DC2FD43AFE6B35
+:10B37000E1E7E493B9120575ACCB5E90BC46E4AB53
+:10B3800099EA0B05F6207CDC84761347F779BFA990
+:10B39000F6950DBDAF19A82FC1673CC46FAD42FF34
+:10B3A000AAAD375C4AF562AD57DB2FD6F57BD713D4
+:10B3B000DD753BB4FB6ABFD9A47C5F4FF59A8DEA7B
+:10B3C0003EEDBD26EA37F3A8FED3EE67662AFDA65A
+:10B3D00092FF40A933572A77883F33EBFF0C5E2357
+:10B3E000F2D6FC688BDD4270BAD9CEE26DFD0666FE
+:10B3F000C7EA7DD89AC86C44F5DBDA8DC0EA675598
+:10B400008EF94F1B1DA48FFCA793595D8CF53CABA7
+:10B4100047309EF0FE1E6522A0DD3D171FCA1411A5
+:10B42000CF733DD976AAB75F5EEB807F9D17A64F9D
+:10B43000ADF7E74A3BAB0CD447DD887D146E35F79A
+:10B440003ED96642B87913D00D242D3B8EEAA6E290
+:10B45000FD1278E91DF03E508E6B971A4F52B0BE28
+:10B460008F9047943C09E409FA79A3A2B7E8EC0469
+:10B47000CD798CFD1CCDF771A599DAEF3D0E7F6E6D
+:10B4800009C573FE7DBCE302CDFD36C16DF791CDDC
+:10B4900004F03FBC57AE88B1C2BF82CD1D12E71782
+:10B4A00068EE6F889DB79FECBBFC0BDD183B704BC3
+:10B4B000647765018047502FB386B5E7C507DB2168
+:10B4C00016F1471DD48D99577880EA16A3ACDD5F3D
+:10B4D000AEDAC55498AA99439C913BB7FBD1219110
+:10B4E000D945099CF7707911C9590F5E79BCDC46C2
+:10B4F00069A5FB6603F38B59BD2D768A47939D5A48
+:10B50000F927D768E59FEAD2CA3B6D9556DEE96E0A
+:10B51000ADBCCF6DD5CAD7EAD1CACFB67196E6FE1B
+:10B52000B4F64A0D3C7DF302CDFDF3BD0B3570CE74
+:10B530008EAB34F767742CD39CE777AFD69CAB7691
+:10B5400036D60E2EF4358FB13311C408FDAB7A56C2
+:10B55000EDA070FFAD1A3CFF6FFD6F1FA3FFA7C8E2
+:10B56000D731DEBD153B7437B9EB65D13CAE9D9943
+:10B570002794EB59BFF6B69C5815437795FCE654D3
+:10B58000F21B94FF91C3160EDBFDF67D14CF0A8EDD
+:10B5900038AB88AEA2807B1F85F392A1F6AA38BA99
+:10B5A000EF00D932858F9CE8FEE5A502E8347E8560
+:10B5B000F094B03CAFF0AC93E2F072D977DE36167F
+:10B5C0006EC9E94BC2F320A194E7856A4714E822CB
+:10B5D000E452A1EC0325E92961F9ABF323EC07C0A0
+:10B5E00040FD8068F2B65927AA77EC9B25568FB9A3
+:10B5F000587DF686E06273A545267F06C5F7DF25F0
+:10B60000BBDECEC4B8764AB4CBAC9E13026DC45434
+:10B610009018A3A4E5A9AF76501F87ED2CCD2BFF82
+:10B6200074476DB52797916F0994F0B699FEF56749
+:10B63000BA8E64A2FC0704CBFA42FCF6AD5927335C
+:10B64000287F1925944401CD4F1C47E9FCCCDC240C
+:10B6500019F9C3781B10650F89C273ABC0FA9093B8
+:10B66000F4D8CC08FFDDA867790B94BEEC1A455ED0
+:10B670006A5FB654C13F804FACC2787E4DF71B4C19
+:10B680002E7529C3CA1CCA6DB7E0FB374C3517505D
+:10B690005F0A8E423BEFE7D53E2D4DFA297955EDF5
+:10B6A0006BCF76BF2E6548D32FC3CEC409E7916315
+:10B6B000E75E61BEF9FB039BA2591E1AD894CEE641
+:10B6C0008BE1F74FB1F7AF71BFA3B193EB5ADFD75F
+:10B6D000D8DFF59E8F34E781A4903E0DF90FEC4A38
+:10B6E0009D7735CA6FE4056309F5ABA8B7385B7180
+:10B6F000F8FDC03DD3E710BEFFCDE7A74CBEFD6B04
+:10B70000FD6CEEA6F2796CED110607D606D83A96D6
+:10B710004FB5BF5557C3DF209BEAE59030C93ED1F6
+:10B72000BCE6311BEF83FA674FA9A47CDC9F6ED087
+:10B73000F1358BC3A9A5260ECF9B4F6B506FDE480A
+:10B74000FD6DBF000E01ED61A9E07CEC7AE4BB3A2F
+:10B75000D9956BA37A7275284F87FED0941FB8567F
+:10B76000407DBE1EEFCA27FE052C065313189D59B7
+:10B77000D4370C899E3C0163C14D4F765753FD3F32
+:10B7800034C9738A3276ADADAB9AFA832103F78F51
+:10B790005B9E7C84F9C3B716D74C7AE71341F2312C
+:10B7A0007B7E49F06E67F616302C8CF8BB823AAF80
+:10B7B000A17E9BFA9B60145F67DBF8DF5F2AC7AC52
+:10B7C0004B6D3CAEDD426B31E9E5EE2CFA7BCAE80D
+:10B7D0006623905F203E8748F87AF85C760AF2404C
+:10B7E000750D566FAC5F2878D5E8A3F8A1CE751615
+:10B7F000DBACECBD241B9FD724DD67F4B6B1FCEEB7
+:10B80000CFA8463ADBF558EF50DF7010D81C6D8496
+:10B81000E661117A596CE3FD17DC08C0CF93B7D10C
+:10B820007943EFC0318A27DF67BAAE24390C8872BA
+:10B8300009C59386D8BDACDE6BB6C9EC3BA497F1C5
+:10B840008F71E14ED2CF2F380F5C45FA6D300578FD
+:10B85000DDAACC03CF26B791E5FE8772D9FCCB9E3B
+:10B8600041F4A9F422FDCDB688B99D4A7FF89D1F09
+:10B87000F60B75AEA5C2835B3664919FA15EF8BCE2
+:10B880005112AE5B38C1F70F2AFA3E96E2F410FE71
+:10B89000D56E3EF70BDB4DFBCD4749CFBD66162776
+:10B8A000CFF6FD583E1BF6F43279209FD7127F1158
+:10B8B0007CDE1BC9E748CFE18772E59FCF5F309DF3
+:10B8C000FF1D29B8ED9B0C19BF6FD8FDC611B2BB87
+:10B8D00006751EDFA59D33182761FF9A30D11C1D08
+:10B8E000B34F445D6654BF9FAAD37E8F0539CDA95F
+:10B8F000BBC9DFA97E71F0BF8BA9F9B84BE96B8496
+:10B90000C0EB2C1F103EF287F58287E545758ED17E
+:10B910002660DE23DDBA5A589E90CE35DBC99EBB29
+:10B92000D006FDE4073A47349B5F8FE9A3BF35B8E3
+:10B930007691FCD6BC53994C7D76E79B0B947E8D1B
+:10B94000E7A962C52E8B093FD19F1BC7ECB548A163
+:10B95000AFC484F55026857C8FC4E715CAFC63D339
+:10B96000EB9A3EEFBF32596853001E000000000002
+:10B9700000000000000000001F8B08000000000015
+:10B9800000FFFB51CFC0F0038AC515191844D41924
+:10B99000184C341818566820C46989B5B829D39F43
+:10B9A000C9C2C0900DC4B9409C0FC47C4C0C0CFCA7
+:10B9B0004CC4EB171445B0F50419188480FC6F02D1
+:10B9C0000C0CD7851818BE8B30300803F92E40F1C7
+:10B9D0000420CE01626FA0580B905E04C4DD402CA1
+:10B9E000228ADF7C5102F26B8551F937D1F87B84D2
+:10B9F000F0EB5710C12FAF47401E1B16D1223F3E20
+:10BA00002229D03B10585F01955F26C7C0D0270F71
+:10BA10008C7FA8B80192FC4B20BB5C0EC2F69660EE
+:10BA2000602806F20D15B09BEB03942F01CA7D85AB
+:10BA3000CA0300CCCCBA8C680300000000000000F0
+:10BA40001F8B08000000000000FFE57D0B78144507
+:10BA5000B670F574F7CC2499994C12F2E03D490088
+:10BA600011030E2144C0709924C0A2460D021A147D
+:10BA7000750292849097887EECAEFE330189A0A86F
+:10BA8000F1B9AC17DD416137B2E8060C1835E0605A
+:10BA900000B32EBAC145C0E72680BC362443F0B9B6
+:10BAA000CB5E6F9D53D533DD9D09C4C7DE7FEFFFAD
+:10BAB0008F9F5FA5BAAAEB71DEE7D4E942328F27E8
+:10BAC000640A21DFC18F969F8B8490F850596F20B4
+:10BAD0002E924188D766F46D4CA6CF88237AE6680B
+:10BAE0005A981DD1375843EFE9CBD59EA434691835
+:10BAF000210F791C5812E223844EB55A2005F51601
+:10BB0000A83B93E07D3A3E21FDE8F80F46E2F8308D
+:10BB10002D99181A671031E07B53ADF989B01E4298
+:10BB20006A47E6C3FC163B21FD7B9F9F8E88EBA7EF
+:10BB3000EF0DC1F724FA9EB5EFEF2965570EFD13FF
+:10BB4000F6DF6DF66D1408F1EFFCC77158EF9986BA
+:10BB5000390E135D6F76B7D93F05EABE6C9F89B683
+:10BB6000E76EFBC026D1FEE5DB4409DA0D3B23F08E
+:10BB7000FDCE75820FEA95A6D647AEA4F5C03691E4
+:10BB80003C0FD3F82D069240C87133613F8715EB07
+:10BB90004511AC5ABE7ED76D305F49A38944D0F7BA
+:10BBA0008F37882EA82FD928F8089DAFFCB5078CB1
+:10BBB00003E878C53EA13EC241EB1B1F333AE83E85
+:10BBC00097EFFCD8D646E17CDA63260E23EEA3A4D9
+:10BBD0003E8D9052DF96E903E8FBA59B052780BECA
+:10BBE00074DDD94E585F69833C5CA4E32DAE8B2293
+:10BBF0008E916CEEEF08CCD77C14E7DB260F83F92F
+:10BC00004ACEDF650424E56E93912ECAE93A60DFDF
+:10BC1000CABCA73D6B713E059EE52FD2F968BF8A6D
+:10BC20009705276CB1C240DCB08ECED7220A5EB039
+:10BC3000C0FEAA8D23ACEA7D146E877D94FAD61BD4
+:10BC4000A75B607DEB8D4569A1F116D7FDA7767DD9
+:10BC50006B5313DD69BDE3F3B487827444A85E4A75
+:10BC6000880BE94FF219818E95E7E78518C4F7E252
+:10BC70003A9138CCA1F1153AF07EC0E9748795F17C
+:10BC800001C7DB123BE02C84B76E3BC7A314C8543A
+:10BC90008FAF948F003EE87A6A3D762C1FF72461BF
+:10BCA000F9A4C781707BDA3312CBB51E273E7FC65D
+:10BCB0003301CB751E1796CF796660E9F3E463BF55
+:10BCC000E73D05586EF0B8F1F96F3D2558D679AAD1
+:10BCD000F0F926CF322C377BBCF8FC65CF2A2CEB51
+:10BCE0003DB5586E057CD1B2C1E3C37EDB3D7558CE
+:10BCF000367AEAF1F9EB9E462CD77038DAB248B6BC
+:10BD000044E16073113B453B89CD7365CBB41E9B09
+:10BD1000CFEA09F3BCD9465A4F70D33A85CB80326B
+:10BD20007FB689D60754B1F621F7921C33AD0FF1D7
+:10BD3000B2F69435AE9C085A4FA965ED23D67973B7
+:10BD400022697D848FB58FDAECCF89A2F551F5ACED
+:10BD50007D4C13C9B5D0FA183FABA7EF73E55A690C
+:10BD60003DBD95D5333FF1E6DA683DB38DBD3FA9C2
+:10BD7000C3273A2C3DF1B055762C2014574DDEB92F
+:10BD80002E89CA9BAD46C75DC449C87BDEF92E89A2
+:10BD9000CA8706D985ED6DDEC5AC6E74617BB77759
+:10BDA00029F6DF2EBBB15DAABE0FDBB71BDDD89E27
+:10BDB000505D83ED8DB217DB47563F8AED8D462FE0
+:10BDC000B64FAA5E8BF5D7651FB6E755AFC7FEAF76
+:10BDD0001B7DD8FEF8FD9B5C5369FD05C1BD1DE4CC
+:10BDE000DE0AC15D4252819EEA9340EED570F9F9B8
+:10BDF0001C101D6DAFE96F443EDCFA6EE60BC0BF50
+:10BE0000F8EB07F5A2DF3E988CE3BC89E3C8741C0D
+:10BE1000F1E2E3A4BF3741334EFA7B25CA382D380F
+:10BE20004E44DFC6D9FADE24ED7ADE2B55C6D90F93
+:10BE3000FCB4C2DAB77DA5FF394BBB9E3F9729E31F
+:10BE40007C84EB89E9DB7A1A3ED0C2A7E183207CAF
+:10BE50008EE238F17D5B4FC6412D7C320E06E1D378
+:10BE600081E3F4EFDB380D07B5F069381884CF971C
+:10BE7000089FC17DDB57C6212D7C320E05E1F35FA3
+:10BE8000B89EE4BE8DB3FD532D7CB67F1A848F49D6
+:10BE900080F50CEFDBBE323FD3C227F3B3207CEC3E
+:10BEA00038CEA57D1B67FB675AF86CFF2C089FFEF8
+:10BEB00038CEE8BEED2BF3AF5AF864FE35089F1478
+:10BEC00001E033B66FEB69FC5C0B9FC6CF83F0B922
+:10BED0000CC719DFB7F54C38AE85CF84E341F86461
+:10BEE000E0BE26F66D9CC6E35AF8341E0FC26732D8
+:10BEF0008E33B96FFB9A70420B9F092782F0998E9F
+:10BF0000E364BBEB985146C7B1F63ECEEB67B4F0A5
+:10BF100079FD4C103ED7E338D3E838A9171F675294
+:10BF2000A7163E933A83F029C071AEEADB38AF77AB
+:10BF30006AE1F37A67103E8538CEB57DDBD7A42E53
+:10BF40002D7C267531F88C3B50956BA3ED54173A38
+:10BF500045FACA951D2E9740EBA29DD545BB93800F
+:10BF60005D222AF606697589F47DCBE698F4078987
+:10BF7000DAEEC8B913E8C74AAD31B5DD113D21523B
+:10BF800063E7C4B86235F5B8190334FDE3F35334FD
+:10BF9000ED8905A334EDFDDDE99AFAC092499AFED8
+:10BFA00083AB7234F5A1CBAED6F44FF6DEA0A9A7D1
+:10BFB000AEBA59D37F78ED7C4DFB256B4B35ED97B1
+:10BFC000FA9668EA97D5FD42D37F74FD724DFBE582
+:10BFD0008D0F6ADAC7FA1FD7D4C7B53CA3E93FBEB5
+:10BFE000F5794DFB15873769DA27B66DD5D4AF3CA7
+:10BFF000F9BACECEB3D88F5FC6EB22D03D61767F43
+:10C000007FE6F7F8AD46AC1B0758D08EDF652D7282
+:10C010001CA3F835BEB5C0D18FE217700A7E45F675
+:10C0200080924BDAE8F37B26B92FB1D3E7F718DD1E
+:10C0300097DBC3D8A7941E049204A5C300A5BEFD38
+:10C040000199D163CEC0F323DAE9FB9586C0881845
+:10C050005ACF12B31B817E770ACC2F8A144915F46C
+:10C060008B3411F40B1E48CE7CC1ABA2D75583296B
+:10C070001F0AA17157C9EE24B033DEAA6EF7821DE4
+:10C08000523398EE6B0021CD42BBDF4BFDB4070667
+:10C090001725B9E9782623B5D3D5F31BE9FC693810
+:10C0A0007F0BD0EB7B307F7CCFF94D291334F39B92
+:10C0B000879468E6371BE9FC7642DEAF3EC5E7A70A
+:10C0C000489844C85F845338BF694809CEFF8091BF
+:10C0D000FA2BEAF92383F31F86FD7FD6DBFE532676
+:10C0E00069F73FA454BB7F23DBFF91EAB37CFE4892
+:10C0F000DCFF51E12CDBFF9052B67F131B3738BFBA
+:10C100002D08FF93307F672FF39B52B3B4FB1F5A68
+:10C11000A6DDBF89CDDF5DFD2D9FDF82F39F13BEBE
+:10C1200065FB1F5A86F31B4D6E27D08F7160649597
+:10C130008FCE4F1D6107490472A1F340393216FDBD
+:10C14000E49784145CC73D918CDEBE8AA4F486F229
+:10C15000C6CBFC581F956C99D4EFE2B4BE7873B689
+:10C1600011E412B6537F65215FEA1D8D22D2377923
+:10C17000D2E41B4ED7DBD9287AA17EC793937D20CA
+:10C18000FF2A4DE4F67C784F227E78FEF953A39F78
+:10C1900057EF4B5F2EAC958FB7A9F82DE847E59088
+:10C1A00091551698D7AEA91FA17E10A1FEC527D420
+:10C1B000CF2094248FCA6CBECFA8BF04F536EA2FD7
+:10C1C000413B21D5B85FE2757D308CAE3F9F283F63
+:10C1D00017EEF32664293A9EC4F8F7C81AC107F887
+:10C1E000B87D5914057E683D85DE384D9DEE0FFB08
+:10C1F00007AE127CCF0B38861BE033938F4760BDB0
+:10C20000B45E6067EF1CA2E8EF4F51B060D5408A82
+:10C210008BD038B3884B4EA4EFCF595A2843E8A2AD
+:10C220005510062F01FA5920539711E0E78D276921
+:10C230009C38E87A6FB6B3F167BAE4636DAAF51477
+:10C24000C866573E5D4F41A188EB9F3543DBFED169
+:10C25000CE2897610C2D573D81F3CCC9D7B6DF545A
+:10C26000A0ADCF756BEB54EFC9A0F76E29D13FA7F6
+:10C2700060A1FB9C17842B5D285DE7AD1C0EB756B3
+:10C28000C95E0D5EC16D55DA21A0E026B82F7C5F36
+:10C29000ECD9FFF665DA7AA1575B5FB04A373EA763
+:10C2A0009BE31CFF47803E687902E883C2F318A72E
+:10C2B0008F905CD5D2C78DC16D30FA50F6715C623B
+:10C2C0002838BE8ED1C7C2DAA8F0F45018A4079758
+:10C2D0009ABE147AB88DD3C3A79C1E8AD76AE96A1E
+:10C2E0002EF1AD4CA2EFDFB26617E2E9A050C8E82C
+:10C2F000E1970A3DB469E8C1CDE9418FBFDB383D24
+:10C30000DCF673460F7A7CB6717A685B7B4E262921
+:10C310003DF14AF1A0A9533CE8F06E37023D507C54
+:10C3200084A587F9C17DD38DD3FA02DED6035F9C45
+:10C330001EB03D05C04E104EF87E6ACFFE544E68CA
+:10C34000EAC56BC3E3BFB2313BEE986A5DE5F557D2
+:10C35000C51D53F55B5C3753535FE49BABE95FBC92
+:10C36000B650D3BEB07691A67DC1AA3B35F542EF5B
+:10C37000CF35FD6F5F56AD69BFB56AB5A6FD969224
+:10C38000C734F5B9EE5F6BFADF54B05ED33E27FFDA
+:10C39000454DFBAC195B34F599AED734FD0D3B2F01
+:10C3A000BD1EE831EBA048C0FE38E67120DD1FF766
+:10C3B0008CC4F2A4C7897C71DA3301CB7D8DCD4F5B
+:10C3C0005C49BB7C192888264C7F16911842F62CB4
+:10C3D0007757AFCA027D4E50EFFE717951B5771095
+:10C3E00095530607C2396FAD91F8C711228052E20A
+:10C3F000F307C4507B561B6D8FEBBD3D6FAD14B67C
+:10C400003DAB4D0A3B6EE5E38543ED61E233217EB2
+:10C410002603C13EEAE2F6B9BEBD4C20F9EAE78444
+:10C420002C47FE8F3130FD5C666472A26C6BFF1C82
+:10C430006283BA7F44D585E6ABA7CC9508F491AA70
+:10C44000E1E3E2B59769E43C81E86D3CD0D938CDB1
+:10C45000F3C575576ADEEBD825E2BA2B4086507DCE
+:10C460003D8CE4070CA097FDCD43668D8675BACE52
+:10C470001A405E35C6A3FDD8E19911774C023CE61F
+:10C480006379D25380E5718F1BCB639E122C8F781A
+:10C49000AAB06CF32CC3F2338F17CB4F3CABB0FC7C
+:10C4A000C8538BE561CF5A2C0F7A7C581EF0D461AB
+:10C4B000F9BEA71ECB564F23969D1E17960ABF297D
+:10C4C000F0D0D3DD49AEA74F03FD5D80CEE2C407B7
+:10C4D000AA570D0AD159E28A87ABBD59A171F3D68B
+:10C4E0009A389D2468E86108F864E3815E4C9C5E9C
+:10C4F000C2B7E7AD952FD89ED526871DBFF2F97F2D
+:10C500000DBDCDF991F416A2A7813A7A4ABD183D26
+:10C510004D12C787E8698EC1CEF41FA7A787601F99
+:10C5200061FC8F6230EAC6ABEC3A57148B67F37349
+:10C53000076AD1B278369F7B051DAE15ED3FDF4807
+:10C54000C073F7C8BF8F80787DF761AA28937BDF1F
+:10C550009F9E5E7A87BB0BFDA0221F55A2E37AB691
+:10C56000474432B84618C80C924EC8EAE1BF75CEAF
+:10C570004FC3BA4462E17D9F736698F32802674F08
+:10C58000891787EB0AEB576360BCE3CFFC2313CA20
+:10C59000398614E6DF348B68DF13FF0B4E806F5053
+:10C5A0001F999C4910070F0C37DAD13EF059B4F0AF
+:10C5B000F3D27A66087EAB298C5A51DFD72621FC4C
+:10C5C000867D35A27F1FE07731397F3178CEF70D38
+:10C5D000F897C0F362F2F1627291B81C2F37D2FD66
+:10C5E00077ED1C9DFEA003E4E085E1AD9C5FE9D7FB
+:10C5F000F3BC287D2F3AEE4A50E8B87508A1F388BD
+:10C60000A21DC7EF6EB884C92FC5EEDB66F2F50533
+:10C61000AF6792B5E33DC5F94F19AFBBE5051BF810
+:10C620005B4B920CF66361F0A094E5F5C9768BDA6A
+:10C63000FE6CD4D6BB6B8519F568273AA2678F06C6
+:10C640003D61B71F1B06723B094B659C254946FBA4
+:10C65000312AF74ED7A546333FCFC7E4C1E6189439
+:10C6600017A73D66ECFF53AFA7B77194F510D24002
+:10C670008E9A411ED3B6D4DEFBF74ACFD217463C82
+:10C68000F76D92BF02FBD04CFFFF0EFC0D22615DE7
+:10C6900019B7B25EF49A2E87E79B35F3D1F71CCA1F
+:10C6A00019EB772917E21B891C57E896EA8B635C24
+:10C6B0009F2CAE8BB06BEDCF184DBDB2B1BF5D639B
+:10C6C0008FC21F54FE922A4102FA29E3E4D325596E
+:10C6D0005609747D6F429010E85660FDCACD6D46D4
+:10C6E000B703CE9519DE7A5B1FC5DF4C89927C8932
+:10C6F000B916CF614BEA2F9D0A7AE64CC38A0488AB
+:10C700001B2C16BBEFC90FF3BE2C3179BFC827070E
+:10C71000B4F63DA70F42C7559E635C94588EABEAB2
+:10C720001D06168FD18F9B00E3C65F1C3E159BF73D
+:10C730004F073B410FA78AC6B34637CA45FA5F6623
+:10C74000084E0AFCDE14F313243A7E695D3BC62DC5
+:10C750004ECADE11BFBC80BCECB93F4BD2F128D52C
+:10C76000BEBCA415E6993F814F441C377D4CE5F8CB
+:10C77000A93FC904E410394F7B65624886FB3B063C
+:10C7800062C80CF93BF31B16E701BC4F81BF47E5BC
+:10C79000E61D24DF867820B599E0DF9C218619000C
+:10C7A000A733E47DDB38151E7225238733958294E9
+:10C7B0001E4CC1F1DDFDC1EF3215D4B48A63E0B97E
+:10C7C000A4F83FC2771847720B98B750C09E7B8978
+:10C7D000B91AE897FA511A3F8DFA519A3AF5A334EB
+:10C7E000F522724302E425143D29139F8070D2B4D0
+:10C7F0008F92EC88C762525503F6D1AF79FC6DBEBB
+:10C800009D4803E93ECB5F7D36B390EEE76A89C56C
+:10C81000FD9473F545B10C0EA5253EA3CBD2737FD5
+:10C82000471BC6DD48253F8CC7CECF6F36621E053D
+:10C83000B44A99DCF449E97DFF890DA22BC206FDBB
+:10C84000E87365BDC9DF7FFFFAFD12F238EEA3B4CD
+:10C850006E2601FAEB9127C0F723D7092E5F187EC9
+:10C860002AE474AFE8A73B017EE343F1ACFB74F527
+:10C87000D51CBE4AFD295DFB0F962FFD8846BEBC28
+:10C8800029BAEF93C6337902F017A400F2D70F1E2E
+:10C890003FA9C7F8AB811F7FB2F10769F99E8EFFF0
+:10C8A000D44FBAFE613DD6BF3EDCFACB5F7D69BB9B
+:10C8B00097EA97D23F3C652394DF4E49B5094E8AEB
+:10C8C000F7B28D2B6D2E903B92D7067C71CA27CE86
+:10C8D00008470F87B87CA506884580782BFC49C798
+:10C8E0003FBDE9A1EBC09EF86AA36CC7386A9DC939
+:10C8F0006FA2F45CD1B0288F8CC17A3BAB3F70162D
+:10C90000E8BFB2513EA2A6D3D2DF3D95007935945F
+:10C9100052061A92A0F4A37F52B1E1F3E9606F547A
+:10C920009200F2ABFE3D98FF9B58D48785C6E89EE7
+:10C93000ED18984980F7D9AFB2E1A1B3A20DFE6A14
+:10C94000C33890BE7F09F7375A246B3F3C27B98222
+:10C950005C01F2548107F1317F63C58BBF1AD34E5E
+:10C96000D7D3B1E14F36410527C54FEAAE5FF09B03
+:10C97000D71DBDCBEF4ECA876ABB56D14F8E46EE50
+:10C980002735B1B24CF6DBAEA4F2A46CBDECF4D208
+:10C99000C7652FBDF0DB67207EFDA1C9399C8EBF26
+:10C9A000F8A53D0727D1FAE22D72BF3CB60D8B905A
+:10C9B00010C24B25FD7F597A080FA5AFEC313A46DE
+:10C9C000B3E7F7C686F0B178CB2E2319DD131EB975
+:10C9D000F5BB8C6D963078A96F9F0E76DF8A17BFF6
+:10C9E0003682BC3BB5532089C961E0B97E0FDA8538
+:10C9F0000027C423C753106FBAFE95142FA05F14ED
+:10CA00003CE9DB37717902E339D2909E5F7E9DCE9F
+:10CA10005FF291C909FB2F79F92E1BECE38454C511
+:10CA2000E8FAD9950920DF4A646F821D4BF6BCE411
+:10CA3000B9BB91DE8AF7DF9DC0E292AEFE06D495C7
+:10CA4000DEFEB0BF85EBE6E0FE8A881BE9AEE45966
+:10CA500031DF47CB2F2532634B18BEB8566672F2D2
+:10CA6000C4F35423D0FD9D50F4C0FB22D70377625A
+:10CA7000DCF36EBE176A3162FD4B33C3D330D9C0CD
+:10CA8000E52CD32B417ADDF000EA8BD3835D8970EE
+:10CA9000BE5619D20FA837C4FDD312197E989EC175
+:10CAA000F7A89EC985E7D0BF5576458CD1BC877A5B
+:10CAB00045997F299F9FAE3B12ECB51309E1FD8F8D
+:10CAC0009FCB0ADF53BB42455F2AFE66FCBE613541
+:10CAD000E36F85DF7D336740FB170718FFC07BA03E
+:10CAE00067E9BAFC89D8BE6BB680F2C044FCE1F8B5
+:10CAF0007A83CCF95ADBAED0095DB72444ABE805A4
+:10CB0000C68F45F8A35E2F7A92BEA7929795309F65
+:10CB1000ADE7780ADF1673FE9F216BF99FAC8BEFB0
+:10CB2000533E6599ECFBED33C0AF943FBD0EE0572B
+:10CB3000391FF6FDB7CDCD076FA67CFAB77A854FC2
+:10CB4000B5F253CFA7255BEF26409F7A3EFDDBA0D1
+:10CB50002A12964FE9F3B07C3AA8ED7F547E2AF072
+:10CB6000AB02F84585E0A7C8C3DEE0A8978756D991
+:10CB700011561ED2DF0192D993FE14BA53E8ADF4D8
+:10CB8000F7E54341EE04E952A1BB205D2A74A7DF1B
+:10CB9000AF167EFAF64932C175E5BF26A3FF5CD613
+:10CBA000C4F242E97B7B0766209C5CA8C648EDDEA8
+:10CBB00081FDD4759FAE5EAFEBEFD2D5F375FDDD91
+:10CBC000BA7A95A67F5963B39120FEFD9A7EE2B2B0
+:10CBD00067C8D1B870F4EA637E59C359A317E8C295
+:10CBE00012C0F7E5E5C40B7986811D22C605BA2877
+:10CBF0008C6B207EB139D9E7A5726365048B3F74D5
+:10CC0000D903B6585AAE8C61F540BCB106E49EF229
+:10CC10003C10C1E28A5DF9015B8CCA9F6A6F1251B8
+:10CC20006EB7F9C88C707E16D528C8476DA4B77644
+:10CC300076EE354DB40C590671A55AD10936F81D5A
+:10CC4000D537D9E0DCA9AB29F5FA02FA7CE11F451A
+:10CC50004C7BE98AB48D817511AF4BEAAFF26F4E10
+:10CC600012EFD359747F0B9A989F73C71A9D3D4258
+:10CC7000D6203D1559961A419E527FE288F6BC8611
+:10CC8000F145291FAF649DB65D799FD201FAF3A5E6
+:10CC90001BB4ED6EEE0F7FA0F0C9583296FBA32CAB
+:10CCA0000EC3E5F23431EDFA028A8FAE1691986820
+:10CCB000BDBB49447C746F167C104F23DE78E4B70B
+:10CCC0000A124079A8C0A903F8C9D8BBBCEAD8F6B3
+:10CCD00069E62F816EB67F3CE63F69D9B1FDC3118D
+:10CCE0006F40FDD543433E263DFBE7EE8CC073FF0E
+:10CCF000AE9D56A4F7AE1DEF0EF925D45F33396112
+:10CD00009D5D3BBF1E03F4D3B5DC5402F2AE6B3025
+:10CD10008BC7AED8F1F59836D4AFF733FD6164FE1A
+:10CD20006177D33F3E13FA4149770576C3CE28E4B5
+:10CD3000A7CAD72330DFBB6BC7D7996ECB4FB79F3E
+:10CD40000A9EE7D16525055B617D312C8FA1F28DAF
+:10CD5000892F54D3F9CB1B761917D0F6DC37FF395E
+:10CD600006E468D756660F75CA6DCF411E4394F12D
+:10CD7000DC7299E2AB13988A3ACDBF3366E402DFE6
+:10CD8000F484CB3F313ED65778A4FCAF8187E06274
+:10CD9000F2CEEA330BB0EF6F3FFB18E39A26A44BB9
+:10CDA00065BF7FABAF467BE562FBCEFE7F6EDF8269
+:10CDB000BF2FFB76FF9BEFFB38D7BB7A3EE849E7F6
+:10CDC0003BEEC1FA4B5627AEB78FF4EE85FDC7FF99
+:10CDD000FBEEFF7BE37D2BC5BBEDE2FBFECDFF5AF7
+:10CDE000BCFFF1368E773B7ED7F3E63F717DDF5790
+:10CDF000CEBDF96F8EF7DEF6AFD8F5AD862A7B068D
+:10CE00005D5F01A9B582613137BEDB92E1806CD7ED
+:10CE100073FD308F0ECE4BC3F84D0123F30B4D90B5
+:10CE200047077EFB1C41890BA21F751DB71FAE1B58
+:10CE3000548276C875AE8799DD2055B566D3FEADB0
+:10CE4000390B9C987349D20FBBA13E7B32AF6BFD6F
+:10CE5000C9F704E212A81D7F5DCE352D60D75EEFC5
+:10CE600012D1EEA525DABB1F0C99CE9E4FD0FA3D0C
+:10CE700073DDDAFA4D05DAFA1C3EDE8D84ADFFC6AD
+:10CE80007CC107715553F613F11067352D948990C5
+:10CE90000CF942552BC1BF9893AF7D7F1FF8C1E3BA
+:10CEA0007F3C1C534D0A1C97205C48B6E8DC48FACE
+:10CEB0000047BEEED6D9637D90CF4C242783E38D07
+:10CEC000E54E8C83737F5BE6EFCB9655ADC0CFB25A
+:10CED000CECF56FCE5DEE04DB8FF8DE3A484E02F15
+:10CEE000BB44F4BF659DFFADE0E5FBE243C1E38FCA
+:10CEF000C5CB973ABC0CB2B808F0ABCCFD85A916EF
+:10CF000027AB0FCA2778DEC8FD05A99F8B78D342CF
+:10CF100079DF8BCCE66C385F338F1430DE71FD1A0D
+:10CF200011F583394DC075E54F90318FF873437E0D
+:10CF300026E03B6FDC1515BF60CB70023C1771B863
+:10CF400017912AB45FC9F9EFBECBCA84730682F683
+:10CF5000EF221721D752BFAD284BF0475278154B1F
+:10CF6000C41B9D0E716F811CD1C4BDB575F8FD4702
+:10CF700042689C8BF5EF4DBEFCD4E55FA93C3B328B
+:10CF80008CFA411E9EBB4958DC56F1AF6F6F627040
+:10CF9000AC2C137C2948777E395F75EEF81CE7834B
+:10CFA000BFDE3B0EE564F6A3A3A3D1EF7739D06FC4
+:10CFB000A8E47E43B7D7110D71AEEEA6547E3E9B1A
+:10CFC0006B53CB55A5DCCFFDEEBF407E212DBBA61C
+:10CFD0000AB522F8712480F15CEFD408B2314CFE1E
+:10CFE000EBFF311938FD54611C007E6226E091FD93
+:10CFF0008AE9ABD1B12ABCADB9F69434A6271EE0BC
+:10D000007744750EF963E10B7E3EC0757F44DBF417
+:10D01000FC30FBAD35B13856DE5BDFE2779C373450
+:10D0200025CB00971BA68A9A73FB5526EE978D2376
+:10D03000E3605D796F5D659B087869119DF0DD6641
+:10D0400065D359A33BCC79B01E9E303EC4D58FCA60
+:10D05000CE2280E7D1872308F8D1EFF273C634F8E7
+:10D060006E220D433A2E882BFE9AC3B5D364C77245
+:10D07000565EB61C4FE74D6BB08F85A3D401BC7FC5
+:10D08000271821E3218987BDA7F41B50C6FAB51BD9
+:10D09000ED15E1F63F3C82EDBF9838EF9920FCFB9F
+:10D0A000E12DFB51AB3F07EC83A93CAED283AE0927
+:10D0B000F247F70CC107FA1BFC61ACE7B1EF84DF64
+:10D0C00055BEB3BE81E95985EEF570DECBE1ACCC3F
+:10D0D0007FDCC4E2AF7FE2FCA5C05981AF7EBD4AD0
+:10D0E0007F2AAFA6A8E351D7378E7D19EC9B8A26FD
+:10D0F000C16EA04355486D46E0C3CAC6C764386FC9
+:10D1000099EB60E312297F8C3A9FA0D3C4F23B9A3B
+:10D11000D3AFBC0DE8E4DC1A13E842E2BAE3AC0D8D
+:10D12000E4F0BB06E79FE17B6AEF7B22D9780179C7
+:10D13000F5B1A7CE3555528F9B8CEB9C55962D4360
+:10D14000F8EC96B25D72A28A9E3A4DB1D8AE3C1F01
+:10D1500050E64887E7743E5C87F7111381EF42D2AF
+:10D16000EA5BF1FBD45BAA62181D96D4EF32623DF4
+:10D1700019FB2BF329F3E8F969769E36EF78416EB7
+:10D18000DB20804B9EC9BFD419864E1F332BE78E00
+:10D19000DF534FB828DD8EF9FF484F2C55F4441B60
+:10D1A000E6B92BEFCF35333E57E989C4707A62492F
+:10D1B000B52311F0B064476A2230C9923F4E4B0844
+:10D1C000A7273EF0B073E343FCBBEEAED9544F5CEF
+:10D1D000AED213B323904EF4EFE59A95738D8BE89E
+:10D1E00009056FFFC3F2E603D01361F8FB46B3569F
+:10D1F0004FDCD854887AE2C6D9A2E6FBAA6BCD17D9
+:10D20000D313D90973B12E3BA3C2D0CF07DCBF39EA
+:10D21000C4F3FB611ED0176BCC76849B5E6FF42643
+:10D22000D7C7F655AEFF5F82B322D797CC61F743DD
+:10D23000F4A44382F4BC642E95EB02D02393EB4B11
+:10D240006EE5714E9D9CCD07399BA196B3ECFD0A0E
+:10D2500037D30B958DC9BF9A47DB6FAE959D66DAC4
+:10D26000FFE690DCCD54CBDD356609E1DC43EE967C
+:10D2700030B97BAE691CDA4FBDEDEF532E6FA93C80
+:10D280001BE60C431F05F3A234DFDF1D1DFB76DA1E
+:10D290002BC02FEF8A787EFB39B703F68D7D3B03D9
+:10D2A000ECE9537C3DDBB8FCEBF4F85C53A91CC8FB
+:10D2B000BD83D9D3E59B45845F4503E3FF8A619134
+:10D2C0003E07AD4F4FFF16CF6117EF60E7B0740711
+:10D2D00079D92AFC2F7EB7AD06CE0516AF17F01C04
+:10D2E00019BE5F0078167378163917E3394AF1DAF8
+:10D2F000F0E73FE5BCDFA2A6F5180F5FE4D3F62BFD
+:10D300001F76F529F047F24C0C0F79AF08BEF5C92E
+:10D3100090CFA0EBE75C8DE747E5F5DAE707F97E0C
+:10D32000178AFEB457E8FBE4CFCCBFD3C3FBA01EE3
+:10D330002E253F122EFB295C32FEF570E90D0ED42E
+:10D34000BEC7F3013D3C0E2B72259D64001F7E6E0F
+:10D3500070A15CF1BE43E142E7BBE3B1E19AFB405F
+:10D360008E73B8BC6B70D7F4877E1502F62B5EB750
+:10D37000654F02ADCFAB2763E178A178AD560F07BB
+:10D38000F57E8303F5FABCAA2D02E4C72EE4DFFB89
+:10D3900095F81EC37B546E5D46F53CEDBF20DDE481
+:10D3A0008673F0FD1101949B0ADDC64730FB258E84
+:10D3B000CBA1A3030253513F350A76E4477F04D340
+:10D3C00057144F70BF4BF3C4AFA773BCB0B8522310
+:10D3D000C36325C51BF0F3F4265EAF6376E02D4AE8
+:10D3E000BD5EF0390490ABBB64765F8C40E2048E86
+:10D3F00004957E84F3D5EC04159E77B433FADF28C8
+:10D4000038F1818FFEF743F0DC2BDD333BA6AFF420
+:10D41000AEC0293E428BE7FD11AD79E3FAC1F99B1D
+:10D42000E0C47B739A62F09CE8582DBBFF2595BF42
+:10D43000A7E70BF03BD4F7D1CC8485437EF38C086F
+:10D44000CC0FC57953985DA6964FFA7B80BE6FFED0
+:10D45000512569457B2C94C7E87EDE04E3CD10346A
+:10D46000F94E1009033AFF09C6BFD57C81F14992F4
+:10D470001DF396EFB22BCFEDECBB2C5E6F1E9C79AB
+:10D48000681E85EFB955A2135CA89B0C8E835920AA
+:10D490006F1E9409F0CBB97DB28BE98128D43B850E
+:10D4A000EF1EC5EFD90A590E1A29BC8FE997A37C44
+:10D4B0003D1F51BDED82580AA91F0FF7E0CC76EE53
+:10D4C0009AE680784BC6FE9570CE392BD77EF02039
+:10D4D000E07335BB07E9C8AA5CF4D3EEBA53407ECB
+:10D4E0003B4CF106EFCF999D7CF0209DF7D655F18E
+:10D4F000786E39CF157F239C63CEDB273A1DB4DFCE
+:10D5000082EBAD1638C7BC66A448DC2AF8DC4A5A60
+:10D5100031BE33AFEACE39B0EE12AA0FC56428F798
+:10D520004F4B84FA3A01DFAFF4BA8DF0BD66EBDA07
+:10D53000B3C60C3A7F11ED0760AF5CC7FA556E10A9
+:10D540009C90FA5DD4F418CACBA20D025E34D34A83
+:10D55000ED5F331BD767A6E3B6AEA3EFD37A31BC3A
+:10D560000FE36E88B911CE272BE93AF1FD09D57882
+:10D570002E5D44DFA3CDA475C39D38DEA275028164
+:10D58000EF034B26243F3201C6DB273BA1FDD0AE83
+:10D590005F1B61DDB7D1F9FAD3F117886DD3A03FD6
+:10D5A000F9A560C7FB87EA4660DCAD0B360C2F544B
+:10D5B0000DC73AE6133B100C923A1F654704FB4E29
+:10D5C000B86859750DECABCD1B9F6C40BA3A6B0433
+:10D5D0003D7E8CC2DB4D873C6A64792ECDDEA3C6CE
+:10D5E00036951CFD282215DFBFA3311BF3261692AA
+:10D5F0007CCC9B7057337BA47D65840FE26AEDB2CF
+:10D600007D083C6F5E69C2E79D2F31FDD339B80DAF
+:10D61000E3DB27D6C904BE5F5CB12EF569C0E389A0
+:10D62000CD32D29BF82CCB1B287E89C5C99AD7B1A5
+:10D63000714F2C35B27BB5A09DD68B5F54F20AB4E6
+:10D6400072ACC8518A724A2F97F4726BD193D54647
+:10D6500020D91EF26AE9749457A554EF00A1F59001
+:10D6600057836A306EAA975795C4A2C8A974885F79
+:10D6700016960FBE6D2DD0F1ADEC838156FF6B5F1A
+:10D680003E057AB7CC4AE04985647F5A6074418090
+:10D690005FE6356DF912F8A0645E04DEC7751CF014
+:10D6A000007CB3260ECFAF8B7C85086F252FB77813
+:10D6B000AD96CE95F8E35CB7485C6AFD5512455CC3
+:10D6C000AA7E87EEA3F44AE7B9BD51F081A83C7465
+:10D6D0005FFBDEBB33B06EC7752DE3F6C11A2BD2EC
+:10D6E000F3A19F9F5D09F47ADBBD02017B9D78DD8C
+:10D6F00035A00F2BD60A0E880F17DFCBDE2FA6EF33
+:10D70000C3BA0FFD9AD115A56F07D07FC5BAC7F66A
+:10D7100062FF0D8203C63FB4BE10ED8912AF48B060
+:10D720007D433BFA0F544F619E59B3574C00FAAFFB
+:10D73000B8DF64075349A123852EDBF97D08C4ECCB
+:10D740001C338BBEB70A1615DF931EC50221A84FE6
+:10D75000814E2ABD8CCEDA5F929D403617A74BF6DC
+:10D760001DFC09AE5FC567E74C87EF748AA97E048C
+:10D770003A6D5E976B043BE2844FC0FC8A9E74490D
+:10D780002C6A3B4AA1CB670526AF7BD0A38E0E7BCC
+:10D79000D01DA74B85FE2851A35F59B64F26F0FD3B
+:10D7A000BD9E1EDD72FD8D90FF51F832DD0F5D6F65
+:10D7B0006ECDCFD15E57E048EB09502F9258DE8FE7
+:10D7C000C20FE512CB0FFBDEEBD3CDBF2982E7877B
+:10D7D000013F882C7FC94FE77D7BF30B982F79663B
+:10D7E00053FB7568DFBC41E900E0BFD94AFCE87F24
+:10D7F000F8500E953688986F4D247FE62C95DFAE55
+:10D80000E4BF2CFE8315E15DBAD5E4CBA3EF976EA0
+:10D810003F3A06F311960730BFC7BB4960E71FDEEA
+:10D82000B631F0FD50A9C4F270F476C1F04816E7A5
+:10D83000EA782DAA00EC36A18EDDB3575A7F936C9F
+:10D8400052C5750745CA382FED87E7635E8A67B80A
+:10D850001F01D6A7BEDF4DC9BFE97891D15F69A38B
+:10D860008CF65C69DD964EC8C32C3D6C423FB7B266
+:10D87000EEAC11FCD8DC3FBC84F7F355368A9A3CF9
+:10D88000BC1EF96F75A2DF04F95B0DE5787E43EBF2
+:10D89000ED58AF0F9F077AB13CADC57FD8B1DD4BD6
+:10D8A00041B8F895DFD9F0BEBED68D36FCEEA9EEB4
+:10D8B000C2F9A73DF2DDEA575F30DFED34FC4109E4
+:10D8C000EBBA485DBE601D936B747D99F961E2C44B
+:10D8D000417BEBA52F9F837CEC8EAD7F7B0ED65BCF
+:10D8E000F65FE79E83BC1AB233C20EF648E5A60F78
+:10D8F000309F5579AF2492D97F9D2FFE0EF3803B48
+:10D900003F343961B4CE1D278680BDD1B9E5DB0433
+:10D91000C8EF5DBA631AC673966ECB4D2461E205FB
+:10D920004A0974EBEB431EB21E5FCD0DCD98FF7319
+:10D9300086E21BE443307FB1BE9CE5833A78DEE2A9
+:10D94000E6F0F9DE3DF2141B665D3F19E46203B3B5
+:10D950000B2E9AAF7880E2F1F23EE06FF36A2E4F21
+:10D96000C2E3EF0CFC41F15413A9CD57FCB261E1C5
+:10D970006F9E81B686B85EF315FD7D809B924F3E0B
+:10D980002BD2F55824F0CDD6DF637E28E02DCF01D1
+:10D99000F2F9CB2110173E290730FE10D861C2EFF3
+:10D9A0002C4B771C42FEE9DCB61FF3B509CFEBEE3A
+:10D9B00024C11FCBC3E5B19ECA0D5696E7C8E10F3F
+:10D9C00079900E1B3EE7F98E8C8E953CC8DEF21FD7
+:10D9D0005B2253F87D2A2C4FB37CC3C73CAF308405
+:10D9E0002F6102E0A9FD8279A50A1CEC00872BD4E7
+:10D9F000F9BCE1F34C8379DF1C5F803F90D3C17C9D
+:10DA00005D5A1F04F99B3EE11009230F3AD7B33C3E
+:10DA1000E04E39FCF7CC4A7E6FB39E4F7D7DCBEB59
+:10DA2000BDD8FABF2F7C1A221D38AE1E4E1DE7C38B
+:10DA3000CBF1E39CEF7FF0F7216582FEFB93CF8172
+:10DA40001ECB1BDA8D789F89E23FF1FD76F0785A84
+:10DA5000C72611F33E6BEA9B518EEBE545053F2748
+:10DA6000D1AFF71BBEDE8A46A6273AB65A7D163AD4
+:10DA70004EC75BAF213D576C6EC7BCD3BD75AF18A9
+:10DA8000DB54E7CBA0277CAAF577BCBC6B0CCA6D36
+:10DA90007EBF987E1E63149BA7B229FC3C959BCF4A
+:10DAA0006AE659ECAD37DA2D179FEFB4E4BA09C630
+:10DAB0003BDDCAECA5D3F5E20C5F98F94F71BD4987
+:10DAC000482D3B0FA5FA12EF59B3B27BD5445B2426
+:10DAD000DA5F4BAD130E47F783D288792F2BAA79E3
+:10DAE0009ECC7DCE24C0F70AEBD504D6BB12E0ABAA
+:10DAF000F2E365BB9B80DD2627E567A8CF5994F547
+:10DB00001BFB19884F85FFA5D61989E07F12C93BF9
+:10DB100008D6715DCAD712E8BF560F8BDF93F34763
+:10DB200087C1F356C9BE278E8EDB3A557042E8B5E1
+:10DB300027DDFB347186992EED7DB1F80D1CDD5F7C
+:10DB4000B7D380F6A0D5E0B7D32EC41AD19A840EED
+:10DB5000AC8338A404FC1402F3211EF49867C1FDC1
+:10DB6000C83642CD53E8E79434F79F444F9074F79A
+:10DB7000A19003C328BD5A38BD2A71392BFB9B8E57
+:10DB8000DB86F7ACC4A4916A20DF355637DA0D4F37
+:10DB9000F0FB69E86F24E441C49248A7FAFE263AF4
+:10DBA000AFE6FB383AAFA61EE3D2D6E36648C7C25B
+:10DBB000E99738BE8EE9A205E11033CDA0F86B7964
+:10DBC000C31342EB8E89274E3FB45F6BC1EF012830
+:10DBD0007B79D5FBB058B4EBA6EBD3C889E8B43653
+:10DBE000AF81AD53F3DC4E1C02EEDFA57D4ED7AB0B
+:10DBF000A917467179271109E49DC5DC4A38FCBB99
+:10DC000035F0BE5FDA373801F043B85FED2590CFCD
+:10DC100012CDF741E7D7F4B7437480CDAF1D870C21
+:10DC2000B2ABBF43BD9CEBBF5196FC2551949E32D5
+:10DC30008756616276561249C3EFA59BFAA17C4ACA
+:10DC40005996837927422DA3AB616B08F2CDB000C2
+:10DC5000CF9BBA3F12ED5193997823D2E17B36E204
+:10DC600095D361161FCF43702C37D0A1A45594D6FD
+:10DC7000E87B4D811CC3428A847A68A2E35746B987
+:10DC8000AAA3289FD6CC742719C6C2F6DE5EB93B7C
+:10DC90000BB9F65288081AAAF7EE69198C2204EF1C
+:10DCA000F120DEBD7B80C66B953A15ECF09D7F6D53
+:10DCB00064B0EE3253795F9BC2EA8F3EB47725DCC5
+:10DCC00037936ECF7F14F649CCF65178DEE58FD5C9
+:10DCD000DCF3DD9B7E51D63972833F17EE05BE3AE9
+:10DCE000C0EEF51D6E0D7E778F7A78A345A9FBD126
+:10DCF0008FC86FD88F72ADBC7E3FB61BA04ECBA134
+:10DD000071FEDC81749F2F471D9A9674291DAFA167
+:10DD100030093ED97F35EAD01EF8EE3004878F57A0
+:10DD2000EE1E148283B4FCC33D2D93D570F8700FA2
+:10DD3000D8217D85C3AB0F7D8870E8EBBE295D6C73
+:10DD400007BC5C936DC0FBD6AE386CC1F80AFD45CC
+:10DD5000A03EE2E3ACEFE5BB6CC51FA1E3EC54D3FE
+:10DD600097F29E4257BDD14D2AB18F62F76C6AE996
+:10DD7000A72BCAF536ACAB25CA758F351EF78FF7C2
+:10DD8000005CE3763BA78E0BD135B1B8C7C1FDEE81
+:10DD9000A32CF35BA354F2F29AEC25620AC4C98166
+:10DDA00017E243FB895FE68D1841F719EF3260DE19
+:10DDB000FC288BFB20CC632B08F82177EC0AE21EB1
+:10DDC000278821BE50E6ABD9C1FCF59A42836F3952
+:10DDD0003BEF1560BC107DB4E9E823C0E8A3B11D9A
+:10DDE000E9A3A2A99DD14763754E64063B37033F63
+:10DDF000BF9604C602DE3BA2BE9A2651FA1F1A1530
+:10DE0000A801BA91BDE7A6E55D8A703D1D163F7C6D
+:10DE10007DCABE7AC36F6D4BCA4369E04FEE33E0F3
+:10DE200079970237A55F8C85E5C5B658DD5F03FCA1
+:10DE30002A27B4ED85ED6F6D791FF3366CFB6ED834
+:10DE400005EFDB66530C3942F3D6EE5B8EF767D7EE
+:10DE500006D87DD8D124E005BDDE3B3C18FF04E1A7
+:10DE600001764F1AC0A31DF96513FF5E2CAB5170EC
+:10DE7000819E1F1AC5EE0D89B4B0F3EB211611D7A0
+:10DE800039C4C2CE59E2F7BD2582BF9575BF01FBEB
+:10DE9000C74399A6DEFFFDBCBFA489AF2BF854E8A9
+:10DEA000894AD228B87FE44C8C3BD1A2A19FD8A844
+:10DEB00014D578CA7B8F7888F30EAA47AFD83DFF78
+:10DEC0002ED0AB947EBE00FC04FB8D9623006E4AE0
+:10DED0007FA0CF70F8A1EF0D87F9601EB017B6ECE8
+:10DEE0005E22E23D1A7DC46B26DC1B49FB6746912E
+:10DEF000AAADF4FDCC685A423D8ED713797D202B14
+:10DF0000533F711A04FA7C3D8FBB4EB6F0FC31C909
+:10DF10003EEA86D15067765C565224EA05856FE169
+:10DF20000E0838B796F8F9754A20C5007853F858A6
+:10DF30000A18FC56AAB452248701F218DEF1D07DEB
+:10DF40004BBDCB9DAB2F65DF71EA9FCFE4EBF9C1F1
+:10DF5000F6F5173DBEEF9E09F02D37B73D7203ADC4
+:10DF6000575C7A0ECF079747555C79A17B2FF4EB6E
+:10DF70007FE7FCDB5140874DDF98C27E0F55C3E140
+:10DF8000D6E229C0F732F9BD2E2451C93356E5B186
+:10DF9000421BB7CB109529F81CEDACFF401108F8D7
+:10DFA000F44AB1F07E54329E1F4ED1E5ADFE879FFC
+:10DFB000C5F932C130002571C92836CF37CC4E3271
+:10DFC000D3FFE09C691A3F177B4772AFB0D2F1DEF6
+:10DFD00021EC7C3533AEAA19EAC4C4C6CF26DAFBDD
+:10DFE0000A32136BA7C6C2B8D1C918DFCA35EBDA3B
+:10DFF00053BD12C869929A8C7989D388CA3E637AD4
+:10E0000003EDEE08BA2E90E3D78C2C744EE5EDE7C5
+:10E01000E8FF434DE4F6992A7FE32AC75CE7548D75
+:10E02000FD528BF701FDE99FE2EDE1F22C3EE3FCAE
+:10E03000DFE2C977C2F9B31E9E390EE17EABA3279A
+:10E04000DCF570D4C35D81AB1E8ED99F38A7C68620
+:10E0500081931E2ED348ED48D0630ADCF57079C752
+:10E06000CCE8E29D3413DEABF88EC4E0F80E352325
+:10E07000A11EA49B6811EF01CE8CE2F53747B0BA20
+:10E0800082EFA864C4B71EAE7A3866C6F1F7E358CB
+:10E09000FFBD002F09E502E247A19BCCD4AADD31E8
+:10E0A0002A7A50ECEB691C2ED4BE46FB3937DE8A47
+:10E0B0007126B0AFA72584E0965BCED6953BDCF207
+:10E0C0003CF8A9F475BCBF720AE13FFF143C2FCAAB
+:10E0D000E45505CE53BED1DAC9D39AA69F8238C380
+:10E0E0005093FB7EA0CF801083E77514EE477470C9
+:10E0F000D7BE67D7D6F570F803FC31B127BC143A08
+:10E10000FBC0C2E34E03C820B097C7BC96110DF206
+:10E110009B34C5868D4B5C71383F380EA757A4637E
+:10E1200081B883CFEDA93F428EEDA35A5225C73661
+:10E130008BEED396F89E724CC1D3648E87C9C4BB54
+:10E140000BE24B9389F445D01F480EEDBF5BD9E736
+:10E15000403210F67983C5C1E43FDF6770DFD4BC7D
+:10E1600084F9B3F8FC59660B7E5F4302524710CE28
+:10E170002978DF91D7181B5A8792BF4F86541166B2
+:10E18000CFCDC37BAE295CC87751A17598AC828492
+:10E19000F7FDF0759CA9337B218FAD5B7447819DA2
+:10E1A000D721EC1B83FB93FC2340FFE9DBCF35EE4B
+:10E1B000AE8076DAAF08FBF1F52F1659FC21B0C31B
+:10E1C000E47B3EB9773B95B235EA09857EB3E0FB47
+:10E1D000D4CB81DEFD0361DD5340D5D172E759F622
+:10E1E0001D437663BA04F3ECE96679FF39C42581EF
+:10E1F0007DABA7DFEF4BA7A178456008F8298A5DC2
+:10E2000036D5EA1E69A5CF57F3EF669BCE8E18056B
+:10E2100078F9C1F474404B4F0A1D51BA1A0FF0EC53
+:10E22000CAF8FC6930C7DFCD3897007A51B1DF43B7
+:10E23000768A6B02ACA7373B7E89D53DC57A013B18
+:10E240005EB1672EE68790DDD441A674741BC7CB00
+:10E250003C73ABCCEECD0F60FEFDEA48E55E3B477C
+:10E2600024D891B7AD4ED95407E786D52CFE7E6BE6
+:10E2700095ACF183DD90DD86EFB3FB666F5FA66D35
+:10E28000FF4C60FE7EA157FB9C581234F7EDF69CC4
+:10E29000D7E035C0BCC323313F413FAF7E7FFA7921
+:10E2A000F5F3ADE67ED56A63ED48A7CA2E596065E1
+:10E2B000F650F7AAC7EBE0CABADEE0E7360F48939C
+:10E2C00054F7ABB5AD8E2C08776F8C329E02EF7988
+:10E2D000C4CFE20055F2DFC3DD839BE566F181DE4A
+:10E2E000E61D16988A76A0E149BF08F6FCB0004109
+:10E2F000FB3B2BE0322CD0F801CC4FEEE107C0BD48
+:10E3000026B45ED6B08BF901F5D5E84F94517F0263
+:10E31000F4CC7A389B1EC0179486FE41D0DF85FC72
+:10E32000A92CB8CF92FBC312A597D45AD67FA3F5D8
+:10E330005DE36A09FC5577924C2963E3C3EFD798F4
+:10E34000A95F55934C2208F5AB5E78F8FDE96BC0E8
+:10E350005F8E7509707F28ADD758FAF7DDBFDEF8FC
+:10E36000F0FE1AB86F94FA65EBAC2A7FB737FE78E7
+:10E37000048C910BF047BA3D7F23F0A112AF688A5D
+:10E38000E07C1F11A4BB6880974227572F9B8F7E8C
+:10E3900045C425E787409E5816C7FF162B8FC346F6
+:10E3A000B1F79F12DD5B90BFDF3A3F02E2CBEF8C0B
+:10E3B0003C8AFE5C9395C5E7F7794AD07E52F0B966
+:10E3C000CB2A703FC93F10F8EDDAF1CD71E09764C8
+:10E3D000C902DE43DA24FB9E4CCF007934DBBE82D7
+:10E3E0006E296BA211BF136B8AF00FBC5B65A7355A
+:10E3F000F1FB4C9BCEEE1DA8CE631E66CDDD6545C0
+:10E40000FAF38B307E56C6EEC3A0EF7BD32F21FDEF
+:10E41000E112407F90F3FB13F0FCA8618F0DE24204
+:10E420001DFC7E82330DCD09F36959BEE52F36F010
+:10E43000D7DEE7703823B5E23D4A65DB44BCFF8395
+:10E44000CE9B700BC4A71B1664B2EFF7D877678A10
+:10E45000FE4CFF67F3C07C1634C4EFC8147B72B265
+:10E46000D9EB83F535558B182F9EACBB376C0ABFA3
+:10E47000374C6F5F9EB42A71E904CC875A6A67F300
+:10E48000F4C64F59DFC4129F8ADFB224BF08EBCF16
+:10E49000FA2681C01597675A529EC8033F9EC8CE80
+:10E4A000E130AC4476A3FDCACF9FE86F37DC43BEB2
+:10E4B0009357DE6C3837EB4A2466FBFD970960778B
+:10E4C000B9FBB1E022D3078A7D37E51B6D7C556F20
+:10E4D000E7E6348DBD7F204178B37FA722C0EE559B
+:10E4E000EB61FF06A687B57B09790CE190BE2DF59F
+:10E4F0001AB84729FD8F063BCCDB027C110FF83C94
+:10E5000087F7FC5410FF8DD05ED120DAFDB07E92EB
+:10E510007119F09562372870693CDF6C1E43D79102
+:10E5200075D6605F4E877833F005FACFE3FEBC2FD7
+:10E530000EF4575340C27382ACB3BBA316A8E46079
+:10E54000D379033E7FF3FC5BDAE781D8CBE0BD2DC6
+:10E5500006E617EFDEFBF728904B6F9EEFC6F182C1
+:10E5600076434FBB18E1916B15837167B55D4CC461
+:10E57000AC0390B7352D9AAA31A177BB37FB137244
+:10E58000BF95F4B41F72C01E11C3D8111CCE743EC7
+:10E5900009F8486F575C6EE3F1E6C1241DEEA36CE9
+:10E5A0003C1FB718BF1F6E8AB22F477DCCECA5AEBB
+:10E5B000DDA71FBF069EEF13D9FD11E745E4A7B7FE
+:10E5C000762E1EDAA6E25B2A39114F5FF53FDBF9A2
+:10E5D00006EDFFD59E481647979C97A9BF7708F58B
+:10E5E000F77178F907B0F338EF00B8D7E907DB2FF8
+:10E5F0001D3DFCFA3C1BDAC381E9A01E46AC6B371B
+:10E6000002FE5BACF9D7D990DFEAA3002E5E92330D
+:10E61000904C80F37A92037415A82676F027B6B54D
+:10E62000180C80978C8DC998A7B3899F572EAAAFD5
+:10E630003526ABE862113FEF3A297B87C4AA9E1FBB
+:10E64000B031F972724FE96F304FE34313191EC6B0
+:10E65000DE6CB0317DFB8AD17BCD66E877C480DF8C
+:10E660000DEDDEFBFA5EB8CF78D161C75888FF3D6B
+:10E67000627360BFC67D9B6A20CFB7F113D052543E
+:10E68000AF6C28140D74DE378883C5EF0E18D01FC9
+:10E690000FC63D892B0EF6F9105FCF1B2D06CDF965
+:10E6A000D81BFCDEDD7B6D32B62FB18988C7AD2D5E
+:10E6B0003971A0375AACEEBB6DA02F8EB5D5C01204
+:10E6C00094789F62AF4D3CB0F59AD1F4CF891D0686
+:10E6D0003BA0DB71E07911F6EB3849488C407AD8E1
+:10E6E0006F743C8F7ABC373AD878741D6F01BF2A9B
+:10E6F000F0A79AFFA1345A7FA3558A85FC2E05FE08
+:10E70000CA3E94F91DF5C4B5DE82ACE4DA7A81B86C
+:10E71000B3925F3ACE4E947F2F01E9D268733D6A7F
+:10E7200063F60EDAD727F730BBE815AE474952E15A
+:10E7300050809F82A77A1B8B332AEBE96DFEDFDBCB
+:10E74000989E54CAEF4BD79B648717E9661BCB0F83
+:10E750007778FDE654C8236B4CC57FCF499567FB9E
+:10E760007BA4E793DA7B051BDB0C06F80EAC628713
+:10E770001083E66D1FEDEB209D49F5487F8D8709DD
+:10E78000F27169DD9D2CEE48E50DBF7F0DCFD18183
+:10E790007FF8797A7F8196139BD6AF1888F0F5DBE6
+:10E7A00080AF4270A27C036555AD11E875D1525619
+:10E7B00016F373E9456BDDC89F45EB587EE11E5BA0
+:10E7C00032AEE70CA75762881C00F9272E0E7F6532
+:10E7D000DD799C6E4F353CD10CF352FAFA13E0739D
+:10E7E00052E3634FC372157A3DB541C6714A22B5F3
+:10E7F000E7F6AD7CBC6D0718BD4FDC20E7C0FD5FC0
+:10E8000013BDC40E71EC37366C14417EBF01F49C0D
+:10E81000CCF81CF4EDC93D0F46FD02F45CBB814011
+:10E82000BCFC152329D9A2E28BDDEB5FD5F06F6923
+:10E830005DF53518976F8B1540CE2B7CABC0FD1561
+:10E84000A3F32AE4FFEB74FC3F95BD2F473BB0DFF9
+:10E85000139CFF9F9841F99F3E8AD91023C038AF7F
+:10E8600018C3DF07F7F50FA4BFA05C6DEB2157BFFE
+:10E870006672B5CD964AE7AFB8B61BE30CC1F57129
+:10E88000BA7962AA4237C902C0BF96627018C08BBB
+:10E89000C215E899DACDB7DF90865CD922E1390F4D
+:10E8A0003F47E2F91FCA77020ABF86E499C2B76EF2
+:10E8B0007334D8D553AB56805D1F97E745FA3C2596
+:10E8C000B887C6527D760AF8388C3C38C1E5C75700
+:10E8D000B2FB62F7EE0F007A2EA11E22EC87AC137A
+:10E8E000EC8017A5DDB18EDDC33A3C5AD09CBF2B1E
+:10E8F000F51F0CEF408FFB418747637C3A60843CF7
+:10E90000D5113EA6C7889083FC400C570F003E5B94
+:10E9100044F5D7CD2AFD754AAE453A55E0707934B5
+:10E92000935F5FC5B07DFF95D38515E285AA732FF0
+:10E93000EA904802E36751607C2EC2F8A7F64CBA11
+:10E940000AE9FDDAF0F46E07FF2A16FE3DA7F54846
+:10E950009F3133ECF81DCB1392332246631FF9B07D
+:10E96000DCBDF157E8D701FD02BFF746FF2540FFA8
+:10E97000240CDDFB28DDABF0A7D001A58B6BA255E5
+:10E98000F2414F17CA79A302975774E7954F47335F
+:10E9900079B080978E5EF26694FDFC603C9FEC81BE
+:10E9A000E7F90CCF21BE027C2BF2E16717E1AF3D06
+:10E9B000D1766CAFF97401E6A9D4F273AB7A3E9FBD
+:10E9C000B2EEA5D182E67C4B7FEE34CAE2BE2B5A72
+:10E9D000773EEA480BD1C7346ECF2ED968C273FF99
+:10E9E0002DD00278DBCDFEBD6CE53DBB440D4F0A5A
+:10E9F000EA15D14C8E2BF4E1586624C3A8FFF255DA
+:10EA000072E16EC8FFF959AB376F34DDC716A377D3
+:10EA1000F6B5E80738AF82F1AFCA33D8211F24C654
+:10EA2000651720DE81240A7CB88FCD332ED5791965
+:10EA3000FAC90EE73890070F737C29F855E0D09B90
+:10EA40009EEB0DAF7B387CE279BB5E8E1473FE9E2D
+:10EA5000C2FB5D5C8E7845E0271B712F1761FD5965
+:10EA60004CFE05E54816C173C9977572E4E59F5ED3
+:10EA70008EBCAC912313DAC2CA11FA0BCBFFF11B87
+:10EA800016A21D4B0E87B7637746333D1C0FFA93D2
+:10EA9000F68BF7B2F3DE8739DD528AC4BCC9DA0DD2
+:10EAA00026CC1357E4906D36C9817FAFD906FA168C
+:10EAB0007ACD761F9E0CE7C54946079C5F9F92035F
+:10EAC00088F753D401AF45FAC8C7FBC7C3C82302B0
+:10EAD000F112EF4783D0EF9C2636219F2C994650A8
+:10EAE0007FEEDE7805D255495E8A00745B5A1723A3
+:10EAF000407BEC54BB01E494B28F2B9619C8B071E3
+:10EB0000C80707D472E40A6F15FEBBCD43E3DC49A6
+:10EB1000720C21471F3DFB3375BCA88DD6D5F12261
+:10EB20005A7FE0FBC48B8E46071E8078D13F6CAEC7
+:10EB30007698779425FF28EAB7C42A91A8E4D6C529
+:10EB4000ECB71F4A2F953C2E455AA9344ED0C481AC
+:10EB50006FAB73601CF82B584FC580E34FC37078C0
+:10EB6000AF46587B9BADA31F970BE41382F8E89741
+:10EB70005F2542FC45913B067BACE22F0B9097A1B1
+:10EB8000F0DB7F031C7DB5D7008000000000000093
+:10EB90001F8B08000000000000FFCD7D097894D590
+:10EBA000D5F07DE79D2DCB2493C9427626ECBB039F
+:10EBB00009ABB14E086090040710448D380990B03D
+:10EBC000640391D2D6968120068A182BB554B10ED3
+:10EBD00014FA51451BB61ADBA013401A143456AD73
+:10EBE000D8AFA561911D8980FDD38AE53BE7DC7B29
+:10EBF00033F34E26026A9FE70F0FCFCD5DDE7BCF4A
+:10EC00003DFB3D77492D63793B22199B90B350ED35
+:10EC100006A9C9CC3C161B831F2F6343793E7A0893
+:10EC2000E659986B20636BF27579DE018C5DC79FA6
+:10EC30003BFD69A2153E8E676CFED630EB4933B5BD
+:10EC400067D7E17F795D8C265F599F643DD9C79F67
+:10EC50009F8FBF24C1FF334CCF12182B63E2A7E173
+:10EC6000CBDFFF7018B4C7DF55C6DE54DD89568090
+:10EC7000A7DCDC12D5DDCED833F9C713DC91D45232
+:10EC800087DF3D22C67871B9E3BDDE718C79DE5530
+:10EC9000D916C80F36193D4A34FCE264766B82E817
+:10ECA0000F7E9406C5671904F97F43552C6397FEC0
+:10ECB000ADA3F4C59FB8F232E0FB8A7A9D6339B404
+:10ECC000AB685018CB62CCD19579CD198CD58547DE
+:10ECD0000D62D05FCEBE48A701CA2F2966AF298337
+:10ECE000D100088741C23FA2357D1BD4573798D841
+:10ECF0006AC85ECA61AC19E1D53BA2D9003F7E0764
+:10ED00001D7EA60FCC00CA6B1D2E0B639BC278FF25
+:10ED10009BC2647B7B3483B4DB92D1EC04C0A7D765
+:10ED200033160DF481C48369F6926E03F499301F93
+:10ED30003DF318804ED9AD3E15F1D2ADD5AE6391FD
+:10ED4000FE71F4AD8CE6DB4D6FD73960FC3A81F78C
+:10ED50009D4D3B543DE073D898DA6A15D2D228F71E
+:10ED600058C4F3A8ECAA6A2C8FCDF7A86E689FA5AB
+:10ED700054EDB3005ED878E6D802E5CC07838F84E3
+:10ED8000FA16D61805D998232DCE28281F75C6D96E
+:10ED90003800E61DED620AF6C7D8321ABF5FA4CB71
+:10EDA00085FDB238A75200FD0CFB0723BCC87E7658
+:10EDB000368D56EC006F5CF318C51EC05F304DE217
+:10EDC000ABF5CCFE53ECD77348E740BADAEB987357
+:10EDD00023B4EFFA72BF312CCADFBED2AAD078B703
+:10EDE000BBDDB94646F379D80ADF8F9CEEDD6700BC
+:10EDF0007886CFF1EC33DA03E63397517F292D1E65
+:10EE00009A47D211770EA68B2D31D4CFA833BEC628
+:10EE100001D0AE4B15CC07CAD39A3F5410AF6955F9
+:10EE2000CD0AD27167D35E8237B5793F4F8111EA3F
+:10EE300020DD01725517308FC5161DCD63B145A178
+:10EE400074E5C599892EA87FC4EA5E6C19EA9FC74C
+:10EE5000CA1C776215F4BFBEA95BFB7C7B02BCB702
+:10EE6000C1678827D9DF72AB91FA69B2B87F84F3A2
+:10EE7000AB9CDE7200796F47D39FA3482E1AE288BD
+:10EE8000BE09878E133D129600CEA078FDA1850A9B
+:10EE900083AAF5854033A5239E27B8DD8E31998856
+:10EEA0006F809FF8C71A3109F8F2628CBB06C791D0
+:10EEB000ED2714D922505FB4E7C577CF2E658E5960
+:10EEC0003D00CFFB8B77B26E4877F712A47B7BBBFC
+:10EED000818F87213F318BB316FBBBA4B0E938CEBD
+:10EEE0004B9842F94B069E97F8FAAB95E3EB11EB82
+:10EEF000A4C596788E272BF0F14B61BC5DB01E7ACD
+:10EF0000D7CABFB30B7E61CD9C5F701EA8BF64BB28
+:10EF1000DDA2DFDB9DEE5C3DE793CD08E7C811DEA7
+:10EF20007DC8B7C3F33CFB90FFD398E0933CCE275A
+:10EF3000C1FCBECF6AA37E469D696588F72C85B962
+:10EF400002E92ED3D710AEA1C8DFA3897F401EB639
+:10EF5000E378C352AA54038012C7AC135877C6DEB5
+:10EF6000B6DAA95DE608E73EE437ABD345F27C208C
+:10EF7000C24AE52B33387FC0F77F40FC05CBD32E48
+:10EF800094A3017E398A437E8CECC88FBF13F0BCFA
+:10EF90002DE4A563FFEE3F61FF71CD3AA7029D0C02
+:10EFA0003F12E965D074F8A22A15E18F63C0FF0013
+:10EFB000A06D8E3507E52CA5CCA1205D9B225C873A
+:10EFC000ADD40F23BDB93247E7AD86EFE6463B89A6
+:10EFD0007EDFD83EEC676636CC6F1FC01EFC15E1A5
+:10EFE000037BB0B608F5F46FFF69443D6A97F2D72A
+:10EFF0003424A238803FAE48BDE0A7F771D20B4160
+:10F00000F40ED673C1F4F6EB05AD9E037C5DE0F41F
+:10F010007067229FC5352F52B97ED0EAB5CEE8D1B0
+:10F02000413F083A5C8A707E81F85C0C3288E37A52
+:10F0300046B33E58DE991D0E8B89A476FF453B1CD6
+:10F040001613DFD10EEBCCAD0715C04779836A5795
+:10F05000610AD58FD99C48FF17EB148709E5A441B5
+:10F06000257E78716538D94B09EF67BBA307B1DB03
+:10F070002015F2CFDCDDC98E56C688F1ED9087F100
+:10F080002F5979D6687527C504E893171BBE084326
+:10F090003CF74F64034EC6620BA7D60E830829F0D7
+:10F0A000BD097F5310AF836B5414AC69EE9D269558
+:10F0B000E8D61DFB1BCE5AFE9C0D70BDBC6DB4CEB8
+:10F0C0001DC837F55767EC05F82B23B85DBEB4F7BC
+:10F0D0005A2FE433597FF79262D27B3F072B1913E3
+:10F0E000A01FDFEE7382EB6156683DD51F87762A3D
+:10F0F000D723008551E63E7AF427D47087AAF527F6
+:10F100008839AA7B027E107F8DE184BFEA9E20773A
+:10F110001904E748EC7FBFC5C892A0FC0AC823B613
+:10F1200093707F03784707E2D10F6FAAF55484E00C
+:10F130000BD50F5F3B5D900ED0BF6AD1D33C2EB193
+:10F140007007D2B3CEE864487FCF51E11F08BA55AB
+:10F15000089EBBD430F4881BE6F7E29154077E7F0B
+:10F16000A9FE4A982E12FD46F7149C979AD61A8546
+:10F17000F6705FC395BE2D0348BF4DC5F22B874E79
+:10F18000D8DC03BED1FC6684A687767E95FAC89A41
+:10F1900040FF50617C7EC17CA43434FE4B1944F2A4
+:10F1A000C7501F7AD299B71AE6BD72A0E0A77B9923
+:10F1B0001DE53E98DE46ABAB2226406EFF15EDAA5C
+:10F1C00042B8709C942134CF85981F747866A6410C
+:10F1D00087F31BC3D06E4A7F0FFDEFB0217EFF4E39
+:10F1E000CEAF7DFE3DAF0D3AC468BE3FC67100F89C
+:10F1F000E53A80AF128CC1EA8CC079FB881EE562CB
+:10F200007EE5E6489F0AF361BB0C175AA41EE8D6B8
+:10F21000117EA04F0DC2E719ED38E246FAFE35D255
+:10F22000518DF8D1375BD15F85F9ACC67A36A2280B
+:10F2300011E7DF2FD2B905F5FC4BCB18F1F3A55739
+:10F240009877134C76FB7E1DF1CB46D68FF8BE9F88
+:10F25000EEF20C5724C9F33A843BABB956877AB720
+:10F26000A7D7AE437DDAB7B94EA7233E70FF2286FB
+:10F27000FCE49957F4005FFF6D55EA37E4076F68C7
+:10F280007EEF40AFCD81F49278CB167C908D7843A1
+:10F2900083D0AABFD062F6E30DE8C3526C1DFB63B6
+:10F2A000AC251DF1D4F8FAE95E2DD05FC51BA76728
+:10F2B000205E2AFE60222618F387BED1C8EF9FE5A4
+:10F2C00084F6672E2CAD72E8C19F7A25A61BD985DE
+:10F2D00032D66C443FA1BC6E81431FA0CFA5FF7600
+:10F2E000C8D09C8FFD1F1AAAB26580E72B8EE15D06
+:10F2F00058083BD1EE2FA1BF06B02F47D811CFAF92
+:10F30000674573FFD146F620B8FDA1A5731C637A4B
+:10F3100074DEDFA1C161D3BDF07D7E901F743486A1
+:10F32000DBB5B6186E8741213B11CE8BBFB7783D58
+:10F33000507471C847510CFDCC5D1F647A808F2ECC
+:10F34000B2E647FE8872763592D671F9833FCA5C81
+:10F3500066F1CBE51D23F8DCEF78ED70941DDAE75C
+:10F360006FDF17E709C0DF1D4C7FB59DAF33705CC1
+:10F3700046E3337D4B2FA407FBE3D9043BA4F9AF4D
+:10F38000BF15C7F9204187745E24F4DBEFB028C0B5
+:10F39000DFCE5F52417C24F3E56D66E68D0DC8EB50
+:10F3A0009B8DB8042E6F8B645E68B737C612477AA0
+:10F3B000269925A39EE9145F3789CFE07289CF4350
+:10F3C00083CFA6A35FF15927FE706F1B6FD7CEF7CF
+:10F3D0004BC14FD7FBF3EF7CA53EEC0AF15D848D6A
+:10F3E000D3E98A636417F4F7F28DBE1ED610EDE4FC
+:10F3F000FA32184F6F5F2B8DC07E7FDF66CA0B0518
+:10F4000097DEA6FB767ECA21802AC01FDCA6BA53EF
+:10F410006DC21F9C0CF98ABE57C6D1BA5AF28BD066
+:10F420007B77304F23CA6F307F487AF7B001DDFA1F
+:10F43000A372662948B78B3176CE37421EA47C046E
+:10F44000E331389D6064EE50EB80AF62245EC39878
+:10F4500007F4E1231B0D64DF0F5FFBF8DE4CE0F7E0
+:10F46000D31B0CD6E530E49C17F6A53E03F57306D6
+:10F470009BAC0AE44FDB7D3D50EE4B5F505DC80F07
+:10F48000A7373C923013D2F320BF650047E946030B
+:10F4900095CFD9F828959F15725DFA427C7FD49755
+:10F4A00087F7AF4E403ACEF9EA89694897ED466B47
+:10F4B000FFC190966D531C6302F03D6F739826BF99
+:10F4C0005DC7E6E03C245D99E26EAF47133FD5A6E9
+:10F4D000FB76711F9FD6DF04FF72AAA0E3C4293018
+:10F4E000EF8AA157C8AFDF77209CECC99B912AF91E
+:10F4F0008FBEC1FFEF9DDB209FFB95DE41BE9DA02F
+:10F50000F3584167B05CA4B74BCC3C9FFBBA9EFC60
+:10F51000CF5C8B4AF886F69163A1FE7BA2BD0FF407
+:10F520002CCA2153B3D78D847663A30D0CEDD0F78D
+:10F530007CF3F219D8C93BDBF4C75B02E6339AD5FA
+:10F54000F6417F38871982CA9D7A2CCF356BCBC79D
+:10F55000F6B8FB2CFA0F63ADDA72C9778FD8B4FA1C
+:10F5600062DF81733F9B00F32B39A492FF7C237DE4
+:10F57000FC2EC2AF473ABF5DB80DBE3B2CB072F84F
+:10F58000DAE91549C857231486F1ACD3D742CBE347
+:10F590001FA45E6640DF3E7EFA1638E6B6E751DC11
+:10F5A000EF19B1A03D8FF0DFBC1EFB7A3D759B8D3E
+:10F5B000C73382ED46B0DCFCB7EC46FEE0B7D23D87
+:10F5C000164A7F83E985ED5CEF06EB89603B21E11C
+:10F5D0000A86B7BC4DA7B10F5FA11E191A68278C08
+:10F5E0006427BEC3F570836D68C7F530F831842F8A
+:10F5F000CF303DADC3C1DF6AC4760322EDB139001F
+:10F60000D20A6BB708B27F16F77E5B401CAAFFB622
+:10F610005A1DEA8DF6F88C411BA791EBD577849D96
+:10F62000A813FA1CD6ABB4CEDF18EE4ED4E3B8C99B
+:10F6300046C7968C8EF8F948B4EFCCCF957EACBE19
+:10F6400086FBB18F585D9A3819EB93A889FBA25FAE
+:10F650008EF2EDD91B4EF3FC54710D4239D433E7D1
+:10F66000DF6D01F4A93670F883E1898FE576923178
+:10F6700017F907B27CF6E8D07A5C89D553FB9C6712
+:10F68000EF4F47FFEDD3C607D251BF7E1A14E7ED07
+:10F690004C1E9E16F2FAA4B02331222EF014CA1189
+:10F6A000E441DA9DDBE1FB554B5D24573F5D3A9D1C
+:10F6B000D267962EA1FA13B60C1ADF9AF367577722
+:10F6C000C0D3C9352AD989D94657AF18F8EEA459FD
+:10F6D00047F18513559179BB22B19CD17A72F6B36B
+:10F6E00013B67802E27E276C7AA24367F38C8FFD13
+:10F6F00066FABD9CB544A1BD6AE7D7231DECB52DC4
+:10F7000016E37FAC2501DB552ACDBDB6291DC7B751
+:10F7100032677C2CF29791F547B9A90BE7F628B828
+:10F720005D4A2CE7C3BFA11F0BFD7E8A762B849E0A
+:10F73000B10B3A2FB438EDB1A4EF22C95F27B881DD
+:10F740005FBE8C727647B8605DD613D3615D787CFE
+:10F750006EB1C52AF8C3A9F0758EAB5F6C88F85BF3
+:10F7600067F19E6038DE11780D8E03C954C681861C
+:10F77000C6F2F9BC6DB36AE24218FF0E15FFF979C3
+:10F780002CD7A31BC35B3C2ACAC3037C3DDE25DB0D
+:10F79000A3607C2B25BF3607E35F77C5F2B8A52DA4
+:10F7A000CF9D88EBF6E444A303E336372B8F03EABF
+:10F7B0009C7C5FC0AD2338D6377BC27A015C09CD13
+:10F7C000EE1C23A45371310DF8EDC2AA9621DDA0E1
+:10F7D0001D21236B7FB857918B6C689229F42840C8
+:10F7E0001A8672678C724F45BA0C9B55558D71FA0B
+:10F7F0009432BEFF70567177B5019F9C7D2B3CA45F
+:10F800003F5C22E8CF94D1C968FAB3361B08AEAC8E
+:10F81000CD3F9F817C9FB5F92EBD12A08796C71A58
+:10F8200068FE67DF9AD795E2169F9858CF107AEA5C
+:10F8300087825F1E1074D8690CCD7F8B45BB6FAC7F
+:10F84000CF5B405569F5F9E2D880385B45F965D260
+:10F85000E79363ED34CEF3FABA03C980CFE767319B
+:10F8600087078AE66DDD48F1D79DC6BAF1B8EFE4A7
+:10F87000A9D031A4FBFE037F38908C7EE42CFB6082
+:10F88000F423DABF3FF4D24A2C7F7E0E1B8CF84F54
+:10F89000F23EAD603CE69F61B584AF7F6E31B165ED
+:10F8A00018B77DBF6EFC0F21BFBE4CC750BF04CF41
+:10F8B0001B4632E81231F519742338FD510F4ABA4C
+:10F8C000030319911E926E88BFED90EEDFF21AC10C
+:10F8D0002FE19A2AE2DEF3B66E1F8F7C925C6653AC
+:10F8E000304E20E1BA913D7931F6DBD993EFD00E5D
+:10F8F000BF121B222E1DC20EEF880D618783ED2FD4
+:10F90000B3387763BB1BD9E1E182FF36C606ED7FD2
+:10F91000E07E5908BA0D8DED100FDF1F1B62FFE36B
+:10F9200046F1F0DEB172FF431B0F7FC9C8F56FAD22
+:10F930008D3D3C2984BC7413E3EBD6B51AD17EC649
+:10F94000352821F5D9628B51EE1F7E1C1BB05F124A
+:10F95000AC8F43E0F728B6EFBBCDB7175B0D89E955
+:10F960001181EE5BBFEBB0DE0D31CE29813FFB2272
+:10F9700046FBA6F62A46FA0AF25E1E14F42914374C
+:10F98000B0384F93DDBAC1BED59DD61CF283E43E9C
+:10F99000D554ABD64F8C8B93ED9C9F239C699DD8FF
+:10F9A000897F093CC1FCDB70DCB8454CB31F23F7F1
+:10F9B00061E2AA3C8A310BCD11A3F86AD758F7321D
+:10F9C00003B46B1DC91C9B201F5D68CD417D6A9BE4
+:10F9D000E368C4FD9A9517793C7EE502E65D4EFD2D
+:10F9E000F0F93277372FCA17D22D302E1011C7E118
+:10F9F0008888E3720676D21CC7E10A8F0BB0939217
+:10FA00001EBA753E95E8DA1ADA4E05D0D546DF778C
+:10FA100042D7EF502EED7137E71FF78CBB05BE19AB
+:10FA20001877737CF3144C4BECDF048F9789F30F3A
+:10FA30001E0FF82C2BEE26F8ECEA2DEE8F1E8850C8
+:10FA4000BE5DDCA5235E27C485D0776BF2757D484B
+:10FA50005FB3704728BB3A232EF2BF7D5E6486A059
+:10FA6000F72D9D1779F1272D46A4B3DCF790F0060A
+:10FA70009F1391E5150D4A26AE3F73F65DA375C041
+:10FA8000A5C67FD33AA0E3790F3EEE42E403806738
+:10FA9000AC3AA0CE07F277799B9156EA2AB3FF22BF
+:10FAA0001BE3F64D06E6B5537B33B6EFC778FB7E16
+:10FAB000DB563663DCAA1FD37BC47A54B9CEFDA8CB
+:10FAC0006894E37E4D2A5B8DF9ADBCBE8A9997613F
+:10FAD0005C3A7A848ED903F019E30C67F6007CC691
+:10FAE000E6D93479B94E9E2FC68D77256BBEEF329D
+:10FAF000BD9BA67D92BB9FA63E65CE104D3EAD6AD6
+:10FB000094A67D57B0CF81F90CCFDD9AF6DD6B2638
+:10FB10006BF23D6B1FD0B43FCDAA9ECDC6797A9CC7
+:10FB2000CD3D00CE5902CEDEEB8B35DFF5D7D50DBE
+:10FB3000F3A120F9141FEEFFCD166C324BC473FAFB
+:10FB40007AE769FA3DFF6A5E9302F89D5D6B3819AA
+:10FB5000189F217C007E4BEA15F61C8C5BBA5E5B1D
+:10FB60003FA7E1E9952990CEF56ACBE7E1BE9C82FB
+:10FB7000FCAD2DDFAD733D82EB9DED7122CE28E211
+:10FB80003DAC037F44D2B89737F07897EAE91DC4BB
+:10FB90001F5A3AB16FC92F76C12FA6442DBF84D901
+:10FBA000B5FC527A70E7301FEB88FF883E417CE459
+:10FBB000817F017897F895F8B738B47CF55DE19DC1
+:10FBC00031AF91DB0D6DF93FE2B4F1B57E91EEE31B
+:10FBD000A8B7AED42F5271BF8DE5F17DFB2BF55741
+:10FBE000071DB26BF6D73ADB4F3A1717185717FBBA
+:10FBF0004997703FF1367613FB89FBFE85F800D9F3
+:10FC0000771B801FD80887B97DFF30CCBF7F14AC2D
+:10FC100037650A76E3CB38B227FE7DD76AF87A5883
+:10FC2000F45F5C08AFDC8793E772E4F92116C9E75B
+:10FC300029FB013CA8F143F1FC9F2D02D7ADDBF776
+:10FC40002FA4F5963C3FC4C4B9BF107E3FE9EF3AFC
+:10FC5000FC3589FC81F0786ECF23316DF707C4F94C
+:10FC60002E69CF3BEB47EEB775962A7B55DA3F6C92
+:10FC700055C21D9B42D8935EF1DF72FD75A6431CF1
+:10FC8000BA577CE0FAEBD12B07D0AE00DEFB62B9AD
+:10FC9000C502F65AF1DBEB5F444411BFB61E54BDFA
+:10FCA000BDA1E0B2D91E6D033C368469ED884CAB32
+:10FCB000CCC903F4B158AF3DE727F71183DB676385
+:10FCC000FB80FD27F84EE38FAC1CC2FDB5EC786ECF
+:10FCD000DFBF88E4FEC11491AF0C5A1755D670BF30
+:10FCE0006C23F8E90D01FD4C89B750FBA511395380
+:10FCF000E2298EC0D7BB2B3314F227562A0AF921EA
+:10FD000067A24753FDB5B89CC9C43F629C29E8BBB4
+:10FD1000C1FFDA6E1C1EBB388F23FB37C7F3F6E634
+:10FD2000F8D1944E89B78AB8B3B51FF2476584936A
+:10FD3000FA35AAA1F7A5A6C7F379ADB530E9276AC8
+:10FD4000E2FEE384DEC438BF89FBA3F96313FC71D0
+:10FD50007EA6667F688C13F17D853E77A29EBA539E
+:10FD6000D0BDB378BFB38F753F6E27758CF7FB128C
+:10FD700043C6FB1DE328DE0F5FEA715EC1717FA4FD
+:10FD80004384CD2F3F8FC4B7DB8354D44FF54677E0
+:10FD900035AEBB5A7783FF0EC57DBC2DB41F30F046
+:10FDA000507707AEAF5666B0BD16E4B7658CA17F3D
+:10FDB0005FDFA25B1E06F56B3CCC8AF52337F0753E
+:10FDC0005BE97ABB03A7698075B065885F1FAC8B60
+:10FDD0008F21BCD7B74C6EC4FD8135F7321B9AA179
+:10FDE0005A569B1B85FED0061672DDF89490B30917
+:10FDF000397B55D417F1E8DF87A0D353824EA00F8B
+:10FE0000D6229D87B7BAAFF0FD38AE4F4825E2FA4B
+:10FE100074BFCE1B6A3D3F373A771DF2C1406FE891
+:10FE2000F5C35A0BE7B77511AEE7A8DD2E7EEEB528
+:10FE300054EADF593AA607BA4F11749DB2819FDF89
+:10FE400060D7AE5F57A59FC8A87F867AA5F45E8B62
+:10FE500017E343A50D191E82CBA5387AA2BE687898
+:10FE6000DF85F9D2AC2C2BC6239C7F65CAA93EE462
+:10FE70006232AEBFF4EC94D42764C7E368DF69B2A2
+:10FE8000E0B7B5163B3F470D288E00FC976E58B67D
+:10FE900017CFEF7CF46B46FB4B47D4D661D8D954CF
+:10FEA00040CE922198EA5921C52BF8FED5BDA21F5C
+:10FEB000CFBF615CB37FDCA90D07693E470CCC6303
+:10FEC000063EBAB4E73E3BFADB2BE3CD14C793FB07
+:10FED000B24755F7E36484F4AD1508DAFD0D115609
+:10FEE0008C7FFC43F05D46827B1FD2C7BD7C7C05C6
+:10FEF000DAC19665A674C4A37B79921A0770BAD743
+:10FF00002A34EFD1CB938C787E61E68AC1E3504FDF
+:10FF10000D61CE9518DF7928968594D3F3F17C9DF9
+:10FF2000585C6560C6689A8411E32F176B148ABF0A
+:10FF3000E0FE5B01D0678E985FF9AAF7A3883FECDB
+:10FF4000F06F181ECBE53F73AA4A491EC1CE6BE481
+:10FF5000A78CD51993A09F796B6039DB8DECFDF1EF
+:10FF60000EFE43C079EFF23A6D7D255BF3399D7F3C
+:10FF700061E0EF5BD02E68EB3F95F2E8600EA4AB3A
+:10FF80007BB1C58CE784460BBC14AD51ACA85F6651
+:10FF9000AE688CBF0FF2339B5407F2B4C40BEBE88E
+:10FFA000EFD3398FCB4D3D693D70D96EEF82EDDCDB
+:10FFB000515CFF2B7AF7702C7F28D63D1CD7F1AD12
+:10FFC0009F58189E9B39D606FE18C61ECD6C10C5CC
+:10FFD0001FAC6CD0A4003B5A64B02660BCDFC316D3
+:10FFE0002632BEB7650E9C77A5790DF98195E80795
+:10FFF000F2F9911FF8502C67D5D6D7153A9FC3EA6E
+:020000021000EC
+:100000000DE4079A851F78D65E9B00AE17733D6E90
+:1000100020392DDE16437E68F18A5C23F26FF1AE43
+:1000200018D243E0077ED863989F8EC756641E4857
+:10003000847E8BEB321CAA967E5AFFB8E698A45BAE
+:1000400047BF4F4BB793A1E806F4D294A72408FF0B
+:100050004ED08B3D164B7E47E182B77A9A019ECBFC
+:10006000556174EEA833FF83A5C6D1BE9E5C17E62A
+:1000700025B7AFDF68DFFCCA9AA144B7607AE5FD17
+:1000800067E670B427ECAF16867AECA1EEECE1C916
+:1000900050FEB0C2E5EBA1EAF17928A759095C6FDF
+:1000A000BEB714666864ECFDA566E6ECC5D8074BE0
+:1000B000AD94FF686922E53F5E6AA7F493A57D28A9
+:1000C0003D29E26852CE8001885F472570F91A9574
+:1000D00020E2DE6C5122AA8CBCFF7C305467C5A1A3
+:1000E000D2278C4D63EC1E272023C0DF997E6F043E
+:1000F00012B93DDF62B08E4B44FF719542FABED813
+:1001000075BBA63DF825463CFFCDFA64FACBE99CC9
+:1001100098DD3819F8F0FEFC584DFB6935299AFC3A
+:10012000E4043BCD7B525E774DF90385FD35F9A2A2
+:100130003640029E2F30DBF8FEAAD8B767CCC6D770
+:10014000EB56DEF66AD5F02EDF0778AF1E32507D13
+:10015000303D245D67ADD731378036733DCC0DFA25
+:100160003D593B93E4EAFC110BD9FD95DB32DF1DD1
+:1001700001F963DB0CB4BF7E6C45EC5ADC3F3EB644
+:100180002D3E8A41EA5EA9321FFAC17AAB9105E899
+:10019000B7DC15CBE8FC5691D7E440F92FDAEFF93C
+:1001A00095CCDBD11F4420513E3E54BD3E85E8E74F
+:1001B00024FCBE14E6DD02F933A0AFF1C8F8CC167A
+:1001C0000ED71985ADC0FCD9B0BFF5FA3EC071B1EC
+:1001D000A0B64487EB01F5503CE9CB1D2A43BE2D68
+:1001E0005C60A0FDBBB91FA91B31CF9421299CDE07
+:1001F0002A9D47642F99A87FD60A1C02ED16FDD6CA
+:10020000B489D6774CE4770FF4AE16FC897C74265B
+:10021000863963085885E03DF77EFC46ACF7E3D3AA
+:100220003B08E7FDA5DEB53201F8EB5C897710E904
+:10023000B5C7E249AE82F17ED2C8F59607E540F136
+:10024000EB4BBF9C2D273E9D69702438485F652588
+:10025000A1BE3AB9C640E79899DE193589D63F3B29
+:10026000888FE53827F5F67108DFC99A0C86FB966A
+:10027000C56B54F20790FF787B2FE7FFA755371B1C
+:100280000EFDD6286ED6A523DF3CB260389D639A5A
+:1002900021D641C17AE0339055772F7F7EDE1E7ED6
+:1002A000CE8665B5E8EF1D18388F157CBC44DEBFDF
+:1002B0003C0750D6ED4F47D1E5BEDCD43D1AEDF0FA
+:1002C000D90F55E2B3B3DD6A8725023D2FE8F60E5C
+:1002D000FB3EE4CF17784EE921FF54B87B6702AEAE
+:1002E00057746BD2956E783EF6C4DADBE1BB73AF20
+:1002F000181C24E64BE2497FCC7B696ED7C0F38E95
+:100300001DF5972F99EFBF389314C0E77C7BDD383C
+:10031000EB005C77BB841DE2F8B1E3E62AE0C5BAE6
+:100320004EC143C3ECC450CB6A3C773D13C4243068
+:100330004E7842EC8F1F107A45FA09115D787EA63F
+:100340008EF3377B5521BF0D7E34FABF529C4F94FC
+:100350007A5FEAEB32564BFBC14712F839C6B98ACD
+:1003600097DA55E0CE2EA8A8122B0F42976D35795B
+:10037000BD19D49735D00F48EE62E7FB43C6579EB0
+:1003800045B62D65CD7C7E41EDCE19BC25CD191D20
+:10039000ED4D8975E30A1BF56F7060FCA454C869C4
+:1003A00079ADE2F5F17990DD94F18AD9C26E06DB80
+:1003B000A70EF628C80ECD0EB2B3AC566B5701DEB1
+:1003C000481C47C21B0CA72BC24278980770A1BDDE
+:1003D0002D717B0F4C24B8150750B2033CA5CC35CA
+:1003E0002606E701F53E7B47F882E7D5015E31CF6F
+:1003F00060B84B1C9FFB70FF18CF8751BC29681E4B
+:10040000921EC1FE9AA44B8987E3B7A441217A7E4C
+:10041000DAEE07328A1B497E8105509DF67BD74470
+:10042000D467A5EB40FF66F8F947F2D33C56178531
+:10043000FC52C17C2B9350BE7C75D346A2DFBEE13B
+:100440007D23CA49A1CDD7531783285CFBD3BCB405
+:1004500080F544109E6F44D76F8A379C955EC6BD69
+:10046000004FB337ABCEB0419A76E21C9187E4607F
+:100470008EC763C4F8C61CB1EEBF119C957A7E6E20
+:10048000FC86F076E2277D5BB8F3BA68FD62BF9F19
+:10049000D5333A949E6AF7AF82ECFADF0C3C7E21AA
+:1004A000F5F155BD93E225502EFCAE2A2B8F9B070C
+:1004B000E9F1B42CD2E325C2AECB714EADDF49F1E8
+:1004C000B7D968F703CA3F5DB793E2FEC6576647E0
+:1004D000A1FF7D6AFDCCB578BEEBD4B69964E74B3D
+:1004E0009F9376DE6D0CF41F72D717BDF863E4DFBF
+:1004F000AD61149F2FD9EF16EB1ED0ABD0CEBE9EB0
+:10050000EB51B68EEBD552B48703C81EF6C6768B78
+:100510004BDCBD510E02CAC94E2E9EE9FEDD1EE81F
+:1005200077F1CB110E0FA1C2EAD391DF6EF5A13D99
+:100530002C5FF8F1513CE70EF6FFA31F48FB0FD9E3
+:100540008D7AF7922E286FC2EE97AB1BD3ADE827BA
+:10055000083BF15FC0BF3934FE8710FE8B11FF01ED
+:10056000FB20C76B389E6706E1FFC41A4E9795DBE8
+:10057000BA47E1FAF1784D77F2B38E6FEB49F89F05
+:10058000B51AF0CFE35F5A3FAB06F08FEB08C43FDC
+:10059000C05BBCDF2EF0EFE0F8AFE178676B783A34
+:1005A000AB039E3D748E61F1AF4D0EF41BCE84F90A
+:1005B000C89F3AB35D65D5017E98F483BE60B5BF30
+:1005C000427F4DE27F6EAFE641A87F0A9FFE531443
+:1005D000D261EE761EA4EF807FE6EC82FEB87FFC4F
+:1005E00076BFE9952EF1017ED34DD2A982B918D9F3
+:1005F000C5863F1DC17583E2844F6D788F46DCD779
+:10060000A8D7DED7C0331985368C2F38CC6684271F
+:1006100035F81E8A9B611CF99F3D3F9FB190E4BC59
+:100620005573BE6D22F319BAA0FF58A7D0FDC6F2CC
+:10063000453951390CE3D45504C7E92E8AE6FC78D4
+:10064000B9AA23FFB1CCC8FD48B93FF9AEF00FDE1F
+:10065000EDC2D725EF75B1D27797C218D9814B1665
+:10066000A317EF23C07A2A11C7F7EC3111DD8E22D0
+:100670004C807FD528E2366002914F1F649C4F1F4B
+:100680008C6CA23839AC545E40BBF8D0129383FC1A
+:10069000DAB8688AD73E20F4DD83912B5D681F1E8F
+:1006A0008A343A31857E3D7888CE301A8687F10DBE
+:1006B000C946BAAF53686E790597BE0F279E78D4A6
+:1006C0000CA0DE06EE37C655E0D75DD7633BD2C53A
+:1006D0004F1F6D9CA7323C74DCA355E04B713A2947
+:1006E0009E6382BEC3018E2B682FB1DC6EE5F19D47
+:1006F0000D40278B9FBEC1E5CCC3F703CAF05CE376
+:1007000028C6196404E15F932F33F2FAF0C4AF26D0
+:10071000ACCB66ECCFCC3E10E956863A04D7F74511
+:10072000D15E8C97DF83F1251BA67AE297C97AE622
+:10073000D1F1B42612CFCC8978D34481CFA92398A4
+:100740002F1AF0EE3BA88D77DDE7D3F97A037EEF21
+:10075000D1FB1A913F7566BBC10AE3B8F29421B888
+:100760002E295B7E73F0A6259AF3D7A5425EC7CFEC
+:1007700085B5FE80C7211E046145BCCDD0B3FDEA1E
+:1007800010CE0788974A9BDD43ED1628140F95710C
+:100790003649FFC1D07D201D1F14F0413F3551F86F
+:1007A000BD3134BDFA26CAF5731DADABE70BB99B5D
+:1007B0002FE56D9B56DEC627DAA9BD827E30E0EDBF
+:1007C0004191762617E344FFE312B95C64DDE278D9
+:1007D0002CB2359DCEB708792937F1FEE5F8F788B8
+:1007E000744CA28DFA95F000BF1EC77E74A00190D4
+:1007F0005F4FD656937F348705C4B533FCED245F35
+:1008000077CCB7EB11DD754C8DADB310F5CAF7C2DF
+:100810001CA8471F34D6F5AC8AECD84EEEDB14B2D8
+:100820006603233D29E261C2FE8C5523E97C40A189
+:10083000C2EF0F5ECAB17874D118A73110690B638B
+:10084000143A3FF137B17FF250F4E28928D785514D
+:10085000463DA633582BF5FB776BB7E8FB18DE3324
+:100860005631760E038FC877C2B8D5A877787E8DBB
+:10087000339BA24A227FC72127E0E1DE6B407FCA7B
+:100880007F2FDF09FD5F7A4BD4B33BE9FB4B8F0B26
+:100890003EF6E4F2FCCF657D1ECFAF92F5F93CFF4A
+:1008A000A4EC5FE49F0EAA5F1654FF4B9E5FBC3E14
+:1008B0003FDF837EEB68CED285A314D2537B84BE08
+:1008C000285CEE23FC16EAF6F27434F3E9B26EDC2F
+:1008D0006E53A26B0FDA1FD572D282F6F7D564275A
+:1008E000E59F4F702F4BC475D424C563447DFBA195
+:1008F00097ECC1C44ECE1FEDE9C2E3F89B92A0BFB6
+:10090000A17EFB05FDAC4E8CBFF57E1C491CAE8064
+:100910007E9EF926F0FCA7233C1BBE493FB392B54F
+:10092000FD487F484975BE86F36327E334E745E613
+:10093000FFC4118DF12786E74500F5F397D7A5672A
+:1009400042FFF35F7D3DBD04FD2561E72BDA74CCEA
+:1009500089F734DB18A5E71B3F31E27DB38A5D8D53
+:10096000C671D0AE12D2DC00B8CA049C60E7F49322
+:1009700003EC7383D01B8C3DCDF7375F3DAB477ADB
+:10098000CED7D59D7A0EEDF62825E43ECD66F1DD75
+:10099000D14ECE17EF157AE86A9AB311E7F96B8C4E
+:1009A00021403EB7BA93FB60491C5F85C2EECD1C67
+:1009B0006631DB01CF433FE4FB54251B3286603CAC
+:1009C000F8CD84D1EF247E6D3CB595C7531B783CA0
+:1009D000B5D0D6BC089437332695AD31DFC1D88465
+:1009E0005F48390391856FF34C325F9D3F269BC76B
+:1009F000BB307F76FD636B506E9AC2B91FFBD0F09F
+:100A000081E1A8175A3222745690E737E38B8C495C
+:100A100043B1FC8E71589E63B2F42A22FC32E28B01
+:100A200037E35DC7905FB03DC641DC465FFC7D307B
+:100A30000FF7DB2A9DA7750F8A7087DA77FA87C0D0
+:100A4000AB31C94A69139019FD1709871C1FFCF9BE
+:100A500045CDD0DFC9E5498357DB719F25C7903469
+:100A6000D43F7E4682FB72E0F82775AC172E296EC4
+:100A7000168E4B020E03EE5D03BE5DD92A7306ACE3
+:100A8000F3268F89D0E4EFCD8F65CEC038EDBD2938
+:100A90009AFCF4C2EE9AF60FCCEAAFA92F30356774
+:100AA0005505F8B19DFB491E82A7D26209477FEE2A
+:100AB000EF0D5FFCE541F4FF36AB0EF455E7EED9E0
+:100AC000F297DBA1D5653C4E45F1473BC5CBCEC97E
+:100AD000F3287AA73E705FE8226BA6F33E9DED03F4
+:100AE000C975EE7CEB7E3A77F65DEF03F54A12EBC3
+:100AF000DD216C08DAC3CB551F51BCAE2292CFEF7B
+:100B0000E2EBC78CB80F8AFB8AD781DFEFC20FD127
+:100B10003F6CF3503C3BB7FE18ED9B1D48E47ABA9E
+:100B20002275811EEF1D55428A76681CE8AB68E08D
+:100B300097E646367017EEBB6658B81FDE3699B199
+:100B400058E42B1EDF694A88A17BD7F36BF2A8BC5F
+:100B5000A22D9CFA7F4F6D1E47E7095F5368FFA1E6
+:100B600020E5A1E5787EB829DC33E01118B7E077FD
+:100B700077E521DE2A76F1F3B505EA9FB316405AF0
+:100B8000569B47DF17A8AC49017F61422EB7BF05CE
+:100B900068F321AF0EB3AC46BBAB1A7DBD9E473D9B
+:100BA00063B4909E896E7B80C6AF6C33D3F7F72415
+:100BB000717FD7D0C2E11ADBE6A272C90F5393BA94
+:100BC00069D60F86F8CD7A7C97C3D0C2A8FDDD6DBB
+:100BD000FD2895F37DBBCFAFE93EAE21FEEAB81408
+:100BE00098F7DB718A95DC90203D7CA56A78340B00
+:100BF000A1A7DAC769E3E7F44C6DFCDC5E618A7398
+:100C00007E12C031F1B1163DEE07B148B315F13592
+:100C100071C4607B49807CA97BEF37227D0CEBDEC1
+:100C200037A29D36419A1B505F2ECE3304EBE90567
+:100C300049524F2FA354DA1D767506F9A933AC82B9
+:100C40000185FCCC10FA547EDF4C6B1AA0E36E1EBB
+:100C5000C77F34C5BD02F545730E9BBE83F4667332
+:100C60003AEEC37C57F0039DCD0AF9892D741E75A9
+:100C7000E208BB0EE3FFAB045C528E6F348FC5A25B
+:100C8000FD7B2A5B82FDBE77E79DCD4EE8AFF14745
+:100C90009999680FE4B8CF25F17B29CCDA7A0DD782
+:100CA00083956F44D851DE0B703186FB9D7B4CB42D
+:100CB0004E8172DACFA87CC3B409EF895446C17A59
+:100CC00015C6CF7D33CC877CDCF866981EED46EFE9
+:100CD00074F77348CFDC377B8FC1F5A1B3C1A4672C
+:100CE000E4F7389F273DDB09BC37D25BC17C26E5A2
+:100CF000D35DC3E5A548F069B1903FB790A32B55EC
+:100D00005D480EAF3C0640E33EE963CAC05DE8279C
+:100D1000D82DF47E9394CB025C0F417941FF183AB1
+:100D2000FF2BFD8D60392C6BB352BFE56D7621EF43
+:100D300036CA4BB92B167263127EC62CC1E7BB5361
+:100D4000DCEF205E0AAA41EEA3681F3F0BE5C9CF86
+:100D500037462BF217F04D624980FC5437DECFD076
+:100D60003F31C5B9886F66411AE89FCC6EF74FAC2A
+:100D7000E31200FE892B327478DFA99D7FDBF9E650
+:100D8000E6F87F8F9097E2485F4FF4670D55610E4C
+:100D90003C877E398EEFF72C5CC5F1B8D0E0CA45B0
+:100DA000FF62E12F158A97A1DF817A69D8912A63C2
+:100DB000601CE5FEB641CC0E7898D2D683D23713AC
+:100DC000DC47110F456DD304BE067DA3FDC5A14EC2
+:100DD0001E4732784D8E8D19184772AB48E733693C
+:100DE000CCFA4CE07EDE7A1DC5C3E4BEA38C2B9901
+:100DF000F0BC7C801DFD425F9B4EEF3704C79972AB
+:100E0000B8DDBFB0D94076BFACF1CFC374507F2EF0
+:100E1000C3D905EDC9977A771BF2F5BCC9DE570D2A
+:100E2000909FFFE4CEA891763F3EEBF4BE9E6847CC
+:100E3000EB008F18EFAA5BA3E679B9BF13C1F7C91E
+:100E4000387F4B7E0EE6F3796DDD889FAE5499C8EE
+:100E50000E5D01BE65017648DA1DA9E7A5FD917C0E
+:100E60005DAEE7FAAB3C32DAEBC908B43B935C39D0
+:100E7000C8777DF8791ABFDDD9B47614CAC1A53810
+:100E80003AB728ED46B01CBCB6141CD35E1DED8EDF
+:100E9000D4EB52CF4BBB35FAE52F77FE15CD558AF3
+:100EA0007B4032E0EB6E3DB75F77EB2DC43F63E3F1
+:100EB00026E9916F6E5E8F1E137AF498468F5674F2
+:100EC00062070627DF9A1C7415EDF34CDC7F443D66
+:100ED0001FD8DFA329A3C7E03CC627733BFB5DC136
+:100EE000DD99FE1F9F7C6BFA7F58B288F7DD40FFCB
+:100EF000172673FD1FACEF9995BFA773694F5F2F3E
+:100F0000DA83A30CEC03DAC18608FB16610FC85E16
+:100F100084477BBFCE1E5C4D9B5988780A610F1EAB
+:100F20004AFE16F640F2A1941B2927522E82E5486C
+:100F3000CAC5849FC23A11E9F41EBF5750AEF76C80
+:100F4000A3FD467BC46094CF763F6E9742F2D6C134
+:100F50004E08F9F1CB8BD66E48B990F222E5A75C2A
+:100F6000C8C5EC20B9D8A7D63D330AF7CB92DD6BC4
+:100F700093E3FD7252B623D83E74CA57185964B32E
+:100F8000E3AA18F25539A4817C65EA441E9E49BE45
+:100F900035BF68D94DF2D36FFEFBFCF49B4EF8E9E8
+:100FA0007FBE0D3F75F4633FCEB2033C57B240DFC6
+:100FB00066F8F96DC23B8CFB0FDDF97A00D6970419
+:100FC0007793318DE23E13AEB32A8A2F0ABE947412
+:100FD00096FEC06C11773893E27A07E1C5F5C082BE
+:100FE0009BD37B4467535CB311D727B3210DF40324
+:100FF0003AF37F9B6F51EFBD7193743E96FC9DFB5E
+:101000008DC79243FB8DC7B1FC9BD2B5209789F861
+:10101000DE8F0B30DE38E1299167CB0A108FD34683
+:10102000C8FA9F3CE9EC81FA81C9B838C539DE536A
+:1010300045DEB3F4F018683FE119E68F9B43FDD815
+:10104000ECE8F6B888C2FCED95E71F3BBC86E8519A
+:10105000CBE5CCDDA2E7FB3F229F05794B407E44E8
+:10106000507E036F1FA56F6181E745909F94219C7F
+:10107000CEAE00FF0186DF7F05ED85556118D7A84C
+:101080008CDBF8D615D46BF50AED45B5E381D514A4
+:101090003853C5FBB9945F73D8093EC203BB78BE11
+:1010A0004F4AED931EBDE837E0DCBDA14E71D2B9C9
+:1010B00083118AB75B46477CF749D1DA27FCD16BAD
+:1010C000BF67781EEF56BE6FBFCFD68DBEF7996E45
+:1010D00061FCFBB2439F7FFE5E0AE7EF3159D121ED
+:1010E000EBC7A5A8BC1F1137A0F1A1684A5DE87B3A
+:1010F000B013C5B8CDB85F42F8DCF624E2B7D92802
+:10110000F1FDF293C8776319D3C4CF607CCADF9F27
+:10111000F272418D9E4FD71984AFAF9BEF8014A917
+:10112000BFFDF8F204D1CBF435F87684C0B75DFB8F
+:10113000BDEFEBE835ACC3F7826FE7483E766AF85F
+:101140003D5AEF22FE8C8E53ACE84757B8C2D6E02A
+:101150007AC12F9FBF27BE6C96FB031DE4EFB5023B
+:1011600094BF0A8947CFEB4FA2FCBA74EDEDB93CAE
+:10117000B6F33573F601BC52C80FBE7FE4F9FA2707
+:10118000312E097C41F594D707C01D2C8F7541F98C
+:10119000EC20F915F247FA03ED01E0A927EAB7B808
+:1011A00063467B009FFC4CD0E9A2B827DA3C9AFB4F
+:1011B00093CDDD78BA2385FB8FCF097C6E12ED9B32
+:1011C000C303F090AAE11F1FAE5B02E64D78BA3F61
+:1011D0004ECEFB93827CD063CD365EBF2DE5A32738
+:1011E0003DD9FE7C707FAFA67C528078F1F7FFF18D
+:1011F00061F423EE1778DB9172E4B02752D039C145
+:10120000FF4E21F007BD63518EFCA174E48F1F7661
+:10121000E44F4FD0F7F44E7767DF7B3A7EEF0CFA5E
+:101220009EE13DEA9BFF5ED02D3F88AE7941741D63
+:1012300013942F9479AF46FF4ABD5C5CFFF4E30939
+:101240007118DF54E838BF9F9F4F93BD996F95FC8D
+:101250007BE630F2AB9F9FCF129E27D709BA79CE9B
+:101260003D897A7812EAE151FEFC14D443943F5F41
+:1012700080FB617E7B7581EAEFAB91ED2F92FD7A69
+:101280006085ECEF33CA4B3A32CF25B277F70BBD0E
+:10129000C33CADA4F7E735F0EF3F7DFEF3C35F2B12
+:1012A0000FB54178D91094F704B55F7703FBB622E8
+:1012B000E8FBC782EAD704E5D707E56BB4DF17CDB3
+:1012C00052480E8B46F0FDC960B90CE68F2F52DAFA
+:1012D000E363EDF65C8924FF4E235713AA79FEFAE7
+:1012E000F3FF29A8890CC8A7B0891EB2EF305AC0F5
+:1012F000FD41D0B91E15F8C1D089DEBCD899DEEC0D
+:10130000136CEF79FD3FF0D724DA2FD2F825FB5488
+:101310006DBE51957047BDBB2832605F955926E27E
+:10132000BABAF3FD9B8889635203FC224FF84467E5
+:10133000C03C65FB715F5D5771BCF8D4F0899B714F
+:101340007F68B4D8D7B4F114ECA58AF6BA52C46F4A
+:10135000C6E1395D6C17EEEBB930D00F6275BD7028
+:101360009E8D3F52F9BB50D5401FC05311B3D37966
+:10137000D39978EABE3BD447472FF90D7CB7EF47A6
+:10138000EA12B4D34797C4D239A645A9DCEFDC17DB
+:10139000DD356136E41B231E267DDBF8C4584AF791
+:1013A000AACE95AD56E83A357962645FAC8F263C9B
+:1013B0003936C44F5C06FC9D996A2738DC366B428F
+:1013C0003DFADBAB0DB45F082D7E45FCF3A469301C
+:1013D000AEB78B96F5A7FDB0E29F4F1A87F7B08A9C
+:1013E0001F37D03E498BCE4A7122F7EAB1742E6A7C
+:1013F000D60A917AEEA2F4CDFFFCBA1AEF69B5BE17
+:10140000A0D0FB0E775CAD7B67109E9BACE94EF7DE
+:101410002EDE8075009EFB3EBEBEB717CF219F0813
+:10142000ABA273A4D09EEE8B955EB3BF3B310BDBBA
+:10143000ABD6E5D0FE1494A3FF7C6A95BA09EF41C0
+:10144000154559C2F1FCF6A9AF18C5754E3D6EA2FF
+:1014500077228E47BA67AC8FA3FBB8E8E9B3538A0B
+:101460003D4A013C4CDAD067626212969B047DFBD8
+:101470004415011E8A74EDFC43F6A42486E727A5D3
+:10148000F699B805E671EA97BDE97CD8C154E7E45E
+:1014900054C0D72FD29C5352E3115E6EB7DEFC0FBF
+:1014A000DF8FFCE385E204E4AF8752395FBFD1569A
+:1014B0009C10F8BE77C9453DF1C19B46FB227A27B7
+:1014C000303C4DC17536F0412CC6CD6789750BF0A7
+:1014D000F3929D21FCABE1A92AD1ABF1A7F1D94848
+:1014E0005F3F5F0F7F17F519AD37205FB121732D77
+:1014F000DAB993A625EC440FD67EFE91ED0B233C82
+:1015000019B68579C332307EEA1C87FCCD12EB7A9E
+:101510004DB604C8A168FF770F3FE7FB77688FEBF4
+:10152000BEBF7BFED712B89F21DB9746593CE85CD3
+:101530009CB658F4488FA3FAA5A7F03C5AC90B06ED
+:10154000B203252FC43FD68AFA07F806E36BC1F32E
+:10155000FA63AA81C7313A934BCF18AD5CB231130D
+:1015600071BE9DC965CD86DC899B233B97CB522BF1
+:10157000D74FE35EE0EF51960EB5E8717F73F40B41
+:101580006F6DA17B740BC286E0BD89D2174C44AF4E
+:10159000168BC563BD0DEF1358F431903E9BCAED19
+:1015A00069BD909F5C95E9CD4328A57B1272DFF061
+:1015B000EC92679EC5E397E79877DA70C0DF6527FE
+:1015C000E7D3CBBB548A3F06EF23961FDC69CC617F
+:1015D00037B18F7883FDC332D622DEDF0DFD7DF07B
+:1015E000FEE1ABA9C1FB8706BA4F5E2AF60F73373F
+:1015F000280477E9127ECF3F3796C78D4F2E05FA24
+:101600001B69DE1EEB103C0FCDED4E2953BC66F876
+:10161000F5AE0D0B288ED913F184716EF16EE2894F
+:1016200030473AAEF34B5E0823FC96FE6AEE5F7ECF
+:101630009985F7FA0AE202D7D5FB912F387E19DE99
+:101640001F94FD9C5EF6637AA731F745581FC37C53
+:101650004A63D8ABF76720BD92D2719F53B62B5D1A
+:10166000FEA35EBC1DACAF611D5DB44AE5EFC7ECE7
+:1016700036911D04594F6401F72C67AD38683472F8
+:101680003BC6128709FFDAEEBF9F761CEAF1EA6ECD
+:10169000A5B88726F127EF5115E9F8FB74853A853F
+:1016A000EE578126A37B499753B95F7B3A959F6795
+:1016B000284A77D0FD9CF2B526C7F20CDE4FFB7DA1
+:1016C0004F58DF95EB9A4B683FF3F7268AAB54AE41
+:1016D00008738645F1F3173B06D0F96ABD11F05146
+:1016E00066E7FAE2B2986FA57DD25D749F41CF8E16
+:1016F000E8A1BEDCC2F563790CE03D92338A6E1836
+:10170000BE67C7E8DC24F69B3428607C4594433FE1
+:10171000F6287FBF4D3A5683711B6CDF7710E2319C
+:1017200076DA7484EF1595E41990B47604FA7DAFF7
+:10173000A899B8DE2E5AB56F1CEADFF9DB07E38DF6
+:101740000956F4EA07643FE60BFAB7887367C59059
+:10175000C777B622D2B83CB9551E2F8A485334EF0A
+:1017600010C9FAF255061EBF073D8F8AA57CD9C75E
+:10177000D46FB9A53901F56FF96EC330D4D351696F
+:101780005C2E8B97A5651F01BE2A3644D3BB8365AB
+:101790009E0223E6CB6A15CAFBBF8B4F473E3DBF77
+:1017A000E2B528E49F1361BE9E68975A178439E812
+:1017B000DEA195C7EBCEAFE849F79566599B2DF8AA
+:1017C0009EC1AC45DD6DA8BF8F5A7D46AC3F5A9790
+:1017D000A1C3BCD36ACDC6BC537F1BE5CF8BF32D11
+:1017E000F4837CA5703A976DDB67C4BF4F3244CC5D
+:1017F000F7E22B1FF4C2F84F797A732FB42BC0078E
+:10180000BD5210CF2F2964972BB6F1F3EE920F2A19
+:10181000900F40EEE6093EA8D8F5DAF7511E2A905F
+:10182000FE433AF211F0F37E2ADFB1711CE3DFEFE1
+:10183000473E91760CF22B0C368CDFF17C661AA7B2
+:101840003F948FE1E59E01FC1C5DFB39048D1C7407
+:10185000465F571AB787C5CB4CA46F5D695C1E5AAB
+:1018600056ED8E42FA5D7C65DF01DC6729DF0156AB
+:10187000DA1E421E043E2A71FE51043FF9179538C4
+:10188000DF28FFFCDBF95EC86125E3F393F3ADD4F9
+:101890008BF9CB7AF1FD24C12F654CE06B576F2E8D
+:1018A0007742CE508EE9BD0E313FB74DFB0EE5F7C6
+:1018B000C5FCDC2265D6BA28C40FD217F50F3E103E
+:1018C0006994FA049A5CDCBE91CEF14B7A49F857E0
+:1018D000093840DF39636C7E3AB674F24E6495E0A5
+:1018E0009B638F7749AF07FC9DDF4ACF6C11BFEA3E
+:1018F00003C6937C23C7CB7D79D2DD386FE8DF87C1
+:10190000FDCB718F7A22F4D8CF51C6E543C22FE5C3
+:1019100032B7FAA1BB074761BB8B96EE0370DE9C22
+:101920008EABD2ACF4BD13FD05F8DE59AF50DCFA36
+:101930009858E71F7BFCB5A8E2017E7E7F427C279A
+:10194000F90C7F303E26E16DB2F1387030DC520F79
+:1019500049B8739FB8EF6E2C97F0E3BE51209F4AB1
+:101960003C4A7E95F7F582F996784EDA4FB573FECC
+:10197000AE4C3D46E7773A9407F727FCA213E25CAA
+:10198000796B3CE371FF1589FB35F78A188B0CB432
+:101990003FD28EC0CF1A7D80FD69BFA716E73C8B72
+:1019A00074BB90D68DFA3FC7EA8C39D06FD999E6CF
+:1019B00071F8CE9DF443EFB8EA53A3315EB58B9F27
+:1019C0007793FC5276613FC941B9B8FF54B4EA83BA
+:1019D00082E1C8EFBF35D0BE4ED1E3638DE8DFCFE3
+:1019E000DD327318A201EF41A05E3FBB796826BFCC
+:1019F00059604D9886F721363F33ED01289F55AF4A
+:101A0000D2BB0DD80FCA6FD1A399145F3D11D65226
+:101A1000300AFDF81FA856F4E36FDF32F4316C7F13
+:101A2000BBA56B0C3DB6B13996F24E7D34D907E9B2
+:101A3000F7CA7380D5E2DEC75F84DE3FDC9E2AE210
+:101A4000FC5F752FDC8F6FDD1846EFAC141AED7557
+:101A50003E1C6F4F175A67541AF1EA23DD5B25BF0E
+:101A60006C8E9199938650B93909CA0F1A9A1F45FD
+:101A70003B72F051CB607C3F92A9D78615737F9A59
+:101A8000EF3BC66ADF2D91707C24C60FEE4F7EDFE0
+:101A900084EB081BDD4FA4EFCFAEF8ED34B48367C1
+:101AA000B7F6B4E1BC4FEF09A3FB03A70DDA77CF7C
+:101AB0006EF5DE57F07D29796FF5749AD68F93FC19
+:101AC0007EC37B377FD39E83BCD1B9A50B4B19DD79
+:101AD000FB7E398DD1F76322BEDA89E7084B6A4D68
+:101AE00056BC077312F91EF7B376ABFCFEA599CB73
+:101AF000C1C9DD9974BFB7E46F3C5F52A778F13E6E
+:101B0000F2FEA79FA0F30AB3C1CFC4AB09EDFEF369
+:101B1000BAA7A7A1385C76B857E27DFECB5BF9F98E
+:101B20008A0EEF321CDC7920C9DEB9DFFC5DFBCB0D
+:101B3000320E119FAEBDCF2FF12CD74F6F023F8CCD
+:101B400018E2C7DB674BE790BF7C61A99BD24BCA09
+:101B5000B1B5B7231F5BA2E9BEC01FEB9F51F1BD1A
+:101B6000A8F25D83AFE13A78546434BD93F2D9D2E0
+:101B700025B48F7A616915A592DE320E77C7AE461D
+:101B8000FAEEB3FACC06BC9FFB4664B4B003B69041
+:101B900074EDECDEB19CD7B91F70FA4AB8CF6D9DD9
+:101BA0001985F36A7C3EB66124D23522DA8A7E5FDB
+:101BB000A93847726A3DF7ABCF98A37F930FF43DE6
+:101BC000B3614A02BE3737BBF1DE69585EB247B136
+:101BD000E27AC0B1675214AEDB3ED5B744E1FDA84E
+:101BE0004FD7CB7B555EFA3B54A3F2D8146C3FCA57
+:101BF000A767F60CBE758D7C32F2829EEEBF9E8783
+:101C0000728A935C0BA73809FCC4E2B991D9AFF38F
+:101C1000F84AFB3A57ACF36E17F37E34DD26F73102
+:101C2000A83C77042F3FBD61E744ECEFEC668315D9
+:101C3000E1FE6CB381FA9F07EB331DC07B662B5F1F
+:101C4000F7601ED7CB67B7F2F5CDBC3ABEBE295FB1
+:101C50006070F2FBA25A7ECC0D6847EFFB74F25E17
+:101C6000C83C279FDF3CB09738DF60BE8D6175743C
+:101C70008FEC9B9E170DE6DBF9925F857E68E7D7B8
+:101C8000CEF844E013E51DF955F2C3BCF57CDFDE68
+:101C900056373807F94EF247F03B59D546C6DF575D
+:101CA000D485D37BB89322ED06B40F53E25AC620F5
+:101CB0005A3E4EE77E809AAB73E2BD37566D0AF905
+:101CC000CECE8A74EE57457465C4EFDE742B3FCFD9
+:101CD00029EE7FC914269286767B5284ED0B3B3425
+:101CE000793AFDAE7BF4C0CF936EB73DDADDC1D853
+:101CF0002FD30BEED1C37C2665DA767783FCF3BF56
+:101D00009AC0F3B7D9861A20BF4C9978CF18C8D794
+:101D1000A73B9F4A0F18E7EC962E69383F28FF191A
+:101D200096D7C5BB7F8E69A5B80F7649691DB424C7
+:101D3000C3DFFEFD3D96A37FB4FBF32D0696EE18A0
+:101D40008079097FE8B425DDF9ABF4F88EE5C58C20
+:101D50003D4EE7F53CFC1E0EFCB8CC09784F8AF3EB
+:101D60005BB1BC975313742FC7C1EF9FC9FB52F2ED
+:101D70003E545FFF7DB20DB7729FEC9281FF1D2A2A
+:101D8000C5A9BD0FA634FC89DEF9A9F6B09630A22C
+:101D900083F69E4D39BE53771BDD0BA2FB874C6F3C
+:101DA000277D3357FA3B68AC87F9DF296089FCFC53
+:101DB000C1A3821F4F2F653D7A80E89F7FB739CA44
+:101DC0000E705C98E8EB85FA2032DCFD27C4D7E979
+:101DD0000DD5A90BE3F01EAAC9910FEDCF78F97DBF
+:101DE000CE32E1B7B2CDF1422FA8BE3BA15D534642
+:101DF000DF4D6887DE177C7521C397FE23D42B192E
+:101E00007C9D04EDE83C5DDEF2BBE2B1DD85ED4F8B
+:101E1000F4980D709B0006BCA7351EFA1C61A3F751
+:101E2000AA984AFBCF5EFE7E929E79A26CF8EED510
+:101E300033E9E23E11DD13947492F8EF4017181A5B
+:101E4000FD599D991910EEBE6C03FDFD2F491FF938
+:101E5000CEE2C2DD3CFE427724451EE348A7CDE238
+:101E6000EF9F75B08B6F91BF0A62E9D1E89F0D3388
+:101E700043DBC9111B8DD8F5776D2FFF9D2EFC928A
+:101E8000C16C70E03B92A5A2CD58B5D08EEF5B2D12
+:101E90008C37D37B250B5FE84EFCC196FC9005B6D2
+:101EA000631B62895F5666A884FFB9F58CDE1D2A24
+:101EB000A84FA6F394F9F5364AA3DA12A9FCEC6F01
+:101EC000DEC9E27A89D3A7E07FBA8CA6734BFFD331
+:101ED0009B52D6D97BA79166BACFBBF020B76B0BCC
+:101EE000A7CABFC7C2EFAFBB0438AEC81A8A0BB9C6
+:101EF0003ADC53E7EF57BAF0BE007EE734507D6717
+:101F0000EF574AFC9A04DD82DFB39C7A303391DECE
+:101F10007F14EF594E17ED9AC5BDB3CEDEB5BC4F59
+:101F2000B47B226A5C13F2DD746769C8772DF59E75
+:101F30003007FACF86D4487A47E13E37F8979AF5CA
+:101F40004C8B1EF1302D9BBF733975BAB6DE90FDF8
+:101F500039E97343768777920CA88F4D2E6DFBEC91
+:101F6000AEC20EF5657DBFF65DD15423D94F3DBE9F
+:101F70003B0BF969E25D51F40FD1FFBFECB410FFE8
+:101F80009BC43BB8CD2C2B11F5C2ADBE27FBFFDBAC
+:101F9000FBB1C1EFC406BF03DB7FEB424D7E60DDCA
+:101FA0000F35ED6FAB5FAEA91FEC5BADA9CF6CFA3F
+:101FB00099263FB4F9394DFBE1473669EA47B6BC8B
+:101FC000A4A9BFFDCC0E4DFE8ED63F68DADFD9B690
+:101FD0005793CF61EF68DAE79A3FD0E4C75AFF57CB
+:101FE000D3FEAEC4139AFAF1F6F39AFA097DAE68FD
+:101FF000F2058E2F35ED3F37BA577745BF22EA0CF1
+:10200000F1AD3A4361F844F9E5A62966D4076BBA05
+:102010000A7D24F86FB9B0D3AC07A37BAC63D56C51
+:102020001FF15F3DFFBBA0C1764F7FDEE5C4F81F07
+:102030007B8DDF6B8B067F521F307E8CD3CC02FFF3
+:10204000EE5D6C9E55938F77256ADA77996ED7D4BB
+:1020500027B9FB68EA53E63834F9B4AA119AF65D59
+:10206000973835F90C4F9EA67DF71A9726DFB37681
+:10207000BAA67DEFF56E4D7D5FEF1C4D7DFFAD5532
+:102080009AFCC0BA259AF6B7D57B34F5837D359A8C
+:10209000FACCA65A4D7E68F37A4DFBE147BC9AFA1A
+:1020A000912D5B35F5B79FA9D3E4EF68ADD7B4BFE9
+:1020B000B3CDA7C9E7B0839AF6B9E6F735F9B1D63B
+:1020C0004F34EDEF4A3CA6A91F6F3FABA9977ECED8
+:1020D000843E9F6BCB85DF53E0F897E6FBF6F76E07
+:1020E0007728741FEA5CD76EF27DC5963015FD2403
+:1020F00017C5996C781011F515DE27B7F1F33985FE
+:1021000014AF8A237F884C941DCF0B81DF1085ABE1
+:10211000B68C0CF4AB23FCFE5BEAF5CC9BF7DFDA64
+:1021200084FFDCD5EEBE88F231AF6EFB387A9F9823
+:102130007956221CF2FDBF7783DE6D95E978F3199D
+:10214000A60FF0170F86D5A60EF99A38C178F305B9
+:1021500086EFC1B6F72BE222F8C7BD1706F4BF160B
+:10216000D617F8F7236B979AE96FC7FF6CA995F21A
+:10217000EB962652FEFF003A29BF47008000000080
+:102180001F8B08000000000000FFED7D0B78544518
+:102190009670DDEEDB8F249DD07975779EDC3C490F
+:1021A00048089DF0D8003E3A216040C0E635044919
+:1021B000A4C1A84143BA81F84F7475BB311002B273
+:1021C000B391D11095C1860164199D092EA3D1093F
+:1021D0009AF09AE03A4C601CC5D91937A0A3E28E58
+:1021E000101EE3CFEE8FC37FCEA97B93BE9D0E382A
+:1021F000FE3AFFF73FFAFBB4385575AB4E559D7369
+:10220000EA3CAA2AAD5E898922636DDE1C4A9FF3EF
+:10221000DA9998C9D8366F31C1DBBD0E82FDDE7206
+:102220004A777A9D94BFCB5B41F01EAF8BD2BDDE67
+:102230001A4AF7793D54FE92B781E09F7A7D94B6B1
+:102240007B9B29FF156F0BC107BC6D04BFEAF553DB
+:10225000DAE1DD4BE91BDE762AEFF47610FCA6B757
+:102260008BE02E6F0FC187BCBD041FF19E26F8982E
+:10227000B78FD21EEF6794BEEDEDA7F277BC57097A
+:10228000BE8EBFDB19FC2ACD9FE431263097E67A5B
+:102290001EC2CCC92632F600FE4B82FFE24688CC35
+:1022A000C2D8FD8CFF3ED7B09A76139477FEF23FEA
+:1022B0008502C674A58C8D1F0F6962F6CEC634C622
+:1022C00026B075E64F7218D34057D76307FB094E07
+:1022D000191319D6C3DF752DFEDFC7583CFCBF9418
+:1022E000E5784C836953091442FBBE55827F771A07
+:1022F00055D7203EAB8D1CBF695A1395573E2CF81D
+:102300000D02635522F3E98B18FB7D5854011BC164
+:10231000D8258F2E47C47221DC0E8304F88F3A44EF
+:102320000E7E5D2C8EB1A59D861D9BD206F1AA84E2
+:10233000EF35F0FD2B561A0CAB643D3AC403F21D89
+:10234000DA18C69EB7B8A64B90FF608AC6A787F674
+:1023500099C99FED8C64EC2D8B6B06E65FF2DC7700
+:102360000C1B7FC06CCFC67E661BBAE21741FFFD17
+:10237000C7B5F69DD2F0F3E16E29676CDC0DCADFBC
+:102380003C97EC023CCAFFA275E1FC9FD04556F891
+:10239000F3012F49E0784A1A553ADBEA5A82F87C71
+:1023A00019E9B9470353F8E56DABF6AC812155AE99
+:1023B000CA1AE182EFEE822563198CCD65928E41B7
+:1023C000F97CE6389A064D2D642E8217311FA56FD1
+:1023D000C5BBAAB19DC5CC4FB06BB22135D4B88274
+:1023E000F172CB78B9657C94F471ABAB8EE3E520E8
+:1023F000BC4E4CBA231BC7A5E0F59655A27A73587C
+:10240000FF76C4EFCB83173F113286D2C7774017D0
+:1024100026681EEB313DAC73A38ED1F78D8F087EFD
+:10242000A46B852E2A9991B7FB18E40B817402F4F2
+:102430005184FCD29F3A3792E8E449091A7C7092A1
+:10244000D6A71F0BE3D4F8B3052DD1875E00FC1E81
+:102450008803FA481F9E0EEA9A210DE01FA0AF677D
+:10246000B0BDF3AFFF5D0ECE97FBCD4912CE57A3A3
+:1024700006D601E8D8F7B6D6BE5B92991460ED9403
+:10248000317EA46B26DAED73C7E07AB1A54EA8DFE2
+:10249000AD650DFBF387F6FB2AAE17B47FC2A62B02
+:1024A000F753BB9CCF95F29FE2FAC563CAEBAD5ED2
+:1024B000F569AD16F03F71E89C5E1A13621C0D6F52
+:1024C000E76606E0EFEE3833DD6142E4FAF2E74515
+:1024D0000EE69F94E944A11FAD3ED2B5C314881700
+:1024E000EF17E8F9E74437D140CF1944CF9FF8E020
+:1024F000D3390669C42248FB606ABA2075BD60D62C
+:1025000023DD2C67764AAB9993D20760F9917E9DC3
+:10251000BEA7F438EF0FB276CAAF2BBED782F47CD9
+:10252000BFC6958A702DEBA57C37EB2FB3C1FC2D70
+:102530006C5E7BD40658CF6F796A5A02CCEF3CFFB1
+:10254000B2A398CEDD257CE293883F7A10AF3EC1DE
+:10255000B33E11FABFFBA592F549903F47CBD78513
+:10256000FD2B5F17457E048F1BF8A1978FCB41E3AE
+:10257000D24695ABF8A1F209E610A09DFE8306FFB6
+:10258000CEB400FE287EE8DF93508E89FDF7E07A16
+:10259000BBDF34C4E07A3F08E21BC72938186B80E0
+:1025A000FE90D62A63882A88DE1F62E176ACF7B9EE
+:1025B0004CDF9FA730A2EFCF05E66040BF1774A69F
+:1025C0006601E55AAACB5604F8AC60BE2606E56E55
+:1025D000CD4B05384F2325D7A744D71FB53715A6B0
+:1025E000A1FCF7A70A28FFF719EC8D69AAFD845D05
+:1025F0008F4021E361389F3FC076C70EC54B283E10
+:10260000F69F421463063DF3198B88BFD944E4EB6F
+:10261000443DF157234E6D06F6E3943CA6A1ED9F91
+:1026200090F1EDF94A4B74EF83F1EC1642F5C3F7E4
+:102630002B43F8603F243F2C8CFAD1A7713E56FA09
+:1026400063A6BE6427D0756A844B978682C116C77D
+:10265000E58B99CB979EB44F33717DE64CDEA8C8CD
+:10266000656A8FDDC6E5D1099DE443F844499A1DAA
+:1026700024D7809CBDABF897A7118FBB8CA62E2DBD
+:10268000A4EC16DD9FFA947D307D70FFBD4BD97FA1
+:102690006FE1FBEF1C99B5EF12BBBAF17BC6EC3AC8
+:1026A000C42F97FD5E998F6DB8DF2AF271C87E0B3B
+:1026B00003EBC5F913252B8374B5C0C7BF3A25DCDE
+:1026C0008F7CC436E7D2F8F4B2FC0CFEDE5AC15857
+:1026D000A651C613FE4B70195966CE209C54635602
+:1026E000C1291E9BAAFEC80649559EE6CB51956797
+:1026F00034DB5570564BB1AAFEA836870ACEF59743
+:10270000ABEAE7ED75AAE031ED15AAFA633B5CAAE6
+:10271000F2C2AE1A55F9B81E8F0A9ED0DBA0AAFFEE
+:1027200077A77DAAF2497DCDAAF2299FB5A8E05BE3
+:10273000FBDB54F56FBFEA579597B07F56954F3541
+:10274000EE57C1D3CCAFABEABF80FB16F0CF1DB6BE
+:102750006E55FE0CE9B8EABB3B734EAAE017E47570
+:10276000F62D0E27BE682DE7FBD16CFB07AA765825
+:10277000E768BEFE613C6F7BCF1F0B514E6ED7F4F6
+:10278000A721DD4A5A7322F27166F1DC4340662CC0
+:10279000DBB1AA14C55B4EF95387301DEDDC5F8AAF
+:1027A0006C925F71F210A605AE8BA5D01CB3D74416
+:1027B0001FC6B4C85338D58AA834CC3D8CE944DF51
+:1027C000AAA928575F785C3F1AF9282A46A14F0723
+:1027D000D1677D8286F8B97EB1C98FF2C732C52430
+:1027E000329013961F5AD6B1024C8B9A316DF61A5D
+:1027F000995F0FFA809751BAC96B66FE6C2067AF7C
+:102800008DE0FA93F795A7433B23AB4433AA99E6AF
+:10281000518F2548D0BEF5E5969C5D76C6D6EDB0C5
+:10282000CFD7E542FF199EC53BA2014E638E05300E
+:102830007F1698233699B1253BDF76FAF287C29747
+:10284000339D4D2417C4F65CD4FF947637967E6E84
+:10285000D79821DFF74BE71198F7ADF1E1F41DC2EE
+:1028600025995FA75D470BB60BF99EF6107CFC4CD3
+:102870001ADF7F97A4737D0A8784EB66E5CBC6AC2D
+:10288000A0A78C80B9DC3AA9E10CEAF0A2D927A074
+:102890007C62D7E07B902B89582983E0DBC3014E13
+:1028A0004058626C7F96EBC7D8AFD5C5D8D900FA2F
+:1028B00049A851C35B619ECF660EE2A35BAAF18972
+:1028C0003006DD8F9D763BF4B3AD0AC60BF0563D66
+:1028D000D737947AA3348CF6F72FD3F87ECEAECDCB
+:1028E000B7A39EF4A53C9EE7BCFD8B3ECE447BEB9C
+:1028F0002AA589351EC105F2CD5AE9B4FBA09EAECA
+:1029000011E62384DEF28B3491BED71D7E4490A065
+:10291000DEA76912C189957E1A77520DB41B80BF5C
+:102920004DF40966C8B73DE613103F9BD96967F0BF
+:102930001D335A88FED7C83C616BF8CBA28F410F7C
+:10294000D3799D76ACA7BB13E8331F27D46366B851
+:102950004EC9E347B010EBA3A4863E0D73DC409F45
+:102960008F4A7DD443FBC5DD26290BE8FB85C5A630
+:102970008A1D21DAFB549E9F0D31EAFE2D5A3E1F1F
+:102980008ADCBE6CE6EBA8F0F19A68A692E36B5283
+:10299000C65B6F84AFB5CDC85C01F86E857ECCD0C8
+:1029A000BEE1AB55661C3FE8D04EEA4FE4F264C787
+:1029B0008F72C86E0A5EC721F408943FA208E9A38B
+:1029C000CFDF087C68A8D2DB516FB2FE4393807BD7
+:1029D00073226B1150BE5853CA7A44DCD74457AEA9
+:1029E00033843E7933BA54D64FD99F83D74B773D42
+:1029F000E3FD129CEF7FD531D4C7561F8F8F710531
+:102A0000D0534C3AA7CB62D6A245FE98CCDA29BD6A
+:102A100085F5527A1BEBA7D4C1CC22A6A5CC4E6972
+:102A20001973523A9D79282D672D94CE64ED94CE7A
+:102A300062BD94823D43A99399C9EE9A07FB37A6DC
+:102A40000B9893D2EF310FA599E99C7E2B580BC1BF
+:102A500077B3764A3B80EF243DFA018C9476829CD2
+:102A6000C3F44D9073987679252665A31F2087D2ED
+:102A7000235E3BA5C7BCC594F6781D54EF6D6F3936
+:102A8000A5EF789D949EF05650DAEB7551BD53DE5C
+:102A90001A4ADFF57A287DCFDB40E969AF8FD2DFB4
+:102AA000799B291DA5077EC6F9CDE92B447D3EF50E
+:102AB00023BD4302F9EC91E5D26187E699DCF1B8D8
+:102AC0006E1A66403A285B2320FD5973340E3FA4EA
+:102AD0009B72560BF742BAE104D7DF0CD648D20FEF
+:102AE000AD6DF58204ED76087DDA0858CBE9E9A9E9
+:102AF000738D209F4B3AD9BA083BC2194F1981EE0A
+:102B000076E83CFD3BA0BC64A734D7087BD6E4C87C
+:102B100053FFB18FC3543EE9086B34033C2B3DFB9C
+:102B2000A93881E381C2EF7B3B73E6AECD443C25FF
+:102B3000C2F3C534302C51BF7EC444FA7561DBD971
+:102B4000420DC0931A4C45681706D4EB42BA1FAE2B
+:102B50005E70B9F2DDB65596469C870D9F805A0E81
+:102B600059A9197D85ABF3D5ED6ABE5EFF4C7B8319
+:102B7000FE03EB0937686F7F96A3327DC2FF7E3A72
+:102B80000FA66FDDF58FF66BC80F648EC1FD74570D
+:102B9000349733FDA09FEE04BC77C5C8F0C64C1A2D
+:102BA00017CA435CB70D9BD2FD3E80778539571F0E
+:102BB000C7F27FD4D87742D1AE70D7A65C8233C932
+:102BC0003FB121C69313938FFA3CDF975A931F0DA1
+:102BD0009302F8BF399DCBAFADB75CE9DD81764498
+:102BE000B38665C1773B9B976FCC81767EBC19F429
+:102BF000078047DC5ABD310BCAD3376A266A65198C
+:102C00008778FC7873F59E4DA85F258F8EC98676F0
+:102C1000336479991ADB57B806E8BC55AFB6A79567
+:102C2000F49F647EA98666CE826C4D95EDF41D3AC4
+:102C30005611B8DFFD4CC6EF57593CD5DDCEFD57D8
+:102C40008691E1FE2760FC2523B9BFC3B2CE48FEC2
+:102C50000E4BF27F9DBC03CA2DDB347654E9446BE6
+:102C6000ED5A1DEAFB8B593BF2E30E817FEF4BE1FE
+:102C70007A21280AE97303ECF2ADDED38B3203FC30
+:102C800084B60A9F80F67BC9C85AA10FF79FE40754
+:102C900005B4FB2D152EC11589F68187CACF65B9FC
+:102CA0007E920EF8D92AE1FB40FD92B912705DA127
+:102CB000DF8A76D2F35851607FA7B3F83CAC073B6C
+:102CC00099F4D5757AC22B78BE4E65971EC0F695DD
+:102CD000750C2EFF7E06B7AB773D015D201F4CE2E1
+:102CE00076F389DD89A43FCE690D77A0FD74E2A952
+:102CF000D165046F99EC403DF2C4EEC9D3319DB368
+:102D00006526D53B21B01EB487E76CB95BC4FCD403
+:102D10000CC00BDB3BA3277A9CB3E541F9FB47CB07
+:102D2000B0BC58E3FB09DA91C58DFB22D04E9E1C46
+:102D3000F94A12A627347DF5DDD0FF5D66F62BDC5F
+:102D40009E9D1BE3FEB11CFE31F7A9741DEAD7BF9F
+:102D50004B4FA7F59CCF1CC4075083ECBA5BF6F62B
+:102D60001E064D8ADDD6DE3F15CC5CE6E8301FC17D
+:102D7000B4B4CB5E86D357D6E33C82E9F45E4F19F8
+:102D8000AA2FE5A75B8E60BA24D7F53B9C9F17FF5F
+:102D9000E17BAFBC08F0C8C7EBCDA807653ED137D3
+:102DA0006327F9EB740CF9216B92A7458B046C74C3
+:102DB000C6A07C78F6695183FBB921AD250C61C3AF
+:102DC0007DE91AB40B7745B7D4D0B8B3C219CEE3B6
+:102DD000DBB00F215D64453B63909F802F691D3EF2
+:102DE00093E9D310ED3147637E18CF1FA817CEE1CA
+:102DF000F303F55AC204EA274620FB13D406DCBFCE
+:102E00006DF2FEDDC63C09381FD648CF0EF4EB64E8
+:102E10009570FE67919C2EB07AD344FA849CCD962F
+:102E200016CF9DB80E5697E8EB0BA43BD80607F4D7
+:102E300091748219DAD75B050E839C21BCF0877EE2
+:102E40000C8BC9427A8D82BFB502DA0BD033701C6D
+:102E5000F34C83DF2974179BC1C73542A6BFAC650D
+:102E6000BC3D05DFB80C2E9F016F4983F868657C77
+:102E7000601C9A007C02EAD1F806F066761BD20547
+:102E8000487A81A74C1203C75FAD7184A15D647A53
+:102E9000F5FBE84F8942390278FE53F72423F269A3
+:102EA000F0387232D208DF46D087516F9FE9E2FCDA
+:102EB000DB58E911C83E4218C79F2C3AD01F68352D
+:102EC000AD167401E3B526F37D7A66A5A71BE5CAA6
+:102ED000CCE2083BD2F79DAC7D9D99F3F7914CC0B5
+:102EE0006F141BF899D8C441BDF0474FBF7B1297B0
+:102EF0003499B597E4E2FEF9F8FDB370FDB63E3AB9
+:102F0000B307F14FCC79AA3B061A745E94D77D19AA
+:102F1000F7EBA46C133F0E1C479207E040BF448DB3
+:102F2000BA1CE841052B7465131AA271BFD144E4A1
+:102F3000CF9C817A4A9486E43BC829614148FD339D
+:102F400088AEE4F957D6E7AE8C4C5A37AB89AF035D
+:102F5000EBB71B1746CA8355D609FA6D04361F0115
+:102F600074DF58A6F50B68D762FD28ACCFE29D91BF
+:102F700043D769874E9A3903E5F4C31AF36E367462
+:102F80005E81DC7E4B7AEDC371540EF9A291FC7D1B
+:102F900001F86A43C1EAF5B859FD6DAC6BEE8CB42B
+:102FA000A1F989C90B66E23E9B58CB68FD83CB47EC
+:102FB0003DA65E57B237C7A3FF88F9BBBEC17ACE24
+:102FC0004CDE5586FA7CF0BA2A74971A1B7A5F1089
+:102FD00033395FA646D84F95935E21929EE04C11FF
+:102FE000E303EDA20D197C1FBAFD3513ED43EC236D
+:102FF000A31FB75C7B57EF93B9B00EA5573468AEEB
+:10300000B0A3EF1CFAE14C48A7FDEADDD5FF0AF5B5
+:10301000A67D651A87F96FB0BE19E810F1F5809D9D
+:1030200001F0DA2FF6B4A0A3A4B192D971DF55FA5A
+:10303000D923F7F30B9DDF49F23557643B490E82E4
+:10304000651E402F0069897E78197356B690DD6839
+:10305000CDCC07598D6EBDF625B45FFE49CFD0EFBC
+:1030600038AF42D295C0F8E7554ABA65E8C7175954
+:1030700039EA11F32BEC943FBFD2CEF38D3C7F4164
+:103080008583F217543A78BE09F2613E1656F87BF2
+:10309000BDD0EE42538CA4413F78A593975F355045
+:1030A000F93B600F6402C98787F949DEB77CA6E166
+:1030B000F1124FB85F005C0D91453D12CEDF7D1AD5
+:1030C0007B162486149199017EB6C2E9D742F9F3A2
+:1030D000CC9F8013F946F56A6736E4BF912C9A714C
+:1030E0007C6F38C06EC6F9AB1569DEE907F01B3599
+:1030F000C914CFD821FBAD7D2B8CE467055D87FC1F
+:10310000AC6C45A2ACC7F0F26DCBCD7ED4C7400EFF
+:10311000D23AF6DF27921E00F2F0ED1CD48B5ECA85
+:10312000B4874948B76A7EB3542F2FA1F62A99195C
+:10313000EDF25995BCBDC697347E0DEA55A679339C
+:10314000910E1AF7323BDAAFCF569F2A8B45789B08
+:10315000DDCEE5875A2E34566F392EE1783C1A734E
+:1031600016D5E77EAD464FE92EAD30C8CFB4DED2DE
+:10317000A0FC182A6FEC3DD84E4255A97D13D4B35C
+:10318000C038D18FBD4DCFF37DF7881467B0548B15
+:103190005DE68241FE4E91A7D0827C1845F245C57E
+:1031A0005FA35F52C33F92F914F85DC471F97631A1
+:1031B0003BC9955DEA7A20273528AF52DAD4F96702
+:1031C000B204C52FA59A87E079B67AB8DC0B1EE762
+:1031D000E0B8BAC246D1B8347C5C28D7203FD77457
+:1031E00088F2732B45BB24A1BC6B3F85E31FF5928E
+:1031F000C8BA009E555D3413E969D6660DB94366B9
+:10320000B35E920B371BB7E2DF081E67F0F8366437
+:103210006869DF1CD007D71B491F6C7DC4A4C1B8E7
+:1032200022E85BE1E8573897551A9E09F33022539C
+:10323000D6D7AF6BB93C6934119DEAAC8FE504FA7F
+:103240001F84D1A523B0BEEE7AECBC728A1BE9685C
+:10325000DCC172AC58966393FA607C2AFF73389392
+:1032600002E6F7D6FE18157CFBD54455FD12102E4C
+:1032700081E5538D79AAF269E6712AF80EDB1455BF
+:10328000FD19D254157C67CE9DAAFAB3EDF355F023
+:103290005DC54B54F5E73AEE5595CF2F7F4855BEA7
+:1032A000D0B946052FAAF87B55FDC5AE4655F99213
+:1032B0009A2755E5C1F693929666723FCF569BE7E3
+:1032C000A483E48B4B70460EAD67A914FB03D73D76
+:1032D0002A82EB53C1F51AE5F57841E0FDB1FE48CD
+:1032E0000DF29DE27F63ED912AFF5CD7E4C9C63EF3
+:1032F00013FA72ECEF23DDB213DC1FC5FCFC3BC5F7
+:103300007FD5FD04D483F65647A65B71BF43BFABA0
+:103310004B0FFDF935E4BFB736D70BB40F6EAEE7F0
+:103320007E95AB7AE68A0DC08385F37EE5788E8242
+:1033300027734470FF6018CFDF26FB959E43BF5272
+:1033400036633FB0287E7817B59B50ACF7A17F4617
+:10335000A8F6087A945B2E66364828079753FF979D
+:103360002BEC2358887956D256AF8D39A07D5BBDA2
+:103370006FAD1EC656973969CBB3D0BCCDC3C81F3D
+:10338000F368E6942D6B81E7FF2153A2754910F98C
+:103390003C3F5FF7C6B93DD05F6B95A508E56A7005
+:1033A0007992BBF3E2B11B943FBFF2D50FEEBFD1D0
+:1033B000F7751D679A02CA87F58B56243247001DA0
+:1033C0004886D07EF91FC874E59EAC273FD6335A95
+:1033D000D793C8CF1726FFD7C4BDF0DD79E9CA3D22
+:1033E000A8A743FE0F301FEAD1BC9ECFBC44E729FB
+:1033F00052F340BF47FD3B2C34DD1E94DB17AD95E7
+:10340000FDE8075A1DA997D0CE4F327E467EEA0EC0
+:103410001DB7AB83EDF7E707ECED76B2BFF7CBED69
+:10342000EC9653AD997FCF8C3E265AE4F84088F94C
+:10343000D046B50928AF12ABC54F02F9A23B524F97
+:103440007E048B49F63B986A547E01C56FD01D7986
+:10345000BF80746FE95A417E7AF417607B07E57587
+:1034600009F6172419FFB4E8E3D81BB5CF06F223F9
+:103470008410FD04E1A1F82782FBF1A33E81FBCC7F
+:10348000CA70D22782C77D39B3E450663CF248FF48
+:10349000C93B507E9FD2D17E381CBD8449E1CC1FF0
+:1034A000D07E6F26B7EF23726254F991F644E60F8F
+:1034B000F45FB364F32711320C5BCC487DDFC65157
+:1034C000D8DFDBBCBF133ABB8DF441D8F6D0FE7B0E
+:1034D0004FE6E7EE5C4669AB6C97B7011F63FA9C59
+:1034E000D74CFAD936E03F84B77B254AFDDE1C4A2B
+:1034F000777AED54BECB5B4CF01EAF83E0BDDE723D
+:103500004AF7799D94FF92B782E09F7A5D94B67BEB
+:103510006B28FF15AF87E003DE06825F457D5044D0
+:103520003F7533A56F785BA8BCD3DB46F09B5E3F4D
+:10353000A55DDEBD947FC8DB4EF0116F07C1C7BC2F
+:103540005D04F7787B287DDBDB4BF9EF784F13DCEC
+:103550002B8F93B1E65E2FFA2B5CA284FADDB3AE1B
+:103560006A33EAD7B6651A338AF336976605FA39AD
+:10357000B655F2789F6D9586FC40A087FA519FB3AF
+:103580002D7BFAF8342A5F40E55BB149304AACAB99
+:10359000B8FECA56EAA99E150F02C177DB6A2BFD59
+:1035A0005A805BB2C3A9DCBA4A24BBED798D273AB5
+:1035B0009BEB5D24BFAD3AAE3F28741021FBE9229E
+:1035C000B2444A976573FCA33242EF2319594AFC6F
+:1035D000A4B907C767AB82F121BE55F5468C5F5A87
+:1035E000EF83F149A43FAE3A047824C378117FC039
+:1035F00087FCC26C19D797AD55EB08AFE465F3941F
+:10360000786734DAE96D9EFAB9846FA5487ECD36C5
+:10361000D7A1E8FB504ECAE77CACF1E14E7FFE50EB
+:103620007C3282F0DFC6B8DD900CFAD2FE10E300E7
+:103630008B47A9C7FD788F1943FAF126CB7A62B27E
+:10364000C0F98F3D2C12FF6D67A0F7C177CF817E47
+:10365000E7433950BA6F15FAAB1ECD724DCC023C20
+:103660007E248D3F24021C53CEDB4FAF17F7A01EE4
+:103670000DEB7DAE09F2373EB8D989B671EC6669BB
+:103680002DB25BDBB25713D0FF952CA8D74749CB9F
+:10369000653CB63B787BCFD58BE44FB6AE3A90769F
+:1036A00084F75B86FD268EFA7D18BA613216481AB9
+:1036B0001419C955E245EC2FECA1CDE5D85FFC66A5
+:1036C00087D25F21F6F775E769E4E365565708BCD2
+:1036D0008693273793238BB322E3488E24B1249417
+:1036E00023CFEBB8DCF29DE4FA241D869934B41F95
+:1036F000257EAEC4D383E3E835323D241942C76149
+:10370000570DE8FD3EAAB7DDB1C949E74B303E0B86
+:1037100045AB756C05AEF3EA9270F3DA10F4A0A431
+:103720005B508E01DFDF8B4623B5B3B99CB7A3E1B5
+:10373000EDDCCA56115C6232FB42C86B257D5A6EC5
+:10374000E7812C4EB7490FBEB4F118AEEFDB3A3A21
+:1037500013F49CC6BF11ED04DF092DC9D7446DFBDE
+:103760008E3D017835CBE3794EEFCFB523FF407B1B
+:10377000F92857915FF2C97FC16605CCBBF2DD5ACB
+:10378000D98FFDA36B1BA229BE5CB52E0CF5A33609
+:1037900066247AB0EA3CD18501F46045BA0C411F39
+:1037A000FBB2F44A3CD5543211E3327C5F9E8A72FC
+:1037B00009F03E581D45FBE1D465EFDE3916E05BAC
+:1037C000AE8876D4CB9EABE5E71327FD5143E726C1
+:1037D000DE7C9CDB7DB7FDB7B21EF47B27C8E9B366
+:1037E00068E7417A4B33B377C1BADC526D22FFCD23
+:1037F000AD57C5B381761AB9A4C7A37DC1FD3553B2
+:10380000FAA13C80FE267DA6AE0F33AA453D23A13A
+:103810004F9D6FAB3A70661AF4D356CB3F6EBBF632
+:10382000FE71847DF51AF29300F529F49340FE4D64
+:10383000D19780E716371A19C973EB32A319E541FE
+:10384000B7259CE45FDB6213E9A11B325787A19E79
+:103850006CA8AA8FC674A4DEB7037DA7DDBBFF7D6D
+:103860009E2D81E42D3F7F8184590CFAC0BD7AAE34
+:10387000E4F8FAB64CCB4479A9A1F2C3BBFF7D8B27
+:103880000F7D07AC85F090342C910F7E00BE9BE23B
+:10389000D402DF2F40674E44F874AEAB07E54342D5
+:1038A0009CAF1B8BB69ACE56D2F9E2CA38E2335D92
+:1038B000B587E931BFB2C818C8E70A9FFCB5FCFF5D
+:1038C000B41CE7BB991CB859BB37E3F79FA573BE7F
+:1038D00019CE9E360C234F15FB18CF9A638A6C4B7A
+:1038E000FBEA597D48FDEAF66CCE67C57A7E3E64F8
+:1038F0004EC5F4728AC3F8FA443CC79693CDF9A931
+:10390000CD124971E2B674D6857103DF720DF7F7F7
+:10391000C4F1FFDA2AD3C93FD42A78A27D19783EB0
+:10392000C29586EBD706731409FDB7A672B9CEFC13
+:103930001E33C6ABA19D9A40FCC1DEF3A9E9989164
+:103940003E4CFE0B2DF19EA40FF0B7A35F1CFD179C
+:10395000C1DFDDDAAF866FBFAA864B984E054F35C3
+:10396000AAE16966356CC9E67AFA1D3675FE0C491E
+:103970000D27A71C09D3F073EDA6017FB344F0BB5C
+:1039800099017EA00D9A7601E725A5AF96FCB2AD10
+:10399000A9DCDF935CAFF67324B296B53102F96D02
+:1039A00054F9B6FC5502FA736CD5EA7C9807158C6D
+:1039B000CB8AF4BF24D7959F8D71E9027EEE3A4BF6
+:1039C000EBE9CDC575688B233E4A93CF050DDD1F0E
+:1039D000B7D0B89576900F7C01E345FA0F842FE6B7
+:1039E000BA2667C7733EF005EE97F97D3AE403A562
+:1039F000BFE1F841E1C762396EA29CABB922B7A51D
+:103A00009CABA997CFC775049DC7B9925C46E78167
+:103A1000AEF4AE090FC577C867BE6CCE77986E94CA
+:103A2000CFD720DFF9F49CEF30DFF0D52A6728FDEF
+:103A3000F0BCBCAF3CB437CCFC71C0F856B647AB59
+:103A40006077478239F0BCD343F80F74BA37333A02
+:103A5000475A2B0FE78B33BFDBD308E95B5A970B31
+:103A6000D76765D6593D8F33F5EB51FE9E97F7DF4B
+:103A70000D82DD385AC094DBA58D66BB11FDBDCC2F
+:103A80009FA1F257287E87D52BD2AC3180FF8801C9
+:103A90003F82D34CE74DE333C98F1135D571372BB6
+:103AA000043CF7CC986F04A2DC854E5590C78F6517
+:103AB00097FDD0973C385E03FAAB02CE2319440F32
+:103AC00023B97335954901E7CA5B65FFC5001F9BA4
+:103AD0009697607F3FCC96783C8679D672FF9FDAC6
+:103AE0005F66B86A53B533D87EB2AADF56D92F7253
+:103AF000F3F6D5FE37C3D5F461DACF0E6ADF1CB218
+:103B0000FDC176D57EBCAF111F6F433E18CEFFB509
+:103B10005F96A71B6C9E5EF47FE918D89514070684
+:103B2000FA98886A23FF69C3F979535DB2DA0FA660
+:103B3000637E921FCF47D690FC48603E8ADF59983B
+:103B400087F2D7474DE7F1BB60B9711379C1988708
+:103B5000A1DE00FDA9F2573FC2F7D346C1EE423CB9
+:103B600083C7F3FF8ADDAB891CDF4BFA734AB86465
+:103B7000B881DEDBEA7525E3F71BC23D3518EBFEA5
+:103B80003CBB2E763DE83D1B30C6087C7635BB71CC
+:103B9000BECF84FB24A78FF5711AA227CBDD961D1B
+:103BA000DA007AB2E85D69A8F75A34F2392FFCA13D
+:103BB000BF6CBD65E7A610FD2BFA9B025B2B008F47
+:103BC00000BA6D95F5E681FE9624EED006B4633119
+:103BD000B80AA93FE55CA3D25FD337EB6FABECF734
+:103BE00052FAB3DEA31E9F55EFA1F159E5FD47E957
+:103BF0006F2B8E2F045FDDB43FD98E1EE86FA97A3C
+:103C00007C568387C667D572FFE1407F4DDFACBF2E
+:103C100036F91E934DE6D3E1CEFD370E9CAB761AF6
+:103C200051AEB429FE40797FBB14B4BFAD96F737CF
+:103C3000E5FB4B71E9E4DFBDD433DF186A5FC3FDF8
+:103C40008CC97A2493F54826EB9108CF997AA63E41
+:103C50001EE8B0F0C5B6F922ECE3731E3A333E1508
+:103C6000E0192FF6CF17615F9AF3E2990349F0C983
+:103C7000CB2FBECCCB7F78E64A32949B7CEFCD2F06
+:103C800003382A96EFC70ADE4ABFB78DE27AA3BB94
+:103C9000E173EEBF04F98AFB5663AA87A17FF14264
+:103CA000727FD432A8EF4EE9B72C0F312F4AEA6E5B
+:103CB000384F7E46147928FFE6E1BF40B4CF53EE7B
+:103CC0006794ABEF6744456D22FD2F8CF9CD28EF4B
+:103CD000228C0EBA4FF8D628BE1F2C64F60A6E3717
+:103CE0004859F2390DBACF31BF586ED77CCBCFB11E
+:103CF0007CA1C6B11EEDD9DF4EAA8A47F558391707
+:103D00009737787F72D7F51B9C1F0EBE3F39E7238C
+:103D100081EBC223B8BFA53B57E2F7B902FC86A8E6
+:103D2000F70E379FB5A3B87D3F389F0E3E9F310EEB
+:103D30003E9FE6FEA8B5B0FEEEE87ECB13C49F5DC5
+:103D400021E76BC8BC06CD5FFD28A6D8795AA4B779
+:103D50009BCDB732AFCAF9C14641CAA2FDEA4F793D
+:103D60002AFD8331BB142A8E83F419B8BFEA6D4E45
+:103D700086FE195D9C3D07CF9537FE451BF25CDE44
+:103D80006E793ED64685D3B9CEC6283DD9DBDD5106
+:103D90003319FA9745D3749A97B2A8723A6FA98DDE
+:103DA00065ED688F069F23D78EB89BCE0169AD68FD
+:103DB00041403A702ED961A4F889B9E886E7C8C5B0
+:103DC0009B9D238F99C9CF9147E9257459B445EA42
+:103DD000439E237F6C14DFF7BB713C71883F8C27B7
+:103DE0006D701CA299C7D1313F02F2F56617237F8F
+:103DF000BA3CDEC7E47550EA1BCC1E86F240ABB776
+:103E00004BA8A768C3F93E61B069584E08BFC8F710
+:103E100047E9E8FB4F72CD34AF1A23D7CBE7FC5A02
+:103E200008E94F7A7594E24F0A4D67C3D1C93C0D3A
+:103E30003F47A7F0E102939ECEF72D30D94AD10F2C
+:103E4000B20008EFB39880FAB72DE2F78145BB0DB9
+:103E5000E9E737536EFFF96F18BAF9B97C3E35437D
+:103E600047F7E34E09CC618F197A7ED5E98C9E869F
+:103E70006E9ABB669D5987ECF7E2F2EF15617B867F
+:103E8000E353751689EC9F7746A15CA84E5B1F0F24
+:103E9000F0A2CA421DDDDF94E344EE082EC79FD195
+:103EA000BA4E8EA278D1E751A54847627F2AE2A395
+:103EB000C48902EABD372A9EEACDE1D7C5A0DE1843
+:103EC00094D3677FEF62B41EB6507A12DA4F2C306B
+:103ED0006E23CB07B4A302F3D17E6201EB272C2F14
+:103EE000B6F68590174A9A60DB92520D7C9E90D070
+:103EF00042A992FFAC435BEE0FB1AE57E575FDC62C
+:103F0000764C1B603B71D08E01FBE52ACEDB17D5CA
+:103F1000A72CE36148756517C98EB1E9153E9388F2
+:103F2000BF06611EAF04FB4575DEB0D5EB4BA1FBB0
+:103F3000FEF2386D2BD646A31D03551C489FDBBCF3
+:103F40006D29659983E3C8CE91E9138DB689A817C9
+:103F5000F35F725CCB0CF497249B34743E012653C0
+:103F6000752F616E59F4B4383445DDCC6E92D02E85
+:103F7000EF253D3FE1BA96F820E1F0628671ABA4EF
+:103F8000B87601EF030DF423DF6FAE97E3B9575C0A
+:103F900065348E04EBC0FECEC80E8DF3CD4579742A
+:103FA000E5698E51C28FD5E5C971FCDCC2FDD5E152
+:103FB0007E09E83AA9B6574038010C38F4C5275CA9
+:103FC0006F4C6B4279F25A04F98BB56D99CC07F2BC
+:103FD00027557445E5E03CFBA5FFA6C990070BDF1C
+:103FE000AD7C209CF4B336A16506D925F769582825
+:103FF0003FCF981CEEC728C8E1FC9F606B4DA91EFF
+:1040000087E9D344375F97CF6790B31DF4D9119FE9
+:104010002DFA581CD47B9A75A1E9739BDCEFC07E06
+:1040200021CF5F187319917FB582933B39F7EEDB8F
+:10403000B7CF82CE1346E75536C97A8DD24E444E5D
+:104040003B1546D81D0CCF450A6607DF07CC3E9BC3
+:104050000FD6ABF92B6D487BEBC11C791F496BB2B6
+:1040600061FDB24CBB0DFD94C1F7551AD326DA7031
+:104070007D1A670CD0A931705FE84ECB7E1FCF53FD
+:10408000997A742CF01C5970AAC77321B1372897FC
+:10409000CF97371DE2E7429B4C45BD780EA1C9146E
+:1040A0005744C7FE4CFC9CA952DF643A46F2DE64DA
+:1040B000E7F15613EE0F02A2C7E7A13BED18CD833F
+:1040C000526F5A0E97AB267B17C3FB5BE1763FD549
+:1040D0000B139D3E0DE01F16C7E8FE4F9891F35558
+:1040E00004AC8F3180EF957E6FCBD1D1BC352517D5
+:1040F000F596107E22DE04674DB6221BEDDB38DF1D
+:10410000D06F63B442DF9CAF1F97E75B69A7513E56
+:10411000FF7A4F43CEFCB258F41339D7E460BBA604
+:10412000E546B483B491E36FD8DE8661DB6B5E282D
+:10413000B7F738F28536B2C88CEDE9505E84A0C37B
+:1041400067E476FE57E3ED30B374DF97605A309F33
+:104150002D94DEA3A4468CA38F1BFADD3796BFEB0C
+:10416000D47E2490BF7B71FC2B93CF1E2BA11CEE21
+:104170003FDA2EDB278A9D6191DBDE2EF07BE83E65
+:1041800021DC4EEF36C87687254C3D0F83F741F989
+:104190003A5CAEE0E7E62EC7318A6B04F3F3E577CD
+:1041A0003E8A0EB44F50EF736473BB0453B44B1C80
+:1041B000B29F0D61F41BA09DA2F0FD805FB742FA93
+:1041C000A75B003F03C86F0DB42B247B88BE0DC9CD
+:1041D0007D69C8E7A9F23B0543F6D75C2EA7854762
+:1041E0003F4B43FE2E8BEB4FC0EF82F9FC8547AE71
+:1041F00026E0785E983170CE86E243AB17A7F37B5A
+:10420000D9C7FF1CED0AD1FECDEE7F459DDDB486FA
+:10421000F4C0E55C0FFC5BDF07DBBE8CEB9D1D8211
+:10422000DAEFA4CDE57AE75FE47DCC7A55A4F72DEB
+:10423000CE65B92E201FB60AE6E5287F531FE1E7B9
+:10424000E6563F5EFFD90321F84118EDFA734E8020
+:104250003D5CDCAC273F5AA3297DC48DE21CC3AF73
+:10426000B387CB71797D4B1E35F2F3242EAE175BED
+:104270005CF7D33995E0F323C3D53B24CB3DA5BEF2
+:1042800001DB4779629A47FE804B6823A0BF4D96B9
+:104290007BC17876E264C8F36304B9127568451887
+:1042A000B6AB93EDB1ED8A3FA3A2C8E808F85EB7BC
+:1042B000B8C8581A402F8D8C9FDF0D6EFFCEDC01E1
+:1042C0007D5AA5AFE8709F45DF509CF8A7013943A0
+:1042D0008A65B8CA8E51FA0F3E3F16705E2C8CF379
+:1042E00029B7675AF1DC18E8B76B2B968FC4F96DC4
+:1042F000155D2F58611EFA3F30D039E70F65BEECCF
+:1043000093F972B8F5F3B143A08C31F6043B829770
+:10431000D6804EC68F40FE68CCD494FB438CB35CF1
+:104320001E6708FDFAD6DCAFA75F97E686D0AF51CF
+:104330007F7604C51F0261D49B1D21F4EB1382EC30
+:104340000F90CFED9CD0491D7D300F276E1D616F02
+:1043500094E89E91C35E04F6C38B6732516F9F232E
+:104360000CBCC723DB318C60B02316225E739967C7
+:10437000DF0302C5515AEE48A3EE045C8F9BADA744
+:1043800024FB1137C23A61DCA1F5DAB219A1E20CC3
+:10439000FF38402728BA02EF07C02A04C49586C414
+:1043A000CB82E263184E1938FFAB1D5AFFAE62751F
+:1043B000FC6AE335EEBF30AC60FE27043C1FAA2E3A
+:1043C0009F5FAE0B8ECFA9E25A0B9DBA607C7C88B2
+:1043D0006FB28C6FCAB607290E3E2D45E4FDAC6462
+:1043E00064CF07C7BD0C85BD0E2DEAC3158CF4F74D
+:1043F000603F369E1725FF5E0563CF0974DE5A7D48
+:10440000DFE4E959E7F8FB1C2DE5D88F2D53C350A5
+:104410003F0EBEAFA0C49BF0984CE07D69E5DD2265
+:10442000CB620DE1C77CB753B9E29787FAA6124B6E
+:10443000C0B9EE556CA03EDDA3F2851EF7D6D65965
+:1044400014EF4F1CEF29EC82A2243BA37948AA6603
+:104450006407C03CA8E2FA86945D34CE4B358CC527
+:10446000F238A0AA3C017670A44F18BF2ACE0FE301
+:1044700054C1C176E7CDEC4D434AE60DE5F9CDFCDC
+:104480008D06395EF8466E641CE93B63D818D47714
+:104490002C8B9FA6F5B804EB817E59348442C5036A
+:1044A0003743FB6807BA905FE2D1DFC454EFCA30EC
+:1044B0008748F7C984628EB310EBE4F1E17C46FCD7
+:1044C0006D0807950BF859986C70E0BC1B0C00C385
+:1044D00090053D332640BE56F637AF1598883033E9
+:1044E000DB8DDC4FA8BC6BE3A7776D86EB0774FF11
+:1044F000BE30ECCFC7BF53FA19F28EDB0DBE27FBDF
+:10450000CD1CFC7D19F91D95FE879BFFE1DE6DFB3F
+:10451000C3D4772770BF6732D16BE520BD12BC4C86
+:10452000A647FC1EE5C2BD4AB1AD770CDE373CFBA9
+:1045300070841DFDE003E3F0DDA9E5EFD1FD75ED2D
+:104540000DE0619348BE0F8C4B6EEFAF1D17FD025F
+:10455000E4DA06BC3484E74F2A199D27B0B84ACF65
+:1045600089740E00C6A0921301EF13407B1B0EF15D
+:1045700073AF5BF19D0B71B05FD42BD06EB0554221
+:104580007E083B4849AB19BF1FACE0D5A8073D1AD0
+:10459000E952C3F5E8D9A63E11CF35E9E2FA45E480
+:1045A0001FE7682EC707E8379ED1F90B6D927CCEC6
+:1045B00071A4C4DF4DCBE4FB9BD2CF84D11A59FE4A
+:1045C000F7D2FB47B3234ED54B76C6F2F6C52F4440
+:1045D000FFFCEC11A7EAD3002ED867E170D2A92B1B
+:1045E0006966C6ECFBAC0BD19F3F3BEFD495748062
+:1045F0008BF6D978F9144646CEF87D090BD19F3158
+:1046000061B459D5FE5B38D7F1DF3CD51A3421CFE0
+:1046100063DF365A394FC9E83EADB3F397A7312E61
+:10462000E954F647872E48DF81220BDE23937F7102
+:1046300051140F9D29D3D99DF8EE5214FA2DBB6861
+:104640007E470DFAE99FFE6BFCF482437997CACC52
+:104650002A81FF1B1B982B2C2380EE9943739D9F6F
+:1046600003A6B881828FD2FF10BC6069C59840BC98
+:10467000B6513B0A5E170A0DA48705C7872E08FDB1
+:10468000DBF19C54C4CFD62FC275BA10D99F2A0033
+:104690001C9EB79ED6ED427CFF76C11E00EBF83A19
+:1046A00056EF2BA275FCA3D6513D7A02BEDBC5DFC7
+:1046B0006F6896E3504FC6BB7C689F01DDD1B9326D
+:1046C0005F8A9EFC4865E30547A03FB06E34F7CB98
+:1046D0005C92D3698616CF49A04BF70181AD85FA6C
+:1046E000EE6B97F5A89FCCEE3CA3473DBAEEC01900
+:1046F0003DDE4BAD4318DAA9DBA67784D2FFFE324C
+:104700005AABF2972976D7D194ECF5E877ABAB1694
+:10471000E81EDEEAD7B91F6EF5321C256377DFB2DB
+:104720009FFCB855CEEEF5982E657D47F1DD88C526
+:104730002EADEADCC0929A08553CBECA13AB8297F4
+:10474000B6C0EAC03EBBB42149F51DC35DCF82EFC0
+:10475000280EFED0FEAF90D771B16D732FFABB1645
+:10476000BBD47ACCECCEB5620CE2ED11EC1ACEFEE5
+:10477000127EB7848F10D200BD0AE67D5A07D7A3F8
+:10478000EA2A8C649F54220CF35A59ABF5E39373D5
+:104790004753F454EEEE10A8DC2D97BB6B046E5714
+:1047A000CBF275A98CE3928327A7D175529FA337CB
+:1047B0003300DFA515E5E7881E657D43195785C4DD
+:1047C000F58D0D29EFE9B0DDA5DF17586C1A8D4B7B
+:1047D000A5472DA951C3551E5D909ED5A743F9BD90
+:1047E000B4419DFFF3D1F2BE9EC7F2909FDE182D1B
+:1047F000889F1807E13FA5BC7702EF815DD23A0F91
+:10480000227DD6EABB0A70DFBBA47511AC94437E4F
+:104810001DDFAFB8BEA201CEC3EF1B750E33DEA7FE
+:10482000F5AD14886E97B000BD276DB03EC1DAA11A
+:1048300070BF2277C39CF5E40F3D2898516F281371
+:104840001D22DE836F1CC68F7E51E68313AC2F1FA3
+:10485000F1CA46228575CA9E3F82F699ECB796F951
+:10486000308E943D4E20BFC49D80714311A622C955
+:104870009139B03784419AAD6DAF20F93E566FE65D
+:10488000EF62DA58A0BC70FC331370BE1075B20B27
+:10489000937BE8FDBD396D9B2FA25CCCCC70143DA1
+:1048A00005F83D19C6FB7FF275C1BF16DAA9CB3FEB
+:1048B00046F2D30AE481FDD6D96439DAA1F6CF5A9B
+:1048C00051AE21C1CCCAA77E1394F832D015EDC3E6
+:1048D0005DA5A49F58E57E9F2D94B8DDFCA07C2E9D
+:1048E0008DF9D6E2F9FABED18CF295F41BFBABCA76
+:1048F0000431285E50371AE679A5AD4F75DEE95BC5
+:104900006CBF01E92CB87D18BE2A5E394D7B2D8A1B
+:10491000EE771DCCB0DEE8FE94D6A83EB7A4338770
+:1049200007DDBB53CB9FD9F6A4A07B771941F7EEE7
+:10493000F282EEDDA9EFF92D744E09BA77A7BEE732
+:1049400067B0CD54D50F93E6A9E0889CBB55F523FD
+:10495000EDCBD5E7AE8EFFBC4248C777067D7D2EF6
+:10496000988766E08DE298C17D242F0A2A431A3E7B
+:104970002ECC846973A1A10BE9A43991DBE786E30E
+:104980000FDBBAA01DE388978CE86FFC89E02F4508
+:10499000FBC4289F5319FD1853ED33AF1570BE5259
+:1049A000D2DBF25CB3F3617DF2F74A49FC1DE0DE35
+:1049B000D1B83E467C6C03F9E6557EAF78AC6C47C7
+:1049C00028ED3C5F5832350FBECF7FCC3183E2EC0F
+:1049D0001DFC7EF04E3D8FA7F85EE5E75BF33BFAEA
+:1049E000348E00FE3E99C7F590679CA5141FA9EB75
+:1049F000845D16F9A9EDAC1EEF65D4757647E17EAE
+:104A000056E03CAB47BFC960BEBCCF89FDE168AF93
+:104A1000FFAC3D743C6D6D9E9EF8E3982CD7AB1EA9
+:104A2000D672BB913966E1B971455E57EDE7E3ABEC
+:104A30005AA8E7E760311A1D426E839C3EAB96C3CD
+:104A40000EF57E708B7F3DCA0E90DFAA7A4B174C15
+:104A500027BBB712E436F231C87375797213C917E0
+:104A600090E7AA7C77DE803CCFBF0EDF9D766A425E
+:104A70008EF3708148F378DA3595E6FF199847F49C
+:104A8000A73D3364DEF87CDE6CBE5EC6B50F58B75A
+:104A9000E07ABF2EE0EBF6F230F2FA7D795D770A2C
+:104AA000BD45284CDDCE70A2DB254663099E7B38D0
+:104AB00096F26513C6E1AA7E2ED03DFD7FEB3E6ED9
+:104AC00041FD5FBFFFA805FD61EEF6A316B04D598D
+:104AD000AD4E5A8B7A3CD0851DF59EBA8E2EC27F84
+:104AE00065FBB86ECC5FD921D0FB3DEE0317A7D391
+:104AF00038595F13C60B770E83D78FF2B8FEBE37D7
+:104B00004FE27E3017F489FBFD0183DF2F201D80EB
+:104B10005C42BC5E17F0E535B673A3B122941EF576
+:104B20006FF27C1FD9A867E8AFAF85EF711CC75241
+:104B30008EE98D4847FB05B2B5DDED27174660FBD2
+:104B4000F53A86FA8582DF1729BD1FE2F83FA8D61D
+:104B5000A1A78035566B69BE3FA8D7523BDAFB74DC
+:104B6000042F5EC1CF551CAEFEA82909DAFDA05660
+:104B7000A07B0C53EFFBF3318417AFE0FA5A303DC2
+:104B80002BF41A4C9FC1F43B844E6BBE199D1EC979
+:104B900093EFD5E4B102DCE761DDA759917E1EE118
+:104BA000F7E32BAE1DD6A17F33BDC96C7F02E03188
+:104BB0005AFF7A0BCA89C3BCBCB07687C0E58D7436
+:104BC00037F26152B39EA1BDFB7E1E974BEFE37A95
+:104BD000C5E3D0FA058CAF31B1371DE5529A1C4FB1
+:104BE0007A45C72AF6535C90CB9B31AFD954EF96E8
+:104BF00037E571BD43918340E6AEFDE4976D4FC448
+:104C00007B142FCBE74153E5F6B232FAA7CF85F4F8
+:104C1000AA4C2F67643C14F8B24CFF6CDBCF681FC2
+:104C20009F2DC759663674D179CC3C83EB5394875A
+:104C3000B352DFABC57DAE39FDED7C3A678D3725CC
+:104C400026E2FBC9FC7778D2A7DBD660DC2F379C45
+:104C5000D631ECE053741E382C6BBC35549C434960
+:104C6000DD57257A8FB0EE6A3AA50A3CF7D0397D38
+:104C70001FD90117A7139F5CB5A9DE2DFC54C67B75
+:104C80008CF23E5D27F7F3809C168B8B06EB29F3A5
+:104C9000809E651C6F58D62E5AAF35AB5821A9752A
+:104CA000EC29FECE66ED4901DFBD58A473E84C3017
+:104CB000DFEF8D60251F8BFC1D245736C64D8C748D
+:104CC0002FFB84D74C70AFD746F029AF44E9AD61D4
+:104CD000CE887C6867E1114F16CEDBE1945627DE63
+:104CE00057BCF08E4EA66B33BF2F2ED3DAE54E2D78
+:104CF00033629CEB00E8E3C220FEF75C4DA4FBDDD1
+:104D0000BFC3FEA09F950DBF217967AFB9381DEDD8
+:104D1000A2C2DA334D08BB1BFE3C1DF5890F61FFB3
+:104D200020BD1EF47B9B8072E424BDD35D79358663
+:104D3000DA7959D33F1DF9CBF7A640F76F3EECB8AF
+:104D4000A8B7F2FD89DC73782F1CFDF2B3F2A3B98A
+:104D50001CE92CD4D0FA3A24D53BEBDDA3FF2B0A77
+:104D6000D7C3D820FD7A0A7EDFA365C8BF9B4AFB64
+:104D7000A3CC21E4EF69F4DF65F371B0ECA1E51594
+:104D80007A5F169E93AC90E938B8BC3C7FC03FA1D7
+:104D900073CAEFEB0801FEA12AC6DF3F05BBA72BB4
+:104DA0001CF8B8AA732AF967AA3CC20DFD33C3D117
+:104DB000E1D74DEB18F7CF2830DA8D817E4DB41B4B
+:104DC00099AA7F1F7F072B25F386F774DC7D891452
+:104DD000CFAF6B6614EF5A797534A5E75FDF2021FA
+:104DE000FF18C3FB5BE97E6BB686EC8C953EB5FE87
+:104DF00033A580CB8529057CDE5CF9602FE5B00109
+:104E00007B09ECA27BF3B95D147588A9ECA5E07C65
+:104E1000B2978CF23D1D1013AE5742E07D474169B9
+:104E20000D7E97CA5A88CED93BFCFE72F038D7E483
+:104E3000733E55F87A31F235D26F07E7EBE076E74B
+:104E40001594AC413EDA384C7CAB5CE6FB956D8C3E
+:104E5000E6CBDD1643F3F4056B7396025D7E0178B5
+:104E6000E03DD20B4E6744347C7FC1E58CC0F33DFE
+:104E70008A1CA86B0BA7EF3666CE8BC573A3CD48F3
+:104E8000F7D0DEF98EA9469CE77BDA38FF29FD7D55
+:104E9000D8B53816F96982AE5F6F87F2E4CE335128
+:104EA000A8F74D787D7E2CF2E17078FEFD1819CFC1
+:104EB00086C4121E9787BD70A26C4F007EEE27BA83
+:104EC000E89DFA871A18D16FF7ABFF56877C7CBE36
+:104ED00033C28CFBE6170723E8BDCA0B6F1AE83D07
+:104EE0009A5AF97DD52F747D7348BF7C5D4BF722AC
+:104EF000DD6FFE472BF2A3FB55039D3B7CA873C3DC
+:104F000045DCF76A3B679CC377566B5FFADBF2C3FD
+:104F1000CA8654D28B14F83FBC4627BEF37B5EE4AE
+:104F200072E2A18E7F217DF7A16B970BF07CCA17EF
+:104F300007FFC744946BEEB72E4F4479E6FEC5E5F4
+:104F40008958EE7E2DC2134A5FB95EC0FD3ECA7E0F
+:104F500099F6AEA8F20FAD90E9236D5D0BBD073D4C
+:104F6000E1E4027BE0BB0F13B2344EAC3FE1B76526
+:104F7000B1F7057CB7AE57A438E3F8936511D501B6
+:104F800074794F814EF12F7E23BF0E93DFC719F046
+:104F9000E3F4F2777F36F68AFC7DA31A81EEA183D3
+:104FA000FE32E45E1AADFF8A587ADF8889CE3BC7AD
+:104FB0008C47388BDE05623EE3D1CC003D6971AF92
+:104FC000A6CB007454D169E822FDBE573C43B0AC77
+:104FD0003FDD73F1D3C83421847F26E7D43494E3D2
+:104FE000C17E1AF84522DE8ABE55E971A520FEC1B0
+:104FF000FE9BA51577907F28D87F93D62B6A668F66
+:10500000C7F7DFE93A2F8CF76923F28BA287E2FA20
+:105010001D08C1FF6BC67039A6F0D5BA5E1EFF5DD4
+:10502000D75B6ACC84B456E6AB03B09DFAA0FD759D
+:105030009DF377A31F61DDB545116360BED6BD3B0F
+:105040008F3D81FC6F2E3566E177D7EE302ECC1F79
+:10505000A497E0FEA68CE1F272404F1866DFCB9772
+:10506000F1FA5BED7F3963E4F36CFF87EF7F6087D4
+:105070008F1DC3EDF025DC4FC2EDF0E07D4391C7FD
+:105080004ABB2E799D87CA63FE7748C05E2679ECBD
+:105090001A2351BDE4CEB9B16447BFBB2056320DCF
+:1050A0006D3F43B46B62F287B6AFE8716E9FE3A8C1
+:1050B00011ED1C8796FB491708F4BE99A2F7B99D1C
+:1050C00002E9E3EE4A9D1FEB2978F52EE07ED585B7
+:1050D0000E9D3F4C18D40F15FD71A0DC2E50B9A2C7
+:1050E0004F2A7A63AF93FB71178CE7E5B786B91641
+:1050F000E17C7DD81546F91326F17CC69C479300C8
+:105100005EF43D8111FFCBFAA442A7C1FAE6A5CE19
+:105110008C1BBED7B34DA64F85CF5283F843D9BF62
+:105120009AF339DDD7E1FE1D8BFBF77FAAF4F2E09D
+:105130007661FF7E08F16F461D12BE1FFF5BD1191D
+:10514000CA3EFF4AD60BFE5E59BFDE232588AF72EA
+:105150004E76B87DB54ED66F862B6FCEFF7AFCBCEF
+:10516000471EDFDF8A9F778EF9BF439F1DD00BF567
+:10517000A1C7794741C94FC6C0BC866B3D749E73B9
+:10518000B8F7CD1E95F555B07355747C3445AF41D5
+:10519000BBC85DC3FD03CDD1D2AFC97E39AEA5F783
+:1051A000571E92EF733E78D54C692DEAC9902ED9DF
+:1051B0007B92DED95D52A3C6BF197DB7F8FDAA3434
+:1051C0008AEB57B132F22B5575469BF1BC7F737C4D
+:1051D000FB31E42BDF6EADB43BB0FEC6D1727D2354
+:1051E000F7B7D544D3DF8F61417A40952758DF5711
+:1051F000EB0553643FD170FAC12FBAC3B85CE9D153
+:10520000129FD739F9DF55D07772B9E06E0823BF06
+:1052100009DA6B88D7670D821FDF3D5F29D7FB4C0A
+:10522000EC25FF13C5D3A0CAB9CEA72C0EB2DFD48C
+:10523000F1A395BB7E4B7233388E1473408E0B0DE9
+:10524000C48D26D2799095604FE29FBC724BD25D9F
+:1052500038FF801FF393DC71A8FC30977A3E22FB65
+:1052600073C9EB3CFE33247ED43C93C78FF0DD95AD
+:10527000107EC8A5238F1DC5BFA374B3B8515DC7E9
+:1052800049BA473244FF08D23BAE8D51FB19478AD9
+:10529000DC8F3BB25330A37F6AA43C8F7FB7319C35
+:1052A000F4EAE97FA88E4579A0ACD3F9B97C5ECF4A
+:1052B0007F70A504BF9BF807D11C06E3FAC507F56C
+:1052C000BF49E2B06494F0BBFA08B463CEFF6175E5
+:1052D00004CEEB2F20C5BF2FF1DA6931A43FD22BCA
+:1052E000CB2DD80FA30BC8BF2CFBA545D80F230788
+:1052F000FD39C1DF6D97BF6B063385FC98AFF3F8BE
+:105300007E73826B26C1CFA633FE1EA683FCCEFF22
+:1053100002748DFEA23C182CC69F7F1ACED661BCAB
+:10532000A839DEF536F1D1B31A09F908BEA73893CA
+:105330006FBF44FB234E19C6730AF4FC5D46EA0CAA
+:10534000D66BB4BC8E0960C7623C09B05980F1E6E7
+:105350003C39AE5310CE446CFF499D6B13BE97F998
+:1053600064B7685F4B4C608FC577BF83E34B828324
+:10537000C7C5953893121F1F2ECE24603F059CEEA3
+:10538000F8B91587807173259EC4BEE7A4205763C2
+:10539000B187CEF73F53C848AE7F8B719E25F92168
+:1053A000E24835C86324CFD571C54D39AF109DFE95
+:1053B000B5F1C43D63D8B71CFFE2F3138CF7F8E8EE
+:1053C0004B16B2B7BEFAEF51B4CF765EA6FDF042EF
+:1053D000BF41BE8FD0C7FDEC9D3AF22F5C00BB2DC4
+:1053E0003E609F3D9ACFDB3DD43995E8FF406F5931
+:1053F00004D63F2FE76F7C77C1FCD94897BD22BD0B
+:10540000078BE7E3D00E3BD02B4E40BDE55B5C97AE
+:10541000EF8F09B12EC6F0D0EF4CE4CB7C945FC087
+:10542000E963EA07DCFE72D7F3388A59960BEE720D
+:105430003DC9C163291641F19F5B43C5595EEFA782
+:105440007DA36A8540F71CBE719CA5A35BDEB78275
+:10545000FCD3E5D3496E0EE7B70E889BABCAB715F0
+:105460000C9C8723FF75548199C61DE3292CC1B379
+:1054700087CAF8BFC575B8736C083AFB16DB5F695D
+:10548000FF6EDB9F92F7DDB6BFE63B6E7F6DDE778A
+:105490001BE7DEF11DE37FF53B6EFFCC773C3FAFB2
+:1054A000E5FFFF73000370709C3FF85C4070BCDF49
+:1054B00070FC3E1F966D1036F777416A8C7AB542C4
+:1054C00000512D46EFA27708664DE271B08D65461A
+:1054D000FF0E61F07C80325F4B0BB91D61CEBFE8DF
+:1054E0008B85794E75F496C5A29F6C127F87FD82DD
+:1054F000FCCE2A13CDF4CE18D44CC0FBF1CD61A163
+:10550000E3AA61727BC3ED23CF1796DC31369EFE92
+:105510006C43C8FB1D2FC8FE47730723BF2413A588
+:105520008479D4AF9480FAD088233C3FAA8B397613
+:10553000105E52DA3CB207A534C46F8B1CEF8D9914
+:10554000999D86FEE818D00B311EF814C605298EE9
+:1055500065A67A4A7F1F8CE5FD6DD13181EE5BE552
+:10556000F2F34CACF9A02A9EF78EAEEBE36502C5D0
+:10557000F39623FEBFD274E5EF4C938918E637FF0C
+:105580008099E28C2726BD487F775689EFAD31F3AD
+:105590002A87D16E063CD61C1C47F4BBE4D0A4F786
+:1055A000F1E93377A6680F754F51F1179C96FD1DF1
+:1055B0008ABF40896BFD5EF6937C88FE17BA1F2276
+:1055C00051EA1DABF9B6F727EFD810FCBF45E0FE56
+:1055D00021DFAFB87F689CDE9E11786E72B33CAF5E
+:1055E000CBBA78DC42F1F7EC93C733EE116D97013B
+:1055F000F6D2714D63F4B8CF8F6B4A09C7B4C0E1DE
+:10560000D7E07DF0C5D5FB35CAFA85A2A3D6B1B2E5
+:105610001FA3A79FE27AFF1214E7FF602C3FBF3061
+:10562000AF90E3F101D82408AFC9121B517D1C7162
+:105630008B591B2A9E54057631E2B9AC99E3ADCC67
+:105640007755973415FB3973B4BF09D3A29AB4A91F
+:10565000E46FAFBDD884FA9BFBDAE563B793BF4C28
+:105660002FA13D714F9FDAEFB60AA3A5F18427FD64
+:105670009D5ADF0C91ECE3713344A29F98AA30B29B
+:105680005F63744C6B42782ED78B8ACAE3A622CC18
+:105690001644933E58D42345DF973FE8078B995132
+:1056A0001F8FF374B3F8AAE24FBB35CCF11AAEE703
+:1056B0005F1B5F5DF9CEBB74AE541997322F4A9CC5
+:1056C00074B8F8AA72CEC15D7E45752EC32DF64F13
+:1056D00047FFE3B88367F4F2394B33FE1D6125FEC3
+:1056E0003AEEF58B147755E2AC6ECF45D2ABE13B89
+:1056F0003D7E3F0E963F2106DF17E2F1D757F19E20
+:10570000941EEFFF99E9BED41BF2FDC54E183FE68B
+:10571000BFE9CDA1B4CB6BA7F490B7985277E7451A
+:105720008AD77E38561DEF53E27997B4CE3363D5CE
+:10573000E723090E8EF769C3B9BFC6DDA3A3BF97E0
+:10574000E17EC748F2BBA47319DDEBFAF2A46B2427
+:10575000E25D87F1B600BA38EFB087E13B61E79DC3
+:10576000F6308CB38DEB3EA7C7F32F7562AF1EFDED
+:10577000618071121E4D741FB8C8CFF77696D0DFC6
+:10578000E3BA695CACE36F1317FB9FE541012100AD
+:10579000800000001F8B08000000000000FFB5170C
+:1057A0005D4C5367F47CB7B7E596DF0B2A3F227256
+:1057B000C16298A2DCC240A7311674AC135C8A4A5D
+:1057C0000201B5662E92092DD9CCC2CBD23A8901FD
+:1057D000DDC3B2B864F3A92683E8B687FA93AD6E49
+:1057E000550B0B84252EE2C39C71C9520D3333BA7D
+:1057F0008162DCD85CD839DFBDB5BDD8BD2CDAA458
+:10580000393D3FDF39DFF9FF0A003007DAE756B9E3
+:1058100006E74CF8A5CFC6FF0F3DA44F8CE3DDBDD6
+:105820004BEB2617C4F1BB3EC9356903F85D9CCE2E
+:10583000942B00F687CE5A1C041FCFAC7621FCEDCA
+:10584000C2DFB54A3A80F7D24C2D20EEFD66A6960F
+:10585000F8DEAFD27A02E94FDB7BD78E975E047019
+:1058600096416B10F9552EC17182E0B8C3FA4645D6
+:105870005C6EC02538E9FC80AD349BE8C75CA5D9D7
+:105880007B13F4F539456700E939AFDAAC89F409DF
+:10589000BB19A006E90C5CC124F66B5581DBDF7FE8
+:1058A000D22A4F4A7A1CF1DB1DCC36E0DE50813C17
+:1058B000591EC7F7D38F02FC6E6622D40274E9B971
+:1058C000B86472D7AAA8AF3B3F6A8152A24C5B5C16
+:1058D000AB305EDF4BFDAC1260F8FCBEE268051732
+:1058E000952017A04D3F37E0DC5B9CB110C07F3D99
+:1058F00005CA98461391DF4A3F148E2A22DA69A717
+:105900005F78E5B6FCF7274CAB11BACDFE68C2BD97
+:10591000DA9D82C39AC9ED2E6DCE207931CE2F212A
+:10592000A5D34BB7AD22CC5128E413F417C25A02C9
+:10593000D2A8AD366EEF06047EB0A17C9B5388A43E
+:10594000A09DD6704A04506F955304DF8B087BCD21
+:105950008112467CF126E72B6F3611BF4FAE2A0429
+:10596000F4E3E7CB16794109BFDF6434218EAAF353
+:10597000D3FE523CAF763195DC6AEF34F2F19341BD
+:105980007EEED6E3B23334FC7221F75F36019ECB54
+:105990001D03388E7677F618CFED6E75DE61743F95
+:1059A000F8A07F33CA814D900789DE6B94A33A3B00
+:1059B0008DF11F007026D64337D5410D41C6E1E772
+:1059C000E813D54515062A58113F37BF7E4674F9AE
+:1059D000F9FA62F00CF117517D560DD828BF4D022F
+:1059E0009401E1F5922D419F5F15B99E0F6501FC71
+:1059F00028D717DE3EC8307E7D8F5F915A506E4AA1
+:105A0000AE97CAD2E3B8F732D6531640F5F06C031E
+:105A1000C5FB589881154D79F3F1BE28577DB16EBD
+:105A20009CAD4EBCA7E6DF31CCF9443AD5819A0D46
+:105A30009A5F2061BCFC17586010ED55353D1C493C
+:105A4000A3F8B9B2D53285ECD80EA523EE6D126B52
+:105A500018E12E3C40F80E1690F0E7F62B9D5B0007
+:105A6000ED54B7D8AF52DC5B3ACCAA1588DEDA40E9
+:105A7000F46B5950372912FFC47BA9C42F67AA556C
+:105A800021BEB39EF88D5F4444AAE7AD14A56578A6
+:105A9000B7CB288D7DB3C1EA0E501F5537A311F443
+:105AA0006F47873540FEB5849BCD90CEEB41A0BEBD
+:105AB0007B5BCFEDB7458F32A3489F095767915F56
+:105AC0000BCCD316156135EA2EC84178E1BE05B07E
+:105AD0001FBCE2B44546B9733E4CAC05E04B9FC4D5
+:105AE00061C827836339C0D7BE7C0EC33E85D32FE0
+:105AF000FACA398CF8540E477C6B35A8CA3C9E957F
+:105B0000E1FB02DD27A75970259B6F7EBD3E62F940
+:105B1000AA0BEF29A67B3EBAEA2E9693C8C7205A55
+:105B20002C14D66AFDC930675EE7C306B2E381E88C
+:105B3000613AA760BE610D46218430EFBFEB6FAACA
+:105B4000529B6FD902B893F167F4FA048722D03CD4
+:105B50007A4BD2FA7F78C55F3C9E5248B9B21EF3A9
+:105B6000E61937410AD28FD46B737FBE9EEB184F74
+:105B7000C0B8DDC078129CCF6FB5F8CB281FAD74CC
+:105B80008F24E7A7F4FAC40A30BB32B49C32BC4F6E
+:105B9000476C0E6020B2308F1D211649C53EDF19BB
+:105BA000DE744724D8C3E096717E3CD77DD8E646A4
+:105BB000A589F3B6338D26F9135C4AD5E22C593406
+:105BC000D86FD5F65A935D8B730C6EB56B75719467
+:105BD0009A05EBFBE879163888FDE7A918BB4E73E8
+:105BE0002CCF01D08BC3C7939F1E31D13C0F99EFAF
+:105BF0003D99E3D81F798A0C1D3994370C26F6415C
+:105C0000817E0724C06D9463911C616E25CA2D1995
+:105C10009F257D9FD8156E2F77579001BA5004FEAF
+:105C200083345F462D50771AED779D637090FA3B71
+:105C3000E00205F7FDE8F11B874F21DD738EC9B443
+:105C40008EBA8357F99EEF162778FF78C2772DBC5E
+:105C50001E8337357A88390249F23A40FB1DED6ED2
+:105C6000467F686E741F300552D06EC339ADAFBD2C
+:105C70000E4B40417CACE81D91F09DE719E4D11C2E
+:105C8000532616A511FF80190225DCAFA6BA84FDA4
+:105C9000845F85FC8EEDCFD8FEF1C0F45821D56B22
+:105CA0002753230ADF3FB78CFB052F921BDF2FED15
+:105CB000A16133CD1BDC4306B9DD8E863B343F71D9
+:105CC000CF18E94B0EDFE7F98028AF53DC2F067EB3
+:105CD0008D3D63E16D2C095809157338CF3655CACF
+:105CE0003CDFAD6EC6DC181F497075919F7091C97D
+:105CF000346FE7C7ABD1AEF541A39F412FE677C81C
+:105D0000A2D5C7D03A16F0A37C23A294F7A18B7B2F
+:105D1000FC0CFD1CAA62AA40F120218CC7163D3E56
+:105D20002F801F6E4BFCA9706CAE1AE035AC612B56
+:105D3000D653A35E0F00016EA7F9E3D408BD238EEE
+:105D40009A83F92A7F97F8F97D6755E0FCD414E827
+:105D500049D6AF6BEC75B36A0DC93DF3F7D32E7B13
+:105D600092F7D347F876223B7BED4C24BF30BE2B15
+:105D7000A9BFEF155DCB1C41F481C9B58FCE755914
+:105D800022ABA9BE1F98DC1C8FF191EEA1FD828B86
+:105D9000EF16F591008CCF8723E567CC949776A218
+:105DA000C7EE5B1297E3B8E969FCA10ACFDAEFA16D
+:105DB000CA9AA7FD7E86FA17ABCF577F6EB2BC1D7D
+:105DC000A2F997A47E7ED2E71FC01299F7CB933831
+:105DD00083B68764E0753CAAEFF57EA6FC487BC8D5
+:105DE000FF9D190695F85CEDCFD0F47FA6EB8BC133
+:105DF000511DF69B35B9F9F627F439FC8BC9718A28
+:105E0000EEBDF2A4004A82DFAB82A9A024F85D199E
+:105E1000CA31E0F6C862837CF578A9815F33B1C2EC
+:105E2000C05F73BDCA80BF145D67905FFF6BBD012B
+:105E3000DF30BDC520BFF1CF6D063CD6BF7558B968
+:105E400089E73649AF1BE40A3B8D7E15F518FD2A1C
+:105E5000EE35FA15D35BE237FAB7ACDFE85F4EF602
+:105E6000835C85DEA1FFFC9149FB60203CC3F334D9
+:105E7000359D02133447C4A8B61FC266BE17A6F0EC
+:105E8000FFE2A2843C2CA7D73FDA19092FB3D2B97D
+:105E90000F9D362BBDDB2E510D603EFE05D7762EB5
+:105EA00017E00E00000000000000000000000000ED
+:105EB0001F8B08000000000000FFE3E36660F8515C
+:105EC0000FC1D3B81818367221F84301B7334368AD
+:105ED0003E16060601207EC7C8C0F09E91043338E6
+:105EE00010EC7E20BB0A88277150CF7D43112FE52F
+:105EF000A19F5D5FA0763D1518787F83B083100366
+:105F0000839B300383B40884BF5F0455DE5108C10E
+:105F10007E2E41995D9F81FA018DEBBB318003009C
+:105F200000000000000000001F8B080000000000BF
+:105F300000FFE57D0B7C54D5B5F73E731E33939976
+:105F40004C260F4242004F08202A842140088838FE
+:105F50000990068D9A080888CA000142483211A9A2
+:105F6000975E6D672214D16A1B2D6DA397DA0141EC
+:105F7000A3450D18E840031D4C41BC5A8D0A4A5BED
+:105F8000B541313C0A4978E8C5D65BEF5E6BEF332B
+:105F900099736642A2B6DFFDBEDF177FFE36FBECCB
+:105FA00073F65E7BADFF5A7BEDB51F2359C613D345
+:105FB00015847C057FD71372482484F4EB4E3B0B89
+:105FC000683A8E107F8E39B0552024B4EFEFED245F
+:105FD0008590B34DB355732621FBC79843D7D3F2B1
+:105FE000B381FC8099964FDD79C421D17CD54E5187
+:105FF0008272D33E2B7EDFB1510840DE6B6EFDF125
+:10600000B534DFB553249B69D5246437915442DA03
+:106010002D84FDA9F1985F6A65D9AA4DFBEF82F640
+:10602000CA836662A5DFB737896EC8AFDC2A040869
+:106030006DAF6AF783CA005ADFB280D06855697EB7
+:10604000EB638A1A4FC803FBFEEC68B31372DA677E
+:1060500021AA82FD286F1C494845607BE100FA7D3A
+:10606000C536C165A2F5576C3CD701F45534C9C398
+:10607000445ADF8A061B5147B0B6BF22D05ECB0719
+:10608000D8DE4E7928B457FEE53D0A11A19FB21B18
+:10609000BEABA27440BFB5764FFBEAB13D8D9F55B4
+:1060A000CFD1F6E87BD52F0A2EE862B58978808EAD
+:1060B0008EDDD6B94FDBA17FB5CAF0F8C87E2CDCE7
+:1060C00005FDA8086C520AED40DF2665E9C8EEFA26
+:1060D0005634FC879EBEFAACFE9E8872637ADA471D
+:1060E000593ABC3B5F4188BB91D64BA480523AAA37
+:1060F000FBF907422221E3A17E91A896EEFAA9E4DA
+:106100001107FE23F49F940FFEBDF181AD99DD725E
+:106110005BE9049975CBEDBC93CB51EACA8DAC5FBA
+:106120004B7F0CF2A0F4D4F99C983EEE4BC37483E1
+:106130004F45BEFDDC3702D37A9F0B9F3FE9CBC3AF
+:1061400074A3CF8DE953BE224C03BE127C6FB36F94
+:106150002EA65B7C1E7CFE8CAF1CD3065F0D3E7FA3
+:10616000DEB71AD36D3E3F3E7FD1B71ED3465F1DCB
+:10617000A63B405E346DF205F0BD5DBE064C83BEAD
+:10618000467CBEC717C4F411CE47C764922F513E58
+:1061900038DCC449C54E928ADDF932CD2795B07CF2
+:1061A000EA1DFE7C85E6533D344FF932A032946FF0
+:1061B000A6F90135AC7CF0FDA4C042F383FDAC7CB4
+:1061C000C823EE022BCD0FA963E5C337FA0BE268B3
+:1061D0007E7880955FBD2D5460A3F9AB1B5979760D
+:1061E00033996AA7F9EC10CBE7BCE19E1A4FF3395B
+:1061F000AD2C9FFB817FAA83E673DBD8F793CE0497
+:1062000044D51E2D871DB2BA9850596DF4CF704BEE
+:1062100013695E51EF212ECA1FFFAD6E299DF24317
+:10622000766379C83F1FCB9B143796BFE32FC3FC1F
+:106230002ED983E5C7FD552CAF78B0FC73FFBD9810
+:106240000FCA7E2CB7D4FA585EF163F980DAF5589C
+:10625000FF1E3980E5236B1FC3F23D4A00CB1F5F51
+:10626000FBA47B1ACDAF113C3F073CD2B49C640128
+:106270009E1AD34A289ED609642EE0F707003A8A70
+:10628000CB75E90AEAE18E3FE43E0DFA8B7F299057
+:106290005FFACCC399F8FDAFB01E99D623F65E4FD6
+:1062A000CE9B79BA7A72DE2CD7EA6980F7D658FB92
+:1062B00056CF8E3727E9E979B342AB673BD213DF7C
+:1062C000B77EE5BC35594FCF5B955A3D7B909EC458
+:1062D000BED1D37444CF9FA62361FEB4203DFDFA06
+:1062E00046CFB8F7F4FC19F75E983F6F603DE97D43
+:1062F000ABA7E93D3D7F9ADE0BF3E708F66B50DF75
+:10630000FA35EE7D3D7FC6BD1FE6CF47484F66DFBD
+:10631000EAD9F5A19E3FBB3E0CF3E704D633AC6F40
+:10632000FDCAFD48CF9FDC8FC2FCE9C27AAEEA5BB2
+:106330003DBB3ED2F367D74761FE7C81F58CEA5BBB
+:10634000BF72FFA2E74FEE5FC2FC310950CF98BE8B
+:10635000D113FC54CF9FE0A761FED8B09EF17DA37E
+:1063600027AF5DCF9FBCF6307F520490FBC4BED5F3
+:10637000136CD7F327D81EE6CF20ACE7BABEF52BB7
+:10638000EF849E3F7927C2FC198EFDCAA77A0FF4CD
+:10639000105A4F7CCFF5EC39ABE7CF9EB361FE8C42
+:1063A000C67AA6D37AB27AAF6752879E3F933AC233
+:1063B000FCC9C37A66F4AD9E3D1D7AFEECE908F394
+:1063C000271FF97353DFFA35A953CF9F499D8C3F9F
+:1063D000630FD74C75D0723A16BA44FAC9B567DC68
+:1063E0006E81E64527CB8B4E1701BF44D4FC0DD2FE
+:1063F000EA16E9F7F66D89390F9348BFA3A014FA9E
+:10640000154FBDB148BF23212F4EE7E724BA93743F
+:10641000F9E4A201BAF7FB950CD195F79F7BB5AED5
+:106420003CDD93A3CB67944FD2BD3FA8A64097BF56
+:1064300062F50DBAF733FDB7EAF259EB6FD7BD3FFE
+:10644000AC6E91AEFCCAFA0A5DF9558195BAFC357D
+:106450000DFFAE7B7F54E303BAF2D1C18775E563CC
+:10646000428FEBF2630F3DA97B7F7CEB665DF98485
+:10647000A3CFEBCA27B6EDD0E5AF3DB9C7E0E7D96A
+:106480009DEDD7F0BC08B827CCEF4F57D0DF0BC538
+:106490002B985706D8D18FDF1FBF543D4EE5ABBCBC
+:1064A000B2584DA1F20599123AAEE70F28BFB28D4E
+:1064B0003EBF7792E74A277D7EAFE219ED8CE19FE0
+:1064C000523C08240D52D504A9B1FC4199E1B120F8
+:1064D000E3CBE1C7E8F75E53D7F0449AEF2FE6D756
+:1064E000035E9E124C88D33891D4C07B716682F3D0
+:1064F000820733739FF647E075FD20AA874277BD78
+:10650000EB654F1AF8199B6BDFF6831FB26E10ED27
+:10651000D700429E16DE0EF987D2EF072D4DF3D03D
+:10652000FACC0AF5D323DB5768FB23B1FD0668FFDD
+:10653000C51EDA370FC9D3B56F195CAE6BDFA2D0B9
+:10654000F69DD41FA8FD236F9F0A6112212F0B7F98
+:10655000C4F6CD83CBB1FD07153A5F896C3F2EDCC5
+:106560007E10F4771FB43F3E46FF874CD2F77F7012
+:1065700085BEFF0AEBFF2BB5C778FB71D8FF16E18C
+:1065800018EBFFE00AD67F33AB37DCBE23CCFF43EA
+:10659000D0FF377BEA7FD6647DFFAFA8D4F7DFCC8E
+:1065A000DA7FA7F6146FDF8EEDBF2B9C62FDBFA2D2
+:1065B00012DB57CC1E17E047C988AB09D0F6C9409B
+:1065C0006A98FA035C683B908E48A2A026E4516169
+:1065D00008D2716F1CC3DBE771146F686FFCF89C05
+:1065E00004A865CBA5F32E8EF515DBF215B04B583C
+:1065F0004EE72B4B38A9654111F14D369803C3285E
+:10660000BD1D41D10FF9B20DD705C0FE79CD644152
+:10661000097C2791103CFFF467A33647F6CB982EF0
+:10662000A993DBDB22F42D3C8F2A20236A287DD31B
+:106630000104E3BBF31FD37910A1F38B0FE83C8374
+:1066400050487E22B3F63EA2F325C8B7D1F9129482
+:1066500013528BDFD1EA0EA751FA4B38FD1F4B4C7A
+:106660005F3FBE4308F8A97E7EFEBD31384F5DB066
+:10667000DA4699DE4DC7427FB22E4FFBE5073975EA
+:10668000ED3607360BC85F15F8558AAA49C8E2F5FA
+:106690001994D7DDEFBF4FC59E4E597F1B71CBFDBF
+:1066A000E9FB77AE12063969BBB3DDE61C364EB89E
+:1066B000334CA8D724C39447C8AD4D63645A03290B
+:1066C00075CB1FB745B43BB3489F9F5DA2CF77C83A
+:1066D0006ED944E9EA2815C8265AEF9CB9FA72AD7A
+:1066E0001DBB2989C999B75792CAE89B03690E3C1B
+:1066F00076A29CE73AD9B71A3DDEC5329DC2823CEC
+:10670000FDFD08C8D59F82EFDDEE64FD36D23B5714
+:10671000B6B84B683FE72E1403806F23FD7FDA671E
+:10672000739BB269BAFEA7323145F7C748FF3C8F69
+:10673000B13F8D328CC3F3CB8DCF196EDAB9FC3FEC
+:10674000067CD0F404E083D27F9CE3A3DBAE327CF2
+:1067500078CD9E9B010F5D4F8804E5CAF1721BC77F
+:10676000CB923A3D2E08F1C820C76573859C8723DC
+:10677000703087E36059BD1E377712BF9C1E432ED1
+:10678000F3366CFA619A1ADDBF0F396EE63FB21F1D
+:10679000F913DD4F26A7BBB89CEEACD197DFC6E559
+:1067A0007A2797EBDCFAC70E50F3416E570332E8B5
+:1067B000BBF73E4D9E6D3A797AB83C8D74DEC5E5E7
+:1067C00079D7F7983C8DF4B67179B6D55F90C990BA
+:1067D000687A8DF42D581DD51F05E4B9D01F5B9E36
+:1067E000DE607EF2F188E7558D33928F47E8D98AD3
+:1067F00086525D7E79609EEEFD65F50B75E54BEA90
+:1068000096EBCA17AFBF5B975FE8FF9EEEFD05AB47
+:106810006B75E577D63CA42B9F5FFE982E3FCFF398
+:1068200084EEFD397337E9CA67973CA72B9F59B4AB
+:106830005D972F75EFD6BD6FDA77D52D80CF378E68
+:106840008804FC89CF5C27302EF8994B76C13BC772
+:106850007D2AE2BADD3702D3933E17E2FEB42F0F52
+:10686000D38E608B1DC6093A2E2E2589D4CC9B6E03
+:10687000AE5D3F10C66982E3E916D3AC5AFF6442AD
+:106880007E6D5291DFC5F50A098D254480C186D3FE
+:10689000D1254694B7F5525E4F0D7F727479715BC6
+:1068A000ECE7DEC7175EE18C1177E9D65392017EE3
+:1068B0004F27F7BB8DE5950229897C4EC803A8D7E1
+:1068C000E7F8B85BA930FDAFDC915E401C900F0D7E
+:1068D000AFB95C7B8D14E4FD0127593A3D5E567FCC
+:1068E0008DCEBE1388CAF603BC8DD53D5FD170AD89
+:1068F000EEBB33FB45A4BB1A6CC54418164B5E3780
+:10690000811D0EB50C9E390AE874BF6182712AD8C8
+:106910000FFDC233BEA2E4E312C8AF04D393BEB9E5
+:1069200098B6FB3C981EF79563FAB1AF06D336DFF5
+:106930006A4C3FF2F931FDC0B71ED33FF9EA303D52
+:10694000EAABC7F43D5F00D3C3BE064CDFF135624E
+:10695000DAEA0B62DAE17363AAE95D6FB83BC9C793
+:10696000E1D380BF1838EB786055EDFAC9DD383BCC
+:106970006FBAAFD63FB09BCFC5F5668E87541D1E4C
+:10698000BE806033E2AC97F27A99E3B0A7EF6397E9
+:106990007B37FF6BF036DEC4FCCC6F8AB76E3C658C
+:1069A00018F094D51B9EFA89E3BBF134DEE4647ED3
+:1069B0000FC7D38FA01F31E61505E084F48BF0D705
+:1069C000DC3616A7E6EB09D45365716ADEF61AFACF
+:1069D0006E2BFA758111306E9C1FF1B7E110873F65
+:1069E0007FD44C277D3DF7CF88939EF9EEC6F9CD35
+:1069F000D2001DBCC646975BE3185FAD265244E843
+:106A0000B8F6D0B0675C8B46625E2249F07DC05517
+:106A10001A1FA35EEA2B037F7BE3EB9AF8CFB3A1A7
+:106A2000BEF627FF9E0BE97813F397E35A44F4DB95
+:106A300049E86917F0373C2E995D6910DFEE1AA618
+:106A400038D16F08D8F5FCF3D37C6E37FF1EA23C1B
+:106A50006AC571B72E0DF937F4F3E1E97DE05F6F98
+:106A6000F6BD377E2E0A0CF897F0B337FBD89B5D46
+:106A7000246EF5C520ED7FE7BE51390FAB60078767
+:106A8000B0795A0FFCD6D6A58CF47CFF6BE2B833F4
+:106A900055C371EB6042DBF988EBCBF9A62B1340B1
+:106AA0002EB41E9C1F74EDE47E7E2F723D9BA9AF19
+:106AB000CF6BAC2F4121C268DA6EBCA29004426A4F
+:106AC00044CFA322CE6F5C6D7E881BECB3B9D6A8F1
+:106AD000306F3CFD6648851AF5F185F3879E76C0D8
+:106AE0003C6C659AC9793C861CB5B4AA31D3698FD0
+:106AF0009CAF04F5F9F375425123CEE7D48459A332
+:106B0000609C713A8F0F05BB9F86A956CFCA34C5CA
+:106B1000799CDADDD30D59096CFE1760F6645B22AF
+:106B2000DA9BD33E0BBEFFCFA6A7A77A347A0869BB
+:106B3000229F58C09ED3B2AC9EDFEF511FA48B0A98
+:106B4000C43749B3FC39CC37ADF4FFAF8640BD1232
+:106B5000E6B57ABD8DA2DF3C1A9E6FD3B547BF5311
+:106B6000B5B557F8AE67BD9348BB867B2ABF57F9CA
+:106B7000FAF08A06AB53EFC726EAF2DE60BA53E7B3
+:106B8000D7C23FC071AF1124C05F25875FA7645F84
+:106B90000F78DA0CC14398BF08ECBD2A4B9BE25139
+:106BA000515D5A019F8BF234FCAB73FE4CEDD4A9BE
+:106BB000D765027A46BEA454E5F2A920E2CD444C42
+:106BC00034BF98BFBDA86945318C5BA74C6CFE50A3
+:106BD000464A1C303F2E2775B9104F3D4B4C45A0FF
+:106BE0009F67C93B8EB111FA784E54B0D2C5EBF510
+:106BF0007E3C9DDFEBF2CBEAF5F9A5E4D6545807CD
+:106C00005FBA41260101EC86BEFC98E8C47A9791F0
+:106C10009A75306EFF9CC7BB1639899441E9ABFA6F
+:106C2000CD2F7317523A2E896CFCD5D67197273128
+:106C3000FA2B660514377DFF93A6B1B7510B44BFFD
+:106C40000FAC83756D7F29716D25D1F2FBBAF41BF2
+:106C5000E9D5FC81A8F5644E474A83E00EC4B063D1
+:106C60008A24303DE3F6EE6AC9A98B83E4423E22D2
+:106C70000EF28DF194427478DA2C7A064BE3197E89
+:106C8000000F82D4A578BE4DFD6951F55F2DF5FB4F
+:106C900027D63F90D69FABAB3FF79F4AFFD028FA4D
+:106CA0000B62D55FF59B1776F9A93DA978E9670EC8
+:106CB00042C7C953525DAA8BCAB572EB0F1D6E9ABB
+:106CC0009E94FC0EC0EBA98058144BDEABC3F27649
+:106CD000DB0588BBC13F69FDA79FFF11C6233EDFCF
+:106CE0002A3B319ED6600E99A93E56372D2F26D9C4
+:106CF000983FC6F20F9E13211FD4E3AFE2D99FA5A0
+:106D0000C2FE0A8A141E5F0AA13F5BBDE5D3421C86
+:106D10009F4817EA91F13B68FF5212DABF854A4259
+:106D20007439A513E3045ECE176FD38FCE890EF8A6
+:106D3000571BCEDF8DEF9773FF74B9149FD26EA3EC
+:106D4000FF9E4026803DD4F84102CC3F5DF3DC2F0E
+:106D5000B28F517ACE6C79DD2144F049D3A3F38D03
+:106D60008B7FB547EDD9DE76503D8BF483B4F14A85
+:106D70000D72BFBA99A59572C8712DD5FBCA4DB2D7
+:106D8000CB4F1F57BEF0F4334F421CF38F66D73002
+:106D90005AFF8A170EBC3789E6576C97538A5937C2
+:106DA000EC426AB75CBCF4FFD539DD72A878F98093
+:106DB000A28E62CFEF4FEA96C78AEDFB15322A9A70
+:106DC0001F531BF72B6DF61872693C56087EC29A4A
+:106DD000E7FE4B81F8E2A97D02E99F19839F9B0E94
+:106DE000A01F007C4239723985E56678DF4BE502E9
+:106DF000F65A9393B1FC466E4FA03E7524E2F9C556
+:106E00003DB4FDF23F995DD0FFF217EF71403F4E68
+:106E100048350CD7BFFC612AD8AF72D99FEAC49419
+:106E20003D2F7FEABB88B7656F7F3715E349C49D67
+:106E30006EC2B1C79F0EFD5BB27136F66F29F120AD
+:106E4000EECA7F29960468FA99448AB6C7D08B0E99
+:106E5000AE17273653478CF6EF04CC1FC15EBF2315
+:106E6000E2BE2A42EE26A0FFDFE57DA11E02E63F3C
+:106E7000B330391D904C5CAFA8B71989D72D0FB628
+:106E8000827C4E0F72F78775162F91FC9C1FC2579C
+:106E9000B45EF1EDE9FD997C882AE5F2EFE8383F30
+:106EA000159EC3FBADB2DB9AADFB8E7C95D9DDFEA2
+:106EB0002ADE3EA53B0EC6E713A9B1FDD501B2A659
+:106EC000F7749C8EC057847E337DDFF210D36F4DF4
+:106ED000DF03A545507EF130D31FF80EC63F4A5759
+:106EE000A83F96EF9F25A03DA0F3E6587ABD45E662
+:106EF0007AAD2FD77042E996848408BC40FD49C81A
+:106F00007F5C5F59BA817E17612FBDD09E23BA3E48
+:106F10004D6F9771FD3F05FA7F4DB7FE938D4CEF96
+:106F20007BF69FFC2C6E23079E7912F495EAA75FEF
+:106F3000057D954BA0DF7FDDD6F2DEED544FFFDA05
+:106F4000A8E9A9DE7E1AF5B47CC778124B4FFF6A18
+:106F50007791987A4A9FC7D4537B1BE2F8FF94FD40
+:106F6000D4F89728EBF9A7D9C39EF868B4872F4ABD
+:106F70002AF2D3680FE9DF61921B8D3F0D771ADE8D
+:106F80002A7E5D7505D89D302E35DC8571A9E12EF0
+:106F90002A7EABE39FB1FCCF106BA274CDB7D44F68
+:106FA000817984A58BE0BC2B7F9688EBA6968B0419
+:106FB000F5BE80C8B86FF07D53CD78F043A7FCFDD7
+:106FC000B6B3F7527AE713BFCCD6E5EB64F4EBBF68
+:106FD000FCEAABC9B43FB773FECEA7ECBE89CA6367
+:106FE000AE2484E2289DF324E24F4882F8AC403E70
+:106FF0008EA0637EB93E0F7F5352BBEBE9EDFDAF30
+:107000003B0FF9A6E9DB3EB676F52EA443B179290C
+:10701000124FA52057CA3FEF38213004ED529B5440
+:107020001231AF7A9CDB9DB7A7CD1C0FFE4BFE9CA7
+:1070300051090CE783717EEBE5F6EBBC5F4D00BBBD
+:107040007EBE390BE7AFE70F2D8E8FB56FB285E3AC
+:10705000EC005F57E9B40B7522C57D27E942FFC5F7
+:107060006FB792AD31D6FDBE2F9BF8E483CB8DFE7A
+:1070700089546E73390EE7D14F137222E436EBA6B2
+:107080005392235A0EF0F771C43CEBDBF217700DEC
+:10709000FC6DB1B61596C488D7FD84F36FCA2B5F1B
+:1070A000E0FED569CDF912F0719A5DD4C5391ED4D0
+:1070B000F475241909744D7965F9A3E3298EBD8708
+:1070C0004417EC57F5369F533C31E6BB467E42FDF4
+:1070D000E0471E909DC8AF2372C912E0EB91D956CC
+:1070E00002EB96EF2AAEAA58744E37B378C83C52DA
+:1070F000F2D938E1FF3EFEE6CF890F15507E9CB7EE
+:10710000B3FDC0D1F8637A7FDE29046A05C0A1C847
+:10711000F2294200E26485C4F3E86401F5FDFA480F
+:10712000FB951F2C7D01F6D554370B4E132DAF96D2
+:10713000DA14C0B137B85D02FFFC4695B831DE20E5
+:10714000D58C9A1511D73A204BC8AF96BFDD7E2754
+:10715000F0F7C22C3301BADC23CF3960DCBFD03C5E
+:1071600016F5A0A77EFDC147A64C93A01E82F8305D
+:10717000E2A130C5A6CBCF9E4A06BAA8DCA698DB12
+:10718000EE71C590DF3285E1ACCFF6CDF2FF997D8F
+:107190009B4CED1BC3B51C69DF462B51F6AD7F2C14
+:1071A000FBB6B256ED0FB858B937AB3FC875E56BB3
+:1071B0004BFAC5B26FAFFAD8FCFD35BE0FBB7320DA
+:1071C000B56FA323ECDB406ADF62C46DD315CDFF3E
+:1071D000ECC5BE59FE77F4EF55B06F31FA3B52D192
+:1071E000DBB7A2E65AB46F450345DD7EA82C85CFF8
+:1071F000E77AB46F0B7F361BF3B2CB16033FC05751
+:10720000B06FAF713B07ED809D5BA438B1FDBEDA76
+:10721000B9D2BEDAB9FF253E6B766EE520769E23A5
+:107220001A87CCCEADCC64766EE55E66E7560E630B
+:1072300076CE68DF0AA2EC1BFBBE7A04FD1EE78B4C
+:1072400099BFB8839617CF955D16FA7EB1AA9D5F58
+:10725000A8191F69EF162912F239CADEB9CEE13931
+:1072600090DEECDD5B60EF86A21D1B0A7A64C4C76A
+:107270000D436DBAFD7247BE68FFF54BA02F7F101E
+:10728000719EFDBE89CD8BF67DD13E16F46E37A77B
+:10729000E75185C9B3C3E7477B3A7524D3F7AA43BF
+:1072A00071384E543709ACBFF70B0115C681BF5D6D
+:1072B000C2F9F29D7BD97C798E99F183FC9BC8CE73
+:1072C0005D50162C8CC0C3DC4B1518D79C2B110BB2
+:1072D000F8AF0B0EDD700AFCD60597D6A3BFBB0036
+:1072E0009EC3BE89ED6DEB3268BB772E1770DEA1B1
+:1072F000EDEF9817B6977A3F767E73EC7D1A533888
+:107300003D53EE1302B02FA7B77D102F72FD9B23C4
+:10731000B621BFC85B62CCF8A4F65E984F2EC69724
+:10732000AA55CC6F0EF389F24D15A2F944255DBC28
+:1073300030B59B2F77EEA4FD4DE9B9BF1ADFA2F758
+:10734000E1B8713EB380BFD7131F343E47F59FF3BA
+:107350009DFAA9B89FC7C88F46CDCE5C4346815ED3
+:10736000BE6FF23C3A1E70F49F942F94CEDBE60D74
+:10737000D39DE7D9C5F97293E7D8B45415F8486A94
+:107380000067B7976F3F904AFB778B3B330742E626
+:10739000B3FFA67820FED062ED423BA8E130CDCC11
+:1073A00070F8578EC323039CD370BC090A4ED4AF28
+:1073B00090C1CEF17D645ECA67D05F6F908F4F142D
+:1073C0009FA09F85DA780572A1FFBCA999C9C55B0A
+:1073D00023A05C6E265D0781EFD529822B44AB2A62
+:1073E0000C6EFF21ECB77AD54A9F839E970BAECDEA
+:1073F0008C1DF6F4D498389662E1183709468C9BB8
+:107400000BE0BD24D8B768C6F6EFFC1EB347463F75
+:10741000658AB9F508D033E5DF64B2091E06E87F56
+:10742000113830FA31517AF035F7FDA472FBFD2A9C
+:10743000C8C10EFCEE52C01FF286D8F8A3957B257A
+:10744000751AF24D9343908E2FE3981C60A9DFC804
+:10745000E75BB43CE01FDE6F1664F87E06954F32A2
+:107460002D9A6AFAE2A08677B31ACD2F8827A4470F
+:10747000D80DB06F91EB96D5C1B7914F37ACA2EE56
+:10748000991ACD274D3E60072FC7AF28FD09EE8F13
+:10749000B97FEA9BEA4F9A59AF3FFBAC5DAF8F864D
+:1074A00038DA5E01ED0A694ED4C50FF2CC6C5ED6B7
+:1074B00062F520CEBB5E935D9BD568FB7315970B81
+:1074C000CC5722CFEF4D850EC1BAB1D34A3ED1FA87
+:1074D0003D84E12C723C78D5EA41F9F554FF045E15
+:1074E0007F4FFE9896FF0EB407FB16557D7BC6F1C5
+:1074F000488B27F5D6AF6966663FBE69BFB476BED6
+:10750000EEBA8397B462FC4D5B7FD82C7A7E2EC393
+:10751000FCB848D0AD7350CA71FDF29F50FF58E5DA
+:1075200032F543FC2844F9FCEAB6A7315E7DF6F952
+:10753000633783FEACF8AD482C549F3AB6C5931020
+:10754000DB07A2809F50D124E27A169142B93323FF
+:10755000FC0C42D6307EBC148F76A7628739504C23
+:10756000BFAFD8F54936C4DD3A1E60F6CFFF3CC741
+:10757000A3BF2D1BD6FB2B24B68E6F94CFBD1C9FB3
+:107580006776DBE682FD161AD879D78AC639B23912
+:1075900022CE506596595C7BB70DF759FB9F13704F
+:1075A0009F32D01779CE52DBFF79E63966972B826E
+:1075B0007200CECD56346CEF803878C55133FAAFB7
+:1075C000DE86730AF8A7535F7A01FD236F50D4C596
+:1075D00041A3E28F0D62C80CF1B3A62AB403347F35
+:1075E0000CF38DB1E3F0BDC5C956BCB477979FB21B
+:1075F00070C5CBCF3AF0DC6CEB5607C6211B2E1FB3
+:10760000FF8F8A37363E74D978E3698E8F5F99F59C
+:10761000EB35A42119E39094BEDC9218718B30EE07
+:107620005FF8EC29580F3BB3E3AF4F01BD95FFB8AE
+:10763000F0D47DE08FEDB33A61BCF63E7F04D71302
+:10764000B4EF76733DEF78EE595C87E9F8A3D9057E
+:10765000B575EC3D3118D6233AB67F910A71DB55EA
+:107660007BA7E33C6DD5CEA9FD498C798096026E4F
+:10767000037D580732CAABA5A96530D07996CA1BDD
+:107680005CB670FCB8B18AC5E3551E37DE167BBD0B
+:107690002D2A4EDC34F396EB60FC6E925D2AE943B2
+:1076A000BCF83095E3E83EC86FDB439ABD8F29BF35
+:1076B000B3F00F2AA7F70DF2FBAC69C9AF9E84B2F5
+:1076C000A6E41EE3C5A13EF04D5BCFDB62767F6C86
+:1076D00006BDD9F16B8CCF83DCE85C8374BCF0D938
+:1076E0006088B39C94BBEEC2FD337BCDB82FAA62F9
+:1076F000EFFBA83F1D3BDFC6F532C2D7D53A48F8AD
+:107700008FAD83F0399C774B3C8B3373FE431C5A0F
+:1077100075E0731E6F6638D6E2D03DC59FD32D6CE1
+:107720003F91B6CE58B5E5CF0A31C4F5853C90D32C
+:10773000B1CBAE8B6A7C70021F2644AEA7C48EF319
+:1077400087D7DDB8BC407EE07F85D74B687E20C4FC
+:10775000CF03C2FB24863DE8D8C4D6613AE4D8FB07
+:107760000FB5F595148B414F037D5B57E98DFEAF47
+:10777000CB1F19269BE3A3F974E6CBD8767C824510
+:10778000F876FB612A85A8F57F0BACCF371D5360D7
+:10779000FEA18D635A7FCFF079F299E7453CEFB1B6
+:1077A000AEB105EDB8D15E5413161F34D23B83D36E
+:1077B0005B1D64E3C4991DF1013BADE7CC2BBB110C
+:1077C000CFD5DB8E297E5ADFC1869795B688FD52CC
+:1077D000304E0422E83FF3E2FE6CB67EC4E6E5C616
+:1077E00076E6F076BCCDB1DBF16E3BA76B6785BF6B
+:1077F0005161E7772EDFDE69C93D07EA3BDD2A13D9
+:10780000D8BF7FBA512C0AC4687F9245D6E2F24CA9
+:107810006FE87889E71DE3D9F946314941FF7A5588
+:107820007CDED18414481515E2146B6AD9FED2357A
+:10783000DF77A581BCD724DE86EB6D7506FE3A5353
+:107840009CF910BF704E2B19077035DA9B44B7496D
+:1078500047FFAAF8A2FE701E7F2DF7C788E4C2F387
+:1078600097A2A3B008FA233A4D4E6B8CF505D95E6A
+:10787000423C117C919DFAF392E4CBB12AD4A3ED62
+:10788000A3A9B4B41EC442A71BB70A4B79ECDDFC14
+:10789000594EEC77E7363E4F7013D599CAF683C13F
+:1078A000B8D1B923219B8CC60F899BE2D1C69F0B0F
+:1078B000DBF6EF077BB4D641DC8954CF285755312E
+:1078C0000BCE8D8EB1085980D3736FFE96D66B6D3B
+:1078D0001671FED069D7F685BA1341CF6CE411DC7E
+:1078E000FF0750FE2AB99B4EE3BE4002AFA476DFED
+:1078F0002B315DB4E3BCE7FC46160710C9D5BF9831
+:10790000CCE2702400F4F3F16405A7F33CA4F07E0C
+:107910009982E73A96BDF6726E88303944F22BB9F7
+:10792000487FBEB4DEEAC8867579E277B7C2399976
+:10793000325E5FBF12FDB953AA7E7ED0D3255C4F65
+:10794000FFBAB4F010D8BF32CF52B4EBFDE7EACFA4
+:10795000A51AF75921BDB02F8CEADD9342F4BEABD6
+:10796000F2E6C7D6C17C397AFF151901FBC92A484E
+:107970009C0BCEE7AC68D097EF03BB7915B093D8DA
+:107980002F17EFEB95BF6DC37F3179DC65F9EB0AFB
+:10799000C1FBDBE231AEB2ECB5C5689FCC697AFEC3
+:1079A0005A553D7F6D238C7CD4F339DEA5E79B3699
+:1079B000FFEC89CF0979FAF3BE463E4B84C71B0220
+:1079C0002C0E11B5BF2DB809E936F2D9C8D7760B00
+:1079D0005FF7E27CA57F25965466B281EE74298418
+:1079E0007A61D4A30C7B48807F0F4A09D4E257AE5A
+:1079F00078B4EF69BC3F4219FBCE067A2402BD2E53
+:107A0000D42338D10776DE463E70B65B41589F904E
+:107A1000AFAEE9599EF794FEFED822FAD546C0EFE4
+:107A200068D42B766E378904D664829EBA9C306EF9
+:107A300037FA2C6A9904F79F10B56C28DC7BE2C4F6
+:107A4000F4C77C1F4AE74882FB821B431753C13EA1
+:107A5000FD38A7EB66B07BDE25A404ECE0CD716CAD
+:107A60009EB298A77FB72ADCAE4E7BED7AF8BE595E
+:107A700056E15C7867F356CB30C80745BC7FC49BA2
+:107A8000587715B4DFD12C33BACA2C816110BFD816
+:107A90002B63BB1D6593F17C65D86F6B66FB403A29
+:107AA0009B3F712C8EB0E71DC19F5E05F1AC274C4A
+:107AB000B1F79F0CB79AF8FD35DF70FC6D8CDA7F5B
+:107AC00037DCCAF6C7FD7808ED4775E9793E0E3315
+:107AD0007DB896CBF9F74B6FC0FEEF6C1654184784
+:107AE0000AC53B6E1C45FB39F188C4E3302C2E39A6
+:107AF0008EBFBF9BB8D2801F13AF2302E8F3C43FF1
+:107B000012DCB735AE6629CEAB7EEBA038CF8675DA
+:107B1000528A5BB07367ECE8BF8F6F9574B84C9C6A
+:107B2000E6698179E684A304EDED84A3FAF23C12C0
+:107B300010B19D36FDF36B4FEAF305568E6F074982
+:107B4000057C6FF85244BA3ABB88EB015A6F67D98B
+:107B500000BCEFA6F3229CDAA5E9976251AC717ED6
+:107B600026E081F2EB0985E0F8F2C4523BC6EF5FF4
+:107B7000595A71058CEB9F7FCF7345AC73E011763A
+:107B80002981EDAF722750E229AED70A8CDF75E963
+:107B90002531F6EB6B38D670ADE1397D699C27D67F
+:107BA000BEC40FADCC0F29583A4250605EB64F208C
+:107BB000C0D78E073C973D37E3270F64003DDEE0DA
+:107BC00005F4B32DCD823B969FB1CAEA60F3BE07A0
+:107BD000FCB5B01FEF5EAA94601F7BAE7703CEABFF
+:107BE0006E87A02B7C67A95B88E7709758C866886A
+:107BF000674B75E9B7C603EEA7CE5847E97DB2C417
+:107C000084727E427621FDFE2A4230BEC0E3B50377
+:107C10006F269B22CF23FFC09AFFB095D6FBB0D52D
+:107C2000897249F6B804A0DFF5DFFFE500BDEEBCC0
+:107C30006446390EE0F31FEDBBAD9C4FA3E3DC6B54
+:107C400001FFA43C05F5C3E571A865C9702F01E5E6
+:107C50007B8C7554CD2F4DF250DB46E949B29BF039
+:107C60007E2EE276AB4E6DDF19E1EF45E8030909A0
+:107C700004F6A569F654681642F114FFE32CF610D9
+:107C8000CC3392CA69BF2909566261F5B54A67C209
+:107C9000E7AA719F3BC5652E1C6E22B8AF0D36D288
+:107CA00042FD9A9DD5ECF3DA4482F666ED635260AC
+:107CB0000DAD67A3D46685F849A65B2D80AD444918
+:107CC000928AE7BD0795337DB465FD3231ECAF5044
+:107CD000651FF30F7141ACF5BA8FC3FCF2BC00FC19
+:107CE000CA3ED4F50AB8352E2B6BCF75C082FE790B
+:107CF000D86E703FAC908FBB133F35B1FD02A1EB46
+:107D000071BF9DB68E66B41B540FDE1541AF3E9514
+:107D1000089ECF75D3FF72B52D7711F6838F93B977
+:107D2000C19A16F4DDC4912D80C76B5FC7BB38A222
+:107D3000ECC884373C6B80DE6F6A3F8C781813A2E6
+:107D4000FAC8E53352857B2A9CE13C94B75AF9FC8A
+:107D50008EDB9B94D271FDD1AFE53833F257D36BF4
+:107D6000A3BEE7AC76B598B1D60032C1D80E11BA31
+:107D7000E950B3C01EBD21827FDF994FF142E9BABD
+:107D800017F40EFCF38B8119809B0DCDDFB1827E41
+:107D90007CE3F1A3997E1DB1BFFA27A2A7C3CAF65F
+:107DA000873B800FD5FB2FF2F12384720ECB95EA2F
+:107DB00047643C44C3BD11E79A5EAC810B33B2F01B
+:107DC0007C1C01F98842230AD64C363A81AF9A7F4F
+:107DD000BD26ECCF26E2B99E554ED6DE1A59F3CB1E
+:107DE0005D16E8EFAAF882FE975B17F55EA2F3979F
+:107DF00088F3305EA90BE767DE4B0A09247F0B7E10
+:107E00000569EBB93A7EA5C4C5E05707E8D1F8FF8C
+:107E100027FB936DECCF836A777FAE259EDFB6514B
+:107E2000BB907B4F7D3AC305399C16890BBE5ED94A
+:107E3000937EE751FD06D72D4A9F0D7A3CB199EA12
+:107E4000B1295A8F5D7209DE5BE7DA6B437B67D439
+:107E5000EB8BBC5F5E1BE37B8DE8991107F37153DD
+:107E6000D760C05DB64A928B29B1D94191ADAFB60A
+:107E700026EBC691E8F1DD8F7652F32F35BFD2F8AD
+:107E80005ED8AFE4E38616CF148214FFB4DFF7C7E1
+:107E900079E6015FD738D9FC130E9A82BFFC03AB99
+:107EA000E70EA0CF46FB1007EB1A2342992C5E1277
+:107EB000D2E95B4FFA6533E84F6348C271CC4FC7D4
+:107EC000B16142CFF4F48B4B64F452AB027ECAC072
+:107ED0005CC21AAB26B8AF7B6036BB4766600EBB90
+:107EE000F7F1DFE3D87ACC7D716CDCD0D21F584B30
+:107EF000EE817EC912F19B73BE39DD402AC40FEFBB
+:107F00008F73DF0DFCB014B9B11F194EE21228DED9
+:107F100032A44601F6372455AA028B1B1236EE40D6
+:107F20004AEBCB2856F361DCCAA0B616E22019CD85
+:107F3000B1CFF56C8893BF5DBCAB29EA3CCA8638EB
+:107F4000E66F1F54687F938BD9799470DC86920F0B
+:107F5000FCED88BF0D3BDBF1195B0FF527323E1BB3
+:107F6000E75F2030E897C4F33F5488644DC2F9912D
+:107F7000DF04DF992C383FB2115723D8CF97E2584E
+:107F80005C759DE05A0FF99F485D16B86F47C3FFB7
+:107F90008F27DFEA92E82B8EEBCE67C39C95EAC36E
+:107FA000F320AF8EC9E787AFC51E740D6678738B5B
+:107FB000BAFDEF9ADC82B24E6E56888744DAEB78CF
+:107FC00005E7F71D429C0BE6431DCB0546A760E184
+:107FD000E703247D9C86DB436D1C78272E13E9B7CD
+:107FE00011FF18BC1FCCE2B2003D1AFDE173A4865C
+:107FF000739EC673A06959E1B84D3AEE932D51E0D6
+:108000008E2F72BED986FE97D7C1F4DF8887FE60B7
+:108010003C2E736E92F2AB15E4DB5FAE49047BDB62
+:10802000FFCEE30E90AF910F9D827FCC4158DFFAD7
+:10803000831C739F8896A6A50D28057F342D3D0DC2
+:1080400053ED79BD5D8A19073CCDF5EE1BE3B59E76
+:10805000580CF3C3D3D09FB39E77DE73A3BA776176
+:108060007CBC3E8EF1BB5ED1F8A826809E75E75D94
+:1080700009EC7E924476FF9093C97383CF522A49CC
+:1080800091EFB9D11FE947DC33E68111D82093ADD8
+:10809000886B16BFD1CE655043C7E497C8E8FAB9DC
+:1080A0006F4C29EC9F916DCC2E5DDC301DDB4B2598
+:1080B0000F588753BE2E2D31B920AE7376D19F1C39
+:1080C00070147C51466B2EE0FD88E8916DE331D44D
+:1080D0008DF3B76573954088422AA59E1A2426978A
+:1080E00019B8EEB8D01473FFB3DDC6E6DFCD714E1C
+:1080F0004CD3D20697968D8DCC0F44396978A47AEB
+:10810000985E36AEFB9C30C5470AB46FD4A74E9933
+:108110000461DD40B387299CFF9A3DD6F42105F424
+:108120000CD6014BA87DD4E43984BF9A8AF14AFC6D
+:10813000139A5FFD02E6038EEB0AD0DE51FD5F8FDE
+:10814000FA3282D96F2BD8D3883865E7DEF707C1BA
+:10815000FADF87DFBF100FEB407F91BAE2C17E9E4E
+:10816000BCFFDD783837F4E1FD2C5E7197611E3578
+:10817000C1C6ECFAA3B6926CE8D702DF7FE77A2299
+:10818000704956B3758DE501D1709E5C7F2F4F55B8
+:1081900063B2E19E1E3FD65BC5EFE732CAA192CB28
+:1081A00061F9B64D4A860AED7BDCB67E706E8FA013
+:1081B000BD3CD9148FF3118D9E45DBC6283077FA6C
+:1081C0004BB399AF7FB7CA6C5C7017C37A9687F3CD
+:1081D000CD48E7C17D36AC6FC9CFD8FE9485B4AD2C
+:1081E000D5D4BE7A9AD9790B633F967CA816F6A7A8
+:1081F000C25BF29080F36278FF7E3A4E79563F88F8
+:10820000EB5EC67E1AEFCD319E5FD5E653CBB8FC50
+:10821000CB8807F52FEA5C6B335B9F36C6FFCE1F1A
+:10822000CAB261FF6D3CFE914B26C079E81D87867E
+:10823000245CEE3EE533FC1E26B8571AD2933E82EC
+:1082400069B64D65F76434BF7D2FE0AA3AB81DEFDB
+:1082500019FBBAF6A6AAF99403F6306B7687FA9161
+:10826000AB013FA44CD0F997D59B2E286CBECBF820
+:1082700070077F7E07F4371BF659AB3F9A4CE57CBD
+:1082800047A57C31F21E32BF4D7FEEA6AFFDD5FA79
+:10829000A9F55B2BAFE2FBD18CDF69F8CFE6782C38
+:1082A000DB52BA6E0065D19ABD2706F3F368784EAB
+:1082B00047C397113FCB484961BA108193E647B154
+:1082C0005F9A3CCBEA16F2FEFBD3F8BA5E1AC48F73
+:1082D0007AC38D111F1D72DB60D067233E3A7AB8D6
+:1082E0005FE42736E62794A9EE4288675137769DEA
+:1082F00033C24F3929D51DBC0FF46C0BC379C4F8B8
+:10830000CB9CB9D7651CCF57C6ABFDE13E3D94DB96
+:1083100044D81760F6C37B5A3BED3EB76BA8047C8C
+:108320002FC2F4B4AFC435746877F9D2272E38C0A1
+:108330008FEE1C41308ED311AFA7F7773611E9F9D4
+:108340001D9743A5D4FA8F3F838DDAD28AFB1DDABD
+:10835000BFE471A02FCD45B1FAF927FE1DE1F786E4
+:10836000DDC5F54C9B972CE072BBAB99AD672FDA5E
+:10837000588AF230EED77A43701666D0AA3C8D63E5
+:108380001490BF513E4B5CDFC17D605172228FF073
+:108390007D011EDCA753562F62DCC328BF7CBB9334
+:1083A0009DA3576B701EB7428ABD0E79A5DDF4B54B
+:1083B000FA63ECC7C22601EDA491FE655B6AD70D96
+:1083C00020D07FD6BFE87E8406A25DE2FDD4FA55B8
+:1083D000465C78FF40D4FA50DBF524723FF5F2E6B4
+:1083E000C5B82FBF9AF69FB03812C68534FA357AD1
+:1083F0008DFD2814CFC81688E3AE165C609FA3EFEE
+:108400002773EBEE3F5CD8B07F20C8AF5D62FB66A0
+:10841000DBFD02CE0B3B3F206C7D60BD80EB693DF8
+:10842000CAAF99ED07EA598E350ADCE757B651888D
+:1084300029C765F5F9AEA111766A7960866BA88EB9
+:10844000DE46DC1FB2A2A154F77C809DC793B8FD25
+:10845000EE4DDF484D62CC3893A65F9ABE69FA971D
+:108460006F57D93C470A1CCCC804BBFE18CE4BA89A
+:108470005DBEDACED707E6D157AA9FB8A05B1F58DA
+:1084800092C7E4B3442CC6E73DD957CA079D7D1E69
+:1084900067D7EF7FF8B6FDD1FAA1E985D63FA35E95
+:1084A00018F9AFC5D58C7230F21FE882F9C11B7B79
+:1084B0006D810704D07746A77FAF15E9EC482B7094
+:1084C000C139C83FC00794CEEAF4DB315F239694EC
+:1084D000DA715EC7E74DE3FA163FC8E17ED64EABD0
+:1084E0007B2C3B4754920CB89852DB36D3E2A4F86D
+:1084F0007C647421DC2B3AE5B1B69910FA5EF2C8BF
+:108500009842B85F7ECAD6B6772D2EEAD7D58E2D83
+:1085100084FBE55780DD80F60796DB10573DE58943
+:10852000E7F27995BD3FCE5C329FDDCBCCCA2B29DB
+:108530008F2D743CAB3C3CFCF7A09F95ADC545101E
+:10854000B7A98488371DCFAADC8E902D9B8DE79329
+:10855000E87BDB6C9E5576F0EB2EADC5F1ADF2B04D
+:1085600084FA440EB1B8A844FB6AA5DFAD8DA37EA2
+:108570002FE5EFDA248B0BE6AFF4B91FE6B56B936A
+:10858000DCAA1AF15C931F7C0774AC35B175FBFD56
+:10859000AF0D4F68BBCC78BFDF4726C33CA4C5678F
+:1085A000C1D4589EAF38F17C44BE89C5358CE5BF37
+:1085B000D2EC2C51330017D5871416AFA67FE04FAD
+:1085C0005611A617D5849DEBAA3A4CF01C4BF5A189
+:1085D000423CC702FBFC3FD6E1F05F738EA51B5700
+:1085E0008C4F059230598AC0F534BB559717FB9BC9
+:1085F00046407F8818E78273186286A96607EDBF38
+:1086000078054D293F24A74B84FB5AEAA64E11E179
+:10861000BEA93532DF3F6262E7CCB5F69A387FB447
+:10862000F4B4BD6407C8FDEC5BADB936B67E81F32A
+:1086300061ADBF6B04371160DE7580E0F9809C147A
+:10864000D202FCB311771EE0ED3D7B12E7375B37BA
+:10865000A67F1990BACCA697558AF7571F5984FA66
+:10866000E04A30DD9349F36FD997B17C86E9422621
+:1086700085F0DBF67296BFC6746108CDBF6B5FCE26
+:10868000F2B0C04907B623F68A42FF486887E37D07
+:108690009BFB1AC0B76462F117E91505D753B47D87
+:1086A000216BE9440BF0F81ED84D88A7D416FCDAEC
+:1086B00006F1EA02B70AFB3D36F37B83BE69AAF1F5
+:1086C00055B49970FE0329F0FF43CE4F4D2EA4C937
+:1086D0007D0DEC8B258DEE6B601DEDB4DDD306F6C4
+:1086E00066EC1BAD53C07E37BDF3A75CBC9FFC0A94
+:1086F00056CFD837E89C90F6E7EC6F066D8A5C8F12
+:108700003E6DCFFF14BEA36240FF54509DE40EAAFD
+:10871000876BDC4455B260BEAC9F2F3611669FB6A6
+:10872000D94ACE825CC9C0108E5B45F6924EC86BAA
+:10873000F69CB426F5695F9B92BD5A847139292352
+:10874000787411D8FFDFB17B3D04B71BF773BE14FB
+:10875000BED78CED0FB1C1FE10D07F1749F3A7F241
+:10876000F8178B2F9394DC887930EF07FD7E1AEC95
+:10877000379F6063FB0768BF44B0AB63888AE958E2
+:1087800088676581283D98DF431A8FDE47EB7FDCE1
+:10879000CAE2499606A28B0F66C7B338CB4C078B4B
+:1087A0000FC6C98DB782FF10778E38C17FE8FCA550
+:1087B00022E1FE22C97923AE8F1D3411A0F7593969
+:1087C000E084F599AEAB247533E9AEAF93CB5BABE8
+:1087D000F77145BD0AE272731DCC3F7D369FE07E86
+:1087E000E8AE534A00D64D93322C3591F19F2BF9C8
+:1087F000770F390B32E321FEBC378E40FB13F6C5F1
+:1088000099400EBFDE9663053CBC043CA27C483216
+:108810003BEF86FA922E507A33F139DB272FA9638A
+:1088200012287F27DD6057E1BEA967AD8D37E07E56
+:10883000D0174C78BFEE4B8AAB14F22F9D579D603A
+:108840007F9FCD6C8CC3FEBC60C2FEBC14D775F597
+:108850004A4AF7C323587C4AB21109ECB2642A5041
+:10886000EFA6CF73E3D93C49B3D3CBE399FE3C2EBB
+:10887000103C0F2099F2517FB4FD3A9D5D04F7EB57
+:10888000F49BD52A028EE34AB5B851488478CFE4E8
+:1088900012827EDB64BB8CE772607F309C1B9BC2C4
+:1088A000EDEF940F2A713D814AE030DC7FD962E719
+:1088B000F768F175C5EB394EAE236D22F891D75D9F
+:1088C000222E88075D7F498AE9474EE7F53E23104F
+:1088D0002981BE977F51950077F944EFE74DAF2F7F
+:1088E0003C05E3E0548BE139F889488F1BCFF74F03
+:1088F000771AEE4F8EE7F3D6C16470E43E316D1DFA
+:1089000068BA38F209F4538B1417F065BBDDFD3EED
+:10891000AC7BFA5B6572B938E2333EB69F6FC4A593
+:10892000385CFFA1F8B4032EAEAEAFF35B69BFAF06
+:108930001ECAEA071C825DB9F29729C960E7CDF12A
+:10894000CCDE68A9863BC0973381E1CB39BA5B3F67
+:1089500057C567E27B9ABE01EEA09E3D72607EAC79
+:1089600075658AD75580D7ED7682F3B31FA55BE690
+:10897000829E69EDEC8967F837A6EB6A57EE87753A
+:108980001DFF676CBC9836E0921239DE7FE86438D0
+:10899000F3AA75336FA6FDF3DA655CBF49E5E78B93
+:1089A00022F1921E81170D771D7616EFD1F03375E7
+:1089B000F7BB223C9FFA1921CE4C129E8768F8998A
+:1089C000E267389C72888D13BDE1C7DDE59C06E641
+:1089D000310A3787186E0A283EF0F7B77AC08F1130
+:1089E000374FF58A9B2FF13CFCAABD532FBB6E1865
+:1089F000F4E9F77D1AD389B6D8FB828F727EEF56E1
+:108A0000EA6ECC067B7193899D7F9348C6AD14E7CF
+:108A1000BBE3B47BE56BB220BF5D62F6677BB31945
+:108A2000EDCF76BBC78371D7340B9ECB2692A70DB3
+:108A3000F6F5BB0658D4C8DFD1F82EC761A31C9A3F
+:108A40007802FCEFD798FCF36ECA811BEC487A19C8
+:108A500093C3B893CA2611E2428EFCFD80AF4FE06B
+:108A60004E2DC0C37105EF25AA3EAEA05DFCCDBE64
+:108A7000B70B21BEA9ED1F9EB0E7EDC28291F03E7B
+:108A8000C3D96BDCAE6A793C4A0176D2702FFDC443
+:108A9000F07926FDBDF225809FECEE72E37DEB734D
+:108AA000E084171D776E6D734D07B360BC6F7D4E0C
+:108AB000889D1F9B7DD43D1D4C65D47DEB1C0FB75D
+:108AC00091D65D7162F4FDDF747C3E160FF1FBD729
+:108AD000430AC4C11B959A6BD87CA2260BEC8FA6C7
+:108AE00077F847F9D6F8E108DD7DFFC3F8F8F38899
+:108AF0004B62F738B529B84EF82861DF35F271EBD3
+:108B00002BAEF739AB5E9C0FF6706CB91BD76D5767
+:108B100039457CFE1312B26481BC5C12AE7734CA54
+:108B2000EAD41342F77B442A1961A7E57BFAC58D85
+:108B300085F6EF70784C0EF02BA4AE43F0DD84493F
+:108B40003963C16EDBC7AC4D86714CA39BD255B463
+:108B5000D5DE4D87465727C7C91D8E8526C778F6AF
+:108B60001DD8A1E0B1760B7CAFE1A071EF3926FFF3
+:108B7000083C80FCBBF1202C80BCC6071B4FB5FC19
+:108B80003F1F0FA181209F1EF1007108C7B7C2438C
+:108B900016F055C303F5D7AE02FE68FE5AA3C2F61F
+:108BA0001D6A790D0745F67C7CCFA510DC3F44F6A5
+:108BB00059D9396D4F22AE57BCEC646D747ED83EE6
+:108BC00098BA9864B283F9EBDAEF898C0909E8570F
+:108BD0008EA106E10EF4E306A23D74717E9176410A
+:108BE000807B37716F7906F897A164D08B31E6E20C
+:108BF00010E07F876D4A06F88739B6C95980AF5DA6
+:108C00002356BD0E43D6AE01E52F6F51BBFD27CDD8
+:108C1000EEB5F06AB5F66F7430FB74BD9B9D0F0224
+:108C2000BB1D498766FF412C4087109A63FACA86AC
+:108C3000F6BAB90DEC39D041F9BA5F204DE01FE426
+:108C40009BDC2953C1CFEB179280CECEBD5F0C8643
+:108C5000386571F3AB4781DE626D3DD4A55F0F359A
+:108C6000FAD19ABFA3CD2B347F489BCF82DF04E596
+:108C7000D9FCB9D3CCD6AD26872C786EF9F1F3EABE
+:108C8000556EAEBF12ED4731EFC72DA415E9D2EEF8
+:108C90001DB999F3A3F8109D876643392137513EDA
+:108CA000DCC4EF1DB9C9A5BF57E196BCD8F78E68E3
+:108CB000F5F4F6BE717CB8D6B06EF46DD3433E7653
+:108CC000CFC87FFAD83C77D210D12FC1809A97CEE7
+:108CD000EE6970323E1C52628F57FBB9FE4E32B5C0
+:108CE00065C3B9E5FD7BFE8EE3E32B7BFEFE1EF83C
+:108CF00089134F4904F6B54E3A352E01D7E7F3D222
+:108D0000703D59ABD7FB69938DB0E7881FED77575E
+:108D10000E527ADC0AD067C1F4B7671EFF29D477F8
+:108D2000F1B84422CF4D142A9EA110C72DE4BFBF35
+:108D3000735060FE92567E90FFEEC5F31CB7B021D3
+:108D400042BB8FC41C21E79BF83D199A5C6F3A59CE
+:108D5000744ACA8E960FFCFD33E20B5A5CA199F35C
+:108D60008FB4FC11CFB77CA7E96E09FCF3EFA4899F
+:108D7000C41DD1EE0C95CEE023E21C2F3B0C7E4AA5
+:108D8000CB733FBD998E2BDE3744DC4AE86DDEFEA7
+:108D90007A36E45BC598F78F18F9FB9DE6BBF1FEC8
+:108DA0009121092AD2D35BFB93AEA638190D722705
+:108DB000CCCFCB65F77718E5FBCA9EFF486E1BD971
+:108DC00033BF7B92BF510EBF3D5380EB4EBDC9C335
+:108DD00088DB7DB49F7EDABF10EDA79FFA63AFF802
+:108DE0009C98FFBD2F0DF31A5EBD7B9F4E067F4EF4
+:108DF000C3E9F464869B89BB7F9A4CECDDF232F2C6
+:108E0000ED7307F36BE610D7EC9BE93F770AAE787A
+:108E1000B4177ED20AFBB34A388D730E17A2FF41F6
+:108E2000F87910E33836471C89E7DE7BFDDD9BA12E
+:108E3000F932985BE37805BFC702B8368E53456FA9
+:108E4000D449E0B2154AAB981DE37EBA469751CE9D
+:108E5000474809F6A3273A8D3830D2ABF9E7DAEF65
+:108E6000C0507E4C4FA2F5DDAAE663FFA2C661CEDC
+:108E7000979EC6DF9EFA959CC0E3DE1CFF174E4E00
+:108E80007B0BD8DB93BE19E5662CD7EC47213490D9
+:108E900083A91FFC912109A9A80F859714E2A6E3D5
+:108EA0000C19A83FFF4E8AAF40BCDDE364CF7AC205
+:108EB0005BF52513F12477E34E0E3E6603DCED9659
+:108EC000EA6C101FBDCE5EBA06546FDAA705B3F088
+:108ED0009E8736138190D9F4E6732D1047F01E2536
+:108EE000783EA0A079FF54C0E9EFA5569C47755E77
+:108EF00024E4B1083F33D8BCC6067E5830859D6F48
+:108F00003B984874FB90F72730BC068F9FBFD91D54
+:108F1000A3FC122F9F49DC29D9382EC763FCA3700C
+:108F2000BD09FB3F4D701D4801BF659E80F385CE96
+:108F3000BD130EA4507A3BEE4C443B333DF8E0DDCC
+:108F40004E2A88C6FF1E8BCFBB160A78CF40A1EAF7
+:108F5000C27C615926EEDF98F08FE499C5503E43FC
+:108F6000C6F9CD74B1528278D4D9342107E68B7B0F
+:108F700084B65AF81D5C7F296B8738FDC930FF7CA9
+:108F8000A738790CFE769CAAE587E1EF0312C33C73
+:108F90006DD5CE0BFBCDB47CD56C01F7EF4E77666B
+:108FA000107F047E0AD753798EA5B86CEE5F00B8A7
+:108FB0009E59A43F3738BBC4460291EB168213EF8B
+:108FC000213BC8F7697709FC5E7CAEE73770BCCF00
+:108FD000999BACFBAE94303FD3BB5364F771E4B3C1
+:108FE000DFA1D6F4EB46AE8737F0F9F13C4F868E21
+:108FF0008E6288D288403F5B47BEE5621B0ECFA5DC
+:10900000E20787E7D3F66E1C6198D78A956B111734
+:10901000696C1D6F36EC8213C16EEADFBB254F9F72
+:109020008FA1C797B5139A3D98BD57C475C3D9F999
+:1090300094CF0289F2D3BFAEBD9860721D8078D004
+:10904000AD97DC788F4E94BDF8A0E81BD98BDF502C
+:109050001DCCA37AFD64021F370791416037A68BB0
+:10906000DB7E0A38EAA4E3A639068EB471479BEF8B
+:1090700017523D06DC90336C9D65FAA534DCEFA4F5
+:10908000CDF7C37684FA25AE18FED26F12B274F70C
+:109090007A84ED4A845F22E77E7BBF643AF5479588
+:1090A0001CA06F20F18F457B8671C942D81805F14D
+:1090B000C1B47318E7F14A74FE8AE3F3D3882FB082
+:1090C0007F4252B77E18FD152DCE3CD6A9F9537AB2
+:1090D0009C84E38DB3D87DA51A4E0A819FA0FFB36F
+:1090E000448CEBF4861BADFDDEF012A2F6084C5664
+:1090F0008F78E1FAF775F1F2176D7C194A86F6055B
+:10910000271A3E34BC18C79BFF34C4837A1A6FBA3F
+:109110007A196F0E8C90D1AEF7E6D77CEAE4F3EAC9
+:109120000427A6375C351B7F97682CD811F037F9D8
+:10913000B8158E6BD5339C1C685B24C1FA9117EC73
+:109140004766B71CB478F0FF00C6C481D500800024
+:10915000000000001F8B08000000000000FFBD7C25
+:109160000B7C54D5B9EFB767EF7924334966924940
+:10917000323C841D082121090E21BC1137490811F8
+:10918000A20CA8888FD6011F6020094DADD5536F62
+:10919000332181526C3D58BDD67BF4F43758ED41F4
+:1091A0000D75080183277026A098F0D020F8C07AAA
+:1091B000DA6829451B92185A0F6ACFF57CDFB7F69B
+:1091C0004E662683A5F7DE73879F2ED65E6BAFF5BE
+:1091D000ADEFF95FDF5A9B4AC09F0A50B315209844
+:1091E0000650F9E1864A4806E83B20011403D4966C
+:1091F000C9411BFEB5B4FDB1C745DD0C5689DF5131
+:109200006126C0F5207E0B950EC5E60658E695BC96
+:10921000721680D62EDEBFE19225A862FD7AAFF9E4
+:10922000E31E9BE8FB35FF5F03C800B8517F7F1941
+:10923000FD0FFB2FD3A460185F5D363BBAFF8D97FF
+:10924000CA3F91A6022CD7629EC34F3E93A7F2223B
+:10925000CCBE24AC5744B78F7326B9CFD9F12FE3D6
+:1092600061FCD732C0C5F3656F51F7AFE977EDC840
+:10927000F2483D526601E8ACB77119DB5E6E017FC2
+:10928000C881254D50C4650052010A9DB8981958EF
+:10929000BF64010DF9086313E0F7B93A1D1386DFC7
+:1092A0003F88E30770DC308E1FC8013854EFE4FAC2
+:1092B0006BF51EAE5F93822FA4E37F87BFB0A8B883
+:1092C0009EC5EDDF51FC38DFE24B0A8F3B9BD69306
+:1092D0004F0B8371B49E3FF716FDE30D30DCBFB634
+:1092E000FD338BBFF0F2EBF95BF3E7A7A83C3FCD72
+:1092F000AB150CCFBB44011883EB5C9A1BCD5F63AD
+:109300009E58F9C6CA6FB9FE7EACFC56C4ACC79075
+:109310000FF4A2328D8AC3FF4B26D0A65F5E7E4338
+:10932000F2B1F8B3BD0523DB017EC9721A1E4F9757
+:1093300017742BBE42419719F5BA52B70BD4EF40C0
+:109340000ACAB9B213C28948D8F5E72B3E51A8F42E
+:109350004AF071943E037C6CC85B1E1E7FD125E4ED
+:109360006BDAF0BC8B146477113D1F0B8138EBA8CE
+:10937000A17114EA1F60396CD9615A15C2755C631A
+:10938000813B7D54268A32E094B87D93D3C4E3F6C2
+:10939000FFC56682AB015E3E985902489FD7EA3C02
+:1093A0000613014266E0F7BF4E52B9DFE6240824F7
+:1093B000E0FCA074DBC85E9412805CB43B65B4250D
+:1093C000D88843362B611FD961BF578106B4DB2F84
+:1093D0008DF70E056E0714C9E68F734C8D59F47E18
+:1093E000B87B1EF69B55A4A8DBB08BCBAA7E87DA90
+:1093F000FB0E589DF45EFFFEEF7798699CBF8017C7
+:109400002984D70E5881DAE73BCC41F21F8BE4E385
+:10941000B209EBFD030056EC3F7F55B814506ED7F0
+:109420004077A313CBB924C738F27B8DD69BCEFEF1
+:10943000C3310AE5B44097D302DD6F951E90D98FF2
+:109440009426C941C81AF653D7EA325A806C253A95
+:1094500016B4E17AB1FDDA4B4A5CBFB4481F77E13C
+:109460009F4121935C08D17ABBA84DF8A312D01478
+:10947000C0294B6D31EDE497909E45CEE8E773C966
+:1094800077A25EEF8EF14BF833D1BCF73BC5BC8BB6
+:10949000E4BF26F7E0FA5FB668EFCD437A074E9A4D
+:1094A000E1597C0EE7B13267245FDAD0AE83399799
+:1094B000B78BFD07133515E97999F4C741F5D19AB2
+:1094C0003AF5F2FDA7F60C94607778B97985021326
+:1094D000581D4F7B3286F93D82AF3AFF63F9D9229E
+:1094E00041931DF9BCB0DD5B46AE65041F3B918F17
+:1094F000F85EC980C6F35C291F0DFB78F95CA246B3
+:10950000FAFEF2B9D11ACDFF2AE96BFAB0FEEF3FAD
+:109510003B9848FE13F9A82AA817032E9BF759D6A3
+:109520005FA1F7A15139C16D586FD1F5FCE5C48138
+:10953000A3F9C4EFEB4DDE67691A65E3C41585E452
+:1095400037B7969CC577240DA407D17E24D509771B
+:10955000601940FB217D0BA402EB93194240F336C6
+:109560006AF034950BE6AB29C4EF411CB3DB41E351
+:10957000A929A4E7F0D78B337D8523F9DE528F0A22
+:1095800085F3B4D6DB34251B605FBD93EB6DF51E10
+:109590002E5FAD57B9DC742CF9C1208E53AB593412
+:1095A000256DF87D57AAB08F05E86788AE052005C0
+:1095B00003A8730B1ED6F55E91829B249213AE27EF
+:1095C000829F2897C19EDC08FE36294D9366B235EE
+:1095D000B0BC8BF24DFC3E06FFE0F35923FBA3DC4D
+:1095E000A3EAAA4B627EE6BAB42417963F74F852F7
+:1095F000A86C916E397C01B8EE12F55BE50B38FE74
+:10960000F4F0427810E3C374140CF1157FB713FD26
+:10961000333A2C40F2C180CA7659A4D3A37D2E4997
+:10962000E7703E329DAFC7E07BD6CA30E9D13EE855
+:109630004923BE17DB7C76B428A443C855936EF645
+:109640004838DE9C748B5726D226FAA66F44FE75E6
+:10965000A4E384D8BFA32363AC8AF6A6296FBC4FCA
+:1096600076ADD91C61812BCCBD3D11713C139E712F
+:1096700052BC229FF635F2BDF377C901F66B8873B1
+:10968000C88F759E4AF686719E6B2ED9BC56D27FC6
+:109690007A11EDF56062F254F2CFD05DC6EBB8D628
+:1096A00026D6916FF617BBD89F850F9FC0F7FE6D2A
+:1096B0001080FCE935DD1FCA80F4949AF2327B9069
+:1096C000CEC3D2E4142A9FFC5D720197A7927B89D6
+:1096D0003F074D7695E67DA75E2DCE467DD1DE72A5
+:1096E00098001DD682B71C0A9527EAA1381BF5E51C
+:1096F000AD7A1B9727EB9D5C9EAAF7707918DB4922
+:109700009F5EC776D2B737B09DEA5DD84EE5311C73
+:1097100097CAA2DB9378BC96DB922CB48E83C9D017
+:109720006CCC4FFA144E0CB78217E03F1EFB6AABAD
+:10973000ED2A8C97567FA1340DF9F4B3AF2A14ACFF
+:109740001F5B3CEEA1BF60BBF967A61FDB90DE9BF1
+:109750004E395A8F63DD9EAAFCD841FA792C119DAF
+:109760002399B5B94B433AA6936F1CCD6CD760369D
+:10977000D6D3F47AC07C5DD97C8095A53DF9E042D2
+:10978000257159AFB3217F57DAFDDFA3BA25B0ABFE
+:10979000A2EC2AAA6388247B97CC41B6F7B1927BCE
+:1097A00005C6BB950EFF7F12BF0D7BD1A43FA491D0
+:1097B0007F98A949E072B3BC8393A4E1E746BF95C3
+:1097C0008E45FF49FABADE25B37DCD982F6941C792
+:1097D00048FB35FACD38AB9691FC669E2F6FA2728E
+:1097E00059858BEBBE55B39AC8FECB1C977BBF94B3
+:1097F000DF7FD06566BD2D51B05F9C3868F49B8ECD
+:109800004A46B87BA02B31F82CE9F5697F6312D664
+:109810001779B28A64DD3703D75D3BB6517BE5EB40
+:10982000AD6C57DE242FE1F299A89069D8BED02103
+:1098300079C3642AF33F6A4AA376A7E425B62DD4F8
+:10984000A69D28A6F66CD9BB90EAA7D5320A51A7E7
+:109850009485F32E60BFC5B9295E1BBE772AFCD064
+:1098600045D2DF85B949DE04F2F34AF0E91AAA7B52
+:10987000ADDE0695D6F15869328DA34A5E13D65BEC
+:109880006E28FD1F4447892F052489DA5D0AE1D738
+:10989000277FF7C33227F66B192701D9CFA970DECE
+:1098A0009F88FE859D896A02F9698BB38CDE6BB156
+:1098B00048CE4D5CF79552FF408E597D1EC73D7EC8
+:1098C0009B9DE341E55B058C838EDF3686E342E5B5
+:1098D0005BF34BA83C6E1278BDF2ADCA0A6E3741FD
+:1098E000989C4AE5EDDFE2F7B697FEB0CC8DE31F1A
+:1098F0001BEF62DF82722A5622FC24F60789DEBF44
+:10990000BD9AFB7748990F9DC5FE170B528AAC385C
+:109910007FB93B21AA7FC55857547D49F6A86225D7
+:10992000C24F56166445D56F28968AB323FAFBE6D4
+:109930002744D55794B98AB323FADF54392AAABEEB
+:10994000F2A6ACA8FA42D31CE13FEA617E99B0F3DB
+:10995000F965D9208C89FCA953F47D03DBEF263B04
+:10996000EF12F8A9C885F809E552D655CC71B9D8D7
+:10997000AEFBAF00747B6692FF17BF2E1C8FDE8399
+:1099800020FE99497848FC1676231E207CA460DCD2
+:109990008EA0A7CC111DC72B40CD27FF5BD1B9846A
+:1099A000F154B96779199A31F231FABD0AF9618136
+:1099B0004362E82EEA32C7A5B7626CF4FB06AEAB91
+:1099C000D0E96B31F99B52098B05B46EC235C67A6A
+:1099D0000C3A2EB79E0AF98E3214FFDF5C572CFD2D
+:1099E000001B797F114BD7A04BC78188A71807763A
+:1099F000A6323EC49F3B1E3E30704F25FA3757A417
+:109A00007F7348EEE58597F76FC6B897C37BC6B8F6
+:109A1000C6FBD02CF3FCC6FB43CF5529FEF39DD8E3
+:109A20003F29CE73B714FFF973D1FD17286AA3033A
+:109A3000EDF82848DE00F1FBB8AA10242B3DAD3527
+:109A400051B9E843BF427874F1D9401395F37A8352
+:109A5000C7ADB8FEEB726595F20D061E8A5DD78C18
+:109A600054B14F3A7A49B5ABD8DE1250EDB4BF6865
+:109A70007958B5D33EAA45830ADA2F6A134D1B697C
+:109A8000BFA1E56389F59C54E1E7F352058E31CA25
+:109A900067657F5E2A96D5B69E47098BD47C316078
+:109AA00021307094705EC1489C7754093A68BEA317
+:109AB0000F071DBE083F7EA5386F14295B3AE9A742
+:109AC000A445FA91525B8216E93716395D51F5AF1C
+:109AD0009CAAD8C77B4645BD779D9A15D50FF16BDB
+:109AE0002EE1A0460BE42AE4474D895EC277B17CA3
+:109AF000FC177DFD5E8793E01398DDAAEC8F13972A
+:109B0000BCA5827FB1CF57A48A7DEA6F683D586EAD
+:109B10004F15F435C93E01E21037933EC4D6714F5C
+:109B2000BA8AC6C3913DA4775EBBE922426FF84E64
+:109B3000EAD5D729A8CFDEE9A6EF4EC4FA23A98B30
+:109B4000447D9E69CF04ACFF34B55CD4AF364D374D
+:109B50007B017E058BAF2BC37ABADBE74FC579FB60
+:109B6000CD8EAD12E219C52441917B78FFFB8805AB
+:109B7000E3290A16954C7321AD76ABD82FD724A0D4
+:109B8000FFA3FE259A4AFCAA4930E4DC9341711DEB
+:109B9000EECE3491BF30F66F760BBE87EFE7D8FC80
+:109BA000B5425FC2C92AFAA5FBF72FCA24BDD89EC9
+:109BB000EAE4F5E7EF99E7217F85747D97FAFD7F69
+:109BC000A46B533CBA9ACC629EDE96FC528ABBF9D7
+:109BD000E3511CD2B0BC70BBCFCF1342A82B8CCBAF
+:109BE000358F84F54697C54B387DFB907CAFAC6CC8
+:109BF000D4F313B25DE88D9C62DAB81BCB9FEBFA0D
+:109C0000F214CD3B83E61918B71CF5019C03E3560B
+:109C1000148A3AE9832C170D10DE1EF8569297F736
+:109C2000C763077EFB03ACBF7747BE9770F4078915
+:109C3000823FAB82131A7BB03ECD1ABC2A8C743E95
+:109C400094E67F96F4E0366B7012EB9B6363128DA3
+:109C50002F69C0FB10637F87FB38D5327124EE1F5C
+:109C6000392FD888CFB7CC117C36E6459EDA28EE5E
+:109C7000BC375B3C37E8C0F95B88FF063D4374C0E6
+:109C80005827C7031079A445B243E461FF60E2BCE2
+:109C9000492D191FD6F79C35F1BEAECFD85780E6B7
+:109CA000583D939B789E392736C94C6C00FFCCD425
+:109CB0005948AFB6ADE77DFA8CEEE87DFAAC4E7F41
+:109CC000A903DF9BF57EFC7CC83C7DDCD910942980
+:109CD0005ECFE989EE374FDFA7CF3B1FFDFCCD54A8
+:109CE0003DBE8D86D191798E3A7DFF33787C420AD4
+:109CF000E929F93A19F96E5165989D3AEC375AEB12
+:109D0000B15F0EF9471B9785A79D7711FD6DF5A8EB
+:109D1000D016F2931E2E0D7B2A3C0D77C2D4887983
+:109D200074BD37F838F8BEE0E3B49EDC9FCFC7BA05
+:109D3000B9D30C4175789D73753E0D82E0F3A0D3C5
+:109D4000C27C9ED9F5CBE9617C64F598408D585F63
+:109D5000829A086A843FB5E7A646D565433E3ACE67
+:109D600098AE8F9FE41D1D358E81370CF9BD9A5A30
+:109D7000DE493864BA631DE38E94D913A2C62D3E22
+:109D80001E2B27641CE17624F29F08D79F56A270F1
+:109D9000C62C77803800B33F546270C97699EC685E
+:109DA000EED9E8E7E6B4CBC8ED72FC84A93F9FEF9B
+:109DB000FEFBF9E9D2A2F9995611CDCF745F343F79
+:109DC000335745F36D943F9A2F63D64D896ABF6A26
+:109DD0006351547DFC8373A3FA6761008CAC4FDC44
+:109DE000BA24AAFFA4ED2BA2EA939FBA2DAA7F5E04
+:109DF000704D547BFECEAA2B927F61A82EAA1FB174
+:109E0000D7F40DF2BFBAED1FA2E6F9EF96FFA23428
+:109E10003D2FAFCB7F998E435C1AFAC7A2E138453C
+:109E2000E915F293AEF637BEA0FC4BA044E5BC5357
+:109E30006009781BB1ED09D927915F1B83AC36A16E
+:109E4000DF6832C13AF2F78F9A4C9C8734ECBC2A17
+:109E50004DE08BAA34E1F79F469BA6F866F0CFEC65
+:109E6000DE9E4478433699A09BE29AE265BF71C6B4
+:109E700001E16B713E7934705EAB3479F6B299A82A
+:109E800087F29B32EF1FE5D17E50717D8DC71F3F5A
+:109E900041F99F8B0E9B4AFA2AA7FA0314B7707DEB
+:109EA000A1E761245E79AF3E3C89F649467D95671E
+:109EB000E366EABFEA8E859368FF3AF4FC8E8E492A
+:109EC000651172885CDF8A38F8E87B69223F67C4D5
+:109ED00087DBAC6A630FCA6B9A2CFC3FC685EFA583
+:109EE000E1FA3F901E360B9C1530D3BA314E72DE2C
+:109EF000DF8580BA0ECB94E178A47E8D4AF5C184CB
+:109F000068DCF9261144FB085B2AC7FF5B0D7FBBA9
+:109F10002E8FF936E888EE3F78F744C1CF6F23D70C
+:109F200090DF672C621D06DDE7753FFCA9EE877B9D
+:109F3000C9FF46E49BD7ED783C89F0F5995C81A791
+:109F40008DE7CFE8727D264DE0E9F53B139C9179D2
+:109F5000C7EA902BAA5EDB36CA7936420FD71BEBD5
+:109F6000F04B0AAD63836E3FD59D3DC9B701E3F168
+:109F7000A7D370DC9A1D17BFBD8FDE370D648838FC
+:109F80001AE0F96E790F18D7DFF21544E1D297D2B3
+:109F9000447EE525A20BCB95583851DF56626C778D
+:109FA00051F9C6FC72B23B7C1E96B0BEAC13CC8499
+:109FB000D396FBB3CCC4F453E07D672F2E6D5F9A2C
+:109FC000CAF3DC043E33C5C577BF5D9D44FD86C63C
+:109FD00033C61943B959D42B57C09C41F99A6B2405
+:109FE000C60D389F8D9EFBEE18B399E2AF31DFBBF3
+:109FF000E0BFF00EEAC50AF0F2B8C6F800A9517E3B
+:10A00000F803CB901CED24BFBA2E5398F239756734
+:10A01000AC7CFED1DF30F0EB0790CEDF557DB15741
+:10A0200042BA7FBB7AE057FBF0F9AD4FA1DFC5B56F
+:10A0300066DBFD87D322CEC3CEDC7D91ED0CF1C86B
+:10A04000F34F92337AC9EA25FBF8A0EAA59C48BCF5
+:10A050007F226D6127BD07B3D3E29E47C4EE2BABD1
+:10A06000483FD96E55C699865EDEA7EB65DD0B933A
+:10A07000F9795DD2D07A44FD7999F3577507ACBC74
+:10A08000BF7F47D787AA17BF9819999F6B41BD54C7
+:10A0900073A8747249E79C2AF266CFF1C1A9D46F04
+:10A0A000A3ECEF213D3978E9E364AAEF79F34B5E45
+:10A0B0000FDC7465F4F723F322F95C9B34F02EF97E
+:10A0C00093EA7D5695F250A5FBF28EDD8EF59A4E01
+:10A0D000F43BB89E0BAE9E234FD37E6ABF04949789
+:10A0E000AA0927B073AF69958294C7AA6ADBBD65D8
+:10A0F0000CD6AB9A971793BAD6260B3F56D32205A8
+:10A10000693CF0A7317F8A74DB287D35EF1F0BB0E7
+:10A11000BDEFA818FF5C7D78EA59F44F7D2D9F9D17
+:10A12000233A36B459393F762E296C1983F35ED819
+:10A130002D8502EAB0DDF6B9C43E6A5DE8310BCD8B
+:10A14000BBEEB9E5D9040FFBF69DB4907F5CD7FA5E
+:10A1500058B9FEBC5884FB20DBC5FA9D1D9322F341
+:10A1600049F721FC83C8F881F40508F78290E309D8
+:10A170005D3EABDA273612BBD0AFED7D5A62BFE64B
+:10A180007493DF3BB8EBDFFF95E6DDFF2F9398FF7D
+:10A19000C557C67FF005184FD4E8F3C0F95316DA57
+:10A1A0001FD6B49ACFC53B17FABEDB77957BC6F0B6
+:10A1B000FE3616576FB18038B79900C1E7291E38AF
+:10A1C000062CAB919E1F5107A447710E58D660DD37
+:10A1D00046764671C2E308C6DB17D7B9159E0FF75E
+:10A1E000081BE39D57D6EAEDA56A8F85F270359E70
+:10A1F0005E0BE9754DF813715EDFF651B91667BF56
+:10A200005CED167ED3D003C3DEEBD2A7B05D98879A
+:10A21000E260C8C6765FB86680E253DD7ED40EDAAF
+:10A2200017B8FC034477606F824AEB2BDDF7C9CC8B
+:10A230009E8879FEA4DB8751AF79F9A3A966E2E78E
+:10A240009E8FA62A49C3CFFB321CEBE2E555AADD5F
+:10A25000224E6F4EF69D8FB683046F18E7AD69B737
+:10A26000F3F907DAC1968EE2483BB875DD0ED2F3FA
+:10A2700076D98B1601356DCBFD0DDC3FC94BE291D4
+:10A28000DB1606480F65A78FF513FE8AF3CDD4CFF2
+:10A290007D2652AEDB7F1BE991E2084F8ACC6BD45E
+:10A2A000987A7ED121915CB76B269AAF08D86FC996
+:10A2B0000E5F0FEF9F8A3354DAC71E9E510EC4A75C
+:10A2C0009F1E90385F6B4EF56FCD22F91E95B9BF7A
+:10A2D000E5F00B013A97EE9B06C5449FB1DE9F4E19
+:10A2E0000B838CE36C2E042F4DBB79FF2D1ED2DF28
+:10A2F0009FA61F617C61F78680FC4A23E206CAE7BD
+:10A30000D80B42611A2721D7572CE33C796E27F3EB
+:10A31000CB62F57B291F944D755C874DF1AD23FA17
+:10A320006CEE44B19F1E7B6579BA3EB27F85CE1B31
+:10A33000FD9C2FE9330B3DEDBB0A185FF31D9D39E2
+:10A34000D4A409BEC1762E6BDB3AA646C6DB44F028
+:10A35000DBE879DFFE5BBC44BF3951D7F78C44B6EC
+:10A360008BD8F9FF99F499E46E5AB3358BF84C7C8D
+:10A370005347F67B5AEF67F003147F2ED92B92AA2E
+:10A38000C5CB0F8D77973C4E72DD9CEACB7515F0EF
+:10A39000F1AC00C39EC4B87687FDFF5764FF1FE988
+:10A3A000FCDCA2F86DC4DF4D7ADD6CF1A94EB67FFE
+:10A3B0009F4AF30FAD6F74FCF5B5E9F6BA6582FFFD
+:10A3C0001BD7B74F5F9F3915F58DC64B06EE674E0D
+:10A3D0000E0648FF9A92A078133E3EEC2AF790DDD5
+:10A3E0006D39F4C538B2F7A624AF0728AF7560D62B
+:10A3F0002AB2FB2DA36F63FDFFF485BC2239629E58
+:10A40000136925ADE4BF7E69ACCBE2CFA575FC42F4
+:10A41000D723635DE96EDFABEE88BC118C755F916D
+:10A42000FE80BE9FF3EAF117F7739CFFEB87442F82
+:10A430009D27EED671B7023ED61B3B7855C6551AFE
+:10A440001CA37B1F8D1D26D846CBA6E454C4395DC2
+:10A45000B26C32367D9A0DB7E6746C4CED6FBAEB88
+:10A46000963421BDFB21200B7C169DAF004DD2A45C
+:10A47000C83CC56B55F1F314CFF81BC92EFF569E8F
+:10A48000624ED8B4DA92F2F7E72BCEBAA3F73D9F2B
+:10A49000BA55262A942BF431144E0C8ABC174CA7BB
+:10A4A0007D5333F112FF7B06D7CAF62DF5E5DA5C52
+:10A4B000684FEEFBB76D1D8B76972DD64FF546FA9C
+:10A4C0007BA7C03D43F98FD7A630EE463F27F3FE6A
+:10A4D000DFA9D31223B762C46BC0F78852A3F22757
+:10A4E000E1235F26937EED4A55DF22B90C74C97CC7
+:10A4F0004F2441E9B1B8E2D8D93EC203E8F78BD383
+:10A50000C53EC4D626CE176DAAC67E31C1E99C26AB
+:10A5100047D8C579B7C89F571FF9609C0531DC053E
+:10A52000D3F1E4021C7FC3DE96644AC3AD3FF3F669
+:10A530004CBA9253A2F81DE9B8FE4FA51D3936C298
+:10A54000A95B8353893FA1F08414F293850A049494
+:10A55000A238F1F1A922DE14D73CC587FF50D83EBE
+:10A560007D2DE1E5DAB0582FCD61C6A6BC36E07A84
+:10A570005F5B632A8D57FB6F074693BF7A295DE0C7
+:10A580009A172F4D11EF2BA050FFAC7497AEE741F7
+:10A5900013E50B5FD2F38C7D974CDCCF98BFB06D89
+:10A5A000A1EC443D28086F3FC479CD76AB4AF24D0B
+:10A5B000780E043FDA131877D61E5C0C14E7FA5DA8
+:10A5C000E095B07D57E2C06F491F060E58553A77A7
+:10A5D0004D706E87541C7F977E4F2B0F15B2C5317F
+:10A5E000FCDC982FA1FDE7941324BDE0F3DF0465A4
+:10A5F0003B5CE388E47712D35DA2EBD5AEC4B089AF
+:10A60000CE450626E15E87E91AA613785E83CE3C26
+:10A61000F6FBBB2C03E77EE066BA9CA4077920E832
+:10A6200084F6C92AF9D104A7C6EB4870AADE8034A3
+:10A6300092AEDAA908FCD06E1E25E73577D8AE6B4E
+:10A640001387EB36B4855D13403F8FFFD5363A8FC5
+:10A650001FAA9383993DFCFE2DE92F6C6B1ACBF951
+:10A66000BD808CA2B66399944AEB54797DE845B5D8
+:10A67000F422C107BAAF67B789F6A1FEA8E70EAA10
+:10A680003B443FAFD5695F92C5F64287D74378F028
+:10A690007E297CEE5AB4D7DEC77C2905B8AE5ED3DE
+:10A6A000A1079AB1DF9F568772E83EE97356FF1AF9
+:10A6B000D2CF573E5CF34821F9DB5D666F25F99DEB
+:10A6C0009EC0CF1887BF6856B745D81D8C1DC8E0FF
+:10A6D000FB8031F3D49ED9F433C2D7FDFB2595CE50
+:10A6E000BDFBCD03E388EE9AF63F5AE8BE64EDFE6B
+:10A6F0008F184F4B19FE1A9A6F765B03DF6B9B0323
+:10A70000DBF95E1BFA43BE9F18F2087F32783AE706
+:10A71000D98608393C912EEC0D06FCE3295EB5EB99
+:10A72000F67A90F6DD58EEEDB875228DBF57CF075B
+:10A7300018EF35C0A131C4F74DF01A97C6F3FEA04B
+:10A7400052417A96FFAEED4E2DA2FFA3E902BF3D26
+:10A750009A2E70667686BF89E85DDFF1B12599D6BD
+:10A760007936348EF6B921454D71C6F12343F61B77
+:10A77000634FB5CA8085FAD79E07F62B28EFA6143B
+:10A7800094DF4BEFB64D598DCFF7A24C5228AEE275
+:10A79000FE94E2EF5EB36F0CF56F78E7F3A9E4C7C0
+:10A7A0001E484FE7F57F7E60FD78E21BEA7F492275
+:10A7B000D9D96E60BF66D86901D929BE5F40FA5FFA
+:10A7C0004CF53CF6CBBB2CDD4BD82EF79A80EC1227
+:10A7D000F59FED01F5DF49F8AEC089F6C0EF4F6691
+:10A7E0003BDFD56DD21827A35F9FC4F5921BA9BE8E
+:10A7F000ABBBCCC9764EF7058AC85EC387789C1080
+:10A80000C024129D04BEA8FC883B99E936FCE5E70C
+:10A810006ED0E3869AE2C575D86539CA3E22E2A4B5
+:10A82000A81B71F4C933DB9E407B81EED428DC0F7A
+:10A83000EF0BBFFF5D3D56D5BD3E775933AEB3EE4E
+:10A8400084CCED07F57D5E58D793437A7E86E28609
+:10A850003A5DDCEFA5E733B04EF75D676A1B4B0945
+:10A8600063CDAED87E98CAB9BE502941C8F9ABBAFB
+:10A870000F9B8599E793FEB51EBA2E9FEECDF59FEF
+:10A88000B1420292D8FAE5C06F5FC4B53D7010F9CD
+:10A890001F274EE17258FF106F8D01CFC8F67EC999
+:10A8A000F023BD4B481FFB5AE5E13A1252838A4D13
+:10A8B000F577D23FDD16C0BA3F437B9F54E2C7997C
+:10A8C000FEF7493FFB4F7E994166B9F7B4D8C7B749
+:10A8D0005AB47CD29FD609B8B58DA3A7AFA58B3C3F
+:10A8E0004FB115E29E4B7EA5C7C19C003C22F1FEF4
+:10A8F0005C760651EE175A65CD82F8E73C0456CED9
+:10A90000237FA3E76FEF01FDA7E11F94CFBD7AF589
+:10A910001EC22B18B7EE7D62C4B9BF89F4696DBB46
+:10A9200004FF846B5FF74CFC7B09465EEBBEB61DF3
+:10A9300047C6A03CAB9E8BEEB761E89E7B88F7BD17
+:10A940001B9AA3EF1B7C95AEE396893091700BEABE
+:10A9500013FB07B3029D56D4DF5732FD9F105E7E76
+:10A96000C924F8847E95EDF213B71E674A843F1A16
+:10A97000B8007C8F286F67E830DDD799DB9CE5A5B0
+:10A9800039E62AA27D6E5B16C719508232DD3798F0
+:10A99000ADF9CB195F07B4D3742F649DEE27C1893D
+:10A9A0007F28BFA3AF6B9D8EE7EE0B46D33D07829A
+:10A9B0008D34CFDA9DE2FED1FA9DF1BF13A8D5C741
+:10A9C000D9F0D4C923940EAC0E45F7ABD5F953DBBF
+:10A9D00016FDBC057812189F117DCFFC4AEF43FC91
+:10A9E000C92CF0C5DBFA3846FBB519C27FD62079F1
+:10A9F00024DF0D4139487AB34E0A240B7C0B8ED5E7
+:10AA000048F75D86BEE8F765EFD6F97397AE2FBCC1
+:10AA10002E7CBFFA192948E78077FF249AFE7B42F3
+:10AA2000ABCB491F62F56A5DB399F16D156CB4103B
+:10AA3000BE8DD5ABAA217DD96EA13816AB4F357E20
+:10AA4000E932740B5CFE7F4BF77A7398F34CEBFFA3
+:10AA5000A7E4A53CD4BDADDFB1505E74A47D08F978
+:10AA600056197AA2AFEBEF5DCFED867CA7C01496A6
+:10AA70006F45DA15EE83A2F1F46ECB509E92F37C13
+:10AA8000839D13383F6EE851EC38E53A2E5FFC1495
+:10AA90007079A1ADD44EF8A2FFB8C92BA99C7F4C08
+:10AAA0002E443E4C3F2003E18DFEF6898F0790FE39
+:10AAB000A213C53752BE7CFA098C3FD8BEA7B3F8A3
+:10AAC00057E45F11E1A4917D2FECCA4EFBBD83C713
+:10AAD000E1F8DD7FBCE8F14AF2C3C7CB8A695C09C3
+:10AAE000DBE97E78911E871A8E17D97B22E2D1FD91
+:10AAF0001922DFBEC5F3FB47695FB078B7D94BF9C0
+:10AB00008EC566FFA604A4AFE805C9DB80B31DE9C6
+:10AB10003EF4248D8BF6A452BE66F1EEEF1DA2F634
+:10AB2000DA5D12D3DFDFBE287F17C5C7A0ECA5B85A
+:10AB3000D7DF7E57C1BD84730EDC537057C47C478A
+:10AB400052855F597C9599E371EF68FB2F2B29CFD4
+:10AB5000A9ED60FFD0FBEA1E0B7F57B04B020FAE92
+:10AB6000F388E7F0AF890FBDFB4E5A08E497B69E15
+:10AB7000B4F4C4F1CF467901B77161CEBF6EB7F0BE
+:10AB80003DCABD7FB0D07A6B9EFB88F369556D12CC
+:10AB9000FBA7AA67E4A04A799E03AF58483F6B9A87
+:10ABA00025C8CC8A6C37733BF951AAFFB159F865B7
+:10ABB00043EFD7E87A6EE8BD61076B74FF75D7D6AF
+:10ABC000683DBF17B42DA3F1FD7B9A57F33DA07BE1
+:10ABD000B6C7F75F861F5C4BFB528C2B6B9F8AEED0
+:10ABE00077DF907E07D8BFC7FAC95732F4F3D83C55
+:10ABF000C823FD1E0CAF19AFA03D7D7EB26A3CC4D8
+:10AC0000C93B1ED7F180118F07C3268E67B1FDFAAD
+:10AC1000DA2E5A288ED676FE99F16B79FB672C874F
+:10AC2000CAF60EBEAF7A3DF837101FAF6FB73B09BB
+:10AC30004757F608BB5FD26E0D06256A0F35917C2B
+:10AC4000FB0F8AEF3B02AF4A8CA340F77F6B757E08
+:10AC5000AED5F9B716F76763E8DE8ABEFFBE2F7779
+:10AC6000C711BAE251A33FDFD0753899F8B8048410
+:10AC70007F5A1212FEC99087115F46C6D1816F9329
+:10AC80003CD7B75BF9BEF852DD3F2D6D16DF93C59B
+:10AC9000FA8BFE517691FFDD2BE88D8DA735ADD176
+:10ACA000FDBB32D2D9DF0FEA78F813C3DFE8F2A890
+:10ACB0001C003BE5E797A8B237C86F752B347FE7D8
+:10ACC0005489CF633BD58929F1EE4B19E59B3ACEE8
+:10ACD00037EACB284F86FD43CEED8EC87DFC8D999B
+:10ACE00002AF54CD910324CF887DCFB2A2ACB8FB84
+:10ACF0001EC844BADF187BD74FA645EE7BB41D397A
+:10AD0000A4673FF23C5E49F78C6A9B857FE89B8D88
+:10AD1000E3A6108E07C6C5B5CDD620ED4F6A514FBC
+:10AD2000F87B30D20FB2BF766911E907EE1B1C9990
+:10AD300048CF723AAAC4F52F6FC3388EC32F2FFBAA
+:10AD40008CF5AA2B5BAC1BF996196F1F61EC1F6A7F
+:10AD50002E099C6A3CAF517A781F51D32EEE49B729
+:10AD60001EFA625C16D2DB7FE03FC6ADC67241A61A
+:10AD700088BFAD25A18FE9BECFE7BB6C71F1E8902C
+:10AD8000BF979AD80E6ACC3D198C57F6232E9C8516
+:10AD90007EF3ED4F79DFD17A28E14ECAC7F5ADF1E8
+:10ADA0008F777E839C1A6013E3DA4DD0C425E19E31
+:10ADB000481CB8D629EE0FDDABC749AA3F8C7A7D77
+:10ADC0002FF65D5014CFEE035BE64923EDDDF01B5B
+:10ADD000D5BABEAF2FD8B1858EE063F151B56E47BD
+:10ADE00088FC392EC6E2A21B33A3F5B4E1ED44C6BC
+:10ADF000B9FD5DB29372C4C8D75F8C26DC87F87E3C
+:10AE0000429C3CEBA7BA5EF6EAE7BE0DB365E69B53
+:10AE1000698E280D1C85FC637DE93FE908521CCB37
+:10AE20003FF8CA0492FFFA9DD1E745243F3FDFDF98
+:10AE30000AB2FCAA43763E4332DA5F3AF8CA14D229
+:10AE4000B386B7BFCC1172F922C7E2BE3C7D46295A
+:10AE50004962FF6B92C4FE77AFD2934CFBAEDAFD32
+:10AE6000B22FF2FEBC21E7BB75FD0145ECF3D765BF
+:10AE7000AA5C6F68177A613A204A9C7FA5C8F3984C
+:10AE800079FE11ED25A82FDF10B780E842D9D79AB7
+:10AE90000758EF6A4F9A989EDA938319D911EF05F4
+:10AEA00068DC4CF27B0D1B80FD881DC8BF2EA5EF12
+:10AEB0000FB1BEF4FD04C65947263C5229CEAD64FD
+:10AEC00020BFF5C0DB559323FDFF053DEE03F1C127
+:10AED0004328E70931BFCE874DB042CF13083DAEBE
+:10AEE000D2712CEEAF9AC88E63F757578A931B0E18
+:10AEF0005881F2C7B51F58F93ED0E707D6F2FE1DBC
+:10AF00002EF927939F01BFFF6A2A1F38B876323D7A
+:10AF1000FFFCE07D5773DE53DA1495AF08107D1EF9
+:10AF2000C2517F79F776C2975D0AE390A2AED3EF64
+:10AF3000D2F9EA9E56337F9B59BD77C6E38124C27E
+:10AF40004F454BE9BB9D3D9D0AEB1FE22A0347D9C4
+:10AF500019479D28661C85E3F8825C161FABA47117
+:10AF60004F9414533709DBC99F4D271CE518C6556C
+:10AF7000063DFF9C29F8D9DF91C0F9130926083D49
+:10AF800083EC28BA37B4BECE3864439B1CF5BD862B
+:10AF9000F1DEEE4C71AEB0D7D0B390A4B11EED1679
+:10AFA000E586B63D19B48EF5E610EB4943B359B4C6
+:10AFB000EF1225D0F9CD0CFED83840FC39468F5021
+:10AFC0002E4B2CC1B184DB770F9D07EAF73982E263
+:10AFD0005E5D63E744FE6E68B0738F3B5EFC394E86
+:10AFE000E73348DAD12CB1CF896DAFF3887CC6D175
+:10AFF00033C22F1E5DE89F1CCF3F06A044ECFB250B
+:10B000005D7EADE68A78E7861B3D22DFB4736CE097
+:10B0100028E971EFEE043E37EC7589FC6C694B97BB
+:10B0200042DF9FAC6F9566503C5A9FFB1E7F9F820C
+:10B03000F562F683E1FD7C6E5ADDBCBB5C8B43C7D9
+:10B04000B51E111F97E8DF018FD057BDFD1478D3CF
+:10B05000F57DDA23745E73AAD2EC14DF9989EF4A86
+:10B060006FD0FDF98DD79B19379D02D52CCE3FC4EB
+:10B0700039C532DD2FDFA0FBF911DF3B3F039BE930
+:10B080009C22F67B67C3AFDFAC8FBF02341E37F65E
+:10B09000BBF59B753C78B32FFAF9A54C1D07E6402C
+:10B0A0000EF9F310C617BE1F9197C0717A69E1A41B
+:10B0B000B83883BE0357F5EFC0A934E4DE90F71E1D
+:10B0C000C7BFA31D677ECDDF139C49800971CEC524
+:10B0D00086E39FE13F6E12F2D6CF2DAA9D824643B2
+:10B0E000EE17700716991F33E43E46E7FFFFF13D68
+:10B0F000A05C5022F325CFCAFE311E3A9FB0F53234
+:10B10000FEC615701CC4758DD3D735CE1A11DF2E2F
+:10B110008C5A1D577F87D7971A1071C4CD65479EEB
+:10B120009571627548E2EFFBAAC3625F5B5D26F62C
+:10B13000B539AD02A7AEBC490A6A12BBC3D3449F5E
+:10B14000A13FCB6C020F187A32C42F5D7FA89DF00F
+:10B15000C10D3A3E88D5A3C9D05D4EF9E65B34C92E
+:10B160004BF72A477C3FBF6ADAEBE4EE2FA73FA8F4
+:10B170006FFCEF22C4EAD1F73DFE120FE5D3BA0708
+:10B180005716E2B847F3FE388EF4A6E63276F32D72
+:10B190008F88133B1D81A37CDFA4453FEF6FC96BF4
+:10B1A000EB217E7402E3C75E57F7963A81ABF9BC98
+:10B1B000BF3A9CC0DF4356B7DBF9BBB0EAD686C4C2
+:10B1C00029E47FDB65AF1DEB95AD27CB889F95C547
+:10B1D000E23E4AAD5DDC8BB3B9FDB7107DD77B3B5A
+:10B1E000A2CFF92D3DBFA8FB063D8FF56B1B09A330
+:10B1F000A5FFF7F99B8D3A5FEABA2E664CC1A9FE0E
+:10B2000090E6AF267DEC7FFD450B1DD7D54E79A589
+:10B210009CAE886DF4A8DCEFFAE68E264AF31AF4A9
+:10B2200077643AF9F95173702CE3D2822BBB0FD3B8
+:10B23000B0FF8DA914A7FA3ABAA65A22F4BBB70EEA
+:10B24000FD731CF9358049B75B854B495AA1E3254D
+:10B2500061C7B5070E67503EA297ECB780CA7792D8
+:10B26000B3B1ACDE7D2A7912E196BDA21CC219ED04
+:10B2700032F703A527E7E6A448FA36337D17426282
+:10B280001C809E9C1B0B23DB1BFF5FDBFFD3A427D3
+:10B29000D5B69E28FB37F884BB7CFE3E3770D0CAFB
+:10B2A000F708E8BCC61521C757747F340B374B64C9
+:10B2B000A773E87C7A22413B05EEA0BA026125958E
+:10B2C000CE8BC3B2B87F3796FDF74C7DFE594AB896
+:10B2D00083EEE9CED1CF37E74237F75B00035C6AF4
+:10B2E000E0E4EF8B4BC0CBE56C5B7829C1F1825079
+:10B2F00088BF9F096728AE7336FD3BE638F21EE62D
+:10B300009B02E70C7EC8740E26EE1BC5AEA75BD76A
+:10B31000C7599AF03B041DE87EEE6C08F1B9FB3585
+:10B32000D0A39FBFC75FC73CDCF7D1B9DB35683B13
+:10B3300089CC8F20F79F4FEB91E3ADA767298B193D
+:10B34000CA9C449F14CE307D6DBFF275F4D36D4D11
+:10B35000CA57DF35D0F783E2E1734B6FFB1BEFD3A6
+:10B360007D6249D3F8BEB197BEC7A67D4E58E91D90
+:10B37000F2631300FEDDB3E637646FC6F71AE00729
+:10B38000BEE711FBBD062DF77CC6F03D35E3FEEDB3
+:10B39000CEE00A95EE6FAC72DBF8DFAD29B28D9B83
+:10B3A0004E79CA87D2FCBF21BDFA406A9EC4832869
+:10B3B000C1198C6375BDB283369BD62F69C6F7223F
+:10B3C000C0FA32F4EF0164007FB763B78AEF691EF9
+:10B3D000413DB4A5B2F6AB740F1A1E2E55092F6F5E
+:10B3E00071D9BCF45DAE95E8B50FD3DB6813F72FC8
+:10B3F0008CFB6BB17C6CB419794AAF8D7176CC77CC
+:10B400003E77DAFCFF9BE8BF3FA924937060FECB38
+:10B41000F33D7C3F29C15877898DEBC3F71A193763
+:10B4200036D17D6AA4AB311DF81EE2E1A49C14BAAA
+:10B430001FD5D825EE5337A607D87F9BFD12FBF307
+:10B44000C6CED24E8A07830E0BDFAB6E74F934AAD8
+:10B4500007D22144FE9FF83EDFE0BB6998EF21FD53
+:10B460005E5091EDD75751DE7F9A1B4AE9BD696165
+:10B470006D12F1C0F81E06E5E019954ECFA3EF7BE3
+:10B4800081E2E4FB17861C503158999DBA7C0DB9B6
+:10B49000388DEFF83525EA3B7E435E8F240AB99854
+:10B4A000E926CC447E57A57163E561F0FDBF008FAE
+:10B4B00040AEB13049000000000000000000000074
+:10B4C0001F8B08000000000000FF3B24C3C0F0A356
+:10B4D0001E81EF4A313030F1A28AD112EFE364606D
+:10B4E00010E062603005E2FB3C0C0C3380F44C2031
+:10B4F00016E566601003E21A20DE0DC47B80F819A1
+:10B5000050FC3910EF00E21B3C10FDBE4C0C0CFE51
+:10B51000401C08C4C140FC958181E11B03F1F67316
+:10B520000A33304C1547F02F03D99F24E9E7FFC1B8
+:10B5300086430CE96BDF71A07DF3AC107C46207B69
+:10B54000BE15AA9A0556F8CD588826BF088DBF1893
+:10B550008FFE720354FE5A4D34B3B581E90949CDCB
+:10B560003A4DFC6E41C7AA40FFA9013100ADF15F21
+:10B57000CA68030000000000000000000000000096
+:10B580001F8B08000000000000FFE57D097894D5BE
+:10B59000D5F07DE75D66269999BC816CAC4ED844A8
+:10B5A0000B7442421A10DB618B6811834B051798AC
+:10B5B00008644F2620F5C7DAEFCF40005151438B86
+:10B5C000355AB40304051B34D88041020EE0822DA5
+:10B5D000D5D86A5DDAD2A0C81A93801BFE5DFCCE76
+:10B5E00039F7BEC9FB4E2682B5FFFFF5FBFEF8F822
+:10B5F0005CEE7BF7B3DD73CE3DF78EE218C7948B1C
+:10B6000018FB12FFBEC798DDC6181BD79D32562304
+:10B61000D24A2DCFCD58D003FFCC62ACDCAD85979C
+:10B62000A7333665871AF95E12E43748613BE46D4B
+:10B630007B9D54DEBE9EE7236ECDCFA0FCA33AC80F
+:10B640004BD0DEDEF2C06550DEB943661BB1DB9144
+:10B65000713696C2D83107E37F5990CF66ACC0C926
+:10B66000B3E51BF6CDC5F6454D76E684FECA7715E3
+:10B67000CEBC0CF28507558655CA372FD3FA43BE88
+:10B68000382C3560BE63329F5F68A71CDE0CF53B2B
+:10B690003C2D2937B8183B55E5605E8DB16A774B74
+:10B6A000CAF5A3182B096FCFC57625F5920F973AE7
+:10B6B00065C7E697FBE1BAB64A3EBB97B1D22DF11A
+:10B6C000CC3B92CFE14BF8FF58A31CF91E942F8678
+:10B6D0007532E8B790D5E43219C75FAB79DDDDF09C
+:10B6E0003B55A5D33846BE7C2B8C03ED2A9E967C19
+:10B6F000B8C40A1B0B34C0F8EDBB9CB337B9707DDE
+:10B70000CBB4116E5CD7DD1AD62B0CE7EF747A71CF
+:10B710007E1BB45C282F59BF412B18D5DD5FE996FD
+:10B72000BED679D50E4D0D98CAA3D353558C794703
+:10B7300074E74B18F33740BF4C096BB346777FFF74
+:10B74000802532968CFDCBCCEBE8EE1F2049DF4301
+:10B750006FC13F015EA13D6E82AB81B7C53AFCDB94
+:10B76000DB8DB7B3BAC0A3D2996DEEDF481F403C62
+:10B77000C07C6A104E90AE11F3F34C649314E8DF72
+:10B78000E367BAC47A5F8F91D6A82C9FC1580B4249
+:10B79000A3FDCA78C86B6C11F331F69315D9FEA9D5
+:10B7A00090BF9F05E6E2BC57488122C413630D6930
+:10B7B00048BFAB24361BD7FF039C3494AFEA07F491
+:10B7C0000970AF9996BD4996C4DC93305FF0C4BD53
+:10B7D000E9D44F21F5A3423F43CFDF8F9E9B63E91E
+:10B7E00047CF2D32FAA9A47E9C17D64F4DEE04EB1D
+:10B7F0007C724B8C7EEEA47EDC17B62EFD8A89D639
+:10B80000F95C5146FD244EF5B100D4970D7A602DB8
+:10B810007E19CA5DF58963EF6566BA98BC12F9DFD7
+:10B820000D5C62A68B849C380B1D26FAFB58F2D067
+:10B83000937EEC5B220F834412351A5FEBAF915C71
+:10B8400098D4DF41F93BFABB482EDC312170B10EB0
+:10B85000F3C0B1593FC86B816FEB31E81AE629B1EB
+:10B86000344CBD364CA3CBEF56391C260FF8DB8881
+:10B8700023D03E68EB1C9108F9F5D2A45F205C361A
+:10B88000331BC1274E6695582FCECE483EDD9D9E78
+:10B89000BD296482D3EA41807FA9BBDFD56A200D30
+:10B8A000E96B2BBB2184F4B66A10ACA73F634F85CC
+:10B8B000AE8F8414683FA8200DE169D780BFCDE327
+:10B8C0006B30FE281AFF191C77078E3FAEE7F8F69B
+:10B8D000213996F11D838B2CE33B34181FE87D172B
+:10B8E000BB558C0FF09BC0D8F3A15B687CFBE022BA
+:10B8F0001AFF6E8D1559C68FEB1AFF051CF7A5DED2
+:10B90000D63F648275FD834BACEBD7F8FA5F650BCD
+:10B91000C5F871B4FE5F8716F0F50F2EE1EBB7F3B3
+:10B920007EBBC6F774C1FF751CF7ADDED63F74A2AF
+:10B9300075FD179559D76FE7E3BFCBCAC5F82E1A27
+:10B94000FFBD50195FFF456534BE660FF8908EB499
+:10B9500001719561189F0D0486482519E5A7746447
+:10B960001FC6A0FD3A3684E070471CA7BBCFE2801B
+:10B97000DE5CDDF28E8581A3409E55089A2FAD9F37
+:10B98000A4A19CA572907B0BC5541734C9B4DFB039
+:10B9900075F6F070986F7B931CC2FC827597876573
+:10B9A000DAEFD8BC3C6CA7B0087EFFF0A1D11BCD6C
+:10B9B000EB8A4E17D6A8C75A2D7CC4E7139ACC46FB
+:10B9C00056C2FCA621118CEBCE1F0339CA407EBEA5
+:10B9D0000F7214D3E32A8C07DF8F829C659A996FCC
+:10B9E00096F17D3CC4DE1C99827282FF1D5338BCE7
+:10B9F0008F2D91C208FFCFD62ED2503E2DAC890795
+:10BA0000A077CF2328F0D4B9CB1EDE28113CBD0887
+:10BA10009F1B891519FB33A0B51F80B6B0B6AFA523
+:10BA2000DD2D2CBC320DEACF5F933F4887F5DF3C1C
+:10BA3000DB3E56C6FD83F907D8888FD9005B0E63BD
+:10BA4000B31BD7AA032073E36CF5FD5653FB3901F2
+:10BA50006BFEE6226BBE5D0DAB36D4378A25B60190
+:10BA6000FABDB5D25A6E8C9328F5E17815E3FD2026
+:10BA700085CFF7564CC7E2679DF03A57E76D8DF9D1
+:10BA800004EF525984F6CBD66446F84FA67A019D4E
+:10BA9000AF3B7ABE7355873F0FE633F74E99E019F7
+:10BAA0003DFFD6BDF17EDB18486B3F569104A3D70E
+:10BAB000133DFF794BA3D7A3931E961F8AFECEE9B1
+:10BAC000249A9E824D93FA1E35D52B6FB8B2EF5152
+:10BAD000137D956E9965C91787E758EA17D6E65B17
+:10BAE000CA17D6145BCAE7AF5E64C9E787EEB4D461
+:10BAF0009FB77499A5FCD6CA7B2CE53717ADB5E482
+:10BB0000E7041EB1D4BF71F6064BB96DEF25D720FF
+:10BB10001F55BF2533DC373E751D7B00F5C14F5DDA
+:10BB20008A0FF171A22A8DF8E0549597D2F6A64CAF
+:10BB30004780CBC1025471162E6B08AD9E88729956
+:10BB400091FC2C5EB633141A08DAADE425F8C9B5B9
+:10BB50001A8B00094BAC4F171D77CAA6F2D6F39487
+:10BB6000D702A367F62C975B637F0F6ECCBF08E507
+:10BB70004E6FF200FE06E03ED721F6F7E8F232897A
+:10BB8000E599BF33B69CF8FC9C90B3651A9707659E
+:10BB9000CFF69BCC3C988F8CA8FCAAF11A00A82861
+:10BBA00027513B4F467A002EB0D0CB500B7FB7EDDC
+:10BBB00093695E152813C6A3C8C95B23A19C891C81
+:10BBC000187CDD689C87FF7E09F9AE2999F6F5B6E9
+:10BBD000AAE97D8F2A889F3C4A4F54CDA6F4585538
+:10BBE00080D2A3554594BE5F5549696BD5524A0F23
+:10BBF000578528FD53D56A4ADFABAAA1F49DAA5AFE
+:10BC00004AFF5015A6B4BDCA4FA9C10F5DF237490E
+:10BC1000E8ABC2AE809D87F267C55A5640DD16E29A
+:10BC2000735F1AF2F959D76723501F3FFB8E9DA10E
+:10BC3000BEDF1BBCA2E9AD773CFA495F290803FED1
+:10BC4000337B963BE3389E9C36369D813CBA67F841
+:10BC500013BEDB46515E4192810DC937CB1DA3DF78
+:10BC6000618CF0753E3C317FE7986B011FC71EFD6C
+:10BC70006B36F67B4EEC7F710764DA875964930F5D
+:10BC8000F165821BED6B9D3B84BC3F0FFC3EEA825D
+:10BC90005FCB6006E9044927FA3BDB68670AC2B15B
+:10BCA000393E0CC4CFCE1EDCE4417E5C9C66D38F53
+:10BCB000C68083919637A4EB2EF3FED364CD9FAD5F
+:10BCC00091A637903CF6265C3F1AE94AD78F0E437F
+:10BCD000FCA7516AF4B3384DD38F02BF9EDA3234D9
+:10BCE00081EFDF61BE0FD62712BD825D48F5FFD51B
+:10BCF000F3E9AD1F633E8C35B20F1C280FA06CE832
+:10BD0000F9ED9D1E78573ED1F2105FCDEA67A82F5E
+:10BD1000C4C1FF5F0EC17E15CA1BFD061BE490FD6A
+:10BD2000DBF8BDDE321EB4F31A3637B6EB9D6E1566
+:10BD300076CCA02B90571A1ACB64273A75EBBE929B
+:10BD400068C9079BFAE9967D06FF01FC0F82524104
+:10BD5000BA291354D4A1B8564B30BF23283F012F22
+:10BD60004189D72B77B46A012F91630BEA19B7E5A4
+:10BD70001874E7BDF18F20EF4FFE4665F762F9DFDB
+:10BD8000605650AE1AC520F76C909F2F72B735964B
+:10BD9000CE40B977D2C6F7F9052CCF83464F11AB09
+:10BDA000C9463DE723669B8EF4FF11FB9D27D364B4
+:10BDB0006FF86C1AAD73FE6AEB3E0BFA99255F586B
+:10BDC0006BCD17B06B5390DE0BD6A92C2C215F5A8C
+:10BDD000CBBD369DFA2D6495ABC8DE417B05C6BD53
+:10BDE0004D67CA00985FF9738F65E743FE3B36AE37
+:10BDF000A71BF67B711F3EFF92A4B0E687F20F1AD5
+:10BE0000337F7019C3F6E15528A7426EE6DBCC7A82
+:10BE1000E2EFEBCE3F7ABEC67ED2C38F20E6216F23
+:10BE200091FCE11876DA349B24F4AD10A537E0BA22
+:10BE30004D7A6BBE8083912F8FCADF1995FFA7E9DA
+:10BE40002D8959E8ED8814C8B72573FA427D41520F
+:10BE50003AB5C037E93FAD47FFE5FFD2FE0742FFE5
+:10BE6000D996FEEFFC97F63FACC7FC57C6EABFFC7D
+:10BE7000B96D3B43206F4A9E79C8C3601F3AA9D46D
+:10BE8000A4F800EF659B577A900E4E28210FD2F34D
+:10BE9000C9B03C3D163DEC467A203FA2DF25A15DAE
+:10BEA00085FF84FE4F3D75DF4CDC673EDBACEA640A
+:10BEB0002F6DB147ECC0AF158DC533D818CA1FE13F
+:10BEC000F9BBCFC8986FB2D267C9930FA5A0FF0D79
+:10BED0002845D81311D2972AEA3ECCC57D28C83A06
+:10BEE00089CFA2DBE1F8E7FA907CCCD7127A96C32F
+:10BEF0003C49CF0F0AB8041BEF3B23A3EF93B57265
+:10BF00003F6854FD22A1FFD4DBDC49C7C07462DF67
+:10BF100061DF417969C08385B9FE53BDF5E13147E1
+:10BF2000603E6D75BFF1482638197C76B661FE2FEC
+:10BF30009EF7F62E8FDB859DD7DD2E4CEDBC4D4256
+:10BF40006F6BE669991AF1A05E5CB641F585E07306
+:10BF5000D9B64D4F3C8A76EABB76DF70E8BF74DB1A
+:10BF60004B7F9800F9D2ED6AD20CBE0C9794D28D1B
+:10BF70009720FCBF746C371E4A7EF592E61DCDBF3C
+:10BF8000FFB84F373E4AB7EFD3D8E89EF098D2B00B
+:10BF90004F6B75C5C04BC3915CD4AFAAB77EAEA141
+:10BFA0003D7972AFC452D363C073C34BA427209CA6
+:10BFB000088F024F5D788BAA1F04BCA03C37F01499
+:10BFC0005DFE80903FD89F7714D1F3D3CFA35FF964
+:10BFD0003DBB0FD75FF4F4ED1E5CC771A592D3F59E
+:10BFE000632B53FC306E911A4AD129E5DF8B1EFF7B
+:10BFF00021D15BE11B3F4CE1F6A0BF9F8DF6A6501F
+:10C000003F5CDFC2F537D0FA0A5880E8AEE8313934
+:10C010002F0CE9A70A9BBE3D065F64C89C2F8E6F5C
+:10C0200004850BD6771CED12F4B3FE4E0E6F267FFF
+:10C03000C82286FCFF43C33FCE1653FE5307C79367
+:10C0400043B609BE026DCF4CAF7577B7207E4E0D5B
+:10C05000F2A7A21F2DC894908087F425F42BBF313E
+:10C060002D95E38779956CD10EF48029F81DEBB7F7
+:10C07000A87EE7184B3BF6657AF7F84BC4F830EF2B
+:10C0800038DCBF8FA7B0A28618EBBB5536F81EF67A
+:10C0900071137D99F89BF37BDD3D9CBF0D7E0FCF27
+:10C0A0009A8EE59FBCC9F907DBE1FE08F38AA4522A
+:10C0B000F9BEEB259207761689C5D775AAE06B6B9A
+:10C0C000B94127306F454A30D10BF6DF87E04FFE8C
+:10C0D000B38275D0CE242F83389EA7677F06DF16E4
+:10C0E0000AFE1F255BF99FADE77CDFBB7E15A27DB5
+:10C0F000AE4C0D3FF128F22BF067C88BFCAAE6E1AD
+:10C10000BA4FD71FF8C34DC0A7A71B0C3EB5CACF67
+:10C11000683E2D7A76B384F419CDA7A78B401B898E
+:10C12000C5A7F03D269F16B5FE3F959F06FCAE8F36
+:10C13000829F210F7B8363B43C3C63F3123CA3E5F5
+:10C1400021FCBDC9B27BD29F417706BD95FCB2FCF4
+:10C1500022F217187469D05D175D1A74D7C3FF6295
+:10C16000815F74F960A405A093BC5D2AD95565CDA3
+:10C17000FC3C0CDABD3C208BE0E4A76D8CD5BC3CCC
+:10C1800020C99C0F47E51BA2EAFBA3F27951F503F6
+:10C1900051F94A4BFDB2A6031A23FC472CF5EC4B90
+:10C1A0001F651FC4B0878CFD26D878460B215D0C17
+:10C1B000ECD450DEA9CB410545FFE01E99ECC50E3D
+:10C1C00080F12A18A7A33E3D1C02B9B1D2C9EDF0F7
+:10C1D0000EBDD3D307D295893CDF99ACAD42B96788
+:10C1E0007CEF74723F47475EA727D1E4A738D22C73
+:10C1F00093DC6E0DB3E9B1FC20B0A310DE5B596F88
+:10C20000E5DCFF394D760D5E8AF6688DEC431377D9
+:10C21000C1B21B3DE82AE9681E7ACD6CF8BEF05524
+:10C22000998E553AE23C63705E2CE457FA99EC899A
+:10C23000132CF4B389E8CF6CE676C5823551FA0841
+:10C240005B43F454E05AA2A13C053BE07DAB3F9731
+:10C25000F34589E8AF68BDB5DC688F275A68DF957C
+:10C26000D459CB03C23EDA65F04906CB2039838628
+:10C270000FDAE7422E4F93475D331BF0D1715066C2
+:10C28000789E79B659267C9CADE7E7972C944CFCB8
+:10C2900056C13A491E1A706A437ED27A97576D3B4F
+:10C2A000FE9C7D17D2CDCE3F8EF939A46D3BDF1DAC
+:10C2B000B11BF3CFBD3DF88FAC67FD297B9DE43703
+:10C2C000EED8EB267AEFD8F3DBC177617E979DFC41
+:10C2D000751D7B3F1F83F4D7B1DC5E84F2AE631023
+:10C2E000B787AAF77C3EA695F6D71584B7A3B2C642
+:10C2F000F5A3E6BF1E9692308555A1DEB0379EF8B5
+:10C3000029F8BC93FC0B1D7B3ECF0EB8FE75EBA944
+:10C3100010E7391D6E36FB599C5F22F78307778F34
+:10C32000DFB40CCFA31BF769F3A17CCA0B7F1F837B
+:10C3300072B4E359AE0FB5ABAD8FE3794587FCE13D
+:10C340003215E0DC8E4CD59FB1FB94119343A36270
+:10C35000C1E5EFE437B95078680AB74FFFFDE12136
+:10C36000F9B9BC73871D12AEFB8BC37F44B9B0D73C
+:10C370004E7469ACF774C332D257CEB7EEE1CA7FC0
+:10C38000173AB8D0754B910B59F7D47F737CFF5A8D
+:10C39000F6D2FCA2F9A0279DEFB983F2DBDC3E9A2E
+:10C3A000EF05D2FB82FF69787F16F0EE39FFBAAB5A
+:10C3B000FFCDD7DD3BDE5F9D2BF0AEE3797FF085CF
+:10C3C000BFD3FCBEAE9CDBF4DF94EE0DBDFE159B2F
+:10C3D000F7CD0CA83F9DD5B850B1B8B27CFFAB19D2
+:10C3E00050FACAC0038938DFC951E73746FAA6C2F6
+:10C3F000EDA6C9928DEC419628097B90DB51038410
+:10C40000FE30604901E9210306DECFF506C5BB0E0B
+:10C41000CF1F5F193CDF47B1146CEC3B01CCEB97AD
+:10C420008BBCD59EFCB9C4FC78343A60F0F70FA2FF
+:10C430005E3B70A04C7A2FA4A4EFBEE899CEBF97C4
+:10C440006916BBE74AAFD50ECA4DB2DA4B53457FEA
+:10C45000D3189FFF3497140E031C260FFA6912FAA3
+:10C4600047270F579904F95C165881F6C55497B5BC
+:10C47000BF063CC319F7CDE168570D380E599787B1
+:10C48000701C24939FF4BC70C47913DC32C2182F43
+:10C49000C3141F87639F721FF99D85BD4D474D9043
+:10C4A000575CAB5A909F15B497391CC8CE36ECE553
+:10C4B000DEE0CD84FDAD88210DF82B0365BFD3DA16
+:10C4C0001FD9DF065EBE2E3E0C3C7E53BCBC1B85D6
+:10C4D0009781AE450AF2EB74B417FA62FD0C9E1F09
+:10C4E0001852E8DC4DD80B57781729A4F70CCC501C
+:10C4F000105F858EA6ABF01CC4E193681E17B7D9F8
+:10C50000687F70644904F791B50AE5DFB0E9E3108C
+:10C51000DF332F7BEEF49D0CFDE67E8DC73DE5F10C
+:10C52000F38FBF7DF9E5448C1714782C84FFAF4658
+:10C530003FFF7A168903382D545828A10FFABD25DC
+:10C54000F6BEC5EF6DCDE3DF7753BAFB395FFDDE95
+:10C55000E4CABF3A7D0EE4D8FB00F35D980EA3E178
+:10C5600015B35DFD9D660EAFE021161EC2E32AE401
+:10C570003CD339E11D82FE9FFBD3B39968D74EEAC5
+:10C580001895C0E5EB30B21782C25E38CBBC093ECD
+:10C5900017CAD7A10974FE795076C78A2BDC2AEC1A
+:10C5A000ED5F627C09A41D75AC4646FB8D75921F3C
+:10C5B0003754E7609B63C4B7E4AB869F4AE00DFE47
+:10C5C000E46C3C8FE1E32F84A60966BCB5CD38A9A5
+:10C5D0008CE98907FC7BDF741EF54DE18BF63DC2CB
+:10C5E00077ABB335372F86FCB85DC06FE6FE2FC83A
+:10C5F000FF7969F3061BD2EFA57536CBF96AA92A34
+:10C60000ECB1B16C2CCE6BE67EA73B0BF17250F611
+:10C61000613C67B0F98C1688712E180D4FEC1FFD28
+:10C62000E95B559DF86BB7DA301FE1BAFB2307438E
+:10C630003B7A9756531A6B9E03EC7C9E0B59C3EDC5
+:10C6400063D2FFFDE03BA9C315998CF6671D137EED
+:10C650008F68FA6344C767B7B030EEAF68AFA25CCB
+:10C66000385BCF687F0790DC8F7637F0FBF7CC7EA6
+:10C670009C8B9BB6FF12F5828A6649C723860AA562
+:10C6800055433F6DB02951C67D38C36BC4BBEAA387
+:10C69000AF37F1C5565521F81E98B0FB661CF7E37D
+:10C6A000368DA19EE27FB1D383FBF8C7CD99C40735
+:10C6B000BDADEB5755ECAAA948372A9787D1F4307E
+:10C6C000AA3ECE92BF4C0EF447FE9A696F5DE28B94
+:10C6D00081BFEF6B923817BC40F916FEFF4CBEBD10
+:10C6E00069C8B7809C67E2A3BE5A0FF9961A4BBE81
+:10C6F0002D96BCA908F7C57B86A6225E17BFAA2681
+:10C70000C7926FDBAAF839E733224EB9A311E4DBF5
+:10C71000B74DF2AD11E45B8C7890BF5FA87C0BFF46
+:10C72000D7F0DF36946F31D6AB6B56F936A6F908E1
+:10C73000C9B7318D364B3CAF5D3B9F7C9392AF4781
+:10C74000FDF8A0EA8B8F413FDB843EFE8C884BC412
+:10C750007150CEE56A3A8D7FA172EEE20B9573FFC0
+:10C76000457036E4DCE21D8CE29C7BD22197738B12
+:10C7700077819C93901EB99C5BBC8771BF5C947C55
+:10C780001BD943BE31AA5F11E1ED834DE90FDF02F2
+:10C79000FD8DF5AB3E07D41FDB2DEFC699E55DAEF1
+:10C7A000A610DC7AC8BB831726EF76087907726C6F
+:10C7B00008CAD768FAF0355BE3C1778F3F5EFF2B7D
+:10C7C000E497DFCA74DEF8868D9F0FBD36FE7816BB
+:10C7D000D2D763623E8B84DC6BAF0A51FF535EE4B9
+:10C7E000EB2B77F138F18A46AE1F56D44B612FFC04
+:10C7F0003377C2171ACEBF788FC452213FCBCEEB0E
+:10C80000B3278DF3323623C3440F0B724AC9CFBF0F
+:10C8100040610EF4E397BA724FA2FE5B9AC3FDFE2D
+:10C82000A5E27BF1ABADABD0FF5DFC8844E7A5464C
+:10C830007CAB11E7DB236EA27919F977A3E32766B6
+:10C840008AB8A999BF94C21B62C47F946EB1E67F77
+:10C8500022F86F96DC4AF062AFCB31E3388C7A5D18
+:10C86000703A28E05427D37EDA0527809B37BD270E
+:10C870009C00D3333252BAE152FC5B586F56EFEB57
+:10C8800035E016BD6EC37F5D2AFAE90D0E069C7B6E
+:10C89000AC5FC01DEC029293D1F058A775F9B53387
+:10C8A000314E09E886E44CE8D70017182F6FD27094
+:10C8B000CB7D974705FD64D64C9A82E10CB330AE30
+:10C8C0001CCA0B6A17BDDC0FE031EE1DEF58DC4EC1
+:10C8D0002F9B600FE039EC566727C941830EDB358B
+:10C8E000AE071C14F0DDDDBF7232D9F94D928E7A9D
+:10C8F0004830E224B80601AE78FF28A870FC068113
+:10C900001E91FF0E3CF21987E31EC98BFE9D5C63EE
+:10C91000BF42BC40FDCC668E97605822BC64B14ECD
+:10C920003A7FA9A8957C11845FD306829F219FE15D
+:10C93000CF65C693897E9558F44B954CFB65A9A8A5
+:10C9400037D35EF307A4E7994FAA6C03811BFEFB64
+:10C950002A7A3E4F1C50349EDA04BCB6213C5D0856
+:10C96000B74EAE7745BEA0FB504679500959E03925
+:10C97000E5D1735F09AF7106BC908E51BE35E7CB30
+:10C98000982F689258DFF49EEBC5F35033BF17EF32
+:10C9900039C2FB7F4CF2B118EBBE60BAEE859E8BBC
+:10C9A000806EF1BCA437BA8E86533BD2F3B7BAE996
+:10C9B000F93567E7A14CA4E73D12F74334275ACE77
+:10C9C000353D761EF7B5D509740FEBEE7C55F56D48
+:10C9D000F4C690CB82EED17E30DF37BB041782F1F4
+:10C9E000A25B1C14EF47F318C2F553B37CDEE66478
+:10C9F000C9D767F5DEBFDB2EC58C2737F423233F6D
+:10CA00001AC7C3F8F926186F64F778D1FB83E12FB2
+:10CA100038DFBAFADBBFD9BA8C71BE6E3C5490B520
+:10CA2000105E8DB8A82352E0472AEA73D3254BFC49
+:10CA300015CC5CC8AD6FDC7FAA96DC7BFF2C4DA7C4
+:10CA4000FB74B7EBC6779DE8334F67E27C6FE2DBA0
+:10CA5000B8EF7FECE7E7985936F6D644DC3F26ABD3
+:10CA60000CE9EAE3432AF9A13F9ECAE36EAFF9ED70
+:10CA700001055D3ED7F0983876CD3889ECAC37B0FB
+:10CA8000EBF1A8873B987F04C12F13EFED65D4D558
+:10CA90004CF1025F8FDD12AEC6D437A533E935C441
+:10CAA000DB249921DE5AFC7DA7B8207FFB872C036D
+:10CAB0005DA0A01F50FBB1075932D69BE04F263333
+:10CAC000667CE3276F5E07F3187F48F679A1DEAC3A
+:10CAD000032E17037D7AE47A1B0B98E0358185AB32
+:10CAE000D1DF34FEA8FF3A9C7711E83B784FA4A829
+:10CAF0007943B507F3EB256A1F0C05723DB09E6DB7
+:10CB0000B56772BF857201EA6137C1F5BC5EB04E90
+:10CB1000F261887241F35A8A2F2AA893E842E1B65B
+:10CB2000B0C41CBCDFB003FADDB61EDA67E1FE0557
+:10CB3000EDB1DFBA336F5E877207E649EDEBF9B905
+:10CB40007C01B4F322BFD42DA2FE8AD74B0CEFB3E5
+:10CB500014D5F37DA9E890EAC3F2C67D8FD07E3B61
+:10CB600003C6EB978EFB50642ADD0BCA9474BA2F70
+:10CB7000191A4CF8EB601C7F6CFA20F20B52BCAB1C
+:10CB800097C0A098E363FE641F42F2B3C0B74CEBBA
+:10CB90000BFDBC96939C6E23BA3A43E7ED4701DE4A
+:10CBA0000180F71B225EE540CE075AAB695FFCC2ED
+:10CBB0003E949F9B344DA2388E852C8FE238668E32
+:10CBC000E7FAE6EB973BC3E8E77B5DED1C88DF0FF8
+:10CBD0005C6EA7EFEDDBB81C6E1FD44AFEF6E3EBEC
+:10CBE0005586F758AAD7CB242F8ED7AB743F567EE5
+:10CBF0008CC731146EE3FAC781F5BCDFE3A8B7E157
+:10CC0000B9079643BE70AB11E7C0E5B4617F16E883
+:10CC10003CFEC290BBE562DD3DF6A175CB3424D964
+:10CC200068795B2EE471098B90BD1C2D77CBF11CCC
+:10CC3000DD837C191D27E6EAB663900E225F105D46
+:10CC4000571C5219DA31D2076DB91497B647A2733F
+:10CC50008BF1CD921FE31A8ADEB18749FF0EE7CF31
+:10CC6000FB11EE2FEFDA19862C1F433C809CCAB1D2
+:10CC700077FEE9A7F0FDE41B0E8C0802BAC927B8BD
+:10CC80001B71BE599B793C4FD61BEB52F03E2F9B3C
+:10CC9000DA97E44061ADCC0226397152F25F771326
+:10CCA000DF1F74D4770C7C66693505B8BF7ECBC1B5
+:10CCB000F755EF66156364D8EF843D04F6811FF5E0
+:10CCC0009BE25D6B5334131D14EF599B22C3F75540
+:10CCD000221EA61AF7576857ACF1718AF74AFA066E
+:10CCE000D338463F46BFDA2EDE6EE81E9EF6D67F6C
+:10CCF00031CE8FD6F9A986F222BA9F1EE3F7D24F22
+:10CD0000CEEFCFAD93605E39AFCB14AC9EF3C18C48
+:10CD1000A1E6731D2335FCCAD96FDA98DF04BF9CE6
+:10CD20003FC531BF09DF8DE380EF017F5737496190
+:10CD3000A784F9235A7916E575E4F30AE17FAE98E2
+:10CD4000CACFEB1A33DE58817C3F234B227A60A195
+:10CD500080D63789F4352FFAFD0BB378FB42688F04
+:10CD6000FCD8F808E74F90135E942315EBD7E652F2
+:10CD7000FD3AC98BFD376EC8277DA4284766545EEF
+:10CD80007784F4A3A2A62349C8C7C0B7EB501FA855
+:10CD90009868D7518E1BFC68F0F7EBE23E2B73E8E6
+:10CDA000A3F17EC6FF46E68BC1D7F2212ED783F5CD
+:10CDB0009C1F83399C5F5FDFA6E20A2F84BF899F97
+:10CDC0008F6FE1FC2A3F76432EDE872FDCCCEFC34A
+:10CDD0001F583F45437DFA7858A2FDA6277F73BDB3
+:10CDE000359ABFAB25BEEF7D5DFDD2E06F838FE14D
+:10CDF000EF6A1CAF0CF814EF4F46F3F54CB5E10F9A
+:10CE0000B7C37CAF791AD603F39DF2DD3B3DAD2667
+:10CE10003909F914CC17283C9ECB902BE50A8FFBDF
+:10CE2000FBDAF38B1A3F6CB7FA477E674FE4F1EBFE
+:10CE3000752AD1FDF9F8B3079F5D207F5E285F9DBD
+:10CE40008F3F8DF1E53DD67E7E27E82DBABF7680F7
+:10CE50006B04E0FA4AFD268AF3FDE8A92333113F6B
+:10CE6000A5BB81CE91BEEADD2C82724E09D37E55E0
+:10CE7000D228D33D01A644B2AF739BF998C76D95F4
+:10CE80003EE3267A2A79D61E9E01ED4B767E3086C9
+:10CE9000E2689677525C5AE829A12F875AC7201F6B
+:10CEA00094283C7E2C5A2E041CDC0FD7B62B7E36E1
+:10CEB000AE4FDAC2DF8F2869B851B59BCE256E74AC
+:10CEC000A8463D3AD70D011DE3FD5D9C9FF9DD02AB
+:10CED000236EAC6D2B9713254D2AD981255BB6B7F0
+:10CEE00063FC70C93B76F27705B79CA1FB10539E9B
+:10CEF000D946FE9460936C397FEB11B7B9458ED853
+:10CF000031EEB0B19CCE1D217F84F20DB1E397CFFD
+:10CF1000175F58FACC9E9D210061E9AF9EF4A07C7A
+:10CF200039D5B2D98370877EBF326EBA479C66C34B
+:10CF30003D5F19A7790AFF018C738F43D835469C52
+:10CF4000EB96BEA447C2FCB2F3629C7374E9E5DBC6
+:10CF50003E7D1CEF11B43D7BFA719C6FD93F3E7E44
+:10CF60001CE3C1D85E27ED77C1A7DEA2386CA3DD34
+:10CF700026B1DFB56F7D92E2D7DBDFB5FBB0B7F648
+:10CF80003DC707633C60FBF62F52D06FB964CF34C6
+:10CF9000F2EB2ED9312595C5D82F8C14E9367C01BA
+:10CFA000F1F3D1F83AD07880E2D63E027CA3FCEBD4
+:10CFB0008ABB6D28E771CC5E116F5B1FFB9E428FB1
+:10CFC000F8DAC6EBAEB91CE57E23D71FCF1B67FB93
+:10CFD00026E0F1DB1780BF7AC32F101B7F1FE13FD4
+:10CFE000004FFBA2F0F769E3C25F3C8A658D7D7B51
+:10CFF0008DB38D5C00DC8C7B100F38FC871CC988DE
+:10D00000E75F525C33E26D8617F79F4F07E3FD91B0
+:10D01000136AE75CBA5FB8C7AE63BC68C99EB789DC
+:10D020007FDA77BC417E6826EE23B4B3AE3F1E3F65
+:10D030002E8975D6B9797CAE803FC6EF7A3DF45D16
+:10D04000C4E9723A36E2777B8BDB959D5CCF36EE96
+:10D050006794D7FD51C4C376E34BCA413C1DF9CA5E
+:10D060007868030EBA90C3DD71E8B1E3A3BBEE2B81
+:10D07000087C21FE701FEA8A3387FCC0B1E4377A4E
+:10D080009BC59007ED1B78FC7ABB1AFB5EB011972D
+:10D09000FE8F683E0D5F583CFAF9E6FF75E1D381DB
+:10D0A000CA4F724F38B5FD2DB61C4F774ADFEC9E44
+:10D0B0006199147D6FCAEB1C87713B4734B483BB05
+:10D0C000EC6CB1DE36E1576F7B4AA678E5550D076B
+:10D0D000488E47CB8B0A7C2F25C67C33C57C2B9A88
+:10D0E000F83ED1F6AC3BEC827EDAF6EF227AAEA8BF
+:10D0F0003F42F1D22F6FF995D66A8A8BC07D226CA0
+:10D100009A7FDBD3FBC690DC16EFB2448F33498C99
+:10D11000136C8E3D4EB0FE8C659CD25083A6BBCE68
+:10D120003FDE29C57F23F677AA85EB83A71AE4E9BA
+:10D13000E118E30F73AAD677A160BFA4F767DCFC00
+:10D14000BD19D91347FAE51277CE3B0949986A14FD
+:10D15000AF55BD4CC477FD872F0DF15DEDBE8AE163
+:10D160007C57227C4D7E1E550F30D44BD5B4BC2C41
+:10D17000F42B44CB1B2DC9C6C226FC2F714F4FF593
+:10D18000D279476420E2F370C67115FBFD4B949F82
+:10D19000EA2F0A5B950AF3FB4B48F22D837ED9DF19
+:10D1A0003E1894E7EED97F971EF163D9E257AAB0F3
+:10D1B000771E46BB84BDE0A4F80679AF93DEF9087C
+:10D1C0003EEEA4F51ED8F1F913A45FFFC2CEF8B964
+:10D1D0000F582F20AF0A75DEC7F11D9F3FFE57D4B1
+:10D1E0009FB1318C5FF838D447BBA13E9EEC9C8E3A
+:10D1F0006713C6A05FA4F085BB66A23C2B8CE7F446
+:10D2000058F84C6AB81AFA3B96CCF3C7B60DA27719
+:10D21000254A9F7553DCE8811DCF55E0BED4FE4CF6
+:10D220003CC37DA9FD05A1E7FF52BC5355AB7ACDA8
+:10D23000F1E3C54CF19AEFF39462DE12AFC4C82F4C
+:10D24000417C84FEAAA604BA0704FAAFA59F8FD436
+:10D25000CE3B7C44C7A1FEFCFE53A43FCA83E87AC0
+:10D2600046F9BDCE21E25E39B47375D70F6A9D05CC
+:10D270003C5FD39FCB9316AAFFB053F88F4579CF6D
+:10D280007E79FD8784FCEEEE87B7AF10EFD044D3F4
+:10D29000EF46D16FE996BF5F1CEB9D9518F3A7EFA2
+:10D2A0003F9458C8867ACA7627BD7F85EF28E07DEF
+:10D2B000859D1A3FD72AF344E89D9BDD421E97C502
+:10D2C00045E8DD9DFE621E581FF3CCD1FA34BD9FA8
+:10D2D000F69C93615C59F90B6E3FE2BB7CE7E7C7B4
+:10D2E0007E9E857189F114175FFEC2FF223A28B72E
+:10D2F00047E6223F746EB7B38DC8E7DB5F1D8CFC39
+:10D30000DAA64606F7F98AF3BAF206BBF5FEBF586D
+:10D31000C7A9AADACBF0BEBB71AFB6A41739F357D1
+:10D3200027D7A35F71FA5F7212BF5BDF733A55357F
+:10D330003B13DF5930EA973862CBC577515E7C13D7
+:10D3400039EEEA713FF55D9CCF47AC2505FD3E15F2
+:10D35000A077A33C2FD9923E10FD04FB9DC63B0451
+:10D36000DE04DC8FF6AB5EB2A73135EF3327AA7C43
+:10D3700099CA30F4DF8CCC54601D1D1BCE14F467A9
+:10D380001847EA9C1D4BEE9D76C6D33A4A1CF69888
+:10D39000F79DCF09BA7A0F8DFE643E1EF28731EEFB
+:10D3A0007E354C72F88E382FD52B01BB08BF976E97
+:10D3B000999369797F45A9A17AC0A704CF62B64E37
+:10D3C000CB32C96F63BCE2A559994A267E57FE4FFE
+:10D3D00017BDCADD7866A124D20B150163B6AE9FD6
+:10D3E000E57E88A2E639107E1ACBD3151949A586A9
+:10D3F000F83D8E3550EA02758BBF5356C9504E9E8C
+:10D4000010E7F6E8EFC2B41B5E7792DC0F0D626C9A
+:10D41000783ABE07E14DD04DF053F1101EE6635748
+:10D420002A1997173374B493A550807D09F4545D7D
+:10D43000353D13E911FEFC180749A607CCCFA3BF61
+:10D44000FC05EA4140A7FC3DBFEFB270358018C330
+:10D4500081C9AF3A99F177E856BFC3CCF6C6A5713A
+:10D460009278E7681FC93117EBFEEB843C8A55942C
+:10D47000B7D509FFC8C1734497CE22A817C6BB58B9
+:10D48000241E52D728E59499FF3D599037D1A93EE3
+:10D49000D15A1ECD1720D7A2C66D20F841BF9F4498
+:10D4A000F5FB4954BF9F7C55BF069C828E8D3E7C08
+:10D4B000A76265559E801B1FCF21E006F01989EFFA
+:10D4C000E8315B9C4F9C87135CE3C46CEC581FF005
+:10D4D0005A1E974E78B92F616F27C641B3A45A865A
+:10D4E00076EF0A89EFD3F097E732B563BA83F8F0A5
+:10D4F0001E314EB980F30AC33FD5A3BE93F4AF1ECD
+:10D50000F59DBDD58F8B5DDFDDDB7CE263CF27B181
+:10D5100097FE6BE263F6FF75E552C50B6FBF86E7BA
+:10D52000B65DF24907D05BF5CCF238D433138FFDEA
+:10D53000A395BE703DD331D08AEF38A46FA0B7B8A1
+:10D5400061D6EFD174D21B7DE58B7540DED50FE03F
+:10D550007093187F6A1D3FF7BE6509F7D38179E89C
+:10D56000C7FA378BFA37390AC9DF70C4C6DFBFBACA
+:10D57000A596EB91B7FC58A6F3E91EEF51E13F8069
+:10D58000DF6E5D2A8523E9B1DED76275783F6E9E36
+:10D59000183FFABDAA00F3E6AE9663BD57C5E9D2BF
+:10D5A000B85717FD4EC5029627DE21B37E3FEBD458
+:10D5B000BBE467CDA8EE7D2CB416E81EF54FA07B2A
+:10D5C0003C97C7EB621417E2D1785C48CB203A4F06
+:10D5D00033E4DFD991DE04DCAF997F30FFAEF3EFA7
+:10D5E0008BAFF4A69AEF1D2AE7E22CEFF554ABBE01
+:10D5F00034946FEA39D05FC154D6CE0D615E533991
+:10D60000E8ADC4FC18BE49722A4D09A35C54F43C31
+:10D6100056887AAF78EFC3A8AF255DD5A567BE0E53
+:10D62000FF6F8E4B26BE5CBCD64BF7B63F8BCFDB75
+:10D6300089F4247B727C01574F7A08EDE0EBAEC68B
+:10D6400075A7F75C4FB5E6F391BE7D158080FC6F42
+:10D650003E07CE4FB67BDFF6E2FC7EA332F4BBF48E
+:10D66000848FEF4418CACF8607507C889C306304AF
+:10D670008EBF46BC6FBABA6A24A52BAA984879BC5B
+:10D68000DC8A2AAF487344EA17E974AA776F551AFF
+:10D69000E55755F92835E0EBF0D5D0FB938E617C4A
+:10D6A0007C872EF0976413F00B90FEE548ABA473D3
+:10D6B00045A75E19C177DFD840D87770597A0DC178
+:10D6C00057D319F935A13EE5ED988754AD9D41F842
+:10D6D00052F44A5608E56FC5078E225C9DDE4B2D3D
+:10D6E000EF5ADAD3C646BD7F1A056F83DEB671B82E
+:10D6F000DF2F717A8B86FBFD6A8B17E322EEBFB2B8
+:10D70000EB5D29823B98431CEEBFE6E7B43DE1DECA
+:10D71000327BBE09EEEEECE904F7FB049CEF1670D9
+:10D72000AD1678A816F0AC46B8537EA4C8FB443AB0
+:10D730009DD27BC4FBB72B111F90CA087780877DD1
+:10D740005488C9301EBA79F1CFEE1274ABDBC81F12
+:10D750002ABBF2FC08777B1287BBC3057820BA0688
+:10D76000B87BB13C44F0545D1CCE509FE341E415BE
+:10D77000847B267EE7F800B8F78D1F87F27082055C
+:10D78000CE5AD2E40B83FB237C7F4B127C1E0DBF51
+:10D79000248DBFAF6BF0776FFA71B588B7AE16EF17
+:10D7A00027221C51AF7908E0C3340E4FFE7DA4C878
+:10D7B000FB284D16F67F35E001CB1F16FA10C21973
+:10D7C000D31FC573FB3CC956B94F4538F5E1EFF29D
+:10D7D000B0A4101B98CD78682FFEA5859817F3C6C6
+:10D7E000F9AFD74A3FB2AE44BD03E97D18E96DDD1C
+:10D7F000ABAA0DCF3FE4A55759EE67CBB3FD895EC9
+:10D80000827F4042BDE63EC1876B915E687EDC1E32
+:10D810005E29E8E06EF1FEEE3D827EEE17FCFCA094
+:10D8200041373E7E3F64CD741EC798946113EF204C
+:10D830004698394E30D1D7C0349817D9365E4AE968
+:10D840009D4BF68E9DF8367E14F3237D25BE7367BF
+:10D8500098BF439BD70FF5A144E3DDD989DEC439D6
+:10D8600074313DA288F720656E4FB6C47CDFB5DA0F
+:10D87000B7DF817E99DEE613EFF3A7AF84F1E26BA9
+:10D88000DD6447F50DE4CD590879572DD8550CCBFB
+:10D89000B97C70C1BC0B4DF411DF8B5F47755D59CE
+:10D8A00080F44AF638A43FA91DEA44F802ACBDE86A
+:10D8B000BF7A48CDEB87FBC14389B1FD70B3E2B9B4
+:10D8C000BFC49375A9C59FB04EF5533B7DA255DEED
+:10D8D000AC13FB439FA956FE30F683CB447F9FC514
+:10D8E000077E140F7496726E2AC9CFA46B63EF0F74
+:10D8F000D5AA16C2F739AA4773BE0EE56B5C6FEE68
+:10D900002177189D839C0D8CD888FE2F83BE96337B
+:10D910002EE7428CEB93C6BA7E86F43E02F7019D59
+:10D92000E81EF701CCCBC334A29B945B6CE47F5818
+:10D9300025F8EC5EC15F6B045F3D807C3502DF81C2
+:10D94000F651FA13C14FEB90FF20DD129FCEF57810
+:10D95000F1BE9761C72C778CA5F71CAB5D36DA0F4B
+:10D960009477ED6117DA05FBC6EBE8F791DD597A9C
+:10D97000C08DE5590E3FC0434ACCD2915E3E732F15
+:10D98000B8E8ABE25B01FDF4AEB0A2727FA49E9456
+:10D99000C7DE1F45A753F49E80AA5FCBD03FFD7022
+:10D9A00052A513E1FC703C8FD3AACDCF26B8033E1D
+:10D9B000B6C59BE2A552675FD5F51E1F76FF702F97
+:10D9C000EF12EC12F2820D0CB16126F9502BDE7BC6
+:10D9D00064DE101B699213CB87E732F4EBF5940FEA
+:10D9E000BDC8CBCD5C5EAE9062CB4B437F37E46568
+:10D9F000B45C31D295174DB7DCA7545D3E46F26654
+:10DA0000646CFFC1EFE3EDFC1D6AE6F3E5A7F72CBC
+:10DA10000778FDDE0C2FD4830C7FC5F762AC275A44
+:10DA20003E9EB8CAD85703F43ED002CDFBF0F8AF03
+:10DA3000DC57ADFB41E1B9D5A40F149CCBA1B4A830
+:10DA4000763AF111C3D318939D7C7CFD0F3D88DF9E
+:10DA5000E3B5E27C7CBD1AC6B8A47D1BEF7A600EEC
+:10DA6000C075C1E3329D8FE33D0DD914DFC2B2BC56
+:10DA7000A4A71BEF231E0FDFEE31C73114FCD4E93E
+:10DA800047FDBF377A2C581FDB7F538DFF44BB8384
+:10DA9000F946A25D01FA5D6704F5BF9F38E9DD181C
+:10DAA000231FDA18EF33C78F18E95BF1D3CE21DCDF
+:10DAB000DF8AF73317D29DAB0F9DD7F4CE177CDCEE
+:10DAC00063E833C773D247459C35C07D96C57FCA8E
+:10DAD000CF498F097F1873F4521E27CABDBD947BAE
+:10DAE000783C13D36397FFD37EA4513DECB421B8A7
+:10DAF000FEF2DAD3ABDEA52FD6F3806211C7BD608C
+:10DB0000637C78790CBE5920EE072F10E75D067D07
+:10DB1000157FDFD0B3395D46D3ADF4D42544A71FBC
+:10DB20001F54C95F5B01F4877A98F4D4787A8F69BF
+:10DB3000D913973D780BC0F993433295979D731095
+:10DB40005DB6FF878FE2FC3B7FABD2EF267C727025
+:10DB50001AC5EBB78BF79EBBF8CEC5EDDA1B5C5C44
+:10DB6000AE149CBB97E8BB8BAEC2F335E4DB82738B
+:10DB70000F905E5680EFBD4EC0758F78799222E887
+:10DB80007702B61F92BB1CEA15B6723E61134315AD
+:10DB9000E48FDE10EFBB37063FDFE0F25AE2450BC1
+:10DBA0005BD750FF0CF4C324535CC802F1FB07851C
+:10DBB00078B884E57A88A521DF08F9D64DFFD677B5
+:10DBC000B0DB9DD6751AE9C2AE754EB0D861DDEBFB
+:10DBD000FC2EE773A16F14B6E6F07975ADE7E7E3C5
+:10DBE00063ADA77B1D13A97D7B62ECF1EF17E31FEB
+:10DBF000AB2AC29B5BAC44BCB75B10BE5DC3F7D520
+:10DC00000AD627F6914CEB2AAC2DB5C42B15D4E6D9
+:10DC1000D3FB7A85EBF3B5DB4CFB53175E42FE97E3
+:10DC2000270DEBC6CBFD6B2E23BCA8AEBC3B917E73
+:10DC30008F3D557CC77B5EEC97E3E984161A534908
+:10DC4000F2EA764FACFB4DF747E3A956E009EC80CA
+:10DC50002C139E0CFC44B73FB6B9FC8EF7F01CE2C7
+:10DC600011FE9A50EFF22B0A7FE9B1E1F7A4A0D799
+:10DC700063A00F042E087EDFB2C4CBF50A3F816F8C
+:10DC8000033EC677D0E7C208B727913793B13F4E1E
+:10DC90000FE7835BF7F8821E26C55ECF6B5DEB59FD
+:10DCA000CA42A0C79CD4B83ED1FB7AEE6221C70518
+:10DCB000ACA78B4FF32D7CFADA9A5B389F0AFC9F56
+:10DCC000DC7F0FD1F5B170BC0FE3547A5BCF6B48AA
+:10DCD00007E362D0C1B0101B95FD7F8F0E4E68FE2A
+:10DCE000118FE03E02FB15EED3C54FDE3FC63CBFB1
+:10DCF000B7E227FD9EF6A59A0B3BA70E4DF61DF445
+:10DD0000D27E27FBAA6149435D813F63FB12CFA30B
+:10DD10009FA19F6E45E2CFC6C4D28B5756052EC732
+:10DD2000F38BEAAAA2CBD18FAA0A3D97A19E9BCEE4
+:10DD30007F1723D67B7DCCCDF1BBB2AA92CE3F9884
+:10DD400023C4F494EE7700D8894CF2472B2EAB7E97
+:10DD5000A6A9011DFDDF9A78A7405502ABD3B3D029
+:10DD60005F94941132C1EF1F2E7EEEB2266DBF8EEE
+:10DD7000E71A76E81FFD608E81CA598BFFEC456576
+:10DD8000415FC093F11C731C6BF04B12F913CF462B
+:10DD9000F913CF5AE69104F3FE0A3B5B7178E81C55
+:10DDA0005261C28F2CE0015F681FBB5BE7EB5C1E1A
+:10DDB000EF217D60D54536B2EBD609FFF4CFD02FE9
+:10DDC0004D7051E8BC01C3E0B0BE96C0D7E1C4734A
+:10DDD0000C19EDAD08E5DDF862974C4F1F4A984FDE
+:10DDE000645E09F37D596415DA0F1D935AEF203FE5
+:10DDF000A03390E606BC7ED6AFE5B084E712798109
+:10DE00008B11CEB57228C30BF57F21776660BDC13B
+:10DE100050F44E1F9E5E84F71202A6F3CE21B48EFC
+:10DE2000EEBCDC337FD15225EAFCEF6F179BCB5F52
+:10DE300071FA2FC679543BF9FB60491F4874BE57ED
+:10DE4000DD75EE9447FBF26437C723D105D2D54187
+:10DE5000AE379D55BC097DC89F3D32F345CB3C7C18
+:10DE600096BC22ECD13AA0533CA732E86398E2B7C3
+:10DE7000211D0DAF81EF663CC6D077FBB8E879F085
+:10DE800098FAB9313F1897E8553E97CBF7E3287ACF
+:10DE9000D82DF1F9878AEDDC6E642119F13AC7209B
+:10DEA0003C6505CF2732E38FECB5778D7327B682BB
+:10DEB000E7759E0BDEC6CFB9A3E733A7F9EE163C94
+:10DEC000EF99D3DC6F3E9E7BCE29BAF8434C77ABFB
+:10DED0009DFBE3515EFC50227DF6A6B75E54E32124
+:10DEE000DDF1E6467A9F60AE9BEFBF7359A78AF8D3
+:10DEF0000F305DE3E756615ADF6DCC27F20D2AFA49
+:10DF00001D6E89846FB81A72B7BE18BE1AD5BDB916
+:10DF1000073B5F42B4051AF45C3A1B32DA35F95E0E
+:10DF2000E679DEAE0B0E4EF1FB478A83D6D5BD6E89
+:10DF300007C1C15827D4247C74C149BCCF66C0A591
+:10DF40006BDDF1375F85FEF8DEE4DC1CC7E80F7996
+:10DF50009C3C9F57349C3EC12290930BDDFE1FB921
+:10DF6000A1FC7AB7FF2E4CCB1C9D839521C437555D
+:10DF700098AF900317A5001C3E1A14B83819E1D1C8
+:10DF8000D2F782F4FEC34E2E0F0EA71B7A6DAB1B89
+:10DF9000E99BBDC8F55AE3F73256ED387EFF8D0098
+:10DFA0009F8F5EE5EFCD95CBDE6BEE22FFB2CC62AC
+:10DFB000D921467A58F80D1E76DBC47BD17C9DF3BF
+:10DFC000140EEF798DF174CF6EDE52D9F2BEFDBC26
+:10DFD000A53C7E95292D63AEB7D8092B045DF7ECDF
+:10DFE00007FD1AD1FDCC5F3A99DE2DD9A9E993C876
+:10DFF000CFF138A7B3F953FD32C6FD4F582D911F0D
+:10E0000069FC516F532BE4E787137DC8AEF3EF5CD7
+:10E010009C89EF9754B4703F67AABC28E33F207DEA
+:10E02000683FDFEF31BF08E1E4F27B5DA6F39A368B
+:10E03000B53243477ABED5E54779907FBDFF5DC4D1
+:10E04000A7E1E730F6DDE7400FC038CEFC5BBC3916
+:10E05000481FF90D4E3FA50EA6C4815CCB5798030F
+:10E06000D3548D294E4CE39803D3ECE5427FAA9D0F
+:10E0700045FA8327274FC3F7C4F39B9FFC14DB1794
+:10E080002A917D92899EF29B5FFD82EEC3F9F3286F
+:10E090004EF75B5B348BDD39BAC19AFF7693359FBF
+:10E0A00011B1E6330F5AF303706D267D73FF1E1E08
+:10E0B0009F527A9ADFEF7D1E60A0223CB6D9493E7E
+:10E0C0004E296DCEC67887D34FBB6D58BEFBEFDCB3
+:10E0D000EEEEDCEAA47725F7BD17C7E292F01D6AE1
+:10E0E000E7462C3F1DD7908DFE45A84F714BB0BB26
+:10E0F0008E40BB71E7A506BD8629BE69E73FF8FDE6
+:10E1000094CEADF630C6519CDEF5E4D3489FA7B758
+:10E110000E207DEC792964C37E43F770FC4F88F3B1
+:10E1200058E454E916AB3D7E42E8011D27B579E875
+:10E1300017BAB8D6BAEE4BC2D67CA7A87F1B337DE0
+:10E140004FC7F810EFAA34DC6737C57EBFFD73C137
+:10E15000174F3DA519742B8BF71E9937A5FBBEE20F
+:10E16000EEEE73DB2503808E4A111643BABF974645
+:10E170008DDB850FD17F92382FEBFCAD4CF03955FC
+:10E18000556489EFE8D2FBAA7C69534DFB5141ED00
+:10E19000BE947CD257F7A5DC66DA67CAB61E48B9CA
+:10E1A00019FA6BDBA2D0EFEB95CD79E2810949F842
+:10E1B0005D6EC0F96239FAE7DA1A5EF2603DD08B23
+:10E1C000C79AE3BD0A6BC7A54D35F1E9D7A54B83C7
+:10E1D0009FCA740E9FE7725A72F11E46692DFF1D89
+:10E1E000BED2861BAEBB1AE1BE9EDF4FCF56589EF5
+:10E1F0000CFC53B6FD86EF8F86EFC1C7C6F9703EA3
+:10E20000D9F8242DDEBBAD3F43F776EEB571FF4460
+:10E21000345C467B387EEFFD81AB08E512F4F7A253
+:10E220006D2CB53F68037DE4C4E4D06B374395D3D0
+:10E23000ACE10F57535C96959E803E25D4B73A3794
+:10E240004BBE8DF47579F6B5A85AFB97513C3A94BC
+:10E25000C7B4378AC3D67EA2F17CA547327EF76861
+:10E26000A4995EA2EBF59D11A2DFB72A5B0A72CDDD
+:10E27000A4EF971DADA178D8E871C819688A3BC191
+:10E28000FDD14B7CEC147A02931CD9225E7C28CF02
+:10E29000D3BBA748974010A597B2A95E84EBB56C95
+:10E2A0003AA6CF4B91076499CB03F2336D8B277954
+:10E2B000D0A6B73EF173A4A3FAD1741ED65FDCEFEB
+:10E2C0006EF346E8BD58E37771DA749E2F69765293
+:10E2D0003CD5E98F349297CB308E13EB3FEDB4D918
+:10E2E000405F3BBDBDEF648C0B6E6BE0EF8A9F6AB5
+:10E2F000E83B59FB8AFD379AEF8D7DF108FE13DF6D
+:10E300004FF5F88B3DB8DFACE071D3A97D2B332AF4
+:10E3100063E0C96897A45566A0BDD279ABCBB7912D
+:10E32000EB53E90AF9DDD3C8AF922FFC49F7E9793D
+:10E330007778A0BE1BEAFAE1FF3E07E58DE877FC9F
+:10E3400040F6DDA10FED3E1F5F9015A0FBE3F40347
+:10E350003630FE7C854514A0B7F9B8AF8CA13CC916
+:10E36000CFF9EB258A235CB0C6BA1E7CE7DABC1F66
+:10E3700016E12F290EC5B8B0064A8BD65BCB8B7140
+:10E38000FFF050BC17C5CB94D459CB198B901FAD5F
+:10E39000ACFE4B7B2CB87DCA8CF5F96B3C16B9A34F
+:10E3A00092DCF950CEA3F595A23700D29BC4FE1C97
+:10E3B000BC33276D01A41D4B27A42DC8C47BEE7C64
+:10E3C0001F23D38EF898BF8F573A954506F1777182
+:10E3D00018EE8FA5CD526434E61D2CE419CBBFE3B3
+:10E3E000FB20B86EF33D3163DDB85EF377F626C7E8
+:10E3F000AB71CF10D76B2E2F137028ABB75BFC3AE5
+:10E4000013EAA590FBDB787FA995DA55347E69B7CE
+:10E41000F42BF65FD8B79913F035A168838C8B790C
+:10E42000A84B8E872F89750FE5B080DF433714F432
+:10E43000437E7D10F5CFFE02C039249F849F804526
+:10E440001C305E5C66579ECAB397F3FC3E4FE08A71
+:10E45000DA8160AFA9013A879A2FE7BD8CF71B4795
+:10E4600026065E42BCCCB7F9072BC4B7FE11E417F1
+:10E470005DCAE1F0F0D8CA4B2A63D9C502BF3F9309
+:10E480001AE85C3EB48BEFA3EEAC4ED5ECF7FE8BF6
+:10E49000904709FB5BE95E4FE70E89EE133F221DB3
+:10E4A000A1FBB68F5CE96568C7A7019E50EE3E22CE
+:10E4B000B115F85E5E56E3AC452F219EB3E27C7841
+:10E4C000DE5FDE38492E77D1FAB9BE155FB901CFCC
+:10E4D0008352E78D1C8B740EEB9E772D7CFFD0E36F
+:10E4E000A5F1FAB938DED39687D2178FC2F1F316A9
+:10E4F000BD847C383A8EEEA1A702ACDC7D285D8D10
+:10E500007A541ACBD887FA60DA0CEF58F4B93FE4A2
+:10E51000E1E324DBE479B350CF1BCBF37D7E2CF910
+:10E52000371211AEA57152ED6C3ACE17BFA35EE85B
+:10E53000403F82CB84EF299519387EEA509E2669A8
+:10E54000118A0F3C64E0BD99C7E92DD119C9E925AD
+:10E550005F4C4A453BEE501B18D420BF0E0D34ECE7
+:10E56000CC888BF4F06123797D61F72DC9E0F75FEA
+:10E5700092061BFA0FAFD7A1FA133251AEBEC1F506
+:10E58000F14F5C7EF2575FA6C58EBF4F48E0780A18
+:10E590009E8B636193FF3838FB33D21383E73C2CA7
+:10E5A0006CDA27F0BD4D731C7759D17EFA1D847249
+:10E5B000D642F701CA1BAC71E797C5C51ED7A0F3B9
+:10E5C000E0391B0BF525321E88F6D721A973D5C279
+:10E5D00024BA174BE73BC1731A0B99C60F9EEB6326
+:10E5E000CD77CD3385FAE9AEC7ACF59A3EA77A2C44
+:10E5F000A7D583E3B4EBADB48F04CF29D4CED86FC5
+:10E600003AC2B6900AFCDCEEE5E51DE23CCFA86F0D
+:10E61000F4D73E5B13F7DEF8BBE86D552078002E8B
+:10E620008F369F217F7459F33E828B410FDDF08935
+:10E630006721137C52AA5B2236E0ED690F6EB87B2E
+:10E6400014D890C9FB051F8736DDED9F08E5F8BBA0
+:10E650000F26BE8ECFEAE27312330FD9642E174213
+:10E6600075774F9D68CA8BFA5DED439BAF980A346E
+:10E6700095358AB7BFE6C1275E594E4E8B1A11DF1A
+:10E68000DF3938CF6DCA3BA2F22EC88F36E5F5A828
+:10E69000F2A4A8F2B4A8FC405EBFCD1D192CFB402B
+:10E6A000DE3FF8D415F8FB9E6DFD2273F1058F3522
+:10E6B000F2B62BF0F77CCBB3F8EFD356344B3EC910
+:10E6C000243F2BBACEF35BB5F9A3100E2D2FA31C5C
+:10E6D000286B9274D4EB5D0DDB2394C7765E53BB3D
+:10E6E000066E3F96351CA176BDF63FD2467C7CEF88
+:10E6F000C8F7A9DEF9CE9FD80CEBEF5BF5761E7557
+:10E70000440A2C4E48EE7E7FBD6DFBDBDDBF2F0A39
+:10E71000DFDBFBF90F901C8DBA071EC4F9B8BAF9FC
+:10E72000C480E3BD23CFD27BB47F1CDDFC16AA03DB
+:10E73000F14BCE2C53A0DD9FCB8F8F437D0BDFB4ED
+:10E74000C57DE36752F812DC8F1E65814B70DC5B80
+:10E75000CB87EFC39F4C38ACB63E86EF956F78F011
+:10E76000E52B1498DF6177EB20FC09B74D096FF0BA
+:10E770007C722B7F5145FF1DE1E7F0A0D64136C8E2
+:10E780003F99C0A6537E78EB63987F3DE104AF3F8D
+:10E79000BA7590ACA30972F28AA990DFACC7E6F70C
+:10E7A000DA04AE371BF39B36DCFF53840B2BE3FB01
+:10E7B0000D5E3376803C9D5B726ADB6680C7DC1F32
+:10E7C000C5939CDBDC76DD55790487501EC611A607
+:10E7D0000A78D37E48725D217DA21FEE817DBAF159
+:10E7E000E91EDCE2A5FDE2D2CAEDA837A4CE1D45A4
+:10E7F000FB45A1C72FE9C9DD69381952A82FE93AAD
+:10E8000097EBB28DE22352EF72931EF5A0F83D0311
+:10E81000E03BA20F97C0CB36B19E6D09DCBFF680FE
+:10E82000671AF5F39EE47FC42163CA424EF2A7C57E
+:10E8300091BE72F306902B20D7D78979AF5B7B0905
+:10E84000F9296E463FF128FCEEEFD76754B7FEBFBB
+:10E850002E03F2AE6EBB6EDD2C7F3FF3B9F6BA0D20
+:10E86000BCDC905BEBD2797B63BF4AADE6E3A43EB0
+:10E8700078C9465C47BCC2287E7BE1EC111B97D16E
+:10E88000FE7F2DAD9FF9FDFDD00E3F5A3CC4867A28
+:10E89000A9819FC2E1FE5712603D3789DFEF35F055
+:10E8A000648C4FB7E2517F90417F403B353140EB64
+:10E8B000077D620C0F6EE0FA04D21633C19729ADC2
+:10E8C000E3F0FBFF2038B5FD2BE0F44F9F7747C9FD
+:10E8D0002190370CFB2F5F7ADC72FFED3F01D123D3
+:10E8E0002A700080000000001F8B0800000000005C
+:10E8F00000FFC57D0B7854D5B5F03E73CEBC929920
+:10E9000064264C9249C8E38440081071124344F0D5
+:10E9100031848851693B50D4D87A71203C022699C1
+:10E92000A8D5624BFF0C12790918342250C181021C
+:10E93000C55BF506458C1A70448A7AAFF68EADB782
+:10E94000576C7FFF08888F4A32A2F5D297FDD75ABD
+:10E950007BEF64CE24A9B4B6BDF93EDCEEB3CFD9CB
+:10E960007BEDB5D76BAFB5F61EA6F54C0A5CC0D8EB
+:10E9700066256ACEAE642C7C48F1ED61F007CF6766
+:10E980003B19FBF7B4A0D595C9D89FF1EF0AC6E6AD
+:10E990007EBF29275806ED8D2318CB612CF5BBCF00
+:10E9A000D4DE00D5B94B3F7A7C0F7C3FF77BA98C36
+:10E9B000E903EF438F8CC1F7EFBC6D5BCF2E84D2A0
+:10E9C000D2193579A0BC86F956C07BEF98584327F9
+:10E9D000F4F70EBE7A096355DFBBE5353691B1DB3E
+:10E9E0005D2A6393185BABF873988A250BDBE0BB59
+:10E9F000F02C4B644F11637D1153D80CFD75B82377
+:10EA00005B17C1B81DD795F9C2D05F1F637E86EF33
+:10EA10002D4BA5F73ADC3D4CC3F64B741740C20EA4
+:10EA20007EA1FA19D4E3375A22BB14785ECEC2769F
+:10EA30006C5F323E1286FAF3300E7D7F634A640FBC
+:10EA4000B6CF828FA0DE71A3371286FEEC2C624710
+:10EA5000783A76FA73321C8CE5AAAC05E1EF28828D
+:10EA60003A94592BD9CD0107E2CF3F719673000F2D
+:10EA70005F7799683EA9953D4FFF37F4C7D6DB7D98
+:10EA800063A0B0E1AB586FCF2678993B5885F86604
+:10EA90001AFC03B8EA1FC889ACC3E7CC5785EBB1B1
+:10EAA000DAE99F47F0FF205547F81FB6B335B60A9D
+:10EAB0002815D666CB00FC0B7858FB43000C633757
+:10EAC000E3008097FFD770D6A9C3F32B5D0AAD078B
+:10EAD000FCF96D558CCD67BC7DFEF2D477958958D5
+:10EAE000AA516B1A3C5B73A5BFC746EFB13F8FE2DB
+:10EAF000A50DFA0B32F1B725EE44BA09E27769D8D1
+:10EB0000FFEF9DBA03EBF0FD445C76F8BE74E0FBCA
+:10EB10003A17A3F9CF5539FCAC355547FC4AFCC828
+:10EB2000B24EC2D7FE903F713C394E72BFF7BAFC6D
+:10EB30003722BE00EFD1740FE245A5754D86D7632D
+:10EB4000896FB043FBDC56D57D37E033B8CC49F351
+:10EB500095F0DE9C1DBF8C150FEEFF746A739586D1
+:10EB6000F35FC6E99D2DB702E212F16219A8035DB9
+:10EB70002C64F163266588E75AF445847F5147C2C7
+:10EB8000F7F4DF2FAC89EF497E61BA9204BFA02B66
+:10EB90005DD170DD820A5F378B253E375036186EA7
+:10EBA00089CFD582EE245D24E37B35E27BD2607C85
+:10EBB0007B2C3DF9D86F709995F094DC3F6311FA86
+:10EBC000EE213BF00FD0DD1645217ADD72576A64E5
+:10EBD00025F2A73DBE17F1193A7C15AD77EF9214D7
+:10EBE0009DC12BDB2C30419433879D9C8F4B7A4AFF
+:10EBF000909F7A61CE7E589FDED7D59D614502C138
+:10EC000058F3EBEA2EA4FFDE67AFE6FDAC48D5195A
+:10EC1000D4438861183714FE432B03BC9E34C52CA3
+:10EC2000345E17E057C209FF7AE15F43C580BCE854
+:10EC3000C3061CBF8BCB0798E1121AE7DB296C1DBA
+:10EC40008CDB6C52FC26686F5E3A3EB292C3614325
+:10EC50003E6A1420359B589B5231C0F7CDA6132530
+:10EC6000B795F1360DDEBB85F17581F78E2A005F11
+:10EC7000A36D7D4C45BA45FA87F6A5D85E3480FF72
+:10EC8000E6F5BFF913C2DF7CC048178D8F19E7B1D5
+:10EC900034919E8A06E824B592E389D5B0C81880DD
+:10ECA000D729EAA9B5B1888A785A56CD4E02E966C5
+:10ECB0001EE99981F4E3ACEC64F3A10C7DC0FC1176
+:10ECC000807B4AF7CE9746C2FBEEDA583E4E37B409
+:10ECD000ECB68B4E5D34B0BE12CE4BBA37A9CC41E8
+:10ECE000E3D177008A7FBF83DE1B37FB82C4F26EDD
+:10ECF000FA2ED3A412BDF6E023E41BCD9FA3C038A7
+:10ED00009B978C32E17AA6827C43B9BCB07DECAE95
+:10ED10001584677F09CAB707D380CE099FBE2A949E
+:10ED20002FA5EEEA5FBBA0BFA7DCD5FF8D258E1314
+:10ED300070E2F44790BE48A6E764BD23DFCB2E6E99
+:10ED4000296F710CFF1EF017E12DBE359DCB0F4DC5
+:10ED5000A1FAA2FF30EF5C47F0694437B76D2F226C
+:10ED600079DCC0DA89DE1A59C482F4BBC8C6C2692C
+:10ED700040178BE0B57428176FB1323D61FD9644A2
+:10ED80008CF546210F6E6131FAFE967D49ED352CEA
+:10ED9000EA84F6261B8BA662D9696C6F667141EF17
+:10EDA0007FB6263E671D7CBE378B7577D744D4204F
+:10EDB000CC7BAB1D745706BED04EEB3365F94E5A73
+:10EDC000CFF40A7FD13DA84F5E35FB7601DDBE272B
+:10EDD000D64BE2E75E57F5BB88F714D544F38FDFD7
+:10EDE0006325FC9C02BD8DEB7F9F9BDD3C1BCADE37
+:10EDF00056DD3B7A34A2C95530DB3918CFEB9EB3D0
+:10EE00003720DDB8DD26C2B77C7ECC65A67AD5DD9D
+:10EE100002FF2B5223BB8A08DD13919EAA46497D2F
+:10EE2000CA26CE82FABB6656D709F5E6EB1D41EC41
+:10EE3000AF07ED07A817B8B9DE28705B687EB22E61
+:10EE4000E72BE906C6A1FE522EE2A584638C5BC8BF
+:10EE500041B6897F27F4EFE625293B49FFF6D3AF7A
+:10EE60008911FD96052C88D7E7845C794ECA9536C2
+:10EE70002B972B9A6BEE32A83FF741996F1DE095C7
+:10EE80009582DE83EF1B3F4AD1919E5EF9E85FEFEA
+:10EE9000FD19B49FFDC0A25BA17D01D218ACDB734C
+:10EEA0000A9747607F30D48F8DC0F6386EE3C1B1CA
+:10EEB000647F1CB408FB46C8CFC6B4E0D685D04FEB
+:10EEC000E393993EA064F6BC39F2E85E6C3F64F7C8
+:10EED000ED817E1B53385E1B9F1B49DF3F610F4E48
+:10EEE00077C33C73AD919F3C8172E3052BD97B675F
+:10EEF000597411C27FB6D3AEE07B27705EE95042F1
+:10EF00009B82F3EA76923D047C9AB310BE3BB936FD
+:10EF10009BCF4BE0E9E48609C4179BCD7CBCF0B3E2
+:10EF20000ABD7FC21C989103F5134F97FB564053BF
+:10EF30005FC012B5003D87EEE3765EBD49DF8178A4
+:10EF4000628753095EB91EA18D8B67627B68E9F207
+:10EF5000AFA37C1C8ECF51DEB304B9D9CBE205C878
+:10EF60004FDB1A467546519F748FF3915A655E5870
+:10EF70007CA01B177FF79499E3357EC84CF47CBEC8
+:10EF8000FDE37CB52AAE7F709C10C86526F98FE43E
+:10EF900072425D1DAACEC8FE0C3D972DEC3A63FB74
+:10EFA000EBCEE01D6EA0BFE6FBFFE79D6584DF387A
+:10EFB000C945D69E497C79CAEC9F8B74EBAE895AC1
+:10EFC000E627E8F30D82AFEAADC2FE63514B221F84
+:10EFD000CAF6AA6A23DDCB72BDA07F678CCBF7C1CE
+:10EFE000ED26C11FDFB4A21E9BC2416685A8471C47
+:10EFF000D8BF4EFD4FF9206AA9877AE1F2A8659142
+:10F0000028914F00DF511BCCFBD45627E76F4003FC
+:10F01000F6B36832237DB94805FBB5029FEB5D3D31
+:10F02000B02EA79F7673FAFA236005F03D8F89F71B
+:10F03000AC60EF821C7BA64D89E27E60DE16EB2E73
+:10F040007B11F2B55F75E27A6E57488ECD6B9B5699
+:10F05000B215EA4B0F5C40EB9F3699D3E5D2889B03
+:10F06000F4E214211FEBAD110BD9DF3F5118F2016F
+:10F07000F44F7674237C945331180F28D70DF41075
+:10F0800049A8835D34A593CB5506F29C25D84B52F5
+:10F09000DEA31C6749F69F913EC2521F71B9C7F4A7
+:10F0A0006C947B522EDFEB0A74B949AE8DCEC6F557
+:10F0B00085F5E47273BF42786D622DA44FA41EE8FB
+:10F0C0001F57E891D36A98EB2BEB262A5F7717D16D
+:10F0D000784B5927E913A95786A383D7BF840E7E9F
+:10F0E000867400ED8D1FB0E865305EE372166D9A90
+:10F0F000C84BE744D28F5C4FDAB89EC432E53CF48B
+:10F1000065B27E4CD687C97A30DBC2F59D5C6769F3
+:10F11000CF644FE776C094E51195C1FC36A6F93F60
+:10F12000CE9C3460D784DEB2D9F40BB11E60A3E06C
+:10F13000BDC569D36ECA86F690C6FCC857A980972C
+:10F140009DF07CBBB07B6BB339DD7B2D9C7ECD5AB3
+:10F1500080953B705D62B4CF8D673217D2A3C4E750
+:10F1600076277C5781DF71FDD4FFBD8DB5A5247C4A
+:10F170005FFD9C9DE4EAE7CF3A2356B24782856E55
+:10F18000E82FEB5756B2537B9F73923EED15FAD0A2
+:10F1900083F628D1CB2AAE5F715D272135558F6468
+:10F1A00048FBCA352351044AFBACC9CDEDACC1F6CE
+:10F1B00090682F8A5DCFE9CA4AFBCCCFDD3D7762EC
+:10F1C0001DE061689FFF8F58E7D081E9E5DF87E7A1
+:10F1D000A180C3C7B11F2C477AB5AADFB9DE06F4F8
+:10F1E00035435D1EBF0BE6D194EF70A19EAB29FCA9
+:10F1F000F52F6F84FA8707CCCC8AEBBC677A1D1B8E
+:10F2000035BCFC5D12319FE849E0975BF619EB4D88
+:10F210009DC67AA8CB582FC8707A4E4F20D9E1FBF3
+:10F2200033D0B5D5DAF2C14E80D7FABC95F4D1A768
+:10F23000EE607106CA5B53FC18E2D95AF8F144F447
+:10F240006F84BA3F51B0B402EDC4CA38FE91AF3FEB
+:10F25000B7CF2B740D81B701FC319B89F00CD63AE6
+:10F260002F49CE85049F782CFE0F5F84F92F9A9D3D
+:10F27000E2BA9B9EF8674EAA427B926064A12D572A
+:10F280007F88FB2D786F09AEFFE959F01EC0D5B01D
+:10F2900085EBC346164B43BE6D06BBD3064B7C477E
+:10F2A000065F875BDAE25551F8DF8E8CDA7108A7CA
+:10F2B000F6272D80F4B11AFB4DB093AFCDE07AE084
+:10F2C000967D76D729031EDD867AA82BC7752A91ED
+:10F2D000FF84FC61798A96B81F7A57095E8BF86BB8
+:10F2E000B2F558A6C1F857FCE93392F78B97CDA732
+:10F2F0007DC4805D6D25F9B4F8AE203D7F692BDFBC
+:10F30000179EDE6AD711EFA7B7F3FDE3E23C47C4CF
+:10F3100006FF7B859BDBDB8BE13B45198CC764BC1F
+:10F32000BDFFF0555EA4A3F7191F2FDCC9ED8FF7C1
+:10F330005D80AF62FE0EF6F77E17D8EF0AE2F9AAFB
+:10F340000F512E2EDEAEFAD04E60879CE48F59BC52
+:10F35000FDCA710B1DD8DFA723A6A15F68C795E87A
+:10F3600089C2F70211EED7895D01CFB51D17931D34
+:10F370007774BB95C3E9B6EDC5795CF12795F84A7A
+:10F3800033B120DAC71D16FF38E467FDE13D337065
+:10F390005DDE9F956BA2F71F57980BF1E15E968596
+:10F3A000CF172B5A00F9B761CB929989F64E6A862E
+:10F3B0004AEB35AD7079568F83F8E97AD4A34DDBEB
+:10F3C000817F70FCD96FFFF2464F223FDD5EC54C56
+:10F3D00009F6CBC35F237AC2BF28E06BB1C0D75711
+:10F3E000E52B6BAAE48B961294A38BEF6E29710D1B
+:10F3F0006157F4F3C5C39C0FEFCB50B8FF202FC368
+:10F40000B0CF186E5FE62835915EB1F9987F0F9402
+:10F41000D9B02DC6FDF7810C8DDA0F64707B5FFBD0
+:10F42000DD6DFB5E87794DCD086ECF807A21F39735
+:10F43000E3BAEB71573598B18862B2BBD8C3566E48
+:10F44000C76ADC8EDE9CC9F6AE4BD88F77627F9997
+:10F450002417F6623FBDC7FF780CF1DA5CF0F14487
+:10F46000B40F42E73EB3A01FCDD1AD903C77F80278
+:10F470000CE925D43D8B2D281B90C3211FD713C920
+:10F48000F3FA5306DFEF843C71EAE7FD119C7F3B02
+:10F49000DC9C3EB72D4B213FE4364FC48E40FFB578
+:10F4A0007C2AEDA525C2EF67DBFD945F45FA8E2827
+:10F4B000AE3158D7397FF435CC8DA830CE87BB8B91
+:10F4C000C9DFD977609A4F8536C7EE1FAD198578A9
+:10F4D000EA32FBF07D87AF270DE7F7E1EE9369385D
+:10F4E000BF86DD2ACDBB21F249D6C2B201B9F033C5
+:10F4F00025F83ACA01E6521C38BE940F1FEEFE34BE
+:10F500006B8183FB0B487F560E8D97A7DCD37E8ED5
+:10F51000DF5F71395F978F1EB74650EE7D6407FD40
+:10F5200096206F3F72727D772A43EEEF3A0B50DFE1
+:10F53000F4D76F2A35A19CF88E8BCFDF63E92C407E
+:10F540007EFC8D62EC67E91A138B806C5FB206500B
+:10F5500003F2E8A3479F294079FFE19E670AE62767
+:10F56000C097FC9D2C7BE578C26F26FDA81E4B340E
+:10F570000FC79BEFB3727FE5307E54F93EDBC2FDCF
+:10F58000A17D3EAB8E7428BFEB6B48F1A37DDBC73A
+:10F590006C24FFE6770BBFACDF3FDA83FB18F97D05
+:10F5A00052FF151E4E4F4A9742FE83D4B238C9E32C
+:10F5B000BF59DE7B603D13E43DACF3BF215F34D91E
+:10F5C000E2C74632A20F0BE2CDD2ECD0503F65AD80
+:10F5D000E4F415BFC344FB2A4BAED781F2EC8A9208
+:10F5E00094361330A227256D22C601F2734BE9FD34
+:10F5F0007035A7FB7016237F5B0E6B51485EBBB85E
+:10F60000DF3E6F3273AD83EAAC11DC9EF132DF1660
+:10F61000B598D65D41FF90C487D40B483F281F3F63
+:10F62000526C443F4AB74276A76AEA9C8BFD0E476C
+:10F630004F1347C8FD3FA7A7FEFA3F899E268F18A4
+:10F640008E9E823AD193D736343D093FF179BFCFB0
+:10F65000C201DCBF660B7CDD27E44EFC0E9BF49BF5
+:10F660002B38DF99A2BF9936475445FDE1337F9C83
+:10F67000E8FF7D18EC5FDC27E5A0FD0EE5C895F3FB
+:10F68000745A3716EB417F41EAC536D28FF79A623A
+:10F690004568AF648F6FD98F74913DB7AC6225ED2B
+:10F6A000FFF2DCA80F50B7921F745975E0D488049C
+:10F6B0007BE110DFCF34DFE5A7E7D3BBB97D101ABC
+:10F6C0006D217B38D4A584719D9B039608DA416B2C
+:10F6D00015EE5F096FB0EB3CEEA3AFA0B8CF0F748F
+:10F6E0001E178A48FF6FCF8EEF23BD3538C8EF91C4
+:10F6F0001C3F3AF885CAC71FC368FC8E721EAFEA6A
+:10F70000B85AE7FE15B17E1DB3FC396EB407D618A2
+:10F71000F959C685FA9C8018186FFE7A3BAD43AE46
+:10F72000CAF1CCD26D5CFF0C960BE467CE9A2C1616
+:10F7300046C46FFAF91C2405D67345BB8C3739CB08
+:10F7400002456879BFBBE9B7AFA400BD66A19F8E33
+:10F750006FCAC268F7937F98D7C97DFCA00900C91A
+:10F76000C5D6FF5C577369425DBC3FF0FDDC6B6B37
+:10F77000F248EFF6B723D8A08F65DD6FD7311E357D
+:10F78000D0AE81BD6BEB52F8F761C7B5578E063C22
+:10F790002872FCFF5CEB477FA19D19C64B844F4B41
+:10F7A000EADF0CFD3B74F97EBCF64A78E1C10A59E8
+:10F7B000BF66AD1FE0BBCF6CEC8F502ABEC78A1C62
+:10F7C000EFD6AC6DEBD6E70DD8056027EC1A913972
+:10F7D000601FAC7E7B66FB853056AAEB530BEA5D5F
+:10F7E000A9E7431E85EC8F647E3D20E4C3DF2C57E0
+:10F7F000F54176F4811124577B66204BC2FE83E4E9
+:10F8000076687980A13D07F64817C2DB7BFCE3D31D
+:10F810002F427BEFECDF1F1BA9E37BB7CE45BB3745
+:10F82000744E23BA0DED53230AD0AD4DF00BE871A1
+:10F830008A0B487A5AEA1274EA0E338C73741C529B
+:10F84000268589BE5A0AAE83B5CCF7F85F4238E404
+:10F85000BE3279DEBF1EC1F70FA1D2EAAD25D8FFB7
+:10F860006E85A19DB0AEF444D602DA37BD9BB530AB
+:10F87000E1BB255D0F123E97EC330F89C75F8FE028
+:10F8800071DEE6679FF6A3DCF828A2904C68D022D0
+:10F890006BA740BDA1C1849620AB8CCCBB91E21C70
+:10F8A00075163606E67704ED268463DF37C353709A
+:10F8B000DEF04F8147DB028B489F6EABB339284E99
+:10F8C000543AFF56C2832BC58F7858575A9D83E30D
+:10F8D00034CF9AE1A2F808D871D8DE7CD7B7C82F08
+:10F8E00024E15AD765AE453BA70AECB9A700EEFC68
+:10F8F0008C6B6A7DC0C723D5FDE5B73B305E3EB457
+:10F900001CFF6E26A78B362510FE4625F94159A20D
+:10F910005FB3B08BDB8D9F8DB018E22B9F8DE0F62F
+:10F92000ECA5E1D874249FC35A4F2ADAD321E6FF0D
+:10F9300004F7CF2CE0D0F7D03A7179E469D5C93F0C
+:10F9400066F3F4DC7B21B65FAAD1FE85693D0FE04A
+:10F95000B8BD6B3DBE754CF001D6EF2AA37D4FBDFF
+:10F9600027A87832F9BC707D7B9FBDAA1CFD88D288
+:10F97000EE5AFBA89DF4E65AA77E7F2DCAD3DF6915
+:10F980003C1FC0168F4D877E96FE3E83C65D6B8FF3
+:10F99000ACC5F50FEF54A9BDD8117460BF4BBEB90B
+:10F9A0006522D22B73444A508F9A3DED0CE918B66C
+:10F9B0002BE42FB179020CE3C4D3C3F33405F5452E
+:10F9C000923D331DFD55B45FF190BFB65AF0C71894
+:10F9D000A082D3366285B63F8F18B06F5EF9E31C04
+:10F9E0000D1F4ABBC764E3FEF39ABA1486F62D5B7B
+:10F9F000153F66427FBD27C6D00E6EEA54689CA6AE
+:10FA0000D2272DB86FB9A593F37748EC33007F0563
+:10FA100068578CF1A40A7BA08DFB3958ECD848C4F8
+:10FA2000F3637C3D1983F712FCAB8CADE0F240F43C
+:10FA30006711718626E157024D48ED3E8FB45BEFAA
+:10FA400016FDB7F3528CBB5989F955C46BB962F0F6
+:10FA500087CBF22AF17DFA91F80CE4DF38D017FA5F
+:10FA600097B62AB36EFD29CC6FEBA4F13E34C1BC2E
+:10FA7000404E6A053E075204BC57767D3203E98644
+:10FA8000D532E2D7E6AE696A9383C76FD05EC84EBF
+:10FA90006DD989EDD93797927EC6F8C86C78FE3556
+:10FAA0000FE7B31C07F7D779EF0E1761BC33FD489A
+:10FAB000E0D69FE2F817A490BF351BD6C69941E562
+:10FAC0001AF46F7959F98BA87FBD33F50A8447C6BC
+:10FAD000F5302E38AB8CE438D5337C8A7F179437D9
+:10FAE00078DC340EECEF6A115E7C1E710CC419D107
+:10FAF0006F87E3621C0FCBDE9CA8467E7ED0E77B3F
+:10FB0000904EBBAC2EC4D7CCAE97DF427D3BD3C664
+:10FB10003A29EE9A64B7C4D3BE19443AED3B737ADE
+:10FB2000C73D08D775077D94CF92648F5C7139B754
+:10FB3000CB3FDA93AA233FEC12721BEC471E7F796E
+:10FB40009CEF2393EDC8EFF6AF2FB723FBEB7F7746
+:10FB50003B92C317DEC3F328A47C0F897D5F5FC38C
+:10FB6000D934D45F2B3DD2AE4DCAF7D82DF23DBA71
+:10FB700087CEF7D076F2F80F864149EEBA2D22AE45
+:10FB8000E5F7CE43FF87BB84E4C02B7B53C34837E4
+:10FB9000673BED6497696E4B14E16A7BDA1AC13CEE
+:10FBA000883645E0EB90885759441C2CA344478382
+:10FBB000E2A02540723FFCA499C7ABD2228FEE850C
+:10FBC0007AE3E11C11CF62D47FF8D954C277638AFB
+:10FBD0009E8EFD37FEFB088671AA3E180FD7F909E5
+:10FBE0007B70BB87E25ABC7FF68255E7F1B3688928
+:10FBF0001BF0B033C2EDBF93A5A6A805E6BD93895F
+:10FC00003C9FF532AEC5E7D9B761248FCBA03182D6
+:10FC1000FBB2B5DC5F542FE35587B91FAE5EC4A5B8
+:10FC20004ECE5EF408A658B4292DB5B84FFB7CDD46
+:10FC300034F29FDF79FF2C2AEBD718FDFD8BD03FE4
+:10FC40005F3C103F967EF7F9CC67E1F6F380FFD07A
+:10FC500004F68CBE46AB46FD59C45C77A33ED0C3C8
+:10FC6000B07A1743D906251AF10A6019DED3D67A7D
+:10FC70005270BD57B799486F85DB4C7E7C4FD2CB15
+:10FC8000AB1EAE67DFF570BD03A88EE038B26C33F3
+:10FC90008B7883E86F053345B13429BC5CEDD26ABB
+:10FCA00087D2DFB2BF36738B6D1ADACDF926F277C1
+:10FCB0007F6EF1D791BF38A384D6A9CDD9B2A696CD
+:10FCC000B7132F7D6E8F07A8FD328D1B964CCF404A
+:10FCD00079FA8287C71792F1B6B0DD584F8EC32CE0
+:10FCE0008918EBF52C3836A798C70D129FBF20F462
+:10FCF000C4E7EB8A04BE7D1694BB72FE2BF238DE9D
+:10FD00004CF9BC1C955F5D8774300AE3CA45587294
+:10FD1000BF2ACC84E01F75994721FA4882B7CDCD20
+:10FD2000E929BC96FB21FF5AF893E1FED09325F810
+:10FD3000D8EFC5B865BDCB4271E8F3F597A4641A56
+:10FD4000F7B7FDF5BFFFFE96EFE7D7AA22BFC6457E
+:10FD50007269BE8BCFE5A4E2DB1BC5E70EB01F7056
+:10FD60001E6BD50A9423D3BFE9A079341F063982CC
+:10FD700071ACE53D05A8D79BAB7B4A305E938C5FA9
+:10FD8000845693F20CDE9BEF81FD08DA0D6B8CF14B
+:10FD9000B8C1F1557F616626EE7B4EEE7F19F5D72F
+:10FDA0007E3BE92FF8BF17ADC8FFCF16915C8B38AB
+:10FDB0008363312E144A89EEF87111DA31DC8E6AD0
+:10FDC000EAB6EE443B717E5B427C0FFFB3DE18EF78
+:10FDD000636B32C8EFCE3A8CCF1B1E4EFA6E50FCCE
+:10FDE000AF9DD665B325380EF91DF410E51D9C595D
+:10FDF0006262B8BEF5AA6F112AA93376A37D7EC6CA
+:10FE0000C9D76B46A6D43F3EB2BFFAEB83D6D957CB
+:10FE100082EB5C6F62C1C47E9A709D617D1BC53AA6
+:10FE20009F79FAE2125CE78FF75F5C82EBBCD9DC6A
+:10FE3000EE47BE297507AF41FC9CBA3240F615E685
+:10FE4000EF201F9D2F3DDE94448F37FDE3E8B12E58
+:10FE5000311F32593F36F4E3CBA81F3D163D0FE565
+:10FE6000C17C9BF52FEA49FC1BD29F67B392FFE34D
+:10FE7000F01F3FDD48F918DD2AD927B2BFC35AB0B9
+:10FE800018EDA3C36F797D6165F8FED385FDE5B5F7
+:10FE9000B130FA59E4BE40DA97C9F278B998CF0385
+:10FEA00099FEDF8CF81BE23CD27FDC20DEB1453EC0
+:10FEB000E576EF6EC5C7FDC79DE44F6E3E34CF8536
+:10FEC000FEE20F22DC7FDCFC7439F98F97445E8AF6
+:10FED000623E19EB565CB81F59B2FBDD34CC03907F
+:10FEE000FB5ED8E7DE9F49F935C6FDEF07919369C0
+:10FEF00098370070BF8F70A77AE216A4FB66D8FF10
+:10FF000061DE60B3163F86FD367B18D905955DC668
+:10FF1000FDA08CEF6E0B5848EE6EEB562228AFB367
+:10FF20002CC1A23CD46B2CCF753A7580CF2299FEA0
+:10FF300017907E07E2EAFE5D5897FEA79EADE94462
+:10FF4000BF3D66E677A13CDBEA14F24C23F9F6DB11
+:10FF500087DD91750976C36F23DC4E5822F3C134D7
+:10FF600016D560BD16CDF11FC7F546791F4D92F726
+:10FF7000897519AFBF8545492F35B19EFEBCB0C408
+:10FF8000F792E3F9180737F4C35ACA75F493DDE41E
+:10FF9000F0519CABEBCF56637B98EF9B811F96553E
+:10FFA0000CD0AF5C0749BFCDC21F1D6A38B10AE94A
+:10FFB00037D4A5B8707FDDE8E3F4DB08FB2FCC9BDA
+:10FFC0004DE677D669CC131D8EFF7FDDCF779CFF82
+:10FFD0007F3DAC9CFAC7F85BDFEF973F9CEFE5FCF9
+:10FFE000A5FFBE7F9EDD0AE7CBA47925EF5B93FDDD
+:10FFF000EE72DF79BEF2F08B247C7CF10FC6C77005
+:020000022000DC
+:10000000F230256BE8FD42725CE3AF9687FFE0F8C3
+:10001000C623871E4A3381A8585214F672BBCE6F8E
+:100020008817CF501D7E1E3755793E4572DC5D9F87
+:1000300021E2EE9C9F5F7A5AA5F56A12F1E1A64390
+:100040004E1FBEDAE0584CF1D9E4F8E952B67F060B
+:100050002E51721CB511F9B8F8CBE3A91765393DDB
+:10006000249F745684790AC9795A2F393E1D114C40
+:1000700058EFEA32D8080C41D7362DCC32129E4FB9
+:10008000CBE2F6F44B229FC86BE1E705EE73A6FACC
+:10009000711FE335F17CA77C4F607AD62494EF0280
+:1000A0009FCFDEC04C809747CC9D244FC24D0E1F82
+:1000B000CA3FE9C791FDEF10718BF3A5F36F671984
+:1000C000E9BCBFFE4FE2FB8592BEFFDAB8DD16C089
+:1000D0008D811F18D1EF6B18672A1A4CB7C3F533FF
+:1000E0001CFD2ECB0ADC9E4578F14FA4FCE6F39470
+:1000F0002FA995F193E82F6207AC3AFA376DE2FC2D
+:100100000B5B9F23F6EBBEAA599497CDCF8FC87394
+:1001100036C3D98F1BFBF99FDB8FFDF5BF93FDC85D
+:10012000DC81769CE7A9697ECAFB5FED04F8715F0C
+:10013000F8A875C8F32CF2DCC597F95DF6F6C3CDC7
+:10014000E96AEFB070FF63E5E793FF34F9F9FB3438
+:10015000F4A30EDF4F58E47BC6FC229EC67625F83A
+:10016000B743319EAFF79280573E7F44E8C5F46CA9
+:10017000FF515CA78F8FDB6C2C1D4C9E4A2E179B6A
+:10018000030E8A2F3477F2BC97E6E58CE47733FAD6
+:100190004FCBD0AF388BA1BD373523F833FC7EF57C
+:1001A000DB8EB09A8E7EF7D90CEDBBDEE3BCFEA9E8
+:1001B0003BF8736C0F2DEFA17846C7EC8F28EFAAA0
+:1001C000EACF9FAEAAAD2478C98FE0B11ACFAD7C3B
+:1001D00091C5E30FB2FC43BF3CF1935FFFE3069E82
+:1001E0009F1DF2F85DE88F907EF1543D467EA6E6B5
+:1001F00003DC68AB52F97CD8F7F3889E9A0F4C2B3E
+:1002000047FF29EBB497A39D5BF52B07EDF73EBEA7
+:100210002B97F224EA3DC10F513E3A2B2357A35DA1
+:100220005A08E3A0BDFBF1FEABCB116E29FF36A34C
+:10023000FF1CC6DFEC34FAC7998DE7D92FDD9B4F41
+:10024000FBCB6247F053EC6FB39DC311DE23CEA30B
+:1002500008BF7932FF4BBECF564D344EF6B76D1402
+:100260002F977261B399056DC503F2E478962EF26B
+:100270004C445E63F72C9EA722EA0E8F31BFF381B8
+:10028000CC2B8F233CC7B3B4AF961FE618942F40F6
+:10029000FD627E18C505589CFC2DA9E7B81D3DCA16
+:1002A00065217A7202DF519C06E809EDF94BE3B152
+:1002B000E9789E6B7447F452C4F3E17326C2933617
+:1002C000EB358AD3A42B7CBCE2F53D6BC7A21FC6DD
+:1002D000F5E665B8A47ABBAB1A513A3523909F4D29
+:1002E000FB8C96521CAFFABFCC3C9FF2502AF917F8
+:1002F0003A0A1A299FB2F76DABE13C4E7219667744
+:1003000053FEE4A8AE5F50BCC0794019322F76721C
+:10031000B683F0D61C8ECDA01C9B4B3D2467B54305
+:10032000BFA238B5B6564309C4DACC7E139E430B40
+:10033000AF60E4EF1CD3E132E17A158AFC98BEC3CA
+:100340007F9818A4FD8A8C0F44787E93B96715EEC8
+:10035000C3B4153D9787713D0EB84DCD65D85FBCD0
+:1003600099FC2D875219D24F6157F1DD53A15EB828
+:10037000C645F1B0BEE76E2924FF2ACC73CC10F33A
+:100380002CCA36F3FE0FA59A509F699B980F47D54C
+:10039000DC59D504F78350877E468A3C55193F4582
+:1003A0003F14EAA9F4ECE0D7303FB6FF1CD2B214F8
+:1003B0007E0E49E3FE12E7B2B71FC7F33D3B2CFCAC
+:1003C0009CE791C3136693DF6FADA6E03A7CEEE63F
+:1003D000F99437669B0CE74206F07F84F256471D7E
+:1003E000FA05D76B3016F6AF9939BD686B3D3BD136
+:1003F000BFB8382D4879BA97B545558A9FB94E3D53
+:1004000050AB27EC73B6703DD3BC8FEFCB93F73571
+:100410005FA65F6ECB36DA2DFDF57F92DDF283FEAF
+:10042000F1FFC6FD0A33EEF392ED97E47DDD203B4C
+:100430003CA9BFE1EC18998F523D300EB7A79DD271
+:100440004E0A1BF275AA1DE27CA1CDD8FFE5235C04
+:10045000345F99BF93B5525F8179FAF11F30F2D7BB
+:10046000C93CA27035CFF7099B6C74EED0CBDA296A
+:100470007F68248B2A0AF9D37AE87C6D36E611C1AD
+:1004800077EBB24751BFDB996F8D4AF25257106E2E
+:100490003BE69F50BE6A64EB221CE73A078D63C7B8
+:1004A000FC938B3085C0BF15E5EBF4061E5FC805D5
+:1004B0007D8CF49B3B9AD3A1BD8EE7A1C83C1399D8
+:1004C0001722F1502DF09B3B765111CAC1B54AF06D
+:1004D0005171AE99CBFF0D4E715E19EC6BCFC079A7
+:1004E000E43EC6FB0F3798F8796437AF778CD1F9C3
+:1004F00079A02FF839BB8E729E7732283F2509AF3D
+:10050000323FE5C9B4E011E497E4F3CB924E12D642
+:100510008FCE476F3BC4EDFAEA060BCDA36FC9350A
+:10052000E497EC5B6262A8FFABBBAD9CEE92C6DBCE
+:1005300056676151EC578BD8517ECAF5FF32BB1616
+:10054000D6B514FDBE475A6B2F3A05383EDA1AA0CD
+:10055000B2CFAE74AA17D2F9D2B928A99ED8F2F9AF
+:10056000B55A0EE6DBC40B142099E7B77E3493EA44
+:1005700099F177B0FEEA16CFD73490C37D63E23BA2
+:100580001478FFFF797FC4DB911673197BF7A1877D
+:1005900066861D5F41DFFD9125E7719C41BDD3C497
+:1005A0007A56C5C85F24F45D2597875E8785EC255C
+:1005B000AFC83F6535221F15233B505F99534E71DD
+:1005C0007B07D30FC4B03D8F9FCF8276A2FF956388
+:1005D000B87FDA26E882E549BF544F18E5DBCA2226
+:1005E000377DDF2F8F0F5823DC3FC6C77FE3E90B32
+:1005F00028BE25F36A1973E5CFB980F26C0CF5FBC0
+:10060000ECE21CA6E6CAC773EC2BCDC2EE15F5369C
+:100610006730C58BF3443E047BEE8D2BBF5B867C3D
+:1006200074E6E0F747A35CBBCA02FB8221E4D8EE84
+:100630001C2EC7FACC8E350A7C57E30C8EF0C2FA1A
+:10064000BF953A77061E29A81B31CD82471758F867
+:100650005115F19A29E8C43D87C3E7AE0928987778
+:10066000BAD2CEC7CD0C6A7E3AF7109CA35C077055
+:10067000AF54B8BC868FD2C98E2AD5D3F11C61A3E2
+:1006800038D7AA0AB97149E72615EDF59FB7BE35E7
+:1006900055D306E0FB858887FFA2C8783EA2DCCB55
+:1006A000ED6259CE56F50B90FE56ADF0BC36F31206
+:1006B0007CCEE9F8CAB4659598A77D556A4B25FAB2
+:1006C00069073D4F87E76509752B7FAFD1162FC0AE
+:1006D00073E60BEDC149888FCFE7BD7B27CA873B07
+:1006E00073DF7807F324DE300B3991AF88F5EE988D
+:1006F0009E06EB79ACD82DF23C6C440FC7C6723F16
+:10070000647F1EDB3885F2FA66CEE1E749AF65B15A
+:10071000B61EF89E9C15D03E637211D9913345DE0A
+:10072000C58CB70269E8179871435C43393A9C5D00
+:100730007495D7ACF724F0C3D5BAB17E6DA9B1FEDC
+:10074000359FB1FE8DC97F1A9B587FD9EE9F8DF4DE
+:10075000F4BCC2F33EC3973017D1BD4709A3FD32A5
+:10076000E1995C710E97E727FEABD8773D3399513D
+:100770007BD63EDB2E3C3720FDD7AA689FE065B6CE
+:10078000C20C7EEF03EABBB822F21C3D14D3610712
+:100790006F75713F2EBC6B817E0ECED3893FAA460A
+:1007A000DA52904EB21C267639F252A58DEC9A237D
+:1007B00082EEE4B9EA2A8D0530CF02869C83E51BE0
+:1007C00066D78BE8A70E7FC818E7DB691AE55B8A56
+:1007D00031185B41F587045D1F91F2FF079A585766
+:1007E000E04018EFECFA5C1E872E65745EFE6C65C7
+:1007F00009D525DD4BFE01AE1E8DA14145F427E94B
+:10080000F9A74E0BD1837ABF49F8BB34130259EADA
+:10081000927080B8C9423DC9C8FE9571BA7C9B6C84
+:10082000D7FCF87E0E93757EDE2B4BD4A1296AAAE5
+:1008300040FDFCF2EF487F3B7C419C8725CD46E79D
+:100840009386E3A35D827F7625F1914BBB9AF8E80E
+:10085000A7CE923B08EE6B9C2ED4AFA53097BA0C76
+:100860002AFD232AF03BCE4F6A8A4F47BEF966ED38
+:10087000F1A95A829C86EF9BF8F7A9C6EFBDF07DDF
+:1008800046C2F769F07DD9E0EF773B6D51D344EC78
+:10089000A74AEF217D18A5C95E23E6AD66F1EFAE4C
+:1008A0001179B1A3D3E07DD45BA5C63C1336D967DB
+:1008B000A3FCE4A4BC92AB94E539C85757DB9ABAC1
+:1008C0007BA0BF97C53A5E650A7EE682E72FCF2DF3
+:1008D000398AFC576B8B6898D7772D8BAEC2C5EDE4
+:1008E0009B167CC45D4CF2E159E4936635383603BF
+:1008F000EA67CCEDA36F2D22FE79CE9B39185E49B5
+:1009000027125EA417A43F492FC970F7AFE7D73B62
+:1009100029116F3BD851584ABB8AB1169E77ADE773
+:100920000FCC0B886886AD6534DA352F2F0993DC40
+:10093000B8CAFD00E565BD9C1BFC4F946775177E2A
+:1009400052A0E1CBDE796371DF00F0C6FE37E1959E
+:10095000F6E3A0BCE30F2D86BCE3E1F84C8E1B420E
+:10096000BB50C5FCE49D94471C9AE3F0E1799110DB
+:10097000E6C15652FC8AECC2E7146E6F87159BB035
+:10098000E3CE373F99717BAFA9DFDE33E4D77794AD
+:1009900073B83B6ED5E5FD35DC5E9CC7B83D394B81
+:1009A000B42F7451BBCCC3EFD8C9FD861D4F8FD572
+:1009B000B15FB003C97E60E9C2CE2C32DE9B837F7B
+:1009C0004AD640DEF86633B75FB7997C5594E76244
+:1009D000E1F7E29C91FE8C317CFC64FF626E8E62DA
+:1009E000884FF7D7FF4EFEC55277303F07FA5B5866
+:1009F000E62F504C0817F733027D3E1C6398FED655
+:100A0000321AEDFEAB59CB9BA662A2CFE21CA4CF5B
+:100A100009409FC506FA1C9D93C9E524C225E9B388
+:100A20009F2E4B93F3CA8217603F1DEECE5F35A316
+:100A3000BDDC6DF5F1BC5A9E27982C0712E059A039
+:100A400071783CAA4AF04CC27193E1391F3E49A427
+:100A5000CF6CC6F961387EC9D658D85931C02F2F0E
+:100A6000DB8335087F3FDFACE2FBA34170AB0EA216
+:100A7000AFEB6FE47194502AD747184FC981F167E3
+:100A800089F1AF5FCBE9F0FA7FB110DD02F8518454
+:100A90007FB6689FD5DD447954B36BCC2712ED0047
+:100AA00019B7A913EFCDF1949B9105E6CC34C64B51
+:100AB000EA6EE2F19AEB588B19E1BD7E8EB19F3A56
+:100AC000B6FE13CC0BABBBC9F83C98D31F67198B90
+:100AD0007196A3C28FD007FC82FCF4D3CCC50FDF84
+:100AE0000AF43BF6876515E877BA326BC9EE4D50CC
+:100AF000FFF1B6F154FF69D6B7BFF306B6EF28A1F0
+:100B00007A0D26B9E13E08F911F54DD58DD714C1FE
+:100B1000B847EDA2DF5BF939026F4AB06316BCE754
+:100B20009D388AF2216B84BCE95BC8DBAFBDD0C9BC
+:100B3000535E6FD6C9DF5893C2EFF579ADFCBF2B7A
+:100B4000303FB76694A8573C3F1EEB47954FE81ED1
+:100B500080DE268786F86FCEE57EDA09A54A741C0A
+:100B6000E0A52643F4DFC4E735B3E2D15CE48F9A15
+:100B70006ADECF04DFB4B5C5F89EE92CD57B736D72
+:100B800069280F259FB5E770FD2CEDA980E0FB6774
+:100B9000FCEFB68D807E0336C587530C4C7E97DF05
+:100BA0005FE5E0E7CB02FE220DFDBCD3FD3C7FB349
+:100BB000DAB62207F7E75F0F5A2A715E2E5BF9510A
+:100BC000B46FD2274F9B44F9BE3666463D0774DFAB
+:100BD000417C78F1270569486C0E23DD4BBA9A25D4
+:100BE000E9BDC648D7C0AFDB7232BF5C5E1BE8DA36
+:100BF0003E40D7C3D9B900D78F09AEA946FDD53F2E
+:100C00004E125F268F3B9CBCC0BF44793A005F27E1
+:100C1000F15F1E66C515237FB64BFEEC42382CA64D
+:100C2000189DB329547CE3E960EA307686842F1F4F
+:100C30007DAE1583E1C23F4DDA7FFCCF83FBF23CF2
+:100C4000D10EDFF959C6005C30FE2B240F577178A6
+:100C5000B62B2D5CBE087B5CEEE79BE57CBB8CF382
+:100C6000AD4AE1E7DEBDE87721DF7BF9F87EB8CF5A
+:100C7000631DE47C42426FCFB1059C1698DB75EE94
+:100C80007AA29F1B58F869B48F963983FF17F174C5
+:100C9000C4143E84FB9C85CC4FF157A08F77721211
+:100CA000EC0D096F329E9A8791A7C9F349C6CFC050
+:100CB000BAC5C8BE93E7D8FAE77B9EF3947689C796
+:100CC00062F4776508FF5486F0472145A17E9EC9EE
+:100CD000527CB82F98EE53C8BE98C96C249767D63B
+:100CE000727D9EE1E0F687D4FBC3F1C7159733927E
+:100CF00057331B993837C7E7954C87D9ACE70E2C8B
+:100D000067DAF4AD0B90EFD14ED107E09FE9E07EBA
+:100D1000ECEC5C213F58CF24D4F3FDF5417ABE675B
+:100D200012CA9FE4FBC9669EE3FED28C738CCA99FB
+:100D3000BE7727A19ECFA8ED998472CCE9F27B7390
+:100D4000270DDC1F988CC7D1B92619873B2FFA4C89
+:100D5000E61F193F6B7306C7E238D2CF714689553B
+:100D6000E14B151E97E83F588474EC76154D43FF10
+:100D7000C51C1BE82318BACB15BC3017E9ED8F0052
+:100D80000F6E0EF155C0E37535C17B343E2CE1E1A9
+:100D90003681872B855E3DFBB04AF1891A7FE94396
+:100DA000184208BD626611E2573FE94579BFD8593C
+:100DB00030A0A2F8FE634EB23316BF5A4FF195B180
+:100DC0005B4C4C4FD093E32229867B3226ECCB3010
+:100DD000D42FE8CC35BC7F61D728437B7974BCA184
+:100DE000FDA2572A0CF549B12986F72F7EABDA50C0
+:100DF000BFA4E71AC3FB533F986DA883C6D070DE2B
+:100E00007B9F55D83698F765F16F19BEFFCDB6199F
+:100E1000AF60BCF3A4D8F7B2B03F560A785820E9C7
+:100E2000F6DC7C637F5125AA5421DFF3BF05EB7903
+:100E3000BEF634C05C62BF0BDB8DF6C4E22DC67A11
+:100E400043F7A655281B07E779B454E35539C97908
+:100E50001E35AE7926A4CF502ED817E31011EC62C0
+:100E6000CC331B8ECFBF6CFD4BD8E82F5B7FFEFED3
+:100E7000160BD9F58B5F7DAA2A0A8FAC5EE3FADBED
+:100E800075E3FAA7961AD7DFE933AE7FFA64E3FA7F
+:100E9000BBFDC6F51F516B5CFFCC8071FDB3EB8CC5
+:100EA000EB9F1334AEFFC806E3FAE7B718D7BB7061
+:100EB00099713D8BC24B0DEDC9EB2FE565F19ADBC6
+:100EC0008CEF017A4D097420E96841A081F277C660
+:100ED000B47FCF304E323DC0BED144F7BFC13E6E6D
+:100EE0009B72FEF401D28AFCBDC9F4F16FB9C2EE67
+:100EF000147401FAA813E50AD8174F61593756D868
+:100F0000FB81A1ED0B29BF12F579E2BE7838B93625
+:100F1000484F897DF2B07A0AF7C9F6817DF270F404
+:100F20007B1CB38FC88E5A4F7EA51B5D1C8E4FF164
+:100F3000D125E8CF7D82F4F271007032C07B1CE7CE
+:100F400003E31F4F9940FE8D6FB328D9EDFF82193F
+:100F50009630D8CD98A8ADE23D4F3A95F5426F2F27
+:100F600014FE8F85F6E05BB9DCEF519885E3E6C5AA
+:100F7000E8BC147B6DC479DD237102E30820784F4F
+:100F8000611C01CA5E3BA79BD352AEF899EE49C0E3
+:100F9000E7FCE94A29D9B56A0AE53DCDBF4121FD03
+:100FA00034FF7F781917FA2CB95CB94CE2B35DD8DD
+:100FB00003DC2E48C7C39A1477624107E1CDE7C22C
+:100FC0007586FEB81FFF47FC7CCDE30AD32667D0A9
+:100FD00031335A675C6F3C0FA5DA389C8F9B990DB3
+:100FE000F1398105C90EBC5703D1C6FB1BCFFB7B72
+:100FF0006314FAD354F5FF7CAD06E3CF382EFA9F85
+:101000001D3E86FE66D5EB63E8BF1AF4FCC014BA39
+:1010100024A3BFCEF87BF88778917EC23C412FBBDA
+:101020009D8CFBBD92FC86235590C098BF63E6E77C
+:10103000C3BDDA16BE9F3CE65B634D9837636637E7
+:101040009EE7FB327B08F36D4F27E4C7C3BA0C79E8
+:101050008FE9B43CAEEF57B6365C8671A25E1107DD
+:10106000BBA7357819AEB7AAF9282F0EEF5772270C
+:101070007C6FF1407B029F6A8E0643DDEC08105EB8
+:1010800056B5B610DD98C53D50ABF36E730513FC35
+:1010900012178E14F6862DCC5C594C98C6F0F7C109
+:1010A0007486F3555DDAE9C47DA8D50BFD25CA2BFE
+:1010B000AD9025FAADD7B4B610DCAB9460103BB35D
+:1010C0008E66513BE0DBAAE1595478BEF52A92675F
+:1010D00016E76D3EBCF76738FC59BDDAE78972C880
+:1010E0003FD22887EE6FB55D8EF85AD9BA8CC69379
+:1010F000786B6F755D8EF58DAD5ED1BE82DA4DB5C4
+:10110000BA82F4711A6821867116ADC789713DB033
+:101110003319C603CD5E5B0499C8EAE1F0B2A305BA
+:10112000441F735D1C06F48DE5037DBCB3CC4CFB02
+:10113000D3DBF31DF4FEEDAF8F79D10F7C60011E80
+:1011400051FF8AF9F48F23F06711728869C100F2A8
+:10115000952557237F74866B36ADE3DFDA9FC4BBDA
+:10116000C5CE281FD492EF20BBEB7CE10C8D14F789
+:101170005009BC27E30FF04472F47681A7DBEFE25D
+:101180007EBEDBEF6094C7CE96C15FD5005D8D1447
+:10119000F2259B05A86C6F05C15282EB6563410B7C
+:1011A000E875D6492FDBD1BF83ED7ECD8DA1EA4D09
+:1011B000359E59586E9C7CAA1DD9F1BE4B3F8B6160
+:1011C00089BE74C497AB8145F0CC1FC58E3D781D98
+:1011D00035AFA789F6B43A5E4F17EDE9015ECFF758
+:1011E0003FA9D4206049F1977C47C6D5A351BE2DB5
+:1011F00060FC7CB2B8E7603B13F2C29131AB06DB16
+:101200006F6274BE40B6FF50B4E7384EAC29463921
+:101210003CC7F8FD5681876CC789F6E9149F31B643
+:10122000CBF84AA6E3EC2BF47D99B1FD41F1BDD397
+:101230007136361DDB471BC7DF20DA531D3CEF0834
+:10124000C4213F472FDAEF15ED766CC7F14B8DEDDA
+:101250006BC5F82B9500AD433F9F89F8E48E569DF2
+:10126000EAC97CF6EAC80C7E8E59F0996B191BF21C
+:10127000DCFCAB2379BE4C9ADEE3F70F210F657BD4
+:10128000864BA3B8AFEAB5101D591D428E083EEC3F
+:1012900097234A8B8F1317F7977F193D03E17E8EB3
+:1012A000F2AC00FE909EF3BE6362C1047996DB98B7
+:1012B000C28209EF7B176418EA5937E51ADEF7CCCA
+:1012C00019656877548E37B4B3583EF1C76D82AE56
+:1012D00052CA2A0CEDF2BE02A6733E9276B579F49C
+:1012E00014C37B674BF574A4EDD357CBFBAB7C36B3
+:1012F000940BB7394765231FFEA475321ADF20EF20
+:101300006CA27489D24B47C956B6EAA25E4AF5C7A9
+:10131000DC3CAF7A65AB8FD78B189D6F5ED95A4B8B
+:10132000F5C7812FB1FCD7563F957BA00E160EFB5B
+:1013300011F4AF433F3BA17FAC3F02FD63B91DFAFF
+:10134000C7F287D03FB66F857EB1FE10C085E583BA
+:10135000D00F3E7F00FAC7FAA6D600D5EF6BADA33B
+:10136000FA86D62095F7B636D0F3B5AD2D545FDDAD
+:10137000BA8CCA7B5AC354AE6C5D43ED16A1371FBD
+:1013800013E71F1F9BC6CF7D27AF7F469EF2D5EE8A
+:10139000BBA804455E65C893C8C8C37D75A7312F37
+:1013A00010F14770D8391E93E1182BE018CF622B4B
+:1013B00052B9DCA038EB982EDFDDA9C0A7235BF87B
+:1013C000BA1775C5A93DA7818F3756CC9379C22C22
+:1013D000AF8A1FEFC5F77A9558752A8F37931F8309
+:1013E00079013F55E2DC339179C484706993417F80
+:1013F00027CCB31F5F6E0E27E26D28782BF2787C26
+:1014000043ADECE4F79BD4B64791CD52FC2D74BFAD
+:1014100089AD2E10D5A0F40482744FC2F8733360E6
+:10142000930572EDDCE54C8732AFD1B8FFCA5D5051
+:1014300061D8E7A8E73632FD22E8B7CCB84F4A19A1
+:101440007D9BE13B5BDEF70CED16CFDD86F6F9B751
+:1014500014ADF2223E47328A3B59D7AF603900D7EC
+:10146000C28E4D045750E0BD57D1F9FDEDFBC5EFDD
+:101470004408FBFFC72E812FDB7ADAD78E75F36A1B
+:10148000497AD884FAE7E3A7D2498EEE7DC444FEB8
+:10149000ED712C6242793301CC486CBF006F7256FB
+:1014A000E9CA1C15EBE54C57B17E118BD3BE08EC95
+:1014B000FF3AA417B0FF1FB143FD4C7EF0C73CBFFD
+:1014C0002B4A7ABA44AC6789DC076DD192FDC373AD
+:1014D000F3C85F633C07D626F6012BDC55D918EF1D
+:1014E000ED1D26FFCEE9FDD6D405B01ECE9C3A2ACE
+:1014F000E5F30DBA69C873D1CBBE2ABF6C013D625A
+:10150000E4976508FF99CA9F67A1BBAA79749CF804
+:10151000A6CD2CE5989E8E726CA0EE4B27BBA23B0D
+:1015200087F0A389F5D9DB1AA4FC00394FED77D3F6
+:101530005C980F5622F24FF7B5DE3AB526211F66AA
+:10154000B7A0DF5216AB453D5A5A66F245A827AF01
+:10155000C17F611FDDEEC773FA5A05F3A1181EC7DC
+:10156000DAE9BCBAF6854A7940DA914B980E76B042
+:10157000C31165E1B2817E99F0837C47C8F5CF5CE9
+:1015800035340FAD40DA473ED4DDEC33873F867407
+:10159000F7598799B3E509637BA983919E5B546AE8
+:1015A00089E80AA623B4D33D8BDA0E85E515211C04
+:1015B000D3BDF3508F1F4C25BA4DDD524557C37B29
+:1015C0004CC1F57900C7991EFDA0491A57F05ED3AA
+:1015D00004CB2EB41BC7225E709CD1A584C7856244
+:1015E000BEFB5A57109E9E15F368CBEFC73B87870B
+:1015F000F9FC78CFE9A20EE9BF31CE734365F53728
+:10160000F0DEC6953155D874467CAE33C726CE532E
+:1016100006E002389F453855849BFCBF7C7E4D8F89
+:1016200070BF19C8B15A8ABB4E32B1C4B8AB2CA333
+:1016300042FECDC87311BC4EEFDCA90B2E4AACDFC5
+:101640004474FDB8C2E71F766A3C2FCDEFD713FD77
+:10165000C4EBE47E599C7F4811F0F6DFE3369EE749
+:10166000613A586C0BE62D0DB71FFE252ECAA4C497
+:10167000FD30E81818579D64A33C9F75328F4B7F4F
+:1016800043C77C332CF1FC8A4DD0E96AA731AFE423
+:101690005C1EB777CE89F5E8B371BEC6B8647956DB
+:1016A000C2BD17DDF5E4FF9171CCBE6E9E0F2EFD1D
+:1016B0006B4B0409F41DE578E87B58A5F8E592EE3C
+:1016C0006BF97DA1871EA07B56A12F1DE9A15EBCF1
+:1016D0005FBFC6E8EF59B03BB02A451FEC575AC46C
+:1016E000C2E4D748F62725FB917E9B27F6693E5634
+:1016F0008E71CA93EB8B8FA5E07EA688D1B9DB9162
+:10170000EA93748F3158FBED784F292BE3F7F424DB
+:10171000AFFB250516C2F33EB9AE631CE467D837AC
+:1017200089F3FFBE17CF7E7D0CF4F396AE18CE8101
+:10173000BCA59B098FE381AEB1EC64AC76A8FBA09D
+:10174000B2F34D5FEDBCC0A5C6DFD768EAEA3996B3
+:10175000AA93BCCBCA0778FA8EFD3EAD8CF8274E13
+:10176000BF075157C4E141B8F1FCCB7ED3277313B7
+:10177000E9607CBEC6ED837CD35793BF3546B8CEB7
+:1017800094BD99750D876B1CC2D51B3D919568B7AB
+:1017900048B8F60F73BFFAA55F154F938DFA200175
+:1017A0004F53FF129EF65B86866796C0CF4F8EF230
+:1017B000FB4206B77F45FDD56184F7CC63B1EB51A1
+:1017C0003C02BCB3087FDE5359143315F8EBAC145C
+:1017D000F45929E48E8FCEA8B0D0DB17537E5EA7D4
+:1017E000C6DB43772E8AE07902DF8B0B0AD1DFE07C
+:1017F0003C6EA57B9E42497922B25C2FE6B13F57F1
+:1018000019120FABF3B9BC78F1B5F9D4DFBD6F593C
+:1018100019CA83ED22DFF55E57A70DEFEF9578C467
+:101820007A0594214B7C112ABA7B2B3FB3E98E2198
+:10183000C633F1F1EE4BE21B399E2C57E49772BB95
+:101840005439AAE23987FB2E7D93EED9BAAF5223E1
+:1018500099FB37E37F7D12FEA36F667D9DD3CB8A14
+:101860007CF4A32AEFA57D03EA2125FEB332C49FB1
+:101870002548F30FBD6D653B95C1786A14F42BE7DD
+:1018800027E72FE1765EB680CE99E07A20E0ABC5FF
+:10189000FB524FA40BBD87F3223D71A9C6CF894CE3
+:1018A000D2685DEF9B3C85CEF5EC17F914F14B2C1B
+:1018B00043FE2EC333026FF79EFB450CEFA90D7755
+:1018C0009BE95E05A6F578BF0974147A5DA37B9A3F
+:1018D000819E6AF1DEA8175F3B9B86FBE803F966F1
+:1018E00082FB403E97877DE7D45A3A6FF3DA672E42
+:1018F0003581FE9FCE57855D128BE1399A8D15FC9F
+:10190000DC8043D8018ED74E3520FC8EC9DFB32A48
+:10191000097A764FBE95BEDB688967F9300E744848
+:101920006551EEDFA1FBEFFACF0BBA381E9A2B8F71
+:10193000929DE0E8E6F7E23D9DAF135C08F7417841
+:101940009E32EE33573DB657C278A306BE77BAF83B
+:101950007AA64CE2F7D0DC77E9CF5D78EF5EBAC2C9
+:10196000E8FEE84B0ACC06395E5FC4D7A1B3321655
+:101970001B85FCE5D228AFB6337A9B0DED7AC917EB
+:10198000A347A9F4DD6A9197BE7A7229F199A4E37D
+:10199000B905C157916E36025F3C49764E2C309D99
+:1019A000F0E32AC7FCE3C795581DB73F2C2ED42F70
+:1019B000A5269381DF8A0B38DDC812EC52B277EE90
+:1019C00010B42CF57D5BC4C630BFFFB7E766A5A396
+:1019D0005DDA9627ED3CBF0DF1B55D09A417E1383E
+:1019E000FFA5D2BEEFC5D74E34E0B86D302FE4DB93
+:1019F0007B7EEA588FF6499BCB4F7C2AC7D7DC26E3
+:101A0000B11EBC9FFD16FF2BE86F8CBBF97D4447D0
+:101A1000A65C6343FA87F74CD8CF7BADF80B1AD896
+:101A20004F0DF90716BA66CFC0EF16B1E02AB46BB6
+:101A30001775A8867B17EE11F262E1B914164DD81E
+:101A40001F2C9CFC2D3A37B6F05C1A8B82BD758F2B
+:101A500038177D8F3857C40A383D3B44E915E5DF18
+:101A6000CCF7BE24BD95F9CBBDF339DFB302E8B79F
+:101A700049E9B114C1101BA7FC9ECEEBBCD7EA62AA
+:101A8000D192047807CD73048B268CD3FFDE391BEB
+:101A9000CD67607D39FD0ECCD7417878AFD54B78D6
+:101AA0001CBEFF91063C0EF43FCA80C7C1FD97D013
+:101AB000F8EFB5967E49FF1386E95F37C03FD0EF58
+:101AC000681AB7F7C8FC1FA702DF1D89DEBDEDF954
+:101AD0004AFC1D332BFD7E01EBEAACA673848F33E9
+:101AE0003A677AE7E1DFBD83F99A77EEB2F8708C56
+:101AF0003E737CAE6F083D339AB9C2789F972CC76E
+:101B00001714D37C929FDBB4880BF3326DA59A0B2C
+:101B10007F1FD1C66291BB71DF5269233927E3422F
+:101B2000B2DF3FE5A9F23C3BC907796FCB12919731
+:101B300057EC085E81EBBED4D4DEFC13F8F683D2FA
+:101B4000363A37CC989BF633326EA3E12FBF15A3FC
+:101B50005F30C0F0FCCD137A70067EF74310271873
+:101B6000C7512FD81DC4BCB50D62DFB8C11EF3FA32
+:101B700012E4E60D05DA57B317DA93E876D22FF7B9
+:101B80004639DDDE50807E2235F6C4FC22CCB7ED2E
+:101B900011F776E9168A77551EA3FBFEE6CB7DFF8B
+:101BA0009AE4BC8E7C37DAD132CE94867977686B32
+:101BB0006CE4F7BED5A7F27AFD7F8CA07310B0FF5E
+:101BC000492D43F9B25FE5FE2011DF3A2BE6D067DD
+:101BD000DB5840F9F7221FE46CF74B74AFE4D935BA
+:101BE0006368FDEB5FF83EDD0BB73F97EBB1BE439B
+:101BF0004ED263F5565F15DE5BB83F97DBAB9D5A5F
+:101C000034AD22C17E5D9D574DF2F9E335634C89B9
+:101C1000F18FEF0A79B051FA37B578159E67F9B8A8
+:101C200032FA33D2A307ECF43B51A683BFABA2FB3D
+:101C30002D375AE97701AA0F8EDB5C87FBC3348D01
+:101C4000F2914D07ED04CF9975FC7E2DFC16E55DF4
+:101C5000D3C191F4FB56F5A971CA276C4AF195607E
+:101C6000DCAFFEE054BAD7FFE486710528FF4E646E
+:101C7000EA0574AFF1063CF409F54363F9F3B517CF
+:101C8000D37955E7C6D4E0507E10A98F92EFEFDAF2
+:101C90009F5BDEDB85F81967F3A1FC7D4FF1F1B89E
+:101CA000EF2BF1D93AC515F9F9D27AD769FA7DBC8B
+:101CB000FA8E776F62F4DC43742BF773C9E3D50BAC
+:101CC0007DB5DF129F8BBF4B56BF52E05DFC4E626D
+:101CD000BDA99C7EAF4FE27D63D23DB74F08FD2486
+:101CE000CB93AF69745F20D81105E81F3A79D84AC1
+:101CF000747672E3043AAF2EC7AB079CB8802F4FBF
+:101D000064E813715D9F16F2AA7E25DFA7CAE7304B
+:101D10007E0C7FE7307E48A5BCAE3E573C0DE3927B
+:101D2000F23D59EF9F4FB74ABF97B53FF7455A6FFE
+:101D3000A02786F4647AC1497A3AF4827517AEE72F
+:101D4000C7952C8CFECFF05BFCF7C78E1CB292FDC2
+:101D5000DC779CEF6F07DD9FE68817E0FDA1A117F8
+:101D600046921CEBCB8FEFE0F6B69DDFABF846F06A
+:101D70006211FFCD11F711E6A09DF7F9217B14ED5B
+:101D80003C28299E1066BBBDF4FC702A43FF0F94CB
+:101D900014CF63CA012FFDEE0C6B17DFC7E8FB3BC6
+:101DA0000B8263512EDF590CFD3BF0FB53F4DEE751
+:101DB000A38217520C8AB15C315E2EF59B1F2CA4B6
+:101DC000E7CA675EFE7B2AEDA23D46ED216BF0621D
+:101DD0009AC7AF9C6CE710F3FCAAF7EE1D2D1841D3
+:101DE000EB28E1063C93DD988C97B30526F17B3B0D
+:101DF0001C1FC974D9BF9E5F021FFA5FE8BCF621A1
+:101E0000BE8EEBC659B81C593B81EC63D69662C8AE
+:101E10009F5B7188DFC3D0BBC149EBDC67F63F84B1
+:101E2000FA28FE8699F17BEDC022403FC5E4A1F976
+:101E3000E523914FBF642DCFB3FBE8D1F70BE63913
+:101E4000F05CF2FB8673C9D25F089DA4A13FC6E196
+:101E5000D3D3E697717B5D25F8F8EF7A6D34EBF418
+:101E6000BB6BE10DE3C81F71D2A21FA4DF875B77B4
+:101E70008109E94A2D17F277139F9FBC2F4BDE7B18
+:101E8000958C9F8AC262927F4D2C7833DEA17E8230
+:101E9000E959C26146F7FF917BDF8469889A9FE226
+:101EA000B6AC85F4C2E07BF62C5FF2BB6CFFBBF5F1
+:101EB0002A5C2BF4EF9587D350AF7EE0E2FB463AE5
+:101EC0007D8F7A5DE5F36CC30F30AF8305A6144EAA
+:101ED000A27692871F28BC5DCAB941F3477AC17EBA
+:101EE000F03DE8EB9A42EE7F63AE0C71C82B6CC1FB
+:101EF0003C4DA99F428A66C273F3A7DC7A1AD2E3EB
+:101F0000A9B5C5192B300FC6AD6725DAD5A1A38CAD
+:101F1000CE8BEB78DFF8C5F8FB32FE89E8F7DB9F64
+:101F200061F43B24C3F3E4B49EB989ED730AB99E0E
+:101F30009B5F28F699854CE45726E38DAFFB62B191
+:101F4000EE6A79F072DA8726BDB7784BBAA087A41B
+:101F5000E7EDCF7F97F2A01E36DE1349B15F18EF91
+:101F600083572C61E5422C5328AFBD611397730D45
+:101F7000AFCE2CB98BD7E95E85693BEFA1DFE35982
+:101F8000B0EBCA12C6E516AD83A4C70505FE12B4B0
+:101F9000E3E25B5517F245C31695E051CD3ED756A7
+:101FA000787E7A8B99ECBB0601CFE9BC601AAD9BB9
+:101FB000C6340BE0FDB4164C23FB75ABF8DDA1A4D1
+:101FC00079C07B6F6A1543E0C7C6D799F0533C04CC
+:101FD0001DBC61A2755A80BF0B8970EC54C8BF79D3
+:101FE0003A3F7833D64FC1FE1FCFE9AB9B96D07DE9
+:101FF00036C9F83E6D0B127D2E16F391F84C1E4734
+:10200000E2B30FF189F6D22B5348EF851E5491624B
+:10201000D98BDD9FD2BE7CDAA12BDF998ACF3781A5
+:10202000DDA2A39E1DF5B36FA39E5BA3528C7AFE27
+:10203000A1E22C96A4AF71FF39FFF53969A6043DE2
+:10204000A93EC8F1A43AE7A42DA4F7CF7E1DE9EB81
+:1020500084EECBAA4878EFF1C2FEB88361BDEA37BF
+:10206000FD210DC769586FA679C975E9C379A07CB0
+:102070006B4F8D20FDF7E5C5A95FB94EFDF48DEBE3
+:1020800020E909DEFBAF429718274CF2E85451B023
+:10209000CA37049D2C7A00C6C5FEB638E9FED2F3D5
+:1020A0001D57E2A37FBD055F531DD7714711F9D1BD
+:1020B0004D6F6874C8E044FB5505C8C7F5A02FD024
+:1020C0006F51AFC4DFA17B640F59E91EE6FA4DB72B
+:1020D000DC8CE3D51FB79AB0FDD4E1AB26125C4986
+:1020E000EB0A782A188ADEFB8AE205BE04FC813DF1
+:1020F00041FC2DE7930037C101FB29BA8FA8AF0837
+:10210000D633410EBC59C8ED2E78DF6521FAE6F7CB
+:1021100061F5CFD795345F57D27CDF6444DFCC17AD
+:10212000A4F92C78DB6AC2E70BEEBFB604F73DA733
+:10213000D64DA7799DCAF04F44FE3A5500FD0F21B8
+:102140002F17DC0FF32CFB0BF36CB7D37A0D3BCFBF
+:102150008CF80EF617E6F989A04339CFF7343D0D18
+:10216000F3F943CFAA0CFD2EA1FCC0C6A9BC4EBFFB
+:10217000131732737A086D4AA57CDFDE6EFEFB040E
+:10218000520EC078E7490F26A28753D5FAE6C9D088
+:10219000DFFF073F3717B700800000001F8B0800E4
+:1021A0000000000000FFCD7D0B7854D5B5FF3E73D5
+:1021B00066269364924C12088140983C09908449A9
+:1021C00002888A767804D1020D4F798993071042EC
+:1021D0005EA0B5696BCD4002A2450D352A5AD401E7
+:1021E00081A2A20D0A0A15BC032A6245C5578BB607
+:1021F000E526405179C6A05EAEB5D7FFFAAD7D4E5B
+:1022000072CE9054DBDEFB7DFF7C1FDF669FFD5AA4
+:102210007BEDB5D75EAFBDE7C23DAACBEF16E2E4DA
+:10222000DD056FFFBC17A5F7AA2E81FC58DFCD0294
+:10223000F98FC32CFE144A938BA670FE659B6BA589
+:1022400022C489A6BFFD41A1FC857D36B7A0F20B53
+:102250002945F7CE467E8FEA5A41ED2F0C689F251F
+:102260008673B9D844E5EA5D239A502E1E1EE6CA4D
+:10227000A0F2F20D61426409FEFB56687F23E93B40
+:10228000520BA56B556F7834A54D2FFD44C9A56F32
+:1022900056378F57F3AB24F7DD347EB95558EDF937
+:1022A000A8DC9E392D4788F37B6D1303D9323F2379
+:1022B00087CB3FB052798D5DF85AF87BAD7D6A0EC1
+:1022C0008FE2B6D2388BA90F914AE9FA18EF60EA8B
+:1022D0007F318D9342E37D8BBF1F5C0EDF0ECBE71A
+:1022E0000B8AA89F7B6D62F673D95DF5F434DB4DE4
+:1022F0001DF6466D7B573B558825C63CE1A122243F
+:10230000BF14794757BE32A4BC2AA47C47BFCFA7CD
+:1023100014392F1F7F03C61FD185C7120D8F3B2C89
+:10232000F41DEB728F12D844FF2DB1BAEDCB09FE2C
+:10233000E7C6889BD14FA95538AECD47BD0E9E5FED
+:1023400089553486E5E3BB87EBE9F3A6FE1AC3E2C1
+:10235000281FD1CEE353BD8976439EDA9BE09AAB2A
+:10236000C1A3A74BB785BB4EEAF3A07F552DB1A6FD
+:102370007CCDEEBEAE93067C2FC57FFAD2BF49342A
+:10238000FB91C08BFCABDADD7A3092E8A74DF1CD42
+:102390007553BF170E7E1D9DEDE6751F5944EB9BCF
+:1023A000AFA63E7F98E6DBBE47F56C42BF6FD8FD17
+:1023B0004A0CFDE79B8B0F6EA7EFD52FA789BBDDDE
+:1023C0005DF30FC5E385DD17A353E9FBF943F60879
+:1023D000318CE6B9377EAC9DE862475C7BB778AF5D
+:1023E000D5D65DEFEFBCB5357AAAA1DE79D11A3D1D
+:1023F000CD402F25BB2FD68B5CC69F5FCDEFC2EFA4
+:10240000897DBDC7AAF4BDF4F7FDC65A28BD5FC3D8
+:10241000DBBD36F7136B096EFF9E30CF1682FBFCD7
+:102420001BB32D687FFE8D722DBDCDCBE95F4F2490
+:1024300063FC688BA4777DBC356E0BF7536A697BB0
+:10244000EC1ADA8FA5BFEB93D290D2555E6AC9CF52
+:10245000C43A6FB7B52F00DCE715B14689EBEAE760
+:102460007EB79BDB9FDFF3C963E00F27EE1D904F24
+:10247000644DF941B93E2A3FFF5141A68BFA3D7F99
+:102480004F5F0FF8C2769BFB36A6B7BBA23CD8F7CE
+:102490007A7F18A716FDEFB962A40FE947125ECA4A
+:1024A000E7FAE4B87E25BFABDF688BFBBED1E0174F
+:1024B000BFB779B650B2FCEF697D62313FECE76E91
+:1024C000D6A1744D98709BF8C94A86BB4478EC221B
+:1024D0004D960B03BD958922FEBEB0C9FC7D11F15E
+:1024E000097C5FBCDEFCBD5C34AD6EA5F92D09989E
+:1024F000BF0BDA3FFE04EC6BFDAFC55E14057AFF3F
+:1025000036CC544FF835FE401F095F25B41FC1C7B4
+:102510009E5102819558DFBB549E67E8BCDE75A7CB
+:1025200070BB8722FF6741AB615D8F5B843591F0A3
+:102530007ADC2E1C89F9E8470885FAF5EF0B0B6C5D
+:10254000A126770FFE2AB9047CAF31C22208BE5BF8
+:102550005DE07C42ACD8F74932FA295D53E86D352D
+:10256000C077C1E67DE8E7D4BEFD5DE2D754EFF861
+:10257000D840D35882EBF8DDAAA7A11BB84EAFB163
+:10258000884001E1E32E2102F1947FF293E4625A44
+:1025900097CFB67C925C62A47F45CC36D2A39E12C4
+:1025A00024BC3EEF61EFD2FC8ED35C309FD07A5DCD
+:1025B000EB6B8657C767B82A6ABBA387CF40F7542F
+:1025C0009EF5775578B1EFF7D902A0CFC88D5F3C63
+:1025D000380FF4B9D7E64AA1B16BF6A95E95E62D9E
+:1025E000F6A8810C9C637B4F4457E09CD953E05282
+:1025F0000DF3AED9A316E17C39BFFB62426936F711
+:1026000033C5ED44FB073CA0DF9EE0F89B5BFDF784
+:10261000F89FD7CCFFCE657F907003F8C0C6539962
+:10262000E0EFC407FFE6A6799ECFFCC68EBC10ADD6
+:1026300023417F045FB49BE0BC10F82A5A105C8EE3
+:10264000BDAA37D0CD3A44A5D8194FFF327C130923
+:10265000BE842EF8089EA894115D7056BBDBED3841
+:10266000672F38A273C14F694293F212B4F3C90DB8
+:10267000FE5A3A49107F1DBF67E1CA70C80B4D8AE8
+:10268000278CBE97ED55F9DC2ADB1B19C016183FC5
+:10269000C8C9F9D247D54018E527A8A3FF309BEA5F
+:1026A0002FBE47F5D08E14FB37DEF6071BD6758399
+:1026B0004DA01C88035C4B34B896ECFDE1670A8D95
+:1026C000B378DF2D0730CEE207140F17A8F3EDE83B
+:1026D00077C9438A88574067B6E3463A5BD864CEE9
+:1026E0002F12AD0B5415FCC1FC9DF09E5C41FD9674
+:1026F000EF0E73DD8DF102A1E542BC4AF0D468FF14
+:10270000CFCA583BF700D5CFDA68673C9C0F17E279
+:1027100008F6ABB53541200DB626631DCFEFF96B3A
+:1027200032D6B1E677FF9529BA59BFCEFDB437AAA4
+:10273000D7A94821AE4E51C4B7A9A0FB8B538ABA82
+:10274000A96F1B20F7C5369BBF9F87CA0F6CFC8AF9
+:10275000F9C1853DBE81AE6EE8B76BBFFAC32D8966
+:102760004883E102E9F016D70DD827240F62BE3561
+:102770009B564FDB44F9F0976C38B9444D8693F77C
+:102780000BF6C74243BFFA3ED906BE807484E40FFD
+:10279000B601F21C3DAA9D7BDBF6774CC9E8069E8C
+:1027A000A36E1BD7B30D105CEF5977D15CD05B845F
+:1027B000C51F0DBE2DBC5E772FC2B3A2D157435D9E
+:1027C000AD82EF89A289D3FEA285D34785F0395126
+:1027D0005F785CC0B3100362813FDEF38CCFBECC68
+:1027E000377FACAD217835E8C41F2B025BE8FFEAE8
+:1027F0004687506320EDB546A35154CEB4FB065234
+:10280000B9ED03D5A240DE1DA0AFA7C785FDF7A592
+:1028100073468C71FDF61F2E9988FEAA76A9228C2C
+:10282000FA3BB7D326824ED4A7FD027C1CFEC29E83
+:1028300002BEB4571190976B288FEF35A3ADDE80A1
+:10284000012F77A4D8180FD52999F29CB67A0F4D8D
+:10285000A27ECFBB4AEC90EB6D87CB26E2BCB125C4
+:1028600096D801D7FEC3631D2958B7582BEF9BD5C7
+:102870007BF5718FB8D07F54EC070C6F63B645447D
+:1028800053BBC6A3610146A643F2A1300DAF8DC173
+:10289000F10E7737EBE317E393C4282ADFA94E0440
+:1028A0009CE75C252EACA32D96E8EE0A6A6FF34EEA
+:1028B000BC9AFA0D8B8D8B077C6B52D2783DBF8A08
+:1028C000AD6538BF22F1C2CFFBB7B608F9C6FE65C9
+:1028D0002AE3BEE921DECF350E397ED43E95CF51B5
+:1028E00071A543E3DBEFBB4A699C05C9BE47410FB5
+:1028F0009DFC6DC4AB02FC39CB6261F9ACF135E7EC
+:102900005AF021BDFC6C8AA4377D3D56F5B2BAC0A1
+:102910003F1ED5E87395ABC8916F98A7ADB745C377
+:1029200057910378DA612F3A84F3A59DBEE3DC3C2E
+:102930009038CD013D85EA59D0CFA97ADA3176F4C5
+:102940003BC301FC2EEA553201ED168BDAD5D86F68
+:102950008BD7AB2268E0AB8D3639EEA24B11221833
+:10296000DF35EE225A3F6E7F295A04E9DC6D0C9761
+:10297000F51AA3E4FE792345EE9F0FB5F9B469F982
+:102980007F99AF7BCC7CFD5CEC1FB69648FEFE4683
+:102990000AF55BA5B44E48A1F9AD4EECB003BFA754
+:1029A000EA5D22986980F7B279C68BA061DCCE7AA5
+:1029B000971C3C9FAEF57033FC5DF375321E4ED50F
+:1029C00027321E7BEE3FC984C7AEFE534D78BCBC98
+:1029D000FF4C1EFF547DD677F43FB487FEDD26F80A
+:1029E000BBFA4DE771C56EDF40F0973B5DC40F98B1
+:1029F0006E885F50B95DF13D7E35E4DB8FC204E443
+:102A0000BEAFC27D835C06FEF00DCE65D6E782497F
+:102A1000E0B77ED1CC69CDEE8B13D0DE4D7C01FBCF
+:102A2000492FAF11ED0C27F885E88335B4BAB97C8E
+:102A3000B76F10F4221D8E4E79E675A7DF42FB209A
+:102A40006CDFDFA3B18F2F58DBA778286DD9AB4699
+:102A50001AF7757CAAA4A7B103BEC86DA5EFD56807
+:102A6000477CEFB697970E027EAAC3DA7301F7810F
+:102A700097FF968B73E4AB7D4B07E2FB36AACFF250
+:102A800087BDBDDA63E82F5DB8FC96515DA933556B
+:102A9000EEFFD0EFDBF635F4031CDB89BD09920BAA
+:102AA000ABEB2A0A4EC6830D79EF07FF12C4B75865
+:102AB0001FDA3D5D1D03F9EE439279283F7C8F9428
+:102AC0001B860F10014B0AE4BE0F67834F548FB073
+:102AD000BBA00A47E41D61793B6284C3A550FDBFDA
+:102AE000F797E3DB212FA4A17D613CE8F9CA64F1EB
+:102AF000EFC96D1B42F64FF0BDEAED345E95DA3A50
+:102B0000659CC2FB283F157CFBAD2FDED6F4D704B5
+:102B1000ACCF019C6B04CFFB5A3F65A9BE2B50CFB5
+:102B2000E768BDE70AAA377356DF64E847C59A7EAF
+:102B300026261152AE647E94033BC8E5E7B6D483E3
+:102B40005E527C3EE0C1DFD7E1C1F935344938FA45
+:102B5000125E456220751A8D3B21D5A2DB0F14C091
+:102B60003D449BE333FD5A96C7F2391988031DFD96
+:102B7000B3E34E4BF54E06FC7AFD0F67CDCBF175F6
+:102B8000736EE8F2BCDDDEB20C70B65739597FFCCB
+:102B90000045D4EE89596141351A7A8A730DF4F9EA
+:102BA000A3910B0EF6267C8C8FF2CD43FFB36FBC46
+:102BB0007E35F2CA8178F772D07371EB48D6EFC2D6
+:102BC0007D37A3BCD2E11B9840533C37C037280661
+:102BD000877C51BC5C27519453D42DFC129E6245D6
+:102BE0008EDF18E52B473FC596238F5D816FD62377
+:102BF0006C6F108DBDB99F737651DE9DFCAFE3E124
+:102C000098368FFD3671ED259ADFFE75319E06826E
+:102C1000B7ECCE1B17D450BAD0529410544D70DF7D
+:102C2000964A5D57FA8B07F62579EE9C4D83BB4E8D
+:102C300083DBEACA34EEE750B81B7479E5170AEB78
+:102C400083FC47F917FDB181BB291F66B9F8C17430
+:102C50009C5B3916B6936C88A0BD457AE43B1A9C00
+:102C60008FD2BE73C4F1F735F89E1821DB273E687A
+:102C700009C07E5034760FAFD313D54E8F4A6315FB
+:102C80000BB71D7250A9F0B2FEFCD7317FDBD74ADB
+:102C9000F36A4EF5DD07BCDD1C6F49FE80E1F00DE7
+:102CA0009D0A796BB49CC73F9037791ED384CBC6FD
+:102CB0004299586B81FC31CD25A7B25091FB63BA84
+:102CC000F0DA30DE4CE1E37AEF9DB77BA14FBC0731
+:102CD0005D88E0BE51F8F9FB1C11E0749E0872FD9E
+:102CE0009B442BE7757C137DDCDC4BD2C7277D54DE
+:102CF000C6FF56C0FD6E64EE803A9AC7D48706655B
+:102D0000B07ED5DC9BF1F35D704FD5E886F6EF6FB2
+:102D1000B18ED8BF33A89F693784ECDFF1BDF5F5DC
+:102D2000CCF847FBE84847A7FEE4EC4B78B84E5B8D
+:102D3000D2EBBC4B597F12C2C5F2D18FB47D5BA8D8
+:102D40003A452F5A9F236ED297089689639625623B
+:102D5000BEAFAF106F15D03ABE3E46150D5CD3CB5B
+:102D6000EDA668FD4DE93FE133D85B0F8B60AFE125
+:102D7000D4AEF092EFD518827B8ABABD3196CA27BD
+:102D8000F627BDC6C0EFAEEFB5C30AFDEE8674F3FD
+:102D9000F749D966FD67B2685231FE94E1E67AFBE5
+:102DA0008127A2B3F753A5FE22868821DFF27A0B92
+:102DB0008B713E1D932EDA2F101C1169BE8FB12E20
+:102DC000CB27FF7501C61556399FEAB755B6EB1DDF
+:102DD00027798B28509CACA7932253CA25C87F4AD9
+:102DE000F203D2D3F56E4ECFD2798FF2F3F51ECE29
+:102DF00017A4159D40BF256B3EB7627DEE0C97F87A
+:102E00002E6F699A00B02A76B71C445A162C9A8005
+:102E10006376D1A1DA8348EFECD4DB6A59BED3E103
+:102E2000BE45A3D35BA2A6FD3087D6E1963DAA8717
+:102E3000F303A64D9FDC0B791BE77BA2A3AA4B44AF
+:102E400033245754ABDE2F0197776FDBC1789ADFBD
+:102E500027F5A318EECFEABD0CF799FA899C4E4AE4
+:102E60002BFA1BE8CC2B3E67796CF2F6366B12D549
+:102E70002FF42A5EECDB6BBD2210A0FDB7DE26CF5F
+:102E800081F5740E601F8FC999F6E8AD027CDA6790
+:102E90004BA37166DEB0A410E34C19556C45BD1B05
+:102EA000BF211920A58B4EBF8BEEF5F95769EB7644
+:102EB000EE6585F1D8B1332D0672C1F25D697D9062
+:102EC00012BFD4F5DD48E0ADE39285E1EC381AC1DC
+:102ED000FA86DE6EF9AE48E63BCB07D803C260B790
+:102EE0003C43EB2C0CF2E699677EE2369E2B67E2C0
+:102EF0005ABEFA18FCED2F92BF916473EA11F0BF2D
+:102F0000FEFD3CA093F39A9C4D7A4624CEBF6ACD39
+:102F1000AE08FE84FC990869CF1DF96CD258EC2FDD
+:102F20008C471C4EE8FC2BF3D987527FEEEE1A6FCC
+:102F30005BCBC28F1FA1FCB980C56FA3F3E99C686E
+:102F400039FF3BF0DFCD4EB6EBDDA9103C387FB743
+:102F5000F4E37C96628DA8C3F92B02BCBFB314B70F
+:102F6000B58EF855E5730FF703FDBD44381845E5F8
+:102F70002FAD8B647EF692CD73AC0EFD3D2AFBFB2C
+:102F8000CDBD3F3DBE1BE93D55F93FC5F2A4C5315E
+:102F9000FECB7EB56408DAD3F92EFA527F4FBFA874
+:102FA00004C3693FE734EF5FD997E01BB6A1CDD2E8
+:102FB0008FD2BCCD4A03D2A1036E3804BBF30D6996
+:102FC0006E6E5FB03D454DC236EC17F8F8077CEEEB
+:102FD0009BE581ECE6CFC7F6135D72C110A5E5F461
+:102FE0004682352CF968BE8FF1D7C4F3D9B577FA8C
+:102FF000FBF304E6411207E02EB67BF81C0AF83713
+:10300000623DCFF9B23CACD715F91F069D9DF32563
+:1030100078702EBD407AFC55A87FCCCAF37C71F342
+:10302000BBD1B0EBC4907E1C0E7F485EFB04D4AFD6
+:103030001AE0167E6A3FE0B1EB26023FD53B776D82
+:10304000E47E2A1D1EE8B9E5BB2E1E4C829C78BD8D
+:10305000F064800E77CAFC2FC77B3D2A4DB57CE318
+:1030600097327FA488F345A4755A51BF54CA470FBD
+:1030700069E79F68CD65FEC8A4EDEE5AAF5F523197
+:10308000CAD7A7F8FBC2AEAD9F9B74DE55A561AB56
+:10309000D865FB2363E725335EBEE77967D7CE2D7E
+:1030A000BDBF87ECC21F4EFDC06C033BFA06BB3CA4
+:1030B000A7B7107F01BDE8E7348DFB0BEC5F6AEF2B
+:1030C000053F4D52959C9D848FA487C258CEF8BE73
+:1030D000E3CF8E59CDE7B62E67D544483EC8670585
+:1030E000B55F18E5BB0BF35BA89DF3C2EACE861C67
+:1030F0003223CA7B37BE573ADA9331073A3FEF455E
+:10310000BE5A25B92BCD207739E3BED7F95917E53B
+:103110006DC67CBE6FFDB19104670C525DCF22ADD0
+:10312000A35B7E9CBABD05FCF88130C98FA30A98C9
+:103130001FE9F30BEDFF15DAF73EE233AFD179E289
+:1031400023DC8F738EB1F27ABE6AA93C48E770A186
+:103150001C01846C8D1DCE796F14E16FBC5315BEBC
+:103160006EF4453DA5F57A1EF899D02BD254AFB038
+:1031700057AC1DFBF7FBCE5BD5D6478DD0F9A9BB6D
+:10318000977076376F39CF5BC247F4015EC62ADF8E
+:103190006FBE0E5BD141ACC338671E9F8BE39C535F
+:1031A0008FF904C37F18DF43E7193A1FE1F87EF275
+:1031B000D28F15E1B760FF7D6E67FBDA5E5BEBD304
+:1031C000BF257CEE5D92ED819DE805F05EF0CF6855
+:1031D0003BCBB37BA3841F7C65EFD48400EC452FED
+:1031E000414F04DFE82D6479B8ACBF770E95537F6B
+:1031F000FDC2685FC05E342F42EB9F0646FB157D23
+:10320000B87D8352FB660EDAAF8864BE733420F952
+:1032100078736C709E4ADF9B3FCF14A8775404D616
+:10322000A4A2DEEDD25F43E54935D46FF3922112BB
+:10323000CEFF51F9DC68CEF3F68D73321F67FB4C7D
+:10324000F3546F5FF8AF7A69EBD5BC5196F7833DC5
+:1032500014E52994A7F4639BAC3F57ABF7914697CD
+:10326000B4CF990FF8A6445A41E7FDD24BC2D29988
+:103270002979FBC2EFF3485906DB28E7565C9FC269
+:10328000F4A3D9CB666B7C5BEF0F0D1C23212FCBF6
+:10329000BF390BB784839E679687B741EE3B5ABE12
+:1032A000320A7AFB4C9F1A0C835C39A3D0DB29AF1E
+:1032B000A5625CAF1CB74CD7FF82A5C0EBCBED0E6F
+:1032C0007137CBF7C102A33EA5AF6F55CB9878A35A
+:1032D000DE5C6127FE42F02CD1F66D9AD3D73B7DA0
+:1032E00004F4E9EBE38DFAF4A7650FE4F2FED2C62D
+:1032F0003B5BEF8D3F990EB96D22A7FA789D7A0F4F
+:10330000D64DE757A097DB25BD086BFB478B29DF20
+:10331000307B8807F6EA89D31C4C6F1D2DE12C1FEA
+:1033200037CC8EF0C26ED7B02B8CED06376BFB839B
+:10333000F428A61BFFBE28EEA7D22EF395CF65304A
+:10334000DDBC600F3CB915E52F87B37FB6325A8ECE
+:103350005BF9BB248D2EBD29AB7AB15F8EE9A53216
+:10336000C21DC3E5BF8F677A7A36DC57007C127DB9
+:10337000B25DBCD21ECC8C25FC1FD3E80F7A23FB98
+:10338000F56AA3986E8596F7FD3C9EF538927F7995
+:103390003CDF7D4339EFB37BFB2EC43E5A1EC9F0A0
+:1033A0001C73C9F26395B1BC0FE6DFB7F430FCC5FE
+:1033B000C78AECBC5F8EED5559DEFA739D1A849F67
+:1033C0005BA7CF9A25C7DF86F9A8BAE1A3E4DDD4CD
+:1033D000CFFC955593D06E7EC5ED5370DEF69AF610
+:1033E00029FB6943F7F3FC4AB37FD497EE9D8CF930
+:1033F000D56407761CA47E1E9C736A11D6D39FEEFB
+:103400009B86F53E6F6F7DE14F0477EB8A3FB25E9E
+:10341000747DB46F26BE5FD8F31BAE5FBDF2BF16DE
+:1034200041CEAFB64A7AD1CFE31A8D7E45866F1E64
+:10343000EA57AE7C9DF581C8EC23927FDEFEFDF855
+:10344000CEE9BD5B5E50A8DDD288BDD59CAA815C6B
+:103450009C6B679460B492067C4A3DEDAC2B188D52
+:1034600075F159A49CB8745B881F184B91A0D97F43
+:10347000A8DDD21619BF42F2821DF4195A7F297DA8
+:10348000E77ADFF37B856891DF6377DF7BB55CF7F5
+:10349000607038FCAE199BB0EEE776FD26D3E87776
+:1034A0000D4D2F8757CEFFACB65FCEEAFB65B6BD9C
+:1034B000D35E00B9EBFC337D4C7476FEC9C19C3FF2
+:1034C000ADB42B114A977F57785A46727C8DB765F9
+:1034D00024E4E707B5EF4BE35B4682AFE97C4E3867
+:1034E0005A7259FFCF6AC985BEABF34751D492C90E
+:1034F000DF032D9968FF8245DA53F88FE0A8783A08
+:1035000069E3DDD20FE1B70C477EE826E4F5711AD6
+:10351000C2251FE969BE8FA54B3BE6F939F69BBD75
+:10352000547FD07ABBA97C70C09CDF9A2EEDE70354
+:1035300043E26FFAA9EDFBC3708E3C21BAF5D73F89
+:10354000A38DF3D4539D713CAAA6CF0AB74E1F6E2C
+:1035500029DFDB80EF8F3AF17D6B12F1E5A59863EF
+:103560002ACF5F9E674F49FBCD0B79BE249C17E79E
+:10357000811782FF8558CA6743BE9278D5F33A3ED9
+:1035800043E7BFF2A34549B0DF7E94AEDBF93C7D53
+:1035900040973ADE1A6CA4EF64433F2E2F386985BA
+:1035A000DEEC492CB31AECDAEBF31CD8578B37E47A
+:1035B000398C74D6B0ADE010491CE2EC36AB072074
+:1035C000375803F7427E6FD8A6B6F805973BBC5430
+:1035D000FFACF3C0DBA8B768436C3EE46DBDFDE211
+:1035E000F52312CB0C700EDD665E879C16737ED8B9
+:1035F0006E73FE04CE80DEFF7CBBBCA0395F70C85A
+:103600009CFFE4835B67819CCB55FFBD2AF4893F17
+:103610004D3884F3F1D3175E8CC6FA2CFD4BD9419B
+:10362000E849A17122B46E0AF408FF5685E9E3B2B5
+:1036300078911EF8811E0F819D61A4930AE13F6875
+:103640004DB9BCFE19D132CB4B745559B7BCE064AF
+:103650004157BF57B6ACB343CE0B1DB7A7FD2F9C48
+:103660005E37EC6AC5A364D9557563C509F82DD6D4
+:10367000BE3B01F457FC4B85E58AE2E707BD0ABE75
+:10368000DFB663CE0D9CCE9AC8F8D0ED7D8BF72ABD
+:10369000C128CABB4649BA5DB85E617DBDA4D11CD4
+:1036A0004757B63624DEA6D95CBE78F7FEFF869F64
+:1036B000BEDCF118C7335C1E271878057A5BC5A7F6
+:1036C00082ED3D159BBF0D3397CB792DD4E7E1BF3C
+:1036D00096E3E1AE92553ACFB793C8D0F9F04B5785
+:1036E000516A06E1FDAAE68DAA949BBDC5EC9775CB
+:1036F000DA39CEB0CA21829104CFA128BBD745DFE9
+:103700002FAE8F6279615118C99FF99C8A708E43E0
+:10371000F4C4A0DDA977549683AAE2251EAA1E57F9
+:1037200002B0C556C1488AFC1332BF04DE2655D20A
+:103730008FD7003FD6CD98174D526FABB406F70325
+:103740002F9DE7C03673BD4A9AE7D138C859E6EFD6
+:10375000D5A29DEBD7ECFE36CCF8DD60DF657D525F
+:10376000D76B55C83304A77A4704CBB3C49823401A
+:1037700057AB14EFC30E15299DE3A0EF254E962FEE
+:10378000E66E94E747338C839083D70D66B967AEB6
+:10379000E2CD04BEC4BA70D6A7A9DC1FDE8BE564F7
+:1037A0009643484E6639AA7D8E9DE3129BF35A825A
+:1037B00090C79A1F48F1D00A327FE4F3E89E7096D2
+:1037C0007B9AA74AB9A7795D1F6EFF3140EB0B3991
+:1037D0005AE2B9F99E1C1EB79F2ADB893E520F2080
+:1037E000B93A137A02C1E541B92E4767C5FA4AB022
+:1037F000EEFAFC9B63DBA3E0C712E5F1DF4B6ED86A
+:10380000A29D87EDEBC203F0539C548A0E5A0CF62E
+:10381000A95B32E4F93172AC77AB568FFD1965962E
+:10382000A977FF80E0297BD0E26E48E95A07E1F5ED
+:103830006662FE27D785E783EE468E95F6A7637905
+:10384000929F470E171CBF73BBD6EFED1916539A04
+:103850001841F448FD9C2C94F6EDA8E1456C07A4B2
+:1038600035BAB9BB38903519F29C2AB317FDFE9AC8
+:103870006EE0E9A48BF152DE3DB94CD924E1F2723D
+:10388000BCDFC85F85B3FDF0A476DEE8EB4174349D
+:1038900082CF718D9FADD3E8665DCF7463A28BB983
+:1038A00090B7413773E4B9D84957DAFA12DDF07AA4
+:1038B000B7135D48BA11E26BB42F744B793B44DF08
+:1038C000EAD4B77BD0B7880E9EC8E86DA817420728
+:1038D000C21A18F18FFC2C25A362472AB40449565A
+:1038E000E147DC2CCE46C6D75DD6C04A82A7BF557D
+:1038F000AECB00ABA43B3A65FC11F95CDF8BF8D989
+:10390000E2FB170B2FD52F4E126CB74A27F926264C
+:103910008EDB09A47007AAB0E7508AF6C531B2FF62
+:1039200062A26FC4B3517F5E4B9CC6DC46C27F2A45
+:10393000587E40FBE87C6EEFB7C8F65E2BA503D33C
+:10394000E43E6A5F15C6F82BBE734026E864D25881
+:10395000339D24664A39414F1B33DDBADC90087E23
+:1039600050D23898CF9986F0A2AA5DD8A7CF487DCB
+:10397000A378F54D934700BE67E33DD8C2A7A7ECF7
+:1039800060FF4A49E39C1F7F083D655B387FDF98F5
+:10399000E97B0F783FADB817ECA20F25335FB12755
+:1039A000527B5FCBD473BFA3748A7FC7DB9023A6FF
+:1039B000CC50B9FE1421EDB9A2518E33D9FFB935DF
+:1039C00091FA9B3C5AE1F094B67057F232F855B434
+:1039D000F53DA6D17743B898FD9C13700DC84CCD2A
+:1039E000861F8224D46EE4E401995AFD31CA06C8C8
+:1039F0004303C7C9FDA7D7473FE8372D53EEB7CFDD
+:103A0000B47DA7E709AF5CBF6C4D585B5A34525B7D
+:103A10007010A5F3B2C69E039F99942A26AC07DEC8
+:103A20007FAA8A4D0C6F7B31F385A84C37F8828FC3
+:103A30001459A6FB6D8399EEDBC6B4B7DD49F9B620
+:103A40002D39D27EA7E9F30B5D82E582B63192EF84
+:103A5000B56F8964FE73CCD51A1527ED5DACDF9781
+:103A60006A24F1D7BA867BE1372E75DADB707E2CBB
+:103A70007C603AFBFB4B9B49BF475CFD5AB37E4FD2
+:103A80007A78586637FA7AA85E0E9A011D95AD5578
+:103A9000980E073678EC7D99CF292ECCAFCC194CF7
+:103AA00007FF2FF384735CF0657AFB3784F791B0DE
+:103AB0001F0B0EBA1A3AC8D70BE3163715B37E1A86
+:103AC00099ED63FE355025BC101DCFD4E86F12EC84
+:103AD000A0E04BD6D6BED897AF6568DFE35C994EC1
+:103AE000A6EB70BE6FD066736502BEB655E1169C3C
+:103AF000B793564AFAA67DE7C0BD80BBAC2202FC54
+:103B0000E0B8D67EFE0A6BD146CAF777086B541C24
+:103B1000E82B8FE93B90E5FB0CEBF7E92FC428C8B5
+:103B20000DA56BD749B834FA10D623E3E3699C4F4F
+:103B3000B7A4E4C3AEA0D353206B6C76E608035D54
+:103B4000CC50981E683E87609F9D9755928F72FA61
+:103B5000BE1FF432696C301D71D8856A25C7AB76FB
+:103B6000240A0FE2873A443BCB231D248F803FEA8F
+:103B70007C46E72744175E4742D77AEB7C656B3D6E
+:103B8000814678DE56EFE0F4A97A97B0124FD85EFE
+:103B90009FC8F967EBDD9CB6D467F1F7E7EA3D9C77
+:103BA000DF593F8AF32FD47B39BFBB7E22A7BFAB3F
+:103BB0002FE2EF841FE64B3ADFD1F9934E5F3A9F35
+:103BC0000AA5AB058466DC33A0F6CC0F753E887978
+:103BD00058F2BBF893BECEA94A913F11FC50B4CE27
+:103BE00001FF2854CF3EF322E1B9A3DCC9F1A11DA6
+:103BF00042F2C10EA783CF8D64BBD80DFB40C33208
+:103C00006FDB9D8673785EB922AC06BABDA9365CBF
+:103C1000580D747D735DAC293FBFEEFDD7FA50FFA0
+:103C20003F8BF12DC2FA1CBBE3D4A37FA4EF8FDF3F
+:103C3000713A03EB4E706C7908E3DE1EA1C1D12A04
+:103C4000E1BADDCEF2D2C008A94FE1CF6188732D71
+:103C50004E897DFB3704E7316D1D06DA5DB346C141
+:103C60002EB34A75ADA42A1F63BDE8FB9FB5F52AA4
+:103C7000A90B637C96346AFBD418FF4CF83CDE57E2
+:103C8000B05CA77885801FE9F82FEC419211C471D0
+:103C9000C51150681C8594ADF9B017AE79FD28E4C4
+:103CA00074A5EE10CBD53E8793E32884DF76D6D873
+:103CB0009F527790EB89D6FEA638C8C8E15E3BF8E4
+:103CC00005681BEB56927540609F8B2685EFF1943B
+:103CD00069DFCBD628A6F8E27B3355E68B8732AC7A
+:103CE0009C0ECA149A13A589CF299D5E897F703CCA
+:103CF0006359539E7D91812F9768DF4BB32CA67833
+:103D0000C74319322E6A109805A57767A5DA1732CE
+:103D1000DF7373DCBD5EBF242B7F75EA70F483E82C
+:103D2000A0AEF68F645AB9DDA10C9784C741E7595C
+:103D300014C7E9747B2EE872CCA7F8EF950C3FEB23
+:103D40005915CF3EFD2CFC7B157F0AE3F3A9629841
+:103D500066DFC80E8C9CCEF28FD7A98C84FC2DD741
+:103D60007FFCD37F89467C54CD4E6957A5B40D693D
+:103D7000F5EDE56C57ABF6D0FE88039F35FBCD5FC4
+:103D80007DF64FD1ADAC97F893B4F85B8EF7AADE11
+:103D90007982E3C0F4B8AFD07635CA37ACA7EA7100
+:103DA00001BA3FB6709F8DF74DCD1E85F5989A5D8F
+:103DB0001713C0E76AF6AD4AE82E2E27B45F3D5EC2
+:103DC00040B7BFD588B59FC37F4884C3F80FADFF08
+:103DD000766654AF53430562D5AE603B8855701C80
+:103DE000C7722D8EB32390C17EE19EE4ED9AF5C497
+:103DF000F049BFEDB0BA6310AF7C418889DDAD53A7
+:103E0000FC20797E9FA37D04BFF085ED2ACB91171E
+:103E1000B647F17EA8DE7EFF41C4DB556F56D88DD4
+:103E200057258E30DEAA77AAC261E00F35B00BC5E8
+:103E3000F70CE7D2A7A36A415F4B5A14EF16F8AD0F
+:103E40001DEE98DE0678DA35FA5A1AD63292D74540
+:103E500083FF14F89A41CE5CB2F77E8E13A47AE702
+:103E600059AEF96D24C7B3510F6F03CE331B0AD877
+:103E70004FBDA4654735CB05DB235D10694EDBCC18
+:103E8000F729BED1C6FB4693D3CEC04F82F6CFAA48
+:103E90002C0F034EECCBD35A3CABDECE3248B6B33C
+:103EA0006878FB0DF6E788AEFA4B5ADAA2D3A9FE82
+:103EB00027BBDFE7D43948EEE325CE23B938473FA7
+:103EC000D919C9F7ED3ED9F9EB092FD178E75AC6D0
+:103ED000F4520CFB6CE0201BD73FB741C601F32521
+:103EE00011D60F5A783E67B62729AC2703DF849F87
+:103EF000333B9F8FB6F03EF6FF7B71ABB3156BC8BB
+:103F00007D84EBB24780FE5BB5FB11ED9AFDE57F4A
+:103F1000A7FF6AED7B9B52A48D23EF3B083D0EC2A9
+:103F2000A5ED3BD5C9FB6E79949DEF2F2C18E6BE0D
+:103F3000711EF8E89B328E51F4773F04FD6FC13B50
+:103F4000F16C6F596E73F741FE8BC336F6132C2854
+:103F5000F01CF5A17E8C9DED4A22B17504ECAD6D8F
+:103F60002952BEA85C433B9350DC8FE8CD4FF8ACA0
+:103F70000C58848FF29307A5F2BA3E526EF1DAD94B
+:103F8000FF13E4FB92C7ECC28F7B2FFEE7A47E5D9C
+:103F9000992AFD0E8F607F515A1917CC8C87DD4E00
+:103FA000A39BCA69546EA09FCA4DC14CC84F67ED10
+:103FB000D21E8972E84D95F9B25E8346A7E807FDE7
+:103FC000B6A5B8CEB3BCBB2B4A40EFB0BC1825EDAC
+:103FD00021BF09DF146638AF6F1A24E9B841F3072F
+:103FE000FAB748F80017E4F825F6A64CC8B9FAB8AD
+:103FF0004BA29B78BCB3DA784B229AA4FF448BC7C0
+:10400000437D1EDF26D8BFD3FE6418CBCBA7FB1E93
+:104010007901E39F7E7230C711B4A50416EDE6F274
+:10402000708EE3AE782A2C08783F7B328AED589F59
+:10403000D9A41CF6595402CB6187A21E5C80FE3ABB
+:10404000368729E0A39F29C29E88F22DBD590EA86C
+:10405000A8AF633F4905B117C8AF944E84DCF7D9C8
+:1040600096C16C27FAEC0D952F29D0F735F8EE1391
+:104070004D0B7EC6F2BFF43F9E7EEA6F83BBF3AF6B
+:10408000546C36DBC3F4F5D7CBEF1824ED03770C73
+:10409000927AC9CA412EE97F8B6C793095E729F96C
+:1040A00003AD03EB7FB41F13606F3FD6B22741719E
+:1040B00002CFC1CC5F03EFDBA49E757ABB8DFD42BE
+:1040C000152F4679D9FE74E7157CEFB042957278CA
+:1040D0008545DEDBABD0EE99564467B27D8BF0CDE3
+:1040E0007A6DFB16551B478EFBD9D601D29F10D493
+:1040F000F22FE4F03DB84971E2E6692C5F6DC80526
+:104100005E2F6E8EE4F8791AC78BB8878A9FFD5CA4
+:10411000E2336611EB0774AE317FAED4F873D59DF0
+:1041200057C7E05E817847E5FB1217AD9E3EE0BFC2
+:10413000A1F87A4FE3634B5F7894F94125ED17C4FA
+:10414000592DD5FCCB4B9F52589E5CBAFAEA879802
+:10415000EFBE6D13B85F70B6E5FE68E37AECD5F894
+:1041600067577B0FD75F4AF565FB37A3199EAD36BE
+:104170000FE0095DC7EFDDFE29F55F6A5FD142F20E
+:1041800045EEE5F3BF288EDCF627F095EDE16C6790
+:10419000A3F5E77B46676C2D8B30FF33CF8433BFAD
+:1041A00039132BF7FD27749EFAED80E787F7B15D91
+:1041B000EDBDE902E7D0E280B95F1DAEFD1ADFAFC9
+:1041C0008AF7C4C04F5345EB81FE687D7EC4EDDFA6
+:1041D000B171FBD0F93C8E76230CFBF49948A69B79
+:1041E00033FDE4BA9C7976109F676DB192DE09DEEB
+:1041F00064E84B6762658A1B3EA0870A97A48733F1
+:10420000635AD81E7046D9C1699B4DB6ABA8D3FC82
+:10421000DA447F89A01FD026ECA98EB54720C7803D
+:10422000CF8FCCE73488FBCEA17673D029CEBFBE2A
+:1042300059F2DC8478053ECF7E1BF6E3B4F03D7383
+:104240009F264F566EBFDC4F8875AADCAEB03FEBA1
+:104250009276FE02EA5EBADD9FE872A95FF1226EF5
+:104260006B69E3B225A0FBA5B5EBE681EEF5792CF1
+:10427000D5EE5FB7292AC3D3164EFB27FBF2F174A4
+:10428000FCAA598A1E9F275CFAF9457B382CCB2D56
+:10429000E988B24DD45F65A3B296C749D1F55B39C1
+:1042A0003F1D4FB8CD02FB5E9B76DFB9A7F9EB70DF
+:1042B000F6044F5296E44F6D29F29E6FFB5BF2BEFF
+:1042C000F6C56F0A62E2FE813CC891FA7A7F047FEC
+:1042D000166810728FC6E796C2AE4E70666E30FBDF
+:1042E00073B2369BF343B69BF3D93BCDF9DCBDE605
+:1042F000BCE75573DE85717B77E109FA36E203A1ED
+:104300006F2385BEEDCE94FA36F2D0B79142DFC668
+:1043100077E8DBC843DF461EFA36F2D0B79142DFBA
+:10432000C6F7391A9E2A357B29D681E3D4F684EB69
+:10433000F100BC5F2ECC49603E2AAC521FBDB024B8
+:104340009BE5C74E3BD35407DB99F438A7B7A27C53
+:10435000E3B27AC37F7B6475DF146EC7F6E79ADF3A
+:1043600049FB73657EB813F68ED6559FAC86D8137D
+:1043700088F24D44FD0BB6F6ADC06F55DD2BEC6FEA
+:104380006F5DE17EE70772FDD8EEA2C72D15E3DC75
+:1043900003DF267D49C66F7B1C463B6AA85F48AC9D
+:1043A00035E4213F359BF3A17E20F035AF695F35C1
+:1043B000311D3C6E6BEF0BBE7FE24907DFF33AA184
+:1043C000D9EDC46C17CB63BA3CDF298FDDA36CC277
+:1043D000F9BD242B8EDB771CCA30DDD30B4D4B2F60
+:1043E000E5B3BCDA995FAB58304ED98C15FB59AFA9
+:1043F0004E8CE673E9160DB64190FF0D700F0E441A
+:1044000098E868E8B6B810BF653F53FD61BB5343F9
+:10441000FC96434CE5D3D71698EFB5175D6D2A1F70
+:1044200068EF8C877348FF96069F4BD6B9E8CCE7B8
+:10443000F986D64B563C7F84BF56BC25E5D3329ACD
+:1044400087B7407B9F231FFE39EF14E0AFBCC51632
+:104450008BF3BE543B87449DF95C2EB70ABF2BAE4D
+:104460008BEECA5DC21B4BEDBFB43625331DDD712B
+:10447000345925142D19722437087DE58D2746827D
+:10448000AEAAD48DC92E2ABF55096CC545ECD3718F
+:104490003B12AEA4F2FFB4F81EC9A2754AB605EFEE
+:1044A0009D0F3EBA234DE0BD91136B9F8FE6B83C44
+:1044B0008DFE926DAE08D0C1C62695F514D8CDD428
+:1044C000B82E3AD9D8141F01BDA67C8CE297727120
+:1044D000B449DF0BC547A19AFD8E9BE67BF1902A7C
+:1044E000EF406AF35CEE92F545BA6CAFDFB3D7E705
+:1044F0007B52D3472B36BE96790B7D3F3B787F2E80
+:10450000AE8457D6EFE6792FB56CDFDA97D27B1DF4
+:10451000BE5D98D7F2B7C6455F49E37CB95DC687F3
+:10452000FFB5F989C7FCC44FEF6C7AC20EFB418519
+:104530003560871E5CFEE4463BE218AEDBB691BFF9
+:104540002FDA56CCF600FDBEDAA77A7CB3868FF25E
+:10455000B1CA0617CDB3FF60C94FCA23641C4BA173
+:104560003AFA35DC13B8B84DC9C3BC6614EDB0E3F4
+:104570001EFF3B1ADF09DD371D87A717F686BDAB87
+:1045800045F120DFD33E9989CB72440FD32FB9393F
+:104590009D716908EBD51F0AD2BE708E6487E8D77B
+:1045A000875569CF433C12AD73B93DD86B3AE4856A
+:1045B00097E5FB0F55740E8DCA87DE2EC4559416F1
+:1045C0008D564D745E333ED2B40F660BC3BEA2FE51
+:1045D00066897EA6FC8C4969A6FA37CE181AE2676E
+:1045E000CEEF2A67FE7595E95D97AADBFD6E85E340
+:1045F0007BC69ABF537A3BD3D90DA6F655629AE98A
+:104600005D97259BDF653C1395D9A18F956BF7418D
+:1046100066FBDAB4EFADFC9D2662DAAF03D33C7FD4
+:1046200094E7A58DFD08BA1D7D36FE9FD6DD79196C
+:10463000D1198F89F85BD83B7C6679E408EBA942F5
+:10464000AE4395668FAACA92F6A82AFF113BE29B59
+:1046500009FFD62442497593C2F646AAEF488A93C9
+:10466000F9DBF17DA7F95E07FABB84F2436A31F604
+:1046700057687935CD1BE74235EC47B083E9FD6BD0
+:10468000FDEAF4197ACF3EB41FDF6037EFE78A6D99
+:104690003B0EF623BC4C2F8ACD437C4965CB545B43
+:1046A00071F6E574A6F3FD8BE516B67F751C7E8565
+:1046B000E9ACA3DCEA91F1DDFF181FD55E696F0D4F
+:1046C000A5BF45341FF89917ED543C0145D6035E4C
+:1046D000FA812E43F092D40DBE743C75E22DA47C79
+:1046E00031FE331CF1114A007CF232BCE878D4FA76
+:1046F0005FE4132C67123C018627A43F312A74FF24
+:10470000DDC2EF20746C50844BF96E3C4CBB24ED41
+:104710003603D3E4BCDB77291EC8EBB32E59F97BF3
+:1047200027BD14C938F51993CCFBB3937E8AE47E78
+:1047300099792981DBFD6FD3D177D18FEE9F098DD8
+:10474000FFD6EF5D2D1AACDD4B1A21467CFB4FC422
+:10475000AFEB72404FE749E779E3D2F0EF4CEDF66B
+:104760001C5E1E95CAF1DA3ECD8EA8F3639FD64E2D
+:104770001FB798CADD05A0EFFE09B017AF6E4C4B0E
+:1047800036BE17E35B65633B6FF28A784E8BC35D81
+:104790000938478A57C8774D8EDFD52701FE88E351
+:1047A000AB6CBD2651D7C77F3A3C59E4205FC8E9BE
+:1047B000897561B38D76783D6D1A2CED35FA397EA9
+:1047C000CE72387A36F6DFAA5DD108055ABAEAFD0C
+:1047D000912E3ACF57597C8F0F667FEF463ECF859B
+:1047E0006B632EEC70BA3C51B1AAB00FCEFDCAFF7C
+:1047F00079E5319CFBBE15B604C8A39F7DA00A8451
+:10480000CED079C672C4A7E192AE3FDD12C9F710CF
+:104810003F558417FEA625EAFE5C97E95CDD3B0B5D
+:10482000E3FFDE41E38EC0B881AD8918D7E3CFC482
+:10483000B8BE151931DDD957F4B466BD94F3B6EAA4
+:10484000F664CDEE0CF91E79C8F7706241BE471EC2
+:10485000F23D52C8F7F8BE4DF32F0C6C68CF837E43
+:10486000EA1F2BB26AF9BC7566417EBF4589F080AC
+:10487000FFDCA278FA70BCC166F9DEC4F29075D58F
+:10488000D36BDA490633D0ED0F2E3984316E6E8C3E
+:104890008835E5C739FA9AEA17BA524CE5D7250E9A
+:1048A00036955FEFCE33E57F9875A5A9FE64CF18E6
+:1048B00053FE47A3AE37D59FEA9D6ACA4F9F38C7BC
+:1048C000547F6651B1A9FCC6D94B4CE5737CCB4CE7
+:1048D000F979E53F35D5BFA97685A9DC2B5C569CD7
+:1048E000777BA17711DE5F86DE45E92D6F65388D18
+:1048F000EB3A7A9CA5DB77794E697250BFA1DE3620
+:10490000D025EED7800E0768F767BEC0B9D21B7EF0
+:10491000C9A022F5DE237D4137A1F542CB47471ED2
+:10492000B8E8A6352C7A2A7AA695F8C4E82B0E1496
+:10493000A4517EF5538533ADC45F465F7DE0F954E5
+:10494000CA373DB54A960F3B7011E5514FDF20F352
+:10495000D3058B1A8F0CF97A869FE631FA07A96B7B
+:104960003DD26ED26DBC69A73D88F080784DE001E4
+:104970006990E813E901A24FA4AF127D96A50B71CF
+:1049800090E813E921D23FF1FDF7A47F223D4CFAD4
+:1049900027D2B749FF447A84F44FA4EFD5CFE6F489
+:1049A000837A1FB7FB437D39A747EB6BF9FBC7F54C
+:1049B000759CFEB9DECFDF5D43743B4390ED31BAA9
+:1049C000FFAB1A7E47D8ED76DBCE1AFDC28A579E22
+:1049D000A7BABFB2A156B446629FB65A634F39BA5E
+:1049E000FC903DF35BAB386590BF5E0FF7260DE1A1
+:1049F000F1FBBB986F6BDF8F89E903F2699D0A5267
+:104A00007D29289F995FBA2A86F8C70FBEA9B5816C
+:104A10005E3EB4747F7FFB0B8D4EDA877833878CD4
+:104A2000E8F2BBEB7EEFCEF81A835F1EFE6C3D8E84
+:104A300047F7C7F39F213E47F793EBF141D76AEF62
+:104A400023E97E703DFE47EFB7F09260BE77CD1A46
+:104A50002BCB2D515611C4387A9CCF358E963CC441
+:104A60003B5C53E9E438B73EF41DEF23523D2FDEA3
+:104A700099DBFC25D5CFEDF2BBF7D1E641E53C8FC4
+:104A8000C24B3EB6D75EA3C51DA0BD4396F33B7592
+:104A9000881183FC4129DBE11E55A87D7E571C004F
+:104AA000EA47CAFA41F497FE158D17DDB58F06C4A3
+:104AB000B5E4216E6C40B593E3C6368C09F2BDB9FE
+:104AC000E9B1D7DED3AA224E38E6C7D8474FA7FAB6
+:104AD0006602CFEFEE730FF0507E5A5C5A6FA4530C
+:104AE00043DEB5EB667DE6625D757CE978D7D74B32
+:104AF000C7B7219E8AF1FC5DEB17BA6EA1EBA5AF9B
+:104B000053E1A52EFC037F97AF4FD7FAC13EFBFFC1
+:104B1000CBFA0CB7B6F07DCCB04A8707707DD77A58
+:104B2000DDDC2E26E03E78F125F741A44BD27C5FF8
+:104B3000807F968A31135CC0914BCD819D27B4DE76
+:104B4000F2EF59EFE1907A07E20AD67C9D7679BDC3
+:104B5000DD21F51A620BD67E2DED4C37E27C3DE46B
+:104B6000B6B11FEDCD703D1EC3EBCCA3751CA7F1F4
+:104B7000A343A296CF0F12D7FC58DFF1DA528FCBA6
+:104B80005ECC72EE78A7596E9CF04D5123C69DD035
+:104B90002B448ED6FCE13768FD5E279AB8DFD07BC8
+:104BA000F23768F269E83DF9E78668F2658A4801FC
+:104BB0009F1A2F3C122EEDBD83F12ED96F92462FF6
+:104BC000696E558C063D089F15CCF155BC77908BCE
+:104BD00071FD9CBF5E0438FDA108723F938991224C
+:104BE000FF23216CF29D03793FB35AF5FD27E42C96
+:104BF000FD5EE6C270DFABD877AF444E998FF728E1
+:104C0000C6158C4B47BB03E3DD2C9F1C70A4B1BCC5
+:104C1000847D658BEBDA7F6FD0F9926E95F7069104
+:104C2000E2DE603A6D96D7E9FC41FE86AC1502EDF6
+:104C300026B8CD71387AFB1FBAC60A6B41CFFCFD8E
+:104C400087B97BFAC3AEF366ECA0F1B083BF197BE2
+:104C5000C578CCF7CDD83E169986D939CD7931BDF6
+:104C60003B794EA7E7AEF126086B7CCF78D6F11AD8
+:104C70008A4F1DCFFF025E2F7487D72F060B29376F
+:104C8000474A3EA2E3B72AACF31E671F635C44A504
+:104C900043E2E933808C7BB87557F13C3EA917FDA0
+:104CA00081EF4575A3B83CD40E2536C7705E7FC72B
+:104CB000ECCC83EF4627127CD7397CEA50C2CBD9A3
+:104CC000FC60264930E2930D0D7CEFFADCB3AA07B5
+:104CD000F27FA5EA5EEB014F7953653FA0F8E695B8
+:104CE00064F809C5E6EEE3A32B1D12AFBAFEB3329A
+:104CF000AD88F7A7701524CAF7D5E43D725D1EE8AC
+:104D00001F26E38BF5FBCC3DC9072323241FEB1F94
+:104D100026F9AEBE9ED48EF349D4CF48E25349F76C
+:104D200045B03EB0DBE54D1A0A7FCA786192A7759F
+:104D3000BDBFA3977C3FF05A91F9D068CA8F3F64FA
+:104D400013012AEF182F4CF164856F94F2BB16FA09
+:104D5000FD98B044D2AF0CFC20DC1D617A6F343278
+:104D60002BCE948FF2F433D58F19956A2A8FF50ED6
+:104D70003195C74FCC37E57B175D65AADF67F658DD
+:104D800053BEAFEF0653FDA4F269A6BCCE9792E4E2
+:104D90002731A076AEA9FDC0BA1253FD147F85F964
+:104DA000FD54BFF74856029E77947F696B9687BC87
+:104DB000AF6A1196915DEF90FC3A5ADE0799E85C74
+:104DC000C4EF916434FDCC0C8FFA8D8A732629468A
+:104DD000E1F724AE739BF96061A2393FDE95F72AB3
+:104DE000966E9C2B34FE28A8809E926AADA6EFF3A7
+:104DF000866A7C3457E4B29EFE5DEBEF1B625AFF7D
+:104E0000507C5D4E0FCFE705DDD29E6F9C17ECF90D
+:104E100046BCC09E6FCCC39E6FAC0F7BBEB11CF670
+:104E20007C6379C121331D8C3862A6832B8E9AE96D
+:104E300040A7CFD0F5BAB2D54C1FC2A7F8947FB027
+:104E40005E577F6AA69FD0F521098BD76F825311D9
+:104E50008FA4FCFBEBB52E64BD3AD787F00DF9F6B5
+:104E6000DAE050BE275B78481578B7E4516D9ED7DD
+:104E70000DADE527C3B65B7DBFE67DAED155435F83
+:104E800049571D879E0F071F7D34A4FFD7FBF902EA
+:104E9000A83F3BFE62B21DF4D12EDF456B031FEE2F
+:104EA000DD15B7497ABABC77F23395E3188E599A73
+:104EB00014F0EB8218DF36F0CB9BB36B15F8671359
+:104EC00045D18E4588CBF98FB064E4170C94F77701
+:104ED00045762BDF7FD0F9E282241917D83254F3BC
+:104EE000F37A64DCCEF343A5DD24CAE3E238E3E2DF
+:104EF0006C79BF83D499E40539C0C7E1F041C0475C
+:104F0000B385DF696CB5B9396EC4FF862AE0F783D3
+:104F10001C0BF9728026DF357CE47000FE41EB85C6
+:104F2000E99C1D1C7098E25B876E7399F2392D899C
+:104F3000A6FAC376BB4DE579C12C5379C1218F29DF
+:104F40003FE2C82853FD2B8E7A4DF92B5B279AEA56
+:104F50005FFD6991299F24DA1F067E072A528F3E42
+:104F6000333455E2C92D387E6FC19DB1F2DEA7A65C
+:104F70005FEB72BA1EF7ECD3E83954DE1F68F771A5
+:104F80001C75435FE1E17B180E4D9F12663DC0A783
+:104F9000C52D77DEA3F09BE396F578E54E7D41D3F2
+:104FA0000F7439DD10AFEC35C62B2F08EBFE3DE05A
+:104FB000FFD2D63D14FE817639DF869FDAF9DE888E
+:104FC0000E57283C33B538DA2D8EEEEFF5D8B225E2
+:104FD0009D256514FD1DF4FE98CDD3CA6FDD5F36A7
+:104FE0009EA7D54FF4D5F00BBB67A5FBBBC75B30C5
+:104FF0004CCE67BEC572F3D46C8ECF32BD83DF3B1F
+:105000005BEAFD51B94AB7F35B1023E3A7448CDD9B
+:105010000DFAED793C89CF44BB68E4FB475A9CFF0D
+:105020004D6B5BEE194445F3ED4DDA7B60011BE8F7
+:1050300061D25892C3F284D8B66557B393E4A2C73D
+:10504000EAAC6C3FE9BFDD358B24B8CEFB1B0349CE
+:10505000EF017D40B681BEB42147E571AEC19E1B14
+:1050600081FDF64D679C3DFB0584D0CE0BA94F75A5
+:10507000436F4C87FA3CFEAFE3ED43F1A4EBAD4246
+:105080008B334CD7E0D2F1D76977D0F0A7DF7F70B0
+:105090002FB3156D72F23D8A8988DBD2D7AF2547D1
+:1050A000D265AD860FD4033FEAA95EA19A1D03FB2A
+:1050B000728770C7B8BAA1433DFDBFC28B8EFF9EF9
+:1050C000EE57F5C41F42F9C277DDB7EA894EFFD922
+:1050D0007B57063E21E368B47509A45BD83F7D6722
+:1050E00094793F6FCC96768D71DABEA2F3DD996725
+:1050F000E61702F6F18655AAC62FE4395E9C52C423
+:10510000EF118B3A17CB33E51A2FD6CFD7850FC8BF
+:10511000F7E0AEF516255C45F992669BD848A015D8
+:10512000FBBB8FF366BF931B71FE9E44C0CD263739
+:105130001AB7B44909EC4FB9FCBDECC54EF97E5C19
+:10514000E8BBD98B35FD172F2A60DF86FA65EECFD5
+:10515000D6CE6B8FF07C2BE167BDA50B7E8DDE027A
+:10516000F21D31E8C3AAB4F3709C968E3737FC2445
+:10517000F15D79C26F4416CEF3466BB771749DF83A
+:10518000D5FD2A9D7EC2C31CAF1F1A1770D6FF4AD9
+:1051900074777E1ADD7FD3D33EE8F4DF7C875FA887
+:1051A000C369891E053E04FFBFDBE857F9F3488257
+:1051B00090FD2731F08FB46AFD898DB9DDDD4FF4A4
+:1051C000ADD8C5F110AB2CBEFF405CF219EA1FEF61
+:1051D000B0DEE53C9080FBF89334BBD3E5F3D6E436
+:1051E000B0D1F27E40875FE5F5EE9828EF73131F8C
+:1051F00015D877BA1F7FAA08F642AAFB497C6B46EE
+:1052000031FE753F49717014C339B361B10D4F4818
+:10521000B63E7C7B6184BBCB7FD23A40C6E7F4E4E8
+:1052200047997EC9C3FDCDB87415F7732C3B45CAA9
+:105230006B8DF72C039D0DD9266C9867ABADFBDF0A
+:1052400019989223F7D152F8D27B1BE27E5628ACF4
+:10525000072C57841E07C47C5ECF5F6CD2F2853268
+:105260007FCB2A996FD5DEC5DAAAD93B304FA498F7
+:105270000FF4F0ED9A3D04F3408A79E03BF81AF21E
+:10528000E06BC883AF210FBE86147C0DDF4B445109
+:10529000729E2AFD3DE30DFB03FE9EF106B909FE59
+:1052A0001E631EFE1E637DF87B8CE5F0F718CBE1D4
+:1052B000EF31E6E1EF31D687BFC79887BFC7581FE8
+:1052C000FE1E631EFE1E637DF87B8CE5F0F718CB97
+:1052D000E1EF31E6E1EF31D687BFC7587E739D62BB
+:1052E000F207DDACBD3B50BA3E8EE9A339B52829A3
+:1052F00087D6F73F23FFE7C7B654ACF3DE25FC6E35
+:1053000060558447AE73D344B9EE1621D7B97D0EEC
+:10531000AFF3ED76992F94F1C2A1F403BFCAF874EC
+:10532000E957410ABF0A52F85590C2AF32DE2AFD52
+:105330002A48E157C177F85590C2AF82147E15A470
+:10534000F0AB20855F0529FC2A6807BF0A52F85593
+:10535000F01D7E15A4F0ABE0FB318203FE151D2E7F
+:10536000C8F9E9263D94E8D0A487BA4C79C8F9C6B3
+:10537000FA90F38DE590F38DE590F38D79C8F9C639
+:10538000FA90F38DF91BF188716F29EF1BDB41DE79
+:1053900037E6739AFCAFC1863579C3F95791B646A3
+:1053A000298F292E92EB729E9A05FF586BB8921C9A
+:1053B000EB213976C56F678DBF92F889166F972BF1
+:1053C000DA2D586FF67BD3BAF98282E38373FE3B02
+:1053D00091CB757F2BFFD1BAE7ED14AC376CCB9036
+:1053E00070E9ED3DC2A522D5EB77E5BBAF173ABE1C
+:1053F0005E8FF9A5010E5228F310079177BB331F7A
+:10540000F1ED5B2D8A8C0B5D29E37243E9AA49E338
+:105410004B5B2D3B0E4450BBF662C5837B07995610
+:1054200071C8960F3CD5E6439EA8CB89D5E2836B25
+:10543000AF423C900EB76E7F243EC1F7DD46B70BFE
+:105440007B198D73CD17C28EDF5B986497F204DAF7
+:1054500041DF1CEA57BC9B0CF4BD32479E7B3EFFEC
+:10546000B2ABCAE8FBD0EDB557E11EDDA408D9EE1A
+:10547000378F47331EA7342A9BF0FEC9E8EDC28B55
+:10548000FBB1BFD4E01EBADD652FE3715D7CFF4E3A
+:10549000EFB7784332DF172C16ADE313D927A1F00D
+:1054A000FBE63ADE687EAF627EC4E20FC18EFC2F5F
+:1054B000DFC32171F1FBDCC3B966786C21E2DBC488
+:1054C0005EF90EE4E4E1C5AB7A135CBE807C07F2C2
+:1054D0009A2F6A5FE3FC66F90E2493CF48868FCF3C
+:1054E000C3417E85DFFF98E2DF68E9E5C6BDE015D0
+:1054F000B604D4DF2E3C500B060979AF559F57B642
+:1055000038620957402FE2957803FD11E798017A38
+:10551000C9F3D8F87D90A956970DFC4697738A5D1C
+:1055200072EC4275740CDFF70B91132E36F6E6B869
+:105530008D7F3D8EA483EF932FDF15CE72858FF87C
+:1055400007F8E6B93C197759B9ECC39196D4AE384F
+:1055500092D32981AD78DFF374EA8EE8510ACB113A
+:1055600087C05FDB1A9FE77B82C5AB5EE3FB10174A
+:105570001B1F8896F7AAA47FA54CC39B6E6F5AA8E1
+:10558000AD4F99163F74BC5EBECF4BE730BFF7718D
+:10559000B1D1C67246A8BC2884EB0F88732B6FB4B8
+:1055A000F1DDD3C56B8B57278AEE7E77C52BE3CF12
+:1055B000B5719734DA384EA85C7B472BF477589650
+:1055C0006A72E8D26DE6EF277242E44FFDFD44AD0A
+:1055D0004EF15BAFCC6439A8D6C671EEF35748B92B
+:1055E00048EC1001DC6798BF629C05EF58CCDFE502
+:1055F000F528DDD0D13B9A7C34098312DEA75E8A80
+:1056000060BE32ED523FCECFBA94C8E98D97B2E476
+:1056100077AC1DD14B6BA1BC5FFFBE2617CD441CE0
+:105620006501E4B23E4CD71D44D7182257E35743D7
+:10563000BCCA2B30C34FB2F956214E73D246C1F7C4
+:105640009126437EA282D990A70AB02F520AF93E32
+:10565000C64485EFB74C1EBE4CDB07B42F04F311D4
+:105660007EF7C3377E6A00F137B37D3B2C58777DD8
+:105670003FF8FC6DFC0EE664BF62C77B813E4DCFF8
+:10568000D6E93D745F2C88D4EC634E69FFEAB48F91
+:1056900001587E9C27F246C4B32E802DB39FB6B02E
+:1056A00084AAA86C599E9C1B79632394AC7FD36E0B
+:1056B00032DF6291F79F48FEE3787571A4B00FE581
+:1056C0008BD72AF98897D7E1FA7AD8D849C37A775D
+:1056D000D14149E7FECCEE03BD60F95D1926FF4CD0
+:1056E000685A4AF8C63E5A10D3FA63FCD2D0845C9A
+:1056F000E11D9F8877C8F5F98A20E202E76AF9DBA5
+:105700009EBDF28F6B9C8C27CE8FCDED7723E23F31
+:10571000FE65FE385FB11A7F37AA4DF17973E53D1A
+:10572000C80958DFC8EC767EC76066A64B9E2F215D
+:105730007696DB72DDF25D84107B4B69B63C6F843C
+:10574000D59D3C8FFD3A6EB657EAF33E6E33DF339C
+:10575000D5D3EA5C6937F8BFBA27F1A045DEFB7FF5
+:10576000C412D8F122D16BA0B76F01E6FB08E2BDED
+:10577000197E1FCF4F7F47A3934F69EF65E8F474FD
+:10578000ACEE22DF972871DADDAA819ECAD6287C8A
+:105790001FB1A44EDE27F6AD51E4BDFC1EEC578FC1
+:1057A000CFF99ADF517AFC1711B250C3EF7CFB910D
+:1057B000D71C295DF8FD53DDAF6C927F0633106F67
+:1057C0003FB7369CDF41FE7A58D18F017F64B687A0
+:1057D000D76912F134D49F1AE3FB29BE97882307B7
+:1057E000616F5CF0F3B7F87DE19ABD29FCEE61F1E1
+:1057F000EEBCD57847E5EB61BE3B72897E8B9D2E72
+:105800003BE490EAC6583E9717F4D1EEA98B76F6A2
+:10581000E7E9EBF360AE94078A3C729C0B9A3E4535
+:1058200008B34D35D593E77FE83ED4EDA2A1F695B8
+:10583000D0F72ABECB9E027B89DD6057D5ED31B60D
+:10584000ACE373709ECFB777FFBB8DAFEB76474D60
+:105850009F5DD8A9CF664FE803B97F9DE2821DBD49
+:10586000CCE9BE11F1F565876C88F01493E2DCF2A7
+:10587000DD92BBE4BB2525B7E6313F9B8F35C9C719
+:10588000BD8751BC8FCB0294C6F7BCDFE7AD7B650B
+:10589000C01ED053D0CBF7E0CB5C5E7B9C412E2A60
+:1058A0006D524CEF18E8F91773A51D723EA919C087
+:1058B000DF4DB7A6D8F186D07C128F1037F8BA46E4
+:1058C000277A3BAAC771259352C541F9AE14C19DF1
+:1058D00022C733FE4E514993F93D06AACF72DDFE31
+:1058E000DC28EEAFD845F34E41EA6238090F8CA7A9
+:1058F000F67BA83F378FC3EB511A0CD86037988FCF
+:105900007816CACF75056C18A7A451BE8FE25B2B21
+:10591000C7F1AD89B5E7402EB0BAEC038CF260A3B5
+:105920007CCF78BEF6FB11042FCBCB658427DCF34C
+:10593000D2EF7D86E2AB5883BFAC29D62C5F36AD63
+:10594000B3617DE6F4F05EC3971A1D97348EE1FBD8
+:10595000F565562FDF97F069F8FEEBB2F0BBE12753
+:1059600099D3FC902D05798D2F7D093CF7069E82F9
+:1059700019FC3ED2B2708E679EE36AE2F976E2FBD2
+:1059800001C20FE4155711E39BE8C48F38C0B2661B
+:10599000F3FA76C11325DF656F2EE6FDB7C8EAB3CB
+:1059A000BB8C70ACDF9F81FB5B7368DFE3FD27E19D
+:1059B000F2F17DCC530FDCC8BFFB063881E7288F9E
+:1059C0007B02DE3B22BA61BAD6E9674181DCCFFABD
+:1059D0007851C3ACD20E3FECBBF6A9F720E4F30636
+:1059E0005A6FD8FF7BDAA7765C00A471ED65F2DD13
+:1059F000BAD07DABEF577D9FEAFB56DFCF8FD98AB8
+:105A000082894A17DFA1F3BDF6B96EF03449837776
+:105A1000AEB6AE84D75785C1AE376298DCDFF3539C
+:105A2000CDFB1FFDA1DF54BD7C6C3003F73DF5FAC3
+:105A3000FAB8F3E3643BEC03D05BEA304B67FDE577
+:105A40005CDF62E21FA59DFC63FBAA04F08F1D0AC8
+:105A5000FBE196DF23E5BEE5CFC87BE16796BFF8A3
+:105A6000F62CAA77FAC18D0B8CF72FCA82925F2C85
+:105A700024790BFC6391260F6CCCF4E50D33ECE735
+:105A8000B2FB9FC9C4FE98DB92770A6FA8D1BCF91C
+:105A9000BDA33F3FF3D28757B9BBCE5D7D1E256BBB
+:105AA000DEB5153B8D7893F47E7756079F5BA5385E
+:105AB000B7E853696331F36191487A8FD2B5EEA1AB
+:105AC000F450DCA8B09C575A3732A0FE2FF2EBD22C
+:105AD000B553F98D287DBDF4775FF47357877FA6A2
+:105AE000B64E73357A9E3D4CEEC3B9E529F645BCFA
+:105AF000FF53ECF8BDCD395AF99C32F3F7CEF5726D
+:105B000075F2FBD5D827B89F84F5EA586B93F6CB8E
+:105B1000ED97AD5732E4021D8EC59A9D72A1666F56
+:105B20005CA4C9CBB45E8B8DEBB5F871B95EA5CF23
+:105B3000BEF517BC5346F3D3DEA393EF0A94B4EC3F
+:105B4000E0759BB3669D2D85EAFD64588A29FEA801
+:105B5000B436CF053BFDDC351B6DE0073F1926F160
+:105B6000164AF7F3B5F8621DAF388F14833F47AF7D
+:105B70000F3EB883C6B9755978B4F177ED021A3D76
+:105B800097D6C6C661BCD2DAE27BA17FE9E740E8DE
+:105B9000FE3B112EF74509F587FD79628C87EF559D
+:105BA000CFD77E372FB4FE431ADDFDDA26DFBF4C98
+:105BB0008A6C7992E33B6A223CE013E9E9AD018CFF
+:105BC0000B7A06DC768B7C2F33BDB2F573C041A215
+:105BD0003CC7F520C57B5B10ED1328BFC922EF79C8
+:105BE000A5AA32DDA7E107A637948B5EADFC1E5F48
+:105BF000E7BB5121F46A179BD7E0DD1F7B2FC1EF74
+:105C0000A6E9F4A9F7A3D3A74EBF3DCD6FD7F79C64
+:105C1000DF8914CDCE92E54976D0B80BEE1BC4BF18
+:105C20006BF15DF3B46BEF3576CE374CFEDEC765B6
+:105C3000F34D97FA52CFF36D2E4CE866BEA1F3D424
+:105C4000F7891E43DFE94F6992FE94130A9D63D4DE
+:105C5000EEC4B2708EABD3E7A5DBF5BFEFBD878F87
+:105C600086C569F6AAD628C897F3B5DF51114199C0
+:105C7000C7F7A986EFFAF9AFBF5FA7F3E993B5DAE3
+:105C8000F9285AEFC17E1675697C0FF558D389281B
+:105C9000BC1373628C844F6F77AB4DDE73165176F5
+:105CA00037DECFBBE9D63CFEBD94858D7D589FBDC8
+:105CB000A92E8DF9C24D7E581745A71EB048E38323
+:105CC00091B716AFBE02F5D7A7F0EFC22D747A4E8A
+:105CD000ADE7F6433D9013239BA7DA53591E96FA7E
+:105CE00082EE17BB5511457C4F0D7C12FBCBB23FAA
+:105CF0001DE7CFE2F5523F9864116BE03F1DD8508D
+:105D000034A12FF8C4C38AFC3D9A0DE6F7BC860E79
+:105D10002AFA027C26F45DBC5B6D2D5EE8A782E466
+:105D20000ED8D1163A8B589EBF45E393C79ADBF83D
+:105D3000BD7E1DAF8FE0BF78A72AC47E146A271AE4
+:105D4000A8D907FF1FAF8F7B3D0080000000000037
+:105D50001F8B08000000000000FFB57C0B5C546541
+:105D6000DAF87BCE992BCCC080C84512878B84850E
+:105D700034C080D7DA518150BBA0BBB9BA218E653F
+:105D8000CA650650DB5D77D7FE8CA1A6667DFA4515
+:105D9000A665ED80976AC376483428A8C90B99593F
+:105DA0007F62376A2FB9635BE62D40BAFCEDBF6DA9
+:105DB0007DCFF3BCE7301751DBFDBE6FFCF97B797B
+:105DC000DFF35E9FFBF3BCCF3963348C751B186324
+:105DD0002A8B8E413968488964998C8D09695F6185
+:105DE0004C89C3F625DB45C64640FB7C93C8621947
+:105DF0002BD731FA7D8FBF1F31761F3C37C3F3425B
+:105E0000A934D607FDD737CCA072C9D6C26DAEF182
+:105E10008C250925B1936360C0E36AB6078A25CE55
+:105E20001977302BCCD3A48DD225C373B52B29C7BA
+:105E3000E09F6F49E343490CC69D69D4CF77437B0C
+:105E400081694E41148C5FBA332A5B32FBFB5D6F74
+:105E500011181BC958A573461C4B61CCF1DDE167D5
+:105E60004CA9B01F98D304F37FE50977BBA08BA39F
+:105E7000AE2D4982233CAAB3A758A07F95D8316F95
+:105E800012CC734E70EF4DA0FEE63853C0FAA1E578
+:105E9000E93AC6CCE98C39FFCF8734CFE7E2893BBA
+:105EA00016C07887737F04CE53F5F81FF201326C69
+:105EB0009D68CFB2E4E1BC8D7B4D121C747B6356B0
+:105EC000099CE3BEC7C746DA332F9FF7B668B6A86A
+:105ED00004DACBDB18C157695FE88ED420DCED5EB5
+:105EE000A6316169629A6828CF486C9507CADB526F
+:105EF000D8A2B9067FBB0DE100EB9E89DC9254026B
+:105F0000ED157B9F48324379D6C8EBA57B7F7A9C01
+:105F10004540FFDD5A0DE2D5AE621A0B8CBBD7258A
+:105F2000D8DC50B2F268C61210A36E7D9991B159B7
+:105F300096709AAF627B0E63B9FE7DC1736A3FAB08
+:105F400062C5B88F31F503D9CBA1FC8BCA7B1FE2A8
+:105F5000F32FB57A8B2B19F16226BCFC658B548428
+:105F6000EDAEFB053656C0FA7E631AAC5F16C96A01
+:105F7000717CA1F4579B04CF571C10B2B5307B78CD
+:105F800066B7E61E039116D159B589D3D98A7675BD
+:105F90005122E07F458B402D0E9557331CBE2A2F92
+:105FA0004D66E680FD56B6B668CCB08EA319CE0914
+:105FB000FD1D9E539AA5785EB685B17CC027FE89EB
+:105FC000F86B3EA5B937003FD5AD1C2ECE56DEBED0
+:105FD0003803903B99B66213D2A0DE2650BD3E6BCB
+:105FE000C2FC35AAC07AFEFC3569589A084E4C3579
+:105FF000905402F0DC94D1A341FC3BD7CAF3425D3C
+:106000001DB05E0D12E548DE9E6AC0F1661AAF3C17
+:1060100077B646D178AF336C03BB0936516D50610A
+:1060200059EF344460B9B356CC50597173611609B5
+:10603000E0DF111691C52261CAAA5E3D4012503BB5
+:10604000705884F6DC48FB83489F710CB802E83333
+:1060500091790506F4DFDFF9592ECE7FCB18DF17D3
+:106060000CB6AE5E337D7E01D0C3268B7C8E4C5F3A
+:106070002ED2F1C84340AFB0BFA7D56C833E07CF47
+:1060800057C2E6423BCCC208CFDF84B9F7C0DFAFCE
+:10609000316F22CECF74DE541CF79ACCA7255AC399
+:1060A0000601F6F59B14FB63B88F3B05F5F86C1100
+:1060B00071208DC57EFD6AFE9C6D79C2A603FC4FE2
+:1060C000E7E867A345E66240A29A51F106A463C1DE
+:1060D0006663AB60FD07330FDDCB802E1E1ED03113
+:1060E0002D9CAF5ECFCF3D7D20EC9400FD468F2AE6
+:1060F000165916F437AB5829F43F94297A55D89F8E
+:10610000E9DCD89FE90A6DBE0C599681FCD0887AEB
+:106110001BF5EF78F31B01CA44E9E2E1483857E286
+:106120002F054B3DF4291B3CFDF4FF85B2F452537F
+:10613000CBEFA1FC75A4BD19517772B0F8941D5036
+:10614000F6B0C9A3B364F2F902F7DFF1AB6F22A294
+:1061500045FFBEFA074EEF7BD98AA5CE22C0B8E92B
+:106160001D92579B75F97EFAE361E3A9D48FE1395B
+:10617000FB0DA25B10B0FFE10F717FD37506AF146A
+:1061800081E3D4177C3AFF38661E1D75FA4646280F
+:10619000F83E91B158DC3C8C1FB8687037C1B96FBC
+:1061A00091F94FA1AF1E8B48F8E991F1A4C091E994
+:1061B000B222917EEBD58A5EF085B34C3F7FD6E864
+:1061C00038FF0C5E126D38FF60B9D6CD608AC18E83
+:1061D00054D2275792A77F0079CA40D7BC976AFB51
+:1061E00033C20FF94A07FC78970C2FC03FC3F9253B
+:1061F00079FEBB64B8DD6510399C7E120227996E6A
+:1062000014BA50F62F98635869B41F9FECD7DD4736
+:106210002393098FE3FF83E3EF13C2DF3727D60110
+:106220001BB151FF984578FC5FC09F57B4FE0BF837
+:10623000EB0EC59F577F3DE2EF71D1D284FC800801
+:10624000C8A1D226C2F9580623FE2F93C22C9BE088
+:106250007C76E4FF9B88EF8F22DF2BFC3EA6D837AD
+:106260001EF5E449C69EC17DF9440FB5A766A71087
+:106270009F5FC7BA13B01DF09C3717F12ED876E890
+:10628000242C7DFB5E86F55D1506CB1E386FBF5B4B
+:1062900074A961FE8628F78EA5B06EC35D991617A6
+:1062A000B63396D58672A03CCC827ABE218ACB8545
+:1062B0008605E9A4870F7E2725ADC2732C08B33469
+:1062C00041FF866CDF2313A0DE30D66C7141D757B7
+:1062D0000596BE1DC7CFD1D13A0D7338DD363C329D
+:1062E000DA8D7A05F4CFF37AA83F591EC6F09C0DDB
+:1062F0008DB68468A0CB9722ECA3B361FFA3244E94
+:10630000D70DC9D00EE536A164C17D38DF78BE6FE8
+:10631000DF82B017F7C22CFA341059D07E7295B1D3
+:1063200009E5A5429777A5737937C6756A07C2C98B
+:10633000359D65D4C2FC7F93E94B81BB60636C558E
+:10634000B41FFE0A9DC5C8701756737A734D97E542
+:10635000623573D70B085FE60B07F8966941414237
+:106360006934D9ADB8EFFAE5801709F7CFE17F526C
+:1063700064E59E61F8E747282CF3884C04E48F32EB
+:10638000C6F9A30CE908E96F15D05100FD31DF759E
+:1063900051A7C3653A82F16B8D25D370BDCF853F80
+:1063A000E463E3897F4AF3875B67563697030BF410
+:1063B000F699D89FED8E14515FAE30F1F54E647FA3
+:1063C000361AF5C5C95FBD791D96C7234A6ECB86BF
+:1063D000FEDB167C5D84E2FC6F093E359EE36F0BAD
+:1063E000FEFF68B443CA56BF49F4FE43F759281963
+:1063F00032504EAF047DA615B0E474B0F23E467440
+:1064000090C86A896EE365FD050CA3473975F300F2
+:10641000D88ECABCF0FF4797746C89CE5F9FC6A226
+:1064200082EA33740941FD0B4DC941CF6F8D1F17AF
+:10643000F47CA6393BA83E3B635250FFDB2DD38250
+:10644000EA774E9C19D47F8E6D4E50DDC64C241FCA
+:106450003AEA8A733F01BBE1B5BA92DC4F5497E345
+:1064600063AAF6D07EB305E824DB3B5F3509EA91E9
+:10647000875626437D53CB115E4F3CF44532E06690
+:1064800073CBD1F92AD0DB536F3CF4450AD41F6D8E
+:10649000E9E2CFA7C062A340ACB6BC39DF05F89AE9
+:1064A0009B62DF8AF89A77A9F6288AF9F7D7CCBDDC
+:1064B0002F5942B930677406EC2737C5FE103EBF2E
+:1064C0002BF69E759100FB1F7D5BAB463CBF985D34
+:1064D000B215E9A1FF22A7F353889791FF7E099691
+:1064E00003D9618A9CBD923C54F8AD03F4C61215E1
+:1064F000C24947A5B7CE44E5A1BA782A8FD499D925
+:10650000128063575D0695C7EA2CD47EBC6E229537
+:1065100027EA6C54BE5B574C65775D09950AFFB25C
+:10652000BD960D6A2442972AEAB4CE4F8F57D263A4
+:106530002028D969059FD0F94DBDAD399BCE759DF9
+:1065400009E959693FDAF9815904FA9D6AD5113D83
+:106550004F35749B75565E47B9B8FB22F38A11BC60
+:106560009F2AB05F8C271BFD98A90E03F54B1B8457
+:106570007E59D8EFCD0494F7536B3516B4639E5013
+:1065800033971EF66F14DF90701DE320CA6CD80598
+:1065900018D53A905771A06BF139F4633A28770F08
+:1065A000F2F54647D72E47F934BACC60A9E7F29501
+:1065B000E44BE2086F02EE2F71A586DA8D628F1927
+:1065C000E5605F9D7716D269812CE70A345CEF3075
+:1065D00011E4BD807CFB6D5722DAF3EDDC9E2FD0F9
+:1065E00096EC44FAAE5671FE65317AF71E5C47D5DB
+:1065F0005DF12CF4EB894DB46C4268C51F64696091
+:10660000B717D61467A2DCED615B88AFC15EFD13DE
+:10661000D2DB8F3381DF459948609EF8E2F0A64DCA
+:1066200002DAADD7E7215DCED59A0F30E0075FF6ED
+:1066300000D1FBDC48731E7A0ABEECAF793DCE7CFC
+:106640004080E7263630BF00EA55CFE94D9F04F081
+:10665000A9D3131554AF694B307D12C0A755F80765
+:10666000FA47B7092A94BB0E792BA704FB05C4B7D8
+:10667000B3F8730DDFDF8006EDD88BD966A26FB05B
+:106680009749EF0FCC34BA9B60BF71236AB357A010
+:10669000FD9469CEC37E49EA8108F463FABF5515BB
+:1066A000BBC9EF1988F8C9783F7D3DD321517B28BC
+:1066B000DDB5E6707FAF26CDB019F1501DAFD351D7
+:1066C000D971B188919D56928676B94DC3FDCBD0D4
+:1066D000F17B73B81E495EAF21B940A208B66C0BBE
+:1066E000634ADDC52632D6F88BB021BF07C0C93456
+:1066F00063653FC8356247415A507F1BF61F7A8E4B
+:10670000F61CF38F4F7949BB63AD4A5E0FE96529EB
+:1067100073A33F182AC7AB72A365B9C0F1FC748C90
+:10672000BE11F19C26017DE750C94C50268633B23C
+:1067300037135FD7BB913E77EB39FDA789BCDC2DC2
+:10674000F2FE9A30E6427A57FC874DB9F629B979BC
+:10675000348F97E6915AB291AE139887D657EC24AE
+:10676000A51FD8437A1202AA8174C4D754491C16B3
+:106770009E2772A615E58C44FEB0B14F03E4775F07
+:1067800078C4AA40FC55E37843E0B8E9344E19EFE9
+:106790005C25B24F47905C243A72A689E42F564B91
+:1067A000EC8880FE16EBD6A09E53C6F5821CFC1426
+:1067B000F0F047908B587E08F210D7FF33C8432C77
+:1067C000FF0AF210DB4F823CC4D207F210DB3F0617
+:1067D0007988E5BCBB8D56E49F9AB669ECD3207EE0
+:1067E00050DB7D01F5DE69C3D39143A6A3DEE4E16E
+:1067F0009FAFCBE17E45EF2D1C9FFDA0BFD1FF00D9
+:10680000BA5C6B8ABEB21EEF37B2F91E80D3B67C7B
+:106810006E87F427F0FAD21C35D56D22DB8EE3B7F4
+:10682000E56BF8FA2962393EB745F3797BD345B277
+:106830009FA64E9EB624079EDB62A13DC75FEFBDBB
+:10684000813FB78DE2ED437A567E3E25D7A4F8EF1F
+:10685000E9DC2F65642701BDD3FC4AFFF726723EB1
+:106860000CEDEF4E138BDDC3C0E32D996F892FD054
+:106870009E463E480EE08B6A33F18542870AFD55FD
+:10688000E57238A769653A07DD42F0431D83723A25
+:106890004E4FF625C0C5C6E03CBB05995F42F901E5
+:1068A0004AD4070A3F287CA0D07B22F09910ED3F04
+:1068B000C7CD21F4AA948FCAE7E88E35FE9CF0DAA2
+:1068C000A136A1DF7733CC87E313C5C177EF46FE4E
+:1068D0008C359AD1F52C7CC8503B9C1CEBFAEFC24E
+:1068E00043910B5780C76570D0F0F25F8503C939BB
+:1068F00094E348BFC3C8ADFD39D1B25DCEE9F744DA
+:106900008E6D1FD251BFA057A1DFD0AF67C3DAD9B8
+:10691000DBF2397F287454053A10EB8978CED4CB5A
+:10692000E59E729EA1732E6324FFD2C2787B289EBF
+:10693000957305C8BFC33901F11FC6B87D711DD855
+:1069400017E84F4DC935D33EFA477E56B695F9CF75
+:106950007F470E6F7F4A94881E14FD32D42E488BD9
+:10696000E66406E91D66423FAF534BFCEE057FE649
+:106970002518873E219BE43FBF20E37170FE58112C
+:10698000EDBBBEAF0D2ED4637DA3064E0A30BE6FA5
+:106990003B18366497D86E1340EFDE073A06F5D4FD
+:1069A00005907B2C9DB173721CA1CF73F124FA73F7
+:1069B000353B24A603504A3BBE9A87F4B4B4536DCA
+:1069C000A2B8D0F6C78E213D9E6E15CC6897F4B55F
+:1069D000C2F1A1BFB3C1E8D643FF22A863FF650699
+:1069E0008DDBCCD7A3F883435EEF537D750AC68554
+:1069F00066EC5013DC973E2FB9D13E3BBC7DA50A17
+:106A0000EBA7DD028B837145D2EAAE04A8573E2D79
+:106A100058B430CE61283A8BF182CAE799C50BF39E
+:106A200057B618C9CF5DDAA0FED817605F94BBB720
+:106A30006AD0EE29DF19DC5EB93BB80EF822F9EF17
+:106A40006886F600F9FC6D8E3186ECCD712C1BED5D
+:106A50004DD6C0E3B98A7CBFDC6E757139BA82CB82
+:106A60006DC6BE8C457F5FEAFC2AE96303AFCF9118
+:106A7000EBA7A0FEF9571C2F0A5CAAE5B53F4F60B3
+:106A8000560F9CB7BA536F42FFBFBAFDEF1118B74C
+:106A9000AF09F3517C9FBD2299D0DEDBD826B91017
+:106AA000BECE0EFD2E11E0567DE03D8DD988705F83
+:106AB0004EF6CAADCCB51EE3DC5E5164DD4447DD65
+:106AC00014A766B681A5384F5FBBDE847640F52BF0
+:106AD0001F74DD8DF50302D3231E47FB884E96EE0F
+:106AE0004086A52DDD26E4FBE94442BC229E3D9173
+:106AF00084AF658877C433E01DF12C213E71BC5111
+:106B0000E3E6742251FDF4731CBF0ADE8BA4CD1A98
+:106B10006CAF6CE4789EB163CFB630A2033593E9D5
+:106B200080F07E7A27C7BBA6739D6614D26F630878
+:106B30001DB46B87E800F777191D84E0BF02F08D64
+:106B40007220940E42F1DF93C3E506D8DFA79F427F
+:106B5000FBDB087E01F3C7234656F51E8D81F5CA7F
+:106B6000A2CF3B9743FBD8F89758DA088A7F15E401
+:106B700062FC6BE63BEB105D3DB35EC8467AA957FD
+:106B8000FBF63C81718BA8708AE3F427CFD9F932E8
+:106B90009CBB20FA9BA416D87FCD6B5ABADE28C9BD
+:106BA0001587EC358C9729F174C033C5C99C1D5AE3
+:106BB0001E176B2DB405FA73FD09FC5C859A81B232
+:106BC000E5E817C07CB88E60E37E5E55078F172816
+:106BD0007E59951237680E8E1B08A677A85F452E42
+:106BE0008F5FA5C6DD6C463BBC7E01B387A55E4DBD
+:106BF0003FF078CCD3B2DF7445FBF10A7A42B11B87
+:106C0000992B386EA1C8A96513F91E8FFEE2B86AE8
+:106C100004C6FD760B848F8A0E904F70DE0AB7DAB9
+:106C20006D1602F849EEFF19D21BC0ED8CABF6A031
+:106C30002821DD1968BF0E993EAB918EE0BC95D638
+:106C40003722F09C0E59AE38DA8D147FAB645B8A24
+:106C500090EE2A613DEF30F454F95C0BF929D7A28C
+:106C600027C5CEAC6E0DEEB7317748CE8CFF1EE057
+:106C7000BB016439D77B2E99FE3223F1DE6F9099E8
+:106C800023919F87F49FC0ED3745FE5CBF1D583CA4
+:106C900060DE716E1D5305AC7FE373A6A0FA784FDA
+:106CA0007C50FF9BDACC41CFB3BD1941CF738F59D4
+:106CB00082EA79DD1383FA4FF8D016549FE42B0E45
+:106CC000EA3FE54C49507D3013CE7395FBC15BE341
+:106CD00085A0FE33CDFAA0F967674405D5070D32CC
+:106CE0007C64BB52B1775FCEE5F66E68A9C0F776DB
+:106CF0004BF03A8ABF7EE7C4E0F5E6D882D7FBA125
+:106D000078D90BFA54057EC273A05FB1FC1DF8134D
+:106D10002AF0139AC19FC0FA8BE04F60E9017F020D
+:106D2000DB5F027F02EBADE04F60FD20F83F586F64
+:106D3000AB2BA6F295BA126ABF16FCBAE4758FC9DE
+:106D4000EB1E97D7FD77E174429EEF5D79BE6E9C96
+:106D50002FCDFFDC593C56BC04FC3C2DFAACC68759
+:106D60007EC30A5F11C62D06DE9218C6A599DD7D89
+:106D7000AC2E06F5D9088A33B39281B731AE527D75
+:106D800020D5B4C98CFAEC0FEFE2F3BE56C98C7C67
+:106D900079A8EDEF1138CF854B61745F4A7A10EF17
+:106DA0001BBF6154DF04CF310E3AB3050408E93745
+:106DB0000FE9B70B694ADD4DF7BD25CD2D1AC45338
+:106DC00015F2293C7FCBA30E7EFE5C63D07313F6D5
+:106DD00087B24AE5A638C2B936653E2FF577A4F1E9
+:106DE0007BCF73CF1D5E3F05F56FCBE211787F5EE1
+:106DF000D5FC5EECBD57C1C7E7075FC8A4FBCA76E8
+:106E000098CFE09FCFD9AE96EB7CFF8EB496A26868
+:106E1000541CCD021B0BC505B685EE5FAADAF63809
+:106E2000506E5565DCAD66009F7E8F24C737F8BD78
+:106E300091C3C4B81DE7F92202EF575FF71CBDC329
+:106E400086F8ED381C81EBF6B74A41FED3682BB7C4
+:106E50008F475B3584BF0BAD8723F05E77A3E730A8
+:106E600087BBCA4BE73F24D7FBA12478B74974FE00
+:106E70008A4B62D03D768655A27966B68D35E2B9E9
+:106E80007A3C7CBD1CAB99B7A72D5E82FB3F1EBF31
+:106E9000204F227B100435CAF11B66EF413BA4CA88
+:106EA00023D986F3EF0AE479BBD49C4EDF4ADBDFBB
+:106EB00085F2F878F1886CD2118A9F69E5766F9136
+:106EC000C69E867AA4C76036229D3F589C6A44FCC1
+:106ED0001EC212DB8B7769EC06BCC7E6EBF598BAED
+:106EE0002390EE7A5A7325B47794F9F2E57587E822
+:106EF0007B086F2EC253B9BBD180F3F8F1C7DB73A7
+:106F0000AC26EA7FDCFDDE3CB4AB7A32C2C92EE9A6
+:106F1000D230F2A7AB9AB95DDCD391D818784F92F2
+:106F20006395FDF20C91F0DAD7A696FBDDBD8705DF
+:106F3000F553D3392FEC0EDE8FC97DEA51B4C71D4E
+:106F40004F4B0CF5A2435D1B8BE7FF6C67F0FECA4D
+:106F500065383BD4DED8D8007A75B40FF18D81E85E
+:106F6000BC5DE11333E153C1634F06B7E77AE2F941
+:106F7000BDA4A3650FD1F5E5F1A4EE64F41F127F63
+:106F8000A9A378E7B5FC67C56E08F0AF18FA8BEADD
+:106F9000E2D43C31C56F1FBC966BABB68E44BFAB21
+:106FA00084FCCA1E06F62CACE9447B3A92F21FB66A
+:106FB000E1BA83AD6ABABF76EADA667D0276D9A015
+:106FC000051805F63DB8532DDF7BD90C68D72E95F3
+:106FD000EDDACFCCF67C09F4AF738D48E7736486A5
+:106FE000911FD327CBBDCF5B92EF24BBE1986442C6
+:106FF0007F688687DBC18E666ED7567B92FF632AD9
+:10700000DAEDCD6ACCD4608A1DE294ED90D3B2DD86
+:107010007B7ACD8086FC9B4E813D968C792A5BBB2A
+:1070200012E1B9337316D9B34EA999EC8965DB83A4
+:10703000ED07B06F82EA55CF85DA17727CCB13DC8F
+:10704000AEF887DBAC4376C638F4670AA5A971C8E9
+:107050000F2FC87855FC9B95E32D94B7B351659ECF
+:10706000A5C421105E359DFB2B70DF6E479885FC13
+:107070008D55AF105CFBBFE47E4C7F3C2378F4332E
+:107080000EDFFE364EE7356AC18DF9483540B6341D
+:107090009F4E70AFC138B36B3082E41363C5C8171D
+:1070A0002B16707FD586315F286B157E08D1ABB764
+:1070B000A87C5254809C68B3A650BF020DB3A33E77
+:1070C0005B69B4907E1BA3E3767AE16A4F36D2C344
+:1070D00018F0C7B501F1F831860101FBED7E80C7DC
+:1070E000FF9578C21C95491D15A01F195B43FD959E
+:1070F000F941A2F0F1D79ADF04F31BFCF303BC23A0
+:1071000011DE5F582DA4B793E628F7FFB5C497CAE0
+:10711000792E00BD611C1863348837C7CE37C89FED
+:1071200073B2EEF538AE2882EFA308F783F5305E30
+:10713000FE5196E7B179BCBC4D2E15F9D590677B11
+:10714000DF0AF59579F63F5949AE99883E57CAB49A
+:1071500002F64C9C6F18F9BBE21D89F0FA05F003AA
+:10716000F2FBC25AC19C16642F713AAFE14DEC3C60
+:10717000F3F44E4538B86CDD1998D7C6387F2D5AD0
+:10718000A537A705DE0720BDA3FF5102FFF2D12FCF
+:10719000E3BF7253C56D9457B52AD68CF71735C81F
+:1071A0000F29D7A6FF50BA87DF4EA4B76AA6B5A0AD
+:1071B0007EA9690B7D6E51A13DFE4D085F24C97407
+:1071C000DA6817E87EBDF15B158FA3950A1437BB0B
+:1071D0000B1A914EE987FDCAA7B9717ECCB3A0FB0B
+:1071E000AE861839EF2B86EEE17E229FFF2E95F7B3
+:1071F0000DE4EFA36A4F32C6718E3AF93DD502E62F
+:10720000A17BDD52D64D656F78F5012F4DEE1A8DBD
+:107210007EF807762DC5911AD7361951CE66B1B5CD
+:1072200026BC1F033679EEFBDC2BDB1BA1F7689431
+:107230009F95E7C7F3CABC92F83CA0833380A3F8BC
+:107240009CCBC757BD7F2002E17EFEFEFDF37ECAC8
+:10725000D00F02B905F354D6B664D0BD8C8B7567D8
+:10726000E4FBF1ABE053C11FB49983F00A67B90E98
+:10727000E0339F0DE4636ED3B5F0A9C039493DF00A
+:10728000630425E8319243A17856E05ECD6AD53C8F
+:10729000FE56FBEE02E8FFB3B5A219EDCACBF07EB5
+:1072A0000DFC78F5FC91D728903F7B257C29785AF6
+:1072B000C8BC54FF308A8FFB70A144F1C3FF697CC6
+:1072C00035E4D94BF2AEC2B7A17C7A25BE5CB42AB4
+:1072D000847F43F874882F2DF02F007FF65511C45A
+:1072E0008F0A7E1D66F09351FF75182D6E76393E1C
+:1072F000D1DFC5FD54B60AEC49E187F0AB8FFCE362
+:10730000507C01ADD8501F54E705F3A982C72BC9A3
+:107310002D45EE7DC4BC474D02DD67703EFE85966F
+:10732000F2E994FB0CE5DEE2D13CAE6F42CB8FC0BC
+:107330006EC17BA24D193D23D1DEEBD528F3F07B46
+:10734000D78FD6748FC67CCD8FA6F1B257C3F34CBE
+:1073500094BA2D8CC7033F4AD0BA106E1F09E3A61A
+:10736000A31DF091F0CB3B783D4E63C6FA82B8E99D
+:1073700026A8F7AA95F8E183B2FC7653F9D18209E1
+:1073800005D44F6047101E668195D03A82105D0C7F
+:10739000FBF9E8E76373F05E4039FF03793C8EF454
+:1073A0001BF91C43F1F65F09146F5F04AAC384F74D
+:1073B00002D39F284E81F693BF4ECDA6FBCA15C1BE
+:1073C000EBA3FE4DA638E5569AE7964B03EAC5991E
+:1073D000FE7D0DE9CD828BBC7DC9D8A07C665BF4B7
+:1073E00038EE27BB5323518F297A6DF0D87E436046
+:1073F0001CF5AC1C771EAA8F7B2429502FBEB1F739
+:10740000E1749CA75CE3CAB218308FF9A924B41FB9
+:10741000CAF73E944E76EDDE8DE9E89F94373D9CA9
+:107420006EA37AB89DFC23153FF7F97D93766D0A1C
+:10743000B0A36F9DC0EDFB52DD1B8568DFCEBAF1B6
+:10744000F37518B71FFB6B81E2700B59F73AD4B78D
+:1074500065199CAF58838EE43FCC47F7A47BC6DD0B
+:10746000BE1BE5FEF18CBFAB97A0FECD53D17C6572
+:10747000CCBD390EE36F1B048ABFF9FB8FA67BD707
+:10748000C56B054D7C0CEA519E77FDC7BC2882E395
+:107490003D1BB2BBB0BD6C356F9FA575B7F6E03C28
+:1074A0004F6828CF0A14654A49C03DF61FF3F83DDE
+:1074B000DDA2CD72BEB1BCCED86DB18D81E7FCA38B
+:1074C0008C7F56FE01C9833B65BCDCB6FABD23F157
+:1074D000306FA4DAFE67942BEF3E7E3A0DE55941FA
+:1074E000F4D94CA4F3B11AFB931578EE262DC52BD5
+:1074F000AD5989521CF4CFB97FDA63582E5ABDF8C2
+:10750000C90A8CFB6ED7911FA6EC6F856016D15F00
+:107510003DDCF8D37B106E671EE779A42B1AAF8F82
+:10752000BB5AFEE2B3753C1FFCF93A1D952FD49966
+:1075300098198EB8AF2E9EEABFAF3353C9E673FADF
+:1075400052F2A6AE345FEEA530CA5BB66ED0511EC5
+:107550007DAED6F6551EC06BEC0DCEA68DF2B9C62B
+:10756000C2F86C57F20C848375E3F22E34614FE558
+:1075700071FFEAED9E0D496487AF3EF54C053CCFA7
+:10758000CC2FF90EC7EB765EA478C1E1F687CA105E
+:10759000DEE54D5A7E3EF9DC671E4F8F7B12E3BC61
+:1075A0006FA9C97FAFD979EA998D50DEBB79B92629
+:1075B00090DE7FE879BF95F7732DBEBA121CFE7579
+:1075C000BE7A3889F8A709F82AF3DFE7AB9AD56BBA
+:1075D000087E73F34BC6E6C3FECFA85D49C84F676C
+:1075E000C6DD4C74EEEA1408FE8A1C57C6A7E6F303
+:1075F000FBE82AD1B399EC48598E7F059E23C2F748
+:107600008DF6CFD2D18EFEAA6DC155CF7DB00E3D85
+:10761000228C9BE9A80C7D9EAFB1A7625E71BEC8AB
+:10762000EDE7D0E7B7E72B71781EB7C59F1090A79D
+:10763000E2848D4546A3FE13BC6120979D6DB79EE5
+:1076400055A1FF067EE1C7C17628FB3840AF5F69D0
+:10765000BFD72AAB711E955FEE4EF85064DE003D39
+:107660003EC917C6BC01EB0EF92BD0A6A1FB9E04A8
+:10767000920B8837CC87EA6B1FD784F5B31A8EC775
+:10768000BE83E097F1B80C93F2FDE73CDB7E3E0B46
+:10769000E56CE879AB5F394FF4E1687BE8A240E73D
+:1076A0009F79569575EDF3BFB1F77C16E2EFACDA32
+:1076B000978FFE579FC6978578A87E95CBF37F1549
+:1076C0000E4A7BC5060D8F130A26F2230BA50B1459
+:1076D00007E83BC6E300D5EDBB489E0E76F0784C3C
+:1076E0008DD85D1487F18BDA535D28CF06E3B95F3F
+:1076F00006F3DB28CF2155D683AA81A43920D71ED3
+:1077000019A207EE0F9E41FED5E03C1E07E561651C
+:107710008533B42BCE213F437BD9AAE4F548E767F4
+:10772000DC2373503EBE9DF58F6A8ADFBD1E6E92CC
+:10773000C88E9530C778084E43E7704B3CD18729F7
+:10774000767138B305F4ABD198EF24BFFA38BF9FF8
+:10775000ABB981F3137B85F39373ED1B9AF880F932
+:107760007E25F393624FCE7AFD1FC4970FE7DA9E12
+:1077700040BE0C475988F3C547521EB5F21E8772AA
+:107780001F69E890FDF862899ED7B4490CEFE5586F
+:10779000BC91F20A8AD916CAB79CC53C53795E8F50
+:1077A000EFD129F07CF6EB522EE6A1813D4DF7DBBF
+:1077B0004561F634CCD3EA150519AE1EEB9C007D6D
+:1077C000F67E3EF757A74A02E9B1818470B253664C
+:1077D000CE7796E27E957E5A91EB339887EC2CE635
+:1077E0001EC8C27B55E61DC8C2FB56A5DFBCD7C369
+:1077F0006B492F328F755EC03AA7F379BCF30BBC8F
+:107800001F07795223DFC3164ADF6E437F6B45277C
+:10781000BF7FEC15933FC03C3317C019F17A1EF0BF
+:107820006A43FD6367361BF2CFF8916EE49F9A7D41
+:1078300002C37CBDEA766D13C685AAD5BE58A4E7FF
+:107840008D6DEF6B909E6BF05E763C8E6772BCDC4C
+:107850004479BF3526C6EFF5DAAEFF00E376CE6396
+:107860005C8B3A55EF513C00E536AE57D5DA42FE17
+:10787000BF8379C9FF773407D3CD603C8FE787F2A8
+:10788000C9E97C73107FCCDCCEF9631EE6731B68FC
+:1078900038C55F67C6C7915DE21FC7F16093CEAF81
+:1078A000433BA63F45A07CFCFE30D75AB48F5CE931
+:1078B000DCAEE97FED052BBDF7A3735B7F8CF93C54
+:1078C000B2DD3B73C3569514B09F991D3CDED81FA3
+:1078D000C6CA0F12DEEDD7213E7CB92567F231BE54
+:1078E000A31978770AC683441E1F0D3D875D8E6BF2
+:1078F0001C67FCFD2865DFB31313B93C636EA2A3BC
+:107900002E39BF5BC9D751C6DF324150EED1B89F87
+:107910002458AEFA5E1ADED7609E2BDED760F93BA4
+:10792000391F16EF6BB0FEA29C0F8BF735D88EF780
+:1079300035586F95F361F1BE06EB785F83E52B72E6
+:107940003EEC71DC2AE5F16D7C0AE9A20B796D94BD
+:10795000BFDE1B1D521F15DCBF375A08AE8F12A8A1
+:10796000BF69C2C6A730FF7893922FC5CC46B4C377
+:107970002AC2F9FB1AA9067BEC04F4F38B77ED45D8
+:107980007F1EF89BDE9F2B885E504AEF97C46819D4
+:10799000CAA3DB27D8474F80F1C78ECD48DB4A7298
+:1079A000524FF7ECBD3FBB3192E27A6F494C8225D2
+:1079B000A765E4AEB5427D9A4120FA85F96E2A5159
+:1079C000FC4C986746C762AB8ACB0713DACB85922B
+:1079D0006309AEB322419F8B72F888D59E81FB511B
+:1079E000E05D346A591ADA455D6AF307189F75BD80
+:1079F000A366E85729713CA5DF93D669F9B8BF990A
+:107A000019A96B73707E60369477360D6BC6FDD9FD
+:107A1000C470A19EE4975985F2207F02A79BE96676
+:107A20006E1F7B35665534FAF561D362F05EB74B55
+:107A3000C6F33119CFC7653CE33D57818ADF7361D7
+:107A400089F75C5886E6A32DCF2FB14D20780F24FF
+:107A500005E6B3CD92DF97000AA1F7D49C721CF320
+:107A60004B59EE34E695DCCAC779689E2A398E7781
+:107A70005E1D7C6FA88CF38F6754CEBD89CB6B16CF
+:107A8000A9E179BFD73117E615CF7D3981E2507D65
+:107A90006ED1A506BCCF055E4779C65EE6FE2E8B8D
+:107AA000E77C33777F1CF5AB97E3A9CEE8EE747CD7
+:107AB000AFA34FE62FA57EF03B9E97E4CC81BA8121
+:107AC000DE23A1F339E776A74741BD4FD08B485F4E
+:107AD000CE26FEBC47E63F678A3C9F7C1EA6F32469
+:107AE000213EFA3B5F4EC2F7103719BC4BB9FCF789
+:107AF000A693DC66DE74CC6F3A2F784E62BEF1AD91
+:107B00006D29A5986F7F5EED7906EBB3DBD2785DCA
+:107B10006839690A7C3ED29384F9C8B7B6A59662E3
+:107B20003EF2F9912DCF445902EAEA974EE273CD25
+:107B30008369A5989F3C5BEB3E568774F37B4E5F51
+:107B4000FA7D074E237CAADAB9FD3E7DDF810B2F3B
+:107B5000A17E3E60A4BC8275139209DFF5EDCF6E65
+:107B6000467AEB6B51133F6C6A7EFF99DF503F2DD5
+:107B70008559666B3D560CC994B41DBA1BF7353B4D
+:107B8000DCF325D6174FBC89F6317B04E7EBA51350
+:107B9000734A914FFB0EECFB05EAB3D99160D8E232
+:107BA0007E5ED0137E2AF78F2BC0B8409FB1BB0CEE
+:107BB000E7AFFE9D96E71FEC8F9B8E7182FF9CC006
+:107BC000F3312A6ED89284FA567CE5F9BDBFC1F82C
+:107BD000E6EFF474DF5313CDEDBD4AA9317F39E1EF
+:107BE0006FD75ECC5BE97B5E4FF7AF151893B3E2BE
+:107BF0007BAC63293EFFEA3FFF5E8678289476EEF1
+:107C0000C5F62F77EB4584438FC6167933F2618F23
+:107C10009AFCCE0AB95ED13B82EF27DC5744F88B41
+:107C2000D99284FAB672C4AFEEC07DCF96B63C83CB
+:107C30007E0F7B564B770E679F07B8C1B8B37BD4D6
+:107C4000984903FB30AA905ECE0B5BCA9EC4F9F73D
+:107C5000F07EE7F55B089EAE3DD7335C0FFA31D47A
+:107C6000C7E785AD41ED67F73C9B857EE9B9DFCD80
+:107C700026FF54A173855F2A776B83F422498258CB
+:107C80008C5BCA3F938B1902E259E70EEEE87B92B8
+:107C9000F9C79F6B567B3500A30A2D5B8BF9CD0A84
+:107CA0003F5426DE5A8CE7AB141BD3D17EA9C8F50E
+:107CB00095215F9CD5335D3CF47B5BD65B95AD6BCA
+:107CC000E6A01D7CA5FDFC4596475FC97CF8559B49
+:107CD000DE1D78DF185AFEB58E994FA8FCF585B5E4
+:107CE0005AB2E595F9DED6781CE8AF554773F971BD
+:107CF00012FA37831CFB93ACEF16AD0AEEFFEE04CD
+:107D00009E4F59ADF1A5A3FE53E67F7B8289DB87A9
+:107D10002A5F3ACAABD071B32559DEBC2090BCA90A
+:107D20006C154ED1FB2408D2583F3C2B752E37E6FC
+:107D3000130D8787F87C190F12E6F170BEAA6CD676
+:107D4000DBF4304F55982F02ED2587D117817650FF
+:107D5000DF2B126B92D117A3CC9FE25F4F89535652
+:107D600078D436FD70EBC171D04F5E867F03285604
+:107D70004FE47C53DE164EEB31932F1FE9B67C6740
+:107D8000F0383CA729801FFBDA76C506FAEB0CF722
+:107D90004DF751A7886FFAFFF931BD075E29B2B5DB
+:107DA000784F794EE0EF83409DDE073927DF775625
+:107DB0007E6D0843FA39F79583F8B84FF0919C7BB4
+:107DC000B1CD4672AC4FED2339B76B6211AF47F9B5
+:107DD000CA506EBD38F1A7243FFA127C65F89ED2D6
+:107DE00066A58E2FCC811DD0D1B690E4C96C89E7F1
+:107DF00051B05D6A138F1371782F93E1C4D886DE7A
+:107E00003AF243D466B4973A272AF7421AFFF92583
+:107E10003F3FF531F3BE56E4CF7203C57DC0BE6A65
+:107E20007E09EDC005B1168CA787C24DB95F8C895C
+:107E3000FE6629E2E91DA37DECC43CBCCFF4919F12
+:107E400001D44EF67CF56B5AF237FBD5037B517E9D
+:107E5000B98DF67113019E0E4DF77A547117D4BE89
+:107E60002E34ED6721BD911CE1F4D697B98BBF0785
+:107E700022DF4F4E92F100FA8C35227D081CCF870D
+:107E8000DBF69F4079D3D79D4A723A949FCEB63D98
+:107E9000168172E343D0EFAE8078C0878B9FA57CBC
+:107EA00080F9980702E53D6B83CF37F8ED8FC92F36
+:107EB000649B03DA911E1B82EBA17041BAF406F1B8
+:107EC000818BF67D3FF21BC0A76A7A7735C261A825
+:107ED0003E17EA5240FD50483DA43F2BE1F6C3FD5A
+:107EE0001318CDEB18EDED253F7E1FCFEFAD07BD8D
+:107EF00046F503E1743F2DEE03BD15C3F516EA8B7D
+:107F0000AA886E8A5FF51DD0D2BDCA83ED9F25E198
+:107F1000F9811E294E53D5FE722CFAF7EB2698698B
+:107F20007ED08FB1941773A03D16FD11A5DD217A87
+:107F3000D2E5F70CB2507E28ED4EC99B4E79E54252
+:107F400077163E5F27CB1987087509EB8CCEE110B9
+:107F500038DFB37689E47C28DE56C9F40AF2218B37
+:107F6000F2395EE1F103451E54C872E510B667723E
+:107F7000FE3729F75278CF847C3F8C9CF85A8123B6
+:107F8000ABA5F8CEFD13CDBC2E8FA77979FC89E780
+:107F9000EDBD7A3E2B2513C79995F745FDF228D5FF
+:107FA0002F5F500EC4931C78501D0BE7AA7C46B07F
+:107FB000D4C3908AD23545D09D2D532D2FA2B81A07
+:107FC000E6E71A2EDF57281D454EE4F8AD14B91F19
+:107FD0005EB957A0FBA5736A7E6F07F286DE0F5865
+:107FE00056B0A608F9EFBE18A726D05FBED6FC4B48
+:107FF0001B82EBCB6AD714C50DC3E795ABB6768D64
+:108000006497CF57616F2C8A355FDEAEECFB9C5EC8
+:10801000D9E774F5C84078CC5F533412CA65BA7F8B
+:10802000171EFCDCE7DAB55ECA572D5D43F7C4B70F
+:108030005CAA0D8AB35E6BBE0AE6A67B902BED3F71
+:10804000B47408DE5E8C2B31E0AF3DC467C03701ED
+:10805000EBC5CBF43A149F285F3C06FD53665F3CAA
+:1080600026303E115AE29B3322E58AB8A8043E2C02
+:10807000B30C030FA5FFD1893CCE1A3F91D3F1A8D1
+:10808000D9553B5E6214D7E941F97BA5F74CFE2236
+:10809000EFEF07BF6732239CF7EBD49B30FED3DFB3
+:1080A000F90DC587FBD719E6F37B07034B80E75D26
+:1080B000F1E39B02E3C0AB26713B24DCCAED9D9A41
+:1080C0000CF5D5E34B99C6A1F812D91B99E174DFE1
+:1080D000D2D7F605E9B7FE8E3C13DE8BF475BB0DE7
+:1080E000C86F35FFFC7FB1A887FB3A3EA5BCB4BE84
+:1080F0006F3FA37CB58D72DEE0A13639DFABDB6C60
+:10810000C4F6FEE2BF1761BF4D72E98F2FF0F898F9
+:10811000522AF18300FFF93BD4537B4C1B1FC554FB
+:1081200099CAB02D24BFC07F8E46BDE18F2B98E346
+:10813000868BC304C615D2543CAE8025C615D2D258
+:10814000785C01EB1857C012E30AD88E7105AC6356
+:108150005C01EB1857C03AC615B0C4B802B67F2907
+:10816000BFE7D10F828BC73D0D24F757627E33C026
+:108170006F6527BFBF5AB947A27B617CCF03F5DF8C
+:1081800065793BAD72DE8E672BDD07D61C902C889F
+:10819000227C1FC4958EF93B0347311E54D32258CD
+:1081A000D698B17D3EED636347DE07A5D8BE476D27
+:1081B00011CD444F1C9F8D825B8F7CD5B187E257D8
+:1081C00005719D94EF5FD32C308CBBCED3723FD919
+:1081D00029416B0EDDAB921DEDD47693FF52F59CD9
+:1081E000600E7CEFBB66E2459213CA7DF552FE88B5
+:1081F000393D7AF392203D6BE37957F827ECC72994
+:10820000E777931D1260172DC57B6C6C97BEA5F7A1
+:108210004D9CE0E08E10AE9D7755D9D1B21EF3B5DE
+:108220007E68FE55E124F9DE3A9BBF4752FCF89286
+:108230007D0760BDC12D5AB2536E9F60BF6D521E47
+:10824000E619D828EE72B4534F7ED6275BAF0F8A5B
+:10825000BB144AD751DC63855A20FD7DC46A9F3B1D
+:1082600009E87246F1BD146F99116F243E56E8F08B
+:10827000496BC94F70DE15E3F977980AB5ECE7341E
+:108280009F9CCFA5E0A9B05E70E3F72C16330BBD21
+:108290003FB008C0877151E5FB1F8B18CFAF50E886
+:1082A0006AC55681E88ABEBC10F0BD8445F83D1011
+:1082B000D07FF76AB9FD9B28F27BF2C44D3C8FE278
+:1082C0003E66A7FC9165487D12E9D7D77CD06E0F3A
+:1082D000BF2E89DBF7E6389C7FF17135E50717C6BD
+:1082E000DD9E6E273D5F40F91382F76EE9FB1BAF01
+:1082F000263F83F3278EAAB9DC0178929FD585F4B7
+:108300004AF11E3B95C7EBCAA99C22BF1F16FA5E15
+:10831000437FE7CB2D38BEB0C66041F85FF13DC06A
+:10832000B0ABBFFFE694F3EB12C59E5C33C2E36BC8
+:108330008305E15118D749EF89A5CAF33F9C5BB289
+:1083400009F1698B602E5C1FEF69B6007C8BF040F1
+:1083500002C6D13D367CCF66A05330513EF56572E2
+:1083600074EB3ACC53A949134C18AF2D0ADB5218C1
+:108370000BF317A524D377766ADA781CB60F4A4E2A
+:108380000753DC92C0C7AA62317ECFF1E8CBB53F7C
+:108390003D29CFDF3E5BE6B3FE8E2F781EF1B5E3BD
+:1083A000B4BBE9FB1C4C4FEFAFD30FF635FBC6D186
+:1083B00014AF55E868B039AE09E9A845D613A5A5AC
+:1083C000EFA9D18E68CCB337231CCA965C5C174BDF
+:1083D000E71C3E4EA6E4DF87C6C902E5EDFF46DE98
+:1083E000FD89BA5A2ADFAD5B4565779D8B9E07E80C
+:1083F0008B2308BF1F106F7D7BD230F156A6334709
+:1084000092BE05BEE7F1ED90F82AF0BB18C0EF333D
+:108410003AA2EED980F64883C682F7CD98FFBCD247
+:1084200040F2E1FD49C3C65915F819282E3BC8F49E
+:10843000398887E919A92A119EFF6D921014E74423
+:10844000BEC17322DF60897CA352F9F9E6690DA3EE
+:10845000EF94A17DE022FB404FF85DBF06E40AD413
+:10846000EF65A620B9722144AE8023F3337A5FAC66
+:1084700043CB3609FEFCCFE9505CCA1946CE78B82A
+:108480009C191DE6799EBEB3501D46F9C5C0EF4448
+:10849000674737F2BCBD25AC84D61D46DED07B3E97
+:1084A000F78E1838F914F4BFF76103D939EB139636
+:1084B000E6FF77E4CD9F2771783C81DF73505DED57
+:1084C0007B0E9B05BC8F5DB1906523BE95EF39C4D3
+:1084D000C118F27BFFF5EF398C983C12BFE7E00A38
+:1084E000FA9E43DC15BEE7306AB27161E0F71C46C4
+:1084F0004D1EB130F87B0EC685F89DB2FFC1EF3935
+:10850000A44FCEBBFC7B0E374E36FFA0EF39803D2B
+:108510009B89E34FE4D8C66399289F3BF4FDE5E3CC
+:10852000F23D6497682FC5B228C2A5A276D16DC569
+:10853000F26DD1733FB6035F4C4478153D967D03D1
+:108540007E972551EBA1BCF227ADB64938FF6BB938
+:10855000B6C9F83C34DE5F2F9F0FF6730BF60BCDD8
+:108560001F53E8E2AEC95C0ECD93CBA9F5C3BFC7DC
+:108570003F6F32BF4FBED6BE61BF77E07ACAFED929
+:1085800096C556DC0FECF74EDC27ECB7044B66883B
+:108590000E7A0FF8727A75C9FB62742E908FB33F12
+:1085A000E1F62895E92A7714DA0DA31E7047E17EDB
+:1085B00047350EE8F17D90DFBA06F4683FFC76F5AA
+:1085C000801EDB7F6BE3F9DAA1F36F9FCCFD91F4A2
+:1085D000A903347E0CFCDD4DFEC14014DA6DE9E5E3
+:1085E0004734AE147A4F6DF62741769399F87B8C19
+:1085F000DC36E60191213D8CD9C1781E63410CE93E
+:10860000B94A1DEF5AF9C0FD22D2D13837EC3B8070
+:10861000FEAEDFAE1A0C7EAFD74BE3AAE425C05EF8
+:108620000B7AEE643CBF74942C8FD05EC4EFD939C2
+:10863000CB8FD077A6C08E0B998FBE7930944F59CF
+:10864000ADB3BFE63353BE6250BFA577FF663DFAB8
+:10865000B5E5A55B35E4172F69598FA5C3F19E26B3
+:108660008E917D19D41FECCBA0FA65FB0CD947F590
+:10867000FD17D7C70DB32ED0C156A413850E8EAAF1
+:108680003DE3D04F3DEA0CB3F0F71D3CF45D9A2674
+:10869000F9BDF45DFF39DDCAF365395DC0F81D3FF2
+:1086A0008C8EEAA9BFF21DAF6B958A1C1CFACE8D89
+:1086B00086B9285E39CB4872AE46F6FFAA9798C8AD
+:1086C0001E51F8BA5AE539B51EFBC51879FE9B8ACA
+:1086D000D1F7AB7AC45194CF4D3FACCF4AA5FBAC98
+:1086E000D87A8F17E71DB85DA0EFB9158473B95A12
+:1086F0002896389E85E74744FE5D81A7517E4898BD
+:1087000047C1BF37302597BF3F10CFF877DB98CAF6
+:108710001CF29D36391E7AEDEFB4F1EF92CDE7F7FA
+:10872000720D5125A5CBF1F9821BE8F9C1EF521F5B
+:10873000B1E2FE2A94EFB4717BBF614E063D7F55D6
+:1087400030AF413DE17A805DE93B6D7AE4FB80EF3B
+:10875000B3BD87F8BAD6F7D994EF0F1C5D70C32369
+:108760007B391CBD78EF5533CB18E4AFFF17313C94
+:108770009ED2C05600000000000000000000000073
+:088780000408350000000000B0
+:00000001FF
diff --git a/firmware/bnx2x-e1h-4.8.53.0.fw.ihex b/firmware/bnx2x-e1h-4.8.53.0.fw.ihex
new file mode 100644 (file)
index 0000000..48d7612
--- /dev/null
@@ -0,0 +1,12028 @@
+:10000000000039D8000000600000063000003A40CF
+:100010000000191C000040780000009C0000599866
+:10002000000082E400005A38000000D40000DD2007
+:100030000000C7CC0000DDF8000000780001A5C872
+:10004000000056980001A648000000C00001FCE82E
+:100050000000F1D40001FDB0000000040002EF88B0
+:10006000020400480000000F020400540000004594
+:1000700002040058000000840204005C0000000636
+:100080000204007000000004020400780000000078
+:100090000204007C121700000204008022170000F6
+:1000A00002040084321700000604008800000005E6
+:1000B0000204009C12150000020400A0221500009A
+:1000C000020400A432150000060400A80000000489
+:1000D000020400B802100000020400BC001000007E
+:1000E000020400C010100000020400C42010000030
+:1000F000020400C830100000020400CC40100000D0
+:10010000060400D000000003020400DC0010000020
+:10011000020400E012140000020400E422140000B3
+:10012000020400E832140000020400EC4214000053
+:10013000060400F000000003010401240000000098
+:1001400001040128000000000104012C000000004F
+:100150000104013000000000020401D00000890603
+:1001600002040004000000FF02040008000000FF79
+:100170000204000C000000FF02040010000000FF59
+:1001800002040014000000FF02040018000000FF39
+:100190000204001C000000FF02040020000000FF19
+:1001A000020400240000003E0204002800000000B9
+:1001B0000204002C0000003F020400300000003F59
+:1001C000020400340000003F020400380000003F39
+:1001D0000204003C0000003F020400400000003F19
+:1001E000020400440000003F020404CC00000001AF
+:1001F00002042008000002110204200C000002008A
+:10020000020420100000020402042014000002195D
+:100210000204201C0000FFFF020420200000FFFF5A
+:10022000020420240000FFFF020420280000FFFF3A
+:1002300002042038000000200204203C00000000DE
+:100240000204204000000034020420440000003575
+:10025000060420480000001C020420B80000000131
+:10026000060420BC0000005F0204223807FFFFFFE5
+:100270000204223C0000003F0204224007FFFFFF6F
+:10028000020422440000000F010422480000000084
+:100290000104224C00000000010422500000000074
+:1002A0000104225400000000010422580000000054
+:1002B0000104225C00000000010422600000000034
+:1002C0000104226400000000010422680000000014
+:1002D0000104226C000000000104227000000000F4
+:1002E00001042274000000000104227800000000D4
+:1002F0000104227C000000000C042000000003E840
+:100300000A042000000000010B0420000000000A85
+:1003100002050044000000200205004800000032F1
+:10032000020500900215002002050094021500202D
+:1003300002050098000000300205009C0810000033
+:10034000020500A000000033020500A400000030F8
+:10035000020500A800000031020500AC0000000208
+:10036000020500B000000005020500B40000000610
+:10037000020500B800000002020500BC00000002F7
+:10038000020500C000000000020500C400000005D6
+:10039000020500C800000002020500CC00000002B7
+:1003A000020500D000000002020500D40000000198
+:1003B00002050114000000010205011C00000001FB
+:1003C00002050120000000020205020400000001F5
+:1003D0000205020C0000004002050210000000406F
+:1003E0000205021C0000002002050220000000138C
+:1003F0000205022400000020060502400000000A59
+:1004000004050280002000000205005000000007E3
+:100410000205005400000007020500580000000813
+:100420000205005C000000080205006000000001F9
+:100430000605006400000003020500D80000000665
+:100440000205000400000001020500080000000190
+:100450000205000C00000001020500100000000170
+:100460000205001400000001020500180000000150
+:100470000205001C00000001020500200000000130
+:100480000205002400000001020500280000000110
+:100490000205002C000000010205003000000001F0
+:1004A00002050034000000010205003800000001D0
+:1004B0000205003C000000010205004000000001B0
+:1004C000020500E00000000D020500E80000000742
+:1004D000020500F000000007020500F80000000718
+:1004E000020500E40000002D020500EC00000027DA
+:1004F000020500F400000027020500FC00000027B0
+:10050000020500E00000001D020500E800000017E1
+:10051000020500F000000017020500F800000017B7
+:10052000020500E40000003D020500EC0000003779
+:10053000020500F400000037020500FC000000374F
+:10054000020500E00000004D020500E80000004741
+:10055000020500F000000047020500F80000004717
+:10056000020500E40000006D020500EC00000067D9
+:10057000020500F400000067020500FC00000067AF
+:10058000020500E00000005D020500E800000057E1
+:10059000020500F000000057020500F800000057B7
+:1005A000020500E40000007D020500EC0000007779
+:1005B000020500F400000077020500FC000000774F
+:1005C0000406100002000020020600DC000000010A
+:1005D000010600D80000000004060200000302200B
+:1005E000020600DC00000000010600B80000000068
+:1005F000010600C800000000010600BC0000000069
+:10060000010600CC0000000007180400009B000059
+:1006100008180798000D0223071C0000325E000036
+:10062000071C800035960C98071D00001AEA19FE79
+:10063000081D43D057860225011800000000000065
+:10064000011800040000000001180008000000006C
+:100650000118000C0000000001180010000000004C
+:100660000118001400000000021800200000000122
+:1006700002180024000000020218002800000003F5
+:100680000218002C000000000218003000000004D6
+:1006900002180034000000010218003800000000B9
+:1006A0000218003C00000001021800400000000495
+:1006B0000218004400000000021800480000000179
+:1006C0000218004C00000003021800500000000057
+:1006D0000218005400000001021800580000000435
+:1006E0000218005C00000000021800600000000119
+:1006F00002180064000000030218006800000000F7
+:100700000218006C000000010218007000000004D4
+:1007100002180074000000000218007800000004B5
+:100720000218007C00000003061800800000000290
+:10073000021800A400003FFF021800A8000003FFF9
+:100740000218022400000000021802340000000019
+:100750000218024C00000000021802E4000000FF32
+:100760000618100000000400021B8BC000000001EE
+:10077000021B800000000034021B804000000018B3
+:10078000021B80800000000C021B80C000000020C3
+:100790000C1B83000007A1200A1B83000000013806
+:1007A0000B1B830000001388021B83C0000001F4B0
+:1007B000021B1480000000010A1B148000000000CE
+:1007C000061A1000000002B3041A1ACC0001022716
+:1007D000061AA020000000C8061AA00000000002AF
+:1007E000021A1AD000000000061A1AD800000004ED
+:1007F000061A367800000006061A3670000000025D
+:10080000061A500000000002061A500800000004FA
+:10081000061A501800000004061A502800000004B0
+:10082000061A503800000004061A50480000000460
+:10083000061A505800000004061A50680000000410
+:10084000061A507800000002061A4000000000025C
+:10085000061A400800000002041A62C000200228A4
+:10086000061A20000000016C061AB00000000028E3
+:10087000061AB1400000000C061A32C00000001237
+:10088000061A335000000064061A810800000002B6
+:10089000061A25B00000016C061AB0A0000000285E
+:1008A000061AB1700000000C061A3308000000128E
+:1008B000061A34E000000064061A811000000002ED
+:1008C000021A2B6000000000061A3000000000022F
+:1008D000041A300800050248061A301C0000000700
+:1008E000061A31C000000008061A5000000000027D
+:1008F000061A508000000012061A40000000000294
+:10090000021A2B6400000000061A303800000002B2
+:10091000041A30400005024D061A3054000000074A
+:10092000061A31E000000008061A5010000000020C
+:10093000061A50C800000012061A40080000000203
+:10094000021A2B6800000000061A30700000000236
+:10095000041A307800050252061A308C0000000795
+:10096000061A320000000008061A5020000000029B
+:10097000061A511000000012041A4010000202571B
+:10098000021A2B6C00000000061A30A800000002BA
+:10099000041A30B000050259061A30C400000007DE
+:1009A000061A322000000008061A5030000000022B
+:1009B000061A515800000012041A40180002025E84
+:1009C000021A2B7000000000061A30E0000000023E
+:1009D000041A30E800050260061A30FC0000000727
+:1009E000061A324000000008061A504000000002BB
+:1009F000061A51A000000012041A402000020265ED
+:100A0000021A2B7400000000061A311800000002C0
+:100A1000041A312000050267061A3134000000076D
+:100A2000061A326000000008061A5050000000024A
+:100A3000061A51E800000012041A40280002026C55
+:100A4000021A2B7800000000061A31500000000244
+:100A5000041A31580005026E061A316C00000007B6
+:100A6000061A328000000008061A506000000002DA
+:100A7000061A523000000012041A403000020273BD
+:100A8000021A2B7C00000000061A318800000002C8
+:100A9000041A319000050275061A31A400000007FF
+:100AA000061A32A000000008061A5070000000026A
+:100AB000061A527800000012041A40380002027A26
+:100AC0000200A294071D29110200A2980000000054
+:100AD0000200A29C009C04240200A2A000000000CE
+:100AE0000200A2A4000002090200A270000000009F
+:100AF0000200A274000000000200A27000000000CA
+:100B00000200A274000000000200A27000000000B9
+:100B10000200A274000000000200A27000000000A9
+:100B20000200A27400000000020100B400000001F5
+:100B3000020100B800000001020100DC0000000119
+:100B40000201010000000001020101040000000197
+:100B50000201007C00300000020100840000002837
+:100B60000201008C000000000201013000000004BE
+:100B70000201025C000000010201032800000000E5
+:100B800002016080000000010201055400000030F5
+:100B9000020100C400000001020100CC00000001BD
+:100BA000020100F800000001020100F00000000155
+:100BB00002010080003000000201008800000028CF
+:100BC0000201009000000000020101340000000456
+:100BD000020102DC000000010201032C0000000001
+:100BE0000201608400000001020105640000003081
+:100BF000020100C800000001020100D00000000155
+:100C0000020100FC00000001020100F400000001EC
+:100C1000020C100000000020020C2008000002114D
+:100C2000020C200C00000200020C20100000020444
+:100C3000020C201C0000FFFF020C20200000FFFF20
+:100C4000020C20240000FFFF020C20280000FFFF00
+:100C5000020C2038000000C6020C203C00000000FE
+:100C6000020C204000000034020C2044000000353B
+:100C7000060C20480000001C020C20B800000001F7
+:100C8000060C20BC0000005F020C223807FFFFFFAB
+:100C9000020C223C0000003F020C224007FFFFFF35
+:100CA000020C22440000000F010C2248000000004A
+:100CB000010C224C00000000010C2250000000003A
+:100CC000010C225400000000010C2258000000001A
+:100CD000010C225C00000000010C226000000000FA
+:100CE000010C226400000000010C226800000000DA
+:100CF000010C226C00000000010C227000000000BA
+:100D0000010C227400000000010C22780000000099
+:100D1000010C227C000000000C0C2000000003E805
+:100D20000A0C2000000000010B0C20000000000A4B
+:100D3000020C400800000411020C400C00000400EA
+:100D4000020C401000000404020C401400000421B6
+:100D5000020C401C0000FFFF020C40200000FFFFBF
+:100D6000020C40240000FFFF020C40280000FFFF9F
+:100D7000020C403800000046020C403C0000000518
+:100D8000020C404000000034020C404400000035DA
+:100D9000020C404800000007060C404C0000005BBD
+:100DA000020C41B800000001060C41BC0000000329
+:100DB000020C41C800000001060C41CC0000001BE1
+:100DC000020C423807FFFFFF020C423C0000003FCC
+:100DD000020C424007FFFFFF020C42440000000FDC
+:100DE000010C424800000000010C424C00000000D1
+:100DF000010C425000000000010C425400000000B1
+:100E0000010C425800000000010C425C0000000090
+:100E1000010C426000000000010C42640000000070
+:100E2000010C426800000000010C426C0000000050
+:100E3000010C427000000000010C42740000000030
+:100E4000010C427800000000010C427C0000000010
+:100E5000010C4280000000000C0C4000000003E880
+:100E60000A0C4000000000010B0C40000000000ACA
+:100E7000020D004400000032020D008C021500201B
+:100E8000020D009002150020020D009408100000D1
+:100E9000020D009800000033020D009C00000002CB
+:100EA000020D00A000000000020D00A400000005DB
+:100EB000020D00A800000005060D00AC00000002B5
+:100EC000020D00B400000002020D00B80000000393
+:100ED000020D00BC00000002020D00C00000000175
+:100EE000020D00C800000002020D00CC000000024C
+:100EF000020D010800000001020D015C000000016C
+:100F0000020D016400000001020D016800000002F2
+:100F1000020D020400000001020D020C000000207E
+:100F2000020D021000000040020D021400000040FB
+:100F3000020D022000000003020D02240000001830
+:100F4000060D028000000012040D03000024027C44
+:100F5000020D004C00000001020D005000000002D4
+:100F6000020D005400000008020D005800000008A7
+:100F7000060D005C00000004020D00C40000000427
+:100F8000020D000400000001020D00080000000135
+:100F9000020D000C00000001020D00100000000115
+:100FA000020D001400000001020D001800000001F5
+:100FB000020D001C00000001020D002000000001D5
+:100FC000020D002400000001020D002800000001B5
+:100FD000020D002C00000001020D00300000000195
+:100FE000020D003400000001020D00380000000175
+:100FF000020D003C00000001020D01140000000978
+:10100000020D011C0000000A020D0124000000076F
+:10101000020D012C00000007020D01340000000C3D
+:10102000020D013C0000000B020D0144000000070E
+:10103000020D011800000029020D01200000002A05
+:10104000020D012800000027020D013000000027DA
+:10105000020D01380000002C020D01400000002BA1
+:10106000020D014800000027020D011400000019C4
+:10107000020D011C0000001A020D012400000017DF
+:10108000020D012C00000017020D01340000001CAD
+:10109000020D013C0000001B020D0144000000177E
+:1010A000020D011800000039020D01200000003A75
+:1010B000020D012800000037020D0130000000374A
+:1010C000020D01380000003C020D01400000003B11
+:1010D000020D014800000037020D01140000004914
+:1010E000020D011C0000004A020D0124000000470F
+:1010F000020D012C00000047020D01340000004CDD
+:10110000020D013C0000004B020D014400000047AD
+:10111000020D011800000069020D01200000006AA4
+:10112000020D012800000067020D01300000006779
+:10113000020D01380000006C020D01400000006B40
+:10114000020D014800000067020D01140000005963
+:10115000020D011C0000005A020D0124000000577E
+:10116000020D012C00000057020D01340000005C4C
+:10117000020D013C0000005B020D0144000000571D
+:10118000020D011800000079020D01200000007A14
+:10119000020D012800000077020D013000000077E9
+:1011A000020D01380000007C020D01400000007BB0
+:1011B000020D014800000077020E004C00000032D2
+:1011C000020E009402150020020E00980215002065
+:1011D000020E009C00000030020E00A0081000006B
+:1011E000020E00A400000033020E00A80000003030
+:1011F000020E00AC00000031020E00B00000000240
+:10120000020E00B400000004020E00B8000000004E
+:10121000020E00BC00000002020E00C0000000022E
+:10122000020E00C400000000020E00C80000000210
+:10123000020E00CC00000007020E00D000000002E9
+:10124000020E00D400000002020E00D800000001CF
+:10125000020E00E400000001020E01440000000143
+:10126000020E014C00000001020E015000000002BD
+:10127000020E020400000001020E020C00000040F9
+:10128000020E021000000040020E021C00000004CA
+:10129000020E022000000020020E02240000000EB8
+:1012A000020E02280000001B060E030000000012C0
+:1012B000040E0280001B02A0020E00540000001069
+:1012C000020E005800000007020E005C0000000F34
+:1012D000020E006000000010020E00640000000B0F
+:1012E000060E006800000003020E00DC0000000390
+:1012F000020E000400000001020E000800000001C0
+:10130000020E000C00000001020E0010000000019F
+:10131000020E001400000001020E0018000000017F
+:10132000020E001C00000001020E0020000000015F
+:10133000020E002400000001020E0028000000013F
+:10134000020E002C00000001020E0030000000011F
+:10135000020E003400000001020E003800000001FF
+:10136000020E003C00000001020E004000000001DF
+:10137000020E004400000001020E01100000000FE8
+:10138000020E01180000000E020E012000000000F5
+:10139000020E012800000000020E01140000002FC0
+:1013A000020E011C0000002E020E012400000000AD
+:1013B000020E012C00000000020E01100000001FB0
+:1013C000020E01180000001E020E012000000000A5
+:1013D000020E012800000000020E01140000003F70
+:1013E000020E011C0000003E020E0124000000005D
+:1013F000020E012C00000000020E01100000004F40
+:10140000020E01180000004E020E01200000000034
+:10141000020E012800000000020E01140000006FFF
+:10142000020E011C0000006E020E012400000000EC
+:10143000020E012C00000000020E01100000005FEF
+:10144000020E01180000005E020E012000000000E4
+:10145000020E012800000000020E01140000007FAF
+:10146000020E011C0000007E020E0124000000009C
+:10147000020E012C000000000730040000D2000022
+:10148000083007A8000B02BB0734000031B600008B
+:101490000734800036500C6E0735000037591A03A8
+:1014A00007358000286127DA0835FF40401802BD63
+:1014B00001300000000000000130000400000000C6
+:1014C00001300008000000000130000C00000000A6
+:1014D0000130001000000000013000140000000086
+:1014E0000230002000000001023000240000000251
+:1014F00002300028000000030230002C0000000031
+:10150000023000300000000402300034000000010E
+:1015100002300038000000000230003C00000001F2
+:1015200002300040000000040230004400000000CF
+:1015300002300048000000010230004C00000003AF
+:101540000230005000000000023000540000000192
+:1015500002300058000000040230005C000000006F
+:10156000023000600000000102300064000000034F
+:1015700002300068000000000230006C0000000132
+:10158000023000700000000402300074000000000F
+:1015900002300078000000040230007C00000003EC
+:1015A0000630008000000002023000A400003FFF6F
+:1015B000023000A8000003FF0230022400000000F7
+:1015C00002300234000000000230024C0000000033
+:1015D000023002E40000FFFF063020000000080097
+:1015E00002338BC000000001023380000000001AAB
+:1015F000023380400000004E023380800000001063
+:10160000023380C0000000200C3383000007A120BB
+:101610000A338300000001380B3383000000138875
+:10162000023383C0000001F40C3383801DCD6500BC
+:101630000A3383800004C4B40B338380004C4B40D6
+:101640000A331480000000000233148000000001FF
+:10165000063220000000010206328980000000C826
+:1016600006328960000000020632322800000004C1
+:10167000063232000000000904323224000102BFA9
+:1016800006323180000000200632500000000400C5
+:10169000063240000000000204324008000102C08F
+:1016A0000632400C0000000306326B6800000002A6
+:1016B00004326B70000202C106326B10000000029F
+:1016C000043274C0000202C30233080001000000AB
+:1016D00004330C00001002C50233080000000000B3
+:1016E00004330C40001002D506329000000000A028
+:1016F0000632950000000040063297000000003CD2
+:1017000006322450000000B406322AD00000000245
+:101710000632308000000020063280000000012CDC
+:101720000232323800000000063250000000002073
+:101730000632510000000020063252000000002056
+:101740000632530000000020063254000000002042
+:10175000063255000000002006325600000000202E
+:10176000063257000000002006325800000000201A
+:10177000063259000000002006325A000000002006
+:1017800006325B000000002006325C0000000020F2
+:1017900006325D000000002006325E0000000020DE
+:1017A00006325F000000002006326B780000005215
+:1017B00006326E080000000C06329280000000A085
+:1017C0000632960000000040063297F00000003C10
+:1017D00006322720000000B406322AD8000000029A
+:1017E0000632310000000020063284B00000012CD7
+:1017F0000232323C0000000006325080000000201F
+:101800000632518000000020063252800000002085
+:101810000632538000000020063254800000002071
+:10182000063255800000002006325680000000205D
+:101830000632578000000020063258800000002049
+:10184000063259800000002006325A800000002035
+:1018500006325B800000002006325C800000002021
+:1018600006325D800000002006325E80000000200D
+:1018700006325F800000002006326CC0000000527B
+:1018800006326E380000000C02322A3000000000E0
+:10189000063230000000000406324018000000024A
+:1018A00002322A340000000006323010000000042A
+:1018B000063240280000000202322A3800000000F0
+:1018C00006323020000000040632403800000002DA
+:1018D00002322A3C000000000632303000000004D2
+:1018E000063240480000000202322A400000000098
+:1018F000063230400000000406324058000000026A
+:1019000002322A4400000000063230500000000479
+:10191000063240680000000202322A48000000003F
+:1019200006323060000000040632407800000002F9
+:1019300002322A4C00000000063230700000000421
+:1019400006324088000000020720040000740000F6
+:1019500008200780001002E507240000322600005E
+:1019600007248000246E0C8A0824CBB064F002E7C0
+:101970000120000000000000012000040000000021
+:1019800001200008000000000120000C0000000001
+:1019900001200010000000000120001400000000E1
+:1019A00002200020000000010220002400000002AC
+:1019B00002200028000000030220002C000000008C
+:1019C000022000300000000402200034000000016A
+:1019D00002200038000000000220003C000000014E
+:1019E000022000400000000402200044000000002B
+:1019F00002200048000000010220004C000000030B
+:101A000002200050000000000220005400000001ED
+:101A100002200058000000040220005C00000000CA
+:101A200002200060000000010220006400000003AA
+:101A300002200068000000000220006C000000018D
+:101A4000022000700000000402200074000000006A
+:101A500002200078000000040220007C0000000347
+:101A60000620008000000002022000A400003FFFCA
+:101A7000022000A8000003FF022002240000000052
+:101A800002200234000000000220024C000000008E
+:101A9000022002E40000FFFF0620200000000800F2
+:101AA00002238BC000000001022380000000001010
+:101AB00002238040000000120223808000000030DA
+:101AC000022380C00000000E022383C0000001F446
+:101AD00002231480000000010A231480000000008B
+:101AE000062210000000004206227020000000C8FC
+:101AF0000622700000000002022211E8000000002F
+:101B000006223000000000C0062240700000008065
+:101B10000622528000000004062267000000010037
+:101B2000062290000000040004226B08002002E955
+:101B300002230800013FFFFF04230C0000100309EB
+:101B4000022308000000000004230C4000100319C9
+:101B500006228000000000A0062285000000004050
+:101B6000062287000000003C0622404000000006DC
+:101B700006228280000000A00622860000000040AD
+:101B8000062287F00000003C0622405800000006B4
+:101B9000022211480000000006223300000000026B
+:101BA00006226040000000300222114C00000000BC
+:101BB0000622330800000002062261000000003007
+:101BC0000222115000000000062233100000000223
+:101BD000062261C000000030022211540000000003
+:101BE0000622331800000002062262800000003046
+:101BF00002221158000000000622332000000002DB
+:101C000006226340000000300222115C0000000048
+:101C10000622332800000002062264000000003083
+:101C20000222116000000000062233300000000292
+:101C3000062264C00000003002221164000000008F
+:101C400006223338000000020622658000000030C2
+:101C50000216100000000020021700080000000219
+:101C60000217002C000000030217003C00000004D3
+:101C7000021700440000000802170048000000029C
+:101C80000217004C00000090021700500000009066
+:101C9000021700540080009002170058081400003A
+:101CA000021700600000008A021700640000008034
+:101CB00002170068000000900217006C000000800E
+:101CC000021700700000000602170078000007D01D
+:101CD0000217007C0000076C02170038007C10041B
+:101CE000021700040000000F061640240000000246
+:101CF000021640700000001C02164208000000019D
+:101D000002164210000000010216422000000001ED
+:101D100002164228000000010216423000000001B5
+:101D20000216423800000001021642600000000264
+:101D30000C16401C0003D0900A16401C0000009CAA
+:101D40000B16401C000009C40216403000000008B9
+:101D5000021640340000000C02164038000000104B
+:101D6000021640440000002002164000000000015E
+:101D7000021640D8000000010216400800000001D1
+:101D80000216400C00000001021640100000000185
+:101D90000216424000000000021642480000000007
+:101DA00006164270000000020216425000000000B9
+:101DB0000216425800000000061642800000000291
+:101DC00002166008000004240216600C00000410D3
+:101DD00002166010000004140216601C0000FFFFD1
+:101DE000021660200000FFFF021660240000FFFFC3
+:101DF000021660280000FFFF021660380000002075
+:101E00000216603C00000020021660400000003412
+:101E100002166044000000350216604800000023EE
+:101E20000216604C000000240216605000000025DD
+:101E300002166054000000260216605800000027B9
+:101E40000216605C00000029021660600000002A93
+:101E5000021660640000002B021660680000002C6F
+:101E60000216606C0000002D061660700000005223
+:101E7000021661B800000001061661BC0000001FD8
+:101E80000216623807FFFFFF0216623C0000003FA7
+:101E90000216624007FFFFFF021662440000000FB7
+:101EA00001166248000000000116624C00000000AC
+:101EB000011662500000000001166254000000008C
+:101EC00001166258000000000116625C000000006C
+:101ED000011662600000000001166264000000004C
+:101EE00001166268000000000116626C000000002C
+:101EF000011662700000000001166274000000000C
+:101F000001166278000000000116627C00000000EB
+:101F10000C166000000003E80A16600000000001D3
+:101F20000B1660000000000A021680400000000648
+:101F30000216804400000005021680480000000AD6
+:101F40000216804C000000050216805400000002BA
+:101F5000021680CC00000004021680D000000004AD
+:101F6000021680D400000004021680D8000000048D
+:101F7000021680DC00000004021680E0000000046D
+:101F8000021680E400000004021680E8000000044D
+:101F90000216880400000004021680300000007C55
+:101FA000021680340000003D021680380000003F19
+:101FB0000216803C0000009C021680F00000000722
+:101FC000061680F4000000050216880C01010101CC
+:101FD00002168108000000000216810C00000004B7
+:101FE0000216811000000004021681140000000295
+:101FF000021688100801200402168118000000054E
+:102000000216811C00000005021681200000000558
+:1020100002168124000000050216882C20081001F9
+:1020200002168128000000080216812C000000061C
+:102030000216813000000007021681340000000003
+:1020400002168830010101200616813800000004C4
+:1020500002168834010101010216814800000000C7
+:102060000216814C0000000402168150000000049A
+:10207000021681540000000202168838080120046C
+:1020800002168158000000050216815C0000000560
+:102090000216816000000005021681640000000540
+:1020A0000216883C20081001021681680000000812
+:1020B0000216816C00000006021681700000000705
+:1020C00002168174000000010216884001010120FF
+:1020D00002168178000000010216817C00000001D8
+:1020E00002168180000000010216818400000001B8
+:1020F00002168844010101010216818800000001D6
+:102100000216818C00000004021681900000000479
+:10211000021681940000000202168848080120047B
+:1021200002168198000000050216819C000000053F
+:10213000021681A000000005021681A4000000051F
+:102140000216881420081001021681A80000000859
+:10215000021681AC00000006021681B000000007E4
+:10216000021681B400000001021688180101012046
+:10217000021681B800000001021681BC00000001B7
+:10218000021681C000000001021681C40000000197
+:102190000216881C01010101021681C8000000011D
+:1021A000021681CC00000004021681D00000000459
+:1021B000021681D4000000020216882008012004C3
+:1021C000021681D800000005021681DC000000051F
+:1021D000021681E000000005021681E400000005FF
+:1021E0000216882420081001021681E80000000869
+:1021F000021681EC00000006021681F000000007C4
+:102200000216E40C000000000216882801010120DB
+:102210000616E410000000040216E00001010101AE
+:102220000216E420000000000216E424000000046E
+:102230000216E428000000040216E42C000000024C
+:102240000216E004080120040216E4300000000534
+:102250000216E434000000050216E4380000000510
+:102260000216E43C000000050216E00820081001F8
+:102270000216E440000000080216E44400000006D4
+:102280000216E448000000070216E44C00000000BB
+:102290000216E00C010101200616E45000000004C3
+:1022A0000216E010010101010216E46000000000C6
+:1022B0000216E464000000040216E4680000000452
+:1022C0000216E46C000000020216E014080120046B
+:1022D0000216E470000000050216E4740000000518
+:1022E0000216E478000000050216E47C00000005F8
+:1022F0000216E018200810010216E4800000000811
+:102300000216E484000000060216E48800000007BC
+:102310000216E48C000000010216E01C01010120FD
+:102320000216E490000000010216E494000000018F
+:102330000216E498000000010216E49C000000016F
+:102340000216E020010101010216E4A000000001D4
+:102350000216E4A4000000040216E4A80000000431
+:102360000216E4AC000000020216E024080120047A
+:102370000216E4B0000000050216E4B400000005F7
+:102380000216E4B8000000050216E4BC00000005D7
+:102390000216E028200810010216E4C00000000820
+:1023A0000216E4C4000000060216E4C8000000079C
+:1023B0000216E4CC000000010216E02C010101200D
+:1023C0000216E4D0000000010216E4D4000000016F
+:1023D0000216E4D8000000010216E4DC000000014F
+:1023E0000216E030010101010216E4E000000001E4
+:1023F0000216E4E4000000040216E4E80000000411
+:102400000216E4EC000000020216E0340801200489
+:102410000216E4F0000000050216E4F400000005D6
+:102420000216E4F8000000050216E4FC00000005B6
+:102430000216E038200810010216E500000000082E
+:102440000216E504000000060216E5080000000779
+:102450000216E03C0101012002168240003F003FCD
+:1024600002168244000000000216E524003F003FEF
+:102470000216E52800000000021682480000000055
+:102480000216824C003F003F0216E52C00000000BF
+:102490000216E530003F003F0216825001000100A5
+:1024A00002168254010001000216E5340100010009
+:1024B0000216E538010001000616825800000002ED
+:1024C0000216E53C000000000216E5400000000096
+:1024D0000216826000C000C00216826400C000C004
+:1024E0000216E54400C000C00216E54800C000C066
+:1024F000021682681E001E000216826C1E001E005C
+:102500000216E54C1E001E000216E5501E001E00BD
+:1025100002168270400040000216827440004000A3
+:102520000216E554400040000216E5584000400005
+:1025300002168278800080000216827C8000800073
+:102540000216E55C800080000216E56080008000D5
+:1025500002168280200020000216828420002000C3
+:102560000216E564200020000216E5682000200025
+:1025700006168288000000020216E56C00000000CA
+:102580000216E570000000000216829000000000B4
+:1025900002168294000000000216E574000000009C
+:1025A0000216E57800000000021682980000000084
+:1025B0000216829C000000000216E57C000000006C
+:1025C0000216E58000000000021682A00000000054
+:1025D000021682A400000001061682A80000000A6C
+:1025E000021681F400000C08021681F80000004079
+:1025F000021681FC0000010002168200000000208B
+:1026000002168204000000170216820800000080F3
+:102610000216820C00000200021682100000000068
+:102620000216821801FF01FF0216821401FF01FF4A
+:102630000216E51001FF01FF0216E50C01FF01FF84
+:102640000216823C00000013021680900000013F39
+:102650000216806000000140021680640000014004
+:10266000061680680000000202168070000000C09C
+:1026700006168074000000070216809C00000048C7
+:10268000021680A000000048061680A40000000288
+:10269000021680AC00000048061680B0000000075B
+:1026A000021682380000800002168234000025E401
+:1026B0000216809400007FFF0216822000070007A8
+:1026C0000216821C000700070216E5180007000723
+:1026D0000216E51400070007021682280000000019
+:1026E00002168224FFFFFFFF0216E5200000000013
+:1026F0000216E51CFFFFFFFF0216E6BC000000000B
+:102700000216E6C0000000020216E6C40000000146
+:102710000216E6C8000000030216E6CC0000000422
+:102720000216E6D0000000060216E6D400000005FE
+:102730000216E6D800000007021680EC000000FF39
+:1027400002140000000000010214000C000000014F
+:1027500002140040000000010214004400007FFF4A
+:102760000214000C00000000021400000000000031
+:102770000214006C000000000214000400000001BC
+:1027800002140030000000010214000400000000E8
+:102790000214005C000000000214000800000001A8
+:1027A00002140034000000010214000800000000C0
+:1027B0000214006000000000020200580000003215
+:1027C000020200A003150020020200A4031500204D
+:1027D000020200A801000030020200AC0810000054
+:1027E000020200B000000033020200B4000000301A
+:1027F000020200B800000031020200BC0000000329
+:10280000020200C000000006020200C40000000333
+:10281000020200C800000003020200CC0000000217
+:10282000020200D000000000020200D400000002FA
+:10283000020200DC00000000020200E000000006CE
+:10284000020200E400000004020200E800000002AE
+:10285000020200EC00000002020200F00000000191
+:10286000020200FC0000000602020120000000003D
+:102870000202013400000002020201B00000000167
+:102880000202020C0000000102020214000000011A
+:10289000020202180000000202020404000000010B
+:1028A0000202040C0000004002020410000000407C
+:1028B0000202041C000000040202042000000020A8
+:1028C000020204240000000202020428000000208A
+:1028D000060205000000001204020480001F032904
+:1028E000020200600000000F020200640000000706
+:1028F000020200680000000B0202006C0000000EE3
+:10290000020200700000000E0602007400000003C6
+:10291000020200F4000000040202000400000001B2
+:1029200002020008000000010202000C0000000189
+:102930000202001000000001020200140000000169
+:1029400002020018000000010202001C0000000149
+:102950000202002000000001020200240000000129
+:1029600002020028000000010202002C0000000109
+:1029700002020030000000010202003400000001E9
+:1029800002020038000000010202003C00000001C9
+:1029900002020040000000010202004400000001A9
+:1029A00002020048000000010202004C0000000189
+:1029B000020200500000000102020108000000C8ED
+:1029C0000202011800000002020201C4000000001F
+:1029D000020201CC00000000020201D4000000024B
+:1029E000020201DC00000002020201E4000000FF1C
+:1029F000020201EC000000FF0202010000000000E2
+:102A00000202010C000000C80202011C00000002CA
+:102A1000020201C800000000020201D00000000014
+:102A2000020201D800000002020201E000000002E0
+:102A3000020201E8000000FF020201F0000000FFB6
+:102A4000020201040000000002020108000000C8A8
+:102A50000202011800000002020201C4000000008E
+:102A6000020201CC00000000020201D400000002BA
+:102A7000020201DC00000002020201E4000000FF8B
+:102A8000020201EC000000FF020201000000000051
+:102A90000202010C000000C80202011C000000023A
+:102AA000020201C800000000020201D00000000084
+:102AB000020201D800000002020201E00000000250
+:102AC000020201E8000000FF020201F0000000FF26
+:102AD000020201040000000002020108000000C818
+:102AE0000202011800000002020201C400000000FE
+:102AF000020201CC00000000020201D4000000022A
+:102B0000020201DC00000002020201E4000000FFFA
+:102B1000020201EC000000FF0202010000000000C0
+:102B20000202010C000000C80202011C00000002A9
+:102B3000020201C800000000020201D000000000F3
+:102B4000020201D800000002020201E000000002BF
+:102B5000020201E8000000FF020201F0000000FF95
+:102B6000020201040000000002020108000000C887
+:102B70000202011800000002020201C4000000006D
+:102B8000020201CC00000000020201D40000000299
+:102B9000020201DC00000002020201E4000000FF6A
+:102BA000020201EC000000FF020201000000000030
+:102BB0000202010C000000C80202011C0000000219
+:102BC000020201C800000000020201D00000000063
+:102BD000020201D800000002020201E0000000022F
+:102BE000020201E8000000FF020201F0000000FF05
+:102BF00002020104000000000728040000BD0000DC
+:102C0000082807A8000B0348072C00003406000022
+:102C1000072C800037960D02072D00003BC31AE8F1
+:102C2000072D8000382629D9072E0000124537E3EA
+:102C3000082E22203BBC034A0128000000000000AF
+:102C40000128000400000000012800080000000026
+:102C50000128000C00000000012800100000000006
+:102C600001280014000000000228002000000001DC
+:102C700002280024000000020228002800000003AF
+:102C80000228002C00000000022800300000000490
+:102C90000228003400000001022800380000000073
+:102CA0000228003C0000000102280040000000044F
+:102CB0000228004400000000022800480000000133
+:102CC0000228004C00000003022800500000000011
+:102CD00002280054000000010228005800000004EF
+:102CE0000228005C000000000228006000000001D3
+:102CF00002280064000000030228006800000000B1
+:102D00000228006C0000000102280070000000048E
+:102D1000022800740000000002280078000000046F
+:102D20000228007C0000000306280080000000024A
+:102D3000022800A400003FFF022800A8000003FFB3
+:102D400002280224000000000228023400000000D3
+:102D50000228024C00000000022802E40000FFFFED
+:102D60000628200000000800022B8BC00000000194
+:102D7000022B800000000000022B804000000018A1
+:102D8000022B80800000000C022B80C00000006637
+:102D90000C2B83000007A1200A2B830000000138C0
+:102DA0000B2B830000001388022B83C0000001F46A
+:102DB0000C2B8340000001F40A2B8340000000002C
+:102DC0000B2B8340000000050A2B83800004C4B451
+:102DD0000C2B83801DCD65000A2B148000000000A1
+:102DE0000B2B8380004C4B40022B14800000000111
+:102DF000062A29C800000004042A29D80002034C2E
+:102E0000062A208000000048062A9020000000C802
+:102E1000062A900000000002062A21A80000008671
+:102E2000062A200000000020022A23C8000000001B
+:102E3000042A23D00002034E042A249800040350DD
+:102E4000022A2C2000000000022A2C1000000000A2
+:102E5000042A2C0800020354022A3010000000014A
+:102E6000062A404000000010042A400000100356CB
+:102E7000062A6AC000000002062A6B000000000457
+:102E8000042A840800020366022B080000000000E8
+:102E9000042B0C0000100368022B08000100000046
+:102EA000042B0C4000080378022B080002000000ED
+:102EB000042B0C6000080380062AC000000000FC00
+:102EC000062A24A800000014062A25480000002431
+:102ED000062A266800000024062A2788000000240D
+:102EE000062A28A800000024062AA00000000028C6
+:102EF000062AA1400000000C042A29E000020388F1
+:102F0000022A300000000001062A502000000002C2
+:102F1000062A503000000002062A5000000000027D
+:102F2000062A501000000002022A52080000000188
+:102F3000042A6AC80002038A062A6B1000000042B5
+:102F4000062A6D2000000004062AC3F0000000FCE1
+:102F5000062A24F800000014062A25D800000024C0
+:102F6000062A26F800000024062A2818000000245B
+:102F7000062A293800000024062AA0A00000002804
+:102F8000062AA1700000000C042A29E80002038C24
+:102F9000022A300400000001062A50280000000226
+:102FA000062A503800000002062A500800000002DD
+:102FB000062A501800000002022A520C00000001EC
+:102FC000042A6AD00002038E062A6C180000004210
+:102FD000062A6D3000000004022AC7E0000000004D
+:102FE000042A29F000100390062A50480000000E21
+:102FF000022AC7E400000000042A2A30001003A0BF
+:10300000062A50800000000E022AC7E800000000D7
+:10301000042A2A70001003B0062A50B80000000EDF
+:10302000022AC7EC00000000042A2AB0001003C0E6
+:10303000062A50F00000000E022AC7F0000000002F
+:10304000042A2AF0001003D0062A51280000000E9E
+:10305000022AC7F400000000042A2B30001003E00D
+:10306000062A51600000000E022AC7F80000000086
+:10307000042A2B70001003F0062A51980000000E5D
+:10308000022AC7FC00000000042A2BB00010040034
+:10309000062A51D00000000E0210100800000001A6
+:1030A0000210105000000001021010000003D000B8
+:1030B000021010040000003D091018000200041066
+:1030C0000910110000280610061011A000000018B9
+:1030D00006102400000000E00210201C0000000088
+:1030E0000210202000000001021020C00000000299
+:1030F000021020040000000102102008000000015E
+:1031000009103C0000050638091038000005063D8E
+:10311000091038200005064206104C00000001008E
+:1031200002104028000000100210404400003FFF41
+:103130000210405800280000021040840084924A87
+:1031400002104058000000000210800000001080B3
+:10315000021080AC00000000021080380000001057
+:103160000210810000000000061081200000000213
+:1031700002108008000002B502108010000000005C
+:10318000061082000000004A021081080001FFFFC3
+:1031900006108140000000020210800000001A802A
+:1031A0000610900000000024061091200000004A44
+:1031B000061093700000004A061095C00000004AF7
+:1031C0000210800400001080021080B00000000196
+:1031D0000210803C0000001002108104000000007A
+:1031E00006108128000000020210800C000002B5C9
+:1031F0000210801400000000061084000000004A45
+:103200000210810C0001FFFF06108148000000023F
+:103210000210800400001A80061090900000002424
+:10322000061092480000004A061094980000004AD8
+:10323000061096E80000004A02108000000010808E
+:10324000021080AC00000002021080380000001064
+:103250000210810000000000061081200000000222
+:1032600002108008000002B502108010000000006B
+:10327000061082000000004A021081080001FFFFD2
+:1032800006108140000000020210800000001A8039
+:103290000610900000000024061091200000004A53
+:1032A000061093700000004A061095C00000004A06
+:1032B0000210800400001080021080B000000003A3
+:1032C0000210803C00000010021081040000000089
+:1032D00006108128000000020210800C000002B5D8
+:1032E0000210801400000000061084000000004A54
+:1032F0000210810C0001FFFF06108148000000024F
+:103300000210800400001A80061090900000002433
+:10331000061092480000004A061094980000004AE7
+:10332000061096E80000004A02108000000010809D
+:10333000021080AC00000004021080380000001071
+:103340000210810000000000061081200000000231
+:1033500002108008000002B502108010000000007A
+:10336000061082000000004A021081080001FFFFE1
+:1033700006108140000000020210800000001A8048
+:103380000610900000000024061091200000004A62
+:10339000061093700000004A061095C00000004A15
+:1033A0000210800400001080021080B000000005B0
+:1033B0000210803C00000010021081040000000098
+:1033C00006108128000000020210800C000002B5E7
+:1033D0000210801400000000061084000000004A63
+:1033E0000210810C0001FFFF06108148000000025E
+:1033F0000210800400001A80061090900000002443
+:10340000061092480000004A061094980000004AF6
+:10341000061096E80000004A0210800000001080AC
+:10342000021080AC0000000602108038000000107E
+:103430000210810000000000061081200000000240
+:1034400002108008000002B5021080100000000089
+:10345000061082000000004A021081080001FFFFF0
+:1034600006108140000000020210800000001A8057
+:103470000610900000000024061091200000004A71
+:10348000061093700000004A061095C00000004A24
+:103490000210800400001080021080B000000007BD
+:1034A0000210803C000000100210810400000000A7
+:1034B00006108128000000020210800C000002B5F6
+:1034C0000210801400000000061084000000004A72
+:1034D0000210810C0001FFFF06108148000000026D
+:1034E0000210800400001A80061090900000002452
+:1034F000061092480000004A061094980000004A06
+:10350000061096E80000004A021205B00000000113
+:103510000212049000E383400212051400003C10E4
+:103520000212066C0000000102120670000000008A
+:1035300002120494FFFFFFFF02120498FFFFFFFF37
+:103540000212049CFFFFFFFF021204A0FFFFFFFF17
+:10355000021204A4FFFFFFFF021204A8FFFFFFFFF7
+:10356000021204ACFFFFFFFF021204B0FFFFFFFFD7
+:10357000021204BCFFFFFFFF021204C0FFFFFFFFA7
+:10358000021204C4FFFFFFFF021204C8FFFFFFFF87
+:10359000021204CCFFFFFFFF021204D0FFFFFFFF67
+:1035A000021204D8FFFFFFFF021204DCFFFFFFFF3F
+:1035B000021204E0FFFFFFFF021204E4FFFFFFFF1F
+:1035C000021204E8FFFFFFFF021204ECFFFFFFFFFF
+:1035D000021204F0FFFFFFFF021204F4FFFFFFFFDF
+:1035E000021204F8FFFFFFFF021204FCFFFFFFFFBF
+:1035F00002120500FFFFFFFF02120504FFFFFFFF9D
+:1036000002120508FFFFFFFF0212050CFFFFFFFF7C
+:1036100002120510FFFFFFFF021204D4FF802000FA
+:10362000021204B4F0005000021204B8F00080004E
+:1036300002120390000000080212039C0000000820
+:10364000021203A000000008021203A400000002FE
+:10365000021203BC00000004021203C000000005B7
+:10366000021203C400000004021203D00000000094
+:103670000212036C00000001021203680000003F08
+:10368000021201BC00000040021201C00000180834
+:10369000021201C400000803021201C8000008035E
+:1036A000021201CC00000040021201D00000000311
+:1036B000021201D400000803021201D8000008031E
+:1036C000021201DC00000803021201E00001000305
+:1036D000021201E400000803021201E800000803DE
+:1036E000021201EC00000003021201F000000003CE
+:1036F000021201F400000003021201F800000003AE
+:10370000021201FC0000000302120200000000038C
+:10371000021202040000000302120208000000036B
+:103720000212020C0000000302120210000000034B
+:10373000021202140000000302120218000000032B
+:103740000212021C0000000302120220000000030B
+:1037500002120224000000030212022800002403C7
+:103760000212022C0000002F021202300000000999
+:103770000212023400000019021202380000018413
+:103780000212023C00000183021202400000030604
+:103790000212024400000019021202480000000652
+:1037A0000212024C0000030602120250000003063F
+:1037B00002120254000003060212025800000C8696
+:1037C0000212025C000003060212026000000306FF
+:1037D00002120264000000060212026800000006E5
+:1037E0000212026C000000060212027000000006C5
+:1037F00002120274000000060212027800000006A5
+:103800000212027C00000006021202800000000684
+:103810000212028400000006021202880000000664
+:103820000212028C00000006021202900000000644
+:103830000212029400000006021202980000000624
+:103840000212029C00000006021202A00000030601
+:10385000021202A400000013021202A800000006D7
+:10386000021202B000001004021202B400001004A0
+:103870000212032400106440021203280010644066
+:10388000021205B400000001021201B000000001A4
+:103890000600A000000000160200A0EC5554000035
+:1038A0000200A0F0555555550200A0F400005555F2
+:1038B0000200A0F8F00000000200A0FC5554000037
+:1038C0000200A100555555550200A10400005555B0
+:1038D0000200A108F00000000200A18C5554000075
+:1038E0000200A190555555550200A1940000555570
+:1038F0000200A198F00000000200A19C000000005E
+:103900000200A1A0000100000200A1A400005014C8
+:103910000200A1A8000000000200A45C00000C004E
+:103920000200A61C000000030200A06CFF5C000067
+:103930000200A070FFF55FFF0200A0740000FFFF0F
+:103940000200A078F00003E00200A07C000000006C
+:103950000200A0800000A0000600A0840000000576
+:103960000200A0980FE000000600A09C00000007E5
+:103970000200A0B8000004000600A0BC0000000384
+:103980000200A0C8000010000600A0CC0000000348
+:103990000200A0D8000040000600A0DC00000003E8
+:1039A0000200A0E8000100000600A22C00000004B4
+:1039B0000200A10CFF5C00000200A110FFF55FFFF8
+:1039C0000200A1140000FFFF0200A118F00003E0B4
+:1039D0000200A11C000000000200A1200000A000C5
+:1039E0000600A124000000050200A1380FE000003D
+:1039F0000600A13C000000070200A15800000800DA
+:103A00000600A15C000000030200A1680000200085
+:103A10000600A16C000000030200A17800008000F5
+:103A20000600A17C000000030200A1880002000043
+:103A30000600A23C0000000400000000000000009E
+:103A40000000003100000000000000000000000045
+:103A50000000000000000000000000000000000066
+:103A600000000000000000000000000000310032F3
+:103A70000000000000000000000000000000000046
+:103A80000000000000000000000000000000000036
+:103A9000000000000000000000320056000000009E
+:103AA0000000000000000000000000000000000016
+:103AB0000000000000000000000000000000000006
+:103AC000000000000056008C000000000000000014
+:103AD000008C009000900094009400980098009C46
+:103AE000009C00A000A000A400A400A800A800ACB6
+:103AF00000AC00B100B100B300B300B5000000009D
+:103B000000000000000000000000000000000000B5
+:103B100000000000000000000000000000B50100EF
+:103B2000010001060106010C010C01140114011C25
+:103B3000011C01240124012C012C01340134013C1D
+:103B4000013C01440144014C000000000000000061
+:103B50000000000000000000000000000000000065
+:103B60000000000000000000000000000000000055
+:103B70000000000000000000000000000000000045
+:103B80000000000000000000000000000000000035
+:103B90000000000000000000000000000000000025
+:103BA0000000000000000000000000000000000015
+:103BB0000000000000000000000000000000000005
+:103BC00000000000000000000000000000000000F5
+:103BD00000000000000000000000000000000000E5
+:103BE00000000000000000000000000000000000D5
+:103BF0000000000000000000014C01510000000026
+:103C000000000000015101520152015301530154BF
+:103C100001540155015501560156015701570158EC
+:103C200001580159000000000000000000000000E1
+:103C30000000000000000000000000000000000084
+:103C40000000000000000000000000000000000074
+:103C50000159015E015E016A016A017600000000FF
+:103C60000000000000000000000000000000000054
+:103C70000000000000000000000000000000000044
+:103C80000000000000000000000000000000000034
+:103C90000000000000000000000000000000000024
+:103CA0000000000000000000017601770000000025
+:103CB0000000000000000000000000000000000004
+:103CC00000000000000000000000000000000000F4
+:103CD000000000000177019A0000000000000000D1
+:103CE00000000000000000000000000000000000D4
+:103CF00000000000000000000000000000000000C4
+:103D0000019A01C200000000000000000000000055
+:103D100000000000000000000000000000000000A3
+:103D200000000000000000000000000001C201F3DC
+:103D3000000000000000000001F301FA01FA020196
+:103D4000020102080208020F020F02160216021DEB
+:103D5000021D02240224022B022B02630000000039
+:103D600000000000026302670267026B026B026FD1
+:103D7000026F0273027302770277027B027B027F7B
+:103D8000027F0283028302D102D102EB02EB030520
+:103D9000030503080308030B030B030E030E0311B3
+:103DA00003110314031403170317031A031A031D43
+:103DB000031D035E035E0362036203660366036919
+:103DC0000369036C036C036F036F03720372037563
+:103DD000037503780378037B037B037E037E037FF5
+:103DE00000000000000000000000000000000000D3
+:103DF00000000000000000000000000000000000C3
+:103E00000000000000000000037F0391000000009C
+:103E100000000000000000000000000000000000A2
+:103E20000000000000000000000000000000000092
+:103E300000000000039103A603A603A903A903AC95
+:103E40000000000000000000000000000000000072
+:103E50000000000000000000000000000000000062
+:103E600003AC03D9000000000000000000000000C7
+:103E70000000000000000000000000000000000042
+:103E800000000000000000000000000003D904DC76
+:103E90000000000000000000000000000000000022
+:103EA0000000000000000000000000000000000012
+:103EB000000000000000000004DC04E304E304E769
+:103EC00004E704EB00000000000000000000000018
+:103ED00000000000000000000000000000000000E2
+:103EE0000000000004EB052B0000000000000000B3
+:103EF000052B05340534053D053D05460546054FB2
+:103F0000054F0558055805610561056A056A057381
+:103F1000057305CB05CB05DD05DD05EF05EF05F2E6
+:103F200005F205F505F505F805F805FB05FB05FEA9
+:103F300005FE060106010604060406070607060E2E
+:103F40000000000000000000000000000000000071
+:103F50000000000000000000000000000000000061
+:103F60000000000000000000060E06140000000023
+:103F70000000000000000000000000000000000041
+:103F80000000000000000000000000000000000031
+:103F900000000000061406170000000000000000EA
+:103FA0000000000000000000000000000000000011
+:103FB0000000000000000000000000000000000001
+:103FC0000617061D000000000000000000000000B1
+:103FD00000000000000000000000000000000000E1
+:103FE00000000000000000000000000000000000D1
+:103FF0000000000000000000061D062C062C063BF9
+:10400000063B064A064A06590659066806680677B8
+:1040100006770686068606950695070600000000C8
+:104020000000000000000000000000000000000090
+:104030000000000000000000000000000000000080
+:1040400000000000070607190719072A072A073B7F
+:104050000000000000000000000000000000000060
+:104060000000000000000000000000000000000050
+:10407000000000000000000000010000000204C079
+:104080000003098000040E4000051300000617C05D
+:1040900000071C800008214000092600000A2AC0F1
+:1040A000000B2F80000C3440000D3900000E3DC085
+:1040B000000F42800010474000114C00001250C019
+:1040C0000013558000145A4000155F00001663C0AD
+:1040D0000017688000186D4000197200001A76C041
+:1040E000001B7B80001C8040001D8500001E89C0D5
+:1040F000001F8E8000209340000020000000400040
+:1041000000006000000080000000A0000000C0006F
+:104110000000E0000001000000012000000140005C
+:1041200000016000000180000001A0000001C0004B
+:104130000001E00000020000000220000002400038
+:1041400000026000000280000002A0000002C00027
+:104150000002E00000030000000320000003400014
+:1041600000036000000380000003A0000003C00003
+:104170000003E000000400000004200000044000F0
+:1041800000046000000480000004A0000004C000DF
+:104190000004E000000500000005200000054000CC
+:1041A00000056000000580000005A0000005C000BB
+:1041B0000005E000000600000006200000064000A8
+:1041C00000066000000680000006A0000006C00097
+:1041D0000006E00000070000000720000007400084
+:1041E00000076000000780000007A0000007C00073
+:1041F0000007E00000080000000820000008400060
+:1042000000086000000880000008A0000008C0004E
+:104210000008E0000009000000092000000940003B
+:1042200000096000000980000009A0000009C0002A
+:104230000009E000000A0000000A2000000A400017
+:10424000000A6000000A8000000AA000000AC00006
+:10425000000AE000000B0000000B2000000B4000F3
+:10426000000B6000000B8000000BA000000BC000E2
+:10427000000BE000000C0000000C2000000C4000CF
+:10428000000C6000000C8000000CA000000CC000BE
+:10429000000CE000000D0000000D2000000D4000AB
+:1042A000000D6000000D8000000DA000000DC0009A
+:1042B000000DE000000E0000000E2000000E400087
+:1042C000000E6000000E8000000EA000000EC00076
+:1042D000000EE000000F0000000F2000000F400063
+:1042E000000F6000000F8000000FA000000FC00052
+:1042F000000FE0000010000000102000001040003F
+:1043000000106000001080000010A0000010C0002D
+:104310000010E0000011000000112000001140001A
+:1043200000116000001180000011A0000011C00009
+:104330000011E000001200000012200000124000F6
+:1043400000126000001280000012A0000012C000E5
+:104350000012E000001300000013200000134000D2
+:1043600000136000001380000013A0000013C000C1
+:104370000013E000001400000014200000144000AE
+:1043800000146000001480000014A0000014C0009D
+:104390000014E0000015000000152000001540008A
+:1043A00000156000001580000015A0000015C00079
+:1043B0000015E00000160000001620000016400066
+:1043C00000166000001680000016A0000016C00055
+:1043D0000016E00000170000001720000017400042
+:1043E00000176000001780000017A0000017C00031
+:1043F0000017E0000018000000182000001840001E
+:1044000000186000001880000018A0000018C0000C
+:104410000018E000001900000019200000194000F9
+:1044200000196000001980000019A0000019C000E8
+:104430000019E000001A0000001A2000001A4000D5
+:10444000001A6000001A8000001AA000001AC000C4
+:10445000001AE000001B0000001B2000001B4000B1
+:10446000001B6000001B8000001BA000001BC000A0
+:10447000001BE000001C0000001C2000001C40008D
+:10448000001C6000001C8000001CA000001CC0007C
+:10449000001CE000001D0000001D2000001D400069
+:1044A000001D6000001D8000001DA000001DC00058
+:1044B000001DE000001E0000001E2000001E400045
+:1044C000001E6000001E8000001EA000001EC00034
+:1044D000001EE000001F0000001F2000001F400021
+:1044E000001F6000001F8000001FA000001FC00010
+:1044F000001FE000002000000020200000204000FD
+:1045000000206000002080000020A0000020C000EB
+:104510000020E000002100000021200000214000D8
+:1045200000216000002180000021A0000021C000C7
+:104530000021E000002200000022200000224000B4
+:1045400000226000002280000022A0000022C000A3
+:104550000022E00000230000002320000023400090
+:1045600000236000002380000023A0000023C0007F
+:104570000023E0000024000000242000002440006C
+:1045800000246000002480000024A0000024C0005B
+:104590000024E00000250000002520000025400048
+:1045A00000256000002580000025A0000025C00037
+:1045B0000025E00000260000002620000026400024
+:1045C00000266000002680000026A0000026C00013
+:1045D0000026E00000270000002720000027400000
+:1045E00000276000002780000027A0000027C000EF
+:1045F0000027E000002800000028200000284000DC
+:1046000000286000002880000028A0000028C000CA
+:104610000028E000002900000029200000294000B7
+:1046200000296000002980000029A0000029C000A6
+:104630000029E000002A0000002A2000002A400093
+:10464000002A6000002A8000002AA000002AC00082
+:10465000002AE000002B0000002B2000002B40006F
+:10466000002B6000002B8000002BA000002BC0005E
+:10467000002BE000002C0000002C2000002C40004B
+:10468000002C6000002C8000002CA000002CC0003A
+:10469000002CE000002D0000002D2000002D400027
+:1046A000002D6000002D8000002DA000002DC00016
+:1046B000002DE000002E0000002E2000002E400003
+:1046C000002E6000002E8000002EA000002EC000F2
+:1046D000002EE000002F0000002F2000002F4000DF
+:1046E000002F6000002F8000002FA000002FC000CE
+:1046F000002FE000003000000030200000304000BB
+:1047000000306000003080000030A0000030C000A9
+:104710000030E00000310000003120000031400096
+:1047200000316000003180000031A0000031C00085
+:104730000031E00000320000003220000032400072
+:1047400000326000003280000032A0000032C00061
+:104750000032E0000033000000332000003340004E
+:1047600000336000003380000033A0000033C0003D
+:104770000033E0000034000000342000003440002A
+:1047800000346000003480000034A0000034C00019
+:104790000034E00000350000003520000035400006
+:1047A00000356000003580000035A0000035C000F5
+:1047B0000035E000003600000036200000364000E2
+:1047C00000366000003680000036A0000036C000D1
+:1047D0000036E000003700000037200000374000BE
+:1047E00000376000003780000037A0000037C000AD
+:1047F0000037E0000038000000382000003840009A
+:1048000000386000003880000038A0000038C00088
+:104810000038E00000390000003920000039400075
+:1048200000396000003980000039A0000039C00064
+:104830000039E000003A0000003A2000003A400051
+:10484000003A6000003A8000003AA000003AC00040
+:10485000003AE000003B0000003B2000003B40002D
+:10486000003B6000003B8000003BA000003BC0001C
+:10487000003BE000003C0000003C2000003C400009
+:10488000003C6000003C8000003CA000003CC000F8
+:10489000003CE000003D0000003D2000003D4000E5
+:1048A000003D6000003D8000003DA000003DC000D4
+:1048B000003DE000003E0000003E2000003E4000C1
+:1048C000003E6000003E8000003EA000003EC000B0
+:1048D000003EE000003F0000003F2000003F40009D
+:1048E000003F6000003F8000003FA000003FC0008C
+:1048F000003FE000003FE00100000000000001FF79
+:104900000000020000007FF800007FF800000704AC
+:104910000000350000000001FFFFFFFFFFFFFFFF69
+:10492000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF97
+:10493000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87
+:10494000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF77
+:10495000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF67
+:10496000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF57
+:10497000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF47
+:10498000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF37
+:10499000FFFFFFFFFFFFFFFFFFFFFFFF0000000023
+:1049A000FFFFFFFF00000000FFFFFFFFFFFFFFFF13
+:1049B00000000000FFFFFFFF00000000FFFFFFFFFF
+:1049C000FFFFFFFF00000000FFFFFFFF00000000EF
+:1049D000FFFFFFFF0000000300BEBC20FFFFFFFF42
+:1049E00000000000FFFFFFFF00000000FFFFFFFFCF
+:1049F0000000000300BEBC20FFFFFFFF000000001E
+:104A0000FFFFFFFF00000000FFFFFFFF00000003AB
+:104A100000BEBC20FFFFFFFF00000000FFFFFFFF04
+:104A200000000000FFFFFFFF0000000300BEBC20ED
+:104A3000FFFFFFFF00000000FFFFFFFF000000007E
+:104A4000FFFFFFFF0000000300BEBC20FFFFFFFFD1
+:104A500000000000FFFFFFFF00000000FFFFFFFF5E
+:104A60000000000300BEBC2000002000000040C089
+:104A700000006180000082400000A3000000C3C06D
+:104A80000000E4800001054000012600000146C04E
+:104A900000016780000188400001A9000001C9C031
+:104AA0000001EA8000020B4000022C0000024CC012
+:104AB00000026D8000028E400002AF000002CFC0F5
+:104AC0000002F0800003114000033200000352C0D6
+:104AD00000037380000394400003B5000003D5C0B9
+:104AE0000003F6800004174000043800000458C09A
+:104AF0000004798000049A400000800000010380D7
+:104B00000001870000020A8000028E00000311806D
+:104B1000000395000004188000049C0000051F801D
+:104B20000005A300000626800006AA0000072D80CD
+:104B30000007B100000834800008B80000093B807D
+:104B40000009BF00000A4280000AC600000B49802D
+:104B5000000BCD00000C5080000CD400000D5780DD
+:104B6000000DDB0000007FF800007FF800000487E4
+:104B700000001500000019000000002800100000CF
+:104B80000000000000000000FFFFFFFF40000000E9
+:104B90004000000040000000400000004000000015
+:104BA0004000000040000000400000004000000005
+:104BB00040000000400000004000000040000000F5
+:104BC00040000000400000004000000040000000E5
+:104BD00040000000400000004000000040000000D5
+:104BE00040000000400000004000000040000000C5
+:104BF00040000000400000004000000040000000B5
+:104C000040000000400000004000000000007FF86D
+:104C100000007FF8000003E000001500FFFFFFFF29
+:104C2000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF94
+:104C3000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF84
+:104C4000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF74
+:104C5000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF64
+:104C6000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF54
+:104C7000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF44
+:104C8000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF34
+:104C9000FFFFFFFFFFFFFFFFFFFFFFFF40000000E0
+:104CA0004000000040000000400000004000000004
+:104CB00040000000400000004000000040000000F4
+:104CC00040000000400000004000000040000000E4
+:104CD00040000000400000004000000040000000D4
+:104CE00040000000400000004000000040000000C4
+:104CF00040000000400000004000000040000000B4
+:104D000040000000400000004000000040000000A3
+:104D100040000000400000004000000000001000C3
+:104D2000000020800000310000004180000052009F
+:104D30000000628000007300000083800000940087
+:104D40000000A4800000B5000000C5800000D6006F
+:104D50000000E6800000F700000107800001180055
+:104D600000012880000139000001498000015A003B
+:104D700000016A8000017B0000018B8000019C0023
+:104D80000001AC800001BD000001CD800001DE000B
+:104D90000001EE800001FF0000007FF800007FF8B6
+:104DA0000000023E0000350010000000000028ADA9
+:104DB000000000000001000100350804CCCCCCC587
+:104DC000FFFFFFFFFFFFFFFF7058103C00000000D7
+:104DD000CCCC0201CCCCCCCCCCCC0201CCCCCCCC3D
+:104DE000CCCC0201CCCCCCCCCCCC0201CCCCCCCC2D
+:104DF000CCCC0201CCCCCCCCCCCC0201CCCCCCCC1D
+:104E0000CCCC0201CCCCCCCCCCCC0201CCCCCCCC0C
+:104E100000000000FFFFFFFF400000004000000016
+:104E20004000000040000000400000004000000082
+:104E30004000000040000000400000004000000072
+:104E40004000000040000000400000004000000062
+:104E50004000000040000000400000004000000052
+:104E60004000000040000000400000004000000042
+:104E70004000000040000000400000004000000032
+:104E80004000000040000000400000004000000022
+:104E90004000000040000000000E0232011600D663
+:104EA000001000000000000000720236012300F331
+:104EB00000100000000000000000FFFF00000000E4
+:104EC0000000FFFF000000000000FFFF00000000E6
+:104ED0000000FFFF000000000000FFFF00000000D6
+:104EE0000000FFFF000000000000FFFF00000000C6
+:104EF0000000FFFF000000000000FFFF00000000B6
+:104F00000000FFFF000000000000FFFF00000000A5
+:104F10000000FFFF000000000000FFFF0000000095
+:104F20000000FFFF000000000000FFFF0000000085
+:104F30000000FFFF000000000000FFFF0000000075
+:104F40000000FFFF000000000000FFFF0000000065
+:104F50000000FFFF000000000000FFFF0000000055
+:104F60000000FFFF000000000000FFFF0000000045
+:104F70000000FFFF000000000000FFFF0000000035
+:104F80000000FFFF000000000000FFFF0000000025
+:104F90000000FFFF000000000000FFFF0000000015
+:104FA0000000FFFF000000000000FFFF0000000005
+:104FB0000000FFFF000000000000FFFF00000000F5
+:104FC0000000FFFF000000000000FFFF00000000E5
+:104FD0000000FFFF000000000000FFFF00000000D5
+:104FE0000000FFFF000000000000FFFF00000000C5
+:104FF0000000FFFF000000000000FFFF00000000B5
+:105000000000FFFF000000000000FFFF00000000A4
+:105010000000FFFF000000000000FFFF0000000094
+:105020000000FFFF000000000000FFFF0000000084
+:105030000000FFFF000000000000FFFF0000000074
+:105040000000FFFF000000000000FFFF0000000064
+:105050000000FFFF000000000000FFFF0000000054
+:105060000000FFFF000000000000FFFF0000000044
+:105070000000FFFF000000000000FFFF0000000034
+:105080000000FFFF000000000000FFFF0000000024
+:105090000000FFFF000000000000FFFF0000000014
+:1050A0000000FFFF000000000000FFFF0000000004
+:1050B0000000FFFF00000000FFFFFFF3320FFFFFC3
+:1050C0000C30C30CC30C30C3CF3CF300F3CF3CF324
+:1050D0000000CF3CCDCDCDCDFFFFFFF130EFFFFF86
+:1050E0000C30C30CC30C30C3CF3CF300F3CF3CF304
+:1050F0000001CF3CCDCDCDCDFFFFFFF6305FFFFFF0
+:105100000C30C30CC30C30C3CF3CF300F3CF3CF3E3
+:105110000002CF3CCDCDCDCDFFFFF4061CBFFFFF7D
+:105120000C30C305C30C30C3CF300014F3CF3CF3B5
+:105130000004CF3CCDCDCDCDFFFFFFF2304FFFFFC0
+:105140000C30C30CC30C30C3CF3CF300F3CF3CF3A3
+:105150000008CF3CCDCDCDCDFFFFFFFA302FFFFFB4
+:105160000C30C30CC30C30C3CF3CF300F3CF3CF383
+:105170000010CF3CCDCDCDCDFFFFFFF731EFFFFFCE
+:105180000C30C30CC30C30C3CF3CF300F3CF3CF363
+:105190000020CF3CCDCDCDCDFFFFFFF5302FFFFF61
+:1051A0000C30C30CC30C30C3CF3CF300F3CF3CF343
+:1051B0000040CF3CCDCDCDCDFFFFFFF3310FFFFF42
+:1051C0000C30C30CC30C30C3CF3CF300F3CF3CF323
+:1051D0000000CF3CCDCDCDCDFFFFFFF1310FFFFF64
+:1051E0000C30C30CC30C30C3CF3CF300F3CF3CF303
+:1051F0000001CF3CCDCDCDCDFFFFFFF6305FFFFFEF
+:105200000C30C30CC30C30C3CF3CF300F3CF3CF3E2
+:105210000002CF3CCDCDCDCDFFFFF4061CBFFFFF7C
+:105220000C30C305C30C30C3CF300014F3CF3CF3B4
+:105230000004CF3CCDCDCDCDFFFFFFF2304FFFFFBF
+:105240000C30C30CC30C30C3CF3CF300F3CF3CF3A2
+:105250000008CF3CCDCDCDCDFFFFFFFA302FFFFFB3
+:105260000C30C30CC30C30C3CF3CF300F3CF3CF382
+:105270000010CF3CCDCDCDCDFFFFFFF730EFFFFFCE
+:105280000C30C30CC30C30C3CF3CF300F3CF3CF362
+:105290000020CF3CCDCDCDCDFFFFFFF5304FFFFF40
+:1052A0000C30C30CC30C30C3CF3CF300F3CF3CF342
+:1052B0000040CF3CCDCDCDCDFFFFFFF331EFFFFF61
+:1052C0000C30C30CC30C30C3CF3CF300F3CF3CF322
+:1052D0000000CF3CCDCDCDCDFFFFFFF1310FFFFF63
+:1052E0000C30C30CC30C30C3CF3CF300F3CF3CF302
+:1052F0000001CF3CCDCDCDCDFFFFFFF6305FFFFFEE
+:105300000C30C30CC30C30C3CF3CF300F3CF3CF3E1
+:105310000002CF3CCDCDCDCDFFFFF4061CBFFFFF7B
+:105320000C30C305C30C30C3CF300014F3CF3CF3B3
+:105330000004CF3CCDCDCDCDFFFFFFF2304FFFFFBE
+:105340000C30C30CC30C30C3CF3CF300F3CF3CF3A1
+:105350000008CF3CCDCDCDCDFFFFFFFA302FFFFFB2
+:105360000C30C30CC30C30C3CF3CF300F3CF3CF381
+:105370000010CF3CCDCDCDCDFFFFFF97056FFFFFD8
+:105380000C30C30CC30C30C3CF3CC000F3CF3CF394
+:105390000020CF3CCDCDCDCDFFFFFFF5310FFFFF7E
+:1053A0000C30C30CC30C30C3CF3CF300F3CF3CF341
+:1053B0000040CF3CCDCDCDCDFFFFFFF3320FFFFF3F
+:1053C0000C30C30CC30C30C3CF3CF300F3CF3CF321
+:1053D0000000CF3CCDCDCDCDFFFFFFF1310FFFFF62
+:1053E0000C30C30CC30C30C3CF3CF300F3CF3CF301
+:1053F0000001CF3CCDCDCDCDFFFFFFF6305FFFFFED
+:105400000C30C30CC30C30C3CF3CF300F3CF3CF3E0
+:105410000002CF3CCDCDCDCDFFFFF4061CBFFFFF7A
+:105420000C30C305C30C30C3CF300014F3CF3CF3B2
+:105430000004CF3CCDCDCDCDFFFFFFF2304FFFFFBD
+:105440000C30C30CC30C30C3CF3CF300F3CF3CF3A0
+:105450000008CF3CCDCDCDCDFFFFFF8A042FFFFF4D
+:105460000C30C30CC30C30C3CF3CC000F3CF3CF3B3
+:105470000010CF3CCDCDCDCDFFFFFF9705CFFFFF77
+:105480000C30C30CC30C30C3CF3CC000F3CF3CF393
+:105490000020CF3CCDCDCDCDFFFFFFF5310FFFFF7D
+:1054A0000C30C30CC30C30C3CF3CF300F3CF3CF340
+:1054B0000040CF3CCDCDCDCDFFFFFFF3316FFFFFDF
+:1054C0000C30C30CC30C30C3CF3CF300F3CF3CF320
+:1054D0000000CF3CCDCDCDCDFFFFFFF1302FFFFF42
+:1054E0000C30C30CC30C30C3CF3CF300F3CF3CF300
+:1054F0000001CF3CCDCDCDCDFFFFFFF6305FFFFFEC
+:105500000C30C30CC30C30C3CF3CF300F3CF3CF3DF
+:105510000002CF3CCDCDCDCDFFFFFFF630BFFFFF6A
+:105520000C30C30CC30C30C3CF3CF314F3CF3CF3AB
+:105530000004CF3CCDCDCDCDFFFFFFF2304FFFFFBC
+:105540000C30C30CC30C30C3CF3CF300F3CF3CF39F
+:105550000008CF3CCDCDCDCDFFFFFFFA302FFFFFB0
+:105560000C30C30CC30C30C3CF3CF300F3CF3CF37F
+:105570000010CF3CCDCDCDCDFFFFFFF731CFFFFFEA
+:105580000C30C30CC30C30C3CF3CF300F3CF3CF35F
+:105590000020CF3CCDCDCDCDFFFFFFF0307FFFFF12
+:1055A0000C30C30CC30C30C3CF3CF300F3CF3CF33F
+:1055B0000040CF3CCDCDCDCDFFFFFFFF30CFFFFF73
+:1055C0000C30C30CC30C30C3CF3CF3CCF3CF3CF353
+:1055D0000000CF3CCDCDCDCDFFFFFFFF30CFFFFF93
+:1055E0000C30C30CC30C30C3CF3CF3CCF3CF3CF333
+:1055F0000001CF3CCDCDCDCDFFFFFFFF30CFFFFF72
+:105600000C30C30CC30C30C3CF3CF3CCF3CF3CF312
+:105610000002CF3CCDCDCDCDFFFFFFFF30CFFFFF50
+:105620000C30C30CC30C30C3CF3CF3CCF3CF3CF3F2
+:105630000004CF3CCDCDCDCDFFFFFFFF30CFFFFF2E
+:105640000C30C30CC30C30C3CF3CF3CCF3CF3CF3D2
+:105650000008CF3CCDCDCDCDFFFFFFFF30CFFFFF0A
+:105660000C30C30CC30C30C3CF3CF3CCF3CF3CF3B2
+:105670000010CF3CCDCDCDCDFFFFFFFF30CFFFFFE2
+:105680000C30C30CC30C30C3CF3CF3CCF3CF3CF392
+:105690000020CF3CCDCDCDCDFFFFFFFF30CFFFFFB2
+:1056A0000C30C30CC30C30C3CF3CF3CCF3CF3CF372
+:1056B0000040CF3CCDCDCDCDFFFFFFFF30CFFFFF72
+:1056C0000C30C30CC30C30C3CF3CF3CCF3CF3CF352
+:1056D0000000CF3CCDCDCDCDFFFFFFFF30CFFFFF92
+:1056E0000C30C30CC30C30C3CF3CF3CCF3CF3CF332
+:1056F0000001CF3CCDCDCDCDFFFFFFFF30CFFFFF71
+:105700000C30C30CC30C30C3CF3CF3CCF3CF3CF311
+:105710000002CF3CCDCDCDCDFFFFFFFF30CFFFFF4F
+:105720000C30C30CC30C30C3CF3CF3CCF3CF3CF3F1
+:105730000004CF3CCDCDCDCDFFFFFFFF30CFFFFF2D
+:105740000C30C30CC30C30C3CF3CF3CCF3CF3CF3D1
+:105750000008CF3CCDCDCDCDFFFFFFFF30CFFFFF09
+:105760000C30C30CC30C30C3CF3CF3CCF3CF3CF3B1
+:105770000010CF3CCDCDCDCDFFFFFFFF30CFFFFFE1
+:105780000C30C30CC30C30C3CF3CF3CCF3CF3CF391
+:105790000020CF3CCDCDCDCDFFFFFFFF30CFFFFFB1
+:1057A0000C30C30CC30C30C3CF3CF3CCF3CF3CF371
+:1057B0000040CF3CCDCDCDCDFFFFFFFF30CFFFFF71
+:1057C0000C30C30CC30C30C3CF3CF3CCF3CF3CF351
+:1057D0000000CF3CCDCDCDCDFFFFFFFF30CFFFFF91
+:1057E0000C30C30CC30C30C3CF3CF3CCF3CF3CF331
+:1057F0000001CF3CCDCDCDCDFFFFFFFF30CFFFFF70
+:105800000C30C30CC30C30C3CF3CF3CCF3CF3CF310
+:105810000002CF3CCDCDCDCDFFFFFFFF30CFFFFF4E
+:105820000C30C30CC30C30C3CF3CF3CCF3CF3CF3F0
+:105830000004CF3CCDCDCDCDFFFFFFFF30CFFFFF2C
+:105840000C30C30CC30C30C3CF3CF3CCF3CF3CF3D0
+:105850000008CF3CCDCDCDCDFFFFFFFF30CFFFFF08
+:105860000C30C30CC30C30C3CF3CF3CCF3CF3CF3B0
+:105870000010CF3CCDCDCDCDFFFFFFFF30CFFFFFE0
+:105880000C30C30CC30C30C3CF3CF3CCF3CF3CF390
+:105890000020CF3CCDCDCDCDFFFFFFFF30CFFFFFB0
+:1058A0000C30C30CC30C30C3CF3CF3CCF3CF3CF370
+:1058B0000040CF3CCDCDCDCD001000000007010051
+:1058C00000028170000B81980002025000010270FA
+:1058D000000F028000010370000800000008008033
+:1058E00000028100000B8128000201E0000102009B
+:1058F0000007021000020280000F0000000800F004
+:1059000000028170000B81980002025000010270B9
+:10591000000B82800008033800100000000801001E
+:1059200000028180000B81A80002026000018280D9
+:10593000000E829800080380000B0000000100B0F8
+:10594000000280C0000580E8000201400001016003
+:10595000000E017000038250CCCCCCCCCCCCCCCC93
+:10596000CCCCCCCCCCCCCCCC00002000CCCCCCCC87
+:10597000CCCCCCCCCCCCCCCCCCCCCCCC0000200077
+:10598000CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC57
+:1059900004002000000000001F8B08000000000031
+:1059A00000FFFB51CFC0F0038A277033309CE345E2
+:1059B000F0E981831829D35FC6CEC05001C4554099
+:1059C000BC0B883FB132307C66255EFF352904DB95
+:1059D000488281211E88D7883130A84922C41DA45D
+:1059E00019182603F9A150B147403A5F8A32770F60
+:1059F000169CA68029E62A8760A7639147C6196886
+:105A0000F24BE550F99904F40F34BEA28ECAFFA2FE
+:105A10000AA113A0E257D1E4BF42E53BA0FEBAA61B
+:105A20008EDDDC4E32FD5DC302A101FC99B04798CA
+:105A300003000000000000001F8B080000000000B1
+:105A400000FFED7D0B7854D5B5F03E731E3393798E
+:105A5000E424E43181104E1E2068080384888AB74C
+:105A6000271030F6D27678D5582D0EAF10F2866B0F
+:105A70002DBDB67F06084978A8C11F11ADD5E12913
+:105A8000F6821D3122B6880328D2ABBD37587C552B
+:105A9000EB1FD10B8A90442A6AEFB5E5EEB5F63ECE
+:105AA000C99C9309047BDBAFFFFFFD7C9FEEECC735
+:105AB000D97BEDF5DA6BADFD18C93181A40D23E476
+:105AC00022FCFB0621929D1032A1379DE32021D7B5
+:105AD000184292662FFDDD921442DCBAE2BF49A360
+:105AE000A9BBFEE41A9A5F5FECF0AFA44D5B1F4DBB
+:105AF000786A092DBFEFA12FC34FD07CFAEC79ADA6
+:105B0000C5B47ECE24C90F5D1D1AAB1002EDE7D8D7
+:105B1000C276015281E5979030A17F92AFE8F845B7
+:105B200084B8E89F2497FE37891CB2A5603EE4D173
+:105B3000A09E029946483631FE55607E36FC09F536
+:105B4000447767D0EF759E77E513EC7F8E5F0ADBB5
+:105B5000E94773F20372C84DD3C6086D49C71DFBF0
+:105B60005D3908F9C00C99E46387B6D8FE6FCA0F97
+:105B70004C7514D2FE670B08FFF9D94936DA82CC8E
+:105B8000A6EDE13B224E1F1ACC679FD9E8B8DFE0B3
+:105B9000DFDDDF40FFA7C05F4B09A1E5CB1C0C9EFA
+:105BA000E4D9D9C530CE8919D71643BF73A61332AD
+:105BB00088564D9D3DF69044F3EB1A89DF4EDBCDC0
+:105BC000290D1CCF81D9F8CBA79302E8978EEE6000
+:105BD0007D5FC4FFEB38EF643EDE3FCC1E2B10FA36
+:105BE00041F6978AA95D72A0F953D14B486A052DF9
+:105BF0001F1953EE9F769AD0F2E4E9E6F64013724D
+:105C00001D2125C49372EA1AFA7716C9BA2842AD43
+:105C10006A0B8CEEE50F6B4AFFFDF922D001FA12F8
+:105C2000FBD61F6A9CE9E9A0F85A377B9687D0F427
+:105C3000F5C02C0FE0EFF5D9B3108FD6F673666779
+:105C400027025EFB1BEFFE063AD008FA3DC7B3B54C
+:105C50007E9048EA23F4FB393AD1C331FDDF01934A
+:105C60004D256409301B4DB325D5A6D2FA6C8DE8BD
+:105C70009138E39502B1693B92499928E352F30FB9
+:105C800061BB3726D94AC371E67307EFC7551AB807
+:105C9000670EA56FD674127551BA1229AAC6E2759D
+:105CA0005D8A541A8E03C7DD1C5E42687BCFC0E15B
+:105CB0007165D802D09F32470CC4C2F50380674299
+:105CC0006F4AA24CEEE6F818FD72BFFB6C508F33A2
+:105CD0008FBB008E0990AAEC3B0E8F0C7C9301B217
+:105CE0009682FC43C26324E0FBCC1EB9240107E585
+:105CF0008FA1F01715AE2DA47BD41214B256EC4729
+:105D0000F4A42403BD5711DE0F29514F517E1542D3
+:105D1000AB848BD75C6A9E123965F035F0A93B19CC
+:105D2000C7BF1C5E48A018E55231D48878C007E38D
+:105D30002BF94DED02A5CBBAD1E57E946F8A219067
+:105D400033437EE1DF57F43B37FFCCBD9CD291CA91
+:105D5000916B39D38F8ADF2C67EB928EB50820C800
+:105D600064B9490F1012244077036FEBBEA278BCD0
+:105D700004BF5BFBDD6FC8E7603298C927933F051E
+:105D8000FA07BD79D37E07F0F53ADF5E07CC6B5D8D
+:105D9000FE5E827A8AD3C7E8D795AF5D52CED681B0
+:105DA0007C8D80EEC348A79EF2D1A7C6027E76A660
+:105DB0002AF78B747E3B9308EAD9756B48782BD011
+:105DC000B594E5B56F69E1B5748E3B9DBCBE98D6C0
+:105DD000D3BC06EDA9BEDB3A490B87687E6B8B8D81
+:105DE000B51FAB85459A1F319184148A4F6DC5C28A
+:105DF000954E5ABE75A3EA17B55EFD34A225672DF0
+:105E0000B4DFB2DEA60AF0BD8FAD233BF3493844C0
+:105E1000C7DFB139F99B23693E14B2F987D34FF23A
+:105E2000F8FA45D9A5442802B4313A9C21795CAEF0
+:105E30000402E5A9BC7CCB7EFFBF8EA4F03D365D9D
+:105E4000F2AFA0453BD6CF4CD0289E766881043F68
+:105E50004D7FF0C07CCCEFCC0C2600DD766E9C9F95
+:105E6000004CF1C0E6991B46417B61D2611DE96C93
+:105E7000D6FF471F283AEC00384B999E4F6A0D7E9B
+:105E800053A2F9BC4912B9894E21CFAD21DCDB1FE9
+:105E9000B211584FFBE86D8BBE4ED4CD7957EBB4A1
+:105EA0008F817F5D0F160920DA3B3586E7413792F7
+:105EB000F08AECBEE3EF5CC8EA13295D800E2EBFCA
+:105EC000625967965AF856477970713CB95A751CF1
+:105ED0008F487A8990D68B57FA9F4662F0E97AF01C
+:105EE0002881F5E98AE76381275DA07C0F83AB9C5D
+:105EF000EFB91E1CF7CA5763E3F1B121EF1EA07F73
+:105F000022C577612404EB507A61240AFCE2C95768
+:105F100034B00B9A0931C9C5A1D1FB7C1D203713C0
+:105F2000223E58AFD78D7E83C98F5681F830E66FF9
+:105F3000B4F7E4B79358FBC1A88772F8CE537869D9
+:105F400039BB87CB594F7F84AD4724731CC2754F33
+:105F5000E161755E1C7D4CC80A94CB9749E07A815B
+:105F6000A6DECDED51A7066CAEDF0079B7400291F9
+:105F700038DF4D13D87AD242745DA0E9A3442F16BE
+:105F8000709D4B66FAD7B22EF5D19FBC5D16E9160F
+:105F900040DF68D43E803487F831CD23014C4792EE
+:105FA000564CAF26114CF3493BA605A41B5343AFF7
+:105FB000F8892A427EC4C4FAC920E7A4DA638BE5D3
+:105FC000BBD06432B23ECE3C9A2D787390F8EBF899
+:105FD0001D025FE748A68AFC43F87AF16EB018E824
+:105FE000C55428FCBBDBCCEFE224BE0E38EA3D6989
+:105FF000805733DD8D5454CD7C5A6DF0A944241C58
+:10600000C7321FC463CCB8D6FE5673FBC6989F9C9C
+:10601000A2231F496E66CF5038F4BD71F0D1280815
+:106020007C9E41ABDC3AB229BF4B49B6C85A9A6B49
+:10603000744F76E8382F3F894767EB7CACF02ABE77
+:1060400081C1B3A9079E0ACB3AFA97C2F34FA6FEC5
+:10605000A44CB21DD60BA28670DE56BCF6F9DE4209
+:106060008FFEE4D29169D6574A8AD70287859F0668
+:10607000687F7CE34BEA7FE4C3FA1B21412AECA949
+:10608000F90101E67FAD401A13295EC868A2EDA0B0
+:1060900070CDF56ACC8E8B693719F491660BC97493
+:1060A000BECF92EE23D03EE427911DF4B367F36D8B
+:1060B000A55B697DAA9FB663FD05401EAE1D6D0BF5
+:1060C00040B9D19F4E9E32F547FD2E11F0E136E8E2
+:1060D00063F1C3E4B136B41F957CA26F89235FC717
+:1060E000B97C151D71EAB09EB8CA94B0331BFA8F03
+:1060F00014433EB59AF8615D9FD4CDE651C6E130B8
+:10610000E69DFA5940007E6AF7313BC05548D03FC2
+:106110005432DA74F01FDDB40EF5427E541753503A
+:106120003FA23FD81F9E3D5F3DED0BD07E7DD4B991
+:106130006A07BE92FCE9A09F578F56C860FABDF867
+:106140003B3BF6FFB9A762188999CF470DD1B10B38
+:10615000A9C170A6E118A6671BDA31ED6C780BD3E4
+:10616000FEE94A598EDACEEB7EE2D7C01E100F3F11
+:1061700047340FC01DD5755C171CA212B32E808248
+:1061800006FF6FD3D8BCF0DA6CC46B08E64DD56758
+:10619000787836E05B0A009E873822C2D27C867708
+:1061A000C03FD001CA8B8E3CB702F15C4DC6029E47
+:1061B00037C9A40CF43CE013D6897D82ED0E800330
+:1061C000F2F369FEFA8FFAC1FB5986F78C97299E84
+:1061D000004E494B64C6AD8EF2953B910B12D7270A
+:1061E000BD7A92F9D9BDF6BDF6EF00CF964689ACDF
+:1061F00085BCA6684A11B7F7414A8215D3C1DFDCD6
+:10620000563EFD28D80BB9E25787645A3EB45E3A31
+:10621000D911234F596574FDA476C2B0E5E6F2ECBE
+:1062200090394F07407F34B7C55C3EC4C6F5AE8792
+:1062300078401EADF35AB6E85771FDD3550D24EAE8
+:106240009663F202C3A79117BC133B42747ECB4600
+:10625000118C034CB7B1F5B315BEA37C712F4FD78A
+:106260005BFA315269A2DB46C6303D196F7DBADD5B
+:10627000563CCE46FB6BB04D1E67A372E4922204DF
+:10628000EC77975BD1E3F993D36D128E9F20B5EB3A
+:106290002285ABFB3AE2DF4AF1BE4CEE8E827C2CCB
+:1062A0002BD6FC215047FE30CA6312D56162F61529
+:1062B000C153027050784A6C384E04FBE9A6380787
+:1062C000FB7D99CCFA5D364A236837F603E75536ED
+:1062D00019E10CD80409FD344E97551539F74DA333
+:1062E000D94E559F05FD67260567C17846B96F7E73
+:1062F00029FA6319C3CCF42B77D467017F540622A3
+:10630000D3807F4E7B5F6C92E9BCB73610BF44F1FF
+:10631000FF9E2B701BF457737BFD08B07FDF065E7A
+:1063200098002A3B807AACA564A55FA2E572891427
+:1063300095293FCA130FBF2517401A2A86388B9319
+:10634000D4337D47F54B2235BD1C23F58F217EA22A
+:10635000803CD072556F25600F38A8DB703286EF15
+:10636000944C731E6CFAD87C7F7AE3722998E727E5
+:106370008703FE09DAE9DD49CC7F9226FA0B00DEBD
+:106380007BAFFFA606F0FCC46633F967567F4D5A13
+:10639000FE6F69791068E2FEB6B4FCD5B4BCF1803A
+:1063A00097569C9763CA32940B05F02432F907BFC5
+:1063B000BE671DE478F85BCFDB582F5737BC35F844
+:1063C000C3E120A71D833FA4C4592D0591FF423E80
+:1063D000F0B5281C92998F09784F1362526E1718E6
+:1063E000F69B9C5A887494DCD2A98E98F5DDC08FF8
+:1063F000B2FCDDC11F8E87F46D4CAD7855A4200131
+:106400003FD068D713B718E0FAEF34E2A979C41F78
+:10641000A53873A4B0786A7A5E280AF37252FD092F
+:10642000EBD33D235F6BC5F081C50F3B94AD203F9F
+:10643000B48CB6615CB36578E49002F90C6A40D123
+:106440007A67CA5D21886D4CCD637CE3F4B3F5D4E3
+:10645000353C8C7E98A1BFBD1C1F5EAD1CF5B3679B
+:10646000A2D9DE31D601272BA2F436DB51CE94A679
+:106470004FC582BE7E9A539B761AE569A4B93F2325
+:10648000DED16EE3F18B6BC9B5683759E212FDE1DD
+:10649000CD6BF87113D9BCDCD34918FCE6F48951F3
+:1064A000C49BD7CFF066D89B1E3EBF9B4A2304FCFB
+:1064B000BE9EF8F3CD0C6FEBAF8BA27FB77EEC29BD
+:1064C000B467BD851D263FCEF81ECAA1FEFCC4766A
+:1064D000A8A1F618CB1B71238AA7E91969BDEB6146
+:1064E0002BB7DBAD7453279262D0634747A7158360
+:1064F000DEBEB784C24EAB3C7A589762F0ADF27EF6
+:10650000D47C86DF7BCBD87C697BF4D3EF9D9893DA
+:1065100004E366F2F8B0117FEEF1CBEBCD784F28B3
+:10652000B4C4852D7EB7EA67F4524BCCE5AB395F36
+:106530002B22A7572A19CEE835303E4F32F8BC84BB
+:10654000F17932DF37482FD10E011D924A99FF4D64
+:106550002C7EF34D291D8C5E378FC8003FFCFEA9B1
+:10656000DD3E669730BA26717EBCEFC61102C87157
+:10657000728926407D723EC35332C513AC77C9A5DC
+:10658000CCEFF64ED4B05D5209A35B0B7C4CE15FBF
+:1065900003748A891F3B4B5B75A07F6BF14E1D74A2
+:1065A0005932C5E1200ACFD4520A1BD89DB45F806E
+:1065B000D75318C5B85A524970D8A5FC7A42A2825E
+:1065C000CD87F8106C684BE93C25587E6862B22094
+:1065D000D07EEFA77CC0F180713C178FA3DF5F787E
+:1065E00012F5DCFDF04D36C8A9F6EB1C9A27A5364E
+:1065F0003FF807F797E608F1E2E7C6BCFB83CB2A32
+:10660000C712F83531FC7295C8E3DE16FE5D4722ED
+:106610006A2EC857486FF7A5F5EA0F83FF7AE4653D
+:1066200012E3CBFEF489A187DD2418B265F7D51FEC
+:1066300092CEF8DE9E174079EB03EF24C6AF528A64
+:10664000B9FC3691DB7F865ED19207142727A10023
+:10665000AE7722D74F4FDA020BC554F0BBC3B84E0A
+:10666000B8C874AE37199FCA9CFFA6E633BDE24A8C
+:1066700089B076978DA73A90DFD634A8A81F5AC65E
+:10668000DED59E43F1B06678931FBE738C6B19B94B
+:106690008DF6DB3C7C79702B0CC0FD30D4BF22AC76
+:1066A000838C5F8D7D30030E9219D2619FCC097E61
+:1066B00011E06724DB5F902412B58FEB1DDF954757
+:1066C000E1CD6769289FC10DFEC9EBB6E02A9C6F3A
+:1066D0007E6B94A29BCE9BC9CB6A21425C22CCEB01
+:1066E000727C1EB231BE8E9FF6F75D02ECD3C4E120
+:1066F000DFDD22DBA7592D478850087E1BED89F28C
+:10670000C9EA6C6A97C781A391F36BD52E67F8C36A
+:10671000187EAB892499F275FB33C21FC6FA117734
+:106720000AB84F51CDD158433AB200CFEF291AF6EB
+:10673000576BEB48837C17E94E5B027810038F8B15
+:1067400074FD7752BEC4B8907B60EBD6E5F0A781AC
+:106750000CD18540CBE4A90F79988E17DC07E3694B
+:106760002A2BBFD271E3F0F50BB17C4DC457596AA7
+:10677000E56B7F14F9DA9D12C57AB79FF1B5C18F29
+:10678000899C1FAD7C688CBF9EC7AFD6723E5F33BD
+:10679000A1498570DFDA519B309EE62CDA5C017CE2
+:1067A000DE32AA250C7CDE64F035DF17A1FE2EDB7D
+:1067B0001FD35AA3B04E2672BE56D4EE06907BEB82
+:1067C0007C5D9338BC3405BE06B8395FBF07F893CB
+:1067D000FDDD08AEC1D76B07CCD7BA456F9BD3FEA2
+:1067E000FC27D9C2D71E89F1E767C0D7004F0AB38B
+:1067F00063DC3E96CA7EEADFC7E9E70689F9996B52
+:10680000B91CACE572B0B61F39F83F22F303FE9A0B
+:1068100072308BC98143A2E58993AE8C1F25B0D31A
+:10682000E3C87B9E24FCB5E1DE3443BC723CFE270A
+:1068300030CD84BEF434D2CF44E7C0E43B8FC9737B
+:106840007F72BE76687C38FE5364F4A7F82E9226D9
+:106850005C39BEFF5A7015727E36F04382C528B788
+:10686000317A663AC02BA9869E7904D3A979AD28DE
+:10687000A786BE81580AFA2B6A2BC63B9C99AD6845
+:106880009F39F398BE31FC24EB7C8DB87813D73355
+:1068900049792102EB9F3D85703FAA9EF95199CC21
+:1068A0001F30E2D586FDA8187ED4D0BB709FA77993
+:1068B000783DDA97CD37D63BE2EDC336FBEE77F085
+:1068C0004D5FD33EEB1A5A0EFDAEC9BB9FC4B3C396
+:1068D0008C7918FB464E3E6E731EB5A8605CDF32A5
+:1068E000FCDE6AC73467B2FE7ABEE77A57EED1BBE8
+:1068F0002C8F76546E8C9F6FE9C7E00385E843A325
+:10690000103718E41E09E74C9A84043FD8C74D920B
+:10691000209D72901E7BA95A891640FF2766BC9C59
+:1069200085F6B23DB806E4BCE9AB8003E2A9AB53FF
+:106930005EF3C6969F9DF1E6B7C16CA5DFD5E27EFA
+:106940008E8348B1FB6327DCDBD17E4BC837C7E9B8
+:106950009C14AE0902C413CCE50A8FBF2899E672D5
+:1069600099C75FA4144B39E70FB934BE5E7993EB36
+:1069700015DF02764EE7C41C16D73B712B4F6730EC
+:10698000FE3EC7DB75F334C2F5EE5F531F25E5F617
+:10699000C2EF9BE2C7F822996547BB3E2B859D2B32
+:1069A00020B1E726E05F6BA24462FCCCA18197FF97
+:1069B00008F1D4610BBECA063C6B15EA615846DB90
+:1069C000A56C9CC76342F72818CFE63A8BFBF5020B
+:1069D00045E3726A120BF4DBDB2185EFBDC0523A4E
+:1069E0008F7B0591BFECC03722D0298CA98B44B195
+:1069F000DE433A309F081BE6B9E08751BF4BC433F2
+:106A00004C611BC68D7ECCF643D688786E83A80376
+:106A1000B4BFC9ED2AF89742887EE71AF877BE40DE
+:106A20006B31C8C4E0B208C693ADED7C53D839A031
+:106A30003E7AFBAF4FDF375273818F542C37E81CFF
+:106A400014F54E6942DFF25F8981F312C6AB58DC60
+:106A5000CD5A5F2AE91740DEACE5C20B7F3A057ECE
+:106A6000F4AA6764F4A3A73C2347BF41F3355B0452
+:106A7000F4536D079DE80F773EC2F2518FA243FB9E
+:106A800073DB058C07D5D9DBEFBD01E28ACF880423
+:106A9000FD8D7019EE8B9DE27326FB59BE9C07801D
+:106AA0006AB61C9A0BDF57ECB713D877A8796EF14A
+:106AB000B76FA0F9C5C764F4516A76AC50607F65C2
+:106AC00049588840BE6B32C1F143FBC4F00EDABEB8
+:106AD000CBDB9E36C70DFB2B0EA25D45E1F6B4A7BE
+:106AE000CDA6F4A90C3F350DBEABDC2DF8C1FF9847
+:106AF000F2CC8EA319F4BB9A27043CA750B5CB4522
+:106B0000B418BA9C6A13A3DF80F8339D27F8C58BAD
+:106B100049EB34C07BCD8E0D8A1613B73CD330922F
+:106B200068F6DE7CCD13741CFA5DED93821FA658C7
+:106B30006B2341E08FCEE79C65DBDC30BF15CA08D4
+:106B40000FCCAB5981768BC3F3F6C17E7A65788B17
+:106B5000328DD6573EB245298FE1A7AA5DD7102DB9
+:106B6000863F4E6DCE4DBFD47A7B86AE5BB1F0547E
+:106B700012A6B788145666C4EC7B76C8499C3F457C
+:106B800053FF06DF875E2718C70A3DEF41BC1A7422
+:106B90005BA632BD60D0EDBCCAE9287517CD88B3BD
+:106BA000AF7A2FD0C10EF12A15D3FB1B7C986E6CE7
+:106BB000D0903E9B007F57E1BE06967B279162886E
+:106BC0008B7875A2C2529F3C5D2F96214E1260F9C0
+:106BD000B4DB83827689F91BE92639380F825CB7EA
+:106BE000C94F4C96E8BABE49092E257E3ABEB47705
+:106BF00072C97560A705E7C8A9B09F1DAC60F1E830
+:106C0000880FE4A289EFCB7C4B66F2D694A1607C1E
+:106C100064D3F78BB6A1ED41185E367DBF7C27ECBF
+:106C2000ABD17EE6CA54AE1A65DA4FEEE5FB499B5E
+:106C30003BD1D44FDADC0AA39FC5D88F7360FD6CBB
+:106C40009A7BBD199EB995463FF5D88F6760F34A88
+:106C5000BB6392199E3BAAB19FF4DBFD681F8806B7
+:106C6000FF9076DC1775EF4E1AB796C4F2D1E41F89
+:106C7000C3781E2A55B17C943831C1244F497AB269
+:106C8000293FA874B0A97D6A20C7549F5E76B58558
+:106C90002FDDA8BF314F818A26B138AB325841BDB4
+:106CA000533CD881F9BB06BB51EFDC757DF02AB0AF
+:106CB000F70056D0F37729C1316A1CBEA1F3120840
+:106CC000C6CF341BA47DEC32BEEF3979C85723DE22
+:106CD000A7DFD7D9BA4724D1FC434AF12330EFAD1F
+:106CE00032B3E38D3843829DA0FE6BCE2EDA168A36
+:106CF000C16BCB50CA2F426FBF2D72D007FCB87347
+:106D0000F56F574A14BEA6A10A1E6E7A5CFEEDE12D
+:106D100010B5999B8796FB00FF7685EA8FD8F11511
+:106D20003A7E3E8EBF1BC6DF2B333BD93ABE3D6752
+:106D3000A2697C475685697C8742C7A7F2B16FF587
+:106D40003B7C7C8ABFEB0979567E07C7B76755E065
+:106D5000F8CD0AA9308D9FD033FE01909FC3FDCDA1
+:106D60003FE77AF3FCB32ACDF357D8FC8FAEFE8011
+:106D70008F9F80F37F59FE80CD3FAB92CDDFCEFA5F
+:106D8000ED19DFDB83FF5761FEAFF537FFDC49E626
+:106D9000F90FAB36CFDFCEC67F63F5277C7C378E0D
+:106DA000FFA6FC099BFFB06A1C5FB107FDC047CA84
+:106DB00090847AF09FA961A461405DA3E3403A9278
+:106DC000C5A937C83908C75D098CEF3E4FA0FCE65E
+:106DD000EED5A7244C2590EACB5ACED355BB8B15C4
+:106DE000E62F84D05F58C4415DB85FC4F58C6CB4A5
+:106DF000878753783BF78B21C82FDC78239E5BACC9
+:106E0000B313DC77A75630FA1FFFF1C0E8ADB1F33A
+:106E1000B2A68B5A65CBFE1383C738EF5424ABA6BA
+:106E2000FC2988A7503D7C12FC1F9A9E96E978B4F5
+:106E3000FC43F083AE8A951B762E8C7677229FCE0C
+:106E4000EBBB1CFE5312C3F7A93B05DC47F87CC320
+:106E50005205F4D9A25697C96FA8E374EA7ECE8E84
+:106E6000FB8DC679BE5B501409F9FDC16F1D05BBD2
+:106E700071F1E641A6EF6E27E1D5701473C1FA797E
+:106E800043553AFFDBCAECE3448C6BEB43581C9C44
+:106E90000C81B84959DB067908CDDC52269BECF908
+:106EA0005B83E6FC6D15E67CA71C966D60CF2C110C
+:106EB000C816DAEFF7EB65CBB900368E5749E676A0
+:106EC000251BEFBB948619B4E8FB908E836215E90D
+:106ED0003A5765DF1AF0D4DD2D9328AEC71DA9B847
+:106EE0000F144A45BF2DA8B2795BE19D2B3BF400FE
+:106EF0008567EE8F44C4A715FE8E832EDD46EDF325
+:106F00008ECD7F90217E6C9D8F15FE3B965BE7A317
+:106F10002AB03ECC0B59CB199F58F9A96E7FF13698
+:106F2000B33D7BF3B658FBB56AD70C537E49F85690
+:106F300053FBC59BE799EA17B52E31D52F68596ADF
+:106F4000CACF0BFDC8D4FE8EE52B4CF5DFAF5F63D7
+:106F5000AABFAD6283297F6BF02153FB5BCAB69851
+:106F6000EA6D07477D07E468D5EB229EFDBDE03E54
+:106F7000752FD89B17DC12EE737E44ED159083338A
+:106F8000D45E81B473FF78F4A7A91E2C874DA2F9B3
+:106F9000CA98552D99A09709EACF7265C2AAD02444
+:106FA0008A17B0D7A97C889B15121D04CE4C720F8E
+:106FB0001F778B31F51D97A9DF4C057D7CDF7AB1FA
+:106FC000237E79DDD679C3D4387E6AAFDC9221B0D6
+:106FD000CE7559CE9F1869B5E53CA7B1BF7D81EB51
+:106FE000D96A85E983EABD1993617386FAE523E2DC
+:106FF0009D9BECF93E22B00D48B0FE53811F869850
+:10700000F66BAA76E59AE4FBEC2111E1AA059D4016
+:10701000F5EA1752608D0272163D92356B34C0A1AD
+:10702000AF5540EFEC4FC575FD6C43E936D8AF3F27
+:10703000D310C0F4A386324C4F350431FDB0A10209
+:10704000D3930DF59876342CC7F4BD8610A6EF3691
+:10705000B460FABB86564CDF6AD88CE91B0D614CD4
+:107060003B1B744C0D79E8D1BF016E0F1B1BD784FD
+:10707000DBC37C2E8DA93DE7C270FFF7BCFBF3118B
+:1070800060EF9F7FCB8EFB6CFDE1CBCA6FFDD351D0
+:10709000477BA53C3C089D636BBD3381D1C9692307
+:1070A000A5641CECFFECF4CFCFC7BCC42EF584FD67
+:1070B000333C71FA85785DFAE5E944F4EE829994FF
+:1070C0001EA71EFEAF22E8F702AC7F60071C1171FD
+:1070D0001D26D16D7EA0D795E24D78E1F759102F8E
+:1070E0003BD783BFF62C888B5DABA8D8FFF9363B26
+:1070F00081F8D2F9032EBCCF75FED8362FC8E33203
+:107100009F188E3D47614D6B22D961B7C9EF36E7B5
+:10711000CFB70AA5781E9A6889B347035FA961387B
+:107120000FD2D9E0C3D4E867994FC171CEECCA65DC
+:1071300071337E5E83EC4E427EA57E27B6FF9F862E
+:10714000A7BF7E0C780869231F38085E71BB98DBE7
+:107150007FFB7EF949FA4C81F82A39207F0EF682AE
+:107160009DFE77111C652261DEE8B72E2286EC6356
+:10717000A07CB7693CFA9D66F8F417732EC5B7E694
+:10718000FB34220468BF469CA40AFE80F330F5025B
+:10719000C6AB8C784997E46E11C6F4C64BEA78BC4E
+:1071A000B8C6D1A10469D1B9B6DC4BEE9F9E69384F
+:1071B000A6C239AF0A47AB02CE4F45645409E8B9BD
+:1071C000736DABD2C01EAC12CFDF152F7E9B6767ED
+:1071D00071BD2561B9DBBC8E72FE20B45FA39C1D1E
+:1071E00072749F8AC99FB5313BDBDAEF04FBC0F6AE
+:1071F0002D6A771F9F7683D6174FB5FB3F55303EDC
+:107200002E11535CC9C0DF7B4A60829DE2A972D710
+:10721000FB688F7E248746DC7D09FDD4777E6E9FD8
+:10722000E97C7288B4C338F327F2818876CB3B744B
+:107230003DFDF815999DDBE4E7807BF695F9BEFEF0
+:10724000029E9BDF5685E7843EDEF78F68FF2D2484
+:10725000012FD281B416811D798ED84A014FE7C81B
+:107260006BDEF13174B8953A4A40EF052D663B86E6
+:10727000DABFA6FCE2CDE67C39999906FAA47CA394
+:107280004CC202CECF547FB35DC57E1793FA265809
+:107290005725EE8FCC57893484EAD59A677F5634C8
+:1072A0008FC211B4333FC888BF2C49667660654AE7
+:1072B00058817DC20FDAC67FF70620833DDC04715A
+:1072C000289248FC3B485FFC5E29FC56788DF5BA55
+:1072D0004F1C88C321EE12E2EE03D6DA056ECF868C
+:1072E000303DC0E76DF805C72CF915767EDE5224D7
+:1072F00022D0FD9CEA08D912B1DE1F8578DC5EBB86
+:107300007F950671FCC06A7B6A6FDCDF6897640F4B
+:1073100062F959E1D5723CF720450BF0DE218FEF81
+:107320002B9C1FC4046F019C23F540DC1ECE753AD4
+:10733000BD5B21DFE4A9C0F31F7520EFB4BF7BBCA8
+:10734000D38E419CDA415AA33AE55FBBCFB21FA06E
+:1073500099F32E904BD0675080E7A209C6B95C2301
+:10736000CDED3C7E73FE312E8F7481433EEE39DFCE
+:10737000E67047E13C0999289DEDF1B772C0DF63E3
+:10738000F0C3FD56687FA7CADAD7F27DDD3BDF9EEA
+:107390009C9E7C097D54F7A540C231EB489DD4AD3D
+:1073A000001FD67D2961F9D7D69B1A5D5563F4E697
+:1073B0002B4AF059FB04A627013E818E13BBDF64E4
+:1073C000BD877002F861422F3F7C6D385288497F3B
+:1073D000BFA7048FC583E36BF7EFEBD3FF09E0BBD7
+:1073E000FFB1FEF3FAF4DF110FFE9A67F7EC0BD151
+:1073F000F5B5F2170F78E110D3C7526B1A9CEFACBA
+:10740000DEB1DA0B72F99114F2025D3F0E8B71EF6F
+:10741000E7A63B0CBED3DD708FB096F3DD999FAF2E
+:10742000FB36F82F9FEF90558C0FECB247ED942967
+:107430006BDB9630F9D8657F9FE59BF1BC53DD7E11
+:10744000B3BEA87CFC81340D0F5585B8FF1C45FFE9
+:10745000A076FB7F4C03BBAB8E74A3DEB37E07E349
+:107460007F998CF6C03C25B16FBD710EAB8EE3A544
+:10747000AE6D1DDE13AF6BBBF934139A0EF43BAD4A
+:10748000DF5570BBDFE1309FDF34F042C2CCEE5FEE
+:10749000F5C48305EF53B8CE6E7FC52BE4C7F22940
+:1074A000D37FE7230B1EFBA5D6BF5C7552FD186B7F
+:1074B0005F1BEBB4B69FFB2B07585A2D47BDE00F5F
+:1074C000566F91F1BC7BF59E6D3B1F86F8CCDB7649
+:1074D000FF70DA7FD59E97DEB89EE6AB9E9253A6EC
+:1074E000B369B8E19EA2419F3AFADFF271BDF4A8F8
+:1074F0007CFA25451BCDCA7F9CDC4B97AAA70E2999
+:1075000064745F7C4C891C52D87EB6853E91F7A787
+:10751000815FB1EA892F14D05F1F1F14487A761C4F
+:107520007C6E7909ED63C013D293D3AB877E96F658
+:1075300075942EA8172DF4B2B6FB98AF07D02FC4C0
+:10754000E3297F3FF94BD8B7F99DDD0F78A878F292
+:107550009FBC309FD3523DE3F39FAD4E83FB20157C
+:1075600072284DC59495573CFA03E4BFC5C77F9078
+:10757000C6CEC5EA19FC5C5706CC73D12373709E46
+:10758000E524887C58F13376CFFC82444A9F8A23D5
+:1075900027F739D83A767AAB1D37114FC34202FB31
+:1075A00018AF89E11D180F64E70D7F60EC3F91650E
+:1075B00098BFE060F45AE430EEF1D1A524967FB78D
+:1075C00037B7039DCE0CD5D3218E5C47A410C78757
+:1075D0007091F62B1E9F9ACECF1D685211FF8EEA36
+:1075E000FF29500EEDDB65DD5960FA8E5CCCEE1D97
+:1075F000FF4E3E3E853B01ECD7D369D41E8C33BF92
+:10760000030E639DA676560C9FC5C83B93FFED6B9A
+:1076100098BC1BF21F9E510AF59F9D607204DF818A
+:10762000FD42E18AA663FDA1D902EA073B89C69320
+:10763000F3ED32977373BD955F28FC12ACC73D7CA8
+:1076400003E324231DD0BE2DDF48BF8FD5AB30AE62
+:10765000B76FBF861C2FE6FA60AD451F90475207F3
+:10766000B47F5B2D87773E0CF24BE535A481FCCAD5
+:10767000F85EC127BB8FBCF13D2AB79F440CB935DA
+:10768000EB55ABDC56EC9D40E2C9ED276E3F892BF4
+:10769000B7B43CAEDCBA3B909FFFD67AD5C0E3D3FB
+:1076A000163C1A7AB23F7C5AF5E4B71D5A5C3D4944
+:1076B000FF9D20457DF9D1E04383FF2AFFA506CF3A
+:1076C0000BF5F0A9C1873D7C6AF0619F78A4098F12
+:1076D000D6FABBE16F3A85C07332C6CFAB0FB0FDAF
+:1076E00067FADDD12185882F1D9739D27A74484AEF
+:1076F0006C3E6CC9472CED754B3E60691FB4E4EBE2
+:107700004DEDABF71F51D8B99EA8A99DB8FCA7E4D1
+:107710008338F101631DAA6BFB5409017FB8BBF1EB
+:107720007B79250979205EFEBC88F1F22E8AE3265A
+:107730003A4ED7EE6C7C8F60B593C557BAD46E2F96
+:10774000D893AB9358BE3B5569023D6894773B593B
+:10775000DCAF2BD0ED4D8AB1EFDE3F20A21EEF084B
+:1077600093D2787E28DE40A1F8ED20FDD5B3FD80D0
+:107770002EB0D761BC84AC30F0E354D19DB51CE28F
+:1077800035AD22DE6B5BB8E2162F9C23E93A90FB05
+:107790009D325ABEE8D722DBA60CE952468C1FF870
+:1077A00011096D9A24C0FEF57AE49F0507985FB829
+:1077B000707D7C79A8E4DF95BBEF5440EF527FEEFB
+:1077C00064ECBE87D14FC52396F203FFC8E5A6152A
+:1077D000E31F95DBCDF5411E3F18ECE4E7BEC792F1
+:1077E000B1DC7FB7C5DE0F9E2AE67FA78CD2A7EB60
+:1077F0009848E03CC1F90322D2E7FC6E767E00E3B4
+:10780000FCD701BF772BB1E7A9CE827C5DD5BF1E27
+:107810003BFBCCEF8BEE063EDAF74EC14F697A7632
+:10782000DFDB237E05F967DFCC7A87F46D3FE5A0C7
+:1078300013F755BA0E7A90FFBB9EFF4DD6DD907FB1
+:10784000CE8EF1ECAE835F14003F75ADB457801E51
+:10785000ECE2E7EF563DFF454107AEBF8D48C7A9B3
+:107860004EE64F9F3FF05FEFC1FD81F307E8ACC0EC
+:10787000BE38E842F9AAFBA513E36F5DCF7F511430
+:10788000EB27FCA5F3A9E5FB9D5D1E52B617E04B67
+:1078900062FB4475BFBA6E1BBC2F51D3764859406A
+:1078A000EBA7BCF0A702D0AF5D7B99DDD429773C74
+:1078B0000AFB7981350F34CA945E9D20648369FF89
+:1078C0006BDE280139EA8B973F615C71A0F858FCA8
+:1078D0007F0D3E049DE93F4F184C852907FFF8DED8
+:1078E0003BA0270EDA912F8DF97E125981F6CCE557
+:1078F000E6DDF4FFDCBC85E840E6BD03E63DE1EFF4
+:1079000077DED7C0A1A1D4BE72D097CF9FBF0BF3B3
+:107910007B3C7E847780FCFED2DFF9FCAF98EE7B67
+:1079200029DDBD979FF7877FE7F3EE9FEEBF9ECBE4
+:10793000E9AEC27998BA17FE84F05DA99E9312FE53
+:10794000BEE5BDBFF91BF6FE5A9BBF35271BCF9383
+:107950003AC0B0707B66B6407871EDC8992AD89D60
+:10796000623FEFD54C48607E9528B0F721C850168D
+:107970000F24DCCF82630DF80E889BDD3B93DC4D3A
+:10798000687713C9DFAE53BCACBD7ABE1FCF1A9166
+:10799000716F05219F39C98FF16E8BBFD928105D9A
+:1079A000A0F6AE74F5378F81DF238FB445ED0598CF
+:1079B000BE0F69338F63CAAA62F287DCF9E6BC5353
+:1079C00033E7EDBC3F0761F03B7C240CF16C71D4D4
+:1079D0006115CED3896325024FA538496B08FC0E8B
+:1079E000BBCFFC7D5202E17EEF5F86C78A0416A7FB
+:1079F000128571ED3AE071940DE3DC78481BF1E2F9
+:107A0000C7F7BA08F7AF7BF1DAD40EF894C03F6637
+:107A1000F617FAD584FBD312EF421A69D39DE676A6
+:107A2000DC8FBE2C9D185DB2AA399D9699E862D074
+:107A3000210E7D4C7431F07CA5F4B1D2C58AFFEBE8
+:107A400013185FF7472F832E996E1DEFD7C9DC7F80
+:107A500028013F13F2990182FBABDC7F905274BC8A
+:107A6000A724AA7EBC97007E5C941AE02FEFDE86E6
+:107A7000F1A4733F7FFFDB004FD5AF44E2A0F8EBEA
+:107A8000DCED2151F85E0A2BE09F56B689B84F40D5
+:107A9000A468D1AC987D62C30FA8FA8507E753B9F3
+:107AA000D71E9E4EBFAFDCF74101DA612BBBD1CFB1
+:107AB00009FD5C60740F7514C03E70A5C4FC112BE9
+:107AC000BFAC4960F196B3CFB9CA20AE23EC62E7F0
+:107AD0007F2B23B7C8F698734DA10499C59B9E735D
+:107AE000A15E083D21E0F928802FF6DCA9E1879C02
+:107AF0007D4260F0ED97F19D98CA5D4F75427CAA7A
+:107B0000F22DBB1FCCF8BA5D9FE27EC8945FECF10A
+:107B100076A01F2E9AE2127DE201BB44E48FDAB612
+:107B20001AF443681EF9A236C2FDEF2BF457AB7E60
+:107B3000F1FC3EB87056F5F4E35E887F9D69DFE1A5
+:107B4000C5B8C0AE4BC7E7FAF8FF9135DCFFFFD6EA
+:107B500069764F3BBEFF7F06FEA076F1D30996FB08
+:107B6000ABBB06B1F71449B4E852EF7155EDB9F06B
+:107B700028C4AFCFEEFDE45180BBFACF7F7814FC70
+:107B80000A72D0A9C27D82BA9FBF8EF13EE3BBDFED
+:107B9000703DD0F9C4E3182FED7C9BFA1FF45FE72A
+:107BA000F3A7B3C0CFEC7CEA8F69104FB9F3F9A902
+:107BB000F86ECE9DCF4C492771F4899102FF86075C
+:107BC00010AFB5D2ED48DB11F47FCE51BA83FFD9A7
+:107BD00013D789D4B07899C6E339BBE3C7C7FBC4D0
+:107BE0006FDA667DE7C6424865BF460610C7394171
+:107BF000E939660074DCCDE375916F5D328E730EEA
+:107C0000FEA0F43A6BA1E385B6458F3D0C756D83FC
+:107C1000FA8DE34407803F23FEBE3F41FF2201E48B
+:107C200068EFBF60FC0CE8379D4EB873CF852CD849
+:107C3000BFF848EE9E8BEF853C6F57211E51F9FC33
+:107C40009B284F9DCF1CC7F836E171F04ED2F38FC1
+:107C5000C52BF999CCBAED1E16FFE17480F890E6B9
+:107C6000C5721E07627C6DC487FA8B0B8D71B17370
+:107C700027C6BE40CDF67778BCA5976EC244A0D784
+:107C8000FB97DCCF30F0A0021EAE8D8D7BC68FC37C
+:107C9000F5C43D2D74037A42BCB327AE49D8137B9B
+:107CA0007561E1CD7871F4CE2D2C5EDA29C73F8F56
+:107CB00065C441AF7659E29FE181C53F2F378F2BD5
+:107CC000C5D3609786FD5AF175F6ABF8FAFD5BAE49
+:107CD000819D5FE8777FADDA7C1FE63D2538DD05C5
+:107CE000FB6B6DEF2B04CFA774B3732B7CBE67F9CE
+:107CF000F9D3B33F17312ED6143982FADDAA3F8C5F
+:107D0000FD572BBC7770786BF7B3F5E3EC5E4FD87B
+:107D10004DFB397BF839E4EBDADDEF635CEEE8AE7E
+:107D2000A7958E98F516D68F70CC7CCE3E79A8801C
+:107D3000C579E3DF1BAB71317BB3EE40FC71EA76B2
+:107D40007F6A1AA72A1451981D70E9F1CE48FA2DBE
+:107D5000D0DF997619DF4D3A1311E3BE171C70C9B5
+:107D60007C1FA195C90F5D47F19EC071767FA7F07A
+:107D7000B5043C577FE7F1D277E0FDB73BA95883C4
+:107D8000DDDFB682F169DB4FF42140EFB6E3DF13AC
+:107D900061FDDA07F88DB1FF8B4ED44FF150FD50E5
+:107DA000F46EA010D8D5AA77AE7DCB66829F8E9355
+:107DB0000EEB4223ED07EE83C0B939BC57EE9D565A
+:107DC0000AF088AA4D750A7DE721BBF97D55DEAF23
+:107DD000AC9AEF2190AFC66BD08F6F268B4B66CCE1
+:107DE0003252169F0C19F787CA13C2ABE87C7FAFDB
+:107DF0000637BB285E7C9E8DD92F1178276AA20694
+:107E0000F6D3632E7EDEC14BBCECBC833B64A37A0D
+:107E1000FD61FFF60D93089E67D8067CD9739E819D
+:107E2000440B802F8D767DEA2DE71D32E1132A5A0F
+:107E300022873317EE2550FDB26A86772BE41FF1B7
+:107E4000B0F7CDB248F72138DFB08DDBA3D960158C
+:107E5000E7F67DE7ECEBBE6F9632A578E9303F851B
+:107E6000D3F55F53E15C7CCA2DC54F0D5169852D5B
+:107E7000631ADCA34979BC786C06CDCF5FFFF4347C
+:107E8000ACFFF7E2B15934FF937B0EB2FA2A01CF6F
+:107E9000C1BEB0AE761AF0EFD796FBD9143366B9EF
+:107EA0007F05F0772EF0EE77176970AEA25BE1EFF9
+:107EB0006504A0DDD0890C7F99EE779F027F6598DD
+:107EC000AD6305F0EB63CF7F9184F716F9FBA12A30
+:107ED0006954E1DC152D9A78F112E7F3FABCFBCC7A
+:107EE000F5CB8D49C177813F9AE78DBC6F1A1DEFA5
+:107EF000E18A710E760ED0F24EA39A82745DC8E9C3
+:107F00004AF83DCB457C3E8BC590C202DFAD5C7F1D
+:107F100019EF51578B57F41E3587ABDBD5EFFB6755
+:107F20007F00783393827F00FC59DF3F7BC515B813
+:107F300000F519E55FE27D5CE33D33EBBB6844EAA5
+:107F40008EFB3EFB56FE2E5A7FF0FE9B3B28BA6905
+:107F5000FF392F687B8F51391BB350F1C3D1CF311B
+:107F6000CB0BFDD220C226047610A71F3CCF88F78A
+:107F70001FEE22B85FDB651774F0AFBBFE49457D8D
+:107F80009EB9703AFA5F5DAEEC089C33EABA5BC307
+:107F90007D3D8A0101E469E881C428F887541E3ECA
+:107FA000B7C8C3E766FE378FDB7551DBDF81FDA9FC
+:107FB000BC3F6AA0C5DC8BED12999EEE6AD0108E94
+:107FC000A1247408D6FD818E97E3E6EB37A7CF4650
+:107FD0009B9EEB9E80F81FEE8EC1FF2877BF74CC6E
+:107FE00077333AE6BBE3D0D1FA6EDD7BAEE058687A
+:107FF00077BAFC28BE5F677DAFCE4ADF3AA9F5218C
+:10800000783B2BEDC0A7B8FE18F41BB37C2CD2290B
+:10801000869E93008E31073EB501BC061D1FECE71E
+:108020003C79A99BAD73D6F1D2CA3A0607E3B49F57
+:10803000E5D64CF70E0A1C457E89CA69BA8DC587FC
+:10804000FAB6EFB7FF9C4B9DF32C5059BF14FF734A
+:10805000004F06FE6F75F3FBEA7DF17F3BB4A3F89A
+:10806000BF1DE63F00FCCFBB14FE0DFBBF8AEB87B4
+:108070002AD89FA27CF41FDACCB41C3AEE34D18DFE
+:1080800072B06487C8F731D9FB5F863E59725DFDD7
+:1080900021B817B9E46702F2EB42FEFEE527FCFDCA
+:1080A0004BEBB9C1F2B210EACBCB9F1F0CA33EAA97
+:1080B000DA652EFF6777CFBB975978DE172435AD89
+:1080C000F7BD4E2BFECFBBB9DE58E8B4C57B2FD72A
+:1080D0004887D6DB4CE7CC33A6F4F483FEA0CFA6CA
+:1080E000BD89F1B87F9509C4137429A510DE192044
+:1080F000854209F45BCCE5D7E86FD872F3FA9F1D8F
+:1081000032DF43CC6D31DF431CDE6ABE8778D56633
+:10811000F33DC45161F33DC46B768D33E54747AE03
+:1081200037B51FB37FB2293F36FA4D53FBF1C7660F
+:108130009AF213DABF676A7FED5BF34DF5D775549A
+:108140009AEA6FF86899297F63F73F9BDA471731FE
+:10815000FD78B8617911DC5B30F07278A96253A1C7
+:108160007CE9089B5A105B9EA66B059016E9E07FA0
+:10817000F5272F531C3F2A8A5DA78B896CD26F533A
+:108180001CE67CD46DFE7D8F972C7235A47E52CB7D
+:10819000089A1DBC240FCF6353F93AC6F5DBB10131
+:1081A000EAB7DFA07CD5469B206F952FE3BD019AEF
+:1081B00086D88FADB0779F1F729AF9D4D78F5EF9AA
+:1081C0009DDB3807D4CAFA53CBC64B263931CA3F98
+:1081D0002A8C2D17164FC77340FDF5ABF8165CB30C
+:1081E0007D10BC3B3C0F53A3BCA9CC16F7DCDF676A
+:1081F000EEBFD07FDADCC78EFA0CF07CCEF7DA2641
+:1082000038BF567B7B37FA511976335E7AF3EC5DD3
+:1082100063039E471A483EACF7C6FDB64534E1EB12
+:1082200036CE77D1DB33D3E09C41663FFE55A18744
+:10823000E9EB471B42D72C04C21187E95E7956B49B
+:108240006E1AF839C3F879EB4DB6F8E7A0923C0CFA
+:108250002FE9A048C15E50DD682F9C2B7FD70B4FC4
+:10826000C7DC680F2679E838F3C7B417B1FBD4BA76
+:108270007FE6E85EB80D7D94E50E6C02FD92E59315
+:108280008896DD179EF4DB832DF08E7863B2CDEFF8
+:10829000C67CB700E3D97F4CC8203A5EE39F458493
+:1082A000AFF1F075783EC8EEAEC7B8AB314FC2CF74
+:1082B000091871E60BBED98980CFC6AB7BEE07E10A
+:1082C0007B9017DCC176E8F7C24619C76D9C2C98E5
+:1082D000EA8D794B9BBF8DF7BEB2DC6CDEE574DEB8
+:1082E00000B73D93C1D5F8A8403211AEFFBDF428C8
+:1082F000F835FB5CF8DE07C5C710C0C7393DFB7316
+:108300009B31793AAF9A41EEAD6BD19E89EFA74E82
+:1083100037E6A18F34D13BE32A33FCE24619FDC690
+:1083200045496E3CEF106E8872FA9AE7DFE49BF9DC
+:108330009D5B295CAB4E88F8DEB6D6D1BAF428FD39
+:10834000AEBCCDE50F6B7DF17F4E63F052F8A77B9D
+:1083500040DE364FC3F9E3796A80FF31813C9C0DE2
+:10836000FC172C453E186C23B06FD3C74EF0307904
+:108370009EED51D97B35BE722687BE85D76CA7FD91
+:108380009579FA5DF76FF3B075FF364F9C75FF7204
+:10839000EF075797B51F8554D445B43708A91F1167
+:1083A0006B47533D560EFD1B7931F1C705D06FFF6A
+:1083B000769ABF6544F6E5ED34B0CF800F0DFBEC47
+:1083C0004E8FD9AE8CD1BB3FF430BDFB43CFC0F450
+:1083D000EE8FA1FDE9EF45E3DA35A94A7CBDF7B49C
+:1083E00087DD1FAC531582E703FBD90FD8C9E5DA47
+:1083F0003AEFFED6A5CBF91F392E834FCDFAFEFCFE
+:10840000312D11F454CA0742DC77B7862CBF6D3C7E
+:10841000D06B9BAD7833CCF76716FE78684D9FF52F
+:108420002BCCF1188E8BC76A8A479B098F3B3C97F0
+:10843000B00FBFB6BEAF30DFF3E9E4F8A67ABF09EC
+:10844000C63B37EBBD22886BD4CEF91CF5FED71E98
+:10845000A7CCBCAE187E391D6705E0A173D69F7905
+:108460007CAE03E34AAB9EB92A11E25835930D7AEC
+:1084700044F07DAAF3F939489773FBEC3AC0792EA2
+:10848000999D133DB7EFDAA310F7F8A4E158722CC9
+:108490007DCF3D79BC48A6FD9DDB7BBC48C2037700
+:1084A00061D33BD435177F5B1470F7DE4BE8E137BF
+:1084B000075B8F363A597CE54138173786DABF6A51
+:1084C00012F2657A9AED5E28171DBF1DFC215C39FA
+:1084D0003FE62FA659B24AD03316C17ED33C37EEC1
+:1084E00067F972C9C86CFA9D12AD87E3CCC4F96A0A
+:1084F00098C0EF04B84E44F1F7023CEF7660F83EC6
+:10850000F143B2029EC2FFBD1A3C09784F3AAB0953
+:10851000891AC4778A6E1E4753690AD3BFDDB73AFA
+:10852000F0F78C8405AFAA53A8FEDA3C93FD8EDDEC
+:10853000F9630B92C01F695599DEF20DEBE163B44C
+:108540008B07E76B371723E6757C574055191D924B
+:10855000336C6B8A358CC7F9F398FE25521AFF3DB0
+:1085600029CAB71ECDA6431CD8F8CEC5BF2B52FCD6
+:10857000BFCE037846DBFCF04E8FFBAB6F38CA9260
+:1085800069FBCC28BE5F5E94C0E19DC3DE07EFFBB4
+:108590004EE345D37D18B5D4FC4EB727D0B414E2D2
+:1085A000FCD0EF6DC9F8CE8BB99EA2389196BB0B6B
+:1085B000CDE5AE0A9A8FE147EB77D6F6865F92AEAD
+:1085C0003238F63738100FBF6C50FD79948F0E3467
+:1085D000F8307FB041C334DA3012CB0F37F8312F87
+:1085E000DAF46C984FFAAF7F9014BBEEC2EF549D53
+:1085F0008CE1C37572E4ADF9808FDF8888AF15AF69
+:108600008E47FEDE349A8E3A86BD677332C6FEFE12
+:10861000E9F257D24A285F0DF9D1AFD34AC6C3EF6A
+:1086200096B0F31770413AF61EEE7A25A0F993E062
+:108630007734C6343B86C2FBA4C15BC9589423FD82
+:10864000C589F0BB0B7B336CB47E9A94D7ECF807EA
+:1086500080ABDE64E7AFE7E7331F9F6CD6AFE3BCC8
+:108660004CFF660AC5E3BC71F8097E5300FDAC39C6
+:10867000C6B907331E8954BFE1768AEBE6EFB3DF54
+:108680005F4854C7FBE1BDF7CD5EC3CEA9F7C5BEB9
+:10869000E7BE99FF0E44E2E1256817293EF63B103C
+:1086A000290A7B0F8904934DEFEDCDE5FDCC06063D
+:1086B0009AD0571FCFE6FD151D790EFB83DF9788F3
+:1086C000F5EF87F0DFC3D8CCF5D3743550EC4DED22
+:1086D0006D67D45BBFEB59776D21D10BF6430189F0
+:1086E00080BD04ED8A69BBD40F0302DCEF33CED723
+:1086F0003E0BF8CDEFFDDD937D02C3EB933C7D8A0D
+:10870000FF4E49D4139807E3FB163C12DA0376CAEE
+:108710003EBB06625274E48FF87E94F83BC501E7D5
+:10872000FC530FBCCFEEE5D93A1438BFB8D25B7C0E
+:1087300013C45145A53E03F3F74E6F81FC839EFAA7
+:1087400087D8A3DDC537011FA4F3F706080400018D
+:108750000E08AAE18F63FD43B34E65649FCCF22BF4
+:10876000BD37368732215F3F0FF808F28DB4BF7DE9
+:1087700049C121C0476EE186E6633742DE687F0368
+:10878000B6FF895765FE8F3B980DF64A4F5EA57977
+:108790004F4C5E6279E260A931BF9A237FC473D0E7
+:1087A000B507D83B5DA907660830CFD4FD3310FF6D
+:1087B000E7D5B7BC2B348C878F60EB048B971BF409
+:1087C00030EEE1A6D983F77963F8619DD76CC7C411
+:1087D000DC27BC0FF0DDD31F8FAFCB36F69E4AF7F8
+:1087E0008FD8EFC60D037B5484B8B986692EDCA3FD
+:1087F000A7FEC170125C3998D65FE3CD413A5EB5F1
+:108800003BFBCDA95A2F5FA7642977803E4EB5F870
+:1088100035D95C3F8F508B7F93482B370AC1B5F019
+:108820009E6C688FACE27D935D19284767B98E22F4
+:10883000F583315FCDEFBFCB2B836B47811E59C4CE
+:10884000F46E5576A058A6DF573D978DBF0B67F0A5
+:108850005D5552246D9CBBF75CB791377E47E42190
+:10886000B5D509EFF218FB5AB5FB3764C13EFDC719
+:1088700087DE463B71496236C259D3765C81DF6937
+:10888000A96DA37C47BFFBD8D963C7A35FF287C894
+:10889000A06F02BEFED068C3CBDDFDD9552F52FDBF
+:1088A000A6D385EA688303D39D7AFDD5E00A9CF0C0
+:1088B0002EB8C949F9E9F11C5D05FEEABCB71EF501
+:1088C000D8E38A3A0AF8AFD3FBC366E0E7AA24915B
+:1088D000F3EB0F5FD6F3F87E3DCDEFB9B7EDA6BF52
+:1088E00068DF60A1D9FEA97BC48DFC41ED92DF0257
+:1088F0001FD56EB68560FDB339DAF1BE7327E81B6C
+:10890000D45FE6FB991B05A60F4373581CFA72F758
+:10891000342BBE7491708CFDBD2491E9AB0A29847F
+:10892000FB76155F7AB1FE2F1FC769BA0FDA771C85
+:1089300037D61BE354F78E837C52FDF661F4CF5F8C
+:10894000BCDAB0AF75D4FF773EC5CF6138F574E8B7
+:10895000E741D9D027D4CFA47886E71E793E24F901
+:108960000879A947FFAC6D2EC904FAF6D613B37E79
+:10897000D2254AB79712783E747F73C9A438ED1395
+:108980002CED738CFC4FB17F2B3C0F3A7BF30EDA4E
+:108990005EFA93BD270FF06DB059FA4B36C6DF86ED
+:1089A000FD19FCB7C7BBFB6578EFE9A5A440F11042
+:1089B00066DF6820875B24157F87D1C0F31EBE3E2B
+:1089C000557C798D09FFBD782F30959F6ED04CFB7B
+:1089D000A18B172EC37B3F7BF83A564142EC3EDB1E
+:1089E00023B9A67DD0FF0FC7D785A3B81F384AFE8D
+:1089F000C6708C32E9815E38F24DE55F170E316941
+:108A0000766936EC53ADB1A19F90660B3972C06E9A
+:108A1000FB5FECF71A203407E799A8616CDA57CEB0
+:108A200039609F07C6798E448E49E3409E746D0578
+:108A3000AC533F91D0AFA1E50E3919866ED5E1FD5B
+:108A40002B2A95D85F4E75B08619F5E6776287AB0D
+:108A5000A458A2E5E3D579B8EEE594DD5507F6FD17
+:108A60003677E1CF571393BCA27DB25A588AF6C726
+:108A70009AC4179B61DF383D81D9330279B1F95827
+:108A800046BC7A26AF2DF7BD7813C431B6AED4AE4E
+:108A9000067F6EAB331C390CEBF93D6EFC3DAADC56
+:108AA00075E116F8BD0A71830DD74B3129BC6B2BCC
+:108AB0009C177860841FEC8BAD60D740FB356E5CF3
+:108AC000FF5B1A42682FAFE2EBC0F6F5935438E72C
+:108AD000DCE8969261BD6B91EB6F05B85EBAEF640E
+:108AE000B3E33AD063FE96413CEFCB80754DCB713A
+:108AF0008CE5F514195B576883C18534F2C3FF44D4
+:108B0000AD12D43327D10E6B742FAB043B8ED6BF7E
+:108B1000ECA0787A3C99E385D7E7F4E8A593CDA05B
+:108B200007C515BDF9123AEF1D3F637AEA09DA3F2E
+:108B3000BC2B45E713827718BB4749E8872524C13A
+:108B40006FC7D074740EFB9D5BAA17BDE8C7493888
+:108B50005F631F4919C57E0F1DDAC37A9390918315
+:108B6000FB98CA0CF65E83E271E3FD66E37756DD9F
+:108B7000C4F8A7B37829DF677159DE4370AE5F8907
+:108B80009BE94E783721864F15CB7B0B1209CC071A
+:108B90007B4B54CDE5BF49E4FB4A83D8EFAD0EB71C
+:108BA00085D02EA35284E935248AF6D968D281F97A
+:108BB00031E06DE6C2352C0D2F8E8D27BAC8E2BB91
+:108BC0000111ECC7B45B8D784CF0F544BADEBF966A
+:108BD000C8E336FC778C536614E27E7D6612AB5F89
+:108BE00015C8BB0FECBC8D33A6619CC6B0EF8CF5ED
+:108BF000D2B0DF16729857AB425C7BC1B0EB163A2D
+:108C0000593E75B6FEE068886BB6530B341BEE2FE9
+:108C1000B3F86AF9E6E234B0CB161EBA15EDE44CAF
+:108C200095D9658B36CE5082A3E1DEDA3CF4078A13
+:108C3000374C48847D84D54E7FE27585E867E2FB3A
+:108C4000B903B5C7B6A65D3519E471AB8D1290CAEC
+:108C5000FB4BB2EE1E0B7CB1210FEDCCAD09C1C6B2
+:108C600024DAEFD67FD6FCAB68FEA74EBDF0388C79
+:108C7000B33A81D5C3BB51C09B3DE712B6E1BBC936
+:108C8000FD8D6F3D97F052127B7FCAA8FF6F537E18
+:108C90007C7D0080000000001F8B080000000000A9
+:108CA00000FFBD7D0B7C94D595F8FD66BE796566A9
+:108CB00092C963F2220913C24B5E4E9E80224C126F
+:108CC000C243B44C102A20E8F03490A7485DDCBAC7
+:108CD000FF0C043050B60657112BEA8462C5AABBBC
+:108CE00041A31B35EA8080B8D66D44DAD216FD8FD9
+:108CF0004A1510488AB5D2FEDD65CF39F7DECC7C47
+:108D00009319F0B5FFB4FE3EEEF7DDE779DF73CEE1
+:108D1000BD73E912FC4D612C94A43056CAD8C151E0
+:108D20008CF58C618CA9DE2406CF4D066FD2E2341F
+:108D3000C6FA7EA367BBE1F517666F92C3C6D82556
+:108D4000D12EFA79AA99B1A089B1B3CD6E161CC102
+:108D5000D8996633956B961F98C6A09F9A0E85B9D1
+:108D6000F2195BC5DA36633FAF3B9269DC55013DD2
+:108D70000B8E64F47709FE5BBDFC28D55FDDC9EB83
+:108D8000D7B20EAABF92314F073C6BF75A59D01C8D
+:108D9000AE5FDF51AC691F4AD251BFD725FB063BFE
+:108DA0009C8CDD5B3DFCBE2A789F565D62F6E1FA45
+:108DB000588EE313ABA8AF87F73AE6EB88B1AE77EE
+:108DC000045CDE49828A4EACEDD0B132C6D63AE0C0
+:108DD0009F2EC61E50D87C6CB7F6F715192963C2B2
+:108DE000EDD62A9E0CC798F8706ABCA86781D48813
+:108DF000B2DA67C4F5355E34D2FBF30EB35F0763B6
+:108E00001EC9F43F702DAC7F26EB5319CC539F90B5
+:108E1000388E5DCD588B2571373E67BA0C7DA10821
+:108E200038303353717E33F82BF6EBC469479471B5
+:108E3000D83E40ED67D98EA90C4073C45E7303839E
+:108E4000F737B090CA0A06CE0FFAFD28B2DF5923D1
+:108E5000B5E51BDDDAF2EC09DA32637E82D74F9A90
+:108E60009BCA4E1AC2FDFE04A6D611032EB70258A5
+:108E7000B17EED5E4BE064041EEB3B9235E5C6AE81
+:108E8000ACC0C988716AF11F59F05F135F779D58B4
+:108E9000F70746DFAD0EC05B3D0B1971DD40C146E3
+:108EA000EF58C6AC16E6457C1DD86FF1B012E8CF7E
+:108EB000666EB7007C1BBBAB9525F0DE6A87EF3092
+:108EC0003F2796E16935F0FA8C05880EE08FDA3994
+:108ED000BD99ED5B15E413B7ABDAFECDE7DD00FF1E
+:108EE000DD93024F953DAC2446ACA30ED6911E5E99
+:108EF000C739EB0765882F58CF6FECA5481746A6F2
+:108F00002485D7F3ADE1B55C0BAFC65D36A237184B
+:108F1000E7BD4418A761A7CE6F84B2CEDC63447E60
+:108F2000B917E93C06DE721C4A4C3C6F433CC7E073
+:108F3000A7EDACFC3EE4C71CE41F18C7B6EE2765DE
+:108F4000278B818FAA3717FAA0BE4D05FE86715474
+:108F5000F8BFA908C8D93B6D5532D0E9293BE7C312
+:108F60000D892E7AEE50BC0AE2355DE7C947FAD585
+:108F700027B843CCC1F1A366421960CBAEC162F9F8
+:108F8000BD1EE8EF21981BCB168409F078C8C2CB30
+:108F90002F39CAEFDD08E36E4AE6E50D3FBDB9D5CE
+:108FA0003F09CA16599E43E5870C6D413DE0DDFF40
+:108FB00082C9F5443EB5F728585E3032F0044C4D76
+:108FC0003F8465235EA62642E720B7F42F9A769B5E
+:108FD000A05ED0EEFB2784A75CFF39FBF13C362670
+:108FE000667F7E4D7F79DFAC3F18BF537775F8FB06
+:108FF000D4C49D413D6FE7C2762CA7E7033FF49FA1
+:10900000FEA2896D85E22306769B17DAD55D2C6377
+:10901000C10839D423F079B6D941725BBEAF43F9A8
+:109020003D06F9A987E4707D47AA46FE4AB95C7FF0
+:10903000F15A4D7F398E7CC257BDDA43F2ADFEE264
+:1090400064FA1E12F2F46C7326E989F8E30CD2C8B4
+:10905000F5F0381359B0F872E34CA2EF721CE6CB6E
+:1090600022B9BD06E70C24A43782BC87712E0C758B
+:1090700025255F469FD976029145AC679B1A3463DC
+:10908000FFDBDC071CBE18FC20E544B8BD51DB1E2D
+:10909000F4231B81F4ED6348B7FFAC7ACC91FAD48A
+:1090A00066F038506FA8F68A232E37344D7E6486DA
+:1090B0000A286951393D7FD9B681E8D16E701F41C8
+:1090C000FCDAED3A971FBEAFB7E93C48272D0E7387
+:1090D00000F1BD51B9C1817243F66B07318FF3B80E
+:1090E000601B427A3DDE7AD58B89540F669219A9AE
+:1090F0001FFFF7C683C5170F1C8FBD31F1880BFA10
+:10910000574B746E0BE00B91FA71041D44F763DF4B
+:10911000A9C69C77743D09FFB8F836841211FEE7A2
+:109120006DBA198118F32E4D56BE9B9E5A1425DF39
+:10913000937F3B3C88ED95D00F0AF249FE9626A31B
+:10914000FC2DBC9058E922399FEEB573B185E3B68A
+:10915000D88E9A7DA48F98ED13D9BF3E3EFD49B8B5
+:1091600018DEAA64881F6004867AE34A70B02B4137
+:109170002FE29715AA0CE5D3403A6FA7F9F4D777F9
+:1091800043E711EB6F51DD0EA46BFD751E33CA99D9
+:10919000F58E39E6109437AAAED9F92087FADE02A7
+:1091A0007B12D6B729ADC81C8B8F5AC16EC4F92D5E
+:1091B0004DD669D6239F661DE7DFE8F75B92B99E1F
+:1091C00068DD3FB1C753129F7E40D279518F9BCB50
+:1091D00054C756589FDEC0E76B896307CA7EE3C158
+:1091E0006BCB7E0BC96975A83980F644F4789B5423
+:1091F000778F07BE6F82F9F8B19CC3C7DF54A23ADC
+:109200007643D71657023347D437384B08FE176CCE
+:10921000694C0FDF37213DC6989784D3BCE4EF68D3
+:109220003FF9A2E832F7B7C3D9100D5DB6C6A2CB9D
+:1092300079A8374BF9FC993972FE4393BE8E7C8C2A
+:10924000A69BB249CC837C9701CF76586FA7CA669C
+:10925000EC437D80B6D64498DFCD36E600993E39A2
+:10926000B57C6732ACB7ACE78091213F743A691D99
+:1092700075A27DF4B8A6148E3F538A839E49C73DDC
+:109280004F4F01F876F624B814F8D49902FA300654
+:109290007C8F08BC33D6C69F6A681CF28FAC5FB661
+:1092A000887976C3F350026B3583BDB24FC807C6C9
+:1092B000EEE74F151817C699FDCAE8DD642F8AF549
+:1092C0001F02B580F5D3D343E314FD77C0DB5E58AE
+:1092D0007D04DEEACD21C2DBDB46DF6B089FC6E3FF
+:1092E000A1742C771E3D9387F870B670FBB5EF25FF
+:1092F0006B00E96E207ED6D3FCEA2E0E62FEE28180
+:1093000078AB5383A45FEB2EE6D17758B7DF9C127E
+:10931000FE3E1B6C8609B02E66E67042F8C4C2475A
+:10932000BBE06B890F50EBA3ED021F08A78FC43E73
+:10933000A71FEF4EE36606783F6BE6EF996724DFE1
+:1093400087097DFE51425E00F7331F0D07CE467A36
+:10935000505DE9917AA7CEE2B96F3EAC9BBDAB6799
+:109360004FC06359A5AD15EDAB65264F12DA5DCB45
+:10937000DED32BEBF30984C4072B043CCF32F75D1B
+:10938000883FFF368BE309C29F76FF97BFA3BCF8E7
+:109390001D68BFA24BEF46937169A5CD8FFD96F571
+:1093A000543C6D87F72B5BAD2E06FD2E9BE2FE0431
+:1093B000EDBD65F7595C1BF271BF38A43C0BFA5D3B
+:1093C000FB60BE03E581759D37D3EC0693E07EEB31
+:1093D0004C2BE06D93B264895208AC7D7FCA1615A0
+:1093E000F0ACFE57E56716285F757FC116F3758CE4
+:1093F000BD82B21CED59FFD09968DFFE12A746F678
+:109400002EB76F7F794427CAC55BA6820A18E5ECA0
+:10941000D4D960CE2B538AB79861FCF4144FA10EB7
+:10942000C65B93326126F6B7F4BEB17FDD09DF7704
+:10943000A4CC9AA9E613DE447BEFCCCAA1D06E92ED
+:109440002CCFB354427F695616B6A72700BF0F0929
+:109450008F8FF67767BFFDBD60E6D41CC04B4553C8
+:10946000A50AFDBF9E72DB9631573136FE817287A9
+:1094700007C63F98B264A615F0DF6994F5976DF1C1
+:10948000C0589DCCF78601BEFFF1FEBA9966A89F31
+:1094900096EA2D74C0FA53CDF76F9991FB1DF865CC
+:1094A000A412BD4F2C487112DF1C4690E6ADEB3381
+:1094B00072FD2AF83D87D3717F792494ED11E54C34
+:1094C0005EEEDC105B7E9C4EE572B93321F6778F41
+:1094D000904B00EFA00EE9B3CB1A18961F9627C049
+:1094E0004FE609C45FDBB93C01BE9A63273E8ED9C3
+:1094F000DF37E55F803BF5D3A97AACE8BF90720D0A
+:109500006666C571BE4C7669E47559CF5292B7BF95
+:109510004A157CEBE2F071566AE50A33F70C47B85E
+:10952000C8768BC53AF3474BFF52D088FCB9D6E2D8
+:10953000C9C0F9ACDD579EC12E6387D75D2CD7F823
+:109540004BC2EB984AEF07F40BFDB944FFEE315FD5
+:10955000075EC95780571A7DBFD23AC3FD69FD3BEC
+:1095600003FBE37E9E017AC5187B9E1B53B85E41C8
+:10957000F8EB22E4DA4A215F416A913D7EFEC5ABF9
+:10958000766FCD8F1C7703F50FF87D7A0AEE2F41A9
+:10959000BEA21C2B533DB3B07E594F8A03ED79A078
+:1095A000B78D82DE54A43789E7CE94A6725AEF763F
+:1095B000C5B13B861DF81339AF36C583F649C622BF
+:1095C0009F7E49C4FCA4FC87FE3B45FF259C9E1F53
+:1095D000EDA7E7C5C83FC22FC4DC40DF6307CE5FFD
+:1095E000C136CE08FDF5822580F39170FBB6F42FCD
+:1095F000ED87BAB87A2A91DA651C0F26BAA09E21A7
+:10960000C5C5F9B9E3E3C46B515F75E999E2E2EBD3
+:1096100046B95126E5A4BFE748854A764C582EBB8B
+:10962000C89E917233683687EBDFBFBD67C646942C
+:10963000AB26BE2F4FD383142F0ACFE3E514AE2FF2
+:1096400027F89827961D7824D92EE508ADE3E17513
+:1096500095EC63589F5DE8D709213FF9B39E4C66AE
+:10966000C23EE1F090FA7BB629F4AFDC4FA6A547E5
+:1096700059063BA5415710EE1FBFCF89A0FB63825F
+:109680000EA2F1F35DE513C0C18F70484DE172C8C1
+:10969000096505ED0B15F417C0FF5CB5CDBD353F71
+:1096A00062DE362E8F9D7A1D976357E08BB454FE91
+:1096B000BDEF253BF173181EDC8EF92F01F7761DE7
+:1096C000ABC17DC1211DF009D2A28DAFF3FC8B5936
+:1096D000D4EFE7293AB9FEEF452EB71B613CCED750
+:1096E000643FD6BF3CA85D3B7FDEDFDC544E8F6518
+:1096F000C73D8568C70CF3DADCB85F28EB9973C007
+:1097000000E5E1DD8A036B4B3A1FDEC1F914A84B7B
+:10971000C0E5AD6722FBB5A5723AFABED631FC387A
+:10972000A757C4CBE2083ECD4DB57178C1FA4C08BD
+:109730004F552B47E5F3FB9B87F78001D65B07F07E
+:1097400040B12DE1D6D9B1648305F9F83873231FF0
+:109750009FEF58A21B8B78DDC9C8BEEB970F0FF0A7
+:1097600075487B14E8B203E9F2EAD45C1A6FD87149
+:109770008F750C7C1F867613FA953BEC01DC574CF9
+:109780004EF5CD4D4578CEEDAB64204A1AAC4DEB8D
+:109790002D11EFFBEB77417DA2639F7E2CCEF3363C
+:1097A000C6B6BAC2EB81A9FAD11F5A6F043E2DA0EA
+:1097B0007210E1D669E4F5FB16338ACF34E8FB8CEE
+:1097C000F81DF4F72CA2CFA3BA14C42FEE9BD06ED1
+:1097D000AED37B7314DCD76798DCA807601F42F414
+:1097E0007EC8C2540BF4FF263C514E57E9EFD88F88
+:1097F000F0AA2A50DC2D24AEDA85DC6041DC37CDBE
+:109800009E62257A645FDD39B41AF5BF95E309FAE3
+:10981000318B7ECCE6A230FFFD3AEF2ADAFF48FD1D
+:10982000764851A89F43D78DDEDD12B12FC2FE507E
+:10983000FE1F52AA73EE40FA17FB3AB20FD3C27A58
+:1098400017ED95225B24DEFD627EA13CA4A3487B3C
+:1098500014EDD37E7BD6DFB1653AC8D9F1333A82B5
+:109860003A0752D1F333FF01D65105F6AC05E0704B
+:109870005B2A973387F2FDFA449CDF30583FBC3AAD
+:109880009CE01BD3640B8F932EFC0FE946EE2F4810
+:109890004FE0CFBFA7723BE727695C1EFE218D9783
+:1098A000D31363FB2BBE10F55413971F5BCBB9FC8E
+:1098B0008FAEB741F4FBADEDDE318A667F0F76EFF8
+:1098C00086546EF71AB95F88C713960AFA063B8763
+:1098D000F014B6AB783C50DAA15FF4CCA3F272F38B
+:1098E0007BD9E8BFBFED9FE6DD87F4B6F2377AF2A9
+:1098F000579C14F18295C9BEF464DCBF27C4F6AB53
+:109900003C27D675BA99911FF8538C1B82EC3D8980
+:10991000714328AFDAF9E034E4BFD52C40FEE0E52E
+:109920003B37515C707940612E05F7695EEE271672
+:10993000F858BD47AFF14BDFAE361993C784E977CE
+:10994000459B366E58B3AB5853FEF6F669250B446B
+:10995000C8A1B0FC9946EFA3FB95F41E6DA77ED479
+:10996000ECD2F8C397EE1C46EB97F5973137AD77FD
+:10997000596B8166DEAC95F349BCF949BA45BBD455
+:109980001F739E46CDFB8F00FEFE08FFFFD25343A0
+:10999000691E2DA9BEFF40BA09CFC3CAFC1ABFDA9F
+:1099A00024C727B05666E17E49A023FFE5EC81502D
+:1099B0002AA7FF6F0FF7D171F605E3FEBFEE0BCAC2
+:1099C000267139CCDA14360C1EE3A76AEDB4BFA0B9
+:1099D000BE2BC5A795EB6B61472D5FA4AD7751D426
+:1099E000BB28EA5DC9BF12699F290528D7787F0D7A
+:1099F000828FF3CF1C35BAA0DEF8346EC716393D1E
+:109A00009750EF6CB3248E437FCA364B5E00F552FD
+:109A1000FFFABA381D6D33483F8A3B03E1D6FE5F3B
+:109A200077B6A888C77DB00F007958FEE841168A3E
+:109A3000905337AE533CCB01DE7621EFEADC7C7DE0
+:109A400075EEA07128F4935DC7E795D3B15F5123FC
+:109A5000DAE5D4087F5F9A41B3CFCCC1324E258D71
+:109A6000CBE39C9AA03214EA65EFDAA3A8D85F870B
+:109A7000427A33BB0900134157D925DCBEB9B1A4E2
+:109A80005D5936260C87565DF51807E0A735DDEAE7
+:109A9000467D738FD337240DE7792218C4EDFCF887
+:109AA000133D2ADAEF3F757A0AD29C6138B8F48EFA
+:109AB0006CD4A7D6137C9E6DFDFB63AE6728A24DC8
+:109AC000FEABDDDC9ED1B3238CDB87A4AFD2378C19
+:109AD00024BD27E7979E22F4453AF33D67A3FAADEC
+:109AE0008CF0C9683DE91B86EFE6F62CC7775581F7
+:109AF000770FBEAFCAB8AAA805DE176C0BAA4BA198
+:109B0000DDCBBB62FB83CB853E81754CC2F5C9754D
+:109B10005C492EC87A86387E0AC90FD619B1F71F5C
+:109B200030227D2F7F346D21CEB76EA39199943072
+:109B3000FC7FEAF4CEC6F96477B42B081BE9DF9307
+:109B4000E34AFF1D7E47FEFCC828F996D35F5CFE02
+:109B50005FA7F72C8F94671B8D8427693F87E7C722
+:109B6000EDFDD5695CCFBEEAF42EC1F934746D27E2
+:109B70007FCFAA3D1F1A63F9ABA3F9E24A70546A7A
+:109B8000F8BEA06EBE3980EB2F7F54253AA8DD6861
+:109B9000A43859DD33FBB89FE71EE6463951D7B1EB
+:109BA0004F590EE3D63EB34F591101D74175010508
+:109BB000E733C22EF990CBAF68BA473F32DA2D8730
+:109BC0002D5C4E9C2DB7F91580EB5983AF0EEB9DA4
+:109BD000CDB2BAFDF9613CBCB96FFA11CC37B03FD8
+:109BE000670AE2B355B73BD30CF55A4719DD485F16
+:109BF0003F75FA36235C52546F27B64F4EB3BBD72E
+:109C0000435B978915A1BCFBBA70181F4527E3EF8A
+:109C1000E1FCD3857288DB9145C83F8134BBB4A792
+:109C200048AE1D36F0753CC7F87CFF9EEA7990E897
+:109C3000F8480A8D9B5D1754D09F9D7FE639926B43
+:109C4000B2FF309D791E89E4DF2BCFB3C388F45671
+:109C50002BE450F9A37B948F23E6FD4B30F4916EF7
+:109C6000B29F01BAB4D1F7FD33D3A83E33B9F0BDEA
+:109C700042ED6AE1FB8A087923D71143EEECC3F584
+:109C8000D84EF41CE47227C8FD8D62BED1F87C1555
+:109C9000E51F7C9A06EA99DE1BFD23312E7A78486F
+:109CA00002F527E54034DFBE2AE81CE5A5CE46FED6
+:109CB0005AB22BE5FC64BD2267C5FE3482430FC156
+:109CC000A17E974AEBA9327A87DE11C10FBF16FD3C
+:109CD0001DB8F90323CAFD07FEFD5DA2C7FA36854C
+:109CE000E2F1ACED5DE33CD447FEA7F46867CEE259
+:109CF0002601DBF1C2BB84A7599D5C2ED777EE53BA
+:109D000097D9C2749A7FE6C0AD4867F51D2686FBD9
+:109D100022A0BFDF207CA2E954C247CADD78F8B494
+:109D2000CEE07294F98DE44785FD543EFA29A4DC17
+:109D3000FE7BAA4EF809F8FB0B69BC1CA61FDFA727
+:109D4000088FB0DCB5105FE49F293A60C67DB85B30
+:109D5000213F7F5A258767E4BCAAC7C6979BCE548C
+:109D6000A137D450DE1C7B58BEF7CB7FD1FE0B81D0
+:109D70006F781FE4EFD910D4F372FED1F8CB77726D
+:109D80007D1B83CEFE1BD711ADDFA43D20E9E6C9C4
+:109D90005DAA468FD89D46EACF0E1B739CC78E7274
+:109DA0001ECFD861E0FA6CC77A7300E5C99B0B78C7
+:109DB0005E997DA13188CF43BAA575F8FD50361F55
+:109DC000BF55A75B83E5D60D36D64278F5243A4BCE
+:109DD000917E1219978F5C1E3EF03C9767757E5BF3
+:109DE00080C13FEB7C739753DC39CDE2C6B833F3C7
+:109DF0001D34CEB30FA42BD773FB8D2E783FAB83CE
+:109E0000F39FC403C853A22FC90F12AE617872B872
+:109E10004B7E92F8F8BBF46703BD7CA7BCAA3DDA81
+:109E200078DCDB46DFD54EBECF3A6C70A19F86C78B
+:109E300017E2D16FEDBAB7B34F821DB53AF32D7A61
+:109E40004ABE85FDAC86BF2709BC1738B9BEAF74C2
+:109E500072BAA92DE920BEAC3DD944FC6C9BC1E58A
+:109E60009AED84561E33F6CF62BDDBA85D95B563CF
+:109E70001AE677543DAE3870BF1F4F6EDEAEF0FC71
+:109E8000B84F77BD9188F972EC2BB0F2319E62E148
+:109E9000EB9DEBE472E2EC5E0038D17B93F172F65D
+:109EA000FB95FA63C1630AC2B356C0FAEC3395134B
+:109EB000FF847EECBD49EE61B0E4CF9EB9E9EE3F90
+:109EC000C1BCCFEE99E246F7655A8B97E8A7CF69F8
+:109ED00071E37E03C4F70CF417AEEF7823F15A68F0
+:109EE00077FAE9AB8B506ED78A799E795EBF0EE127
+:109EF000B2E1C97F9B8CDF6B034AAA09C7D9FBF883
+:109F00007F6763BEEA9E46F217B53CFDBA11F317B0
+:109F1000748176FE7E6F9203EB9DFEF9F6C908EF21
+:109F2000968E16FA7EE6E7ED543EF0E4BFBDF67776
+:109F3000F4E37813DD58EFCCF3FB092F753E95F26F
+:109F4000DBE2D1F58E7DFBB9BC443D8F7C309FCBED
+:109F50003149D7927E4F3F79DBC448BD21DFB70A34
+:109F60007F4E6B02D7239F09FEADADE0F1CECF9EB1
+:109F7000B5CCA7FD8131341CF7C57563385DDC2D88
+:109F8000E051D77187A1C146EDA99FDF02DFE373DE
+:109F90002CD0E72723298564CF25CAD7F957AA0FE4
+:109FA000F526A0BFE7E6451F2A381FEB9826432D6C
+:109FB000CDF369FE1D561DF9BD6C6D6C3FFBBF38BE
+:109FC0006DC22EE07C90DD599DE3223960720F8BCB
+:109FD000B087B36B7C2D1827BE7EADCFAD073CBEDE
+:109FE0007CEAE8B441507E72A4524CF8D72B5CCF87
+:109FF000F96D344E3DFAC1818F760B3E497730F5CD
+:10A000001A9203DC1F50A532D5467EAA3E9213F564
+:10A01000AD420FEE117E6E735FDE4D766A67BB2632
+:10A02000621F06ED6C362AF7E5FD10F34A67F8E784
+:10A0300093DE711969BE67A43C607EF27B4A7E8B19
+:10A04000F61BA1BCC1FCD1579DE55D281FE5333D42
+:10A050008EBFE4EFE2FBB8744F17CA15B63755A3AD
+:10A060000FE2C99503379FE77AFB950F890E1B9086
+:10A070000E717CDF498DDE5E4EC215E8F0A50F89BA
+:10A080000E977771F9DAD0556EC4FDD40EE1D76919
+:10A0900010F4847484FBE8BF3A93699C86C9A1E1FB
+:10A0A00028A7CE0BBA3BFF12A7B7433A1DF9010E02
+:10A0B000ED1EDDDEA20CD48F4A8D97F0DD00F8E6B0
+:10A0C00076F3DAA36867D5D73037F26B43A7E0079A
+:10A0D000B07B11BE0D5DD5CBB1BF416933C9DF0D7A
+:10A0E00076C9B441506EA863A5C86FD9BB2A5E4239
+:10A0F000BA605D7C3F9E5D03F62CD24D5ABD5B9FDE
+:10A100008F7A8FDBBDD78F2CA3F63B725D14E7F2FD
+:10A1100057318AF3EF40FB19F55DD6686E3FFB3689
+:10A1200092DDC55C09E437653E750DD66FF02F6290
+:10A1300094D711CDC72F29B40F680858291F685626
+:10A1400017B77F1ABA381F9F93F0914F43CFADE4F2
+:10A150008F7FC1C4FC11FED0375F9ACEF5EC8B2601
+:10A16000D2B39F357BD8C7B0A0B785BC9770AC6D14
+:10A17000CBD721DD32769309E7B14CCCA3CDC0F526
+:10A1800046B2D00305DBF83CD474E1774CD789A7FD
+:10A19000519BE7E2F0937FE19C188FC8225DE8397C
+:10A1A00018BA7E7990F8A4EE19DE5F9AC9537867E1
+:10A1B00004BD4AFB289A1E0BC4B8D9BB0E2A284CF2
+:10A1C000B277CDD1F0F9F5352CD808EBBC7E972EBF
+:10A1D00038651CD94D0B499EAF37B258F92A23D2A6
+:10A1E000B9FD5695EA2D44BF76D5CD3677A43FB953
+:10A1F0002AC1A3B3A01D5724FDD8DE128C1B9D4A93
+:10A20000B7BB116FE3D25DD20ED3D85B03F7DFDCAF
+:10A210000EBCA1CD3F0EF71F81F509F329AE09DA77
+:10A220008DFCDC0E688FFBF7DDD7FE9CEFDF5BB8A3
+:10A23000FF020407C999546F09FA8F9D05DEB55CCA
+:10A240003FD9DDB1D6F3AA93AFE7C0CDB716E23E52
+:10A25000B161AE8DF8E1815794A59CDE4011E2BE5C
+:10A26000DAC7F983017F3CE1227A243BAAA1C91B0A
+:10A27000884D8F9C5F1AC0AE423B1BE8710DB793AF
+:10A280006D8CF313A74BB9BF47B91569CF4A3E8D03
+:10A29000E67B49BFFD7CFF35F9FDBC81F3E37980A6
+:10A2A00003D27B3F9DBFCCE97CEB7AE047F8BE153B
+:10A2B000F8B12542FE47EF7F709EB81F90F2F61E60
+:10A2C000A777513ACAA1DD6F6DC650AB948F0D2FA1
+:10A2D0006F197E39BBCB8C95A15F33F06B24FD6089
+:10A2E0008CD65E444F3FEA09EBBAD8FE8FBBD26DE5
+:10A2F000DFCD3F3F302FE5AEF4D2817929E9A87355
+:10A30000106FBBAD01B48FA51F297A3E4B049F4946
+:10A310007CCAFD03C621B0FEFD82EF37897A8F88A3
+:10A3200067C4BE84F8C1A5F37D4879F671F4916CD9
+:10A33000F77DF9B5E438522F46D38D8CA3E07AAA85
+:10A34000C7C4AFD7B65FECCFA2E8F829C15F0B80D6
+:10A350003770DE6D86E017C48F77D819E513F8994A
+:10A360002715E371AF8DE07C34B26F38B6B766FA6B
+:10A37000BE44BA927E5D7C8F71AA5A11BFACDD6B70
+:10A3800008449E7FB93783D138BD76B35F0FFC9107
+:10A390009BE9DB87EDFD15CC1D443DF38F168A2B21
+:10A3A00081815B8AF2A691851211CEEF25FB5E209A
+:10A3B000FAD5F70C47BFE33925340EDF9F10FEDADC
+:10A3C00013C25FFB7ED77BCFBE02AD17BF726EF1AB
+:10A3D0008F91CE5EB4E4217D9CB0F4E7BF25A1DD72
+:10A3E0007D81B9922E770E699159EF5523FC67272D
+:10A3F000ECB1FD7F6F0B3C378A782B5319EDC3B757
+:10A400006770F9193EBFC4E3ADEFEBB4FE37F91C3A
+:10A4100093C1E1DF19E71C506106DFD7740EE1FC40
+:10A42000D8D7AE50BCAF66DDFA3FEB412ED4ACB509
+:10A4300007E9099FD18EAB71F8833A289F3070B934
+:10A44000047F73CD6561FD07F5D449C8337E07C528
+:10A45000BF960AFDB5ACE9CDBFA15FA14665E6494F
+:10A460004518C7F21E1E049F3EB52D4F44F1BFF2A2
+:10A470004777A6A37ECA58D426F2C1A63AD0FE5585
+:10A480003C37E82F592F676FA96427131D00DE1E84
+:10A49000CCF0F6221F2F4AE27EC145775A03FE0810
+:10A4A00079B857F06134FD7C10E7BCCD97191501E0
+:10A4B000EC6F61AAF76FD4EF9DE73472EDBC12FA2E
+:10A4C000C523485F77D8DD4FF0EEF222F363D20563
+:10A4D000FC6B310E04A2B1B7B067F8BA7CA4E3BE3E
+:10A4E000BCDFA15FABDBE4F0BBF0BB91BECB76F190
+:10A4F000E241F1E3402E23D247C34585E86169F785
+:10A500009BC751AE37A821A293A5661BE1B1E1A27A
+:10A51000CAE9A9D5703624DB03EED7A47AD232601B
+:10A520009EFE7B2725533C09F889C3172A459CE3E7
+:10A53000F832C3372803E0F79035F136DC7F5D3021
+:10A54000BB92308FADD108F4703575E73547D843ED
+:10A550002CC7AEA583EEB7FE86F35A6EF61951AF3F
+:10A56000AFF034D179B14549C152C79848BC4FD2F8
+:10A570005F1AFDF5F17E49C897F78D3C6F64209D09
+:10A58000733C6CCF10F5B239BFBC9FC76A9EC3E75E
+:10A59000287842BBF787887291280F17F5D279790E
+:10A5A0009AE097F7C7F17AD1E32C15E37C99E1990A
+:10A5B0008C7082764123D2C76B163A67C44A40FE3C
+:10A5C000A1BC5B934B762CC8B96908771827984CC7
+:10A5D000F54CA4675813C841C0676FA98BE0B3B5A9
+:10A5E0001CE805E341AF9A281E24F12BF11A8DCF08
+:10A5F0008519CA77CB4F1F18BF5E98513A307ECD70
+:10A60000D850C217D14B8CF31FF1F0F56B3BC70349
+:10A61000F0EBF20CD283C1B1917CB349C051CAB501
+:10A62000F713B478FD3C9DE3A15ED4BB84761FDABA
+:10A63000D1EE3EE2BFF75378FDB402AE97A45DFEC3
+:10A640004F022E5FA66B9F52CF44FBD1BF14F2E2A4
+:10A65000CB74EE4707BCDE8DF395FA09E44C301954
+:10A66000F878D1EB2692336C631FE5D540BDFF83AC
+:10A67000F05A64EABB3515F4CA0FC1DE311651BB7E
+:10A680004B284706ECEFC748BAB033D4DBAD190E00
+:10A690006E1F94F4F1B8D748BEAEA50CE48772657E
+:10A6A000FC630C210BE4F06B22BF42C1BCAE146210
+:10A6B0006717F60770FF978CD230DCA3C73B21E801
+:10A6C000E0D10C4525BC15B242C4DBADEF7E6E5F18
+:10A6D0000C5D9E13E765934DBE76ECE7ECDD6F9164
+:10A6E0009D7EC2181CDE668BF1DD187CEC2125FCFA
+:10A6F000FDB6A7F47EE3D5987F7EF6C19B61DD4B66
+:10A700007BF46E1C72E93D5FBC331EEDEC1E03C58D
+:10A710006B40DF6F5371DE4DDCAE3CA1D3D2C1671D
+:10A720007769F73DAF0B7A90E772A5DC91FA7C155B
+:10A730007373799390B81BCB1FDD713B9DCB5DCEBE
+:10A74000BC873D00F7D36B66925D7C3BF3515ECFD7
+:10A75000B256ED39DB156DDAF2ED3B079CC32539B6
+:10A76000BC2A10FD5EF8A52B63EBFBF3822E3F3372
+:10A770008AF8FD7A53CCF8FDEF85FC09C7D9FBB404
+:10A78000F1FB572F1FBF6F8C8ADF87ED88E8F83DFC
+:10A79000EFF713616F60BF9171FCCF2A62AFE3A343
+:10A7A0000C69B75835F9199F0CB05B12E97BE3458A
+:10A7B0004B9CF9D8E8FD672B638FD3D73F8E365F6C
+:10A7C00020DC9EE709C8FDB5A493C68B59A4676534
+:10A7D00059DAC7E17639F43DFABCBAF46F4BBEF8EA
+:10A7E0005861E62CF2476D1776BC9BF2333F46BBAF
+:10A7F00008F972BAEBB5104C71D98F270E578784C0
+:10A80000F9267A1D405F674211F2D898694F23FDFF
+:10A81000EB666E3A9727E8FED6BBABE87CCFFFBD70
+:10A82000A73223326E2AF7530D46698FD934FA9630
+:10A8300045E9E3655D6F911D06F6D770143E7F7A9A
+:10A84000F56ED2C32B99371DE9BDF7D511746EE5AE
+:10A85000DBEA61399F9BFC4B0C3CBF358DEC8739A3
+:10A86000623E3775733B5067F618681C0F7339D218
+:10A87000698BCDE70B425485F275FDF347E71D6305
+:10A8800093C4FC156C0FF0BD4E3CD9525F26CEDB55
+:10A8900084E3EA310D269089CF96896E173EA7286A
+:10A8A0005E95CF83E3791A6BCAC1FA3A7348CFD762
+:10A8B000093348C7F6FDF0A2B25D9437CEBD70EB08
+:10A8C0000A7C6FB3933C318A794CCF04B988FC6D14
+:10A8D00066665CB7C9163C4DF133F1F457B8888F02
+:10A8E000FD4318F9411258079D3FB5D9CEF971B112
+:10A8F0000EE650B06C715C08E27EE29CC3E6C7F3E2
+:10A90000C4202F6765A23F5FF9D54AC40BC867EE24
+:10A91000178AF75D0DF2F31142DEA588F9B50879C3
+:10A9200097C5DC8AB8C780E4DDFDF69537E07E2662
+:10A930008D79F7A3BC7B387106C5FD32988FE693FD
+:10A940003A43D5C82DA7575BCE98AF46CB3B05E71A
+:10A9500097E5D3BE37B3139497A404BD9997526972
+:10A960001F3612FD310621378E59783EC26631CF2F
+:10A970003B3353886E8E59785EC2B7B65BDCDA7DA6
+:10A980007D430A3FBF7F3EDD6CC6F1C08EB913E147
+:10A990000776CC077E16CEDF2C9CD24179029B6FC6
+:10A9A00054DC1BE0FD66BB6BBD0AA4EB9FA9707F66
+:10A9B0008FEA28C77C9CF63C871BF3441B45BEF7F7
+:10A9C000668BA3F619F2639A783DD6B719E396ED34
+:10A9D0005B1D0EAC9756D937CD88FBAA15CCB19B21
+:10A9E000C5A0F7AF808F60BE3FC732E04911F46366
+:10A9F0003DE2BA85D620BEEFC17F17F0F29432DC7B
+:10AA0000BFF2BF82EE423A77C93C7AD2978DDD859C
+:10AA10006FD860BC82B985E4AFF756F2B82F1372D5
+:10AA200060BC1C57F0D9B561BAA7EF85A23CB45BF6
+:10AA3000F87FD34C3CAEEB8021CAC49143AC9FC697
+:10AA4000F9C1CDE41FE7D36B58F80FFBAB0CF74F00
+:10AA500072696AF87398EF60A822B3BBA50EEA8DFD
+:10AA60005783FB91AFAF15CF42F13C547E23E9E50C
+:10AA70001E9DCD65D4713E3717A0ABC3AB47B894CC
+:10AA800039B6B4603FD729417AE6CDD8DE82D39F6C
+:10AA900023FC4CC999C6009E376B99007826BFC825
+:10AAA0009F0FA3FF5AFF2FAC18F174CC20F59E27FF
+:10AAB00089E7FFB9683DD50E3E5997CE337B2EC24C
+:10AAC000F9283FCFC6D0748BF8FE97A9554997D780
+:10AAD000BB3C0F30254BCFE5E30C1E876D9C6FA66A
+:10AAE000BCE546710F03537DF93F8CF0AFC8B8C584
+:10AAF000BB06367F5F8CFD464A16B707E6DCC0FD15
+:10AB0000C28D221F477E4FCCE27EB2BF644E7B37A0
+:10AB100093EC3D1E6FFD9D945F23D948945F11F225
+:10AB2000E58F245FCADF8E277FB4DF85FC99E72994
+:10AB300036D0BE40C82129EFBD22EF6801F31810BE
+:10AB40004F3DE21E95A3E5AB480EDDCC7CF4FEF74D
+:10AB5000153CFF0008D380FDDD34436B3FCDF36A25
+:10AB6000CB37CF8FB6AF383EE4B80B7CDAEF73A4A7
+:10AB70009D3C436B272FFA87AF9249CF67FCA2FE1B
+:10AB8000D2E0703E5163543E5183C8276AEC2A3CA0
+:10AB90009416914FD4D8CDF3891ABAAE944FC4ED20
+:10ABA00029AF29B01FE324DE5AD294EC0D917F72B5
+:10ABB00010F34F8AC2746EAFB0F33C0CE6A1BCA296
+:10ABC0001C8795CE5DB4EA8AC88FDB9A68D7F8DD1A
+:10ABD000B7AE7755613DE9BF95F9434837B1F6C344
+:10ABE000D9597C5FB343E17E74FF0233ED3B9D0591
+:10ABF0005E4D5CC1A967C7D1AFF86EA64BD6273FA3
+:10AC0000C90E832FAB189E0185D17989FEF67AB6DD
+:10AC100091FC905172CA99EAA6388033692CF9F5F3
+:10AC2000E77517923F92D92CEE614AB8FF7973DB32
+:10AC300055CCEB69EC6E5797DBC27437364BEC435F
+:10AC4000ACCC8AF4DAEFD77BCE447EBD6493B730C8
+:10AC50000BDAD71983E4BF8BA0577A1F4F5FDE2E24
+:10AC6000E8C550E15DB002E6D7FB8ED18DFB6B0AE3
+:10AC7000CC41FFCFBF944C7E49750E233DB5B19CAE
+:10AC8000CB935EF493C13A3E4DE6F7FA6CAC66A402
+:10AC90005FCFA74C233A5EC502873DE847DB0574CA
+:10ACA0001879CFD21E6DB98E7590FEA97B66003DD6
+:10ACB000937C94F2B89EB9F4068C1B746ADBB3A142
+:10ACC0005A395C28F447F1BCA92D98FF50ACE3F247
+:10ACD000912D770F9A43FBF5458E4F2C28727FA15B
+:10ACE0005CCEAEEBB59FD273FEE77AA154F41FADF4
+:10ACF000BF4A853D3719E417EE6FA57D06F5A97C9F
+:10AD000050D7ADCFD485E75922DA49BB50EA0B8939
+:10AD1000AFF2098CE179B5BBB2847C1AC28620BE41
+:10AD2000A17FE21305375829D4BF1FF785D78AF1D1
+:10AD3000801EFCA8BFFD3A7300E96BB3D244FAD27F
+:10AD40008CF63F3CB72A3ED20BFF5EE3D7237D4C07
+:10AD5000644D37DD00F526997BAC28B7804EFE3177
+:10AD6000927E5A58306F9FA2A123FA7E36F9ED9851
+:10AD70007424F55AF0F7DC9E99C5BC74CF93E70FA5
+:10AD8000DCEE3AA8F07D26D89F07D1EE7A5B3793A8
+:10AD9000E864262C03EB5539B4F89F9EA92D47DFB4
+:10ADA0000FC5D05A284374487806549C4FF4BD51BF
+:10ADB0001E29F79856EEE5B3AF78DEF896C33F420A
+:10ADC000FF83751D1B89F60E58AAC48FD1F4B027D6
+:10ADD000EB7B8FB7ECC98A116FE9157EE56B58687C
+:10ADE000E533CA407A3B7F689D3E33822E257FBC87
+:10ADF0006CE07913CAEB3CAE35C1CCC604112E25EC
+:10AE0000DCFF28F9E31AA4D39430FD9589F787A4D1
+:10AE10007C19CC0623BD5DD76509EA013F85A2BF39
+:10AE20006B90FE8AC2F689DC77B44C184067F998BB
+:10AE3000170EF64C01D295B44F8A958E163CE7FD5D
+:10AE4000FC4BF7B6E07C23E8EA2D84C35905E88A79
+:10AE5000FC6A03F4ADF67B14DD49FC4B7BBA9C35F0
+:10AE6000D17E676E02D7B3C1EADB49CF82B824BA7C
+:10AE70007B730EA7BB2AE621BA2B675A7AA9346BDB
+:10AE8000CBD1740923EAB474E723BA8BA6D77874BC
+:10AE90003718E94EEADBD42BD3DDE74877DFC58FDF
+:10AEA0003990EE3ECF72C6A7BB687A93F26C9FC50D
+:10AEB00051897675638D42FAA1F89DA12D581E51D6
+:10AEC0009F4F76F6BE6437D9DD8D4DFC7B498F47A9
+:10AED0008F7933056BC5F77C6F25961BD7C177E853
+:10AEE000BAF418CFAB197A0FFF5EB8A1E90DBCBF59
+:10AEF000A0D1CFDBBF7C7A339D870A6C16EDCBDB0C
+:10AF00002AB1DCD8CADB7F8A71AEAB31BF2DD082CB
+:10AF1000EFAFDA96EFE6DB6F6ED74F11EBDDA73CB4
+:10AF2000F706B56BE3ED6E3F6C4E60E427E0F6FA92
+:10AF300064B1CE29BBF83AD33EBE7E860BE86345AA
+:10AF40009F9FECB94F74756524EFE2ECB3CB95B6D7
+:10AF50001C7C4E4739A647BCBB5BF543781C743755
+:10AF60000C717536F7D3C8F821E6295447D817571E
+:10AF700067733B44D64B4F61747E8DFDCC4EFE72A1
+:10AF800019DF0C3EC414D407B8466197C48C774EC1
+:10AF90002F6822BB62FA6019E70CA94B61DCC24B37
+:10AFA0009F4F8BE5472ACBE6F6F329917721DFD730
+:10AFB00004F2754817FB9048E8FCF09077D09EDBD0
+:10AFC00097CC34E7DCF6E5F3F2D4ECBC7F6ECD0130
+:10AFD000F8EA9A54BCF78BE52994B7F2831E164C15
+:10AFE0004A1C38FFE92A0B1A290F8ACF7F658B513B
+:10AFF000DC57C2E5DA3C813F366918D1EF5C81A7A6
+:10B00000EA6CA1178B5931CAA979026F3F343719FD
+:10B01000B8BE6E3344C98F79D9283F1E8E6BCF6B73
+:10B02000BF47C9971A31EE4A61C7AF627DE43FFD61
+:10B0300044D8F1A71EE676FC6AD641FED3DE9F71A6
+:10B040003BBE1E9687F412ED07ADDDAB2DD77768BA
+:10B05000CB0DA0DEB1FFC6AE28B93386FBA57B1FA2
+:10B06000AE2F433F64CDCE77C8FF5D23E54C402B28
+:10B0700067C040E772E6A151E4BFFAD6F2E319D8FF
+:10B08000D59569F24BEFC97646F8775EE4792E0DD7
+:10B090008CFB117AED236FC17D2C8BD24FD172A521
+:10B0A00050C815E9FF90F25BCA9B42C6F514EC77D5
+:10B0B000DFF1609B283BEFE16CA1AFC4FE4DFA4D80
+:10B0C000A47D5488F611D2D7A82622BAB07E72BFCA
+:10B0D0006DD247E8A5052566C47B9119F81BE1A64A
+:10B0E000B78DF5D934F4F168F6E5F783DAEF51F46A
+:10B0F00023F7630B05FDDC84911818FF0F721FB84E
+:10B100008AD3CF5CE63D84F4F3FBD59C7EE4BEF0AD
+:10B110009BEF033DFAC87DA0DC4F7EDDFD603FDD87
+:10B1200058C03E86E7B15CE917E0F1FD4685D3459E
+:10B13000FD9CDF3D56C5C2F2E2683373AB8670B941
+:10B1400065A6C98C7E971603DF2FCD99F57ED9D2DF
+:10B1500008F913B4971F40B8B16E27F977EBADDA51
+:10B1600071362B3D77FD11F7558F5AC9AF74E10841
+:10B170002393E5C2AE11940FFE9981C75BE57C6E07
+:10B180003FBCF7B510D45BB9EE9662CC2FA8550240
+:10B190002FD6C1B70FACBE7791BF6B7541712F67CA
+:10B1A0000FC527E4B8F1FDBA7E92C7C6035C3FF72E
+:10B1B000290994DF0BEF8747C6E9FE3888CBEFDC1F
+:10B1C0004CDF07B81EA9475BFAF327F813B4301B0E
+:10B1D0009412CEA708E74D707FCB5F98E78A79136A
+:10B1E0001B23E204D03E66BEDB7921CF47617201AA
+:10B1F000CC6765BAA717D77F4AC4854F8938E2A9BB
+:10B20000441E57FC7B7F7DFEB40DE27AE894883BB8
+:10B210009E4AD1C69B64BD44F13CD96CF66E346045
+:10B22000BC9E793782FE703D646AA27C95451C5FA6
+:10B23000BD2F256BEE11C81A543E6A10B4FB99D38A
+:10B24000AB1F04E32C6FD39E83EA15F7DBF60ABA33
+:10B25000E9B5F0A71C376B50F5286CD7BB80DFB37E
+:10B26000DA5F9E28CB5EEABFF7BA10C9A3FEF28F61
+:10B2700042E29C3AF793C8F840BCF86174BC30FADB
+:10B280009C6974BC7FB1E43711EF5F24E4D4E26EB3
+:10B290001E6FB8D5CC360F82EFB7756750FCB82655
+:10B2A000D13F5C13EFF75BBF519E87A4CFDEDC9EDE
+:10B2B000FEF8F8CF22E2E3F5223E5A2FD7D7A95D58
+:10B2C000DF6401CFEF313E3E799073607C3C3A9F62
+:10B2D000E245B4330C613CAC7170B855E9EB2AD14E
+:10B2E0004F7C6139A33CF7356F2D6B413FF29A2DAE
+:10B2F000E296556177D70B38C75B97D3AB632E8D3A
+:10B30000BF3E81B922D693E54BD194C9928FC83301
+:10B310001D5493AD699FDB3444537FF0BA519AEFCB
+:10B32000F9FE224DB9A0F51A4DFD616D159AF2880E
+:10B330009DD76BEA17B22149E46F3BA2475F12BB6E
+:10B340002A3047F37DF4DE859AF69FB2A61D93A0BE
+:10B350005EA7457B2F33F37B7AC69485F3A9C77626
+:10B360002CD5F4C3824A50290BDF33F699B8A7795C
+:10B37000790F8F875CDDB55A334EADBE8EF0181D48
+:10B38000EF2D627DE4376E0828EE201B18FF5DD597
+:10B39000D54EEDAE64F7C878C8C64122DE97CDB26F
+:10B3A000395D47D3858DECC30BBBF4E47F2C64C3BC
+:10B3B0001F9A44F032B0806B20FE2E30EE17BBF0A7
+:10B3C0008CDD8D7945B7BFB58CE663CAD4D205DE76
+:10B3D0001F18B95EEB482D5DD8DD5A3A489AA0A5F2
+:10B3E000836878277BB474C142F0BFCBC03B7586BD
+:10B3F000966EFEB7E0DC81F0B586E15B7CD0D3626F
+:10B4000023B8F1BC35699F99843D141DD790764EC1
+:10B410007090B0BB453F322EB159F1935DD51F7787
+:10B420009C10CC0BE6A33DD5C4B85FC97B10E56F7B
+:10B430000CBF24BD8FE79794709D9BC0F5672DF3DB
+:10B4400092FC3E66E1FEA493D5ABC89FB4923591C1
+:10B45000DDFDD99CE9C2EFE8A77A57CA5318909F3F
+:10B4600000F6298BF0D7AE068B1AEF1F8A86A7D27B
+:10B47000AD04ED786E98754B7DE0A3FC150FDEED05
+:10B48000A989FF68ED5FE65122E597B487E5781258
+:10B490009E52AEC9714CAC499F897C1125E7D8C832
+:10B4A000E8F893D69F23FD41328E23E34CD1FE9BD7
+:10B4B00008BBB8558F71D2C1F92D78CEB7D8E1212C
+:10B4C0003F6129EBB905DF4F3077B4A82EE1BFB853
+:10B4D0008AF5FB2FE2EAAB2BC4B56FF22BA147F242
+:10B4E00007C6B3657C1C96FFF11FA1F124C5958B9F
+:10B4F000F398F3F20827D2D340BFA6FBF82BD08FE6
+:10B500005ED7978AF5AA30313D22DEFDA612A2F55C
+:10B51000FC907936459EDB6F601DD36E217F32E84B
+:10B5200049BC27A793FBBB5857B43DAC92BF590702
+:10B530002B41BAAF651171DEFCF0772AEB079665F7
+:10B540001ED295EC89A7F18272CAA3E0F9534CC8C8
+:10B5500041B9FF8CB7CF93F918F27E4F9977549485
+:10B5600023F8751C1B87FD03BF95E594A27F01F8A6
+:10B570005389E4C7FE3C25FA3E801FA3D62FF33142
+:10B58000F4F612F21B2D8B5CEFD78087B45B7E9CA8
+:10B59000C3E8E9C871D1B33EE1C46F3DF8B9A4472F
+:10B5A000933FDA68840D0DFA135E1479811D5ABB3E
+:10B5B000FD961C9D801BDFF75C095EF1F121F2F81E
+:10B5C000043EBEAE1D26F3F8241C970C84FB0A0D26
+:10B5D0005CFBF78FFD705F110BEE122EE74A7B7E4E
+:10B5E00081F8D2DB8FA523BC17A67A5763FDDCE375
+:10B5F000A14F145D785E55FAB394877BA14B4FE75A
+:10B60000FF1AAEE372B0E1253D8986F3DD268AB3E9
+:10B61000D674BD4176E1D96610B406FCBD0C187233
+:10B62000D865FC0851F08EB74F92EBD99023F6E520
+:10B6300062FD32EF07D6B93927665E473F1CB4DF9B
+:10B64000051CAAF46392F01C597FBE92DA97177911
+:10B650005F5FF43A2A7278FEDB29B3F73EECEFC362
+:10B660009E9C1DD85F95BEFB7036C267AD42E7BB9E
+:10B67000A698F879DC2C715E6F42A8C98DE79933E2
+:10B6800073F87D66237EA4F7621CF9FDB577A6E00A
+:10B690003934D9FF084547E747197BEE837F2CC132
+:10B6A000F8E62237DE6FBFD824EE2FBACB1A2C0073
+:10B6B00039F2BA91DF476518D244E766FA92F5E4A9
+:10B6C000D74CD3B3A9487772DEF2BCAD7C8FF701BB
+:10B6D000605EB17C3FA5A5AF780DFA7B043DC875CF
+:10B6E0004FA9EC2B6EB285E12FF33CA3E15325F873
+:10B6F00043EE431BF05E5BD0BFE7CDBC1C7DAF6D5E
+:10B70000FFFE7458FF3D36F6C8B87E83C593341EDD
+:10B71000F951DC6BFB17872789DF77A4BDA7F6BC3F
+:10B72000C8B797BF5312EFDE9BFFCC51BE977B8209
+:10B73000E2E585CBBCFF7870694856997A359D73F0
+:10B74000F75EAEDE2BFFAD8FB9DFBE28BEF7DFD3CD
+:10B75000F96AECBCC55EB1CE707E6188CE29F7E790
+:10B760002DBE547ED97B471AF03ED20838C8BCF6AD
+:10B7700006BC8FB43846BFD09FCB76E57B87AAC482
+:10B78000BC1A308F3035F23DA7B7F03869222F3020
+:10B7900094887CFBCB2E3D9DE3FFE511DD8CDD31F4
+:10B7A000E69D9BCBE132CAA9121F8D0EF2FBB5E3D9
+:10B7B000D593E779E4B9D8E8F97556846EC5F9638D
+:10B7C0009E72ACF11CB97C3F2BE7DD99C2F1D1F040
+:10B7D0009A89DF9BAAF27CF2CE94D04AE2138716B4
+:10B7E000CFC3041E3BAF0FE5D1B9B299DCEF108F88
+:10B7F0001E26A7FACA51BEC87BEECAD426C511C1FF
+:10B800008F57A28730DCF51ABC0E84BB91BECB7E6D
+:10B810004F1F157CCB3C36DCCF2D11FA6EC99E5ADA
+:10B82000B287E57EE9F44E3DE56F9C663CAE72BAA8
+:10B830004DA1FDD0521F63EB402EAD7CA27833AA00
+:10B84000AE2599B09614FE1E7F1F66E9C6A8F8BA09
+:10B85000D85F49BD2AC75FBE4D6B17D7B06D7F4615
+:10B86000FBE9F4512E3F56B026D23F2B1FD0F6579E
+:10B87000B367D6A738CFE8BC8011C28F372D57ECFD
+:10B8800057CA5819EA8F354F7C6EC49F6089C71715
+:10B89000F8FB4F4387F1DF7DC227FE8E083E6FC95C
+:10B8A000F5FC2017FD3EEFF2F9AECEF5CDC9457F90
+:10B8B000C9BB7C7E17EA2E703DB32B8DF45B8BFDEC
+:10B8C0002E92FFFAC15CFEDF8BF735009C4C26718F
+:10B8D0006FBAAE499F48F64D80E8EC43E71D737E92
+:10B8E00040657726F243DAD3D36760BFCEA7AD1E9B
+:10B8F0005CDFD6724F21FA2FB656F3F3A166138F91
+:10B90000DF077E39F100865386766CAF40179DA322
+:10B910007B7F10FD42ADBA3F1FC6BC98D6C93C5FC5
+:10B92000325D17DA3F28623CA7359089F17DE768E0
+:10B930007E6F4E9ABEBC90CB7F6E2736085C5CE86B
+:10B940002A207F62AF41FA173B2C742EAB8EFF2E5C
+:10B95000C628C6F12FF3EA700E9176F1D966A6F9E2
+:10B960009D86511D4AD09048F7A8503CA86E4330A0
+:10B97000FD16D4674FA9144F93F34B7B3DAB02E305
+:10B9800066528FDDA238B8BF4DD8FD0B98FCE3712D
+:10B99000B7F9829E16087BFF162B87F752E6CEC3B7
+:10B9A000760BCD2C5107AC764B654729ADB3D690BD
+:10B9B0008C76858C1FC5B74762FBC91A7E61E7E7A5
+:10B9C0009E95BEE1D8C919F4415D863FDB853C698F
+:10B9D00018CECFFFB1A1CC83F1CA86D746D0EF30C5
+:10B9E0009912783C1CE49619EF113A84FA1ED6BDE0
+:10B9F000EA158BC85B0A8873CDFCDED8C639394599
+:10BA0000741EF1781FDDFF71DE10CA23FE067984F3
+:10BA100037A6BE92FBBB1FE0BDEB0DD960D741F945
+:10BA200074EE9F7879486825DE1B9992778997474D
+:10BA3000853EC1724E5EC26C2A178556EAA13C3E15
+:10BA40002F939771030A0436356FF06C3FDA2DC9D6
+:10BA5000C22E7087E8BC77C3CB237491FE58771E43
+:10BA6000976767843FF94C3EBB6D0EC27B64ECFA6E
+:10BA70006979D2DE6EA3F5C9F5CAF62C3376BBFF21
+:10BA800010727E9538A73DC5CA5A2D3CFEE74F047B
+:10BA90003C1CEC1E41F1CB7FCD4DE1FD3B42744F90
+:10BAA0008FEC27FA771CE4B8AB15FE7B59E7A3F2BD
+:10BAB000BC7E97CBE52B8CB391C619EAE1E79BE7F7
+:10BAC000E41422FE006FAAC09BCAF7C9ED7C7ED0A9
+:10BAD0002FFEFE13E88762F4FB1FFC0AEAE787E704
+:10BAE0001D4D2727C538AB5A78DCB62FB980E869D9
+:10BAF0008A55DCF752A25DC7F83C6E9FBAF392C537
+:10BB0000791D09AF0C85C6691170CC090D9F33F6FC
+:10BB10009BAFFBAFFF4BEB8EC09707EF6D39D8C5DE
+:10BB2000EF371E9FC7F185F49C4276E0764D7F6724
+:10BB3000D647B59FC0285FAE21A580DADF2BEE6F18
+:10BB400095F7D961BBFC71DCBE45BB57DEA7C1FCD4
+:10BB50009359641CB2FFDE8C0E71BF70FF3A6F28E0
+:10BB600011EB7488753A22EF33ECE7CF637D79737C
+:10BB7000ED03E9B81FFEFDFD8D2912FD69F83C5665
+:10BB80007FC8D7F1F072551E9727DF1B5EE43CA3F8
+:10BB9000E0D90FE7A8F94978227F53BB315ABA940C
+:10BBA000F3CC11F43980BFF3BFE578E27ED9FABB5C
+:10BBB00079BE387369E9BABE335F87F909B2DD0728
+:10BBC00078C0A034EC27BC214FEC2773584E9CBCA6
+:10BBD000476F9E33A67F91DE47EF277B93E5EFD932
+:10BBE00069FD1ABD4EFE7B39FE73FC7E836BA3FCA0
+:10BBF0003C188F7ACE166E17D62FDAF263027E03C8
+:10BC0000FD547D7938BF1253C5F3F83B5BABF34A63
+:10BC100067AB6077942455DC990FE5A6C7C693FC03
+:10BC20002E1954F1793EC8F3358F4DE0DF47577C2C
+:10BC30003E04CB791379798AE77994F760B4CC9E86
+:10BC40009A15B62BEECC73D1B8FA4A1DDD6B67425C
+:10BC50002306D6637ADD44F98012AEF19E25265D77
+:10BC600053ACF3BFF7F4D3038FBF4CC07FBAD01FE0
+:10BC700028FC052155E32FE84DE4E7CF7B5FFD92DB
+:10BC8000CED7DC9BE75B9F07ED1BAD676FCD87F2DF
+:10BC900006EB0714EF533C6087A01FC6E5608B607E
+:10BCA000BECAD9AD5EB49FD86AB75925B80AFF1885
+:10BCB000DEA907F07BE5B5A77E3C880FE3C5794C8C
+:10BCC0001472A0F1B5BFFD15E3C48D676C6E341B13
+:10BCD00027763F7C27DA5F13BBDFFE1BD7C3FC3C14
+:10BCE000909CF744F47FC2FB095D269AFFC4EEAB3B
+:10BCF0005660FD6BDFEB2E403AB9EE44B005C5420D
+:10BD0000EFABFF3E48730E887D7AD97CD1B8F1390C
+:10BD1000098F3F01A093081E3FE7F0F88AF2D9CEC1
+:10BD20003B8F6E0E9193547BDE0AEC788A3B5F600A
+:10BD3000096E8C7BC873FDD17ED5E3D5B03E787F8C
+:10BD40005D1FCC20C29E9E72D10C82245C2E67C9DE
+:10BD50009A72A5394B53BFCA91AFF93E3DF32ACD34
+:10BD6000F799AE424D79D6C8899AFA37BACB35E5FC
+:10BD7000D913666AEA577BAA35E5C26087A67EF1C9
+:10BD8000912EEDF7634C8F78283AEE7E039FA5271E
+:10BD90003DE49E2D3BD5F4063E27FE858323DAAF96
+:10BDA0007CCDC58E37F0BDF42B479F9F927EE69BDE
+:10BDB000F5B68031B63F39532D08DF83A0D7F1F3B4
+:10BDC00053EF25FBFE807893E7A7A6A05F1990505C
+:10BDD00075DBB99FE2EF325C58C4FD6EC711319438
+:10BDE0004F6E277FE57143D3B37FE47903B928F71A
+:10BDF000AEEB9BAF59F7948B3ECDBACBD9AA283C7A
+:10BE0000DDA1295739EED6D49F9EB95EF37DA66B8E
+:10BE10004B149EB66BCA37BA1F8EC2537B149E9EBC
+:10BE2000D27C97F4DD2DFC5FAFA1DF0A9E93423DEB
+:10BE3000958887C9A7FA081F137ADA2A114FD71CE9
+:10BE4000EF207C9504BD95282ECB8E34BD81CF206C
+:10BE5000ECCBB0DD81E64C7A1E6C7691FFEB70F393
+:10BE6000487A1E6976D3FBFF689E40CF5F357BE83A
+:10BE7000F99FCD33E8D9D3ECA567477307D57FAEDB
+:10BE8000B98BFBCF52FBEFDDC845BFC1795DA8017F
+:10BE900023C68EC15B499E9E4F089DC7F2067FEB6D
+:10BEA000ECA92034F0671D902F7F209E452E4FFB7C
+:10BEB00060780E1ECCF8FD19227FA343E729443B8E
+:10BEC0007CF4E30FDEA7E632B669BD37137F3A187C
+:10BED000CB662813B2E9F7901EBCCF93C3D8B3A8A2
+:10BEE0004AE8BEF7076763B957FC9EE7E0C71F241F
+:10BEF0003BFC5BC7D93D03E2ECA307C788B33F7B9C
+:10BF0000CA65477FCFD1AF46D8111E4785DFCBC367
+:10BF10000A0DF83B1CE56AA101F5ECF138E7215464
+:10BF20005379C9E0525CB77B1EE5915F6FA0DFE1FA
+:10BF30009BA3F0FDAFAC97ECE2FAA0F74613EDA798
+:10BF40008EE93C2B903F7A95BEC710CE373DFE144C
+:10BF5000E9A95E7B5F1EC2AFFAF1BDBCECEC7B4C85
+:10BF60007147940D1C3E958F3F39DB6FFB5EE133CB
+:10BF70001BD7110D9FB9831D7C5F11F4E4A21D2016
+:10BF8000CBC7AA3DF514572CF70CC3751CF59A388E
+:10BF9000FF7AED8161E437F294CE8BF0FFF40C363A
+:10BFA000D0FAE7A2DE443FE8427D20D6EF159E1F7F
+:10BFB000CCED3DA213DC672EB0D2BEE0988EDFA39D
+:10BFC000105DDFEEE2FBA3CFE2DC879C28BE57DCEE
+:10BFD00054FFEC0BD05FEF5A0B75DDEB1D41F658AB
+:10BFE0006F13401768BAF754D339FEDDE41620A169
+:10BFF00038EF2DF82FF8FE6CF79D5FFC06EA7FB056
+:10C00000D6EA261DE21845F05B282A2F4E3593FD0F
+:10C01000B4784E6E05EAC55B44BCF056BB9A4E61DF
+:10C020004335D9E8807E96DB0A370304D9CAB46A5F
+:10C0300023FE64534DCE1D9BF1B97AE87623F25866
+:10C04000DD987D9BD18CAD07162E25F9177AA7199F
+:10C05000E675DB3ABD8BEFE7E4F9DADA6F94F722A5
+:10C06000E9F798C84F0220D07E35C9A568F649493E
+:10C07000824E1F182CE23163D9D84BDA78D74EE4C0
+:10C08000A3B38BDF191E271EA1FD2EECC7DF8A7B11
+:10C090009EA3EF4F91E33A5C7CFF75CC089489F640
+:10C0A000E442AE07C6CDFF7C4329AC7F5CB7434773
+:10C0B000790DB7D5BF8078B8D025F068605DC84FDE
+:10C0C00037F9977CF01B424C9AE6DCF095F4A5BB5F
+:10C0D000C75119A92F4B42DECA487D39A1AFAD1215
+:10C0E000F5A2D48FC1E61A218F9B488E1E6C5E4745
+:10C0F000E5C3CD7E7A1E696E15F2B88DBEFFAA79B2
+:10C10000A790C701218FF7D2FBEEE6F9F47CADD9F9
+:10C1100047CF85A9BED7116E328E3BD7ECA3BCDCCE
+:10C12000430F9B18C6F12E749B288F0338E2B1474A
+:10C13000D2304FC944E744A3F395A2E57C3F3D7458
+:10C140000EB8B7E56DE4F7FE3C23B41707C7A7A701
+:10C15000A3CC6547B9F4F1E0F324878EBA5C76B4DA
+:10C16000A74F3E2ECA1E97DD00E53F0DEE25FD715F
+:10C17000D4E7B29BA0FCC9E3BDFCBBDF65B740F9C7
+:10C18000D3C17DFC7B8051D0FFECE02F488E9533EE
+:10C19000E520F247A5397F2AA80BD0D7E507912FD4
+:10C1A000A6672E998A7CB160B08BE872A66BFD41C0
+:10C1B0002CCF1AD9AEE215151E5BE1466C5791568D
+:10C1C000AD62BBA939776CC476D3866E5723DBCDBD
+:10C1D00018B36F23966F70B7AB689F2E4039561A0D
+:10C1E000EE4796E57729A7653EDDD5DD5ED207E30C
+:10C1F000BABCA40F245C2AE6566F42FF676397E23D
+:10C20000C0DFA5A998ABF4273360EE6203DE930A82
+:10C21000F2FAFF3DAE77AC87753662F91A2AB7ADF0
+:10C22000FF06FAED7F00F6E231E800800000000032
+:10C230001F8B08000000000000FFD53C097854E582
+:10C24000B5E7CE9D2D64924C360842E2649924965F
+:10C250002C43B6261064480CEE3001F944651910E1
+:10C26000C2164804EB17AB7E191A17E0698D6BD123
+:10C27000AA6FC4B5AFB6E461D458091DAA52D287DB
+:10C280003A5510B47974A488F0999011DC78D2C72B
+:10C290003BE7FCF766E6CE248014FDBE078693FFDD
+:10C2A000FEFBD9CFF9FF5F008053F8B3027F603403
+:10C2B000FE38253D8C046804F167BFD16DB295034B
+:10C2C000AC34078CA0A32F41A3AB1060AF0E9676C1
+:10C2D0001400A424C3FC7A0B968DB0740B96E75D12
+:10C2E0006803480568DABA206E8185DABBE36660C8
+:10C2F000FB4517E2AF38CE52056E54E0930AD49B4B
+:10C300009C89344F9A4DD21FCAC76F8550784A0610
+:10C31000E8B79A3DBA048044937BAC0DC7ED9BFB14
+:10C320004E835887AF88D6316CBD1EEBE300326C6C
+:10C33000561E1FCA8219545E09ED46C846B8F5CF8D
+:10C34000FBA422DA97C52723844E435F205FECF9D4
+:10C350005416FE63063D54E07AE9036E6999D7707E
+:10C36000206056EAF1673974EC706622DE5ED47E96
+:10C370006F04BF18BF43FB7D15E28DBE377569BFE3
+:10C3800003545B0F8D433002CBB8DFD912FE5E85BC
+:10C39000FF0D8F874967C0C3A4A1F010B51FF01A25
+:10C3A000418EDED70ACB6EA673E4BEC09DCAFCD117
+:10C3B000088121F7A7F245F4FEDA05FEF502FF2514
+:10C3C00036E7745A5FDDFC389053008E6D35794D39
+:10C3D00099DCFFA93D2944179375832D9A3E5B5B39
+:10C3E0006783DE00B0ADD5CDD0D7BA14F476803FE8
+:10C3F000B53673F9ADD6162EEF68F530DCD9BA8EA6
+:10C40000E15F5ADBB97E57EB462EBFDBEA65E86F8A
+:10C410007D91BF5F3B7F6586DB124DFFD5C9CE4561
+:10C42000C48F9E7BAA13993EB8F753C8AB9E1AC817
+:10C430006FB644C30183659D94C0658F11F7E1D940
+:10C4400016E36DC37DFD738CBB89C619A8097EAD4B
+:10C45000437C434A80F1D030D2BD9ABE4B461C3A51
+:10C460008966F5E412FE0EEB3CBF0764D9569BD3F8
+:10C47000A5473E381A8F551700DC82650FCEF3783A
+:10C48000AAAB85FA417EC048E39CA23F93717C0928
+:10C490006677F03A10A21C0EC408E8B1492C8FD17F
+:10C4A00050C8DD40BA9FF960E0E91319B68233CB7A
+:10C4B000C570F8A893AB039E32A46765ACC384D55E
+:10C4C0007D12F8A412845346D6008ED3976ED413EF
+:10C4D0009C14445650C7C39FC9DF226386F1CB1416
+:10C4E00048D4946BCDA335EDEBAC999AFABEF45CCD
+:10C4F0001EFFD2B48B34EDFA46579AC5BC532F2396
+:10C50000D865746F5C80740956991C9BB0FEBD9809
+:10C51000F822280698161BBF89E07B31195E6A371E
+:10C52000EDC0C914C07D4E937D238B105597DBC69B
+:10C530006BC7ED995363C37657E65769D721C12579
+:10C54000B4DFAB1D5334DFA7575EAEE9EF32FB9388
+:10C5500008ADF5CE7ACDF7C696AF419F0C30B1E568
+:10C5600024E84B01C6FB3A34E394EEECD2B41FBF8F
+:10C570001B6412EB927D8E3709961F74CAC42A156C
+:10C58000879BDF2458F5A53F83F6014EB059519F94
+:10C590004B8ADC8347023D962729E5CAA0B72D8147
+:10C5A000E87012F2F548BF8930C2216363A9F2BF77
+:10C5B0004E101F4C5220003207F6AB164B80793AD2
+:10C5C0008BD798456A05E51BF5C106C991A6473882
+:10C5D000470E5450F928048A08CA3A979EF86B2AE5
+:10C5E000348FA5B209DC69043F4874BF4F7CDC2F4F
+:10C5F00005DAC4E282C9C4CF753FFF68DE6DAC17AF
+:10C60000621C265CDFEFBAFE914A6BFDBB3FF591E1
+:10C61000376C217E6FB27ECD7852CB8D2DC7197FBE
+:10C620006AB96F2DCC77E192DB0D689F1036FEAFB3
+:10C63000CC760AEDDA3AA25323FCC9B8BA20D41E4C
+:10C640003ABE18C47731EABF7A5AD304C2D7DF5D45
+:10C650004E6C576F1072089E45F54E1CA73E46293A
+:10C66000834FD4A72AEDA1B29ECBE96A7D95686F6E
+:10C6700057C77B58B41FAD9695F12E52CBCDA29CD7
+:10C68000A9CEF7A02817AAE5FF7071394EB43F6113
+:10C690009B55EF2908E9FF53AADD180FE3C96EA0E7
+:10C6A0003D9033C91E48BB1A981FA2ED85B65EB1F6
+:10C6B00017F37F237B8CC5448FCB63DF21B9EE90CA
+:10C6C00080E4BAF17683D38BF37F9ED451B4C61243
+:10C6D000C2DFE7B7087CBB6AE39C32B65FF96ADE6B
+:10C6E00026E223396EF7C885F8DD3A56C77AA74E99
+:10C6F000B63881E87BAFD0FB6AFF48D8D0F2868697
+:10C700009E51F5B2C4F3C16CFCC1F9FAEF1BF5F40C
+:10C7100006C2598E3F9770939929F4DC48D4AD95A1
+:10C72000F8F336EA5933D23D251B9C3A6C9FF21A36
+:10C73000EA67A2F141BFD0C7AFC5F824149C958F1A
+:10C74000BDC9F66FA18C528EF87B2DCF9D97897C49
+:10C750007A34CE9F4B7CDBD0B28DD7758DDDCAE3AA
+:10C76000833558108ECFE2CC28FC979E01FFA53F61
+:10C7700026FE718203A4CF752874B4BEE596B778FF
+:10C78000BFCB95EFAC5F3243EDB82C47978FC639DE
+:10C7900032081F0E854E0774B60A055F5713BEFA9E
+:10C7A00017FB7313B1ECF0F947BAD93EEC2A97881E
+:10C7B000EECD7140743F2AF98BF60E41FF8ED60EF6
+:10C7C000B6CB5B5ABB18BE8473D0BA557CDD108DD6
+:10C7D000DFF967C0EFFC1F13BFA3F401A303FBAD98
+:10C7E000DA073C4E85FF8011C2F44C2BF125E2277D
+:10C7F000A14BE2FA3AB92021A0A98F13FE528E7301
+:10C800003CF1E9CA19BBAA37482179981C0B1D31A4
+:10C8100049CCD70E85AF1DC4D72AFF223F96EA1117
+:10C82000CF6F9DC47E43E037C4BFC0F3A878BA3B46
+:10C830001AAF1B888EA7C1ABB6FE07C66B27FAC717
+:10C84000A43782AFC478376546E3F9770A5E557C32
+:10C850006F53E47F383C6F233CA79E7F3C6FCBB483
+:10C86000F1B891F81ECE3E45D2475DF710725A7E60
+:10C870002E723A2DDBAAF8DFE8771646D3FD6DA2BB
+:10C88000BB5943F79E33C853CF8F294F91788B8480
+:10C890008D12B83A2CD1DF3FCB1C56DF9D173C4E92
+:10C8A0000ACED6F86793BF756BFCB329186169FD92
+:10C8B000D89B34E53AEBAD9AF697A6ADD5D45F6E2A
+:10C8C0005BAFA9BF32FF014DF96AC763117EE6D3A2
+:10C8D0009AFA7AE76F34F5739BB76BEAE7B7F468B7
+:10C8E000EA1778FEAA29AB78DCDA0A1C2F6D6B35C3
+:10C8F0002BF1D3650CAB03FE5A12838B0F07D9DFE4
+:10C90000ACF4B7D7B24BB2AF83FDD1329FAB96C276
+:10C91000AA8A9DCD6F12F4B55A95782D8DE15BAD45
+:10C9200036D6EF3B5AF319EE6C7528F15A25C35DE4
+:10C93000AD4E254E73318CB40BAF66BBA764213D61
+:10C94000A6BDBC4407B880E97FF867C15E5ABC77D2
+:10C95000BC8EE2DC35CA5E8E577FB3FF36E4AFE3B0
+:10C96000CD2607957BB71F31D80AA3F965EEB732FC
+:10C9700038C3F86C6ECB5F0DE467CD450FBA630822
+:10C98000399D9AA5637E20F703502FCC368321056D
+:10C99000F5C1ECD992A30DF8BB079218FADC583F09
+:10C9A0004D0F3E1396EB2D7A9F299E97E632A33FBB
+:10C9B0003D4B2C134C7AF0503DA424739C7E0D7D8E
+:10C9C000B4A13C3865B818BFCF223F1CFB5D6FE9AE
+:10C9D0003090DDBD6EE72FFA6FC37AB8D353CEF136
+:10C9E0003D5C6225FD2D793ED69D1A37BCBC2035B5
+:10C9F000E150185F4F25194EA5F8D1E17752DC7A46
+:10CA000093C1F19C2DBADF05CA7EA7C912FB6FC185
+:10CA1000D74DDE4D52483E717F3B4DB8CF26E201E7
+:10CA2000DA67B3C19757447EF676F6B39B2AD716DA
+:10CA3000119D9A2E913E311585E29DA6962FD98F94
+:10CA40008FD4CF91F04CF190C36F65FEDBDFBA93CA
+:10CA5000F9458D8B7A5B7D5C2E0BB86AC3E3A339F5
+:10CA600093FF4DA6B8A7EA4B11FF4C3CE9DCFB5302
+:10CA7000DC77A0D5FF2FE517D4BC829A6788CC5B02
+:10CA8000A87A64DEAD75096EDCEF9A2C5106F3943A
+:10CA900074A6A35E4055DFDE9A156597EFC83ABDD0
+:10CAA0007ED6D6FFC0FAF96CF9BF314DD8D548BE55
+:10CAB000DF37E30503AD53E5EF48FE9F437D70FE8E
+:10CAC000394D92D7837A7AF69276C344E9DCF97DC0
+:10CAD000B9E5A0888B23EDC2F7B60736A69B5C2B81
+:10CAE000737C61926F72501E44A5434734DD3ACF88
+:10CAF00040B7CE1F936ED176F1E0BC73B38BA0F13B
+:10CB0000CFDFCB8AF2273EC83ABD1FA9ADFF81F720
+:10CB10006D1D6B63B87244EF3C5927EA457C620196
+:10CB20001DF2EF8057E6B87469667B3CC533501937
+:10CB30008C277DB7AC5B06F20F41EFD48F46FE5CCD
+:10CB4000A2F0671FF83E247E5C05F77E4109982518
+:10CB5000D54BAE223DB7F40943084FFCAF93F32702
+:10CB6000AB947ECB2D9D46DAEFF267B5EDD4711A0A
+:10CB70005F8AC81F575FFA19B0DDF073DE6F55A7E3
+:10CB8000B6DF77597129876259164B08EF67D2A72C
+:10CB900047C9AE1BC2CA275B39BF203FF3E0039EE3
+:10CBA000B121FAC46447F1715CF6E9F9585BFF23DF
+:10CBB000F3B11CF7AC91E8F97DF978BFDD9945EB4D
+:10CBC00056F5F3A0DE79C3C47A67A0DC26F2A43759
+:10CBD000FDAE2D9EF8E40438881D162AF9D2856A28
+:10CBE000BE749D365F3AB9CFC779B94907BD6D713B
+:10CBF00048F789BD1ECEDB55ED76B759B0FCD35D45
+:10CC00004E99FCA3F16FB9645AB7EADFA8FE4E480B
+:10CC10008FE5B0BEE3BC6BF6D9EB3BD52EAAF63060
+:10CC2000D20E5606DB6BC9FE4DF8B6E34D82E72BFC
+:10CC3000AF1E69F7DE8B137AE2A8C157BE97FC8C52
+:10CC4000D7631CCF41F4FAAFCB167EC64CCF02039C
+:10CC5000CB1F091FCADB0C456EAE4F765F974DF5B3
+:10CC60008ABDD0999D06B2A37572DF23D7125FF9F2
+:10CC700065CE1BDE7CC707BFFFB5EDCCF98526EB83
+:10CC800071F63F868B339A74E0A6F8A2A4D6564A72
+:10CC90007E0CC56D944754F38A91ED9FB0D7ACC814
+:10CCA000E63C57B5DF49EBD928D6331CBD9A5ABEAE
+:10CCB000D0E431879BBFA9BBDCBA304C3E5ECA16BC
+:10CCC000F12ED2DB7AC81CA2F7D9F2C5FFB7F865FE
+:10CCD0009A0C1E09ED6CA1E415FE2F083F780EF8A2
+:10CCE00019CE8320433758F97C6A2138182E021751
+:10CCF000C37CBBDB4B7C3360088E24BEEA7FF5BB74
+:10CD000002E29BFE8B27B657C1F93B5F8AF4FF0610
+:10CD1000C6DB78FE8157BEDB43FC397087E1ACF49B
+:10CD2000C6EA646727F151E479CBBB53643ED7016F
+:10CD3000FD7A968B7AABE80397A4721BEBD84CE68E
+:10CD40008B90DE1CF5B4AA371760BFC24F74ACD706
+:10CD50006099E4B563D3AE808E45AC7071A657A6DA
+:10CD600072A7A82F5C99E895B05C581523EA6F4A22
+:10CD7000F44226C5430196CBF900AC0F1780D08B47
+:10CD8000378293F78991419684FD176F3597703EEE
+:10CD9000160239A4FF8B288E1A224EB7E608792F87
+:10CDA000CE12FABEB8469B17F9305BC91BDB6B4A43
+:10CDB000721056E738F7121D8B93FC1B1E2AA37CBA
+:10CDC000900E36A17C7D56752B9F77AAFD1AED3506
+:10CDD000BD84BFCD1270BCE2E936799F13E78C2386
+:10CDE000C3CFCDF2EDB507A8DD115A7BF9F078C5B8
+:10CDF0007E1CF747CB9587D7574CB11BE7FBF14318
+:10CE000025CFCBE5FF79E6EBFA3B0BF84CC1437E2F
+:10CE100072A3DD7D9CD76F04B0D0FA9F14711440CB
+:10CE20007306E547973C65D2919FF1119A63C80359
+:10CE3000F81BC6DD04FF1BE367827FC7F899E02774
+:10CE4000183F13FC07C6CF04177F3B1E8322808D3B
+:10CE5000394E4B4E79E81C3072BD861C81CFC1F92A
+:10CE6000BB8D3C7F9DDDCDF81DA4F7EBE0A573994C
+:10CE7000CD89C10B924EC36F03DDDFF0F9E9707805
+:10CE800051CF2523EBBF53E85AD4A967FB5FD415D4
+:10CE9000886F086B77418E91EB0B5F39184FE31F5A
+:10CEA000B50EE2D729E196A7E944F982672D330848
+:10CEB000BF75766709ED1BE53C83F651D4F5C18358
+:10CEC00013CB787CAB64A375041FE5B821621F9176
+:10CED0007850F7B539D1BF81FA6F7E258B76827A8B
+:10CEE0000784DC101F4943ED772DF3CF7453B0CC8A
+:10CEF0008AEB9D7E4A6E1E0AFF75F6298CE77754F1
+:10CF00007E53CFC715FE52E976AEF21D391E906BE7
+:10CF1000847EE76AD2A536B24B27E3C92FAC57EE21
+:10CF2000197475E6BC47FBF4EC94C16E633ED6C839
+:10CF3000DF62855F5458D86D7411BD36771FCA59AA
+:10CF40006461FAE42CC6F6B372EC9ABC6761D589C9
+:10CF5000C71F4AE1F6569AEA3A78BACE8AE3DF600A
+:10CF6000DEFE366D69AEF593BA442CCF4F93761042
+:10CF70005C60CB9C9A64A3E57A79FD37E64FD94192
+:10CF8000227595A39EFDB929A464C2EC43AD3996E0
+:10CF90000E1F07CB75D6644DF9D2B4319AF697DBE4
+:10CFA000B235F557E68FD3D4ABF35EE528D5B42B75
+:10CFB0004E0A66515C87FB60B980E764AF5DA27D75
+:10CFC000EFBE621C96A73D3FCB416ECA66A57EDAD6
+:10CFD000965A2FD16300F1694487EA70E5FA471F3A
+:10CFE000A2C122E286C6EE6776386DE710370C13D1
+:10CFF0002FAC00718E3F5CDC10192FA0FE7C90F4EA
+:10D0000067F1ABD758DB70DCCD55272EB0E13EEF92
+:10D01000CCC13882EC8D12470CC73F837222D904F1
+:10D02000FFF4C8F0DC10FC03F00B851F059CF63EF6
+:10D03000FA3305DF5FBF7D4AFA8DF3071EC5EF5750
+:10D040006044BEAFD8E8786F0DE5A7DE9181CEF9D8
+:10D05000E124AE03EB1BE87739C4F7B0E8E9BB463F
+:10D06000A7F0770FB9A6AB94FCDF1F7314BFAA71AA
+:10D07000FB5DA3CB42F570F3279AF670BB74B7A69D
+:10D080007C67A6B67CEF94BBC3FB0FE797356C5C5F
+:10D090006074A39C363C2C39BD43E88BC1F5A428B1
+:10D0A000FAA17B09EBDB43DB97196D71D1ED57E1F9
+:10D0B0007894B76C18C6DEAA7AEA3A199A87AA7FDA
+:10D0C000479DCF717EE7FB08714FF6CDF39AB0C351
+:10D0D0001F25B88DE17CB22F479C7BF43FF6C01D25
+:10D0E0005FD379EEEB22BEEA4F14F6A3A8F3339D8B
+:10D0F0000E61F108C15F45D6808EECD2C0D2580FC8
+:10D10000A09C352D8BF3E88AC98F087E681E4F5E80
+:10D11000C72D0F9A91CE1FEB741ABB3C40C11696D7
+:10D12000FB9EFDD98C3BE9F702712FE97CEDB32F13
+:10D1300007847DAD117A631EF19F62B7005556D307
+:10D140005D3068C748CF105EA89C6BBFF5FD87C9EE
+:10D15000CFEF117A83F20A37B05FE0B468F30D1DA8
+:10D160002CE7F8BB2DFC3ED759EB8FB7DA8D96F341
+:10D17000A84746D8B5798721F4C5FB57223D9B5E69
+:10D1800097F95ED0B1ADF60408D31F91786CDA2818
+:10D19000B39CABE5A35BE5CBBC6C0F8319F585D1E4
+:10D1A000F806A783E57FB555CCB77AD23733C84E9A
+:10D1B000AFEED68B4B2FC3CDB34E065BD83C9BB79F
+:10D1C0009996925D53D73F6055F449F75749530AF2
+:10D1D000045C3B847D45BFC090427E41BDC4F1EC00
+:10D1E0009EEE513584A73D12F86C253CC435665C33
+:10D1F000DF4C311C7DB7505E14D2F2F99EA51AD7D0
+:10D20000AAF1ECACEE5976F2633FEC5CB807290763
+:10D2100093ECD9CC4FD78287FDEE3D89AE74CA938B
+:10D220004C53EE3FEC490CF691BFBD6752AC44F74E
+:10D230001970FC3B697C755F7B0CAEF466DE9792DF
+:10D240002F75FE443E157BF671A2AA67EBE4DBA7BF
+:10D250005C49E7F773C04AF1EC7459F8D5F04721FF
+:10D26000CFAA5E6D92FC496CAAED33A6DB114FA3E9
+:10D270005A7EA9E47DDB35F700CFD6AF1E8CA35FC5
+:10D2800094987F563944BCB1AAFAF347AEC5F95712
+:10D2900061BC4FFEDDC2AEEDFB087F91F1FD607C0D
+:10D2A000F52FE67BA3E333D732DADFCD771CDF73CC
+:10D2B0002D44C769837181EA5F3E17CBE7D6A85832
+:10D2C000857C28FC7A645BEEDE35587FE42F0666A9
+:10D2D000D73727FDEAE8AD58BEF9B958C6F391240F
+:10D2E000F0901D39B229CFEBC1064B74C15EB26F0D
+:10D2F000B0258ECF693E7B32EFB72F517EF2B776E5
+:10D30000F643487E6CE8C27C46F78FE8FBCBA3B9B6
+:10D310001FB8C5BC0D8A5CCA2F14DE5F4DF52F24E3
+:10D32000737E42A5DFE127639C14AC7D05BE222BF2
+:10D33000B2DEE792E710DD5B5CA17B69BF847CF91C
+:10D34000D508F706DAF7F2C7FFF3C389B89FDA17F3
+:10D35000AEFE5515AE6FD907A940E384E83AB4DFB5
+:10D36000706C6BB6907F053F2B5E8CF11E0CD32743
+:10D370002B3B1235E5A6AED1DE83617A68F09E7252
+:10D38000A3C4E7048D8A5CED37BADBED94D7A5FB27
+:10D39000A94C3F711FB584CEAB08FFF79918FF91D8
+:10D3A0007CF6A25D396756F33CC9604E23B9750B14
+:10D3B000FC0DDC97B789E2319F3D49F13B82B933DF
+:10D3C0000AC3F9B377D51B9CE731897B8F31439F23
+:10D3D000EB77DA13B97D83F94B4D9E6955CB094D37
+:10D3E000FE675501B01F50D2662BBD89CE8714BA97
+:10D3F000DC9FEE7A8DF1DEF1C0ABBB189F4FDCF203
+:10D4000031CDBBD3C2F4835D4A3C16116F3598BF52
+:10D4100050E4EF698D7F7EE8B1BD4594FF38F4CAD2
+:10D42000B822CAD32E94FD877E9DC9F79CF6DF866D
+:10D4300070CBCEF7392F1EB9DEA87B0C92D0438D6E
+:10D44000B48F64BAFFE37AC7CE722EF4C3810D8520
+:10D450008C3F351F3D7064E878505DA73ABEBA3EF8
+:10D46000757CB5DDDFEC225FD06FF41791FD5F4175
+:10D47000E73061FBEA8FF717255AE8BB55F81349E7
+:10D48000580EE3B77FF5BC2AF27C6AF05C56C947B8
+:10D49000EDD3ADFD9911F9AFAFE321833B5CEF7E96
+:10D4A000CF732A75BDEAFDDA7EAB85FD9B937625A9
+:10D4B0001F9F0EE9D40EEB1D3EF2BFB7981CE4C7C8
+:10D4C000279A5C908BF86934FAF8FE9ADA2FD1E447
+:10D4D000E6EF9179F9814423D0BDE58154E5FCF76D
+:10D4E0002B60BD4271E8169CB7AC56D7BCC512D2B2
+:10D4F00087AAFE2C1B87DF0BE81EA93EE42720DF4E
+:10D5000094156BDB87F6A32DFF7BAEA06359B26E3B
+:10D51000C838B92457C8651B74C8429E851D9DA88C
+:10D52000E01D0DBF1CEED7AC52F4FC40BCD9430744
+:10D53000BB13B78A7BAB13F5BEED04510B404B1206
+:10D540005D99F489F1BAB4FA9C6CC81CB6CBE3D8E7
+:10D550002E4F50C87DB7D4CCF75B43F75CFD32C18A
+:10D560008B21C8D009563D412403C34BC0C5702A46
+:10D570003433BC0CDA195E011D0CAF023F43F8894D
+:10D58000AF0DD81EDC6E65FFE9F2253AB2CB65D748
+:10D590000EED97CF52F0353C3E50CB579C3B3EA60C
+:10D5A0002AF77287C5CBD87CE67B152F26E24FEC95
+:10D5B0001703DE34829320C0E34C2646CEA678DDE6
+:10D5C000C6F77E6BC1C9E5BAB3C44765C0AD77176E
+:10D5D0000C8197DAA1F9649EC22703B9C0F851E91A
+:10D5E000F548AE8DCB2ADD30504C237B104D4FC813
+:10D5F000A07596C5D61CA7A722B73F5F36538F7A72
+:10D60000B4ACB4660DA9905FE64E15E589352FD30D
+:10D61000517DFBF3978A72714DA9C1815EE8DACB27
+:10D62000665E82FAD9ADDC2737A311A07B6372B6A0
+:10D630003817762BF7CA4D72E65ABA2F66BA0D58CC
+:10D64000DFB86300FCECD722B791BCB8451C7BB3B4
+:10D6500055D0AF3AD67D4B2ED933B32FDE8674B872
+:10D66000796DDD28B29BF718C5F89FA4DAC6BD8195
+:10D67000F83299C4BD5675BF58EF89C17240B2AD3A
+:10D6800069C90CAD4B5DC759CC7BD7E9E6CD4F7767
+:10D690006F203D023607C7156314FBBE65CBC4344B
+:10D6A000F430701D565E47202E774D0B56DD91EEFF
+:10D6B0007A84C61B88137CF808D1297578E8CB7565
+:10D6C0003E943BC4F781B5DFBCEA23BDF4292E04A8
+:10D6D000C7F94DAEFB715A47932E90518AF4FB4522
+:10D6E0002C7A000521BE96909873100F6D4EF01A9B
+:10D6F000595E947736CAF9992A17038B713CC44F47
+:10D7000099CB558BEE2254CC6E7E9360A5BBBD1693
+:10D710006B689E17683D4D72B081F8E468E207C6F9
+:10D720004F596EC70AFE54F459F7B69EDBC688A25D
+:10D730000BC2E4B269DB89AFFF86746F3A66715041
+:10D74000F3903C3EB6469CE75A34FA4695D3095DC1
+:10D75000263E389CB8F5A2C5D46ED207BDD9A4B771
+:10D7600027F706DAC87D1EE8DE3B46C889EAD77F80
+:10D77000239D8B7DF9CC8CFC914010F9235E9C831A
+:10D7800073FCF48A38075FADE43DA9ECE17D8B784A
+:10D79000548D3B57F6BC2DDE8579F06F05BD2B12FD
+:10D7A0007F963E71E355C46F91EF8BD478B449698D
+:10D7B000B7A2D77B37ED27F2BD5113C5A345C3BF31
+:10D7C000376A7AA296E3D1C8F746BDB94AFE4AB194
+:10D7D0008FA0F8A14B9436B43F0BC78746AF09F72B
+:10D7E000B6FAC9350E2B95D32D0ED6C7573D0EE18F
+:10D7F000EDE18964E619559E97AD93D8BF56F15A6D
+:10D80000FCBCC949EB287E7E14FBCDE8EF8B7BE99D
+:10D810004A3E91DE12D07B83CD89C12CBA67BAB95A
+:10D820003BDF41FEF81F5A9DF00F43687D6A3C5074
+:10D8300027BF544BEF878E2DC2380B3FADEE79A634
+:10D84000CD8CE5D5EBE95510A584F313C8AF2ADFDD
+:10D85000298397C601EF43D5083B153937A5E9C0A1
+:10D8600016868F18DB08B00D910F3029F48BCD4F41
+:10D87000D2D4C7392ED0F44FA8CCD2D4B7C588F7AC
+:10D8800032E071FA0B2A42EF48129D3FD1F4830037
+:10D89000FEAD08BD17B9277EEA4E7E4FE26FE03C31
+:10D8A00045F265259AF62679AB4CFC5DFDA55E43F5
+:10D8B000CF9F52A61BF156B91BFD1C9C67429FB619
+:10D8C0003E26E001EA17B35BAFC94B986CDAF285EC
+:10D8D000794A9E622C8CD5E42906F12EF8FED86197
+:10D8E0001DF34505E4FCAABA8CF06C00AF2D1A6F4D
+:10D8F000C740F85DC7C65A1CF4966A42CFCB32C9FE
+:10D9000041AA4B8BFF51B3B5F81FEDD6E27BCC5249
+:10D910002DBED39BB5F8BEB0458BD74C8F166FD9B3
+:10D92000EB2668DADBDB6B34E5BC8D5768DA5FE445
+:10D930009DA1298F7BF17A4DFBC28E859AFAE2AECA
+:10D94000E59A7A95CF86E383F1BED511FCA603DD77
+:10D9500069F8A074E7CF35F3FD50F49F9FA7E80561
+:10D9600085FED72B76E5DDF8C3F792B84E8B157A96
+:10D970007030DF506DE078EE3D5B726D1CE905C5DF
+:10D98000DEB9147B07394F89B255941D7E71BFA251
+:10D99000649FAB36DE46F72CC4FD8A8AC3EDB50919
+:10D9A000D43EE21DD6F44A4973DE1DF92E6BA667FC
+:10D9B000AD9C20D1BD44713F31F21E84FA3EABDEF6
+:10D9C00019A339271FEEBD969A5FC278018C142FD8
+:10D9D000E8CCFC3E31DA1F726C94D95F73B3FFF66A
+:10D9E00067C9CD79A76BCCFE0CE2EFECB1EEF5790F
+:10D9F00088B7A33A878DFD3DE5FDD6006D8CDF2FFE
+:10DA0000F5CCA43CE90086BB94D7D4DFB36326BD34
+:10DA10005BC4E55B031522ACA63F8FE6B91FA4717A
+:10DA20000E48D6BB4BB1EFBB133ECF207B66A27333
+:10DA3000FE123EFF7E382FFCFC7B14EE0FF56D408E
+:10DA400067F3F079EECF258E533EA7C1AAC2E477E3
+:10DA50009D41794F2AE2B6B90ABED4B86D8E32FF25
+:10DA6000011C6229EAF3B95D7F66BCAC48EB53E266
+:10DA7000BD668715C7BF71ACA584EF7B394B1D22EE
+:10DA8000DE57E3B831F2F7B1B367BA87B522ED8854
+:10DA9000269E86979287CC5746E6C542FB16E31F23
+:10DAA000581FCB76E8C0FA74CE3F86C63FCAF985C8
+:10DAB000B9CDDAFBDDF35B3ED2F0DF02CF279AFA75
+:10DAC000404AD03006F71F7875F4D41B107FFDAFA5
+:10DAD000982A289E45BAF5E49587C60FDC97778982
+:10DAE000F01BCEB4CFCF791DBDCAFD5A759FFB5B2D
+:10DAF000F77139D01A88B8EFE4D1C4BF2A34FE09CF
+:10DB0000F2C98F0E4A231C43E57366E78B38A95789
+:10DB10007977DAABBC3BED55DE89F62AEF427B958F
+:10DB200077A1EABBDD5E099C74BF648EE47A6A81EA
+:10DB3000C4EF760FD13E9B96078BE85D635371600F
+:10DB40009E24F3BBDD23F47D8877BB459295F46971
+:10DB5000EA35F46EF7F008CF51B2D8D9F989D75029
+:10DB6000BC70D828E4A3F4C56F66D27BBDC753DD73
+:10DB7000C789BF3F95641FF3F3EB129F2B8333607C
+:10DB80009C7116EF7ABFCB13E73427F3C4B9890A27
+:10DB900047E60BBD564AB09CE8726F2EBFBBDA68F1
+:10DBA000E27757389F5317761F22F27D5CC91F4DCD
+:10DBB0003ED21F6ADE27215F9C37D3BB395A67CA22
+:10DBC000FD26F16E2EE0CFA07776740FCA45F2BD28
+:10DBD0001B9CE21D5EDEA6F0F73009F9CA3DBD458B
+:10DBE000A079A7B7B2E7C07ED227AFE5B993F353C8
+:10DBF00043EFC756C66F677FAF20DFC6F3E27A797F
+:10DC0000FFA817EE24FA9CC77C61567E79F4FFD7F3
+:10DC10006038BCF52FF63F5A90197AF716F6DEAD4C
+:10DC2000203F2CAFA7AE3F34CEE9E542CD7BA9E53E
+:10DC3000438FDD934B72867411F948599A3F63887C
+:10DC4000FED3F305FDEF4F774DA0F997378BBC60FE
+:10DC5000886FDA6FF998E8DC6319F23EBFDA3F7239
+:10DC60009F2BB7F5303E709FF3687F61FBBC8CF053
+:10DC7000A5EEB3BF7BEFA305B673DFDFF77D776E4D
+:10DC80001A81716DD2507976B43E617E9949ED3F2B
+:10DC900056AFED8F0E39E5B1BB48DED16FE954E2E6
+:10DCA0001EB2CBC417AA5DEE54E22029B083ED0268
+:10DCB000CD4B7271B7E461FBA8E63BDA24B47F94E4
+:10DCC0005770AF617B215F6871105F7722EFF94970
+:10DCD0001EF4CE58CE7347C4D73F8B75DF4478BC53
+:10DCE000F9AF35A328FEDEF2972B94384ED8AB72ED
+:10DCF000853FCB697EDA474102F36D99B2BE0A7364
+:10DD000033FBC955E091455E43C993ACDFC1F1DFF8
+:10DD1000FF011A14AFAAD043000000000000000069
+:10DD20001F8B08000000000000FFFB51CFC0F00374
+:10DD30008A739418187A351818366B32306868313F
+:10DD400030883120E46885AF7153A69F9B9581810F
+:10DD50001788F981581088D73331306C60225EFF04
+:10DD6000115104FB9E2003C351207F1990EE1466CD
+:10DD7000605805641F03E22F40BE801003830C101F
+:10DD8000FF1561603005D2C1406C03C4C745F19BEB
+:10DD90007F82807CBC082ABF1B8D9F278C5FFF255C
+:10DDA00011FCF20F08C863C33216E4C74722057A94
+:10DDB00007023729A2F28FCA33303C546060D05139
+:10DDC00082F09B91E4ED8062C7E421EC2992C0B817
+:10DDD00007CAB5286237772A50FE0450CE4B8934E3
+:10DDE000F7DCD341E5AF3484D000BC3E14E4A80393
+:10DDF00000000000000000001F8B08000000000071
+:10DE000000FFE57D0B7C54C5B9F89C3DE7EC6E92B4
+:10DE1000DDCD262121BCC22601440DB8400CA04115
+:10DE2000370F5294A8E1A1A2226C782421EF22F6A8
+:10DE3000621FBFDDF088C4521B1FC5D48B7651B062
+:10DE4000D18B3640D058175C9E458B6DE845A0D5E8
+:10DE50007A13405E06B240A5B645FDCFF7CD9CDDF6
+:10DE6000734E36266AEFFFF6FEFFDB9F1DE6CCCC35
+:10DE70003733DF7CF3BDE69B8964BE91D88713F20C
+:10DE800025FC6E25E451891092184E9B3C93C69F49
+:10DE90009409B1ED7E24EA3B99840C9E6B7046D1C7
+:10DEA000A25F08644E4B0621C9658D7546FA3D791F
+:10DEB000917DBCE808C319987CE4BABD09840C7252
+:10DEC000D3F66682BF2FE97F3FB737C69174C87912
+:10DED00085A231E1FA4A9ABC48FA7B87AABE9B1414
+:10DEE00075A6DD48FBFB51FD20B785901FC3784622
+:10DEF00042A9CB40B2E8B8785D6F2EFD3F3A0EAF35
+:10DF0000CDE85B2910221A1CB1442424262348A002
+:10DF10009DBE9F673CEDD74908A736AAC84AE74986
+:10DF2000C8B49608F57289807888CD76257BE97823
+:10DF3000577D2EE2BC570D22A49DD62792D34E6862
+:10DF40003A95C461BDC72D2306427ED5AE3F120768
+:10DF5000851B9B19245E15DC060F210E13C5AFC768
+:10DF60008CE92A8F9DA7C9C4710D21AB3D0E4C577A
+:10DF7000794663FAD8D027DB7306D0F90C32D8E99A
+:10DF800048488363A6DD91118627C72D30E73809FD
+:10DF9000C92629AEC4545A2FD140C84D84DC42F35F
+:10DFA0007523081949EC8450FC3D93BC2CCA9D0193
+:10DFB0007907E6450371C37C6332032E91E22DC6D7
+:10DFC00069CF951CE1EFF81B80DF5F782C15D6C177
+:10DFD0007D1BCCEF19E2ECF0029EDD46E7265A7F6E
+:10DFE000A5EC4C5E4AE18A46DA2E83ADBB94101E46
+:10DFF000DF4CC01FED8FCCC9D5ACD730184722B449
+:10E0000073DC05EB6471B2755A097415611DE6F293
+:10E0100075586577D919FD384924FA11ED5AFAB1C6
+:10E020006468E98F7EB19FBA9EE769BF4D42ED3BC0
+:10E0300053E93CBD4B0CCE4DF4DB60A15100F80A16
+:10E04000BC25C480FD2AF9416552A063B41A9E170D
+:10E05000CBE9F7F60E73CFEF2D06E252E872532AA2
+:10E060007C77C4CEA0E3266647EC4C6BCFF187E902
+:10E0700024D925C940EF0E4C1B0447AC00E37C4774
+:10E08000249B049C7F72A4F6FFD3ED08F1E17A375C
+:10E09000F07554DA513C203D791F8B463C88503452
+:10E0A000390CE7171CCF17AD454F434A48E3685872
+:10E0B0005F9A5F87F463A6792BE69BB0DC1ECA3FAC
+:10E0C0008BE5C9AC3E5D5EBA18BDE3555917DA6EF3
+:10E0D00003C29142705E44389650BF9B303F2094FB
+:10E0E000FF25D61FCAEAF7B71F25EDCE0D9EC2F950
+:10E0F000BF2E3B009FC2DBD6C0AD942E0E6E107CAF
+:10E10000269A0FEC8C41FE757EFD0C9F89E267D745
+:10E1100038930BEA9FDF9883F9BCEDEFDB245A5E5E
+:10E12000B55D94206FD879D6D641F15B636A7FFCE8
+:10E1300066FA3DB85D242F6077D3719F9DE2B448A5
+:10E140003E63F9922896ADDAB06B1EC02D6B339109
+:10E15000280AA7EACDD23B6FA6F9D20332812A550D
+:10E160009BEA8C83697E894F6881FC8A9D1F603F92
+:10E17000DDB9A40CF6F739E05B942F75DBDA93EE8A
+:10E18000A6DFCB7D5B0AA07EF966C1094B5CBE7E33
+:10E19000D78700BFBC551E2152F815CD31C4A1DA76
+:10E1A0002F79DB17DF09E3AD7A472694ED91B2AB07
+:10E1B0000F199118A44623E0B56AD31346E09BE7F4
+:10E1C0003C07B01F059F552FD37E68BBEAD70427B5
+:10E1D0004CADDAC0F8CD8537A3E6BC688179D51996
+:10E1E0004741FB371F3542BD525FF1EB510E18DF3F
+:10E1F0000663018C73FD0663898A6F5634FF5633BC
+:10E20000AE534DE903DD19BDAFE739CEB7957C3983
+:10E21000154048DF92CF3843C5879E33C421FD5750
+:10E22000348BC411811F78DFE7FB608795F103BE53
+:10E230005E4BEDC01AC2EB75C9CED74F0A66CD88CA
+:10E24000C0E71EE7F2A391CB8F27417ED0F4692E61
+:10E250003FD671F9D1E471E2F7673D93305DEF711C
+:10E2600061FABC671AA63E4F11D67BC13307D38D26
+:10E270001E377E7FC9538669B3A716BFBFE2598E8A
+:10E28000E9668F17BFBFE65983698BA711D3AD9E8F
+:10E29000264C5B3D3EACF7BAA719D3364F0B7EFF39
+:10E2A000B5A70D53BF2780E94E585F9A063CED98FD
+:10E2B000EEF61CC374AFA703DBEDF79CC1742DC74A
+:10E2C000BB2D9BE448146F36174139185FE8CA919B
+:10E2D000693EBE88E593E67A738C349FE4A6798A1A
+:10E2E000C7C195811C13CD0FAE65E5293F24B966E2
+:10E2F0009A4FF1B2F2B4B5AEDC289A4F6B64E5A345
+:10E30000D67B73A3697E948F955FB739901B43F3D7
+:10E31000D7B5B0F2B17E9267A1F9B101961F7FD057
+:10E320009567A5F9F1ED2C9FF5A137CF46F3591D5F
+:10E33000ACFD4D5D81BC589ABF29C8CA6FB94AF27D
+:10E34000ED03402E0B98CFB5E4E4C7D17CAE9DE53C
+:10E350000B86164B8E08F4B753EE5808227C86B015
+:10E36000D125517EB3D3D8F110157D64A1F0AA4B0D
+:10E37000A2FC3320934550FEB0F03A96078C641906
+:10E38000943F2ABC8DE5BB650796FF5C38C0F2461A
+:10E390000796FF877008F37B651796EF10FEC4F2AF
+:10E3A000461796FF5E3881F9FDB21BCB3B852E9652
+:10E3B00037BAB1FC49E953573EED2FDFE09E2EDC22
+:10E3C0000872DB5D8672596A49067E59CFF9FF04EF
+:10E3D00040062DAF1F644439B8F3F3AC174581D321
+:10E3E000F600C897BC04FA0585335B48047D82C2F9
+:10E3F00011FB8673CB179334706EF9A24C81F32016
+:10E40000C289EA1F9C9D5FDCA41DCF17E50A9C1200
+:10E410009C97B57FF3BAE5CB6CED78BEAC54E0D4F5
+:10E42000209CB8FE8D27204FD4C009C8A50A9CE5C2
+:10E430000827B17FE37119276BE0B88C4B1438754E
+:10E44000086750FFE0048C376BC763AC50E03C8634
+:10E45000781ED6BF79B94C53B4E3315529709EC2AA
+:10E46000F1A4F60FCE6EAB163FBBAD21FCAC473826
+:10E4700023FB37AF5C9B163FB9B6107E36219C6BF1
+:10E48000FB0767B74D8B9FDDB6107E5E43FC8CE9C2
+:10E49000DFBC7263B5F8C98D0DE1E70D1CCFB8FE86
+:10E4A0008D676FA2163F7B1343F809209C1BFB3737
+:10E4B0009EFC242D7EF29342F87907E14CEE1F9CDE
+:10E4C000BD495AFCEC4D0AE1E70F08674AFFE695A3
+:10E4D0003F508B9FFC8121FC7C807072DCCD4CA96D
+:10E4E000A470ACBDC3D93F4C8B9FFDC342F83989A2
+:10E4F00070A65238E97DC32948D1E2A72025849F20
+:10E50000F308E7B6FEC1D99FA2C5CFFE94107EAE38
+:10E51000209C3BFA37AF82E15AFC140C67F8B955DE
+:10E520001A877286CA4E27D8E7DF199AE31232C1DA
+:10E530004E6279D1EE24A0F7888A3E43DA5D22AD9F
+:10E540006FD91C37FE31A2D66B728D064ACF56AA00
+:10E55000E5A9F59AD849D11A3D2ACE15AFC9274C5D
+:10E560001BACA99F5894A6291F38E73A4DF920F70C
+:10E57000784D7E48D94D9AFAC36A7335F9E1CB6F6D
+:10E58000D7D44FF5CED4E4D3D7DCAFA93FB2718155
+:10E59000A6FC9AA6724DF9B5BEA59AFCF5CDDFD7BB
+:10E5A000D41FD3B242537E43DB639AF27181273585
+:10E5B000F909079ED5D4BFB1FD054DF9C463AF6815
+:10E5C000CA27776CD5E46F3EF36B4DFD29C1DD9A08
+:10E5D000FCAD9FBDABA99F43FE53AB6F9B3FD0D417
+:10E5E0009F6A3FA129FF4EF2273A3D556B1FAFCCE2
+:10E5F00021CCAF3288D9AF01AB11F3C6C11666A7E3
+:10E60000584B1C2729FD18772F740CA0F4033403F2
+:10E610007651CEE0B26B3AE8F7EFDDE4BEC64EBF0E
+:10E620007FCFE8BEC11E41BFA1F4269064481D06FD
+:10E6300048F5E58FCA8CDE73875C1DD549DBD7189A
+:10E6400082A3E268FE2331E73EA0C7F90603EE830A
+:10E650006891D442BD681341BBE9D1D4AC17BDAABF
+:10E66000FDB06618D5338430DC35B23B19F528C3CC
+:10E67000F83AD09BEA87D1790D2664D18A71BBBC68
+:10E680002368FB6125C9E08F3019993F24D4BF91DD
+:10E69000F69F81FD2F81FE6B7AE9DF943649D3BF67
+:10E6A00039A54CD3BFD948FBB713F290E126DEBFA2
+:10E6B00019FD36CB564CC6FE4D2965D8FFA3466AD8
+:10E6C00077A9FB8F0EF5FF8881F6EB3130BBB9C718
+:10E6D000FCD36ED2CE3FA55C3B7F239BFF4A432EEB
+:10E6E000EF3F1AE7BF6A450E9B7F4A399BBF89C13E
+:10E6F0000DF56F0BE1BF01FAFF692FFD9BD2B3B59A
+:10E70000F31F5EA99DBF89F5FF94E176DEBF05FB8F
+:10E710007F7AC56D6CFEC32BB17FA3C9ED04FA31BE
+:10E720000E89AEF5D1FEC9506A250D0472A1FD40D7
+:10E730003A3A1EFD08771AD2701CDF8B66F47625F4
+:10E740009AD21BF2332FB3C37D947352BBAA9AD3D0
+:10E750007AC5E61C23F03D2C4F2264311FEAA23615
+:10E7600011E99B3C6DF28DA4E3BDD0267A21BFE870
+:10E77000E9293EE0AF352632BF08DA492400DF3F01
+:10E78000FED99817D4F3D2A78B1BE55391FC45DE35
+:10E790005C32BA968EEF0210812A7F9CDA71601883
+:10E7A0007F48ED1E42ED9F1332EBEF236AEF41BE2F
+:10E7B00083DA7B6838933AE657F3BADE1F41C75FC6
+:10E7C00044949F0BE7792F6E290A4F62FBF7F85AA2
+:10E7D000C107EB317F790C457E783CC5DE044DBE28
+:10E7E000C6C4EA076F137C2F0808C30DF899C1E16E
+:10E7F00011182FCDCFB1B3364777DEB15FB0D17DE1
+:10E80000B466085D8B309C59C4250FA4EDEF5E56AD
+:10E810002C836BA75D1086819FB066A14C02683780
+:10E820007B134906270E3ADEFBED0CFE0C977C525B
+:10E83000ED479B239B5D45743C738A451CFFAC6987
+:10E84000DAF23FED8C7119C6D274CD53D8CFDD45C5
+:10E85000DAF27BE768F3F7B9B5792A576590AB0F21
+:10E8600094E9BF53B42481DF31F41B00E37C90E3CF
+:10E87000E1C15AD9AB59576A761B95727084B809B1
+:10E88000CE0BDB8B3DEBCF5FAECD177BB5F9856B48
+:10E8900074F039DD9CE2EB7F1CE883A6A7813E285B
+:10E8A0003E4F72FA08F3552D7DDC139A06A30F65CF
+:10E8B0001EA724B604A7D633FA58DC1813991E8A6B
+:10E8C00043F4E052D397420FF3383DFC99D34369A8
+:10E8D0009396AEEE23BED5C9B4FD036B77E13A1D26
+:10E8E000118A193DFC40A1870E0D3DB8393DE8D78E
+:10E8F0006F1EA787798F307AD0AF6707A7878EA65C
+:10E90000CB3249EBB9AE741D3479BA0EBA75B7A3E0
+:10E910001F8AAE47447A58109A379D38CD2FE46548
+:10E920003DD68BD30396A701DA09E209DBA7F7AC42
+:10E930004FF984265FDA1479FD6BDA36AC3DA9FA1B
+:10E940005ED5F2F25AB57FBBA2798B26BFC4F7A67B
+:10E95000A67E69D32E4D7E71E33B9AFA0BD71CD26B
+:10E96000E48BBD7FD4D49FBFBC5353FE60ED594DA3
+:10E97000F903651735F9FBDC7FD3D4BF778EF0132D
+:10E9800075FEEEA2A89FA8EBCF9A16A7C9CF700D6F
+:10E99000D2D437ECBCF62EA0C783EF8B04F48F4F94
+:10E9A0009DA7D1FFF9A95376429D931E07EE83538D
+:10E9B0009ED1989EF138719F9CF34CC2F442DB1EAD
+:10E9C0000BC8152A474BE0C8A674E596BA35D9207E
+:10E9D000D709CADF8A956FD4798712B21494638AF3
+:10E9E000EFC22623094C204400E1C4C7151455E5A5
+:10E9F0001D7D9437514191D0B3BCB023F2F79A27D3
+:10EA00008B87DB239C7F84F73519027A52772FE7B7
+:10EA100024950229527F276405F281AD5C4FA93409
+:10EA2000327E51B975502EB1413E30AAF6ABFA6B29
+:10EA3000A19B6C20D049BA663F97365DAFE1F704E1
+:10EA4000BCCF89406F1334DF2B9A6FD6B4EBDA2535
+:10EA5000E2B8AB819750B9FD2A297A52043E15D805
+:10EA600093326B0C8CD3F514E6DB12518FECF2343D
+:10EA7000AF85F3C7739E164CCF78DA303DE509AC0D
+:10EA80008573C0939E03981EF7B463DAE13986E973
+:10EA9000479E0E4C3FF49CC1F44F9E20A6C73C9F5E
+:10EAA000617AC4437E02700E7BCC98FEC163C7B40A
+:10EAB000DD938CE9058F0FFB51F65D5F747786CB94
+:10EAC000ED73407F11E86CBB78AC6ECDD0309DBD4E
+:10EAD000B9F223A43305CF854D264E0F491A7A0883
+:10EAE00080ED7723D04B1FE54D32A7C3DEDA472EEA
+:10EAF000AF79E1BF87DEAE7C4B7A0BD3D3101D3DDF
+:10EB0000A5F7454F1FAAE9E98AC1CEE420A7A71FB0
+:10EB1000F3736B7DBF51123BA70CE977AEDB0C8022
+:10EB2000AAA5FCDC84906998BFC4FB5E49C1B5A36B
+:10EB30001EE81B0D72EBD2E8BF8F8273874BC7E8CC
+:10EB4000E2A7F63E3F3D9DF48E7717DA43253EBAA5
+:10EB5000E80911C61BCDF01A6520D3C878421A46C1
+:10EB6000BEE45C90817989C4437B9F734684F33A09
+:10EB700042756BC06F5F785D69BD3216E09D7AF6B5
+:10EB80001F59905EE1FA75F41E11F57C1278D109D7
+:10EB9000F80DC925933319FCF3C191463BEA09648A
+:10EBA000BA167FDEDB35F86B4855CECF1B93117F4D
+:10EBB00023AE8C1AD40FFCF5C5DFFBC2E70298F731
+:10EBC0007F033EFBE28F7DF145E272BCD646E7DF74
+:10EBD000BD73CCF8C71CC007BF1ADFCA799C7E3C46
+:10EBE000F992F4B5E8B83B49A1E3F614885BD82460
+:10EBF000DA11FEA5D66B62615D4270FA584FE1ED05
+:10EC00003FA780BD7F3E550B2F4B07EFD281176D7D
+:10EC100060772D4D5ED87032C23A2869554B5D83BE
+:10EC200045AD87B669F3971A85692D382E47ECEC08
+:10EC30003120276A1B18DF5E8EA90267697209F608
+:10EC400073AE393D96D97B3EC60F36C721BF38E734
+:10EC500029C3FAFFECF1F40647190F21ADE484193A
+:10EC6000F8312D4BEFBD7EAFF42CFDC588E7DD7E7E
+:10EC7000F90AE88966FADF9760771009F30ADC9AE7
+:10EC800016D16BBA01BE6FD6F447DB399433E22F4D
+:10EC9000D3BE6ADF48E49442B7545ED483BD80E7B4
+:10ECA0009B4B1AD47A5955CB7735F99AB6471AD473
+:10ECB0007A5C05FC83F25F522B484037959C8CBAF6
+:10ECC00025CB1A818EAF18824F808F08AC5E95B924
+:10ECD000C3E8A69FCEB7B275EB6D7CE73CE65488DF
+:10ECE0003B283337E2397259CBB5F92067CEB7AE3E
+:10ECF0004C02F95B215EFA5E5184F6BF94042E5FEC
+:10ED0000E4A056CFE7F441285CD5BCE9CF12C21786
+:10ED1000CD7719985F460FB78DCB91BEF053BDF9F3
+:10ED200050C1CD8E9E78AA6EBB6874235FA4FFCBC2
+:10ED30000AE349C15FB154D426D171973777A2FF56
+:10ED4000E28CEC1DF583AFE0973DE767493E15A3E4
+:10ED50009A9797B4433F0B26F18E88E3DE0F281F66
+:10ED60003FFB5B99001F225769AD2C74CD70BBC768
+:10ED7000400C5961BB67416B4521E0FBECEBD3D103
+:10ED8000EE5B448A6CB80EA4310BEC9CF3C480712A
+:10ED900055E7C91F6C1354EBF0B164E478A65C30FE
+:10EDA00089BB3410BE7B10D85FA639F5EDE258F868
+:10EDB0002E297690F025CA15B780F11773D8772FD2
+:10EDC00031D701FD527B4A63AF517B4A93A7F6943A
+:10EDD000265F426626413C45C9D332F10988274D5A
+:10EDE000F941C98EE32B25B5F5A01FFD9CFBE1166B
+:10EDF000D8893484CA87AA379ECB2AA6F3E9929889
+:10EE0000FF4B890F584265C5205A5E5EE633BA2C27
+:10EE10003DE777A275C23D94F3033C160770BFD15E
+:10EE2000C7E26B8843CAE2AA4F5AEFF31FD82ABA47
+:10EE3000A26C508F7E57C69BFAF5E7AF9F2F214FEC
+:10EE4000E23CCA9B67601C568F78073E1FB9597019
+:10EE5000F922EC27511634F12E0932C39FE2D71A5A
+:10EE6000AECB5F0F7995DF6BA2AEFC1BF39701442D
+:10EE7000C35F8A25F7703991F113C0BF2005717FF8
+:10EE80007D63F8C93DE05F2FDFF84F843F54BBEF4F
+:10EE900029FC89FFD4F18FE831FEBC48F0ABDE7865
+:10EEA000F57588772CFFD5CF6C84EEB7B35263929B
+:10EEB00093AE7BE5A6D53617F01DC96B837D71D661
+:10EEC000274E8B440FDF9779DC1F715904F0BBC2CA
+:10EED0003F29FC73AFFCF84EB0A3AE6C92EDE84F47
+:10EEE0006D36054C949EAB5B971492B198EF64F924
+:10EEF000472F02FDD7B4C9C7D5745AFECB9F254111
+:10EF00007C10A5942186644803689F546FFCB80068
+:10EF1000F48D1A12C4FDAA6F07FD7F168FF2B0D8C8
+:10EF200018DBB31C1D3449D09EFD6A5A7F7C51B456
+:10EF3000417ADB69E06FD4B244BF90BE5D19B73B44
+:10EF40002A64EB00E4AB13C944E0AB0A5E888FD9B6
+:10EF50001D2B5F7E666C271D57D7C6DFDA0415BEF2
+:10EF6000147BE952CBC25FFCDAD13B1FBF40F7A351
+:10EF70005ABF55E494A38DDB4B7E9656CA011BC441
+:10EF800073556E909D5EFAB9F2D5175F7A16FCD96B
+:10EF90007F34394752F815AFEE3B7213CD576C9161
+:10EFA0000714B2695884A4F0FAD4D0FF968F0FAF3B
+:10EFB00047F9B67D46C718F6FD87F1E175A9D8B2C5
+:10EFC000CB48C6F4C4475ECB2E638725C2FAB4741F
+:10EFD0001680FEB7F2E5BF1A81EF9DDD299081A969
+:10EFE00011F0B9611FEA8780275C4FBE5EA1F5D39F
+:10EFF000D5AFA1EB027246BF5EFA7A859CBF005C7A
+:10F0000088B3A1F4FDDAAF210EEE4F2627E0A1EC84
+:10F01000B5876C309FD3522DA3F3E7562701BF2B42
+:10F0200093BD49764CD9F7B2E71F46FA2B3DF470F1
+:10F0300012F357BA061950767A07C13C17AFBF1BB7
+:10F04000E75942DC488765CF89453E9A7E2A916917
+:10F050005B22EC934B7C9F9C7E812E2E9DE7694525
+:10F060002EFC41E472E1BBE80F7D98CF856A909851
+:10F07000FFD4CCD6EB806CD0C8D110FD6E7C14E5EB
+:10F08000C7B961AE8170EE561396172847C4435333
+:10F0900007B275627207DB51B99307DFA17EBBEC43
+:10F0A0008A1AAB69877246E97F19EF9F8E3B1AF483
+:10F0B000B7D34991ED91E146850F503D434567AA8D
+:10F0C000FDCEF6FFC606B6DF95FDEF9B310DCAFFFC
+:10F0D0007298ED23680772978E2B3010CB77CD1680
+:10F0E000903F984820D23EDF28F37DAE2DD7D30B3A
+:10F0F0001DBF24C4AAE806FA89C77540795FF234B7
+:10F100006DAFE2A335D0AFAD275C651F97727E70FF
+:10F110001EF8C1F5617E40D627F62B5EB452F6BDCF
+:10F12000F42CEC5FBA5FBD0ED8BF7211CCFF93CD4B
+:10F130007B8EDC4FF7ED272DCABED5F255FDBE2DD7
+:10F14000DBFA30C69FEBF7ED27436B49C47D4BBF1D
+:10F1500047DCB7433BFE47F8AA82C724A396AF2AF1
+:10F160007CB2377CEAF9E416D98178D5F349FA3BC9
+:10F170004CB27AD2A342870AFD95FF47D570E0478B
+:10F18000213A55E83044A70A1DEAE7ADC5A3BEFC05
+:10F1900023F02D527A297A53C6F3954A3F8B03A662
+:10F1A000EDF60FC9447CB950CC91C6FD4306A8F3D7
+:10F1B0003E5DBE4557DFA5CB17E9EABB75F95A4D51
+:10F1C000FDCAB63D46827410D0D41397FF3B393147
+:10F1D0002112DDFA98BFA1F5A211EE39D45882D8D8
+:10F1E0005E5E41BC101F19DC21E2B95137C5713D8B
+:10F1F000F83736A7FABC948FAC8E627E856E7BD0D2
+:10F20000164FD3D5712C1F4C34D6031F54BE07A301
+:10F2100098DFB1BB28688B53D95B9D7E11F9788745
+:10F220002FF2BD0D2A6970DD3B7AB9D7A19C8F758D
+:10F2300047DBC6627FD1293EA0C7A9A2256539F860
+:10F24000A11A4527E8EC8BEAEEB5C17955B73FFD29
+:10F25000AE39F4FBE27744168EE37549835476D0D9
+:10F2600019E25D972D405CF05AA49F857E66172DAC
+:10F270005A1B793F94F37625966546E0BBD40E3948
+:10F28000AE3EEF51E094ADD77DF74FE7FBA611ED11
+:10F29000FFF28DDA7237B79F7F64E4FC671C19C7F1
+:10F2A000ED57E6BFE17C7BAA9871D71CBA3EDD071B
+:10F2B0004462A2F94B7E11D7E7D266C107FE37E25E
+:10F2C0004DC4FD574D8246F57D882ED85FD7F4CECC
+:10F2D000C7BAB6FF39EB074047AF7F30F6DF69DAD0
+:10F2E000F5FA1F47BD05F9378EA67C407AD6CFDBED
+:10F2F0001985F102DD3BAD48FFDD3BDE4BF901E452
+:10F30000DF3439619CDD3BFF3A16E8A97B85A90C07
+:10F31000F860F730E6BF5DB9E3AF633B50FEAEC2C5
+:10F32000756C361A999FC9FF8F8FE0DEC2253F9D0D
+:10F3300015E8173CAEBEE6D7513E82F0FF9AA5BE57
+:10F340000FF46DE753CDE343BAAD64CE56185F1C9E
+:10F350008B7FA8796BF28B75B4FFAAD65DC685B496
+:10F360003CEFEDCFC7621CFD56A6375D903B9E87F4
+:10F37000F8876DC6EFAC94299E2FC026A346F65D94
+:10F38000A63579B08F7AE2E573F4A7F5171FEF1A67
+:10F39000997DFDAF8F0FC1C5F89FD5671660DE7FE1
+:10F3A000FBE803F4839A902E95F97ED25287FA4CAB
+:10F3B0005FF33EFBBF860EFA3B6F21D09F799B4DDA
+:10F3C000FFDAEBFDB8D181EBA2DF073DE97CC7F79F
+:10F3D00030FFAAD589E3ED27BD8F36FD3FB6EE5B42
+:10F3E000E9BADBFA9EF777FEC5E7DDFBBABF338FDC
+:10F3F000AFBB1DCE536BDEFE1CC7F775F95CE9FF92
+:10F4000052BA57F4FD7643AD3D938E6F0E69B482C8
+:10F4100062715FE2254BA603A2702F0FC0F83B3844
+:10F420005F8D6057359998BFCD241858BCDADD82BE
+:10F43000E247443BEB4EAE5FDC39B40CF5903B5DEC
+:10F440003F417D8248B5ED39B47E7BEE4227C66AE6
+:10F4500092F1C7DC909F3D85E7B5F6E6EF04E21236
+:10F46000A87E7F67EEF403A0E7DEE512510FA62920
+:10F47000EABFEFA714B0EF93B4F6D07D6E6DFEDE59
+:10F4800039DAFCDD1CDE3D848DFF9E22C1077E58EB
+:10F4900053CE5389E097352D9689900A7146B5ABC6
+:10F4A000C1EEB8BB48DB7E1928672A7FE337C5E386
+:10F4B0006F43785C8A78213922DE03ED138F7CDC80
+:10F4C000EDB3C7F920CE9A484E86C77BAA9CE83791
+:10F4D000E7F6B8CCDBCB9635EDB09F659D1DAED879
+:10F4E000D3BDE19B70FB1CE1A485F12FBB44B4CFDD
+:10F4F000659D7DAEACCBD75D0F651DBFEDBA3C07FA
+:10F50000EB7263785D865A5C04F6ABCCED877C8B3E
+:10F5100093E587161176AEE8C3FAD20017F1668438
+:10F52000E3D197988B2BE09CCC3C5A407FC85D6B15
+:10F5300045940FE60C01C7553449C6F8E38F0D45D5
+:10F5400059B0DE851326567F9F0DC309F85CC2F1C2
+:10F550005E426A517F2557BFFC323B0BCE2508EA3D
+:10F56000BF4B5C84DC41EDB8926C21100DF16A1246
+:10F57000F1C68E073FB9408E6BFCE4DA3CFC6E4965
+:10F580000AC3E9AB7E6FFCE59F9DFE17E567C729BF
+:10F590009174423A12BB97D476F77C3FC3634DA572
+:10F5A000E04B43BA0BC8EAFBD30566B60FFEEB8708
+:10F5B00013904FE6FC744C2CF30764E27DC41A6E82
+:10F5C000375CF23A62C10F76C99FCECF73F36C6A93
+:10F5D000BEAAA487B81DFE9F109748D3EE7CA15108
+:10F5E000043B8B04D1FFEBCD8FC27BC5FA76A3CC55
+:10F5F00006BEAF6BD12F003F11EEAFF27994D2A6C9
+:10F60000B1F1AA755B7BC759696CCF7580DF71D585
+:10F61000F9DDB7C52FD8FD80D743511D054511E64B
+:10F620003B89E3AF70F7DFF0FEEA4C7FAA0C7899D4
+:10F63000992F6ACEF99D66EECF984026C0B80A771A
+:10F64000DF669B0CEB724074C27DD51AFF45A33B6D
+:10F65000C2F9B11E9F001FFCF027646709E0F3C4E4
+:10F660004FA208D8D5EFF173C90CB8CF9181AE1E67
+:10F6700017F81D73CCCC4FB8CE6CC77456618E9CF6
+:10F6800048FBCD68B58F8350B5C1BCFE3AB303CB00
+:10F6900087F0764ABDC195AC5EA7D15E1D69FEBFFD
+:10F6A0008B12F87999F37B93847FBD75CBF9A935DB
+:10F6B000900BFA41BEE267D1D335C1FD71699AE082
+:10F6C00003F90DF630E60B05D41FDE53EEAFCF6421
+:10F6D0007256A17B3D9EABCDDAF7021EE7787F889C
+:10F6E000D387826705BFFAF12AF529BFBA55ED9F86
+:10F6F000BAAB6DDC6BA0DF54FB05BB8182AA963AE6
+:10F700008CB00F6BDA9E90E17CE63E07834BA4A29F
+:10F71000B1EAF8837566160FB267FCCDF3804E2E02
+:10F72000AF35812C24AE45176DC087DF33387F0F8E
+:10F73000716CDEDF8964D357F0AB0F3CF6F27C5975
+:10F740000D3715E733AB32470677DA0395BBE48113
+:10F750002A7A5A678EC772E5FBE04A07BE0F42FB62
+:10F76000C371781F3711B84F92D1D28EF76C1FA892
+:10F770008D637458D6B2CB88F954CD7B224A3FFAB8
+:10F78000FD34BB501BAFBC30AF6328E0A5D014588C
+:10F79000E68C40A793A39473CAAF29275C946EC7E5
+:10F7A000FE7F2427962972A203E3E395F602DFE7A2
+:10F7B0002A393130929C585AE71808EBB07447FA4E
+:10F7C00040D8244BDF999A14494EBCEF61E7CC47EF
+:10F7D000F97DF6EED9544EDCA09213B3A3904EF40B
+:10F7E000ED3E51F6495F724259B7FFCBFCE67D9082
+:10F7F0001311F6F7173A39718FBF18E5C43DB345B9
+:10F80000CDBDAC4FFB94133949F7615E76C644A079
+:10F810009FF7B97D7394DF0B807E405E6446D911FB
+:10F820006F7AB9D11B5FFF537FF9FAFF109E15BEA7
+:10F83000BE94DA3FA6D4487448909E97DE47F9BA42
+:10F8400000F4C8F8FAD207B99F53C7678B80CF6618
+:10F85000AAF92C6B5FED6672A1A62DF599B9B4FCDF
+:10F86000FE46D909A2F2FE30DFCD52F3DDCCA85E10
+:10F87000F86E19E3BB97FD13507FEA6D7E7FE6FCBF
+:10F8800096F2B311CE08F431676E8CE6DEDE897134
+:10F89000BFC9D806FBE53D11CF793FE67AC0C171FB
+:10F8A000BFC9047DFA493E9E797C3D2F7848793E58
+:10F8B000C55FDE22A64F576D16117FD5AD6CFF5781
+:10F8C000370B3E07CD178CFF1B9ED756EC60E7B574
+:10F8D00074068539AAF5AF78AFA31ECE092A36087B
+:10F8E00078DE0CF71E009FA51C9F25CE0A3C5729E9
+:10F8F0006DD2FAC11BA26D2F901B101EFAC3AB78FC
+:10F90000FD425310CF1D0A7F293837209FD4B6AB54
+:10F910001A71FB59B04F2A9A75DF9D0D78AE0437E6
+:10F92000D441AFAD6AD1967BF8BC178B818C6D1436
+:10F930003EF93DB3F3F478F7E8F153F62DF173880F
+:10F94000E227F39F879F25FE5D785EF075F1A2C7E1
+:10F95000475D143F1F184F32613F7E6C70217FF16D
+:10F96000BE2BE2BB4E8B9E18A9790FE5A71C2FEF8B
+:10F9700019DCF583A05EB580F54AD76FD99744F3BB
+:10F98000735BC8383866286DD2CAE390FC6F75A0E7
+:10F990007C9F5BBB4580B8DAC5FCBE6099EF097CF3
+:10F9A0003FE6C1E554DED3FA0BC79BDC705E7E28D0
+:10F9B0002A88FC53A1DF9D40BF946FFAF9384E0CA2
+:10F9C0000EE6A39C6A13ECB82F03514C6ED17582DE
+:10F9D000776DF64CFE6B015F17E65F6A63EB584389
+:10F9E000D70DF675819FE75B983EF880FF223BE7D5
+:10F9F000F4EF92D9FB380249407EE744FB5C918FDB
+:10FA000070EE9A93A45ADF1D9D8CFE37094EFCE0E0
+:10FA1000A3FFFB36EBDBCBBA2AFA4C7FD757C1D317
+:10FA20004EDD3A1F8A6A2F9C80E7728213DF0BF249
+:10FA3000C7E179D1C946F6FECD41AE1FE9F705D839
+:10FA40001FEAF77866C0C0212E7A5A14C69562BFA5
+:10FA5000694C3F53F329FD3B485F376EA986B4A339
+:10FA60005E168E7F74DF6E06B93F4DD0C449D11942
+:10FA7000E1BEFF27C097A3BE023E4936A37C79C8EA
+:10FA8000CEBEEE196624F01EDAE53532D2D1BD06BF
+:10FA9000C7916CE02F8FC904F6C7E583371E9D3BE5
+:10FAA00000CA45A48FE2F72654836BA598C5AA9196
+:10FAB000E247985C3AC1FBFF1395D7AE6B7897A0ED
+:10FAC000077BE27C70BF74B673D75407F85B320FC4
+:10FAD000AD8673CF5979F62347601D1BD8BB4FC73E
+:10FAE000D7E4A19DF6D07705DC67C7E87A019CBB17
+:10FAF00067A71E3942C7F7E09A443CB79CEB4ABC63
+:10FB000007CE31E71E149D0E5A6FE15D560B9C7FA8
+:10FB10004E1F2D12B70A2F0F9276F4EFCCADFDEEEB
+:10FB2000DDB04FCAA83C84F79CCAFC87A60E84FCB3
+:10FB30007A01DBD778DD46B8E7D9DE74D19849FB86
+:10FB40002FA1F500DD35EB59BD9A8D02BE1758E2A5
+:10FB50007F02F964C946011FC469A7FAAF99C1F5CC
+:10FB60008129D1BE9EB6A7F952680F7037C6DD0352
+:10FB7000E79335749CD87E521D9E5397D076B498E7
+:10FB8000B46FFC2EC25BB25E2070AFB06C52EAE381
+:10FB90009300DE41D909E54777FDDC08E39E47FB8A
+:10FBA0001B44E12F143BA6427DF203C18EEF2E15BC
+:10FBB0005E8BFBBA9BEF3B621FCDE21404A2DCEF2D
+:10FBC00093D4F12A25D169B89F4A96D7D5C3BC3AB8
+:10FBD000BC89A906A4A78B4690E32729BEDD547FE4
+:10FBE0003D616471307BBC278C1D2AFEB9323A1D01
+:10FBF000DB2F6ACB413EB39814613C85BB8EE92371
+:10FC00009DABA37CE057EB94ED29F07DCF6A137E8A
+:10FC1000BFF02A933B178675A07FFBF47A99C0BD8D
+:10FC2000C795EBD3D7C13A9EDE2C3BE1DC407C8EFE
+:10FC3000C51194BECAFC647BD633B8A79B197FCB91
+:10FC40007BEEEE02E0DBA5944F99707E5A3E56E2C1
+:10FC500028473EF55C14E34B7A7EA5E753658D1B80
+:10FC600022CBA1650591E5D0D07AEE378D2C9F6B24
+:10FC70008885E9BBE3C978F06316570D9BD704F478
+:10FC8000FC20BB70D01E78F3D39F81DCADB4E23B87
+:10FC900065D5927D9DC0E88300FF9FEBDFF229ECE4
+:10FCA00087B2B951F80ED929580FD8476B13F01CF9
+:10FCB000BBC4578C7857E2794B9BB4F4AEF821EF74
+:10FCC000738BC4A5965F6531C4A5AA77F447946E7B
+:10FCD000693FF3DB041FB0CAA33FEADCFF7026E6EE
+:10FCE000ED38AEE55C3F586B45BA3EFAC8C5D54025
+:10FCF000B7F37E2810D0DB89D75D0FF2B0BA497018
+:10FD0000809FB8F487AC7D296D0FE33EFA73465FA0
+:10FD100094CE1DB00FAAD73FB11FEB6F141C00FF8C
+:10FD2000E88662D427CABC22C1F28D9D684750790B
+:10FD300085F1687BBC6212EC83EA55263BB86215FC
+:10FD40007A52E8B393BFA740CCCEB1B3683B67B457
+:10FD500003F9B29E2EC53942489E02FDD47819BDE2
+:10FD600075BE2A3B618BF44D9FEC1EBD427F22D0B5
+:10FD70005F6698FEF6ACCF33023D9EF60918679198
+:10FD800007F40BF4F9B2E29F2116B51ED5177DEAF0
+:10FD9000E9B007FDC1CB58E961FA54E8514F87C774
+:10FDA00025720F8CFBA1D551388FBCFA37EF59CE95
+:10FDB000F6199ECFE5D53F9204FBBA446271400A22
+:10FDC0005EAB241637D6635C4FD71907F5677CBA4C
+:10FDD00071CC8A0EC9EDF120B7A93E4A02B49FDF6B
+:10FDE0006C7E11E32BCFBFD27927EA376F513A00EF
+:10FDF000FC6FB69200DA213EE447E5AD22C66913F6
+:10FE00002990354B65BF2B713115BFB222BECBB7E0
+:10FE10009A7C85B47DF9EB27C6625CC20AA67F7B1B
+:10FE20005F11D83988B7632CDC3B2A97587C8E5EEB
+:10FE30002FF85D34B3C3BBDE8C99037A9BD0CCDE44
+:10FE4000172C6FB95736A9FCBBFBA265A51E9E9364
+:10FE500079E93AC3FB0A303EF5FB764A5C4ED7CBD4
+:10FE60008CFECADB64D4E7CA9BB75C8078CDF263B2
+:10FE700026B4776B9A2F1AC19ECDFBD5ABEC1DC46F
+:10FE8000365113A7D7233EAE590C9820AEABB50A16
+:10FE9000CF7168BE13F32D3C1EED6BC66F55FC6A27
+:10FEA000C7EB5E8AC28A6DBFB4E17B85ED9B6C783F
+:10FEB0005FAAF9ABE3557BC4C3B534F078B83B4EC9
+:10FEC00013E48F91E3E1CEC13F28217D16AD8D87EC
+:10FED00023CD8CBFD17166457A0F35A477BDFAE981
+:10FEE000F310CFDDB5F593E761DC955F5C7E1EE234
+:10FEF0006CA88268073DA5E695F731FE5569171F86
+:10FF0000C3EDA0977F89F1C317FE687202B40B3B63
+:10FF10004EA780FE7161CBDF92202E78D98EA9E8A2
+:10FF2000DF59B63D0FDFBDEDCD9E05FAF5F5237E19
+:10FF300059BF6E7B5AF7603CD079BAEEC027427148
+:10FF40008E2D552C7ED4C1E31B37478E17EF11CF72
+:10FF5000D83AEBAE29C01F5B999ED0675CE361BACB
+:10FF60009E37F4631D37F3F8D5963BBE32AEF13CB5
+:10FF7000FC83AED7B8186D7CE8A7AD8B7FF12C94CD
+:10FF8000B526F41AD718E807FE9478F4CFA35DD904
+:10FF90003189B0DEFF81F1A4B07E850EE0D79FA647
+:10FFA00080BFF88C1C44BF44708709EF6B96EF3814
+:10FFB0008AFBE9C2F64318EF4D785CF80512FAB1F6
+:10FFC000F85DEE03AAD96865F1907C1D205ED261D0
+:10FFD000C3EF3C2E92D1B5122FD95B9CE4B298347A
+:10FFE000FE3E0B8BE7ACDAF8018F3F0CAF9B30097C
+:10FFF000D6ABF32BE350153CD8010F13D571C0914C
+:020000021000EC
+:10000000E3524371C0BA7583F5043E1E8AF3A5F925
+:10001000A110EFE9138E468A2BBFB081C50F5F9008
+:1000200023DF8F56E2826B6274FBD6D7BF78E0BEC7
+:10003000E6F175F1343FC6A1A11B055F5D5723F3BF
+:10004000F72763846F64B785EE9B540AFAFB2C4F45
+:10005000C4C07D99D64E23BE93A2D8557CBE5DDC2C
+:10006000DFD6F58A8871A2F52D7B90BFEBF9473575
+:100070003F47D18F77231F6F751B931F5D5BAD3E8D
+:100080000B85D3B5FB4DA4EBEACD9D18A7BABF797C
+:100090009BB14375FE0CF2C3A71A7FD76BBBC62278
+:1000A0003FE7EFA2E9FBD9CAF9638D3F723F359B69
+:1000B0002F6AFAA9F0B618ED96BEFB3B27B9EE05FC
+:1000C00078E7DA991E75AE459CE68BD0FFCF626467
+:1000D0006E5737323F3895A3F83E9C95BD0727DA17
+:1000E000A2512F5B669D740CDE215D6635625CCC8F
+:1000F000CA3A1E47F3236732ACF74AEBED04C6BB9E
+:100100001AF0ABB2EF65BB9B803E27271765AACFDD
+:100110006194F11B0718884FBD8FADD306827D4ACD
+:1001200024EF5018C79D697F95402EB67B987F9F1E
+:100130005C3D3102BEB74BF67D09146E7BBEE00418
+:10014000D76C4FBA67F0437E0697F61D5DBC5347E8
+:10015000E777C969403DD16A08D86915628D6A4F51
+:100160004603D7411C52125EA5C07889C73CE611F0
+:10017000703FD446A8DA0AF59C92E65D95D849927C
+:10018000EE9D15727804A5570BA757C55F6765FFED
+:10019000A6703BF0FD96B80C5207E4BBD6EA467D4C
+:1001A000E2299B0BEF3FD2DF6888938827D14EF579
+:1001B000BB50B45FCD7D3BDAAF261FE7D2E613A676
+:1001C000492723C99B043E8E02D18278889B6AE02E
+:1001D000FAB2AB70645278DC7189C41980F23B2C9E
+:1001E000788F806E2FAF7A1E168B76DC747C1A3E69
+:1001F000119BD1E135B0716ABEDB8903DF47A7E30C
+:100200003DAE1BAF266FB5707E271109F89DC5DC8A
+:100210004E38FE2F69F0BD4A2A8A4F224C64C238FC
+:10022000E93021DE2596CF83F6AFA96F07EF01EB0A
+:100230005F0B870CB5ABEFB5DEC0E5E0114B518A23
+:1002400085EE93ACE1B518B89D9D2CB84E4EA065D7
+:10025000FE01C89FD296E7615C8AD0C8E86AC45A9A
+:1002600082FB664490C755AD8A463DD56426DEA81C
+:10027000F1703F8E78E5F1D08B8F9F3F395618286B
+:1002800028690DA535DACE1FCC352CA68BD00245BA
+:1002900014FE108B6B0CF45F3FC39D6C1807D31BCF
+:1002A00056BF7728EEDA6BC16368A81BBAFFC0148B
+:1002B0006421F82E08F10EDD0F72B851C953C60E35
+:1002C000EF06344687F22E33E5F78D692C7FF3DA9B
+:1002D000A1F5F07E4DA7BDE8660B8CC76CBF0ECFB5
+:1002E000C302F19AF7D57B932FCA38476F0CE4C14C
+:1002F000FBC7B707D9FBC523ADA17BFC288F3759B6
+:10030000947C00ED8BA2D643C8D7AA5A0E61B901DE
+:10031000F2341D9E10C81B42E779BF654C41F2B50F
+:10032000145E6B71323CC1B1D03266BFA4C1C3B898
+:10033000FABDD9613C482B6ED0E1E186AF85878557
+:100340006B6FA887F755FA3B6F4A170B005FD373A3
+:100350000CF88EDBC46316F4BFD05F14CA230E679B
+:10036000432FF7BC153B85C22957D397D24EA1AB7B
+:10037000DEE8269DD8AF63EF836AE9E7DF2DAE871D
+:1003800000DE328B2BDD9688F3C77705A6BB8B8BFF
+:10039000F213C2744D2CEE09F0AEFE11CB821F5A3F
+:1003A00054FEDAE9394BC5343ADE1F0123B8313C3B
+:1003B0009FC4E5DEA851749E892E03C6D51FB1B82F
+:1003C00057403BDB9C600062CB2612F704410CF7E0
+:1003D000A3EC8FFA1DCC8EAF2F36F856B0F360FC2D
+:1003E000BB1D61FAE8D0D14790D1475B27D247B512
+:1003F000BF93D1475B5D6E343F57033BBA9104C74F
+:10040000C1BA37590A0BA461946E6282F54037B2C3
+:10041000F7B682C228C4EB3A185F8FF5E1E352E6E3
+:10042000D5DBFA361E48FB7106D899070D781EA653
+:10043000E04DA9B7C3C2E246FFCDE67E11FAA99905
+:10044000D4B11F966FEB813F605C87EDE0CC5DD04F
+:10045000DE369BAE9023DC6FE3C115F84E78237F28
+:10046000D73B9604BD20D77BC707DB3F217C80DECE
+:100470009301F8E8C4FDF20ABF6796DD26B840CEC6
+:100480000F8F61EF90BC6E6176F5BB1691A74CAFF4
+:10049000493CB85B04FB2B7B9501EB27429AA19E5C
+:1004A000FF2A5E5FD2F8DD957555E88972D218781B
+:1004B000CFE4F978F71E2DFDC4C7A4A9E029ED1EED
+:1004C000F790A245945026EE5DF010C8554A3F3E85
+:1004D0004DBB317214E02D443F943E23AD0F6D7738
+:1004E00088AD6B7C0CE80B5BF62E15F15D8E7EAE55
+:1004F0006B16BC4749EB67C590DAADB47D562C4D01
+:10050000219FC0F303797E084BD33F741A04FA7D10
+:1005100003F7CB9EE5782592FDBA996320CFF4B816
+:10052000ECE418940BCABE856754E05C5BE2E7DB41
+:1005300069C13403AC9BB28FA5A02160A5422B4DAD
+:10054000721820CEE15D8FBB08CE0B7BE33BB75F1B
+:10055000CBEE81EABF7FCEC7F38DF5EBBFF4B82FAA
+:10056000FE39E0B7CADCF1F84C9AAFBEF632FA6950
+:1005700057C454DFFC55EF68E8C7FFEED5DFC40071
+:100580001DFA3F3345BC3F35CECAE8F180670EB651
+:10059000CBE2EF0492814A1CB22ACE15CAB85E861D
+:1005A0004B9986DF51CFBA055920ACA7578A87F6F9
+:1005B00031A978AE78AB2EAE55392FBB25C0FC8063
+:1005C00059B1BE42ECEFFA74F6F7493E63FA9299DC
+:1005D000FE0FCEA1A6F27333D731FB5E1087590907
+:1005E0008DF9083F3615FD5A3944FBFE41D640AF20
+:1005F0006480F2F454849767D695A713F45B916BEB
+:10060000AEC3F94D252AFD0CE546A313F8F1F4D14C
+:1006100094FEF9F7CBF4BFE126327F86CACEB8CD7F
+:10062000715F51BE466F69C477857EFBB9383F5212
+:10063000FCC563213C1715413C801E8FB90E6195A6
+:10064000D5D113DF7AFCE9F1ADE0518FB79C0F9D56
+:10065000F9F18E9EF8D1E3237C7EE95B0BEB3075DC
+:10066000B488F24BC17B4FFCB0F5FAEDB5B49E00F7
+:10067000F442F10DF84C1730BE272B86D34F6C3A5D
+:10068000E2370B14C001480F98D7E3558FC7AC046D
+:10069000DE3E81D5DF0FF81A89FC00ED2165DDB261
+:1006A000D26BF7C641DEC4E84CD1ABA772BC50BDDB
+:1006B0001AF5E6BC442BFA9B40AF9E9A14C65B5ECB
+:1006C000151B57DE48CB0B609FFE0AFCD1B1080614
+:1006D000DFC5BC95F05FE0563C5FCAE25905DFB765
+:1006E0007EA6D593A7FA0BCE82FE3DDCE45E6505BF
+:1006F0007F8C1087E77914FFC775F8D7B6B36BF313
+:100700007A7CFC0AFE31B927DE147AABB372FD7C29
+:1007100030190AFAF2D8373363817F137F7C44BFE4
+:10072000C4C4634521389C6E919E05E20E7DB7A737
+:100730007F0B3E76904A49151FBB5372AFB3DED88C
+:10074000938F29EB3585AFC714E2DD057EA62944DA
+:10075000FA4BC81E480DCFFF792BF7B30D2143602C
+:100760009E5F581C8CFFF37986E64DD54BE83F9B86
+:10077000F79F6DB6E0FD1B1294BA42784EC3F79313
+:10078000BCC6F8F0386465BD536A09D3E7E6E2FBFE
+:10079000D9142FE4CB98F038B6590509DF0FE2E3FE
+:1007A00038DF6CF6429CDBD392FB0D2BF83D848343
+:1007B00063717E526014C83F7DF9E5B6BDD5504ED9
+:1007C000EB95603D3EFE0A91F91F823B4CBE1752ED
+:1007D0007BD753E9F64639A1D07136DC7BBD01E801
+:1007E0003E28C2B8FDFC5C65E74576CFC145ECAB61
+:1007F000AEA7F0F65D62F702F228DB817A7AFAEDB5
+:100800008B4EF349701EB4D3D3AB22CF1BF8FD5BE4
+:10081000453FBB6875BF0FEBDEC0EFE3FA2F8EBA22
+:100820000ED6E71BD3D5612D5D29F444E9EB38F4EE
+:10083000D39DF9F13A50CBDFCBBC9C04F251D1E30C
+:10084000C3FA8AEB63A8D79B3E3FDCE6EEB27E8517
+:100850003EAFE8357DD92364AF4446D371CEE3EB98
+:1008600033D7DC2EB38BC6418CD36F8856DECB7367
+:1008700044833E39AF21ED95663857AC637EF90766
+:100880006B658D3DEC86DBBED89EBD673B7FB9B600
+:10089000FC238AEF41F1F8CEADD68E86FD91147E11
+:1008A000CFB767BF062FC8C97923A3317E4EDFAF0C
+:1008B0007E7EFA7EF5FD3570FBAAC1D838DAA9D262
+:1008C0004FEC3616477D69CD93CDF0145E6FF8730B
+:1008D0009B87B8D47F6FAEA3217A4EA4F7681478B3
+:1008E0000ABEE7C2CB98E00FA895FF1EE99DDD6C1C
+:1008F00037F313F4D6EF88603EEA8386A70322E835
+:10090000F5238204F5F0ECA0CBB050630F307BB937
+:10091000873D00EFA4D07C65EB2E660FB4D4A15DBB
+:100920005149ED0A903B1BE01D90C17C401968279E
+:1009300084EC5E88AFCA867732B95D0C4FA7A537C5
+:10094000B2FA331F4F37358C00BBD59D0C2F93CE99
+:10095000B45DFBA899DA57F5A9248A50FBAAC8769A
+:10096000ED77D64EA2DC3BDE25C0BBA434FFA865E4
+:1009700072FFEDEC99B6D18F82BF81DA67B7D95497
+:10098000766F6FFBE3669B03F1D9DBFEE8B417CD0E
+:1009900004388ADF82F221E407FE28BEFFA342F476
+:1009A000170B7853E8E5F6E50BD1CE88BAE66A0A6C
+:1009B000C49365733A70DBB85F3686C1A9896170EC
+:1009C000264A6E37F4D3BDFBEA28F03BBF3BFA045E
+:1009D000DA797E2BF3DB1FF49415A9E3DB6B6D0250
+:1009E000A797C010D87F77DCB82701EC956C59C069
+:1009F000F74EFDB2EFE9F199C09F66DB57D2296649
+:100A00004F36E2FD327F5460C8C32A3DCECFDF4D62
+:100A1000F55FDC3F441DFFDC6ECDABB531F822C085
+:100A2000CFCEDC7B0CF480DEE44E58AEB804902BC5
+:100A3000E4EAA1243C5F6ADD67039F68177FE7E073
+:100A40007CEB9EA40534ADDAF29F36B0E3EA383E83
+:100A5000CE4BEDF85E53E57611DF13A1FD263D0088
+:100A60007EEBD68559ECDE1FBBAFA6C8D5F19FEF54
+:100A70001952C49C8978FF4CD137A798BD3E189F66
+:100A8000BF8EFD1DCC29BAF7C96EE5EF93E9F5CF0E
+:100A9000676CB2E22FC3F8A96576D64F6FFB2BFBCC
+:100AA000B304E253EDBF6C2920C2F8B33F4BC2EF51
+:100AB000E70FA43D5508F63D919D2301AC44F6A2F5
+:100AC0007ECBCFA7E86F2FBC7BBE9367DE6EBD3CAD
+:100AD000EB66246E2AD704D0C7DC0398D391C907EC
+:100AE00045FFBBF533ADDF55AF072B7232D73F6EF5
+:100AF000D510027877CCC2FB1307248CF7D2EBC950
+:100B0000538305BDE8C34F207D6D6D4D8F017BFE86
+:100B1000DF609F00DDB65EC6F783AA49E01E78C796
+:100B2000A9BA55B40760FC24F37AD8678A3EA1E0DD
+:100B3000A5EDEA1EF358DA7FF645837D0505F176CB
+:100B4000F02F68574FF8FDC1049067FEA084E707B7
+:100B5000D917F7C62C54F145FF55037E7FFBEA6E8B
+:100B6000EDF760FCF5D06E8B81D9CB7BF7FF3D06AE
+:100B7000F8D4DB572F21BC903ED1536F46FD3BCFBD
+:100B80002A86FCD16ABD9988D98721DE6B6A2C152B
+:100B90006B42EFFA70CE87649595F4D42B42782798
+:100BA0002E09F0D0431F56F0ACD3333EB2713D77DF
+:100BB00018190FEF5EB65D4DA8C07BC7FE18FB0A83
+:100BC00094CF4C8FEADE7BEEC9E9F0FDA0C8DE9D34
+:100BD000B82AE27EDABDB36278876ADF524E8AEBCA
+:100BE0007665D0C50B6FD1FA57F64533FFBAE4BC32
+:100BF0005E7D4F225CDFC7F11518CCCEE9BC83E1E6
+:100C0000BDA86FACCF74F5B0F7FF61433D39580014
+:100C1000E262D4FA4E23ACFFBFD98A3E67FCA52519
+:100C200006F88B97E40E21B4DFB268920B7415AC12
+:100C30002376B033B61F3018605D3237A5625CCFC3
+:100C40002BFC1C73494BA3315545174BF839D81968
+:100C5000D99B12AFFABE3296F19733FBCA7F8171EE
+:100C60001D7F34919111F4D085B14CFE6E337AA77B
+:100C70006F867AC70D78DF68EFFE5FEF877793970F
+:100C80001C738C03BFE09458B60FDA0EBE520F717E
+:100C9000C16D1F82D4A2726663B168A0FDBE451CFF
+:100CA000CCAF7798FDBDD6903F94B812609E37C503
+:100CB00032BEFDD60183E6DCEC2DFEBEEFF5B18C35
+:100CC0000FA5C632BFDAD603B9090B70FFB947C406
+:100CD000821FF064473D6C45C50FA8E86F930F6F06
+:100CE0009D3E86FE737297C10ECBED38FC8208F3F1
+:100CF000759C21244E203DF4390A6FAC1ADE5B5DF1
+:100D00000C1E1DC76ED8AF0AFEA904FE7106CDBF2A
+:100D1000D52EC5433C98827F651E4AFF8E16E2DAC7
+:100D200060C1ADE4DAFA15FE68E5EF314CB013E5C9
+:100D3000EF33205D6EB7B96E89C5726F0AE4CFECF0
+:100D4000637AD2362E4F4972F170C09FB24EF3795A
+:100D5000AA8CA7B7FEEFE7E354D2AF4BD7AFC80ECC
+:100D60002FD2CD76164FEEF006CCE91077D6968EC0
+:100D70007F9F4A15977B3F8EFF8CF6FDC2B60E8390
+:100D800001EE8F55EF10E250DDEDA7BE1DA233A995
+:100D900005E9AFED18C17D5CDEFC5DE68FA4729FB6
+:100DA000BFEB86E7EBB07FF839FB2081A693FD1BF4
+:100DB000560E41FC066CB0AFC278A2FB06D2DA46F2
+:100DC00023D0EB92652C2DE5E7D54B9ADCB83F4B51
+:100DD000D6B378C465B1A94C3E737A2586E8C1F8CC
+:100DE000DEBA4D7B8FF01F5C7E9E6D7D6A0FF44BEB
+:100DF000E9EBFB808F9BDA9E5807C355E8F5EC467C
+:100E000019E194456BCFF33DB1CCCFB8FD30A3F7DA
+:100E1000C91BE55C784F6CB297D8C1BFFDD6C64DF3
+:100E200022F0EFB7809E53D93E07797B66DF6331AE
+:100E3000DF07F9D66920E047DF6624655B54FB6273
+:100E4000EF863734FBB7BCB96E3AFAEB3BE205E00C
+:100E5000F3CABE55F0BECDE8BC0DF7FF9DBAFD9FAD
+:100E6000CFDAB7C2BAD07A4FF1FDFFD434BAFFE976
+:100E7000A7B88D7102C0D9668CFCCEDC4BDF90FE2A
+:100E8000427CB5A3075F7D2996F91F6CE9B4FFEAA0
+:100E90003B2EA1FF21343E4E374FE52B74932A00A1
+:100EA000FE1BE90A8E007C51BC023D533D7AFECC0C
+:100EB0000CDC9507243CFFE1E74B3C2E0477946A59
+:100EC000BF86F999B26FDD6FC038B2F26B57829E60
+:100ED0009F50E845FA3C2BB887C753797616F671D0
+:100EE000047EB08EE3E38AECEEEB7DFFC140CF657C
+:100EF000D46284F990F5821DD6452977AC67EFBDA1
+:100F00001EE6F094EF87BF2DBE833DDE213DCCF081
+:100F10001D34425CEB281F936344C8C5FD400CB7E9
+:100F20000F867DB684CAAFFB55F2EBACDC8874AAA1
+:100F3000E0E123CEB7AEC4B1793FCEC7E9071F5D6C
+:100F4000A20AFF8224096C3F8B02DBE722C03FBB71
+:100F5000EFA6DB90DEEF884CEF76B0B7E2E1EF472B
+:100F60006D40FA8C9B66C77B2F4F49CEA8388D7E8B
+:100F7000E4C374EFA667D0CE03FA85FDDE1BFD97B0
+:100F800001FD930874EFA374AF5A3F850E285DFCF2
+:100F90001DF0A57CD7D385720EA9E0659BEE1C736E
+:100FA000AA9DE1E9FF00528D6EB5008000000000AF
+:100FB0001F8B08000000000000FFBD7D097C54D598
+:100FC000D5F87DF366C93233994C76B230490CA01E
+:100FD0002C0E4980B0D84E08204A88C352D7A0931F
+:100FE00000094B36109556948120068B18152DB6A6
+:100FF000208385EF431B6D10A858832610112D62A6
+:10100000DCB17FA54190454122A81FED87F53BE764
+:10101000DC7B33336F26026AFFE1C7EFE6DE77DF62
+:101020005DCE7ECF39F7C56ED3313684310763AEDE
+:10103000E6018C7D8F3FBFF4978C2DA1E77337CFEE
+:101040005E712482D1CFF7F0BFBA795E50BD76C70A
+:10105000AF571CE9E7AFCFC55F52E0FF71A66789C4
+:101060008C55F147AC4CEF89B525C0FB119DD66C72
+:1010700098B466E2196384039F781983F66F631C42
+:10108000543EAA6FDED32B1FCA31CCE985A6399B0B
+:1010900033158F99B105361BAD67F927D393DDB0B2
+:1010A000DE46C6C6E3BA9BC57C72DDD93685C699D5
+:1010B000E029738F898367664F9E7BA0FFF90766DF
+:1010C0004F966D88BF3EA170BEEA18404B8CC47E1F
+:1010D0006355980CE69FBFC9E4336532B6059FC4DB
+:1010E000C32ADBA37C9B32FDEFD9F4CCA5B73396A2
+:1010F0006BCBA475C1EA5AB1EE58686497C1BCDFE6
+:101100006696B59BE1D1D51DDEE281B08F2D46EF0D
+:10111000D489993898F31A1CFF9A629DED01586A98
+:10112000ACCBA63807D092695EB68FCF9397EDEC23
+:10113000CFB2A1EE70E6B92D8C8D12F862AD30C938
+:10114000703F1C42F1C6E1D9135E17207C86501710
+:101150007A7EE2D5A81B7D66FFF34401BF2F63783A
+:10116000F9ADC1D3DB660E1D27603E554966CCCA7A
+:101170003C4B555CFF2866DBE4F03F778C622E1C0D
+:101180007F9A1857B6CBFA8FA6AFAE10FA9A867828
+:10119000AD8EE822BAEA53D06974C0BC4C19DD8B1D
+:1011A000C1FA98EEDA5EAC80BAEA71BD0048552902
+:1011B000E0EBC7F6848D33D7239ED90113CBC90C3E
+:1011C000DD67B5CDC0E1B6D130FA66E897E065B825
+:1011D00003C08B83E38535DE8AF86BDC686288D7D1
+:1011E0006F6339DCAC53D96803F4B7427F24F7C688
+:1011F000A99E035741BD31D9E850609E13862EC287
+:10120000FB89ABA08DE8C3AD20BE4FBC3AE29ADFAC
+:1012100040BB77A28EE5C08B5B8DB005A4C3BFA792
+:10122000F9362948A72DC427F3C7B2C12678DEBEF8
+:101230006918D1D5ACE22C05E976CEE658059FDBDE
+:10124000C7D8742AF3EF63D84295E813F8A0DE16E6
+:10125000808F61DE3A15E1D53BCE936C8865EC1149
+:10126000DB35E323D281CE3259241BCCD843505FE7
+:1012700009706BB4BB14164BF506730AF121632396
+:1012800008AEAD0CF0D418D55D774560FF2C5E7FBD
+:10129000A4F1EA868634C69E897135229E3E30BB13
+:1012A0001FC1F98726D5A944E782AE7F80CE7E1282
+:1012B000BDD42E2C6287F3E0F70E660EA41B904778
+:1012C000B76E06F895E83D9B705D35BD8E3E8EC3CA
+:1012D000D5B67C65F484A17BB98E782117D8C78CEC
+:1012E000F011EFAE53CBCD7EB9B3C566174CED52BE
+:1012F000265BFCFC8672EB7933973B59509A229817
+:10130000D762C77E3EA223ACC7E4FAE5D1CA62DD4C
+:10131000785F183E7E0D89EB6794CFACE57FFFF2D6
+:101320009BA1D01F7F57899F5EE3FCC4E5F5A3C551
+:101330009F26223C9093F0BDDBC51CEB973ADFEA79
+:101340008B74B95F659BA03ED864F42A31B86DE612
+:10135000B0258AF1900D5B9456CB20A8FF4B612EEF
+:10136000C0C3E97FA954AEBFD73D3E13DEAFD9A1BC
+:10137000732E857E352D0AF183B337F345001D3773
+:101380004759073118AF70B7D96580F6D34A04C9F9
+:10139000659C00D76190EB2FE8CA6882E7F52DC005
+:1013A0007F503D5D08A8C6F5EA9D316C801FBE8365
+:1013B000DE7CB41FEC00DA1B9DC8674F45F2F19F3D
+:1013C0008ACCF081108352BEE788014A6159826E4F
+:1013D000F47AC662004F5078B11CB530DBA5073CEB
+:1013E0002B7AE63500BE4675B5AA089FAC2E878ECF
+:1013F00099FDF3E9BB18ED3B4BEFD03903F4D5D69B
+:10140000BDCFAB7A80EBD0318DF52A9489319E6FB8
+:1014100010DE2346D5D5637B5CB157F540FF7CA534
+:101420006EB705E9EC1AE644B92AF924AE93B5C1C2
+:101430007259EC814E9715DA471C77B50D80FDC7C0
+:10144000B89982E349FD0D7CC662910EE35DCA4402
+:101450001867E83F18C1478EB375EF6805F93EBEBF
+:10146000638CE218104AE76B98E3B738AE779FCEEB
+:1014700089F8753433D70694137FBA620CC24BF6E1
+:10148000EF1DCBF5CA488FA7084415EE2706E71DC8
+:101490007EA36FB701D6336C9677B7D111B09FD9C1
+:1014A0008CC64BEDF4D23E520E780AB1CCB6C6D201
+:1014B00038238EB7B60D807E4975B01F684FEF7820
+:1014C0004F41B8A6D7752888CFAD7B77D17AD33A6C
+:1014D000DA7929F8EB79611774DB03561DED23DB0C
+:1014E000CAF5CDF2535C6F66C77AB2AD09FE7D2CAA
+:1014F0002FF424D7C1F86BF66675EF17E5EE952843
+:10150000E403E4526EAC91C6B9CBEAE98FFBABBD04
+:10151000B1730FD2E0F37BDFB1127FB4C4137E133B
+:10152000F77D4AF8485C48BA98ADD9375F4179B140
+:10153000A61470A684C259CA8D35B87EA21F5BF46A
+:1015400024A0CF27ED9E82D8407BA5CC1E9D1520E0
+:1015500097E47B8F2F66EE19B09061EDE55B59162D
+:10156000C9F77EB101F27DC2C0FB22919E9A2C2E5A
+:1015700017B69F56D88D38CF335842FB33065E9747
+:10158000F07A40E0333B7652B6750887930DE8F861
+:101590009948DE4F2B8FEE8DD509BB83D30BEBE043
+:1015A000F482FB08B4BF66C6723C8C74798AF49CE2
+:1015B0004EA6E2FE8617F87623DD0E1BEFDD8DF4D6
+:1015C0009FCE049D8CE774A2A5F7DB63B97C1D71E7
+:1015D000BC8B21DCF315E60E67EF54C672BB29BE47
+:1015E0006334D10FF04319CE3734B54E35A0DC66E5
+:1015F000B609A87F7E13EBA07E7905AEDD486F3675
+:10160000979BF879BED9C6E92693D307BC3F271C20
+:101610003F6D433E1AE0E7A378A44773283DDE26DA
+:10162000E0F41B01DFD0F13D77E1F8F11D3A9702BC
+:10163000830C3B60F631E83A6C01E849E45306F468
+:101640000F0BB4CFB215229FA5563915C4EB02B3C8
+:10165000FB1EDCD772948DF948CF3A5F3DBC976C86
+:101660007311FE7EB49E6867116C68909DF5402CE6
+:10167000B7E35795A1BC7EFA5B23CA5387E4BFBD8D
+:10168000B9D1E501F4F1C7507C3F120EDF5A39A7FA
+:10169000C5B75F2E04CB3980D75A8E0F6EE7C77758
+:1016A0002C50B97C08966B3DE123443E083CFCC1BC
+:1016B000ECDA84EBCCC64540E91DCDFA617B4FFAEC
+:1016C000F8C558F34FB3672FAC8F5F8C4D08D5C763
+:1016D000BA88AED7158047758BEA50610BF58BEC55
+:1016E0002EC4FFFA66C58976E1EE1695E861FDF233
+:1016F00028D29B72BD5F6E8F19C4AE8452F03F6BCF
+:101700008F257D5A1B2BE65F06BFC0FCA76DBCBAB8
+:10171000DDE6793D500EAD6FF92612E1DC3F5971DF
+:101720001D41BB4AAB8F81851478DF84BF2908D760
+:10173000C10D2A32D6F59EAD2695F0F62E8E378C49
+:1017400075BE330AD6F5A7A6D1BA407BEBEC8EAFB7
+:101750006FDD05EBAF8DE6FAB9369AEBE7D3BBCE7A
+:10176000F7417ABB76E174927BC3F49E8F03E5DC8C
+:101770001BFD0E7339CC4A6D47FBE3D42EE5FB68A5
+:1017800000A135A29F1EED0A35CAA906DB15441C2F
+:10179000F539001F845F5B14C1AF3E07F82E93D666
+:1017A0007902D7D96E31B214683F0BFC88FDE4BAD8
+:1017B0007FC47ACF845F6F9AED68B4A00BD5BFBEAB
+:1017C0006EBC201E607CD5A2A77D9C66514EC4676E
+:1017D000B3D1C510FFDE83C23E1078AB113477BAA7
+:1017E00065C8010FEC6FFD813427BE7F7AC7D948E9
+:1017F0009D19ED478F6A877DA9E95D56D487BB5B4C
+:10180000CE5EDE3980E49BC10EEB3BBBEFB0DD3337
+:10181000E047EDCF6ABF88FDD5EACD0D817622AADB
+:101820005952941A3A525ADAFEA90C22FE63280F32
+:10183000BD19CC570FFB5E3E50D0D354E640BED707
+:10184000E27BBBCD9D610FE0DBCD36B703D785F3DF
+:10185000A4E6D23EB3B03EE8CDE979061DEE6F0CAA
+:1018600043BD29ED3DB94FB4C72373FDFB93F65E2D
+:10187000F7FE73CE0FDAC768DF83EC740E742CC5E5
+:10188000735A2D2885073203F7DF4A78A916FBAC77
+:101890008E30B7AAB02FB6CD70B253CA83ACD07D0C
+:1018A000009E86F37D380F7810CF7F373BEB114ECB
+:1018B000FA0E1BDAAFB0AF91B80F5650968C70F895
+:1018C000C0EC9A8CF2FE99258CE8FAF4B3CCF714AC
+:1018D0006C7A4BBB8EE86603BB82E8FF0ADD995B3E
+:1018E000DD66E2EBB1F87E7E47A30EE56F8ECFA1F9
+:1018F00043B97A7947B34E47F4E0192FE074560F95
+:10190000EBEBDF54A7FE48BA98149E2E42F0F6ABDC
+:1019100040BC49B88D12F4300AE18632B94B7FB22F
+:1019200033C20F37C00B4BB5878EC7586706C2A9A5
+:10193000EDC5637D3A61BC9A978FDD8A70A9F9ABDA
+:10194000898861CC5F2F8F41BAFFB230BC5D737262
+:10195000719D5B0FC478AB3D8BE47B15EB30A2BD72
+:101960000072DDAD0F90EBD28EDB67E828C6F1F791
+:101970000D51D91280F359E7B02416465FC8723F63
+:10198000DA6D39007FF455E1F9E4C5FC186E47DAE9
+:1019900083FC5AB2DCB778967B8CA1E7F1F60D8E0A
+:1019A000247F4EB1C61E7AC8CEED8DA7ED5CCF81E7
+:1019B0006076E13A4FFDC5E2F342D3A9DCF7AD0C06
+:1019C000E0746ADBBB795EA0A353ACE3F69790DFCB
+:1019D000BE36D3B9AE78F0FB794B2C7EFEBC8AFBC9
+:1019E00052D8552FBC697540FFE22DBBE3BD01F015
+:1019F000BB8AE9BFEEA6EB4C9C97EF8FE93BFB203F
+:101A00003ED84B27121D5016BFF86A3CA703383743
+:101A10000D45FF14E78F3F635380DD5DBCB0C63DCD
+:101A2000262FC01F732E92F902EBFA0E231E89ABEC
+:101A3000CF99A9FD76BB259EE44D2FD60BE54D8FA2
+:101A4000F0BA48786ADB253CF70D3E9181F6C597E0
+:101A50003DD8C507ECC17EAF37167BDC6372FCF561
+:101A6000BF7DA7DEE60EF35E8B18FFAC737812DA4B
+:101A70007DC5C6D6CBC2F9E1E439530BA737CE57A3
+:101A800046E3B87F39671A1F6E5DDBEDBA9FE63F0C
+:101A9000D807AB0AB00B4BF49E37EDDC5FB06A326F
+:101AA000D46B2E3F3B8ECED9925E84DCBB8A79DB31
+:101AB000907FB5F421F1FDBEC45B2A4B45BC3D6966
+:101AC0007770BA11FC20F9430B476D39C1C83CE16E
+:101AD000CE03CF75C3359279411EDEBEC1407AFE7A
+:101AE000CDF31F4ECD037A3FB6D6605B0A53CE5A74
+:101AF000B73BED51F4A70D36D914A81F73B45E8619
+:101B00007C5FB94E75233D1C5B7B7BE27428BF0074
+:101B1000FEAD8275546E3050FBAC0D7750FB09C1A1
+:101B2000D795EB12FAA3BC7CB3FD8144C4E3ACEFC0
+:101B3000EEBF1EF1B2C568EB3F18CAAA26C53D2606
+:101B400000DE73364606D5B7E8D82CDC87C42B53A5
+:101B50003CDDCF1DB01E63DC4FC4636B881FD518FE
+:101B6000C7EDCC9229B0EF9A2167C9BEDFBD278AA5
+:101B7000F4C92B6695ECC8D6C1FFF3B72BA15EF470
+:101B80009DDE49369EC0F358816786CE40A08F8A7D
+:101B9000085E2F7A514F766891452578B7825C1D93
+:101BA000434ADE651E0BFD7E21DF5347AD1E0EFD51
+:101BB000C6C61818EAA15FB4CE2966A0277F794E61
+:101BC000FF6967C07E4633971EEDE24266086A5F92
+:101BD00011657D0AED5A184C8FFAB02822F8F9D811
+:101BE000CBAE3D81F6C4585B70BBA4BF9C38A0BF90
+:101BF000FE7EB9B17BCFE78F4C807D56EC53C99EFA
+:101C0000BE905CDE8FFBCA417CBF51DA04EFBD2978
+:101C1000A0F3E6F963CB5290BE0A14867EAE63E76A
+:101C2000C3F3E55C419F8C019EFBF9F13CD139BBCC
+:101C3000BB8E6C7F5DC1BCEE3AAEFFE2E5D90FCB47
+:101C4000AB4E3BF76F68F587967FFE53FAA378F0AB
+:101C5000AB195E0B95FF85E5C92D5CFE6AE58556DF
+:101C60005FC87569D75B7D4E0DD213CF0979E2D776
+:101C700017467AFE339E8F6BE286849E8FC19E212B
+:101C8000787987EAE95C0E76D7EDD86F80D911575D
+:101C9000084B5A66CB8A46B9D664F1DC1917E0972F
+:101CA000EADFD4A843F9D1EDAF3104FB6DE4F9F5D7
+:101CB0009E38BEFFF2385E87F32B9DFB3744799246
+:101CC000F5386F2FA333307E25CBFB85FC9076AFA4
+:101CD000B477A59D2BED597D03B767B363DD417ED6
+:101CE00033D6AF5F903F18ED74E473EFAE28DAE7B8
+:101CF000678A7B10F26915733D1417A007EB0D7C02
+:101D0000FDDAF5BC1627EC13E6263B41B6CF1C1DC9
+:101D10005E9E6F8DD353FFC2C76FCA403BEEB3B612
+:101D20009B3350CE7EA6F1FFF6C40F0F0B7E7D5085
+:101D3000E89358E1277808F908EAC0EDAE2DF0FEE7
+:101D40008AC56EE2ABDF2EBE91CA47172FA4E78F7C
+:101D5000C565D2FCB6C277DCD900A7232B55D217B4
+:101D6000338DEE3EB1F0DE91081DF91B0ED799C7F9
+:101D70006F33633BA3F3E5CCC7276CF206F8011F72
+:101D8000C37D0CE9799FAF09BC5E2A9D56B34E2BEB
+:101D9000EAAD6E7A3D10A2B7DB112FA7596722F684
+:101DA000AB553AFA3429A1F33FC85CAF61BF662353
+:101DB000EB8F7CD31CC5F592B6DF9B027FABD09E28
+:101DC00085F233D45F61E4CC3B825E7B5B5DEFC424
+:101DD00091BC3393DD4EEB56294EF43ECE07E7B46B
+:101DE0000FF139C689D05F976DB575C755F879C7BA
+:101DF000FD715C187F5C4FFE1FED3AEE89E770D5F0
+:101E0000FA856429FD42C7C47E16C5D982FC44E820
+:101E10000F0FE70FBA3ADE48FBDB10D5E9C5B8A8CB
+:101E2000F7667E3E4F1AE555D0DF955ADC5888FE9E
+:101E3000B07FC6713FA67DBC2719CFF1BD928D4EF4
+:101E4000F4E35C2C3F0E6876F138814747EB58D3BA
+:101E5000E18DEC03EB4AECF0141AA134C426D2F85D
+:101E600049AC6E09E20DFA1130F2DBA37C8A3C74B6
+:101E700043973C214761A591C877DBAD1E533CBC1D
+:101E80003774465D3DFAED53AB783CE284E2E96D90
+:101E9000CF0E8D1BCB32395EF0AF88BBE66F34D0EE
+:101EA000BAF2373E46F1D1FC8D57EB950039941FBD
+:101EB0006FA0FE275E9DD39BFC181F858FBF0E88E9
+:101EC000E7F462461FE1108A8786A5BF7EF13F31A5
+:101ED000AEDC09F650B03CEF173F24206FA1FA0C9E
+:101EE000C9737D3CD7237FC07C0558D31F66C87C4F
+:101EF000850DE48FDD6A6CBE06E351DE1A1D43BC1E
+:101F0000B7EFF92BC56B67CD7050BCB6FBFD7DCF2D
+:101F10002CC7F63FCC628311FE29BE8715F4CF7C17
+:101F20001BC9E3C9DF6E32B125B0A5D96F37533C69
+:101F3000784D958EA17CD1EE1B6632E8785CDBA0F3
+:101F40002BE0F8473928F10E0464447C48BC21FC9E
+:101F5000B698316EFC02AD5FAECB807EF004DCC77C
+:101F6000966B904E7A55D915F417C8755D489F4CFD
+:101F70008AFF69FAE467D4C3B7C55F9C1E9E81746B
+:101F8000AED5C35AFDDB64715562BF0BE9E1134264
+:101F9000FE4D89D7C443307E16066FC7841C0CF0F3
+:101FA0008FDF19FF23FCE31FA11C09E31F7FC6C8B5
+:101FB000E56FA39DDD36290CBFBC27E6D7ADEE3219
+:101FC000A2FE8C6F51C2CAB36CAB51C61357E0FA74
+:101FD00064FC442B8FC3C0B711FB5FDED4BA0B7B0C
+:101FE000E5C65E168DE6DB15DFC3B937CC3C6B0466
+:101FF0009F3B16308AA33AEA18C92BA8FBB893B0C6
+:1020000095F223001F4FE0B8178A639DB615921D05
+:1020100024E35686D8E0F3F89E78D9CFF547C46F0D
+:102020007A0F7AE24F625DB0FF67B05FFC02161470
+:102030009F917199F83AAF62CC4775C4C8DFDA3B1B
+:10204000CEB304F33FBA8633E753508F29B515A2B8
+:102050003CB5CF72B661FC66F929EE9F5F3E8FF901
+:10206000962A0179059E2CCA0342BC05FA07760A16
+:10207000F9B653AC1BF4E45FE3F9BA5AE203F4A4F3
+:10208000C4876E75AB4A78ED0AAFA702F0DAFE435B
+:1020900078FD19F9F29D8BE4CB0F2F856EFE7191BF
+:1020A00074F34B8C6F0C093BDF678857ED7C4067FE
+:1020B0004783F8BE073ADB7889F1D2F9E69FA8A7F3
+:1020C00042E1FA5D7C42285C5716EBFA91BC6651FE
+:1020D000CE707AD59660FE4FE791D812865C7A1E54
+:1020E000C9FA7B3B8D8867190791EBD5E68FC8F657
+:1020F0009A16250FCF9F85BBCFD339E074DBBFE89D
+:102100001C109A07C2E79D0FE48DFC39561DD0DCE8
+:102110000AFC77A6C948277595397E370AFDF77BF3
+:102120000DCCE7A0FE11D8FF0AC6FB5FD1B4BC03FB
+:10213000FD575730BD579C4795EFB91D15837C7CE3
+:10214000C55E95F2BFD866FEBC8E452C41FF744C2F
+:10215000818E3902E019EB8A628E0078C68DB7074E
+:10216000D5E53979AE9837C1DD2BE8FDA41BB382E4
+:10217000FAA778AE087A9E3A2B37A89E5E3722A837
+:102180007FEF85A383EA99DE6B83FA67374C0EAA4B
+:10219000E734DE1CD4FF18AB7B7C14ECB33FFA5B56
+:1021A000003FCCEBEAB80CD63B43ACB7EF9AF2A0B9
+:1021B000F781FD5A311E385390C917CF8DDFAB0020
+:1021C0001C6708FFCEE5BE3941E3CF55AB887E677B
+:1021D000361A8E04FA69F4AC6B4F2AC0B9C6A73818
+:1021E0005BA15EB926F8F9EC1D1BE8BDD9BEE0F68F
+:1021F000B99B83EB83DE9CD29FE701B929BF72466E
+:1022000042B0DF8785D08999E4F499B5DCFFA57ADF
+:10221000FB6AE824185FEC27D28D43D08D293998CA
+:102220006E221DC17453F9FAD6A108072DFCA3FB39
+:1022300069E8C90BFF7E00FE1667307D69E14EFB41
+:10224000837556EC50D8EF9550B8CF6A7978792AD3
+:102250000B853B633E23D71FC1ED8F68E0FD81D91D
+:10226000F318CA89B33B16A8188763E3793CFFECDF
+:102270008EAF07ED7384892FE584C497D62504F8C3
+:102280007F647CE934C619AF64171167DCFD4F84A5
+:1022900007C8008F01F3110B9C11DD71C5487F3C0D
+:1022A000492B3F6509FAE3B904D22BFE786C3DBC9B
+:1022B0003D34E60337AE53C6E564BE8ECC2B0A939D
+:1022C0009FFC978404CC0FB447E3F9754BFB7C3A31
+:1022D00077C9BC2226F202C3D8FFA44F9AF1D714C3
+:1022E000B20B762670BDFE0A8ED76D1788BC2FA95B
+:1022F000D77B1A47C6DF7A2A955D2AC513BB942877
+:10230000E75361F4CA47093F51BF85E68F7F14A8A0
+:10231000476AEE38BB07F50BC0FD636CB758406FDA
+:102320002B7EBDFDBB682BD16BD7EBAAAF2F349CA6
+:102330008970C4D8018E2D22DFAF45E4FBC9F5D6E4
+:1023400045A4BAF479D81E9CFF27E38ADAFD8DC232
+:10235000FE71FE3ABC1764972CCFE576DB690187E6
+:102360000D166E271813B99D50AB391FD53670FB6B
+:102370000CA4D7AC9680718C8916EADFDF5C684CC0
+:10238000C47184DF6579A64276C57245217BE47706
+:10239000B6D1F4FCCF09858644E8FF6F31AF1160F8
+:1023A000886563165F8F439317FE92E8FF52C268F9
+:1023B0002A8D8936E17FB65D81F4916A7619A95D2F
+:1023C0000D1FA78A4EE4FB1A29F264B47180714292
+:1023D0006EA2DFDFC4EDD2E2B18941FEFEF78CF1DF
+:1023E000C2DFAFD0EB2E9453BF1478EFC9FFEFEAF2
+:1023F000676B47F1ADF5FFAF8CE4FE7F191F08F165
+:10240000FF3BC785F5FF231EA2ED7EFEE993D82D85
+:102410009FD2503EED307AEAF1FCD5B51DEC7868DC
+:10242000EEE7EBA4B8C0C07DD94E3C672DCF64BBAE
+:102430002C486F4B18433B7F47A76E69243C5FE9EC
+:1024400065367C3E7C2D3FBF55AE7138719B520E78
+:102450005C9DC8FD8706381F5B72F1BDC96D1827EA
+:10246000583995D9510D35B2C6222BDA456B59D85A
+:10247000F3E368414F130A7751FE764217CFB70F47
+:10248000EDA793767E21E2735897E72C8FCF717971
+:10249000422211CFA9ED3A5FB8737DB2ADE86AA4CC
+:1024A000AF81BEF0E78891C24FE632BB27E2F80366
+:1024B000B7F17CD84A297F67E8981EF03E45E07561
+:1024C000CA5A9ED7C1CE7FFFBD2AED4546E333945D
+:1024D0002B95532D3EF41355B6647A695D6EC599FC
+:1024E00083F2A2E56D37D62BF3F36DE89770FD9D6F
+:1024F0002947FB91A9C9B8FCD2B3A3529E901E8F65
+:10250000A738D464416F23F1B09C40727E6534C01B
+:10251000BB72ED925D98D7F3FE1F19C59B0EA85DA7
+:102520004371B05F017016E662A967A5E4B748A6DB
+:1025300071A68A71BCFF827923FCF3FEAAE575DAE5
+:10254000CF0103F346001D9DDE798303EDEEE5091F
+:1025500011E4CF9371DA83AAE73E5242FAAE1A5CD5
+:10256000DA4D2DD136F4839CDEF9613AC64D3EB981
+:10257000E7AC05EDD87FE8BB2C982F7C7CD1BB164F
+:1025800017C0F193452AE59DDD2AF48684FB7D89F9
+:102590001CEE1F27BA1721DC6F5BFCDDD0C03C2A84
+:1025A000B63081E879B64FA5905CB79CDD1C8D16DE
+:1025B0004A77BDBA392EA82EF540B589D5853BBFDF
+:1025C000BC24E86976D30663AA03E7F7AC42FA387D
+:1025D000AEE774747C9BC5E7CDF4AFA7BC69B011BE
+:1025E000ED837FB498582BEA337D8781E749BB8A16
+:1025F00015A00B8FC0BF769D7B5E8EA6F1663EC692
+:10260000E54719CCB510E0EB69994D7241BB8F9944
+:102610009F38C625015C67AE5018FAE3B0FF22C0B0
+:102620009F67E1FD5FA1FDA5DD679937580E48F969
+:102630005529F03CBD21F87965CB6F699C19CC43D5
+:1026400079206027699E5F730CF50AD84741ED67D2
+:10265000F6669B518F6F4914F1EDA16CD8F7F0FE2F
+:10266000AE88EC184F187E92E5C9C53622D6CF1732
+:102670004750797C31A3725122A7E3AA96B7EF4461
+:102680007BA966C716238E73C9F1819613D69B99D1
+:102690005FEF96E83DAF211ED92C25284E50B3E1BF
+:1026A000AC91EC32019F52D15E8AF0003CDCC21C3E
+:1026B000ABF13C505A65F0C7E9E0FF5B72BFC36005
+:1026C000BF80DAD1913917B55FB94FB96FF9BC5AEC
+:1026D000057A0CF3BEE48345421FCDD83869792FC3
+:1026E0000051FDCE63199DFCBC49F67891C06B5139
+:1026F000C4FD648F1785D8E3EC3DDCB7A4C74AE678
+:10270000243DA2A53B4907CC6CA0F72384BDDE4D38
+:102710006F2D0F125C243DCC5C5D68E4E69BC7C85E
+:10272000ED4A6FB2F0D726A3BF16E830C83E06BA0E
+:102730000BAA6BEDF12F0D9D19281FB476B8CCE7CD
+:10274000D4C2E76022CF5F9AE1708DB30DC0738071
+:102750007B39F985F146CA10E4DBC63D7723DF6E8D
+:10276000E47CF30F410FB3923C1149F0DCB3F49ACF
+:102770001AC47FE7125306F2B367698A1A0FFD3D48
+:10278000AB1492C3A397A61811CED3970D1E877CC6
+:102790009DCB5C34FEB43816D66E189CC4E54779E0
+:1027A0009D811963082946F40B9F6A50C82F8C9AA3
+:1027B0006422E06B96C057F58AB7ADA4AF1CF06FEA
+:1027C000285E1FE03FB3EA2A091F70EE08CBC7520C
+:1027D000AF54B166630A8C3B67651BD1319C47825D
+:1027E000FAD7B29584AFEA664D7BDDD5843FD8B980
+:1027F00011CF89B53B829FF74F127682933991BEF4
+:102800003D775A2230AF71B4804FD94AC586726B7A
+:10281000FAB2B6841BA03E7DAFEA84ED74C387850F
+:10282000FA23281FEDCCDE1CF2579C713892B09F22
+:10283000C7CAED5245EF1986EDD3E23CC3D0CFD8DD
+:10284000F59185617EDFA1732A73E411950FA2FCD7
+:102850002A1B1B3429C0BE2F33D812311EE965F361
+:1028600093C53DB88840F8D446AC247EA8457E8800
+:10287000F0F3C3348C7BA1DDF3A24279846C473042
+:10288000BD9F703426C29190B9EF33909C2E6F8A11
+:10289000A5F371F9B22223EAD5F26DB1641FC1F933
+:1028A000F4BDCB86FAF1796859DE9E6418B7BC395D
+:1028B000D3A906E331F4DC19B0CE390D8724FE8E9E
+:1028C000F480BF23E1F007780B6A2F4F127249E0C2
+:1028D0008D2D8A23BD5A3AEFD59C0858D799BA480E
+:1028E000CA93ECE97CC4668CA0FC03E9BF1ADFAB99
+:1028F000DBCF44793E67570E21FC69F136FEDFD30A
+:1029000087A1BDCBFE6E6168674DCB66B74D86F67D
+:10291000DB14CE6FD3EAAF198F76C4DD495C9EBD60
+:102920000572D0D597B1B7410EBA400EBE0BF21169
+:10293000EBEF2F4EA6FA878B1D547EB4B81F954738
+:1029400084BF5FF21D1002D1ED92242E179724C987
+:10295000F8FA82643469C6FFFBDD213A1BDE676C3E
+:102960009B30369DB1EB5CC1FAF7C6A9C1FAB5D36D
+:10297000601B978CE7DB150AD9A3E5EE9141FDE1D9
+:10298000DC64C47B2BAC5F9EBF9DF486C33819E822
+:10299000F1A6E2B8A0FED737A406D59F4872D0FAB8
+:1029A000268DCF0E6ABFB9B47F50BDEC9C9131A487
+:1029B000774701F1CF0291670407778E171BEFFB72
+:1029C00075DDB0A4BB60BD5FEF33D0732D3E245ED8
+:1029D00067AC519907C69BBE06E41F2CF148E3740F
+:1029E000E2AF2F0E58E85CB2BC296F7F01D40F35DF
+:1029F00019280FE8D0B2B85568AF1D6A4AB032281E
+:102A00003DCB5561D7D88C2C40DE152D5B42F9A605
+:102A1000653E9393EC9776EF93B2EEC0F32A2E12B5
+:102A2000F9E43DD5D7AA10FE5C04DF6722E95EE138
+:102A300071B027F12AE1F44EBEAEE30A5B86F513CE
+:102A4000911FF7B90BD6716A6263850EFD15EABE58
+:102A500004929FCFAB0CE9B6749E81F20C66BFAFB7
+:102A60006EC03A53725339BE55CAA366CF98687C7C
+:102A7000D6051402FD163C6D7AEA01AEFF787DFBA7
+:102A800040DF03823E918E8EC732572C2D56A1F522
+:102A90007EFE76C2067CEE87A76F10EE7BBDC1FD81
+:102AA0006612E0EFF30ADF20926F8B1288AFB470EA
+:102AB0003F62E4F2CB8B7CA0F8E5A69FCF96927E96
+:102AC000986E70263A496EE5A7A0DC3AB2D24076FD
+:102AD00030D3BBAC93488F3E4F742CE739A2778C30
+:102AE000C3F51D69C864985F51BE52A5F30AD21F91
+:102AF000EFEFE3E7D487550FD824CCDBA07858520A
+:102B000028DDDC3E6F18E55D6AED6D597E09BCEA93
+:102B100009B04BE6ECE479812CBF533F7560E03E91
+:102B200096F1F93C0541F94A5559AF1D34EBC82ED1
+:102B30008CC173C289F754A2B313598D4393019F7B
+:102B40002775BB86DE05F52F267A8FEAA13E22DAAD
+:102B5000F32F84EB5CDDCA0C250BF3FA0FAF1A09D7
+:102B6000EF7DFEACC1496C2EECFC39CFCCEEFD43C1
+:102B7000F615D81BBDB8DDE14AC1FBCF731DCD1AD8
+:102B80007B80C3C78149200017DB6A056D377678E3
+:102B900088E5013C574FD7314FE079E0B0C8E3B149
+:102BA00024F373A8B41BA6247339335DC7E99BBD16
+:102BB000AC707A03FB2A500F48B93D17F3AA55BFF2
+:102BC0001E9072BB8A3552FE8A2399DB2FB3151FE4
+:102BD000D9DD35988902FD2B6C3C6856B5D9E4F3F4
+:102BE00065D298B640FB607A329727738CCF3E8EC1
+:102BF000E45BC93AF83E35FD3E37F82A3A3243F5F0
+:102C00004F856DC3323B8D6F70A29FB752F06B75CD
+:102C1000A3E26B253B85EB51E9579D29F4A8563F6C
+:102C200085E8258D3E9AA9D1BBAC3158CFC27AE94F
+:102C3000DEB25CAF769DEE680BC1610EAC0BF56F3A
+:102C400085C7B7A784D6AD3801A321EBA964EE31BF
+:102C5000B1B80F78DEEA085D9F765F21EB15FBD4F3
+:102C6000AEBBC2F9552BE6BB543529042FED3E24EB
+:102C70003EB4769CC44B8597C3B7A245217C7ED6D3
+:102C80006D1F32F26F4BBA61CDF02FE07D4947B036
+:102C9000AF12946F95AB411E6786D2D31CD66C459C
+:102CA000BAA961ADCB5390DF5A9BAF1F8E7E86B51C
+:102CB0006FD3F9A9D4DE9AA38B05507A73578EBFD0
+:102CC000CA4FE7178A27FC5CF0C3DDE9A59F1EE029
+:102CD0003573A3EA8A1C14D44FE43F7A098EB3BC3F
+:102CE0005E23FA6367093FE585D659ABE7F75F2EA8
+:102CF000B85E01CF9F7BDD0F27F76477853F17769E
+:102D0000DB5B1A3DFFB181FB5BA57CFE5AEF22FF26
+:102D10002EB40B3BACCEC6E37D1AB99E9E4F72BD5E
+:102D200042E87939CFD1355B295E3013ED8080F6EA
+:102D3000CF566FA578A5F1D99956B4CB8FAE99BE71
+:102D40000AF3528F364D27BD5FF97BA9F73DC64088
+:102D50007BA2684DD9FA7B908E3747525CB1A2DDD9
+:102D600023CE452067A19F630D97AB6C3597B39534
+:102D7000A81F07907EEC8BFDEEACF0F4457E086852
+:102D800027BD79E774CF9F77C2B877FE29DAE925A6
+:102D900050D85A7564CFDB5A513F56CFFFF020DE32
+:102DA000D3017BE0FD5F4B7B00AA45064F5B32EA17
+:102DB00021610754AB1B326C683708BDF11F807F5F
+:102DC0004478F8E712FCCB11FE01F1DB4F1B389C75
+:102DD000A76BE07F7825C7CBF2A66C2B9E2F3F6DAB
+:102DE000C826BBEBD3A61C82FF8C0700FEDC5F1F4E
+:102DF0006C773500FCF17C81F087F596B73B04FCDD
+:102E00009D1CFE0D1CEE6C252F6784C0D94BF95715
+:102E100077FED1E4443BE278642BD957C7B7A8AC1E
+:102E20003EC02E9376D137ACF149B4DF24FC67F76E
+:102E3000E91884F2A7F4E1D7AC8887D95B785031E0
+:102E400004FECC9544F1C7EEF9BBEDA86F115FDD30
+:102E500076D445E2A986B919E9C796D70EE039427A
+:102E60007171BF458DBC6FB623F8BE19E69295DA35
+:102E7000D1C5E28C88C0F5A469EFD37918C6BDBE70
+:102E8000CDF9EAD6F9C4E75D4179B925ACD580FE24
+:102E900036D6ACD03DEDEA0585D6428671B53A5AB4
+:102EA00087334509CACBAE5675644F5619457C44E5
+:102EB000E45524897E4929DC2F909C62A3F2742476
+:102EC000237D70DA62F4E17D2A385F25E3FCDE9D24
+:102ED00026C2DB415C13C05F350A3F33A842A4B76A
+:102EE0005B18A7D35BCC7B29AE07279775A81FA7D4
+:102EF0002D3439C9CE8D8FA1F8D2CD42DEDD625E90
+:102F0000EE463D31CD6C746109E37A31F9D7301A60
+:102F1000A687F90DBD8C74EFB034A2F3593C12DFD3
+:102F2000967CF88E0858EA95608EA31F187EDDF611
+:102F30007D5C285EFCF809F64BD74685F78B0C17AD
+:102F400070505C2EF23F9B60EC2858C7A814076FA6
+:102F500077D8B83F7A2DE0C9E2C7AFB69D7979FC42
+:102F6000B20AF3B1F9F758BC241F545D50BDCAC86A
+:102F70009F4F796243F1EA34C6DE618E8188B72AB9
+:102F8000942178EE2F8BF1617CEF3AF487DBB1D49A
+:102F900013BD4CD633AF8E970D663B0EC7FDE325B0
+:102FA000029EBF2A60AD3100F7D6D783FDF337B458
+:102FB000EA5AFB027CAFD3B7B6217DEA221C061B7E
+:102FC000CCE31EAFE4E239A56AE9C5ADB7E289A654
+:102FD000E2D5A3A0AEE3F9AC5DBFE6FE895B805904
+:102FE000116EB7EA59BB9ACBE900E1526B7778A929
+:102FF000DF3C85E237322E20F13F18860FC4E32DE7
+:10300000627D304E8315DF3786C7D77C812FCC8C0D
+:1030100046B8CF157C3757F25B5330BF3D827804FA
+:103020003E55D02E06B8DD22CA9EF8E2A1146E47A6
+:103030003F94C2CFEFF75CE27CCCDC95417979829A
+:103040005FAA4D7C7C39FF75A27C30C54EE3CBF581
+:1030500000BD7E8AE3E8400220BD1E69AC27FB6804
+:10306000160B88C365FAFB49BA0EAD77CB11DDF7B5
+:10307000581ABB6620E8955F443A518EDE626CCEEA
+:10308000A93387F69371E652D661A0EF03493F99C1
+:10309000D03F635533E535952AFC1EF4E9428B5742
+:1030A0000776E2C722BE7B06EC469CA73456A1FCFD
+:1030B000AF69317796205F975A8D7A2C3F16F1DFF2
+:1030C0005B59178DFF892D2BE60686DF4D5031E6C3
+:1030D000070BF8A4D805FBAD47F9C3EB2B5D69E4FA
+:1030E0008D12F54FF7615C66EA79A003AA1F2E7670
+:1030F000C1BCA75F15CFD991627C7EFA3E41CFDE7D
+:10310000E334DEE9C7E4F353FCF90AF9FC2B5E7FF4
+:10311000508E2FEA0F6B9E2FD13C7F82D75B9FF89A
+:10312000AAD88BF6EB684EDAA523149257462137BE
+:103130004A97B6129C4B75BB78399AB5EAF22FDCE8
+:10314000EF648ADB989280F7CE8F58500FFF33D50B
+:10315000654C817E9F2679FE86E59C498AD78872D8
+:10316000F73D1FE985921EF2278D42AE9FEAE5A644
+:10317000F7A51E8371DEC3F12F759CBB43C7F9E42D
+:10318000C78C734D6AC838477FCCBEFE9CCAE12409
+:10319000C791765171BA4BE985FC3A666490BF706D
+:1031A000EEBDCE18F44B31CC7703D0CF5DDA9C91D5
+:1031B00007E3CF7DEEC58C0AB49B84BEAF39A7323E
+:1031C00017C8A3DA730A955FB47D64C47BB335DB9B
+:1031D000DA8CE3A05F2D944501EBAA12EB047DA7E6
+:1031E0009F1CA0A78DBD74426E3CCCF3329E3BA1C8
+:1031F000477CCED5351FFD3DEAEF114AD8F8F2974E
+:10320000627F077BB81F61EEC5E551616F5734EEF1
+:10321000F314063960FCA2FAF0F902BF12EB28158C
+:10322000FA6FFA504B8403E03CE43D1E5FAF589BBD
+:10323000998BFE6263F2E804825B8F7ED62EEE6786
+:103240006DE17ED6527BC702FC4E99BB57EC83F8EA
+:10325000DDB209BF937C062C0BEF8E37C97ABF898C
+:103260006346713F18D6F37E9FF920F2CDDE286EBB
+:10327000CF4E1B36300AE5436766B4CE06FCAC4F32
+:103280002A73F74AC0F6ABC6617BA1C9D2A78CE00E
+:10329000CB882EF449EEFEB84EEC8FFE118FB1357F
+:1032A000E106D887E70D95EE037806457BC2C5CBCE
+:1032B0002FEFC5E5B9BB978DE0B15707EBCCF5AF64
+:1032C00043CE0F76FD820E18EFC8D294C10F38306E
+:1032D0001E53785DAF04FFFCB3923CA302E73FA20C
+:1032E000637DF06871B1EB182EF0711DC2064AF7CC
+:1032F00028A0B780F3DEE431D141F5A9C571CC1522
+:10330000E8BF9D9A1A54BFB1343BA8FFCD33FA07EA
+:103310003D9F68EAC8AF0BB0677BB697BC049F5A65
+:103320008B250AEDBA4F5ABEF9E016B40337AA4E00
+:10333000B45967EFDCF4C148E87506F01B477E49D5
+:1033400007F9D13E9779747A973E307E748A75502A
+:10335000BEA23CD75E6CDC68AEAD9DF2097FAE7854
+:10336000D1BC5EE2FC9BCB72513F9EA97B9FFC7956
+:103370003566BECF532F1EE2DF2D44BD02747F356C
+:10338000BE88F6E23910FCC0FF453B0E519CCD864D
+:10339000C14DB4F7D3E6E9F1FE642D94A85FC68170
+:1033A000DC8A01BAE9686303B761DE48A685DBE51C
+:1033B000E7A690BF7C6F14F7FBEC4D8CA5EF48CCD3
+:1033C0006DB886DA6BCE45D3F86FA91DE3282FFAC6
+:1033D0000585E2131353A72DC5FDEC8DF20EB81D24
+:1033E000E69DF8E7ABC723DC6AB6F17B0213D5771D
+:1033F000F2E74159D5780DBD3F51657B15B01F628D
+:10340000CEDD42E34E441B00EAEA50CB03A89755B9
+:10341000636B9F3FA0BC315A48DED49E8BA4F72635
+:103420001471FDFD7B214F0C9D7C5D63CF4DA2E7A8
+:10343000922E7CBDB282F2F70D091BF5F8BD214337
+:10344000A742FDAF3DD79F4AB9DF37FAFD91BE2FA6
+:103450006048F87A1CE68DBE11AFD8C82CD1C8E3FD
+:10346000B375C362581879D53DCF399E6F6C3AC792
+:10347000F38FFF3BCDF517E4C392459D7A8C17314E
+:1034800073840DE1555230D85111C067EAAE9B8C60
+:10349000881FC3EAB78DA8AF4D5016053CAF16F98B
+:1034A000585A79DD22E483FC8E9BD43F2C7906D1D7
+:1034B000E7AD3641A0828F9E167C2CDFEFA0330E45
+:1034C000E0713BF7F3B7A679DE4239D151C86E7C83
+:1034D0009EE4674706C6697EAEF5039E2314B21BC1
+:1034E0003B29AFBEA4C0A1C3F8C07BDD7A87F3F34C
+:1034F00085F6D126F6FD96CA16E2B86FFDF2971D45
+:103500002E18AFEDEEBC3CD40B72DECF7AF17B0B04
+:10351000CCD6751ECF87B52F473B90EF27E2E10C45
+:10352000E3A23B4D746E81768A77D4BE6C7A0AEF43
+:10353000BBD55AE1FC0AF317BD12D98A74DCF64AEE
+:10354000A41EF5C71DBD3D9F217C8A5EE93B06CFC9
+:103550008BAE16939E91FDE33A4AF2B687F55E482C
+:103560007E69E94CF2A7A781F34B99A0D372C17F82
+:103570001EC14767EB92880FCF2E8245633C759141
+:1035800032701BDA0B0E0B7D974EF2E5443C1F4167
+:10359000FBC4FEB1748FA1EA5C6C101F569FCB1464
+:1035A000FC1D47ED92DFCA059F98847D3143D0B55D
+:1035B000B45B243FB2744F622AEC63623DF0BD9568
+:1035C000E2FEF9C84F7EBA31DA90BE806E922B02CD
+:1035D000F8A7BEED2686768A29DE4D743303CA40ED
+:1035E0003B6566B79D621B9708EB2F5996A9C37B75
+:1035F0009BF2796AEAA5D17F44AAC82730B7E6A032
+:103600005D6BA88B74E27D9A33F13C1E347F058795
+:10361000E37C83BB08ED8CF94F28E43F43FB03E5D3
+:10362000D2D00375C640BFCA4DE706513C7DCAB92A
+:10363000CBA834267B2E4738949DBB5EE06BD08FA1
+:103640008A3F0E7171BF92C167726EC844BF9247C4
+:10365000453C1F4F67B64703E37D6B54F28FC9B8F3
+:10366000A4F43399F0DE4F803EFD46DF9841DFA39E
+:10367000D1FA9D0AB9FE3FB9D140FABFAAED9DA18A
+:103680003A78FE79A62B09F5C97A83A708F733673C
+:10369000B2EF3903D4E73EB8D53ADCE18767B3BE71
+:1036A0003507F56933C011FD5FCD2BD5F13E6EF7BF
+:1036B00044F3381AA76F49CF5A3A9F732E9BE07391
+:1036C000B6CE447AE82CD02D0BD04352EF48392F98
+:1036D000F58FA4EB6A3D975FD5E618CA23F3EB9DFF
+:1036E00049EE42A4BB7E3C1FD0AF779E5A3502F90B
+:1036F000E0743CE55D4BBD21F9E085C5C9944724E4
+:10370000F592E40329CFA57C97742FF5D6E83FFD09
+:10371000EFD6BFC3AF93D23C77A5027D5DABE7FA8E
+:10372000EB5ABD85E8676CFC243DD2CDC5CBD143B7
+:10373000428E1E0A92A3353DE88145A9527E5E1C49
+:103740001FCC117C33DEC4ED4894F381E3B5A68D24
+:103750007E08F7B13A95EBD99F6BDD3DC9FFD5A93E
+:103760009726FF97A45E9CFCFFEF54FE9D0AADBC1C
+:10377000C70F71A3BC3FBDF3721FEA83830CF40330
+:10378000EAC19668C726A10F485F44C5F87E481F66
+:1037900014F69EFEDFA9E1F5C1666CFFB1FA40D2D6
+:1037A00097E41BC927922FB47C24F962C26FE1BC55
+:1037B00088787A8BDF8FAAD67B9B280EE9881E8CAF
+:1037C000FCD96DC76D5388DF42F484E01F3FBF040E
+:1037D000EB0DC91F925F24FF540BFE9829F843F2AA
+:1037E000C56EB5F9D111980A90E6F908E588E49319
+:1037F000AAE7B5FAA147BA424F239B195FC790AE1B
+:10380000AAA10CA42B530FFC70F012F5C2BE8BA41E
+:10381000A7AFFEF3F4F4550FF474E6A7D053A81D38
+:10382000FB61BE03D673361FE46DA69FDE26FC8DBA
+:1038300071FB219B9F07F646F17DEE35A693FF674E
+:10384000C2F73CCF57DA033385BF41D2691ED80196
+:103850006943FCF8C7F3C0BC8B937B8467537C87B8
+:1038600011CF2733A10CB4037AB27F53D32E4DEE80
+:10387000458AFE17C2F380B49FDD6E1C90161EAF02
+:1038800003D37E025E2762A22AF92BB24B5CA3000F
+:103890003F0F89BAB74F09C2F1FA02F9FCB2552EAF
+:1038A0003DCA07D6FDDD75F477BCA5CA7ACEFE31D8
+:1038B000B09E098F32BF1F1D9E8F1D15D3ED1F5166
+:1038C00098BF7F715AD6FE95A4E71B45DE4AA79E96
+:1038D000C783443D1FEA96807A81A6BE96F7B7EA71
+:1038E0003B59603E09D28D92CBF1EC0EB01F60FACD
+:1038F000F6B3A82F6C0A43FF466DFC8657CFA25C37
+:10390000DBA1506CAA1B0EDE810407FA3E38D507F6
+:10391000EF775DC6D8CDDB78FDF6B54356792F132A
+:10392000E306DC1B32342B2ECA4728507C5999A160
+:10393000F0BE3D4DCA13B91E46F71402DE6798AFBC
+:103940007729EF77E74D67D1FBADA64B98FF8651FE
+:10395000E1EF6FAC10FDC6E4C7847DFE709ACAE14A
+:103960002FFC06343F344D690E7F9FFF09C12F1D88
+:10397000183F21784E5A85FEED0EA384B77B15C201
+:103980007B2C63417E34989FEA1BD7BA4B1AF47C98
+:10399000BB2E0DBC7E68BF77A505DB03F49B065FDD
+:1039A000A61F80F7DD61DE7704BFDFFA43F85A1205
+:1039B000F2BEA0DB59928E5D41F41EA377137DC643
+:1039C000C42B36B4A36BDC912BF1BCE0E7CFD21251
+:1039D000829B8C1384F0DFB4923103C84E12CF6FF8
+:1039E0005B85FCEBD675F7E7FC28E91AAF36015C7E
+:1039F000C9F507EFBF9C76EB2AF44F025DD073AA9E
+:103A0000EB03D6ADE5C7664D7D94867F05FF91FC3F
+:103A1000407D0070CA41F9167FC8E808A0934F04A2
+:103A20009C4E897CF28ED1DC9EECC8E2E577693C45
+:103A30002EF599A0CB53929EA202E09016443FF43B
+:103A4000F72102F64D70BA295EF2F3BD25C5C0BF5D
+:103A50001D76FEFC7FD6FE669537CD5FD78EF7CFFD
+:103A6000B5F796205CBAC7F72EDA8F76C44D026E92
+:103A7000DFADBD67BF7780C073A2FFBBAB401FF453
+:103A80003D9E6AA40F25943E5E0DA52FAFE67DFAFC
+:103A90003B043DBDFFB75079E0D2BCCFF07B10179F
+:103AA000FFBEC05BB106AFE335781DA3A997CABAC4
+:103AB0002F48FE4AB95CBEE3E1FB12E3D1AFA9D0C7
+:103AC00075243F3D3F48F43CD726E97715C1D54FD3
+:103AD000CF0FED47FA9DDC2CE9B591F4CF2494C3C8
+:103AE00023FCF5292887A8FE7009C6C5FCFAEA91CF
+:103AF0005528B76F6890FD1FA5FE372F93E3ADA63D
+:103B0000E7128F8C3D46FAEEA67CA9AF1E27B93F7F
+:103B1000A785BFEF4CFFDDFE1FE487460D5CD66A2C
+:103B2000EA5E4DFFD517D06FCB34EF2FD23C5FA9A3
+:103B3000A9AFD1D41B82DF2F9BA1101F9615F0389F
+:103B4000A5962FB5F4E14AEFB673BAF5B96226FB34
+:103B50002E88AF26D4F3FAB5E91B4B1ACC01F575C4
+:103B60009B4A385FC06C01F79F41E67A55A0074336
+:103B70000F72B320BD07B9D94FABEFF9F37FE0AFB8
+:103B80002914370AB24B76ABC1F53655ACDBBB75A1
+:103B9000FF820181F1D5E74BF05CDD631CC7DB5C84
+:103BA0003226D02E62CD25AE807DCAFEE3BEFB5EFE
+:103BB000C5F93CEBFE5CB2D18C714F11DFB4F3124E
+:103BC000F4A58AFABA56F86FC6611E2FC693A25A98
+:103BD00073E60F08D8276BEE83FB6CBB5BE5DFB7A2
+:103BE000AB07FC009CCA9883F250A73317E5A5B633
+:103BF000C5C42CFC2F786FF7DDEA42D4D30717C673
+:103C0000515ED32BE9FC7CB13BA677E24CA8B745CB
+:103C1000DF46F2B6EDFEB154EE525DCBBB6C8C2D9F
+:103C20005EF74A89F9727C1E4370BA3BFDA5922566
+:103C300040EFF7A63BE87D8FDD96B803EDED070C6E
+:103C40001437040E7892E8E741D3603C6F972DE972
+:103C50004F71B1F2C7268DC37BA4E5F719285ED258
+:103C6000A9B3919FC8F3C058CA939AB14C94DEABE4
+:103C7000A97CE5DF7FACC77BA65DEB14FA4ECD5582
+:103C80005F37FF6D10D42B1BB2E97EC6CBE774946F
+:103C900017FEE99ABE3ECC533E1C5947F9A5D09F6A
+:103CA000EEBB569E77EC2FC9C7FEAA0D53388E4245
+:103CB0003BDACF4757A84FE13DCE32AB250AF3BBE5
+:103CC0008F7EC7C8AF73F43E137DEFE653B3E7D6DC
+:103CD00035F1748F092D7D765471581580C3DAF44F
+:103CE000FD25C929D86E12F8DC6F2D033E2FD37540
+:103CF000D30FE9938A585E5FBBEECD924DB08FA390
+:103D00004FF4A57CB1840CD7BA7480D7E10CD7935B
+:103D1000548AFBD9AFFC9BC7255F3A599E88F4B5FE
+:103D200059D0F5CBE7CA1303FF6E41C5293DD1C178
+:103D30002B46C702FAEE6954BA82E76CA08338F4C6
+:103D40009BCF10E716A0E7855BC3D8574BD3B93D8F
+:103D5000D6F6DB84518E20BAFE98E4299D37A0FE6A
+:103D600062FA47A4E78E9816622E75773E24DB1D13
+:103D70004970323445FA2233D17FEA1AE7A2F34F71
+:103D8000739FC996003E14FD3FF1F2FCDF4FA03F48
+:103D90009EFB3EF1FE3F4B603C43F6AFB45ABC681D
+:103DA0005C1CB358F4888F83FAC547313FAD629DE0
+:103DB00081F440C5BA84455D287F806ED0BFA6DD02
+:103DC0009729C3C0FD183DC6573F2F199316785E3B
+:103DD0003941F2BB27BE7C37FD44C9C6013DF365BE
+:103DE000A58DCBA771EBF8F7752B8758F474BF7BC3
+:103DF000DDAB9BE81EF0BCC85CBC5751B9CE44F8A3
+:103E0000EAB458BCB62BF1BE81451F0BE5A174AED8
+:103E10004FF5190EC24791CAF411B954D23D0A198F
+:103E20003F3CB1F0D1C7311DF373E6BB7E18C0EF44
+:103E30008C8BD3E9996D2AF91FB5F1C4EAD7B71A6B
+:103E40000BD98F8827F61047AC629DE2BBE2E1E315
+:103E500089DA38E2BFD2C5BDB3EE38A281BE875140
+:103E600029E288456B155A7FE542FEBD92A238EEE5
+:103E70003F3EB218E8A02FEDDF6BCBC53C69AE7FAB
+:103E80002A99E28B805FAF5E3B8FFC9975E91C5EDF
+:103E900065E23BB087239D1978DEAF58174970AEB5
+:103EA0007C72F6074FE4E37DC089F181E76B9BA04C
+:103EB0000F189FE13D6839CEB125F7D077678BD6D3
+:103EC000C33919F3B463D973376522DE523230DE59
+:103ED00029FB552EBDBB0FEF07E76CD877D90A95A4
+:103EE0007F0F6BBB89F421F07C320BB82F3E63D976
+:103EF000EB4623D7672C79A8B0B31DFEFB6C9FC29D
+:103F000073FC0441ADB8B726E127EF5B95E9F8F7FC
+:103F1000364B750ADDC3028946F7977E91C1FDA332
+:103F20007919DCCE2DCB70D23D9EEA5526E7D24CD6
+:103F30003E4EF7BD7538E755EB3A2A28AEF9171310
+:103F4000F9576A9745BA22AD3C1FE3F9019477AD62
+:103F500037023CAA1C5C6EFC42D063AD63D2D594A0
+:103F60009FAE6707F0EF07565BB89CAC8E05B89B19
+:103F70003901E986E2F73919E553E2B8298302E607
+:103F800057443B8CE3B0FAC7DDAB630DE8A7C1FE35
+:103F9000970F4238C65D7F23AEEF5995F81A80B46B
+:103FA000AA00EDBF67D53C3C7797ADD83D0EE5F054
+:103FB000DC2D83F146052B7BEE5DD2237305FE3BA2
+:103FC000453E5A39D4F1BB81376470B9E951B9DF44
+:103FD000E806012F4907F279F50A03F7E383BC47A6
+:103FE0000153BDE4431AB7DAD2918872B87ABB8123
+:103FF000EE87DF8CEB0638972F491F7500E8AADCA7
+:104000001043DF51ADF24E3462BDAA51A1BAFFBDDB
+:10401000840CA4D32F96BD6045FA391CD99A83FA33
+:10402000A96B5EA493EE29DAB8DFEE8B653974AF25
+:104030006986ADC382DF6599B120DB8E72FCA0ADCD
+:10404000D588CF0F3667EAB0EEB2D94661DDA5BF9D
+:1040500092EA5F887C17FA41BA52389EAB9A761B77
+:10406000F1EF2FDD2BE8E2D4B3EFF6413F50754678
+:10407000471FD42F40077D5211CECF28A49F6B9AA3
+:10408000781EBCA4831AA403E0BB39820E6AB6BDB5
+:104090007017F2430DE23F37948E809EDBA9FDF945
+:1040A0000DE3187FBF1DE944EA33A82F33A03FCEAC
+:1040B000C8EB8B05FEA17D0C6FF70EE0F975DDF9FD
+:1040C00008417CD0137ED766E8043E4C2477D78A1B
+:1040D000FD76AED86E45FC9D7A76F71E8CB7543FC0
+:1040E0000FDADA11861F043C6A71FF565A3FD9195C
+:1040F000B5B85FAB7FFFDD742FF8B096F1FDC9FD59
+:10410000D6EAC5FEE573F1FE3AB1CF2A26E0B5AD99
+:104110002FE73BC167C8C7F4DD21B13F8F3DF8BB36
+:10412000BABBC5FE9A44C96CCD56840FE217E50FA1
+:10413000D08FCB28E5097439B56503E5F74B7CC909
+:10414000F5BFEFD72B2EFC9354128F9D3D7CF7B615
+:1041500045F0C9A1FB92327600FCBED84C9F0D24DD
+:104160007AD507CC27E946CE57F4A749D7E2BE61F6
+:10417000FC561C5FCE7BD01BADC7710E32CE1F72BA
+:10418000FD922F8BEAA75D3BD88AFD4E59B2D15ED6
+:1041900011787C3FC346EFBBD06E80F75D3B14F2D5
+:1041A0005F1F12E7FD43F7BD602D1FE0A7F777C53E
+:1041B000BA259DE10FFAC9E47AF7DAB93F58BB6E28
+:1041C0002987E4BA8BEEBFE15A6C97EBC7F8512010
+:1041D0009D4A384A7A95F7FAB4744B3427F5AADA2F
+:1041E000337DD7A61DA2FC9D9076ED78C23E3A2C79
+:1041F000F2CDBB9E56F97DE765C9ED41F78E1833C8
+:1042000007EA9F25F3AEB615623CB749A17B1E5263
+:10421000AFC0CF4A7D803E92F6C1F0DE3C7FA5362E
+:10422000DE7502F15975BC631C7E9244DAA5577D98
+:10423000DDAAC6A0FF6A1BCF8393745375B29DF8A5
+:10424000A15ADC932A5BF1EEC46148F74F1B28CEDC
+:104250005376DF5823DAFBB3374D1F8AE0C07B1259
+:1042600028DF4F6C1C9247E061B6C4EBF1BEC4C6B8
+:1042700047AFC7BF5F3A63874ADFA1C171908FCB59
+:10428000EEC8237FEBE1C8CE8923D0AEFFB56A43E9
+:10429000BB7EE4A6218BB0FF484BEF58FA78D0C61E
+:1042A00038AABBF431A427A41D2CF303EBC5BD90A1
+:1042B000ECDE9CAF7A75978AC80BACEF83F1F9AE50
+:1042C0000D91F4DDA852A3A3B915E7DB9944E78E5D
+:1042D0005A382625DBE99E2BD969B38C2C222597E9
+:1042E000DA233045F97543C71DA84F5EBFC33218A6
+:1042F000BF8BCBD4F343CBB97DCDE39071C1DF61EC
+:1043000092EBC8EACDE9573B9E7C7F2F9E2BEC7445
+:104310009F91DE3FB1ECE9EB511F9ED89C63C77DB6
+:104320001FDB1949F70B8E1982BFE778A9F7C2B4D2
+:10433000F7A9E43DD7FCDEC1F69CA4FB0BDECBB9AC
+:10434000ECD2F2984E2E66744FFC5C06E3FEE4E875
+:10435000EFB6627E6145A3C986F7648E20FD637C5B
+:104360006BBB4ADF01A2BBDF80AF23DBF3E83E700B
+:10437000C5C7BC5ED1ACF8F0FE72FBC3F753FEC2FA
+:104380004CB037F16A79B73DBDFAE1EB910DCE380B
+:104390003DCBF13B006736F37C8B90EF3ABCBE75AA
+:1043A0004F8AE3FFBFFD2CFD13D37B07DF4793F05C
+:1043B00096E7AA57802E0A72FDF0FB72F12CB29F8D
+:1043C0004F2EF650795A39B46A24D2B32586EE15A9
+:1043D000BCB4E35115BF7353BD6DF0793C1F8F30F2
+:1043E000C7D0F79FBE5CBC90829A2717D7893F8AB7
+:1043F000B654F8157C545EB5AD8DDEFB72475E0B8E
+:10440000DEEB7DD91CC3C59AAB20E83B9912BF3DBA
+:10441000DD5796FBFAFCD71CCF72DD9F6F9E6EC5F1
+:104420007DB5FD21AE6538E2373AC6867660A5C80F
+:104430002F39BA86DBD9C72362FEAB18F07C7CED3E
+:104440009444FC0ED1CCB6A9D7637BC54EC586E794
+:1044500003E7CE49563CCF7DA6EFB4E23DAACFD6C6
+:10446000C8FB573EFABB7B23C6B329D87F44AB9E1B
+:10447000393229844CF432FCA49EEECB7E01EDE46B
+:104480003F391F45FE13F889C37C92992F72BF4BA9
+:10449000F7F9579CFF468A7DB7F7B6CBF806B517F4
+:1044A00015F0F6636BB796D0DF4FDE68B0E1BABFA8
+:1044B000DC68A0F1E7C0B94D07EB3DBE999F83B022
+:1044C0008EE7E8139BF979674E333FEF54CF33B84B
+:1044D000F8FDD260BA2C0AE847DF2DEBE1BB23736D
+:1044E0005C7C7F73407FE27E2F44BFB1AC99EE9F2E
+:1044F0005D6A3EA9967EFFAA9117DD74DB13BD08A5
+:10450000B822FF23DD4ABA98B386C7F5EDCD830BF9
+:1045100091FE249D68BF03586F64FC3BB2BA28FA31
+:10452000EEF724B3C380FA624A7CE718044F5F07B2
+:1045300097AF6A91CE85F7E458BD29EC77C4DE15B4
+:10454000F2781ABC4BF7BB7ADBF8F7CFC47D315950
+:1045500082BE4A477D3E29DAFE8D03BA74AEFFF271
+:104560003A3DD0F5A491F63BB29D80D7F55FF37A42
+:104570009E7D7B16D43FEF7DF63A3DEC6FD295F6EB
+:104580002106A82F59F2CD7563E0B9C9E13AD83BAD
+:10459000609E139B92D2717FD07E08DBA7277A8E14
+:1045A00060592BEE8F9D56BA062DCCF4F77F7BA772
+:1045B000E5E04B0E7FBDD3C0E8BB3BA77BCBF587C7
+:1045C0002F9D0ED7A9DE09A1EDE58CDD47F97C5EB4
+:1045D0007E6F077EDC118978AF8AD35DB9BCC7D303
+:1045E000A0B9C7E3E4F7D5E4FD2A797FEA72FFFDBD
+:1045F000B3B59772FFECFF0069F3B24F0080000083
+:10460000000000001F8B08000000000000FFE57D97
+:104610000B74545596E8B955B73E492A4925845438
+:1046200025A984AA7C2B90C0257C0C3148E5030485
+:104630008858286AD4A005A2808214011D74F455FC
+:1046400061307C9AE98E9F1722462D10957178DD96
+:10465000D1B16D868F532032FC9A0EB463EB8CD3AC
+:104660001DD0D168631B3138F40C366FEF7DCE4D11
+:10467000EA562A80BEE77B6FAD975EF6619F73EEC8
+:10468000F9ECB3FF67DF5B5F192CEBA564C6240F61
+:1046900063AB53A1745A596319947BFFE9CFD26875
+:1046A000C69A83AC3B2E8FC15FA3F5D35150CF7C0C
+:1046B000BA4B502E4B481ACDC660991362D06F99F1
+:1046C00089B1AE12E8263B6DCCC2D81209FE9D011D
+:1046D000FFF9CA194B676C9515FEED44B84287F097
+:1046E0008366467F9F05983FDFC0D81F4F742539EA
+:1046F000F58C9D9D1D2E0CBB18FB65BCCFE69C0068
+:10470000ED1DCD8EA634C6BE7CC3A4D443FF9ED07F
+:10471000DF27F960FCA57AE6EF84926D1FCED824DE
+:10472000282FEAC353A0DF6157F1B68DF0BCCBA9A7
+:10473000630C9E3FEB0AE7FCF578C6822E93F232BB
+:10474000A37E773280EB1E9F3E1CFB9D7D7D5DFE30
+:104750003DB06E93CC5812EC7B068C590E7830002D
+:10476000AC2FC30742340EB40793A0BEC5F5740E38
+:10477000237C302F9BC8D80D8CEFEB0639BC1FF182
+:10478000C5946419F7379B6F0FDB83328CA33333E7
+:1047900003AEBB9875583F4D0098B18E4BC3607FF8
+:1047A00066C063329680C724C6A6EAA113ACAFE9FF
+:1047B00097FA9009D6D784781470D085237A2CD7AD
+:1047C000C3F88BC5BCCB8EBC6BC4C15810FE07EBC5
+:1047D0005922E65DDC71773D9ECB9290E14CB7C0EB
+:1047E000F525FA7F0F9DC772D1EFFEF2AD469CE230
+:1047F000FE1DDA7ECBD9A6AFF5F0FC52D66DC4FD16
+:104800002EEB8C6AEFA8F90CD7BB7C97B6BEDE996D
+:10481000988674C2C6B2B197F4544DE7BD48F49976
+:10482000AA6F74CAB89FE166C50413373D9F47F469
+:10483000C2DE0CB0C87EAC6318D14F8B4B4FE7B1D2
+:104840006497C49CE318BB7E5716734253FDAE6158
+:1048500054265DC8A0FACF5F3936DE5732705ED776
+:10486000BF6AABC6F55DFF6A1195EA3A9A041D4E20
+:10487000D5977486611DE72CB00E809B8EC0628137
+:104880007E9A6ED68718E19999B1BF572CC76B599C
+:10489000DFA54F42580E8AFD4A97243A84643C1F94
+:1048A000EF613D437A621E03B53B9979CDA55CA0CB
+:1048B0001BBB8E3963E0DF24CE2FCE19CF9CEE8157
+:1048C000763958FCB34A588761AE4109417B735C25
+:1048D000D236E43316F474E5C3730DE2B9AE384E44
+:1048E0003709EE54CDF32A1DDC2AFAAD4B9A76181F
+:1048F000E9B2C1B388E82151C9D4ACC7A45F6A400A
+:10490000FAB9D567F8A43B621CA25F58C70D5E29AF
+:1049100084FC787383B6DD50F975AD4425D4478E99
+:10492000E7D5F6FB29D203D03B107E71243D0C9CC9
+:1049300083C5A3C373F02412BDCBCCB9B912E05B1D
+:104940000E1B18EEDF14CFF7790E319786FD800F1E
+:1049500060E2758817A84F2ED7E237C5A3C5E7B028
+:104960003A2D7E867BB5FBB735E46ADA337C233596
+:10497000ED598BCB3470B6BF42D37FC4EA6A0DECDD
+:104980000ACED4F4CF5B7FA3062E68BD5DD3BFA84B
+:104990007D81A6BD38749FA67DD48E260D5CDAF984
+:1049A00088A6FF985D8F6BDAC786376ADAC71D7EE7
+:1049B0004A034FE8DAA2E97FCD07DB34ED93BA5F13
+:1049C000D3B45FDBF386069EDCBB5BD37FCA850373
+:1049D0001AB88A1DD3F4AF31FF56034FB5FEABA60C
+:1049E000FF74FBC79AF619CE3F6ADA67B9BFD1D216
+:1049F0006B3C9793D72BFFA579EE5993EFDF505F70
+:104A0000344B95DD4186F4EB243EBA354DA7840145
+:104A1000FE832A97041D9E1C612539C1F2598EB769
+:104A200014E9B0328C7C7C6E9744F2E0AB28BD2850
+:104A3000FFD1EB91A09DFD4A525E7622DD415DC41F
+:104A4000FC291E339323D639ACCEAA81877BED9AFD
+:104A5000FEB606A7A63DC3E7D6B4672D563470B69A
+:104A6000BF5CD37FC46A8F067605EB34FDF3D67B3B
+:104A70003570416B83A67F51BB4FD35E1C5AAC6926
+:104A80001FB5C3AF814B3B576BFA8FD915D4B48F89
+:104A90000DAFD7B48F3BDCAA812774B56BFA5FF3F7
+:104AA0004148D33EA97B87A6FDDA9E4E0D3CB977DF
+:104AB00097A6FF940B610D5CC58E68FAD7984F6A74
+:104AC000E0A9D60F35FDA7DB4F6BDA67383FD7B4C7
+:104AD000AB76D02CF7D7DA7A61175DAFFC59F37C4F
+:104AE000B0DAC3903E826F484AB313D6EB02E13F7F
+:104AF0009CE47C779C1EED282F18148C0129AD4175
+:104B0000FD920C420CE90A488C35A6E22840AC2004
+:104B1000B74955C1F3C9684F0090AA73B9FCA01FEB
+:104B200013D85AEBA766B21B1C9740DF5DC2BF29A2
+:104B3000834B94A09FAAEB85F966A14E023A6F724F
+:104B4000F93C2E58CF7D9DAF4FCB626827045B7038
+:104B50001DA00793BB416F9E886377794B068F3703
+:104B6000C30C788998EF485CABA3CC32F4FC33CC0F
+:104B700067A97FFFB8063EAE04FB6B8A18FFA7A0AB
+:104B8000EE65B0FB5A03C037058C3D15B012FC4CE6
+:104B9000C04E705BC049657BC04DE5968042ED1DFF
+:104BA0008172825F0878080E05EAA8DC16F052FDD3
+:104BB000F64003C1AF047C54EE082CA6F2B5809FEA
+:104BC000DA77065613FCF34090CACEC07AAA7F2348
+:104BD000D04AF09B817682DF0A84A8DC15D841E5B3
+:104BE000EE4027B5EF0DEC22F8ED4098E070E03094
+:104BF000C107025D041F0C7C40F0A140379587037C
+:104C00003D541E0DF452FBF1C0058207CE4B6B578D
+:104C10003361572E1274C0D2B83D792F3F52F685BA
+:104C20008E2D46BB7791A04343359887407786CC3D
+:104C3000C26DCD2E3C6AA01337D1C971B42FAF9687
+:104C40004ED070407A0D563337D29B5AB654E9C9CC
+:104C5000FE0CAE90422F73BB88EB6F3353F537B524
+:104C6000373E2885D09E9B0776B211F8E623619FD8
+:104C70007C14C7E5F539BFC18D765FA314AFC0665C
+:104C800001FE77B23BE02F8CA47FD75ED356B49F52
+:104C9000D4F535C2383A18E7BFEC2E5A57233B6C8F
+:104CA000C0F540BD470FFC72C6E6DBE202BABE2F7C
+:104CB0005B17342213594285DE44C68C76DFF348F5
+:104CC000E7E7FCF71CC2C1175995429CE77A537875
+:104CD000F8AD307FEF11BDB2CD39345E96B7CE005E
+:104CE000E17D99F6B73F77A01D5FF717BD0FCFE1C4
+:104CF0008421B1210474DDE99288CF3A5D3A4DD91F
+:104D000066F7FD02D7F96DA2FF4E1DA0F2DBEB5650
+:104D1000BCB212B6D4B8A22019ED55F00F0C685FE2
+:104D2000CF614E03CA879B98E75D1CEA66E623F8CD
+:104D30005616A452B6F976E1BE6E6321827D15A6A1
+:104D40009C58FB8A5ED73B38D8702C759AF290DD60
+:104D50007700C7FB36D143EB3A31697A21EE4B5DE0
+:104D60009739C349FD66B3DE17707DDFEEFBFA535A
+:104D7000296F309DFC88F4618169B03F33C2793777
+:104D800003EFE038CD0F4B21A473953E1AC14CA719
+:104D9000F11F857A29925E804ED07F4BEBCD99939F
+:104DA00048F4D24DF26F923E68047BFA842E542868
+:104DB000E9894E8C12AC73511AD049EED0F4F0C090
+:104DC0007A2823E420D0D91738DE9FFEE11A37E293
+:104DD0006DF9DB939C88B7661D9C07D073F0A89E85
+:104DE000EC042644BBFEDAD210F907B2A2CC29C5E6
+:104DF00073E37271BF9EAD7E3D86DC4DC8E5F474F1
+:104E0000C26EA80BD1B89CEFD5767D2E3F477D2E84
+:104E10003FDFA6159F2DD5C3FA4F1CF8DCE82C8D7B
+:104E2000B18FD53F79283F82AE97EF3A3DCD837E53
+:104E300017EB2EB93171A0BE50CCABD291DE98E801
+:104E4000DB6A895C573F5DC7E7225DA7005DE7111C
+:104E50005D7F8A76F96C9333F95628BB013561285A
+:104E60007D2F5AC97F5CC0142A17322F958B800C76
+:104E7000908EBDC1278D88F7FB5827D53F507E7790
+:104E80003AD2F5BD3A1FF9D94B5917D52F67BDB5A1
+:104E900078B437AF5FF3AE1D567D53EB9353914417
+:104EA0006F0CCD7F17CB39DBA54F834EE293EC5CC3
+:104EB000C047B7E47F2213E6BF7D67D51359503F43
+:104EC0005BCFCF851DE3E7A2CA91E87D035F14E0C5
+:104ED000F3DFA678685FFAA43A0D5F343ECE3C1249
+:104EE0008CD3BBCF14DAE68AE093F2FBFF9085F215
+:104EF0004CEEBD13CF7BF9DBA6543CEFFB18D7FB80
+:104F000092478DAFA8FA9E11BDDFCFE215ECF78571
+:104F1000A0EF2FB219D1F71712388A65037628CB84
+:104F2000F1D9CBF206F4F672DDCED18827D0EB951D
+:104F3000780EF77DDCD932D685FA2094837688E125
+:104F40003593D2ECD2E817762901858D9F213E7FDB
+:104F50008AE38E19BC2EA9FCD09FD1EE301959D00E
+:104F60005C467CCE26227F671A89BF9A11B57938B4
+:104F70008FD7E9B70C1EFF8458EFE1EFB83F1D84CF
+:104F8000FDBC2CC59A87EB2F53FCC03C2447D2199B
+:104F9000CD73472EE763753E66E976A09D7E34C1EA
+:104FA000773B9E8F1A4752FDC8C3AECFF2F17C66A5
+:104FB000576C50E5338DC7AEE372E984C11944F8EC
+:104FC00044954B0109D62F6F6F28FFA70F701D372F
+:104FD000982D618C77B04AC3D97EFF3577401FDFAB
+:104FE000A0EAE3CAA8F88E1AF7618A01D757CC3E27
+:104FF00052F141F11D554E0ED2BFB0B12EC49F8863
+:1050000097F5C779FEB93FCEA3C3798D428E32E6BC
+:10501000777B23F8D4D600AE8BC67F30B37C8DFF70
+:1050200060D5C0D97EBBA6FF88D54E4DBB2BE8D638
+:10503000B4E7AD573470416BB9A67F51BB47031736
+:1050400087EA34FD47EDF06AE0D2CE064DFF31BB72
+:105050007C9AF6B1E1C59AF67187FD1A7842D76A53
+:105060004DFF6B3E086ADA2775AFD7B45FDBD3AA72
+:105070008127F7B66BFA4FB910D2B457B1BFD5B488
+:10508000D7985FD7C02FC6F178E754EB3F689E9B57
+:105090006EDFAF815F88E7F19A19CE23DAE7C5F9B1
+:1050A000066F8B277E98E53EA969DFFFC8C8CD8DC6
+:1050B000C02FA14774E47FB6D5713DC51AAA391D2A
+:1050C000C4F1BED72B1F6AE6CBD1F7BA908E9D7A7A
+:1050D0006B26F2757EF99C034076ACD0B3A21AC55C
+:1050E0009DBBEEC903588EF4BE5E8D6C53D270F238
+:1050F0000096A37D5F570319336571CA3B5896F933
+:10510000C7D6D87089ABE7BC83E5C4E08A1A94B3EC
+:1051100060267EB108D67D3E38926D84752565AADD
+:10512000715E0FD1EDAA0C1DF1F9AADB2C14374BDF
+:10513000BFD622A33EDF1CE81A7910ECDCF4A7D31B
+:10514000D762DC693DD8F9A122B017C0EEC7F25989
+:10515000B0EB43E01C6D04BB1FCB4D60F763FD73E8
+:1051600060F7239CFE74D97A7C6ED5C97BEA7261A4
+:10517000FC110FCA563453D739752B0EC07AEC0F79
+:105180001AAD284B8CAE67E29CB08EEC65B08E0AEF
+:10519000428B0751FDEC52301C32391C07FDEC2BC1
+:1051A000741AB81DFF45B02E588BCF973EE9DEAE7E
+:1051B00030F6F9B6B337198A619F795DB76D4D0145
+:1051C000389779E602BED3F12C60FC93798FCD0934
+:1051D000960C8697147AFF487249EE2C463EB51617
+:1051E0007D9481EBDA50FD85A2B3E23C8FCC390887
+:1051F000EB7E7E78BC58E72373AAF2AF665CCF796A
+:1052000094EF50EFEF8C2147FE53E8FF93795C2F2A
+:10521000C39F15E5938D9308B3819D940CF276F3AB
+:10522000A4D5A7D1A790AD4109E523BB08CF4F1462
+:1052300028C823784AFC441EB247795354E433E724
+:10524000C178361FD84E91F1B1C55A78339CE71911
+:10525000C3C07A0C77E98232ECC1F0925751609E5C
+:105260008E79B05F80371BB5FE65918E917D719F01
+:10527000BAEE8B372968A7DD97C7F5F09680BBECAF
+:105280001303FA7F4AD9274047998BFD920FE4AB6D
+:10529000ADD1AB04A19FE1D2DFEF372261DFC53A88
+:1052A000519F63FD9A08BB27478C6BB8A427BC1994
+:1052B0009ABD4A6AC4FC06BDE4EF8C617795E6C9E5
+:1052C000FCB96646ED86771E969C305F666348BAE9
+:1052D00087C6F14B0AD4DBC2BC3EABB1535A08F0CF
+:1052E0001D794E3A07759CACC5B0FE083CD9E5A0C7
+:1052F0006485E7ED8F0625C483DDEA555822E2DA9E
+:105300004BFCBD52F0B47DF5C4B24F86E1BABD8A04
+:1053100017E79BA5F29BDFCA703D1F2BBFA942BDBB
+:10532000F61B3DC3FB8C6F9C4A725A8C7DA8A5A9C5
+:105330005BCF3C97F16792721EF1939EBCDDE22C2D
+:1053400000FE7DF1364BC3D6187476471EA7B375A1
+:1053500099AADEE2EB49D7733CA9FAEA1B2BA71FF7
+:10536000556EAD4CE1B03ACECAECF12437865A8F77
+:10537000AD3D8EF922D6BB19E6B1E2FDCC772BAC60
+:105380008837F021BC349FCCE5E9D6E7DDE4374629
+:10539000D3CF203E00D19B5C8674D91D6A06BA31FA
+:1053A000CD332A682FDAFE5B8B84722493B54A28AA
+:1053B000476DD9B58765D4E7B2AFD81BC38EBE128F
+:1053C0003FA8E7A9DA2583CFCFF9BB2AB2430D0C5A
+:1053D000E9B6C9E5B4E1F9A974DA746478AA2FE2F0
+:1053E0003CD70B3A2E67AD7AE4D30AD6496525EB54
+:1053F000A2F23AD64BA58759652CAB9942652DF39D
+:1054000052398DF9A9AC63AD54CE649D54D6B32EF8
+:105410002AC1BFA3D2CBACE487DE08760C96739981
+:1054200097CA5B989FCA2D48DF13F0FEA195E0DB79
+:10543000592795BB80FF9D45181F3153B917E43993
+:10544000966F833CC7320CF2DC69C2F8889BCA8332
+:105450000185CA4381722A0F073CD4EF68A08ECA27
+:10546000E3012F9527020D5476057CD4EF5460316B
+:1054700095EF05FC54BE1F584DE507812095FF129E
+:10548000584F659111E40AE2DBDD3D16FD9A9C8FD1
+:105490008D1E27E8A34FF384FFEBD1FDF7E2F178EF
+:1054A0008E3ABA83B1D5AE94901E6D6E9D2704E5F9
+:1054B000467793743794EB4E703BD6644B243BD9BC
+:1054C000D6BE4A72C2B8BBA46E7D029CEDDEBC0F94
+:1054D000E798414F54ED656B1314847FFFA419E8DE
+:1054E00070ABC1DFBB15DA7FF5D2BFCE3183CEAE54
+:1054F000483CF5C7D7384CED930EB2662BC007F287
+:105500004E3F9926F175A0103EFED2C773D6E4E354
+:105510003AB91C79D5058E36FA190F5BC8CF18DB5E
+:105520007E66AC0EE049AB2D65E81F47F4A3B8F5E5
+:1055300050FDA2DBD5E73A56A437231ED67D0AEEEE
+:105540008913E565F7588CCF458EABBBBAF999FE48
+:1055500032F347F6932E335E5191E754DEFF037426
+:105560001E4DDF864B1FBFAEA3F8983515F5FAF632
+:10557000142E777AB3E343DB60DDDB5305BC219F58
+:10558000F6B50E61D8D7BA8DB964C76F8FF3361DE3
+:10559000C1F6BFD129DBA0697BBC6F6331C1F914AF
+:1055A000AF5997EA77A35ECA49E0FAB1CDF1489CBA
+:1055B0003382FFFF22E4EEE6CABEAEADE84FADD7C0
+:1055C000B102786EDBFA051BDC30CE4B9BC02E029D
+:1055D0003879F2C20D05D09EBB4137512F641EAE03
+:1055E000E3A54D0B5FD928E1B823530B61DC3C21C7
+:1055F0003F7386758F5D0974DE66D4C615FAF56350
+:105600003EE7978530CC19D0BF39225EB1D5C01A9C
+:1056100022F566413E97B73545BC344CE1F13CD3A9
+:1056200088F8D0E3B0FFAA113CFE93BED64CF19FA0
+:1056300074C77F9E9C0EEDE91D3A054D5AD9B6748C
+:105640008D01FD9EDB5827F2E356893F1FCCE6769D
+:1056500032182CB97322FC1EB037CAF223E2A7F627
+:1056600086A084718CAA114B258C37A73BEE933012
+:10567000FE91DEE0937C89E827F9A9FDAE229F2BFD
+:105680001FD6676F84E735F7B1BE0C3C5798B781DA
+:10569000F20964561639DFEC228E872764203DB468
+:1056A000DFD71A695DD1F89AE5AE1E993F7CE01C00
+:1056B000A3DBBFCCE7E7B8FD719802F960128F1F3A
+:1056C0009C783993ECE5D96DF11EF4234F3C39B247
+:1056D00096E0A72A3C68FF9E78B9621A96B39F9A13
+:1056E00049FD4E48EC30C605663F75BB8CF53979EF
+:1056F000B02E1CEFB491E871F653F789E71FA9C5E6
+:10570000F6725DF0EFD09F2E6F7E2D01E3051589B7
+:105710006F64617942D7BD6A3FCC7F8395FD1AD50E
+:10572000B57743DADFD4C13FE63C996BC0788C375C
+:105730003F97CEF326E631F07C072FF9B7953BBAB9
+:10574000DE018B8E5DD7D95B83D7BA9E5DD6835839
+:1057500056871534A359ED61EF412CA775F96BD12C
+:10576000BCA9FBA0F52096DD237D5EC4FFABFFED59
+:1057700096375E0578C463ABAC6887E63FDE3D6371
+:105780001BC52F0D0CF9A16092BF558F046CF6A6B6
+:10579000A27C78F6195987FADDE46A8D43D8744FF4
+:1057A000AE0EE34CDB535A17D3BE0BE219E2F128DD
+:1057B000E821A48B82146F2AF213F0259DC39D82E9
+:1057C0003E4D297E6B0AD68B7B8EFE7EF11C5ED809
+:1057D000DFAF354EA27952A5A0C4CD08B423EC4268
+:1057E0009FB7337F06E2C396E8DF8AF1AD822ACE07
+:1057F000FF2C91D305766F99488F50103EBDD53F51
+:105800000BCFC1E6EBCF1BE074076AB0DF3EC925C2
+:1058100098EE7F364B1C063943EBC23F8CE7A45B06
+:10582000D2C9CE51D76F6B80F122EC0EDCC78D96BA
+:1058300081E754BADB20F6F584280BE6F3F1D4F5C2
+:105840006ECCE77A1DD6EDD4E17AF4623DB00F5DFF
+:10585000C47A22FAD1FEFAD7CD143BD205637E89F1
+:1058600097CC2947EE7FA1CE13371AD7FFD65F61B9
+:105870005C2909E508ACF367FB2799914FA3F7F181
+:1058800042BE88FB80BD8CFEC34C1FE7DFE646BFEF
+:1058900084FE940D61DCBF43F6605CD46669920CB3
+:1058A00011FBB539B89E9ED9E8DF8F7265667982A3
+:1058B00082F43D8B75AEB572FE3E980FEB2B62FD08
+:1058C0007F163671C04E7CFE99F74EE2913A5867CA
+:1058D0005531EACFC7EEA5BC89CD8FCC3C8CEBCF40
+:1058E000743FB93F1506F47E2DCE7D3E8F6F6577F0
+:1058F000C89ABC872CBFACC98BC858AC6D077AD08E
+:10590000C02A5DD9A5D529A86F7409253367A09D44
+:1059100092A423F90E724A9A1BD31E8DA22B817F6B
+:10592000F57CDECDCFA773B359F839B05EC57C7373
+:10593000A2D8AC7A4E306F33B07932D07D73AD3EA1
+:1059400024A11F8FFDF132B2970DF7260E3EA7ADB1
+:1059500006E7CC1928A71FD45929AF2A0AAFA06798
+:10596000FE99FC9407D3A81DEA6533C53D23D6AB49
+:105970008F056BCFE34AFD3B5878CE0CD7E0FA4C4D
+:10598000C7DC99A8673397323AFFE8F6A247B5E734
+:105990004A7EEF788CA3B150F8079CE74CC7F65AC3
+:1059A000B4EFA3CF55A5BB9C61B1F5C223055C2F15
+:1059B000E42428A7EAC8AE90C94EF066CBC323FD05
+:1059C000A4EFF2B91F30E55716D243EC6373081FFA
+:1059D00055C25D3F298673A8EED3A1FBC2DE3D7E92
+:1059E000E0E999504EFDF57B4DC7A0DFD4EF2CE3E5
+:1059F000B07E37EB9E8181A0E06103F98D6BBE7CA8
+:105A0000A5150344CD8D4C41BDABCEE328E0FA6E25
+:105A10008F21E425F95A2CB36D2407D9C54B11F415
+:105A200002909EE887B7316F632BF991B6FC12861E
+:105A3000793CCDACF30ED297678D0CE3AF37363897
+:105A40000D55B0FF1B1B9D86F9789F21B33AB423F7
+:105A50006E6A50A8FEA64685D79B79FDDC060FD559
+:105A6000CF6DF4F07A0BD45B300F29D41580716FB1
+:105A7000B6A43A75781FD0E8E5ED174CD47E1CFC2F
+:105A800001CC278C8F0B91BC6FEDD1F17B237F7CF8
+:105A90004882B59A12CB0E3B117FF7E8145017CC11
+:105AA000942D332BC0CF3678437A687F8E853210A1
+:105AB00091BB1736790BA17EB743B6E2FE76837BA6
+:105AC0008BF947C1A532E19DFE00DEBDD841F73A12
+:105AD0005B45FC3EB8C44CF166B07528DECC9664DC
+:105AE0000A3B86B7772CB086D01E033948E7D87BAF
+:105AF0008F4C7600C8C3A36EB48B76E62B189FCA72
+:105B00005CAAE5B7F4850BAA68BC4666453FBDBEF6
+:105B1000918FD7BC5317D2A15D65B97126D241F3DD
+:105B20000EA6A03FFBECC253B5C310EE50142E3F9F
+:105B3000B472A179E153479CB81FBFCE5A40FD799A
+:105B40001CAFD95FBD5D2F0DF0339DB773407E0C48
+:105B50009637CA611C27635EB582F1C174D827C627
+:105B6000F33B8CBC3E78A74CF72DE90BE5B075F400
+:105B7000007F670B14A6231F26917CD1F0D7C89D08
+:105B80005AF879C1A7C0EF32EE2BB89D513E67D1CC
+:105B9000766D3F90933A9457D9EDDAFA5B8BFAE33E
+:105BA000021A3C44E3D9E6E7722F7A9F03FB0AC747
+:105BB00015D1BE747C5F28D7A0BED87280EA8B1B3B
+:105BC00065C5E94479D7790AF75FB453666180EB1C
+:105BD0001796CD447AAADFA4A3F0C8F5AC8BE4C233
+:105BE00095F6ADC63BA2F719BDBFEFF2F55C8EA8E6
+:105BF000F6E01366B207DB1EB6E8F09E15ECAD7852
+:105C00008C2BDC55541D2C407B40C81DC3253D9773
+:105C100027CD16A25383ED517764FCA16554F5138B
+:105C200005D46FD88D753C6E41FB8E96633F17E3AC
+:105C30004DEAD6E6E35DDB131F953FA6CDC79B7209
+:105C400021332A7F2C2F2A7F6C94A67DAA755C5461
+:105C5000FED8B551F963351A78967B96A6FFF5CA3A
+:105C60004D1AF886F23B34FDE778EED6B4DF547770
+:105C7000BFA6FD66EF4A0D7C6BC35F6BFADFE66B78
+:105C8000D6B4DFB1F8279AF668FF492D771570F979
+:105C9000BED9EE3F49016CD0F791F73D6A99DE28F5
+:105CA000F7469E7B5202B7A7A2FBFDB980D3FB8BC0
+:105CB000129F8F05ED9A781CF3D835F1BA7045859F
+:105CC000B91BC6711A95DF21DD62E20EBFBFB66B4C
+:105CD000EED9F63F0EFD60BCA6C45C1BEA3B8CFF10
+:105CE000FA40B9378774745F615BBF4A223DB86977
+:105CF000158FAB5C30523CAF7F1DAC8EC6FB46DCD3
+:105D00006BA9EBEC1071A42D18474285E49941FD75
+:105D100056C6F17E3F4D57E38E3E1A37A3DC18A4DA
+:105D2000FCBC857E09E3C0CD3E66C57B9374CB0287
+:105D30009AFF9B0625995D262EDA16B0330FCC67A5
+:105D40005F155C6384BD7D52D0F7D4B3F0BCDDCF6A
+:105D5000281ED35BF0ED53188FE943E108749D21B1
+:105D6000733C3FF7C0EECF5F81F9DAE6A597A15CFF
+:105D70008D6ECF5ABEF7EB4397697F6ED95B1FDEFE
+:105D80007BB9E71FD875BA25A27DC838694326F3C9
+:105D900044D001E02CE6FD805CC8F5F9F20A23C589
+:105DA000B1AE01FC1502BEBFAAF8CF893BE0B93FF6
+:105DB00039FBEE443B1DEA65AC877E84D73FE59F07
+:105DC000A3FC929C5160DFA3FD1D179B6EC715724B
+:105DD000BA956D8DBD18076A4A343AD1CFCF32BB20
+:105DE000CA3E1907746DE07E75B4FFFE5CBFBFDD6F
+:105DF00049FE779118274B947A2B7F9E99834C4EBE
+:105E000017F71431F0A14F6A97505E652E943F8DBD
+:105E1000E48BFD89468A23A45B44DCC1B258131786
+:105E200050E306FB13EF9590EED3C34B289E8FF102
+:105E3000021C6F5CA193D6111D2FC832E7D3BA861E
+:105E40001E9FF5D7274831E6895A871A9F889E27D3
+:105E500084F604EA9965F1644F44EF7B4961557912
+:105E6000E170E4D7DE93D3517E9F32903E1C8A5E70
+:105E700030CF3C1431FEB442EEDF63FE78643DE681
+:105E8000878722E3D9CC41EF2B100C2A6684B17BA3
+:105E90004311CE7794CF77C2A0D8C91E04B587FE30
+:105EA0005F7D21D703D330976D38F219F7CBDB81B3
+:105EB000AFB1DC12B0927DD601FC87F00B012795C3
+:105EC000A1809BCA6D0185DAB707CA097E25E0214A
+:105ED0007847A08ECAD7025EAADF196820F8E701CA
+:105EE0001F959D81C554FF46C04FF09B81D504BFCF
+:105EF00085F66001C6A9D753B93BD04AED7B03EDC7
+:105F000004BF1D0851190EECA0FA03814E820F0642
+:105F100076117C281026F870E0309547035D547F99
+:105F20003CF001C137E33EC9AE58DF15C078854F5C
+:105F300076A27DF7AC6FA115ED6BFB7C9D15C57945
+:105F4000BB4FB704E31C1D8DFC1E13EF23310E0461
+:105F5000766808ED39FBFC678E4CA5F6B9D4BE19FE
+:105F60008704A7C4B682DBAF6C9991FAD930210AB5
+:105F70009EEB58DA18D203DC5A184FEDB61532F9F9
+:105F80006DCFE9FC2985DCEE22F96D3370FB41A56C
+:105F90008335855CDEAE29E4F75C1F16F1734ACACF
+:105FA0008BAD479E2D54EDA6F587717FF679B03FF6
+:105FB0005CEFBC5566BC97B5DDA3B3727B93DFCBBA
+:105FC0003A60BFB87E580FC585D97C6E2FDBE6AD31
+:105FD000A57539E6DF48EDD6A24753D04F6FF7AF2E
+:105FE0009A43EB6D9429AED9EE3B9082F76CCF8942
+:105FF0007C27DBF0786FA864F07A9E8D5A7F07E3E8
+:106000007E8303ECA5D763EC03D36E49CF3011C771
+:106010007BD41C338ED729E8D72171FE630FCAC405
+:106020007F2F30B0FBE0B92D60DF05510E54BFB6B5
+:1060300002E355BD85BE9D28379F778E3F20039C88
+:106040005AC7C7CF5D25BF8276349CF7E72D50BF76
+:10605000E1BE4D5E5CEAB04DCE35C86EEDF3DFCAF1
+:10606000C0F89743D29E8F5ABE2DF6F982878FB71C
+:1060700065954CF164DB8A375D07F9BCBB91FF3352
+:106080008B3E8AC3304CDE5CA70E4586639EFC3592
+:10609000CE1777FFA63A42CD268F3ADF589CEF6A9B
+:1060A000F134E2B15A9B2FC6BA869227579223BF8A
+:1060B0002914EF8164B12C9423CF19B8DC0A9EE433
+:1060C000F62425054D1A3C8F9A2FA0E60F44E70BC6
+:1060D000FC5EE029CBC462DEE77ED64FBF413AD7F3
+:1060E000173C1BBD9467E3923149873519D8127A62
+:1060F000EFA72ADEBA26063DA8E55328C700C11F30
+:106100001632712E9BEAF8383A3ECE64B682E02A07
+:106110008B3518435EABE533629C7F2BE4749B7533
+:10612000DFCE0D87F07C8F1A28376A8B2EB401FDE5
+:1061300084E0093DC9D74C7DE7D65722D6F51741F3
+:106140009F5B8CA162BC876E87F14A50AE22BF94E0
+:1061500050FC82D547E05D7DEE3F841DF0FCC575A7
+:106160002974FF3C6F6D1CDA47EDCC4CF46033F8BA
+:1061700053C646D0830DE932067D388B8C340EFC35
+:1061800059AA26E2BD0CD7CB35289760DDFB162631
+:10619000913EAC99FFDEAC310057F6C994CFB265A1
+:1061A00029CFD39CF4EF3ACA1379FB31EEF75DF7B0
+:1061B000502DBD9F9421CA67D1CF83B2723D53C287
+:1061C000702E950B2D14BF997C413E13E9A75148C1
+:1061D0007A3CFA173C5E736DAFAC790F6D528FB697
+:1061E0003F60548F764646B7B6DE3EEFCDD353615F
+:1061F0009EF6A5FCE1F68BBF3B827070958EE22483
+:10620000EAFB64509341F14D399881F99B1BCC8C8A
+:10621000E4B96DBED98AF2607F7A3CC9BFF6DB2C47
+:106220006487AECB6F8A433BD9346F550A96238C73
+:10623000C1AD183BBDE6D52D37D92791BC55F355D7
+:1062400082AC1CEC81BB8DDCC8093EF7F45419E527
+:1062500025CF6799F4EA96A783F9D8AD95D6E1D40E
+:10626000B14CBEF97EF876BAB796B8BE701AA11DC9
+:10627000E079A37CD715417B465A703F366DB69CBA
+:1062800069A47C6B4C3282F90D0BFDCC88F58D65D1
+:10629000E6483E57F9E4FBF27F3CC687875F590E1C
+:1062A0005C69DC2BF17B413EE79BA1FC69D310F2DA
+:1062B00054F58F1F29E0FC8B6C4B7AF58C31A67D51
+:1062C000F5AB22CE67E5469EA732BB615A1DDDC302
+:1062D00004BB65CCE77B51DC0BB5A727D23D717BB6
+:1062E0002E0BE3BD4170818EC77BD2F87FED8DB957
+:1062F000141F6A93FC29C13CCC97F0B9F0FCDA0179
+:106300004789307F5B0E97EB2CE4B7E27D358CB389
+:106310003872FDE0EF05B574CCC81EA6F8859E78EE
+:10632000CF698C88B7635C1CE317D1CF4DEED5C223
+:10633000532E68E12A66D0C035662D3CD5AA853734
+:1063400015713B7DBA5D5B3FC3A9851DD907E37419
+:106350003CCFDFC222E249F0F75E7E441C68DD6874
+:10636000FE3E5F76F7528ACBB6E5F0788F639536BE
+:10637000CE91C54212E22F7369543CD6BD663F866A
+:1063800097ED0BA3E341FC5E02F0A1A947318A7CA3
+:10639000F0EA689E87DE3DD2B7BD08CEB3600C5FE1
+:1063A000C7AB1D4D743FC5DAD388AF5C225F69B0BF
+:1063B000BE7C8AE8401D0FF92218B17FE48748F8B7
+:1063C000A151BE37701EE48B60A4FE2CE936D0FBD1
+:1063D000AB62BEA1F843E5CF72718FA2E6DDF4890E
+:1063E000B1D4BC9B55225F705754BE4E9FA3361943
+:1063F000FDE7BEAE95F1B1F810F92E68E27C88E5B4
+:1064000006917F837C182CE27C88F5A6EF56786392
+:10641000D98B0B055DDCBF63C9864F22F6B7AC7321
+:1064200085065EBEEBE10D91F951F7E33F3008BF01
+:106430009E517EED52B19D2F4FFFCB2BCD0CCD4801
+:10644000DF0728CF96159C31F27BA75E239EEB4297
+:1064500061FF99CCB3F2D12FDB11E2F26C9D88374A
+:10646000345B1533C681993B5513C750E3114D4B2F
+:106470005CB654D847727F7CC16BA57CDCE1F91413
+:10648000DF48AAF1DCCEC632D653649C6B0662DDCF
+:106490008EC156C0E9F957D93341C7C0BE4D17F870
+:1064A0007BC9FDB0EC67248F2EE468EADB449CA333
+:1064B0009FBF2D0BAA703E8BDB49FBB031FF1A1E2C
+:1064C00017D4C6D14CE23DE7C1E33B34F56D227EE3
+:1064D00072E5F1B57139D385BC21C62F8C1ADF1A4C
+:1064E00073FC8171B5F1BDABB8374F714F183A2EBF
+:1064F00036D2CDE9699DDDDF85713183E07F6606A7
+:106500003A9988F280FFE9E3797EAEC1A18D8F19B7
+:1065100030AF0BFA3F97B898E48AFA3EB5FD99057B
+:1065200012CACB27F0FDE8A4C1F2245A8ED844DE6B
+:106530007CB41C81F93470D3C35CCF364B8A0FE531
+:1065400073F47EFE7FF1877589E3BBC8AECE8E778C
+:106550009A2E630FB7058263F1B975F1FEC578070E
+:106560007EF78E91694F94E37BEB8CF86CC58E2996
+:1065700073310FB64DF0EB13693AA2A7F4DBD3B732
+:10658000EA23E829DDE873A13D9CAE13F95FF887A3
+:1065900071B427D2B76D8C31BF6AD7A9B0AD01D61F
+:1065A00011718E6DC29EEE9FEF8ECCADFA8871D2C6
+:1065B0004DBEB1345F7FFEA398AFE587CDB759C418
+:1065C000C3D4F96C776AF76733FA697F36A187D449
+:1065D000F936E3FE62F0D515E713FE75FF7C7769A7
+:1065E000F76733F9697F36F53B1BEA7C2D3F6C3E3C
+:1065F000BBE0CF76F1DE973D9E7F3764A8F7239A04
+:10660000FBF3CCBD66942FED6ABC50E8BB7351FA26
+:10661000AE49E83BF5F97369B914FF3D77F8267385
+:106620002C3D87FA8D093B93093B93093B13E1D934
+:1066300035A7570D077AFCBB1D37CF9541AFCFBEAD
+:10664000FFF4F81C80DFD9F18BB932E8A9D9AF9EED
+:106650007E330B1E29FEDBFB38FCF4E93E07B45BFE
+:1066600082CFCCAD05386918D7CFEABAD57977B9DA
+:10667000B95DB97C751E8F6F829C453DD69CE367E2
+:10668000187FFCCAD19B341FFA2FCFEE4D5F100349
+:106690002F6AB97C75217F1EADC08998CFC648AFDF
+:1066A000DDA8BEC752A77D8F25296923D987712C04
+:1066B0006445399660F6D0FB97D71673BD70335397
+:1066C0001AB85FE12C10791CF4DECB4DE5625C6BEF
+:1066D000E52FB1FD669DE709F477FF79D2BCE1684B
+:1066E0003EAB7973A306DE3BDDFE7DDE4F9EFDB142
+:1066F000C46DE5641E8F9936CAC9DF7B8B882BA2D7
+:106700005D3C143E3F7573FF7E009F1E8ECF540F7D
+:10671000C7A7B537690D9CFFF294DEF4C7894FC354
+:1067200031F13508AF51F8FB939BA97EA01EED888F
+:106730002BE15BC5AB9A5FD82C390BC85E67199A01
+:10674000FC60C61467AC7B1EA4CF483D6BB47B19BC
+:10675000DAA38634C58DF9EFCD7FD1C7CCDB7315B5
+:106760008BF85E523CE57D362719C91FDF9F3493B5
+:1067700061FC59B64C23BCD426D5513EA67E18EBFD
+:10678000447F353A0F5D9F7C3BE509E96DE8614048
+:10679000D99FC7EC31235FE93F56925D4800579976
+:1067A000872E5F290F3D7526CF434F323A315ED891
+:1067B0009E688C9987FEAD9BFB5DFB717F69B81F5E
+:1067C00023FF6E88D8976CE5F7EE589F00F546AB2F
+:1067D0008F51FC5DECFF5B6107A9FD4D563F43F90E
+:1067E000A0372A4EB45FF4A95C7FE0775BDC31E22E
+:1067F000285FBB0DF4FCFDA3AC5CCF99B9DD3EFB7B
+:1068000037B1DF27282B9644BC2436DD0D453737BA
+:10681000EA78DE9DCA97732D46CA079C6BB1D3F701
+:106820006CE60221F6A446F4BFEE56FE3EB5ACD8A7
+:10683000919E7E7BED945FFE96E1B50097DBA766A7
+:1068400018E8BDC25312F328A983F35DBDDE94A9F5
+:10685000B8CC1BEA4FAF45762C18C3C84E7A75C129
+:1068600043AD954EF28FEA8A919E7D73A6A20F7773
+:1068700063C3D877B1FFF2042ECFD5FBA5E509FCA1
+:106880007DDE6B64DF6CECFF55C51749D5485F7240
+:106890006F0EAE2BA23FDD3345F49F5B3C81FACFF8
+:1068A000E6AFDDF5D27739CEA59DF9C8C7E87CEC17
+:1068B000B1EC29F4B758E4BD86901FE87745D6A31C
+:1068C000BFC522CE535A506EEB8E214FD432C33EF9
+:1068D0006EE442A0D78C8CB154AAF5CF7AF475A19E
+:1068E00018E7FC9038E71FECF7B4C36A270EF83DB1
+:1068F000E0EF3C84F8F872E1A9F4F1B0A5076ABFB3
+:1069000026BFC76EECFFCE16F97103B0F6BEB32DED
+:10691000D05B8CDF196088878911F98B62BFF625FF
+:106920006B52D0EF81B3F420DD7604BC236B0D03F2
+:10693000CFBF2CE4080B16D2F306B12E475AEB0C4E
+:106940008CBB382C3ACA7360CCAA9167736A53A681
+:10695000A6A10BBB9C291627FAF75DE41764E0FBA0
+:106960000D189F7CE73686F75F59699D12DA75FD31
+:10697000F388F7C657897BE13E5F2DED27C3D6EF3D
+:106980009731F25FD38273506EF53DC35794F19205
+:10699000B6DD91C6F31FEE5D181F7202BD672DEDC7
+:1069A000C24F4FB00C70F830A69F71A9D9D5827232
+:1069B000E657091477D6B7E7B320C8FBB0ECFB1B4A
+:1069C000C277C8F9902E4F6C169E5BB6289EECB924
+:1069D00076A97506F931F7E858AC78D1CE62EEA702
+:1069E000FC8F622BBFCFB54FE4F4631F3F72E1B859
+:1069F000ABE7FF77849EF949B293DE7F52EDA34D5A
+:106A000043F8478E913A215F845E11F833339F1922
+:106A1000F9452F7979B074C76BAFBD96CEE8535B5B
+:106A200048471B84FDA38E139F1FA2C678C543F25F
+:106A300052B27AB8BEB0FAED4138AF75DFE963CE35
+:106A4000FF85A0FB35D90FD9B17FADD3E7C632FAA8
+:106A50003D98969C7BDD783E2D33FBE995ECBA960C
+:106A600033CEDF613E56F028CF37D89F5D68C3EF45
+:106A700041590E1B64D365E2F146D027CECBD8191D
+:106A80004691AFDE7280E799B658CABA30AFA1C559
+:106A90009256466AD8C2F356D5FE16CB21D20716B7
+:106AA00085DFDF5A507F48B84CC04709AEEB10E194
+:106AB00043ED7750C85D8B1266F85E5A9CD24AFD52
+:106AC000CCB2D78379CAE63446F744662BF017E296
+:106AD000355FC7CC31F4C9BE62AE4F5A4ACABAAAB2
+:106AE000697D327EB98EB5D8CBECA4E711EFF07C8E
+:106AF000738696CFBF137857C76916F9B477AE4E31
+:106B000009D68EC33893F71BA4E716CB027310F592
+:106B10005AE2F8CB8E671A39D478FBD78AF1BE4394
+:106B200079AE4F2CB3E27806C6F7158DF7E1629C7B
+:106B3000FFD5FB7BC02CBD474D301D58D81EEB7DCB
+:106B4000ACFEF313F7F2D1CFFD6079BC561B870280
+:106B500079EC1E09FB5A5672E65035D5F0F8D30B86
+:106B6000C29F51FD927431F60B127FBF3F28C52B97
+:106B7000F45D0CE1A7A4C769F130F03E2D3F876FAB
+:106B80001A781EDE37694C7C874ECBD7DF1CFF3866
+:106B900045939F057CEC31713FC623DEA7F588380D
+:106BA0001DC2186FA0179D04FFF7C7891B9C3FC328
+:106BB000EFAC99408EEB605CC9E127FA3639BA5DDB
+:106BC000C8EF39E2FB0FD178FEC9482EAFA5477A4E
+:106BD0005C78AF519BD69B118BDF5F7CF84206EE51
+:106BE000E7C519FD793B74DFF4E269E7E602C4CB3F
+:106BF00011EDFB6FEAF84D47CEA7F822FDA5C0E5E1
+:106C0000DF2F4B3AB37125D98D0BB8DDF87FFA7DB4
+:106C1000B317E6733B7597A495CF4F08B91C14FCC6
+:106C200060BB20D3F743EE2AF2AD403A6A93AC0B37
+:106C3000502EE73CCCF3F29A1E5BD5B328067FB406
+:106C40008CF2FDD5C808BFBA7CBD91E45EB3253790
+:106C5000F972F728439FBB9FE4947ADE558F9879A9
+:106C6000BE8A8FDBD1E9BE7B290F263A3F65A87E1D
+:106C7000D5239D440F6A7F138E8FF2C57223C515ED
+:106C8000CEA18F81713B2BB733A2D75989C898C049
+:106C9000F163067D997460491C8E6B10FEDC0B6AF3
+:106CA0005CA4A1CCEC8978DE705B99B93A824E9AEB
+:106CB00019CF0F8E1EFF372355FB22ACB1630CA8F2
+:106CC0007F31C694269FED973B6478F2FCB4950320
+:106CD0007CCCE30E43E7A3C571BE2D237BAC0DF343
+:106CE000D2C00E5ED3B06004E2B74DF6BD68033C7F
+:106CF000F47E68A23CEADF0B3EED167C3AD4F9053F
+:106D0000D90130D2187B9C1DC497E2804EC6272340
+:106D10005F34E7EBEA4231F6795CECF332F67878EF
+:106D2000E4F7B3C70F89FE1A7B1CED6D4FD4FD4607
+:106D3000248C76B627863D7E4212F105912774C2D7
+:106D4000E0DCD50D7839313999BE975690C0EF5DAA
+:106D50004EA07F52067EC8ABA7F3D17E992DF57F5A
+:106D60001749F8438C60F047FE05F9620EF3BFB691
+:106D700048223EE2F735781B9F7EE573DE3692D1DE
+:106D8000BA36C0F9E1FD46DBC5F93362DD67A48E92
+:106D900052FD37506511EF13333C9D88FBAC41F732
+:106DA0007451F772786DD39F77AC1FDCFF8672ED5C
+:106DB000BDD9868B3C2E625AC2428F4B9897AA6DE2
+:106DC000BFA9CE107D2FA8B94FBBD96B885E0F7DB0
+:106DD00017D421D69BDD711FDDBF4FCDE6F944A648
+:106DE000658CE204D1F76DA6B15D1E3DDACF0D8C46
+:106DF000ECFDE83839E6A952FCB081B12D12E579F5
+:106E00006BDF7379A6FE73FE7D94D63A9CC70E762F
+:106E100010DAD3D1EF49A8F75AEAF751553CABDF66
+:106E20008F4ABF4D47EB63C129D4AEC6FDF17BB895
+:106E300055E911F9E42B587F7F7A7F2B187BDF9B74
+:106E4000DBEA29CF2073BC7F6C189AB2144678C84D
+:106E50005AC8C86F003C68F2094CD9DB699FE71635
+:106E600033364C223C68DA3340D3D3FDC0426D7ECA
+:106E700001EC530347FBAB57F2534DD9F99795F308
+:106E8000578A639AC4BDE49451E2FB97A5AC14ED14
+:106E9000A2F4DB9EA1F33807E781715F749C62DD89
+:106EA0003B6E82F1D18FFC77C12FCDE26E5BFDAEE0
+:106EB0000FF3C8F41E9B54CED72C0DF3F27BE912CE
+:106EC000467C6E8A6766CC8F972A4C1EC4BBC90469
+:106ED000306C5932327306D4EB453C7B8DC46484EC
+:106EE000995531F3F8A3FA5DA1107D5768A879D4BC
+:106EF000EF2BB2207F4E9D67D077F52EF33CF97BC8
+:106F0000D6E8E76B299EA9CE3F14FE87FA8EDEBF36
+:106F1000D5BC3781C7531D44AF8D03F44AF07C4183
+:106F20008FF83CCA85BBD5667B5729FA0F671E4C84
+:106F300050364A11FB08CED2F3EF037EBFF1FAD7E9
+:106F4000617792BCEFDF9718EFFBEE8BFE22E4DA5D
+:106F50003A7C5909F35E1A19E531A4FBAA3F972937
+:106F6000FF00F6A0911311DF4980F1D63DCEEF1F4F
+:106F700036E3773EF0FEE7C040FEED13166CF7D126
+:106F80007736D4BC5CCCA35D5B32F03E72F47D837B
+:106F9000BD11C689986FB2990513409FA4F43105BD
+:106FA000BFF3ECB96854A6037E6C7DA05001BF937B
+:106FB0009989EEA52AAD7E33FF0EE10A166967EFC7
+:106FC000976EA5EFBD86BF6494BF143ECF88EEC315
+:106FD0009FC3C4702EFFF8DDFB7AE4CBA97D5D7AF8
+:106FE000D4F393FBFCA47FF6D94F3DEDE2E7629921
+:106FF00011911F751D5B54CFE98A9F972CEA275F7B
+:10700000306AF8FDDA5EA3461EC8175BBE46FD6512
+:10701000EA89AA67D33FE3E3F928DE2DDBB5ED5318
+:10702000443ED0DB2ADF5FC3AEA173BC981633CFDA
+:107030006EE0DCD5736EE27174C6C7796E94F79F0B
+:10704000464D40FFC04771E864C42FD8172995DD2D
+:10705000CC8E7958E54C998E72BDB2F31DA487E4AD
+:10706000B33C0F3C7AFCFD5FBE95857EC39EC99DF7
+:1070700059682FEDF9F2153D8E57D5D3CBB03E1997
+:107080004A1EA4584C78AA10B43350CFE34491F56B
+:10709000B49E4AE765E5E4CF504E1A876EDF33D9D8
+:1070A000C2C2E4877526A03DC77C7CFE64B3CA5784
+:1070B000EC2F97705E84819FF654EA526A619F7B41
+:1070C0009E91156CDCD3F34602CEBFE7EC39CD7A46
+:1070D00098FE22F345ACFB5A71EE532B7BC9FE7E22
+:1070E0004AAC2BF96C2FC5A15395DE30EADBD4C333
+:1070F0007AFAFE37B3F0BCC8614CA1389ABA5EFC8C
+:107100006E2A3ED78272DE88FBB3325628EC7E2888
+:10711000332A8355988F9ACC764A486B532B7D41FE
+:10712000A4E7E4A59C9E93ADFEC318BF4F5EAFA33A
+:107130003845F259DF06F4CB92CB6505C9E44AF82D
+:10714000EC10F3B78AF9D4F9D5F58CA8F44BE87EA6
+:1071500024B3E362FEAE2A138EBF5ACCEF14EB5970
+:10716000C5E83B2CC967AD55E82F27839D41DF3328
+:10717000B8E2799A35F345B7274FD99945E7E0B199
+:107180001ED90AE3A5645B365441B9CEA123FF3270
+:10719000A987513C3DA9279DE47D524FA128278A0C
+:1071A000FA69420F703993D4F3502DAF6FA1D2A476
+:1071B000CA17873F8CFB98DACBB87C717849BE98A8
+:1071C000D2B87C51E9B856952BCC5A321FEAF70F4A
+:1071D000FFACB5069E7BF773FEFEE5BBD95CBEBC7B
+:1071E000FB25F7FB4D69BFD3A35CAA42C305FA4D4B
+:1071F000BBC0ED33951FABBA25361148639A83E7C0
+:10720000871FBAC89F3B84D9D500AF6312C929959F
+:107210006E6B05DDAEB3EA8349D8FE8189DE773433
+:1072200039CEE598C11EFE83AEF7417CEFF8F73307
+:107230007AEF5D41F5827E434B492E9A846C39E4A6
+:107240005860413E847948AE1E7218E9BC0E083A77
+:107250003E67AFE908C33F5BCCDFFC693ED4FFC1AA
+:107260009EEB40934C3D971E412F5F88F33B2BE8EC
+:10727000A629DD7B53C904FCFE621ECD7BCEFE0D2C
+:10728000BD7FB2DCF61F9FC6FA2EA73A8EFA7C4F5E
+:1072900068A519CFF5D09B1F9F40B4ABE35F237B5C
+:1072A000EFE4E37E339AF8D0123BCF7890FCF3AD55
+:1072B00088967F8B4A860FC8BF7A6691791E12E73F
+:1072C000EB59421E4D55B8DD5E6FE5E7555FB25F85
+:1072D000A6FE8A8BF655AFD28DF2E45AE47F9BF27C
+:1072E00024D14B7D3EA797BD829E0F0A7CCEEC63D6
+:1072F0009DE897ED2F986E190BF83EE2D213FF1C14
+:1073000019BBC65206CF1D2995F04B026C7AC9D61F
+:10731000B5A900CF5224A2A7FA92AD1D4DD07F96F9
+:107320003541A903F8E8F9B31634AF0E05BC8497CC
+:10733000E972F8E354179E1BC7D3CCCAB08CFE4F3A
+:10734000BD63BF8CFAF66DC4AB11E32E1EC1677529
+:10735000041F576A2CB88F23A526212F3DE3515EC9
+:10736000CECA37D58FA1757C7D6C4C1ABE776F5015
+:10737000F8953CA7FFC9827EEACC276B53A0DFCCEF
+:10738000926619D77BD42C91FC3CDAD744F993C789
+:107390003B39ACD22D3D077479BC6F5B7312B66F6D
+:1073A00097483ED52B2F1DE2EA8FD3A73A7E0F0BCD
+:1073B000B6E17730CF29AFB7603EF5B1BE05CFCC8F
+:1073C000013C1C7F533FC4B84D1FADC071DF4C243E
+:1073D0003A9E6D3569F4B18C4E69845EAD1E6FD3F3
+:1073E000C0F54A0DC5D3CF2992E50678DEF35DAD31
+:1073F0007B3991D152DA77BDE87B4CE17C79CCA125
+:1074000023BE3CD6F7B89C8AF05946FB919976DEAC
+:10741000FA921AB2AFCE295BF54467820FD5F154C8
+:107420003A3E8A4F231EED9CFF8FF66DB320BD1DA3
+:1074300075BF23E3395D67891A57D0A1AADFF05DD4
+:1074400071A49FDA51FBF37E86EB5138FE6B94D723
+:107450008F237DD53B64A2A7A3CAFE9A1486BF27BB
+:1074600062D2ECFFFE1DC99AF19775DA3470B45DF3
+:10747000B5CFFDDBA7CBC40E66A447D847F9C23E03
+:10748000D21F77E0FAAE681729EBE8F74906D9452D
+:10749000F9DC2E8AB68754BE6ED689B8AC8EC76525
+:1074A000A3F9DF58FAC3EEF1D82A498EBCBF5BC6F8
+:1074B000BA7390BEE6A31286F11ED075A723FC1501
+:1074C000EB6D8B07397CADCC7669BFBFCABF373F48
+:1074D000BED4771EE59574364CDF6165AB18E507C1
+:1074E000E86B789E115E66AD88D48B25FDF12D8DFD
+:1074F0005DA44BD89B8578AC386BE4F18F9EE8385F
+:1075000097EA1F8525F22BAE522EEA93F9B87BE657
+:10751000F078677F79338F931509FCE5941A695DDC
+:107520008A80F7DC16FB9EB5A454FA41F9A2DF0766
+:10753000DF2980EFAF90E6619E3D55B1D79152CAE9
+:10754000E3B5779778F24AA12C2AF11596225E3D91
+:10755000605FD377C53D649FA9E3BC33CAE316FDE2
+:107560004661C9BCDC0E8FEE07ED63689C86D8E3EC
+:1075700040FB387A7E6EECF643B839FC7D23FB3055
+:10758000D243060C64A6F2522AE3E516FAAE468808
+:10759000FBE70D1ED2F34691AF88371091FCC7F47C
+:1075A000F534BE1C9E41F7582DD82583FBF9917602
+:1075B00094AC846A22E3AD6AB9A894DF73CE28152F
+:1075C000EFF34C6013C8AFA8BCFC3CEAF343CDC357
+:1075D000EC6557C87B5EF363D349FAC3E4275FA524
+:1075E0007D600E4A91DF391F6ABF894A941C8AC2A6
+:1075F000D350F35CED79DC22E8F66AD75D657ACC8E
+:107600004EF9D12ECE076B057DF5DBD53F1E3FBE73
+:107610003F1F86FECAD9FBFE93F87E4A4268A53713
+:10762000C67E5E14FBF931E5C1D370CE1B8CA1FB85
+:10763000D1DE9907A76302D27BC7F2F1F005B09EB5
+:1076400037C5FC2D9695EB6F85475B1CBA98F91EE4
+:107650006FFE787AA20D3FD9FF95E3DCFB6D20A782
+:107660005B1E7DD0ACB08175306BD915CEF947E388
+:1076700013755D6D5B305E624DBDAAF7145A5CAF49
+:1076800024E07D69EDE74D76FC0E46B43DA0C6438F
+:1076900054BDA5C64D54BBA4C2C1E31F33EDFC7B52
+:1076A0003D15F669A4DF0FB2AE1AF2AF303B6D2282
+:1076B000B10AFD19DD5AFBE43ABF57463B2ADA9E70
+:1076C000A84D3345D907BD7A94DF1517B5FD54FE93
+:1076D000F8AC54C45154791765479ACF9F4940BBC1
+:1076E000EBED0B67282E148D9FEB2E5CDE9FBDAE5D
+:1076F0005D4FF783D171ADB72FE4D2FDA011AF1B61
+:10770000C1D4CACC3FC48C80974C7B6B9511EC18CC
+:10771000A38329F8DD36FC5833C60D8D17789C7C81
+:10772000849DFBD7898BC12F85513395A07DC1786E
+:107730007CCE48EFD3995DEF91BDBD09EA86219ECD
+:10774000C79E19A68B110753CF638AC0EF6EE6B7A9
+:10775000E3EF814DB18BF7F72E46DB59FC3C2DA2B0
+:107760007FE2622D3E2DE23C27835B43DF79ECD341
+:107770003E6F11E76B591AFB1CECA3639F43A27A7F
+:107780000E13B6C5E1396C59BC4D8A750E998B2F15
+:107790007F0E5B845FA9D2EFB4AC04B2AFF7A6E86A
+:1077A000E8FB417B13C359CB31FEFDB299DECFAC70
+:1077B000107136B4A4109F6BB797BF8471DB71A3AF
+:1077C000F5748E7B25D1FFBC8EFFFE60CF78EA1F5B
+:1077D00027B383F8BB8007FBAAE9BB1BD1FCBBD353
+:1077E0007A00DD33B6CEB93D6B019C8325FB8099D1
+:1077F000FB9B83CF07EF3F4A05BE4B7BF8B954A6EE
+:107800009DD4A3BD5EF266ECF351E38F7BA49D3A59
+:10781000202B36AAAF8BFC98913BA3ECE9B32D64E7
+:10782000675BC647D5F7C039D1BD8E9FEC16D9A18D
+:107830003DAFEB8738A74A1187307F7D8AE265FB31
+:10784000FA4E717EE9D1C62527F75DFE9C5E13E7EF
+:10785000B453C4A17E2EE2009DC27F7E23E0A4F239
+:10786000CD809BEADF0A2804EF0A940B61C1CF7731
+:10787000563ECB4717AFAA84FBED47CF73BF7D7F42
+:1078800062A883BEEF74DE42DF17A4BD4D14BFDBD8
+:10789000077C722CCE49BF1F7834DB4CF1B3A3A513
+:1078A000BFFB7B8ABB7C6BD1F1B80BC7B37A4EEBC5
+:1078B000704E186F5D858BEEA536E04714A1FFEE84
+:1078C0003289BEFF341B0E04EF45543A37F569F197
+:1078D000590FFF6595F1DF1DC8427F618C8BE8A4CD
+:1078E00042EF73223E37BA4F915F1E57D8EE1B8787
+:1078F0007180F17A26BEFB143445AC3B0E6F42E03A
+:1079000079538944DF731A0ABFD1E58654AE2FA399
+:10791000EBFF7534D7831BDDDBE83C773BBAB25015
+:10792000AFEF13F910B3642948BF5F2877DDB11CAE
+:10793000F65B91651FBB11C02DA35368FDFB4A4F39
+:10794000531CF8D88557C621FD1DB3765A30CE7921
+:10795000CCC9DF53871395F97BB79DF22D31F2A483
+:10796000D5F258E922FAFD957FFC7CEFDAD17CDF75
+:107970004C52F50A8C5B81FB4D42F9DEB202F9C331
+:1079800098B983FCCCE873AA705FB388DEF364FC1B
+:107990007B4FBFB6862C783F1CED67027D6C42FFA3
+:1079A00078F7043D7DAFAD5EE6E782E788E7A41F88
+:1079B000A3137E99767C66653E63FAC079601DDE0E
+:1079C000D7D03AF13EAAEFADBF9262F8B583D6C9DF
+:1079D000FC9E58F9B0D1CFCD76B2209A86B3151659
+:1079E00076A19F70309FC6996DE5E3CC12717C9BA8
+:1079F000A0FF59177594DF81F4D680CF95CC2779F5
+:107A000072CCF550571DACB71ECEC641FE469356FC
+:107A10000E09395B5F5245F7BDC7DC07C6A3BEBF81
+:107A2000BE74E5E13227C29FD45441B729A52FD5B2
+:107A3000205D5A942E8A2F4C76CB745D787DB936B2
+:107A40004ED1AF17A3F44BB4BEA88F923B11F7549D
+:107A50004E43C4F9CF729F4B88A483ABC7CB1C2F76
+:107A60007EAF7BD6051EA71D8C97F7E973A503781B
+:107A7000893EEFD878893EA7013CADEAAACB1D8CA0
+:107A80005F156FBF2E79C91A99E71B8DB71F8AAF93
+:107A9000E6D15641AF5C9E5708BE7D3B3B4471B773
+:107AA000B74BF9EF4B1D73FF96E2BFB358A8630DB8
+:107AB000CA45E0CB3942F9E823E44C341E06F8F419
+:107AC0003F282EBFFBF3B7282EAACA2113F225EABE
+:107AD00013C11FEAB999901F916F2FF0EF875E2DA8
+:107AE0007FA87C45EB213F38A48FCC1FFCDFC55F0E
+:107AF0007B71CD18177616523CB8CAD1A5C77BAC9E
+:107B0000C950D23D92887FD23A9C91F53C6E1C5967
+:107B10004F712FA1F7D4B8A6DABE3EBB2B41185542
+:107B2000A4474DC2DE51FDC47D8E53647FAAFA5432
+:107B300016F7FE57AB4FF7087D3A54FBDE73BB795F
+:107B4000DCE7CB433D0F801C9F9C6FA4EFB84C0E2D
+:107B50003FCCDFA3708449FE6F7437911F0CFB6923
+:107B600046A304E67544E6F3A9E5BEF36D0AD6EF35
+:107B700095BBF40AF507FF16E0038656FA9D860DBD
+:107B80008F737D1357F451D6E5DE83BAB34F99E670
+:107B90004AC2EF616F5F83DF010B2A8CBEEB98B5A1
+:107BA000B48B45EEF7A531DCAF9D9CFFD61D076871
+:107BB000DD1FEA69DD6857039D4F969D0E05E7CFEF
+:107BC000F6DB23FDEC7DD9F7DA9D00B77C696C0804
+:107BD000D17AC3A37E01F3EC33578D074B8DED7340
+:107BE0001F18F50BC0C74673D504CCA3ACB6DFDBBA
+:107BF0003E1FE5DAD95B2660FC1BECBC56D4B7838C
+:107C0000F6DFB7CD8CBF3B5DED789FD631A2AFAB31
+:107C100006BFBF5AEDE0F748BED1BE87C64C407BD9
+:107C200039ECC1734F349F0C22DD4C16EB65172FD6
+:107C300051FC41BD97D9739ED347FFF8400FB88FD1
+:107C40006BBF5C45F722B97DBAF926A0D5757D3C9E
+:107C50007F0CDBF17BE058BF28861D00F35CE74B0F
+:107C6000C6F3EBCABA3786DECDEDFB36E083E7F626
+:107C70006470BC44B76F1EC3ED82B8AFDECF7292A2
+:107C80003DC0F57FB0C012F33B55B7A9FAD21A3BFD
+:107C90000F452D5579A5DA23805FB32102BF9BC61E
+:107CA00070FFFD7CA9A703F1F77DE77F0A710BE563
+:107CB000F152CFF631C391AE045FAD9763C601EECA
+:107CC0001CF3A3C52B6E4113EFABBE73E96FE986BE
+:107CD000A6DB41746550E9F821A2E3FF8BF47BE257
+:107CE000FBD0EF207974FE14DDC347D3B14ABF0344
+:107CF00074C8E69B9206E87928BAC17E8B9206E8A2
+:107D00007AA87EFBCEBF1F93DE07C6E9BD2CDDAB94
+:107D1000F4B759D0917A0F5429CE79FDD78CECFE67
+:107D2000A33D46F577C6357E11E83FCAA3AEB072D3
+:107D3000B97FB43797FB193D66BA9F9AE95E29BEB1
+:107D4000BB0D5D23C6AD11F27EA6DB755939AFEAD6
+:107D50000B55DFFD4F7C774398008000000000004A
+:107D60001F8B08000000000000FFED7D0B7454C75E
+:107D70009560BDEED73FA9919E3E881692A085C022
+:107D8000164640EBFF053D7D10321FA7C1180B9032
+:107D90004C8BE0041B49DD60E2903D9EA131321224
+:107DA0009FCD621FCC7866BD390D038C9DB177C025
+:107DB000561C610BDCE237384BECC671189C4C3C0E
+:107DC000C243086C6CD318C743B24ABCF7DE7A0FC3
+:107DD000F56B750BDB43EBCC6457E740A95EBDAA9E
+:107DE000BA75EBFE6FD5D37A3363CCCED817F85380
+:107DF0003DBCAC081A19CB65F4F305FCDBE2F2EBF1
+:107E0000252B63DFB9EECBB443F9932CDF0A671E51
+:107E100063AF5F35CAAC88B1AEA9E3F6EAB387FABF
+:107E20008F75088C15437B12748676EF54C17700EA
+:107E30001E31D1272E9D1E7DDE9F4CFDAECD958738
+:107E4000B3FA329D63687AAF3E8DB159F89B0ECA82
+:107E500020932D33A0CCED5AC712A0CC2CF9369626
+:107E60004C622EB1843193F29EE9CA6BDF15F03972
+:107E7000931983FEEB95F556307F5D0DC031CFCC65
+:107E8000BCF189387AD3C9C9D05ECD970AE369D7E6
+:107E90001DDE9FFEA529F3E430362E57A0F5CDFB5D
+:107EA0008CF94CF06B756EEB023603E78771CCD121
+:107EB000C7A9601E99E9011DE55EDB2AE83F6BAAB0
+:107EC000C9E1E5AF4BF8DE6CC6DF1B3ECE7AC64A91
+:107ED00086C6D9E209C8FA54C68E494CE92F5B6FB1
+:107EE000C167E7F8C37A85B23E536ECD55C4CBEB7C
+:107EF00092C7E10778670F868D6F1DCB583A63559F
+:107F00009F699F8B0E6D7D385C30FB58FAE54F5FA3
+:107F1000C07C4633C78F395D47F8795D32FA903EB1
+:107F20002AAED4EE6293184B96EC87FCF0DC2A99CB
+:107F30001D3E053633F6537EAFB8020404ED9FC2F2
+:107F4000BF1480739B6EEF5A27D0DD166C4C1FA2B6
+:107F500097250B4C1A38962E49D4D49B9AC769EAB8
+:107F6000CB574FD4EC6F73DBDD9AFA431B666AEA9A
+:107F7000AE274A35F5559DD59AF156EF9CAB69FF72
+:107F8000D6EE6F68EA6B9E7F50537F74FFCA11E98B
+:107F9000221A5F88B691E98979053BD2BF884D3AAC
+:107FA000FCCFC59CD3A3F7F7217FC27EBD6EAFB7D0
+:107FB000AD82FED5573F8DE7FDB4F4C5BC7200F924
+:107FC000A356D91798C72B407B8D52AD95BE45F46B
+:107FD0005E633645E41B95EEB60A5611C7AF66DA06
+:107FE000FDAAB06DBDAE477E2E1AD0EB61BE5937EB
+:107FF000B5FC572135FC06C767CCAFC7F584CBA5C8
+:10800000FFEE18937A399E60B57F01FCC4ACC98C31
+:108010009547C7A34AA7B75D37635F6FDDCAFCEA20
+:108020007A2B58A00EE93EDABA673BFC7A926B5184
+:10803000D61DBE5E15FEEF6F865F81EF5FFF23F3F7
+:10804000ED1310DBB288FCE6DF5DEBCFB52B400211
+:10805000BC27157AA8918227128B900E980365830E
+:108060007190F9510ED433C16F8452961C04AF380D
+:1080700068EF34302AEB717E711086A6D245EB355D
+:108080000ECA8D286F452CA9EE9CC7EB8E065E8725
+:10809000F7A82ED5F2BAE73E5E8792EA5E27AF4395
+:1080A0003FAAEF5A8CF5CEB8C0894401EBBE2558E3
+:1080B000370E1E5ACA4BFF05814A99E49638E85D8F
+:1080C000A7A77EEC22AF073771FAD0F283315EF6B4
+:1080D000F9B3195F3D3C3F81BF4DC2FD5CD76F00D6
+:1080E0003CD48A82C30EEFD50C32873F15F7D5E416
+:1080F00090D997E033A033316D88CF8C2C98B14A5A
+:10810000203E790FF1ADCAEDE1E368E9AB1EF55A07
+:1081100001EC3BFCBE3119E530A7A7FAB2E0122C06
+:10812000F1F913D03E7B32FC4B1E4E1F2A5CA2326B
+:108130005FA5B55F8FAAB6321826B75917D15985F2
+:10814000799D2CD987CB6D7150E52F2E2FC2E1562A
+:10815000E5AD391FF86C1AFB3A7C96B90A6AB3AEE2
+:10816000BEABF0D9BA303E93ADF79684F019103219
+:10817000D3F0D9B7899E6E275F4E09837526184FB5
+:10818000F60CE823CA9954C04342243E9BFB1BB221
+:108190001FA2C89737F01758676E7E989C51F45C01
+:1081A000B5AAE7FEA8B3A2DDE2677A11CB707CC85E
+:1081B0002C3B31D273B53CBE0906BA6BA80EF890C1
+:1081C0000F81BE631F15DC06CF9BC9CE62B85A80F3
+:1081D000C7AAE2318C6EAD712F9D90ECBC05F5EC19
+:1081E00018856E4E66A711DFC376BDC742E49DB504
+:1081F000E8CBF101CD3709C7736622BFD540DBC696
+:1082000082E1FD33B10FF09935C87C3E78CFEA08A2
+:108210000858AF46FD9E8DF4CFEA51FE575F09E83E
+:1082200025EAA5E5975B7400BF3F01A4578B7C51FD
+:10823000309C2E64E6D3E37E7CD5FDAFB61F349030
+:10824000BC0EDBFF9A41B0CF004E39D5E420FA1ABC
+:108250006464CFC84EC1C748BEAC21BCA8F6E3AD2C
+:10826000F6266817E8912E627BB340F6D0A76CB370
+:1082700081F305F3FA557A86E7CBAF303911ED3447
+:10828000CBF3D47E6C1323FAA8B6973C556747B856
+:108290000676CC44B824BD0A973F15C7BD60E2708E
+:1082A000F9DA087FD50AFEE4411D3343BBBF4F69AD
+:1082B0000FA35FFF20B7D3FC4FC42B70DDC8F04382
+:1082C000BF07D04E069368E5DD03FF4384F7DC6902
+:1082D000773FDF015DAE28F0FC6F856E3FDA2451F9
+:1082E000B93ECDF5FD7CA0C77F916E7CE266C80FDC
+:1082F0003944F7D5F6CF27901E52F1D93786F410BE
+:10830000C24DF8E8B34483DBAA107538BC0ABFE558
+:108310008CC8572A9C2A7C577C7AAB0BC67BB3E768
+:108320005F131CF621F84B45E77E84FBCDC14F67F8
+:10833000B888EF9235766634F96652FC88A44C967C
+:108340002BA6A23E8873CC85758CCB74D1BA4C36E3
+:10835000A31DFD024B2793F360487382CF8CF0F787
+:10836000A737ECD243FBD6A92233C1FB5BB3BC36A3
+:108370005AA7FE0986EB9993E96103D6E8F377657E
+:108380003E29119C835047BFC7C6F1A29F68F4F8ED
+:10839000E0B95FC7D61C0AC1CBC102EE8F9DCDE705
+:1083A000E5DA171ED97629843FDA0FADD3D4DDBDC7
+:1083B000DFDB762954DE6E1044DC9736858EDBD900
+:1083C000C004F45F5A453BE1A143379086F56B2C1E
+:1083D000787E0AAE0FE78F00FF3FE75B623DFFD27A
+:1083E000A950F68FE1FE69FF241FF90DEAFC1F2B4F
+:1083F000EBFF385F177338A6011EBAB3BFC5709F75
+:108400006A6C7C3F4D50727AE67243F577869E73B4
+:108410007951A53E0F3ADE73121DE91CA8764C99DE
+:10842000F611E97D27D2BB71A8BEB548D7E88BF01D
+:10843000FE730522C17BC016B93D5BA1979D135CFD
+:10844000DDD9E8DF3FAB736C8625CECBDC3A1EE589
+:10845000FD56DB7AA253E6E2EB58C038BFCECBF430
+:108460007819E8D179FEB782422AD68DCCC286F837
+:1084700057F50BE7893ED101FDBBF2D79971DD5D60
+:10848000B6F5661CCF84D6826E383CEABA0FECE6AD
+:10849000F3CECBF489E0E9B2B9B97BC501A83FA31B
+:1084A000AC7B5EEE3A6AAF6AF49F14097FE06743E3
+:1084B000DDE868F5E23C2687BD46C23A736CC6B279
+:1084C0004F7889EC1355BF0DE94FAD9D72FABA9103
+:1084D000E463D7159DCF44F2535E3007DE9FAFBCF7
+:1084E0006D0D727BBE6BBFA35FC4F71C02F9E3F393
+:1084F00073BF4D769D35772EB7E7B3567991549873
+:108500004FF0A13F314FC55B9E565F191D17B7A0B5
+:10851000FA30DED4EAD1592CC090BE2AC2FCF370E6
+:108520007D3BBB40B1D7725931DA2B2D26DF63C8B2
+:108530000F960D423AC2A1E27545818EE820867CF5
+:10854000B06726945DD965B4AFFACCD31704985FB1
+:1085500017DF6643BED0DB8C7EC41BB38A1F0DA819
+:10856000F34DC2FF3325B2B7B08E842F7D3979FC2D
+:108570006E96C786EBEC32B0A648F2A7B680F3FD44
+:1085800007597E920FD1DA8D1B04D27BAA7C376605
+:1085900032D937C278DB8C5CCE805FD22B40BF3EB5
+:1085A000A417A0FF175AB3F7E905A27B19E5F1ADAF
+:1085B00052B1EF120BB91FFE668189CA93CA7E546D
+:1085C0007F7136C33582FCAFAAF23084DF94CAC70C
+:1085D0003365F2F14C222F7395713F2EE27CDC5C07
+:1085E000147BB95F9A337AFB1C4B7A8D87522890A3
+:1085F000E879DD9887492EC5126F39A38837A35DC6
+:10860000A13F07A713B5FD7345DEFFAA20E674B2AC
+:10861000B47214E5412CE9A4E2CF83DECF97FF7951
+:10862000EC47DA68AEE3A399F2D442E093BF9C2E04
+:10863000DF83E596D723DBBBF3632F77D31E8072EE
+:10864000F104DF3723E9B37985B197FB4BD1BE48FD
+:10865000E1F645F8FCCB153D144B79D20465B31116
+:10866000D61F01FF8F8EC2FCCB7350EF727B81E56A
+:108670009EB9A40FB1DFE167B22EC43E067B141C85
+:1086800041B443053992DDED8DFD7E2D7D483F647B
+:10869000AFCC615C1FA8F32F2CE1F87A7A14E0B01C
+:1086A00000DEEA256EAF9BC2E050CBBF2D8CBD7DB6
+:1086B0002AE943E04805BB1FCB0542447BAFA7D066
+:1086C00018737E1A0B78D9E2608D91E4C9C9D8EF8E
+:1086D0004B9A0DCAAAE9CED328D7964B87E7605CA0
+:1086E000F9FBF81FE61BD279BE61A5C1E545FFAED7
+:1086F0004BB23BBC768C47ACA2FACA7CBB43AF52B0
+:108700003EB6DF947CDB056CD7517DE5EF241FDAA4
+:10871000C3DF17D69DC9C6F136EB1DFB18C69D9564
+:108720007C838DE71BAC369E9F106D3CEF60B529B6
+:1087300079071BCF3B586D4ADEC1C6F30E569B929C
+:1087400077B0F1BC83D5A6E41D6C3CEF60B5297908
+:10875000071BCF3B586D6ADEC1D33815E391369EB7
+:1087600077B0DA78DEC16AE379079897E71D6C3C49
+:10877000EF0070F1BC832D72DEC13A947720FFF1D7
+:108780001896A467B85F7F54A9CF067BDD34637861
+:108790005EB56AE7FE2D1817AB0972FC5539785E95
+:1087A000D914B4770A307E4566B0DF04FE65451102
+:1087B000C3F0D5B0F9C3F313DDD9E7BD02FAA3B016
+:1087C0009729BC03E529EA187F3F7CFE6171573B7E
+:1087D0008FE7D6657E8BF03BBB2C4878C3E71887C4
+:1087E000AD53F213B556ADFF2A7FE6B2F9715F992A
+:1087F000D49908F890456DBB88F92F8CBB5EF1D7F2
+:1088000061DCB76A501B7715331BD4B83CCF4B845F
+:10881000C139DFE11C5F046B6A017F2A01E6CFC129
+:10882000A415AE53127C5EA4B7DD1B88BEBC3B45CD
+:10883000C71468AA0464609EA512206A86D254C632
+:10884000ACD24CF29B389DFED7D4BDF1D9280F0392
+:108850007A46046C233CA8F9850458BF3483FC2B6A
+:10886000F2EF2A33FDBF473A50EB82CCF338825DFA
+:1088700062CD802FF96E265C3693ABCE906FEB45C0
+:10888000E635C37341E9379B05294E2D3389F276CE
+:10889000B5CC4165D174576911F0A3CEEC75E17A7E
+:1088A000AAEC6609F9853DEE3CDB48F1E47AE93251
+:1088B000E04900F6F862DA48768AC82EABF81C4523
+:1088C000BB481F2F7822C9AD8AD8EB61B2832A0A30
+:1088D00019C9C72D2CB2FC7CAC84CBCF374B5DDFE4
+:1088E000443CD7FB16D58F872E8FBED04A799B6D1F
+:1088F00061F1C25BFD8A626F4724E7903DB901E9EF
+:108900007AF1048F0DE18816C7782AF6F0EC491B3E
+:10891000C1AE7B7614EC5AD443B7EC2AFB9993FA98
+:10892000503BCAB10E4FBAD0EFBA929038AADDC30D
+:108930003C14678D1CAF796914E22099A8BF13FE1F
+:108940000B9D63EA3A02FB87E5FBBC54E1F88E42DB
+:1089500087E34B63CF17D3A0D4273E610B8D1B77E2
+:1089600059040E9741D0C0F5B962FFFDA024F678F6
+:108970002A81727DA9FC2EF261D574F96758AA7C10
+:108980003BDFE1BA40FC292DAA4F02F9BC667F7695
+:1089900001EA8906DB5EE32A80F7D552F9FD223A27
+:1089A0006FF41F5B1E6EB11E8F47BCF7B922CBA3BD
+:1089B000BB1109C5E44FDE28E2FEE467848728FE88
+:1089C000E4AF8B63BE2F7BEA7386FCC970FE1F5B2E
+:1089D000CCE39D6347018E06285746F1EBA68CC277
+:1089E000FC8D5ABF6EBF3E44CE104185E6696CDCFB
+:1089F000AF6311FC3D9735BABF377B14D6B110F386
+:108A000071B591F5DA7DC531F7AF967E03CA0733AC
+:108A10005BFDA9D0C4BC306FDA50BEB2C9D5AF0F70
+:108A20008D733F38E1E037E508707EB338E672F2C7
+:108A30007C9C1EF975BD19E1E96A067E8DB05F2543
+:108A400025DCFF9B3BE111968876633A43F711E4FE
+:108A500009CF3736297E6383A27F762A72D4532CBE
+:108A600052E92CE5F5B951E8FAD7CAFB8D4A9CB614
+:108A70005162F22B91F47FECE9E6FC3828E7C671ED
+:108A800038EF0DF3CFDF53F4C49ED8D3CF9E0CA0A4
+:108A900093B9B591F17530F674B17402CCBFD4F6C8
+:108AA000F41C90F8B02F9B0D945F9C2EBF580CEFD8
+:108AB0006D8BC2579F2B7869863E3AB0FB5BA03422
+:108AC00042F91090815440FAED55EC6F018E30144C
+:108AD0002004DEF1E8E7F43AE41E7CCE5C6DE47F2E
+:108AE00084C81BCA9F569939DF74A783FF88FE0E7E
+:108AF00033D33993AE20CF9F7665F2FC68383C6A59
+:108B0000FEF46F458F19CF71776516C485F2DDEBE2
+:108B10009B98266FDC7585E785C14F8AD3FA49C9D2
+:108B2000E427858F9F90B9745EA87F24C8DC1F025C
+:108B30007F26505C3CE417A9FECF987CF95CF17F5E
+:108B400002FD1DCD9F1147490F8B30073EFFDD749D
+:108B5000F9DF108F23D0D31FA3D0D39FB0DF7F3492
+:108B60007A62CC11B768CCF071BBB21EB7B58E700B
+:108B70003F2021D31991CE54FA027A9B503276E8E5
+:108B80007D21F3B44A6F134B8ABF3EBD5DC0BEF07A
+:108B9000EFACE1AFECD649D1FB9DB57ACC280FFA0A
+:108BA00032D79BF19EC4D4992E07CE6B11996C00DD
+:108BB00038BB5C3E339E7B003B2FBF6484BCC1CD81
+:108BC000222E3F7EADECFFDC099CFF2A960BBE7D7A
+:108BD000C07F4D6C9701F74D7DFF5849ECFD887BB8
+:108BE0007248EE35968C20F75E56F8E273055F2BDF
+:108BF000DAD629E7995844FB6755ECFD8C342B9461
+:108C00007352D745A4E35B7487E78522AC6714E20F
+:108C1000E0E7C7E4E03C4CCD2B6D40FC3E56C4F190
+:108C200017CDFE7D6A14FCB38900D74AF69901FD81
+:108C30006959FFC7AC48E7118E15D9399C069003D6
+:108C400080DF9559BAB731FCD995A4B587D4F767B9
+:108C50002BFEAE6714E467520ECEC3F11A7E0E4CA3
+:108C60002DCFC53E1EB0B488FBB9FF80FC0EFC734F
+:108C7000A8A458E3E7FEA864643FF7B57F8FDC1A29
+:108C800050E8A8CB11D99E7D21F6FB40E7E060DDDE
+:108C9000EF7C15B9116E6FAAE59ED8DB7B69597A16
+:108CA0009C87C3D1C8B4E7246EF1DF28E02D5D8F27
+:108CB000F368E97725E3FA5F85C3581AF3738CE705
+:108CC00067E831FFC3F9797DA92BBE94EC368F1983
+:108CD000F537D80714675FB939251FCD2AD8676BD8
+:108CE000A996BE934A47A6EFE4D23B40DFAA9CFC7C
+:108CF00017614C53A8BC99A8C89B69A5B1DFAF29DF
+:108D000018AF488E2CAF2B631FE7DB73774E747957
+:108D1000AC9E37FB47411B4F6EBD258F634E4769A5
+:108D2000A9FA2179ACEA87703C8D865E480CD10B9C
+:108D30000D51E4CC68C03136041FB59D02E5AF98F3
+:108D40008DF9A6C0AF9DD839E4DEC7965188134F80
+:108D50000F8D7FC860AF47A0E3DDA5B1CF7FA3BC77
+:108D6000E9377CDB36D2F947A3D5C5283F6273319A
+:108D70003BEC9FB1B395F2F6C605AD9487669D02B4
+:108D8000E5FD98F42EF979AB6CDEA7307D365C9E5C
+:108D90006C8D395E8B72D897F637C5287ECDEBF88F
+:108DA0004A3AF937AFA33C1524EE47B30DCC4EF742
+:108DB000A4AF7CB9FB582F2012302F9AC4E83E761E
+:108DC000A7E1C77ACC471B053EFE5CE6E7F94F9763
+:108DD00077FCA3F09EE5A0317F3B547F519A4DFB79
+:108DE000DE69E5CFBBF69BF39F84A59EB6159EC1B9
+:108DF000F3E153A727531CECC5038F6BECEC5ABC73
+:108E0000C7807EDF0B1E867EA229D33571243B9C52
+:108E1000317F92AE8C509AA8947A5EFA059D6DF8D7
+:108E2000FB3BF7F748E867BD78C04C727FEA819E4C
+:108E3000F85521E32796713EB6063DFE1900AF3581
+:108E4000D3733209EF1D2BF9739179CED4C22B6302
+:108E5000A4009D0FDF91576B0EA5BB2EA9D64C79B0
+:108E6000E45C9D638A1DEBFC1C43FCF4DAFD82404C
+:108E70007EDD2E1150EF9AE1BA867AEC0D89EBC3B4
+:108E8000A9536B49AB752AE71E76E42D3980EFC7ED
+:108E90004FAFA7F13B59647BCC58C6E5F08B0699E0
+:108EA000E67DF18048E7C855BCDE697CD6CB300F43
+:108EB000E0A3DEA6A77BD8A78D4E11E5D0E93481CB
+:108EC000ED822DDFE97885EE99EC8802EF2F4AB923
+:108ED0009FCA6CA9447FA7F7772E8F747E5FA5BFCA
+:108EE000C93364A90CEDC0499E2694FFCCB6E43684
+:108EF0007CF124DFBF4387E6CF03FCCF7DC17F2217
+:108F00000EF7216BCF785CF707A5766ABF450F1F78
+:108F1000BD42F4B0C5C8EFE37875718E03B08E859D
+:108F2000D60111CF4F18528394E76D2AE3F2748B68
+:108F3000CA0F63811FE03D7D06BF07C526DAA9CEB3
+:108F400026072784DEA39E55A6AC970532F1F9C209
+:108F5000F87737D81D8C15F6A6378BB0FE8589EFCC
+:108F60006EC8867A49EF785ECF78F7B36C89B1B274
+:108F7000DE0C5E9FF6EE6793A05ED19BC9EB953049
+:108F8000D478B09B7AB39ABD7938BEA419BF150FB7
+:108F900072147FFD526FD2458C5F3528EB871F031B
+:108FA000CEE3ECFB473AEFE2345BFD782E83C986D3
+:108FB000B0F8193485DC7760A90924FFD4FB0BF3E2
+:108FC000457F3FF6D799FD84DFBB5927D97380AD24
+:108FD000DD5F147E797B2E5CEE6DD9C85C784E8C9B
+:108FE000B16609EF33084CD67DC1E3784E9C5F85AE
+:108FF000479D7F185CB0B5C89F43703D4FE3A87094
+:109000005DCB377951DE7A6B59AE27044FD784E0B8
+:109010000F186C45DAAC1D0FE13E5D1B139C204020
+:109020003DB97C1BEDDBB5B1C11F088E90BA81EF55
+:10903000635B6F09ED639728B7219D9B8CD66E21EA
+:1090400091B1EEB884190CE6D931D6E5C57B6E40F6
+:109050007774EFD89B65741C0038EB8BB4F9A1C70B
+:10906000153AFB83220FE6987679CE015DBA7B0430
+:1090700086F770DC83378CA8FF16F65D3462BEA4D9
+:10908000A3E7A211E9BE03EB304EC7F3C688F96F20
+:1090900063B95EBD2F4AE791D64B1C4FA7B2EE7A5B
+:1090A0002A15E0E9582DD0BDBCF54792E6607D7DDC
+:1090B0002BAE92B1E55587E720B9B438FB9FC27259
+:1090C000251B38950A24B4CCA567F6103DB9624D2E
+:1090D0003CB387E8C9164F8AA6BE7217ECCE0C289F
+:1090E000376668FA31E5FEEA3236F483E7989A94F7
+:1090F0007D5C66DB19C0B8EE3297C13B1032DEC230
+:10910000BECD6232C2ED111C748DD2CBCF3FADE02B
+:109110002B84521C7A1FCFF7F40AC4EF1D6D7ABA64
+:10912000C7D3DCCBEDAEE63582CF2E201EF8BD0DC9
+:1091300077AF40EDEEDEA7EB9311EF1B000F00477A
+:10914000DAF8847D2C114793E9DCD54A055677DFA0
+:1091500039038EB3E23B02DD6755BF9BA0C2BFB2AD
+:10916000A991CE91017C5EA44F759D4DF647E95CB7
+:10917000D5CA89970DA887617D970634F8D4D65B48
+:109180003CDAFACA8DDAFAD132E59EF234360DF9BC
+:10919000E9789920E23924B5FE51D6F9B7F15EE7B6
+:1091A0006ED1790AE9B3CDE89F81FA7EB7E8A2BA19
+:1091B000DA0ECF3B18F19DF8E100F1B140FCB9C5E2
+:1091C000204B35F83D977681E87605B6ABF3670F0F
+:1091D000BD4F75FDF0FA4D55EE5A9C1BE8BB30476C
+:1091E0000509ED907A511693F3882F229E77F9BDE9
+:1091F000C2076FA3F603B8EE4222857DBAEBFE44A8
+:109200009F17E6BDEBCD563AE7765721D0811DF981
+:109210005E47E7D6E6E3792F28EF03796881F22EDF
+:10922000FDA12692EF338D12C977E59C972A2FE492
+:1092300017B5E7B6E6679E213BEBBEE776D279B578
+:10924000C93972C1D3A80F2D7CFE1D4704DF6618F3
+:10925000A723EF34C9CF71323F2FD76153E4682F72
+:10926000C85175FDB0BFE350AE612269411ECD9B70
+:109270006E56A95D263928F86B75E8FF8E53E6DD3A
+:109280005F6DA775A73D7A48C0756731EF6601E647
+:10929000BB823A7CEC50F955EDD7B5F80BE85D563A
+:1092A000AFB5635B45D7E365305FBB6DC0C8CF2DFD
+:1092B000068DA81FEEE0F8DE48E3C3F27574EE50A9
+:1092C000E2FB30473F988076CEFAA339E3D808F620
+:1092D0008DDEACD3C8118314A79137F373B5F26751
+:1092E000A1432B77BE5196A3695F244FD3B4DFDF30
+:1092F00058A8A93FE0ACD4BCFF60539DA66EB2CD88
+:10930000D3BC6FB12FD6D4E373976BDE1FE358A5A0
+:109310006937BDF5A32601ED71B377C00578E8067E
+:10932000DE284B1ED223D312E06528E30A2D562CEB
+:10933000BBF34D744EB67B3CE89744ECFF1D3A7787
+:10934000694E7CC95C03E5DF0BBE5AFC7E0EA0C9EA
+:1093500085F6DB3D4F68E3F0C7AB385FA96543B9DD
+:10936000EBC10A28F35EB067F07BE9817B707FCCAC
+:10937000718CDB45AF99C92E9A89765388BF71B03D
+:10938000BA667E39F67B42BE17F982F532690ABCAD
+:10939000B7CF083B8B7AEE3523F5CBEB1DD085E6B6
+:1093A000F77F59CEE5C1B3CEDA7B71FC8E3ED0B2E9
+:1093B000C84FCF7D6844BFAEA3AF3F01F5D90CE7DE
+:1093C0008746B4CF879E2B7A4E0CC6619CE31F0E56
+:1093D000E923DE63DD5E6EA4F14F2B72BDE53B7ABF
+:1093E0003A4F8BF7376B4A86E473CBE1A01FEF63EC
+:1093F000B7B4F37B9B788E36929C06F9FC61A8BCCF
+:109400007D361DF4C14C1A4FA30F9697F9E9DE3E45
+:10941000C86FCDFB2B97345CC57C25C871EDF34C30
+:109420007E1E96B10103FA7320D735ED1BCB95FB59
+:109430009CD358DE1720072E3823DFDB7DBB8A9FA5
+:1094400033B8E0AAA37D7816F089E7479F1D863FD1
+:109450008ED7DBE1ED65A48190FD1B66FF5771FFA0
+:10946000EAE52872FBA2B2BFFB8440010A55B7337C
+:109470008EE87785B975EDA542DC97CFB7A2BFDE40
+:10948000F22381EEC1FFB2FFAD343BACDF78F8547C
+:109490001ADE97761F3A9586F789DB0CF6CD68CFF2
+:1094A000037DD03DE48E5E3FC1DF7EA8B01F9FB735
+:1094B000F70A0E14C9EE9EEB0DB44E36B015FDA39F
+:1094C0007D51E03A58CEEDABC3E5762ADD2E9813F8
+:1094D000F57E8FC9E713901E403E215C47C00F8286
+:1094E000FABE6DE6A648F6D46505DF27B71919DE82
+:1094F000FB6D83FEB88ED359A78DF8BD8596C3B09A
+:109500002E01D771EE81781C7F8381A19DA1C2F7C6
+:109510007156E0035CFFFBAB0D0CCF2D6F59AD27EF
+:109520007CBFBF81DB27FA877FBD3503EACB802E66
+:10953000F13B0F2756DF389D01E3BEBF86DB69751F
+:109540000F1B882F97AD136EDD4B0EA56B956EFF2D
+:1095500046A1D370FA0DA7DB61F4BAE6EBD1EBDBE1
+:10956000E5B7EC9019A8F761FFE78C433AFA1E7350
+:109570001C407E1A3C611807704FDA2A39C0C36359
+:10958000D3F5BEA7D2506E9CE0EDF96D7B052E7F22
+:10959000ECCB717D19DD4686F7082E2AFB7651D972
+:1095A000373B0B0AF1C8CF626012CAA96C25CEF90D
+:1095B0008A81351D46FF52E4F267FA8F6D7BB787CB
+:1095C000D0EF7F2BE774ABCAC56946E63A6CC5F7A6
+:1095D0000F8D5F04E3BC6CE0E7352728E34DC90934
+:1095E000362C825257C1E5E46F1538D4FA9F143EE9
+:1095F00060277F43F85C68E6F89FB7D1DF8CEBF813
+:1096000099C975BD1CDE5F30E17C1BEABDEE493FA8
+:10961000C9E3DFB973901DEE56F07FA2FC37CF632C
+:10962000EECF32358EF6D772F46909E9D932A568E2
+:10963000DC48F130F7CD6CE64A01BABA9943A55A35
+:109640005F74FCAA7180FC82EB0DC42F37D3E9B99B
+:10965000DAEF5305EEE9468E07D6974A7A1BE4B651
+:109660005816926750F1A0FAE39629FB69BF1E5B7A
+:10967000C728EECFD8D3848F156DE7845618E741FD
+:10968000836CB002BECF2736ADBD3485B19F6C620E
+:10969000CC050B3ABBC9CC5C77037D6C92A81ED875
+:1096A00064A3FABB9BEC545EB638C7A2FE79E0A473
+:1096B000670AE2ED44D61E672DCC73EDAC81F04114
+:1096C0003B06F4FD98426B37FAF4CC0CED377A94F4
+:1096D000EFAD28F03F743383B940BEFC02E7838EC0
+:1096E000ED1B7F4672CFB1E67A03FA49F96D17B7E1
+:1096F00062DDBDF1770D685F7C00FA04E90CEC7E59
+:109700006613509E9C33DA810E9A6FA6D0382FEBE9
+:10971000820DC877DE630243FAFCA0F7BA711CD74A
+:1097200057742DE1F94D74E69F2DAD4822FCB8FB2E
+:10973000F2757C7F8B74A1F729FAEFF94302EE876B
+:1097400079A3FD9D4AEC7F46CF90AFB7D70613A40F
+:109750000872F8028C8B97A3701D5886B73719BD15
+:1097600053F03C419342C7E1ED8B15FA044C1B9436
+:10977000EF2932218D9F23C19F1658526232F94141
+:10978000FE38E0E796BEBAAB22961E817DA8F5CFE3
+:10979000D88721767C343AFCB2257E43E6C3294340
+:1097A00075F42343EF7FA01F19E9FB82A6ACC9E340
+:1097B000468A77B907C0BE83FDEA00C3C99E82F41A
+:1097C0003E8DCA4F8E74D9917FCC71C13DA82FD8E0
+:1097D0005D3AF23BDABD5A7BA841E18706C51E7AA5
+:1097E000B442EB3F819FD45EC1FDA484E34CE33FD0
+:1097F000853F27FFC98C7C05F34E83FD7925D2FE7A
+:1098000054D5AEC77E13D82EA27306748EF415BE3F
+:10981000CEBFA8E07A54E5EB65C8D748BFBD9CAF82
+:10982000C3C76DA9AAF90B1C775B947B10F757F19E
+:10983000F1DA9F13085FEEE752084F1FB3E79CB5BC
+:1098400040971F031CFB802EAF399DF149D0FF9A32
+:10985000CB199F6C1D92031DCFC553BF6D9317A7E6
+:10986000B442FD19A47B18EF93DE3A8A6F3EF41CD4
+:10987000E73F75BE0FFCCB52909F8A0D41A303DAE0
+:1098800033FB2E26A01D587CE4FE14E4C368706EE2
+:10989000AD54E0DCF8D8DA4B299C1EF01CEE5A459A
+:1098A000BFB99FF41B11FF6B3732A2DFFED77ED901
+:1098B000817CFC495FBC84FAF0E3A3F15E94FFD79E
+:1098C0008E997C3A81FC106F22C8B58F0D03F791F9
+:1098D000BD79442FA1FFE83EF6DB3DC88FEED74CA3
+:1098E00068F9B1B57D5DD751EFB5F5DD7B55C4F2B3
+:1098F000A5D1E587F68D8FD37AD5FA6F3799ED2804
+:10990000473F11B99C58DBFB2AD9BF6B076FCCC00E
+:1099100038EAC747FF4F09CA35F79B374A509EB907
+:10992000DFB85182EDEE1FC77B22D92D71B3F484CD
+:1099300057555F66BF276AE2451B14FAC8EEDCD5AF
+:109940003809F0577C6E8903F3B66A7BF1149D13D6
+:10995000DF2FFE797DCAC321FD3A0322E58D8ACE31
+:10996000D5C7AF0EA1CB47AA0C9AEF947DD5380F7F
+:10997000B6E2F72D6FC575023AFA0EECB680C8BF95
+:109980002FBB46F0A1BF01F64B783FB2A7AE3D9288
+:1099900042F71099E89C3FBD08EB531CDBED2856BD
+:1099A000CCA72687D84BCB023ABF09E8A8A9CFE4B9
+:1099B000277B3F205EA4BA62473D74FD3763B285C2
+:1099C00008719ADC77E7A01C0F8FD7C0CF18845B93
+:1099D000B5AFCEA7F3F851A647D22D04B89A3B995C
+:1099E00084781D16D7699A4BF1A2F0F88E3DB0DB52
+:1099F0008CFDEC937512C2ABDAA5B88F3D11E4C0B3
+:109A00005F567279A6F2576780E7F53A03B5E6C963
+:109A1000507E5769EF9174CC0B78E9ECBBFF00C620
+:109A2000173A071F8C9F0EF374BEB798619EE79A92
+:109A3000546B9E82FD06E79A1FC81BA29BF0F91A81
+:109A40002AB95D34642F44D67FA50A5F8F961E2CF9
+:109A5000ACFCF3D083E09F575472FF7C058F9F705E
+:109A6000FF3C5C7FA872591D77AD82EFE172F92A45
+:109A7000D939E047935C5E5B69A7F732FB16A59086
+:109A80007FFDDE9214BB75F8F839A243979C377CB2
+:109A90007CD59E737BE55366F47B643DF1A77B899F
+:109AA000E0C3FC976AFFB99D02D9E5EE66830FDF3C
+:109AB00053E10A2CE1F1D8076483CF220CD989AA9B
+:109AC0001D79ABDD2150BB6A57AAF663C0C9E3BB61
+:109AD0004B8A78FB658B6B55E5585CA7859E17977D
+:109AE000F3E78C394FA15FF5E05281911C50EC4AAD
+:109AF000954EC3EDCE4FFB7212478A433DAFD0A7C0
+:109B0000CA6713C2F843D563CF54707EEB403D5E05
+:109B1000887AFCF71AFB3C7C5CD0E38F57523F46B7
+:109B2000FD8B7E2E3A23F9EB6665FCADEAFE054E11
+:109B3000D620BC592CB019FDCC68FAF57B8A9D1350
+:109B4000ADFD19C57EBC1D3F1F56E4C868F1F3CBBF
+:109B500095B7F270FFA9F9F9967D688C62BF57D569
+:109B6000BC86FB1FA7F7046A90FFFE9781E2EEE137
+:109B7000EF3DA5FA9F22D3ECCFA92CA30EFD23F72E
+:109B80001A1E3FE84EB2BF437ECC5B7A86E3AC053B
+:109B90007F10EDB8476F2651D986F632942B5E3888
+:109BA00047F988156BB4F077634C17FBAFCBA6F37E
+:109BB000032DAC9EE24C2D7D49D216500ADD630F79
+:109BC0009D46BEF21ED0DB0F84BEFF88FABE99C749
+:109BD000E136A6FB28F71A660FB478C2ED7EAD7D9C
+:109BE00050A9C48DA2D9096FF45BB85C39A3273E94
+:109BF000EFC078D34CC68C7D5C2EB837F23849471D
+:109C0000DFE604FC086ABBD27E450C501C8AF26B6E
+:109C1000F0EAD5BEA7D3E83E97ACCD27B5EFFF3924
+:109C2000C9CBF0BC52720F974BEE36BD92472AA1BA
+:109C3000EF97B7833F390EED4BBBFD1B8877808BC9
+:109C4000F948DEC89AB8CB3E25AFF4E9997F253FA5
+:109C500074C5912879A4EE793C8FA47C2777781E6F
+:109C6000E9F4A90CFBEDF3481DBDE7E81ECBEDF2CE
+:109C700049A6AA5B711C8A3B4E14797C77629F20AF
+:109C800061BC6A621F5F77E9B638B2AF1B7EB53A36
+:109C900005E581BA4F9F2CE2F8FDE4FDCF6AB05F85
+:109CA000C9AF44C902EB7AE3FD0D3FCBE075BBD9E8
+:109CB0008EFD36C4A33FF3C9AFD6C7237EDF801223
+:109CC000F7E7C717C4C8F1C9A178756615C59D9592
+:109CD00078B508FA70CC505C27BCDF8B555C6E748D
+:109CE00083BB4271CD233CEFDF9DEE9A47F5BF9ECB
+:109CF000C4F8DF2990291EFD2AD035C68DA6C16281
+:109D0000312FFD3FE35827E691BAC7BA7E427CF473
+:109D1000D73A3BF211F4A7FC93F7B09DF423866A7F
+:109D200031CF33033F5B40F7315229DF738FB28F5E
+:109D3000E9E0CFA25F09D02CC13CF43425DF332306
+:109D40008E8938FE0E836BFB54CC2FF58B8ECDC4E1
+:109D5000048E143C6F199E7712649E2F57F34F6A3E
+:109D6000DE3C5AFE49C07994EF56F0F396B280F982
+:109D70007435CFC4963A29F9B5A5CC43F7427C8017
+:109D8000B3AF73DE6B84FCCFC31511F23FEB2B989E
+:109D9000629F69F38DDB735F213AFDAA79C6C378B0
+:109DA000AEE28EE6C5ECDC0F0D83BB28E9D334F2BE
+:109DB000BBFEF86F09A467FB6E903EBC1634B10081
+:109DC000C51F0778DCBDCF4071866BE0BF8D0DD11C
+:109DD000B3EF54F0718FF7D511FDF704EAE3F1FD0D
+:109DE000DF2BCFB7BDB7E47EB4F7BD01FE1D0BC6B8
+:109DF000B83FD613108BD16EB983FBF2646584F53E
+:109E000099E3B87E0AE7A35285FF4AAB389EEBDEA2
+:109E1000E77E987B03CFAF488A5C707B785EFD74E9
+:109E2000569AA0C6D3C745CABF1C0992DE687944BA
+:109E3000A0EFC97CD9FCCB33E991F3F12B7A2F4603
+:109E4000CEBF343690FC8C16CF0E8F63FF9D2AFF59
+:109E5000A6F338767A9544EB4EF6E4D78C6343EB61
+:109E6000BF83FBB07456847DB883E36F9C1DDBF128
+:109E7000EBCA633BFE13311E7F7B8CC7FF61796C9D
+:109E8000F3EBBA8AD8C2FFDB18C3DF1F09FEFF5706
+:109E9000CF0784E7FFC3CF0B849F0330BDF5B01716
+:109EA000DBBA849D413FC3EF8DBFD624801C149341
+:109EB000F6D37DCE05E53C1FB6ADDEECDB2B0C9D6D
+:109EC0001B50F1F56835F723A5BCEB5EFC5ED404AE
+:109ED00039509F82F1B272FE7743AE59785E8C8919
+:109EE000523AE6C9E0CDF4C56097745B22E7595356
+:109EF00095F1A2E99183D5358B6715E31F3D8A7CE7
+:109F00000EFF874A1C52EAE5F7E999684F5F4CF368
+:109F1000DAD3D11E4A3CC99F27F899BC97E0B267B3
+:109F20002FE67FDC201BE17B46C9FF26CFBB2B1B26
+:109F3000E3D2C96017625EF069CC0F923F2BD17BF0
+:109F4000EA7C9766713FEA190313309FEB9DCACFF5
+:109F500039B19EDF91FDA6E6F5CE1AFC975A05CAE7
+:109F6000EBB523FC3FD5F9F3F6652B440CF8CDEBAC
+:109F70009128DFF876F9DFE5BA681E9EE77B4CE2B0
+:109F8000AF9C40BF19E078EC6821D1EF8AE3E5FF90
+:109F9000D48CFEC76491F03CCCAF54E205179478A2
+:109FA000871A2F50F35BFFACC4493EC0F80B9403F3
+:109FB000180F8172FB2CDD9DD64FDB6745E0FF67F4
+:109FC000041E1FF2FE94C7870A8D8E9CD0F3947FE7
+:109FD000358BEF63AB9FE72FD478CF0F95F5147EC9
+:109FE0004FEFC7EFA1156E9D6E443D5FB8352B0E48
+:109FF000CB19B24F9706F85EB6FAB04EDDBF487483
+:10A00000B45759E7B63341CAEFBD1A96F7BF348B40
+:10A010009F6768A9E6FB7B09FFA018D41F9B226EEF
+:10A0200041F331B14AD247CA2BB5805F8C70B67606
+:10A0300073B8557CB7F8ED7538CFC553C1AD581618
+:10A04000ACC9AEA3B87BDBF5AD68BFB9076F9CAEFA
+:10A05000A67899D18EFEC44303DAB8DB13D53CFE53
+:10A06000FE2A1AE088B77B45F28F0BEF15897E92A6
+:10A070005B2CE4BF261B98DE8AF545DC2E2A684C53
+:10A08000ADC33A5B9244F660C1197BD2C379437188
+:10A09000B0E47B378C453CDD2ECFAAC6D32E5BE4E3
+:10A0A000E3B89F5F35CFDA7EF63D3A6FAAAE4BC577
+:10A0B0008B9A2F8D966755CF3DB81B3FD39CD3709D
+:10A0C0008BC1068C3F161EBD6854CE5F4AB6ECA10C
+:10A0D0003C6CE191EB947F55F3AD6ECF75B2ABA1C3
+:10A0E0009F11FBF76CE2F9D7D7000E2C7B61DDB234
+:10A0F00009EFA1DBA8EC8375E3F3639B72A9F46F0E
+:10A100007250797C531995F899C9F464CCDB5EA739
+:10A11000BCEDD559C3CE4D525E6FB7E8FC08F115C2
+:10A1200092F7A37A78DE4F1FC7E335EE3306FABE07
+:10A13000A1FBAC99E4774D5FEB44F40F3E3FE79A07
+:10A1400088707760DE2D842E3E911D9624F4839DC9
+:10A150000E0BE6DB0AFBAF1AF13C4C871830623C71
+:10A160000C20CFC0238BEE9EEBFCDC6F5F8D05F1E6
+:10A170007BDBFC58EFFFCF8F7D95FC5877353F2771
+:10A18000ADCA9102A74EDE8BE519D9F270889CD832
+:10A19000E6E4F9946D9327111FEE764E4A5A1D326C
+:10A1A0005E67238F5F24DF3BD912FAFC97D53C1FF3
+:10A1B000962C306724795633FBEBDDC71B416ED7F5
+:10A1C00044B2FB3FF929D0E54CA08B23DF9E3890A9
+:10A1D000C7193F341EB7AD71F5C431289F2E98D8EA
+:10A1E000141EAFD3C4E358585E2E5A5C6E45A34E7E
+:10A1F000B6D079A1E004D4DBE1F13326062770BDA7
+:10A200002E67E0BD1498318395B161F9B95F30DFF5
+:10A21000CF27C3FBCB1A75A42FD43C5D41A3C8360E
+:10A22000017D166C34F8283FD7285EA476C56FEC04
+:10A23000940A3290CE3F386B9430AE161E1F7334A2
+:10A24000EEEF9E04FD1D6D02DD0BBA5D1E4F3D0756
+:10A25000DED2DB3F07E36DF96C57773DF4CF9FAC5F
+:10A2600093F0FCF4F07C1E3FFF5DA0D839E171361D
+:10A27000A433B44BC2E3F01B153AD8389BEBADD7EF
+:10A28000147F531D47ED174E3F3F9DCDF56DB4B87C
+:10A29000FE5165BCCEC6826D93717F17E818EA93B4
+:10A2A000CEC65AF3E490F176CCE6E7DB9EC1FC60C3
+:10A2B0006A687E90E701C3F382AA9C2BECFF7D03C2
+:10A2C000E27B37C86BD4636E1BCF1F141EAB398380
+:10A2D0007263084EAEB777C39E07C8BE732431BE03
+:10A2E0002EFA7B45DEA302C5E70A167C763C1EEA01
+:10A2F000CC9944F7B0DC67276FB1A23C5A2016E333
+:10A30000BD1EB753B89567C27CD2FDEFACA1EFBCC0
+:10A31000163E907F0EF7E58166039D0F54F5DEFD36
+:10A32000EF3435F0F6BD4FC6617BAEE0B0D8F179C1
+:10A33000237D3F76FE4B7EFABB580B113A90E781A6
+:10A34000B39744E49BCB16D7DF231F152E52F24C54
+:10A35000CD5C4F3FD0B7C8C0C8CED3EACD13599F0C
+:10A36000533CE8465F21E58F52F0FC43DE90BE2966
+:10A370003C0A7A6CCC9DD3633F9D2D113E67821EB3
+:10A3800043789217F13C7DF8FEEF50F63F9A5E8AD3
+:10A39000268751FFF0FB63DE0CC1365C8FDB31EEAC
+:10A3A000538AF63A94E3A2D3DF1F6671BA4E8A62EB
+:10A3B000CFFD49A1DFA8E7A77A4727CFF487D97F48
+:10A3C0001E7963D5FF52F34DAABFF6A0620FAB65AD
+:10A3D0009352FEBBEF37A0728D78BF2139F2FD8614
+:10A3E000870E0968A7A8F71B4E1959CDE1543C4FB9
+:10A3F000ABDC77F22D223BE9D4DFFC62EB8BA97852
+:10A40000DF4990501DB51F3A477ABE1DEC23B2A715
+:10A41000FA7ECBE3AD87F8F9F0F6DEC8DFDDDBAD21
+:10A42000D8DFF53223B9D1AE9CB76DE851F244B70D
+:10A43000E2968F8BA1714BB73D30563DC7EB237F22
+:10A440004F1BC78C16B7EC60413AB7DBB14670A022
+:10A450007EB8DD39DC5DCA79DDA8714C79E473B969
+:10A46000E1714CB95A9BC7B96F96C4F7DB250868F0
+:10A47000EF9A75CE363AB77F4C90229DF35E5ACD57
+:10A48000E5F47C250F72D0C8E9E3608540F76FF0F2
+:10A490001E1EEEFBC163FC1ECEC1027E0F47CD7BAC
+:10A4A000A8F76BA60EE53DE8FE9D7A2F47BD67C372
+:10A4B000988FE05AF45C1C7DC76B87E1908DDBBD03
+:10A4C0005E7E3F1A6510E6434DCC13895F6BAB6B24
+:10A4D000C46A7AEF8EDB4F8F5447F07B7D8A1FE989
+:10A4E000AE8EEA2FACAFD6FA0B540FF717EE54DE50
+:10A4F000E38BD9EC4EFBFB87631C8F9E323BB6F19E
+:10A50000C4EC48FBB6C5A2FD1EAF5A5E56E4DFB0F0
+:10A51000EFC50DBB2FC9F57AB760FFA74ACAA71BC5
+:10A52000289FAECAD5EE317CFC1F29E3A9654029DE
+:10A53000BBA37CD7F9974ABCAC4B947B10EE692F38
+:10A5400068E397D30F69E397337B9335F57CFF7806
+:10A55000CDFB85672669DA8B03F768DA4B2F146821
+:10A56000EAE503159AF72BAFD46AEAB382DAF86505
+:10A57000F5CDC561F7387DB4BE1AA0DCD07E75E696
+:10A580006F6ADECB58A35D579647BBAE891BB5EB10
+:10A5900052C7CDF66AD797D3AD5D5F32E6E3F2BE20
+:10A5A0007E3E2E7FB65DC9C7E558B0DF338D932D53
+:10A5B00068B7A9F7A9D5F7FE2F376658DF407F00A7
+:10A5C00000000000000000001F8B080000000000D9
+:10A5D00000FFB3E46660F8510FC17BB918186E72C2
+:10A5E00021F84301CF6786D06A2C0C0C1A40CCC6E8
+:10A5F000C4C0C0CE44BC7E714E047B1D0703C34C57
+:10A6000020DEC831F0FE1A487C9D877E76A9F34291
+:10A610006859C181F73708570A3130B40A3330C45A
+:10A620008840F80CA2A8F2554208B6A924657639EC
+:10A6300002F5030024CC7134800300000000000008
+:10A6400000000000000000001F8B08000000000058
+:10A6500000FFE57D0B7854D5B5F03E731E3393793A
+:10A6600064F2200F02F18400A242180284870827B6
+:10A6700021C4A8018380BC54263C43483211A8BFA2
+:10A680006DBD77260411ADB551691BBCE81D1014D2
+:10A690001575A0D1061CE84014B1DADBA8F8A8D5DE
+:10A6A0007650444048C2CB8B2DD57FAFB5CF49E61D
+:10A6B0009C4C48D4F6BFFFFFFDF1F3DBECB3CFD9E0
+:10A6C0007BEDF5DA6BADBDF61EC1329A244E22E465
+:10A6D0005BF8A365842784F4E92CDB0ADA8F9164A4
+:10A6E00042FC2F8BF2368E10EE778EF0A45184BC94
+:10A6F000B5990B98693DBCCF4608AD9FDE343D60EF
+:10A70000CE2264FF08B302EF9FDE9A8FF5C92FBDFA
+:10A71000E714687BD54BBC0075D3BE13CE889D1063
+:10A72000AFB9E5A16BE9F3F69778B2850E45FC93D6
+:10A730004D2485906316C2FE2EB2FA522BAB566D95
+:10A74000DE7F07F45BDE642656DA4FD5EE65D3AEC6
+:10A75000A5F565874402AF546DAB95FAD2FAF200C5
+:10A760001784FA9A7D7FC671DA0A48797028212702
+:10A770007D16225F49EBCE969459F47945606711B6
+:10A78000BC5FB183739BE8FB159BF67F0CFD5734D0
+:10A790008A0379DAFF8AED36220F61637F4B601EF0
+:10A7A0004BA601BC556F88C44CEBE5975649047025
+:10A7B00024D44BA50E18FF614976C03887701C0D54
+:10A7C0009F55CFD071E877D52F706E985AB589789C
+:10A7D000009ED6DDD6394FDA615EB5D260F87EF7DD
+:10A7E0007D12BCB72C50F6B25506F8364B4500E743
+:10A7F000A6CDD2D2A19DFDADD8FEA60EAE630DD9D9
+:10A80000A99EA8766379D247886CEEAC5710A20453
+:10A81000ED0077409A3EACF3F9792E8190D1D03F8C
+:10A820004F644B67FF9430C807FEF7E83F810FF68F
+:10A830003A02DBB23AE9B5D245FF2D77D2EBAC4B09
+:10A84000A59FD09E17DDBF563E0474A0F0D4FB5CDC
+:10A85000583EE24BC372834F46BCFDCA3704CB0659
+:10A860009F1B9F3FE61B8BE5269F82E513BE622C54
+:10A8700003BE527C6F8B6F0E965B7D1E7CFE94AF89
+:10A880001CCBEDBE1A7CFEACEF6E2C77F8FCF8FC0E
+:10A8900005DF7A2C83BE7A2C77F91AB06CF405F0B8
+:10A8A000BD977DDBB16CF205F1F91E5F1396215F58
+:10A8B00018CB7D405F5A867D2D581EF07D88E5AB14
+:10A8C000BE087E77D0771CCB0755BC3B27907C8198
+:10A8D000E2CDA9101715179258A2E48BB49E58CA5E
+:10A8E000EA29B7F9F3255A4FF1D03AC563DFCA70A8
+:10A8F000BE99D6FBD6B0F6CC7B488185D633FDAC6D
+:10A900007DC0834A8195D607D4B3F6C19BFC0571FF
+:10A91000B43E38C0DAAFDE112EB0D1FAD541D69EA2
+:10A92000132293EDB49E1366F5DCB794C90E5ACF8B
+:10A930006D61F5BC8FFD939DB49E1761DF8F3F1550
+:10A940009E1C4FEBE3DB59FBC44BA4D045EB130932
+:10A9500087F5027B7E6102AD17B858BDA85F9920CC
+:10A96000C7E0BF7D626411A1BCB0DD7FB322A4D378
+:10A97000BA145945DC149FFE39580F8B6431B4BFAB
+:10A98000E52F538471B42E91D5D0FE177F05B61FE5
+:10A9900010656C6FF7AFC2F603928CEDA6DA7BB050
+:10A9A000FEAAA8607B72EDBDF8FEAB9282ED836BD0
+:10A9B0001FC2FA41D183ED636B7F8DEF1F943CD8AA
+:10A9C000FEC8DA805248EBFFC179B6005FD7719EAE
+:10A9D00072920DFC1A4C2BA5FCBA8E2373403E1EBE
+:10A9E00000A6A6F2B02E5D5240BFEDFB47DE933CC1
+:10A9F000A7F27632D4973EF54016F6F31CF623D232
+:10AA00007EF89EFB99F8CD585D3F13BF29D7FA69B0
+:10AA100084F7EAACBDEB67DF37E3F5F07C53A1F5D3
+:10AA2000B317FB71F46E5E13BF9DA087E7DB4AADE1
+:10AA30009F83D84F42EFE0098B6374FD84C5655A4C
+:10AA40003F7FC47EFAF40E1E451AA7EB4791966B22
+:10AA5000FD7C88FDA4F7AE9FB074AD1E1E6985D63F
+:10AA6000CF11ECA77FEFE6A598AFD3C363AED2FAC0
+:10AA7000398974CFEA5D3F071C7AFC1C7074E0E7EB
+:10AA80001CC233A877F32A70EAF153E0ECC0CF255B
+:10AA9000ECE7AADEF573C0A9C7CF0167077E440EB5
+:10AAA000E635AC77F32A88D7E3A720BE033F4E0EE6
+:10AAB000E019D13B785EEDA3C7CFAB7D3AF0938A26
+:10AAC000F08CEE1D3C85297AFC14A674E04746788C
+:10AAD000C6F5AE9F5753F4F87935A5033F57613F4C
+:10AAE000D7F56E5E85A97AFC14A676E02717FBC918
+:10AAF000F76C477808EDC7D17D3F07FBEBF173B0EA
+:10AB00007F077EAEC57EA6D07EB27BEEA728538F90
+:10AB10009FA2CC0EFC14229E6FE85D3F0733F5F830
+:10AB20003998D9819FA9D8CFD4DECDABE80A3D7E34
+:10AB30008AAE60F899248CC07586AE9D6E9E7E723A
+:10AB40007DBF7C85A3EFF32E56E75D6E02760FAFD7
+:10AB5000D933A445E1E9FBF61D09B90F9068BBA6FE
+:10AB6000E076C08F835A79D1764DFCD8389D1D95FB
+:10AB7000A024EAEA49C57D75EFF7291DA06B4F9D1A
+:10AB800073B5AE3DDD93ABAB67948FD7BDDFBFA68A
+:10AB90004057BFE2EE1B75EF67F96FD1D5B3D7CF42
+:10ABA000D3BD3FA87EA1AEFDCA860A5DFB55819547
+:10ABB000BAFA35DB7FA27B7F58708DAE7D78D303E8
+:10ABC000BAF611E14774F591871ED3BD3FBA658B84
+:10ABD000AE7DCC87CFEADAC74576E9EAD71EDFA398
+:10ABE0007BFFBAF603BAFAA48BBFD7BD9F4FDED561
+:10ABF000DBDB963FEBDE9FE2FA4CD77E7DDA9706F1
+:10AC00003BD5EE3A768D5AE741AE08FA25FE740937
+:10AC1000EDD5B043C2BAD4D7CEFC14C752F928E55B
+:10AC20001FE9C0223919F992FE51BB21BF6FF99576
+:10AC300011FAFCAEF19E2B5DF4F95D9267B82B869C
+:10AC40007D43F98D236950CA26288DEDF7898CDF65
+:10AC50000B322E0D3E42BFF79ADA0727D0FA703E2C
+:10AC60003F08F2F1326742BB3A8E2735F05E9C997D
+:10AC7000A0DF745F56DE93FE287958DF9FDA195CF7
+:10AC800067BFEB454F1ADA51B59FF8C1CE59D79F30
+:10AC9000CEAB2F21AF709F84FD03E9F7FD97A67916
+:10ACA000687F6689FA19D1E34B74FCA1387E18E4F9
+:10ACB000E1208C3FBAEBF8E6016375E35B32CB75BC
+:10ACC000E35B243ABE8B90DFD77EAE8E4F89309EF9
+:10ACD0009037B9CF717C7366398E7F9F44FDAEE8A3
+:10ACE000F1E33AC66F81F9BFDFDDFC078CD7CF3FB8
+:10ACF000B3423F7F89CDFFA3DAD3EAF87138FF3F33
+:10AD000073A7D9FC332BD8FCCDACDF8EF19D1DF899
+:10AD10008FC0F8C7BA19DF9C3D413FFF2B2AF5F3DE
+:10AD200037B3F14FD65E50C7B7E3F85F7217D8FC60
+:10AD3000AFA8C4F125B3C70DFC2365C4D504E8F85A
+:10AD4000A41F557CA9C02E741C28872452A12164FD
+:10AD50001B3700E1B82B8EF1DB577194DF509FF960
+:10AD6000F1390950CD9947FD4695D757ECC8974022
+:10AD7000EF613BF5B796A8A02E6EE291BFC90673AE
+:10AD8000601085B7B589F7437DF186EB02A05FBD02
+:10AD900066B2A014BE1348189E7FFECB615BA2E78B
+:10ADA000652C97D48BC72251F2D6E1071690213536
+:10ADB00014BE29C004A33BEB9F523F0E1CE38FA996
+:10ADC000DF43A8FFF399C8C6FB0BF5F7A01EA1FE51
+:10ADD0001E3ACEA416BFA3DD1D4EA3F097AAF07FA6
+:10ADE0002A3079FDF4362EE0A7F2F9D58F47A07FFF
+:10ADF000BDE06E1B457A271C65FE245D9DCECB0F02
+:10AE0000746ADF6D0E6CE110BF32E06B3A8A262166
+:10AE10008BD667505C77BEFFC1BEA907392721B723
+:10AE200012454CA5EFDFBE9AEBEFA2E3CE52CCB9B0
+:10AE30006C1D52324C28D724C33496905B1A478835
+:10AE4000B407325D113F8D448D3BA3585F9F55AAD7
+:10AE5000AFB78A8A68A270B54EE7C866DAEFEC39F8
+:10AE6000FA766D9C81A644466775BC528A9374FA43
+:10AE7000683694B9F0D885749EE362DF6AF078177B
+:10AE800089248C7EBCBF0F01BAFA93F1BD792E36AE
+:10AE90006F23BC73448B524AE739A78C0F007F1B8A
+:10AEA000E1FF689F4D31E5D072FDA32231759D8F82
+:10AEB00011FEB91EE37C8222ACF3F3CB8DCF19DFF8
+:10AEC0001C53E9FF29F0072DBF00FEA0F01F55F924
+:10AED000A353AF32FEF09A3DD3801FDA37F204E974
+:10AEE000AAF2CBAD2ABF2CA9D7F305211E11E8B8D1
+:10AEF0006C0E97FB40141FCC56F96059839E6F6E01
+:10AF0000277E313D065DE66ED87C6F9ADC757E9FAC
+:10AF1000A87C33FFC1FD889FAEF36474BA43A5D308
+:10AF2000ED35FAF65B55BADEAED2754EC3C3AF51FE
+:10AF3000F541E6C90111E4DDFB538D9E111D3D3D38
+:10AF40002A3D8D70DEA1D2F38E1F337A1AE18DA8CF
+:10AF5000F48C349C13C980AEF01AE15B707797F9DA
+:10AF6000605CABCC1F9B9EDEA6FC5547A39E57059D
+:10AF70006F5875344ACE566C9FAEAB2F0FCCD5BDF3
+:10AF8000BFACA14CD7BEA47EB9AE7DD1FA3B75F55E
+:10AF900032FF8F75EF2FB8BB56D77E7BCDFDBAF64B
+:10AFA000F9E50FEBEA733D1B75EFCF9EB359D73E22
+:10AFB000ABF4195DFB8CE29DBAFA7465B7EE7DD3F4
+:10AFC000BEAB6E06FE7CEB3D9E803D71C1FD05C6AD
+:10AFD000332FB84537BC73D427235F1FF30DC1F25D
+:10AFE000B8CF8D7C7FD23716CBD6A6663BAC137418
+:10AFF0005D5C4A12086932CDAB5DDF0FD66982EB2A
+:10B0000069C8E4A9F5D37AB34946792869904878A4
+:10B0100024211C2C362A1CED7C547BA487F606AA1E
+:10B02000F893BAB69744623FF73E527605F06577DB
+:10B03000EB03FDCB00BBA74DB5EB8DED951C298D2A
+:10B040007E4EC81A84C36A627647A5C4E4BF7257AD
+:10B050007A0171423D3CB8E672E3052993A7029F4D
+:10B0600064EBE47859C3353AFD4E209ADC07F86D5D
+:10B07000A4EEF98AEDD7EABE3BB59F47B8AB41577E
+:10B080008C8365B1F43313E8E17073E68C6100A73B
+:10B090007214EB4D7DD02E3CE52B5E757410D0AF55
+:10B0A00014CBE3BE39581EF379B03CEA2BC7F253F8
+:10B0B0005F0D9611DFDD58FEC5E7C7F263DF7A2C1E
+:10B0C0003FF2D563F9A1AF01CBF77D012C0FFBB6A1
+:10B0D00063F98E2F88658BAF09CB569F82A52677A3
+:10B0E0003DF1DD71751D3E09FC1783CFA43A7FED5C
+:10B0F000FA099D7C16C7DF877CA6E1B9A4C1ACF232
+:10B10000438A8E1F12C097433EEBA1BD4154F9B054
+:10B11000BBEF63B77BB7FC6BF86DEA0FE4B74E7E0D
+:10B12000CA30F053764FFC348C8FE2A7A92617B3B0
+:10B130007B547EFA19CC23865F310F8C903E51F6FA
+:10B140009A926F82756CA5BA0F421F60FDAC3A7679
+:10B150001D7DB705EDBAC0105837CE0EF9DB60D8AB
+:10B160004738FB21257E56F7F333F249F77857D05D
+:10B17000BF591AA0444FEADA6E8D6378B59A483108
+:10B18000A1EBDAFD839E722F1C8A758124C2F70120
+:10B19000F774478C7EA9AD0CF8ED09AF758EAF72D0
+:10B1A000A0BF638FFD3D0FCAA926662FC735F36880
+:10B1B000B793F0936EC06FC7BA6476A741BCBD7DEC
+:10B1C00090E442BB814CD6E3CF5FA0C3DFFD1447C0
+:10B1D0002DB8EED6A721FE067E3538BD17F8EB490F
+:10B1E000BFF784CF8530EF7F013E7BD28F3DE945AD
+:10B1F000A2C82F34D1F9B7ED1B96FB800CE35E1E7D
+:10B20000DFDAFE9A119E5F7E473E6E4BD1F8B8257D
+:10B2100093801FA4CACBD9C62BE3812E1DFDF44019
+:10B220004FEE779F6482FF7E3A4BDFDF7DC6FEE202
+:10B2300025C20DA7E33A2489C453BF92F76CE3D12A
+:10B240009F7147FC1037D86773D7C9E0379EFCAFB2
+:10B25000B00C3DEBE30B670F3DE9043F6C651A5FF3
+:10B260007334061DB5B22A9855638FF6579AF4F5D4
+:10B27000B3F55C7110E725C7CF1C06EB8CABE6A8D5
+:10B28000087A3F0D4BAD9F9569128E73727B763CA9
+:10B29000F3FF024C9FEC48407D73D267C1F7FFD9A2
+:10B2A000F074D78F060F218DE4330BE873DA96DD47
+:10B2B000FDFBDDCA83705E82F82909895F81BF6961
+:10B2C000A5FF7F3B00FA15B0AEF5EB0DF27EF370F3
+:10B2D00078BE43371EFD4ED6F68CE1BBEEE54E2020
+:10B2E000C734BEA7F4FBABBABFBD62BBB5466FC7E0
+:10B2F00026E8EADEA6F41A9D5D0BFF00C3BD8613A7
+:10B300006009AB54D9B04DB0AF077EDA03C149F044
+:10B310005F38F65E9525227964149716E0D385632D
+:10B3200035FE9767FF99EAA9136F8A04E48C5CA243
+:10B3300050E5A9AE20F29B8998687D91FAF6C2C6C5
+:10B340001525B06E9D78F926F44316935227F8C759
+:10B35000E5A43E0FE2B5A789A918E4F33479C7390B
+:10B36000324A1EAD82849D2E5AAFB7E3A97FAFABA0
+:10B370002F6BD0D797925B5260DF7EE9069104383D
+:10B38000D01BFAF6AF7917F6BB8CD4AC8375FB579C
+:10B390006ABC6BA18B0819546F55FDF6F1BC320ADB
+:10B3A000874B6071166D1F7A7922F37F2A66062417
+:10B3B00085BEFF59E3C85BA906A2DF07D6C17EBCE4
+:10B3C0007F3A716F235DE9F75DE137C2ABD9035D69
+:10B3D000F6C3553892B7734A20861ECB14382667B9
+:10B3E000AABE2B105CBAB8C73443FD7BF35332D1ED
+:10B3F000F1D31EDE93278C66FC03FCC009ED92E7B7
+:10B4000087F49FD6A5FF827F6AFFFD68FF79BAFEA9
+:10B41000A7FD53FB1FD805FE79B1FAAFFAEDF32F64
+:10B42000FBA93EA978F1974E42D7C913427D8A9B6A
+:10B43000D2B572DBBD4E8596C705BF13F8F54480C3
+:10B440002F8E45EF87054E1542C5CE41DC0DFE49D6
+:10B45000FB3FF9ECCF301EF1D536D185F1B4EDE6E6
+:10B46000B099CA6175E3F2129283F523AC7EDF19BD
+:10B470001EEA4D7AFEAB78FA9729901F4239458D26
+:10B480002F85D19EADDEFA7911AC4F5ED28E7264FB
+:10B49000FC0EC6BF9888FAAF4C8AEFDA4EE1C4388A
+:10B4A0008157C58BB7F16767782794377C01FA829B
+:10B4B0007A22E8C71BBF2B57EDD4358223F9988D2C
+:10B4C000FE7B0C19037A51C30B09303BB5EE995F33
+:10B4D000E71CA1709DDAFAA6938BC297264F67836B
+:10B4E0008BFE738FDCBDDE6DA5F2166D0F69EB96DA
+:10B4F000DCA4DAD72156568A6127E4F3546E16DDB0
+:10B500007EFAB8F2F9279F7A0CE2997F32BB07D115
+:10B51000FE573CFFDAFBE3697DC54E31B9844DC36C
+:10B52000CEA574D2C74BFFBF3BB7931E15BF794D55
+:10B530009287B1E7F72476D265C5CEFD1219D615EC
+:10B540001F9383FBA5883D067D82478AC05EA87B4A
+:10B55000E6BF2588339ED8C791D4AC18F8DCFC1A16
+:10B56000DA038027A4A74AAF0EFA19DEF752BA8091
+:10B57000DE36D2CBF8DE2255BF40BF906741F9FBE3
+:10B58000853D9007F591D90D78287F619513E6F3F5
+:10B590008550C3F8FCF17B53409F958BFE141796A2
+:10B5A000EC79F9133F42FE5BF6F68F5230BE4494BD
+:10B5B0007413AE45FE7498E7924DB3709E4B8907A5
+:10B5C000F9B0FC71BE3440CB0B0229DE19434EACFE
+:10B5D0002293932FB650E2D2797E01FE24E8EF77D2
+:10B5E000F8C036B4BBEF24A00F7EA4CE855A0C5809
+:10B5F000BF6061F4FAABBA2E10B03EA3F977EB7DD1
+:10B600002D40A793FD9554D877F112C1AFE283FB8B
+:10B6100096F6CBBF3D2595D189C8429EFA1D5DF7B0
+:10B6200027C37378BF4554AC39BAEFC8B7599DE307
+:10B63000AF56C7A770C7C17AFD454A6CFB354FD4DA
+:10B64000F4005DB7A3F82C4ADE99FC6FBD9FC9BB1F
+:10B6500026FF81E9C5D07EFE309323F80ED6430A3B
+:10B66000573815DBF7CFE4503F503F3A969C6F15A3
+:10B670005539D7B71BF985C22F70F1517C03E324EC
+:10B68000221D70DF65E906FA7D941EF5C2B8CEAEC4
+:10B69000FD6A72BC4CF35B45BD3E209B981EE8DE04
+:10B6A000AEF2239E2AC5C0538F81FC5279F5CB2080
+:10B6B000BF6229CCFFCB1DCDEFCFA372FB655093AA
+:10B6C0005BBD5E35CA6DF9AED12496DC7E69779399
+:10B6D00098724B9FC7945B7B04F9F9FFB45ED5F079
+:10B6E000380CF0784D271E353DD91D3E8D7AF290ED
+:10B6F00020235E8D7A92FE1D26795DF951E3438DFC
+:10B70000FF2A9EABBA02F451079F6A7CD8C1A71AE0
+:10B710001F7689EFEAF0686CBF00FB3414AEF9962F
+:10B720008DD38E5257D2D24E70DF267F268FFBAA42
+:10B7300096F384E5811011F3433F30D58C063B75B9
+:10B74000E2DF6F3D7D1785773EF18B2C2FA05E44A5
+:10B75000BBFFD2B7DF4EA0F399A7E2793E45FB5479
+:10B760004A973902178EA370CE15883F3E11E2B773
+:10B770001CF9340A8EF9E5FA3AFC4D4CE9ECA7A71E
+:10B78000F7BFAB9FF27DCBB7295D3F1D44C8BB50CF
+:10B790008A38BC10CD57D381AE147FDE515C600077
+:10B7A000EAA988501AE577BD2032FBF3EDC219A350
+:10B7B000C1BEC99F3D2C9EF1FB60F47BBDAA3E3B00
+:10B7C000EB97E341CF9F0D65A37F7BF6D02247AC7B
+:10B7D000BCD06695CF5E53F75DDAEC5C3D4FF9BFA8
+:10B7E0008DB4A37DE3B75BC9B618FB821B454D5FE3
+:10B7F000AB74A37F3C1D7F8ECA8773E9A7F1B95153
+:10B80000749B39F584E0EC4A07F8FB34CA0FFBA1BE
+:10B81000F805BE06FC365B2345A531E279CFA9F8D1
+:10B820009B78E06BCCCF2D0CE50B80C7423BAF8BF8
+:10B83000833CA9C9EB503214E09A7860F9CF4753A2
+:10B840003EF61EE2DD908FEB0D9D913C31FC6123B5
+:10B850003EA17FB0338F882EC4D77B62E912C0EB44
+:10B860007BB3AC04F635DF95DC55B1E02C33B3F592
+:10B87000662E29BD308AFBBF0FBFF9B31DE1028AD6
+:10B880008FB37696F7DD95FF98DC9F7571815A0E20
+:10B89000F89067F5642E0071B422E2F9F9040EE520
+:10B8A0007D52B4FECA6F9AFE3CE4F55487389789FE
+:10B8B000B6570B1109F8D8DBB45300FBFD269928C5
+:10B8C000188F106A86CD8C8A7B1D1105C457F3DF53
+:10B8D000E6DD0EF83D37D34C002E65E81927D80178
+:10B8E000E74223510EBA9BD71F7C645AA108FD1072
+:10B8F000E40F233F1425DB74F55993493F37A5DB4B
+:10B90000447364953B06FDEA24C667BDD66F96FF77
+:10B91000CFF4DB04AADF185F8BD1FAED2689F17D25
+:10B92000947E4B8DA5DF56D6CAA9C0172BF766A704
+:10B93000025D57BEB1A44F2CFDF6BA8FF9F76FA880
+:10B9400079E66DFDA87E1B1EA5DFFA51FD1623AE1C
+:10B950003B5AEAA57EB3FCCFC8DFEBA0DF62CCB7D1
+:10B9600058C59FA6DF8A43B5A8DF8AFBF1BA7CA938
+:10B9700049524FFAADEC97B3B02EBA6D31F807F0DB
+:10B980000AFAED0D55CFC138A0E7FE5D727D273D67
+:10B9900057D55B3DF73F84674DCFADECCFA13DD38D
+:10B9A000950F999E5B99C5F4DCCABD4CCFAD1CC404
+:10B9B000F49C51BF1574D16FECFBEA21F47BF423A6
+:10B9C000B37E7D1B6D2F9923BA2DF4FD12593B9F39
+:10B9D00051333A5ADFFDBBD48DBE739FC1732E3DE8
+:10B9E000E9BB3F82BE1B847A6C20C891913F6E1CDC
+:10B9F00068D3E5D3BDF7F5B1E75E0479F9038FFEAF
+:10BA0000F70726E627EDFBFAD84890BBF7001EAAF9
+:10BA1000EF9E51F9AFD5E7477D3A792893F7AA7B96
+:10BA200018FEAA1B3936DFD57C408675E06F17D12A
+:10BA30008FBE7D2FF3A3679B5BFAD8C0CFFF5F2239
+:10BA4000CA25FD2B298BE28739172B30EEB92BCE77
+:10BA5000B905FCCC3902B1801DBBE0D08D27C07E7A
+:10BA60005D70713DDABD0BE07922E9C8FB98DBA17E
+:10BA700027F5F6EBBCA69DAF6590AEF91013CD8C03
+:10BA80002E13577181CD595DF323A85D86F92DC61C
+:10BA90003C89DFABF39FCD47105FE48F7CCCF8E5AA
+:10BAA000EF8D787233BC54ADE6F578AAE162E28995
+:10BAB00052BAA42CA5132FB7BF14599701EDCB3957
+:10BAC000F4B78CF3D6F0669CBF8647CDBF59A0BEB5
+:10BAD0003F3F7424669E8886E72EF9221ADE0DF811
+:10BAE000784BD333D7906120971F983C3F1F0D7C34
+:10BAF000F47B8A170AE7AD7307E9CE2BBDA3E26595
+:10BB0000AAE748618A0C782435C067F3CA77BE96E5
+:10BB100042E777B392950B21F5597F933C108F68DC
+:10BB2000B6B6A31ED4F8709499C98559D52BEFF5F4
+:10BB30007515E27AD3C4B950BEC2063DA7E699791D
+:10BB4000EF61F2D7CCFDF7BA8C518867582E489137
+:10BB5000B65E015DE83FA786185DBC4017FACF6965
+:10BB6000A4FD20E0BD3A997387E1FDA69DF7023F51
+:10BB7000BD6EA5CF41CECB39F716860E7B7ACA654E
+:10BB8000F95888C5C718CCC8EB5C3F17C07B895DE6
+:10BB9000ED9389E696F7008E89546E36C3C300FD97
+:10BBA0002F8AFE46FBC5C8073DE50375C7EFB92AD6
+:10BBB0009E5F073AD801DFED12D843DE305B7FB4D9
+:10BBC00076AF201722DE343A34D1F56514A38329E9
+:10BBD000069E6FD6EA2A9EBD214E84EF6FA0FE6FAF
+:10BBE0001207BB7E5F1FD4F8DD2C77C513C415D2B6
+:10BBF000A3F406E8B7E87DCDEAA6B7115F37AEA695
+:10BC0000E699DC155F1A7D400F5E0E6FDDCA4FD3DB
+:10BC100091987961DF557E4699F5F2B3CFDAFEE669
+:10BC20007088ABEDE550AF9050822E7E30D3CCECD7
+:10BC30009666AB07F9BCFD0DD1BD45EEAA7FA6A85F
+:10BC400074017F25FA7CE2649808E84D97957CA6FC
+:10BC5000CD7B00E3B7E8F5E075AB07E9D75DFF33CF
+:10BC6000CCCCFEEDCE1ED3EAD7C37890D728EBC755
+:10BC700033AE475A5CA9A77979D471BFEFBCB471D0
+:10BC8000BEEBBE8497B4603C4EDB9FD8C37B768905
+:10BC9000603F1673BA7D100A39EE6FFE13FABF5972
+:10BCA0001ADD7DFF103F0A533CBFBEE3498C639F02
+:10BCB0007EF6C834909F15AFF0C442E5AF75878318
+:10BCC00084599E8804764245238FFB5D4408E7CD66
+:10BCD00088B233A827C3F0F1A203F55EC52E73A086
+:10BCE000847E5FF1F26739107F6B5DC3F49FFF596B
+:10BCF000951FFD911CC807A810D8FEBC913E8FA8C7
+:10BD0000FC796AB76D0EE86F6E3B3BC75B119C2DEB
+:10BD10009AA3E20CF79B4516E7DE6DC33C6CFF333C
+:10BD20001CE631037CD1E748B5FCD053CF30BD5C75
+:10BD3000D12406E03C70C5F69DAD1017AFF8D08C4D
+:10BD4000F6AB77FB1909ECD3C92F3ECFCE1B37F1E9
+:10BD5000BA78689738E4763E6C86F8596315EA013C
+:10BD60005A3F82F5A01AF7FB8E71B2152FEE7DD9DE
+:10BD70004F51B8E2374F3BF15C70CB3627C623B743
+:10BD80005F7E5FA04BDC3178BF1A779CFA05C1F566
+:10BD90002176DCF1A4CA2721B33EEE48B627613CE8
+:10BDA00092C299571A237ED1C1FFCF5F7802F6CD98
+:10BDB0004EEDFAF20980BBF29B734FFC94E2932A9A
+:10BDC0002017ACDBDE67DFC37D06EDBBF7557DD208
+:10BDD000FACCD3B84FD3FA27B31B7A6BDDFB4526D9
+:10BDE000EC53B4EEFC3A05E2B8ABF74E417F6DF58B
+:10BDF0004B9353490C7F402B817F03BDD82732D210
+:10BE0000ADB9B13913E03C4DE90EEB77473C3958F9
+:10BE1000C5E2F4B21A47DE117B5FAE4BDCB871C6E7
+:10BE2000CDD7C13ADE28BA65D28BF8F1614ACFE1AD
+:10BE3000BDA0E30E759F2038F5B2F1E3D3F00F4AB1
+:10BE4000AF0B667D1CFE42E392FF7C0CDA1A93BABC
+:10BE50008D1F877B813F6DDF6FBF59211690A35DDA
+:10BE6000CF61DC1EE8477D0FD2FAFC854C88BB1CF5
+:10BE700017DBEFC0FCEBBD66CCA3AAD8FB01CA530D
+:10BE8000EB4B6FE3BE1A51F7DF5A49C71FDB27514F
+:10BE90007D3AEF56078B3BAB7480B8B4ECC4E76ACD
+:10BEA000FC99F1B51697EE2E1E3DD63280EDBFAB54
+:10BEB000FB91555BFF2C1143BC9F1B0BF43A72D9CD
+:10BEC0007D540D0F2EC0C398E8FD96D8F1FF8EFD6E
+:10BED0001603DD809E608F75ECA7D07A3F88AB0794
+:10BEE000B80F62EDDFB56E66FB34AD62ECBC456D3C
+:10BEF000FF65A4C5B0EF12E8DDBE4B4FF3F8AE7896
+:10BF0000CA0627B44F577C9DBA145BBFDF6AE1D4E1
+:10BF10007B03BEE7BE7E2567CC1B98057C59D57890
+:10BF200044027B4A5BDFB4F99E52FDE753CFF278BF
+:10BF30004E645DB019F5BB517F5413163734C25BA4
+:10BF40006E617AABBA89AD1FA776390276DACFA9CE
+:10BF500003BB91AFAB771C91FCB4BF83DB7F234560
+:10BF6000A2F2AC60FD0844C17FEA85FD396C7F898F
+:10BF7000F9EBC671EE52C7F186628FE3DD71463789
+:10BF8000CE0A7F5062E77E2E3FDE4941990DFD9D2E
+:10BF90006C1109E4FD9F0CF2C58118E3CFB5885AF6
+:10BFA0003C8BC90F5D47F11CA6839DBBE41325B4F0
+:10BFB000BB573BC67E08E7FD573B2419E21775B512
+:10BFC0002C2FB5EEDFDC6940EFBA845B713FAEDE4B
+:10BFD000805F57B22B1FE21AAEC2D251C0AE46BD2F
+:10BFE00093A09874F0AF7614A7CA14CEB5AA9D4654
+:10BFF00004379E0BE59D45C5301FDE65725963EC25
+:10C000003B88F652E289C28BE8D29FE3249746CA66
+:10C01000D08F967F53696939888D2E05538C85B1F1
+:10C02000ECDDFC992E9C77DB0ED57F5088EC4A61C5
+:10C030007964B08EB4ED8ACF21C3F143A2507EB4AF
+:10C04000A9CFB91DFBF7835E5AEB244A0295338AC8
+:10C050005599CF86F3AC232C5C36F0E999FF7A85AD
+:10C06000F66B0DF1E857B4D9B57C522501E4CC4606
+:10C070001EC4BC4160E56F933AE134E613127825A3
+:10C08000EA3E8D29BC1DFDA1B39B587C802757FF3C
+:10C090007A028BCF9100C0AFAE2F2B5438CF12E273
+:10C0A0000EC3FB3B1C180F58F6C622941FA0433446
+:10C0B000BE928AF5E75E1BACCE1CF067365A55BFC0
+:10C0C000C6AFB4C0399BC56ABF7D4AF5E762A918FF
+:10C0D000FA415E97A8F2FAE5D2A243988FE6598A10
+:10C0E0007A3E758EFEDCAC314F4B20AA9F1C60FE61
+:10C0F0007397BCADA6CD08B7317F6BC5767D5DC3A8
+:10C10000E327A037AF027412FBE5E2803DE237324D
+:10C11000F8D713467D77FC9AD3F4F8B5CA7AFCDADF
+:10C120008618F1A7C7AFC3ADC797E6977687DFF844
+:10C13000B1FA73C8FF2AFC8A56D58E54F14AFF4AD9
+:10C140002D294C6503DCE94218E5C2284719F63071
+:10C1500007FFEE9F1CA8C5AFDC0ED4EF69EA7CB8E0
+:10C16000C5EC3B1BC8110FF0BA518EE02420E879D2
+:10C170001BF9D875CC0AC4FA8C7C7B4DF7F45C357E
+:10C18000FDD5230BE9579B807F87233FB0F3BE8902
+:10C190002450970572EA76C1FA1DF459DC8B45B834
+:10C1A000F785B8170F82FB5E5C583EA4E6ABB40D72
+:10C1B00025786E30183E9F02FAE9A1DCF669A0F7F7
+:10C1C000BC4B4829E8C11FC5B1F3030FA865BF38B0
+:10C1D00049D5AB856F4C82EF43A20CE7D5DB42DB40
+:10C1E0002C83A0DEC4E33D2ADE84FAAB60FCD6904B
+:10C1F000C8E05A6C090C8238C85E11C76D5D3C01FD
+:10C20000CF6576D86F21962FD216FACCB9284A9FDF
+:10C21000B7363D7A15C4B9369A62E7A94CB19A7E11
+:10C22000D8FA1BEC92B737C5CAF2EA1E1A40E7519A
+:10C230003DFDACBA0E3379B856A5F3AB4B6FC4F9DC
+:10C24000BF14E26458478AF8DB6E1A46E739EE3DC0
+:10C25000418DCFB078E528F5FD3AD02FA85FEBDF10
+:10C26000E5E9C3DD470502E7F446D52C457FEB152C
+:10C2700027E573CA17794A7024F06D612801EFCD64
+:10C28000F17E4CD0AE1FDD22E8F8334F5D57F3222C
+:10C29000545EC044F950DF3E2E2218ECA0000FFC83
+:10C2A00075ED71FDF38556D5EE729214E0F30D979E
+:10C2B000780EF25EDBDA897B0D85BB6D715F84A33E
+:10C2C000ED3C9CFAA5E525BE38D67ABFCACAF8620D
+:10C2D000A344709DD9B8D48EF1C5034B2BAE80F525
+:10C2E000FDAB1F7BAE88758E3C4A3FC5B37C2C25C9
+:10C2F0009E8C05FE5ECB31BCD7A797C6C8F7D7F892
+:10C3000059E36F8DAFD397C67962E5357E63657665
+:10C310005AC1D2219C04FEDA3E0E8FE3B6AEF15C28
+:10C32000F6DC8D9FACC90078BC4DE7D0EEB6843802
+:10C330002596BDB1C1EAC4FE5BD7F86B218FEF2E05
+:10C340002A9CA027BBEF7703FA5B3F81A02C7C6778
+:10C35000A92FC373BC4B2C640BC4BB85FAF45B1CC4
+:10C36000C0FF936F5847E17DACD484EBEB46D18D91
+:10C37000F0FBAB08C1F8831ACFED378D6C8E3ECF42
+:10C38000FC8435FF592BA5C7B35617D225C9E3E660
+:10C39000007EF73FFEDB09F2DD76D18C74ECABFA60
+:10C3A00043DA77AF5999DD36334ED90ADF93F26419
+:10C3B0009413B7C7E95E3C12EE4DA0788F92A34E5E
+:10C3C000FAF9F1BB440FD571149E44BB09F99228C8
+:10C3D0008AECD2C529FD28479A5C903047208F4DC2
+:10C3E000D3AB5C880B3BA81C8CB2D8C3E0772496F7
+:10C3F000D3795310ACC4C2FA6B114E759CCBC63CBA
+:10C4000079CA977970388A6048141271A17F4DDF1C
+:10C410006A7A7A6D02417959FBB010A8A3FD6C12BB
+:10C42000225688AF64297201A41A250A329E17EF9A
+:10C430005F4E30FFD296FD784287DD42857EC4375D
+:10C44000FC8258FB797C9C862FCF1F406FE41C6ACE
+:10C450003F00E68DDBCAC673BF66413BBD437FA884
+:10C46000F65891BAFE8EFBDCC4F209C29348F43E42
+:10C470009B517F68F6C9B8EB226B60BF68DC9F18E0
+:10C480009CB45B05BE1BADCEB7439FA8EBE69810EE
+:10C49000D527F4FBDCD0C866B8072BF76326C75D49
+:10C4A000F4C9213F0FF8FBBE7AC4C81723C2542E2B
+:10C4B000D5F6A132DCA7E1EAA843FB1983DE499E49
+:10C4C0003E2A15ED5C95DF8C78D6E4DB28F7B9774A
+:10C4D000BB9BCD0C2EE6471AC6215C271C7236E8A2
+:10C4E000A5B778B0F7DBF2291E285CBF02F9A3F4E8
+:10C4F0004B381FB801E6BF2174BD15E4E47BAF27BC
+:10C5000021FA75549EF6D3BC273EAE0FAE274EC01F
+:10C5100043F5FEF3EA7A12467A77C8019593E878F4
+:10C5200089C6FF467ED7E4A30E2EDEC8C673760406
+:10C53000D6599E0BE2653066B2C90578D5ECED3A66
+:10C54000D5BE25FE74B4FF56BB88BA1E6506804F63
+:10C55000EA44CD5E775BA2E353AB1D05A997DB4FA1
+:10C56000F55EA4FE59D4391BAFD08EFE9BF7A28492
+:10C57000CFBF37FE9A2814793AFC8D891BDD157FD1
+:10C58000F17184B0FBC2FE9F9FDF0C237FDC277715
+:10C59000CEEF5AE2792542F547DEAAF57536193F06
+:10C5A000399C96D7552F68FB9FDDE901A3BC8FA965
+:10C5B000AC6FC6704B0FF2EEB5A9F8256406E8B370
+:10C5C000F1616AB7647595FFF3EAFCBC3686F7B68D
+:10C5D0005BDB07833CADE73D3571682F464C26B0E9
+:10C5E0002B7613B47BDCFB8F3A51DE5B9274EB4FFE
+:10C5F00057BBC08FF2A9D9A79A5D6A7CAFC32E55ED
+:10C60000D71B2D3ECA355179A1F03C19E7F1031C27
+:10C61000752EE6BFC20157D0634F583D75C05F36D7
+:10C620003A9738D82F1912CE62F196B04E3EBB938E
+:10C63000479B41DE82143FB0FEF9E9FA3788EB1ED2
+:10C640009EB171090C5EAA85C0BEE99747D860D536
+:10C6500004F3C7FBE5B0FB6BFAE5B2FB3237C73139
+:10C66000FB658BA17CC25AFA18CC4B1488DF9CFB6B
+:10C67000FDE10650210EF9649CD200F8B0142B386D
+:10C680008F0C17717394DE19429083BC89C44A9948
+:10C6900063F147D2B9FF48FBCB2891F3813F3206C3
+:10C6A000123C379A118A7D9EE89538F187D9EB8D37
+:10C6B0005DCEC1BCA2CACF4189CE37A9849D83E992
+:10C6C00088FB50F001BFAD8E5B71B2AD17D83EABA9
+:10C6D0003F81E1D9E8BF01C1605E825ABF57228223
+:10C6E0003511FD2B3FF0AFDF6441FFCA46DC41D07E
+:10C6F000B71FC4B1F8EC3ACEBD1EEABF10DA2D70F8
+:10C70000CF8F26379A3C3C34E116B7405F755E7791
+:10C7100036077C5F2A17EF009E5B279C1DBC1667BF
+:10C72000D29EC9F84EE175F9F61AFD9A441DFDAC8A
+:10C73000105789D6F30E6908D8EDAD5C9C1BFCAA96
+:10C74000D6E51C8397B3A8E71104DD3CD36CCC1F5E
+:10C750006953F5E7DFE3B2901FB5F584CE6F3DC6B0
+:10C760007F0DF3E838876A38776A3C979A96DD112F
+:10C77000074AC77CDC5209EE3223674336B4E3BC78
+:10C78000CEF64C12E3BC646AC41AF35CB05652BCD9
+:10C790007D0D784B156B12401FA7DECEF488111F5C
+:10C7A0006D9C7FC441D847FB8318331F452BD3D2E0
+:10C7B0006E4A584CDF4F4BBF014BED79835D8819B2
+:10C7C000574CB2713FECDC6403B118FCCD241BED77
+:10C7D000EFB4E79DF71514FF768CBB37C431BC3737
+:10C7E000C431BC37481A3EE57890BFCEBA5B97F7A4
+:10C7F000B4C1674910200FD19F8EF2B9C4C5E8DDDE
+:10C80000F9BE82F64D1FA2DC301794C406916C432A
+:10C81000BE67F121ED7CC8AF7CCF2440BE94DB968F
+:10C82000A5FAFB1646DF0406F7F90D5370DC14B2C7
+:10C83000C63A98E27969A9C90D71A3D30B3F72C2B8
+:10C8400091E985192D79200FA7798F1BE6974A98D2
+:10C850005FB86C8E1408D32E931BA8C26274BA0101
+:10C86000F73BCB4C31F3AEC7D8D8FEE9D138179699
+:10C870006969D3904E9DF59204F04B8C7C4AE53566
+:10C880007DF1A8CE73CC946F145B0C796B134913B4
+:10C8900087EB5B18F195ACB1B3AAB7357949063986
+:10C8A000847DAB52AA47353A0F505F4DC1B828FE80
+:10C8B00071A1D7BF067FC3795D01EA454D8EC810CF
+:10C8C000A6E7ADA077A3E2A16D7B3FE80FFB8E9FAB
+:10C8D000FCDB3907EC3BFD556877809E3D7ECFBB86
+:10C8E0000E38C7F4C93D2C2E7287C14F5B6463FAC2
+:10C8F0007F8FAD741EE07781EF1F799E287E2577AC
+:10C90000B3FD93E501DE70DE5D7F6F505530C97079
+:10C910008F901FF15AA5DE1F66A4C7461B8BB72C4C
+:10C92000DFB159CA90617C4F258C7F5CF5438F370E
+:10C930003AD0DFD1E059B8638404BED95F4366754D
+:10C94000FFBD4564EB875202FB671E156F46380F2B
+:10C95000AAF76A2FF925CB8F29A363DD4DF5B02700
+:10C96000C4CE7B18E7B1E413B92895126FC9FD1C3A
+:10C97000FADDF0FE3D743DF3DC7D1FEEB319E7D91F
+:10C98000F55E1F05FDB3652ABD8DE76D9785D83E21
+:10C99000F862E241F9EC72FE36C4CEC518E38D6749
+:10C9A0000F65DB000FBFB0A9F1C43C3206CE6DEFBE
+:10C9B0003A3420FE72F7569F52EF8B827BBBA13C2C
+:10C9C000EE2358CE032390E2BF32F4F65DC05FD56C
+:10C9D0004D3BF13EB4EFAA8FAA42279C904BADE9A4
+:10C9E000256A876E03F9208B399D7D5ABDF99CC459
+:10C9F000FC6A869FDBD4E7B7013E7220DF5BFED97D
+:10CA0000044AEFDB2AC5F3D1F7A53D6FD3EFC3F797
+:10CA100076BEDA3CB5796BED556A5E9CF13B4D0E06
+:10CA2000E6A97CB978EBF4757D298AEAF67E91A9AE
+:10CA30009E93C3F3421A9F2D23A545E931F849A3DC
+:10CA40006F07DF847E8EF3D3E8BAB8BE4CC5833F50
+:10CA50004DDD4F4C837895918F7A3AA7DD2A463287
+:10CA600041BE8D7CD2DACD7D28211BB32F16CB4A57
+:10CA700011C4CFA8F9BBCE1565DF1C17EA0FFE1451
+:10CA8000E46E2BE3FB0E3D084E31E8F737455CFFC3
+:10CA9000573AE454B8FF0FE9370EF213CC7E784FC3
+:10CAA0001BE7984F51068A80FF622C4FFA4A958106
+:10CAB000833ADB976E3CE704FBBB6D08C1B851AB12
+:10CAC000430FEF691B8F7AE3B44A8F4AA1E59B3F7E
+:10CAD00083CEDADA827917C72EA971A74BE6E2581E
+:10CAE000F3B4D839DDBD7877A872A8F9350B54FABC
+:10CAF000DD1162FBE90B374D477A74C9BF54FDA1C4
+:10CB0000B2460EF58E913E4BDCD7633EDAA2403E34
+:10CB10007EDF855EE441A4BB916E77DA5DEC1E3763
+:10CB2000A146827BED8E6DE270FF7185107BFF73F5
+:10CB3000B6DDF49DE6639C4777F02FDB5ABBAE2F42
+:10CB400081F98F9080CF8DF06BF35F4214A6A7D44C
+:10CB5000F976372F1299C4F234D4757F399C5B81F2
+:10CB6000FD93077996CFADC6A134F835788DF328BB
+:10CB7000E22BF17C415B038F79D977F8D97D067779
+:10CB8000ACE570FDED8E4E9A5ED1F67BAA9BCA3065
+:10CB90006FCB43FB013BB6ED63C2F629D67378CF6A
+:10CBA0005BB7F40CB17CA5EEE84908A3DB624A3719
+:10CBB000F03FBBDE9F90AF0C8CDE270ADCA00C8C14
+:10CBC000DEB72241CC5759B17DBAEEF98D76358E5C
+:10CBD000A5EAF59EE48FD424C48C6F69F2A6C99FA0
+:10CBE000268F77DA65666F0A81831959809F87D10E
+:10CBF000BFA1FA7A9E9DF93D0FCDA5AF546F3CA71A
+:10CC0000DBA7583296D16B095F82CFBBD3BB140F21
+:10CC10003ABDBDD8AECFC3F8A1F3D1E6A1C98936DC
+:10CC20003FA39C18BF37D2438BEF19E962A407C01A
+:10CC3000097EC65B7B6D813514CEB73806B77FAFF2
+:10CC400015E16E4D9BACC0B9CDEAF4F958FE013E3A
+:10CC50004C07FBB0B4CE8E76AEEA878DEA5D5C22DF
+:10CC600057B5CB5EB22A23D9B9A7D224E09389B5B0
+:10CC700091191617218F3E585C04F7A44E7C383268
+:10CC80000342F1BF7EF04656DF1679D7E286FBFC01
+:10CC90004B8A0A69FD71D02FA02FFA95DBE0FB6E5D
+:10CCA000EBC473F9BACCDE1F652E9DCFEEB166EDF5
+:10CCB00095D43EB3D0F5AEF2F0E057417E2B5B4AFF
+:10CCC0008A212E54091178BADE5529CEB02D87ADB0
+:10CCD000FBE3E97B1FD93C4FD921EE76712DAE8B5A
+:10CCE000958705942F7288C567053A572BFD6E6DA1
+:10CCF0001CB593297ED7265ADCE017D3E77EF09740
+:10CD0000D7262AB21CF55CA31F7C0770AC35B17C1A
+:10CD100082FD6F0C8E8F5CC62ED8EF2325E0CF34BA
+:10CD2000FB2C581ADBF325179EE7C837B17889B179
+:10CD3000FD6DBB76AE49CE00BEA83E24A1FCC31F4C
+:10CD4000D89F5584C9493561E7D0AA0E133C775363
+:10CD50007DA808CFDDC0B9844F757AE05F73EEA679
+:10CD600093AF189E0A04AE44881AB7D06ED5D5F991
+:10CD700054D310980FE1E3DC706E84CF30D5ECA271
+:10CD8000F3E7AFA025C587E072F370FF4CFDE4899F
+:10CD90003CDC9F5527AA792D26763EBE63DD57E5FC
+:10CDA0004F2BFB394A8F02DD4FFFB125CFC6F6531B
+:10CDB000D0AFD6E65BC72984037FED3582E71972D1
+:10CDC000934933E0CF4694B1C06F1647A2CA976C1F
+:10CDD0003F9BFE6540E9369B7E23537EFFFAC19F51
+:10CDE00022FFBBE34DABB2689D73F8593DC3742E6F
+:10CDF0008BB230EFA865F56B4CE706D0BAE858C3A4
+:10CE0000EAB0F14A173EB3A3AEC83F14C67131BAB7
+:10CE1000EE50AE01FE164C2CAE231C90707F47CB1B
+:10CE200057594B7906F8D1E2607A745D6DC173365B
+:10CE3000889B172832E44FEC51EF41FABEA5865784
+:10CE4000DE66427F094AC07FBC83E153A30B69546D
+:10CE5000AE813C5E1254AE817DBD7E0E4FA2837EBC
+:10CE60003FF2AD9689A0CF1BDFF9280FEF73BF8289
+:10CE7000F533F22DEA43D2F99CFE6DFFCDD1FBE4F0
+:10CE8000FD1CF9A9F01D2503DAAF9CEC22B751393E
+:10CE9000AC53882C65839FADF72F1B09D34F1FD947
+:10CEA0004AAF70A03E09E33AF613BB6700D48D7E0B
+:10CEB000336949EC55DE9D947337EE172566347D52
+:10CEC000B810D685DFB17B4A3845C1FCD3173BEE9D
+:10CED0006B231897B2913837C48D899BA4F953D42A
+:10CEE000F89A89F155725E94FFACCE877E5F08791F
+:10CEF000F2636C2CBF81CE8F07FD3A82C8588E84B6
+:10CF0000385936A0D883F53D24F8E14F69FF8F5892
+:10CF1000597CCAB29DE8E28F650E16B779C0C9E2A6
+:10CF20008F7162F016B02BE2CE1017D8156D8F4BB3
+:10CF300002EECF0BAE9B70DFEEA009E3DC4F8B015E
+:10CF400017EC17B55F25C85B48677F6D2ADDB57E96
+:10CF50001F91E4AB20EEF70B27AB3F9D4F308FBB0B
+:10CF6000FD841480FDDCC40C4B4D743C699E83D958
+:10CF7000BBBF7315CC043A04F7C611187FCCBE387A
+:10CF800013D0E3B91DB956E08B170147140F89661A
+:10CF9000D79DD05FE2390A6F163E67F9FD823C22C9
+:10CFA0009EE277FC8D7619EED17ADA1ABC11F3562F
+:10CFB0009F37E1BDC12F4AEEE9507FF1ACEC023D55
+:10CFC000FC7456300EE7F3BC09E7F3625CFBD52B2B
+:10CFD00029DC0F0C61F12EC14604D0CF82A940BEDE
+:10CFE000933E5FAEF2B1A6AF37811CD1FA231CC1CC
+:10CFF000730C82291FE548CB276A6B27984FD467AB
+:10D00000660B0FFC1C375D8B3B857988174D2825F7
+:10D0100068CF4DB08B78CE05F299E1BCDB44550F5B
+:10D020004FFCB8B284E507BB0FC3BD9ECD76F57E3D
+:10D0300030759F7392CA27D791086FA1EDD75D24F1
+:10D040006E88274DBAA8DF8F78CA605F4E51FB57B4
+:10D05000DA5D85F0389FE8EDBF290D4527603D2C4E
+:10D06000208A00FC34D96268073BD209F7F0EB9FB5
+:10D070003FE050FDDC4C92199DC7A6ED434DE18782
+:10D080006E44FBB55872035E76DA950F203FC0DF21
+:10D090002292CBC5259FF2B17CC321176D04AE2C23
+:10D0A000A4FC6987F95CDD50EFB7D2795F3D90F55C
+:10D0B0000F7C08FAE5CAC7939340DF8F57E9A5951F
+:10D0C0001ADF017FB9E2197FB98677CAE7D38E2CC0
+:10D0D0007C4F9337E03BE8678F18981F6BBF9BF23C
+:10D0E000EBD3C0AF3BED04FDB89FA55BE6809C6928
+:10D0F000E3B4AA7C6D2CD7D5AEDC0FBFFBE4BFC078
+:10D10000D68DC2BE17A5E875BF4F0283D72BD7CFE8
+:10D11000980679687611F3CC52D47351D1FC921EE3
+:10D12000C52F1ADFB5DA599C48E39FC9BBDFE5E19B
+:10D13000F9E40B84B8B24887BFA2F1CF447F18F757
+:10D14000812712E69F18F9675737FC937F5E1640D8
+:10D150006F75E19F438C7FBAE31BDA0FDE6B61E4EE
+:10D160009F771CAABDDD2DFF5CC2F3FCABF74EBE62
+:10D17000EC7E65934F9F9F6A2CC7D962E72FBB5403
+:10D18000BCEF96EA6FCA01BD31D5C4CEEF0924E3E6
+:10D19000160AEFEE38EDDEFC9A6CA8EF14981EDA52
+:10D1A0001932A31EDA69F778307E9B6661E757056E
+:10D1B0004F04CE23B8FB5AE4E8DF21D9EE6076585D
+:10D1C000500C8FFB02ECF137181F8C9D9ACB432A31
+:10D1D0005AFA62A617461D9736C3EFCF3DEACCBF79
+:10D1E000007C9606B8A3DF798F4A78CF52F55109B3
+:10D1F000F5E36FF7BD5D04F1512DCF79CC9EB78B70
+:10D200000A86C2FB8CDFFEA1EA65AD8E4740405F17
+:10D210001AEEDD1FD7711E4B7F6F7E29F0514E67CE
+:10D22000BBF13EF9601CDB3F994D6411869871B4E7
+:10D23000F45EB8DECC78AFFCEC303BFF36F3B027C1
+:10D24000F6BDF22A7F18EF37A7F6778A13ECEFE7DF
+:10D250005AF6416884C86CDD0E4A35D7303FA326A4
+:10D260001BF8499343FCA3F80B7E3244F7BB06B787
+:10D27000A9F37FD02DB0FBA92212EE4BFE9CB0EF9C
+:10D2800082EA3A36CAC9F440EEEA17E6039C23CB99
+:10D290009566A0CBB32E16D7F905095BB2816E6EE9
+:10D2A00001F75382A23CF90BAEF33D22940EB1D3A9
+:10D2B000F63D7DE246C2F88F3A3D639C609F09EDE2
+:10D2C00087E0BB31E37347821EB78F589B04EB9A0C
+:10D2D000063785AB789BBD130E0DAE814EC6978F7A
+:10D2E0003ACBC6001EE03BD04B4D478E59E07B8DBC
+:10D2F0001F827BCF303E88E20BE0834EBEE01640BB
+:10D300005DC383A2AECFB7FD8BF8428B6BF4C81719
+:10D3100010B7707E2FBE980B7835F205B5E73CCE7E
+:10D3200018F65C50627993C6E73FB1E7E3FB6E897C
+:10D3300060DE13D96765BF6BE849C07D90DFB8D860
+:10D34000986D9F1CCBA4A62859E56476BDF63B2AB0
+:10D3500023C21CDA9F23A8A2B80DEDBC7EA827DD4E
+:10D360002AFEC8318E83FB4631373E03ECD0701263
+:10D37000D86B23CC256190875DB68919603FE6DACA
+:10D380002664C3FC5F1EB2FA4D58D25EEE5BFE9B74
+:10D39000AD72A77DA5E9C366B55B6DFC352A7F4CF0
+:10D3A00052D87927D0EBD17068EB039009E0E0C246
+:10D3B000B34DDFDA508F8722146F93000E8A87FDFA
+:10D3C0001C6904FB21DFA4244F063BB04F580038F2
+:10D3D000DBF67E9D09F1CE92D0EB1F02BC25DA3E32
+:10D3E000AC5BBF0F6BB4B7357B48F33F347B49F37D
+:10D3F0007BC1AE82F632D51F7199D9BED884B005F3
+:10D40000EF5378E4AC7C95A2CAB340E751A2CEE3D7
+:10D4100066D2827069F7A94C53F1517288FAAB3920
+:10D42000D04EC8548A87A9EA7D2A53DDFAFB226EC2
+:10D430001E1BFB3E15AD9F9EDE37AE1BD71AF6A313
+:10D440007E6879C8C7EE4FF9BD8FF9C3E307F07E58
+:10D4500001D6DFB159ECFE0917C3C32129F63A768C
+:10D460005195EBF1A6480E9CC7DEBFE7EFB86E1EE4
+:10D47000D8F3F7F7C18E1C77422090973BFEC4A8E3
+:10D4800078CC0F182B235F69FD7A3F6FB411F69C9F
+:10D4900044FFDECC410A8F7225C067C1F295538FDD
+:10D4A0003C0AFD9D3F2A90E8731F45926720C4E522
+:10D4B0008BD4DF1D3AC8317B4A6B3FA8FEDEC71113
+:10D4C000956F212143BB67C51C45E7A9EAFD1F1ADB
+:10D4D0005DA71E2F3E21E474A50FFCFD33E2105A18
+:10D4E000FCE19CAA0F49F39FF07CCEF58D770A6092
+:10D4F000BF5F9FC613256ADC1B64EAE947C5214E5E
+:10D500003A0DF66FF3338F4E83BCE5B7784C81F458
+:10D510008676BE9903F5163EE6BD2A46FC5E1FBA26
+:10D5200013EF55991BCFE4A3A7F1C75F4DF96438FA
+:10D53000D09D303B308FDD4B62A4EF813DFF9114D5
+:10D5400019DA3DBEBBA3BF910EAF9C2AC07DAC9E35
+:10D55000E861E4DB7D749EFE2BE177532DC48FBF21
+:10D560009BEAC2FAABBE34AC6BFCEADDFB6412D8BA
+:10D57000791A9F4E49627C336EF7A349C4DE492F66
+:10D5800023DE86C533FE7FC9AAD925EE59D3E8A389
+:10D5900077E93A848CEA272D903756AAC23AFB7075
+:10D5A00011DA25443DCF625CDF66F3B74D0175DAD1
+:10D5B000D3EFFECC94CB7AF57B39C56FD50BB00E8B
+:10D5C0001609AB991E53ED780D1E239DDF23A50888
+:10D5D0007F77F019F9C008E74B1DF9F60AAE07DAB4
+:10D5E000EFE0CC18982526C69887868F9984AEC719
+:10D5F000D9BD5F8F6F8CD7DBEFE78E17FE11D0DAC6
+:10D600009DBC19E9666CD7F447110C908BA51FECF3
+:10D6100093B9F12948DFA28B1251E83A43FAE9CFD6
+:10D62000F593922B91DF56B9D8B3EEF8ADFA224FAD
+:10D630003C233BF94E6C7AD8067CB75BA8B7411CFB
+:10D64000F53AFBF43A10BDC2CF0B66E2FD1511139B
+:10D6500081D0DA94D099668833783F2478BEA120AF
+:10D66000B47F32F0E9AB420BFA596DE7097938CA59
+:10D67000EE6C0AD5D9C02E6B4A66E7F30E26105D14
+:10D68000FEF4C578A66F9A8E9E9DA6C4681FEE62B2
+:10D69000FC3C8328C939F49F45EB297F801FDCC7F8
+:10D6A00081719242CEFD5A32D82D7339F423DAF6C5
+:10D6B0008E792D99C2DB7A7B02EA99294DF7DDE953
+:10D6C000A28408FE63243E6F2FE3F0FE8422D98DEE
+:10D6D000F5A2C559E8F78DF926694609B4DF20A2FD
+:10D6E000DF3385AF14205E753A8DC3AB3CF6709185
+:10D6F0005AF83D62FF74360E71F993C03F7DA7243E
+:10D700006904FE669EACD507E1EF2E1283FFB6FAE0
+:10D71000A573FBCDB47DF52C0EF38DA7B832883FF1
+:10D720008A7F8AD64B38AF5B42A905C0D7338AF5CA
+:10D73000E71EC3AA3D39ABD44602D1FBF99C0BE5E9
+:10D74000FAA0B5FD56FC1DF1BD2281F969727EA3D8
+:10D75000CAEFB3E724E9BE9B4E98DDA9C9D54DAA0F
+:10D76000FCDDA8FACD733D19BAF14B09B387FE4031
+:10D77000DA0B8164F7B8D87EF4B4F696C3F3E125EA
+:10D78000BEDF68D087370D31F8BD7CE55AE48B34B5
+:10D79000CE8DF7C8B8F5ED378FD5D78DF26BD40F96
+:10D7A000B3208B8FEFAA27347D306B2F2F423C683C
+:10D7B000563EC533DAC57ABBBD277D3126AE1B7D0B
+:10D7C0007149BE17CC902EFAE2E3E2EFA52F7E4B13
+:10D7D000DD96B154AEDF8E57D7CDFEA43FE88D293C
+:10D7E000FC8E47818FDAE8BA698EC147DABAA3C5E1
+:10D7F000018AA81CA31E38C5F663A65C4C27FE91BF
+:10D800009D71800E3D42ED12770C7BA9353E1BE5E4
+:10D81000AB43EF687A25CA2E11F37EB85D3285DA04
+:10D82000A3522EC0D70FE12B52EF252982842B88DB
+:10D830001FA69DC1389057A0FE2CAECF4F227F81EE
+:10D84000FEE3123BE5C368AF6871E80A97664FE9EB
+:10D85000F9A5231E3993DDC3AAF14911E013E47F32
+:10D86000268FFB04FF1BD47F03B300800000000061
+:10D870001F8B08000000000000FFC57C097854558C
+:10D8800096F079F55E2D495592AA6C148BF012B67C
+:10D890008424588480EC165958A314A080CB688146
+:10D8A0000B6B129A719CEE69FFA642024343B78349
+:10D8B000D2DACEE8F457D83A831AB40801039DD0DF
+:10D8C00015504C5834082EF8D91A6D1AD10E4984C7
+:10D8D000D646BBBFCFFF9C73EF4BAA2A854DFFFFF7
+:10D8E0003FDF9FB47DB9EFDE77EFB9673FE79E97E3
+:10D8F000DB9B55B3AD08E0F6998A071400D0F177A9
+:10D9000022C042E07FC3ACAD16F08EC7BED7FC6923
+:10D91000870DF8E73BFC2F9C90FC2CA450CF0B907C
+:10D9200009B054CE5FFC577D333D5E3C277AFE52F2
+:10D9300098FDB9920C701BF8CD301CF7F3C58EFF23
+:10D94000EC4B15C7972E8B7E9EE94C4ABF9087FF04
+:10D95000180123BE5301CAD4BA9DB722BCDD275596
+:10D960008F554C33D1FE0F39C5FE0F35970C807C97
+:10D9700080DF7416A7F8B13DB611211C0DD0BAD1C5
+:10D98000C6ED71EC07F1C5EFE8E7663C9F05FC21A9
+:10D9900007B6B45221B701480518EDC4452760FF0A
+:10D9A0002A9E3F0DC78624C0EF73245CD900AFE7E1
+:10D9B00098E704F1BDC3B85E00D70DE3FA015CF748
+:10D9C000C84627F75FDBE8E6FE0D2E446A06C0FA7C
+:10D9D0001427AF372FF776871FDF5BE3CCE6E750DE
+:10D9E0003EDA44F836E02F7B6A080410DFAF77ACEC
+:10D9F000D09474802AB7E2B166F5D1014FE3588E16
+:10DA0000F3CB25BE2BB72A10C4E7E51FAE2B07C406
+:10DA10005F5733EE87F8A92A558336FC6749D363ED
+:10DA20003B45DF0CD608FADE228E0233B516CD86D2
+:10DA3000FB2CF0281E15F7F13689F76FF52A411DEA
+:10DA4000FF798B279A1E8763E8BE58AEB380FE0F1E
+:10DA5000DF5B30470986719D0593A2DF5B7C75D63D
+:10DA6000E7CAD8FE7CB498E83EB63FBFDC4E74B738
+:10DA7000E33F86C130A2FB958BA56F8D853EBAC56D
+:10DA8000B6B1748E1DBF169DEF273A675C9BCEC65C
+:10DA9000FB7F8BCE0F114E90BE70F41B8B9E04301B
+:10DAA000BBE9071AD179F6558DD7AD32CE3314863E
+:10DAB000D279FED459F86FB742DFFCAAA62F2DFE0B
+:10DAC000826B9FE76FEDBF2245E7FD695F6F7EDFE9
+:10DAD000BEF33480C178CEF939D1F88DA56B2CBD59
+:10DAE00016CAF762E9B535E61C065DA013996860B1
+:10DAF0001CBC5F55198E6BD1AD972E16FF084F7E5B
+:10DB0000FF71805FF3B9FAD693748276CD5720E027
+:10DB10003247C803F2752005E95BDE0AE14404ECF4
+:10DB2000968B733ED7A8F528F069C439E8E753838C
+:10DB3000CE6ADFFA655707B2FC19FB966910B0147C
+:10DB4000D2732197B1F055D23A23697E80F968CB20
+:10DB50002ED3B2109E63BA05EEF5519B28DA034E20
+:10DB6000A1071A9D265EB7FB2B9B096E0478E5F092
+:10DB7000806240F83C56E709D28B2133F0FB45C95F
+:10DB80003ACFDF9C048104DC1FB4769B0FF9442B51
+:10DB900006C84139D306598235B8649D16F691DC22
+:10DBA000757B34A846B9BBD178EF48E02E40926C23
+:10DBB000FE7494A9268BDE0FB74FC57937156AFA24
+:10DBC000369CE2B2EA3FA0F1AE66AB93DEEB3EF8E4
+:10DBD000CF2D665AE72BF02084F05A3332158E4F42
+:10DBE000739883A437CAD493AA09FBDD3D00A48FA0
+:10DBF000A62D0B9700D26D3AB4D738B19D42748CE4
+:10DC000043BFBFD0793384DE1A88749A21E9344344
+:10DC1000EAAB926695F54649921A84AC3EFD74B320
+:10DC2000A4D18C407B490AEE3B43533C35D8BFF925
+:10DC3000AA16C58F2F933EBAB14F1F95C9F5BD3DAA
+:10DC4000BA869601664234FF96350A3D54628B7956
+:10DC50002EED0FBEC97C55E68C1E9F42BA13F9FB10
+:10DC6000628C5E8218FB53A6FE35B903F1F08AC5BB
+:10DC7000FBDE5484BBE7B4199EC5E770113B93FBF0
+:10DC8000E3A731C61EC5B6070F277A7584EB15E2E8
+:10DC90002307F50779F5B1D79E3FB6A3A7988EF174
+:10DCA0004ADD220DB2992DCFBA33FBF0DE0FBF92C1
+:10DCB0000EB178AD977ADEDBE87C8D8EDB0F8FAD11
+:10DCC000B3D89E97FC49D748F5FDBDF834E4E595F7
+:10DCD0000B895EE2FF572E0CF2B2FD4AD2593E0C80
+:10DCE000793878FE7222E951C4A7AE219FF4B86C4E
+:10DCF0009E67999F851C84068E0A6EC3FE8524C18B
+:10DD0000F7AF24F61CCF23BCDF62F23C4BDB68EBA1
+:10DD1000872F2A20FDB975D1793380E205E5872860
+:10DD20004F8AEE84BBB10DA03C11FF055221487211
+:10DD3000628610D0BE355E789ADA19D3F414C2FB2D
+:10DD4000655CB3DD41EBE929C4F7F0D72B137D0502
+:10DD5000FDF15FBF117C1AEED3B0D1E6D3502F1C7A
+:10DD6000D8E8E47EE34637B78736EADC6E3A91FCC2
+:10DD700043F21FAABC169F16A157E6A50AFD300361
+:10DD8000F50EC13503946000796FC623C0F2887226
+:10DD900010DCA410BDF03C397DF844FA5CEE88E854
+:10DDA00043AD563B2193A582E95E9867E2F7D1091E
+:10DDB000083E9FD57F3ED23FAABF8CFC1684C3EF9E
+:10DDC000F296B9B00D397CB35D88DF7A65E9D14B45
+:10DDD000C0FDB9F4BC5EB943BD84EB8F0FCF841F87
+:10DDE000A2BD188F8421BCE2CF5D04FF84160B1006
+:10DDF0007DD0B0B27C161AF2F9B5A25CC0FD4884A1
+:10DE0000BE1B8CEF59CBC3C44F07A0238DF05E64BB
+:10DE1000F3D9497E97B9043F7895DBDD0AAE3739EF
+:10DE2000C3E25109B4E1BEF1EB117F2D19B821CE47
+:10DE30006F69C91CA2E713B7BDF13EC9B7D7E608A1
+:10DE4000AB6C98CC9D1D11F67C003CE3247F927452
+:10DE5000DC7768475A3F4E0EB09EBB6A09925E6BF4
+:10DE60003D93EC09E33ED3AFDAD8BFACA717516EB0
+:10DE70000F27268F653D13420D43F26313E7986D1C
+:10DE8000F6AF233CA0653E7A0ADFFBED6500D2AF1A
+:10DE9000D3DB3F54C90F2D31E50EE840388F2AA35C
+:10DEA00053A87DF2E3E47C6ECF2477127E0E9BECC8
+:10DEB0003AEDFBCE46BD7404F2CBA98D503A02F97F
+:10DEC000E3AD8D366E4F6F74727B66A39BDBA33818
+:10DED0004EFCF33A8E137FBD81E3D46FC3716A4F5A
+:10DEE000E03AD47ADF7298487E67BCE5D0A82DBCB2
+:10DEF0002B89DBFA3B932C748EC3C95067EC4FFC23
+:10DF0000144E0C378007E52ED5FD53DB0D683FAD71
+:10DF1000FE02651CC0D454F75C6D3AAE3B7BE88FC3
+:10DF2000BEC2F119A9C37E6A43786F3BE3683889A2
+:10DF3000FDD2C7F59F3A883F4F24A292243C64B794
+:10DF4000795136C793D218C468F7C224ECA719FDDB
+:10DF5000ECB9A5C80A4B4A3AF2C005B0F3B1E17377
+:10DF60006D88DF2576FF3F51DF12689B533A9DFA9B
+:10DF7000107092BC2BE620CBFB10257D11DABFADD3
+:10DF80000EFFC4D4087FC0ABFC218DF4C344AF02A4
+:10DF9000AE74A67770A4D2F7DC98B7D55136311598
+:10DFA000F9F7D72E95F969C234C51B74F4975F63EE
+:10DFB000DE84F37A29D16FE2C559B5D42E98E3E215
+:10DFC000BE6FD94DB524FFA58E6BBD5FC2EF875CD8
+:10DFD00066D647C51ACE8B63178D79E391C9C8FF02
+:10DFE000EE694B0C3E4B7C7DD65F9384FD327756B9
+:10DFF000A12A753470DFB56B1B8D97BFDEC072E54B
+:10E0000049F2E859C48AEDA569383ED3A178C22403
+:10E010002AD33EA94DA371A7E221B4CDF48E3B557E
+:10E0200044E32354CF4CEA9FD54B9DD89ED1664EF6
+:10E03000BD84F366E7A4786CF8DE99F08FAE10FF2C
+:10E04000CECC49F224E81417049FAEA4BEC7EAA9B7
+:10E05000D6E91C8F9524D33ABAE23161BFFED6923D
+:10E06000FF457014FB52405168DCA5911FFBE4C7CB
+:10E070003F2975E2BCFAA10A90FC9C09E7FE91E0F9
+:10E080009FD99AA8272040F5166729BD576F519C44
+:10E090009BB8EF2BA1F9815166FD795CF7E49D7681
+:10E0A000B607E56FE5B35F74F2CEC16C17CADF9AAD
+:10E0B000564CED4993F0DBCBDF2A9FC3E326089350
+:10E0C0005229BFEB1FF8BD1D253F294DC7F54F0C49
+:10E0D00073B16E413A956A117A0DE78342EFDF55CD
+:10E0E000C1F35B94013F3A8FF3AFE4A7145A71FF79
+:10E0F00059E90951F3E70C7145F5E78D1858AA4520
+:10E10000D8B1F2FCACA8FEAD454AE98888F9BE69F1
+:10E110000951FD45A5AED21111F36F2B1F18D55F24
+:10E12000725B56547FA669B2D01F1BA1BC54C87D38
+:10E130007929FB9BD9AC870A9D62EE1B387E3F8E06
+:10E1400017B6097FAAD085FE14D2A5B4AD88FD808C
+:10E15000367C8FC68BEC528F05A0DD3D91EC80FCA8
+:10E1600009E22FF68B6577663BFA056389AE68B7DF
+:10E1700023E02F7544DBF1FA44E127CC017FAD0B9E
+:10E18000E939A7751EFB5765E9D54561207C46BF77
+:10E190001F0B372AD19D77131FB66AAC37E70C895E
+:10E1A000D9AFADD4C17E8CF4EFE6C8B78C7D21E049
+:10E1B0006D27FFC63887B1FFB5CE33479DC67EE1D8
+:10E1C000DF3AD7AC9C85A5A971E15FCFFE4C2C9CB2
+:10E1D00079A9324F81FE15FB85ADA9EC2FE24F7A6C
+:10E1E0003C3FC1F07FCA51CFB922F59C43495F58EB
+:10E1F000706D3D67AC7B2DFFCF58D7781FEA54DE9A
+:10E20000DF78BFF7B9AEC47FBE1BE727C5799EAEE6
+:10E21000C47FFE5CF4FC199A5EE340793E0E8A27C7
+:10E2200040783FA96BE49A959CF5D6525BF6A15FC6
+:10E2300023B770F6F9402DB5533B8327AD78FEB96F
+:10E2400039AA4EF907C32FEA1767A50A7FE4F855E4
+:10E25000DDAEE3787D40B753DC51FF886EA7F8AAA6
+:10E26000DE0B73288EF40E37ADA738C49B872DF6CE
+:10E27000EF4D15FA7E857CDF680FA9FE15047F85BA
+:10E28000ADE351F2492ABFE9B1105F1C277F2FBFD0
+:10E29000BFBF775C0B3A68BFE38F041DBE087D7E6D
+:10E2A000BDFEDE2262A60CE253C517A94F4A6C09D7
+:10E2B000BE48FD51E67445F5C793FF83EFCD760F59
+:10E2C0008C7A6FAE9E15350FFDD81CF2876A2C90A4
+:10E2D000A3913E35257AC8CF8BC5E3EFE5F93D0E16
+:10E2E00027B951604ED7557F1CFBE42911F88B7D6F
+:10E2F000BE3D55C47383C89EE33A2752756E6B5575
+:10E300009F70E6D07F267E88ED63ACBA8CD6C3952D
+:10E31000DDC4771EBBE90ABAE0F0D2E3F3E76A682E
+:10E32000FF3DE34DFF381CFBC71E5F21FA534DFB39
+:10E33000B2B1DFFAF87DA27FA369BCD983EC19B82A
+:10E340007F6E29F90BE9BE7F27FA759B1D5B15D4FB
+:10E35000039509A8D7B0D54C0A14A6F7C5C7DB2D7D
+:10E36000685F91C0C86C5E17D2C06E15F17465C24B
+:10E37000D020D913ADD8AB13DE2A130C7A77649270
+:10E380009D87DA0951719DDD82EFE1FB6536FF0B58
+:10E39000826FC2C93AEAA5870E960D20FE3891EA2F
+:10E3A000643CE4ED9BEA267D85F0ED21FBFEFF0158
+:10E3B000BEE678F0D59AC53E9DF57925648FF38643
+:10E3C0002179943EFA156A3A3F4F0821EFB0BFEE2B
+:10E3D0007553FEB1C665F190FF7E42F2EFF5B6359A
+:10E3E000328FA1DA051FA929A6F57BB17D5BF2CF9B
+:10E3F00019B92F6ABEA10B913FC0D933745181E87E
+:10E40000137FA86A610FF9E13DFF90E4A1F8F98359
+:10E4100044813F18D2F3D18FF1F97B77E779B6F1D8
+:10E420007381A765C1EC9A0EEC8FB3066FA0FCE375
+:10E43000A134FF4784873BADC191CC878EF549B4A9
+:10E440008FE2058E538CF80FE33CDD32BC7F5C70AD
+:10E45000EDFDC1467665E9648177637FC4B18DE8DF
+:10E46000F1DE24F1DC8007E1E8263E30E0EA8507B2
+:10E470008638398F0022FFD425E38B2E5A8FECA7E4
+:10E48000EA1079DC3F9838FF5245C28AFD7DE74D9E
+:10E490001C0F1A79E02210FB4D3EB54965E003F8E8
+:10E4A0003B51A2965E695CCBF1FD84762D26FEF68B
+:10E4B000B23D9D2ADFBFA9D55FE2A0F6FDE8795302
+:10E4C000651C3F09822AC559933B62C61BE77F46FC
+:10E4D000EB4FBD18FD3C294DDAC3413028324FB215
+:10E4E00041C64D974F66A7101F6B182BA8480F8B7E
+:10E4F000AEC2A4D43E3DD3B011E759499FDAB82D3E
+:10E5000038EBBC8FF669DC880C3F9AF4AA9B5B431E
+:10E51000EE0ACEC2BD3036621F2917061E2FBF2F4E
+:10E52000F038AE23E797D3B06F6E354350EFC3C3D7
+:10E5300014892F0CDF38FEBB7CD1C1F66B62DB6225
+:10E5400095E4D9EA36811E71BE043D11F4087D6C54
+:10E55000CF498DEAAB929EB509D17ECA78B94F9268
+:10E560006750D47A86BF62D0F350EAAC56F263C6E5
+:10E570003B56B1DF9232293B6AFDA293D1F82E04BB
+:10E580009F97E263CF87C071C0C4B35A947F32298A
+:10E59000BC83F963D287D1CFA79C8FEE97A6C9FC25
+:10E5A000562CDDAE854F18FBCB69E97F3F3E5DDE23
+:10E5B000687CA6CD89C667862F1A9F039645E36BB4
+:10E5C000A03F1A1F83578D891ABF617D61547FD880
+:10E5D0000FA744CDCF428319D91FBE755ED4FC91DD
+:10E5E0003B1645F5473F7567D4FCDCE08AA8F1BCD3
+:10E5F000DD6BFE2EFA17843644CD27349BBE87FE92
+:10E600003736FE4BD47EFF53F4AF8DA1FF56D2E7D1
+:10E6100013885EA8370BFBEC19B925A43F5D4D6F3D
+:10E620007C43799B40B1CEF9AAC03CF0D4E0D82F0E
+:10E63000549F427A6E30A2DA847AA3D604ABC81E05
+:10E640003C6A32711ED390F317D3843FF2629AC8AA
+:10E650007B19787B1AED22D94155EA4373FA8E244F
+:10E66000F253549309DAC9FE691ED61FE71C10BE87
+:10E6700019F7550701E7C54A92272D9888FCA8BECF
+:10E68000A972FCA90EF2838EF6A4E6E4CE53849F11
+:10E690002B0E9B4E7CABA6FA0364DFF09CA1E7A196
+:10E6A000BF9FF3DE465849F196D15FE65EBF99E61B
+:10E6B0002FBB7BE6488A7F7B9FDFADAC2C8DA043D0
+:10E6C000E43917C5F1AB0EA409FB67D813C37EDC90
+:10E6D00069D56B3AD03E8C53857D40BB71200DF1DE
+:10E6E000F181F28859F86901339D1FED2ADF27B8BF
+:10E6F000D021DF806D4A9FDDD2BF43E6FA203BDAAE
+:10E700006F7D9300A33844F7F03DE31D86FE5D95D1
+:10E71000CBF8BBEC889E7FF9FEE102AFF720F690C4
+:10E720000EE72CE23C06FC17A55EFE42EAE54ED25F
+:10E73000C711F9EB55BB7626917F7E2E47F8E3C6CD
+:10E74000F3DF493AFF2E4DE5F3AFDD9DB0FE7C04CB
+:10E75000DE2A42AEA87E55E3C0F591F9CDB5C639A3
+:10E76000FC8A46E75827E5A8A2B523F94E607FFE4C
+:10E77000C3345CB772D7957B0ED0FBA69E4C616705
+:10E7800003BCDFD2F780E382A57F8128BFB633CDFB
+:10E79000CC7075A689386109364EE4BB25E803B80C
+:10E7A000A87D63DA2CE23F7C1E56B0BFA015CCA436
+:10E7B000BF16FAB3CC84F433E079673F1EEDCF691E
+:10E7C0003AEF731BF8F87EFBDD7B2A92D80F34D624
+:10E7D00033D64181203FEF3D57C09C49799FE90ADC
+:10E7E000FB17B89F8D9EFBEE1EBC99ECB0B1DFBB52
+:10E7F000E0BFF40EF2C522F0F0BAC6FA40D73411E9
+:10E800007AF9034B2F1DED44BF0D6DA630E585361B
+:10E810009CB3F2BD4A7775CFCB0F239C1FAFF9662F
+:10E82000BF82707FB4BCE7BF0EE0F33B9E5241470E
+:10E83000BEF1D9FD5A7A44BC79EEFE2B2C6FE8AFBD
+:10E840003CFF2429A597AC1E92930FD6BC342A32E4
+:10E850005E484E9F99904EF73B93D2E2DE6FC4C65E
+:10E86000A56B883F597E75F64B0DBE5C2DF972C3C2
+:10E870000BA3F9F986A4DEF388FEF32AE7C1363448
+:10E880005B39AFF18EE487352F7E333132CF578F2E
+:10E890007CA95BA975724BF7A63AFA09FB4E5E1E7E
+:10E8A000CB71ABEACFA2731EBEFA6932F5F7BDF9A0
+:10E8B0002D9F076EBB3EF8BB11799178AE4AEA797D
+:10E8C00097F44AC501AB4EF9AC9203B927EEC27E6C
+:10E8D000652BEA1F3CCF2557C7B1A7291E3BA800CF
+:10E8E000E5B72AC309ACE42B1B9420E5C3D634EE6C
+:10E8F000DD3218FB6BEA161611BB56250B7D5659F7
+:10E90000AF0437B11F3E87E95C2865A3E450EEBF32
+:10E91000E5E378D771B1FE858DB0F63CC69D5DF517
+:10E920005F5E2038D6355A39CF7621296C198CFB99
+:10E930005EDAAB84027A9FDC76B9441CB62AF4987E
+:10E9400085F65DF5DCC211E436761D386D213DB9E2
+:10E95000AAE1B159F2799130FF41968BB5BB9595FB
+:10E960009179ACD5E80E42A4FD42F80213FBEA40CF
+:10E970004E49FA2C6B1A5E43E842BDB6FF6985F535
+:10E98000DA42E2970F0EEFF9DD6F68DF83FF3D9209
+:10E99000F15F747DF8075F80FD8B4AB90F5C3C63C3
+:10E9A000A1F8B2B2C17C21DEFD5263BAEF1EDACF0C
+:10E9B000888F63FDEE2D1610F73FD9107C9EEC82F8
+:10E9C000A3C7B21CE1F9579A80F068CE1ECB0AECBF
+:10E9D000DB48CEC85EB81DC17871F5BE748DF18478
+:10E9E000B1C4FA78F7A021395EA27758289F57E979
+:10E9F000EEB4105F57863F17F7FF8D9FCCF2C689A4
+:10EA0000B75F4E57A4333F274ADE37648C61B93075
+:10EA1000F7DAC3908DE5BE60450FD9A90D07913B8C
+:10EA200014A2B7BF87E00EEC4FD0E97C25073E9FCC
+:10EA3000D811B1CF1FA57CF4E6595EF964AC99F00A
+:10EA4000B9EF93B15A52DFF3AE4CC7AA78799997D0
+:10EA5000D385DDDE9CECBB182D07099E30EE5BD91B
+:10EA600064E77B1494832D2D45917270C7AA5DC411
+:10EA7000E74DAA0725022A1B17FAAB797E9287C8B1
+:10EA8000A336CE0C101FAA4E1FF327FC15F79B28A8
+:10EA9000EF8F50FFCD4DF73F4D72AC396065641E6E
+:10EAA000A4D2D4F1AB1685E8BAC36BA2FD0A81F5F6
+:10EAB00096EAF075703C5594A953DC7B74C22C2007
+:10EAC0003CFDBC59E1BCAF39D5BF358BE87B5CE57B
+:10EAD000F996A32F04E8BEBB6B1C14117CC6797F8A
+:10EAE0003E2E0C2AAEB3B9003CB4EDE6834BDDC438
+:10EAF000BF3FCF38C67E86DD1302D22B35E83F50AC
+:10EB0000DEC79E1F0AD33A0939BE2215F75993EE84
+:10EB100064BEB458FD1ECA273D20FB36CDB78AE03F
+:10EB2000B3A5278AF87BC8F5E5F9BA48FECD746F1E
+:10EB3000E9E77C4B9759F069D70DC07122D7FC4C9F
+:10EB4000A6212FE3CD063BB8AD6A54D646DAD744AA
+:10EB5000F0DBE879D7C1A51E82DF9C2DF93D33910A
+:10EB6000E52276FF8F889FA9CEC0B4626B16E1992B
+:10EB7000F0A6F79FF7A1E47B031FA0F973485E118D
+:10EB8000546FBCFC923FBDF82CD17573AA2FC7956A
+:10EB9000CFD7BCC2297627C6953B9CFF01C9B731A8
+:10EBA000BF95F089EF6FD1FC36C2EF51895FB3C5D5
+:10EBB000A73B59FE7D3AEDDF7BBE41F1CFF78D3C9F
+:10EBC000DF966CFFF79EEFCFF27CE654E4375A2FC6
+:10EBD00019789E39391820FEAB4D82A24DF8F8A85D
+:10EBE0006B969BE46ECB916F8692BCD72679DC4006
+:10EBF00079B1E69B9691DC6F197427F3FF172FE428
+:10EC000016AA11FB24A7177F45E73B2FCFB1C5E21A
+:10EC1000CFA1737C2CCF699C6B49BAEF2FE911F916
+:10EC20002618927E5DFCB3D7B8D794719E47DA61FF
+:10EC30008CF3388FD80D895C7FB657FAE11AF898B3
+:10EC40007FECE0D1D9BFF2C209AA2BA96931C13644
+:10EC50003A3E25B522EEFD925593110C7A6D18B20D
+:10EC6000D335348D3B9FD839AF16E13E080155F8B6
+:10EC700069D1F90CF02A5E25328FF1DA9AEBCB6379
+:10EC80003CE3AF21798DCD634C0E9B965B52AE2356
+:10EC90009FF1DABCB8F98CD119D171514186CEC03F
+:10ECA0008572047F86C28941913783F194BFEA2639
+:10ECB0005B85E39FE39959DE95AE1C9B0BEDE0135A
+:10ECC0004F6CDB3A0DE57084C003F56B88C9F5F134
+:10ECD000EC07F5E6475E1BC37E38EA3D95F3024E2E
+:10ECE000094B0C1D8BD07F1341A5272ABF123EF67E
+:10ECF0006D32F1DB9E54FD2DA24F4F9BCA75280942
+:10ED00005A87C51547EE0E907F8076E09F33843E8C
+:10ED1000B7358A7B4B9BEE653D99E0748E5323E4B7
+:10ED2000242F43D8A58A631F0CB5A02C5D329D4CBF
+:10ED3000CEC7F5D7EDAF4FA634DEDA736F4FA4D24E
+:10ED40009F3B35FF820C3CFF17CAAE5136F25BB7D2
+:10ED500006C7127E42E16CAECF2CD020A015F687FC
+:10ED6000A7EA293C14BA04954FA5715BD0347E25DF
+:10ED7000F15F55589C97F630A38ACC6D54B8DFD517
+:10ED800058934AEB55FDB67910E9AF9732849FF35B
+:10ED9000E2D53CF1BE061ACDBF3FC325992A68A231
+:10EDA0007CE34B324FD97555E579C6FE058D335559
+:10EDB00027F2417E78C711CE8B365975A26FC27388
+:10EDC00020F0D194C07E68D5E1D94076AFDB051E36
+:10EDD00005C7F724F67C44FCD0D36CD5E93E37C197
+:10EDE000B9035271FD3DB21E2C1719B6DED1F7DC06
+:10EDF000D82FA1E997944324BEE07BE5046D074C2E
+:10EE00007744E23B49D859C9577B12C326BA67E910
+:10EE100041DFEF5986AB0F4EE07D0D3873D90EEC14
+:10EE2000B1F45CF8713AC3E5243EC8050127348D7E
+:10EE3000D649AF2638BD7C8E04A7EE0928FDE1AA8D
+:10EE40001A8B8E20CACFA3A4CCA6F4C97755625FD3
+:10EE5000DF86B2B0271BA4FCB76E2B9D16D9478561
+:10EE600033A9EFFDFF78E2F8B6DA219CFF0BA84842
+:10EE70007F3BB649A9744E21572812DE8C42810788
+:10EE8000AA0BB4DBC478EF7CE473472ADB7F9EE7F0
+:10EE9000B13AEDF3B2585EF87ED1F00F1F52C217AF
+:10EEA0006E46D2763EE64BC9C773759A8E3C5C8738
+:10EEB000F3FEB83C342A8CFD16ABFF79E2CF573F06
+:10EEC0005CB1BD80F4EF1EB3A79CF44F47E071F630
+:10EED000CB5F34EBDB22E40E86F46472DD61CC3E62
+:10EEE00055E7363D4EFE76F74145A7FBF46E73CFEE
+:10EEF0005082BBB2E9330BD563561DFC84FDEBB2E7
+:10EF00004CFF5EDA6F526335D7CF4D861D5C3F876D
+:10EF10007A91EB20436EA14F2E9F1DF56C75041D59
+:10EF2000DE93F2063DFE6164BF9AA4BC1EA6381CA7
+:10EF3000DBFD2D770CA7F5F7CBFC80F15E351C19B6
+:10EF40004C78DF04AF716B3CEF0E6A5CBF9CF7AE90
+:10EF5000ED5E6FC4FCD352FE4FCBFD5667FADF2047
+:10EF600078D7B67C6AA1D2C2AAF3A1A114F78634DD
+:10EF70003DC519478FF4CA6F8C3C55693D169A5FA1
+:10EF8000751158AF20BD6B53907E2FBDDB386639AD
+:10EF90003EDF8F3449213B8BF12AD9E3FD66DF60E8
+:10EFA0009A5FFDCED763498F1D2420F07F5F37AF76
+:10EFB0001D467843FE2F4E2439DB0BACD70C39CDE0
+:10EFC0002739C5F7F389FF8BA89FCB7A798FA57D69
+:10EFD0001ECBE57E13905C22FFB33C20FF3BC9DFD4
+:10EFE000CB77A23CF0FBA359CEF7B49BBCEC37A384
+:10EFF0005E1FC9FDE2C5D4DFD35EEA6439A73A8457
+:10F000004292D7F0115E270440D7F2450AF822FD5C
+:10F01000FFBC8C64712F24F1393943D883508E9E04
+:10F02000E2C173D855354A3E22ECA5E84B7B5A9A8B
+:10F03000F9976DBF98465226ED8453DA49FF78D68A
+:10F04000FBFF286DD586D7A72CA8C3736E38A5F211
+:10F05000F86119F785259F1C91F91AB21B7A9AA8B5
+:10F060001FA6E713B04FF5E513BDEB4BC81C4D9A37
+:10F07000B3E328B5537CA11272DBA62D6B3F6A1651
+:10F08000629E47FCD770646E1ED5E3759FB3420243
+:10F0900082D8F06DCF472F221E1E3E8CF88F63A7BB
+:10F0A000F038CC7FE87F0D0677FFF16E45EA91409E
+:10F0B000D27CE2C7AE06B5AF8F8054226353DFFD2A
+:10F0C000A47D7B006DE77F677A0767223ECF0CF057
+:10F0D00073DB7DFADB4C12CBFD67455CDF60F1E64C
+:10F0E00011FF346463A81B874FAD9922EF536485E9
+:10F0F000B8F79C37670A39181580ED0AC7EBAA33B1
+:10F100008874BFD4A07A2DE82F5D84C092A9A46F23
+:10F11000645EF701903F5EFC45FA3C28BB0F90DF30
+:10F120008276EBC15FC4D61178D96F31F25800EB0B
+:10F130004DC45F2B9B14F80FC4C5AA67A2E7AF9319
+:10F1400075F2AB1B771D1B8C745DF35CCC38F92D0D
+:10F150007CFF11E278785D5D743DC3CD99D27F1953
+:10F160000EC3C97F41BE623D61D6A0D58A7CAC602A
+:10F17000144322F69249E00BF52BCB67BE616F8AF0
+:10F18000855EEAB9045CA794BB3B7494EA81A6D47B
+:10F190006579688F299A189FD29825EEA7B4A04A5E
+:10F1A000750C93BCFE59EC7707BC67A9DE6495D457
+:10F1B00097E0C45FCAFBC8D3AF92FEDDEA606C9DE6
+:10F1C000A8C053959C37198235B4EFCADDA2DE6919
+:10F1D000EDEEE8F955124FEB9E3A7D8CD28515A1E4
+:10F1E000987189A7AAC6983A16B138DC9F29EFAD65
+:10F1F000647DFBF5D65BFCD12CFC8DB7E53AC6F8F7
+:10F20000E64C91EFADC463107DD705D520F1D12A2E
+:10F2100025902CFC5E702CC7F3DD67B081ACCFBDB0
+:10F220005FE2E93EC93F7C7E7CBFE219F17DC5FD0E
+:10F230003F8B867F0DF82C83F1F9830D3FB050DEB4
+:10F240003196DF56D599D9FF5D23F113CB5F6B7AE9
+:10F25000F9678785EC5B2C7F55FA956BC02FFCF620
+:10F26000FF5BF80D3AAF91CBAC3587393FB5F60966
+:10F27000C543F9AB6B9DABF73CF27C7FEFB99E3594
+:10F28000E83D06C630BDE7A45D17BD63FDEDBD9644
+:10F29000DEBC26E7052FB766733EDDE0ABD87566AA
+:10F2A00049BF7DF653C27FBDD4586227FFA3FBA49C
+:10F2B000C9A3E89CAF4C2EC0F38F6F5681FC91EE32
+:10F2C000A6E13B03087FE1A9A2C5945F1F7F0AED79
+:10F2D00013DD07B716FD5702DF077BD248EE67B68E
+:10F2E0008D48FBBD83D761FBDE7DB2706739E9E9EC
+:10F2F00093A545B4AE82E3549F5E28ED54F5C94210
+:10F300007B4784BDFA4DA6C8CF6F71FFFE518A1BA3
+:10F3100066EF357B283F32DBECDF9480F015BEA032
+:10F3200078AA71B763ED479EA47551BE28CD8AF3C4
+:10F33000FEE9088D57ED5118FEEEA6B2BC3D643FC4
+:10F3400083AA87EC6277D37DF90F921FD4FC40FE2D
+:10F350007D11FB1D4B15FA66F60D66B6D79D83EC45
+:10F36000BF2EA7BCA87717EB8DCE43FB2CFC7DC32B
+:10F370001E05DC78CE63EEA32F131E3A0F9CB65009
+:10F380001050D270DAD211477F1BED250CF3C29CCE
+:10F39000AFDD61E1FACDFD7FB0D0792B9FFB84F327
+:10F3A0006F6B287E203FEF1995BF773ADAFCAA856C
+:10F3B000F8B4B24E81015991E3661E27FD4AFDCF94
+:10F3C000EA849E36F87F85E47783FF0D795821F52E
+:10F3D000DA7D5BE3F3BBA1FF1E04EF9641B8DE03C9
+:10F3E00075CBB90EE9811DD1F35752FC7A23CD17A5
+:10F3F000FCBEF2A9E8F1D5BD7C1E60FD1FAB47BF86
+:10F4000033F47F2EE4129F5F0EAF18A6A13C7D7DE2
+:10F410007ACD308893AF3C29FD06C36E5F0E9BD832
+:10F42000EEC5CEEB6ABC62217B5BD5FA27F673672B
+:10F43000357DC9F4286F6AE17AD95BC0BF8EF07957
+:10F440004B93DD49FE767987D003F39AACC1A04295
+:10F45000E3A15AA273F761F1BD49E090C2FE1648DC
+:10F46000BDB852E275A5C4E34A8CE306537D8C8C8B
+:10F47000E32B65BCBE3A67D7312A29A994E3EBDABE
+:10F480008E26131EE781D05BF342426F19F431ECF4
+:10F4900050ACBE400B770FD1776D9395EBD6E74B11
+:10F4A000BD35BF0EF596D25F7F740FB48BFCF17E35
+:10F4B0000177ACDDAD6C889EEF1A20FCD8CBD27FF3
+:10F4C0002E1C104D97F21EB0537E7F9EAE7A82FCAA
+:10F4D00056BB46FBB78E457EC3F55BF5E129F1EAE5
+:10F4E000B58CF64D191718FD059467C3F921E70E81
+:10F4F0004764DCFF9F03847FB366B21A20BA46C418
+:10F50000490B0AB3E2C6497309F43786DCF7B371D5
+:10F5100091719277D728E2B77F75EF2CA7BAA6AA88
+:10F520003AA12FBA26E1BA29E4F703FBD15575D6E3
+:10F5300020C53355C82FFC7D1AF109C96393524683
+:10F540007C8271C6EDB4FE42BAEAC4F32F6C44FB70
+:10F550008ECB2F2CFD92F9AB6D843837E26D40BC19
+:10F56000B8C388372AAF0ABFD6785EA97570DC5158
+:10F57000D924EAB51B8E7C33340BE1ED6EFEF3D05B
+:10F58000E5544F3E40D8E786E2D0A75457F4F51E25
+:10F590005B5CFFB557FF2BB52C0F95E68E4CF66BD9
+:10F5A0000EA21F7913EAD1B7BFE038A5E148C2BD6A
+:10F5B00094CFEB5AE11FE6FC1E3A55C326F683377B
+:10F5C000412DB7E41F45FA8D2B9DA24EE941693FBD
+:10F5D000A9FF08F2F583387746617FF937F449854A
+:10F5E000E4EBD510D83255E9AF072AA4DCACCDDF67
+:10F5F000B585AEF663FDA70A294F1831B0BD8CF56D
+:10F600009FFE33865FABDF4E64FFB8BB4D7552AED5
+:10F6100019F1FBAB41E427625C901D275FFB85E499
+:10F62000CF4E797F5C3D4965FC99268BD6F0B710AB
+:10F630008FCC37DDA71D41B26F79875FCD263E584D
+:10F64000BB3BFADE89E8E8E7BAB1A0C84785EC7CA5
+:10F6500017658CBF74F8D531C46FD56F7F3B4AD026
+:10F66000E79B5196F46BC367B48A22E2669322E269
+:10F67000E6FD5A4732C56B5507555F643DBF41EF04
+:10F6800097A53C8126F203F50374E6ABEA26C11F79
+:10F69000A666D1E2FE4B447EC8CCFBF71B2F46BECC
+:10F6A000F91E7B060417F24095B987F9AFEAB489D1
+:10F6B000E1A93A7D397344C47B015A7700E9BFEA76
+:10F6C00075C0FAC40EA46FE7D3F791D89FFF7E02EE
+:10F6D000FB61C7B2B7978BFB2F15487F3DFCF69AAD
+:10F6E000D191F660E200712F0E840737793FBF1089
+:10F6F000FB4B3C6C824532BF20F879AF8C9B302E9F
+:10F700007B73409CB8EC7AFDE9EA662B50FEB9EABF
+:10F71000032BD7197DDDBC92E37EB8EA1F4DFA06B4
+:10F72000FCFE1BA97DF8F0CAD1F4FCEBC3AB6FE47F
+:10F730007CA9B2292ACF1120F8DCE45F7DF5EE5DCB
+:10F74000E47FB669EC9F14B69D7D97EE69F7359816
+:10F75000F9DBD18AFD13760692C8AF2A9C4FDF11E0
+:10F76000ED6BD598FFD0DF32FC2B3BFB57A78AD837
+:10F77000BFC2757C416E8B4E94D3BAA78A8B689AB0
+:10F7800082E3A4D7C6937FE5E8F3B70C783E93F8FD
+:10F79000EC6E49E0BC8B02D982CF604414DCEB1ADA
+:10F7A0005E67FF645DA31AF5FD88F1DE5F06887B66
+:10F7B00087EF0C3E0B295EE6A3BDA25DD7B82F9361
+:10F7C000CEB1D61C623EA9AE338BF13DA205BA077D
+:10F7D0009AC01F4107083F27E811D2659E2538844B
+:10F7E000FCFABDBDF78AB22E2428EAF56A5A87F3DF
+:10F7F000774C975BF7A5C7B34327E99E071DBEE388
+:10F8000059221E8A1DFFAD5BE4418E9F13FAF1F869
+:10F810004CFFE8787A3200C5225FA048FA3588EFBD
+:10F82000ED63E735D37A78FEDD4302C7898F3BF776
+:10F8300026F0FD63A74BE4754BEADB34FA1E666DD8
+:10F84000833281ECD2DA9CF7F87B19EC17919E5C3D
+:10F850001B3EC8F7AF15757B6779E3C0B1DD2DECB2
+:10F86000C33CF99D72ECF87C397E063C19329EDB74
+:10F870004EF73E67CACD4EF1DD9BF8EEF556A9D79F
+:10F8800017DF62663FEA0CE866717F22EE391648A0
+:10F89000BD7DABD4F7B1DF631BFAFD76B9CEC2678D
+:10F8A0006033DD73C47E9F7DBBF40F178197D7EF64
+:10F8B000F75DBDF41363FFFE42895BEAF551308AC0
+:10F8C000F47A08ED0DD75BE426B0DD9E5F3032AEF2
+:10F8D000DF41DFA9EBF23B756A0DFA57E7BEC7F6C9
+:10F8E000F078CBB997F9FB867309901DE79EADCFF1
+:10F8F0001E1A7AE436417779EF51E114301AF4BFD9
+:10F9000084115A647ECDA0FF83920EFFC7754539DE
+:10F91000A045E6630EA9FE07DD195447DDC9FE3890
+:10F920009E80ED219E6BA83CD7506B849DBB3470AC
+:10F93000795C3EEE3B5F6A40D893746E5B72ADECCF
+:10F9400037568414FEEEB0220CA27F9BC2F9CA5136
+:10F950000D2D5CBFB1A454F178855A3C4BF0197C55
+:10F96000B4C026FC03835F7AF125F988C6C95FB865
+:10F9700055FA0BB1FC341ADA67D1FA4BBD8A87EA23
+:10F9800036AFC947CBC6BD4EE1EEB5F808F9D24C4B
+:10F990007A31969F5E73FB1F25FC75B75F5E5280C0
+:10F9A000EB1FCFFD6C28F14FE535E4E84549BFDD9D
+:10F9B0008EC071AE63A9977504F5B98D1D849756F5
+:10F9C00060BFB2D3D5BE6583F0B7B98EA0229CC00C
+:10F9D000F5A5154D76FE6EADA2A13A710CE9E326B0
+:10F9E000D563C77E79C3E952CA239417893A972A07
+:10F9F000BBA8BBABB28BBABBB9E9FEE7DC13F8EF2F
+:10FA00000344D711583A7EB5E17BF83E56DF359373
+:10FA10000F37E17F4E0F354BFC6C68BB923986C4C3
+:10FA200034DD7F88E0EE7EFD450B7D8A5135E6D5DD
+:10FA3000595482D6ECD679DE2D752DB5945636E024
+:10FA4000B7BB9D42EF9A8343D86FCDBFBE7A9BEA86
+:10FA5000836F8C25FBD5D5D236D612C1EF9D1B50B6
+:10FA60006FC7A1633598A41C6BDC2ACA22E9470939
+:10FA7000B9AE6A3E9A49F98B4E92E77C6ADF491E1D
+:10FA8000816DC5DE33C923C99FD92F5A63BD4B4D44
+:10FA90002ACF03AD63D4ED4991F06D66F82E85C48D
+:10FAA0003A001DA31617448ED7FCBFD60717853E14
+:10FAB000E888D207069E4216E0EF880387AD5CA770
+:10FAC00040F73FAE083A6A0305FD6EC2608AE476ED
+:10FAD00032DD7B0F27974F83BBA9AF41584BA5FB66
+:10FAE000E9B02AEAFB86B0BE9F28F7BF490BB750A2
+:10FAF0003DF064795F3A05DA79DE0CE8E1D60B4E29
+:10FB0000FE0EBA183CDC4EB285E7535A2B3F14E286
+:10FB1000EF7BC2999AEB824D7E6F1D87DE7D78D395
+:10FB2000E082810F95EED5443D53EC796E1828FCA8
+:10FB3000BC9BBC420F914B41F5C09320C4F7F9D355
+:10FB4000A143DEEBC73FC7548C0BE91E6F3ABA31B5
+:10FB5000898C8F20CF9F46E751E39DA7633E931981
+:10FB60004A9D049F12CE347D67BFFE7374533528BF
+:10FB7000E5BDEFEBE9FA7151DF3DA8A7E98DF7A9E3
+:10FB80007E59F17AB9BED943DF8D53FC13D63A7B47
+:10FB9000F55936C098812B72064EE8FB6E04FCC006
+:10FBA0007524B1DF8D447C27021723FE2E9251E786
+:10FBB000BB3BB848A73A9165E936FE7B3B85B6A1C9
+:10FBC000E329AF7928CD9F333083EA7DEB46F2629B
+:10FBD0005A7002FBB992BFECE09D447850BCC6F766
+:10FBE0002BC07CD3FBF70B3281BF27B25BC5773EBE
+:10FBF000DB911F6DA92C053AD55FC323253AF9D3B4
+:10FC00005B5C360F7D476C25B8ED7D70D7D8441D01
+:10FC1000488D4DD47918F572B178ADB119794E8F00
+:10FC20008DFDF198EF907E62F3DF42787A28A998F3
+:10FC3000FF0E53DE2BD3DC5C0F25BF7FAA4930F0CB
+:10FC4000506CE3E77DF594EC67D6523D37C259938B
+:10FC5000015CFF783469540AD565D5B4897AEE9A87
+:10FC60008C00EB77B35F617D5FD35AD24AF6E2B284
+:10FC7000C3C275DD352E51071FC880D0F37A343DDD
+:10FC8000A619F4A0FB4B598F64D0655C3A94D07BE5
+:10FC9000E3C2DE91849342DBCB37D0FDC2B87074EF
+:10FCA0007D19D26935D1A9F73B1ECDC9F51E067D58
+:10FCB000907198D99D92EE06BD9CC6DF23F06A51E3
+:10FCC0007F8FC0A0E3F644412F3355E00CE77775F2
+:10FCD0005A37964EFF1BE114C1BAB04B000000002A
+:10FCE00000000000000000001F8B08000000000062
+:10FCF00000FFCB936560F8518FC0F9D20C0CDEBCCD
+:10FD0000A862B4C40C5C0C0C41405C0EC41A407B6D
+:10FD10006F01E9DB401CCECDC01001C4FB81F81F90
+:10FD200010FF07620D20D604E25F407945A81B5BF7
+:10FD3000981818DA80B80388BB805887918141975A
+:10FD40009178FB93841918DE8923F87A120C0CCD74
+:10FD500052F4F3FF60C33156F4B5EF29D03E4E178D
+:10FD6000043FC71998245C50D570BBE03783074D1A
+:10FD70009E178DCF87477F9E212ABF5C0B953F4DF5
+:10FD80008781E123929A0A2DFC6E41C78A460C0CAA
+:10FD90004A46C4ABDF608CCA0F3081D000F9ADB1E8
+:10FDA00009A803000000000000000000000000009F
+:10FDB0001F8B08000000000000FFE57D097C54D582
+:10FDC000F5F07DF3969949662693900D0871028AA5
+:10FDD000A88013086940B4C322A2228E5BC50D26F9
+:10FDE00002D93710FDF0AFFD3210362DD6D0824645
+:10FDF0008B74C0A0C182040D1824E0002EF82FD50A
+:10FE0000D8BF7B5B0C4AC31692801B7EB5E57FCEC4
+:10FE1000B9F725EF4D26806DBF5FFBFDBF69F1E6A9
+:10FE2000BC7BDF5DCE76CF3DF7DCFB14DB2896F89C
+:10FE300063C6CEE00FD2AB2C8CB151DDE96CDBA0F8
+:10FE4000A187FA74E7FF5965D3EA87421EABD06EEB
+:10FE50001ED6FD9CB185547E408C6B38BB1CD3F400
+:10FE6000101B0E8F6DC91696CCD87D6E46BF01094A
+:10FE7000BE742991B1CE1556F7BA0C78AE7A5C08EB
+:10FE8000DFF7C8207750C2F73CC95216E43FA2BA48
+:10FE9000D701CCBE3F23B36CC666DAE06F0FFCC35C
+:10FEA0007AA0BE7CAC6C1063EA699905A07FEA7702
+:10FEB00012A5033436C3EF0078F92D6CDCD0EEFECA
+:10FEC000B913FDEC7380B7E8F9897E5BC0907F09B8
+:10FED00093A8FFECFB4AAA5F6F6FF1F25B6C3E07E1
+:10FEE0003616948DCF3B967FE9C2E78B9B6EA17A45
+:10FEF00018532CD8CF72B7C84FFC5C6396EEFABB90
+:10FF0000F114A27674D8D304EDFE8831E9B5BFB6FA
+:10FF100032C043D556D56305BC4CD8AA867F0C7039
+:10FF2000E95A2984B065979D31C04BFB6A0E879DC5
+:10FF30009A0FCB9FA80518AA28B736FFFC0AC4DB86
+:10FF40005699ADA366FC84F7561BC73B6BE4709EC5
+:10FF50009D83A56B774FC7F70B1AADCC0EF5956E49
+:10FF6000CF9F7A05C0F9FB5486454AD72FD0FA01B6
+:10FF70005C1892EA11EE18CFA8FDE03639B41ECA1B
+:10FF800077B89A936F83F11FABB431CFC5D06F6749
+:10FF900073F2AD8087A2D09649F85ED146C98B2C0A
+:10FFA0003461EBFA37FBC27BA51B24AF15F0525C22
+:10FFB00017CB3C43781FCEC0BFD60639FC63C89F21
+:10FFC0000BE3641948D7EA494CC6F657681E6737F1
+:10FFD0009E8E550E611E6B375CBA01DA81F7CA5EE0
+:10FFE00094BC38C4320B0B205FB66FB74F7BD68101
+:10FFF000E35BA00D76E2B8966A582E3F94BBCDEE37
+:020000022000DC
+:10000000C1FEADD526417ED1EAB55A9E81FEC575A9
+:1000100097318FCDD0AF9A412946FE884C8F019BF6
+:1000200018FB53C498AF1EF94409693719E4A29F1D
+:10003000144FF42EAE934DF50326194B82FF7E002C
+:100040007F02BE823B9D84579D6E73051FE9743B02
+:1000500025E487299DD9C6FAF5F4E74807E84F75E6
+:10006000A59BD25F54A652BAB2D243F47902F107EB
+:10007000E972D16FD758364E81765D3EE646314BF8
+:1000800098E21BA7029CE0E770F2DD01C97396F1CC
+:10009000EBE9136A20176572159BE453FA02AC056D
+:1000A000E6302FB4AFDCE89B389AB1D759E0711C29
+:1000B000FF222950807465AC3ED50F745922811EF1
+:1000C000017C2DC541021E96F4057E063A3D714F16
+:1000D000F6B3B224C69A8870DE738F66503D3554ED
+:1000E0008F0AF50C3A773DC9D3734CF5244F2FD0C6
+:1000F000EB594BF5D8CFAF9E27A68F31F7677A9192
+:100100005ECF0B586E91F3FCC6953C63ACB93F33A0
+:100110004AA89E94BBBD2C00E5659D7F58B34F86D1
+:100120007CC7C6F8118F32231F8DDF86F53941AAAF
+:100130008C7C1497136392A7785F8209EE33B99F82
+:10014000A97C927FA0293F65DAA5117CE970B75E92
+:100150002660E854385EA3FE6AFD34D23BE3FAD948
+:10016000087EA09F83F4CE03630217BBA1DFD8579C
+:1001700006F47F400B5CEE8EC237302E89A562EA12
+:10018000B1601A99BF54E5781BDFFFFBC107E1FDA1
+:10019000724BE7E07880FF4B1AF7218EFB8FA84C5B
+:1001A000816E3132ABC072315646FA6F6946F6B392
+:1001B00041035E970D007E91BAEB5DA60652911F3A
+:1001C0005B821541E4CF253041B07E8C1D6415E182
+:1001D000E085F0FE80BC54C4BF5503FD616C5F83B5
+:1001E000F68752FBADD87E5B2FED5B07E698DAB75A
+:1001F000A51798DAB769D03EC8476770BE681FF088
+:100200003786B1936C3EB56F4D2FA0F6976AACC0A0
+:10021000D47E4C57FBDF60BBDF63FB4951C63F70A8
+:100220008C79FCE945E6F16B7CFC6C4150B41F43D2
+:10023000E397A4201F7F7A111FBF95D7DBD5BEABF4
+:100240000BFF9A04ED3AA45EC63F68AC79FC1794A4
+:1002500098C76FE5EDBB172C13ED3BA8FD78691926
+:100260001FFF0525D4BE660D78918FB4FE31152190
+:100270009C4FD34080524807FA281D92C018E8933B
+:10028000DFB2818487076238DF7D1303FCE6E8D69E
+:10029000A72C041208F37099E0E9E28DE3343E3FA5
+:1002A00007695E9F2DBA3AAB51A6F98CADB4862E84
+:1002B00082FEB637CA418467ADBC3224D37C0A764D
+:1002C00002BEA7B0303EFFF3AA61EB8CE38A4C6715
+:1002D00057ABAD2D06B9EAD2EFE3D9900AE85F0536
+:1002E00032C1A86EB815F434033DFC39E8634C0FF5
+:1002F000ABDC2E39047A9C5D6C949B05DC2E09B234
+:10030000F78740FF7F22FADFAA707CB7CE9342883E
+:10031000FF6F56CCD1509FCDAE8E05A477F7A35C6E
+:10032000D0A973BB3544F6144C07889FDB491419D8
+:10033000FBD3AE1BDE945C303FD6F431BD77370B78
+:100340002D4E85F23397E70E70C3F8EF9A661D21A4
+:10035000E3FCC47CFD2D24C7ACBF2587B1690D2B00
+:10036000D4FE00DC3E4DFDBCC5F0FE1D01337C57C4
+:1003700081196E5743AA05ED994289AD857AEFA997
+:1003800030E7EBED4C9612385D457B3F011CF48560
+:1003900047F7603A021FBB89AED3DDFC5DBD3FE588
+:1003A0000FA92C4CF3714B1223FA2751B9809B8F64
+:1003B0003BB2BFD3559BCF0FFD99FEA04CF88CEC00
+:1003C0007FCBAE589F05ECD9969A2F5564C1C8F1E2
+:1003D00044F67FC6FCC8F1B8359C1F728391CF39B3
+:1003E0009F44F25379E3B85F1E32F05369FDB5BF05
+:1003F0003C6478AFB8EE26135C18BAC3543EBF26EF
+:10040000D7943FBBBAD0943F73D91C139C1B7CD0AC
+:10041000547EC6FC05A6FC7B2A1E31E5DF55B0C222
+:1004200004DF1178CA54FEF6696B4DF9965D97DCCE
+:10043000887254F581CC70DEF8DAD1FA73B437BF24
+:1004400076285EA4C711B057500E8E81BD82697B9D
+:10045000E348B2AB410FE63130A1564BFB83CBC62C
+:10046000A25E66A43F43D2EF83C134C69E973C840C
+:100470003FB94663616061892574F171A76CC86FEB
+:1004800039477E0D08FAC89EF9724BF4E7E5EB7226
+:100490002F40BDD39B3E805F7F9CE73A843D1099FF
+:1004A0005F2231BFF1B9BE7EBA5CE27ABE44AC5382
+:1004B0004A5EEA3B9EB9100E0FAE385B7BF5805466
+:1004C000D49368FD27213F801418E8515C37C82475
+:1004D000DF6DBB65EA5719EA04D0AB99CCBF574230
+:1004E0003D13DE9B7ECB30EC87EF75D4FBAC3189BE
+:1004F000E6F5B6CAC9BF3CA4227DFC941EA99C4661
+:10050000696B6580D2439505947E5E5941694BE5E0
+:100510007C4A0F540629FD63E5324A3FADACA6F490
+:10052000E3CA1A4A3FAC0C51DA5EE9A35497872E0E
+:10053000FDEB17F6B058B7C0036E0F8BB12C82B22B
+:10054000CD24E7DE5494F3538E6F06A3BD7FEA6398
+:1005500060A28CDEF115C96FBDD3D147F64A5E08A3
+:1005600098A74FCF7C7B0CA793DDC22633D0478F53
+:100570005CF49CF7DEA1042BC832C0A9DE9B9C5121
+:10058000EA85B90FE9752E3A315FE7705C67B73ECF
+:10059000FD976CACF77269209F87F7CA340FB3F0F0
+:1005A000B35EA4D70FC59BF4DA9FD25BA0DC892E83
+:1005B000FC35A73348E7486EAAFF5483952988C7BE
+:1005C000A6D8102E8D4FED7BD685F2383755AE3E2E
+:1005D00034B2777C95D667543B0CE3296F34C3A7BC
+:1005E000AAA5C9DC7FE089BB7518F295BBFAD04596
+:1005F00048FF544AF57AE6A66AD4CEB1BA41717C76
+:10060000FE0EF17970633CF12BAC3BA9FC3FBB3F84
+:10061000BDD5A3F787B106F6850DF501E40D3AF7D0
+:10062000FAA807DD95AF343FD2AB49FD06ED85183A
+:10063000F8776620D6AB10ACD75B5E2F07AD97E39B
+:10064000F38DA6F6E03D8FBEA6C7F77AE75B85B5CA
+:10065000EAE3047D75A5F0E714D7D9ABCDF34ABC26
+:10066000092E6FEC5B6D9A67F00F907F562129C8B9
+:100670003F25829B3A14C73209FA976AF150BDE5CB
+:10068000122F576A6BD1021E62C766B433EECDD10A
+:10069000F9CF73FB1F40DF1FFDADCA1EC57CE1D73C
+:1006A00051F56CB06F2DE8E711D0BD0DC55350EF7B
+:1006B0001DDD763DD927B398DF858BA402569D8D2D
+:1006C00076CE0966998CFC7F82FDDE35D2B0DEC81D
+:1006D000B768D49F99CBCCF32CD8672638BFC60C0B
+:1006E000E7B19B9391DFF356AA30B7A05C9AF36F02
+:1006F000B7B849BEF259C5125AEF083FD8BD6EA629
+:10070000F407B92F7DE599ECDCA1E887E0FA5BF707
+:100710000F1426703BA52831A4F920FF8B86913F4A
+:10072000B982E1FBA125A8A7824EE65DCF7AD2EF80
+:1007300087F63FB2BFFA7CD2C34F21FA21D749BE18
+:10074000509475DAC31649D85B414A978B71EB76A2
+:100750006B4D045C1B01D747C07F37BF253213BFE9
+:10076000A55A02359624CE5F682F484AA716F84747
+:10077000EA4FED517FED3FB5FE34A83FDB547FFDDE
+:100780003FB5FE0B7BF4BF295AFDA5AF6CDA16040A
+:100790007D53B479958BC13C7454A94EF602DD4B60
+:1007A000D62F76211F1C51822EE4E7A321797234C3
+:1007B0007EF8D222FCA2CCE790705D857F42FDC717
+:1007C0005EF8D954B4E7BE59AFBA69BD54670D5B42
+:1007D000414ECB1A0AA7A0DF17E0831C5E7A52466F
+:1007E000B8D1CC9F45CFAF4A46FF1E708A584F8480
+:1007F000C95E2AABFDF3249C87CA5927C959E47BFB
+:10080000D8FEE904D28FB95A5CCF7CE827D9F9E544
+:10081000022FE50D3F3B29BB30BDF630EA13B04C4B
+:10082000C80E8F7CAF40D841872CCEC4565842B1F9
+:100830001FB11FA1DED4F1C242DC0EAADAF0E4F04F
+:1008400083D0AFB6DADFBA2403BE74793B553FF3E9
+:10085000D7AF7A7AD7CBED62BDD7FD5E88DEF334B1
+:100860000AFBAD89A7256AD885F671C95AD51B84BC
+:10087000C7259B9E7DEE695CAF7E62F55E04F51731
+:100880006F7AE3C33100176F5113A7F06138A4E406
+:100890006EFA94C3BFF923BAE951F4F21B9A6718B0
+:1008A0007FFE7042375D8AB7ECD6D8B09EF898507C
+:1008B000BF5B6B7144A14FFDC1496867556DF85628
+:1008C000C375E5D15D124BC98882CFB56F90BD80ED
+:1008D00078227A0A7A75D12FA27C39D005F57A244C
+:1008E000BD22CBBD81FA6514AF17FD93C0DF2FBECB
+:1008F0008A7EEC4FAD5EC443C18BF7B9703C8795DF
+:100900000ACEE7CF2C4E463F7D811A4C7653CA9FC4
+:1009100017ACB99FF82FFFBDFB93F9FAD0D7D74298
+:100920007355B02F8E73F6EADB689C792C407C58A7
+:10093000F08CEC0F41FAB5C2266F892227C5329799
+:1009400093C3EB80B830CEC3B84E41BFEEEFE5D0D5
+:100950007AF28FCC61A80FEED7FDF16C2EC15F8BC0
+:10096000FD8471B2455FE7DA4CFC5BBBB419E974F6
+:100970006C802F05FD6AE54C090A7C4867A05EF98A
+:10098000BDAB53389D9847C916EF815D30019F6319
+:10099000F966D5671F6E7A8F9DC9E86E7F9E681FC6
+:1009A000FA1D83F3F9E16456501F657C35B2AE073A
+:1009B000605E37F09941DEB9FCD73EC2E55D97FF36
+:1009C000D04D9331FFABF7B91CE17B385F42BFC21A
+:1009D0002994BFFB5689F4839585A3C979AD2AE490
+:1009E000DC9C1FC92FD07F458A33F00DB69340742D
+:1009F00020BF5ADE4A78DFA857B15D57CF7A7539E4
+:100A0000CE17FA204F067D7059B73E60ABB91EE88D
+:100A1000DDEE0AF2F59B1A7AEE69945F90D7A00793
+:100A2000E557F5E3F88F6FDCFBE19D20B7C7EB7569
+:100A3000B935EBD548B92D7869BD847C1A29B7C77B
+:100A40000BC04A8926B7F03CAADC16B4FC4BF4AACA
+:100A50008EC7C765B35ED5F5646FF88CD49397CA1B
+:100A60009EA87A127EEFB3EC9EFCA8F3A1CE7F4540
+:100A7000BF29BD80FC093A9FEA7CD8C5A73A1FF67A
+:100A8000F0CF98F018997F3BF2040CC1BF5D257F31
+:100A9000624913DF8F83F7DEEC9F45F8F2D134C74C
+:100AA000AADFEC9F68844311707D44795F04EC8F6A
+:100AB000281F88802B4CE54B1AF76A8CF8206C2A8B
+:100AC000679DFF2BF6459475AC3E0F95379CD482FD
+:100AD000C81F699D1AEA3F752198A8E83FDC299351
+:100AE000FFB00370BC04DAE9D898110A821E596C71
+:100AF000E7EBCD0E77A72B01D2C5F11CEE4CD296B9
+:100B0000A01ED49F77DAB91FA4C3DFE98A37F83172
+:100B10000E36C9A4C75B426C72343F09CC3484DF03
+:100B200016D65B3EF78F76E0BE33B687FBCE40CF5E
+:100B3000AB6547FA7C5CBF56CB5E6023366BC1ED7C
+:100B40002E74A177340DBA711A3C9FFDB6CCB76DE7
+:100B5000823EA5AF61DD7184059F182BE17EDE72B8
+:100B6000E29F994D7C1D326B7974792812EFE5393B
+:100B7000E669A87761FDF0B9D10FACD753B03AE27E
+:100B800079D3F5426EAA693D58546BCE0F88F5D4DF
+:100B900037BAFEC96499A47F70A184EB7AA1B7AF7C
+:100BA0009687DE380DE8D3B14F66B8BF7AAA4926DA
+:100BB000FA9CDAC8F753593089E4AF8C7592BED4E9
+:100BC000F1D686F27571EF7AAC6DEB9FB21F423EA3
+:100BD000DAF687E1BF82B46DDB27837720FCCA4752
+:100BE000E97F603DCB4FD865273F73C72E27F17F44
+:100BF000C7CEDFA53F84F0762BF9F73A767D3B1C14
+:100C0000F9B163A1B500F560C700BE7EAADAF9EDBF
+:100C1000F0169A7F17111D33148DE87DAAE92F076E
+:100C2000302EE054138C0AED8B5DB1245FE5AFDA12
+:100C3000C91FD1B1F3DBEC80E39F379E32B1FFD304
+:100C4000E164D35EC2FEC573BF79F98ED1CF2EC0E9
+:100C5000FDF186DDDA4CC89FF0DA5F87A37EED7880
+:100C600089DB4DED6ACB1ADCDF18BA485EA802BDFD
+:100C7000DA51C8FA31B66FD1C4F128473DF1F257C5
+:100C8000F2B39C2F3E26287C3DFBEF8F0FC9C7F5A2
+:100C90009F33649370DCDF1DF803EA895D56E24BF5
+:100CA0007DBCC7EB17903D73AE71DFFB3F6EDC522E
+:100CB000F87CC6BDE0DF9CFFAD8A87FA1729073DA7
+:100CC000F97CE703046F727AA9BFE7C9EF6BFFA74E
+:100CD000D1FD25A0BBEBDCE30EFF3F4BF7B7A70B25
+:100CE000BABB313EA0FCB5BF52FF7EA89E6BF93760
+:100CF000A77B6FE3D7EDFDB72C9EF733A1FC6456BD
+:100D0000ED40C3E2DAD23D6F6742EE5B697BE3B14F
+:100D1000BFE323F67BF4345EE5FEB6F1B8EF03EDF6
+:100D2000B27849AC17F93AABBFB02FFACFCB233B1F
+:100D3000A47FDA63644F30C5B312F72BDF4A9FE913
+:100D4000A5D80B36E2E300C2EE2B056C5E6FFE4ABF
+:100D5000623EDC4AED9F7EFD3EB473D3D264B28323
+:100D60002125FBF775D764FEBC4433AD87AEF598FB
+:100D7000D7479312CDEBA889A2BEAB19EFFFD50ED2
+:100D80002914023C8C1FF0CB44F4A78EBF48651297
+:100D9000C093586011AE3B263ACCF59DC07D6C8364
+:100DA000BFF1EFC5E3C42E3C0E5CE9473C0E90C991
+:100DB000AF7A4E3C62BF096F99218CC7618A97E375
+:100DC00031A1D44B7E6AB11EC76EA21DA3389634E2
+:100DD000A33C2BB89EE678A075B8BE9EEE0DDF4C06
+:100DE000ACCF15D1A48E7F254DF6D9CDF5D1FA5CC7
+:100DF000A7CB0FA5874EC77F942EC9AA992E698EBF
+:100E0000390ACAEB645C3F8CC4F2991C4E0B2AB4BD
+:100E1000DF24D60FD778E628418027A4652A48AF7B
+:100E20007CDBF6228C1FB57925EAC7C56D169A1FA3
+:100E30006C5912E17D488D42F07B16F728A4F7D457
+:100E40002B5E39FE20433FBB4FE306BA9FEF977CF2
+:100E50007FE6CCD86CF4C7F01FC67FDE00EBB75935
+:100E6000AB593806F0345B61C1B804F4934BEC73B2
+:100E7000939FDC0CE3EFAAE4EE7ACE55BE37BDF2C9
+:100E8000CF4E5F013DF6F9458C6DC7946F8A28C639
+:100E9000F5F68F9A38BECAF7B3D0401E8721FB0DF6
+:100EA000FB8A2FABDC3FF3CA1F5F1A89EBDC711D95
+:100EB00043E3B87ECDE271A962BD708A79E2BC0ECF
+:100EC000D4AF83E268BF749FEC8C16E7B841ACBF27
+:100ED0007F83F1289076D4B26A19D757AC93FCBEC1
+:100EE000C15A1B5B1F251E668D6A117E224137F891
+:100EF000C9D9B87FC3DB9F0DAFC619E9D636E5A8BF
+:100F000032BC271DF0F7B961FFEA1FC52FAEF711FC
+:100F1000BF1BEC2D93FC51F447BDC0DFD43DDF91E6
+:100F20009FF4D2A6B516E4DF4B6B2DA6FDD83A553B
+:100F3000F83146B011D8AFA97BECCE2CA4CB3ED96A
+:100F40008BF1A5E54D27B540947DC4487C62FDE852
+:100F50007F6F55DDD4EE0EB57E26E275C7091BC343
+:100F600075F576ADBA385A3FEFB4F27ECE66F5F736
+:100F70000DCFF8F7C3EFB80E47783CAE3F6B99F052
+:100F80008344F21F233E3E55C74238BFE27A15F52F
+:100F9000C2A98D8CE67740C963B8FE0679FFB1D14E
+:100FA000AF7371E396DFA05D50D624B9714BA24CAC
+:100FB00069D1D08F5BDE182FE33C9CE9D1E36FDD74
+:100FC000C36E35C845ABAA10BEF68ED97117B6FBF5
+:100FD000659BC6D04EF1BDDEE9C279FCCBA691245B
+:100FE00007BD8DEBE54A563411E31C843E8CE48743
+:100FF000A11B634CF01572A01FCAD7546BCB3C6F7A
+:1010000014FA2DD324B18F789EFA2DF4FF997E7BAC
+:101010005FD76F01D96F9023BFC09B41BFA544D359
+:101020006F73254F0AE27DEECE412948D7B96FABE9
+:1010300049D1F4DBA64ABE2FBA59C44D7734807E1D
+:10104000BBDCA0DF1A40BF45891F19A3E97EFA73F4
+:10105000E8B7D0BF46FE36A17E8B32DE1B04FE749D
+:10106000FD36BCE920E9B7E10D16533CF0444DF8DC
+:101070009B7AD56F52D2AD681FEF53BDB151F8675F
+:1010800093B0C7378B38466C07F55C95F6C3F45CB4
+:10109000DEF9EAB97F119E753D37772BA3B8E89E3C
+:1010A0007CC8F5DCDCEDA0E724E447AEE7E6EE64BF
+:1010B000DC2F17A1DF86F4D06F8CCA9785F9FBE58A
+:1010C0008D194FDE0DF58DF0A95E1B941FD1ADEF8C
+:1010D0004619F55D95D68BBEDB777EFA6EABD07781
+:1010E000A0C706A27E8DE40F6F9339DE7CC7E8C3EC
+:1010F0001B5F4679F99D4CFB92EF59F8FED13BA35B
+:101100000F67217F7D2AFAF3A2C6E9D95E19A4FAF6
+:1011100027BCCEC757BA91FBCBCB1AB87D58562BFC
+:10112000873CF0E7A431DF69D8FFC29D124B01F87C
+:10113000266BF5130EB4EB9F5799581F4DC934F029
+:10114000C3AC9C62F2FB57D95DEBF0FCD12C85D986
+:10115000D0BF5FEC987414EDE0E21CBE1F502C9ED3
+:10116000EB71B0B3BBF464443C48E39C37FBB39EE3
+:10117000711653AD9CAE539F954218B7DA33EE22E9
+:10118000447AA1B8CEFCFC5D217F37C92D842FF6AF
+:10119000AE1C35EE432FD785A77D024F8017139ED7
+:1011A0004252543C01A5A7642677E3A5F0772D4B66
+:1011B000705FA0F02989F69123C7ADE32D72FC3A48
+:1011C0001E753F77B1A82FBF692D9D6B8AC48B8E8A
+:1011D000E7487C74E13D021FEF695D7EED9118D711
+:1011E000047C437A26F89F801768C73FEE22D3F924
+:1011F0009B8F045E46568F9B80E10F37611C3AE45B
+:10120000E7D5CC79B32FE063D4C79E11389D5E310A
+:10121000C61AC07DDA0DF64ED2833A1F0EB3723E67
+:10122000D4845ED9D1AF623CADF31B2537DA21E51A
+:10123000613BE1B51CF8D10E45F63EF5CD24815752
+:10124000379DAF6A14F313D0C182EB267DBE0AF13D
+:10125000F358239B385DCAEB385DB25827EDC7942D
+:10126000D548DE308CA7AC710EC5A1EBFA197E0E05
+:10127000239DA2F0AF128D7F193A9BB3BBE7CD62DD
+:10128000516EAAB5FA43DCE7990AF2B196D810FE7E
+:101290007716FE3E57FC5024BD2E1378DB847875FC
+:1012A00020FE3AB9FD15FE8ECE69E9F9E54AD084F3
+:1012B000D7094F9FE6FCB753F2A05FAC0B6FC8CFC6
+:1012C000903F4AC71BF233D2A1295746380FF0DDB1
+:1012D00027A3E77871BFD428F7853B0FF2FA9F91D7
+:1012E000BC2CCAB87F307FFF40BEEE4DDE8759C5AB
+:1012F0003A41F0F73BF6CEFD2391BF774ADC2FD180
+:10130000146FDAF7BCC1CAD74D1BEC2007B8DFF663
+:10131000B6EA5DE7E9A91FAEB27239C0F584C7E04D
+:10132000F7BA040782F1A675368A17A47E0CE4F694
+:10133000AA515F6FB2B3A45BB37AAF7F8AA8BF37FD
+:101340007B498787617BA8471BA1BD21DDED45CE89
+:1013500017BAFFE05CE3BA43F0CFDF3B2EBD9D1F21
+:101360001A4F55CE9A695F4C8FAB4AB5045E51D186
+:10137000BE9B2C99E2B7A0E782CEFF70FDB76AA3AF
+:101380007AAF9FA5DAC88ED0CFCB5E2D3B5810F038
+:10139000F6A54F2579012BE383B1387F8C8779102F
+:1013A000922FF78FFAE86ECA97699FEDC6DFF5298D
+:1013B000C57DC81B790C1DBB315322FBE13DAC6CD4
+:1013C00034DAE136E6B38A26213FE747F1213CD7FC
+:1013D00092595B3DC103723DA22E5485A9774267A5
+:1013E000E23B48AF7132437A35FBFA4CC0F9F7BEA5
+:1013F0003FB34CDC8A073B81EA19B18F2561B931D3
+:10140000BE245ACE8C6EF8EAFD5BA07FA3F7CB5EBC
+:101410000F94BB69AFC381723664B585050C78192A
+:10142000C34255E8771A7DC8770BEA8302B07BF098
+:101430007C4941D3DA2A17C2AB257ABF3C1898E41D
+:1014400082FE6DAA3939E932D40B500EAB295FCD3B
+:10145000CB95D74A5E0C71CE6B5A41F14879B512E3
+:101460001D60DC1492988DD71BB241BD9B56C3FB07
+:1014700059387FC1FB586FEDC9F76F41BD03FDA41B
+:10148000F737F2FDFA3C78CF8372523B87EA2B5C48
+:101490002D313C0753B091CF4F05FB552FE637EC6C
+:1014A0007E8AE6DD29D05EDF0C9C8FC213E93CD139
+:1014B00048C94DE7381FBE80F456070E185FF0A5E7
+:1014C000F3F80949C062FDA3DB7FFD6DFC5C539E10
+:1014D0007781D607EA79272729C342FC7492F6E17F
+:1014E0000F01BE03569C37793CCBDE9C2FB416C34C
+:1014F000FC98631B44EFCF6A1C47711EB3999FE2AF
+:101500003CA68EE676E7BB57DA43E8EF7B57ED4C17
+:10151000C3E77BAFB4D2F3F64D5C0FB70F6821BFC2
+:10152000FBE1D52AC3F32F55AB65D2138737AA74D5
+:101530006E577E86C737E46FE276C8DED5BCDEC361
+:1015400075DC7E9BF0CC6D93701ECE5FCFCFF9EA39
+:101550007A5A5F87E6B90B4DF35BA49ED5F570A967
+:10156000C04741F55ADA4F8FD4BBA5FA7C18A16F5A
+:101570004B719F9DF6D3C32447A5F591F1658E6EFF
+:10158000BF0DF243F83BE2EFB2FD2AC3758DF4457F
+:10159000DB248A67C3F91EF24737493E8C7B28F863
+:1015A000D81A227B3C943BE33F709EF9C4CAF0C832
+:1015B000482BD203F4548EB5F38FBF84E747DFB3D3
+:1015C00061E410F04F2EE15F8F13CE5ACFE37EB26D
+:1015D000DE5B998CE78DD9C43EA407F26B641630AC
+:1015E000E88DA392EF963BF9FCE046FB47A76B968C
+:1015F000569D87F36C918DEB47CF7A95CE8BC70BB9
+:1016000018D60B3EB4770AB7AF48D60CFC50B87367
+:101610004532A80EB644C4CB548973E6851A6FA729
+:101620007097E45E6B6847AF47AF57DBCEDF1BB404
+:1016300093A7BDD55F88FDA3717EADA1DE88ACA761
+:1016400047FBBDD493F35FA757E2B9FF9C77650AC8
+:1016500076CFF962CA20E33E8F9EEA7EE6ECF72D54
+:10166000CC67C05FCE1F6398CF40EF865120FF400C
+:10167000BF1B1AB93DD730EAA0569A45B01BE5BD4D
+:101680004CF8A3CB26F2FDBB86CCF716A1FC4FC9C4
+:1016900092881F5830A0F54924FBCD83FB00F959EF
+:1016A000FCFD7C781FE5B2E1292EA7A02F3CA84FB6
+:1016B000CA56AF9844E56B250FD6DFB03697EC924B
+:1016C000821C99517EED41B2930A1A0F26A23C83E7
+:1016D000FCAE447BA06CACD58DEA58974B5DCEDF59
+:1016E00015E76199CD3D0CCF77E0765834F996F740
+:1016F0003361B772B92CCFE172FBEE261547783E05
+:10170000724E72ADCBB18C729CD52DC77B574FD02A
+:1017100050AE0F87248AA399807A00E57C831EE768
+:10172000C4EDD8F395F373D999A520BF385FEA7259
+:10173000AECB75A43C372B2DB7623FEEBBD24EE348
+:101740009870D5F60FEFE3FA8AF65F275CF5603202
+:10175000EAC73C85C779E9782D55785C608F7EAD06
+:101760005CA0F53D9FFE45F4E333ABD95F126F8B70
+:10177000E7F1EFB52AF1FDB9E4B3879C9DA77C9E04
+:10178000AF5C9D4B3EF5F6E59DE67AE2916947F543
+:10179000ACAF1DF018063CBEB5F1598A0F3EF1C240
+:1017A000C1A94887E21DC0E7C85F1B9D2C8C7A4EFB
+:1017B00009D1BC55D420D33903A684B36F711AE57F
+:1017C00098C775156F76123F15BD640D4D81F78B67
+:1017D000B67D319CE26A167652DC5AF005612F071D
+:1017E0005B86A31C14293CBE2C522FFCDAC6EDE705
+:1017F000B6EDB1D3707C521DBFDFA2A8FE76D56ACC
+:10180000D8A778C2A652BB508EF67983C0C778FE9F
+:1018100017FB67BC57418F2B6BDBC0F54451A31AF4
+:10182000C27B328AEAB6B463BC71D1C756F27F95E7
+:10183000D79DA4F31413366F22FF4A79A36CDA8F75
+:10184000EB11DF592787AD1897D8504AFB90001F3E
+:1018500024B85EC453FEC0F8C3E2CD3BB705018592
+:10186000C52F3FEF42FD72AC79BD0BF10EF59E35F1
+:10187000DEBA473C67FD23229EF386C3746F4B2F6D
+:10188000F19CC7F00F1094B76DE6784E56D787ECF1
+:101890004BE867B63FCAFE47977DBEE9EB35781E39
+:1018A000A1EDA5E36BB0DF257FFB720DC689B15DAD
+:1018B000769AF7CA5FF880E2B7F5F7BEB0097FC83D
+:1018C00086E729FEBDFD13AB176B6BDF79381DE38F
+:1018D00006DBB77C978CFECC793BAF267FEFBCADA7
+:1018E0001352589479434F917F43E7117F1F49B7B3
+:1018F000BD0D7B299EED04D01DF560579C6E7D29A2
+:101900008F7FF688F8DC8DD1CF3BF488C76DB8E5C2
+:10191000C62B51FF37707BF29C71B9EF033D2F3F0F
+:101920000F3A6E14F1D7F5379C352EF704FE01F40B
+:10193000B2D8CD74FCBA61F6AF9FC6BC863EBDC6B8
+:10194000E586CF037FFA798A776C3EA71DE5E8A587
+:10195000DF503C34D26F8A07E7A3AFD3F13CCA1102
+:10196000B5733ACE3F9D3BAD74DF4FD1CE8F489ECD
+:10197000DAB7BE477E6A26CE35B4B3AE1F8F3F9727
+:10198000C4786B9D3C9E57D001E37D3D2E7A2EE2BC
+:101990007A395FEBF1BEBDC5F95E6D1F28EE0FE031
+:1019A000F1C8A5B57F10F1B3DD749372905E07CFD7
+:1019B0001A47ADE3C12DF472771C7BF4B8EAAE3858
+:1019C000F608BA213D719EEA8A5307386D04F94939
+:1019D0003E8A762EA27D2D8F7F6F57A39F37D6E349
+:1019E000DA7D11F4D6C7DB9BBCE8727BAE71FC508C
+:1019F0003CD16642524F7CB57D1F5DBFCFB44B7F5B
+:101A0000D7FABEEBBC548914791EEB5EE4CBD286C8
+:101A100083E4CFEC5A7F8BF1B609FF7BDB0B32C539
+:101A2000392FA9DF4BFA3D527F94E1BD2D51FA7B4E
+:101A3000BF5DD8E78D7CFE687BC91972403D6D7B28
+:101A4000B6135F976D3C4871D66FD6BDACB518E242
+:101A50002770FE0819C6D3F6E2EEE1A4CFC5FD302B
+:101A600091ED548976CA9BA2B753BEF1A4A99DE219
+:101A700060BDE6769CBBBD638AEF76ACEF5833B7AA
+:101A8000138FD5CB9343D1F669ECAAD8EFAFE629F3
+:101A9000CCA3740F8E93DF7B23BB62C8EE9CE7CC94
+:101AA000F9382E11538DE2BAAA168838B09F7A53AE
+:101AB00091DE55CEEB18F67731E2D7E0FF51DD012C
+:101AC00086F6AA9AEACF42BF43A4DED1122D2C6437
+:101AD000A0F73CE7E4140FED8B84D3909E07320F00
+:101AE000AB58EF6711FEABCF14B62405FAF7595087
+:101AF000F22E807AD9F75F0CF03B7BD6AFC381879B
+:101B00006593BFA9CCDA7900D72BEC353BED47C8FC
+:101B1000BBEC747F48F91A3B8D77EFD66F9F23BBE0
+:101B2000FBD756C6F787605583F796B9791D87B7F7
+:101B30007EBBE62F6857E3CBD07EFE1A288FEB8959
+:101B40008DB1B4FEE978298EEE51CB7FEDA1A9A825
+:101B5000D7F263393FE66F4E0955417DAD491C6EA2
+:101B6000DD3480EEAB287EC949F1A57BB7BE528635
+:101B7000F354FBE6580C3360EDAF09FBFF37E27E10
+:101B8000AD1AD5638C332F648AC7782EA818615399
+:101B90005C13233F06C911FAB11AE3E83C11D8C51A
+:101BA000A67A4EA89D0F78898F83FDF839AA703FD9
+:101BB000D40791E5F4FCFD767E8EBDDC0AEF39BAE0
+:101BC000CB976B9D791CAEEEC7F5493395FF44E783
+:101BD0007391DFB35E5EFE23BDDEAE7AF8FB65E295
+:101BE0007E9B48FE3DD4A557FE7A71B4FB5BA2F400
+:101BF0009F9EDF2FB1A005ED962D76BAB70BEF674C
+:101C0000C0730EDB34BEFF55E20AD3FD393B843E80
+:101C10002E8909D37D3EFD443FB03CC2CCD6F22292
+:101C2000D2BDF4153BC3F8B3D2D79C3EA477E9B636
+:101C30006F5B7F9585F18BB1E4D72B7DED7F111F15
+:101C4000945AC3D3E9FEBC2D5686F7E7B56D793BB0
+:101C50001DE5B54D0DA7279C655FAFB4DE6ABE5785
+:101C6000408CE35865E842BC77413FAF5BD48B9E24
+:101C7000B93286DBD7F6189F3586E4DD7C4FD4B1C8
+:101C8000CAC641C6F3FB459EE87AB17F8CFA8F9DA8
+:101C90004377F438F7DA3F2609ED99E66474409605
+:101CA000813D8EFABCA8EEE430F41F7C16A3DF6FF2
+:101CB000E089C3F9E833AD7318EABFCFD23B871987
+:101CC000E7992395368FA2925F87D28EB527F3FAD4
+:101CD000318C37B54F8BA6F786C5C412FE8A1E8E8F
+:101CE0008D7A8E7A4C0CE7AB34681F536C17E54342
+:101CF0006FF7332D447AB831C6C3EB490B69F8BC92
+:101D0000B86EFB20231E0A956A2A07724AF82C64D3
+:101D10002BB52C83FED6DB2B9CEFF028743F81F291
+:101D20007FBAF855EEA6333991318E51E014665CD6
+:101D3000F233EBE74814D56F43FC69CCEF5664648B
+:101D4000956A92F718564FA903CC2E7E5F5A054329
+:101D50003D7944ECEFA31F0CD36E7C3D487A3F38AD
+:101D600080B18B32F0BE094F9CDB80BF6B70B33EFD
+:101D700009E3692B18D71753DC688F48C1003B0370
+:101D8000FC5455593788DF03C27C182F49262CF4A0
+:101D9000CFE57EF33BB483804FF93D8457B15015B6
+:101DA000A018C386C9EF3A9EF1FBF3967DCC8CEB6D
+:101DB0008F12410716DC4D7ACCC1BA7F9D00A35A21
+:101DC000457D5B15F7B71CDC9F73B85918EDC358F8
+:101DD000070BC742EA18AA1C33CABF2B0B60035F6C
+:101DE000BAC79AF323E502F45A44BBF5843FA8F737
+:101DF000AB887ABF8AA8F7ABB3D5ABE3A9DC3628AA
+:101E000003EFA5585C592FF0C6DBB309BC017E86F1
+:101E1000E03D7FCC12E315FBE684D718D11B2B964F
+:101E200007BA6E8EC9207EFA59DCAE4E8C97668951
+:101E3000350CD7C38B24FDBE4FE67718DE636E1BCF
+:101E4000C9E123A29DCD02CF8B74BF558FF276B22C
+:101E5000BF7A94B7F7563E267A79676FFD898DDE93
+:101E60009FF85EEAAF8E8D5AFF0FD54B65AF7DF4BC
+:101E70000EEEEF76E92737A0DE6C676E46FD541A4A
+:101E8000DFFAB7167AC2ED4C5B9A99DE31C8DFC033
+:101E90006F31179A9F47F24914FE72F48571DF295A
+:101EA000DABBF3617E5E4DE7835C31BE89B57C9F12
+:101EB000FCEE79DC8F07CB461FE6DF25F2EFAEE1C3
+:101EC000F6E3DD0FCBB40F1B79BFD5C1FFCDEFE13A
+:101ED000B8071F80BCDD335F0A8533A2DDDBC5DEBA
+:101EE0008F877A6788FE44DE8315609E49CBE4685D
+:101EF000F76071BED4CFE145DE7F318BF9C5FD6659
+:101F0000E6E759316EE2DB2225A4550FED9EC7822C
+:101F10002B80EFD1FE04BEC7FD2F599CC7662E8DC6
+:101F2000C7D7DF9A60D27FA78678E270BE66AF8B94
+:101F3000E76EFE7CEEB59E14E37945E574ACE91ED0
+:101F4000A02AD59B8AFA4D3D7D3DF3801C6AA707E8
+:101F5000318F211FEC56127E0CF3243D95AA84503C
+:101F60002F2A6E3FCB47BB379EF3B35E5E4BBCAEB2
+:101F7000CBCE7C17FE1D46E681FFCF5DE1A1F3DFEE
+:101F80005739FCA771FE955D39DE80A3273F04B762
+:101F9000F27157E1B8337A8EA74AF37AC9DEBE0EE2
+:101FA000E645F2CB796DD83FD9EAF9C883FDFBADA0
+:101FB000CAD00FD3133FDE2321C83F15EA4F712447
+:101FC00072DC94C1D8FE72BC6F14F4FF3271BFE8AA
+:101FD000A24A26521E57B708EF1FA53447A43E91C8
+:101FE0004EA6728F8A7B4A97547A29D5F16BF356A5
+:101FF000D33D98B60B79FB36B7A05FA245E02F40E2
+:10200000F6972DB582F61DEDEE8A30DE27C7D26039
+:10201000DEC161B9AB09BF9A9B91BF13CA136C456E
+:102020001852B5660AD1497157B07CC84F7504067D
+:10203000C7A27DE331DF87694D1D71D6FB31BBF847
+:102040006D13C7FB6312E7B748BC3FA6367B306E03
+:10205000E2B16BBBEEAB22BCC37288E3FD3FF97EFD
+:102060006E4FBC374F9B69C0BB337B32E1FD6702CB
+:10207000CF4B055EAB041DAA043EABC4BDAF55E219
+:10208000DEDC2A81DF2AC43BA48F887B7B17233DBB
+:10209000209511EFC0BFD6A14126437B7C0F0F5284
+:1020A00087E05BB785FCA4B2C3EF43BC5B1339DEAA
+:1020B0006D0EA003F135E0DD83F941C2A7EAE078B7
+:1020C00086F29C0E025610EF23F139A707E0FDB609
+:1020D000D824D487634C78D612C79F1FDE9FE2F3C3
+:1020E0005BA290F348FC256AFC5E605DBE7BB38F0B
+:1020F000AB445C7695B89711F18876CD2AC00FBBBA
+:1021000098E3933F1F22602FA54962FD5F0574C0CD
+:10211000FC27853D8478C674672C5FB7245A2A76DD
+:10212000AB88A7047EDF0F4B0CB2B46CC64380F1C2
+:10213000971A641E84F5FDE15A33FFC86E25E27ECE
+:1021400049CF93C86F2BDF562DB87F2FCFBFDE74DA
+:10215000AE5B9EE68BF710FE0312DA353F1372B8C2
+:1021600002F985FAC7D7C38B051F2C15F7063F2246
+:10217000F8E73121CF8FEB7CE3E5E748964FE6F1B6
+:102180008E89991671BF629819E309E3BDF54C83F6
+:102190007ED1DAC64329DD9FC93EB692DCC60E6504
+:1021A0003EE4AFF88F1F0CF1FB70FD7DD11E8AD786
+:1021B000EFBF1DEB89BF830EB4871571CFA4CCD7B9
+:1021C00093CD51EF8DADF2EEB1A15FA6B7FEECBE9F
+:1021D000691BF173DEE5441ED627E0BF6336C08E6F
+:1021E0001A5857C12FD61BC85E8C7AA5C649FCEB7E
+:1021F00080FEE71BF824B617FFCE54C7B51B505F0F
+:10220000BC80062430C12F6A06D911CF80730FFA23
+:10221000B156A9FEBE382FAC8A8FEE8FFB652CDF3E
+:102220008770655D6AF22BAC547DF49E7BAC59EFF0
+:10223000AC14F344C244B39CE8F3C24F457D573914
+:10224000023BB15FC9A727923C27DE1C7D9EA852A6
+:10225000B520DEF751358CCB773057E3F6730FFDA1
+:10226000C3689FE45460F03AF483E97CB690717DD2
+:102270001764DCAED4C7F504F2BD15E70337F13FB0
+:10228000CE0708CB176AFCDEE3BB2DE4875822E4B7
+:10229000ED512167CB857CFD1CE5CB8AF7587B2966
+:1022A000FD8590AB952887901E8FCDE0F6BCB83F9A
+:1022B0004C5FCF2CB48DA0FB22AB1C169A17944F09
+:1022C000AC2107AE0F768F76A3FF477666B9034E33
+:1022D000CCCFA2FBDCA5F82C37F2CD37CE59179C1A
+:1022E0002D1E16C84FF7162B2AF74BEAF7C8578949
+:1022F000FB0854F7CD0CFDD54F2656D829DE359670
+:10230000C787D7E46613DE811E9DB186755ACAB4AD
+:10231000EBBAEEFBC3EA9FECE55E83EF85DE606916
+:102320004176A1414FD488FB249927C88618F4C56B
+:10233000C28B2631F4EFF5D413BDE8CDF55C6F2EDA
+:1023400092A2EB4DDD8ED7F566A47ED1D3C5174C96
+:10235000369DBF541D5E467A6748743F42B2C3CA79
+:10236000F72F99D79B9BD1331FF095EC30E00BED05
+:1023700021DD6FF1E328E389D49347AED3E7D7009B
+:10238000DD3B344BF33C39FAACF3AB795EC83FFD2F
+:1023900008CD4F79A747535A50732DD9230C77692D
+:1023A0000CF72E1C5E7DBF0BE97BB846EC9FAF5649
+:1023B0004318BF74B8667119C1D5760FD266DC2F89
+:1023C0001E74E13D4DB3D6C8B49F7E2426984EF1CD
+:1023D0009FDF9F39231BE26316AC5D9A8EFC386B3E
+:1023E000DD523A377B24C137D86F80599687EC7914
+:1023F000FDFEC6BC67AD3EB4C77BE3DBBCD5D1FDFB
+:102400003D55F827AE53987708AE4376BBC6748621
+:10241000810F8EFCC24EEB822A2DD88E70D5BA5811
+:102420007C83552544BF0F28D571B50FE994EAF098
+:102430005D8B297324D07E4FEF72C4DB6F455F3B09
+:10244000EEBB3E2DEE45023ADD64F2BBF27DD7567F
+:10245000E14763B65EF26344BEA7977C178F936231
+:10246000EEE8F97FB7FF69688FF55D318EBFB4E69E
+:10247000F8924FE889791FA150C48BCF5A171B5A85
+:102480001845CE6689F3C7B3C47E99CE8F85D7EB46
+:10249000F639E7E3483E975EB884F8FACB7D2ACD5B
+:1024A0006B65C0AFA8EFA51746D37D500B9EBBE26E
+:1024B000718C0BFC6ABF4CF925A7EDC4C7ED3FF545
+:1024C000D23982CEDFA9F49D88AFF65D4DE701DAFF
+:1024D000C5FDD33A9ED29C7C3DBCC6C1F550DEE919
+:1024E0009F913C74F15768A686729E77FAE75C5E0E
+:1024F000F0FED93138ECEBDE1C77A1E06B80D72CF5
+:102500009F346921D49BDFC2E58A8D0D96911F7B94
+:102510006DACF7D128F2BFC6E131F9B5F25B96F3A5
+:10252000F7C0AE4C34C499CC12DF7BC83FCDEF6509
+:1025300065EE204B457912FAB05B0ECCF772B7DB33
+:10254000CDE3D4D317BBC6798569FDD63DCEABE8C4
+:10255000799EB053F25B4613DC3D9E5F8D8E369EB6
+:10256000EE718CA5F2EDF1D1DBFF50B4DF5A59C00A
+:102570007CA04F8BC4FDBF79A1FB34D41F79ABE3A2
+:102580001324C3B8F26B8A4DF14F7935B974DF5F0C
+:10259000FEEA5CED5E83BC76D185CD36D1E543475E
+:1025A00080E832D5E1DFE340B97CA1F0814F3D58AE
+:1025B0002FA7D3112D38BC82F4DB7DAE68E7A73E90
+:1025C0008CA4538DA013AC1FB20C74D2E913F97E06
+:1025D000EBFAD2073EC5FD8BA7F8ED45BDEBB10880
+:1025E000FA6544C75FA783F36B2BD80F81F3C2DF73
+:1025F00065A6F8BB5EF127E8ADE3477F0EF6DF5135
+:1026000094FB4E94CD51581FE78773E1ADBB7DC15C
+:102610000FE3A28F27C5A9F3C37C1604013EAA715C
+:10262000FBA3F7F13CC482B6F3184F979C2E36F10A
+:10263000438A7301975341FFA37B1E21BE6E0DC5D4
+:102640007AED19BD8F27C5D90B1F5C186443B3FF02
+:10265000EFF1C111CD37F8299C4760DEC279BDF09A
+:10266000F9C7861BFB97EA1897E6C479A9FAFCF626
+:10267000B783E3BDFB701D1E5C277BAB6048258ED6
+:10268000C0607CBFC8F5F437E8DF5B14FFC4F068B6
+:1026900076F4E2CA7D97A0DFB5AAB2995255D8C5A3
+:1026A0000CEDE20CFE5D8F68F7055E2BF4EBE2CAE1
+:1026B00066EEB7B50599DB70CF003B3292FCD88A45
+:1026C000C36CCF696AC08D7E734DDC83A02A81659F
+:1026D0001959E8674ACC0C1AF0778D93EFD72C4F35
+:1026E000DDE3C6FD102BD48FFE335B9A72CAE4770C
+:1026F0007B5D99E5043AE9D744C7B07A9F24911FDE
+:10270000F254841FF294A91F89CDA67D8A48BC2863
+:1027100036FE1D288509FFB3C087FE9DA4A56E3E29
+:10272000CE95C28FFD04FAAF2F023B36D645F6C1D7
+:10273000920B2C7C7D6853E8BE2B6B3C2FAFC5F110
+:1027400071D871FF43C6F559986027DE1026D3D59E
+:102750008B12C2F1CC2321DC878597E07AA3635CDE
+:10276000CB03F8FC797B20D70978FFA66FF301092A
+:10277000F733FC818B11CF357230D303E57F2D7792
+:102780006662B974C8FA3881A717E0398780619FFB
+:1027900094DFD7DC0DCB3DE10BE62B11FB86DF5F31
+:1027A0006CCCB7C7F82AB01F91DFCB4AFC42A2FD20
+:1027B00041FC4C079FFFFD343F2F77F27505F10771
+:1027C000F2D73E6E3F9D523C71B8EF87D879DDB4A9
+:1027D000EF63F3BC6E684F11EBD85AE057C5B04FAA
+:1027E00077A1E2B3203F5D540DCF8DFD8D62272789
+:1027F00038E8DAF2A876BDDE3F3CAF83F8944F4F5D
+:10280000227B24922F7674ED27F0EF69DDA1339EB1
+:10281000B288C3F14CFFD1FAEE93AEFDAA451C7607
+:1028200073A8FC5EBE3FFE696E1CC599EAFDB8A3A5
+:10283000696933DAC57734F59D89F8BCA3E0E23FD6
+:1028400063BA43EDDC138BFAE27E89CE97DDF9C1E2
+:10285000EB6A2CA45BDF5F47F71F3C2FE4713AEB78
+:102860005491FE01E6D6F87E5788DF47C5BC02AE1C
+:1028700057D15F71773874DB0D00DDF37AE80634E9
+:10288000F7A6EFEB7C03D543A0DE3D89F694F4F781
+:102890001ABD6F7298BFD7357EC546E3E91EAF8D6E
+:1028A000C6AF8F0F7A4AF8EFC28FB8F74DC7C7F897
+:1028B000997CDC77C4DE751D3BCB3AE00EDBB03F84
+:1028C000F3783EDE9F48FC7C8559A01F5F74FAF6C2
+:1028D000203F3EE3F4ED45BD5762EB4C570692BCFA
+:1028E000BC85CFCBE4C005C930FE130302172721F6
+:1028F0001E9AFB9C97BD7FC0CEF9FB809DF3F781AC
+:102900000C9DAF5B9CC8D7EC74228D53FF7EC792A1
+:10291000AD871FBB1DF8FBC4DBFC3EBB52D973E384
+:1029200043E4979699312E3E323D20FC0C2D5D7C80
+:10293000C8C73B43E1F232A32196CEC1CC982F9B6E
+:10294000EEDB9F319FC7C332A579F8ADA675C222D1
+:1029500011D7D2B31EF48344D63373FE04BA17657D
+:102960009BE61E477E91359CCF664EF4C9788E60FB
+:10297000CC3289F6F1471FF234B6003C3314EF45F0
+:10298000319DF9E07F0DC2FB51CA9AB97F34459E53
+:1029900093F9534857EDE1F33DC273104F0E9FC7B3
+:1029A00061D8CF69532B32DDC8CFF7387CA80772C6
+:1029B0006FF57D8274D5FD22FABCFB0AD801181789
+:1029C0009A7BB72707F924B7DEEEA3D4C69418D0B4
+:1029D0006BB90AB3619AA231C58E690CB3619ABD15
+:1029E00050D84F353791FDE0CAF16B78BF796ED37F
+:1029F000F35FE3FBF94A78B764E0ABDCA6B7BFA3AB
+:102A000073763E3FC5FD5E56A799D69FC3EACDF0CB
+:102A1000E58D6638336C8647EE33C36538366867B4
+:102A20008CF81EE19E9D5686DF2B2BDE6CA538F4BC
+:102A30005771AEA0785E3BE9C509C54DD91827711D
+:102A4000FC45A705FD953BFEFA32C559746E8A65B3
+:102A50001867B8FBD318168371BC9BEDEB30BF1819
+:102A60006887FED9E2CDF6B5184FB3ED529D4F43BE
+:102A7000140FB5ED6FFCBC4BE7066B08E32E8E6FB1
+:102A80007FFE45E4CBE31BFA931DF6AA14B4607DE8
+:102A9000C14738DDC708BD3E46E8F5E23AF37AFCA7
+:102AA0000A976EAFBA87E2FC372681E3BBB5B22F37
+:102AB00087C5772574FB6D8CB067DD40CFCF8776F7
+:102AC000D37988D0CF79A17B351FD16B410CEAB384
+:102AD0008EA3DA0CF44B5D5C63C6A3CEDF9784CC87
+:102AE000CF27BA24A1E70CCF33305EC5B32415E756
+:102AF000EF67A3DF537FBD8BDB192FBCA0E9F2206A
+:102B00008B7B2A99C770AEB25BEFB379FD319E081B
+:102B1000E935B0FB797144BB7AFDB12E2ECF5FDA77
+:102B2000F879824481876395FBC86EE8B2232B7DD8
+:102B3000BE890638AF6677722EE16F77F2BD86F9EF
+:102B4000AA64C3DEE4BB304EAE4E418F362BB9E3F0
+:102B5000B99F8F49C4E7723DF613F3118F6DF56F7E
+:102B6000B8B01CD8D9238C7167F93557FB261AE405
+:102B7000FE87F2B94EB71237C7CB2B39CD93F09CF5
+:102B800048710DFF8E6171FD6DB7DC80F85ECDCFB1
+:102B9000D3672BCC2F833C966CB9EDFA61F0BCFC6B
+:102BA00099515EEC0F54712B3E2FDE7892CE153D7D
+:102BB0006AE1FE8E48FA04059F3DFA134701EA399F
+:102BC000A8EF75CB087A7F9F05EC9B23E383EFDCAE
+:102BD00005458EB3FA0F6FA0F830339F02DF4B68C4
+:102BE000BF75AE97BCEBE8E9C2EC9BD154F72DA0C2
+:102BF0007879C88FBA7E290C99EB89A4EF6AC16FE6
+:102C0000F01B62E493C8727DA604E9DC74C97CD031
+:102C10009306FF43C9A16A8ACF8D6C07235898C1D8
+:102C20000EDA81E17528979B789C16FC245BB688A8
+:102C3000631FC461BAC715F91118A2F85236D183BF
+:102C400078BD994DC654D7376D39F5C3B1FCAB5239
+:102C5000CB73BFA2FA9C24E76DEE30DD6FDB4F9C97
+:102C6000476FF37058FFEE8F9E5FD464A7B8AEE352
+:102C70002734D2BF0B309E14CBBF68B758C0683D15
+:102C8000BEA5CF788C536EABE7F7A51FABEF335ED5
+:102C90003BCBBC1EA94FF4F9F620FE391AFD7ABED3
+:102CA0002617CE838B781C774A9F8ACC8A2874D2C9
+:102CB000DF4BD42A3271FDD3798FC3BB8EF014CC95
+:102CC00050C8EF9F4A7E9A5CE19F3AE8F6BFED025A
+:102CD000BA39A1AC0FFE25EC93D7A1DFF30BD9FBDA
+:102CE000807B50F73EFDACAC009DDFA30FF440FBB2
+:102CF0003315165680DF66E23C359C609A4F67AE0E
+:102D000096289E71D672F378F0BE6EE3FC5AC0AA84
+:102D1000A9DE22564F69C16A737E21CE472E3C2719
+:102D2000C7E3768A6ACDF9FAB9C0928D67ACD1F063
+:102D3000F635D3C7E7FB02C727DD6CA3FEDDB72A54
+:102D40008EEF7769CC87F36DE72A27E9FF6216A03B
+:102D50007EDC29E6FDF207737DB320ED983FD33783
+:102D6000AB0F9ECBE7F3232D19499EF9BD7EC5130A
+:102D7000597800BFCF87E1BC5BDC248587216C03D9
+:102D8000511DC19FE3BD26387EE379367DFC386E48
+:102D9000E373F63EA76F119E9B92F9B88DF9250259
+:102DA0001F251BAD267FD1988D52D079399EAF6AF1
+:102DB000A1F7CA1ACE584DF58A791DEC016607BAFB
+:102DC0008D29582BE3605675E9F1D025D1CECB1C67
+:102DD00010785C755B5E5F94DBC7D1BEED27109DFC
+:102DE000437A4AF8A358D806EDC58CEC82293F7B7C
+:102DF000218793E21EBDA6268DBE2F4AFB61336557
+:102E0000FF9B780EB3323ED0370EDA9969F1A52BCD
+:102E100024BFBEC1E46F9DCFF1F0E4888A4B2AA2A3
+:102E2000ACB7753A3F21D5539C40703B9FA79D5945
+:102E30009D6AC0201723E3B8BE8CDBD342E78F3AEC
+:102E4000B74A74FEF929E9209D0F7EEA5A0F43FF25
+:102E5000402AD009F5EF53125B84F7FC6535DC346A
+:102E6000E70DA473568C17E30F4A1BC6C9A50E1AAB
+:102E70003FB7E3622BD6E2BE54CA8C212390DF61B8
+:102E8000DC336E86E7A3E33CD45E5F07A77BEAC230
+:102E900060C6DCA1D8BE7FCE1B288FC362E8BC7C95
+:102EA0000AE0CA9940E932B4CF5259E66EB43353BE
+:102EB000A77846A04F7F958BB793649167DC84F623
+:102EC000E3080E273C2CF9D61113AEA07652ACFCC9
+:102ED000937AF81CED4D1BFA271C067A4FA8C8C43C
+:102EE000F65306F134510BA7613DFBBBE81EA075FC
+:102EF000C83C37237D3DEFBB7129B82EDCDF060BC4
+:102F000075D063FBD3F4FD97B083ECFB0B87F0F235
+:102F1000C24E9997C9CFE724A6EBF6152FD7A1FA91
+:102F2000E246A25E7D8FDBF95F397CE407BF42EBAE
+:102F3000E53C80A053F9E9581632CC0BE5D3BE210D
+:102F4000FBB3FCB4CBF41CEF0935C6959714ECA188
+:102F5000EF3B94B2663A9F505A6F8E83BF22267A17
+:102F6000BB3A9F979F9659306ABB9AF9F9E93E2C74
+:102F7000D8275AB964F3F3D392196EFC569453E8E8
+:102F800039CB6971E1FA710ACE47A8674296A07AF7
+:102F900079375DDADD2DA679A8DDC3E10EB1BFA8D2
+:102FA000E7EBF5B74FD3C4393D7ECF7B5B252820B7
+:102FB000C0CFD34D27C9DF5DD2B49BF0A3F3453713
+:102FC0009E6259D080A7E4AAE6B00564FCE9B8FD8A
+:102FD0004B875E0224D9A3CBF33B4B7D63211FBFFC
+:102FE0006B6190EFD8AC2E792775B3CA220BFDF038
+:102FF000EED289638D302FDFFD7EF3351381B7B2BA
+:1030000086F2F76BE3DE7B6B21C606759D3BE84CD1
+:10301000F73B0DB02D0276003CCC00BB23F213230E
+:10302000F25323E0345EBECD194E97BD8C6D8EFBFE
+:10303000E01A05F45C5BDFF074BC796479D547D79E
+:10304000E0F78E4BB3F8F77BCB9A24AF64D0A3653F
+:103050005E1E87E4F0B6683387221E9ADF447D50F7
+:10306000D228B971FDE0A8DF122618DFF318DEAB15
+:10307000E7EBD392FA83F45EAFF50FB1903C3F3AA1
+:10308000E4732A77AEFD2D36C5FC3DAFDEF6BB52AC
+:103090002D81B750DFEAF7C7B76DF9A8FB7BAA20EF
+:1030A0007FED7D7D7B499F469C5B2FC7FE38BAE54F
+:1030B00045C7E3A3434ED17DBA7F18D6F4019A07E2
+:1030C000B1F34E2EC0AB75FF547A7814DA5F7827CF
+:1030D0002FCE1F4F48A14B705E7A9A052EC176EF16
+:1030E00029BD68377E6AEC80DAF20C5E09F34DDCAC
+:1030F00049C2FF0167CB00FC64DDE9C7FFC2E1A460
+:1031000016BA09E6B6EAEFAFC1EFCD1E18D032C04D
+:1031100002F0F78F5F3A99E08B5A9E41F8C2EA04B9
+:103120000E0F6B1920C3FB03837D2623FDD6BBA3A3
+:10313000CBFD09A16FF4FEC50EF61D8943FBAA84E1
+:10314000CF3B782CDA067A757AD1B14DEB011FD3DB
+:10315000FF2396F4DDFAB65BAEF3131E827E8C6F0E
+:103160004C11F8A67991F4BB42F6445F9C0B13BA5C
+:10317000E9E94C6FF6D0BC7169C516B41F52A60FB1
+:10318000A579E35597EF27EE51DDE9E9249EFEC4CA
+:10319000EDE6FA5BB650BC46CA434EB2AB1E17DF33
+:1031A0006700B923FE7008BA58DC7C3CFF0D197328
+:1031B000D11B0080000000001F8B080000000000F1
+:1031C00000FFDD7D0D7894C5B5F0BCBBEFFEEF26AA
+:1031D000BB9B4DB209F979F343081071139318A9F9
+:1031E000D64D881831B50B22626B7149F84930C948
+:1031F00046AD162DBD5948548208D146040AB8E19F
+:1032000002622BFD82458C1AE88288F62BBDDF72A4
+:10321000EBAD3FBDD71B7E8A884256B45CEA6DEBAE
+:103220009D736626D977935CA87A7B9FE78B8FBEC8
+:10323000CE3BF3CE9C3973FEE69C33B31ABB86902B
+:1032400064428E25DC30C74E9FDF31E6159D4C224F
+:10325000A4BB33F49C494BC87B1221C44548F009F8
+:1032600053687B0E21DFEDD1047589B4DEE14D7327
+:1032700016D1B2447CBD45C3E5BD7FD5DEE5B3D2F2
+:1032800072312DD3E7AB12998BF533BD690E5AFE1F
+:1032900002FEAEA7E51E569FAE25AD589FC3BE7F6A
+:1032A000AA84DCE5A3CFD4763A6E297DAE9DB8B56D
+:1032B0009D8E6B918917CA0BE7166C5D4E616A7320
+:1032C000CC427889D79B2651F84E36E66A56D1769D
+:1032D000BFA7AFC835845C51E0CDB097D1F940FFAE
+:1032E000741CD2442795363CFE1C9837ADAFD77A74
+:1032F000B3643ACFDB1DFE39D0BE5EE39D42B4D04D
+:1033000089B7C07705B423889F39763BB627F2404A
+:1033100019BCFFFF084F95B8EE5F114F77EF34757A
+:103320009D2C24F8F705FDB7B9D7A12A07FAD2BA20
+:103330004E1A87CB77C3FFD07148AD2493143A2C33
+:10334000AB226E8DFF36E8BF79E9077AA28137514B
+:103350003DF42FF0BE4E0AEB52E9FC82FB24CF76FF
+:10336000C2DECFB2119295E8BF13E621E09EF7C30B
+:10337000E6347FD1F07C2C3F78A9E6765A9CB7E4FE
+:10338000CCAEEDF4FB790F59085186DBD31E719D4D
+:10339000DF7FCFB89A5C499FFADEB086E2EBFD1979
+:1033A000C4B39CB67B5F431A00FFEF73BC953F74B8
+:1033B000F7113285905FD9B5F89D49D083E4DBBD24
+:1033C00088E2B753224123D0C34C3DD2C36088D298
+:1033D000C395B0FE747DE8FBEE07278782747D06F7
+:1033E000C90091613E15C4BE5D89A9BFA300EB2948
+:1033F0009D044DB43EDA680E6D95805E28A0A55000
+:103400003F09EB5F95D8FA07EF30E238DD33191D3D
+:1034100076373A43C11C00B68B00DEC6A2A3947671
+:1034200082744864EF9499B6617C6CE372C1523A3D
+:10343000F0E2DBB43FB2DAE4194F1FB0843294BB40
+:1034400052713C4A0FAB91BE640647FD8FD342AB2D
+:10345000705C4F39ACCBA336EF7C781FFD914501F2
+:10346000F83799C84A63097D4AA4C3E8A4EBC0E1D0
+:10347000215D4F13A083BB60008A877F6F386F5335
+:10348000E8FB9FD825840308CD584E481D61F5758B
+:10349000CB2CC7A429F0D4860D09F4DDCA1BBC03CC
+:1034A00082BE72D9D348FBF373BA22EBA336C08332
+:1034B0001FBE4B80FE3FB7295628D3EFA7C0F2D3DB
+:1034C000EF0B87BFFF39F07D19C0C7E0276D166588
+:1034D000BB348C1FF1FCB980AFEB696FEC78629C58
+:1034E000F87E8FD9BDFF07F045F11E4E74015EB422
+:1034F000B8AEF1F0BAF4D1C74DB47E5E9BD6B182BE
+:10350000E2D3BFD486F315F0DE951ABD8EE48DECC0
+:10351000FF94A5A55C86F92F65744F961928E26281
+:10352000F1A21F2E53D25D48A28735D228EFE5F0D5
+:1035300001807F5177CCF7F8DFBF1A62DB09BE212B
+:103540008A14073FA72B459261DDFC125B37BD3E15
+:103550003A0FE4563CDC029FFFC6E58DA08B787CD9
+:10356000FF1BE0BB6C24BE5DFA814CE8D7BFD48062
+:10357000788AEF9F90107EF7B489044D94EED64B75
+:1035800012D2EBFA072D21909B83A6E80EC067604C
+:10359000FF8DB8DEE71ACD0AA14D36EA19BF05F74F
+:1035A000DB181F170C1480DC3B47E7ECA5EB73EE30
+:1035B00037DA9EA0248020A4E537DAAD40FFE75E2D
+:1035C000BE89F5B3DCA2105A0E0086E9B881E07F0F
+:1035D000B6118A57699611C73FB1570A19A0BE8F15
+:1035E000E239465E9EA3FF36940CCB8D41A800388D
+:1035F000FA2C08079D69238EF75D335945C76FD1B3
+:10360000485E0DAD6F593229D4CEE031C6CAD51609
+:103610000DE9904A86F9BF4573BCE0DE225627A724
+:103620007079AC60BB431285B3C9B83AA205FA05FC
+:103630003EA0F54BA03E67781D5A567FF417984779
+:10364000CB1E357D343DAF9EC79258BACA19A61716
+:103650004B29C317A926A1F1145E1B2F5B6A2221F7
+:103660002DE063E93472E22ADAF4E0C074A0235B4F
+:10367000692FA9A3CFC069E20D51B8A7F6F7BC36F0
+:103680008EB677D4443261BA81A5BFCD3B79D5F0EF
+:103690003A0B38AFE97F424BAC381E7E4741F1EE22
+:1036A000B662BB89B3AE887DAEC0EF92354C2F0FAA
+:1036B000C02BE01F99E9CD755C6F52FD8AF27A61EB
+:1036C000D704D4AFA0FF40CE3D95C0F431C83D90A3
+:1036D000336D8EAAAB1C749E6667D51447191BC741
+:1036E0006783E927A1FE88A7EB783D24DAA5E6B534
+:1036F00016B75AC76E47F90CF116DD90C8E4882C4E
+:103700006179D1AF753DAB103E19E9E6DECD3928C0
+:10371000971B48971EE8BC8984F440C78B8C24987B
+:1037200040E962116D96489F8BD71B8812B37E8D3E
+:103730002175B989CB85BB4904BFBF7B675C7D35EB
+:1037400009DB687DB391842DF0EC55D7B7507D8EA1
+:103750007CD6F78521F63DE966F3BD8BAFBBA33A76
+:10376000A4F5D3796F3051DDEA84065DB83E5397F6
+:10377000F5E07A269678731E06BDF22B9D672BA581
+:10378000DB3FF0F512F83966AFAA00BC9BB51A9C76
+:103790007FF46103E2E724D5E3B0FE6B1DE4AE598C
+:1037A000F479AE8D78F37580267BD62CDB483CAF60
+:1037B0007AC5D40074D3E0D0A8E82AD3A1C372F9A3
+:1037C0000A8EFFE596D0D61C44F714A0A7F25CA1A0
+:1037D00057C99499B47C4C47ED3B5A6E9963F543B5
+:1037E0007F03604FD0F2FD0E26CFEE77E8713D45A6
+:1037F00059CC57D00D1D07FB335FC59E028E654324
+:10380000ED9F6074C3F5F0BA46730FEAE121FAD573
+:1038100010A4DF229F1EF0FA0A972BF3C16EA1F8C5
+:103820007E851214C88F602FB35F293EE62DA5E573
+:10383000574E1779562940674CDEBCF21D3359416B
+:10384000877CF3CC4F1FFB275A7FFEB45E31D0FA42
+:1038500005406B74FD5E918817C60BBE680881BE7B
+:103860006CD2337BB469FF15CC9ED1FB372C8471AD
+:103870005ED079C0DE694A083DB703EBD33C94A221
+:10388000C9AB3A86CFE0CB16F6BD39F4B39FBBA0E7
+:103890003ED513A4EDA326FF4658D7748392887AA9
+:1038A000F9D75AC2C6091738285E8F8798DD7D9CE4
+:1038B0005649304EBF0DFBA17C9AB690F673A233E9
+:1038C00015E743E52FDA5927D618B682FC5D373461
+:1038D000AE84ED8FEB7CD3D368F9F88BC59EE5B44D
+:1038E0006AD0A70FEB293D07D632BBAF5EA36C01B0
+:1038F000FC90FD169C87588FC09AC5B5501F58B2D2
+:10390000EC16908F63F139C87B122337CF9168167C
+:10391000F0D3C686DCDE30E895FE891E54AFC44D78
+:10392000179FD28D9DB53DA963F88DEED3213D5FE4
+:103930006EFF40177239D343304E80CA6522F80FAC
+:10394000E5724C593B5A99AD63E095546EDFA9EB93
+:103950005312FC47605D5A9EFC8FF7972A305E1425
+:10396000E522E94A46BE3CA9F3CE03BA755487F571
+:1039700075317AFDA483D999F5066E0792B03E960B
+:103980000F457D79959AEEC5F304A77F5B84C9F74F
+:1039900091F51ACE1FB71A408F4D6520936CD02336
+:1039A00056E85FC1FEA79E0EEBEB69397B5958BF05
+:1039B000883F814F28BEC3463AEF931B6C8CBF29CA
+:1039C0001AA09F451504F5E5222DB5634BE0BDD245
+:1039D0003740D7E5D48B0EA42FF2678A158AEFF90A
+:1039E00084B73350BB97CAB1973AA430EC0BE6AF1B
+:1039F000376C35E5005F7BB53658CFCD12CAB1F9CB
+:103A00001D95051B6879C99E2B70FD132A185D2E24
+:103A10000939502F4EE5F2B1DE10D2A31DFE3389D5
+:103A2000C03E88F68FF67413FD28AD64241E40AEA8
+:103A3000ABE8211453A6F6D1D45E26570995E724A6
+:103A4000C66E12F21EE43889B303D5F41114FA8855
+:103A5000C93DA2A482DC1372F998DD97E8443B3E8D
+:103A60003F15D697AE27939BBB25C46B3369457D25
+:103A700022F4C0D0B85C8F9CD20699BE323C81CF74
+:103A80007C670EAEEB12D28BFA44E895B1E820DFEA
+:103A9000A9E1FB88D1E960BC53C1FE9A4E93F07551
+:103AA00074BCA66524DC3C853D6D53503F323D69B6
+:103AB000647A129EE6CBD097F1FA315E1FC6EBC155
+:103AC000543DD377629D853D933A8DD901539785B7
+:103AD000B4A408FC35DEEA94E461BB26F08ED1A8DC
+:103AE0005C09651FC905F99E50F9622AAD0FC8C46B
+:103AF0000B7C65A178E9A1EF3773FBB72795CDD78C
+:103B0000AD67F4AB937DA4D80AEB12C17D6F3499F5
+:103B1000D8811E053E37DBE87725F01DE3B7A1EF1E
+:103B20008DA4C31CF37DD52B26D43F175EB6850C20
+:103B3000688FF8B31DB4BF94DF1BD04E3DF78A0DDC
+:103B4000F5E939AE0F5DC2EF401E617E16BEAE4193
+:103B500052358E00ED4B33C6810814F659B383D924
+:103B60005923ED215E9F1399C3E8CA80FBCD0B8ECC
+:103B70008107A04CE121A07F6E71327E0FEC995637
+:103B8000FC43FA3EE0B37A18F6FDC540AF06EDF708
+:103B9000E718297D4DD72E8B3E48E7D19C69B58328
+:103BA0007EABCEFED7DFDD41CB1FEED11103ACF3F0
+:103BB000F6697349EED8F2B731A43B3E10C32F77B4
+:103BC000EF54979B7BD5E5409FBA7CBFD3E63A651F
+:103BD00041D9E1F982D2B5C1D07ABA87C26B78D522
+:103BE00080FA6886D3FF9013E4AD267A18F06CC88B
+:103BF000FE780AF83B02FD9F48F03450368A1431B3
+:103C0000FC035F5F30CDCFB68F82B761FC11A30696
+:103C1000F14CAD75F6443917E07CE2D27B3F3C4075
+:103C2000E7BF6896D9BE02DF786BCBCAC19E441845
+:103C30004960FD4D1FC2BE8BB66B84F53F3593B610
+:103C4000A37035AC67FAB0894412806F5BA8DD6958
+:103C5000A44BFC1BCE6F777744CBC3F47FBB9D3561
+:103C600013014EF92FB20FE8E351E837C64EDEEAF2
+:103C70006472FC4BFB993246F899B602FE9A8D03AA
+:103C8000FA4A3AFEF57FF90CE5FDE2A5AFE13E8286
+:103C9000CE633EB3AB4D0AC8A7C50F1EC0F762DFA7
+:103CA000762AD38AFBB6D7361858D9A1C7F2A9CD40
+:103CB0006C5FB9B8570AC13CA55917932A412F6CBC
+:103CC000D6D90D64245EE3F1F8C1A6B713C0EFF5B1
+:103CD00001221DF67B12B3C7ECAD09B87F505A1311
+:103CE000C0BE0CACBFF143908F8B376B3D602F9003
+:103CF0007D36F4CF2CDE7CC3C48556E8E7D3A44AD6
+:103D0000F0136DB9013C54D0CE17627E9EC8F5F415
+:103D1000BDBCE56A05F8F1D06606FF62877107D081
+:103D2000D1F57FD1227FC91AE2073BB95BEF9D082D
+:103D30007CAD6CDA3E1DD6E78399E91A6CBF4B2245
+:103D400076C08B63690ABC5F2CC93EE0E386F58DC3
+:103D5000B5B1764F9D93F9C72AB397A50C5891AF8B
+:103D6000E6803E6DDE4CF908C69FF5DEEFEE700D85
+:103D7000F395346BFD2D53A1FF67751EE0BB217BCE
+:103D800066D3B790BEE02F4CF1B598E3EBABF29958
+:103D9000C122F8A4B500E4EAE215AD05F651EC8CB9
+:103DA000213ED944F9723221A79D12F902FC9319E0
+:103DB0004ED5BE63AC7D9AB550837AC6E821DEED60
+:103DC000F4994AB7C9B01FB725C9586F4BD2237DA4
+:103DD000CB7FBA77E76FE8BC9E74FA2F80BECC2603
+:103DE000DE62D06B4AD45E45CD5A4035DA61641349
+:103DF000B3AF89CCFC85EB92C98E5531FB7353125E
+:103E0000DB4F5039F105F473EEDD3F1F06FCB6645D
+:103E10007D3C05EC85C0C5CFF4E05FB3F64B28DFF1
+:103E2000AD1E1F01BA09F4CF240B8A86E572C0C308
+:103E3000F446FCBCE624E9981C7545B19F4A97827C
+:103E4000E56E07417ADAB8D48CF6FE4657C80440CE
+:103E5000FFAD7C2BECA746EE0F346EFB85570B7441
+:103E60001E92ECE3A1AC30FE186C9817D2D2713ED2
+:103E7000DC9617C4F29E4A8F96D659B7FDE3CA5C0A
+:103E8000C0539FCE03EDAD9E810498DF87DB4E24A7
+:103E9000C0FC1AB66971DE0DA14F5216160DCB0982
+:103EA0009DC65F900476825DB2C2F8425E7CB8ED3A
+:103EB000D3940556E63F407D5A3A3A5ECCCECAC905
+:103EC000F0FDF5DF64EB726697210472F08C89F9DE
+:103ED000F745BB3336A6FFAE4B12FECDDE2CD03FEE
+:103EE000436579A206E4C4F7ED6CFE2E7D6F16F0F3
+:103EF000E54792BA9F252BB52444E552E34A8984CD
+:103F0000A8CC3FF3DC4B5920FF3FDCFE52565D0C42
+:103F10007CF1DF89E78D496A7F9AF0AFBAF4E10C52
+:103F200018AFCE63607ECC31FCABA23D59CFFCA470
+:103F300083946B810EC577830D662FD8BB83C4181D
+:103F400002975B5D3FF7D77ABDF92ED8D788EFE3AC
+:103F5000FA5F0DF444E192FA24F427588AA2289FCC
+:103F6000BFB4FC77D1F58C91FF749D8DB04ECDC65A
+:103F7000E8E17104E9430F78D3B75865D05729EDCC
+:103F80008CBEA2F76B709FE532274C81B8803EDD76
+:103F90006D05F9767D81B9439308EFB342D03E3386
+:103FA000BD10BF0B5631FA0FA610F4C3A5915609E8
+:103FB000FDB476E6E7CFA820F655B4F8B32466E75B
+:103FC000B88967BD360FD75FC23807C78BD00F409F
+:103FD00047202FCF4846A423A95F427B54ABE99DDD
+:103FE00007FD8E45572BC5BA72BA1A2AFF9DE8EA1B
+:103FF0004941C723E8CAAF205DB98DA3D315F72384
+:104000005F767B12F4C1BE3695E36B2D973FD1FBF3
+:104010008DC2AF2EC17C6B797FB5466B580B7AC4CD
+:10402000A3FB38D63FBC89DAC5B07F4A03BB9E3EAE
+:10403000C7B5CF5770DD486400FC0896AB8DA82F3C
+:104040001FD34472C08E499DD4BA1BE823755E51BC
+:10405000493BEE0B331CA01740D7A27F74E9341FF5
+:10406000B323581C283A538FFB9C96072B7DCC8E8C
+:10407000A8417E09AC3629A007A7F5E72C07FA0866
+:104080002C231E03D271CF8645E0CF9D6DF580AC09
+:1040900013F125B252CD779D128B53056F22180F65
+:1040A0001B8E330D6CF921E8FFC622F49B0CF98FAF
+:1040B000F309EA8DCB8D43D6AD3621DE45FC68D0C1
+:1040C00046117425FA91B13F9268647A68A47C40E5
+:1040D000FF734A05117FEBA19C2ECA3CDE23F85FDB
+:1040E000C4A36C45BE1CB0C82B9C39BF32439C0492
+:1040F000FC776CB31684FD00FA8D5919DDCA4F693F
+:104100002820E950FB9FABAA3362CABCFDD0F7C19F
+:104110005537575F8BFA77A81EC0A67A5994BD26EB
+:1041200005E255C3F532B5838D7D12FFBEE2E61B75
+:10413000A8AA1E94C4F87FEEF4821FD14454E3C5AC
+:10414000C227C7F5AFA3FD5B15DE3E38EE26E8EFCC
+:10415000A912517EA0D34BE15BAB53F78728E5DF73
+:1041600043418CF77F530EAF5A9D316C1F507BE15A
+:10417000CF4965C376C2A3EFD5765D49C7B2D83FB4
+:10418000D583FE15FA3EE092D00E89E7D70497F466
+:10419000D5EC6B65847D9DE062F6F5746049BA2FBD
+:1041A00041F91D58E62360DF52BBC4E942BBE4E39A
+:1041B000530768FDB9599F1F1EA740BB7BE6C1BED0
+:1041C0002A705146F91BD8A90D49946F8CFDCCAECD
+:1041D000A6FA1CE305827E96D839FD388204FC9746
+:1041E000DDFBA432A077425AB36EA36BF903973775
+:1041F00013C7E1FBCDF87997BB985F205058B5A164
+:1042000000FADF2611B01756151E4F5980FBA9631F
+:10421000290B63BE6BEC7B0AF1D9B853372A1ECB4E
+:10422000A9E104786C79F9452FC88D3321096542DD
+:10423000831CEA04BBB6A141031621290DCDBF039F
+:10424000E31F73F5643C9D5F06D777819DB706A792
+:10425000C2BCE9BF127DB5D1B708E5C4C6B9462BCB
+:10426000C6910AEBEE413CD8CD5EC0C3AAC2AA34C7
+:1042700018A765E6743BC64DA83D07F52D0F7E07D0
+:10428000FD4502AE557DBA1AB077CAA95DF70B0A93
+:1042900077A673468D87F2F538EDEEE2FBAC10574A
+:1042A0001F5D8EFFBF6446171D922FF8ED52F48FED
+:1042B00092587F67761FB31F6F71E955FEF15B5C03
+:1042C000CCAEBD36189906E4B25F1EB0805D1D20ED
+:1042D000DE4F605F4D7C56653BAE13935FAE360597
+:1042E000FD6646D7C0635742FDB532EE67883CF0A5
+:1042F0006318F75CA7CBB38A703E80F283452190A8
+:10430000C7FB5CFEEFC2FA96737BF5DCCB371683F6
+:104310007F51D85F9DCF99506F76DA94276B404ECE
+:10432000FE49667903C668641AED67C9E74E1CB793
+:10433000D314EA84F50FF668B1BEC9EA5F04F4DB72
+:1043400078EBFA299887600D15801ED5B9BA08D088
+:1043500031DDBEA01FC5E8F21188234F0BCE972593
+:10436000D0177176CD34F063E1BEC5857EDC2ACEF0
+:104370001FE329159C32222B747C91346CE7BCF925
+:10438000E7D932BC14F68FC6C8FCEED573CD04EC69
+:104390005CF248F4B006FCF8AE08017BB8B957C22D
+:1043A000719A0B5FD0C3FEE5EE5EC6DF01BEDFA0F3
+:1043B000F8CBC27894CBC2ED810E46672472781C8C
+:1043C000E0F979B69E84D076317E5742963379C033
+:1043D000FBD3F3F84333F737514D88F5AB5CC2CECE
+:1043E00058A18E5BF071D74911AF16F05A2CA9FC79
+:1043F000E4E2D9C3BF4F3C189D0EFC1BA5F4057E1B
+:10440000A70DD2CC7B5EA7F3DB5036C903A6989BE1
+:104410009293B604DE5352A4782FEDFB643AD00D8C
+:10442000A921C8AF2D7D95DA662B8BEB605E8CA53C
+:10443000B507EA53EF2A44FD0C719359F4FDB31C00
+:10444000AF6956E6C773AF08E6401C34F1A0EF9E93
+:10445000D761FC2BCCE8874DA56B6373E27325F81D
+:10446000BDDCA4F800E86777AD5202F088781FC47D
+:104470000B67160DE7E3383D92772B7DEE76399882
+:10448000DFCE406A005E781FB20EC71FC19F07E3F0
+:10449000427C0F9EE7D2C232FAFFC9C096EDB8EF58
+:1044A00037603E486DDF1BEF80FEAD35925E8CC7F6
+:1044B000C6D92DD589B7BE02F43F78F6D4968701C8
+:1044C000AEDBF67A30EF25CE1EB9FE9BCC3E3FB375
+:1044D000DDA2003F6CE5729BDA8FC827C15D6C3F9F
+:1044E000196F471E75A9F72743E5AFDD8E64F00508
+:1044F000B7B33C0B21DF037CFF37D8703E01F4D704
+:10450000BF0DC113970FB28DE783F48F9E0FF2E6B4
+:104510000E4B10E8E17CAF09FD92328F7B9DB545D3
+:104520001F002475380ECF01791B5872E6E71ACAAE
+:104530007F720F8B23C9128F33FD4A4B585CCC6BB3
+:1045400007FF8B805B764C777B8B403EB27937716F
+:10455000BF5193B34061F12E9637D494102E007B57
+:10456000EA55AE879ACC2C5E35E8D087615DA326EC
+:10457000FF1F5D18D762DF935F1A94D8B8564F8833
+:10458000D975270A35613D9D670FD807B06EAB59C5
+:104590007C6B289F60BFA1C7C0E290581EECCC4145
+:1045A00039592FE256FB993FAE9EC7A74ECC5AF41D
+:1045B0000CA45C7448AD35B03FBBB0AA12FDE80F47
+:1045C0003C39139FF52BD57EFF45E0A7CF1B8E23EB
+:1045D0000BFF7B1DF1E899BD3CEC47D450FB4559DE
+:1045E000295781BECC21F61520FF95205DADABE9A2
+:1045F000B3833EC168973412D83972A7CB0CEBFB5A
+:10460000688706F554B043E3857602CF39C9CC8F6D
+:10461000744D32F36BD0A50AC138E2D9A1E371071A
+:10462000DEDF72A209C35323B1E7A376B966347DF6
+:104630002DFAEBD0B51AC14F17CDD4A0DFFB82DE27
+:104640003B17FDC6CE020279541DB6D69535AC1E79
+:1046500079E78229EAC3FAEB64664812C509F233A6
+:104660003599E7CBC5E16D6197BA1C1F8F690CA91D
+:10467000CBF5C43F212D8FC50F62DFA72633F97517
+:1046800061550EC7B707F3E3C4FC976730BC6932C6
+:10469000D93337B36A2ED0412EC49773E0C9FCAB2F
+:1046A0007426087FEE752E09E9230EDE0E30DA80BF
+:1046B000BE3A593CF46F853F1EEECAE414AE1FBCEF
+:1046C0006E885FD6DBF5188FBE5C3F495DB25A0E2F
+:1046D0000D95BFFEFD2CDB27756A799E8D1DE5507B
+:1046E0009D9DCDE584E4D91186F7566A2FC03C3AEA
+:1046F000B525603F4CBBD58AF368D96F423F70F354
+:10470000B2812CD0E32D55030510B789C72F402B5C
+:104710000BF945DBD5B9E8FE03EC84D8763C5F4B5A
+:104720001D67F5FE20B90CF6392776BF01FA6AB786
+:1047300009F515FDBF0306F0B3BC9C83F6CC8736A4
+:104740007F1BB40B98C35B9ECD01BB85D94DCDFDBE
+:10475000861EB00BEB3A62E27CF09FD5EAB81F5997
+:10476000E944FF3BE956BF6FD814F7DD883860177E
+:10477000AEF33ABD7F22F03BD53B987F70B65183B4
+:104780007903F55ACF2290B7674D6A7BFCAC8DADAB
+:10479000D796A175F6A0BDB565CC75F614C03AD70D
+:1047A0006B883FB69F665867BABE4D7C9DCFBE787A
+:1047B0007501ACF3C7BBAF2E80755EA7EBF202DFCD
+:1047C000B439FC5B9369BF276FF0A13D25F2582FE8
+:1047D000971EF724ABFD2B43E5FF21FFCA58FA30A3
+:1047E0003C04875A1FBAF44A06C8833AA3E1BFD5EE
+:1047F0008BF037AA1FCF68407FC7FE3F7FBA66079E
+:10480000C8817E2DDA23A2BFFDB23F0FECA1FDEFE0
+:10481000B83D4169ECFE1BB95FD86D2441F0AB880F
+:104820007D80B027E3E5F15B7C3E1F257B6F00BBFD
+:10483000E6CBFA8D1BF83B63E85366E76E933CCCFE
+:104840006FDC8B7EE4967DF3EDE0273E1D627EE318
+:1048500096178BD16FDC187A2D0C7965A45FB2C3E3
+:10486000FEA371DBB104C80710FB5CBAAF3D938CAB
+:10487000F4A8DEEF9E0E9D4880FC010A7725E871C2
+:104880008B2BAA07BA6FA1FB3DC8236C91A387A10C
+:10489000DF1617C13C97D23EF5FE4FC47937FAF4C4
+:1048A000287737F64B2190D7297A7F4E06E8359244
+:1048B00061C77820E7B38BC9DED494B2D8F8BAF7D1
+:1048C000F3E4E4E17CB0810D8948BF033AE2B583AB
+:1048D0003CDB60E3F24C46F9F6C74D8E10CB0F631C
+:1048E000EDFF18627642A3C80B934958A6EBB56852
+:1048F000B6F75D586F90F7E138791F5B1671FBBB17
+:104900004918F552331918CA0F8B6D171FD78778BE
+:10491000B8AA1FD25AAC801FEC4EAB07E081F8B8A2
+:10492000BA3EC8F6EB941F96960CD3AF580741BF1A
+:104930002DDC0F1D6838FE08D06FA04FB2837DD7E5
+:10494000E461F4DB44F75B90471BCFEFA4579D373E
+:104950003A16FF97A6A8F5D150F9EFE45FBD3E45A2
+:10496000CDF762FEC26F3F34CF7E89F165DCBCE2D9
+:10497000F7A9F1FE76B1CFBC5C793827452D0F87BA
+:10498000CA7F67795837B42EF1F2501DCFF89BE5F6
+:10499000E1FF705CE3997D4F27C0BE03EC78D8A798
+:1049A000ACDCAE63F91314FDB1F1E2E95AAB97C583
+:1049B0004FB5A25E1D8757A6F3383CE3EBD75ED414
+:1049C000E2BA35F33871F33E9B079A365817639C69
+:1049D000363E7EBA84EC9E0E4B151F476D027ECE8E
+:1049E000BB743C75750A8B8F525872206F213E6FD5
+:1049F000EB35EBA749FE9875AF2AA21B8251E8DB85
+:104A000028078933E6FDC6146657BFC6F38BDC7AE8
+:104A1000768E60ADCDE285FD8C5BC3F29F7EE0F2C9
+:104A20006D82BC18A3C2F1FAF2ED4443F1F28CAEF0
+:104A300017E54AB0D9EA013928FC37A2FF8B3C5E62
+:104A400071D9FA3F8EDEF7FC0FD37B3C7EF68BF1FB
+:104A5000FED6B8DD7A8A1B155F10A4E323105FCA67
+:104A60001949BF63F533161D1F4DF11D496176FECF
+:104A700014CC57B84C3963298D9E003F11D963502F
+:104A8000C0AF097E12D48FABD3783EAAA77C26E6AE
+:104A900069B37325E21CCE5876E40743EBC3ECC838
+:104AA0000FC65C9F2F6747DEEEF07D087476B2D2AA
+:104AB0008BE7011EB551F8617FF89C61D4732EE23B
+:104AC0003CC6A5FC2D5FC4D1D517FF4B72D4923ADA
+:104AD000965DF975CBD1CF13C07F3A763F419EFFEB
+:104AE0001941BC45F749646B8C5F3B1061F97B1938
+:104AF0001C5EF1FE3FF8BEA121D59B994ADF7FFCE9
+:104B0000AED14812A99E2E6572B1C567C5B8424B99
+:104B10002FCB7F695946508EB780DFB408FC8933AC
+:104B200009D87D4F3AFD13208FEED1F7AC416D22AD
+:104B3000F8DB6711B0F3CEBDCBCA339CFEC99867D2
+:104B4000B76C00E318DDB3CE601E56F9179F3E52D6
+:104B5000538AF0A23FC165509F67B93D95C933F1B3
+:104B60009C3D846F2FFAF33F6E60F9DA0197D70E00
+:104B70007E09E10FB728118C2BB4EC61C65BB996A6
+:104B8000CD87FC3003E9A9654F6531F84D49AFA9E0
+:104B900018ECDDF2DF5B71DFF7F183E99827B1CF25
+:104BA000E5AF027CD84A4337817D9A4DC701BBF7F8
+:104BB000E3DD371503DC42FEAD03BF391D7F9D4D9C
+:104BC000ED1727469677BF644726EE339BACFE5A17
+:104BD00098FF3A138323B89D9F4FE1FEF278FE17AA
+:104BE0007C9FAAD5E038A9DF35629C5CC885753A00
+:104BF000E237E60DCB93129E671870F13CC7FE9921
+:104C00002C4F8597AD2E75BEE747C93794003C25DC
+:104C1000A9F2578B675947E40B94A4B27896EA5CE3
+:104C2000A2E522B3A773ED7AA427DB4AC2E254942B
+:104C30009EC0AEBF361A9906E7BCF2BBC3D7029E30
+:104C4000F75FD4209EE49947303E9328B1F1F256A5
+:104C50000F744E007F8CFDADEB6049952E7B15A047
+:104C6000F449A7EF8154E4FFD64218AFEA5F742CF1
+:104C7000BF729F05FD0CDD594D985F79EE3D83EACB
+:104C80007C4EFC334856603E656EDF6F314E60DB14
+:104C9000238D9A27FB44AA15F9A62518998E393633
+:104CA000D7BA50CECAFB7E1F04BB43EE944102919B
+:104CB0000E9D5703E7D382CB09FAF5C777DB35B0F2
+:104CC0005ED93C3F6670FF7F4EF1E3BE45C40542AE
+:104CD0002CBF4937F008ECC7E4E503DF0CC27AECDF
+:104CE00071685AC07FAA8BB6A0DF659F05FDACD95D
+:104CF0007D792BBE41CBD92BED18071B7CE5EE6CE3
+:104D0000CCE7A7F31C3FCA3C1F4A65F948F23E8B2B
+:104D100006F499FC04F1C0A8B223A50AE17E8A96A4
+:104D2000693FDF077A4A1E8E9B823F0AF45443AAEA
+:104D30007F07D0CDD0B9A4A566762E899FA7B52DC3
+:104D40007D6F179CF7D9C2FDB907F74F9E85FEBF4F
+:104D50004E598275B8E060F9952FA4B278E248FC0C
+:104D60001FC43CD6DC7DBF657A8DE202FA97758C54
+:104D70005EE44E570FF8195F49F063DEEE751D6172
+:104D80002DC6CDEC277F5CA3C4EC77D6333DD3B2E0
+:104D900093EDCFE3F73797D22FBF1E92334CBF0C62
+:104DA00095FF4E76CBEFE2F4CADFBC6F21EAFD5EE1
+:104DB000BCFD12BFBF1B618FC7F537961D23F25094
+:104DC000AA86C761F6B44DD84941559E4E95959F28
+:104DD0003B34AAFB5F9F64477A10793B29EDCA7286
+:104DE000C8DB8FFE88A0DF4EE415893CA26015CB9E
+:104DF000F7096A8C782ED14DBA307F681C094B12A6
+:104E0000FAD706F0FC6D2AE411D1EF4FA4E662FF59
+:104E10009B8967A516E5A62201FC26C83F4902B872
+:104E2000431B16C178B759713C13E49F24E13E033C
+:104E3000F939DDC7F256A735B0B8433AD5CF504E51
+:104E4000CF6774699AABC73C56915722F24F045E04
+:104E5000AA38BED3272CCA01B928F254D6993DE509
+:104E60006017C1396838BF1C6C34F3BC13D66F7738
+:104E7000632E9E4FFEB27929F17816F929FA447F04
+:104E8000A6BB6CE43967413731EB89706DDCC7EC48
+:104E9000FCAA063DCE63B07106FA2B071B3504EC65
+:104EA00081AA7E03A3C3B8F136CED59330F42B8705
+:104EB0004C204F053D5CCACEA5EB5B08FEE0836D40
+:104EC0003BF34E52DE3FD4D68BCF4193D4ABBD12D1
+:104ED000CFA1CE03C9F58DB4FC5AF91AC8B78966BB
+:104EE0004994846AD3AFFA964CF5C46072F47D2875
+:104EF000DFBEE17BAC3C3EBA45A2ED9BD33E62ED0A
+:104F00008136D3A9D85EFFEFB541EB57D07F7F261E
+:104F1000F1F91C35EE64F4EB3C12413F12D77FA54A
+:104F20004C3EBAAD7AB49FDC3C1F9554F3FC5488D8
+:104F3000F8D0727B5A31C6EFAD44D91381FA0C0315
+:104F4000B32708E387F6F1CC6F6DE4F4403284BFF9
+:104F50006A2008F2AE3DC781DF0FC9E73D8610F336
+:104F60009BB1F18FBE78059E4B1279B684D833671A
+:104F70005F81F936AAF25A133FA729DB33E1BC7BE4
+:104F8000BB8EDBC1BC7CC4E65F88F304BEA4F6DD47
+:104F9000D11B7E5004FC7476EF0FF341CEDDA8A741
+:104FA000FB8451E45A593A936B833AEB4A897EB7B2
+:104FB000C6E66F013A7CC7326F3A1C319A9B54A9FE
+:104FC0007700BCC1E7B480D7644E278ED90C3E472A
+:104FD000B54F823CD476131B37D92F7BF15C847F8D
+:104FE000B6741B85BB5D62F29B7E94887655A19258
+:104FF0000871C8267EEE55CBE58896CB917F6E1B57
+:10500000C897A9C1784DEF135AB0E77FCBE3E2BF51
+:10501000CD519F9FE87133B8C5739656B902E8CF5A
+:10502000A5AB3A524BE940ABF78470FD326D1837AF
+:105030003E602B770FD0EFA5EC1F95423E777BE6C5
+:105040008F4A21BEA7757ADCBE98728F9BD17F35BF
+:10505000B403BC595A4BC1EFFBB5F59748FB2BFA8B
+:10506000F2FD0DF56360703519A359706EFE59930A
+:105070007F3BACFF85F9C7302EFC40FAD1F721AF5A
+:10508000E3A88ED15D3093E7E393EE690994EE0EC9
+:10509000E739785E0A8BBF1E9EC0FCA8547EB1FC27
+:1050A000D18912E621D6CE66E7626F26918E01FA8B
+:1050B0003D3A5968FDF48A1CB47F6B799EC8F47739
+:1050C0007C09B07ED36F8FCA20F7C7B2E76E74EB4E
+:1050D0009481183EBE4951976F2E5497BFE5519762
+:1050E000BF5DF19709B16593D97B10E8F55589DF6C
+:1050F00047710DB1237FBAA420D85D935F4AE7E7DB
+:1051000089593EE54FF97EF1A50A82F5293B8D5B71
+:105110008D50CFFDEF5A5E3FD94D8CD94EC407EA72
+:10512000E9A8C4F3325D1893227BEFB1333F346DAD
+:10513000ABA7FDEC9DAF201FA75835E49BC0EBA5A6
+:1051400046B4C3045FB49B287D533C968F339A8149
+:10515000DEDB759EF5D097D66C50402F572618B1E0
+:105160006FED3FC8A8D7969B0CC44ECB071F376383
+:10517000B95C263EC823A120CE86E7519D27D40ADC
+:10518000F3A5ED60BEED0E1657D796EB51CFD37E4B
+:10519000715D0F3EA109119C7FA58CF9A61C66C10B
+:1051A0007774247CFF34E76BAD8684518EA5B37B86
+:1051B000390ED1FEA1DF83BFD2F6A0DFAE50B91306
+:1051C000EACF1B27E0B9A8C0D0792F5903C015DA60
+:1051D000B97CE867E7F2043F0BF942A55EBE2B8578
+:1051E000309014F80F053B05EC0482FB0011B7CC9E
+:1051F000348A7AD90BFDA60DB567E7E05278995647
+:1052000085352560A7BCF127A0C3B1E445611A9399
+:1052100013E229E4C516C3C3476AAF196D3D0AEF0F
+:10522000C7F20C9B9DADC7840CE04BAD794206E8FC
+:10523000CD768747F1C5940BE9766AAE13F045DB6E
+:10524000D1F2AD35C7F2E518FD5498C6E4006DE71C
+:105250004DA2F01E342919C0BFA38CDBCCC6B57C8F
+:10526000BDE3BAE9B8B4DD411B1D97B6DB663284F5
+:105270003509A38D5FA1C078971A97A21D913F832E
+:10528000AF03A59320F8C10EDA3448AF3378BEF2ED
+:10529000C164361E2954E7FFE49BE9F8985FA6CE67
+:1052A000F7B951DAD4017AFA6953C256A0CF373828
+:1052B000DD1CB6FC433ED8696FCC2B388472267156
+:1052C000790710D10CD28BF246C8C10B69C7CAA1AD
+:1052D0004CE5E18D6974DE0FE41E9D079D1F723C55
+:1052E0009D8FF6A5D95B935636127E419F026EA024
+:1052F00053E08B213A8D835FD01BB9A51713253757
+:10530000533B179EC2EE25A495E5C52B99C3F3A385
+:10531000443EDDD8CAE6D11844B86F74FC18F3E6F1
+:10532000EE18E7FF1EC035F7CA4FF0BE22E29E3FDF
+:1053300001F67714DE7969C9FF7BF0C6DBF997CAFD
+:105340000F1F8BCFC5F8D2AC9D981F1E986DC57CE2
+:10535000F1693C3F36D0A0C1B800DD0FE23EA28526
+:1053600018432097A772BB5C9C5B784562FED6E031
+:105370008B06457D3F517CDEB88279E9C1652CBF43
+:105380007CC87E6F56D07E1FD273FC9C44773193CD
+:10539000EDDDF728EAFB89E613F5FD440BED2171FD
+:1053A0006F8A94329CBFDFDD4390FEBB6DB9589F7E
+:1053B000AE65FA887C83E9A3EE1CA2BA1F699D3909
+:1053C0003411F394785EC146C83FF86FF20B7E9AB1
+:1053D00026A9FCC243E5AFC92FDCE6F0EF023A5B39
+:1053E00058E4CD92283DD6EB997F98D2EBA6088160
+:1053F00074C5D67CD8A7DD445ADFD2E421BDFE02B5
+:10540000E97532A5D73C15BDEE61FC1544212DE8A8
+:1054100075884E0BE3F300FDFB60DC6E47EFEF5B3E
+:10542000605FD36FF0B03C6896D7192F1F62E059C8
+:105430002033785C5A2DC2F33AF4130FCFE5F04DC8
+:105440002C9DA612C61F63F14FAA4C82B69261FE34
+:105450003199FD6FC1B8437CF408DBCF8E805B6B64
+:10546000457A9A73078B7F052CCC2E8038581A1DED
+:105470007F261F7F4EA7AFDA01ED664A0C0F61FA57
+:105480000F857F16AF9FD9DF8C7970B3AA75C7637C
+:10549000ED20212F45DC6D2E6F7FAB7DA60EF2D265
+:1054A00067D7AAE35D73EF64F1B639B3D5FDCC25B8
+:1054B000AB3FC17C4DD2AA03FCCDBD535DFF49DAA1
+:1054C000509C6C02C4C90E713FD020E513E0A3D7F5
+:1054D00093176FBA87D2F9849F149580DFF0869472
+:1054E000C66D4FD0F2B31B2761F9F594EF7EFF280C
+:1054F000D46F29C072355CE204FB56E043CA67856D
+:10550000E577CCC849007DC2FBBD87E07BB7D9DF1A
+:105510003D93B6734FC9C53CD66AEED7185CC8EA4E
+:105520006FBED2C65295EF52D05F5C6D66F7351DE7
+:10553000297EBB04F2AAAB7379B9E4D549503E2465
+:105540007D82F73A9C6BB6CAB00E2DE9CCCF3EB93E
+:10555000500A4FA478A976F2FE9BD9BC6A4B9E4BA9
+:10556000073EA9AE62FD4CF65476E6413BCD792C60
+:105570009F4B372600FE05BFE5F07D95B02B7D5C87
+:105580004EBCE43DD69144FBF519250F4CD1577123
+:105590008CDD4B6665E7037DDE1C19FCF4D3BC2C67
+:1055A000EFB6CAB83C0DE4E12D7E7D29CCCB6E2C44
+:1055B0003E0479118915956598A76D24B8BE94FEAF
+:1055C000C7A7033F5EFD495602109D554DFF82BEA1
+:1055D000660ABAAF56D337E5DBC9E9659796DF2A85
+:1055E000FA360DD3F758F63E85AB02E1FA865AAF8C
+:1055F0000D8D13C79FF1E38E2537E02F56FE0EC3A6
+:10560000D78B7C9801D98D79C0A75D824F6F023806
+:10561000F49A089E8FCA963C93F0807185C7887A69
+:105620002F8E5F057C99E0332F190917FCC9C26ED4
+:10563000657F2EF0A364F07AFA9D973887E1A2E3A4
+:10564000DF910E7AFC1106CF66A995C919BE2F11FC
+:10565000FE971631DF3EF57CCBCDEC1E0337F8CB41
+:105660003076523C6908EECB5807319F00D7E7B33C
+:105670008D3E9B9ECEED36473DD2CFED54A33A28CA
+:105680005EC274FF0F701ED404F7C17E6F21F162F9
+:10569000FC9CD247203DC66E12F0C6E3A9650CB94A
+:1056A0001A3F9F78FC0CAF5B240D9EE2FCE1D07C9E
+:1056B0002F739EF1F68A4BAFF65B3AB97FD139EC86
+:1056C0004F2C84FA5A62F6A03FD123E17EAF96DADE
+:1056D0001F20A76B6B08FA719C560DFA13851D32BB
+:1056E000169F5CFF4D26B76A9B083FF7C8E6174F29
+:1056F0008FA964E07E78D61A950D0B80FF1BACAAAB
+:105700007306B556168F784EC8113250067A7FA8A8
+:105710003C42EF0F94811C8ABF7FAEF622F37B3BA5
+:105720002F4AF8ACF51C2B03BDEFAC1928037956B2
+:1057300067F7FE14D655DC13198FCFBDE91A919780
+:105740007259741ACF47220E7AC4E67F393DC63F9C
+:1057500075568AA09F75B5CBCEE7E7CF017A76D88C
+:10576000732AC1EF34DBD8AA03BB38D1E13F90CE16
+:10577000E4E8175FC0E6179A523CDE56ED7F5866A4
+:10578000C3221EEEE578B881EBD9F39BB4B80FA91C
+:10579000F6163E0DA1A0C09B3A1242BEF5A27E14A1
+:1057A000F7C69DA7065518DA3F6F437DBBF857F53E
+:1057B00018279BB05E4394187D39316456DD7F32E3
+:1057C00079A75355BEA2375DD5FECABE5C557D7123
+:1057D0007892AAFEAA374B54E5B2C85455FBABDF0A
+:1057E000A95295AF1998A16ABF03F43DC5E3374E9E
+:1057F000CF52BDFF68E3F437213E7D5DF43BAAEF55
+:105800004F703F04097A238574FE0B04BD5EAC53D0
+:105810007D4FCD9AB0540E7CCFFE16AC6679F795CD
+:105820001463B1FD2DEC52DB13379028E62BB684C0
+:10583000244F9840DE9DBABEB1AF07F17AA97B0F25
+:1058400026B8E66BC05497C6513B632220825C0D9C
+:10585000798363F1FBA5D6BF80E47FA9F537B8D57E
+:10586000EB6F52D4EB6F2954AFBFCDA35EFFC40AD8
+:10587000F5FA3BBCEAF54FAA51AF7FB24FBDFEA986
+:1058800073D5EB9FE657AFFFB806F5BA67B6AAD750
+:105890003B7BA97A5D73824B54F5F17420E849C8CB
+:1058A000CFBC95F7AADB53A46862E842D0D9025F67
+:1058B00003E6638DEF7A48355E3C7D4C203C8FF4E7
+:1058C0002BD247E5386E7F72BAA07AA96A5C32DAC9
+:1058D0001937C073EE046EFFFB46B73384FC8AD5DC
+:1058E000EBB1FBE6B1E4DA087DC5F7D163EA2BD86A
+:1058F000479B86F7D163D1EFBB84EA591C7C35FA0C
+:10590000CFEEB033380E9A993DFF29545D43DBD179
+:10591000361514DE77613E74FC77CD93D10FF21DFE
+:10592000D2AB8371EF24117CCE23517CFA895D7553
+:10593000BE6501F1E9B95F6409E0A9C938500E7A82
+:10594000FFC2FCA3EF637CEE48D265DD07721CE268
+:105950003FE30939C5E5C9498803D1F23913F7276F
+:105960007A89E28AC1E729EEF7AC9B26A19E255AE7
+:1059700033E6B1D5DD2EA19EAAFB0FF66C1FC7F44E
+:10598000DA88E75281D72E6E1F303BA10F0EDD6201
+:10599000FC90F8AD688F7AECB0DEB43F1687F9471B
+:1059A000767FB1DBC8E0DC2511B9C289C70671DD9D
+:1059B00061FDE17C9BDBC8E0DBA52346C0EF64E230
+:1059C00047FBF031998A3CD6EF24D6EFD15CF01733
+:1059D0009ACD6F7EAB1AF2A9E5E072F4DF7F8FA853
+:1059E000FDF777B64AE8BFFF1E859B3EDD768F1B2D
+:1059F000F4B228EF02B8211E00EDE8FB5477AB04A7
+:105A0000FEB1AFADBF3D0FB1765FB2BFA17E0883DF
+:105A10000BFE603D857F3683D2B781D2CBB6EF11C6
+:105A2000F41FC6FB6BC769A90681FC311DBB97C07B
+:105A30002DAF67FBE2C31EBBCACF44740E38477A52
+:105A4000297B0EF2BE4FC59CD3A07434EAFDBA1F69
+:105A500065B07CA4F6B6C844884B9EE371D787DB5B
+:105A6000DEC4B256F6605E26DCF7E588F95EEFA28A
+:105A7000F531724EB6D2EF63E48DCEEAC3CB6B1E26
+:105A8000698B60BC53C7EF257B34E35EBB3FC6BF69
+:105A9000F2CE386E271983C49E42B8694FFF4E4F2D
+:105AA00023403F5ABB7C2A761F6D70D3FE62F5EE11
+:105AB000C564121B7F58D9F60EC2FD88E4F7436710
+:105AC000867C1236517C1B6438034DDF6FB811E5BC
+:105AD000AFDE76AF07EEA11A0B7F06B77C21567EAC
+:105AE0007E388EDFCFC5E5E7936DD1C9304E7BDBC5
+:105AF000800A6F5D6D17F1FD9A3652C4EA3FC47A91
+:105B00004D8D82F4738AD24204E27AF2800DFCC198
+:105B1000D43E26107FD6B98D186F30B818BCE4A2D9
+:105B20000BE9639E9DC1003EBF4C4A1FEF2FD5E19C
+:105B3000FEFABE4C2BB6BFEF37E30F7829DFEA2918
+:105B40001AB47FC37C86C761F8D373F94964BF0F69
+:105B5000E4803E5DC63885D33E0BD7F1CBF627F007
+:105B6000AE3711CC47D6675AD15EB85C38DD196ABA
+:105B7000BCC7E38FE209E5FF7D1C4FF73DC8FC93EE
+:105B8000F7DD4FF03C05594AFFCA87E96A1C978741
+:105B9000A9C487CFAE362A080DB05E46E29F40ED1D
+:105BA00011D28B8D4DE0A7827AAFEC80D48827AAE2
+:105BB0005D33E1B9A6E26417B0E3DA6B3F8BC01343
+:105BC0006211802F7B0309C155BC98AB40C777F8A1
+:105BD000593981D727CC65E5445E9FE863E54CEFF2
+:105BE0000B523500161747CBB43A6FCA0779BC8001
+:105BF000B073F1FC7E8DCD84CB0BAB736635D4DFF7
+:105C000049F09C8BA8FF09AF4FB31E5F99077A63D9
+:105C1000B6FAFB0D1C0FA9D6E35DD330DEA6AE1796
+:105C2000F1AC64EBF937F1FB2275FD53FC7B9BF57E
+:105C30007C641AD4E7ABC77F9CD75BAC2CEF8DCAD2
+:105C40007E767F03AF7F8CD79BA01EC62F64F55A4C
+:105C500071DF096FD7C9E118E2331E430C2633BF49
+:105C6000F2963623F2573CBFDD07F773950DF39B91
+:105C70007D2919F5DE86FB3298DC495006BCDE51E1
+:105C8000E4A2A877DA65CC37D0BAF5484F062B974F
+:105C9000279C1F87E489D4EA6144C6E4F4A5E89A06
+:105CA00012F005906B59F40FE83AE3FB1AE28F917A
+:105CB00073E94D66E28FE583054E5539E5CE74559F
+:105CC0007BD7EC5C55BDB57492AA9ECC76229FDC46
+:105CD000CBE9CB5C54A2AA17F765906DBC9D9DB52E
+:105CE000D3E54F55B53B5FA824028D9FBA49DCA38D
+:105CF000E631827CB8D7969B0AFCF8B3B60A444ECC
+:105D00003BE527F6B4F3A71B8C59FA5478B910CBAE
+:105D1000CF3B587E7F7B9B879573089EAF6F6FABA1
+:105D2000C1F22ECA9FF0FC699B179FDB6959A1CF76
+:105D30007FA4FD2BB49F1EDA3F949FA1FDC3733354
+:105D4000ED1F9E3FA1FD43FD06DA2F949FA670C173
+:105D5000F329DA0FBCFF31ED1FCA4FB4F9B0BCB65E
+:105D60006D2E961F6FF3E3F3B1B6067CDFD9D68AAA
+:105D7000E547DB96E2F3E1B6203EDBDB56627D2FA2
+:105D8000A793E7F979DCE72BD9BD03F1EBDF9F217E
+:105D900061BB2F9D9F534A157AB92A3FA73F03FC49
+:105DA00002BDEAFC54C01FC26162788C87E36806BA
+:105DB000B30F2791C8720B931F18071FDFE75961B4
+:105DC000A1FC35AE95AD7B4E5F14EBD31AD8784766
+:105DD000B99D405C419251CE8E9B43BB7352A4CA85
+:105DE000C2F207D00F43DC143FE5EC5A7246E621BD
+:105DF0000DC02557503D1E33AF217C39189C80B70C
+:105E0000D1E0FD578E376D692FBB5FA7A62B0C6CB9
+:105E100066F6B6E2FD3AC6B9BEB04C9F2E9F1FEFA4
+:105E2000E99874713ADD2452F976F19B44A1CF8C44
+:105E300026F5FE317D41896A7FA6BDB8862857D1F7
+:105E40007E8BD4FB3C73FEBDAAEF8C190FA9EAF53B
+:105E5000AE15AAFABABB731E71033EC7B1B89961F9
+:105E6000F5720221E485DD4F205CE64C368F73929B
+:105E7000C27E5F6037FF3D13BE7F79D6CEF1655C91
+:105E80008DFBF2090E562C480C6A400F7DFC8B44AA
+:105E9000947F3B9ED1A09F7E22096940DE4CA6E6FE
+:105EA00024D45F01378C6BF1AA262D948B89A285AF
+:105EB000F255248AFB3ABA7FD164D2F56BD1FA9FAE
+:105EC00031D1F2D94CFFB32CBF308CFABA80AF6716
+:105ED00081D8C7AD97E3FDDCC64CF437A9CF257652
+:105EE000F0FD4B8789F90D973BCA53C10E3E3746EB
+:105EF0003EA8CD7DE28D0514DFB6B463F814EF1F24
+:105F00005734A39ED7CFCB94BE5A5EF77AAA4FD40C
+:105F10007C9307F3385BFACF29E0766BC98F22FFB9
+:105F200074E8843C5312419E0D973D8924661E3BC4
+:105F3000DADEC9935121FA116F325F37315FF94FC1
+:105F40009576C84B2CE079D13BDBD2F2ABC70F7F03
+:105F5000EFE37450482235A05F0B8B349E1074E041
+:105F6000B5ABFC31A6FC2E2F9C0B934B8807C4F2DB
+:105F700044D285F729C87FD5623E9A7CF01AA25098
+:105F8000FBD86A0D9360D170BF84FB75BECFE5FC72
+:105F900067F66A9C8F9C25EC260FE874F299D51B56
+:105FA000013AFCAC5BC7D8F4B8BABED04A50EF2D6A
+:105FB0002AD4871409EECBEBC27B40E52D12C9C869
+:105FC0000138A6B9E7837EDF6B413AB6AC2FC79F95
+:105FD00030B859E3AF40FC0E287B35C2E8A2ED9AF9
+:105FE00027EBB7823D3901F06205BCDC915F0D43C0
+:105FF000E717221E17F2792FE4F3E8C81CC23F838B
+:106000008778BC701FEFA26EE18F52CFF3F1D2AA56
+:106010006FC3BDA2ED112DFF9922353E57E92253E2
+:10602000E64BC37051381766825C01B8AF820FD857
+:10603000FC9A9F91C8C61C946B35686F9469303F79
+:106040003D9E2E9B3299DC8F66D8D97DE4EE534875
+:10605000CFC3E5936F2C48C2FD33B35B6C32CB8F5B
+:10606000F47A9558BFF72AE15FE4E772CC1CDEA111
+:106070007B0527B1BC602B89AC87BCB4B1F6F52B8E
+:10608000327370DCE17D3DB55D203FA5CC88795C45
+:10609000AB443EA172549969634F385765E474FA72
+:1060A000A84D9DF7B39DCF6F3B5F8F41A3C87BF297
+:1060B000D616C79CF3A9EBAF473F9688D30E72FF65
+:1060C000E1A0591D576DE4A43078A8ABCA0CF1C10A
+:1060D0002E16A76DECBF99DD6BBBEFC7782F30EDA7
+:1060E00053017AA8E7EDEB57AAFD580B77FA915FB9
+:1060F000E3FD64F17E318A393DEC1FE3FD625B33E1
+:10610000F97EC2438A210E7B6275DE6133EC7772C1
+:10611000089E0F1FA77D01EFDDA6BB812EB84F970C
+:1061200014B1FBA3E2D7FF54961EF1B253ACEF7843
+:106130002BDAA53BCB981CD879E0FC2DE3693F2BEB
+:106140007324D5F98095393A5CA7B7297DC3B397F5
+:10615000909AD1EE293B94A9F96A72EF5AF5EFC1F2
+:1061600034F70D1CB62828FF5E03BA1F3CFC7942A9
+:1061700011F251147FBFC408C23099C10DE7B37644
+:106180006B3E99174B0F6F67CA58FF36A78B2F0DC1
+:1061900057B51AAEB3456FA5CC6070FD0EE4C6B915
+:1061A000F0F194587B46C0B57B8CDF03F8F0ABE28E
+:1061B000A942AD1F62F074FABFC3D36EFDE8F0FCD4
+:1061C00095C3F3B343EC5E9B91F55F519F75ABE1D3
+:1061D0003DFB7C640E88490AEF5F117FEE9329181E
+:1061E00013E6F8EB2DE5F459CAE58F07CF5091C0BF
+:1061F0007B57631E66AF4C926AA15CBE007FF72C92
+:1062000093EFC3021A3F9EBF21EF1946957FD764D3
+:1062100031BADE9D2E8D8A87D22C36CF0347EAB263
+:10622000C1BFF1D83B0602726133CFBF7ECCDE6BBB
+:10623000847BA6051EA15C429F017D741128BCC70A
+:106240004A3F332AD651C6D3B0F1D6C6F18D184F86
+:106250003CA76415327B553AA48573386BAF7D0B30
+:10626000EF7F5B5B2AA3ECFDD2F85F1D87FFF05B3D
+:1062700029B7307A999245E16B91FE90F06D5A0EF4
+:1062800048D17F2A827C15BD1FE71FA078EC91467C
+:10629000E2292D8BD18B989F98BF80DB76DD025C45
+:1062A00007DBBB06541AA5BCBDD017895CFFC1BC77
+:1062B000505F5C2BB3734C6532AEFBDA8AA978EE83
+:1062C0006C37CF17895EA31FF577441670BC3D76F7
+:1062D000F1B711B84739D8AFC3FB3F883CE0BE15D2
+:1062E000EE1FFF8D8CF789537AAA81FBCC0E1C39E7
+:1062F0009F00FBEBF9593A847B3E97878317B535AE
+:10630000781EECC867766D0CFDD76569B97D12897A
+:10631000C039AF3525EC3C8B95DB03D623271B001A
+:106320007E6BC543062986DE66651910AE35FA68B0
+:106330008A87F617D8A72561E6FFC17B1987CEB3F8
+:10634000DA191E5A4A0FA1BD60ED67F735D66529E7
+:106350004CCE52B8F7D2F7E6899FD9EBA1BE948E06
+:10636000973BFCBDCDCED6D35CC6EE4B5A7BED3F02
+:10637000DBE13EC844F81D47D8EFF2790AB89272C3
+:1063800035BCDF482417F8CB2E63BE5A6FF85E2366
+:10639000D8FB822FDECAD562BB47F93989472B0A61
+:1063A0004370AE4CD0B135DBFF4016CC8FF2C50B3D
+:1063B00068EF447CD3103FF662C833DF2545E632F0
+:1063C0003B446F073E2CD46854FC16E1EB269E54E8
+:1063D000FDA3DD733FA75DA1F73B424602E74DFEFB
+:1063E00078716622D8A71D19C2DEF31A015F9B25BA
+:1063F0005F620E8CF32F5ADC0F1E3872BC01C6EDA3
+:10640000A0F302BE7DF875EB6AB0533AEC5EE4533C
+:1064100031BEECD0F0F560FDECD67BDF047F64D4B8
+:10642000C1EECD3A38758611E89FB6D3403F7FA0C4
+:10643000FBF7F004E8A71AFD060BEDB3A6C3778BB4
+:1064400088FF11B06F17756B55F7833CCCE5C5C25B
+:106450008B16128ED92F2CACF80E9E6B5C78310106
+:10646000DF3FCCCFED3FCCCFBDEDE2F878993F5F79
+:10647000CFFA8AFB6F4F9CDE4AFEDD8E3AC6F7BB31
+:1064800060FD9AA5013DA8FA35533FC7F3647F68C4
+:10649000B393B02106DE11F34C22E1987187DA5DE7
+:1064A00034917052ECFA32FA1D9EAF15EBFFD0E634
+:1064B000463C8EDDFF38151E87FBCF53E17164FF2C
+:1064C0000558FF87B6C24BF43F798CFE7354F00F2A
+:1064D000F79B8FEFCF1DAC7BD642F9EE6078C5C637
+:1064E000574BE1F7F70CF87B1BA4AFB70ACFB9EE17
+:1064F00022780EFA81FD7F7A1FF2521FD8AAF7C0C8
+:106500001883BAE83CCF287A269FD88370EF9C780E
+:10651000BE9D9587EB1CFFDE2887EC90676A2C9464
+:10652000EDA0E78C24125A01FB975223CA3911DFE0
+:1065300012FDFE3453AB92B3E27EA1469E7FD86833
+:1065400061F1AF26ABFF2CACFF124D57CBCF681FCC
+:10655000A70B3BF07C3B210EDCD788F88E0CFBC5EB
+:106560003C707DF9089C0B9B97E3FF0CBEFB091563
+:106570002B10EFD15EB1CD0FF9798FF37DE4E3A657
+:1065800088DB13233F75D9F257B31BBAE2E8B7ECA7
+:10659000773BC28C7E75D940BFDAC8CFEB72E07C06
+:1065A000E300BF674E41FBB9AEF430DE475927FC2C
+:1065B000022BE3F356321D604F8B785402E41782AE
+:1065C000DDB086DD53586F61E5FA5F27E1B917BA90
+:1065D0001FB214819CD9AD65FE221E073BCF611E00
+:1065E00034AEC902FC0EF27C97F3FDAFE1BDA7E724
+:1065F000578E473AA8FFE50FF11EC3DDE94C9F0D0A
+:10660000EEB3A13EAB3778CAE15ECDDDE9CC6EEDED
+:1066100095C309253176ECA3195528A73F5E395E4D
+:10662000131B27199FCDE4C21AE1FF94A3E570CE96
+:10663000EAE3D2F03FA13EDD63C2DF1BD3ECFD53A2
+:1066400039DEBFBAC680BF6351B577E2BAB9B05F71
+:106650004C90311F5BB3D784F09C5DC5EE83836F94
+:1066600041EE35EF1D87BFCB566F8962DE64B3D92B
+:106670005300F1C1FABDDFC0DF9F38F1F8C42C90A0
+:1066800083C793952CBC6FFB718A743AEFE3FB26AA
+:10669000B0F79D57E3B96ADB1A8B7F34FF88D04B84
+:1066A000F1F7CDED4E2F3ED707F89968F4801C5EC8
+:1066B00038E45F67F707D6BF199DA524A0FF06F34E
+:1066C00017EAEDA7F0F71DEBBB8FDD49303EE9423D
+:1066D000FA15FBBCF871EBB9FEDAAD8FCE83DFD5CE
+:1066E000AB6FE7F8E7BFF759AF29C6DF9B14F85F38
+:1066F00013771FF3F738DEC5F3C41119EFB9A47689
+:106700004516F88F4EEC3720BD9D583319EF5710C2
+:10671000E3D55358ED944F8F3B9529B0BE0BB2157E
+:1067200036FF76B67F15EFE9F811F8BDCEE83E2DBD
+:10673000E6AF0DDAA30910C714ED4479683EFD5A9F
+:10674000FCBDB7DDE90770DD295D11A02BCD2F6DF4
+:10675000A8B703BF64BF1BF7712909829F34F88E65
+:1067600001F77B07F719D09E1E7C979DCF1F71EF15
+:106770009F359A05F7DC067E390EE5DA6066740B04
+:10678000B3BF4D78CFE4E051FFD53C5E9CC6EFD15E
+:106790004C03BBEFC23E5318EC3EFAC4B843906CB6
+:1067A00073E3FBFD16BC2F883ED9F924698F1B7F4C
+:1067B000378974F1EF23F8FD0359FE0920A71FC89C
+:1067C000A3FD5BE1FB93D8EE42AEFF4A8C591192D8
+:1067D000CEC74BC77E33FDD9F85EFACCCD7E0FA86D
+:1067E0008BD747B03E60F05F8DF3F8BD8DF48C32EF
+:1067F000CFAF7A5FE47DD949B88E026E8A67B42341
+:10680000E3F1D293CDF69F021FF17439B49E9780C5
+:106810000FFC3278BFC03EB68EAB26EA993CE99CAD
+:106820008CF632DE30149327B87CDF074897833A22
+:10683000EFD3A097A2477584DDC3482D03F05754CA
+:10684000B076F516E6F710709CE1E7071A3B591E83
+:10685000E199E73EC89A6F85F3F31FA8CECF0BFFEF
+:1068600021ED2401FC33568F925057C4EC762DC293
+:10687000C57E8F6E8D4EC1DF0B0C3E3E11FD122783
+:10688000F4CA5EBC0776D5151AA0276D3197BF4FA5
+:10689000B07989FBDDC43D6DF17819C866FAB2990B
+:1068A000F8EF823BFE8F132585074BF1BE4A74FF3C
+:1068B0006B20CD52F69A587E3BEA8591F742EA2F3B
+:1068C000F17B82FFBBE553B05665809F6002E8D53F
+:1068D000D376B67FC45B2240BF6BD93C3BE003B8A4
+:1068E000FF82F84E835EC45B25281E4E4BAC3E9E55
+:1068F000CE84BC1B810FA01BE817BEA37D7F9E9D8D
+:10690000C3F63F76273F9417D4435EAAD057014978
+:10691000D6C07D0F271D4A02D0E5C9CE3CE772C81C
+:10692000F7712829B1F676E010C17B0E1438FF7399
+:1069300035FC2E92770AF805773BD5FE8878785E8D
+:10694000A81C40FDF35F98C6C553008000000000FE
+:106950001F8B08000000000000FFB57D0B7854D5A8
+:10696000B5FF3E73662633794E1E8484409824E436
+:10697000018430090F4141074810156878092885BE
+:10698000930710421E88B6175BDB0C24205AB441D3
+:1069900051D18B76404154B4414141037700A55811
+:1069A0005163D5566DCB0D88BC1F31A897FFADAD97
+:1069B000FFF55BFB9C64CE90A8B5B7F93ED8D967CC
+:1069C000BFD75A7BEDF5DA3BDF7C433FD7096175D2
+:1069D0002B42F41022CE6D11629810A3DC82F34298
+:1069E000D885C811FCF38DCA89DB3A5C8885F88D9F
+:1069F000AAAAF9DAB59EC82BEB2D5C1FE375467782
+:106A0000F1BDF1B5FF50F228B3214C0887FE3D5D82
+:106A1000880F311E8D7BEA90DDA70C461A2EAC093B
+:106A20004254AC75FA451AA56F4ECCBA53E685426E
+:106A300075C76C5C99D84AE3966F2ACA1291B21F47
+:106A400041F3AAD0E7559EEACD52870AD1F6A8EACB
+:106A5000DA84F6EB559E8F6AF3B81EA5EF27D6DBD6
+:106A60005CCBA99F0A7D3E277A6BD1C5B994B70A42
+:106A7000ABBD80F2562DDA45FD2E78542DF677B158
+:106A80003EAAF781B5A00BF8604D893A7C32A81E6A
+:106A9000D66994E3BFF7687257D1FCC2E977CC633B
+:106AA000A3E2F7D1FC4EF4D1E6217FFC9330B18212
+:106AB000F2EADA45D1EEDC2BE17DC2A1457B720121
+:106AC0005FB91E039EA1E318F0BC0878C620BDBACA
+:106AD000C54BF0AB7D48F5A0CEBEE64BD180DF982C
+:106AE0003D4547AEC1F7B561228CDAEC3B9CFECE4A
+:106AF000AD348F8BAB55413D8AD23D198982C6DBBF
+:106B00006EF97C2EE073BF4DCC7A91D2D2B7A747F5
+:106B10005B28FD46A71FF5210927356A7AF47CAE6C
+:106B2000DF3EB998F2C7DC9EC482A07A3FD6E92C3A
+:106B3000145F656BFF168D712AD6D8785D065E2EC0
+:106B4000621D34BF8B8D11FEE504978BBDDBB85FF2
+:106B5000034F46BF15C083414F546FA5DBA58FE39C
+:106B6000B31747115CD3B4E19E2EE864C183342E81
+:106B7000FA5B1FE575E67DFF710D7874E09B962545
+:106B80000CFC038F4FA46DBC97BE59DEB30AD193A2
+:106B9000E0D0787DAA42DFCBF6840985FA2B53DA60
+:106BA0008E28099C77FB14AC7FF13C8C57F67198CA
+:106BB00005E5C7F75E9FC7F30AC12BC129B52B7A3C
+:106BC000BF98D696EA0982DFC53E6D7379BE067D11
+:106BD00074CE9BE751BB374C605F5C4C237C4676A0
+:106BE000C2B101F819C6F55D76A66F6F1EE0D7B188
+:106BF0005E57C87A5D21EBFD40307D0B8FC6EB29D7
+:106C0000FF24CC82EFE50FDC94E5A6718EDF3B8E8E
+:106C1000D7753CCE9B87FD753C95FACFBD729DE53F
+:106C20000FD03A73BF659D8D4EC657B7EB8C6B7B0B
+:106C3000427CCB3A37EA7468ACF333AB3BDA8AFA7E
+:106C4000BB55B19C8A6AFB14DF7F8DCCBB56D0D07C
+:106C5000B536490FB56B23FCC0D78566DB047F6E64
+:106C6000271FA0F1BE273D58981E8E8F753F3C020E
+:106C7000F4759FEAF2B9019721EFFC9CF2C7EF5738
+:106C80005D02F9B1127EC40F2CE00FC7538B27733E
+:106C90007EAFCDB582FAF9B4F16F7F04FD5CDC63A1
+:106CA000730B5E5FF1FDB390A7F982AF115C6EC606
+:106CB000B854CEEB57EF19D68872F1E86057A6BBEF
+:106CC0000BBE1402E78A35AA691FD201C1E3D53E83
+:106CD00090E2C63A0C381387CD9A3AA8131EC84FD3
+:106CE0001FD409975ABBD09AF8FB12FB944141FC80
+:106CF0000CF04997E744FF3CC9C7D2A283F673C89A
+:106D0000FC42F98F51CF48FFD2C157CCFC7851706B
+:106D10009EE05019925F1CC237AA42CAAB43CAB761
+:106D2000F7FA9CF940E8F813D3E4BE31E058AAC35F
+:106D300071BB45917CE43EC5BF897E2DB5BAED4B54
+:106D400069FE2F8E11F3D04F995538AEE57DD9CE1F
+:106D5000EB2BB58A86B0027CF7703D63DDD45F43D0
+:106D6000581CE5C3251FA27A13EC417983DF1AF37F
+:106D7000094F93F030D2C55B9D8DC783E059DD1478
+:106D80006BCAD7EE4A6E3CEEE8CC2FC62FC9F46F23
+:106D900022AD7E38E0227FAA77B51E8C20FA49B258
+:106DA00068E169D4EFC583FF1B9DEB66BC0F2F26FE
+:106DB000FC16A8E92F1DA6F5B6ED563D9BD0EF9B1E
+:106DC000F2FC115F5F7A781B7DAFD99B21EE75775E
+:106DD000AE3F148E17775D8A4EA7EF170ED9C30505
+:106DE000C901A5CDF163EDD1BCBFBA84BB5B87BB44
+:106DF000D1DF056B6BF494A07A17446BF4D4207A3E
+:106E000029DD75A94EE431FC7C6A101FFF744F8F99
+:106E1000B12A7D2FFB7DAFB1164AC7E9FDDE6F7346
+:106E20003FB986E6EDDB1DE6D94CF3BEF0E62C0B50
+:106E3000DA5F78B3424F7FEAE5F4B34F53317EB463
+:106E400045D2BB31DE8834294F95598E3E311AFC2C
+:106E5000FFD59E69F5699DE56596822CE0799BAD2D
+:106E60006D2EE67D4111AB95B8CE7EC6A5B9B9FDB4
+:106E700085DD279F007FF8F4FE3E05602B177667BF
+:106E8000E769547EE1E321592EEAF7C27DC91EF07D
+:106E9000856D36F74F99DEEE89F260DF1BFD619C50
+:106EA00025E87FF755C335A41FCBF9523E4F93E336
+:106EB000FA9482CE7EA32DEE5F8F02BFF8BDCDB3D4
+:106EC0009992A57FCFE8198BF5613F778187B2D57D
+:106ED00061C26DE2272B78DEA5C263871C84721124
+:106EE000445FE5A298BFCF6F347F5F407C02DF171D
+:106EF000AE377FAF108DAB5A697D8BFCE6EF82F623
+:106F00008F2F11FBDAF869E2F37EF1D66FC24CF5F0
+:106F1000844FE70F0EE6C7A5B41FC1C79E57FCFEFE
+:106F200015C0EF3D2AAF33745DCBD3D2781D8F44AB
+:106F3000FC636E6B105E8F59843589E07ACC2E1C11
+:106F40004905E847089CABBE3D61FECDD4E4DEFEBA
+:106F50005FA59632DF4BB2E03CB8C305CE47FDEDEE
+:106F600039998A7ECA5617795B83E677D1E67DE444
+:106F7000E79057DF237E4DF58E8DF5378EA5791D71
+:106F8000BB57F5D47731AF33249FF9E3091EF728B7
+:106F9000C23F84F2CF9C4C2D21BC9CDE7C32B534A8
+:106FA00098FE15312B981E8D9466C2EB82AC89F445
+:106FB00018AD05EB09ADD7895FF37C0D783A55B173
+:106FC000A42B7A7814744FE5397F5705E4CE9A3DA7
+:106FD000363FE83362E3170FDF0AFA6CB6B940DADE
+:106FE000B57B542FE474B15BF567E21C6BFE34BAD9
+:106FF00012E7CCEE212E3568DD740E17E37CB9B0B4
+:10700000EB5262592EF73319F244ED9E873CA0DF14
+:10701000EEE6F15C9AFAAFF13FAF99FF9DCFFD200C
+:10702000F146F0818D27B2C0DF890F3E9786FD992A
+:10703000F5B51D79215A8783FE687E2CBF5FF47FEA
+:10704000C5F2A5A359F5FABBC0C39E343BC3FF07E5
+:10705000CF6F02CD2FB1737E349F3DE0CBC63C6B2A
+:10706000DC6D769CB3171DD179E0A7B4A089F989AE
+:10707000FAF9E4067F2D9B2888BF16EE9EBFC20951
+:1070800079A151F1400F286F56F9DC2ADFA0FADD13
+:107090008497C2ECBBF63B219F3E44E5D474BC3AD6
+:1070A000EA8FB3A8FEC2FB54CEEFDBF8D33FDA8001
+:1070B000D70D3611063C86476FD2C7637968913E7B
+:1070C000BF45CD379D56A0B7EC513D01B4DF1CE55F
+:1070D000C1F7B2D5B663C1F4351FBF507FF3D72BCC
+:1070E000FE401AF884B9FCC2309FCE2742BE6F5CC6
+:1070F00035757F02522BEB898BFCE672FCBC4EF39C
+:10710000A9D57FDF9AB9A617F073C129440BF6AB56
+:10711000B595F51D11684D051E2FECFE2C1578ACAC
+:107120007DF57FB24417F8EBD84FCD510927228463
+:10713000384BE7C63716D0FDA5C9C55DD47FB18FE2
+:10714000DC175B6DBE5E9063F76FFC8AF9C1C5DD2D
+:107150005A5F5717F4DBB95F7D4E4B12D280532034
+:107160001DDAE4BA11FB84E4C17B411F9B564DDD5F
+:107170004479E76B364842A2363392F70BF6C7FCE8
+:10718000A07E8D7DB2157C01E930C91F5EEC23E540
+:1071900084D5BABCB0755FFBE4CC2EE6B33ACD26FD
+:1071A000CFDB3E926FCC4D2B0E4F879C61F1450398
+:1071B0001FC2EB7527107C159DBEEA972D51F03D3F
+:1071C000493472DA5B3471FAB8105A24EA0B8F0B27
+:1071D0007016A24F2CE0C77B9ED7AB31DFFC898EA7
+:1071E0003BF06AD0832F56F837D3EFEA46875063D7
+:1071F00020EDB546A351D4A0A9BFEE4BE5B60F5480
+:10720000D69FD43E063E3D2EE0F7CBC8E931C1F80B
+:10721000DB77B87402FAABDE497A2EF5777E874DBC
+:1072200004A0575969BF503DDBE12FEC69E04BCD1D
+:107230008A80BC5C4B797CAF1D65F5FA83E0929740
+:107240002EE1919A9EC570BB60F51E9A08FA73955F
+:10725000DA21D7DB0E974FC079634B2AB5635EFB0B
+:107260000E8F75A4016FB156DE37AB9A8D715B5CE2
+:10727000E83F2AF6039E6F43AE454453BB868FC258
+:10728000FC0C4C87E443613A5C1B02850E7717F8CF
+:10729000F189C2143182CA77A81330CFF3AE5217E6
+:1072A000F0688B957687309B7702F49AB0D8B878DF
+:1072B000CC6F447A06CFFFABD8253CCFAF48BC801B
+:1072C000BE41F27A31F20DBDCB55867DE323BC8FF2
+:1072D0006B1D72FCA83D2A9FA362A443E7DBEFBBB2
+:1072E000CA689CC8BEDA24D083319FA861AF0BF076
+:1072F000E71C8B85E5B3863722D7802F18E51BD294
+:1073000025BD19F858996075817F3CAED3E74A577F
+:10731000B1A320689DB61E161D5EC50EC069BBBD1B
+:10732000F810CE9736FA8E73737FD25407F414AAEE
+:1073300067413F27EA68C764A3DFE90EC07741428F
+:10734000E978B45B2896ACC27E5BB85E1581203EBE
+:10735000DB6093E32EB81C2102433AC75D40F8E39B
+:10736000F697A3F97B8353D66B8892FBE7CE7429FB
+:107370002FAED4D3B57AFA83F9BAC7CCD7CFC7FE2C
+:10738000714BA9E4EF77A653BFD54AEB788826ABBB
+:1073900092DAED80EF893A97088405CDF78A75C6B1
+:1073A0008B40D0381DF52E3B45203E181F6EC6473A
+:1073B000E77A23B9FC445D12C3B1FBFE534C70EC79
+:1073C000EC3FC304C72BFBCFE2F2137539DFD1FFCB
+:1073D000C06EFA4F33CDBFB3DF7EFC5DECD2FA82D4
+:1073E000BFDCED227EC074D3CA7626BBA2FD067632
+:1073F0002FF1719880DCF79553CB7605F1876DE915
+:10740000765D9F0BA480DFFAC43A4E6B775D1A8FCE
+:10741000F66EE20B6CE7D0CB6B451BCF13FC02FA88
+:10742000BD48B6BAB97C97960DBDC89847873CF35E
+:10743000BB489F85F641D89EBF47631F5FB4B64DDA
+:10744000867DAAA9598D08DED707F4FD31B6CF177E
+:1074500079B0D7D5A01DF1BD9FEE5D9C0DF8D48409
+:10746000B5E561DEFBF7FE2D0FE7C8577B16F7C5C4
+:10747000F7AD549FE50F7B5B8D27A8BF7EC2E5B3B8
+:107480008CE84C9BF5FD1FFA7DEB9EFA5E98C736A3
+:10749000D83D482EAC59F656C6F178B021EF83E0BE
+:1074A0005F82F816EB43BBA6A96320DF7D48320F4D
+:1074B000E587EE9672C3D03EC26F4983DCF7E12CBC
+:1074C000F0899A61761754E1F0FC1696B7C38739B4
+:1074D0005C389F9FED93C1EBB3434EC840FBA2784D
+:1074E000A6E754F1AFC96D1B42F64FE00F35DB68DC
+:1074F000BC6AB575F23885F7D131F0A99AB7BF7873
+:1075000047D75F13819F5A8C4BF0785FEF27214359
+:107510003B897A9AA3F5BEABA8DE8C9B9353A11F3F
+:1075200095E8FA9998484019C9FC6810EC20579ED4
+:10753000DB520F7A4DD134C0C197ECF0E0FC1A98C1
+:10754000221CC971D8D0FEF4A934EE57E916C32E17
+:10755000AA60DE03F4353DDFAB69692C9F93FE38EA
+:10756000D0D13F3BAE25C3FB77F00BA3FE8737DFBF
+:107570003A48EBE2DC30E479BBBDE936CCB3AD3A56
+:1075800092F54798F3D0EEC99BC3022AEC8AB6C89D
+:10759000D5D0E73F8A987BB007C1E3FE282D228330
+:1075A000DACD9A79C32AE495FDF1EEA5A0E792D64B
+:1075B000E1C0E7D34E2D2683C6AF72687D1369897B
+:1075C000E7FB68D93138E48BE3259E44F1A0E22E35
+:1075D000E72FE753A2C8F10F476949E8A7C4D2F2E1
+:1075E000C455F8666D617B8368E8C1FD9CB78B8AE2
+:1075F000AEE47F030E47F475ECB3896B2FD3FAF634
+:10760000AD8DF1D4D37CCBEF9E39B796D2F996E20B
+:10761000C4806A9A7716D655E52BE99B4CF2F3792C
+:107620009B3EEF65FABCADAEACE0FD1C3AEF7A4391
+:107630005EF985C2FA20FF50FE155FACFF5ECA8777
+:10764000592E7D300DE7D6200BDB493684D3DE2260
+:107650003DF25D7D9E8FD3BE73C4F1F7D5F89E14C5
+:107660002EDB273D6CF1C37E503C7637E3E9C99AA7
+:10767000488F4A639508B71D725099F0B25CFCD9E7
+:1076800098BFED69A575156668D7016EF3E22DA95F
+:107690001FF03CB48153206F8D92EBF8167993D78D
+:1076A0003155B86C2C94893516C81F535D7229F377
+:1076B00015B93FA609AF0DE3CD101AD7FBC305BB23
+:1076C00017FAC41FA00BD1BC670A1F7F9F2DFC9C1B
+:1076D000DE2A025CFFC7A295F306BC893EE6254878
+:1076E000FA38D95365F8DF8C79BF1791D76719AD90
+:1076F00063CA23D999AC5FADEBC1F0F9AE794FD134
+:10770000E986F6EF3CF483FD3B9DFA997A63C8FE67
+:107710002DEC61E033F3DBF6514B7B87FE14994C83
+:1077200070B85E47E9F5DEC5AC3F15A991C247F8D0
+:107730006919A5FA21771CF22E4F48A075DCFDB916
+:10774000D4837EB75CBC3D84CA7F374615F5DCD256
+:10775000CBF2D464BD9FC9BDC79F869DF5B00824F8
+:107760000CA5B9175DD65E8FA1F94E56B735C45238
+:10777000F984DEA4C704F1BD1B12B65BA1D7DDD826
+:10778000CFFC7D62AE59DF99241A55C079F250734F
+:10779000BD7D800FD1D78A0CA9B788016280EEDF4A
+:1077A00063B9FB477A1FED132FD9E10B793543BB42
+:1077B00007705C3AE9B3B9185758E57A6ADE51D9CF
+:1077C0009E778CE42C2F9DDFC7EBE8840893F208AA
+:1077D000F2A7486E407AA6CECDE9393AE7517EA1AC
+:1077E000CE23EB67143F807D56BAFA732BF072B745
+:1077F00053C2F96E67AA1F76B58AA6C6F1985EE5F0
+:10780000AEA68348CB03C5E371CC2E38B4E420D2B6
+:10781000BB3BF4B6250EDD5FC0F3BF5DA7D3DBA392
+:10782000A6DE3488F6C9EDBBA5DFEBF63E53A74DC7
+:107830004A40DEC6F9EEE8A8FAB22234DA22CFA82E
+:10784000DECD58B7B7F9E8C1785AE7C9BA113CFF9D
+:10785000D3755E9EFFD9BA099CFE3DA3F839AE27C9
+:107860003E67796CD2B6A3D614AA5FE455BCD8B7EC
+:10787000D77A85DF4F74B1DE26CF81F5740E601F95
+:107880008F1934F5F13B30E90C6D27DACFB871511F
+:1078900011C6993CA2C48A7A33BF16223EAD934EDC
+:1078A000BF8BEE8DF557EBF83BBF5761789EDF1B22
+:1078B000CBF06CDF911103F960E9CE8C9E48896FA3
+:1078C0001A7A6F04E0D77ED9C2F36DFF289CF58E3B
+:1078D000D0F64B770EEC897A6709DF2248DE3CFB55
+:1078E000FC7FB883CF95B3714D5F7D02FEF657C91B
+:1078F000DF48B239F118F85FEF5E1ED0CB055DCEE0
+:10790000263D2302E75F8D6E57047F42FE6CB8B4BC
+:10791000E70E7F21652CF617C673139CC31C19B99B
+:10792000C787707F477E46FDBDFC589207FAEFB9C6
+:10793000ED8FA463FCAD4DF33F798CFA3FEFB7F8C0
+:107940006C744E9D174D175E051F7E2A92ED7B7756
+:107950002B342F9CC39B7B713E47B1862FC3392CA0
+:10796000FCBCCF7314B77519F1ADAA171FED057ADA
+:107970007C8D603082CA5F5B1BC17CED359BE7C8A4
+:1079800032F4F7B8ECEFE9FBEF3CB60BE97DD50537
+:107990007752FA65461CE3A1FC814503D09ECE795F
+:1079A000914CFD3DF78A1280BF6AD0BA7D2B926957
+:1079B0007E83371CB5F4A234FF29A51EE9C03E37EB
+:1079C0001E82FDF96F196E6E3F645B9A9A826DD9C3
+:1079D000CBFFC9757CFE9BE582DC759F8FED253A58
+:1079E000E583014AD3998D34D7B0D48F0A348663A6
+:1079F00023AF6767F3B4F76F155807491E98778967
+:107A0000DDC3E791DFB711783EAFE57858BF2BF6BD
+:107A10003D0A7A3BAF257A703EBD4CFAFCD5A87F73
+:107A2000C4CAEB7CE5A9F7A261DF89213DD909BF72
+:107A3000487EDB78D4AFEEE316F087F579E2FA09F9
+:107A4000804FCD8E9D1BB99F2A8707FA6EC5CE4BFE
+:107A50000753202FDE203C99A0C71D32FFAB42AF59
+:107A600047A5A5566CFC52E65B8A395F4CDA27FCC9
+:107A7000FEA24CCA498FE8E7A068CD637EC924EE18
+:107A8000EEC4D7AFA818E5EBD37CC9B06F1BE727CE
+:107A90009D7BA9FDB065ECB27DCBD85B53192EDF81
+:107AA000F3DCB3EBE797D1DF2376E173523F30DFAE
+:107AB000C09EBEC12ECFEBCDC467402FC6794DE32B
+:107AC000E6F593EDBDE0AF29AA326807C123E59141
+:107AD000309637BEEFF8B36256F1F96DC85BB5E189
+:107AE000922FF2D941ED5F88D2AEEE370C76327923
+:107AF000DE0BAB3B17F2C8E351DE6BFAB1BCD59697
+:107B00008A35D0397A1DE653A392FC9511247F451E
+:107B1000C67DAF733410E52D42FBEF5B7F6C04CD67
+:107B2000330629F1EF68A486DE455A4897FC397D73
+:107B30005B13F8F34361923F470D61BE64AC33744D
+:107B40009C03C40734E23B6FD039A3113F181739A7
+:107B5000C6CA787DDD527590CEE522390208DA1A60
+:107B60003B94F3DE28826361A42AB42EF4472325D4
+:107B7000BCCDC73AC7274498EA1525C4DAB18FBFF0
+:107B8000EFFA551D4F6AB83CBFD47083BFBA137467
+:107B9000BF7DC8FAE57A6F770E63BE3A56F97EEB81
+:107BA0002EB215DF093C8F8BCCE773735CE4942312
+:107BB0009AE075D4E17BE87A43D7251CDF4F8EFA33
+:107BC00089227C16ECC7CFED6C776BB6B53EF75BC0
+:107BD000826BF3A25C0FEC472FD3BE70809F4EB533
+:107BE000B39CDB0CD992EA37F770715CCB6BBADFD0
+:107BF000DC375B6FEF147CBE34CFEEC57EF45E6184
+:107C00003410EC48F5D26FD26C5BF216CEEBE6E5A1
+:107C1000291E9A8150C1EF69CB7CE497FCBC5E09B8
+:107C2000DC0A7F81EF73BB40FD75B1FED5E9945F3F
+:107C3000F78B0C9ECF47A48FD762BC8A70E65BEBB4
+:107C400062BDC971049F97FFA1F279B22E9FF29194
+:107C5000CCD7D96EB36E8A37197EAD041D6FEB3663
+:107C6000CAF25EB093A23C4DB6FFC426EBDFA2D7AA
+:107C70004BD0F1FBB14EA7B4FF993F689323ACA062
+:107C8000FF77FB95BEC6FB467893E1177AAC3C9331
+:107C90006D98B754DE90C6F4A4DBD366E9FCDCE84B
+:107CA000170D1CC3214FCB9FD9F3373B41DF332A3C
+:107CB0009C47211F7E54B1220A7AFD0C4D0D842170
+:107CC000BE6A7A91B743AE4BC7B85E396EB9A11F91
+:107CD00006CA00DFBD6D0E712FCBFF8121C1FA9660
+:107CE00081E745FABEAD6E1AF360B07E5D6927FE8E
+:107CF0003318E5723F57456ABF077DD5EEBAE1C13B
+:107D000060BDFB54F94379BCEFF471CFD5791F3CCA
+:107D10009E09396F02A7C6B81DFA11F049FDF6D5C4
+:107D2000CF73DAEF3E0BF0DAE494FA92B5EDE38527
+:107D300094AF9F3580CFF709531D5ED8F5DA77846D
+:107D4000F961AFAD9F15EEC5BAEAF744F9615798EE
+:107D5000A7EF1BD2BBF8BB6FBB8DE9ADCAEE7F6648
+:107D60000BB5ABDADB9FE989E895ED96BE57236446
+:107D700079B4376DE55094F764FA79CDE68EE1F287
+:107D80003755C1E5E181AC5882779B533B8575132C
+:107D9000BDB2FDBCCA2EBF1FD1E912FA25FBFF966A
+:107DA0004471BF42CF6B3F8F677D4F58BDC9F39180
+:107DB000BF7D20AF47B3CB7D216AA47E78C425E781
+:107DC00075A4399EF785418F478AB7DC939580EF7C
+:107DD00024AFD2FCFEB24C0DC01F6ED09F32F5F224
+:107DE000DB5751BB4F5F55D96F33E7D78B0FE3FBA1
+:107DF0009C15D51339ADBC6B329FCBF51FA7EEA2F6
+:107E0000F284A9A7D8BF6BE07F4E95D99F9A98E9D5
+:107E1000553381DF5CFFF68354FFE1D9271600AFAD
+:107E2000C333354726ECDBF6D697FF4CF36D5DFE8A
+:107E300027D6A336446B11F87E71F7D35CBF66C5B5
+:107E4000FF2C807E50639574639CDBB53A3DBF91F7
+:107E5000A9C5A2FFAA15BF633D2222B745F2D7BB31
+:107E6000BE1F3F3AD3BCF96585DA2D0E6FAEE154E3
+:107E7000F5E7E1FC3BAB04A2950C862BEB75E75CC8
+:107E80008168E047B348B972F1D610BF315092A86B
+:107E9000DB8BA8DDE226558F57F4DB41A7A1F51750
+:107EA000D377AEF73DBF578A26F93D76D7FDD73059
+:107EB000FE4500FEAE33CF646E023D9CDFF9745682
+:107EC000B09F3634BD72BE72FDE7F47D738EBED8AE
+:107ED000406FDBC24CF6850BCF24EBF426E9E9C2F8
+:107EE00033D9ECE74ED4F7D905C5670947BB5F081E
+:107EF0008E67109EA6E11C97E36D1A0EB9FB619D7B
+:107F00002F2E8E6F1A0EBE67F041E168CA63BB4127
+:107F10004E531EF464837F8AE2A62CFEEE6FCA42A3
+:107F2000FB972DD20E63CCA7F2B9148E7BA2B5F0CD
+:107F3000FEAE7C6EE026E48D71EA9D92EFD43B2587
+:107F40007F095DB79629EDE8A44FE61EA7B3A43ECE
+:107F500096F4825CE49365DE29F30B3794D8E16FE5
+:107F6000AFB7C9BC6B7D89FD18E6F73569B5C44F5D
+:107F70007374BFC5027FA9DD0BFBFEFAE5E11C3F70
+:107F800031DB3ECF4B69F67ABB695C030FFDFDE642
+:107F9000EF8BF4F9F40D890BEAA5B6ED0BC339F6B6
+:107FA000A4E8328E6049A6B4E33EFB6C477C91AAFC
+:107FB000EBDBC26DD0A15BEA1B8CD78FED065EEFC9
+:107FC00048A1F92FD6E3A55EB648B8FA9E957CE3A2
+:107FD000E57C2D05E7D505C01DE75C2CE57321EF99
+:107FE00049BC1979035FA1F05DF1F18214D8959F26
+:107FF000C894F6C7507C2C8F1ADE13E5065CCFD4EC
+:108000001DCA00DC8D759DA8F37AE968EBB4BFAF9B
+:10801000CF77688C8F7C47307DD76F1D7288242086
+:10802000716EABD58325D45BFDF743BFA8DFAA36BD
+:10803000F904973B80977391FBDF41BD051B620BF1
+:10804000A00F18ED17AE2FF29607CD7BE056335EEA
+:10805000063599F3837799F35B71060DFBE7DBE552
+:1080600007CCF92187CCF9931FDC7133B64F85EA31
+:10807000BB5F85BEF3E7F187704E9F7AF99568E0A4
+:108080006BF15FCB0F428F0B8D67213C2AD0737C45
+:108090005B14A6972BE25ABAE14346DC06766230BF
+:1080A000DD540ADF416BDA95F5CF8AA69BBD4467A4
+:1080B00055CBDECF907AB3EC7764D35A3BE4CED085
+:1080C00071BBE33B22D2EBC63E2A1921CBAE5E3612
+:1080D0004E7C8AFED6BC371EF458F22B85E59B9267
+:1080E00097B25F07DD1CDD3EFB464E6F9EC0F03051
+:1080F000EC920B9B954014E55D2344877F1FF18B29
+:10810000A50D21F19F6B42E282D699CB17EEDAF7EB
+:10811000FF104750E17882E32EAE8C67F41F805E3B
+:1081200059794AB07DAAF2A96FC2CCE5725DF3F528
+:108130007518E7ADF05DCBF17B57CBAAE238FEA313
+:1081400073E9A84B3B8573CB3877AF5EB75195F297
+:10815000BCB784FDC891768E8BAC76884004CDEB9D
+:108160005094DDEBA2EF97D647B1BCB280E45CE857
+:108170008B940A27C74D7A62D0EEC4BB2ACB65D553
+:10818000F1121ED5BF51FCB01D57C3A88BFC933212
+:10819000BF4804D8BE0B3AF206AD03F80BCE8B46AF
+:1081A000A95F565903FB009F8E7368ABB95E15AD8E
+:1081B000F3A338C87BE6EF35A28DEBD7EEFA262C79
+:1081C000F87B903D9AF55E43FF5675F94AFD653898
+:1081D000CB4F74208483BE6CBADCBEEE1E92236843
+:1081E0007D2B0D7BF85A29DFDDB2519E63249F67FA
+:1081F000014EEBD6927C86EFA46F20CE442C0AF77A
+:108200004BF95EEA0BEB6667B15CF4F23F5E0A4045
+:108210001F697B4861BBD2BA7CD9EFBAFBFA7339CC
+:10822000F8A7C2E384B11CB66E8A51DE87F5914F80
+:1082300030C564C8F9FAF71E6EFEDE4BF566C13E26
+:10824000221E74B27DC490FB0DB9BE2E56CBC91A46
+:10825000D6B9FE75B16D51F0BB898AF8EF25B76CC0
+:10826000D6CFE3365A3FFC2AC795E283F08F19F543
+:108270004666C97365F858EF16BD1EFB5FCA2D53DD
+:10828000EEBD8EE655FEB0C50D7BA18107E1F5661A
+:10829000010EC7D73A0B4077C3C74A7BD9917CC937
+:1082A000E723860A8E371AABF73B36CB624A93C276
+:1082B000891EA99FE345D21E1F35B498ED9624135D
+:1082C000CCEB2A6E65B2DE4FB9BDF8F7A3BB984F71
+:1082D000075D144AF9FBF86DCA26392F2FC7270E00
+:1082E0007FC0C9F6CEE3FA3964E081E86818CB0FA5
+:1082F0003A5F8B0DA19BB5A0079C87A00725986EC0
+:10830000CC74718B22E12BEE93F2F7BA589937E8CF
+:1083100082F43FF1BFA09B22C1F0EF4E0F34D6DBB9
+:108320009D1E4874B00874D0512F840E84D53FEC44
+:10833000DBFC42A52362872B848214ABF021CE178D
+:108340006724C3EB1EAB1FB178BDAD122F7DAC927D
+:10835000EEE8B4F18517707D2FE27D4B1E5C28BCE2
+:1083600054BF2445B07DAD1FC9553171DC4E204549
+:10837000588E0ABB13A5685F1223FB2FE92938FE2C
+:108380008EFAF35AE274E6361CFE5EC17205DA47D5
+:1083900017707B9F45B6F75A29ED9B21F598B69546
+:1083A000611CBF5C72779F2CD0C9C4B1663A39A2F8
+:1083B000D39591DE94EDD68D759E24F083D286FE02
+:1083C0007CDED43B8BAB77029FCF47B0FC59B2EA3F
+:1083D000C79386617E2FC47B80C23393B7B33FA817
+:1083E000B461F64F3E84BEB4D5C9DF2BB2B5F559A2
+:1083F00090FF15F7DC9DF4A174C6017B12B5D79AE6
+:10840000A69C7F95D2C9BEEDEF409E983C5DE5FAF3
+:108410009385B43F8B0639CE24DFE7D624EA6FD2AA
+:108420002885C3698E3A5DA9B7C10FA4E3F7A92CCB
+:1084300045977FE43D8192557DB2D273E13F21C9DA
+:10844000B80B39FD53A3FE186503E4A5BEE3E4FEB3
+:1084500033EAA31FF47B3A4BCA55BFD5E162E40966
+:10846000AE5CBF7C75D8D18C68A4B64036A5E9FD5A
+:10847000C7BE84754E4C17E3D703EE77AA6213CFBD
+:10848000B7AD84F94254961BF4AB9142CDFAE3D6D2
+:10849000FECC278F8E693B7A37E58F6E1E24ED8CDC
+:1084A000BA7D61BE4BB07C70748CE4776D9B239871
+:1084B000FE8FB85AA3E2A43D8EED0D653A497CB615
+:1084C000ACFE7EF8B9CB22ED47717ECC7F681AC72F
+:1084D0002794AD530361B807B0C66C6FA88AD4DE89
+:1084E000C67E08B51B84DA074033A0A3F2350AD351
+:1084F00061DF7A8F3D99F99CE2C2FACA2303FD70CD
+:108500000E947B9C1CC77C85FDE06B82FB70D8B908
+:10851000050789B5676B9F004E258D25ACEF46E4B6
+:108520006ACCBFFAAA0417EC179DFE26C25E0BBEEA
+:10853000646D4DC6BEFC55969BF13031CE9515C984
+:1085400074EDE4FB11476DAE2CCCEFE84AA705E7CC
+:10855000EDC41592BE69DF39708FE11EAB08073F8D
+:10856000D89A25FB9DB3DC5ABC91F2BD1DC21A15E9
+:1085700007FACA67FA5ED85FFB2DE675EA17620450
+:10858000E489B2356BE5BC74FA10D696C2781AE766
+:10859000D4E6B402D8013AE4DBFE63DB01C70EBACD
+:1085A00098AE303DD07A0EC18E9CDEBFF432CAE95F
+:1085B000FB3ED0CBC4B1817E881B2F52AB38BEB6F8
+:1085C0003D4978E0776C176D2C8FB4933C02BE6701
+:1085D000F019839F105D781D899DF8DE5247532264
+:1085E0001EBEB5CEC1E9B3752E6125786FAB4BE2E7
+:1085F000FC0B756E4E9BEA72F8FB8B751ECEEFA8D6
+:108600001BC1F997EBBC9CDF553781D357EB8AF937
+:10861000BBC1AF083ECC970CBE63F02783BE0C3EB7
+:10862000154A577309CCB81741ED991F1A7C10EB06
+:10863000B01474F22703CFE94AB12F09FC50B4CE2D
+:1086400006FF2852CF3DFF0AC1B9BD2292ED22EDAF
+:1086500042F2C1F648079F07A976B10BF689FADB0B
+:10866000BC47EF0E3A876FAD508435888E7FBCC40F
+:1086700029AC41743C6F59AC293F67D9FB6FF4A416
+:10868000FEDF8DD172B3691E477E79E2F13FD1F7EB
+:10869000DFFCF24C26F04EF3D8FC08C6BD2B5C9FE5
+:1086A00047AB9CD75D769697FA864B7DAB6FB8D477
+:1086B000B7F0E3088ACF3DA2E3A3242DF69DA7B12E
+:1086C0006FECAE9B47C04EB452DE4BFA04F8A3F2F7
+:1086D000BFE8F82B5D16C6702D6DD0F76B70DC36D9
+:1086E000C1F558B260F94EF10A01BFD7B15FD803A6
+:1086F000242B88638AC3AF407622E56B0EEC98ABDF
+:108700007FF711E47665D92196B3354724C77F08F2
+:108710009FED5C707FCAB2835C4FB4F636C56F467E
+:108720000CF5DAC13740E3C05F69CE7E81FD2E1AB9
+:1087300015BE7F54AE7F2F5FAD98E2A26764ABF2A7
+:10874000DE459695D3F359423F471AF9BC32E89675
+:10875000F808C7619637E6DB1704F1E752FD7B594D
+:108760008EC514A7797F969DFB398FCD49FDDE9B81
+:10877000936E9FCFFCCFCDF7058CFAA53905AB6082
+:108780004F2E5D83A8A6CEF625D9567D5E2EA97FF5
+:1087900039E85C8BE2F8A22ECF07439E39855F470C
+:1087A000F2FC59EFAA7CE1B917E08FACFC73189F7B
+:1087B00053958375FB4AAE7FF8349683BC91CA709B
+:1087C000C8E112FF85CFFD351A715DB53BA4BD9799
+:1087D000D2A3486BEEAA60FB5E8D87F6491CF8AD0C
+:1087E000D9EFFFFA0B7FE6FB9D84B0143D6E98E352
+:1087F000D46A767CCAF16BB0C7F986727F1C5F1DA4
+:10880000DABE56F99AF557422CC3A768CF97893C30
+:108810008F9D9712C1E76AF7AC4CEC2A8E28B41FE3
+:1088200023CEC1B0FFD58A359FC3CF597BD7849360
+:1088300092DE65FFA1ED1ECA8E4A38315020C6EE89
+:108840002AB6935805C79F2CD5ED38EDFE4CF6633C
+:10885000772777D7AEA7462492B55BDD3188B3BEC4
+:1088600028C484AEF0F449B6946BCFD33E823FFB6C
+:10887000E23695E5CA8BDBA2783FD46C7BF020E230
+:10888000046B9E52D8ED582D5A38CEAF66872A1CFD
+:10889000C1E71DEC47F1DDCF73F173514B405F8BA6
+:1088A0009A14EF669A4FBBC31DD323683EAF80BEB8
+:1088B00088341787350D47FFC6FC9F077F0B92371B
+:1088C00017353FC8F18D54EF02CB37BF8DE0383CF0
+:1088D0003AC9DEC13CCF6E18C2FEF5454DDB6B5880
+:1088E0003ED816E182E9E98CCD7C0FE4803EDE8142
+:1088F0006C298F9CD5EDD1675F50591FC23CB12FB9
+:10890000CFE871B846BB37F5766F664BF9A7265BA3
+:10891000EE4FA3FEA2A6A3D1FDA8FEC95DEF73FA98
+:10892000BEBE6F1645B6F03DCF933B22F89EE0C920
+:108930001DFF39FE351AEF7CD3980425689F9DC82A
+:10894000B6C97DBA41C62FF32517D6139A783D676D
+:10895000B7A528AC2F03DEA4B79FDDF112DF4336A5
+:10896000E4EB1F1C2F384BB186DCA3183D08728D39
+:10897000A355BFD7D1A6DB63FE6FFAAFD1BF27598E
+:108980008AF571E43D0D61C46FB864BD2235B72727
+:10899000F6DDDCC1EE99B8972DDE927197A2B7FB98
+:1089A00011E87F73DF8D67BBCB529BBB27F25F1C47
+:1089B000268595E0337788CE57925A87C1BE7B349F
+:1089C0004DCA15863FAD6AB522BC04BF5E44673E02
+:1089D000E4FDAAD06007C949677C3D5661F1DA71B0
+:1089E0003E46D9992EEAB73B37C1BE75C42E7CEC02
+:1089F0007F7BD129FD27E9D20FF218F617A5557113
+:108A000081AC78D8F174BAA99A4AE541F453B529F2
+:108A1000900539EA9C5DDA2B510EFDA9AA40D6AB30
+:108A2000D7E914FDA0DFA369AE0B2CF7EE8C12D0B2
+:108A30003F2CAF4449BBC8D3CE4D6141E776BF1C44
+:108A40008B1177C7FE4ADF66393FCC0BF2FC227BE5
+:108A50006316E45D63DC45D18D3CDE397DBC45E1C8
+:108A60008DD29FA3C711A23E8F6F13EC776A7B262E
+:108A70008CE5E633C92D2F63FC33CFF4E7B887A329
+:108A800069FE05BBB8DCC9F1E795CF860530DFD3B9
+:108A9000CF44B15DEBB44DCA63A7A312591E3B147A
+:108AA000F5F05CF6633D15A6C02E745A11F62494B9
+:108AB0006FEEC1F24065DD32F6D754127B811C4B5C
+:108AC000E904C87FA737F7677BD1E93755BE5C411A
+:108AD000DF57E3BB261AE7FE8CF58008B6239E79A4
+:108AE000F66FFD83FD3B465AF994D93E66D083511B
+:108AF0005E9423F960518ED4536EC871715A1DD1A2
+:108B0000F4703AAF53F207C203EB81B41F1361EF65
+:108B10003FD2B43B5189049C0359FF09B86F95FAC1
+:108B2000D6996D36F65355BE12E5653BD4DD57F147
+:108B30007DC94A55CAE3951679DF50F9E556B6FF67
+:108B4000D43FE32C003C08DEACDFB66D56F571E493
+:108B5000B8A7B7F4917E8D809E7F7910FB3526C62D
+:108B600089795359CEDA9007B85E7A2A82E3FE6992
+:108B70001C2FE2342A7FF67309CF9805AC27D0C1A9
+:108B8000CDFCB94AE7CFD5775F1383FB10E25D9543
+:108B9000EF795CB27A7A82FF86C2EBD11C9D3FBF2F
+:108BA000FC38F3832ADA37880F5BACFB13173FAB33
+:108BB000B05CB978D5358F30DF7DC726702FE25C89
+:108BC000D383D1C1F8A8CF91FCB0B3BD87EB2FA65A
+:108BD000FAB2FD5BD13C9F2D360FE6138AC7EFDD5D
+:108BE000FE59F507B5AF6C22F922EFCAF55F122DD9
+:108BF0003FFD33F8CB3627FB5109FF7C3FEAACAD94
+:108C00006901D67FF67927F39DB3B172DF9FA4F394
+:108C1000D4978DF9DCF46BB6CBFC619AC039B4D033
+:108C20006FEED798D7EA1C9BA4B7784F0CFC44D5BD
+:108C3000840FF447F8F911B77FD7C6ED43D7B34097
+:108C40006FD7B14F9F8F60BA39DB4BE2E5EC0BD9A0
+:108C50007C9E1D8D95F44EF34D85DE743656A6B878
+:108C600099047AA874497A383BA689ED026795ED94
+:108C70009C1EB5C97695CB747F3BD15F12E807B4D3
+:108C800009BBAA634D0BE419F0F9E1059C06704F8E
+:108C90003BD48E0E3AC5F9D7AAEF33E31D05F6EBA8
+:108CA000B09FA789EFC76BBA3C59B5ED4A7F25F055
+:108CB00054B54D617FDA7F19FDD0AC130C3F00D164
+:108CC000E5629FC2EF222C6EB86D11FBD396ACBD4E
+:108CD00015746FAC63B17E6FFCA8A2F27C8E3A690A
+:108CE000FFE45E399E01DFDFE7281DEF75B88CF3E6
+:108CF0008BF6F03B396E4947946DA4FEAA1A943561
+:108D00003C4E9AA1E7CAF5197022B0D861E73BAA98
+:108D1000DFD3EE6EFDC63CBB9BCF319DCF1F4D9385
+:108D2000F793DBDE96F7CC2F7D3D2426EE5BE44106
+:108D3000BE6160F487B863D020F5F322F81CF635E5
+:108D4000ECEB34CFAC0D66FF4ECE53E6FC806DE607
+:108D50007CEE0E733EAFD99CF7BC6ECEFF09E30EDE
+:108D6000EB8413F46FC43542FF460AFDDB1D26F584
+:108D70006FE4A17F2385FE8DEFD0BF9187FE8D3CF0
+:108D8000F46FE4A17F2385FE8DEFEEFE124E55BAFF
+:108D9000BD1478E0B8BADD4E233E81F7CBC5D98942
+:108DA000CC478555EAA51717E5B2FCD8616F9AE262
+:108DB000607B93118F9518AD85F7471C80D2B22A3E
+:108DC000398DDBB11DBAF6556987AE2A7046C2EE01
+:108DD000D1BAF2E42A883DA7A3B418D4BF686BDBEC
+:108DE00002F8562F3BC07EFFD6E5EE77AF93F863CF
+:108DF000FB8B115F5582730F7C9BF4251977EE7105
+:108E000004DB5343FD44624D501EF2D33A733ED40B
+:108E10002F04BEE635EDAB46C6C76F6C6DC9E0FBEF
+:108E20009F3EE3E0FB699FEAF63B31CBC1F298211C
+:108E3000CF23CE1B70597A9FB209E795A77F1CC339
+:108E4000B9FD50A6E97E61685A767908CBF31DF921
+:108E5000358A05E3944F5FBE8FF56ACDCBE7D2ED3F
+:108E6000FADCB2D75B4CF3EEEF0F37D1D1C0AD7166
+:108E7000217ECC5EA6FA8377A587F8310798CAA72A
+:108E8000AD1962BE8F5F7C8DA9BCAFBD236ECFA133
+:108E9000FBB9E4FC5CB2CEA5C8025E6F68BD54C5E8
+:108EA000F327F86FC5DB524E2DA773C61BAFBF2B40
+:108EB00052007F9D7732E057D1648B859DAD4C3F4A
+:108EC00087C432F3B95C61153E575C27DD55B88421
+:108ED0003796DA7F696D4C653AFAE547A92A8168C9
+:108EE000D180963CE8AF8BDE7C7238E8AA5ADD98D8
+:108EF000EAA2F23B14FF165C203F13B73D712495A4
+:108F000027A95A497FC273AA2D70FF1CF0D1ED1911
+:108F100002EFA47CBAE6A5688E1FD4E92FD5E60A35
+:108F2000071D6C6C54594F81FD4C8DEBA4938D8DB6
+:108F3000F1E1D06B2AC6283EC8C7065C0CFA08854A
+:108F400007C9EFEFBA69BD970EC9F7948C752E75F6
+:108F5000C9FAA241B637DE0730D67B5CD7472B373C
+:108F6000BE91753B7D3FD77F5F9E1B7EDCBA5DBCAB
+:108F7000EEC5966D5B92297DC7A1DD85752D7D7B44
+:108F80005CF4481AE7CB6D32AEFDB3754F3EE1237A
+:108F90007E7A77E39376E80F9556BF9DDFCD7966AD
+:108FA000A31DF10ED76FDDC8DF176C2D617B8071BB
+:108FB000CFEE941197ADC3A362ACB2C145EB3CDEDA
+:108FC0005FCA8515E1329EA6481DF54602D6B55505
+:108FD000C9C7BAA6176FB7E3FD8187F57AA1FBA6CB
+:108FE000FDF0B4A21EB07B35291CC7D4DD3E99111B
+:108FF000E8CFFB64DAE5344EA75F1EC87ADE8782CD
+:10900000B42F9C23B921FAF56155DAF59A55F94E3A
+:10901000983D90300DF2C25EF96E45359D43230AAE
+:10902000A0B70B7135A5C5A354139DD7164698F666
+:10903000C12C11B4AFA8BF9B452F537EFAC40C536B
+:10904000FD99D30786F89D0B3ACB997F5D6D7A8F9A
+:10905000A6FA2E9F5B61BBC758F3774AEF623ABB13
+:10906000D1D4BE5A4C35BD47B3E8A9F718CE4465F4
+:1090700076C4E154E8F758666947F5EFADFC9D16F4
+:1090800062DAAF7D333C7F92E7A58DFD09863D7D99
+:10909000167ECFE8EABC0CEF881745BC30EC1D9A71
+:1090A000591E69613D55483C54EBF6A8EA1C698F8E
+:1090B000AAF6B5D8118F4DF0B7A610486A1A15B6A2
+:1090C00037527D474A9CCCDF85EF3BCCF752D0DF4F
+:1090D00065941F524BB0BF42CB6B68DD38176A6096
+:1090E00047623BD884936C0733C6D1FB37E834F42E
+:1090F0007D80D0FE060C7033FFAEDCBAFD602F829F
+:10910000CFB4E2D87CC49D54354DB195E45E496F2F
+:1091100006FFBF546161BF7EFBE1034C6FED155646
+:109120008F8C4BFF76B8D478A5DD35940E17D0BA66
+:10913000E07F5EB043F1F815590FF0E905FA0C81B4
+:109140004F4A177033E0D501BF90727E3F6E28E220
+:1091500026E47B0A57C025149EFA380B34C17227C7
+:10916000CDCBCFF30AE9578C08DD8FB7DBD9FFB041
+:1091700041112EE5BBE131F5B2B4E3F4CD90EB6FD4
+:10918000DBA97820BFDF7CD9CADF3BE8A758C6D966
+:109190004F9F68DEAF1DF4542CF7CF8CCB89DCEEEB
+:1091A000DF4557DF454F86FF26347EDDB847E61999
+:1091B000A0DFB71A26867DF34FC4E11BF24177E7A3
+:1091C0004CC739E4D2F11099DEE5F9BC342A9DE3AD
+:1091D000CC35DDBE68F0694D6F678C5B42E5EE789B
+:1091E000D07B6F7E67715543466AF0FB37DA4A1BC6
+:1091F000DB815397C7735AE27425E27C29592EDF2D
+:109200006939764FCF44F8298EADB4254CA4AE8F82
+:10921000DD3934550C42BE88D34FD786CD0AB6CF40
+:109220001BE92D03E4F9619CEFE72D87A367613FFC
+:10923000AEDC198D90A1C52BDF1FEEA273BED9A2A3
+:109240002D1AC0FEE08D7CCE0BD7C63CD8E70C397A
+:10925000A37265514FC80355FF38F004E4016DB99E
+:109260002D1172EAE90F5481D01A3AE758BE38E559
+:1092700094F47D6A7304DFAB3CA5082FFC518BD4BA
+:109280007D792ED379DB7C33C68F70D2B8C330AEF4
+:109290007F4B12C6F5F8B230AEB63C33A62BBB8B73
+:1092A00091D6AE97F2DF16C3CEACDBA321F7230F26
+:1092B000B95F644BB91F79C8FD4821F7E37B0DFC0A
+:1092C0000EF01BD7B7E5436FF58D15394BF81C8EA3
+:1092D000CC815C7FBB12EE013FBA5DF1F4E478848F
+:1092E0000F62E5F91B8257231DDD46B25910DD5E82
+:1092F00077D92182E3EBC68858537E9C23D954BF8B
+:10930000C895662ABF3EA9BFA9FC0677BE297F5330
+:10931000CE4853FD499E31A6FC8F46DC60AA3FC56E
+:109320003BC5949F3661B6A9FE8CE21253F9CC5925
+:109330008B4CE5B3B5DB4CF95B2BEE34D5FFF192EA
+:10934000E5A672AF7059710E36431F23B8EF853E04
+:1093500046E9ED6F674606E375D4384B97EF0C3559
+:109360000D90FA5674AEF739D025EE09810EFBE860
+:10937000F780F6E29C1906BF654091FA704B32E81F
+:1093800026B45E68F9A888FD97F09465FFE76E9FA4
+:1093900061253E31EAAAFD4332287FFBC0E619561B
+:1093A000E22FA3AED9FF523AE57FF1DC37B27CF071
+:1093B000FE4B285772F7CBFC34C122C8AF06CE9BB8
+:1093C000E1A3758CBA2E7D8D47DA53BA8C53355292
+:1093D000C001719D8003D200D127D2FD449F485F18
+:1093E00027FA2CB7097190E813E921D24BF1FDF768
+:1093F000A497223D4C7A29D277482F45DA427A2920
+:10940000D23FD4CDE2F4833A8DDBFDB1AE82D38F6F
+:10941000EA96F0F74FEA9671FA973A1F7FFF648059
+:10942000617F08B09DC6F08BD5C01F097BDE2EDBA7
+:10943000B960BFB1E295E7ABE1C7AC5F225A23B098
+:109440004F5BADB1271C9DFEC9EEF9AD559C08924E
+:10945000CB9CE1DECF06F0F8BD5DCCB7F5EF47C49D
+:10946000B43E0584A74FD3B5B3E007330ACA56C646
+:1094700010FFB8EEEB2536D0CB8796AEEFA3EFD535
+:10948000F9DBA703BD6DE8F75AFD5DA66B1D32AE93
+:10949000F05A6B6B3DDBDBBF146EC403ED33ECEFB6
+:1094A000F758F95EB1F285E0FCE804C1F9FA2F5BE8
+:1094B000380EF15A972789CF1D3D6FC40575F8FD09
+:1094C000F11314EF63F8E18D789FC22F5AC7413E24
+:1094D000181D69778785C40DC0DFBE2FEA8FC6BC13
+:1094E000F87D27C3BFFFD4972280F7F20C3FFEB56B
+:1094F0008E9634D81546DFE1F004C73319FE7AE5BD
+:109500008B1615E78911AF648C63CC3BCA4AFD15F5
+:1095100074C6235DEB6ACA475C467D7524F7D79312
+:10952000BEE3DD49AAE755B95D533EECC7A3AB22C4
+:109530003D42E98C13E8A9AF9BEAF13A0BBFD03862
+:109540004E62B41E27817E1CB29CDF011C9D104818
+:10955000C6FB9FA397D83DB0833E8EB8B382CEB8EA
+:1095600005D48F08DAC79827FAEDF715CD17F2BCA6
+:10957000D7CBF09DE692F429DC7A5E3FAF85632C71
+:10958000DBBB543D5F1CE6FA6B04D1CFAD19DA901A
+:1095900081D4DF1F948CCC7CD617327A60DF4F09E0
+:1095A0007947B00BFA1931F0FF847EBC12EFBD058C
+:1095B000DBE142E9C8C08F414F06DEBBA32B830E1F
+:1095C00082E2D018EF1D71657A7FA1F4D61D9D1936
+:1095D000F475AD43D201F08CF82083AE942F9AF845
+:1095E0001EEBE82A079F7F065D85D2C5957425E9A5
+:1095F000B4FE270EEEEF4ABAEAA407C0E587D355BA
+:109600008B8AF3F89FA5A7796D623CEEFF975C7695
+:109610001F44DAAB9FB6177CA64C8C190F12132E81
+:109620007510EC62A1F532BAA9174A7FA1ED6EBCA4
+:10963000A25D466E70BB71FA5919DAAE12ED7A046A
+:10964000B71BC271116FE9F708DE721A712D9E996E
+:1096500090530EB96DF22D2FE18DCC27BA19A7F3D7
+:10966000F34362099FBF24EEFA404F853A698DCBE0
+:109670005DC8FA426164D7710537EAEDC77F5DDCEA
+:1096800080F98C4F30CBE337EAF2FCF5A291FB0F67
+:109690007D47E1C6DCEB59CE0F7D4761F3403DFECF
+:1096A000204DA481DF170A8F9C9FFE0E46A1BECFDE
+:1096B0005374BAC970AB62541CEE9B6A561C32AF2D
+:1096C000E31D8C3C8CEBE3FC0DC2CFE94D22C0FDC9
+:1096D0004CA20309F91F096193EF5FC8FBBA35AAD1
+:1096E000F6DF90578D7BBA4F3BB557B0CF0F444C48
+:1096F0009E83774AC60D19D70FEDF617BA59CEDB00
+:10970000EFC860B913FBD216D7C927DEA473BA5FBE
+:10971000A6BC378A14F746FBD179FA3B3AC791BF0A
+:109720003167B940BBF16E73BC93D1FE26D7386167
+:109730008DEFFE9CBC296F776FD8CDDE8ACD2E04CD
+:109740007EDF8ABDAA10EB7D2BB6A745A661764EBB
+:1097500007BDD2AF2BB9D8A0FBCEF1C6F378DDC1DF
+:10976000D9806B283C0D38FF00B81EEB0AAE7B0792
+:10977000089637AA23245FAD8E907CD580737558E8
+:10978000C77DDE9EC1F127550E09AFF9CBAE11564C
+:1097900012F5172C1BC9F99375C207B89FC69260C2
+:1097A000100FB1F709EB58CE1BEFDC9D7DF8BDE83B
+:1097B000249AE72A87F63F98DFB98240164984E267
+:1097C000E4867ABE8F7FFE05D5037DAA4A75AFF188
+:1097D000C0CEFA962AEF717D7D2015FE58F154D740
+:1097E000F1E8550E095F439F1CD2AF98F7ADB15F0A
+:1097F00085FEBE80215FF50E93F1DCC63DF7EEE4F9
+:10980000ADE1E192AFF50E93FCD8C0EB06BB7EEE66
+:10981000533FC3898FA6FC3A9CF5AB98586F4C2EEA
+:10982000EC8385C2A49F187695F604F97ECAB5220A
+:10983000EB9151942F3C64137E2A6F074340799239
+:10984000F4B3B61FBAA482EF174529FC3E86716FA8
+:10985000292CC922DC417CC2E90E37BD4B1B911378
+:1098600067CA47797A99EAC78C483795C77A0798C3
+:10987000CAE3271498F23D8AAF36D5EF396BAC298D
+:109880009FACDD68AA9F5231D59437F8588AFC24E2
+:10989000FA2CB9C5D4BEEFB25253FD345FA5A95C12
+:1098A000C53B9B3140ABB7252711CF81CA9F8CD5D3
+:1098B0004B43DEE3B508CBF0CE776BFE335ADECBFD
+:1098C0009910B980DFAFC96CFC99799EEA446B2C82
+:1098D000A5D7BBCD7CB128C99C1F17B94F81DF71BB
+:1098E0009CCBCC9F5396584DF91FE5EAFC344FE4CE
+:1098F000B1DDE3BBF0AF0D30E13F144E440FFC7E11
+:10990000683B9DEF3ECCEBCD327E0F077E93E0753A
+:10991000C06F120C07F84D82F3F09B04D787DF2449
+:10992000B81C7E93E0F22187CCF81FD662C6FF55A3
+:109930001F99F16FD06577781AD96AA60FA1299A75
+:10994000F22D78BAE694997E42F1731D895BB109D4
+:10995000C087E209B87F38BE5686E08BF0C3F73780
+:10996000DB7B47317E1ED7D7756D6020DF972E3A9F
+:10997000A40ABC6F63ACF371FDDC3F6DD51A73892B
+:10998000CFFCCE5D90043E769D907EDBF155164F68
+:1099900080BA7F20649CD929DA43A83F2BFE52AAC3
+:1099A0001D74D226DFCF7B0E7C79D895F1B23E12A2
+:1099B0004FF8BEF6CF54BE2775C4D2A8808FAF8EA5
+:1099C000D19E009F9997BB84D79B248AB72F405C78
+:1099D000D47F85A5223FB7AFBCC72D725BF9FE8946
+:1099E000C127E7A6C8B8A92DB9BA7FDD23E3A79E92
+:1099F000C995727794C7C571DE25B9F27E0DA98B22
+:109A0000A97307013E879DD980CF3A0BBFEBD98A56
+:109A10007BE4099DF7C8210F43FEECA3CB7FF51F24
+:109A20003B1C5847F67A613A7FFBFB1DA6F8E281A2
+:109A30005B5DA6FCA0A62453FDC1BBDCA6F2FC40E6
+:109A40008EA97CC8218F293FAC6584A9FE551F795A
+:109A50004DF991AD134CF5AF39556CCAA788B6478F
+:109A600001DFBE8AB4531CCD4D97FAB95B70DCE4BC
+:109A7000DCBB63E57D5FDD7E61C8FB46DCB9A6D358
+:109A800075A81ED1D72EE5E8FA6421F54687AE1FEA
+:109A90000AB33EA1E971E31DF7587CE6B871235E75
+:109AA000BC43EFD0F58A8E7B349DF1E2DEE078F1A5
+:109AB000B9615DBF1F7D5EC77BE8FCFBDAE57AEB31
+:109AC000EFB4F3BD1D635EA1F349C99674BBD9D150
+:109AD000F5BDAABFE54AFB466B66F125D0FD1336FE
+:109AE0004F2BFF6D842BC6F3B4225EB7FE1776CFE3
+:109AF0000AF7778F3777B05CCF1C8B65DE945C8E6E
+:109B00008B33FDDD84884192BEAD8375FB4AC878F6
+:109B1000736364DC9A88B1BB41BFDD8F27E1996430
+:109B2000170D7CFF4BBF67F1E3354DF7A1688EBD84
+:109B3000517F3FCE6F033D4C1C4BF2593EC9135B26
+:109B40007A3D144972CA13CBAC6C9F8A7BFE57379F
+:109B5000FBFA75DE9FE94BFA10E803B20EF4A80792
+:109B6000F25429B70C92EB2B52BFEEB8E7C07E1827
+:109B700021F4F34370BC4F17F4C67468ACE3DF758F
+:109B8000EFC1A0DB503819FAAFD0E33BFB19F3D299
+:109B9000E167EC07037EC6FD13F76DB6E24D917CDD
+:109BA0008F6502E2E50CFC6DC993F6C6053A3C50A0
+:109BB0000FFCA8BB7A456A6E0CECF7EDC21DE3EA18
+:109BC000820E3BEAFF9BE062C0BFBBFB6DDDF1870D
+:109BD00050BEF05DF7DDBAA3D37FF6DE5B109F9039
+:109BE000F14B3A5EFCFD2C1C17707794793F3F32A5
+:109BF00048F2899183F4FDE423FDD6CC2F04FC0FB9
+:109C0000F52B559D5FC8F3BC24AD98DFAFC6F98A2C
+:109C1000FB5BF3374AF94788E2C4AB87C28F6FE337
+:109C2000FBCBD77A05DB6D4A1B153FDEF92AF175B0
+:109C3000AD0FB39FCFCD7207BF3BC8264D6A5746C5
+:109C4000EDF6A55DF9CEFAC248F9EE60E8FBEA0B45
+:109C500075BD192F6A60DF86FABDEE19A4FBB13C11
+:109C6000C2C3F29C1ED750A1D7E9A037BF7C6F0EAC
+:109C70007A32F631A51C1F67C0CD0D3FD490CE3C83
+:109C8000C1373C07E77983B5CBF8C50EF81A7EAB30
+:109C90000EBFEC61BE27111A8F71CE7720BA2B3F11
+:109CA00098E11FEB6E1F74F8C7BEC3EFD61E69891B
+:109CB000C6DFF169DF26DF67E9F45BFD65B8CB221B
+:109CC000FD5331F03FB5EAFD898D795DDD0FD59605
+:109CD000EFE43894668BB67310ADEF2CF58F777B7D
+:109CE000EF89DC9F88771126EA76A92BD7ADCBCDFB
+:109CF000A314E98FF6A98CEFF609F25E3DF15181CC
+:109D00007D67C44F4C118104A4861F4A5B3D92E1DC
+:109D10006FF8A14A0223799E33EA17DAF0E468EB80
+:109D2000A3771585BB3BFD53AD7D645C54777EAA5C
+:109D30006997F3B9BFE997AFE17E3E189426E5B67F
+:109D400086FB6E039D0DD82A6C5867ABADEBBF4BFD
+:109D500051A8F3AB12E89A3D82E2AD962BBC2F9648
+:109D60002AC288BF623E6FE42F35EAF92299BF7D8F
+:109D7000A5CCB7EAEFA76DD1ED20582752AC077AF2
+:109D8000F936DD4E827520C53AF01D7C0D79F0352F
+:109D9000E4C1D790075F430ABE86EFA5A2381576C7
+:109DA0005BF8D30A83F607FC6985417213FC69C12D
+:109DB00079F8D382EBC39F165C0E7F5A7039FC6929
+:109DC000C179F8D382EBC39F169C873F2DB83EFC28
+:109DD00069C179F8D382EBC39F165C0E7F5A703944
+:109DE000FC69C179F8D382EBC39F165C3E6F996220
+:109DF000F2B7CDD3DF7F285B1FCFF45198511C9B66
+:109E000047F8FDEF887FFCC4960E3C372F02DD2E0D
+:109E1000AD0EF7483C374E9078B70889E7B6D98C35
+:109E2000E7BBEC325F24E3B443E9077EAB429BF42B
+:109E30005B2185DF0A29FC5648E1B72ACC947E2BAA
+:109E4000A4F05BE13BFC5648E1B7420ABF1552F86B
+:109E5000AD90C26F85147E2BB483DF0A29FC56F8BF
+:109E60000EBF1552F8ADF0FD08CD03FE2B635E90DA
+:109E7000F3FB99F452A243935EEA32E521E707D758
+:109E8000879C1F5C0E393FB81C727E701E727E70FC
+:109E90007DC8F9C1F94983DCBCBF20EF07B783BC9B
+:109EA0001F9C1FD4E87B03B6AB491B2EBC8EB43578
+:109EB0004A7942710931352F7326FC8BAD4E253519
+:109EC000D623846DF980998594D7F438C73CD16640
+:109ED00001BE39AE80F0A60504C7650FFA7FC95CE4
+:109EE0006EF8B3F987F09EBF43B0DE50A3DFAF3505
+:109EF000DA7B844B456AD4EFCC775D2F747CA31E4C
+:109F0000F3CBA0799062998F7893FCBB220B70AF52
+:109F1000608B4591F1B82B643C74285DADCA93E722
+:109F2000FB16CBF6FDE1885329513CB8EF9165153E
+:109F3000876C0580D392027EF72A2F565FD792ABAB
+:109F4000118765CCDBB04B129FE07B86A3DA84BD22
+:109F50009CC619FD85B0E3EF734CB44B7902EDA0BC
+:109F60006F0EF429DE4D41F4BD2C4F9E7B9AEFB667
+:109F7000ABCBE9FBC06D4BAEC6FDC589E1B2DDD30D
+:109F8000BF8966384E6E50F89ECEA86DC28BFBC955
+:109F9000CB757E3A709BCB5ECEE3BAF8DEA3D16F71
+:109FA000C98654BEA759225A0B710F450C55F83D6E
+:109FB0007C036EB4BED7B1BE2CDA2AB02FFFE0FB13
+:109FC0004F242E7E9FFB4FA387C61621AE5034CB65
+:109FD000F742270D2D59D983E6A5F9E57BA1A3BF4B
+:109FE00058F206E79F92EF8532F90CE7F9F179987C
+:109FF000ED53F8FD95C9BE8D960437EE652FB72554
+:10A00000A2FE36E1815805F508F78A8D75E58A16B6
+:10A010008B5301BD8803F141F4479C633AE825DF87
+:10A0200063E3F759A6585D36F01B43CE2971C9B1D9
+:10A030008BD451317CCF32444EB8D4D083E3627E8E
+:10A04000789C4E3BDFE75FBAD3C97285B65E61BECE
+:10A05000793E5FC6BB56DDF6E1704B7A679CCE99C0
+:10A0600034FF16BC037B267D7BF40885E588BD792B
+:10A0700004D7A30D2FF13DCD92956FF03D944B0D7C
+:10A080000F45CBFB6CD2FF52AEC3CDB03BCDD7F169
+:10A0900053AEC7691DAB93EF3AD339CCEFAE5C6AD0
+:10A0A000B0B19C112A2F1AF2A7F11E9110AE3FC237
+:10A0B000CE53D160E33BC00BD794AC4A1257CA9140
+:10A0C0008B75397351838DE3B22AF4F7D442FF6E56
+:10A0D000CF623D1E6BF156F3F74FF242E450E37D41
+:10A0E0004DBD4EC9DB0766B03CB4C4C6FECD39CB0E
+:10A0F000A57C24B60B3FEE93CC593ECE82F766E6A4
+:10A10000ECF47A942EE8E95D5D4E9AD8EA64F84F53
+:10A11000B91CC1FC65EAE514CEDF7C3999D3999767
+:10A1200065DC2AEE22816E5A8BE43B07EFEBF2D11D
+:10A130000CC4B1C6433EEBC9F4DD4EF48D21F2747C
+:10A14000BE35C0AB1C807838D1A6AD449CECC48D24
+:10A1500082EF834D821C45FDCF825C158FFD9156A9
+:10A16000C4F76126287CBF68D2D0DBF4FD40FB43F6
+:10A17000303FE1F757B4C2297EC439CDD2B65B80F7
+:10A180007F635F68BEA3FC5EEA249F62C73B929A2E
+:10A19000AE6F1B741FBA3FE646E876B2486907EB1C
+:10A1A000B09361B27824C9B76A26E4D3B9B06DF62A
+:10A1B000D20981601F952BCB7BFC76D5CC069241D2
+:10A1C000FF55FBC91C8B45DE3F233990EF0B88966A
+:10A1D000A29E942F59A314403F32E6F5B967EC389C
+:10A1E000CFB04E3A28EDD8A7F21EE5D27B324D7E95
+:10A1F0009BD0B48CE08DFD3437A6F5270A6168F456
+:10A2000060E12D1C81F7EB85F1285400F198B7E847
+:10A21000F9EAC13BFFB43A97E1C4F991BF7D68A662
+:10A220002FF25FE09373146BF0DF1B4BB268570D96
+:10A23000EEC1F750C703BF11B96DFC9E444AB64B3F
+:10A24000F2A9107B4BF56089C750BB4B59AE3C77E8
+:10A2500084D59D7A2BFB7BDC6CB734D67DCC66BE77
+:10A26000E76BA4F307EBE75EDDBFE79ECAC316F911
+:10A27000FEC26316FFF657885E2FF7D06660BD8F6B
+:10A2800021DE9EE7AFF1FA8CF74C3AF895FE6E8925
+:10A29000414F47965DE2FB2AA59176B71A444FE5F8
+:10A2A000AB15BE0F5ABA4CDEE7D6562BF25D846E64
+:10A2B000EC58BF99FDBFFC9ED56F7E112E0B75F833
+:10A2C000CEB1B7BCE148EB84EF9F973D60937C34FF
+:10A2D0009089FB0EB72C71F2BBD99F7B8AAB060F1E
+:10A2E000039E3C8CA771D8E5547F4B8CB604DF4BA2
+:10A2F00045CB41D81DE7FEFC6D7E8FBAB6398DDFA8
+:10A30000BF2CD995BF0AEFD97CEED17E82F5974458
+:10A31000BAEC90476A1A62F97C9EDB53BFCF2BDA06
+:10A32000D8CF67E0E7BEC1D28E777DBE1CE7A2AE74
+:10A330005711C06C534CF5BAB6631AF6D1503B4B6B
+:10A34000E8BB21DF655781DDC41E645F35EC32B6A2
+:10A350009C63B371AECFB177FDF73EF7EAF337F404
+:10A36000DAF91D7A6DEEF89E90FFD72A2ED8D3CB5E
+:10A3700023DD3371BFA1FC900D91B462629C5BBE82
+:10A380001F738F7C3FA6F48E7CE66773809302DC9C
+:10A390003B19C9FBB8DC4FE990EEF7FBAD6B0FF44E
+:10A3A000D90D7A0A78F91D827297D71E17241F9546
+:10A3B000352AA677248CFC0B8355C99748DD00FC11
+:10A3C0007E7C479A1D6F39CD213109F1997B412758
+:10A3D000C33ADB513D8E3F99982E0ECAF7BD14FE4D
+:10A3E000BBE4182FF8EF5B95369ADFC3A0FA2CDF99
+:10A3F000ED1A1CC5FD95B868DD69485D3C4F8203C8
+:10A40000C3A9ED3EEACFCDE3303ECA027E1BEC0786
+:10A410007310F742F95B5C7E1BC6296D90EFD46820
+:10A420006BE438DAEA58FB20C8075697BD4FB05C9A
+:10A43000D820DFBD9EA3FFDD119A2FCBCDE50427E9
+:10A44000DCB333EEDD86C2AB449F7F7963AC59CE7B
+:10A450006C5C6B037E6677F35EC639DD0E5DDA30C9
+:10A4600086DF3728B77AF9BE8AA6C3FBB3DB9CF731
+:10A47000C25F327BDD23B634CAFF65B0946BCFE98F
+:10A48000FB71627A2093DFA9BACDC9F1E3B35D8D88
+:10A49000BCDE0E783F44F081DCE22A6678139DF83A
+:10A4A000106F59BECE8CDFCEF944C977FCD795F03A
+:10A4B000FE5B60D5ECAEE079ACDF9789F8A1D9B44A
+:10A4C000EFF10E9770697C1FF6C44333F9EF056214
+:10A4D0009E1CCFE6718FC7BB5344374CD706FD187F
+:10A4E000F7F38DF1AC1EABB4C77BBE6B9F7A0F4206
+:10A4F0004EAF277CC30FD0DD3EB5E302268D6B2F18
+:10A5000097EF075EC1EFF4FDFAFF016A916CD3008B
+:10A51000800000001F8B08000000000000FFED7DA0
+:10A520007B5C5565BAF0BBD6DA57D8C0668BB051A4
+:10A53000C00D0262116D10101575A1805B736A6306
+:10A540003729C48DB7500191ACA89FF3B10D6FA905
+:10A5500095262A9675B6A68D957570B2461B9BD921
+:10A560006A9A5D0F3A8DD33953B6CD32BB09D234D6
+:10A570009F7DD399BEE779DEB560AF0DA475A6F9CE
+:10A58000CEEFFC3EFCE3F57DD77B7DEECFF35E7630
+:10A5900022634CB23136789883B1818C1918934577
+:10A5A000C83FA177FBED02639571ACBE2D13D22895
+:10A5B00056FF6B0B63DFE3DFF89E74A253642C8FAE
+:10A5C000B1DBA05D1B7CAF10D9ABCCD6F33DD3295A
+:10A5D000D0F78A1436D31DD41EFBC37EE3D5EF1308
+:10A5E000FC698B337BEAABE356D878BBA9D07E9A63
+:10A5F00005EB8BDDF51BA83ECFB3E92691C53236BE
+:10A60000DB04FF87A594487B56C4E632D6B057706A
+:10A610001AA1A8E14189B118489F8BF0B164C6BE68
+:10A6200068F8CD3BB740BDCF376FAF64437BE635AD
+:10A63000C73F8A39463036F75236730C606CDEA558
+:10A640003194560FF364380706D5DBF85CBA07C6B9
+:10A65000BFAD2DFBDC7F305AB79FE530F6FE73BFF0
+:10A66000FDE368E897319FDE7D4DCF3A66AD3EA1B0
+:10A67000AFB204C38DAF734D4657158379CEB6186C
+:10A680001C1214CD5E5EC5649827B333671AE413B9
+:10A6900075CC2B42BF6CFD16D904EBF330FE57B5D9
+:10A6A0005C90A95D63BE4F82F50C867AC61C5EDFA6
+:10A6B0000CF0F7580C678448A8E82D910319BCCD1D
+:10A6C000F7293DF81D0CA921A707EF890A1DCC5ECB
+:10A6D00057066D7BF0050333960FEB651CAEEAFC65
+:10A6E000A72AF3BF6DBD20FBA0DE0D4E07CF572775
+:10A6F0001BE6C17AE7AC4F36CC86B45CF95E3E47C8
+:10A700005BDE8D2FAB8AAFCC9576584F571BC75762
+:10A71000D73A3DE1AB6B4F2F7C2531A9671E7700FF
+:10A72000BED8008E2F3682E30B53C057A5332FA817
+:10A73000DEBF707CCD7EFEED0F5E76D0FAA8FFCE38
+:10A74000078DBE1DD0FFACB6BD84B7F2D51BF4C9D2
+:10A7500050AFCE994C7051DBCFAECFB63280E76DA3
+:10A76000ABB7EB1D16FCEEE893EE219559103F4177
+:10A770009E099067BA40BC3BA2A77E39A47B619C2E
+:10A78000258BCD91ECDA9E71B628F43CBB3EDA867F
+:10A79000E3CDAEAF7A886571FA7767F6E6BFB36648
+:10A7A000CE17B3A03FE4CFB345CE24E48B0A51D4F7
+:10A7B000F09B9A3E847883793D06E03523FEC3DB27
+:10A7C0009E46380C5E14E66C864FA9A9011F8E8B3D
+:10A7D000F48CF33688CC6B827AA935818B388F5410
+:10A7E000A0286C8769848D52160BF91D30ED024844
+:10A7F00053249EEE73F2F5C3773F7E6731813C5C54
+:10A80000BF4ACFA1F46A603B57A700FE0D31CCD9F7
+:10A81000ECE8A14FB51F953E55FAED6F7D7BAE700C
+:10A820007D6793393C598633C904E3563E3CCCB925
+:10A8300046B8FC3A0D61000F5BD07A81580B6C7DF5
+:10A84000AC3735905776CD0FADB7A524B68FF586CA
+:10A85000AE53E5933926CEC3C02751019877D7FA76
+:10A86000A1510CF12D302FCA9DB38BCD22CE5B5D53
+:10A87000D7534D5019E6B6BBC944E9334DC068C340
+:10A88000003E4D76CA3FDFE4A0B4AD2983CADB9D0C
+:10A89000369A3F6381886980A78A3085FFFD3C8FA7
+:10A8A000E56541E5536D9CEE4E5B0311B62039FD25
+:10A8B00071BD790D8B42FA0E3C88FCCC1A87B25DD3
+:10A8C00030D4E9F56723C44CA44F3E3FB5DD127D7B
+:10A8D00027C93F166170EC02969BB124FB7423E0FC
+:10A8E0006BEEF2382790129BD13894E4C20C6FB40F
+:10A8F0009300B07E0B4378CC53E460F892AA952382
+:10A90000B17E6BB2558071E65A9CE75AA9FDD5CE4F
+:10A91000FBF17B4B99212593AACA26906377287275
+:10A920006C89C0DCC88777A09C44FE120FA5A2FEEC
+:10A93000B9A355F01B29CF560B00D721CDEED27805
+:10A9400094135B05E70E6CBB0DE4A9A9479E760D39
+:10A95000737F817A817D07F407FD5F252002715D99
+:10A960006D721CCAF14D827517C379B90D089F0528
+:10A970000A9D9C6E3913E1C8EC81EBA3F85F10656A
+:10A98000CC238B286F1B143D86644079454E0E31D5
+:10A9900070F841CADA113F3AA709E9A0CB9212C573
+:10A9A000FA286F884889C3F239AD12C945959EAA25
+:10A9B000D535287C3317BEA3DE2B912A6291BE5673
+:10A9C000B64CA474CE8692CD5EA0E324C11D3B9A02
+:10A9D000D6A367B89E39B513AF47BC55EF30469B39
+:10A9E000006F497A6F524E103FCED9BE2A8941BBC3
+:10A9F000F3DBCDD351FE175BCB8AA3A1FDBC6DD198
+:10AA0000D952901E49CAE67A6441EDC43806F0ACCA
+:10AA1000F9FB9127ACA08FE7429F56E8FF9BB670E9
+:10AA20009F17AAD434ED4F9280E7DE3179E2B3A1CB
+:10AA3000FE42F1E02DA3501F08BEA7E2A9BE23CE1F
+:10AA4000DA873C50D373C00F0EA0F7DAFFF51EF57E
+:10AA5000F395F8D6F5E5D0BEA6F68548EC67E1A6F5
+:10AA60003FE45BA1FCA0E849C3FE3F17B63F654544
+:10AA7000026CDD9E857A7CEEA6B4284F1FF217F992
+:10AA800000F151BD5F20F8AAE5337C510684BBC7B5
+:10AA9000CF0C564CADCC80F47E5E628D680FA8F66C
+:10AAA0008C5A3E329BCBADF351EB93904EE63FB5C3
+:10AAB0002509F5CC67113C5FF1D4AD6FA0DCF2EC59
+:10AAC000341A10AF1E1D3338519F7941BF221D55D6
+:10AAD00003FFC693DD61AE047A2ACA0E27B8CE6F93
+:10AAE0001D41FA519D177CA7F2CF74CC85F318D283
+:10AAF000DC998D74FF679D7F2EE2F3CFF566A71773
+:10AB0000F199CDF5DB9FD74BA558EE0586417BE447
+:10AB1000CFEB5F8848B5F4D86F25D2FBB28476D6E8
+:10AB20008B4236EAEDF0CC76C32CB21B18D1599D7E
+:10AB300095D359C3017DE9E018B2C7A8A446E73709
+:10AB4000F485AF058ABDD59DDFB7D7807C52B3872A
+:10AB5000DB11356D67C88E50ED925A859F17EE391F
+:10AB6000437685DAAE6E1F874BED3E5E5E9501C87B
+:10AB70001DCDE5800042BA0AF105F9FBFEF5D7D3F9
+:10AB80009769F27B297FDFB5562E0F759D49A8B7CF
+:10AB9000D6649C3420FE6B972BFD425E1F34DEBCD6
+:10ABA000EC81042F2C1F6AC1F60E8DFD50BB2F9A2D
+:10ABB000DAFB6BC356A3BE97EB2C3A4C9B6B2DA4D0
+:10ABC000FFB7D58B19BA5C9C5C9813EDB983619182
+:10ABD000592847072E3C650648026A3B8F8850BEBD
+:10ABE0003ACA732FD2671C03AE90506FF805B45F5A
+:10ABF0003B5EF97404F63F6E48E06B0653D70BBF1B
+:10AC00009B5E0CF26419982D641F670646201D0F89
+:10AC10003CCCE5F4E37AB61AF51BD3B9D93428F75E
+:10AC2000A3DC423C7F1BE6DB05FFFF1DF30FC6FEE6
+:10AC300099C93F14DBBDA4D0A7DB68592DC0BCAEB9
+:10AC40001EEA59834BBE41D05F932D220EA434AC33
+:10AC5000D7A1E7DF557B758222A713C18E40BBC801
+:10AC600030C86E413A6E36F3F509B2CC1A611EF760
+:10AC7000671E9E8D7A7A6DA78919619D133AC3C8A4
+:10AC80007E4D1CE422BDD66C4E22BD2D3874AC0224
+:10AC9000EA1FCE14FD3AACCF4C3EACCF4C2176AE81
+:10ACA0006896B19D70F0B56F51BE0F962E1E8982C9
+:10ACB000F50DBE477036439DCAAE738FFF1BA415BA
+:10ACC0009776ECFD5748FF2DCAB313E17ABACB75DE
+:10ACD000C603A85B6B6D3339B9DE60C1EB3878EF22
+:10ACE000B79136B1677E1D9DE79EFB4D2EA62627A8
+:10ACF000EA9F090725D21FA1F3E9B0C3C487523DDB
+:10AD0000B23B3B2CA24F10B0FE91F7707E134C1655
+:10AD1000BF84F6BA49FF65B07E618EC4E87357936D
+:10AD20004A61DF8391108B93477D74D14276EB3873
+:10AD3000850F553A7B2B9BDB8F6F297255853373BB
+:10AD4000C82C58AFA8F06CD6ABFA2210CE327BF8E4
+:10AD5000769152AFEB9228931D5E6DF431E8B2EB21
+:10AD6000E050D233FDC9D93FA0DD01F6C4F254F959
+:10AD70005D842753F4EECD0AFC54FD2D29FDDFAC94
+:10AD8000C0F1668BC8E1765308DC147A0AA5971ED9
+:10AD90007A8841DBA31BCFECBEF6A351C984DF6BDD
+:10ADA0001EE678FD90F0FAED5B2B80CDD8A0BF4D6C
+:10ADB00021FCFE0C78F58BB93F02AFEDA178F59B35
+:10ADC00087215E37896467A01D8876A307E5C0B533
+:10ADD00094E7F66006233951298539D724E3778033
+:10ADE0004316C987A3281F54B930C415B806F5E91E
+:10ADF0006970E5717E01B18D97E7A4105D24B0F60E
+:10AE0000782C07BCE7A17D279986667E0C72B7E592
+:10AE100001DFDEDF403FCD826FEB3C988FF7668B22
+:10AE200013EDB70E9FE8D5C33C5AA259D67E18BF82
+:10AE300065FE554E2F9633456E4C37F8D07E83EF26
+:10AE4000498DF8BD9C7F7FE9EF671F44FBAC338DD4
+:10AE5000D1BA5AB2593ADA672D6519F4FDB7AADCAE
+:10AE6000793082B72FE3F4DD32DFE6433DF4E8A327
+:10AE7000BEE1A8275AB6CBF136480D519EF81C9872
+:10AE8000FF2089D37D4B329443BA597097CFC57E4A
+:10AE9000AEE1F30D94873DFF1474654E05D106E5D0
+:10AEA000A71B2376A05C55E974F0302EDF8778CF9E
+:10AEB0006C45387927B08C7AE8FF4385DE54F80B6F
+:10AEC000C0368D00F798103CA87417A3C05F58CA0D
+:10AED000E9CF3B41594F1DF3A1BF910053090738FA
+:10AEE000571AC1F0837496D5938DF36F5E0CF89169
+:10AEF000701D1C0FA74556DDD6075F15E628F10D1E
+:10AF00001802F9A69271BEA944BA427A6C04BA0A30
+:10AF1000A2471648883E17AED015CA8308F7B81C5A
+:10AF200058E757C21FF2B1F0ADFF94A6F735CEA493
+:10AF30001C2E2F1E337B4A7348EF4DD0D89D6F6572
+:10AF40007F9A88FAE5F4BDAF25609A14E59E8CEBF4
+:10AF5000D85CFED75214FF1FC607F4B88E0FCBFF84
+:10AF60004F22DA2D954B5F23FABFD2799699983705
+:10AF70001CE01E5D2C38FD00BF792D46E724F81635
+:10AF8000575C750CE159D66A74189156D8628D1CBD
+:10AF90003B2B8F40378A1DDA6A24BA39F74B89F484
+:10AFA000C1B9928BAF0E800FE756084EAC57D63220
+:10AFB0006C2590372B2916A85E9957A07A65A91C95
+:10AFC0005F271A05A23740AF253B28DE31A7F58E53
+:10AFD000A988DF13C55F0FA4F8C17A1847E5632E6F
+:10AFE000DE489E9529F5AB561B9147BBBF97B5AC84
+:10AFF000BA88FC3FD31B52DE3AE953ECB7AC515B45
+:10B00000EEC635821D77574E440CCA07E664CEEF74
+:10B010001148F240F20FFA93BB407144CF300FC297
+:10B02000C389BC617AA4EB990857A0DBE8A57CDD55
+:10B0300033A70ABE49B0CE9916CE671F9609BEFB4C
+:10B04000053EFF0940EF65501E0B745D16C3E438E2
+:10B0500048DD26E60FC7792E1DF609CADBD338D4A2
+:10B0600028AAEF8FB4A15CF7E81189B7322FA5E5C4
+:10B07000CC47E9EDCC4FF398C13A937490AF93FC71
+:10B080002B318EF32BB36703D2D75F8B4E9C16E028
+:10B09000FBDD3942DE2894438D0368DD975B1F702A
+:10B0A000A5807606AA41AC5F96E37E14FBB3CA4C3A
+:10B0B0008F71AB74958E5A993715D617BBDEE29B0C
+:10B0C00004EB8B6BF51CC2F5A64F373810EF8313DA
+:10B0D000F83A1374DC9F3F546E60A3810E363F181C
+:10B0E000E6433ADBBC3520DAA1FEE6038001CC97CB
+:10B0F000AF14BCF0DDEA614E8CD359751E11EDFE24
+:10B10000A2568F1808E2A7E1B241443991BED32379
+:10B11000A29EB45AD7533D355FACD44F3779065908
+:10B12000C94E9E4EF4335CA11FB59FD456835F0475
+:10B13000B817C94A7D99B757FB618A9E56DB6139BA
+:10B14000D2677AABA34F3F454D5B503F838FF808E2
+:10B15000C605D27BCA1F71FDDA84F01B78F3AB36CB
+:10B160004C370321F8711C9DC74CE379F83CD3158B
+:10B17000DA87BFBF7F8FE3631EF0BBB9F5FE22E421
+:10B18000A3CD001FC4F3E69DB3CCD4CFF4599A7974
+:10B1900031A986F22508074BEF753CA2CC2F3DD58F
+:10B1A000235A69BDCE4368E7A5CB8CE2016A3F769E
+:10B1B0001D7405F46A777A857ACCCB905A94B84797
+:10B1C0003A8EB34E40FF315DC157496BFD6133F696
+:10B1D000E366145F4CCF85FEA1FE268483A137FC75
+:10B1E00042E7995ECCE77342A9DF8EF194746CE775
+:10B1F00058114374C5E7D7D5EA14621C97B18FA0E4
+:10B20000FDC9907E9EC2B80CA4CF4E7E6D4A2EB46E
+:10B210007FFED19776B4D0520E3EB30FE556ABF514
+:10B22000E69B709C83229FFF4D72E25D98DF6D204C
+:10B230003D9ABE534EDB44799313FDEBAE56DF557A
+:10B240002F42BD2C18C664EB3D8F130A9CDA153AC9
+:10B25000383979CB205CEF5345772C5802ED875F66
+:10B26000F7388D3B7CCAFC9416C80F9BF8CBAB30EB
+:10B270007F5F8EC73C02E4FEB0D25FDEB60FE56AA8
+:10B28000E9FC1C8297C57645F2A939DAE3F502BFDD
+:10B290003747DC528EFCB8D26670482477EB19FA37
+:10B2A00059CD1177DBB1BFE5D1F9264C0DD6BF36AC
+:10B2B000A19C3C6EC931211E9A2D131896EBAC0A45
+:10B2C0009EBE1B4FFA40528872778473BA4C74E565
+:10B2D0006428270C0906ADBCD671792FD91D3EB460
+:10B2E0009FBAACF54881CC600954A07C935479692D
+:10B2F000717A713CC9E2B4A3BFB44291372C86AFD6
+:10B30000D36039F79F38AF5EFD632E96504B7F8632
+:10B31000B0CC2841F93FDA9BC6103E575383C5BBDA
+:10B3200018F544687F5D2070508EA34F4776337EBA
+:10B3300048EEDD5EB21B347AA45B5E7AA2F521F2A0
+:10B34000521E817AA2582079E961EB0CB8FE120CEA
+:10B35000B2005C3CDBB85E54F97B26CE05F0E549D3
+:10B3600065915C5EE9E473260EC6EFD1AE5C2A45BA
+:10B37000221E025EC9E0E9C39FF778937F501E9DAD
+:10B3800041FA87A90790FE21FD44E10F8F8A076FDC
+:10B39000D9F5A3505FCB12D90395CB8536B4CFE254
+:10B3A000BCD14769BEC5DC2E6897BFA6F51C2A89AB
+:10B3B0004B44797962D999C7EF41BDBE299CF4FF0E
+:10B3C000A4A56756603C6EA657701A21EF591A7DE6
+:10B3D000F77B986F343A5D903FABF081FB974591D6
+:10B3E000684F08B8CE8C9E75561632839BE239F1B1
+:10B3F0003396403B4FA3E0343B7AE0A1C77A52EF4B
+:10B40000F505BC3746FED0FA3FBCD7A8C859773EF1
+:10B41000CAD9A2C6E4870A705DEBF57C9E8DD1D7B0
+:10B4200053DE27393976B91C9EA9D83F9EA5B3575C
+:10B43000C6C3F7C06A41F9CEF156A9C8E540E38812
+:10B4400063183F0D2C17483E79BC52A21FDACD5C21
+:10B450009E4D78EF280A905DD8E53DB4925A2B7244
+:10B46000DEA37436178C58946FA7DFE3FE9F47FE68
+:10B470006325B69BD3A2B5832602FD0C40B8BC67FA
+:10B4800026FDE9F196D1BAEFF04569EA55AD8ED3C4
+:10B49000E43DAB8BAEC7B0E7AC7B27523CAF9239F3
+:10B4A0002291DE2A656E37C19F251BE633579D4FDB
+:10B4B00031B7C72A8BC17EA2EF5A7BB0C7FE893352
+:10B4C00020DFA87854F1133AEF5E7619E376D0AC1A
+:10B4D00075DA7ADD761030168ABACAE5DA76BF32C6
+:10B4E000BB9F45B9E8DE38E01BF2ABAE501E828050
+:10B4F000217F6E26E3711FA6E843D5CE2F597A51DE
+:10B500008F726866E3453DC273E6D21FE6A75F38D7
+:10B51000B5F3BEA1204ABB3E394E93BFD13544534B
+:10B52000FF66F730CDF75BA75FABF95EEE19A9C9EF
+:10B53000DF5E3D5E537F46FD24AD1C7A379AD6A36D
+:10B54000E2A7BF79BFA5E8A37742EC12359D3AE2A6
+:10B550003F1391BF3F2C67E4BF7C7833D3F8311D94
+:10B56000232482E7805C3DF931F7E5C8EF8F20BFE7
+:10B57000C94FF4A1C2F34373A1C928A27F62E47E3C
+:10B5800079A85F729039505ECED4B1FD42548FFFDE
+:10B59000670EF39CC7FEBAE30D4B0FF17843881F8B
+:10B5A00073A578FF7006CCBF0F79794D2EF7C316BF
+:10B5B000EE36AFFF38088EB56DD19AFCA2FDF1EBE7
+:10B5C0003F0ED63B4B041DAEB346E1935A16A07D09
+:10B5D00052BBE8A0FEEAC4402CE63B58676CB4F4CA
+:10B5E0008F838B0A0F808F253728DEA9FAC33F1976
+:10B5F0003E450A9ECBB4701A93CBE3905F8F10291F
+:10B60000DD9C23C7E7FE03F11CB49EF4DCBC7FDCA9
+:10B610007A2247C859089F9F1BAFDFE31E0F94177C
+:10B620008E900B7F26B84CFE47C2A547CF472FD838
+:10B630000DFAA3729D81FBFDDE335CBF3772FDFE08
+:10B640007CB48FF6879BF344E70E07ED97D23EE973
+:10B65000A17B8D611918DF59A1237D797A99908199
+:10B66000FEC226218CFC360FAB4816C8BEB978C87E
+:10B6700048FD31AA07EDFD3A90F351053E6B09E410
+:10B68000DFCCE571B1356E714A8A03F5F61FAC1E49
+:10B690008A8B7AE2111E9EFD30E16B69DF45EE2B4D
+:10B6A0007E12D06BE5D112858F5FCCD5D13A1F2E9B
+:10B6B00014B99D942ABA701F6315D8A968570696C5
+:10B6C000EB285F91C7E9596DF71F0A9DC794DD14F8
+:10B6D00086F388DA24BA7D7D8CFB512E8F0F3D795D
+:10B6E0005718EDB3012A7468EFDBBDD6692E58AF49
+:10B6F000BDD0968DB6DFDADC68EA6F4D469715CF80
+:10B70000A1FC8C7478CA8EFEA0C0FA8C33CD55E6AD
+:10B71000ABEE0F5894FE36E941BFA29D2298281E39
+:10B7200061F11AF9F91567B126DECA1C020B6EA782
+:10B73000D6F328F46AC7421BE197F6EFD578B15DDE
+:10B74000A117A41BC4BB4ACFA1FD8389EC8DCCE912
+:10B7500089F3D915528E1AE5D98D748FFDEA901FA1
+:10B76000BC5CFE076EBEC4E32CDED7DEC37988E185
+:10B770005F529C0CEC4ACE5F4B43E2BE3F914F02BE
+:10B78000660ECF4084561EDEABD0C9DA7F82DE481B
+:10B79000BA02BC3E9CCBE58FABC0FD36CA3BC7B2FC
+:10B7A000D430A2FB1F0B2796604538515EBA723821
+:10B7B00079F33D1F109E74CC6FB4717F0BF9E17269
+:10B7C0007CA4C23149649EBEF4F2883CE5FB1BCAEE
+:10B7D0007EAEB76AC80FD9612877C502C6D22CCC15
+:10B7E00061BCB6FF7A0E9C8F85E86A39D2E5AE96C9
+:10B7F0009430E4CF6465BCCA9BD2A70C77A05F20CD
+:10B8000018D00E04BFC3C0E33FDC4E57E57A4FB9F2
+:10B81000D67EC4724F668F1FA6DAF7EA773C97820E
+:10B82000E3AAF359A5D861FDCD7755124B72A2DC7E
+:10B830005A768F80F0DCB15AD4F87D715E612503B1
+:10B840003F3ECE7FAF13FD8E38B0AFCD28CF75F51C
+:10B850008233085E817B810A381387F82BE04FE240
+:10B860003ABD67895E42C757D7B1AB858F1BE75D8D
+:10B870002CC8909F54512FA0DFB756997F5C05A329
+:10B88000EF69993E01E3219E16568AE3555633032C
+:10B89000C6F52A33995386F2CAC64374DEEDB9025F
+:10B8A00039256F20C94F3A4FE32AF0A4E7011D4D17
+:10B8B0004D28437667B84B86F1897F161DA7B54C96
+:10B8C000F0A2EF59D4E23C84FE01D011C57D3C2D9D
+:10B8D000011A5FE7E571725D8BC1E98075488D657E
+:10B8E000B4FF21551B9C32D43BB629DF8FF1952D37
+:10B8F0008DDCDF0DF59374D6FAD7C3D15FAB109909
+:10B9000044010A792AFA5956852E5630773BEEF7CC
+:10B910003319FE41BB48A5DC5A3D6F2A6622E5D0AB
+:10B920007883DC139F409E6BDC40B2D394AA8D6772
+:10B93000482D2BC9AF33627DA8AC0F897748D5A5B8
+:10B94000141797ACDAF25BF32262088E593C1E9E04
+:10B9500073EF888DB7C27C727F79E31F303D8741DA
+:10B9600033805BFEB23B074C87FF16ACD87823A62A
+:10B970004FBCCEE89CC18FE057668CFAF1FCFAE828
+:10B9800095F2ABB2260FD0B9C2AF7DD2BF1A4F0924
+:10B99000E54F95FE43F94E4DD75E867FD7260512BB
+:10B9A000910F4FDF3B3203DB5736DE73C8C7885F2A
+:10B9B0000507D077A577711123BA605697D05B5EE3
+:10B9C00084370B49ECBF371F3F867C3BFEEFE71304
+:10B9D0007F08DF95098CCE6381FD49F69C9AAADF2A
+:10B9E00023F2B93EBD906724BC4E46C10AAC3B056C
+:10B9F000DAE0BEC778604E2BA47F2EF03C8BE34D7F
+:10BA0000813C9EEF7BFD406B0CAE374BC7F58EA79C
+:10BA1000DB8EE67648B7FFA8D80F59063605EDDC71
+:10BA2000C02611776E59E0C0E73BD6E2BE6BB9C9BC
+:10BA30009906EBCABADF48F484048AF6519668A7DF
+:10BA4000B8E5AEB68FCB699FB1D1C0D2286EE00EFB
+:10BA5000C3736400CFB0AA4CB257C3AC68AF7A8549
+:10BA6000A4AA881E7B08F5220AB42CEFAD53AC3093
+:10BA7000FEAE42B047337BEC1CD5FE599C9F4CEB8D
+:10BA800057ED2068C7B0DD8FE5A74A0B4B22BB19E5
+:10BA9000E683FBF7B64C2690ED1352FFF43223D920
+:10BAA000AF76AF7BCA70B45B97A7E6A0DD0AE39AD6
+:10BAB000246E7FFD3BCA67BB4EF95E28E6E0B949BC
+:10BAC000751F800574D1188753EDAAFEE7A563E7BB
+:10BAD00054B905957F9B2F9FC17EFF5972DD635539
+:10BAE000E84D4D63F879E0E90ABD8DCF37539A9E52
+:10BAF000FFB3DB73A7AE93FE79EBFE39D7E1FA9F74
+:10BB0000B18ED8FF21F8D83CF97FC63A6E99F24F32
+:10BB10005C87375F6EC8CF4379D646E788EC2E7EC8
+:10BB20002E1CE4DE3DBC9CCB398B930964C7FF74AB
+:10BB300079D784FD9D411F1CCFA17877083A1867FB
+:10BB400088A5A188ECCDA58CF681862CE5FB404329
+:10BB5000963A4D22DA03166E270E52ECCE414BB9BF
+:10BB6000DD19A79C2B888B117D32D43FF6CB5BCAA5
+:10BB7000E7C6E0BE9091ECD5E636DDF516D4535E0F
+:10BB800089CE8F86DA89D2D2954A9C5F6B9FAAF6BE
+:10BB9000681AE379FDB2B3B44FA7DAA34394F2B4C1
+:10BBA000A57C3F60488BD61E8DABD6DA8FFA82100B
+:10BBB0003B73A9BA7FD049EBD32DD7E9F1FC7FA81D
+:10BBC000DD897BB0A81407AB7A06B4FE4DD730F6FA
+:10BBD000747EF7F98C1CDC1F9AB95AD0E83955CF1E
+:10BBE0000224287EA4E2E343D473883FF734B55F90
+:10BBF000D26F3EAF48704C2E4FD79C5362EC7E1EE6
+:10BC00002F71733AFAF5EA116BD1AEDDB7EEC63794
+:10BC1000317D69FD9DE1E504AFF5546F7FCBC6EB47
+:10BC200030FF5076BB3D12E6F5D0A853EF09D0EFB8
+:10BC30006A3CE385EBB378298FB6149E8BD0B37A38
+:10BC4000DADFDBA40F4C9F0DE52B12451C91BE23C0
+:10BC50001D9832189D9F3059787EF5358CEEE33073
+:10BC6000E55C9F1A87093DD7B7CAC3C75905F0C419
+:10BC7000733596187E1FA939E1FEE908EF668781C2
+:10BC8000E139398B72EE4F62D5AE2AA877DC7EBFE0
+:10BC90007D16EE0B6718887EA498CE26C493D99E95
+:10BCA00063AFC27142E235CD29E9372059BCB5FBFB
+:10BCB000F09E67207D7BCFC92F319D2AB5EFC3F35E
+:10BCC000255246889FD26BBF9811DC9B87335F4A11
+:10BCD00032963B6E10914E75EB6F9A86FE54C150B2
+:10BCE000E71A584F5802F31B601E61BDF689797B35
+:10BCF000A9209CCED54896F5150DD8DFA808BA7FA7
+:10BD0000C0BE03AECBA7F34DF457F680A8473A0E5A
+:10BD100053F68FC3327BED1FD3FCC2304DE1593B4C
+:10BD2000E4C3157A5F637BCA87FB776B13526E108F
+:10BD30001D3DF5695F19D6BBF2BB1BAB685FFD26E5
+:10BD40009315CF9F8529FBCAA1E374A53A5B67438E
+:10BD50006AB418647316F1550F5F72E0D85383E626
+:10BD600001F5FA9CA73A6E731EC783DA9FD1C264AD
+:10BD7000B42343F7AD43FB817970BE56EAA9FD3188
+:10BD8000D646E70174888B517DB5ABA7B90DDFE9C5
+:10BD900024BB1FFF82E382CC1A43FC35AC55DBCEBB
+:10BDA0009CCACF0DA8F4182A2FA5D0FDF7D47A6F1E
+:10BDB00038E1819F2708AD1F0AD7D0F6F0B7335876
+:10BDC000DEDD60E1FB885DA99DB922AC7BA53D4726
+:10BDD000337F5ABFD0D37FEFFD3C6DBE4C36F6B9F2
+:10BDE0003E94077DCD77824EBB6F596CD1B62F8DB7
+:10BDF000D17E772568F39245E9DF916DA2F31A8E23
+:10BE00007C139EF753F9D818E2EFF78ADF2AFA2E4F
+:10BE100091C9741E7593DE790EE5C4E33340D201F7
+:10BE20007D3C2CF8CC582E55B45B510FC6ADD39346
+:10BE30009C7AFCAE5BCEE0BDA016A06B84E571F7EA
+:10BE4000479B6EC57CB148F10D9BFB7039D251CB3D
+:10BE5000775FBF371BCF9F3A0D74CE5B3DB7B1758F
+:10BE6000AC612B1E0B8ACB94CD69F0FDA12AE68430
+:10BE700099B02363632371FC2DD1A215F5DDF3D1B5
+:10BE8000F5FF8E7194E6198CF61942E15737D246C8
+:10BE900072366E75B680F75B1E1E9B5F8972310627
+:10BEA000FC6594AF90CA7DC517C715F0F8C0B6C53C
+:10BEB0002FC523BE37580FDB699E15A213A7D85292
+:10BEC000C1E57F8B85D13E7BF3A852371E4DEC72C6
+:10BED000C90E3C8BD8E2DE41F35E592D72D9AC9C81
+:10BEE000970158C851399CBE0C364AFD986E34B340
+:10BEF000F839289792C2E87C507FF681B484CB57FA
+:10BF00006C6FCCE9BFDE43118DF1C85CCB67E49F59
+:10BF10009F0BFD6D9DB199F2AA3C8D53E8BBBBDF31
+:10BF2000103DBA1BF04B72361AE42C9EC7638E8705
+:10BF300089B775F5C2B4203AD555807CCDE2E72E9D
+:10BF4000307EBBBEA834E387FC4C9D9BCBE51855E7
+:10BF50001EBBEB9761DC05DAFB515F633F78CE0FC8
+:10BF60005219D7B751A83F447EF30C8303EF39E849
+:10BF70002A400E437B5D82564F1C18C9F135FBC128
+:10BF8000BBCC9EA0384D8C721E66A3BEDE9C06EB19
+:10BF9000D93843746E07786CA96810FA8AC7C455FB
+:10BFA000707E990DF5D16FDE5291131BBC9E668C8D
+:10BFB00073C0D036D70F9FDBD385C8BF5D2379BC54
+:10BFC000BD67DD1CBE71403FA8879A4797AEE66A01
+:10BFD000DA41725567E56D6DAE7A3A07D955C1CF32
+:10BFE0005DAD13F87E82A4C4CB9B8BF249BFF44BAA
+:10BFF0002F152B499F84E2579D3FFDE507E91199D5
+:10C00000F1F119879BB4CE4CFAE107DA3B74F94A97
+:10C010007DD40B1E6D7FBA625136E3F8A85F10AF76
+:10C020003AE6C57B93A1FD952AFC163A1FC969E043
+:10C03000EDB19D8DF88BF4DB6901E0C8E982CEA1FA
+:10C04000B3F7383CB7243A7C6BF8012ED28774AE34
+:10C050002BA5F7788F098E65B8EFE87D5DA2F3E731
+:10C06000A17A4FCDAB7030B136E79C3EEC4D9C0FC2
+:10C07000EA3569A7D789FA01D0978AED362A4B09A4
+:10C08000BBB3D45CE0E8ADD7BA5C6DABAF82729362
+:10C090008399F6033C4C53997F30C079ED33CF1C24
+:10C0A000BF8AF53D0EAE03F899E0BCE6F94733E6EA
+:10C0B000407BF3EDAD26B4B943CFA1F56EEFA47686
+:10C0C000714BAB4CD319C5236554B986080BD9AF56
+:10C0D000CC7486E4B334C9C6EDA7103DB90EF85050
+:10C0E0008FF04A6404AFD03871E8F84905C9FCDE26
+:10C0F000E4E2521A774345A71EE3905DAE7AC54E3F
+:10C10000F2F4A9EF42FBB17B3AA723FF77151AC8D7
+:10C110001E7EF8C1499311CFDE6512C5D17AD17B5D
+:10C12000C8BA3D23F59CAE1C8BCD287FB7CCB9DBBC
+:10C13000ECE8C3FED852318BCE2F5A96703B63A5E4
+:10C14000BD81E488A542B9E7A2D8CB71AABF13A2EA
+:10C1500027B7543798F1DE9B7ADE9085D8DB97EDD0
+:10C16000BF1FBDBB61F98BF1A84FEE2A6988C77963
+:10C170006F89F04F7713DFD5939F02F2381EE5F1F8
+:10C18000A2910E922FDDF27FC6393B0E1E18695523
+:10C19000F88ADB435FE27F41BF668D92A714601C83
+:10C1A0002DB5448E7660BC74DFBBD300AE93BD7AF0
+:10C1B000F2638DFB81F4C12F322638495F9E1E68E1
+:10C1C000B0229DAC6AFC468FF76BCEE2E955E87F62
+:10C1D0005502B78756C51898DF42F3A1454F752E13
+:10C1E00066A8A7F509DC3701BFC58F79162310FDB6
+:10C1F0004C8EF1BAAD00872931BEBB30AD4AACD709
+:10C20000D9609C1247B480F09DA263C5061EAF9D05
+:10C2100085F35C11F311C55927A7C5D17D54A3C57A
+:10C22000ADC3FBC97A67D5F6B58CCE8B51BC15B0C2
+:10C230004AF7E18C18C7BDB6278EABEE13A9F1DC27
+:10C24000750529042F21C1FF2DE223CB1A10F11E01
+:10C250007E983E40F6F8AA4613F941CD093BDA91A3
+:10C260003D3223F83EA47A3E17E063B1027C560CBF
+:10C27000BC9BD6959414BB17E7A5FA91F120AF505B
+:10C28000DE6525CC9B8AEB4B7AC3ED4A867AC60CD9
+:10C290005D366016E0EAB9A278AC1EC6213C58D8DB
+:10C2A000384CFBABBF22D140F1D8D0F2270B785CE1
+:10C2B000320B0521AEEB5E13DDCF5D75E0BEF7AA54
+:10C2C000507E1E3039C967678114BCFFDE1D77665A
+:10C2D0007CFFDDAE9CBFB5DB0D743FA63BBECCF84A
+:10C2E000BEBC1AE7881AE5D98C78F231C721F4C7A9
+:10C2F000FEAB718F1B46CA4F607FAC6DC015C56326
+:10C30000C2C6EA689F2729857982F7055629EB5F1F
+:10C31000D50D877A3BEAF575289407F60F878D3798
+:10C32000E7BB2622DD46EC8847FDDA47BC431317FE
+:10C33000C17B2879B10462FA93AA799C2466EA3C0D
+:10C340008A774853F93ED90A1660FCDCA0C0847C89
+:10C35000BAEA4BFD0D7087E8D7CC7A929391AE90F4
+:10C36000B8482F7F45E6766588DCDBA2F0F9F1025C
+:10C3700025EE91CFF2BFE79325BB2852D9F7891854
+:10C38000954272E811570AD943C41C41F0BE9C9DE6
+:10C390007350B1877EA79C8FF72BE7830F2BE78322
+:10C3A0005FC5770BC0903F86EF16407ABCC949E560
+:10C3B0006F341528CA99E36F45EE9248B21F94F97D
+:10C3C000E994F9ADB04E7325037E566DD3D37958F9
+:10C3D00063C284E968CF32AFDC9E11DB73EF8775EF
+:10C3E000C2BFFC9E73A75D091E3A4F3AC7CAF73F0A
+:10C3F000557C2D54EAAF12B619905FC7766AE136C4
+:10C40000FE52A4C6AE2C62DAF397134D4334F54BBB
+:10C41000ACDAF39793ECD76ABE4F7668CF5F5E973E
+:10C42000313E641F564B570B13806E804EAA337DEE
+:10C4300034FF85D6528A7BCD0DB9C77447AB363FE2
+:10C44000DFA7CD2FDCADCDABE7C9C34629F43092D1
+:10C450008DFC31F14EE4F70C85EF0701BF6FB33A65
+:10C460009911DACF1678BFF81EC6001BED4BC976BE
+:10C470008C23ACE3F79FB05CC7CBBDC395F67ABE07
+:10C480006FC58EDBE8BE1D4BCCE1ED06F0EF7EFC08
+:10C490008EA4F1720EAF87FE12D61BA2F453C3E531
+:10C4A000939C45FE829BEC33236BB3626A01FEC210
+:10C4B000349A39E99E750CAB27BF7590727F325163
+:10C4C000E8A4BC43B086613E4570A6F0F8858FE4D1
+:10C4D000C35049FE752AF1895B7447F4E6970DB99C
+:10C4E000BA07F0AAF8860291E4E2235646EFF9D89B
+:10C4F0005CF713BF6EC316B06E336B8F49157AF8B5
+:10C50000E7EDBC61C45F135C0EDA2FB515240B7820
+:10C510002EA588859CCB364569E8A3C41A17425FCF
+:10C520004342E84B4B7F7F9DECD5453990CE42E8A6
+:10C53000F02FBEE5512C18AF4C8FFA058FD58976B8
+:10C540004A059ECA02964F75469B31EE678BD173A2
+:10C5500079A5D83FA54A9FABE459EBB2E1FB6B56F6
+:10C56000D149E6F6BA2D3DF12518DF9600F635EAF9
+:10C570006399915C7DB0D31F7635D47F04FCFF6551
+:10C580000CFD1BEB64BCEF65B5E4105F3F624979BD
+:10C5900000F35ED0E8587F4331F7AFE5E86C82EFF7
+:10C5A00051A1BE05EFA53DC2F24CA9C1F52DBCFEBF
+:10C5B0007A596451909F183182EABF9D6766F8CE20
+:10C5C0008177A0D98771EC63F2AC77DD41EB7F7B9B
+:10C5D00014D707AF191CF1A80F1E997C77A687D234
+:10C5E000748D5F684B10E4BECE17858F3672BD9296
+:10C5F0005BE2C7787C74C234579903FD1DB70BE921
+:10C6000042E712F1E85B37FD442B7EA8E406C10F38
+:10C610004B9B745D0E43FFE3110B77351E299ED5AE
+:10C620005286F90291EE03D95CE2EBD9B8AE027EF4
+:10C63000FEF04AE571A81E18329ADBBF9386443C8F
+:10C640003014FADF50245AB1FF0D7A2BDDE7F14E9A
+:10C6500066E45717BBEA97E0BC6D09110CCF6FDA9F
+:10C660000A1A78BED8C0CC004F936BBD17F1694A47
+:10C67000F58CC0F647077E7A1CED195B82483A704C
+:10C68000A2CBF9AE1BEB1728F19DE279EB703C9B36
+:10C6900045B49A590F1C54B9BE9EC9CBC9FFB20A02
+:10C6A000F4DECC0A6B430DCEE7918470B2F36DAE2D
+:10C6B000060BE279C3403DD14149227F576A55C2FA
+:10C6C000B40ACCFF62A09171BEF32F1F8AFE815382
+:10C6D000A075355B1A685EC72E8939C1EF96A8A987
+:10C6E000D9A185CFEF46F1F89009E3F1809FB7F526
+:10C6F000CC9C9A8BF4A3A778537F7C6B735DCE7E22
+:10C70000FB61FE2A94030B11BE8597C2984F40FA35
+:10C710003D2961FE777F015B80D6D960C1FE416E05
+:10C72000BBFAA2BF88D19C7E9B0B0E4BF84E82D7E2
+:10C7300021101F345B4E4E443E7828B58CE8E8A1AA
+:10C74000828F9A892F86F3FCDB79F7EE413C7A13CE
+:10C75000C3697FE7A1825931C1F4BE609448F432C5
+:10C76000EE6F614E3FE2639481F8FB9108C7568CEF
+:10C770004F79F3CC64BF4B8275D96C98E7C46228BB
+:10C7800087FEA25D623EF17E75058F0B2B307ED554
+:10C79000653B84F8904A66317EAE4939F71491EFD3
+:10C7A0005C4335B4FA6F952597DECFD892D07042AE
+:10C7B000D9B620BB6A9022570694884528DF0659CF
+:10C7C000B85D65EB940594BBA1FB47AABED729EDE4
+:10C7D0008C325BA6A3541B37D215707D1B6A7FE990
+:10C7E0002CDC5EC33FBC8FAECF353F89E738743158
+:10C7F000DA7A7F19A59C730AB1AF543ADF60E57A03
+:10C800006243AED18774BDA198DB592A1FABF247B2
+:10C8100085BF2A87D47B7EEF28F695514E5E3687FA
+:10C82000E4EA99E5786F07D49E7317C37B8956FABB
+:10C83000FEAE721FF194626FBDA7D85BFFA1D85BFB
+:10C84000EFA3BD05F986518308BF37142E76DD08A6
+:10C85000F31A902011DF143A4E4CC4EDAF71192732
+:10C860002C7DD96111D1A20EE3058F34F27B4936BC
+:10C8700097ED9815F159CF95F92C6B766934BBBCBF
+:10C880007CF2E37AD2D13EE4EB7B55B94F794C99F7
+:10C89000FF7165FE6F28F357ED8F4943BE32A1BC8F
+:10C8A000DF10AFEF477E29FC29A7D0B9A85079B592
+:10C8B00001C408E9EB2291FC9F2078E76AE4BD25DA
+:10C8C00020F7F54E59C9681EBFDB6076572C467CB1
+:10C8D0004E6614A79DE8AA27B96503B94572B3F857
+:10C8E0005CEB6CCA473883E59E518163B1CB5A8EAD
+:10C8F00072BE38464F1F5724A4D0BD5BD5FE0E1D17
+:10C90000F772F00C9567A682F55EE2F3FF47726C52
+:10C910002CE3E38EBD243AFD5CDE1C4F2679239187
+:10C920007C0AED5F95376F63CC6420BE4F64A1FB3A
+:10C9300000770A614E84E79D287C303F97D17DFFC8
+:10C94000C18A3D6757DED1014EA1B8CED84EB0F5B1
+:10C9500083F87AFC2553F71B6CDC8E8FD6E4279A7C
+:10C96000E235F54BACC99AEF93ECC335DF273BB208
+:10C9700035F9EB324669EAFFC259A4C9DF50305994
+:10C9800053BF4C2ED3E46566A577480E36ED1EFAEC
+:10C99000B11EFDA7B6A11FA7F5864FA1F1F00B0EA2
+:10C9A00060E1B5A38B67E80046855187EF4C86FCB4
+:10C9B000C6D19367E880EF0A071FFE3A195868D37B
+:10C9C000E8293C7FF5E1AF5320BF65F4753C3F8615
+:10C9D00091F0DC3A7AEA0C2FE0591CEA797434D0F1
+:10C9E000F12D97EA8FA23DF8C765D3E6264BF84EA6
+:10C9F00040596206CCE76C8AE761FC7E73ECAC15AB
+:10CA0000781176FC77F5748FED37A379BB8E8BFCAC
+:10CA10005D8D8E8BFC1D0DBBC8F1F65353F5BECB5F
+:10CA2000040E9A7EDF5F11647EAF05FDCD3969DCAF
+:10CA3000DFC414FD4D4CD1DFC414FDCD397AEE6F47
+:10CA4000628AFE2696A3BF89E95B4D32A5EF34B911
+:10CA5000286D6F7253DA7DBFE029E76A3D0A38EF2F
+:10CA60004F8B5B98C3E417114EA1E74A3AF49D4FF0
+:10CA7000D07ECA45E6C0FB1287224E3970BFAC3962
+:10CA8000CF44742E74B63B4CF0BD3097E79B2FB665
+:10CA90003B507E611EED9E8EE8B66C94BFCDB51600
+:10CAA00027EEBB355FF4C7239F14D61BE8DE4C711D
+:10CAB0006727C5E90A2DFCBD844311C78E28E39181
+:10CAC0005CDA7991F9457C27C7DCEEB02AE3603F58
+:10CAD000306E32EAB7C225302EF55BBF98FAA9B0A6
+:10CAE000748F2B848C6BFAE171270A41E3A67631AF
+:10CAF0007A1701C77568C6F54B743FFCA25FC27810
+:10CB00006147B4D38E714D355F8CDF21BF45CFDFD8
+:10CB10005F2C74F825D493B8BD89EF5BC681D833F8
+:10CB2000D3790D1FC965A84771B99D5D7C9D179A82
+:10CB3000FC0B909F8A957760C08CA57B9B4C0C73F7
+:10CB4000A2BE2891BE3B363817DF39E3EFA0151B94
+:10CB5000DDDB901FEB745CDEB01833DF57D0B5CF50
+:10CB6000FF15D43B193B98EC9504FB4B2C7504B492
+:10CB70005FE4CA44BBE3245B4F72687594E77F8F20
+:10CB8000067ABE31B35E50F427F5637785EFC0FDBA
+:10CB9000888E5786E5211F4D333A5E64C0BF7F1FE4
+:10CBA000DD44FC3C2DCA91872FACFD7DF40A9E8F9D
+:10CBB00073BC883783ADAC694671FC8F3F2F45F15C
+:10CBC0000D749AA70A3AB47FD4735376D1133606FC
+:10CBD000E054EBFACAC0E7D769C07870D41807C12F
+:10CBE0006FE06146E7983A2747F876E07EDF80FA03
+:10CBF0006C8C87B24C471ED64BD277D27DF28EEF2B
+:10CC0000F8FD27A819795350FCFE898392ABAFF841
+:10CC1000E3C931DC4E5D946A598778A8B39B4C9484
+:10CC20001EBC48E78299CE9D8AF16BD9D0F77BA9CB
+:10CC3000AF8EE1FA2179A54131024174C294E53009
+:10CC4000A6E6BD0CF4D0F6BBC3BADF8B037032434B
+:10CC50009AC8F3DE1D8F17EB34F565ACDFFD1DE3DD
+:10CC6000F4ACA7BDFCDBCD8F2F4F55C6437A99C7D7
+:10CC7000C87F0CD53B6B0B6DEA3B3F84E7C763CCA9
+:10CC8000DBE93D5249798714EA5A314E11CEE83D2D
+:10CC9000AEC1BF37FB9A819E769A393DA78A3CDDAB
+:10CCA00029F2FAEA3BA5EABB6BCF147A6E2BCCA330
+:10CCB0007EFCD48FB4371BDFCB88676D34BEFA6E31
+:10CCC000945A2F01F420092B5D673AE2AB5012FB16
+:10CCD00084E7E7638AE6201D5C68F2B24F82F4CDF8
+:10CCE00085F0C8C660FCD549DAF75A3F1F3381DAB0
+:10CCF000A9ED6B1B27B24F2878E9273AAA4D156991
+:10CD00001FBD4E62AFE23B9C20590DA897D576A778
+:10CD100040DEE278EF82FCC5F43D90BB9FE8D13E57
+:10CD20009D4EE9FB4D1E2A3FDD544D69A0A99ECAC8
+:10CD30003F6A6AA4F496DB2372917F16ED5FC63ECC
+:10CD400009A2F7DA36BD2710943F55D4371DAD51EF
+:10CD5000E8E85472DFDF9F1CC3EDBB53E3383E3B72
+:10CD6000C0DEC0F7DA802E975B6DFDDB1D1DCAFDAE
+:10CD7000AEA3E3F9FE65473CCF2F1FC3FD6E596498
+:10CD8000ADD8FEE87803EF3F45ACC6EFB28DF77B38
+:10CD90002A5DA477A47E35B1E8FE31583F16CA73E8
+:10CDA0007AF2A7AEE2DFE541BC5C9DAFFAFDB64288
+:10CDB000ABFAEE613A7FCF8FDFF7027AA7FED5FAA2
+:10CDC0006326703E0CADEF4BE5E7C943E1F1A9C224
+:10CDD000B7C4176867231F2407F1459D83F842A550
+:10CDE0004395FED6167238A71A153A0FE7E7EE07F5
+:10CDF000A32E847683E3CCB48F20E3BBCBB09E9D7F
+:10CE000082C22FA1FCA0BC63ACF283CA072ABD0F6B
+:10CE1000063EE3EF34F3758C95FA795F5859477BFA
+:10CE20006CC45D84D7837A2BEAADB1127F2F79B0C1
+:10CE3000D8F5CEEDC89FB1110E8C9196ACB2D4F757
+:10CE400025C73EFEAFC243950BFDC0A3171C0CCAFD
+:10CE5000BBC33F120E24E7508E23FDF621B74E8C44
+:10CE6000B1297617A7DFCFC7C86F221D7508661DC9
+:10CE7000DE7BE830F77D5FF0E878BE0E958ED61643
+:10CE8000324A07E33A87F6967BEA7ABAD7790723DC
+:10CE9000F9971AC6CB43F1ACAE2B48FE9DC179A9D8
+:10CEA000F0640CEC1FE827A1C642EFE8DD56E8E08D
+:10CEB000FC36F0D3CA0DAC67FD358A3E7B4C94F846
+:10CEC0007BC88A7EE92E17A49965991ABD4347CF7E
+:10CED0003A5FE1EF8AFB45568DEF72A36F1D1C1779
+:10CEE0001F52C8E543D7F43C11F7132FFCD542F786
+:10CEF0008B2F0CEA3C8DF6CE85563D53DE239B2AC4
+:10CF000080DE9D8B3E130CF9A5F29EF3E7E8F70E49
+:10CF1000837A6D174FA3BDB568ABC44C789E60EBA8
+:10CF200037B7203DCD7B454FE7999A5B371E477A4F
+:10CF30003CB74FC0E76FD9857D02C5316B5B227C62
+:10CF400066A85F0A79AC7FC76EC9C7E38B32C53963
+:10CF50006A94F13E31D7A5A05D3E71EB5D3A84FB4A
+:10CF6000BCED028B837E8FB4DE790CDF1D39B78D6B
+:10CF7000DF2F6B3647EEC0F9974AEB0C83A07CC1DC
+:10CF8000765E5E6329FD0CF743173CCD28FEB36047
+:10CF90006F04F98FF35AF41F0582EC8EEA6DDAFC08
+:10CFA0007CD666403A58B0535B5EB307F241F279E3
+:10CFB00050A1122F19CEB2295ED2C2E307AA7CEF8C
+:10CFC0006D5F7BB91C6D50DEFF667F89A5F70F5F33
+:10CFD000F926E9230BCF9729F93390FFEA1B8E1727
+:10CFE000152E75CAD85FC5B3DC365867DD2B662BA6
+:10CFF000FAED7507CE46E279B04561017A1799BD21
+:10D000002C59D1DE7B60BFE445F8D61E343F89FB46
+:10D0100098752F9E30603CA174DF62B2572631EFC5
+:10D020004AF49BFDA2C8DA898EDAE97D5F2677CEC5
+:10D03000C37E2E1C305BD10EA87BF94FC76EC7FC98
+:10D040008B02DDA7BC9018203A99B755A27B430C00
+:10D050002DB4FC1E3A9110AF88E7B6287A8FE50E02
+:10D06000C43BE219F0EE48463AE171D0794F4BF4F7
+:10D07000BDB9B5D980F5CFF9387E55BC974A4B0973
+:10D08000CF0B1EE7F89CB875D7E630A483A7F564EC
+:10D090008F1F817683783B0D1D185EE1FD5FD8C53B
+:10D0A000CF9177D3C10163371DE03C2F4707C0A75D
+:10D0B000A4F72F47079DE89792BFFFDDB9C7D00EB1
+:10D0C0008FE0E787D5771BD5771A072E3C7514DFDD
+:10D0D000E74AB3BF407677A5ED8BDAC58CDE099DB4
+:10D0E0005388E74B26BFBD02D17772CAB3D9142F3C
+:10D0F000D507766DC178437438C5C73A92CBB6E18F
+:10D10000FB98C5B66F93F6C23A16FDCE48E711EB11
+:10D11000157EC63F3C07A2BE4B0C78A7F319B50796
+:10D120008DFC5CC63EEDFBE11DF19CCE4B0C9D954C
+:10D130008BD14F80FE701C41E6FEE9C283FC1D4589
+:10D14000D59F5CA8BEA7B847FB6E83607D9BEA3D78
+:10D1500050984270181A37D68176797339F3840D56
+:10D16000FD217DC1DFA97C5CF18BFAB527FBD11BCA
+:10D17000AA1DC9BC21F7DA15B97547019FE3D1BBD8
+:10D18000DFD0E17B8C1D3BF9EF3BCC3F08F22A0658
+:10D19000F719F51AB953A7D4FF14E90FE076DE5B4F
+:10D1A000FF922805CB97F78BB19F9AA7793F7548D7
+:10D1B000571457F56F0E83FEBE6CD333E497054CBE
+:10D1C0009137FB23286ED44BBEECDCBE12CDF7505A
+:10D1D000BA5A0876262E2294BEEAF669EB3D5DA87F
+:10D1E000EC7B0E67D7E0F9FFAF31E090D7235FBA51
+:10D1F000DFE9678E28E4EF6E7D2868EFEF0F6B059F
+:10D20000960FEA77B8CFC463A44AFEEADD564DFE16
+:10D210009A36BBA6FEB5FB1D9AEFD9FE0CCDF711D1
+:10D22000C79D9A7C5E7B81A6FEC8F7644D7E54C084
+:10D23000A5A93FE6BC5B93EFCA84F5F461CFA8E9EA
+:10D2400024BBA0A93FD961D6F47F5D46B426DF6533
+:10D2500051E0A3D899AAFDFBA7426EFF86A62A7CBF
+:10D260007FE1D48EA3FAED371468C72B93B5E35D45
+:10D27000295EF01D419D9EFF7E02A6F8FB09BA348F
+:10D28000FEFB0998C7DF4FC0147F3F01CB7FDDE471
+:10D29000A4FCBEA602CABF047E09E6F7839F82E90A
+:10D2A000CBE09F60F9E5E0774C19F7B832EE1BCA86
+:10D2B000B83F154E6F29FDBDA3F487EF0DEAF43D8D
+:10D2C000DF6B5D79E225E0E322DB67745F596E086E
+:10D2D00094621CA3F37589E1F967E6F11D6F8A4139
+:10D2E000FD3680A19DC4DC9D6FE23E6EDD8B43ADBB
+:10D2F00078AEEF81FD7F7807BF5FD82751BCE6F09D
+:10D30000FEB391D8CF9797C2E9300AE945C8D77CD8
+:10D310002B507E0D7CC7736793F74ACABB676DA419
+:10D32000EFBE4C55F33EBA2FEDDEB3D780785AB836
+:10D330007B2F7D7F1DF85AF37DF776CD772BD6872F
+:10D3400074A1CE477185CFF7ABFDF9A97E4D2A7F39
+:10D350003FFEF3DD47568E417DBCB76A00C6B51768
+:10D36000EE39113BFB07F0F1D54BCF66A21EA83D6D
+:10D370002029E7D1787FB507F44A9ECFBF26756F85
+:10D38000299E37637B04BAB3F4255B4FE7C416EEDE
+:10D39000DF5583727661C6ED7A8A7FB5494ABC83D0
+:10D3A000BFD3506365DCAE6BFB3A12DFA9FF7DDBB8
+:10D3B000D1EBF11E74C7C123F45E4CC73E49E34F65
+:10D3C0008D1DCBF13B762CF7FFBEDC772412CF0905
+:10D3D0003ED07684C35DE7A7F51F56F21D9012BCC0
+:10D3E000F74BB4FEF99724CDEF01B8C071A1FBCD86
+:10D3F000FBD322705D27DBF878D3407D50796AD566
+:10D400001C9CFF1BF6F23CE57D32FADDA18EABAE33
+:10D41000DB857276619BD4E779F739D82FCCEF980A
+:10D420009ED3E9EBA92F1C1B04707FC335209B748E
+:10D430008452AF622CD79BA5064F2AEA91931647D8
+:10D4400004D2F9FDAEA11188DFC39862B9EB49BAE5
+:10D4500007BE601F1FEFA4B53D12E9EEE4BE1152F6
+:10D46000F0FECB2DCA7ABAE9BB1B6F5EC253B56F13
+:10D47000BB05FBE9C11F2F9F36D64AF5DFF09DB8EB
+:10D4800005EDAC9319FCDDC0630646FEF5C23DDC3C
+:10D490004E3E7970F0F6E0FB59D3147C7464F07D55
+:10D4A000F50BFBF54ABDDB77314D3D3DC7D74EED62
+:10D4B0007CACBE330FA17D5EF3B844671D6AF4F502
+:10D4C000B1B8FE4FB769E757ADC0B946EF8F8D0DC4
+:10D4D000A2D79A03DD7C63213A3FA0F28983F0A9A9
+:10D4E000E2F16486C4E765E7EFF8D5ECDD4574DD6D
+:10D4F0003BBEC4E3B783EF313929BE74197F5AB5F7
+:10D500001B82FC2DFABD23BD6B689E98D2631F9CC5
+:10D510002E941F1A9B877E989BFCCC930CEC5B1877
+:10D52000B316EDEB28FA1D89CD386ED73E3DBDFF11
+:10D530005F6B3AB000DF23EF7202A3C0BCBBB6E959
+:10D54000BBDF67463B779E62E77EEAF0E44BA07F55
+:10D550006B9789B4BE9A3D920FCF175C50E4DE57AB
+:10D560007B936F407AAD392E59D13F9AD896FC7093
+:10D57000612EE977B257EBDAB89D5CB75B20BB58F8
+:10D58000B5436A153BE49C62079F5BD6C9EDE35740
+:10D5900004B611EAAD0D037B04E65D9B3985ECDA38
+:10D5A0005A69DDCAC10E3C47A5B51BE61F3C44E7DE
+:10D5B000AEC0CED1942FDCADCDD7B669F3AABFF8FB
+:10D5C000D2D86E3B6338FA372552611CF2C39B0AEE
+:10D5D0005E557FE7CE6B9CF4FB270FE81C53D4B855
+:10D5E00004C26BD12B2FCCC779FB6AC29CE47F3479
+:10D5F000FE96E0DAF117EED774E0DE1BF233E3F0CB
+:10D60000EDD8CFE97C915EF0E1EFBA2C425D81FD6F
+:10D610009904DF328C3B7BBB22493E29E7081ACABA
+:10D62000B9FF2A630C18A6B27E2CF7E743F5EA3857
+:10D630005D408A0E921381B12954AFD8C0CF57DE16
+:10D6400019E124FD36C4C4EDF521266EAF0FD17566
+:10D650002EA3DF851824F07D8EAC9769FF606D9D49
+:10D6600085F617047B950EE1B17650950EE97D881D
+:10D67000B52D03FD3A355F8CDF337BEC83528B474E
+:10D6800087E3EC8C17947D04AE4FCB74567D749079
+:10D690007E656C99667EEA3DCC9F7D7E56989FA5FF
+:10D6A000677E80EF286CFF75AE93EC86A432F5F7A9
+:10D6B0001AEA492EA8F0FC12E8BD187045776C8173
+:10D6C0006E6AB61D22FFB296B5AFC476A5917C1DD9
+:10D6D000A506FEBE5169184F75E3B8FC2A51D2A5C4
+:10D6E000E3B4F6C39171B27E1CA43BC6B94DE3F21C
+:10D6F000683F9579617D0D6FF377D643E53E9413CE
+:10D700003D7D0D7C88F26F46BD604DD5D8699CBFCC
+:10D7100016F1A26E3E5AF8F693C427EA39CC6AC6CF
+:10D72000F97B66A3D99A1AC4178B90DFD0DE77C332
+:10D73000BF7C8C13F0BF6AEB7C3A97E9698CB5A289
+:10D740005FB748FA92F6257E2CDF2DDAAFCDFBCD00
+:10D750009CFEFD1102F94919E3BAE30DC48F490A91
+:10D760007F6CF708740E60FB773A1ECFAB10287EF3
+:10D7700077331436DA944962BDEA22BA4F7233E342
+:10D780004763594B8CF2BB3D31B46F7993B2EE9B3A
+:10D7900075FE4328578EEADB92319E74B4D6E4C4FA
+:10D7A000FECB591BBD6F5AC1DA293D155EF7A29F0A
+:10D7B0003AF72622DDFDC963A478D6F6E53B225070
+:10D7C000BE67B1E556DC4F0450ECC6B701FBB3733E
+:10D7D00042F71DD5FBC4602FC7217D02FE27211D06
+:10D7E0009C07DCD8737AB75FF8C71723117F5F2CCB
+:10D7F00079E1965B19FA5F9DE4472DA85F46F75DD6
+:10D80000819CDA33F27BF0AAE25DC55B375E1DF0E6
+:10D810002F18AFB0A6048493F46519C9A57F91E8C9
+:10D820009CD6E5F0AAC27DBC829F3B0E70F9158A9A
+:10D830006F150FB7E2BBF54349EF6E233C3123C9A7
+:10D84000CB507AB81CBE8030E93CD9C41823F9A16A
+:10D8500083452E4F07CF13285E793BF3BC1280F42B
+:10D8600096F0F7F5FCDE0AC75B8582B73F31DF2F04
+:10D870003292FF71783B32CEDD346E606FBE0DE5C3
+:10D88000D3FEF8B2C6E1FC37555FFA18F263083FE1
+:10D8900087F06B371E9DF02F088F9EC648E2CB6E37
+:10D8A0007C4B7BAE4C2FE27F308EB55FF0F993AFAF
+:10D8B000805F0546BFBFF8F838ADDE54F1A6C2A5BB
+:10D8C000BFB8E007CC7FD42AD0BE0AE7E3BB8D7493
+:10D8D000FF43DD5751F74F5E19C7F55C68FA01D871
+:10D8E0004BB85FB526E3E440B4334F19D47EF8FE5D
+:10D8F000EF07CBDA13F1F7B63E28E2E92903FFDDA3
+:10D900000F352F87F1B8E407F1462FC2E90361F81C
+:10D9100004D4331F08F75CCFF3710607E6CBE32688
+:10D92000E03D90537A358E79BF127FF0F179948F74
+:10D930002CA67A02FF5D4A07FEDE1DF62B0836177D
+:10D94000CCE783BBD2E87D9DEE7D8D71DC0E7F46FA
+:10D95000594777DCFF5E81E2FE335135E1FEC48436
+:10D960002D2E7C87F3F47D43B369DFB4413B3EEA5F
+:10D97000FD648A976EE0E7FE2E75EAAB82F45BB732
+:10D98000BE2DBEC8CBE7E4D1EF8CA8BF4727DB860E
+:10D9900073FFDCC77FDF50D5675DC75FB004C77317
+:10D9A0003F53E2DFDDF9E10F2605EBC3434FAD4DF9
+:10D9B000C77EAA0DDE2CA7057F87EEB124B45BAA33
+:10D9C0009F5A954EF6F4530FA4A35F54BD636DBAEE
+:10D9D0004CF9700FF9653ABEEE2F9E1B45E7F3D464
+:10D9E000FEF6CADCAFA8301D2A41BD3DE5EAAF56C0
+:10D9F000E0FE41DA7D02C5FF66B0F615A8672B335D
+:10DA0000385FB11613C97FE88FF66B770DFFC54EEF
+:10DA100094076F649CD5CF817A123E203510DFD5F4
+:10DA2000F2ADA3DF095CCD7F27B0A77E22EDFF56C4
+:10DA30002D17E89DAB19F5FC77F3A4F1D104C75974
+:10DA4000ABB38FD1FB574B79F914A36FDF49EC6768
+:10DA50008B81DF3F64EE94E0FB7092B25F38739D80
+:10DA6000F27B71CA38699B63B707AF5352F61D59F1
+:10DA7000EA7724DF6E50F03275E98957EDD0EF5424
+:10DA8000BDC73C1EBEBFB3E95CAA9F611CF4333A1C
+:10DA90005F9866F03C3A1FD7BDC34871D2DCACC179
+:10DAA000521CD4CF5952B411D3994BAB1E9D8F72D7
+:10DAB000B8D594CD8F35F2F935084E11E5F491EDD6
+:10DAC000B7CE42B89DDFC47FFFAB61FB30FADDC249
+:10DAD000FEE4DEAF9AF8EFF93DDD64A2F4D9262B1F
+:10DAE000C3A3EBCF35D929FFAF4D0E4AD9F43CCDB6
+:10DAF000EFD8F4D7DF884BE1F4BB73B9ABCDF43B7F
+:10DB0000880D4639753CC02BEDAADA1D0F28EBC2F3
+:10DB1000F7B8B2BDC913110EB90F2C3E86A6B37566
+:10DB20003CDF977DF3E4EA2414D6772C3DF3C47CE4
+:10DB3000F87EFB78F7350827D3B68B14A7387260C8
+:10DB40005525C2BB7A8791AF4F59F7F94DE9718FCF
+:10DB5000627CF9753DC50D166D3BF3C4030C7F87E0
+:10DB600077B12198DEAF74BD578FE77EE6E5F8AA5E
+:10DB70003F38FC78BE5A9B44FCB303F82AF3A7F362
+:10DB8000D5A2A5CB087ECBC6BB6F42B89DD77B93F1
+:10DB9000909FCE0F1F4B74EE7D4520F8AB72BCDB1F
+:10DBA000AF56E0BF506C5B5798DC23C7BF61B90428
+:10DBB000DF43073E4D47FBF99BFDE53FB8EE97601D
+:10DBC000DDFE6118AF33511AFA3DDFE019EA84F542
+:10DBD000E5F7F33EE8D2F16AFC9F9F53C03F213640
+:10DBE000F89D21E68D82F9D41C14FC6159A8CF263A
+:10DBF0007DA643BF11FCCF8F34E78C19FB28489FCB
+:10DC0000F737DFCBA575D84F5A8FDC1DF99EC8FCBE
+:10DC1000417A7B54208CF983C6EDF673A0CC40FB8F
+:10DC20004EF12417106F782EECC281E13B30FF9942
+:10DC300081E3F1C24B604FF1781093F27BD6F9D9B2
+:10DC4000812FB250CE86AEB7EEE52F883E6AF6AF92
+:10DC5000BA28D0FA277FA6CBBAFCFA0F3DF54516B5
+:10DC6000E2EF337D201FFDB60B864016E2A1EEB732
+:10DC70005C9EFF5838A8E5F3571BE8F73AEB04130E
+:10DC8000D14989F425C51F2E1CE7F187BA034F92AD
+:10DC90003CED3AC8E3408BC4F6D2388C9BD49F3914
+:10DCA00086F2ACCBCEFD31E89FDE712B1CAAE84199
+:10DCB0005D6712DEF73BD84D0FDC8F3C8FFC3B0CD1
+:10DCC000FB69A3F3BD2C2B9CA15DF139F2F3307CF1
+:10DCD000BF307925D2F979DFC01C948F6F66FDAD16
+:10DCE0008EE286BF0FA77BB2B56D92E69C79F73ABC
+:10DCF0007C123F70C454FB299CC9C1E7B90C8E1B30
+:10DD0000C86E7E83EF132EBA8AF3137B99F353ED1B
+:10DD1000F243067B507FBB157E52EDC829BFFF1B27
+:10DD2000F1E5B38532FD04D54FA5C7FF9FFEF74C43
+:10DD3000FF2F4133EC630080000000001F8B0800C0
+:10DD40000000000000FFA55A0D705455963EEFBD2F
+:10DD5000FE4927DD4913421208840642881A6203ED
+:10DD60008172D6C4E9FC6E2033BB016B2DC4088DD3
+:10DD700022249D7482E8EC6AB96E1A02AC6475368E
+:10DD80008C59471D479B9F8028EC769440C0A00D7E
+:10DD90000ACBA26B45AA263A555B54ABAC0EE0A663
+:10DDA00023823BD6E2B8E73BEFB5DD1DE24FEDA69F
+:10DDB0008ABA7DEECFB9E79E7BCE77CE3D8FB45247
+:10DDC00022CA226ACFCD082A0AFFA66EA245446D58
+:10DDD00029247FF641451FAFD364BC7D40A3C958B9
+:10DDE00093EB08CE9E415447DD269A45B4844265A4
+:10DDF000A471BF29F2CB5B79BCFE0D6D4117936115
+:10DE00001BAD6AB013D5A67A0B3614130DABCAAA94
+:10DE10008662CC0B952E9D4BF40DFE7E4A749B873B
+:10DE2000994F222AD3140FF61B9D9C16DCC95D8BDB
+:10DE300097FB1B494D98A7EAF3984F53087C82A3A0
+:10DE4000254B1DD868B46499233EEF8E37D2D60790
+:10DE5000314EA1D23B12F6F94B8F856821D117CBF9
+:10DE600017AA0F65F279AEDA037433518D76ED2976
+:10DE700085F7DD70CC4C5605FC67BCAFF239026704
+:10DE800034EA65FA52470A79ACCCCE4B1E0FCF1B51
+:10DE9000993B29D8C5E76F3FA09089E7B51DB1EE42
+:10DEA0004CE1796DE648B69BF7DD36F03B8B87DBBE
+:10DEB000F6FEF72CAEB958CF4736439E1415FA6DCF
+:10DEC00077F24F17917F60CEFB77313FFF694DF4BA
+:10DED000ED37BD6721D6D7059E8FFD5A0EF6D58248
+:10DEE0006EA5F05627DAFD3CAF48BF9B6FF8DFE523
+:10DEF0005C5786B3387EBEF8395DA2A718BDF869B5
+:10DF00003EF702D68B46EB437659EE21967B716E37
+:10DF1000CE8E2E25719DAE5F8F76694B0ECB159DF3
+:10DF2000A9B81566154D0D6C76421F858AB39717F3
+:10DF3000475F7FB9742DF49B122CBD9DCF17B59010
+:10DF4000DCC7E2C7B69BB40479160F6A1EDC433403
+:10DF5000959A0EC9BD7BA7E23EA8BC61A96712D6FF
+:10DF60008DBE7B2B6F195579BDFDFA7304CA757987
+:10DF7000CEB0A9C97D1B72D7E7E5ED80FED900C4FC
+:10DF80008E4EA9FAFE1E95C7E7C7D7BF689CA74665
+:10DF90002BCE89F0F806C59DE31C679F58BB87F51B
+:10DFA000BE86EFE945BE6FB42F753869CD6CA2FD12
+:10DFB0001DB942FF73874BDA504791F4BFD2E11687
+:10DFC000FA60C72D421FEAF0083DD05127EDD18EEF
+:10DFD00006E93F0351FF8C70A020ECE2147C6D4AEF
+:10DFE0009C1ECE1C434F499E3F9CA924D353149999
+:10DFF000FF70B83C1860FAA532A79C938DCAD1C0B7
+:10E00000FA684E4B2FA10CB4F9414A67BBB17B03B0
+:10E010001EB6FB3FD4EDDA4333C5CF4B30AF3AF3F6
+:10E02000CE46F8DBE52C2B69ACCFC31EEFDF63DEF9
+:10E03000E9D35505DBD13F68735BF9FE8757DC9464
+:10E0400001BD47FF4D238DB7AE285AB0B994E90AF8
+:10E05000BB2276CCFC6E6EC866BBC64FE65335B8A5
+:10E06000BAD4A4E38473B602FDB7AEC13E1B26DB6F
+:10E07000165879FC4AB9F757D827A6F7DA29EB0AD8
+:10E08000BCD08BD9F5BECAF302FF6EA65E9EF780A8
+:10E09000C39D64DF47CB2B82B09BC545B336CF070A
+:10E0A0007F76BAD9BC3FBBF57EC8E751D3944EC149
+:10E0B000319709B810C4FDF33E952E45EC306C71D4
+:10E0C0009932997F38B5222BC0EB4E19F77DDAB81B
+:10E0D000EF33C67DBFC3FDD5DCBECBFD6887B81F5F
+:10E0E000ED8A989E4DA385D05FF0A70D2F7944EF60
+:10E0F000A3F9A0A3665A0E3B5C023FD3F127BF8170
+:10E10000E578A25C97E36E037F866E6BE8D3D785D4
+:10E11000844F8B85BCB0FF4B589F609FB175F1F564
+:10E1200024EDB29B2990C2E7A0C3B620F4445389E2
+:10E13000805FCB0EE7082E6929B38ACF4F647A013E
+:10E14000099ED2AB567D5EAE6B21FC857524FB8C9F
+:10E1500004D58099EDC49F395498C9F28E187E1663
+:10E16000A30FFD4913FCF6CF679ADBD714FD7CFEA5
+:10E1700065438513B05EB1A9B033FF4E7DFCACE1C1
+:10E1800087FE99063FE33C9412CAC77D448F1DCE9B
+:10E19000BF87E92E7B78AD1E07C28582DF142E5C17
+:10E1A000069C5442E7C84DD477FC7DAFE927D047A1
+:10E1B000E879D0FDC77FAFD34ADF3967E2F8A450D2
+:10E1C000BEE204FD8141F73D3FC19D409B5F398721
+:10E1D00071CBA6DF7BAB27336E5883A73B6037FF3D
+:10E1E000A2DB97ED40FF27D05BCB112BC12E2B0F6D
+:10E1F000F47FF60A8FB7F43BDC80FBA86786E8BBA8
+:10E20000F3C8DEC7616F237D66F187AEFDBF7BFE7D
+:10E2100011996725985BBD35544ABCCFD1E37FE3A4
+:10E2200035619FB4D015D06F579C1739EA27EAFEA5
+:10E230003D54F1A93700BDF51FF86BC4B5FA0C0ABF
+:10E24000C06EE965BE4766E47BF5866A2AE171C760
+:10E25000D04AF06F7BC9EA869DFA5ECDA9841F5F24
+:10E26000F3CC14FB6BBEB13B1F71573DBA6FCF238C
+:10E2700059986723C8DB9EC976C47AF5693B16DDD9
+:10E280002FF7B76BCF6F20F73E1BED643ECDCC036D
+:10E29000FB35EF991D0CF0D15EFBFAE395B8871AB8
+:10E2A000EDB93DE8BFB2DBA6420F672D9E8C72F838
+:10E2B000E159B3BB17EB0CBA7978A22E4F5AA4568A
+:10E2C000EE2FAB3B1F71D737F1E1BF80DCF55AF77A
+:10E2D000F3CFE23C7BAD843871611FEB8DD75DE8F5
+:10E2E00035CFC72D8FEC7398602F9794EE95CF8222
+:10E2F0007FAF3EEF92AD5BF419E89D43D88FE711F5
+:10E30000E2F225657B52FF85DEBD255ED6DFC5972F
+:10E31000EA8BBD09F61BF317DF6E6B527C14246089
+:10E320005CF219BFC919203BC7DF6683BC78E89946
+:10E33000916729BEFEE27E73D8C23A6AB6D2E694ED
+:10E34000CCB83FF8F2FEBC0EE7F3A93B0A91C73404
+:10E350002F88AC845F5CB0514A2ECF7BDB885FBED8
+:10E36000831B972A25DF2D4F4D85EEC75773F53850
+:10E370007675C0160C28DF1D8FFEA3839CEFCC8E14
+:10E38000D377AF677E29717E6F5B42AD6EDEB72DAE
+:10E3900053C78F733C7F3FE35895B1CFAA8792E76D
+:10E3A000DF529129F6D3668914220EC6F82FAC8865
+:10E3B000E15AA4107835765D3DD213E0C8CB8AE0EF
+:10E3C00088EFA0F2A1966EA8343BAE4F5F4A20A81A
+:10E3D000958C7F0FB98B8C7B605EEF55E87EE5DB1B
+:10E3E0006FF3D8984F4B6A241D7953AB23928E7CE0
+:10E3F00068E4A8463B8DEBCB8AF19F19DFAF494615
+:10E40000B83F64F6D8C6DB8F8F433C6F1D7EB32ABE
+:10E410003EA9D0FDA669204DF623676411ECB6E94C
+:10E42000B9E47538A733C11F470676657B13E28FC1
+:10E43000CF903BAA7C287E13FDFAA37CD8814FA500
+:10E44000CD0AABF622AFB1650A4D293A1DB0B1E550
+:10E45000FBBEB4A7C27E2E5E6D153F1E5122827395
+:10E46000B927AE0A3E8C982382738ECAFF11FC181E
+:10E4700099105909DCCAADB4AF96F1C991952E1E19
+:10E48000FFB2C2A0A791E40385273257034FEAB534
+:10E49000D1B711376997D9093F89E97B9DA127A297
+:10E4A000C7863B78FC0F41B30BF1614EA562E40BCC
+:10E4B00096F8F9B5B83F8D90EBC041F86793DDDD74
+:10E4C0002BA3C1FDAF201FBC33DBDDE5BA5E6F328D
+:10E4D00087E5CACAFC6A2DEE293BDDFB8F15CCDF30
+:10E4E0005F1CC907CEB1B54B1C6A7BDDBA13FB4775
+:10E4F000CDA37B805F171CDE272B589FAD96A1AD67
+:10E50000A52CD267E6C829A4F84B606F8223BABD58
+:10E510008D14EFB2089F1E562AEB6797710F944B2C
+:10E52000B403F6A1E8F7FCE6C0ABEF006F468666E1
+:10E53000094E8FF5A70B034FA603373EE0F81E9850
+:10E5400013EFFF60F55E0BFA97BFB8C312E1F69EBA
+:10E55000CDC9E7BB7CEDF60CF80B3D9ED00F7BECF4
+:10E5600049A6C7EA0576194EF28380E8FD9CC729C3
+:10E57000F2B7540EB5410FDFD2CB98D612E8136331
+:10E58000E831F3A941CF1FCE7948F8B64E0B0F43BF
+:10E590006F2307CC047CEFE4B826747F5A10EF1A7F
+:10E5A000F500C7AD2C3D6E215EB4A40FADC4BD8C8B
+:10E5B000F45B9D98BFE9C8A7F9383FDB633ECEDB2B
+:10E5C00072E47036C1CE8DF704C7C76C8CB7F41FE8
+:10E5D000C9C6BB24D6DFAA860A211747B812E0476E
+:10E5E000ACDFAF850B217F8B325482F128E496F9A2
+:10E5F0004C6BA049CED1AAE87E4F4734C1F9B1F7A0
+:10E60000F651856EAF8C0F25C807371DBD5412B16A
+:10E61000C7F1A0D9C09513E82FD6FDDFB9C8C0094E
+:10E620005EDA0CBF1F0727BC31DCA3F516C87DAE30
+:10E6300042973BB65EF8CA3B2320E36DAF5D2A9953
+:10E64000598C75C63C4AC0A359717C010EE40A0E70
+:10E650006C3267F3B97CCF2BEE4E5ED2DCB8B1964C
+:10E66000A7D33AD3FDB5D06B1305E45D3756AEB1F1
+:10E6700076F470857EBF3E557F8FFBF628C14E969F
+:10E68000EB22637DEE7CC19B30F0675DF5C65AF8E6
+:10E69000DF7D597E4BE2BBF987F8AFED49A6D7ADD8
+:10E6A000DF589B338E9FFB1EDA7E6A125DCFAFD997
+:10E6B000BBA336DB757D7F4CEE8BB6989C95E64907
+:10E6C00089FA58BEB17612B7EB52FEAFFAD0CF7DC1
+:10E6D000F188358CB8CBFAB5E0FCB7FD71BD2509E2
+:10E6E000B77F805F33056B9D33BE5BFEB16DAB12B0
+:10E6F0001E56804FEC5FBDE267EC3709FB6DAA1830
+:10E7000053A7685A3D1D793779574F4FAC538C6DDD
+:10E710001928A7A8B788BD49CB7EB8D23D8E3E62E6
+:10E72000F36FAED4649F4D861D4FA96F79E6151E19
+:10E730007FB9CC5356C97E55AEA992BF8FDDA7A62F
+:10E7400052CF0F86B21DBF803D4507CD4EF849B967
+:10E75000A6EB334FBDFC2EFC312FDBE1EA647E35A6
+:10E760005569FABC633627EA40D1635FE57BE0FF79
+:10E770005BECCBA5CE62B2D3641E3F953B57F03D18
+:10E78000B6CFC7C63E69A57ABED35E64FEFE3A53D5
+:10E79000B1E3DB3A93E41BC569C1D91287BF90F896
+:10E7A000161D5CE8D45CC0F7A01DFED6FEF57F67A1
+:10E7B000230E8F0CFE67BA0BB875EDD374D8CFB6A5
+:10E7C000818FD3810F27066639D09E1D7239D01FE5
+:10E7D000ADFBB816F3BA8C365E67308B9CB136F65B
+:10E7E0007E8ED51312DED1CDD06BAF73DB2F4B6194
+:10E7F000EFA9DD8263FC8ECE44FC88D7195C39E337
+:10E80000D56512EB0C05B3F53A035AD4190ACC7A44
+:10E810009D0134EA0C685167403FEA0CA051670043
+:10E820008D3A0368D419D0A2CE80FE2BA86BB1BC60
+:10E83000514EDE50DFAAD1EC82FF0FF46A41E4F5BD
+:10E840000F1CD3747A8712C47D7FC6FB230E46AF9C
+:10E85000E875B028C75379E71F34CBFB201ADA5E7E
+:10E860003713F7D6AFB97155171137D914DBCDA3CC
+:10E8700027511F6AEF53DC1B5DE85F2E726C1B5C37
+:10E88000F87E23FA7BCD6ED585FBBA9A8DFA976F09
+:10E89000B057EA58D539C72C72CFFB15CAE1FDEF46
+:10E8A000B0EAEF64BFC6BD2CF7B045953CDA6F1DEA
+:10E8B00092F74BCB8B8A734D421EDA7ECBE78213E5
+:10E8C0009DB6F49D90D71FB239D724C5578FE47DEC
+:10E8D0007EFC74C18D3C43454CAFD5A790DF5E7B79
+:10E8E000013821F948427EB4D6D9FC33E467A45DEF
+:10E8F00033E1FC7E7EE84E64F9D63D6DFE2892B091
+:10E900007F733099F60DF66DCD23C899DC8F4A03DD
+:10E91000E2B23F94DC1FAA74647D92C63FE6D13C0C
+:10E92000E45B75FFB4E6403FEF77B9DB2AF9CA61D3
+:10E930008FF77025FBF149B347EA2F278FD9E4BD44
+:10E94000757EFB9CA4FA4B8D3655EA1F1BCC8AC4FE
+:10E95000F12BE5DE63B0CBAABA7BA5EE5295EB10A6
+:10E960007F8ED9E1D1F28637C077C35C97D4BF6A76
+:10E97000ACF40BE1C77E2FF73C68167FABE95482FD
+:10E980002AD3ABC96D817FAD62758A3D99ED8F2920
+:10E99000EC0FAB78AFC604BBDAB05D91BC420A1095
+:10E9A000ACE795863E570DFEEB570AFBCBBD563DB7
+:10E9B0000FCE5355E19FD7C5718BE7DF475E0BFC48
+:10E9C000661DC755B41C675F8F70BF376D6ABE9EEA
+:10E9D000E7BB72C07FF51933014F6A727E5EE8951E
+:10E9E000785FEDFC84EF5B09DFA57D73D3F7E1A8C9
+:10E9F000893E49C86B4F9A75FC617DCA7BEB14EC6C
+:10EA000055EA3E5E69CF743449BBA28CC4FF0B3417
+:10EA10003D6F2FE0BB72664ADDA20FEB6BDAED6E45
+:10EA2000E83F860BBB8DFCBE40E596E7ED4ED55B1F
+:10EA30000BD329DC3F8D5BCA147E61E77CD4715C0B
+:10EA4000C23F4F3DBBC0057D7C6977431F3539C749
+:10EA5000E6E1DD31CBE0FF7259C355DC97279D021B
+:10EA6000D89F8F43DDACDF5A1C48415D3DE4D15057
+:10EA7000273FA638F1AEBF1E4FB76F71C2CF0A1441
+:10EA800027EAB7B5A9DD35D9CCBF76E60C37F09CBF
+:10EA9000F155EA6123DCEA76706B5053F4B5A66C4D
+:10EAA000D4F30DFF29F7A6544D8AF7D71B7E141D0A
+:10EAB000FC221DF1F547D46D77837F806CEE5E8379
+:10EAC0003FECA0FEA66952BF8DD9D1E5FD393B616F
+:10EAD0004753ABF4758D8DEF99914F0CDDE6CDC1A9
+:10EAE000FE2BD77CBE255BCE397EBD8C713703B83B
+:10EAF0003BB65E16C3F13D46FD1D786B32EABA2681
+:10EB0000A3AE6B32EABA26A3AE6B32EABA26A3AE44
+:10EB10006B32EABA26A3AE6B32EABA26A913AE97D5
+:10EB2000F6DD8E87A41DEA08C87842BCB8B9EAC7EA
+:10EB3000D55D17558D5377A5145786C45DF67BBDFB
+:10EB4000DE3DA6CECAFEAE26F87BD5E0847B1E4312
+:10EB50005ED26371B338546BF1163C60177CF0548D
+:10EB60008D5B6F8DE9CF2EF5D9CB649B8F7BA82C65
+:10EB70009A655251C734EE2356EF84DFE09CF01BB8
+:10EB8000B4F01BD3ECB8DFFCD6C2AE5DAAE7090136
+:10EB9000C9136C72BF5B3732AE307D2F399370E58D
+:10EBA000B331B8C20F9A159063EDA095BA743F23A4
+:10EBB000F84F25377F9C3F0ECE84749C99961ADAC5
+:10EBC000877DA6B5A5BA9117B3BF8B9D9DDCA6889E
+:10EBD000BFAFA106D9771CBC49479E7CEFC4D17357
+:10EBE000BFE1F9F7FE835DF29DAD93D72EFAFFE00A
+:10EBF0004D4D95AE8F5F77847DE75996EA54B643C5
+:10EC00008E57D5162A92BAB89A2AFE50A33DAE580E
+:10EC100080A377D33CDC77B5B5E139C899C3FE2E24
+:10EC2000EFDF2CA3BE6B1A6ADECBF4D9EC3C37BE07
+:10EC3000AB4DCD3D44050B804775C5B0ABB3D4ADEE
+:10EC400060DD6319DEBF83BFDC5ECCA756E3FE96B2
+:10EC50005397B6B34BEE63CE42DCFB32ABAB1FF542
+:10EC6000862D6F9E907AC2B20CD742D41BB6BC7967
+:10EC70005AA7735CFD8A1BE5B213ABAB7F82F866C3
+:10EC8000EB3E9F1067FDA1094974FBC0E4EEF30958
+:10EC900071AE053FF89D4E3F534CB8AF5643945C60
+:10ECA000D5BB1DF2F9EBFE4B7FCFD3A8C4C9A7AAF1
+:10ECB000745C9C7482C2B0E7D1C50EF9FE973371C3
+:10ECC000FD3CD4DBA8D8B510F338AFFD35ECF8E245
+:10ECD000AD9EA7C127CF38770EF1793558C7900D73
+:10ECE000ED19E3BBE429D5DB88B6363D60927E356D
+:10ECF000588AF66D35F420FAD92F76814FED93F3CB
+:10ED00006E2C623ACF1A9AB7DE8E78E9D98DFE73EF
+:10ED1000659E5EEC37B6EEDF699C8FE5D98779C3D7
+:10ED200085AAE4F9C337EA6DCC2EC2553A0E1D37D9
+:10ED3000FCA8AC93E4FBE758FB395EA51A78F9FD13
+:10ED400072B3BC47204F4C7EEA5E5D0A7958DEA361
+:10ED500086BCAF619CEC99528FF96E7B0DC87EC763
+:10ED60000D3B657C6C39AFE3A3B485A6E004E40DEC
+:10ED7000531E0D4E80BC53768CDA5CDCBE1018B589
+:10ED8000217F78E16F476DE87FC14375E3E1BF56AE
+:10ED9000AD09DFC2B251593F9DF71A9277C2E8041C
+:10EDA000E46F854D6F59026CB7739EE67D93F2B7A1
+:10EDB000228963D30D5B9AFEA84AB087E9CF90E41D
+:10EDC000AB549D25E3BE14DDFF7D8F3EA8C28E6E41
+:10EDD00008B2DC09F637E769D3E54812DFB0AC6B5F
+:10EDE000317083F3B5A4713F3347BE3CC5C023E403
+:10EDF0008F8D8C37FEA6B7BE42BEC879DC187E8CDC
+:10EE00004D311C26C45DEFEB1117FC2079DEDABB17
+:10EE10001ED98AF76D53E3768BBC8FD7F46D45DB33
+:10EE2000DAFA9E258724BF4C9ACFF965127D9D9C06
+:10EE300063E4687BF0F3AD39E3ECCB76702DD10E53
+:10EE40004E9A4337E0BD7AD29FEA0E481C09DD0F87
+:10EE50007CD9D96A7723AEECFA55A5D8D7B7F5A9EE
+:10EE6000328FA9FA47D951A7CC0F545211FCE6872B
+:10EE7000DA11E0E1EC243C0C48DD72894370AEDD30
+:10EE80007807B6AD714A3E12F3EB3653E8C3AD983E
+:10EE900097E590EF110CB745A62C7C6F9AE2EE4AED
+:10EEA000C82BCE2E9915049DDD190A83EFE8CF15E6
+:10EEB00037EAC8D5693AAED6A80DAD7B79FC2D35B9
+:10EEC0002CB8F15BE007F36FB7AC977645D94CB13E
+:10EED000DB5C0A29FAFF67702DC47B3DF63DAD6708
+:10EEE0005BB0EF20DEFB4AF099B5A88FFE955DE49C
+:10EEF0008906D58099CFD3338104B77BEE2C94B8A3
+:10EF000013A586C6FB91FF2C4F953A6ACF04D71301
+:10EF1000F86EDAD37CA3E4F587FEA4C7FBD1A5295C
+:10EF20006EE4713DF35C1B71AE9E475D32FE9AA2AA
+:10EF3000F30B3CA1EBA767A97ECE9EE64C799FC55B
+:10EF4000EEA167876732BEBF5932BCE5D5A803186A
+:10EF5000DF1F7B66703FB74F290D77DE073E737565
+:10EF6000795794B9E4DE4EDE79E3137B747D86F144
+:10EF70001DAC7D8923E9FDFEBFFE80CBB3202200BE
+:10EF80000000000000000000040835000000000040
+:00000001FF
diff --git a/firmware/cis/3CCFEM556.cis.ihex b/firmware/cis/3CCFEM556.cis.ihex
new file mode 100644 (file)
index 0000000..e4d92b1
--- /dev/null
@@ -0,0 +1,13 @@
+:1000000001030000FF152D050033436F6D004D65A2
+:100010006761686572747A2033434346454D3535D0
+:1000200036004C414E202B2035366B204D6F6465D9
+:100030006D0000FF20040101560521020000060B9F
+:1000400002004D000000006B000000FF001303439E
+:100050004953210206001A060507001067021B0912
+:1000600087011901556430FFFFFF00130343495313
+:10007000210202001A060527001177021B09A701B9
+:090080001901552330FFFFFF00B8
+:00000001FF
+#
+# This card is MFC-compliant, but identifies itself as single function
+#
diff --git a/firmware/cis/3CXEM556.cis.ihex b/firmware/cis/3CXEM556.cis.ihex
new file mode 100644 (file)
index 0000000..895010b
--- /dev/null
@@ -0,0 +1,13 @@
+:1000000001030000FF152C050033436F6D004D65A3
+:100010006761686572747A20334358454D353536CB
+:10002000004C414E202B2035366B204D6F64656DA2
+:100030000000FF20040101350021020000060B0230
+:10004000004C0000000069000000FF00130343495A
+:1000500053210206001A0501070008631B098701E6
+:100060001901556430FFFFFF001303434953210278
+:1000700002001A0501270009631B09A70119015590
+:060080002330FFFFFF002A
+:00000001FF
+#
+# This card is MFC-compliant, but identifies itself as single function
+#
diff --git a/firmware/cxgb3/t3fw-7.1.0.bin.ihex b/firmware/cxgb3/t3fw-7.1.0.bin.ihex
deleted file mode 100644 (file)
index 1042f75..0000000
+++ /dev/null
@@ -1,1885 +0,0 @@
-:1000000060007400200380002003700000001000D6
-:1000100000002000E100028400070000E1000288E7
-:1000200000010000E0000000E00000A0010000006E
-:1000300044444440E3000183200200002001E0002A
-:100040002001FF101FFFD0001FFFC000E300043C91
-:1000500002000000200069881FFFC290200069D0C4
-:100060001FFFC29420006A101FFFC29820006A84FC
-:100070001FFFC29C200003C0C00000E43100EA3131
-:1000800000A13100A03103020002ED306E2A05000C
-:10009000ED3100020002160012FFDBC03014FFDA5F
-:1000A000D30FD30FD30F03431F244C107249F0D347
-:1000B0000FD30FD30F12FFD5230A00240A00D30F4A
-:1000C000D30FD30F03431F244C107249F0D30FD327
-:1000D0000FD30F14FFCE03421F14FFCB03421F1296
-:1000E000FFCCC0302D37302D37342D37382D373CED
-:1000F000233D017233ED00020012FFC4C0302F37E0
-:10010000002F37102F37202F3730233D017233ED6A
-:1001100000020012FFBEC0302737002737102737F4
-:1001200020273730233D017233ED03020012FFB95F
-:1001300013FFBA0C0200932012FFB913FFB90C028F
-:1001400000932012FFB8C0319320822012FFB71312
-:10015000FFB7932012FFB715FFB316FFB6C030D715
-:100160002005660160001B00000000000000000088
-:10017000043605000200D30FD30F05330C6E3B1479
-:100180000747140704437631E604360505330C6F40
-:100190003BED00020012FFA615FFA3230A00D720A3
-:1001A000070443043E0505330C0747146F3BF00377
-:1001B000020012FFA1C03014FFA1D30FD30FD30F41
-:1001C0009340B4447249F2D30FD30FD30F14FF9B63
-:1001D000834014FF9B834012FF9B230A0014FF9A65
-:1001E000D30FD30FD30F9340B4447249F2D30FD33C
-:1001F0000FD30F14FF95834012FF95C92F832084DE
-:10020000218522BC22743B0F8650B4559630B433FE
-:100210007433F463FFE60000653FE1655FDE12FFC3
-:100220007C230A0028374028374428374828374C91
-:10023000233D017233ED03020000020012FF7AC079
-:1002400032032E0503020012FF7813FF819320C0B2
-:1002500011014931004831010200C00014FF7E0441
-:10026000D23115FF7D945014FF7D04D33115FF7CEE
-:10027000945014FF7C04D43115FF7C24560014FFE5
-:100280007B04D53115FF7B24560010FF7A03000054
-:10029000000000000000000000000000000000005E
-:1002A000000000000000000000000000000000004E
-:1002B000000000000000000000000000000000003E
-:1002C000000000000000000000000000000000002E
-:1002D000000000000000000000000000000000001E
-:1002E000000000000000000000000000000000000E
-:1002F00000000000000000000000000000000000FE
-:1003000000000000000000000000000000000000ED
-:1003100000000000000000000000000000000000DD
-:1003200000000000000000000000000000000000CD
-:1003300000000000000000000000000000000000BD
-:1003400000000000000000000000000000000000AD
-:10035000000000000000000000000000000000009D
-:10036000000000000000000000000000000000008D
-:10037000000000000000000000000000000000007D
-:10038000000000000000000000000000000000006D
-:10039000000000000000000000000000000000005D
-:1003A000000000000000000000000000000000004D
-:1003B000000000000000000000000000000000003D
-:1003C000000000000000000000000000000000002D
-:1003D000000000000000000000000000000000001D
-:1003E000000000000000000000000000000000000D
-:1003F00000000000000000000000000000000000FD
-:1004000000000000000000000000000000000000EC
-:1004100000000000000000000000000000000000DC
-:1004200063FFFC000000000000000000000000006E
-:100430000000000000000000000000001FFC0000A1
-:100440001FFC0000E30005C81FFC00001FFC0000AB
-:10045000E30005C81FFC00001FFC0000E30005C806
-:100460001FFFC0001FFFC000E30005C81FFFC00042
-:100470001FFFC018E30005C81FFFC0181FFFC018EA
-:10048000E30005E01FFFC0181FFFC28CE30005E07A
-:100490001FFFC28C1FFFC28CE30008541FFFC290D5
-:1004A0001FFFC58CE3000854200000002000016AF3
-:1004B000E3000B502000018020000180E3000CBC11
-:1004C0002000020020000203E3000CBC2000021CFC
-:1004D00020000220E3000CC02000022020000226A1
-:1004E000E3000CC42000023C20000240E3000CCCDE
-:1004F0002000024020000249E3000CD02000024C02
-:1005000020000250E3000CDC2000025020000259C1
-:10051000E3000CE02000025C20000260E3000CEC31
-:100520002000026020000269E3000CF02000026C51
-:1005300020000270E3000CFC200002702000027911
-:10054000E3000D002000028C2000028CE3000D0C63
-:100550002000029020000293E3000D0C200002AC6A
-:10056000200002B0E3000D10200002D0200002F2B3
-:10057000E3000D14200003B0200003B0E3000D38A9
-:10058000200003B0200003B0E3000D38200003B0CA
-:10059000200003B0E3000D38200003B0200003B0BA
-:1005A000E3000D38200003B020006BA8E3000D38F5
-:1005B00020006BA820006BA8E3007530000000004D
-:1005C00000000000000000001FFC00001FFC0000F5
-:1005D0001FFFC5901FFFC67020006BA820006BA8EE
-:1005E000DEFFFE000000080CDEADBEEF1FFFC2A064
-:1005F0001FFCFE001FFFC0941FFFC5C0300000009D
-:10060000003FFFFF8040000010000000080FFFFFC8
-:100610001FFFC26D000FFFFF804FFFFF8000000033
-:1006200000000880B000000560500000600000007D
-:1006300040000011350000004100000010000001E2
-:1006400020000000000010007FFFFFFF40000000BE
-:1006500005000000800000190400000000000800F0
-:1006600010000005806000007000000020000009FC
-:10067000001FF8008000001EA0000000F80000002D
-:1006800007FFFFFF080000001800000001008001C4
-:10069000420000001FFFC21D1FFFC0DC00010080E0
-:1006A000604000001A0000000C0000000000300054
-:1006B000600008008000001C000100008000001A9B
-:1006C00080000018FC0000008000000100004000D5
-:1006D000030000008000040050000003FFFFBFFF84
-:1006E0001FFFC3D400000FFFFFFFF000000016D073
-:1006F0000000FFF7A50000001FFFC4B01FFFC4618A
-:100700000001000800000B20202FFF801FFFC455B0
-:1007100000002C00FFFEFFF800FFFFFF1FFFC57861
-:1007200000002000FFFFDFFF0000FFEF01001100CD
-:100730001FFFC3D21FFFC590FFFFEFFF0000FFFBAD
-:100740001FFFC6301FFFBEA0FFFFF7FF1FFFC064E3
-:100750000000FFFD1FFFC6200001FBD01FFFC5B03A
-:100760001FFFC6601FFFC591E0FFFE001FFFC5A071
-:10077000000080001FFFC53C1FFFC5B41FFFC068FD
-:100780001FFFC4D01FFCFFD800010081E10006005C
-:10079000000027101FFCFE301FFCFE70E10002006D
-:1007A0001FFFC5381FFFC5500003D0901FFFC56451
-:1007B0002B5063802B5079802B5090802B50A6803B
-:1007C0001FFFC4690100110F202FFE0020300080A0
-:1007D000202FFF000000FFFF0001FFF82B50B200A8
-:1007E0002B50B208000100102B50B1802B50B2806A
-:1007F0002B50BA00000100112B50BD282B50BC809B
-:100800002B50BDA020300000DFFFFE005000000292
-:1008100000C0000002000000FFFFF7F41FFFC06CE3
-:10082000000FF80004400000001000000C40000021
-:100830001C400000E00000A01FFFC5401FFD000895
-:100840001FFFC5541FFFC5681FFFC57CE100069050
-:10085000E10006EC000000000000000000000000C5
-:100860000000000001000000000000000000000087
-:100870000000000020100040201000402010004028
-:1008800020140080200C0000200C0000200C000030
-:1008900020100040201400802014008020140080CC
-:1008A000201800C0201C0100201C0100201C010099
-:1008B00020200140201800C0201800C0201800C0CF
-:1008C000201C0100201800C0201800C0201800C003
-:1008D000201C010020200140202001402020014058
-:1008E00020200940202009402020094020200940E4
-:1008F00020240980FFFFFFFFFFFFFFFFFFFFFFFF37
-:1009000000000000000000000000000000000000E7
-:1009100000000000200052FC200051CC200052FCBE
-:10092000200052FC200051082000510820005108EE
-:1009300020004F4820004F4820004F4020004EAC80
-:1009400020004D5420004B342000490800000000D6
-:1009500000000000200052CC200051982000523CA2
-:100960002000523C20004FF020004FF020004FF0BC
-:1009700020004FF020004FF020004F3820004FF0B3
-:1009800020004C7420004AE4200048B4000000001D
-:100990000000000020000BE0200038BC200004C054
-:1009A000200044A820000BD820003FB4200003F012
-:1009B000200044682000489020003CC420003BE018
-:1009C00020003838200036C42000343420002F9412
-:1009D00020003A3C20002BF4200028282000653419
-:1009E000200023B4200020942000204020001D2C53
-:1009F000200018402000157020000DEC20000C2471
-:100A00002000113420001320200041AC20003C784D
-:100A100020000BE8200004C00000000000000000DF
-:100A200000000000000000000000000000000000C6
-:100A300000000000000000000000000000000000B6
-:100A400000000000000000000000000000000000A6
-:100A50000000000000000000000000000000000096
-:100A60000000000000000000000000000000000086
-:100A70000000000000000000000000000000000076
-:100A80000000000000000000000000000000000066
-:100A900000000000000000003264000000000000C0
-:100AA0003264000064006400640064006400640058
-:100AB000640064000000000000000000000000006E
-:100AC0000000000000000000000000000000000026
-:100AD0000000000000000000000000000000000016
-:100AE0000000000000000000000000000000000006
-:100AF00000000000000000000000000000001000E6
-:100B000000000000000000000000000000000000E5
-:100B100000000000000010000000000000000000C5
-:100B200000000000000000000043238000000000DF
-:100B300000000000000000000000000000000000B5
-:100B400000000000000000000000000000000000A5
-:100B5000005C94015D94025E94035F940043000086
-:100B60000000000000000000000000000000000085
-:100B70000000000000000000000000000000000075
-:100B80000000000000000000000000000000000065
-:100B9000005C90015D90025E90035F900053000046
-:100BA0000000000000000000000000000000000045
-:100BB0000000000000000000000000000000000035
-:100BC0000000000000000000000000000000000025
-:100BD000009C94001D90019D94029E94039F940498
-:100BE0000894050994060A94070B9400430000003A
-:100BF00000000000000000000000000000000000F5
-:100C000000000000000000000000000000000000E4
-:100C1000009C90019D90029E90071D90039F900460
-:100C20007890057990067A90077B90005300000039
-:100C300000000000000000000000000000000000B4
-:100C400000000000000000000000000000000000A4
-:100C500000DC94001D9001DD9402DE9403DF940417
-:100C60000494050594060694070794080894090956
-:100C7000940A0A940B0B940043000000000000004B
-:100C80000000000000000000000000000000000064
-:100C900000DC9001DD9002DE900B1D9003DF9004DC
-:100CA000B49005B59006B69007B79008B89009B90A
-:100CB000900ABA900BBB90005300000063FFFC0049
-:100CC0002000696410FFFF0A00000000200069880E
-:100CD00000D23110FFFE0A0000000000200069D0A1
-:100CE00000D33110FFFE0A000000000020006A104F
-:100CF00000D43110FFFE0A000000000020006A84CA
-:100D000000D53110FFFE0A000000000063FFFC0068
-:100D1000E00000A012FFF78220028257C82163FF83
-:100D2000FC12FFF303E83004EE3005C0309320944A
-:100D300021952263FFFC00001FFFD000000400206B
-:100D40001FFFC5901FFFC670200A0011FFFB13FF95
-:100D5000FB03E63101020016FFFA17FFFAD30F7703
-:100D60006B069060B4667763F85415505419E60F1B
-:100D7000140063FFF90000006C1004C020D10F00C4
-:100D80006C1004C0C71AEF06D830BC2BD720857270
-:100D90000D4211837105450B957202330C237601C8
-:100DA0007B3B04233D089371A32D12EEFE19EEFE4A
-:100DB000A2767D632C2E0A00088202280A01038E87
-:100DC000380E0E42C8EE29A67E6D4A050020880026
-:100DD000308C8271D10FC0F0028F387FC0EA63FF80
-:100DE000E400C0F1C050037E0CA2EE0E3D1208825A
-:100DF0000203F538050542CB5729A67E2FDC100FDC
-:100E00004F366DFA0500208800308CBC75C0300864
-:100E1000E208280A01058338030342C93E29A67E59
-:100E20000D480CD30F6D8A0500208800B08C8271AC
-:100E3000D10FC05008F53875C0C163FFBBC0600258
-:100E4000863876C0DA63FFD46C101216EED8C1F87B
-:100E5000C1E72B221E2C221DC0D07BC12F292006CA
-:100E6000D7B0299CFACC57282070288CFF282470F2
-:100E700064915C2AB0000EA80C6481670FA90C6411
-:100E800092B3C1E97EA13969AC2F600036292006F2
-:100E9000D7D0299CFACC57282070288CFF282470A2
-:100EA0006491352AD0000EA80C6481640FA90C64EB
-:100EB000931BC1E97EA10968AC09C020D10F0000D5
-:100EC000002D25028A32C0900A6F5065F5AD2924A5
-:100ED000670908476585A92F200C18EEB50CFE118F
-:100EE000A8EE28E286B44978930260057A19EEB13B
-:100EF00009F90A2992A3689007882009880C65855A
-:100F00006627E28564756065558E7BC104D9B06043
-:100F10000001C0908B941CEEA80B88148CC40B0BA2
-:100F200047A8CC18EEA609BB1008CC029C7018EE9E
-:100F3000A41CEEA508A8010B88020C4C021BEEA114
-:100F40009C710B880298722C90232B902204C8105D
-:100F500006BB100C4C1208BB0228902107CC100CC9
-:100F600088100C88020B88021CEE998B330CBB0195
-:100F70008C340B880298739C999C748B958C399B4C
-:100F80007588968B38987688979C799B7898771C8B
-:100F9000EE9028E2850CFC082DC4CF08480B28E60B
-:100FA0008565550B2B221E2D221D7BD9022B0A0095
-:100FB00064BF062CB00728B000DA2006880A288211
-:100FC0004CC0D10B8000DBA065AFE763FEEB0000F7
-:100FD000292070659E9C6004E42A207065AEC36081
-:100FE00004DB00002EB0032C2067D4E065C1058A25
-:100FF000328C330AFF500C4554BC5564F4E619EEAC
-:1010000075882A09A90109880C64821BC0926000B6
-:10101000DD2ED0032A2067D4E065A0D88A328B3336
-:101020000AFC500B4554BC5564C4B919EE6A882AB1
-:1010300009A9017989D50BEA5064A4DD0CEE11C031
-:10104000F02F16132E16168AE78CE82A16128EE950
-:10105000DFC0AAEA7EAB01B1CF0BA85065834288FE
-:1010600037DBC0AE89991E789B022BCC012B161B57
-:1010700029120E2B0A0029161A7FC3077FC9027E88
-:10108000AB01C0B165B4988B352F0A002A0A007AEB
-:10109000C30564C3C72F0A0165F4842B12162B16EF
-:1010A00019005104C0C100CC1A2CCCFF2C16170C0F
-:1010B000FC132C16182B121A2A121BDC505818FA83
-:1010C000C0D0C0902E5CF42C12172812182F121BBF
-:1010D0002A121A08FF010CAA018834074C0AAB8BAC
-:1010E0002812192BC6162F86082A86092E74102955
-:1010F00024672E70038975B1EA2A7403B0990949EF
-:101100000C659DB52B20672D250265B3F42B221E9F
-:101110002C221D7BC901C0B064BD9E2CB00728B035
-:1011200000DA2006880A28824CC0D10B8000DBA0A0
-:1011300065AFE763FD8389BAB19965909788341CE0
-:10114000EE2698BA8F331EEE1F0F4F542FB42C8DFE
-:101150002A8A320EDD020CAC017DC9660A49516F44
-:1011600092608A3375A65B2CB0130AED510DCD0148
-:101170000D0D410C0C417DC9492EB012B0EE65E356
-:10118000C2C0D08E378CB88A368FB97CA3077AC993
-:10119000027EFB01C0D1CED988350AAD020E8E0881
-:1011A00078EB022DAC0189B7DAC0AF9B79BB01B1F6
-:1011B000CADCB0C0B07DA3077AD9027CEB01C0B114
-:1011C00064B15DC091292467C020D10F00008ADA84
-:1011D000B1AA64A0BC2E20672D250265E30B1FED8C
-:1011E000F98A3218EDFE0FAF0108FF0C65F2860A8E
-:1011F00048516F820260027DC090292467090A4726
-:1012000065A2F27BC901C0B064BCAE2CB00728B0A7
-:1012100000DA2006880A28824CC0D10B8000DBA0AF
-:1012200065AFE763FC9300000CE9506492EB0CEFB0
-:1012300011C080281611AFBF2F16198EF88BF7DA60
-:10124000E08FF92B1610ABFB7FBB01B1EA0CA85065
-:101250006580D68837DCE0AF89991C789B022CEC3E
-:10126000012C161B29120C2C0A0029161A7AE307E6
-:101270007AE9027FBB01C0C165C2A48B352C0A008C
-:101280002A0A007AE30564E1CA2C0A0164CE1160DF
-:10129000028D88341BEDD198DA8F331EEDCA0F4FC3
-:1012A000542FD42C8C2A8A320ECC020BAB010CBBEF
-:1012B0000C65BF0E0A49516E920263FF058A330A1C
-:1012C000AB5064BEFD2CD0130AEE510ECE010E0EB3
-:1012D000410C0C410ECC0C65CEE82FD012B0FF654E
-:1012E000F26EC0B08E378CD88A362FD2097CA30715
-:1012F0007AC9027EFB01C0B165BEC78835DBA0AEEE
-:101300008E78EB01B1AB89D7DAC0AF9D79DB01B143
-:10131000CAC0C07BA3077AB9027DEB01C0C165CE0C
-:10132000A1C090292467C020D10F88378C3698142B
-:101330000CE90C29161408F80C981D78FB072812E4
-:1013400014B088281614891D9F159B16C0F02B1207
-:101350001429161A2B161B8B147AE30B7AE90688CC
-:10136000158E1678EB01C0F165F1B929121A2F120A
-:10137000118A352E121B9A1AAFEE2F1210C0A0AF91
-:101380009F79FB01B1EE9F11881AC0F098107AE3A3
-:101390000A7EA9052A12017A8B01C0F164F08160EE
-:1013A000018289368B3799170BE80C981F09C90CF5
-:1013B00029161578EB07281215B088281615D9C0FC
-:1013C0009A199E188A1F2E12152A161A2E161BDA23
-:1013D000C0C0E08C177F930B7FA90688188F1978FF
-:1013E000FB01C0E165E13D29121A2F12138A352E47
-:1013F000121B9A1BAFEE2F1212C0A0AF9F79FB01F8
-:10140000B1EE9F13881BC0F098127AE30A7EA905FB
-:101410002A12037A8B01C0F165F1092E12162E16DD
-:10142000192A121B005104C0E100EE1AB0EE2E166C
-:10143000170EFF132F16180FCC01ACAA2F121A0E7D
-:10144000BC01ACFC7FCB01B1AA2A161B2C161A6377
-:10145000FC6200007FB30263FE3163FE2B7EB302A9
-:1014600063FC3463FC2E00006450C0DA20DBF058CB
-:1014700015DEC020D10FC09163FD7E00C09163FADC
-:101480004CDA20DB70C0D12E0A80C09A2924682C47
-:1014900070075814CED2A0D10F034C0B18ED51DBBE
-:1014A000C0A82878C3022BCDF8D9B063FA65000034
-:1014B0002A2C74DB40580E5063FAE80000002D25FA
-:1014C000027BC901C0B064B0172CB00728B000DAA5
-:1014D0002006880A28824CC0D10B8000DBA065AFB3
-:1014E000E7C020D10FC09163FC04022A02580250C9
-:1014F0000AA202060000022A0258024D0AA20206AF
-:101500000000DB70DA20C0D12E0A80C09E2924683A
-:101510002C70075814AEC020D10FC09463FBCF00CD
-:10152000C09663FBC9C09663FBC400002A2C74DB21
-:1015300030DC405BFE13DBA0C2A02AB4002F200CDD
-:1015400063FF27008D358CB77DCB0263FDD263FC32
-:10155000718F358ED77FEB0263FDC563FC6400009D
-:101560006C1004C020D10F006C1004C020D10F00FB
-:101570006C10042B221E28221DC0A0C09429240612
-:101580002A25027B8901DBA0C9B913ED08DA2028DE
-:10159000B0002CB00703880A28824CC0D10B800011
-:1015A000DBA065AFE7C020D10F0000006C1004295C
-:1015B00020062A2102689805289CF965811A0A0AE2
-:1015C0004C65A0F016ECFB2B629E1AECF86FB8028B
-:1015D0006000F12AA22668A0078B200ABB0C65B028
-:1015E000E32A629D64A0DD2B200C0CBC11A6CC2D3F
-:1015F000C2866FD9026000D71DECEF0DBD0A2DD257
-:10160000A368D0078E200DEE0C65E0C327C285C00D
-:10161000E06470BB1DECF468434D1CECF38A2B0CAA
-:10162000AA029A7089200899110D99029971882A45
-:1016300098748F329F75282104088811987718ECC8
-:10164000E40CBF11A6FF2DF285A8B82E84CF2DDCA7
-:10165000282DF685C85A2A2C74DB40580DE7D2A0F5
-:10166000D10FC020D10F00002C9CF964C08D2C201C
-:10167000668931B1CC0C0C472C24666FC669709E0C
-:101680006618ECDA89308F2B0989400B991009FF15
-:101690000208FF029F708C2008CC110DCC029C71B7
-:1016A0008A339A7389329972882A98748F349F7515
-:1016B00063FF820000CC57DA20DB30DC405814B8DE
-:1016C000C020D10F00DA20C0B658154763FFE500EF
-:1016D000DA2058154563FFDC00DA20DB30DC40DD22
-:1016E000505815C7D2A0D10F2B21045813DA1DEC86
-:1016F000BD2B200CC0E02E246663FF842F2123C065
-:10170000C87FC30263FF792C20662B2104B1CC0C67
-:101710000C472C24665813CF1DECB32B200CC0E0D3
-:101720002E246663FF5A00006C1004C0B7C0A116D7
-:10173000ECB015ECA2D720D840B822C04005350245
-:101740009671957002A438040442C94B1AEC95199D
-:10175000EC9629A67EC140D30F6D4A050080880013
-:10176000208C220A88A272D10FC05008A53875B00B
-:10177000E363FFD76C100893149412292006655276
-:1017800088C0716898052A9CF965A29816EC892989
-:1017900021028A1409094C6590C78AA00A6A512A55
-:1017A000ACFD65A0BCCC5FDB30DA208C1258147C19
-:1017B000C0519A14C7BF9BA98E142EE20968E0603D
-:1017C0002F629E1DEC7A6FF8026000812DD2266890
-:1017D000D0052F22007DF9752C629DC79064C06DE5
-:1017E0009C118A142B200C2AA0200CBD11A6DD0A06
-:1017F0004F14BFA809880129D286AF88288C09799F
-:101800008B551FEC6C0FBF0A2FF2A368F00528223E
-:10181000007F894329D285D49065907760003D0090
-:10182000002B200C1FEC640CBD11A6DD29D2860F05
-:10183000BF0A6E96102FF2A368F00488207F8905F6
-:1018400029D285659165DA205814E7600013DA2003
-:10185000C0B65814E5600009C09063FFB9DA20589B
-:1018600014E28914899109FE506551E48C128D149B
-:10187000DA20DBD08DD09E100D6D515813549A1480
-:1018800064A208C75F8FA195A9C0510F0F479F128F
-:1018900063FEFB00C091C0F12820062C2066288C36
-:1018A000F9A7CC0C0C472C24666FC6088D148DD17B
-:1018B00070DE01C090DD90648159C9D32A12012BDA
-:1018C00021045813648A14C0B02B24668EA92AA060
-:1018D000200E28141CEC438D1415EC37C1700A77C8
-:1018E0003685562DDC28AC2C9C13DED0A8557CD335
-:1018F000022EDDF8D3E0DA40055B02DC305BFF8AC4
-:10190000D4A028200CB455C0D02B0A882F0A800CF4
-:101910008C11A6CC29C285AF3FAB9929C6851CEC9A
-:101920002CDEF0AC882D84CF28120329120478F322
-:10193000022EFDF8289020D3E007880CC17008081B
-:1019400047289420087736657FAB891413EC2A89E1
-:1019500090C0F47797491BEC28C1CA28210485144C
-:10196000099E4006EE11875304881185520E8802A5
-:101970000C88029BA09FA18F2B9DA598A497A7954B
-:10198000A603FF029FA22C200C1EEC11AECE0CCCA5
-:101990001106CC082BC2852DE4CF2BBC202BC6858D
-:1019A0002A2C748B12580D14D2A0D10F28203DC0C0
-:1019B000E07C877F2E24670E0A4765A07B1AEC0F18
-:1019C00088201EEBFD8F148EE48FF40888110A889E
-:1019D000020F8F14AFEE1FEC0A98910FEE029E904B
-:1019E0001EEC09C0801AEBFA2CD285AABAB8CC2812
-:1019F000A4CF2CD6852C21022F20700ECC02B1FF53
-:101A00002F24702C2502C020D10F87148770070760
-:101A10004763FD6E282123C099798B0263FE9ADD0E
-:101A2000F063FE9500DA20DB308C12DD505814F4A0
-:101A3000D2A0D10FC0E163FF7A8B148C12DD50C0AD
-:101A4000AA2E0A802A2468DA20581360D2A0D10F67
-:101A5000007096552B629E6EB8531DEBD42DD22686
-:101A600068D0048E207DE9452A629DCBAF2B2104EE
-:101A70002C20665812F8C090292466821418EBE2D4
-:101A80008F2108FF019F21C020D10F008B10C9B802
-:101A90008CA00C6C51CCCC8E241FEBD08DE19E140D
-:101AA0000FDD029DE18810658FA9C020D10FDA20DB
-:101AB000C0B658144DC020D10F0000006C1006298C
-:101AC0002102C0D07597102A32047FA70A8B357F78
-:101AD000BF052D25020DD902090C4C65C18216EBFC
-:101AE000B41EEBB228629EC0FA78F3026001882926
-:101AF000E2266890078A2009AA0C65A17A2A629DCD
-:101B0000DFA064A1772B200C0CBC11A6CC29C286C7
-:101B1000C08C79830260015719EBA709B90A299291
-:101B2000A3689007882009880C65814327C2851C1B
-:101B3000EBA964713A8931098B140CBB016FB11D9B
-:101B40002C20669F10B1CC0C0C472C24666EC6026C
-:101B500060014009FF5065F13A8A102AAC188934B7
-:101B6000C0C47F973C18EBAA1BEBA98F359C719BD7
-:101B7000708B209D7408BB029B72C08298751BEB12
-:101B8000A50F08409B730F881198777FF70B2F21C3
-:101B900002284A0008FF022F2502C0B4600004009A
-:101BA0000000C0B07E97048F362F25227D970488D1
-:101BB000372825217C9736C0F1C0900AF9382F3C90
-:101BC0002009094264908619EB7618EB7728967EF7
-:101BD00000F08800A08C00F08800A08C00F0880045
-:101BE000A08C2A629D2DE4A22AAC182A669D893019
-:101BF0007797388F338A3218EB8007BE0B2C21047D
-:101C0000B4BB04CC1198E0C08498E1882B9DE59A80
-:101C1000E69FE71AEB78099F4006FF110FCC020AF6
-:101C2000880298E2C1FC0FCC022CE604C9B82C2033
-:101C30000C1EEB670CCA11AECC06AA0829A2852D92
-:101C4000C4CF09B90B29A685CF5CC020D10FC081B4
-:101C5000C0900F8938C08779880263FF7263FF667E
-:101C600000CC57DA20DB30DC4058134DC020D10FB8
-:101C7000DA205813DD63FFE8C0A063FE82DA20C0DB
-:101C8000B65813D963FFD900DB402A2C74580C5A7C
-:101C9000D2A0D10F8A102B210458126E1EEB44C023
-:101CA000D02D246663FEB1006C1006D62019EB3FE0
-:101CB0001EEB4128610217EB3E08084C65805F8AE5
-:101CC000300A6A5169A3572B729E6EB83F2A92263A
-:101CD00068A0048C607AC9342A729D2C4CFECAAB71
-:101CE0002B600CB64F0CBD11A7DD28D2860EBE0AA4
-:101CF00078FB269C112EE2A32C160068E0052F62CB
-:101D0000007EF91522D285CF2560000D00DA60C073
-:101D1000B65813B5C85A60010F00DA605813B2659F
-:101D20005106DC40DB308D30DA600D6D51581227E2
-:101D3000D3A064A0F384A1C05104044763FF6D00E5
-:101D4000C0B02C60668931B1CC0C0C472C64666F36
-:101D5000C60270960A2B610458123EC0B02B64660E
-:101D60006550B42A3C10C0E7DC20C0D1C0F002DFCF
-:101D7000380F0F4264F09019EB0A18EB0B28967E8F
-:101D80008D106DDA0500A08800C08CC0A089301DC0
-:101D9000EB1A77975388328C108F3302CE0BC02406
-:101DA00092E12261049DE00422118D6B9BE59FE787
-:101DB00098E61FEB100998400688110822020FDDF3
-:101DC00002C18D9DE208220292E4B4C22E600C1F73
-:101DD000EB000CE811A7882C8285AFEE0C220B2BB0
-:101DE000E4CF228685D2A0D10F28600CD2A08C111E
-:101DF00019EAF80C8D11A988A7DD2ED2852B84CF86
-:101E00000ECC0B2CD685D10FC0F00ADF387FE8024C
-:101E100063FF6C63FF6000002A6C74C0B2DC20DDDD
-:101E20004058121CC0B063FF63C020D10F000000F7
-:101E30006C10042C221D2A221EC049D320293006F2
-:101E4000243468C0407AC105DDA060000200C0D023
-:101E50006E9738C08F2E0A802B3014C09629340616
-:101E60000EBB022E31022B34147E8004243502DE98
-:101E7000407AC10EC8ABDBD0DA302C0A00580A76A3
-:101E80002E31020E0F4CC8FEC020D10F6895F828E5
-:101E9000310208084C658FEF1AEAC61CEAC42BA26F
-:101EA0009EC09A7B9B462BC22668B0048D307BD99E
-:101EB0003B29A29DC0E3CB9394901BEAD72D31041C
-:101EC0009B9608DD110EDD029D979D9112EAD4C00C
-:101ED000E524C4A22E34062F310228A29D02FF025F
-:101EE000288C3028A69D2F3502C020D10FDA30C0B3
-:101EF000B658133DC020D10F6C10062920066898F3
-:101F000005289CF965825D29210209094C6592101A
-:101F1000CD51DB30DA20044C025812A1C051D3A0BD
-:101F2000C7AF2A360AC0E019EAA31DEAA91FEAA230
-:101F30008A3A16EA9FB1AC64C13528629E6F880266
-:101F40006001F129DC332992266890078B2009BBB8
-:101F50000C65B1E027629DC08E6471D82B200C0CFB
-:101F6000BC11A6CC29C2867983026001D219EA91FC
-:101F700009B90A2992A397106890082822000988B5
-:101F80000C6581BB27C2856471B5292006299CF99F
-:101F90006491EC2C20668931B1CC0C0C472C246662
-:101FA0006EC6026001A109F85065819B883689F4EC
-:101FB000088C14AC991CEA810C99022C21049970AC
-:101FC00019EA980808479971892A0988100899021E
-:101FD00018EA95089902997228301329301204885A
-:101FE0001006991008990228302C9A740C88100851
-:101FF000C802098802987389379975883898768A53
-:1020000039C0819A771AEA888935987B9978098945
-:10201000140A9902997A8A30893277A73618EA76B3
-:102020008F33987CC084987D882B2E761129761268
-:102030002F761319EA700A9F4006FF1104CA11098E
-:1020400088020FAA02987EC1F90FAA022A7610C050
-:10205000AA600001C0A6ADBF0CBC11A6CC29C285E8
-:102060002EF4CF09A90B29C685655107C020D10FD1
-:102070002B200C0CBC1106CC0828C28609B90A6FAB
-:10208000890260012E2992A36890082A220009AAD9
-:102090000C65A11F2AC28564A11928203D0828408B
-:1020A00064808C843504841464408485F574537F83
-:1020B0008436048414644077745374293013C08CBC
-:1020C00079886CC0902924670908476580ED8820CD
-:1020D00089F484351FEA4B048414A4940F440294B9
-:1020E000A014EA4608881104880298A1843698A3AF
-:1020F000048414A4990F990299A219EA42ADB42854
-:10210000C2852E44CF288C1028C6852821022F2076
-:1021100070098802B2FF2F2470282502C020D10F39
-:1021200000CC57DA20DB30DC4058121DC020D10F24
-:10213000C09163FF8FDA20C0B65812AB63FFE10095
-:10214000DA205812A963FFD88A102B2104581141B4
-:102150001DEA201FEA192B200CC0E02E24668A3AC3
-:1021600063FE480000DA20DB30DC40DD50581324E9
-:10217000D2A0D10F2A2C74DB40580B1FD2A0D10F54
-:10218000292123C08879830263FE202A12002C2093
-:10219000662B21042CCC010C0C472C246658112DE5
-:1021A0001DEA0C1FEA052B200CC0E02E24668A3A9B
-:1021B00063FDF800DA2058128C63FF64DA205BFFBD
-:1021C0001CD2A0D10F0000006C10089515C061C191
-:1021D000B0D9402A203DC0400BAA010A64382A2009
-:1021E0000629160668A8052CACF965C33B1DE9F263
-:1021F0006440052F120564F29C2621021EE9EE06BA
-:10220000064C6562E315E9EA6440D98A3529300352
-:102210009A140A990C6490CC2C200C8B149C110CF1
-:10222000CC11A5CC9C122CC286B4BB7CB30260023C
-:10223000D38F110EFE0A2EE2A368E0098620D30F89
-:102240000E660C6562BE88122882856482B6891487
-:1022500064905EDA80D9308C201EE9E81FE9E91D20
-:10226000E9D68B148DD4D4B07FB718B88A293C1026
-:10227000853608C6110E66029681058514A5D50F10
-:10228000550295800418146D8927889608CB11088B
-:1022900088140EBB02A8D8299C200F88029BA19805
-:1022A000A088929BA3088814A8D80F880298A22A15
-:1022B000AC1019E9D4C0C08F141EE9C586128D1167
-:1022C000286285AEDD08FF0B2CD4CF2821022F66B3
-:1022D000858B352A2070098802ABAA2825022A247A
-:1022E00070C020D10F29529E18E9B16F9802600288
-:1022F0000828822668800829220008990C6591F92F
-:102300002A529DC1CA9A1364A1EF2B200C262006E5
-:102310000CB811A5882D82860EBE0A7DC30260020C
-:10232000022EE2A368E0082F22000EFF0C65F1F3F5
-:10233000288285DE806481FF9810266CF96461FF35
-:102340002C20668831B1CC0C0C472C24666EC6025A
-:102350006001BC08FD5065D1B617E9B419E9981AB7
-:10236000E99F2C21048B2D2830102F211D0C881063
-:102370000BFB090C88020A880209BB0264415289DE
-:1023800010C04D9B90979198928D35D9E064D06C98
-:10239000D730DBD0D8307FD713273C10BCE92632AA
-:1023A000168C3996E69CE78A37B4389AE80B1314F2
-:1023B0006430492A821686799A9696978C778A7D18
-:1023C0009C982B82172C7C209A9A2A9C189B998681
-:1023D0007BB03BB8896DB9218BC996A52692162A88
-:1023E000AC18B8999BA196A08BC786CD9BA22B92C7
-:1023F0001596A49BA386CB2CCC2026A605C0346BB7
-:10240000D4200D3B0C0DD8090E880A7FB705C0906B
-:102410009988BC88C0900B1A126DAA069988998B6E
-:10242000288C18C0D01BE9831CE98216E978B1FF1B
-:102430002A211C23E6130F0F4F26E6122F251D7F9E
-:10244000A906C0F0C08028251D05F6111AE9718F74
-:10245000202BE6152CE6162DE61726E6180AFA02BA
-:102460002AE614292006299CF96490FF29200C8D66
-:1024700015C0801AE9570C9C11AA99A5CCDA202B1B
-:10248000C2852894CF0B4B0B2BC685C0B08C165839
-:102490001114D2A0D10F8A356FA548D8308BD56DD5
-:1024A000A90C8A860A8A14CBA97AB337288C10C063
-:1024B00080282467080B4765B112DA20DB302C1224
-:1024C00006581137D3A0C0C1C0D02DA4039C1563FA
-:1024D000FD26863664610C8910C04D9B90979198BB
-:1024E0009263FEA4C08163FFC78A15CCA7DA20DB04
-:1024F000308C1658112BC020D10FDA20C0B65811DD
-:10250000BA63FFE400DA208B115811B763FFD900DA
-:102510009E178A132B210458104F8E17C0B02B24FE
-:102520006663FE34C08063FE09DA20DB308C16DD82
-:1025300050581233D2A0D10FDA205811AB63FFA844
-:102540002D2123C0C87DC30263FE0D8A132B2104F5
-:102550002C20669817B1CC0C0C472C246658103DE3
-:102560008E17C0D02D246663FDEE0000262123B017
-:102570006606064F262523656EF128206A7F8705AB
-:102580000829416490A5C0D01BE91C19E92B26201D
-:102590000723E61BB16609FA022BE61A28200A2D4A
-:1025A000E61D2AE61E09880228E61C88260606473C
-:1025B00028E6202B220826E53E2BE6212D24072C99
-:1025C00020062A206468C347B44463FE9EDB30DAE9
-:1025D000208D15C0CE2E0A802C24688C1658107BB6
-:1025E000D2A0D10F8E102A321616E8F30A2A1486CA
-:1025F000662BE61297E127E61328E614AA66096619
-:102600000296E02EEC4869ED50C14663FD7A000069
-:1026100064AFB419E8E928201689920A880C009161
-:102620000400881AA8B8982963FF9C002B21046E27
-:10263000B81E2C2066B8CC0C0C472C2466C9C09E52
-:10264000178A135810048E17C0348F20C0D02D2441
-:1026500066C06826240663FF2C008D35C08064D0D8
-:102660004AD9E0DC30DBE0DF301AE8F4B188B4FFAF
-:1026700017E8F486C9249DFF8DC82CCC102D463058
-:102680000767012D46320A66011DE8EE264631AD88
-:102690006D2D463326F21597B796B684C3BCBB940E
-:1026A000B58D35299C107D83C22F211DC14663FD48
-:1026B0004B0000006C1006292006289CF86582C398
-:1026C0002921022B200C09094C6590E116E8B90C70
-:1026D000BA11A6AA2DA2862C0A127DC3026002900E
-:1026E00019E8B509B90A2992A36890078C2009CC8A
-:1026F0000C65C27C29A2856492762D629E1AE8AB95
-:102700006FD8026002722AA22629160168A0082B3F
-:1027100022000ABB0C65B26029629DC18C6492588C
-:102720002A21200A806099102C203CC7EF000F3E20
-:10273000010B3EB1BD0FDB390BBB098F260DBD115F
-:102740002DDC1C0D0D410EDD038E27B1DD0D0D417D
-:102750000FEE0C0DBB0B2BBC1C0BB7027EC71C2C49
-:1027600021257BCB162D1AFC0CBA0C0DA16000099B
-:102770003E01073EB1780987390B770A77EB026093
-:10278000020A2C2123282121B1CC0C0C4F2C25230B
-:102790007C8B29B0CD2D2523C855DA20DB30580F8E
-:1027A000FA292102CC96C0E80E9E022E2502CC57B3
-:1027B000DA20DB30DC4058107AC020D10F2C2066A4
-:1027C0008931B1CC0C0C472C24666EC6026001D353
-:1027D00009FD5065D1CD2F0A012E30112922146434
-:1027E000E01128221B090C4400C10400FA1A0A88CF
-:1027F0000228261B2E3010C0A0C0B088301CE86E06
-:1028000094129513C04125203C2CC022088D1477CA
-:1028100087052F0A010CFA38C0F2C0840858010F4E
-:102820005F010F4B3805354007BB10C0F0084F382B
-:1028300008FF100FBB0228ECFEC0F0084F38842BB5
-:102840000BA8100AFF102A21200F88020B8802080B
-:10285000440218E87D8F110844022821250A2A1411
-:102860000828140488110A88022A210494F08B2075
-:1028700004E41008BB1104BB02C04A04BB029BF174
-:10288000842A08AB110BEB0294F40A54110B440296
-:102890000555100D1B4094F707BB100B550208554A
-:1028A00002C08195F68433C05094F3B1948B329575
-:1028B000F898F99BF2C080C1BC24261498FB9BF5C4
-:1028C00099FA853895FC843A94FD8B3B9BFE8839B8
-:1028D00098FF853525F6108436851324F6118B373D
-:1028E00084122BF612C0B064C08189307797468D70
-:1028F0003288332E30108F111CE840099940069918
-:10290000112CF614C0C42CF6158C2B2DF61A28F6B3
-:102910001B2BF61904A81109880208EE0219E835E4
-:10292000C18008EE0209C90229F6162EF618C09ECB
-:10293000600004000000C09A2F200C18E8250CFE4F
-:1029400011A8FFA6EE2DE2852BF4CF0D9D0B2DE6F1
-:1029500085C87F8A268929A7AA9A260A990C090977
-:102960004829252565504CC020D10F00C09A63FF2F
-:10297000C6DA2058109D63FE34DA20C0B658109A8B
-:1029800063FE2A00689738C020D10F0000DA20DBF0
-:1029900070581057C0B0C0C10ACA390ACB3865BDDB
-:1029A000E063FE098A102B2104580F2AC0B02B24A3
-:1029B0006663FE21DB402A2C7458090FD2A0D10F88
-:1029C000DA20580F2F63FCF76C1004C020D10F00E1
-:1029D0006C1004290A801EE81D1FE81D1CE7F50C79
-:1029E0002B11ACBB2C2CFC2DB2850FCC029ED19CA4
-:1029F000D0C051C07013E81914E81818E8162AB2AC
-:102A000085A82804240A234691A986B8AA2AB6854F
-:102A1000A98827849F25649FD10F00006C100AD6D7
-:102A200030283010292006288CF964829B68980B86
-:102A30002A9CF965A1B2022A02580F1189371BE7B7
-:102A4000DEC89164520E2A21020A0C4C65C2588DD0
-:102A50003019E7D774D7052E212365E29E2F929E69
-:102A60001AE7D36FF8026002532AA22668A0082C46
-:102A700022000ACC0C65C2442A929D64A23E9A159B
-:102A80001FE7CD8D67C1E664D00E2B620618E7CA3A
-:102A900064B0052880217B8B422B200C18E7C50CE5
-:102AA000BC11A8CC29C28679EB450FBE0A2EE2A341
-:102AB00068E0048F207EF9372CC2859C1864C233ED
-:102AC0002B212F87660B7B360B790C6F9D266ED2E0
-:102AD000462C203D7BC740CE5560001E2A200CC1ED
-:102AE000B28C205810759A1864A2458D6763FFCF89
-:102AF000C0C063FFC5D7B063FFD300C0E060000271
-:102B00002E60030EDB0C6EB20EDC700CEA11AA6AAA
-:102B10002AAC20580199D7A0DA20DB70C1C82D213A
-:102B20002058101B8C268B279A160CBB0C7AB334BA
-:102B30008F18896399F3886298F28E659EF82D60EC
-:102B4000108A189D1768D729C0D09DA92C22182B50
-:102B500022139CAB9BAA97A58E667E73026000979A
-:102B6000CF5860001FDA208B16580FE165A138633B
-:102B7000FFBDC081C0908F18C0A29AF999FB98FA46
-:102B800097F563FFD2DB30DA20DC40580F85C05167
-:102B9000D6A0C0C02BA0102CA4039B172C12080297
-:102BA0002A02066B02DF702D60038E179D149E10A3
-:102BB0000CDD11C0E0AD6D2DDC205801188C148B9C
-:102BC00016ACAC2C64038A268929ABAA0A990C9A04
-:102BD00026886609094829252507880C98662F222A
-:102BE00018A7FF2F261863FE96DA20DB30DC40DDC5
-:102BF00050581083D2A0D10FC0302C20668961B10B
-:102C0000CC0C0C472C24666EC6026000D2C0300982
-:102C1000FD5065D0CA8E6764E069647066DB608CC5
-:102C200018DF70DA202D60038E170CDD119E10ADB9
-:102C30006D2DDC201EE7845800F9232618DA208B3E
-:102C400016DC402F2213DD50B1FF2F2613580F241E
-:102C5000D2A0D10F0028203D084840658DE76F9530
-:102C60003EDA308DB56D990C8CA80C8C14CACF7CD3
-:102C7000D32D2AAC10C090292467090D4764DDC507
-:102C8000600092002C1208066B022D6C20077F0258
-:102C90008E17DA209E101EE76B58007D63FF9A00A6
-:102CA000C09163FFD1000000655081DA20DB60DC59
-:102CB00040580F3BC020C0F02FA403D10FDA20C032
-:102CC000B6580FC963FFE000006F950263FD6CDA30
-:102CD00020DB30DC40DD50C4E0580EBCD2A0D10F68
-:102CE0008A152B2104580E5B232466286010981740
-:102CF00063FF2100DA20580FBC63FFABC858DB30FC
-:102D0000DA20580EA12A210265AF9CC09409A902BD
-:102D100029250263FF91DB30DC40DD50C0A32E0A81
-:102D2000802A2468DA20580EA9D2A0D10FC020D161
-:102D30000FDA202B200C580FC563FF6B6C10042892
-:102D40002006C062288CF8658125C050C7DF2B2281
-:102D50001BC0E12A206B29212300A104B099292559
-:102D600023B1AA00EC1A0BC4010A0A442A246B04FA
-:102D7000E4390DCC030CBB012B261B6440692920D0
-:102D80000C1BE70B0C9A110BAA082FA2861BE70954
-:102D90006FF9026000B60B9B0A2BB2A368B0082C37
-:102DA00022000BCC0C65C0A42BA2851DE72D64B0BE
-:102DB0009B8C2B2421040DCC029CB08820C0C5081C
-:102DC00088110C880298B1882A08441198B48F346D
-:102DD00094B79FB5C0401EE6FE2DA2850E9E082525
-:102DE000E4CF2DDC282DA68529210209094C689401
-:102DF0001A689820C9402A210265A00B2A221E2B9E
-:102E0000221D7AB10265A079C020D10F2C21236543
-:102E1000CFDE6000082E21212D21237EDBD52B2241
-:102E20001E2F221D2525027BF901C0B064BFC413EB
-:102E3000E6DF2CB00728B000DA2003880A28824C8D
-:102E4000C0D10B8000DBA065AFE763FFA62A2C741E
-:102E5000C0B02C0A02580D951CE7039CA08B2008DB
-:102E6000BB1106BB029BA1893499A263FF790000C4
-:102E7000262468DA20DB30DC40DD50580FE1D2A098
-:102E8000D10FDA202B200C580F58C020D10F000092
-:102E90006C1006073D14C080DC30DB40DA20C047F0
-:102EA000C02123BC30032838080842774001B1DD37
-:102EB00064815A1EE6BB19E6BC29E67ED30F6DDAA3
-:102EC0000500508800308CC0E0C02025A03C14E6EE
-:102ED000BAB6D38FC0C0D00F87142440220F8940C8
-:102EE000941077F704C081048238C0F10B2810C019
-:102EF00044C02204540104FD3802520102FE380885
-:102F0000DD10821C07EE100E6E020EDD02242CFE78
-:102F1000C0E004FE380AEE100E88020D88028DAB68
-:102F20001EE6AA08D8020E880298B0C0E80428104D
-:102F30000E5E0184A025A125084411084402052540
-:102F400014045511043402C0810E8E3994B18FAA35
-:102F500084109FB475660C26A11FC0F2062614606B
-:102F60000009000026A120C0F20626140565020F04
-:102F7000770107873905E6100778100866020655BD
-:102F80000295B625A1040AE611085811082802087E
-:102F9000660296B7C060644056649053067E11C0C6
-:102FA000F489C288C30B340B96459847994618E6B6
-:102FB000919F410459110E99021FE68F020E470896
-:102FC000D80298420E99029F40C1E00E990299449E
-:102FD0002FA00CB4380CF91114E67E1EE675A4FF80
-:102FE000AE992E928526F4CF0E880B289685D10FA8
-:102FF0002BA00C1FE66F1CE6760CBE11ACBBAFEE2F
-:103000002DE28526B4CF0D3D0B2DE685D10FC08076
-:1030100005283878480263FEA263FE966C1006C04D
-:10302000C06570F18830C030088714778712C0B04F
-:10303000C0A619E661299022C030CC97C03160004B
-:1030400003C0B0C0A6C0E0C091C0D4C08225203C5F
-:103050000B3F109712831CC0700858010D5D0108CA
-:103060009738C0800B9838077710048810086802DA
-:10307000087702C0800D98382D3CFE0888100D9E00
-:10308000388D2B0AEE1008EE0207EE020CB8100F76
-:10309000DD02053B400EDD029D408920043D100805
-:1030A00099110D99022D210409A90208DD119941F8
-:1030B000872A05B9100D3D020ABB110DBB02087726
-:1030C0000297442821258712082814048811071E16
-:1030D0004007EE100E990275660926211F06261478
-:1030E000600006002621200626140868029B470976
-:1030F0008802984629200CD2C0C0800C9E111BE685
-:10310000341FE62BAB99AFEE2DE2852894CF0DADA1
-:103110000B2DE685D10FDD40C0A6C0B08E51CAE0B0
-:10312000B2AAB1BB2DDC108F500E783698100877FC
-:103130000C9FD898D989538F52991199DB9FDA7EC9
-:103140008309B1CC255C10C97763FFCF88108D113E
-:1031500008E70C9751AD8DD7F078DB01B1F79D539F
-:1031600097528830C030088714088840648ED5652F
-:10317000BEC963FEBC0000006C1004D720B03A88C2
-:1031800020C0308221CAA0742B1E2972046D080F42
-:10319000C980C9918575B133A2527A3B0B742B0853
-:1031A00063FFE900649FECD10FD240D10F00000013
-:1031B0006C1008D630C0709515DA408E3914E5FED3
-:1031C0009A1464E0026451FC2920062A9CF865A246
-:1031D0005F2A21020A0B4C65B21F2C320015E5F460
-:1031E00074C7052D212365D3242E529E1AE5F06F56
-:1031F000E80260021B2AA22668A0082B22000ABB54
-:103200000C65B20C2E529D1DE5EB64E2038B386415
-:10321000B22D9E16C8BC8D691EE5E864D0052EE06F
-:10322000217BEB492E200C18E5E20CEF11A8FF29B9
-:10323000F286C186798B4A17E5DF07E70A2772A372
-:10324000687004882077893925F2856452A2272185
-:103250002E07B73607B90C6F9D01D7B089696E92FA
-:103260004228203D7B873C8A15CDAF600018C1B253
-:103270008C202A200C580E90D5A064A2AC8B6863D9
-:10328000FFCBC05063FFC3C0E06000022E60030E9E
-:103290009B0C6EB20EDC700CEA11AA6A2AAC285B99
-:1032A000FFB6D7A0DA20DB70C1C42D211F580E381D
-:1032B0008C268B27D4A00CBB0C7AB3258A63C090D4
-:1032C0009A538862995898528F659F598E679E5B72
-:1032D0008D6697559D5A8B687B7B748B15CEB3603A
-:1032E000000DDA20DB40580E0265A10D63FFCC0013
-:1032F000DA20DB308C14580DAAD6A0C0C0C0D19DF6
-:10330000152CA403DA20DB60DF70DC50C0E0256000
-:10331000039E101EE5C10C5D11AD6D2DDC285BFF19
-:103320003F8E66A5A88F67286403AF7F77FB01B146
-:10333000EE9E669F678D268C29A4DD0DCC0C9D2604
-:103340008B680C0C482C252507BB0C9B6863FEC3BF
-:103350002C20668961B1CC0C0C472C24666EC60209
-:103360006000B809FD5065D0B2CBBF8E69CBEBDBF6
-:1033700060DC50DF70DA201EE5BC2D6003C0809851
-:10338000100CDD11AD6D2DDC285BFF248B15C942BF
-:103390008A2629220904AA082A26060A990C09095C
-:1033A0004829252565B13CC020D10F00DB602D6C7C
-:1033B00028DF70DA20C0C01EE5AC9C10DC505BFE3C
-:1033C000B463FFC7002D203D0D4D4065DDF96FE56D
-:1033D00022DA308F456DE90C8EAA0E8E14C9E37E79
-:1033E000F3112AAC10C090292467090F4764FDD758
-:1033F00060014100C09163FFED00881565814CDAE2
-:1034000020DB608C14580D66C020C09029A403D125
-:103410000FDA20C0B6580DF463FFDE008A162B21A8
-:1034200004580C8CC0A02A24668B6863FF3A000005
-:10343000002B9CF965B0C5DA20580C9163FD910012
-:103440002B200C0CBA11A5AA2FA286C1C27FC302E1
-:103450006000FC0DB90A2992A36890078C2009CC62
-:103460000C65C0EB26A2856460E52C20668931B12D
-:10347000CC0C0C472C24666FC60270960ADAE02B3F
-:103480002104580C74272466893077974B18E55926
-:103490001DE55A8A328B33C0F42C2104099E400664
-:1034A000EE1104CC110ECC029F61C1E00ECC029D46
-:1034B000608F2B9A669B679C64976508FF029F62EA
-:1034C0002F200C18E5430CFE11A5EE2DE285A8FF78
-:1034D00027F4CF2DDC202DE6858F1565F091C020D7
-:1034E000D10F00002A2C748B14580643D2A0D10FA0
-:1034F00000DA20DBE0580DBC63FEFE0000DA20DBC2
-:10350000308C148D15580E3ED2A0D10F00008815B6
-:10351000C888DA20DB30580C9C2A210265AEDAC05C
-:103520009409A90229250263FECFDA202B200C582A
-:103530000DC763FEC4272468DA20DB302C12042D6B
-:1035400012052E0A80580CA163FC7C00C020D10F0C
-:10355000DA20580DA58A15CDA1DA20033B022C12E2
-:1035600004580D0F27A403C020D10F00C020D10F95
-:103570002A2C748B14580620D2A0D10F6C100C2862
-:103580002102941008084C6583621FE50929F29E08
-:103590006F98026003661DE50529D2266890082A07
-:1035A000220009AA0C65A3542CF29D64C34E2B2063
-:1035B0000C0CB611AF66286286C1EC78E30260039A
-:1035C0004619E4FC09B90A2992A36890078A2009E0
-:1035D000AA0C65A33224628564432CC0E12A310918
-:1035E000C07027246689359A11992A8836991298CD
-:1035F0002B89379813992C883899140858149815E2
-:10360000982D89392A25042E251D29251C28302886
-:10361000C09228243C2A30290808479816098901B5
-:103620002A243D2A311599170A094109A90C299C18
-:10363000EC29251F7E87192D2A000DA06000083E69
-:10364000010A3EB1AD08DA390EAA110A990C2925F2
-:103650001F2A211F18E5060A8160C1D0941A951B04
-:1036600001083E00053EB184054839843C259CFC98
-:103670000D883629201408AA1C8D3D2726182E26D1
-:10368000132E26142E261527261B2E246B2724677F
-:1036900027246808581C0909432924142932112AAF
-:1036A000252E28252F27252427252527252C2725A6
-:1036B000232525202425212D2522841A2D211C8512
-:1036C0001B6FD202600209C0A099186D080AB1AA46
-:1036D00000A10400E91A7D9B0263FFEE8918C080F7
-:1036E000C0E1C070C0D29B1D951B961C9C1E16E4A9
-:1036F000D12C203D15E4E00C0B400DCC010BE7383C
-:103700001DE4C30A77100CE8380B8810C0C49C4134
-:103710000877029D40B0A80988118B209C499D48DC
-:10372000954B9643087702861418E4D115E4B9083E
-:10373000770205BB029B4A9B429746881287110875
-:10374000DA149A4E0D88100D77110877021AE4AC3E
-:1037500006D8140D6610087702974FC78F984D98BA
-:103760004C9845871598440715140D55110A5502B4
-:10377000954715E4C18A262D46102D46182D462062
-:103780002C46112C46192C46212B46122B461A2862
-:1037900046142846152B46228816254624254626FB
-:1037A0008B170A0C48090D4885130EDD1105CC1145
-:1037B0000839400BEB390299101EE4B00DCC020D14
-:1037C0005511082D400655022E461316E47B0FDDD9
-:1037D00011254616080840851B0188100DBB02867E
-:1037E000671DE4A70988020CBB0219E4771CE4A555
-:1037F0002B46172D461BA7661BE4A4C0702C461C45
-:103800000988028C1E28461E2B4623C0908B1D293A
-:10381000461D29461F18E49D29462728462529319B
-:10382000162E200629246A243117962D2425238656
-:103830001CCCE1272407C0D7090E4064E0829A29F6
-:1038400009284164809164409B2D2406C098094951
-:1038500036280AA024628501C404A844282104242F
-:1038600066850888118E3F8A3E2D32100EA41800FE
-:10387000C4040EAE1800EE110ACA530EDD02C0E3F6
-:103880000E880298C11EE48209084E9EC08E2094C4
-:10389000C398C59DC418E44E1DE47F05EE110EAA21
-:1038A000020DAA02A8B82784CF9AC21EE44024F2CF
-:1038B0009D27E4A2244C1824F69D655052C020D1C7
-:1038C0000F2D2406C0A0C09809493604A93863FF0B
-:1038D0007FC0A063FE070000654F6DC098C0A82A96
-:1038E000240663FF6B2D2406C09063FF63CC57DA78
-:1038F00020DB308C10580C2AC020D10F00DA20C0F9
-:10390000B6580CB963FFE500DA20580CB763FFDC4A
-:103910002A2C748B10580538D2A0D10F6C100628B1
-:1039200020068A336F8202600161C05013E42029AF
-:10393000210216E41F699204252502D9502C201576
-:103940009A2814E41D8F2627200B0AFE0C04770901
-:103950002B711C64E1398E428D436FBC0260016F94
-:1039600000E104B0C800881A08A80808D8029827FF
-:103970002B200668B32ECE972B221E2C221D011160
-:10398000027BC901C0B064B0172CB00728B000DAC0
-:103990002003880A28824CC0D10B8000DBA065AFD1
-:1039A000E7C020D10F2D206464DFCA8B29C0F10B42
-:1039B000AB0C66BFC02B200C0CBC11A6CC28C28659
-:1039C0002E0A0878EB611EE3FB0EBE0A2EE2A36806
-:1039D000E0052822007E894F29C2851EE4076490F5
-:1039E000461FE4159E90C084989128200A95930F55
-:1039F000880298928E200FEE029E942F2007882630
-:103A00002F950A98969A972E200625240768E34357
-:103A10002921022AC2851DE3EE2AAC20ADBD25D4A2
-:103A2000CF2AC68563FF4E002E2065CBEDC08228CD
-:103A30002465C9F605E4310002002A62821BE3F71F
-:103A40002941020BAA022A668209E4312921026374
-:103A5000FF23000064DFB88F422E201600F1040D12
-:103A6000EE0C00EE1AAEAE9E2963FFA38A202B3225
-:103A700021B1AA9AB0293221283223B499293621BA
-:103A80007989A92B32222B362163FFA0C020D10FC8
-:103A90009F27252415ACB828751C2B2006C0C12EE5
-:103AA000BCFE64E0AB68B7772DBCFD65DEC72D209A
-:103AB00064C0F064D0868E290EAE0C66E089C0F139
-:103AC00028205A288CFE08CF3865FEE863FF58008E
-:103AD00000E0049310C0810AF30C038339C78F08F8
-:103AE000D80308A80108F80C080819A83303C80C63
-:103AF000A8B828751C030B472B24158310CBB700DF
-:103B0000E104B0BC00CC1AACAC0CDC029C27659E76
-:103B10005EC0B20B990209094F29250263FE5000CD
-:103B20002D206A0D2D4165DF7EDA20C0B0580C755E
-:103B300064AF18C0F163FEEF9F2763FFD02E221FF2
-:103B400065EE3263FF79000028221F658E2763FF30
-:103B50006E252406252502C09063FE196C100665AB
-:103B600071332B4C18C0C7293C18C0A1C08009A8CC
-:103B7000380808426481101CE38A1AE38B2AC67E47
-:103B80002A5CFDD30F6DAA0500B08800908C894097
-:103B9000C0A00988471FE3B4080B47094C50090D22
-:103BA0005304DD10B4CC04CC100D5D029D310CBB70
-:103BB000029B3088438E2098350FEE029E328D2670
-:103BC000D850A6DD9D268E40C0900E5E5064E097D2
-:103BD0001CE39A1EE389038B0BC0F49FB19EB02DAA
-:103BE000200A99B30CDD029DB28F200CFF029FB416
-:103BF0008E262D20079EB68C282DB50A9CB7292429
-:103C0000072F20062B206469F339CBB61DE36B2305
-:103C100020168DD20B330C00D10400331AB48DA3BF
-:103C2000C3932922200C13E36A1FE3610C2E11AF0A
-:103C3000EEA3222924CF2FE285D2A00FDD0B2DE6A3
-:103C400085D10F002E200CB48C0CEB111FE3611DED
-:103C5000E358AFEEADBB22B28529E4CF02C20B22FE
-:103C6000B685D2A0D10F00002E200C1CE3511FE31B
-:103C7000580CEB11AFEEACBB22B28529E4CF028227
-:103C80000B22B685D2A0D10FC0D00BAD387DC802B3
-:103C900063FEEC63FEE08E40272C747BEE12DA703C
-:103CA000C0B32C3C18DD50580A7B8940C08063FEAD
-:103CB000E3DE60DA20DB30DC40DD505800059A108E
-:103CC000DB50077A0258044C881063FEF8000000AD
-:103CD0006C100692121EE3428C40AE2D0C8C472EC7
-:103CE0003C1804CA0BD9A07DA30229ADF875C30204
-:103CF000600084C0B0C023C0A09D106D0844B89F70
-:103D00000EB80A8D900EB70BB8770D6D36ADAA9D23
-:103D1000800D660CD8F000808800708C879068B1A8
-:103D200024B22277D3278891C0D0CB879890279C44
-:103D30001000708800F08C9D91CB6FC08108BB0390
-:103D400075CB3663FFB4B1222EEC1863FFD4859295
-:103D50000D770C86939790A6D67D6B01B1559693FF
-:103D60009592600016B3CC2D9C188810D9D078D3CA
-:103D7000C729DDF863FFC100C0238A421BE3470067
-:103D8000CD322D44029B3092318942854379A10581
-:103D90001EE3430E550187121BE334897095350BE2
-:103DA0009902993288420A880C98428676A6A6968D
-:103DB000768F44AFAF9F44D10F0000006C10089382
-:103DC00011D6308830C091086351080847059838EB
-:103DD0009812282102293CFD08084C6581656591EF
-:103DE000628A630A2B5065B18B0A6F142E0AFF7C1E
-:103DF000A60A2C205ACCC42D0A022D245A7FE00298
-:103E0000600215892888261FE32609880C65820F21
-:103E10002E200B0FEE0B2DE0FE2EE0FF08DD110E25
-:103E2000DD021EE320AEDD1EE3201CE3200EDD01DB
-:103E30000DCC37C180084837B88DB4889810896098
-:103E40001AE2DE7B96218B622AA0219C147BA317A9
-:103E50009D132A200C8B108C20580B978C148D13DB
-:103E6000DBA0CEAC6001C4002E200C1BE2D10CEA1A
-:103E7000110BAA082BA2861FE2CF7BDB3B0FEF0AB8
-:103E80002FF2A368F0052822007F892C2BA28564DD
-:103E9000B0AA87628826DE700C7936097A0C6FAD7D
-:103EA0001C8F279B1508FF0C77F3197E7B729D13DF
-:103EB0009C149B15CF56600025C0B063FFD0D790EF
-:103EC00063FFDD00009D139C14DA20DB70580B08A3
-:103ED0008B158C148D1365A06A8E6263FFCC00DA9B
-:103EE000208B11DC40580AAED6A08B15C051DE7075
-:103EF000DA20DC60DD405BFF768D138C14D9A02EB8
-:103F0000200C1BE2AB1FE2B20CEA11AFEFC0E0AB3A
-:103F1000AA2BA2852EF4CF0B990B29A68563FF1D32
-:103F200000DA20DC60DD40DE708912282007DF50D7
-:103F3000A9882824075BFF09D2A0D10F00DBE0DAB3
-:103F400020580B296550EF2A20140A3A4065A0EB4F
-:103F5000DB60DC40DD30022A0258099CD6A064A058
-:103F6000D584A183A0040447030547951203635138
-:103F7000C05163FE5C2C2006D30F28CCFD6480A5C5
-:103F800068C704C0932924062C2006C0B18D641F85
-:103F9000E28A9D279D289D298FF29D2600F104002D
-:103FA000BB1A00F004B0BE0EDD01C0F0ADBB8D65E4
-:103FB0002F24070D0E5E01EE11AEBB2E0AFEB0BB24
-:103FC0000B0B190EBB36C0E20B0B470EBB372B2475
-:103FD0001618E2820A09450D0B422B240B29240AEC
-:103FE000B4BE2E240C7D88572920162FCCFDB09D01
-:103FF0000A5C520DCC362C246465FDEC0C0C476435
-:10400000CDE618E26D8E2888820C9F0C008104009A
-:10401000FF1AAFEE9E2963FDCF1CE29C63FE1300E6
-:104020001CE29363FE0C8D6563FFA500DA202B2054
-:104030000C580B06645F0FC020D10F00C020D10FB9
-:10404000C093292416C09363FFA000006C1004C025
-:104050006017E2561DE259C3812931012A3008292F
-:10406000240A78A108C3B27BA172D260D10FC0C16B
-:104070006550512625022AD0202F200B290AFB2B20
-:1040800020142E201526241509BB010DFF0928F147
-:104090001C2B2414A8EE2EF51C64A0B52B221E2880
-:1040A000221D0111027B8901DB6064B0172CB0076F
-:1040B00028B000DA2007880A28824CC0D10B800083
-:1040C000DBA065AFE7DB30DC40DD50DA205800D8FC
-:1040D000292102090B4CCAB2D2A0D10F00CC5A2C14
-:1040E00030087BC1372ED02064E02D022A02033B2A
-:1040F00002DC40DD505800CED2A0D10F2B2014B0EE
-:10410000BB2B24140B0F4164F0827CB7CAC0C10CD6
-:104110009C022C2502D2A0D10FC020D10F2E200648
-:1041200069E2C12F21020F0F4C69F1B8262406263F
-:1041300025022B221E28221D2A200B2920150DAA1C
-:10414000092CA11C262415AC9929A51C7B814A6049
-:104150000049B0BB2B24140B0D41CBD67CB7022CED
-:1041600025022B221E2E221D7BE9022B0A0064B0A1
-:10417000172CB00728B000DA2007880A28824CC024
-:10418000D10B8000DBA065AFE7C020D10F2624064D
-:10419000D2A0D10F26240663FFC7DB601DE20764AF
-:1041A000BF422CB00728B000DA2007880A28824CCA
-:1041B000C0D10B8000DBA065AFE71DE1FF63FF24EA
-:1041C0006C1004282006C0646F8564CA5B29201423
-:1041D0007D9726DA20DB30DC40055D025800192986
-:1041E0002102090A4CC8A3C020D10F00C0B10B9B0B
-:1041F000022B2502C020D10F0000022A02033B023D
-:104200002C0A015800CAC9AADA20DB30DC40580960
-:10421000E429A011D3A07E97082C0AFD0C9C012C48
-:10422000A411C0512D201406DD022D241463FFA219
-:10423000DA20DB30DC40DD50C0E0580964D2A0D188
-:104240000F0000006C100616E1DA1CE1DA65513B44
-:10425000C0E117E1D62821028B2008084C65807B3D
-:104260002932000969516993722A629E6EA8482A10
-:10427000722668A0027AB93F2A629DB44FCBA72B61
-:10428000200C0CBD1106DD0828D28678FB150CBF6A
-:104290000A2FF2A368F00488207F89072DD285D3E6
-:1042A0000F65D0602A210419E202D30F7A9B1DDA30
-:1042B00020580864600024002C21041BE1FD7CBB15
-:1042C00013DA20C0B658085FC9536000EFDA2058EF
-:1042D0000A46600006DA20C0B6580A436550DDDCA5
-:1042E00040DB308D30DA200D6D515808B8D3A06412
-:1042F000A0CA1CE1B0C05184A18EA00404470E0ED8
-:104300004763FF50002B2104C08C8931C070DF70DF
-:1043100009F950098F386EB8172C2066AECC0C0CFA
-:10432000472C24667CFB099D105808CA8D10272451
-:104330006694D11EE1B6B8DC9ED0655056C0D7B8A1
-:104340003AC0B1C0F00CBF380F0F42CBF119E19465
-:1043500018E19628967EB04BD30F6DBA0500A08861
-:1043600000C08C2C200CC0201DE19A0CCF11A6FFA0
-:104370002EF285ADCC27C4CF0E4E0B2EF685D10F75
-:10438000C0800AB83878D0CD63FFC1008E300E0EE1
-:104390004763FEBD2A2C742B0A01044D025808BD48
-:1043A0002F200C12E18B0CF911A699A2FF27F4CF54
-:1043B000289285D2A008480B289685D10FC020D11D
-:1043C0000F0000006C1004C060CB55DB30DC4005F2
-:1043D0005D02022A025BFF9B29210209084CC88268
-:1043E000D2A0D10F2B2014B0BB2B24140B0C41CB2B
-:1043F000C57DB7EBC0C10C9C022C2502D2A0D10F09
-:104400000000022A02033B02066C02C0D0C7F72E4E
-:10441000201428310126250228240A0FEE012E241B
-:104420001458010D63FFA300262406D2A0D10F006B
-:104430006C1006282102D62008084C65809D2B2090
-:104440000C12E15B0CB811A2882A8286B5497A93D6
-:104450000260009719E15809B90A2992A3689008E7
-:104460002A620009AA0C65A0822882851CE1636487
-:1044700080799C80B887B14B9B819B10655074C03C
-:10448000A7D970280A01C0D0078D380D0D42CBDEA8
-:104490001FE1441EE1452EF67ED830D30F6D4A054C
-:1044A00000808800908C2E3008C0A000EE322E7460
-:1044B0000028600C19E1470C8D11A2DDA988C020ED
-:1044C0002CD2852284CFD2A00CBC0B2CD685D10F48
-:1044D000C0F0038F387FA0C063FFB400CC582A6CB3
-:1044E00074DB30DC405807F1C020D10FDA60580986
-:1044F000BE63FFE7DD402A6C74C0B0DC705808650D
-:104500002E30088B1000EE322E740028600C19E15A
-:10451000300C8D11A2DDA988C0202CD2852284CF39
-:10452000D2A00CBC0B2CD685D10F00006C10042936
-:104530002014282006B199292414688124C0AF2CA6
-:104540000A012B21022C24067BA004C0D02D2502B9
-:10455000022A02033B02044C02C0D05800BFD2A082
-:10456000D10FC020D10F00006C1004293101C2B45A
-:1045700029240A2A3011C28378A16C7BA169645076
-:10458000472C2006C0686FC562CA572D20147CD7FF
-:1045900022DA20DB30DC40DD505BFFA52921020957
-:1045A0000E4CC8E2C020D10FC0F10F9F022F250290
-:1045B000C020D10FDA20DB30C0C05BFFDC28201424
-:1045C00006880228241463FFC72920151BE0FB2A54
-:1045D000200BC0C09C240BAA092BA11C2C2415ABBA
-:1045E0009929A51C63FF9900C020D10FDA20DB3088
-:1045F000DC40DD50C0E0580875D2A0D10F000000AB
-:104600006C1004CB5513E0F625221F0D46110655FC
-:104610000CA32326221E25261F06440B24261E73C8
-:104620004B1DC852D240D10F280A80C04024261FFB
-:10463000A82828261E28261DD240D10FC020D10F21
-:10464000244DF824261E63FFD80000006C100428B7
-:104650002006D6206E85026000DE17E0D51DE0DC66
-:1046600019E0D5C0C1C0202A8CFC64A1322B6102A4
-:10467000B44E0B0B4C65B0A82B600C2A62000CB832
-:10468000110788082F828609B90A7FE30260009F1C
-:104690002992A368900509AA0C65A09328828564D5
-:1046A000808DB8891BE0DA94819B8065514DC0B73D
-:1046B000B838C0A1C0E009AE380E0E4264E0481A16
-:1046C000E0B81FE0B92FA67EB04A6DAA0500808829
-:1046D00000908CC0A02E600C0CE811A7882F82855A
-:1046E000ADEE0F4F0B2F86852B600622E4CF68B10D
-:1046F0002A296015C0B2C99AD2A02D61022B640686
-:104700000CDD022D6502D10FC0E008AE387EB0B7D7
-:1047100063FFAB00226406D2A0D10F00D2A0D10F5C
-:1047200000CC57DA60DB30DC4058089DC020D10F48
-:10473000DA6058092D63FFE80028221E29221D781F
-:104740009902280A00C176C1C1C1D21BE0A5C124CB
-:10475000AB6B6480437891402A80000CAF0C64F00E
-:10476000AE0DAE0C64E0A802AF0C64F0A207AE0C74
-:1047700064E09C2FACE864F0962EACE764E0902FE8
-:10478000ACE664F08A2A800708A80B088A027B83BB
-:10479000022A8DF8D8A065AFBBC0906000730000FE
-:1047A0002B600C0CB811A7882E82866EE87909BAA6
-:1047B0000A2AA2A368A0048E607AE96B2A82856423
-:1047C000A0651FE08DC0E32E64069EA19FA01FE0A0
-:1047D000B92E600A92A30FEE029EA28E600FEE0227
-:1047E0009EA42F60147AFF4722A417ADBE2F8285A6
-:1047F00022E4CF2FFC182F868563FE702A6C74C0CC
-:10480000B1DC90DD405807A31DE072C0C163FEC457
-:10481000D9A0DA60DB30DC40DD50C2F0C1E009FE37
-:10482000395807EAD2A0D10FDA605808EF63FEF0DA
-:104830002CA4170DBE0829828522E4CF299C1829B3
-:10484000868564500C2A6C74044B0258016BD2A00C
-:10485000D10FC020D10F00006C10062B221E282281
-:104860001D93107B8901C0B0C0C9C03BC1F20406D2
-:10487000401DE05BC0E2C0740747010E4E01AD2D44
-:104880009E11C0402E0A1464B06E6D084428221D8B
-:104890007B81652AB0007EA13B7FA1477B51207CB4
-:1048A000A14968A91768AA1473A111C09F79A10C26
-:1048B000C18B78A107C1AE290A1E29B4007CA12BA7
-:1048C0002AB0070BAB0BDAB07DB3022ABDF8DBA030
-:1048D000CAA563FFB428B01089116987BB649FB86B
-:1048E00063FFDC00647FB463FFD50000646FD0C059
-:1048F00041C1AE2AB40063FFC62B2102CEBE2A22DC
-:104900001D2B221E7AB12A8C107CB1217AB901C0EC
-:10491000B0C9B913E026DA2028B0002CB00703880C
-:104920000A28824CC0D10B8000DBA065AFE7D240E3
-:10493000D10F8910659FD463FFF300006C1008C08D
-:10494000D0C8598C302921020C0C4760000C8E30E5
-:104950000E1E5065E19E292102C0C116E015090B0B
-:104960004C65B0908A300A6E5168E3026000852F72
-:10497000629E1BE00E6EF8532BB22668B0052E2205
-:10498000007BE94727629DB748CB7F97102B200C0F
-:10499000B04E0CBF11A6FF29F2869E12798B4117EB
-:1049A000E00507B70A2772A368700488207789306A
-:1049B00029F285DF90D7906590652A210419E03CA3
-:1049C0007A9B22DA2058069F600029002C21041BC4
-:1049D000E0387CBB18DA20C0B658069AC958600186
-:1049E0004CC09063FFCCDA2058087F600006DA20C4
-:1049F000C0B658087D655135DC40DB308D30DA209B
-:104A00000D6D515806F2C0D0D3A064A12029210217
-:104A1000C05184A18CA00404470C0C4763FF3E00E6
-:104A2000C09C8831DBD008F850089B3828210498B6
-:104A3000116E8823282066AC8C0C0C472C24667CD5
-:104A4000BB159F139E148A108B115807028E148F6A
-:104A500013C0D02D24668A30C092C1C81BDFEC7F02
-:104A6000A6099BF099F12CF40827FC106550A4B816
-:104A70003ADF70C051C08007583808084264806728
-:104A800018DFC819DFC929867E6A420AD30F6DE98B
-:104A90000500A08800F08CC0A08930B4E37F962880
-:104AA000C0F207E90B2C94089B909F912F200C12C9
-:104AB000DFC80CF811A688298285A2FF2DF4CFD279
-:104AC000A009330B238685D10F22200C891218DF11
-:104AD000C00C2B11A6BBA8222D24CF2CB285D2A0AE
-:104AE0000C990B29B685D10FC087C0900A59387927
-:104AF000809663FF8ADB30DA20C0C1C0D05BFF56EE
-:104B0000292102C0D02A9CFE65AE4D2D2502C09001
-:104B100063FE45009E142A2C74C0B1DC70DD405841
-:104B200006DD8E14C0D01BDFB9C1C863FF6AC02088
-:104B3000D10F00006C100628210216DF9D08084CDA
-:104B400065821929629E6F980260022019DF9829F8
-:104B500092266890078A2009AA0C65A20F27629DF9
-:104B6000C0CC6472072B21048E31C0A0DDA00EFEE4
-:104B7000500ECD386EB8102C2066B1CC0C0C472CE2
-:104B800024667CDB026001EFC0C12930081BDF8A8C
-:104B900064909C2F0AFFC0D3B09E64E10268921318
-:104BA0006450882A2C74044B025800930AA202060F
-:104BB000000000002B200C2721040CBC11A6CC29DE
-:104BC000C286280A087983026001B919DF7A09B917
-:104BD0000A2992A36890082E220009EE0C65E1A430
-:104BE0002EC28564E19E26200713DF836E7B026060
-:104BF000019A17DF7A1FDF8319DFB0C0D228200A9D
-:104C000093E09DE1A9690F880298E22F90802A9491
-:104C100080B1FF07FF029FE32EC2851FDF6D0EDE0E
-:104C20000BAFBF2AF4CF2EC685655F76C020D10FAB
-:104C30002830102930112E301300993200ED3264E3
-:104C400080EE2A30141FDF9D00AA3278EF050F9EF8
-:104C5000092DE47F1EDF9B66A0050F98092A84803A
-:104C6000B4A718DF98C76F009104AE9EDDE000AFD7
-:104C70001A00C31A6EE1052DB2000DED0C1EDF9275
-:104C800008D81C063303AE882A848B2EB02E2784C6
-:104C90008C03EE010FEE022EB42E58018F63FEFF3F
-:104CA0002931082925042830142E3109B088648060
-:104CB000A32E240AC0812E30162CB4232E240BB42C
-:104CC000EF2F240C8C378B36292504DEB0DFC00C87
-:104CD0008F390B8E390FEE0264EEC4089F1101C4A8
-:104CE000048D380CB81800C4040CBE1800EE110E68
-:104CF000DD02C0E30EFF021EDF669F719E701EDFA5
-:104D0000658F2098739D7405FF110BCD53C180985A
-:104D1000750FDD020EDD029D721EDF242A24662F30
-:104D2000629D2AE4A22FFC182F669D63FE7100008D
-:104D3000002F30121BDF6600FA3278FF050B980B4C
-:104D40002A847F66D0050B9A0B2DA4802A3011008F
-:104D5000AA3263FF442F240A9E2B63FF56CC57DAF6
-:104D600020DB30DC4058070EC020D10F00DA20C015
-:104D7000B658079D63FFE500DA70580636C0A02AD2
-:104D8000246663FE02DA2058079863FFCFB16928D2
-:104D9000200A8620090947991129240798107F8144
-:104DA0002693E027E50A9AE388109DE119DF428DFA
-:104DB00011096F029FE42DE416098802C0D398E21E
-:104DC0002A240763FE5100001DDF0B0868118F11B4
-:104DD000892B93E008FF02C08F9FE50D990299E2AD
-:104DE000047F11C0D49DE108FF029FE463FFD0005F
-:104DF0006C1004C020D10F006C100485210D3811F7
-:104E000014DEE98622A42408660C962205330B934F
-:104E100021743B13C862D230D10FC030BC29992114
-:104E200099209322D230D10F233DF8932163FFE3E1
-:104E30006C100AD620941817DEDED930B8389819CD
-:104E40009914655252C0E1D2E02E61021DDEDB0EE4
-:104E50000E4C65E1628F308E190F6F512FFCFD658E
-:104E6000F1558EE129D0230E8F5077E66B8F181EF7
-:104E7000DF18B0FF0FF4110F1F146590CE18DF1567
-:104E80008C60A8CCC0B119DEC928600B09CC0B0D11
-:104E9000880929811C28811A2A0A0009880C08BA65
-:104EA000381BDF0B0CA90A2992947B9B0260008CB3
-:104EB0002B600C94160CBD11A7DD29D286B8487959
-:104EC00083026000D219DEBB09B80A2882A39817B2
-:104ED0006880026000A36000A51ADEFF84180AEE55
-:104EE00001CA981BDEB28C192BB0008CC06EB313B4
-:104EF0001DDEAF0C1C520DCC0B2DC295C0A17EDB6C
-:104F0000AE6000380C0C5360000900000018DEF1A0
-:104F10008C60A8CCC0B119DEA528600B09CC0B0DA4
-:104F2000880929811C28811A2A0A0009880C08BAD4
-:104F3000380CA90A2992947E930263FF72DA60C04A
-:104F4000BA58072964507360026600001ADE988C14
-:104F5000192AA0008CC06EA31A18DE940C1C5208EB
-:104F6000CC0B18DEDB2BC295C0A178B30263FF3FE8
-:104F700063FFC9000C0C5363FF09896078991829F5
-:104F8000D285C9922B729E1DDE896EB8232DD22642
-:104F9000991369D00B60000DDA6058071360001791
-:104FA0000088607D890A9A1A29729D9C129915CFF2
-:104FB00095DA60C0B658070C6551F58D148C18DB76
-:104FC000D08DD0066A020D6D51580580D3A09A1479
-:104FD00064A1DD82A085A1B8AF9F19050547020233
-:104FE000479518C05163FE602B6104C08C8931C0A5
-:104FF000A009F950098A386EB81F2C6066A2CC0C43
-:105000000C472C64667CAB119F119E1B8A155805BA
-:10501000918E1B8F11C0A02A64669F1164F0E12954
-:1050200012032812096DF9172F810300908DAEFE2F
-:105030000080889F9200908C008088B89900908CA6
-:1050400065514E8A10851A8B301FDE6B88122960DD
-:105050000708580A2C82942D61040ECC0C2C8694DF
-:105060006FDB3C1CDE95AC9C29C0800B5D50A29987
-:1050700009094729C48065D0DA2E600CC0D01FDE34
-:10508000540CE811AFEEA7882282852DE4CF0242AE
-:105090000B228685D2A0D10F8E300E0E4763FDA65F
-:1050A000A29C0C0C472C64077AB6CD8B602E600A4C
-:1050B000280AFF08E80C64810E18DE7E831682132E
-:1050C000B33902330B2C34162D350AC02392319F8D
-:1050D00030C020923308B20208E80292349832C0FD
-:1050E000802864072B600CD2A01CDE390CBE11A7EF
-:1050F000EE2DE285ACBB28B4CF0D9D0B2DE685D1FE
-:105100000F8B1888138D30B88C0D8F470D4950B414
-:10511000990499100D0D5F04DD1009FF029F800DA9
-:10512000BB029B8165508D851AB83AC0F1C0800CD6
-:10513000F83808084264806B1BDE1A19DE1B29B69A
-:105140007E8D18B0DD6DDA0500A08800C08CC0A08F
-:1051500063FEF30082138B161DDE2B28600AC0E06D
-:105160002EC4800D880202B20B99239F20C0D298D2
-:10517000229D2122600CB2BB0C2D11A7DD28D28507
-:1051800008BB0B18DE132BD685A8222E24CFD2A065
-:10519000D10F9E1B851A2A6C748B185BFF178E1B10
-:1051A00063FEA300C087C0900AF93879809263FF3C
-:1051B00086C020D10F9E1B2A6C74C0B18D18580573
-:1051C000358E1B851A63FE7E886B8213891608BE96
-:1051D000110ECE0202920B9E25B4991EDE069F2070
-:1051E0000E88029822C0EF04D8110E88029824C0BD
-:1051F000E49E21C080D2A02B600C2864071CDDF443
-:105200000CBE11A7EE2DE285ACBB28B4CF0D9D0BD3
-:105210002DE685D10F0000006C1004C020D10F00D6
-:105220006C10048633C071C030600001B1330031AE
-:105230000400741A0462017460F1D10F6C1004024E
-:105240002A02033B025BFFF61CDDDC1BDE24C79F4A
-:1052500088B009A903098A019AB079801EC0F00FAD
-:10526000E4311DDDD30002002BD2821EDE1D2AC1D7
-:10527000020EBB022BD6820AE431D10F28C102C133
-:105280009009880208084F28C50208E431D10F00B0
-:105290006C1004C0C00CE43112DDC81ADDC5000278
-:1052A0000029A28218DE111BDE0F2621020B9901B4
-:1052B00008660129A68226250206E43114DE0C15B3
-:1052C000DE07236A902326128550242611252613F3
-:1052D000222C40D10F0000006C1008D6102B0A645D
-:1052E000291AB41ADDB20D23111CDDB30F2511B834
-:1052F0001898130E551118DDFEAC55A838AA332C9A
-:1053000080FF2A80FEA933288D0129800108AA1177
-:105310002880000CAA0208881109880208AA1C2803
-:105320008C0828160458084C14DDA40AA70224414E
-:10533000162A30802B120407AA28580847B1338B4D
-:1053400013B4559A6004AC28B4662C56277B69E0E8
-:1053500016DDDB9412C050C0D017DD979D15D370B9
-:10536000D4102F60802E60829F169E178816728937
-:105370001A8D128C402A607F0DCC282B3A200CAA63
-:1053800028580835C0B10ABE372E35408F1772F93C
-:105390001A8D128C402A60810DCC282B3A200CAA41
-:1053A0002858082DC0B10ABE372E3542B233B44456
-:1053B000B1556952B6B466C0508F15B877D370B284
-:1053C000FF9F156EF899D10F6C1004C021D10F000A
-:1053D0006C1004270A001CDD761FDD871EDD8A1D88
-:1053E000DD731ADDB51BDDC3C02824B0006D2A753E
-:1053F000AA48288080C09164806100410415DD6E58
-:10540000C03125502E00361A0655010595390C5627
-:10541000110C66082962966E974D0D590A2992243F
-:1054200068900812DDA702420872993B2362951228
-:10543000DD6BCB349F300282020E4402C092993160
-:1054400094329233AD52246295C090244C1024665D
-:105450009524B0002924A0AA42292480B177B14420
-:1054600004044224B400D10FD10FD10F6C10041AE0
-:10547000DD4F2AA00058021C5BFFD5022A02033B25
-:10548000025BFFD11BDD4DC9A12CB102C0D40DCCF4
-:10549000020C0C4F2CB5020CE431D10FC0A00AE471
-:1054A0003118DD430002002F828219DD562EB10231
-:1054B00009FF022F86820EE431D10F006C1004C068
-:1054C0002002E43114DD3D16DD3A00020022628242
-:1054D000234102732F0603E431C020D10F19DD8769
-:1054E0001ADD862841020A2A010988012A668228D3
-:1054F000450208E43115DD7D12DD8225461DD10F00
-:105500006C1004292006289CF96480A02A9CFD6563
-:10551000A0968A288D262F0A087AD9042B221FC824
-:10552000BD2C206464C0812E22090EAE0C66E0788A
-:105530002B200C1EDD1F0CBC11AECC28C28619DD41
-:105540001D78F3026000AD09B90A2992A36890089A
-:105550002E220009EE0C65E09B29C2851FDD276421
-:1055600090929F90C0E41FDD349E9128200AC0E0F5
-:105570009E930F8802989288200F880298942F207B
-:10558000079A979D962F950A2E24072820062920F2
-:105590006468833328C28512DD0E288C20A2B22EC7
-:1055A00024CF28C685C020D10FC020D10F2A206A61
-:1055B0000111020A2A4165AF52DA20C0B05805D164
-:1055C00064AFE5C021D10F00649FC81FDCFB2D2014
-:1055D000168FF209DD0C00F10400DD1AADAD9D2936
-:1055E00012DCFC28C285A2B22E24CF288C2028C62B
-:1055F00085C020D10FC021D10F0000006C100426FF
-:105600000A001BDD4015DCEC28206517DCE9288C3E
-:10561000FE6480940C4D110DBD082CD2F52BD2F4F4
-:105620002ED2F77CB13DB4BB2BD6F47BE9052BD24F
-:10563000F62BD6F47CB92C2AD2F62AD6F52AD6F443
-:1056400006E4310002002872822AFAFF0041042990
-:105650000A012F510200991A0A9903098801287634
-:10566000820FE4312624652BD2F48E5A2CD2F5B069
-:10567000EE9E5A7BCB1629D2F62FD2F70CB80C0926
-:10568000FF0C08FF0C0F2F14C8F96000320BCA0C76
-:105690000A2A14CEA92B5102C0C20CBB020B0B4F1D
-:1056A0002B55020BE431D10F00DB30DA205BFF9485
-:1056B0001BDD1564AF5D0C4D11ADBD63FFA800008F
-:1056C00006E4310002002F728218DCD42E51020849
-:1056D000FF022F76820EE431D10F00006C1004C05F
-:1056E0003003E43116DCB315DCB40002002462821E
-:1056F00074472118DD05875A084801286682CD7352
-:1057000019DD030C2A11AA9922928329928472919D
-:10571000038220CC292B51020BE431C020D10F0091
-:105720001FDCFC2E51020FEE012E55020EE431B0AB
-:105730002DB17C9C5A12DCF708DD112D5619D10FC2
-:105740006C10061BDC9A1EDC9C22B0001ADCF36F86
-:1057500023721DDCDAC04818DCF21FDCF0DC10D547
-:10576000C083F000808600508A6D4A4F0F35110DBE
-:1057700034092440800B560A296294B1330E55092E
-:105780002251400F44110C440A874009A80C02889A
-:105790003622514107883608770CA89929669497D4
-:1057A00040296295874109A80C0288360788360887
-:1057B000770CA8992966959741030342B1380808E8
-:1057C0004298F0D10F1CDCD713DCD827B00023326D
-:1057D000B5647057C091C0D016DCD615DCD4C0407B
-:1057E0002AC00003884328C4006D793C004104B1FD
-:1057F0004400971A7780148E502FB2952DB695AF2E
-:10580000EE2EED2006EE369E5060001877A009833C
-:10581000509D5023B69560000223B295223D20068C
-:10582000223622B695B455B8BBD10F000388432861
-:10583000C400D10F6C1004C04004E43115DCBE007C
-:105840000200885013DCBDCB815BFFBD1CDCBC0CAF
-:105850002D11ADCC2BC2822AC28394507BAB142E67
-:10586000C28429C2850ABD0C0E990C0D990C092918
-:10587000146000050BA90C092914993015DC4F2A76
-:1058800051020AE4312A2CFC58004B2B32000AA2A8
-:10589000022BBCFF9B30CCB6C8A4D2A0D10F000015
-:1058A00004E4311EDC430002002DE2822FBAFF2CFB
-:1058B00051020FDD012DE6820CE431D10F00000012
-:1058C0006C1004D10F0000006C1004C020D10F0038
-:1058D0006C100413DC9BC0D103230923318DC0A0BD
-:1058E0006F340260008D19DC321BDC3317DC940C42
-:1058F0002811A8772672832572822CFAFF765147E9
-:1059000088502E7285255C0425768275E9052572FE
-:10591000842576827659292E72842E76822E76837D
-:105920000AE4310002002392820021042FB1020018
-:10593000D61A0C66030633012396820FE4312672D1
-:105940008325728260000200D8A07659220AE431D1
-:1059500000020023928200210400D21A2FB1020C0F
-:1059600022030232012296820FE431D280D10F004D
-:10597000D280D10FC020D10F6C1004DB30862015EF
-:10598000DC0B280A00282502DA2028B0002CB007FA
-:1059900005880A28824C2D0A010B8000DBA065AF28
-:1059A000E61ADC040A4A0A29A2A3C7BF769101D1EC
-:1059B0000F2BA6A3D10F00006C1004C0D1C7CF1BC2
-:1059C000DBFE19DBFB17DBF90C2811A87786758540
-:1059D00074C0A076516288508E77B455957475E97D
-:1059E00003857695747659278F769F759F740AE4A0
-:1059F00031000200239282B42E2FB10200E1040094
-:105A0000D61A0C66030633012396820FE43186759D
-:105A100083747639280AE4310002002E9282B4227F
-:105A200000210424B10200DF1A0CFF030FEE012E47
-:105A3000968204E431D280D10FD8A07651D6D2809C
-:105A4000D10F00006C1004290A801EDC001FDC004E
-:105A50001CDBD80C2B11ACBB2C2CFC2DB2850FCC35
-:105A6000029ED19CD0C051C07013DBFC14DBFB182C
-:105A7000DBF92AB285A82804240A234691A986B80E
-:105A8000AA2AB685A98827849F25649FD10F000084
-:105A90006C100419DC2C0C2A11A9A98990C48479F2
-:105AA0008B761BDC1AABAC2AC2832CC2847AC16809
-:105AB0008AA02BBC30D3A064A05E0B2B0A2CB2A30F
-:105AC00019DBE568C0071DDC20D30F7DC94AA92971
-:105AD000299D0129901F68913270A603D3A0CA9E08
-:105AE000689210C7AF2AB6A32A2CFC5BFFB3D23052
-:105AF000D10F000013DBC503A3018C311DDBB60CF5
-:105B00008C140DCC012CB6A363FFDC00C020D10F98
-:105B1000DA205BFFCCC020D10FC020D10F000000E5
-:105B20006C1004DB30C0D019DBA1DA202830002251
-:105B3000300708481209880A28824CDC200B8000B4
-:105B40001BDB9C0C4A11ABAA29A28409290B29A6AC
-:105B500084D10F006C1004C04118DB9517DB970C43
-:105B60002611A727277030A866256286007104A336
-:105B70005500441A75414822628415DBB802320B85
-:105B8000C922882117DB940884140744017549054C
-:105B9000C834C020D10FD10F0809471DDBEBC0B2BC
-:105BA0008E201FDB820E0E43AFEC2BC4A00FEE0A3B
-:105BB0002DE6242A6284C0200A990B296684D10F1D
-:105BC000C020D10F6C1004DB30C0D018DB78DA2095
-:105BD00025300022300708580A28824CDC200B8030
-:105BE000008931709E121BDB720C4A11ABAA29A2EC
-:105BF0008409290B29A684D10F09C95268532600AC
-:105C0000910418DB6DC0A12F811200AA1A0AFF02AD
-:105C10002F85121EDB670C4D11AEDD2CD2840C2CAF
-:105C20000B2CD684D10FC0811FDB64B89A0A0A47B7
-:105C30002EF11200A10400881A08EE022EF5121DA2
-:105C4000DB5C0C4C11ADCC2BC2840B2B0B2BC68414
-:105C5000D10F00006C1004DB30C0D019DB54DA2007
-:105C600028300022300709880A28824CDC200B806B
-:105C7000001CDB4F0C4B11ACBB2AB2840A2A0B2A46
-:105C8000B684D10F6C1004C04118DB4916DB4B0CF5
-:105C90002711A626266030A872252286006104A35B
-:105CA0005500441A75410822228402320BD10F009C
-:105CB000C020D10F6C100415DBA502491429561120
-:105CC0002452120208430F8811C073008104003669
-:105CD0001A008104C78F00771A087703074401066A
-:105CE0004402245612D10F006C10066E230260008D
-:105CF000AC6420A7C0A0851013DB7E16DB94C040E7
-:105D0000A6AA2BA2AE0B194164906668915D6892B9
-:105D10005268933C2AA2AA283C7F288C7F0A0A4D0D
-:105D20002980012880002AACF208881109880275B0
-:105D300089462B3D0129B0002BB0010899110B9920
-:105D4000027A9934B8332A2A00B1447249B160000A
-:105D50004A7FBF0715DB7F63FFB90000253AE86380
-:105D6000FFB10000253AE863FFA90000250A64633B
-:105D7000FFA1C05A63FF9C0000705F082534FF0537
-:105D80008C142C34FE70AF0B0A8D142E3D012AE4C6
-:105D9000012DE400DA405BFD5063FFA7D10FD10F66
-:105DA0006C10041ADB0519DB021CDB6A1BDB6BC001
-:105DB00080C07160000D00000022A430B1AA299CAF
-:105DC000107B915F26928679C2156E6262C0206D4B
-:105DD000080AB12200210400741A764BDB63FFEE3F
-:105DE0002292850D6311032514645FCFD650032DD5
-:105DF000436DD9039820B4220644146D492298209B
-:105E000098219822982398249825982698279828AE
-:105E10009829982A982B982C982D982E982F222CD8
-:105E20004063FF971EDAE327E68027E681D10F0063
-:105E3000C02063FF830000006C1004C062C04112E8
-:105E4000DADE1ADADA13DB452AA00023322D19DB59
-:105E50003F2BACFE2992AE6EA30260008E090E406D
-:105E60002D1AC2C2CD0EDC392C251664B0895BFF19
-:105E70009E15DB3B1ADAE52B3AE80A3A015805761B
-:105E80002B21160ABB28D3A02B560058058D8B500A
-:105E90000ABB082A0A0058058C15DB322D21022C7A
-:105EA0003AE80C3C2804DD022D25029C505805845C
-:105EB0008B50AABBC0A15805841CDB2B2D21020CE2
-:105EC0003C2806DD0213DB292D25029C3058057C79
-:105ED0008B30AABBC0A258057C2A2102C0B40BAAF1
-:105EE000020A0A4F2A2502580590D10F242423C301
-:105EF000CC2C251663FF760018DB211CDB1D19DB7B
-:105F00001E1BDB1C17DAF085202E0AFD1FDB1D2D62
-:105F1000202E24F47A24F47E24F4820EDD0124F46D
-:105F2000862E0AF707552806DD02C0750EDD01052D
-:105F30000506AB5BA959C0E8AC5C24C4AB0EDD021E
-:105F400027C4AC2E0ADFA85527B4EC0EDD0124B41B
-:105F5000EBC2E027942C0EDD0224942B2E0A800D38
-:105F60000D4627546C24546B0EDD022D242E63FE47
-:105F7000FC0000006C10042A0A302B0A035BFF4D62
-:105F800012DAF3C390292616C3A1C0B3C08A28260B
-:105F9000175BFF48C03CC3B12B26161ADA872AA02C
-:105FA0002023261764A079C3A2C0B15BFF42C3A21D
-:105FB000C0B15BFF40C3C22C2616C2AFC0B12326BE
-:105FC000175BFF3CC28F282616C0FE2F2617C2E2A1
-:105FD0002E26162A0AA1C0B1C0D82D26175BFF3580
-:105FE0002A0AA12A2616C3A6C0B3C1922926175B86
-:105FF000FF31C3C62C2616C1B32A0AA22B2617C00E
-:10600000B35BFF2C290AA2292616C185282617C2B0
-:10601000FB2F2616C0E72E26171DDADA2D2610D103
-:106020000FC3A2C0B35BFF2363FF82006C10041C8C
-:10603000DAA41BDA9118DAD417DAD516DAD515DA1C
-:10604000D5C0E0C0D414DAA01FDA5CC0288FF06D90
-:106050002A36DAC0D9C07C5B020FC90C1CDA9A0C54
-:106060009C28A8C3A6C22A36802A2584A4C2A7CC0D
-:106070002D248C2B248A2B24872E248BB1BB2E36E7
-:106080009F2C369E2C369DB1AC1CDA7B1BDAC3C02C
-:10609000286D2A33DAC0D9C07C5B020FC90C1CDA28
-:1060A000890C9C28A8C3A6C22A36802B2584A4C2AA
-:1060B000B1BBA7CC2D248C2E248B2A248A2E369F6C
-:1060C0002C369E2C369DB1ACC07919DA791BDAB525
-:1060D00013DAB31ADAB318DAB414DA7A16DAB404C3
-:1060E000F42812DAB304660C040506A252A858AAD2
-:1060F0005AA3539B3029A50027848AC091C0A52AA2
-:10610000848C29848B17DAAC18DAABA75726361D96
-:1061100026361E2E361F16DAA913DAA9A655043321
-:106120000C2826C82E75002D54AC2E54AB2E54AA24
-:106130002326E62326E52E26E7D10F006C10061352
-:10614000DA8717DA8224723D2232937F2F0B6D0893
-:10615000052832937F8F0263FFF3C0C4C0B01ADA00
-:1061600016C051D94004593929A4206E44020BB5F8
-:1061700002C3281EDA11DDB025E422052D392DE4F5
-:1061800021C0501EDA9019DA8018DA8016DA821DE2
-:10619000DA8E94102A724517DA4C6DA94BD450B39D
-:1061A000557A5B17DF50756B071FDA038FF00F5FAF
-:1061B0000C12DA4402F228AE2222D681D54013DA3C
-:1061C00041746B0715D9FD855005450C035328B163
-:1061D00045A73FA832A93322369D22369E24368019
-:1061E0002B369F2BF48B2CF48C14DA5C24424DC09C
-:1061F00030041414C84C6D0806B133041414C8429A
-:1062000063FFF20015D9EAC4400031041AD9EBC08B
-:10621000D193A200DD1AC138B0DD9DA318DA502B4E
-:10622000824D29824E29A51C2882537A871E2C5420
-:10623000008E106FE45D12D9E02F211D23211C2F49
-:10624000251B04330C23251C23251AD10FC06218EB
-:10625000DA3F88807E87D989102654006F94191BF5
-:10626000D9D62AB11C0A1A1404AA0C2AB51C2AB5BC
-:106270001D2AB51A2AB51BD10F1BD9CF2AB11C0A6A
-:106280001A1403AA0C2AB51C2AB51D2AB51A2AB558
-:106290001BD10F001CD9C92BC11D2DC11C2BC51B27
-:1062A00003DD0C2DC51C2DC51AD10F006C1006196D
-:1062B000D9C214DA2612DA2915DA44C73FC0E02E13
-:1062C00056A82E56A92E56AA2E56AB23262918D9E3
-:1062D000EADB101CDA3EC0D42A42452D16019C1080
-:1062E00000B0890A880C2896005BFF942B22E318E3
-:1062F000D9B20B5B149B842A22E48B84B1AA0A5A7C
-:10630000140BAA0C9A852922E509591499862F2283
-:10631000CD0F5F149F875BFF455BFF1623463BC194
-:10632000B01DD9A51CDA032AD1022C463A0BAA02C9
-:106330000A0A4F2AD50258047C5BFEBF5BFE98C058
-:1063400050C0B016D99B14D9A317DA12C0C0C73EEB
-:1063500093122C262DC0306000430000007F9F0F59
-:10636000B155091914659FF4C0500AA9027FA7EF1F
-:1063700018D98FDA5008580A28822C2B0A000B8073
-:1063800000005104D2A0C091C7AF00991A0A990326
-:106390009912CE33642067D3202B200795138C12DB
-:1063A0002A62827CA85F18D98108580A28822CDAD0
-:1063B000500B8000D2A0643FDA8A310A8A1404AA02
-:1063C00001C8298B210B8B1404BB017BA945DDA0DF
-:1063D0007A7B081DD9792DD2000DAD0CDB3019D98F
-:1063E000731AD9B82812030ADA28088C021DD9F5C5
-:1063F00009880A28823C0DAA080B8000652F97D3D4
-:1064000020C0B063FF97CB53B1550050040A09195F
-:1064100063FF4900DAB07B7B071AD9678AA00ABA02
-:106420000C1BD9A88C310BAB280C8A141CD9E6ACF8
-:10643000BB1CD9E504AA012BC68163FF907FA7C7C7
-:1064400063FF62006C100427221EC08008E4311B29
-:10645000D9580002002AB28219D958003104C0610B
-:1064600000661A2991020A6A022AB68209E43115E5
-:10647000D9B30C3811A8532832822432842A8CFCD8
-:106480007841102921022A368297A009690229251C
-:1064900002D10F002B21022C32850B6B022CCCFC7D
-:1064A0002C368297C02B2502D10F00006C1004C03F
-:1064B000E71DD93B1CD93D0D4911D7208B228A20DD
-:1064C0000B4B0BD2A007A80C9B72288CF4C8346F1E
-:1064D0008E026000A21FD933A298AF7B78B334C973
-:1064E0003DC081C0F0028F380F0F42C9FA2CD67E12
-:1064F000D5206D4A0500308800508C8870089808B7
-:1065000078B16CD2A09870D10FC0F0038F387FE0C3
-:10651000DE63FFD8027B0CAFBB0B990C643046D80E
-:1065200030C0F1C05002F5380505426450792CD6D0
-:106530007E0B36122F6C100F4F366DFA05008088D7
-:1065400000208C06440CC081250A0003B208237C7D
-:106550000C0385380505426450592CD67E6D4A05DA
-:1065600000208800308CD2A0A798BC889870D10FEA
-:10657000D2A0BC799970D10FD2302BAD08C0F1C038
-:10658000500BF538050542CB552CD67E083F14C17B
-:10659000600F660C064636D30F6D6A050020880032
-:1065A000B08C827063FF2D00C05003F53875E08019
-:1065B00063FF7A00C06002863876E0A063FF9A002D
-:1065C000C05003F53875E0C363FFBD006C1004D6FE
-:1065D0002068520F695324DA20DB30DC405800F089
-:1065E000D2A0D10FDA20DB30DC405800ED9A242411
-:1065F000240EC02122640FC020D10F00B83BB04C44
-:106600002A2C7489242D200E2E200FA4DDB1EE2E0D
-:10661000240FB0DD2D240E2890072D9003A488B000
-:1066200088B1DD2D94032894075BFFA069511DC03C
-:10663000E082242A600F18D9662A240329600E8F6D
-:106640002029240708FF029F209E64D10FC020D17B
-:106650000F0000006C1004942319D95EC0B3083AEF
-:10666000110BAA02992019D8D29A2116D8D0C0505D
-:1066700028929D2564A2288C1828969DD10F000091
-:106680006C1004282066C038232406B788282466A6
-:10669000D10F00006C1006035A0C0D36110D5C1161
-:1066A000D8208B2282210CBB0C06550F9B82023214
-:1066B0000B928113D8BCD920A38F6450531CD8B837
-:1066C000C0D71BD8B9A256C0E1290A0004E938098D
-:1066D000094276F34A044302C99E2BC67E6DAA0581
-:1066E00000208800308C8981A95909FA0C64A079AE
-:1066F00099818A82C8ADD290D10FC06002E6387607
-:10670000D0DA63FFD4C020BC89998199809282D16C
-:106710000F7F2304292DF8998165BFD963FFE50018
-:10672000028F0CA3FF0F3312931003AA0CD340CB9C
-:106730009E2BC67E86106D6A0500208800308CBCBA
-:1067400082290A0004F308240A010349380909428E
-:10675000CA982BC67E6DAA0500208800308C0F5980
-:106760000CA989BC99998163FF87BC89998163FFD2
-:1067700080C06002E63876D0BA63FFB4C0700247CA
-:106780003877D0D063FFCA006C100414D895C1527A
-:10679000A424CA3028221D73811B292102CD952AE9
-:1067A000300075A912DA20033B022C30072D0A02B3
-:1067B0005801C2653FDDD10F2B300703BB0BDAB0A8
-:1067C00074B3022ABDF8D3A063FFC6006C1004297D
-:1067D0002006C0706E9741292102C08F2A2014C064
-:1067E000B62B240606AA022A241479800227250241
-:1067F0002A221E2C221D7AC10EC8ABDA20DB302CD7
-:106800000A00033D025BF8146450752D21020D0D42
-:106810004CC9D3C020D10F00002E9CFB64E0822F16
-:1068200021020F0F4C65F0911AD8621CD86029A282
-:106830009EC08A798B5D2BC22668B0048D207BD9DF
-:106840005229A29DC0F364904A97901DD8732E21BF
-:10685000049D9608EE110FEE029E979E9118D86F38
-:10686000C0E527C4A22E24062BA29D2F21022BBCFB
-:106870003008FF022F25022BA69DC020D10F00005B
-:10688000002F300068F938DA20DB30DC4058004453
-:1068900063FF7700022A022B0A065800D3220A005F
-:1068A000D10F655010283000688924022A02033B6A
-:1068B00002DC4058003BC020D10FD270D10F000045
-:1068C0002A2C74033B02044C025BFEF863FF3B007E
-:1068D000DB30DC402A2C745BFEF5C020D10F0000B9
-:1068E0006C1004C83F89268829A399992609880C29
-:1068F000080848282525CC52C020D10FDB402A2C7F
-:10690000745BF93DD2A0D10F6C1004D820D730822F
-:10691000220D451105220C928264207407420B134C
-:10692000D821D420A383732302242DF885807451A9
-:106930004CBC82C0906D081600408800708C77397E
-:1069400003D720C0918680743901D420746102631A
-:10695000FFE2CA98C097C0411BD8A0C0A00B8B0C07
-:106960000B4A380A0A42C9AA1DD80E1CD80F2CD6C9
-:106970007EC140D30F6D4A0500208800308C97807F
-:10698000D270D10FBC8FC0E00F4E387E90E263FF13
-:10699000D6BC8292819280C0209282D10F000000EA
-:1069A0006C1006C0D71CD7FE1BD8000D4911D7208C
-:1069B0002E221F28221D0E4E0BD280078A0C2E7607
-:1069C0001F2AAC80C8346FAE026000CB2F0A801A39
-:1069D000D804A29EAA7A7EA33FC93FC0E1C050025C
-:1069E000E538050542CA552BC67EDB20D30F6D4A1C
-:1069F0000500308800B08C2E721DAE9E0EA50C6472
-:106A00005086D2802E761DC091298403D10FC050AC
-:106A100003E53875D0D363FFCD15D7F1027E0CA501
-:106A2000EE643051C0A1250A0002A538033A0205E0
-:106A300005426450922BC67E0E35129510255C10CF
-:106A4000054536D30F6D5A0500A08800208CC0A1E3
-:106A5000A3E2C05023FA8003730C03A538AF73057B
-:106A600005426450722BC67E851005450C6D5A0593
-:106A700000208800308CD280C0A10E9B0CAB7BAF75
-:106A8000BB2B761D2A8403D10FD280C0C1AF7D2DD0
-:106A9000761D2C8403D10F00D2302E8D08C0F1C09A
-:106AA000500EF538050542CB592BC67E0A3F14C15E
-:106AB000600F660C064636D30F6D6A05002088000D
-:106AC000E08C22721D63FF03C061C05003653875FE
-:106AD000D80263FF6263FF5CC05002A53875D0879F
-:106AE00063FF8100C06003F63876D0BF63FFB90052
-:106AF0006C10042A201529201614D7AF0A990CCB44
-:106B00009D2E200B04ED092BD11C8F2809BC36AC1F
-:106B1000AA0CBB0C2BD51C0A0A472A2415CAAF8B1A
-:106B2000438942B0A800910400881AA8FF0FBB0255
-:106B30009B278F260FB80C783B1AC020D10F00007E
-:106B4000292102C0A20A9902292502C021D10F00E1
-:106B50008B2763FFDC2BD11C0CAA0C0A0A472A24C2
-:106B600015ACBB2BD51CC9AE8B438C288F42B0AD66
-:106B700000F10400DD1AADCC0CBB029B27DA20B774
-:106B8000EB580019C021D10F9F2763FFEF000000D1
-:106B90006C100428203C64304705306000073E013B
-:106BA000053EB156076539054928C77FA933030655
-:106BB00041076603B166060641A6337E871E222181
-:106BC00025291AFC732B1502380C09816000063E3A
-:106BD00001023EB12406423903220AD10FD230D13C
-:106BE0000FC05163FFC000006C100427221EC0803C
-:106BF00008E4311DD76F0002002CD2821BD76F0032
-:106C00003104C06100661A2BB1020C6C022CD682D2
-:106C10000BE43119D7F20C3A11AA932832829780EB
-:106C2000253282243284B45525368275410A2921C1
-:106C300002096902292502D10F2A21022B32830A77
-:106C40006A022B36822A2502D10F00006C1004192B
-:106C5000D76327221EC08009770208E4311DD7546C
-:106C60000002002CD2821BD754003104C0610066A0
-:106C70001A2BB1020C6C022CD6820BE43119D7D737
-:106C80000C3A11AA932832829780253282243284CA
-:106C9000B45525368275410B2A21020A6A022A253B
-:106CA00002D10F002B21022C32830B6B022C368277
-:106CB0002B2502D10F0000006C10041BD73D0C2ABD
-:106CC00011ABAA29A286B438798B221BD73A19D7DF
-:106CD000610B2B0A2BB2A309290868B00274B90D05
-:106CE000299D0129901F6E920822A285D10FC020F4
-:106CF000D10FC892C020D10FDA205BEF35C020D170
-:106D00000F0000006C100414D72A28429E19D727C0
-:106D10006F88026000BA2992266890078A2009AA23
-:106D20000C65A0AC2A429DC0DC64A0A42B200C19E9
-:106D3000D7210CBC11A4CC2EC28609B90A7ED3027D
-:106D400060009A2992A36890078D2009DD0C65D018
-:106D50008C25C2856450862D2104C0306ED80D2C40
-:106D60002066B8CC0C0C472C246665C07B1CD79CD5
-:106D700018D7281AD71E19D72F1DD724C0E49E5123
-:106D80009D508F209357935599539A569A5408FFC4
-:106D9000021AD73A9F5288269F5A9E599D58935E51
-:106DA0009C5D935C9A5B080848058811985FC0D881
-:106DB0001FD7080CB911A499289285AFBF23F4CF2F
-:106DC000288C402896858E262D24069E29C020D109
-:106DD0000FCA33DA20C0B65BFF84C72FD10FC93A80
-:106DE000DA205BFF81C72FD10FDBD05BFE1A232493
-:106DF000662B200C63FF7500C72FD10FC72FD10F53
-:106E00006C1004C85B29200668941C689607C02093
-:106E1000D10FC020D10FDA20DB30DC40DD502E0A4C
-:106E2000005BFE6AD2A0D10F2E200C18D6E10CEF29
-:106E300011A8FF29F286C088798B751AD6DE0AEA76
-:106E40000A2AA2A368A0048B207AB96423F285647D
-:106E5000305E1CD6E82A0A802D2068292067282168
-:106E6000040B991104881109880208DD02C09428D6
-:106E70004A1008DD0218D6E0993198308B2B9A37EA
-:106E80009D340CBB029B32C0C09C359C362A2C74AE
-:106E9000DB40C0D318D6CF29F285A8EE299C202C40
-:106EA000E4CF29F6852D2406DD405BFDFAD2A0D182
-:106EB0000FDA20DBE05BFF4CC020D10F6C100AD64C
-:106EC000302A2006941128ACF86583872B2122C034
-:106ED000F22A21246550082AAC010A0A4F2A2524E7
-:106EE0007ABB0260037F2C21020C0C4C65C3192E67
-:106EF00022158D32C0910EDD0C65D39088381ED6D8
-:106F0000AC64836B8C37C0B8C0960CB9399914B493
-:106F10009A9A120D991199138F6718D6A7C9FB2851
-:106F200080217F83168B142C22002A200C5BFF62A9
-:106F3000D4A064A3A88F6760002800002B200C89D0
-:106F4000120CBA11AEAA2CA2861DD69A7C9B3E0DBD
-:106F5000BD0A2DD2A368D00488207D893024A28563
-:106F600064436427212E07F73607F90C6F9D01D77C
-:106F7000F0DA20DB70C1C42D211F5BFF0589268854
-:106F800027DDA009880C7A8B179A10600006C04094
-:106F900063FFCC0000DA208B105BFED58D1065A25C
-:106FA00067C0E09E488C649C498B658A669B4A9AC0
-:106FB0004B97458F677F7302600120CD529D10DA99
-:106FC00020DB302C12015BFE768D10C051D6A08FD5
-:106FD000A7C0C08A68974D9A4C8869896A984E996B
-:106FE0004F8E6A8A69AE7E77EB01B1AA9E6A9A6972
-:106FF0008B60C0A00B8E1477B701C0A1C091C08474
-:1070000093159D179516C0D025203CC03008580117
-:10701000089338C082083310085B010535400B9D8A
-:107020003807DD100BAB100E19402A211F079910ED
-:1070300003DD020DBB020553100933020A55112965
-:1070400021250A2A140929140499110A99020933DD
-:10705000028A2B2921040BAA021BD6E208991109E6
-:1070600055020855020BAA029A40892088140899F3
-:107070001109880219D6631DD6DC09880298418B54
-:107080002A9346954783150DBB0285168D179B44A1
-:107090008A658966AACAA97C77CB01B1AA07FB0CCD
-:1070A0009C669A6588268E29AD87972607EE0C0E7A
-:1070B0000E482E25259B672B200C87131ED63D0CD2
-:1070C000B911AE99289285A78828968517D641C010
-:1070D00090A7BB29B4CF871863FE3C008C60C0E04A
-:1070E000C091C0F0C034C0B82A210428203C08AAAE
-:1070F000110B8B01038301039F380B9B39C03208AE
-:10710000FF10038801089E380C881407EE100FEE5C
-:107110000203880108983905BF1029211F0ABB11F5
-:1071200007881008FF020BAA0218D6350929140394
-:10713000AA022B212583200B2B1404BB1108331129
-:107140000FBB020B99028B148F2A0B3302083302F8
-:107150008B2B6470868868974D984C8769886A93F2
-:10716000419946974E984FC07077C701C0719A47B2
-:1071700018D69E0B7C100CEC0208F802984418D626
-:107180009B0CBC0208CC029C402A200C295CFEC04F
-:10719000801FD6071CD60F0CAE112B2124ACAAAF32
-:1071A000EEB0BB8F132CE28528A4CFAFCC2CE685A4
-:1071B0002A22152B2524B1AA2A26156490DBC9D2D0
-:1071C0008F262E22090DFF082F26060FEE0C0E0E1D
-:1071D000482E25256550E4C020D10F00C070934192
-:1071E0009F4499469A4777C70A1CD5F32CC022C002
-:1071F000810C87381CD67F0B781008E80208B8028B
-:107200000C8802984063FF8000CC57DA20DB608C4A
-:10721000115BFDE3292102689806689403C020D120
-:107220000F2B221EC0A029221D2A25027B9901C0F6
-:10723000B064BFE813D5DE2CB00728B000DA200315
-:10724000880A28824CC0D10B8000DBA065AFE763C1
-:10725000FFCA000068A779DA20DB30DC40DD505B34
-:10726000FEE8D2A0D10FC16DC19D29252C6000047C
-:1072700029252CD6902624672F2468DA20DB308C31
-:1072800011DD502E0A805BFD51D2A0D10FC168C123
-:10729000A82A252C63FFDD000000C8DF8C268B297F
-:1072A000ADCC9C260CBB0C0B0B482B25252A2C7433
-:1072B000DB602C12015BFD94D2A0D10F2A2C748BC1
-:1072C000115BF6CDD2A0D10FDA205BFE4763FF3809
-:1072D00000DA20C0B15BFE8B65AF2D63FBEDDA20D9
-:1072E0002B200C5BFE5A63FF1F00000012D6428267
-:1072F00020028257C82163FFFC12D63E03E8300407
-:10730000EE3005B13093209421952263FFFC0000FC
-:1073100010D63A910092019302940311D611821073
-:1073200001EA30A21101F031C04004E4160002006D
-:1073300011D6338210234A00032202921011D5FD88
-:10734000C021921004E43184038302820181000091
-:10735000D23001230000000010D62A910092019340
-:1073600002940311D600821001EA30A21101F1311A
-:10737000C04004E41600020011D621821013D5A7E4
-:10738000032202921004E43184038302820181000B
-:1073900000D330013300000010D61B91008101653D
-:1073A000104981026510448103CF1F92019302941A
-:1073B0000311D5EE821001EA30A21101F231C04072
-:1073C00004E41600020011D60D821013D58E03229C
-:1073D00002921004E431840383028201C0109103FD
-:1073E00091029101810000D43001430012D5BDC04B
-:1073F0003028374028374428374828374C233D0168
-:107400007233ED03020063FFFC00000010D5FF9112
-:107410000092019302940311D5FD8210921011D5B0
-:10742000AF8310032202921011D5FA12D5C1921027
-:10743000C04004E41600020011D5F1821013D5A853
-:10744000032202921004E43184038302820181004A
-:1074500000D53001530000006C10026E322FD62090
-:10746000056F04043F04745B2A05440C00410400CA
-:10747000331A220A006D490D73630403660CB122AE
-:107480000F2211031314736302222C01D10FC83B86
-:10749000D10F000073630CC021D10F000000000069
-:1074A00044495630C020D10F6C10020040046B4C90
-:1074B00007032318020219D10F020319C020D10FAC
-:1074C0006C100202EA30D10F6C1002CC2503F031AF
-:1074D00060000F006F220503F1316000056F230586
-:1074E00003F231000200D10F6C1002CC2502F03003
-:1074F000D10F00006F220402F130D10F6F2304027C
-:10750000F230D10FC020D10F6C1002220A20230AC2
-:10751000006D280E28374028374428374828374C34
-:10752000233D01030200D10F6C100202E431D10FA0
-:107530000A0000004368656C73696F204657204459
-:10754000454255473D3020284275696C7420576587
-:1075500064204F63742020382031353A35303A3575
-:1075600030205044542032303038206F6E20636C0D
-:10757000656F70617472613A2F686F6D652F666513
-:107580006C69782F772F66775F372E30292C20563D
-:10759000657273696F6E2054337878203030372EDF
-:1075A00030312E3030202D203130303730313030F6
-:0875B000100701006F4EF8BB4B
-:00000001FF
diff --git a/firmware/cxgb3/t3fw-7.4.0.bin.ihex b/firmware/cxgb3/t3fw-7.4.0.bin.ihex
new file mode 100644 (file)
index 0000000..38dda94
--- /dev/null
@@ -0,0 +1,1917 @@
+:1000000060007400200380002003700000001000D6
+:1000100000002000E100028400070000E1000288E7
+:1000200000010000E0000000E00000A0010000006E
+:1000300044444440E3000183200200002001E0002A
+:100040002001FF101FFFD0001FFFC000E300043C91
+:100050000200000020006B741FFFC29020006BBCE8
+:100060001FFFC29420006BFC1FFFC29820006C7021
+:100070001FFFC29C200003C0C00000E43100EA3131
+:1000800000A13100A03103020002ED306E2A05000C
+:10009000ED3100020002160012FFDBC03014FFDA5F
+:1000A000D30FD30FD30F03431F244C107249F0D347
+:1000B0000FD30FD30F12FFD5230A00240A00D30F4A
+:1000C000D30FD30F03431F244C107249F0D30FD327
+:1000D0000FD30F14FFCE03421F14FFCB03421F1296
+:1000E000FFCCC0302D37302D37342D37382D373CED
+:1000F000233D017233ED00020012FFC4C0302F37E0
+:10010000002F37102F37202F3730233D017233ED6A
+:1001100000020012FFBEC0302737002737102737F4
+:1001200020273730233D017233ED03020012FFB95F
+:1001300013FFBA0C0200932012FFB913FFB90C028F
+:1001400000932012FFB8C0319320822012FFB71312
+:10015000FFB7932012FFB715FFB316FFB6C030D715
+:100160002005660160001B00000000000000000088
+:10017000043605000200D30FD30F05330C6E3B1479
+:100180000747140704437631E604360505330C6F40
+:100190003BED00020012FFA615FFA3230A00D720A3
+:1001A000070443043E0505330C0747146F3BF00377
+:1001B000020012FFA1C03014FFA1D30FD30FD30F41
+:1001C0009340B4447249F2D30FD30FD30F14FF9B63
+:1001D000834014FF9B834012FF9B230A0014FF9A65
+:1001E000D30FD30FD30F9340B4447249F2D30FD33C
+:1001F0000FD30F14FF95834012FF95C92F832084DE
+:10020000218522BC22743B0F8650B4559630B433FE
+:100210007433F463FFE60000653FE1655FDE12FFC3
+:100220007C230A0028374028374428374828374C91
+:10023000233D017233ED03020000020012FF7AC079
+:1002400032032E0503020012FF7813FF819320C0B2
+:1002500011014931004831010200C00014FF7E0441
+:10026000D23115FF7D945014FF7D04D33115FF7CEE
+:10027000945014FF7C04D43115FF7C24560014FFE5
+:100280007B04D53115FF7B24560010FF7A03000054
+:10029000000000000000000000000000000000005E
+:1002A000000000000000000000000000000000004E
+:1002B000000000000000000000000000000000003E
+:1002C000000000000000000000000000000000002E
+:1002D000000000000000000000000000000000001E
+:1002E000000000000000000000000000000000000E
+:1002F00000000000000000000000000000000000FE
+:1003000000000000000000000000000000000000ED
+:1003100000000000000000000000000000000000DD
+:1003200000000000000000000000000000000000CD
+:1003300000000000000000000000000000000000BD
+:1003400000000000000000000000000000000000AD
+:10035000000000000000000000000000000000009D
+:10036000000000000000000000000000000000008D
+:10037000000000000000000000000000000000007D
+:10038000000000000000000000000000000000006D
+:10039000000000000000000000000000000000005D
+:1003A000000000000000000000000000000000004D
+:1003B000000000000000000000000000000000003D
+:1003C000000000000000000000000000000000002D
+:1003D000000000000000000000000000000000001D
+:1003E000000000000000000000000000000000000D
+:1003F00000000000000000000000000000000000FD
+:1004000000000000000000000000000000000000EC
+:1004100000000000000000000000000000000000DC
+:1004200063FFFC000000000000000000000000006E
+:100430000000000000000000000000001FFC0000A1
+:100440001FFC0000E30005C81FFC00001FFC0000AB
+:10045000E30005C81FFC00001FFC0000E30005C806
+:100460001FFFC0001FFFC000E30005C81FFFC00042
+:100470001FFFC018E30005C81FFFC0181FFFC018EA
+:10048000E30005E01FFFC0181FFFC290E30005E076
+:100490001FFFC2901FFFC290E30008581FFFC290C9
+:1004A0001FFFC58CE3000858200000002000016AEF
+:1004B000E3000B542000018020000180E3000CC009
+:1004C0002000020020000203E3000CC02000021CF8
+:1004D00020000220E3000CC420000220200002269D
+:1004E000E3000CC82000023C20000240E3000CD0D6
+:1004F0002000024020000249E3000CD42000024CFE
+:1005000020000250E3000CE02000025020000259BD
+:10051000E3000CE42000025C20000260E3000CF029
+:100520002000026020000269E3000CF42000026C4D
+:1005300020000270E3000D0020000270200002790C
+:10054000E3000D042000028C2000028CE3000D105B
+:100550002000029020000293E3000D10200002AC66
+:10056000200002B0E3000D14200002D0200002F2AF
+:10057000E3000D18200003B0200003B0E3000D3CA1
+:10058000200003B0200003B0E3000D3C200003B0C6
+:10059000200003B0E3000D3C200003B0200003B0B6
+:1005A000E3000D3C200003B020006D94E3000D3CFF
+:1005B00020006D9420006D94E3007720000000007F
+:1005C00000000000000000001FFC00001FFC0000F5
+:1005D0001FFFC5901FFFC67020006D9820006D980A
+:1005E000DEFFFE000000080CDEADBEEF1FFFC2A064
+:1005F0001FFCFE001FFFC0941FFFC5C0300000009D
+:10060000003FFFFF8040000010000000080FFFFFC8
+:100610001FFFC26D000FFFFF804FFFFF8000000033
+:1006200000000880B000000560500000600000007D
+:1006300040000011350000004100000010000001E2
+:100640002000000000001000400000000500000035
+:1006500080000019040000000000080010000005E0
+:10066000806000007000000020000009001FF800FA
+:100670008000001EA0000000F800000007FFFFFF40
+:100680000800000018000000010080014200000086
+:100690001FFFC21D1FFFC0DC000100806040000082
+:1006A0001A0000000C0000001000000A00003000DA
+:1006B000600008008000001C000100008000001A9B
+:1006C00080000018FC0000008000000100004000D5
+:1006D000030000008000040050000003FFFFBFFF84
+:1006E0001FFFC3D400000FFFFFFFF000000016D073
+:1006F0000000FFF7A50000001FFFC4B01FFFC4618A
+:100700000001000800000B20202FFF801FFFC455B0
+:1007100000002C00FFFEFFF800FFFFFF1FFFC57861
+:1007200000002000FFFFDFFF0000FFEF01001100CD
+:100730001FFFC3D21FFFC590FFFFEFFF0000FFFBAD
+:100740001FFFC6301FFFBEA0FFFFF7FF1FFFC064E3
+:100750000000FFFD1FFFC6200001FBD01FFFC5B03A
+:100760001FFFC6601FFFC591E0FFFE001FFFC5A071
+:10077000000080001FFFC53C1FFFC5B41FFFC068FD
+:100780001FFFC4D01FFCFFD8000100817FFFFFFFC7
+:10079000E1000600000027101FFCFE301FFCFE7069
+:1007A000E10002001FFFC5381FFFC5500003D090B5
+:1007B0001FFFC5642B5063802B5079802B50908095
+:1007C0002B50A6801FFFC4690100110F202FFE00CF
+:1007D00020300080202FFF000000FFFF0001FFF805
+:1007E0002B50B2002B50B208000100102B50B180EA
+:1007F0002B50B2802B50BA00000100112B50BD28A5
+:100800002B50BC802B50BDA020300000DFFFFE002D
+:100810005000000200C0000002000000FFFFF7F4DB
+:100820001FFFC06C000FF800044000000010000023
+:100830000C4000001C400000E00000A01FFFC5406D
+:100840001FFD00081FFFC5541FFFC5681FFFC57CA3
+:10085000E1000690E10006EC00000000000000004E
+:100860000000000000000000010000000000000087
+:100870000000000000000000201000402010004098
+:100880002010004020140080200C0000200C0000EC
+:10089000200C000020100040201400802014008054
+:1008A00020140080201800C0201C0100201C010022
+:1008B000201C010020200140201800C0201800C08A
+:1008C000201800C0201C0100201800C0201800C003
+:1008D000201800C0201C01002020014020200140E1
+:1008E00020200140202009402020094020200940EC
+:1008F0002020094020240980FFFFFFFFFFFFFFFFAA
+:10090000FFFFFFFF000000000000000000000000EB
+:100910000000000000000000200054902000536000
+:1009200020005490200054902000529C2000529CA3
+:100930002000529C200050DC200050DC200050D4CD
+:100940002000504020004EE820004CC820004A9C67
+:100950000000000000000000200054602000532C24
+:10096000200053D0200053D0200051842000518417
+:10097000200051842000518420005184200050CC5C
+:100980002000518420004E0820004C7820004A4866
+:10099000000000000000000020000BE820003A30BA
+:1009A000200004C02000463C20000BE0200041480D
+:1009B000200003F0200045FC20004A2420003E5483
+:1009C00020003D70200039AC2000383C200035ACC0
+:1009D0002000310C20003BCC20002D6C2000280092
+:1009E000200067182000238C2000206C2000201895
+:1009F00020001D04200018182000154820000E2C8F
+:100A000020000C2C2000110C200012F82000434084
+:100A100020003E0820000BF0200004C00000000071
+:100A200000000000000000000000000000000000C6
+:100A300000000000000000000000000000000000B6
+:100A400000000000000000000000000000000000A6
+:100A50000000000000000000000000000000000096
+:100A60000000000000000000000000000000000086
+:100A70000000000000000000000000000000000076
+:100A80000000000000000000000000000000000066
+:100A900000000000000000000000000032640000C0
+:100AA0000000000032640000640064006400640020
+:100AB00064006400640064000000000000000000A6
+:100AC0000000000000000000000000000000000026
+:100AD0000000000000000000000000000000000016
+:100AE0000000000000000000000000000000000006
+:100AF00000000000000000000000000000000000F6
+:100B000000001000000000000000000000000000D5
+:100B100000000000000000000000100000000000C5
+:100B200000000000000000000000000000432380DF
+:100B300000000000000000000000000000000000B5
+:100B400000000000000000000000000000000000A5
+:100B500000000000005C94015D94025E94035F94C9
+:100B60000043000000000000000000000000000042
+:100B70000000000000000000000000000000000075
+:100B80000000000000000000000000000000000065
+:100B900000000000005C90015D90025E90035F9099
+:100BA00000530000000000000000000000000000F2
+:100BB0000000000000000000000000000000000035
+:100BC0000000000000000000000000000000000025
+:100BD00000000000009C94001D90019D94029E94D2
+:100BE000039F94040894050994060A94070B940043
+:100BF00043000000000000000000000000000000B2
+:100C000000000000000000000000000000000000E4
+:100C100000000000009C90019D90029E90071D9096
+:100C2000039F90047890057990067A90077B900056
+:100C30005300000000000000000000000000000061
+:100C400000000000000000000000000000000000A4
+:100C50000000000000DC94001D9001DD9402DE9491
+:100C600003DF94040494050594060694070794088A
+:100C700008940909940A0A940B0B9400430000009D
+:100C80000000000000000000000000000000000064
+:100C90000000000000DC9001DD9002DE900B1D9052
+:100CA00003DF9004B49005B59006B69007B790089E
+:100CB000B89009B9900ABA900BBB9000530000009D
+:100CC00063FFFC0020006B5010FFFF0A00000000D3
+:100CD00020006B7400D23110FFFE0A0000000000FB
+:100CE00020006BBC00D33110FFFE0A0000000000A2
+:100CF00020006BFC00D43110FFFE0A000000000051
+:100D000020006C7000D53110FFFE0A0000000000CA
+:100D100063FFFC00E00000A012FFF7822002825770
+:100D2000C82163FFFC12FFF303E83004EE3005C076
+:100D30003093209421952263FFFC00001FFFD00018
+:100D4000000400201FFFC5901FFFC670200A00117D
+:100D5000FFFB13FFFB03E63101020016FFFA17FF4A
+:100D6000FAD30F776B069060B4667763F85415B5C5
+:100D7000541A610F140063FFF90000006C1004C0E6
+:100D800020D10F006C1004C0C71AEF06D830BC2B5E
+:100D9000D72085720D4211837105450B9572023380
+:100DA0000C2376017B3B04233D089371A32D12EEA7
+:100DB000FE19EEFEA2767D632C2E0A000882022820
+:100DC0000A01038E380E0E42C8EE29A67E6D4A0532
+:100DD00000208800308C8271D10FC0F0028F387FE4
+:100DE000C0EA63FFE400C0F1C050037E0CA2EE0E27
+:100DF0003D1208820203F538050542CB5729A67E2D
+:100E00002FDC100F4F366DFA0500208800308CBCA7
+:100E100075C03008E208280A01058338030342C977
+:100E20003E29A67E0D480CD30F6D8A050020880050
+:100E3000B08C8271D10FC05008F53875C0C163FF06
+:100E4000BBC06002863876C0DA63FFD46C1012161D
+:100E5000EED8C1F9C1E8C1C72B221E28221DC0D07F
+:100E60007B81312920060BB702299CFA655008289E
+:100E70002072288CFF28247264915C2AB0000CA890
+:100E80000C6481670EA90C6492B37FA13769AC2F03
+:100E90006000340000282006D7D0288CFACC572ACE
+:100EA00020722AACFF2A24726481352AD0000CA952
+:100EB0000C6491640EAC0C64C31B7FA10768AC0783
+:100EC000C020D10F002D25028A32C0900A6E5065D5
+:100ED000E5B5292467090F4765F5B12C200C1FEEF5
+:100EE000B50CCE11AFEE29E286B4487983026005D5
+:100EF0008219EEB109C90A2992A36890078F2009C7
+:100F0000FF0C65F56E2FE28564F56865559628221D
+:100F10001D7B8105D9B060000200C0908B9417EE54
+:100F2000A70B881487740B0B47A87718EEA509BB8D
+:100F30001008770297F018EEA317EEA408A8010B8B
+:100F400088020747021BEEA097F10B880298F22750
+:100F500090232B902204781006BB1007471208BB81
+:100F6000022890210777100C88100788020B88024E
+:100F700017EE988B3307BB0187340B880298F397E1
+:100F80009997F48B9587399BF588968B3898F688D6
+:100F90009797F99BF898F717EE8F28E28507C7080F
+:100FA0002D74CF08480B28E68565550F2B221E2887
+:100FB000221D7B89022B0A0064BF042CB00728B0D5
+:100FC00000DA2006880A28824CC0D10B8000DBA002
+:100FD00065AFE763FEE90000292072659E9C60040E
+:100FE000E72A207265AEC36004DE00002EB0032C39
+:100FF0002067D4E065C1058A328C330AFF500C4566
+:1010000054BC5564F4EB19EE74882A09A9010988C7
+:101010000C64821FC0926000DD2ED0032A2067D4AA
+:10102000E065A0D88A328B330AFC500B4554BC557E
+:1010300064C4BE19EE69882A09A9017989D50BEA29
+:101040005064A4E30CEE11C0F02F16132E16168A6E
+:10105000E78CE82A16128EE9DFC0AAEA7EAB01B15E
+:10106000CF0BA8506583468837DBC0AE89991E78C0
+:101070009B022BCC012B161B29120E2B0A002916C2
+:101080001A7FC3077FC9027EAB01C0B165B49D8BD7
+:10109000352F0A002A0A007AC30564C3CB2F0A0140
+:1010A00065F4892B12162B1619005104C0C100CC0F
+:1010B0001A2CCCFF2C16170CFC132C16182B121AFA
+:1010C0002A121BDC50581974C0D0C0902E5CF42C2E
+:1010D00012172812182F121B2A121A08FF010CAA25
+:1010E000018834074C0AAB8B2812192BC6162F86A1
+:1010F000082A86092E74102924672E70038975B179
+:10110000EA2A7403B09909490C659DB32B20672D19
+:10111000250265B3FA2B221E2C221D7BC901C0B00B
+:1011200064BD9C2CB00728B000DA2006880A28820B
+:101130004CC0D10B8000DBA065AFE763FD8189BAAD
+:10114000B19965909788341CEE2598BA8F331EEEBE
+:101150001E0F4F542FB42C8D2A8A320EDD020CAC98
+:10116000017DC9660A49516F92608A3375A65B2C6E
+:10117000B0130AED510DCD010D0D410C0C417DC98F
+:10118000492EB012B0EE65E3C6C0D08E378CB88A57
+:10119000368FB97CA3077AC9027EFB01C0D1CED9B4
+:1011A00088350AAD020E8E0878EB022DAC0189B7A6
+:1011B000DAC0AF9B79BB01B1CADCB0C0B07DA30778
+:1011C0007AD9027CEB01C0B164B161C09129246776
+:1011D000C020D10F00008ADAB1AA64A0C02C206719
+:1011E0002D250265C3111DEDF88A321EEDFD0DADF2
+:1011F000010EDD0C65D28A0A4E516FE20260028157
+:10120000C090292467090F4765F2F828221D7B89C1
+:10121000022B0A0064BCA82CB00728B000DA200614
+:10122000880A28824CC0D10B8000DBA065AFE76341
+:10123000FC8D00000CE9506492ED0CEF11C0802889
+:101240001611AFBF2F16198EF88BF7DAE08FF92B36
+:101250001610ABFB7FBB01B1EA0CA8506580D688A5
+:1012600037DCE0AF89991C789B022CEC012C161B13
+:1012700029120C2C0A0029161A7AE3077AE9027F50
+:10128000BB01C0C165C2A58B352C0A002A0A007AB1
+:10129000E30564E1CA2C0A0164CE0D60028E883435
+:1012A0001BEDCF98DA8F331EEDC80F4F542FD42C7F
+:1012B0008C2A8A320ECC020BAB010CBB0C65BF0A28
+:1012C0000A49516E920263FF018A330AAB5064BE31
+:1012D000F92CD0130AEE510ECE010E0E410C0C412A
+:1012E0000ECC0C65CEE42FD012B0FF65F26EC0B00C
+:1012F0008E378CD88A362FD2097CA3077AC9027E12
+:10130000FB01C0B165BEC38835DBA0AE8E78EB01B2
+:10131000B1AB89D7DAC0AF9D79DB01B1CAC0C07B60
+:10132000A3077AB9027DEB01C0C165CE9DC09029AB
+:101330002467C020D10F88378C3698140CE90C290B
+:10134000161408F80C981D78FB07281214B088288A
+:101350001614891D9F159B16C0F02B121429161AFE
+:101360002B161B8B147AE30B7AE90688158E1678F8
+:10137000EB01C0F165F1BA29121A2F12118A352E2C
+:10138000121B9A1AAFEE2F1210C0A0AF9F79FB016B
+:10139000B1EE9F11881AC0F098107AE30A7EA90571
+:1013A0002A12017A8B01C0F164F0816001838936D1
+:1013B0008B3799170BE80C981F09C90C291615785B
+:1013C000EB07281215B088281615D9C09A199E184F
+:1013D0008A1F2E12152A161A2E161BDAC0C0E08C90
+:1013E000177F930B7FA90688188F1978FB01C0E13E
+:1013F00065E13E29121A2F12138A352E121B9A1BF1
+:10140000AFEE2F1212C0A0AF9F79FB01B1EE9F1378
+:10141000881BC0F098127AE30A7EA9052A12037A83
+:101420008B01C0F165F10A2E12162E16192A121B15
+:10143000005104C0E100EE1AB0EE2E16170EFF1395
+:101440002F16180FCC01ACAA2F121A0EBC01ACFC3F
+:101450007FCB01B1AA2A161B2C161A63FC5E000072
+:101460007FB30263FE3163FE2B7EB30263FC306305
+:10147000FC2A00006450C0DA20DBC0581648C020A7
+:10148000D10FC09163FD7A00C09163FA44DA20DB8A
+:1014900070C0D12E0A80C09A2924682C7007581574
+:1014A00038D2A0D10F03470B18ED4FDB70A8287876
+:1014B00073022B7DF8D9B063FA6100002A2C74DB2B
+:1014C00040580EB363FAE4000029221D2D25027B4B
+:1014D0009901C0B0C9B62CB00728B000DA20068840
+:1014E0000A28824CC0D10B8000DBA065AFE7C0208A
+:1014F000D10FC09163FBFF00022A025802440AA2E6
+:1015000002060000022A025802410AA20206000056
+:10151000DB70DA20C0D12E0A80C09E2924682C708E
+:1015200007581517C020D10FC09463FBC9C096633C
+:10153000FBC4C09663FBBF002A2C74DB30DC405B2D
+:10154000FE11DBA0C2A02AB4002C200C63FF2700F0
+:101550008D358CB77DCB0263FDD263FC6D8F358EEC
+:10156000D77FEB0263FDC563FC6000006C1004C014
+:1015700020D10F006C1004C020D10F006C10042B80
+:10158000221E28221DC0A0C0942924062A25027BE1
+:101590008901DBA0C9B913ED06DA2028B0002CB010
+:1015A0000703880A28824CC0D10B8000DBA065AFFE
+:1015B000E7C020D10F0000006C10042C20062A2167
+:1015C0000268C80528CCF965812E0A094C6591048A
+:1015D0008F30C1B80F8F147FB00528212365812774
+:1015E00016ECF529629E6F98026000F819ECF1295B
+:1015F00092266890078A2009AA0C65A0E72A629DB6
+:1016000064A0E12B200C0CB911A6992D92866FD9FC
+:10161000026000DB1DECE90DBD0A2DD2A368D007E6
+:101620008E200DEE0C65E0C7279285C0E06470BF88
+:101630001DECEE68434E1CECED8A2B0CAA029A704E
+:1016400089200899110D99029971882A98748F320E
+:101650009F75282104088811987718ECDE0CBF11BB
+:10166000A6FF2DF285A8B82E84CF2DDC282DF68577
+:10167000C85A2A2C74DB40580E46D2A0D10FC02085
+:10168000D10F00000029CCF96490B12C206689317B
+:10169000B1CC0C0C472C24666EC60260008509F89C
+:1016A0005065807F1CECD38A2B0F08400B881008F4
+:1016B000AA020CAA029A7089200899110D99029920
+:1016C00071883398738C329C728A2A9A74893499FF
+:1016D0007563FF7D00CC57DA20DB30DC4058151DE8
+:1016E000C020D10F00DA20C0B65815AC63FFE5006A
+:1016F000DA205815AA63FFDC00DA20DB30DC40DD9D
+:1017000050581638D2A0D10FC858DA20DB30581400
+:101710008A2A210265AFBDC09409A9022925026366
+:10172000FFB200002B21045814351DECAFC0E02E91
+:1017300024668F302B200C0F8F1463FF662921380D
+:10174000C08879830263FF5B2C20662B2104B1CC17
+:101750000C0C472C24665814291DECA3C0E02E2441
+:10176000668F302B200C0F8F1463FF376C1004C072
+:10177000B7C0A116ECA015EC92D720D840B822C073
+:10178000400535029671957002A438040442C94B95
+:101790001AEC8519EC8629A67EC140D30F6D4A0547
+:1017A00000808800208C220A88A272D10FC05008C5
+:1017B000A53875B0E363FFD76C1006931394112915
+:1017C0002006655288C0716898052A9CF965A29820
+:1017D00016EC792921028A1309094C6590CD8AA05B
+:1017E0000A6A512AACFD65A0C2CC5FDB30DA208CDE
+:1017F000115814D8C0519A13C7BF9BA98E132EE25B
+:101800000968E0602F629E1DEC6A6FF80260008438
+:101810002DD22668D0052F22007DF9782C629DC735
+:101820009064C0709C108A132B200C2AA0200CBD41
+:1018300011A6DD0A4F14BFA809880129D286AF88F6
+:10184000288C09798B591FEC5C0FBF0A2FF2A36813
+:10185000F0052822007F894729D285D490659075AC
+:1018600060004300002B200C1FEC540CBD11A6DDC2
+:1018700029D2860FBF0A6E96102FF2A368F0048853
+:10188000207F890529D285659165DA20581543C9DD
+:101890005C6001FF00DA20C0B658154060000C0003
+:1018A000C09063FFB50000DA2058153C6551E48D07
+:1018B000138C11DBD08DD0022A020D6D515813AD5F
+:1018C0009A1364A1CEC75F8FA195A9C0510F0F478E
+:1018D0009F1163FEFD00C091C0F12820062C2066F8
+:1018E000288CF9A7CC0C0C472C24666FC6098D13E5
+:1018F0008DD170DE02290A00099D02648159C9D385
+:101900008A102B21045813BD8A13C0B02B24662ED5
+:10191000A2092AA0200E28141CEC338D1315EC27E5
+:10192000C1700A773685562DDC28AC2C9C12DED08F
+:10193000A8557CD3022EDDF8D3E0DA40055B02DC4B
+:10194000305BFF8AD4A028200CB455C0D02B0A8865
+:101950002F0A800C8C11A6CC29C285AF3FAB9929E8
+:10196000C6851CEC1CDEF0AC882D84CF2812022921
+:10197000120378F3022EFDF8289020D3E007880C9C
+:10198000C170080847289420087736657FAB891313
+:1019900013EC1A8990C0F47797491BEC18C1CA2838
+:1019A00021048513099E4006EE1187530488118592
+:1019B000520E88020C88029BA09FA18F2B9DA59898
+:1019C000A497A795A603FF029FA22C200C1EEC0152
+:1019D000AECE0CCC1106CC082BC2852DE4CF2BBC8F
+:1019E000202BC6852A2C748B11580D69D2A0D10FDB
+:1019F00028203DC0E07C877F2E24670E0A4765A023
+:101A00007B1AEBFF88201EEBED8F138EE48FF4081A
+:101A100088110A88020F8F14AFEE1FEBFA98910F0E
+:101A2000EE029E901EEBF9C0801AEBEA2CD285AA3A
+:101A3000BAB8CC28A4CF2CD6852C21022F20720E28
+:101A4000CC02B1FF2F24722C2502C020D10F8713A6
+:101A5000877007074763FD6E282138C099798B028C
+:101A600063FE9ADDF063FE9500DA20DB308C11DD39
+:101A70005058155CD2A0D10FC0E163FF7A8B138C54
+:101A800011DD50C0AA2E0A802A2468DA205813BC1F
+:101A9000D2A0D10FC020D10F6C1006292102C0D0D6
+:101AA0007597102A32047FA70A8B357FBF052D2535
+:101AB000020DD902090C4C65C18216EBBE1EEBBCAF
+:101AC00028629EC0FA78F30260018829E2266890B5
+:101AD000078A2009AA0C65A17A2A629DDFA064A169
+:101AE000772B200C0CBC11A6CC29C286C08C798324
+:101AF0000260015719EBB109B90A2992A36890074E
+:101B0000882009880C65814327C2851CEBB364716A
+:101B10003A8931098B140CBB016FB11D2C20669FD3
+:101B200010B1CC0C0C472C24666EC6026001400933
+:101B3000FF5065F13A8A102AAC188934C0C47F97E7
+:101B40003C18EBB31BEBB28F359C719B708B209DC7
+:101B50007408BB029B72C08298751BEBAE0F0840E5
+:101B60009B730F881198777FF70B2F2102284A006B
+:101B700008FF022F2502C0B4600004000000C0B0BE
+:101B80007E97048F362F25227D97048837282521BC
+:101B90007C9736C0F1C0900AF9382F3C20090942E1
+:101BA00064908619EB8018EB8128967E00F08800FF
+:101BB000A08C00F08800A08C00F08800A08C2A6225
+:101BC0009D2DE4A22AAC182A669D89307797388F1C
+:101BD000338A3218EB8A07BE0B2C2104B4BB04CC29
+:101BE0001198E0C08498E1882B9DE59AE69FE71A5A
+:101BF000EB82099F4006FF110FCC020A880298E28F
+:101C0000C1FC0FCC022CE604C9B82C200C1EEB71D1
+:101C10000CCA11AECC06AA0829A2852DC4CF09B9D9
+:101C20000B29A685CF5CC020D10FC081C0900F8941
+:101C300038C08779880263FF7263FF6600CC57DA89
+:101C400020DB30DC405813C3C020D10FDA205814F9
+:101C50005363FFE8C0A063FE82DA20C0B658144F79
+:101C600063FFD900DB402A2C74580CC9D2A0D10FD5
+:101C70008A102B21045812E11EEB4EC0D02D246691
+:101C800063FEB1006C1006D62019EB491EEB4B2801
+:101C9000610217EB4808084C65805F8A300A6A5178
+:101CA00069A3572B729E6EB83F2A922668A0048CB7
+:101CB000607AC9342A729D2C4CFECAAB2B600CB6DC
+:101CC0004F0CBD11A7DD28D2860EBE0A78FB269CDC
+:101CD000112EE2A32C160068E0052F62007EF91594
+:101CE00022D285CF2560000D00DA60C0B658142BD3
+:101CF000C85A60010F00DA60581428655106DC40AC
+:101D0000DB308D30DA600D6D5158129AD3A064A08B
+:101D1000F384A1C05104044763FF6D00C0B02C6080
+:101D2000668931B1CC0C0C472C64666FC602709684
+:101D30000A2B61045812B1C0B02B64666550B42AF6
+:101D40003C10C0E7DC20C0D1C0F002DF380F0F42EA
+:101D500064F09019EB1418EB1528967E8D106DDA4F
+:101D60000500A08800C08CC0A089301DEB247797A7
+:101D70005388328C108F3302CE0BC02492E1226143
+:101D8000049DE00422118D6B9BE59FE798E61FEB15
+:101D90001A0998400688110822020FDD02C18D9DA4
+:101DA000E208220292E4B4C22E600C1FEB0A0CE897
+:101DB00011A7882C8285AFEE0C220B2BE4CF228654
+:101DC00085D2A0D10F28600CD2A08C1119EB020C87
+:101DD0008D11A988A7DD2ED2852B84CF0ECC0B2C9C
+:101DE000D685D10FC0F00ADF387FE80263FF6C634D
+:101DF000FF6000002A6C74C0B2DC20DD4058128FF6
+:101E0000C0B063FF63C020D10F0000006C10042C31
+:101E1000221D2A221EC049D320293006243468C03E
+:101E2000407AC105DDA060000200C0D06E9738C0C6
+:101E30008F2E0A802B3014C0962934060EBB022E3A
+:101E400031022B34147E8004243502DE407AC10E28
+:101E5000C8ABDBD0DA302C0A00580AE52E31020E6E
+:101E60000F4CC8FEC020D10F6895F8283102080831
+:101E70004C658FEF1AEAD01CEACE2BA29EC09A7B4B
+:101E80009B462BC22668B0048D307BD93B29A29D8E
+:101E9000C0E3CB9394901BEAE02D31049B9608DDC0
+:101EA000110EDD029D979D9112EADDC0E524C4A2CA
+:101EB0002E34062F310228A29D02FF02288C3028E2
+:101EC000A69D2F3502C020D10FDA30C0B65813B30B
+:101ED000C020D10F6C1006292006689805289CF9AF
+:101EE00065825D29210209094C659210CD51DB30D4
+:101EF000DA20044C02581317C051D3A0C7AF2A36BA
+:101F00000AC0E019EAAD1DEAB31FEAAC8A3A16EA44
+:101F1000A9B1AC64C13528629E6F88026001F129C5
+:101F2000DC332992266890078B2009BB0C65B1E051
+:101F300027629DC08E6471D82B200C0CBC11A6CCDE
+:101F400029C2867983026001D219EA9B09B90A295C
+:101F500092A3971068900828220009880C6581BB1D
+:101F600027C2856471B5292006299CF96491EC2C5F
+:101F700020668931B1CC0C0C472C24666EC60260F9
+:101F800001A109F85065819B883689F4088C14AC4E
+:101F9000991CEA8B0C99022C2104997019EAA1086A
+:101FA00008479971892A09881008990218EA9E0839
+:101FB000990299722830132930120488100699105A
+:101FC00008990228302C9A740C881008C8020988D5
+:101FD00002987389379975883898768A39C0819ABA
+:101FE000771AEA918935987B99780989140A9902B8
+:101FF000997A8A30893277A73618EA808F33987CAD
+:10200000C084987D882B2E76112976122F7613198D
+:10201000EA7A0A9F4006FF1104CA110988020FAA32
+:1020200002987EC1F90FAA022A7610C0AA600001A8
+:10203000C0A6ADBF0CBC11A6CC29C2852EF4CF0919
+:10204000A90B29C685655107C020D10F2B200C0C88
+:10205000BC1106CC0828C28609B90A6F8902600142
+:102060002E2992A36890082A220009AA0C65A11FB4
+:102070002AC28564A11928203D08284064808C84E8
+:102080003504841464408485F574537F8436048455
+:1020900014644077745374293013C08C79886CC0F1
+:1020A000902924670908476580ED882089F48435E4
+:1020B0001FEA55048414A4940F440294A014EA5017
+:1020C00008881104880298A1843698A3048414A473
+:1020D000990F990299A219EA4CADB428C2852E44F1
+:1020E000CF288C1028C6852821022F20720988024B
+:1020F000B2FF2F2472282502C020D10F00CC57DA5E
+:1021000020DB30DC40581293C020D10FC09163FF18
+:102110008FDA20C0B658132163FFE100DA2058138C
+:102120001F63FFD88A102B21045811B41DEA2A1FFF
+:10213000EA232B200CC0E02E24668A3A63FE480076
+:1021400000DA20DB30DC40DD505813A6D2A0D10FDE
+:102150002A2C74DB40580B8ED2A0D10F292138C015
+:102160008879830263FE202A12002C20662B21042A
+:102170002CCC010C0C472C24665811A01DEA161F0C
+:10218000EA0F2B200CC0E02E24668A3A63FDF8008B
+:10219000DA2058130263FF64DA205BFF1CD2A0D15F
+:1021A0000F0000006C10089515C061C1B0D9402A1D
+:1021B000203DC0400BAA010A64382A2006291606D1
+:1021C00068A8052CACF965C33B1DE9FC6440052FEC
+:1021D000120564F29C2621021EE9F806064C65628F
+:1021E000E315E9F46440D98A352930039A140A9931
+:1021F0000C6490CC2C200C8B149C110CCC11A5CC15
+:102200009C122CC286B4BB7CB3026002D38F110E29
+:10221000FE0A2EE2A368E0098620D30F0E660C6545
+:1022200062BE88122882856482B6891464905EDA60
+:1022300080D9308C201EE9F21FE9F31DE9E08B14F0
+:102240008DD4D4B07FB718B88A293C10853608C61B
+:10225000110E66029681058514A5D50F550295804D
+:102260000418146D8927889608CB110888140EBBB2
+:1022700002A8D8299C200F88029BA198A088929B35
+:10228000A3088814A8D80F880298A22AAC1019E9CC
+:10229000DEC0C08F141EE9CF86128D11286285AE74
+:1022A000DD08FF0B2CD4CF2821022F66858B352A21
+:1022B0002072098802ABAA2825022A2472C020D1E4
+:1022C0000F29529E18E9BB6F9802600208288226E7
+:1022D00068800829220008990C6591F92A529DC14D
+:1022E000CA9A1364A1EF2B200C2620060CB811A566
+:1022F000882D82860EBE0A7DC3026002022EE2A3F2
+:1023000068E0082F22000EFF0C65F1F3288285DEBD
+:10231000806481FF9810266CF96461FF2C20668828
+:1023200031B1CC0C0C472C24666EC6026001BC088F
+:10233000FD5065D1B617E9BD19E9A21AE9A92C210A
+:10234000048B2D2830102F211D0C88100BFB090C3D
+:1023500088020A880209BB026441528910C04D9B61
+:1023600090979198928D35D9E064D06CD730DBD0BE
+:10237000D8307FD713273C10BCE92632168C39960B
+:10238000E69CE78A37B4389AE80B13146430492A7C
+:10239000821686799A9696978C778A7D9C982B825E
+:1023A000172C7C209A9A2A9C189B99867BB03BB864
+:1023B000896DB9218BC996A52692162AAC18B899B1
+:1023C0009BA196A08BC786CD9BA22B921596A49B12
+:1023D000A386CB2CCC2026A605C0346BD4200D3B85
+:1023E0000C0DD8090E880A7FB705C0909988BC8863
+:1023F000C0900B1A126DAA069988998B288C18C068
+:10240000D01BE98C1CE98B16E981B1FF2A211C2322
+:10241000E6130F0F4F26E6122F251D7FA906C0F0E9
+:10242000C08028251D05F6111AE97A8F202BE615A4
+:102430002CE6162DE61726E6180AFA022AE61429D3
+:102440002006299CF96490FF29200C8D15C0801A64
+:10245000E9610C9C11AA99A5CCDA202BC28528949D
+:10246000CF0B4B0B2BC685C0B08C1658118AD2A04F
+:10247000D10F8A356FA548D8308BD56DA90C8A86C7
+:102480000A8A14CBA97AB337288C10C08028246715
+:10249000080B4765B112DA20DB302C12065811AD5B
+:1024A000D3A0C0C1C0D02DA4039C1563FD268636E1
+:1024B00064610C8910C04D9B909791989263FEA423
+:1024C000C08163FFC78A15CCA7DA20DB308C165891
+:1024D00011A1C020D10FDA20C0B658123063FFE43A
+:1024E00000DA208B1158122D63FFD9009E178A1332
+:1024F0002B21045810C28E17C0B02B246663FE3403
+:10250000C08063FE09DA20DB308C16DD505812B52E
+:10251000D2A0D10FDA2058122163FFA82D2138C094
+:10252000C87DC30263FE0D8A132B21042C206698FC
+:1025300017B1CC0C0C472C24665810B08E17C0D0A5
+:102540002D246663FDEE0000262138B06606064F96
+:10255000262538656EF128206A7F870508294164A1
+:1025600090A5C0D01BE92619E93426200723E61BD5
+:10257000B16609FA022BE61A28200A2DE61D2AE682
+:102580001E09880228E61C882606064728E6202B16
+:10259000220826E53E2BE6212D24072C20062A20A2
+:1025A0006468C347B44463FE9EDB30DA208D15C0F7
+:1025B000CE2E0A802C24688C165810F1D2A0D10F90
+:1025C0008E102A321616E8FD0A2A1486662BE612A9
+:1025D00097E127E61328E614AA6609660296E02E1C
+:1025E000EC4869ED50C14663FD7A000064AFB41950
+:1025F000E8F328201689920A880C00910400881AB2
+:10260000A8B8982963FF9C002B21046EB81E2C20CB
+:1026100066B8CC0C0C472C2466C9C09E178A135888
+:1026200010778E17C0348F20C0D02D2466C0682646
+:10263000240663FF2C008D35C08064D04AD9E0DCCD
+:1026400030DBE0DF301AE8FDB188B4FF17E8FD8623
+:10265000C9249DFF8DC82CCC102D46300767012D55
+:1026600046320A66011DE8F7264631AD6D2D463328
+:1026700026F21597B796B684C3BCBB94B58D3529A1
+:102680009C107D83C22F211DC14663FD4B000000BD
+:102690006C1006292006289CF86582BF2921022B90
+:1026A000200C09094C6590E116E8C30CBA11A6AAE2
+:1026B0002DA2862C0A127DC30260028C19E8BF0984
+:1026C000B90A2992A36890078C2009CC0C65C278BE
+:1026D00029A2856492722D629E1AE8B56FD80260B5
+:1026E000026E2AA22629160168A0082B22000ABB26
+:1026F0000C65B25C29629DC18C6492542A21200A27
+:10270000806099102C203CC7EF000F3E010B3EB1BA
+:10271000BD0FDB390BBB098F260DBD112DDC1C0D48
+:102720000D410EDD038E27B1DD0D0D410FEE0C0DB9
+:10273000BB0B2BBC1C0BB7027EC71C2C21257BCBF3
+:10274000162D1AFC0CBA0C0DA16000093E01073EC3
+:10275000B1780987390B770A77EB0260020A2C21DE
+:1027600023282121B1CC0C0C4F2C25237C8B29B0A4
+:10277000CD2D2523C855DA20DB3058106F292102D2
+:10278000CC96C0E80E9E022E2502CC57DA20DB3014
+:10279000DC405810F0C020D10F2C20668931B1CC1C
+:1027A0000C0C472C24666EC6026001D309FD5065EF
+:1027B000D1CD2F0A012E301129221464E0112822D4
+:1027C0001B090C4400C10400FA1A0A880228261BBF
+:1027D0002E3010C0A0C0B0941295131CE878883039
+:1027E0002CC022088D14778704C0F10CFA38C04140
+:1027F000C0F225203CC0840858010F5F010F4B3800
+:1028000005354007BB10C0F0084F3808FF100FBB5C
+:102810000228ECFEC0F0084F38842B0BA8100AFFEA
+:10282000102A21200F88020B880208440218E8862B
+:102830008F110844022821250A2A14082814048824
+:10284000110A88022A210494F08B2004E41008BBAA
+:102850001104BB02C04A04BB029BF1842A08AB11DD
+:102860000BEB0294F40A54110B44020555100D1B96
+:102870004094F707BB100B5502085502C08195F62E
+:102880008433C05094F3B1948B3295F898F99BF24D
+:10289000C080C1BC24261499FA9BF598FB85389515
+:1028A000FC843A94FD8B3B9BFE883998FF85352547
+:1028B000F6108436851324F6118B3784122BF6120A
+:1028C000C0B064C07E89307797438D3288332E3014
+:1028D000108F111CE84A0999400699112CF614C072
+:1028E000C42CF6158C2B2DF61A28F61B2BF6190482
+:1028F000A81109880208EE0219E840C18008EE021A
+:1029000009C90229F6162EF618C09E600001C09A69
+:102910002F200C18E8300CFE11A8FFA6EE2DE28542
+:102920002BF4CF0D9D0B2DE685C87F8A268929A71C
+:10293000AA9A260A990C090948292525655050C0EC
+:1029400020D10F00C09A63FFC6DA2058111463FE2D
+:1029500038DA20C0B658111163FE2E0068973C2B60
+:102960009CFD64BE24C020D10FDA20DB705810CD4E
+:10297000C0C0C0D10ADA390ADC3865CDE063FE098F
+:102980008A102B2104580F9DC0B02B246663FE21B2
+:10299000DB402A2C7458097ED2A0D10FDA20580FC0
+:1029A000A263FCF76C1004C020D10F006C10042946
+:1029B0000A801EE8261FE8261CE7FF0C2B11ACBB83
+:1029C0002C2CFC2DB2850FCC029ED19CD0C051C0C6
+:1029D0007013E82214E82118E81F2AB285A82804F9
+:1029E000240A234691A986B8AA2AB685A9882784ED
+:1029F0009F25649FD10F00006C100AD6302830103C
+:102A0000292006288CF964829B68980B2A9CF9651A
+:102A1000A1B2022A02580F8489371BE7E8C89164E3
+:102A2000520E2A21020A0C4C65C2588D3019E7E17A
+:102A300074D7052E212365E29E2F929E1AE7DD6F43
+:102A4000F8026002532AA22668A0082C22000ACCB1
+:102A50000C65C2442A929D64A23E9A151FE7D78D49
+:102A600067C1E6C8DD2B620618E7D564B00528808B
+:102A7000217B8B432B200C18E7CF0CBC11A8CC2951
+:102A8000C28679EB460FBE0A2EE2A368E0052F222C
+:102A9000007EF9372CC2859C1864C2332B212F8706
+:102AA000660B7B360B790C6F9D266ED2462C203D33
+:102AB0007BC740CE5560001E2A200CC1B28C205826
+:102AC00010F79A1864A2458D6763FFCFC0C063FFFB
+:102AD000C5D7B063FFD300C0E06000022E60030ED4
+:102AE000DB0C6EB20EDC700CEA11AA6A2AAC20581C
+:102AF0000199D7A0DA20DB70C1C82D212058109190
+:102B00008C268B279A160CBB0C7AB3348F188963EA
+:102B100099F3886298F28E659EF82D60108A189D50
+:102B20001768D729C0D09DA92C22182B22139CAB43
+:102B30009BAA97A58E667E7302600097CF586000AF
+:102B40001FDA208B1658105765A13863FFBDC0816E
+:102B5000C0908F18C0A29AF999FB98FA97F563FF75
+:102B6000D2DB30DA20DC40580FFBC051D6A0C0C009
+:102B70002BA0102CA4039B172C1208022A02066B10
+:102B800002DF702D60038E179D149E100CDD11C0A6
+:102B9000E0AD6D2DDC205801188C148B16ACAC2CDC
+:102BA00064038A268929ABAA0A990C9A26886609A1
+:102BB000094829252507880C98662F2218A7FF2F7A
+:102BC000261863FE96DA20DB30DC40DD5058110514
+:102BD000D2A0D10FC0302C20668961B1CC0C0C473B
+:102BE0002C24666EC6026000D2C03009FD5065D04C
+:102BF000CA8E6764E069647066DB608C18DF70DA27
+:102C0000202D60038E170CDD119E10AD6D2DDC2084
+:102C10001EE78D5800F9232618DA208B16DC402F8A
+:102C20002213DD50B1FF2F2613580F9AD2A0D10FD7
+:102C30000028203D084840658DE76F953EDA308DCD
+:102C4000B56D990C8CA80C8C14CACF7CD32D2AACF2
+:102C500010C090292467090D4764DDC5600092000B
+:102C60002C1208066B022D6C20077F028E17DA20CB
+:102C70009E101EE77458007D63FF9A00C09163FFA9
+:102C8000D1000000655081DA20DB60DC40580FB1D4
+:102C9000C020C0F02FA403D10FDA20C0B658103FD7
+:102CA00063FFE000006F950263FD6CDA20DB30DC2F
+:102CB00040DD50C4E0580F32D2A0D10F8A152B212D
+:102CC00004580ECE232466286010981763FF210055
+:102CD000DA2058103263FFABC858DB30DA20580FC7
+:102CE000162A210265AF9CC09409A9022925026316
+:102CF000FF91DB30DC40DD50C0A32E0A802A24681F
+:102D0000DA20580F1FD2A0D10FC020D10FDA202B0C
+:102D1000200C58104763FF6B6C1004282006C0621B
+:102D2000288CF8658125C050C7DF2B221BC0E12A03
+:102D3000206B29212300A104B099292523B1AA00E1
+:102D4000EC1A0BC4010A0A442A246B04E4390DCCA2
+:102D5000030CBB012B261B64406929200C1BE715C3
+:102D60000C9A110BAA082FA2861BE7136FF90260B9
+:102D700000B60B9B0A2BB2A368B0082C22000BCC28
+:102D80000C65C0A42BA2851DE73664B09B8C2B2458
+:102D900021040DCC029CB08820C0C50888110C8885
+:102DA0000298B1882A08441198B48F3494B79FB51B
+:102DB000C0401EE7082DA2850E9E0825E4CF2DDC1D
+:102DC000282DA68529210209094C68941A689820A3
+:102DD000C9402A210265A00B2A221E2B221D7AB18E
+:102DE0000265A079C020D10F2C212365CFDE6000C1
+:102DF000082E21212D21237EDBD52B221E2F221DE3
+:102E00002525027BF901C0B064BFC413E6E92CB0EC
+:102E10000728B000DA2003880A28824CC0D10B8032
+:102E200000DBA065AFE763FFA62A2C74C0B02C0AB4
+:102E300002580E081CE70C9CA08B2008BB1106BB97
+:102E4000029BA1893499A263FF790000262468DAE5
+:102E500020DB30DC40DD50581063D2A0D10FDA20E7
+:102E60002B200C580FCEC020D10F00006C1006078D
+:102E70003D14C080DC30DB40DA20C047C02123BCD9
+:102E800030032838080842774001B1DD64815A1EBA
+:102E9000E6C519E6C629E67ED30F6DDA050050882F
+:102EA00000308CC0E0C02025A03C14E6C4B6D38F0F
+:102EB000C0C0D00F87142440220F8940941077F7A8
+:102EC00004C081048238C0F10B2810C044C0220421
+:102ED000540104FD3802520102FE3808DD10821C44
+:102EE00007EE100E6E020EDD02242CFEC0E004FE82
+:102EF000380AEE100E88020D88028DAB1EE6B4086B
+:102F0000D8020E880298B0C0E80428100E5E018432
+:102F1000A025A125084411084402052514045511D3
+:102F2000043402C0810E8E3994B18FAA84109FB4EC
+:102F300075660C26A11FC0F2062614600009000069
+:102F400026A120C0F20626140565020F7701078727
+:102F50003905E61007781008660206550295B62571
+:102F6000A1040AE61108581108280208660296B75B
+:102F7000C060644056649053067E11C0F489C288D4
+:102F8000C30B340B96459847994618E69B9F41041E
+:102F900059110E99021FE699020E4708D80298426D
+:102FA0000E99029F40C1E00E990299442FA00CB4E3
+:102FB000380CF91114E6881EE67FA4FFAE992E9214
+:102FC0008526F4CF0E880B289685D10F2BA00C1FD9
+:102FD000E6791CE6800CBE11ACBBAFEE2DE2852677
+:102FE000B4CF0D3D0B2DE685D10FC0800528387874
+:102FF000480263FEA263FE966C1006C0C06570F1C5
+:103000008830C030088714778712C0B0C0A619E690
+:103010006B299022C030CC97C031600003C0B0C093
+:10302000A6C0E0C091C0D4C08225203C0B3F1097C1
+:1030300012831CC0700858010D5D01089738C080CC
+:103040000B9838077710048810086802087702C0C8
+:10305000800D98382D3CFE0888100D9E388D2B0A67
+:10306000EE1008EE0207EE020CB8100FDD02053B71
+:10307000400EDD029D408920043D100899110D99F4
+:10308000022D210409A90208DD119941872A05B9F9
+:10309000100D3D020ABB110DBB02087702974428B0
+:1030A00021258712082814048811071E4007EE10F6
+:1030B0000E990275660926211F0626146000060077
+:1030C0002621200626140868029B47098802984694
+:1030D00029200CD2C0C0800C9E111BE63E1FE63595
+:1030E000AB99AFEE2DE2852894CF0DAD0B2DE68583
+:1030F000D10FDD40C0A6C0B08E51CAE0B2AAB1BBAC
+:103100002DDC108F500E7836981008770C9FD898C9
+:10311000D989538F52991199DB9FDA7E8309B1CCFB
+:10312000255C10C97763FFCF88108D1108E70C97D5
+:1031300051AD8DD7F078DB01B1F79D5397528830B0
+:10314000C030088714088840648ED565BEC963FE08
+:10315000BC0000006C1004D720B03A8820C0308238
+:1031600021CAA0742B1E2972046D080FC980C99151
+:103170008575B133A2527A3B0B742B0863FFE900CB
+:10318000649FECD10FD240D10F0000006C100AD622
+:10319000302E3027D950DA4015E6092430269A150A
+:1031A00029160464E0026493732920062A9CF865BA
+:1031B000A3CE2A2102270A040A0B4C65B3978C3050
+:1031C00074C7052D212365D4A0C0A62B0A032C2289
+:1031D00000580F0B64A3B917E5F78E389A1664E30D
+:1031E000BA2F6027285021C9F37E8311C2B08C20EA
+:1031F0002A200C580F2AD7A0CDA16004A200C2B08B
+:103200008C202A200C580EFED7A064A4862F212ED5
+:103210008B680FBF360FB90C6F9D54296027D5B04E
+:103220006E920528203D7B8F4CDA20DB50C1C42DE7
+:10323000211F580EC48B269A189A1989272AAC3850
+:103240000B990C7A93538963C08099738F62987835
+:103250009F728E659E798D679D7B8C6695759C7A35
+:103260008E687E53026000B18B1465B050600038E8
+:10327000DBF063FFA5008A14C9A92E60030E9B0C26
+:103280006EB2A5DC500CEA11AA6A2AAC285BFFB129
+:10329000D5A063FF93C0E063FFE2DA208B18580EDD
+:1032A0008165A2B163FF9E0000DA20DB308C1558E7
+:1032B0000E29D6A0C0C0C0D12D16042CA403DC70EA
+:1032C000DA20DB60DF502D6003C0E09E109D171EEA
+:1032D000E5D20CDD110D6D082DDC285BFF478E66F5
+:1032E0008F678817AF5FA8A828640375FB01B1EE4C
+:1032F0008A189E669F6789268829AA9909880C9949
+:10330000268E6808084805EE0C28252515E5AC9E94
+:103310006865EECC63FEE6000000C9432F21232B35
+:1033200021212FFC010F0F4F2F25237FBB026003AC
+:10333000142C20668961B1CC0C0C472C24666EC617
+:103340000260022809FD5065D22264E1B62E602792
+:1033500064E1B0DC70DF50DA20DB601EE5C32D6075
+:1033600003C08098100CDD11AD6D2DDC285BFF22B1
+:10337000644181C0442B0A008C202A200C580EA0E6
+:103380000AA70265A00FC0B02C22002A200C580EFC
+:103390009CD7A064AFEFDA20C1BCC1C82D21208F1B
+:1033A000188E268929AFEE9E260E990C0909482908
+:1033B0002525580E64C090C050C0C288609A191E5E
+:1033C000E57FC0A12EE022088F14778704C0810E0C
+:1033D0008938C0800B93102D203C2921200CDC0162
+:1033E00004DB010929140BA8380CA5380D3D401C3D
+:1033F000E5968B2B088810075510085502053302F7
+:103400002821250F154003BB020CBB0207551005F0
+:10341000D3100828140ADD11048811098802053325
+:10342000022921040833029B70C0808A201BE58F8B
+:1034300008AA110BAA029A71C0A1852A93769574E5
+:1034400008931103DD020ADD029D778C63C1DC9CC9
+:10345000738B6298789A799B72232214C0C0B1351D
+:103460002526149C7B9D75937A2B621A9B7C2A627D
+:103470001C9A7D28621D987E25621B957F2362170A
+:103480002376102D62182D76112C62192C76126479
+:10349000E0B98E6077E73DC0FE13E5571DE558C1E2
+:1034A000818A628B630495110E9C4006CC110C55E9
+:1034B00002247615085502C0802D76148D2B2B76AC
+:1034C0001B2A761A28761925761803DD022D761622
+:1034D0006000030000C0FA2E200C19E53E18E53507
+:1034E000A9E90CEE11A8EEC0802DE2852894CF0D3D
+:1034F000FD0B2DE685DA208B198C158D14580D6582
+:10350000D2A0D10FDC70DF50DB602D6C28C0A01E74
+:10351000E5569A10DA205BFE5563FE53002B203DE2
+:103520000B4B4065BC826FE527DA308F556DE90C97
+:103530008EAA0E8E14C9E87EF3162AAC10C090290C
+:103540002467090F4764FC6060015F00C0FA63FFF5
+:1035500085C09163FFE88814658168DA20DB608CA0
+:1035600015580D7CC020C09029A403D10F8A162BBA
+:103570002104580CA2C0A02A24668E6863FDCA00EC
+:10358000002B9CF965B0FDDA20580CA763FC2200E3
+:1035900000DA20C0B6580E0163FFBA002B200C0CD5
+:1035A000BE11A7EE2DE286C1C27DC30260011819CB
+:1035B000E50209B90A2992A36890082A220009AAFB
+:1035C0000C65A10326E2856460FD2C20668931B17B
+:1035D000CC0C0C472C24666FC60270960C8A162BF6
+:1035E0002104580C86C0D02D24668E3077E74D1C00
+:1035F000E5021BE5028F328833C0A42D21040E9909
+:103600004006991104DD1109DD029A61C19009DDBE
+:10361000029B60C0908B2B9D649F66986799650C98
+:10362000BB029B6228200C1AE4EBAA8A0C8811A723
+:10363000882F828529A4CF2FFC202F86858A1465A8
+:10364000A0A6C020D10FB0FC8B142C2523C8B70234
+:103650002A02066B02580CB82A210265AEF7C0D8C0
+:103660000DAD022D250263FEEC008E14C8E8DA20B1
+:10367000DB30580CB12A210265AEDA07AF022F25E4
+:103680000263FED100DA20DB308C158D14580E5504
+:10369000D2A0D10FDA202B200C580DC063FEB6004B
+:1036A000DA202B200C580DE263FEAADA20DB308CE6
+:1036B000152D12042E0A80280A00282468580CB000
+:1036C00063FAE500C020D10FDA20580DB48914CD7B
+:1036D00092DA20DB308C15580D1FDBA0C020C0A073
+:1036E0002AB403D10FC020D10F2A2C748B15580691
+:1036F00028D2A0D10F0000006C100C2821029410D9
+:1037000008084C6583621FE4AB29F29E6F98026043
+:1037100003661DE4A729D2266890082A220009AA78
+:103720000C65A3542CF29D64C34E2B200C0CB611D7
+:10373000AF66286286C1EC78E30260034619E49E16
+:1037400009B90A2992A36890078A2009AA0C65A3DF
+:103750003224628564432CC0E12A3109C0702724D9
+:103760006689359A11992A88369912982B89379843
+:1037700013992C883899140858149815982D89395C
+:103780002A25042E251D29251C283028C0922824EE
+:103790003C2A302908084798160989012A243D2A1D
+:1037A000311599170A094109A90C299CEC29251FF3
+:1037B0007E87192D2A000DA06000083E010A3EB147
+:1037C000AD08DA390EAA110A990C29251F2A211FE2
+:1037D00018E4A80A8160C1D0941A951B01083E0024
+:1037E000053EB184054839843C259CFC0D8836296A
+:1037F000201408AA1C8D3D2726182E26132E2614C9
+:103800002E261527261B2E246B27246727246808BD
+:10381000581C0909432924142932112A252E282548
+:103820002F27252427252527252C27252325252037
+:103830002425212D2522841A2D211C851B6FD202BF
+:10384000600209C0A099186D080AB1AA00A104007D
+:10385000E91A7D9B0263FFEE8918C080C0E1C07049
+:10386000C0D29B1D951B961C9C1E16E4722C203DFD
+:1038700015E4820C0B400DCC010BE7381DE4640A03
+:1038800077100CE8380B8810C0C49C410877029D63
+:1038900040B0A80988118B209C499D48954B9643C0
+:1038A000087702861418E47315E45A08770205BBFA
+:1038B000029B4A9B4297468812871108DA149A4E57
+:1038C0000D88100D77110877021AE44E06D8140DF2
+:1038D0006610087702974FC78F984D984C98458788
+:1038E0001598440715140D55110A5502954715E40E
+:1038F000638A262D46102D46182D46202C46112C65
+:1039000046192C46212B46122B461A2846142846C7
+:10391000152B462288162546242546268B170A0C89
+:1039200048090D4885130EDD1105CC110839400BEF
+:10393000EB390299101EE4520DCC020D5511082DE1
+:10394000400655022E461316E41D0FDD11254616BE
+:10395000080840851B0188100DBB0286671DE449DD
+:103960000988020CBB0219E4191CE4472B46172DE9
+:10397000461BA7661BE446C0702C461C0988028CB7
+:103980001E28461E2B4623C0908B1D29461D294606
+:103990001F18E43F2946272846252931162E2006E0
+:1039A00029246A243117962D242538861CCCE1273A
+:1039B0002407C0D7090E4064E0829A29092841648F
+:1039C000809164409B2D2406C098094936280AA09E
+:1039D00024628501C404A84428210424668508883B
+:1039E000118E3F8A3E2D32100EA41800C4040EAE74
+:1039F0001800EE110ACA530EDD02C0E30E880298C9
+:103A0000C11EE42409084E9EC08E2094C398C59D13
+:103A1000C418E3F01DE42105EE110EAA020DAA025E
+:103A2000A8B82784CF9AC21EE3E224F29D27E4A21D
+:103A3000244C1824F69D655052C020D10F2D240629
+:103A4000C0A0C09809493604A93863FF7FC0A063AD
+:103A5000FE070000654F6DC098C0A82A240663FFCA
+:103A60006B2D2406C09063FF63CC57DA20DB308CCB
+:103A700010580C38C020D10F00DA20C0B6580CC73F
+:103A800063FFE500DA20580CC563FFDC2A2C748B39
+:103A90001058053FD2A0D10F6C10062820068A339B
+:103AA0006F8202600161C05013E3C229210216E354
+:103AB000C1699204252502D9502C20159A2814E3B7
+:103AC000BF8F2627200B0AFE0C0477092B711C647C
+:103AD000E1398E428D436FBC0260016F00E104B09A
+:103AE000C800881A08A80808D80298272B2006685A
+:103AF000B32ECE972B221E2C221D0111027BC90151
+:103B0000C0B064B0172CB00728B000DA2003880AD0
+:103B100028824CC0D10B8000DBA065AFE7C020D16C
+:103B20000F2D206464DFCA8B29C0F10BAB0C66BF7C
+:103B3000C02B200C0CBC11A6CC28C2862E0A0878FB
+:103B4000EB611EE39D0EBE0A2EE2A368E00528226B
+:103B5000007E894F29C2851EE3A96490461FE3B603
+:103B60009E90C084989128200A95930F880298927D
+:103B70008E200FEE029E942F200788262F950A98FC
+:103B8000969A972E200625240768E3432921022AC6
+:103B9000C2851DE3902AAC20ADBD25D4CF2AC685B1
+:103BA00063FF4E002E2065CBEDC082282465C9F648
+:103BB00005E4310002002A62821BE3982941020BCE
+:103BC000AA022A668209E43129210263FF23000048
+:103BD00064DFB88F422E201600F1040DEE0C00EECB
+:103BE0001AAEAE9E2963FFA38A202B3221B1AA9A76
+:103BF000B0293221283223B4992936217989A92B79
+:103C000032222B362163FFA0C020D10F9F2725240D
+:103C100015ACB828751C2B2006C0C12EBCFE64E074
+:103C2000AB68B7772DBCFD65DEC72D2064C0F0649E
+:103C3000D0868E290EAE0C66E089C0F128205A2865
+:103C40008CFE08CF3865FEE863FF580000E004935F
+:103C500010C0810AF30C038339C78F08D80308A862
+:103C60000108F80C080819A83303C80CA8B828756F
+:103C70001C030B472B24158310CBB700E104B0BC09
+:103C800000CC1AACAC0CDC029C27659E5EC0B20B6B
+:103C9000990209094F29250263FE50002D206A0D63
+:103CA0002D4165DF7EDA20C0B0580C8F64AF18C09C
+:103CB000F163FEEF9F2763FFD02E221F65EE326374
+:103CC000FF79000028221F658E2763FF6E252406DA
+:103CD00029210263FE1B00006C10066571332B4C1A
+:103CE00018C0C7293C18C0A1C08009A838080842DC
+:103CF0006481101CE32C1AE32D2AC67E2A5CFDD3B6
+:103D00000F6DAA0500B08800908C8940C0A009887A
+:103D1000471FE355080B47094C50090D5304DD10AC
+:103D2000B4CC04CC100D5D029D310CBB029B3088DD
+:103D3000438E2098350FEE029E328D26D850A6DD98
+:103D40009D268E40C0900E5E5064E0971CE33B1EA3
+:103D5000E32B038B0BC0F49FB19EB02D200A99B3C7
+:103D60000CDD029DB28F200CFF029FB48E262D2009
+:103D7000079EB68C282DB50A9CB72924072F20064C
+:103D80002B206469F339CBB61DE30D2320168DD2A9
+:103D90000B330C00D10400331AB48DA3C393292232
+:103DA000200C13E30C1FE3030C2E11AFEEA322290A
+:103DB00024CF2FE285D2A00FDD0B2DE685D10F0099
+:103DC0002E200CB48C0CEB111FE3031DE2FAAFEEB6
+:103DD000ADBB22B28529E4CF02C20B22B685D2A0A8
+:103DE000D10F00002E200C1CE2F31FE2FA0CEB11A5
+:103DF000AFEEACBB22B28529E4CF02820B22B6859E
+:103E0000D2A0D10FC0D00BAD387DC80263FEEC63E9
+:103E1000FEE08E40272C747BEE12DA70C0B32C3C8F
+:103E200018DD50580A868940C08063FEE3066E02A2
+:103E3000022A02DB30DC40DD505800049A10DB50CF
+:103E4000DA70580453881063FEF700006C10069275
+:103E5000121EE2E48C40AE2D0C8C472E3C1804CA96
+:103E60000BD9A07DA30229ADF875C302600084C000
+:103E7000B0C023C0A09D106D0844B89F0EB80A8D35
+:103E8000900EB70BB8770D6D36ADAA9D800D660C00
+:103E9000D8F000808800708C879068B124B22277B7
+:103EA000D3278891C0D0CB879890279C100070882A
+:103EB00000F08C9D91CB6FC08108BB0375CB36633E
+:103EC000FFB4B1222EEC1863FFD485920D770C86D7
+:103ED000939790A6D67D6B01B1559693959260000D
+:103EE00016B3CC2D9C188810D9D078D3C729DDF80B
+:103EF00063FFC100C0238A421BE2E900CD322D449A
+:103F0000029B3092318942854379A1051EE2E50E7C
+:103F1000550187121BE2D5897095350B99029932AC
+:103F200088420A880C98428676A6A696768F44AF79
+:103F3000AF9F44D10F0000006C10089311D6308859
+:103F400030C0910863510808470598389812282115
+:103F500002293CFD08084C6581656591628A630A07
+:103F60002B5065B18B0A6F142E0AFF7CA60A2C20F9
+:103F70005ACCC42D0A022D245A7FE0026002158912
+:103F80002888261FE2C809880C65820F2E200B0F97
+:103F9000EE0B2DE0FE2EE0FF08DD110EDD021EE22D
+:103FA000C2AEDD1EE2C21CE2C20EDD010DCC37C185
+:103FB00080084837B88DB488981089601AE2807BF1
+:103FC00096218B622AA0219C147BA3179D132A2083
+:103FD0000C8B108C20580BB18C148D13DBA0CEAC45
+:103FE0006001C4002E200C1BE2730CEA110BAA081E
+:103FF0002BA2861FE2717BDB3B0FEF0A2FF2A36837
+:10400000F0052822007F892C2BA28564B0AA876244
+:104010008826DE700C7936097A0C6FAD1C8F279BD1
+:104020001508FF0C77F3197E7B729D139C149B156A
+:10403000CF56600025C0B063FFD0D79063FFDD008E
+:10404000009D139C14DA20DB70580B168B158C1412
+:104050008D1365A06A8E6263FFCC00DA208B11DCC1
+:1040600040580ABCD6A08B15C051DE70DA20DC6047
+:10407000DD405BFF768D138C14D9A02E200C1BE243
+:104080004D1FE2540CEA11AFEFC0E0ABAA2BA285A2
+:104090002EF4CF0B990B29A68563FF1D00DA20DCD7
+:1040A00060DD40DE708912282007DF50A9882824AF
+:1040B000075BFF09D2A0D10F00DBE0DA20580B37F5
+:1040C0006550EF2A20140A3A4065A0EBDB60DC4023
+:1040D000DD30022A025809A7D6A064A0D584A183A6
+:1040E000A00404470305479512036351C05163FEC2
+:1040F0005C2C2006D30F28CCFD6480A568C704C0C3
+:10410000932924062C2006C0B18D641FE22C9D2724
+:104110009D289D298FF29D2600F10400BB1A00F016
+:1041200004B0BE0EDD01C0F0ADBB8D652F24070DC0
+:104130000E5E01EE11AEBB2E0AFEB0BB0B0B190ECC
+:10414000BB36C0E20B0B470EBB372B241618E224FC
+:104150000A09450D0B422B240B29240AB4BE2E2438
+:104160000C7D88572920162FCCFDB09D0A5C520D7E
+:10417000CC362C246465FDEC0C0C4764CDE618E2CB
+:104180000F8E2888820C9F0C00810400FF1AAFEE6E
+:104190009E2963FDCF1CE23E63FE13001CE23563E3
+:1041A000FE0C8D6563FFA500DA202B200C580B2038
+:1041B000645F0FC020D10F00C020D10FC09329240D
+:1041C00016C09363FFA000006C1004C06017E1F8F4
+:1041D0001DE1FBC3812931012A300829240A78A175
+:1041E00008C3B27BA172D260D10FC0C16550512605
+:1041F00025022AD0202F200B290AFB2B20142E2049
+:104200001526241509BB010DFF0928F11C2B2414C8
+:10421000A8EE2EF51C64A0A92B221E28221D011138
+:10422000027B8901DB6064B0172CB00728B000DA8C
+:104230002007880A28824CC0D10B8000DBA065AF24
+:10424000E7DB30DC40DD50DA205800DE29210209AE
+:104250000B4CCAB2D2A0D10F00CC5A2C30087BC173
+:10426000372ED02064E02D022A02033B02DC40DD21
+:10427000505800D4D2A0D10F2B2014B0BB2B241443
+:104280000B0F4164F0797CB7CAC0C10C9C022C258D
+:1042900002D2A0D10FC020D10F2E200669E2C12684
+:1042A00024062B221E2F221D29200B2820150D99B4
+:1042B000092A911C262415AA8828951C7BF149609F
+:1042C0000048B0BB2B24140B0A4164A0627CB702E7
+:1042D0002C25022B221E2C221DD30F7BC901C0B01E
+:1042E000C9B62CB00728B000DA2007880A28824C0B
+:1042F000C0D10B8000DBA065AFE7C020D10F00006C
+:10430000262406D2A0D10F0000DB601DE1AC64BF03
+:104310004F2CB00728B000DA2007880A28824CC04A
+:10432000D10B8000DBA065AFE71DE1A463FF310086
+:1043300026240663FF9C00006C1004282006260A31
+:10434000046F856364502A2920147D9724022A0271
+:10435000DB30DC40DD50580019292102090A4CC825
+:10436000A2C020D10FC0B10B9B022B2502C020D1CF
+:104370000F00022A02033B022C0A015800D1C9AAED
+:10438000DA20DB30DC405809F329A011D3A07E9756
+:10439000082C0AFD0C9C012CA411C0512D201406E0
+:1043A000DD022D241463FFA4DA20DB30DC40DD5075
+:1043B000C0E0580973D2A0D10F0000006C1006169F
+:1043C000E17D1CE17D655157C0E117E179282102AB
+:1043D0002D220008084C6580932B32000B6951296F
+:1043E0009CFD6590872A629E6EA84C2A722668A062
+:1043F000027AD9432A629DCBAD7CBE502B200C0C97
+:10440000BD11A6DD28D2862F4C0478FB160CBF0AFE
+:104410002FF2A368F0052822007F89072DD285D3CB
+:104420000F65D0742A210419E1A3D30F7A9B2EDAE9
+:104430002058086E600035002D21041BE19E7DBBD5
+:1044400024DA20C0B6580869CA546001030B2B5007
+:104450002B240BB4BB0B0B472B240C63FFA0DA20DF
+:10446000580A4E600006DA20C0B6580A4C6550E083
+:10447000DC40DB302D3200022A020D6D515808BDA0
+:104480001CE14ED3A064A0C8C05184A18EA0040436
+:10449000470E0E4763FF3500002B2104C08C893185
+:1044A000C070DF7009F950098F386EB8172C20667C
+:1044B000AECC0C0C472C24667CFB099D105808CF11
+:1044C0008D1027246694D11EE151B8DC9ED0655032
+:1044D00056C0D7B83AC0B1C0F00CBF380F0F42CBAE
+:1044E000F119E13018E13228967EB04BD30F6DBA46
+:1044F0000500A08800C08C2C200CC0201DE1360CCB
+:10450000CF11A6FF2EF285ADCC27C4CF0E4E0B2EB9
+:10451000F685D10FC0800AB83878D0CD63FFC100CE
+:104520008E300E0E4763FEA12A2C742B0A01044D17
+:10453000025808C22F200C12E1270CF911A699A2EB
+:10454000FF27F4CF289285D2A008480B289685D162
+:104550000FC020D10F0000006C1004C060CB55DBF1
+:1045600030DC40055D02022A025BFF94292102092A
+:10457000084CC882D2A0D10F2B2014B0BB2B24141E
+:104580000B0C41CBC57DB7EBC0C10C9C022C2502A6
+:10459000D2A0D10F0000022A02033B02066C02C027
+:1045A000D0C7F72E201428310126250228240A0F0F
+:1045B000EE012E241458010E63FFA300262406D218
+:1045C000A0D10F006C1006282102D62008084C65E7
+:1045D000809D2B200C12E0F70CB811A2882A82864D
+:1045E000B5497A930260009719E0F409B90A299253
+:1045F000A36890082A620009AA0C65A08228828517
+:104600001CE0FF6480799C80B887B14B9B819B1034
+:10461000655074C0A7D970280A01C0D0078D380D25
+:104620000D42CBDE1FE0E01EE0E12EF67ED830D357
+:104630000F6D4A0500808800908C2E3008C0A000C5
+:10464000EE322E740028600C19E0E30C8D11A2DD0F
+:10465000A988C0202CD2852284CFD2A00CBC0B2CE0
+:10466000D685D10FC0F0038F387FA0C063FFB400A0
+:10467000CC582A6C74DB30DC405807F6C020D10FD0
+:10468000DA605809C663FFE7DD402A6C74C0B0DC0D
+:104690007058086A2E30088B1000EE322E740028F5
+:1046A000600C19E0CC0C8D11A2DDA988C0202CD2A1
+:1046B000852284CFD2A00CBC0B2CD685D10F000054
+:1046C0006C1004292014282006B19929241468812B
+:1046D00024C0AF2C0A012B21022C24067BA004C08D
+:1046E000D02D2502022A02033B02044C02C0D058FE
+:1046F00000C0D2A0D10FC020D10F00006C1004293F
+:104700003101C2B429240A2A3011C28378A16C7BFA
+:10471000A1696450472C2006C0686FC562CA572D36
+:1047200020147CD722DA20DB30DC40DD505BFFA593
+:10473000292102090E4CC8E2C020D10FC0F10F9F01
+:10474000022F2502C020D10FDA20DB30C0C05BFF72
+:10475000DC28201406880228241463FFC7292015AA
+:104760001BE0972A200BC0C09C240BAA092BA11C7C
+:104770002C2415AB9929A51C63FF9900C020D10FEB
+:10478000DA20DB30DC40DD50C0E058087DD2A0D11B
+:104790000F0000006C1004CB5513E09225221F0D72
+:1047A000461106550CA32326221E25261F06440B60
+:1047B00024261E734B1DC852D240D10F280A80C038
+:1047C0004024261FA82828261E28261DD240D10FA7
+:1047D000C020D10F244DF824261E63FFD80000000E
+:1047E0006C1004D620282006C0706E85026000D4AC
+:1047F0001DE07919E07112E06F2A8CFC64A1302B66
+:104800006102B44C0B0B4C65B0A22B600C8A600C9F
+:10481000B8110288082E828609B90A7EC302600098
+:104820009A2992A368900509AA0C65A08E28828512
+:10483000648088B8891BE07594819B80655155C060
+:10484000B7B8382A0A01C0C009AC380C0C4264C0A1
+:10485000421FE0541EE0562EF67EB04AD30F6DAADA
+:104860000500808800908CC0A029600C0C9C11A2CF
+:10487000CC2BC285AD990B4B0B2BC6852860062728
+:1048800094CF6881222D6015D2A0C9D2C0E22E64D7
+:1048900006D10F00C0F008AF387FB0BD63FFB10094
+:1048A000276406D2A0D10F00D2A0D10F00CC57DAD6
+:1048B00060DB30DC405808A7C020D10FDA6058090F
+:1048C0003763FFE80028221E29221DD30F789901A3
+:1048D000C080C1D6C1C11BE043C122AB6B64804222
+:1048E00078913F2A80000CAE0C64E0BB02AF0C64F0
+:1048F000F0B52EACEC64E0AF0DAF0C64F0A92EACBB
+:10490000E864E0A32FACE764F09D2EACE664E0978A
+:104910002F800708F80BDA807B83022A8DF8D8A055
+:1049200065AFBC28612308D739D97060007B0000CF
+:104930002B600C0CB811A2882C82862A0A087CAB4A
+:104940007E09BA0A2AA2A368A0052C62007AC96F60
+:104950002A828564A0691FE029276504C0E3C0C4DA
+:104960002E64069CA11CE0549FA02E600A97A30C05
+:10497000EE029EA28F600CFF029FA42E60147AEFBD
+:104980004627A417ADBC2F828527C4CF2FFC202F2C
+:10499000868563FE692A6C74C0B1DC90DD405807DF
+:1049A000A71DE00C63FEC100D9A0DA60DB30C2D0E5
+:1049B000C1E0DC4009DE39DD505807F1D2A0D10F4B
+:1049C000DA605808F663FEE4290A0129A4170DBF2E
+:1049D000082E828527F4CF2EEC202E868564500B7E
+:1049E0002A6C74DB4058016AD2A0D10FC020D10FCD
+:1049F0006C10062B221E28221D93107B8901C0B04B
+:104A0000C0C9C03BC1F20406401DDFF6C0E2C0745D
+:104A10000747010E4E01AD2D9E11C0402E0A1464B1
+:104A2000B06E6D084428221D7B81652AB0007EA1EE
+:104A30003B7FA1477B51207CA14968A91768AA1434
+:104A400073A111C09F79A10CC18B78A107C1AE29B8
+:104A50000A1E29B4007CA12B2AB0070BAB0BDAB0DD
+:104A60007DB3022ABDF8DBA0CAA563FFB428B0104D
+:104A700089116987BB649FB863FFDC00647FB463FE
+:104A8000FFD50000646FD0C041C1AE2AB40063FFFF
+:104A9000C62B2102CEBE2A221D2B221E7AB12A8CC1
+:104AA000107CB1217AB901C0B0C9B913DFC1DA20D5
+:104AB00028B0002CB00703880A28824CC0D10B8094
+:104AC00000DBA065AFE7D240D10F8910659FD463AA
+:104AD000FFF300006C1008C0D0C8598C30292102A7
+:104AE0000C0C4760000C8E300E1E5065E19E292193
+:104AF00002C0C116DFB0090B4C65B0908A300A6E57
+:104B00005168E3026000852F629E1BDFA96EF85397
+:104B10002BB22668B0052E22007BE94727629DB79D
+:104B200048CB7F97102B200CB04E0CBF11A6FF294D
+:104B3000F2869E12798B4117DFA007B70A2772A36E
+:104B4000687004882077893029F285DF90D79065D6
+:104B500090652A210419DFD77A9B22DA205806A310
+:104B6000600029002C21041BDFD37CBB18DA20C095
+:104B7000B658069EC95860014CC09063FFCCDA203D
+:104B8000580886600006DA20C0B65808846551359A
+:104B9000DC40DB308D30DA200D6D515806F6C0D088
+:104BA000D3A064A120292102C05184A18CA00404B7
+:104BB000470C0C4763FF3E00C09C8831DBD008F8EF
+:104BC00050089B3828210498116E8823282066AC51
+:104BD0008C0C0C472C24667CBB159F139E148A10EA
+:104BE0008B115807068E148F13C0D02D24668A307F
+:104BF000C092C1C81BDF867FA6099BF099F12CF4F7
+:104C00000827FC106550A4B83ADF70C051C0800777
+:104C1000583808084264806718DF6319DF64298602
+:104C20007E6A420AD30F6DE90500A08800F08CC0AF
+:104C3000A08930B4E37F9628C0F207E90B2C9408D2
+:104C40009B909F912F200C12DF630CF811A68829EE
+:104C50008285A2FF2DF4CFD2A009330B238685D104
+:104C60000F22200C891218DF5B0C2B11A6BBA82287
+:104C70002D24CF2CB285D2A00C990B29B685D10F4B
+:104C8000C087C0900A593879809663FF8ADB30DA92
+:104C900020C0C1C0D05BFF56292102C0D02A9CFE93
+:104CA00065AE4D2D2502C09063FE45009E142A2C52
+:104CB00074C0B1DC70DD405806E18E14C0D01BDF3B
+:104CC00053C1C863FF6AC020D10F00006C100628D2
+:104CD000210216DF3808084C65821929629E6F98F8
+:104CE0000260022019DF332992266890078A200982
+:104CF000AA0C65A20F27629DC0CC6472072B210409
+:104D00008E31C0A0DDA00EFE500ECD386EB8102C36
+:104D10002066B1CC0C0C472C24667CDB026001EFD2
+:104D2000C0C12930081BDF2564909C2F0AFFC0D327
+:104D3000B09E64E1026892136450882A2C74044B7C
+:104D4000025800930AA20206000000002B200C2744
+:104D500021040CBC11A6CC29C286280A087983023A
+:104D60006001B919DF1509B90A2992A36890082EC4
+:104D7000220009EE0C65E1A42EC28564E19E262086
+:104D80000713DF1E6E7B0260019A17DF151FDF1EFF
+:104D900019DF4BC0D228200A93E09DE1A9690F8852
+:104DA0000298E22F90802A9480B1FF07FF029FE3D0
+:104DB0002EC2851FDF080EDE0BAFBF2AF4CF2EC632
+:104DC00085655F76C020D10F2830102930112E3034
+:104DD0001300993200ED326480EE2A30141FDF3860
+:104DE00000AA3278EF050F9E092DE47F1EDF36669C
+:104DF000A0050F98092A8480B4A718DF33C76F0075
+:104E00009104AE9EDDE000AF1A00C31A6EE1052DDD
+:104E1000B2000DED0C1EDF2D08D81C063303AE8842
+:104E20002A848B2EB02E27848C03EE010FEE022EE7
+:104E3000B42E58018F63FEFF29310829250428303C
+:104E4000142E3109B0886480A32E240AC0812E302C
+:104E5000162CB4232E240BB4EF2F240C8C378B3656
+:104E6000292504DEB0DFC00C8F390B8E390FEE021E
+:104E700064EEC4089F1101C4048D380CB81800C436
+:104E8000040CBE1800EE110EDD02C0E30EFF021E80
+:104E9000DF019F719E701EDF008F2098739D740547
+:104EA000FF110BCD53C18098750FDD020EDD029D01
+:104EB000721EDEBF2A24662F629D2AE4A22FFC18F0
+:104EC0002F669D63FE710000002F30121BDF010072
+:104ED000FA3278FF050B980B2A847F66D0050B9A6F
+:104EE0000B2DA4802A301100AA3263FF442F240A1C
+:104EF0009E2B63FF56CC57DA20DB30DC4058071579
+:104F0000C020D10F00DA20C0B65807A463FFE50027
+:104F1000DA7058063AC0A02A246663FE02DA2058E6
+:104F2000079F63FFCFB16928200A862009094799A6
+:104F30001129240798107F812693E027E50A9AE338
+:104F400088109DE119DEDD8D11096F029FE42DE4CB
+:104F500016098802C0D398E22A240763FE51000094
+:104F60001DDEA60868118F11892B93E008FF02C08F
+:104F70008F9FE50D990299E2047F11C0D49DE1084D
+:104F8000FF029FE463FFD0006C1004C020D10F002B
+:104F90006C100485210D381114DE848622A42408A7
+:104FA000660C962205330B9321743B13C862D230F2
+:104FB000D10FC030BC29992199209322D230D10F32
+:104FC000233DF8932163FFE36C100AD62094181751
+:104FD000DE79D930B83898199914655252C0E1D2A7
+:104FE000E02E61021DDE760E0E4C65E1628F308E82
+:104FF000190F6F512FFCFD65F1558EE129D0230E5D
+:105000008F5077E66B8F181EDEB3B0FF0FF4110FD1
+:105010001F146590CE18DEB08C60A8CCC0B119DE2C
+:105020006428600B09CC0B0D880929811C28811A82
+:105030002A0A0009880C08BA381BDEA60CA90A291E
+:1050400092947B9B0260008C2B600C94160CBD111B
+:10505000A7DD29D286B8487983026000D219DE56CE
+:1050600009B80A2882A398176880026000A360002C
+:10507000A51ADE9A84180AEE01CA981BDE4D8C1917
+:105080002BB0008CC06EB3131DDE4A0C1C520DCC2D
+:105090000B2DC295C0A17EDBAE6000380C0C5360B6
+:1050A000000900000018DE8C8C60A8CCC0B119DEAD
+:1050B0004028600B09CC0B0D880929811C28811A16
+:1050C0002A0A0009880C08BA380CA90A2992947E89
+:1050D000930263FF72DA60C0BA580730645073609D
+:1050E000026600001ADE338C192AA0008CC06EA361
+:1050F0001A18DE2F0C1C5208CC0B18DE762BC2952A
+:10510000C0A178B30263FF3F63FFC9000C0C536377
+:10511000FF09896078991829D285C9922B729E1D42
+:10512000DE246EB8232DD226991369D00B60000DB2
+:10513000DA6058071A6000170088607D890A9A1A99
+:1051400029729D9C129915CF95DA60C0B658071345
+:105150006551F58D148C18DBD08DD0066A020D6D6B
+:1051600051580584D3A09A1464A1DD82A085A1B80A
+:10517000AF9F190505470202479518C05163FE60AD
+:105180002B6104C08C8931C0A009F950098A386E9E
+:10519000B81F2C6066A2CC0C0C472C64667CAB114B
+:1051A0009F119E1B8A155805958E1B8F11C0A02A32
+:1051B00064669F1164F0E12912032812096DF91742
+:1051C0002F810300908DAEFE0080889F9200908C0E
+:1051D000008088B89900908C65514E8A10851A8B92
+:1051E000301FDE06881229600708580A2C82942D89
+:1051F00061040ECC0C2C86946FDB3C1CDE30AC9C26
+:1052000029C0800B5D50A29909094729C48065D047
+:10521000DA2E600CC0D01FDDEF0CE811AFEEA788CE
+:105220002282852DE4CF02420B228685D2A0D10FA7
+:105230008E300E0E4763FDA6A29C0C0C472C640713
+:105240007AB6CD8B602E600A280AFF08E80C6481CC
+:105250000E18DE1983168213B33902330B2C341661
+:105260002D350AC02392319F30C020923308B202FC
+:1052700008E80292349832C0802864072B600CD270
+:10528000A01CDDD40CBE11A7EE2DE285ACBB28B46A
+:10529000CF0D9D0B2DE685D10F8B1888138D30B85F
+:1052A0008C0D8F470D4950B4990499100D0D5F0472
+:1052B000DD1009FF029F800DBB029B8165508D852B
+:1052C0001AB83AC0F1C0800CF83808084264806B04
+:1052D0001BDDB519DDB629B67E8D18B0DD6DDA059A
+:1052E00000A08800C08CC0A063FEF30082138B1660
+:1052F0001DDDC628600AC0E02EC4800D880202B2FF
+:105300000B99239F20C0D298229D2122600CB2BB12
+:105310000C2D11A7DD28D28508BB0B18DDAE2BD6CE
+:1053200085A8222E24CFD2A0D10F9E1B851A2A6CCD
+:10533000748B185BFF178E1B63FEA300C087C090A1
+:105340000AF93879809263FF86C020D10F9E1B2A0C
+:105350006C74C0B18D185805398E1B851A63FE7E9A
+:10536000886B8213891608BE110ECE0202920B9E24
+:1053700025B4991EDDA19F200E88029822C0EF045B
+:10538000D8110E88029824C0E49E21C080D2A02BA0
+:10539000600C2864071CDD8F0CBE11A7EE2DE28582
+:1053A000ACBB28B4CF0D9D0B2DE685D10F000000BE
+:1053B0006C1004C020D10F006C10048633C071C083
+:1053C00030600001B13300310400741A04620174CA
+:1053D00060F1D10F6C1004022A02033B025BFFF65E
+:1053E0001CDD771BDDBFC79F88B009A903098A01AF
+:1053F0009AB079801EC0F00FE4311DDD6E0002000E
+:105400002BD2821EDDB82AC1020EBB022BD6820A25
+:10541000E431D10F28C102C19009880208084F2841
+:10542000C50208E431D10F006C1004C0C00CE43197
+:1054300012DD631ADD6000020029A28218DDAC1BB8
+:10544000DDAA2621020B990108660129A6822625DC
+:105450000206E43114DDA715DDA2236A902326128B
+:105460008550242611252613222C40D10F00000040
+:105470006C1008D6102B0A64291AB41ADD4D0D23BE
+:10548000111CDD4E0F2511B81898130E551118DD9B
+:1054900099AC55A838AA332C80FF2A80FEA933285E
+:1054A0008D0129800108AA112880000CAA02088811
+:1054B0001109880208AA1C288C08281604580862BA
+:1054C00014DD3F0AA7022441162A30802B1204075C
+:1054D000AA2858085DB1338B13B4559A6004AC28E0
+:1054E000B4662C56277B69E016DD769412C050C056
+:1054F000D017DD329D15D370D4102F60802E6082BE
+:105500009F169E17881672891A8D128C402A607F0A
+:105510000DCC282B3A200CAA2858084BC0B10ABE43
+:10552000372E35408F1772F91A8D128C402A608100
+:105530000DCC282B3A200CAA28580843C0B10ABE2B
+:10554000372E3542B233B444B1556952B6B466C051
+:10555000508F15B877D370B2FF9F156EF899D10FA1
+:105560006C1004C021D10F006C1004270A001CDD50
+:10557000111FDD221EDD251DDD0E1ADD501BDD5E37
+:10558000C02824B0006D2A75AA48288080C0916484
+:10559000806100410415DD09C03125502E00361A06
+:1055A0000655010595390C56110C66082962966E50
+:1055B000974D0D590A29922468900812DD42024243
+:1055C0000872993B23629512DD06CB349F3002822C
+:1055D000020E4402C092993194329233AD52246249
+:1055E00095C090244C1024669524B0002924A0AACC
+:1055F00042292480B177B14404044224B400D10F7D
+:10560000D10FD10F6C10041ADCEA2AA00058021C3A
+:105610005BFFD5022A02033B025BFFD11BDCE8C91A
+:10562000A12CB102C0D40DCC020C0C4F2CB5020C35
+:10563000E431D10FC0A00AE43118DCDE0002002FF3
+:10564000828219DCF12EB10209FF022F86820EE45C
+:1056500031D10F006C1004C02002E43114DCD816E4
+:10566000DCD5000200226282234102732F0603E48C
+:1056700031C020D10F19DD221ADD212841020A2A6A
+:10568000010988012A668228450208E43115DD18DF
+:1056900012DD1D25461DD10F6C1004292006289C03
+:1056A000F96480A02A9CFD65A0968A288D262F0A81
+:1056B000087AD9042B221FC8BD2C206464C0812E17
+:1056C00022090EAE0C66E0782B200C1EDCBA0CBC56
+:1056D00011AECC28C28619DCB878F3026000AD099F
+:1056E000B90A2992A36890082E220009EE0C65E001
+:1056F0009B29C2851FDCC26490929F90C0E41FDC8E
+:10570000CE9E9128200AC0E09E930F88029892882E
+:10571000200F880298942F20079A979D962F950A1C
+:105720002E240728200629206468833328C2851286
+:10573000DCA9288C20A2B22E24CF28C685C020D177
+:105740000FC020D10F2A206A0111020A2A4165AF39
+:1057500052DA20C0B05805E464AFE5C021D10F0093
+:10576000649FC81FDC962D20168FF209DD0C00F116
+:105770000400DD1AADAD9D2912DC9728C285A2B2C6
+:105780002E24CF288C2028C685C020D10FC021D13F
+:105790000F0000006C1004260A001BDCDB15DC8700
+:1057A00028206517DC84288CFE6480940C4D110D34
+:1057B000BD082CD2F52BD2F42ED2F77CB13DB4BB70
+:1057C0002BD6F47BE9052BD2F62BD6F47CB92C2A08
+:1057D000D2F62AD6F52AD6F406E431000200287261
+:1057E000822AFAFF004104290A012F510200991A66
+:1057F0000A99030988012876820FE4312624652B53
+:10580000D2F48E5A2CD2F5B0EE9E5A7BCB1629D20A
+:10581000F62FD2F70CB80C09FF0C08FF0C0F2F1451
+:10582000C8F96000320BCA0C0A2A14CEA92B510207
+:10583000C0C20CBB020B0B4F2B55020BE431D10F36
+:1058400000DB30DA205BFF941BDCB064AF5D0C4DF5
+:1058500011ADBD63FFA8000006E4310002002F7205
+:105860008218DC6E2E510208FF022F76820EE43180
+:10587000D10F00006C1004C03003E43116DC4E156B
+:10588000DC4F00020024628274472118DCA0875A92
+:10589000084801286682CD7319DC9E0C2A11AA994A
+:1058A0002292832992847291038220CC292B510267
+:1058B0000BE431C020D10F001FDC972E51020FEEF8
+:1058C000012E55020EE431B02DB17C9C5A12DC92AF
+:1058D00008DD112D5619D10F6C10061BDC351EDCAE
+:1058E0003722B0001ADC8E6F23721DDC75C0481899
+:1058F000DC8D1FDC8BDC10D5C083F000808600506F
+:105900008A6D4A4F0F35110D34092440800B560A19
+:10591000296294B1330E55092251400F44110C44B1
+:105920000A874009A80C02883622514107883608A8
+:10593000770CA8992966949740296295874109A810
+:105940000C02883607883608770CA899296695973F
+:1059500041030342B13808084298F0D10F1CDC72B1
+:1059600013DC7327B0002332B5647057C091C0D0E8
+:1059700016DC7115DC6FC0402AC00003884328C4C0
+:10598000006D793C004104B14400971A7780148E71
+:10599000502FB2952DB695AFEE2EED2006EE369E29
+:1059A0005060001877A00983509D5023B695600081
+:1059B0000223B295223D2006223622B695B455B870
+:1059C000BBD10F0003884328C400D10F6C1004C062
+:1059D0004004E43115DC59000200885013DC58CB38
+:1059E000815BFFBD1CDC570C2D11ADCC2BC2822A74
+:1059F000C28394507BAB142EC28429C2850ABD0C8D
+:105A00000E990C0D990C0929146000050BA90C09BD
+:105A10002914993015DBEA2A51020AE4312A2CFCB8
+:105A200058004B2B32000AA2022BBCFF9B30CCB695
+:105A3000C8A4D2A0D10F000004E4311EDBDE0002B6
+:105A4000002DE2822FBAFF2C51020FDD012DE682DC
+:105A50000CE431D10F0000006C1004D10F000000E5
+:105A60006C1004C020D10F006C100413DC36C0D1C0
+:105A700003230923318DC0A06F340260008D19DB30
+:105A8000CD1BDBCE17DC2F0C2811A87726728325BF
+:105A900072822CFAFF76514788502E7285255C045D
+:105AA00025768275E9052572842576827659292E18
+:105AB00072842E76822E76830AE4310002002392CD
+:105AC000820021042FB10200D61A0C6603063301AE
+:105AD0002396820FE43126728325728260000200D1
+:105AE000D8A07659220AE4310002002392820021D4
+:105AF0000400D21A2FB1020C220302320122968234
+:105B00000FE431D280D10F00D280D10FC020D10F4D
+:105B10006C1004DB30862015DBA6280A002825023D
+:105B2000DA2028B0002CB00705880A28824C2D0AFC
+:105B3000010B8000DBA065AFE61ADB9F0A4A0A2949
+:105B4000A2A3C7BF769101D10F2BA6A3D10F00004E
+:105B50006C1004C0D1C7CF1BDB9919DB9617DB94FF
+:105B60000C2811A87786758574C0A076516288507C
+:105B70008E77B455957475E90385769574765927B3
+:105B80008F769F759F740AE431000200239282B4DD
+:105B90002E2FB10200E10400D61A0C660306330171
+:105BA0002396820FE431867583747639280AE431AE
+:105BB0000002002E9282B42200210424B10200DFF0
+:105BC0001A0CFF030FEE012E968204E431D280D12D
+:105BD0000FD8A07651D6D280D10F00006C100429C6
+:105BE0000A801EDB9A1FDB9A1CDB730C2B11ACBBEB
+:105BF0002C2CFC2DB2850FCC029ED19CD0C051C064
+:105C00007013DB9614DB9518DB932AB285A8280461
+:105C1000240A234691A986B8AA2AB685A98827848A
+:105C20009F25649FD10F00006C100419DBC70C2A5C
+:105C300011A9A98990C484798B761BDBB5ABAC2AFA
+:105C4000C2832CC2847AC1688AA02BBC30D3A064E2
+:105C5000A05E0B2B0A2CB2A319DB7F68C0071DDBEB
+:105C6000BBD30F7DC94AA929299D0129901F68919D
+:105C70003270A603D3A0CA9E689210C7AF2AB6A3FB
+:105C80002A2CFC5BFFB3D230D10F000013DBB10331
+:105C9000A3018C311DDB510C8C140DCC012CB6A34F
+:105CA00063FFDC00C020D10FDA205BFFCCC020D125
+:105CB0000FC020D10F0000006C1004DB30C0D019E1
+:105CC000DB3CDA2028300022300708481209880A15
+:105CD00028824CDC200B80001BDB370C4A11ABAA5E
+:105CE00029A28409290B29A684D10F006C1004C0B5
+:105CF0004118DB3017DB320C2611A727277030A89C
+:105D000066256286007104A35500441A7541482235
+:105D1000628415DB5202320BC922882117DB2F085F
+:105D20008414074401754905C834C020D10FD10F30
+:105D30000809471DDB86C0B28E201FDB1D0E0E43F7
+:105D4000AFEC2BC4A00FEE0A2DE6242A6284C020FB
+:105D50000A990B296684D10FC020D10F6C1004DB87
+:105D600030C0D018DB13DA20253000223007085865
+:105D70000A28824CDC200B80008931709E121BDBCC
+:105D80000D0C4A11ABAA29A28409290B29A684D19A
+:105D90000F09C95268532600910418DB08C0A12FCF
+:105DA000811200AA1A0AFF022F85121EDB020C4D77
+:105DB00011AEDD2CD2840C2C0B2CD684D10FC081DB
+:105DC0001FDAFFB89A0A0A472EF11200A1040088D0
+:105DD0001A08EE022EF5121DDAF70C4C11ADCC2B81
+:105DE000C2840B2B0B2BC684D10F00006C1004DB7C
+:105DF00030C0D019DAEFDA202830002230070988C5
+:105E00000A28824CDC200B80001CDAEA0C4B11AC17
+:105E1000BB2AB2840A2A0B2AB684D10F6C1004C0A4
+:105E20004118DAE416DAE60C2711A626266030A817
+:105E300072252286006104A35500441A7541082288
+:105E4000228402320BD10F00C020D10F6C10041538
+:105E5000DB410249142956112452120208430F88CB
+:105E600011C07300810400361A008104C78F0077C7
+:105E70001A087703074401064402245612D10F0082
+:105E80006C10066E23026000AC6420A7C0A08510D1
+:105E900013DB1916DB30C040A6AA2BA2AE0B1941AA
+:105EA00064906668915D68925268933C2AA2AA2821
+:105EB0003C7F288C7F0A0A4D2980012880002AAC6B
+:105EC000F20888110988027589462B3D0129B00026
+:105ED0002BB0010899110B99027A9934B8332A2A08
+:105EE00000B1447249B160004A7FBF0715DB1B63F4
+:105EF000FFB90000253AE863FFB10000253AE863E6
+:105F0000FFA90000250A6463FFA1C05A63FF9C003B
+:105F100000705F082534FF058C142C34FE70AF0B25
+:105F20000A8D142E3D012AE4012DE400DA405BFDC8
+:105F30005063FFA7D10FD10F6C10041ADAA019DA41
+:105F40009D1CDB061BDB07C080C07160000D0000DC
+:105F50000022A430B1AA299C107B915F26928679F9
+:105F6000C2156E6262C0206D080AB12200210400D1
+:105F7000741A764BDB63FFEE2292850D63110325C5
+:105F800014645FCFD650032D436DD9039820B422FB
+:105F90000644146D49229820982198229823982429
+:105FA00098259826982798289829982A982B982CED
+:105FB000982D982E982F222C4063FF971EDA7E276B
+:105FC000E68027E681D10F00C02063FF8300000038
+:105FD0006C1004C062C04112DA791ADA7513DAE182
+:105FE0002AA00023322D19DADB2BACFE2992AE6EEB
+:105FF000A30260008E090E402D1AC2C2CD0EDC39FC
+:106000002C251664B0895BFF9E15DAD71ADAD12BDE
+:106010003AE80A3A0158058C2B21160ABB28D3A06E
+:106020009B505805A32B52000ABB082A0A005805AA
+:10603000A215DACE2D21022C3AE80C3C2804DD0210
+:106040002D25029C5058059A8B50AABBC0A158051B
+:106050009A1CDAC72D21020C3C2806DD0213DAC592
+:106060002D25029C305805928B30AABBC0A2580542
+:10607000922A2102C0B40BAA020A0A4F2A2502580A
+:1060800005A6D10F242423C3CC2C251663FF76004C
+:1060900018DABD1CDAB919DABA1BDAB817DA8B8547
+:1060A000202E0AFD1FDAB92D202E24F47A24F47E46
+:1060B00024F4820EDD0124F4862E0AF70755280603
+:1060C000DD02C0750EDD01050506AB5BA959C0E810
+:1060D000AC5C24C4AB0EDD0227C4AC2E0ADFA8558D
+:1060E00027B4EC0EDD0124B4EBC2E027942C0EDDC6
+:1060F0000224942B2E0A800D0D4627546C24546BD9
+:106100000EDD022D242E63FEFC0000006C10042A1C
+:106110000A302B0A035BFF4D12DA8FC39029261633
+:10612000C3A1C0B3C08A2826175BFF48C03CC3B1D7
+:106130002B26161ADA222AA02023261764A079C358
+:10614000A2C0B15BFF42C3A2C0B15BFF40C3C22C7F
+:106150002616C2AFC0B12326175BFF3CC28F28268C
+:1061600016C0FE2F2617C2E22E26162A0AA1C0B19B
+:10617000C0D82D26175BFF352A0AA12A2616C3A6EA
+:10618000C0B3C1922926175BFF31C3C62C2616C1A6
+:10619000B32A0AA22B2617C0B35BFF2C290AA22917
+:1061A0002616C185282617C2FB2F2616C0E72E26E5
+:1061B000171DDA762D2610D10FC3A2C0B35BFF23C3
+:1061C00063FF82006C10041CDA3F1BDA2C18DA70B3
+:1061D00017DA7116DA7115DA71C0E0C0D414DA3B3F
+:1061E0001FD9F7C0288FF06D2A36DAC0D9C07C5B82
+:1061F000020FC90C1CDA350C9C28A8C3A6C22A368B
+:10620000802A2584A4C2A7CC2D248C2B248A2B245D
+:10621000872E248BB1BB2E369F2C369E2C369DB1FB
+:10622000AC1CDA161BDA5FC0286D2A33DAC0D9C07D
+:106230007C5B020FC90C1CDA240C9C28A8C3A6C2E4
+:106240002A36802B2584A4C2B1BBA7CC2D248C2E4A
+:10625000248B2A248A2E369F2C369E2C369DB1AC58
+:10626000C07919DA141BDA5113DA4F1ADA4F18DA37
+:106270005014DA1516DA5004F42812DA4F04660CBA
+:10628000040506A252A858AA5AA3539B3029A50078
+:1062900027848AC091C0A52A848C29848B17DA4868
+:1062A00018DA47A75726361D26361E2E361F16DA51
+:1062B0004513DA45A65504330C2826C82E75002D43
+:1062C00054AC2E54AB2E54AA2326E62326E52E26C4
+:1062D000E7D10F006C100613DA2317DA1E24723D83
+:1062E0002232937F2F0B6D08052832937F8F026334
+:1062F000FFF3C0C4C0B01AD9B1C051D94004593954
+:1063000029A4206E44020BB502C3281ED9ACDDB00F
+:1063100025E422052D392DE421C0501EDA2C19DA8E
+:106320001C18DA1C16DA1E1DDA2A94102A72451778
+:10633000D9E76DA94BD450B3557A5B17DF50756B15
+:10634000071FD99E8FF00F5F0C12D9DF02F228AE23
+:106350002222D681D54013D9DC746B0715D99885D4
+:106360005005450C035328B145A73FA832A9332255
+:10637000369D22369E2436802B369F2BF48B2CF4B0
+:106380008C14D9F824424DC030041414C84C6D0844
+:1063900006B133041414C84263FFF20015D985C452
+:1063A000400031041AD986C0D193A200DD1AC13849
+:1063B000B0DD9DA318D9EC2B824D29824E29A51C56
+:1063C0002882537A871E2C54008E106FE45D12D9F8
+:1063D0007B2F211D23211C2F251B04330C23251C5F
+:1063E00023251AD10FC06218D9DB88807E87D9890E
+:1063F000102654006F94191BD9712AB11C0A1A1463
+:1064000004AA0C2AB51C2AB51D2AB51A2AB51BD117
+:106410000F1BD96A2AB11C0A1A1403AA0C2AB51C2C
+:106420002AB51D2AB51A2AB51BD10F001CD9642B19
+:10643000C11D2DC11C2BC51B03DD0C2DC51C2DC57D
+:106440001AD10F006C100619D95D14D9C212D9C522
+:1064500015D9E0C73FC0E02E56A82E56A92E56AA41
+:106460002E56AB23262918D985DB101CD9DAC0D4C7
+:106470002A42452D16019C1000B0890A880C2896E6
+:10648000005BFF942B22E318D94D0B5B149B842AED
+:1064900022E48B84B1AA0A5A140BAA0C9A852922E9
+:1064A000E509591499862F22CD0F5F149F875BFF52
+:1064B000455BFF1623463BC1B01DD9401CD99E2A1F
+:1064C000D1022C463A0BAA020A0A4F2AD5025804D6
+:1064D000925BFEBF5BFE98C050C0B016D93614D98F
+:1064E0003E17D9AEC0C0C73E93122C262DC03060D7
+:1064F00000440000007F9F0FB155091914659FF4F7
+:10650000C0500AA9027FA7EF18D92ADA5008580A02
+:1065100028822C2B0A000B8000005104D2A0C091CD
+:10652000C7AF00991A0A99039912CE3864206BD329
+:10653000202B20072516032C12022A62827CA863D6
+:1065400018D91C01110208580A28822CDA500B8035
+:1065500000D2A0643FD58A310A8A1404AA01C82A4D
+:106560002B22010B8B1404BB017BA945DDA07A7B98
+:10657000081DD9122DD2000DAD0CDB3019D90D1A22
+:10658000D95288130ADA28DC801DD99009880A2894
+:10659000823C0DAA080B8000652F93D320C0B06306
+:1065A000FF9400007FAF34B1550050040A0919630D
+:1065B000FF42DAB07B7B081AD9012AA2000ABA0C82
+:1065C0001BD9428C310BAB280C8A141CD980ACBB74
+:1065D0001CD98004AA012BC68163FF8F645F60C051
+:1065E00050C0B0C7CE9C1263FF5500006C1004274A
+:1065F000221EC08008E4311BD8EF0002002AB282BC
+:1066000019D8EF003104C06100661A2991020A6AA4
+:10661000022AB68209E43115D94A0C3811A8532848
+:1066200032822432842A8CFC7841102921022A36B5
+:106630008297A0096902292502D10F002B21022C83
+:1066400032850B6B022CCCFC2C368297C02B25029A
+:10665000D10F00006C1004C0E71DD8D21CD8D40D97
+:106660004911D7208B228A200B4B0BD2A007A80CF4
+:106670009B72288CF4C8346F8E026000A31FD8CAA6
+:10668000A298AF7B78B334C93DC081C0F0028F3887
+:106690000F0F42C9FA2CD67ED5206D4A05003088EE
+:1066A00000508C887008980878B16DD2A09870D18D
+:1066B0000FC0F0038F387FE0DE63FFD8027B0CAFA2
+:1066C000BB0B990C643047D830C0F1C05002F5388C
+:1066D0000505426450792CD67E0B36122F6C100FB4
+:1066E0004F366DFA0500808800208C06440CC0816E
+:1066F000C05003B208237C0C038538050542645062
+:106700005A2CD67ED30F6D4A0500208800308CD2DB
+:10671000A0A798BC889870D10FD2A0BC799970D1ED
+:106720000FD2302BAD08C0F1C0500BF53805054233
+:10673000CB542CD67E083F14260A100F660C064652
+:10674000366D6A0500208800B08C827063FF2D00D2
+:10675000C05003F53875E08063FF7A00C0600286A0
+:106760003876E09F63FF9900C05003F53875E0C4A8
+:1067700063FFBE006C1004D62068520F695324DA00
+:1067800020DB30DC405800F3D2A0D10FDA20DB3020
+:10679000DC405800F09A2424240EC02122640FC04B
+:1067A00020D10F00B83BB04C2A2C7489242D200E28
+:1067B0002E200FA4DDB1EE2E240FB0DD2D240E28E7
+:1067C00090072D9003A488B088B1DD2D9403289400
+:1067D000075BFFA069511DC0E082242A600F18D812
+:1067E000FE2A240329600E8F2029240708FF029F18
+:1067F000209E64D10FC020D10F0000006C100494C3
+:106800002319D8F6C0B3083A110BAA02992019D857
+:10681000699A2116D867C05028929D2564A2288CB9
+:106820001828969DD10F00006C1004282066C038EF
+:10683000232406B788282466D10F00006C100603B5
+:106840005A0C0D36110D5C11D8208B2282210CBB05
+:106850000C06550F9B8202320B928113D853D9201C
+:10686000A38F6450561CD84FC0D71BD850A256C017
+:10687000E1C09004E93809094276F34F044302CAA3
+:10688000912BC67ED30F6DAA0500208800308C891D
+:1068900081A95909FA0C64A07D99818A8264A00FAC
+:1068A000D290D10FC06002E63876D0D763FFD10016
+:1068B000C020BC89998199809282D10F7F230429BD
+:1068C0002DF8998165BFD863FFE50000028F0CA306
+:1068D000FF0F3312931003AA0CD3406490402BC6D1
+:1068E0007E8610D30F6D6A0500208800308CBC8234
+:1068F000C090A4F3C041034938090942CA9B2BC682
+:106900007E6DAA0500208800308C0F590CA989BC27
+:1069100099998163FF8400BC89998163FF7C00C0E1
+:106920006002E63876D0B963FFB300C07002473822
+:1069300077D0CD63FFC700006C100414D82AC15271
+:10694000A424CA3128221D73811C292102659016B6
+:106950002A300075A912022A02033B022C3007C01C
+:10696000D25801D0653FDCD10F2B300703BB0B0B96
+:10697000BA0274B3022ABDF8D3A063FFC4000000BA
+:106980006C1004292006C0706E9741292102C08F27
+:106990002A2014C0B62B240606AA022A24147980C1
+:1069A000022725022A221E2C221D7AC10EC8ABDA2C
+:1069B00020DB302C0A00033D025BF80D6450742D7F
+:1069C00021020D0D4CC9D3C020D10F00002E9CFB1D
+:1069D00064E0822F21020F0F4C65F0911AD7F61C4C
+:1069E000D7F429A29EC08A798B5D2BC22668B00499
+:1069F0008D207BD95229A29DC0F364904A97901DA7
+:106A0000D8062E21049D9608EE110FEE029E979E49
+:106A10009118D802C0E527C4A22E24062BA29D2FD0
+:106A200021022BBC3008FF022F25022BA69DC0207F
+:106A3000D10F00002F300068F939DA20DB30044C28
+:106A40000258004463FF7700022A022B0A0658000E
+:106A5000D3220A00D10F6550102830006889240223
+:106A60002A02033B02DC4058003BC020D10FD27009
+:106A7000D10F00002A2C74033B02044C025BFEF58C
+:106A800063FF3B00DB30DC402A2C745BFEF2C0204D
+:106A9000D10F00006C1004C83F89268829A399995A
+:106AA0002609880C080848282525CC52C020D10F7B
+:106AB000DB402A2C745BF936D2A0D10F6C1004D8BD
+:106AC00020D73082220D451105220C928264207459
+:106AD00007420B13D7B5D420A383732302242DF8C8
+:106AE000858074514CBC82C0906D081600408800AF
+:106AF000708C773903D720C0918680743901D420F7
+:106B000074610263FFE2CA98C097C0411BD835C0C8
+:106B1000A00B8B0C0B4A380A0A42C9AA1DD7A21C2B
+:106B2000D7A32CD67EC140D30F6D4A050020880024
+:106B3000308C9780D270D10FBC8FC0E00F4E387E62
+:106B400090E263FFD6BC8292819280C0209282D173
+:106B50000F0000006C1006C0D71CD7921BD7940DF5
+:106B60004911D7202E221F28221D0E4E0BD280073E
+:106B70008A0C2E761F2AAC80C8346FAE026000CB20
+:106B80002F0A801AD798A29EAA7A7EA33FC93FC037
+:106B9000E1C05002E538050542CA552BC67EDB2010
+:106BA000D30F6D4A0500308800B08C2E721DAE9E4A
+:106BB0000EA50C645086D2802E761DC091298403C8
+:106BC000D10FC05003E53875D0D363FFCD15D785FD
+:106BD000027E0CA5EE643051C0A1250A0002A53842
+:106BE000033A020505426450922BC67E0E3512957B
+:106BF00010255C10054536D30F6D5A0500A088009E
+:106C0000208CC0A1A3E2C05023FA8003730C03A51B
+:106C100038AF730505426450722BC67E851005455A
+:106C20000C6D5A0500208800308CD280C0A10E9BCC
+:106C30000CAB7BAFBB2B761D2A8403D10FD280C057
+:106C4000C1AF7D2D761D2C8403D10F00D2302E8D47
+:106C500008C0F1C0500EF538050542CB592BC67E51
+:106C60000A3F14C1600F660C064636D30F6D6A05E5
+:106C700000208800E08C22721D63FF03C061C050B9
+:106C800003653875D80263FF6263FF5CC05002A5DC
+:106C90003875D08763FF8100C06003F63876D0BFB7
+:106CA00063FFB9006C10042A201529201614D7435D
+:106CB0000A990CCB9D2E200B04ED092BD11C8F289B
+:106CC00009BC36ACAA0CBB0C2BD51C0A0A472A24DB
+:106CD00015CAAF8B438942B0A800910400881AA856
+:106CE000FF0FBB029B278F260FB80C783B1AC020E2
+:106CF000D10F0000292102C0A20A9902292502C051
+:106D000021D10F008B2763FFDC2BD11C0CAA0C0AAE
+:106D10000A472A2415ACBB2BD51CC9AE8B438C2843
+:106D20008F42B0AD00F10400DD1AADCC0CBB029B6C
+:106D300027DA20B7EB580019C021D10F9F2763FF36
+:106D4000EF0000006C100428203C643047053060E0
+:106D500000073E01053EB156076539054928C77F42
+:106D6000A933030641076603B166060641A6337ED2
+:106D7000871E222125291AFC732B1502380C098144
+:106D80006000063E01023EB12406423903220AD1C8
+:106D90000FD230D10FC05163FFC000006C10042728
+:106DA000221EC08008E4311DD7030002002CD282CD
+:106DB0001BD703003104C06100661A2BB1020C6CB2
+:106DC000022CD6820BE43119D7870C3A11AA9328EA
+:106DD00032829780253282243284B45525368275DA
+:106DE000410A292102096902292502D10F2A21021B
+:106DF0002B32830A6A022B36822A2502D10F000029
+:106E00006C100418D6EC0C2711087708267286251A
+:106E10003C04765B1315D6E805220A2222A36820DB
+:106E200002742904227285D10FC020D10F00000006
+:106E30006C100419D6EB27221EC08009770208E4E3
+:106E4000311DD6DC0002002CD2821BD6DC003104BE
+:106E5000C06100661A2BB1020C6C022CD6820BE4C6
+:106E60003119D7600C3A11AA9328328297802532C3
+:106E700082243284B45525368275410B2A21020AB8
+:106E80006A022A2502D10F002B21022C32830B6BC0
+:106E9000022C36822B2502D10F0000006C10041B3F
+:106EA000D6C50C2A11ABAA29A286B438798B221B2D
+:106EB000D6C219D6E80B2B0A2BB2A309290868B051
+:106EC0000274B90D299D0129901F6E920822A28596
+:106ED000D10FC020D10FC892C020D10FDA205BEEB5
+:106EE000B3C020D10F0000006C100414D6B22842A9
+:106EF0009E19D6AF6F88026000BA29922668900763
+:106F00008A2009AA0C65A0AC2A429DC0DC64A0A41A
+:106F10002B200C19D6A90CBC11A4CC2EC28609B901
+:106F20000A7ED30260009A2992A36890078D2009F7
+:106F3000DD0C65D08C25C2856450862D2104C030BF
+:106F40006ED80D2C2066B8CC0C0C472C246665C07E
+:106F50007B1CD72518D6AF1AD6A619D6B61DD6AB28
+:106F6000C0E49E519D508F209357935599539A5644
+:106F70009A5408FF021AD6C29F5288269F5A9E59D9
+:106F80009D58935E9C5D935C9A5B08084805881148
+:106F9000985FC0D81FD6900CB911A499289285AFDC
+:106FA000BF23F4CF288C402896858E262D24069E5C
+:106FB00029C020D10FCA33DA20C0B65BFF78C72FB3
+:106FC000D10FC93ADA205BFF75C72FD10FDBD05B39
+:106FD000FE0B2324662B200C63FF7500C72FD10FF7
+:106FE000C72FD10F6C1004C85B29200668941C6859
+:106FF0009607C020D10FC020D10FDA20DB30DC4053
+:10700000DD502E0A005BFE5ED2A0D10F2E200C18A0
+:10701000D6690CEF11A8FF29F286C088798B791AFE
+:10702000D6660AEA0A2AA2A368A0048B207AB96865
+:1070300023F2856430621BD670290A802C206828D0
+:1070400020672D21040B881104DD1108DD020DCC11
+:1070500002C0842D4A100DCC021DD66898319D3097
+:107060008A2B99379C340BAA02C0C09C359C369A57
+:10707000322A2C74DB4028F285C0D3288C2028F6D5
+:10708000852C25042D24061FD653DD40AFEE2CE4BD
+:10709000CF5BFDEAD2A0D10F00DA20DBE05BFF3F3F
+:1070A000C020D10F6C100AD6302A200624160128E1
+:1070B000ACF86583862B2122C0F22A2124CC572AE2
+:1070C000AC010A0A4F2A25247ABB0260037F2C21D7
+:1070D000020C0C4C65C3192E22158D32C0910EDDA9
+:1070E0000C65D39088381ED63364836B8C37C0B858
+:1070F000C0960CB9399914B49A9A120D9911991332
+:107100008F6718D62EC9FB2880217F83168B142CFD
+:1071100022002A200C5BFF61D4A064A3B38F6760B8
+:10712000002800002B200C89120CBA11AEAA2CA248
+:10713000861DD6217C9B3E0DBD0A2DD2A368D004AE
+:1071400088207D893024A28564436427212E07F797
+:107150003607F90C6F9D01D7F0DA20DB70C1C42D22
+:10716000211F5BFEF889268827DDA009880C7A8B11
+:10717000179A10600006C04063FFCC0000DA208B35
+:10718000105BFEC88D1065A267C0E09E488C649CB1
+:10719000498B658A669B4A9A4B97458F677F730236
+:1071A000600120CD529D10DA20DB302C12015BFEF5
+:1071B000698D10C051D6A08FA7C0C08A68974D9A1C
+:1071C0004C8869896A984E994F8E6A8A69AE7E7733
+:1071D000EB01B1AA9E6A9A698B60C0A00B8E1477EE
+:1071E000B701C0A1C091C08493159D179516C0D05A
+:1071F00025203CC030085801089338C0820833105D
+:10720000085B010535400B9D3807DD100BAB100EF8
+:1072100019402A211F07991003DD020DBB020553F7
+:10722000100933020A55112921250A2A14092914A3
+:107230000499110A99020933028A2B2921040BAA05
+:10724000021BD66A0899110955020855020BAA02B9
+:107250009A408920881408991109880219D5EA1DD5
+:10726000D66409880298418B2A9346954783150D69
+:10727000BB0285168D179B448A658966AACAA97CBC
+:1072800077CB01B1AA07FB0C9C669A6588268E29EC
+:10729000AD87972607EE0C0E0E482E25259B672BF3
+:1072A000200C87131ED5C40CB911AE99289285A75E
+:1072B0008828968517D5C8C090A7BB29B4CF871852
+:1072C00063FE3C008C60C0E0C091C0F0C034C0B828
+:1072D0002A210428203C08AA110B8B0103830103F7
+:1072E0009F380B9B39C03208FF10038801089E3875
+:1072F0000C881407EE100FEE020388010898390578
+:10730000BF1029211F0ABB1107881008FF020BAA12
+:107310000218D5BC09291403AA022B212583200BAE
+:107320002B1404BB110833110FBB020B99028B14F1
+:107330008F2A0B33020833028B2B64708688689780
+:107340004D984C8769886A93419946974E984FC0EB
+:107350007077C701C0719A4718D6260B7C100CECC9
+:107360000208F802984418D6230CBC0208CC029CF0
+:10737000402A200C295CFEC0801FD58E1CD5960C9F
+:10738000AE112B2124ACAAAFEEB0BB8F132CE2853B
+:1073900028A4CFAFCC2CE6852A22152B2524B1AA10
+:1073A0002A26156490DBC9D28F262E22090DFF08EC
+:1073B0002F26060FEE0C0E0E482E25256550E4C034
+:1073C00020D10F00C07093419F4499469A4777C7D8
+:1073D0000A1CD57A2CC022C0810C87381CD6070B1A
+:1073E000781008E80208B8020C8802984063FF8011
+:1073F00000CC57DA20DB608C115BFDD629210268B6
+:107400009806689403C020D10F2B221EC0A0292209
+:107410001D2A25027B9901C0B064BFE813D5652CF5
+:10742000B00728B000DA2003880A28824CC0D10BAC
+:107430008000DBA065AFE763FFCA000068A779DAC8
+:1074400020DB30DC40DD505BFEE7D2A0D10FC16D08
+:10745000C19D29252C60000429252CD6902624675F
+:107460002F2468DA20DB308C11DD502E0A805BFD82
+:1074700044D2A0D10FC168C1A82A252C63FFDD002A
+:107480000000C8DF8C268B29ADCC9C260CBB0C0BD6
+:107490000B482B25252A2C74DB602C12015BFD8701
+:1074A000D2A0D10F2A2C748B115BF6B9D2A0D10FC8
+:1074B000DA205BFE3A63FF3800DA20C0B15BFE8A57
+:1074C00064ABF1655F352D2124B1DD2D252463FFEB
+:1074D0001FDA202B200C5BFE5663FF1412D5C882E6
+:1074E00020028257C82163FFFC12D5C403E8300490
+:1074F000EE3005B13093209421952263FFFC00000B
+:1075000010D5C0910092019302940311D597821077
+:1075100001EA30A21101F031C04004E4160002007B
+:1075200011D5B98210234A00032202921011D5828C
+:10753000C021921004E4318403830282018100009F
+:10754000D23001230000000010D5B09100920193C9
+:1075500002940311D586821001EA30A21101F131A3
+:10756000C04004E41600020011D5A7821013D52BE9
+:10757000032202921004E431840383028201810019
+:1075800000D330013300000010D5A19100810165C6
+:10759000104981026510448103CF1F920193029428
+:1075A0000311D574821001EA30A21101F231C040FA
+:1075B00004E41600020011D593821013D5130322A0
+:1075C00002921004E431840383028201C01091030B
+:1075D00091029101810000D43001430012D542C0D4
+:1075E0003028374028374428374828374C233D0176
+:1075F0007233ED03020063FFFC00000010D585919B
+:107600000092019302940311D5838210921011D538
+:10761000348310032202921011D58012D5469210A5
+:10762000C04004E41600020011D577821013D52D56
+:10763000032202921004E431840383028201810058
+:1076400000D53001530000006C10026E322FD6209E
+:10765000056F04043F04745B2A05440C00410400D8
+:10766000331A220A006D490D73630403660CB122BC
+:107670000F2211031314736302222C01D10FC83B94
+:10768000D10F000073630CC021D10F000000000077
+:1076900044495630C020D10F6C10020040046B4C9E
+:1076A00007032318020219D10F020319C020D10FBA
+:1076B0006C100202EA30D10F6C1002CC2503F031BD
+:1076C00060000F006F220503F1316000056F230594
+:1076D00003F231000200D10F6C1002CC2502F03011
+:1076E000D10F00006F220402F130D10F6F2304028A
+:1076F000F230D10FC020D10F6C1002220A20230AD1
+:10770000006D280E28374028374428374828374C42
+:10771000233D01030200D10F6C100202E431D10FAE
+:107720000A004368656C73696F20465720444542E0
+:1077300055473D3020284275696C74204672692097
+:107740004D61792020382031363A30373A333620AF
+:107750005044542032303039206F6E20636C656F96
+:1077600070617472612E6173696364657369676EB9
+:107770006572732E636F6D3A2F686F6D652F666546
+:107780006C69782F772F66775F372E31292C20563A
+:10779000657273696F6E2054337878203030372EDD
+:1077A00030342E3030202D203130303730343030EE
+:0877B000100704000071489469
+:00000001FF
index 064279e33bbb7f3692d0f774744729f6db8894dd..36df60b6d8a4b79e9fde8f0f58e3a76ee8d0a1f4 100644 (file)
 #include "dat.h"
 #include "alloc.h"
 
+struct inode *nilfs_bmap_get_dat(const struct nilfs_bmap *bmap)
+{
+       return nilfs_dat_inode(NILFS_I_NILFS(bmap->b_inode));
+}
+
 int nilfs_bmap_lookup_at_level(struct nilfs_bmap *bmap, __u64 key, int level,
                               __u64 *ptrp)
 {
-       __u64 ptr;
+       sector_t blocknr;
        int ret;
 
        down_read(&bmap->b_sem);
        ret = bmap->b_ops->bop_lookup(bmap, key, level, ptrp);
        if (ret < 0)
                goto out;
-       if (bmap->b_pops->bpop_translate != NULL) {
-               ret = bmap->b_pops->bpop_translate(bmap, *ptrp, &ptr);
-               if (ret < 0)
-                       goto out;
-               *ptrp = ptr;
+       if (NILFS_BMAP_USE_VBN(bmap)) {
+               ret = nilfs_dat_translate(nilfs_bmap_get_dat(bmap), *ptrp,
+                                         &blocknr);
+               if (!ret)
+                       *ptrp = blocknr;
        }
 
  out:
@@ -53,6 +58,16 @@ int nilfs_bmap_lookup_at_level(struct nilfs_bmap *bmap, __u64 key, int level,
        return ret;
 }
 
+int nilfs_bmap_lookup_contig(struct nilfs_bmap *bmap, __u64 key, __u64 *ptrp,
+                            unsigned maxblocks)
+{
+       int ret;
+
+       down_read(&bmap->b_sem);
+       ret = bmap->b_ops->bop_lookup_contig(bmap, key, ptrp, maxblocks);
+       up_read(&bmap->b_sem);
+       return ret;
+}
 
 /**
  * nilfs_bmap_lookup - find a record
@@ -101,8 +116,7 @@ static int nilfs_bmap_do_insert(struct nilfs_bmap *bmap, __u64 key, __u64 ptr)
                        if (n < 0)
                                return n;
                        ret = nilfs_btree_convert_and_insert(
-                               bmap, key, ptr, keys, ptrs, n,
-                               NILFS_BMAP_LARGE_LOW, NILFS_BMAP_LARGE_HIGH);
+                               bmap, key, ptr, keys, ptrs, n);
                        if (ret == 0)
                                bmap->b_u.u_flags |= NILFS_BMAP_LARGE;
 
@@ -158,8 +172,7 @@ static int nilfs_bmap_do_delete(struct nilfs_bmap *bmap, __u64 key)
                        if (n < 0)
                                return n;
                        ret = nilfs_direct_delete_and_convert(
-                               bmap, key, keys, ptrs, n,
-                               NILFS_BMAP_SMALL_LOW, NILFS_BMAP_SMALL_HIGH);
+                               bmap, key, keys, ptrs, n);
                        if (ret == 0)
                                bmap->b_u.u_flags &= ~NILFS_BMAP_LARGE;
 
@@ -417,38 +430,6 @@ void nilfs_bmap_sub_blocks(const struct nilfs_bmap *bmap, int n)
                mark_inode_dirty(bmap->b_inode);
 }
 
-int nilfs_bmap_get_block(const struct nilfs_bmap *bmap, __u64 ptr,
-                        struct buffer_head **bhp)
-{
-       return nilfs_btnode_get(&NILFS_BMAP_I(bmap)->i_btnode_cache,
-                               ptr, 0, bhp, 0);
-}
-
-void nilfs_bmap_put_block(const struct nilfs_bmap *bmap,
-                         struct buffer_head *bh)
-{
-       brelse(bh);
-}
-
-int nilfs_bmap_get_new_block(const struct nilfs_bmap *bmap, __u64 ptr,
-                            struct buffer_head **bhp)
-{
-       int ret;
-
-       ret = nilfs_btnode_get(&NILFS_BMAP_I(bmap)->i_btnode_cache,
-                              ptr, 0, bhp, 1);
-       if (ret < 0)
-               return ret;
-       set_buffer_nilfs_volatile(*bhp);
-       return 0;
-}
-
-void nilfs_bmap_delete_block(const struct nilfs_bmap *bmap,
-                            struct buffer_head *bh)
-{
-       nilfs_btnode_delete(bh);
-}
-
 __u64 nilfs_bmap_data_get_key(const struct nilfs_bmap *bmap,
                              const struct buffer_head *bh)
 {
@@ -476,11 +457,6 @@ __u64 nilfs_bmap_find_target_seq(const struct nilfs_bmap *bmap, __u64 key)
                return NILFS_BMAP_INVALID_PTR;
 }
 
-static struct inode *nilfs_bmap_get_dat(const struct nilfs_bmap *bmap)
-{
-       return nilfs_dat_inode(NILFS_I_NILFS(bmap->b_inode));
-}
-
 #define NILFS_BMAP_GROUP_DIV   8
 __u64 nilfs_bmap_find_target_in_group(const struct nilfs_bmap *bmap)
 {
@@ -493,64 +469,51 @@ __u64 nilfs_bmap_find_target_in_group(const struct nilfs_bmap *bmap)
                (entries_per_group / NILFS_BMAP_GROUP_DIV);
 }
 
-static int nilfs_bmap_prepare_alloc_v(struct nilfs_bmap *bmap,
-                                     union nilfs_bmap_ptr_req *req)
+int nilfs_bmap_prepare_alloc_v(struct nilfs_bmap *bmap,
+                                union nilfs_bmap_ptr_req *req)
 {
        return nilfs_dat_prepare_alloc(nilfs_bmap_get_dat(bmap), &req->bpr_req);
 }
 
-static void nilfs_bmap_commit_alloc_v(struct nilfs_bmap *bmap,
-                                     union nilfs_bmap_ptr_req *req)
+void nilfs_bmap_commit_alloc_v(struct nilfs_bmap *bmap,
+                                union nilfs_bmap_ptr_req *req)
 {
        nilfs_dat_commit_alloc(nilfs_bmap_get_dat(bmap), &req->bpr_req);
 }
 
-static void nilfs_bmap_abort_alloc_v(struct nilfs_bmap *bmap,
-                                    union nilfs_bmap_ptr_req *req)
+void nilfs_bmap_abort_alloc_v(struct nilfs_bmap *bmap,
+                             union nilfs_bmap_ptr_req *req)
 {
        nilfs_dat_abort_alloc(nilfs_bmap_get_dat(bmap), &req->bpr_req);
 }
 
-static int nilfs_bmap_prepare_start_v(struct nilfs_bmap *bmap,
-                                     union nilfs_bmap_ptr_req *req)
+int nilfs_bmap_start_v(struct nilfs_bmap *bmap, union nilfs_bmap_ptr_req *req,
+                      sector_t blocknr)
 {
-       return nilfs_dat_prepare_start(nilfs_bmap_get_dat(bmap), &req->bpr_req);
-}
-
-static void nilfs_bmap_commit_start_v(struct nilfs_bmap *bmap,
-                                     union nilfs_bmap_ptr_req *req,
-                                     sector_t blocknr)
-{
-       nilfs_dat_commit_start(nilfs_bmap_get_dat(bmap), &req->bpr_req,
-                              blocknr);
-}
+       struct inode *dat = nilfs_bmap_get_dat(bmap);
+       int ret;
 
-static void nilfs_bmap_abort_start_v(struct nilfs_bmap *bmap,
-                                    union nilfs_bmap_ptr_req *req)
-{
-       nilfs_dat_abort_start(nilfs_bmap_get_dat(bmap), &req->bpr_req);
+       ret = nilfs_dat_prepare_start(dat, &req->bpr_req);
+       if (likely(!ret))
+               nilfs_dat_commit_start(dat, &req->bpr_req, blocknr);
+       return ret;
 }
 
-static int nilfs_bmap_prepare_end_v(struct nilfs_bmap *bmap,
-                                   union nilfs_bmap_ptr_req *req)
+int nilfs_bmap_prepare_end_v(struct nilfs_bmap *bmap,
+                            union nilfs_bmap_ptr_req *req)
 {
        return nilfs_dat_prepare_end(nilfs_bmap_get_dat(bmap), &req->bpr_req);
 }
 
-static void nilfs_bmap_commit_end_v(struct nilfs_bmap *bmap,
-                                   union nilfs_bmap_ptr_req *req)
-{
-       nilfs_dat_commit_end(nilfs_bmap_get_dat(bmap), &req->bpr_req, 0);
-}
-
-static void nilfs_bmap_commit_end_vmdt(struct nilfs_bmap *bmap,
-                                      union nilfs_bmap_ptr_req *req)
+void nilfs_bmap_commit_end_v(struct nilfs_bmap *bmap,
+                            union nilfs_bmap_ptr_req *req)
 {
-       nilfs_dat_commit_end(nilfs_bmap_get_dat(bmap), &req->bpr_req, 1);
+       nilfs_dat_commit_end(nilfs_bmap_get_dat(bmap), &req->bpr_req,
+                            bmap->b_ptr_type == NILFS_BMAP_PTR_VS);
 }
 
-static void nilfs_bmap_abort_end_v(struct nilfs_bmap *bmap,
-                                  union nilfs_bmap_ptr_req *req)
+void nilfs_bmap_abort_end_v(struct nilfs_bmap *bmap,
+                           union nilfs_bmap_ptr_req *req)
 {
        nilfs_dat_abort_end(nilfs_bmap_get_dat(bmap), &req->bpr_req);
 }
@@ -566,128 +529,44 @@ int nilfs_bmap_mark_dirty(const struct nilfs_bmap *bmap, __u64 vblocknr)
        return nilfs_dat_mark_dirty(nilfs_bmap_get_dat(bmap), vblocknr);
 }
 
-int nilfs_bmap_prepare_update(struct nilfs_bmap *bmap,
-                             union nilfs_bmap_ptr_req *oldreq,
-                             union nilfs_bmap_ptr_req *newreq)
+int nilfs_bmap_prepare_update_v(struct nilfs_bmap *bmap,
+                               union nilfs_bmap_ptr_req *oldreq,
+                               union nilfs_bmap_ptr_req *newreq)
 {
+       struct inode *dat = nilfs_bmap_get_dat(bmap);
        int ret;
 
-       ret = bmap->b_pops->bpop_prepare_end_ptr(bmap, oldreq);
+       ret = nilfs_dat_prepare_end(dat, &oldreq->bpr_req);
        if (ret < 0)
                return ret;
-       ret = bmap->b_pops->bpop_prepare_alloc_ptr(bmap, newreq);
+       ret = nilfs_dat_prepare_alloc(dat, &newreq->bpr_req);
        if (ret < 0)
-               bmap->b_pops->bpop_abort_end_ptr(bmap, oldreq);
+               nilfs_dat_abort_end(dat, &oldreq->bpr_req);
 
        return ret;
 }
 
-void nilfs_bmap_commit_update(struct nilfs_bmap *bmap,
-                             union nilfs_bmap_ptr_req *oldreq,
-                             union nilfs_bmap_ptr_req *newreq)
+void nilfs_bmap_commit_update_v(struct nilfs_bmap *bmap,
+                               union nilfs_bmap_ptr_req *oldreq,
+                               union nilfs_bmap_ptr_req *newreq)
 {
-       bmap->b_pops->bpop_commit_end_ptr(bmap, oldreq);
-       bmap->b_pops->bpop_commit_alloc_ptr(bmap, newreq);
-}
+       struct inode *dat = nilfs_bmap_get_dat(bmap);
 
-void nilfs_bmap_abort_update(struct nilfs_bmap *bmap,
-                            union nilfs_bmap_ptr_req *oldreq,
-                            union nilfs_bmap_ptr_req *newreq)
-{
-       bmap->b_pops->bpop_abort_end_ptr(bmap, oldreq);
-       bmap->b_pops->bpop_abort_alloc_ptr(bmap, newreq);
+       nilfs_dat_commit_end(dat, &oldreq->bpr_req,
+                            bmap->b_ptr_type == NILFS_BMAP_PTR_VS);
+       nilfs_dat_commit_alloc(dat, &newreq->bpr_req);
 }
 
-static int nilfs_bmap_translate_v(const struct nilfs_bmap *bmap, __u64 ptr,
-                                 __u64 *ptrp)
+void nilfs_bmap_abort_update_v(struct nilfs_bmap *bmap,
+                              union nilfs_bmap_ptr_req *oldreq,
+                              union nilfs_bmap_ptr_req *newreq)
 {
-       sector_t blocknr;
-       int ret;
-
-       ret = nilfs_dat_translate(nilfs_bmap_get_dat(bmap), ptr, &blocknr);
-       if (ret < 0)
-               return ret;
-       if (ptrp != NULL)
-               *ptrp = blocknr;
-       return 0;
-}
+       struct inode *dat = nilfs_bmap_get_dat(bmap);
 
-static int nilfs_bmap_prepare_alloc_p(struct nilfs_bmap *bmap,
-                                     union nilfs_bmap_ptr_req *req)
-{
-       /* ignore target ptr */
-       req->bpr_ptr = bmap->b_last_allocated_ptr++;
-       return 0;
+       nilfs_dat_abort_end(dat, &oldreq->bpr_req);
+       nilfs_dat_abort_alloc(dat, &newreq->bpr_req);
 }
 
-static void nilfs_bmap_commit_alloc_p(struct nilfs_bmap *bmap,
-                                     union nilfs_bmap_ptr_req *req)
-{
-       /* do nothing */
-}
-
-static void nilfs_bmap_abort_alloc_p(struct nilfs_bmap *bmap,
-                                    union nilfs_bmap_ptr_req *req)
-{
-       bmap->b_last_allocated_ptr--;
-}
-
-static const struct nilfs_bmap_ptr_operations nilfs_bmap_ptr_ops_v = {
-       .bpop_prepare_alloc_ptr =       nilfs_bmap_prepare_alloc_v,
-       .bpop_commit_alloc_ptr  =       nilfs_bmap_commit_alloc_v,
-       .bpop_abort_alloc_ptr   =       nilfs_bmap_abort_alloc_v,
-       .bpop_prepare_start_ptr =       nilfs_bmap_prepare_start_v,
-       .bpop_commit_start_ptr  =       nilfs_bmap_commit_start_v,
-       .bpop_abort_start_ptr   =       nilfs_bmap_abort_start_v,
-       .bpop_prepare_end_ptr   =       nilfs_bmap_prepare_end_v,
-       .bpop_commit_end_ptr    =       nilfs_bmap_commit_end_v,
-       .bpop_abort_end_ptr     =       nilfs_bmap_abort_end_v,
-
-       .bpop_translate         =       nilfs_bmap_translate_v,
-};
-
-static const struct nilfs_bmap_ptr_operations nilfs_bmap_ptr_ops_vmdt = {
-       .bpop_prepare_alloc_ptr =       nilfs_bmap_prepare_alloc_v,
-       .bpop_commit_alloc_ptr  =       nilfs_bmap_commit_alloc_v,
-       .bpop_abort_alloc_ptr   =       nilfs_bmap_abort_alloc_v,
-       .bpop_prepare_start_ptr =       nilfs_bmap_prepare_start_v,
-       .bpop_commit_start_ptr  =       nilfs_bmap_commit_start_v,
-       .bpop_abort_start_ptr   =       nilfs_bmap_abort_start_v,
-       .bpop_prepare_end_ptr   =       nilfs_bmap_prepare_end_v,
-       .bpop_commit_end_ptr    =       nilfs_bmap_commit_end_vmdt,
-       .bpop_abort_end_ptr     =       nilfs_bmap_abort_end_v,
-
-       .bpop_translate         =       nilfs_bmap_translate_v,
-};
-
-static const struct nilfs_bmap_ptr_operations nilfs_bmap_ptr_ops_p = {
-       .bpop_prepare_alloc_ptr =       nilfs_bmap_prepare_alloc_p,
-       .bpop_commit_alloc_ptr  =       nilfs_bmap_commit_alloc_p,
-       .bpop_abort_alloc_ptr   =       nilfs_bmap_abort_alloc_p,
-       .bpop_prepare_start_ptr =       NULL,
-       .bpop_commit_start_ptr  =       NULL,
-       .bpop_abort_start_ptr   =       NULL,
-       .bpop_prepare_end_ptr   =       NULL,
-       .bpop_commit_end_ptr    =       NULL,
-       .bpop_abort_end_ptr     =       NULL,
-
-       .bpop_translate         =       NULL,
-};
-
-static const struct nilfs_bmap_ptr_operations nilfs_bmap_ptr_ops_gc = {
-       .bpop_prepare_alloc_ptr =       NULL,
-       .bpop_commit_alloc_ptr  =       NULL,
-       .bpop_abort_alloc_ptr   =       NULL,
-       .bpop_prepare_start_ptr =       NULL,
-       .bpop_commit_start_ptr  =       NULL,
-       .bpop_abort_start_ptr   =       NULL,
-       .bpop_prepare_end_ptr   =       NULL,
-       .bpop_commit_end_ptr    =       NULL,
-       .bpop_abort_end_ptr     =       NULL,
-
-       .bpop_translate         =       NULL,
-};
-
 static struct lock_class_key nilfs_bmap_dat_lock_key;
 
 /**
@@ -714,31 +593,26 @@ int nilfs_bmap_read(struct nilfs_bmap *bmap, struct nilfs_inode *raw_inode)
        bmap->b_inode = &NILFS_BMAP_I(bmap)->vfs_inode;
        switch (bmap->b_inode->i_ino) {
        case NILFS_DAT_INO:
-               bmap->b_pops = &nilfs_bmap_ptr_ops_p;
-               bmap->b_last_allocated_key = 0; /* XXX: use macro */
+               bmap->b_ptr_type = NILFS_BMAP_PTR_P;
+               bmap->b_last_allocated_key = 0;
                bmap->b_last_allocated_ptr = NILFS_BMAP_NEW_PTR_INIT;
                lockdep_set_class(&bmap->b_sem, &nilfs_bmap_dat_lock_key);
                break;
        case NILFS_CPFILE_INO:
        case NILFS_SUFILE_INO:
-               bmap->b_pops = &nilfs_bmap_ptr_ops_vmdt;
-               bmap->b_last_allocated_key = 0; /* XXX: use macro */
+               bmap->b_ptr_type = NILFS_BMAP_PTR_VS;
+               bmap->b_last_allocated_key = 0;
                bmap->b_last_allocated_ptr = NILFS_BMAP_INVALID_PTR;
                break;
        default:
-               bmap->b_pops = &nilfs_bmap_ptr_ops_v;
-               bmap->b_last_allocated_key = 0; /* XXX: use macro */
+               bmap->b_ptr_type = NILFS_BMAP_PTR_VM;
+               bmap->b_last_allocated_key = 0;
                bmap->b_last_allocated_ptr = NILFS_BMAP_INVALID_PTR;
                break;
        }
 
        return (bmap->b_u.u_flags & NILFS_BMAP_LARGE) ?
-               nilfs_btree_init(bmap,
-                                NILFS_BMAP_LARGE_LOW,
-                                NILFS_BMAP_LARGE_HIGH) :
-               nilfs_direct_init(bmap,
-                                 NILFS_BMAP_SMALL_LOW,
-                                 NILFS_BMAP_SMALL_HIGH);
+               nilfs_btree_init(bmap) : nilfs_direct_init(bmap);
 }
 
 /**
@@ -764,7 +638,7 @@ void nilfs_bmap_init_gc(struct nilfs_bmap *bmap)
        memset(&bmap->b_u, 0, NILFS_BMAP_SIZE);
        init_rwsem(&bmap->b_sem);
        bmap->b_inode = &NILFS_BMAP_I(bmap)->vfs_inode;
-       bmap->b_pops = &nilfs_bmap_ptr_ops_gc;
+       bmap->b_ptr_type = NILFS_BMAP_PTR_U;
        bmap->b_last_allocated_key = 0;
        bmap->b_last_allocated_ptr = NILFS_BMAP_INVALID_PTR;
        bmap->b_state = 0;
index 4f2708abb1ba446e1b3b93144a37349b313ad5d8..b2890cdcef124883c8993d54f14a71c23c61863c 100644 (file)
@@ -64,6 +64,8 @@ struct nilfs_bmap_stats {
  */
 struct nilfs_bmap_operations {
        int (*bop_lookup)(const struct nilfs_bmap *, __u64, int, __u64 *);
+       int (*bop_lookup_contig)(const struct nilfs_bmap *, __u64, __u64 *,
+                                unsigned);
        int (*bop_insert)(struct nilfs_bmap *, __u64, __u64);
        int (*bop_delete)(struct nilfs_bmap *, __u64);
        void (*bop_clear)(struct nilfs_bmap *);
@@ -86,34 +88,6 @@ struct nilfs_bmap_operations {
 };
 
 
-/**
- * struct nilfs_bmap_ptr_operations - bmap ptr operation table
- */
-struct nilfs_bmap_ptr_operations {
-       int (*bpop_prepare_alloc_ptr)(struct nilfs_bmap *,
-                                     union nilfs_bmap_ptr_req *);
-       void (*bpop_commit_alloc_ptr)(struct nilfs_bmap *,
-                                     union nilfs_bmap_ptr_req *);
-       void (*bpop_abort_alloc_ptr)(struct nilfs_bmap *,
-                                    union nilfs_bmap_ptr_req *);
-       int (*bpop_prepare_start_ptr)(struct nilfs_bmap *,
-                                     union nilfs_bmap_ptr_req *);
-       void (*bpop_commit_start_ptr)(struct nilfs_bmap *,
-                                     union nilfs_bmap_ptr_req *,
-                                     sector_t);
-       void (*bpop_abort_start_ptr)(struct nilfs_bmap *,
-                                    union nilfs_bmap_ptr_req *);
-       int (*bpop_prepare_end_ptr)(struct nilfs_bmap *,
-                                   union nilfs_bmap_ptr_req *);
-       void (*bpop_commit_end_ptr)(struct nilfs_bmap *,
-                                   union nilfs_bmap_ptr_req *);
-       void (*bpop_abort_end_ptr)(struct nilfs_bmap *,
-                                  union nilfs_bmap_ptr_req *);
-
-       int (*bpop_translate)(const struct nilfs_bmap *, __u64, __u64 *);
-};
-
-
 #define NILFS_BMAP_SIZE                (NILFS_INODE_BMAP_SIZE * sizeof(__le64))
 #define NILFS_BMAP_KEY_BIT     (sizeof(unsigned long) * 8 /* CHAR_BIT */)
 #define NILFS_BMAP_NEW_PTR_INIT        \
@@ -131,11 +105,9 @@ static inline int nilfs_bmap_is_new_ptr(unsigned long ptr)
  * @b_sem: semaphore
  * @b_inode: owner of bmap
  * @b_ops: bmap operation table
- * @b_pops: bmap ptr operation table
- * @b_low: low watermark of conversion
- * @b_high: high watermark of conversion
  * @b_last_allocated_key: last allocated key for data block
  * @b_last_allocated_ptr: last allocated ptr for data block
+ * @b_ptr_type: pointer type
  * @b_state: state
  */
 struct nilfs_bmap {
@@ -146,14 +118,22 @@ struct nilfs_bmap {
        struct rw_semaphore b_sem;
        struct inode *b_inode;
        const struct nilfs_bmap_operations *b_ops;
-       const struct nilfs_bmap_ptr_operations *b_pops;
-       __u64 b_low;
-       __u64 b_high;
        __u64 b_last_allocated_key;
        __u64 b_last_allocated_ptr;
+       int b_ptr_type;
        int b_state;
 };
 
+/* pointer type */
+#define NILFS_BMAP_PTR_P       0       /* physical block number (i.e. LBN) */
+#define NILFS_BMAP_PTR_VS      1       /* virtual block number (single
+                                          version) */
+#define NILFS_BMAP_PTR_VM      2       /* virtual block number (has multiple
+                                          versions) */
+#define NILFS_BMAP_PTR_U       (-1)    /* never perform pointer operations */
+
+#define NILFS_BMAP_USE_VBN(bmap)       ((bmap)->b_ptr_type > 0)
+
 /* state */
 #define NILFS_BMAP_DIRTY       0x00000001
 
@@ -162,6 +142,7 @@ int nilfs_bmap_test_and_clear_dirty(struct nilfs_bmap *);
 int nilfs_bmap_read(struct nilfs_bmap *, struct nilfs_inode *);
 void nilfs_bmap_write(struct nilfs_bmap *, struct nilfs_inode *);
 int nilfs_bmap_lookup(struct nilfs_bmap *, unsigned long, unsigned long *);
+int nilfs_bmap_lookup_contig(struct nilfs_bmap *, __u64, __u64 *, unsigned);
 int nilfs_bmap_insert(struct nilfs_bmap *, unsigned long, unsigned long);
 int nilfs_bmap_delete(struct nilfs_bmap *, unsigned long);
 int nilfs_bmap_last_key(struct nilfs_bmap *, unsigned long *);
@@ -182,7 +163,67 @@ void nilfs_bmap_commit_gcdat(struct nilfs_bmap *, struct nilfs_bmap *);
 /*
  * Internal use only
  */
+struct inode *nilfs_bmap_get_dat(const struct nilfs_bmap *);
+int nilfs_bmap_prepare_alloc_v(struct nilfs_bmap *,
+                              union nilfs_bmap_ptr_req *);
+void nilfs_bmap_commit_alloc_v(struct nilfs_bmap *,
+                              union nilfs_bmap_ptr_req *);
+void nilfs_bmap_abort_alloc_v(struct nilfs_bmap *,
+                             union nilfs_bmap_ptr_req *);
 
+static inline int nilfs_bmap_prepare_alloc_ptr(struct nilfs_bmap *bmap,
+                                              union nilfs_bmap_ptr_req *req)
+{
+       if (NILFS_BMAP_USE_VBN(bmap))
+               return nilfs_bmap_prepare_alloc_v(bmap, req);
+       /* ignore target ptr */
+       req->bpr_ptr = bmap->b_last_allocated_ptr++;
+       return 0;
+}
+
+static inline void nilfs_bmap_commit_alloc_ptr(struct nilfs_bmap *bmap,
+                                              union nilfs_bmap_ptr_req *req)
+{
+       if (NILFS_BMAP_USE_VBN(bmap))
+               nilfs_bmap_commit_alloc_v(bmap, req);
+}
+
+static inline void nilfs_bmap_abort_alloc_ptr(struct nilfs_bmap *bmap,
+                                             union nilfs_bmap_ptr_req *req)
+{
+       if (NILFS_BMAP_USE_VBN(bmap))
+               nilfs_bmap_abort_alloc_v(bmap, req);
+       else
+               bmap->b_last_allocated_ptr--;
+}
+
+int nilfs_bmap_prepare_end_v(struct nilfs_bmap *, union nilfs_bmap_ptr_req *);
+void nilfs_bmap_commit_end_v(struct nilfs_bmap *, union nilfs_bmap_ptr_req *);
+void nilfs_bmap_abort_end_v(struct nilfs_bmap *, union nilfs_bmap_ptr_req *);
+
+static inline int nilfs_bmap_prepare_end_ptr(struct nilfs_bmap *bmap,
+                                            union nilfs_bmap_ptr_req *req)
+{
+       return NILFS_BMAP_USE_VBN(bmap) ?
+               nilfs_bmap_prepare_end_v(bmap, req) : 0;
+}
+
+static inline void nilfs_bmap_commit_end_ptr(struct nilfs_bmap *bmap,
+                                            union nilfs_bmap_ptr_req *req)
+{
+       if (NILFS_BMAP_USE_VBN(bmap))
+               nilfs_bmap_commit_end_v(bmap, req);
+}
+
+static inline void nilfs_bmap_abort_end_ptr(struct nilfs_bmap *bmap,
+                                           union nilfs_bmap_ptr_req *req)
+{
+       if (NILFS_BMAP_USE_VBN(bmap))
+               nilfs_bmap_abort_end_v(bmap, req);
+}
+
+int nilfs_bmap_start_v(struct nilfs_bmap *, union nilfs_bmap_ptr_req *,
+                      sector_t);
 int nilfs_bmap_move_v(const struct nilfs_bmap *, __u64, sector_t);
 int nilfs_bmap_mark_dirty(const struct nilfs_bmap *, __u64);
 
@@ -193,28 +234,20 @@ __u64 nilfs_bmap_data_get_key(const struct nilfs_bmap *,
 __u64 nilfs_bmap_find_target_seq(const struct nilfs_bmap *, __u64);
 __u64 nilfs_bmap_find_target_in_group(const struct nilfs_bmap *);
 
-int nilfs_bmap_prepare_update(struct nilfs_bmap *,
-                             union nilfs_bmap_ptr_req *,
-                             union nilfs_bmap_ptr_req *);
-void nilfs_bmap_commit_update(struct nilfs_bmap *,
-                             union nilfs_bmap_ptr_req *,
-                             union nilfs_bmap_ptr_req *);
-void nilfs_bmap_abort_update(struct nilfs_bmap *,
-                            union nilfs_bmap_ptr_req *,
-                            union nilfs_bmap_ptr_req *);
+int nilfs_bmap_prepare_update_v(struct nilfs_bmap *,
+                               union nilfs_bmap_ptr_req *,
+                               union nilfs_bmap_ptr_req *);
+void nilfs_bmap_commit_update_v(struct nilfs_bmap *,
+                               union nilfs_bmap_ptr_req *,
+                               union nilfs_bmap_ptr_req *);
+void nilfs_bmap_abort_update_v(struct nilfs_bmap *,
+                              union nilfs_bmap_ptr_req *,
+                              union nilfs_bmap_ptr_req *);
 
 void nilfs_bmap_add_blocks(const struct nilfs_bmap *, int);
 void nilfs_bmap_sub_blocks(const struct nilfs_bmap *, int);
 
 
-int nilfs_bmap_get_block(const struct nilfs_bmap *, __u64,
-                        struct buffer_head **);
-void nilfs_bmap_put_block(const struct nilfs_bmap *, struct buffer_head *);
-int nilfs_bmap_get_new_block(const struct nilfs_bmap *, __u64,
-                            struct buffer_head **);
-void nilfs_bmap_delete_block(const struct nilfs_bmap *, struct buffer_head *);
-
-
 /* Assume that bmap semaphore is locked. */
 static inline int nilfs_bmap_dirty(const struct nilfs_bmap *bmap)
 {
index 4cc07b2c30e0c893e9baf4df3f26c305f2f9c805..7e0b61be212e8a18476518db9507d2d018f7fed6 100644 (file)
@@ -46,15 +46,18 @@ void nilfs_btnode_cache_init_once(struct address_space *btnc)
        INIT_LIST_HEAD(&btnc->i_mmap_nonlinear);
 }
 
-static struct address_space_operations def_btnode_aops;
+static struct address_space_operations def_btnode_aops = {
+       .sync_page              = block_sync_page,
+};
 
-void nilfs_btnode_cache_init(struct address_space *btnc)
+void nilfs_btnode_cache_init(struct address_space *btnc,
+                            struct backing_dev_info *bdi)
 {
        btnc->host = NULL;  /* can safely set to host inode ? */
        btnc->flags = 0;
        mapping_set_gfp_mask(btnc, GFP_NOFS);
        btnc->assoc_mapping = NULL;
-       btnc->backing_dev_info = &default_backing_dev_info;
+       btnc->backing_dev_info = bdi;
        btnc->a_ops = &def_btnode_aops;
 }
 
index 35faa86444a75dbdbc2ab50b703359833fd0e5cb..3e2275172ed623cc48e428619fdd66b9a47484a9 100644 (file)
@@ -38,7 +38,7 @@ struct nilfs_btnode_chkey_ctxt {
 };
 
 void nilfs_btnode_cache_init_once(struct address_space *);
-void nilfs_btnode_cache_init(struct address_space *);
+void nilfs_btnode_cache_init(struct address_space *, struct backing_dev_info *);
 void nilfs_btnode_cache_clear(struct address_space *);
 int nilfs_btnode_submit_block(struct address_space *, __u64, sector_t,
                              struct buffer_head **, int);
index 6b37a2767293d1e123454eb662fe90bd76c8f735..aa412724b64eb41ab297c029b166ea3849de4710 100644 (file)
@@ -29,6 +29,7 @@
 #include "btnode.h"
 #include "btree.h"
 #include "alloc.h"
+#include "dat.h"
 
 /**
  * struct nilfs_btree_path - A path on which B-tree operations are executed
@@ -109,8 +110,7 @@ static void nilfs_btree_clear_path(const struct nilfs_btree *btree,
             level < NILFS_BTREE_LEVEL_MAX;
             level++) {
                if (path[level].bp_bh != NULL) {
-                       nilfs_bmap_put_block(&btree->bt_bmap,
-                                            path[level].bp_bh);
+                       brelse(path[level].bp_bh);
                        path[level].bp_bh = NULL;
                }
                /* sib_bh is released or deleted by prepare or commit
@@ -123,10 +123,29 @@ static void nilfs_btree_clear_path(const struct nilfs_btree *btree,
        }
 }
 
-
 /*
  * B-tree node operations
  */
+static int nilfs_btree_get_block(const struct nilfs_btree *btree, __u64 ptr,
+                                struct buffer_head **bhp)
+{
+       struct address_space *btnc =
+               &NILFS_BMAP_I((struct nilfs_bmap *)btree)->i_btnode_cache;
+       return nilfs_btnode_get(btnc, ptr, 0, bhp, 0);
+}
+
+static int nilfs_btree_get_new_block(const struct nilfs_btree *btree,
+                                    __u64 ptr, struct buffer_head **bhp)
+{
+       struct address_space *btnc =
+               &NILFS_BMAP_I((struct nilfs_bmap *)btree)->i_btnode_cache;
+       int ret;
+
+       ret = nilfs_btnode_get(btnc, ptr, 0, bhp, 1);
+       if (!ret)
+               set_buffer_nilfs_volatile(*bhp);
+       return ret;
+}
 
 static inline int
 nilfs_btree_node_get_flags(const struct nilfs_btree *btree,
@@ -488,8 +507,7 @@ static int nilfs_btree_do_lookup(const struct nilfs_btree *btree,
        path[level].bp_index = index;
 
        for (level--; level >= minlevel; level--) {
-               ret = nilfs_bmap_get_block(&btree->bt_bmap, ptr,
-                                          &path[level].bp_bh);
+               ret = nilfs_btree_get_block(btree, ptr, &path[level].bp_bh);
                if (ret < 0)
                        return ret;
                node = nilfs_btree_get_nonroot_node(btree, path, level);
@@ -535,8 +553,7 @@ static int nilfs_btree_do_lookup_last(const struct nilfs_btree *btree,
        path[level].bp_index = index;
 
        for (level--; level > 0; level--) {
-               ret = nilfs_bmap_get_block(&btree->bt_bmap, ptr,
-                                          &path[level].bp_bh);
+               ret = nilfs_btree_get_block(btree, ptr, &path[level].bp_bh);
                if (ret < 0)
                        return ret;
                node = nilfs_btree_get_nonroot_node(btree, path, level);
@@ -579,6 +596,87 @@ static int nilfs_btree_lookup(const struct nilfs_bmap *bmap,
        return ret;
 }
 
+static int nilfs_btree_lookup_contig(const struct nilfs_bmap *bmap,
+                                    __u64 key, __u64 *ptrp, unsigned maxblocks)
+{
+       struct nilfs_btree *btree = (struct nilfs_btree *)bmap;
+       struct nilfs_btree_path *path;
+       struct nilfs_btree_node *node;
+       struct inode *dat = NULL;
+       __u64 ptr, ptr2;
+       sector_t blocknr;
+       int level = NILFS_BTREE_LEVEL_NODE_MIN;
+       int ret, cnt, index, maxlevel;
+
+       path = nilfs_btree_alloc_path(btree);
+       if (path == NULL)
+               return -ENOMEM;
+       nilfs_btree_init_path(btree, path);
+       ret = nilfs_btree_do_lookup(btree, path, key, &ptr, level);
+       if (ret < 0)
+               goto out;
+
+       if (NILFS_BMAP_USE_VBN(bmap)) {
+               dat = nilfs_bmap_get_dat(bmap);
+               ret = nilfs_dat_translate(dat, ptr, &blocknr);
+               if (ret < 0)
+                       goto out;
+               ptr = blocknr;
+       }
+       cnt = 1;
+       if (cnt == maxblocks)
+               goto end;
+
+       maxlevel = nilfs_btree_height(btree) - 1;
+       node = nilfs_btree_get_node(btree, path, level);
+       index = path[level].bp_index + 1;
+       for (;;) {
+               while (index < nilfs_btree_node_get_nchildren(btree, node)) {
+                       if (nilfs_btree_node_get_key(btree, node, index) !=
+                           key + cnt)
+                               goto end;
+                       ptr2 = nilfs_btree_node_get_ptr(btree, node, index);
+                       if (dat) {
+                               ret = nilfs_dat_translate(dat, ptr2, &blocknr);
+                               if (ret < 0)
+                                       goto out;
+                               ptr2 = blocknr;
+                       }
+                       if (ptr2 != ptr + cnt || ++cnt == maxblocks)
+                               goto end;
+                       index++;
+                       continue;
+               }
+               if (level == maxlevel)
+                       break;
+
+               /* look-up right sibling node */
+               node = nilfs_btree_get_node(btree, path, level + 1);
+               index = path[level + 1].bp_index + 1;
+               if (index >= nilfs_btree_node_get_nchildren(btree, node) ||
+                   nilfs_btree_node_get_key(btree, node, index) != key + cnt)
+                       break;
+               ptr2 = nilfs_btree_node_get_ptr(btree, node, index);
+               path[level + 1].bp_index = index;
+
+               brelse(path[level].bp_bh);
+               path[level].bp_bh = NULL;
+               ret = nilfs_btree_get_block(btree, ptr2, &path[level].bp_bh);
+               if (ret < 0)
+                       goto out;
+               node = nilfs_btree_get_nonroot_node(btree, path, level);
+               index = 0;
+               path[level].bp_index = index;
+       }
+ end:
+       *ptrp = ptr;
+       ret = cnt;
+ out:
+       nilfs_btree_clear_path(btree, path);
+       nilfs_btree_free_path(btree, path);
+       return ret;
+}
+
 static void nilfs_btree_promote_key(struct nilfs_btree *btree,
                                    struct nilfs_btree_path *path,
                                    int level, __u64 key)
@@ -669,13 +767,13 @@ static void nilfs_btree_carry_left(struct nilfs_btree *btree,
                                nilfs_btree_node_get_key(btree, node, 0));
 
        if (move) {
-               nilfs_bmap_put_block(&btree->bt_bmap, path[level].bp_bh);
+               brelse(path[level].bp_bh);
                path[level].bp_bh = path[level].bp_sib_bh;
                path[level].bp_sib_bh = NULL;
                path[level].bp_index += lnchildren;
                path[level + 1].bp_index--;
        } else {
-               nilfs_bmap_put_block(&btree->bt_bmap, path[level].bp_sib_bh);
+               brelse(path[level].bp_sib_bh);
                path[level].bp_sib_bh = NULL;
                path[level].bp_index -= n;
        }
@@ -722,14 +820,14 @@ static void nilfs_btree_carry_right(struct nilfs_btree *btree,
        path[level + 1].bp_index--;
 
        if (move) {
-               nilfs_bmap_put_block(&btree->bt_bmap, path[level].bp_bh);
+               brelse(path[level].bp_bh);
                path[level].bp_bh = path[level].bp_sib_bh;
                path[level].bp_sib_bh = NULL;
                path[level].bp_index -=
                        nilfs_btree_node_get_nchildren(btree, node);
                path[level + 1].bp_index++;
        } else {
-               nilfs_bmap_put_block(&btree->bt_bmap, path[level].bp_sib_bh);
+               brelse(path[level].bp_sib_bh);
                path[level].bp_sib_bh = NULL;
        }
 
@@ -781,7 +879,7 @@ static void nilfs_btree_split(struct nilfs_btree *btree,
                *keyp = nilfs_btree_node_get_key(btree, right, 0);
                *ptrp = path[level].bp_newreq.bpr_ptr;
 
-               nilfs_bmap_put_block(&btree->bt_bmap, path[level].bp_bh);
+               brelse(path[level].bp_bh);
                path[level].bp_bh = path[level].bp_sib_bh;
                path[level].bp_sib_bh = NULL;
        } else {
@@ -790,7 +888,7 @@ static void nilfs_btree_split(struct nilfs_btree *btree,
                *keyp = nilfs_btree_node_get_key(btree, right, 0);
                *ptrp = path[level].bp_newreq.bpr_ptr;
 
-               nilfs_bmap_put_block(&btree->bt_bmap, path[level].bp_sib_bh);
+               brelse(path[level].bp_sib_bh);
                path[level].bp_sib_bh = NULL;
        }
 
@@ -897,12 +995,12 @@ static int nilfs_btree_prepare_insert(struct nilfs_btree *btree,
        level = NILFS_BTREE_LEVEL_DATA;
 
        /* allocate a new ptr for data block */
-       if (btree->bt_ops->btop_find_target != NULL)
+       if (NILFS_BMAP_USE_VBN(&btree->bt_bmap))
                path[level].bp_newreq.bpr_ptr =
-                       btree->bt_ops->btop_find_target(btree, path, key);
+                       nilfs_btree_find_target_v(btree, path, key);
 
-       ret = btree->bt_bmap.b_pops->bpop_prepare_alloc_ptr(
-               &btree->bt_bmap, &path[level].bp_newreq);
+       ret = nilfs_bmap_prepare_alloc_ptr(&btree->bt_bmap,
+                                          &path[level].bp_newreq);
        if (ret < 0)
                goto err_out_data;
 
@@ -924,8 +1022,7 @@ static int nilfs_btree_prepare_insert(struct nilfs_btree *btree,
                if (pindex > 0) {
                        sibptr = nilfs_btree_node_get_ptr(btree, parent,
                                                          pindex - 1);
-                       ret = nilfs_bmap_get_block(&btree->bt_bmap, sibptr,
-                                                  &bh);
+                       ret = nilfs_btree_get_block(btree, sibptr, &bh);
                        if (ret < 0)
                                goto err_out_child_node;
                        sib = (struct nilfs_btree_node *)bh->b_data;
@@ -936,7 +1033,7 @@ static int nilfs_btree_prepare_insert(struct nilfs_btree *btree,
                                stats->bs_nblocks++;
                                goto out;
                        } else
-                               nilfs_bmap_put_block(&btree->bt_bmap, bh);
+                               brelse(bh);
                }
 
                /* right sibling */
@@ -944,8 +1041,7 @@ static int nilfs_btree_prepare_insert(struct nilfs_btree *btree,
                    nilfs_btree_node_get_nchildren(btree, parent) - 1) {
                        sibptr = nilfs_btree_node_get_ptr(btree, parent,
                                                          pindex + 1);
-                       ret = nilfs_bmap_get_block(&btree->bt_bmap, sibptr,
-                                                  &bh);
+                       ret = nilfs_btree_get_block(btree, sibptr, &bh);
                        if (ret < 0)
                                goto err_out_child_node;
                        sib = (struct nilfs_btree_node *)bh->b_data;
@@ -956,19 +1052,19 @@ static int nilfs_btree_prepare_insert(struct nilfs_btree *btree,
                                stats->bs_nblocks++;
                                goto out;
                        } else
-                               nilfs_bmap_put_block(&btree->bt_bmap, bh);
+                               brelse(bh);
                }
 
                /* split */
                path[level].bp_newreq.bpr_ptr =
                        path[level - 1].bp_newreq.bpr_ptr + 1;
-               ret = btree->bt_bmap.b_pops->bpop_prepare_alloc_ptr(
-                       &btree->bt_bmap, &path[level].bp_newreq);
+               ret = nilfs_bmap_prepare_alloc_ptr(&btree->bt_bmap,
+                                                  &path[level].bp_newreq);
                if (ret < 0)
                        goto err_out_child_node;
-               ret = nilfs_bmap_get_new_block(&btree->bt_bmap,
-                                              path[level].bp_newreq.bpr_ptr,
-                                              &bh);
+               ret = nilfs_btree_get_new_block(btree,
+                                               path[level].bp_newreq.bpr_ptr,
+                                               &bh);
                if (ret < 0)
                        goto err_out_curr_node;
 
@@ -994,12 +1090,12 @@ static int nilfs_btree_prepare_insert(struct nilfs_btree *btree,
 
        /* grow */
        path[level].bp_newreq.bpr_ptr = path[level - 1].bp_newreq.bpr_ptr + 1;
-       ret = btree->bt_bmap.b_pops->bpop_prepare_alloc_ptr(
-               &btree->bt_bmap, &path[level].bp_newreq);
+       ret = nilfs_bmap_prepare_alloc_ptr(&btree->bt_bmap,
+                                          &path[level].bp_newreq);
        if (ret < 0)
                goto err_out_child_node;
-       ret = nilfs_bmap_get_new_block(&btree->bt_bmap,
-                                      path[level].bp_newreq.bpr_ptr, &bh);
+       ret = nilfs_btree_get_new_block(btree, path[level].bp_newreq.bpr_ptr,
+                                       &bh);
        if (ret < 0)
                goto err_out_curr_node;
 
@@ -1023,18 +1119,16 @@ static int nilfs_btree_prepare_insert(struct nilfs_btree *btree,
 
        /* error */
  err_out_curr_node:
-       btree->bt_bmap.b_pops->bpop_abort_alloc_ptr(&btree->bt_bmap,
-                                                   &path[level].bp_newreq);
+       nilfs_bmap_abort_alloc_ptr(&btree->bt_bmap, &path[level].bp_newreq);
  err_out_child_node:
        for (level--; level > NILFS_BTREE_LEVEL_DATA; level--) {
-               nilfs_bmap_delete_block(&btree->bt_bmap, path[level].bp_sib_bh);
-               btree->bt_bmap.b_pops->bpop_abort_alloc_ptr(
-                       &btree->bt_bmap, &path[level].bp_newreq);
+               nilfs_btnode_delete(path[level].bp_sib_bh);
+               nilfs_bmap_abort_alloc_ptr(&btree->bt_bmap,
+                                          &path[level].bp_newreq);
 
        }
 
-       btree->bt_bmap.b_pops->bpop_abort_alloc_ptr(&btree->bt_bmap,
-                                                      &path[level].bp_newreq);
+       nilfs_bmap_abort_alloc_ptr(&btree->bt_bmap, &path[level].bp_newreq);
  err_out_data:
        *levelp = level;
        stats->bs_nblocks = 0;
@@ -1049,14 +1143,12 @@ static void nilfs_btree_commit_insert(struct nilfs_btree *btree,
 
        set_buffer_nilfs_volatile((struct buffer_head *)((unsigned long)ptr));
        ptr = path[NILFS_BTREE_LEVEL_DATA].bp_newreq.bpr_ptr;
-       if (btree->bt_ops->btop_set_target != NULL)
-               btree->bt_ops->btop_set_target(btree, key, ptr);
+       if (NILFS_BMAP_USE_VBN(&btree->bt_bmap))
+               nilfs_btree_set_target_v(btree, key, ptr);
 
        for (level = NILFS_BTREE_LEVEL_NODE_MIN; level <= maxlevel; level++) {
-               if (btree->bt_bmap.b_pops->bpop_commit_alloc_ptr != NULL) {
-                       btree->bt_bmap.b_pops->bpop_commit_alloc_ptr(
-                               &btree->bt_bmap, &path[level - 1].bp_newreq);
-               }
+               nilfs_bmap_commit_alloc_ptr(&btree->bt_bmap,
+                                           &path[level - 1].bp_newreq);
                path[level].bp_op(btree, path, level, &key, &ptr);
        }
 
@@ -1153,7 +1245,7 @@ static void nilfs_btree_borrow_left(struct nilfs_btree *btree,
        nilfs_btree_promote_key(btree, path, level + 1,
                                nilfs_btree_node_get_key(btree, node, 0));
 
-       nilfs_bmap_put_block(&btree->bt_bmap, path[level].bp_sib_bh);
+       brelse(path[level].bp_sib_bh);
        path[level].bp_sib_bh = NULL;
        path[level].bp_index += n;
 }
@@ -1192,7 +1284,7 @@ static void nilfs_btree_borrow_right(struct nilfs_btree *btree,
                                nilfs_btree_node_get_key(btree, right, 0));
        path[level + 1].bp_index--;
 
-       nilfs_bmap_put_block(&btree->bt_bmap, path[level].bp_sib_bh);
+       brelse(path[level].bp_sib_bh);
        path[level].bp_sib_bh = NULL;
 }
 
@@ -1221,7 +1313,7 @@ static void nilfs_btree_concat_left(struct nilfs_btree *btree,
        unlock_buffer(path[level].bp_bh);
        unlock_buffer(path[level].bp_sib_bh);
 
-       nilfs_bmap_delete_block(&btree->bt_bmap, path[level].bp_bh);
+       nilfs_btnode_delete(path[level].bp_bh);
        path[level].bp_bh = path[level].bp_sib_bh;
        path[level].bp_sib_bh = NULL;
        path[level].bp_index += nilfs_btree_node_get_nchildren(btree, left);
@@ -1252,7 +1344,7 @@ static void nilfs_btree_concat_right(struct nilfs_btree *btree,
        unlock_buffer(path[level].bp_bh);
        unlock_buffer(path[level].bp_sib_bh);
 
-       nilfs_bmap_delete_block(&btree->bt_bmap, path[level].bp_sib_bh);
+       nilfs_btnode_delete(path[level].bp_sib_bh);
        path[level].bp_sib_bh = NULL;
        path[level + 1].bp_index++;
 }
@@ -1276,7 +1368,7 @@ static void nilfs_btree_shrink(struct nilfs_btree *btree,
        nilfs_btree_node_move_left(btree, root, child, n);
        unlock_buffer(path[level].bp_bh);
 
-       nilfs_bmap_delete_block(&btree->bt_bmap, path[level].bp_bh);
+       nilfs_btnode_delete(path[level].bp_bh);
        path[level].bp_bh = NULL;
 }
 
@@ -1300,12 +1392,10 @@ static int nilfs_btree_prepare_delete(struct nilfs_btree *btree,
                path[level].bp_oldreq.bpr_ptr =
                        nilfs_btree_node_get_ptr(btree, node,
                                                 path[level].bp_index);
-               if (btree->bt_bmap.b_pops->bpop_prepare_end_ptr != NULL) {
-                       ret = btree->bt_bmap.b_pops->bpop_prepare_end_ptr(
-                               &btree->bt_bmap, &path[level].bp_oldreq);
-                       if (ret < 0)
-                               goto err_out_child_node;
-               }
+               ret = nilfs_bmap_prepare_end_ptr(&btree->bt_bmap,
+                                                &path[level].bp_oldreq);
+               if (ret < 0)
+                       goto err_out_child_node;
 
                if (nilfs_btree_node_get_nchildren(btree, node) >
                    nilfs_btree_node_nchildren_min(btree, node)) {
@@ -1321,8 +1411,7 @@ static int nilfs_btree_prepare_delete(struct nilfs_btree *btree,
                        /* left sibling */
                        sibptr = nilfs_btree_node_get_ptr(btree, parent,
                                                          pindex - 1);
-                       ret = nilfs_bmap_get_block(&btree->bt_bmap, sibptr,
-                                                  &bh);
+                       ret = nilfs_btree_get_block(btree, sibptr, &bh);
                        if (ret < 0)
                                goto err_out_curr_node;
                        sib = (struct nilfs_btree_node *)bh->b_data;
@@ -1343,8 +1432,7 @@ static int nilfs_btree_prepare_delete(struct nilfs_btree *btree,
                        /* right sibling */
                        sibptr = nilfs_btree_node_get_ptr(btree, parent,
                                                          pindex + 1);
-                       ret = nilfs_bmap_get_block(&btree->bt_bmap, sibptr,
-                                                  &bh);
+                       ret = nilfs_btree_get_block(btree, sibptr, &bh);
                        if (ret < 0)
                                goto err_out_curr_node;
                        sib = (struct nilfs_btree_node *)bh->b_data;
@@ -1381,12 +1469,12 @@ static int nilfs_btree_prepare_delete(struct nilfs_btree *btree,
        node = nilfs_btree_get_root(btree);
        path[level].bp_oldreq.bpr_ptr =
                nilfs_btree_node_get_ptr(btree, node, path[level].bp_index);
-       if (btree->bt_bmap.b_pops->bpop_prepare_end_ptr != NULL) {
-               ret = btree->bt_bmap.b_pops->bpop_prepare_end_ptr(
-                       &btree->bt_bmap, &path[level].bp_oldreq);
-               if (ret < 0)
-                       goto err_out_child_node;
-       }
+
+       ret = nilfs_bmap_prepare_end_ptr(&btree->bt_bmap,
+                                        &path[level].bp_oldreq);
+       if (ret < 0)
+               goto err_out_child_node;
+
        /* child of the root node is deleted */
        path[level].bp_op = nilfs_btree_do_delete;
        stats->bs_nblocks++;
@@ -1398,15 +1486,12 @@ static int nilfs_btree_prepare_delete(struct nilfs_btree *btree,
 
        /* error */
  err_out_curr_node:
-       if (btree->bt_bmap.b_pops->bpop_abort_end_ptr != NULL)
-               btree->bt_bmap.b_pops->bpop_abort_end_ptr(
-                       &btree->bt_bmap, &path[level].bp_oldreq);
+       nilfs_bmap_abort_end_ptr(&btree->bt_bmap, &path[level].bp_oldreq);
  err_out_child_node:
        for (level--; level >= NILFS_BTREE_LEVEL_NODE_MIN; level--) {
-               nilfs_bmap_put_block(&btree->bt_bmap, path[level].bp_sib_bh);
-               if (btree->bt_bmap.b_pops->bpop_abort_end_ptr != NULL)
-                       btree->bt_bmap.b_pops->bpop_abort_end_ptr(
-                               &btree->bt_bmap, &path[level].bp_oldreq);
+               brelse(path[level].bp_sib_bh);
+               nilfs_bmap_abort_end_ptr(&btree->bt_bmap,
+                                        &path[level].bp_oldreq);
        }
        *levelp = level;
        stats->bs_nblocks = 0;
@@ -1420,9 +1505,8 @@ static void nilfs_btree_commit_delete(struct nilfs_btree *btree,
        int level;
 
        for (level = NILFS_BTREE_LEVEL_NODE_MIN; level <= maxlevel; level++) {
-               if (btree->bt_bmap.b_pops->bpop_commit_end_ptr != NULL)
-                       btree->bt_bmap.b_pops->bpop_commit_end_ptr(
-                               &btree->bt_bmap, &path[level].bp_oldreq);
+               nilfs_bmap_commit_end_ptr(&btree->bt_bmap,
+                                         &path[level].bp_oldreq);
                path[level].bp_op(btree, path, level, NULL, NULL);
        }
 
@@ -1501,7 +1585,7 @@ static int nilfs_btree_check_delete(struct nilfs_bmap *bmap, __u64 key)
                if (nchildren > 1)
                        return 0;
                ptr = nilfs_btree_node_get_ptr(btree, root, nchildren - 1);
-               ret = nilfs_bmap_get_block(bmap, ptr, &bh);
+               ret = nilfs_btree_get_block(btree, ptr, &bh);
                if (ret < 0)
                        return ret;
                node = (struct nilfs_btree_node *)bh->b_data;
@@ -1515,9 +1599,9 @@ static int nilfs_btree_check_delete(struct nilfs_bmap *bmap, __u64 key)
        nextmaxkey = (nchildren > 1) ?
                nilfs_btree_node_get_key(btree, node, nchildren - 2) : 0;
        if (bh != NULL)
-               nilfs_bmap_put_block(bmap, bh);
+               brelse(bh);
 
-       return (maxkey == key) && (nextmaxkey < bmap->b_low);
+       return (maxkey == key) && (nextmaxkey < NILFS_BMAP_LARGE_LOW);
 }
 
 static int nilfs_btree_gather_data(struct nilfs_bmap *bmap,
@@ -1542,7 +1626,7 @@ static int nilfs_btree_gather_data(struct nilfs_bmap *bmap,
                nchildren = nilfs_btree_node_get_nchildren(btree, root);
                WARN_ON(nchildren > 1);
                ptr = nilfs_btree_node_get_ptr(btree, root, nchildren - 1);
-               ret = nilfs_bmap_get_block(bmap, ptr, &bh);
+               ret = nilfs_btree_get_block(btree, ptr, &bh);
                if (ret < 0)
                        return ret;
                node = (struct nilfs_btree_node *)bh->b_data;
@@ -1563,7 +1647,7 @@ static int nilfs_btree_gather_data(struct nilfs_bmap *bmap,
        }
 
        if (bh != NULL)
-               nilfs_bmap_put_block(bmap, bh);
+               brelse(bh);
 
        return nitems;
 }
@@ -1584,10 +1668,10 @@ nilfs_btree_prepare_convert_and_insert(struct nilfs_bmap *bmap, __u64 key,
 
        /* for data */
        /* cannot find near ptr */
-       if (btree->bt_ops->btop_find_target != NULL)
-               dreq->bpr_ptr
-                       = btree->bt_ops->btop_find_target(btree, NULL, key);
-       ret = bmap->b_pops->bpop_prepare_alloc_ptr(bmap, dreq);
+       if (NILFS_BMAP_USE_VBN(bmap))
+               dreq->bpr_ptr = nilfs_btree_find_target_v(btree, NULL, key);
+
+       ret = nilfs_bmap_prepare_alloc_ptr(bmap, dreq);
        if (ret < 0)
                return ret;
 
@@ -1595,11 +1679,11 @@ nilfs_btree_prepare_convert_and_insert(struct nilfs_bmap *bmap, __u64 key,
        stats->bs_nblocks++;
        if (nreq != NULL) {
                nreq->bpr_ptr = dreq->bpr_ptr + 1;
-               ret = bmap->b_pops->bpop_prepare_alloc_ptr(bmap, nreq);
+               ret = nilfs_bmap_prepare_alloc_ptr(bmap, nreq);
                if (ret < 0)
                        goto err_out_dreq;
 
-               ret = nilfs_bmap_get_new_block(bmap, nreq->bpr_ptr, &bh);
+               ret = nilfs_btree_get_new_block(btree, nreq->bpr_ptr, &bh);
                if (ret < 0)
                        goto err_out_nreq;
 
@@ -1612,9 +1696,9 @@ nilfs_btree_prepare_convert_and_insert(struct nilfs_bmap *bmap, __u64 key,
 
        /* error */
  err_out_nreq:
-       bmap->b_pops->bpop_abort_alloc_ptr(bmap, nreq);
+       nilfs_bmap_abort_alloc_ptr(bmap, nreq);
  err_out_dreq:
-       bmap->b_pops->bpop_abort_alloc_ptr(bmap, dreq);
+       nilfs_bmap_abort_alloc_ptr(bmap, dreq);
        stats->bs_nblocks = 0;
        return ret;
 
@@ -1624,7 +1708,7 @@ static void
 nilfs_btree_commit_convert_and_insert(struct nilfs_bmap *bmap,
                                      __u64 key, __u64 ptr,
                                      const __u64 *keys, const __u64 *ptrs,
-                                     int n, __u64 low, __u64 high,
+                                     int n,
                                      union nilfs_bmap_ptr_req *dreq,
                                      union nilfs_bmap_ptr_req *nreq,
                                      struct buffer_head *bh)
@@ -1642,12 +1726,10 @@ nilfs_btree_commit_convert_and_insert(struct nilfs_bmap *bmap,
 
        /* convert and insert */
        btree = (struct nilfs_btree *)bmap;
-       nilfs_btree_init(bmap, low, high);
+       nilfs_btree_init(bmap);
        if (nreq != NULL) {
-               if (bmap->b_pops->bpop_commit_alloc_ptr != NULL) {
-                       bmap->b_pops->bpop_commit_alloc_ptr(bmap, dreq);
-                       bmap->b_pops->bpop_commit_alloc_ptr(bmap, nreq);
-               }
+               nilfs_bmap_commit_alloc_ptr(bmap, dreq);
+               nilfs_bmap_commit_alloc_ptr(bmap, nreq);
 
                /* create child node at level 1 */
                lock_buffer(bh);
@@ -1661,7 +1743,7 @@ nilfs_btree_commit_convert_and_insert(struct nilfs_bmap *bmap,
                        nilfs_bmap_set_dirty(bmap);
 
                unlock_buffer(bh);
-               nilfs_bmap_put_block(bmap, bh);
+               brelse(bh);
 
                /* create root node at level 2 */
                node = nilfs_btree_get_root(btree);
@@ -1669,8 +1751,7 @@ nilfs_btree_commit_convert_and_insert(struct nilfs_bmap *bmap,
                nilfs_btree_node_init(btree, node, NILFS_BTREE_NODE_ROOT,
                                      2, 1, &keys[0], &tmpptr);
        } else {
-               if (bmap->b_pops->bpop_commit_alloc_ptr != NULL)
-                       bmap->b_pops->bpop_commit_alloc_ptr(bmap, dreq);
+               nilfs_bmap_commit_alloc_ptr(bmap, dreq);
 
                /* create root node at level 1 */
                node = nilfs_btree_get_root(btree);
@@ -1682,8 +1763,8 @@ nilfs_btree_commit_convert_and_insert(struct nilfs_bmap *bmap,
                        nilfs_bmap_set_dirty(bmap);
        }
 
-       if (btree->bt_ops->btop_set_target != NULL)
-               btree->bt_ops->btop_set_target(btree, key, dreq->bpr_ptr);
+       if (NILFS_BMAP_USE_VBN(bmap))
+               nilfs_btree_set_target_v(btree, key, dreq->bpr_ptr);
 }
 
 /**
@@ -1694,13 +1775,10 @@ nilfs_btree_commit_convert_and_insert(struct nilfs_bmap *bmap,
  * @keys:
  * @ptrs:
  * @n:
- * @low:
- * @high:
  */
 int nilfs_btree_convert_and_insert(struct nilfs_bmap *bmap,
                                   __u64 key, __u64 ptr,
-                                  const __u64 *keys, const __u64 *ptrs,
-                                  int n, __u64 low, __u64 high)
+                                  const __u64 *keys, const __u64 *ptrs, int n)
 {
        struct buffer_head *bh;
        union nilfs_bmap_ptr_req dreq, nreq, *di, *ni;
@@ -1725,7 +1803,7 @@ int nilfs_btree_convert_and_insert(struct nilfs_bmap *bmap,
        if (ret < 0)
                return ret;
        nilfs_btree_commit_convert_and_insert(bmap, key, ptr, keys, ptrs, n,
-                                             low, high, di, ni, bh);
+                                             di, ni, bh);
        nilfs_bmap_add_blocks(bmap, stats.bs_nblocks);
        return 0;
 }
@@ -1754,9 +1832,9 @@ static int nilfs_btree_prepare_update_v(struct nilfs_btree *btree,
                nilfs_btree_node_get_ptr(btree, parent,
                                         path[level + 1].bp_index);
        path[level].bp_newreq.bpr_ptr = path[level].bp_oldreq.bpr_ptr + 1;
-       ret = nilfs_bmap_prepare_update(&btree->bt_bmap,
-                                       &path[level].bp_oldreq,
-                                       &path[level].bp_newreq);
+       ret = nilfs_bmap_prepare_update_v(&btree->bt_bmap,
+                                         &path[level].bp_oldreq,
+                                         &path[level].bp_newreq);
        if (ret < 0)
                return ret;
 
@@ -1768,9 +1846,9 @@ static int nilfs_btree_prepare_update_v(struct nilfs_btree *btree,
                        &NILFS_BMAP_I(&btree->bt_bmap)->i_btnode_cache,
                        &path[level].bp_ctxt);
                if (ret < 0) {
-                       nilfs_bmap_abort_update(&btree->bt_bmap,
-                                               &path[level].bp_oldreq,
-                                               &path[level].bp_newreq);
+                       nilfs_bmap_abort_update_v(&btree->bt_bmap,
+                                                 &path[level].bp_oldreq,
+                                                 &path[level].bp_newreq);
                        return ret;
                }
        }
@@ -1784,9 +1862,9 @@ static void nilfs_btree_commit_update_v(struct nilfs_btree *btree,
 {
        struct nilfs_btree_node *parent;
 
-       nilfs_bmap_commit_update(&btree->bt_bmap,
-                                &path[level].bp_oldreq,
-                                &path[level].bp_newreq);
+       nilfs_bmap_commit_update_v(&btree->bt_bmap,
+                                  &path[level].bp_oldreq,
+                                  &path[level].bp_newreq);
 
        if (buffer_nilfs_node(path[level].bp_bh)) {
                nilfs_btnode_commit_change_key(
@@ -1805,9 +1883,9 @@ static void nilfs_btree_abort_update_v(struct nilfs_btree *btree,
                                       struct nilfs_btree_path *path,
                                       int level)
 {
-       nilfs_bmap_abort_update(&btree->bt_bmap,
-                               &path[level].bp_oldreq,
-                               &path[level].bp_newreq);
+       nilfs_bmap_abort_update_v(&btree->bt_bmap,
+                                 &path[level].bp_oldreq,
+                                 &path[level].bp_newreq);
        if (buffer_nilfs_node(path[level].bp_bh))
                nilfs_btnode_abort_change_key(
                        &NILFS_BMAP_I(&btree->bt_bmap)->i_btnode_cache,
@@ -1930,7 +2008,9 @@ static int nilfs_btree_propagate(const struct nilfs_bmap *bmap,
                goto out;
        }
 
-       ret = btree->bt_ops->btop_propagate(btree, path, level, bh);
+       ret = NILFS_BMAP_USE_VBN(bmap) ?
+               nilfs_btree_propagate_v(btree, path, level, bh) :
+               nilfs_btree_propagate_p(btree, path, level, bh);
 
  out:
        nilfs_btree_clear_path(btree, path);
@@ -2066,12 +2146,9 @@ static int nilfs_btree_assign_v(struct nilfs_btree *btree,
        ptr = nilfs_btree_node_get_ptr(btree, parent,
                                       path[level + 1].bp_index);
        req.bpr_ptr = ptr;
-       ret = btree->bt_bmap.b_pops->bpop_prepare_start_ptr(&btree->bt_bmap,
-                                                              &req);
-       if (ret < 0)
+       ret = nilfs_bmap_start_v(&btree->bt_bmap, &req, blocknr);
+       if (unlikely(ret < 0))
                return ret;
-       btree->bt_bmap.b_pops->bpop_commit_start_ptr(&btree->bt_bmap,
-                                                       &req, blocknr);
 
        key = nilfs_btree_node_get_key(btree, parent,
                                       path[level + 1].bp_index);
@@ -2114,8 +2191,9 @@ static int nilfs_btree_assign(struct nilfs_bmap *bmap,
                goto out;
        }
 
-       ret = btree->bt_ops->btop_assign(btree, path, level, bh,
-                                           blocknr, binfo);
+       ret = NILFS_BMAP_USE_VBN(bmap) ?
+               nilfs_btree_assign_v(btree, path, level, bh, blocknr, binfo) :
+               nilfs_btree_assign_p(btree, path, level, bh, blocknr, binfo);
 
  out:
        nilfs_btree_clear_path(btree, path);
@@ -2171,7 +2249,7 @@ static int nilfs_btree_mark(struct nilfs_bmap *bmap, __u64 key, int level)
                WARN_ON(ret == -ENOENT);
                goto out;
        }
-       ret = nilfs_bmap_get_block(&btree->bt_bmap, ptr, &bh);
+       ret = nilfs_btree_get_block(btree, ptr, &bh);
        if (ret < 0) {
                WARN_ON(ret == -ENOENT);
                goto out;
@@ -2179,7 +2257,7 @@ static int nilfs_btree_mark(struct nilfs_bmap *bmap, __u64 key, int level)
 
        if (!buffer_dirty(bh))
                nilfs_btnode_mark_dirty(bh);
-       nilfs_bmap_put_block(&btree->bt_bmap, bh);
+       brelse(bh);
        if (!nilfs_bmap_dirty(&btree->bt_bmap))
                nilfs_bmap_set_dirty(&btree->bt_bmap);
 
@@ -2191,6 +2269,7 @@ static int nilfs_btree_mark(struct nilfs_bmap *bmap, __u64 key, int level)
 
 static const struct nilfs_bmap_operations nilfs_btree_ops = {
        .bop_lookup             =       nilfs_btree_lookup,
+       .bop_lookup_contig      =       nilfs_btree_lookup_contig,
        .bop_insert             =       nilfs_btree_insert,
        .bop_delete             =       nilfs_btree_delete,
        .bop_clear              =       NULL,
@@ -2210,6 +2289,7 @@ static const struct nilfs_bmap_operations nilfs_btree_ops = {
 
 static const struct nilfs_bmap_operations nilfs_btree_ops_gc = {
        .bop_lookup             =       NULL,
+       .bop_lookup_contig      =       NULL,
        .bop_insert             =       NULL,
        .bop_delete             =       NULL,
        .bop_clear              =       NULL,
@@ -2227,43 +2307,13 @@ static const struct nilfs_bmap_operations nilfs_btree_ops_gc = {
        .bop_gather_data        =       NULL,
 };
 
-static const struct nilfs_btree_operations nilfs_btree_ops_v = {
-       .btop_find_target       =       nilfs_btree_find_target_v,
-       .btop_set_target        =       nilfs_btree_set_target_v,
-       .btop_propagate         =       nilfs_btree_propagate_v,
-       .btop_assign            =       nilfs_btree_assign_v,
-};
-
-static const struct nilfs_btree_operations nilfs_btree_ops_p = {
-       .btop_find_target       =       NULL,
-       .btop_set_target        =       NULL,
-       .btop_propagate         =       nilfs_btree_propagate_p,
-       .btop_assign            =       nilfs_btree_assign_p,
-};
-
-int nilfs_btree_init(struct nilfs_bmap *bmap, __u64 low, __u64 high)
+int nilfs_btree_init(struct nilfs_bmap *bmap)
 {
-       struct nilfs_btree *btree;
-
-       btree = (struct nilfs_btree *)bmap;
        bmap->b_ops = &nilfs_btree_ops;
-       bmap->b_low = low;
-       bmap->b_high = high;
-       switch (bmap->b_inode->i_ino) {
-       case NILFS_DAT_INO:
-               btree->bt_ops = &nilfs_btree_ops_p;
-               break;
-       default:
-               btree->bt_ops = &nilfs_btree_ops_v;
-               break;
-       }
-
        return 0;
 }
 
 void nilfs_btree_init_gc(struct nilfs_bmap *bmap)
 {
-       bmap->b_low = NILFS_BMAP_LARGE_LOW;
-       bmap->b_high = NILFS_BMAP_LARGE_HIGH;
        bmap->b_ops = &nilfs_btree_ops_gc;
 }
index 4766deb52fb165f457255d4579381fe641550268..0e72bbbc6b648bb1a420f735fedaafe11b3d29ab 100644 (file)
 struct nilfs_btree;
 struct nilfs_btree_path;
 
-/**
- * struct nilfs_btree_operations - B-tree operation table
- */
-struct nilfs_btree_operations {
-       __u64 (*btop_find_target)(const struct nilfs_btree *,
-                                 const struct nilfs_btree_path *, __u64);
-       void (*btop_set_target)(struct nilfs_btree *, __u64, __u64);
-
-       struct the_nilfs *(*btop_get_nilfs)(struct nilfs_btree *);
-
-       int (*btop_propagate)(struct nilfs_btree *,
-                             struct nilfs_btree_path *,
-                             int,
-                             struct buffer_head *);
-       int (*btop_assign)(struct nilfs_btree *,
-                          struct nilfs_btree_path *,
-                          int,
-                          struct buffer_head **,
-                          sector_t,
-                          union nilfs_binfo *);
-};
-
 /**
  * struct nilfs_btree_node - B-tree node
  * @bn_flags: flags
@@ -80,13 +58,9 @@ struct nilfs_btree_node {
 /**
  * struct nilfs_btree - B-tree structure
  * @bt_bmap: bmap base structure
- * @bt_ops: B-tree operation table
  */
 struct nilfs_btree {
        struct nilfs_bmap bt_bmap;
-
-       /* B-tree-specific members */
-       const struct nilfs_btree_operations *bt_ops;
 };
 
 
@@ -108,10 +82,9 @@ struct nilfs_btree {
 
 int nilfs_btree_path_cache_init(void);
 void nilfs_btree_path_cache_destroy(void);
-int nilfs_btree_init(struct nilfs_bmap *, __u64, __u64);
+int nilfs_btree_init(struct nilfs_bmap *);
 int nilfs_btree_convert_and_insert(struct nilfs_bmap *, __u64, __u64,
-                                  const __u64 *, const __u64 *,
-                                  int, __u64, __u64);
+                                  const __u64 *, const __u64 *, int);
 void nilfs_btree_init_gc(struct nilfs_bmap *);
 
 #endif /* _NILFS_BTREE_H */
index cadd36b14d07058d9521b0f753f3411e5b5a388a..7d49813f66d6c157d95c9ec8f6568379fa71565c 100644 (file)
@@ -295,10 +295,6 @@ int nilfs_cpfile_delete_checkpoints(struct inode *cpfile,
                return -EINVAL;
        }
 
-       /* cannot delete the latest checkpoint */
-       if (start == nilfs_mdt_cno(cpfile) - 1)
-               return -EPERM;
-
        down_write(&NILFS_MDT(cpfile)->mi_sem);
 
        ret = nilfs_cpfile_get_header_block(cpfile, &header_bh);
@@ -384,9 +380,10 @@ static void nilfs_cpfile_checkpoint_to_cpinfo(struct inode *cpfile,
 }
 
 static ssize_t nilfs_cpfile_do_get_cpinfo(struct inode *cpfile, __u64 *cnop,
-                                         struct nilfs_cpinfo *ci, size_t nci)
+                                         void *buf, unsigned cisz, size_t nci)
 {
        struct nilfs_checkpoint *cp;
+       struct nilfs_cpinfo *ci = buf;
        struct buffer_head *bh;
        size_t cpsz = NILFS_MDT(cpfile)->mi_entry_size;
        __u64 cur_cno = nilfs_mdt_cno(cpfile), cno = *cnop;
@@ -410,17 +407,22 @@ static ssize_t nilfs_cpfile_do_get_cpinfo(struct inode *cpfile, __u64 *cnop,
                kaddr = kmap_atomic(bh->b_page, KM_USER0);
                cp = nilfs_cpfile_block_get_checkpoint(cpfile, cno, bh, kaddr);
                for (i = 0; i < ncps && n < nci; i++, cp = (void *)cp + cpsz) {
-                       if (!nilfs_checkpoint_invalid(cp))
-                               nilfs_cpfile_checkpoint_to_cpinfo(
-                                       cpfile, cp, &ci[n++]);
+                       if (!nilfs_checkpoint_invalid(cp)) {
+                               nilfs_cpfile_checkpoint_to_cpinfo(cpfile, cp,
+                                                                 ci);
+                               ci = (void *)ci + cisz;
+                               n++;
+                       }
                }
                kunmap_atomic(kaddr, KM_USER0);
                brelse(bh);
        }
 
        ret = n;
-       if (n > 0)
-               *cnop = ci[n - 1].ci_cno + 1;
+       if (n > 0) {
+               ci = (void *)ci - cisz;
+               *cnop = ci->ci_cno + 1;
+       }
 
  out:
        up_read(&NILFS_MDT(cpfile)->mi_sem);
@@ -428,11 +430,12 @@ static ssize_t nilfs_cpfile_do_get_cpinfo(struct inode *cpfile, __u64 *cnop,
 }
 
 static ssize_t nilfs_cpfile_do_get_ssinfo(struct inode *cpfile, __u64 *cnop,
-                                         struct nilfs_cpinfo *ci, size_t nci)
+                                         void *buf, unsigned cisz, size_t nci)
 {
        struct buffer_head *bh;
        struct nilfs_cpfile_header *header;
        struct nilfs_checkpoint *cp;
+       struct nilfs_cpinfo *ci = buf;
        __u64 curr = *cnop, next;
        unsigned long curr_blkoff, next_blkoff;
        void *kaddr;
@@ -472,7 +475,9 @@ static ssize_t nilfs_cpfile_do_get_ssinfo(struct inode *cpfile, __u64 *cnop,
                if (unlikely(nilfs_checkpoint_invalid(cp) ||
                             !nilfs_checkpoint_snapshot(cp)))
                        break;
-               nilfs_cpfile_checkpoint_to_cpinfo(cpfile, cp, &ci[n++]);
+               nilfs_cpfile_checkpoint_to_cpinfo(cpfile, cp, ci);
+               ci = (void *)ci + cisz;
+               n++;
                next = le64_to_cpu(cp->cp_snapshot_list.ssl_next);
                if (next == 0)
                        break; /* reach end of the snapshot list */
@@ -511,13 +516,13 @@ static ssize_t nilfs_cpfile_do_get_ssinfo(struct inode *cpfile, __u64 *cnop,
  */
 
 ssize_t nilfs_cpfile_get_cpinfo(struct inode *cpfile, __u64 *cnop, int mode,
-                               struct nilfs_cpinfo *ci, size_t nci)
+                               void *buf, unsigned cisz, size_t nci)
 {
        switch (mode) {
        case NILFS_CHECKPOINT:
-               return nilfs_cpfile_do_get_cpinfo(cpfile, cnop, ci, nci);
+               return nilfs_cpfile_do_get_cpinfo(cpfile, cnop, buf, cisz, nci);
        case NILFS_SNAPSHOT:
-               return nilfs_cpfile_do_get_ssinfo(cpfile, cnop, ci, nci);
+               return nilfs_cpfile_do_get_ssinfo(cpfile, cnop, buf, cisz, nci);
        default:
                return -EINVAL;
        }
@@ -533,20 +538,14 @@ int nilfs_cpfile_delete_checkpoint(struct inode *cpfile, __u64 cno)
        struct nilfs_cpinfo ci;
        __u64 tcno = cno;
        ssize_t nci;
-       int ret;
 
-       nci = nilfs_cpfile_do_get_cpinfo(cpfile, &tcno, &ci, 1);
+       nci = nilfs_cpfile_do_get_cpinfo(cpfile, &tcno, &ci, sizeof(ci), 1);
        if (nci < 0)
                return nci;
        else if (nci == 0 || ci.ci_cno != cno)
                return -ENOENT;
-
-       /* cannot delete the latest checkpoint nor snapshots */
-       ret = nilfs_cpinfo_snapshot(&ci);
-       if (ret < 0)
-               return ret;
-       else if (ret > 0 || cno == nilfs_mdt_cno(cpfile) - 1)
-               return -EPERM;
+       else if (nilfs_cpinfo_snapshot(&ci))
+               return -EBUSY;
 
        return nilfs_cpfile_delete_checkpoints(cpfile, cno, cno + 1);
 }
index 1a8a1008c3420c9d6b2798c00c1025c031434c48..788a45950197c3299b03e1985e31b0b349053efa 100644 (file)
@@ -39,7 +39,7 @@ int nilfs_cpfile_delete_checkpoint(struct inode *, __u64);
 int nilfs_cpfile_change_cpmode(struct inode *, __u64, int);
 int nilfs_cpfile_is_snapshot(struct inode *, __u64);
 int nilfs_cpfile_get_stat(struct inode *, struct nilfs_cpstat *);
-ssize_t nilfs_cpfile_get_cpinfo(struct inode *, __u64 *, int,
-                               struct nilfs_cpinfo *, size_t);
+ssize_t nilfs_cpfile_get_cpinfo(struct inode *, __u64 *, int, void *, unsigned,
+                               size_t);
 
 #endif /* _NILFS_CPFILE_H */
index bb8a5818e7f119d46ffbbb6b3309f523a6dc060d..0b2710e2d56547ac7aa36b6367e5ed6f36685c49 100644 (file)
@@ -92,21 +92,6 @@ void nilfs_dat_abort_alloc(struct inode *dat, struct nilfs_palloc_req *req)
        nilfs_palloc_abort_alloc_entry(dat, req);
 }
 
-int nilfs_dat_prepare_free(struct inode *dat, struct nilfs_palloc_req *req)
-{
-       int ret;
-
-       ret = nilfs_palloc_prepare_free_entry(dat, req);
-       if (ret < 0)
-               return ret;
-       ret = nilfs_dat_prepare_entry(dat, req, 0);
-       if (ret < 0) {
-               nilfs_palloc_abort_free_entry(dat, req);
-               return ret;
-       }
-       return 0;
-}
-
 void nilfs_dat_commit_free(struct inode *dat, struct nilfs_palloc_req *req)
 {
        struct nilfs_dat_entry *entry;
@@ -391,36 +376,37 @@ int nilfs_dat_translate(struct inode *dat, __u64 vblocknr, sector_t *blocknrp)
        return ret;
 }
 
-ssize_t nilfs_dat_get_vinfo(struct inode *dat, struct nilfs_vinfo *vinfo,
+ssize_t nilfs_dat_get_vinfo(struct inode *dat, void *buf, unsigned visz,
                            size_t nvi)
 {
        struct buffer_head *entry_bh;
        struct nilfs_dat_entry *entry;
+       struct nilfs_vinfo *vinfo = buf;
        __u64 first, last;
        void *kaddr;
        unsigned long entries_per_block = NILFS_MDT(dat)->mi_entries_per_block;
        int i, j, n, ret;
 
        for (i = 0; i < nvi; i += n) {
-               ret = nilfs_palloc_get_entry_block(dat, vinfo[i].vi_vblocknr,
+               ret = nilfs_palloc_get_entry_block(dat, vinfo->vi_vblocknr,
                                                   0, &entry_bh);
                if (ret < 0)
                        return ret;
                kaddr = kmap_atomic(entry_bh->b_page, KM_USER0);
                /* last virtual block number in this block */
-               first = vinfo[i].vi_vblocknr;
+               first = vinfo->vi_vblocknr;
                do_div(first, entries_per_block);
                first *= entries_per_block;
                last = first + entries_per_block - 1;
                for (j = i, n = 0;
-                    j < nvi && vinfo[j].vi_vblocknr >= first &&
-                            vinfo[j].vi_vblocknr <= last;
-                    j++, n++) {
+                    j < nvi && vinfo->vi_vblocknr >= first &&
+                            vinfo->vi_vblocknr <= last;
+                    j++, n++, vinfo = (void *)vinfo + visz) {
                        entry = nilfs_palloc_block_get_entry(
-                               dat, vinfo[j].vi_vblocknr, entry_bh, kaddr);
-                       vinfo[j].vi_start = le64_to_cpu(entry->de_start);
-                       vinfo[j].vi_end = le64_to_cpu(entry->de_end);
-                       vinfo[j].vi_blocknr = le64_to_cpu(entry->de_blocknr);
+                               dat, vinfo->vi_vblocknr, entry_bh, kaddr);
+                       vinfo->vi_start = le64_to_cpu(entry->de_start);
+                       vinfo->vi_end = le64_to_cpu(entry->de_end);
+                       vinfo->vi_blocknr = le64_to_cpu(entry->de_blocknr);
                }
                kunmap_atomic(kaddr, KM_USER0);
                brelse(entry_bh);
index d9560654a4b7c5c856d50670b2b7de9f2d584065..d328b81eead403311d599f2f8a45694be3044e0a 100644 (file)
@@ -47,6 +47,6 @@ void nilfs_dat_abort_end(struct inode *, struct nilfs_palloc_req *);
 int nilfs_dat_mark_dirty(struct inode *, __u64);
 int nilfs_dat_freev(struct inode *, __u64 *, size_t);
 int nilfs_dat_move(struct inode *, __u64, sector_t);
-ssize_t nilfs_dat_get_vinfo(struct inode *, struct nilfs_vinfo *, size_t);
+ssize_t nilfs_dat_get_vinfo(struct inode *, void *, unsigned, size_t);
 
 #endif /* _NILFS_DAT_H */
index c6379e482781542aee0f479df8371b7da95744b0..342d9765df8df2bab8ca8a57869f77bc57f739e5 100644 (file)
@@ -25,6 +25,7 @@
 #include "page.h"
 #include "direct.h"
 #include "alloc.h"
+#include "dat.h"
 
 static inline __le64 *nilfs_direct_dptrs(const struct nilfs_direct *direct)
 {
@@ -62,6 +63,47 @@ static int nilfs_direct_lookup(const struct nilfs_bmap *bmap,
        return 0;
 }
 
+static int nilfs_direct_lookup_contig(const struct nilfs_bmap *bmap,
+                                     __u64 key, __u64 *ptrp,
+                                     unsigned maxblocks)
+{
+       struct nilfs_direct *direct = (struct nilfs_direct *)bmap;
+       struct inode *dat = NULL;
+       __u64 ptr, ptr2;
+       sector_t blocknr;
+       int ret, cnt;
+
+       if (key > NILFS_DIRECT_KEY_MAX ||
+           (ptr = nilfs_direct_get_ptr(direct, key)) ==
+           NILFS_BMAP_INVALID_PTR)
+               return -ENOENT;
+
+       if (NILFS_BMAP_USE_VBN(bmap)) {
+               dat = nilfs_bmap_get_dat(bmap);
+               ret = nilfs_dat_translate(dat, ptr, &blocknr);
+               if (ret < 0)
+                       return ret;
+               ptr = blocknr;
+       }
+
+       maxblocks = min_t(unsigned, maxblocks, NILFS_DIRECT_KEY_MAX - key + 1);
+       for (cnt = 1; cnt < maxblocks &&
+                    (ptr2 = nilfs_direct_get_ptr(direct, key + cnt)) !=
+                    NILFS_BMAP_INVALID_PTR;
+            cnt++) {
+               if (dat) {
+                       ret = nilfs_dat_translate(dat, ptr2, &blocknr);
+                       if (ret < 0)
+                               return ret;
+                       ptr2 = blocknr;
+               }
+               if (ptr2 != ptr + cnt)
+                       break;
+       }
+       *ptrp = ptr;
+       return cnt;
+}
+
 static __u64
 nilfs_direct_find_target_v(const struct nilfs_direct *direct, __u64 key)
 {
@@ -90,10 +132,9 @@ static int nilfs_direct_prepare_insert(struct nilfs_direct *direct,
 {
        int ret;
 
-       if (direct->d_ops->dop_find_target != NULL)
-               req->bpr_ptr = direct->d_ops->dop_find_target(direct, key);
-       ret = direct->d_bmap.b_pops->bpop_prepare_alloc_ptr(&direct->d_bmap,
-                                                              req);
+       if (NILFS_BMAP_USE_VBN(&direct->d_bmap))
+               req->bpr_ptr = nilfs_direct_find_target_v(direct, key);
+       ret = nilfs_bmap_prepare_alloc_ptr(&direct->d_bmap, req);
        if (ret < 0)
                return ret;
 
@@ -111,16 +152,14 @@ static void nilfs_direct_commit_insert(struct nilfs_direct *direct,
        bh = (struct buffer_head *)((unsigned long)ptr);
        set_buffer_nilfs_volatile(bh);
 
-       if (direct->d_bmap.b_pops->bpop_commit_alloc_ptr != NULL)
-               direct->d_bmap.b_pops->bpop_commit_alloc_ptr(
-                       &direct->d_bmap, req);
+       nilfs_bmap_commit_alloc_ptr(&direct->d_bmap, req);
        nilfs_direct_set_ptr(direct, key, req->bpr_ptr);
 
        if (!nilfs_bmap_dirty(&direct->d_bmap))
                nilfs_bmap_set_dirty(&direct->d_bmap);
 
-       if (direct->d_ops->dop_set_target != NULL)
-               direct->d_ops->dop_set_target(direct, key, req->bpr_ptr);
+       if (NILFS_BMAP_USE_VBN(&direct->d_bmap))
+               nilfs_direct_set_target_v(direct, key, req->bpr_ptr);
 }
 
 static int nilfs_direct_insert(struct nilfs_bmap *bmap, __u64 key, __u64 ptr)
@@ -152,25 +191,18 @@ static int nilfs_direct_prepare_delete(struct nilfs_direct *direct,
 {
        int ret;
 
-       if (direct->d_bmap.b_pops->bpop_prepare_end_ptr != NULL) {
-               req->bpr_ptr = nilfs_direct_get_ptr(direct, key);
-               ret = direct->d_bmap.b_pops->bpop_prepare_end_ptr(
-                       &direct->d_bmap, req);
-               if (ret < 0)
-                       return ret;
-       }
-
-       stats->bs_nblocks = 1;
-       return 0;
+       req->bpr_ptr = nilfs_direct_get_ptr(direct, key);
+       ret = nilfs_bmap_prepare_end_ptr(&direct->d_bmap, req);
+       if (!ret)
+               stats->bs_nblocks = 1;
+       return ret;
 }
 
 static void nilfs_direct_commit_delete(struct nilfs_direct *direct,
                                       union nilfs_bmap_ptr_req *req,
                                       __u64 key)
 {
-       if (direct->d_bmap.b_pops->bpop_commit_end_ptr != NULL)
-               direct->d_bmap.b_pops->bpop_commit_end_ptr(
-                       &direct->d_bmap, req);
+       nilfs_bmap_commit_end_ptr(&direct->d_bmap, req);
        nilfs_direct_set_ptr(direct, key, NILFS_BMAP_INVALID_PTR);
 }
 
@@ -244,8 +276,7 @@ static int nilfs_direct_gather_data(struct nilfs_bmap *bmap,
 }
 
 int nilfs_direct_delete_and_convert(struct nilfs_bmap *bmap,
-                                   __u64 key, __u64 *keys, __u64 *ptrs,
-                                   int n, __u64 low, __u64 high)
+                                   __u64 key, __u64 *keys, __u64 *ptrs, int n)
 {
        struct nilfs_direct *direct;
        __le64 *dptrs;
@@ -275,8 +306,7 @@ int nilfs_direct_delete_and_convert(struct nilfs_bmap *bmap,
                        dptrs[i] = NILFS_BMAP_INVALID_PTR;
        }
 
-       nilfs_direct_init(bmap, low, high);
-
+       nilfs_direct_init(bmap);
        return 0;
 }
 
@@ -293,11 +323,11 @@ static int nilfs_direct_propagate_v(struct nilfs_direct *direct,
        if (!buffer_nilfs_volatile(bh)) {
                oldreq.bpr_ptr = ptr;
                newreq.bpr_ptr = ptr;
-               ret = nilfs_bmap_prepare_update(&direct->d_bmap, &oldreq,
-                                               &newreq);
+               ret = nilfs_bmap_prepare_update_v(&direct->d_bmap, &oldreq,
+                                                 &newreq);
                if (ret < 0)
                        return ret;
-               nilfs_bmap_commit_update(&direct->d_bmap, &oldreq, &newreq);
+               nilfs_bmap_commit_update_v(&direct->d_bmap, &oldreq, &newreq);
                set_buffer_nilfs_volatile(bh);
                nilfs_direct_set_ptr(direct, key, newreq.bpr_ptr);
        } else
@@ -309,12 +339,10 @@ static int nilfs_direct_propagate_v(struct nilfs_direct *direct,
 static int nilfs_direct_propagate(const struct nilfs_bmap *bmap,
                                  struct buffer_head *bh)
 {
-       struct nilfs_direct *direct;
+       struct nilfs_direct *direct = (struct nilfs_direct *)bmap;
 
-       direct = (struct nilfs_direct *)bmap;
-       return (direct->d_ops->dop_propagate != NULL) ?
-               direct->d_ops->dop_propagate(direct, bh) :
-               0;
+       return NILFS_BMAP_USE_VBN(bmap) ?
+               nilfs_direct_propagate_v(direct, bh) : 0;
 }
 
 static int nilfs_direct_assign_v(struct nilfs_direct *direct,
@@ -327,12 +355,9 @@ static int nilfs_direct_assign_v(struct nilfs_direct *direct,
        int ret;
 
        req.bpr_ptr = ptr;
-       ret = direct->d_bmap.b_pops->bpop_prepare_start_ptr(
-               &direct->d_bmap, &req);
-       if (ret < 0)
+       ret = nilfs_bmap_start_v(&direct->d_bmap, &req, blocknr);
+       if (unlikely(ret < 0))
                return ret;
-       direct->d_bmap.b_pops->bpop_commit_start_ptr(&direct->d_bmap,
-                                                    &req, blocknr);
 
        binfo->bi_v.bi_vblocknr = nilfs_bmap_ptr_to_dptr(ptr);
        binfo->bi_v.bi_blkoff = nilfs_bmap_key_to_dkey(key);
@@ -377,12 +402,14 @@ static int nilfs_direct_assign(struct nilfs_bmap *bmap,
                return -EINVAL;
        }
 
-       return direct->d_ops->dop_assign(direct, key, ptr, bh,
-                                        blocknr, binfo);
+       return NILFS_BMAP_USE_VBN(bmap) ?
+               nilfs_direct_assign_v(direct, key, ptr, bh, blocknr, binfo) :
+               nilfs_direct_assign_p(direct, key, ptr, bh, blocknr, binfo);
 }
 
 static const struct nilfs_bmap_operations nilfs_direct_ops = {
        .bop_lookup             =       nilfs_direct_lookup,
+       .bop_lookup_contig      =       nilfs_direct_lookup_contig,
        .bop_insert             =       nilfs_direct_insert,
        .bop_delete             =       nilfs_direct_delete,
        .bop_clear              =       NULL,
@@ -401,36 +428,8 @@ static const struct nilfs_bmap_operations nilfs_direct_ops = {
 };
 
 
-static const struct nilfs_direct_operations nilfs_direct_ops_v = {
-       .dop_find_target        =       nilfs_direct_find_target_v,
-       .dop_set_target         =       nilfs_direct_set_target_v,
-       .dop_propagate          =       nilfs_direct_propagate_v,
-       .dop_assign             =       nilfs_direct_assign_v,
-};
-
-static const struct nilfs_direct_operations nilfs_direct_ops_p = {
-       .dop_find_target        =       NULL,
-       .dop_set_target         =       NULL,
-       .dop_propagate          =       NULL,
-       .dop_assign             =       nilfs_direct_assign_p,
-};
-
-int nilfs_direct_init(struct nilfs_bmap *bmap, __u64 low, __u64 high)
+int nilfs_direct_init(struct nilfs_bmap *bmap)
 {
-       struct nilfs_direct *direct;
-
-       direct = (struct nilfs_direct *)bmap;
        bmap->b_ops = &nilfs_direct_ops;
-       bmap->b_low = low;
-       bmap->b_high = high;
-       switch (bmap->b_inode->i_ino) {
-       case NILFS_DAT_INO:
-               direct->d_ops = &nilfs_direct_ops_p;
-               break;
-       default:
-               direct->d_ops = &nilfs_direct_ops_v;
-               break;
-       }
-
        return 0;
 }
index 45d2c5cda8120682e182c526afdecd4acb647aec..a5ffd66e25d04b7a014b583b49287803f58e40c3 100644 (file)
 
 struct nilfs_direct;
 
-/**
- * struct nilfs_direct_operations - direct mapping operation table
- */
-struct nilfs_direct_operations {
-       __u64 (*dop_find_target)(const struct nilfs_direct *, __u64);
-       void (*dop_set_target)(struct nilfs_direct *, __u64, __u64);
-       int (*dop_propagate)(struct nilfs_direct *, struct buffer_head *);
-       int (*dop_assign)(struct nilfs_direct *, __u64, __u64,
-                         struct buffer_head **, sector_t,
-                         union nilfs_binfo *);
-};
-
 /**
  * struct nilfs_direct_node - direct node
  * @dn_flags: flags
@@ -55,13 +43,9 @@ struct nilfs_direct_node {
 /**
  * struct nilfs_direct - direct mapping
  * @d_bmap: bmap structure
- * @d_ops: direct mapping operation table
  */
 struct nilfs_direct {
        struct nilfs_bmap d_bmap;
-
-       /* direct-mapping-specific members */
-       const struct nilfs_direct_operations *d_ops;
 };
 
 
@@ -70,9 +54,9 @@ struct nilfs_direct {
 #define NILFS_DIRECT_KEY_MAX   (NILFS_DIRECT_NBLOCKS - 1)
 
 
-int nilfs_direct_init(struct nilfs_bmap *, __u64, __u64);
+int nilfs_direct_init(struct nilfs_bmap *);
 int nilfs_direct_delete_and_convert(struct nilfs_bmap *, __u64, __u64 *,
-                                   __u64 *, int, __u64, __u64);
+                                   __u64 *, int);
 
 
 #endif /* _NILFS_DIRECT_H */
index 19d2102b6a69ee09fa0d7b7a819b96e31c51e903..1b3c2bb20da92665c84fe3ca3a0ab85399865cce 100644 (file)
@@ -52,8 +52,9 @@
 #include "dat.h"
 #include "ifile.h"
 
-static struct address_space_operations def_gcinode_aops = {};
-/* XXX need def_gcinode_iops/fops? */
+static struct address_space_operations def_gcinode_aops = {
+       .sync_page              = block_sync_page,
+};
 
 /*
  * nilfs_gccache_submit_read_data() - add data buffer and submit read request
index 49ab4a49bb4faa121e2a7e03f6869ae79841b201..2696d6b513b7177d2efb9c2805ca878ebf0277a3 100644 (file)
  *
  * This function does not issue actual read request of the specified data
  * block. It is done by VFS.
- * Bulk read for direct-io is not supported yet. (should be supported)
  */
 int nilfs_get_block(struct inode *inode, sector_t blkoff,
                    struct buffer_head *bh_result, int create)
 {
        struct nilfs_inode_info *ii = NILFS_I(inode);
-       unsigned long blknum = 0;
+       __u64 blknum = 0;
        int err = 0, ret;
        struct inode *dat = nilfs_dat_inode(NILFS_I_NILFS(inode));
+       unsigned maxblocks = bh_result->b_size >> inode->i_blkbits;
 
-       /* This exclusion control is a workaround; should be revised */
-       down_read(&NILFS_MDT(dat)->mi_sem);     /* XXX */
-       ret = nilfs_bmap_lookup(ii->i_bmap, (unsigned long)blkoff, &blknum);
-       up_read(&NILFS_MDT(dat)->mi_sem);       /* XXX */
-       if (ret == 0) { /* found */
+       down_read(&NILFS_MDT(dat)->mi_sem);
+       ret = nilfs_bmap_lookup_contig(ii->i_bmap, blkoff, &blknum, maxblocks);
+       up_read(&NILFS_MDT(dat)->mi_sem);
+       if (ret >= 0) { /* found */
                map_bh(bh_result, inode->i_sb, blknum);
+               if (ret > 0)
+                       bh_result->b_size = (ret << inode->i_blkbits);
                goto out;
        }
        /* data block was not found */
@@ -240,7 +241,7 @@ nilfs_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
 struct address_space_operations nilfs_aops = {
        .writepage              = nilfs_writepage,
        .readpage               = nilfs_readpage,
-       /* .sync_page           = nilfs_sync_page, */
+       .sync_page              = block_sync_page,
        .writepages             = nilfs_writepages,
        .set_page_dirty         = nilfs_set_page_dirty,
        .readpages              = nilfs_readpages,
@@ -249,6 +250,7 @@ struct address_space_operations nilfs_aops = {
        /* .releasepage         = nilfs_releasepage, */
        .invalidatepage         = block_invalidatepage,
        .direct_IO              = nilfs_direct_IO,
+       .is_partially_uptodate  = block_is_partially_uptodate,
 };
 
 struct inode *nilfs_new_inode(struct inode *dir, int mode)
index d6759b92006fe8b17d7c81ba79eb158e1665c0a9..6ea5f872e2de041cb5ba028f2b6f2ff731ed90e4 100644 (file)
@@ -152,7 +152,7 @@ nilfs_ioctl_do_get_cpinfo(struct the_nilfs *nilfs, __u64 *posp, int flags,
 
        down_read(&nilfs->ns_segctor_sem);
        ret = nilfs_cpfile_get_cpinfo(nilfs->ns_cpfile, posp, flags, buf,
-                                     nmembs);
+                                     size, nmembs);
        up_read(&nilfs->ns_segctor_sem);
        return ret;
 }
@@ -182,7 +182,8 @@ nilfs_ioctl_do_get_suinfo(struct the_nilfs *nilfs, __u64 *posp, int flags,
        int ret;
 
        down_read(&nilfs->ns_segctor_sem);
-       ret = nilfs_sufile_get_suinfo(nilfs->ns_sufile, *posp, buf, nmembs);
+       ret = nilfs_sufile_get_suinfo(nilfs->ns_sufile, *posp, buf, size,
+                                     nmembs);
        up_read(&nilfs->ns_segctor_sem);
        return ret;
 }
@@ -212,7 +213,7 @@ nilfs_ioctl_do_get_vinfo(struct the_nilfs *nilfs, __u64 *posp, int flags,
        int ret;
 
        down_read(&nilfs->ns_segctor_sem);
-       ret = nilfs_dat_get_vinfo(nilfs_dat_inode(nilfs), buf, nmembs);
+       ret = nilfs_dat_get_vinfo(nilfs_dat_inode(nilfs), buf, size, nmembs);
        up_read(&nilfs->ns_segctor_sem);
        return ret;
 }
@@ -435,24 +436,6 @@ static int nilfs_ioctl_mark_blocks_dirty(struct the_nilfs *nilfs,
        return nmembs;
 }
 
-static int nilfs_ioctl_free_segments(struct the_nilfs *nilfs,
-                                    struct nilfs_argv *argv, void *buf)
-{
-       size_t nmembs = argv->v_nmembs;
-       struct nilfs_sb_info *sbi = nilfs->ns_writer;
-       int ret;
-
-       if (unlikely(!sbi)) {
-               /* never happens because called for a writable mount */
-               WARN_ON(1);
-               return -EROFS;
-       }
-       ret = nilfs_segctor_add_segments_to_be_freed(
-               NILFS_SC(sbi), buf, nmembs);
-
-       return (ret < 0) ? ret : nmembs;
-}
-
 int nilfs_ioctl_prepare_clean_segments(struct the_nilfs *nilfs,
                                       struct nilfs_argv *argv, void **kbufs)
 {
@@ -491,14 +474,6 @@ int nilfs_ioctl_prepare_clean_segments(struct the_nilfs *nilfs,
                msg = "cannot mark copying blocks dirty";
                goto failed;
        }
-       ret = nilfs_ioctl_free_segments(nilfs, &argv[4], kbufs[4]);
-       if (ret < 0) {
-               /*
-                * can safely abort because this operation is atomic.
-                */
-               msg = "cannot set segments to be freed";
-               goto failed;
-       }
        return 0;
 
  failed:
@@ -615,7 +590,7 @@ static int nilfs_ioctl_get_info(struct inode *inode, struct file *filp,
        if (copy_from_user(&argv, argp, sizeof(argv)))
                return -EFAULT;
 
-       if (argv.v_size != membsz)
+       if (argv.v_size < membsz)
                return -EINVAL;
 
        ret = nilfs_ioctl_wrap_copy(nilfs, &argv, _IOC_DIR(cmd), dofunc);
index bb78745a0e30d0e7bda05d4416f9f72e5b74db75..3d3ddb3f51775301533daf55ff21e331a360ff63 100644 (file)
@@ -430,6 +430,7 @@ nilfs_mdt_write_page(struct page *page, struct writeback_control *wbc)
 
 static struct address_space_operations def_mdt_aops = {
        .writepage              = nilfs_mdt_write_page,
+       .sync_page              = block_sync_page,
 };
 
 static struct inode_operations def_mdt_iops;
@@ -449,7 +450,7 @@ struct inode *
 nilfs_mdt_new_common(struct the_nilfs *nilfs, struct super_block *sb,
                     ino_t ino, gfp_t gfp_mask)
 {
-       struct inode *inode = nilfs_alloc_inode(sb);
+       struct inode *inode = nilfs_alloc_inode_common(nilfs);
 
        if (!inode)
                return NULL;
index da6fc0bba2e5306d407538c7bc0eba94277a055a..edf6a59d9f2a1710e404e45250308dfa06ba28f9 100644 (file)
@@ -263,6 +263,7 @@ extern void nilfs_dirty_inode(struct inode *);
 extern struct dentry *nilfs_get_parent(struct dentry *);
 
 /* super.c */
+extern struct inode *nilfs_alloc_inode_common(struct the_nilfs *);
 extern struct inode *nilfs_alloc_inode(struct super_block *);
 extern void nilfs_destroy_inode(struct inode *);
 extern void nilfs_error(struct super_block *, const char *, const char *, ...)
index 57afa9d24061c9db67db822a4392db0edde4dd4c..d80cc71be7499cd62be748324eec1be57ecfe43a 100644 (file)
@@ -28,7 +28,6 @@
 #include "segment.h"
 #include "sufile.h"
 #include "page.h"
-#include "seglist.h"
 #include "segbuf.h"
 
 /*
@@ -395,6 +394,24 @@ static void dispose_recovery_list(struct list_head *head)
        }
 }
 
+struct nilfs_segment_entry {
+       struct list_head        list;
+       __u64                   segnum;
+};
+
+static int nilfs_segment_list_add(struct list_head *head, __u64 segnum)
+{
+       struct nilfs_segment_entry *ent = kmalloc(sizeof(*ent), GFP_NOFS);
+
+       if (unlikely(!ent))
+               return -ENOMEM;
+
+       ent->segnum = segnum;
+       INIT_LIST_HEAD(&ent->list);
+       list_add_tail(&ent->list, head);
+       return 0;
+}
+
 void nilfs_dispose_segment_list(struct list_head *head)
 {
        while (!list_empty(head)) {
@@ -402,7 +419,7 @@ void nilfs_dispose_segment_list(struct list_head *head)
                        = list_entry(head->next,
                                     struct nilfs_segment_entry, list);
                list_del(&ent->list);
-               nilfs_free_segment_entry(ent);
+               kfree(ent);
        }
 }
 
@@ -431,12 +448,10 @@ static int nilfs_prepare_segment_for_recovery(struct the_nilfs *nilfs,
        if (unlikely(err))
                goto failed;
 
-       err = -ENOMEM;
        for (i = 1; i < 4; i++) {
-               ent = nilfs_alloc_segment_entry(segnum[i]);
-               if (unlikely(!ent))
+               err = nilfs_segment_list_add(head, segnum[i]);
+               if (unlikely(err))
                        goto failed;
-               list_add_tail(&ent->list, head);
        }
 
        /*
@@ -450,7 +465,7 @@ static int nilfs_prepare_segment_for_recovery(struct the_nilfs *nilfs,
                                goto failed;
                }
                list_del(&ent->list);
-               nilfs_free_segment_entry(ent);
+               kfree(ent);
        }
 
        /* Allocate new segments for recovery */
@@ -791,7 +806,6 @@ int nilfs_search_super_root(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi,
        u64 seg_seq;
        __u64 segnum, nextnum = 0;
        __u64 cno;
-       struct nilfs_segment_entry *ent;
        LIST_HEAD(segments);
        int empty_seg = 0, scan_newer = 0;
        int ret;
@@ -892,12 +906,9 @@ int nilfs_search_super_root(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi,
                if (empty_seg++)
                        goto super_root_found; /* found a valid super root */
 
-               ent = nilfs_alloc_segment_entry(segnum);
-               if (unlikely(!ent)) {
-                       ret = -ENOMEM;
+               ret = nilfs_segment_list_add(&segments, segnum);
+               if (unlikely(ret))
                        goto failed;
-               }
-               list_add_tail(&ent->list, &segments);
 
                seg_seq++;
                segnum = nextnum;
index 1e68821b4a9bbdd54576a81bbebc740ceea0d6ec..9e3fe17bb96bcb86ec786a4469d659b9554ae399 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/crc32.h>
 #include "page.h"
 #include "segbuf.h"
-#include "seglist.h"
 
 
 static struct kmem_cache *nilfs_segbuf_cachep;
@@ -394,7 +393,7 @@ int nilfs_segbuf_write(struct nilfs_segment_buffer *segbuf,
                 * Last BIO is always sent through the following
                 * submission.
                 */
-               rw |= (1 << BIO_RW_SYNCIO);
+               rw |= (1 << BIO_RW_SYNCIO) | (1 << BIO_RW_UNPLUG);
                res = nilfs_submit_seg_bio(wi, rw);
                if (unlikely(res))
                        goto failed_bio;
diff --git a/fs/nilfs2/seglist.h b/fs/nilfs2/seglist.h
deleted file mode 100644 (file)
index d39df91..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * seglist.h - expediential structure and routines to handle list of segments
- *             (would be removed in a future release)
- *
- * Copyright (C) 2005-2008 Nippon Telegraph and Telephone Corporation.
- *
- * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * Written by Ryusuke Konishi <ryusuke@osrg.net>
- *
- */
-#ifndef _NILFS_SEGLIST_H
-#define _NILFS_SEGLIST_H
-
-#include <linux/fs.h>
-#include <linux/buffer_head.h>
-#include <linux/nilfs2_fs.h>
-#include "sufile.h"
-
-struct nilfs_segment_entry {
-       __u64                   segnum;
-
-#define NILFS_SLH_FREED                0x0001  /* The segment was freed provisonally.
-                                          It must be cancelled if
-                                          construction aborted */
-
-       unsigned                flags;
-       struct list_head        list;
-       struct buffer_head     *bh_su;
-       struct nilfs_segment_usage *raw_su;
-};
-
-
-void nilfs_dispose_segment_list(struct list_head *);
-
-static inline struct nilfs_segment_entry *
-nilfs_alloc_segment_entry(__u64 segnum)
-{
-       struct nilfs_segment_entry *ent = kmalloc(sizeof(*ent), GFP_NOFS);
-
-       if (likely(ent)) {
-               ent->segnum = segnum;
-               ent->flags = 0;
-               ent->bh_su = NULL;
-               ent->raw_su = NULL;
-               INIT_LIST_HEAD(&ent->list);
-       }
-       return ent;
-}
-
-static inline int nilfs_open_segment_entry(struct nilfs_segment_entry *ent,
-                                          struct inode *sufile)
-{
-       return nilfs_sufile_get_segment_usage(sufile, ent->segnum,
-                                             &ent->raw_su, &ent->bh_su);
-}
-
-static inline void nilfs_close_segment_entry(struct nilfs_segment_entry *ent,
-                                            struct inode *sufile)
-{
-       if (!ent->bh_su)
-               return;
-       nilfs_sufile_put_segment_usage(sufile, ent->segnum, ent->bh_su);
-       ent->bh_su = NULL;
-       ent->raw_su = NULL;
-}
-
-static inline void nilfs_free_segment_entry(struct nilfs_segment_entry *ent)
-{
-       kfree(ent);
-}
-
-#endif /* _NILFS_SEGLIST_H */
index 22c7f65c2403461dddd1e62ebe230bf56aab2376..aa977549919ecd2d92d40ff3d3d4f17f207f4814 100644 (file)
@@ -39,7 +39,6 @@
 #include "sufile.h"
 #include "cpfile.h"
 #include "ifile.h"
-#include "seglist.h"
 #include "segbuf.h"
 
 
@@ -79,7 +78,8 @@ enum {
 /* State flags of collection */
 #define NILFS_CF_NODE          0x0001  /* Collecting node blocks */
 #define NILFS_CF_IFILE_STARTED 0x0002  /* IFILE stage has started */
-#define NILFS_CF_HISTORY_MASK  (NILFS_CF_IFILE_STARTED)
+#define NILFS_CF_SUFREED       0x0004  /* segment usages has been freed */
+#define NILFS_CF_HISTORY_MASK  (NILFS_CF_IFILE_STARTED | NILFS_CF_SUFREED)
 
 /* Operations depending on the construction mode and file type */
 struct nilfs_sc_operations {
@@ -810,7 +810,7 @@ static int nilfs_segctor_clean(struct nilfs_sc_info *sci)
 {
        return list_empty(&sci->sc_dirty_files) &&
                !test_bit(NILFS_SC_DIRTY, &sci->sc_flags) &&
-               list_empty(&sci->sc_cleaning_segments) &&
+               sci->sc_nfreesegs == 0 &&
                (!nilfs_doing_gc() || list_empty(&sci->sc_gc_inodes));
 }
 
@@ -1005,44 +1005,6 @@ static void nilfs_drop_collected_inodes(struct list_head *head)
        }
 }
 
-static void nilfs_segctor_cancel_free_segments(struct nilfs_sc_info *sci,
-                                              struct inode *sufile)
-
-{
-       struct list_head *head = &sci->sc_cleaning_segments;
-       struct nilfs_segment_entry *ent;
-       int err;
-
-       list_for_each_entry(ent, head, list) {
-               if (!(ent->flags & NILFS_SLH_FREED))
-                       break;
-               err = nilfs_sufile_cancel_free(sufile, ent->segnum);
-               WARN_ON(err); /* do not happen */
-               ent->flags &= ~NILFS_SLH_FREED;
-       }
-}
-
-static int nilfs_segctor_prepare_free_segments(struct nilfs_sc_info *sci,
-                                              struct inode *sufile)
-{
-       struct list_head *head = &sci->sc_cleaning_segments;
-       struct nilfs_segment_entry *ent;
-       int err;
-
-       list_for_each_entry(ent, head, list) {
-               err = nilfs_sufile_free(sufile, ent->segnum);
-               if (unlikely(err))
-                       return err;
-               ent->flags |= NILFS_SLH_FREED;
-       }
-       return 0;
-}
-
-static void nilfs_segctor_commit_free_segments(struct nilfs_sc_info *sci)
-{
-       nilfs_dispose_segment_list(&sci->sc_cleaning_segments);
-}
-
 static int nilfs_segctor_apply_buffers(struct nilfs_sc_info *sci,
                                       struct inode *inode,
                                       struct list_head *listp,
@@ -1161,6 +1123,7 @@ static int nilfs_segctor_collect_blocks(struct nilfs_sc_info *sci, int mode)
        struct the_nilfs *nilfs = sbi->s_nilfs;
        struct list_head *head;
        struct nilfs_inode_info *ii;
+       size_t ndone;
        int err = 0;
 
        switch (sci->sc_stage.scnt) {
@@ -1250,10 +1213,16 @@ static int nilfs_segctor_collect_blocks(struct nilfs_sc_info *sci, int mode)
                        break;
                sci->sc_stage.scnt++;  /* Fall through */
        case NILFS_ST_SUFILE:
-               err = nilfs_segctor_prepare_free_segments(sci,
-                                                         nilfs->ns_sufile);
-               if (unlikely(err))
+               err = nilfs_sufile_freev(nilfs->ns_sufile, sci->sc_freesegs,
+                                        sci->sc_nfreesegs, &ndone);
+               if (unlikely(err)) {
+                       nilfs_sufile_cancel_freev(nilfs->ns_sufile,
+                                                 sci->sc_freesegs, ndone,
+                                                 NULL);
                        break;
+               }
+               sci->sc_stage.flags |= NILFS_CF_SUFREED;
+
                err = nilfs_segctor_scan_file(sci, nilfs->ns_sufile,
                                              &nilfs_sc_file_ops);
                if (unlikely(err))
@@ -1486,7 +1455,15 @@ static void nilfs_segctor_end_construction(struct nilfs_sc_info *sci,
 {
        if (unlikely(err)) {
                nilfs_segctor_free_incomplete_segments(sci, nilfs);
-               nilfs_segctor_cancel_free_segments(sci, nilfs->ns_sufile);
+               if (sci->sc_stage.flags & NILFS_CF_SUFREED) {
+                       int ret;
+
+                       ret = nilfs_sufile_cancel_freev(nilfs->ns_sufile,
+                                                       sci->sc_freesegs,
+                                                       sci->sc_nfreesegs,
+                                                       NULL);
+                       WARN_ON(ret); /* do not happen */
+               }
        }
        nilfs_segctor_clear_segment_buffers(sci);
 }
@@ -1585,7 +1562,13 @@ static int nilfs_segctor_collect(struct nilfs_sc_info *sci,
                if (mode != SC_LSEG_SR || sci->sc_stage.scnt < NILFS_ST_CPFILE)
                        break;
 
-               nilfs_segctor_cancel_free_segments(sci, nilfs->ns_sufile);
+               if (sci->sc_stage.flags & NILFS_CF_SUFREED) {
+                       err = nilfs_sufile_cancel_freev(nilfs->ns_sufile,
+                                                       sci->sc_freesegs,
+                                                       sci->sc_nfreesegs,
+                                                       NULL);
+                       WARN_ON(err); /* do not happen */
+               }
                nilfs_segctor_clear_segment_buffers(sci);
 
                err = nilfs_segctor_extend_segments(sci, nilfs, nadd);
@@ -2224,10 +2207,8 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode)
                nilfs_segctor_complete_write(sci);
 
                /* Commit segments */
-               if (has_sr) {
-                       nilfs_segctor_commit_free_segments(sci);
+               if (has_sr)
                        nilfs_segctor_clear_metadata_dirty(sci);
-               }
 
                nilfs_segctor_end_construction(sci, nilfs, 0);
 
@@ -2301,48 +2282,6 @@ void nilfs_flush_segment(struct super_block *sb, ino_t ino)
                                        /* assign bit 0 to data files */
 }
 
-int nilfs_segctor_add_segments_to_be_freed(struct nilfs_sc_info *sci,
-                                          __u64 *segnum, size_t nsegs)
-{
-       struct nilfs_segment_entry *ent;
-       struct the_nilfs *nilfs = sci->sc_sbi->s_nilfs;
-       struct inode *sufile = nilfs->ns_sufile;
-       LIST_HEAD(list);
-       __u64 *pnum;
-       size_t i;
-       int err;
-
-       for (pnum = segnum, i = 0; i < nsegs; pnum++, i++) {
-               ent = nilfs_alloc_segment_entry(*pnum);
-               if (unlikely(!ent)) {
-                       err = -ENOMEM;
-                       goto failed;
-               }
-               list_add_tail(&ent->list, &list);
-
-               err = nilfs_open_segment_entry(ent, sufile);
-               if (unlikely(err))
-                       goto failed;
-
-               if (unlikely(!nilfs_segment_usage_dirty(ent->raw_su)))
-                       printk(KERN_WARNING "NILFS: unused segment is "
-                              "requested to be cleaned (segnum=%llu)\n",
-                              (unsigned long long)ent->segnum);
-               nilfs_close_segment_entry(ent, sufile);
-       }
-       list_splice(&list, sci->sc_cleaning_segments.prev);
-       return 0;
-
- failed:
-       nilfs_dispose_segment_list(&list);
-       return err;
-}
-
-void nilfs_segctor_clear_segments_to_be_freed(struct nilfs_sc_info *sci)
-{
-       nilfs_dispose_segment_list(&sci->sc_cleaning_segments);
-}
-
 struct nilfs_segctor_wait_request {
        wait_queue_t    wq;
        __u32           seq;
@@ -2607,10 +2546,13 @@ int nilfs_clean_segments(struct super_block *sb, struct nilfs_argv *argv,
        err = nilfs_init_gcdat_inode(nilfs);
        if (unlikely(err))
                goto out_unlock;
+
        err = nilfs_ioctl_prepare_clean_segments(nilfs, argv, kbufs);
        if (unlikely(err))
                goto out_unlock;
 
+       sci->sc_freesegs = kbufs[4];
+       sci->sc_nfreesegs = argv[4].v_nmembs;
        list_splice_init(&nilfs->ns_gc_inodes, sci->sc_gc_inodes.prev);
 
        for (;;) {
@@ -2629,6 +2571,8 @@ int nilfs_clean_segments(struct super_block *sb, struct nilfs_argv *argv,
        }
 
  out_unlock:
+       sci->sc_freesegs = NULL;
+       sci->sc_nfreesegs = 0;
        nilfs_clear_gcdat_inode(nilfs);
        nilfs_transaction_unlock(sbi);
        return err;
@@ -2835,7 +2779,6 @@ static struct nilfs_sc_info *nilfs_segctor_new(struct nilfs_sb_info *sbi)
        INIT_LIST_HEAD(&sci->sc_dirty_files);
        INIT_LIST_HEAD(&sci->sc_segbufs);
        INIT_LIST_HEAD(&sci->sc_gc_inodes);
-       INIT_LIST_HEAD(&sci->sc_cleaning_segments);
        INIT_LIST_HEAD(&sci->sc_copied_buffers);
 
        sci->sc_interval = HZ * NILFS_SC_DEFAULT_TIMEOUT;
@@ -2901,9 +2844,6 @@ static void nilfs_segctor_destroy(struct nilfs_sc_info *sci)
                nilfs_dispose_list(sbi, &sci->sc_dirty_files, 1);
        }
 
-       if (!list_empty(&sci->sc_cleaning_segments))
-               nilfs_dispose_segment_list(&sci->sc_cleaning_segments);
-
        WARN_ON(!list_empty(&sci->sc_segbufs));
 
        down_write(&sbi->s_nilfs->ns_segctor_sem);
index 476bdd5df5be1cede75fb57cea725e20eb6faacc..0d2a475a741b764cc352bf3e0a305b5fcced30ae 100644 (file)
@@ -90,8 +90,9 @@ struct nilfs_segsum_pointer {
  * @sc_nblk_inc: Block count of current generation
  * @sc_dirty_files: List of files to be written
  * @sc_gc_inodes: List of GC inodes having blocks to be written
- * @sc_cleaning_segments: List of segments to be freed through construction
  * @sc_copied_buffers: List of copied buffers (buffer heads) to freeze data
+ * @sc_freesegs: array of segment numbers to be freed
+ * @sc_nfreesegs: number of segments on @sc_freesegs
  * @sc_dsync_inode: inode whose data pages are written for a sync operation
  * @sc_dsync_start: start byte offset of data pages
  * @sc_dsync_end: end byte offset of data pages (inclusive)
@@ -131,9 +132,11 @@ struct nilfs_sc_info {
 
        struct list_head        sc_dirty_files;
        struct list_head        sc_gc_inodes;
-       struct list_head        sc_cleaning_segments;
        struct list_head        sc_copied_buffers;
 
+       __u64                  *sc_freesegs;
+       size_t                  sc_nfreesegs;
+
        struct nilfs_inode_info *sc_dsync_inode;
        loff_t                  sc_dsync_start;
        loff_t                  sc_dsync_end;
@@ -225,10 +228,6 @@ extern void nilfs_flush_segment(struct super_block *, ino_t);
 extern int nilfs_clean_segments(struct super_block *, struct nilfs_argv *,
                                void **);
 
-extern int nilfs_segctor_add_segments_to_be_freed(struct nilfs_sc_info *,
-                                                 __u64 *, size_t);
-extern void nilfs_segctor_clear_segments_to_be_freed(struct nilfs_sc_info *);
-
 extern int nilfs_attach_segment_constructor(struct nilfs_sb_info *);
 extern void nilfs_detach_segment_constructor(struct nilfs_sb_info *);
 
@@ -240,5 +239,6 @@ extern int nilfs_search_super_root(struct the_nilfs *, struct nilfs_sb_info *,
 extern int nilfs_recover_logical_segments(struct the_nilfs *,
                                          struct nilfs_sb_info *,
                                          struct nilfs_recovery_info *);
+extern void nilfs_dispose_segment_list(struct list_head *);
 
 #endif /* _NILFS_SEGMENT_H */
index 98e68677f04571c562fe9ccac0d2a365cc73b369..37994d4a59cc95a6f70ae097d850adeab376fc67 100644 (file)
@@ -18,6 +18,7 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  *
  * Written by Koji Sato <koji@osrg.net>.
+ * Rivised by Ryusuke Konishi <ryusuke@osrg.net>.
  */
 
 #include <linux/kernel.h>
@@ -108,6 +109,102 @@ static void nilfs_sufile_mod_counter(struct buffer_head *header_bh,
        nilfs_mdt_mark_buffer_dirty(header_bh);
 }
 
+/**
+ * nilfs_sufile_updatev - modify multiple segment usages at a time
+ * @sufile: inode of segment usage file
+ * @segnumv: array of segment numbers
+ * @nsegs: size of @segnumv array
+ * @create: creation flag
+ * @ndone: place to store number of modified segments on @segnumv
+ * @dofunc: primitive operation for the update
+ *
+ * Description: nilfs_sufile_updatev() repeatedly calls @dofunc
+ * against the given array of segments.  The @dofunc is called with
+ * buffers of a header block and the sufile block in which the target
+ * segment usage entry is contained.  If @ndone is given, the number
+ * of successfully modified segments from the head is stored in the
+ * place @ndone points to.
+ *
+ * Return Value: On success, zero is returned.  On error, one of the
+ * following negative error codes is returned.
+ *
+ * %-EIO - I/O error.
+ *
+ * %-ENOMEM - Insufficient amount of memory available.
+ *
+ * %-ENOENT - Given segment usage is in hole block (may be returned if
+ *            @create is zero)
+ *
+ * %-EINVAL - Invalid segment usage number
+ */
+int nilfs_sufile_updatev(struct inode *sufile, __u64 *segnumv, size_t nsegs,
+                        int create, size_t *ndone,
+                        void (*dofunc)(struct inode *, __u64,
+                                       struct buffer_head *,
+                                       struct buffer_head *))
+{
+       struct buffer_head *header_bh, *bh;
+       unsigned long blkoff, prev_blkoff;
+       __u64 *seg;
+       size_t nerr = 0, n = 0;
+       int ret = 0;
+
+       if (unlikely(nsegs == 0))
+               goto out;
+
+       down_write(&NILFS_MDT(sufile)->mi_sem);
+       for (seg = segnumv; seg < segnumv + nsegs; seg++) {
+               if (unlikely(*seg >= nilfs_sufile_get_nsegments(sufile))) {
+                       printk(KERN_WARNING
+                              "%s: invalid segment number: %llu\n", __func__,
+                              (unsigned long long)*seg);
+                       nerr++;
+               }
+       }
+       if (nerr > 0) {
+               ret = -EINVAL;
+               goto out_sem;
+       }
+
+       ret = nilfs_sufile_get_header_block(sufile, &header_bh);
+       if (ret < 0)
+               goto out_sem;
+
+       seg = segnumv;
+       blkoff = nilfs_sufile_get_blkoff(sufile, *seg);
+       ret = nilfs_mdt_get_block(sufile, blkoff, create, NULL, &bh);
+       if (ret < 0)
+               goto out_header;
+
+       for (;;) {
+               dofunc(sufile, *seg, header_bh, bh);
+
+               if (++seg >= segnumv + nsegs)
+                       break;
+               prev_blkoff = blkoff;
+               blkoff = nilfs_sufile_get_blkoff(sufile, *seg);
+               if (blkoff == prev_blkoff)
+                       continue;
+
+               /* get different block */
+               brelse(bh);
+               ret = nilfs_mdt_get_block(sufile, blkoff, create, NULL, &bh);
+               if (unlikely(ret < 0))
+                       goto out_header;
+       }
+       brelse(bh);
+
+ out_header:
+       n = seg - segnumv;
+       brelse(header_bh);
+ out_sem:
+       up_write(&NILFS_MDT(sufile)->mi_sem);
+ out:
+       if (ndone)
+               *ndone = n;
+       return ret;
+}
+
 int nilfs_sufile_update(struct inode *sufile, __u64 segnum, int create,
                        void (*dofunc)(struct inode *, __u64,
                                       struct buffer_head *,
@@ -490,7 +587,8 @@ void nilfs_sufile_do_set_error(struct inode *sufile, __u64 segnum,
  * nilfs_sufile_get_suinfo -
  * @sufile: inode of segment usage file
  * @segnum: segment number to start looking
- * @si: array of suinfo
+ * @buf: array of suinfo
+ * @sisz: byte size of suinfo
  * @nsi: size of suinfo array
  *
  * Description:
@@ -502,11 +600,12 @@ void nilfs_sufile_do_set_error(struct inode *sufile, __u64 segnum,
  *
  * %-ENOMEM - Insufficient amount of memory available.
  */
-ssize_t nilfs_sufile_get_suinfo(struct inode *sufile, __u64 segnum,
-                               struct nilfs_suinfo *si, size_t nsi)
+ssize_t nilfs_sufile_get_suinfo(struct inode *sufile, __u64 segnum, void *buf,
+                               unsigned sisz, size_t nsi)
 {
        struct buffer_head *su_bh;
        struct nilfs_segment_usage *su;
+       struct nilfs_suinfo *si = buf;
        size_t susz = NILFS_MDT(sufile)->mi_entry_size;
        struct the_nilfs *nilfs = NILFS_MDT(sufile)->mi_nilfs;
        void *kaddr;
@@ -531,20 +630,22 @@ ssize_t nilfs_sufile_get_suinfo(struct inode *sufile, __u64 segnum,
                        if (ret != -ENOENT)
                                goto out;
                        /* hole */
-                       memset(&si[i], 0, sizeof(struct nilfs_suinfo) * n);
+                       memset(si, 0, sisz * n);
+                       si = (void *)si + sisz * n;
                        continue;
                }
 
                kaddr = kmap_atomic(su_bh->b_page, KM_USER0);
                su = nilfs_sufile_block_get_segment_usage(
                        sufile, segnum, su_bh, kaddr);
-               for (j = 0; j < n; j++, su = (void *)su + susz) {
-                       si[i + j].sui_lastmod = le64_to_cpu(su->su_lastmod);
-                       si[i + j].sui_nblocks = le32_to_cpu(su->su_nblocks);
-                       si[i + j].sui_flags = le32_to_cpu(su->su_flags) &
+               for (j = 0; j < n;
+                    j++, su = (void *)su + susz, si = (void *)si + sisz) {
+                       si->sui_lastmod = le64_to_cpu(su->su_lastmod);
+                       si->sui_nblocks = le32_to_cpu(su->su_nblocks);
+                       si->sui_flags = le32_to_cpu(su->su_flags) &
                                ~(1UL << NILFS_SEGMENT_USAGE_ACTIVE);
                        if (nilfs_segment_is_active(nilfs, segnum + j))
-                               si[i + j].sui_flags |=
+                               si->sui_flags |=
                                        (1UL << NILFS_SEGMENT_USAGE_ACTIVE);
                }
                kunmap_atomic(kaddr, KM_USER0);
index a2e2efd4ade1065b89cd3c1e64f3407d5ed5a16c..a2c4d76c3366968e3d0a44a37278b9a9dcd90de0 100644 (file)
@@ -43,42 +43,26 @@ void nilfs_sufile_put_segment_usage(struct inode *, __u64,
                                    struct buffer_head *);
 int nilfs_sufile_get_stat(struct inode *, struct nilfs_sustat *);
 int nilfs_sufile_get_ncleansegs(struct inode *, unsigned long *);
-ssize_t nilfs_sufile_get_suinfo(struct inode *, __u64, struct nilfs_suinfo *,
+ssize_t nilfs_sufile_get_suinfo(struct inode *, __u64, void *, unsigned,
                                size_t);
 
+int nilfs_sufile_updatev(struct inode *, __u64 *, size_t, int, size_t *,
+                        void (*dofunc)(struct inode *, __u64,
+                                       struct buffer_head *,
+                                       struct buffer_head *));
 int nilfs_sufile_update(struct inode *, __u64, int,
                        void (*dofunc)(struct inode *, __u64,
                                       struct buffer_head *,
                                       struct buffer_head *));
-void nilfs_sufile_do_cancel_free(struct inode *, __u64, struct buffer_head *,
-                                struct buffer_head *);
 void nilfs_sufile_do_scrap(struct inode *, __u64, struct buffer_head *,
                           struct buffer_head *);
 void nilfs_sufile_do_free(struct inode *, __u64, struct buffer_head *,
                          struct buffer_head *);
+void nilfs_sufile_do_cancel_free(struct inode *, __u64, struct buffer_head *,
+                                struct buffer_head *);
 void nilfs_sufile_do_set_error(struct inode *, __u64, struct buffer_head *,
                               struct buffer_head *);
 
-/**
- * nilfs_sufile_cancel_free -
- * @sufile: inode of segment usage file
- * @segnum: segment number
- *
- * Description:
- *
- * Return Value: On success, 0 is returned. On error, one of the following
- * negative error codes is returned.
- *
- * %-EIO - I/O error.
- *
- * %-ENOMEM - Insufficient amount of memory available.
- */
-static inline int nilfs_sufile_cancel_free(struct inode *sufile, __u64 segnum)
-{
-       return nilfs_sufile_update(sufile, segnum, 0,
-                                  nilfs_sufile_do_cancel_free);
-}
-
 /**
  * nilfs_sufile_scrap - make a segment garbage
  * @sufile: inode of segment usage file
@@ -99,6 +83,38 @@ static inline int nilfs_sufile_free(struct inode *sufile, __u64 segnum)
        return nilfs_sufile_update(sufile, segnum, 0, nilfs_sufile_do_free);
 }
 
+/**
+ * nilfs_sufile_freev - free segments
+ * @sufile: inode of segment usage file
+ * @segnumv: array of segment numbers
+ * @nsegs: size of @segnumv array
+ * @ndone: place to store the number of freed segments
+ */
+static inline int nilfs_sufile_freev(struct inode *sufile, __u64 *segnumv,
+                                    size_t nsegs, size_t *ndone)
+{
+       return nilfs_sufile_updatev(sufile, segnumv, nsegs, 0, ndone,
+                                   nilfs_sufile_do_free);
+}
+
+/**
+ * nilfs_sufile_cancel_freev - reallocate freeing segments
+ * @sufile: inode of segment usage file
+ * @segnumv: array of segment numbers
+ * @nsegs: size of @segnumv array
+ * @ndone: place to store the number of cancelled segments
+ *
+ * Return Value: On success, 0 is returned. On error, a negative error codes
+ * is returned.
+ */
+static inline int nilfs_sufile_cancel_freev(struct inode *sufile,
+                                           __u64 *segnumv, size_t nsegs,
+                                           size_t *ndone)
+{
+       return nilfs_sufile_updatev(sufile, segnumv, nsegs, 0, ndone,
+                                   nilfs_sufile_do_cancel_free);
+}
+
 /**
  * nilfs_sufile_set_error - mark a segment as erroneous
  * @sufile: inode of segment usage file
index 1777a3467bd29b7cfc86b9d811eeacbd317c3efe..ab785f85aa501abb40691a61b24395e0419c62f8 100644 (file)
@@ -133,7 +133,7 @@ void nilfs_warning(struct super_block *sb, const char *function,
 
 static struct kmem_cache *nilfs_inode_cachep;
 
-struct inode *nilfs_alloc_inode(struct super_block *sb)
+struct inode *nilfs_alloc_inode_common(struct the_nilfs *nilfs)
 {
        struct nilfs_inode_info *ii;
 
@@ -143,10 +143,15 @@ struct inode *nilfs_alloc_inode(struct super_block *sb)
        ii->i_bh = NULL;
        ii->i_state = 0;
        ii->vfs_inode.i_version = 1;
-       nilfs_btnode_cache_init(&ii->i_btnode_cache);
+       nilfs_btnode_cache_init(&ii->i_btnode_cache, nilfs->ns_bdi);
        return &ii->vfs_inode;
 }
 
+struct inode *nilfs_alloc_inode(struct super_block *sb)
+{
+       return nilfs_alloc_inode_common(NILFS_SB(sb)->s_nilfs);
+}
+
 void nilfs_destroy_inode(struct inode *inode)
 {
        kmem_cache_free(nilfs_inode_cachep, NILFS_I(inode));
index e4e5c78bcc93ffed8e65fce8529ce6cc4651da97..8b8889825716a9df7b7f71cff2102d89ee547eec 100644 (file)
@@ -32,7 +32,6 @@
 #include "cpfile.h"
 #include "sufile.h"
 #include "dat.h"
-#include "seglist.h"
 #include "segbuf.h"
 
 
index 3a6b193d84442176628885c30960cc935d92368e..0ff7566c767c5dfcccbe6d2ea771fd43ba7781e8 100644 (file)
@@ -202,9 +202,12 @@ static int ramfs_parse_options(char *data, struct ramfs_mount_opts *opts)
                                return -EINVAL;
                        opts->mode = option & S_IALLUGO;
                        break;
-               default:
-                       printk(KERN_ERR "ramfs: bad mount option: %s\n", p);
-                       return -EINVAL;
+               /*
+                * We might like to report bad mount options here;
+                * but traditionally ramfs has ignored all mount options,
+                * and as it is used as a !CONFIG_SHMEM simple substitute
+                * for tmpfs, better continue to ignore other mount options.
+                */
                }
        }
 
index 4db89e98535d25eae5be6c9496b622e1296613f7..82ec6a3c050095a018e4594fe28dec4d5408e49e 100644 (file)
@@ -47,7 +47,7 @@
 
 /* Current ACPICA subsystem version in YYYYMMDD format */
 
-#define ACPI_CA_VERSION                 0x20090320
+#define ACPI_CA_VERSION                 0x20090521
 
 #include "actypes.h"
 #include "actbl.h"
@@ -201,6 +201,8 @@ acpi_evaluate_object_typed(acpi_handle object,
 acpi_status
 acpi_get_object_info(acpi_handle handle, struct acpi_buffer *return_buffer);
 
+acpi_status acpi_install_method(u8 *buffer);
+
 acpi_status
 acpi_get_next_object(acpi_object_type type,
                     acpi_handle parent,
@@ -375,7 +377,7 @@ acpi_status acpi_leave_sleep_state_prep(u8 sleep_state);
 acpi_status acpi_leave_sleep_state(u8 sleep_state);
 
 /*
- * Debug output
+ * Error/Warning output
  */
 void ACPI_INTERNAL_VAR_XFACE
 acpi_error(const char *module_name,
@@ -394,6 +396,9 @@ void ACPI_INTERNAL_VAR_XFACE
 acpi_info(const char *module_name,
          u32 line_number, const char *format, ...) ACPI_PRINTF_LIKE(3);
 
+/*
+ * Debug output
+ */
 #ifdef ACPI_DEBUG_OUTPUT
 
 void ACPI_INTERNAL_VAR_XFACE
index f555d927f7c0f17bb630a2c1ca3f868205b4af68..37ba576d06e857c51a4c9b62f3d7464eee87fbd2 100644 (file)
@@ -429,20 +429,12 @@ typedef unsigned long long acpi_integer;
 
 /* Data manipulation */
 
-#define ACPI_LOWORD(l)                  ((u16)(u32)(l))
-#define ACPI_HIWORD(l)                  ((u16)((((u32)(l)) >> 16) & 0xFFFF))
-#define ACPI_LOBYTE(l)                  ((u8)(u16)(l))
-#define ACPI_HIBYTE(l)                  ((u8)((((u16)(l)) >> 8) & 0xFF))
-
-/* Full 64-bit integer must be available on both 32-bit and 64-bit platforms */
-
-struct acpi_integer_overlay {
-       u32 lo_dword;
-       u32 hi_dword;
-};
-
-#define ACPI_LODWORD(integer)           (ACPI_CAST_PTR (struct acpi_integer_overlay, &integer)->lo_dword)
-#define ACPI_HIDWORD(integer)           (ACPI_CAST_PTR (struct acpi_integer_overlay, &integer)->hi_dword)
+#define ACPI_LOBYTE(integer)            ((u8)   (u16)(integer))
+#define ACPI_HIBYTE(integer)            ((u8) (((u16)(integer)) >> 8))
+#define ACPI_LOWORD(integer)            ((u16)  (u32)(integer))
+#define ACPI_HIWORD(integer)            ((u16)(((u32)(integer)) >> 16))
+#define ACPI_LODWORD(integer64)         ((u32)  (u64)(integer64))
+#define ACPI_HIDWORD(integer64)         ((u32)(((u64)(integer64)) >> 32))
 
 #define ACPI_SET_BIT(target,bit)        ((target) |= (bit))
 #define ACPI_CLEAR_BIT(target,bit)      ((target) &= ~(bit))
index 8e2cdc57b1974f5430b4d39fe681090f9ffd0441..935c5d7fc86eb44f2050e5f21ba1aedd8ef0b930 100644 (file)
@@ -62,4 +62,8 @@
  */
 #define ACPI_UNUSED_VAR __attribute__ ((unused))
 
+#ifdef _ANSI
+#define inline
+#endif
+
 #endif                         /* __ACGCC_H__ */
index 6d49b2a498c4d5c92ae49d974be3b6a693b9bfae..fcb8e4b159b1cde3060d27fd1761c898fa0a0250 100644 (file)
@@ -1,11 +1,11 @@
 /******************************************************************************
  *
- * Name: aclinux.h - OS specific defines, etc.
+ * Name: aclinux.h - OS specific defines, etc. for Linux
  *
  *****************************************************************************/
 
 /*
- * Copyright (C) 2000 - 2008, Intel Corp.
+ * Copyright (C) 2000 - 2009, Intel Corp.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
 #ifndef __ACLINUX_H__
 #define __ACLINUX_H__
 
+/* Common (in-kernel/user-space) ACPICA configuration */
+
 #define ACPI_USE_SYSTEM_CLIBRARY
 #define ACPI_USE_DO_WHILE_0
 #define ACPI_MUTEX_TYPE             ACPI_BINARY_SEMAPHORE
 
+
 #ifdef __KERNEL__
 
 #include <linux/string.h>
 #include <linux/spinlock_types.h>
 #include <asm/current.h>
 
-/* Host-dependent types and defines */
+/* Host-dependent types and defines for in-kernel ACPICA */
 
 #define ACPI_MACHINE_WIDTH          BITS_PER_LONG
-#define acpi_cache_t                        struct kmem_cache
-#define acpi_spinlock                   spinlock_t *
 #define ACPI_EXPORT_SYMBOL(symbol)  EXPORT_SYMBOL(symbol);
 #define strtoul                     simple_strtoul
 
-#else                          /* !__KERNEL__ */
+#define acpi_cache_t                        struct kmem_cache
+#define acpi_spinlock                       spinlock_t *
+#define acpi_cpu_flags                      unsigned long
+#define acpi_thread_id                      struct task_struct *
+
+#else /* !__KERNEL__ */
 
 #include <stdarg.h>
 #include <string.h>
 #include <ctype.h>
 #include <unistd.h>
 
+/* Host-dependent types and defines for user-space ACPICA */
+
+#define ACPI_FLUSH_CPU_CACHE()
+#define acpi_thread_id                      pthread_t
+
 #if defined(__ia64__) || defined(__x86_64__)
 #define ACPI_MACHINE_WIDTH          64
 #define COMPILER_DEPENDENT_INT64    long
 #define __cdecl
 #endif
 
-#define ACPI_FLUSH_CPU_CACHE()
-#endif                         /* __KERNEL__ */
+#endif /* __KERNEL__ */
 
 /* Linux uses GCC */
 
 #include "acgcc.h"
 
-#define acpi_cpu_flags unsigned long
-
-#define acpi_thread_id struct task_struct *
 
+#ifdef __KERNEL__
+/*
+ * Overrides for in-kernel ACPICA
+ */
 static inline acpi_thread_id acpi_os_get_thread_id(void)
 {
        return current;
@@ -119,30 +130,32 @@ static inline acpi_thread_id acpi_os_get_thread_id(void)
 #include <acpi/actypes.h>
 static inline void *acpi_os_allocate(acpi_size size)
 {
-       return kmalloc(size, irqs_disabled()? GFP_ATOMIC : GFP_KERNEL);
+       return kmalloc(size, irqs_disabled() ? GFP_ATOMIC : GFP_KERNEL);
 }
+
 static inline void *acpi_os_allocate_zeroed(acpi_size size)
 {
-       return kzalloc(size, irqs_disabled()? GFP_ATOMIC : GFP_KERNEL);
+       return kzalloc(size, irqs_disabled() ? GFP_ATOMIC : GFP_KERNEL);
 }
 
 static inline void *acpi_os_acquire_object(acpi_cache_t * cache)
 {
        return kmem_cache_zalloc(cache,
-                                irqs_disabled()? GFP_ATOMIC : GFP_KERNEL);
+               irqs_disabled() ? GFP_ATOMIC : GFP_KERNEL);
 }
 
-#define ACPI_ALLOCATE(a)       acpi_os_allocate(a)
-#define ACPI_ALLOCATE_ZEROED(a)        acpi_os_allocate_zeroed(a)
-#define ACPI_FREE(a)           kfree(a)
+#define ACPI_ALLOCATE(a)        acpi_os_allocate(a)
+#define ACPI_ALLOCATE_ZEROED(a) acpi_os_allocate_zeroed(a)
+#define ACPI_FREE(a)            kfree(a)
 
-/*
- * We need to show where it is safe to preempt execution of ACPICA
- */
-#define ACPI_PREEMPTION_POINT()                \
-       do {                            \
-               if (!irqs_disabled())   \
-                       cond_resched(); \
+/* Used within ACPICA to show where it is safe to preempt execution */
+
+#define ACPI_PREEMPTION_POINT() \
+       do { \
+               if (!irqs_disabled()) \
+                       cond_resched(); \
        } while (0)
 
-#endif                         /* __ACLINUX_H__ */
+#endif /* __KERNEL__ */
+
+#endif /* __ACLINUX_H__ */
index e8852c092fea913dc529fb49a04fa84b376a13cd..28cc03bf19e6e2ed6f9372f6e331fb1a8803de5f 100644 (file)
 #define        EOWNERDEAD      130     /* Owner died */
 #define        ENOTRECOVERABLE 131     /* State not recoverable */
 
+#define ERFKILL                132     /* Operation not possible due to RF-kill */
+
 #endif
index b3afd2219ad2e61baa8cc5ad607cd207192d442b..a2df7030d49d2fa11067bb4ad8d714937644e54d 100644 (file)
@@ -311,6 +311,7 @@ unifdef-y += ppp-comp.h
 unifdef-y += ptrace.h
 unifdef-y += quota.h
 unifdef-y += random.h
+unifdef-y += rfkill.h
 unifdef-y += irqnr.h
 unifdef-y += reboot.h
 unifdef-y += reiserfs_fs.h
index eff898aac02bcec8021f418bc2a969488cf86a42..8cb05aae661c11b238d020808abf321d85d43a71 100644 (file)
@@ -1,3 +1,4 @@
 header-y += raw.h
 header-y += bcm.h
 header-y += error.h
+header-y += netlink.h
diff --git a/include/linux/can/dev.h b/include/linux/can/dev.h
new file mode 100644 (file)
index 0000000..4a37a56
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * linux/can/dev.h
+ *
+ * Definitions for the CAN network device driver interface
+ *
+ * Copyright (C) 2006 Andrey Volkov <avolkov@varma-el.com>
+ *               Varma Electronics Oy
+ *
+ * Copyright (C) 2008 Wolfgang Grandegger <wg@grandegger.com>
+ *
+ * Send feedback to <socketcan-users@lists.berlios.de>
+ */
+
+#ifndef CAN_DEV_H
+#define CAN_DEV_H
+
+#include <linux/can/netlink.h>
+#include <linux/can/error.h>
+
+/*
+ * CAN mode
+ */
+enum can_mode {
+       CAN_MODE_STOP = 0,
+       CAN_MODE_START,
+       CAN_MODE_SLEEP
+};
+
+/*
+ * CAN common private data
+ */
+#define CAN_ECHO_SKB_MAX  4
+
+struct can_priv {
+       struct can_device_stats can_stats;
+
+       struct can_bittiming bittiming;
+       struct can_bittiming_const *bittiming_const;
+       struct can_clock clock;
+
+       enum can_state state;
+       u32 ctrlmode;
+
+       int restart_ms;
+       struct timer_list restart_timer;
+
+       struct sk_buff *echo_skb[CAN_ECHO_SKB_MAX];
+
+       int (*do_set_bittiming)(struct net_device *dev);
+       int (*do_set_mode)(struct net_device *dev, enum can_mode mode);
+       int (*do_get_state)(const struct net_device *dev,
+                           enum can_state *state);
+};
+
+struct net_device *alloc_candev(int sizeof_priv);
+void free_candev(struct net_device *dev);
+
+int open_candev(struct net_device *dev);
+void close_candev(struct net_device *dev);
+
+int register_candev(struct net_device *dev);
+void unregister_candev(struct net_device *dev);
+
+int can_restart_now(struct net_device *dev);
+void can_bus_off(struct net_device *dev);
+
+void can_put_echo_skb(struct sk_buff *skb, struct net_device *dev, int idx);
+void can_get_echo_skb(struct net_device *dev, int idx);
+
+#endif /* CAN_DEV_H */
diff --git a/include/linux/can/netlink.h b/include/linux/can/netlink.h
new file mode 100644 (file)
index 0000000..9ecbb78
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * linux/can/netlink.h
+ *
+ * Definitions for the CAN netlink interface
+ *
+ * Copyright (c) 2009 Wolfgang Grandegger <wg@grandegger.com>
+ *
+ * Send feedback to <socketcan-users@lists.berlios.de>
+ *
+ */
+
+#ifndef CAN_NETLINK_H
+#define CAN_NETLINK_H
+
+#include <linux/types.h>
+
+/*
+ * CAN bit-timing parameters
+ *
+ * For futher information, please read chapter "8 BIT TIMING
+ * REQUIREMENTS" of the "Bosch CAN Specification version 2.0"
+ * at http://www.semiconductors.bosch.de/pdf/can2spec.pdf.
+ */
+struct can_bittiming {
+       __u32 bitrate;          /* Bit-rate in bits/second */
+       __u32 sample_point;     /* Sample point in one-tenth of a percent */
+       __u32 tq;               /* Time quanta (TQ) in nanoseconds */
+       __u32 prop_seg;         /* Propagation segment in TQs */
+       __u32 phase_seg1;       /* Phase buffer segment 1 in TQs */
+       __u32 phase_seg2;       /* Phase buffer segment 2 in TQs */
+       __u32 sjw;              /* Synchronisation jump width in TQs */
+       __u32 brp;              /* Bit-rate prescaler */
+};
+
+/*
+ * CAN harware-dependent bit-timing constant
+ *
+ * Used for calculating and checking bit-timing parameters
+ */
+struct can_bittiming_const {
+       char name[16];          /* Name of the CAN controller hardware */
+       __u32 tseg1_min;        /* Time segement 1 = prop_seg + phase_seg1 */
+       __u32 tseg1_max;
+       __u32 tseg2_min;        /* Time segement 2 = phase_seg2 */
+       __u32 tseg2_max;
+       __u32 sjw_max;          /* Synchronisation jump width */
+       __u32 brp_min;          /* Bit-rate prescaler */
+       __u32 brp_max;
+       __u32 brp_inc;
+};
+
+/*
+ * CAN clock parameters
+ */
+struct can_clock {
+       __u32 freq;             /* CAN system clock frequency in Hz */
+};
+
+/*
+ * CAN operational and error states
+ */
+enum can_state {
+       CAN_STATE_ERROR_ACTIVE = 0,     /* RX/TX error count < 96 */
+       CAN_STATE_ERROR_WARNING,        /* RX/TX error count < 128 */
+       CAN_STATE_ERROR_PASSIVE,        /* RX/TX error count < 256 */
+       CAN_STATE_BUS_OFF,              /* RX/TX error count >= 256 */
+       CAN_STATE_STOPPED,              /* Device is stopped */
+       CAN_STATE_SLEEPING,             /* Device is sleeping */
+       CAN_STATE_MAX
+};
+
+/*
+ * CAN controller mode
+ */
+struct can_ctrlmode {
+       __u32 mask;
+       __u32 flags;
+};
+
+#define CAN_CTRLMODE_LOOPBACK  0x1     /* Loopback mode */
+#define CAN_CTRLMODE_LISTENONLY        0x2     /* Listen-only mode */
+#define CAN_CTRLMODE_3_SAMPLES 0x4     /* Triple sampling mode */
+
+/*
+ * CAN device statistics
+ */
+struct can_device_stats {
+       __u32 bus_error;        /* Bus errors */
+       __u32 error_warning;    /* Changes to error warning state */
+       __u32 error_passive;    /* Changes to error passive state */
+       __u32 bus_off;          /* Changes to bus off state */
+       __u32 arbitration_lost; /* Arbitration lost errors */
+       __u32 restarts;         /* CAN controller re-starts */
+};
+
+/*
+ * CAN netlink interface
+ */
+enum {
+       IFLA_CAN_UNSPEC,
+       IFLA_CAN_BITTIMING,
+       IFLA_CAN_BITTIMING_CONST,
+       IFLA_CAN_CLOCK,
+       IFLA_CAN_STATE,
+       IFLA_CAN_CTRLMODE,
+       IFLA_CAN_RESTART_MS,
+       IFLA_CAN_RESTART,
+       __IFLA_CAN_MAX
+};
+
+#define IFLA_CAN_MAX   (__IFLA_CAN_MAX - 1)
+
+#endif /* CAN_NETLINK_H */
diff --git a/include/linux/can/platform/sja1000.h b/include/linux/can/platform/sja1000.h
new file mode 100644 (file)
index 0000000..01ee2ae
--- /dev/null
@@ -0,0 +1,35 @@
+#ifndef _CAN_PLATFORM_SJA1000_H_
+#define _CAN_PLATFORM_SJA1000_H_
+
+/* clock divider register */
+#define CDR_CLKOUT_MASK 0x07
+#define CDR_CLK_OFF    0x08 /* Clock off (CLKOUT pin) */
+#define CDR_RXINPEN    0x20 /* TX1 output is RX irq output */
+#define CDR_CBP                0x40 /* CAN input comparator bypass */
+#define CDR_PELICAN    0x80 /* PeliCAN mode */
+
+/* output control register */
+#define OCR_MODE_BIPHASE  0x00
+#define OCR_MODE_TEST     0x01
+#define OCR_MODE_NORMAL   0x02
+#define OCR_MODE_CLOCK    0x03
+#define OCR_MODE_MASK     0x07
+#define OCR_TX0_INVERT    0x04
+#define OCR_TX0_PULLDOWN  0x08
+#define OCR_TX0_PULLUP    0x10
+#define OCR_TX0_PUSHPULL  0x18
+#define OCR_TX1_INVERT    0x20
+#define OCR_TX1_PULLDOWN  0x40
+#define OCR_TX1_PULLUP    0x80
+#define OCR_TX1_PUSHPULL  0xc0
+#define OCR_TX_MASK       0xfc
+#define OCR_TX_SHIFT      2
+
+struct sja1000_platform_data {
+       u32 clock;      /* CAN bus oscillator frequency in Hz */
+
+       u8 ocr;         /* output control register */
+       u8 cdr;         /* clock divider register */
+};
+
+#endif /* !_CAN_PLATFORM_SJA1000_H_ */
index 3a1dbba4d3ae2da500e710387d130cd8ad5dd4c2..20a100fe2b4f3040554f3994706d8f7b238460af 100644 (file)
@@ -143,3 +143,12 @@ extern void clockevents_notify(unsigned long reason, void *arg);
 #endif
 
 #endif
+
+#ifdef CONFIG_GENERIC_CLOCKEVENTS
+extern ktime_t clockevents_get_next_event(int cpu);
+#else
+static inline ktime_t clockevents_get_next_event(int cpu)
+{
+       return (ktime_t) { .tv64 = KTIME_MAX };
+}
+#endif
index a1f17abba7dc1123bc1884e74027f3604913f871..3d7a6687d247c32577cf6bad2f7cb483fd434c51 100644 (file)
@@ -182,6 +182,33 @@ static inline unsigned compare_ether_addr_64bits(const u8 addr1[6+2],
        return compare_ether_addr(addr1, addr2);
 #endif
 }
+
+/**
+ * is_etherdev_addr - Tell if given Ethernet address belongs to the device.
+ * @dev: Pointer to a device structure
+ * @addr: Pointer to a six-byte array containing the Ethernet address
+ *
+ * Compare passed address with all addresses of the device. Return true if the
+ * address if one of the device addresses.
+ *
+ * Note that this function calls compare_ether_addr_64bits() so take care of
+ * the right padding.
+ */
+static inline bool is_etherdev_addr(const struct net_device *dev,
+                                   const u8 addr[6 + 2])
+{
+       struct netdev_hw_addr *ha;
+       int res = 1;
+
+       rcu_read_lock();
+       for_each_dev_addr(dev, ha) {
+               res = compare_ether_addr_64bits(addr, ha->addr);
+               if (!res)
+                       break;
+       }
+       rcu_read_unlock();
+       return !res;
+}
 #endif /* __KERNEL__ */
 
 /**
index 131b127b70f8a1fb07ffa0e2a4aaba2166f12f78..9b660bd2e2b37db4a955d02e02929db4531b7ded 100644 (file)
@@ -26,11 +26,14 @@ struct ethtool_cmd {
        __u8    phy_address;
        __u8    transceiver;    /* Which transceiver to use */
        __u8    autoneg;        /* Enable or disable autonegotiation */
+       __u8    mdio_support;
        __u32   maxtxpkt;       /* Tx pkts before generating tx int */
        __u32   maxrxpkt;       /* Rx pkts before generating rx int */
        __u16   speed_hi;
-       __u16   reserved2;
-       __u32   reserved[3];
+       __u8    eth_tp_mdix;
+       __u8    reserved2;
+       __u32   lp_advertising; /* Features the link partner advertises */
+       __u32   reserved[2];
 };
 
 static inline void ethtool_cmd_speed_set(struct ethtool_cmd *ep,
@@ -563,6 +566,11 @@ struct ethtool_ops {
 #define SUPPORTED_Pause                        (1 << 13)
 #define SUPPORTED_Asym_Pause           (1 << 14)
 #define SUPPORTED_2500baseX_Full       (1 << 15)
+#define SUPPORTED_Backplane            (1 << 16)
+#define SUPPORTED_1000baseKX_Full      (1 << 17)
+#define SUPPORTED_10000baseKX4_Full    (1 << 18)
+#define SUPPORTED_10000baseKR_Full     (1 << 19)
+#define SUPPORTED_10000baseR_FEC       (1 << 20)
 
 /* Indicates what features are advertised by the interface. */
 #define ADVERTISED_10baseT_Half                (1 << 0)
@@ -581,6 +589,11 @@ struct ethtool_ops {
 #define ADVERTISED_Pause               (1 << 13)
 #define ADVERTISED_Asym_Pause          (1 << 14)
 #define ADVERTISED_2500baseX_Full      (1 << 15)
+#define ADVERTISED_Backplane           (1 << 16)
+#define ADVERTISED_1000baseKX_Full     (1 << 17)
+#define ADVERTISED_10000baseKX4_Full   (1 << 18)
+#define ADVERTISED_10000baseKR_Full    (1 << 19)
+#define ADVERTISED_10000baseR_FEC      (1 << 20)
 
 /* The following are all involved in forcing a particular link
  * mode for the device for setting things.  When getting the
@@ -605,6 +618,7 @@ struct ethtool_ops {
 #define PORT_MII               0x02
 #define PORT_FIBRE             0x03
 #define PORT_BNC               0x04
+#define PORT_OTHER             0xff
 
 /* Which transceiver to use. */
 #define XCVR_INTERNAL          0x00
@@ -619,6 +633,11 @@ struct ethtool_ops {
 #define AUTONEG_DISABLE                0x00
 #define AUTONEG_ENABLE         0x01
 
+/* Mode MDI or MDI-X */
+#define ETH_TP_MDI_INVALID     0x00
+#define ETH_TP_MDI             0x01
+#define ETH_TP_MDI_X           0x02
+
 /* Wake-On-Lan options. */
 #define WAKE_PHY               (1 << 0)
 #define WAKE_UCAST             (1 << 1)
index 8300cab30f9a7c2f5e4fafea7a5fa2955bee1934..51b793466ff3adcadb4e6bcc0d372494dbf7440c 100644 (file)
@@ -17,6 +17,7 @@
 #define FS_ENET_PD_H
 
 #include <linux/string.h>
+#include <linux/of_mdio.h>
 #include <asm/types.h>
 
 #define FS_ENET_NAME   "fs_enet"
@@ -130,10 +131,7 @@ struct fs_platform_info {
        
        u32 device_flags;
 
-       int phy_addr;           /* the phy address (-1 no phy) */
-       char bus_id[16];
-       int phy_irq;            /* the phy irq (if it exists)  */
-
+       struct device_node *phy_node;
        const struct fs_mii_bus_info *bus_info;
 
        int rx_ring, tx_ring;   /* number of buffers on rx     */
index 0d2f7c8a33d6aa2983fd610bac1fb7b4ebc44cca..7400900de94a692320c771e8881661e10ebe51b7 100644 (file)
@@ -30,8 +30,11 @@ struct hrtimer_cpu_base;
  * Mode arguments of xxx_hrtimer functions:
  */
 enum hrtimer_mode {
-       HRTIMER_MODE_ABS,       /* Time value is absolute */
-       HRTIMER_MODE_REL,       /* Time value is relative to now */
+       HRTIMER_MODE_ABS = 0x0,         /* Time value is absolute */
+       HRTIMER_MODE_REL = 0x1,         /* Time value is relative to now */
+       HRTIMER_MODE_PINNED = 0x02,     /* Timer is bound to CPU */
+       HRTIMER_MODE_ABS_PINNED = 0x02,
+       HRTIMER_MODE_REL_PINNED = 0x03,
 };
 
 /*
index 4b501b48ce86efdb43dffd84d62ed8116d53d7ce..a9173d5434d1cd85fa15174ced031ccca34ee4fd 100644 (file)
@@ -493,6 +493,7 @@ struct ieee80211s_hdr {
 /* Mesh flags */
 #define MESH_FLAGS_AE_A4       0x1
 #define MESH_FLAGS_AE_A5_A6    0x2
+#define MESH_FLAGS_AE          0x3
 #define MESH_FLAGS_PS_DEEP     0x4
 
 /**
@@ -540,10 +541,10 @@ struct ieee80211_tim_ie {
        u8 dtim_period;
        u8 bitmap_ctrl;
        /* variable size: 1 - 251 bytes */
-       u8 virtual_map[0];
+       u8 virtual_map[1];
 } __attribute__ ((packed));
 
-#define WLAN_SA_QUERY_TR_ID_LEN 16
+#define WLAN_SA_QUERY_TR_ID_LEN 2
 
 struct ieee80211_mgmt {
        __le16 frame_control;
@@ -1068,8 +1069,12 @@ enum ieee80211_category {
        WLAN_CATEGORY_DLS = 2,
        WLAN_CATEGORY_BACK = 3,
        WLAN_CATEGORY_PUBLIC = 4,
+       WLAN_CATEGORY_HT = 7,
        WLAN_CATEGORY_SA_QUERY = 8,
+       WLAN_CATEGORY_PROTECTED_DUAL_OF_ACTION = 9,
        WLAN_CATEGORY_WMM = 17,
+       WLAN_CATEGORY_VENDOR_SPECIFIC_PROTECTED = 126,
+       WLAN_CATEGORY_VENDOR_SPECIFIC = 127,
 };
 
 /* SPECTRUM_MGMT action code */
@@ -1081,6 +1086,15 @@ enum ieee80211_spectrum_mgmt_actioncode {
        WLAN_ACTION_SPCT_CHL_SWITCH = 4,
 };
 
+/* Security key length */
+enum ieee80211_key_len {
+       WLAN_KEY_LEN_WEP40 = 5,
+       WLAN_KEY_LEN_WEP104 = 13,
+       WLAN_KEY_LEN_CCMP = 16,
+       WLAN_KEY_LEN_TKIP = 32,
+       WLAN_KEY_LEN_AES_CMAC = 16,
+};
+
 /*
  * IEEE 802.11-2007 7.3.2.9 Country information element
  *
@@ -1261,7 +1275,9 @@ static inline bool ieee80211_is_robust_mgmt_frame(struct ieee80211_hdr *hdr)
                if (ieee80211_has_protected(hdr->frame_control))
                        return true;
                category = ((u8 *) hdr) + 24;
-               return *category != WLAN_CATEGORY_PUBLIC;
+               return *category != WLAN_CATEGORY_PUBLIC &&
+                       *category != WLAN_CATEGORY_HT &&
+                       *category != WLAN_CATEGORY_VENDOR_SPECIFIC;
        }
 
        return false;
@@ -1383,4 +1399,43 @@ static inline int ieee80211_freq_to_ofdm_chan(int s_freq, int freq)
                return -1;
 }
 
+/**
+ * ieee80211_tu_to_usec - convert time units (TU) to microseconds
+ * @tu: the TUs
+ */
+static inline unsigned long ieee80211_tu_to_usec(unsigned long tu)
+{
+       return 1024 * tu;
+}
+
+/**
+ * ieee80211_check_tim - check if AID bit is set in TIM
+ * @tim: the TIM IE
+ * @tim_len: length of the TIM IE
+ * @aid: the AID to look for
+ */
+static inline bool ieee80211_check_tim(struct ieee80211_tim_ie *tim,
+                                      u8 tim_len, u16 aid)
+{
+       u8 mask;
+       u8 index, indexn1, indexn2;
+
+       if (unlikely(!tim || tim_len < sizeof(*tim)))
+               return false;
+
+       aid &= 0x3fff;
+       index = aid / 8;
+       mask  = 1 << (aid & 7);
+
+       indexn1 = tim->bitmap_ctrl & 0xfe;
+       indexn2 = tim_len + indexn1 - 4;
+
+       if (index < indexn1 || index > indexn2)
+               return false;
+
+       index -= indexn1;
+
+       return !!(tim->virtual_map[index] & mask);
+}
+
 #endif /* LINUX_IEEE80211_H */
index 1108f3e099e3bcb7a80b89c9ee2f43fa5dcefa88..b9a6229f3be7751d58ea43bc938da8afecfc42b0 100644 (file)
@@ -67,6 +67,9 @@
 #define IFF_ISATAP     0x80            /* ISATAP interface (RFC4214)   */
 #define IFF_MASTER_ARPMON 0x100                /* bonding master, ARP mon in use */
 #define IFF_WAN_HDLC   0x200           /* WAN HDLC device              */
+#define IFF_XMIT_DST_RELEASE 0x400     /* dev_hard_start_xmit() is allowed to
+                                        * release skb->dst
+                                        */
 
 #define IF_GET_IFACE   0x0001          /* for querying only */
 #define IF_GET_PROTO   0x0002
index 5ff89809a581b507cdae24e501316849175b9528..b554300ef8bff2d08e6d6a1ed616164310901dd0 100644 (file)
@@ -86,6 +86,8 @@
 #define ARPHRD_IEEE80211 801           /* IEEE 802.11                  */
 #define ARPHRD_IEEE80211_PRISM 802     /* IEEE 802.11 + Prism2 header  */
 #define ARPHRD_IEEE80211_RADIOTAP 803  /* IEEE 802.11 + radiotap header */
+#define ARPHRD_IEEE802154        804
+#define ARPHRD_IEEE802154_PHY    805
 
 #define ARPHRD_PHONET  820             /* PhoNet media type            */
 #define ARPHRD_PHONET_PIPE 821         /* PhoNet pipe header           */
index 60e8934d10b5e070ab2289a19c787935026722b1..ae3a1871413dd031b41edcd9e4159f92a1363081 100644 (file)
 #define ETH_P_DSA      0x001B          /* Distributed Switch Arch.     */
 #define ETH_P_TRAILER  0x001C          /* Trailer switch tagging       */
 #define ETH_P_PHONET   0x00F5          /* Nokia Phonet frames          */
+#define ETH_P_IEEE802154 0x00F6                /* IEEE802.15.4 frame           */
 
 /*
  *     This is an Ethernet frame header.
index 18db0668065a61c6e5af363f3db50ddd1d5b629a..dea7d6b7cf982fcb2d78266faddc7ba43a1db3a2 100644 (file)
@@ -46,6 +46,8 @@ struct sockaddr_ll
 #define PACKET_VERSION                 10
 #define PACKET_HDRLEN                  11
 #define PACKET_RESERVE                 12
+#define PACKET_TX_RING                 13
+#define PACKET_LOSS                    14
 
 struct tpacket_stats
 {
@@ -63,14 +65,22 @@ struct tpacket_auxdata
        __u16           tp_vlan_tci;
 };
 
+/* Rx ring - header status */
+#define TP_STATUS_KERNEL       0x0
+#define TP_STATUS_USER         0x1
+#define TP_STATUS_COPY         0x2
+#define TP_STATUS_LOSING       0x4
+#define TP_STATUS_CSUMNOTREADY 0x8
+
+/* Tx ring - header status */
+#define TP_STATUS_AVAILABLE    0x0
+#define TP_STATUS_SEND_REQUEST 0x1
+#define TP_STATUS_SENDING      0x2
+#define TP_STATUS_WRONG_FORMAT 0x4
+
 struct tpacket_hdr
 {
        unsigned long   tp_status;
-#define TP_STATUS_KERNEL       0
-#define TP_STATUS_USER         1
-#define TP_STATUS_COPY         2
-#define TP_STATUS_LOSING       4
-#define TP_STATUS_CSUMNOTREADY 8
        unsigned int    tp_len;
        unsigned int    tp_snaplen;
        unsigned short  tp_mac;
@@ -135,5 +145,6 @@ struct packet_mreq
 #define PACKET_MR_MULTICAST    0
 #define PACKET_MR_PROMISC      1
 #define PACKET_MR_ALLMULTI     2
+#define PACKET_MR_UNICAST      3
 
 #endif
index 049d6c9428db60b78dbb49a595e774da001effb0..915ba5789f0eb62c02c1c2664e7ef66b1e631ab5 100644 (file)
@@ -55,6 +55,7 @@
 #define IFF_NO_PI      0x1000
 #define IFF_ONE_QUEUE  0x2000
 #define IFF_VNET_HDR   0x4000
+#define IFF_TUN_EXCL   0x8000
 
 /* Features for GSO (TUNSETOFFLOAD). */
 #define TUN_F_CSUM     0x01    /* You can hand me unchecksummed packets. */
index 5a9aae4adb444a3c8a63b5b9c5afd2c4456396de..5eb9b0f857e0720569eb04373ef42fb51bb04c9a 100644 (file)
@@ -44,7 +44,7 @@ struct ip_tunnel_prl {
        __u16                   flags;
        __u16                   __reserved;
        __u32                   datalen;
-       __u32                   __reserved2;
+       __u32                   rs_delay;
        /* data follows */
 };
 
index e1ff5b14310e817197fbf77c5af9522f2b862f6b..7ff9af1d0f05676a915734fc069a553a3eb27d8a 100644 (file)
@@ -118,8 +118,7 @@ extern int vlan_hwaccel_do_receive(struct sk_buff *skb);
 extern int vlan_gro_receive(struct napi_struct *napi, struct vlan_group *grp,
                            unsigned int vlan_tci, struct sk_buff *skb);
 extern int vlan_gro_frags(struct napi_struct *napi, struct vlan_group *grp,
-                         unsigned int vlan_tci,
-                         struct napi_gro_fraginfo *info);
+                         unsigned int vlan_tci);
 
 #else
 static inline struct net_device *vlan_dev_real_dev(const struct net_device *dev)
@@ -154,8 +153,7 @@ static inline int vlan_gro_receive(struct napi_struct *napi,
 }
 
 static inline int vlan_gro_frags(struct napi_struct *napi,
-                                struct vlan_group *grp, unsigned int vlan_tci,
-                                struct napi_gro_fraginfo *info)
+                                struct vlan_group *grp, unsigned int vlan_tci)
 {
        return NET_RX_DROP;
 }
index d60122a3a0886310e9221405ad1c022f9d3d2fa7..cf196da04ec92434ded51b599a7ae837f030c528 100644 (file)
@@ -107,6 +107,7 @@ struct in_addr {
 #define MCAST_JOIN_SOURCE_GROUP                46
 #define MCAST_LEAVE_SOURCE_GROUP       47
 #define MCAST_MSFILTER                 48
+#define IP_MULTICAST_ALL               49
 
 #define MCAST_EXCLUDE  0
 #define MCAST_INCLUDE  1
index 476d9464ac82d27c53a0fc48c435639f77391dcd..c662efa6828985a4025951a1c655cf5bf85300cf 100644 (file)
@@ -169,6 +169,12 @@ struct ipv6_devconf {
        __s32           accept_dad;
        void            *sysctl;
 };
+
+struct ipv6_params {
+       __s32 disable_ipv6;
+       __s32 autoconf;
+};
+extern struct ipv6_params ipv6_defaults;
 #endif
 
 /* index values for the variables in ipv6_devconf */
index 35e9b0fd014b9adc68b63b358fb57b0d07de2f69..7acb87a448726e91449ed1c9abee8611f04c94ac 100644 (file)
@@ -79,7 +79,7 @@ int attach_capi_ctr(struct capi_ctr *);
 int detach_capi_ctr(struct capi_ctr *);
 
 void capi_ctr_ready(struct capi_ctr * card);
-void capi_ctr_reseted(struct capi_ctr * card);
+void capi_ctr_down(struct capi_ctr * card);
 void capi_ctr_suspend_output(struct capi_ctr * card);
 void capi_ctr_resume_output(struct capi_ctr * card);
 void capi_ctr_handle_message(struct capi_ctr * card, u16 appl, struct sk_buff *skb);
index 883cd44ff765d9d90fdac42c11f51062bb8b8ef3..1b2e1747df1a02f8cc4ef308fc8a90c2aeb00a83 100644 (file)
@@ -97,12 +97,14 @@ extern const char linux_proc_banner[];
 #define        KERN_INFO       "<6>"   /* informational                        */
 #define        KERN_DEBUG      "<7>"   /* debug-level messages                 */
 
+/* Use the default kernel loglevel */
+#define KERN_DEFAULT   "<d>"
 /*
  * Annotation for a "continued" line of log printout (only done after a
  * line that had no enclosing \n). Only to be used by core/arch code
  * during early bootup (a continued line is not SMP-safe otherwise).
  */
-#define        KERN_CONT       ""
+#define        KERN_CONT       "<c>"
 
 extern int console_printk[];
 
index 93150ecf3ea404d1b5bcb9c1090ea290c22d64ae..5d10ae364b5eb5d0a50d220938dd2f020a8cafb2 100644 (file)
@@ -56,6 +56,18 @@ static inline int hlist_nulls_empty(const struct hlist_nulls_head *h)
        return is_a_nulls(h->first);
 }
 
+static inline void hlist_nulls_add_head(struct hlist_nulls_node *n,
+                                       struct hlist_nulls_head *h)
+{
+       struct hlist_nulls_node *first = h->first;
+
+       n->next = first;
+       n->pprev = &h->first;
+       h->first = n;
+       if (!is_a_nulls(first))
+               first->pprev = &n->next;
+}
+
 static inline void __hlist_nulls_del(struct hlist_nulls_node *n)
 {
        struct hlist_nulls_node *next = n->next;
@@ -65,6 +77,12 @@ static inline void __hlist_nulls_del(struct hlist_nulls_node *n)
                next->pprev = pprev;
 }
 
+static inline void hlist_nulls_del(struct hlist_nulls_node *n)
+{
+       __hlist_nulls_del(n);
+       n->pprev = LIST_POISON2;
+}
+
 /**
  * hlist_nulls_for_each_entry  - iterate over list of given type
  * @tpos:      the type * to use as a loop cursor.
index 6b71d2dce50855aa637ed5d32648e657a5433115..41d1eeb9b3bd5ea554308dd22bffbd05a8c23050 100644 (file)
@@ -12,7 +12,8 @@ struct mISDN_dsp_element {
        void    *(*new)(const char *arg);
        void    (*free)(void *p);
        void    (*process_tx)(void *p, unsigned char *data, int len);
-       void    (*process_rx)(void *p, unsigned char *data, int len);
+       void    (*process_rx)(void *p, unsigned char *data, int len,
+                       unsigned int txlen);
        int     num_args;
        struct mISDN_dsp_element_arg
                *args;
@@ -24,6 +25,7 @@ extern void mISDN_dsp_element_unregister(struct mISDN_dsp_element *elem);
 struct dsp_features {
        int     hfc_id; /* unique id to identify the chip (or -1) */
        int     hfc_dtmf; /* set if HFCmulti card supports dtmf */
+       int     hfc_conf; /* set if HFCmulti card supports conferences */
        int     hfc_loops; /* set if card supports tone loops */
        int     hfc_echocanhw; /* set if card supports echocancelation*/
        int     pcm_id; /* unique id to identify the pcm bus (or -1) */
index 97ffdc1d344245c99085fbc2d1007188a50091b0..7f9831da847f8dca1e4b3e7a4662e9119ff565eb 100644 (file)
@@ -89,11 +89,6 @@ struct dchannel {
        void                    (*phfunc) (struct dchannel *);
        u_int                   state;
        void                    *l1;
-       /* HW access */
-       u_char                  (*read_reg) (void *, u_char);
-       void                    (*write_reg) (void *, u_char, u_char);
-       void                    (*read_fifo) (void *, u_char *, int);
-       void                    (*write_fifo) (void *, u_char *, int);
        void                    *hw;
        int                     slot;   /* multiport card channel slot */
        struct timer_list       timer;
@@ -151,11 +146,6 @@ struct bchannel {
        u_long                  Flags;
        struct work_struct      workq;
        u_int                   state;
-       /* HW access */
-       u_char                  (*read_reg) (void *, u_char);
-       void                    (*write_reg) (void *, u_char, u_char);
-       void                    (*read_fifo) (void *, u_char *, int);
-       void                    (*write_fifo) (void *, u_char *, int);
        void                    *hw;
        int                     slot;   /* multiport card channel slot */
        struct timer_list       timer;
@@ -185,7 +175,7 @@ extern int  dchannel_senddata(struct dchannel *, struct sk_buff *);
 extern int     bchannel_senddata(struct bchannel *, struct sk_buff *);
 extern void    recv_Dchannel(struct dchannel *);
 extern void    recv_Echannel(struct dchannel *, struct dchannel *);
-extern void    recv_Bchannel(struct bchannel *);
+extern void    recv_Bchannel(struct bchannel *, unsigned int id);
 extern void    recv_Dchannel_skb(struct dchannel *, struct sk_buff *);
 extern void    recv_Bchannel_skb(struct bchannel *, struct sk_buff *);
 extern void    confirm_Bsend(struct bchannel *bch);
index 5da3d95b27f1612b7b008c3495caf419a089be06..45100b39a7cfe6bb8a621f110e7231dd9310aea5 100644 (file)
 #define OPTION_L2_PTP          2
 #define OPTION_L2_FIXEDTEI     3
 #define OPTION_L2_CLEANUP      4
+#define OPTION_L1_HOLD         5
 
 /* should be in sync with linux/kobject.h:KOBJ_NAME_LEN */
 #define MISDN_MAX_IDLEN                20
@@ -291,19 +292,19 @@ struct mISDN_devrename {
 
 /* MPH_INFORMATION_REQ payload */
 struct ph_info_ch {
-        __u32 protocol;
-        __u64 Flags;
+       __u32 protocol;
+       __u64 Flags;
 };
 
 struct ph_info_dch {
-        struct ph_info_ch ch;
-        __u16 state;
-        __u16 num_bch;
+       struct ph_info_ch ch;
+       __u16 state;
+       __u16 num_bch;
 };
 
 struct ph_info {
-        struct ph_info_dch dch;
-        struct ph_info_ch  bch[];
+       struct ph_info_dch dch;
+       struct ph_info_ch  bch[];
 };
 
 /* timer device ioctl */
@@ -317,6 +318,7 @@ struct ph_info {
 #define IMCTRLREQ      _IOR('I', 69, int)
 #define IMCLEAR_L2     _IOR('I', 70, int)
 #define IMSETDEVNAME   _IOR('I', 71, struct mISDN_devrename)
+#define IMHOLD_L1      _IOR('I', 72, int)
 
 static inline int
 test_channelmap(u_int nr, u_char *map)
@@ -362,7 +364,8 @@ clear_channelmap(u_int nr, u_char *map)
 #define MISDN_CTRL_HFC_RECEIVE_ON      0x4006
 #define MISDN_CTRL_HFC_ECHOCAN_ON      0x4007
 #define MISDN_CTRL_HFC_ECHOCAN_OFF     0x4008
-
+#define MISDN_CTRL_HFC_WD_INIT         0x4009
+#define MISDN_CTRL_HFC_WD_RESET                0x400A
 
 /* socket options */
 #define MISDN_TIME_STAMP               0x0001
diff --git a/include/linux/mdio.h b/include/linux/mdio.h
new file mode 100644 (file)
index 0000000..cfdf1df
--- /dev/null
@@ -0,0 +1,356 @@
+/*
+ * linux/mdio.h: definitions for MDIO (clause 45) transceivers
+ * Copyright 2006-2009 Solarflare Communications 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, incorporated herein by reference.
+ */
+
+#ifndef __LINUX_MDIO_H__
+#define __LINUX_MDIO_H__
+
+#include <linux/mii.h>
+
+/* MDIO Manageable Devices (MMDs). */
+#define MDIO_MMD_PMAPMD                1       /* Physical Medium Attachment/
+                                        * Physical Medium Dependent */
+#define MDIO_MMD_WIS           2       /* WAN Interface Sublayer */
+#define MDIO_MMD_PCS           3       /* Physical Coding Sublayer */
+#define MDIO_MMD_PHYXS         4       /* PHY Extender Sublayer */
+#define MDIO_MMD_DTEXS         5       /* DTE Extender Sublayer */
+#define MDIO_MMD_TC            6       /* Transmission Convergence */
+#define MDIO_MMD_AN            7       /* Auto-Negotiation */
+#define MDIO_MMD_C22EXT                29      /* Clause 22 extension */
+#define MDIO_MMD_VEND1         30      /* Vendor specific 1 */
+#define MDIO_MMD_VEND2         31      /* Vendor specific 2 */
+
+/* Generic MDIO registers. */
+#define MDIO_CTRL1             MII_BMCR
+#define MDIO_STAT1             MII_BMSR
+#define MDIO_DEVID1            MII_PHYSID1
+#define MDIO_DEVID2            MII_PHYSID2
+#define MDIO_SPEED             4       /* Speed ability */
+#define MDIO_DEVS1             5       /* Devices in package */
+#define MDIO_DEVS2             6
+#define MDIO_CTRL2             7       /* 10G control 2 */
+#define MDIO_STAT2             8       /* 10G status 2 */
+#define MDIO_PMA_TXDIS         9       /* 10G PMA/PMD transmit disable */
+#define MDIO_PMA_RXDET         10      /* 10G PMA/PMD receive signal detect */
+#define MDIO_PMA_EXTABLE       11      /* 10G PMA/PMD extended ability */
+#define MDIO_PKGID1            14      /* Package identifier */
+#define MDIO_PKGID2            15
+#define MDIO_AN_ADVERTISE      16      /* AN advertising (base page) */
+#define MDIO_AN_LPA            19      /* AN LP abilities (base page) */
+#define MDIO_PHYXS_LNSTAT      24      /* PHY XGXS lane state */
+
+/* Media-dependent registers. */
+#define MDIO_PMA_10GBT_SWAPPOL 130     /* 10GBASE-T pair swap & polarity */
+#define MDIO_PMA_10GBT_TXPWR   131     /* 10GBASE-T TX power control */
+#define MDIO_PMA_10GBT_SNR     133     /* 10GBASE-T SNR margin, lane A.
+                                        * Lanes B-D are numbered 134-136. */
+#define MDIO_PMA_10GBR_FECABLE 170     /* 10GBASE-R FEC ability */
+#define MDIO_PCS_10GBX_STAT1   24      /* 10GBASE-X PCS status 1 */
+#define MDIO_PCS_10GBRT_STAT1  32      /* 10GBASE-R/-T PCS status 1 */
+#define MDIO_PCS_10GBRT_STAT2  33      /* 10GBASE-R/-T PCS status 2 */
+#define MDIO_AN_10GBT_CTRL     32      /* 10GBASE-T auto-negotiation control */
+#define MDIO_AN_10GBT_STAT     33      /* 10GBASE-T auto-negotiation status */
+
+/* LASI (Link Alarm Status Interrupt) registers, defined by XENPAK MSA. */
+#define MDIO_PMA_LASI_RXCTRL   0x9000  /* RX_ALARM control */
+#define MDIO_PMA_LASI_TXCTRL   0x9001  /* TX_ALARM control */
+#define MDIO_PMA_LASI_CTRL     0x9002  /* LASI control */
+#define MDIO_PMA_LASI_RXSTAT   0x9003  /* RX_ALARM status */
+#define MDIO_PMA_LASI_TXSTAT   0x9004  /* TX_ALARM status */
+#define MDIO_PMA_LASI_STAT     0x9005  /* LASI status */
+
+/* Control register 1. */
+/* Enable extended speed selection */
+#define MDIO_CTRL1_SPEEDSELEXT         (BMCR_SPEED1000 | BMCR_SPEED100)
+/* All speed selection bits */
+#define MDIO_CTRL1_SPEEDSEL            (MDIO_CTRL1_SPEEDSELEXT | 0x003c)
+#define MDIO_CTRL1_FULLDPLX            BMCR_FULLDPLX
+#define MDIO_CTRL1_LPOWER              BMCR_PDOWN
+#define MDIO_CTRL1_RESET               BMCR_RESET
+#define MDIO_PMA_CTRL1_LOOPBACK                0x0001
+#define MDIO_PMA_CTRL1_SPEED1000       BMCR_SPEED1000
+#define MDIO_PMA_CTRL1_SPEED100                BMCR_SPEED100
+#define MDIO_PCS_CTRL1_LOOPBACK                BMCR_LOOPBACK
+#define MDIO_PHYXS_CTRL1_LOOPBACK      BMCR_LOOPBACK
+#define MDIO_AN_CTRL1_RESTART          BMCR_ANRESTART
+#define MDIO_AN_CTRL1_ENABLE           BMCR_ANENABLE
+#define MDIO_AN_CTRL1_XNP              0x2000  /* Enable extended next page */
+
+/* 10 Gb/s */
+#define MDIO_CTRL1_SPEED10G            (MDIO_CTRL1_SPEEDSELEXT | 0x00)
+/* 10PASS-TS/2BASE-TL */
+#define MDIO_CTRL1_SPEED10P2B          (MDIO_CTRL1_SPEEDSELEXT | 0x04)
+
+/* Status register 1. */
+#define MDIO_STAT1_LPOWERABLE          0x0002  /* Low-power ability */
+#define MDIO_STAT1_LSTATUS             BMSR_LSTATUS
+#define MDIO_STAT1_FAULT               0x0080  /* Fault */
+#define MDIO_AN_STAT1_LPABLE           0x0001  /* Link partner AN ability */
+#define MDIO_AN_STAT1_ABLE             BMSR_ANEGCAPABLE
+#define MDIO_AN_STAT1_RFAULT           BMSR_RFAULT
+#define MDIO_AN_STAT1_COMPLETE         BMSR_ANEGCOMPLETE
+#define MDIO_AN_STAT1_PAGE             0x0040  /* Page received */
+#define MDIO_AN_STAT1_XNP              0x0080  /* Extended next page status */
+
+/* Speed register. */
+#define MDIO_SPEED_10G                 0x0001  /* 10G capable */
+#define MDIO_PMA_SPEED_2B              0x0002  /* 2BASE-TL capable */
+#define MDIO_PMA_SPEED_10P             0x0004  /* 10PASS-TS capable */
+#define MDIO_PMA_SPEED_1000            0x0010  /* 1000M capable */
+#define MDIO_PMA_SPEED_100             0x0020  /* 100M capable */
+#define MDIO_PMA_SPEED_10              0x0040  /* 10M capable */
+#define MDIO_PCS_SPEED_10P2B           0x0002  /* 10PASS-TS/2BASE-TL capable */
+
+/* Device present registers. */
+#define MDIO_DEVS_PRESENT(devad)       (1 << (devad))
+#define MDIO_DEVS_PMAPMD               MDIO_DEVS_PRESENT(MDIO_MMD_PMAPMD)
+#define MDIO_DEVS_WIS                  MDIO_DEVS_PRESENT(MDIO_MMD_WIS)
+#define MDIO_DEVS_PCS                  MDIO_DEVS_PRESENT(MDIO_MMD_PCS)
+#define MDIO_DEVS_PHYXS                        MDIO_DEVS_PRESENT(MDIO_MMD_PHYXS)
+#define MDIO_DEVS_DTEXS                        MDIO_DEVS_PRESENT(MDIO_MMD_DTEXS)
+#define MDIO_DEVS_TC                   MDIO_DEVS_PRESENT(MDIO_MMD_TC)
+#define MDIO_DEVS_AN                   MDIO_DEVS_PRESENT(MDIO_MMD_AN)
+#define MDIO_DEVS_C22EXT               MDIO_DEVS_PRESENT(MDIO_MMD_C22EXT)
+
+/* Control register 2. */
+#define MDIO_PMA_CTRL2_TYPE            0x000f  /* PMA/PMD type selection */
+#define MDIO_PMA_CTRL2_10GBCX4         0x0000  /* 10GBASE-CX4 type */
+#define MDIO_PMA_CTRL2_10GBEW          0x0001  /* 10GBASE-EW type */
+#define MDIO_PMA_CTRL2_10GBLW          0x0002  /* 10GBASE-LW type */
+#define MDIO_PMA_CTRL2_10GBSW          0x0003  /* 10GBASE-SW type */
+#define MDIO_PMA_CTRL2_10GBLX4         0x0004  /* 10GBASE-LX4 type */
+#define MDIO_PMA_CTRL2_10GBER          0x0005  /* 10GBASE-ER type */
+#define MDIO_PMA_CTRL2_10GBLR          0x0006  /* 10GBASE-LR type */
+#define MDIO_PMA_CTRL2_10GBSR          0x0007  /* 10GBASE-SR type */
+#define MDIO_PMA_CTRL2_10GBLRM         0x0008  /* 10GBASE-LRM type */
+#define MDIO_PMA_CTRL2_10GBT           0x0009  /* 10GBASE-T type */
+#define MDIO_PMA_CTRL2_10GBKX4         0x000a  /* 10GBASE-KX4 type */
+#define MDIO_PMA_CTRL2_10GBKR          0x000b  /* 10GBASE-KR type */
+#define MDIO_PMA_CTRL2_1000BT          0x000c  /* 1000BASE-T type */
+#define MDIO_PMA_CTRL2_1000BKX         0x000d  /* 1000BASE-KX type */
+#define MDIO_PMA_CTRL2_100BTX          0x000e  /* 100BASE-TX type */
+#define MDIO_PMA_CTRL2_10BT            0x000f  /* 10BASE-T type */
+#define MDIO_PCS_CTRL2_TYPE            0x0003  /* PCS type selection */
+#define MDIO_PCS_CTRL2_10GBR           0x0000  /* 10GBASE-R type */
+#define MDIO_PCS_CTRL2_10GBX           0x0001  /* 10GBASE-X type */
+#define MDIO_PCS_CTRL2_10GBW           0x0002  /* 10GBASE-W type */
+#define MDIO_PCS_CTRL2_10GBT           0x0003  /* 10GBASE-T type */
+
+/* Status register 2. */
+#define MDIO_STAT2_RXFAULT             0x0400  /* Receive fault */
+#define MDIO_STAT2_TXFAULT             0x0800  /* Transmit fault */
+#define MDIO_STAT2_DEVPRST             0xc000  /* Device present */
+#define MDIO_STAT2_DEVPRST_VAL         0x8000  /* Device present value */
+#define MDIO_PMA_STAT2_LBABLE          0x0001  /* PMA loopback ability */
+#define MDIO_PMA_STAT2_10GBEW          0x0002  /* 10GBASE-EW ability */
+#define MDIO_PMA_STAT2_10GBLW          0x0004  /* 10GBASE-LW ability */
+#define MDIO_PMA_STAT2_10GBSW          0x0008  /* 10GBASE-SW ability */
+#define MDIO_PMA_STAT2_10GBLX4         0x0010  /* 10GBASE-LX4 ability */
+#define MDIO_PMA_STAT2_10GBER          0x0020  /* 10GBASE-ER ability */
+#define MDIO_PMA_STAT2_10GBLR          0x0040  /* 10GBASE-LR ability */
+#define MDIO_PMA_STAT2_10GBSR          0x0080  /* 10GBASE-SR ability */
+#define MDIO_PMD_STAT2_TXDISAB         0x0100  /* PMD TX disable ability */
+#define MDIO_PMA_STAT2_EXTABLE         0x0200  /* Extended abilities */
+#define MDIO_PMA_STAT2_RXFLTABLE       0x1000  /* Receive fault ability */
+#define MDIO_PMA_STAT2_TXFLTABLE       0x2000  /* Transmit fault ability */
+#define MDIO_PCS_STAT2_10GBR           0x0001  /* 10GBASE-R capable */
+#define MDIO_PCS_STAT2_10GBX           0x0002  /* 10GBASE-X capable */
+#define MDIO_PCS_STAT2_10GBW           0x0004  /* 10GBASE-W capable */
+#define MDIO_PCS_STAT2_RXFLTABLE       0x1000  /* Receive fault ability */
+#define MDIO_PCS_STAT2_TXFLTABLE       0x2000  /* Transmit fault ability */
+
+/* Transmit disable register. */
+#define MDIO_PMD_TXDIS_GLOBAL          0x0001  /* Global PMD TX disable */
+#define MDIO_PMD_TXDIS_0               0x0002  /* PMD TX disable 0 */
+#define MDIO_PMD_TXDIS_1               0x0004  /* PMD TX disable 1 */
+#define MDIO_PMD_TXDIS_2               0x0008  /* PMD TX disable 2 */
+#define MDIO_PMD_TXDIS_3               0x0010  /* PMD TX disable 3 */
+
+/* Receive signal detect register. */
+#define MDIO_PMD_RXDET_GLOBAL          0x0001  /* Global PMD RX signal detect */
+#define MDIO_PMD_RXDET_0               0x0002  /* PMD RX signal detect 0 */
+#define MDIO_PMD_RXDET_1               0x0004  /* PMD RX signal detect 1 */
+#define MDIO_PMD_RXDET_2               0x0008  /* PMD RX signal detect 2 */
+#define MDIO_PMD_RXDET_3               0x0010  /* PMD RX signal detect 3 */
+
+/* Extended abilities register. */
+#define MDIO_PMA_EXTABLE_10GCX4                0x0001  /* 10GBASE-CX4 ability */
+#define MDIO_PMA_EXTABLE_10GBLRM       0x0002  /* 10GBASE-LRM ability */
+#define MDIO_PMA_EXTABLE_10GBT         0x0004  /* 10GBASE-T ability */
+#define MDIO_PMA_EXTABLE_10GBKX4       0x0008  /* 10GBASE-KX4 ability */
+#define MDIO_PMA_EXTABLE_10GBKR                0x0010  /* 10GBASE-KR ability */
+#define MDIO_PMA_EXTABLE_1000BT                0x0020  /* 1000BASE-T ability */
+#define MDIO_PMA_EXTABLE_1000BKX       0x0040  /* 1000BASE-KX ability */
+#define MDIO_PMA_EXTABLE_100BTX                0x0080  /* 100BASE-TX ability */
+#define MDIO_PMA_EXTABLE_10BT          0x0100  /* 10BASE-T ability */
+
+/* PHY XGXS lane state register. */
+#define MDIO_PHYXS_LNSTAT_SYNC0                0x0001
+#define MDIO_PHYXS_LNSTAT_SYNC1                0x0002
+#define MDIO_PHYXS_LNSTAT_SYNC2                0x0004
+#define MDIO_PHYXS_LNSTAT_SYNC3                0x0008
+#define MDIO_PHYXS_LNSTAT_ALIGN                0x1000
+
+/* PMA 10GBASE-T pair swap & polarity */
+#define MDIO_PMA_10GBT_SWAPPOL_ABNX    0x0001  /* Pair A/B uncrossed */
+#define MDIO_PMA_10GBT_SWAPPOL_CDNX    0x0002  /* Pair C/D uncrossed */
+#define MDIO_PMA_10GBT_SWAPPOL_AREV    0x0100  /* Pair A polarity reversed */
+#define MDIO_PMA_10GBT_SWAPPOL_BREV    0x0200  /* Pair B polarity reversed */
+#define MDIO_PMA_10GBT_SWAPPOL_CREV    0x0400  /* Pair C polarity reversed */
+#define MDIO_PMA_10GBT_SWAPPOL_DREV    0x0800  /* Pair D polarity reversed */
+
+/* PMA 10GBASE-T TX power register. */
+#define MDIO_PMA_10GBT_TXPWR_SHORT     0x0001  /* Short-reach mode */
+
+/* PMA 10GBASE-T SNR registers. */
+/* Value is SNR margin in dB, clamped to range [-127, 127], plus 0x8000. */
+#define MDIO_PMA_10GBT_SNR_BIAS                0x8000
+#define MDIO_PMA_10GBT_SNR_MAX         127
+
+/* PMA 10GBASE-R FEC ability register. */
+#define MDIO_PMA_10GBR_FECABLE_ABLE    0x0001  /* FEC ability */
+#define MDIO_PMA_10GBR_FECABLE_ERRABLE 0x0002  /* FEC error indic. ability */
+
+/* PCS 10GBASE-R/-T status register 1. */
+#define MDIO_PCS_10GBRT_STAT1_BLKLK    0x0001  /* Block lock attained */
+
+/* PCS 10GBASE-R/-T status register 2. */
+#define MDIO_PCS_10GBRT_STAT2_ERR      0x00ff
+#define MDIO_PCS_10GBRT_STAT2_BER      0x3f00
+
+/* AN 10GBASE-T control register. */
+#define MDIO_AN_10GBT_CTRL_ADV10G      0x1000  /* Advertise 10GBASE-T */
+
+/* AN 10GBASE-T status register. */
+#define MDIO_AN_10GBT_STAT_LPTRR       0x0200  /* LP training reset req. */
+#define MDIO_AN_10GBT_STAT_LPLTABLE    0x0400  /* LP loop timing ability */
+#define MDIO_AN_10GBT_STAT_LP10G       0x0800  /* LP is 10GBT capable */
+#define MDIO_AN_10GBT_STAT_REMOK       0x1000  /* Remote OK */
+#define MDIO_AN_10GBT_STAT_LOCOK       0x2000  /* Local OK */
+#define MDIO_AN_10GBT_STAT_MS          0x4000  /* Master/slave config */
+#define MDIO_AN_10GBT_STAT_MSFLT       0x8000  /* Master/slave config fault */
+
+/* LASI RX_ALARM control/status registers. */
+#define MDIO_PMA_LASI_RX_PHYXSLFLT     0x0001  /* PHY XS RX local fault */
+#define MDIO_PMA_LASI_RX_PCSLFLT       0x0008  /* PCS RX local fault */
+#define MDIO_PMA_LASI_RX_PMALFLT       0x0010  /* PMA/PMD RX local fault */
+#define MDIO_PMA_LASI_RX_OPTICPOWERFLT 0x0020  /* RX optical power fault */
+#define MDIO_PMA_LASI_RX_WISLFLT       0x0200  /* WIS local fault */
+
+/* LASI TX_ALARM control/status registers. */
+#define MDIO_PMA_LASI_TX_PHYXSLFLT     0x0001  /* PHY XS TX local fault */
+#define MDIO_PMA_LASI_TX_PCSLFLT       0x0008  /* PCS TX local fault */
+#define MDIO_PMA_LASI_TX_PMALFLT       0x0010  /* PMA/PMD TX local fault */
+#define MDIO_PMA_LASI_TX_LASERPOWERFLT 0x0080  /* Laser output power fault */
+#define MDIO_PMA_LASI_TX_LASERTEMPFLT  0x0100  /* Laser temperature fault */
+#define MDIO_PMA_LASI_TX_LASERBICURRFLT        0x0200  /* Laser bias current fault */
+
+/* LASI control/status registers. */
+#define MDIO_PMA_LASI_LSALARM          0x0001  /* LS_ALARM enable/status */
+#define MDIO_PMA_LASI_TXALARM          0x0002  /* TX_ALARM enable/status */
+#define MDIO_PMA_LASI_RXALARM          0x0004  /* RX_ALARM enable/status */
+
+/* Mapping between MDIO PRTAD/DEVAD and mii_ioctl_data::phy_id */
+
+#define MDIO_PHY_ID_C45                        0x8000
+#define MDIO_PHY_ID_PRTAD              0x03e0
+#define MDIO_PHY_ID_DEVAD              0x001f
+#define MDIO_PHY_ID_C45_MASK                                           \
+       (MDIO_PHY_ID_C45 | MDIO_PHY_ID_PRTAD | MDIO_PHY_ID_DEVAD)
+
+static inline __u16 mdio_phy_id_c45(int prtad, int devad)
+{
+       return MDIO_PHY_ID_C45 | (prtad << 5) | devad;
+}
+
+static inline bool mdio_phy_id_is_c45(int phy_id)
+{
+       return (phy_id & MDIO_PHY_ID_C45) && !(phy_id & ~MDIO_PHY_ID_C45_MASK);
+}
+
+static inline __u16 mdio_phy_id_prtad(int phy_id)
+{
+       return (phy_id & MDIO_PHY_ID_PRTAD) >> 5;
+}
+
+static inline __u16 mdio_phy_id_devad(int phy_id)
+{
+       return phy_id & MDIO_PHY_ID_DEVAD;
+}
+
+#define MDIO_SUPPORTS_C22              1
+#define MDIO_SUPPORTS_C45              2
+
+#ifdef __KERNEL__ 
+
+/**
+ * struct mdio_if_info - Ethernet controller MDIO interface
+ * @prtad: PRTAD of the PHY (%MDIO_PRTAD_NONE if not present/unknown)
+ * @mmds: Mask of MMDs expected to be present in the PHY.  This must be
+ *     non-zero unless @prtad = %MDIO_PRTAD_NONE.
+ * @mode_support: MDIO modes supported.  If %MDIO_SUPPORTS_C22 is set then
+ *     MII register access will be passed through with @devad =
+ *     %MDIO_DEVAD_NONE.  If %MDIO_EMULATE_C22 is set then access to
+ *     commonly used clause 22 registers will be translated into
+ *     clause 45 registers.
+ * @dev: Net device structure
+ * @mdio_read: Register read function; returns value or negative error code
+ * @mdio_write: Register write function; returns 0 or negative error code
+ */
+struct mdio_if_info {
+       int prtad;
+       u32 __bitwise mmds;
+       unsigned mode_support;
+
+       struct net_device *dev;
+       int (*mdio_read)(struct net_device *dev, int prtad, int devad,
+                        u16 addr);
+       int (*mdio_write)(struct net_device *dev, int prtad, int devad,
+                         u16 addr, u16 val);
+};
+
+#define MDIO_PRTAD_NONE                        (-1)
+#define MDIO_DEVAD_NONE                        (-1)
+#define MDIO_EMULATE_C22               4
+
+struct ethtool_cmd;
+struct ethtool_pauseparam;
+extern int mdio45_probe(struct mdio_if_info *mdio, int prtad);
+extern int mdio_set_flag(const struct mdio_if_info *mdio,
+                        int prtad, int devad, u16 addr, int mask,
+                        bool sense);
+extern int mdio45_links_ok(const struct mdio_if_info *mdio, u32 mmds);
+extern int mdio45_nway_restart(const struct mdio_if_info *mdio);
+extern void mdio45_ethtool_gset_npage(const struct mdio_if_info *mdio,
+                                     struct ethtool_cmd *ecmd,
+                                     u32 npage_adv, u32 npage_lpa);
+extern void
+mdio45_ethtool_spauseparam_an(const struct mdio_if_info *mdio,
+                             const struct ethtool_pauseparam *ecmd);
+
+/**
+ * mdio45_ethtool_gset - get settings for ETHTOOL_GSET
+ * @mdio: MDIO interface
+ * @ecmd: Ethtool request structure
+ *
+ * Since the CSRs for auto-negotiation using next pages are not fully
+ * standardised, this function does not attempt to decode them.  Use
+ * mdio45_ethtool_gset_npage() to specify advertisement bits from next
+ * pages.
+ */
+static inline void mdio45_ethtool_gset(const struct mdio_if_info *mdio,
+                                      struct ethtool_cmd *ecmd)
+{
+       mdio45_ethtool_gset_npage(mdio, ecmd, 0, 0);
+}
+
+extern int mdio_mii_ioctl(const struct mdio_if_info *mdio,
+                         struct mii_ioctl_data *mii_data, int cmd);
+
+#endif /* __KERNEL__ */
+#endif /* __LINUX_MDIO_H__ */
index ad748588faf1a2c0e6af662dfd1e790ecc766aa9..359fba8802746111b4c10c640487b889dc9d6937 100644 (file)
@@ -239,6 +239,22 @@ static inline unsigned int mii_duplex (unsigned int duplex_lock,
        return 0;
 }
 
+/**
+ * mii_advertise_flowctrl - get flow control advertisement flags
+ * @cap: Flow control capabilities (FLOW_CTRL_RX, FLOW_CTRL_TX or both)
+ */
+static inline u16 mii_advertise_flowctrl(int cap)
+{
+       u16 adv = 0;
+
+       if (cap & FLOW_CTRL_RX)
+               adv = ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
+       if (cap & FLOW_CTRL_TX)
+               adv ^= ADVERTISE_PAUSE_ASYM;
+
+       return adv;
+}
+
 /**
  * mii_resolve_flowctrl_fdx
  * @lcladv: value of MII ADVERTISE register
@@ -250,18 +266,12 @@ static inline u8 mii_resolve_flowctrl_fdx(u16 lcladv, u16 rmtadv)
 {
        u8 cap = 0;
 
-       if (lcladv & ADVERTISE_PAUSE_CAP) {
-               if (lcladv & ADVERTISE_PAUSE_ASYM) {
-                       if (rmtadv & LPA_PAUSE_CAP)
-                               cap = FLOW_CTRL_TX | FLOW_CTRL_RX;
-                       else if (rmtadv & LPA_PAUSE_ASYM)
-                               cap = FLOW_CTRL_RX;
-               } else {
-                       if (rmtadv & LPA_PAUSE_CAP)
-                               cap = FLOW_CTRL_TX | FLOW_CTRL_RX;
-               }
-       } else if (lcladv & ADVERTISE_PAUSE_ASYM) {
-               if ((rmtadv & LPA_PAUSE_CAP) && (rmtadv & LPA_PAUSE_ASYM))
+       if (lcladv & rmtadv & ADVERTISE_PAUSE_CAP) {
+               cap = FLOW_CTRL_TX | FLOW_CTRL_RX;
+       } else if (lcladv & rmtadv & ADVERTISE_PAUSE_ASYM) {
+               if (lcladv & ADVERTISE_PAUSE_CAP)
+                       cap = FLOW_CTRL_RX;
+               else if (rmtadv & ADVERTISE_PAUSE_CAP)
                        cap = FLOW_CTRL_TX;
        }
 
index ea1bf5ba092f79b50e72b07e250362b5731194ae..c7211ab6dd4be15f61ba7cc899703f0f29b08474 100644 (file)
@@ -25,5 +25,7 @@
 
 #define SDIO_VENDOR_ID_MARVELL                 0x02df
 #define SDIO_DEVICE_ID_MARVELL_LIBERTAS                0x9103
+#define SDIO_DEVICE_ID_MARVELL_8688WLAN                0x9104
+#define SDIO_DEVICE_ID_MARVELL_8688BT          0x9105
 
 #endif
index 0e2e100c44a275f719377d7c0e2ad113743d404d..3ceb0cc1bc787382dd00d3ea27292422f161881b 100644 (file)
@@ -3,12 +3,20 @@
 
 #include <linux/types.h>
 #include <linux/netlink.h>
+#include <linux/types.h>
 
 struct net_dm_drop_point {
        __u8 pc[8];
        __u32 count;
 };
 
+#define is_drop_point_hw(x) do {\
+       int ____i, ____j;\
+       for (____i = 0; ____i < 8; i ____i++)\
+               ____j |= x[____i];\
+       ____j;\
+} while (0)
+
 #define NET_DM_CFG_VERSION  0
 #define NET_DM_CFG_ALERT_COUNT  1
 #define NET_DM_CFG_ALERT_DELAY 2
index 5a96a1a406e9017d96a51067923f503fb592deb4..9ea8d6dfe54058ae95515de7f1b6bcdcb173142f 100644 (file)
 
 #include <linux/device.h>
 #include <linux/percpu.h>
+#include <linux/rculist.h>
 #include <linux/dmaengine.h>
 #include <linux/workqueue.h>
 
+#include <linux/ethtool.h>
 #include <net/net_namespace.h>
 #include <net/dsa.h>
 #ifdef CONFIG_DCB
@@ -49,7 +51,6 @@
 #endif
 
 struct vlan_group;
-struct ethtool_ops;
 struct netpoll_info;
 /* 802.11 specific */
 struct wireless_dev;
@@ -210,6 +211,19 @@ struct dev_addr_list
 #define dmi_users      da_users
 #define dmi_gusers     da_gusers
 
+struct netdev_hw_addr {
+       struct list_head        list;
+       unsigned char           addr[MAX_ADDR_LEN];
+       unsigned char           type;
+#define NETDEV_HW_ADDR_T_LAN           1
+#define NETDEV_HW_ADDR_T_SAN           2
+#define NETDEV_HW_ADDR_T_SLAVE         3
+#define NETDEV_HW_ADDR_T_UNICAST       4
+       int                     refcount;
+       bool                    synced;
+       struct rcu_head         rcu_head;
+};
+
 struct hh_cache
 {
        struct hh_cache *hh_next;       /* Next entry                        */
@@ -447,12 +461,25 @@ enum netdev_queue_state_t
 };
 
 struct netdev_queue {
+/*
+ * read mostly part
+ */
        struct net_device       *dev;
        struct Qdisc            *qdisc;
        unsigned long           state;
-       spinlock_t              _xmit_lock;
-       int                     xmit_lock_owner;
        struct Qdisc            *qdisc_sleeping;
+/*
+ * write mostly part
+ */
+       spinlock_t              _xmit_lock ____cacheline_aligned_in_smp;
+       int                     xmit_lock_owner;
+       /*
+        * please use this field instead of dev->trans_start
+        */
+       unsigned long           trans_start;
+       unsigned long           tx_bytes;
+       unsigned long           tx_packets;
+       unsigned long           tx_dropped;
 } ____cacheline_aligned_in_smp;
 
 
@@ -670,7 +697,9 @@ struct net_device
 #define NETIF_F_GRO            16384   /* Generic receive offload */
 #define NETIF_F_LRO            32768   /* large receive offload */
 
+/* the GSO_MASK reserves bits 16 through 23 */
 #define NETIF_F_FCOE_CRC       (1 << 24) /* FCoE CRC32 */
+#define NETIF_F_SCTP_CSUM      (1 << 25) /* SCTP checksum offload */
 
        /* Segmentation offload features */
 #define NETIF_F_GSO_SHIFT      16
@@ -747,10 +776,11 @@ struct net_device
        unsigned char           addr_len;       /* hardware address length      */
        unsigned short          dev_id;         /* for shared network cards */
 
-       spinlock_t              addr_list_lock;
-       struct dev_addr_list    *uc_list;       /* Secondary unicast mac addresses */
+       struct list_head        uc_list;        /* Secondary unicast mac
+                                                  addresses */
        int                     uc_count;       /* Number of installed ucasts   */
        int                     uc_promisc;
+       spinlock_t              addr_list_lock;
        struct dev_addr_list    *mc_list;       /* Multicast mac addresses      */
        int                     mc_count;       /* Number of installed mcasts   */
        unsigned int            promiscuity;
@@ -776,8 +806,11 @@ struct net_device
  */
        unsigned long           last_rx;        /* Time of last Rx      */
        /* Interface address info used in eth_type_trans() */
-       unsigned char           dev_addr[MAX_ADDR_LEN]; /* hw address, (before bcast
-                                                          because most packets are unicast) */
+       unsigned char           *dev_addr;      /* hw address, (before bcast
+                                                  because most packets are
+                                                  unicast) */
+
+       struct list_head        dev_addr_list; /* list of device hw addresses */
 
        unsigned char           broadcast[MAX_ADDR_LEN];        /* hw bcast add */
 
@@ -797,6 +830,11 @@ struct net_device
  * One part is mostly used on xmit path (device)
  */
        /* These may be needed for future network-power-down code. */
+
+       /*
+        * trans_start here is expensive for high speed devices on SMP,
+        * please use netdev_queue->trans_start instead.
+        */
        unsigned long           trans_start;    /* Time (in jiffies) of last Tx */
 
        int                     watchdog_timeo; /* used by dev_watchdog() */
@@ -867,49 +905,10 @@ struct net_device
        /* max exchange id for FCoE LRO by ddp */
        unsigned int            fcoe_ddp_xid;
 #endif
-
-#ifdef CONFIG_COMPAT_NET_DEV_OPS
-       struct {
-               int                     (*init)(struct net_device *dev);
-               void                    (*uninit)(struct net_device *dev);
-               int                     (*open)(struct net_device *dev);
-               int                     (*stop)(struct net_device *dev);
-               int                     (*hard_start_xmit) (struct sk_buff *skb,
-                                                           struct net_device *dev);
-               u16                     (*select_queue)(struct net_device *dev,
-                                                       struct sk_buff *skb);
-               void                    (*change_rx_flags)(struct net_device *dev,
-                                                          int flags);
-               void                    (*set_rx_mode)(struct net_device *dev);
-               void                    (*set_multicast_list)(struct net_device *dev);
-               int                     (*set_mac_address)(struct net_device *dev,
-                                                          void *addr);
-               int                     (*validate_addr)(struct net_device *dev);
-               int                     (*do_ioctl)(struct net_device *dev,
-                                                   struct ifreq *ifr, int cmd);
-               int                     (*set_config)(struct net_device *dev,
-                                                     struct ifmap *map);
-               int                     (*change_mtu)(struct net_device *dev, int new_mtu);
-               int                     (*neigh_setup)(struct net_device *dev,
-                                                      struct neigh_parms *);
-               void                    (*tx_timeout) (struct net_device *dev);
-               struct net_device_stats* (*get_stats)(struct net_device *dev);
-               void                    (*vlan_rx_register)(struct net_device *dev,
-                                                           struct vlan_group *grp);
-               void                    (*vlan_rx_add_vid)(struct net_device *dev,
-                                                          unsigned short vid);
-               void                    (*vlan_rx_kill_vid)(struct net_device *dev,
-                                                           unsigned short vid);
-#ifdef CONFIG_NET_POLL_CONTROLLER
-               void                    (*poll_controller)(struct net_device *dev);
-#endif
-       };
-#endif
 };
 #define to_net_dev(d) container_of(d, struct net_device, dev)
 
 #define        NETDEV_ALIGN            32
-#define        NETDEV_ALIGN_CONST      (NETDEV_ALIGN - 1)
 
 static inline
 struct netdev_queue *netdev_get_tx_queue(const struct net_device *dev,
@@ -980,9 +979,7 @@ static inline bool netdev_uses_trailer_tags(struct net_device *dev)
  */
 static inline void *netdev_priv(const struct net_device *dev)
 {
-       return (char *)dev + ((sizeof(struct net_device)
-                              + NETDEV_ALIGN_CONST)
-                             & ~NETDEV_ALIGN_CONST);
+       return (char *)dev + ALIGN(sizeof(struct net_device), NETDEV_ALIGN);
 }
 
 /* Set the sysfs physical device reference for the network logical device
@@ -1012,6 +1009,12 @@ void netif_napi_add(struct net_device *dev, struct napi_struct *napi,
 void netif_napi_del(struct napi_struct *napi);
 
 struct napi_gro_cb {
+       /* Virtual address of skb_shinfo(skb)->frags[0].page + offset. */
+       void *frag0;
+
+       /* Length of frag0. */
+       unsigned int frag0_len;
+
        /* This indicates where we are processing relative to skb->data. */
        int data_offset;
 
@@ -1047,14 +1050,6 @@ struct packet_type {
        struct list_head        list;
 };
 
-struct napi_gro_fraginfo {
-       skb_frag_t frags[MAX_SKB_FRAGS];
-       unsigned int nr_frags;
-       unsigned int ip_summed;
-       unsigned int len;
-       __wsum csum;
-};
-
 #include <linux/interrupt.h>
 #include <linux/notifier.h>
 
@@ -1119,9 +1114,9 @@ extern int                dev_restart(struct net_device *dev);
 #ifdef CONFIG_NETPOLL_TRAP
 extern int             netpoll_trap(void);
 #endif
-extern void          *skb_gro_header(struct sk_buff *skb, unsigned int hlen);
 extern int            skb_gro_receive(struct sk_buff **head,
                                       struct sk_buff *skb);
+extern void           skb_gro_reset_offset(struct sk_buff *skb);
 
 static inline unsigned int skb_gro_offset(const struct sk_buff *skb)
 {
@@ -1138,16 +1133,34 @@ static inline void skb_gro_pull(struct sk_buff *skb, unsigned int len)
        NAPI_GRO_CB(skb)->data_offset += len;
 }
 
-static inline void skb_gro_reset_offset(struct sk_buff *skb)
+static inline void *skb_gro_header_fast(struct sk_buff *skb,
+                                       unsigned int offset)
 {
-       NAPI_GRO_CB(skb)->data_offset = 0;
+       return NAPI_GRO_CB(skb)->frag0 + offset;
+}
+
+static inline int skb_gro_header_hard(struct sk_buff *skb, unsigned int hlen)
+{
+       return NAPI_GRO_CB(skb)->frag0_len < hlen;
+}
+
+static inline void *skb_gro_header_slow(struct sk_buff *skb, unsigned int hlen,
+                                       unsigned int offset)
+{
+       NAPI_GRO_CB(skb)->frag0 = NULL;
+       NAPI_GRO_CB(skb)->frag0_len = 0;
+       return pskb_may_pull(skb, hlen) ? skb->data + offset : NULL;
 }
 
 static inline void *skb_gro_mac_header(struct sk_buff *skb)
 {
-       return skb_mac_header(skb) < skb->data ? skb_mac_header(skb) :
-              page_address(skb_shinfo(skb)->frags[0].page) +
-              skb_shinfo(skb)->frags[0].page_offset;
+       return NAPI_GRO_CB(skb)->frag0 ?: skb_mac_header(skb);
+}
+
+static inline void *skb_gro_network_header(struct sk_buff *skb)
+{
+       return (NAPI_GRO_CB(skb)->frag0 ?: skb->data) +
+              skb_network_offset(skb);
 }
 
 static inline int dev_hard_header(struct sk_buff *skb, struct net_device *dev,
@@ -1442,12 +1455,18 @@ extern int              napi_gro_receive(struct napi_struct *napi,
                                         struct sk_buff *skb);
 extern void            napi_reuse_skb(struct napi_struct *napi,
                                       struct sk_buff *skb);
-extern struct sk_buff *        napi_fraginfo_skb(struct napi_struct *napi,
-                                         struct napi_gro_fraginfo *info);
+extern struct sk_buff *        napi_get_frags(struct napi_struct *napi);
 extern int             napi_frags_finish(struct napi_struct *napi,
                                          struct sk_buff *skb, int ret);
-extern int             napi_gro_frags(struct napi_struct *napi,
-                                      struct napi_gro_fraginfo *info);
+extern struct sk_buff *        napi_frags_skb(struct napi_struct *napi);
+extern int             napi_gro_frags(struct napi_struct *napi);
+
+static inline void napi_free_frags(struct napi_struct *napi)
+{
+       kfree_skb(napi->skb);
+       napi->skb = NULL;
+}
+
 extern void            netif_nit_deliver(struct sk_buff *skb);
 extern int             dev_valid_name(const char *name);
 extern int             dev_ioctl(struct net *net, unsigned int cmd, void __user *);
@@ -1514,6 +1533,8 @@ static inline int netif_carrier_ok(const struct net_device *dev)
        return !test_bit(__LINK_STATE_NOCARRIER, &dev->state);
 }
 
+extern unsigned long dev_trans_start(struct net_device *dev);
+
 extern void __netdev_watchdog_up(struct net_device *dev);
 
 extern void netif_carrier_on(struct net_device *dev);
@@ -1671,6 +1692,12 @@ static inline void __netif_tx_unlock_bh(struct netdev_queue *txq)
        spin_unlock_bh(&txq->_xmit_lock);
 }
 
+static inline void txq_trans_update(struct netdev_queue *txq)
+{
+       if (txq->xmit_lock_owner != -1)
+               txq->trans_start = jiffies;
+}
+
 /**
  *     netif_tx_lock - grab network device transmit lock
  *     @dev: network device
@@ -1778,6 +1805,13 @@ static inline void netif_addr_unlock_bh(struct net_device *dev)
        spin_unlock_bh(&dev->addr_list_lock);
 }
 
+/*
+ * dev_addr_list walker. Should be used only for read access. Call with
+ * rcu_read_lock held.
+ */
+#define for_each_dev_addr(dev, ha) \
+               list_for_each_entry_rcu(ha, &dev->dev_addr_list, list)
+
 /* These functions live elsewhere (drivers/net/net_init.c, but related) */
 
 extern void            ether_setup(struct net_device *dev);
@@ -1790,11 +1824,24 @@ extern struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name,
        alloc_netdev_mq(sizeof_priv, name, setup, 1)
 extern int             register_netdev(struct net_device *dev);
 extern void            unregister_netdev(struct net_device *dev);
+
+/* Functions used for device addresses handling */
+extern int dev_addr_add(struct net_device *dev, unsigned char *addr,
+                       unsigned char addr_type);
+extern int dev_addr_del(struct net_device *dev, unsigned char *addr,
+                       unsigned char addr_type);
+extern int dev_addr_add_multiple(struct net_device *to_dev,
+                                struct net_device *from_dev,
+                                unsigned char addr_type);
+extern int dev_addr_del_multiple(struct net_device *to_dev,
+                                struct net_device *from_dev,
+                                unsigned char addr_type);
+
 /* Functions used for secondary unicast and multicast support */
 extern void            dev_set_rx_mode(struct net_device *dev);
 extern void            __dev_set_rx_mode(struct net_device *dev);
-extern int             dev_unicast_delete(struct net_device *dev, void *addr, int alen);
-extern int             dev_unicast_add(struct net_device *dev, void *addr, int alen);
+extern int             dev_unicast_delete(struct net_device *dev, void *addr);
+extern int             dev_unicast_add(struct net_device *dev, void *addr);
 extern int             dev_unicast_sync(struct net_device *to, struct net_device *from);
 extern void            dev_unicast_unsync(struct net_device *to, struct net_device *from);
 extern int             dev_mc_delete(struct net_device *dev, void *addr, int alen, int all);
@@ -1856,15 +1903,14 @@ static inline int net_gso_ok(int features, int gso_type)
 
 static inline int skb_gso_ok(struct sk_buff *skb, int features)
 {
-       return net_gso_ok(features, skb_shinfo(skb)->gso_type);
+       return net_gso_ok(features, skb_shinfo(skb)->gso_type) &&
+              (!skb_has_frags(skb) || (features & NETIF_F_FRAGLIST));
 }
 
 static inline int netif_needs_gso(struct net_device *dev, struct sk_buff *skb)
 {
        return skb_is_gso(skb) &&
               (!skb_gso_ok(skb, dev->features) ||
-               (skb_shinfo(skb)->frag_list &&
-                !(dev->features & NETIF_F_FRAGLIST)) ||
                unlikely(skb->ip_summed != CHECKSUM_PARTIAL));
 }
 
@@ -1874,6 +1920,16 @@ static inline void netif_set_gso_max_size(struct net_device *dev,
        dev->gso_max_size = size;
 }
 
+static inline void skb_bond_set_mac_by_master(struct sk_buff *skb,
+                                             struct net_device *master)
+{
+       if (skb->pkt_type == PACKET_HOST) {
+               u16 *dest = (u16 *) eth_hdr(skb)->h_dest;
+
+               memcpy(dest, master->dev_addr, ETH_ALEN);
+       }
+}
+
 /* On bonding slaves other than the currently active slave, suppress
  * duplicates except for 802.3ad ETH_P_SLOW, alb non-mcast/bcast, and
  * ARP on active-backup slaves with arp_validate enabled.
@@ -1887,6 +1943,14 @@ static inline int skb_bond_should_drop(struct sk_buff *skb)
                if (master->priv_flags & IFF_MASTER_ARPMON)
                        dev->last_rx = jiffies;
 
+               if ((master->priv_flags & IFF_MASTER_ALB) && master->br_port) {
+                       /* Do address unmangle. The local destination address
+                        * will be always the one master has. Provides the right
+                        * functionality in a bridge.
+                        */
+                       skb_bond_set_mac_by_master(skb, master);
+               }
+
                if (dev->priv_flags & IFF_SLAVE_INACTIVE) {
                        if ((dev->priv_flags & IFF_SLAVE_NEEDARP) &&
                            skb->protocol == __cpu_to_be16(ETH_P_ARP))
@@ -1908,6 +1972,28 @@ static inline int skb_bond_should_drop(struct sk_buff *skb)
 }
 
 extern struct pernet_operations __net_initdata loopback_net_ops;
+
+static inline int dev_ethtool_get_settings(struct net_device *dev,
+                                          struct ethtool_cmd *cmd)
+{
+       if (!dev->ethtool_ops || !dev->ethtool_ops->get_settings)
+               return -EOPNOTSUPP;
+       return dev->ethtool_ops->get_settings(dev, cmd);
+}
+
+static inline u32 dev_ethtool_get_rx_csum(struct net_device *dev)
+{
+       if (!dev->ethtool_ops || !dev->ethtool_ops->get_rx_csum)
+               return 0;
+       return dev->ethtool_ops->get_rx_csum(dev);
+}
+
+static inline u32 dev_ethtool_get_flags(struct net_device *dev)
+{
+       if (!dev->ethtool_ops || !dev->ethtool_ops->get_flags)
+               return 0;
+       return dev->ethtool_ops->get_flags(dev);
+}
 #endif /* __KERNEL__ */
 
-#endif /* _LINUX_DEV_H */
+#endif /* _LINUX_NETDEVICE_H */
index af9d2fb97212966ae2661894f3fe0d7e872ae376..2aea50399c0b0f761eaed0d11098a0c2a4c97ddc 100644 (file)
@@ -33,6 +33,7 @@ header-y += xt_limit.h
 header-y += xt_mac.h
 header-y += xt_mark.h
 header-y += xt_multiport.h
+header-y += xt_osf.h
 header-y += xt_owner.h
 header-y += xt_pkttype.h
 header-y += xt_quota.h
index 885cbe282260dcb2658f9e8fe680b066809d3fbe..a8248ee422b7e35f98babd634b9e41408b87e26d 100644 (file)
@@ -75,75 +75,6 @@ enum ip_conntrack_status {
        IPS_FIXED_TIMEOUT = (1 << IPS_FIXED_TIMEOUT_BIT),
 };
 
-/* Connection tracking event bits */
-enum ip_conntrack_events
-{
-       /* New conntrack */
-       IPCT_NEW_BIT = 0,
-       IPCT_NEW = (1 << IPCT_NEW_BIT),
-
-       /* Expected connection */
-       IPCT_RELATED_BIT = 1,
-       IPCT_RELATED = (1 << IPCT_RELATED_BIT),
-
-       /* Destroyed conntrack */
-       IPCT_DESTROY_BIT = 2,
-       IPCT_DESTROY = (1 << IPCT_DESTROY_BIT),
-
-       /* Timer has been refreshed */
-       IPCT_REFRESH_BIT = 3,
-       IPCT_REFRESH = (1 << IPCT_REFRESH_BIT),
-
-       /* Status has changed */
-       IPCT_STATUS_BIT = 4,
-       IPCT_STATUS = (1 << IPCT_STATUS_BIT),
-
-       /* Update of protocol info */
-       IPCT_PROTOINFO_BIT = 5,
-       IPCT_PROTOINFO = (1 << IPCT_PROTOINFO_BIT),
-
-       /* Volatile protocol info */
-       IPCT_PROTOINFO_VOLATILE_BIT = 6,
-       IPCT_PROTOINFO_VOLATILE = (1 << IPCT_PROTOINFO_VOLATILE_BIT),
-
-       /* New helper for conntrack */
-       IPCT_HELPER_BIT = 7,
-       IPCT_HELPER = (1 << IPCT_HELPER_BIT),
-
-       /* Update of helper info */
-       IPCT_HELPINFO_BIT = 8,
-       IPCT_HELPINFO = (1 << IPCT_HELPINFO_BIT),
-
-       /* Volatile helper info */
-       IPCT_HELPINFO_VOLATILE_BIT = 9,
-       IPCT_HELPINFO_VOLATILE = (1 << IPCT_HELPINFO_VOLATILE_BIT),
-
-       /* NAT info */
-       IPCT_NATINFO_BIT = 10,
-       IPCT_NATINFO = (1 << IPCT_NATINFO_BIT),
-
-       /* Counter highest bit has been set, unused */
-       IPCT_COUNTER_FILLING_BIT = 11,
-       IPCT_COUNTER_FILLING = (1 << IPCT_COUNTER_FILLING_BIT),
-
-       /* Mark is set */
-       IPCT_MARK_BIT = 12,
-       IPCT_MARK = (1 << IPCT_MARK_BIT),
-
-       /* NAT sequence adjustment */
-       IPCT_NATSEQADJ_BIT = 13,
-       IPCT_NATSEQADJ = (1 << IPCT_NATSEQADJ_BIT),
-
-       /* Secmark is set */
-       IPCT_SECMARK_BIT = 14,
-       IPCT_SECMARK = (1 << IPCT_SECMARK_BIT),
-};
-
-enum ip_conntrack_expect_events {
-       IPEXP_NEW_BIT = 0,
-       IPEXP_NEW = (1 << IPEXP_NEW_BIT),
-};
-
 #ifdef __KERNEL__
 struct ip_conntrack_stat
 {
index b2f384d42611ca7c604540c7c6761b30d5fc9592..4352feed23775831bfbf8373c85c44df9dfd14be 100644 (file)
@@ -15,7 +15,8 @@ enum tcp_conntrack {
        TCP_CONNTRACK_LAST_ACK,
        TCP_CONNTRACK_TIME_WAIT,
        TCP_CONNTRACK_CLOSE,
-       TCP_CONNTRACK_LISTEN,
+       TCP_CONNTRACK_LISTEN,   /* obsolete */
+#define TCP_CONNTRACK_SYN_SENT2        TCP_CONNTRACK_LISTEN
        TCP_CONNTRACK_MAX,
        TCP_CONNTRACK_IGNORE
 };
index c600083cbdf50ccc29774d2bd8c8f8cb1ca551ba..bff4d5741d98c19ad32a5e87a401713514a67dbc 100644 (file)
@@ -46,7 +46,8 @@ struct nfgenmsg {
 #define NFNL_SUBSYS_CTNETLINK_EXP      2
 #define NFNL_SUBSYS_QUEUE              3
 #define NFNL_SUBSYS_ULOG               4
-#define NFNL_SUBSYS_COUNT              5
+#define NFNL_SUBSYS_OSF                        5
+#define NFNL_SUBSYS_COUNT              6
 
 #ifdef __KERNEL__
 
@@ -75,7 +76,7 @@ extern int nfnetlink_subsys_unregister(const struct nfnetlink_subsystem *n);
 
 extern int nfnetlink_has_listeners(unsigned int group);
 extern int nfnetlink_send(struct sk_buff *skb, u32 pid, unsigned group, 
-                         int echo);
+                         int echo, gfp_t flags);
 extern void nfnetlink_set_err(u32 pid, u32 group, int error);
 extern int nfnetlink_unicast(struct sk_buff *skb, u_int32_t pid, int flags);
 
index 1a865e48b8ebf583a1e6235b64d4ed9fb9eb24d5..ed4ef8d0b11b6348b65ddeb49aa7d1b5e6f6a948 100644 (file)
@@ -101,6 +101,7 @@ enum ctattr_protoinfo_dccp {
        CTA_PROTOINFO_DCCP_UNSPEC,
        CTA_PROTOINFO_DCCP_STATE,
        CTA_PROTOINFO_DCCP_ROLE,
+       CTA_PROTOINFO_DCCP_HANDSHAKE_SEQ,
        __CTA_PROTOINFO_DCCP_MAX,
 };
 #define CTA_PROTOINFO_DCCP_MAX (__CTA_PROTOINFO_DCCP_MAX - 1)
index c9efe039dc57c4e2c2dce6ec11751a3d6d1c9819..1030b7593898d440498b221cf9828809076bc6da 100644 (file)
@@ -184,9 +184,10 @@ struct xt_counters_info
  * @matchinfo: per-match data
  * @fragoff:   packet is a fragment, this is the data offset
  * @thoff:     position of transport header relative to skb->data
- * @hotdrop:   drop packet if we had inspection problems
+ * @hook:      hook number given packet came from
  * @family:    Actual NFPROTO_* through which the function is invoked
  *             (helpful when match->family == NFPROTO_UNSPEC)
+ * @hotdrop:   drop packet if we had inspection problems
  */
 struct xt_match_param {
        const struct net_device *in, *out;
@@ -194,8 +195,9 @@ struct xt_match_param {
        const void *matchinfo;
        int fragoff;
        unsigned int thoff;
-       bool *hotdrop;
+       unsigned int hooknum;
        u_int8_t family;
+       bool *hotdrop;
 };
 
 /**
index 982a89f7827272c202a752b69776715594712605..2584f4a777def8fcaf11960d05a2be7386ba63ad 100644 (file)
@@ -15,4 +15,9 @@ struct xt_NFQ_info {
        __u16 queuenum;
 };
 
+struct xt_NFQ_info_v1 {
+       __u16 queuenum;
+       __u16 queues_total;
+};
+
 #endif /* _XT_NFQ_TARGET_H */
diff --git a/include/linux/netfilter/xt_osf.h b/include/linux/netfilter/xt_osf.h
new file mode 100644 (file)
index 0000000..fd2272e
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2003+ Evgeniy Polyakov <johnpol@2ka.mxt.ru>
+ *
+ *
+ * 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
+ */
+
+#ifndef _XT_OSF_H
+#define _XT_OSF_H
+
+#define MAXGENRELEN            32
+
+#define XT_OSF_GENRE           (1<<0)
+#define        XT_OSF_TTL              (1<<1)
+#define XT_OSF_LOG             (1<<2)
+#define XT_OSF_INVERT          (1<<3)
+
+#define XT_OSF_LOGLEVEL_ALL    0       /* log all matched fingerprints */
+#define XT_OSF_LOGLEVEL_FIRST  1       /* log only the first matced fingerprint */
+#define XT_OSF_LOGLEVEL_ALL_KNOWN      2 /* do not log unknown packets */
+
+#define XT_OSF_TTL_TRUE                0       /* True ip and fingerprint TTL comparison */
+#define XT_OSF_TTL_LESS                1       /* Check if ip TTL is less than fingerprint one */
+#define XT_OSF_TTL_NOCHECK     2       /* Do not compare ip and fingerprint TTL at all */
+
+struct xt_osf_info {
+       char                    genre[MAXGENRELEN];
+       __u32                   len;
+       __u32                   flags;
+       __u32                   loglevel;
+       __u32                   ttl;
+};
+
+/*
+ * Wildcard MSS (kind of).
+ * It is used to implement a state machine for the different wildcard values
+ * of the MSS and window sizes.
+ */
+struct xt_osf_wc {
+       __u32                   wc;
+       __u32                   val;
+};
+
+/*
+ * This struct represents IANA options
+ * http://www.iana.org/assignments/tcp-parameters
+ */
+struct xt_osf_opt {
+       __u16                   kind, length;
+       struct xt_osf_wc        wc;
+};
+
+struct xt_osf_user_finger {
+       struct xt_osf_wc        wss;
+
+       __u8                    ttl, df;
+       __u16                   ss, mss;
+       __u16                   opt_num;
+
+       char                    genre[MAXGENRELEN];
+       char                    version[MAXGENRELEN];
+       char                    subtype[MAXGENRELEN];
+
+       /* MAX_IPOPTLEN is maximum if all options are NOPs or EOLs */
+       struct xt_osf_opt       opt[MAX_IPOPTLEN];
+};
+
+struct xt_osf_nlmsg {
+       struct xt_osf_user_finger       f;
+       struct iphdr            ip;
+       struct tcphdr           tcp;
+};
+
+/* Defines for IANA option kinds */
+
+enum iana_options {
+       OSFOPT_EOL = 0,         /* End of options */
+       OSFOPT_NOP,             /* NOP */
+       OSFOPT_MSS,             /* Maximum segment size */
+       OSFOPT_WSO,             /* Window scale option */
+       OSFOPT_SACKP,           /* SACK permitted */
+       OSFOPT_SACK,            /* SACK */
+       OSFOPT_ECHO,
+       OSFOPT_ECHOREPLY,
+       OSFOPT_TS,              /* Timestamp option */
+       OSFOPT_POCP,            /* Partial Order Connection Permitted */
+       OSFOPT_POSP,            /* Partial Order Service Profile */
+
+       /* Others are not used in the current OSF */
+       OSFOPT_EMPTY = 255,
+};
+
+/*
+ * Initial window size option state machine: multiple of mss, mtu or
+ * plain numeric value. Can also be made as plain numeric value which
+ * is not a multiple of specified value.
+ */
+enum xt_osf_window_size_options {
+       OSF_WSS_PLAIN   = 0,
+       OSF_WSS_MSS,
+       OSF_WSS_MTU,
+       OSF_WSS_MODULO,
+       OSF_WSS_MAX,
+};
+
+/*
+ * Add/remove fingerprint from the kernel.
+ */
+enum xt_osf_msg_types {
+       OSF_MSG_ADD,
+       OSF_MSG_REMOVE,
+       OSF_MSG_MAX,
+};
+
+enum xt_osf_attr_type {
+       OSF_ATTR_UNSPEC,
+       OSF_ATTR_FINGER,
+       OSF_ATTR_MAX,
+};
+
+#endif                         /* _XT_OSF_H */
diff --git a/include/linux/netfilter/xt_socket.h b/include/linux/netfilter/xt_socket.h
new file mode 100644 (file)
index 0000000..6f475b8
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef _XT_SOCKET_H
+#define _XT_SOCKET_H
+
+enum {
+       XT_SOCKET_TRANSPARENT = 1 << 0,
+};
+
+struct xt_socket_mtinfo1 {
+       __u8 flags;
+};
+
+#endif /* _XT_SOCKET_H */
index cbe8ce3bf486121ca2cbaa49d9a1b022a766ff28..dbea93b694e5aa6e30749949df01fe4dce25f3d3 100644 (file)
@@ -7,7 +7,7 @@
  * Copyright 2008 Michael Wu <flamingice@sourmilk.net>
  * Copyright 2008 Luis Carlos Cobo <luisca@cozybit.com>
  * Copyright 2008 Michael Buesch <mb@bu3sch.de>
- * Copyright 2008 Luis R. Rodriguez <lrodriguez@atheros.com>
+ * Copyright 2008, 2009 Luis R. Rodriguez <lrodriguez@atheros.com>
  * Copyright 2008 Jouni Malinen <jouni.malinen@atheros.com>
  * Copyright 2008 Colin McCabe <colin@cozybit.com>
  *
@@ -25,6 +25,8 @@
  *
  */
 
+#include <linux/types.h>
+
 /**
  * DOC: Station handling
  *
  *     to get a list of all present wiphys.
  * @NL80211_CMD_SET_WIPHY: set wiphy parameters, needs %NL80211_ATTR_WIPHY or
  *     %NL80211_ATTR_IFINDEX; can be used to set %NL80211_ATTR_WIPHY_NAME,
- *     %NL80211_ATTR_WIPHY_TXQ_PARAMS, %NL80211_ATTR_WIPHY_FREQ, and/or
- *     %NL80211_ATTR_WIPHY_CHANNEL_TYPE.
+ *     %NL80211_ATTR_WIPHY_TXQ_PARAMS, %NL80211_ATTR_WIPHY_FREQ,
+ *     %NL80211_ATTR_WIPHY_CHANNEL_TYPE, %NL80211_ATTR_WIPHY_RETRY_SHORT,
+ *     %NL80211_ATTR_WIPHY_RETRY_LONG, %NL80211_ATTR_WIPHY_FRAG_THRESHOLD,
+ *     and/or %NL80211_ATTR_WIPHY_RTS_THRESHOLD.
  * @NL80211_CMD_NEW_WIPHY: Newly created wiphy, response to get request
  *     or rename notification. Has attributes %NL80211_ATTR_WIPHY and
  *     %NL80211_ATTR_WIPHY_NAME.
@@ -75,8 +79,8 @@
  * @NL80211_CMD_SET_KEY: Set key attributes %NL80211_ATTR_KEY_DEFAULT,
  *     %NL80211_ATTR_KEY_DEFAULT_MGMT, or %NL80211_ATTR_KEY_THRESHOLD.
  * @NL80211_CMD_NEW_KEY: add a key with given %NL80211_ATTR_KEY_DATA,
- *     %NL80211_ATTR_KEY_IDX, %NL80211_ATTR_MAC and %NL80211_ATTR_KEY_CIPHER
- *     attributes.
+ *     %NL80211_ATTR_KEY_IDX, %NL80211_ATTR_MAC, %NL80211_ATTR_KEY_CIPHER,
+ *     and %NL80211_ATTR_KEY_SEQ attributes.
  * @NL80211_CMD_DEL_KEY: delete a key identified by %NL80211_ATTR_KEY_IDX
  *     or %NL80211_ATTR_MAC.
  *
  *     set (%NL80211_ATTR_REG_TYPE), if the type of regulatory domain is
  *     %NL80211_REG_TYPE_COUNTRY the alpha2 to which we have moved on
  *     to (%NL80211_ATTR_REG_ALPHA2).
+ * @NL80211_CMD_REG_BEACON_HINT: indicates to userspace that an AP beacon
+ *     has been found while world roaming thus enabling active scan or
+ *     any mode of operation that initiates TX (beacons) on a channel
+ *     where we would not have been able to do either before. As an example
+ *     if you are world roaming (regulatory domain set to world or if your
+ *     driver is using a custom world roaming regulatory domain) and while
+ *     doing a passive scan on the 5 GHz band you find an AP there (if not
+ *     on a DFS channel) you will now be able to actively scan for that AP
+ *     or use AP mode on your card on that same channel. Note that this will
+ *     never be used for channels 1-11 on the 2 GHz band as they are always
+ *     enabled world wide. This beacon hint is only sent if your device had
+ *     either disabled active scanning or beaconing on a channel. We send to
+ *     userspace the wiphy on which we removed a restriction from
+ *     (%NL80211_ATTR_WIPHY) and the channel on which this occurred
+ *     before (%NL80211_ATTR_FREQ_BEFORE) and after (%NL80211_ATTR_FREQ_AFTER)
+ *     the beacon hint was processed.
  *
  * @NL80211_CMD_AUTHENTICATE: authentication request and notification.
  *     This command is used both as a command (request to authenticate) and
  *     frame, i.e., it was for the local STA and was received in correct
  *     state. This is similar to MLME-AUTHENTICATE.confirm primitive in the
  *     MLME SAP interface (kernel providing MLME, userspace SME). The
- *     included NL80211_ATTR_FRAME attribute contains the management frame
- *     (including both the header and frame body, but not FCS).
+ *     included %NL80211_ATTR_FRAME attribute contains the management frame
+ *     (including both the header and frame body, but not FCS). This event is
+ *     also used to indicate if the authentication attempt timed out. In that
+ *     case the %NL80211_ATTR_FRAME attribute is replaced with a
+ *     %NL80211_ATTR_TIMED_OUT flag (and %NL80211_ATTR_MAC to indicate which
+ *     pending authentication timed out).
  * @NL80211_CMD_ASSOCIATE: association request and notification; like
  *     NL80211_CMD_AUTHENTICATE but for Association and Reassociation
  *     (similar to MLME-ASSOCIATE.request, MLME-REASSOCIATE.request,
  *     NL80211_CMD_AUTHENTICATE but for Disassociation frames (similar to
  *     MLME-DISASSOCIATE.request and MLME-DISASSOCIATE.indication primitives).
  *
+ * @NL80211_CMD_MICHAEL_MIC_FAILURE: notification of a locally detected Michael
+ *     MIC (part of TKIP) failure; sent on the "mlme" multicast group; the
+ *     event includes %NL80211_ATTR_MAC to describe the source MAC address of
+ *     the frame with invalid MIC, %NL80211_ATTR_KEY_TYPE to show the key
+ *     type, %NL80211_ATTR_KEY_IDX to indicate the key identifier, and
+ *     %NL80211_ATTR_KEY_SEQ to indicate the TSC value of the frame; this
+ *     event matches with MLME-MICHAELMICFAILURE.indication() primitive
+ *
+ * @NL80211_CMD_JOIN_IBSS: Join a new IBSS -- given at least an SSID and a
+ *     FREQ attribute (for the initial frequency if no peer can be found)
+ *     and optionally a MAC (as BSSID) and FREQ_FIXED attribute if those
+ *     should be fixed rather than automatically determined. Can only be
+ *     executed on a network interface that is UP, and fixed BSSID/FREQ
+ *     may be rejected. Another optional parameter is the beacon interval,
+ *     given in the %NL80211_ATTR_BEACON_INTERVAL attribute, which if not
+ *     given defaults to 100 TU (102.4ms).
+ * @NL80211_CMD_LEAVE_IBSS: Leave the IBSS -- no special arguments, the IBSS is
+ *     determined by the network interface.
+ *
  * @NL80211_CMD_MAX: highest used command number
  * @__NL80211_CMD_AFTER_LAST: internal use
  */
@@ -260,6 +303,13 @@ enum nl80211_commands {
        NL80211_CMD_DEAUTHENTICATE,
        NL80211_CMD_DISASSOCIATE,
 
+       NL80211_CMD_MICHAEL_MIC_FAILURE,
+
+       NL80211_CMD_REG_BEACON_HINT,
+
+       NL80211_CMD_JOIN_IBSS,
+       NL80211_CMD_LEAVE_IBSS,
+
        /* add new commands above here */
 
        /* used to define NL80211_CMD_MAX below */
@@ -278,6 +328,7 @@ enum nl80211_commands {
 #define NL80211_CMD_ASSOCIATE NL80211_CMD_ASSOCIATE
 #define NL80211_CMD_DEAUTHENTICATE NL80211_CMD_DEAUTHENTICATE
 #define NL80211_CMD_DISASSOCIATE NL80211_CMD_DISASSOCIATE
+#define NL80211_CMD_REG_BEACON_HINT NL80211_CMD_REG_BEACON_HINT
 
 /**
  * enum nl80211_attrs - nl80211 netlink attributes
@@ -296,6 +347,18 @@ enum nl80211_commands {
  *     NL80211_CHAN_HT20 = HT20 only
  *     NL80211_CHAN_HT40MINUS = secondary channel is below the primary channel
  *     NL80211_CHAN_HT40PLUS = secondary channel is above the primary channel
+ * @NL80211_ATTR_WIPHY_RETRY_SHORT: TX retry limit for frames whose length is
+ *     less than or equal to the RTS threshold; allowed range: 1..255;
+ *     dot11ShortRetryLimit; u8
+ * @NL80211_ATTR_WIPHY_RETRY_LONG: TX retry limit for frames whose length is
+ *     greater than the RTS threshold; allowed range: 1..255;
+ *     dot11ShortLongLimit; u8
+ * @NL80211_ATTR_WIPHY_FRAG_THRESHOLD: fragmentation threshold, i.e., maximum
+ *     length in octets for frames; allowed range: 256..8000, disable
+ *     fragmentation with (u32)-1; dot11FragmentationThreshold; u32
+ * @NL80211_ATTR_WIPHY_RTS_THRESHOLD: RTS threshold (TX frames with length
+ *     larger than or equal to this use RTS/CTS handshake); allowed range:
+ *     0..65536, disable with (u32)-1; dot11RTSThreshold; u32
  *
  * @NL80211_ATTR_IFINDEX: network interface index of the device to operate on
  * @NL80211_ATTR_IFNAME: network interface name
@@ -319,7 +382,7 @@ enum nl80211_commands {
  *
  * @NL80211_ATTR_STA_AID: Association ID for the station (u16)
  * @NL80211_ATTR_STA_FLAGS: flags, nested element with NLA_FLAG attributes of
- *     &enum nl80211_sta_flags.
+ *     &enum nl80211_sta_flags (deprecated, use %NL80211_ATTR_STA_FLAGS2)
  * @NL80211_ATTR_STA_LISTEN_INTERVAL: listen interval as defined by
  *     IEEE 802.11 7.3.1.6 (u16).
  * @NL80211_ATTR_STA_SUPPORTED_RATES: supported rates, array of supported
@@ -380,6 +443,8 @@ enum nl80211_commands {
  *
  * @NL80211_ATTR_MAX_NUM_SCAN_SSIDS: number of SSIDs you can scan with
  *     a single scan request, a wiphy attribute.
+ * @NL80211_ATTR_MAX_SCAN_IE_LEN: maximum length of information elements
+ *     that can be added to a scan request
  *
  * @NL80211_ATTR_SCAN_FREQUENCIES: nested attribute with frequencies (in MHz)
  * @NL80211_ATTR_SCAN_SSIDS: nested attribute with SSIDs, leave out for passive
@@ -408,6 +473,44 @@ enum nl80211_commands {
  * @NL80211_ATTR_REASON_CODE: ReasonCode for %NL80211_CMD_DEAUTHENTICATE and
  *     %NL80211_CMD_DISASSOCIATE, u16
  *
+ * @NL80211_ATTR_KEY_TYPE: Key Type, see &enum nl80211_key_type, represented as
+ *     a u32
+ *
+ * @NL80211_ATTR_FREQ_BEFORE: A channel which has suffered a regulatory change
+ *     due to considerations from a beacon hint. This attribute reflects
+ *     the state of the channel _before_ the beacon hint processing. This
+ *     attributes consists of a nested attribute containing
+ *     NL80211_FREQUENCY_ATTR_*
+ * @NL80211_ATTR_FREQ_AFTER: A channel which has suffered a regulatory change
+ *     due to considerations from a beacon hint. This attribute reflects
+ *     the state of the channel _after_ the beacon hint processing. This
+ *     attributes consists of a nested attribute containing
+ *     NL80211_FREQUENCY_ATTR_*
+ *
+ * @NL80211_ATTR_CIPHER_SUITES: a set of u32 values indicating the supported
+ *     cipher suites
+ *
+ * @NL80211_ATTR_FREQ_FIXED: a flag indicating the IBSS should not try to look
+ *     for other networks on different channels
+ *
+ * @NL80211_ATTR_TIMED_OUT: a flag indicating than an operation timed out; this
+ *     is used, e.g., with %NL80211_CMD_AUTHENTICATE event
+ *
+ * @NL80211_ATTR_USE_MFP: Whether management frame protection (IEEE 802.11w) is
+ *     used for the association (&enum nl80211_mfp, represented as a u32);
+ *     this attribute can be used
+ *     with %NL80211_CMD_ASSOCIATE request
+ *
+ * @NL80211_ATTR_STA_FLAGS2: Attribute containing a
+ *     &struct nl80211_sta_flag_update.
+ *
+ * @NL80211_ATTR_CONTROL_PORT: A flag indicating whether user space controls
+ *     IEEE 802.1X port, i.e., sets/clears %NL80211_STA_FLAG_AUTHORIZED, in
+ *     station mode. If the flag is included in %NL80211_CMD_ASSOCIATE
+ *     request, the driver will assume that the port is unauthorized until
+ *     authorized by user space. Otherwise, port is marked authorized by
+ *     default in station mode.
+ *
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
  */
@@ -492,6 +595,30 @@ enum nl80211_attrs {
        NL80211_ATTR_AUTH_TYPE,
        NL80211_ATTR_REASON_CODE,
 
+       NL80211_ATTR_KEY_TYPE,
+
+       NL80211_ATTR_MAX_SCAN_IE_LEN,
+       NL80211_ATTR_CIPHER_SUITES,
+
+       NL80211_ATTR_FREQ_BEFORE,
+       NL80211_ATTR_FREQ_AFTER,
+
+       NL80211_ATTR_FREQ_FIXED,
+
+
+       NL80211_ATTR_WIPHY_RETRY_SHORT,
+       NL80211_ATTR_WIPHY_RETRY_LONG,
+       NL80211_ATTR_WIPHY_FRAG_THRESHOLD,
+       NL80211_ATTR_WIPHY_RTS_THRESHOLD,
+
+       NL80211_ATTR_TIMED_OUT,
+
+       NL80211_ATTR_USE_MFP,
+
+       NL80211_ATTR_STA_FLAGS2,
+
+       NL80211_ATTR_CONTROL_PORT,
+
        /* add attributes here, update the policy in nl80211.c */
 
        __NL80211_ATTR_AFTER_LAST,
@@ -580,6 +707,18 @@ enum nl80211_sta_flags {
        NL80211_STA_FLAG_MAX = __NL80211_STA_FLAG_AFTER_LAST - 1
 };
 
+/**
+ * struct nl80211_sta_flag_update - station flags mask/set
+ * @mask: mask of station flags to set
+ * @set: which values to set them to
+ *
+ * Both mask and set contain bits as per &enum nl80211_sta_flags.
+ */
+struct nl80211_sta_flag_update {
+       __u32 mask;
+       __u32 set;
+} __attribute__((packed));
+
 /**
  * enum nl80211_rate_info - bitrate information
  *
@@ -1062,4 +1201,27 @@ enum nl80211_auth_type {
        NL80211_AUTHTYPE_FT,
        NL80211_AUTHTYPE_NETWORK_EAP,
 };
+
+/**
+ * enum nl80211_key_type - Key Type
+ * @NL80211_KEYTYPE_GROUP: Group (broadcast/multicast) key
+ * @NL80211_KEYTYPE_PAIRWISE: Pairwise (unicast/individual) key
+ * @NL80211_KEYTYPE_PEERKEY: PeerKey (DLS)
+ */
+enum nl80211_key_type {
+       NL80211_KEYTYPE_GROUP,
+       NL80211_KEYTYPE_PAIRWISE,
+       NL80211_KEYTYPE_PEERKEY,
+};
+
+/**
+ * enum nl80211_mfp - Management frame protection state
+ * @NL80211_MFP_NO: Management frame protection not used
+ * @NL80211_MFP_REQUIRED: Management frame protection required
+ */
+enum nl80211_mfp {
+       NL80211_MFP_NO,
+       NL80211_MFP_REQUIRED,
+};
+
 #endif /* __LINUX_NL80211_H */
diff --git a/include/linux/nl802154.h b/include/linux/nl802154.h
new file mode 100644 (file)
index 0000000..2cda00c
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ * nl802154.h
+ *
+ * Copyright (C) 2007, 2008, 2009 Siemens AG
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#ifndef NL802154_H
+#define NL802154_H
+
+#define IEEE802154_NL_NAME "802.15.4 MAC"
+#define IEEE802154_MCAST_COORD_NAME "coordinator"
+#define IEEE802154_MCAST_BEACON_NAME "beacon"
+
+enum {
+       __IEEE802154_ATTR_INVALID,
+
+       IEEE802154_ATTR_DEV_NAME,
+       IEEE802154_ATTR_DEV_INDEX,
+
+       IEEE802154_ATTR_STATUS,
+
+       IEEE802154_ATTR_SHORT_ADDR,
+       IEEE802154_ATTR_HW_ADDR,
+       IEEE802154_ATTR_PAN_ID,
+
+       IEEE802154_ATTR_CHANNEL,
+
+       IEEE802154_ATTR_COORD_SHORT_ADDR,
+       IEEE802154_ATTR_COORD_HW_ADDR,
+       IEEE802154_ATTR_COORD_PAN_ID,
+
+       IEEE802154_ATTR_SRC_SHORT_ADDR,
+       IEEE802154_ATTR_SRC_HW_ADDR,
+       IEEE802154_ATTR_SRC_PAN_ID,
+
+       IEEE802154_ATTR_DEST_SHORT_ADDR,
+       IEEE802154_ATTR_DEST_HW_ADDR,
+       IEEE802154_ATTR_DEST_PAN_ID,
+
+       IEEE802154_ATTR_CAPABILITY,
+       IEEE802154_ATTR_REASON,
+       IEEE802154_ATTR_SCAN_TYPE,
+       IEEE802154_ATTR_CHANNELS,
+       IEEE802154_ATTR_DURATION,
+       IEEE802154_ATTR_ED_LIST,
+       IEEE802154_ATTR_BCN_ORD,
+       IEEE802154_ATTR_SF_ORD,
+       IEEE802154_ATTR_PAN_COORD,
+       IEEE802154_ATTR_BAT_EXT,
+       IEEE802154_ATTR_COORD_REALIGN,
+       IEEE802154_ATTR_SEC,
+
+       __IEEE802154_ATTR_MAX,
+};
+
+#define IEEE802154_ATTR_MAX (__IEEE802154_ATTR_MAX - 1)
+
+extern struct nla_policy ieee802154_policy[];
+
+/* commands */
+/* REQ should be responded with CONF
+ * and INDIC with RESP
+ */
+enum {
+       __IEEE802154_COMMAND_INVALID,
+
+       IEEE802154_ASSOCIATE_REQ,
+       IEEE802154_ASSOCIATE_CONF,
+       IEEE802154_DISASSOCIATE_REQ,
+       IEEE802154_DISASSOCIATE_CONF,
+       IEEE802154_GET_REQ,
+       IEEE802154_GET_CONF,
+       IEEE802154_RESET_REQ,
+       IEEE802154_RESET_CONF,
+       IEEE802154_SCAN_REQ,
+       IEEE802154_SCAN_CONF,
+       IEEE802154_SET_REQ,
+       IEEE802154_SET_CONF,
+       IEEE802154_START_REQ,
+       IEEE802154_START_CONF,
+       IEEE802154_SYNC_REQ,
+       IEEE802154_POLL_REQ,
+       IEEE802154_POLL_CONF,
+
+       IEEE802154_ASSOCIATE_INDIC,
+       IEEE802154_ASSOCIATE_RESP,
+       IEEE802154_DISASSOCIATE_INDIC,
+       IEEE802154_BEACON_NOTIFY_INDIC,
+       IEEE802154_ORPHAN_INDIC,
+       IEEE802154_ORPHAN_RESP,
+       IEEE802154_COMM_STATUS_INDIC,
+       IEEE802154_SYNC_LOSS_INDIC,
+
+       IEEE802154_GTS_REQ, /* Not supported yet */
+       IEEE802154_GTS_INDIC, /* Not supported yet */
+       IEEE802154_GTS_CONF, /* Not supported yet */
+       IEEE802154_RX_ENABLE_REQ, /* Not supported yet */
+       IEEE802154_RX_ENABLE_CONF, /* Not supported yet */
+
+       __IEEE802154_CMD_MAX,
+};
+
+#define IEEE802154_CMD_MAX (__IEEE802154_CMD_MAX - 1)
+
+#endif
index b86fa2ffca0c3ca5f613b4b63b79a2260310b9d3..81bc252dc8ac35d9ed7fbe877308f52ae59eb623 100644 (file)
@@ -198,6 +198,7 @@ static inline int notifier_to_errno(int ret)
 #define NETDEV_CHANGENAME      0x000A
 #define NETDEV_FEAT_CHANGE     0x000B
 #define NETDEV_BONDING_FAILOVER 0x000C
+#define NETDEV_PRE_UP          0x000D
 
 #define SYS_DOWN       0x0001  /* Notify of system down */
 #define SYS_RESTART    SYS_DOWN
index 6a7efa242f5e50dd7c1b87f25c75a47a25964cc1..7be2d1043c1613b84bdaeb26c230e82e0bd508ef 100644 (file)
@@ -77,6 +77,9 @@ extern int of_n_size_cells(struct device_node *np);
 extern const struct of_device_id *of_match_node(
        const struct of_device_id *matches, const struct device_node *node);
 extern int of_modalias_node(struct device_node *node, char *modalias, int len);
+extern struct device_node *of_parse_phandle(struct device_node *np,
+                                           const char *phandle_name,
+                                           int index);
 extern int of_parse_phandles_with_args(struct device_node *np,
        const char *list_name, const char *cells_name, int index,
        struct device_node **out_node, const void **out_args);
diff --git a/include/linux/of_mdio.h b/include/linux/of_mdio.h
new file mode 100644 (file)
index 0000000..c9663c6
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * OF helpers for the MDIO (Ethernet PHY) API
+ *
+ * Copyright (c) 2009 Secret Lab Technologies, Ltd.
+ *
+ * This file is released under the GPLv2
+ */
+
+#ifndef __LINUX_OF_MDIO_H
+#define __LINUX_OF_MDIO_H
+
+#include <linux/phy.h>
+#include <linux/of.h>
+
+extern int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np);
+extern struct phy_device *of_phy_find_device(struct device_node *phy_np);
+extern struct phy_device *of_phy_connect(struct net_device *dev,
+                                        struct device_node *phy_np,
+                                        void (*hndlr)(struct net_device *),
+                                        u32 flags, phy_interface_t iface);
+
+#endif /* __LINUX_OF_MDIO_H */
index 9f36e1cdbf01c4016b1e21ba4d40a83fe5b43cc6..aa01d38c9971a745feec8bb70b0fa93392dcc08e 100644 (file)
 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SMBUS        0x0034
 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE  0x0035
 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA 0x0036
-#define PCI_DEVICE_ID_NVIDIA_NVENET_10         0x0037
-#define PCI_DEVICE_ID_NVIDIA_NVENET_11         0x0038
 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA2        0x003e
 #define PCI_DEVICE_ID_NVIDIA_GEFORCE_6800_ULTRA 0x0040
 #define PCI_DEVICE_ID_NVIDIA_GEFORCE_6800       0x0041
 #define PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_IDE  0x0053
 #define PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_SATA 0x0054
 #define PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_SATA2        0x0055
-#define PCI_DEVICE_ID_NVIDIA_NVENET_8          0x0056
-#define PCI_DEVICE_ID_NVIDIA_NVENET_9          0x0057
 #define PCI_DEVICE_ID_NVIDIA_CK804_AUDIO       0x0059
 #define PCI_DEVICE_ID_NVIDIA_CK804_PCIE                0x005d
 #define PCI_DEVICE_ID_NVIDIA_NFORCE2_SMBUS     0x0064
 #define PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE       0x0065
-#define PCI_DEVICE_ID_NVIDIA_NVENET_2          0x0066
 #define PCI_DEVICE_ID_NVIDIA_MCP2_MODEM                0x0069
 #define PCI_DEVICE_ID_NVIDIA_MCP2_AUDIO                0x006a
 #define PCI_DEVICE_ID_NVIDIA_NFORCE2S_SMBUS    0x0084
 #define PCI_DEVICE_ID_NVIDIA_NFORCE2S_IDE      0x0085
-#define PCI_DEVICE_ID_NVIDIA_NVENET_4          0x0086
 #define PCI_DEVICE_ID_NVIDIA_MCP2S_MODEM       0x0089
 #define PCI_DEVICE_ID_NVIDIA_CK8_AUDIO         0x008a
-#define PCI_DEVICE_ID_NVIDIA_NVENET_5          0x008c
 #define PCI_DEVICE_ID_NVIDIA_NFORCE2S_SATA     0x008e
 #define PCI_DEVICE_ID_NVIDIA_GEFORCE_7800_GT   0x0090
 #define PCI_DEVICE_ID_NVIDIA_GEFORCE_7800_GTX  0x0091
 #define PCI_DEVICE_ID_NVIDIA_NFORCE3           0x00d1
 #define PCI_DEVICE_ID_NVIDIA_NFORCE3_SMBUS     0x00d4
 #define PCI_DEVICE_ID_NVIDIA_NFORCE3_IDE       0x00d5
-#define PCI_DEVICE_ID_NVIDIA_NVENET_3          0x00d6
 #define PCI_DEVICE_ID_NVIDIA_MCP3_MODEM                0x00d9
 #define PCI_DEVICE_ID_NVIDIA_MCP3_AUDIO                0x00da
-#define PCI_DEVICE_ID_NVIDIA_NVENET_7          0x00df
 #define PCI_DEVICE_ID_NVIDIA_NFORCE3S          0x00e1
 #define PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA     0x00e3
 #define PCI_DEVICE_ID_NVIDIA_NFORCE3S_SMBUS    0x00e4
 #define PCI_DEVICE_ID_NVIDIA_NFORCE3S_IDE      0x00e5
-#define PCI_DEVICE_ID_NVIDIA_NVENET_6          0x00e6
 #define PCI_DEVICE_ID_NVIDIA_CK8S_AUDIO                0x00ea
 #define PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA2    0x00ee
 #define PCIE_DEVICE_ID_NVIDIA_GEFORCE_6800_ALT1 0x00f0
 #define PCI_DEVICE_ID_NVIDIA_NFORCE_SMBUS      0x01b4
 #define PCI_DEVICE_ID_NVIDIA_NFORCE_IDE                0x01bc
 #define PCI_DEVICE_ID_NVIDIA_MCP1_MODEM                0x01c1
-#define PCI_DEVICE_ID_NVIDIA_NVENET_1          0x01c3
 #define PCI_DEVICE_ID_NVIDIA_NFORCE2           0x01e0
 #define PCI_DEVICE_ID_NVIDIA_GEFORCE3          0x0200
 #define PCI_DEVICE_ID_NVIDIA_GEFORCE3_1                0x0201
 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE  0x036E
 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA 0x037E
 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA2        0x037F
-#define PCI_DEVICE_ID_NVIDIA_NVENET_12         0x0268
-#define PCI_DEVICE_ID_NVIDIA_NVENET_13         0x0269
 #define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800  0x0280
 #define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800_8X    0x0281
 #define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800SE     0x0282
 #define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5700_2    0x0348
 #define PCI_DEVICE_ID_NVIDIA_QUADRO_FX_GO1000       0x034C
 #define PCI_DEVICE_ID_NVIDIA_QUADRO_FX_1100         0x034E
-#define PCI_DEVICE_ID_NVIDIA_NVENET_14              0x0372
 #define PCI_DEVICE_ID_NVIDIA_NVENET_15              0x0373
-#define PCI_DEVICE_ID_NVIDIA_NVENET_16              0x03E5
-#define PCI_DEVICE_ID_NVIDIA_NVENET_17              0x03E6
 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA      0x03E7
 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SMBUS            0x03EB
 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_IDE       0x03EC
-#define PCI_DEVICE_ID_NVIDIA_NVENET_18              0x03EE
-#define PCI_DEVICE_ID_NVIDIA_NVENET_19              0x03EF
 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA2     0x03F6
 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA3     0x03F7
 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_SMBUS            0x0446
 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_IDE      0x0448
-#define PCI_DEVICE_ID_NVIDIA_NVENET_20              0x0450
-#define PCI_DEVICE_ID_NVIDIA_NVENET_21              0x0451
-#define PCI_DEVICE_ID_NVIDIA_NVENET_22              0x0452
-#define PCI_DEVICE_ID_NVIDIA_NVENET_23              0x0453
 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_SMBUS     0x0542
-#define PCI_DEVICE_ID_NVIDIA_NVENET_24              0x054C
-#define PCI_DEVICE_ID_NVIDIA_NVENET_25              0x054D
-#define PCI_DEVICE_ID_NVIDIA_NVENET_26              0x054E
-#define PCI_DEVICE_ID_NVIDIA_NVENET_27              0x054F
-#define PCI_DEVICE_ID_NVIDIA_NVENET_28              0x07DC
-#define PCI_DEVICE_ID_NVIDIA_NVENET_29              0x07DD
-#define PCI_DEVICE_ID_NVIDIA_NVENET_30              0x07DE
-#define PCI_DEVICE_ID_NVIDIA_NVENET_31              0x07DF
 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_IDE       0x0560
 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP73_IDE       0x056C
 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP78S_SMBUS    0x0752
 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP77_IDE       0x0759
-#define PCI_DEVICE_ID_NVIDIA_NVENET_32              0x0760
-#define PCI_DEVICE_ID_NVIDIA_NVENET_33              0x0761
-#define PCI_DEVICE_ID_NVIDIA_NVENET_34              0x0762
-#define PCI_DEVICE_ID_NVIDIA_NVENET_35              0x0763
 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP73_SMBUS     0x07D8
 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP79_SMBUS     0x0AA2
-#define PCI_DEVICE_ID_NVIDIA_NVENET_36              0x0AB0
-#define PCI_DEVICE_ID_NVIDIA_NVENET_37              0x0AB1
-#define PCI_DEVICE_ID_NVIDIA_NVENET_38              0x0AB2
-#define PCI_DEVICE_ID_NVIDIA_NVENET_39              0x0AB3
 
 #define PCI_VENDOR_ID_IMS              0x10e0
 #define PCI_DEVICE_ID_IMS_TT128                0x9128
 #define PCI_SUBDEVICE_ID_CCD_SWYX4S    0xB540
 #define PCI_SUBDEVICE_ID_CCD_JH4S20    0xB550
 #define PCI_SUBDEVICE_ID_CCD_IOB8ST_1  0xB552
+#define PCI_SUBDEVICE_ID_CCD_JHSE1     0xB553
+#define PCI_SUBDEVICE_ID_CCD_JH8S      0xB55B
 #define PCI_SUBDEVICE_ID_CCD_BN4S      0xB560
 #define PCI_SUBDEVICE_ID_CCD_BN8S      0xB562
 #define PCI_SUBDEVICE_ID_CCD_BNE1      0xB563
 #define PCI_DEVICE_ID_MPC8547E         0x0018
 #define PCI_DEVICE_ID_MPC8545E         0x0019
 #define PCI_DEVICE_ID_MPC8545          0x001a
+#define PCI_DEVICE_ID_MPC8569E         0x0061
+#define PCI_DEVICE_ID_MPC8569          0x0060
 #define PCI_DEVICE_ID_MPC8568E         0x0020
 #define PCI_DEVICE_ID_MPC8568          0x0021
 #define PCI_DEVICE_ID_MPC8567E         0x0022
 #define PCI_DEVICE_ID_MPC8572          0x0041
 #define PCI_DEVICE_ID_MPC8536E         0x0050
 #define PCI_DEVICE_ID_MPC8536          0x0051
+#define PCI_DEVICE_ID_P2020E           0x0070
+#define PCI_DEVICE_ID_P2020            0x0071
 #define PCI_DEVICE_ID_MPC8641          0x7010
 #define PCI_DEVICE_ID_MPC8641D         0x7011
 #define PCI_DEVICE_ID_MPC8610          0x7018
 
 #define PCI_VENDOR_ID_QMI              0x1a32
 
+#define PCI_VENDOR_ID_AZWAVE           0x1a3b
+
 #define PCI_VENDOR_ID_TEKRAM           0x1de1
 #define PCI_DEVICE_ID_TEKRAM_DC290     0xdc29
 
index 97e40cb6b5881973f382beacbd65a7bbfc52a6de..b1368b8f6572c80c2185a2512a7e9576594796d5 100644 (file)
@@ -79,7 +79,7 @@ typedef enum {
  * Need to be a little smaller than phydev->dev.bus_id to leave room
  * for the ":%02x"
  */
-#define MII_BUS_ID_SIZE        (BUS_ID_SIZE - 3)
+#define MII_BUS_ID_SIZE        (20 - 3)
 
 /*
  * The Bus class for PHYs.  Devices which provide access to
@@ -407,7 +407,7 @@ struct phy_driver {
 /* A Structure for boards to register fixups with the PHY Lib */
 struct phy_fixup {
        struct list_head list;
-       char bus_id[BUS_ID_SIZE];
+       char bus_id[20];
        u32 phy_uid;
        u32 phy_uid_mask;
        int (*run)(struct phy_device *phydev);
@@ -444,10 +444,16 @@ static inline int phy_write(struct phy_device *phydev, u16 regnum, u16 val)
 
 int get_phy_id(struct mii_bus *bus, int addr, u32 *phy_id);
 struct phy_device* get_phy_device(struct mii_bus *bus, int addr);
+int phy_device_register(struct phy_device *phy);
 int phy_clear_interrupt(struct phy_device *phydev);
 int phy_config_interrupt(struct phy_device *phydev, u32 interrupts);
+int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
+               u32 flags, phy_interface_t interface);
 struct phy_device * phy_attach(struct net_device *dev,
                const char *bus_id, u32 flags, phy_interface_t interface);
+int phy_connect_direct(struct net_device *dev, struct phy_device *phydev,
+               void (*handler)(struct net_device *), u32 flags,
+               phy_interface_t interface);
 struct phy_device * phy_connect(struct net_device *dev, const char *bus_id,
                void (*handler)(struct net_device *), u32 flags,
                phy_interface_t interface);
diff --git a/include/linux/regulator/lp3971.h b/include/linux/regulator/lp3971.h
new file mode 100644 (file)
index 0000000..6140164
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * National Semiconductors LP3971 PMIC chip client interface
+ *
+ *  Copyright (C) 2009 Samsung Electronics
+ *  Author: Marek Szyprowski <m.szyprowski@samsung.com>
+ *
+ * Based on wm8400.h
+ *
+ * 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 __LINUX_REGULATOR_LP3971_H
+#define __LINUX_REGULATOR_LP3971_H
+
+#include <linux/regulator/machine.h>
+
+#define LP3971_LDO1  0
+#define LP3971_LDO2  1
+#define LP3971_LDO3  2
+#define LP3971_LDO4  3
+#define LP3971_LDO5  4
+
+#define LP3971_DCDC1 5
+#define LP3971_DCDC2 6
+#define LP3971_DCDC3 7
+
+#define LP3971_NUM_REGULATORS 8
+
+struct lp3971_regulator_subdev {
+       int id;
+       struct regulator_init_data *initdata;
+};
+
+struct lp3971_platform_data {
+       int num_regulators;
+       struct lp3971_regulator_subdev *regulators;
+};
+
+#endif
diff --git a/include/linux/regulator/max1586.h b/include/linux/regulator/max1586.h
new file mode 100644 (file)
index 0000000..4456319
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * max1586.h  --  Voltage regulation for the Maxim 1586
+ *
+ * Copyright (C) 2008 Robert Jarzmik
+ *
+ * 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
+ */
+
+#ifndef REGULATOR_MAX1586
+#define REGULATOR_MAX1586
+
+#include <linux/regulator/machine.h>
+
+#define MAX1586_V3 0
+#define MAX1586_V6 1
+
+/* precalculated values for v3_gain */
+#define MAX1586_GAIN_NO_R24   1000000  /* 700000 .. 1475000 mV */
+#define MAX1586_GAIN_R24_3k32 1051098  /* 735768 .. 1550369 mV */
+#define MAX1586_GAIN_R24_5k11 1078648  /* 755053 .. 1591005 mV */
+#define MAX1586_GAIN_R24_7k5  1115432  /* 780802 .. 1645262 mV */
+
+/**
+ * max1586_subdev_data - regulator data
+ * @id: regulator Id (either MAX1586_V3 or MAX1586_V6)
+ * @name: regulator cute name (example for V3: "vcc_core")
+ * @platform_data: regulator init data (contraints, supplies, ...)
+ */
+struct max1586_subdev_data {
+       int                             id;
+       char                            *name;
+       struct regulator_init_data      *platform_data;
+};
+
+/**
+ * max1586_platform_data - platform data for max1586
+ * @num_subdevs: number of regultors used (may be 1 or 2)
+ * @subdevs: regulator used
+ *           At most, there will be a regulator for V3 and one for V6 voltages.
+ * @v3_gain: gain on the V3 voltage output multiplied by 1e6.
+ *           This can be calculated as ((1 + R24/R25 + R24/185.5kOhm) * 1e6)
+ *           for an external resistor configuration as described in the
+ *           data sheet (R25=100kOhm).
+ */
+struct max1586_platform_data {
+       int num_subdevs;
+       struct max1586_subdev_data *subdevs;
+       int v3_gain;
+};
+
+#endif
diff --git a/include/linux/regulator/userspace-consumer.h b/include/linux/regulator/userspace-consumer.h
new file mode 100644 (file)
index 0000000..b4554ce
--- /dev/null
@@ -0,0 +1,25 @@
+#ifndef __REGULATOR_PLATFORM_CONSUMER_H_
+#define __REGULATOR_PLATFORM_CONSUMER_H_
+
+struct regulator_consumer_supply;
+
+/**
+ * struct regulator_userspace_consumer_data - line consumer
+ * initialisation data.
+ *
+ * @name: Name for the consumer line
+ * @num_supplies: Number of supplies feeding the line
+ * @supplies: Supplies configuration.
+ * @init_on: Set if the regulators supplying the line should be
+ *           enabled during initialisation
+ */
+struct regulator_userspace_consumer_data {
+       const char *name;
+
+       int num_supplies;
+       struct regulator_bulk_data *supplies;
+
+       bool init_on;
+};
+
+#endif /* __REGULATOR_PLATFORM_CONSUMER_H_ */
index 164332cbb77c81e7623dc5c9c193739cd7f87313..16e39c7a67fcf24533b0e12a60ed3b04433e6ee7 100644 (file)
@@ -4,6 +4,7 @@
 /*
  * Copyright (C) 2006 - 2007 Ivo van Doorn
  * Copyright (C) 2007 Dmitry Torokhov
+ * Copyright 2009 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 as published by
  */
 
 #include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/mutex.h>
-#include <linux/device.h>
-#include <linux/leds.h>
+
+/* define userspace visible states */
+#define RFKILL_STATE_SOFT_BLOCKED      0
+#define RFKILL_STATE_UNBLOCKED         1
+#define RFKILL_STATE_HARD_BLOCKED      2
 
 /**
  * enum rfkill_type - type of rfkill switch.
- * RFKILL_TYPE_WLAN: switch is on a 802.11 wireless network device.
- * RFKILL_TYPE_BLUETOOTH: switch is on a bluetooth device.
- * RFKILL_TYPE_UWB: switch is on a ultra wideband device.
- * RFKILL_TYPE_WIMAX: switch is on a WiMAX device.
- * RFKILL_TYPE_WWAN: switch is on a wireless WAN device.
+ *
+ * @RFKILL_TYPE_ALL: toggles all switches (userspace only)
+ * @RFKILL_TYPE_WLAN: switch is on a 802.11 wireless network device.
+ * @RFKILL_TYPE_BLUETOOTH: switch is on a bluetooth device.
+ * @RFKILL_TYPE_UWB: switch is on a ultra wideband device.
+ * @RFKILL_TYPE_WIMAX: switch is on a WiMAX device.
+ * @RFKILL_TYPE_WWAN: switch is on a wireless WAN device.
+ * @NUM_RFKILL_TYPES: number of defined rfkill types
  */
 enum rfkill_type {
-       RFKILL_TYPE_WLAN ,
+       RFKILL_TYPE_ALL = 0,
+       RFKILL_TYPE_WLAN,
        RFKILL_TYPE_BLUETOOTH,
        RFKILL_TYPE_UWB,
        RFKILL_TYPE_WIMAX,
        RFKILL_TYPE_WWAN,
-       RFKILL_TYPE_MAX,
+       NUM_RFKILL_TYPES,
 };
 
-enum rfkill_state {
-       RFKILL_STATE_SOFT_BLOCKED = 0,  /* Radio output blocked */
-       RFKILL_STATE_UNBLOCKED    = 1,  /* Radio output allowed */
-       RFKILL_STATE_HARD_BLOCKED = 2,  /* Output blocked, non-overrideable */
-       RFKILL_STATE_MAX,               /* marker for last valid state */
+/**
+ * enum rfkill_operation - operation types
+ * @RFKILL_OP_ADD: a device was added
+ * @RFKILL_OP_DEL: a device was removed
+ * @RFKILL_OP_CHANGE: a device's state changed -- userspace changes one device
+ * @RFKILL_OP_CHANGE_ALL: userspace changes all devices (of a type, or all)
+ */
+enum rfkill_operation {
+       RFKILL_OP_ADD = 0,
+       RFKILL_OP_DEL,
+       RFKILL_OP_CHANGE,
+       RFKILL_OP_CHANGE_ALL,
 };
 
-/*
- * These are DEPRECATED, drivers using them should be verified to
- * comply with the rfkill usage guidelines in Documentation/rfkill.txt
- * and then converted to use the new names for rfkill_state
- */
-#define RFKILL_STATE_OFF RFKILL_STATE_SOFT_BLOCKED
-#define RFKILL_STATE_ON  RFKILL_STATE_UNBLOCKED
-
-/**
- * struct rfkill - rfkill control structure.
- * @name: Name of the switch.
- * @type: Radio type which the button controls, the value stored
- *     here should be a value from enum rfkill_type.
- * @state: State of the switch, "UNBLOCKED" means radio can operate.
- * @user_claim_unsupported: Whether the hardware supports exclusive
- *     RF-kill control by userspace. Set this before registering.
- * @user_claim: Set when the switch is controlled exlusively by userspace.
- * @mutex: Guards switch state transitions.  It serializes callbacks
- *     and also protects the state.
- * @data: Pointer to the RF button drivers private data which will be
- *     passed along when toggling radio state.
- * @toggle_radio(): Mandatory handler to control state of the radio.
- *     only RFKILL_STATE_SOFT_BLOCKED and RFKILL_STATE_UNBLOCKED are
- *     valid parameters.
- * @get_state(): handler to read current radio state from hardware,
- *      may be called from atomic context, should return 0 on success.
- *      Either this handler OR judicious use of rfkill_force_state() is
- *      MANDATORY for any driver capable of RFKILL_STATE_HARD_BLOCKED.
- * @led_trigger: A LED trigger for this button's LED.
- * @dev: Device structure integrating the switch into device tree.
- * @node: Used to place switch into list of all switches known to the
- *     the system.
- *
- * This structure represents a RF switch located on a network device.
- */
-struct rfkill {
-       const char *name;
-       enum rfkill_type type;
-
-       bool user_claim_unsupported;
-       bool user_claim;
-
-       /* the mutex serializes callbacks and also protects
-        * the state */
-       struct mutex mutex;
-       enum rfkill_state state;
-       void *data;
-       int (*toggle_radio)(void *data, enum rfkill_state state);
-       int (*get_state)(void *data, enum rfkill_state *state);
+/**
+ * struct rfkill_event - events for userspace on /dev/rfkill
+ * @idx: index of dev rfkill
+ * @type: type of the rfkill struct
+ * @op: operation code
+ * @hard: hard state (0/1)
+ * @soft: soft state (0/1)
+ *
+ * Structure used for userspace communication on /dev/rfkill,
+ * used for events from the kernel and control to the kernel.
+ */
+struct rfkill_event {
+       __u32 idx;
+       __u8  type;
+       __u8  op;
+       __u8  soft, hard;
+} __packed;
 
-#ifdef CONFIG_RFKILL_LEDS
-       struct led_trigger led_trigger;
-#endif
+/* ioctl for turning off rfkill-input (if present) */
+#define RFKILL_IOC_MAGIC       'R'
+#define RFKILL_IOC_NOINPUT     1
+#define RFKILL_IOCTL_NOINPUT   _IO(RFKILL_IOC_MAGIC, RFKILL_IOC_NOINPUT)
+
+/* and that's all userspace gets */
+#ifdef __KERNEL__
+/* don't allow anyone to use these in the kernel */
+enum rfkill_user_states {
+       RFKILL_USER_STATE_SOFT_BLOCKED  = RFKILL_STATE_SOFT_BLOCKED,
+       RFKILL_USER_STATE_UNBLOCKED     = RFKILL_STATE_UNBLOCKED,
+       RFKILL_USER_STATE_HARD_BLOCKED  = RFKILL_STATE_HARD_BLOCKED,
+};
+#undef RFKILL_STATE_SOFT_BLOCKED
+#undef RFKILL_STATE_UNBLOCKED
+#undef RFKILL_STATE_HARD_BLOCKED
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <linux/device.h>
+#include <linux/leds.h>
+#include <linux/err.h>
+
+/* this is opaque */
+struct rfkill;
 
-       struct device dev;
-       struct list_head node;
-       enum rfkill_state state_for_resume;
+/**
+ * struct rfkill_ops - rfkill driver methods
+ *
+ * @poll: poll the rfkill block state(s) -- only assign this method
+ *     when you need polling. When called, simply call one of the
+ *     rfkill_set{,_hw,_sw}_state family of functions. If the hw
+ *     is getting unblocked you need to take into account the return
+ *     value of those functions to make sure the software block is
+ *     properly used.
+ * @query: query the rfkill block state(s) and call exactly one of the
+ *     rfkill_set{,_hw,_sw}_state family of functions. Assign this
+ *     method if input events can cause hardware state changes to make
+ *     the rfkill core query your driver before setting a requested
+ *     block.
+ * @set_block: turn the transmitter on (blocked == false) or off
+ *     (blocked == true) -- ignore and return 0 when hard blocked.
+ *     This callback must be assigned.
+ */
+struct rfkill_ops {
+       void    (*poll)(struct rfkill *rfkill, void *data);
+       void    (*query)(struct rfkill *rfkill, void *data);
+       int     (*set_block)(void *data, bool blocked);
 };
-#define to_rfkill(d)   container_of(d, struct rfkill, dev)
 
-struct rfkill * __must_check rfkill_allocate(struct device *parent,
-                                            enum rfkill_type type);
-void rfkill_free(struct rfkill *rfkill);
+#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
+/**
+ * rfkill_alloc - allocate rfkill structure
+ * @name: name of the struct -- the string is not copied internally
+ * @parent: device that has rf switch on it
+ * @type: type of the switch (RFKILL_TYPE_*)
+ * @ops: rfkill methods
+ * @ops_data: data passed to each method
+ *
+ * This function should be called by the transmitter driver to allocate an
+ * rfkill structure. Returns %NULL on failure.
+ */
+struct rfkill * __must_check rfkill_alloc(const char *name,
+                                         struct device *parent,
+                                         const enum rfkill_type type,
+                                         const struct rfkill_ops *ops,
+                                         void *ops_data);
+
+/**
+ * rfkill_register - Register a rfkill structure.
+ * @rfkill: rfkill structure to be registered
+ *
+ * This function should be called by the transmitter driver to register
+ * the rfkill structure. Before calling this function the driver needs
+ * to be ready to service method calls from rfkill.
+ *
+ * If the software blocked state is not set before registration,
+ * set_block will be called to initialize it to a default value.
+ *
+ * If the hardware blocked state is not set before registration,
+ * it is assumed to be unblocked.
+ */
 int __must_check rfkill_register(struct rfkill *rfkill);
+
+/**
+ * rfkill_pause_polling(struct rfkill *rfkill)
+ *
+ * Pause polling -- say transmitter is off for other reasons.
+ * NOTE: not necessary for suspend/resume -- in that case the
+ * core stops polling anyway
+ */
+void rfkill_pause_polling(struct rfkill *rfkill);
+
+/**
+ * rfkill_resume_polling(struct rfkill *rfkill)
+ *
+ * Pause polling -- say transmitter is off for other reasons.
+ * NOTE: not necessary for suspend/resume -- in that case the
+ * core stops polling anyway
+ */
+void rfkill_resume_polling(struct rfkill *rfkill);
+
+
+/**
+ * rfkill_unregister - Unregister a rfkill structure.
+ * @rfkill: rfkill structure to be unregistered
+ *
+ * This function should be called by the network driver during device
+ * teardown to destroy rfkill structure. Until it returns, the driver
+ * needs to be able to service method calls.
+ */
 void rfkill_unregister(struct rfkill *rfkill);
 
-int rfkill_force_state(struct rfkill *rfkill, enum rfkill_state state);
-int rfkill_set_default(enum rfkill_type type, enum rfkill_state state);
+/**
+ * rfkill_destroy - free rfkill structure
+ * @rfkill: rfkill structure to be destroyed
+ *
+ * Destroys the rfkill structure.
+ */
+void rfkill_destroy(struct rfkill *rfkill);
+
+/**
+ * rfkill_set_hw_state - Set the internal rfkill hardware block state
+ * @rfkill: pointer to the rfkill class to modify.
+ * @state: the current hardware block state to set
+ *
+ * rfkill drivers that get events when the hard-blocked state changes
+ * use this function to notify the rfkill core (and through that also
+ * userspace) of the current state.  They should also use this after
+ * resume if the state could have changed.
+ *
+ * You need not (but may) call this function if poll_state is assigned.
+ *
+ * This function can be called in any context, even from within rfkill
+ * callbacks.
+ *
+ * The function returns the combined block state (true if transmitter
+ * should be blocked) so that drivers need not keep track of the soft
+ * block state -- which they might not be able to.
+ */
+bool __must_check rfkill_set_hw_state(struct rfkill *rfkill, bool blocked);
+
+/**
+ * rfkill_set_sw_state - Set the internal rfkill software block state
+ * @rfkill: pointer to the rfkill class to modify.
+ * @state: the current software block state to set
+ *
+ * rfkill drivers that get events when the soft-blocked state changes
+ * (yes, some platforms directly act on input but allow changing again)
+ * use this function to notify the rfkill core (and through that also
+ * userspace) of the current state.  It is not necessary to notify on
+ * resume; since hibernation can always change the soft-blocked state,
+ * the rfkill core will unconditionally restore the previous state.
+ *
+ * This function can be called in any context, even from within rfkill
+ * callbacks.
+ *
+ * The function returns the combined block state (true if transmitter
+ * should be blocked).
+ */
+bool rfkill_set_sw_state(struct rfkill *rfkill, bool blocked);
+
+/**
+ * rfkill_set_states - Set the internal rfkill block states
+ * @rfkill: pointer to the rfkill class to modify.
+ * @sw: the current software block state to set
+ * @hw: the current hardware block state to set
+ *
+ * This function can be called in any context, even from within rfkill
+ * callbacks.
+ */
+void rfkill_set_states(struct rfkill *rfkill, bool sw, bool hw);
 
 /**
- * rfkill_state_complement - return complementar state
- * @state: state to return the complement of
+ * rfkill_blocked - query rfkill block
  *
- * Returns RFKILL_STATE_SOFT_BLOCKED if @state is RFKILL_STATE_UNBLOCKED,
- * returns RFKILL_STATE_UNBLOCKED otherwise.
+ * @rfkill: rfkill struct to query
  */
-static inline enum rfkill_state rfkill_state_complement(enum rfkill_state state)
+bool rfkill_blocked(struct rfkill *rfkill);
+#else /* !RFKILL */
+static inline struct rfkill * __must_check
+rfkill_alloc(const char *name,
+            struct device *parent,
+            const enum rfkill_type type,
+            const struct rfkill_ops *ops,
+            void *ops_data)
+{
+       return ERR_PTR(-ENODEV);
+}
+
+static inline int __must_check rfkill_register(struct rfkill *rfkill)
+{
+       if (rfkill == ERR_PTR(-ENODEV))
+               return 0;
+       return -EINVAL;
+}
+
+static inline void rfkill_pause_polling(struct rfkill *rfkill)
+{
+}
+
+static inline void rfkill_resume_polling(struct rfkill *rfkill)
+{
+}
+
+static inline void rfkill_unregister(struct rfkill *rfkill)
+{
+}
+
+static inline void rfkill_destroy(struct rfkill *rfkill)
+{
+}
+
+static inline bool rfkill_set_hw_state(struct rfkill *rfkill, bool blocked)
+{
+       return blocked;
+}
+
+static inline bool rfkill_set_sw_state(struct rfkill *rfkill, bool blocked)
 {
-       return (state == RFKILL_STATE_UNBLOCKED) ?
-               RFKILL_STATE_SOFT_BLOCKED : RFKILL_STATE_UNBLOCKED;
+       return blocked;
 }
 
+static inline void rfkill_set_states(struct rfkill *rfkill, bool sw, bool hw)
+{
+}
+
+static inline bool rfkill_blocked(struct rfkill *rfkill)
+{
+       return false;
+}
+#endif /* RFKILL || RFKILL_MODULE */
+
+
+#ifdef CONFIG_RFKILL_LEDS
 /**
- * rfkill_get_led_name - Get the LED trigger name for the button's LED.
+ * rfkill_get_led_trigger_name - Get the LED trigger name for the button's LED.
  * This function might return a NULL pointer if registering of the
- * LED trigger failed.
- * Use this as "default_trigger" for the LED.
+ * LED trigger failed. Use this as "default_trigger" for the LED.
  */
-static inline char *rfkill_get_led_name(struct rfkill *rfkill)
-{
-#ifdef CONFIG_RFKILL_LEDS
-       return (char *)(rfkill->led_trigger.name);
+const char *rfkill_get_led_trigger_name(struct rfkill *rfkill);
+
+/**
+ * rfkill_set_led_trigger_name -- set the LED trigger name
+ * @rfkill: rfkill struct
+ * @name: LED trigger name
+ *
+ * This function sets the LED trigger name of the radio LED
+ * trigger that rfkill creates. It is optional, but if called
+ * must be called before rfkill_register() to be effective.
+ */
+void rfkill_set_led_trigger_name(struct rfkill *rfkill, const char *name);
 #else
+static inline const char *rfkill_get_led_trigger_name(struct rfkill *rfkill)
+{
        return NULL;
-#endif
 }
 
+static inline void
+rfkill_set_led_trigger_name(struct rfkill *rfkill, const char *name)
+{
+}
+#endif
+
+#endif /* __KERNEL__ */
+
 #endif /* RFKILL_H */
index 4896fdfec91383902df140dd05723d64dd2bc769..c900aa530070d7c08ad4a0851e684ac6931c98b9 100644 (file)
@@ -261,6 +261,7 @@ extern void task_rq_unlock_wait(struct task_struct *p);
 extern cpumask_var_t nohz_cpu_mask;
 #if defined(CONFIG_SMP) && defined(CONFIG_NO_HZ)
 extern int select_nohz_load_balancer(int cpu);
+extern int get_nohz_load_balancer(void);
 #else
 static inline int select_nohz_load_balancer(int cpu)
 {
@@ -1796,11 +1797,23 @@ extern unsigned int sysctl_sched_child_runs_first;
 extern unsigned int sysctl_sched_features;
 extern unsigned int sysctl_sched_migration_cost;
 extern unsigned int sysctl_sched_nr_migrate;
+extern unsigned int sysctl_timer_migration;
 
 int sched_nr_latency_handler(struct ctl_table *table, int write,
                struct file *file, void __user *buffer, size_t *length,
                loff_t *ppos);
 #endif
+#ifdef CONFIG_SCHED_DEBUG
+static inline unsigned int get_sysctl_timer_migration(void)
+{
+       return sysctl_timer_migration;
+}
+#else
+static inline unsigned int get_sysctl_timer_migration(void)
+{
+       return 1;
+}
+#endif
 extern unsigned int sysctl_sched_rt_period;
 extern int sysctl_sched_rt_runtime;
 
@@ -2212,6 +2225,12 @@ static inline int test_tsk_need_resched(struct task_struct *tsk)
        return unlikely(test_tsk_thread_flag(tsk,TIF_NEED_RESCHED));
 }
 
+static inline int restart_syscall(void)
+{
+       set_tsk_thread_flag(current, TIF_SIGPENDING);
+       return -ERESTARTNOINTR;
+}
+
 static inline int signal_pending(struct task_struct *p)
 {
        return unlikely(test_tsk_thread_flag(p,TIF_SIGPENDING));
index c2731bfe04d8a3255cc00d35af5b87dfb052895f..b464b9d3d242242c67c75444c99303fe22b8a00d 100644 (file)
@@ -487,17 +487,17 @@ typedef enum {
         *
         * Value          Cause Code
         * ---------      ----------------
-        * 0x0100          Request to Delete Last Remaining IP Address.
-        * 0x0101          Operation Refused Due to Resource Shortage.
-        * 0x0102          Request to Delete Source IP Address.
-        * 0x0103          Association Aborted due to illegal ASCONF-ACK
-        * 0x0104          Request refused - no authorization.
+        * 0x00A0          Request to Delete Last Remaining IP Address.
+        * 0x00A1          Operation Refused Due to Resource Shortage.
+        * 0x00A2          Request to Delete Source IP Address.
+        * 0x00A3          Association Aborted due to illegal ASCONF-ACK
+        * 0x00A4          Request refused - no authorization.
         */
-       SCTP_ERROR_DEL_LAST_IP  = cpu_to_be16(0x0100),
-       SCTP_ERROR_RSRC_LOW     = cpu_to_be16(0x0101),
-       SCTP_ERROR_DEL_SRC_IP   = cpu_to_be16(0x0102),
-       SCTP_ERROR_ASCONF_ACK   = cpu_to_be16(0x0103),
-       SCTP_ERROR_REQ_REFUSED  = cpu_to_be16(0x0104),
+       SCTP_ERROR_DEL_LAST_IP  = cpu_to_be16(0x00A0),
+       SCTP_ERROR_RSRC_LOW     = cpu_to_be16(0x00A1),
+       SCTP_ERROR_DEL_SRC_IP   = cpu_to_be16(0x00A2),
+       SCTP_ERROR_ASCONF_ACK   = cpu_to_be16(0x00A3),
+       SCTP_ERROR_REQ_REFUSED  = cpu_to_be16(0x00A4),
 
        /* AUTH Section 4.  New Error Cause
         *
index 5fd389162f014ccb053d8563de6ce2a16cedd90f..fa51293f270811832b97e8f660f979ae14e0bc44 100644 (file)
@@ -189,20 +189,23 @@ struct skb_shared_info {
        atomic_t        dataref;
        unsigned short  nr_frags;
        unsigned short  gso_size;
+#ifdef CONFIG_HAS_DMA
+       dma_addr_t      dma_head;
+#endif
        /* Warning: this field is not always filled in (UFO)! */
        unsigned short  gso_segs;
        unsigned short  gso_type;
        __be32          ip6_frag_id;
        union skb_shared_tx tx_flags;
-#ifdef CONFIG_HAS_DMA
-       unsigned int    num_dma_maps;
-#endif
        struct sk_buff  *frag_list;
        struct skb_shared_hwtstamps hwtstamps;
        skb_frag_t      frags[MAX_SKB_FRAGS];
 #ifdef CONFIG_HAS_DMA
-       dma_addr_t      dma_maps[MAX_SKB_FRAGS + 1];
+       dma_addr_t      dma_maps[MAX_SKB_FRAGS];
 #endif
+       /* Intermediate layers must ensure that destructor_arg
+        * remains valid until skb destructor */
+       void *          destructor_arg;
 };
 
 /* We divide dataref into two halves.  The higher 16 bits hold references
@@ -301,9 +304,6 @@ typedef unsigned char *sk_buff_data_t;
  *     @tc_verd: traffic control verdict
  *     @ndisc_nodetype: router type (from link layer)
  *     @do_not_encrypt: set to prevent encryption of this frame
- *     @requeue: set to indicate that the wireless core should attempt
- *             a software retry on this frame if we failed to
- *             receive an ACK for it
  *     @dma_cookie: a cookie to one of several possible DMA operations
  *             done by skb DMA functions
  *     @secmark: security marking
@@ -319,10 +319,7 @@ struct sk_buff {
        ktime_t                 tstamp;
        struct net_device       *dev;
 
-       union {
-               struct  dst_entry       *dst;
-               struct  rtable          *rtable;
-       };
+       unsigned long           _skb_dst;
 #ifdef CONFIG_XFRM
        struct  sec_path        *sp;
 #endif
@@ -380,7 +377,6 @@ struct sk_buff {
 #endif
 #if defined(CONFIG_MAC80211) || defined(CONFIG_MAC80211_MODULE)
        __u8                    do_not_encrypt:1;
-       __u8                    requeue:1;
 #endif
        /* 0/13/14 bit hole */
 
@@ -423,6 +419,21 @@ extern void skb_dma_unmap(struct device *dev, struct sk_buff *skb,
                          enum dma_data_direction dir);
 #endif
 
+static inline struct dst_entry *skb_dst(const struct sk_buff *skb)
+{
+       return (struct dst_entry *)skb->_skb_dst;
+}
+
+static inline void skb_dst_set(struct sk_buff *skb, struct dst_entry *dst)
+{
+       skb->_skb_dst = (unsigned long)dst;
+}
+
+static inline struct rtable *skb_rtable(const struct sk_buff *skb)
+{
+       return (struct rtable *)skb_dst(skb);
+}
+
 extern void kfree_skb(struct sk_buff *skb);
 extern void consume_skb(struct sk_buff *skb);
 extern void           __kfree_skb(struct sk_buff *skb);
@@ -1062,7 +1073,7 @@ extern void skb_add_rx_frag(struct sk_buff *skb, int i, struct page *page,
                            int off, int size);
 
 #define SKB_PAGE_ASSERT(skb)   BUG_ON(skb_shinfo(skb)->nr_frags)
-#define SKB_FRAG_ASSERT(skb)   BUG_ON(skb_shinfo(skb)->frag_list)
+#define SKB_FRAG_ASSERT(skb)   BUG_ON(skb_has_frags(skb))
 #define SKB_LINEAR_ASSERT(skb)  BUG_ON(skb_is_nonlinear(skb))
 
 #ifdef NET_SKBUFF_DATA_USES_OFFSET
@@ -1701,6 +1712,25 @@ static inline int pskb_trim_rcsum(struct sk_buff *skb, unsigned int len)
                     skb = skb->prev)
 
 
+static inline bool skb_has_frags(const struct sk_buff *skb)
+{
+       return skb_shinfo(skb)->frag_list != NULL;
+}
+
+static inline void skb_frag_list_init(struct sk_buff *skb)
+{
+       skb_shinfo(skb)->frag_list = NULL;
+}
+
+static inline void skb_frag_add_head(struct sk_buff *skb, struct sk_buff *frag)
+{
+       frag->next = skb_shinfo(skb)->frag_list;
+       skb_shinfo(skb)->frag_list = frag;
+}
+
+#define skb_walk_frags(skb, iter)      \
+       for (iter = skb_shinfo(skb)->frag_list; iter; iter = iter->next)
+
 extern struct sk_buff *__skb_recv_datagram(struct sock *sk, unsigned flags,
                                           int *peeked, int *err);
 extern struct sk_buff *skb_recv_datagram(struct sock *sk, unsigned flags,
@@ -1715,8 +1745,14 @@ extern int              skb_copy_and_csum_datagram_iovec(struct sk_buff *skb,
                                                        struct iovec *iov);
 extern int            skb_copy_datagram_from_iovec(struct sk_buff *skb,
                                                    int offset,
-                                                   struct iovec *from,
+                                                   const struct iovec *from,
+                                                   int from_offset,
                                                    int len);
+extern int            skb_copy_datagram_const_iovec(const struct sk_buff *from,
+                                                    int offset,
+                                                    const struct iovec *to,
+                                                    int to_offset,
+                                                    int size);
 extern void           skb_free_datagram(struct sock *sk, struct sk_buff *skb);
 extern int            skb_kill_datagram(struct sock *sk, struct sk_buff *skb,
                                         unsigned int flags);
index b32725075d7183a58bbf192fef069f26b8ef2735..5241e4fb4ecad02ce47bdcfbf2c6efb6b7953e98 100644 (file)
@@ -47,4 +47,14 @@ struct smsc911x_platform_config {
 #define SMSC911X_FORCE_EXTERNAL_PHY            (BIT(3))
 #define SMSC911X_SAVE_MAC_ADDRESS              (BIT(4))
 
+/*
+ * SMSC911X_SWAP_FIFO:
+ * Enables software byte swap for fifo data. Should only be used as a
+ * "last resort" in the case of big endian mode on boards with incorrectly
+ * routed data bus to older devices such as LAN9118. Newer devices such as
+ * LAN9221 can handle this in hardware, there are registers to control
+ * this swapping but the driver doesn't currently use them.
+ */
+#define SMSC911X_SWAP_FIFO                     (BIT(5))
+
 #endif /* __LINUX_SMSC911X_H__ */
index aee3f1e1d1ce18405626b9adf80e820193259a63..0f953fe40413f2a43e09d00091a82dcbc423301f 100644 (file)
@@ -18,7 +18,7 @@
 enum
 {
        IPSTATS_MIB_NUM = 0,
-       IPSTATS_MIB_INRECEIVES,                 /* InReceives */
+       IPSTATS_MIB_INPKTS,                     /* InReceives */
        IPSTATS_MIB_INHDRERRORS,                /* InHdrErrors */
        IPSTATS_MIB_INTOOBIGERRORS,             /* InTooBigErrors */
        IPSTATS_MIB_INNOROUTES,                 /* InNoRoutes */
@@ -28,7 +28,7 @@ enum
        IPSTATS_MIB_INDISCARDS,                 /* InDiscards */
        IPSTATS_MIB_INDELIVERS,                 /* InDelivers */
        IPSTATS_MIB_OUTFORWDATAGRAMS,           /* OutForwDatagrams */
-       IPSTATS_MIB_OUTREQUESTS,                /* OutRequests */
+       IPSTATS_MIB_OUTPKTS,                    /* OutRequests */
        IPSTATS_MIB_OUTDISCARDS,                /* OutDiscards */
        IPSTATS_MIB_OUTNOROUTES,                /* OutNoRoutes */
        IPSTATS_MIB_REASMTIMEOUT,               /* ReasmTimeout */
@@ -42,6 +42,12 @@ enum
        IPSTATS_MIB_OUTMCASTPKTS,               /* OutMcastPkts */
        IPSTATS_MIB_INBCASTPKTS,                /* InBcastPkts */
        IPSTATS_MIB_OUTBCASTPKTS,               /* OutBcastPkts */
+       IPSTATS_MIB_INOCTETS,                   /* InOctets */
+       IPSTATS_MIB_OUTOCTETS,                  /* OutOctets */
+       IPSTATS_MIB_INMCASTOCTETS,              /* InMcastOctets */
+       IPSTATS_MIB_OUTMCASTOCTETS,             /* OutMcastOctets */
+       IPSTATS_MIB_INBCASTOCTETS,              /* InBcastOctets */
+       IPSTATS_MIB_OUTBCASTOCTETS,             /* OutBcastOctets */
        __IPSTATS_MIB_MAX
 };
 
index 421afb4d29b01cc8236b9f41ab745743162d636d..3b461dffe244a120f012294ebf46ba718526e04c 100644 (file)
@@ -194,7 +194,8 @@ struct ucred {
 #define AF_RXRPC       33      /* RxRPC sockets                */
 #define AF_ISDN                34      /* mISDN sockets                */
 #define AF_PHONET      35      /* Phonet sockets               */
-#define AF_MAX         36      /* For now.. */
+#define AF_IEEE802154  36      /* IEEE802154 sockets           */
+#define AF_MAX         37      /* For now.. */
 
 /* Protocol families, same as address families. */
 #define PF_UNSPEC      AF_UNSPEC
@@ -233,6 +234,7 @@ struct ucred {
 #define PF_RXRPC       AF_RXRPC
 #define PF_ISDN                AF_ISDN
 #define PF_PHONET      AF_PHONET
+#define PF_IEEE802154  AF_IEEE802154
 #define PF_MAX         AF_MAX
 
 /* Maximum queue length specifiable by listen.  */
@@ -303,14 +305,15 @@ struct ucred {
 #define SOL_BLUETOOTH  274
 #define SOL_PNPIPE     275
 #define SOL_RDS                276
+#define SOL_IUCV       277
 
 /* IPX options */
 #define IPX_TYPE       1
 
 #ifdef __KERNEL__
 extern int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len);
-extern int memcpy_fromiovecend(unsigned char *kdata, struct iovec *iov, 
-                               int offset, int len);
+extern int memcpy_fromiovecend(unsigned char *kdata, const struct iovec *iov,
+                              int offset, int len);
 extern int csum_partial_copy_fromiovecend(unsigned char *kdata, 
                                          struct iovec *iov, 
                                          int offset, 
@@ -318,6 +321,8 @@ extern int csum_partial_copy_fromiovecend(unsigned char *kdata,
 
 extern int verify_iovec(struct msghdr *m, struct iovec *iov, struct sockaddr *address, int mode);
 extern int memcpy_toiovec(struct iovec *v, unsigned char *kdata, int len);
+extern int memcpy_toiovecend(const struct iovec *v, unsigned char *kdata,
+                            int offset, int len);
 extern int move_addr_to_user(struct sockaddr *kaddr, int klen, void __user *uaddr, int __user *ulen);
 extern int move_addr_to_kernel(void __user *uaddr, int ulen, struct sockaddr *kaddr);
 extern int put_cmsg(struct msghdr*, int level, int type, int len, void *data);
index 79506f5f9e67f4d975f592e2c373d52b2b137472..1b5d5384fcd395e3fe802984fb25b4031f1b96e9 100644 (file)
@@ -22,9 +22,6 @@ struct libertas_spi_platform_data {
         * speed, you may want to use 0 here. */
        u16 use_dummy_writes;
 
-       /* GPIO number to use as chip select */
-       u16 gpio_cs;
-
        /* Board specific setup/teardown */
        int (*setup)(struct spi_device *spi);
        int (*teardown)(struct spi_device *spi);
diff --git a/include/linux/spi/wl12xx.h b/include/linux/spi/wl12xx.h
new file mode 100644 (file)
index 0000000..11430ca
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * This file is part of wl12xx
+ *
+ * Copyright (C) 2009 Nokia Corporation
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef _LINUX_SPI_WL12XX_H
+#define _LINUX_SPI_WL12XX_H
+
+struct wl12xx_platform_data {
+       void (*set_power)(bool enable);
+};
+
+#endif
index 9d5078bd23a38a08285e81d4d4e63407646ff873..8afac76cd7487648a7bc626ea7ef660f9fdc6897 100644 (file)
@@ -377,7 +377,7 @@ struct tcp_sock {
        unsigned int            keepalive_time;   /* time before keep alive takes place */
        unsigned int            keepalive_intvl;  /* time interval between keep alive probes */
 
-       unsigned long last_synq_overflow; 
+       int                     linger2;
 
 /* Receiver side RTT estimation */
        struct {
@@ -406,8 +406,6 @@ struct tcp_sock {
 /* TCP MD5 Signagure Option information */
        struct tcp_md5sig_info  *md5sig_info;
 #endif
-
-       int                     linger2;
 };
 
 static inline struct tcp_sock *tcp_sk(const struct sock *sk)
index 469b82d88b3b133b5bbadf5b72304f5657f2b961..0482229c07db348636a9089722b69168a8b4dcc9 100644 (file)
@@ -97,10 +97,12 @@ extern void tick_clock_notify(void);
 extern int tick_check_oneshot_change(int allow_nohz);
 extern struct tick_sched *tick_get_tick_sched(int cpu);
 extern void tick_check_idle(int cpu);
+extern int tick_oneshot_mode_active(void);
 # else
 static inline void tick_clock_notify(void) { }
 static inline int tick_check_oneshot_change(int allow_nohz) { return 0; }
 static inline void tick_check_idle(int cpu) { }
+static inline int tick_oneshot_mode_active(void) { return 0; }
 # endif
 
 #else /* CONFIG_GENERIC_CLOCKEVENTS */
@@ -109,6 +111,7 @@ static inline void tick_cancel_sched_timer(int cpu) { }
 static inline void tick_clock_notify(void) { }
 static inline int tick_check_oneshot_change(int allow_nohz) { return 0; }
 static inline void tick_check_idle(int cpu) { }
+static inline int tick_oneshot_mode_active(void) { return 0; }
 #endif /* !CONFIG_GENERIC_CLOCKEVENTS */
 
 # ifdef CONFIG_NO_HZ
index 6cdb6f3331f11b6a80d7cd2c85a45706937b16d3..ccf882eed8f8d5c35852ec65151c5b4112e8b564 100644 (file)
@@ -163,7 +163,10 @@ extern void add_timer_on(struct timer_list *timer, int cpu);
 extern int del_timer(struct timer_list * timer);
 extern int mod_timer(struct timer_list *timer, unsigned long expires);
 extern int mod_timer_pending(struct timer_list *timer, unsigned long expires);
+extern int mod_timer_pinned(struct timer_list *timer, unsigned long expires);
 
+#define TIMER_NOT_PINNED       0
+#define TIMER_PINNED           1
 /*
  * The jiffies value which is added to now, when there is no timer
  * in the timer wheel:
index aa3475fcff643a3d2b32fddff911b66e88eea48e..9910e3bd5b316918466359ca20ae3a88914892bd 100644 (file)
@@ -170,17 +170,37 @@ struct timex {
 #include <asm/timex.h>
 
 /*
- * SHIFT_KG and SHIFT_KF establish the damping of the PLL and are chosen
- * for a slightly underdamped convergence characteristic. SHIFT_KH
- * establishes the damping of the FLL and is chosen by wisdom and black
- * art.
+ * SHIFT_PLL is used as a dampening factor to define how much we
+ * adjust the frequency correction for a given offset in PLL mode.
+ * It also used in dampening the offset correction, to define how
+ * much of the current value in time_offset we correct for each
+ * second. Changing this value changes the stiffness of the ntp
+ * adjustment code. A lower value makes it more flexible, reducing
+ * NTP convergence time. A higher value makes it stiffer, increasing
+ * convergence time, but making the clock more stable.
  *
- * MAXTC establishes the maximum time constant of the PLL. With the
- * SHIFT_KG and SHIFT_KF values given and a time constant range from
- * zero to MAXTC, the PLL will converge in 15 minutes to 16 hours,
- * respectively.
+ * In David Mills' nanokernel reference implementation SHIFT_PLL is 4.
+ * However this seems to increase convergence time much too long.
+ *
+ * https://lists.ntp.org/pipermail/hackers/2008-January/003487.html
+ *
+ * In the above mailing list discussion, it seems the value of 4
+ * was appropriate for other Unix systems with HZ=100, and that
+ * SHIFT_PLL should be decreased as HZ increases. However, Linux's
+ * clock steering implementation is HZ independent.
+ *
+ * Through experimentation, a SHIFT_PLL value of 2 was found to allow
+ * for fast convergence (very similar to the NTPv3 code used prior to
+ * v2.6.19), with good clock stability.
+ *
+ *
+ * SHIFT_FLL is used as a dampening factor to define how much we
+ * adjust the frequency correction for a given offset in FLL mode.
+ * In David Mills' nanokernel reference implementation SHIFT_FLL is 2.
+ *
+ * MAXTC establishes the maximum time constant of the PLL.
  */
-#define SHIFT_PLL      4       /* PLL frequency factor (shift) */
+#define SHIFT_PLL      2       /* PLL frequency factor (shift) */
 #define SHIFT_FLL      2       /* FLL frequency factor (shift) */
 #define MAXTC          10      /* maximum time constant (shift) */
 
@@ -192,10 +212,10 @@ struct timex {
 #define SHIFT_USEC 16          /* frequency offset scale (shift) */
 #define PPM_SCALE ((s64)NSEC_PER_USEC << (NTP_SCALE_SHIFT - SHIFT_USEC))
 #define PPM_SCALE_INV_SHIFT 19
-#define PPM_SCALE_INV ((1ll << (PPM_SCALE_INV_SHIFT + NTP_SCALE_SHIFT)) / \
+#define PPM_SCALE_INV ((1LL << (PPM_SCALE_INV_SHIFT + NTP_SCALE_SHIFT)) / \
                       PPM_SCALE + 1)
 
-#define MAXPHASE 500000000l    /* max phase error (ns) */
+#define MAXPHASE 500000000L    /* max phase error (ns) */
 #define MAXFREQ 500000         /* max frequency error (ns/s) */
 #define MAXFREQ_SCALED ((s64)MAXFREQ << NTP_SCALE_SHIFT)
 #define MINSEC 256             /* min interval between updates (s) */
index 36fabb95c7d38f073de7536ebb1956687441198f..5d44059f6d63feb02dbc8f2defc3d6ffb1d9cfba 100644 (file)
@@ -183,6 +183,7 @@ extern void usbnet_tx_timeout (struct net_device *net);
 extern int usbnet_change_mtu (struct net_device *net, int new_mtu);
 
 extern int usbnet_get_endpoints(struct usbnet *, struct usb_interface *);
+extern int usbnet_get_ethernet_addr(struct usbnet *, int);
 extern void usbnet_defer_kevent (struct usbnet *, int);
 extern void usbnet_skb_return (struct usbnet *, struct sk_buff *);
 extern void usbnet_unlink_rx_urbs(struct usbnet *);
index c89de7f4e5b945fd18e4b373d09caef740ae7529..4fdcc563551898fecf27193a1da3e669fd7aeae3 100644 (file)
@@ -59,7 +59,7 @@ enum {
         * M - Major: change if removing or modifying an existing call.
         * m - minor: change when adding a new call
         */
-       WIMAX_GNL_VERSION = 00,
+       WIMAX_GNL_VERSION = 01,
        /* Generic NetLink attributes */
        WIMAX_GNL_ATTR_INVALID = 0x00,
        WIMAX_GNL_ATTR_MAX = 10,
@@ -78,6 +78,7 @@ enum {
        WIMAX_GNL_OP_RFKILL,    /* Run wimax_rfkill() */
        WIMAX_GNL_OP_RESET,     /* Run wimax_rfkill() */
        WIMAX_GNL_RE_STATE_CHANGE,      /* Report: status change */
+       WIMAX_GNL_OP_STATE_GET,         /* Request for current state */
 };
 
 
@@ -113,6 +114,10 @@ enum {
        WIMAX_GNL_RESET_IFIDX = 1,
 };
 
+/* Atributes for wimax_state_get() */
+enum {
+       WIMAX_GNL_STGET_IFIDX = 1,
+};
 
 /*
  * Attributes for the Report State Change
index d5148a7889a6350f43b4bae0ae757545fd1621e6..433693ef2bb083c0b81cf1bb5fa49625ef0045c6 100644 (file)
@@ -266,7 +266,7 @@ enum i2400m_ro_type {
 
 /* Misc constants */
 enum {
-       I2400M_PL_PAD = 16,     /* Payload data size alignment */
+       I2400M_PL_ALIGN = 16,   /* Payload data size alignment */
        I2400M_PL_SIZE_MAX = 0x3EFF,
        I2400M_MAX_PLS_IN_MSG = 60,
        /* protocol barkers: sync sequences; for notifications they
index 3ad5390a4dd5b61f8abbaeab00ba50d0cd17b07e..968166a45f86718ab1badc888f9b7788e6e825cf 100644 (file)
@@ -81,12 +81,6 @@ enum {
        BT_CLOSED
 };
 
-/* Endianness conversions */
-#define htobs(a)       __cpu_to_le16(a)
-#define htobl(a)       __cpu_to_le32(a)
-#define btohs(a)       __le16_to_cpu(a)
-#define btohl(a)       __le32_to_cpu(a)
-
 /* BD Address */
 typedef struct {
        __u8 b[6];
@@ -171,15 +165,6 @@ static inline struct sk_buff *bt_skb_send_alloc(struct sock *sk, unsigned long l
        return skb;
 }
 
-static inline int skb_frags_no(struct sk_buff *skb)
-{
-       register struct sk_buff *frag = skb_shinfo(skb)->frag_list;
-       register int n = 1;
-
-       for (; frag; frag=frag->next, n++);
-       return n;
-}
-
 int bt_err(__u16 code);
 
 extern int hci_sock_init(void);
index 73aead222b32cb202ca626da891a4721a6b5a24a..c4ca4228b0830bc542d1f1d635987c86d03e3f11 100644 (file)
@@ -137,6 +137,8 @@ struct hci_dev {
        struct device           *parent;
        struct device           dev;
 
+       struct rfkill           *rfkill;
+
        struct module           *owner;
 
        int (*open)(struct hci_dev *hdev);
index f566aa1f0a4c9f64229af015ec7e0d16da817791..e919fca1072a7d096dd3b8743c4dada3a3dc9768 100644 (file)
 #define __L2CAP_H
 
 /* L2CAP defaults */
-#define L2CAP_DEFAULT_MTU      672
-#define L2CAP_DEFAULT_FLUSH_TO 0xFFFF
+#define L2CAP_DEFAULT_MTU              672
+#define L2CAP_DEFAULT_FLUSH_TO         0xffff
+#define L2CAP_DEFAULT_RX_WINDOW                1
+#define L2CAP_DEFAULT_MAX_RECEIVE      1
+#define L2CAP_DEFAULT_RETRANS_TO       300    /* 300 milliseconds */
+#define L2CAP_DEFAULT_MONITOR_TO       1000   /* 1 second */
+#define L2CAP_DEFAULT_MAX_RX_APDU      0xfff7
 
 #define L2CAP_CONN_TIMEOUT     (40000) /* 40 seconds */
 #define L2CAP_INFO_TIMEOUT     (4000)  /*  4 seconds */
@@ -64,17 +69,29 @@ struct l2cap_conninfo {
 #define L2CAP_LM_SECURE                0x0020
 
 /* L2CAP command codes */
-#define L2CAP_COMMAND_REJ 0x01
-#define L2CAP_CONN_REQ    0x02
-#define L2CAP_CONN_RSP    0x03
-#define L2CAP_CONF_REQ    0x04
-#define L2CAP_CONF_RSP    0x05
-#define L2CAP_DISCONN_REQ 0x06
-#define L2CAP_DISCONN_RSP 0x07
-#define L2CAP_ECHO_REQ    0x08
-#define L2CAP_ECHO_RSP    0x09
-#define L2CAP_INFO_REQ    0x0a
-#define L2CAP_INFO_RSP    0x0b
+#define L2CAP_COMMAND_REJ      0x01
+#define L2CAP_CONN_REQ         0x02
+#define L2CAP_CONN_RSP         0x03
+#define L2CAP_CONF_REQ         0x04
+#define L2CAP_CONF_RSP         0x05
+#define L2CAP_DISCONN_REQ      0x06
+#define L2CAP_DISCONN_RSP      0x07
+#define L2CAP_ECHO_REQ         0x08
+#define L2CAP_ECHO_RSP         0x09
+#define L2CAP_INFO_REQ         0x0a
+#define L2CAP_INFO_RSP         0x0b
+
+/* L2CAP feature mask */
+#define L2CAP_FEAT_FLOWCTL     0x00000001
+#define L2CAP_FEAT_RETRANS     0x00000002
+#define L2CAP_FEAT_ERTM                0x00000008
+#define L2CAP_FEAT_STREAMING   0x00000010
+#define L2CAP_FEAT_FCS         0x00000020
+#define L2CAP_FEAT_FIXED_CHAN  0x00000080
+
+/* L2CAP checksum option */
+#define L2CAP_FCS_NONE         0x00
+#define L2CAP_FCS_CRC16                0x01
 
 /* L2CAP structures */
 struct l2cap_hdr {
@@ -106,17 +123,23 @@ struct l2cap_conn_rsp {
        __le16     status;
 } __attribute__ ((packed));
 
+/* channel indentifier */
+#define L2CAP_CID_SIGNALING    0x0001
+#define L2CAP_CID_CONN_LESS    0x0002
+#define L2CAP_CID_DYN_START    0x0040
+#define L2CAP_CID_DYN_END      0xffff
+
 /* connect result */
-#define L2CAP_CR_SUCCESS    0x0000
-#define L2CAP_CR_PEND       0x0001
-#define L2CAP_CR_BAD_PSM    0x0002
-#define L2CAP_CR_SEC_BLOCK  0x0003
-#define L2CAP_CR_NO_MEM     0x0004
+#define L2CAP_CR_SUCCESS       0x0000
+#define L2CAP_CR_PEND          0x0001
+#define L2CAP_CR_BAD_PSM       0x0002
+#define L2CAP_CR_SEC_BLOCK     0x0003
+#define L2CAP_CR_NO_MEM                0x0004
 
 /* connect status */
-#define L2CAP_CS_NO_INFO      0x0000
-#define L2CAP_CS_AUTHEN_PEND  0x0001
-#define L2CAP_CS_AUTHOR_PEND  0x0002
+#define L2CAP_CS_NO_INFO       0x0000
+#define L2CAP_CS_AUTHEN_PEND   0x0001
+#define L2CAP_CS_AUTHOR_PEND   0x0002
 
 struct l2cap_conf_req {
        __le16     dcid;
@@ -143,10 +166,14 @@ struct l2cap_conf_opt {
 } __attribute__ ((packed));
 #define L2CAP_CONF_OPT_SIZE    2
 
+#define L2CAP_CONF_HINT                0x80
+#define L2CAP_CONF_MASK                0x7f
+
 #define L2CAP_CONF_MTU         0x01
 #define L2CAP_CONF_FLUSH_TO    0x02
 #define L2CAP_CONF_QOS         0x03
 #define L2CAP_CONF_RFC         0x04
+#define L2CAP_CONF_FCS         0x05
 
 #define L2CAP_CONF_MAX_SIZE    22
 
@@ -162,6 +189,8 @@ struct l2cap_conf_rfc {
 #define L2CAP_MODE_BASIC       0x00
 #define L2CAP_MODE_RETRANS     0x01
 #define L2CAP_MODE_FLOWCTL     0x02
+#define L2CAP_MODE_ERTM                0x03
+#define L2CAP_MODE_STREAM      0x04
 
 struct l2cap_disconn_req {
        __le16     dcid;
index 5389afdc129756abcef4c088b2c7adfd84165670..1a21895b732bbd5821b419a0a6e239dbd5c3b904 100644 (file)
 #ifndef __NET_CFG80211_H
 #define __NET_CFG80211_H
+/*
+ * 802.11 device and configuration interface
+ *
+ * Copyright 2006-2009 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/debugfs.h>
+#include <linux/list.h>
 #include <linux/netlink.h>
 #include <linux/skbuff.h>
 #include <linux/nl80211.h>
 #include <linux/if_ether.h>
 #include <linux/ieee80211.h>
-#include <linux/wireless.h>
-#include <net/iw_handler.h>
-#include <net/genetlink.h>
+#include <net/regulatory.h>
+
 /* remove once we remove the wext stuff */
 #include <net/iw_handler.h>
+#include <linux/wireless.h>
+
 
 /*
- * 802.11 configuration in-kernel interface
+ * wireless hardware capability structures
+ */
+
+/**
+ * enum ieee80211_band - supported frequency bands
+ *
+ * The bands are assigned this way because the supported
+ * bitrates differ in these bands.
  *
- * Copyright 2006, 2007        Johannes Berg <johannes@sipsolutions.net>
+ * @IEEE80211_BAND_2GHZ: 2.4GHz ISM band
+ * @IEEE80211_BAND_5GHZ: around 5GHz band (4.9-5.7)
  */
+enum ieee80211_band {
+       IEEE80211_BAND_2GHZ,
+       IEEE80211_BAND_5GHZ,
+
+       /* keep last */
+       IEEE80211_NUM_BANDS
+};
 
 /**
- * struct vif_params - describes virtual interface parameters
- * @mesh_id: mesh ID to use
- * @mesh_id_len: length of the mesh ID
+ * enum ieee80211_channel_flags - channel flags
+ *
+ * Channel flags set by the regulatory control code.
+ *
+ * @IEEE80211_CHAN_DISABLED: This channel is disabled.
+ * @IEEE80211_CHAN_PASSIVE_SCAN: Only passive scanning is permitted
+ *     on this channel.
+ * @IEEE80211_CHAN_NO_IBSS: IBSS is not allowed on this channel.
+ * @IEEE80211_CHAN_RADAR: Radar detection is required on this channel.
+ * @IEEE80211_CHAN_NO_HT40PLUS: extension channel above this channel
+ *     is not permitted.
+ * @IEEE80211_CHAN_NO_HT40MINUS: extension channel below this channel
+ *     is not permitted.
  */
-struct vif_params {
-       u8 *mesh_id;
-       int mesh_id_len;
+enum ieee80211_channel_flags {
+       IEEE80211_CHAN_DISABLED         = 1<<0,
+       IEEE80211_CHAN_PASSIVE_SCAN     = 1<<1,
+       IEEE80211_CHAN_NO_IBSS          = 1<<2,
+       IEEE80211_CHAN_RADAR            = 1<<3,
+       IEEE80211_CHAN_NO_HT40PLUS      = 1<<4,
+       IEEE80211_CHAN_NO_HT40MINUS     = 1<<5,
 };
 
-/* Radiotap header iteration
- *   implemented in net/wireless/radiotap.c
- *   docs in Documentation/networking/radiotap-headers.txt
+#define IEEE80211_CHAN_NO_HT40 \
+       (IEEE80211_CHAN_NO_HT40PLUS | IEEE80211_CHAN_NO_HT40MINUS)
+
+/**
+ * struct ieee80211_channel - channel definition
+ *
+ * This structure describes a single channel for use
+ * with cfg80211.
+ *
+ * @center_freq: center frequency in MHz
+ * @max_bandwidth: maximum allowed bandwidth for this channel, in MHz
+ * @hw_value: hardware-specific value for the channel
+ * @flags: channel flags from &enum ieee80211_channel_flags.
+ * @orig_flags: channel flags at registration time, used by regulatory
+ *     code to support devices with additional restrictions
+ * @band: band this channel belongs to.
+ * @max_antenna_gain: maximum antenna gain in dBi
+ * @max_power: maximum transmission power (in dBm)
+ * @beacon_found: helper to regulatory code to indicate when a beacon
+ *     has been found on this channel. Use regulatory_hint_found_beacon()
+ *     to enable this, this is is useful only on 5 GHz band.
+ * @orig_mag: internal use
+ * @orig_mpwr: internal use
  */
+struct ieee80211_channel {
+       enum ieee80211_band band;
+       u16 center_freq;
+       u8 max_bandwidth;
+       u16 hw_value;
+       u32 flags;
+       int max_antenna_gain;
+       int max_power;
+       bool beacon_found;
+       u32 orig_flags;
+       int orig_mag, orig_mpwr;
+};
+
 /**
- * struct ieee80211_radiotap_iterator - tracks walk thru present radiotap args
- * @rtheader: pointer to the radiotap header we are walking through
- * @max_length: length of radiotap header in cpu byte ordering
- * @this_arg_index: IEEE80211_RADIOTAP_... index of current arg
- * @this_arg: pointer to current radiotap arg
- * @arg_index: internal next argument index
- * @arg: internal next argument pointer
- * @next_bitmap: internal pointer to next present u32
- * @bitmap_shifter: internal shifter for curr u32 bitmap, b0 set == arg present
+ * enum ieee80211_rate_flags - rate flags
+ *
+ * Hardware/specification flags for rates. These are structured
+ * in a way that allows using the same bitrate structure for
+ * different bands/PHY modes.
+ *
+ * @IEEE80211_RATE_SHORT_PREAMBLE: Hardware can send with short
+ *     preamble on this bitrate; only relevant in 2.4GHz band and
+ *     with CCK rates.
+ * @IEEE80211_RATE_MANDATORY_A: This bitrate is a mandatory rate
+ *     when used with 802.11a (on the 5 GHz band); filled by the
+ *     core code when registering the wiphy.
+ * @IEEE80211_RATE_MANDATORY_B: This bitrate is a mandatory rate
+ *     when used with 802.11b (on the 2.4 GHz band); filled by the
+ *     core code when registering the wiphy.
+ * @IEEE80211_RATE_MANDATORY_G: This bitrate is a mandatory rate
+ *     when used with 802.11g (on the 2.4 GHz band); filled by the
+ *     core code when registering the wiphy.
+ * @IEEE80211_RATE_ERP_G: This is an ERP rate in 802.11g mode.
  */
+enum ieee80211_rate_flags {
+       IEEE80211_RATE_SHORT_PREAMBLE   = 1<<0,
+       IEEE80211_RATE_MANDATORY_A      = 1<<1,
+       IEEE80211_RATE_MANDATORY_B      = 1<<2,
+       IEEE80211_RATE_MANDATORY_G      = 1<<3,
+       IEEE80211_RATE_ERP_G            = 1<<4,
+};
 
-struct ieee80211_radiotap_iterator {
-       struct ieee80211_radiotap_header *rtheader;
-       int max_length;
-       int this_arg_index;
-       u8 *this_arg;
+/**
+ * struct ieee80211_rate - bitrate definition
+ *
+ * This structure describes a bitrate that an 802.11 PHY can
+ * operate with. The two values @hw_value and @hw_value_short
+ * are only for driver use when pointers to this structure are
+ * passed around.
+ *
+ * @flags: rate-specific flags
+ * @bitrate: bitrate in units of 100 Kbps
+ * @hw_value: driver/hardware value for this rate
+ * @hw_value_short: driver/hardware value for this rate when
+ *     short preamble is used
+ */
+struct ieee80211_rate {
+       u32 flags;
+       u16 bitrate;
+       u16 hw_value, hw_value_short;
+};
 
-       int arg_index;
-       u8 *arg;
-       __le32 *next_bitmap;
-       u32 bitmap_shifter;
+/**
+ * struct ieee80211_sta_ht_cap - STA's HT capabilities
+ *
+ * This structure describes most essential parameters needed
+ * to describe 802.11n HT capabilities for an STA.
+ *
+ * @ht_supported: is HT supported by the STA
+ * @cap: HT capabilities map as described in 802.11n spec
+ * @ampdu_factor: Maximum A-MPDU length factor
+ * @ampdu_density: Minimum A-MPDU spacing
+ * @mcs: Supported MCS rates
+ */
+struct ieee80211_sta_ht_cap {
+       u16 cap; /* use IEEE80211_HT_CAP_ */
+       bool ht_supported;
+       u8 ampdu_factor;
+       u8 ampdu_density;
+       struct ieee80211_mcs_info mcs;
 };
 
-extern int ieee80211_radiotap_iterator_init(
-   struct ieee80211_radiotap_iterator *iterator,
-   struct ieee80211_radiotap_header *radiotap_header,
-   int max_length);
+/**
+ * struct ieee80211_supported_band - frequency band definition
+ *
+ * This structure describes a frequency band a wiphy
+ * is able to operate in.
+ *
+ * @channels: Array of channels the hardware can operate in
+ *     in this band.
+ * @band: the band this structure represents
+ * @n_channels: Number of channels in @channels
+ * @bitrates: Array of bitrates the hardware can operate with
+ *     in this band. Must be sorted to give a valid "supported
+ *     rates" IE, i.e. CCK rates first, then OFDM.
+ * @n_bitrates: Number of bitrates in @bitrates
+ */
+struct ieee80211_supported_band {
+       struct ieee80211_channel *channels;
+       struct ieee80211_rate *bitrates;
+       enum ieee80211_band band;
+       int n_channels;
+       int n_bitrates;
+       struct ieee80211_sta_ht_cap ht_cap;
+};
 
-extern int ieee80211_radiotap_iterator_next(
-   struct ieee80211_radiotap_iterator *iterator);
+/*
+ * Wireless hardware/device configuration structures and methods
+ */
 
+/**
+ * struct vif_params - describes virtual interface parameters
+ * @mesh_id: mesh ID to use
+ * @mesh_id_len: length of the mesh ID
+ */
+struct vif_params {
+       u8 *mesh_id;
+       int mesh_id_len;
+};
 
- /**
+/**
  * struct key_params - key information
  *
  * Information about a key
@@ -105,27 +254,6 @@ struct beacon_parameters {
        int head_len, tail_len;
 };
 
-/**
- * enum station_flags - station flags
- *
- * Station capability flags. Note that these must be the bits
- * according to the nl80211 flags.
- *
- * @STATION_FLAG_CHANGED: station flags were changed
- * @STATION_FLAG_AUTHORIZED: station is authorized to send frames (802.1X)
- * @STATION_FLAG_SHORT_PREAMBLE: station is capable of receiving frames
- *     with short preambles
- * @STATION_FLAG_WME: station is WME/QoS capable
- * @STATION_FLAG_MFP: station uses management frame protection
- */
-enum station_flags {
-       STATION_FLAG_CHANGED            = 1<<0,
-       STATION_FLAG_AUTHORIZED         = 1<<NL80211_STA_FLAG_AUTHORIZED,
-       STATION_FLAG_SHORT_PREAMBLE     = 1<<NL80211_STA_FLAG_SHORT_PREAMBLE,
-       STATION_FLAG_WME                = 1<<NL80211_STA_FLAG_WME,
-       STATION_FLAG_MFP                = 1<<NL80211_STA_FLAG_MFP,
-};
-
 /**
  * enum plink_action - actions to perform in mesh peers
  *
@@ -148,14 +276,17 @@ enum plink_actions {
  * @supported_rates: supported rates in IEEE 802.11 format
  *     (or NULL for no change)
  * @supported_rates_len: number of supported rates
- * @station_flags: station flags (see &enum station_flags)
+ * @sta_flags_mask: station flags that changed
+ *     (bitmask of BIT(NL80211_STA_FLAG_...))
+ * @sta_flags_set: station flags values
+ *     (bitmask of BIT(NL80211_STA_FLAG_...))
  * @listen_interval: listen interval or -1 for no change
  * @aid: AID or zero for no change
  */
 struct station_parameters {
        u8 *supported_rates;
        struct net_device *vlan;
-       u32 station_flags;
+       u32 sta_flags_mask, sta_flags_set;
        int listen_interval;
        u16 aid;
        u8 supported_rates_len;
@@ -348,92 +479,6 @@ struct bss_parameters {
        u8 basic_rates_len;
 };
 
-/**
- * enum environment_cap - Environment parsed from country IE
- * @ENVIRON_ANY: indicates country IE applies to both indoor and
- *     outdoor operation.
- * @ENVIRON_INDOOR: indicates country IE applies only to indoor operation
- * @ENVIRON_OUTDOOR: indicates country IE applies only to outdoor operation
- */
-enum environment_cap {
-       ENVIRON_ANY,
-       ENVIRON_INDOOR,
-       ENVIRON_OUTDOOR,
-};
-
-/**
- * struct regulatory_request - used to keep track of regulatory requests
- *
- * @wiphy_idx: this is set if this request's initiator is
- *     %REGDOM_SET_BY_COUNTRY_IE or %REGDOM_SET_BY_DRIVER. This
- *     can be used by the wireless core to deal with conflicts
- *     and potentially inform users of which devices specifically
- *     cased the conflicts.
- * @initiator: indicates who sent this request, could be any of
- *     of those set in nl80211_reg_initiator (%NL80211_REGDOM_SET_BY_*)
- * @alpha2: the ISO / IEC 3166 alpha2 country code of the requested
- *     regulatory domain. We have a few special codes:
- *     00 - World regulatory domain
- *     99 - built by driver but a specific alpha2 cannot be determined
- *     98 - result of an intersection between two regulatory domains
- * @intersect: indicates whether the wireless core should intersect
- *     the requested regulatory domain with the presently set regulatory
- *     domain.
- * @country_ie_checksum: checksum of the last processed and accepted
- *     country IE
- * @country_ie_env: lets us know if the AP is telling us we are outdoor,
- *     indoor, or if it doesn't matter
- * @list: used to insert into the reg_requests_list linked list
- */
-struct regulatory_request {
-       int wiphy_idx;
-       enum nl80211_reg_initiator initiator;
-       char alpha2[2];
-       bool intersect;
-       u32 country_ie_checksum;
-       enum environment_cap country_ie_env;
-       struct list_head list;
-};
-
-struct ieee80211_freq_range {
-       u32 start_freq_khz;
-       u32 end_freq_khz;
-       u32 max_bandwidth_khz;
-};
-
-struct ieee80211_power_rule {
-       u32 max_antenna_gain;
-       u32 max_eirp;
-};
-
-struct ieee80211_reg_rule {
-       struct ieee80211_freq_range freq_range;
-       struct ieee80211_power_rule power_rule;
-       u32 flags;
-};
-
-struct ieee80211_regdomain {
-       u32 n_reg_rules;
-       char alpha2[2];
-       struct ieee80211_reg_rule reg_rules[];
-};
-
-#define MHZ_TO_KHZ(freq) ((freq) * 1000)
-#define KHZ_TO_MHZ(freq) ((freq) / 1000)
-#define DBI_TO_MBI(gain) ((gain) * 100)
-#define MBI_TO_DBI(gain) ((gain) / 100)
-#define DBM_TO_MBM(gain) ((gain) * 100)
-#define MBM_TO_DBM(gain) ((gain) / 100)
-
-#define REG_RULE(start, end, bw, gain, eirp, reg_flags) { \
-       .freq_range.start_freq_khz = MHZ_TO_KHZ(start), \
-       .freq_range.end_freq_khz = MHZ_TO_KHZ(end), \
-       .freq_range.max_bandwidth_khz = MHZ_TO_KHZ(bw), \
-       .power_rule.max_antenna_gain = DBI_TO_MBI(gain), \
-       .power_rule.max_eirp = DBM_TO_MBM(eirp), \
-       .flags = reg_flags, \
-       }
-
 struct mesh_config {
        /* Timeouts in ms */
        /* Mesh plink management parameters */
@@ -504,7 +549,7 @@ struct cfg80211_scan_request {
        int n_ssids;
        struct ieee80211_channel **channels;
        u32 n_channels;
-       u8 *ie;
+       const u8 *ie;
        size_t ie_len;
 
        /* internal */
@@ -612,6 +657,11 @@ struct cfg80211_auth_request {
  * @ssid_len: Length of ssid in octets
  * @ie: Extra IEs to add to (Re)Association Request frame or %NULL
  * @ie_len: Length of ie buffer in octets
+ * @use_mfp: Use management frame protection (IEEE 802.11w) in this association
+ * @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.
  */
 struct cfg80211_assoc_request {
        struct ieee80211_channel *chan;
@@ -620,6 +670,8 @@ struct cfg80211_assoc_request {
        size_t ssid_len;
        const u8 *ie;
        size_t ie_len;
+       bool use_mfp;
+       bool control_port;
 };
 
 /**
@@ -658,6 +710,60 @@ struct cfg80211_disassoc_request {
        size_t ie_len;
 };
 
+/**
+ * struct cfg80211_ibss_params - IBSS parameters
+ *
+ * This structure defines the IBSS parameters for the join_ibss()
+ * method.
+ *
+ * @ssid: The SSID, will always be non-null.
+ * @ssid_len: The length of the SSID, will always be non-zero.
+ * @bssid: Fixed BSSID requested, maybe be %NULL, if set do not
+ *     search for IBSSs with a different BSSID.
+ * @channel: The channel to use if no IBSS can be found to join.
+ * @channel_fixed: The channel should be fixed -- do not search for
+ *     IBSSs to join on other channels.
+ * @ie: information element(s) to include in the beacon
+ * @ie_len: length of that
+ * @beacon_interval: beacon interval to use
+ */
+struct cfg80211_ibss_params {
+       u8 *ssid;
+       u8 *bssid;
+       struct ieee80211_channel *channel;
+       u8 *ie;
+       u8 ssid_len, ie_len;
+       u16 beacon_interval;
+       bool channel_fixed;
+};
+
+/**
+ * enum wiphy_params_flags - set_wiphy_params bitfield values
+ * WIPHY_PARAM_RETRY_SHORT: wiphy->retry_short has changed
+ * WIPHY_PARAM_RETRY_LONG: wiphy->retry_long has changed
+ * WIPHY_PARAM_FRAG_THRESHOLD: wiphy->frag_threshold has changed
+ * WIPHY_PARAM_RTS_THRESHOLD: wiphy->rts_threshold has changed
+ */
+enum wiphy_params_flags {
+       WIPHY_PARAM_RETRY_SHORT         = 1 << 0,
+       WIPHY_PARAM_RETRY_LONG          = 1 << 1,
+       WIPHY_PARAM_FRAG_THRESHOLD      = 1 << 2,
+       WIPHY_PARAM_RTS_THRESHOLD       = 1 << 3,
+};
+
+/**
+ * enum tx_power_setting - TX power adjustment
+ *
+ * @TX_POWER_AUTOMATIC: the dbm parameter is ignored
+ * @TX_POWER_LIMITED: limit TX power by the dbm parameter
+ * @TX_POWER_FIXED: fix TX power to the dbm parameter
+ */
+enum tx_power_setting {
+       TX_POWER_AUTOMATIC,
+       TX_POWER_LIMITED,
+       TX_POWER_FIXED,
+};
+
 /**
  * struct cfg80211_ops - backend description for wireless configuration
  *
@@ -688,10 +794,11 @@ struct cfg80211_disassoc_request {
  * @get_key: get information about the key with the given parameters.
  *     @mac_addr will be %NULL when requesting information for a group
  *     key. All pointers given to the @callback function need not be valid
- *     after it returns.
+ *     after it returns. This function should return an error if it is
+ *     not possible to retrieve the key, -ENOENT if it doesn't exist.
  *
  * @del_key: remove a key given the @mac_addr (%NULL for a group key)
- *     and @key_index
+ *     and @key_index, return -ENOENT if the key doesn't exist.
  *
  * @set_default_key: set the default key on an interface
  *
@@ -733,6 +840,23 @@ struct cfg80211_disassoc_request {
  * @assoc: Request to (re)associate with the specified peer
  * @deauth: Request to deauthenticate from the specified peer
  * @disassoc: Request to disassociate from the specified peer
+ *
+ * @join_ibss: Join the specified IBSS (or create if necessary). Once done, call
+ *     cfg80211_ibss_joined(), also call that function when changing BSSID due
+ *     to a merge.
+ * @leave_ibss: Leave the IBSS.
+ *
+ * @set_wiphy_params: Notify that wiphy parameters have changed;
+ *     @changed bitfield (see &enum wiphy_params_flags) describes which values
+ *     have changed. The actual parameter values are available in
+ *     struct wiphy. If returning an error, no value should be changed.
+ *
+ * @set_tx_power: set the transmit power according to the parameters
+ * @get_tx_power: store the current TX power into the dbm variable;
+ *     return 0 if successful
+ *
+ * @rfkill_poll: polls the hw rfkill line, use cfg80211 reporting
+ *     functions to adjust rfkill hw state
  */
 struct cfg80211_ops {
        int     (*suspend)(struct wiphy *wiphy);
@@ -747,13 +871,13 @@ struct cfg80211_ops {
                                       struct vif_params *params);
 
        int     (*add_key)(struct wiphy *wiphy, struct net_device *netdev,
-                          u8 key_index, u8 *mac_addr,
+                          u8 key_index, const u8 *mac_addr,
                           struct key_params *params);
        int     (*get_key)(struct wiphy *wiphy, struct net_device *netdev,
-                          u8 key_index, u8 *mac_addr, void *cookie,
+                          u8 key_index, const u8 *mac_addr, void *cookie,
                           void (*callback)(void *cookie, struct key_params*));
        int     (*del_key)(struct wiphy *wiphy, struct net_device *netdev,
-                          u8 key_index, u8 *mac_addr);
+                          u8 key_index, const u8 *mac_addr);
        int     (*set_default_key)(struct wiphy *wiphy,
                                   struct net_device *netdev,
                                   u8 key_index);
@@ -818,9 +942,473 @@ struct cfg80211_ops {
                          struct cfg80211_deauth_request *req);
        int     (*disassoc)(struct wiphy *wiphy, struct net_device *dev,
                            struct cfg80211_disassoc_request *req);
+
+       int     (*join_ibss)(struct wiphy *wiphy, struct net_device *dev,
+                            struct cfg80211_ibss_params *params);
+       int     (*leave_ibss)(struct wiphy *wiphy, struct net_device *dev);
+
+       int     (*set_wiphy_params)(struct wiphy *wiphy, u32 changed);
+
+       int     (*set_tx_power)(struct wiphy *wiphy,
+                               enum tx_power_setting type, int dbm);
+       int     (*get_tx_power)(struct wiphy *wiphy, int *dbm);
+
+       void    (*rfkill_poll)(struct wiphy *wiphy);
 };
 
-/* temporary wext handlers */
+/*
+ * wireless hardware and networking interfaces structures
+ * and registration/helper functions
+ */
+
+/**
+ * struct wiphy - wireless hardware description
+ * @idx: the wiphy index assigned to this item
+ * @class_dev: the class device representing /sys/class/ieee80211/<wiphy-name>
+ * @custom_regulatory: tells us the driver for this device
+ *     has its own custom regulatory domain and cannot identify the
+ *     ISO / IEC 3166 alpha2 it belongs to. When this is enabled
+ *     we will disregard the first regulatory hint (when the
+ *     initiator is %REGDOM_SET_BY_CORE).
+ * @strict_regulatory: tells us the driver for this device will ignore
+ *     regulatory domain settings until it gets its own regulatory domain
+ *     via its regulatory_hint(). After its gets its own regulatory domain
+ *     it will only allow further regulatory domain settings to further
+ *     enhance compliance. For example if channel 13 and 14 are disabled
+ *     by this regulatory domain no user regulatory domain can enable these
+ *     channels at a later time. This can be used for devices which do not
+ *     have calibration information gauranteed for frequencies or settings
+ *     outside of its regulatory domain.
+ * @reg_notifier: the driver's regulatory notification callback
+ * @regd: the driver's regulatory domain, if one was requested via
+ *     the regulatory_hint() API. This can be used by the driver
+ *     on the reg_notifier() if it chooses to ignore future
+ *     regulatory domain changes caused by other drivers.
+ * @signal_type: signal type reported in &struct cfg80211_bss.
+ * @cipher_suites: supported cipher suites
+ * @n_cipher_suites: number of supported cipher suites
+ * @retry_short: Retry limit for short frames (dot11ShortRetryLimit)
+ * @retry_long: Retry limit for long frames (dot11LongRetryLimit)
+ * @frag_threshold: Fragmentation threshold (dot11FragmentationThreshold);
+ *     -1 = fragmentation disabled, only odd values >= 256 used
+ * @rts_threshold: RTS threshold (dot11RTSThreshold); -1 = RTS/CTS disabled
+ */
+struct wiphy {
+       /* assign these fields before you register the wiphy */
+
+       /* permanent MAC address */
+       u8 perm_addr[ETH_ALEN];
+
+       /* Supported interface modes, OR together BIT(NL80211_IFTYPE_...) */
+       u16 interface_modes;
+
+       bool custom_regulatory;
+       bool strict_regulatory;
+
+       enum cfg80211_signal_type signal_type;
+
+       int bss_priv_size;
+       u8 max_scan_ssids;
+       u16 max_scan_ie_len;
+
+       int n_cipher_suites;
+       const u32 *cipher_suites;
+
+       u8 retry_short;
+       u8 retry_long;
+       u32 frag_threshold;
+       u32 rts_threshold;
+
+       /* If multiple wiphys are registered and you're handed e.g.
+        * a regular netdev with assigned ieee80211_ptr, you won't
+        * know whether it points to a wiphy your driver has registered
+        * or not. Assign this to something global to your driver to
+        * help determine whether you own this wiphy or not. */
+       const void *privid;
+
+       struct ieee80211_supported_band *bands[IEEE80211_NUM_BANDS];
+
+       /* Lets us get back the wiphy on the callback */
+       int (*reg_notifier)(struct wiphy *wiphy,
+                           struct regulatory_request *request);
+
+       /* fields below are read-only, assigned by cfg80211 */
+
+       const struct ieee80211_regdomain *regd;
+
+       /* the item in /sys/class/ieee80211/ points to this,
+        * you need use set_wiphy_dev() (see below) */
+       struct device dev;
+
+       /* dir in debugfs: ieee80211/<wiphyname> */
+       struct dentry *debugfsdir;
+
+       char priv[0] __attribute__((__aligned__(NETDEV_ALIGN)));
+};
+
+/**
+ * wiphy_priv - return priv from wiphy
+ *
+ * @wiphy: the wiphy whose priv pointer to return
+ */
+static inline void *wiphy_priv(struct wiphy *wiphy)
+{
+       BUG_ON(!wiphy);
+       return &wiphy->priv;
+}
+
+/**
+ * set_wiphy_dev - set device pointer for wiphy
+ *
+ * @wiphy: The wiphy whose device to bind
+ * @dev: The device to parent it to
+ */
+static inline void set_wiphy_dev(struct wiphy *wiphy, struct device *dev)
+{
+       wiphy->dev.parent = dev;
+}
+
+/**
+ * wiphy_dev - get wiphy dev pointer
+ *
+ * @wiphy: The wiphy whose device struct to look up
+ */
+static inline struct device *wiphy_dev(struct wiphy *wiphy)
+{
+       return wiphy->dev.parent;
+}
+
+/**
+ * wiphy_name - get wiphy name
+ *
+ * @wiphy: The wiphy whose name to return
+ */
+static inline const char *wiphy_name(struct wiphy *wiphy)
+{
+       return dev_name(&wiphy->dev);
+}
+
+/**
+ * wiphy_new - create a new wiphy for use with cfg80211
+ *
+ * @ops: The configuration operations for this device
+ * @sizeof_priv: The size of the private area to allocate
+ *
+ * Create a new wiphy and associate the given operations with it.
+ * @sizeof_priv bytes are allocated for private use.
+ *
+ * The returned pointer must be assigned to each netdev's
+ * ieee80211_ptr for proper operation.
+ */
+struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv);
+
+/**
+ * wiphy_register - register a wiphy with cfg80211
+ *
+ * @wiphy: The wiphy to register.
+ *
+ * Returns a non-negative wiphy index or a negative error code.
+ */
+extern int wiphy_register(struct wiphy *wiphy);
+
+/**
+ * wiphy_unregister - deregister a wiphy from cfg80211
+ *
+ * @wiphy: The wiphy to unregister.
+ *
+ * After this call, no more requests can be made with this priv
+ * pointer, but the call may sleep to wait for an outstanding
+ * request that is being handled.
+ */
+extern void wiphy_unregister(struct wiphy *wiphy);
+
+/**
+ * wiphy_free - free wiphy
+ *
+ * @wiphy: The wiphy to free
+ */
+extern void wiphy_free(struct wiphy *wiphy);
+
+/**
+ * struct wireless_dev - wireless per-netdev state
+ *
+ * This structure must be allocated by the driver/stack
+ * that uses the ieee80211_ptr field in struct net_device
+ * (this is intentional so it can be allocated along with
+ * the netdev.)
+ *
+ * @wiphy: pointer to hardware description
+ * @iftype: interface type
+ * @list: (private) Used to collect the interfaces
+ * @netdev: (private) Used to reference back to the netdev
+ * @current_bss: (private) Used by the internal configuration code
+ * @bssid: (private) Used by the internal configuration code
+ * @ssid: (private) Used by the internal configuration code
+ * @ssid_len: (private) Used by the internal configuration code
+ * @wext: (private) Used by the internal wireless extensions compat code
+ * @wext_bssid: (private) Used by the internal wireless extensions compat code
+ */
+struct wireless_dev {
+       struct wiphy *wiphy;
+       enum nl80211_iftype iftype;
+
+       /* private to the generic wireless code */
+       struct list_head list;
+       struct net_device *netdev;
+
+       /* currently used for IBSS - might be rearranged in the future */
+       struct cfg80211_bss *current_bss;
+       u8 bssid[ETH_ALEN];
+       u8 ssid[IEEE80211_MAX_SSID_LEN];
+       u8 ssid_len;
+
+#ifdef CONFIG_WIRELESS_EXT
+       /* wext data */
+       struct {
+               struct cfg80211_ibss_params ibss;
+               u8 bssid[ETH_ALEN];
+               s8 default_key, default_mgmt_key;
+       } wext;
+#endif
+};
+
+/**
+ * wdev_priv - return wiphy priv from wireless_dev
+ *
+ * @wdev: The wireless device whose wiphy's priv pointer to return
+ */
+static inline void *wdev_priv(struct wireless_dev *wdev)
+{
+       BUG_ON(!wdev);
+       return wiphy_priv(wdev->wiphy);
+}
+
+/*
+ * Utility functions
+ */
+
+/**
+ * ieee80211_channel_to_frequency - convert channel number to frequency
+ */
+extern int ieee80211_channel_to_frequency(int chan);
+
+/**
+ * ieee80211_frequency_to_channel - convert frequency to channel number
+ */
+extern int ieee80211_frequency_to_channel(int freq);
+
+/*
+ * Name indirection necessary because the ieee80211 code also has
+ * a function named "ieee80211_get_channel", so if you include
+ * cfg80211's header file you get cfg80211's version, if you try
+ * to include both header files you'll (rightfully!) get a symbol
+ * clash.
+ */
+extern struct ieee80211_channel *__ieee80211_get_channel(struct wiphy *wiphy,
+                                                        int freq);
+/**
+ * ieee80211_get_channel - get channel struct from wiphy for specified frequency
+ */
+static inline struct ieee80211_channel *
+ieee80211_get_channel(struct wiphy *wiphy, int freq)
+{
+       return __ieee80211_get_channel(wiphy, freq);
+}
+
+/**
+ * ieee80211_get_response_rate - get basic rate for a given rate
+ *
+ * @sband: the band to look for rates in
+ * @basic_rates: bitmap of basic rates
+ * @bitrate: the bitrate for which to find the basic rate
+ *
+ * This function returns the basic rate corresponding to a given
+ * bitrate, that is the next lower bitrate contained in the basic
+ * rate map, which is, for this function, given as a bitmap of
+ * indices of rates in the band's bitrate table.
+ */
+struct ieee80211_rate *
+ieee80211_get_response_rate(struct ieee80211_supported_band *sband,
+                           u32 basic_rates, int bitrate);
+
+/*
+ * Radiotap parsing functions -- for controlled injection support
+ *
+ * Implemented in net/wireless/radiotap.c
+ * Documentation in Documentation/networking/radiotap-headers.txt
+ */
+
+/**
+ * struct ieee80211_radiotap_iterator - tracks walk thru present radiotap args
+ * @rtheader: pointer to the radiotap header we are walking through
+ * @max_length: length of radiotap header in cpu byte ordering
+ * @this_arg_index: IEEE80211_RADIOTAP_... index of current arg
+ * @this_arg: pointer to current radiotap arg
+ * @arg_index: internal next argument index
+ * @arg: internal next argument pointer
+ * @next_bitmap: internal pointer to next present u32
+ * @bitmap_shifter: internal shifter for curr u32 bitmap, b0 set == arg present
+ */
+
+struct ieee80211_radiotap_iterator {
+       struct ieee80211_radiotap_header *rtheader;
+       int max_length;
+       int this_arg_index;
+       u8 *this_arg;
+
+       int arg_index;
+       u8 *arg;
+       __le32 *next_bitmap;
+       u32 bitmap_shifter;
+};
+
+extern int ieee80211_radiotap_iterator_init(
+   struct ieee80211_radiotap_iterator *iterator,
+   struct ieee80211_radiotap_header *radiotap_header,
+   int max_length);
+
+extern int ieee80211_radiotap_iterator_next(
+   struct ieee80211_radiotap_iterator *iterator);
+
+extern const unsigned char rfc1042_header[6];
+extern const unsigned char bridge_tunnel_header[6];
+
+/**
+ * ieee80211_get_hdrlen_from_skb - get header length from data
+ *
+ * Given an skb with a raw 802.11 header at the data pointer this function
+ * returns the 802.11 header length in bytes (not including encryption
+ * headers). If the data in the sk_buff is too short to contain a valid 802.11
+ * header the function returns 0.
+ *
+ * @skb: the frame
+ */
+unsigned int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb);
+
+/**
+ * ieee80211_hdrlen - get header length in bytes from frame control
+ * @fc: frame control field in little-endian format
+ */
+unsigned int ieee80211_hdrlen(__le16 fc);
+
+/**
+ * ieee80211_data_to_8023 - convert an 802.11 data frame to 802.3
+ * @skb: the 802.11 data frame
+ * @addr: the device MAC address
+ * @iftype: the virtual interface type
+ */
+int ieee80211_data_to_8023(struct sk_buff *skb, u8 *addr,
+                          enum nl80211_iftype iftype);
+
+/**
+ * ieee80211_data_from_8023 - convert an 802.3 frame to 802.11
+ * @skb: the 802.3 frame
+ * @addr: the device MAC address
+ * @iftype: the virtual interface type
+ * @bssid: the network bssid (used only for iftype STATION and ADHOC)
+ * @qos: build 802.11 QoS data frame
+ */
+int ieee80211_data_from_8023(struct sk_buff *skb, u8 *addr,
+                            enum nl80211_iftype iftype, u8 *bssid, bool qos);
+
+/**
+ * cfg80211_classify8021d - determine the 802.1p/1d tag for a data frame
+ * @skb: the data frame
+ */
+unsigned int cfg80211_classify8021d(struct sk_buff *skb);
+
+/*
+ * Regulatory helper functions for wiphys
+ */
+
+/**
+ * regulatory_hint - driver hint to the wireless core a regulatory domain
+ * @wiphy: the wireless device giving the hint (used only for reporting
+ *     conflicts)
+ * @alpha2: the ISO/IEC 3166 alpha2 the driver claims its regulatory domain
+ *     should be in. If @rd is set this should be NULL. Note that if you
+ *     set this to NULL you should still set rd->alpha2 to some accepted
+ *     alpha2.
+ *
+ * Wireless drivers can use this function to hint to the wireless core
+ * what it believes should be the current regulatory domain by
+ * giving it an ISO/IEC 3166 alpha2 country code it knows its regulatory
+ * domain should be in or by providing a completely build regulatory domain.
+ * If the driver provides an ISO/IEC 3166 alpha2 userspace will be queried
+ * for a regulatory domain structure for the respective country.
+ *
+ * The wiphy must have been registered to cfg80211 prior to this call.
+ * For cfg80211 drivers this means you must first use wiphy_register(),
+ * for mac80211 drivers you must first use ieee80211_register_hw().
+ *
+ * Drivers should check the return value, its possible you can get
+ * an -ENOMEM.
+ */
+extern int regulatory_hint(struct wiphy *wiphy, const char *alpha2);
+
+/**
+ * regulatory_hint_11d - hints a country IE as a regulatory domain
+ * @wiphy: the wireless device giving the hint (used only for reporting
+ *     conflicts)
+ * @country_ie: pointer to the country IE
+ * @country_ie_len: length of the country IE
+ *
+ * We will intersect the rd with the what CRDA tells us should apply
+ * for the alpha2 this country IE belongs to, this prevents APs from
+ * sending us incorrect or outdated information against a country.
+ */
+extern void regulatory_hint_11d(struct wiphy *wiphy,
+                               u8 *country_ie,
+                               u8 country_ie_len);
+/**
+ * wiphy_apply_custom_regulatory - apply a custom driver regulatory domain
+ * @wiphy: the wireless device we want to process the regulatory domain on
+ * @regd: the custom regulatory domain to use for this wiphy
+ *
+ * Drivers can sometimes have custom regulatory domains which do not apply
+ * to a specific country. Drivers can use this to apply such custom regulatory
+ * domains. This routine must be called prior to wiphy registration. The
+ * custom regulatory domain will be trusted completely and as such previous
+ * default channel settings will be disregarded. If no rule is found for a
+ * channel on the regulatory domain the channel will be disabled.
+ */
+extern void wiphy_apply_custom_regulatory(
+       struct wiphy *wiphy,
+       const struct ieee80211_regdomain *regd);
+
+/**
+ * freq_reg_info - get regulatory information for the given frequency
+ * @wiphy: the wiphy for which we want to process this rule for
+ * @center_freq: Frequency in KHz for which we want regulatory information for
+ * @desired_bw_khz: the desired max bandwidth you want to use per
+ *     channel. Note that this is still 20 MHz if you want to use HT40
+ *     as HT40 makes use of two channels for its 40 MHz width bandwidth.
+ *     If set to 0 we'll assume you want the standard 20 MHz.
+ * @reg_rule: the regulatory rule which we have for this frequency
+ *
+ * Use this function to get the regulatory rule for a specific frequency on
+ * a given wireless device. If the device has a specific regulatory domain
+ * it wants to follow we respect that unless a country IE has been received
+ * and processed already.
+ *
+ * Returns 0 if it was able to find a valid regulatory rule which does
+ * apply to the given center_freq otherwise it returns non-zero. It will
+ * also return -ERANGE if we determine the given center_freq does not even have
+ * a regulatory rule for a frequency range in the center_freq's band. See
+ * freq_in_rule_band() for our current definition of a band -- this is purely
+ * subjective and right now its 802.11 specific.
+ */
+extern int freq_reg_info(struct wiphy *wiphy,
+                        u32 center_freq,
+                        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);
@@ -834,9 +1422,72 @@ int cfg80211_wext_siwscan(struct net_device *dev,
 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_ibss_wext_siwfreq(struct net_device *dev,
+                              struct iw_request_info *info,
+                              struct iw_freq *freq, char *extra);
+int cfg80211_ibss_wext_giwfreq(struct net_device *dev,
+                              struct iw_request_info *info,
+                              struct iw_freq *freq, char *extra);
+int cfg80211_ibss_wext_siwessid(struct net_device *dev,
+                               struct iw_request_info *info,
+                               struct iw_point *data, char *ssid);
+int cfg80211_ibss_wext_giwessid(struct net_device *dev,
+                               struct iw_request_info *info,
+                               struct iw_point *data, char *ssid);
+int cfg80211_ibss_wext_siwap(struct net_device *dev,
+                            struct iw_request_info *info,
+                            struct sockaddr *ap_addr, char *extra);
+int cfg80211_ibss_wext_giwap(struct net_device *dev,
+                            struct iw_request_info *info,
+                            struct sockaddr *ap_addr, char *extra);
+
+struct ieee80211_channel *cfg80211_wext_freq(struct wiphy *wiphy,
+                                            struct iw_freq *freq);
+
+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);
+
+/*
+ * callbacks for asynchronous cfg80211 methods, notification
+ * functions and BSS handling helpers
+ */
 
 /**
  * cfg80211_scan_done - notify that scan finished
@@ -864,6 +1515,14 @@ cfg80211_inform_bss_frame(struct wiphy *wiphy,
                          struct ieee80211_mgmt *mgmt, size_t len,
                          s32 signal, gfp_t gfp);
 
+struct cfg80211_bss*
+cfg80211_inform_bss(struct wiphy *wiphy,
+                   struct ieee80211_channel *channel,
+                   const u8 *bssid,
+                   u64 timestamp, u16 capability, u16 beacon_interval,
+                   const u8 *ie, size_t ielen,
+                   s32 signal, gfp_t gfp);
+
 struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy,
                                      struct ieee80211_channel *channel,
                                      const u8 *bssid,
@@ -883,6 +1542,7 @@ struct cfg80211_bss *cfg80211_get_mesh(struct wiphy *wiphy,
                                       const u8 *meshid, size_t meshidlen,
                                       const u8 *meshcfg);
 void cfg80211_put_bss(struct cfg80211_bss *bss);
+
 /**
  * cfg80211_unlink_bss - unlink BSS from internal data structures
  * @wiphy: the wiphy
@@ -902,10 +1562,19 @@ void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *bss);
  * @len: length of the frame data
  *
  * This function is called whenever an authentication has been processed in
- * station mode.
+ * station mode. The driver is required to call either this function or
+ * cfg80211_send_auth_timeout() to indicate the result of cfg80211_ops::auth()
+ * call.
  */
 void cfg80211_send_rx_auth(struct net_device *dev, const u8 *buf, size_t len);
 
+/**
+ * cfg80211_send_auth_timeout - notification of timed out authentication
+ * @dev: network device
+ * @addr: The MAC address of the device with which the authentication timed out
+ */
+void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr);
+
 /**
  * cfg80211_send_rx_assoc - notification of processed association
  * @dev: network device
@@ -913,33 +1582,42 @@ void cfg80211_send_rx_auth(struct net_device *dev, const u8 *buf, size_t len);
  * @len: length of the frame data
  *
  * This function is called whenever a (re)association response has been
- * processed in station mode.
+ * processed in station mode. The driver is required to call either this
+ * function or cfg80211_send_assoc_timeout() to indicate the result of
+ * cfg80211_ops::assoc() call.
  */
 void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len);
 
 /**
- * cfg80211_send_rx_deauth - notification of processed deauthentication
+ * cfg80211_send_assoc_timeout - notification of timed out association
+ * @dev: network device
+ * @addr: The MAC address of the device with which the association timed out
+ */
+void cfg80211_send_assoc_timeout(struct net_device *dev, const u8 *addr);
+
+/**
+ * cfg80211_send_deauth - notification of processed deauthentication
  * @dev: network device
  * @buf: deauthentication frame (header + body)
  * @len: length of the frame data
  *
  * This function is called whenever deauthentication has been processed in
- * station mode.
+ * station mode. This includes both received deauthentication frames and
+ * locally generated ones.
  */
-void cfg80211_send_rx_deauth(struct net_device *dev, const u8 *buf,
-                            size_t len);
+void cfg80211_send_deauth(struct net_device *dev, const u8 *buf, size_t len);
 
 /**
- * cfg80211_send_rx_disassoc - notification of processed disassociation
+ * cfg80211_send_disassoc - notification of processed disassociation
  * @dev: network device
  * @buf: disassociation response frame (header + body)
  * @len: length of the frame data
  *
  * This function is called whenever disassociation has been processed in
- * station mode.
+ * station mode. This includes both received disassociation frames and locally
+ * generated ones.
  */
-void cfg80211_send_rx_disassoc(struct net_device *dev, const u8 *buf,
-                              size_t len);
+void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len);
 
 /**
  * cfg80211_hold_bss - exclude bss from expiration
@@ -958,4 +1636,55 @@ void cfg80211_hold_bss(struct cfg80211_bss *bss);
  */
 void cfg80211_unhold_bss(struct cfg80211_bss *bss);
 
+/**
+ * cfg80211_michael_mic_failure - notification of Michael MIC failure (TKIP)
+ * @dev: network device
+ * @addr: The source MAC address of the frame
+ * @key_type: The key type that the received frame used
+ * @key_id: Key identifier (0..3)
+ * @tsc: The TSC value of the frame that generated the MIC failure (6 octets)
+ *
+ * This function is called whenever the local MAC detects a MIC failure in a
+ * received frame. This matches with MLME-MICHAELMICFAILURE.indication()
+ * primitive.
+ */
+void cfg80211_michael_mic_failure(struct net_device *dev, const u8 *addr,
+                                 enum nl80211_key_type key_type, int key_id,
+                                 const u8 *tsc);
+
+/**
+ * cfg80211_ibss_joined - notify cfg80211 that device joined an IBSS
+ *
+ * @dev: network device
+ * @bssid: the BSSID of the IBSS joined
+ * @gfp: allocation flags
+ *
+ * This function notifies cfg80211 that the device joined an IBSS or
+ * switched to a different BSSID. Before this function can be called,
+ * either a beacon has to have been received from the IBSS, or one of
+ * the cfg80211_inform_bss{,_frame} functions must have been called
+ * with the locally generated beacon -- this guarantees that there is
+ * always a scan result for this IBSS. cfg80211 will handle the rest.
+ */
+void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, gfp_t gfp);
+
+/**
+ * wiphy_rfkill_set_hw_state - notify cfg80211 about hw block state
+ * @wiphy: the wiphy
+ * @blocked: block status
+ */
+void wiphy_rfkill_set_hw_state(struct wiphy *wiphy, bool blocked);
+
+/**
+ * wiphy_rfkill_start_polling - start polling rfkill
+ * @wiphy: the wiphy
+ */
+void wiphy_rfkill_start_polling(struct wiphy *wiphy);
+
+/**
+ * wiphy_rfkill_stop_polling - stop polling rfkill
+ * @wiphy: the wiphy
+ */
+void wiphy_rfkill_stop_polling(struct wiphy *wiphy);
+
 #endif /* __NET_CFG80211_H */
index 6be3b082a070332187ff6134ad04fd0e09da3279..7fc409c19b37e9e9c6d692724258e64d71c12596 100644 (file)
@@ -195,6 +195,12 @@ struct dst_entry * dst_clone(struct dst_entry * dst)
 }
 
 extern void dst_release(struct dst_entry *dst);
+static inline void skb_dst_drop(struct sk_buff *skb)
+{
+       if (skb->_skb_dst)
+               dst_release(skb_dst(skb));
+       skb->_skb_dst = 0UL;
+}
 
 /* Children define the path of the packet through the
  * Linux networking.  Thus, destinations are stackable.
@@ -246,7 +252,7 @@ static inline void dst_negative_advice(struct dst_entry **dst_p)
 
 static inline void dst_link_failure(struct sk_buff *skb)
 {
-       struct dst_entry * dst = skb->dst;
+       struct dst_entry *dst = skb_dst(skb);
        if (dst && dst->ops && dst->ops->link_failure)
                dst->ops->link_failure(skb);
 }
@@ -265,13 +271,13 @@ static inline void dst_set_expires(struct dst_entry *dst, int timeout)
 /* Output packet to network from transport.  */
 static inline int dst_output(struct sk_buff *skb)
 {
-       return skb->dst->output(skb);
+       return skb_dst(skb)->output(skb);
 }
 
 /* Input packet from network to transport.  */
 static inline int dst_input(struct sk_buff *skb)
 {
-       return skb->dst->input(skb);
+       return skb_dst(skb)->input(skb);
 }
 
 static inline struct dst_entry *dst_check(struct dst_entry *dst, u32 cookie)
index c2bb5cae65156cacfe24d31fa954a7317aa7d188..ca4b2e840078627befec9069f7bdc972778fe7b5 100644 (file)
@@ -48,14 +48,12 @@ struct fib_rules_ops
                                         struct flowi *, int);
        int                     (*configure)(struct fib_rule *,
                                             struct sk_buff *,
-                                            struct nlmsghdr *,
                                             struct fib_rule_hdr *,
                                             struct nlattr **);
        int                     (*compare)(struct fib_rule *,
                                           struct fib_rule_hdr *,
                                           struct nlattr **);
        int                     (*fill)(struct fib_rule *, struct sk_buff *,
-                                       struct nlmsghdr *,
                                        struct fib_rule_hdr *);
        u32                     (*default_pref)(struct fib_rules_ops *ops);
        size_t                  (*nlmsg_payload)(struct fib_rule *);
index 747c255d1df034dcac884a1bffb5dfffbb889978..1b0e3ee4ddd84dbe31250710395c17c34a9ebc8c 100644 (file)
@@ -88,6 +88,8 @@ struct genl_ops
 };
 
 extern int genl_register_family(struct genl_family *family);
+extern int genl_register_family_with_ops(struct genl_family *family,
+       struct genl_ops *ops, size_t n_ops);
 extern int genl_unregister_family(struct genl_family *family);
 extern int genl_register_ops(struct genl_family *, struct genl_ops *ops);
 extern int genl_unregister_ops(struct genl_family *, struct genl_ops *ops);
diff --git a/include/net/ieee802154/af_ieee802154.h b/include/net/ieee802154/af_ieee802154.h
new file mode 100644 (file)
index 0000000..0d78605
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * IEEE 802.15.4 inteface for userspace
+ *
+ * Copyright 2007, 2008 Siemens AG
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Written by:
+ * Sergey Lapin <slapin@ossfans.org>
+ * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
+ */
+
+#ifndef _AF_IEEE802154_H
+#define _AF_IEEE802154_H
+
+#include <linux/socket.h> /* for sa_family_t */
+
+enum {
+       IEEE802154_ADDR_NONE = 0x0,
+       /* RESERVED = 0x01, */
+       IEEE802154_ADDR_SHORT = 0x2, /* 16-bit address + PANid */
+       IEEE802154_ADDR_LONG = 0x3, /* 64-bit address + PANid */
+};
+
+/* address length, octets */
+#define IEEE802154_ADDR_LEN    8
+
+struct ieee802154_addr {
+       int addr_type;
+       u16 pan_id;
+       union {
+               u8 hwaddr[IEEE802154_ADDR_LEN];
+               u16 short_addr;
+       };
+};
+
+#define IEEE802154_PANID_BROADCAST     0xffff
+#define IEEE802154_ADDR_BROADCAST      0xffff
+#define IEEE802154_ADDR_UNDEF          0xfffe
+
+struct sockaddr_ieee802154 {
+       sa_family_t family; /* AF_IEEE802154 */
+       struct ieee802154_addr addr;
+};
+
+/* master device */
+#define IEEE802154_SIOC_ADD_SLAVE              (SIOCDEVPRIVATE + 0)
+
+#endif
diff --git a/include/net/ieee802154/mac_def.h b/include/net/ieee802154/mac_def.h
new file mode 100644 (file)
index 0000000..8cb6846
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+ * IEEE802.15.4-2003 specification
+ *
+ * Copyright (C) 2007, 2008 Siemens AG
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Written by:
+ * Pavel Smolenskiy <pavel.smolenskiy@gmail.com>
+ * Maxim Gorbachyov <maxim.gorbachev@siemens.com>
+ * Maxim Osipov <maxim.osipov@siemens.com>
+ * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
+ */
+
+#ifndef IEEE802154_MAC_DEF_H
+#define IEEE802154_MAC_DEF_H
+
+#define IEEE802154_FC_TYPE_BEACON      0x0     /* Frame is beacon */
+#define        IEEE802154_FC_TYPE_DATA         0x1     /* Frame is data */
+#define IEEE802154_FC_TYPE_ACK         0x2     /* Frame is acknowledgment */
+#define IEEE802154_FC_TYPE_MAC_CMD     0x3     /* Frame is MAC command */
+
+#define IEEE802154_FC_TYPE_SHIFT               0
+#define IEEE802154_FC_TYPE_MASK                ((1 << 3) - 1)
+#define IEEE802154_FC_TYPE(x)          ((x & IEEE802154_FC_TYPE_MASK) >> IEEE802154_FC_TYPE_SHIFT)
+#define IEEE802154_FC_SET_TYPE(v, x)   do {    \
+       v = (((v) & ~IEEE802154_FC_TYPE_MASK) | \
+           (((x) << IEEE802154_FC_TYPE_SHIFT) & IEEE802154_FC_TYPE_MASK)); \
+       } while (0)
+
+#define IEEE802154_FC_SECEN            (1 << 3)
+#define IEEE802154_FC_FRPEND           (1 << 4)
+#define IEEE802154_FC_ACK_REQ          (1 << 5)
+#define IEEE802154_FC_INTRA_PAN                (1 << 6)
+
+#define IEEE802154_FC_SAMODE_SHIFT     14
+#define IEEE802154_FC_SAMODE_MASK      (3 << IEEE802154_FC_SAMODE_SHIFT)
+#define IEEE802154_FC_DAMODE_SHIFT     10
+#define IEEE802154_FC_DAMODE_MASK      (3 << IEEE802154_FC_DAMODE_SHIFT)
+
+#define IEEE802154_FC_SAMODE(x)                \
+       (((x) & IEEE802154_FC_SAMODE_MASK) >> IEEE802154_FC_SAMODE_SHIFT)
+
+#define IEEE802154_FC_DAMODE(x)                \
+       (((x) & IEEE802154_FC_DAMODE_MASK) >> IEEE802154_FC_DAMODE_SHIFT)
+
+
+/* MAC's Command Frames Identifiers */
+#define IEEE802154_CMD_ASSOCIATION_REQ         0x01
+#define IEEE802154_CMD_ASSOCIATION_RESP                0x02
+#define IEEE802154_CMD_DISASSOCIATION_NOTIFY   0x03
+#define IEEE802154_CMD_DATA_REQ                        0x04
+#define IEEE802154_CMD_PANID_CONFLICT_NOTIFY   0x05
+#define IEEE802154_CMD_ORPHAN_NOTIFY           0x06
+#define IEEE802154_CMD_BEACON_REQ              0x07
+#define IEEE802154_CMD_COORD_REALIGN_NOTIFY    0x08
+#define IEEE802154_CMD_GTS_REQ                 0x09
+
+/*
+ * The return values of MAC operations
+ */
+enum {
+       /*
+        * The requested operation was completed successfully.
+        * For a transmission request, this value indicates
+        * a successful transmission.
+        */
+       IEEE802154_SUCCESS = 0x0,
+
+       /* The beacon was lost following a synchronization request. */
+       IEEE802154_BEACON_LOSS = 0xe0,
+       /*
+        * A transmission could not take place due to activity on the
+        * channel, i.e., the CSMA-CA mechanism has failed.
+        */
+       IEEE802154_CHNL_ACCESS_FAIL = 0xe1,
+       /* The GTS request has been denied by the PAN coordinator. */
+       IEEE802154_DENINED = 0xe2,
+       /* The attempt to disable the transceiver has failed. */
+       IEEE802154_DISABLE_TRX_FAIL = 0xe3,
+       /*
+        * The received frame induces a failed security check according to
+        * the security suite.
+        */
+       IEEE802154_FAILED_SECURITY_CHECK = 0xe4,
+       /*
+        * The frame resulting from secure processing has a length that is
+        * greater than aMACMaxFrameSize.
+        */
+       IEEE802154_FRAME_TOO_LONG = 0xe5,
+       /*
+        * The requested GTS transmission failed because the specified GTS
+        * either did not have a transmit GTS direction or was not defined.
+        */
+       IEEE802154_INVALID_GTS = 0xe6,
+       /*
+        * A request to purge an MSDU from the transaction queue was made using
+        * an MSDU handle that was not found in the transaction table.
+        */
+       IEEE802154_INVALID_HANDLE = 0xe7,
+       /* A parameter in the primitive is out of the valid range.*/
+       IEEE802154_INVALID_PARAMETER = 0xe8,
+       /* No acknowledgment was received after aMaxFrameRetries. */
+       IEEE802154_NO_ACK = 0xe9,
+       /* A scan operation failed to find any network beacons.*/
+       IEEE802154_NO_BEACON = 0xea,
+       /* No response data were available following a request. */
+       IEEE802154_NO_DATA = 0xeb,
+       /* The operation failed because a short address was not allocated. */
+       IEEE802154_NO_SHORT_ADDRESS = 0xec,
+       /*
+        * A receiver enable request was unsuccessful because it could not be
+        * completed within the CAP.
+        */
+       IEEE802154_OUT_OF_CAP = 0xed,
+       /*
+        * A PAN identifier conflict has been detected and communicated to the
+        * PAN coordinator.
+        */
+       IEEE802154_PANID_CONFLICT = 0xee,
+       /* A coordinator realignment command has been received. */
+       IEEE802154_REALIGMENT = 0xef,
+       /* The transaction has expired and its information discarded. */
+       IEEE802154_TRANSACTION_EXPIRED = 0xf0,
+       /* There is no capacity to store the transaction. */
+       IEEE802154_TRANSACTION_OVERFLOW = 0xf1,
+       /*
+        * The transceiver was in the transmitter enabled state when the
+        * receiver was requested to be enabled.
+        */
+       IEEE802154_TX_ACTIVE = 0xf2,
+       /* The appropriate key is not available in the ACL. */
+       IEEE802154_UNAVAILABLE_KEY = 0xf3,
+       /*
+        * A SET/GET request was issued with the identifier of a PIB attribute
+        * that is not supported.
+        */
+       IEEE802154_UNSUPPORTED_ATTR = 0xf4,
+       /*
+        * A request to perform a scan operation failed because the MLME was
+        * in the process of performing a previously initiated scan operation.
+        */
+       IEEE802154_SCAN_IN_PROGRESS = 0xfc,
+};
+
+
+#endif
+
+
diff --git a/include/net/ieee802154/netdevice.h b/include/net/ieee802154/netdevice.h
new file mode 100644 (file)
index 0000000..e2506af
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * An interface between IEEE802.15.4 device and rest of the kernel.
+ *
+ * Copyright (C) 2007, 2008, 2009 Siemens AG
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Written by:
+ * Pavel Smolenskiy <pavel.smolenskiy@gmail.com>
+ * Maxim Gorbachyov <maxim.gorbachev@siemens.com>
+ * Maxim Osipov <maxim.osipov@siemens.com>
+ * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
+ */
+
+#ifndef IEEE802154_NETDEVICE_H
+#define IEEE802154_NETDEVICE_H
+
+/*
+ * A control block of skb passed between the ARPHRD_IEEE802154 device
+ * and other stack parts.
+ */
+struct ieee802154_mac_cb {
+       u8 lqi;
+       struct ieee802154_addr sa;
+       struct ieee802154_addr da;
+       u8 flags;
+       u8 seq;
+};
+
+static inline struct ieee802154_mac_cb *mac_cb(struct sk_buff *skb)
+{
+       return (struct ieee802154_mac_cb *)skb->cb;
+}
+
+#define MAC_CB_FLAG_TYPEMASK           ((1 << 3) - 1)
+
+#define MAC_CB_FLAG_ACKREQ             (1 << 3)
+#define MAC_CB_FLAG_SECEN              (1 << 4)
+#define MAC_CB_FLAG_INTRAPAN           (1 << 5)
+
+static inline int mac_cb_is_ackreq(struct sk_buff *skb)
+{
+       return mac_cb(skb)->flags & MAC_CB_FLAG_ACKREQ;
+}
+
+static inline int mac_cb_is_secen(struct sk_buff *skb)
+{
+       return mac_cb(skb)->flags & MAC_CB_FLAG_SECEN;
+}
+
+static inline int mac_cb_is_intrapan(struct sk_buff *skb)
+{
+       return mac_cb(skb)->flags & MAC_CB_FLAG_INTRAPAN;
+}
+
+static inline int mac_cb_type(struct sk_buff *skb)
+{
+       return mac_cb(skb)->flags & MAC_CB_FLAG_TYPEMASK;
+}
+
+#define IEEE802154_MAC_SCAN_ED         0
+#define IEEE802154_MAC_SCAN_ACTIVE     1
+#define IEEE802154_MAC_SCAN_PASSIVE    2
+#define IEEE802154_MAC_SCAN_ORPHAN     3
+
+/*
+ * This should be located at net_device->ml_priv
+ */
+struct ieee802154_mlme_ops {
+       int (*assoc_req)(struct net_device *dev,
+                       struct ieee802154_addr *addr,
+                       u8 channel, u8 cap);
+       int (*assoc_resp)(struct net_device *dev,
+                       struct ieee802154_addr *addr,
+                       u16 short_addr, u8 status);
+       int (*disassoc_req)(struct net_device *dev,
+                       struct ieee802154_addr *addr,
+                       u8 reason);
+       int (*start_req)(struct net_device *dev,
+                       struct ieee802154_addr *addr,
+                       u8 channel, u8 bcn_ord, u8 sf_ord,
+                       u8 pan_coord, u8 blx, u8 coord_realign);
+       int (*scan_req)(struct net_device *dev,
+                       u8 type, u32 channels, u8 duration);
+
+       /*
+        * FIXME: these should become the part of PIB/MIB interface.
+        * However we still don't have IB interface of any kind
+        */
+       u16 (*get_pan_id)(struct net_device *dev);
+       u16 (*get_short_addr)(struct net_device *dev);
+       u8 (*get_dsn)(struct net_device *dev);
+       u8 (*get_bsn)(struct net_device *dev);
+};
+
+static inline struct ieee802154_mlme_ops *ieee802154_mlme_ops(
+               struct net_device *dev)
+{
+       return dev->ml_priv;
+}
+
+#endif
+
+
diff --git a/include/net/ieee802154/nl802154.h b/include/net/ieee802154/nl802154.h
new file mode 100644 (file)
index 0000000..78efcdf
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * nl802154.h
+ *
+ * Copyright (C) 2007, 2008, 2009 Siemens AG
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#ifndef IEEE802154_NL_H
+#define IEEE802154_NL_H
+
+struct net_device;
+struct ieee802154_addr;
+
+int ieee802154_nl_assoc_indic(struct net_device *dev,
+               struct ieee802154_addr *addr, u8 cap);
+int ieee802154_nl_assoc_confirm(struct net_device *dev,
+               u16 short_addr, u8 status);
+int ieee802154_nl_disassoc_indic(struct net_device *dev,
+               struct ieee802154_addr *addr, u8 reason);
+int ieee802154_nl_disassoc_confirm(struct net_device *dev,
+               u8 status);
+int ieee802154_nl_scan_confirm(struct net_device *dev,
+               u8 status, u8 scan_type, u32 unscanned,
+               u8 *edl/*, struct list_head *pan_desc_list */);
+int ieee802154_nl_beacon_indic(struct net_device *dev, u16 panid,
+               u16 coord_addr);
+
+#endif
index f74665d7bea88374170c644d167167cab229b892..22c73a77cd991b3b5bc6f7a50333b50a6a2b6cdc 100644 (file)
@@ -100,7 +100,7 @@ static inline struct sock *__inet6_lookup_skb(struct inet_hashinfo *hashinfo,
 
        if (unlikely(sk = skb_steal_sock(skb)))
                return sk;
-       else return __inet6_lookup(dev_net(skb->dst->dev), hashinfo,
+       else return __inet6_lookup(dev_net(skb_dst(skb)->dev), hashinfo,
                                   &ipv6_hdr(skb)->saddr, sport,
                                   &ipv6_hdr(skb)->daddr, ntohs(dport),
                                   inet6_iif(skb));
index a44e2248b2ef108f1bff42062449bac760ec9899..d522dcf3031ab8ad7806af1d572e22751c93a6da 100644 (file)
@@ -385,7 +385,7 @@ static inline struct sock *__inet_lookup_skb(struct inet_hashinfo *hashinfo,
        if (unlikely(sk = skb_steal_sock(skb)))
                return sk;
        else
-               return __inet_lookup(dev_net(skb->dst->dev), hashinfo,
+               return __inet_lookup(dev_net(skb_dst(skb)->dev), hashinfo,
                                     iph->saddr, sport,
                                     iph->daddr, dport, inet_iif(skb));
 }
index de0ecc71cf0388d944ec0a032b7ffe8453324a95..20a6957af870a0b12973a4b3cb937d5e0aeac011 100644 (file)
@@ -130,7 +130,8 @@ struct inet_sock {
                                freebind:1,
                                hdrincl:1,
                                mc_loop:1,
-                               transparent:1;
+                               transparent:1,
+                               mc_all:1;
        int                     mc_index;
        __be32                  mc_addr;
        struct ip_mc_socklist   *mc_list;
index 4ac7577f98d0ba37808d3d4c52db8e0fc6c79592..72c36926c26d80363bec2bdc3094d91ecb109e9e 100644 (file)
@@ -168,7 +168,10 @@ struct ipv4_config
 extern struct ipv4_config ipv4_config;
 #define IP_INC_STATS(net, field)       SNMP_INC_STATS((net)->mib.ip_statistics, field)
 #define IP_INC_STATS_BH(net, field)    SNMP_INC_STATS_BH((net)->mib.ip_statistics, field)
+#define IP_ADD_STATS(net, field, val)  SNMP_ADD_STATS((net)->mib.ip_statistics, field, val)
 #define IP_ADD_STATS_BH(net, field, val) SNMP_ADD_STATS_BH((net)->mib.ip_statistics, field, val)
+#define IP_UPD_PO_STATS(net, field, val) SNMP_UPD_PO_STATS((net)->mib.ip_statistics, field, val)
+#define IP_UPD_PO_STATS_BH(net, field, val) SNMP_UPD_PO_STATS_BH((net)->mib.ip_statistics, field, val)
 #define NET_INC_STATS(net, field)      SNMP_INC_STATS((net)->mib.net_statistics, field)
 #define NET_INC_STATS_BH(net, field)   SNMP_INC_STATS_BH((net)->mib.net_statistics, field)
 #define NET_INC_STATS_USER(net, field)         SNMP_INC_STATS_USER((net)->mib.net_statistics, field)
index 5f53db7e4e576f61450f83db2e2c5f14a871ce64..0e1b8aebaff860f01e414e377737ed1eedb66d0a 100644 (file)
@@ -142,7 +142,7 @@ static inline void ip6_dst_store(struct sock *sk, struct dst_entry *dst,
 
 static inline int ipv6_unicast_destination(struct sk_buff *skb)
 {
-       struct rt6_info *rt = (struct rt6_info *) skb->dst;
+       struct rt6_info *rt = (struct rt6_info *) skb_dst(skb);
 
        return rt->rt6i_flags & RTF_LOCAL;
 }
index 8b12667f7a2bccad312fc0e63e679dfd02ec3509..ef91fe924ba42ddf5a0748836726098ec2a95f9a 100644 (file)
@@ -124,14 +124,12 @@ struct fib_result_nl {
 #ifdef CONFIG_IP_ROUTE_MULTIPATH
 
 #define FIB_RES_NH(res)                ((res).fi->fib_nh[(res).nh_sel])
-#define FIB_RES_RESET(res)     ((res).nh_sel = 0)
 
 #define FIB_TABLE_HASHSZ 2
 
 #else /* CONFIG_IP_ROUTE_MULTIPATH */
 
 #define FIB_RES_NH(res)                ((res).fi->fib_nh[0])
-#define FIB_RES_RESET(res)
 
 #define FIB_TABLE_HASHSZ 256
 
@@ -145,7 +143,6 @@ struct fib_result_nl {
 struct fib_table {
        struct hlist_node tb_hlist;
        u32             tb_id;
-       unsigned        tb_stamp;
        int             tb_default;
        int             (*tb_lookup)(struct fib_table *tb, const struct flowi *flp, struct fib_result *res);
        int             (*tb_insert)(struct fib_table *, struct fib_config *);
index fdf9bd7437057e26b0f9cd3bdadb8c70ed8a09f6..5d3036fa1511695879a18d3adc02f57feef49392 100644 (file)
@@ -28,11 +28,18 @@ struct ip_tunnel
        unsigned int                    prl_count;      /* # of entries in PRL */
 };
 
+/* ISATAP: default interval between RS in secondy */
+#define IPTUNNEL_RS_DEFAULT_DELAY      (900)
+
 struct ip_tunnel_prl_entry
 {
        struct ip_tunnel_prl_entry      *next;
        __be32                          addr;
        u16                             flags;
+       unsigned long                   rs_delay;
+       struct timer_list               rs_timer;
+       struct ip_tunnel                *tunnel;
+       spinlock_t                      lock;
 };
 
 #define IPTUNNEL_XMIT() do {                                           \
index c1f16fc49adeff0e5f6a2c66bf79fbad7b2440c1..f27fd83d67d8395ad5e30c9131010d73902a43b1 100644 (file)
@@ -126,15 +126,28 @@ extern struct ctl_path net_ipv6_ctl_path[];
        SNMP_ADD_STATS##modifier((net)->mib.statname##_statistics, (field), (val));\
 })
 
+#define _DEVUPD(net, statname, modifier, idev, field, val)             \
+({                                                                     \
+       struct inet6_dev *_idev = (idev);                               \
+       if (likely(_idev != NULL))                                      \
+               SNMP_UPD_PO_STATS##modifier((_idev)->stats.statname, field, (val)); \
+       SNMP_UPD_PO_STATS##modifier((net)->mib.statname##_statistics, field, (val));\
+})
+
 /* MIBs */
 
 #define IP6_INC_STATS(net, idev,field)         \
                _DEVINC(net, ipv6, , idev, field)
 #define IP6_INC_STATS_BH(net, idev,field)      \
                _DEVINC(net, ipv6, _BH, idev, field)
+#define IP6_ADD_STATS(net, idev,field,val)     \
+               _DEVADD(net, ipv6, , idev, field, val)
 #define IP6_ADD_STATS_BH(net, idev,field,val)  \
                _DEVADD(net, ipv6, _BH, idev, field, val)
-
+#define IP6_UPD_PO_STATS(net, idev,field,val)   \
+               _DEVUPD(net, ipv6, , idev, field, val)
+#define IP6_UPD_PO_STATS_BH(net, idev,field,val)   \
+               _DEVUPD(net, ipv6, _BH, idev, field, val)
 #define ICMP6_INC_STATS(net, idev, field)      \
                _DEVINC(net, icmpv6, , idev, field)
 #define ICMP6_INC_STATS_BH(net, idev, field)   \
index 85f80eadfa35fae702a8377dddebf9e92d6aaf12..21ee49ffcbaf7d9980a52b4dd84cc2ff4f849c6f 100644 (file)
@@ -73,8 +73,17 @@ struct iucv_sock {
        struct sk_buff_head     backlog_skb_q;
        struct sock_msg_q       message_q;
        unsigned int            send_tag;
+       u8                      flags;
+       u16                     msglimit;
 };
 
+/* iucv socket options (SOL_IUCV) */
+#define SO_IPRMDATA_MSG        0x0080          /* send/recv IPRM_DATA msgs */
+#define SO_MSGLIMIT    0x1000          /* get/set IUCV MSGLIMIT */
+
+/* iucv related control messages (scm) */
+#define SCM_IUCV_TRGCLS        0x0001          /* target class control message */
+
 struct iucv_sock_list {
        struct hlist_head head;
        rwlock_t          lock;
index 3b83a80e3fe0d69ec3e0c2a1fa6a48f71297374b..c061044769737f72a54bb1afe8e70c6d77ca38a7 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/wireless.h>
 #include <linux/device.h>
 #include <linux/ieee80211.h>
-#include <net/wireless.h>
 #include <net/cfg80211.h>
 
 /**
  * not do so then mac80211 may add this under certain circumstances.
  */
 
-/**
- * struct ieee80211_ht_bss_info - describing BSS's HT characteristics
- *
- * This structure describes most essential parameters needed
- * to describe 802.11n HT characteristics in a BSS.
- *
- * @primary_channel: channel number of primery channel
- * @bss_cap: 802.11n's general BSS capabilities (e.g. channel width)
- * @bss_op_mode: 802.11n's BSS operation modes (e.g. HT protection)
- */
-struct ieee80211_ht_bss_info {
-       u8 primary_channel;
-       u8 bss_cap;  /* use IEEE80211_HT_IE_CHA_ */
-       u8 bss_op_mode; /* use IEEE80211_HT_IE_ */
-};
-
 /**
  * enum ieee80211_max_queues - maximum number of queues
  *
@@ -150,6 +133,13 @@ struct ieee80211_low_level_stats {
  * @BSS_CHANGED_ERP_SLOT: slot timing changed
  * @BSS_CHANGED_HT: 802.11n parameters changed
  * @BSS_CHANGED_BASIC_RATES: Basic rateset changed
+ * @BSS_CHANGED_BEACON_INT: Beacon interval changed
+ * @BSS_CHANGED_BSSID: BSSID changed, for whatever
+ *     reason (IBSS and managed mode)
+ * @BSS_CHANGED_BEACON: Beacon data changed, retrieve
+ *     new beacon (beaconing modes)
+ * @BSS_CHANGED_BEACON_ENABLED: Beaconing should be
+ *     enabled/disabled (beaconing modes)
  */
 enum ieee80211_bss_change {
        BSS_CHANGED_ASSOC               = 1<<0,
@@ -158,14 +148,10 @@ enum ieee80211_bss_change {
        BSS_CHANGED_ERP_SLOT            = 1<<3,
        BSS_CHANGED_HT                  = 1<<4,
        BSS_CHANGED_BASIC_RATES         = 1<<5,
-};
-
-/**
- * struct ieee80211_bss_ht_conf - BSS's changing HT configuration
- * @operation_mode: HT operation mode (like in &struct ieee80211_ht_info)
- */
-struct ieee80211_bss_ht_conf {
-       u16 operation_mode;
+       BSS_CHANGED_BEACON_INT          = 1<<6,
+       BSS_CHANGED_BSSID               = 1<<7,
+       BSS_CHANGED_BEACON              = 1<<8,
+       BSS_CHANGED_BEACON_ENABLED      = 1<<9,
 };
 
 /**
@@ -187,12 +173,16 @@ struct ieee80211_bss_ht_conf {
  * @timestamp: beacon timestamp
  * @beacon_int: beacon interval
  * @assoc_capability: capabilities taken from assoc resp
- * @ht: BSS's HT configuration
  * @basic_rates: bitmap of basic rates, each bit stands for an
  *     index into the rate table configured by the driver in
  *     the current band.
+ * @bssid: The BSSID for this BSS
+ * @enable_beacon: whether beaconing should be enabled or not
+ * @ht_operation_mode: HT operation mode (like in &struct ieee80211_ht_info).
+ *     This field is only valid when the channel type is one of the HT types.
  */
 struct ieee80211_bss_conf {
+       const u8 *bssid;
        /* association related data */
        bool assoc;
        u16 aid;
@@ -200,12 +190,13 @@ struct ieee80211_bss_conf {
        bool use_cts_prot;
        bool use_short_preamble;
        bool use_short_slot;
+       bool enable_beacon;
        u8 dtim_period;
        u16 beacon_int;
        u16 assoc_capability;
        u64 timestamp;
        u32 basic_rates;
-       struct ieee80211_bss_ht_conf ht;
+       u16 ht_operation_mode;
 };
 
 /**
@@ -248,6 +239,8 @@ struct ieee80211_bss_conf {
  * @IEEE80211_TX_INTFL_NEED_TXPROCESSING: completely internal to mac80211,
  *     used to indicate that a pending frame requires TX processing before
  *     it can be sent out.
+ * @IEEE80211_TX_INTFL_RETRIED: completely internal to mac80211,
+ *     used to indicate that a frame was already retried due to PS
  */
 enum mac80211_tx_control_flags {
        IEEE80211_TX_CTL_REQ_TX_STATUS          = BIT(0),
@@ -265,6 +258,7 @@ enum mac80211_tx_control_flags {
        IEEE80211_TX_CTL_RATE_CTRL_PROBE        = BIT(12),
        IEEE80211_TX_INTFL_RCALGO               = BIT(13),
        IEEE80211_TX_INTFL_NEED_TXPROCESSING    = BIT(14),
+       IEEE80211_TX_INTFL_RETRIED              = BIT(15),
 };
 
 /**
@@ -518,52 +512,76 @@ struct ieee80211_rx_status {
  * Flags to define PHY configuration options
  *
  * @IEEE80211_CONF_RADIOTAP: add radiotap header at receive time (if supported)
- * @IEEE80211_CONF_PS: Enable 802.11 power save mode
+ * @IEEE80211_CONF_PS: Enable 802.11 power save mode (managed mode only)
+ * @IEEE80211_CONF_IDLE: The device is running, but idle; if the flag is set
+ *     the driver should be prepared to handle configuration requests but
+ *     may turn the device off as much as possible. Typically, this flag will
+ *     be set when an interface is set UP but not associated or scanning, but
+ *     it can also be unset in that case when monitor interfaces are active.
  */
 enum ieee80211_conf_flags {
        IEEE80211_CONF_RADIOTAP         = (1<<0),
        IEEE80211_CONF_PS               = (1<<1),
+       IEEE80211_CONF_IDLE             = (1<<2),
 };
 
 
 /**
  * enum ieee80211_conf_changed - denotes which configuration changed
  *
- * @IEEE80211_CONF_CHANGE_RADIO_ENABLED: the value of radio_enabled changed
- * @IEEE80211_CONF_CHANGE_BEACON_INTERVAL: the beacon interval changed
+ * @_IEEE80211_CONF_CHANGE_RADIO_ENABLED: DEPRECATED
  * @IEEE80211_CONF_CHANGE_LISTEN_INTERVAL: the listen interval changed
  * @IEEE80211_CONF_CHANGE_RADIOTAP: the radiotap flag changed
- * @IEEE80211_CONF_CHANGE_PS: the PS flag changed
- * @IEEE80211_CONF_CHANGE_DYNPS_TIMEOUT: the dynamic PS timeout changed
+ * @IEEE80211_CONF_CHANGE_PS: the PS flag or dynamic PS timeout changed
  * @IEEE80211_CONF_CHANGE_POWER: the TX power changed
  * @IEEE80211_CONF_CHANGE_CHANNEL: the channel/channel_type changed
  * @IEEE80211_CONF_CHANGE_RETRY_LIMITS: retry limits changed
+ * @IEEE80211_CONF_CHANGE_IDLE: Idle flag changed
  */
 enum ieee80211_conf_changed {
-       IEEE80211_CONF_CHANGE_RADIO_ENABLED     = BIT(0),
-       IEEE80211_CONF_CHANGE_BEACON_INTERVAL   = BIT(1),
+       _IEEE80211_CONF_CHANGE_RADIO_ENABLED    = BIT(0),
        IEEE80211_CONF_CHANGE_LISTEN_INTERVAL   = BIT(2),
        IEEE80211_CONF_CHANGE_RADIOTAP          = BIT(3),
        IEEE80211_CONF_CHANGE_PS                = BIT(4),
-       IEEE80211_CONF_CHANGE_DYNPS_TIMEOUT     = BIT(5),
-       IEEE80211_CONF_CHANGE_POWER             = BIT(6),
-       IEEE80211_CONF_CHANGE_CHANNEL           = BIT(7),
-       IEEE80211_CONF_CHANGE_RETRY_LIMITS      = BIT(8),
+       IEEE80211_CONF_CHANGE_POWER             = BIT(5),
+       IEEE80211_CONF_CHANGE_CHANNEL           = BIT(6),
+       IEEE80211_CONF_CHANGE_RETRY_LIMITS      = BIT(7),
+       IEEE80211_CONF_CHANGE_IDLE              = BIT(8),
 };
 
+static inline __deprecated enum ieee80211_conf_changed
+__IEEE80211_CONF_CHANGE_RADIO_ENABLED(void)
+{
+       return _IEEE80211_CONF_CHANGE_RADIO_ENABLED;
+}
+#define IEEE80211_CONF_CHANGE_RADIO_ENABLED \
+       __IEEE80211_CONF_CHANGE_RADIO_ENABLED()
+
 /**
  * struct ieee80211_conf - configuration of the device
  *
  * This struct indicates how the driver shall configure the hardware.
  *
+ * @flags: configuration flags defined above
+ *
  * @radio_enabled: when zero, driver is required to switch off the radio.
- * @beacon_int: beacon interval (TODO make interface config)
+ * @beacon_int: DEPRECATED, DO NOT USE
+ *
  * @listen_interval: listen interval in units of beacon interval
- * @flags: configuration flags defined above
+ * @max_sleep_period: the maximum number of beacon intervals to sleep for
+ *     before checking the beacon for a TIM bit (managed mode only); this
+ *     value will be only achievable between DTIM frames, the hardware
+ *     needs to check for the multicast traffic bit in DTIM beacons.
+ *     This variable is valid only when the CONF_PS flag is set.
+ * @dynamic_ps_timeout: The dynamic powersave timeout (in ms), see the
+ *     powersave documentation below. This variable is valid only when
+ *     the CONF_PS flag is set.
+ *
  * @power_level: requested transmit power (in dBm)
- * @dynamic_ps_timeout: dynamic powersave timeout (in ms)
+ *
  * @channel: the channel to tune to
  * @channel_type: the channel (HT) type
+ *
  * @long_frame_max_tx_count: Maximum number of transmissions for a "long" frame
  *    (a frame not RTS protected), called "dot11LongRetryLimit" in 802.11,
  *    but actually means the number of transmissions not the number of retries
@@ -572,12 +590,13 @@ enum ieee80211_conf_changed {
  *    number of transmissions not the number of retries
  */
 struct ieee80211_conf {
-       int beacon_int;
+       int __deprecated beacon_int;
        u32 flags;
        int power_level, dynamic_ps_timeout;
+       int max_sleep_period;
 
        u16 listen_interval;
-       bool radio_enabled;
+       bool __deprecated radio_enabled;
 
        u8 long_frame_max_tx_count, short_frame_max_tx_count;
 
@@ -639,37 +658,6 @@ struct ieee80211_if_init_conf {
        void *mac_addr;
 };
 
-/**
- * enum ieee80211_if_conf_change - interface config change flags
- *
- * @IEEE80211_IFCC_BSSID: The BSSID changed.
- * @IEEE80211_IFCC_BEACON: The beacon for this interface changed
- *     (currently AP and MESH only), use ieee80211_beacon_get().
- * @IEEE80211_IFCC_BEACON_ENABLED: The enable_beacon value changed.
- */
-enum ieee80211_if_conf_change {
-       IEEE80211_IFCC_BSSID            = BIT(0),
-       IEEE80211_IFCC_BEACON           = BIT(1),
-       IEEE80211_IFCC_BEACON_ENABLED   = BIT(2),
-};
-
-/**
- * struct ieee80211_if_conf - configuration of an interface
- *
- * @changed: parameters that have changed, see &enum ieee80211_if_conf_change.
- * @bssid: BSSID of the network we are associated to/creating.
- * @enable_beacon: Indicates whether beacons can be sent.
- *     This is valid only for AP/IBSS/MESH modes.
- *
- * This structure is passed to the config_interface() callback of
- * &struct ieee80211_hw.
- */
-struct ieee80211_if_conf {
-       u32 changed;
-       const u8 *bssid;
-       bool enable_beacon;
-};
-
 /**
  * enum ieee80211_key_alg - key algorithm
  * @ALG_WEP: WEP40 or WEP104
@@ -684,16 +672,6 @@ enum ieee80211_key_alg {
        ALG_AES_CMAC,
 };
 
-/**
- * enum ieee80211_key_len - key length
- * @LEN_WEP40: WEP 5-byte long key
- * @LEN_WEP104: WEP 13-byte long key
- */
-enum ieee80211_key_len {
-       LEN_WEP40 = 5,
-       LEN_WEP104 = 13,
-};
-
 /**
  * enum ieee80211_key_flags - key flags
  *
@@ -1109,11 +1087,9 @@ ieee80211_get_alt_retry_rate(const struct ieee80211_hw *hw,
  * need software support for parsing the TIM bitmap. This is also supported
  * by mac80211 by combining the %IEEE80211_HW_SUPPORTS_PS and
  * %IEEE80211_HW_PS_NULLFUNC_STACK flags. The hardware is of course still
- * required to pass up beacons. Additionally, in this case, mac80211 will
- * wake up the hardware when multicast traffic is announced in the beacon.
- *
- * FIXME: I don't think we can be fast enough in software when we want to
- *       receive multicast traffic?
+ * required to pass up beacons. The hardware is still required to handle
+ * waking up for multicast traffic; if it cannot the driver must handle that
+ * as best as it can, mac80211 is too slow.
  *
  * Dynamic powersave mode is an extension to normal powersave mode in which
  * the hardware stays awake for a user-specified period of time after sending
@@ -1134,11 +1110,53 @@ ieee80211_get_alt_retry_rate(const struct ieee80211_hw *hw,
  * way the host will only receive beacons where some relevant information
  * (for example ERP protection or WMM settings) have changed.
  *
- * Beacon filter support is informed with %IEEE80211_HW_BEACON_FILTER flag.
- * The driver needs to enable beacon filter support whenever power save is
- * enabled, that is %IEEE80211_CONF_PS is set. When power save is enabled,
- * the stack will not check for beacon miss at all and the driver needs to
- * notify about complete loss of beacons with ieee80211_beacon_loss().
+ * Beacon filter support is advertised with the %IEEE80211_HW_BEACON_FILTER
+ * hardware capability. The driver needs to enable beacon filter support
+ * whenever power save is enabled, that is %IEEE80211_CONF_PS is set. When
+ * power save is enabled, the stack will not check for beacon loss and the
+ * driver needs to notify about loss of beacons with ieee80211_beacon_loss().
+ *
+ * The time (or number of beacons missed) until the firmware notifies the
+ * driver of a beacon loss event (which in turn causes the driver to call
+ * ieee80211_beacon_loss()) should be configurable and will be controlled
+ * by mac80211 and the roaming algorithm in the future.
+ *
+ * Since there may be constantly changing information elements that nothing
+ * in the software stack cares about, we will, in the future, have mac80211
+ * tell the driver which information elements are interesting in the sense
+ * that we want to see changes in them. This will include
+ *  - a list of information element IDs
+ *  - a list of OUIs for the vendor information element
+ *
+ * Ideally, the hardware would filter out any beacons without changes in the
+ * requested elements, but if it cannot support that it may, at the expense
+ * of some efficiency, filter out only a subset. For example, if the device
+ * doesn't support checking for OUIs it should pass up all changes in all
+ * vendor information elements.
+ *
+ * Note that change, for the sake of simplification, also includes information
+ * elements appearing or disappearing from the beacon.
+ *
+ * Some hardware supports an "ignore list" instead, just make sure nothing
+ * that was requested is on the ignore list, and include commonly changing
+ * information element IDs in the ignore list, for example 11 (BSS load) and
+ * the various vendor-assigned IEs with unknown contents (128, 129, 133-136,
+ * 149, 150, 155, 156, 173, 176, 178, 179, 219); for forward compatibility
+ * it could also include some currently unused IDs.
+ *
+ *
+ * In addition to these capabilities, hardware should support notifying the
+ * host of changes in the beacon RSSI. This is relevant to implement roaming
+ * when no traffic is flowing (when traffic is flowing we see the RSSI of
+ * the received data packets). This can consist in notifying the host when
+ * the RSSI changes significantly or when it drops below or rises above
+ * configurable thresholds. In the future these thresholds will also be
+ * configured by mac80211 (which gets them from userspace) to implement
+ * them as the roaming algorithm requires.
+ *
+ * If the hardware cannot implement this, the driver should ask it to
+ * periodically pass beacon frames to the host so that software can do the
+ * signal strength threshold checking.
  */
 
 /**
@@ -1298,10 +1316,6 @@ enum ieee80211_ampdu_mlme_action {
  *     This function should never fail but returns a negative error code
  *     if it does.
  *
- * @config_interface: Handler for configuration requests related to interfaces
- *     (e.g. BSSID changes.)
- *     Returns a negative error code which will be seen in userspace.
- *
  * @bss_info_changed: Handler for configuration requests related to BSS
  *     parameters that may vary during BSS's lifespan, and may affect low
  *     level driver (e.g. assoc/disassoc status, erp parameters).
@@ -1330,11 +1344,14 @@ enum ieee80211_ampdu_mlme_action {
  *     the scan state machine in stack. The scan must honour the channel
  *     configuration done by the regulatory agent in the wiphy's
  *     registered bands. The hardware (or the driver) needs to make sure
- *     that power save is disabled. When the scan finishes,
- *     ieee80211_scan_completed() must be called; note that it also must
- *     be called when the scan cannot finish because the hardware is
- *     turned off! Anything else is a bug! Returns a negative error code
- *     which will be seen in userspace.
+ *     that power save is disabled.
+ *     The @req ie/ie_len members are rewritten by mac80211 to contain the
+ *     entire IEs after the SSID, so that drivers need not look at these
+ *     at all but just send them after the SSID -- mac80211 includes the
+ *     (extended) supported rates and HT information (where applicable).
+ *     When the scan finishes, ieee80211_scan_completed() must be called;
+ *     note that it also must be called when the scan cannot finish due to
+ *     any error unless this callback returned a negative error code.
  *
  * @sw_scan_start: Notifier function that is called just before a software scan
  *     is started. Can be NULL, if the driver doesn't need this notification.
@@ -1390,6 +1407,10 @@ enum ieee80211_ampdu_mlme_action {
  *     is the first frame we expect to perform the action on. Notice
  *     that TX/RX_STOP can pass NULL for this parameter.
  *     Returns a negative error code on failure.
+ *
+ * @rfkill_poll: Poll rfkill hardware state. If you need this, you also
+ *     need to set wiphy->rfkill_poll to %true before registration,
+ *     and need to call wiphy_rfkill_set_hw_state() in the callback.
  */
 struct ieee80211_ops {
        int (*tx)(struct ieee80211_hw *hw, struct sk_buff *skb);
@@ -1400,9 +1421,6 @@ struct ieee80211_ops {
        void (*remove_interface)(struct ieee80211_hw *hw,
                                 struct ieee80211_if_init_conf *conf);
        int (*config)(struct ieee80211_hw *hw, u32 changed);
-       int (*config_interface)(struct ieee80211_hw *hw,
-                               struct ieee80211_vif *vif,
-                               struct ieee80211_if_conf *conf);
        void (*bss_info_changed)(struct ieee80211_hw *hw,
                                 struct ieee80211_vif *vif,
                                 struct ieee80211_bss_conf *info,
@@ -1441,6 +1459,8 @@ struct ieee80211_ops {
        int (*ampdu_action)(struct ieee80211_hw *hw,
                            enum ieee80211_ampdu_mlme_action action,
                            struct ieee80211_sta *sta, u16 tid, u16 *ssn);
+
+       void (*rfkill_poll)(struct ieee80211_hw *hw);
 };
 
 /**
@@ -1572,6 +1592,20 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw);
  */
 void ieee80211_free_hw(struct ieee80211_hw *hw);
 
+/**
+ * ieee80211_restart_hw - restart hardware completely
+ *
+ * Call this function when the hardware was restarted for some reason
+ * (hardware error, ...) and the driver is unable to restore its state
+ * by itself. mac80211 assumes that at this point the driver/hardware
+ * is completely uninitialised and stopped, it starts the process by
+ * calling the ->start() operation. The driver will need to reset all
+ * internal state that it has prior to calling this function.
+ *
+ * @hw: the hardware to restart
+ */
+void ieee80211_restart_hw(struct ieee80211_hw *hw);
+
 /* trick to avoid symbol clashes with the ieee80211 subsystem */
 void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
                    struct ieee80211_rx_status *status);
@@ -1774,24 +1808,6 @@ __le16 ieee80211_generic_frame_duration(struct ieee80211_hw *hw,
 struct sk_buff *
 ieee80211_get_buffered_bc(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
 
-/**
- * ieee80211_get_hdrlen_from_skb - get header length from data
- *
- * Given an skb with a raw 802.11 header at the data pointer this function
- * returns the 802.11 header length in bytes (not including encryption
- * headers). If the data in the sk_buff is too short to contain a valid 802.11
- * header the function returns 0.
- *
- * @skb: the frame
- */
-unsigned int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb);
-
-/**
- * ieee80211_hdrlen - get header length in bytes from frame control
- * @fc: frame control field in little-endian format
- */
-unsigned int ieee80211_hdrlen(__le16 fc);
-
 /**
  * ieee80211_get_tkip_key - get a TKIP rc4 for skb
  *
diff --git a/include/net/netfilter/ipv4/nf_conntrack_icmp.h b/include/net/netfilter/ipv4/nf_conntrack_icmp.h
deleted file mode 100644 (file)
index 3dd22cf..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-#ifndef _NF_CONNTRACK_ICMP_H
-#define _NF_CONNTRACK_ICMP_H
-/* ICMP tracking. */
-#include <asm/atomic.h>
-
-struct ip_ct_icmp
-{
-       /* Optimization: when number in == number out, forget immediately. */
-       atomic_t count;
-};
-#endif /* _NF_CONNTRACK_ICMP_H */
index 86591afda29c42425d839b7695f7269485d087e7..67edd50a398ac28a24312735d6e9e5541868d914 100644 (file)
@@ -9,7 +9,6 @@
 
 #ifndef _NF_CONNTRACK_ICMPV6_H
 #define _NF_CONNTRACK_ICMPV6_H
-#include <asm/atomic.h>
 
 #ifndef ICMPV6_NI_QUERY
 #define ICMPV6_NI_QUERY 139
 #define ICMPV6_NI_REPLY 140
 #endif
 
-struct nf_ct_icmpv6
-{
-       /* Optimization: when number in == number out, forget immediately. */
-       atomic_t count;
-};
-
 #endif /* _NF_CONNTRACK_ICMPV6_H */
index 6c3f964de9e1d652841cfe9510e895db3519cec9..a632689b61b40f581e4cc1d25fe65ebcac053995 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/netfilter/nf_conntrack_dccp.h>
 #include <linux/netfilter/nf_conntrack_sctp.h>
 #include <linux/netfilter/nf_conntrack_proto_gre.h>
-#include <net/netfilter/ipv4/nf_conntrack_icmp.h>
 #include <net/netfilter/ipv6/nf_conntrack_icmpv6.h>
 
 #include <net/netfilter/nf_conntrack_tuple.h>
@@ -34,8 +33,6 @@ union nf_conntrack_proto {
        struct nf_ct_dccp dccp;
        struct ip_ct_sctp sctp;
        struct ip_ct_tcp tcp;
-       struct ip_ct_icmp icmp;
-       struct nf_ct_icmpv6 icmpv6;
        struct nf_ct_gre gre;
 };
 
@@ -96,6 +93,8 @@ struct nf_conn {
            plus 1 for any connection(s) we are `master' for */
        struct nf_conntrack ct_general;
 
+       spinlock_t lock;
+
        /* XXX should I move this to the tail ? - Y.K */
        /* These are my tuples; original and reply */
        struct nf_conntrack_tuple_hash tuplehash[IP_CT_DIR_MAX];
@@ -144,6 +143,8 @@ static inline u_int8_t nf_ct_protonum(const struct nf_conn *ct)
        return ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum;
 }
 
+#define nf_ct_tuple(ct, dir) (&(ct)->tuplehash[dir].tuple)
+
 /* get master conntrack via master expectation */
 #define master_ct(conntr) (conntr->master)
 
@@ -200,8 +201,10 @@ extern struct nf_conntrack_tuple_hash *
 __nf_conntrack_find(struct net *net, const struct nf_conntrack_tuple *tuple);
 
 extern void nf_conntrack_hash_insert(struct nf_conn *ct);
+extern void nf_ct_delete_from_lists(struct nf_conn *ct);
+extern void nf_ct_insert_dying_list(struct nf_conn *ct);
 
-extern void nf_conntrack_flush(struct net *net, u32 pid, int report);
+extern void nf_conntrack_flush_report(struct net *net, u32 pid, int report);
 
 extern bool nf_ct_get_tuplepr(const struct sk_buff *skb,
                              unsigned int nhoff, u_int16_t l3num,
index 0ff0dc69ca4a53b9b3827122e715f1a15c1fa0cc..4f20d58e2ab74a5155c89d9284eedbec6d2bd19f 100644 (file)
@@ -6,17 +6,54 @@
 #define _NF_CONNTRACK_ECACHE_H
 #include <net/netfilter/nf_conntrack.h>
 
-#include <linux/notifier.h>
-#include <linux/interrupt.h>
 #include <net/net_namespace.h>
 #include <net/netfilter/nf_conntrack_expect.h>
+#include <linux/netfilter/nf_conntrack_common.h>
+#include <linux/netfilter/nf_conntrack_tuple_common.h>
+#include <net/netfilter/nf_conntrack_extend.h>
+
+/* Connection tracking event types */
+enum ip_conntrack_events
+{
+       IPCT_NEW                = 0,    /* new conntrack */
+       IPCT_RELATED            = 1,    /* related conntrack */
+       IPCT_DESTROY            = 2,    /* destroyed conntrack */
+       IPCT_STATUS             = 3,    /* status has changed */
+       IPCT_PROTOINFO          = 4,    /* protocol information has changed */
+       IPCT_HELPER             = 5,    /* new helper has been set */
+       IPCT_MARK               = 6,    /* new mark has been set */
+       IPCT_NATSEQADJ          = 7,    /* NAT is doing sequence adjustment */
+       IPCT_SECMARK            = 8,    /* new security mark has been set */
+};
+
+enum ip_conntrack_expect_events {
+       IPEXP_NEW               = 0,    /* new expectation */
+};
 
-#ifdef CONFIG_NF_CONNTRACK_EVENTS
 struct nf_conntrack_ecache {
-       struct nf_conn *ct;
-       unsigned int events;
+       unsigned long cache;            /* bitops want long */
+       unsigned long missed;           /* missed events */
+       u32 pid;                        /* netlink pid of destroyer */
+};
+
+static inline struct nf_conntrack_ecache *
+nf_ct_ecache_find(const struct nf_conn *ct)
+{
+       return nf_ct_ext_find(ct, NF_CT_EXT_ECACHE);
+}
+
+static inline struct nf_conntrack_ecache *
+nf_ct_ecache_ext_add(struct nf_conn *ct, gfp_t gfp)
+{
+       struct net *net = nf_ct_net(ct);
+
+       if (!net->ct.sysctl_events)
+               return NULL;
+
+       return nf_ct_ext_add(ct, NF_CT_EXT_ECACHE, gfp);
 };
 
+#ifdef CONFIG_NF_CONNTRACK_EVENTS
 /* This structure is passed to event handler */
 struct nf_ct_event {
        struct nf_conn *ct;
@@ -24,47 +61,96 @@ struct nf_ct_event {
        int report;
 };
 
-extern struct atomic_notifier_head nf_conntrack_chain;
-extern int nf_conntrack_register_notifier(struct notifier_block *nb);
-extern int nf_conntrack_unregister_notifier(struct notifier_block *nb);
+struct nf_ct_event_notifier {
+       int (*fcn)(unsigned int events, struct nf_ct_event *item);
+};
+
+extern struct nf_ct_event_notifier *nf_conntrack_event_cb;
+extern int nf_conntrack_register_notifier(struct nf_ct_event_notifier *nb);
+extern void nf_conntrack_unregister_notifier(struct nf_ct_event_notifier *nb);
 
-extern void nf_ct_deliver_cached_events(const struct nf_conn *ct);
-extern void __nf_ct_event_cache_init(struct nf_conn *ct);
-extern void nf_ct_event_cache_flush(struct net *net);
+extern void nf_ct_deliver_cached_events(struct nf_conn *ct);
 
 static inline void
 nf_conntrack_event_cache(enum ip_conntrack_events event, struct nf_conn *ct)
 {
+       struct nf_conntrack_ecache *e;
+
+       if (nf_conntrack_event_cb == NULL)
+               return;
+
+       e = nf_ct_ecache_find(ct);
+       if (e == NULL)
+               return;
+
+       set_bit(event, &e->cache);
+}
+
+static inline int
+nf_conntrack_eventmask_report(unsigned int eventmask,
+                             struct nf_conn *ct,
+                             u32 pid,
+                             int report)
+{
+       int ret = 0;
        struct net *net = nf_ct_net(ct);
-       struct nf_conntrack_ecache *ecache;
-
-       local_bh_disable();
-       ecache = per_cpu_ptr(net->ct.ecache, raw_smp_processor_id());
-       if (ct != ecache->ct)
-               __nf_ct_event_cache_init(ct);
-       ecache->events |= event;
-       local_bh_enable();
+       struct nf_ct_event_notifier *notify;
+       struct nf_conntrack_ecache *e;
+
+       rcu_read_lock();
+       notify = rcu_dereference(nf_conntrack_event_cb);
+       if (notify == NULL)
+               goto out_unlock;
+
+       if (!net->ct.sysctl_events)
+               goto out_unlock;
+
+       e = nf_ct_ecache_find(ct);
+       if (e == NULL)
+               goto out_unlock;
+
+       if (nf_ct_is_confirmed(ct) && !nf_ct_is_dying(ct)) {
+               struct nf_ct_event item = {
+                       .ct     = ct,
+                       .pid    = e->pid ? e->pid : pid,
+                       .report = report
+               };
+               /* This is a resent of a destroy event? If so, skip missed */
+               unsigned long missed = e->pid ? 0 : e->missed;
+
+               ret = notify->fcn(eventmask | missed, &item);
+               if (unlikely(ret < 0 || missed)) {
+                       spin_lock_bh(&ct->lock);
+                       if (ret < 0) {
+                               /* This is a destroy event that has been
+                                * triggered by a process, we store the PID
+                                * to include it in the retransmission. */
+                               if (eventmask & (1 << IPCT_DESTROY) &&
+                                   e->pid == 0 && pid != 0)
+                                       e->pid = pid;
+                               else
+                                       e->missed |= eventmask;
+                       } else
+                               e->missed &= ~missed;
+                       spin_unlock_bh(&ct->lock);
+               }
+       }
+out_unlock:
+       rcu_read_unlock();
+       return ret;
 }
 
-static inline void
-nf_conntrack_event_report(enum ip_conntrack_events event,
-                         struct nf_conn *ct,
-                         u32 pid,
-                         int report)
+static inline int
+nf_conntrack_event_report(enum ip_conntrack_events event, struct nf_conn *ct,
+                         u32 pid, int report)
 {
-       struct nf_ct_event item = {
-               .ct     = ct,
-               .pid    = pid,
-               .report = report
-       };
-       if (nf_ct_is_confirmed(ct) && !nf_ct_is_dying(ct))
-               atomic_notifier_call_chain(&nf_conntrack_chain, event, &item);
+       return nf_conntrack_eventmask_report(1 << event, ct, pid, report);
 }
 
-static inline void
+static inline int
 nf_conntrack_event(enum ip_conntrack_events event, struct nf_conn *ct)
 {
-       nf_conntrack_event_report(event, ct, 0, 0);
+       return nf_conntrack_eventmask_report(1 << event, ct, 0, 0);
 }
 
 struct nf_exp_event {
@@ -73,9 +159,13 @@ struct nf_exp_event {
        int report;
 };
 
-extern struct atomic_notifier_head nf_ct_expect_chain;
-extern int nf_ct_expect_register_notifier(struct notifier_block *nb);
-extern int nf_ct_expect_unregister_notifier(struct notifier_block *nb);
+struct nf_exp_event_notifier {
+       int (*fcn)(unsigned int events, struct nf_exp_event *item);
+};
+
+extern struct nf_exp_event_notifier *nf_expect_event_cb;
+extern int nf_ct_expect_register_notifier(struct nf_exp_event_notifier *nb);
+extern void nf_ct_expect_unregister_notifier(struct nf_exp_event_notifier *nb);
 
 static inline void
 nf_ct_expect_event_report(enum ip_conntrack_expect_events event,
@@ -83,12 +173,27 @@ nf_ct_expect_event_report(enum ip_conntrack_expect_events event,
                          u32 pid,
                          int report)
 {
-       struct nf_exp_event item = {
-               .exp    = exp,
-               .pid    = pid,
-               .report = report
-       };
-       atomic_notifier_call_chain(&nf_ct_expect_chain, event, &item);
+       struct net *net = nf_ct_exp_net(exp);
+       struct nf_exp_event_notifier *notify;
+
+       rcu_read_lock();
+       notify = rcu_dereference(nf_expect_event_cb);
+       if (notify == NULL)
+               goto out_unlock;
+
+       if (!net->ct.sysctl_events)
+               goto out_unlock;
+
+       {
+               struct nf_exp_event item = {
+                       .exp    = exp,
+                       .pid    = pid,
+                       .report = report
+               };
+               notify->fcn(1 << event, &item);
+       }
+out_unlock:
+       rcu_read_unlock();
 }
 
 static inline void
@@ -105,12 +210,16 @@ extern void nf_conntrack_ecache_fini(struct net *net);
 
 static inline void nf_conntrack_event_cache(enum ip_conntrack_events event,
                                            struct nf_conn *ct) {}
-static inline void nf_conntrack_event(enum ip_conntrack_events event,
-                                     struct nf_conn *ct) {}
-static inline void nf_conntrack_event_report(enum ip_conntrack_events event,
-                                            struct nf_conn *ct,
-                                            u32 pid,
-                                            int report) {}
+static inline int nf_conntrack_eventmask_report(unsigned int eventmask,
+                                               struct nf_conn *ct,
+                                               u32 pid,
+                                               int report) { return 0; }
+static inline int nf_conntrack_event(enum ip_conntrack_events event,
+                                    struct nf_conn *ct) { return 0; }
+static inline int nf_conntrack_event_report(enum ip_conntrack_events event,
+                                           struct nf_conn *ct,
+                                           u32 pid,
+                                           int report) { return 0; }
 static inline void nf_ct_deliver_cached_events(const struct nf_conn *ct) {}
 static inline void nf_ct_expect_event(enum ip_conntrack_expect_events event,
                                      struct nf_conntrack_expect *exp) {}
@@ -118,7 +227,6 @@ static inline void nf_ct_expect_event_report(enum ip_conntrack_expect_events e,
                                             struct nf_conntrack_expect *exp,
                                             u32 pid,
                                             int report) {}
-static inline void nf_ct_event_cache_flush(struct net *net) {}
 
 static inline int nf_conntrack_ecache_init(struct net *net)
 {
index da8ee52613a59f202e341fb96b1d5c6c097ab37d..7f8fc5d123c550e437be2279039ea5d4f4bd6d43 100644 (file)
@@ -8,12 +8,14 @@ enum nf_ct_ext_id
        NF_CT_EXT_HELPER,
        NF_CT_EXT_NAT,
        NF_CT_EXT_ACCT,
+       NF_CT_EXT_ECACHE,
        NF_CT_EXT_NUM,
 };
 
 #define NF_CT_EXT_HELPER_TYPE struct nf_conn_help
 #define NF_CT_EXT_NAT_TYPE struct nf_conn_nat
 #define NF_CT_EXT_ACCT_TYPE struct nf_conn_counter
+#define NF_CT_EXT_ECACHE_TYPE struct nf_conntrack_ecache
 
 /* Extensions: optional stuff which isn't permanently in struct. */
 struct nf_ct_ext {
index ee2a4b369a0466ac884af3f282dec210e41c2a56..1b7068000927c564be434e32b7e24240a2d44c14 100644 (file)
@@ -50,6 +50,8 @@ extern struct nf_conn_help *nf_ct_helper_ext_add(struct nf_conn *ct, gfp_t gfp);
 
 extern int __nf_ct_try_assign_helper(struct nf_conn *ct, gfp_t flags);
 
+extern void nf_ct_helper_destroy(struct nf_conn *ct);
+
 static inline struct nf_conn_help *nfct_help(const struct nf_conn *ct)
 {
        return nf_ct_ext_find(ct, NF_CT_EXT_HELPER);
index ba32ed7bdabe75c0655e728fbdcebbffae492151..3767fb41e541fb5d5404fcb5931b561c5d30a2c2 100644 (file)
@@ -59,11 +59,11 @@ struct nf_conntrack_l4proto
                           const struct nf_conntrack_tuple *);
 
        /* Print out the private part of the conntrack. */
-       int (*print_conntrack)(struct seq_file *s, const struct nf_conn *);
+       int (*print_conntrack)(struct seq_file *s, struct nf_conn *);
 
        /* convert protoinfo to nfnetink attributes */
        int (*to_nlattr)(struct sk_buff *skb, struct nlattr *nla,
-                        const struct nf_conn *ct);
+                        struct nf_conn *ct);
        /* Calculate protoinfo nlattr size */
        int (*nlattr_size)(void);
 
index eddb50289d6d12b8cb8a234c373f8574a0cb5562..007bdb07dabb22f9aabc1e9014a55440de86769b 100644 (file)
@@ -939,6 +939,15 @@ static inline u64 nla_get_u64(const struct nlattr *nla)
        return tmp;
 }
 
+/**
+ * nla_get_be64 - return payload of __be64 attribute
+ * @nla: __be64 netlink attribute
+ */
+static inline __be64 nla_get_be64(const struct nlattr *nla)
+{
+       return *(__be64 *) nla_data(nla);
+}
+
 /**
  * nla_get_flag - return payload of flag attribute
  * @nla: flag netlink attribute
index 9dc58402bc09e4b5d1c210cf081313cfbccd968d..ba1ba0c5efd1b5047d9251acee2211043e4d0805 100644 (file)
@@ -14,16 +14,17 @@ struct netns_ct {
        struct hlist_nulls_head *hash;
        struct hlist_head       *expect_hash;
        struct hlist_nulls_head unconfirmed;
+       struct hlist_nulls_head dying;
        struct ip_conntrack_stat *stat;
-#ifdef CONFIG_NF_CONNTRACK_EVENTS
-       struct nf_conntrack_ecache *ecache;
-#endif
+       int                     sysctl_events;
+       unsigned int            sysctl_events_retry_timeout;
        int                     sysctl_acct;
        int                     sysctl_checksum;
        unsigned int            sysctl_log_invalid; /* Log invalid packets */
 #ifdef CONFIG_SYSCTL
        struct ctl_table_header *sysctl_header;
        struct ctl_table_header *acct_sysctl_header;
+       struct ctl_table_header *event_sysctl_header;
 #endif
        int                     hash_vmalloc;
        int                     expect_vmalloc;
index e37fe3129c17ddbf192de69ed3984f2ee5fbc93b..82a3191375f5c380f49ce42b13d9364822293959 100644 (file)
@@ -41,16 +41,17 @@ static inline void *qdisc_priv(struct Qdisc *q)
 typedef u64    psched_time_t;
 typedef long   psched_tdiff_t;
 
-/* Avoid doing 64 bit divide by 1000 */
-#define PSCHED_US2NS(x)                        ((s64)(x) << 10)
-#define PSCHED_NS2US(x)                        ((x) >> 10)
+/* Avoid doing 64 bit divide */
+#define PSCHED_SHIFT                   6
+#define PSCHED_TICKS2NS(x)             ((s64)(x) << PSCHED_SHIFT)
+#define PSCHED_NS2TICKS(x)             ((x) >> PSCHED_SHIFT)
 
-#define PSCHED_TICKS_PER_SEC           PSCHED_NS2US(NSEC_PER_SEC)
+#define PSCHED_TICKS_PER_SEC           PSCHED_NS2TICKS(NSEC_PER_SEC)
 #define PSCHED_PASTPERFECT             0
 
 static inline psched_time_t psched_get_time(void)
 {
-       return PSCHED_NS2US(ktime_to_ns(ktime_get()));
+       return PSCHED_NS2TICKS(ktime_to_ns(ktime_get()));
 }
 
 static inline psched_tdiff_t
diff --git a/include/net/regulatory.h b/include/net/regulatory.h
new file mode 100644 (file)
index 0000000..47995b8
--- /dev/null
@@ -0,0 +1,101 @@
+#ifndef __NET_REGULATORY_H
+#define __NET_REGULATORY_H
+/*
+ * regulatory support structures
+ *
+ * Copyright 2008-2009 Luis R. Rodriguez <lrodriguez@atheros.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.
+ */
+
+
+/**
+ * enum environment_cap - Environment parsed from country IE
+ * @ENVIRON_ANY: indicates country IE applies to both indoor and
+ *     outdoor operation.
+ * @ENVIRON_INDOOR: indicates country IE applies only to indoor operation
+ * @ENVIRON_OUTDOOR: indicates country IE applies only to outdoor operation
+ */
+enum environment_cap {
+       ENVIRON_ANY,
+       ENVIRON_INDOOR,
+       ENVIRON_OUTDOOR,
+};
+
+/**
+ * struct regulatory_request - used to keep track of regulatory requests
+ *
+ * @wiphy_idx: this is set if this request's initiator is
+ *     %REGDOM_SET_BY_COUNTRY_IE or %REGDOM_SET_BY_DRIVER. This
+ *     can be used by the wireless core to deal with conflicts
+ *     and potentially inform users of which devices specifically
+ *     cased the conflicts.
+ * @initiator: indicates who sent this request, could be any of
+ *     of those set in nl80211_reg_initiator (%NL80211_REGDOM_SET_BY_*)
+ * @alpha2: the ISO / IEC 3166 alpha2 country code of the requested
+ *     regulatory domain. We have a few special codes:
+ *     00 - World regulatory domain
+ *     99 - built by driver but a specific alpha2 cannot be determined
+ *     98 - result of an intersection between two regulatory domains
+ * @intersect: indicates whether the wireless core should intersect
+ *     the requested regulatory domain with the presently set regulatory
+ *     domain.
+ * @country_ie_checksum: checksum of the last processed and accepted
+ *     country IE
+ * @country_ie_env: lets us know if the AP is telling us we are outdoor,
+ *     indoor, or if it doesn't matter
+ * @list: used to insert into the reg_requests_list linked list
+ */
+struct regulatory_request {
+       int wiphy_idx;
+       enum nl80211_reg_initiator initiator;
+       char alpha2[2];
+       bool intersect;
+       u32 country_ie_checksum;
+       enum environment_cap country_ie_env;
+       struct list_head list;
+};
+
+struct ieee80211_freq_range {
+       u32 start_freq_khz;
+       u32 end_freq_khz;
+       u32 max_bandwidth_khz;
+};
+
+struct ieee80211_power_rule {
+       u32 max_antenna_gain;
+       u32 max_eirp;
+};
+
+struct ieee80211_reg_rule {
+       struct ieee80211_freq_range freq_range;
+       struct ieee80211_power_rule power_rule;
+       u32 flags;
+};
+
+struct ieee80211_regdomain {
+       u32 n_reg_rules;
+       char alpha2[2];
+       struct ieee80211_reg_rule reg_rules[];
+};
+
+#define MHZ_TO_KHZ(freq) ((freq) * 1000)
+#define KHZ_TO_MHZ(freq) ((freq) / 1000)
+#define DBI_TO_MBI(gain) ((gain) * 100)
+#define MBI_TO_DBI(gain) ((gain) / 100)
+#define DBM_TO_MBM(gain) ((gain) * 100)
+#define MBM_TO_DBM(gain) ((gain) / 100)
+
+#define REG_RULE(start, end, bw, gain, eirp, reg_flags) \
+{                                                      \
+       .freq_range.start_freq_khz = MHZ_TO_KHZ(start), \
+       .freq_range.end_freq_khz = MHZ_TO_KHZ(end),     \
+       .freq_range.max_bandwidth_khz = MHZ_TO_KHZ(bw), \
+       .power_rule.max_antenna_gain = DBI_TO_MBI(gain),\
+       .power_rule.max_eirp = DBM_TO_MBM(eirp),        \
+       .flags = reg_flags,                             \
+}
+
+#endif
index 4e8cae0e58415191845543b39717dc138d024194..40f6346ef4964047484e1dd42a8c03c36266d60e 100644 (file)
@@ -210,7 +210,7 @@ static inline struct inet_peer *rt_get_peer(struct rtable *rt)
 
 static inline int inet_iif(const struct sk_buff *skb)
 {
-       return skb->rtable->rt_iif;
+       return skb_rtable(skb)->rt_iif;
 }
 
 #endif /* _ROUTE_H */
index 23f08fe1d50ae29980f7b192fbcf6943ea1c73d6..edfcacf3250e5695c07f5cbeba9d7de10037d57d 100644 (file)
@@ -1939,10 +1939,8 @@ void sctp_association_free(struct sctp_association *);
 void sctp_association_put(struct sctp_association *);
 void sctp_association_hold(struct sctp_association *);
 
-struct sctp_transport *sctp_assoc_choose_init_transport(
-       struct sctp_association *);
-struct sctp_transport *sctp_assoc_choose_shutdown_transport(
-       struct sctp_association *);
+struct sctp_transport *sctp_assoc_choose_alter_transport(
+       struct sctp_association *, struct sctp_transport *);
 void sctp_assoc_update_retran_path(struct sctp_association *);
 struct sctp_transport *sctp_assoc_lookup_paddr(const struct sctp_association *,
                                          const union sctp_addr *);
index b259fc5798fb2f909fda0cc80be04d906b3879cc..1580c04f68bc20df0ba36955caf7d5f5fff5538d 100644 (file)
@@ -147,6 +147,8 @@ enum sctp_optname {
 #define SCTP_GET_LOCAL_ADDRS   SCTP_GET_LOCAL_ADDRS
        SCTP_SOCKOPT_CONNECTX, /* CONNECTX requests. */
 #define SCTP_SOCKOPT_CONNECTX  SCTP_SOCKOPT_CONNECTX
+       SCTP_SOCKOPT_CONNECTX3, /* CONNECTX requests. (new implementation) */
+#define SCTP_SOCKOPT_CONNECTX3 SCTP_SOCKOPT_CONNECTX3
 };
 
 /*
index 57c93628695fc064e688bbc33b0b45fe9a0cef7c..8c842e06bec86ad77cbe2f612d1a29d09bb3b421 100644 (file)
@@ -153,6 +153,11 @@ struct linux_xfrm_mib {
                per_cpu_ptr(mib[!in_softirq()], get_cpu())->mibs[field]--; \
                put_cpu(); \
        } while (0)
+#define SNMP_ADD_STATS(mib, field, addend)     \
+       do { \
+               per_cpu_ptr(mib[!in_softirq()], get_cpu())->mibs[field] += addend; \
+               put_cpu(); \
+       } while (0)
 #define SNMP_ADD_STATS_BH(mib, field, addend)  \
        (per_cpu_ptr(mib[0], raw_smp_processor_id())->mibs[field] += addend)
 #define SNMP_ADD_STATS_USER(mib, field, addend)        \
@@ -160,5 +165,17 @@ struct linux_xfrm_mib {
                per_cpu_ptr(mib[1], get_cpu())->mibs[field] += addend; \
                put_cpu(); \
        } while (0)
-
+#define SNMP_UPD_PO_STATS(mib, basefield, addend)      \
+       do { \
+               __typeof__(mib[0]) ptr = per_cpu_ptr(mib[!in_softirq()], get_cpu());\
+               ptr->mibs[basefield##PKTS]++; \
+               ptr->mibs[basefield##OCTETS] += addend;\
+               put_cpu(); \
+       } while (0)
+#define SNMP_UPD_PO_STATS_BH(mib, basefield, addend)   \
+       do { \
+               __typeof__(mib[0]) ptr = per_cpu_ptr(mib[!in_softirq()], raw_smp_processor_id());\
+               ptr->mibs[basefield##PKTS]++; \
+               ptr->mibs[basefield##OCTETS] += addend;\
+       } while (0)
 #endif
index 4bb1ff9fd15bcc2b1bbc24c3cbd853fcd796da5c..010e14a93c9256a0d92e35232e2292e746e8f86c 100644 (file)
@@ -1217,9 +1217,13 @@ static inline int skb_copy_to_page(struct sock *sk, char __user *from,
 
 static inline void skb_set_owner_w(struct sk_buff *skb, struct sock *sk)
 {
-       sock_hold(sk);
        skb->sk = sk;
        skb->destructor = sock_wfree;
+       /*
+        * We used to take a refcount on sk, but following operation
+        * is enough to guarantee sk_free() wont free this sock until
+        * all in-flight packets are completed
+        */
        atomic_add(skb->truesize, &sk->sk_wmem_alloc);
 }
 
index 646dbe3962eab7ae3832c9e8641549ef9e9d95f9..19f4150f4d4d166380f95079c1877af28e6d62a5 100644 (file)
@@ -266,6 +266,19 @@ static inline int tcp_too_many_orphans(struct sock *sk, int num)
                 atomic_read(&tcp_memory_allocated) > sysctl_tcp_mem[2]);
 }
 
+/* syncookies: remember time of last synqueue overflow */
+static inline void tcp_synq_overflow(struct sock *sk)
+{
+       tcp_sk(sk)->rx_opt.ts_recent_stamp = jiffies;
+}
+
+/* syncookies: no recent synqueue overflow on this listening socket? */
+static inline int tcp_synq_no_recent_overflow(const struct sock *sk)
+{
+       unsigned long last_overflow = tcp_sk(sk)->rx_opt.ts_recent_stamp;
+       return time_after(jiffies, last_overflow + TCP_TIMEOUT_INIT);
+}
+
 extern struct proto tcp_prot;
 
 #define TCP_INC_STATS(net, field)      SNMP_INC_STATS((net)->mib.tcp_statistics, field)
@@ -889,30 +902,32 @@ static inline int tcp_prequeue(struct sock *sk, struct sk_buff *skb)
 {
        struct tcp_sock *tp = tcp_sk(sk);
 
-       if (!sysctl_tcp_low_latency && tp->ucopy.task) {
-               __skb_queue_tail(&tp->ucopy.prequeue, skb);
-               tp->ucopy.memory += skb->truesize;
-               if (tp->ucopy.memory > sk->sk_rcvbuf) {
-                       struct sk_buff *skb1;
-
-                       BUG_ON(sock_owned_by_user(sk));
-
-                       while ((skb1 = __skb_dequeue(&tp->ucopy.prequeue)) != NULL) {
-                               sk_backlog_rcv(sk, skb1);
-                               NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPPREQUEUEDROPPED);
-                       }
-
-                       tp->ucopy.memory = 0;
-               } else if (skb_queue_len(&tp->ucopy.prequeue) == 1) {
-                       wake_up_interruptible(sk->sk_sleep);
-                       if (!inet_csk_ack_scheduled(sk))
-                               inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK,
-                                                         (3 * tcp_rto_min(sk)) / 4,
-                                                         TCP_RTO_MAX);
+       if (sysctl_tcp_low_latency || !tp->ucopy.task)
+               return 0;
+
+       __skb_queue_tail(&tp->ucopy.prequeue, skb);
+       tp->ucopy.memory += skb->truesize;
+       if (tp->ucopy.memory > sk->sk_rcvbuf) {
+               struct sk_buff *skb1;
+
+               BUG_ON(sock_owned_by_user(sk));
+
+               while ((skb1 = __skb_dequeue(&tp->ucopy.prequeue)) != NULL) {
+                       sk_backlog_rcv(sk, skb1);
+                       NET_INC_STATS_BH(sock_net(sk),
+                                        LINUX_MIB_TCPPREQUEUEDROPPED);
                }
-               return 1;
+
+               tp->ucopy.memory = 0;
+       } else if (skb_queue_len(&tp->ucopy.prequeue) == 1) {
+               wake_up_interruptible_poll(sk->sk_sleep,
+                                          POLLIN | POLLRDNORM | POLLRDBAND);
+               if (!inet_csk_ack_scheduled(sk))
+                       inet_csk_reset_xmit_timer(sk, ICSK_TIME_DACK,
+                                                 (3 * tcp_rto_min(sk)) / 4,
+                                                 TCP_RTO_MAX);
        }
-       return 0;
+       return 1;
 }
 
 
index 6b3824edb39e027918b520b0ee031c9d442a44a0..2af7bf839f2309b52230da79ffa4ea40129abd74 100644 (file)
 struct net_device;
 struct genl_info;
 struct wimax_dev;
-struct input_dev;
 
 /**
  * struct wimax_dev - Generic WiMAX device
@@ -293,8 +292,8 @@ struct input_dev;
  *     See wimax_reset()'s documentation.
  *
  * @name: [fill] A way to identify this device. We need to register a
- *     name with many subsystems (input for RFKILL, workqueue
- *     creation, etc). We can't use the network device name as that
+ *     name with many subsystems (rfkill, workqueue creation, etc).
+ *     We can't use the network device name as that
  *     might change and in some instances we don't know it yet (until
  *     we don't call register_netdev()). So we generate an unique one
  *     using the driver name and device bus id, place it here and use
@@ -316,9 +315,6 @@ struct input_dev;
  *
  * @rfkill: [private] integration into the RF-Kill infrastructure.
  *
- * @rfkill_input: [private] virtual input device to process the
- *     hardware RF Kill switches.
- *
  * @rf_sw: [private] State of the software radio switch (OFF/ON)
  *
  * @rf_hw: [private] State of the hardware radio switch (OFF/ON)
diff --git a/include/net/wireless.h b/include/net/wireless.h
deleted file mode 100644 (file)
index 64a7620..0000000
+++ /dev/null
@@ -1,472 +0,0 @@
-#ifndef __NET_WIRELESS_H
-#define __NET_WIRELESS_H
-
-/*
- * 802.11 device management
- *
- * Copyright 2007      Johannes Berg <johannes@sipsolutions.net>
- */
-
-#include <linux/netdevice.h>
-#include <linux/debugfs.h>
-#include <linux/list.h>
-#include <linux/ieee80211.h>
-#include <net/cfg80211.h>
-
-/**
- * enum ieee80211_band - supported frequency bands
- *
- * The bands are assigned this way because the supported
- * bitrates differ in these bands.
- *
- * @IEEE80211_BAND_2GHZ: 2.4GHz ISM band
- * @IEEE80211_BAND_5GHZ: around 5GHz band (4.9-5.7)
- */
-enum ieee80211_band {
-       IEEE80211_BAND_2GHZ,
-       IEEE80211_BAND_5GHZ,
-
-       /* keep last */
-       IEEE80211_NUM_BANDS
-};
-
-/**
- * enum ieee80211_channel_flags - channel flags
- *
- * Channel flags set by the regulatory control code.
- *
- * @IEEE80211_CHAN_DISABLED: This channel is disabled.
- * @IEEE80211_CHAN_PASSIVE_SCAN: Only passive scanning is permitted
- *     on this channel.
- * @IEEE80211_CHAN_NO_IBSS: IBSS is not allowed on this channel.
- * @IEEE80211_CHAN_RADAR: Radar detection is required on this channel.
- * @IEEE80211_CHAN_NO_FAT_ABOVE: extension channel above this channel
- *     is not permitted.
- * @IEEE80211_CHAN_NO_FAT_BELOW: extension channel below this channel
- *     is not permitted.
- */
-enum ieee80211_channel_flags {
-       IEEE80211_CHAN_DISABLED         = 1<<0,
-       IEEE80211_CHAN_PASSIVE_SCAN     = 1<<1,
-       IEEE80211_CHAN_NO_IBSS          = 1<<2,
-       IEEE80211_CHAN_RADAR            = 1<<3,
-       IEEE80211_CHAN_NO_FAT_ABOVE     = 1<<4,
-       IEEE80211_CHAN_NO_FAT_BELOW     = 1<<5,
-};
-
-/**
- * struct ieee80211_channel - channel definition
- *
- * This structure describes a single channel for use
- * with cfg80211.
- *
- * @center_freq: center frequency in MHz
- * @max_bandwidth: maximum allowed bandwidth for this channel, in MHz
- * @hw_value: hardware-specific value for the channel
- * @flags: channel flags from &enum ieee80211_channel_flags.
- * @orig_flags: channel flags at registration time, used by regulatory
- *     code to support devices with additional restrictions
- * @band: band this channel belongs to.
- * @max_antenna_gain: maximum antenna gain in dBi
- * @max_power: maximum transmission power (in dBm)
- * @beacon_found: helper to regulatory code to indicate when a beacon
- *     has been found on this channel. Use regulatory_hint_found_beacon()
- *     to enable this, this is is useful only on 5 GHz band.
- * @orig_mag: internal use
- * @orig_mpwr: internal use
- */
-struct ieee80211_channel {
-       enum ieee80211_band band;
-       u16 center_freq;
-       u8 max_bandwidth;
-       u16 hw_value;
-       u32 flags;
-       int max_antenna_gain;
-       int max_power;
-       bool beacon_found;
-       u32 orig_flags;
-       int orig_mag, orig_mpwr;
-};
-
-/**
- * enum ieee80211_rate_flags - rate flags
- *
- * Hardware/specification flags for rates. These are structured
- * in a way that allows using the same bitrate structure for
- * different bands/PHY modes.
- *
- * @IEEE80211_RATE_SHORT_PREAMBLE: Hardware can send with short
- *     preamble on this bitrate; only relevant in 2.4GHz band and
- *     with CCK rates.
- * @IEEE80211_RATE_MANDATORY_A: This bitrate is a mandatory rate
- *     when used with 802.11a (on the 5 GHz band); filled by the
- *     core code when registering the wiphy.
- * @IEEE80211_RATE_MANDATORY_B: This bitrate is a mandatory rate
- *     when used with 802.11b (on the 2.4 GHz band); filled by the
- *     core code when registering the wiphy.
- * @IEEE80211_RATE_MANDATORY_G: This bitrate is a mandatory rate
- *     when used with 802.11g (on the 2.4 GHz band); filled by the
- *     core code when registering the wiphy.
- * @IEEE80211_RATE_ERP_G: This is an ERP rate in 802.11g mode.
- */
-enum ieee80211_rate_flags {
-       IEEE80211_RATE_SHORT_PREAMBLE   = 1<<0,
-       IEEE80211_RATE_MANDATORY_A      = 1<<1,
-       IEEE80211_RATE_MANDATORY_B      = 1<<2,
-       IEEE80211_RATE_MANDATORY_G      = 1<<3,
-       IEEE80211_RATE_ERP_G            = 1<<4,
-};
-
-/**
- * struct ieee80211_rate - bitrate definition
- *
- * This structure describes a bitrate that an 802.11 PHY can
- * operate with. The two values @hw_value and @hw_value_short
- * are only for driver use when pointers to this structure are
- * passed around.
- *
- * @flags: rate-specific flags
- * @bitrate: bitrate in units of 100 Kbps
- * @hw_value: driver/hardware value for this rate
- * @hw_value_short: driver/hardware value for this rate when
- *     short preamble is used
- */
-struct ieee80211_rate {
-       u32 flags;
-       u16 bitrate;
-       u16 hw_value, hw_value_short;
-};
-
-/**
- * struct ieee80211_sta_ht_cap - STA's HT capabilities
- *
- * This structure describes most essential parameters needed
- * to describe 802.11n HT capabilities for an STA.
- *
- * @ht_supported: is HT supported by the STA
- * @cap: HT capabilities map as described in 802.11n spec
- * @ampdu_factor: Maximum A-MPDU length factor
- * @ampdu_density: Minimum A-MPDU spacing
- * @mcs: Supported MCS rates
- */
-struct ieee80211_sta_ht_cap {
-       u16 cap; /* use IEEE80211_HT_CAP_ */
-       bool ht_supported;
-       u8 ampdu_factor;
-       u8 ampdu_density;
-       struct ieee80211_mcs_info mcs;
-};
-
-/**
- * struct ieee80211_supported_band - frequency band definition
- *
- * This structure describes a frequency band a wiphy
- * is able to operate in.
- *
- * @channels: Array of channels the hardware can operate in
- *     in this band.
- * @band: the band this structure represents
- * @n_channels: Number of channels in @channels
- * @bitrates: Array of bitrates the hardware can operate with
- *     in this band. Must be sorted to give a valid "supported
- *     rates" IE, i.e. CCK rates first, then OFDM.
- * @n_bitrates: Number of bitrates in @bitrates
- */
-struct ieee80211_supported_band {
-       struct ieee80211_channel *channels;
-       struct ieee80211_rate *bitrates;
-       enum ieee80211_band band;
-       int n_channels;
-       int n_bitrates;
-       struct ieee80211_sta_ht_cap ht_cap;
-};
-
-/**
- * struct wiphy - wireless hardware description
- * @idx: the wiphy index assigned to this item
- * @class_dev: the class device representing /sys/class/ieee80211/<wiphy-name>
- * @custom_regulatory: tells us the driver for this device
- *     has its own custom regulatory domain and cannot identify the
- *     ISO / IEC 3166 alpha2 it belongs to. When this is enabled
- *     we will disregard the first regulatory hint (when the
- *     initiator is %REGDOM_SET_BY_CORE).
- * @strict_regulatory: tells us the driver for this device will ignore
- *     regulatory domain settings until it gets its own regulatory domain
- *     via its regulatory_hint(). After its gets its own regulatory domain
- *     it will only allow further regulatory domain settings to further
- *     enhance compliance. For example if channel 13 and 14 are disabled
- *     by this regulatory domain no user regulatory domain can enable these
- *     channels at a later time. This can be used for devices which do not
- *     have calibration information gauranteed for frequencies or settings
- *     outside of its regulatory domain.
- * @reg_notifier: the driver's regulatory notification callback
- * @regd: the driver's regulatory domain, if one was requested via
- *     the regulatory_hint() API. This can be used by the driver
- *     on the reg_notifier() if it chooses to ignore future
- *     regulatory domain changes caused by other drivers.
- * @signal_type: signal type reported in &struct cfg80211_bss.
- */
-struct wiphy {
-       /* assign these fields before you register the wiphy */
-
-       /* permanent MAC address */
-       u8 perm_addr[ETH_ALEN];
-
-       /* Supported interface modes, OR together BIT(NL80211_IFTYPE_...) */
-       u16 interface_modes;
-
-       bool custom_regulatory;
-       bool strict_regulatory;
-
-       enum cfg80211_signal_type signal_type;
-
-       int bss_priv_size;
-       u8 max_scan_ssids;
-
-       /* If multiple wiphys are registered and you're handed e.g.
-        * a regular netdev with assigned ieee80211_ptr, you won't
-        * know whether it points to a wiphy your driver has registered
-        * or not. Assign this to something global to your driver to
-        * help determine whether you own this wiphy or not. */
-       void *privid;
-
-       struct ieee80211_supported_band *bands[IEEE80211_NUM_BANDS];
-
-       /* Lets us get back the wiphy on the callback */
-       int (*reg_notifier)(struct wiphy *wiphy,
-                           struct regulatory_request *request);
-
-       /* fields below are read-only, assigned by cfg80211 */
-
-       const struct ieee80211_regdomain *regd;
-
-       /* the item in /sys/class/ieee80211/ points to this,
-        * you need use set_wiphy_dev() (see below) */
-       struct device dev;
-
-       /* dir in debugfs: ieee80211/<wiphyname> */
-       struct dentry *debugfsdir;
-
-       char priv[0] __attribute__((__aligned__(NETDEV_ALIGN)));
-};
-
-/** struct wireless_dev - wireless per-netdev state
- *
- * This structure must be allocated by the driver/stack
- * that uses the ieee80211_ptr field in struct net_device
- * (this is intentional so it can be allocated along with
- * the netdev.)
- *
- * @wiphy: pointer to hardware description
- * @iftype: interface type
- */
-struct wireless_dev {
-       struct wiphy *wiphy;
-       enum nl80211_iftype iftype;
-
-       /* private to the generic wireless code */
-       struct list_head list;
-       struct net_device *netdev;
-};
-
-/**
- * wiphy_priv - return priv from wiphy
- */
-static inline void *wiphy_priv(struct wiphy *wiphy)
-{
-       BUG_ON(!wiphy);
-       return &wiphy->priv;
-}
-
-/**
- * set_wiphy_dev - set device pointer for wiphy
- */
-static inline void set_wiphy_dev(struct wiphy *wiphy, struct device *dev)
-{
-       wiphy->dev.parent = dev;
-}
-
-/**
- * wiphy_dev - get wiphy dev pointer
- */
-static inline struct device *wiphy_dev(struct wiphy *wiphy)
-{
-       return wiphy->dev.parent;
-}
-
-/**
- * wiphy_name - get wiphy name
- */
-static inline const char *wiphy_name(struct wiphy *wiphy)
-{
-       return dev_name(&wiphy->dev);
-}
-
-/**
- * wdev_priv - return wiphy priv from wireless_dev
- */
-static inline void *wdev_priv(struct wireless_dev *wdev)
-{
-       BUG_ON(!wdev);
-       return wiphy_priv(wdev->wiphy);
-}
-
-/**
- * wiphy_new - create a new wiphy for use with cfg80211
- *
- * create a new wiphy and associate the given operations with it.
- * @sizeof_priv bytes are allocated for private use.
- *
- * the returned pointer must be assigned to each netdev's
- * ieee80211_ptr for proper operation.
- */
-struct wiphy *wiphy_new(struct cfg80211_ops *ops, int sizeof_priv);
-
-/**
- * wiphy_register - register a wiphy with cfg80211
- *
- * register the given wiphy
- *
- * Returns a non-negative wiphy index or a negative error code.
- */
-extern int wiphy_register(struct wiphy *wiphy);
-
-/**
- * wiphy_unregister - deregister a wiphy from cfg80211
- *
- * unregister a device with the given priv pointer.
- * After this call, no more requests can be made with this priv
- * pointer, but the call may sleep to wait for an outstanding
- * request that is being handled.
- */
-extern void wiphy_unregister(struct wiphy *wiphy);
-
-/**
- * wiphy_free - free wiphy
- */
-extern void wiphy_free(struct wiphy *wiphy);
-
-/**
- * ieee80211_channel_to_frequency - convert channel number to frequency
- */
-extern int ieee80211_channel_to_frequency(int chan);
-
-/**
- * ieee80211_frequency_to_channel - convert frequency to channel number
- */
-extern int ieee80211_frequency_to_channel(int freq);
-
-/*
- * Name indirection necessary because the ieee80211 code also has
- * a function named "ieee80211_get_channel", so if you include
- * cfg80211's header file you get cfg80211's version, if you try
- * to include both header files you'll (rightfully!) get a symbol
- * clash.
- */
-extern struct ieee80211_channel *__ieee80211_get_channel(struct wiphy *wiphy,
-                                                        int freq);
-/**
- * ieee80211_get_channel - get channel struct from wiphy for specified frequency
- */
-static inline struct ieee80211_channel *
-ieee80211_get_channel(struct wiphy *wiphy, int freq)
-{
-       return __ieee80211_get_channel(wiphy, freq);
-}
-
-/**
- * ieee80211_get_response_rate - get basic rate for a given rate
- *
- * @sband: the band to look for rates in
- * @basic_rates: bitmap of basic rates
- * @bitrate: the bitrate for which to find the basic rate
- *
- * This function returns the basic rate corresponding to a given
- * bitrate, that is the next lower bitrate contained in the basic
- * rate map, which is, for this function, given as a bitmap of
- * indices of rates in the band's bitrate table.
- */
-struct ieee80211_rate *
-ieee80211_get_response_rate(struct ieee80211_supported_band *sband,
-                           u32 basic_rates, int bitrate);
-
-/**
- * regulatory_hint - driver hint to the wireless core a regulatory domain
- * @wiphy: the wireless device giving the hint (used only for reporting
- *     conflicts)
- * @alpha2: the ISO/IEC 3166 alpha2 the driver claims its regulatory domain
- *     should be in. If @rd is set this should be NULL. Note that if you
- *     set this to NULL you should still set rd->alpha2 to some accepted
- *     alpha2.
- *
- * Wireless drivers can use this function to hint to the wireless core
- * what it believes should be the current regulatory domain by
- * giving it an ISO/IEC 3166 alpha2 country code it knows its regulatory
- * domain should be in or by providing a completely build regulatory domain.
- * If the driver provides an ISO/IEC 3166 alpha2 userspace will be queried
- * for a regulatory domain structure for the respective country.
- *
- * The wiphy must have been registered to cfg80211 prior to this call.
- * For cfg80211 drivers this means you must first use wiphy_register(),
- * for mac80211 drivers you must first use ieee80211_register_hw().
- *
- * Drivers should check the return value, its possible you can get
- * an -ENOMEM.
- */
-extern int regulatory_hint(struct wiphy *wiphy, const char *alpha2);
-
-/**
- * regulatory_hint_11d - hints a country IE as a regulatory domain
- * @wiphy: the wireless device giving the hint (used only for reporting
- *     conflicts)
- * @country_ie: pointer to the country IE
- * @country_ie_len: length of the country IE
- *
- * We will intersect the rd with the what CRDA tells us should apply
- * for the alpha2 this country IE belongs to, this prevents APs from
- * sending us incorrect or outdated information against a country.
- */
-extern void regulatory_hint_11d(struct wiphy *wiphy,
-                               u8 *country_ie,
-                               u8 country_ie_len);
-/**
- * wiphy_apply_custom_regulatory - apply a custom driver regulatory domain
- * @wiphy: the wireless device we want to process the regulatory domain on
- * @regd: the custom regulatory domain to use for this wiphy
- *
- * Drivers can sometimes have custom regulatory domains which do not apply
- * to a specific country. Drivers can use this to apply such custom regulatory
- * domains. This routine must be called prior to wiphy registration. The
- * custom regulatory domain will be trusted completely and as such previous
- * default channel settings will be disregarded. If no rule is found for a
- * channel on the regulatory domain the channel will be disabled.
- */
-extern void wiphy_apply_custom_regulatory(
-       struct wiphy *wiphy,
-       const struct ieee80211_regdomain *regd);
-
-/**
- * freq_reg_info - get regulatory information for the given frequency
- * @wiphy: the wiphy for which we want to process this rule for
- * @center_freq: Frequency in KHz for which we want regulatory information for
- * @bandwidth: the bandwidth requirement you have in KHz, if you do not have one
- *     you can set this to 0. If this frequency is allowed we then set
- *     this value to the maximum allowed bandwidth.
- * @reg_rule: the regulatory rule which we have for this frequency
- *
- * Use this function to get the regulatory rule for a specific frequency on
- * a given wireless device. If the device has a specific regulatory domain
- * it wants to follow we respect that unless a country IE has been received
- * and processed already.
- *
- * Returns 0 if it was able to find a valid regulatory rule which does
- * apply to the given center_freq otherwise it returns non-zero. It will
- * also return -ERANGE if we determine the given center_freq does not even have
- * a regulatory rule for a frequency range in the center_freq's band. See
- * freq_in_rule_band() for our current definition of a band -- this is purely
- * subjective and right now its 802.11 specific.
- */
-extern int freq_reg_info(struct wiphy *wiphy, u32 center_freq, u32 *bandwidth,
-                        const struct ieee80211_reg_rule **reg_rule);
-
-#endif /* __NET_WIRELESS_H */
index 2e9f5c0018ae34d25320141366594ce3f22d558f..736bca4508862c668675fff1f03e9d462cb08674 100644 (file)
@@ -994,7 +994,7 @@ static inline int __xfrm_policy_check2(struct sock *sk, int dir,
                return __xfrm_policy_check(sk, ndir, skb, family);
 
        return  (!net->xfrm.policy_count[dir] && !skb->sp) ||
-               (skb->dst->flags & DST_NOPOLICY) ||
+               (skb_dst(skb)->flags & DST_NOPOLICY) ||
                __xfrm_policy_check(sk, ndir, skb, family);
 }
 
@@ -1048,7 +1048,7 @@ static inline int xfrm_route_forward(struct sk_buff *skb, unsigned short family)
        struct net *net = dev_net(skb->dev);
 
        return  !net->xfrm.policy_count[XFRM_POLICY_OUT] ||
-               (skb->dst->flags & DST_NOXFRM) ||
+               (skb_dst(skb)->flags & DST_NOXFRM) ||
                __xfrm_route_forward(skb, family);
 }
 
index 666cc131732ee3cfc7715a6568dabcd57a1e42e2..b2410605b740ed99633992f0d6b2294260c7707b 100644 (file)
@@ -73,6 +73,7 @@ enum fip_state {
  * @link:      current link status for libfc.
  * @last_link: last link state reported to libfc.
  * @map_dest:  use the FC_MAP mode for destination MAC addresses.
+ * @spma:      supports SPMA server-provided MACs mode
  * @dest_addr: MAC address of the selected FC forwarder.
  * @ctl_src_addr: the native MAC address of our local port.
  * @data_src_addr: the assigned MAC address for the local port after FLOGI.
@@ -104,6 +105,7 @@ struct fcoe_ctlr {
        u8 link;
        u8 last_link;
        u8 map_dest;
+       u8 spma;
        u8 dest_addr[ETH_ALEN];
        u8 ctl_src_addr[ETH_ALEN];
        u8 data_src_addr[ETH_ALEN];
diff --git a/include/trace/events/napi.h b/include/trace/events/napi.h
new file mode 100644 (file)
index 0000000..a8989c4
--- /dev/null
@@ -0,0 +1,11 @@
+#ifndef _TRACE_NAPI_H_
+#define _TRACE_NAPI_H_
+
+#include <linux/netdevice.h>
+#include <linux/tracepoint.h>
+
+DECLARE_TRACE(napi_poll,
+       TP_PROTO(struct napi_struct *napi),
+       TP_ARGS(napi));
+
+#endif
index cb8a15c1958318c52c116d08e33003ad2ea0cc98..b675a67c9ac39ebb058068e7f269c236d6973864 100644 (file)
@@ -43,6 +43,8 @@
 #include <linux/seq_file.h>
 #include <linux/err.h>
 #include <linux/debugobjects.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
 
 #include <asm/uaccess.h>
 
@@ -193,12 +195,24 @@ struct hrtimer_clock_base *lock_hrtimer_base(const struct hrtimer *timer,
  * Switch the timer base to the current CPU when possible.
  */
 static inline struct hrtimer_clock_base *
-switch_hrtimer_base(struct hrtimer *timer, struct hrtimer_clock_base *base)
+switch_hrtimer_base(struct hrtimer *timer, struct hrtimer_clock_base *base,
+                   int pinned)
 {
        struct hrtimer_clock_base *new_base;
        struct hrtimer_cpu_base *new_cpu_base;
+       int cpu, preferred_cpu = -1;
+
+       cpu = smp_processor_id();
+#if defined(CONFIG_NO_HZ) && defined(CONFIG_SMP)
+       if (!pinned && get_sysctl_timer_migration() && idle_cpu(cpu)) {
+               preferred_cpu = get_nohz_load_balancer();
+               if (preferred_cpu >= 0)
+                       cpu = preferred_cpu;
+       }
+#endif
 
-       new_cpu_base = &__get_cpu_var(hrtimer_bases);
+again:
+       new_cpu_base = &per_cpu(hrtimer_bases, cpu);
        new_base = &new_cpu_base->clock_base[base->index];
 
        if (base != new_base) {
@@ -218,6 +232,40 @@ switch_hrtimer_base(struct hrtimer *timer, struct hrtimer_clock_base *base)
                timer->base = NULL;
                spin_unlock(&base->cpu_base->lock);
                spin_lock(&new_base->cpu_base->lock);
+
+               /* Optimized away for NOHZ=n SMP=n */
+               if (cpu == preferred_cpu) {
+                       /* Calculate clock monotonic expiry time */
+#ifdef CONFIG_HIGH_RES_TIMERS
+                       ktime_t expires = ktime_sub(hrtimer_get_expires(timer),
+                                                       new_base->offset);
+#else
+                       ktime_t expires = hrtimer_get_expires(timer);
+#endif
+
+                       /*
+                        * Get the next event on target cpu from the
+                        * clock events layer.
+                        * This covers the highres=off nohz=on case as well.
+                        */
+                       ktime_t next = clockevents_get_next_event(cpu);
+
+                       ktime_t delta = ktime_sub(expires, next);
+
+                       /*
+                        * We do not migrate the timer when it is expiring
+                        * before the next event on the target cpu because
+                        * we cannot reprogram the target cpu hardware and
+                        * we would cause it to fire late.
+                        */
+                       if (delta.tv64 < 0) {
+                               cpu = smp_processor_id();
+                               spin_unlock(&new_base->cpu_base->lock);
+                               spin_lock(&base->cpu_base->lock);
+                               timer->base = base;
+                               goto again;
+                       }
+               }
                timer->base = new_base;
        }
        return new_base;
@@ -235,7 +283,7 @@ lock_hrtimer_base(const struct hrtimer *timer, unsigned long *flags)
        return base;
 }
 
-# define switch_hrtimer_base(t, b)     (b)
+# define switch_hrtimer_base(t, b, p)  (b)
 
 #endif /* !CONFIG_SMP */
 
@@ -907,9 +955,9 @@ int __hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim,
        ret = remove_hrtimer(timer, base);
 
        /* Switch the timer base, if necessary: */
-       new_base = switch_hrtimer_base(timer, base);
+       new_base = switch_hrtimer_base(timer, base, mode & HRTIMER_MODE_PINNED);
 
-       if (mode == HRTIMER_MODE_REL) {
+       if (mode & HRTIMER_MODE_REL) {
                tim = ktime_add_safe(tim, new_base->get_time());
                /*
                 * CONFIG_TIME_LOW_RES is a temporary way for architectures
index e4ab36ce767222becc860650e0892399ab58b96d..215aaab09e91e1e76839f403dc2e4474a512ef40 100644 (file)
@@ -2899,7 +2899,7 @@ void print_modules(void)
        struct module *mod;
        char buf[8];
 
-       printk("Modules linked in:");
+       printk(KERN_DEFAULT "Modules linked in:");
        /* Most callers should already have preempt disabled, but make sure */
        preempt_disable();
        list_for_each_entry_rcu(mod, &modules, list)
index 5052b5497c67995f57c6b548b0b52c1989f4027b..b4d97b54c1ecfa729eaa4b07dc2f721c25bca3ca 100644 (file)
@@ -687,20 +687,35 @@ asmlinkage int vprintk(const char *fmt, va_list args)
                                  sizeof(printk_buf) - printed_len, fmt, args);
 
 
+       p = printk_buf;
+
+       /* Do we have a loglevel in the string? */
+       if (p[0] == '<') {
+               unsigned char c = p[1];
+               if (c && p[2] == '>') {
+                       switch (c) {
+                       case '0' ... '7': /* loglevel */
+                               current_log_level = c - '0';
+                       /* Fallthrough - make sure we're on a new line */
+                       case 'd': /* KERN_DEFAULT */
+                               if (!new_text_line) {
+                                       emit_log_char('\n');
+                                       new_text_line = 1;
+                               }
+                       /* Fallthrough - skip the loglevel */
+                       case 'c': /* KERN_CONT */
+                               p += 3;
+                               break;
+                       }
+               }
+       }
+
        /*
         * Copy the output into log_buf.  If the caller didn't provide
         * appropriate log level tags, we insert them here
         */
-       for (p = printk_buf; *p; p++) {
+       for ( ; *p; p++) {
                if (new_text_line) {
-                       /* If a token, set current_log_level and skip over */
-                       if (p[0] == '<' && p[1] >= '0' && p[1] <= '7' &&
-                           p[2] == '>') {
-                               current_log_level = p[1] - '0';
-                               p += 3;
-                               printed_len -= 3;
-                       }
-
                        /* Always output the token */
                        emit_log_char('<');
                        emit_log_char(current_log_level + '0');
index 8ec9d13140be832cd88d349248c1cd155fd8da61..8fb88a906aaa21983bd5f61d913971788a4b9444 100644 (file)
@@ -240,7 +240,7 @@ static void start_rt_bandwidth(struct rt_bandwidth *rt_b)
                hard = hrtimer_get_expires(&rt_b->rt_period_timer);
                delta = ktime_to_ns(ktime_sub(hard, soft));
                __hrtimer_start_range_ns(&rt_b->rt_period_timer, soft, delta,
-                               HRTIMER_MODE_ABS, 0);
+                               HRTIMER_MODE_ABS_PINNED, 0);
        }
        spin_unlock(&rt_b->rt_runtime_lock);
 }
@@ -1155,7 +1155,7 @@ static __init void init_hrtick(void)
 static void hrtick_start(struct rq *rq, u64 delay)
 {
        __hrtimer_start_range_ns(&rq->hrtick_timer, ns_to_ktime(delay), 0,
-                       HRTIMER_MODE_REL, 0);
+                       HRTIMER_MODE_REL_PINNED, 0);
 }
 
 static inline void init_hrtick(void)
@@ -4397,6 +4397,11 @@ static struct {
        .load_balancer = ATOMIC_INIT(-1),
 };
 
+int get_nohz_load_balancer(void)
+{
+       return atomic_read(&nohz.load_balancer);
+}
+
 #if defined(CONFIG_SCHED_MC) || defined(CONFIG_SCHED_SMT)
 /**
  * lowest_flag_domain - Return lowest sched_domain containing flag.
@@ -9029,6 +9034,8 @@ void __init sched_init_smp(void)
 }
 #endif /* CONFIG_SMP */
 
+const_debug unsigned int sysctl_timer_migration = 1;
+
 int in_sched_functions(unsigned long addr)
 {
        return in_lock_functions(addr) ||
index ce664f98e3fb67d7741182b9bce3fd29f4b8b88f..0e51a35a44869425aa3f4e7cf9fca498787fd0fb 100644 (file)
@@ -328,6 +328,14 @@ static struct ctl_table kern_table[] = {
                .mode           = 0644,
                .proc_handler   = &proc_dointvec,
        },
+       {
+               .ctl_name       = CTL_UNNUMBERED,
+               .procname       = "timer_migration",
+               .data           = &sysctl_timer_migration,
+               .maxlen         = sizeof(unsigned int),
+               .mode           = 0644,
+               .proc_handler   = &proc_dointvec,
+       },
 #endif
        {
                .ctl_name       = CTL_UNNUMBERED,
index d13be216a7905d1a538286322c242726a1af3aba..1ad6dd46111920d10c5d83f2f90c1aeeb81ca66d 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/notifier.h>
 #include <linux/smp.h>
 #include <linux/sysdev.h>
+#include <linux/tick.h>
 
 /* The registered clock event devices */
 static LIST_HEAD(clockevent_devices);
@@ -54,6 +55,7 @@ unsigned long clockevent_delta2ns(unsigned long latch,
 
        return (unsigned long) clc;
 }
+EXPORT_SYMBOL_GPL(clockevent_delta2ns);
 
 /**
  * clockevents_set_mode - set the operating mode of a clock event device
@@ -187,6 +189,7 @@ void clockevents_register_device(struct clock_event_device *dev)
 
        spin_unlock(&clockevents_lock);
 }
+EXPORT_SYMBOL_GPL(clockevents_register_device);
 
 /*
  * Noop handler when we shut down an event device
@@ -251,4 +254,15 @@ void clockevents_notify(unsigned long reason, void *arg)
        spin_unlock(&clockevents_lock);
 }
 EXPORT_SYMBOL_GPL(clockevents_notify);
+
+ktime_t clockevents_get_next_event(int cpu)
+{
+       struct tick_device *td;
+       struct clock_event_device *dev;
+
+       td = &per_cpu(tick_cpu_device, cpu);
+       dev = td->evtdev;
+
+       return dev->next_event;
+}
 #endif
index 80189f6f1c5a1f7a326c9490e18f571fc8f49ea7..592bf584d1d2b5fa86a7fb605e4f5cf2901eda11 100644 (file)
@@ -509,6 +509,18 @@ static ssize_t sysfs_override_clocksource(struct sys_device *dev,
                }
        }
 
+       /*
+        * Check to make sure we don't switch to a non-highres capable
+        * clocksource if the tick code is in oneshot mode (highres or nohz)
+        */
+       if (tick_oneshot_mode_active() &&
+           !(ovr->flags & CLOCK_SOURCE_VALID_FOR_HRES)) {
+               printk(KERN_WARNING "%s clocksource is not HRT compatible. "
+                       "Cannot switch while in HRT/NOHZ mode\n", ovr->name);
+               ovr = NULL;
+               override_name[0] = 0;
+       }
+
        /* Reselect, when the override name has changed */
        if (ovr != clocksource_override) {
                clocksource_override = ovr;
@@ -537,7 +549,13 @@ sysfs_show_available_clocksources(struct sys_device *dev,
 
        spin_lock_irq(&clocksource_lock);
        list_for_each_entry(src, &clocksource_list, list) {
-               count += snprintf(buf + count,
+               /*
+                * Don't show non-HRES clocksource if the tick code is
+                * in one shot mode (highres=on or nohz=on)
+                */
+               if (!tick_oneshot_mode_active() ||
+                   (src->flags & CLOCK_SOURCE_VALID_FOR_HRES))
+                       count += snprintf(buf + count,
                                  max((ssize_t)PAGE_SIZE - count, (ssize_t)0),
                                  "%s ", src->name);
        }
index 118a3b3b3f9a3de4ffa48a2d30a73f6d8a56d3ef..877dbedc3118275ac77f34c2b63a655f6c1a7617 100644 (file)
@@ -27,7 +27,7 @@
  * timer stops in C3 state.
  */
 
-struct tick_device tick_broadcast_device;
+static struct tick_device tick_broadcast_device;
 /* FIXME: Use cpumask_var_t. */
 static DECLARE_BITMAP(tick_broadcast_mask, NR_CPUS);
 static DECLARE_BITMAP(tmpmask, NR_CPUS);
index 2e8de678e767a76d444c822307b7bd34baff67c5..a96c0e2b89cf82b574de560971256dc7f2bf0931 100644 (file)
@@ -128,6 +128,23 @@ int tick_switch_to_oneshot(void (*handler)(struct clock_event_device *))
        return 0;
 }
 
+/**
+ * tick_check_oneshot_mode - check whether the system is in oneshot mode
+ *
+ * returns 1 when either nohz or highres are enabled. otherwise 0.
+ */
+int tick_oneshot_mode_active(void)
+{
+       unsigned long flags;
+       int ret;
+
+       local_irq_save(flags);
+       ret = __get_cpu_var(tick_cpu_device).mode == TICKDEV_MODE_ONESHOT;
+       local_irq_restore(flags);
+
+       return ret;
+}
+
 #ifdef CONFIG_HIGH_RES_TIMERS
 /**
  * tick_init_highres - switch to high resolution mode
index d3f1ef4d5cbe7a15fdc1d0b5cd2ee195ea4890fc..2aff39c6f10cca1791b403aa521dcd0e696a97e5 100644 (file)
@@ -349,7 +349,7 @@ void tick_nohz_stop_sched_tick(int inidle)
 
                if (ts->nohz_mode == NOHZ_MODE_HIGHRES) {
                        hrtimer_start(&ts->sched_timer, expires,
-                                     HRTIMER_MODE_ABS);
+                                     HRTIMER_MODE_ABS_PINNED);
                        /* Check, if the timer was already in the past */
                        if (hrtimer_active(&ts->sched_timer))
                                goto out;
@@ -395,7 +395,7 @@ static void tick_nohz_restart(struct tick_sched *ts, ktime_t now)
 
                if (ts->nohz_mode == NOHZ_MODE_HIGHRES) {
                        hrtimer_start_expires(&ts->sched_timer,
-                                     HRTIMER_MODE_ABS);
+                                             HRTIMER_MODE_ABS_PINNED);
                        /* Check, if the timer was already in the past */
                        if (hrtimer_active(&ts->sched_timer))
                                break;
@@ -698,7 +698,8 @@ void tick_setup_sched_timer(void)
 
        for (;;) {
                hrtimer_forward(&ts->sched_timer, now, tick_period);
-               hrtimer_start_expires(&ts->sched_timer, HRTIMER_MODE_ABS);
+               hrtimer_start_expires(&ts->sched_timer,
+                                     HRTIMER_MODE_ABS_PINNED);
                /* Check, if the timer was already in the past */
                if (hrtimer_active(&ts->sched_timer))
                        break;
index faf2db897de4b5ef6b82ed81fcef40c6c4452aa9..54d3912f8cadd497d09546ad8b9b1ba42369634d 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/tick.h>
 #include <linux/kallsyms.h>
 #include <linux/perf_counter.h>
+#include <linux/sched.h>
 
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
@@ -605,13 +606,12 @@ static struct tvec_base *lock_timer_base(struct timer_list *timer,
 }
 
 static inline int
-__mod_timer(struct timer_list *timer, unsigned long expires, bool pending_only)
+__mod_timer(struct timer_list *timer, unsigned long expires,
+                                               bool pending_only, int pinned)
 {
        struct tvec_base *base, *new_base;
        unsigned long flags;
-       int ret;
-
-       ret = 0;
+       int ret = 0 , cpu;
 
        timer_stats_timer_set_start_info(timer);
        BUG_ON(!timer->function);
@@ -630,6 +630,18 @@ __mod_timer(struct timer_list *timer, unsigned long expires, bool pending_only)
 
        new_base = __get_cpu_var(tvec_bases);
 
+       cpu = smp_processor_id();
+
+#if defined(CONFIG_NO_HZ) && defined(CONFIG_SMP)
+       if (!pinned && get_sysctl_timer_migration() && idle_cpu(cpu)) {
+               int preferred_cpu = get_nohz_load_balancer();
+
+               if (preferred_cpu >= 0)
+                       cpu = preferred_cpu;
+       }
+#endif
+       new_base = per_cpu(tvec_bases, cpu);
+
        if (base != new_base) {
                /*
                 * We are trying to schedule the timer on the local CPU.
@@ -669,7 +681,7 @@ out_unlock:
  */
 int mod_timer_pending(struct timer_list *timer, unsigned long expires)
 {
-       return __mod_timer(timer, expires, true);
+       return __mod_timer(timer, expires, true, TIMER_NOT_PINNED);
 }
 EXPORT_SYMBOL(mod_timer_pending);
 
@@ -703,10 +715,32 @@ int mod_timer(struct timer_list *timer, unsigned long expires)
        if (timer->expires == expires && timer_pending(timer))
                return 1;
 
-       return __mod_timer(timer, expires, false);
+       return __mod_timer(timer, expires, false, TIMER_NOT_PINNED);
 }
 EXPORT_SYMBOL(mod_timer);
 
+/**
+ * mod_timer_pinned - modify a timer's timeout
+ * @timer: the timer to be modified
+ * @expires: new timeout in jiffies
+ *
+ * mod_timer_pinned() is a way to update the expire field of an
+ * active timer (if the timer is inactive it will be activated)
+ * and not allow the timer to be migrated to a different CPU.
+ *
+ * mod_timer_pinned(timer, expires) is equivalent to:
+ *
+ *     del_timer(timer); timer->expires = expires; add_timer(timer);
+ */
+int mod_timer_pinned(struct timer_list *timer, unsigned long expires)
+{
+       if (timer->expires == expires && timer_pending(timer))
+               return 1;
+
+       return __mod_timer(timer, expires, false, TIMER_PINNED);
+}
+EXPORT_SYMBOL(mod_timer_pinned);
+
 /**
  * add_timer - start a timer
  * @timer: the timer to be added
@@ -1017,6 +1051,9 @@ cascade:
                index = slot = timer_jiffies & TVN_MASK;
                do {
                        list_for_each_entry(nte, varp->vec + slot, entry) {
+                               if (tbase_get_deferrable(nte->base))
+                                       continue;
+
                                found = 1;
                                if (time_before(nte->expires, expires))
                                        expires = nte->expires;
@@ -1307,7 +1344,7 @@ signed long __sched schedule_timeout(signed long timeout)
        expire = timeout + jiffies;
 
        setup_timer_on_stack(&timer, process_timeout, (unsigned long)current);
-       __mod_timer(&timer, expire, false);
+       __mod_timer(&timer, expire, false, TIMER_NOT_PINNED);
        schedule();
        del_singleshot_timer_sync(&timer);
 
index e04b76cc238a69816cd96b57146afbc97cc36da1..f6693969287d83e716733f0d21c6356f70ec8ff5 100644 (file)
@@ -203,7 +203,8 @@ static void start_stack_timer(void *unused)
        hrtimer_init(hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
        hrtimer->function = stack_trace_timer_fn;
 
-       hrtimer_start(hrtimer, ns_to_ktime(sample_period), HRTIMER_MODE_REL);
+       hrtimer_start(hrtimer, ns_to_ktime(sample_period),
+                     HRTIMER_MODE_REL_PINNED);
 }
 
 static void start_stack_timers(void)
index 539e6064e6d4224fb08cac728c2fa71d2bd6e4df..3ef0ab0a543a5bfbf7e4b4cc709ba7919c82bfa5 100644 (file)
@@ -185,10 +185,6 @@ static const struct header_ops fddi_header_ops = {
 static void fddi_setup(struct net_device *dev)
 {
        dev->header_ops         = &fddi_header_ops;
-#ifdef CONFIG_COMPAT_NET_DEV_OPS
-       dev->change_mtu         = fddi_change_mtu,
-#endif
-
        dev->type               = ARPHRD_FDDI;
        dev->hard_header_len    = FDDI_K_SNAP_HLEN+3;   /* Assume 802.2 SNAP hdr len + 3 pad bytes */
        dev->mtu                = FDDI_K_SNAP_DLEN;     /* Assume max payload of 802.2 SNAP frame */
index 313b9ebf92ee23fb4b2b6e6d1dfb2ce75432368c..cd3e8e9295295fd3746cc20bd9068de5c7338d5b 100644 (file)
@@ -193,11 +193,6 @@ static const struct header_ops hippi_header_ops = {
 
 static void hippi_setup(struct net_device *dev)
 {
-#ifdef CONFIG_COMPAT_NET_DEV_OPS
-       dev->change_mtu                 = hippi_change_mtu;
-       dev->set_mac_address            = hippi_mac_addr;
-       dev->neigh_setup                = hippi_neigh_setup_dev;
-#endif
        dev->header_ops                 = &hippi_header_ops;
 
        /*
index d1e10546eb85d824b8f06e499358634bc9c2288b..fe649081fbdcc192426bfc1639068110b2ba6717 100644 (file)
@@ -378,13 +378,13 @@ static void vlan_sync_address(struct net_device *dev,
         * the new address */
        if (compare_ether_addr(vlandev->dev_addr, vlan->real_dev_addr) &&
            !compare_ether_addr(vlandev->dev_addr, dev->dev_addr))
-               dev_unicast_delete(dev, vlandev->dev_addr, ETH_ALEN);
+               dev_unicast_delete(dev, vlandev->dev_addr);
 
        /* vlan address was equal to the old address and is different from
         * the new address */
        if (!compare_ether_addr(vlandev->dev_addr, vlan->real_dev_addr) &&
            compare_ether_addr(vlandev->dev_addr, dev->dev_addr))
-               dev_unicast_add(dev, vlandev->dev_addr, ETH_ALEN);
+               dev_unicast_add(dev, vlandev->dev_addr);
 
        memcpy(vlan->real_dev_addr, dev->dev_addr, ETH_ALEN);
 }
@@ -758,7 +758,7 @@ static void __exit vlan_cleanup_module(void)
                BUG_ON(!hlist_empty(&vlan_group_hash[i]));
 
        unregister_pernet_gen_device(vlan_net_id, &vlan_net_ops);
-       synchronize_net();
+       rcu_barrier(); /* Wait for completion of call_rcu()'s */
 
        vlan_gvrp_uninit();
 }
index c67fe6f7565320f0938e3c97832ba2d76c30ba04..7f7de1a04de6a1a05e07ab2c7d93d5f8cc3e72c0 100644 (file)
@@ -114,9 +114,9 @@ int vlan_gro_receive(struct napi_struct *napi, struct vlan_group *grp,
 EXPORT_SYMBOL(vlan_gro_receive);
 
 int vlan_gro_frags(struct napi_struct *napi, struct vlan_group *grp,
-                  unsigned int vlan_tci, struct napi_gro_fraginfo *info)
+                  unsigned int vlan_tci)
 {
-       struct sk_buff *skb = napi_fraginfo_skb(napi, info);
+       struct sk_buff *skb = napi_frags_skb(napi);
 
        if (!skb)
                return NET_RX_DROP;
index b4b9068e55a754ac09b00b67ac4a78651490d321..96bad8f233e2494b958fd3f88b8634c2693af313 100644 (file)
@@ -290,7 +290,7 @@ static int vlan_dev_hard_header(struct sk_buff *skb, struct net_device *dev,
 
 static int vlan_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-       struct net_device_stats *stats = &dev->stats;
+       struct netdev_queue *txq = netdev_get_tx_queue(dev, 0);
        struct vlan_ethhdr *veth = (struct vlan_ethhdr *)(skb->data);
 
        /* Handle non-VLAN frames if they are sent to us, for example by DHCP.
@@ -309,7 +309,7 @@ static int vlan_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
                vlan_tci |= vlan_dev_get_egress_qos_mask(dev, skb);
                skb = __vlan_put_tag(skb, vlan_tci);
                if (!skb) {
-                       stats->tx_dropped++;
+                       txq->tx_dropped++;
                        return NETDEV_TX_OK;
                }
 
@@ -317,8 +317,8 @@ static int vlan_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
                        vlan_dev_info(dev)->cnt_inc_headroom_on_tx++;
        }
 
-       stats->tx_packets++;
-       stats->tx_bytes += skb->len;
+       txq->tx_packets++;
+       txq->tx_bytes += skb->len;
 
        skb->dev = vlan_dev_info(dev)->real_dev;
        dev_queue_xmit(skb);
@@ -328,15 +328,15 @@ static int vlan_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 static int vlan_dev_hwaccel_hard_start_xmit(struct sk_buff *skb,
                                            struct net_device *dev)
 {
-       struct net_device_stats *stats = &dev->stats;
+       struct netdev_queue *txq = netdev_get_tx_queue(dev, 0);
        u16 vlan_tci;
 
        vlan_tci = vlan_dev_info(dev)->vlan_id;
        vlan_tci |= vlan_dev_get_egress_qos_mask(dev, skb);
        skb = __vlan_hwaccel_put_tag(skb, vlan_tci);
 
-       stats->tx_packets++;
-       stats->tx_bytes += skb->len;
+       txq->tx_packets++;
+       txq->tx_bytes += skb->len;
 
        skb->dev = vlan_dev_info(dev)->real_dev;
        dev_queue_xmit(skb);
@@ -441,7 +441,7 @@ static int vlan_dev_open(struct net_device *dev)
                return -ENETDOWN;
 
        if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr)) {
-               err = dev_unicast_add(real_dev, dev->dev_addr, ETH_ALEN);
+               err = dev_unicast_add(real_dev, dev->dev_addr);
                if (err < 0)
                        goto out;
        }
@@ -470,7 +470,7 @@ clear_allmulti:
                dev_set_allmulti(real_dev, -1);
 del_unicast:
        if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr))
-               dev_unicast_delete(real_dev, dev->dev_addr, ETH_ALEN);
+               dev_unicast_delete(real_dev, dev->dev_addr);
 out:
        netif_carrier_off(dev);
        return err;
@@ -492,7 +492,7 @@ static int vlan_dev_stop(struct net_device *dev)
                dev_set_promiscuity(real_dev, -1);
 
        if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr))
-               dev_unicast_delete(real_dev, dev->dev_addr, dev->addr_len);
+               dev_unicast_delete(real_dev, dev->dev_addr);
 
        netif_carrier_off(dev);
        return 0;
@@ -511,13 +511,13 @@ static int vlan_dev_set_mac_address(struct net_device *dev, void *p)
                goto out;
 
        if (compare_ether_addr(addr->sa_data, real_dev->dev_addr)) {
-               err = dev_unicast_add(real_dev, addr->sa_data, ETH_ALEN);
+               err = dev_unicast_add(real_dev, addr->sa_data);
                if (err < 0)
                        return err;
        }
 
        if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr))
-               dev_unicast_delete(real_dev, dev->dev_addr, ETH_ALEN);
+               dev_unicast_delete(real_dev, dev->dev_addr);
 
 out:
        memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
@@ -644,7 +644,6 @@ static int vlan_dev_init(struct net_device *dev)
                dev->hard_header_len = real_dev->hard_header_len + VLAN_HLEN;
                dev->netdev_ops         = &vlan_netdev_ops;
        }
-       netdev_resync_ops(dev);
 
        if (is_vlan_dev(real_dev))
                subclass = 1;
@@ -671,13 +670,7 @@ static int vlan_ethtool_get_settings(struct net_device *dev,
                                     struct ethtool_cmd *cmd)
 {
        const struct vlan_dev_info *vlan = vlan_dev_info(dev);
-       struct net_device *real_dev = vlan->real_dev;
-
-       if (!real_dev->ethtool_ops ||
-           !real_dev->ethtool_ops->get_settings)
-               return -EOPNOTSUPP;
-
-       return real_dev->ethtool_ops->get_settings(real_dev, cmd);
+       return dev_ethtool_get_settings(vlan->real_dev, cmd);
 }
 
 static void vlan_ethtool_get_drvinfo(struct net_device *dev,
@@ -691,24 +684,13 @@ static void vlan_ethtool_get_drvinfo(struct net_device *dev,
 static u32 vlan_ethtool_get_rx_csum(struct net_device *dev)
 {
        const struct vlan_dev_info *vlan = vlan_dev_info(dev);
-       struct net_device *real_dev = vlan->real_dev;
-
-       if (real_dev->ethtool_ops == NULL ||
-           real_dev->ethtool_ops->get_rx_csum == NULL)
-               return 0;
-       return real_dev->ethtool_ops->get_rx_csum(real_dev);
+       return dev_ethtool_get_rx_csum(vlan->real_dev);
 }
 
 static u32 vlan_ethtool_get_flags(struct net_device *dev)
 {
        const struct vlan_dev_info *vlan = vlan_dev_info(dev);
-       struct net_device *real_dev = vlan->real_dev;
-
-       if (!(real_dev->features & NETIF_F_HW_VLAN_RX) ||
-           real_dev->ethtool_ops == NULL ||
-           real_dev->ethtool_ops->get_flags == NULL)
-               return 0;
-       return real_dev->ethtool_ops->get_flags(real_dev);
+       return dev_ethtool_get_flags(vlan->real_dev);
 }
 
 static const struct ethtool_ops vlan_ethtool_ops = {
@@ -756,6 +738,7 @@ void vlan_setup(struct net_device *dev)
        ether_setup(dev);
 
        dev->priv_flags         |= IFF_802_1Q_VLAN;
+       dev->priv_flags         &= ~IFF_XMIT_DST_RELEASE;
        dev->tx_queue_len       = 0;
 
        dev->netdev_ops         = &vlan_netdev_ops;
index 3628e0a81b40f5e5cd3c4e1523923df2645287ca..b55a091a33dfb98fa0110c45df263772ce58c763 100644 (file)
@@ -279,13 +279,14 @@ static int vlandev_seq_show(struct seq_file *seq, void *offset)
 {
        struct net_device *vlandev = (struct net_device *) seq->private;
        const struct vlan_dev_info *dev_info = vlan_dev_info(vlandev);
-       struct net_device_stats *stats = &vlandev->stats;
+       const struct net_device_stats *stats;
        static const char fmt[] = "%30s %12lu\n";
        int i;
 
        if (!is_vlan_dev(vlandev))
                return 0;
 
+       stats = dev_get_stats(vlandev);
        seq_printf(seq,
                   "%s  VID: %d  REORDER_HDR: %i  dev->priv_flags: %hx\n",
                   vlandev->name, dev_info->vlan_id,
index c19f549c8e74c874d3a35f3ae8ba0cfa78a13592..7051b9710675fa2e81a5eebcd31517eafdab8fb8 100644 (file)
@@ -179,6 +179,7 @@ source "net/lapb/Kconfig"
 source "net/econet/Kconfig"
 source "net/wanrouter/Kconfig"
 source "net/phonet/Kconfig"
+source "net/ieee802154/Kconfig"
 source "net/sched/Kconfig"
 source "net/dcb/Kconfig"
 
index 9e00a55a901bc29a708949bb5d1c4ad9e7d5b5c6..ba324aefda73c886f61418b000304410a694bb9a 100644 (file)
@@ -60,6 +60,7 @@ obj-$(CONFIG_NET_9P)          += 9p/
 ifneq ($(CONFIG_DCB),)
 obj-y                          += dcb/
 endif
+obj-y                          += ieee802154/
 
 ifeq ($(CONFIG_NET),y)
 obj-$(CONFIG_SYSCTL)           += sysctl_net.o
index d6a9243641afaa82cbf9894935a0ddf9acb7a288..b603cbacdc58eccf171c84599a9c2bfd426f74f4 100644 (file)
@@ -939,6 +939,7 @@ static unsigned long atalk_sum_skb(const struct sk_buff *skb, int offset,
                                   int len, unsigned long sum)
 {
        int start = skb_headlen(skb);
+       struct sk_buff *frag_iter;
        int i, copy;
 
        /* checksum stuff in header space */
@@ -977,26 +978,22 @@ static unsigned long atalk_sum_skb(const struct sk_buff *skb, int offset,
                start = end;
        }
 
-       if (skb_shinfo(skb)->frag_list) {
-               struct sk_buff *list = skb_shinfo(skb)->frag_list;
-
-               for (; list; list = list->next) {
-                       int end;
+       skb_walk_frags(skb, frag_iter) {
+               int end;
 
-                       WARN_ON(start > offset + len);
+               WARN_ON(start > offset + len);
 
-                       end = start + list->len;
-                       if ((copy = end - offset) > 0) {
-                               if (copy > len)
-                                       copy = len;
-                               sum = atalk_sum_skb(list, offset - start,
-                                                   copy, sum);
-                               if ((len -= copy) == 0)
-                                       return sum;
-                               offset += copy;
-                       }
-                       start = end;
+               end = start + frag_iter->len;
+               if ((copy = end - offset) > 0) {
+                       if (copy > len)
+                               copy = len;
+                       sum = atalk_sum_skb(frag_iter, offset - start,
+                                           copy, sum);
+                       if ((len -= copy) == 0)
+                               return sum;
+                       offset += copy;
                }
+               start = end;
        }
 
        BUG_ON(len > 0);
index 72277d70c980be38035f11bc7aae0a1be46b8398..6c8016f618661d931467bf2a005ee1933eec1797 100644 (file)
@@ -9,21 +9,10 @@
 #include <linux/if_arp.h>
 #include <linux/if_ltalk.h>
 
-#ifdef CONFIG_COMPAT_NET_DEV_OPS
-static int ltalk_change_mtu(struct net_device *dev, int mtu)
-{
-       return -EINVAL;
-}
-#endif
-
 static void ltalk_setup(struct net_device *dev)
 {
        /* Fill in the fields of the device structure with localtalk-generic values. */
 
-#ifdef CONFIG_COMPAT_NET_DEV_OPS
-       dev->change_mtu         = ltalk_change_mtu;
-#endif
-
        dev->type               = ARPHRD_LOCALTLK;
        dev->hard_header_len    = LTALK_HLEN;
        dev->mtu                = LTALK_MTU;
index 3100a8940afce8f38ca59e8fe27917ab480f7dfd..2912665fc58c3d7ea0614ffeb73268fbad5ccf22 100644 (file)
@@ -228,7 +228,7 @@ static int br2684_start_xmit(struct sk_buff *skb, struct net_device *dev)
        struct br2684_dev *brdev = BRPRIV(dev);
        struct br2684_vcc *brvcc;
 
-       pr_debug("br2684_start_xmit, skb->dst=%p\n", skb->dst);
+       pr_debug("br2684_start_xmit, skb_dst(skb)=%p\n", skb_dst(skb));
        read_lock(&devs_lock);
        brvcc = pick_outgoing_vcc(skb, brdev);
        if (brvcc == NULL) {
@@ -445,9 +445,10 @@ free_skb:
  */
 static int br2684_regvcc(struct atm_vcc *atmvcc, void __user * arg)
 {
+       struct sk_buff_head queue;
        int err;
        struct br2684_vcc *brvcc;
-       struct sk_buff *skb;
+       struct sk_buff *skb, *tmp;
        struct sk_buff_head *rq;
        struct br2684_dev *brdev;
        struct net_device *net_dev;
@@ -505,29 +506,20 @@ static int br2684_regvcc(struct atm_vcc *atmvcc, void __user * arg)
        barrier();
        atmvcc->push = br2684_push;
 
+       __skb_queue_head_init(&queue);
        rq = &sk_atm(atmvcc)->sk_receive_queue;
 
        spin_lock_irqsave(&rq->lock, flags);
-       if (skb_queue_empty(rq)) {
-               skb = NULL;
-       } else {
-               /* NULL terminate the list.  */
-               rq->prev->next = NULL;
-               skb = rq->next;
-       }
-       rq->prev = rq->next = (struct sk_buff *)rq;
-       rq->qlen = 0;
+       skb_queue_splice_init(rq, &queue);
        spin_unlock_irqrestore(&rq->lock, flags);
 
-       while (skb) {
-               struct sk_buff *next = skb->next;
+       skb_queue_walk_safe(&queue, skb, tmp) {
+               struct net_device *dev = skb->dev;
 
-               skb->next = skb->prev = NULL;
-               br2684_push(atmvcc, skb);
-               skb->dev->stats.rx_bytes -= skb->len;
-               skb->dev->stats.rx_packets--;
+               dev->stats.rx_bytes -= skb->len;
+               dev->stats.rx_packets--;
 
-               skb = next;
+               br2684_push(atmvcc, skb);
        }
        __module_get(THIS_MODULE);
        return 0;
index 3dc0a3a42a574c43ba71aaed05f29e6246445b24..e65a3b1477f8edc79dd8d6ab620fc824c95b10ec 100644 (file)
@@ -369,16 +369,16 @@ static int clip_start_xmit(struct sk_buff *skb, struct net_device *dev)
        unsigned long flags;
 
        pr_debug("clip_start_xmit (skb %p)\n", skb);
-       if (!skb->dst) {
-               printk(KERN_ERR "clip_start_xmit: skb->dst == NULL\n");
+       if (!skb_dst(skb)) {
+               printk(KERN_ERR "clip_start_xmit: skb_dst(skb) == NULL\n");
                dev_kfree_skb(skb);
                dev->stats.tx_dropped++;
                return 0;
        }
-       if (!skb->dst->neighbour) {
+       if (!skb_dst(skb)->neighbour) {
 #if 0
-               skb->dst->neighbour = clip_find_neighbour(skb->dst, 1);
-               if (!skb->dst->neighbour) {
+               skb_dst(skb)->neighbour = clip_find_neighbour(skb_dst(skb), 1);
+               if (!skb_dst(skb)->neighbour) {
                        dev_kfree_skb(skb);     /* lost that one */
                        dev->stats.tx_dropped++;
                        return 0;
@@ -389,7 +389,7 @@ static int clip_start_xmit(struct sk_buff *skb, struct net_device *dev)
                dev->stats.tx_dropped++;
                return 0;
        }
-       entry = NEIGH2ENTRY(skb->dst->neighbour);
+       entry = NEIGH2ENTRY(skb_dst(skb)->neighbour);
        if (!entry->vccs) {
                if (time_after(jiffies, entry->expires)) {
                        /* should be resolved */
@@ -406,7 +406,7 @@ static int clip_start_xmit(struct sk_buff *skb, struct net_device *dev)
        }
        pr_debug("neigh %p, vccs %p\n", entry, entry->vccs);
        ATM_SKB(skb)->vcc = vcc = entry->vccs->vcc;
-       pr_debug("using neighbour %p, vcc %p\n", skb->dst->neighbour, vcc);
+       pr_debug("using neighbour %p, vcc %p\n", skb_dst(skb)->neighbour, vcc);
        if (entry->vccs->encap) {
                void *here;
 
@@ -445,9 +445,9 @@ static int clip_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 static int clip_mkip(struct atm_vcc *vcc, int timeout)
 {
+       struct sk_buff_head *rq, queue;
        struct clip_vcc *clip_vcc;
-       struct sk_buff *skb;
-       struct sk_buff_head *rq;
+       struct sk_buff *skb, *tmp;
        unsigned long flags;
 
        if (!vcc->push)
@@ -469,39 +469,28 @@ static int clip_mkip(struct atm_vcc *vcc, int timeout)
        vcc->push = clip_push;
        vcc->pop = clip_pop;
 
+       __skb_queue_head_init(&queue);
        rq = &sk_atm(vcc)->sk_receive_queue;
 
        spin_lock_irqsave(&rq->lock, flags);
-       if (skb_queue_empty(rq)) {
-               skb = NULL;
-       } else {
-               /* NULL terminate the list.  */
-               rq->prev->next = NULL;
-               skb = rq->next;
-       }
-       rq->prev = rq->next = (struct sk_buff *)rq;
-       rq->qlen = 0;
+       skb_queue_splice_init(rq, &queue);
        spin_unlock_irqrestore(&rq->lock, flags);
 
        /* re-process everything received between connection setup and MKIP */
-       while (skb) {
-               struct sk_buff *next = skb->next;
-
-               skb->next = skb->prev = NULL;
+       skb_queue_walk_safe(&queue, skb, tmp) {
                if (!clip_devs) {
                        atm_return(vcc, skb->truesize);
                        kfree_skb(skb);
                } else {
+                       struct net_device *dev = skb->dev;
                        unsigned int len = skb->len;
 
                        skb_get(skb);
                        clip_push(vcc, skb);
-                       skb->dev->stats.rx_packets--;
-                       skb->dev->stats.rx_bytes -= len;
+                       dev->stats.rx_packets--;
+                       dev->stats.rx_bytes -= len;
                        kfree_skb(skb);
                }
-
-               skb = next;
        }
        return 0;
 }
@@ -568,6 +557,7 @@ static void clip_setup(struct net_device *dev)
        /* without any more elaborate queuing. 100 is a reasonable */
        /* compromise between decent burst-tolerance and protection */
        /* against memory hogs. */
+       dev->priv_flags &= ~IFF_XMIT_DST_RELEASE;
 }
 
 static int clip_create(int number)
index 199b6bb79f429aadeaf6a26ad6c3b65d200d1644..ff2e594dca9b935efe720799e6367c8208e630cb 100644 (file)
@@ -34,7 +34,6 @@
 
 /* Proxy LEC knows about bridging */
 #if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
-#include <linux/if_bridge.h>
 #include "../bridge/br_private.h"
 
 static unsigned char bridge_ula_lec[] = { 0x01, 0x80, 0xc2, 0x00, 0x00 };
@@ -271,7 +270,8 @@ static int lec_start_xmit(struct sk_buff *skb, struct net_device *dev)
                printk("%s:No lecd attached\n", dev->name);
                dev->stats.tx_errors++;
                netif_stop_queue(dev);
-               return -EUNATCH;
+               kfree_skb(skb);
+               return NETDEV_TX_OK;
        }
 
        pr_debug("skbuff head:%lx data:%lx tail:%lx end:%lx\n",
@@ -518,18 +518,14 @@ static int lec_atm_send(struct atm_vcc *vcc, struct sk_buff *skb)
        case l_should_bridge:
 #if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
                {
-                       struct net_bridge_fdb_entry *f;
-
                        pr_debug("%s: bridge zeppelin asks about %pM\n",
                                 dev->name, mesg->content.proxy.mac_addr);
 
-                       if (br_fdb_get_hook == NULL || dev->br_port == NULL)
+                       if (br_fdb_test_addr_hook == NULL)
                                break;
 
-                       f = br_fdb_get_hook(dev->br_port->br,
-                                           mesg->content.proxy.mac_addr);
-                       if (f != NULL && f->dst->dev != dev
-                           && f->dst->state == BR_STATE_FORWARDING) {
+                       if (br_fdb_test_addr_hook(dev,
+                                       mesg->content.proxy.mac_addr)) {
                                /* hit from bridge table, send LE_ARP_RESPONSE */
                                struct sk_buff *skb2;
                                struct sock *sk;
@@ -540,10 +536,8 @@ static int lec_atm_send(struct atm_vcc *vcc, struct sk_buff *skb)
                                skb2 =
                                    alloc_skb(sizeof(struct atmlec_msg),
                                              GFP_ATOMIC);
-                               if (skb2 == NULL) {
-                                       br_fdb_put_hook(f);
+                               if (skb2 == NULL)
                                        break;
-                               }
                                skb2->len = sizeof(struct atmlec_msg);
                                skb_copy_to_linear_data(skb2, mesg,
                                                        sizeof(*mesg));
@@ -552,8 +546,6 @@ static int lec_atm_send(struct atm_vcc *vcc, struct sk_buff *skb)
                                skb_queue_tail(&sk->sk_receive_queue, skb2);
                                sk->sk_data_ready(sk, skb2->len);
                        }
-                       if (f != NULL)
-                               br_fdb_put_hook(f);
                }
 #endif /* defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) */
                break;
index 7725da95a767185c5a3cccd0713198a1e8070328..59fdb1d2e8edfc8e3bd0c6eaae058f36a179e7bc 100644 (file)
@@ -3,8 +3,9 @@
 #
 
 menuconfig BT
-       depends on NET && !S390
        tristate "Bluetooth subsystem support"
+       depends on NET && !S390
+       depends on RFKILL || !RFKILL
        help
          Bluetooth is low-cost, low-power, short-range wireless technology.
          It was designed as a replacement for cables and other short-range
index 78958c0f9a40a8e7e04e15c41074c1e47e959398..97f8d68d574daf16880a08b4396d7e1c604c7c93 100644 (file)
@@ -382,7 +382,7 @@ static void cmtp_reset_ctr(struct capi_ctr *ctrl)
 
        BT_DBG("ctrl %p", ctrl);
 
-       capi_ctr_reseted(ctrl);
+       capi_ctr_down(ctrl);
 
        atomic_inc(&session->terminate);
        cmtp_schedule(session);
index cd061510b6bd8356140c428a1187235e87ed31dc..406ad07cdea1d21de0642ead005881c96e3d0716 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/skbuff.h>
 #include <linux/interrupt.h>
 #include <linux/notifier.h>
+#include <linux/rfkill.h>
 #include <net/sock.h>
 
 #include <asm/system.h>
@@ -476,6 +477,11 @@ int hci_dev_open(__u16 dev)
 
        hci_req_lock(hdev);
 
+       if (hdev->rfkill && rfkill_blocked(hdev->rfkill)) {
+               ret = -ERFKILL;
+               goto done;
+       }
+
        if (test_bit(HCI_UP, &hdev->flags)) {
                ret = -EALREADY;
                goto done;
@@ -813,6 +819,24 @@ int hci_get_dev_info(void __user *arg)
 
 /* ---- Interface to HCI drivers ---- */
 
+static int hci_rfkill_set_block(void *data, bool blocked)
+{
+       struct hci_dev *hdev = data;
+
+       BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked);
+
+       if (!blocked)
+               return 0;
+
+       hci_dev_do_close(hdev);
+
+       return 0;
+}
+
+static const struct rfkill_ops hci_rfkill_ops = {
+       .set_block = hci_rfkill_set_block,
+};
+
 /* Alloc HCI device */
 struct hci_dev *hci_alloc_dev(void)
 {
@@ -844,7 +868,8 @@ int hci_register_dev(struct hci_dev *hdev)
        struct list_head *head = &hci_dev_list, *p;
        int i, id = 0;
 
-       BT_DBG("%p name %s type %d owner %p", hdev, hdev->name, hdev->type, hdev->owner);
+       BT_DBG("%p name %s type %d owner %p", hdev, hdev->name,
+                                               hdev->type, hdev->owner);
 
        if (!hdev->open || !hdev->close || !hdev->destruct)
                return -EINVAL;
@@ -900,6 +925,15 @@ int hci_register_dev(struct hci_dev *hdev)
 
        hci_register_sysfs(hdev);
 
+       hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
+                               RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops, hdev);
+       if (hdev->rfkill) {
+               if (rfkill_register(hdev->rfkill) < 0) {
+                       rfkill_destroy(hdev->rfkill);
+                       hdev->rfkill = NULL;
+               }
+       }
+
        hci_notify(hdev, HCI_DEV_REG);
 
        return id;
@@ -924,6 +958,11 @@ int hci_unregister_dev(struct hci_dev *hdev)
 
        hci_notify(hdev, HCI_DEV_UNREG);
 
+       if (hdev->rfkill) {
+               rfkill_unregister(hdev->rfkill);
+               rfkill_destroy(hdev->rfkill);
+       }
+
        hci_unregister_sysfs(hdev);
 
        __hci_dev_put(hdev);
index ca4d3b40d5cea5ac310dafe77177499eab6e554a..bd0a4c1bced048c97e61c106cc45b7c9dba8fac1 100644 (file)
 #include <linux/skbuff.h>
 #include <linux/list.h>
 #include <linux/device.h>
+#include <linux/uaccess.h>
 #include <net/sock.h>
 
 #include <asm/system.h>
-#include <asm/uaccess.h>
 #include <asm/unaligned.h>
 
 #include <net/bluetooth/bluetooth.h>
@@ -52,7 +52,7 @@
 
 #define VERSION "2.13"
 
-static u32 l2cap_feat_mask = 0x0080;
+static u32 l2cap_feat_mask = L2CAP_FEAT_FIXED_CHAN;
 static u8 l2cap_fixed_chan[8] = { 0x02, };
 
 static const struct proto_ops l2cap_sock_ops;
@@ -134,7 +134,8 @@ static inline struct sock *l2cap_get_chan_by_scid(struct l2cap_chan_list *l, u16
        struct sock *s;
        read_lock(&l->lock);
        s = __l2cap_get_chan_by_scid(l, cid);
-       if (s) bh_lock_sock(s);
+       if (s)
+               bh_lock_sock(s);
        read_unlock(&l->lock);
        return s;
 }
@@ -154,17 +155,18 @@ static inline struct sock *l2cap_get_chan_by_ident(struct l2cap_chan_list *l, u8
        struct sock *s;
        read_lock(&l->lock);
        s = __l2cap_get_chan_by_ident(l, ident);
-       if (s) bh_lock_sock(s);
+       if (s)
+               bh_lock_sock(s);
        read_unlock(&l->lock);
        return s;
 }
 
 static u16 l2cap_alloc_cid(struct l2cap_chan_list *l)
 {
-       u16 cid = 0x0040;
+       u16 cid = L2CAP_CID_DYN_START;
 
-       for (; cid < 0xffff; cid++) {
-               if(!__l2cap_get_chan_by_scid(l, cid))
+       for (; cid < L2CAP_CID_DYN_END; cid++) {
+               if (!__l2cap_get_chan_by_scid(l, cid))
                        return cid;
        }
 
@@ -204,7 +206,8 @@ static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct so
 {
        struct l2cap_chan_list *l = &conn->chan_list;
 
-       BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn, l2cap_pi(sk)->psm, l2cap_pi(sk)->dcid);
+       BT_DBG("conn %p, psm 0x%2.2x, dcid 0x%4.4x", conn,
+                       l2cap_pi(sk)->psm, l2cap_pi(sk)->dcid);
 
        conn->disc_reason = 0x13;
 
@@ -215,13 +218,13 @@ static void __l2cap_chan_add(struct l2cap_conn *conn, struct sock *sk, struct so
                l2cap_pi(sk)->scid = l2cap_alloc_cid(l);
        } else if (sk->sk_type == SOCK_DGRAM) {
                /* Connectionless socket */
-               l2cap_pi(sk)->scid = 0x0002;
-               l2cap_pi(sk)->dcid = 0x0002;
+               l2cap_pi(sk)->scid = L2CAP_CID_CONN_LESS;
+               l2cap_pi(sk)->dcid = L2CAP_CID_CONN_LESS;
                l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
        } else {
                /* Raw socket can send/recv signalling messages only */
-               l2cap_pi(sk)->scid = 0x0001;
-               l2cap_pi(sk)->dcid = 0x0001;
+               l2cap_pi(sk)->scid = L2CAP_CID_SIGNALING;
+               l2cap_pi(sk)->dcid = L2CAP_CID_SIGNALING;
                l2cap_pi(sk)->omtu = L2CAP_DEFAULT_MTU;
        }
 
@@ -272,7 +275,7 @@ static inline int l2cap_check_security(struct sock *sk)
                if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH)
                        auth_type = HCI_AT_NO_BONDING_MITM;
                else
-                        auth_type = HCI_AT_NO_BONDING;
+                       auth_type = HCI_AT_NO_BONDING;
 
                if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW)
                        l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
@@ -588,7 +591,8 @@ static inline struct sock *l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t
        struct sock *s;
        read_lock(&l2cap_sk_list.lock);
        s = __l2cap_get_sock_by_psm(state, psm, src);
-       if (s) bh_lock_sock(s);
+       if (s)
+               bh_lock_sock(s);
        read_unlock(&l2cap_sk_list.lock);
        return s;
 }
@@ -808,7 +812,7 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
                goto done;
        }
 
-       if (la.l2_psm && btohs(la.l2_psm) < 0x1001 &&
+       if (la.l2_psm && __le16_to_cpu(la.l2_psm) < 0x1001 &&
                                !capable(CAP_NET_BIND_SERVICE)) {
                err = -EACCES;
                goto done;
@@ -825,7 +829,8 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
                l2cap_pi(sk)->sport = la.l2_psm;
                sk->sk_state = BT_BOUND;
 
-               if (btohs(la.l2_psm) == 0x0001 || btohs(la.l2_psm) == 0x0003)
+               if (__le16_to_cpu(la.l2_psm) == 0x0001 ||
+                                       __le16_to_cpu(la.l2_psm) == 0x0003)
                        l2cap_pi(sk)->sec_level = BT_SECURITY_SDP;
        }
 
@@ -844,12 +849,13 @@ static int l2cap_do_connect(struct sock *sk)
        struct hci_conn *hcon;
        struct hci_dev *hdev;
        __u8 auth_type;
-       int err = 0;
+       int err;
 
        BT_DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst),
                                                        l2cap_pi(sk)->psm);
 
-       if (!(hdev = hci_get_route(dst, src)))
+       hdev = hci_get_route(dst, src);
+       if (!hdev)
                return -EHOSTUNREACH;
 
        hci_dev_lock_bh(hdev);
@@ -950,7 +956,7 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al
                goto done;
        }
 
-       switch(sk->sk_state) {
+       switch (sk->sk_state) {
        case BT_CONNECT:
        case BT_CONNECT2:
        case BT_CONFIG:
@@ -975,7 +981,8 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, int al
        bacpy(&bt_sk(sk)->dst, &la.l2_bdaddr);
        l2cap_pi(sk)->psm = la.l2_psm;
 
-       if ((err = l2cap_do_connect(sk)))
+       err = l2cap_do_connect(sk);
+       if (err)
                goto done;
 
 wait:
@@ -1009,9 +1016,9 @@ static int l2cap_sock_listen(struct socket *sock, int backlog)
                write_lock_bh(&l2cap_sk_list.lock);
 
                for (psm = 0x1001; psm < 0x1100; psm += 2)
-                       if (!__l2cap_get_sock_by_addr(htobs(psm), src)) {
-                               l2cap_pi(sk)->psm   = htobs(psm);
-                               l2cap_pi(sk)->sport = htobs(psm);
+                       if (!__l2cap_get_sock_by_addr(cpu_to_le16(psm), src)) {
+                               l2cap_pi(sk)->psm   = cpu_to_le16(psm);
+                               l2cap_pi(sk)->sport = cpu_to_le16(psm);
                                err = 0;
                                break;
                        }
@@ -1100,11 +1107,11 @@ static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *l
        if (peer) {
                la->l2_psm = l2cap_pi(sk)->psm;
                bacpy(&la->l2_bdaddr, &bt_sk(sk)->dst);
-               la->l2_cid = htobs(l2cap_pi(sk)->dcid);
+               la->l2_cid = cpu_to_le16(l2cap_pi(sk)->dcid);
        } else {
                la->l2_psm = l2cap_pi(sk)->sport;
                bacpy(&la->l2_bdaddr, &bt_sk(sk)->src);
-               la->l2_cid = htobs(l2cap_pi(sk)->scid);
+               la->l2_cid = cpu_to_le16(l2cap_pi(sk)->scid);
        }
 
        return 0;
@@ -1114,7 +1121,7 @@ static inline int l2cap_do_send(struct sock *sk, struct msghdr *msg, int len)
 {
        struct l2cap_conn *conn = l2cap_pi(sk)->conn;
        struct sk_buff *skb, **frag;
-       int err, hlen, count, sent=0;
+       int err, hlen, count, sent = 0;
        struct l2cap_hdr *lh;
 
        BT_DBG("sk %p len %d", sk, len);
@@ -1167,8 +1174,8 @@ static inline int l2cap_do_send(struct sock *sk, struct msghdr *msg, int len)
 
                frag = &(*frag)->next;
        }
-
-       if ((err = hci_send_acl(conn->hcon, skb, 0)) < 0)
+       err = hci_send_acl(conn->hcon, skb, 0);
+       if (err < 0)
                goto fail;
 
        return sent;
@@ -1556,7 +1563,7 @@ static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
 {
        struct l2cap_chan_list *l = &conn->chan_list;
        struct sk_buff *nskb;
-       struct sock * sk;
+       struct sock *sk;
 
        BT_DBG("conn %p", conn);
 
@@ -1568,8 +1575,8 @@ static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
                /* Don't send frame to the socket it came from */
                if (skb->sk == sk)
                        continue;
-
-               if (!(nskb = skb_clone(skb, GFP_ATOMIC)))
+               nskb = skb_clone(skb, GFP_ATOMIC);
+               if (!nskb)
                        continue;
 
                if (sock_queue_rcv_skb(sk, nskb))
@@ -1587,7 +1594,8 @@ static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
        struct l2cap_hdr *lh;
        int len, count;
 
-       BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %d", conn, code, ident, dlen);
+       BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %d",
+                       conn, code, ident, dlen);
 
        len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen;
        count = min_t(unsigned int, conn->mtu, len);
@@ -1598,7 +1606,7 @@ static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
 
        lh = (struct l2cap_hdr *) skb_put(skb, L2CAP_HDR_SIZE);
        lh->len = cpu_to_le16(L2CAP_CMD_HDR_SIZE + dlen);
-       lh->cid = cpu_to_le16(0x0001);
+       lh->cid = cpu_to_le16(L2CAP_CID_SIGNALING);
 
        cmd = (struct l2cap_cmd_hdr *) skb_put(skb, L2CAP_CMD_HDR_SIZE);
        cmd->code  = code;
@@ -1739,8 +1747,8 @@ static int l2cap_parse_conf_req(struct sock *sk, void *data)
        while (len >= L2CAP_CONF_OPT_SIZE) {
                len -= l2cap_get_conf_opt(&req, &type, &olen, &val);
 
-               hint  = type & 0x80;
-               type &= 0x7f;
+               hint  = type & L2CAP_CONF_HINT;
+               type &= L2CAP_CONF_MASK;
 
                switch (type) {
                case L2CAP_CONF_MTU:
@@ -1966,10 +1974,12 @@ static inline int l2cap_connect_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hd
        BT_DBG("dcid 0x%4.4x scid 0x%4.4x result 0x%2.2x status 0x%2.2x", dcid, scid, result, status);
 
        if (scid) {
-               if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, scid)))
+               sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
+               if (!sk)
                        return 0;
        } else {
-               if (!(sk = l2cap_get_chan_by_ident(&conn->chan_list, cmd->ident)))
+               sk = l2cap_get_chan_by_ident(&conn->chan_list, cmd->ident);
+               if (!sk)
                        return 0;
        }
 
@@ -2012,7 +2022,8 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr
 
        BT_DBG("dcid 0x%4.4x flags 0x%2.2x", dcid, flags);
 
-       if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid)))
+       sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
+       if (!sk)
                return -ENOENT;
 
        if (sk->sk_state == BT_DISCONN)
@@ -2079,9 +2090,11 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
        flags  = __le16_to_cpu(rsp->flags);
        result = __le16_to_cpu(rsp->result);
 
-       BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x", scid, flags, result);
+       BT_DBG("scid 0x%4.4x flags 0x%2.2x result 0x%2.2x",
+                       scid, flags, result);
 
-       if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, scid)))
+       sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
+       if (!sk)
                return 0;
 
        switch (result) {
@@ -2142,7 +2155,8 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, struct l2cap_cmd
 
        BT_DBG("scid 0x%4.4x dcid 0x%4.4x", scid, dcid);
 
-       if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid)))
+       sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid);
+       if (!sk)
                return 0;
 
        rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
@@ -2169,7 +2183,8 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, struct l2cap_cmd
 
        BT_DBG("dcid 0x%4.4x scid 0x%4.4x", dcid, scid);
 
-       if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, scid)))
+       sk = l2cap_get_chan_by_scid(&conn->chan_list, scid);
+       if (!sk)
                return 0;
 
        l2cap_chan_del(sk, 0);
@@ -2230,7 +2245,7 @@ static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cm
        if (type == L2CAP_IT_FEAT_MASK) {
                conn->feat_mask = get_unaligned_le32(rsp->data);
 
-               if (conn->feat_mask & 0x0080) {
+               if (conn->feat_mask & L2CAP_FEAT_FIXED_CHAN) {
                        struct l2cap_info_req req;
                        req.type = cpu_to_le16(L2CAP_IT_FIXED_CHAN);
 
@@ -2403,7 +2418,8 @@ drop:
        kfree_skb(skb);
 
 done:
-       if (sk) bh_unlock_sock(sk);
+       if (sk)
+               bh_unlock_sock(sk);
        return 0;
 }
 
@@ -2420,11 +2436,11 @@ static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
        BT_DBG("len %d, cid 0x%4.4x", len, cid);
 
        switch (cid) {
-       case 0x0001:
+       case L2CAP_CID_SIGNALING:
                l2cap_sig_channel(conn, skb);
                break;
 
-       case 0x0002:
+       case L2CAP_CID_CONN_LESS:
                psm = get_unaligned((__le16 *) skb->data);
                skb_pull(skb, 2);
                l2cap_conless_channel(conn, psm, skb);
@@ -2650,7 +2666,8 @@ static int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, u16 fl
                }
 
                /* Allocate skb for the complete frame (with header) */
-               if (!(conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC)))
+               conn->rx_skb = bt_skb_alloc(len, GFP_ATOMIC);
+               if (!conn->rx_skb)
                        goto drop;
 
                skb_copy_from_linear_data(skb, skb_put(conn->rx_skb, skb->len),
@@ -2704,13 +2721,13 @@ static ssize_t l2cap_sysfs_show(struct class *dev, char *buf)
 
                str += sprintf(str, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d\n",
                                batostr(&bt_sk(sk)->src), batostr(&bt_sk(sk)->dst),
-                               sk->sk_state, btohs(pi->psm), pi->scid, pi->dcid,
-                               pi->imtu, pi->omtu, pi->sec_level);
+                               sk->sk_state, __le16_to_cpu(pi->psm), pi->scid,
+                               pi->dcid, pi->imtu, pi->omtu, pi->sec_level);
        }
 
        read_unlock_bh(&l2cap_sk_list.lock);
 
-       return (str - buf);
+       return str - buf;
 }
 
 static CLASS_ATTR(l2cap, S_IRUGO, l2cap_sysfs_show, NULL);
index 374536e050aa546f1a4f4ed27e5a48d9514df62b..e50566ebf9f909af1c54409a02ea25b9b252e809 100644 (file)
@@ -679,7 +679,7 @@ static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src, bdaddr_t *dst
 
        bacpy(&addr.l2_bdaddr, dst);
        addr.l2_family = AF_BLUETOOTH;
-       addr.l2_psm    = htobs(RFCOMM_PSM);
+       addr.l2_psm    = cpu_to_le16(RFCOMM_PSM);
        addr.l2_cid    = 0;
        *err = kernel_connect(sock, (struct sockaddr *) &addr, sizeof(addr), O_NONBLOCK);
        if (*err == 0 || *err == -EINPROGRESS)
@@ -852,9 +852,9 @@ static int rfcomm_send_pn(struct rfcomm_session *s, int cr, struct rfcomm_dlc *d
        }
 
        if (cr && channel_mtu >= 0)
-               pn->mtu = htobs(channel_mtu);
+               pn->mtu = cpu_to_le16(channel_mtu);
        else
-               pn->mtu = htobs(d->mtu);
+               pn->mtu = cpu_to_le16(d->mtu);
 
        *ptr = __fcs(buf); ptr++;
 
@@ -1056,7 +1056,7 @@ static void rfcomm_make_uih(struct sk_buff *skb, u8 addr)
 
        if (len > 127) {
                hdr = (void *) skb_push(skb, 4);
-               put_unaligned(htobs(__len16(len)), (__le16 *) &hdr->len);
+               put_unaligned(cpu_to_le16(__len16(len)), (__le16 *) &hdr->len);
        } else {
                hdr = (void *) skb_push(skb, 3);
                hdr->len = __len8(len);
@@ -1289,7 +1289,7 @@ static int rfcomm_apply_pn(struct rfcomm_dlc *d, int cr, struct rfcomm_pn *pn)
 
        d->priority = pn->priority;
 
-       d->mtu = btohs(pn->mtu);
+       d->mtu = __le16_to_cpu(pn->mtu);
 
        if (cr && d->mtu > s->mtu)
                d->mtu = s->mtu;
@@ -1922,7 +1922,7 @@ static int rfcomm_add_listener(bdaddr_t *ba)
        /* Bind socket */
        bacpy(&addr.l2_bdaddr, ba);
        addr.l2_family = AF_BLUETOOTH;
-       addr.l2_psm    = htobs(RFCOMM_PSM);
+       addr.l2_psm    = cpu_to_le16(RFCOMM_PSM);
        addr.l2_cid    = 0;
        err = kernel_bind(sock, (struct sockaddr *) &addr, sizeof(addr));
        if (err < 0) {
index 4d2c1f1cb5243d2d4e7e7713bc411d4d13491e4d..9aac5213105aaf031e5ca1fcc993a051800e1475 100644 (file)
@@ -65,8 +65,9 @@ static int __init br_init(void)
        brioctl_set(br_ioctl_deviceless_stub);
        br_handle_frame_hook = br_handle_frame;
 
-       br_fdb_get_hook = br_fdb_get;
-       br_fdb_put_hook = br_fdb_put;
+#if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE)
+       br_fdb_test_addr_hook = br_fdb_test_addr;
+#endif
 
        return 0;
 err_out4:
@@ -95,8 +96,9 @@ static void __exit br_deinit(void)
        synchronize_net();
 
        br_netfilter_fini();
-       br_fdb_get_hook = NULL;
-       br_fdb_put_hook = NULL;
+#if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE)
+       br_fdb_test_addr_hook = NULL;
+#endif
 
        br_handle_frame_hook = NULL;
        br_fdb_fini();
index a48f5efdb6bfa9b44fb0149136c169857a6e0931..57bf05c353bc804c58cffb5dc060c53850aacf79 100644 (file)
@@ -71,10 +71,17 @@ static inline int br_mac_hash(const unsigned char *mac)
        return jhash_1word(key, fdb_salt) & (BR_HASH_SIZE - 1);
 }
 
+static void fdb_rcu_free(struct rcu_head *head)
+{
+       struct net_bridge_fdb_entry *ent
+               = container_of(head, struct net_bridge_fdb_entry, rcu);
+       kmem_cache_free(br_fdb_cache, ent);
+}
+
 static inline void fdb_delete(struct net_bridge_fdb_entry *f)
 {
        hlist_del_rcu(&f->hlist);
-       br_fdb_put(f);
+       call_rcu(&f->rcu, fdb_rcu_free);
 }
 
 void br_fdb_changeaddr(struct net_bridge_port *p, const unsigned char *newaddr)
@@ -226,33 +233,26 @@ struct net_bridge_fdb_entry *__br_fdb_get(struct net_bridge *br,
        return NULL;
 }
 
-/* Interface used by ATM hook that keeps a ref count */
-struct net_bridge_fdb_entry *br_fdb_get(struct net_bridge *br,
-                                       unsigned char *addr)
+#if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE)
+/* Interface used by ATM LANE hook to test
+ * if an addr is on some other bridge port */
+int br_fdb_test_addr(struct net_device *dev, unsigned char *addr)
 {
        struct net_bridge_fdb_entry *fdb;
+       int ret;
+
+       if (!dev->br_port)
+               return 0;
 
        rcu_read_lock();
-       fdb = __br_fdb_get(br, addr);
-       if (fdb && !atomic_inc_not_zero(&fdb->use_count))
-               fdb = NULL;
+       fdb = __br_fdb_get(dev->br_port->br, addr);
+       ret = fdb && fdb->dst->dev != dev &&
+               fdb->dst->state == BR_STATE_FORWARDING;
        rcu_read_unlock();
-       return fdb;
-}
-
-static void fdb_rcu_free(struct rcu_head *head)
-{
-       struct net_bridge_fdb_entry *ent
-               = container_of(head, struct net_bridge_fdb_entry, rcu);
-       kmem_cache_free(br_fdb_cache, ent);
-}
 
-/* Set entry up for deletion with RCU  */
-void br_fdb_put(struct net_bridge_fdb_entry *ent)
-{
-       if (atomic_dec_and_test(&ent->use_count))
-               call_rcu(&ent->rcu, fdb_rcu_free);
+       return ret;
 }
+#endif /* CONFIG_ATM_LANE */
 
 /*
  * Fill buffer with forwarding table records in
@@ -326,7 +326,6 @@ static struct net_bridge_fdb_entry *fdb_create(struct hlist_head *head,
        fdb = kmem_cache_alloc(br_fdb_cache, GFP_ATOMIC);
        if (fdb) {
                memcpy(fdb->addr.addr, addr, ETH_ALEN);
-               atomic_set(&fdb->use_count, 1);
                hlist_add_head_rcu(&fdb->hlist, head);
 
                fdb->dst = source;
@@ -398,7 +397,7 @@ void br_fdb_update(struct net_bridge *br, struct net_bridge_port *source,
                if (unlikely(fdb->is_local)) {
                        if (net_ratelimit())
                                printk(KERN_WARNING "%s: received packet with "
-                                      " own address as source address\n",
+                                      "own address as source address\n",
                                       source->dev->name);
                } else {
                        /* fastpath: update of existing entry */
index e4a418fcb35bfe3d163210f0ceeb19a09535e64c..d22f611e40041533d8caa4d801b420ff58b265f0 100644 (file)
@@ -228,6 +228,7 @@ int nf_bridge_copy_header(struct sk_buff *skb)
 static int br_nf_pre_routing_finish_ipv6(struct sk_buff *skb)
 {
        struct nf_bridge_info *nf_bridge = skb->nf_bridge;
+       struct rtable *rt;
 
        if (nf_bridge->mask & BRNF_PKT_TYPE) {
                skb->pkt_type = PACKET_OTHERHOST;
@@ -235,12 +236,13 @@ static int br_nf_pre_routing_finish_ipv6(struct sk_buff *skb)
        }
        nf_bridge->mask ^= BRNF_NF_BRIDGE_PREROUTING;
 
-       skb->rtable = bridge_parent_rtable(nf_bridge->physindev);
-       if (!skb->rtable) {
+       rt = bridge_parent_rtable(nf_bridge->physindev);
+       if (!rt) {
                kfree_skb(skb);
                return 0;
        }
-       dst_hold(&skb->rtable->u.dst);
+       dst_hold(&rt->u.dst);
+       skb_dst_set(skb, &rt->u.dst);
 
        skb->dev = nf_bridge->physindev;
        nf_bridge_push_encap_header(skb);
@@ -320,7 +322,7 @@ static int br_nf_pre_routing_finish_bridge(struct sk_buff *skb)
 
        skb->dev = bridge_parent(skb->dev);
        if (skb->dev) {
-               struct dst_entry *dst = skb->dst;
+               struct dst_entry *dst = skb_dst(skb);
 
                nf_bridge_pull_encap_header(skb);
 
@@ -338,6 +340,7 @@ static int br_nf_pre_routing_finish(struct sk_buff *skb)
        struct net_device *dev = skb->dev;
        struct iphdr *iph = ip_hdr(skb);
        struct nf_bridge_info *nf_bridge = skb->nf_bridge;
+       struct rtable *rt;
        int err;
 
        if (nf_bridge->mask & BRNF_PKT_TYPE) {
@@ -347,7 +350,6 @@ static int br_nf_pre_routing_finish(struct sk_buff *skb)
        nf_bridge->mask ^= BRNF_NF_BRIDGE_PREROUTING;
        if (dnat_took_place(skb)) {
                if ((err = ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, dev))) {
-                       struct rtable *rt;
                        struct flowi fl = {
                                .nl_u = {
                                        .ip4_u = {
@@ -373,7 +375,7 @@ static int br_nf_pre_routing_finish(struct sk_buff *skb)
                                /* - Bridged-and-DNAT'ed traffic doesn't
                                 *   require ip_forwarding. */
                                if (((struct dst_entry *)rt)->dev == dev) {
-                                       skb->dst = (struct dst_entry *)rt;
+                                       skb_dst_set(skb, (struct dst_entry *)rt);
                                        goto bridged_dnat;
                                }
                                /* we are sure that forwarding is disabled, so printing
@@ -387,7 +389,7 @@ free_skb:
                        kfree_skb(skb);
                        return 0;
                } else {
-                       if (skb->dst->dev == dev) {
+                       if (skb_dst(skb)->dev == dev) {
 bridged_dnat:
                                /* Tell br_nf_local_out this is a
                                 * bridged frame */
@@ -404,12 +406,13 @@ bridged_dnat:
                        skb->pkt_type = PACKET_HOST;
                }
        } else {
-               skb->rtable = bridge_parent_rtable(nf_bridge->physindev);
-               if (!skb->rtable) {
+               rt = bridge_parent_rtable(nf_bridge->physindev);
+               if (!rt) {
                        kfree_skb(skb);
                        return 0;
                }
-               dst_hold(&skb->rtable->u.dst);
+               dst_hold(&rt->u.dst);
+               skb_dst_set(skb, &rt->u.dst);
        }
 
        skb->dev = nf_bridge->physindev;
@@ -628,10 +631,10 @@ static unsigned int br_nf_local_in(unsigned int hook, struct sk_buff *skb,
                                   const struct net_device *out,
                                   int (*okfn)(struct sk_buff *))
 {
-       if (skb->rtable && skb->rtable == bridge_parent_rtable(in)) {
-               dst_release(&skb->rtable->u.dst);
-               skb->rtable = NULL;
-       }
+       struct rtable *rt = skb_rtable(skb);
+
+       if (rt && rt == bridge_parent_rtable(in))
+               skb_dst_drop(skb);
 
        return NF_ACCEPT;
 }
@@ -846,7 +849,7 @@ static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff *skb,
                return NF_ACCEPT;
 
 #ifdef CONFIG_NETFILTER_DEBUG
-       if (skb->dst == NULL) {
+       if (skb_dst(skb) == NULL) {
                printk(KERN_INFO "br_netfilter post_routing: skb->dst == NULL\n");
                goto print_error;
        }
index b6c3b71974dc3d02da81b94b9f8f113732d6c157..d5b5537272b47af9c1e8abdcc7a693ac6a7e63cd 100644 (file)
@@ -51,7 +51,6 @@ struct net_bridge_fdb_entry
        struct net_bridge_port          *dst;
 
        struct rcu_head                 rcu;
-       atomic_t                        use_count;
        unsigned long                   ageing_timer;
        mac_addr                        addr;
        unsigned char                   is_local;
@@ -154,9 +153,7 @@ extern void br_fdb_delete_by_port(struct net_bridge *br,
                                  const struct net_bridge_port *p, int do_all);
 extern struct net_bridge_fdb_entry *__br_fdb_get(struct net_bridge *br,
                                                 const unsigned char *addr);
-extern struct net_bridge_fdb_entry *br_fdb_get(struct net_bridge *br,
-                                              unsigned char *addr);
-extern void br_fdb_put(struct net_bridge_fdb_entry *ent);
+extern int br_fdb_test_addr(struct net_device *dev, unsigned char *addr);
 extern int br_fdb_fillbuf(struct net_bridge *br, void *buf,
                          unsigned long count, unsigned long off);
 extern int br_fdb_insert(struct net_bridge *br,
@@ -242,10 +239,9 @@ extern void br_stp_port_timer_init(struct net_bridge_port *p);
 extern unsigned long br_timer_value(const struct timer_list *timer);
 
 /* br.c */
-extern struct net_bridge_fdb_entry *(*br_fdb_get_hook)(struct net_bridge *br,
-                                                      unsigned char *addr);
-extern void (*br_fdb_put_hook)(struct net_bridge_fdb_entry *ent);
-
+#if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE)
+extern int (*br_fdb_test_addr_hook)(struct net_device *dev, unsigned char *addr);
+#endif
 
 /* br_netlink.c */
 extern int br_netlink_init(void);
index 603d89248e7148e1a830146953dfbfdcb54491bd..ee4820aa1843ee5e54c1b677f4cd5875a440d442 100644 (file)
@@ -172,7 +172,8 @@ static ssize_t store_stp_state(struct device *d,
        if (endp == buf)
                return -EINVAL;
 
-       rtnl_lock();
+       if (!rtnl_trylock())
+               return restart_syscall();
        br_stp_set_enabled(br, val);
        rtnl_unlock();
 
index 02b2d50cce4da640f4b62a6652253d217e890af2..4a3cdf8f38131e6b19adf330a0e697a307a39e16 100644 (file)
@@ -189,7 +189,8 @@ static ssize_t brport_store(struct kobject * kobj,
 
        val = simple_strtoul(buf, &endp, 0);
        if (endp != buf) {
-               rtnl_lock();
+               if (!rtnl_trylock())
+                       return restart_syscall();
                if (p->dev && p->br && brport_attr->store) {
                        spin_lock_bh(&p->br->lock);
                        ret = brport_attr->store(p, val);
index 820252aee81f1c1f59bba3cf3e666c2e494b5812..37928d5f284024b871604462fbfa04bc037c61a9 100644 (file)
@@ -142,6 +142,12 @@ static inline int ebt_basic_match(struct ebt_entry *e, struct ethhdr *h,
        return 0;
 }
 
+static inline __pure
+struct ebt_entry *ebt_next_entry(const struct ebt_entry *entry)
+{
+       return (void *)entry + entry->next_offset;
+}
+
 /* Do some firewalling */
 unsigned int ebt_do_table (unsigned int hook, struct sk_buff *skb,
    const struct net_device *in, const struct net_device *out,
@@ -164,7 +170,7 @@ unsigned int ebt_do_table (unsigned int hook, struct sk_buff *skb,
        mtpar.in      = tgpar.in  = in;
        mtpar.out     = tgpar.out = out;
        mtpar.hotdrop = &hotdrop;
-       tgpar.hooknum = hook;
+       mtpar.hooknum = tgpar.hooknum = hook;
 
        read_lock_bh(&table->lock);
        private = table->private;
@@ -249,8 +255,7 @@ letsreturn:
                /* jump to a udc */
                cs[sp].n = i + 1;
                cs[sp].chaininfo = chaininfo;
-               cs[sp].e = (struct ebt_entry *)
-                  (((char *)point) + point->next_offset);
+               cs[sp].e = ebt_next_entry(point);
                i = 0;
                chaininfo = (struct ebt_entries *) (base + verdict);
 #ifdef CONFIG_NETFILTER_DEBUG
@@ -266,8 +271,7 @@ letsreturn:
                sp++;
                continue;
 letscontinue:
-               point = (struct ebt_entry *)
-                  (((char *)point) + point->next_offset);
+               point = ebt_next_entry(point);
                i++;
        }
 
@@ -787,7 +791,7 @@ static int check_chainloops(struct ebt_entries *chain, struct ebt_cl_stack *cl_s
                        /* this can't be 0, so the loop test is correct */
                        cl_s[i].cs.n = pos + 1;
                        pos = 0;
-                       cl_s[i].cs.e = ((void *)e + e->next_offset);
+                       cl_s[i].cs.e = ebt_next_entry(e);
                        e = (struct ebt_entry *)(hlp2->data);
                        nentries = hlp2->nentries;
                        cl_s[i].from = chain_nr;
@@ -797,7 +801,7 @@ static int check_chainloops(struct ebt_entries *chain, struct ebt_cl_stack *cl_s
                        continue;
                }
 letscontinue:
-               e = (void *)e + e->next_offset;
+               e = ebt_next_entry(e);
                pos++;
        }
        return 0;
index 10f0528c3bf59c746de18f52f42e937edc9e9a48..e733725b11d4cdbc1010e65bc441fa2723bdb132 100644 (file)
@@ -903,6 +903,8 @@ static __exit void can_exit(void)
        }
        spin_unlock(&can_rcvlists_lock);
 
+       rcu_barrier(); /* Wait for completion of call_rcu()'s */
+
        kmem_cache_destroy(rcv_cache);
 }
 
index b01a76abe1d2f99dc577064037e4b4a1cb9ecd82..58abee1f1df1b044514079f9245dc7c1b96978a3 100644 (file)
@@ -260,7 +260,9 @@ int skb_kill_datagram(struct sock *sk, struct sk_buff *skb, unsigned int flags)
                spin_unlock_bh(&sk->sk_receive_queue.lock);
        }
 
-       skb_free_datagram(sk, skb);
+       kfree_skb(skb);
+       sk_mem_reclaim_partial(sk);
+
        return err;
 }
 
@@ -280,6 +282,7 @@ int skb_copy_datagram_iovec(const struct sk_buff *skb, int offset,
 {
        int start = skb_headlen(skb);
        int i, copy = start - offset;
+       struct sk_buff *frag_iter;
 
        /* Copy header. */
        if (copy > 0) {
@@ -320,28 +323,24 @@ int skb_copy_datagram_iovec(const struct sk_buff *skb, int offset,
                start = end;
        }
 
-       if (skb_shinfo(skb)->frag_list) {
-               struct sk_buff *list = skb_shinfo(skb)->frag_list;
-
-               for (; list; list = list->next) {
-                       int end;
-
-                       WARN_ON(start > offset + len);
-
-                       end = start + list->len;
-                       if ((copy = end - offset) > 0) {
-                               if (copy > len)
-                                       copy = len;
-                               if (skb_copy_datagram_iovec(list,
-                                                           offset - start,
-                                                           to, copy))
-                                       goto fault;
-                               if ((len -= copy) == 0)
-                                       return 0;
-                               offset += copy;
-                       }
-                       start = end;
+       skb_walk_frags(skb, frag_iter) {
+               int end;
+
+               WARN_ON(start > offset + len);
+
+               end = start + frag_iter->len;
+               if ((copy = end - offset) > 0) {
+                       if (copy > len)
+                               copy = len;
+                       if (skb_copy_datagram_iovec(frag_iter,
+                                                   offset - start,
+                                                   to, copy))
+                               goto fault;
+                       if ((len -= copy) == 0)
+                               return 0;
+                       offset += copy;
                }
+               start = end;
        }
        if (!len)
                return 0;
@@ -350,31 +349,125 @@ fault:
        return -EFAULT;
 }
 
+/**
+ *     skb_copy_datagram_const_iovec - Copy a datagram to an iovec.
+ *     @skb: buffer to copy
+ *     @offset: offset in the buffer to start copying from
+ *     @to: io vector to copy to
+ *     @to_offset: offset in the io vector to start copying to
+ *     @len: amount of data to copy from buffer to iovec
+ *
+ *     Returns 0 or -EFAULT.
+ *     Note: the iovec is not modified during the copy.
+ */
+int skb_copy_datagram_const_iovec(const struct sk_buff *skb, int offset,
+                                 const struct iovec *to, int to_offset,
+                                 int len)
+{
+       int start = skb_headlen(skb);
+       int i, copy = start - offset;
+       struct sk_buff *frag_iter;
+
+       /* Copy header. */
+       if (copy > 0) {
+               if (copy > len)
+                       copy = len;
+               if (memcpy_toiovecend(to, skb->data + offset, to_offset, copy))
+                       goto fault;
+               if ((len -= copy) == 0)
+                       return 0;
+               offset += copy;
+               to_offset += copy;
+       }
+
+       /* Copy paged appendix. Hmm... why does this look so complicated? */
+       for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+               int end;
+
+               WARN_ON(start > offset + len);
+
+               end = start + skb_shinfo(skb)->frags[i].size;
+               if ((copy = end - offset) > 0) {
+                       int err;
+                       u8  *vaddr;
+                       skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+                       struct page *page = frag->page;
+
+                       if (copy > len)
+                               copy = len;
+                       vaddr = kmap(page);
+                       err = memcpy_toiovecend(to, vaddr + frag->page_offset +
+                                               offset - start, to_offset, copy);
+                       kunmap(page);
+                       if (err)
+                               goto fault;
+                       if (!(len -= copy))
+                               return 0;
+                       offset += copy;
+                       to_offset += copy;
+               }
+               start = end;
+       }
+
+       skb_walk_frags(skb, frag_iter) {
+               int end;
+
+               WARN_ON(start > offset + len);
+
+               end = start + frag_iter->len;
+               if ((copy = end - offset) > 0) {
+                       if (copy > len)
+                               copy = len;
+                       if (skb_copy_datagram_const_iovec(frag_iter,
+                                                         offset - start,
+                                                         to, to_offset,
+                                                         copy))
+                               goto fault;
+                       if ((len -= copy) == 0)
+                               return 0;
+                       offset += copy;
+                       to_offset += copy;
+               }
+               start = end;
+       }
+       if (!len)
+               return 0;
+
+fault:
+       return -EFAULT;
+}
+EXPORT_SYMBOL(skb_copy_datagram_const_iovec);
+
 /**
  *     skb_copy_datagram_from_iovec - Copy a datagram from an iovec.
  *     @skb: buffer to copy
  *     @offset: offset in the buffer to start copying to
  *     @from: io vector to copy to
+ *     @from_offset: offset in the io vector to start copying from
  *     @len: amount of data to copy to buffer from iovec
  *
  *     Returns 0 or -EFAULT.
- *     Note: the iovec is modified during the copy.
+ *     Note: the iovec is not modified during the copy.
  */
 int skb_copy_datagram_from_iovec(struct sk_buff *skb, int offset,
-                                struct iovec *from, int len)
+                                const struct iovec *from, int from_offset,
+                                int len)
 {
        int start = skb_headlen(skb);
        int i, copy = start - offset;
+       struct sk_buff *frag_iter;
 
        /* Copy header. */
        if (copy > 0) {
                if (copy > len)
                        copy = len;
-               if (memcpy_fromiovec(skb->data + offset, from, copy))
+               if (memcpy_fromiovecend(skb->data + offset, from, from_offset,
+                                       copy))
                        goto fault;
                if ((len -= copy) == 0)
                        return 0;
                offset += copy;
+               from_offset += copy;
        }
 
        /* Copy paged appendix. Hmm... why does this look so complicated? */
@@ -393,8 +486,9 @@ int skb_copy_datagram_from_iovec(struct sk_buff *skb, int offset,
                        if (copy > len)
                                copy = len;
                        vaddr = kmap(page);
-                       err = memcpy_fromiovec(vaddr + frag->page_offset +
-                                              offset - start, from, copy);
+                       err = memcpy_fromiovecend(vaddr + frag->page_offset +
+                                                 offset - start,
+                                                 from, from_offset, copy);
                        kunmap(page);
                        if (err)
                                goto fault;
@@ -402,32 +496,32 @@ int skb_copy_datagram_from_iovec(struct sk_buff *skb, int offset,
                        if (!(len -= copy))
                                return 0;
                        offset += copy;
+                       from_offset += copy;
                }
                start = end;
        }
 
-       if (skb_shinfo(skb)->frag_list) {
-               struct sk_buff *list = skb_shinfo(skb)->frag_list;
-
-               for (; list; list = list->next) {
-                       int end;
-
-                       WARN_ON(start > offset + len);
-
-                       end = start + list->len;
-                       if ((copy = end - offset) > 0) {
-                               if (copy > len)
-                                       copy = len;
-                               if (skb_copy_datagram_from_iovec(list,
-                                                                offset - start,
-                                                                from, copy))
-                                       goto fault;
-                               if ((len -= copy) == 0)
-                                       return 0;
-                               offset += copy;
-                       }
-                       start = end;
+       skb_walk_frags(skb, frag_iter) {
+               int end;
+
+               WARN_ON(start > offset + len);
+
+               end = start + frag_iter->len;
+               if ((copy = end - offset) > 0) {
+                       if (copy > len)
+                               copy = len;
+                       if (skb_copy_datagram_from_iovec(frag_iter,
+                                                        offset - start,
+                                                        from,
+                                                        from_offset,
+                                                        copy))
+                               goto fault;
+                       if ((len -= copy) == 0)
+                               return 0;
+                       offset += copy;
+                       from_offset += copy;
                }
+               start = end;
        }
        if (!len)
                return 0;
@@ -442,8 +536,9 @@ static int skb_copy_and_csum_datagram(const struct sk_buff *skb, int offset,
                                      __wsum *csump)
 {
        int start = skb_headlen(skb);
-       int pos = 0;
        int i, copy = start - offset;
+       struct sk_buff *frag_iter;
+       int pos = 0;
 
        /* Copy header. */
        if (copy > 0) {
@@ -494,33 +589,29 @@ static int skb_copy_and_csum_datagram(const struct sk_buff *skb, int offset,
                start = end;
        }
 
-       if (skb_shinfo(skb)->frag_list) {
-               struct sk_buff *list = skb_shinfo(skb)->frag_list;
-
-               for (; list; list=list->next) {
-                       int end;
-
-                       WARN_ON(start > offset + len);
-
-                       end = start + list->len;
-                       if ((copy = end - offset) > 0) {
-                               __wsum csum2 = 0;
-                               if (copy > len)
-                                       copy = len;
-                               if (skb_copy_and_csum_datagram(list,
-                                                              offset - start,
-                                                              to, copy,
-                                                              &csum2))
-                                       goto fault;
-                               *csump = csum_block_add(*csump, csum2, pos);
-                               if ((len -= copy) == 0)
-                                       return 0;
-                               offset += copy;
-                               to += copy;
-                               pos += copy;
-                       }
-                       start = end;
+       skb_walk_frags(skb, frag_iter) {
+               int end;
+
+               WARN_ON(start > offset + len);
+
+               end = start + frag_iter->len;
+               if ((copy = end - offset) > 0) {
+                       __wsum csum2 = 0;
+                       if (copy > len)
+                               copy = len;
+                       if (skb_copy_and_csum_datagram(frag_iter,
+                                                      offset - start,
+                                                      to, copy,
+                                                      &csum2))
+                               goto fault;
+                       *csump = csum_block_add(*csump, csum2, pos);
+                       if ((len -= copy) == 0)
+                               return 0;
+                       offset += copy;
+                       to += copy;
+                       pos += copy;
                }
+               start = end;
        }
        if (!len)
                return 0;
index e2e9e4af3ace6c2975ebab961f20c5bbf3aa0157..576a61574a936fcab9a7608d2d83c677127aebb6 100644 (file)
 #include <linux/in.h>
 #include <linux/jhash.h>
 #include <linux/random.h>
+#include <trace/events/napi.h>
 
 #include "net-sysfs.h"
 
@@ -268,7 +269,8 @@ static const unsigned short netdev_lock_type[] =
         ARPHRD_IRDA, ARPHRD_FCPP, ARPHRD_FCAL, ARPHRD_FCPL,
         ARPHRD_FCFABRIC, ARPHRD_IEEE802_TR, ARPHRD_IEEE80211,
         ARPHRD_IEEE80211_PRISM, ARPHRD_IEEE80211_RADIOTAP, ARPHRD_PHONET,
-        ARPHRD_PHONET_PIPE, ARPHRD_VOID, ARPHRD_NONE};
+        ARPHRD_PHONET_PIPE, ARPHRD_IEEE802154, ARPHRD_IEEE802154_PHY,
+        ARPHRD_VOID, ARPHRD_NONE};
 
 static const char *netdev_lock_name[] =
        {"_xmit_NETROM", "_xmit_ETHER", "_xmit_EETHER", "_xmit_AX25",
@@ -285,7 +287,8 @@ static const char *netdev_lock_name[] =
         "_xmit_IRDA", "_xmit_FCPP", "_xmit_FCAL", "_xmit_FCPL",
         "_xmit_FCFABRIC", "_xmit_IEEE802_TR", "_xmit_IEEE80211",
         "_xmit_IEEE80211_PRISM", "_xmit_IEEE80211_RADIOTAP", "_xmit_PHONET",
-        "_xmit_PHONET_PIPE", "_xmit_VOID", "_xmit_NONE"};
+        "_xmit_PHONET_PIPE", "_xmit_IEEE802154", "_xmit_IEEE802154_PHY",
+        "_xmit_VOID", "_xmit_NONE"};
 
 static struct lock_class_key netdev_xmit_lock_key[ARRAY_SIZE(netdev_lock_type)];
 static struct lock_class_key netdev_addr_lock_key[ARRAY_SIZE(netdev_lock_type)];
@@ -1047,7 +1050,7 @@ void dev_load(struct net *net, const char *name)
 int dev_open(struct net_device *dev)
 {
        const struct net_device_ops *ops = dev->netdev_ops;
-       int ret = 0;
+       int ret;
 
        ASSERT_RTNL();
 
@@ -1064,6 +1067,11 @@ int dev_open(struct net_device *dev)
        if (!netif_device_present(dev))
                return -ENODEV;
 
+       ret = call_netdevice_notifiers(NETDEV_PRE_UP, dev);
+       ret = notifier_to_errno(ret);
+       if (ret)
+               return ret;
+
        /*
         *      Call device private open method
         */
@@ -1688,7 +1696,16 @@ int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev,
                                goto gso;
                }
 
+               /*
+                * If device doesnt need skb->dst, release it right now while
+                * its hot in this cpu cache
+                */
+               if (dev->priv_flags & IFF_XMIT_DST_RELEASE)
+                       skb_dst_drop(skb);
+
                rc = ops->ndo_start_xmit(skb, dev);
+               if (rc == 0)
+                       txq_trans_update(txq);
                /*
                 * TODO: if skb_orphan() was called by
                 * dev->hard_start_xmit() (for example, the unmodified
@@ -1718,6 +1735,7 @@ gso:
                        skb->next = nskb;
                        return rc;
                }
+               txq_trans_update(txq);
                if (unlikely(netif_tx_queue_stopped(txq) && skb->next))
                        return NETDEV_TX_BUSY;
        } while (skb->next);
@@ -1735,8 +1753,12 @@ u16 skb_tx_hash(const struct net_device *dev, const struct sk_buff *skb)
 {
        u32 hash;
 
-       if (skb_rx_queue_recorded(skb))
-               return skb_get_rx_queue(skb) % dev->real_num_tx_queues;
+       if (skb_rx_queue_recorded(skb)) {
+               hash = skb_get_rx_queue(skb);
+               while (unlikely (hash >= dev->real_num_tx_queues))
+                       hash -= dev->real_num_tx_queues;
+               return hash;
+       }
 
        if (skb->sk && skb->sk->sk_hash)
                hash = skb->sk->sk_hash;
@@ -1800,7 +1822,7 @@ int dev_queue_xmit(struct sk_buff *skb)
        if (netif_needs_gso(dev, skb))
                goto gso;
 
-       if (skb_shinfo(skb)->frag_list &&
+       if (skb_has_frags(skb) &&
            !(dev->features & NETIF_F_FRAGLIST) &&
            __skb_linearize(skb))
                goto out_kfree_skb;
@@ -2049,11 +2071,13 @@ static inline int deliver_skb(struct sk_buff *skb,
 }
 
 #if defined(CONFIG_BRIDGE) || defined (CONFIG_BRIDGE_MODULE)
-/* These hooks defined here for ATM */
-struct net_bridge;
-struct net_bridge_fdb_entry *(*br_fdb_get_hook)(struct net_bridge *br,
-                                               unsigned char *addr);
-void (*br_fdb_put_hook)(struct net_bridge_fdb_entry *ent) __read_mostly;
+
+#if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE)
+/* This hook is defined here for ATM LANE */
+int (*br_fdb_test_addr_hook)(struct net_device *dev,
+                            unsigned char *addr) __read_mostly;
+EXPORT_SYMBOL(br_fdb_test_addr_hook);
+#endif
 
 /*
  * If bridge module is loaded call bridging hook.
@@ -2061,6 +2085,8 @@ void (*br_fdb_put_hook)(struct net_bridge_fdb_entry *ent) __read_mostly;
  */
 struct sk_buff *(*br_handle_frame_hook)(struct net_bridge_port *p,
                                        struct sk_buff *skb) __read_mostly;
+EXPORT_SYMBOL(br_handle_frame_hook);
+
 static inline struct sk_buff *handle_bridge(struct sk_buff *skb,
                                            struct packet_type **pt_prev, int *ret,
                                            struct net_device *orig_dev)
@@ -2374,26 +2400,6 @@ void napi_gro_flush(struct napi_struct *napi)
 }
 EXPORT_SYMBOL(napi_gro_flush);
 
-void *skb_gro_header(struct sk_buff *skb, unsigned int hlen)
-{
-       unsigned int offset = skb_gro_offset(skb);
-
-       hlen += offset;
-       if (hlen <= skb_headlen(skb))
-               return skb->data + offset;
-
-       if (unlikely(!skb_shinfo(skb)->nr_frags ||
-                    skb_shinfo(skb)->frags[0].size <=
-                    hlen - skb_headlen(skb) ||
-                    PageHighMem(skb_shinfo(skb)->frags[0].page)))
-               return pskb_may_pull(skb, hlen) ? skb->data + offset : NULL;
-
-       return page_address(skb_shinfo(skb)->frags[0].page) +
-              skb_shinfo(skb)->frags[0].page_offset +
-              offset - skb_headlen(skb);
-}
-EXPORT_SYMBOL(skb_gro_header);
-
 int dev_gro_receive(struct napi_struct *napi, struct sk_buff *skb)
 {
        struct sk_buff **pp = NULL;
@@ -2407,7 +2413,7 @@ int dev_gro_receive(struct napi_struct *napi, struct sk_buff *skb)
        if (!(skb->dev->features & NETIF_F_GRO))
                goto normal;
 
-       if (skb_is_gso(skb) || skb_shinfo(skb)->frag_list)
+       if (skb_is_gso(skb) || skb_has_frags(skb))
                goto normal;
 
        rcu_read_lock();
@@ -2456,10 +2462,25 @@ int dev_gro_receive(struct napi_struct *napi, struct sk_buff *skb)
        ret = GRO_HELD;
 
 pull:
-       if (unlikely(!pskb_may_pull(skb, skb_gro_offset(skb)))) {
-               if (napi->gro_list == skb)
-                       napi->gro_list = skb->next;
-               ret = GRO_DROP;
+       if (skb_headlen(skb) < skb_gro_offset(skb)) {
+               int grow = skb_gro_offset(skb) - skb_headlen(skb);
+
+               BUG_ON(skb->end - skb->tail < grow);
+
+               memcpy(skb_tail_pointer(skb), NAPI_GRO_CB(skb)->frag0, grow);
+
+               skb->tail += grow;
+               skb->data_len -= grow;
+
+               skb_shinfo(skb)->frags[0].page_offset += grow;
+               skb_shinfo(skb)->frags[0].size -= grow;
+
+               if (unlikely(!skb_shinfo(skb)->frags[0].size)) {
+                       put_page(skb_shinfo(skb)->frags[0].page);
+                       memmove(skb_shinfo(skb)->frags,
+                               skb_shinfo(skb)->frags + 1,
+                               --skb_shinfo(skb)->nr_frags);
+               }
        }
 
 ok:
@@ -2509,6 +2530,22 @@ int napi_skb_finish(int ret, struct sk_buff *skb)
 }
 EXPORT_SYMBOL(napi_skb_finish);
 
+void skb_gro_reset_offset(struct sk_buff *skb)
+{
+       NAPI_GRO_CB(skb)->data_offset = 0;
+       NAPI_GRO_CB(skb)->frag0 = NULL;
+       NAPI_GRO_CB(skb)->frag0_len = 0;
+
+       if (skb->mac_header == skb->tail &&
+           !PageHighMem(skb_shinfo(skb)->frags[0].page)) {
+               NAPI_GRO_CB(skb)->frag0 =
+                       page_address(skb_shinfo(skb)->frags[0].page) +
+                       skb_shinfo(skb)->frags[0].page_offset;
+               NAPI_GRO_CB(skb)->frag0_len = skb_shinfo(skb)->frags[0].size;
+       }
+}
+EXPORT_SYMBOL(skb_gro_reset_offset);
+
 int napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb)
 {
        skb_gro_reset_offset(skb);
@@ -2526,16 +2563,10 @@ void napi_reuse_skb(struct napi_struct *napi, struct sk_buff *skb)
 }
 EXPORT_SYMBOL(napi_reuse_skb);
 
-struct sk_buff *napi_fraginfo_skb(struct napi_struct *napi,
-                                 struct napi_gro_fraginfo *info)
+struct sk_buff *napi_get_frags(struct napi_struct *napi)
 {
        struct net_device *dev = napi->dev;
        struct sk_buff *skb = napi->skb;
-       struct ethhdr *eth;
-       skb_frag_t *frag;
-       int i;
-
-       napi->skb = NULL;
 
        if (!skb) {
                skb = netdev_alloc_skb(dev, GRO_MAX_HEAD + NET_IP_ALIGN);
@@ -2543,47 +2574,14 @@ struct sk_buff *napi_fraginfo_skb(struct napi_struct *napi,
                        goto out;
 
                skb_reserve(skb, NET_IP_ALIGN);
-       }
 
-       BUG_ON(info->nr_frags > MAX_SKB_FRAGS);
-       frag = info->frags;
-
-       for (i = 0; i < info->nr_frags; i++) {
-               skb_fill_page_desc(skb, i, frag->page, frag->page_offset,
-                                  frag->size);
-               frag++;
-       }
-       skb_shinfo(skb)->nr_frags = info->nr_frags;
-
-       skb->data_len = info->len;
-       skb->len += info->len;
-       skb->truesize += info->len;
-
-       skb_reset_mac_header(skb);
-       skb_gro_reset_offset(skb);
-
-       eth = skb_gro_header(skb, sizeof(*eth));
-       if (!eth) {
-               napi_reuse_skb(napi, skb);
-               skb = NULL;
-               goto out;
+               napi->skb = skb;
        }
 
-       skb_gro_pull(skb, sizeof(*eth));
-
-       /*
-        * This works because the only protocols we care about don't require
-        * special handling.  We'll fix it up properly at the end.
-        */
-       skb->protocol = eth->h_proto;
-
-       skb->ip_summed = info->ip_summed;
-       skb->csum = info->csum;
-
 out:
        return skb;
 }
-EXPORT_SYMBOL(napi_fraginfo_skb);
+EXPORT_SYMBOL(napi_get_frags);
 
 int napi_frags_finish(struct napi_struct *napi, struct sk_buff *skb, int ret)
 {
@@ -2613,9 +2611,46 @@ int napi_frags_finish(struct napi_struct *napi, struct sk_buff *skb, int ret)
 }
 EXPORT_SYMBOL(napi_frags_finish);
 
-int napi_gro_frags(struct napi_struct *napi, struct napi_gro_fraginfo *info)
+struct sk_buff *napi_frags_skb(struct napi_struct *napi)
 {
-       struct sk_buff *skb = napi_fraginfo_skb(napi, info);
+       struct sk_buff *skb = napi->skb;
+       struct ethhdr *eth;
+       unsigned int hlen;
+       unsigned int off;
+
+       napi->skb = NULL;
+
+       skb_reset_mac_header(skb);
+       skb_gro_reset_offset(skb);
+
+       off = skb_gro_offset(skb);
+       hlen = off + sizeof(*eth);
+       eth = skb_gro_header_fast(skb, off);
+       if (skb_gro_header_hard(skb, hlen)) {
+               eth = skb_gro_header_slow(skb, hlen, off);
+               if (unlikely(!eth)) {
+                       napi_reuse_skb(napi, skb);
+                       skb = NULL;
+                       goto out;
+               }
+       }
+
+       skb_gro_pull(skb, sizeof(*eth));
+
+       /*
+        * This works because the only protocols we care about don't require
+        * special handling.  We'll fix it up properly at the end.
+        */
+       skb->protocol = eth->h_proto;
+
+out:
+       return skb;
+}
+EXPORT_SYMBOL(napi_frags_skb);
+
+int napi_gro_frags(struct napi_struct *napi)
+{
+       struct sk_buff *skb = napi_frags_skb(napi);
 
        if (!skb)
                return NET_RX_DROP;
@@ -2719,7 +2754,7 @@ void netif_napi_del(struct napi_struct *napi)
        struct sk_buff *skb, *next;
 
        list_del_init(&napi->dev_list);
-       kfree_skb(napi->skb);
+       napi_free_frags(napi);
 
        for (skb = napi->gro_list; skb; skb = next) {
                next = skb->next;
@@ -2773,8 +2808,10 @@ static void net_rx_action(struct softirq_action *h)
                 * accidently calling ->poll() when NAPI is not scheduled.
                 */
                work = 0;
-               if (test_bit(NAPI_STATE_SCHED, &n->state))
+               if (test_bit(NAPI_STATE_SCHED, &n->state)) {
                        work = n->poll(n, weight);
+                       trace_napi_poll(n);
+               }
 
                WARN_ON_ONCE(work > weight);
 
@@ -3444,6 +3481,319 @@ void dev_set_rx_mode(struct net_device *dev)
        netif_addr_unlock_bh(dev);
 }
 
+/* hw addresses list handling functions */
+
+static int __hw_addr_add(struct list_head *list, int *delta,
+                        unsigned char *addr, int addr_len,
+                        unsigned char addr_type)
+{
+       struct netdev_hw_addr *ha;
+       int alloc_size;
+
+       if (addr_len > MAX_ADDR_LEN)
+               return -EINVAL;
+
+       list_for_each_entry(ha, list, list) {
+               if (!memcmp(ha->addr, addr, addr_len) &&
+                   ha->type == addr_type) {
+                       ha->refcount++;
+                       return 0;
+               }
+       }
+
+
+       alloc_size = sizeof(*ha);
+       if (alloc_size < L1_CACHE_BYTES)
+               alloc_size = L1_CACHE_BYTES;
+       ha = kmalloc(alloc_size, GFP_ATOMIC);
+       if (!ha)
+               return -ENOMEM;
+       memcpy(ha->addr, addr, addr_len);
+       ha->type = addr_type;
+       ha->refcount = 1;
+       ha->synced = false;
+       list_add_tail_rcu(&ha->list, list);
+       if (delta)
+               (*delta)++;
+       return 0;
+}
+
+static void ha_rcu_free(struct rcu_head *head)
+{
+       struct netdev_hw_addr *ha;
+
+       ha = container_of(head, struct netdev_hw_addr, rcu_head);
+       kfree(ha);
+}
+
+static int __hw_addr_del(struct list_head *list, int *delta,
+                        unsigned char *addr, int addr_len,
+                        unsigned char addr_type)
+{
+       struct netdev_hw_addr *ha;
+
+       list_for_each_entry(ha, list, list) {
+               if (!memcmp(ha->addr, addr, addr_len) &&
+                   (ha->type == addr_type || !addr_type)) {
+                       if (--ha->refcount)
+                               return 0;
+                       list_del_rcu(&ha->list);
+                       call_rcu(&ha->rcu_head, ha_rcu_free);
+                       if (delta)
+                               (*delta)--;
+                       return 0;
+               }
+       }
+       return -ENOENT;
+}
+
+static int __hw_addr_add_multiple(struct list_head *to_list, int *to_delta,
+                                 struct list_head *from_list, int addr_len,
+                                 unsigned char addr_type)
+{
+       int err;
+       struct netdev_hw_addr *ha, *ha2;
+       unsigned char type;
+
+       list_for_each_entry(ha, from_list, list) {
+               type = addr_type ? addr_type : ha->type;
+               err = __hw_addr_add(to_list, to_delta, ha->addr,
+                                   addr_len, type);
+               if (err)
+                       goto unroll;
+       }
+       return 0;
+
+unroll:
+       list_for_each_entry(ha2, from_list, list) {
+               if (ha2 == ha)
+                       break;
+               type = addr_type ? addr_type : ha2->type;
+               __hw_addr_del(to_list, to_delta, ha2->addr,
+                             addr_len, type);
+       }
+       return err;
+}
+
+static void __hw_addr_del_multiple(struct list_head *to_list, int *to_delta,
+                                  struct list_head *from_list, int addr_len,
+                                  unsigned char addr_type)
+{
+       struct netdev_hw_addr *ha;
+       unsigned char type;
+
+       list_for_each_entry(ha, from_list, list) {
+               type = addr_type ? addr_type : ha->type;
+               __hw_addr_del(to_list, to_delta, ha->addr,
+                             addr_len, addr_type);
+       }
+}
+
+static int __hw_addr_sync(struct list_head *to_list, int *to_delta,
+                         struct list_head *from_list, int *from_delta,
+                         int addr_len)
+{
+       int err = 0;
+       struct netdev_hw_addr *ha, *tmp;
+
+       list_for_each_entry_safe(ha, tmp, from_list, list) {
+               if (!ha->synced) {
+                       err = __hw_addr_add(to_list, to_delta, ha->addr,
+                                           addr_len, ha->type);
+                       if (err)
+                               break;
+                       ha->synced = true;
+                       ha->refcount++;
+               } else if (ha->refcount == 1) {
+                       __hw_addr_del(to_list, to_delta, ha->addr,
+                                     addr_len, ha->type);
+                       __hw_addr_del(from_list, from_delta, ha->addr,
+                                     addr_len, ha->type);
+               }
+       }
+       return err;
+}
+
+static void __hw_addr_unsync(struct list_head *to_list, int *to_delta,
+                            struct list_head *from_list, int *from_delta,
+                            int addr_len)
+{
+       struct netdev_hw_addr *ha, *tmp;
+
+       list_for_each_entry_safe(ha, tmp, from_list, list) {
+               if (ha->synced) {
+                       __hw_addr_del(to_list, to_delta, ha->addr,
+                                     addr_len, ha->type);
+                       ha->synced = false;
+                       __hw_addr_del(from_list, from_delta, ha->addr,
+                                     addr_len, ha->type);
+               }
+       }
+}
+
+
+static void __hw_addr_flush(struct list_head *list)
+{
+       struct netdev_hw_addr *ha, *tmp;
+
+       list_for_each_entry_safe(ha, tmp, list, list) {
+               list_del_rcu(&ha->list);
+               call_rcu(&ha->rcu_head, ha_rcu_free);
+       }
+}
+
+/* Device addresses handling functions */
+
+static void dev_addr_flush(struct net_device *dev)
+{
+       /* rtnl_mutex must be held here */
+
+       __hw_addr_flush(&dev->dev_addr_list);
+       dev->dev_addr = NULL;
+}
+
+static int dev_addr_init(struct net_device *dev)
+{
+       unsigned char addr[MAX_ADDR_LEN];
+       struct netdev_hw_addr *ha;
+       int err;
+
+       /* rtnl_mutex must be held here */
+
+       INIT_LIST_HEAD(&dev->dev_addr_list);
+       memset(addr, 0, sizeof(addr));
+       err = __hw_addr_add(&dev->dev_addr_list, NULL, addr, sizeof(addr),
+                           NETDEV_HW_ADDR_T_LAN);
+       if (!err) {
+               /*
+                * Get the first (previously created) address from the list
+                * and set dev_addr pointer to this location.
+                */
+               ha = list_first_entry(&dev->dev_addr_list,
+                                     struct netdev_hw_addr, list);
+               dev->dev_addr = ha->addr;
+       }
+       return err;
+}
+
+/**
+ *     dev_addr_add    - Add a device address
+ *     @dev: device
+ *     @addr: address to add
+ *     @addr_type: address type
+ *
+ *     Add a device address to the device or increase the reference count if
+ *     it already exists.
+ *
+ *     The caller must hold the rtnl_mutex.
+ */
+int dev_addr_add(struct net_device *dev, unsigned char *addr,
+                unsigned char addr_type)
+{
+       int err;
+
+       ASSERT_RTNL();
+
+       err = __hw_addr_add(&dev->dev_addr_list, NULL, addr, dev->addr_len,
+                           addr_type);
+       if (!err)
+               call_netdevice_notifiers(NETDEV_CHANGEADDR, dev);
+       return err;
+}
+EXPORT_SYMBOL(dev_addr_add);
+
+/**
+ *     dev_addr_del    - Release a device address.
+ *     @dev: device
+ *     @addr: address to delete
+ *     @addr_type: address type
+ *
+ *     Release reference to a device address and remove it from the device
+ *     if the reference count drops to zero.
+ *
+ *     The caller must hold the rtnl_mutex.
+ */
+int dev_addr_del(struct net_device *dev, unsigned char *addr,
+                unsigned char addr_type)
+{
+       int err;
+       struct netdev_hw_addr *ha;
+
+       ASSERT_RTNL();
+
+       /*
+        * We can not remove the first address from the list because
+        * dev->dev_addr points to that.
+        */
+       ha = list_first_entry(&dev->dev_addr_list, struct netdev_hw_addr, list);
+       if (ha->addr == dev->dev_addr && ha->refcount == 1)
+               return -ENOENT;
+
+       err = __hw_addr_del(&dev->dev_addr_list, NULL, addr, dev->addr_len,
+                           addr_type);
+       if (!err)
+               call_netdevice_notifiers(NETDEV_CHANGEADDR, dev);
+       return err;
+}
+EXPORT_SYMBOL(dev_addr_del);
+
+/**
+ *     dev_addr_add_multiple   - Add device addresses from another device
+ *     @to_dev: device to which addresses will be added
+ *     @from_dev: device from which addresses will be added
+ *     @addr_type: address type - 0 means type will be used from from_dev
+ *
+ *     Add device addresses of the one device to another.
+ **
+ *     The caller must hold the rtnl_mutex.
+ */
+int dev_addr_add_multiple(struct net_device *to_dev,
+                         struct net_device *from_dev,
+                         unsigned char addr_type)
+{
+       int err;
+
+       ASSERT_RTNL();
+
+       if (from_dev->addr_len != to_dev->addr_len)
+               return -EINVAL;
+       err = __hw_addr_add_multiple(&to_dev->dev_addr_list, NULL,
+                                    &from_dev->dev_addr_list,
+                                    to_dev->addr_len, addr_type);
+       if (!err)
+               call_netdevice_notifiers(NETDEV_CHANGEADDR, to_dev);
+       return err;
+}
+EXPORT_SYMBOL(dev_addr_add_multiple);
+
+/**
+ *     dev_addr_del_multiple   - Delete device addresses by another device
+ *     @to_dev: device where the addresses will be deleted
+ *     @from_dev: device by which addresses the addresses will be deleted
+ *     @addr_type: address type - 0 means type will used from from_dev
+ *
+ *     Deletes addresses in to device by the list of addresses in from device.
+ *
+ *     The caller must hold the rtnl_mutex.
+ */
+int dev_addr_del_multiple(struct net_device *to_dev,
+                         struct net_device *from_dev,
+                         unsigned char addr_type)
+{
+       ASSERT_RTNL();
+
+       if (from_dev->addr_len != to_dev->addr_len)
+               return -EINVAL;
+       __hw_addr_del_multiple(&to_dev->dev_addr_list, NULL,
+                              &from_dev->dev_addr_list,
+                              to_dev->addr_len, addr_type);
+       call_netdevice_notifiers(NETDEV_CHANGEADDR, to_dev);
+       return 0;
+}
+EXPORT_SYMBOL(dev_addr_del_multiple);
+
+/* unicast and multicast addresses handling functions */
+
 int __dev_addr_delete(struct dev_addr_list **list, int *count,
                      void *addr, int alen, int glbl)
 {
@@ -3506,24 +3856,22 @@ int __dev_addr_add(struct dev_addr_list **list, int *count,
  *     dev_unicast_delete      - Release secondary unicast address.
  *     @dev: device
  *     @addr: address to delete
- *     @alen: length of @addr
  *
  *     Release reference to a secondary unicast address and remove it
  *     from the device if the reference count drops to zero.
  *
  *     The caller must hold the rtnl_mutex.
  */
-int dev_unicast_delete(struct net_device *dev, void *addr, int alen)
+int dev_unicast_delete(struct net_device *dev, void *addr)
 {
        int err;
 
        ASSERT_RTNL();
 
-       netif_addr_lock_bh(dev);
-       err = __dev_addr_delete(&dev->uc_list, &dev->uc_count, addr, alen, 0);
+       err = __hw_addr_del(&dev->uc_list, &dev->uc_count, addr,
+                           dev->addr_len, NETDEV_HW_ADDR_T_UNICAST);
        if (!err)
                __dev_set_rx_mode(dev);
-       netif_addr_unlock_bh(dev);
        return err;
 }
 EXPORT_SYMBOL(dev_unicast_delete);
@@ -3532,24 +3880,22 @@ EXPORT_SYMBOL(dev_unicast_delete);
  *     dev_unicast_add         - add a secondary unicast address
  *     @dev: device
  *     @addr: address to add
- *     @alen: length of @addr
  *
  *     Add a secondary unicast address to the device or increase
  *     the reference count if it already exists.
  *
  *     The caller must hold the rtnl_mutex.
  */
-int dev_unicast_add(struct net_device *dev, void *addr, int alen)
+int dev_unicast_add(struct net_device *dev, void *addr)
 {
        int err;
 
        ASSERT_RTNL();
 
-       netif_addr_lock_bh(dev);
-       err = __dev_addr_add(&dev->uc_list, &dev->uc_count, addr, alen, 0);
+       err = __hw_addr_add(&dev->uc_list, &dev->uc_count, addr,
+                           dev->addr_len, NETDEV_HW_ADDR_T_UNICAST);
        if (!err)
                __dev_set_rx_mode(dev);
-       netif_addr_unlock_bh(dev);
        return err;
 }
 EXPORT_SYMBOL(dev_unicast_add);
@@ -3606,8 +3952,7 @@ void __dev_addr_unsync(struct dev_addr_list **to, int *to_count,
  *     @from: source device
  *
  *     Add newly added addresses to the destination device and release
- *     addresses that have no users left. The source device must be
- *     locked by netif_tx_lock_bh.
+ *     addresses that have no users left.
  *
  *     This function is intended to be called from the dev->set_rx_mode
  *     function of layered software devices.
@@ -3616,12 +3961,15 @@ int dev_unicast_sync(struct net_device *to, struct net_device *from)
 {
        int err = 0;
 
-       netif_addr_lock_bh(to);
-       err = __dev_addr_sync(&to->uc_list, &to->uc_count,
-                             &from->uc_list, &from->uc_count);
+       ASSERT_RTNL();
+
+       if (to->addr_len != from->addr_len)
+               return -EINVAL;
+
+       err = __hw_addr_sync(&to->uc_list, &to->uc_count,
+                            &from->uc_list, &from->uc_count, to->addr_len);
        if (!err)
                __dev_set_rx_mode(to);
-       netif_addr_unlock_bh(to);
        return err;
 }
 EXPORT_SYMBOL(dev_unicast_sync);
@@ -3637,18 +3985,33 @@ EXPORT_SYMBOL(dev_unicast_sync);
  */
 void dev_unicast_unsync(struct net_device *to, struct net_device *from)
 {
-       netif_addr_lock_bh(from);
-       netif_addr_lock(to);
+       ASSERT_RTNL();
 
-       __dev_addr_unsync(&to->uc_list, &to->uc_count,
-                         &from->uc_list, &from->uc_count);
-       __dev_set_rx_mode(to);
+       if (to->addr_len != from->addr_len)
+               return;
 
-       netif_addr_unlock(to);
-       netif_addr_unlock_bh(from);
+       __hw_addr_unsync(&to->uc_list, &to->uc_count,
+                        &from->uc_list, &from->uc_count, to->addr_len);
+       __dev_set_rx_mode(to);
 }
 EXPORT_SYMBOL(dev_unicast_unsync);
 
+static void dev_unicast_flush(struct net_device *dev)
+{
+       /* rtnl_mutex must be held here */
+
+       __hw_addr_flush(&dev->uc_list);
+       dev->uc_count = 0;
+}
+
+static void dev_unicast_init(struct net_device *dev)
+{
+       /* rtnl_mutex must be held here */
+
+       INIT_LIST_HEAD(&dev->uc_list);
+}
+
+
 static void __dev_addr_discard(struct dev_addr_list **list)
 {
        struct dev_addr_list *tmp;
@@ -3667,9 +4030,6 @@ static void dev_addr_discard(struct net_device *dev)
 {
        netif_addr_lock_bh(dev);
 
-       __dev_addr_discard(&dev->uc_list);
-       dev->uc_count = 0;
-
        __dev_addr_discard(&dev->mc_list);
        dev->mc_count = 0;
 
@@ -3853,7 +4213,7 @@ static int dev_ifsioc_locked(struct net *net, struct ifreq *ifr, unsigned int cm
 
        switch (cmd) {
                case SIOCGIFFLAGS:      /* Get interface flags */
-                       ifr->ifr_flags = dev_get_flags(dev);
+                       ifr->ifr_flags = (short) dev_get_flags(dev);
                        return 0;
 
                case SIOCGIFMETRIC:     /* Get the metric on the interface
@@ -4262,6 +4622,7 @@ static void rollback_registered(struct net_device *dev)
        /*
         *      Flush the unicast and multicast chains
         */
+       dev_unicast_flush(dev);
        dev_addr_discard(dev);
 
        if (dev->netdev_ops->ndo_uninit)
@@ -4333,39 +4694,6 @@ unsigned long netdev_fix_features(unsigned long features, const char *name)
 }
 EXPORT_SYMBOL(netdev_fix_features);
 
-/* Some devices need to (re-)set their netdev_ops inside
- * ->init() or similar.  If that happens, we have to setup
- * the compat pointers again.
- */
-void netdev_resync_ops(struct net_device *dev)
-{
-#ifdef CONFIG_COMPAT_NET_DEV_OPS
-       const struct net_device_ops *ops = dev->netdev_ops;
-
-       dev->init = ops->ndo_init;
-       dev->uninit = ops->ndo_uninit;
-       dev->open = ops->ndo_open;
-       dev->change_rx_flags = ops->ndo_change_rx_flags;
-       dev->set_rx_mode = ops->ndo_set_rx_mode;
-       dev->set_multicast_list = ops->ndo_set_multicast_list;
-       dev->set_mac_address = ops->ndo_set_mac_address;
-       dev->validate_addr = ops->ndo_validate_addr;
-       dev->do_ioctl = ops->ndo_do_ioctl;
-       dev->set_config = ops->ndo_set_config;
-       dev->change_mtu = ops->ndo_change_mtu;
-       dev->neigh_setup = ops->ndo_neigh_setup;
-       dev->tx_timeout = ops->ndo_tx_timeout;
-       dev->get_stats = ops->ndo_get_stats;
-       dev->vlan_rx_register = ops->ndo_vlan_rx_register;
-       dev->vlan_rx_add_vid = ops->ndo_vlan_rx_add_vid;
-       dev->vlan_rx_kill_vid = ops->ndo_vlan_rx_kill_vid;
-#ifdef CONFIG_NET_POLL_CONTROLLER
-       dev->poll_controller = ops->ndo_poll_controller;
-#endif
-#endif
-}
-EXPORT_SYMBOL(netdev_resync_ops);
-
 /**
  *     register_netdevice      - register a network device
  *     @dev: device to register
@@ -4405,23 +4733,6 @@ int register_netdevice(struct net_device *dev)
 
        dev->iflink = -1;
 
-#ifdef CONFIG_COMPAT_NET_DEV_OPS
-       /* Netdevice_ops API compatibility support.
-        * This is temporary until all network devices are converted.
-        */
-       if (dev->netdev_ops) {
-               netdev_resync_ops(dev);
-       } else {
-               char drivername[64];
-               pr_info("%s (%s): not using net_device_ops yet\n",
-                       dev->name, netdev_drivername(dev, drivername, 64));
-
-               /* This works only because net_device_ops and the
-                  compatibility structure are the same. */
-               dev->netdev_ops = (void *) &(dev->init);
-       }
-#endif
-
        /* Init, if this function is available */
        if (dev->netdev_ops->ndo_init) {
                ret = dev->netdev_ops->ndo_init(dev);
@@ -4707,13 +5018,30 @@ void netdev_run_todo(void)
  *     the internal statistics structure is used.
  */
 const struct net_device_stats *dev_get_stats(struct net_device *dev)
- {
+{
        const struct net_device_ops *ops = dev->netdev_ops;
 
        if (ops->ndo_get_stats)
                return ops->ndo_get_stats(dev);
-       else
-               return &dev->stats;
+       else {
+               unsigned long tx_bytes = 0, tx_packets = 0, tx_dropped = 0;
+               struct net_device_stats *stats = &dev->stats;
+               unsigned int i;
+               struct netdev_queue *txq;
+
+               for (i = 0; i < dev->num_tx_queues; i++) {
+                       txq = netdev_get_tx_queue(dev, i);
+                       tx_bytes   += txq->tx_bytes;
+                       tx_packets += txq->tx_packets;
+                       tx_dropped += txq->tx_dropped;
+               }
+               if (tx_bytes || tx_packets || tx_dropped) {
+                       stats->tx_bytes   = tx_bytes;
+                       stats->tx_packets = tx_packets;
+                       stats->tx_dropped = tx_dropped;
+               }
+               return stats;
+       }
 }
 EXPORT_SYMBOL(dev_get_stats);
 
@@ -4748,18 +5076,18 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name,
        struct netdev_queue *tx;
        struct net_device *dev;
        size_t alloc_size;
-       void *p;
+       struct net_device *p;
 
        BUG_ON(strlen(name) >= sizeof(dev->name));
 
        alloc_size = sizeof(struct net_device);
        if (sizeof_priv) {
                /* ensure 32-byte alignment of private area */
-               alloc_size = (alloc_size + NETDEV_ALIGN_CONST) & ~NETDEV_ALIGN_CONST;
+               alloc_size = ALIGN(alloc_size, NETDEV_ALIGN);
                alloc_size += sizeof_priv;
        }
        /* ensure 32-byte alignment of whole construct */
-       alloc_size += NETDEV_ALIGN_CONST;
+       alloc_size += NETDEV_ALIGN - 1;
 
        p = kzalloc(alloc_size, GFP_KERNEL);
        if (!p) {
@@ -4771,13 +5099,17 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name,
        if (!tx) {
                printk(KERN_ERR "alloc_netdev: Unable to allocate "
                       "tx qdiscs.\n");
-               kfree(p);
-               return NULL;
+               goto free_p;
        }
 
-       dev = (struct net_device *)
-               (((long)p + NETDEV_ALIGN_CONST) & ~NETDEV_ALIGN_CONST);
+       dev = PTR_ALIGN(p, NETDEV_ALIGN);
        dev->padded = (char *)dev - (char *)p;
+
+       if (dev_addr_init(dev))
+               goto free_tx;
+
+       dev_unicast_init(dev);
+
        dev_net_set(dev, &init_net);
 
        dev->_tx = tx;
@@ -4789,9 +5121,17 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name,
        netdev_init_queues(dev);
 
        INIT_LIST_HEAD(&dev->napi_list);
+       dev->priv_flags = IFF_XMIT_DST_RELEASE;
        setup(dev);
        strcpy(dev->name, name);
        return dev;
+
+free_tx:
+       kfree(tx);
+
+free_p:
+       kfree(p);
+       return NULL;
 }
 EXPORT_SYMBOL(alloc_netdev_mq);
 
@@ -4811,6 +5151,9 @@ void free_netdev(struct net_device *dev)
 
        kfree(dev->_tx);
 
+       /* Flush device addresses */
+       dev_addr_flush(dev);
+
        list_for_each_entry_safe(p, n, &dev->napi_list, dev_list)
                netif_napi_del(p);
 
@@ -4970,6 +5313,7 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char
        /*
         *      Flush the unicast and multicast chains
         */
+       dev_unicast_flush(dev);
        dev_addr_discard(dev);
 
        netdev_unregister_kobject(dev);
@@ -5325,12 +5669,6 @@ EXPORT_SYMBOL(net_enable_timestamp);
 EXPORT_SYMBOL(net_disable_timestamp);
 EXPORT_SYMBOL(dev_get_flags);
 
-#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
-EXPORT_SYMBOL(br_handle_frame_hook);
-EXPORT_SYMBOL(br_fdb_get_hook);
-EXPORT_SYMBOL(br_fdb_put_hook);
-#endif
-
 EXPORT_SYMBOL(dev_load);
 
 EXPORT_PER_CPU_SYMBOL(softnet_data);
index b75b6cea49dab47cbca9098a259ac44e4e51b4c8..9d66fa953ab7bdbb160090e3544e038dff658eae 100644 (file)
 #include <linux/timer.h>
 #include <linux/bitops.h>
 #include <net/genetlink.h>
+#include <net/netevent.h>
 
 #include <trace/events/skb.h>
+#include <trace/events/napi.h>
 
 #include <asm/unaligned.h>
 
@@ -38,7 +40,8 @@ static void send_dm_alert(struct work_struct *unused);
  * and the work handle that will send up
  * netlink alerts
  */
-struct sock *dm_sock;
+static int trace_state = TRACE_OFF;
+static spinlock_t trace_state_lock = SPIN_LOCK_UNLOCKED;
 
 struct per_cpu_dm_data {
        struct work_struct dm_alert_work;
@@ -47,11 +50,18 @@ struct per_cpu_dm_data {
        struct timer_list send_timer;
 };
 
+struct dm_hw_stat_delta {
+       struct net_device *dev;
+       struct list_head list;
+       struct rcu_head rcu;
+       unsigned long last_drop_val;
+};
+
 static struct genl_family net_drop_monitor_family = {
        .id             = GENL_ID_GENERATE,
        .hdrsize        = 0,
        .name           = "NET_DM",
-       .version        = 1,
+       .version        = 2,
        .maxattr        = NET_DM_CMD_MAX,
 };
 
@@ -59,19 +69,24 @@ static DEFINE_PER_CPU(struct per_cpu_dm_data, dm_cpu_data);
 
 static int dm_hit_limit = 64;
 static int dm_delay = 1;
-
+static unsigned long dm_hw_check_delta = 2*HZ;
+static LIST_HEAD(hw_stats_list);
 
 static void reset_per_cpu_data(struct per_cpu_dm_data *data)
 {
        size_t al;
        struct net_dm_alert_msg *msg;
+       struct nlattr *nla;
 
        al = sizeof(struct net_dm_alert_msg);
        al += dm_hit_limit * sizeof(struct net_dm_drop_point);
+       al += sizeof(struct nlattr);
+
        data->skb = genlmsg_new(al, GFP_KERNEL);
        genlmsg_put(data->skb, 0, 0, &net_drop_monitor_family,
                        0, NET_DM_CMD_ALERT);
-       msg = __nla_reserve_nohdr(data->skb, sizeof(struct net_dm_alert_msg));
+       nla = nla_reserve(data->skb, NLA_UNSPEC, sizeof(struct net_dm_alert_msg));
+       msg = nla_data(nla);
        memset(msg, 0, al);
        atomic_set(&data->dm_hit_count, dm_hit_limit);
 }
@@ -111,10 +126,11 @@ static void sched_send_work(unsigned long unused)
        schedule_work(&data->dm_alert_work);
 }
 
-static void trace_kfree_skb_hit(struct sk_buff *skb, void *location)
+static void trace_drop_common(struct sk_buff *skb, void *location)
 {
        struct net_dm_alert_msg *msg;
        struct nlmsghdr *nlh;
+       struct nlattr *nla;
        int i;
        struct per_cpu_dm_data *data = &__get_cpu_var(dm_cpu_data);
 
@@ -127,7 +143,8 @@ static void trace_kfree_skb_hit(struct sk_buff *skb, void *location)
        }
 
        nlh = (struct nlmsghdr *)data->skb->data;
-       msg = genlmsg_data(nlmsg_data(nlh));
+       nla = genlmsg_data(nlmsg_data(nlh));
+       msg = nla_data(nla);
        for (i = 0; i < msg->entries; i++) {
                if (!memcmp(&location, msg->points[i].pc, sizeof(void *))) {
                        msg->points[i].count++;
@@ -139,6 +156,7 @@ static void trace_kfree_skb_hit(struct sk_buff *skb, void *location)
         * We need to create a new entry
         */
        __nla_reserve_nohdr(data->skb, sizeof(struct net_dm_drop_point));
+       nla->nla_len += NLA_ALIGN(sizeof(struct net_dm_drop_point));
        memcpy(msg->points[msg->entries].pc, &location, sizeof(void *));
        msg->points[msg->entries].count = 1;
        msg->entries++;
@@ -152,24 +170,80 @@ out:
        return;
 }
 
+static void trace_kfree_skb_hit(struct sk_buff *skb, void *location)
+{
+       trace_drop_common(skb, location);
+}
+
+static void trace_napi_poll_hit(struct napi_struct *napi)
+{
+       struct dm_hw_stat_delta *new_stat;
+
+       /*
+        * Ratelimit our check time to dm_hw_check_delta jiffies
+        */
+       if (!time_after(jiffies, napi->dev->last_rx + dm_hw_check_delta))
+               return;
+
+       rcu_read_lock();
+       list_for_each_entry_rcu(new_stat, &hw_stats_list, list) {
+               if ((new_stat->dev == napi->dev)  &&
+                   (napi->dev->stats.rx_dropped != new_stat->last_drop_val)) {
+                       trace_drop_common(NULL, NULL);
+                       new_stat->last_drop_val = napi->dev->stats.rx_dropped;
+                       break;
+               }
+       }
+       rcu_read_unlock();
+}
+
+
+static void free_dm_hw_stat(struct rcu_head *head)
+{
+       struct dm_hw_stat_delta *n;
+       n = container_of(head, struct dm_hw_stat_delta, rcu);
+       kfree(n);
+}
+
 static int set_all_monitor_traces(int state)
 {
        int rc = 0;
+       struct dm_hw_stat_delta *new_stat = NULL;
+       struct dm_hw_stat_delta *temp;
+
+       spin_lock(&trace_state_lock);
 
        switch (state) {
        case TRACE_ON:
                rc |= register_trace_kfree_skb(trace_kfree_skb_hit);
+               rc |= register_trace_napi_poll(trace_napi_poll_hit);
                break;
        case TRACE_OFF:
                rc |= unregister_trace_kfree_skb(trace_kfree_skb_hit);
+               rc |= unregister_trace_napi_poll(trace_napi_poll_hit);
 
                tracepoint_synchronize_unregister();
+
+               /*
+                * Clean the device list
+                */
+               list_for_each_entry_safe(new_stat, temp, &hw_stats_list, list) {
+                       if (new_stat->dev == NULL) {
+                               list_del_rcu(&new_stat->list);
+                               call_rcu(&new_stat->rcu, free_dm_hw_stat);
+                       }
+               }
                break;
        default:
                rc = 1;
                break;
        }
 
+       if (!rc)
+               trace_state = state;
+
+       spin_unlock(&trace_state_lock);
+
        if (rc)
                return -EINPROGRESS;
        return rc;
@@ -197,6 +271,44 @@ static int net_dm_cmd_trace(struct sk_buff *skb,
        return -ENOTSUPP;
 }
 
+static int dropmon_net_event(struct notifier_block *ev_block,
+                       unsigned long event, void *ptr)
+{
+       struct net_device *dev = ptr;
+       struct dm_hw_stat_delta *new_stat = NULL;
+       struct dm_hw_stat_delta *tmp;
+
+       switch (event) {
+       case NETDEV_REGISTER:
+               new_stat = kzalloc(sizeof(struct dm_hw_stat_delta), GFP_KERNEL);
+
+               if (!new_stat)
+                       goto out;
+
+               new_stat->dev = dev;
+               INIT_RCU_HEAD(&new_stat->rcu);
+               spin_lock(&trace_state_lock);
+               list_add_rcu(&new_stat->list, &hw_stats_list);
+               spin_unlock(&trace_state_lock);
+               break;
+       case NETDEV_UNREGISTER:
+               spin_lock(&trace_state_lock);
+               list_for_each_entry_safe(new_stat, tmp, &hw_stats_list, list) {
+                       if (new_stat->dev == dev) {
+                               new_stat->dev = NULL;
+                               if (trace_state == TRACE_OFF) {
+                                       list_del_rcu(&new_stat->list);
+                                       call_rcu(&new_stat->rcu, free_dm_hw_stat);
+                                       break;
+                               }
+                       }
+               }
+               spin_unlock(&trace_state_lock);
+               break;
+       }
+out:
+       return NOTIFY_DONE;
+}
 
 static struct genl_ops dropmon_ops[] = {
        {
@@ -213,6 +325,10 @@ static struct genl_ops dropmon_ops[] = {
        },
 };
 
+static struct notifier_block dropmon_net_notifier = {
+       .notifier_call = dropmon_net_event
+};
+
 static int __init init_net_drop_monitor(void)
 {
        int cpu;
@@ -236,12 +352,18 @@ static int __init init_net_drop_monitor(void)
                ret = genl_register_ops(&net_drop_monitor_family,
                                        &dropmon_ops[i]);
                if (ret) {
-                       printk(KERN_CRIT "failed to register operation %d\n",
+                       printk(KERN_CRIT "Failed to register operation %d\n",
                                dropmon_ops[i].cmd);
                        goto out_unreg;
                }
        }
 
+       rc = register_netdevice_notifier(&dropmon_net_notifier);
+       if (rc < 0) {
+               printk(KERN_CRIT "Failed to register netdevice notifier\n");
+               goto out_unreg;
+       }
+
        rc = 0;
 
        for_each_present_cpu(cpu) {
@@ -252,6 +374,7 @@ static int __init init_net_drop_monitor(void)
                data->send_timer.data = cpu;
                data->send_timer.function = sched_send_work;
        }
+
        goto out;
 
 out_unreg:
index 98691e1466b80699b664983e5403b4b1a3a19db2..bd309384f8b82dcb928c8236cc2901d39f9cee9f 100644 (file)
@@ -299,7 +299,7 @@ static int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
        } else if (rule->action == FR_ACT_GOTO)
                goto errout_free;
 
-       err = ops->configure(rule, skb, nlh, frh, tb);
+       err = ops->configure(rule, skb, frh, tb);
        if (err < 0)
                goto errout_free;
 
@@ -500,7 +500,7 @@ static int fib_nl_fill_rule(struct sk_buff *skb, struct fib_rule *rule,
        if (rule->target)
                NLA_PUT_U32(skb, FRA_GOTO, rule->target);
 
-       if (ops->fill(rule, skb, nlh, frh) < 0)
+       if (ops->fill(rule, skb, frh) < 0)
                goto nla_put_failure;
 
        return nlmsg_end(skb, nlh);
index 6d62d4618cfc66a5c106e331b3eca0e85ff41f28..78e5bfc454ae00e627705515cbd857cd3d9c67d9 100644 (file)
@@ -128,12 +128,12 @@ static void est_timer(unsigned long arg)
                npackets = e->bstats->packets;
                brate = (nbytes - e->last_bytes)<<(7 - idx);
                e->last_bytes = nbytes;
-               e->avbps += ((s64)(brate - e->avbps)) >> e->ewma_log;
+               e->avbps += (brate >> e->ewma_log) - (e->avbps >> e->ewma_log);
                e->rate_est->bps = (e->avbps+0xF)>>5;
 
                rate = (npackets - e->last_packets)<<(12 - idx);
                e->last_packets = npackets;
-               e->avpps += ((long)rate - (long)e->avpps) >> e->ewma_log;
+               e->avpps += (rate >> e->ewma_log) - (e->avpps >> e->ewma_log);
                e->rate_est->pps = (e->avpps+0x1FF)>>10;
 skip:
                read_unlock(&est_lock);
index 4c9c0121c9dae3c70a6fe99d57d6111bfa7545e3..16ad45d4882b56a2c531a0a944bc31c690ff5a4b 100644 (file)
@@ -97,6 +97,31 @@ int memcpy_toiovec(struct iovec *iov, unsigned char *kdata, int len)
        return 0;
 }
 
+/*
+ *     Copy kernel to iovec. Returns -EFAULT on error.
+ */
+
+int memcpy_toiovecend(const struct iovec *iov, unsigned char *kdata,
+                     int offset, int len)
+{
+       int copy;
+       for (; len > 0; ++iov) {
+               /* Skip over the finished iovecs */
+               if (unlikely(offset >= iov->iov_len)) {
+                       offset -= iov->iov_len;
+                       continue;
+               }
+               copy = min_t(unsigned int, iov->iov_len - offset, len);
+               if (copy_to_user(iov->iov_base + offset, kdata, copy))
+                       return -EFAULT;
+               offset = 0;
+               kdata += copy;
+               len -= copy;
+       }
+
+       return 0;
+}
+
 /*
  *     Copy iovec to kernel. Returns -EFAULT on error.
  *
@@ -122,10 +147,11 @@ int memcpy_fromiovec(unsigned char *kdata, struct iovec *iov, int len)
 }
 
 /*
- *     For use with ip_build_xmit
+ *     Copy iovec from kernel. Returns -EFAULT on error.
  */
-int memcpy_fromiovecend(unsigned char *kdata, struct iovec *iov, int offset,
-                       int len)
+
+int memcpy_fromiovecend(unsigned char *kdata, const struct iovec *iov,
+                       int offset, int len)
 {
        /* Skip over the finished iovecs */
        while (offset >= iov->iov_len) {
@@ -236,3 +262,4 @@ EXPORT_SYMBOL(csum_partial_copy_fromiovecend);
 EXPORT_SYMBOL(memcpy_fromiovec);
 EXPORT_SYMBOL(memcpy_fromiovecend);
 EXPORT_SYMBOL(memcpy_toiovec);
+EXPORT_SYMBOL(memcpy_toiovecend);
index a1cbce7fdae5851f6534f433eb0aa3be3a06e1e6..163b4f5b03656952e9db99f7092050463dc11af7 100644 (file)
@@ -771,6 +771,28 @@ static __inline__ int neigh_max_probes(struct neighbour *n)
                p->ucast_probes + p->app_probes + p->mcast_probes);
 }
 
+static void neigh_invalidate(struct neighbour *neigh)
+{
+       struct sk_buff *skb;
+
+       NEIGH_CACHE_STAT_INC(neigh->tbl, res_failed);
+       NEIGH_PRINTK2("neigh %p is failed.\n", neigh);
+       neigh->updated = jiffies;
+
+       /* It is very thin place. report_unreachable is very complicated
+          routine. Particularly, it can hit the same neighbour entry!
+
+          So that, we try to be accurate and avoid dead loop. --ANK
+        */
+       while (neigh->nud_state == NUD_FAILED &&
+              (skb = __skb_dequeue(&neigh->arp_queue)) != NULL) {
+               write_unlock(&neigh->lock);
+               neigh->ops->error_report(neigh, skb);
+               write_lock(&neigh->lock);
+       }
+       skb_queue_purge(&neigh->arp_queue);
+}
+
 /* Called when a timer expires for a neighbour entry. */
 
 static void neigh_timer_handler(unsigned long arg)
@@ -835,26 +857,9 @@ static void neigh_timer_handler(unsigned long arg)
 
        if ((neigh->nud_state & (NUD_INCOMPLETE | NUD_PROBE)) &&
            atomic_read(&neigh->probes) >= neigh_max_probes(neigh)) {
-               struct sk_buff *skb;
-
                neigh->nud_state = NUD_FAILED;
-               neigh->updated = jiffies;
                notify = 1;
-               NEIGH_CACHE_STAT_INC(neigh->tbl, res_failed);
-               NEIGH_PRINTK2("neigh %p is failed.\n", neigh);
-
-               /* It is very thin place. report_unreachable is very complicated
-                  routine. Particularly, it can hit the same neighbour entry!
-
-                  So that, we try to be accurate and avoid dead loop. --ANK
-                */
-               while (neigh->nud_state == NUD_FAILED &&
-                      (skb = __skb_dequeue(&neigh->arp_queue)) != NULL) {
-                       write_unlock(&neigh->lock);
-                       neigh->ops->error_report(neigh, skb);
-                       write_lock(&neigh->lock);
-               }
-               skb_queue_purge(&neigh->arp_queue);
+               neigh_invalidate(neigh);
        }
 
        if (neigh->nud_state & NUD_IN_TIMER) {
@@ -1001,6 +1006,11 @@ int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new,
                neigh->nud_state = new;
                err = 0;
                notify = old & NUD_VALID;
+               if ((old & (NUD_INCOMPLETE | NUD_PROBE)) &&
+                   (new & NUD_FAILED)) {
+                       neigh_invalidate(neigh);
+                       notify = 1;
+               }
                goto out;
        }
 
@@ -1088,8 +1098,8 @@ int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new,
                        struct neighbour *n1 = neigh;
                        write_unlock_bh(&neigh->lock);
                        /* On shaper/eql skb->dst->neighbour != neigh :( */
-                       if (skb->dst && skb->dst->neighbour)
-                               n1 = skb->dst->neighbour;
+                       if (skb_dst(skb) && skb_dst(skb)->neighbour)
+                               n1 = skb_dst(skb)->neighbour;
                        n1->output(skb);
                        write_lock_bh(&neigh->lock);
                }
@@ -1182,7 +1192,7 @@ EXPORT_SYMBOL(neigh_compat_output);
 
 int neigh_resolve_output(struct sk_buff *skb)
 {
-       struct dst_entry *dst = skb->dst;
+       struct dst_entry *dst = skb_dst(skb);
        struct neighbour *neigh;
        int rc = 0;
 
@@ -1229,7 +1239,7 @@ EXPORT_SYMBOL(neigh_resolve_output);
 int neigh_connected_output(struct sk_buff *skb)
 {
        int err;
-       struct dst_entry *dst = skb->dst;
+       struct dst_entry *dst = skb_dst(skb);
        struct neighbour *neigh = dst->neighbour;
        struct net_device *dev = neigh->dev;
 
@@ -1298,8 +1308,7 @@ void pneigh_enqueue(struct neigh_table *tbl, struct neigh_parms *p,
                if (time_before(tbl->proxy_timer.expires, sched_next))
                        sched_next = tbl->proxy_timer.expires;
        }
-       dst_release(skb->dst);
-       skb->dst = NULL;
+       skb_dst_drop(skb);
        dev_hold(skb->dev);
        __skb_queue_tail(&tbl->proxy_queue, skb);
        mod_timer(&tbl->proxy_timer, sched_next);
index 2da59a0ac4ac4a527f3db356893b614ed0a0a585..3994680c08b976f1d54a626f2ed14bcac770684c 100644 (file)
@@ -78,7 +78,7 @@ static ssize_t netdev_store(struct device *dev, struct device_attribute *attr,
                goto err;
 
        if (!rtnl_trylock())
-               return -ERESTARTSYS;
+               return restart_syscall();
 
        if (dev_isalive(net)) {
                if ((ret = (*set)(net, new)) == 0)
@@ -225,7 +225,8 @@ static ssize_t store_ifalias(struct device *dev, struct device_attribute *attr,
        if (len >  0 && buf[len - 1] == '\n')
                --count;
 
-       rtnl_lock();
+       if (!rtnl_trylock())
+               return restart_syscall();
        ret = dev_set_alias(netdev, buf, count);
        rtnl_unlock();
 
@@ -238,7 +239,8 @@ static ssize_t show_ifalias(struct device *dev,
        const struct net_device *netdev = to_net_dev(dev);
        ssize_t ret = 0;
 
-       rtnl_lock();
+       if (!rtnl_trylock())
+               return restart_syscall();
        if (netdev->ifalias)
                ret = sprintf(buf, "%s\n", netdev->ifalias);
        rtnl_unlock();
@@ -497,7 +499,6 @@ int netdev_register_kobject(struct net_device *net)
        dev->platform_data = net;
        dev->groups = groups;
 
-       BUILD_BUG_ON(BUS_ID_SIZE < IFNAMSIZ);
        dev_set_name(dev, "%s", net->name);
 
 #ifdef CONFIG_SYSFS
index 499a67eaf3ae201262c4a2e53f20870721b8f184..f1e982c508bb16df812024014d953c184e777247 100644 (file)
@@ -25,5 +25,8 @@
 
 #define CREATE_TRACE_POINTS
 #include <trace/events/skb.h>
+#include <trace/events/napi.h>
 
 EXPORT_TRACEPOINT_SYMBOL_GPL(kfree_skb);
+
+EXPORT_TRACEPOINT_SYMBOL_GPL(napi_poll);
index e3bebd36f053ef5ad656b7ea81fa1a03e0c2dc74..b7292a2719dc046bd6772cbd8ee4926e811d0254 100644 (file)
@@ -115,41 +115,34 @@ static void net_free(struct net *net)
        kmem_cache_free(net_cachep, net);
 }
 
-struct net *copy_net_ns(unsigned long flags, struct net *old_net)
+static struct net *net_create(void)
 {
-       struct net *new_net = NULL;
-       int err;
-
-       get_net(old_net);
-
-       if (!(flags & CLONE_NEWNET))
-               return old_net;
-
-       err = -ENOMEM;
-       new_net = net_alloc();
-       if (!new_net)
-               goto out_err;
+       struct net *net;
+       int rv;
 
+       net = net_alloc();
+       if (!net)
+               return ERR_PTR(-ENOMEM);
        mutex_lock(&net_mutex);
-       err = setup_net(new_net);
-       if (!err) {
+       rv = setup_net(net);
+       if (rv == 0) {
                rtnl_lock();
-               list_add_tail(&new_net->list, &net_namespace_list);
+               list_add_tail(&net->list, &net_namespace_list);
                rtnl_unlock();
        }
        mutex_unlock(&net_mutex);
+       if (rv < 0) {
+               net_free(net);
+               return ERR_PTR(rv);
+       }
+       return net;
+}
 
-       if (err)
-               goto out_free;
-out:
-       put_net(old_net);
-       return new_net;
-
-out_free:
-       net_free(new_net);
-out_err:
-       new_net = ERR_PTR(err);
-       goto out;
+struct net *copy_net_ns(unsigned long flags, struct net *old_net)
+{
+       if (!(flags & CLONE_NEWNET))
+               return get_net(old_net);
+       return net_create();
 }
 
 static void cleanup_net(struct work_struct *work)
@@ -203,9 +196,7 @@ struct net *copy_net_ns(unsigned long flags, struct net *old_net)
 static int __init net_ns_init(void)
 {
        struct net_generic *ng;
-       int err;
 
-       printk(KERN_INFO "net_namespace: %zd bytes\n", sizeof(struct net));
 #ifdef CONFIG_NET_NS
        net_cachep = kmem_cache_create("net_namespace", sizeof(struct net),
                                        SMP_CACHE_BYTES,
@@ -224,15 +215,14 @@ static int __init net_ns_init(void)
        rcu_assign_pointer(init_net.gen, ng);
 
        mutex_lock(&net_mutex);
-       err = setup_net(&init_net);
+       if (setup_net(&init_net))
+               panic("Could not setup the initial network namespace");
 
        rtnl_lock();
        list_add_tail(&init_net.list, &net_namespace_list);
        rtnl_unlock();
 
        mutex_unlock(&net_mutex);
-       if (err)
-               panic("Could not setup the initial network namespace");
 
        return 0;
 }
index 64f51eec6576290e3b2df361316ee5448396642d..9675f312830dd762bcd530eee90569de5a89b320 100644 (file)
@@ -24,6 +24,7 @@
 #include <net/tcp.h>
 #include <net/udp.h>
 #include <asm/unaligned.h>
+#include <trace/events/napi.h>
 
 /*
  * We maintain a small pool of fully-sized skbs, to make sure the
@@ -137,6 +138,7 @@ static int poll_one_napi(struct netpoll_info *npinfo,
        set_bit(NAPI_STATE_NPSVC, &napi->state);
 
        work = napi->poll(napi, budget);
+       trace_napi_poll(napi);
 
        clear_bit(NAPI_STATE_NPSVC, &napi->state);
        atomic_dec(&trapped);
@@ -300,8 +302,11 @@ static void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb)
                for (tries = jiffies_to_usecs(1)/USEC_PER_POLL;
                     tries > 0; --tries) {
                        if (__netif_tx_trylock(txq)) {
-                               if (!netif_tx_queue_stopped(txq))
+                               if (!netif_tx_queue_stopped(txq)) {
                                        status = ops->ndo_start_xmit(skb, dev);
+                                       if (status == NETDEV_TX_OK)
+                                               txq_trans_update(txq);
+                               }
                                __netif_tx_unlock(txq);
 
                                if (status == NETDEV_TX_OK)
index 0666a827bc62d3a9cd067c744c650f4d6337d563..19b8c20e98a4fdaf997a8d32c21bb1436e49915b 100644 (file)
@@ -3438,6 +3438,7 @@ static __inline__ void pktgen_xmit(struct pktgen_dev *pkt_dev)
              retry_now:
                ret = (*xmit)(pkt_dev->skb, odev);
                if (likely(ret == NETDEV_TX_OK)) {
+                       txq_trans_update(txq);
                        pkt_dev->last_ok = 1;
                        pkt_dev->sofar++;
                        pkt_dev->seq_num++;
@@ -3690,8 +3691,7 @@ out1:
 #ifdef CONFIG_XFRM
        free_SAs(pkt_dev);
 #endif
-       if (pkt_dev->flows)
-               vfree(pkt_dev->flows);
+       vfree(pkt_dev->flows);
        kfree(pkt_dev);
        return err;
 }
@@ -3790,8 +3790,7 @@ static int pktgen_remove_device(struct pktgen_thread *t,
 #ifdef CONFIG_XFRM
        free_SAs(pkt_dev);
 #endif
-       if (pkt_dev->flows)
-               vfree(pkt_dev->flows);
+       vfree(pkt_dev->flows);
        kfree(pkt_dev);
        return 0;
 }
index 86234923a3b7600571d434e884fed063a318c718..79687dfd695702864ee25af518d2a6ee073709ce 100644 (file)
@@ -20,7 +20,7 @@ int skb_dma_map(struct device *dev, struct sk_buff *skb,
        if (dma_mapping_error(dev, map))
                goto out_err;
 
-       sp->dma_maps[0] = map;
+       sp->dma_head = map;
        for (i = 0; i < sp->nr_frags; i++) {
                skb_frag_t *fp = &sp->frags[i];
 
@@ -28,9 +28,8 @@ int skb_dma_map(struct device *dev, struct sk_buff *skb,
                                   fp->size, dir);
                if (dma_mapping_error(dev, map))
                        goto unwind;
-               sp->dma_maps[i + 1] = map;
+               sp->dma_maps[i] = map;
        }
-       sp->num_dma_maps = i + 1;
 
        return 0;
 
@@ -38,10 +37,10 @@ unwind:
        while (--i >= 0) {
                skb_frag_t *fp = &sp->frags[i];
 
-               dma_unmap_page(dev, sp->dma_maps[i + 1],
+               dma_unmap_page(dev, sp->dma_maps[i],
                               fp->size, dir);
        }
-       dma_unmap_single(dev, sp->dma_maps[0],
+       dma_unmap_single(dev, sp->dma_head,
                         skb_headlen(skb), dir);
 out_err:
        return -ENOMEM;
@@ -54,12 +53,12 @@ void skb_dma_unmap(struct device *dev, struct sk_buff *skb,
        struct skb_shared_info *sp = skb_shinfo(skb);
        int i;
 
-       dma_unmap_single(dev, sp->dma_maps[0],
+       dma_unmap_single(dev, sp->dma_head,
                         skb_headlen(skb), dir);
        for (i = 0; i < sp->nr_frags; i++) {
                skb_frag_t *fp = &sp->frags[i];
 
-               dma_unmap_page(dev, sp->dma_maps[i + 1],
+               dma_unmap_page(dev, sp->dma_maps[i],
                               fp->size, dir);
        }
 }
index c2e4fb8f3546c06a39b22b8c8538ecdf7187c3e7..1a94a3037370a4c70ee3862fb9676a4975eddeb1 100644 (file)
@@ -210,7 +210,7 @@ struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask,
        shinfo->gso_type = 0;
        shinfo->ip6_frag_id = 0;
        shinfo->tx_flags.flags = 0;
-       shinfo->frag_list = NULL;
+       skb_frag_list_init(skb);
        memset(&shinfo->hwtstamps, 0, sizeof(shinfo->hwtstamps));
 
        if (fclone) {
@@ -323,7 +323,7 @@ static void skb_clone_fraglist(struct sk_buff *skb)
 {
        struct sk_buff *list;
 
-       for (list = skb_shinfo(skb)->frag_list; list; list = list->next)
+       skb_walk_frags(skb, list)
                skb_get(list);
 }
 
@@ -338,7 +338,7 @@ static void skb_release_data(struct sk_buff *skb)
                                put_page(skb_shinfo(skb)->frags[i].page);
                }
 
-               if (skb_shinfo(skb)->frag_list)
+               if (skb_has_frags(skb))
                        skb_drop_fraglist(skb);
 
                kfree(skb->head);
@@ -381,7 +381,7 @@ static void kfree_skbmem(struct sk_buff *skb)
 
 static void skb_release_head_state(struct sk_buff *skb)
 {
-       dst_release(skb->dst);
+       skb_dst_drop(skb);
 #ifdef CONFIG_XFRM
        secpath_put(skb->sp);
 #endif
@@ -503,7 +503,7 @@ int skb_recycle_check(struct sk_buff *skb, int skb_size)
        shinfo->gso_type = 0;
        shinfo->ip6_frag_id = 0;
        shinfo->tx_flags.flags = 0;
-       shinfo->frag_list = NULL;
+       skb_frag_list_init(skb);
        memset(&shinfo->hwtstamps, 0, sizeof(shinfo->hwtstamps));
 
        memset(skb, 0, offsetof(struct sk_buff, tail));
@@ -521,13 +521,12 @@ static void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
        new->transport_header   = old->transport_header;
        new->network_header     = old->network_header;
        new->mac_header         = old->mac_header;
-       new->dst                = dst_clone(old->dst);
+       skb_dst_set(new, dst_clone(skb_dst(old)));
 #ifdef CONFIG_XFRM
        new->sp                 = secpath_get(old->sp);
 #endif
        memcpy(new->cb, old->cb, sizeof(old->cb));
-       new->csum_start         = old->csum_start;
-       new->csum_offset        = old->csum_offset;
+       new->csum               = old->csum;
        new->local_df           = old->local_df;
        new->pkt_type           = old->pkt_type;
        new->ip_summed          = old->ip_summed;
@@ -538,6 +537,7 @@ static void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
 #endif
        new->protocol           = old->protocol;
        new->mark               = old->mark;
+       new->iif                = old->iif;
        __nf_copy(new, old);
 #if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
     defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
@@ -550,10 +550,17 @@ static void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
 #endif
 #endif
        new->vlan_tci           = old->vlan_tci;
+#if defined(CONFIG_MAC80211) || defined(CONFIG_MAC80211_MODULE)
+       new->do_not_encrypt     = old->do_not_encrypt;
+#endif
 
        skb_copy_secmark(new, old);
 }
 
+/*
+ * You should not add any new code to this function.  Add it to
+ * __copy_skb_header above instead.
+ */
 static struct sk_buff *__skb_clone(struct sk_buff *n, struct sk_buff *skb)
 {
 #define C(x) n->x = skb->x
@@ -569,16 +576,11 @@ static struct sk_buff *__skb_clone(struct sk_buff *n, struct sk_buff *skb)
        n->cloned = 1;
        n->nohdr = 0;
        n->destructor = NULL;
-       C(iif);
        C(tail);
        C(end);
        C(head);
        C(data);
        C(truesize);
-#if defined(CONFIG_MAC80211) || defined(CONFIG_MAC80211_MODULE)
-       C(do_not_encrypt);
-       C(requeue);
-#endif
        atomic_set(&n->users, 1);
 
        atomic_inc(&(skb_shinfo(skb)->dataref));
@@ -755,7 +757,7 @@ struct sk_buff *pskb_copy(struct sk_buff *skb, gfp_t gfp_mask)
                skb_shinfo(n)->nr_frags = i;
        }
 
-       if (skb_shinfo(skb)->frag_list) {
+       if (skb_has_frags(skb)) {
                skb_shinfo(n)->frag_list = skb_shinfo(skb)->frag_list;
                skb_clone_fraglist(n);
        }
@@ -818,7 +820,7 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail,
        for (i = 0; i < skb_shinfo(skb)->nr_frags; i++)
                get_page(skb_shinfo(skb)->frags[i].page);
 
-       if (skb_shinfo(skb)->frag_list)
+       if (skb_has_frags(skb))
                skb_clone_fraglist(skb);
 
        skb_release_data(skb);
@@ -1090,7 +1092,7 @@ drop_pages:
                for (; i < nfrags; i++)
                        put_page(skb_shinfo(skb)->frags[i].page);
 
-               if (skb_shinfo(skb)->frag_list)
+               if (skb_has_frags(skb))
                        skb_drop_fraglist(skb);
                goto done;
        }
@@ -1185,7 +1187,7 @@ unsigned char *__pskb_pull_tail(struct sk_buff *skb, int delta)
        /* Optimization: no fragments, no reasons to preestimate
         * size of pulled pages. Superb.
         */
-       if (!skb_shinfo(skb)->frag_list)
+       if (!skb_has_frags(skb))
                goto pull_pages;
 
        /* Estimate size of pulled pages. */
@@ -1282,8 +1284,9 @@ EXPORT_SYMBOL(__pskb_pull_tail);
 
 int skb_copy_bits(const struct sk_buff *skb, int offset, void *to, int len)
 {
-       int i, copy;
        int start = skb_headlen(skb);
+       struct sk_buff *frag_iter;
+       int i, copy;
 
        if (offset > (int)skb->len - len)
                goto fault;
@@ -1325,28 +1328,23 @@ int skb_copy_bits(const struct sk_buff *skb, int offset, void *to, int len)
                start = end;
        }
 
-       if (skb_shinfo(skb)->frag_list) {
-               struct sk_buff *list = skb_shinfo(skb)->frag_list;
+       skb_walk_frags(skb, frag_iter) {
+               int end;
 
-               for (; list; list = list->next) {
-                       int end;
-
-                       WARN_ON(start > offset + len);
-
-                       end = start + list->len;
-                       if ((copy = end - offset) > 0) {
-                               if (copy > len)
-                                       copy = len;
-                               if (skb_copy_bits(list, offset - start,
-                                                 to, copy))
-                                       goto fault;
-                               if ((len -= copy) == 0)
-                                       return 0;
-                               offset += copy;
-                               to     += copy;
-                       }
-                       start = end;
+               WARN_ON(start > offset + len);
+
+               end = start + frag_iter->len;
+               if ((copy = end - offset) > 0) {
+                       if (copy > len)
+                               copy = len;
+                       if (skb_copy_bits(frag_iter, offset - start, to, copy))
+                               goto fault;
+                       if ((len -= copy) == 0)
+                               return 0;
+                       offset += copy;
+                       to     += copy;
                }
+               start = end;
        }
        if (!len)
                return 0;
@@ -1531,6 +1529,7 @@ int skb_splice_bits(struct sk_buff *skb, unsigned int offset,
                .ops = &sock_pipe_buf_ops,
                .spd_release = sock_spd_release,
        };
+       struct sk_buff *frag_iter;
        struct sock *sk = skb->sk;
 
        /*
@@ -1545,13 +1544,11 @@ int skb_splice_bits(struct sk_buff *skb, unsigned int offset,
        /*
         * now see if we have a frag_list to map
         */
-       if (skb_shinfo(skb)->frag_list) {
-               struct sk_buff *list = skb_shinfo(skb)->frag_list;
-
-               for (; list && tlen; list = list->next) {
-                       if (__skb_splice_bits(list, &offset, &tlen, &spd, sk))
-                               break;
-               }
+       skb_walk_frags(skb, frag_iter) {
+               if (!tlen)
+                       break;
+               if (__skb_splice_bits(frag_iter, &offset, &tlen, &spd, sk))
+                       break;
        }
 
 done:
@@ -1590,8 +1587,9 @@ done:
 
 int skb_store_bits(struct sk_buff *skb, int offset, const void *from, int len)
 {
-       int i, copy;
        int start = skb_headlen(skb);
+       struct sk_buff *frag_iter;
+       int i, copy;
 
        if (offset > (int)skb->len - len)
                goto fault;
@@ -1632,28 +1630,24 @@ int skb_store_bits(struct sk_buff *skb, int offset, const void *from, int len)
                start = end;
        }
 
-       if (skb_shinfo(skb)->frag_list) {
-               struct sk_buff *list = skb_shinfo(skb)->frag_list;
+       skb_walk_frags(skb, frag_iter) {
+               int end;
 
-               for (; list; list = list->next) {
-                       int end;
-
-                       WARN_ON(start > offset + len);
-
-                       end = start + list->len;
-                       if ((copy = end - offset) > 0) {
-                               if (copy > len)
-                                       copy = len;
-                               if (skb_store_bits(list, offset - start,
-                                                  from, copy))
-                                       goto fault;
-                               if ((len -= copy) == 0)
-                                       return 0;
-                               offset += copy;
-                               from += copy;
-                       }
-                       start = end;
+               WARN_ON(start > offset + len);
+
+               end = start + frag_iter->len;
+               if ((copy = end - offset) > 0) {
+                       if (copy > len)
+                               copy = len;
+                       if (skb_store_bits(frag_iter, offset - start,
+                                          from, copy))
+                               goto fault;
+                       if ((len -= copy) == 0)
+                               return 0;
+                       offset += copy;
+                       from += copy;
                }
+               start = end;
        }
        if (!len)
                return 0;
@@ -1670,6 +1664,7 @@ __wsum skb_checksum(const struct sk_buff *skb, int offset,
 {
        int start = skb_headlen(skb);
        int i, copy = start - offset;
+       struct sk_buff *frag_iter;
        int pos = 0;
 
        /* Checksum header. */
@@ -1709,29 +1704,25 @@ __wsum skb_checksum(const struct sk_buff *skb, int offset,
                start = end;
        }
 
-       if (skb_shinfo(skb)->frag_list) {
-               struct sk_buff *list = skb_shinfo(skb)->frag_list;
+       skb_walk_frags(skb, frag_iter) {
+               int end;
 
-               for (; list; list = list->next) {
-                       int end;
-
-                       WARN_ON(start > offset + len);
-
-                       end = start + list->len;
-                       if ((copy = end - offset) > 0) {
-                               __wsum csum2;
-                               if (copy > len)
-                                       copy = len;
-                               csum2 = skb_checksum(list, offset - start,
-                                                    copy, 0);
-                               csum = csum_block_add(csum, csum2, pos);
-                               if ((len -= copy) == 0)
-                                       return csum;
-                               offset += copy;
-                               pos    += copy;
-                       }
-                       start = end;
+               WARN_ON(start > offset + len);
+
+               end = start + frag_iter->len;
+               if ((copy = end - offset) > 0) {
+                       __wsum csum2;
+                       if (copy > len)
+                               copy = len;
+                       csum2 = skb_checksum(frag_iter, offset - start,
+                                            copy, 0);
+                       csum = csum_block_add(csum, csum2, pos);
+                       if ((len -= copy) == 0)
+                               return csum;
+                       offset += copy;
+                       pos    += copy;
                }
+               start = end;
        }
        BUG_ON(len);
 
@@ -1746,6 +1737,7 @@ __wsum skb_copy_and_csum_bits(const struct sk_buff *skb, int offset,
 {
        int start = skb_headlen(skb);
        int i, copy = start - offset;
+       struct sk_buff *frag_iter;
        int pos = 0;
 
        /* Copy header. */
@@ -1790,31 +1782,27 @@ __wsum skb_copy_and_csum_bits(const struct sk_buff *skb, int offset,
                start = end;
        }
 
-       if (skb_shinfo(skb)->frag_list) {
-               struct sk_buff *list = skb_shinfo(skb)->frag_list;
+       skb_walk_frags(skb, frag_iter) {
+               __wsum csum2;
+               int end;
 
-               for (; list; list = list->next) {
-                       __wsum csum2;
-                       int end;
-
-                       WARN_ON(start > offset + len);
-
-                       end = start + list->len;
-                       if ((copy = end - offset) > 0) {
-                               if (copy > len)
-                                       copy = len;
-                               csum2 = skb_copy_and_csum_bits(list,
-                                                              offset - start,
-                                                              to, copy, 0);
-                               csum = csum_block_add(csum, csum2, pos);
-                               if ((len -= copy) == 0)
-                                       return csum;
-                               offset += copy;
-                               to     += copy;
-                               pos    += copy;
-                       }
-                       start = end;
+               WARN_ON(start > offset + len);
+
+               end = start + frag_iter->len;
+               if ((copy = end - offset) > 0) {
+                       if (copy > len)
+                               copy = len;
+                       csum2 = skb_copy_and_csum_bits(frag_iter,
+                                                      offset - start,
+                                                      to, copy, 0);
+                       csum = csum_block_add(csum, csum2, pos);
+                       if ((len -= copy) == 0)
+                               return csum;
+                       offset += copy;
+                       to     += copy;
+                       pos    += copy;
                }
+               start = end;
        }
        BUG_ON(len);
        return csum;
@@ -2324,8 +2312,7 @@ next_skb:
                st->frag_data = NULL;
        }
 
-       if (st->root_skb == st->cur_skb &&
-           skb_shinfo(st->root_skb)->frag_list) {
+       if (st->root_skb == st->cur_skb && skb_has_frags(st->root_skb)) {
                st->cur_skb = skb_shinfo(st->root_skb)->frag_list;
                st->frag_idx = 0;
                goto next_skb;
@@ -2636,7 +2623,7 @@ struct sk_buff *skb_segment(struct sk_buff *skb, int features)
                        } else
                                skb_get(fskb2);
 
-                       BUG_ON(skb_shinfo(nskb)->frag_list);
+                       SKB_FRAG_ASSERT(nskb);
                        skb_shinfo(nskb)->frag_list = fskb2;
                }
 
@@ -2661,30 +2648,40 @@ int skb_gro_receive(struct sk_buff **head, struct sk_buff *skb)
 {
        struct sk_buff *p = *head;
        struct sk_buff *nskb;
+       struct skb_shared_info *skbinfo = skb_shinfo(skb);
+       struct skb_shared_info *pinfo = skb_shinfo(p);
        unsigned int headroom;
        unsigned int len = skb_gro_len(skb);
+       unsigned int offset = skb_gro_offset(skb);
+       unsigned int headlen = skb_headlen(skb);
 
        if (p->len + len >= 65536)
                return -E2BIG;
 
-       if (skb_shinfo(p)->frag_list)
+       if (pinfo->frag_list)
                goto merge;
-       else if (skb_headlen(skb) <= skb_gro_offset(skb)) {
-               if (skb_shinfo(p)->nr_frags + skb_shinfo(skb)->nr_frags >
-                   MAX_SKB_FRAGS)
+       else if (headlen <= offset) {
+               skb_frag_t *frag;
+               skb_frag_t *frag2;
+               int i = skbinfo->nr_frags;
+               int nr_frags = pinfo->nr_frags + i;
+
+               offset -= headlen;
+
+               if (nr_frags > MAX_SKB_FRAGS)
                        return -E2BIG;
 
-               skb_shinfo(skb)->frags[0].page_offset +=
-                       skb_gro_offset(skb) - skb_headlen(skb);
-               skb_shinfo(skb)->frags[0].size -=
-                       skb_gro_offset(skb) - skb_headlen(skb);
+               pinfo->nr_frags = nr_frags;
+               skbinfo->nr_frags = 0;
 
-               memcpy(skb_shinfo(p)->frags + skb_shinfo(p)->nr_frags,
-                      skb_shinfo(skb)->frags,
-                      skb_shinfo(skb)->nr_frags * sizeof(skb_frag_t));
+               frag = pinfo->frags + nr_frags;
+               frag2 = skbinfo->frags + i;
+               do {
+                       *--frag = *--frag2;
+               } while (--i);
 
-               skb_shinfo(p)->nr_frags += skb_shinfo(skb)->nr_frags;
-               skb_shinfo(skb)->nr_frags = 0;
+               frag->page_offset += offset;
+               frag->size -= offset;
 
                skb->truesize -= skb->data_len;
                skb->len -= skb->data_len;
@@ -2715,7 +2712,7 @@ int skb_gro_receive(struct sk_buff **head, struct sk_buff *skb)
 
        *NAPI_GRO_CB(nskb) = *NAPI_GRO_CB(p);
        skb_shinfo(nskb)->frag_list = p;
-       skb_shinfo(nskb)->gso_size = skb_shinfo(p)->gso_size;
+       skb_shinfo(nskb)->gso_size = pinfo->gso_size;
        skb_header_release(p);
        nskb->prev = p;
 
@@ -2730,16 +2727,13 @@ int skb_gro_receive(struct sk_buff **head, struct sk_buff *skb)
        p = nskb;
 
 merge:
-       if (skb_gro_offset(skb) > skb_headlen(skb)) {
-               skb_shinfo(skb)->frags[0].page_offset +=
-                       skb_gro_offset(skb) - skb_headlen(skb);
-               skb_shinfo(skb)->frags[0].size -=
-                       skb_gro_offset(skb) - skb_headlen(skb);
-               skb_gro_reset_offset(skb);
-               skb_gro_pull(skb, skb_headlen(skb));
+       if (offset > headlen) {
+               skbinfo->frags[0].page_offset += offset - headlen;
+               skbinfo->frags[0].size -= offset - headlen;
+               offset = headlen;
        }
 
-       __skb_pull(skb, skb_gro_offset(skb));
+       __skb_pull(skb, offset);
 
        p->prev->next = skb;
        p->prev = skb;
@@ -2786,6 +2780,7 @@ __skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len)
 {
        int start = skb_headlen(skb);
        int i, copy = start - offset;
+       struct sk_buff *frag_iter;
        int elt = 0;
 
        if (copy > 0) {
@@ -2819,26 +2814,22 @@ __skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len)
                start = end;
        }
 
-       if (skb_shinfo(skb)->frag_list) {
-               struct sk_buff *list = skb_shinfo(skb)->frag_list;
-
-               for (; list; list = list->next) {
-                       int end;
+       skb_walk_frags(skb, frag_iter) {
+               int end;
 
-                       WARN_ON(start > offset + len);
+               WARN_ON(start > offset + len);
 
-                       end = start + list->len;
-                       if ((copy = end - offset) > 0) {
-                               if (copy > len)
-                                       copy = len;
-                               elt += __skb_to_sgvec(list, sg+elt, offset - start,
-                                                     copy);
-                               if ((len -= copy) == 0)
-                                       return elt;
-                               offset += copy;
-                       }
-                       start = end;
+               end = start + frag_iter->len;
+               if ((copy = end - offset) > 0) {
+                       if (copy > len)
+                               copy = len;
+                       elt += __skb_to_sgvec(frag_iter, sg+elt, offset - start,
+                                             copy);
+                       if ((len -= copy) == 0)
+                               return elt;
+                       offset += copy;
                }
+               start = end;
        }
        BUG_ON(len);
        return elt;
@@ -2886,7 +2877,7 @@ int skb_cow_data(struct sk_buff *skb, int tailbits, struct sk_buff **trailer)
                return -ENOMEM;
 
        /* Easy case. Most of packets will go this way. */
-       if (!skb_shinfo(skb)->frag_list) {
+       if (!skb_has_frags(skb)) {
                /* A little of trouble, not enough of space for trailer.
                 * This should not happen, when stack is tuned to generate
                 * good frames. OK, on miss we reallocate and reserve even more
@@ -2921,7 +2912,7 @@ int skb_cow_data(struct sk_buff *skb, int tailbits, struct sk_buff **trailer)
 
                if (skb1->next == NULL && tailbits) {
                        if (skb_shinfo(skb1)->nr_frags ||
-                           skb_shinfo(skb1)->frag_list ||
+                           skb_has_frags(skb1) ||
                            skb_tailroom(skb1) < tailbits)
                                ntail = tailbits + 128;
                }
@@ -2930,7 +2921,7 @@ int skb_cow_data(struct sk_buff *skb, int tailbits, struct sk_buff **trailer)
                    skb_cloned(skb1) ||
                    ntail ||
                    skb_shinfo(skb1)->nr_frags ||
-                   skb_shinfo(skb1)->frag_list) {
+                   skb_has_frags(skb1)) {
                        struct sk_buff *skb2;
 
                        /* Fuck, we are miserable poor guys... */
@@ -3016,12 +3007,12 @@ EXPORT_SYMBOL_GPL(skb_tstamp_tx);
  */
 bool skb_partial_csum_set(struct sk_buff *skb, u16 start, u16 off)
 {
-       if (unlikely(start > skb->len - 2) ||
-           unlikely((int)start + off > skb->len - 2)) {
+       if (unlikely(start > skb_headlen(skb)) ||
+           unlikely((int)start + off > skb_headlen(skb) - 2)) {
                if (net_ratelimit())
                        printk(KERN_WARNING
                               "bad partial csum: csum=%u/%u len=%u\n",
-                              start, off, skb->len);
+                              start, off, skb_headlen(skb));
                return false;
        }
        skb->ip_summed = CHECKSUM_PARTIAL;
index 7dbf3ffb35ccd6cb3308dab70fa33ce9cd9f8d5c..06e26b77ad9e78437948592eb1781539b6947703 100644 (file)
@@ -155,6 +155,7 @@ static const char *af_family_key_strings[AF_MAX+1] = {
   "sk_lock-27"       , "sk_lock-28"          , "sk_lock-AF_CAN"      ,
   "sk_lock-AF_TIPC"  , "sk_lock-AF_BLUETOOTH", "sk_lock-IUCV"        ,
   "sk_lock-AF_RXRPC" , "sk_lock-AF_ISDN"     , "sk_lock-AF_PHONET"   ,
+  "sk_lock-AF_IEEE802154",
   "sk_lock-AF_MAX"
 };
 static const char *af_family_slock_key_strings[AF_MAX+1] = {
@@ -170,6 +171,7 @@ static const char *af_family_slock_key_strings[AF_MAX+1] = {
   "slock-27"       , "slock-28"          , "slock-AF_CAN"      ,
   "slock-AF_TIPC"  , "slock-AF_BLUETOOTH", "slock-AF_IUCV"     ,
   "slock-AF_RXRPC" , "slock-AF_ISDN"     , "slock-AF_PHONET"   ,
+  "slock-AF_IEEE802154",
   "slock-AF_MAX"
 };
 static const char *af_family_clock_key_strings[AF_MAX+1] = {
@@ -185,6 +187,7 @@ static const char *af_family_clock_key_strings[AF_MAX+1] = {
   "clock-27"       , "clock-28"          , "clock-AF_CAN"      ,
   "clock-AF_TIPC"  , "clock-AF_BLUETOOTH", "clock-AF_IUCV"     ,
   "clock-AF_RXRPC" , "clock-AF_ISDN"     , "clock-AF_PHONET"   ,
+  "clock-AF_IEEE802154",
   "clock-AF_MAX"
 };
 
@@ -212,6 +215,7 @@ __u32 sysctl_rmem_default __read_mostly = SK_RMEM_MAX;
 
 /* Maximal space eaten by iovec or ancilliary data plus some space */
 int sysctl_optmem_max __read_mostly = sizeof(unsigned long)*(2*UIO_MAXIOV+512);
+EXPORT_SYMBOL(sysctl_optmem_max);
 
 static int sock_set_timeout(long *timeo_p, char __user *optval, int optlen)
 {
@@ -444,7 +448,7 @@ static inline void sock_valbool_flag(struct sock *sk, int bit, int valbool)
 int sock_setsockopt(struct socket *sock, int level, int optname,
                    char __user *optval, int optlen)
 {
-       struct sock *sk=sock->sk;
+       struct sock *sk = sock->sk;
        int val;
        int valbool;
        struct linger ling;
@@ -463,15 +467,15 @@ int sock_setsockopt(struct socket *sock, int level, int optname,
        if (get_user(val, (int __user *)optval))
                return -EFAULT;
 
-       valbool = val?1:0;
+       valbool = val ? 1 : 0;
 
        lock_sock(sk);
 
-       switch(optname) {
+       switch (optname) {
        case SO_DEBUG:
-               if (val && !capable(CAP_NET_ADMIN)) {
+               if (val && !capable(CAP_NET_ADMIN))
                        ret = -EACCES;
-               else
+               else
                        sock_valbool_flag(sk, SOCK_DBG, valbool);
                break;
        case SO_REUSEADDR:
@@ -582,7 +586,7 @@ set_rcvbuf:
                        ret = -EINVAL;  /* 1003.1g */
                        break;
                }
-               if (copy_from_user(&ling,optval,sizeof(ling))) {
+               if (copy_from_user(&ling, optval, sizeof(ling))) {
                        ret = -EFAULT;
                        break;
                }
@@ -690,9 +694,8 @@ set_rcvbuf:
        case SO_MARK:
                if (!capable(CAP_NET_ADMIN))
                        ret = -EPERM;
-               else {
+               else
                        sk->sk_mark = val;
-               }
                break;
 
                /* We implement the SO_SNDLOWAT etc to
@@ -704,6 +707,7 @@ set_rcvbuf:
        release_sock(sk);
        return ret;
 }
+EXPORT_SYMBOL(sock_setsockopt);
 
 
 int sock_getsockopt(struct socket *sock, int level, int optname,
@@ -727,7 +731,7 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
 
        memset(&v, 0, sizeof(v));
 
-       switch(optname) {
+       switch (optname) {
        case SO_DEBUG:
                v.val = sock_flag(sk, SOCK_DBG);
                break;
@@ -762,7 +766,7 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
 
        case SO_ERROR:
                v.val = -sock_error(sk);
-               if (v.val==0)
+               if (v.val == 0)
                        v.val = xchg(&sk->sk_err_soft, 0);
                break;
 
@@ -816,7 +820,7 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
                break;
 
        case SO_RCVTIMEO:
-               lv=sizeof(struct timeval);
+               lv = sizeof(struct timeval);
                if (sk->sk_rcvtimeo == MAX_SCHEDULE_TIMEOUT) {
                        v.tm.tv_sec = 0;
                        v.tm.tv_usec = 0;
@@ -827,7 +831,7 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
                break;
 
        case SO_SNDTIMEO:
-               lv=sizeof(struct timeval);
+               lv = sizeof(struct timeval);
                if (sk->sk_sndtimeo == MAX_SCHEDULE_TIMEOUT) {
                        v.tm.tv_sec = 0;
                        v.tm.tv_usec = 0;
@@ -842,7 +846,7 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
                break;
 
        case SO_SNDLOWAT:
-               v.val=1;
+               v.val = 1;
                break;
 
        case SO_PASSCRED:
@@ -1002,8 +1006,9 @@ struct sock *sk_alloc(struct net *net, int family, gfp_t priority,
 
        return sk;
 }
+EXPORT_SYMBOL(sk_alloc);
 
-void sk_free(struct sock *sk)
+static void __sk_free(struct sock *sk)
 {
        struct sk_filter *filter;
 
@@ -1027,6 +1032,18 @@ void sk_free(struct sock *sk)
        sk_prot_free(sk->sk_prot_creator, sk);
 }
 
+void sk_free(struct sock *sk)
+{
+       /*
+        * We substract one from sk_wmem_alloc and can know if
+        * some packets are still in some tx queue.
+        * If not null, sock_wfree() will call __sk_free(sk) later
+        */
+       if (atomic_dec_and_test(&sk->sk_wmem_alloc))
+               __sk_free(sk);
+}
+EXPORT_SYMBOL(sk_free);
+
 /*
  * Last sock_put should drop referrence to sk->sk_net. It has already
  * been dropped in sk_change_net. Taking referrence to stopping namespace
@@ -1065,7 +1082,10 @@ struct sock *sk_clone(const struct sock *sk, const gfp_t priority)
                newsk->sk_backlog.head  = newsk->sk_backlog.tail = NULL;
 
                atomic_set(&newsk->sk_rmem_alloc, 0);
-               atomic_set(&newsk->sk_wmem_alloc, 0);
+               /*
+                * sk_wmem_alloc set to one (see sk_free() and sock_wfree())
+                */
+               atomic_set(&newsk->sk_wmem_alloc, 1);
                atomic_set(&newsk->sk_omem_alloc, 0);
                skb_queue_head_init(&newsk->sk_receive_queue);
                skb_queue_head_init(&newsk->sk_write_queue);
@@ -1126,7 +1146,6 @@ struct sock *sk_clone(const struct sock *sk, const gfp_t priority)
 out:
        return newsk;
 }
-
 EXPORT_SYMBOL_GPL(sk_clone);
 
 void sk_setup_caps(struct sock *sk, struct dst_entry *dst)
@@ -1170,13 +1189,20 @@ void __init sk_init(void)
 void sock_wfree(struct sk_buff *skb)
 {
        struct sock *sk = skb->sk;
+       int res;
 
        /* In case it might be waiting for more memory. */
-       atomic_sub(skb->truesize, &sk->sk_wmem_alloc);
+       res = atomic_sub_return(skb->truesize, &sk->sk_wmem_alloc);
        if (!sock_flag(sk, SOCK_USE_WRITE_QUEUE))
                sk->sk_write_space(sk);
-       sock_put(sk);
+       /*
+        * if sk_wmem_alloc reached 0, we are last user and should
+        * free this sock, as sk_free() call could not do it.
+        */
+       if (res == 0)
+               __sk_free(sk);
 }
+EXPORT_SYMBOL(sock_wfree);
 
 /*
  * Read buffer destructor automatically called from kfree_skb.
@@ -1188,6 +1214,7 @@ void sock_rfree(struct sk_buff *skb)
        atomic_sub(skb->truesize, &sk->sk_rmem_alloc);
        sk_mem_uncharge(skb->sk, skb->truesize);
 }
+EXPORT_SYMBOL(sock_rfree);
 
 
 int sock_i_uid(struct sock *sk)
@@ -1199,6 +1226,7 @@ int sock_i_uid(struct sock *sk)
        read_unlock(&sk->sk_callback_lock);
        return uid;
 }
+EXPORT_SYMBOL(sock_i_uid);
 
 unsigned long sock_i_ino(struct sock *sk)
 {
@@ -1209,6 +1237,7 @@ unsigned long sock_i_ino(struct sock *sk)
        read_unlock(&sk->sk_callback_lock);
        return ino;
 }
+EXPORT_SYMBOL(sock_i_ino);
 
 /*
  * Allocate a skb from the socket's send buffer.
@@ -1217,7 +1246,7 @@ struct sk_buff *sock_wmalloc(struct sock *sk, unsigned long size, int force,
                             gfp_t priority)
 {
        if (force || atomic_read(&sk->sk_wmem_alloc) < sk->sk_sndbuf) {
-               struct sk_buff * skb = alloc_skb(size, priority);
+               struct sk_buff *skb = alloc_skb(size, priority);
                if (skb) {
                        skb_set_owner_w(skb, sk);
                        return skb;
@@ -1225,6 +1254,7 @@ struct sk_buff *sock_wmalloc(struct sock *sk, unsigned long size, int force,
        }
        return NULL;
 }
+EXPORT_SYMBOL(sock_wmalloc);
 
 /*
  * Allocate a skb from the socket's receive buffer.
@@ -1261,6 +1291,7 @@ void *sock_kmalloc(struct sock *sk, int size, gfp_t priority)
        }
        return NULL;
 }
+EXPORT_SYMBOL(sock_kmalloc);
 
 /*
  * Free an option memory block.
@@ -1270,11 +1301,12 @@ void sock_kfree_s(struct sock *sk, void *mem, int size)
        kfree(mem);
        atomic_sub(size, &sk->sk_omem_alloc);
 }
+EXPORT_SYMBOL(sock_kfree_s);
 
 /* It is almost wait_for_tcp_memory minus release_sock/lock_sock.
    I think, these locks should be removed for datagram sockets.
  */
-static long sock_wait_for_wmem(struct sock * sk, long timeo)
+static long sock_wait_for_wmem(struct sock *sk, long timeo)
 {
        DEFINE_WAIT(wait);
 
@@ -1392,6 +1424,7 @@ struct sk_buff *sock_alloc_send_skb(struct sock *sk, unsigned long size,
 {
        return sock_alloc_send_pskb(sk, size, 0, noblock, errcode);
 }
+EXPORT_SYMBOL(sock_alloc_send_skb);
 
 static void __lock_sock(struct sock *sk)
 {
@@ -1460,7 +1493,6 @@ int sk_wait_data(struct sock *sk, long *timeo)
        finish_wait(sk->sk_sleep, &wait);
        return rc;
 }
-
 EXPORT_SYMBOL(sk_wait_data);
 
 /**
@@ -1541,7 +1573,6 @@ suppress_allocation:
        atomic_sub(amt, prot->memory_allocated);
        return 0;
 }
-
 EXPORT_SYMBOL(__sk_mem_schedule);
 
 /**
@@ -1560,7 +1591,6 @@ void __sk_mem_reclaim(struct sock *sk)
            (atomic_read(prot->memory_allocated) < prot->sysctl_mem[0]))
                *prot->memory_pressure = 0;
 }
-
 EXPORT_SYMBOL(__sk_mem_reclaim);
 
 
@@ -1575,78 +1605,92 @@ int sock_no_bind(struct socket *sock, struct sockaddr *saddr, int len)
 {
        return -EOPNOTSUPP;
 }
+EXPORT_SYMBOL(sock_no_bind);
 
 int sock_no_connect(struct socket *sock, struct sockaddr *saddr,
                    int len, int flags)
 {
        return -EOPNOTSUPP;
 }
+EXPORT_SYMBOL(sock_no_connect);
 
 int sock_no_socketpair(struct socket *sock1, struct socket *sock2)
 {
        return -EOPNOTSUPP;
 }
+EXPORT_SYMBOL(sock_no_socketpair);
 
 int sock_no_accept(struct socket *sock, struct socket *newsock, int flags)
 {
        return -EOPNOTSUPP;
 }
+EXPORT_SYMBOL(sock_no_accept);
 
 int sock_no_getname(struct socket *sock, struct sockaddr *saddr,
                    int *len, int peer)
 {
        return -EOPNOTSUPP;
 }
+EXPORT_SYMBOL(sock_no_getname);
 
-unsigned int sock_no_poll(struct file * file, struct socket *sock, poll_table *pt)
+unsigned int sock_no_poll(struct file *file, struct socket *sock, poll_table *pt)
 {
        return 0;
 }
+EXPORT_SYMBOL(sock_no_poll);
 
 int sock_no_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 {
        return -EOPNOTSUPP;
 }
+EXPORT_SYMBOL(sock_no_ioctl);
 
 int sock_no_listen(struct socket *sock, int backlog)
 {
        return -EOPNOTSUPP;
 }
+EXPORT_SYMBOL(sock_no_listen);
 
 int sock_no_shutdown(struct socket *sock, int how)
 {
        return -EOPNOTSUPP;
 }
+EXPORT_SYMBOL(sock_no_shutdown);
 
 int sock_no_setsockopt(struct socket *sock, int level, int optname,
                    char __user *optval, int optlen)
 {
        return -EOPNOTSUPP;
 }
+EXPORT_SYMBOL(sock_no_setsockopt);
 
 int sock_no_getsockopt(struct socket *sock, int level, int optname,
                    char __user *optval, int __user *optlen)
 {
        return -EOPNOTSUPP;
 }
+EXPORT_SYMBOL(sock_no_getsockopt);
 
 int sock_no_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m,
                    size_t len)
 {
        return -EOPNOTSUPP;
 }
+EXPORT_SYMBOL(sock_no_sendmsg);
 
 int sock_no_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m,
                    size_t len, int flags)
 {
        return -EOPNOTSUPP;
 }
+EXPORT_SYMBOL(sock_no_recvmsg);
 
 int sock_no_mmap(struct file *file, struct socket *sock, struct vm_area_struct *vma)
 {
        /* Mirror missing mmap method error code */
        return -ENODEV;
 }
+EXPORT_SYMBOL(sock_no_mmap);
 
 ssize_t sock_no_sendpage(struct socket *sock, struct page *page, int offset, size_t size, int flags)
 {
@@ -1660,6 +1704,7 @@ ssize_t sock_no_sendpage(struct socket *sock, struct page *page, int offset, siz
        kunmap(page);
        return res;
 }
+EXPORT_SYMBOL(sock_no_sendpage);
 
 /*
  *     Default Socket Callbacks
@@ -1723,6 +1768,7 @@ void sk_send_sigurg(struct sock *sk)
                if (send_sigurg(&sk->sk_socket->file->f_owner))
                        sk_wake_async(sk, SOCK_WAKE_URG, POLL_PRI);
 }
+EXPORT_SYMBOL(sk_send_sigurg);
 
 void sk_reset_timer(struct sock *sk, struct timer_list* timer,
                    unsigned long expires)
@@ -1730,7 +1776,6 @@ void sk_reset_timer(struct sock *sk, struct timer_list* timer,
        if (!mod_timer(timer, expires))
                sock_hold(sk);
 }
-
 EXPORT_SYMBOL(sk_reset_timer);
 
 void sk_stop_timer(struct sock *sk, struct timer_list* timer)
@@ -1738,7 +1783,6 @@ void sk_stop_timer(struct sock *sk, struct timer_list* timer)
        if (timer_pending(timer) && del_timer(timer))
                __sock_put(sk);
 }
-
 EXPORT_SYMBOL(sk_stop_timer);
 
 void sock_init_data(struct socket *sock, struct sock *sk)
@@ -1795,8 +1839,10 @@ void sock_init_data(struct socket *sock, struct sock *sk)
        sk->sk_stamp = ktime_set(-1L, 0);
 
        atomic_set(&sk->sk_refcnt, 1);
+       atomic_set(&sk->sk_wmem_alloc, 1);
        atomic_set(&sk->sk_drops, 0);
 }
+EXPORT_SYMBOL(sock_init_data);
 
 void lock_sock_nested(struct sock *sk, int subclass)
 {
@@ -1812,7 +1858,6 @@ void lock_sock_nested(struct sock *sk, int subclass)
        mutex_acquire(&sk->sk_lock.dep_map, subclass, 0, _RET_IP_);
        local_bh_enable();
 }
-
 EXPORT_SYMBOL(lock_sock_nested);
 
 void release_sock(struct sock *sk)
@@ -1895,7 +1940,6 @@ int sock_common_getsockopt(struct socket *sock, int level, int optname,
 
        return sk->sk_prot->getsockopt(sk, level, optname, optval, optlen);
 }
-
 EXPORT_SYMBOL(sock_common_getsockopt);
 
 #ifdef CONFIG_COMPAT
@@ -1925,7 +1969,6 @@ int sock_common_recvmsg(struct kiocb *iocb, struct socket *sock,
                msg->msg_namelen = addr_len;
        return err;
 }
-
 EXPORT_SYMBOL(sock_common_recvmsg);
 
 /*
@@ -1938,7 +1981,6 @@ int sock_common_setsockopt(struct socket *sock, int level, int optname,
 
        return sk->sk_prot->setsockopt(sk, level, optname, optval, optlen);
 }
-
 EXPORT_SYMBOL(sock_common_setsockopt);
 
 #ifdef CONFIG_COMPAT
@@ -1989,7 +2031,6 @@ void sk_common_release(struct sock *sk)
        sk_refcnt_debug_release(sk);
        sock_put(sk);
 }
-
 EXPORT_SYMBOL(sk_common_release);
 
 static DEFINE_RWLOCK(proto_list_lock);
@@ -2171,7 +2212,6 @@ out_free_sock_slab:
 out:
        return -ENOBUFS;
 }
-
 EXPORT_SYMBOL(proto_register);
 
 void proto_unregister(struct proto *prot)
@@ -2198,7 +2238,6 @@ void proto_unregister(struct proto *prot)
                prot->twsk_prot->twsk_slab = NULL;
        }
 }
-
 EXPORT_SYMBOL(proto_unregister);
 
 #ifdef CONFIG_PROC_FS
@@ -2324,33 +2363,3 @@ static int __init proto_init(void)
 subsys_initcall(proto_init);
 
 #endif /* PROC_FS */
-
-EXPORT_SYMBOL(sk_alloc);
-EXPORT_SYMBOL(sk_free);
-EXPORT_SYMBOL(sk_send_sigurg);
-EXPORT_SYMBOL(sock_alloc_send_skb);
-EXPORT_SYMBOL(sock_init_data);
-EXPORT_SYMBOL(sock_kfree_s);
-EXPORT_SYMBOL(sock_kmalloc);
-EXPORT_SYMBOL(sock_no_accept);
-EXPORT_SYMBOL(sock_no_bind);
-EXPORT_SYMBOL(sock_no_connect);
-EXPORT_SYMBOL(sock_no_getname);
-EXPORT_SYMBOL(sock_no_getsockopt);
-EXPORT_SYMBOL(sock_no_ioctl);
-EXPORT_SYMBOL(sock_no_listen);
-EXPORT_SYMBOL(sock_no_mmap);
-EXPORT_SYMBOL(sock_no_poll);
-EXPORT_SYMBOL(sock_no_recvmsg);
-EXPORT_SYMBOL(sock_no_sendmsg);
-EXPORT_SYMBOL(sock_no_sendpage);
-EXPORT_SYMBOL(sock_no_setsockopt);
-EXPORT_SYMBOL(sock_no_shutdown);
-EXPORT_SYMBOL(sock_no_socketpair);
-EXPORT_SYMBOL(sock_rfree);
-EXPORT_SYMBOL(sock_setsockopt);
-EXPORT_SYMBOL(sock_wfree);
-EXPORT_SYMBOL(sock_wmalloc);
-EXPORT_SYMBOL(sock_i_uid);
-EXPORT_SYMBOL(sock_i_ino);
-EXPORT_SYMBOL(sysctl_optmem_max);
index 8727cead64ad5f55bd4980d4964ede930d3242a9..a37debfeb1b2bcb3309d93fc5d45b5f82e202d6e 100644 (file)
@@ -33,7 +33,8 @@ void sk_stream_write_space(struct sock *sk)
                clear_bit(SOCK_NOSPACE, &sock->flags);
 
                if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
-                       wake_up_interruptible(sk->sk_sleep);
+                       wake_up_interruptible_poll(sk->sk_sleep, POLLOUT |
+                                               POLLWRNORM | POLLWRBAND);
                if (sock->fasync_list && !(sk->sk_shutdown & SEND_SHUTDOWN))
                        sock_wake_async(sock, SOCK_WAKE_SPACE, POLL_OUT);
        }
index 164b090d5ac3d5fed2b1d84753d11101f8a790f0..25d717ebc92e9152b77dc678e181551b160c7191 100644 (file)
@@ -51,6 +51,7 @@ int dma_skb_copy_datagram_iovec(struct dma_chan *chan,
 {
        int start = skb_headlen(skb);
        int i, copy = start - offset;
+       struct sk_buff *frag_iter;
        dma_cookie_t cookie = 0;
 
        /* Copy header. */
@@ -94,31 +95,28 @@ int dma_skb_copy_datagram_iovec(struct dma_chan *chan,
                start = end;
        }
 
-       if (skb_shinfo(skb)->frag_list) {
-               struct sk_buff *list = skb_shinfo(skb)->frag_list;
-
-               for (; list; list = list->next) {
-                       int end;
-
-                       WARN_ON(start > offset + len);
-
-                       end = start + list->len;
-                       copy = end - offset;
-                       if (copy > 0) {
-                               if (copy > len)
-                                       copy = len;
-                               cookie = dma_skb_copy_datagram_iovec(chan, list,
-                                               offset - start, to, copy,
-                                               pinned_list);
-                               if (cookie < 0)
-                                       goto fault;
-                               len -= copy;
-                               if (len == 0)
-                                       goto end;
-                               offset += copy;
-                       }
-                       start = end;
+       skb_walk_frags(skb, frag_iter) {
+               int end;
+
+               WARN_ON(start > offset + len);
+
+               end = start + frag_iter->len;
+               copy = end - offset;
+               if (copy > 0) {
+                       if (copy > len)
+                               copy = len;
+                       cookie = dma_skb_copy_datagram_iovec(chan, frag_iter,
+                                                            offset - start,
+                                                            to, copy,
+                                                            pinned_list);
+                       if (cookie < 0)
+                               goto fault;
+                       len -= copy;
+                       if (len == 0)
+                               goto end;
+                       offset += copy;
                }
+               start = end;
        }
 
 end:
index d1dd95289b8960bd1556e3cecbd025b4bb83ca8e..a0a36c9e6cce0bbacdbfb9a46c668715ecb10f60 100644 (file)
@@ -452,7 +452,7 @@ static struct dst_entry* dccp_v4_route_skb(struct net *net, struct sock *sk,
                                           struct sk_buff *skb)
 {
        struct rtable *rt;
-       struct flowi fl = { .oif = skb->rtable->rt_iif,
+       struct flowi fl = { .oif = skb_rtable(skb)->rt_iif,
                            .nl_u = { .ip4_u =
                                      { .daddr = ip_hdr(skb)->saddr,
                                        .saddr = ip_hdr(skb)->daddr,
@@ -507,14 +507,14 @@ static void dccp_v4_ctl_send_reset(struct sock *sk, struct sk_buff *rxskb)
        const struct iphdr *rxiph;
        struct sk_buff *skb;
        struct dst_entry *dst;
-       struct net *net = dev_net(rxskb->dst->dev);
+       struct net *net = dev_net(skb_dst(rxskb)->dev);
        struct sock *ctl_sk = net->dccp.v4_ctl_sk;
 
        /* Never send a reset in response to a reset. */
        if (dccp_hdr(rxskb)->dccph_type == DCCP_PKT_RESET)
                return;
 
-       if (rxskb->rtable->rt_type != RTN_LOCAL)
+       if (skb_rtable(rxskb)->rt_type != RTN_LOCAL)
                return;
 
        dst = dccp_v4_route_skb(net, ctl_sk, rxskb);
@@ -528,7 +528,7 @@ static void dccp_v4_ctl_send_reset(struct sock *sk, struct sk_buff *rxskb)
        rxiph = ip_hdr(rxskb);
        dccp_hdr(skb)->dccph_checksum = dccp_v4_csum_finish(skb, rxiph->saddr,
                                                                 rxiph->daddr);
-       skb->dst = dst_clone(dst);
+       skb_dst_set(skb, dst_clone(dst));
 
        bh_lock_sock(ctl_sk);
        err = ip_build_and_send_pkt(skb, ctl_sk,
@@ -567,7 +567,7 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
        struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb);
 
        /* Never answer to DCCP_PKT_REQUESTs send to broadcast or multicast */
-       if (skb->rtable->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST))
+       if (skb_rtable(skb)->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST))
                return 0;       /* discard, don't send a reset here */
 
        if (dccp_bad_service_code(sk, service)) {
index b963f35c65f6616ae5da169c3f328e7a73767ed0..05ea7440d9e51b6f40e29b7335277c4853b8ca7d 100644 (file)
@@ -314,8 +314,9 @@ static void dccp_v6_ctl_send_reset(struct sock *sk, struct sk_buff *rxskb)
        struct ipv6hdr *rxip6h;
        struct sk_buff *skb;
        struct flowi fl;
-       struct net *net = dev_net(rxskb->dst->dev);
+       struct net *net = dev_net(skb_dst(rxskb)->dev);
        struct sock *ctl_sk = net->dccp.v6_ctl_sk;
+       struct dst_entry *dst;
 
        if (dccp_hdr(rxskb)->dccph_type == DCCP_PKT_RESET)
                return;
@@ -342,8 +343,9 @@ static void dccp_v6_ctl_send_reset(struct sock *sk, struct sk_buff *rxskb)
        security_skb_classify_flow(rxskb, &fl);
 
        /* sk = NULL, but it is safe for now. RST socket required. */
-       if (!ip6_dst_lookup(ctl_sk, &skb->dst, &fl)) {
-               if (xfrm_lookup(net, &skb->dst, &fl, NULL, 0) >= 0) {
+       if (!ip6_dst_lookup(ctl_sk, &dst, &fl)) {
+               if (xfrm_lookup(net, &dst, &fl, NULL, 0) >= 0) {
+                       skb_dst_set(skb, dst);
                        ip6_xmit(ctl_sk, skb, &fl, NULL, 0);
                        DCCP_INC_STATS_BH(DCCP_MIB_OUTSEGS);
                        DCCP_INC_STATS_BH(DCCP_MIB_OUTRSTS);
index 36bcc00654d350f408c88f6c4d0f16945c2f7d63..c0e88c16d0888b5222ca250c01a27bf3078a7e2a 100644 (file)
@@ -350,7 +350,7 @@ struct sk_buff *dccp_make_response(struct sock *sk, struct dst_entry *dst,
        /* Reserve space for headers. */
        skb_reserve(skb, sk->sk_prot->max_header);
 
-       skb->dst = dst_clone(dst);
+       skb_dst_set(skb, dst_clone(dst));
 
        dreq = dccp_rsk(req);
        if (inet_rsk(req)->acked)       /* increase ISS upon retransmission */
index 9647d911f916c792a3c0e7c4a6b01f2715fd2aa7..a5e3a593e47224e8bd4a1a85ddd949141143816c 100644 (file)
@@ -1075,6 +1075,7 @@ static int dn_accept(struct socket *sock, struct socket *newsock, int flags)
        int err = 0;
        unsigned char type;
        long timeo = sock_rcvtimeo(sk, flags & O_NONBLOCK);
+       struct dst_entry *dst;
 
        lock_sock(sk);
 
@@ -1102,8 +1103,9 @@ static int dn_accept(struct socket *sock, struct socket *newsock, int flags)
        }
        release_sock(sk);
 
-       dst_release(xchg(&newsk->sk_dst_cache, skb->dst));
-       skb->dst = NULL;
+       dst = skb_dst(skb);
+       dst_release(xchg(&newsk->sk_dst_cache, dst));
+       skb_dst_set(skb, NULL);
 
        DN_SK(newsk)->state        = DN_CR;
        DN_SK(newsk)->addrrem      = cb->src_port;
@@ -1250,14 +1252,8 @@ static int dn_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
                if (skb) {
                        amount = skb->len;
                } else {
-                       skb = sk->sk_receive_queue.next;
-                       for (;;) {
-                               if (skb ==
-                                   (struct sk_buff *)&sk->sk_receive_queue)
-                                       break;
+                       skb_queue_walk(&sk->sk_receive_queue, skb)
                                amount += skb->len;
-                               skb = skb->next;
-                       }
                }
                release_sock(sk);
                err = put_user(amount, (int __user *)arg);
@@ -1644,13 +1640,13 @@ static int __dn_getsockopt(struct socket *sock, int level,int optname, char __us
 
 static int dn_data_ready(struct sock *sk, struct sk_buff_head *q, int flags, int target)
 {
-       struct sk_buff *skb = q->next;
+       struct sk_buff *skb;
        int len = 0;
 
        if (flags & MSG_OOB)
                return !skb_queue_empty(q) ? 1 : 0;
 
-       while(skb != (struct sk_buff *)q) {
+       skb_queue_walk(q, skb) {
                struct dn_skb_cb *cb = DN_SKB_CB(skb);
                len += skb->len;
 
@@ -1666,8 +1662,6 @@ static int dn_data_ready(struct sock *sk, struct sk_buff_head *q, int flags, int
                /* minimum data length for read exceeded */
                if (len >= target)
                        return 1;
-
-               skb = skb->next;
        }
 
        return 0;
@@ -1683,7 +1677,7 @@ static int dn_recvmsg(struct kiocb *iocb, struct socket *sock,
        size_t target = size > 1 ? 1 : 0;
        size_t copied = 0;
        int rv = 0;
-       struct sk_buff *skb, *nskb;
+       struct sk_buff *skb, *n;
        struct dn_skb_cb *cb = NULL;
        unsigned char eor = 0;
        long timeo = sock_rcvtimeo(sk, flags & MSG_DONTWAIT);
@@ -1758,7 +1752,7 @@ static int dn_recvmsg(struct kiocb *iocb, struct socket *sock,
                finish_wait(sk->sk_sleep, &wait);
        }
 
-       for(skb = queue->next; skb != (struct sk_buff *)queue; skb = nskb) {
+       skb_queue_walk_safe(queue, skb, n) {
                unsigned int chunk = skb->len;
                cb = DN_SKB_CB(skb);
 
@@ -1775,7 +1769,6 @@ static int dn_recvmsg(struct kiocb *iocb, struct socket *sock,
                        skb_pull(skb, chunk);
 
                eor = cb->nsp_flags & 0x40;
-               nskb = skb->next;
 
                if (skb->len == 0) {
                        skb_unlink(skb, queue);
index 05b5aa05e50ee3599a68984b12b831a79bcfe3b0..923786bd6d016044bafc5aed4c2b6a38122af7c7 100644 (file)
@@ -204,7 +204,7 @@ static void dn_short_error_report(struct neighbour *neigh, struct sk_buff *skb)
 
 static int dn_neigh_output_packet(struct sk_buff *skb)
 {
-       struct dst_entry *dst = skb->dst;
+       struct dst_entry *dst = skb_dst(skb);
        struct dn_route *rt = (struct dn_route *)dst;
        struct neighbour *neigh = dst->neighbour;
        struct net_device *dev = neigh->dev;
@@ -224,7 +224,7 @@ static int dn_neigh_output_packet(struct sk_buff *skb)
 
 static int dn_long_output(struct sk_buff *skb)
 {
-       struct dst_entry *dst = skb->dst;
+       struct dst_entry *dst = skb_dst(skb);
        struct neighbour *neigh = dst->neighbour;
        struct net_device *dev = neigh->dev;
        int headroom = dev->hard_header_len + sizeof(struct dn_long_packet) + 3;
@@ -270,7 +270,7 @@ static int dn_long_output(struct sk_buff *skb)
 
 static int dn_short_output(struct sk_buff *skb)
 {
-       struct dst_entry *dst = skb->dst;
+       struct dst_entry *dst = skb_dst(skb);
        struct neighbour *neigh = dst->neighbour;
        struct net_device *dev = neigh->dev;
        int headroom = dev->hard_header_len + sizeof(struct dn_short_packet) + 2;
@@ -313,7 +313,7 @@ static int dn_short_output(struct sk_buff *skb)
  */
 static int dn_phase3_output(struct sk_buff *skb)
 {
-       struct dst_entry *dst = skb->dst;
+       struct dst_entry *dst = skb_dst(skb);
        struct neighbour *neigh = dst->neighbour;
        struct net_device *dev = neigh->dev;
        int headroom = dev->hard_header_len + sizeof(struct dn_short_packet) + 2;
index 5d8a2a56fd397a66516cd272e25988a75a901d28..932408dca86da3de19a371469f1ea4d54dac1403 100644 (file)
@@ -578,6 +578,7 @@ out:
 static __inline__ int dn_queue_skb(struct sock *sk, struct sk_buff *skb, int sig, struct sk_buff_head *queue)
 {
        int err;
+       int skb_len;
 
        /* Cast skb->rcvbuf to unsigned... It's pointless, but reduces
           number of warnings when compiling with -W --ANK
@@ -592,22 +593,12 @@ static __inline__ int dn_queue_skb(struct sock *sk, struct sk_buff *skb, int sig
        if (err)
                goto out;
 
+       skb_len = skb->len;
        skb_set_owner_r(skb, sk);
        skb_queue_tail(queue, skb);
 
-       /* This code only runs from BH or BH protected context.
-        * Therefore the plain read_lock is ok here. -DaveM
-        */
-       read_lock(&sk->sk_callback_lock);
-       if (!sock_flag(sk, SOCK_DEAD)) {
-               struct socket *sock = sk->sk_socket;
-               wake_up_interruptible(sk->sk_sleep);
-               if (sock && sock->fasync_list &&
-                   !test_bit(SOCK_ASYNC_WAITDATA, &sock->flags))
-                       __kill_fasync(sock->fasync_list, sig,
-                                   (sig == SIGURG) ? POLL_PRI : POLL_IN);
-       }
-       read_unlock(&sk->sk_callback_lock);
+       if (!sock_flag(sk, SOCK_DEAD))
+               sk->sk_data_ready(sk, skb_len);
 out:
        return err;
 }
index 2013c25b7f5aff64ad41e1ff865072fff705ff79..a65e929ce76cc67b01b35642584fbf7b80b37355 100644 (file)
@@ -85,7 +85,7 @@ static void dn_nsp_send(struct sk_buff *skb)
        dst = sk_dst_check(sk, 0);
        if (dst) {
 try_again:
-               skb->dst = dst;
+               skb_dst_set(skb, dst);
                dst_output(skb);
                return;
        }
@@ -382,7 +382,7 @@ int dn_nsp_check_xmit_queue(struct sock *sk, struct sk_buff *skb, struct sk_buff
 {
        struct dn_skb_cb *cb = DN_SKB_CB(skb);
        struct dn_scp *scp = DN_SK(sk);
-       struct sk_buff *skb2, *list, *ack = NULL;
+       struct sk_buff *skb2, *n, *ack = NULL;
        int wakeup = 0;
        int try_retrans = 0;
        unsigned long reftime = cb->stamp;
@@ -390,9 +390,7 @@ int dn_nsp_check_xmit_queue(struct sock *sk, struct sk_buff *skb, struct sk_buff
        unsigned short xmit_count;
        unsigned short segnum;
 
-       skb2 = q->next;
-       list = (struct sk_buff *)q;
-       while(list != skb2) {
+       skb_queue_walk_safe(q, skb2, n) {
                struct dn_skb_cb *cb2 = DN_SKB_CB(skb2);
 
                if (dn_before_or_equal(cb2->segnum, acknum))
@@ -400,8 +398,6 @@ int dn_nsp_check_xmit_queue(struct sock *sk, struct sk_buff *skb, struct sk_buff
 
                /* printk(KERN_DEBUG "ack: %s %04x %04x\n", ack ? "ACK" : "SKIP", (int)cb2->segnum, (int)acknum); */
 
-               skb2 = skb2->next;
-
                if (ack == NULL)
                        continue;
 
@@ -586,7 +582,7 @@ static __inline__ void dn_nsp_do_disc(struct sock *sk, unsigned char msgflg,
         * to be able to send disc packets out which have no socket
         * associations.
         */
-       skb->dst = dst_clone(dst);
+       skb_dst_set(skb, dst_clone(dst));
        dst_output(skb);
 }
 
@@ -615,7 +611,7 @@ void dn_nsp_return_disc(struct sk_buff *skb, unsigned char msgflg,
        int ddl = 0;
        gfp_t gfp = GFP_ATOMIC;
 
-       dn_nsp_do_disc(NULL, msgflg, reason, gfp, skb->dst, ddl,
+       dn_nsp_do_disc(NULL, msgflg, reason, gfp, skb_dst(skb), ddl,
                        NULL, cb->src_port, cb->dst_port);
 }
 
index 0cc4394117dfa0a7417a35652363c5bb99e5de5a..1d6ca8a98dc62bf4f6e6660e4b3662393089d638 100644 (file)
@@ -678,7 +678,7 @@ out:
 
 static int dn_output(struct sk_buff *skb)
 {
-       struct dst_entry *dst = skb->dst;
+       struct dst_entry *dst = skb_dst(skb);
        struct dn_route *rt = (struct dn_route *)dst;
        struct net_device *dev = dst->dev;
        struct dn_skb_cb *cb = DN_SKB_CB(skb);
@@ -717,7 +717,7 @@ error:
 static int dn_forward(struct sk_buff *skb)
 {
        struct dn_skb_cb *cb = DN_SKB_CB(skb);
-       struct dst_entry *dst = skb->dst;
+       struct dst_entry *dst = skb_dst(skb);
        struct dn_dev *dn_db = dst->dev->dn_ptr;
        struct dn_route *rt;
        struct neighbour *neigh = dst->neighbour;
@@ -730,7 +730,7 @@ static int dn_forward(struct sk_buff *skb)
                goto drop;
 
        /* Ensure that we have enough space for headers */
-       rt = (struct dn_route *)skb->dst;
+       rt = (struct dn_route *)skb_dst(skb);
        header_len = dn_db->use_long ? 21 : 6;
        if (skb_cow(skb, LL_RESERVED_SPACE(rt->u.dst.dev)+header_len))
                goto drop;
@@ -1392,7 +1392,8 @@ make_route:
                goto e_neighbour;
 
        hash = dn_hash(rt->fl.fld_src, rt->fl.fld_dst);
-       dn_insert_route(rt, hash, (struct dn_route **)&skb->dst);
+       dn_insert_route(rt, hash, &rt);
+       skb_dst_set(skb, &rt->u.dst);
 
 done:
        if (neigh)
@@ -1424,7 +1425,7 @@ static int dn_route_input(struct sk_buff *skb)
        struct dn_skb_cb *cb = DN_SKB_CB(skb);
        unsigned hash = dn_hash(cb->src, cb->dst);
 
-       if (skb->dst)
+       if (skb_dst(skb))
                return 0;
 
        rcu_read_lock();
@@ -1437,7 +1438,7 @@ static int dn_route_input(struct sk_buff *skb)
                    (rt->fl.iif == cb->iif)) {
                        dst_use(&rt->u.dst, jiffies);
                        rcu_read_unlock();
-                       skb->dst = (struct dst_entry *)rt;
+                       skb_dst_set(skb, (struct dst_entry *)rt);
                        return 0;
                }
        }
@@ -1449,7 +1450,7 @@ static int dn_route_input(struct sk_buff *skb)
 static int dn_rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq,
                           int event, int nowait, unsigned int flags)
 {
-       struct dn_route *rt = (struct dn_route *)skb->dst;
+       struct dn_route *rt = (struct dn_route *)skb_dst(skb);
        struct rtmsg *r;
        struct nlmsghdr *nlh;
        unsigned char *b = skb_tail_pointer(skb);
@@ -1554,7 +1555,7 @@ static int dn_cache_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, void
                err = dn_route_input(skb);
                local_bh_enable();
                memset(cb, 0, sizeof(struct dn_skb_cb));
-               rt = (struct dn_route *)skb->dst;
+               rt = (struct dn_route *)skb_dst(skb);
                if (!err && -rt->u.dst.error)
                        err = rt->u.dst.error;
        } else {
@@ -1570,7 +1571,7 @@ static int dn_cache_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, void
        skb->dev = NULL;
        if (err)
                goto out_free;
-       skb->dst = &rt->u.dst;
+       skb_dst_set(skb, &rt->u.dst);
        if (rtm->rtm_flags & RTM_F_NOTIFY)
                rt->rt_flags |= RTCF_NOTIFY;
 
@@ -1622,15 +1623,15 @@ int dn_cache_dump(struct sk_buff *skb, struct netlink_callback *cb)
                        rt = rcu_dereference(rt->u.dst.dn_next), idx++) {
                        if (idx < s_idx)
                                continue;
-                       skb->dst = dst_clone(&rt->u.dst);
+                       skb_dst_set(skb, dst_clone(&rt->u.dst));
                        if (dn_rt_fill_info(skb, NETLINK_CB(cb->skb).pid,
                                        cb->nlh->nlmsg_seq, RTM_NEWROUTE,
                                        1, NLM_F_MULTI) <= 0) {
-                               dst_release(xchg(&skb->dst, NULL));
+                               skb_dst_drop(skb);
                                rcu_read_unlock_bh();
                                goto done;
                        }
-                       dst_release(xchg(&skb->dst, NULL));
+                       skb_dst_drop(skb);
                }
                rcu_read_unlock_bh();
        }
index 14fbca55e908fba5e067312dc9561e94af2606b0..72495f25269fa5435cd5b17f3e403ba0e74ee4ba 100644 (file)
@@ -115,7 +115,7 @@ static int dn_fib_rule_match(struct fib_rule *rule, struct flowi *fl, int flags)
 }
 
 static int dn_fib_rule_configure(struct fib_rule *rule, struct sk_buff *skb,
-                                struct nlmsghdr *nlh, struct fib_rule_hdr *frh,
+                                struct fib_rule_hdr *frh,
                                 struct nlattr **tb)
 {
        int err = -EINVAL;
@@ -192,7 +192,7 @@ unsigned dnet_addr_type(__le16 addr)
 }
 
 static int dn_fib_rule_fill(struct fib_rule *rule, struct sk_buff *skb,
-                           struct nlmsghdr *nlh, struct fib_rule_hdr *frh)
+                           struct fib_rule_hdr *frh)
 {
        struct dn_fib_rule *r = (struct dn_fib_rule *)rule;
 
index ed131181215dc3d8cb642101ca3f958116c74d80..2175e6d5cc8d4dcab16e06c069d9016f4880be18 100644 (file)
@@ -67,7 +67,7 @@ static int dsa_slave_open(struct net_device *dev)
                return -ENETDOWN;
 
        if (compare_ether_addr(dev->dev_addr, master->dev_addr)) {
-               err = dev_unicast_add(master, dev->dev_addr, ETH_ALEN);
+               err = dev_unicast_add(master, dev->dev_addr);
                if (err < 0)
                        goto out;
        }
@@ -90,7 +90,7 @@ clear_allmulti:
                dev_set_allmulti(master, -1);
 del_unicast:
        if (compare_ether_addr(dev->dev_addr, master->dev_addr))
-               dev_unicast_delete(master, dev->dev_addr, ETH_ALEN);
+               dev_unicast_delete(master, dev->dev_addr);
 out:
        return err;
 }
@@ -108,7 +108,7 @@ static int dsa_slave_close(struct net_device *dev)
                dev_set_promiscuity(master, -1);
 
        if (compare_ether_addr(dev->dev_addr, master->dev_addr))
-               dev_unicast_delete(master, dev->dev_addr, ETH_ALEN);
+               dev_unicast_delete(master, dev->dev_addr);
 
        return 0;
 }
@@ -147,13 +147,13 @@ static int dsa_slave_set_mac_address(struct net_device *dev, void *a)
                goto out;
 
        if (compare_ether_addr(addr->sa_data, master->dev_addr)) {
-               err = dev_unicast_add(master, addr->sa_data, ETH_ALEN);
+               err = dev_unicast_add(master, addr->sa_data);
                if (err < 0)
                        return err;
        }
 
        if (compare_ether_addr(dev->dev_addr, master->dev_addr))
-               dev_unicast_delete(master, dev->dev_addr, ETH_ALEN);
+               dev_unicast_delete(master, dev->dev_addr);
 
 out:
        memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
index 6f479fa522c30c3651dfab020d10d2b6a501efc5..8121bf0029e305c6d13267c9aeee364647fcea97 100644 (file)
@@ -901,15 +901,10 @@ static void aun_tx_ack(unsigned long seq, int result)
        struct ec_cb *eb;
 
        spin_lock_irqsave(&aun_queue_lock, flags);
-       skb = skb_peek(&aun_queue);
-       while (skb && skb != (struct sk_buff *)&aun_queue)
-       {
-               struct sk_buff *newskb = skb->next;
+       skb_queue_walk(&aun_queue, skb) {
                eb = (struct ec_cb *)&skb->cb;
                if (eb->seq == seq)
                        goto foundit;
-
-               skb = newskb;
        }
        spin_unlock_irqrestore(&aun_queue_lock, flags);
        printk(KERN_DEBUG "AUN: unknown sequence %ld\n", seq);
@@ -982,23 +977,18 @@ static void aun_data_available(struct sock *sk, int slen)
 
 static void ab_cleanup(unsigned long h)
 {
-       struct sk_buff *skb;
+       struct sk_buff *skb, *n;
        unsigned long flags;
 
        spin_lock_irqsave(&aun_queue_lock, flags);
-       skb = skb_peek(&aun_queue);
-       while (skb && skb != (struct sk_buff *)&aun_queue)
-       {
-               struct sk_buff *newskb = skb->next;
+       skb_queue_walk_safe(&aun_queue, skb, n) {
                struct ec_cb *eb = (struct ec_cb *)&skb->cb;
-               if ((jiffies - eb->start) > eb->timeout)
-               {
+               if ((jiffies - eb->start) > eb->timeout) {
                        tx_result(skb->sk, eb->cookie,
                                  ECTYPE_TRANSMIT_NOT_PRESENT);
                        skb_unlink(skb, &aun_queue);
                        kfree_skb(skb);
                }
-               skb = newskb;
        }
        spin_unlock_irqrestore(&aun_queue_lock, flags);
 
index 280352aba4034bc2d343171e72f6942635fd74c3..5a883affecd3d2388f8fa4a27e35f2058b053518 100644 (file)
@@ -337,11 +337,6 @@ const struct header_ops eth_header_ops ____cacheline_aligned = {
 void ether_setup(struct net_device *dev)
 {
        dev->header_ops         = &eth_header_ops;
-#ifdef CONFIG_COMPAT_NET_DEV_OPS
-       dev->change_mtu         = eth_change_mtu;
-       dev->set_mac_address    = eth_mac_addr;
-       dev->validate_addr      = eth_validate_addr;
-#endif
        dev->type               = ARPHRD_ETHER;
        dev->hard_header_len    = ETH_HLEN;
        dev->mtu                = ETH_DATA_LEN;
diff --git a/net/ieee802154/Kconfig b/net/ieee802154/Kconfig
new file mode 100644 (file)
index 0000000..1c1de97
--- /dev/null
@@ -0,0 +1,12 @@
+config IEEE802154
+       tristate "IEEE Std 802.15.4 Low-Rate Wireless Personal Area Networks support (EXPERIMENTAL)"
+       depends on EXPERIMENTAL
+       ---help---
+         IEEE Std 802.15.4 defines a low data rate, low power and low
+         complexity short range wireless personal area networks. It was
+         designed to organise networks of sensors, switches, etc automation
+         devices. Maximum allowed data rate is 250 kb/s and typical personal
+         operating space around 10m.
+
+         Say Y here to compile LR-WPAN support into the kernel or say M to
+         compile it as modules.
diff --git a/net/ieee802154/Makefile b/net/ieee802154/Makefile
new file mode 100644 (file)
index 0000000..f99338a
--- /dev/null
@@ -0,0 +1,5 @@
+obj-$(CONFIG_IEEE802154) +=    nl802154.o af_802154.o
+nl802154-y             := netlink.o nl_policy.o
+af_802154-y            := af_ieee802154.o raw.o dgram.o
+
+ccflags-y += -Wall -DDEBUG
diff --git a/net/ieee802154/af802154.h b/net/ieee802154/af802154.h
new file mode 100644 (file)
index 0000000..b1ec525
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Internal interfaces for ieee 802.15.4 address family.
+ *
+ * Copyright 2007, 2008, 2009 Siemens AG
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Written by:
+ * Sergey Lapin <slapin@ossfans.org>
+ * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
+ */
+
+#ifndef AF802154_H
+#define AF802154_H
+
+struct sk_buff;
+struct net_devce;
+extern struct proto ieee802154_raw_prot;
+extern struct proto ieee802154_dgram_prot;
+void ieee802154_raw_deliver(struct net_device *dev, struct sk_buff *skb);
+int ieee802154_dgram_deliver(struct net_device *dev, struct sk_buff *skb);
+struct net_device *ieee802154_get_dev(struct net *net,
+               struct ieee802154_addr *addr);
+
+#endif
diff --git a/net/ieee802154/af_ieee802154.c b/net/ieee802154/af_ieee802154.c
new file mode 100644 (file)
index 0000000..882a927
--- /dev/null
@@ -0,0 +1,372 @@
+/*
+ * IEEE802154.4 socket interface
+ *
+ * Copyright 2007, 2008 Siemens AG
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Written by:
+ * Sergey Lapin <slapin@ossfans.org>
+ * Maxim Gorbachyov <maxim.gorbachev@siemens.com>
+ */
+
+#include <linux/net.h>
+#include <linux/capability.h>
+#include <linux/module.h>
+#include <linux/if_arp.h>
+#include <linux/if.h>
+#include <linux/termios.h>     /* For TIOCOUTQ/INQ */
+#include <linux/list.h>
+#include <net/datalink.h>
+#include <net/psnap.h>
+#include <net/sock.h>
+#include <net/tcp_states.h>
+#include <net/route.h>
+
+#include <net/ieee802154/af_ieee802154.h>
+#include <net/ieee802154/netdevice.h>
+
+#include "af802154.h"
+
+#define DBG_DUMP(data, len) { \
+       int i; \
+       pr_debug("function: %s: data: len %d:\n", __func__, len); \
+       for (i = 0; i < len; i++) {\
+               pr_debug("%02x: %02x\n", i, (data)[i]); \
+       } \
+}
+
+/*
+ * Utility function for families
+ */
+struct net_device *ieee802154_get_dev(struct net *net,
+               struct ieee802154_addr *addr)
+{
+       struct net_device *dev = NULL;
+       struct net_device *tmp;
+       u16 pan_id, short_addr;
+
+       switch (addr->addr_type) {
+       case IEEE802154_ADDR_LONG:
+               rtnl_lock();
+               dev = dev_getbyhwaddr(net, ARPHRD_IEEE802154, addr->hwaddr);
+               if (dev)
+                       dev_hold(dev);
+               rtnl_unlock();
+               break;
+       case IEEE802154_ADDR_SHORT:
+               if (addr->pan_id == 0xffff ||
+                   addr->short_addr == IEEE802154_ADDR_UNDEF ||
+                   addr->short_addr == 0xffff)
+                       break;
+
+               rtnl_lock();
+
+               for_each_netdev(net, tmp) {
+                       if (tmp->type != ARPHRD_IEEE802154)
+                               continue;
+
+                       pan_id = ieee802154_mlme_ops(tmp)->get_pan_id(tmp);
+                       short_addr =
+                               ieee802154_mlme_ops(tmp)->get_short_addr(tmp);
+
+                       if (pan_id == addr->pan_id &&
+                           short_addr == addr->short_addr) {
+                               dev = tmp;
+                               dev_hold(dev);
+                               break;
+                       }
+               }
+
+               rtnl_unlock();
+               break;
+       default:
+               pr_warning("Unsupported ieee802154 address type: %d\n",
+                               addr->addr_type);
+               break;
+       }
+
+       return dev;
+}
+
+static int ieee802154_sock_release(struct socket *sock)
+{
+       struct sock *sk = sock->sk;
+
+       if (sk) {
+               sock->sk = NULL;
+               sk->sk_prot->close(sk, 0);
+       }
+       return 0;
+}
+static int ieee802154_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
+               struct msghdr *msg, size_t len)
+{
+       struct sock *sk = sock->sk;
+
+       return sk->sk_prot->sendmsg(iocb, sk, msg, len);
+}
+
+static int ieee802154_sock_bind(struct socket *sock, struct sockaddr *uaddr,
+               int addr_len)
+{
+       struct sock *sk = sock->sk;
+
+       if (sk->sk_prot->bind)
+               return sk->sk_prot->bind(sk, uaddr, addr_len);
+
+       return sock_no_bind(sock, uaddr, addr_len);
+}
+
+static int ieee802154_sock_connect(struct socket *sock, struct sockaddr *uaddr,
+                       int addr_len, int flags)
+{
+       struct sock *sk = sock->sk;
+
+       if (uaddr->sa_family == AF_UNSPEC)
+               return sk->sk_prot->disconnect(sk, flags);
+
+       return sk->sk_prot->connect(sk, uaddr, addr_len);
+}
+
+static int ieee802154_dev_ioctl(struct sock *sk, struct ifreq __user *arg,
+               unsigned int cmd)
+{
+       struct ifreq ifr;
+       int ret = -EINVAL;
+       struct net_device *dev;
+
+       if (copy_from_user(&ifr, arg, sizeof(struct ifreq)))
+               return -EFAULT;
+
+       ifr.ifr_name[IFNAMSIZ-1] = 0;
+
+       dev_load(sock_net(sk), ifr.ifr_name);
+       dev = dev_get_by_name(sock_net(sk), ifr.ifr_name);
+       if (dev->type == ARPHRD_IEEE802154 ||
+           dev->type == ARPHRD_IEEE802154_PHY)
+               ret = dev->netdev_ops->ndo_do_ioctl(dev, &ifr, cmd);
+
+       if (!ret && copy_to_user(arg, &ifr, sizeof(struct ifreq)))
+               ret = -EFAULT;
+       dev_put(dev);
+
+       return ret;
+}
+
+static int ieee802154_sock_ioctl(struct socket *sock, unsigned int cmd,
+               unsigned long arg)
+{
+       struct sock *sk = sock->sk;
+
+       switch (cmd) {
+       case SIOCGSTAMP:
+               return sock_get_timestamp(sk, (struct timeval __user *)arg);
+       case SIOCGSTAMPNS:
+               return sock_get_timestampns(sk, (struct timespec __user *)arg);
+       case SIOCGIFADDR:
+       case SIOCSIFADDR:
+               return ieee802154_dev_ioctl(sk, (struct ifreq __user *)arg,
+                               cmd);
+       default:
+               if (!sk->sk_prot->ioctl)
+                       return -ENOIOCTLCMD;
+               return sk->sk_prot->ioctl(sk, cmd, arg);
+       }
+}
+
+static const struct proto_ops ieee802154_raw_ops = {
+       .family            = PF_IEEE802154,
+       .owner             = THIS_MODULE,
+       .release           = ieee802154_sock_release,
+       .bind              = ieee802154_sock_bind,
+       .connect           = ieee802154_sock_connect,
+       .socketpair        = sock_no_socketpair,
+       .accept            = sock_no_accept,
+       .getname           = sock_no_getname,
+       .poll              = datagram_poll,
+       .ioctl             = ieee802154_sock_ioctl,
+       .listen            = sock_no_listen,
+       .shutdown          = sock_no_shutdown,
+       .setsockopt        = sock_common_setsockopt,
+       .getsockopt        = sock_common_getsockopt,
+       .sendmsg           = ieee802154_sock_sendmsg,
+       .recvmsg           = sock_common_recvmsg,
+       .mmap              = sock_no_mmap,
+       .sendpage          = sock_no_sendpage,
+#ifdef CONFIG_COMPAT
+       .compat_setsockopt = compat_sock_common_setsockopt,
+       .compat_getsockopt = compat_sock_common_getsockopt,
+#endif
+};
+
+static const struct proto_ops ieee802154_dgram_ops = {
+       .family            = PF_IEEE802154,
+       .owner             = THIS_MODULE,
+       .release           = ieee802154_sock_release,
+       .bind              = ieee802154_sock_bind,
+       .connect           = ieee802154_sock_connect,
+       .socketpair        = sock_no_socketpair,
+       .accept            = sock_no_accept,
+       .getname           = sock_no_getname,
+       .poll              = datagram_poll,
+       .ioctl             = ieee802154_sock_ioctl,
+       .listen            = sock_no_listen,
+       .shutdown          = sock_no_shutdown,
+       .setsockopt        = sock_common_setsockopt,
+       .getsockopt        = sock_common_getsockopt,
+       .sendmsg           = ieee802154_sock_sendmsg,
+       .recvmsg           = sock_common_recvmsg,
+       .mmap              = sock_no_mmap,
+       .sendpage          = sock_no_sendpage,
+#ifdef CONFIG_COMPAT
+       .compat_setsockopt = compat_sock_common_setsockopt,
+       .compat_getsockopt = compat_sock_common_getsockopt,
+#endif
+};
+
+
+/*
+ * Create a socket. Initialise the socket, blank the addresses
+ * set the state.
+ */
+static int ieee802154_create(struct net *net, struct socket *sock,
+               int protocol)
+{
+       struct sock *sk;
+       int rc;
+       struct proto *proto;
+       const struct proto_ops *ops;
+
+       if (net != &init_net)
+               return -EAFNOSUPPORT;
+
+       switch (sock->type) {
+       case SOCK_RAW:
+               proto = &ieee802154_raw_prot;
+               ops = &ieee802154_raw_ops;
+               break;
+       case SOCK_DGRAM:
+               proto = &ieee802154_dgram_prot;
+               ops = &ieee802154_dgram_ops;
+               break;
+       default:
+               rc = -ESOCKTNOSUPPORT;
+               goto out;
+       }
+
+       rc = -ENOMEM;
+       sk = sk_alloc(net, PF_IEEE802154, GFP_KERNEL, proto);
+       if (!sk)
+               goto out;
+       rc = 0;
+
+       sock->ops = ops;
+
+       sock_init_data(sock, sk);
+       /* FIXME: sk->sk_destruct */
+       sk->sk_family = PF_IEEE802154;
+
+       /* Checksums on by default */
+       sock_set_flag(sk, SOCK_ZAPPED);
+
+       if (sk->sk_prot->hash)
+               sk->sk_prot->hash(sk);
+
+       if (sk->sk_prot->init) {
+               rc = sk->sk_prot->init(sk);
+               if (rc)
+                       sk_common_release(sk);
+       }
+out:
+       return rc;
+}
+
+static struct net_proto_family ieee802154_family_ops = {
+       .family         = PF_IEEE802154,
+       .create         = ieee802154_create,
+       .owner          = THIS_MODULE,
+};
+
+static int ieee802154_rcv(struct sk_buff *skb, struct net_device *dev,
+       struct packet_type *pt, struct net_device *orig_dev)
+{
+       DBG_DUMP(skb->data, skb->len);
+       if (!netif_running(dev))
+               return -ENODEV;
+       pr_debug("got frame, type %d, dev %p\n", dev->type, dev);
+
+       if (!net_eq(dev_net(dev), &init_net))
+               goto drop;
+
+       ieee802154_raw_deliver(dev, skb);
+
+       if (dev->type != ARPHRD_IEEE802154)
+               goto drop;
+
+       if (skb->pkt_type != PACKET_OTHERHOST)
+               return ieee802154_dgram_deliver(dev, skb);
+
+drop:
+       kfree_skb(skb);
+       return NET_RX_DROP;
+}
+
+
+static struct packet_type ieee802154_packet_type = {
+       .type = __constant_htons(ETH_P_IEEE802154),
+       .func = ieee802154_rcv,
+};
+
+static int __init af_ieee802154_init(void)
+{
+       int rc = -EINVAL;
+
+       rc = proto_register(&ieee802154_raw_prot, 1);
+       if (rc)
+               goto out;
+
+       rc = proto_register(&ieee802154_dgram_prot, 1);
+       if (rc)
+               goto err_dgram;
+
+       /* Tell SOCKET that we are alive */
+       rc = sock_register(&ieee802154_family_ops);
+       if (rc)
+               goto err_sock;
+       dev_add_pack(&ieee802154_packet_type);
+
+       rc = 0;
+       goto out;
+
+err_sock:
+       proto_unregister(&ieee802154_dgram_prot);
+err_dgram:
+       proto_unregister(&ieee802154_raw_prot);
+out:
+       return rc;
+}
+static void __exit af_ieee802154_remove(void)
+{
+       dev_remove_pack(&ieee802154_packet_type);
+       sock_unregister(PF_IEEE802154);
+       proto_unregister(&ieee802154_dgram_prot);
+       proto_unregister(&ieee802154_raw_prot);
+}
+
+module_init(af_ieee802154_init);
+module_exit(af_ieee802154_remove);
+
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_NETPROTO(PF_IEEE802154);
diff --git a/net/ieee802154/dgram.c b/net/ieee802154/dgram.c
new file mode 100644 (file)
index 0000000..1779677
--- /dev/null
@@ -0,0 +1,394 @@
+/*
+ * ZigBee socket interface
+ *
+ * Copyright 2007, 2008 Siemens AG
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Written by:
+ * Sergey Lapin <slapin@ossfans.org>
+ * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
+ */
+
+#include <linux/net.h>
+#include <linux/module.h>
+#include <linux/if_arp.h>
+#include <linux/list.h>
+#include <net/sock.h>
+#include <net/ieee802154/af_ieee802154.h>
+#include <net/ieee802154/mac_def.h>
+#include <net/ieee802154/netdevice.h>
+
+#include <asm/ioctls.h>
+
+#include "af802154.h"
+
+static HLIST_HEAD(dgram_head);
+static DEFINE_RWLOCK(dgram_lock);
+
+struct dgram_sock {
+       struct sock sk;
+
+       int bound;
+       struct ieee802154_addr src_addr;
+       struct ieee802154_addr dst_addr;
+};
+
+static inline struct dgram_sock *dgram_sk(const struct sock *sk)
+{
+       return container_of(sk, struct dgram_sock, sk);
+}
+
+
+static void dgram_hash(struct sock *sk)
+{
+       write_lock_bh(&dgram_lock);
+       sk_add_node(sk, &dgram_head);
+       sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
+       write_unlock_bh(&dgram_lock);
+}
+
+static void dgram_unhash(struct sock *sk)
+{
+       write_lock_bh(&dgram_lock);
+       if (sk_del_node_init(sk))
+               sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1);
+       write_unlock_bh(&dgram_lock);
+}
+
+static int dgram_init(struct sock *sk)
+{
+       struct dgram_sock *ro = dgram_sk(sk);
+
+       ro->dst_addr.addr_type = IEEE802154_ADDR_LONG;
+       ro->dst_addr.pan_id = 0xffff;
+       memset(&ro->dst_addr.hwaddr, 0xff, sizeof(ro->dst_addr.hwaddr));
+       return 0;
+}
+
+static void dgram_close(struct sock *sk, long timeout)
+{
+       sk_common_release(sk);
+}
+
+static int dgram_bind(struct sock *sk, struct sockaddr *uaddr, int len)
+{
+       struct sockaddr_ieee802154 *addr = (struct sockaddr_ieee802154 *)uaddr;
+       struct dgram_sock *ro = dgram_sk(sk);
+       int err = 0;
+       struct net_device *dev;
+
+       ro->bound = 0;
+
+       if (len < sizeof(*addr))
+               return -EINVAL;
+
+       if (addr->family != AF_IEEE802154)
+               return -EINVAL;
+
+       lock_sock(sk);
+
+       dev = ieee802154_get_dev(sock_net(sk), &addr->addr);
+       if (!dev) {
+               err = -ENODEV;
+               goto out;
+       }
+
+       if (dev->type != ARPHRD_IEEE802154) {
+               err = -ENODEV;
+               goto out_put;
+       }
+
+       memcpy(&ro->src_addr, &addr->addr, sizeof(struct ieee802154_addr));
+
+       ro->bound = 1;
+out_put:
+       dev_put(dev);
+out:
+       release_sock(sk);
+
+       return err;
+}
+
+static int dgram_ioctl(struct sock *sk, int cmd, unsigned long arg)
+{
+       switch (cmd) {
+       case SIOCOUTQ:
+       {
+               int amount = atomic_read(&sk->sk_wmem_alloc);
+               return put_user(amount, (int __user *)arg);
+       }
+
+       case SIOCINQ:
+       {
+               struct sk_buff *skb;
+               unsigned long amount;
+
+               amount = 0;
+               spin_lock_bh(&sk->sk_receive_queue.lock);
+               skb = skb_peek(&sk->sk_receive_queue);
+               if (skb != NULL) {
+                       /*
+                        * We will only return the amount
+                        * of this packet since that is all
+                        * that will be read.
+                        */
+                       /* FIXME: parse the header for more correct value */
+                       amount = skb->len - (3+8+8);
+               }
+               spin_unlock_bh(&sk->sk_receive_queue.lock);
+               return put_user(amount, (int __user *)arg);
+       }
+
+       }
+       return -ENOIOCTLCMD;
+}
+
+/* FIXME: autobind */
+static int dgram_connect(struct sock *sk, struct sockaddr *uaddr,
+                       int len)
+{
+       struct sockaddr_ieee802154 *addr = (struct sockaddr_ieee802154 *)uaddr;
+       struct dgram_sock *ro = dgram_sk(sk);
+       int err = 0;
+
+       if (len < sizeof(*addr))
+               return -EINVAL;
+
+       if (addr->family != AF_IEEE802154)
+               return -EINVAL;
+
+       lock_sock(sk);
+
+       if (!ro->bound) {
+               err = -ENETUNREACH;
+               goto out;
+       }
+
+       memcpy(&ro->dst_addr, &addr->addr, sizeof(struct ieee802154_addr));
+
+out:
+       release_sock(sk);
+       return err;
+}
+
+static int dgram_disconnect(struct sock *sk, int flags)
+{
+       struct dgram_sock *ro = dgram_sk(sk);
+
+       lock_sock(sk);
+
+       ro->dst_addr.addr_type = IEEE802154_ADDR_LONG;
+       memset(&ro->dst_addr.hwaddr, 0xff, sizeof(ro->dst_addr.hwaddr));
+
+       release_sock(sk);
+
+       return 0;
+}
+
+static int dgram_sendmsg(struct kiocb *iocb, struct sock *sk,
+               struct msghdr *msg, size_t size)
+{
+       struct net_device *dev;
+       unsigned mtu;
+       struct sk_buff *skb;
+       struct dgram_sock *ro = dgram_sk(sk);
+       int err;
+
+       if (msg->msg_flags & MSG_OOB) {
+               pr_debug("msg->msg_flags = 0x%x\n", msg->msg_flags);
+               return -EOPNOTSUPP;
+       }
+
+       if (!ro->bound)
+               dev = dev_getfirstbyhwtype(sock_net(sk), ARPHRD_IEEE802154);
+       else
+               dev = ieee802154_get_dev(sock_net(sk), &ro->src_addr);
+
+       if (!dev) {
+               pr_debug("no dev\n");
+               err = -ENXIO;
+               goto out;
+       }
+       mtu = dev->mtu;
+       pr_debug("name = %s, mtu = %u\n", dev->name, mtu);
+
+       skb = sock_alloc_send_skb(sk, LL_ALLOCATED_SPACE(dev) + size,
+                       msg->msg_flags & MSG_DONTWAIT,
+                       &err);
+       if (!skb)
+               goto out_dev;
+
+       skb_reserve(skb, LL_RESERVED_SPACE(dev));
+
+       skb_reset_network_header(skb);
+
+       mac_cb(skb)->flags = IEEE802154_FC_TYPE_DATA | MAC_CB_FLAG_ACKREQ;
+       mac_cb(skb)->seq = ieee802154_mlme_ops(dev)->get_dsn(dev);
+       err = dev_hard_header(skb, dev, ETH_P_IEEE802154, &ro->dst_addr,
+                       ro->bound ? &ro->src_addr : NULL, size);
+       if (err < 0)
+               goto out_skb;
+
+       skb_reset_mac_header(skb);
+
+       err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size);
+       if (err < 0)
+               goto out_skb;
+
+       if (size > mtu) {
+               pr_debug("size = %Zu, mtu = %u\n", size, mtu);
+               err = -EINVAL;
+               goto out_skb;
+       }
+
+       skb->dev = dev;
+       skb->sk  = sk;
+       skb->protocol = htons(ETH_P_IEEE802154);
+
+       dev_put(dev);
+
+       err = dev_queue_xmit(skb);
+       if (err > 0)
+               err = net_xmit_errno(err);
+
+       return err ?: size;
+
+out_skb:
+       kfree_skb(skb);
+out_dev:
+       dev_put(dev);
+out:
+       return err;
+}
+
+static int dgram_recvmsg(struct kiocb *iocb, struct sock *sk,
+               struct msghdr *msg, size_t len, int noblock, int flags,
+               int *addr_len)
+{
+       size_t copied = 0;
+       int err = -EOPNOTSUPP;
+       struct sk_buff *skb;
+
+       skb = skb_recv_datagram(sk, flags, noblock, &err);
+       if (!skb)
+               goto out;
+
+       copied = skb->len;
+       if (len < copied) {
+               msg->msg_flags |= MSG_TRUNC;
+               copied = len;
+       }
+
+       /* FIXME: skip headers if necessary ?! */
+       err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
+       if (err)
+               goto done;
+
+       sock_recv_timestamp(msg, sk, skb);
+
+       if (flags & MSG_TRUNC)
+               copied = skb->len;
+done:
+       skb_free_datagram(sk, skb);
+out:
+       if (err)
+               return err;
+       return copied;
+}
+
+static int dgram_rcv_skb(struct sock *sk, struct sk_buff *skb)
+{
+       if (sock_queue_rcv_skb(sk, skb) < 0) {
+               atomic_inc(&sk->sk_drops);
+               kfree_skb(skb);
+               return NET_RX_DROP;
+       }
+
+       return NET_RX_SUCCESS;
+}
+
+static inline int ieee802154_match_sock(u8 *hw_addr, u16 pan_id,
+               u16 short_addr, struct dgram_sock *ro)
+{
+       if (!ro->bound)
+               return 1;
+
+       if (ro->src_addr.addr_type == IEEE802154_ADDR_LONG &&
+           !memcmp(ro->src_addr.hwaddr, hw_addr, IEEE802154_ADDR_LEN))
+               return 1;
+
+       if (ro->src_addr.addr_type == IEEE802154_ADDR_SHORT &&
+                    pan_id == ro->src_addr.pan_id &&
+                    short_addr == ro->src_addr.short_addr)
+               return 1;
+
+       return 0;
+}
+
+int ieee802154_dgram_deliver(struct net_device *dev, struct sk_buff *skb)
+{
+       struct sock *sk, *prev = NULL;
+       struct hlist_node *node;
+       int ret = NET_RX_SUCCESS;
+       u16 pan_id, short_addr;
+
+       /* Data frame processing */
+       BUG_ON(dev->type != ARPHRD_IEEE802154);
+
+       pan_id = ieee802154_mlme_ops(dev)->get_pan_id(dev);
+       short_addr = ieee802154_mlme_ops(dev)->get_short_addr(dev);
+
+       read_lock(&dgram_lock);
+       sk_for_each(sk, node, &dgram_head) {
+               if (ieee802154_match_sock(dev->dev_addr, pan_id, short_addr,
+                                       dgram_sk(sk))) {
+                       if (prev) {
+                               struct sk_buff *clone;
+                               clone = skb_clone(skb, GFP_ATOMIC);
+                               if (clone)
+                                       dgram_rcv_skb(prev, clone);
+                       }
+
+                       prev = sk;
+               }
+       }
+
+       if (prev)
+               dgram_rcv_skb(prev, skb);
+       else {
+               kfree_skb(skb);
+               ret = NET_RX_DROP;
+       }
+       read_unlock(&dgram_lock);
+
+       return ret;
+}
+
+struct proto ieee802154_dgram_prot = {
+       .name           = "IEEE-802.15.4-MAC",
+       .owner          = THIS_MODULE,
+       .obj_size       = sizeof(struct dgram_sock),
+       .init           = dgram_init,
+       .close          = dgram_close,
+       .bind           = dgram_bind,
+       .sendmsg        = dgram_sendmsg,
+       .recvmsg        = dgram_recvmsg,
+       .hash           = dgram_hash,
+       .unhash         = dgram_unhash,
+       .connect        = dgram_connect,
+       .disconnect     = dgram_disconnect,
+       .ioctl          = dgram_ioctl,
+};
+
diff --git a/net/ieee802154/netlink.c b/net/ieee802154/netlink.c
new file mode 100644 (file)
index 0000000..105ad10
--- /dev/null
@@ -0,0 +1,523 @@
+/*
+ * Netlink inteface for IEEE 802.15.4 stack
+ *
+ * Copyright 2007, 2008 Siemens AG
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Written by:
+ * Sergey Lapin <slapin@ossfans.org>
+ * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
+ */
+
+#include <linux/kernel.h>
+#include <linux/if_arp.h>
+#include <linux/netdevice.h>
+#include <net/netlink.h>
+#include <net/genetlink.h>
+#include <linux/nl802154.h>
+#include <net/ieee802154/af_ieee802154.h>
+#include <net/ieee802154/nl802154.h>
+#include <net/ieee802154/netdevice.h>
+
+static unsigned int ieee802154_seq_num;
+
+static struct genl_family ieee802154_coordinator_family = {
+       .id             = GENL_ID_GENERATE,
+       .hdrsize        = 0,
+       .name           = IEEE802154_NL_NAME,
+       .version        = 1,
+       .maxattr        = IEEE802154_ATTR_MAX,
+};
+
+static struct genl_multicast_group ieee802154_coord_mcgrp = {
+       .name           = IEEE802154_MCAST_COORD_NAME,
+};
+
+static struct genl_multicast_group ieee802154_beacon_mcgrp = {
+       .name           = IEEE802154_MCAST_BEACON_NAME,
+};
+
+/* Requests to userspace */
+static struct sk_buff *ieee802154_nl_create(int flags, u8 req)
+{
+       void *hdr;
+       struct sk_buff *msg = nlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC);
+
+       if (!msg)
+               return NULL;
+
+       hdr = genlmsg_put(msg, 0, ieee802154_seq_num++,
+                       &ieee802154_coordinator_family, flags, req);
+       if (!hdr) {
+               nlmsg_free(msg);
+               return NULL;
+       }
+
+       return msg;
+}
+
+static int ieee802154_nl_finish(struct sk_buff *msg)
+{
+       /* XXX: nlh is right at the start of msg */
+       void *hdr = genlmsg_data(NLMSG_DATA(msg->data));
+
+       if (!genlmsg_end(msg, hdr))
+               goto out;
+
+       return genlmsg_multicast(msg, 0, ieee802154_coord_mcgrp.id,
+                       GFP_ATOMIC);
+out:
+       nlmsg_free(msg);
+       return -ENOBUFS;
+}
+
+int ieee802154_nl_assoc_indic(struct net_device *dev,
+               struct ieee802154_addr *addr, u8 cap)
+{
+       struct sk_buff *msg;
+
+       pr_debug("%s\n", __func__);
+
+       if (addr->addr_type != IEEE802154_ADDR_LONG) {
+               pr_err("%s: received non-long source address!\n", __func__);
+               return -EINVAL;
+       }
+
+       msg = ieee802154_nl_create(0, IEEE802154_ASSOCIATE_INDIC);
+       if (!msg)
+               return -ENOBUFS;
+
+       NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, dev->name);
+       NLA_PUT_U32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex);
+       NLA_PUT(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN,
+                       dev->dev_addr);
+
+       NLA_PUT(msg, IEEE802154_ATTR_SRC_HW_ADDR, IEEE802154_ADDR_LEN,
+                       addr->hwaddr);
+
+       NLA_PUT_U8(msg, IEEE802154_ATTR_CAPABILITY, cap);
+
+       return ieee802154_nl_finish(msg);
+
+nla_put_failure:
+       nlmsg_free(msg);
+       return -ENOBUFS;
+}
+EXPORT_SYMBOL(ieee802154_nl_assoc_indic);
+
+int ieee802154_nl_assoc_confirm(struct net_device *dev, u16 short_addr,
+               u8 status)
+{
+       struct sk_buff *msg;
+
+       pr_debug("%s\n", __func__);
+
+       msg = ieee802154_nl_create(0, IEEE802154_ASSOCIATE_CONF);
+       if (!msg)
+               return -ENOBUFS;
+
+       NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, dev->name);
+       NLA_PUT_U32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex);
+       NLA_PUT(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN,
+                       dev->dev_addr);
+
+       NLA_PUT_U16(msg, IEEE802154_ATTR_SHORT_ADDR, short_addr);
+       NLA_PUT_U8(msg, IEEE802154_ATTR_STATUS, status);
+
+       return ieee802154_nl_finish(msg);
+
+nla_put_failure:
+       nlmsg_free(msg);
+       return -ENOBUFS;
+}
+EXPORT_SYMBOL(ieee802154_nl_assoc_confirm);
+
+int ieee802154_nl_disassoc_indic(struct net_device *dev,
+               struct ieee802154_addr *addr, u8 reason)
+{
+       struct sk_buff *msg;
+
+       pr_debug("%s\n", __func__);
+
+       msg = ieee802154_nl_create(0, IEEE802154_DISASSOCIATE_INDIC);
+       if (!msg)
+               return -ENOBUFS;
+
+       NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, dev->name);
+       NLA_PUT_U32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex);
+       NLA_PUT(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN,
+                       dev->dev_addr);
+
+       if (addr->addr_type == IEEE802154_ADDR_LONG)
+               NLA_PUT(msg, IEEE802154_ATTR_SRC_HW_ADDR, IEEE802154_ADDR_LEN,
+                               addr->hwaddr);
+       else
+               NLA_PUT_U16(msg, IEEE802154_ATTR_SRC_SHORT_ADDR,
+                               addr->short_addr);
+
+       NLA_PUT_U8(msg, IEEE802154_ATTR_REASON, reason);
+
+       return ieee802154_nl_finish(msg);
+
+nla_put_failure:
+       nlmsg_free(msg);
+       return -ENOBUFS;
+}
+EXPORT_SYMBOL(ieee802154_nl_disassoc_indic);
+
+int ieee802154_nl_disassoc_confirm(struct net_device *dev, u8 status)
+{
+       struct sk_buff *msg;
+
+       pr_debug("%s\n", __func__);
+
+       msg = ieee802154_nl_create(0, IEEE802154_DISASSOCIATE_CONF);
+       if (!msg)
+               return -ENOBUFS;
+
+       NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, dev->name);
+       NLA_PUT_U32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex);
+       NLA_PUT(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN,
+                       dev->dev_addr);
+
+       NLA_PUT_U8(msg, IEEE802154_ATTR_STATUS, status);
+
+       return ieee802154_nl_finish(msg);
+
+nla_put_failure:
+       nlmsg_free(msg);
+       return -ENOBUFS;
+}
+EXPORT_SYMBOL(ieee802154_nl_disassoc_confirm);
+
+int ieee802154_nl_beacon_indic(struct net_device *dev,
+               u16 panid, u16 coord_addr)
+{
+       struct sk_buff *msg;
+
+       pr_debug("%s\n", __func__);
+
+       msg = ieee802154_nl_create(0, IEEE802154_BEACON_NOTIFY_INDIC);
+       if (!msg)
+               return -ENOBUFS;
+
+       NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, dev->name);
+       NLA_PUT_U32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex);
+       NLA_PUT(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN,
+                       dev->dev_addr);
+       NLA_PUT_U16(msg, IEEE802154_ATTR_COORD_SHORT_ADDR, coord_addr);
+       NLA_PUT_U16(msg, IEEE802154_ATTR_COORD_PAN_ID, panid);
+
+       return ieee802154_nl_finish(msg);
+
+nla_put_failure:
+       nlmsg_free(msg);
+       return -ENOBUFS;
+}
+EXPORT_SYMBOL(ieee802154_nl_beacon_indic);
+
+int ieee802154_nl_scan_confirm(struct net_device *dev,
+               u8 status, u8 scan_type, u32 unscanned,
+               u8 *edl/* , struct list_head *pan_desc_list */)
+{
+       struct sk_buff *msg;
+
+       pr_debug("%s\n", __func__);
+
+       msg = ieee802154_nl_create(0, IEEE802154_SCAN_CONF);
+       if (!msg)
+               return -ENOBUFS;
+
+       NLA_PUT_STRING(msg, IEEE802154_ATTR_DEV_NAME, dev->name);
+       NLA_PUT_U32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex);
+       NLA_PUT(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN,
+                       dev->dev_addr);
+
+       NLA_PUT_U8(msg, IEEE802154_ATTR_STATUS, status);
+       NLA_PUT_U8(msg, IEEE802154_ATTR_SCAN_TYPE, scan_type);
+       NLA_PUT_U32(msg, IEEE802154_ATTR_CHANNELS, unscanned);
+
+       if (edl)
+               NLA_PUT(msg, IEEE802154_ATTR_ED_LIST, 27, edl);
+
+       return ieee802154_nl_finish(msg);
+
+nla_put_failure:
+       nlmsg_free(msg);
+       return -ENOBUFS;
+}
+EXPORT_SYMBOL(ieee802154_nl_scan_confirm);
+
+/* Requests from userspace */
+static struct net_device *ieee802154_nl_get_dev(struct genl_info *info)
+{
+       struct net_device *dev;
+
+       if (info->attrs[IEEE802154_ATTR_DEV_NAME]) {
+               char name[IFNAMSIZ + 1];
+               nla_strlcpy(name, info->attrs[IEEE802154_ATTR_DEV_NAME],
+                               sizeof(name));
+               dev = dev_get_by_name(&init_net, name);
+       } else if (info->attrs[IEEE802154_ATTR_DEV_INDEX])
+               dev = dev_get_by_index(&init_net,
+                               nla_get_u32(info->attrs[IEEE802154_ATTR_DEV_INDEX]));
+       else
+               return NULL;
+
+       if (dev->type != ARPHRD_IEEE802154) {
+               dev_put(dev);
+               return NULL;
+       }
+
+       return dev;
+}
+
+static int ieee802154_associate_req(struct sk_buff *skb,
+               struct genl_info *info)
+{
+       struct net_device *dev;
+       struct ieee802154_addr addr;
+       int ret = -EINVAL;
+
+       if (!info->attrs[IEEE802154_ATTR_CHANNEL] ||
+           !info->attrs[IEEE802154_ATTR_COORD_PAN_ID] ||
+           (!info->attrs[IEEE802154_ATTR_COORD_HW_ADDR] &&
+               !info->attrs[IEEE802154_ATTR_COORD_SHORT_ADDR]) ||
+           !info->attrs[IEEE802154_ATTR_CAPABILITY])
+               return -EINVAL;
+
+       dev = ieee802154_nl_get_dev(info);
+       if (!dev)
+               return -ENODEV;
+
+       if (info->attrs[IEEE802154_ATTR_COORD_HW_ADDR]) {
+               addr.addr_type = IEEE802154_ADDR_LONG;
+               nla_memcpy(addr.hwaddr,
+                               info->attrs[IEEE802154_ATTR_COORD_HW_ADDR],
+                               IEEE802154_ADDR_LEN);
+       } else {
+               addr.addr_type = IEEE802154_ADDR_SHORT;
+               addr.short_addr = nla_get_u16(
+                               info->attrs[IEEE802154_ATTR_COORD_SHORT_ADDR]);
+       }
+       addr.pan_id = nla_get_u16(info->attrs[IEEE802154_ATTR_COORD_PAN_ID]);
+
+       ret = ieee802154_mlme_ops(dev)->assoc_req(dev, &addr,
+                       nla_get_u8(info->attrs[IEEE802154_ATTR_CHANNEL]),
+                       nla_get_u8(info->attrs[IEEE802154_ATTR_CAPABILITY]));
+
+       dev_put(dev);
+       return ret;
+}
+
+static int ieee802154_associate_resp(struct sk_buff *skb,
+               struct genl_info *info)
+{
+       struct net_device *dev;
+       struct ieee802154_addr addr;
+       int ret = -EINVAL;
+
+       if (!info->attrs[IEEE802154_ATTR_STATUS] ||
+           !info->attrs[IEEE802154_ATTR_DEST_HW_ADDR] ||
+           !info->attrs[IEEE802154_ATTR_DEST_SHORT_ADDR])
+               return -EINVAL;
+
+       dev = ieee802154_nl_get_dev(info);
+       if (!dev)
+               return -ENODEV;
+
+       addr.addr_type = IEEE802154_ADDR_LONG;
+       nla_memcpy(addr.hwaddr, info->attrs[IEEE802154_ATTR_DEST_HW_ADDR],
+                       IEEE802154_ADDR_LEN);
+       addr.pan_id = ieee802154_mlme_ops(dev)->get_pan_id(dev);
+
+
+       ret = ieee802154_mlme_ops(dev)->assoc_resp(dev, &addr,
+               nla_get_u16(info->attrs[IEEE802154_ATTR_DEST_SHORT_ADDR]),
+               nla_get_u8(info->attrs[IEEE802154_ATTR_STATUS]));
+
+       dev_put(dev);
+       return ret;
+}
+
+static int ieee802154_disassociate_req(struct sk_buff *skb,
+               struct genl_info *info)
+{
+       struct net_device *dev;
+       struct ieee802154_addr addr;
+       int ret = -EINVAL;
+
+       if ((!info->attrs[IEEE802154_ATTR_DEST_HW_ADDR] &&
+               !info->attrs[IEEE802154_ATTR_DEST_SHORT_ADDR]) ||
+           !info->attrs[IEEE802154_ATTR_REASON])
+               return -EINVAL;
+
+       dev = ieee802154_nl_get_dev(info);
+       if (!dev)
+               return -ENODEV;
+
+       if (info->attrs[IEEE802154_ATTR_DEST_HW_ADDR]) {
+               addr.addr_type = IEEE802154_ADDR_LONG;
+               nla_memcpy(addr.hwaddr,
+                               info->attrs[IEEE802154_ATTR_DEST_HW_ADDR],
+                               IEEE802154_ADDR_LEN);
+       } else {
+               addr.addr_type = IEEE802154_ADDR_SHORT;
+               addr.short_addr = nla_get_u16(
+                               info->attrs[IEEE802154_ATTR_DEST_SHORT_ADDR]);
+       }
+       addr.pan_id = ieee802154_mlme_ops(dev)->get_pan_id(dev);
+
+       ret = ieee802154_mlme_ops(dev)->disassoc_req(dev, &addr,
+                       nla_get_u8(info->attrs[IEEE802154_ATTR_REASON]));
+
+       dev_put(dev);
+       return ret;
+}
+
+/*
+ * PANid, channel, beacon_order = 15, superframe_order = 15,
+ * PAN_coordinator, battery_life_extension = 0,
+ * coord_realignment = 0, security_enable = 0
+*/
+static int ieee802154_start_req(struct sk_buff *skb, struct genl_info *info)
+{
+       struct net_device *dev;
+       struct ieee802154_addr addr;
+
+       u8 channel, bcn_ord, sf_ord;
+       int pan_coord, blx, coord_realign;
+       int ret;
+
+       if (!info->attrs[IEEE802154_ATTR_COORD_PAN_ID] ||
+           !info->attrs[IEEE802154_ATTR_COORD_SHORT_ADDR] ||
+           !info->attrs[IEEE802154_ATTR_CHANNEL] ||
+           !info->attrs[IEEE802154_ATTR_BCN_ORD] ||
+           !info->attrs[IEEE802154_ATTR_SF_ORD] ||
+           !info->attrs[IEEE802154_ATTR_PAN_COORD] ||
+           !info->attrs[IEEE802154_ATTR_BAT_EXT] ||
+           !info->attrs[IEEE802154_ATTR_COORD_REALIGN]
+        )
+               return -EINVAL;
+
+       dev = ieee802154_nl_get_dev(info);
+       if (!dev)
+               return -ENODEV;
+
+       addr.addr_type = IEEE802154_ADDR_SHORT;
+       addr.short_addr = nla_get_u16(
+                       info->attrs[IEEE802154_ATTR_COORD_SHORT_ADDR]);
+       addr.pan_id = nla_get_u16(info->attrs[IEEE802154_ATTR_COORD_PAN_ID]);
+
+       channel = nla_get_u8(info->attrs[IEEE802154_ATTR_CHANNEL]);
+       bcn_ord = nla_get_u8(info->attrs[IEEE802154_ATTR_BCN_ORD]);
+       sf_ord = nla_get_u8(info->attrs[IEEE802154_ATTR_SF_ORD]);
+       pan_coord = nla_get_u8(info->attrs[IEEE802154_ATTR_PAN_COORD]);
+       blx = nla_get_u8(info->attrs[IEEE802154_ATTR_BAT_EXT]);
+       coord_realign = nla_get_u8(info->attrs[IEEE802154_ATTR_COORD_REALIGN]);
+
+       ret = ieee802154_mlme_ops(dev)->start_req(dev, &addr, channel,
+               bcn_ord, sf_ord, pan_coord, blx, coord_realign);
+
+       dev_put(dev);
+       return ret;
+}
+
+static int ieee802154_scan_req(struct sk_buff *skb, struct genl_info *info)
+{
+       struct net_device *dev;
+       int ret;
+       u8 type;
+       u32 channels;
+       u8 duration;
+
+       if (!info->attrs[IEEE802154_ATTR_SCAN_TYPE] ||
+           !info->attrs[IEEE802154_ATTR_CHANNELS] ||
+           !info->attrs[IEEE802154_ATTR_DURATION])
+               return -EINVAL;
+
+       dev = ieee802154_nl_get_dev(info);
+       if (!dev)
+               return -ENODEV;
+
+       type = nla_get_u8(info->attrs[IEEE802154_ATTR_SCAN_TYPE]);
+       channels = nla_get_u32(info->attrs[IEEE802154_ATTR_CHANNELS]);
+       duration = nla_get_u8(info->attrs[IEEE802154_ATTR_DURATION]);
+
+       ret = ieee802154_mlme_ops(dev)->scan_req(dev, type, channels,
+                       duration);
+
+       dev_put(dev);
+       return ret;
+}
+
+#define IEEE802154_OP(_cmd, _func)                     \
+       {                                               \
+               .cmd    = _cmd,                         \
+               .policy = ieee802154_policy,            \
+               .doit   = _func,                        \
+               .dumpit = NULL,                         \
+               .flags  = GENL_ADMIN_PERM,              \
+       }
+
+static struct genl_ops ieee802154_coordinator_ops[] = {
+       IEEE802154_OP(IEEE802154_ASSOCIATE_REQ, ieee802154_associate_req),
+       IEEE802154_OP(IEEE802154_ASSOCIATE_RESP, ieee802154_associate_resp),
+       IEEE802154_OP(IEEE802154_DISASSOCIATE_REQ, ieee802154_disassociate_req),
+       IEEE802154_OP(IEEE802154_SCAN_REQ, ieee802154_scan_req),
+       IEEE802154_OP(IEEE802154_START_REQ, ieee802154_start_req),
+};
+
+static int __init ieee802154_nl_init(void)
+{
+       int rc;
+       int i;
+
+       rc = genl_register_family(&ieee802154_coordinator_family);
+       if (rc)
+               goto fail;
+
+       rc = genl_register_mc_group(&ieee802154_coordinator_family,
+                       &ieee802154_coord_mcgrp);
+       if (rc)
+               goto fail;
+
+       rc = genl_register_mc_group(&ieee802154_coordinator_family,
+                       &ieee802154_beacon_mcgrp);
+       if (rc)
+               goto fail;
+
+
+       for (i = 0; i < ARRAY_SIZE(ieee802154_coordinator_ops); i++) {
+               rc = genl_register_ops(&ieee802154_coordinator_family,
+                               &ieee802154_coordinator_ops[i]);
+               if (rc)
+                       goto fail;
+       }
+
+       return 0;
+
+fail:
+       genl_unregister_family(&ieee802154_coordinator_family);
+       return rc;
+}
+module_init(ieee802154_nl_init);
+
+static void __exit ieee802154_nl_exit(void)
+{
+       genl_unregister_family(&ieee802154_coordinator_family);
+}
+module_exit(ieee802154_nl_exit);
+
diff --git a/net/ieee802154/nl_policy.c b/net/ieee802154/nl_policy.c
new file mode 100644 (file)
index 0000000..c7d71d1
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * nl802154.h
+ *
+ * Copyright (C) 2007, 2008 Siemens AG
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <net/netlink.h>
+#include <linux/nl802154.h>
+
+#define NLA_HW_ADDR NLA_U64
+
+struct nla_policy ieee802154_policy[IEEE802154_ATTR_MAX + 1] = {
+       [IEEE802154_ATTR_DEV_NAME] = { .type = NLA_STRING, },
+       [IEEE802154_ATTR_DEV_INDEX] = { .type = NLA_U32, },
+
+       [IEEE802154_ATTR_STATUS] = { .type = NLA_U8, },
+       [IEEE802154_ATTR_SHORT_ADDR] = { .type = NLA_U16, },
+       [IEEE802154_ATTR_HW_ADDR] = { .type = NLA_HW_ADDR, },
+       [IEEE802154_ATTR_PAN_ID] = { .type = NLA_U16, },
+       [IEEE802154_ATTR_CHANNEL] = { .type = NLA_U8, },
+       [IEEE802154_ATTR_COORD_SHORT_ADDR] = { .type = NLA_U16, },
+       [IEEE802154_ATTR_COORD_HW_ADDR] = { .type = NLA_HW_ADDR, },
+       [IEEE802154_ATTR_COORD_PAN_ID] = { .type = NLA_U16, },
+       [IEEE802154_ATTR_SRC_SHORT_ADDR] = { .type = NLA_U16, },
+       [IEEE802154_ATTR_SRC_HW_ADDR] = { .type = NLA_HW_ADDR, },
+       [IEEE802154_ATTR_SRC_PAN_ID] = { .type = NLA_U16, },
+       [IEEE802154_ATTR_DEST_SHORT_ADDR] = { .type = NLA_U16, },
+       [IEEE802154_ATTR_DEST_HW_ADDR] = { .type = NLA_HW_ADDR, },
+       [IEEE802154_ATTR_DEST_PAN_ID] = { .type = NLA_U16, },
+
+       [IEEE802154_ATTR_CAPABILITY] = { .type = NLA_U8, },
+       [IEEE802154_ATTR_REASON] = { .type = NLA_U8, },
+       [IEEE802154_ATTR_SCAN_TYPE] = { .type = NLA_U8, },
+       [IEEE802154_ATTR_CHANNELS] = { .type = NLA_U32, },
+       [IEEE802154_ATTR_DURATION] = { .type = NLA_U8, },
+       [IEEE802154_ATTR_ED_LIST] = { .len = 27 },
+};
diff --git a/net/ieee802154/raw.c b/net/ieee802154/raw.c
new file mode 100644 (file)
index 0000000..fca44d5
--- /dev/null
@@ -0,0 +1,254 @@
+/*
+ * Raw IEEE 802.15.4 sockets
+ *
+ * Copyright 2007, 2008 Siemens AG
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Written by:
+ * Sergey Lapin <slapin@ossfans.org>
+ * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
+ */
+
+#include <linux/net.h>
+#include <linux/module.h>
+#include <linux/if_arp.h>
+#include <linux/list.h>
+#include <net/sock.h>
+#include <net/ieee802154/af_ieee802154.h>
+
+#include "af802154.h"
+
+static HLIST_HEAD(raw_head);
+static DEFINE_RWLOCK(raw_lock);
+
+static void raw_hash(struct sock *sk)
+{
+       write_lock_bh(&raw_lock);
+       sk_add_node(sk, &raw_head);
+       sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
+       write_unlock_bh(&raw_lock);
+}
+
+static void raw_unhash(struct sock *sk)
+{
+       write_lock_bh(&raw_lock);
+       if (sk_del_node_init(sk))
+               sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1);
+       write_unlock_bh(&raw_lock);
+}
+
+static void raw_close(struct sock *sk, long timeout)
+{
+       sk_common_release(sk);
+}
+
+static int raw_bind(struct sock *sk, struct sockaddr *uaddr, int len)
+{
+       struct sockaddr_ieee802154 *addr = (struct sockaddr_ieee802154 *)uaddr;
+       int err = 0;
+       struct net_device *dev = NULL;
+
+       if (len < sizeof(*addr))
+               return -EINVAL;
+
+       if (addr->family != AF_IEEE802154)
+               return -EINVAL;
+
+       lock_sock(sk);
+
+       dev = ieee802154_get_dev(sock_net(sk), &addr->addr);
+       if (!dev) {
+               err = -ENODEV;
+               goto out;
+       }
+
+       if (dev->type != ARPHRD_IEEE802154_PHY &&
+           dev->type != ARPHRD_IEEE802154) {
+               err = -ENODEV;
+               goto out_put;
+       }
+
+       sk->sk_bound_dev_if = dev->ifindex;
+       sk_dst_reset(sk);
+
+out_put:
+       dev_put(dev);
+out:
+       release_sock(sk);
+
+       return err;
+}
+
+static int raw_connect(struct sock *sk, struct sockaddr *uaddr,
+                       int addr_len)
+{
+       return -ENOTSUPP;
+}
+
+static int raw_disconnect(struct sock *sk, int flags)
+{
+       return 0;
+}
+
+static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
+                      size_t size)
+{
+       struct net_device *dev;
+       unsigned mtu;
+       struct sk_buff *skb;
+       int err;
+
+       if (msg->msg_flags & MSG_OOB) {
+               pr_debug("msg->msg_flags = 0x%x\n", msg->msg_flags);
+               return -EOPNOTSUPP;
+       }
+
+       lock_sock(sk);
+       if (!sk->sk_bound_dev_if)
+               dev = dev_getfirstbyhwtype(sock_net(sk), ARPHRD_IEEE802154);
+       else
+               dev = dev_get_by_index(sock_net(sk), sk->sk_bound_dev_if);
+       release_sock(sk);
+
+       if (!dev) {
+               pr_debug("no dev\n");
+               err = -ENXIO;
+               goto out;
+       }
+
+       mtu = dev->mtu;
+       pr_debug("name = %s, mtu = %u\n", dev->name, mtu);
+
+       if (size > mtu) {
+               pr_debug("size = %Zu, mtu = %u\n", size, mtu);
+               err = -EINVAL;
+               goto out_dev;
+       }
+
+       skb = sock_alloc_send_skb(sk, LL_ALLOCATED_SPACE(dev) + size,
+                       msg->msg_flags & MSG_DONTWAIT, &err);
+       if (!skb)
+               goto out_dev;
+
+       skb_reserve(skb, LL_RESERVED_SPACE(dev));
+
+       skb_reset_mac_header(skb);
+       skb_reset_network_header(skb);
+
+       err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size);
+       if (err < 0)
+               goto out_skb;
+
+       skb->dev = dev;
+       skb->sk  = sk;
+       skb->protocol = htons(ETH_P_IEEE802154);
+
+       dev_put(dev);
+
+       err = dev_queue_xmit(skb);
+       if (err > 0)
+               err = net_xmit_errno(err);
+
+       return err ?: size;
+
+out_skb:
+       kfree_skb(skb);
+out_dev:
+       dev_put(dev);
+out:
+       return err;
+}
+
+static int raw_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
+                      size_t len, int noblock, int flags, int *addr_len)
+{
+       size_t copied = 0;
+       int err = -EOPNOTSUPP;
+       struct sk_buff *skb;
+
+       skb = skb_recv_datagram(sk, flags, noblock, &err);
+       if (!skb)
+               goto out;
+
+       copied = skb->len;
+       if (len < copied) {
+               msg->msg_flags |= MSG_TRUNC;
+               copied = len;
+       }
+
+       err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
+       if (err)
+               goto done;
+
+       sock_recv_timestamp(msg, sk, skb);
+
+       if (flags & MSG_TRUNC)
+               copied = skb->len;
+done:
+       skb_free_datagram(sk, skb);
+out:
+       if (err)
+               return err;
+       return copied;
+}
+
+static int raw_rcv_skb(struct sock *sk, struct sk_buff *skb)
+{
+       if (sock_queue_rcv_skb(sk, skb) < 0) {
+               atomic_inc(&sk->sk_drops);
+               kfree_skb(skb);
+               return NET_RX_DROP;
+       }
+
+       return NET_RX_SUCCESS;
+}
+
+
+void ieee802154_raw_deliver(struct net_device *dev, struct sk_buff *skb)
+{
+       struct sock *sk;
+       struct hlist_node *node;
+
+       read_lock(&raw_lock);
+       sk_for_each(sk, node, &raw_head) {
+               bh_lock_sock(sk);
+               if (!sk->sk_bound_dev_if ||
+                   sk->sk_bound_dev_if == dev->ifindex) {
+
+                       struct sk_buff *clone;
+
+                       clone = skb_clone(skb, GFP_ATOMIC);
+                       if (clone)
+                               raw_rcv_skb(sk, clone);
+               }
+               bh_unlock_sock(sk);
+       }
+       read_unlock(&raw_lock);
+}
+
+struct proto ieee802154_raw_prot = {
+       .name           = "IEEE-802.15.4-RAW",
+       .owner          = THIS_MODULE,
+       .obj_size       = sizeof(struct sock),
+       .close          = raw_close,
+       .bind           = raw_bind,
+       .sendmsg        = raw_sendmsg,
+       .recvmsg        = raw_recvmsg,
+       .hash           = raw_hash,
+       .unhash         = raw_unhash,
+       .connect        = raw_connect,
+       .disconnect     = raw_disconnect,
+};
+
index 5b919f7b45db4db2e263ed7a43f82e2ed9a382af..70491d9035eb40e3496d98e805690aff1329eed1 100644 (file)
@@ -273,29 +273,20 @@ config IP_PIMSM_V2
          you want to play with it.
 
 config ARPD
-       bool "IP: ARP daemon support (EXPERIMENTAL)"
-       depends on EXPERIMENTAL
+       bool "IP: ARP daemon support"
        ---help---
-         Normally, the kernel maintains an internal cache which maps IP
-         addresses to hardware addresses on the local network, so that
-         Ethernet/Token Ring/ etc. frames are sent to the proper address on
-         the physical networking layer. For small networks having a few
-         hundred directly connected hosts or less, keeping this address
-         resolution (ARP) cache inside the kernel works well. However,
-         maintaining an internal ARP cache does not work well for very large
-         switched networks, and will use a lot of kernel memory if TCP/IP
-         connections are made to many machines on the network.
-
-         If you say Y here, the kernel's internal ARP cache will never grow
-         to more than 256 entries (the oldest entries are expired in a LIFO
-         manner) and communication will be attempted with the user space ARP
-         daemon arpd. Arpd then answers the address resolution request either
-         from its own cache or by asking the net.
-
-         This code is experimental and also obsolete. If you want to use it,
-         you need to find a version of the daemon arpd on the net somewhere,
-         and you should also say Y to "Kernel/User network link driver",
-         below. If unsure, say N.
+         The kernel maintains an internal cache which maps IP addresses to
+         hardware addresses on the local network, so that Ethernet/Token Ring/
+         etc. frames are sent to the proper address on the physical networking
+         layer. Normally, kernel uses the ARP protocol to resolve these
+         mappings.
+
+         Saying Y here adds support to have an user space daemon to do this
+         resolution instead. This is useful for implementing an alternate
+         address resolution protocol (e.g. NHRP on mGRE tunnels) and also for
+         testing purposes.
+
+         If unsure, say N.
 
 config SYN_COOKIES
        bool "IP: TCP syncookie support (disabled per default)"
index 7f03373b8c07b8efd7d3bba01221297dfad5ebaa..566ea6c4321dc7023aae885693d34b70ae2fc324 100644 (file)
 #include <linux/mroute.h>
 #endif
 
-extern void ip_mc_drop_socket(struct sock *sk);
 
 /* The inetsw table contains everything that inet_create needs to
  * build a new socket.
@@ -375,6 +374,7 @@ lookup_protocol:
        inet->uc_ttl    = -1;
        inet->mc_loop   = 1;
        inet->mc_ttl    = 1;
+       inet->mc_all    = 1;
        inet->mc_index  = 0;
        inet->mc_list   = NULL;
 
@@ -1003,8 +1003,6 @@ void inet_register_protosw(struct inet_protosw *p)
 out:
        spin_unlock_bh(&inetsw_lock);
 
-       synchronize_net();
-
        return;
 
 out_permanent:
@@ -1248,13 +1246,20 @@ static struct sk_buff **inet_gro_receive(struct sk_buff **head,
        struct sk_buff **pp = NULL;
        struct sk_buff *p;
        struct iphdr *iph;
+       unsigned int hlen;
+       unsigned int off;
+       unsigned int id;
        int flush = 1;
        int proto;
-       int id;
 
-       iph = skb_gro_header(skb, sizeof(*iph));
-       if (unlikely(!iph))
-               goto out;
+       off = skb_gro_offset(skb);
+       hlen = off + sizeof(*iph);
+       iph = skb_gro_header_fast(skb, off);
+       if (skb_gro_header_hard(skb, hlen)) {
+               iph = skb_gro_header_slow(skb, hlen, off);
+               if (unlikely(!iph))
+                       goto out;
+       }
 
        proto = iph->protocol & (MAX_INET_PROTOS - 1);
 
@@ -1269,9 +1274,9 @@ static struct sk_buff **inet_gro_receive(struct sk_buff **head,
        if (unlikely(ip_fast_csum((u8 *)iph, iph->ihl)))
                goto out_unlock;
 
-       flush = ntohs(iph->tot_len) != skb_gro_len(skb) ||
-               iph->frag_off != htons(IP_DF);
-       id = ntohs(iph->id);
+       id = ntohl(*(u32 *)&iph->id);
+       flush = (u16)((ntohl(*(u32 *)iph) ^ skb_gro_len(skb)) | (id ^ IP_DF));
+       id >>= 16;
 
        for (p = *head; p; p = p->next) {
                struct iphdr *iph2;
index f11931c1838176de514d5e70666ebeef180e7183..8a3881e28aca42d5066970276085bfdbe1535499 100644 (file)
@@ -468,13 +468,13 @@ int arp_find(unsigned char *haddr, struct sk_buff *skb)
        __be32 paddr;
        struct neighbour *n;
 
-       if (!skb->dst) {
+       if (!skb_dst(skb)) {
                printk(KERN_DEBUG "arp_find is called with dst==NULL\n");
                kfree_skb(skb);
                return 1;
        }
 
-       paddr = skb->rtable->rt_gateway;
+       paddr = skb_rtable(skb)->rt_gateway;
 
        if (arp_set_predefined(inet_addr_type(dev_net(dev), paddr), haddr, paddr, dev))
                return 0;
@@ -817,7 +817,7 @@ static int arp_process(struct sk_buff *skb)
        if (arp->ar_op == htons(ARPOP_REQUEST) &&
            ip_route_input(skb, tip, sip, 0, dev) == 0) {
 
-               rt = skb->rtable;
+               rt = skb_rtable(skb);
                addr_type = rt->rt_type;
 
                if (addr_type == RTN_LOCAL) {
index 126bb911880fa675861f4b1940655e18fcbe1774..3863c3a4223f45f84167b9a50c708049822f1ce4 100644 (file)
@@ -1347,7 +1347,8 @@ static int devinet_sysctl_forward(ctl_table *ctl, int write,
                struct net *net = ctl->extra2;
 
                if (valp != &IPV4_DEVCONF_DFLT(net, FORWARDING)) {
-                       rtnl_lock();
+                       if (!rtnl_trylock())
+                               return restart_syscall();
                        if (valp == &IPV4_DEVCONF_ALL(net, FORWARDING)) {
                                inet_forward_change(net);
                        } else if (*valp) {
index cafcc49d0993b6a6b39590f6c2246fc806eb463d..e2f950592566ac93267dbd20bc85473d4a759d48 100644 (file)
@@ -40,7 +40,6 @@
 #include <net/route.h>
 #include <net/tcp.h>
 #include <net/sock.h>
-#include <net/icmp.h>
 #include <net/arp.h>
 #include <net/ip_fib.h>
 #include <net/rtnetlink.h>
index ded8c44fb848842a99f9bbe75830936eb596a48e..ecd39454235c0b12f5d99ed86a554220408f403d 100644 (file)
@@ -263,7 +263,6 @@ fn_hash_lookup(struct fib_table *tb, const struct flowi *flp, struct fib_result
 
                        err = fib_semantic_match(&f->fn_alias,
                                                 flp, res,
-                                                f->fn_key, fz->fz_mask,
                                                 fz->fz_order);
                        if (err <= 0)
                                goto out;
index 2c1623d2768bfd2a1e5acd952d8ec610337f1294..637b133973bd88e601aee3b833de0efed5b2a017 100644 (file)
@@ -22,8 +22,7 @@ struct fib_alias {
 /* Exported by fib_semantics.c */
 extern int fib_semantic_match(struct list_head *head,
                              const struct flowi *flp,
-                             struct fib_result *res, __be32 zone, __be32 mask,
-                               int prefixlen);
+                             struct fib_result *res, int prefixlen);
 extern void fib_release_info(struct fib_info *);
 extern struct fib_info *fib_create_info(struct fib_config *cfg);
 extern int fib_nh_match(struct fib_config *cfg, struct fib_info *fi);
index 6080d712082160b649cea3675901072be287f705..92d9d97ec5e388572c0273b3a9754ac0857b97ab 100644 (file)
@@ -134,7 +134,7 @@ static const struct nla_policy fib4_rule_policy[FRA_MAX+1] = {
 };
 
 static int fib4_rule_configure(struct fib_rule *rule, struct sk_buff *skb,
-                              struct nlmsghdr *nlh, struct fib_rule_hdr *frh,
+                              struct fib_rule_hdr *frh,
                               struct nlattr **tb)
 {
        struct net *net = sock_net(skb->sk);
@@ -209,7 +209,7 @@ static int fib4_rule_compare(struct fib_rule *rule, struct fib_rule_hdr *frh,
 }
 
 static int fib4_rule_fill(struct fib_rule *rule, struct sk_buff *skb,
-                         struct nlmsghdr *nlh, struct fib_rule_hdr *frh)
+                         struct fib_rule_hdr *frh)
 {
        struct fib4_rule *rule4 = (struct fib4_rule *) rule;
 
index f831df500907cb9644b601685b150c1a39aa8485..9b096d6ff3f28eadd6a71fd234a172b8a1d15061 100644 (file)
@@ -866,8 +866,7 @@ failure:
 
 /* Note! fib_semantic_match intentionally uses  RCU list functions. */
 int fib_semantic_match(struct list_head *head, const struct flowi *flp,
-                      struct fib_result *res, __be32 zone, __be32 mask,
-                       int prefixlen)
+                      struct fib_result *res, int prefixlen)
 {
        struct fib_alias *fa;
        int nh_sel = 0;
index 33c7c85dfe40c5301e1953d3cddb7a45da305983..d1a39b1277d6beb141d82e19a036a10861990047 100644 (file)
@@ -123,6 +123,7 @@ struct tnode {
        union {
                struct rcu_head rcu;
                struct work_struct work;
+               struct tnode *tnode_free;
        };
        struct node *child[0];
 };
@@ -161,6 +162,8 @@ static void tnode_put_child_reorg(struct tnode *tn, int i, struct node *n,
 static struct node *resize(struct trie *t, struct tnode *tn);
 static struct tnode *inflate(struct trie *t, struct tnode *tn);
 static struct tnode *halve(struct trie *t, struct tnode *tn);
+/* tnodes to free after resize(); protected by RTNL */
+static struct tnode *tnode_free_head;
 
 static struct kmem_cache *fn_alias_kmem __read_mostly;
 static struct kmem_cache *trie_leaf_kmem __read_mostly;
@@ -385,6 +388,29 @@ static inline void tnode_free(struct tnode *tn)
                call_rcu(&tn->rcu, __tnode_free_rcu);
 }
 
+static void tnode_free_safe(struct tnode *tn)
+{
+       BUG_ON(IS_LEAF(tn));
+
+       if (node_parent((struct node *) tn)) {
+               tn->tnode_free = tnode_free_head;
+               tnode_free_head = tn;
+       } else {
+               tnode_free(tn);
+       }
+}
+
+static void tnode_free_flush(void)
+{
+       struct tnode *tn;
+
+       while ((tn = tnode_free_head)) {
+               tnode_free_head = tn->tnode_free;
+               tn->tnode_free = NULL;
+               tnode_free(tn);
+       }
+}
+
 static struct leaf *leaf_new(void)
 {
        struct leaf *l = kmem_cache_alloc(trie_leaf_kmem, GFP_KERNEL);
@@ -495,7 +521,7 @@ static struct node *resize(struct trie *t, struct tnode *tn)
 
        /* No children */
        if (tn->empty_children == tnode_child_length(tn)) {
-               tnode_free(tn);
+               tnode_free_safe(tn);
                return NULL;
        }
        /* One child */
@@ -509,7 +535,7 @@ static struct node *resize(struct trie *t, struct tnode *tn)
 
                        /* compress one level */
                        node_set_parent(n, NULL);
-                       tnode_free(tn);
+                       tnode_free_safe(tn);
                        return n;
                }
        /*
@@ -670,7 +696,7 @@ static struct node *resize(struct trie *t, struct tnode *tn)
                        /* compress one level */
 
                        node_set_parent(n, NULL);
-                       tnode_free(tn);
+                       tnode_free_safe(tn);
                        return n;
                }
 
@@ -756,7 +782,7 @@ static struct tnode *inflate(struct trie *t, struct tnode *tn)
                        put_child(t, tn, 2*i, inode->child[0]);
                        put_child(t, tn, 2*i+1, inode->child[1]);
 
-                       tnode_free(inode);
+                       tnode_free_safe(inode);
                        continue;
                }
 
@@ -801,9 +827,9 @@ static struct tnode *inflate(struct trie *t, struct tnode *tn)
                put_child(t, tn, 2*i, resize(t, left));
                put_child(t, tn, 2*i+1, resize(t, right));
 
-               tnode_free(inode);
+               tnode_free_safe(inode);
        }
-       tnode_free(oldtnode);
+       tnode_free_safe(oldtnode);
        return tn;
 nomem:
        {
@@ -885,7 +911,7 @@ static struct tnode *halve(struct trie *t, struct tnode *tn)
                put_child(t, newBinNode, 1, right);
                put_child(t, tn, i/2, resize(t, newBinNode));
        }
-       tnode_free(oldtnode);
+       tnode_free_safe(oldtnode);
        return tn;
 nomem:
        {
@@ -989,7 +1015,6 @@ static struct node *trie_rebalance(struct trie *t, struct tnode *tn)
        t_key cindex, key;
        struct tnode *tp;
 
-       preempt_disable();
        key = tn->key;
 
        while (tn != NULL && (tp = node_parent((struct node *)tn)) != NULL) {
@@ -1001,16 +1026,18 @@ static struct node *trie_rebalance(struct trie *t, struct tnode *tn)
                                      (struct node *)tn, wasfull);
 
                tp = node_parent((struct node *) tn);
+               tnode_free_flush();
                if (!tp)
                        break;
                tn = tp;
        }
 
        /* Handle last (top) tnode */
-       if (IS_TNODE(tn))
+       if (IS_TNODE(tn)) {
                tn = (struct tnode *)resize(t, (struct tnode *)tn);
+               tnode_free_flush();
+       }
 
-       preempt_enable();
        return (struct node *)tn;
 }
 
@@ -1351,8 +1378,7 @@ static int check_leaf(struct trie *t, struct leaf *l,
                if (l->key != (key & ntohl(mask)))
                        continue;
 
-               err = fib_semantic_match(&li->falh, flp, res,
-                                        htonl(l->key), mask, plen);
+               err = fib_semantic_match(&li->falh, flp, res, plen);
 
 #ifdef CONFIG_IP_FIB_TRIE_STATS
                if (err <= 0)
index 3f50807237e08580d3427d687f9cf82f4da9ce59..97c410e8438895664a9abdbbf5670b26af01dffa 100644 (file)
@@ -356,7 +356,7 @@ static void icmp_push_reply(struct icmp_bxm *icmp_param,
 static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb)
 {
        struct ipcm_cookie ipc;
-       struct rtable *rt = skb->rtable;
+       struct rtable *rt = skb_rtable(skb);
        struct net *net = dev_net(rt->u.dst.dev);
        struct sock *sk;
        struct inet_sock *inet;
@@ -416,7 +416,7 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info)
        struct iphdr *iph;
        int room;
        struct icmp_bxm icmp_param;
-       struct rtable *rt = skb_in->rtable;
+       struct rtable *rt = skb_rtable(skb_in);
        struct ipcm_cookie ipc;
        __be32 saddr;
        u8  tos;
@@ -591,13 +591,13 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info)
                                goto relookup_failed;
 
                        /* Ugh! */
-                       odst = skb_in->dst;
+                       odst = skb_dst(skb_in);
                        err = ip_route_input(skb_in, fl.fl4_dst, fl.fl4_src,
                                             RT_TOS(tos), rt2->u.dst.dev);
 
                        dst_release(&rt2->u.dst);
-                       rt2 = skb_in->rtable;
-                       skb_in->dst = odst;
+                       rt2 = skb_rtable(skb_in);
+                       skb_dst_set(skb_in, odst);
                }
 
                if (err)
@@ -659,7 +659,7 @@ static void icmp_unreach(struct sk_buff *skb)
        u32 info = 0;
        struct net *net;
 
-       net = dev_net(skb->dst->dev);
+       net = dev_net(skb_dst(skb)->dev);
 
        /*
         *      Incomplete header ?
@@ -822,7 +822,7 @@ static void icmp_echo(struct sk_buff *skb)
 {
        struct net *net;
 
-       net = dev_net(skb->dst->dev);
+       net = dev_net(skb_dst(skb)->dev);
        if (!net->ipv4.sysctl_icmp_echo_ignore_all) {
                struct icmp_bxm icmp_param;
 
@@ -873,7 +873,7 @@ static void icmp_timestamp(struct sk_buff *skb)
 out:
        return;
 out_err:
-       ICMP_INC_STATS_BH(dev_net(skb->dst->dev), ICMP_MIB_INERRORS);
+       ICMP_INC_STATS_BH(dev_net(skb_dst(skb)->dev), ICMP_MIB_INERRORS);
        goto out;
 }
 
@@ -926,7 +926,7 @@ static void icmp_address(struct sk_buff *skb)
 
 static void icmp_address_reply(struct sk_buff *skb)
 {
-       struct rtable *rt = skb->rtable;
+       struct rtable *rt = skb_rtable(skb);
        struct net_device *dev = skb->dev;
        struct in_device *in_dev;
        struct in_ifaddr *ifa;
@@ -970,7 +970,7 @@ static void icmp_discard(struct sk_buff *skb)
 int icmp_rcv(struct sk_buff *skb)
 {
        struct icmphdr *icmph;
-       struct rtable *rt = skb->rtable;
+       struct rtable *rt = skb_rtable(skb);
        struct net *net = dev_net(rt->u.dst.dev);
 
        if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) {
index 9eb6219af615af2327daef1ec461e3b1fdb16500..01b4284ed694fc86540da28253e159625acc0f5e 100644 (file)
@@ -311,7 +311,7 @@ static struct sk_buff *igmpv3_newpack(struct net_device *dev, int size)
                return NULL;
        }
 
-       skb->dst = &rt->u.dst;
+       skb_dst_set(skb, &rt->u.dst);
        skb->dev = dev;
 
        skb_reserve(skb, LL_RESERVED_SPACE(dev));
@@ -659,7 +659,7 @@ static int igmp_send_report(struct in_device *in_dev, struct ip_mc_list *pmc,
                return -1;
        }
 
-       skb->dst = &rt->u.dst;
+       skb_dst_set(skb, &rt->u.dst);
 
        skb_reserve(skb, LL_RESERVED_SPACE(dev));
 
@@ -948,7 +948,7 @@ int igmp_rcv(struct sk_buff *skb)
        case IGMPV2_HOST_MEMBERSHIP_REPORT:
        case IGMPV3_HOST_MEMBERSHIP_REPORT:
                /* Is it our report looped back? */
-               if (skb->rtable->fl.iif == 0)
+               if (skb_rtable(skb)->fl.iif == 0)
                        break;
                /* don't rely on MC router hearing unicast reports */
                if (skb->pkt_type == PACKET_MULTICAST ||
@@ -2196,7 +2196,7 @@ int ip_mc_sf_allow(struct sock *sk, __be32 loc_addr, __be32 rmt_addr, int dif)
                        break;
        }
        if (!pmc)
-               return 1;
+               return inet->mc_all;
        psl = pmc->sflist;
        if (!psl)
                return pmc->sfmode == MCAST_EXCLUDE;
index 588a7796e3e3e67ea7a4c2e627e0b557f2bd2e59..b0b273503e2ad4fb58085430ed506d30e1bfd6f7 100644 (file)
@@ -198,8 +198,6 @@ static int inet_twsk_diag_fill(struct inet_timewait_sock *tw,
                tmo = 0;
 
        r->idiag_family       = tw->tw_family;
-       r->idiag_state        = tw->tw_state;
-       r->idiag_timer        = 0;
        r->idiag_retrans      = 0;
        r->id.idiag_if        = tw->tw_bound_dev_if;
        r->id.idiag_cookie[0] = (u32)(unsigned long)tw;
index 8554d0ea1719b7621667026a1641cb7da20ca2d4..68a8d892c711e44764e8856ef265dbb60f1f915b 100644 (file)
@@ -49,19 +49,22 @@ static void __inet_twsk_kill(struct inet_timewait_sock *tw,
        inet_twsk_put(tw);
 }
 
-void inet_twsk_put(struct inet_timewait_sock *tw)
+static noinline void inet_twsk_free(struct inet_timewait_sock *tw)
 {
-       if (atomic_dec_and_test(&tw->tw_refcnt)) {
-               struct module *owner = tw->tw_prot->owner;
-               twsk_destructor((struct sock *)tw);
+       struct module *owner = tw->tw_prot->owner;
+       twsk_destructor((struct sock *)tw);
 #ifdef SOCK_REFCNT_DEBUG
-               printk(KERN_DEBUG "%s timewait_sock %p released\n",
-                      tw->tw_prot->name, tw);
+       pr_debug("%s timewait_sock %p released\n", tw->tw_prot->name, tw);
 #endif
-               release_net(twsk_net(tw));
-               kmem_cache_free(tw->tw_prot->twsk_prot->twsk_slab, tw);
-               module_put(owner);
-       }
+       release_net(twsk_net(tw));
+       kmem_cache_free(tw->tw_prot->twsk_prot->twsk_slab, tw);
+       module_put(owner);
+}
+
+void inet_twsk_put(struct inet_timewait_sock *tw)
+{
+       if (atomic_dec_and_test(&tw->tw_refcnt))
+               inet_twsk_free(tw);
 }
 EXPORT_SYMBOL_GPL(inet_twsk_put);
 
index df3fe50bbf0dc0a76cebf690c4ec8697c7889d1d..a2991bc8e32e5e0b89727086fb1484dfe65ffdc4 100644 (file)
@@ -42,7 +42,7 @@ static int ip_forward_finish(struct sk_buff *skb)
 {
        struct ip_options * opt = &(IPCB(skb)->opt);
 
-       IP_INC_STATS_BH(dev_net(skb->dst->dev), IPSTATS_MIB_OUTFORWDATAGRAMS);
+       IP_INC_STATS_BH(dev_net(skb_dst(skb)->dev), IPSTATS_MIB_OUTFORWDATAGRAMS);
 
        if (unlikely(opt->optlen))
                ip_forward_options(skb);
@@ -81,7 +81,7 @@ int ip_forward(struct sk_buff *skb)
        if (!xfrm4_route_forward(skb))
                goto drop;
 
-       rt = skb->rtable;
+       rt = skb_rtable(skb);
 
        if (opt->is_strictroute && rt->rt_dst != rt->rt_gateway)
                goto sr_failed;
@@ -123,7 +123,7 @@ sr_failed:
 
 too_many_hops:
        /* Tell the sender its packet died... */
-       IP_INC_STATS_BH(dev_net(skb->dst->dev), IPSTATS_MIB_INHDRERRORS);
+       IP_INC_STATS_BH(dev_net(skb_dst(skb)->dev), IPSTATS_MIB_INHDRERRORS);
        icmp_send(skb, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL, 0);
 drop:
        kfree_skb(skb);
index 7985346653bdc9e7c3cf69ae3d477a299d431fd3..575f9bd51ccdf745c62125a45611d845dc015b2b 100644 (file)
@@ -507,7 +507,7 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev,
        /* If the first fragment is fragmented itself, we split
         * it to two chunks: the first with data and paged part
         * and the second, holding only fragments. */
-       if (skb_shinfo(head)->frag_list) {
+       if (skb_has_frags(head)) {
                struct sk_buff *clone;
                int i, plen = 0;
 
@@ -516,7 +516,7 @@ static int ip_frag_reasm(struct ipq *qp, struct sk_buff *prev,
                clone->next = head->next;
                head->next = clone;
                skb_shinfo(clone)->frag_list = skb_shinfo(head)->frag_list;
-               skb_shinfo(head)->frag_list = NULL;
+               skb_frag_list_init(head);
                for (i=0; i<skb_shinfo(head)->nr_frags; i++)
                        plen += skb_shinfo(head)->frags[i].size;
                clone->len = clone->data_len = head->data_len - plen;
@@ -573,7 +573,7 @@ int ip_defrag(struct sk_buff *skb, u32 user)
        struct ipq *qp;
        struct net *net;
 
-       net = skb->dev ? dev_net(skb->dev) : dev_net(skb->dst->dev);
+       net = skb->dev ? dev_net(skb->dev) : dev_net(skb_dst(skb)->dev);
        IP_INC_STATS_BH(net, IPSTATS_MIB_REASMREQDS);
 
        /* Start by cleaning up the memory. */
index e62510d5ea5a60df6b806342e870ace458108962..44e2a3d2359afd99da1324022c221e811d83a0a9 100644 (file)
@@ -602,7 +602,7 @@ static int ipgre_rcv(struct sk_buff *skb)
 #ifdef CONFIG_NET_IPGRE_BROADCAST
                if (ipv4_is_multicast(iph->daddr)) {
                        /* Looped back packet, drop it! */
-                       if (skb->rtable->fl.iif == 0)
+                       if (skb_rtable(skb)->fl.iif == 0)
                                goto drop;
                        stats->multicast++;
                        skb->pkt_type = PACKET_BROADCAST;
@@ -643,8 +643,7 @@ static int ipgre_rcv(struct sk_buff *skb)
                stats->rx_packets++;
                stats->rx_bytes += len;
                skb->dev = tunnel->dev;
-               dst_release(skb->dst);
-               skb->dst = NULL;
+               skb_dst_drop(skb);
                nf_reset(skb);
 
                skb_reset_network_header(skb);
@@ -698,13 +697,13 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
        if ((dst = tiph->daddr) == 0) {
                /* NBMA tunnel */
 
-               if (skb->dst == NULL) {
+               if (skb_dst(skb) == NULL) {
                        stats->tx_fifo_errors++;
                        goto tx_error;
                }
 
                if (skb->protocol == htons(ETH_P_IP)) {
-                       rt = skb->rtable;
+                       rt = skb_rtable(skb);
                        if ((dst = rt->rt_gateway) == 0)
                                goto tx_error_icmp;
                }
@@ -712,7 +711,7 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
                else if (skb->protocol == htons(ETH_P_IPV6)) {
                        struct in6_addr *addr6;
                        int addr_type;
-                       struct neighbour *neigh = skb->dst->neighbour;
+                       struct neighbour *neigh = skb_dst(skb)->neighbour;
 
                        if (neigh == NULL)
                                goto tx_error;
@@ -766,10 +765,10 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
        if (df)
                mtu = dst_mtu(&rt->u.dst) - dev->hard_header_len - tunnel->hlen;
        else
-               mtu = skb->dst ? dst_mtu(skb->dst) : dev->mtu;
+               mtu = skb_dst(skb) ? dst_mtu(skb_dst(skb)) : dev->mtu;
 
-       if (skb->dst)
-               skb->dst->ops->update_pmtu(skb->dst, mtu);
+       if (skb_dst(skb))
+               skb_dst(skb)->ops->update_pmtu(skb_dst(skb), mtu);
 
        if (skb->protocol == htons(ETH_P_IP)) {
                df |= (old_iph->frag_off&htons(IP_DF));
@@ -783,14 +782,14 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
        }
 #ifdef CONFIG_IPV6
        else if (skb->protocol == htons(ETH_P_IPV6)) {
-               struct rt6_info *rt6 = (struct rt6_info *)skb->dst;
+               struct rt6_info *rt6 = (struct rt6_info *)skb_dst(skb);
 
-               if (rt6 && mtu < dst_mtu(skb->dst) && mtu >= IPV6_MIN_MTU) {
+               if (rt6 && mtu < dst_mtu(skb_dst(skb)) && mtu >= IPV6_MIN_MTU) {
                        if ((tunnel->parms.iph.daddr &&
                             !ipv4_is_multicast(tunnel->parms.iph.daddr)) ||
                            rt6->rt6i_dst.plen == 128) {
                                rt6->rt6i_flags |= RTF_MODIFIED;
-                               skb->dst->metrics[RTAX_MTU-1] = mtu;
+                               skb_dst(skb)->metrics[RTAX_MTU-1] = mtu;
                        }
                }
 
@@ -837,8 +836,8 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
        memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
        IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED |
                              IPSKB_REROUTED);
-       dst_release(skb->dst);
-       skb->dst = &rt->u.dst;
+       skb_dst_drop(skb);
+       skb_dst_set(skb, &rt->u.dst);
 
        /*
         *      Push down and install the IPIP header.
@@ -1238,6 +1237,7 @@ static void ipgre_tunnel_setup(struct net_device *dev)
        dev->iflink             = 0;
        dev->addr_len           = 4;
        dev->features           |= NETIF_F_NETNS_LOCAL;
+       dev->priv_flags         &= ~IFF_XMIT_DST_RELEASE;
 }
 
 static int ipgre_tunnel_init(struct net_device *dev)
index 1a58a6fa1dc01d1c9eefd48dbb56c5017cec0689..490ce20faf38b8bbe47aa60d1c7b1b1847fe1059 100644 (file)
@@ -329,7 +329,7 @@ static int ip_rcv_finish(struct sk_buff *skb)
         *      Initialise the virtual path cache for the packet. It describes
         *      how the packet travels inside Linux networking.
         */
-       if (skb->dst == NULL) {
+       if (skb_dst(skb) == NULL) {
                int err = ip_route_input(skb, iph->daddr, iph->saddr, iph->tos,
                                         skb->dev);
                if (unlikely(err)) {
@@ -344,9 +344,9 @@ static int ip_rcv_finish(struct sk_buff *skb)
        }
 
 #ifdef CONFIG_NET_CLS_ROUTE
-       if (unlikely(skb->dst->tclassid)) {
+       if (unlikely(skb_dst(skb)->tclassid)) {
                struct ip_rt_acct *st = per_cpu_ptr(ip_rt_acct, smp_processor_id());
-               u32 idx = skb->dst->tclassid;
+               u32 idx = skb_dst(skb)->tclassid;
                st[idx&0xFF].o_packets++;
                st[idx&0xFF].o_bytes += skb->len;
                st[(idx>>16)&0xFF].i_packets++;
@@ -357,11 +357,13 @@ static int ip_rcv_finish(struct sk_buff *skb)
        if (iph->ihl > 5 && ip_rcv_options(skb))
                goto drop;
 
-       rt = skb->rtable;
-       if (rt->rt_type == RTN_MULTICAST)
-               IP_INC_STATS_BH(dev_net(rt->u.dst.dev), IPSTATS_MIB_INMCASTPKTS);
-       else if (rt->rt_type == RTN_BROADCAST)
-               IP_INC_STATS_BH(dev_net(rt->u.dst.dev), IPSTATS_MIB_INBCASTPKTS);
+       rt = skb_rtable(skb);
+       if (rt->rt_type == RTN_MULTICAST) {
+               IP_UPD_PO_STATS_BH(dev_net(rt->u.dst.dev), IPSTATS_MIB_INMCAST,
+                               skb->len);
+       } else if (rt->rt_type == RTN_BROADCAST)
+               IP_UPD_PO_STATS_BH(dev_net(rt->u.dst.dev), IPSTATS_MIB_INBCAST,
+                               skb->len);
 
        return dst_input(skb);
 
@@ -384,7 +386,8 @@ int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt,
        if (skb->pkt_type == PACKET_OTHERHOST)
                goto drop;
 
-       IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_INRECEIVES);
+
+       IP_UPD_PO_STATS_BH(dev_net(dev), IPSTATS_MIB_IN, skb->len);
 
        if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) {
                IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_INDISCARDS);
index 2c88da6e7862f2b49d4d9ba17197eb9d10205fe8..94bf105ef3c9b7e593df4b8aee0a016d0a9022e7 100644 (file)
@@ -102,7 +102,7 @@ int ip_options_echo(struct ip_options * dopt, struct sk_buff * skb)
        sptr = skb_network_header(skb);
        dptr = dopt->__data;
 
-       daddr = skb->rtable->rt_spec_dst;
+       daddr = skb_rtable(skb)->rt_spec_dst;
 
        if (sopt->rr) {
                optlen  = sptr[sopt->rr+1];
@@ -143,7 +143,7 @@ int ip_options_echo(struct ip_options * dopt, struct sk_buff * skb)
                                                __be32 addr;
 
                                                memcpy(&addr, sptr+soffset-1, 4);
-                                               if (inet_addr_type(dev_net(skb->dst->dev), addr) != RTN_LOCAL) {
+                                               if (inet_addr_type(dev_net(skb_dst(skb)->dev), addr) != RTN_LOCAL) {
                                                        dopt->ts_needtime = 1;
                                                        soffset += 8;
                                                }
@@ -257,7 +257,7 @@ int ip_options_compile(struct net *net,
        struct rtable *rt = NULL;
 
        if (skb != NULL) {
-               rt = skb->rtable;
+               rt = skb_rtable(skb);
                optptr = (unsigned char *)&(ip_hdr(skb)[1]);
        } else
                optptr = opt->__data;
@@ -550,7 +550,7 @@ void ip_forward_options(struct sk_buff *skb)
 {
        struct   ip_options * opt       = &(IPCB(skb)->opt);
        unsigned char * optptr;
-       struct rtable *rt = skb->rtable;
+       struct rtable *rt = skb_rtable(skb);
        unsigned char *raw = skb_network_header(skb);
 
        if (opt->rr_needaddr) {
@@ -598,7 +598,7 @@ int ip_options_rcv_srr(struct sk_buff *skb)
        __be32 nexthop;
        struct iphdr *iph = ip_hdr(skb);
        unsigned char *optptr = skb_network_header(skb) + opt->srr;
-       struct rtable *rt = skb->rtable;
+       struct rtable *rt = skb_rtable(skb);
        struct rtable *rt2;
        int err;
 
@@ -623,13 +623,13 @@ int ip_options_rcv_srr(struct sk_buff *skb)
                }
                memcpy(&nexthop, &optptr[srrptr-1], 4);
 
-               rt = skb->rtable;
-               skb->rtable = NULL;
+               rt = skb_rtable(skb);
+               skb_dst_set(skb, NULL);
                err = ip_route_input(skb, nexthop, iph->saddr, iph->tos, skb->dev);
-               rt2 = skb->rtable;
+               rt2 = skb_rtable(skb);
                if (err || (rt2->rt_type != RTN_UNICAST && rt2->rt_type != RTN_LOCAL)) {
                        ip_rt_put(rt2);
-                       skb->rtable = rt;
+                       skb_dst_set(skb, &rt->u.dst);
                        return -EINVAL;
                }
                ip_rt_put(rt);
index 3e7e910c7c0fd6f229a9ee67a10936f24db36a3f..2470262826694d122b5457d6ef4144b66429d7a2 100644 (file)
@@ -95,7 +95,7 @@ int __ip_local_out(struct sk_buff *skb)
 
        iph->tot_len = htons(skb->len);
        ip_send_check(iph);
-       return nf_hook(PF_INET, NF_INET_LOCAL_OUT, skb, NULL, skb->dst->dev,
+       return nf_hook(PF_INET, NF_INET_LOCAL_OUT, skb, NULL, skb_dst(skb)->dev,
                       dst_output);
 }
 
@@ -118,7 +118,7 @@ static int ip_dev_loopback_xmit(struct sk_buff *newskb)
        __skb_pull(newskb, skb_network_offset(newskb));
        newskb->pkt_type = PACKET_LOOPBACK;
        newskb->ip_summed = CHECKSUM_UNNECESSARY;
-       WARN_ON(!newskb->dst);
+       WARN_ON(!skb_dst(newskb));
        netif_rx(newskb);
        return 0;
 }
@@ -140,7 +140,7 @@ int ip_build_and_send_pkt(struct sk_buff *skb, struct sock *sk,
                          __be32 saddr, __be32 daddr, struct ip_options *opt)
 {
        struct inet_sock *inet = inet_sk(sk);
-       struct rtable *rt = skb->rtable;
+       struct rtable *rt = skb_rtable(skb);
        struct iphdr *iph;
 
        /* Build the IP header. */
@@ -176,15 +176,15 @@ EXPORT_SYMBOL_GPL(ip_build_and_send_pkt);
 
 static inline int ip_finish_output2(struct sk_buff *skb)
 {
-       struct dst_entry *dst = skb->dst;
+       struct dst_entry *dst = skb_dst(skb);
        struct rtable *rt = (struct rtable *)dst;
        struct net_device *dev = dst->dev;
        unsigned int hh_len = LL_RESERVED_SPACE(dev);
 
-       if (rt->rt_type == RTN_MULTICAST)
-               IP_INC_STATS(dev_net(dev), IPSTATS_MIB_OUTMCASTPKTS);
-       else if (rt->rt_type == RTN_BROADCAST)
-               IP_INC_STATS(dev_net(dev), IPSTATS_MIB_OUTBCASTPKTS);
+       if (rt->rt_type == RTN_MULTICAST) {
+               IP_UPD_PO_STATS(dev_net(dev), IPSTATS_MIB_OUTMCAST, skb->len);
+       else if (rt->rt_type == RTN_BROADCAST)
+               IP_UPD_PO_STATS(dev_net(dev), IPSTATS_MIB_OUTBCAST, skb->len);
 
        /* Be paranoid, rather than too clever. */
        if (unlikely(skb_headroom(skb) < hh_len && dev->header_ops)) {
@@ -217,14 +217,14 @@ static inline int ip_skb_dst_mtu(struct sk_buff *skb)
        struct inet_sock *inet = skb->sk ? inet_sk(skb->sk) : NULL;
 
        return (inet && inet->pmtudisc == IP_PMTUDISC_PROBE) ?
-              skb->dst->dev->mtu : dst_mtu(skb->dst);
+              skb_dst(skb)->dev->mtu : dst_mtu(skb_dst(skb));
 }
 
 static int ip_finish_output(struct sk_buff *skb)
 {
 #if defined(CONFIG_NETFILTER) && defined(CONFIG_XFRM)
        /* Policy lookup after SNAT yielded a new policy */
-       if (skb->dst->xfrm != NULL) {
+       if (skb_dst(skb)->xfrm != NULL) {
                IPCB(skb)->flags |= IPSKB_REROUTED;
                return dst_output(skb);
        }
@@ -238,13 +238,13 @@ static int ip_finish_output(struct sk_buff *skb)
 int ip_mc_output(struct sk_buff *skb)
 {
        struct sock *sk = skb->sk;
-       struct rtable *rt = skb->rtable;
+       struct rtable *rt = skb_rtable(skb);
        struct net_device *dev = rt->u.dst.dev;
 
        /*
         *      If the indicated interface is up and running, send the packet.
         */
-       IP_INC_STATS(dev_net(dev), IPSTATS_MIB_OUTREQUESTS);
+       IP_UPD_PO_STATS(dev_net(dev), IPSTATS_MIB_OUT, skb->len);
 
        skb->dev = dev;
        skb->protocol = htons(ETH_P_IP);
@@ -296,9 +296,9 @@ int ip_mc_output(struct sk_buff *skb)
 
 int ip_output(struct sk_buff *skb)
 {
-       struct net_device *dev = skb->dst->dev;
+       struct net_device *dev = skb_dst(skb)->dev;
 
-       IP_INC_STATS(dev_net(dev), IPSTATS_MIB_OUTREQUESTS);
+       IP_UPD_PO_STATS(dev_net(dev), IPSTATS_MIB_OUT, skb->len);
 
        skb->dev = dev;
        skb->protocol = htons(ETH_P_IP);
@@ -319,7 +319,7 @@ int ip_queue_xmit(struct sk_buff *skb, int ipfragok)
        /* Skip all of this if the packet is already routed,
         * f.e. by something like SCTP.
         */
-       rt = skb->rtable;
+       rt = skb_rtable(skb);
        if (rt != NULL)
                goto packet_routed;
 
@@ -355,7 +355,7 @@ int ip_queue_xmit(struct sk_buff *skb, int ipfragok)
                }
                sk_setup_caps(sk, &rt->u.dst);
        }
-       skb->dst = dst_clone(&rt->u.dst);
+       skb_dst_set(skb, dst_clone(&rt->u.dst));
 
 packet_routed:
        if (opt && opt->is_strictroute && rt->rt_dst != rt->rt_gateway)
@@ -401,8 +401,8 @@ static void ip_copy_metadata(struct sk_buff *to, struct sk_buff *from)
        to->pkt_type = from->pkt_type;
        to->priority = from->priority;
        to->protocol = from->protocol;
-       dst_release(to->dst);
-       to->dst = dst_clone(from->dst);
+       skb_dst_drop(to);
+       skb_dst_set(to, dst_clone(skb_dst(from)));
        to->dev = from->dev;
        to->mark = from->mark;
 
@@ -440,7 +440,7 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
        unsigned int mtu, hlen, left, len, ll_rs, pad;
        int offset;
        __be16 not_last_frag;
-       struct rtable *rt = skb->rtable;
+       struct rtable *rt = skb_rtable(skb);
        int err = 0;
 
        dev = rt->u.dst.dev;
@@ -474,7 +474,7 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
         * LATER: this step can be merged to real generation of fragments,
         * we can switch to copy when see the first bad fragment.
         */
-       if (skb_shinfo(skb)->frag_list) {
+       if (skb_has_frags(skb)) {
                struct sk_buff *frag;
                int first_len = skb_pagelen(skb);
                int truesizes = 0;
@@ -485,7 +485,7 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
                    skb_cloned(skb))
                        goto slow_path;
 
-               for (frag = skb_shinfo(skb)->frag_list; frag; frag = frag->next) {
+               skb_walk_frags(skb, frag) {
                        /* Correct geometry. */
                        if (frag->len > mtu ||
                            ((frag->len & 7) && frag->next) ||
@@ -498,7 +498,6 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
 
                        BUG_ON(frag->sk);
                        if (skb->sk) {
-                               sock_hold(skb->sk);
                                frag->sk = skb->sk;
                                frag->destructor = sock_wfree;
                                truesizes += frag->truesize;
@@ -510,7 +509,7 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
                err = 0;
                offset = 0;
                frag = skb_shinfo(skb)->frag_list;
-               skb_shinfo(skb)->frag_list = NULL;
+               skb_frag_list_init(skb);
                skb->data_len = first_len - skb_headlen(skb);
                skb->truesize -= truesizes;
                skb->len = first_len;
@@ -1294,7 +1293,7 @@ int ip_push_pending_frames(struct sock *sk)
         * on dst refcount
         */
        inet->cork.dst = NULL;
-       skb->dst = &rt->u.dst;
+       skb_dst_set(skb, &rt->u.dst);
 
        if (iph->protocol == IPPROTO_ICMP)
                icmp_out_count(net, ((struct icmphdr *)
@@ -1362,7 +1361,7 @@ void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *ar
        } replyopts;
        struct ipcm_cookie ipc;
        __be32 daddr;
-       struct rtable *rt = skb->rtable;
+       struct rtable *rt = skb_rtable(skb);
 
        if (ip_options_echo(&replyopts.opt, skb))
                return;
index 43c05854d752f94c88dbb3dbd4ab43a111a93d0d..fc7993e9061fd855d1cb34b42fa491c49dcd669d 100644 (file)
@@ -57,7 +57,7 @@
 static void ip_cmsg_recv_pktinfo(struct msghdr *msg, struct sk_buff *skb)
 {
        struct in_pktinfo info;
-       struct rtable *rt = skb->rtable;
+       struct rtable *rt = skb_rtable(skb);
 
        info.ipi_addr.s_addr = ip_hdr(skb)->daddr;
        if (rt) {
@@ -157,38 +157,39 @@ void ip_cmsg_recv(struct msghdr *msg, struct sk_buff *skb)
        /* Ordered by supposed usage frequency */
        if (flags & 1)
                ip_cmsg_recv_pktinfo(msg, skb);
-       if ((flags>>=1) == 0)
+       if ((flags >>= 1) == 0)
                return;
 
        if (flags & 1)
                ip_cmsg_recv_ttl(msg, skb);
-       if ((flags>>=1) == 0)
+       if ((flags >>= 1) == 0)
                return;
 
        if (flags & 1)
                ip_cmsg_recv_tos(msg, skb);
-       if ((flags>>=1) == 0)
+       if ((flags >>= 1) == 0)
                return;
 
        if (flags & 1)
                ip_cmsg_recv_opts(msg, skb);
-       if ((flags>>=1) == 0)
+       if ((flags >>= 1) == 0)
                return;
 
        if (flags & 1)
                ip_cmsg_recv_retopts(msg, skb);
-       if ((flags>>=1) == 0)
+       if ((flags >>= 1) == 0)
                return;
 
        if (flags & 1)
                ip_cmsg_recv_security(msg, skb);
 
-       if ((flags>>=1) == 0)
+       if ((flags >>= 1) == 0)
                return;
        if (flags & 1)
                ip_cmsg_recv_dstaddr(msg, skb);
 
 }
+EXPORT_SYMBOL(ip_cmsg_recv);
 
 int ip_cmsg_send(struct net *net, struct msghdr *msg, struct ipcm_cookie *ipc)
 {
@@ -203,7 +204,8 @@ int ip_cmsg_send(struct net *net, struct msghdr *msg, struct ipcm_cookie *ipc)
                switch (cmsg->cmsg_type) {
                case IP_RETOPTS:
                        err = cmsg->cmsg_len - CMSG_ALIGN(sizeof(struct cmsghdr));
-                       err = ip_options_get(net, &ipc->opt, CMSG_DATA(cmsg), err < 40 ? err : 40);
+                       err = ip_options_get(net, &ipc->opt, CMSG_DATA(cmsg),
+                                            err < 40 ? err : 40);
                        if (err)
                                return err;
                        break;
@@ -238,7 +240,8 @@ int ip_cmsg_send(struct net *net, struct msghdr *msg, struct ipcm_cookie *ipc)
 struct ip_ra_chain *ip_ra_chain;
 DEFINE_RWLOCK(ip_ra_lock);
 
-int ip_ra_control(struct sock *sk, unsigned char on, void (*destructor)(struct sock *))
+int ip_ra_control(struct sock *sk, unsigned char on,
+                 void (*destructor)(struct sock *))
 {
        struct ip_ra_chain *ra, *new_ra, **rap;
 
@@ -248,7 +251,7 @@ int ip_ra_control(struct sock *sk, unsigned char on, void (*destructor)(struct s
        new_ra = on ? kmalloc(sizeof(*new_ra), GFP_KERNEL) : NULL;
 
        write_lock_bh(&ip_ra_lock);
-       for (rap = &ip_ra_chain; (ra=*rap) != NULL; rap = &ra->next) {
+       for (rap = &ip_ra_chain; (ra = *rap) != NULL; rap = &ra->next) {
                if (ra->sk == sk) {
                        if (on) {
                                write_unlock_bh(&ip_ra_lock);
@@ -416,7 +419,8 @@ int ip_recv_error(struct sock *sk, struct msghdr *msg, int len)
        /* Reset and regenerate socket error */
        spin_lock_bh(&sk->sk_error_queue.lock);
        sk->sk_err = 0;
-       if ((skb2 = skb_peek(&sk->sk_error_queue)) != NULL) {
+       skb2 = skb_peek(&sk->sk_error_queue);
+       if (skb2 != NULL) {
                sk->sk_err = SKB_EXT_ERR(skb2)->ee.ee_errno;
                spin_unlock_bh(&sk->sk_error_queue.lock);
                sk->sk_error_report(sk);
@@ -431,8 +435,8 @@ out:
 
 
 /*
- *     Socket option code for IP. This is the end of the line after any TCP,UDP etc options on
- *     an IP socket.
+ *     Socket option code for IP. This is the end of the line after any
+ *     TCP,UDP etc options on an IP socket.
  */
 
 static int do_ip_setsockopt(struct sock *sk, int level,
@@ -449,6 +453,7 @@ static int do_ip_setsockopt(struct sock *sk, int level,
                             (1<<IP_ROUTER_ALERT) | (1<<IP_FREEBIND) |
                             (1<<IP_PASSSEC) | (1<<IP_TRANSPARENT))) ||
            optname == IP_MULTICAST_TTL ||
+           optname == IP_MULTICAST_ALL ||
            optname == IP_MULTICAST_LOOP ||
            optname == IP_RECVORIGDSTADDR) {
                if (optlen >= sizeof(int)) {
@@ -474,7 +479,7 @@ static int do_ip_setsockopt(struct sock *sk, int level,
        switch (optname) {
        case IP_OPTIONS:
        {
-               struct ip_options * opt = NULL;
+               struct ip_options *opt = NULL;
                if (optlen > 40 || optlen < 0)
                        goto e_inval;
                err = ip_options_get_from_user(sock_net(sk), &opt,
@@ -556,9 +561,9 @@ static int do_ip_setsockopt(struct sock *sk, int level,
                }
                break;
        case IP_TTL:
-               if (optlen<1)
+               if (optlen < 1)
                        goto e_inval;
-               if (val != -1 && (val < 1 || val>255))
+               if (val != -1 && (val < 0 || val > 255))
                        goto e_inval;
                inet->uc_ttl = val;
                break;
@@ -570,7 +575,7 @@ static int do_ip_setsockopt(struct sock *sk, int level,
                inet->hdrincl = val ? 1 : 0;
                break;
        case IP_MTU_DISCOVER:
-               if (val<0 || val>3)
+               if (val < 0 || val > 3)
                        goto e_inval;
                inet->pmtudisc = val;
                break;
@@ -582,7 +587,7 @@ static int do_ip_setsockopt(struct sock *sk, int level,
        case IP_MULTICAST_TTL:
                if (sk->sk_type == SOCK_STREAM)
                        goto e_inval;
-               if (optlen<1)
+               if (optlen < 1)
                        goto e_inval;
                if (val == -1)
                        val = 1;
@@ -591,7 +596,7 @@ static int do_ip_setsockopt(struct sock *sk, int level,
                inet->mc_ttl = val;
                break;
        case IP_MULTICAST_LOOP:
-               if (optlen<1)
+               if (optlen < 1)
                        goto e_inval;
                inet->mc_loop = !!val;
                break;
@@ -613,7 +618,8 @@ static int do_ip_setsockopt(struct sock *sk, int level,
                } else {
                        memset(&mreq, 0, sizeof(mreq));
                        if (optlen >= sizeof(struct in_addr) &&
-                           copy_from_user(&mreq.imr_address, optval, sizeof(struct in_addr)))
+                           copy_from_user(&mreq.imr_address, optval,
+                                          sizeof(struct in_addr)))
                                break;
                }
 
@@ -677,7 +683,6 @@ static int do_ip_setsockopt(struct sock *sk, int level,
        }
        case IP_MSFILTER:
        {
-               extern int sysctl_igmp_max_msf;
                struct ip_msfilter *msf;
 
                if (optlen < IP_MSFILTER_SIZE(0))
@@ -831,7 +836,6 @@ static int do_ip_setsockopt(struct sock *sk, int level,
        }
        case MCAST_MSFILTER:
        {
-               extern int sysctl_igmp_max_msf;
                struct sockaddr_in *psin;
                struct ip_msfilter *msf = NULL;
                struct group_filter *gsf = NULL;
@@ -849,9 +853,9 @@ static int do_ip_setsockopt(struct sock *sk, int level,
                        break;
                }
                err = -EFAULT;
-               if (copy_from_user(gsf, optval, optlen)) {
+               if (copy_from_user(gsf, optval, optlen))
                        goto mc_msf_out;
-               }
+
                /* numsrc >= (4G-140)/128 overflow in 32 bits */
                if (gsf->gf_numsrc >= 0x1ffffff ||
                    gsf->gf_numsrc > sysctl_igmp_max_msf) {
@@ -879,7 +883,7 @@ static int do_ip_setsockopt(struct sock *sk, int level,
                msf->imsf_fmode = gsf->gf_fmode;
                msf->imsf_numsrc = gsf->gf_numsrc;
                err = -EADDRNOTAVAIL;
-               for (i=0; i<gsf->gf_numsrc; ++i) {
+               for (i = 0; i < gsf->gf_numsrc; ++i) {
                        psin = (struct sockaddr_in *)&gsf->gf_slist[i];
 
                        if (psin->sin_family != AF_INET)
@@ -890,17 +894,24 @@ static int do_ip_setsockopt(struct sock *sk, int level,
                gsf = NULL;
 
                err = ip_mc_msfilter(sk, msf, ifindex);
-       mc_msf_out:
+mc_msf_out:
                kfree(msf);
                kfree(gsf);
                break;
        }
+       case IP_MULTICAST_ALL:
+               if (optlen < 1)
+                       goto e_inval;
+               if (val != 0 && val != 1)
+                       goto e_inval;
+               inet->mc_all = val;
+               break;
        case IP_ROUTER_ALERT:
                err = ip_ra_control(sk, val ? 1 : 0, NULL);
                break;
 
        case IP_FREEBIND:
-               if (optlen<1)
+               if (optlen < 1)
                        goto e_inval;
                inet->freebind = !!val;
                break;
@@ -957,6 +968,7 @@ int ip_setsockopt(struct sock *sk, int level,
 #endif
        return err;
 }
+EXPORT_SYMBOL(ip_setsockopt);
 
 #ifdef CONFIG_COMPAT
 int compat_ip_setsockopt(struct sock *sk, int level, int optname,
@@ -986,13 +998,12 @@ int compat_ip_setsockopt(struct sock *sk, int level, int optname,
 #endif
        return err;
 }
-
 EXPORT_SYMBOL(compat_ip_setsockopt);
 #endif
 
 /*
- *     Get the options. Note for future reference. The GET of IP options gets the
- *     _received_ ones. The set sets the _sent_ ones.
+ *     Get the options. Note for future reference. The GET of IP options gets
+ *     the _received_ ones. The set sets the _sent_ ones.
  */
 
 static int do_ip_getsockopt(struct sock *sk, int level, int optname,
@@ -1143,10 +1154,14 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname,
                        return -EFAULT;
                }
                err = ip_mc_gsfget(sk, &gsf,
-                                  (struct group_filter __user *)optval, optlen);
+                                  (struct group_filter __user *)optval,
+                                  optlen);
                release_sock(sk);
                return err;
        }
+       case IP_MULTICAST_ALL:
+               val = inet->mc_all;
+               break;
        case IP_PKTOPTIONS:
        {
                struct msghdr msg;
@@ -1187,7 +1202,7 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname,
        }
        release_sock(sk);
 
-       if (len < sizeof(int) && len > 0 && val>=0 && val<=255) {
+       if (len < sizeof(int) && len > 0 && val >= 0 && val <= 255) {
                unsigned char ucval = (unsigned char)val;
                len = 1;
                if (put_user(len, optlen))
@@ -1230,6 +1245,7 @@ int ip_getsockopt(struct sock *sk, int level,
 #endif
        return err;
 }
+EXPORT_SYMBOL(ip_getsockopt);
 
 #ifdef CONFIG_COMPAT
 int compat_ip_getsockopt(struct sock *sk, int level, int optname,
@@ -1262,11 +1278,5 @@ int compat_ip_getsockopt(struct sock *sk, int level, int optname,
 #endif
        return err;
 }
-
 EXPORT_SYMBOL(compat_ip_getsockopt);
 #endif
-
-EXPORT_SYMBOL(ip_cmsg_recv);
-
-EXPORT_SYMBOL(ip_getsockopt);
-EXPORT_SYMBOL(ip_setsockopt);
index 88bf051d0cbb4cd8989b44b8e894e6ab0ac60e53..f8d04c256454fe14c4bbd65689e174b7cf9bbc04 100644 (file)
@@ -160,6 +160,9 @@ static char user_dev_name[IFNAMSIZ] __initdata = { 0, };
 /* Protocols supported by available interfaces */
 static int ic_proto_have_if __initdata = 0;
 
+/* MTU for boot device */
+static int ic_dev_mtu __initdata = 0;
+
 #ifdef IPCONFIG_DYNAMIC
 static DEFINE_SPINLOCK(ic_recv_lock);
 static volatile int ic_got_reply __initdata = 0;    /* Proto(s) that replied */
@@ -286,7 +289,7 @@ set_sockaddr(struct sockaddr_in *sin, __be32 addr, __be16 port)
        sin->sin_port = port;
 }
 
-static int __init ic_dev_ioctl(unsigned int cmd, struct ifreq *arg)
+static int __init ic_devinet_ioctl(unsigned int cmd, struct ifreq *arg)
 {
        int res;
 
@@ -297,6 +300,17 @@ static int __init ic_dev_ioctl(unsigned int cmd, struct ifreq *arg)
        return res;
 }
 
+static int __init ic_dev_ioctl(unsigned int cmd, struct ifreq *arg)
+{
+       int res;
+
+       mm_segment_t oldfs = get_fs();
+       set_fs(get_ds());
+       res = dev_ioctl(&init_net, cmd, (struct ifreq __user *) arg);
+       set_fs(oldfs);
+       return res;
+}
+
 static int __init ic_route_ioctl(unsigned int cmd, struct rtentry *arg)
 {
        int res;
@@ -321,20 +335,31 @@ static int __init ic_setup_if(void)
        memset(&ir, 0, sizeof(ir));
        strcpy(ir.ifr_ifrn.ifrn_name, ic_dev->name);
        set_sockaddr(sin, ic_myaddr, 0);
-       if ((err = ic_dev_ioctl(SIOCSIFADDR, &ir)) < 0) {
+       if ((err = ic_devinet_ioctl(SIOCSIFADDR, &ir)) < 0) {
                printk(KERN_ERR "IP-Config: Unable to set interface address (%d).\n", err);
                return -1;
        }
        set_sockaddr(sin, ic_netmask, 0);
-       if ((err = ic_dev_ioctl(SIOCSIFNETMASK, &ir)) < 0) {
+       if ((err = ic_devinet_ioctl(SIOCSIFNETMASK, &ir)) < 0) {
                printk(KERN_ERR "IP-Config: Unable to set interface netmask (%d).\n", err);
                return -1;
        }
        set_sockaddr(sin, ic_myaddr | ~ic_netmask, 0);
-       if ((err = ic_dev_ioctl(SIOCSIFBRDADDR, &ir)) < 0) {
+       if ((err = ic_devinet_ioctl(SIOCSIFBRDADDR, &ir)) < 0) {
                printk(KERN_ERR "IP-Config: Unable to set interface broadcast address (%d).\n", err);
                return -1;
        }
+       /* Handle the case where we need non-standard MTU on the boot link (a network
+        * using jumbo frames, for instance).  If we can't set the mtu, don't error
+        * out, we'll try to muddle along.
+        */
+       if (ic_dev_mtu != 0) {
+               strcpy(ir.ifr_name, ic_dev->name);
+               ir.ifr_mtu = ic_dev_mtu;
+               if ((err = ic_dev_ioctl(SIOCSIFMTU, &ir)) < 0)
+                       printk(KERN_ERR "IP-Config: Unable to set interface mtu to %d (%d).\n",
+                                        ic_dev_mtu, err);
+       }
        return 0;
 }
 
@@ -623,6 +648,7 @@ ic_dhcp_init_options(u8 *options)
                        12,     /* Host name */
                        15,     /* Domain name */
                        17,     /* Boot path */
+                       26,     /* MTU */
                        40,     /* NIS domain name */
                };
 
@@ -798,6 +824,7 @@ static void __init ic_do_bootp_ext(u8 *ext)
 {
        u8 servers;
        int i;
+       u16 mtu;
 
 #ifdef IPCONFIG_DEBUG
        u8 *c;
@@ -837,6 +864,10 @@ static void __init ic_do_bootp_ext(u8 *ext)
                        if (!root_server_path[0])
                                ic_bootp_string(root_server_path, ext+1, *ext, sizeof(root_server_path));
                        break;
+               case 26:        /* Interface MTU */
+                       memcpy(&mtu, ext+1, sizeof(mtu));
+                       ic_dev_mtu = ntohs(mtu);
+                       break;
                case 40:        /* NIS Domain name (_not_ DNS) */
                        ic_bootp_string(utsname()->domainname, ext+1, *ext, __NEW_UTS_LEN);
                        break;
@@ -1403,6 +1434,8 @@ static int __init ip_auto_config(void)
        printk(",\n     bootserver=%pI4", &ic_servaddr);
        printk(", rootserver=%pI4", &root_server_addr);
        printk(", rootpath=%s", root_server_path);
+       if (ic_dev_mtu)
+               printk(", mtu=%d", ic_dev_mtu);
        printk("\n");
 #endif /* !SILENT */
 
index 9054139795af480757357dc626815296666f8919..93e2b787da208aded55d00f2dab116ba629b8b22 100644 (file)
@@ -370,8 +370,7 @@ static int ipip_rcv(struct sk_buff *skb)
                tunnel->dev->stats.rx_packets++;
                tunnel->dev->stats.rx_bytes += skb->len;
                skb->dev = tunnel->dev;
-               dst_release(skb->dst);
-               skb->dst = NULL;
+               skb_dst_drop(skb);
                nf_reset(skb);
                ipip_ecn_decapsulate(iph, skb);
                netif_rx(skb);
@@ -416,7 +415,7 @@ static int ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
 
        if (!dst) {
                /* NBMA tunnel */
-               if ((rt = skb->rtable) == NULL) {
+               if ((rt = skb_rtable(skb)) == NULL) {
                        stats->tx_fifo_errors++;
                        goto tx_error;
                }
@@ -447,15 +446,15 @@ static int ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
        if (tiph->frag_off)
                mtu = dst_mtu(&rt->u.dst) - sizeof(struct iphdr);
        else
-               mtu = skb->dst ? dst_mtu(skb->dst) : dev->mtu;
+               mtu = skb_dst(skb) ? dst_mtu(skb_dst(skb)) : dev->mtu;
 
        if (mtu < 68) {
                stats->collisions++;
                ip_rt_put(rt);
                goto tx_error;
        }
-       if (skb->dst)
-               skb->dst->ops->update_pmtu(skb->dst, mtu);
+       if (skb_dst(skb))
+               skb_dst(skb)->ops->update_pmtu(skb_dst(skb), mtu);
 
        df |= (old_iph->frag_off&htons(IP_DF));
 
@@ -502,8 +501,8 @@ static int ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
        memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
        IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED |
                              IPSKB_REROUTED);
-       dst_release(skb->dst);
-       skb->dst = &rt->u.dst;
+       skb_dst_drop(skb);
+       skb_dst_set(skb, &rt->u.dst);
 
        /*
         *      Push down and install the IPIP header.
@@ -713,6 +712,7 @@ static void ipip_tunnel_setup(struct net_device *dev)
        dev->iflink             = 0;
        dev->addr_len           = 4;
        dev->features           |= NETIF_F_NETNS_LOCAL;
+       dev->priv_flags         &= ~IFF_XMIT_DST_RELEASE;
 }
 
 static void ipip_tunnel_init(struct net_device *dev)
index 13e9dd3012b3a0173f0528fa591cd3eb798e02fd..9a8da5ed92b7cab3c4883b5866c3a69e655a7278 100644 (file)
@@ -226,9 +226,10 @@ static void reg_vif_setup(struct net_device *dev)
        dev->flags              = IFF_NOARP;
        dev->netdev_ops         = &reg_vif_netdev_ops,
        dev->destructor         = free_netdev;
+       dev->features           |= NETIF_F_NETNS_LOCAL;
 }
 
-static struct net_device *ipmr_reg_vif(void)
+static struct net_device *ipmr_reg_vif(struct net *net)
 {
        struct net_device *dev;
        struct in_device *in_dev;
@@ -238,6 +239,8 @@ static struct net_device *ipmr_reg_vif(void)
        if (dev == NULL)
                return NULL;
 
+       dev_net_set(dev, net);
+
        if (register_netdevice(dev)) {
                free_netdev(dev);
                return NULL;
@@ -448,7 +451,7 @@ static int vif_add(struct net *net, struct vifctl *vifc, int mrtsock)
                 */
                if (net->ipv4.mroute_reg_vif_num >= 0)
                        return -EADDRINUSE;
-               dev = ipmr_reg_vif();
+               dev = ipmr_reg_vif(net);
                if (!dev)
                        return -ENOBUFS;
                err = dev_set_allmulti(dev, 1);
@@ -651,7 +654,7 @@ static int ipmr_cache_report(struct net *net,
        ip_hdr(skb)->protocol = 0;                      /* Flag to the kernel this is a route add */
        msg = (struct igmpmsg *)skb_network_header(skb);
        msg->im_vif = vifi;
-       skb->dst = dst_clone(pkt->dst);
+       skb_dst_set(skb, dst_clone(skb_dst(pkt)));
 
        /*
         *      Add our header
@@ -1031,16 +1034,6 @@ int ip_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, int
                if (v != net->ipv4.mroute_do_pim) {
                        net->ipv4.mroute_do_pim = v;
                        net->ipv4.mroute_do_assert = v;
-#ifdef CONFIG_IP_PIMSM_V2
-                       if (net->ipv4.mroute_do_pim)
-                               ret = inet_add_protocol(&pim_protocol,
-                                                       IPPROTO_PIM);
-                       else
-                               ret = inet_del_protocol(&pim_protocol,
-                                                       IPPROTO_PIM);
-                       if (ret < 0)
-                               ret = -EAGAIN;
-#endif
                }
                rtnl_unlock();
                return ret;
@@ -1201,7 +1194,7 @@ static void ip_encap(struct sk_buff *skb, __be32 saddr, __be32 daddr)
        iph->protocol   =       IPPROTO_IPIP;
        iph->ihl        =       5;
        iph->tot_len    =       htons(skb->len);
-       ip_select_ident(iph, skb->dst, NULL);
+       ip_select_ident(iph, skb_dst(skb), NULL);
        ip_send_check(iph);
 
        memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
@@ -1212,7 +1205,7 @@ static inline int ipmr_forward_finish(struct sk_buff *skb)
 {
        struct ip_options * opt = &(IPCB(skb)->opt);
 
-       IP_INC_STATS_BH(dev_net(skb->dst->dev), IPSTATS_MIB_OUTFORWDATAGRAMS);
+       IP_INC_STATS_BH(dev_net(skb_dst(skb)->dev), IPSTATS_MIB_OUTFORWDATAGRAMS);
 
        if (unlikely(opt->optlen))
                ip_forward_options(skb);
@@ -1290,8 +1283,8 @@ static void ipmr_queue_xmit(struct sk_buff *skb, struct mfc_cache *c, int vifi)
        vif->pkt_out++;
        vif->bytes_out += skb->len;
 
-       dst_release(skb->dst);
-       skb->dst = &rt->u.dst;
+       skb_dst_drop(skb);
+       skb_dst_set(skb, &rt->u.dst);
        ip_decrease_ttl(ip_hdr(skb));
 
        /* FIXME: forward and output firewalls used to be called here.
@@ -1354,7 +1347,7 @@ static int ip_mr_forward(struct sk_buff *skb, struct mfc_cache *cache, int local
        if (net->ipv4.vif_table[vif].dev != skb->dev) {
                int true_vifi;
 
-               if (skb->rtable->fl.iif == 0) {
+               if (skb_rtable(skb)->fl.iif == 0) {
                        /* It is our own packet, looped back.
                           Very complicated situation...
 
@@ -1430,7 +1423,7 @@ int ip_mr_input(struct sk_buff *skb)
 {
        struct mfc_cache *cache;
        struct net *net = dev_net(skb->dev);
-       int local = skb->rtable->rt_flags&RTCF_LOCAL;
+       int local = skb_rtable(skb)->rt_flags & RTCF_LOCAL;
 
        /* Packet is looped back after forward, it should not be
           forwarded second time, but still can be delivered locally.
@@ -1543,8 +1536,7 @@ static int __pim_rcv(struct sk_buff *skb, unsigned int pimlen)
        skb->protocol = htons(ETH_P_IP);
        skb->ip_summed = 0;
        skb->pkt_type = PACKET_HOST;
-       dst_release(skb->dst);
-       skb->dst = NULL;
+       skb_dst_drop(skb);
        reg_dev->stats.rx_bytes += skb->len;
        reg_dev->stats.rx_packets++;
        nf_reset(skb);
@@ -1646,7 +1638,7 @@ int ipmr_get_route(struct net *net,
 {
        int err;
        struct mfc_cache *cache;
-       struct rtable *rt = skb->rtable;
+       struct rtable *rt = skb_rtable(skb);
 
        read_lock(&mrt_lock);
        cache = ipmr_cache_find(net, rt->rt_src, rt->rt_dst);
@@ -1955,6 +1947,7 @@ static const struct file_operations ipmr_mfc_fops = {
 #ifdef CONFIG_IP_PIMSM_V2
 static struct net_protocol pim_protocol = {
        .handler        =       pim_rcv,
+       .netns_ok       =       1,
 };
 #endif
 
@@ -2041,8 +2034,19 @@ int __init ip_mr_init(void)
        err = register_netdevice_notifier(&ip_mr_notifier);
        if (err)
                goto reg_notif_fail;
+#ifdef CONFIG_IP_PIMSM_V2
+       if (inet_add_protocol(&pim_protocol, IPPROTO_PIM) < 0) {
+               printk(KERN_ERR "ip_mr_init: can't add PIM protocol\n");
+               err = -EAGAIN;
+               goto add_proto_fail;
+       }
+#endif
        return 0;
 
+#ifdef CONFIG_IP_PIMSM_V2
+add_proto_fail:
+       unregister_netdevice_notifier(&ip_mr_notifier);
+#endif
 reg_notif_fail:
        del_timer(&ipmr_expire_timer);
        unregister_pernet_subsys(&ipmr_net_ops);
index fdf6811c31a246df891495fdc76b46c00e5f783b..1725dc0ef68875253d02e4e6bdd777ead267d9a3 100644 (file)
@@ -12,7 +12,7 @@
 /* route_me_harder function, used by iptable_nat, iptable_mangle + ip_queue */
 int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type)
 {
-       struct net *net = dev_net(skb->dst->dev);
+       struct net *net = dev_net(skb_dst(skb)->dev);
        const struct iphdr *iph = ip_hdr(skb);
        struct rtable *rt;
        struct flowi fl = {};
@@ -41,8 +41,8 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type)
                        return -1;
 
                /* Drop old route. */
-               dst_release(skb->dst);
-               skb->dst = &rt->u.dst;
+               skb_dst_drop(skb);
+               skb_dst_set(skb, &rt->u.dst);
        } else {
                /* non-local src, find valid iif to satisfy
                 * rp-filter when calling ip_route_input. */
@@ -50,7 +50,7 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type)
                if (ip_route_output_key(net, &rt, &fl) != 0)
                        return -1;
 
-               odst = skb->dst;
+               odst = skb_dst(skb);
                if (ip_route_input(skb, iph->daddr, iph->saddr,
                                   RT_TOS(iph->tos), rt->u.dst.dev) != 0) {
                        dst_release(&rt->u.dst);
@@ -60,18 +60,22 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type)
                dst_release(odst);
        }
 
-       if (skb->dst->error)
+       if (skb_dst(skb)->error)
                return -1;
 
 #ifdef CONFIG_XFRM
        if (!(IPCB(skb)->flags & IPSKB_XFRM_TRANSFORMED) &&
-           xfrm_decode_session(skb, &fl, AF_INET) == 0)
-               if (xfrm_lookup(net, &skb->dst, &fl, skb->sk, 0))
+           xfrm_decode_session(skb, &fl, AF_INET) == 0) {
+               struct dst_entry *dst = skb_dst(skb);
+               skb_dst_set(skb, NULL);
+               if (xfrm_lookup(net, &dst, &fl, skb->sk, 0))
                        return -1;
+               skb_dst_set(skb, dst);
+       }
 #endif
 
        /* Change in oif may mean change in hh_len. */
-       hh_len = skb->dst->dev->hard_header_len;
+       hh_len = skb_dst(skb)->dev->hard_header_len;
        if (skb_headroom(skb) < hh_len &&
            pskb_expand_head(skb, hh_len - skb_headroom(skb), 0, GFP_ATOMIC))
                return -1;
@@ -92,7 +96,7 @@ int ip_xfrm_me_harder(struct sk_buff *skb)
        if (xfrm_decode_session(skb, &fl, AF_INET) < 0)
                return -1;
 
-       dst = skb->dst;
+       dst = skb_dst(skb);
        if (dst->xfrm)
                dst = ((struct xfrm_dst *)dst)->route;
        dst_hold(dst);
@@ -100,11 +104,11 @@ int ip_xfrm_me_harder(struct sk_buff *skb)
        if (xfrm_lookup(dev_net(dst->dev), &dst, &fl, skb->sk, 0) < 0)
                return -1;
 
-       dst_release(skb->dst);
-       skb->dst = dst;
+       skb_dst_drop(skb);
+       skb_dst_set(skb, dst);
 
        /* Change in oif may mean change in hh_len. */
-       hh_len = skb->dst->dev->hard_header_len;
+       hh_len = skb_dst(skb)->dev->hard_header_len;
        if (skb_headroom(skb) < hh_len &&
            pskb_expand_head(skb, hh_len - skb_headroom(skb), 0, GFP_ATOMIC))
                return -1;
index 831fe1879dc07dfacdb8eff3970829140f748e16..7505dff4ffdf5a479e431e71177c4fceda544312 100644 (file)
@@ -231,6 +231,12 @@ static inline struct arpt_entry *get_entry(void *base, unsigned int offset)
        return (struct arpt_entry *)(base + offset);
 }
 
+static inline __pure
+struct arpt_entry *arpt_next_entry(const struct arpt_entry *entry)
+{
+       return (void *)entry + entry->next_offset;
+}
+
 unsigned int arpt_do_table(struct sk_buff *skb,
                           unsigned int hook,
                           const struct net_device *in,
@@ -267,67 +273,64 @@ unsigned int arpt_do_table(struct sk_buff *skb,
 
        arp = arp_hdr(skb);
        do {
-               if (arp_packet_match(arp, skb->dev, indev, outdev, &e->arp)) {
-                       struct arpt_entry_target *t;
-                       int hdr_len;
-
-                       hdr_len = sizeof(*arp) + (2 * sizeof(struct in_addr)) +
-                               (2 * skb->dev->addr_len);
+               struct arpt_entry_target *t;
+               int hdr_len;
 
-                       ADD_COUNTER(e->counters, hdr_len, 1);
+               if (!arp_packet_match(arp, skb->dev, indev, outdev, &e->arp)) {
+                       e = arpt_next_entry(e);
+                       continue;
+               }
 
-                       t = arpt_get_target(e);
+               hdr_len = sizeof(*arp) + (2 * sizeof(struct in_addr)) +
+                       (2 * skb->dev->addr_len);
+               ADD_COUNTER(e->counters, hdr_len, 1);
 
-                       /* Standard target? */
-                       if (!t->u.kernel.target->target) {
-                               int v;
+               t = arpt_get_target(e);
 
-                               v = ((struct arpt_standard_target *)t)->verdict;
-                               if (v < 0) {
-                                       /* Pop from stack? */
-                                       if (v != ARPT_RETURN) {
-                                               verdict = (unsigned)(-v) - 1;
-                                               break;
-                                       }
-                                       e = back;
-                                       back = get_entry(table_base,
-                                                        back->comefrom);
-                                       continue;
-                               }
-                               if (table_base + v
-                                   != (void *)e + e->next_offset) {
-                                       /* Save old back ptr in next entry */
-                                       struct arpt_entry *next
-                                               = (void *)e + e->next_offset;
-                                       next->comefrom =
-                                               (void *)back - table_base;
-
-                                       /* set back pointer to next entry */
-                                       back = next;
-                               }
+               /* Standard target? */
+               if (!t->u.kernel.target->target) {
+                       int v;
 
-                               e = get_entry(table_base, v);
-                       } else {
-                               /* Targets which reenter must return
-                                * abs. verdicts
-                                */
-                               tgpar.target   = t->u.kernel.target;
-                               tgpar.targinfo = t->data;
-                               verdict = t->u.kernel.target->target(skb,
-                                                                    &tgpar);
-
-                               /* Target might have changed stuff. */
-                               arp = arp_hdr(skb);
-
-                               if (verdict == ARPT_CONTINUE)
-                                       e = (void *)e + e->next_offset;
-                               else
-                                       /* Verdict */
+                       v = ((struct arpt_standard_target *)t)->verdict;
+                       if (v < 0) {
+                               /* Pop from stack? */
+                               if (v != ARPT_RETURN) {
+                                       verdict = (unsigned)(-v) - 1;
                                        break;
+                               }
+                               e = back;
+                               back = get_entry(table_base, back->comefrom);
+                               continue;
                        }
-               } else {
-                       e = (void *)e + e->next_offset;
+                       if (table_base + v
+                           != arpt_next_entry(e)) {
+                               /* Save old back ptr in next entry */
+                               struct arpt_entry *next = arpt_next_entry(e);
+                               next->comefrom = (void *)back - table_base;
+
+                               /* set back pointer to next entry */
+                               back = next;
+                       }
+
+                       e = get_entry(table_base, v);
+                       continue;
                }
+
+               /* Targets which reenter must return
+                * abs. verdicts
+                */
+               tgpar.target   = t->u.kernel.target;
+               tgpar.targinfo = t->data;
+               verdict = t->u.kernel.target->target(skb, &tgpar);
+
+               /* Target might have changed stuff. */
+               arp = arp_hdr(skb);
+
+               if (verdict == ARPT_CONTINUE)
+                       e = arpt_next_entry(e);
+               else
+                       /* Verdict */
+                       break;
        } while (!hotdrop);
        xt_info_rdunlock_bh();
 
index 5f22c91c6e1518c254d3728a53ce65cb409b26d5..c156db215987638c8b06a6c5163395715e91fbe3 100644 (file)
@@ -596,7 +596,7 @@ static int __init ip_queue_init(void)
 #ifdef CONFIG_SYSCTL
        ipq_sysctl_header = register_sysctl_paths(net_ipv4_ctl_path, ipq_table);
 #endif
-       status = nf_register_queue_handler(PF_INET, &nfqh);
+       status = nf_register_queue_handler(NFPROTO_IPV4, &nfqh);
        if (status < 0) {
                printk(KERN_ERR "ip_queue: failed to register queue handler\n");
                goto cleanup_sysctl;
index 2ec8d7290c400a4e8adfe71888150c41927be835..fdefae6b5dfc2d19209dfd7d7729caaa03f02d80 100644 (file)
@@ -238,8 +238,8 @@ static struct nf_loginfo trace_loginfo = {
 /* Mildly perf critical (only if packet tracing is on) */
 static inline int
 get_chainname_rulenum(struct ipt_entry *s, struct ipt_entry *e,
-                     char *hookname, char **chainname,
-                     char **comment, unsigned int *rulenum)
+                     const char *hookname, const char **chainname,
+                     const char **comment, unsigned int *rulenum)
 {
        struct ipt_standard_target *t = (void *)ipt_get_target(s);
 
@@ -257,8 +257,8 @@ get_chainname_rulenum(struct ipt_entry *s, struct ipt_entry *e,
                   && unconditional(&s->ip)) {
                        /* Tail of chains: STANDARD target (return/policy) */
                        *comment = *chainname == hookname
-                               ? (char *)comments[NF_IP_TRACE_COMMENT_POLICY]
-                               : (char *)comments[NF_IP_TRACE_COMMENT_RETURN];
+                               ? comments[NF_IP_TRACE_COMMENT_POLICY]
+                               : comments[NF_IP_TRACE_COMMENT_RETURN];
                }
                return 1;
        } else
@@ -277,14 +277,14 @@ static void trace_packet(struct sk_buff *skb,
 {
        void *table_base;
        const struct ipt_entry *root;
-       char *hookname, *chainname, *comment;
+       const char *hookname, *chainname, *comment;
        unsigned int rulenum = 0;
 
-       table_base = (void *)private->entries[smp_processor_id()];
+       table_base = private->entries[smp_processor_id()];
        root = get_entry(table_base, private->hook_entry[hook]);
 
-       hookname = chainname = (char *)hooknames[hook];
-       comment = (char *)comments[NF_IP_TRACE_COMMENT_RULE];
+       hookname = chainname = hooknames[hook];
+       comment = comments[NF_IP_TRACE_COMMENT_RULE];
 
        IPT_ENTRY_ITERATE(root,
                          private->size - private->hook_entry[hook],
@@ -297,6 +297,12 @@ static void trace_packet(struct sk_buff *skb,
 }
 #endif
 
+static inline __pure
+struct ipt_entry *ipt_next_entry(const struct ipt_entry *entry)
+{
+       return (void *)entry + entry->next_offset;
+}
+
 /* Returns one of the generic firewall policies, like NF_ACCEPT. */
 unsigned int
 ipt_do_table(struct sk_buff *skb,
@@ -305,6 +311,8 @@ ipt_do_table(struct sk_buff *skb,
             const struct net_device *out,
             struct xt_table *table)
 {
+#define tb_comefrom ((struct ipt_entry *)table_base)->comefrom
+
        static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long))));
        const struct iphdr *ip;
        u_int16_t datalen;
@@ -335,7 +343,7 @@ ipt_do_table(struct sk_buff *skb,
        mtpar.in      = tgpar.in  = in;
        mtpar.out     = tgpar.out = out;
        mtpar.family  = tgpar.family = NFPROTO_IPV4;
-       tgpar.hooknum = hook;
+       mtpar.hooknum = tgpar.hooknum = hook;
 
        IP_NF_ASSERT(table->valid_hooks & (1 << hook));
        xt_info_rdlock_bh();
@@ -348,92 +356,84 @@ ipt_do_table(struct sk_buff *skb,
        back = get_entry(table_base, private->underflow[hook]);
 
        do {
+               struct ipt_entry_target *t;
+
                IP_NF_ASSERT(e);
                IP_NF_ASSERT(back);
-               if (ip_packet_match(ip, indev, outdev,
-                   &e->ip, mtpar.fragoff)) {
-                       struct ipt_entry_target *t;
-
-                       if (IPT_MATCH_ITERATE(e, do_match, skb, &mtpar) != 0)
-                               goto no_match;
+               if (!ip_packet_match(ip, indev, outdev,
+                   &e->ip, mtpar.fragoff) ||
+                   IPT_MATCH_ITERATE(e, do_match, skb, &mtpar) != 0) {
+                       e = ipt_next_entry(e);
+                       continue;
+               }
 
-                       ADD_COUNTER(e->counters, ntohs(ip->tot_len), 1);
+               ADD_COUNTER(e->counters, ntohs(ip->tot_len), 1);
 
-                       t = ipt_get_target(e);
-                       IP_NF_ASSERT(t->u.kernel.target);
+               t = ipt_get_target(e);
+               IP_NF_ASSERT(t->u.kernel.target);
 
 #if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
     defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
-                       /* The packet is traced: log it */
-                       if (unlikely(skb->nf_trace))
-                               trace_packet(skb, hook, in, out,
-                                            table->name, private, e);
+               /* The packet is traced: log it */
+               if (unlikely(skb->nf_trace))
+                       trace_packet(skb, hook, in, out,
+                                    table->name, private, e);
 #endif
-                       /* Standard target? */
-                       if (!t->u.kernel.target->target) {
-                               int v;
-
-                               v = ((struct ipt_standard_target *)t)->verdict;
-                               if (v < 0) {
-                                       /* Pop from stack? */
-                                       if (v != IPT_RETURN) {
-                                               verdict = (unsigned)(-v) - 1;
-                                               break;
-                                       }
-                                       e = back;
-                                       back = get_entry(table_base,
-                                                        back->comefrom);
-                                       continue;
-                               }
-                               if (table_base + v != (void *)e + e->next_offset
-                                   && !(e->ip.flags & IPT_F_GOTO)) {
-                                       /* Save old back ptr in next entry */
-                                       struct ipt_entry *next
-                                               = (void *)e + e->next_offset;
-                                       next->comefrom
-                                               = (void *)back - table_base;
-                                       /* set back pointer to next entry */
-                                       back = next;
+               /* Standard target? */
+               if (!t->u.kernel.target->target) {
+                       int v;
+
+                       v = ((struct ipt_standard_target *)t)->verdict;
+                       if (v < 0) {
+                               /* Pop from stack? */
+                               if (v != IPT_RETURN) {
+                                       verdict = (unsigned)(-v) - 1;
+                                       break;
                                }
+                               e = back;
+                               back = get_entry(table_base, back->comefrom);
+                               continue;
+                       }
+                       if (table_base + v != ipt_next_entry(e)
+                           && !(e->ip.flags & IPT_F_GOTO)) {
+                               /* Save old back ptr in next entry */
+                               struct ipt_entry *next = ipt_next_entry(e);
+                               next->comefrom = (void *)back - table_base;
+                               /* set back pointer to next entry */
+                               back = next;
+                       }
+
+                       e = get_entry(table_base, v);
+                       continue;
+               }
+
+               /* Targets which reenter must return
+                  abs. verdicts */
+               tgpar.target   = t->u.kernel.target;
+               tgpar.targinfo = t->data;
+
 
-                               e = get_entry(table_base, v);
-                       } else {
-                               /* Targets which reenter must return
-                                  abs. verdicts */
-                               tgpar.target   = t->u.kernel.target;
-                               tgpar.targinfo = t->data;
 #ifdef CONFIG_NETFILTER_DEBUG
-                               ((struct ipt_entry *)table_base)->comefrom
-                                       = 0xeeeeeeec;
+               tb_comefrom = 0xeeeeeeec;
 #endif
-                               verdict = t->u.kernel.target->target(skb,
-                                                                    &tgpar);
+               verdict = t->u.kernel.target->target(skb, &tgpar);
 #ifdef CONFIG_NETFILTER_DEBUG
-                               if (((struct ipt_entry *)table_base)->comefrom
-                                   != 0xeeeeeeec
-                                   && verdict == IPT_CONTINUE) {
-                                       printk("Target %s reentered!\n",
-                                              t->u.kernel.target->name);
-                                       verdict = NF_DROP;
-                               }
-                               ((struct ipt_entry *)table_base)->comefrom
-                                       = 0x57acc001;
+               if (tb_comefrom != 0xeeeeeeec && verdict == IPT_CONTINUE) {
+                       printk("Target %s reentered!\n",
+                              t->u.kernel.target->name);
+                       verdict = NF_DROP;
+               }
+               tb_comefrom = 0x57acc001;
 #endif
-                               /* Target might have changed stuff. */
-                               ip = ip_hdr(skb);
-                               datalen = skb->len - ip->ihl * 4;
-
-                               if (verdict == IPT_CONTINUE)
-                                       e = (void *)e + e->next_offset;
-                               else
-                                       /* Verdict */
-                                       break;
-                       }
-               } else {
+               /* Target might have changed stuff. */
+               ip = ip_hdr(skb);
+               datalen = skb->len - ip->ihl * 4;
 
-               no_match:
-                       e = (void *)e + e->next_offset;
-               }
+               if (verdict == IPT_CONTINUE)
+                       e = ipt_next_entry(e);
+               else
+                       /* Verdict */
+                       break;
        } while (!hotdrop);
        xt_info_rdunlock_bh();
 
@@ -444,6 +444,8 @@ ipt_do_table(struct sk_buff *skb,
                return NF_DROP;
        else return verdict;
 #endif
+
+#undef tb_comefrom
 }
 
 /* Figures out from what hook each rule can be called: returns 0 if
@@ -2158,7 +2160,7 @@ static bool icmp_checkentry(const struct xt_mtchk_param *par)
 static struct xt_target ipt_standard_target __read_mostly = {
        .name           = IPT_STANDARD_TARGET,
        .targetsize     = sizeof(int),
-       .family         = AF_INET,
+       .family         = NFPROTO_IPV4,
 #ifdef CONFIG_COMPAT
        .compatsize     = sizeof(compat_int_t),
        .compat_from_user = compat_standard_from_user,
@@ -2170,7 +2172,7 @@ static struct xt_target ipt_error_target __read_mostly = {
        .name           = IPT_ERROR_TARGET,
        .target         = ipt_error,
        .targetsize     = IPT_FUNCTION_MAXNAMELEN,
-       .family         = AF_INET,
+       .family         = NFPROTO_IPV4,
 };
 
 static struct nf_sockopt_ops ipt_sockopts = {
@@ -2196,17 +2198,17 @@ static struct xt_match icmp_matchstruct __read_mostly = {
        .matchsize      = sizeof(struct ipt_icmp),
        .checkentry     = icmp_checkentry,
        .proto          = IPPROTO_ICMP,
-       .family         = AF_INET,
+       .family         = NFPROTO_IPV4,
 };
 
 static int __net_init ip_tables_net_init(struct net *net)
 {
-       return xt_proto_init(net, AF_INET);
+       return xt_proto_init(net, NFPROTO_IPV4);
 }
 
 static void __net_exit ip_tables_net_exit(struct net *net)
 {
-       xt_proto_fini(net, AF_INET);
+       xt_proto_fini(net, NFPROTO_IPV4);
 }
 
 static struct pernet_operations ip_tables_net_ops = {
index f389f60cb105856f690faefd235a852e699c66ae..dada0863946d9da71151320128800d968bdc4a4b 100644 (file)
@@ -27,9 +27,6 @@ MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
 MODULE_DESCRIPTION("Xtables: automatic-address SNAT");
 
-/* Lock protects masq region inside conntrack */
-static DEFINE_RWLOCK(masq_lock);
-
 /* FIXME: Multiple targets. --RR */
 static bool masquerade_tg_check(const struct xt_tgchk_param *par)
 {
@@ -72,16 +69,14 @@ masquerade_tg(struct sk_buff *skb, const struct xt_target_param *par)
                return NF_ACCEPT;
 
        mr = par->targinfo;
-       rt = skb->rtable;
+       rt = skb_rtable(skb);
        newsrc = inet_select_addr(par->out, rt->rt_gateway, RT_SCOPE_UNIVERSE);
        if (!newsrc) {
                printk("MASQUERADE: %s ate my IP address\n", par->out->name);
                return NF_DROP;
        }
 
-       write_lock_bh(&masq_lock);
        nat->masq_index = par->out->ifindex;
-       write_unlock_bh(&masq_lock);
 
        /* Transfer from original range. */
        newrange = ((struct nf_nat_range)
@@ -97,16 +92,11 @@ static int
 device_cmp(struct nf_conn *i, void *ifindex)
 {
        const struct nf_conn_nat *nat = nfct_nat(i);
-       int ret;
 
        if (!nat)
                return 0;
 
-       read_lock_bh(&masq_lock);
-       ret = (nat->masq_index == (int)(long)ifindex);
-       read_unlock_bh(&masq_lock);
-
-       return ret;
+       return nat->masq_index == (int)(long)ifindex;
 }
 
 static int masq_device_event(struct notifier_block *this,
index 0b4b6e0ff2b983985b5b6e3e7a695c6c731d1941..c93ae44bff2a057fcbc089e845369631702ad59d 100644 (file)
@@ -108,17 +108,16 @@ static void send_reset(struct sk_buff *oldskb, int hook)
                addr_type = RTN_LOCAL;
 
        /* ip_route_me_harder expects skb->dst to be set */
-       dst_hold(oldskb->dst);
-       nskb->dst = oldskb->dst;
+       skb_dst_set(nskb, dst_clone(skb_dst(oldskb)));
 
        if (ip_route_me_harder(nskb, addr_type))
                goto free_nskb;
 
-       niph->ttl       = dst_metric(nskb->dst, RTAX_HOPLIMIT);
+       niph->ttl       = dst_metric(skb_dst(nskb), RTAX_HOPLIMIT);
        nskb->ip_summed = CHECKSUM_NONE;
 
        /* "Never happens" */
-       if (nskb->len > dst_mtu(nskb->dst))
+       if (nskb->len > dst_mtu(skb_dst(nskb)))
                goto free_nskb;
 
        nf_ct_attach(nskb, oldskb);
index 23b2c2ee869a85c4f92a5a45bce4f731e4815e13..d71ba7677344136b3564230c372dd4fc7f8e81ea 100644 (file)
@@ -82,18 +82,10 @@ static int icmp_packet(struct nf_conn *ct,
                       u_int8_t pf,
                       unsigned int hooknum)
 {
-       /* Try to delete connection immediately after all replies:
-          won't actually vanish as we still have skb, and del_timer
-          means this will only run once even if count hits zero twice
-          (theoretically possible with SMP) */
-       if (CTINFO2DIR(ctinfo) == IP_CT_DIR_REPLY) {
-               if (atomic_dec_and_test(&ct->proto.icmp.count))
-                       nf_ct_kill_acct(ct, ctinfo, skb);
-       } else {
-               atomic_inc(&ct->proto.icmp.count);
-               nf_conntrack_event_cache(IPCT_PROTOINFO_VOLATILE, ct);
-               nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_icmp_timeout);
-       }
+       /* Do not immediately delete the connection after the first
+          successful reply to avoid excessive conntrackd traffic
+          and also to handle correctly ICMP echo reply duplicates. */
+       nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_icmp_timeout);
 
        return NF_ACCEPT;
 }
@@ -117,7 +109,6 @@ static bool icmp_new(struct nf_conn *ct, const struct sk_buff *skb,
                nf_ct_dump_tuple_ip(&ct->tuplehash[0].tuple);
                return false;
        }
-       atomic_set(&ct->proto.icmp.count, 0);
        return true;
 }
 
index cf7a42bf9820d7433631966d4dd88fb7470f2bcb..155c008626c825729e5ac09fa45740e0bd8486c8 100644 (file)
@@ -140,7 +140,7 @@ nf_nat_mangle_tcp_packet(struct sk_buff *skb,
                         const char *rep_buffer,
                         unsigned int rep_len)
 {
-       struct rtable *rt = skb->rtable;
+       struct rtable *rt = skb_rtable(skb);
        struct iphdr *iph;
        struct tcphdr *tcph;
        int oldlen, datalen;
@@ -218,7 +218,7 @@ nf_nat_mangle_udp_packet(struct sk_buff *skb,
                         const char *rep_buffer,
                         unsigned int rep_len)
 {
-       struct rtable *rt = skb->rtable;
+       struct rtable *rt = skb_rtable(skb);
        struct iphdr *iph;
        struct udphdr *udph;
        int datalen, oldlen;
index 65e470bc6123dfcabf0956b8542ffa043f36980c..3fc598eeeb1a57cc8fc76f1c6ed7c1220ce21326 100644 (file)
@@ -33,6 +33,7 @@ sctp_manip_pkt(struct sk_buff *skb,
               enum nf_nat_manip_type maniptype)
 {
        const struct iphdr *iph = (struct iphdr *)(skb->data + iphdroff);
+       struct sk_buff *frag;
        sctp_sctphdr_t *hdr;
        unsigned int hdroff = iphdroff + iph->ihl*4;
        __be32 oldip, newip;
@@ -57,8 +58,8 @@ sctp_manip_pkt(struct sk_buff *skb,
        }
 
        crc32 = sctp_start_cksum((u8 *)hdr, skb_headlen(skb) - hdroff);
-       for (skb = skb_shinfo(skb)->frag_list; skb; skb = skb->next)
-               crc32 = sctp_update_cksum((u8 *)skb->data, skb_headlen(skb),
+       skb_walk_frags(skb, frag)
+               crc32 = sctp_update_cksum((u8 *)frag->data, skb_headlen(frag),
                                          crc32);
        crc32 = sctp_end_cksum(crc32);
        hdr->checksum = crc32;
index b7dd695691a0858bf20bda8b4f756e05f585ab1f..5567bd0d07500d4b4214e21985df499066b9d5d7 100644 (file)
@@ -167,10 +167,9 @@ nf_nat_in(unsigned int hooknum,
 
        ret = nf_nat_fn(hooknum, skb, in, out, okfn);
        if (ret != NF_DROP && ret != NF_STOLEN &&
-           daddr != ip_hdr(skb)->daddr) {
-               dst_release(skb->dst);
-               skb->dst = NULL;
-       }
+           daddr != ip_hdr(skb)->daddr)
+               skb_dst_drop(skb);
+
        return ret;
 }
 
index cf0cdeeb1db0bc32986b752057407643320c63c6..f25542c48b7d938ebdbe77f0f4d6ac1e9f1c17cc 100644 (file)
@@ -90,14 +90,14 @@ static const struct file_operations sockstat_seq_fops = {
 
 /* snmp items */
 static const struct snmp_mib snmp4_ipstats_list[] = {
-       SNMP_MIB_ITEM("InReceives", IPSTATS_MIB_INRECEIVES),
+       SNMP_MIB_ITEM("InReceives", IPSTATS_MIB_INPKTS),
        SNMP_MIB_ITEM("InHdrErrors", IPSTATS_MIB_INHDRERRORS),
        SNMP_MIB_ITEM("InAddrErrors", IPSTATS_MIB_INADDRERRORS),
        SNMP_MIB_ITEM("ForwDatagrams", IPSTATS_MIB_OUTFORWDATAGRAMS),
        SNMP_MIB_ITEM("InUnknownProtos", IPSTATS_MIB_INUNKNOWNPROTOS),
        SNMP_MIB_ITEM("InDiscards", IPSTATS_MIB_INDISCARDS),
        SNMP_MIB_ITEM("InDelivers", IPSTATS_MIB_INDELIVERS),
-       SNMP_MIB_ITEM("OutRequests", IPSTATS_MIB_OUTREQUESTS),
+       SNMP_MIB_ITEM("OutRequests", IPSTATS_MIB_OUTPKTS),
        SNMP_MIB_ITEM("OutDiscards", IPSTATS_MIB_OUTDISCARDS),
        SNMP_MIB_ITEM("OutNoRoutes", IPSTATS_MIB_OUTNOROUTES),
        SNMP_MIB_ITEM("ReasmTimeout", IPSTATS_MIB_REASMTIMEOUT),
@@ -118,6 +118,12 @@ static const struct snmp_mib snmp4_ipextstats_list[] = {
        SNMP_MIB_ITEM("OutMcastPkts", IPSTATS_MIB_OUTMCASTPKTS),
        SNMP_MIB_ITEM("InBcastPkts", IPSTATS_MIB_INBCASTPKTS),
        SNMP_MIB_ITEM("OutBcastPkts", IPSTATS_MIB_OUTBCASTPKTS),
+       SNMP_MIB_ITEM("InOctets", IPSTATS_MIB_INOCTETS),
+       SNMP_MIB_ITEM("OutOctets", IPSTATS_MIB_OUTOCTETS),
+       SNMP_MIB_ITEM("InMcastOctets", IPSTATS_MIB_INMCASTOCTETS),
+       SNMP_MIB_ITEM("OutMcastOctets", IPSTATS_MIB_OUTMCASTOCTETS),
+       SNMP_MIB_ITEM("InBcastOctets", IPSTATS_MIB_INBCASTOCTETS),
+       SNMP_MIB_ITEM("OutBcastOctets", IPSTATS_MIB_OUTBCASTOCTETS),
        SNMP_MIB_SENTINEL
 };
 
index f774651f0a47fb6d9de74b49438d16b0915fa536..3dc9171a272f61e5a174b571a7fcc4213336344e 100644 (file)
@@ -343,7 +343,7 @@ static int raw_send_hdrinc(struct sock *sk, void *from, size_t length,
 
        skb->priority = sk->sk_priority;
        skb->mark = sk->sk_mark;
-       skb->dst = dst_clone(&rt->u.dst);
+       skb_dst_set(skb, dst_clone(&rt->u.dst));
 
        skb_reset_network_header(skb);
        iph = ip_hdr(skb);
index 28205e5bfa9b703a30baed0afe83c24575080574..cd76b3cb70925fc142c50f652adea2eafc5c7eb2 100644 (file)
@@ -131,8 +131,8 @@ static int ip_rt_min_advmss __read_mostly   = 256;
 static int ip_rt_secret_interval __read_mostly = 10 * 60 * HZ;
 static int rt_chain_length_max __read_mostly   = 20;
 
-static void rt_worker_func(struct work_struct *work);
-static DECLARE_DELAYED_WORK(expires_work, rt_worker_func);
+static struct delayed_work expires_work;
+static unsigned long expires_ljiffies;
 
 /*
  *     Interface to generic destination cache.
@@ -787,9 +787,12 @@ static void rt_check_expire(void)
        struct rtable *rth, *aux, **rthp;
        unsigned long samples = 0;
        unsigned long sum = 0, sum2 = 0;
+       unsigned long delta;
        u64 mult;
 
-       mult = ((u64)ip_rt_gc_interval) << rt_hash_log;
+       delta = jiffies - expires_ljiffies;
+       expires_ljiffies = jiffies;
+       mult = ((u64)delta) << rt_hash_log;
        if (ip_rt_gc_timeout > 1)
                do_div(mult, ip_rt_gc_timeout);
        goal = (unsigned int)mult;
@@ -1064,7 +1067,8 @@ work_done:
 out:   return 0;
 }
 
-static int rt_intern_hash(unsigned hash, struct rtable *rt, struct rtable **rp)
+static int rt_intern_hash(unsigned hash, struct rtable *rt,
+                         struct rtable **rp, struct sk_buff *skb)
 {
        struct rtable   *rth, **rthp;
        unsigned long   now;
@@ -1114,7 +1118,10 @@ restart:
                        spin_unlock_bh(rt_hash_lock_addr(hash));
 
                        rt_drop(rt);
-                       *rp = rth;
+                       if (rp)
+                               *rp = rth;
+                       else
+                               skb_dst_set(skb, &rth->u.dst);
                        return 0;
                }
 
@@ -1210,7 +1217,10 @@ restart:
        rcu_assign_pointer(rt_hash_table[hash].chain, rt);
 
        spin_unlock_bh(rt_hash_lock_addr(hash));
-       *rp = rt;
+       if (rp)
+               *rp = rt;
+       else
+               skb_dst_set(skb, &rt->u.dst);
        return 0;
 }
 
@@ -1407,7 +1417,7 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw,
                                                        &netevent);
 
                                rt_del(hash, rth);
-                               if (!rt_intern_hash(hash, rt, &rt))
+                               if (!rt_intern_hash(hash, rt, &rt, NULL))
                                        ip_rt_put(rt);
                                goto do_next;
                        }
@@ -1473,7 +1483,7 @@ static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst)
 
 void ip_rt_send_redirect(struct sk_buff *skb)
 {
-       struct rtable *rt = skb->rtable;
+       struct rtable *rt = skb_rtable(skb);
        struct in_device *in_dev = in_dev_get(rt->u.dst.dev);
 
        if (!in_dev)
@@ -1521,7 +1531,7 @@ out:
 
 static int ip_error(struct sk_buff *skb)
 {
-       struct rtable *rt = skb->rtable;
+       struct rtable *rt = skb_rtable(skb);
        unsigned long now;
        int code;
 
@@ -1698,7 +1708,7 @@ static void ipv4_link_failure(struct sk_buff *skb)
 
        icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0);
 
-       rt = skb->rtable;
+       rt = skb_rtable(skb);
        if (rt)
                dst_set_expires(&rt->u.dst, 0);
 }
@@ -1858,7 +1868,7 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
 
        in_dev_put(in_dev);
        hash = rt_hash(daddr, saddr, dev->ifindex, rt_genid(dev_net(dev)));
-       return rt_intern_hash(hash, rth, &skb->rtable);
+       return rt_intern_hash(hash, rth, NULL, skb);
 
 e_nobufs:
        in_dev_put(in_dev);
@@ -2019,7 +2029,7 @@ static int ip_mkroute_input(struct sk_buff *skb,
        /* put it into the cache */
        hash = rt_hash(daddr, saddr, fl->iif,
                       rt_genid(dev_net(rth->u.dst.dev)));
-       return rt_intern_hash(hash, rth, &skb->rtable);
+       return rt_intern_hash(hash, rth, NULL, skb);
 }
 
 /*
@@ -2175,7 +2185,7 @@ local_input:
        }
        rth->rt_type    = res.type;
        hash = rt_hash(daddr, saddr, fl.iif, rt_genid(net));
-       err = rt_intern_hash(hash, rth, &skb->rtable);
+       err = rt_intern_hash(hash, rth, NULL, skb);
        goto done;
 
 no_route:
@@ -2244,7 +2254,7 @@ int ip_route_input(struct sk_buff *skb, __be32 daddr, __be32 saddr,
                        dst_use(&rth->u.dst, jiffies);
                        RT_CACHE_STAT_INC(in_hit);
                        rcu_read_unlock();
-                       skb->rtable = rth;
+                       skb_dst_set(skb, &rth->u.dst);
                        return 0;
                }
                RT_CACHE_STAT_INC(in_hlist_search);
@@ -2420,7 +2430,7 @@ static int ip_mkroute_output(struct rtable **rp,
        if (err == 0) {
                hash = rt_hash(oldflp->fl4_dst, oldflp->fl4_src, oldflp->oif,
                               rt_genid(dev_net(dev_out)));
-               err = rt_intern_hash(hash, rth, rp);
+               err = rt_intern_hash(hash, rth, rp, NULL);
        }
 
        return err;
@@ -2763,7 +2773,7 @@ static int rt_fill_info(struct net *net,
                        struct sk_buff *skb, u32 pid, u32 seq, int event,
                        int nowait, unsigned int flags)
 {
-       struct rtable *rt = skb->rtable;
+       struct rtable *rt = skb_rtable(skb);
        struct rtmsg *r;
        struct nlmsghdr *nlh;
        long expires;
@@ -2907,7 +2917,7 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void
                err = ip_route_input(skb, dst, src, rtm->rtm_tos, dev);
                local_bh_enable();
 
-               rt = skb->rtable;
+               rt = skb_rtable(skb);
                if (err == 0 && rt->u.dst.error)
                        err = -rt->u.dst.error;
        } else {
@@ -2927,7 +2937,7 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void
        if (err)
                goto errout_free;
 
-       skb->rtable = rt;
+       skb_dst_set(skb, &rt->u.dst);
        if (rtm->rtm_flags & RTM_F_NOTIFY)
                rt->rt_flags |= RTCF_NOTIFY;
 
@@ -2968,15 +2978,15 @@ int ip_rt_dump(struct sk_buff *skb,  struct netlink_callback *cb)
                                continue;
                        if (rt_is_expired(rt))
                                continue;
-                       skb->dst = dst_clone(&rt->u.dst);
+                       skb_dst_set(skb, dst_clone(&rt->u.dst));
                        if (rt_fill_info(net, skb, NETLINK_CB(cb->skb).pid,
                                         cb->nlh->nlmsg_seq, RTM_NEWROUTE,
                                         1, NLM_F_MULTI) <= 0) {
-                               dst_release(xchg(&skb->dst, NULL));
+                               skb_dst_drop(skb);
                                rcu_read_unlock_bh();
                                goto done;
                        }
-                       dst_release(xchg(&skb->dst, NULL));
+                       skb_dst_drop(skb);
                }
                rcu_read_unlock_bh();
        }
@@ -3390,6 +3400,8 @@ int __init ip_rt_init(void)
        /* All the timers, started at system startup tend
           to synchronize. Perturb it a bit.
         */
+       INIT_DELAYED_WORK_DEFERRABLE(&expires_work, rt_worker_func);
+       expires_ljiffies = jiffies;
        schedule_delayed_work(&expires_work,
                net_random() % ip_rt_gc_interval + ip_rt_gc_interval);
 
index b35a950d2e06ee38d89908aae0c725ea29c16aae..cd2b97f1b6e12a46ef57fd967051ca30da0ea00a 100644 (file)
@@ -161,13 +161,12 @@ static __u16 const msstab[] = {
  */
 __u32 cookie_v4_init_sequence(struct sock *sk, struct sk_buff *skb, __u16 *mssp)
 {
-       struct tcp_sock *tp = tcp_sk(sk);
        const struct iphdr *iph = ip_hdr(skb);
        const struct tcphdr *th = tcp_hdr(skb);
        int mssind;
        const __u16 mss = *mssp;
 
-       tp->last_synq_overflow = jiffies;
+       tcp_synq_overflow(sk);
 
        /* XXX sort msstab[] by probability?  Binary search? */
        for (mssind = 0; mss > msstab[mssind + 1]; mssind++)
@@ -268,7 +267,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
        if (!sysctl_tcp_syncookies || !th->ack)
                goto out;
 
-       if (time_after(jiffies, tp->last_synq_overflow + TCP_TIMEOUT_INIT) ||
+       if (tcp_synq_no_recent_overflow(sk) ||
            (mss = cookie_check(skb, cookie)) == 0) {
                NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_SYNCOOKIESFAILED);
                goto out;
index 7a0f0b27bf1f0affc18e57c96b7c002aa5376fcc..17b89c523f9d1ac590dbc575c8d6be7664851cbb 100644 (file)
@@ -439,12 +439,14 @@ int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg)
                         !tp->urg_data ||
                         before(tp->urg_seq, tp->copied_seq) ||
                         !before(tp->urg_seq, tp->rcv_nxt)) {
+                       struct sk_buff *skb;
+
                        answ = tp->rcv_nxt - tp->copied_seq;
 
                        /* Subtract 1, if FIN is in queue. */
-                       if (answ && !skb_queue_empty(&sk->sk_receive_queue))
-                               answ -=
-                      tcp_hdr((struct sk_buff *)sk->sk_receive_queue.prev)->fin;
+                       skb = skb_peek_tail(&sk->sk_receive_queue);
+                       if (answ && skb)
+                               answ -= tcp_hdr(skb)->fin;
                } else
                        answ = tp->urg_seq - tp->copied_seq;
                release_sock(sk);
@@ -1382,11 +1384,7 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
 
                /* Next get a buffer. */
 
-               skb = skb_peek(&sk->sk_receive_queue);
-               do {
-                       if (!skb)
-                               break;
-
+               skb_queue_walk(&sk->sk_receive_queue, skb) {
                        /* Now that we have two receive queues this
                         * shouldn't happen.
                         */
@@ -1403,8 +1401,7 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
                        if (tcp_hdr(skb)->fin)
                                goto found_fin_ok;
                        WARN_ON(!(flags & MSG_PEEK));
-                       skb = skb->next;
-               } while (skb != (struct sk_buff *)&sk->sk_receive_queue);
+               }
 
                /* Well, if we have backlog, try to process it now yet. */
 
@@ -2518,20 +2515,30 @@ struct sk_buff **tcp_gro_receive(struct sk_buff **head, struct sk_buff *skb)
        unsigned int thlen;
        unsigned int flags;
        unsigned int mss = 1;
+       unsigned int hlen;
+       unsigned int off;
        int flush = 1;
        int i;
 
-       th = skb_gro_header(skb, sizeof(*th));
-       if (unlikely(!th))
-               goto out;
+       off = skb_gro_offset(skb);
+       hlen = off + sizeof(*th);
+       th = skb_gro_header_fast(skb, off);
+       if (skb_gro_header_hard(skb, hlen)) {
+               th = skb_gro_header_slow(skb, hlen, off);
+               if (unlikely(!th))
+                       goto out;
+       }
 
        thlen = th->doff * 4;
        if (thlen < sizeof(*th))
                goto out;
 
-       th = skb_gro_header(skb, thlen);
-       if (unlikely(!th))
-               goto out;
+       hlen = off + thlen;
+       if (skb_gro_header_hard(skb, hlen)) {
+               th = skb_gro_header_slow(skb, hlen, off);
+               if (unlikely(!th))
+                       goto out;
+       }
 
        skb_gro_pull(skb, thlen);
 
@@ -2544,7 +2551,7 @@ struct sk_buff **tcp_gro_receive(struct sk_buff **head, struct sk_buff *skb)
 
                th2 = tcp_hdr(p);
 
-               if ((th->source ^ th2->source) | (th->dest ^ th2->dest)) {
+               if (*(u32 *)&th->source ^ *(u32 *)&th2->source) {
                        NAPI_GRO_CB(p)->same_flow = 0;
                        continue;
                }
@@ -2559,14 +2566,14 @@ found:
        flush |= flags & TCP_FLAG_CWR;
        flush |= (flags ^ tcp_flag_word(th2)) &
                  ~(TCP_FLAG_CWR | TCP_FLAG_FIN | TCP_FLAG_PSH);
-       flush |= (th->ack_seq ^ th2->ack_seq) | (th->window ^ th2->window);
-       for (i = sizeof(*th); !flush && i < thlen; i += 4)
+       flush |= th->ack_seq ^ th2->ack_seq;
+       for (i = sizeof(*th); i < thlen; i += 4)
                flush |= *(u32 *)((u8 *)th + i) ^
                         *(u32 *)((u8 *)th2 + i);
 
        mss = skb_shinfo(p)->gso_size;
 
-       flush |= (len > mss) | !len;
+       flush |= (len - 1) >= mss;
        flush |= (ntohl(th2->seq) + skb_gro_len(p)) ^ ntohl(th->seq);
 
        if (flush || skb_gro_receive(head, skb)) {
index eec3e6f9956cad798b6cc930cf7b799a64fca911..2bdb0da237e69f52f411dd8bcd87219a9b1c14e9 100644 (file)
@@ -77,7 +77,7 @@ int sysctl_tcp_window_scaling __read_mostly = 1;
 int sysctl_tcp_sack __read_mostly = 1;
 int sysctl_tcp_fack __read_mostly = 1;
 int sysctl_tcp_reordering __read_mostly = TCP_FASTRETRANS_THRESH;
-int sysctl_tcp_ecn __read_mostly;
+int sysctl_tcp_ecn __read_mostly = 2;
 int sysctl_tcp_dsack __read_mostly = 1;
 int sysctl_tcp_app_win __read_mostly = 31;
 int sysctl_tcp_adv_win_scale __read_mostly = 2;
@@ -4426,7 +4426,7 @@ drop:
                }
                __skb_queue_head(&tp->out_of_order_queue, skb);
        } else {
-               struct sk_buff *skb1 = tp->out_of_order_queue.prev;
+               struct sk_buff *skb1 = skb_peek_tail(&tp->out_of_order_queue);
                u32 seq = TCP_SKB_CB(skb)->seq;
                u32 end_seq = TCP_SKB_CB(skb)->end_seq;
 
@@ -4443,15 +4443,18 @@ drop:
                }
 
                /* Find place to insert this segment. */
-               do {
+               while (1) {
                        if (!after(TCP_SKB_CB(skb1)->seq, seq))
                                break;
-               } while ((skb1 = skb1->prev) !=
-                        (struct sk_buff *)&tp->out_of_order_queue);
+                       if (skb_queue_is_first(&tp->out_of_order_queue, skb1)) {
+                               skb1 = NULL;
+                               break;
+                       }
+                       skb1 = skb_queue_prev(&tp->out_of_order_queue, skb1);
+               }
 
                /* Do skb overlap to previous one? */
-               if (skb1 != (struct sk_buff *)&tp->out_of_order_queue &&
-                   before(seq, TCP_SKB_CB(skb1)->end_seq)) {
+               if (skb1 && before(seq, TCP_SKB_CB(skb1)->end_seq)) {
                        if (!after(end_seq, TCP_SKB_CB(skb1)->end_seq)) {
                                /* All the bits are present. Drop. */
                                __kfree_skb(skb);
@@ -4463,15 +4466,26 @@ drop:
                                tcp_dsack_set(sk, seq,
                                              TCP_SKB_CB(skb1)->end_seq);
                        } else {
-                               skb1 = skb1->prev;
+                               if (skb_queue_is_first(&tp->out_of_order_queue,
+                                                      skb1))
+                                       skb1 = NULL;
+                               else
+                                       skb1 = skb_queue_prev(
+                                               &tp->out_of_order_queue,
+                                               skb1);
                        }
                }
-               __skb_queue_after(&tp->out_of_order_queue, skb1, skb);
+               if (!skb1)
+                       __skb_queue_head(&tp->out_of_order_queue, skb);
+               else
+                       __skb_queue_after(&tp->out_of_order_queue, skb1, skb);
 
                /* And clean segments covered by new one as whole. */
-               while ((skb1 = skb->next) !=
-                      (struct sk_buff *)&tp->out_of_order_queue &&
-                      after(end_seq, TCP_SKB_CB(skb1)->seq)) {
+               while (!skb_queue_is_last(&tp->out_of_order_queue, skb)) {
+                       skb1 = skb_queue_next(&tp->out_of_order_queue, skb);
+
+                       if (!after(end_seq, TCP_SKB_CB(skb1)->seq))
+                               break;
                        if (before(end_seq, TCP_SKB_CB(skb1)->end_seq)) {
                                tcp_dsack_extend(sk, TCP_SKB_CB(skb1)->seq,
                                                 end_seq);
@@ -4492,7 +4506,10 @@ add_sack:
 static struct sk_buff *tcp_collapse_one(struct sock *sk, struct sk_buff *skb,
                                        struct sk_buff_head *list)
 {
-       struct sk_buff *next = skb->next;
+       struct sk_buff *next = NULL;
+
+       if (!skb_queue_is_last(list, skb))
+               next = skb_queue_next(list, skb);
 
        __skb_unlink(skb, list);
        __kfree_skb(skb);
@@ -4503,6 +4520,9 @@ static struct sk_buff *tcp_collapse_one(struct sock *sk, struct sk_buff *skb,
 
 /* Collapse contiguous sequence of skbs head..tail with
  * sequence numbers start..end.
+ *
+ * If tail is NULL, this means until the end of the list.
+ *
  * Segments with FIN/SYN are not collapsed (only because this
  * simplifies code)
  */
@@ -4511,15 +4531,23 @@ tcp_collapse(struct sock *sk, struct sk_buff_head *list,
             struct sk_buff *head, struct sk_buff *tail,
             u32 start, u32 end)
 {
-       struct sk_buff *skb;
+       struct sk_buff *skb, *n;
+       bool end_of_skbs;
 
        /* First, check that queue is collapsible and find
         * the point where collapsing can be useful. */
-       for (skb = head; skb != tail;) {
+       skb = head;
+restart:
+       end_of_skbs = true;
+       skb_queue_walk_from_safe(list, skb, n) {
+               if (skb == tail)
+                       break;
                /* No new bits? It is possible on ofo queue. */
                if (!before(start, TCP_SKB_CB(skb)->end_seq)) {
                        skb = tcp_collapse_one(sk, skb, list);
-                       continue;
+                       if (!skb)
+                               break;
+                       goto restart;
                }
 
                /* The first skb to collapse is:
@@ -4529,16 +4557,24 @@ tcp_collapse(struct sock *sk, struct sk_buff_head *list,
                 */
                if (!tcp_hdr(skb)->syn && !tcp_hdr(skb)->fin &&
                    (tcp_win_from_space(skb->truesize) > skb->len ||
-                    before(TCP_SKB_CB(skb)->seq, start) ||
-                    (skb->next != tail &&
-                     TCP_SKB_CB(skb)->end_seq != TCP_SKB_CB(skb->next)->seq)))
+                    before(TCP_SKB_CB(skb)->seq, start))) {
+                       end_of_skbs = false;
                        break;
+               }
+
+               if (!skb_queue_is_last(list, skb)) {
+                       struct sk_buff *next = skb_queue_next(list, skb);
+                       if (next != tail &&
+                           TCP_SKB_CB(skb)->end_seq != TCP_SKB_CB(next)->seq) {
+                               end_of_skbs = false;
+                               break;
+                       }
+               }
 
                /* Decided to skip this, advance start seq. */
                start = TCP_SKB_CB(skb)->end_seq;
-               skb = skb->next;
        }
-       if (skb == tail || tcp_hdr(skb)->syn || tcp_hdr(skb)->fin)
+       if (end_of_skbs || tcp_hdr(skb)->syn || tcp_hdr(skb)->fin)
                return;
 
        while (before(start, end)) {
@@ -4583,7 +4619,8 @@ tcp_collapse(struct sock *sk, struct sk_buff_head *list,
                        }
                        if (!before(start, TCP_SKB_CB(skb)->end_seq)) {
                                skb = tcp_collapse_one(sk, skb, list);
-                               if (skb == tail ||
+                               if (!skb ||
+                                   skb == tail ||
                                    tcp_hdr(skb)->syn ||
                                    tcp_hdr(skb)->fin)
                                        return;
@@ -4610,17 +4647,21 @@ static void tcp_collapse_ofo_queue(struct sock *sk)
        head = skb;
 
        for (;;) {
-               skb = skb->next;
+               struct sk_buff *next = NULL;
+
+               if (!skb_queue_is_last(&tp->out_of_order_queue, skb))
+                       next = skb_queue_next(&tp->out_of_order_queue, skb);
+               skb = next;
 
                /* Segment is terminated when we see gap or when
                 * we are at the end of all the queue. */
-               if (skb == (struct sk_buff *)&tp->out_of_order_queue ||
+               if (!skb ||
                    after(TCP_SKB_CB(skb)->seq, end) ||
                    before(TCP_SKB_CB(skb)->end_seq, start)) {
                        tcp_collapse(sk, &tp->out_of_order_queue,
                                     head, skb, start, end);
                        head = skb;
-                       if (skb == (struct sk_buff *)&tp->out_of_order_queue)
+                       if (!skb)
                                break;
                        /* Start new segment */
                        start = TCP_SKB_CB(skb)->seq;
@@ -4681,10 +4722,11 @@ static int tcp_prune_queue(struct sock *sk)
                tp->rcv_ssthresh = min(tp->rcv_ssthresh, 4U * tp->advmss);
 
        tcp_collapse_ofo_queue(sk);
-       tcp_collapse(sk, &sk->sk_receive_queue,
-                    sk->sk_receive_queue.next,
-                    (struct sk_buff *)&sk->sk_receive_queue,
-                    tp->copied_seq, tp->rcv_nxt);
+       if (!skb_queue_empty(&sk->sk_receive_queue))
+               tcp_collapse(sk, &sk->sk_receive_queue,
+                            skb_peek(&sk->sk_receive_queue),
+                            NULL,
+                            tp->copied_seq, tp->rcv_nxt);
        sk_mem_reclaim(sk);
 
        if (atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf)
index 5d427f86b4142115cbc6c02222b8bbd0b34f9506..5a1ca2698c885775914f05fe17ae45d485cbddd2 100644 (file)
@@ -546,7 +546,7 @@ static void tcp_v4_send_reset(struct sock *sk, struct sk_buff *skb)
        if (th->rst)
                return;
 
-       if (skb->rtable->rt_type != RTN_LOCAL)
+       if (skb_rtable(skb)->rt_type != RTN_LOCAL)
                return;
 
        /* Swap the send and the receive. */
@@ -590,7 +590,7 @@ static void tcp_v4_send_reset(struct sock *sk, struct sk_buff *skb)
        arg.csumoffset = offsetof(struct tcphdr, check) / 2;
        arg.flags = (sk && inet_sk(sk)->transparent) ? IP_REPLY_ARG_NOSRCCHECK : 0;
 
-       net = dev_net(skb->dst->dev);
+       net = dev_net(skb_dst(skb)->dev);
        ip_send_reply(net->ipv4.tcp_sock, skb,
                      &arg, arg.iov[0].iov_len);
 
@@ -617,7 +617,7 @@ static void tcp_v4_send_ack(struct sk_buff *skb, u32 seq, u32 ack,
                        ];
        } rep;
        struct ip_reply_arg arg;
-       struct net *net = dev_net(skb->dst->dev);
+       struct net *net = dev_net(skb_dst(skb)->dev);
 
        memset(&rep.th, 0, sizeof(struct tcphdr));
        memset(&arg, 0, sizeof(arg));
@@ -1185,7 +1185,7 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
 #endif
 
        /* Never answer to SYNs send to broadcast or multicast */
-       if (skb->rtable->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST))
+       if (skb_rtable(skb)->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST))
                goto drop;
 
        /* TW buckets are converted to open requests without
@@ -1593,7 +1593,7 @@ process:
 #endif
                {
                        if (!tcp_prequeue(sk, skb))
-                       ret = tcp_v4_do_rcv(sk, skb);
+                               ret = tcp_v4_do_rcv(sk, skb);
                }
        } else
                sk_add_backlog(sk, skb);
@@ -2343,7 +2343,7 @@ void tcp4_proc_exit(void)
 
 struct sk_buff **tcp4_gro_receive(struct sk_buff **head, struct sk_buff *skb)
 {
-       struct iphdr *iph = ip_hdr(skb);
+       struct iphdr *iph = skb_gro_network_header(skb);
 
        switch (skb->ip_summed) {
        case CHECKSUM_COMPLETE:
index 59aec609cec6c6c7d8a721366c9c74fb427937df..416fc4c2e7ebdc7367959407ef99c386d6428c20 100644 (file)
@@ -288,7 +288,7 @@ static inline void TCP_ECN_send_syn(struct sock *sk, struct sk_buff *skb)
        struct tcp_sock *tp = tcp_sk(sk);
 
        tp->ecn_flags = 0;
-       if (sysctl_tcp_ecn) {
+       if (sysctl_tcp_ecn == 1) {
                TCP_SKB_CB(skb)->flags |= TCPCB_FLAG_ECE | TCPCB_FLAG_CWR;
                tp->ecn_flags = TCP_ECN_OK;
        }
@@ -2202,7 +2202,7 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst,
        /* Reserve space for headers. */
        skb_reserve(skb, MAX_TCP_HEADER);
 
-       skb->dst = dst_clone(dst);
+       skb_dst_set(skb, dst_clone(dst));
 
        mss = dst_metric(dst, RTAX_ADVMSS);
        if (tp->rx_opt.user_mss && tp->rx_opt.user_mss < mss)
index 7a1d1ce22e66972f8d42d2d080d848906784b00a..8f4158d7c9a65ffcc02cf28a0abf3c10cc20cc07 100644 (file)
@@ -328,7 +328,7 @@ static inline struct sock *__udp4_lib_lookup_skb(struct sk_buff *skb,
        if (unlikely(sk = skb_steal_sock(skb)))
                return sk;
        else
-               return __udp4_lib_lookup(dev_net(skb->dst->dev), iph->saddr, sport,
+               return __udp4_lib_lookup(dev_net(skb_dst(skb)->dev), iph->saddr, sport,
                                         iph->daddr, dport, inet_iif(skb),
                                         udptable);
 }
@@ -1237,7 +1237,7 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
        struct sock *sk;
        struct udphdr *uh;
        unsigned short ulen;
-       struct rtable *rt = (struct rtable*)skb->dst;
+       struct rtable *rt = skb_rtable(skb);
        __be32 saddr, daddr;
        struct net *net = dev_net(skb->dev);
 
index 4ec2162a437ecc1faca91a862486e53422ab8cb2..f9f922a0ba88754d86d920b8417b4098d47d082a 100644 (file)
@@ -23,7 +23,7 @@ int xfrm4_extract_input(struct xfrm_state *x, struct sk_buff *skb)
 
 static inline int xfrm4_rcv_encap_finish(struct sk_buff *skb)
 {
-       if (skb->dst == NULL) {
+       if (skb_dst(skb) == NULL) {
                const struct iphdr *iph = ip_hdr(skb);
 
                if (ip_route_input(skb, iph->daddr, iph->saddr, iph->tos,
index 7135279f3f8480d20e07120f5b34740811f71a36..3444f3b34ecae4cb964f0fa84b1627bed1573b06 100644 (file)
@@ -28,7 +28,7 @@ static inline void ipip_ecn_decapsulate(struct sk_buff *skb)
  */
 static int xfrm4_mode_tunnel_output(struct xfrm_state *x, struct sk_buff *skb)
 {
-       struct dst_entry *dst = skb->dst;
+       struct dst_entry *dst = skb_dst(skb);
        struct iphdr *top_iph;
        int flags;
 
@@ -41,7 +41,7 @@ static int xfrm4_mode_tunnel_output(struct xfrm_state *x, struct sk_buff *skb)
        top_iph->ihl = 5;
        top_iph->version = 4;
 
-       top_iph->protocol = xfrm_af2proto(skb->dst->ops->family);
+       top_iph->protocol = xfrm_af2proto(skb_dst(skb)->ops->family);
 
        /* DS disclosed */
        top_iph->tos = INET_ECN_encapsulate(XFRM_MODE_SKB_CB(skb)->tos,
index 8c3180adddbf12e2955a9c7a47ccd374b35b790c..c908bd99bcbae11e2f0c18b37363f8382d6a3544 100644 (file)
@@ -29,7 +29,7 @@ static int xfrm4_tunnel_check_size(struct sk_buff *skb)
        if (!(ip_hdr(skb)->frag_off & htons(IP_DF)) || skb->local_df)
                goto out;
 
-       dst = skb->dst;
+       dst = skb_dst(skb);
        mtu = dst_mtu(dst);
        if (skb->len > mtu) {
                icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu));
@@ -72,7 +72,7 @@ EXPORT_SYMBOL(xfrm4_prepare_output);
 static int xfrm4_output_finish(struct sk_buff *skb)
 {
 #ifdef CONFIG_NETFILTER
-       if (!skb->dst->xfrm) {
+       if (!skb_dst(skb)->xfrm) {
                IPCB(skb)->flags |= IPSKB_REROUTED;
                return dst_output(skb);
        }
@@ -87,6 +87,6 @@ static int xfrm4_output_finish(struct sk_buff *skb)
 int xfrm4_output(struct sk_buff *skb)
 {
        return NF_HOOK_COND(PF_INET, NF_INET_POST_ROUTING, skb,
-                           NULL, skb->dst->dev, xfrm4_output_finish,
+                           NULL, skb_dst(skb)->dev, xfrm4_output_finish,
                            !(IPCB(skb)->flags & IPSKB_REROUTED));
 }
index 597487ae6ce8fbe7a0d34ae5eb4a169d30506d19..8c1e86afbbf5208c4eeadee48ce407dbf3b0016f 100644 (file)
@@ -503,7 +503,7 @@ static int addrconf_fixup_forwarding(struct ctl_table *table, int *p, int old)
                return 0;
 
        if (!rtnl_trylock())
-               return -ERESTARTSYS;
+               return restart_syscall();
 
        if (p == &net->ipv6.devconf_all->forwarding) {
                __s32 newf = net->ipv6.devconf_all->forwarding;
@@ -591,7 +591,6 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, int pfxlen,
 {
        struct inet6_ifaddr *ifa = NULL;
        struct rt6_info *rt;
-       struct net *net = dev_net(idev->dev);
        int hash;
        int err = 0;
        int addr_type = ipv6_addr_type(addr);
@@ -608,7 +607,7 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, int pfxlen,
                goto out2;
        }
 
-       if (idev->cnf.disable_ipv6 || net->ipv6.devconf_all->disable_ipv6) {
+       if (idev->cnf.disable_ipv6) {
                err = -EACCES;
                goto out2;
        }
@@ -1520,6 +1519,8 @@ static int addrconf_ifid_infiniband(u8 *eui, struct net_device *dev)
 
 int __ipv6_isatap_ifid(u8 *eui, __be32 addr)
 {
+       if (addr == 0)
+               return -1;
        eui[0] = (ipv4_is_zeronet(addr) || ipv4_is_private_10(addr) ||
                  ipv4_is_loopback(addr) || ipv4_is_linklocal_169(addr) ||
                  ipv4_is_private_172(addr) || ipv4_is_test_192(addr) ||
@@ -1750,6 +1751,7 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len)
        __u32 prefered_lft;
        int addr_type;
        struct inet6_dev *in6_dev;
+       struct net *net = dev_net(dev);
 
        pinfo = (struct prefix_info *) opt;
 
@@ -1807,7 +1809,7 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len)
                if (addrconf_finite_timeout(rt_expires))
                        rt_expires *= HZ;
 
-               rt = rt6_lookup(dev_net(dev), &pinfo->prefix, NULL,
+               rt = rt6_lookup(net, &pinfo->prefix, NULL,
                                dev->ifindex, 1);
 
                if (rt && addrconf_is_prefix_route(rt)) {
@@ -1844,7 +1846,6 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len)
                struct inet6_ifaddr * ifp;
                struct in6_addr addr;
                int create = 0, update_lft = 0;
-               struct net *net = dev_net(dev);
 
                if (pinfo->prefix_len == 64) {
                        memcpy(&addr, &pinfo->prefix, 8);
@@ -3986,6 +3987,75 @@ static int addrconf_sysctl_forward_strategy(ctl_table *table,
        return addrconf_fixup_forwarding(table, valp, val);
 }
 
+static void dev_disable_change(struct inet6_dev *idev)
+{
+       if (!idev || !idev->dev)
+               return;
+
+       if (idev->cnf.disable_ipv6)
+               addrconf_notify(NULL, NETDEV_DOWN, idev->dev);
+       else
+               addrconf_notify(NULL, NETDEV_UP, idev->dev);
+}
+
+static void addrconf_disable_change(struct net *net, __s32 newf)
+{
+       struct net_device *dev;
+       struct inet6_dev *idev;
+
+       read_lock(&dev_base_lock);
+       for_each_netdev(net, dev) {
+               rcu_read_lock();
+               idev = __in6_dev_get(dev);
+               if (idev) {
+                       int changed = (!idev->cnf.disable_ipv6) ^ (!newf);
+                       idev->cnf.disable_ipv6 = newf;
+                       if (changed)
+                               dev_disable_change(idev);
+               }
+               rcu_read_unlock();
+       }
+       read_unlock(&dev_base_lock);
+}
+
+static int addrconf_disable_ipv6(struct ctl_table *table, int *p, int old)
+{
+       struct net *net;
+
+       net = (struct net *)table->extra2;
+
+       if (p == &net->ipv6.devconf_dflt->disable_ipv6)
+               return 0;
+
+       if (!rtnl_trylock())
+               return restart_syscall();
+
+       if (p == &net->ipv6.devconf_all->disable_ipv6) {
+               __s32 newf = net->ipv6.devconf_all->disable_ipv6;
+               net->ipv6.devconf_dflt->disable_ipv6 = newf;
+               addrconf_disable_change(net, newf);
+       } else if ((!*p) ^ (!old))
+               dev_disable_change((struct inet6_dev *)table->extra1);
+
+       rtnl_unlock();
+       return 0;
+}
+
+static
+int addrconf_sysctl_disable(ctl_table *ctl, int write, struct file * filp,
+                           void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+       int *valp = ctl->data;
+       int val = *valp;
+       int ret;
+
+       ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
+
+       if (write)
+               ret = addrconf_disable_ipv6(ctl, valp, val);
+       return ret;
+}
+
 static struct addrconf_sysctl_table
 {
        struct ctl_table_header *sysctl_header;
@@ -4223,7 +4293,8 @@ static struct addrconf_sysctl_table
                        .data           =       &ipv6_devconf.disable_ipv6,
                        .maxlen         =       sizeof(int),
                        .mode           =       0644,
-                       .proc_handler   =       proc_dointvec,
+                       .proc_handler   =       addrconf_sysctl_disable,
+                       .strategy       =       sysctl_intvec,
                },
                {
                        .ctl_name       =       CTL_UNNUMBERED,
@@ -4344,6 +4415,10 @@ static int addrconf_init_net(struct net *net)
                dflt = kmemdup(dflt, sizeof(ipv6_devconf_dflt), GFP_KERNEL);
                if (dflt == NULL)
                        goto err_alloc_dflt;
+       } else {
+               /* these will be inherited by all namespaces */
+               dflt->autoconf = ipv6_defaults.autoconf;
+               dflt->disable_ipv6 = ipv6_defaults.disable_ipv6;
        }
 
        net->ipv6.devconf_all = all;
index 61f55386a236cb7c0ba52f831ebd02a6656c10d7..85b3d0036afdeff08efc32d1179dbabf7a58f9b3 100644 (file)
@@ -72,9 +72,21 @@ MODULE_LICENSE("GPL");
 static struct list_head inetsw6[SOCK_MAX];
 static DEFINE_SPINLOCK(inetsw6_lock);
 
-static int disable_ipv6 = 0;
-module_param_named(disable, disable_ipv6, int, 0);
-MODULE_PARM_DESC(disable, "Disable IPv6 such that it is non-functional");
+struct ipv6_params ipv6_defaults = {
+       .disable_ipv6 = 0,
+       .autoconf = 1,
+};
+
+static int disable_ipv6_mod = 0;
+
+module_param_named(disable, disable_ipv6_mod, int, 0444);
+MODULE_PARM_DESC(disable, "Disable IPv6 module such that it is non-functional");
+
+module_param_named(disable_ipv6, ipv6_defaults.disable_ipv6, int, 0444);
+MODULE_PARM_DESC(disable_ipv6, "Disable IPv6 on all interfaces");
+
+module_param_named(autoconf, ipv6_defaults.autoconf, int, 0444);
+MODULE_PARM_DESC(autoconf, "Enable IPv6 address autoconfiguration on all interfaces");
 
 static __inline__ struct ipv6_pinfo *inet6_sk_generic(struct sock *sk)
 {
@@ -817,13 +829,20 @@ static struct sk_buff **ipv6_gro_receive(struct sk_buff **head,
        struct sk_buff *p;
        struct ipv6hdr *iph;
        unsigned int nlen;
+       unsigned int hlen;
+       unsigned int off;
        int flush = 1;
        int proto;
        __wsum csum;
 
-       iph = skb_gro_header(skb, sizeof(*iph));
-       if (unlikely(!iph))
-               goto out;
+       off = skb_gro_offset(skb);
+       hlen = off + sizeof(*iph);
+       iph = skb_gro_header_fast(skb, off);
+       if (skb_gro_header_hard(skb, hlen)) {
+               iph = skb_gro_header_slow(skb, hlen, off);
+               if (unlikely(!iph))
+                       goto out;
+       }
 
        skb_gro_pull(skb, sizeof(*iph));
        skb_set_transport_header(skb, skb_gro_offset(skb));
@@ -1031,7 +1050,7 @@ static int __init inet6_init(void)
        for(r = &inetsw6[0]; r < &inetsw6[SOCK_MAX]; ++r)
                INIT_LIST_HEAD(r);
 
-       if (disable_ipv6) {
+       if (disable_ipv6_mod) {
                printk(KERN_INFO
                       "IPv6: Loaded, but administratively disabled, "
                       "reboot required to enable\n");
@@ -1220,7 +1239,7 @@ module_init(inet6_init);
 
 static void __exit inet6_exit(void)
 {
-       if (disable_ipv6)
+       if (disable_ipv6_mod)
                return;
 
        /* First of all disallow new sockets creation. */
index 1c7f400a3cfe5d58e95233de5a785b293d2fbeae..4aae658e55016999c25640c41d2624eb49884903 100644 (file)
@@ -277,7 +277,7 @@ static int ipv6_destopt_rcv(struct sk_buff *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->dev), ip6_dst_idev(skb->dst),
+               IP6_INC_STATS_BH(dev_net(skb_dst(skb)->dev), ip6_dst_idev(skb_dst(skb)),
                                 IPSTATS_MIB_INHDRERRORS);
                kfree_skb(skb);
                return -1;
@@ -288,7 +288,7 @@ static int ipv6_destopt_rcv(struct sk_buff *skb)
        dstbuf = opt->dst1;
 #endif
 
-       dst = dst_clone(skb->dst);
+       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;
@@ -333,7 +333,7 @@ static int ipv6_rthdr_rcv(struct sk_buff *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(net, ip6_dst_idev(skb->dst),
+               IP6_INC_STATS_BH(net, ip6_dst_idev(skb_dst(skb)),
                                 IPSTATS_MIB_INHDRERRORS);
                kfree_skb(skb);
                return -1;
@@ -343,7 +343,7 @@ static int ipv6_rthdr_rcv(struct sk_buff *skb)
 
        if (ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr) ||
            skb->pkt_type != PACKET_HOST) {
-               IP6_INC_STATS_BH(net, ip6_dst_idev(skb->dst),
+               IP6_INC_STATS_BH(net, ip6_dst_idev(skb_dst(skb)),
                                 IPSTATS_MIB_INADDRERRORS);
                kfree_skb(skb);
                return -1;
@@ -358,7 +358,7 @@ looped_back:
                         * processed by own
                         */
                        if (!addr) {
-                               IP6_INC_STATS_BH(net, ip6_dst_idev(skb->dst),
+                               IP6_INC_STATS_BH(net, ip6_dst_idev(skb_dst(skb)),
                                                 IPSTATS_MIB_INADDRERRORS);
                                kfree_skb(skb);
                                return -1;
@@ -384,7 +384,7 @@ looped_back:
                        goto unknown_rh;
                /* Silently discard invalid RTH type 2 */
                if (hdr->hdrlen != 2 || hdr->segments_left != 1) {
-                       IP6_INC_STATS_BH(net, ip6_dst_idev(skb->dst),
+                       IP6_INC_STATS_BH(net, ip6_dst_idev(skb_dst(skb)),
                                         IPSTATS_MIB_INHDRERRORS);
                        kfree_skb(skb);
                        return -1;
@@ -403,7 +403,7 @@ looped_back:
        n = hdr->hdrlen >> 1;
 
        if (hdr->segments_left > n) {
-               IP6_INC_STATS_BH(net, ip6_dst_idev(skb->dst),
+               IP6_INC_STATS_BH(net, ip6_dst_idev(skb_dst(skb)),
                                 IPSTATS_MIB_INHDRERRORS);
                icmpv6_param_prob(skb, ICMPV6_HDR_FIELD,
                                  ((&hdr->segments_left) -
@@ -417,7 +417,7 @@ looped_back:
        if (skb_cloned(skb)) {
                /* the copy is a forwarded packet */
                if (pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) {
-                       IP6_INC_STATS_BH(net, ip6_dst_idev(skb->dst),
+                       IP6_INC_STATS_BH(net, ip6_dst_idev(skb_dst(skb)),
                                         IPSTATS_MIB_OUTDISCARDS);
                        kfree_skb(skb);
                        return -1;
@@ -440,13 +440,13 @@ looped_back:
                if (xfrm6_input_addr(skb, (xfrm_address_t *)addr,
                                     (xfrm_address_t *)&ipv6_hdr(skb)->saddr,
                                     IPPROTO_ROUTING) < 0) {
-                       IP6_INC_STATS_BH(net, ip6_dst_idev(skb->dst),
+                       IP6_INC_STATS_BH(net, ip6_dst_idev(skb_dst(skb)),
                                         IPSTATS_MIB_INADDRERRORS);
                        kfree_skb(skb);
                        return -1;
                }
-               if (!ipv6_chk_home_addr(dev_net(skb->dst->dev), addr)) {
-                       IP6_INC_STATS_BH(net, ip6_dst_idev(skb->dst),
+               if (!ipv6_chk_home_addr(dev_net(skb_dst(skb)->dev), addr)) {
+                       IP6_INC_STATS_BH(net, ip6_dst_idev(skb_dst(skb)),
                                         IPSTATS_MIB_INADDRERRORS);
                        kfree_skb(skb);
                        return -1;
@@ -458,7 +458,7 @@ looped_back:
        }
 
        if (ipv6_addr_is_multicast(addr)) {
-               IP6_INC_STATS_BH(net, ip6_dst_idev(skb->dst),
+               IP6_INC_STATS_BH(net, ip6_dst_idev(skb_dst(skb)),
                                 IPSTATS_MIB_INADDRERRORS);
                kfree_skb(skb);
                return -1;
@@ -468,17 +468,17 @@ looped_back:
        ipv6_addr_copy(addr, &ipv6_hdr(skb)->daddr);
        ipv6_addr_copy(&ipv6_hdr(skb)->daddr, &daddr);
 
-       dst_release(xchg(&skb->dst, NULL));
+       skb_dst_drop(skb);
        ip6_route_input(skb);
-       if (skb->dst->error) {
+       if (skb_dst(skb)->error) {
                skb_push(skb, skb->data - skb_network_header(skb));
                dst_input(skb);
                return -1;
        }
 
-       if (skb->dst->dev->flags&IFF_LOOPBACK) {
+       if (skb_dst(skb)->dev->flags&IFF_LOOPBACK) {
                if (ipv6_hdr(skb)->hop_limit <= 1) {
-                       IP6_INC_STATS_BH(net, ip6_dst_idev(skb->dst),
+                       IP6_INC_STATS_BH(net, ip6_dst_idev(skb_dst(skb)),
                                         IPSTATS_MIB_INHDRERRORS);
                        icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT,
                                    0, skb->dev);
@@ -494,7 +494,7 @@ looped_back:
        return -1;
 
 unknown_rh:
-       IP6_INC_STATS_BH(net, ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS);
+       IP6_INC_STATS_BH(net, ip6_dst_idev(skb_dst(skb)), IPSTATS_MIB_INHDRERRORS);
        icmpv6_param_prob(skb, ICMPV6_HDR_FIELD,
                          (&hdr->type) - skb_network_header(skb));
        return -1;
@@ -552,11 +552,11 @@ void ipv6_exthdrs_exit(void)
  **********************************/
 
 /*
- * Note: we cannot rely on skb->dst before we assign it in ip6_route_input().
+ * Note: we cannot rely on skb_dst(skb) before we assign it in ip6_route_input().
  */
 static inline struct inet6_dev *ipv6_skb_idev(struct sk_buff *skb)
 {
-       return skb->dst ? ip6_dst_idev(skb->dst) : __in6_dev_get(skb->dev);
+       return skb_dst(skb) ? ip6_dst_idev(skb_dst(skb)) : __in6_dev_get(skb->dev);
 }
 
 /* Router Alert as of RFC 2711 */
@@ -581,7 +581,7 @@ static int ipv6_hop_jumbo(struct sk_buff *skb, int optoff)
 {
        const unsigned char *nh = skb_network_header(skb);
        u32 pkt_len;
-       struct net *net = dev_net(skb->dst->dev);
+       struct net *net = dev_net(skb_dst(skb)->dev);
 
        if (nh[optoff + 1] != 4 || (optoff & 3) != 2) {
                LIMIT_NETDEBUG(KERN_DEBUG "ipv6_hop_jumbo: wrong jumbo opt length/alignment %d\n",
index f5de3f9dc692164edaf36f7bc0e0dcb0387dbb6f..00a7a5e4ac975a7176d9d3100ea938744865af6b 100644 (file)
@@ -151,7 +151,7 @@ static const struct nla_policy fib6_rule_policy[FRA_MAX+1] = {
 };
 
 static int fib6_rule_configure(struct fib_rule *rule, struct sk_buff *skb,
-                              struct nlmsghdr *nlh, struct fib_rule_hdr *frh,
+                              struct fib_rule_hdr *frh,
                               struct nlattr **tb)
 {
        int err = -EINVAL;
@@ -211,7 +211,7 @@ static int fib6_rule_compare(struct fib_rule *rule, struct fib_rule_hdr *frh,
 }
 
 static int fib6_rule_fill(struct fib_rule *rule, struct sk_buff *skb,
-                         struct nlmsghdr *nlh, struct fib_rule_hdr *frh)
+                         struct fib_rule_hdr *frh)
 {
        struct fib6_rule *rule6 = (struct fib6_rule *) rule;
 
index 3c3732d50c1a167bf362319778562b495d4afdb1..cc4797dd8325f7dd3f33a40957105321c0d3d324 100644 (file)
@@ -228,7 +228,7 @@ int inet6_csk_xmit(struct sk_buff *skb, int ipfragok)
                __inet6_csk_dst_store(sk, dst, NULL, NULL);
        }
 
-       skb->dst = dst_clone(dst);
+       skb_dst_set(skb, dst_clone(dst));
 
        /* Restore final destination back after routing done */
        ipv6_addr_copy(&fl.fl6_dst, &np->daddr);
index 8f04bd9da274f444a35df267efe6a29a37186434..c3a07d75b5f50bafb987a7359c168f504ac81828 100644 (file)
@@ -48,7 +48,7 @@
 
 inline int ip6_rcv_finish( struct sk_buff *skb)
 {
-       if (skb->dst == NULL)
+       if (skb_dst(skb) == NULL)
                ip6_route_input(skb);
 
        return dst_input(skb);
@@ -70,7 +70,7 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
 
        idev = __in6_dev_get(skb->dev);
 
-       IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_INRECEIVES);
+       IP6_UPD_PO_STATS_BH(net, idev, IPSTATS_MIB_IN, skb->len);
 
        if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL ||
            !idev || unlikely(idev->cnf.disable_ipv6)) {
@@ -91,7 +91,7 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
         * arrived via the sending interface (ethX), because of the
         * nature of scoping architecture. --yoshfuji
         */
-       IP6CB(skb)->iif = skb->dst ? ip6_dst_idev(skb->dst)->dev->ifindex : dev->ifindex;
+       IP6CB(skb)->iif = skb_dst(skb) ? ip6_dst_idev(skb_dst(skb))->dev->ifindex : dev->ifindex;
 
        if (unlikely(!pskb_may_pull(skb, sizeof(*hdr))))
                goto err;
@@ -161,7 +161,7 @@ static int ip6_input_finish(struct sk_buff *skb)
        int nexthdr, raw;
        u8 hash;
        struct inet6_dev *idev;
-       struct net *net = dev_net(skb->dst->dev);
+       struct net *net = dev_net(skb_dst(skb)->dev);
 
        /*
         *      Parse extension headers
@@ -169,7 +169,7 @@ static int ip6_input_finish(struct sk_buff *skb)
 
        rcu_read_lock();
 resubmit:
-       idev = ip6_dst_idev(skb->dst);
+       idev = ip6_dst_idev(skb_dst(skb));
        if (!pskb_pull(skb, skb_transport_offset(skb)))
                goto discard;
        nhoff = IP6CB(skb)->nhoff;
@@ -242,8 +242,9 @@ int ip6_mc_input(struct sk_buff *skb)
        struct ipv6hdr *hdr;
        int deliver;
 
-       IP6_INC_STATS_BH(dev_net(skb->dst->dev),
-                        ip6_dst_idev(skb->dst), IPSTATS_MIB_INMCASTPKTS);
+       IP6_UPD_PO_STATS_BH(dev_net(skb_dst(skb)->dev),
+                        ip6_dst_idev(skb_dst(skb)), IPSTATS_MIB_INMCAST,
+                        skb->len);
 
        hdr = ipv6_hdr(skb);
        deliver = ipv6_chk_mcast_addr(skb->dev, &hdr->daddr, NULL);
index 9fb49c3b518af09939516cd4805e24bf8b4479b4..7c76e3d1821551c42acc16d3e2210404a553b4d0 100644 (file)
@@ -78,7 +78,7 @@ int __ip6_local_out(struct sk_buff *skb)
                len = 0;
        ipv6_hdr(skb)->payload_len = htons(len);
 
-       return nf_hook(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, skb->dst->dev,
+       return nf_hook(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, skb_dst(skb)->dev,
                       dst_output);
 }
 
@@ -96,7 +96,7 @@ EXPORT_SYMBOL_GPL(ip6_local_out);
 
 static int ip6_output_finish(struct sk_buff *skb)
 {
-       struct dst_entry *dst = skb->dst;
+       struct dst_entry *dst = skb_dst(skb);
 
        if (dst->hh)
                return neigh_hh_output(dst->hh, skb);
@@ -117,7 +117,7 @@ static int ip6_dev_loopback_xmit(struct sk_buff *newskb)
        __skb_pull(newskb, skb_network_offset(newskb));
        newskb->pkt_type = PACKET_LOOPBACK;
        newskb->ip_summed = CHECKSUM_UNNECESSARY;
-       WARN_ON(!newskb->dst);
+       WARN_ON(!skb_dst(newskb));
 
        netif_rx(newskb);
        return 0;
@@ -126,7 +126,7 @@ static int ip6_dev_loopback_xmit(struct sk_buff *newskb)
 
 static int ip6_output2(struct sk_buff *skb)
 {
-       struct dst_entry *dst = skb->dst;
+       struct dst_entry *dst = skb_dst(skb);
        struct net_device *dev = dst->dev;
 
        skb->protocol = htons(ETH_P_IPV6);
@@ -134,7 +134,7 @@ static int ip6_output2(struct sk_buff *skb)
 
        if (ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr)) {
                struct ipv6_pinfo* np = skb->sk ? inet6_sk(skb->sk) : NULL;
-               struct inet6_dev *idev = ip6_dst_idev(skb->dst);
+               struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb));
 
                if (!(dev->flags & IFF_LOOPBACK) && (!np || np->mc_loop) &&
                    ((mroute6_socket(dev_net(dev)) &&
@@ -159,7 +159,8 @@ static int ip6_output2(struct sk_buff *skb)
                        }
                }
 
-               IP6_INC_STATS(dev_net(dev), idev, IPSTATS_MIB_OUTMCASTPKTS);
+               IP6_UPD_PO_STATS(dev_net(dev), idev, IPSTATS_MIB_OUTMCAST,
+                               skb->len);
        }
 
        return NF_HOOK(PF_INET6, NF_INET_POST_ROUTING, skb, NULL, skb->dev,
@@ -171,21 +172,21 @@ static inline int ip6_skb_dst_mtu(struct sk_buff *skb)
        struct ipv6_pinfo *np = skb->sk ? inet6_sk(skb->sk) : NULL;
 
        return (np && np->pmtudisc == IPV6_PMTUDISC_PROBE) ?
-              skb->dst->dev->mtu : dst_mtu(skb->dst);
+              skb_dst(skb)->dev->mtu : dst_mtu(skb_dst(skb));
 }
 
 int ip6_output(struct sk_buff *skb)
 {
-       struct inet6_dev *idev = ip6_dst_idev(skb->dst);
+       struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb));
        if (unlikely(idev->cnf.disable_ipv6)) {
-               IP6_INC_STATS(dev_net(skb->dst->dev), idev,
+               IP6_INC_STATS(dev_net(skb_dst(skb)->dev), idev,
                              IPSTATS_MIB_OUTDISCARDS);
                kfree_skb(skb);
                return 0;
        }
 
        if ((skb->len > ip6_skb_dst_mtu(skb) && !skb_is_gso(skb)) ||
-                               dst_allfrag(skb->dst))
+                               dst_allfrag(skb_dst(skb)))
                return ip6_fragment(skb, ip6_output2);
        else
                return ip6_output2(skb);
@@ -201,7 +202,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
        struct net *net = sock_net(sk);
        struct ipv6_pinfo *np = inet6_sk(sk);
        struct in6_addr *first_hop = &fl->fl6_dst;
-       struct dst_entry *dst = skb->dst;
+       struct dst_entry *dst = skb_dst(skb);
        struct ipv6hdr *hdr;
        u8  proto = fl->proto;
        int seg_len = skb->len;
@@ -221,7 +222,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
                if (skb_headroom(skb) < head_room) {
                        struct sk_buff *skb2 = skb_realloc_headroom(skb, head_room);
                        if (skb2 == NULL) {
-                               IP6_INC_STATS(net, ip6_dst_idev(skb->dst),
+                               IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
                                              IPSTATS_MIB_OUTDISCARDS);
                                kfree_skb(skb);
                                return -ENOBUFS;
@@ -275,8 +276,8 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
 
        mtu = dst_mtu(dst);
        if ((skb->len <= mtu) || skb->local_df || skb_is_gso(skb)) {
-               IP6_INC_STATS(net, ip6_dst_idev(skb->dst),
-                             IPSTATS_MIB_OUTREQUESTS);
+               IP6_UPD_PO_STATS(net, ip6_dst_idev(skb_dst(skb)),
+                             IPSTATS_MIB_OUT, skb->len);
                return NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, dst->dev,
                                dst_output);
        }
@@ -285,7 +286,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
                printk(KERN_DEBUG "IPv6: sending pkt_too_big to self\n");
        skb->dev = dst->dev;
        icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev);
-       IP6_INC_STATS(net, ip6_dst_idev(skb->dst), IPSTATS_MIB_FRAGFAILS);
+       IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), IPSTATS_MIB_FRAGFAILS);
        kfree_skb(skb);
        return -EMSGSIZE;
 }
@@ -415,7 +416,7 @@ static inline int ip6_forward_finish(struct sk_buff *skb)
 
 int ip6_forward(struct sk_buff *skb)
 {
-       struct dst_entry *dst = skb->dst;
+       struct dst_entry *dst = skb_dst(skb);
        struct ipv6hdr *hdr = ipv6_hdr(skb);
        struct inet6_skb_parm *opt = IP6CB(skb);
        struct net *net = dev_net(dst->dev);
@@ -484,7 +485,7 @@ int ip6_forward(struct sk_buff *skb)
                IP6_INC_STATS(net, ip6_dst_idev(dst), IPSTATS_MIB_INDISCARDS);
                goto drop;
        }
-       dst = skb->dst;
+       dst = skb_dst(skb);
 
        /* IPv6 specs say nothing about it, but it is clear that we cannot
           send redirects to source routed frames.
@@ -565,8 +566,8 @@ static void ip6_copy_metadata(struct sk_buff *to, struct sk_buff *from)
        to->pkt_type = from->pkt_type;
        to->priority = from->priority;
        to->protocol = from->protocol;
-       dst_release(to->dst);
-       to->dst = dst_clone(from->dst);
+       skb_dst_drop(to);
+       skb_dst_set(to, dst_clone(skb_dst(from)));
        to->dev = from->dev;
        to->mark = from->mark;
 
@@ -623,7 +624,7 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr)
 static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
 {
        struct sk_buff *frag;
-       struct rt6_info *rt = (struct rt6_info*)skb->dst;
+       struct rt6_info *rt = (struct rt6_info*)skb_dst(skb);
        struct ipv6_pinfo *np = skb->sk ? inet6_sk(skb->sk) : NULL;
        struct ipv6hdr *tmp_hdr;
        struct frag_hdr *fh;
@@ -631,7 +632,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
        __be32 frag_id = 0;
        int ptr, offset = 0, err=0;
        u8 *prevhdr, nexthdr = 0;
-       struct net *net = dev_net(skb->dst->dev);
+       struct net *net = dev_net(skb_dst(skb)->dev);
 
        hlen = ip6_find_1stfragopt(skb, &prevhdr);
        nexthdr = *prevhdr;
@@ -643,9 +644,9 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
         * check should be redundant, but it's free.)
         */
        if (!skb->local_df) {
-               skb->dev = skb->dst->dev;
+               skb->dev = skb_dst(skb)->dev;
                icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev);
-               IP6_INC_STATS(net, ip6_dst_idev(skb->dst),
+               IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
                              IPSTATS_MIB_FRAGFAILS);
                kfree_skb(skb);
                return -EMSGSIZE;
@@ -657,7 +658,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
        }
        mtu -= hlen + sizeof(struct frag_hdr);
 
-       if (skb_shinfo(skb)->frag_list) {
+       if (skb_has_frags(skb)) {
                int first_len = skb_pagelen(skb);
                int truesizes = 0;
 
@@ -666,7 +667,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
                    skb_cloned(skb))
                        goto slow_path;
 
-               for (frag = skb_shinfo(skb)->frag_list; frag; frag = frag->next) {
+               skb_walk_frags(skb, frag) {
                        /* Correct geometry. */
                        if (frag->len > mtu ||
                            ((frag->len & 7) && frag->next) ||
@@ -679,7 +680,6 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
 
                        BUG_ON(frag->sk);
                        if (skb->sk) {
-                               sock_hold(skb->sk);
                                frag->sk = skb->sk;
                                frag->destructor = sock_wfree;
                                truesizes += frag->truesize;
@@ -689,13 +689,13 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
                err = 0;
                offset = 0;
                frag = skb_shinfo(skb)->frag_list;
-               skb_shinfo(skb)->frag_list = NULL;
+               skb_frag_list_init(skb);
                /* BUILD HEADER */
 
                *prevhdr = NEXTHDR_FRAGMENT;
                tmp_hdr = kmemdup(skb_network_header(skb), hlen, GFP_ATOMIC);
                if (!tmp_hdr) {
-                       IP6_INC_STATS(net, ip6_dst_idev(skb->dst),
+                       IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
                                      IPSTATS_MIB_FRAGFAILS);
                        return -ENOMEM;
                }
@@ -808,7 +808,7 @@ slow_path:
 
                if ((frag = alloc_skb(len+hlen+sizeof(struct frag_hdr)+LL_ALLOCATED_SPACE(rt->u.dst.dev), GFP_ATOMIC)) == NULL) {
                        NETDEBUG(KERN_INFO "IPv6: frag: no memory for new fragment!\n");
-                       IP6_INC_STATS(net, ip6_dst_idev(skb->dst),
+                       IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
                                      IPSTATS_MIB_FRAGFAILS);
                        err = -ENOMEM;
                        goto fail;
@@ -872,16 +872,16 @@ slow_path:
                if (err)
                        goto fail;
 
-               IP6_INC_STATS(net, ip6_dst_idev(skb->dst),
+               IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
                              IPSTATS_MIB_FRAGCREATES);
        }
-       IP6_INC_STATS(net, ip6_dst_idev(skb->dst),
+       IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
                      IPSTATS_MIB_FRAGOKS);
        kfree_skb(skb);
        return err;
 
 fail:
-       IP6_INC_STATS(net, ip6_dst_idev(skb->dst),
+       IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
                      IPSTATS_MIB_FRAGFAILS);
        kfree_skb(skb);
        return err;
@@ -1515,10 +1515,10 @@ int ip6_push_pending_frames(struct sock *sk)
        skb->priority = sk->sk_priority;
        skb->mark = sk->sk_mark;
 
-       skb->dst = dst_clone(&rt->u.dst);
-       IP6_INC_STATS(net, rt->rt6i_idev, IPSTATS_MIB_OUTREQUESTS);
+       skb_dst_set(skb, dst_clone(&rt->u.dst));
+       IP6_UPD_PO_STATS(net, rt->rt6i_idev, IPSTATS_MIB_OUT, skb->len);
        if (proto == IPPROTO_ICMPV6) {
-               struct inet6_dev *idev = ip6_dst_idev(skb->dst);
+               struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb));
 
                ICMP6MSGOUT_INC_STATS_BH(net, idev, icmp6_hdr(skb)->icmp6_type);
                ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTMSGS);
@@ -1544,8 +1544,8 @@ void ip6_flush_pending_frames(struct sock *sk)
        struct sk_buff *skb;
 
        while ((skb = __skb_dequeue_tail(&sk->sk_write_queue)) != NULL) {
-               if (skb->dst)
-                       IP6_INC_STATS(sock_net(sk), ip6_dst_idev(skb->dst),
+               if (skb_dst(skb))
+                       IP6_INC_STATS(sock_net(sk), ip6_dst_idev(skb_dst(skb)),
                                      IPSTATS_MIB_OUTDISCARDS);
                kfree_skb(skb);
        }
index d994c55a5b165d1712525dc09dc4394bfc3f8d37..404d16a97d5c9d85c119f1853ce23e509c924ed5 100644 (file)
@@ -532,8 +532,8 @@ ip4ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
        if (!skb2)
                return 0;
 
-       dst_release(skb2->dst);
-       skb2->dst = NULL;
+       skb_dst_drop(skb2);
+
        skb_pull(skb2, offset);
        skb_reset_network_header(skb2);
        eiph = ip_hdr(skb2);
@@ -560,21 +560,21 @@ ip4ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
                        ip_rt_put(rt);
                        goto out;
                }
-               skb2->dst = (struct dst_entry *)rt;
+               skb_dst_set(skb2, (struct dst_entry *)rt);
        } else {
                ip_rt_put(rt);
                if (ip_route_input(skb2, eiph->daddr, eiph->saddr, eiph->tos,
                                   skb2->dev) ||
-                   skb2->dst->dev->type != ARPHRD_TUNNEL)
+                   skb_dst(skb2)->dev->type != ARPHRD_TUNNEL)
                        goto out;
        }
 
        /* change mtu on this route */
        if (rel_type == ICMP_DEST_UNREACH && rel_code == ICMP_FRAG_NEEDED) {
-               if (rel_info > dst_mtu(skb2->dst))
+               if (rel_info > dst_mtu(skb_dst(skb2)))
                        goto out;
 
-               skb2->dst->ops->update_pmtu(skb2->dst, rel_info);
+               skb_dst(skb2)->ops->update_pmtu(skb_dst(skb2), rel_info);
        }
 
        icmp_send(skb2, rel_type, rel_code, htonl(rel_info));
@@ -606,8 +606,7 @@ ip6ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
                if (!skb2)
                        return 0;
 
-               dst_release(skb2->dst);
-               skb2->dst = NULL;
+               skb_dst_drop(skb2);
                skb_pull(skb2, offset);
                skb_reset_network_header(skb2);
 
@@ -720,8 +719,7 @@ static int ip6_tnl_rcv(struct sk_buff *skb, __u16 protocol,
                skb->pkt_type = PACKET_HOST;
                memset(skb->cb, 0, sizeof(struct inet6_skb_parm));
                skb->dev = t->dev;
-               dst_release(skb->dst);
-               skb->dst = NULL;
+               skb_dst_drop(skb);
                nf_reset(skb);
 
                dscp_ecn_decapsulate(t, ipv6h, skb);
@@ -885,8 +883,8 @@ static int ip6_tnl_xmit2(struct sk_buff *skb,
        }
        if (mtu < IPV6_MIN_MTU)
                mtu = IPV6_MIN_MTU;
-       if (skb->dst)
-               skb->dst->ops->update_pmtu(skb->dst, mtu);
+       if (skb_dst(skb))
+               skb_dst(skb)->ops->update_pmtu(skb_dst(skb), mtu);
        if (skb->len > mtu) {
                *pmtu = mtu;
                err = -EMSGSIZE;
@@ -910,8 +908,8 @@ static int ip6_tnl_xmit2(struct sk_buff *skb,
                kfree_skb(skb);
                skb = new_skb;
        }
-       dst_release(skb->dst);
-       skb->dst = dst_clone(dst);
+       skb_dst_drop(skb);
+       skb_dst_set(skb, dst_clone(dst));
 
        skb->transport_header = skb->network_header;
 
@@ -1100,8 +1098,8 @@ static void ip6_tnl_link_config(struct ip6_tnl *t)
        struct ip6_tnl_parm *p = &t->parms;
        struct flowi *fl = &t->fl;
 
-       memcpy(&dev->dev_addr, &p->laddr, sizeof(struct in6_addr));
-       memcpy(&dev->broadcast, &p->raddr, sizeof(struct in6_addr));
+       memcpy(dev->dev_addr, &p->laddr, sizeof(struct in6_addr));
+       memcpy(dev->broadcast, &p->raddr, sizeof(struct in6_addr));
 
        /* Set up flowi template */
        ipv6_addr_copy(&fl->fl6_src, &p->laddr);
index 228be551e9c1d896eb97ba00ec78fc80cc47d2c0..c769f155c6987ba0fd39339e6a2ec929fde62372 100644 (file)
@@ -398,10 +398,9 @@ static int pim6_rcv(struct sk_buff *skb)
        skb->protocol = htons(ETH_P_IPV6);
        skb->ip_summed = 0;
        skb->pkt_type = PACKET_HOST;
-       dst_release(skb->dst);
+       skb_dst_drop(skb);
        reg_dev->stats.rx_bytes += skb->len;
        reg_dev->stats.rx_packets++;
-       skb->dst = NULL;
        nf_reset(skb);
        netif_rx(skb);
        dev_put(reg_dev);
@@ -442,6 +441,7 @@ static void reg_vif_setup(struct net_device *dev)
        dev->flags              = IFF_NOARP;
        dev->netdev_ops         = &reg_vif_netdev_ops;
        dev->destructor         = free_netdev;
+       dev->features           |= NETIF_F_NETNS_LOCAL;
 }
 
 static struct net_device *ip6mr_reg_vif(struct net *net)
@@ -849,7 +849,7 @@ static int ip6mr_cache_report(struct net *net, struct sk_buff *pkt, mifi_t mifi,
        ipv6_addr_copy(&msg->im6_src, &ipv6_hdr(pkt)->saddr);
        ipv6_addr_copy(&msg->im6_dst, &ipv6_hdr(pkt)->daddr);
 
-       skb->dst = dst_clone(pkt->dst);
+       skb_dst_set(skb, dst_clone(skb_dst(pkt)));
        skb->ip_summed = CHECKSUM_UNNECESSARY;
        }
 
@@ -1078,7 +1078,18 @@ int __init ip6_mr_init(void)
        err = register_netdevice_notifier(&ip6_mr_notifier);
        if (err)
                goto reg_notif_fail;
+#ifdef CONFIG_IPV6_PIMSM_V2
+       if (inet6_add_protocol(&pim6_protocol, IPPROTO_PIM) < 0) {
+               printk(KERN_ERR "ip6_mr_init: can't add PIM protocol\n");
+               err = -EAGAIN;
+               goto add_proto_fail;
+       }
+#endif
        return 0;
+#ifdef CONFIG_IPV6_PIMSM_V2
+add_proto_fail:
+       unregister_netdevice_notifier(&ip6_mr_notifier);
+#endif
 reg_notif_fail:
        del_timer(&ipmr_expire_timer);
        unregister_pernet_subsys(&ip6mr_net_ops);
@@ -1364,14 +1375,6 @@ int ip6_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, int
                if (v != net->ipv6.mroute_do_pim) {
                        net->ipv6.mroute_do_pim = v;
                        net->ipv6.mroute_do_assert = v;
-                       if (net->ipv6.mroute_do_pim)
-                               ret = inet6_add_protocol(&pim6_protocol,
-                                                        IPPROTO_PIM);
-                       else
-                               ret = inet6_del_protocol(&pim6_protocol,
-                                                        IPPROTO_PIM);
-                       if (ret < 0)
-                               ret = -EAGAIN;
                }
                rtnl_unlock();
                return ret;
@@ -1487,7 +1490,7 @@ int ip6mr_ioctl(struct sock *sk, int cmd, void __user *arg)
 
 static inline int ip6mr_forward2_finish(struct sk_buff *skb)
 {
-       IP6_INC_STATS_BH(dev_net(skb->dst->dev), ip6_dst_idev(skb->dst),
+       IP6_INC_STATS_BH(dev_net(skb_dst(skb)->dev), ip6_dst_idev(skb_dst(skb)),
                         IPSTATS_MIB_OUTFORWDATAGRAMS);
        return dst_output(skb);
 }
@@ -1532,8 +1535,8 @@ static int ip6mr_forward2(struct sk_buff *skb, struct mfc6_cache *c, int vifi)
        if (!dst)
                goto out_free;
 
-       dst_release(skb->dst);
-       skb->dst = dst;
+       skb_dst_drop(skb);
+       skb_dst_set(skb, dst);
 
        /*
         * RFC1584 teaches, that DVMRP/PIM router must deliver packets locally
@@ -1722,7 +1725,7 @@ int ip6mr_get_route(struct net *net,
 {
        int err;
        struct mfc6_cache *cache;
-       struct rt6_info *rt = (struct rt6_info *)skb->dst;
+       struct rt6_info *rt = (struct rt6_info *)skb_dst(skb);
 
        read_lock(&mrt_lock);
        cache = ip6mr_cache_find(net, &rt->rt6i_src.addr, &rt->rt6i_dst.addr);
index a51fb33e6864f7d588c8ed81821378d710081411..4b264ed40a8c350bdeffb36971e9ca2a8258f7bb 100644 (file)
@@ -1448,8 +1448,10 @@ static void mld_sendpack(struct sk_buff *skb)
        struct net *net = dev_net(skb->dev);
        int err;
        struct flowi fl;
+       struct dst_entry *dst;
+
+       IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUT, skb->len);
 
-       IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTREQUESTS);
        payload_len = (skb->tail - skb->network_header) - sizeof(*pip6);
        mldlen = skb->tail - skb->transport_header;
        pip6->payload_len = htons(payload_len);
@@ -1458,9 +1460,9 @@ static void mld_sendpack(struct sk_buff *skb)
                IPPROTO_ICMPV6, csum_partial(skb_transport_header(skb),
                                             mldlen, 0));
 
-       skb->dst = icmp6_dst_alloc(skb->dev, NULL, &ipv6_hdr(skb)->daddr);
+       dst = icmp6_dst_alloc(skb->dev, NULL, &ipv6_hdr(skb)->daddr);
 
-       if (!skb->dst) {
+       if (!dst) {
                err = -ENOMEM;
                goto err_out;
        }
@@ -1469,17 +1471,20 @@ static void mld_sendpack(struct sk_buff *skb)
                         &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr,
                         skb->dev->ifindex);
 
-       err = xfrm_lookup(net, &skb->dst, &fl, NULL, 0);
+       err = xfrm_lookup(net, &dst, &fl, NULL, 0);
+       skb_dst_set(skb, dst);
        if (err)
                goto err_out;
 
+       payload_len = skb->len;
+
        err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, skb->dev,
                      dst_output);
 out:
        if (!err) {
                ICMP6MSGOUT_INC_STATS_BH(net, idev, ICMPV6_MLD2_REPORT);
                ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTMSGS);
-               IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_OUTMCASTPKTS);
+               IP6_UPD_PO_STATS_BH(net, idev, IPSTATS_MIB_OUTMCAST, payload_len);
        } else
                IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_OUTDISCARDS);
 
@@ -1772,11 +1777,8 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
                     IPV6_TLV_ROUTERALERT, 2, 0, 0,
                     IPV6_TLV_PADN, 0 };
        struct flowi fl;
+       struct dst_entry *dst;
 
-       rcu_read_lock();
-       IP6_INC_STATS(net, __in6_dev_get(dev),
-                     IPSTATS_MIB_OUTREQUESTS);
-       rcu_read_unlock();
        if (type == ICMPV6_MGM_REDUCTION)
                snd_addr = &in6addr_linklocal_allrouters;
        else
@@ -1786,6 +1788,11 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
        payload_len = len + sizeof(ra);
        full_len = sizeof(struct ipv6hdr) + payload_len;
 
+       rcu_read_lock();
+       IP6_UPD_PO_STATS(net, __in6_dev_get(dev),
+                     IPSTATS_MIB_OUT, full_len);
+       rcu_read_unlock();
+
        skb = sock_alloc_send_skb(sk, LL_ALLOCATED_SPACE(dev) + full_len, 1, &err);
 
        if (skb == NULL) {
@@ -1824,8 +1831,8 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
 
        idev = in6_dev_get(skb->dev);
 
-       skb->dst = icmp6_dst_alloc(skb->dev, NULL, &ipv6_hdr(skb)->daddr);
-       if (!skb->dst) {
+       dst = icmp6_dst_alloc(skb->dev, NULL, &ipv6_hdr(skb)->daddr);
+       if (!dst) {
                err = -ENOMEM;
                goto err_out;
        }
@@ -1834,17 +1841,18 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
                         &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr,
                         skb->dev->ifindex);
 
-       err = xfrm_lookup(net, &skb->dst, &fl, NULL, 0);
+       err = xfrm_lookup(net, &dst, &fl, NULL, 0);
        if (err)
                goto err_out;
 
+       skb_dst_set(skb, dst);
        err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, skb->dev,
                      dst_output);
 out:
        if (!err) {
                ICMP6MSGOUT_INC_STATS(net, idev, type);
                ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTMSGS);
-               IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTMCASTPKTS);
+               IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUTMCAST, full_len);
        } else
                IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTDISCARDS);
 
index 9f061d1adbc2b3770d987ff0fe239a2ef29417bc..9eb68e92cc18108e762f24cc7f12307018f477cc 100644 (file)
@@ -465,8 +465,8 @@ struct sk_buff *ndisc_build_skb(struct net_device *dev,
                                  1, &err);
        if (!skb) {
                ND_PRINTK0(KERN_ERR
-                          "ICMPv6 ND: %s() failed to allocate an skb.\n",
-                          __func__);
+                          "ICMPv6 ND: %s() failed to allocate an skb, err=%d.\n",
+                          __func__, err);
                return NULL;
        }
 
@@ -530,10 +530,10 @@ void ndisc_send_skb(struct sk_buff *skb,
                return;
        }
 
-       skb->dst = dst;
+       skb_dst_set(skb, dst);
 
        idev = in6_dev_get(dst->dev);
-       IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTREQUESTS);
+       IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUT, skb->len);
 
        err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, dst->dev,
                      dst_output);
@@ -658,6 +658,7 @@ void ndisc_send_rs(struct net_device *dev, const struct in6_addr *saddr,
                     &icmp6h, NULL,
                     send_sllao ? ND_OPT_SOURCE_LL_ADDR : 0);
 }
+EXPORT_SYMBOL(ndisc_send_rs);
 
 
 static void ndisc_error_report(struct neighbour *neigh, struct sk_buff *skb)
@@ -1561,8 +1562,8 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
                                   1, &err);
        if (buff == NULL) {
                ND_PRINTK0(KERN_ERR
-                          "ICMPv6 Redirect: %s() failed to allocate an skb.\n",
-                          __func__);
+                          "ICMPv6 Redirect: %s() failed to allocate an skb, err=%d.\n",
+                          __func__, err);
                goto release;
        }
 
@@ -1611,9 +1612,9 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
                                             len, IPPROTO_ICMPV6,
                                             csum_partial(icmph, len, 0));
 
-       buff->dst = dst;
+       skb_dst_set(buff, dst);
        idev = in6_dev_get(dst->dev);
-       IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTREQUESTS);
+       IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUT, skb->len);
        err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, buff, NULL, dst->dev,
                      dst_output);
        if (!err) {
index 834cea69fb53b1a081be1de8368f1b9cec8921dd..d5ed92b143469488f475816a1ebb08a5c1803558 100644 (file)
@@ -12,7 +12,7 @@
 
 int ip6_route_me_harder(struct sk_buff *skb)
 {
-       struct net *net = dev_net(skb->dst->dev);
+       struct net *net = dev_net(skb_dst(skb)->dev);
        struct ipv6hdr *iph = ipv6_hdr(skb);
        struct dst_entry *dst;
        struct flowi fl = {
@@ -28,9 +28,15 @@ int ip6_route_me_harder(struct sk_buff *skb)
 
 #ifdef CONFIG_XFRM
        if (!(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) &&
-           xfrm_decode_session(skb, &fl, AF_INET6) == 0)
-               if (xfrm_lookup(net, &skb->dst, &fl, skb->sk, 0))
+           xfrm_decode_session(skb, &fl, AF_INET6) == 0) {
+               struct dst_entry *dst2 = skb_dst(skb);
+
+               if (xfrm_lookup(net, &dst2, &fl, skb->sk, 0)) {
+                       skb_dst_set(skb, NULL);
                        return -1;
+               }
+               skb_dst_set(skb, dst2);
+       }
 #endif
 
        if (dst->error) {
@@ -41,9 +47,9 @@ int ip6_route_me_harder(struct sk_buff *skb)
        }
 
        /* Drop old route. */
-       dst_release(skb->dst);
+       skb_dst_drop(skb);
 
-       skb->dst = dst;
+       skb_dst_set(skb, dst);
        return 0;
 }
 EXPORT_SYMBOL(ip6_route_me_harder);
index b693f841aeb4f019804778772b7417c9558aa7b5..1cf3f0c6a9598294b74eacf35b66024ad240c759 100644 (file)
@@ -598,7 +598,7 @@ static int __init ip6_queue_init(void)
 #ifdef CONFIG_SYSCTL
        ipq_sysctl_header = register_sysctl_paths(net_ipv6_ctl_path, ipq_table);
 #endif
-       status = nf_register_queue_handler(PF_INET6, &nfqh);
+       status = nf_register_queue_handler(NFPROTO_IPV6, &nfqh);
        if (status < 0) {
                printk(KERN_ERR "ip6_queue: failed to register queue handler\n");
                goto cleanup_sysctl;
index 219e165aea1008368b99b8786a3fcdb731c14a98..ced1f2c0cb6594f80834c8b422982486b4d3a406 100644 (file)
@@ -270,8 +270,8 @@ static struct nf_loginfo trace_loginfo = {
 /* Mildly perf critical (only if packet tracing is on) */
 static inline int
 get_chainname_rulenum(struct ip6t_entry *s, struct ip6t_entry *e,
-                     char *hookname, char **chainname,
-                     char **comment, unsigned int *rulenum)
+                     const char *hookname, const char **chainname,
+                     const char **comment, unsigned int *rulenum)
 {
        struct ip6t_standard_target *t = (void *)ip6t_get_target(s);
 
@@ -289,8 +289,8 @@ get_chainname_rulenum(struct ip6t_entry *s, struct ip6t_entry *e,
                   && unconditional(&s->ipv6)) {
                        /* Tail of chains: STANDARD target (return/policy) */
                        *comment = *chainname == hookname
-                               ? (char *)comments[NF_IP6_TRACE_COMMENT_POLICY]
-                               : (char *)comments[NF_IP6_TRACE_COMMENT_RETURN];
+                               ? comments[NF_IP6_TRACE_COMMENT_POLICY]
+                               : comments[NF_IP6_TRACE_COMMENT_RETURN];
                }
                return 1;
        } else
@@ -309,14 +309,14 @@ static void trace_packet(struct sk_buff *skb,
 {
        void *table_base;
        const struct ip6t_entry *root;
-       char *hookname, *chainname, *comment;
+       const char *hookname, *chainname, *comment;
        unsigned int rulenum = 0;
 
-       table_base = (void *)private->entries[smp_processor_id()];
+       table_base = private->entries[smp_processor_id()];
        root = get_entry(table_base, private->hook_entry[hook]);
 
-       hookname = chainname = (char *)hooknames[hook];
-       comment = (char *)comments[NF_IP6_TRACE_COMMENT_RULE];
+       hookname = chainname = hooknames[hook];
+       comment = comments[NF_IP6_TRACE_COMMENT_RULE];
 
        IP6T_ENTRY_ITERATE(root,
                           private->size - private->hook_entry[hook],
@@ -329,6 +329,12 @@ static void trace_packet(struct sk_buff *skb,
 }
 #endif
 
+static inline __pure struct ip6t_entry *
+ip6t_next_entry(const struct ip6t_entry *entry)
+{
+       return (void *)entry + entry->next_offset;
+}
+
 /* Returns one of the generic firewall policies, like NF_ACCEPT. */
 unsigned int
 ip6t_do_table(struct sk_buff *skb,
@@ -337,6 +343,8 @@ ip6t_do_table(struct sk_buff *skb,
              const struct net_device *out,
              struct xt_table *table)
 {
+#define tb_comefrom ((struct ip6t_entry *)table_base)->comefrom
+
        static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long))));
        bool hotdrop = false;
        /* Initializing verdict to NF_DROP keeps gcc happy. */
@@ -361,7 +369,7 @@ ip6t_do_table(struct sk_buff *skb,
        mtpar.in      = tgpar.in  = in;
        mtpar.out     = tgpar.out = out;
        mtpar.family  = tgpar.family = NFPROTO_IPV6;
-       tgpar.hooknum = hook;
+       mtpar.hooknum = tgpar.hooknum = hook;
 
        IP_NF_ASSERT(table->valid_hooks & (1 << hook));
 
@@ -375,96 +383,86 @@ ip6t_do_table(struct sk_buff *skb,
        back = get_entry(table_base, private->underflow[hook]);
 
        do {
+               struct ip6t_entry_target *t;
+
                IP_NF_ASSERT(e);
                IP_NF_ASSERT(back);
-               if (ip6_packet_match(skb, indev, outdev, &e->ipv6,
-                       &mtpar.thoff, &mtpar.fragoff, &hotdrop)) {
-                       struct ip6t_entry_target *t;
-
-                       if (IP6T_MATCH_ITERATE(e, do_match, skb, &mtpar) != 0)
-                               goto no_match;
+               if (!ip6_packet_match(skb, indev, outdev, &e->ipv6,
+                   &mtpar.thoff, &mtpar.fragoff, &hotdrop) ||
+                   IP6T_MATCH_ITERATE(e, do_match, skb, &mtpar) != 0) {
+                       e = ip6t_next_entry(e);
+                       continue;
+               }
 
-                       ADD_COUNTER(e->counters,
-                                   ntohs(ipv6_hdr(skb)->payload_len) +
-                                   sizeof(struct ipv6hdr), 1);
+               ADD_COUNTER(e->counters,
+                           ntohs(ipv6_hdr(skb)->payload_len) +
+                           sizeof(struct ipv6hdr), 1);
 
-                       t = ip6t_get_target(e);
-                       IP_NF_ASSERT(t->u.kernel.target);
+               t = ip6t_get_target(e);
+               IP_NF_ASSERT(t->u.kernel.target);
 
 #if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \
     defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE)
-                       /* The packet is traced: log it */
-                       if (unlikely(skb->nf_trace))
-                               trace_packet(skb, hook, in, out,
-                                            table->name, private, e);
+               /* The packet is traced: log it */
+               if (unlikely(skb->nf_trace))
+                       trace_packet(skb, hook, in, out,
+                                    table->name, private, e);
 #endif
-                       /* Standard target? */
-                       if (!t->u.kernel.target->target) {
-                               int v;
-
-                               v = ((struct ip6t_standard_target *)t)->verdict;
-                               if (v < 0) {
-                                       /* Pop from stack? */
-                                       if (v != IP6T_RETURN) {
-                                               verdict = (unsigned)(-v) - 1;
-                                               break;
-                                       }
-                                       e = back;
-                                       back = get_entry(table_base,
-                                                        back->comefrom);
-                                       continue;
-                               }
-                               if (table_base + v != (void *)e + e->next_offset
-                                   && !(e->ipv6.flags & IP6T_F_GOTO)) {
-                                       /* Save old back ptr in next entry */
-                                       struct ip6t_entry *next
-                                               = (void *)e + e->next_offset;
-                                       next->comefrom
-                                               = (void *)back - table_base;
-                                       /* set back pointer to next entry */
-                                       back = next;
+               /* Standard target? */
+               if (!t->u.kernel.target->target) {
+                       int v;
+
+                       v = ((struct ip6t_standard_target *)t)->verdict;
+                       if (v < 0) {
+                               /* Pop from stack? */
+                               if (v != IP6T_RETURN) {
+                                       verdict = (unsigned)(-v) - 1;
+                                       break;
                                }
+                               e = back;
+                               back = get_entry(table_base, back->comefrom);
+                               continue;
+                       }
+                       if (table_base + v != ip6t_next_entry(e)
+                           && !(e->ipv6.flags & IP6T_F_GOTO)) {
+                               /* Save old back ptr in next entry */
+                               struct ip6t_entry *next = ip6t_next_entry(e);
+                               next->comefrom = (void *)back - table_base;
+                               /* set back pointer to next entry */
+                               back = next;
+                       }
 
-                               e = get_entry(table_base, v);
-                       } else {
-                               /* Targets which reenter must return
-                                  abs. verdicts */
-                               tgpar.target   = t->u.kernel.target;
-                               tgpar.targinfo = t->data;
+                       e = get_entry(table_base, v);
+                       continue;
+               }
 
-#ifdef CONFIG_NETFILTER_DEBUG
-                               ((struct ip6t_entry *)table_base)->comefrom
-                                       = 0xeeeeeeec;
-#endif
-                               verdict = t->u.kernel.target->target(skb,
-                                                                    &tgpar);
+               /* Targets which reenter must return
+                  abs. verdicts */
+               tgpar.target   = t->u.kernel.target;
+               tgpar.targinfo = t->data;
 
 #ifdef CONFIG_NETFILTER_DEBUG
-                               if (((struct ip6t_entry *)table_base)->comefrom
-                                   != 0xeeeeeeec
-                                   && verdict == IP6T_CONTINUE) {
-                                       printk("Target %s reentered!\n",
-                                              t->u.kernel.target->name);
-                                       verdict = NF_DROP;
-                               }
-                               ((struct ip6t_entry *)table_base)->comefrom
-                                       = 0x57acc001;
+               tb_comefrom = 0xeeeeeeec;
 #endif
-                               if (verdict == IP6T_CONTINUE)
-                                       e = (void *)e + e->next_offset;
-                               else
-                                       /* Verdict */
-                                       break;
-                       }
-               } else {
+               verdict = t->u.kernel.target->target(skb, &tgpar);
 
-               no_match:
-                       e = (void *)e + e->next_offset;
+#ifdef CONFIG_NETFILTER_DEBUG
+               if (tb_comefrom != 0xeeeeeeec && verdict == IP6T_CONTINUE) {
+                       printk("Target %s reentered!\n",
+                              t->u.kernel.target->name);
+                       verdict = NF_DROP;
                }
+               tb_comefrom = 0x57acc001;
+#endif
+               if (verdict == IP6T_CONTINUE)
+                       e = ip6t_next_entry(e);
+               else
+                       /* Verdict */
+                       break;
        } while (!hotdrop);
 
 #ifdef CONFIG_NETFILTER_DEBUG
-       ((struct ip6t_entry *)table_base)->comefrom = NETFILTER_LINK_POISON;
+       tb_comefrom = NETFILTER_LINK_POISON;
 #endif
        xt_info_rdunlock_bh();
 
@@ -475,6 +473,8 @@ ip6t_do_table(struct sk_buff *skb,
                return NF_DROP;
        else return verdict;
 #endif
+
+#undef tb_comefrom
 }
 
 /* Figures out from what hook each rule can be called: returns 0 if
@@ -2191,7 +2191,7 @@ static bool icmp6_checkentry(const struct xt_mtchk_param *par)
 static struct xt_target ip6t_standard_target __read_mostly = {
        .name           = IP6T_STANDARD_TARGET,
        .targetsize     = sizeof(int),
-       .family         = AF_INET6,
+       .family         = NFPROTO_IPV6,
 #ifdef CONFIG_COMPAT
        .compatsize     = sizeof(compat_int_t),
        .compat_from_user = compat_standard_from_user,
@@ -2203,7 +2203,7 @@ static struct xt_target ip6t_error_target __read_mostly = {
        .name           = IP6T_ERROR_TARGET,
        .target         = ip6t_error,
        .targetsize     = IP6T_FUNCTION_MAXNAMELEN,
-       .family         = AF_INET6,
+       .family         = NFPROTO_IPV6,
 };
 
 static struct nf_sockopt_ops ip6t_sockopts = {
@@ -2229,17 +2229,17 @@ static struct xt_match icmp6_matchstruct __read_mostly = {
        .matchsize      = sizeof(struct ip6t_icmp),
        .checkentry     = icmp6_checkentry,
        .proto          = IPPROTO_ICMPV6,
-       .family         = AF_INET6,
+       .family         = NFPROTO_IPV6,
 };
 
 static int __net_init ip6_tables_net_init(struct net *net)
 {
-       return xt_proto_init(net, AF_INET6);
+       return xt_proto_init(net, NFPROTO_IPV6);
 }
 
 static void __net_exit ip6_tables_net_exit(struct net *net)
 {
-       xt_proto_fini(net, AF_INET6);
+       xt_proto_fini(net, NFPROTO_IPV6);
 }
 
 static struct pernet_operations ip6_tables_net_ops = {
index 5a2d0a41694a77791c97eef8e1063b40502029ca..5a7f00cd15ce7e194a0c3f1c1cda956c0eae2843 100644 (file)
@@ -112,7 +112,7 @@ static void send_reset(struct net *net, struct sk_buff *oldskb)
                return;
        }
 
-       nskb->dst = dst;
+       skb_dst_set(nskb, dst);
 
        skb_reserve(nskb, hh_len + dst->header_len);
 
index 9903227bf37c9b2966a127f503d5b52aa97fdec3..642dcb127babf9e80cdf939545df4a617a532083 100644 (file)
@@ -95,18 +95,10 @@ static int icmpv6_packet(struct nf_conn *ct,
                       u_int8_t pf,
                       unsigned int hooknum)
 {
-       /* Try to delete connection immediately after all replies:
-          won't actually vanish as we still have skb, and del_timer
-          means this will only run once even if count hits zero twice
-          (theoretically possible with SMP) */
-       if (CTINFO2DIR(ctinfo) == IP_CT_DIR_REPLY) {
-               if (atomic_dec_and_test(&ct->proto.icmp.count))
-                       nf_ct_kill_acct(ct, ctinfo, skb);
-       } else {
-               atomic_inc(&ct->proto.icmp.count);
-               nf_conntrack_event_cache(IPCT_PROTOINFO_VOLATILE, ct);
-               nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_icmpv6_timeout);
-       }
+       /* Do not immediately delete the connection after the first
+          successful reply to avoid excessive conntrackd traffic
+          and also to handle correctly ICMP echo reply duplicates. */
+       nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_icmpv6_timeout);
 
        return NF_ACCEPT;
 }
@@ -132,7 +124,6 @@ static bool icmpv6_new(struct nf_conn *ct, const struct sk_buff *skb,
                                      type + 128);
                return false;
        }
-       atomic_set(&ct->proto.icmp.count, 0);
        return true;
 }
 
index 058a5e4a60c37e743c6dc001bcf603dc05474c82..f3aba255ad9f21aed45d85295fa3e7542c526078 100644 (file)
@@ -409,7 +409,7 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev)
        /* If the first fragment is fragmented itself, we split
         * it to two chunks: the first with data and paged part
         * and the second, holding only fragments. */
-       if (skb_shinfo(head)->frag_list) {
+       if (skb_has_frags(head)) {
                struct sk_buff *clone;
                int i, plen = 0;
 
@@ -420,7 +420,7 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev)
                clone->next = head->next;
                head->next = clone;
                skb_shinfo(clone)->frag_list = skb_shinfo(head)->frag_list;
-               skb_shinfo(head)->frag_list = NULL;
+               skb_frag_list_init(head);
                for (i=0; i<skb_shinfo(head)->nr_frags; i++)
                        plen += skb_shinfo(head)->frags[i].size;
                clone->len = clone->data_len = head->data_len - plen;
index 97c17fdd6f755958f8de47159cf47f7df25ab0ab..590ddefb7ffcb3b91e5d54ac41c01e9a2bcbcfe2 100644 (file)
@@ -61,7 +61,7 @@ static const struct file_operations sockstat6_seq_fops = {
 
 static struct snmp_mib snmp6_ipstats_list[] = {
 /* ipv6 mib according to RFC 2465 */
-       SNMP_MIB_ITEM("Ip6InReceives", IPSTATS_MIB_INRECEIVES),
+       SNMP_MIB_ITEM("Ip6InReceives", IPSTATS_MIB_INPKTS),
        SNMP_MIB_ITEM("Ip6InHdrErrors", IPSTATS_MIB_INHDRERRORS),
        SNMP_MIB_ITEM("Ip6InTooBigErrors", IPSTATS_MIB_INTOOBIGERRORS),
        SNMP_MIB_ITEM("Ip6InNoRoutes", IPSTATS_MIB_INNOROUTES),
@@ -71,7 +71,7 @@ static struct snmp_mib snmp6_ipstats_list[] = {
        SNMP_MIB_ITEM("Ip6InDiscards", IPSTATS_MIB_INDISCARDS),
        SNMP_MIB_ITEM("Ip6InDelivers", IPSTATS_MIB_INDELIVERS),
        SNMP_MIB_ITEM("Ip6OutForwDatagrams", IPSTATS_MIB_OUTFORWDATAGRAMS),
-       SNMP_MIB_ITEM("Ip6OutRequests", IPSTATS_MIB_OUTREQUESTS),
+       SNMP_MIB_ITEM("Ip6OutRequests", IPSTATS_MIB_OUTPKTS),
        SNMP_MIB_ITEM("Ip6OutDiscards", IPSTATS_MIB_OUTDISCARDS),
        SNMP_MIB_ITEM("Ip6OutNoRoutes", IPSTATS_MIB_OUTNOROUTES),
        SNMP_MIB_ITEM("Ip6ReasmTimeout", IPSTATS_MIB_REASMTIMEOUT),
@@ -83,6 +83,12 @@ static struct snmp_mib snmp6_ipstats_list[] = {
        SNMP_MIB_ITEM("Ip6FragCreates", IPSTATS_MIB_FRAGCREATES),
        SNMP_MIB_ITEM("Ip6InMcastPkts", IPSTATS_MIB_INMCASTPKTS),
        SNMP_MIB_ITEM("Ip6OutMcastPkts", IPSTATS_MIB_OUTMCASTPKTS),
+       SNMP_MIB_ITEM("Ip6InOctets", IPSTATS_MIB_INOCTETS),
+       SNMP_MIB_ITEM("Ip6OutOctets", IPSTATS_MIB_OUTOCTETS),
+       SNMP_MIB_ITEM("Ip6InMcastOctets", IPSTATS_MIB_INMCASTOCTETS),
+       SNMP_MIB_ITEM("Ip6OutMcastOctets", IPSTATS_MIB_OUTMCASTOCTETS),
+       SNMP_MIB_ITEM("Ip6InBcastOctets", IPSTATS_MIB_INBCASTOCTETS),
+       SNMP_MIB_ITEM("Ip6OutBcastOctets", IPSTATS_MIB_OUTBCASTOCTETS),
        SNMP_MIB_SENTINEL
 };
 
index 61f6827e59067f82fbca8c00db67ecd64b0ed521..36a090d87a3d1c8497426b0bfb6d15b5330b80bf 100644 (file)
@@ -625,7 +625,7 @@ static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
 
        skb->priority = sk->sk_priority;
        skb->mark = sk->sk_mark;
-       skb->dst = dst_clone(&rt->u.dst);
+       skb_dst_set(skb, dst_clone(&rt->u.dst));
 
        skb_put(skb, length);
        skb_reset_network_header(skb);
@@ -638,7 +638,7 @@ static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
        if (err)
                goto error_fault;
 
-       IP6_INC_STATS(sock_net(sk), rt->rt6i_idev, IPSTATS_MIB_OUTREQUESTS);
+       IP6_UPD_PO_STATS(sock_net(sk), rt->rt6i_idev, IPSTATS_MIB_OUT, skb->len);
        err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
                      dst_output);
        if (err > 0)
index e9ac7a12f5951f58f1c211b7e064c8dfcf43cf53..2642a41a853518bc6405f6934554bdbaad58c875 100644 (file)
@@ -267,7 +267,7 @@ static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
        struct sk_buff *prev, *next;
        struct net_device *dev;
        int offset, end;
-       struct net *net = dev_net(skb->dst->dev);
+       struct net *net = dev_net(skb_dst(skb)->dev);
 
        if (fq->q.last_in & INET_FRAG_COMPLETE)
                goto err;
@@ -277,7 +277,7 @@ static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
                        ((u8 *)(fhdr + 1) - (u8 *)(ipv6_hdr(skb) + 1)));
 
        if ((unsigned int)end > IPV6_MAXPLEN) {
-               IP6_INC_STATS_BH(net, ip6_dst_idev(skb->dst),
+               IP6_INC_STATS_BH(net, ip6_dst_idev(skb_dst(skb)),
                                 IPSTATS_MIB_INHDRERRORS);
                icmpv6_param_prob(skb, ICMPV6_HDR_FIELD,
                                  ((u8 *)&fhdr->frag_off -
@@ -310,7 +310,7 @@ static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
                        /* RFC2460 says always send parameter problem in
                         * this case. -DaveM
                         */
-                       IP6_INC_STATS_BH(net, ip6_dst_idev(skb->dst),
+                       IP6_INC_STATS_BH(net, ip6_dst_idev(skb_dst(skb)),
                                         IPSTATS_MIB_INHDRERRORS);
                        icmpv6_param_prob(skb, ICMPV6_HDR_FIELD,
                                          offsetof(struct ipv6hdr, payload_len));
@@ -434,7 +434,7 @@ static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
        return -1;
 
 err:
-       IP6_INC_STATS(net, ip6_dst_idev(skb->dst),
+       IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
                      IPSTATS_MIB_REASMFAILS);
        kfree_skb(skb);
        return -1;
@@ -494,7 +494,7 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev,
        /* If the first fragment is fragmented itself, we split
         * it to two chunks: the first with data and paged part
         * and the second, holding only fragments. */
-       if (skb_shinfo(head)->frag_list) {
+       if (skb_has_frags(head)) {
                struct sk_buff *clone;
                int i, plen = 0;
 
@@ -503,7 +503,7 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev,
                clone->next = head->next;
                head->next = clone;
                skb_shinfo(clone)->frag_list = skb_shinfo(head)->frag_list;
-               skb_shinfo(head)->frag_list = NULL;
+               skb_frag_list_init(head);
                for (i=0; i<skb_shinfo(head)->nr_frags; i++)
                        plen += skb_shinfo(head)->frags[i].size;
                clone->len = clone->data_len = head->data_len - plen;
@@ -576,9 +576,9 @@ static int ipv6_frag_rcv(struct sk_buff *skb)
        struct frag_hdr *fhdr;
        struct frag_queue *fq;
        struct ipv6hdr *hdr = ipv6_hdr(skb);
-       struct net *net = dev_net(skb->dst->dev);
+       struct net *net = dev_net(skb_dst(skb)->dev);
 
-       IP6_INC_STATS_BH(net, ip6_dst_idev(skb->dst), IPSTATS_MIB_REASMREQDS);
+       IP6_INC_STATS_BH(net, ip6_dst_idev(skb_dst(skb)), IPSTATS_MIB_REASMREQDS);
 
        /* Jumbo payload inhibits frag. header */
        if (hdr->payload_len==0)
@@ -595,17 +595,17 @@ static int ipv6_frag_rcv(struct sk_buff *skb)
                /* It is not a fragmented frame */
                skb->transport_header += sizeof(struct frag_hdr);
                IP6_INC_STATS_BH(net,
-                                ip6_dst_idev(skb->dst), IPSTATS_MIB_REASMOKS);
+                                ip6_dst_idev(skb_dst(skb)), IPSTATS_MIB_REASMOKS);
 
                IP6CB(skb)->nhoff = (u8 *)fhdr - skb_network_header(skb);
                return 1;
        }
 
        if (atomic_read(&net->ipv6.frags.mem) > net->ipv6.frags.high_thresh)
-               ip6_evictor(net, ip6_dst_idev(skb->dst));
+               ip6_evictor(net, ip6_dst_idev(skb_dst(skb)));
 
        if ((fq = fq_find(net, fhdr->identification, &hdr->saddr, &hdr->daddr,
-                         ip6_dst_idev(skb->dst))) != NULL) {
+                         ip6_dst_idev(skb_dst(skb)))) != NULL) {
                int ret;
 
                spin_lock(&fq->q.lock);
@@ -617,12 +617,12 @@ static int ipv6_frag_rcv(struct sk_buff *skb)
                return ret;
        }
 
-       IP6_INC_STATS_BH(net, ip6_dst_idev(skb->dst), IPSTATS_MIB_REASMFAILS);
+       IP6_INC_STATS_BH(net, ip6_dst_idev(skb_dst(skb)), IPSTATS_MIB_REASMFAILS);
        kfree_skb(skb);
        return -1;
 
 fail_hdr:
-       IP6_INC_STATS(net, ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS);
+       IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), IPSTATS_MIB_INHDRERRORS);
        icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, skb_network_header_len(skb));
        return -1;
 }
index 032a5ec391c575c72fe3036e659bc74721cc8428..658293ea05ba736d143947ceca915cacdf4e5f89 100644 (file)
@@ -800,7 +800,7 @@ void ip6_route_input(struct sk_buff *skb)
        if (rt6_need_strict(&iph->daddr) && skb->dev->type != ARPHRD_PIMREG)
                flags |= RT6_LOOKUP_F_IFACE;
 
-       skb->dst = fib6_rule_lookup(net, &fl, flags, ip6_pol_route_input);
+       skb_dst_set(skb, fib6_rule_lookup(net, &fl, flags, ip6_pol_route_input));
 }
 
 static struct rt6_info *ip6_pol_route_output(struct net *net, struct fib6_table *table,
@@ -911,7 +911,7 @@ static void ip6_link_failure(struct sk_buff *skb)
 
        icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_ADDR_UNREACH, 0, skb->dev);
 
-       rt = (struct rt6_info *) skb->dst;
+       rt = (struct rt6_info *) skb_dst(skb);
        if (rt) {
                if (rt->rt6i_flags&RTF_CACHE) {
                        dst_set_expires(&rt->u.dst, 0);
@@ -1868,7 +1868,7 @@ int ipv6_route_ioctl(struct net *net, unsigned int cmd, void __user *arg)
 static int ip6_pkt_drop(struct sk_buff *skb, int code, int ipstats_mib_noroutes)
 {
        int type;
-       struct dst_entry *dst = skb->dst;
+       struct dst_entry *dst = skb_dst(skb);
        switch (ipstats_mib_noroutes) {
        case IPSTATS_MIB_INNOROUTES:
                type = ipv6_addr_type(&ipv6_hdr(skb)->daddr);
@@ -1895,7 +1895,7 @@ static int ip6_pkt_discard(struct sk_buff *skb)
 
 static int ip6_pkt_discard_out(struct sk_buff *skb)
 {
-       skb->dev = skb->dst->dev;
+       skb->dev = skb_dst(skb)->dev;
        return ip6_pkt_drop(skb, ICMPV6_NOROUTE, IPSTATS_MIB_OUTNOROUTES);
 }
 
@@ -1908,7 +1908,7 @@ static int ip6_pkt_prohibit(struct sk_buff *skb)
 
 static int ip6_pkt_prohibit_out(struct sk_buff *skb)
 {
-       skb->dev = skb->dst->dev;
+       skb->dev = skb_dst(skb)->dev;
        return ip6_pkt_drop(skb, ICMPV6_ADM_PROHIBITED, IPSTATS_MIB_OUTNOROUTES);
 }
 
@@ -2366,7 +2366,7 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void
        skb_reserve(skb, MAX_HEADER + sizeof(struct ipv6hdr));
 
        rt = (struct rt6_info*) ip6_route_output(net, NULL, &fl);
-       skb->dst = &rt->u.dst;
+       skb_dst_set(skb, &rt->u.dst);
 
        err = rt6_fill_node(net, skb, rt, &fl.fl6_dst, &fl.fl6_src, iif,
                            RTM_NEWROUTE, NETLINK_CB(in_skb).pid,
index 664ab82e03b2ed1a1191a5111fb01e4014410235..68e52308e5520f7180e22c0230aea51133fad265 100644 (file)
@@ -15,6 +15,7 @@
  * Roger Venning <r.venning@telstra.com>:      6to4 support
  * Nate Thompson <nate@thebog.net>:            6to4 support
  * Fred Templin <fred.l.templin@boeing.com>:   isatap support
+ * Sascha Hlusiak <mail@saschahlusiak.de>:     stateless autoconf for isatap
  */
 
 #include <linux/module.h>
@@ -80,7 +81,7 @@ struct sit_net {
 static DEFINE_RWLOCK(ipip6_lock);
 
 static struct ip_tunnel * ipip6_tunnel_lookup(struct net *net,
-               __be32 remote, __be32 local)
+               struct net_device *dev, __be32 remote, __be32 local)
 {
        unsigned h0 = HASH(remote);
        unsigned h1 = HASH(local);
@@ -89,18 +90,25 @@ static struct ip_tunnel * ipip6_tunnel_lookup(struct net *net,
 
        for (t = sitn->tunnels_r_l[h0^h1]; t; t = t->next) {
                if (local == t->parms.iph.saddr &&
-                   remote == t->parms.iph.daddr && (t->dev->flags&IFF_UP))
+                   remote == t->parms.iph.daddr &&
+                   (!dev || !t->parms.link || dev->iflink == t->parms.link) &&
+                   (t->dev->flags & IFF_UP))
                        return t;
        }
        for (t = sitn->tunnels_r[h0]; t; t = t->next) {
-               if (remote == t->parms.iph.daddr && (t->dev->flags&IFF_UP))
+               if (remote == t->parms.iph.daddr &&
+                   (!dev || !t->parms.link || dev->iflink == t->parms.link) &&
+                   (t->dev->flags & IFF_UP))
                        return t;
        }
        for (t = sitn->tunnels_l[h1]; t; t = t->next) {
-               if (local == t->parms.iph.saddr && (t->dev->flags&IFF_UP))
+               if (local == t->parms.iph.saddr &&
+                   (!dev || !t->parms.link || dev->iflink == t->parms.link) &&
+                   (t->dev->flags & IFF_UP))
                        return t;
        }
-       if ((t = sitn->tunnels_wc[0]) != NULL && (t->dev->flags&IFF_UP))
+       t = sitn->tunnels_wc[0];
+       if ((t != NULL) && (t->dev->flags & IFF_UP))
                return t;
        return NULL;
 }
@@ -165,8 +173,14 @@ static struct ip_tunnel * ipip6_tunnel_locate(struct net *net,
        struct sit_net *sitn = net_generic(net, sit_net_id);
 
        for (tp = __ipip6_bucket(sitn, parms); (t = *tp) != NULL; tp = &t->next) {
-               if (local == t->parms.iph.saddr && remote == t->parms.iph.daddr)
-                       return t;
+               if (local == t->parms.iph.saddr &&
+                   remote == t->parms.iph.daddr &&
+                   parms->link == t->parms.link) {
+                       if (create)
+                               return NULL;
+                       else
+                               return t;
+               }
        }
        if (!create)
                goto failed;
@@ -209,6 +223,44 @@ failed:
        return NULL;
 }
 
+static void ipip6_tunnel_rs_timer(unsigned long data)
+{
+       struct ip_tunnel_prl_entry *p = (struct ip_tunnel_prl_entry *) data;
+       struct inet6_dev *ifp;
+       struct inet6_ifaddr *addr;
+
+       spin_lock(&p->lock);
+       ifp = __in6_dev_get(p->tunnel->dev);
+
+       read_lock_bh(&ifp->lock);
+       for (addr = ifp->addr_list; addr; addr = addr->if_next) {
+               struct in6_addr rtr;
+
+               if (!(ipv6_addr_type(&addr->addr) & IPV6_ADDR_LINKLOCAL))
+                       continue;
+
+               /* Send RS to guessed linklocal address of router
+                *
+                * Better: send to ff02::2 encapsuled in unicast directly
+                * to router-v4 instead of guessing the v6 address.
+                *
+                * Cisco/Windows seem to not set the u/l bit correctly,
+                * so we won't guess right.
+                */
+               ipv6_addr_set(&rtr,  htonl(0xFE800000), 0, 0, 0);
+               if (!__ipv6_isatap_ifid(rtr.s6_addr + 8,
+                                       p->addr)) {
+                       ndisc_send_rs(p->tunnel->dev, &addr->addr, &rtr);
+               }
+       }
+       read_unlock_bh(&ifp->lock);
+
+       mod_timer(&p->rs_timer, jiffies + HZ * p->rs_delay);
+       spin_unlock(&p->lock);
+
+       return;
+}
+
 static struct ip_tunnel_prl_entry *
 __ipip6_tunnel_locate_prl(struct ip_tunnel *t, __be32 addr)
 {
@@ -267,6 +319,7 @@ static int ipip6_tunnel_get_prl(struct ip_tunnel *t,
                        continue;
                kp[c].addr = prl->addr;
                kp[c].flags = prl->flags;
+               kp[c].rs_delay = prl->rs_delay;
                c++;
                if (kprl.addr != htonl(INADDR_ANY))
                        break;
@@ -316,11 +369,23 @@ ipip6_tunnel_add_prl(struct ip_tunnel *t, struct ip_tunnel_prl *a, int chg)
        }
 
        p->next = t->prl;
+       p->tunnel = t;
        t->prl = p;
        t->prl_count++;
+
+       spin_lock_init(&p->lock);
+       setup_timer(&p->rs_timer, ipip6_tunnel_rs_timer, (unsigned long) p);
 update:
        p->addr = a->addr;
        p->flags = a->flags;
+       p->rs_delay = a->rs_delay;
+       if (p->rs_delay == 0)
+               p->rs_delay = IPTUNNEL_RS_DEFAULT_DELAY;
+       spin_lock(&p->lock);
+       del_timer(&p->rs_timer);
+       if (p->flags & PRL_DEFAULT)
+               mod_timer(&p->rs_timer, jiffies + 1);
+       spin_unlock(&p->lock);
 out:
        write_unlock(&ipip6_lock);
        return err;
@@ -339,6 +404,9 @@ ipip6_tunnel_del_prl(struct ip_tunnel *t, struct ip_tunnel_prl *a)
                        if ((*p)->addr == a->addr) {
                                x = *p;
                                *p = x->next;
+                               spin_lock(&x->lock);
+                               del_timer(&x->rs_timer);
+                               spin_unlock(&x->lock);
                                kfree(x);
                                t->prl_count--;
                                goto out;
@@ -349,13 +417,16 @@ ipip6_tunnel_del_prl(struct ip_tunnel *t, struct ip_tunnel_prl *a)
                while (t->prl) {
                        x = t->prl;
                        t->prl = t->prl->next;
+                       spin_lock(&x->lock);
+                       del_timer(&x->rs_timer);
+                       spin_unlock(&x->lock);
                        kfree(x);
                        t->prl_count--;
                }
        }
 out:
        write_unlock(&ipip6_lock);
-       return 0;
+       return err;
 }
 
 static int
@@ -446,7 +517,10 @@ static int ipip6_err(struct sk_buff *skb, u32 info)
        err = -ENOENT;
 
        read_lock(&ipip6_lock);
-       t = ipip6_tunnel_lookup(dev_net(skb->dev), iph->daddr, iph->saddr);
+       t = ipip6_tunnel_lookup(dev_net(skb->dev),
+                               skb->dev,
+                               iph->daddr,
+                               iph->saddr);
        if (t == NULL || t->parms.iph.daddr == 0)
                goto out;
 
@@ -481,8 +555,9 @@ static int ipip6_rcv(struct sk_buff *skb)
        iph = ip_hdr(skb);
 
        read_lock(&ipip6_lock);
-       if ((tunnel = ipip6_tunnel_lookup(dev_net(skb->dev),
-                                       iph->saddr, iph->daddr)) != NULL) {
+       tunnel = ipip6_tunnel_lookup(dev_net(skb->dev), skb->dev,
+                                    iph->saddr, iph->daddr);
+       if (tunnel != NULL) {
                secpath_reset(skb);
                skb->mac_header = skb->network_header;
                skb_reset_network_header(skb);
@@ -500,8 +575,7 @@ static int ipip6_rcv(struct sk_buff *skb)
                tunnel->dev->stats.rx_packets++;
                tunnel->dev->stats.rx_bytes += skb->len;
                skb->dev = tunnel->dev;
-               dst_release(skb->dst);
-               skb->dst = NULL;
+               skb_dst_drop(skb);
                nf_reset(skb);
                ipip6_ecn_decapsulate(iph, skb);
                netif_rx(skb);
@@ -563,8 +637,8 @@ static int ipip6_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
        if (dev->priv_flags & IFF_ISATAP) {
                struct neighbour *neigh = NULL;
 
-               if (skb->dst)
-                       neigh = skb->dst->neighbour;
+               if (skb_dst(skb))
+                       neigh = skb_dst(skb)->neighbour;
 
                if (neigh == NULL) {
                        if (net_ratelimit())
@@ -588,8 +662,8 @@ static int ipip6_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
        if (!dst) {
                struct neighbour *neigh = NULL;
 
-               if (skb->dst)
-                       neigh = skb->dst->neighbour;
+               if (skb_dst(skb))
+                       neigh = skb_dst(skb)->neighbour;
 
                if (neigh == NULL) {
                        if (net_ratelimit())
@@ -639,7 +713,7 @@ static int ipip6_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
        if (tiph->frag_off)
                mtu = dst_mtu(&rt->u.dst) - sizeof(struct iphdr);
        else
-               mtu = skb->dst ? dst_mtu(skb->dst) : dev->mtu;
+               mtu = skb_dst(skb) ? dst_mtu(skb_dst(skb)) : dev->mtu;
 
        if (mtu < 68) {
                stats->collisions++;
@@ -648,8 +722,8 @@ static int ipip6_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
        }
        if (mtu < IPV6_MIN_MTU)
                mtu = IPV6_MIN_MTU;
-       if (tunnel->parms.iph.daddr && skb->dst)
-               skb->dst->ops->update_pmtu(skb->dst, mtu);
+       if (tunnel->parms.iph.daddr && skb_dst(skb))
+               skb_dst(skb)->ops->update_pmtu(skb_dst(skb), mtu);
 
        if (skb->len > mtu) {
                icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, dev);
@@ -693,8 +767,8 @@ static int ipip6_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
        skb_reset_network_header(skb);
        memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
        IPCB(skb)->flags = 0;
-       dst_release(skb->dst);
-       skb->dst = &rt->u.dst;
+       skb_dst_drop(skb);
+       skb_dst_set(skb, &rt->u.dst);
 
        /*
         *      Push down and install the IPIP header.
index 711175e0571f754539f5bc74975ebb5b83e1f54a..8c2513982b616d35d28d7c9df36ef1b440d57f66 100644 (file)
@@ -131,7 +131,7 @@ __u32 cookie_v6_init_sequence(struct sock *sk, struct sk_buff *skb, __u16 *mssp)
        int mssind;
        const __u16 mss = *mssp;
 
-       tcp_sk(sk)->last_synq_overflow = jiffies;
+       tcp_synq_overflow(sk);
 
        for (mssind = 0; mss > msstab[mssind + 1]; mssind++)
                ;
@@ -175,7 +175,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
        if (!sysctl_tcp_syncookies || !th->ack)
                goto out;
 
-       if (time_after(jiffies, tp->last_synq_overflow + TCP_TIMEOUT_INIT) ||
+       if (tcp_synq_no_recent_overflow(sk) ||
                (mss = cookie_check(skb, cookie)) == 0) {
                NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_SYNCOOKIESFAILED);
                goto out;
index 4b5aa1854260642ec15fcb6124607dfba10f21b1..53b6a4192b161eae3f44b226395e02a691ad120c 100644 (file)
@@ -941,9 +941,10 @@ static int tcp_v6_gso_send_check(struct sk_buff *skb)
        return 0;
 }
 
-struct sk_buff **tcp6_gro_receive(struct sk_buff **head, struct sk_buff *skb)
+static struct sk_buff **tcp6_gro_receive(struct sk_buff **head,
+                                        struct sk_buff *skb)
 {
-       struct ipv6hdr *iph = ipv6_hdr(skb);
+       struct ipv6hdr *iph = skb_gro_network_header(skb);
 
        switch (skb->ip_summed) {
        case CHECKSUM_COMPLETE:
@@ -961,9 +962,8 @@ struct sk_buff **tcp6_gro_receive(struct sk_buff **head, struct sk_buff *skb)
 
        return tcp_gro_receive(head, skb);
 }
-EXPORT_SYMBOL(tcp6_gro_receive);
 
-int tcp6_gro_complete(struct sk_buff *skb)
+static int tcp6_gro_complete(struct sk_buff *skb)
 {
        struct ipv6hdr *iph = ipv6_hdr(skb);
        struct tcphdr *th = tcp_hdr(skb);
@@ -974,7 +974,6 @@ int tcp6_gro_complete(struct sk_buff *skb)
 
        return tcp_gro_complete(skb);
 }
-EXPORT_SYMBOL(tcp6_gro_complete);
 
 static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win,
                                 u32 ts, struct tcp_md5sig_key *key, int rst)
@@ -982,9 +981,10 @@ static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win,
        struct tcphdr *th = tcp_hdr(skb), *t1;
        struct sk_buff *buff;
        struct flowi fl;
-       struct net *net = dev_net(skb->dst->dev);
+       struct net *net = dev_net(skb_dst(skb)->dev);
        struct sock *ctl_sk = net->ipv6.tcp_sk;
        unsigned int tot_len = sizeof(struct tcphdr);
+       struct dst_entry *dst;
        __be32 *topt;
 
        if (ts)
@@ -1053,8 +1053,9 @@ static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win,
         * Underlying function will use this to retrieve the network
         * namespace
         */
-       if (!ip6_dst_lookup(ctl_sk, &buff->dst, &fl)) {
-               if (xfrm_lookup(net, &buff->dst, &fl, NULL, 0) >= 0) {
+       if (!ip6_dst_lookup(ctl_sk, &dst, &fl)) {
+               if (xfrm_lookup(net, &dst, &fl, NULL, 0) >= 0) {
+                       skb_dst_set(buff, dst);
                        ip6_xmit(ctl_sk, buff, &fl, NULL, 0);
                        TCP_INC_STATS_BH(net, TCP_MIB_OUTSEGS);
                        if (rst)
index 8905712cfbb81970acabb56c8a6673713e3e1574..fc333d854728ee875e9068029d0ee44a4456d6c2 100644 (file)
@@ -177,10 +177,9 @@ static struct sock *__udp6_lib_lookup_skb(struct sk_buff *skb,
 
        if (unlikely(sk = skb_steal_sock(skb)))
                return sk;
-       else
-               return __udp6_lib_lookup(dev_net(skb->dst->dev), &iph->saddr, sport,
-                                        &iph->daddr, dport, inet6_iif(skb),
-                                        udptable);
+       return __udp6_lib_lookup(dev_net(skb_dst(skb)->dev), &iph->saddr, sport,
+                                &iph->daddr, dport, inet6_iif(skb),
+                                udptable);
 }
 
 /*
index e20529b4c82532acb318758403979a232db4b0d4..3927832227b933d3fd55218e0bdb15c6369a7e0f 100644 (file)
@@ -31,7 +31,7 @@ static inline void ipip6_ecn_decapsulate(struct sk_buff *skb)
  */
 static int xfrm6_mode_tunnel_output(struct xfrm_state *x, struct sk_buff *skb)
 {
-       struct dst_entry *dst = skb->dst;
+       struct dst_entry *dst = skb_dst(skb);
        struct ipv6hdr *top_iph;
        int dsfield;
 
@@ -45,7 +45,7 @@ static int xfrm6_mode_tunnel_output(struct xfrm_state *x, struct sk_buff *skb)
 
        memcpy(top_iph->flow_lbl, XFRM_MODE_SKB_CB(skb)->flow_lbl,
               sizeof(top_iph->flow_lbl));
-       top_iph->nexthdr = xfrm_af2proto(skb->dst->ops->family);
+       top_iph->nexthdr = xfrm_af2proto(skb_dst(skb)->ops->family);
 
        dsfield = XFRM_MODE_SKB_CB(skb)->tos;
        dsfield = INET_ECN_encapsulate(dsfield, dsfield);
index 5ee5a031bc93a85b453139eaa7581067dcf541d3..c4f4eef032a3dccfb4cebfbc3a2f72bcf231872f 100644 (file)
@@ -30,7 +30,7 @@ EXPORT_SYMBOL(xfrm6_find_1stfragopt);
 static int xfrm6_tunnel_check_size(struct sk_buff *skb)
 {
        int mtu, ret = 0;
-       struct dst_entry *dst = skb->dst;
+       struct dst_entry *dst = skb_dst(skb);
 
        mtu = dst_mtu(dst);
        if (mtu < IPV6_MIN_MTU)
@@ -90,6 +90,6 @@ static int xfrm6_output_finish(struct sk_buff *skb)
 
 int xfrm6_output(struct sk_buff *skb)
 {
-       return NF_HOOK(PF_INET6, NF_INET_POST_ROUTING, skb, NULL, skb->dst->dev,
+       return NF_HOOK(PF_INET6, NF_INET_POST_ROUTING, skb, NULL, skb_dst(skb)->dev,
                       xfrm6_output_finish);
 }
index 2562ebc1b22c0f2d109b26aca2d43ee576477622..7af2e74deda823bf587d298d1f7bab58d8484dd3 100644 (file)
@@ -982,17 +982,12 @@ void irlap_resend_rejected_frames(struct irlap_cb *self, int command)
 {
        struct sk_buff *tx_skb;
        struct sk_buff *skb;
-       int count;
 
        IRDA_ASSERT(self != NULL, return;);
        IRDA_ASSERT(self->magic == LAP_MAGIC, return;);
 
-       /* Initialize variables */
-       count = skb_queue_len(&self->wx_list);
-
        /*  Resend unacknowledged frame(s) */
-       skb = skb_peek(&self->wx_list);
-       while (skb != NULL) {
+       skb_queue_walk(&self->wx_list, skb) {
                irlap_wait_min_turn_around(self, &self->qos_tx);
 
                /* We copy the skb to be retransmitted since we will have to
@@ -1011,21 +1006,12 @@ void irlap_resend_rejected_frames(struct irlap_cb *self, int command)
                /*
                 *  Set poll bit on the last frame retransmitted
                 */
-               if (count-- == 1)
+               if (skb_queue_is_last(&self->wx_list, skb))
                        tx_skb->data[1] |= PF_BIT; /* Set p/f bit */
                else
                        tx_skb->data[1] &= ~PF_BIT; /* Clear p/f bit */
 
                irlap_send_i_frame(self, tx_skb, command);
-
-               /*
-                *  If our skb is the last buffer in the list, then
-                *  we are finished, if not, move to the next sk-buffer
-                */
-               if (skb == skb_peek_tail(&self->wx_list))
-                       skb = NULL;
-               else
-                       skb = skb->next;
        }
 #if 0 /* Not yet */
        /*
index 2f05ec1037ab32322838dfd2cf851e66050ceb0c..8dd7ed7e7c1fa184d18a2eb711194e90a7495f76 100644 (file)
@@ -87,7 +87,7 @@ static int irda_nl_get_mode(struct sk_buff *skb, struct genl_info *info)
        if (!dev)
                return -ENODEV;
 
-       msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
+       msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
        if (!msg) {
                dev_put(dev);
                return -ENOMEM;
@@ -148,21 +148,8 @@ static struct genl_ops irda_nl_ops[] = {
 
 int irda_nl_register(void)
 {
-       int err, i;
-
-       err = genl_register_family(&irda_nl_family);
-       if (err)
-               return err;
-
-       for (i = 0; i < ARRAY_SIZE(irda_nl_ops); i++) {
-               err = genl_register_ops(&irda_nl_family, &irda_nl_ops[i]);
-               if (err)
-                       goto err_out;
-       }
-       return 0;
- err_out:
-       genl_unregister_family(&irda_nl_family);
-       return err;
+       return genl_register_family_with_ops(&irda_nl_family,
+               irda_nl_ops, ARRAY_SIZE(irda_nl_ops));
 }
 
 void irda_nl_unregister(void)
index b51c9187c3476652b2e4f1f01c4e7c52dc637e07..a9b3a6f9ea95f18f2ea8325a72741fb61e0c14cf 100644 (file)
 #include <net/iucv/iucv.h>
 #include <net/iucv/af_iucv.h>
 
-#define CONFIG_IUCV_SOCK_DEBUG 1
-
-#define IPRMDATA 0x80
-#define VERSION "1.0"
+#define VERSION "1.1"
 
 static char iucv_userid[80];
 
@@ -44,6 +41,19 @@ static struct proto iucv_proto = {
        .obj_size       = sizeof(struct iucv_sock),
 };
 
+/* special AF_IUCV IPRM messages */
+static const u8 iprm_shutdown[8] =
+       {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
+
+#define TRGCLS_SIZE    (sizeof(((struct iucv_message *)0)->class))
+
+/* macros to set/get socket control buffer at correct offset */
+#define CB_TAG(skb)    ((skb)->cb)             /* iucv message tag */
+#define CB_TAG_LEN     (sizeof(((struct iucv_message *) 0)->tag))
+#define CB_TRGCLS(skb) ((skb)->cb + CB_TAG_LEN) /* iucv msg target class */
+#define CB_TRGCLS_LEN  (TRGCLS_SIZE)
+
+
 static void iucv_sock_kill(struct sock *sk);
 static void iucv_sock_close(struct sock *sk);
 
@@ -54,6 +64,7 @@ static void iucv_callback_connack(struct iucv_path *, u8 ipuser[16]);
 static int iucv_callback_connreq(struct iucv_path *, u8 ipvmid[8],
                                 u8 ipuser[16]);
 static void iucv_callback_connrej(struct iucv_path *, u8 ipuser[16]);
+static void iucv_callback_shutdown(struct iucv_path *, u8 ipuser[16]);
 
 static struct iucv_sock_list iucv_sk_list = {
        .lock = __RW_LOCK_UNLOCKED(iucv_sk_list.lock),
@@ -65,7 +76,8 @@ static struct iucv_handler af_iucv_handler = {
        .path_complete    = iucv_callback_connack,
        .path_severed     = iucv_callback_connrej,
        .message_pending  = iucv_callback_rx,
-       .message_complete = iucv_callback_txdone
+       .message_complete = iucv_callback_txdone,
+       .path_quiesced    = iucv_callback_shutdown,
 };
 
 static inline void high_nmcpy(unsigned char *dst, char *src)
@@ -78,6 +90,37 @@ static inline void low_nmcpy(unsigned char *dst, char *src)
        memcpy(&dst[8], src, 8);
 }
 
+/**
+ * iucv_msg_length() - Returns the length of an iucv message.
+ * @msg:       Pointer to struct iucv_message, MUST NOT be NULL
+ *
+ * The function returns the length of the specified iucv message @msg of data
+ * stored in a buffer and of data stored in the parameter list (PRMDATA).
+ *
+ * For IUCV_IPRMDATA, AF_IUCV uses the following convention to transport socket
+ * data:
+ *     PRMDATA[0..6]   socket data (max 7 bytes);
+ *     PRMDATA[7]      socket data length value (len is 0xff - PRMDATA[7])
+ *
+ * The socket data length is computed by substracting the socket data length
+ * value from 0xFF.
+ * If the socket data len is greater 7, then PRMDATA can be used for special
+ * notifications (see iucv_sock_shutdown); and further,
+ * if the socket data len is > 7, the function returns 8.
+ *
+ * Use this function to allocate socket buffers to store iucv message data.
+ */
+static inline size_t iucv_msg_length(struct iucv_message *msg)
+{
+       size_t datalen;
+
+       if (msg->flags & IUCV_IPRMDATA) {
+               datalen = 0xff - msg->rmmsg[7];
+               return (datalen < 8) ? datalen : 8;
+       }
+       return msg->length;
+}
+
 /* Timers */
 static void iucv_sock_timeout(unsigned long arg)
 {
@@ -225,6 +268,8 @@ static struct sock *iucv_sock_alloc(struct socket *sock, int proto, gfp_t prio)
        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);
 
@@ -248,11 +293,22 @@ static int iucv_sock_create(struct net *net, struct socket *sock, int protocol)
 {
        struct sock *sk;
 
-       if (sock->type != SOCK_STREAM)
-               return -ESOCKTNOSUPPORT;
+       if (protocol && protocol != PF_IUCV)
+               return -EPROTONOSUPPORT;
 
        sock->state = SS_UNCONNECTED;
-       sock->ops = &iucv_sock_ops;
+
+       switch (sock->type) {
+       case SOCK_STREAM:
+               sock->ops = &iucv_sock_ops;
+               break;
+       case SOCK_SEQPACKET:
+               /* currently, proto ops can handle both sk types */
+               sock->ops = &iucv_sock_ops;
+               break;
+       default:
+               return -ESOCKTNOSUPPORT;
+       }
 
        sk = iucv_sock_alloc(sock, protocol, GFP_KERNEL);
        if (!sk)
@@ -463,11 +519,9 @@ static int iucv_sock_connect(struct socket *sock, struct sockaddr *addr,
        if (sk->sk_state != IUCV_OPEN && sk->sk_state != IUCV_BOUND)
                return -EBADFD;
 
-       if (sk->sk_type != SOCK_STREAM)
+       if (sk->sk_type != SOCK_STREAM && sk->sk_type != SOCK_SEQPACKET)
                return -EINVAL;
 
-       iucv = iucv_sk(sk);
-
        if (sk->sk_state == IUCV_OPEN) {
                err = iucv_sock_autobind(sk);
                if (unlikely(err))
@@ -486,8 +540,8 @@ static int iucv_sock_connect(struct socket *sock, struct sockaddr *addr,
 
        iucv = iucv_sk(sk);
        /* Create path. */
-       iucv->path = iucv_path_alloc(IUCV_QUEUELEN_DEFAULT,
-                                    IPRMDATA, GFP_KERNEL);
+       iucv->path = iucv_path_alloc(iucv->msglimit,
+                                    IUCV_IPRMDATA, GFP_KERNEL);
        if (!iucv->path) {
                err = -ENOMEM;
                goto done;
@@ -521,8 +575,7 @@ static int iucv_sock_connect(struct socket *sock, struct sockaddr *addr,
        }
 
        if (sk->sk_state == IUCV_DISCONN) {
-               release_sock(sk);
-               return -ECONNREFUSED;
+               err = -ECONNREFUSED;
        }
 
        if (err) {
@@ -545,7 +598,10 @@ static int iucv_sock_listen(struct socket *sock, int backlog)
        lock_sock(sk);
 
        err = -EINVAL;
-       if (sk->sk_state != IUCV_BOUND || sock->type != SOCK_STREAM)
+       if (sk->sk_state != IUCV_BOUND)
+               goto done;
+
+       if (sock->type != SOCK_STREAM && sock->type != SOCK_SEQPACKET)
                goto done;
 
        sk->sk_max_ack_backlog = backlog;
@@ -636,6 +692,30 @@ static int iucv_sock_getname(struct socket *sock, struct sockaddr *addr,
        return 0;
 }
 
+/**
+ * iucv_send_iprm() - Send socket data in parameter list of an iucv message.
+ * @path:      IUCV path
+ * @msg:       Pointer to a struct iucv_message
+ * @skb:       The socket data to send, skb->len MUST BE <= 7
+ *
+ * Send the socket data in the parameter list in the iucv message
+ * (IUCV_IPRMDATA). The socket data is stored at index 0 to 6 in the parameter
+ * list and the socket data len at index 7 (last byte).
+ * See also iucv_msg_length().
+ *
+ * Returns the error code from the iucv_message_send() call.
+ */
+static int iucv_send_iprm(struct iucv_path *path, struct iucv_message *msg,
+                         struct sk_buff *skb)
+{
+       u8 prmdata[8];
+
+       memcpy(prmdata, (void *) skb->data, skb->len);
+       prmdata[7] = 0xff - (u8) skb->len;
+       return iucv_message_send(path, msg, IUCV_IPRMDATA, 0,
+                                (void *) prmdata, 8);
+}
+
 static int iucv_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
                             struct msghdr *msg, size_t len)
 {
@@ -643,6 +723,8 @@ static int iucv_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
        struct iucv_sock *iucv = iucv_sk(sk);
        struct sk_buff *skb;
        struct iucv_message txmsg;
+       struct cmsghdr *cmsg;
+       int cmsg_done;
        char user_id[9];
        char appl_id[9];
        int err;
@@ -654,6 +736,10 @@ static int iucv_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
        if (msg->msg_flags & MSG_OOB)
                return -EOPNOTSUPP;
 
+       /* SOCK_SEQPACKET: we do not support segmented records */
+       if (sk->sk_type == SOCK_SEQPACKET && !(msg->msg_flags & MSG_EOR))
+               return -EOPNOTSUPP;
+
        lock_sock(sk);
 
        if (sk->sk_shutdown & SEND_SHUTDOWN) {
@@ -662,6 +748,52 @@ static int iucv_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
        }
 
        if (sk->sk_state == IUCV_CONNECTED) {
+               /* initialize defaults */
+               cmsg_done   = 0;        /* check for duplicate headers */
+               txmsg.class = 0;
+
+               /* iterate over control messages */
+               for (cmsg = CMSG_FIRSTHDR(msg); cmsg;
+                    cmsg = CMSG_NXTHDR(msg, cmsg)) {
+
+                       if (!CMSG_OK(msg, cmsg)) {
+                               err = -EINVAL;
+                               goto out;
+                       }
+
+                       if (cmsg->cmsg_level != SOL_IUCV)
+                               continue;
+
+                       if (cmsg->cmsg_type & cmsg_done) {
+                               err = -EINVAL;
+                               goto out;
+                       }
+                       cmsg_done |= cmsg->cmsg_type;
+
+                       switch (cmsg->cmsg_type) {
+                       case SCM_IUCV_TRGCLS:
+                               if (cmsg->cmsg_len != CMSG_LEN(TRGCLS_SIZE)) {
+                                       err = -EINVAL;
+                                       goto out;
+                               }
+
+                               /* set iucv message target class */
+                               memcpy(&txmsg.class,
+                                       (void *) CMSG_DATA(cmsg), TRGCLS_SIZE);
+
+                               break;
+
+                       default:
+                               err = -EINVAL;
+                               goto out;
+                               break;
+                       }
+               }
+
+               /* allocate one skb for each iucv message:
+                * 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 */
                if (!(skb = sock_alloc_send_skb(sk, len,
                                                msg->msg_flags & MSG_DONTWAIT,
                                                &err)))
@@ -672,13 +804,33 @@ static int iucv_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
                        goto fail;
                }
 
-               txmsg.class = 0;
-               memcpy(&txmsg.class, skb->data, skb->len >= 4 ? 4 : skb->len);
+               /* increment and save iucv message tag for msg_completion cbk */
                txmsg.tag = iucv->send_tag++;
-               memcpy(skb->cb, &txmsg.tag, 4);
+               memcpy(CB_TAG(skb), &txmsg.tag, CB_TAG_LEN);
                skb_queue_tail(&iucv->send_skb_q, skb);
-               err = iucv_message_send(iucv->path, &txmsg, 0, 0,
-                                       (void *) skb->data, skb->len);
+
+               if (((iucv->path->flags & IUCV_IPRMDATA) & iucv->flags)
+                   && skb->len <= 7) {
+                       err = iucv_send_iprm(iucv->path, &txmsg, skb);
+
+                       /* on success: there is no message_complete callback
+                        * for an IPRMDATA msg; remove skb from send queue */
+                       if (err == 0) {
+                               skb_unlink(skb, &iucv->send_skb_q);
+                               kfree_skb(skb);
+                       }
+
+                       /* this error should never happen since the
+                        * IUCV_IPRMDATA path flag is set... sever path */
+                       if (err == 0x15) {
+                               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,
+                                               (void *) skb->data, skb->len);
                if (err) {
                        if (err == 3) {
                                user_id[8] = 0;
@@ -725,6 +877,10 @@ static int iucv_fragment_skb(struct sock *sk, struct sk_buff *skb, int len)
                if (!nskb)
                        return -ENOMEM;
 
+               /* copy target class to control buffer of new skb */
+               memcpy(CB_TRGCLS(nskb), CB_TRGCLS(skb), CB_TRGCLS_LEN);
+
+               /* copy data fragment */
                memcpy(nskb->data, skb->data + copied, size);
                copied += size;
                dataleft -= size;
@@ -744,19 +900,33 @@ static void iucv_process_message(struct sock *sk, struct sk_buff *skb,
                                 struct iucv_message *msg)
 {
        int rc;
+       unsigned int len;
+
+       len = iucv_msg_length(msg);
 
-       if (msg->flags & IPRMDATA) {
-               skb->data = NULL;
-               skb->len = 0;
+       /* store msg target class in the second 4 bytes of skb ctrl buffer */
+       /* Note: the first 4 bytes are reserved for msg tag */
+       memcpy(CB_TRGCLS(skb), &msg->class, CB_TRGCLS_LEN);
+
+       /* check for special IPRM messages (e.g. iucv_sock_shutdown) */
+       if ((msg->flags & IUCV_IPRMDATA) && len > 7) {
+               if (memcmp(msg->rmmsg, iprm_shutdown, 8) == 0) {
+                       skb->data = NULL;
+                       skb->len = 0;
+               }
        } else {
-               rc = iucv_message_receive(path, msg, 0, skb->data,
-                                         msg->length, NULL);
+               rc = iucv_message_receive(path, msg, msg->flags & IUCV_IPRMDATA,
+                                         skb->data, len, NULL);
                if (rc) {
                        kfree_skb(skb);
                        return;
                }
-               if (skb->truesize >= sk->sk_rcvbuf / 4) {
-                       rc = iucv_fragment_skb(sk, skb, msg->length);
+               /* we need to fragment iucv messages for SOCK_STREAM only;
+                * for SOCK_SEQPACKET, it is only relevant if we support
+                * record segmentation using MSG_EOR (see also recvmsg()) */
+               if (sk->sk_type == SOCK_STREAM &&
+                   skb->truesize >= sk->sk_rcvbuf / 4) {
+                       rc = iucv_fragment_skb(sk, skb, len);
                        kfree_skb(skb);
                        skb = NULL;
                        if (rc) {
@@ -767,7 +937,7 @@ static void iucv_process_message(struct sock *sk, struct sk_buff *skb,
                } else {
                        skb_reset_transport_header(skb);
                        skb_reset_network_header(skb);
-                       skb->len = msg->length;
+                       skb->len = len;
                }
        }
 
@@ -782,7 +952,7 @@ static void iucv_process_message_q(struct sock *sk)
        struct sock_msg_q *p, *n;
 
        list_for_each_entry_safe(p, n, &iucv->message_q.list, list) {
-               skb = alloc_skb(p->msg.length, GFP_ATOMIC | GFP_DMA);
+               skb = alloc_skb(iucv_msg_length(&p->msg), GFP_ATOMIC | GFP_DMA);
                if (!skb)
                        break;
                iucv_process_message(sk, skb, p->path, &p->msg);
@@ -799,7 +969,7 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
        int noblock = flags & MSG_DONTWAIT;
        struct sock *sk = sock->sk;
        struct iucv_sock *iucv = iucv_sk(sk);
-       int target, copied = 0;
+       unsigned int copied, rlen;
        struct sk_buff *skb, *rskb, *cskb;
        int err = 0;
 
@@ -812,8 +982,6 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
        if (flags & (MSG_OOB))
                return -EOPNOTSUPP;
 
-       target = sock_rcvlowat(sk, flags & MSG_WAITALL, len);
-
        /* receive/dequeue next skb:
         * the function understands MSG_PEEK and, thus, does not dequeue skb */
        skb = skb_recv_datagram(sk, flags, noblock, &err);
@@ -823,25 +991,45 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
                return err;
        }
 
-       copied = min_t(unsigned int, skb->len, len);
+       rlen   = skb->len;              /* real length of skb */
+       copied = min_t(unsigned int, rlen, len);
 
        cskb = skb;
        if (memcpy_toiovec(msg->msg_iov, cskb->data, copied)) {
-               skb_queue_head(&sk->sk_receive_queue, skb);
-               if (copied == 0)
-                       return -EFAULT;
-               goto done;
+               if (!(flags & MSG_PEEK))
+                       skb_queue_head(&sk->sk_receive_queue, skb);
+               return -EFAULT;
        }
 
-       len -= copied;
+       /* SOCK_SEQPACKET: set MSG_TRUNC if recv buf size is too small */
+       if (sk->sk_type == SOCK_SEQPACKET) {
+               if (copied < rlen)
+                       msg->msg_flags |= MSG_TRUNC;
+               /* each iucv message contains a complete record */
+               msg->msg_flags |= MSG_EOR;
+       }
+
+       /* create control message to store iucv msg target class:
+        * get the trgcls from the control buffer of the skb due to
+        * fragmentation of original iucv message. */
+       err = put_cmsg(msg, SOL_IUCV, SCM_IUCV_TRGCLS,
+                       CB_TRGCLS_LEN, CB_TRGCLS(skb));
+       if (err) {
+               if (!(flags & MSG_PEEK))
+                       skb_queue_head(&sk->sk_receive_queue, skb);
+               return err;
+       }
 
        /* Mark read part of skb as used */
        if (!(flags & MSG_PEEK)) {
-               skb_pull(skb, copied);
 
-               if (skb->len) {
-                       skb_queue_head(&sk->sk_receive_queue, skb);
-                       goto done;
+               /* SOCK_STREAM: re-queue skb if it contains unreceived data */
+               if (sk->sk_type == SOCK_STREAM) {
+                       skb_pull(skb, copied);
+                       if (skb->len) {
+                               skb_queue_head(&sk->sk_receive_queue, skb);
+                               goto done;
+                       }
                }
 
                kfree_skb(skb);
@@ -866,7 +1054,11 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
        }
 
 done:
-       return err ? : copied;
+       /* SOCK_SEQPACKET: return real length if MSG_TRUNC is set */
+       if (sk->sk_type == SOCK_SEQPACKET && (flags & MSG_TRUNC))
+               copied = rlen;
+
+       return copied;
 }
 
 static inline unsigned int iucv_accept_poll(struct sock *parent)
@@ -928,7 +1120,6 @@ static int iucv_sock_shutdown(struct socket *sock, int how)
        struct iucv_sock *iucv = iucv_sk(sk);
        struct iucv_message txmsg;
        int err = 0;
-       u8 prmmsg[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
 
        how++;
 
@@ -953,7 +1144,7 @@ static int iucv_sock_shutdown(struct socket *sock, int how)
                txmsg.class = 0;
                txmsg.tag = 0;
                err = iucv_message_send(iucv->path, &txmsg, IUCV_IPRMDATA, 0,
-                                       (void *) prmmsg, 8);
+                                       (void *) iprm_shutdown, 8);
                if (err) {
                        switch (err) {
                        case 1:
@@ -1007,6 +1198,98 @@ static int iucv_sock_release(struct socket *sock)
        return err;
 }
 
+/* getsockopt and setsockopt */
+static int iucv_sock_setsockopt(struct socket *sock, int level, int optname,
+                               char __user *optval, int optlen)
+{
+       struct sock *sk = sock->sk;
+       struct iucv_sock *iucv = iucv_sk(sk);
+       int val;
+       int rc;
+
+       if (level != SOL_IUCV)
+               return -ENOPROTOOPT;
+
+       if (optlen < sizeof(int))
+               return -EINVAL;
+
+       if (get_user(val, (int __user *) optval))
+               return -EFAULT;
+
+       rc = 0;
+
+       lock_sock(sk);
+       switch (optname) {
+       case SO_IPRMDATA_MSG:
+               if (val)
+                       iucv->flags |= IUCV_IPRMDATA;
+               else
+                       iucv->flags &= ~IUCV_IPRMDATA;
+               break;
+       case SO_MSGLIMIT:
+               switch (sk->sk_state) {
+               case IUCV_OPEN:
+               case IUCV_BOUND:
+                       if (val < 1 || val > (u16)(~0))
+                               rc = -EINVAL;
+                       else
+                               iucv->msglimit = val;
+                       break;
+               default:
+                       rc = -EINVAL;
+                       break;
+               }
+               break;
+       default:
+               rc = -ENOPROTOOPT;
+               break;
+       }
+       release_sock(sk);
+
+       return rc;
+}
+
+static int iucv_sock_getsockopt(struct socket *sock, int level, int optname,
+                               char __user *optval, int __user *optlen)
+{
+       struct sock *sk = sock->sk;
+       struct iucv_sock *iucv = iucv_sk(sk);
+       int val, len;
+
+       if (level != SOL_IUCV)
+               return -ENOPROTOOPT;
+
+       if (get_user(len, optlen))
+               return -EFAULT;
+
+       if (len < 0)
+               return -EINVAL;
+
+       len = min_t(unsigned int, len, sizeof(int));
+
+       switch (optname) {
+       case SO_IPRMDATA_MSG:
+               val = (iucv->flags & IUCV_IPRMDATA) ? 1 : 0;
+               break;
+       case SO_MSGLIMIT:
+               lock_sock(sk);
+               val = (iucv->path != NULL) ? iucv->path->msglim /* connected */
+                                          : iucv->msglimit;    /* default */
+               release_sock(sk);
+               break;
+       default:
+               return -ENOPROTOOPT;
+       }
+
+       if (put_user(len, optlen))
+               return -EFAULT;
+       if (copy_to_user(optval, &val, len))
+               return -EFAULT;
+
+       return 0;
+}
+
+
 /* Callback wrappers - called from iucv base support */
 static int iucv_callback_connreq(struct iucv_path *path,
                                 u8 ipvmid[8], u8 ipuser[16])
@@ -1060,7 +1343,7 @@ static int iucv_callback_connreq(struct iucv_path *path,
        }
 
        /* Create the new socket */
-       nsk = iucv_sock_alloc(NULL, SOCK_STREAM, GFP_ATOMIC);
+       nsk = iucv_sock_alloc(NULL, sk->sk_type, GFP_ATOMIC);
        if (!nsk) {
                err = iucv_path_sever(path, user_data);
                iucv_path_free(path);
@@ -1083,7 +1366,9 @@ static int iucv_callback_connreq(struct iucv_path *path,
        memcpy(nuser_data + 8, niucv->src_name, 8);
        ASCEBC(nuser_data + 8, 8);
 
-       path->msglim = IUCV_QUEUELEN_DEFAULT;
+       /* 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);
        if (err) {
                err = iucv_path_sever(path, user_data);
@@ -1131,19 +1416,17 @@ static void iucv_callback_rx(struct iucv_path *path, struct iucv_message *msg)
                goto save_message;
 
        len = atomic_read(&sk->sk_rmem_alloc);
-       len += msg->length + sizeof(struct sk_buff);
+       len += iucv_msg_length(msg) + sizeof(struct sk_buff);
        if (len > sk->sk_rcvbuf)
                goto save_message;
 
-       skb = alloc_skb(msg->length, GFP_ATOMIC | GFP_DMA);
+       skb = alloc_skb(iucv_msg_length(msg), GFP_ATOMIC | GFP_DMA);
        if (!skb)
                goto save_message;
 
        iucv_process_message(sk, skb, path, msg);
        goto out_unlock;
 
-       return;
-
 save_message:
        save_msg = kzalloc(sizeof(struct sock_msg_q), GFP_ATOMIC | GFP_DMA);
        if (!save_msg)
@@ -1170,7 +1453,7 @@ static void iucv_callback_txdone(struct iucv_path *path,
                spin_lock_irqsave(&list->lock, flags);
 
                while (list_skb != (struct sk_buff *)list) {
-                       if (!memcmp(&msg->tag, list_skb->cb, 4)) {
+                       if (!memcmp(&msg->tag, CB_TAG(list_skb), CB_TAG_LEN)) {
                                this = list_skb;
                                break;
                        }
@@ -1206,6 +1489,21 @@ static void iucv_callback_connrej(struct iucv_path *path, u8 ipuser[16])
        sk->sk_state_change(sk);
 }
 
+/* called if the other communication side shuts down its RECV direction;
+ * in turn, the callback sets SEND_SHUTDOWN to disable sending of data.
+ */
+static void iucv_callback_shutdown(struct iucv_path *path, u8 ipuser[16])
+{
+       struct sock *sk = path->private;
+
+       bh_lock_sock(sk);
+       if (sk->sk_state != IUCV_CLOSED) {
+               sk->sk_shutdown |= SEND_SHUTDOWN;
+               sk->sk_state_change(sk);
+       }
+       bh_unlock_sock(sk);
+}
+
 static struct proto_ops iucv_sock_ops = {
        .family         = PF_IUCV,
        .owner          = THIS_MODULE,
@@ -1222,8 +1520,8 @@ static struct proto_ops iucv_sock_ops = {
        .mmap           = sock_no_mmap,
        .socketpair     = sock_no_socketpair,
        .shutdown       = iucv_sock_shutdown,
-       .setsockopt     = sock_no_setsockopt,
-       .getsockopt     = sock_no_getsockopt
+       .setsockopt     = iucv_sock_setsockopt,
+       .getsockopt     = iucv_sock_getsockopt,
 };
 
 static struct net_proto_family iucv_sock_family_ops = {
index a35240f61ec3bad362fed2da6378920b3f4fcd99..61e8038a55ee300d3875ffcf01532624bc691dd6 100644 (file)
@@ -280,6 +280,7 @@ union iucv_param {
  * Anchor for per-cpu IUCV command parameter block.
  */
 static union iucv_param *iucv_param[NR_CPUS];
+static union iucv_param *iucv_param_irq[NR_CPUS];
 
 /**
  * iucv_call_b2f0
@@ -358,7 +359,7 @@ static void iucv_allow_cpu(void *data)
         *      0x10 - Flag to allow priority message completion interrupts
         *      0x08 - Flag to allow IUCV control interrupts
         */
-       parm = iucv_param[cpu];
+       parm = iucv_param_irq[cpu];
        memset(parm, 0, sizeof(union iucv_param));
        parm->set_mask.ipmask = 0xf8;
        iucv_call_b2f0(IUCV_SETMASK, parm);
@@ -379,7 +380,7 @@ static void iucv_block_cpu(void *data)
        union iucv_param *parm;
 
        /* Disable all iucv interrupts. */
-       parm = iucv_param[cpu];
+       parm = iucv_param_irq[cpu];
        memset(parm, 0, sizeof(union iucv_param));
        iucv_call_b2f0(IUCV_SETMASK, parm);
 
@@ -403,7 +404,7 @@ static void iucv_declare_cpu(void *data)
                return;
 
        /* Declare interrupt buffer. */
-       parm = iucv_param[cpu];
+       parm = iucv_param_irq[cpu];
        memset(parm, 0, sizeof(union iucv_param));
        parm->db.ipbfadr1 = virt_to_phys(iucv_irq_data[cpu]);
        rc = iucv_call_b2f0(IUCV_DECLARE_BUFFER, parm);
@@ -460,7 +461,7 @@ static void iucv_retrieve_cpu(void *data)
        iucv_block_cpu(NULL);
 
        /* Retrieve interrupt buffer. */
-       parm = iucv_param[cpu];
+       parm = iucv_param_irq[cpu];
        iucv_call_b2f0(IUCV_RETRIEVE_BUFFER, parm);
 
        /* Clear indication that an iucv buffer exists for this cpu. */
@@ -574,11 +575,22 @@ static int __cpuinit iucv_cpu_notify(struct notifier_block *self,
                        iucv_irq_data[cpu] = NULL;
                        return NOTIFY_BAD;
                }
+               iucv_param_irq[cpu] = kmalloc_node(sizeof(union iucv_param),
+                                       GFP_KERNEL|GFP_DMA, cpu_to_node(cpu));
+               if (!iucv_param_irq[cpu]) {
+                       kfree(iucv_param[cpu]);
+                       iucv_param[cpu] = NULL;
+                       kfree(iucv_irq_data[cpu]);
+                       iucv_irq_data[cpu] = NULL;
+                       return NOTIFY_BAD;
+               }
                break;
        case CPU_UP_CANCELED:
        case CPU_UP_CANCELED_FROZEN:
        case CPU_DEAD:
        case CPU_DEAD_FROZEN:
+               kfree(iucv_param_irq[cpu]);
+               iucv_param_irq[cpu] = NULL;
                kfree(iucv_param[cpu]);
                iucv_param[cpu] = NULL;
                kfree(iucv_irq_data[cpu]);
@@ -625,7 +637,7 @@ static int iucv_sever_pathid(u16 pathid, u8 userdata[16])
 {
        union iucv_param *parm;
 
-       parm = iucv_param[smp_processor_id()];
+       parm = iucv_param_irq[smp_processor_id()];
        memset(parm, 0, sizeof(union iucv_param));
        if (userdata)
                memcpy(parm->ctrl.ipuser, userdata, sizeof(parm->ctrl.ipuser));
@@ -918,10 +930,8 @@ int iucv_path_sever(struct iucv_path *path, u8 userdata[16])
        if (iucv_active_cpu != smp_processor_id())
                spin_lock_bh(&iucv_table_lock);
        rc = iucv_sever_pathid(path->pathid, userdata);
-       if (!rc) {
-               iucv_path_table[path->pathid] = NULL;
-               list_del_init(&path->list);
-       }
+       iucv_path_table[path->pathid] = NULL;
+       list_del_init(&path->list);
        if (iucv_active_cpu != smp_processor_id())
                spin_unlock_bh(&iucv_table_lock);
        preempt_enable();
@@ -1378,6 +1388,8 @@ static void iucv_path_complete(struct iucv_irq_data *data)
        struct iucv_path_complete *ipc = (void *) data;
        struct iucv_path *path = iucv_path_table[ipc->ippathid];
 
+       if (path)
+               path->flags = ipc->ipflags1;
        if (path && path->handler && path->handler->path_complete)
                path->handler->path_complete(path, ipc->ipuser);
 }
@@ -1413,7 +1425,7 @@ static void iucv_path_severed(struct iucv_irq_data *data)
        else {
                iucv_sever_pathid(path->pathid, NULL);
                iucv_path_table[path->pathid] = NULL;
-               list_del_init(&path->list);
+               list_del(&path->list);
                iucv_path_free(path);
        }
 }
@@ -1717,6 +1729,13 @@ static int __init iucv_init(void)
                        rc = -ENOMEM;
                        goto out_free;
                }
+               iucv_param_irq[cpu] = kmalloc_node(sizeof(union iucv_param),
+                                 GFP_KERNEL|GFP_DMA, cpu_to_node(cpu));
+               if (!iucv_param_irq[cpu]) {
+                       rc = -ENOMEM;
+                       goto out_free;
+               }
+
        }
        rc = register_hotcpu_notifier(&iucv_cpu_notifier);
        if (rc)
@@ -1734,6 +1753,8 @@ out_cpu:
        unregister_hotcpu_notifier(&iucv_cpu_notifier);
 out_free:
        for_each_possible_cpu(cpu) {
+               kfree(iucv_param_irq[cpu]);
+               iucv_param_irq[cpu] = NULL;
                kfree(iucv_param[cpu]);
                iucv_param[cpu] = NULL;
                kfree(iucv_irq_data[cpu]);
@@ -1764,6 +1785,8 @@ static void __exit iucv_exit(void)
        spin_unlock_irq(&iucv_queue_lock);
        unregister_hotcpu_notifier(&iucv_cpu_notifier);
        for_each_possible_cpu(cpu) {
+               kfree(iucv_param_irq[cpu]);
+               iucv_param_irq[cpu] = NULL;
                kfree(iucv_param[cpu]);
                iucv_param[cpu] = NULL;
                kfree(iucv_irq_data[cpu]);
index febae702685cf58726918601bc613caba15f3af6..9208cf5f2bd554fb4d66fba51c327bcc3d7a5aae 100644 (file)
@@ -935,7 +935,7 @@ static int llc_ui_getname(struct socket *sock, struct sockaddr *uaddr,
 
                if (llc->dev) {
                        sllc.sllc_arphrd = llc->dev->type;
-                       memcpy(&sllc.sllc_mac, &llc->dev->dev_addr,
+                       memcpy(&sllc.sllc_mac, llc->dev->dev_addr,
                               IFHWADDRLEN);
                }
        }
index 3477624a4906ec3fc65957a1eb1567f0864153f4..c6bab39b018e75174874432ff06edb1890f3fd5e 100644 (file)
@@ -79,10 +79,6 @@ int llc_conn_state_process(struct sock *sk, struct sk_buff *skb)
 
        if (unlikely(!ev->ind_prim && !ev->cfm_prim)) {
                /* indicate or confirm not required */
-               /* XXX this is not very pretty, perhaps we should store
-                * XXX indicate/confirm-needed state in the llc_conn_state_ev
-                * XXX control block of the SKB instead? -DaveM
-                */
                if (!skb->next)
                        goto out_kfree_skb;
                goto out_skb_put;
index ecc3faf9f11ace6c5bb69153cdb618751433126a..ba2643a43c73c662236ad8f79144dba39d5dcfad 100644 (file)
@@ -1,16 +1,35 @@
 config MAC80211
        tristate "Generic IEEE 802.11 Networking Stack (mac80211)"
+       depends on CFG80211
        select CRYPTO
        select CRYPTO_ECB
        select CRYPTO_ARC4
        select CRYPTO_AES
        select CRC32
        select WIRELESS_EXT
-       select CFG80211
        ---help---
          This option enables the hardware independent IEEE 802.11
          networking stack.
 
+comment "CFG80211 needs to be enabled for MAC80211"
+       depends on CFG80211=n
+
+config MAC80211_DEFAULT_PS
+       bool "enable powersave by default"
+       depends on MAC80211
+       default y
+       help
+         This option enables powersave mode by default.
+
+         If this causes your applications to misbehave you should fix your
+         applications instead -- they need to register their network
+         latency requirement, see Documentation/power/pm_qos_interface.txt.
+
+config MAC80211_DEFAULT_PS_VALUE
+       int
+       default 1 if MAC80211_DEFAULT_PS
+       default 0
+
 menu "Rate control algorithm selection"
        depends on MAC80211 != n
 
index 07656d830bc4d7cec8a9152b9e28d1495dbe1809..bc064d7933ff692e2728bfc68c81ded152c930c1 100644 (file)
 #include <linux/ieee80211.h>
 #include <net/mac80211.h>
 #include "ieee80211_i.h"
+#include "driver-ops.h"
 
 void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
                                    u16 initiator, u16 reason)
 {
        struct ieee80211_local *local = sta->local;
-       struct ieee80211_hw *hw = &local->hw;
        int i;
 
        /* check if TID is in operational state */
@@ -41,8 +41,8 @@ void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
               sta->sta.addr, tid);
 #endif /* CONFIG_MAC80211_HT_DEBUG */
 
-       if (local->ops->ampdu_action(hw, IEEE80211_AMPDU_RX_STOP,
-                                    &sta->sta, tid, NULL))
+       if (drv_ampdu_action(local, IEEE80211_AMPDU_RX_STOP,
+                            &sta->sta, tid, NULL))
                printk(KERN_DEBUG "HW problem - can not stop rx "
                                "aggregation for tid %d\n", tid);
 
@@ -68,6 +68,7 @@ void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
        spin_lock_bh(&sta->lock);
        /* free resources */
        kfree(sta->ampdu_mlme.tid_rx[tid]->reorder_buf);
+       kfree(sta->ampdu_mlme.tid_rx[tid]->reorder_time);
 
        if (!sta->ampdu_mlme.tid_rx[tid]->shutdown) {
                kfree(sta->ampdu_mlme.tid_rx[tid]);
@@ -268,19 +269,23 @@ void ieee80211_process_addba_request(struct ieee80211_local *local,
        /* prepare reordering buffer */
        tid_agg_rx->reorder_buf =
                kcalloc(buf_size, sizeof(struct sk_buff *), GFP_ATOMIC);
-       if (!tid_agg_rx->reorder_buf) {
+       tid_agg_rx->reorder_time =
+               kcalloc(buf_size, sizeof(unsigned long), GFP_ATOMIC);
+       if (!tid_agg_rx->reorder_buf || !tid_agg_rx->reorder_time) {
 #ifdef CONFIG_MAC80211_HT_DEBUG
                if (net_ratelimit())
                        printk(KERN_ERR "can not allocate reordering buffer "
                               "to tid %d\n", tid);
 #endif
+               kfree(tid_agg_rx->reorder_buf);
+               kfree(tid_agg_rx->reorder_time);
                kfree(sta->ampdu_mlme.tid_rx[tid]);
+               sta->ampdu_mlme.tid_rx[tid] = NULL;
                goto end;
        }
 
-       if (local->ops->ampdu_action)
-               ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_RX_START,
-                                              &sta->sta, tid, &start_seq_num);
+       ret = drv_ampdu_action(local, IEEE80211_AMPDU_RX_START,
+                              &sta->sta, tid, &start_seq_num);
 #ifdef CONFIG_MAC80211_HT_DEBUG
        printk(KERN_DEBUG "Rx A-MPDU request on tid %d result %d\n", tid, ret);
 #endif /* CONFIG_MAC80211_HT_DEBUG */
index 947aaaad35d26b03f355299e15d26a7f2514367e..9e5762ad307d9faa55d4bd11400c5d76e7852dcc 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/ieee80211.h>
 #include <net/mac80211.h>
 #include "ieee80211_i.h"
+#include "driver-ops.h"
 #include "wme.h"
 
 /**
@@ -131,11 +132,14 @@ static int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
 
        state = &sta->ampdu_mlme.tid_state_tx[tid];
 
+       if (*state == HT_AGG_STATE_OPERATIONAL)
+               sta->ampdu_mlme.addba_req_num[tid] = 0;
+
        *state = HT_AGG_STATE_REQ_STOP_BA_MSK |
                (initiator << HT_AGG_STATE_INITIATOR_SHIFT);
 
-       ret = local->ops->ampdu_action(&local->hw, IEEE80211_AMPDU_TX_STOP,
-                                      &sta->sta, tid, NULL);
+       ret = drv_ampdu_action(local, IEEE80211_AMPDU_TX_STOP,
+                              &sta->sta, tid, NULL);
 
        /* HW shall not deny going back to legacy */
        if (WARN_ON(ret)) {
@@ -306,8 +310,8 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
 
        start_seq_num = sta->tid_seq[tid];
 
-       ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_TX_START,
-                                      &sta->sta, tid, &start_seq_num);
+       ret = drv_ampdu_action(local, IEEE80211_AMPDU_TX_START,
+                              &sta->sta, tid, &start_seq_num);
 
        if (ret) {
 #ifdef CONFIG_MAC80211_HT_DEBUG
@@ -336,6 +340,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
                         sta->ampdu_mlme.tid_tx[tid]->dialog_token,
                         sta->ampdu_mlme.tid_tx[tid]->ssn,
                         0x40, 5000);
+       sta->ampdu_mlme.addba_req_num[tid]++;
        /* activate the timer for the recipient's addBA response */
        sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.expires =
                                jiffies + ADDBA_RESP_INTERVAL;
@@ -418,8 +423,8 @@ static void ieee80211_agg_tx_operational(struct ieee80211_local *local,
        ieee80211_agg_splice_finish(local, sta, tid);
        spin_unlock(&local->ampdu_lock);
 
-       local->ops->ampdu_action(&local->hw, IEEE80211_AMPDU_TX_OPERATIONAL,
-                                &sta->sta, tid, NULL);
+       drv_ampdu_action(local, IEEE80211_AMPDU_TX_OPERATIONAL,
+                        &sta->sta, tid, NULL);
 }
 
 void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid)
@@ -605,7 +610,6 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid)
 
        *state = HT_AGG_STATE_IDLE;
        /* from now on packets are no longer put onto sta->pending */
-       sta->ampdu_mlme.addba_req_num[tid] = 0;
        kfree(sta->ampdu_mlme.tid_tx[tid]);
        sta->ampdu_mlme.tid_tx[tid] = NULL;
 
@@ -688,7 +692,6 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
 
                sta->ampdu_mlme.addba_req_num[tid] = 0;
        } else {
-               sta->ampdu_mlme.addba_req_num[tid]++;
                ___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR);
        }
        spin_unlock_bh(&sta->lock);
index e677b751d46857db80d163aa58bdbff04a116348..3f47276caeb85dcf7244270ff64d461979537be1 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/rcupdate.h>
 #include <net/cfg80211.h>
 #include "ieee80211_i.h"
+#include "driver-ops.h"
 #include "cfg.h"
 #include "rate.h"
 #include "mesh.h"
@@ -111,7 +112,7 @@ static int ieee80211_change_iface(struct wiphy *wiphy, int ifindex,
 }
 
 static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
-                            u8 key_idx, u8 *mac_addr,
+                            u8 key_idx, const u8 *mac_addr,
                             struct key_params *params)
 {
        struct ieee80211_sub_if_data *sdata;
@@ -140,7 +141,8 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
                return -EINVAL;
        }
 
-       key = ieee80211_key_alloc(alg, key_idx, params->key_len, params->key);
+       key = ieee80211_key_alloc(alg, key_idx, params->key_len, params->key,
+                                 params->seq_len, params->seq);
        if (!key)
                return -ENOMEM;
 
@@ -165,7 +167,7 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
 }
 
 static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
-                            u8 key_idx, u8 *mac_addr)
+                            u8 key_idx, const u8 *mac_addr)
 {
        struct ieee80211_sub_if_data *sdata;
        struct sta_info *sta;
@@ -207,7 +209,7 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
 }
 
 static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
-                            u8 key_idx, u8 *mac_addr, void *cookie,
+                            u8 key_idx, const u8 *mac_addr, void *cookie,
                             void (*callback)(void *cookie,
                                              struct key_params *params))
 {
@@ -245,12 +247,10 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
                iv32 = key->u.tkip.tx.iv32;
                iv16 = key->u.tkip.tx.iv16;
 
-               if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE &&
-                   sdata->local->ops->get_tkip_seq)
-                       sdata->local->ops->get_tkip_seq(
-                               local_to_hw(sdata->local),
-                               key->conf.hw_key_idx,
-                               &iv32, &iv16);
+               if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)
+                       drv_get_tkip_seq(sdata->local,
+                                        key->conf.hw_key_idx,
+                                        &iv32, &iv16);
 
                seq[0] = iv16 & 0xff;
                seq[1] = (iv16 >> 8) & 0xff;
@@ -451,18 +451,11 @@ static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata,
         * This is a kludge. beacon interval should really be part
         * of the beacon information.
         */
-       if (params->interval && (sdata->local->hw.conf.beacon_int !=
-                                params->interval)) {
-               sdata->local->hw.conf.beacon_int = params->interval;
-               err = ieee80211_hw_config(sdata->local,
-                                       IEEE80211_CONF_CHANGE_BEACON_INTERVAL);
-               if (err < 0)
-                       return err;
-               /*
-                * We updated some parameter so if below bails out
-                * it's not an error.
-                */
-               err = 0;
+       if (params->interval &&
+           (sdata->vif.bss_conf.beacon_int != params->interval)) {
+               sdata->vif.bss_conf.beacon_int = params->interval;
+               ieee80211_bss_info_change_notify(sdata,
+                                                BSS_CHANGED_BEACON_INT);
        }
 
        /* Need to have a beacon head if we don't have one yet */
@@ -528,8 +521,9 @@ static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata,
 
        kfree(old);
 
-       return ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON |
-                                         IEEE80211_IFCC_BEACON_ENABLED);
+       ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED |
+                                               BSS_CHANGED_BEACON);
+       return 0;
 }
 
 static int ieee80211_add_beacon(struct wiphy *wiphy, struct net_device *dev,
@@ -580,7 +574,8 @@ static int ieee80211_del_beacon(struct wiphy *wiphy, struct net_device *dev)
        synchronize_rcu();
        kfree(old);
 
-       return ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON_ENABLED);
+       ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED);
+       return 0;
 }
 
 /* Layer 2 Update frame (802.2 Type 1 LLC XID Update response) */
@@ -635,34 +630,45 @@ static void sta_apply_parameters(struct ieee80211_local *local,
        int i, j;
        struct ieee80211_supported_band *sband;
        struct ieee80211_sub_if_data *sdata = sta->sdata;
+       u32 mask, set;
 
        sband = local->hw.wiphy->bands[local->oper_channel->band];
 
-       /*
-        * FIXME: updating the flags is racy when this function is
-        *        called from ieee80211_change_station(), this will
-        *        be resolved in a future patch.
-        */
+       spin_lock_bh(&sta->lock);
+       mask = params->sta_flags_mask;
+       set = params->sta_flags_set;
 
-       if (params->station_flags & STATION_FLAG_CHANGED) {
-               spin_lock_bh(&sta->lock);
+       if (mask & BIT(NL80211_STA_FLAG_AUTHORIZED)) {
                sta->flags &= ~WLAN_STA_AUTHORIZED;
-               if (params->station_flags & STATION_FLAG_AUTHORIZED)
+               if (set & BIT(NL80211_STA_FLAG_AUTHORIZED))
                        sta->flags |= WLAN_STA_AUTHORIZED;
+       }
 
+       if (mask & BIT(NL80211_STA_FLAG_SHORT_PREAMBLE)) {
                sta->flags &= ~WLAN_STA_SHORT_PREAMBLE;
-               if (params->station_flags & STATION_FLAG_SHORT_PREAMBLE)
+               if (set & BIT(NL80211_STA_FLAG_SHORT_PREAMBLE))
                        sta->flags |= WLAN_STA_SHORT_PREAMBLE;
+       }
 
+       if (mask & BIT(NL80211_STA_FLAG_WME)) {
                sta->flags &= ~WLAN_STA_WME;
-               if (params->station_flags & STATION_FLAG_WME)
+               if (set & BIT(NL80211_STA_FLAG_WME))
                        sta->flags |= WLAN_STA_WME;
+       }
 
+       if (mask & BIT(NL80211_STA_FLAG_MFP)) {
                sta->flags &= ~WLAN_STA_MFP;
-               if (params->station_flags & STATION_FLAG_MFP)
+               if (set & BIT(NL80211_STA_FLAG_MFP))
                        sta->flags |= WLAN_STA_MFP;
-               spin_unlock_bh(&sta->lock);
        }
+       spin_unlock_bh(&sta->lock);
+
+       /*
+        * cfg80211 validates this (1-2007) and allows setting the AID
+        * only when creating a new station entry
+        */
+       if (params->aid)
+               sta->sta.aid = params->aid;
 
        /*
         * FIXME: updating the following information is racy when this
@@ -671,12 +677,6 @@ static void sta_apply_parameters(struct ieee80211_local *local,
         *        maybe we should just reject attemps to change it.
         */
 
-       if (params->aid) {
-               sta->sta.aid = params->aid;
-               if (sta->sta.aid > IEEE80211_MAX_AID)
-                       sta->sta.aid = 0; /* XXX: should this be an error? */
-       }
-
        if (params->listen_interval >= 0)
                sta->listen_interval = params->listen_interval;
 
@@ -1120,10 +1120,10 @@ static int ieee80211_set_txq_params(struct wiphy *wiphy,
        p.cw_max = params->cwmax;
        p.cw_min = params->cwmin;
        p.txop = params->txop;
-       if (local->ops->conf_tx(local_to_hw(local), params->queue, &p)) {
+       if (drv_conf_tx(local, params->queue, &p)) {
                printk(KERN_DEBUG "%s: failed to set TX queue "
-                      "parameters for queue %d\n", local->mdev->name,
-                      params->queue);
+                      "parameters for queue %d\n",
+                      wiphy_name(local->hw.wiphy), params->queue);
                return -EINVAL;
        }
 
@@ -1167,7 +1167,8 @@ static int ieee80211_scan(struct wiphy *wiphy,
 
        if (sdata->vif.type != NL80211_IFTYPE_STATION &&
            sdata->vif.type != NL80211_IFTYPE_ADHOC &&
-           sdata->vif.type != NL80211_IFTYPE_MESH_POINT)
+           sdata->vif.type != NL80211_IFTYPE_MESH_POINT &&
+           (sdata->vif.type != NL80211_IFTYPE_AP || sdata->u.ap.beacon))
                return -EOPNOTSUPP;
 
        return ieee80211_request_scan(sdata, req);
@@ -1255,9 +1256,22 @@ static int ieee80211_assoc(struct wiphy *wiphy, struct net_device *dev,
                sdata->u.mgd.flags |= IEEE80211_STA_AUTO_SSID_SEL;
 
        ret = ieee80211_sta_set_extra_ie(sdata, req->ie, req->ie_len);
-       if (ret)
+       if (ret && ret != -EALREADY)
                return ret;
 
+       if (req->use_mfp) {
+               sdata->u.mgd.mfp = IEEE80211_MFP_REQUIRED;
+               sdata->u.mgd.flags |= IEEE80211_STA_MFP_ENABLED;
+       } else {
+               sdata->u.mgd.mfp = IEEE80211_MFP_DISABLED;
+               sdata->u.mgd.flags &= ~IEEE80211_STA_MFP_ENABLED;
+       }
+
+       if (req->control_port)
+               sdata->u.mgd.flags |= IEEE80211_STA_CONTROL_PORT;
+       else
+               sdata->u.mgd.flags &= ~IEEE80211_STA_CONTROL_PORT;
+
        sdata->u.mgd.flags |= IEEE80211_STA_EXT_SME;
        sdata->u.mgd.state = IEEE80211_STA_MLME_ASSOCIATE;
        ieee80211_sta_req_auth(sdata);
@@ -1267,25 +1281,106 @@ static int ieee80211_assoc(struct wiphy *wiphy, struct net_device *dev,
 static int ieee80211_deauth(struct wiphy *wiphy, struct net_device *dev,
                            struct cfg80211_deauth_request *req)
 {
-       struct ieee80211_sub_if_data *sdata;
-
-       sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+       struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 
-       /* TODO: req->ie */
+       /* TODO: req->ie, req->peer_addr */
        return ieee80211_sta_deauthenticate(sdata, req->reason_code);
 }
 
 static int ieee80211_disassoc(struct wiphy *wiphy, struct net_device *dev,
                              struct cfg80211_disassoc_request *req)
 {
-       struct ieee80211_sub_if_data *sdata;
-
-       sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+       struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 
-       /* TODO: req->ie */
+       /* TODO: req->ie, req->peer_addr */
        return ieee80211_sta_disassociate(sdata, req->reason_code);
 }
 
+static int ieee80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
+                              struct cfg80211_ibss_params *params)
+{
+       struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+
+       return ieee80211_ibss_join(sdata, params);
+}
+
+static int ieee80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
+{
+       struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+
+       return ieee80211_ibss_leave(sdata);
+}
+
+static int ieee80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
+{
+       struct ieee80211_local *local = wiphy_priv(wiphy);
+       int err;
+
+       if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
+               err = drv_set_rts_threshold(local, wiphy->rts_threshold);
+
+               if (err)
+                       return err;
+       }
+
+       if (changed & WIPHY_PARAM_RETRY_SHORT)
+               local->hw.conf.short_frame_max_tx_count = wiphy->retry_short;
+       if (changed & WIPHY_PARAM_RETRY_LONG)
+               local->hw.conf.long_frame_max_tx_count = wiphy->retry_long;
+       if (changed &
+           (WIPHY_PARAM_RETRY_SHORT | WIPHY_PARAM_RETRY_LONG))
+               ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_RETRY_LIMITS);
+
+       return 0;
+}
+
+static int ieee80211_set_tx_power(struct wiphy *wiphy,
+                                 enum tx_power_setting type, int dbm)
+{
+       struct ieee80211_local *local = wiphy_priv(wiphy);
+       struct ieee80211_channel *chan = local->hw.conf.channel;
+       u32 changes = 0;
+
+       switch (type) {
+       case TX_POWER_AUTOMATIC:
+               local->user_power_level = -1;
+               break;
+       case TX_POWER_LIMITED:
+               if (dbm < 0)
+                       return -EINVAL;
+               local->user_power_level = dbm;
+               break;
+       case TX_POWER_FIXED:
+               if (dbm < 0)
+                       return -EINVAL;
+               /* TODO: move to cfg80211 when it knows the channel */
+               if (dbm > chan->max_power)
+                       return -EINVAL;
+               local->user_power_level = dbm;
+               break;
+       }
+
+       ieee80211_hw_config(local, changes);
+
+       return 0;
+}
+
+static int ieee80211_get_tx_power(struct wiphy *wiphy, int *dbm)
+{
+       struct ieee80211_local *local = wiphy_priv(wiphy);
+
+       *dbm = local->hw.conf.power_level;
+
+       return 0;
+}
+
+static void ieee80211_rfkill_poll(struct wiphy *wiphy)
+{
+       struct ieee80211_local *local = wiphy_priv(wiphy);
+
+       drv_rfkill_poll(local);
+}
+
 struct cfg80211_ops mac80211_config_ops = {
        .add_virtual_intf = ieee80211_add_iface,
        .del_virtual_intf = ieee80211_del_iface,
@@ -1322,4 +1417,10 @@ struct cfg80211_ops mac80211_config_ops = {
        .assoc = ieee80211_assoc,
        .deauth = ieee80211_deauth,
        .disassoc = ieee80211_disassoc,
+       .join_ibss = ieee80211_join_ibss,
+       .leave_ibss = ieee80211_leave_ibss,
+       .set_wiphy_params = ieee80211_set_wiphy_params,
+       .set_tx_power = ieee80211_set_tx_power,
+       .get_tx_power = ieee80211_get_tx_power,
+       .rfkill_poll = ieee80211_rfkill_poll,
 };
index 210b9b6fecd2a3676c8fe23393c22d87700228b4..11c72311f35b559a7ddcc55e63b002071fffe2d2 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/debugfs.h>
 #include <linux/rtnetlink.h>
 #include "ieee80211_i.h"
+#include "driver-ops.h"
 #include "rate.h"
 #include "debugfs.h"
 
@@ -51,14 +52,6 @@ static const struct file_operations name## _ops = {                  \
 
 DEBUGFS_READONLY_FILE(frequency, 20, "%d",
                      local->hw.conf.channel->center_freq);
-DEBUGFS_READONLY_FILE(rts_threshold, 20, "%d",
-                     local->rts_threshold);
-DEBUGFS_READONLY_FILE(fragmentation_threshold, 20, "%d",
-                     local->fragmentation_threshold);
-DEBUGFS_READONLY_FILE(short_retry_limit, 20, "%d",
-                     local->hw.conf.short_frame_max_tx_count);
-DEBUGFS_READONLY_FILE(long_retry_limit, 20, "%d",
-                     local->hw.conf.long_frame_max_tx_count);
 DEBUGFS_READONLY_FILE(total_ps_buffered, 20, "%d",
                      local->total_ps_buffered);
 DEBUGFS_READONLY_FILE(wep_iv, 20, "%#08x",
@@ -70,11 +63,10 @@ static ssize_t tsf_read(struct file *file, char __user *user_buf,
                             size_t count, loff_t *ppos)
 {
        struct ieee80211_local *local = file->private_data;
-       u64 tsf = 0;
+       u64 tsf;
        char buf[100];
 
-       if (local->ops->get_tsf)
-               tsf = local->ops->get_tsf(local_to_hw(local));
+       tsf = drv_get_tsf(local);
 
        snprintf(buf, sizeof(buf), "0x%016llx\n", (unsigned long long) tsf);
 
@@ -97,13 +89,13 @@ static ssize_t tsf_write(struct file *file,
 
        if (strncmp(buf, "reset", 5) == 0) {
                if (local->ops->reset_tsf) {
-                       local->ops->reset_tsf(local_to_hw(local));
+                       drv_reset_tsf(local);
                        printk(KERN_INFO "%s: debugfs reset TSF\n", wiphy_name(local->hw.wiphy));
                }
        } else {
                tsf = simple_strtoul(buf, NULL, 0);
                if (local->ops->set_tsf) {
-                       local->ops->set_tsf(local_to_hw(local), tsf);
+                       drv_set_tsf(local, tsf);
                        printk(KERN_INFO "%s: debugfs set TSF to %#018llx\n", wiphy_name(local->hw.wiphy), tsf);
                }
        }
@@ -135,6 +127,42 @@ static const struct file_operations reset_ops = {
        .open = mac80211_open_file_generic,
 };
 
+static ssize_t noack_read(struct file *file, char __user *user_buf,
+                         size_t count, loff_t *ppos)
+{
+       struct ieee80211_local *local = file->private_data;
+       int res;
+       char buf[10];
+
+       res = scnprintf(buf, sizeof(buf), "%d\n", local->wifi_wme_noack_test);
+
+       return simple_read_from_buffer(user_buf, count, ppos, buf, res);
+}
+
+static ssize_t noack_write(struct file *file,
+                          const char __user *user_buf,
+                          size_t count, loff_t *ppos)
+{
+       struct ieee80211_local *local = file->private_data;
+       char buf[10];
+       size_t len;
+
+       len = min(count, sizeof(buf) - 1);
+       if (copy_from_user(buf, user_buf, len))
+               return -EFAULT;
+       buf[len] = '\0';
+
+       local->wifi_wme_noack_test = !!simple_strtoul(buf, NULL, 0);
+
+       return count;
+}
+
+static const struct file_operations noack_ops = {
+       .read = noack_read,
+       .write = noack_write,
+       .open = mac80211_open_file_generic
+};
+
 /* statistics stuff */
 
 #define DEBUGFS_STATS_FILE(name, buflen, fmt, value...)                        \
@@ -150,14 +178,12 @@ static ssize_t format_devstat_counter(struct ieee80211_local *local,
        char buf[20];
        int res;
 
-       if (!local->ops->get_stats)
-               return -EOPNOTSUPP;
-
        rtnl_lock();
-       res = local->ops->get_stats(local_to_hw(local), &stats);
+       res = drv_get_stats(local, &stats);
        rtnl_unlock();
-       if (!res)
-               res = printvalue(&stats, buf, sizeof(buf));
+       if (res)
+               return res;
+       res = printvalue(&stats, buf, sizeof(buf));
        return simple_read_from_buffer(userbuf, count, ppos, buf, res);
 }
 
@@ -269,14 +295,11 @@ void debugfs_hw_add(struct ieee80211_local *local)
        local->debugfs.keys = debugfs_create_dir("keys", phyd);
 
        DEBUGFS_ADD(frequency);
-       DEBUGFS_ADD(rts_threshold);
-       DEBUGFS_ADD(fragmentation_threshold);
-       DEBUGFS_ADD(short_retry_limit);
-       DEBUGFS_ADD(long_retry_limit);
        DEBUGFS_ADD(total_ps_buffered);
        DEBUGFS_ADD(wep_iv);
        DEBUGFS_ADD(tsf);
        DEBUGFS_ADD_MODE(reset, 0200);
+       DEBUGFS_ADD(noack);
 
        statsd = debugfs_create_dir("statistics", phyd);
        local->debugfs.statistics = statsd;
@@ -324,14 +347,11 @@ void debugfs_hw_add(struct ieee80211_local *local)
 void debugfs_hw_del(struct ieee80211_local *local)
 {
        DEBUGFS_DEL(frequency);
-       DEBUGFS_DEL(rts_threshold);
-       DEBUGFS_DEL(fragmentation_threshold);
-       DEBUGFS_DEL(short_retry_limit);
-       DEBUGFS_DEL(long_retry_limit);
        DEBUGFS_DEL(total_ps_buffered);
        DEBUGFS_DEL(wep_iv);
        DEBUGFS_DEL(tsf);
        DEBUGFS_DEL(reset);
+       DEBUGFS_DEL(noack);
 
        DEBUGFS_STATS_DEL(transmitted_fragment_count);
        DEBUGFS_STATS_DEL(multicast_transmitted_frame_count);
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
new file mode 100644 (file)
index 0000000..b13446a
--- /dev/null
@@ -0,0 +1,191 @@
+#ifndef __MAC80211_DRIVER_OPS
+#define __MAC80211_DRIVER_OPS
+
+#include <net/mac80211.h>
+#include "ieee80211_i.h"
+
+static inline int drv_tx(struct ieee80211_local *local, struct sk_buff *skb)
+{
+       return local->ops->tx(&local->hw, skb);
+}
+
+static inline int drv_start(struct ieee80211_local *local)
+{
+       return local->ops->start(&local->hw);
+}
+
+static inline void drv_stop(struct ieee80211_local *local)
+{
+       local->ops->stop(&local->hw);
+}
+
+static inline int drv_add_interface(struct ieee80211_local *local,
+                                   struct ieee80211_if_init_conf *conf)
+{
+       return local->ops->add_interface(&local->hw, conf);
+}
+
+static inline void drv_remove_interface(struct ieee80211_local *local,
+                                       struct ieee80211_if_init_conf *conf)
+{
+       local->ops->remove_interface(&local->hw, conf);
+}
+
+static inline int drv_config(struct ieee80211_local *local, u32 changed)
+{
+       return local->ops->config(&local->hw, changed);
+}
+
+static inline void drv_bss_info_changed(struct ieee80211_local *local,
+                                       struct ieee80211_vif *vif,
+                                       struct ieee80211_bss_conf *info,
+                                       u32 changed)
+{
+       if (local->ops->bss_info_changed)
+               local->ops->bss_info_changed(&local->hw, vif, info, changed);
+}
+
+static inline void drv_configure_filter(struct ieee80211_local *local,
+                                       unsigned int changed_flags,
+                                       unsigned int *total_flags,
+                                       int mc_count,
+                                       struct dev_addr_list *mc_list)
+{
+       local->ops->configure_filter(&local->hw, changed_flags, total_flags,
+                                    mc_count, mc_list);
+}
+
+static inline int drv_set_tim(struct ieee80211_local *local,
+                             struct ieee80211_sta *sta, bool set)
+{
+       if (local->ops->set_tim)
+               return local->ops->set_tim(&local->hw, sta, set);
+       return 0;
+}
+
+static inline int drv_set_key(struct ieee80211_local *local,
+                             enum set_key_cmd cmd, struct ieee80211_vif *vif,
+                             struct ieee80211_sta *sta,
+                             struct ieee80211_key_conf *key)
+{
+       return local->ops->set_key(&local->hw, cmd, vif, sta, key);
+}
+
+static inline void drv_update_tkip_key(struct ieee80211_local *local,
+                                      struct ieee80211_key_conf *conf,
+                                      const u8 *address, u32 iv32,
+                                      u16 *phase1key)
+{
+       if (local->ops->update_tkip_key)
+               local->ops->update_tkip_key(&local->hw, conf, address,
+                                           iv32, phase1key);
+}
+
+static inline int drv_hw_scan(struct ieee80211_local *local,
+                             struct cfg80211_scan_request *req)
+{
+       return local->ops->hw_scan(&local->hw, req);
+}
+
+static inline void drv_sw_scan_start(struct ieee80211_local *local)
+{
+       if (local->ops->sw_scan_start)
+               local->ops->sw_scan_start(&local->hw);
+}
+
+static inline void drv_sw_scan_complete(struct ieee80211_local *local)
+{
+       if (local->ops->sw_scan_complete)
+               local->ops->sw_scan_complete(&local->hw);
+}
+
+static inline int drv_get_stats(struct ieee80211_local *local,
+                               struct ieee80211_low_level_stats *stats)
+{
+       if (!local->ops->get_stats)
+               return -EOPNOTSUPP;
+       return local->ops->get_stats(&local->hw, stats);
+}
+
+static inline void drv_get_tkip_seq(struct ieee80211_local *local,
+                                   u8 hw_key_idx, u32 *iv32, u16 *iv16)
+{
+       if (local->ops->get_tkip_seq)
+               local->ops->get_tkip_seq(&local->hw, hw_key_idx, iv32, iv16);
+}
+
+static inline int drv_set_rts_threshold(struct ieee80211_local *local,
+                                       u32 value)
+{
+       if (local->ops->set_rts_threshold)
+               return local->ops->set_rts_threshold(&local->hw, value);
+       return 0;
+}
+
+static inline void drv_sta_notify(struct ieee80211_local *local,
+                                 struct ieee80211_vif *vif,
+                                 enum sta_notify_cmd cmd,
+                                 struct ieee80211_sta *sta)
+{
+       if (local->ops->sta_notify)
+               local->ops->sta_notify(&local->hw, vif, cmd, sta);
+}
+
+static inline int drv_conf_tx(struct ieee80211_local *local, u16 queue,
+                             const struct ieee80211_tx_queue_params *params)
+{
+       if (local->ops->conf_tx)
+               return local->ops->conf_tx(&local->hw, queue, params);
+       return -EOPNOTSUPP;
+}
+
+static inline int drv_get_tx_stats(struct ieee80211_local *local,
+                                  struct ieee80211_tx_queue_stats *stats)
+{
+       return local->ops->get_tx_stats(&local->hw, stats);
+}
+
+static inline u64 drv_get_tsf(struct ieee80211_local *local)
+{
+       if (local->ops->get_tsf)
+               return local->ops->get_tsf(&local->hw);
+       return -1ULL;
+}
+
+static inline void drv_set_tsf(struct ieee80211_local *local, u64 tsf)
+{
+       if (local->ops->set_tsf)
+               local->ops->set_tsf(&local->hw, tsf);
+}
+
+static inline void drv_reset_tsf(struct ieee80211_local *local)
+{
+       if (local->ops->reset_tsf)
+               local->ops->reset_tsf(&local->hw);
+}
+
+static inline int drv_tx_last_beacon(struct ieee80211_local *local)
+{
+       if (local->ops->tx_last_beacon)
+               return local->ops->tx_last_beacon(&local->hw);
+       return 1;
+}
+
+static inline int drv_ampdu_action(struct ieee80211_local *local,
+                                  enum ieee80211_ampdu_mlme_action action,
+                                  struct ieee80211_sta *sta, u16 tid,
+                                  u16 *ssn)
+{
+       if (local->ops->ampdu_action)
+               return local->ops->ampdu_action(&local->hw, action,
+                                               sta, tid, ssn);
+       return -EOPNOTSUPP;
+}
+
+
+static inline void drv_rfkill_poll(struct ieee80211_local *local)
+{
+       if (local->ops->rfkill_poll)
+               local->ops->rfkill_poll(&local->hw);
+}
+#endif /* __MAC80211_DRIVER_OPS */
index 0d95561c0ee017d72cf3b19986a79fc25ad9a1ae..f288d01a634448cafc75983f947cc83f9cad68e2 100644 (file)
 #include "ieee80211_i.h"
 
 /*
- * indicate a failed Michael MIC to userspace; the passed packet
- * (in the variable hdr) must be long enough to extract the TKIP
- * fields like TSC
+ * Indicate a failed Michael MIC to userspace. If the caller knows the TSC of
+ * the frame that generated the MIC failure (i.e., if it was provided by the
+ * driver or is still in the frame), it should provide that information.
  */
 void mac80211_ev_michael_mic_failure(struct ieee80211_sub_if_data *sdata, int keyidx,
-                                    struct ieee80211_hdr *hdr)
+                                    struct ieee80211_hdr *hdr, const u8 *tsc)
 {
        union iwreq_data wrqu;
        char *buf = kmalloc(128, GFP_ATOMIC);
@@ -34,8 +34,9 @@ void mac80211_ev_michael_mic_failure(struct ieee80211_sub_if_data *sdata, int ke
                kfree(buf);
        }
 
-       /*
-        * TODO: re-add support for sending MIC failure indication
-        * with all info via nl80211
-        */
+       cfg80211_michael_mic_failure(sdata->dev, hdr->addr2,
+                                    (hdr->addr1[0] & 0x01) ?
+                                    NL80211_KEYTYPE_GROUP :
+                                    NL80211_KEYTYPE_PAIRWISE,
+                                    keyidx, tsc);
 }
index 4e3c72f20de760c5d24fcaa40c004abd237d5607..0891bfb0699684e0d8971a49b8fa6820b506ec21 100644 (file)
@@ -14,7 +14,6 @@
  */
 
 #include <linux/ieee80211.h>
-#include <net/wireless.h>
 #include <net/mac80211.h>
 #include "ieee80211_i.h"
 #include "rate.h"
@@ -83,89 +82,6 @@ void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_supported_band *sband,
                ht_cap->mcs.rx_mask[32/8] |= 1;
 }
 
-/*
- * ieee80211_enable_ht should be called only after the operating band
- * has been determined as ht configuration depends on the hw's
- * HT abilities for a specific band.
- */
-u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
-                       struct ieee80211_ht_info *hti,
-                       u16 ap_ht_cap_flags)
-{
-       struct ieee80211_local *local = sdata->local;
-       struct ieee80211_supported_band *sband;
-       struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
-       struct ieee80211_bss_ht_conf ht;
-       struct sta_info *sta;
-       u32 changed = 0;
-       bool enable_ht = true, ht_changed;
-       enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
-
-       sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
-
-       memset(&ht, 0, sizeof(ht));
-
-       /* HT is not supported */
-       if (!sband->ht_cap.ht_supported)
-               enable_ht = false;
-
-       /* check that channel matches the right operating channel */
-       if (local->hw.conf.channel->center_freq !=
-           ieee80211_channel_to_frequency(hti->control_chan))
-               enable_ht = false;
-
-       if (enable_ht) {
-               channel_type = NL80211_CHAN_HT20;
-
-               if (!(ap_ht_cap_flags & IEEE80211_HT_CAP_40MHZ_INTOLERANT) &&
-                   (sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) &&
-                   (hti->ht_param & IEEE80211_HT_PARAM_CHAN_WIDTH_ANY)) {
-                       switch(hti->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
-                       case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
-                               channel_type = NL80211_CHAN_HT40PLUS;
-                               break;
-                       case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
-                               channel_type = NL80211_CHAN_HT40MINUS;
-                               break;
-                       }
-               }
-       }
-
-       ht_changed = conf_is_ht(&local->hw.conf) != enable_ht ||
-                    channel_type != local->hw.conf.channel_type;
-
-       local->oper_channel_type = channel_type;
-
-       if (ht_changed) {
-                /* channel_type change automatically detected */
-               ieee80211_hw_config(local, 0);
-
-               rcu_read_lock();
-
-               sta = sta_info_get(local, ifmgd->bssid);
-               if (sta)
-                       rate_control_rate_update(local, sband, sta,
-                                                IEEE80211_RC_HT_CHANGED);
-
-               rcu_read_unlock();
-
-        }
-
-       /* disable HT */
-       if (!enable_ht)
-               return 0;
-
-       ht.operation_mode = le16_to_cpu(hti->operation_mode);
-
-       /* if bss configuration changed store the new one */
-       if (memcmp(&sdata->vif.bss_conf.ht, &ht, sizeof(ht))) {
-               changed |= BSS_CHANGED_HT;
-               sdata->vif.bss_conf.ht = ht;
-       }
-
-       return changed;
-}
-
 void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta)
 {
        int i;
index 3201e1f96365649a5c1ad56f898afa20af9ddf0a..0b30277eb3667bbc113cc89802609959f8d1faae 100644 (file)
@@ -22,6 +22,7 @@
 #include <asm/unaligned.h>
 
 #include "ieee80211_i.h"
+#include "driver-ops.h"
 #include "rate.h"
 
 #define IEEE80211_SCAN_INTERVAL (2 * HZ)
@@ -59,74 +60,65 @@ static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata,
                                    sdata->u.ibss.bssid, 0);
 }
 
-static int __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
-                                    const u8 *bssid, const int beacon_int,
-                                    const int freq,
-                                    const size_t supp_rates_len,
-                                    const u8 *supp_rates,
-                                    const u16 capability, u64 tsf)
+static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
+                                     const u8 *bssid, const int beacon_int,
+                                     struct ieee80211_channel *chan,
+                                     const u32 basic_rates,
+                                     const u16 capability, u64 tsf)
 {
        struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
        struct ieee80211_local *local = sdata->local;
-       int res = 0, rates, i, j;
+       int rates, i;
        struct sk_buff *skb;
        struct ieee80211_mgmt *mgmt;
        u8 *pos;
        struct ieee80211_supported_band *sband;
-       union iwreq_data wrqu;
+       u32 bss_change;
+       u8 supp_rates[IEEE80211_MAX_SUPP_RATES];
 
-       if (local->ops->reset_tsf) {
-               /* Reset own TSF to allow time synchronization work. */
-               local->ops->reset_tsf(local_to_hw(local));
-       }
+       /* Reset own TSF to allow time synchronization work. */
+       drv_reset_tsf(local);
 
-       if ((ifibss->flags & IEEE80211_IBSS_PREV_BSSID_SET) &&
-          memcmp(ifibss->bssid, bssid, ETH_ALEN) == 0)
-               return res;
+       skb = ifibss->skb;
+       rcu_assign_pointer(ifibss->presp, NULL);
+       synchronize_rcu();
+       skb->data = skb->head;
+       skb->len = 0;
+       skb_reset_tail_pointer(skb);
+       skb_reserve(skb, sdata->local->hw.extra_tx_headroom);
 
-       skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400);
-       if (!skb) {
-               printk(KERN_DEBUG "%s: failed to allocate buffer for probe "
-                      "response\n", sdata->dev->name);
-               return -ENOMEM;
-       }
-
-       if (!(ifibss->flags & IEEE80211_IBSS_PREV_BSSID_SET)) {
-               /* Remove possible STA entries from other IBSS networks. */
-               sta_info_flush_delayed(sdata);
-       }
+       if (memcmp(ifibss->bssid, bssid, ETH_ALEN))
+               sta_info_flush(sdata->local, sdata);
 
        memcpy(ifibss->bssid, bssid, ETH_ALEN);
-       res = ieee80211_if_config(sdata, IEEE80211_IFCC_BSSID);
-       if (res)
-               return res;
-
-       local->hw.conf.beacon_int = beacon_int >= 10 ? beacon_int : 10;
 
-       sdata->drop_unencrypted = capability &
-               WLAN_CAPABILITY_PRIVACY ? 1 : 0;
+       sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0;
 
-       res = ieee80211_set_freq(sdata, freq);
+       local->oper_channel = chan;
+       local->oper_channel_type = NL80211_CHAN_NO_HT;
+       ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
 
-       if (res)
-               return res;
+       sband = local->hw.wiphy->bands[chan->band];
 
-       sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
+       /* build supported rates array */
+       pos = supp_rates;
+       for (i = 0; i < sband->n_bitrates; i++) {
+               int rate = sband->bitrates[i].bitrate;
+               u8 basic = 0;
+               if (basic_rates & BIT(i))
+                       basic = 0x80;
+               *pos++ = basic | (u8) (rate / 5);
+       }
 
        /* Build IBSS probe response */
-
-       skb_reserve(skb, local->hw.extra_tx_headroom);
-
-       mgmt = (struct ieee80211_mgmt *)
-               skb_put(skb, 24 + sizeof(mgmt->u.beacon));
+       mgmt = (void *) skb_put(skb, 24 + sizeof(mgmt->u.beacon));
        memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon));
        mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
                                          IEEE80211_STYPE_PROBE_RESP);
        memset(mgmt->da, 0xff, ETH_ALEN);
        memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
        memcpy(mgmt->bssid, ifibss->bssid, ETH_ALEN);
-       mgmt->u.beacon.beacon_int =
-               cpu_to_le16(local->hw.conf.beacon_int);
+       mgmt->u.beacon.beacon_int = cpu_to_le16(beacon_int);
        mgmt->u.beacon.timestamp = cpu_to_le64(tsf);
        mgmt->u.beacon.capab_info = cpu_to_le16(capability);
 
@@ -135,7 +127,7 @@ static int __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
        *pos++ = ifibss->ssid_len;
        memcpy(pos, ifibss->ssid, ifibss->ssid_len);
 
-       rates = supp_rates_len;
+       rates = sband->n_bitrates;
        if (rates > 8)
                rates = 8;
        pos = skb_put(skb, 2 + rates);
@@ -147,7 +139,7 @@ static int __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
                pos = skb_put(skb, 2 + 1);
                *pos++ = WLAN_EID_DS_PARAMS;
                *pos++ = 1;
-               *pos++ = ieee80211_frequency_to_channel(freq);
+               *pos++ = ieee80211_frequency_to_channel(chan->center_freq);
        }
 
        pos = skb_put(skb, 2 + 2);
@@ -157,51 +149,73 @@ static int __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
        *pos++ = 0;
        *pos++ = 0;
 
-       if (supp_rates_len > 8) {
-               rates = supp_rates_len - 8;
+       if (sband->n_bitrates > 8) {
+               rates = sband->n_bitrates - 8;
                pos = skb_put(skb, 2 + rates);
                *pos++ = WLAN_EID_EXT_SUPP_RATES;
                *pos++ = rates;
                memcpy(pos, &supp_rates[8], rates);
        }
 
-       ifibss->probe_resp = skb;
+       if (ifibss->ie_len)
+               memcpy(skb_put(skb, ifibss->ie_len),
+                      ifibss->ie, ifibss->ie_len);
 
-       ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON |
-                                  IEEE80211_IFCC_BEACON_ENABLED);
+       rcu_assign_pointer(ifibss->presp, skb);
 
+       sdata->vif.bss_conf.beacon_int = beacon_int;
+       bss_change = BSS_CHANGED_BEACON_INT;
+       bss_change |= ieee80211_reset_erp_info(sdata);
+       bss_change |= BSS_CHANGED_BSSID;
+       bss_change |= BSS_CHANGED_BEACON;
+       bss_change |= BSS_CHANGED_BEACON_ENABLED;
+       ieee80211_bss_info_change_notify(sdata, bss_change);
 
-       rates = 0;
-       for (i = 0; i < supp_rates_len; i++) {
-               int bitrate = (supp_rates[i] & 0x7f) * 5;
-               for (j = 0; j < sband->n_bitrates; j++)
-                       if (sband->bitrates[j].bitrate == bitrate)
-                               rates |= BIT(j);
-       }
+       ieee80211_sta_def_wmm_params(sdata, sband->n_bitrates, supp_rates);
 
-       ieee80211_sta_def_wmm_params(sdata, supp_rates_len, supp_rates);
-
-       ifibss->flags |= IEEE80211_IBSS_PREV_BSSID_SET;
        ifibss->state = IEEE80211_IBSS_MLME_JOINED;
-       mod_timer(&ifibss->timer, jiffies + IEEE80211_IBSS_MERGE_INTERVAL);
-
-       memset(&wrqu, 0, sizeof(wrqu));
-       memcpy(wrqu.ap_addr.sa_data, bssid, ETH_ALEN);
-       wireless_send_event(sdata->dev, SIOCGIWAP, &wrqu, NULL);
+       mod_timer(&ifibss->timer,
+                 round_jiffies(jiffies + IEEE80211_IBSS_MERGE_INTERVAL));
 
-       return res;
+       cfg80211_inform_bss_frame(local->hw.wiphy, local->hw.conf.channel,
+                                 mgmt, skb->len, 0, GFP_KERNEL);
+       cfg80211_ibss_joined(sdata->dev, ifibss->bssid, GFP_KERNEL);
 }
 
-static int ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
-                                  struct ieee80211_bss *bss)
+static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
+                                   struct ieee80211_bss *bss)
 {
-       return __ieee80211_sta_join_ibss(sdata,
-                                        bss->cbss.bssid,
-                                        bss->cbss.beacon_interval,
-                                        bss->cbss.channel->center_freq,
-                                        bss->supp_rates_len, bss->supp_rates,
-                                        bss->cbss.capability,
-                                        bss->cbss.tsf);
+       struct ieee80211_supported_band *sband;
+       u32 basic_rates;
+       int i, j;
+       u16 beacon_int = bss->cbss.beacon_interval;
+
+       if (beacon_int < 10)
+               beacon_int = 10;
+
+       sband = sdata->local->hw.wiphy->bands[bss->cbss.channel->band];
+
+       basic_rates = 0;
+
+       for (i = 0; i < bss->supp_rates_len; i++) {
+               int rate = (bss->supp_rates[i] & 0x7f) * 5;
+               bool is_basic = !!(bss->supp_rates[i] & 0x80);
+
+               for (j = 0; j < sband->n_bitrates; j++) {
+                       if (sband->bitrates[j].bitrate == rate) {
+                               if (is_basic)
+                                       basic_rates |= BIT(j);
+                               break;
+                       }
+               }
+       }
+
+       __ieee80211_sta_join_ibss(sdata, bss->cbss.bssid,
+                                 beacon_int,
+                                 bss->cbss.channel,
+                                 basic_rates,
+                                 bss->cbss.capability,
+                                 bss->cbss.tsf);
 }
 
 static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
@@ -277,7 +291,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
                goto put_bss;
 
        /* we use a fixed BSSID */
-       if (sdata->u.ibss.flags & IEEE80211_IBSS_BSSID_SET)
+       if (sdata->u.ibss.bssid)
                goto put_bss;
 
        /* not an IBSS */
@@ -322,12 +336,13 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
                                bitrates[rx_status->rate_idx].bitrate;
 
                rx_timestamp = rx_status->mactime + (24 * 8 * 10 / rate);
-       } else if (local && local->ops && local->ops->get_tsf)
-               /* second best option: get current TSF */
-               rx_timestamp = local->ops->get_tsf(local_to_hw(local));
-       else
-               /* can't merge without knowing the TSF */
-               rx_timestamp = -1LLU;
+       } else {
+               /*
+                * second best option: get current TSF
+                * (will return -1 if not supported)
+                */
+               rx_timestamp = drv_get_tsf(local);
+       }
 
 #ifdef CONFIG_MAC80211_IBSS_DEBUG
        printk(KERN_DEBUG "RX beacon SA=%pM BSSID="
@@ -369,13 +384,14 @@ struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
        struct sta_info *sta;
        int band = local->hw.conf.channel->band;
 
-       /* TODO: Could consider removing the least recently used entry and
-        * allow new one to be added. */
+       /*
+        * XXX: Consider removing the least recently used entry and
+        *      allow new one to be added.
+        */
        if (local->num_sta >= IEEE80211_IBSS_MAX_STA_ENTRIES) {
-               if (net_ratelimit()) {
-                       printk(KERN_DEBUG "%s: No room for a new IBSS STA "
-                              "entry %pM\n", sdata->dev->name, addr);
-               }
+               if (net_ratelimit())
+                       printk(KERN_DEBUG "%s: No room for a new IBSS STA entry %pM\n",
+                              sdata->dev->name, addr);
                return NULL;
        }
 
@@ -432,41 +448,33 @@ static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata)
 {
        struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
 
-       mod_timer(&ifibss->timer, jiffies + IEEE80211_IBSS_MERGE_INTERVAL);
+       mod_timer(&ifibss->timer,
+                 round_jiffies(jiffies + IEEE80211_IBSS_MERGE_INTERVAL));
 
        ieee80211_sta_expire(sdata, IEEE80211_IBSS_INACTIVITY_LIMIT);
+
        if (ieee80211_sta_active_ibss(sdata))
                return;
 
-       if ((ifibss->flags & IEEE80211_IBSS_BSSID_SET) &&
-           (!(ifibss->flags & IEEE80211_IBSS_AUTO_CHANNEL_SEL)))
+       if (ifibss->fixed_channel)
                return;
 
        printk(KERN_DEBUG "%s: No active IBSS STAs - trying to scan for other "
               "IBSS networks with same SSID (merge)\n", sdata->dev->name);
 
-       /* XXX maybe racy? */
-       if (sdata->local->scan_req)
-               return;
-
-       memcpy(sdata->local->int_scan_req.ssids[0].ssid,
-              ifibss->ssid, IEEE80211_MAX_SSID_LEN);
-       sdata->local->int_scan_req.ssids[0].ssid_len = ifibss->ssid_len;
-       ieee80211_request_scan(sdata, &sdata->local->int_scan_req);
+       ieee80211_request_internal_scan(sdata, ifibss->ssid, ifibss->ssid_len);
 }
 
-static int ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
+static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
 {
        struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
        struct ieee80211_local *local = sdata->local;
        struct ieee80211_supported_band *sband;
-       u8 *pos;
        u8 bssid[ETH_ALEN];
-       u8 supp_rates[IEEE80211_MAX_SUPP_RATES];
        u16 capability;
        int i;
 
-       if (ifibss->flags & IEEE80211_IBSS_BSSID_SET) {
+       if (ifibss->fixed_bssid) {
                memcpy(bssid, ifibss->bssid, ETH_ALEN);
        } else {
                /* Generate random, not broadcast, locally administered BSSID. Mix in
@@ -482,10 +490,7 @@ static int ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
        printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID %pM\n",
               sdata->dev->name, bssid);
 
-       sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
-
-       if (local->hw.conf.beacon_int == 0)
-               local->hw.conf.beacon_int = 100;
+       sband = local->hw.wiphy->bands[ifibss->channel->band];
 
        capability = WLAN_CAPABILITY_IBSS;
 
@@ -494,29 +499,20 @@ static int ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
        else
                sdata->drop_unencrypted = 0;
 
-       pos = supp_rates;
-       for (i = 0; i < sband->n_bitrates; i++) {
-               int rate = sband->bitrates[i].bitrate;
-               *pos++ = (u8) (rate / 5);
-       }
-
-       return __ieee80211_sta_join_ibss(sdata,
-                                        bssid, local->hw.conf.beacon_int,
-                                        local->hw.conf.channel->center_freq,
-                                        sband->n_bitrates, supp_rates,
-                                        capability, 0);
+       __ieee80211_sta_join_ibss(sdata, bssid, sdata->vif.bss_conf.beacon_int,
+                                 ifibss->channel, 3, /* first two are basic */
+                                 capability, 0);
 }
 
-static int ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
+static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
 {
        struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
        struct ieee80211_local *local = sdata->local;
        struct ieee80211_bss *bss;
+       struct ieee80211_channel *chan = NULL;
        const u8 *bssid = NULL;
        int active_ibss;
-
-       if (ifibss->ssid_len == 0)
-               return -EINVAL;
+       u16 capability;
 
        active_ibss = ieee80211_sta_active_ibss(sdata);
 #ifdef CONFIG_MAC80211_IBSS_DEBUG
@@ -525,14 +521,23 @@ static int ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
 #endif /* CONFIG_MAC80211_IBSS_DEBUG */
 
        if (active_ibss)
-               return 0;
+               return;
 
-       if (ifibss->flags & IEEE80211_IBSS_BSSID_SET)
+       capability = WLAN_CAPABILITY_IBSS;
+       if (sdata->default_key)
+               capability |= WLAN_CAPABILITY_PRIVACY;
+
+       if (ifibss->fixed_bssid)
                bssid = ifibss->bssid;
-       bss = (void *)cfg80211_get_bss(local->hw.wiphy, NULL, bssid,
+       if (ifibss->fixed_channel)
+               chan = ifibss->channel;
+       if (!is_zero_ether_addr(ifibss->bssid))
+               bssid = ifibss->bssid;
+       bss = (void *)cfg80211_get_bss(local->hw.wiphy, chan, bssid,
                                       ifibss->ssid, ifibss->ssid_len,
-                                      WLAN_CAPABILITY_IBSS,
-                                      WLAN_CAPABILITY_IBSS);
+                                      WLAN_CAPABILITY_IBSS |
+                                      WLAN_CAPABILITY_PRIVACY,
+                                      capability);
 
 #ifdef CONFIG_MAC80211_IBSS_DEBUG
        if (bss)
@@ -540,18 +545,14 @@ static int ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
                       "%pM\n", bss->cbss.bssid, ifibss->bssid);
 #endif /* CONFIG_MAC80211_IBSS_DEBUG */
 
-       if (bss &&
-           (!(ifibss->flags & IEEE80211_IBSS_PREV_BSSID_SET) ||
-            memcmp(ifibss->bssid, bss->cbss.bssid, ETH_ALEN))) {
-               int ret;
-
+       if (bss && memcmp(ifibss->bssid, bss->cbss.bssid, ETH_ALEN)) {
                printk(KERN_DEBUG "%s: Selected IBSS BSSID %pM"
                       " based on configured SSID\n",
                       sdata->dev->name, bss->cbss.bssid);
 
-               ret = ieee80211_sta_join_ibss(sdata, bss);
+               ieee80211_sta_join_ibss(sdata, bss);
                ieee80211_rx_bss_put(local, bss);
-               return ret;
+               return;
        } else if (bss)
                ieee80211_rx_bss_put(local, bss);
 
@@ -562,29 +563,24 @@ static int ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
        /* Selected IBSS not found in current scan results - try to scan */
        if (ifibss->state == IEEE80211_IBSS_MLME_JOINED &&
            !ieee80211_sta_active_ibss(sdata)) {
-               mod_timer(&ifibss->timer, jiffies +
-                                         IEEE80211_IBSS_MERGE_INTERVAL);
-       } else if (time_after(jiffies, local->last_scan_completed +
+               mod_timer(&ifibss->timer,
+                         round_jiffies(jiffies + IEEE80211_IBSS_MERGE_INTERVAL));
+       } else if (time_after(jiffies, ifibss->last_scan_completed +
                                        IEEE80211_SCAN_INTERVAL)) {
                printk(KERN_DEBUG "%s: Trigger new scan to find an IBSS to "
                       "join\n", sdata->dev->name);
 
-               /* XXX maybe racy? */
-               if (local->scan_req)
-                       return -EBUSY;
-
-               memcpy(local->int_scan_req.ssids[0].ssid,
-                      ifibss->ssid, IEEE80211_MAX_SSID_LEN);
-               local->int_scan_req.ssids[0].ssid_len = ifibss->ssid_len;
-               return ieee80211_request_scan(sdata, &local->int_scan_req);
+               ieee80211_request_internal_scan(sdata, ifibss->ssid,
+                                               ifibss->ssid_len);
        } else if (ifibss->state != IEEE80211_IBSS_MLME_JOINED) {
                int interval = IEEE80211_SCAN_INTERVAL;
 
                if (time_after(jiffies, ifibss->ibss_join_req +
                               IEEE80211_IBSS_JOIN_TIMEOUT)) {
-                       if (!(local->oper_channel->flags &
-                                               IEEE80211_CHAN_NO_IBSS))
-                               return ieee80211_sta_create_ibss(sdata);
+                       if (!(local->oper_channel->flags & IEEE80211_CHAN_NO_IBSS)) {
+                               ieee80211_sta_create_ibss(sdata);
+                               return;
+                       }
                        printk(KERN_DEBUG "%s: IBSS not allowed on"
                               " %d MHz\n", sdata->dev->name,
                               local->hw.conf.channel->center_freq);
@@ -595,11 +591,9 @@ static int ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
                }
 
                ifibss->state = IEEE80211_IBSS_MLME_SEARCH;
-               mod_timer(&ifibss->timer, jiffies + interval);
-               return 0;
+               mod_timer(&ifibss->timer,
+                         round_jiffies(jiffies + interval));
        }
-
-       return 0;
 }
 
 static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata,
@@ -614,13 +608,10 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata,
        u8 *pos, *end;
 
        if (ifibss->state != IEEE80211_IBSS_MLME_JOINED ||
-           len < 24 + 2 || !ifibss->probe_resp)
+           len < 24 + 2 || !ifibss->presp)
                return;
 
-       if (local->ops->tx_last_beacon)
-               tx_last_beacon = local->ops->tx_last_beacon(local_to_hw(local));
-       else
-               tx_last_beacon = 1;
+       tx_last_beacon = drv_tx_last_beacon(local);
 
 #ifdef CONFIG_MAC80211_IBSS_DEBUG
        printk(KERN_DEBUG "%s: RX ProbeReq SA=%pM DA=%pM BSSID=%pM"
@@ -649,13 +640,13 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata,
        }
        if (pos[1] != 0 &&
            (pos[1] != ifibss->ssid_len ||
-            memcmp(pos + 2, ifibss->ssid, ifibss->ssid_len) != 0)) {
+            !memcmp(pos + 2, ifibss->ssid, ifibss->ssid_len))) {
                /* Ignore ProbeReq for foreign SSID */
                return;
        }
 
        /* Reply with ProbeResp */
-       skb = skb_copy(ifibss->probe_resp, GFP_KERNEL);
+       skb = skb_copy(ifibss->presp, GFP_KERNEL);
        if (!skb)
                return;
 
@@ -746,6 +737,9 @@ static void ieee80211_ibss_work(struct work_struct *work)
        struct ieee80211_if_ibss *ifibss;
        struct sk_buff *skb;
 
+       if (WARN_ON(local->suspended))
+               return;
+
        if (!netif_running(sdata->dev))
                return;
 
@@ -782,101 +776,63 @@ static void ieee80211_ibss_timer(unsigned long data)
        struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
        struct ieee80211_local *local = sdata->local;
 
+       if (local->quiescing) {
+               ifibss->timer_running = true;
+               return;
+       }
+
        set_bit(IEEE80211_IBSS_REQ_RUN, &ifibss->request);
        queue_work(local->hw.workqueue, &ifibss->work);
 }
 
-void ieee80211_ibss_setup_sdata(struct ieee80211_sub_if_data *sdata)
+#ifdef CONFIG_PM
+void ieee80211_ibss_quiesce(struct ieee80211_sub_if_data *sdata)
 {
        struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
 
-       INIT_WORK(&ifibss->work, ieee80211_ibss_work);
-       setup_timer(&ifibss->timer, ieee80211_ibss_timer,
-                   (unsigned long) sdata);
-       skb_queue_head_init(&ifibss->skb_queue);
-
-       ifibss->flags |= IEEE80211_IBSS_AUTO_BSSID_SEL |
-                       IEEE80211_IBSS_AUTO_CHANNEL_SEL;
+       cancel_work_sync(&ifibss->work);
+       if (del_timer_sync(&ifibss->timer))
+               ifibss->timer_running = true;
 }
 
-int ieee80211_ibss_commit(struct ieee80211_sub_if_data *sdata)
+void ieee80211_ibss_restart(struct ieee80211_sub_if_data *sdata)
 {
        struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
 
-       ifibss->flags &= ~IEEE80211_IBSS_PREV_BSSID_SET;
-
-       if (ifibss->ssid_len)
-               ifibss->flags |= IEEE80211_IBSS_SSID_SET;
-       else
-               ifibss->flags &= ~IEEE80211_IBSS_SSID_SET;
-
-       ifibss->ibss_join_req = jiffies;
-       ifibss->state = IEEE80211_IBSS_MLME_SEARCH;
-       set_bit(IEEE80211_IBSS_REQ_RUN, &ifibss->request);
-
-       return 0;
-}
-
-int ieee80211_ibss_set_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size_t len)
-{
-       struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
-
-       if (len > IEEE80211_MAX_SSID_LEN)
-               return -EINVAL;
-
-       if (ifibss->ssid_len != len || memcmp(ifibss->ssid, ssid, len) != 0) {
-               memset(ifibss->ssid, 0, sizeof(ifibss->ssid));
-               memcpy(ifibss->ssid, ssid, len);
-               ifibss->ssid_len = len;
+       if (ifibss->timer_running) {
+               add_timer(&ifibss->timer);
+               ifibss->timer_running = false;
        }
-
-       return ieee80211_ibss_commit(sdata);
-}
-
-int ieee80211_ibss_get_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size_t *len)
-{
-       struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
-
-       memcpy(ssid, ifibss->ssid, ifibss->ssid_len);
-       *len = ifibss->ssid_len;
-
-       return 0;
 }
+#endif
 
-int ieee80211_ibss_set_bssid(struct ieee80211_sub_if_data *sdata, u8 *bssid)
+void ieee80211_ibss_setup_sdata(struct ieee80211_sub_if_data *sdata)
 {
        struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
 
-       if (is_valid_ether_addr(bssid)) {
-               memcpy(ifibss->bssid, bssid, ETH_ALEN);
-               ifibss->flags |= IEEE80211_IBSS_BSSID_SET;
-       } else {
-               memset(ifibss->bssid, 0, ETH_ALEN);
-               ifibss->flags &= ~IEEE80211_IBSS_BSSID_SET;
-       }
-
-       if (netif_running(sdata->dev)) {
-               if (ieee80211_if_config(sdata, IEEE80211_IFCC_BSSID)) {
-                       printk(KERN_DEBUG "%s: Failed to config new BSSID to "
-                              "the low-level driver\n", sdata->dev->name);
-               }
-       }
-
-       return ieee80211_ibss_commit(sdata);
+       INIT_WORK(&ifibss->work, ieee80211_ibss_work);
+       setup_timer(&ifibss->timer, ieee80211_ibss_timer,
+                   (unsigned long) sdata);
+       skb_queue_head_init(&ifibss->skb_queue);
 }
 
 /* scan finished notification */
 void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local)
 {
-       struct ieee80211_sub_if_data *sdata = local->scan_sdata;
-       struct ieee80211_if_ibss *ifibss;
-
-       if (sdata && sdata->vif.type == NL80211_IFTYPE_ADHOC) {
-               ifibss = &sdata->u.ibss;
-               if ((!(ifibss->flags & IEEE80211_IBSS_PREV_BSSID_SET)) ||
-                   !ieee80211_sta_active_ibss(sdata))
-                       ieee80211_sta_find_ibss(sdata);
+       struct ieee80211_sub_if_data *sdata;
+
+       mutex_lock(&local->iflist_mtx);
+       list_for_each_entry(sdata, &local->interfaces, list) {
+               if (!netif_running(sdata->dev))
+                       continue;
+               if (sdata->vif.type != NL80211_IFTYPE_ADHOC)
+                       continue;
+               if (!sdata->u.ibss.ssid_len)
+                       continue;
+               sdata->u.ibss.last_scan_completed = jiffies;
+               ieee80211_sta_find_ibss(sdata);
        }
+       mutex_unlock(&local->iflist_mtx);
 }
 
 ieee80211_rx_result
@@ -906,3 +862,86 @@ ieee80211_ibss_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
 
        return RX_DROP_MONITOR;
 }
+
+int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
+                       struct cfg80211_ibss_params *params)
+{
+       struct sk_buff *skb;
+
+       if (params->bssid) {
+               memcpy(sdata->u.ibss.bssid, params->bssid, ETH_ALEN);
+               sdata->u.ibss.fixed_bssid = true;
+       } else
+               sdata->u.ibss.fixed_bssid = false;
+
+       sdata->vif.bss_conf.beacon_int = params->beacon_interval;
+
+       sdata->u.ibss.channel = params->channel;
+       sdata->u.ibss.fixed_channel = params->channel_fixed;
+
+       if (params->ie) {
+               sdata->u.ibss.ie = kmemdup(params->ie, params->ie_len,
+                                          GFP_KERNEL);
+               if (sdata->u.ibss.ie)
+                       sdata->u.ibss.ie_len = params->ie_len;
+       }
+
+       skb = dev_alloc_skb(sdata->local->hw.extra_tx_headroom +
+                           36 /* bitrates */ +
+                           34 /* SSID */ +
+                           3  /* DS params */ +
+                           4  /* IBSS params */ +
+                           params->ie_len);
+       if (!skb)
+               return -ENOMEM;
+
+       sdata->u.ibss.skb = skb;
+       sdata->u.ibss.state = IEEE80211_IBSS_MLME_SEARCH;
+       sdata->u.ibss.ibss_join_req = jiffies;
+
+       memcpy(sdata->u.ibss.ssid, params->ssid, IEEE80211_MAX_SSID_LEN);
+
+       /*
+        * The ssid_len setting below is used to see whether
+        * we are active, and we need all other settings
+        * before that may get visible.
+        */
+       mb();
+
+       sdata->u.ibss.ssid_len = params->ssid_len;
+
+       ieee80211_recalc_idle(sdata->local);
+
+       set_bit(IEEE80211_IBSS_REQ_RUN, &sdata->u.ibss.request);
+       queue_work(sdata->local->hw.workqueue, &sdata->u.ibss.work);
+
+       return 0;
+}
+
+int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata)
+{
+       struct sk_buff *skb;
+
+       del_timer_sync(&sdata->u.ibss.timer);
+       clear_bit(IEEE80211_IBSS_REQ_RUN, &sdata->u.ibss.request);
+       cancel_work_sync(&sdata->u.ibss.work);
+       clear_bit(IEEE80211_IBSS_REQ_RUN, &sdata->u.ibss.request);
+
+       sta_info_flush(sdata->local, sdata);
+
+       /* remove beacon */
+       kfree(sdata->u.ibss.ie);
+       skb = sdata->u.ibss.presp;
+       rcu_assign_pointer(sdata->u.ibss.presp, NULL);
+       ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED);
+       synchronize_rcu();
+       kfree_skb(skb);
+
+       skb_queue_purge(&sdata->u.ibss.skb_queue);
+       memset(sdata->u.ibss.bssid, 0, ETH_ALEN);
+       sdata->u.ibss.ssid_len = 0;
+
+       ieee80211_recalc_idle(sdata->local);
+
+       return 0;
+}
index e6ed78cb16b39c8dde63a8e895c2c03cff2e6e91..4dbc289641962a1fddad9a520ed9d069a7bc00e6 100644 (file)
@@ -24,7 +24,6 @@
 #include <linux/spinlock.h>
 #include <linux/etherdevice.h>
 #include <net/cfg80211.h>
-#include <net/wireless.h>
 #include <net/iw_handler.h>
 #include <net/mac80211.h>
 #include "key.h"
@@ -236,7 +235,7 @@ struct mesh_preq_queue {
 #define IEEE80211_STA_ASSOCIATED       BIT(4)
 #define IEEE80211_STA_PROBEREQ_POLL    BIT(5)
 #define IEEE80211_STA_CREATE_IBSS      BIT(6)
-/* hole at 7, please re-use */
+#define IEEE80211_STA_CONTROL_PORT     BIT(7)
 #define IEEE80211_STA_WMM_ENABLED      BIT(8)
 /* hole at 9, please re-use */
 #define IEEE80211_STA_AUTO_SSID_SEL    BIT(10)
@@ -249,9 +248,8 @@ struct mesh_preq_queue {
 #define IEEE80211_STA_EXT_SME          BIT(17)
 /* flags for MLME request */
 #define IEEE80211_STA_REQ_SCAN 0
-#define IEEE80211_STA_REQ_DIRECT_PROBE 1
-#define IEEE80211_STA_REQ_AUTH 2
-#define IEEE80211_STA_REQ_RUN  3
+#define IEEE80211_STA_REQ_AUTH 1
+#define IEEE80211_STA_REQ_RUN  2
 
 /* bitfield of allowed auth algs */
 #define IEEE80211_AUTH_ALG_OPEN BIT(0)
@@ -295,6 +293,9 @@ struct ieee80211_if_managed {
        int auth_tries; /* retries for auth req */
        int assoc_tries; /* retries for assoc req */
 
+       unsigned long timers_running; /* used for quiesce/restart */
+       bool powersave; /* powersave requested for this iface */
+
        unsigned long request;
 
        unsigned long last_probe;
@@ -306,6 +307,8 @@ struct ieee80211_if_managed {
        int auth_alg; /* currently used IEEE 802.11 authentication algorithm */
        int auth_transaction;
 
+       u32 beacon_crc;
+
        enum {
                IEEE80211_MFP_DISABLED,
                IEEE80211_MFP_OPTIONAL,
@@ -319,14 +322,6 @@ struct ieee80211_if_managed {
        size_t sme_auth_ie_len;
 };
 
-enum ieee80211_ibss_flags {
-       IEEE80211_IBSS_AUTO_CHANNEL_SEL         = BIT(0),
-       IEEE80211_IBSS_AUTO_BSSID_SEL           = BIT(1),
-       IEEE80211_IBSS_BSSID_SET                = BIT(2),
-       IEEE80211_IBSS_PREV_BSSID_SET           = BIT(3),
-       IEEE80211_IBSS_SSID_SET                 = BIT(4),
-};
-
 enum ieee80211_ibss_request {
        IEEE80211_IBSS_REQ_RUN  = 0,
 };
@@ -337,17 +332,23 @@ struct ieee80211_if_ibss {
 
        struct sk_buff_head skb_queue;
 
-       u8 ssid[IEEE80211_MAX_SSID_LEN];
-       u8 ssid_len;
+       unsigned long request;
+       unsigned long last_scan_completed;
 
-       u32 flags;
+       bool timer_running;
 
-       u8 bssid[ETH_ALEN];
+       bool fixed_bssid;
+       bool fixed_channel;
 
-       unsigned long request;
+       u8 bssid[ETH_ALEN];
+       u8 ssid[IEEE80211_MAX_SSID_LEN];
+       u8 ssid_len, ie_len;
+       u8 *ie;
+       struct ieee80211_channel *channel;
 
        unsigned long ibss_join_req;
-       struct sk_buff *probe_resp; /* ProbeResp template for IBSS */
+       /* probe response/beacon for IBSS */
+       struct sk_buff *presp, *skb;
 
        enum {
                IEEE80211_IBSS_MLME_SEARCH,
@@ -361,6 +362,8 @@ struct ieee80211_if_mesh {
        struct timer_list mesh_path_timer;
        struct sk_buff_head skb_queue;
 
+       unsigned long timers_running;
+
        bool housekeeping;
 
        u8 mesh_id[IEEE80211_MAX_MESH_ID_LEN];
@@ -430,6 +433,12 @@ struct ieee80211_sub_if_data {
 
        int drop_unencrypted;
 
+       /*
+        * keep track of whether the HT opmode (stored in
+        * vif.bss_info.ht_operation_mode) is valid.
+        */
+       bool ht_opmode_valid;
+
        /* Fragment table for host-based reassembly */
        struct ieee80211_fragment_entry fragments[IEEE80211_FRAGMENT_MAX];
        unsigned int fragment_next;
@@ -580,6 +589,7 @@ enum queue_stop_reason {
        IEEE80211_QUEUE_STOP_REASON_AGGREGATION,
        IEEE80211_QUEUE_STOP_REASON_SUSPEND,
        IEEE80211_QUEUE_STOP_REASON_PENDING,
+       IEEE80211_QUEUE_STOP_REASON_SKB_ADD,
 };
 
 struct ieee80211_master_priv {
@@ -606,6 +616,21 @@ struct ieee80211_local {
        unsigned int filter_flags; /* FIF_* */
        struct iw_statistics wstats;
        bool tim_in_locked_section; /* see ieee80211_beacon_get() */
+
+       /*
+        * suspended is true if we finished all the suspend _and_ we have
+        * not yet come up from resume. This is to be used by mac80211
+        * to ensure driver sanity during suspend and mac80211's own
+        * sanity. It can eventually be used for WoW as well.
+        */
+       bool suspended;
+
+       /*
+        * quiescing is true during the suspend process _only_ to
+        * ease timer cancelling etc.
+        */
+       bool quiescing;
+
        int tx_headroom; /* required headroom for hardware/radiotap */
 
        /* Tasklet and skb queue to process calls from IRQ mode. All frames
@@ -626,8 +651,6 @@ struct ieee80211_local {
        spinlock_t sta_lock;
        unsigned long num_sta;
        struct list_head sta_list;
-       struct list_head sta_flush_list;
-       struct work_struct sta_flush_work;
        struct sta_info *sta_hash[STA_HASH_SIZE];
        struct timer_list sta_cleanup;
 
@@ -647,9 +670,6 @@ struct ieee80211_local {
 
        struct rate_control_ref *rate_ctrl;
 
-       int rts_threshold;
-       int fragmentation_threshold;
-
        struct crypto_blkcipher *wep_tx_tfm;
        struct crypto_blkcipher *wep_rx_tfm;
        u32 wep_iv;
@@ -666,15 +686,18 @@ struct ieee80211_local {
 
 
        /* Scanning and BSS list */
+       struct mutex scan_mtx;
        bool sw_scanning, hw_scanning;
        struct cfg80211_ssid scan_ssid;
        struct cfg80211_scan_request int_scan_req;
        struct cfg80211_scan_request *scan_req;
        struct ieee80211_channel *scan_channel;
+       const u8 *orig_ies;
+       int orig_ies_len;
        int scan_channel_idx;
+       int scan_ies_len;
 
        enum { SCAN_SET_CHANNEL, SCAN_SEND_PROBE } scan_state;
-       unsigned long last_scan_completed;
        struct delayed_work scan_work;
        struct ieee80211_sub_if_data *scan_sdata;
        enum nl80211_channel_type oper_channel_type;
@@ -736,28 +759,32 @@ struct ieee80211_local {
        int wifi_wme_noack_test;
        unsigned int wmm_acm; /* bit field of ACM bits (BIT(802.1D tag)) */
 
-       bool powersave;
        bool pspolling;
+       /*
+        * PS can only be enabled when we have exactly one managed
+        * interface (and monitors) in PS, this then points there.
+        */
+       struct ieee80211_sub_if_data *ps_sdata;
        struct work_struct dynamic_ps_enable_work;
        struct work_struct dynamic_ps_disable_work;
        struct timer_list dynamic_ps_timer;
+       struct notifier_block network_latency_notifier;
 
        int user_power_level; /* in dBm */
        int power_constr_level; /* in dBm */
 
+       struct work_struct restart_work;
+
 #ifdef CONFIG_MAC80211_DEBUGFS
        struct local_debugfsdentries {
                struct dentry *rcdir;
                struct dentry *rcname;
                struct dentry *frequency;
-               struct dentry *rts_threshold;
-               struct dentry *fragmentation_threshold;
-               struct dentry *short_retry_limit;
-               struct dentry *long_retry_limit;
                struct dentry *total_ps_buffered;
                struct dentry *wep_iv;
                struct dentry *tsf;
                struct dentry *reset;
+               struct dentry *noack;
                struct dentry *statistics;
                struct local_debugfsdentries_statsdentries {
                        struct dentry *transmitted_fragment_count;
@@ -830,7 +857,7 @@ struct ieee802_11_elems {
        u8 *fh_params;
        u8 *ds_params;
        u8 *cf_params;
-       u8 *tim;
+       struct ieee80211_tim_ie *tim;
        u8 *ibss_params;
        u8 *challenge;
        u8 *wpa;
@@ -903,7 +930,6 @@ static inline int ieee80211_bssid_match(const u8 *raddr, const u8 *addr)
 
 
 int ieee80211_hw_config(struct ieee80211_local *local, u32 changed);
-int ieee80211_if_config(struct ieee80211_sub_if_data *sdata, u32 changed);
 void ieee80211_tx_set_protected(struct ieee80211_tx_data *tx);
 void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
                                      u32 changed);
@@ -927,12 +953,16 @@ int ieee80211_sta_deauthenticate(struct ieee80211_sub_if_data *sdata, u16 reason
 int ieee80211_sta_disassociate(struct ieee80211_sub_if_data *sdata, u16 reason);
 void ieee80211_send_pspoll(struct ieee80211_local *local,
                           struct ieee80211_sub_if_data *sdata);
+void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency);
+int ieee80211_max_network_latency(struct notifier_block *nb,
+                                 unsigned long data, void *dummy);
+void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
+                                     struct ieee80211_channel_sw_ie *sw_elem,
+                                     struct ieee80211_bss *bss);
+void ieee80211_sta_quiesce(struct ieee80211_sub_if_data *sdata);
+void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata);
 
 /* IBSS code */
-int ieee80211_ibss_commit(struct ieee80211_sub_if_data *sdata);
-int ieee80211_ibss_set_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size_t len);
-int ieee80211_ibss_get_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size_t *len);
-int ieee80211_ibss_set_bssid(struct ieee80211_sub_if_data *sdata, u8 *bssid);
 void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local);
 void ieee80211_ibss_setup_sdata(struct ieee80211_sub_if_data *sdata);
 ieee80211_rx_result
@@ -940,14 +970,22 @@ ieee80211_ibss_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
                       struct ieee80211_rx_status *rx_status);
 struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
                                        u8 *bssid, u8 *addr, u32 supp_rates);
+int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
+                       struct cfg80211_ibss_params *params);
+int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata);
+void ieee80211_ibss_quiesce(struct ieee80211_sub_if_data *sdata);
+void ieee80211_ibss_restart(struct ieee80211_sub_if_data *sdata);
 
 /* scan/BSS handling */
 void ieee80211_scan_work(struct work_struct *work);
+int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata,
+                                   const u8 *ssid, u8 ssid_len);
 int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata,
                           struct cfg80211_scan_request *req);
 int ieee80211_scan_results(struct ieee80211_local *local,
                           struct iw_request_info *info,
                           char *buf, size_t len);
+void ieee80211_scan_cancel(struct ieee80211_local *local);
 ieee80211_rx_result
 ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata,
                  struct sk_buff *skb,
@@ -956,9 +994,6 @@ int ieee80211_sta_set_extra_ie(struct ieee80211_sub_if_data *sdata,
                               const char *ie, size_t len);
 
 void ieee80211_mlme_notify_scan_completed(struct ieee80211_local *local);
-void ieee80211_scan_failed(struct ieee80211_local *local);
-int ieee80211_start_scan(struct ieee80211_sub_if_data *scan_sdata,
-                        struct cfg80211_scan_request *req);
 struct ieee80211_bss *
 ieee80211_bss_info_update(struct ieee80211_local *local,
                          struct ieee80211_rx_status *rx_status,
@@ -983,6 +1018,8 @@ int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata,
                             enum nl80211_iftype type);
 void ieee80211_if_remove(struct ieee80211_sub_if_data *sdata);
 void ieee80211_remove_interfaces(struct ieee80211_local *local);
+u32 __ieee80211_recalc_idle(struct ieee80211_local *local);
+void ieee80211_recalc_idle(struct ieee80211_local *local);
 
 /* tx handling */
 void ieee80211_clear_tx_pending(struct ieee80211_local *local);
@@ -995,9 +1032,6 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb, struct net_device *dev);
 void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_supported_band *sband,
                                       struct ieee80211_ht_cap *ht_cap_ie,
                                       struct ieee80211_sta_ht_cap *ht_cap);
-u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
-                       struct ieee80211_ht_info *hti,
-                       u16 ap_ht_cap_flags);
 void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u16 ssn);
 void ieee80211_send_delba(struct ieee80211_sub_if_data *sdata,
                          const u8 *da, u16 tid,
@@ -1027,24 +1061,23 @@ int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
 void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata,
                                       struct ieee80211_mgmt *mgmt,
                                       size_t len);
-void ieee80211_chswitch_timer(unsigned long data);
-void ieee80211_chswitch_work(struct work_struct *work);
-void ieee80211_process_chanswitch(struct ieee80211_sub_if_data *sdata,
-                                 struct ieee80211_channel_sw_ie *sw_elem,
-                                 struct ieee80211_bss *bss);
-void ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata,
-                                u16 capab_info, u8 *pwr_constr_elem,
-                                u8 pwr_constr_elem_len);
-
-/* Suspend/resume */
+
+/* Suspend/resume and hw reconfiguration */
+int ieee80211_reconfig(struct ieee80211_local *local);
+
 #ifdef CONFIG_PM
 int __ieee80211_suspend(struct ieee80211_hw *hw);
-int __ieee80211_resume(struct ieee80211_hw *hw);
+
+static inline int __ieee80211_resume(struct ieee80211_hw *hw)
+{
+       return ieee80211_reconfig(hw_to_local(hw));
+}
 #else
 static inline int __ieee80211_suspend(struct ieee80211_hw *hw)
 {
        return 0;
 }
+
 static inline int __ieee80211_resume(struct ieee80211_hw *hw)
 {
        return 0;
@@ -1053,19 +1086,20 @@ static inline int __ieee80211_resume(struct ieee80211_hw *hw)
 
 /* utility functions/constants */
 extern void *mac80211_wiphy_privid; /* for wiphy privid */
-extern const unsigned char rfc1042_header[6];
-extern const unsigned char bridge_tunnel_header[6];
 u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len,
                        enum nl80211_iftype type);
 int ieee80211_frame_duration(struct ieee80211_local *local, size_t len,
                             int rate, int erp, int short_preamble);
 void mac80211_ev_michael_mic_failure(struct ieee80211_sub_if_data *sdata, int keyidx,
-                                    struct ieee80211_hdr *hdr);
+                                    struct ieee80211_hdr *hdr, const u8 *tsc);
 void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata);
 void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
                      int encrypt);
 void ieee802_11_parse_elems(u8 *start, size_t len,
                            struct ieee802_11_elems *elems);
+u32 ieee802_11_parse_elems_crc(u8 *start, size_t len,
+                              struct ieee802_11_elems *elems,
+                              u64 filter, u32 crc);
 int ieee80211_set_freq(struct ieee80211_sub_if_data *sdata, int freq);
 u32 ieee80211_mandatory_rates(struct ieee80211_local *local,
                              enum ieee80211_band band);
@@ -1088,14 +1122,20 @@ void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue,
                                    enum queue_stop_reason reason);
 void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue,
                                    enum queue_stop_reason reason);
+void ieee80211_add_pending_skb(struct ieee80211_local *local,
+                              struct sk_buff *skb);
+int ieee80211_add_pending_skbs(struct ieee80211_local *local,
+                              struct sk_buff_head *skbs);
 
 void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
                         u16 transaction, u16 auth_alg,
                         u8 *extra, size_t extra_len,
                         const u8 *bssid, int encrypt);
+int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
+                            const u8 *ie, size_t ie_len);
 void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
-                             u8 *ssid, size_t ssid_len,
-                             u8 *ie, size_t ie_len);
+                             const u8 *ssid, size_t ssid_len,
+                             const u8 *ie, size_t ie_len);
 
 void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata,
                                  const size_t supp_rates_len,
index 91e8e1bacaaa1a141ed5396ee54bce2d744250fe..b7c8a4484298bc0c19f546440e33ae88ce1b8210 100644 (file)
@@ -20,6 +20,7 @@
 #include "debugfs_netdev.h"
 #include "mesh.h"
 #include "led.h"
+#include "driver-ops.h"
 
 /**
  * DOC: Interface list locking
@@ -164,14 +165,12 @@ static int ieee80211_open(struct net_device *dev)
        }
 
        if (local->open_count == 0) {
-               res = 0;
-               if (local->ops->start)
-                       res = local->ops->start(local_to_hw(local));
+               res = drv_start(local);
                if (res)
                        goto err_del_bss;
                /* we're brought up, everything changes */
                hw_reconf_flags = ~0;
-               ieee80211_led_radio(local, local->hw.conf.radio_enabled);
+               ieee80211_led_radio(local, true);
        }
 
        /*
@@ -199,8 +198,8 @@ static int ieee80211_open(struct net_device *dev)
         * Validate the MAC address for this device.
         */
        if (!is_valid_ether_addr(dev->dev_addr)) {
-               if (!local->open_count && local->ops->stop)
-                       local->ops->stop(local_to_hw(local));
+               if (!local->open_count)
+                       drv_stop(local);
                return -EADDRNOTAVAIL;
        }
 
@@ -235,17 +234,13 @@ static int ieee80211_open(struct net_device *dev)
                netif_addr_unlock_bh(local->mdev);
                break;
        case NL80211_IFTYPE_STATION:
-       case NL80211_IFTYPE_ADHOC:
-               if (sdata->vif.type == NL80211_IFTYPE_STATION)
-                       sdata->u.mgd.flags &= ~IEEE80211_STA_PREV_BSSID_SET;
-               else
-                       sdata->u.ibss.flags &= ~IEEE80211_IBSS_PREV_BSSID_SET;
+               sdata->u.mgd.flags &= ~IEEE80211_STA_PREV_BSSID_SET;
                /* fall through */
        default:
                conf.vif = &sdata->vif;
                conf.type = sdata->vif.type;
                conf.mac_addr = dev->dev_addr;
-               res = local->ops->add_interface(local_to_hw(local), &conf);
+               res = drv_add_interface(local, &conf);
                if (res)
                        goto err_stop;
 
@@ -306,6 +301,8 @@ static int ieee80211_open(struct net_device *dev)
        if (sdata->flags & IEEE80211_SDATA_PROMISC)
                atomic_inc(&local->iff_promiscs);
 
+       hw_reconf_flags |= __ieee80211_recalc_idle(local);
+
        local->open_count++;
        if (hw_reconf_flags) {
                ieee80211_hw_config(local, hw_reconf_flags);
@@ -317,6 +314,8 @@ static int ieee80211_open(struct net_device *dev)
                ieee80211_set_wmm_default(sdata);
        }
 
+       ieee80211_recalc_ps(local, -1);
+
        /*
         * ieee80211_sta_work is disabled while network interface
         * is down. Therefore, some configuration changes may not
@@ -325,17 +324,15 @@ static int ieee80211_open(struct net_device *dev)
         */
        if (sdata->vif.type == NL80211_IFTYPE_STATION)
                queue_work(local->hw.workqueue, &sdata->u.mgd.work);
-       else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
-               queue_work(local->hw.workqueue, &sdata->u.ibss.work);
 
        netif_tx_start_all_queues(dev);
 
        return 0;
  err_del_interface:
-       local->ops->remove_interface(local_to_hw(local), &conf);
+       drv_remove_interface(local, &conf);
  err_stop:
-       if (!local->open_count && local->ops->stop)
-               local->ops->stop(local_to_hw(local));
+       if (!local->open_count)
+               drv_stop(local);
  err_del_bss:
        sdata->bss = NULL;
        if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
@@ -497,7 +494,6 @@ static int ieee80211_stop(struct net_device *dev)
                /* fall through */
        case NL80211_IFTYPE_ADHOC:
                if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
-                       memset(sdata->u.ibss.bssid, 0, ETH_ALEN);
                        del_timer_sync(&sdata->u.ibss.timer);
                        cancel_work_sync(&sdata->u.ibss.work);
                        synchronize_rcu();
@@ -549,19 +545,22 @@ static int ieee80211_stop(struct net_device *dev)
                conf.mac_addr = dev->dev_addr;
                /* disable all keys for as long as this netdev is down */
                ieee80211_disable_keys(sdata);
-               local->ops->remove_interface(local_to_hw(local), &conf);
+               drv_remove_interface(local, &conf);
        }
 
        sdata->bss = NULL;
 
+       hw_reconf_flags |= __ieee80211_recalc_idle(local);
+
+       ieee80211_recalc_ps(local, -1);
+
        if (local->open_count == 0) {
                if (netif_running(local->mdev))
                        dev_close(local->mdev);
 
-               if (local->ops->stop)
-                       local->ops->stop(local_to_hw(local));
+               drv_stop(local);
 
-               ieee80211_led_radio(local, 0);
+               ieee80211_led_radio(local, false);
 
                flush_workqueue(local->hw.workqueue);
 
@@ -649,7 +648,8 @@ static void ieee80211_teardown_sdata(struct net_device *dev)
                        mesh_rmc_free(sdata);
                break;
        case NL80211_IFTYPE_ADHOC:
-               kfree_skb(sdata->u.ibss.probe_resp);
+               if (WARN_ON(sdata->u.ibss.presp))
+                       kfree_skb(sdata->u.ibss.presp);
                break;
        case NL80211_IFTYPE_STATION:
                kfree(sdata->u.mgd.extra_ie);
@@ -896,3 +896,74 @@ void ieee80211_remove_interfaces(struct ieee80211_local *local)
                unregister_netdevice(sdata->dev);
        }
 }
+
+static u32 ieee80211_idle_off(struct ieee80211_local *local,
+                             const char *reason)
+{
+       if (!(local->hw.conf.flags & IEEE80211_CONF_IDLE))
+               return 0;
+
+#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
+       printk(KERN_DEBUG "%s: device no longer idle - %s\n",
+              wiphy_name(local->hw.wiphy), reason);
+#endif
+
+       local->hw.conf.flags &= ~IEEE80211_CONF_IDLE;
+       return IEEE80211_CONF_CHANGE_IDLE;
+}
+
+static u32 ieee80211_idle_on(struct ieee80211_local *local)
+{
+       if (local->hw.conf.flags & IEEE80211_CONF_IDLE)
+               return 0;
+
+#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
+       printk(KERN_DEBUG "%s: device now idle\n",
+              wiphy_name(local->hw.wiphy));
+#endif
+
+       local->hw.conf.flags |= IEEE80211_CONF_IDLE;
+       return IEEE80211_CONF_CHANGE_IDLE;
+}
+
+u32 __ieee80211_recalc_idle(struct ieee80211_local *local)
+{
+       struct ieee80211_sub_if_data *sdata;
+       int count = 0;
+
+       if (local->hw_scanning || local->sw_scanning)
+               return ieee80211_idle_off(local, "scanning");
+
+       list_for_each_entry(sdata, &local->interfaces, list) {
+               if (!netif_running(sdata->dev))
+                       continue;
+               /* do not count disabled managed interfaces */
+               if (sdata->vif.type == NL80211_IFTYPE_STATION &&
+                   sdata->u.mgd.state == IEEE80211_STA_MLME_DISABLED)
+                       continue;
+               /* do not count unused IBSS interfaces */
+               if (sdata->vif.type == NL80211_IFTYPE_ADHOC &&
+                   !sdata->u.ibss.ssid_len)
+                       continue;
+               /* count everything else */
+               count++;
+       }
+
+       if (!count)
+               return ieee80211_idle_on(local);
+       else
+               return ieee80211_idle_off(local, "in use");
+
+       return 0;
+}
+
+void ieee80211_recalc_idle(struct ieee80211_local *local)
+{
+       u32 chg;
+
+       mutex_lock(&local->iflist_mtx);
+       chg = __ieee80211_recalc_idle(local);
+       mutex_unlock(&local->iflist_mtx);
+       if (chg)
+               ieee80211_hw_config(local, chg);
+}
index 687acf23054d9ecfefeaa810d360020e360a3a83..ce267565e18076ec4a852e52aa54bcdc418c0bbf 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/rtnetlink.h>
 #include <net/mac80211.h>
 #include "ieee80211_i.h"
+#include "driver-ops.h"
 #include "debugfs_key.h"
 #include "aes_ccm.h"
 #include "aes_cmac.h"
@@ -136,8 +137,7 @@ static void ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
                                     struct ieee80211_sub_if_data,
                                     u.ap);
 
-       ret = key->local->ops->set_key(local_to_hw(key->local), SET_KEY,
-                                      &sdata->vif, sta, &key->conf);
+       ret = drv_set_key(key->local, SET_KEY, &sdata->vif, sta, &key->conf);
 
        if (!ret) {
                spin_lock(&todo_lock);
@@ -179,8 +179,8 @@ static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key)
                                     struct ieee80211_sub_if_data,
                                     u.ap);
 
-       ret = key->local->ops->set_key(local_to_hw(key->local), DISABLE_KEY,
-                                      &sdata->vif, sta, &key->conf);
+       ret = drv_set_key(key->local, DISABLE_KEY, &sdata->vif,
+                         sta, &key->conf);
 
        if (ret)
                printk(KERN_ERR "mac80211-%s: failed to remove key "
@@ -290,9 +290,11 @@ static void __ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,
 struct ieee80211_key *ieee80211_key_alloc(enum ieee80211_key_alg alg,
                                          int idx,
                                          size_t key_len,
-                                         const u8 *key_data)
+                                         const u8 *key_data,
+                                         size_t seq_len, const u8 *seq)
 {
        struct ieee80211_key *key;
+       int i, j;
 
        BUG_ON(idx < 0 || idx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS);
 
@@ -318,14 +320,31 @@ struct ieee80211_key *ieee80211_key_alloc(enum ieee80211_key_alg alg,
        case ALG_TKIP:
                key->conf.iv_len = TKIP_IV_LEN;
                key->conf.icv_len = TKIP_ICV_LEN;
+               if (seq) {
+                       for (i = 0; i < NUM_RX_DATA_QUEUES; i++) {
+                               key->u.tkip.rx[i].iv32 =
+                                       get_unaligned_le32(&seq[2]);
+                               key->u.tkip.rx[i].iv16 =
+                                       get_unaligned_le16(seq);
+                       }
+               }
                break;
        case ALG_CCMP:
                key->conf.iv_len = CCMP_HDR_LEN;
                key->conf.icv_len = CCMP_MIC_LEN;
+               if (seq) {
+                       for (i = 0; i < NUM_RX_DATA_QUEUES; i++)
+                               for (j = 0; j < CCMP_PN_LEN; j++)
+                                       key->u.ccmp.rx_pn[i][j] =
+                                               seq[CCMP_PN_LEN - j - 1];
+               }
                break;
        case ALG_AES_CMAC:
                key->conf.iv_len = 0;
                key->conf.icv_len = sizeof(struct ieee80211_mmie);
+               if (seq)
+                       for (j = 0; j < 6; j++)
+                               key->u.aes_cmac.rx_pn[j] = seq[6 - j - 1];
                break;
        }
        memcpy(key->conf.key, key_data, key_len);
index 215d3ef42a4f3c8a3db8017d9792caca7bddff6f..9572e00f532cc670696efb07088a6d0731e2ac17 100644 (file)
@@ -144,7 +144,8 @@ struct ieee80211_key {
 struct ieee80211_key *ieee80211_key_alloc(enum ieee80211_key_alg alg,
                                          int idx,
                                          size_t key_len,
-                                         const u8 *key_data);
+                                         const u8 *key_data,
+                                         size_t seq_len, const u8 *seq);
 /*
  * Insert a key into data structures (sdata, sta if necessary)
  * to make it used, free old key.
index 14134193cd17120e60b4960283ae3782eb2af0c8..092a017b237e35faa10ef4c72a5f0e21b64c33b6 100644 (file)
 #include <linux/wireless.h>
 #include <linux/rtnetlink.h>
 #include <linux/bitmap.h>
+#include <linux/pm_qos_params.h>
 #include <net/net_namespace.h>
 #include <net/cfg80211.h>
 
 #include "ieee80211_i.h"
+#include "driver-ops.h"
 #include "rate.h"
 #include "mesh.h"
 #include "wep.h"
@@ -80,10 +82,9 @@ void ieee80211_configure_filter(struct ieee80211_local *local)
        /* be a bit nasty */
        new_flags |= (1<<31);
 
-       local->ops->configure_filter(local_to_hw(local),
-                                    changed_flags, &new_flags,
-                                    local->mdev->mc_count,
-                                    local->mdev->mc_list);
+       drv_configure_filter(local, changed_flags, &new_flags,
+                            local->mdev->mc_count,
+                            local->mdev->mc_list);
 
        WARN_ON(new_flags & (1<<31));
 
@@ -151,93 +152,19 @@ static void ieee80211_master_set_multicast_list(struct net_device *dev)
        ieee80211_configure_filter(local);
 }
 
-/* everything else */
-
-int ieee80211_if_config(struct ieee80211_sub_if_data *sdata, u32 changed)
-{
-       struct ieee80211_local *local = sdata->local;
-       struct ieee80211_if_conf conf;
-
-       if (WARN_ON(!netif_running(sdata->dev)))
-               return 0;
-
-       memset(&conf, 0, sizeof(conf));
-
-       if (sdata->vif.type == NL80211_IFTYPE_STATION)
-               conf.bssid = sdata->u.mgd.bssid;
-       else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
-               conf.bssid = sdata->u.ibss.bssid;
-       else if (sdata->vif.type == NL80211_IFTYPE_AP)
-               conf.bssid = sdata->dev->dev_addr;
-       else if (ieee80211_vif_is_mesh(&sdata->vif)) {
-               static const u8 zero[ETH_ALEN] = { 0 };
-               conf.bssid = zero;
-       } else {
-               WARN_ON(1);
-               return -EINVAL;
-       }
-
-       if (!local->ops->config_interface)
-               return 0;
-
-       switch (sdata->vif.type) {
-       case NL80211_IFTYPE_AP:
-       case NL80211_IFTYPE_ADHOC:
-       case NL80211_IFTYPE_MESH_POINT:
-               break;
-       default:
-               /* do not warn to simplify caller in scan.c */
-               changed &= ~IEEE80211_IFCC_BEACON_ENABLED;
-               if (WARN_ON(changed & IEEE80211_IFCC_BEACON))
-                       return -EINVAL;
-               changed &= ~IEEE80211_IFCC_BEACON;
-               break;
-       }
-
-       if (changed & IEEE80211_IFCC_BEACON_ENABLED) {
-               if (local->sw_scanning) {
-                       conf.enable_beacon = false;
-               } else {
-                       /*
-                        * Beacon should be enabled, but AP mode must
-                        * check whether there is a beacon configured.
-                        */
-                       switch (sdata->vif.type) {
-                       case NL80211_IFTYPE_AP:
-                               conf.enable_beacon =
-                                       !!rcu_dereference(sdata->u.ap.beacon);
-                               break;
-                       case NL80211_IFTYPE_ADHOC:
-                               conf.enable_beacon = !!sdata->u.ibss.probe_resp;
-                               break;
-                       case NL80211_IFTYPE_MESH_POINT:
-                               conf.enable_beacon = true;
-                               break;
-                       default:
-                               /* not reached */
-                               WARN_ON(1);
-                               break;
-                       }
-               }
-       }
-
-       conf.changed = changed;
-
-       return local->ops->config_interface(local_to_hw(local),
-                                           &sdata->vif, &conf);
-}
-
 int ieee80211_hw_config(struct ieee80211_local *local, u32 changed)
 {
-       struct ieee80211_channel *chan;
+       struct ieee80211_channel *chan, *scan_chan;
        int ret = 0;
        int power;
        enum nl80211_channel_type channel_type;
 
        might_sleep();
 
-       if (local->sw_scanning) {
-               chan = local->scan_channel;
+       scan_chan = local->scan_channel;
+
+       if (scan_chan) {
+               chan = scan_chan;
                channel_type = NL80211_CHAN_NO_HT;
        } else {
                chan = local->oper_channel;
@@ -251,7 +178,7 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed)
                changed |= IEEE80211_CONF_CHANGE_CHANNEL;
        }
 
-       if (local->sw_scanning)
+       if (scan_chan)
                power = chan->max_power;
        else
                power = local->power_constr_level ?
@@ -267,7 +194,7 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed)
        }
 
        if (changed && local->open_count) {
-               ret = local->ops->config(local_to_hw(local), changed);
+               ret = drv_config(local, changed);
                /*
                 * Goal:
                 * HW reconfiguration should never fail, the driver has told
@@ -292,18 +219,78 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
                                      u32 changed)
 {
        struct ieee80211_local *local = sdata->local;
+       static const u8 zero[ETH_ALEN] = { 0 };
 
-       if (WARN_ON(sdata->vif.type == NL80211_IFTYPE_AP_VLAN))
+       if (!changed)
                return;
 
-       if (!changed)
+       if (sdata->vif.type == NL80211_IFTYPE_STATION) {
+               /*
+                * While not associated, claim a BSSID of all-zeroes
+                * so that drivers don't do any weird things with the
+                * BSSID at that time.
+                */
+               if (sdata->vif.bss_conf.assoc)
+                       sdata->vif.bss_conf.bssid = sdata->u.mgd.bssid;
+               else
+                       sdata->vif.bss_conf.bssid = zero;
+       } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
+               sdata->vif.bss_conf.bssid = sdata->u.ibss.bssid;
+       else if (sdata->vif.type == NL80211_IFTYPE_AP)
+               sdata->vif.bss_conf.bssid = sdata->dev->dev_addr;
+       else if (ieee80211_vif_is_mesh(&sdata->vif)) {
+               sdata->vif.bss_conf.bssid = zero;
+       } else {
+               WARN_ON(1);
                return;
+       }
+
+       switch (sdata->vif.type) {
+       case NL80211_IFTYPE_AP:
+       case NL80211_IFTYPE_ADHOC:
+       case NL80211_IFTYPE_MESH_POINT:
+               break;
+       default:
+               /* do not warn to simplify caller in scan.c */
+               changed &= ~BSS_CHANGED_BEACON_ENABLED;
+               if (WARN_ON(changed & BSS_CHANGED_BEACON))
+                       return;
+               break;
+       }
+
+       if (changed & BSS_CHANGED_BEACON_ENABLED) {
+               if (local->sw_scanning) {
+                       sdata->vif.bss_conf.enable_beacon = false;
+               } else {
+                       /*
+                        * Beacon should be enabled, but AP mode must
+                        * check whether there is a beacon configured.
+                        */
+                       switch (sdata->vif.type) {
+                       case NL80211_IFTYPE_AP:
+                               sdata->vif.bss_conf.enable_beacon =
+                                       !!rcu_dereference(sdata->u.ap.beacon);
+                               break;
+                       case NL80211_IFTYPE_ADHOC:
+                               sdata->vif.bss_conf.enable_beacon =
+                                       !!rcu_dereference(sdata->u.ibss.presp);
+                               break;
+                       case NL80211_IFTYPE_MESH_POINT:
+                               sdata->vif.bss_conf.enable_beacon = true;
+                               break;
+                       default:
+                               /* not reached */
+                               WARN_ON(1);
+                               break;
+                       }
+               }
+       }
+
+       drv_bss_info_changed(local, &sdata->vif,
+                            &sdata->vif.bss_conf, changed);
 
-       if (local->ops->bss_info_changed)
-               local->ops->bss_info_changed(local_to_hw(local),
-                                            &sdata->vif,
-                                            &sdata->vif.bss_conf,
-                                            changed);
+       /* DEPRECATED */
+       local->hw.conf.beacon_int = sdata->vif.bss_conf.beacon_int;
 }
 
 u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata)
@@ -382,60 +369,12 @@ static void ieee80211_tasklet_handler(unsigned long data)
        }
 }
 
-/* Remove added headers (e.g., QoS control), encryption header/MIC, etc. to
- * make a prepared TX frame (one that has been given to hw) to look like brand
- * new IEEE 802.11 frame that is ready to go through TX processing again.
- */
-static void ieee80211_remove_tx_extra(struct ieee80211_local *local,
-                                     struct ieee80211_key *key,
-                                     struct sk_buff *skb)
-{
-       unsigned int hdrlen, iv_len, mic_len;
-       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-
-       hdrlen = ieee80211_hdrlen(hdr->frame_control);
-
-       if (!key)
-               goto no_key;
-
-       switch (key->conf.alg) {
-       case ALG_WEP:
-               iv_len = WEP_IV_LEN;
-               mic_len = WEP_ICV_LEN;
-               break;
-       case ALG_TKIP:
-               iv_len = TKIP_IV_LEN;
-               mic_len = TKIP_ICV_LEN;
-               break;
-       case ALG_CCMP:
-               iv_len = CCMP_HDR_LEN;
-               mic_len = CCMP_MIC_LEN;
-               break;
-       default:
-               goto no_key;
-       }
-
-       if (skb->len >= hdrlen + mic_len &&
-           !(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))
-               skb_trim(skb, skb->len - mic_len);
-       if (skb->len >= hdrlen + iv_len) {
-               memmove(skb->data + iv_len, skb->data, hdrlen);
-               hdr = (struct ieee80211_hdr *)skb_pull(skb, iv_len);
-       }
-
-no_key:
-       if (ieee80211_is_data_qos(hdr->frame_control)) {
-               hdr->frame_control &= ~cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
-               memmove(skb->data + IEEE80211_QOS_CTL_LEN, skb->data,
-                       hdrlen - IEEE80211_QOS_CTL_LEN);
-               skb_pull(skb, IEEE80211_QOS_CTL_LEN);
-       }
-}
-
 static void ieee80211_handle_filtered_frame(struct ieee80211_local *local,
                                            struct sta_info *sta,
                                            struct sk_buff *skb)
 {
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+
        sta->tx_filtered_count++;
 
        /*
@@ -477,16 +416,15 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local,
         */
        if (test_sta_flags(sta, WLAN_STA_PS) &&
            skb_queue_len(&sta->tx_filtered) < STA_MAX_TX_BUFFER) {
-               ieee80211_remove_tx_extra(local, sta->key, skb);
                skb_queue_tail(&sta->tx_filtered, skb);
                return;
        }
 
-       if (!test_sta_flags(sta, WLAN_STA_PS) && !skb->requeue) {
+       if (!test_sta_flags(sta, WLAN_STA_PS) &&
+           !(info->flags & IEEE80211_TX_INTFL_RETRIED)) {
                /* Software retry the packet once */
-               skb->requeue = 1;
-               ieee80211_remove_tx_extra(local, sta->key, skb);
-               dev_queue_xmit(skb);
+               info->flags |= IEEE80211_TX_INTFL_RETRIED;
+               ieee80211_add_pending_skb(local, skb);
                return;
        }
 
@@ -696,6 +634,28 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
 }
 EXPORT_SYMBOL(ieee80211_tx_status);
 
+static void ieee80211_restart_work(struct work_struct *work)
+{
+       struct ieee80211_local *local =
+               container_of(work, struct ieee80211_local, restart_work);
+
+       rtnl_lock();
+       ieee80211_reconfig(local);
+       rtnl_unlock();
+}
+
+void ieee80211_restart_hw(struct ieee80211_hw *hw)
+{
+       struct ieee80211_local *local = hw_to_local(hw);
+
+       /* use this reason, __ieee80211_resume will unblock it */
+       ieee80211_stop_queues_by_reason(hw,
+               IEEE80211_QUEUE_STOP_REASON_SUSPEND);
+
+       schedule_work(&local->restart_work);
+}
+EXPORT_SYMBOL(ieee80211_restart_hw);
+
 struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
                                        const struct ieee80211_ops *ops)
 {
@@ -718,9 +678,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
         * +-------------------------+
         *
         */
-       priv_size = ((sizeof(struct ieee80211_local) +
-                     NETDEV_ALIGN_CONST) & ~NETDEV_ALIGN_CONST) +
-                   priv_data_len;
+       priv_size = ALIGN(sizeof(*local), NETDEV_ALIGN) + priv_data_len;
 
        wiphy = wiphy_new(&mac80211_config_ops, priv_size);
 
@@ -728,17 +686,16 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
                return NULL;
 
        wiphy->privid = mac80211_wiphy_privid;
-       wiphy->max_scan_ssids = 4;
+
        /* Yes, putting cfg80211_bss into ieee80211_bss is a hack */
        wiphy->bss_priv_size = sizeof(struct ieee80211_bss) -
                               sizeof(struct cfg80211_bss);
 
        local = wiphy_priv(wiphy);
+
        local->hw.wiphy = wiphy;
 
-       local->hw.priv = (char *)local +
-                        ((sizeof(struct ieee80211_local) +
-                          NETDEV_ALIGN_CONST) & ~NETDEV_ALIGN_CONST);
+       local->hw.priv = (char *)local + ALIGN(sizeof(*local), NETDEV_ALIGN);
 
        BUG_ON(!ops->tx);
        BUG_ON(!ops->start);
@@ -752,15 +709,14 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
        /* set up some defaults */
        local->hw.queues = 1;
        local->hw.max_rates = 1;
-       local->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD;
-       local->fragmentation_threshold = IEEE80211_MAX_FRAG_THRESHOLD;
-       local->hw.conf.long_frame_max_tx_count = 4;
-       local->hw.conf.short_frame_max_tx_count = 7;
+       local->hw.conf.long_frame_max_tx_count = wiphy->retry_long;
+       local->hw.conf.short_frame_max_tx_count = wiphy->retry_short;
        local->hw.conf.radio_enabled = true;
        local->user_power_level = -1;
 
        INIT_LIST_HEAD(&local->interfaces);
        mutex_init(&local->iflist_mtx);
+       mutex_init(&local->scan_mtx);
 
        spin_lock_init(&local->key_lock);
 
@@ -768,6 +724,8 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
 
        INIT_DELAYED_WORK(&local->scan_work, ieee80211_scan_work);
 
+       INIT_WORK(&local->restart_work, ieee80211_restart_work);
+
        INIT_WORK(&local->dynamic_ps_enable_work,
                  ieee80211_dynamic_ps_enable_work);
        INIT_WORK(&local->dynamic_ps_disable_work,
@@ -821,7 +779,17 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
        enum ieee80211_band band;
        struct net_device *mdev;
        struct ieee80211_master_priv *mpriv;
-       int channels, i, j;
+       int channels, i, j, max_bitrates;
+       bool supp_ht;
+       static const u32 cipher_suites[] = {
+               WLAN_CIPHER_SUITE_WEP40,
+               WLAN_CIPHER_SUITE_WEP104,
+               WLAN_CIPHER_SUITE_TKIP,
+               WLAN_CIPHER_SUITE_CCMP,
+
+               /* keep last -- depends on hw flags! */
+               WLAN_CIPHER_SUITE_AES_CMAC
+       };
 
        /*
         * generic code guarantees at least one band,
@@ -829,18 +797,25 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
         * that hw.conf.channel is assigned
         */
        channels = 0;
+       max_bitrates = 0;
+       supp_ht = false;
        for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
                struct ieee80211_supported_band *sband;
 
                sband = local->hw.wiphy->bands[band];
-               if (sband && !local->oper_channel) {
+               if (!sband)
+                       continue;
+               if (!local->oper_channel) {
                        /* init channel we're on */
                        local->hw.conf.channel =
-                       local->oper_channel =
-                       local->scan_channel = &sband->channels[0];
+                       local->oper_channel = &sband->channels[0];
+                       local->hw.conf.channel_type = NL80211_CHAN_NO_HT;
                }
-               if (sband)
-                       channels += sband->n_channels;
+               channels += sband->n_channels;
+
+               if (max_bitrates < sband->n_bitrates)
+                       max_bitrates = sband->n_bitrates;
+               supp_ht = supp_ht || sband->ht_cap.ht_supported;
        }
 
        local->int_scan_req.n_channels = channels;
@@ -860,6 +835,37 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
        else if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)
                local->hw.wiphy->signal_type = CFG80211_SIGNAL_TYPE_UNSPEC;
 
+       /*
+        * Calculate scan IE length -- we need this to alloc
+        * memory and to subtract from the driver limit. It
+        * includes the (extended) supported rates and HT
+        * information -- SSID is the driver's responsibility.
+        */
+       local->scan_ies_len = 4 + max_bitrates; /* (ext) supp rates */
+       if (supp_ht)
+               local->scan_ies_len += 2 + sizeof(struct ieee80211_ht_cap);
+
+       if (!local->ops->hw_scan) {
+               /* For hw_scan, driver needs to set these up. */
+               local->hw.wiphy->max_scan_ssids = 4;
+               local->hw.wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN;
+       }
+
+       /*
+        * If the driver supports any scan IEs, then assume the
+        * limit includes the IEs mac80211 will add, otherwise
+        * leave it at zero and let the driver sort it out; we
+        * still pass our IEs to the driver but userspace will
+        * not be allowed to in that case.
+        */
+       if (local->hw.wiphy->max_scan_ie_len)
+               local->hw.wiphy->max_scan_ie_len -= local->scan_ies_len;
+
+       local->hw.wiphy->cipher_suites = cipher_suites;
+       local->hw.wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
+       if (!(local->hw.flags & IEEE80211_HW_MFP_CAPABLE))
+               local->hw.wiphy->n_cipher_suites--;
+
        result = wiphy_register(local->hw.wiphy);
        if (result < 0)
                goto fail_wiphy_register;
@@ -898,9 +904,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
 
        debugfs_hw_add(local);
 
-       if (local->hw.conf.beacon_int < 10)
-               local->hw.conf.beacon_int = 100;
-
        if (local->hw.max_listen_interval == 0)
                local->hw.max_listen_interval = 1;
 
@@ -965,25 +968,38 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
                }
        }
 
+       local->network_latency_notifier.notifier_call =
+               ieee80211_max_network_latency;
+       result = pm_qos_add_notifier(PM_QOS_NETWORK_LATENCY,
+                                    &local->network_latency_notifier);
+
+       if (result) {
+               rtnl_lock();
+               goto fail_pm_qos;
+       }
+
        return 0;
 
-fail_rate:
+ fail_pm_qos:
+       ieee80211_led_exit(local);
+       ieee80211_remove_interfaces(local);
+ fail_rate:
        unregister_netdevice(local->mdev);
        local->mdev = NULL;
-fail_dev:
+ fail_dev:
        rtnl_unlock();
        ieee80211_wep_free(local);
-fail_wep:
+ fail_wep:
        sta_info_stop(local);
-fail_sta_info:
+ fail_sta_info:
        debugfs_hw_del(local);
        destroy_workqueue(local->hw.workqueue);
-fail_workqueue:
+ fail_workqueue:
        if (local->mdev)
                free_netdev(local->mdev);
-fail_mdev_alloc:
+ fail_mdev_alloc:
        wiphy_unregister(local->hw.wiphy);
-fail_wiphy_register:
+ fail_wiphy_register:
        kfree(local->int_scan_req.channels);
        return result;
 }
@@ -996,6 +1012,9 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw)
        tasklet_kill(&local->tx_pending_tasklet);
        tasklet_kill(&local->tasklet);
 
+       pm_qos_remove_notifier(PM_QOS_NETWORK_LATENCY,
+                              &local->network_latency_notifier);
+
        rtnl_lock();
 
        /*
@@ -1038,6 +1057,7 @@ void ieee80211_free_hw(struct ieee80211_hw *hw)
        struct ieee80211_local *local = hw_to_local(hw);
 
        mutex_destroy(&local->iflist_mtx);
+       mutex_destroy(&local->scan_mtx);
 
        wiphy_free(local->hw.wiphy);
 }
index 9a3e5de0410a802154dbbf71fa48253d4969628c..fc712e60705da4b8a8785b305cec79300be955c7 100644 (file)
@@ -21,6 +21,9 @@
 #define CAPAB_OFFSET 17
 #define ACCEPT_PLINKS 0x80
 
+#define TMR_RUNNING_HK 0
+#define TMR_RUNNING_MP 1
+
 int mesh_allocated;
 static struct kmem_cache *rm_cache;
 
@@ -45,6 +48,12 @@ static void ieee80211_mesh_housekeeping_timer(unsigned long data)
        struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
 
        ifmsh->housekeeping = true;
+
+       if (local->quiescing) {
+               set_bit(TMR_RUNNING_HK, &ifmsh->timers_running);
+               return;
+       }
+
        queue_work(local->hw.workqueue, &ifmsh->work);
 }
 
@@ -343,6 +352,11 @@ static void ieee80211_mesh_path_timer(unsigned long data)
        struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
        struct ieee80211_local *local = sdata->local;
 
+       if (local->quiescing) {
+               set_bit(TMR_RUNNING_MP, &ifmsh->timers_running);
+               return;
+       }
+
        queue_work(local->hw.workqueue, &ifmsh->work);
 }
 
@@ -417,13 +431,39 @@ static void ieee80211_mesh_housekeeping(struct ieee80211_sub_if_data *sdata,
 
        free_plinks = mesh_plink_availables(sdata);
        if (free_plinks != sdata->u.mesh.accepting_plinks)
-               ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON);
+               ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON);
 
        ifmsh->housekeeping = false;
        mod_timer(&ifmsh->housekeeping_timer,
                  round_jiffies(jiffies + IEEE80211_MESH_HOUSEKEEPING_INTERVAL));
 }
 
+#ifdef CONFIG_PM
+void ieee80211_mesh_quiesce(struct ieee80211_sub_if_data *sdata)
+{
+       struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
+
+       /* might restart the timer but that doesn't matter */
+       cancel_work_sync(&ifmsh->work);
+
+       /* use atomic bitops in case both timers fire at the same time */
+
+       if (del_timer_sync(&ifmsh->housekeeping_timer))
+               set_bit(TMR_RUNNING_HK, &ifmsh->timers_running);
+       if (del_timer_sync(&ifmsh->mesh_path_timer))
+               set_bit(TMR_RUNNING_MP, &ifmsh->timers_running);
+}
+
+void ieee80211_mesh_restart(struct ieee80211_sub_if_data *sdata)
+{
+       struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
+
+       if (test_and_clear_bit(TMR_RUNNING_HK, &ifmsh->timers_running))
+               add_timer(&ifmsh->housekeeping_timer);
+       if (test_and_clear_bit(TMR_RUNNING_MP, &ifmsh->timers_running))
+               add_timer(&ifmsh->mesh_path_timer);
+}
+#endif
 
 void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
 {
@@ -432,8 +472,8 @@ void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
 
        ifmsh->housekeeping = true;
        queue_work(local->hw.workqueue, &ifmsh->work);
-       ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON |
-                                  IEEE80211_IFCC_BEACON_ENABLED);
+       ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON |
+                                               BSS_CHANGED_BEACON_ENABLED);
 }
 
 void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata)
index d891d7ddccd74cfcbf17b6c8adfb40936c829634..c7d72819cdd2bdb448d9c323fbf52c22ae5cc47a 100644 (file)
@@ -191,12 +191,8 @@ struct mesh_rmc {
 #define PLINK_CATEGORY         30
 #define MESH_PATH_SEL_CATEGORY 32
 
-/* Mesh Header Flags */
-#define IEEE80211S_FLAGS_AE    0x3
-
 /* Public interfaces */
 /* Various */
-int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr);
 int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr,
                struct ieee80211_sub_if_data *sdata);
 int mesh_rmc_check(u8 *addr, struct ieee80211s_hdr *mesh_hdr,
@@ -267,6 +263,8 @@ void mesh_path_timer(unsigned long data);
 void mesh_path_flush_by_nexthop(struct sta_info *sta);
 void mesh_path_discard_frame(struct sk_buff *skb,
                struct ieee80211_sub_if_data *sdata);
+void mesh_path_quiesce(struct ieee80211_sub_if_data *sdata);
+void mesh_path_restart(struct ieee80211_sub_if_data *sdata);
 
 #ifdef CONFIG_MAC80211_MESH
 extern int mesh_allocated;
@@ -294,10 +292,20 @@ static inline void mesh_path_activate(struct mesh_path *mpath)
 
 void ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local);
 
+void ieee80211_mesh_quiesce(struct ieee80211_sub_if_data *sdata);
+void ieee80211_mesh_restart(struct ieee80211_sub_if_data *sdata);
+void mesh_plink_quiesce(struct sta_info *sta);
+void mesh_plink_restart(struct sta_info *sta);
 #else
 #define mesh_allocated 0
 static inline void
 ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local) {}
+static inline void ieee80211_mesh_quiesce(struct ieee80211_sub_if_data *sdata)
+{}
+static inline void ieee80211_mesh_restart(struct ieee80211_sub_if_data *sdata)
+{}
+static inline void mesh_plink_quiesce(struct sta_info *sta) {}
+static inline void mesh_plink_restart(struct sta_info *sta) {}
 #endif
 
 #endif /* IEEE80211S_H */
index 60b35accda9147305f9213215515c509495bdf28..003cb470ac8478c84329bf29a0687484a2e6acb1 100644 (file)
@@ -836,8 +836,14 @@ void mesh_path_timer(unsigned long data)
        mpath = rcu_dereference(mpath);
        if (!mpath)
                goto endmpathtimer;
-       spin_lock_bh(&mpath->state_lock);
        sdata = mpath->sdata;
+
+       if (sdata->local->quiescing) {
+               rcu_read_unlock();
+               return;
+       }
+
+       spin_lock_bh(&mpath->state_lock);
        if (mpath->flags & MESH_PATH_RESOLVED ||
                        (!(mpath->flags & MESH_PATH_RESOLVING)))
                mpath->flags &= ~(MESH_PATH_RESOLVING | MESH_PATH_RESOLVED);
index a8bbdeca013a1b3caf8c928226b7877b88a57cf6..cb14253587f1e297cb8d3997165c059e53a0e3f0 100644 (file)
@@ -266,6 +266,11 @@ static void mesh_plink_timer(unsigned long data)
         */
        sta = (struct sta_info *) data;
 
+       if (sta->sdata->local->quiescing) {
+               sta->plink_timer_was_running = true;
+               return;
+       }
+
        spin_lock_bh(&sta->lock);
        if (sta->ignore_plink_timer) {
                sta->ignore_plink_timer = false;
@@ -322,6 +327,22 @@ static void mesh_plink_timer(unsigned long data)
        }
 }
 
+#ifdef CONFIG_PM
+void mesh_plink_quiesce(struct sta_info *sta)
+{
+       if (del_timer_sync(&sta->plink_timer))
+               sta->plink_timer_was_running = true;
+}
+
+void mesh_plink_restart(struct sta_info *sta)
+{
+       if (sta->plink_timer_was_running) {
+               add_timer(&sta->plink_timer);
+               sta->plink_timer_was_running = false;
+       }
+}
+#endif
+
 static inline void mesh_plink_timer_set(struct sta_info *sta, int timeout)
 {
        sta->plink_timer.expires = jiffies + (HZ * timeout / 1000);
index 132938b073dc061327e8e3e47e00a8919119481e..d779c57a82203b23194772565d4e6ba2ed172406 100644 (file)
 #include <linux/if_arp.h>
 #include <linux/etherdevice.h>
 #include <linux/rtnetlink.h>
+#include <linux/pm_qos_params.h>
+#include <linux/crc32.h>
 #include <net/mac80211.h>
 #include <asm/unaligned.h>
 
 #include "ieee80211_i.h"
+#include "driver-ops.h"
 #include "rate.h"
 #include "led.h"
 
 #define IEEE80211_ASSOC_TIMEOUT (HZ / 5)
 #define IEEE80211_ASSOC_MAX_TRIES 3
 #define IEEE80211_MONITORING_INTERVAL (2 * HZ)
+#define IEEE80211_PROBE_WAIT (HZ / 5)
 #define IEEE80211_PROBE_IDLE_TIME (60 * HZ)
 #define IEEE80211_RETRY_AUTH_INTERVAL (1 * HZ)
 
+#define TMR_RUNNING_TIMER      0
+#define TMR_RUNNING_CHANSW     1
+
 /* utils */
 static int ecw2cw(int ecw)
 {
@@ -80,6 +87,92 @@ static int ieee80211_compatible_rates(struct ieee80211_bss *bss,
        return count;
 }
 
+/*
+ * ieee80211_enable_ht should be called only after the operating band
+ * has been determined as ht configuration depends on the hw's
+ * HT abilities for a specific band.
+ */
+static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata,
+                              struct ieee80211_ht_info *hti,
+                              u16 ap_ht_cap_flags)
+{
+       struct ieee80211_local *local = sdata->local;
+       struct ieee80211_supported_band *sband;
+       struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
+       struct sta_info *sta;
+       u32 changed = 0;
+       u16 ht_opmode;
+       bool enable_ht = true, ht_changed;
+       enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
+
+       sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
+
+       /* HT is not supported */
+       if (!sband->ht_cap.ht_supported)
+               enable_ht = false;
+
+       /* check that channel matches the right operating channel */
+       if (local->hw.conf.channel->center_freq !=
+           ieee80211_channel_to_frequency(hti->control_chan))
+               enable_ht = false;
+
+       if (enable_ht) {
+               channel_type = NL80211_CHAN_HT20;
+
+               if (!(ap_ht_cap_flags & IEEE80211_HT_CAP_40MHZ_INTOLERANT) &&
+                   (sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) &&
+                   (hti->ht_param & IEEE80211_HT_PARAM_CHAN_WIDTH_ANY)) {
+                       switch(hti->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
+                       case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
+                               if (!(local->hw.conf.channel->flags &
+                                   IEEE80211_CHAN_NO_HT40PLUS))
+                                       channel_type = NL80211_CHAN_HT40PLUS;
+                               break;
+                       case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
+                               if (!(local->hw.conf.channel->flags &
+                                   IEEE80211_CHAN_NO_HT40MINUS))
+                                       channel_type = NL80211_CHAN_HT40MINUS;
+                               break;
+                       }
+               }
+       }
+
+       ht_changed = conf_is_ht(&local->hw.conf) != enable_ht ||
+                    channel_type != local->hw.conf.channel_type;
+
+       local->oper_channel_type = channel_type;
+
+       if (ht_changed) {
+                /* channel_type change automatically detected */
+               ieee80211_hw_config(local, 0);
+
+               rcu_read_lock();
+
+               sta = sta_info_get(local, ifmgd->bssid);
+               if (sta)
+                       rate_control_rate_update(local, sband, sta,
+                                                IEEE80211_RC_HT_CHANGED);
+
+               rcu_read_unlock();
+        }
+
+       /* disable HT */
+       if (!enable_ht)
+               return 0;
+
+       ht_opmode = le16_to_cpu(hti->operation_mode);
+
+       /* if bss configuration changed store the new one */
+       if (!sdata->ht_opmode_valid ||
+           sdata->vif.bss_conf.ht_operation_mode != ht_opmode) {
+               changed |= BSS_CHANGED_HT;
+               sdata->vif.bss_conf.ht_operation_mode = ht_opmode;
+               sdata->ht_opmode_valid = true;
+       }
+
+       return changed;
+}
+
 /* frame sending functions */
 
 static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
@@ -263,13 +356,13 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
 
                switch (ht_info->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
                case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
-                       if (flags & IEEE80211_CHAN_NO_FAT_ABOVE) {
+                       if (flags & IEEE80211_CHAN_NO_HT40PLUS) {
                                cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
                                cap &= ~IEEE80211_HT_CAP_SGI_40;
                        }
                        break;
                case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
-                       if (flags & IEEE80211_CHAN_NO_FAT_BELOW) {
+                       if (flags & IEEE80211_CHAN_NO_HT40MINUS) {
                                cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
                                cap &= ~IEEE80211_HT_CAP_SGI_40;
                        }
@@ -325,6 +418,10 @@ static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
        /* u.deauth.reason_code == u.disassoc.reason_code */
        mgmt->u.deauth.reason_code = cpu_to_le16(reason);
 
+       if (stype == IEEE80211_STYPE_DEAUTH)
+               cfg80211_send_deauth(sdata->dev, (u8 *) mgmt, skb->len);
+       else
+               cfg80211_send_disassoc(sdata->dev, (u8 *) mgmt, skb->len);
        ieee80211_tx_skb(sdata, skb, ifmgd->flags & IEEE80211_STA_MFP_ENABLED);
 }
 
@@ -359,6 +456,277 @@ void ieee80211_send_pspoll(struct ieee80211_local *local,
        ieee80211_tx_skb(sdata, skb, 0);
 }
 
+void ieee80211_send_nullfunc(struct ieee80211_local *local,
+                            struct ieee80211_sub_if_data *sdata,
+                            int powersave)
+{
+       struct sk_buff *skb;
+       struct ieee80211_hdr *nullfunc;
+       __le16 fc;
+
+       if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION))
+               return;
+
+       skb = dev_alloc_skb(local->hw.extra_tx_headroom + 24);
+       if (!skb) {
+               printk(KERN_DEBUG "%s: failed to allocate buffer for nullfunc "
+                      "frame\n", sdata->dev->name);
+               return;
+       }
+       skb_reserve(skb, local->hw.extra_tx_headroom);
+
+       nullfunc = (struct ieee80211_hdr *) skb_put(skb, 24);
+       memset(nullfunc, 0, 24);
+       fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC |
+                        IEEE80211_FCTL_TODS);
+       if (powersave)
+               fc |= cpu_to_le16(IEEE80211_FCTL_PM);
+       nullfunc->frame_control = fc;
+       memcpy(nullfunc->addr1, sdata->u.mgd.bssid, ETH_ALEN);
+       memcpy(nullfunc->addr2, sdata->dev->dev_addr, ETH_ALEN);
+       memcpy(nullfunc->addr3, sdata->u.mgd.bssid, ETH_ALEN);
+
+       ieee80211_tx_skb(sdata, skb, 0);
+}
+
+/* spectrum management related things */
+static void ieee80211_chswitch_work(struct work_struct *work)
+{
+       struct ieee80211_sub_if_data *sdata =
+               container_of(work, struct ieee80211_sub_if_data, u.mgd.chswitch_work);
+       struct ieee80211_bss *bss;
+       struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
+
+       if (!netif_running(sdata->dev))
+               return;
+
+       bss = ieee80211_rx_bss_get(sdata->local, ifmgd->bssid,
+                                  sdata->local->hw.conf.channel->center_freq,
+                                  ifmgd->ssid, ifmgd->ssid_len);
+       if (!bss)
+               goto exit;
+
+       sdata->local->oper_channel = sdata->local->csa_channel;
+       /* XXX: shouldn't really modify cfg80211-owned data! */
+       if (!ieee80211_hw_config(sdata->local, IEEE80211_CONF_CHANGE_CHANNEL))
+               bss->cbss.channel = sdata->local->oper_channel;
+
+       ieee80211_rx_bss_put(sdata->local, bss);
+exit:
+       ifmgd->flags &= ~IEEE80211_STA_CSA_RECEIVED;
+       ieee80211_wake_queues_by_reason(&sdata->local->hw,
+                                       IEEE80211_QUEUE_STOP_REASON_CSA);
+}
+
+static void ieee80211_chswitch_timer(unsigned long data)
+{
+       struct ieee80211_sub_if_data *sdata =
+               (struct ieee80211_sub_if_data *) data;
+       struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
+
+       if (sdata->local->quiescing) {
+               set_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running);
+               return;
+       }
+
+       queue_work(sdata->local->hw.workqueue, &ifmgd->chswitch_work);
+}
+
+void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
+                                     struct ieee80211_channel_sw_ie *sw_elem,
+                                     struct ieee80211_bss *bss)
+{
+       struct ieee80211_channel *new_ch;
+       struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
+       int new_freq = ieee80211_channel_to_frequency(sw_elem->new_ch_num);
+
+       if (ifmgd->state != IEEE80211_STA_MLME_ASSOCIATED)
+               return;
+
+       if (sdata->local->sw_scanning || sdata->local->hw_scanning)
+               return;
+
+       /* Disregard subsequent beacons if we are already running a timer
+          processing a CSA */
+
+       if (ifmgd->flags & IEEE80211_STA_CSA_RECEIVED)
+               return;
+
+       new_ch = ieee80211_get_channel(sdata->local->hw.wiphy, new_freq);
+       if (!new_ch || new_ch->flags & IEEE80211_CHAN_DISABLED)
+               return;
+
+       sdata->local->csa_channel = new_ch;
+
+       if (sw_elem->count <= 1) {
+               queue_work(sdata->local->hw.workqueue, &ifmgd->chswitch_work);
+       } else {
+               ieee80211_stop_queues_by_reason(&sdata->local->hw,
+                                       IEEE80211_QUEUE_STOP_REASON_CSA);
+               ifmgd->flags |= IEEE80211_STA_CSA_RECEIVED;
+               mod_timer(&ifmgd->chswitch_timer,
+                         jiffies +
+                         msecs_to_jiffies(sw_elem->count *
+                                          bss->cbss.beacon_interval));
+       }
+}
+
+static void ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata,
+                                       u16 capab_info, u8 *pwr_constr_elem,
+                                       u8 pwr_constr_elem_len)
+{
+       struct ieee80211_conf *conf = &sdata->local->hw.conf;
+
+       if (!(capab_info & WLAN_CAPABILITY_SPECTRUM_MGMT))
+               return;
+
+       /* Power constraint IE length should be 1 octet */
+       if (pwr_constr_elem_len != 1)
+               return;
+
+       if ((*pwr_constr_elem <= conf->channel->max_power) &&
+           (*pwr_constr_elem != sdata->local->power_constr_level)) {
+               sdata->local->power_constr_level = *pwr_constr_elem;
+               ieee80211_hw_config(sdata->local, 0);
+       }
+}
+
+/* powersave */
+static void ieee80211_enable_ps(struct ieee80211_local *local,
+                               struct ieee80211_sub_if_data *sdata)
+{
+       struct ieee80211_conf *conf = &local->hw.conf;
+
+       /*
+        * If we are scanning right now then the parameters will
+        * take effect when scan finishes.
+        */
+       if (local->hw_scanning || local->sw_scanning)
+               return;
+
+       if (conf->dynamic_ps_timeout > 0 &&
+           !(local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS)) {
+               mod_timer(&local->dynamic_ps_timer, jiffies +
+                         msecs_to_jiffies(conf->dynamic_ps_timeout));
+       } else {
+               if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)
+                       ieee80211_send_nullfunc(local, sdata, 1);
+               conf->flags |= IEEE80211_CONF_PS;
+               ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
+       }
+}
+
+static void ieee80211_change_ps(struct ieee80211_local *local)
+{
+       struct ieee80211_conf *conf = &local->hw.conf;
+
+       if (local->ps_sdata) {
+               ieee80211_enable_ps(local, local->ps_sdata);
+       } else if (conf->flags & IEEE80211_CONF_PS) {
+               conf->flags &= ~IEEE80211_CONF_PS;
+               ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
+               del_timer_sync(&local->dynamic_ps_timer);
+               cancel_work_sync(&local->dynamic_ps_enable_work);
+       }
+}
+
+/* need to hold RTNL or interface lock */
+void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency)
+{
+       struct ieee80211_sub_if_data *sdata, *found = NULL;
+       int count = 0;
+
+       if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_PS)) {
+               local->ps_sdata = NULL;
+               return;
+       }
+
+       list_for_each_entry(sdata, &local->interfaces, list) {
+               if (!netif_running(sdata->dev))
+                       continue;
+               if (sdata->vif.type != NL80211_IFTYPE_STATION)
+                       continue;
+               found = sdata;
+               count++;
+       }
+
+       if (count == 1 && found->u.mgd.powersave &&
+           (found->u.mgd.flags & IEEE80211_STA_ASSOCIATED) &&
+           !(found->u.mgd.flags & IEEE80211_STA_PROBEREQ_POLL)) {
+               s32 beaconint_us;
+
+               if (latency < 0)
+                       latency = pm_qos_requirement(PM_QOS_NETWORK_LATENCY);
+
+               beaconint_us = ieee80211_tu_to_usec(
+                                       found->vif.bss_conf.beacon_int);
+
+               if (beaconint_us > latency) {
+                       local->ps_sdata = NULL;
+               } else {
+                       u8 dtimper = found->vif.bss_conf.dtim_period;
+                       int maxslp = 1;
+
+                       if (dtimper > 1)
+                               maxslp = min_t(int, dtimper,
+                                                   latency / beaconint_us);
+
+                       local->hw.conf.max_sleep_period = maxslp;
+                       local->ps_sdata = found;
+               }
+       } else {
+               local->ps_sdata = NULL;
+       }
+
+       ieee80211_change_ps(local);
+}
+
+void ieee80211_dynamic_ps_disable_work(struct work_struct *work)
+{
+       struct ieee80211_local *local =
+               container_of(work, struct ieee80211_local,
+                            dynamic_ps_disable_work);
+
+       if (local->hw.conf.flags & IEEE80211_CONF_PS) {
+               local->hw.conf.flags &= ~IEEE80211_CONF_PS;
+               ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
+       }
+
+       ieee80211_wake_queues_by_reason(&local->hw,
+                                       IEEE80211_QUEUE_STOP_REASON_PS);
+}
+
+void ieee80211_dynamic_ps_enable_work(struct work_struct *work)
+{
+       struct ieee80211_local *local =
+               container_of(work, struct ieee80211_local,
+                            dynamic_ps_enable_work);
+       struct ieee80211_sub_if_data *sdata = local->ps_sdata;
+
+       /* can only happen when PS was just disabled anyway */
+       if (!sdata)
+               return;
+
+       if (local->hw.conf.flags & IEEE80211_CONF_PS)
+               return;
+
+       if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)
+               ieee80211_send_nullfunc(local, sdata, 1);
+
+       local->hw.conf.flags |= IEEE80211_CONF_PS;
+       ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
+}
+
+void ieee80211_dynamic_ps_timer(unsigned long data)
+{
+       struct ieee80211_local *local = (void *) data;
+
+       if (local->quiescing)
+               return;
+
+       queue_work(local->hw.workqueue, &local->dynamic_ps_enable_work);
+}
+
 /* MLME */
 static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
                                     struct ieee80211_if_managed *ifmgd,
@@ -424,41 +792,16 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
                printk(KERN_DEBUG "%s: WMM queue=%d aci=%d acm=%d aifs=%d "
                       "cWmin=%d cWmax=%d txop=%d\n",
-                      local->mdev->name, queue, aci, acm, params.aifs, params.cw_min,
-                      params.cw_max, params.txop);
+                      wiphy_name(local->hw.wiphy), queue, aci, acm,
+                      params.aifs, params.cw_min, params.cw_max, params.txop);
 #endif
-               if (local->ops->conf_tx &&
-                   local->ops->conf_tx(local_to_hw(local), queue, &params)) {
+               if (drv_conf_tx(local, queue, &params) && local->ops->conf_tx)
                        printk(KERN_DEBUG "%s: failed to set TX queue "
-                              "parameters for queue %d\n", local->mdev->name, queue);
-               }
+                              "parameters for queue %d\n",
+                              wiphy_name(local->hw.wiphy), queue);
        }
 }
 
-static bool ieee80211_check_tim(struct ieee802_11_elems *elems, u16 aid)
-{
-       u8 mask;
-       u8 index, indexn1, indexn2;
-       struct ieee80211_tim_ie *tim = (struct ieee80211_tim_ie *) elems->tim;
-
-       if (unlikely(!tim || elems->tim_len < 4))
-               return false;
-
-       aid &= 0x3fff;
-       index = aid / 8;
-       mask  = 1 << (aid & 7);
-
-       indexn1 = tim->bitmap_ctrl & 0xfe;
-       indexn2 = elems->tim_len + indexn1 - 4;
-
-       if (index < indexn1 || index > indexn2)
-               return false;
-
-       index -= indexn1;
-
-       return !!(tim->virtual_map[index] & mask);
-}
-
 static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata,
                                           u16 capab, bool erp_valid, u8 erp)
 {
@@ -610,6 +953,7 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
                sdata->vif.bss_conf.timestamp = bss->cbss.tsf;
                sdata->vif.bss_conf.dtim_period = bss->dtim_period;
 
+               bss_info_changed |= BSS_CHANGED_BEACON_INT;
                bss_info_changed |= ieee80211_handle_bss_capability(sdata,
                        bss->cbss.capability, bss->has_erp_value, bss->erp_value);
 
@@ -632,20 +976,17 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
         * changed or not.
         */
        bss_info_changed |= BSS_CHANGED_BASIC_RATES;
+
+       /* And the BSSID changed - we're associated now */
+       bss_info_changed |= BSS_CHANGED_BSSID;
+
        ieee80211_bss_info_change_notify(sdata, bss_info_changed);
 
-       if (local->powersave) {
-               if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS) &&
-                   local->hw.conf.dynamic_ps_timeout > 0) {
-                       mod_timer(&local->dynamic_ps_timer, jiffies +
-                                 msecs_to_jiffies(
-                                       local->hw.conf.dynamic_ps_timeout));
-               } else {
-                       if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)
-                               ieee80211_send_nullfunc(local, sdata, 1);
-                       conf->flags |= IEEE80211_CONF_PS;
-                       ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
-               }
+       /* will be same as sdata */
+       if (local->ps_sdata) {
+               mutex_lock(&local->iflist_mtx);
+               ieee80211_recalc_ps(local, -1);
+               mutex_unlock(&local->iflist_mtx);
        }
 
        netif_tx_start_all_queues(sdata->dev);
@@ -664,7 +1005,8 @@ static void ieee80211_direct_probe(struct ieee80211_sub_if_data *sdata)
                printk(KERN_DEBUG "%s: direct probe to AP %pM timed out\n",
                       sdata->dev->name, ifmgd->bssid);
                ifmgd->state = IEEE80211_STA_MLME_DISABLED;
-               ieee80211_sta_send_apinfo(sdata);
+               ieee80211_recalc_idle(local);
+               cfg80211_send_auth_timeout(sdata->dev, ifmgd->bssid);
 
                /*
                 * Most likely AP is not in the range so remove the
@@ -689,8 +1031,6 @@ static void ieee80211_direct_probe(struct ieee80211_sub_if_data *sdata)
 
        ifmgd->state = IEEE80211_STA_MLME_DIRECT_PROBE;
 
-       set_bit(IEEE80211_STA_REQ_DIRECT_PROBE, &ifmgd->request);
-
        /* Direct probe is sent to broadcast address as some APs
         * will not answer to direct packet in unassociated state.
         */
@@ -714,7 +1054,8 @@ static void ieee80211_authenticate(struct ieee80211_sub_if_data *sdata)
                       " timed out\n",
                       sdata->dev->name, ifmgd->bssid);
                ifmgd->state = IEEE80211_STA_MLME_DISABLED;
-               ieee80211_sta_send_apinfo(sdata);
+               ieee80211_recalc_idle(local);
+               cfg80211_send_auth_timeout(sdata->dev, ifmgd->bssid);
                ieee80211_rx_bss_remove(sdata, ifmgd->bssid,
                                sdata->local->hw.conf.channel->center_freq,
                                ifmgd->ssid, ifmgd->ssid_len);
@@ -817,9 +1158,16 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
 
        rcu_read_unlock();
 
+       ieee80211_set_wmm_default(sdata);
+
+       ieee80211_recalc_idle(local);
+
        /* channel(_type) changes are handled by ieee80211_hw_config */
        local->oper_channel_type = NL80211_CHAN_NO_HT;
 
+       /* on the next assoc, re-program HT parameters */
+       sdata->ht_opmode_valid = false;
+
        local->power_constr_level = 0;
 
        del_timer_sync(&local->dynamic_ps_timer);
@@ -831,6 +1179,9 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
        }
 
        ieee80211_hw_config(local, config_changed);
+
+       /* And the BSSID changed -- not very interesting here */
+       changed |= BSS_CHANGED_BSSID;
        ieee80211_bss_info_change_notify(sdata, changed);
 
        rcu_read_lock();
@@ -897,7 +1248,8 @@ static void ieee80211_associate(struct ieee80211_sub_if_data *sdata)
                       " timed out\n",
                       sdata->dev->name, ifmgd->bssid);
                ifmgd->state = IEEE80211_STA_MLME_DISABLED;
-               ieee80211_sta_send_apinfo(sdata);
+               ieee80211_recalc_idle(local);
+               cfg80211_send_assoc_timeout(sdata->dev, ifmgd->bssid);
                ieee80211_rx_bss_remove(sdata, ifmgd->bssid,
                                sdata->local->hw.conf.channel->center_freq,
                                ifmgd->ssid, ifmgd->ssid_len);
@@ -917,6 +1269,7 @@ static void ieee80211_associate(struct ieee80211_sub_if_data *sdata)
                printk(KERN_DEBUG "%s: mismatch in privacy configuration and "
                       "mixed-cell disabled - abort association\n", sdata->dev->name);
                ifmgd->state = IEEE80211_STA_MLME_DISABLED;
+               ieee80211_recalc_idle(local);
                return;
        }
 
@@ -948,6 +1301,17 @@ void ieee80211_beacon_loss_work(struct work_struct *work)
                             u.mgd.beacon_loss_work);
        struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
 
+       /*
+        * The driver has already reported this event and we have
+        * already sent a probe request. Maybe the AP died and the
+        * driver keeps reporting until we disassociate... We have
+        * to ignore that because otherwise we would continually
+        * reset the timer and never check whether we received a
+        * probe response!
+        */
+       if (ifmgd->flags & IEEE80211_STA_PROBEREQ_POLL)
+               return;
+
 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
        if (net_ratelimit()) {
                printk(KERN_DEBUG "%s: driver reports beacon loss from AP %pM "
@@ -957,10 +1321,15 @@ void ieee80211_beacon_loss_work(struct work_struct *work)
 #endif
 
        ifmgd->flags |= IEEE80211_STA_PROBEREQ_POLL;
+
+       mutex_lock(&sdata->local->iflist_mtx);
+       ieee80211_recalc_ps(sdata->local, -1);
+       mutex_unlock(&sdata->local->iflist_mtx);
+
        ieee80211_send_probe_req(sdata, ifmgd->bssid, ifmgd->ssid,
                                 ifmgd->ssid_len, NULL, 0);
 
-       mod_timer(&ifmgd->timer, jiffies + IEEE80211_MONITORING_INTERVAL);
+       mod_timer(&ifmgd->timer, jiffies + IEEE80211_PROBE_WAIT);
 }
 
 void ieee80211_beacon_loss(struct ieee80211_vif *vif)
@@ -977,6 +1346,7 @@ static void ieee80211_associated(struct ieee80211_sub_if_data *sdata)
        struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
        struct ieee80211_local *local = sdata->local;
        struct sta_info *sta;
+       unsigned long last_rx;
        bool disassoc = false;
 
        /* TODO: start monitoring current AP signal quality and number of
@@ -993,17 +1363,21 @@ static void ieee80211_associated(struct ieee80211_sub_if_data *sdata)
                printk(KERN_DEBUG "%s: No STA entry for own AP %pM\n",
                       sdata->dev->name, ifmgd->bssid);
                disassoc = true;
-               goto unlock;
+               rcu_read_unlock();
+               goto out;
        }
 
+       last_rx = sta->last_rx;
+       rcu_read_unlock();
+
        if ((ifmgd->flags & IEEE80211_STA_PROBEREQ_POLL) &&
-           time_after(jiffies, sta->last_rx + IEEE80211_MONITORING_INTERVAL)) {
+           time_after(jiffies, last_rx + IEEE80211_PROBE_WAIT)) {
                printk(KERN_DEBUG "%s: no probe response from AP %pM "
                       "- disassociating\n",
                       sdata->dev->name, ifmgd->bssid);
                disassoc = true;
                ifmgd->flags &= ~IEEE80211_STA_PROBEREQ_POLL;
-               goto unlock;
+               goto out;
        }
 
        /*
@@ -1022,27 +1396,31 @@ static void ieee80211_associated(struct ieee80211_sub_if_data *sdata)
                }
 #endif
                ifmgd->flags |= IEEE80211_STA_PROBEREQ_POLL;
+               mutex_lock(&local->iflist_mtx);
+               ieee80211_recalc_ps(local, -1);
+               mutex_unlock(&local->iflist_mtx);
                ieee80211_send_probe_req(sdata, ifmgd->bssid, ifmgd->ssid,
                                         ifmgd->ssid_len, NULL, 0);
-               goto unlock;
-
+               mod_timer(&ifmgd->timer, jiffies + IEEE80211_PROBE_WAIT);
+               goto out;
        }
 
-       if (time_after(jiffies, sta->last_rx + IEEE80211_PROBE_IDLE_TIME)) {
+       if (time_after(jiffies, last_rx + IEEE80211_PROBE_IDLE_TIME)) {
                ifmgd->flags |= IEEE80211_STA_PROBEREQ_POLL;
+               mutex_lock(&local->iflist_mtx);
+               ieee80211_recalc_ps(local, -1);
+               mutex_unlock(&local->iflist_mtx);
                ieee80211_send_probe_req(sdata, ifmgd->bssid, ifmgd->ssid,
                                         ifmgd->ssid_len, NULL, 0);
        }
 
- unlock:
-       rcu_read_unlock();
-
-       if (disassoc)
+ out:
+       if (!disassoc)
+               mod_timer(&ifmgd->timer,
+                         jiffies + IEEE80211_MONITORING_INTERVAL);
+       else
                ieee80211_set_disassoc(sdata, true, true,
                                        WLAN_REASON_PREV_AUTH_NOT_VALID);
-       else
-               mod_timer(&ifmgd->timer, jiffies +
-                                     IEEE80211_MONITORING_INTERVAL);
 }
 
 
@@ -1055,6 +1433,7 @@ static void ieee80211_auth_completed(struct ieee80211_sub_if_data *sdata)
        if (ifmgd->flags & IEEE80211_STA_EXT_SME) {
                /* Wait for SME to request association */
                ifmgd->state = IEEE80211_STA_MLME_DISABLED;
+               ieee80211_recalc_idle(sdata->local);
        } else
                ieee80211_associate(sdata);
 }
@@ -1187,7 +1566,7 @@ static void ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
 
        ieee80211_set_disassoc(sdata, true, false, 0);
        ifmgd->flags &= ~IEEE80211_STA_AUTHENTICATED;
-       cfg80211_send_rx_deauth(sdata->dev, (u8 *) mgmt, len);
+       cfg80211_send_deauth(sdata->dev, (u8 *) mgmt, len);
 }
 
 
@@ -1218,7 +1597,7 @@ static void ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata,
        }
 
        ieee80211_set_disassoc(sdata, false, false, reason_code);
-       cfg80211_send_rx_disassoc(sdata->dev, (u8 *) mgmt, len);
+       cfg80211_send_disassoc(sdata->dev, (u8 *) mgmt, len);
 }
 
 
@@ -1287,6 +1666,12 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
                 * association next time. This works around some broken APs
                 * which do not correctly reject reassociation requests. */
                ifmgd->flags &= ~IEEE80211_STA_PREV_BSSID_SET;
+               cfg80211_send_rx_assoc(sdata->dev, (u8 *) mgmt, len);
+               if (ifmgd->flags & IEEE80211_STA_EXT_SME) {
+                       /* Wait for SME to decide what to do next */
+                       ifmgd->state = IEEE80211_STA_MLME_DISABLED;
+                       ieee80211_recalc_idle(local);
+               }
                return;
        }
 
@@ -1340,8 +1725,9 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
         *        to between the sta_info_alloc() and sta_info_insert() above.
         */
 
-       set_sta_flags(sta, WLAN_STA_AUTH | WLAN_STA_ASSOC | WLAN_STA_ASSOC_AP |
-                          WLAN_STA_AUTHORIZED);
+       set_sta_flags(sta, WLAN_STA_AUTH | WLAN_STA_ASSOC | WLAN_STA_ASSOC_AP);
+       if (!(ifmgd->flags & IEEE80211_STA_CONTROL_PORT))
+               set_sta_flags(sta, WLAN_STA_AUTHORIZED);
 
        rates = 0;
        basic_rates = 0;
@@ -1421,6 +1807,8 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
        if (elems.wmm_param)
                ieee80211_sta_wmm_params(local, ifmgd, elems.wmm_param,
                                         elems.wmm_param_len);
+       else
+               ieee80211_set_wmm_default(sdata);
 
        if (elems.ht_info_elem && elems.wmm_param &&
            (ifmgd->flags & IEEE80211_STA_WMM_ENABLED) &&
@@ -1476,7 +1864,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
            (memcmp(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN) == 0)) {
                struct ieee80211_channel_sw_ie *sw_elem =
                        (struct ieee80211_channel_sw_ie *)elems->ch_switch_elem;
-               ieee80211_process_chanswitch(sdata, sw_elem, bss);
+               ieee80211_sta_process_chanswitch(sdata, sw_elem, bss);
        }
 
        ieee80211_rx_bss_put(local, bss);
@@ -1507,57 +1895,98 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata,
        ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, false);
 
        /* direct probe may be part of the association flow */
-       if (test_and_clear_bit(IEEE80211_STA_REQ_DIRECT_PROBE,
-                              &ifmgd->request)) {
+       if (ifmgd->state == IEEE80211_STA_MLME_DIRECT_PROBE) {
                printk(KERN_DEBUG "%s direct probe responded\n",
                       sdata->dev->name);
                ieee80211_authenticate(sdata);
        }
 
-       if (ifmgd->flags & IEEE80211_STA_PROBEREQ_POLL)
+       if (ifmgd->flags & IEEE80211_STA_PROBEREQ_POLL) {
                ifmgd->flags &= ~IEEE80211_STA_PROBEREQ_POLL;
+               mutex_lock(&sdata->local->iflist_mtx);
+               ieee80211_recalc_ps(sdata->local, -1);
+               mutex_unlock(&sdata->local->iflist_mtx);
+       }
 }
 
+/*
+ * This is the canonical list of information elements we care about,
+ * the filter code also gives us all changes to the Microsoft OUI
+ * (00:50:F2) vendor IE which is used for WMM which we need to track.
+ *
+ * We implement beacon filtering in software since that means we can
+ * avoid processing the frame here and in cfg80211, and userspace
+ * will not be able to tell whether the hardware supports it or not.
+ *
+ * XXX: This list needs to be dynamic -- userspace needs to be able to
+ *     add items it requires. It also needs to be able to tell us to
+ *     look out for other vendor IEs.
+ */
+static const u64 care_about_ies =
+       (1ULL << WLAN_EID_COUNTRY) |
+       (1ULL << WLAN_EID_ERP_INFO) |
+       (1ULL << WLAN_EID_CHANNEL_SWITCH) |
+       (1ULL << WLAN_EID_PWR_CONSTRAINT) |
+       (1ULL << WLAN_EID_HT_CAPABILITY) |
+       (1ULL << WLAN_EID_HT_INFORMATION);
+
 static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
                                     struct ieee80211_mgmt *mgmt,
                                     size_t len,
                                     struct ieee80211_rx_status *rx_status)
 {
-       struct ieee80211_if_managed *ifmgd;
+       struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
        size_t baselen;
        struct ieee802_11_elems elems;
        struct ieee80211_local *local = sdata->local;
        u32 changed = 0;
-       bool erp_valid, directed_tim;
+       bool erp_valid, directed_tim = false;
        u8 erp_value = 0;
+       u32 ncrc;
 
        /* Process beacon from the current BSS */
        baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt;
        if (baselen > len)
                return;
 
-       ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems);
-
-       ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, true);
-
-       if (sdata->vif.type != NL80211_IFTYPE_STATION)
+       if (rx_status->freq != local->hw.conf.channel->center_freq)
                return;
 
-       ifmgd = &sdata->u.mgd;
-
        if (!(ifmgd->flags & IEEE80211_STA_ASSOCIATED) ||
            memcmp(ifmgd->bssid, mgmt->bssid, ETH_ALEN) != 0)
                return;
 
-       if (rx_status->freq != local->hw.conf.channel->center_freq)
-               return;
+       if (ifmgd->flags & IEEE80211_STA_PROBEREQ_POLL) {
+#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
+               if (net_ratelimit()) {
+                       printk(KERN_DEBUG "%s: cancelling probereq poll due "
+                              "to a received beacon\n", sdata->dev->name);
+               }
+#endif
+               ifmgd->flags &= ~IEEE80211_STA_PROBEREQ_POLL;
+               mutex_lock(&local->iflist_mtx);
+               ieee80211_recalc_ps(local, -1);
+               mutex_unlock(&local->iflist_mtx);
+       }
 
-       ieee80211_sta_wmm_params(local, ifmgd, elems.wmm_param,
-                                elems.wmm_param_len);
+       ncrc = crc32_be(0, (void *)&mgmt->u.beacon.beacon_int, 4);
+       ncrc = ieee802_11_parse_elems_crc(mgmt->u.beacon.variable,
+                                         len - baselen, &elems,
+                                         care_about_ies, ncrc);
 
-       if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) {
-               directed_tim = ieee80211_check_tim(&elems, ifmgd->aid);
+       if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)
+               directed_tim = ieee80211_check_tim(elems.tim, elems.tim_len,
+                                                  ifmgd->aid);
 
+       if (ncrc != ifmgd->beacon_crc) {
+               ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems,
+                                     true);
+
+               ieee80211_sta_wmm_params(local, ifmgd, elems.wmm_param,
+                                        elems.wmm_param_len);
+       }
+
+       if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) {
                if (directed_tim) {
                        if (local->hw.conf.dynamic_ps_timeout > 0) {
                                local->hw.conf.flags &= ~IEEE80211_CONF_PS;
@@ -1580,6 +2009,10 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
                }
        }
 
+       if (ncrc == ifmgd->beacon_crc)
+               return;
+       ifmgd->beacon_crc = ncrc;
+
        if (elems.erp_info && elems.erp_info_len >= 1) {
                erp_valid = true;
                erp_value = elems.erp_info[0];
@@ -1714,6 +2147,11 @@ static void ieee80211_sta_timer(unsigned long data)
        struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
        struct ieee80211_local *local = sdata->local;
 
+       if (local->quiescing) {
+               set_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running);
+               return;
+       }
+
        set_bit(IEEE80211_STA_REQ_RUN, &ifmgd->request);
        queue_work(local->hw.workqueue, &ifmgd->work);
 }
@@ -1723,10 +2161,8 @@ static void ieee80211_sta_reset_auth(struct ieee80211_sub_if_data *sdata)
        struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
        struct ieee80211_local *local = sdata->local;
 
-       if (local->ops->reset_tsf) {
-               /* Reset own TSF to allow time synchronization work. */
-               local->ops->reset_tsf(local_to_hw(local));
-       }
+       /* Reset own TSF to allow time synchronization work. */
+       drv_reset_tsf(local);
 
        ifmgd->wmm_last_param_set = -1; /* allow any WMM update */
 
@@ -1814,25 +2250,18 @@ static int ieee80211_sta_config_auth(struct ieee80211_sub_if_data *sdata)
                return 0;
        } else {
                if (ifmgd->assoc_scan_tries < IEEE80211_ASSOC_SCANS_MAX_TRIES) {
+
                        ifmgd->assoc_scan_tries++;
-                       /* XXX maybe racy? */
-                       if (local->scan_req)
-                               return -1;
-                       memcpy(local->int_scan_req.ssids[0].ssid,
-                              ifmgd->ssid, IEEE80211_MAX_SSID_LEN);
-                       if (ifmgd->flags & IEEE80211_STA_AUTO_SSID_SEL)
-                               local->int_scan_req.ssids[0].ssid_len = 0;
-                       else
-                               local->int_scan_req.ssids[0].ssid_len = ifmgd->ssid_len;
 
-                       if (ieee80211_start_scan(sdata, &local->int_scan_req))
-                               ieee80211_scan_failed(local);
+                       ieee80211_request_internal_scan(sdata, ifmgd->ssid,
+                                                       ssid_len);
 
                        ifmgd->state = IEEE80211_STA_MLME_AUTHENTICATE;
                        set_bit(IEEE80211_STA_REQ_AUTH, &ifmgd->request);
                } else {
                        ifmgd->assoc_scan_tries = 0;
                        ifmgd->state = IEEE80211_STA_MLME_DISABLED;
+                       ieee80211_recalc_idle(local);
                }
        }
        return -1;
@@ -1855,6 +2284,17 @@ static void ieee80211_sta_work(struct work_struct *work)
 
        if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION))
                return;
+
+       /*
+        * Nothing should have been stuffed into the workqueue during
+        * the suspend->resume cycle. If this WARN is seen then there
+        * is a bug with either the driver suspend or something in
+        * mac80211 stuffing into the workqueue which we haven't yet
+        * cleared during mac80211's suspend cycle.
+        */
+       if (WARN_ON(local->suspended))
+               return;
+
        ifmgd = &sdata->u.mgd;
 
        while ((skb = skb_dequeue(&ifmgd->skb_queue)))
@@ -1864,14 +2304,8 @@ static void ieee80211_sta_work(struct work_struct *work)
            ifmgd->state != IEEE80211_STA_MLME_AUTHENTICATE &&
            ifmgd->state != IEEE80211_STA_MLME_ASSOCIATE &&
            test_and_clear_bit(IEEE80211_STA_REQ_SCAN, &ifmgd->request)) {
-               /*
-                * The call to ieee80211_start_scan can fail but ieee80211_request_scan
-                * (which queued ieee80211_sta_work) did not return an error. Thus, call
-                * ieee80211_scan_failed here if ieee80211_start_scan fails in order to
-                * notify the scan requester.
-                */
-               if (ieee80211_start_scan(sdata, local->scan_req))
-                       ieee80211_scan_failed(local);
+               queue_delayed_work(local->hw.workqueue, &local->scan_work,
+                                  round_jiffies_relative(0));
                return;
        }
 
@@ -1882,6 +2316,8 @@ static void ieee80211_sta_work(struct work_struct *work)
        } else if (!test_and_clear_bit(IEEE80211_STA_REQ_RUN, &ifmgd->request))
                return;
 
+       ieee80211_recalc_idle(local);
+
        switch (ifmgd->state) {
        case IEEE80211_STA_MLME_DISABLED:
                break;
@@ -1926,10 +2362,43 @@ static void ieee80211_restart_sta_timer(struct ieee80211_sub_if_data *sdata)
        }
 }
 
+#ifdef CONFIG_PM
+void ieee80211_sta_quiesce(struct ieee80211_sub_if_data *sdata)
+{
+       struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
+
+       /*
+        * we need to use atomic bitops for the running bits
+        * only because both timers might fire at the same
+        * time -- the code here is properly synchronised.
+        */
+
+       cancel_work_sync(&ifmgd->work);
+       cancel_work_sync(&ifmgd->beacon_loss_work);
+       if (del_timer_sync(&ifmgd->timer))
+               set_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running);
+
+       cancel_work_sync(&ifmgd->chswitch_work);
+       if (del_timer_sync(&ifmgd->chswitch_timer))
+               set_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running);
+}
+
+void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata)
+{
+       struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
+
+       if (test_and_clear_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running))
+               add_timer(&ifmgd->timer);
+       if (test_and_clear_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running))
+               add_timer(&ifmgd->chswitch_timer);
+}
+#endif
+
 /* interface setup */
 void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata)
 {
        struct ieee80211_if_managed *ifmgd;
+       u32 hw_flags;
 
        ifmgd = &sdata->u.mgd;
        INIT_WORK(&ifmgd->work, ieee80211_sta_work);
@@ -1949,6 +2418,13 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata)
                IEEE80211_STA_AUTO_CHANNEL_SEL;
        if (sdata->local->hw.queues >= 4)
                ifmgd->flags |= IEEE80211_STA_WMM_ENABLED;
+
+       hw_flags = sdata->local->hw.flags;
+
+       if (hw_flags & IEEE80211_HW_SUPPORTS_PS) {
+               ifmgd->powersave = CONFIG_MAC80211_DEFAULT_PS_VALUE;
+               sdata->local->hw.conf.dynamic_ps_timeout = 500;
+       }
 }
 
 /* configuration hooks */
@@ -2032,13 +2508,6 @@ int ieee80211_sta_set_bssid(struct ieee80211_sub_if_data *sdata, u8 *bssid)
                ifmgd->flags &= ~IEEE80211_STA_BSSID_SET;
        }
 
-       if (netif_running(sdata->dev)) {
-               if (ieee80211_if_config(sdata, IEEE80211_IFCC_BSSID)) {
-                       printk(KERN_DEBUG "%s: Failed to config new BSSID to "
-                              "the low-level driver\n", sdata->dev->name);
-               }
-       }
-
        return ieee80211_sta_commit(sdata);
 }
 
@@ -2047,6 +2516,13 @@ int ieee80211_sta_set_extra_ie(struct ieee80211_sub_if_data *sdata,
 {
        struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
 
+       if (len == 0 && ifmgd->extra_ie_len == 0)
+               return -EALREADY;
+
+       if (len == ifmgd->extra_ie_len && ifmgd->extra_ie &&
+           memcmp(ifmgd->extra_ie, ie, len) == 0)
+               return -EALREADY;
+
        kfree(ifmgd->extra_ie);
        if (len == 0) {
                ifmgd->extra_ie = NULL;
@@ -2068,9 +2544,6 @@ int ieee80211_sta_deauthenticate(struct ieee80211_sub_if_data *sdata, u16 reason
        printk(KERN_DEBUG "%s: deauthenticating by local choice (reason=%d)\n",
               sdata->dev->name, reason);
 
-       if (sdata->vif.type != NL80211_IFTYPE_STATION)
-               return -EINVAL;
-
        ieee80211_set_disassoc(sdata, true, true, reason);
        return 0;
 }
@@ -2082,9 +2555,6 @@ int ieee80211_sta_disassociate(struct ieee80211_sub_if_data *sdata, u16 reason)
        printk(KERN_DEBUG "%s: disassociating by local choice (reason=%d)\n",
               sdata->dev->name, reason);
 
-       if (sdata->vif.type != NL80211_IFTYPE_STATION)
-               return -EINVAL;
-
        if (!(ifmgd->flags & IEEE80211_STA_ASSOCIATED))
                return -ENOLINK;
 
@@ -2104,75 +2574,17 @@ void ieee80211_mlme_notify_scan_completed(struct ieee80211_local *local)
        rcu_read_unlock();
 }
 
-void ieee80211_dynamic_ps_disable_work(struct work_struct *work)
+int ieee80211_max_network_latency(struct notifier_block *nb,
+                                 unsigned long data, void *dummy)
 {
+       s32 latency_usec = (s32) data;
        struct ieee80211_local *local =
-               container_of(work, struct ieee80211_local,
-                            dynamic_ps_disable_work);
-
-       if (local->hw.conf.flags & IEEE80211_CONF_PS) {
-               local->hw.conf.flags &= ~IEEE80211_CONF_PS;
-               ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
-       }
-
-       ieee80211_wake_queues_by_reason(&local->hw,
-                                       IEEE80211_QUEUE_STOP_REASON_PS);
-}
-
-void ieee80211_dynamic_ps_enable_work(struct work_struct *work)
-{
-       struct ieee80211_local *local =
-               container_of(work, struct ieee80211_local,
-                            dynamic_ps_enable_work);
-       /* XXX: using scan_sdata is completely broken! */
-       struct ieee80211_sub_if_data *sdata = local->scan_sdata;
-
-       if (local->hw.conf.flags & IEEE80211_CONF_PS)
-               return;
-
-       if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK && sdata)
-               ieee80211_send_nullfunc(local, sdata, 1);
-
-       local->hw.conf.flags |= IEEE80211_CONF_PS;
-       ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
-}
-
-void ieee80211_dynamic_ps_timer(unsigned long data)
-{
-       struct ieee80211_local *local = (void *) data;
-
-       queue_work(local->hw.workqueue, &local->dynamic_ps_enable_work);
-}
-
-void ieee80211_send_nullfunc(struct ieee80211_local *local,
-                            struct ieee80211_sub_if_data *sdata,
-                            int powersave)
-{
-       struct sk_buff *skb;
-       struct ieee80211_hdr *nullfunc;
-       __le16 fc;
+               container_of(nb, struct ieee80211_local,
+                            network_latency_notifier);
 
-       if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION))
-               return;
-
-       skb = dev_alloc_skb(local->hw.extra_tx_headroom + 24);
-       if (!skb) {
-               printk(KERN_DEBUG "%s: failed to allocate buffer for nullfunc "
-                      "frame\n", sdata->dev->name);
-               return;
-       }
-       skb_reserve(skb, local->hw.extra_tx_headroom);
+       mutex_lock(&local->iflist_mtx);
+       ieee80211_recalc_ps(local, latency_usec);
+       mutex_unlock(&local->iflist_mtx);
 
-       nullfunc = (struct ieee80211_hdr *) skb_put(skb, 24);
-       memset(nullfunc, 0, 24);
-       fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC |
-                        IEEE80211_FCTL_TODS);
-       if (powersave)
-               fc |= cpu_to_le16(IEEE80211_FCTL_PM);
-       nullfunc->frame_control = fc;
-       memcpy(nullfunc->addr1, sdata->u.mgd.bssid, ETH_ALEN);
-       memcpy(nullfunc->addr2, sdata->dev->dev_addr, ETH_ALEN);
-       memcpy(nullfunc->addr3, sdata->u.mgd.bssid, ETH_ALEN);
-
-       ieee80211_tx_skb(sdata, skb, 0);
+       return 0;
 }
index 81985d27cbdaf5d64e22701aac01249d193dc1a5..7a549f9deb967c1acbcf4ce1dbc41d28bcbefb4d 100644 (file)
@@ -2,6 +2,8 @@
 #include <net/rtnetlink.h>
 
 #include "ieee80211_i.h"
+#include "mesh.h"
+#include "driver-ops.h"
 #include "led.h"
 
 int __ieee80211_suspend(struct ieee80211_hw *hw)
@@ -12,11 +14,30 @@ int __ieee80211_suspend(struct ieee80211_hw *hw)
        struct sta_info *sta;
        unsigned long flags;
 
+       ieee80211_scan_cancel(local);
+
        ieee80211_stop_queues_by_reason(hw,
                        IEEE80211_QUEUE_STOP_REASON_SUSPEND);
 
+       /* flush out all packets */
+       synchronize_net();
+
+       local->quiescing = true;
+       /* make quiescing visible to timers everywhere */
+       mb();
+
        flush_workqueue(local->hw.workqueue);
 
+       /* Don't try to run timers while suspended. */
+       del_timer_sync(&local->sta_cleanup);
+
+        /*
+        * Note that this particular timer doesn't need to be
+        * restarted at resume.
+        */
+       cancel_work_sync(&local->dynamic_ps_enable_work);
+       del_timer_sync(&local->dynamic_ps_timer);
+
        /* disable keys */
        list_for_each_entry(sdata, &local->interfaces, list)
                ieee80211_disable_keys(sdata);
@@ -34,157 +55,70 @@ int __ieee80211_suspend(struct ieee80211_hw *hw)
 
        rcu_read_unlock();
 
-       /* remove STAs */
-       if (local->ops->sta_notify) {
-               spin_lock_irqsave(&local->sta_lock, flags);
-               list_for_each_entry(sta, &local->sta_list, list) {
-                       if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
-                               sdata = container_of(sdata->bss,
-                                            struct ieee80211_sub_if_data,
-                                            u.ap);
-
-                       local->ops->sta_notify(hw, &sdata->vif,
-                               STA_NOTIFY_REMOVE, &sta->sta);
-               }
-               spin_unlock_irqrestore(&local->sta_lock, flags);
-       }
-
-       /* remove all interfaces */
-       list_for_each_entry(sdata, &local->interfaces, list) {
-               if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
-                   sdata->vif.type != NL80211_IFTYPE_MONITOR &&
-                   netif_running(sdata->dev)) {
-                       conf.vif = &sdata->vif;
-                       conf.type = sdata->vif.type;
-                       conf.mac_addr = sdata->dev->dev_addr;
-                       local->ops->remove_interface(hw, &conf);
-               }
-       }
-
        /* flush again, in case driver queued work */
        flush_workqueue(local->hw.workqueue);
 
-       /* stop hardware */
+       /* stop hardware - this must stop RX */
        if (local->open_count) {
                ieee80211_led_radio(local, false);
-               local->ops->stop(hw);
-       }
-       return 0;
-}
-
-int __ieee80211_resume(struct ieee80211_hw *hw)
-{
-       struct ieee80211_local *local = hw_to_local(hw);
-       struct ieee80211_sub_if_data *sdata;
-       struct ieee80211_if_init_conf conf;
-       struct sta_info *sta;
-       unsigned long flags;
-       int res;
-
-       /* restart hardware */
-       if (local->open_count) {
-               res = local->ops->start(hw);
-
-               ieee80211_led_radio(local, hw->conf.radio_enabled);
+               drv_stop(local);
        }
 
-       /* add interfaces */
-       list_for_each_entry(sdata, &local->interfaces, list) {
-               if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
-                   sdata->vif.type != NL80211_IFTYPE_MONITOR &&
-                   netif_running(sdata->dev)) {
-                       conf.vif = &sdata->vif;
-                       conf.type = sdata->vif.type;
-                       conf.mac_addr = sdata->dev->dev_addr;
-                       res = local->ops->add_interface(hw, &conf);
-               }
-       }
-
-       /* add STAs back */
-       if (local->ops->sta_notify) {
-               spin_lock_irqsave(&local->sta_lock, flags);
-               list_for_each_entry(sta, &local->sta_list, list) {
+       /* remove STAs */
+       spin_lock_irqsave(&local->sta_lock, flags);
+       list_for_each_entry(sta, &local->sta_list, list) {
+               if (local->ops->sta_notify) {
+                       sdata = sta->sdata;
                        if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
                                sdata = container_of(sdata->bss,
                                             struct ieee80211_sub_if_data,
                                             u.ap);
 
-                       local->ops->sta_notify(hw, &sdata->vif,
-                               STA_NOTIFY_ADD, &sta->sta);
+                       drv_sta_notify(local, &sdata->vif, STA_NOTIFY_REMOVE,
+                                      &sta->sta);
                }
-               spin_unlock_irqrestore(&local->sta_lock, flags);
-       }
-
-       /* Clear Suspend state so that ADDBA requests can be processed */
-
-       rcu_read_lock();
 
-       if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) {
-               list_for_each_entry_rcu(sta, &local->sta_list, list) {
-                       clear_sta_flags(sta, WLAN_STA_SUSPEND);
-               }
+               mesh_plink_quiesce(sta);
        }
+       spin_unlock_irqrestore(&local->sta_lock, flags);
 
-       rcu_read_unlock();
-
-       /* add back keys */
-       list_for_each_entry(sdata, &local->interfaces, list)
-               if (netif_running(sdata->dev))
-                       ieee80211_enable_keys(sdata);
-
-       /* setup RTS threshold */
-       if (local->ops->set_rts_threshold)
-               local->ops->set_rts_threshold(hw, local->rts_threshold);
-
-       /* reconfigure hardware */
-       ieee80211_hw_config(local, ~0);
-
-       netif_addr_lock_bh(local->mdev);
-       ieee80211_configure_filter(local);
-       netif_addr_unlock_bh(local->mdev);
-
-       /* Finally also reconfigure all the BSS information */
+       /* remove all interfaces */
        list_for_each_entry(sdata, &local->interfaces, list) {
-               u32 changed = ~0;
-               if (!netif_running(sdata->dev))
-                       continue;
-               switch (sdata->vif.type) {
+               switch(sdata->vif.type) {
                case NL80211_IFTYPE_STATION:
-                       /* disable beacon change bits */
-                       changed &= ~IEEE80211_IFCC_BEACON;
-                       /* fall through */
+                       ieee80211_sta_quiesce(sdata);
+                       break;
                case NL80211_IFTYPE_ADHOC:
-               case NL80211_IFTYPE_AP:
-               case NL80211_IFTYPE_MESH_POINT:
-                       /*
-                        * Driver's config_interface can fail if rfkill is
-                        * enabled. Accommodate this return code.
-                        * FIXME: When mac80211 has knowledge of rfkill
-                        * state the code below can change back to:
-                        *   WARN(ieee80211_if_config(sdata, changed));
-                        *   ieee80211_bss_info_change_notify(sdata, ~0);
-                        */
-                       if (ieee80211_if_config(sdata, changed))
-                               printk(KERN_DEBUG "%s: failed to configure interface during resume\n",
-                                      sdata->dev->name);
-                       else
-                               ieee80211_bss_info_change_notify(sdata, ~0);
+                       ieee80211_ibss_quiesce(sdata);
                        break;
-               case NL80211_IFTYPE_WDS:
+               case NL80211_IFTYPE_MESH_POINT:
+                       ieee80211_mesh_quiesce(sdata);
                        break;
                case NL80211_IFTYPE_AP_VLAN:
                case NL80211_IFTYPE_MONITOR:
-                       /* ignore virtual */
-                       break;
-               case NL80211_IFTYPE_UNSPECIFIED:
-               case __NL80211_IFTYPE_AFTER_LAST:
-                       WARN_ON(1);
+                       /* don't tell driver about this */
+                       continue;
+               default:
                        break;
                }
+
+               if (!netif_running(sdata->dev))
+                       continue;
+
+               conf.vif = &sdata->vif;
+               conf.type = sdata->vif.type;
+               conf.mac_addr = sdata->dev->dev_addr;
+               drv_remove_interface(local, &conf);
        }
 
-       ieee80211_wake_queues_by_reason(hw,
-                       IEEE80211_QUEUE_STOP_REASON_SUSPEND);
+       local->suspended = true;
+       local->quiescing = false;
 
        return 0;
 }
+
+/*
+ * __ieee80211_resume() is a static inline which just calls
+ * ieee80211_reconfig(), which is also needed for hardware
+ * hang/firmware failure/etc. recovery.
+ */
index d9233ec5061048b773d35e60bbeeee669efd1376..b218b98fba7fbeb573d420ca0829af99f47584c5 100644 (file)
@@ -80,8 +80,7 @@ use_low_rate(struct sk_buff *skb)
        fc = le16_to_cpu(hdr->frame_control);
 
        return ((info->flags & IEEE80211_TX_CTL_NO_ACK) ||
-               (fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA ||
-               is_multicast_ether_addr(hdr->addr1));
+               (fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA);
 }
 
 
@@ -216,7 +215,7 @@ minstrel_get_next_sample(struct minstrel_sta_info *mi)
        unsigned int sample_ndx;
        sample_ndx = SAMPLE_TBL(mi, mi->sample_idx, mi->sample_column);
        mi->sample_idx++;
-       if (mi->sample_idx > (mi->n_rates - 2)) {
+       if ((int) mi->sample_idx > (mi->n_rates - 2)) {
                mi->sample_idx = 0;
                mi->sample_column++;
                if (mi->sample_column >= SAMPLE_COLUMNS)
@@ -245,7 +244,10 @@ minstrel_get_rate(void *priv, struct ieee80211_sta *sta,
 
        if (!sta || !mi || use_low_rate(skb)) {
                ar[0].idx = rate_lowest_index(sband, sta);
-               ar[0].count = mp->max_retry;
+               if (info->flags & IEEE80211_TX_CTL_NO_ACK)
+                       ar[0].count = 1;
+               else
+                       ar[0].count = mp->max_retry;
                return;
        }
 
index 8bef9a1262ff33013e90231a1a09f32d29f7a0f3..a0bef767ceb5b5d97e43a877d7238c85fe884d16 100644 (file)
@@ -289,13 +289,15 @@ rate_control_pid_get_rate(void *priv, struct ieee80211_sta *sta,
                info->control.rates[0].count =
                        txrc->hw->conf.short_frame_max_tx_count;
 
-       /* Send management frames and broadcast/multicast data using lowest
-        * rate. */
+       /* Send management frames and NO_ACK data using lowest rate. */
        fc = le16_to_cpu(hdr->frame_control);
        if (!sta || !spinfo ||
            (fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA ||
-           is_multicast_ether_addr(hdr->addr1)) {
+           info->flags & IEEE80211_TX_CTL_NO_ACK) {
                info->control.rates[0].idx = rate_lowest_index(sband, sta);
+               if (info->flags & IEEE80211_TX_CTL_NO_ACK)
+                       info->control.rates[0].count = 1;
+
                return;
        }
 
index 9776f73c51add2a2bf306370fbcc61a7814db3e5..de5bba7f910ae876637c3002544a6963eebccdfd 100644 (file)
@@ -19,6 +19,7 @@
 #include <net/ieee80211_radiotap.h>
 
 #include "ieee80211_i.h"
+#include "driver-ops.h"
 #include "led.h"
 #include "mesh.h"
 #include "wep.h"
@@ -629,15 +630,6 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
         * possible.
         */
 
-       if (!ieee80211_has_protected(hdr->frame_control)) {
-               if (!ieee80211_is_mgmt(hdr->frame_control) ||
-                   rx->sta == NULL || !test_sta_flags(rx->sta, WLAN_STA_MFP))
-                       return RX_CONTINUE;
-               mmie_keyidx = ieee80211_get_mmie_keyidx(rx->skb);
-               if (mmie_keyidx < 0)
-                       return RX_CONTINUE;
-       }
-
        /*
         * No point in finding a key and decrypting if the frame is neither
         * addressed to us nor a multicast frame.
@@ -648,8 +640,14 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
        if (rx->sta)
                stakey = rcu_dereference(rx->sta->key);
 
+       if (!ieee80211_has_protected(hdr->frame_control))
+               mmie_keyidx = ieee80211_get_mmie_keyidx(rx->skb);
+
        if (!is_multicast_ether_addr(hdr->addr1) && stakey) {
                rx->key = stakey;
+               /* Skip decryption if the frame is not protected. */
+               if (!ieee80211_has_protected(hdr->frame_control))
+                       return RX_CONTINUE;
        } else if (mmie_keyidx >= 0) {
                /* Broadcast/multicast robust management frame / BIP */
                if ((rx->status->flag & RX_FLAG_DECRYPTED) &&
@@ -660,6 +658,21 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
                    mmie_keyidx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS)
                        return RX_DROP_MONITOR; /* unexpected BIP keyidx */
                rx->key = rcu_dereference(rx->sdata->keys[mmie_keyidx]);
+       } else if (!ieee80211_has_protected(hdr->frame_control)) {
+               /*
+                * The frame was not protected, so skip decryption. However, we
+                * need to set rx->key if there is a key that could have been
+                * used so that the frame may be dropped if encryption would
+                * have been expected.
+                */
+               struct ieee80211_key *key = NULL;
+               if (ieee80211_is_mgmt(hdr->frame_control) &&
+                   is_multicast_ether_addr(hdr->addr1) &&
+                   (key = rcu_dereference(rx->sdata->default_mgmt_key)))
+                       rx->key = key;
+               else if ((key = rcu_dereference(rx->sdata->default_key)))
+                       rx->key = key;
+               return RX_CONTINUE;
        } else {
                /*
                 * The device doesn't give us the IV so we won't be
@@ -773,9 +786,7 @@ static void ap_sta_ps_start(struct sta_info *sta)
 
        atomic_inc(&sdata->bss->num_sta_ps);
        set_and_clear_sta_flags(sta, WLAN_STA_PS, WLAN_STA_PSPOLL);
-       if (local->ops->sta_notify)
-               local->ops->sta_notify(local_to_hw(local), &sdata->vif,
-                                       STA_NOTIFY_SLEEP, &sta->sta);
+       drv_sta_notify(local, &sdata->vif, STA_NOTIFY_SLEEP, &sta->sta);
 #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
        printk(KERN_DEBUG "%s: STA %pM aid %d enters power save mode\n",
               sdata->dev->name, sta->sta.addr, sta->sta.aid);
@@ -786,15 +797,12 @@ static int ap_sta_ps_end(struct sta_info *sta)
 {
        struct ieee80211_sub_if_data *sdata = sta->sdata;
        struct ieee80211_local *local = sdata->local;
-       struct sk_buff *skb;
-       int sent = 0;
+       int sent, buffered;
 
        atomic_dec(&sdata->bss->num_sta_ps);
 
        clear_sta_flags(sta, WLAN_STA_PS | WLAN_STA_PSPOLL);
-       if (local->ops->sta_notify)
-               local->ops->sta_notify(local_to_hw(local), &sdata->vif,
-                                       STA_NOTIFY_AWAKE, &sta->sta);
+       drv_sta_notify(local, &sdata->vif, STA_NOTIFY_AWAKE, &sta->sta);
 
        if (!skb_queue_empty(&sta->ps_tx_buf))
                sta_info_clear_tim_bit(sta);
@@ -805,22 +813,16 @@ static int ap_sta_ps_end(struct sta_info *sta)
 #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
 
        /* Send all buffered frames to the station */
-       while ((skb = skb_dequeue(&sta->tx_filtered)) != NULL) {
-               sent++;
-               skb->requeue = 1;
-               dev_queue_xmit(skb);
-       }
-       while ((skb = skb_dequeue(&sta->ps_tx_buf)) != NULL) {
-               local->total_ps_buffered--;
-               sent++;
+       sent = ieee80211_add_pending_skbs(local, &sta->tx_filtered);
+       buffered = ieee80211_add_pending_skbs(local, &sta->ps_tx_buf);
+       sent += buffered;
+       local->total_ps_buffered -= buffered;
+
 #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
-               printk(KERN_DEBUG "%s: STA %pM aid %d send PS frame "
-                      "since STA not sleeping anymore\n", sdata->dev->name,
-                      sta->sta.addr, sta->sta.aid);
+       printk(KERN_DEBUG "%s: STA %pM aid %d sending %d filtered/%d PS frames "
+              "since STA not sleeping anymore\n", sdata->dev->name,
+              sta->sta.addr, sta->sta.aid, sent - buffered, buffered);
 #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
-               skb->requeue = 1;
-               dev_queue_xmit(skb);
-       }
 
        return sent;
 }
@@ -1212,109 +1214,38 @@ ieee80211_drop_unencrypted(struct ieee80211_rx_data *rx, __le16 fc)
        /* Drop unencrypted frames if key is set. */
        if (unlikely(!ieee80211_has_protected(fc) &&
                     !ieee80211_is_nullfunc(fc) &&
-                    (!ieee80211_is_mgmt(fc) ||
-                     (ieee80211_is_unicast_robust_mgmt_frame(rx->skb) &&
-                      rx->sta && test_sta_flags(rx->sta, WLAN_STA_MFP))) &&
-                    (rx->key || rx->sdata->drop_unencrypted)))
-               return -EACCES;
-       /* BIP does not use Protected field, so need to check MMIE */
-       if (unlikely(rx->sta && test_sta_flags(rx->sta, WLAN_STA_MFP) &&
-                    ieee80211_is_multicast_robust_mgmt_frame(rx->skb) &&
-                    ieee80211_get_mmie_keyidx(rx->skb) < 0 &&
+                    ieee80211_is_data(fc) &&
                     (rx->key || rx->sdata->drop_unencrypted)))
                return -EACCES;
+       if (rx->sta && test_sta_flags(rx->sta, WLAN_STA_MFP)) {
+               if (unlikely(ieee80211_is_unicast_robust_mgmt_frame(rx->skb) &&
+                            rx->key))
+                       return -EACCES;
+               /* BIP does not use Protected field, so need to check MMIE */
+               if (unlikely(ieee80211_is_multicast_robust_mgmt_frame(rx->skb)
+                            && ieee80211_get_mmie_keyidx(rx->skb) < 0 &&
+                            rx->key))
+                       return -EACCES;
+               /*
+                * When using MFP, Action frames are not allowed prior to
+                * having configured keys.
+                */
+               if (unlikely(ieee80211_is_action(fc) && !rx->key &&
+                            ieee80211_is_robust_mgmt_frame(
+                                    (struct ieee80211_hdr *) rx->skb->data)))
+                       return -EACCES;
+       }
 
        return 0;
 }
 
 static int
-ieee80211_data_to_8023(struct ieee80211_rx_data *rx)
+__ieee80211_data_to_8023(struct ieee80211_rx_data *rx)
 {
        struct net_device *dev = rx->dev;
-       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data;
-       u16 hdrlen, ethertype;
-       u8 *payload;
-       u8 dst[ETH_ALEN];
-       u8 src[ETH_ALEN] __aligned(2);
-       struct sk_buff *skb = rx->skb;
        struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 
-       if (unlikely(!ieee80211_is_data_present(hdr->frame_control)))
-               return -1;
-
-       hdrlen = ieee80211_hdrlen(hdr->frame_control);
-
-       /* convert IEEE 802.11 header + possible LLC headers into Ethernet
-        * header
-        * IEEE 802.11 address fields:
-        * ToDS FromDS Addr1 Addr2 Addr3 Addr4
-        *   0     0   DA    SA    BSSID n/a
-        *   0     1   DA    BSSID SA    n/a
-        *   1     0   BSSID SA    DA    n/a
-        *   1     1   RA    TA    DA    SA
-        */
-       memcpy(dst, ieee80211_get_DA(hdr), ETH_ALEN);
-       memcpy(src, ieee80211_get_SA(hdr), ETH_ALEN);
-
-       switch (hdr->frame_control &
-               cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) {
-       case cpu_to_le16(IEEE80211_FCTL_TODS):
-               if (unlikely(sdata->vif.type != NL80211_IFTYPE_AP &&
-                            sdata->vif.type != NL80211_IFTYPE_AP_VLAN))
-                       return -1;
-               break;
-       case cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS):
-               if (unlikely(sdata->vif.type != NL80211_IFTYPE_WDS &&
-                            sdata->vif.type != NL80211_IFTYPE_MESH_POINT))
-                       return -1;
-               if (ieee80211_vif_is_mesh(&sdata->vif)) {
-                       struct ieee80211s_hdr *meshdr = (struct ieee80211s_hdr *)
-                               (skb->data + hdrlen);
-                       hdrlen += ieee80211_get_mesh_hdrlen(meshdr);
-                       if (meshdr->flags & MESH_FLAGS_AE_A5_A6) {
-                               memcpy(dst, meshdr->eaddr1, ETH_ALEN);
-                               memcpy(src, meshdr->eaddr2, ETH_ALEN);
-                       }
-               }
-               break;
-       case cpu_to_le16(IEEE80211_FCTL_FROMDS):
-               if (sdata->vif.type != NL80211_IFTYPE_STATION ||
-                   (is_multicast_ether_addr(dst) &&
-                    !compare_ether_addr(src, dev->dev_addr)))
-                       return -1;
-               break;
-       case cpu_to_le16(0):
-               if (sdata->vif.type != NL80211_IFTYPE_ADHOC)
-                       return -1;
-               break;
-       }
-
-       if (unlikely(skb->len - hdrlen < 8))
-               return -1;
-
-       payload = skb->data + hdrlen;
-       ethertype = (payload[6] << 8) | payload[7];
-
-       if (likely((compare_ether_addr(payload, rfc1042_header) == 0 &&
-                   ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) ||
-                  compare_ether_addr(payload, bridge_tunnel_header) == 0)) {
-               /* remove RFC1042 or Bridge-Tunnel encapsulation and
-                * replace EtherType */
-               skb_pull(skb, hdrlen + 6);
-               memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN);
-               memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN);
-       } else {
-               struct ethhdr *ehdr;
-               __be16 len;
-
-               skb_pull(skb, hdrlen);
-               len = htons(skb->len);
-               ehdr = (struct ethhdr *) skb_push(skb, sizeof(struct ethhdr));
-               memcpy(ehdr->h_dest, dst, ETH_ALEN);
-               memcpy(ehdr->h_source, src, ETH_ALEN);
-               ehdr->h_proto = len;
-       }
-       return 0;
+       return ieee80211_data_to_8023(rx->skb, dev->dev_addr, sdata->vif.type);
 }
 
 /*
@@ -1397,7 +1328,7 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx)
                 * mac80211. That also explains the __skb_push()
                 * below.
                 */
-               align = (unsigned long)skb->data & 3;
+               align = ((unsigned long)(skb->data + sizeof(struct ethhdr))) & 3;
                if (align) {
                        if (WARN_ON(skb_headroom(skb) < 3)) {
                                dev_kfree_skb(skb);
@@ -1453,7 +1384,7 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx)
        if (!(rx->flags & IEEE80211_RX_AMSDU))
                return RX_CONTINUE;
 
-       err = ieee80211_data_to_8023(rx);
+       err = __ieee80211_data_to_8023(rx);
        if (unlikely(err))
                return RX_DROP_UNUSABLE;
 
@@ -1639,7 +1570,7 @@ ieee80211_rx_h_data(struct ieee80211_rx_data *rx)
        if (unlikely(!ieee80211_is_data_present(hdr->frame_control)))
                return RX_DROP_MONITOR;
 
-       err = ieee80211_data_to_8023(rx);
+       err = __ieee80211_data_to_8023(rx);
        if (unlikely(err))
                return RX_DROP_UNUSABLE;
 
@@ -1827,6 +1758,9 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
                                   sizeof(mgmt->u.action.u.chan_switch)))
                                return RX_DROP_MONITOR;
 
+                       if (sdata->vif.type != NL80211_IFTYPE_STATION)
+                               return RX_DROP_MONITOR;
+
                        if (memcmp(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN))
                                return RX_DROP_MONITOR;
 
@@ -1837,7 +1771,7 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
                        if (!bss)
                                return RX_DROP_MONITOR;
 
-                       ieee80211_process_chanswitch(sdata,
+                       ieee80211_sta_process_chanswitch(sdata,
                                     &mgmt->u.action.u.chan_switch.sw_elem, bss);
                        ieee80211_rx_bss_put(local, bss);
                        break;
@@ -1932,7 +1866,7 @@ static void ieee80211_rx_michael_mic_report(struct net_device *dev,
            !ieee80211_is_auth(hdr->frame_control))
                goto ignore;
 
-       mac80211_ev_michael_mic_failure(rx->sdata, keyidx, hdr);
+       mac80211_ev_michael_mic_failure(rx->sdata, keyidx, hdr, NULL);
  ignore:
        dev_kfree_skb(rx->skb);
        rx->skb = NULL;
@@ -2287,6 +2221,43 @@ static inline u16 seq_sub(u16 sq1, u16 sq2)
 }
 
 
+static void ieee80211_release_reorder_frame(struct ieee80211_hw *hw,
+                                           struct tid_ampdu_rx *tid_agg_rx,
+                                           int index)
+{
+       struct ieee80211_supported_band *sband;
+       struct ieee80211_rate *rate;
+       struct ieee80211_rx_status status;
+
+       if (!tid_agg_rx->reorder_buf[index])
+               goto no_frame;
+
+       /* release the reordered frames to stack */
+       memcpy(&status, tid_agg_rx->reorder_buf[index]->cb, sizeof(status));
+       sband = hw->wiphy->bands[status.band];
+       if (status.flag & RX_FLAG_HT)
+               rate = sband->bitrates; /* TODO: HT rates */
+       else
+               rate = &sband->bitrates[status.rate_idx];
+       __ieee80211_rx_handle_packet(hw, tid_agg_rx->reorder_buf[index],
+                                    &status, rate);
+       tid_agg_rx->stored_mpdu_num--;
+       tid_agg_rx->reorder_buf[index] = NULL;
+
+no_frame:
+       tid_agg_rx->head_seq_num = seq_inc(tid_agg_rx->head_seq_num);
+}
+
+
+/*
+ * Timeout (in jiffies) for skb's that are waiting in the RX reorder buffer. If
+ * the skb was added to the buffer longer than this time ago, the earlier
+ * frames that have not yet been received are assumed to be lost and the skb
+ * can be released for processing. This may also release other skb's from the
+ * reorder buffer if there are no additional gaps between the frames.
+ */
+#define HT_RX_REORDER_BUF_TIMEOUT (HZ / 10)
+
 /*
  * As it function blongs to Rx path it must be called with
  * the proper rcu_read_lock protection for its flow.
@@ -2298,12 +2269,8 @@ static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
                                           u16 mpdu_seq_num,
                                           int bar_req)
 {
-       struct ieee80211_local *local = hw_to_local(hw);
-       struct ieee80211_rx_status status;
        u16 head_seq_num, buf_size;
        int index;
-       struct ieee80211_supported_band *sband;
-       struct ieee80211_rate *rate;
 
        buf_size = tid_agg_rx->buf_size;
        head_seq_num = tid_agg_rx->head_seq_num;
@@ -2328,28 +2295,8 @@ static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
                        index = seq_sub(tid_agg_rx->head_seq_num,
                                tid_agg_rx->ssn)
                                % tid_agg_rx->buf_size;
-
-                       if (tid_agg_rx->reorder_buf[index]) {
-                               /* release the reordered frames to stack */
-                               memcpy(&status,
-                                       tid_agg_rx->reorder_buf[index]->cb,
-                                       sizeof(status));
-                               sband = local->hw.wiphy->bands[status.band];
-                               if (status.flag & RX_FLAG_HT) {
-                                       /* TODO: HT rates */
-                                       rate = sband->bitrates;
-                               } else {
-                                       rate = &sband->bitrates
-                                               [status.rate_idx];
-                               }
-                               __ieee80211_rx_handle_packet(hw,
-                                       tid_agg_rx->reorder_buf[index],
-                                       &status, rate);
-                               tid_agg_rx->stored_mpdu_num--;
-                               tid_agg_rx->reorder_buf[index] = NULL;
-                       }
-                       tid_agg_rx->head_seq_num =
-                               seq_inc(tid_agg_rx->head_seq_num);
+                       ieee80211_release_reorder_frame(hw, tid_agg_rx,
+                                                       index);
                }
                if (bar_req)
                        return 1;
@@ -2376,26 +2323,50 @@ static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw,
 
        /* put the frame in the reordering buffer */
        tid_agg_rx->reorder_buf[index] = skb;
+       tid_agg_rx->reorder_time[index] = jiffies;
        memcpy(tid_agg_rx->reorder_buf[index]->cb, rxstatus,
               sizeof(*rxstatus));
        tid_agg_rx->stored_mpdu_num++;
        /* release the buffer until next missing frame */
        index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn)
                                                % tid_agg_rx->buf_size;
-       while (tid_agg_rx->reorder_buf[index]) {
-               /* release the reordered frame back to stack */
-               memcpy(&status, tid_agg_rx->reorder_buf[index]->cb,
-                       sizeof(status));
-               sband = local->hw.wiphy->bands[status.band];
-               if (status.flag & RX_FLAG_HT)
-                       rate = sband->bitrates; /* TODO: HT rates */
-               else
-                       rate = &sband->bitrates[status.rate_idx];
-               __ieee80211_rx_handle_packet(hw, tid_agg_rx->reorder_buf[index],
-                                            &status, rate);
-               tid_agg_rx->stored_mpdu_num--;
-               tid_agg_rx->reorder_buf[index] = NULL;
-               tid_agg_rx->head_seq_num = seq_inc(tid_agg_rx->head_seq_num);
+       if (!tid_agg_rx->reorder_buf[index] &&
+           tid_agg_rx->stored_mpdu_num > 1) {
+               /*
+                * No buffers ready to be released, but check whether any
+                * frames in the reorder buffer have timed out.
+                */
+               int j;
+               int skipped = 1;
+               for (j = (index + 1) % tid_agg_rx->buf_size; j != index;
+                    j = (j + 1) % tid_agg_rx->buf_size) {
+                       if (tid_agg_rx->reorder_buf[j] == NULL) {
+                               skipped++;
+                               continue;
+                       }
+                       if (!time_after(jiffies, tid_agg_rx->reorder_time[j] +
+                                       HZ / 10))
+                               break;
+
+#ifdef CONFIG_MAC80211_HT_DEBUG
+                       if (net_ratelimit())
+                               printk(KERN_DEBUG "%s: release an RX reorder "
+                                      "frame due to timeout on earlier "
+                                      "frames\n",
+                                      wiphy_name(hw->wiphy));
+#endif
+                       ieee80211_release_reorder_frame(hw, tid_agg_rx, j);
+
+                       /*
+                        * Increment the head seq# also for the skipped slots.
+                        */
+                       tid_agg_rx->head_seq_num =
+                               (tid_agg_rx->head_seq_num + skipped) &
+                               SEQ_MASK;
+                       skipped = 0;
+               }
+       } else while (tid_agg_rx->reorder_buf[index]) {
+               ieee80211_release_reorder_frame(hw, tid_agg_rx, index);
                index = seq_sub(tid_agg_rx->head_seq_num,
                        tid_agg_rx->ssn) % tid_agg_rx->buf_size;
        }
@@ -2517,6 +2488,18 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb,
                return;
        }
 
+       /*
+        * In theory, the block ack reordering should happen after duplicate
+        * removal (ieee80211_rx_h_check(), which is an RX handler). As such,
+        * the call to ieee80211_rx_reorder_ampdu() should really be moved to
+        * happen as a new RX handler between ieee80211_rx_h_check and
+        * ieee80211_rx_h_decrypt. This cleanup may eventually happen, but for
+        * the time being, the call can be here since RX reorder buf processing
+        * will implicitly skip duplicates. We could, in theory at least,
+        * process frames that ieee80211_rx_h_passive_scan would drop (e.g.,
+        * frames from other than operational channel), but that should not
+        * happen in normal networks.
+        */
        if (!ieee80211_rx_reorder_ampdu(local, skb, status))
                __ieee80211_rx_handle_packet(hw, skb, status, rate);
 
index 3bf9839f59169cda1ded90dd8263fc3e6597097d..2a8d09ad17ff8829cc777143d0cff77dff6052c3 100644 (file)
@@ -21,6 +21,7 @@
 #include <net/iw_handler.h>
 
 #include "ieee80211_i.h"
+#include "driver-ops.h"
 #include "mesh.h"
 
 #define IEEE80211_PROBE_DELAY (HZ / 33)
@@ -202,18 +203,6 @@ ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
        return RX_QUEUED;
 }
 
-void ieee80211_scan_failed(struct ieee80211_local *local)
-{
-       if (WARN_ON(!local->scan_req))
-               return;
-
-       /* notify cfg80211 about the failed scan */
-       if (local->scan_req != &local->int_scan_req)
-               cfg80211_scan_done(local->scan_req, true);
-
-       local->scan_req = NULL;
-}
-
 /*
  * inform AP that we will go to sleep so that it will buffer the frames
  * while we scan
@@ -253,7 +242,7 @@ static void ieee80211_scan_ps_disable(struct ieee80211_sub_if_data *sdata)
 {
        struct ieee80211_local *local = sdata->local;
 
-       if (!local->powersave)
+       if (!local->ps_sdata)
                ieee80211_send_nullfunc(local, sdata, 0);
        else {
                /*
@@ -274,51 +263,62 @@ static void ieee80211_scan_ps_disable(struct ieee80211_sub_if_data *sdata)
        }
 }
 
+static void ieee80211_restore_scan_ies(struct ieee80211_local *local)
+{
+       kfree(local->scan_req->ie);
+       local->scan_req->ie = local->orig_ies;
+       local->scan_req->ie_len = local->orig_ies_len;
+}
+
 void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
 {
        struct ieee80211_local *local = hw_to_local(hw);
        struct ieee80211_sub_if_data *sdata;
+       bool was_hw_scan;
 
-       if (WARN_ON(!local->hw_scanning && !local->sw_scanning))
+       mutex_lock(&local->scan_mtx);
+
+       if (WARN_ON(!local->hw_scanning && !local->sw_scanning)) {
+               mutex_unlock(&local->scan_mtx);
                return;
+       }
 
-       if (WARN_ON(!local->scan_req))
+       if (WARN_ON(!local->scan_req)) {
+               mutex_unlock(&local->scan_mtx);
                return;
+       }
+
+       if (local->hw_scanning)
+               ieee80211_restore_scan_ies(local);
 
        if (local->scan_req != &local->int_scan_req)
                cfg80211_scan_done(local->scan_req, aborted);
        local->scan_req = NULL;
 
-       local->last_scan_completed = jiffies;
+       was_hw_scan = local->hw_scanning;
+       local->hw_scanning = false;
+       local->sw_scanning = false;
+       local->scan_channel = NULL;
 
-       if (local->hw_scanning) {
-               local->hw_scanning = false;
-               /*
-                * Somebody might have requested channel change during scan
-                * that we won't have acted upon, try now. ieee80211_hw_config
-                * will set the flag based on actual changes.
-                */
-               ieee80211_hw_config(local, 0);
-               goto done;
-       }
+       /* we only have to protect scan_req and hw/sw scan */
+       mutex_unlock(&local->scan_mtx);
 
-       local->sw_scanning = false;
        ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
+       if (was_hw_scan)
+               goto done;
 
        netif_tx_lock_bh(local->mdev);
        netif_addr_lock(local->mdev);
        local->filter_flags &= ~FIF_BCN_PRBRESP_PROMISC;
-       local->ops->configure_filter(local_to_hw(local),
-                                    FIF_BCN_PRBRESP_PROMISC,
-                                    &local->filter_flags,
-                                    local->mdev->mc_count,
-                                    local->mdev->mc_list);
+       drv_configure_filter(local, FIF_BCN_PRBRESP_PROMISC,
+                            &local->filter_flags,
+                            local->mdev->mc_count,
+                            local->mdev->mc_list);
 
        netif_addr_unlock(local->mdev);
        netif_tx_unlock_bh(local->mdev);
 
-       if (local->ops->sw_scan_complete)
-               local->ops->sw_scan_complete(local_to_hw(local));
+       drv_sw_scan_complete(local);
 
        mutex_lock(&local->iflist_mtx);
        list_for_each_entry(sdata, &local->interfaces, list) {
@@ -338,18 +338,160 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
                if (sdata->vif.type == NL80211_IFTYPE_AP ||
                    sdata->vif.type == NL80211_IFTYPE_ADHOC ||
                    sdata->vif.type == NL80211_IFTYPE_MESH_POINT)
-                       ieee80211_if_config(sdata,
-                                           IEEE80211_IFCC_BEACON_ENABLED);
+                       ieee80211_bss_info_change_notify(
+                               sdata, BSS_CHANGED_BEACON_ENABLED);
        }
        mutex_unlock(&local->iflist_mtx);
 
  done:
+       ieee80211_recalc_idle(local);
        ieee80211_mlme_notify_scan_completed(local);
        ieee80211_ibss_notify_scan_completed(local);
        ieee80211_mesh_notify_scan_completed(local);
 }
 EXPORT_SYMBOL(ieee80211_scan_completed);
 
+static int ieee80211_start_sw_scan(struct ieee80211_local *local)
+{
+       struct ieee80211_sub_if_data *sdata;
+
+       /*
+        * Hardware/driver doesn't support hw_scan, so use software
+        * scanning instead. First send a nullfunc frame with power save
+        * bit on so that AP will buffer the frames for us while we are not
+        * listening, then send probe requests to each channel and wait for
+        * the responses. After all channels are scanned, tune back to the
+        * original channel and send a nullfunc frame with power save bit
+        * off to trigger the AP to send us all the buffered frames.
+        *
+        * Note that while local->sw_scanning is true everything else but
+        * nullfunc frames and probe requests will be dropped in
+        * ieee80211_tx_h_check_assoc().
+        */
+       drv_sw_scan_start(local);
+
+       mutex_lock(&local->iflist_mtx);
+       list_for_each_entry(sdata, &local->interfaces, list) {
+               if (!netif_running(sdata->dev))
+                       continue;
+
+               /* disable beaconing */
+               if (sdata->vif.type == NL80211_IFTYPE_AP ||
+                   sdata->vif.type == NL80211_IFTYPE_ADHOC ||
+                   sdata->vif.type == NL80211_IFTYPE_MESH_POINT)
+                       ieee80211_bss_info_change_notify(
+                               sdata, BSS_CHANGED_BEACON_ENABLED);
+
+               if (sdata->vif.type == NL80211_IFTYPE_STATION) {
+                       if (sdata->u.mgd.flags & IEEE80211_STA_ASSOCIATED) {
+                               netif_tx_stop_all_queues(sdata->dev);
+                               ieee80211_scan_ps_enable(sdata);
+                       }
+               } else
+                       netif_tx_stop_all_queues(sdata->dev);
+       }
+       mutex_unlock(&local->iflist_mtx);
+
+       local->scan_state = SCAN_SET_CHANNEL;
+       local->scan_channel_idx = 0;
+
+       netif_addr_lock_bh(local->mdev);
+       local->filter_flags |= FIF_BCN_PRBRESP_PROMISC;
+       drv_configure_filter(local, FIF_BCN_PRBRESP_PROMISC,
+                            &local->filter_flags,
+                            local->mdev->mc_count,
+                            local->mdev->mc_list);
+       netif_addr_unlock_bh(local->mdev);
+
+       /* TODO: start scan as soon as all nullfunc frames are ACKed */
+       queue_delayed_work(local->hw.workqueue, &local->scan_work,
+                          IEEE80211_CHANNEL_TIME);
+
+       return 0;
+}
+
+
+static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
+                                 struct cfg80211_scan_request *req)
+{
+       struct ieee80211_local *local = sdata->local;
+       struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
+       int rc;
+
+       if (local->scan_req)
+               return -EBUSY;
+
+       if (local->ops->hw_scan) {
+               u8 *ies;
+               int ielen;
+
+               ies = kmalloc(2 + IEEE80211_MAX_SSID_LEN +
+                             local->scan_ies_len + req->ie_len, GFP_KERNEL);
+               if (!ies)
+                       return -ENOMEM;
+
+               ielen = ieee80211_build_preq_ies(local, ies,
+                                                req->ie, req->ie_len);
+               local->orig_ies = req->ie;
+               local->orig_ies_len = req->ie_len;
+               req->ie = ies;
+               req->ie_len = ielen;
+       }
+
+       local->scan_req = req;
+       local->scan_sdata = sdata;
+
+       if (req != &local->int_scan_req &&
+           sdata->vif.type == NL80211_IFTYPE_STATION &&
+           (ifmgd->state == IEEE80211_STA_MLME_DIRECT_PROBE ||
+            ifmgd->state == IEEE80211_STA_MLME_AUTHENTICATE ||
+            ifmgd->state == IEEE80211_STA_MLME_ASSOCIATE)) {
+               /* actually wait for the assoc to finish/time out */
+               set_bit(IEEE80211_STA_REQ_SCAN, &ifmgd->request);
+               return 0;
+       }
+
+       if (local->ops->hw_scan)
+               local->hw_scanning = true;
+       else
+               local->sw_scanning = true;
+       /*
+        * Kicking off the scan need not be protected,
+        * only the scan variable stuff, since now
+        * local->scan_req is assigned and other callers
+        * will abort their scan attempts.
+        *
+        * This avoids getting a scan_mtx -> iflist_mtx
+        * dependency, so that the scan completed calls
+        * have more locking freedom.
+        */
+
+       ieee80211_recalc_idle(local);
+       mutex_unlock(&local->scan_mtx);
+
+       if (local->ops->hw_scan)
+               rc = drv_hw_scan(local, local->scan_req);
+       else
+               rc = ieee80211_start_sw_scan(local);
+
+       mutex_lock(&local->scan_mtx);
+
+       if (rc) {
+               if (local->ops->hw_scan) {
+                       local->hw_scanning = false;
+                       ieee80211_restore_scan_ies(local);
+               } else
+                       local->sw_scanning = false;
+
+               ieee80211_recalc_idle(local);
+
+               local->scan_req = NULL;
+               local->scan_sdata = NULL;
+       }
+
+       return rc;
+}
+
 void ieee80211_scan_work(struct work_struct *work)
 {
        struct ieee80211_local *local =
@@ -359,17 +501,41 @@ void ieee80211_scan_work(struct work_struct *work)
        int skip, i;
        unsigned long next_delay = 0;
 
+       mutex_lock(&local->scan_mtx);
+       if (!sdata || !local->scan_req) {
+               mutex_unlock(&local->scan_mtx);
+               return;
+       }
+
+       if (local->scan_req && !(local->sw_scanning || local->hw_scanning)) {
+               struct cfg80211_scan_request *req = local->scan_req;
+               int rc;
+
+               local->scan_req = NULL;
+
+               rc = __ieee80211_start_scan(sdata, req);
+               mutex_unlock(&local->scan_mtx);
+
+               if (rc)
+                       ieee80211_scan_completed(&local->hw, true);
+               return;
+       }
+
+       mutex_unlock(&local->scan_mtx);
+
        /*
         * Avoid re-scheduling when the sdata is going away.
         */
-       if (!netif_running(sdata->dev))
+       if (!netif_running(sdata->dev)) {
+               ieee80211_scan_completed(&local->hw, true);
                return;
+       }
 
        switch (local->scan_state) {
        case SCAN_SET_CHANNEL:
                /* if no more bands/channels left, complete scan */
                if (local->scan_channel_idx >= local->scan_req->n_channels) {
-                       ieee80211_scan_completed(local_to_hw(local), false);
+                       ieee80211_scan_completed(&local->hw, false);
                        return;
                }
                skip = 0;
@@ -393,24 +559,39 @@ void ieee80211_scan_work(struct work_struct *work)
                if (skip)
                        break;
 
-               next_delay = IEEE80211_PROBE_DELAY +
-                            usecs_to_jiffies(local->hw.channel_change_time);
+               /*
+                * Probe delay is used to update the NAV, cf. 11.1.3.2.2
+                * (which unfortunately doesn't say _why_ step a) is done,
+                * but it waits for the probe delay or until a frame is
+                * received - and the received frame would update the NAV).
+                * For now, we do not support waiting until a frame is
+                * received.
+                *
+                * In any case, it is not necessary for a passive scan.
+                */
+               if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN ||
+                   !local->scan_req->n_ssids) {
+                       next_delay = IEEE80211_PASSIVE_CHANNEL_TIME;
+                       break;
+               }
+
+               next_delay = IEEE80211_PROBE_DELAY;
                local->scan_state = SCAN_SEND_PROBE;
                break;
        case SCAN_SEND_PROBE:
-               next_delay = IEEE80211_PASSIVE_CHANNEL_TIME;
-               local->scan_state = SCAN_SET_CHANNEL;
-
-               if (local->scan_channel->flags & IEEE80211_CHAN_PASSIVE_SCAN ||
-                   !local->scan_req->n_ssids)
-                       break;
                for (i = 0; i < local->scan_req->n_ssids; i++)
                        ieee80211_send_probe_req(
                                sdata, NULL,
                                local->scan_req->ssids[i].ssid,
                                local->scan_req->ssids[i].ssid_len,
                                local->scan_req->ie, local->scan_req->ie_len);
+
+               /*
+                * After sending probe requests, wait for probe responses
+                * on the channel.
+                */
                next_delay = IEEE80211_CHANNEL_TIME;
+               local->scan_state = SCAN_SET_CHANNEL;
                break;
        }
 
@@ -418,150 +599,53 @@ void ieee80211_scan_work(struct work_struct *work)
                           next_delay);
 }
 
-
-int ieee80211_start_scan(struct ieee80211_sub_if_data *scan_sdata,
-                        struct cfg80211_scan_request *req)
+int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata,
+                          struct cfg80211_scan_request *req)
 {
-       struct ieee80211_local *local = scan_sdata->local;
-       struct ieee80211_sub_if_data *sdata;
-
-       if (!req)
-               return -EINVAL;
-
-       if (local->scan_req && local->scan_req != req)
-               return -EBUSY;
-
-       local->scan_req = req;
-
-       /* MLME-SCAN.request (page 118)  page 144 (11.1.3.1)
-        * BSSType: INFRASTRUCTURE, INDEPENDENT, ANY_BSS
-        * BSSID: MACAddress
-        * SSID
-        * ScanType: ACTIVE, PASSIVE
-        * ProbeDelay: delay (in microseconds) to be used prior to transmitting
-        *    a Probe frame during active scanning
-        * ChannelList
-        * MinChannelTime (>= ProbeDelay), in TU
-        * MaxChannelTime: (>= MinChannelTime), in TU
-        */
-
-        /* MLME-SCAN.confirm
-         * BSSDescriptionSet
-         * ResultCode: SUCCESS, INVALID_PARAMETERS
-        */
-
-       if (local->sw_scanning || local->hw_scanning) {
-               if (local->scan_sdata == scan_sdata)
-                       return 0;
-               return -EBUSY;
-       }
-
-       if (local->ops->hw_scan) {
-               int rc;
-
-               local->hw_scanning = true;
-               rc = local->ops->hw_scan(local_to_hw(local), req);
-               if (rc) {
-                       local->hw_scanning = false;
-                       return rc;
-               }
-               local->scan_sdata = scan_sdata;
-               return 0;
-       }
-
-       /*
-        * Hardware/driver doesn't support hw_scan, so use software
-        * scanning instead. First send a nullfunc frame with power save
-        * bit on so that AP will buffer the frames for us while we are not
-        * listening, then send probe requests to each channel and wait for
-        * the responses. After all channels are scanned, tune back to the
-        * original channel and send a nullfunc frame with power save bit
-        * off to trigger the AP to send us all the buffered frames.
-        *
-        * Note that while local->sw_scanning is true everything else but
-        * nullfunc frames and probe requests will be dropped in
-        * ieee80211_tx_h_check_assoc().
-        */
-       local->sw_scanning = true;
-       if (local->ops->sw_scan_start)
-               local->ops->sw_scan_start(local_to_hw(local));
+       int res;
 
-       mutex_lock(&local->iflist_mtx);
-       list_for_each_entry(sdata, &local->interfaces, list) {
-               if (!netif_running(sdata->dev))
-                       continue;
+       mutex_lock(&sdata->local->scan_mtx);
+       res = __ieee80211_start_scan(sdata, req);
+       mutex_unlock(&sdata->local->scan_mtx);
 
-               /* disable beaconing */
-               if (sdata->vif.type == NL80211_IFTYPE_AP ||
-                   sdata->vif.type == NL80211_IFTYPE_ADHOC ||
-                   sdata->vif.type == NL80211_IFTYPE_MESH_POINT)
-                       ieee80211_if_config(sdata,
-                                           IEEE80211_IFCC_BEACON_ENABLED);
+       return res;
+}
 
-               if (sdata->vif.type == NL80211_IFTYPE_STATION) {
-                       if (sdata->u.mgd.flags & IEEE80211_STA_ASSOCIATED) {
-                               netif_tx_stop_all_queues(sdata->dev);
-                               ieee80211_scan_ps_enable(sdata);
-                       }
-               } else
-                       netif_tx_stop_all_queues(sdata->dev);
-       }
-       mutex_unlock(&local->iflist_mtx);
+int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata,
+                                   const u8 *ssid, u8 ssid_len)
+{
+       struct ieee80211_local *local = sdata->local;
+       int ret = -EBUSY;
 
-       local->scan_state = SCAN_SET_CHANNEL;
-       local->scan_channel_idx = 0;
-       local->scan_sdata = scan_sdata;
-       local->scan_req = req;
+       mutex_lock(&local->scan_mtx);
 
-       netif_addr_lock_bh(local->mdev);
-       local->filter_flags |= FIF_BCN_PRBRESP_PROMISC;
-       local->ops->configure_filter(local_to_hw(local),
-                                    FIF_BCN_PRBRESP_PROMISC,
-                                    &local->filter_flags,
-                                    local->mdev->mc_count,
-                                    local->mdev->mc_list);
-       netif_addr_unlock_bh(local->mdev);
+       /* busy scanning */
+       if (local->scan_req)
+               goto unlock;
 
-       /* TODO: start scan as soon as all nullfunc frames are ACKed */
-       queue_delayed_work(local->hw.workqueue, &local->scan_work,
-                          IEEE80211_CHANNEL_TIME);
+       memcpy(local->int_scan_req.ssids[0].ssid, ssid, IEEE80211_MAX_SSID_LEN);
+       local->int_scan_req.ssids[0].ssid_len = ssid_len;
 
-       return 0;
+       ret = __ieee80211_start_scan(sdata, &sdata->local->int_scan_req);
+ unlock:
+       mutex_unlock(&local->scan_mtx);
+       return ret;
 }
 
-
-int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata,
-                          struct cfg80211_scan_request *req)
+void ieee80211_scan_cancel(struct ieee80211_local *local)
 {
-       struct ieee80211_local *local = sdata->local;
-       struct ieee80211_if_managed *ifmgd;
-
-       if (!req)
-               return -EINVAL;
+       bool swscan;
 
-       if (local->scan_req && local->scan_req != req)
-               return -EBUSY;
-
-       local->scan_req = req;
-
-       if (sdata->vif.type != NL80211_IFTYPE_STATION)
-               return ieee80211_start_scan(sdata, req);
+       cancel_delayed_work_sync(&local->scan_work);
 
        /*
-        * STA has a state machine that might need to defer scanning
-        * while it's trying to associate/authenticate, therefore we
-        * queue it up to the state machine in that case.
+        * Only call this function when a scan can't be
+        * queued -- mostly at suspend under RTNL.
         */
+       mutex_lock(&local->scan_mtx);
+       swscan = local->sw_scanning;
+       mutex_unlock(&local->scan_mtx);
 
-       if (local->sw_scanning || local->hw_scanning) {
-               if (local->scan_sdata == sdata)
-                       return 0;
-               return -EBUSY;
-       }
-
-       ifmgd = &sdata->u.mgd;
-       set_bit(IEEE80211_STA_REQ_SCAN, &ifmgd->request);
-       queue_work(local->hw.workqueue, &ifmgd->work);
-
-       return 0;
+       if (swscan)
+               ieee80211_scan_completed(&local->hw, true);
 }
index 5f7a2624ed7475988d541418ef738494dc0d11e0..68953033403d02f45653932a0fffbbccd1eacc38 100644 (file)
@@ -15,7 +15,7 @@
  */
 
 #include <linux/ieee80211.h>
-#include <net/wireless.h>
+#include <net/cfg80211.h>
 #include <net/mac80211.h>
 #include "ieee80211_i.h"
 #include "sta_info.h"
@@ -84,104 +84,3 @@ void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata,
                        mgmt->sa, mgmt->bssid,
                        mgmt->u.action.u.measurement.dialog_token);
 }
-
-void ieee80211_chswitch_work(struct work_struct *work)
-{
-       struct ieee80211_sub_if_data *sdata =
-               container_of(work, struct ieee80211_sub_if_data, u.mgd.chswitch_work);
-       struct ieee80211_bss *bss;
-       struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
-
-       if (!netif_running(sdata->dev))
-               return;
-
-       bss = ieee80211_rx_bss_get(sdata->local, ifmgd->bssid,
-                                  sdata->local->hw.conf.channel->center_freq,
-                                  ifmgd->ssid, ifmgd->ssid_len);
-       if (!bss)
-               goto exit;
-
-       sdata->local->oper_channel = sdata->local->csa_channel;
-       /* XXX: shouldn't really modify cfg80211-owned data! */
-       if (!ieee80211_hw_config(sdata->local, IEEE80211_CONF_CHANGE_CHANNEL))
-               bss->cbss.channel = sdata->local->oper_channel;
-
-       ieee80211_rx_bss_put(sdata->local, bss);
-exit:
-       ifmgd->flags &= ~IEEE80211_STA_CSA_RECEIVED;
-       ieee80211_wake_queues_by_reason(&sdata->local->hw,
-                                       IEEE80211_QUEUE_STOP_REASON_CSA);
-}
-
-void ieee80211_chswitch_timer(unsigned long data)
-{
-       struct ieee80211_sub_if_data *sdata =
-               (struct ieee80211_sub_if_data *) data;
-       struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
-
-       queue_work(sdata->local->hw.workqueue, &ifmgd->chswitch_work);
-}
-
-void ieee80211_process_chanswitch(struct ieee80211_sub_if_data *sdata,
-                                 struct ieee80211_channel_sw_ie *sw_elem,
-                                 struct ieee80211_bss *bss)
-{
-       struct ieee80211_channel *new_ch;
-       struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
-       int new_freq = ieee80211_channel_to_frequency(sw_elem->new_ch_num);
-
-       /* FIXME: Handle ADHOC later */
-       if (sdata->vif.type != NL80211_IFTYPE_STATION)
-               return;
-
-       if (ifmgd->state != IEEE80211_STA_MLME_ASSOCIATED)
-               return;
-
-       if (sdata->local->sw_scanning || sdata->local->hw_scanning)
-               return;
-
-       /* Disregard subsequent beacons if we are already running a timer
-          processing a CSA */
-
-       if (ifmgd->flags & IEEE80211_STA_CSA_RECEIVED)
-               return;
-
-       new_ch = ieee80211_get_channel(sdata->local->hw.wiphy, new_freq);
-       if (!new_ch || new_ch->flags & IEEE80211_CHAN_DISABLED)
-               return;
-
-       sdata->local->csa_channel = new_ch;
-
-       if (sw_elem->count <= 1) {
-               queue_work(sdata->local->hw.workqueue, &ifmgd->chswitch_work);
-       } else {
-               ieee80211_stop_queues_by_reason(&sdata->local->hw,
-                                               IEEE80211_QUEUE_STOP_REASON_CSA);
-               ifmgd->flags |= IEEE80211_STA_CSA_RECEIVED;
-               mod_timer(&ifmgd->chswitch_timer,
-                         jiffies +
-                         msecs_to_jiffies(sw_elem->count *
-                                          bss->cbss.beacon_interval));
-       }
-}
-
-void ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata,
-                                u16 capab_info, u8 *pwr_constr_elem,
-                                u8 pwr_constr_elem_len)
-{
-       struct ieee80211_conf *conf = &sdata->local->hw.conf;
-
-       if (!(capab_info & WLAN_CAPABILITY_SPECTRUM_MGMT))
-               return;
-
-       /* Power constraint IE length should be 1 octet */
-       if (pwr_constr_elem_len != 1)
-               return;
-
-       if ((*pwr_constr_elem <= conf->channel->max_power) &&
-           (*pwr_constr_elem != sdata->local->power_constr_level)) {
-               sdata->local->power_constr_level = *pwr_constr_elem;
-               ieee80211_hw_config(sdata->local, 0);
-       }
-}
-
index c5f14e6bbde20ab9128f69d28923cf8a3c84b459..a360bceeba59461d8d83e20220a60aba06fe693d 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <net/mac80211.h>
 #include "ieee80211_i.h"
+#include "driver-ops.h"
 #include "rate.h"
 #include "sta_info.h"
 #include "debugfs_sta.h"
  * When the insertion fails (sta_info_insert()) returns non-zero), the
  * structure will have been freed by sta_info_insert()!
  *
+ * sta entries are added by mac80211 when you establish a link with a
+ * peer. This means different things for the different type of interfaces
+ * we support. For a regular station this mean we add the AP sta when we
+ * receive an assocation response from the AP. For IBSS this occurs when
+ * we receive a probe response or a beacon from target IBSS network. For
+ * WDS we add the sta for the peer imediately upon device open. When using
+ * AP mode we add stations for each respective station upon request from
+ * userspace through nl80211.
+ *
  * Because there are debugfs entries for each station, and adding those
  * must be able to sleep, it is also possible to "pin" a station entry,
  * that means it can be removed from the hash table but not be freed.
@@ -292,6 +302,9 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
        skb_queue_head_init(&sta->ps_tx_buf);
        skb_queue_head_init(&sta->tx_filtered);
 
+       for (i = 0; i < NUM_RX_DATA_QUEUES; i++)
+               sta->last_seq_ctrl[i] = cpu_to_le16(USHORT_MAX);
+
 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
        printk(KERN_DEBUG "%s: Allocated STA %pM\n",
               wiphy_name(local->hw.wiphy), sta->sta.addr);
@@ -346,8 +359,7 @@ int sta_info_insert(struct sta_info *sta)
                                             struct ieee80211_sub_if_data,
                                             u.ap);
 
-               local->ops->sta_notify(local_to_hw(local), &sdata->vif,
-                                      STA_NOTIFY_ADD, &sta->sta);
+               drv_sta_notify(local, &sdata->vif, STA_NOTIFY_ADD, &sta->sta);
        }
 
 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
@@ -405,8 +417,7 @@ static void __sta_info_set_tim_bit(struct ieee80211_if_ap *bss,
 
        if (sta->local->ops->set_tim) {
                sta->local->tim_in_locked_section = true;
-               sta->local->ops->set_tim(local_to_hw(sta->local),
-                                        &sta->sta, true);
+               drv_set_tim(sta->local, &sta->sta, true);
                sta->local->tim_in_locked_section = false;
        }
 }
@@ -431,8 +442,7 @@ static void __sta_info_clear_tim_bit(struct ieee80211_if_ap *bss,
 
        if (sta->local->ops->set_tim) {
                sta->local->tim_in_locked_section = true;
-               sta->local->ops->set_tim(local_to_hw(sta->local),
-                                        &sta->sta, false);
+               drv_set_tim(sta->local, &sta->sta, false);
                sta->local->tim_in_locked_section = false;
        }
 }
@@ -482,8 +492,8 @@ static void __sta_info_unlink(struct sta_info **sta)
                                             struct ieee80211_sub_if_data,
                                             u.ap);
 
-               local->ops->sta_notify(local_to_hw(local), &sdata->vif,
-                                      STA_NOTIFY_REMOVE, &(*sta)->sta);
+               drv_sta_notify(local, &sdata->vif, STA_NOTIFY_REMOVE,
+                              &(*sta)->sta);
        }
 
        if (ieee80211_vif_is_mesh(&sdata->vif)) {
@@ -543,9 +553,8 @@ void sta_info_unlink(struct sta_info **sta)
        spin_unlock_irqrestore(&local->sta_lock, flags);
 }
 
-static inline int sta_info_buffer_expired(struct ieee80211_local *local,
-                                         struct sta_info *sta,
-                                         struct sk_buff *skb)
+static int sta_info_buffer_expired(struct sta_info *sta,
+                                  struct sk_buff *skb)
 {
        struct ieee80211_tx_info *info;
        int timeout;
@@ -556,8 +565,9 @@ static inline int sta_info_buffer_expired(struct ieee80211_local *local,
        info = IEEE80211_SKB_CB(skb);
 
        /* Timeout: (2 * listen_interval * beacon_int * 1024 / 1000000) sec */
-       timeout = (sta->listen_interval * local->hw.conf.beacon_int * 32 /
-                  15625) * HZ;
+       timeout = (sta->listen_interval *
+                  sta->sdata->vif.bss_conf.beacon_int *
+                  32 / 15625) * HZ;
        if (timeout < STA_TX_BUFFER_EXPIRE)
                timeout = STA_TX_BUFFER_EXPIRE;
        return time_after(jiffies, info->control.jiffies + timeout);
@@ -577,7 +587,7 @@ static void sta_info_cleanup_expire_buffered(struct ieee80211_local *local,
        for (;;) {
                spin_lock_irqsave(&sta->ps_tx_buf.lock, flags);
                skb = skb_peek(&sta->ps_tx_buf);
-               if (sta_info_buffer_expired(local, sta, skb))
+               if (sta_info_buffer_expired(sta, skb))
                        skb = __skb_dequeue(&sta->ps_tx_buf);
                else
                        skb = NULL;
@@ -610,6 +620,9 @@ static void sta_info_cleanup(unsigned long data)
                sta_info_cleanup_expire_buffered(local, sta);
        rcu_read_unlock();
 
+       if (local->quiescing)
+               return;
+
        local->sta_cleanup.expires =
                round_jiffies(jiffies + STA_INFO_CLEANUP_INTERVAL);
        add_timer(&local->sta_cleanup);
@@ -686,41 +699,10 @@ static void sta_info_debugfs_add_work(struct work_struct *work)
 }
 #endif
 
-static void __ieee80211_run_pending_flush(struct ieee80211_local *local)
-{
-       struct sta_info *sta;
-       unsigned long flags;
-
-       ASSERT_RTNL();
-
-       spin_lock_irqsave(&local->sta_lock, flags);
-       while (!list_empty(&local->sta_flush_list)) {
-               sta = list_first_entry(&local->sta_flush_list,
-                                      struct sta_info, list);
-               list_del(&sta->list);
-               spin_unlock_irqrestore(&local->sta_lock, flags);
-               sta_info_destroy(sta);
-               spin_lock_irqsave(&local->sta_lock, flags);
-       }
-       spin_unlock_irqrestore(&local->sta_lock, flags);
-}
-
-static void ieee80211_sta_flush_work(struct work_struct *work)
-{
-       struct ieee80211_local *local =
-               container_of(work, struct ieee80211_local, sta_flush_work);
-
-       rtnl_lock();
-       __ieee80211_run_pending_flush(local);
-       rtnl_unlock();
-}
-
 void sta_info_init(struct ieee80211_local *local)
 {
        spin_lock_init(&local->sta_lock);
        INIT_LIST_HEAD(&local->sta_list);
-       INIT_LIST_HEAD(&local->sta_flush_list);
-       INIT_WORK(&local->sta_flush_work, ieee80211_sta_flush_work);
 
        setup_timer(&local->sta_cleanup, sta_info_cleanup,
                    (unsigned long)local);
@@ -741,7 +723,6 @@ int sta_info_start(struct ieee80211_local *local)
 void sta_info_stop(struct ieee80211_local *local)
 {
        del_timer(&local->sta_cleanup);
-       cancel_work_sync(&local->sta_flush_work);
 #ifdef CONFIG_MAC80211_DEBUGFS
        /*
         * Make sure the debugfs adding work isn't pending after this
@@ -752,10 +733,7 @@ void sta_info_stop(struct ieee80211_local *local)
        cancel_work_sync(&local->sta_debugfs_add);
 #endif
 
-       rtnl_lock();
        sta_info_flush(local, NULL);
-       __ieee80211_run_pending_flush(local);
-       rtnl_unlock();
 }
 
 /**
@@ -767,7 +745,7 @@ void sta_info_stop(struct ieee80211_local *local)
  * @sdata: matching rule for the net device (sta->dev) or %NULL to match all STAs
  */
 int sta_info_flush(struct ieee80211_local *local,
-                   struct ieee80211_sub_if_data *sdata)
+                  struct ieee80211_sub_if_data *sdata)
 {
        struct sta_info *sta, *tmp;
        LIST_HEAD(tmp_list);
@@ -775,7 +753,6 @@ int sta_info_flush(struct ieee80211_local *local,
        unsigned long flags;
 
        might_sleep();
-       ASSERT_RTNL();
 
        spin_lock_irqsave(&local->sta_lock, flags);
        list_for_each_entry_safe(sta, tmp, &local->sta_list, list) {
@@ -795,39 +772,6 @@ int sta_info_flush(struct ieee80211_local *local,
        return ret;
 }
 
-/**
- * sta_info_flush_delayed - flush matching STA entries from the STA table
- *
- * This function unlinks all stations for a given interface and queues
- * them for freeing. Note that the workqueue function scheduled here has
- * to run before any new keys can be added to the system to avoid set_key()
- * callback ordering issues.
- *
- * @sdata: the interface
- */
-void sta_info_flush_delayed(struct ieee80211_sub_if_data *sdata)
-{
-       struct ieee80211_local *local = sdata->local;
-       struct sta_info *sta, *tmp;
-       unsigned long flags;
-       bool work = false;
-
-       spin_lock_irqsave(&local->sta_lock, flags);
-       list_for_each_entry_safe(sta, tmp, &local->sta_list, list) {
-               if (sdata == sta->sdata) {
-                       __sta_info_unlink(&sta);
-                       if (sta) {
-                               list_add_tail(&sta->list,
-                                             &local->sta_flush_list);
-                               work = true;
-                       }
-               }
-       }
-       if (work)
-               schedule_work(&local->sta_flush_work);
-       spin_unlock_irqrestore(&local->sta_lock, flags);
-}
-
 void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata,
                          unsigned long exp_time)
 {
index 5534d489f50678826f751d7cf04fbcd2af50f45f..49a1a1f76511e480ddf306258d5fec0be97fa6b0 100644 (file)
@@ -88,6 +88,7 @@ struct tid_ampdu_tx {
  * struct tid_ampdu_rx - TID aggregation information (Rx).
  *
  * @reorder_buf: buffer to reorder incoming aggregated MPDUs
+ * @reorder_time: jiffies when skb was added
  * @session_timer: check if peer keeps Tx-ing on the TID (by timeout value)
  * @head_seq_num: head sequence number in reordering buffer.
  * @stored_mpdu_num: number of MPDUs in reordering buffer
@@ -99,6 +100,7 @@ struct tid_ampdu_tx {
  */
 struct tid_ampdu_rx {
        struct sk_buff **reorder_buf;
+       unsigned long *reorder_time;
        struct timer_list session_timer;
        u16 head_seq_num;
        u16 stored_mpdu_num;
@@ -214,6 +216,7 @@ struct sta_ampdu_mlme {
  * @plink_state: peer link state
  * @plink_timeout: timeout of peer link
  * @plink_timer: peer link watch timer
+ * @plink_timer_was_running: used by suspend/resume to restore timers
  * @debugfs: debug filesystem info
  * @sta: station information we share with the driver
  */
@@ -291,6 +294,7 @@ struct sta_info {
        __le16 reason;
        u8 plink_retries;
        bool ignore_plink_timer;
+       bool plink_timer_was_running;
        enum plink_state plink_state;
        u32 plink_timeout;
        struct timer_list plink_timer;
@@ -442,8 +446,7 @@ void sta_info_init(struct ieee80211_local *local);
 int sta_info_start(struct ieee80211_local *local);
 void sta_info_stop(struct ieee80211_local *local);
 int sta_info_flush(struct ieee80211_local *local,
-                   struct ieee80211_sub_if_data *sdata);
-void sta_info_flush_delayed(struct ieee80211_sub_if_data *sdata);
+                  struct ieee80211_sub_if_data *sdata);
 void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata,
                          unsigned long exp_time);
 
index 38fa111d2dc6fff3720fd2990777ff75adc75b37..964b7faa7f17134f6b1e1371557487ba26cdd4cb 100644 (file)
@@ -13,6 +13,7 @@
 #include <asm/unaligned.h>
 
 #include <net/mac80211.h>
+#include "driver-ops.h"
 #include "key.h"
 #include "tkip.h"
 #include "wep.h"
@@ -307,9 +308,8 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm,
                        if (is_multicast_ether_addr(ra))
                                sta_addr = bcast;
 
-                       key->local->ops->update_tkip_key(
-                               local_to_hw(key->local), &key->conf,
-                               sta_addr, iv32, key->u.tkip.rx[queue].p1k);
+                       drv_update_tkip_key(key->local, &key->conf, sta_addr,
+                                           iv32, key->u.tkip.rx[queue].p1k);
                }
        }
 
index 63656266d567e50f5b2d82bc4580d7abdfbf65b4..d238a8939a094de63e1f9782a68b908a4340b998 100644 (file)
@@ -25,6 +25,7 @@
 #include <asm/unaligned.h>
 
 #include "ieee80211_i.h"
+#include "driver-ops.h"
 #include "led.h"
 #include "mesh.h"
 #include "wep.h"
@@ -399,6 +400,7 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
                        sta_info_set_tim_bit(sta);
 
                info->control.jiffies = jiffies;
+               info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
                skb_queue_tail(&sta->ps_tx_buf, tx->skb);
                return TX_QUEUED;
        }
@@ -409,8 +411,24 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
                       sta->sta.addr);
        }
 #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
-       clear_sta_flags(sta, WLAN_STA_PSPOLL);
+       if (test_and_clear_sta_flags(sta, WLAN_STA_PSPOLL)) {
+               /*
+                * The sleeping station with pending data is now snoozing.
+                * It queried us for its buffered frames and will go back
+                * to deep sleep once it got everything.
+                *
+                * inform the driver, in case the hardware does powersave
+                * frame filtering and keeps a station  blacklist on its own
+                * (e.g: p54), so that frames can be delivered unimpeded.
+                *
+                * Note: It should be safe to disable the filter now.
+                * As, it is really unlikely that we still have any pending
+                * frame for this station in the hw's buffers/fifos left,
+                * that is not rejected with a unsuccessful tx_status yet.
+                */
 
+               info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT;
+       }
        return TX_CONTINUE;
 }
 
@@ -429,7 +447,7 @@ ieee80211_tx_h_ps_buf(struct ieee80211_tx_data *tx)
 static ieee80211_tx_result debug_noinline
 ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx)
 {
-       struct ieee80211_key *key;
+       struct ieee80211_key *key = NULL;
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data;
 
@@ -500,7 +518,7 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
        sband = tx->local->hw.wiphy->bands[tx->channel->band];
 
        len = min_t(int, tx->skb->len + FCS_LEN,
-                        tx->local->fragmentation_threshold);
+                        tx->local->hw.wiphy->frag_threshold);
 
        /* set up the tx rate control struct we give the RC algo */
        txrc.hw = local_to_hw(tx->local);
@@ -511,8 +529,7 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
        txrc.max_rate_idx = tx->sdata->max_ratectrl_rateidx;
 
        /* set up RTS protection if desired */
-       if (tx->local->rts_threshold < IEEE80211_MAX_RTS_THRESHOLD &&
-           len > tx->local->rts_threshold) {
+       if (len > tx->local->hw.wiphy->rts_threshold) {
                txrc.rts = rts = true;
        }
 
@@ -542,6 +559,10 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
        if (unlikely(!info->control.rates[0].count))
                info->control.rates[0].count = 1;
 
+       if (WARN_ON_ONCE((info->control.rates[0].count > 1) &&
+                        (info->flags & IEEE80211_TX_CTL_NO_ACK)))
+               info->control.rates[0].count = 1;
+
        if (is_multicast_ether_addr(hdr->addr1)) {
                /*
                 * XXX: verify the rate is in the basic rateset
@@ -754,7 +775,7 @@ ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx)
        struct sk_buff *skb = tx->skb;
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
        struct ieee80211_hdr *hdr = (void *)skb->data;
-       int frag_threshold = tx->local->fragmentation_threshold;
+       int frag_threshold = tx->local->hw.wiphy->frag_threshold;
        int hdrlen;
        int fragnum;
 
@@ -852,6 +873,8 @@ ieee80211_tx_h_calculate_duration(struct ieee80211_tx_data *tx)
 
        do {
                hdr = (void *) skb->data;
+               if (unlikely(ieee80211_is_pspoll(hdr->frame_control)))
+                       break; /* must not overwrite AID */
                next_len = skb->next ? skb->next->len : 0;
                group_addr = is_multicast_ether_addr(hdr->addr1);
 
@@ -885,9 +908,8 @@ ieee80211_tx_h_stats(struct ieee80211_tx_data *tx)
  * deal with packet injection down monitor interface
  * with Radiotap Header -- only called for monitor mode interface
  */
-static ieee80211_tx_result
-__ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx,
-                             struct sk_buff *skb)
+static bool __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx,
+                                         struct sk_buff *skb)
 {
        /*
         * this is the moment to interpret and discard the radiotap header that
@@ -938,7 +960,7 @@ __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx,
                                 * on transmission
                                 */
                                if (skb->len < (iterator.max_length + FCS_LEN))
-                                       return TX_DROP;
+                                       return false;
 
                                skb_trim(skb, skb->len - FCS_LEN);
                        }
@@ -960,7 +982,7 @@ __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx,
        }
 
        if (ret != -ENOENT) /* ie, if we didn't simply run out of fields */
-               return TX_DROP;
+               return false;
 
        /*
         * remove the radiotap header
@@ -969,7 +991,7 @@ __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx,
         */
        skb_pull(skb, iterator.max_length);
 
-       return TX_CONTINUE;
+       return true;
 }
 
 /*
@@ -1003,7 +1025,7 @@ __ieee80211_tx_prepare(struct ieee80211_tx_data *tx,
        /* process and remove the injection radiotap header */
        sdata = IEEE80211_DEV_TO_SUB_IF(dev);
        if (unlikely(info->flags & IEEE80211_TX_CTL_INJECTED)) {
-               if (__ieee80211_parse_tx_radiotap(tx, skb) == TX_DROP)
+               if (!__ieee80211_parse_tx_radiotap(tx, skb))
                        return TX_DROP;
 
                /*
@@ -1067,12 +1089,15 @@ __ieee80211_tx_prepare(struct ieee80211_tx_data *tx,
                info->flags |= IEEE80211_TX_CTL_NO_ACK;
        } else {
                tx->flags |= IEEE80211_TX_UNICAST;
-               info->flags &= ~IEEE80211_TX_CTL_NO_ACK;
+               if (unlikely(local->wifi_wme_noack_test))
+                       info->flags |= IEEE80211_TX_CTL_NO_ACK;
+               else
+                       info->flags &= ~IEEE80211_TX_CTL_NO_ACK;
        }
 
        if (tx->flags & IEEE80211_TX_FRAGMENTED) {
                if ((tx->flags & IEEE80211_TX_UNICAST) &&
-                   skb->len + FCS_LEN > local->fragmentation_threshold &&
+                   skb->len + FCS_LEN > local->hw.wiphy->frag_threshold &&
                    !(info->flags & IEEE80211_TX_CTL_AMPDU))
                        tx->flags |= IEEE80211_TX_FRAGMENTED;
                else
@@ -1147,7 +1172,7 @@ static int __ieee80211_tx(struct ieee80211_local *local,
 
                next = skb->next;
                len = skb->len;
-               ret = local->ops->tx(local_to_hw(local), skb);
+               ret = drv_tx(local, skb);
                if (WARN_ON(ret != NETDEV_TX_OK && skb->len != len)) {
                        dev_kfree_skb(skb);
                        ret = NETDEV_TX_OK;
@@ -1213,7 +1238,6 @@ static void ieee80211_tx(struct net_device *dev, struct sk_buff *skb,
                         bool txpending)
 {
        struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
-       struct sta_info *sta;
        struct ieee80211_tx_data tx;
        ieee80211_tx_result res_prepare;
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
@@ -1245,7 +1269,6 @@ static void ieee80211_tx(struct net_device *dev, struct sk_buff *skb,
                return;
        }
 
-       sta = tx.sta;
        tx.channel = local->hw.conf.channel;
        info->band = tx.channel->band;
 
@@ -1392,7 +1415,8 @@ int ieee80211_master_start_xmit(struct sk_buff *skb, struct net_device *dev)
        }
 
        if ((local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) &&
-           local->hw.conf.dynamic_ps_timeout > 0) {
+           local->hw.conf.dynamic_ps_timeout > 0 &&
+           !local->sw_scanning && !local->hw_scanning && local->ps_sdata) {
                if (local->hw.conf.flags & IEEE80211_CONF_PS) {
                        ieee80211_stop_queues_by_reason(&local->hw,
                                        IEEE80211_QUEUE_STOP_REASON_PS);
@@ -1591,7 +1615,7 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
 {
        struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
        struct ieee80211_local *local = sdata->local;
-       int ret = 1, head_need;
+       int ret = NETDEV_TX_BUSY, head_need;
        u16 ethertype, hdrlen,  meshhdrlen = 0;
        __le16 fc;
        struct ieee80211_hdr hdr;
@@ -2086,18 +2110,18 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
        } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
                struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
                struct ieee80211_hdr *hdr;
+               struct sk_buff *presp = rcu_dereference(ifibss->presp);
 
-               if (!ifibss->probe_resp)
+               if (!presp)
                        goto out;
 
-               skb = skb_copy(ifibss->probe_resp, GFP_ATOMIC);
+               skb = skb_copy(presp, GFP_ATOMIC);
                if (!skb)
                        goto out;
 
                hdr = (struct ieee80211_hdr *) skb->data;
                hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
                                                 IEEE80211_STYPE_BEACON);
-
        } else if (ieee80211_vif_is_mesh(&sdata->vif)) {
                struct ieee80211_mgmt *mgmt;
                u8 *pos;
@@ -2117,7 +2141,7 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
                memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
                /* BSSID is left zeroed, wildcard value */
                mgmt->u.beacon.beacon_int =
-                       cpu_to_le16(local->hw.conf.beacon_int);
+                       cpu_to_le16(sdata->vif.bss_conf.beacon_int);
                mgmt->u.beacon.capab_info = 0x0; /* 0x0 for MPs */
 
                pos = skb_put(skb, 2);
index fdf432f14554d018b3cca371288d5d96d01aafbf..66ce96a69f318bab53cf88a8946c49b494f7b9ab 100644 (file)
 #include <linux/if_arp.h>
 #include <linux/wireless.h>
 #include <linux/bitmap.h>
+#include <linux/crc32.h>
 #include <net/net_namespace.h>
 #include <net/cfg80211.h>
 #include <net/rtnetlink.h>
 
 #include "ieee80211_i.h"
+#include "driver-ops.h"
 #include "rate.h"
 #include "mesh.h"
 #include "wme.h"
+#include "led.h"
 
 /* privid for wiphys to determine whether they belong to us or not */
 void *mac80211_wiphy_privid = &mac80211_wiphy_privid;
 
-/* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */
-/* Ethernet-II snap header (RFC1042 for most EtherTypes) */
-const unsigned char rfc1042_header[] __aligned(2) =
-       { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
-
-/* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */
-const unsigned char bridge_tunnel_header[] __aligned(2) =
-       { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
-
 struct ieee80211_hw *wiphy_to_ieee80211_hw(struct wiphy *wiphy)
 {
        struct ieee80211_local *local;
@@ -100,70 +94,6 @@ u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len,
        return NULL;
 }
 
-unsigned int ieee80211_hdrlen(__le16 fc)
-{
-       unsigned int hdrlen = 24;
-
-       if (ieee80211_is_data(fc)) {
-               if (ieee80211_has_a4(fc))
-                       hdrlen = 30;
-               if (ieee80211_is_data_qos(fc))
-                       hdrlen += IEEE80211_QOS_CTL_LEN;
-               goto out;
-       }
-
-       if (ieee80211_is_ctl(fc)) {
-               /*
-                * ACK and CTS are 10 bytes, all others 16. To see how
-                * to get this condition consider
-                *   subtype mask:   0b0000000011110000 (0x00F0)
-                *   ACK subtype:    0b0000000011010000 (0x00D0)
-                *   CTS subtype:    0b0000000011000000 (0x00C0)
-                *   bits that matter:         ^^^      (0x00E0)
-                *   value of those: 0b0000000011000000 (0x00C0)
-                */
-               if ((fc & cpu_to_le16(0x00E0)) == cpu_to_le16(0x00C0))
-                       hdrlen = 10;
-               else
-                       hdrlen = 16;
-       }
-out:
-       return hdrlen;
-}
-EXPORT_SYMBOL(ieee80211_hdrlen);
-
-unsigned int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb)
-{
-       const struct ieee80211_hdr *hdr = (const struct ieee80211_hdr *)skb->data;
-       unsigned int hdrlen;
-
-       if (unlikely(skb->len < 10))
-               return 0;
-       hdrlen = ieee80211_hdrlen(hdr->frame_control);
-       if (unlikely(hdrlen > skb->len))
-               return 0;
-       return hdrlen;
-}
-EXPORT_SYMBOL(ieee80211_get_hdrlen_from_skb);
-
-int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr)
-{
-       int ae = meshhdr->flags & IEEE80211S_FLAGS_AE;
-       /* 7.1.3.5a.2 */
-       switch (ae) {
-       case 0:
-               return 6;
-       case 1:
-               return 12;
-       case 2:
-               return 18;
-       case 3:
-               return 24;
-       default:
-               return 6;
-       }
-}
-
 void ieee80211_tx_set_protected(struct ieee80211_tx_data *tx)
 {
        struct sk_buff *skb = tx->skb;
@@ -411,6 +341,52 @@ void ieee80211_stop_queue(struct ieee80211_hw *hw, int queue)
 }
 EXPORT_SYMBOL(ieee80211_stop_queue);
 
+void ieee80211_add_pending_skb(struct ieee80211_local *local,
+                              struct sk_buff *skb)
+{
+       struct ieee80211_hw *hw = &local->hw;
+       unsigned long flags;
+       int queue = skb_get_queue_mapping(skb);
+
+       spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
+       __ieee80211_stop_queue(hw, queue, IEEE80211_QUEUE_STOP_REASON_SKB_ADD);
+       __ieee80211_stop_queue(hw, queue, IEEE80211_QUEUE_STOP_REASON_PENDING);
+       skb_queue_tail(&local->pending[queue], skb);
+       __ieee80211_wake_queue(hw, queue, IEEE80211_QUEUE_STOP_REASON_SKB_ADD);
+       spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
+}
+
+int ieee80211_add_pending_skbs(struct ieee80211_local *local,
+                              struct sk_buff_head *skbs)
+{
+       struct ieee80211_hw *hw = &local->hw;
+       struct sk_buff *skb;
+       unsigned long flags;
+       int queue, ret = 0, i;
+
+       spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
+       for (i = 0; i < hw->queues; i++)
+               __ieee80211_stop_queue(hw, i,
+                       IEEE80211_QUEUE_STOP_REASON_SKB_ADD);
+
+       while ((skb = skb_dequeue(skbs))) {
+               ret++;
+               queue = skb_get_queue_mapping(skb);
+               skb_queue_tail(&local->pending[queue], skb);
+       }
+
+       for (i = 0; i < hw->queues; i++) {
+               if (ret)
+                       __ieee80211_stop_queue(hw, i,
+                               IEEE80211_QUEUE_STOP_REASON_PENDING);
+               __ieee80211_wake_queue(hw, i,
+                       IEEE80211_QUEUE_STOP_REASON_SKB_ADD);
+       }
+       spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
+
+       return ret;
+}
+
 void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw,
                                    enum queue_stop_reason reason)
 {
@@ -535,9 +511,17 @@ EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_atomic);
 
 void ieee802_11_parse_elems(u8 *start, size_t len,
                            struct ieee802_11_elems *elems)
+{
+       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;
@@ -551,7 +535,10 @@ void ieee802_11_parse_elems(u8 *start, size_t len,
                left -= 2;
 
                if (elen > left)
-                       return;
+                       break;
+
+               if (calc_crc && id < 64 && (filter & BIT(id)))
+                       crc = crc32_be(crc, pos - 2, elen + 2);
 
                switch (id) {
                case WLAN_EID_SSID:
@@ -575,8 +562,10 @@ void ieee802_11_parse_elems(u8 *start, size_t len,
                        elems->cf_params_len = elen;
                        break;
                case WLAN_EID_TIM:
-                       elems->tim = pos;
-                       elems->tim_len = elen;
+                       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;
@@ -586,15 +575,20 @@ void ieee802_11_parse_elems(u8 *start, size_t len,
                        elems->challenge = pos;
                        elems->challenge_len = elen;
                        break;
-               case WLAN_EID_WPA:
+               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;
@@ -679,32 +673,70 @@ void ieee802_11_parse_elems(u8 *start, size_t len,
                left -= elen;
                pos += elen;
        }
+
+       return crc;
 }
 
 void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata)
 {
        struct ieee80211_local *local = sdata->local;
        struct ieee80211_tx_queue_params qparam;
-       int i;
+       int queue;
+       bool use_11b;
+       int aCWmin, aCWmax;
 
        if (!local->ops->conf_tx)
                return;
 
        memset(&qparam, 0, sizeof(qparam));
 
-       qparam.aifs = 2;
+       use_11b = (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ) &&
+                !(sdata->flags & IEEE80211_SDATA_OPERATING_GMODE);
 
-       if (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ &&
-           !(sdata->flags & IEEE80211_SDATA_OPERATING_GMODE))
-               qparam.cw_min = 31;
-       else
-               qparam.cw_min = 15;
-
-       qparam.cw_max = 1023;
-       qparam.txop = 0;
+       for (queue = 0; queue < local_to_hw(local)->queues; queue++) {
+               /* Set defaults according to 802.11-2007 Table 7-37 */
+               aCWmax = 1023;
+               if (use_11b)
+                       aCWmin = 31;
+               else
+                       aCWmin = 15;
+
+               switch (queue) {
+               case 3: /* AC_BK */
+                       qparam.cw_max = aCWmax;
+                       qparam.cw_min = aCWmin;
+                       qparam.txop = 0;
+                       qparam.aifs = 7;
+                       break;
+               default: /* never happens but let's not leave undefined */
+               case 2: /* AC_BE */
+                       qparam.cw_max = aCWmax;
+                       qparam.cw_min = aCWmin;
+                       qparam.txop = 0;
+                       qparam.aifs = 3;
+                       break;
+               case 1: /* AC_VI */
+                       qparam.cw_max = aCWmin;
+                       qparam.cw_min = (aCWmin + 1) / 2 - 1;
+                       if (use_11b)
+                               qparam.txop = 6016/32;
+                       else
+                               qparam.txop = 3008/32;
+                       qparam.aifs = 2;
+                       break;
+               case 0: /* AC_VO */
+                       qparam.cw_max = (aCWmin + 1) / 2 - 1;
+                       qparam.cw_min = (aCWmin + 1) / 4 - 1;
+                       if (use_11b)
+                               qparam.txop = 3264/32;
+                       else
+                               qparam.txop = 1504/32;
+                       qparam.aifs = 2;
+                       break;
+               }
 
-       for (i = 0; i < local_to_hw(local)->queues; i++)
-               local->ops->conf_tx(local_to_hw(local), i, &qparam);
+               drv_conf_tx(local, queue, &qparam);
+       }
 }
 
 void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata,
@@ -831,16 +863,73 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
        ieee80211_tx_skb(sdata, skb, encrypt);
 }
 
+int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
+                            const u8 *ie, size_t ie_len)
+{
+       struct ieee80211_supported_band *sband;
+       u8 *pos, *supp_rates_len, *esupp_rates_len = NULL;
+       int i;
+
+       sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
+
+       pos = buffer;
+
+       *pos++ = WLAN_EID_SUPP_RATES;
+       supp_rates_len = pos;
+       *pos++ = 0;
+
+       for (i = 0; i < sband->n_bitrates; i++) {
+               struct ieee80211_rate *rate = &sband->bitrates[i];
+
+               if (esupp_rates_len) {
+                       *esupp_rates_len += 1;
+               } else if (*supp_rates_len == 8) {
+                       *pos++ = WLAN_EID_EXT_SUPP_RATES;
+                       esupp_rates_len = pos;
+                       *pos++ = 1;
+               } else
+                       *supp_rates_len += 1;
+
+               *pos++ = rate->bitrate / 5;
+       }
+
+       if (sband->ht_cap.ht_supported) {
+               __le16 tmp = cpu_to_le16(sband->ht_cap.cap);
+
+               *pos++ = WLAN_EID_HT_CAPABILITY;
+               *pos++ = sizeof(struct ieee80211_ht_cap);
+               memset(pos, 0, sizeof(struct ieee80211_ht_cap));
+               memcpy(pos, &tmp, sizeof(u16));
+               pos += sizeof(u16);
+               /* TODO: needs a define here for << 2 */
+               *pos++ = sband->ht_cap.ampdu_factor |
+                        (sband->ht_cap.ampdu_density << 2);
+               memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs));
+               pos += sizeof(sband->ht_cap.mcs);
+               pos += 2 + 4 + 1; /* ext info, BF cap, antsel */
+       }
+
+       /*
+        * If adding more here, adjust code in main.c
+        * that calculates local->scan_ies_len.
+        */
+
+       if (ie) {
+               memcpy(pos, ie, ie_len);
+               pos += ie_len;
+       }
+
+       return pos - buffer;
+}
+
 void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
-                             u8 *ssid, size_t ssid_len,
-                             u8 *ie, size_t ie_len)
+                             const u8 *ssid, size_t ssid_len,
+                             const u8 *ie, size_t ie_len)
 {
        struct ieee80211_local *local = sdata->local;
-       struct ieee80211_supported_band *sband;
        struct sk_buff *skb;
        struct ieee80211_mgmt *mgmt;
-       u8 *pos, *supp_rates, *esupp_rates = NULL;
-       int i;
+       u8 *pos;
 
        skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*mgmt) + 200 +
                            ie_len);
@@ -867,31 +956,9 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
        *pos++ = WLAN_EID_SSID;
        *pos++ = ssid_len;
        memcpy(pos, ssid, ssid_len);
+       pos += ssid_len;
 
-       supp_rates = skb_put(skb, 2);
-       supp_rates[0] = WLAN_EID_SUPP_RATES;
-       supp_rates[1] = 0;
-       sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
-
-       for (i = 0; i < sband->n_bitrates; i++) {
-               struct ieee80211_rate *rate = &sband->bitrates[i];
-               if (esupp_rates) {
-                       pos = skb_put(skb, 1);
-                       esupp_rates[1]++;
-               } else if (supp_rates[1] == 8) {
-                       esupp_rates = skb_put(skb, 3);
-                       esupp_rates[0] = WLAN_EID_EXT_SUPP_RATES;
-                       esupp_rates[1] = 1;
-                       pos = &esupp_rates[2];
-               } else {
-                       pos = skb_put(skb, 1);
-                       supp_rates[1]++;
-               }
-               *pos = rate->bitrate / 5;
-       }
-
-       if (ie)
-               memcpy(skb_put(skb, ie_len), ie, ie_len);
+       skb_put(skb, ieee80211_build_preq_ies(local, pos, ie, ie_len));
 
        ieee80211_tx_skb(sdata, skb, 0);
 }
@@ -931,3 +998,151 @@ u32 ieee80211_sta_get_rates(struct ieee80211_local *local,
        }
        return supp_rates;
 }
+
+int ieee80211_reconfig(struct ieee80211_local *local)
+{
+       struct ieee80211_hw *hw = &local->hw;
+       struct ieee80211_sub_if_data *sdata;
+       struct ieee80211_if_init_conf conf;
+       struct sta_info *sta;
+       unsigned long flags;
+       int res;
+       bool from_suspend = local->suspended;
+
+       /*
+        * We're going to start the hardware, at that point
+        * we are no longer suspended and can RX frames.
+        */
+       local->suspended = false;
+
+       /* restart hardware */
+       if (local->open_count) {
+               res = drv_start(local);
+
+               ieee80211_led_radio(local, true);
+       }
+
+       /* add interfaces */
+       list_for_each_entry(sdata, &local->interfaces, list) {
+               if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
+                   sdata->vif.type != NL80211_IFTYPE_MONITOR &&
+                   netif_running(sdata->dev)) {
+                       conf.vif = &sdata->vif;
+                       conf.type = sdata->vif.type;
+                       conf.mac_addr = sdata->dev->dev_addr;
+                       res = drv_add_interface(local, &conf);
+               }
+       }
+
+       /* add STAs back */
+       if (local->ops->sta_notify) {
+               spin_lock_irqsave(&local->sta_lock, flags);
+               list_for_each_entry(sta, &local->sta_list, list) {
+                       sdata = sta->sdata;
+                       if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
+                               sdata = container_of(sdata->bss,
+                                            struct ieee80211_sub_if_data,
+                                            u.ap);
+
+                       drv_sta_notify(local, &sdata->vif, STA_NOTIFY_ADD,
+                                      &sta->sta);
+               }
+               spin_unlock_irqrestore(&local->sta_lock, flags);
+       }
+
+       /* Clear Suspend state so that ADDBA requests can be processed */
+
+       rcu_read_lock();
+
+       if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) {
+               list_for_each_entry_rcu(sta, &local->sta_list, list) {
+                       clear_sta_flags(sta, WLAN_STA_SUSPEND);
+               }
+       }
+
+       rcu_read_unlock();
+
+       /* setup RTS threshold */
+       drv_set_rts_threshold(local, hw->wiphy->rts_threshold);
+
+       /* reconfigure hardware */
+       ieee80211_hw_config(local, ~0);
+
+       netif_addr_lock_bh(local->mdev);
+       ieee80211_configure_filter(local);
+       netif_addr_unlock_bh(local->mdev);
+
+       /* Finally also reconfigure all the BSS information */
+       list_for_each_entry(sdata, &local->interfaces, list) {
+               u32 changed = ~0;
+               if (!netif_running(sdata->dev))
+                       continue;
+               switch (sdata->vif.type) {
+               case NL80211_IFTYPE_STATION:
+                       /* disable beacon change bits */
+                       changed &= ~(BSS_CHANGED_BEACON |
+                                    BSS_CHANGED_BEACON_ENABLED);
+                       /* fall through */
+               case NL80211_IFTYPE_ADHOC:
+               case NL80211_IFTYPE_AP:
+               case NL80211_IFTYPE_MESH_POINT:
+                       ieee80211_bss_info_change_notify(sdata, changed);
+                       break;
+               case NL80211_IFTYPE_WDS:
+                       break;
+               case NL80211_IFTYPE_AP_VLAN:
+               case NL80211_IFTYPE_MONITOR:
+                       /* ignore virtual */
+                       break;
+               case NL80211_IFTYPE_UNSPECIFIED:
+               case __NL80211_IFTYPE_AFTER_LAST:
+                       WARN_ON(1);
+                       break;
+               }
+       }
+
+       /* add back keys */
+       list_for_each_entry(sdata, &local->interfaces, list)
+               if (netif_running(sdata->dev))
+                       ieee80211_enable_keys(sdata);
+
+       ieee80211_wake_queues_by_reason(hw,
+                       IEEE80211_QUEUE_STOP_REASON_SUSPEND);
+
+       /*
+        * If this is for hw restart things are still running.
+        * We may want to change that later, however.
+        */
+       if (!from_suspend)
+               return 0;
+
+#ifdef CONFIG_PM
+       local->suspended = false;
+
+       list_for_each_entry(sdata, &local->interfaces, list) {
+               switch(sdata->vif.type) {
+               case NL80211_IFTYPE_STATION:
+                       ieee80211_sta_restart(sdata);
+                       break;
+               case NL80211_IFTYPE_ADHOC:
+                       ieee80211_ibss_restart(sdata);
+                       break;
+               case NL80211_IFTYPE_MESH_POINT:
+                       ieee80211_mesh_restart(sdata);
+                       break;
+               default:
+                       break;
+               }
+       }
+
+       add_timer(&local->sta_cleanup);
+
+       spin_lock_irqsave(&local->sta_lock, flags);
+       list_for_each_entry(sta, &local->sta_list, list)
+               mesh_plink_restart(sta);
+       spin_unlock_irqrestore(&local->sta_lock, flags);
+#else
+       WARN_ON(1);
+#endif
+       return 0;
+}
index 959aa8379ccf957a7196283df3c3d98f6aa79bbf..d2d81b103341472613d8dabe14c3fda20c21c01b 100644 (file)
 #include "aes_ccm.h"
 
 
-static int ieee80211_set_encryption(struct ieee80211_sub_if_data *sdata, u8 *sta_addr,
-                                   int idx, int alg, int remove,
-                                   int set_tx_key, const u8 *_key,
-                                   size_t key_len)
-{
-       struct ieee80211_local *local = sdata->local;
-       struct sta_info *sta;
-       struct ieee80211_key *key;
-       int err;
-
-       if (alg == ALG_AES_CMAC) {
-               if (idx < NUM_DEFAULT_KEYS ||
-                   idx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS) {
-                       printk(KERN_DEBUG "%s: set_encrypt - invalid idx=%d "
-                              "(BIP)\n", sdata->dev->name, idx);
-                       return -EINVAL;
-               }
-       } else if (idx < 0 || idx >= NUM_DEFAULT_KEYS) {
-               printk(KERN_DEBUG "%s: set_encrypt - invalid idx=%d\n",
-                      sdata->dev->name, idx);
-               return -EINVAL;
-       }
-
-       if (remove) {
-               rcu_read_lock();
-
-               err = 0;
-
-               if (is_broadcast_ether_addr(sta_addr)) {
-                       key = sdata->keys[idx];
-               } else {
-                       sta = sta_info_get(local, sta_addr);
-                       if (!sta) {
-                               err = -ENOENT;
-                               goto out_unlock;
-                       }
-                       key = sta->key;
-               }
-
-               ieee80211_key_free(key);
-       } else {
-               key = ieee80211_key_alloc(alg, idx, key_len, _key);
-               if (!key)
-                       return -ENOMEM;
-
-               sta = NULL;
-               err = 0;
-
-               rcu_read_lock();
-
-               if (!is_broadcast_ether_addr(sta_addr)) {
-                       set_tx_key = 0;
-                       /*
-                        * According to the standard, the key index of a
-                        * pairwise key must be zero. However, some AP are
-                        * broken when it comes to WEP key indices, so we
-                        * work around this.
-                        */
-                       if (idx != 0 && alg != ALG_WEP) {
-                               ieee80211_key_free(key);
-                               err = -EINVAL;
-                               goto out_unlock;
-                       }
-
-                       sta = sta_info_get(local, sta_addr);
-                       if (!sta) {
-                               ieee80211_key_free(key);
-                               err = -ENOENT;
-                               goto out_unlock;
-                       }
-               }
-
-               if (alg == ALG_WEP &&
-                       key_len != LEN_WEP40 && key_len != LEN_WEP104) {
-                       ieee80211_key_free(key);
-                       err = -EINVAL;
-                       goto out_unlock;
-               }
-
-               ieee80211_key_link(key, sdata, sta);
-
-               if (set_tx_key || (!sta && !sdata->default_key && key))
-                       ieee80211_set_default_key(sdata, idx);
-               if (alg == ALG_AES_CMAC &&
-                   (set_tx_key || (!sta && !sdata->default_mgmt_key && key)))
-                       ieee80211_set_default_mgmt_key(sdata, idx);
-       }
-
- out_unlock:
-       rcu_read_unlock();
-
-       return err;
-}
-
 static int ieee80211_ioctl_siwgenie(struct net_device *dev,
                                    struct iw_request_info *info,
                                    struct iw_point *data, char *extra)
@@ -131,11 +37,13 @@ static int ieee80211_ioctl_siwgenie(struct net_device *dev,
 
        if (sdata->vif.type == NL80211_IFTYPE_STATION) {
                int ret = ieee80211_sta_set_extra_ie(sdata, extra, data->length);
-               if (ret)
+               if (ret && ret != -EALREADY)
                        return ret;
                sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_BSSID_SEL;
                sdata->u.mgd.flags &= ~IEEE80211_STA_EXT_SME;
-               ieee80211_sta_req_auth(sdata);
+               sdata->u.mgd.flags &= ~IEEE80211_STA_CONTROL_PORT;
+               if (ret != -EALREADY)
+                       ieee80211_sta_req_auth(sdata);
                return 0;
        }
 
@@ -149,17 +57,14 @@ static int ieee80211_ioctl_siwfreq(struct net_device *dev,
        struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 
        if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
-               sdata->u.ibss.flags &= ~IEEE80211_IBSS_AUTO_CHANNEL_SEL;
+               return cfg80211_ibss_wext_siwfreq(dev, info, freq, extra);
        else if (sdata->vif.type == NL80211_IFTYPE_STATION)
                sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_CHANNEL_SEL;
 
        /* freq->e == 0: freq->m = channel; otherwise freq = m * 10^e */
        if (freq->e == 0) {
                if (freq->m < 0) {
-                       if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
-                               sdata->u.ibss.flags |=
-                                       IEEE80211_IBSS_AUTO_CHANNEL_SEL;
-                       else if (sdata->vif.type == NL80211_IFTYPE_STATION)
+                       if (sdata->vif.type == NL80211_IFTYPE_STATION)
                                sdata->u.mgd.flags |=
                                        IEEE80211_STA_AUTO_CHANNEL_SEL;
                        return 0;
@@ -183,8 +88,12 @@ static int ieee80211_ioctl_giwfreq(struct net_device *dev,
                                   struct iw_freq *freq, char *extra)
 {
        struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
+       struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 
-       freq->m = local->hw.conf.channel->center_freq;
+       if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
+               return cfg80211_ibss_wext_giwfreq(dev, info, freq, extra);
+
+       freq->m = local->oper_channel->center_freq;
        freq->e = 6;
 
        return 0;
@@ -195,15 +104,17 @@ static int ieee80211_ioctl_siwessid(struct net_device *dev,
                                    struct iw_request_info *info,
                                    struct iw_point *data, char *ssid)
 {
-       struct ieee80211_sub_if_data *sdata;
+       struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
        size_t len = data->length;
        int ret;
 
+       if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
+               return cfg80211_ibss_wext_siwessid(dev, info, data, ssid);
+
        /* iwconfig uses nul termination in SSID.. */
        if (len > 0 && ssid[len - 1] == '\0')
                len--;
 
-       sdata = IEEE80211_DEV_TO_SUB_IF(dev);
        if (sdata->vif.type == NL80211_IFTYPE_STATION) {
                if (data->flags)
                        sdata->u.mgd.flags &= ~IEEE80211_STA_AUTO_SSID_SEL;
@@ -215,10 +126,10 @@ static int ieee80211_ioctl_siwessid(struct net_device *dev,
                        return ret;
 
                sdata->u.mgd.flags &= ~IEEE80211_STA_EXT_SME;
+               sdata->u.mgd.flags &= ~IEEE80211_STA_CONTROL_PORT;
                ieee80211_sta_req_auth(sdata);
                return 0;
-       } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
-               return ieee80211_ibss_set_ssid(sdata, ssid, len);
+       }
 
        return -EOPNOTSUPP;
 }
@@ -229,9 +140,13 @@ static int ieee80211_ioctl_giwessid(struct net_device *dev,
                                    struct iw_point *data, char *ssid)
 {
        size_t len;
-
        struct ieee80211_sub_if_data *sdata;
+
        sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+
+       if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
+               return cfg80211_ibss_wext_giwessid(dev, info, data, ssid);
+
        if (sdata->vif.type == NL80211_IFTYPE_STATION) {
                int res = ieee80211_sta_get_ssid(sdata, ssid, &len);
                if (res == 0) {
@@ -240,14 +155,6 @@ static int ieee80211_ioctl_giwessid(struct net_device *dev,
                } else
                        data->flags = 0;
                return res;
-       } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
-               int res = ieee80211_ibss_get_ssid(sdata, ssid, &len);
-               if (res == 0) {
-                       data->length = len;
-                       data->flags = 1;
-               } else
-                       data->flags = 0;
-               return res;
        }
 
        return -EOPNOTSUPP;
@@ -258,9 +165,11 @@ static int ieee80211_ioctl_siwap(struct net_device *dev,
                                 struct iw_request_info *info,
                                 struct sockaddr *ap_addr, char *extra)
 {
-       struct ieee80211_sub_if_data *sdata;
+       struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+
+       if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
+               return cfg80211_ibss_wext_siwap(dev, info, ap_addr, extra);
 
-       sdata = IEEE80211_DEV_TO_SUB_IF(dev);
        if (sdata->vif.type == NL80211_IFTYPE_STATION) {
                int ret;
 
@@ -275,18 +184,9 @@ static int ieee80211_ioctl_siwap(struct net_device *dev,
                if (ret)
                        return ret;
                sdata->u.mgd.flags &= ~IEEE80211_STA_EXT_SME;
+               sdata->u.mgd.flags &= ~IEEE80211_STA_CONTROL_PORT;
                ieee80211_sta_req_auth(sdata);
                return 0;
-       } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
-               if (is_zero_ether_addr((u8 *) &ap_addr->sa_data))
-                       sdata->u.ibss.flags |= IEEE80211_IBSS_AUTO_BSSID_SEL |
-                                              IEEE80211_IBSS_AUTO_CHANNEL_SEL;
-               else if (is_broadcast_ether_addr((u8 *) &ap_addr->sa_data))
-                       sdata->u.ibss.flags |= IEEE80211_IBSS_AUTO_BSSID_SEL;
-               else
-                       sdata->u.ibss.flags &= ~IEEE80211_IBSS_AUTO_BSSID_SEL;
-
-               return ieee80211_ibss_set_bssid(sdata, (u8 *) &ap_addr->sa_data);
        } else if (sdata->vif.type == NL80211_IFTYPE_WDS) {
                /*
                 * If it is necessary to update the WDS peer address
@@ -312,9 +212,11 @@ static int ieee80211_ioctl_giwap(struct net_device *dev,
                                 struct iw_request_info *info,
                                 struct sockaddr *ap_addr, char *extra)
 {
-       struct ieee80211_sub_if_data *sdata;
+       struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+
+       if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
+               return cfg80211_ibss_wext_giwap(dev, info, ap_addr, extra);
 
-       sdata = IEEE80211_DEV_TO_SUB_IF(dev);
        if (sdata->vif.type == NL80211_IFTYPE_STATION) {
                if (sdata->u.mgd.state == IEEE80211_STA_MLME_ASSOCIATED) {
                        ap_addr->sa_family = ARPHRD_ETHER;
@@ -322,13 +224,6 @@ static int ieee80211_ioctl_giwap(struct net_device *dev,
                } else
                        memset(&ap_addr->sa_data, 0, ETH_ALEN);
                return 0;
-       } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
-               if (sdata->u.ibss.state == IEEE80211_IBSS_MLME_JOINED) {
-                       ap_addr->sa_family = ARPHRD_ETHER;
-                       memcpy(&ap_addr->sa_data, sdata->u.ibss.bssid, ETH_ALEN);
-               } else
-                       memset(&ap_addr->sa_data, 0, ETH_ALEN);
-               return 0;
        } else if (sdata->vif.type == NL80211_IFTYPE_WDS) {
                ap_addr->sa_family = ARPHRD_ETHER;
                memcpy(&ap_addr->sa_data, sdata->u.wds.remote_addr, ETH_ALEN);
@@ -411,334 +306,6 @@ static int ieee80211_ioctl_giwrate(struct net_device *dev,
        return 0;
 }
 
-static int ieee80211_ioctl_siwtxpower(struct net_device *dev,
-                                     struct iw_request_info *info,
-                                     union iwreq_data *data, char *extra)
-{
-       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
-       struct ieee80211_channel* chan = local->hw.conf.channel;
-       bool reconf = false;
-       u32 reconf_flags = 0;
-       int new_power_level;
-
-       if ((data->txpower.flags & IW_TXPOW_TYPE) != IW_TXPOW_DBM)
-               return -EINVAL;
-       if (data->txpower.flags & IW_TXPOW_RANGE)
-               return -EINVAL;
-       if (!chan)
-               return -EINVAL;
-
-       /* only change when not disabling */
-       if (!data->txpower.disabled) {
-               if (data->txpower.fixed) {
-                       if (data->txpower.value < 0)
-                               return -EINVAL;
-                       new_power_level = data->txpower.value;
-                       /*
-                        * Debatable, but we cannot do a fixed power
-                        * level above the regulatory constraint.
-                        * Use "iwconfig wlan0 txpower 15dBm" instead.
-                        */
-                       if (new_power_level > chan->max_power)
-                               return -EINVAL;
-               } else {
-                       /*
-                        * Automatic power level setting, max being the value
-                        * passed in from userland.
-                        */
-                       if (data->txpower.value < 0)
-                               new_power_level = -1;
-                       else
-                               new_power_level = data->txpower.value;
-               }
-
-               reconf = true;
-
-               /*
-                * ieee80211_hw_config() will limit to the channel's
-                * max power and possibly power constraint from AP.
-                */
-               local->user_power_level = new_power_level;
-       }
-
-       if (local->hw.conf.radio_enabled != !(data->txpower.disabled)) {
-               local->hw.conf.radio_enabled = !(data->txpower.disabled);
-               reconf_flags |= IEEE80211_CONF_CHANGE_RADIO_ENABLED;
-               ieee80211_led_radio(local, local->hw.conf.radio_enabled);
-       }
-
-       if (reconf || reconf_flags)
-               ieee80211_hw_config(local, reconf_flags);
-
-       return 0;
-}
-
-static int ieee80211_ioctl_giwtxpower(struct net_device *dev,
-                                  struct iw_request_info *info,
-                                  union iwreq_data *data, char *extra)
-{
-       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
-
-       data->txpower.fixed = 1;
-       data->txpower.disabled = !(local->hw.conf.radio_enabled);
-       data->txpower.value = local->hw.conf.power_level;
-       data->txpower.flags = IW_TXPOW_DBM;
-
-       return 0;
-}
-
-static int ieee80211_ioctl_siwrts(struct net_device *dev,
-                                 struct iw_request_info *info,
-                                 struct iw_param *rts, char *extra)
-{
-       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
-
-       if (rts->disabled)
-               local->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD;
-       else if (!rts->fixed)
-               /* if the rts value is not fixed, then take default */
-               local->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD;
-       else if (rts->value < 0 || rts->value > IEEE80211_MAX_RTS_THRESHOLD)
-               return -EINVAL;
-       else
-               local->rts_threshold = rts->value;
-
-       /* If the wlan card performs RTS/CTS in hardware/firmware,
-        * configure it here */
-
-       if (local->ops->set_rts_threshold)
-               local->ops->set_rts_threshold(local_to_hw(local),
-                                            local->rts_threshold);
-
-       return 0;
-}
-
-static int ieee80211_ioctl_giwrts(struct net_device *dev,
-                                 struct iw_request_info *info,
-                                 struct iw_param *rts, char *extra)
-{
-       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
-
-       rts->value = local->rts_threshold;
-       rts->disabled = (rts->value >= IEEE80211_MAX_RTS_THRESHOLD);
-       rts->fixed = 1;
-
-       return 0;
-}
-
-
-static int ieee80211_ioctl_siwfrag(struct net_device *dev,
-                                  struct iw_request_info *info,
-                                  struct iw_param *frag, char *extra)
-{
-       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
-
-       if (frag->disabled)
-               local->fragmentation_threshold = IEEE80211_MAX_FRAG_THRESHOLD;
-       else if (!frag->fixed)
-               local->fragmentation_threshold = IEEE80211_MAX_FRAG_THRESHOLD;
-       else if (frag->value < 256 ||
-                frag->value > IEEE80211_MAX_FRAG_THRESHOLD)
-               return -EINVAL;
-       else {
-               /* Fragment length must be even, so strip LSB. */
-               local->fragmentation_threshold = frag->value & ~0x1;
-       }
-
-       return 0;
-}
-
-static int ieee80211_ioctl_giwfrag(struct net_device *dev,
-                                  struct iw_request_info *info,
-                                  struct iw_param *frag, char *extra)
-{
-       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
-
-       frag->value = local->fragmentation_threshold;
-       frag->disabled = (frag->value >= IEEE80211_MAX_FRAG_THRESHOLD);
-       frag->fixed = 1;
-
-       return 0;
-}
-
-
-static int ieee80211_ioctl_siwretry(struct net_device *dev,
-                                   struct iw_request_info *info,
-                                   struct iw_param *retry, char *extra)
-{
-       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
-
-       if (retry->disabled ||
-           (retry->flags & IW_RETRY_TYPE) != IW_RETRY_LIMIT)
-               return -EINVAL;
-
-       if (retry->flags & IW_RETRY_MAX) {
-               local->hw.conf.long_frame_max_tx_count = retry->value;
-       } else if (retry->flags & IW_RETRY_MIN) {
-               local->hw.conf.short_frame_max_tx_count = retry->value;
-       } else {
-               local->hw.conf.long_frame_max_tx_count = retry->value;
-               local->hw.conf.short_frame_max_tx_count = retry->value;
-       }
-
-       ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_RETRY_LIMITS);
-
-       return 0;
-}
-
-
-static int ieee80211_ioctl_giwretry(struct net_device *dev,
-                                   struct iw_request_info *info,
-                                   struct iw_param *retry, char *extra)
-{
-       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
-
-       retry->disabled = 0;
-       if (retry->flags == 0 || retry->flags & IW_RETRY_MIN) {
-               /* first return min value, iwconfig will ask max value
-                * later if needed */
-               retry->flags |= IW_RETRY_LIMIT;
-               retry->value = local->hw.conf.short_frame_max_tx_count;
-               if (local->hw.conf.long_frame_max_tx_count !=
-                   local->hw.conf.short_frame_max_tx_count)
-                       retry->flags |= IW_RETRY_MIN;
-               return 0;
-       }
-       if (retry->flags & IW_RETRY_MAX) {
-               retry->flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
-               retry->value = local->hw.conf.long_frame_max_tx_count;
-       }
-
-       return 0;
-}
-
-static int ieee80211_ioctl_siwmlme(struct net_device *dev,
-                                  struct iw_request_info *info,
-                                  struct iw_point *data, char *extra)
-{
-       struct ieee80211_sub_if_data *sdata;
-       struct iw_mlme *mlme = (struct iw_mlme *) extra;
-
-       sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-       if (!(sdata->vif.type == NL80211_IFTYPE_STATION))
-               return -EINVAL;
-
-       switch (mlme->cmd) {
-       case IW_MLME_DEAUTH:
-               /* TODO: mlme->addr.sa_data */
-               return ieee80211_sta_deauthenticate(sdata, mlme->reason_code);
-       case IW_MLME_DISASSOC:
-               /* TODO: mlme->addr.sa_data */
-               return ieee80211_sta_disassociate(sdata, mlme->reason_code);
-       default:
-               return -EOPNOTSUPP;
-       }
-}
-
-
-static int ieee80211_ioctl_siwencode(struct net_device *dev,
-                                    struct iw_request_info *info,
-                                    struct iw_point *erq, char *keybuf)
-{
-       struct ieee80211_sub_if_data *sdata;
-       int idx, i, alg = ALG_WEP;
-       u8 bcaddr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
-       int remove = 0, ret;
-
-       sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-
-       idx = erq->flags & IW_ENCODE_INDEX;
-       if (idx == 0) {
-               if (sdata->default_key)
-                       for (i = 0; i < NUM_DEFAULT_KEYS; i++) {
-                               if (sdata->default_key == sdata->keys[i]) {
-                                       idx = i;
-                                       break;
-                               }
-                       }
-       } else if (idx < 1 || idx > 4)
-               return -EINVAL;
-       else
-               idx--;
-
-       if (erq->flags & IW_ENCODE_DISABLED)
-               remove = 1;
-       else if (erq->length == 0) {
-               /* No key data - just set the default TX key index */
-               ieee80211_set_default_key(sdata, idx);
-               return 0;
-       }
-
-       ret = ieee80211_set_encryption(
-               sdata, bcaddr,
-               idx, alg, remove,
-               !sdata->default_key,
-               keybuf, erq->length);
-
-       if (!ret) {
-               if (remove)
-                       sdata->u.mgd.flags &= ~IEEE80211_STA_TKIP_WEP_USED;
-               else
-                       sdata->u.mgd.flags |= IEEE80211_STA_TKIP_WEP_USED;
-       }
-
-       return ret;
-}
-
-
-static int ieee80211_ioctl_giwencode(struct net_device *dev,
-                                    struct iw_request_info *info,
-                                    struct iw_point *erq, char *key)
-{
-       struct ieee80211_sub_if_data *sdata;
-       int idx, i;
-
-       sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-
-       idx = erq->flags & IW_ENCODE_INDEX;
-       if (idx < 1 || idx > 4) {
-               idx = -1;
-               if (!sdata->default_key)
-                       idx = 0;
-               else for (i = 0; i < NUM_DEFAULT_KEYS; i++) {
-                       if (sdata->default_key == sdata->keys[i]) {
-                               idx = i;
-                               break;
-                       }
-               }
-               if (idx < 0)
-                       return -EINVAL;
-       } else
-               idx--;
-
-       erq->flags = idx + 1;
-
-       if (!sdata->keys[idx]) {
-               erq->length = 0;
-               erq->flags |= IW_ENCODE_DISABLED;
-               return 0;
-       }
-
-       memcpy(key, sdata->keys[idx]->conf.key,
-              min_t(int, erq->length, sdata->keys[idx]->conf.keylen));
-       erq->length = sdata->keys[idx]->conf.keylen;
-       erq->flags |= IW_ENCODE_ENABLED;
-
-       if (sdata->vif.type == NL80211_IFTYPE_STATION) {
-               switch (sdata->u.mgd.auth_alg) {
-               case WLAN_AUTH_OPEN:
-               case WLAN_AUTH_LEAP:
-                       erq->flags |= IW_ENCODE_OPEN;
-                       break;
-               case WLAN_AUTH_SHARED_KEY:
-                       erq->flags |= IW_ENCODE_RESTRICTED;
-                       break;
-               }
-       }
-
-       return 0;
-}
-
 static int ieee80211_ioctl_siwpower(struct net_device *dev,
                                    struct iw_request_info *info,
                                    struct iw_param *wrq,
@@ -747,7 +314,7 @@ static int ieee80211_ioctl_siwpower(struct net_device *dev,
        struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
        struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
        struct ieee80211_conf *conf = &local->hw.conf;
-       int ret = 0, timeout = 0;
+       int timeout = 0;
        bool ps;
 
        if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_PS))
@@ -779,42 +346,18 @@ static int ieee80211_ioctl_siwpower(struct net_device *dev,
                timeout = wrq->value / 1000;
 
  set:
-       if (ps == local->powersave && timeout == conf->dynamic_ps_timeout)
-               return ret;
+       if (ps == sdata->u.mgd.powersave && timeout == conf->dynamic_ps_timeout)
+               return 0;
 
-       local->powersave = ps;
+       sdata->u.mgd.powersave = ps;
        conf->dynamic_ps_timeout = timeout;
 
        if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS)
-               ret = ieee80211_hw_config(local,
-                                         IEEE80211_CONF_CHANGE_DYNPS_TIMEOUT);
-
-       if (!(sdata->u.mgd.flags & IEEE80211_STA_ASSOCIATED))
-               return ret;
+               ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
 
-       if (conf->dynamic_ps_timeout > 0 &&
-           !(local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS)) {
-               mod_timer(&local->dynamic_ps_timer, jiffies +
-                         msecs_to_jiffies(conf->dynamic_ps_timeout));
-       } else {
-               if (local->powersave) {
-                       if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)
-                               ieee80211_send_nullfunc(local, sdata, 1);
-                       conf->flags |= IEEE80211_CONF_PS;
-                       ret = ieee80211_hw_config(local,
-                                       IEEE80211_CONF_CHANGE_PS);
-               } else {
-                       conf->flags &= ~IEEE80211_CONF_PS;
-                       ret = ieee80211_hw_config(local,
-                                       IEEE80211_CONF_CHANGE_PS);
-                       if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)
-                               ieee80211_send_nullfunc(local, sdata, 0);
-                       del_timer_sync(&local->dynamic_ps_timer);
-                       cancel_work_sync(&local->dynamic_ps_enable_work);
-               }
-       }
+       ieee80211_recalc_ps(local, -1);
 
-       return ret;
+       return 0;
 }
 
 static int ieee80211_ioctl_giwpower(struct net_device *dev,
@@ -822,9 +365,9 @@ static int ieee80211_ioctl_giwpower(struct net_device *dev,
                                    union iwreq_data *wrqu,
                                    char *extra)
 {
-       struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
+       struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 
-       wrqu->power.disabled = !local->powersave;
+       wrqu->power.disabled = !sdata->u.mgd.powersave;
 
        return 0;
 }
@@ -997,82 +540,6 @@ static int ieee80211_ioctl_giwauth(struct net_device *dev,
 }
 
 
-static int ieee80211_ioctl_siwencodeext(struct net_device *dev,
-                                       struct iw_request_info *info,
-                                       struct iw_point *erq, char *extra)
-{
-       struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-       struct iw_encode_ext *ext = (struct iw_encode_ext *) extra;
-       int uninitialized_var(alg), idx, i, remove = 0;
-
-       switch (ext->alg) {
-       case IW_ENCODE_ALG_NONE:
-               remove = 1;
-               break;
-       case IW_ENCODE_ALG_WEP:
-               alg = ALG_WEP;
-               break;
-       case IW_ENCODE_ALG_TKIP:
-               alg = ALG_TKIP;
-               break;
-       case IW_ENCODE_ALG_CCMP:
-               alg = ALG_CCMP;
-               break;
-       case IW_ENCODE_ALG_AES_CMAC:
-               alg = ALG_AES_CMAC;
-               break;
-       default:
-               return -EOPNOTSUPP;
-       }
-
-       if (erq->flags & IW_ENCODE_DISABLED)
-               remove = 1;
-
-       idx = erq->flags & IW_ENCODE_INDEX;
-       if (alg == ALG_AES_CMAC) {
-               if (idx < NUM_DEFAULT_KEYS + 1 ||
-                   idx > NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS) {
-                       idx = -1;
-                       if (!sdata->default_mgmt_key)
-                               idx = 0;
-                       else for (i = NUM_DEFAULT_KEYS;
-                                 i < NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS;
-                                 i++) {
-                               if (sdata->default_mgmt_key == sdata->keys[i])
-                               {
-                                       idx = i;
-                                       break;
-                               }
-                       }
-                       if (idx < 0)
-                               return -EINVAL;
-               } else
-                       idx--;
-       } else {
-               if (idx < 1 || idx > 4) {
-                       idx = -1;
-                       if (!sdata->default_key)
-                               idx = 0;
-                       else for (i = 0; i < NUM_DEFAULT_KEYS; i++) {
-                               if (sdata->default_key == sdata->keys[i]) {
-                                       idx = i;
-                                       break;
-                               }
-                       }
-                       if (idx < 0)
-                               return -EINVAL;
-               } else
-                       idx--;
-       }
-
-       return ieee80211_set_encryption(sdata, ext->addr.sa_data, idx, alg,
-                                       remove,
-                                       ext->ext_flags &
-                                       IW_ENCODE_EXT_SET_TX_KEY,
-                                       ext->key, ext->key_len);
-}
-
-
 /* Structures to export the Wireless Handlers */
 
 static const iw_handler ieee80211_handler[] =
@@ -1099,7 +566,7 @@ static const iw_handler ieee80211_handler[] =
        (iw_handler) NULL,                              /* SIOCGIWTHRSPY */
        (iw_handler) ieee80211_ioctl_siwap,             /* SIOCSIWAP */
        (iw_handler) ieee80211_ioctl_giwap,             /* SIOCGIWAP */
-       (iw_handler) ieee80211_ioctl_siwmlme,           /* SIOCSIWMLME */
+       (iw_handler) cfg80211_wext_siwmlme,             /* SIOCSIWMLME */
        (iw_handler) NULL,                              /* SIOCGIWAPLIST */
        (iw_handler) cfg80211_wext_siwscan,             /* SIOCSIWSCAN */
        (iw_handler) cfg80211_wext_giwscan,             /* SIOCGIWSCAN */
@@ -1111,16 +578,16 @@ static const iw_handler ieee80211_handler[] =
        (iw_handler) NULL,                              /* -- hole -- */
        (iw_handler) ieee80211_ioctl_siwrate,           /* SIOCSIWRATE */
        (iw_handler) ieee80211_ioctl_giwrate,           /* SIOCGIWRATE */
-       (iw_handler) ieee80211_ioctl_siwrts,            /* SIOCSIWRTS */
-       (iw_handler) ieee80211_ioctl_giwrts,            /* SIOCGIWRTS */
-       (iw_handler) ieee80211_ioctl_siwfrag,           /* SIOCSIWFRAG */
-       (iw_handler) ieee80211_ioctl_giwfrag,           /* SIOCGIWFRAG */
-       (iw_handler) ieee80211_ioctl_siwtxpower,        /* SIOCSIWTXPOW */
-       (iw_handler) ieee80211_ioctl_giwtxpower,        /* SIOCGIWTXPOW */
-       (iw_handler) ieee80211_ioctl_siwretry,          /* SIOCSIWRETRY */
-       (iw_handler) ieee80211_ioctl_giwretry,          /* SIOCGIWRETRY */
-       (iw_handler) ieee80211_ioctl_siwencode,         /* SIOCSIWENCODE */
-       (iw_handler) ieee80211_ioctl_giwencode,         /* SIOCGIWENCODE */
+       (iw_handler) cfg80211_wext_siwrts,              /* SIOCSIWRTS */
+       (iw_handler) cfg80211_wext_giwrts,              /* SIOCGIWRTS */
+       (iw_handler) cfg80211_wext_siwfrag,             /* SIOCSIWFRAG */
+       (iw_handler) cfg80211_wext_giwfrag,             /* SIOCGIWFRAG */
+       (iw_handler) cfg80211_wext_siwtxpower,          /* SIOCSIWTXPOW */
+       (iw_handler) cfg80211_wext_giwtxpower,          /* SIOCGIWTXPOW */
+       (iw_handler) cfg80211_wext_siwretry,            /* SIOCSIWRETRY */
+       (iw_handler) cfg80211_wext_giwretry,            /* SIOCGIWRETRY */
+       (iw_handler) cfg80211_wext_siwencode,           /* SIOCSIWENCODE */
+       (iw_handler) cfg80211_wext_giwencode,           /* SIOCGIWENCODE */
        (iw_handler) ieee80211_ioctl_siwpower,          /* SIOCSIWPOWER */
        (iw_handler) ieee80211_ioctl_giwpower,          /* SIOCGIWPOWER */
        (iw_handler) NULL,                              /* -- hole -- */
@@ -1129,7 +596,7 @@ static const iw_handler ieee80211_handler[] =
        (iw_handler) NULL,                              /* SIOCGIWGENIE */
        (iw_handler) ieee80211_ioctl_siwauth,           /* SIOCSIWAUTH */
        (iw_handler) ieee80211_ioctl_giwauth,           /* SIOCGIWAUTH */
-       (iw_handler) ieee80211_ioctl_siwencodeext,      /* SIOCSIWENCODEEXT */
+       (iw_handler) cfg80211_wext_siwencodeext,        /* SIOCSIWENCODEEXT */
        (iw_handler) NULL,                              /* SIOCGIWENCODEEXT */
        (iw_handler) NULL,                              /* SIOCSIWPMKSA */
        (iw_handler) NULL,                              /* -- hole -- */
index 0b8ad1f4ecdd8dbb1f77532874c1c5d6f3a60d1a..116a923b14d621e1043b1cb07a5cecaf755039aa 100644 (file)
  */
 const int ieee802_1d_to_ac[8] = { 2, 3, 3, 2, 1, 1, 0, 0 };
 
-static const char llc_ip_hdr[8] = {0xAA, 0xAA, 0x3, 0, 0, 0, 0x08, 0};
-
-/* Given a data frame determine the 802.1p/1d tag to use.  */
-static unsigned int classify_1d(struct sk_buff *skb)
-{
-       unsigned int dscp;
-
-       /* skb->priority values from 256->263 are magic values to
-        * directly indicate a specific 802.1d priority.  This is used
-        * to allow 802.1d priority to be passed directly in from VLAN
-        * tags, etc.
-        */
-       if (skb->priority >= 256 && skb->priority <= 263)
-               return skb->priority - 256;
-
-       switch (skb->protocol) {
-       case htons(ETH_P_IP):
-               dscp = ip_hdr(skb)->tos & 0xfc;
-               break;
-
-       default:
-               return 0;
-       }
-
-       return dscp >> 5;
-}
-
-
 static int wme_downgrade_ac(struct sk_buff *skb)
 {
        switch (skb->priority) {
@@ -94,7 +66,7 @@ static u16 classify80211(struct ieee80211_local *local, struct sk_buff *skb)
 
        /* use the data classifier to determine what 802.1d tag the
         * data frame has */
-       skb->priority = classify_1d(skb);
+       skb->priority = cfg80211_classify8021d(skb);
 
        /* in case we are a client verify acm is not set for this ac */
        while (unlikely(local->wmm_acm & BIT(skb->priority))) {
@@ -129,11 +101,11 @@ u16 ieee80211_select_queue(struct net_device *dev, struct sk_buff *skb)
         * Now we know the 1d priority, fill in the QoS header if
         * there is one (and we haven't done this before).
         */
-       if (!skb->requeue && ieee80211_is_data_qos(hdr->frame_control)) {
+       if (ieee80211_is_data_qos(hdr->frame_control)) {
                u8 *p = ieee80211_get_qos_ctl(hdr);
                u8 ack_policy = 0;
                tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK;
-               if (local->wifi_wme_noack_test)
+               if (unlikely(local->wifi_wme_noack_test))
                        ack_policy |= QOS_CONTROL_ACK_POLICY_NOACK <<
                                        QOS_CONTROL_ACK_POLICY_SHIFT;
                /* qos header is 2 bytes, second reserved */
index 4f8bfea278f25b37ab6cc2a711744f57f368b3c0..dcfae8884b86955e9056952c541f93f3635673ad 100644 (file)
@@ -122,7 +122,7 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx)
                        return RX_DROP_UNUSABLE;
 
                mac80211_ev_michael_mic_failure(rx->sdata, rx->key->conf.keyidx,
-                                               (void *) skb->data);
+                                               (void *) skb->data, NULL);
                return RX_DROP_UNUSABLE;
        }
 
index c26a20c58dde1bbf256fc074a5bfb80c1ad7f2d9..634d14affc8d03684405b5b979952aa4d57c7f5d 100644 (file)
@@ -917,6 +917,19 @@ config NETFILTER_XT_MATCH_U32
 
          Details and examples are in the kernel module source.
 
+config NETFILTER_XT_MATCH_OSF
+       tristate '"osf" Passive OS fingerprint match'
+       depends on NETFILTER_ADVANCED && NETFILTER_NETLINK
+       help
+         This option selects the Passive OS Fingerprinting match module
+         that allows to passively match the remote operating system by
+         analyzing incoming TCP SYN packets.
+
+         Rules and loading software can be downloaded from
+         http://www.ioremap.net/projects/osf
+
+         To compile it as a module, choose M here.  If unsure, say N.
+
 endif # NETFILTER_XTABLES
 
 endmenu
index 6282060fbda91245a331cf8d283f22da2d1c5790..49f62ee4e9ffe2d96d9362bdd91c45fa9c193134 100644 (file)
@@ -77,6 +77,7 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_LIMIT) += xt_limit.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_MAC) += xt_mac.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_MARK) += xt_mark.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_MULTIPORT) += xt_multiport.o
+obj-$(CONFIG_NETFILTER_XT_MATCH_OSF) += xt_osf.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_OWNER) += xt_owner.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_PHYSDEV) += xt_physdev.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_PKTTYPE) += xt_pkttype.o
index e01061f49cdc644b0fe99d48457795458f55aa91..7c1333c67ff3d5f810540eea5f774fc6582030dd 100644 (file)
@@ -3345,22 +3345,8 @@ static struct genl_ops ip_vs_genl_ops[] __read_mostly = {
 
 static int __init ip_vs_genl_register(void)
 {
-       int ret, i;
-
-       ret = genl_register_family(&ip_vs_genl_family);
-       if (ret)
-               return ret;
-
-       for (i = 0; i < ARRAY_SIZE(ip_vs_genl_ops); i++) {
-               ret = genl_register_ops(&ip_vs_genl_family, &ip_vs_genl_ops[i]);
-               if (ret)
-                       goto err_out;
-       }
-       return 0;
-
-err_out:
-       genl_unregister_family(&ip_vs_genl_family);
-       return ret;
+       return genl_register_family_with_ops(&ip_vs_genl_family,
+               ip_vs_genl_ops, ARRAY_SIZE(ip_vs_genl_ops));
 }
 
 static void ip_vs_genl_unregister(void)
index 425ab144f15d4e29d90a9c6078d5221588b18fbb..5874657af7f20dfbf6f212d6bc1b38389eac7275 100644 (file)
@@ -260,8 +260,8 @@ ip_vs_bypass_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
        ip_send_check(ip_hdr(skb));
 
        /* drop old route */
-       dst_release(skb->dst);
-       skb->dst = &rt->u.dst;
+       skb_dst_drop(skb);
+       skb_dst_set(skb, &rt->u.dst);
 
        /* Another hack: avoid icmp_send in ip_fragment */
        skb->local_df = 1;
@@ -324,8 +324,8 @@ ip_vs_bypass_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
        }
 
        /* drop old route */
-       dst_release(skb->dst);
-       skb->dst = &rt->u.dst;
+       skb_dst_drop(skb);
+       skb_dst_set(skb, &rt->u.dst);
 
        /* Another hack: avoid icmp_send in ip_fragment */
        skb->local_df = 1;
@@ -388,8 +388,8 @@ ip_vs_nat_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
                goto tx_error_put;
 
        /* drop old route */
-       dst_release(skb->dst);
-       skb->dst = &rt->u.dst;
+       skb_dst_drop(skb);
+       skb_dst_set(skb, &rt->u.dst);
 
        /* mangle the packet */
        if (pp->dnat_handler && !pp->dnat_handler(skb, pp, cp))
@@ -465,8 +465,8 @@ ip_vs_nat_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
                goto tx_error_put;
 
        /* drop old route */
-       dst_release(skb->dst);
-       skb->dst = &rt->u.dst;
+       skb_dst_drop(skb);
+       skb_dst_set(skb, &rt->u.dst);
 
        /* mangle the packet */
        if (pp->dnat_handler && !pp->dnat_handler(skb, pp, cp))
@@ -553,8 +553,8 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
                IP_VS_DBG_RL("ip_vs_tunnel_xmit(): mtu less than 68\n");
                goto tx_error;
        }
-       if (skb->dst)
-               skb->dst->ops->update_pmtu(skb->dst, mtu);
+       if (skb_dst(skb))
+               skb_dst(skb)->ops->update_pmtu(skb_dst(skb), mtu);
 
        df |= (old_iph->frag_off & htons(IP_DF));
 
@@ -596,8 +596,8 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
        memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
 
        /* drop old route */
-       dst_release(skb->dst);
-       skb->dst = &rt->u.dst;
+       skb_dst_drop(skb);
+       skb_dst_set(skb, &rt->u.dst);
 
        /*
         *      Push down and install the IPIP header.
@@ -665,8 +665,8 @@ ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
                IP_VS_DBG_RL("ip_vs_tunnel_xmit_v6(): mtu less than 1280\n");
                goto tx_error;
        }
-       if (skb->dst)
-               skb->dst->ops->update_pmtu(skb->dst, mtu);
+       if (skb_dst(skb))
+               skb_dst(skb)->ops->update_pmtu(skb_dst(skb), mtu);
 
        if (mtu < ntohs(old_iph->payload_len) + sizeof(struct ipv6hdr)) {
                icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev);
@@ -702,8 +702,8 @@ ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
        memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
 
        /* drop old route */
-       dst_release(skb->dst);
-       skb->dst = &rt->u.dst;
+       skb_dst_drop(skb);
+       skb_dst_set(skb, &rt->u.dst);
 
        /*
         *      Push down and install the IPIP header.
@@ -775,8 +775,8 @@ ip_vs_dr_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
        ip_send_check(ip_hdr(skb));
 
        /* drop old route */
-       dst_release(skb->dst);
-       skb->dst = &rt->u.dst;
+       skb_dst_drop(skb);
+       skb_dst_set(skb, &rt->u.dst);
 
        /* Another hack: avoid icmp_send in ip_fragment */
        skb->local_df = 1;
@@ -828,8 +828,8 @@ ip_vs_dr_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
        }
 
        /* drop old route */
-       dst_release(skb->dst);
-       skb->dst = &rt->u.dst;
+       skb_dst_drop(skb);
+       skb_dst_set(skb, &rt->u.dst);
 
        /* Another hack: avoid icmp_send in ip_fragment */
        skb->local_df = 1;
@@ -900,8 +900,8 @@ ip_vs_icmp_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
                goto tx_error_put;
 
        /* drop the old route when skb is not shared */
-       dst_release(skb->dst);
-       skb->dst = &rt->u.dst;
+       skb_dst_drop(skb);
+       skb_dst_set(skb, &rt->u.dst);
 
        ip_vs_nat_icmp(skb, pp, cp, 0);
 
@@ -975,8 +975,8 @@ ip_vs_icmp_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
                goto tx_error_put;
 
        /* drop the old route when skb is not shared */
-       dst_release(skb->dst);
-       skb->dst = &rt->u.dst;
+       skb_dst_drop(skb);
+       skb_dst_set(skb, &rt->u.dst);
 
        ip_vs_nat_icmp_v6(skb, pp, cp, 0);
 
index 8020db6274b86471149533b40eecd89c496c24d5..5f72b94b4918745f3491b48ba06cbc1714890280 100644 (file)
@@ -39,6 +39,7 @@
 #include <net/netfilter/nf_conntrack_core.h>
 #include <net/netfilter/nf_conntrack_extend.h>
 #include <net/netfilter/nf_conntrack_acct.h>
+#include <net/netfilter/nf_conntrack_ecache.h>
 #include <net/netfilter/nf_nat.h>
 #include <net/netfilter/nf_nat_core.h>
 
@@ -182,10 +183,6 @@ destroy_conntrack(struct nf_conntrack *nfct)
        NF_CT_ASSERT(atomic_read(&nfct->use) == 0);
        NF_CT_ASSERT(!timer_pending(&ct->timeout));
 
-       if (!test_bit(IPS_DYING_BIT, &ct->status))
-               nf_conntrack_event(IPCT_DESTROY, ct);
-       set_bit(IPS_DYING_BIT, &ct->status);
-
        /* To make sure we don't get any weird locking issues here:
         * destroy_conntrack() MUST NOT be called with a write lock
         * to nf_conntrack_lock!!! -HW */
@@ -219,27 +216,70 @@ destroy_conntrack(struct nf_conntrack *nfct)
        nf_conntrack_free(ct);
 }
 
-static void death_by_timeout(unsigned long ul_conntrack)
+void nf_ct_delete_from_lists(struct nf_conn *ct)
 {
-       struct nf_conn *ct = (void *)ul_conntrack;
        struct net *net = nf_ct_net(ct);
-       struct nf_conn_help *help = nfct_help(ct);
-       struct nf_conntrack_helper *helper;
-
-       if (help) {
-               rcu_read_lock();
-               helper = rcu_dereference(help->helper);
-               if (helper && helper->destroy)
-                       helper->destroy(ct);
-               rcu_read_unlock();
-       }
 
+       nf_ct_helper_destroy(ct);
        spin_lock_bh(&nf_conntrack_lock);
        /* Inside lock so preempt is disabled on module removal path.
         * Otherwise we can get spurious warnings. */
        NF_CT_STAT_INC(net, delete_list);
        clean_from_lists(ct);
        spin_unlock_bh(&nf_conntrack_lock);
+}
+EXPORT_SYMBOL_GPL(nf_ct_delete_from_lists);
+
+static void death_by_event(unsigned long ul_conntrack)
+{
+       struct nf_conn *ct = (void *)ul_conntrack;
+       struct net *net = nf_ct_net(ct);
+
+       if (nf_conntrack_event(IPCT_DESTROY, ct) < 0) {
+               /* bad luck, let's retry again */
+               ct->timeout.expires = jiffies +
+                       (random32() % net->ct.sysctl_events_retry_timeout);
+               add_timer(&ct->timeout);
+               return;
+       }
+       /* we've got the event delivered, now it's dying */
+       set_bit(IPS_DYING_BIT, &ct->status);
+       spin_lock(&nf_conntrack_lock);
+       hlist_nulls_del(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnnode);
+       spin_unlock(&nf_conntrack_lock);
+       nf_ct_put(ct);
+}
+
+void nf_ct_insert_dying_list(struct nf_conn *ct)
+{
+       struct net *net = nf_ct_net(ct);
+
+       /* add this conntrack to the dying list */
+       spin_lock_bh(&nf_conntrack_lock);
+       hlist_nulls_add_head(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnnode,
+                            &net->ct.dying);
+       spin_unlock_bh(&nf_conntrack_lock);
+       /* set a new timer to retry event delivery */
+       setup_timer(&ct->timeout, death_by_event, (unsigned long)ct);
+       ct->timeout.expires = jiffies +
+               (random32() % net->ct.sysctl_events_retry_timeout);
+       add_timer(&ct->timeout);
+}
+EXPORT_SYMBOL_GPL(nf_ct_insert_dying_list);
+
+static void death_by_timeout(unsigned long ul_conntrack)
+{
+       struct nf_conn *ct = (void *)ul_conntrack;
+
+       if (!test_bit(IPS_DYING_BIT, &ct->status) &&
+           unlikely(nf_conntrack_event(IPCT_DESTROY, ct) < 0)) {
+               /* destroy event was not delivered */
+               nf_ct_delete_from_lists(ct);
+               nf_ct_insert_dying_list(ct);
+               return;
+       }
+       set_bit(IPS_DYING_BIT, &ct->status);
+       nf_ct_delete_from_lists(ct);
        nf_ct_put(ct);
 }
 
@@ -398,11 +438,7 @@ __nf_conntrack_confirm(struct sk_buff *skb)
        help = nfct_help(ct);
        if (help && help->helper)
                nf_conntrack_event_cache(IPCT_HELPER, ct);
-#ifdef CONFIG_NF_NAT_NEEDED
-       if (test_bit(IPS_SRC_NAT_DONE_BIT, &ct->status) ||
-           test_bit(IPS_DST_NAT_DONE_BIT, &ct->status))
-               nf_conntrack_event_cache(IPCT_NATINFO, ct);
-#endif
+
        nf_conntrack_event_cache(master_ct(ct) ?
                                 IPCT_RELATED : IPCT_NEW, ct);
        return NF_ACCEPT;
@@ -523,6 +559,7 @@ struct nf_conn *nf_conntrack_alloc(struct net *net,
                return ERR_PTR(-ENOMEM);
        }
 
+       spin_lock_init(&ct->lock);
        atomic_set(&ct->ct_general.use, 1);
        ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple = *orig;
        ct->tuplehash[IP_CT_DIR_REPLY].tuple = *repl;
@@ -580,6 +617,7 @@ init_conntrack(struct net *net,
        }
 
        nf_ct_acct_ext_add(ct, GFP_ATOMIC);
+       nf_ct_ecache_ext_add(ct, GFP_ATOMIC);
 
        spin_lock_bh(&nf_conntrack_lock);
        exp = nf_ct_find_expectation(net, tuple);
@@ -807,13 +845,9 @@ void __nf_ct_refresh_acct(struct nf_conn *ct,
                          unsigned long extra_jiffies,
                          int do_acct)
 {
-       int event = 0;
-
        NF_CT_ASSERT(ct->timeout.data == (unsigned long)ct);
        NF_CT_ASSERT(skb);
 
-       spin_lock_bh(&nf_conntrack_lock);
-
        /* Only update if this is not a fixed timeout */
        if (test_bit(IPS_FIXED_TIMEOUT_BIT, &ct->status))
                goto acct;
@@ -821,19 +855,14 @@ void __nf_ct_refresh_acct(struct nf_conn *ct,
        /* If not in hash table, timer will not be active yet */
        if (!nf_ct_is_confirmed(ct)) {
                ct->timeout.expires = extra_jiffies;
-               event = IPCT_REFRESH;
        } else {
                unsigned long newtime = jiffies + extra_jiffies;
 
                /* Only update the timeout if the new timeout is at least
                   HZ jiffies from the old timeout. Need del_timer for race
                   avoidance (may already be dying). */
-               if (newtime - ct->timeout.expires >= HZ
-                   && del_timer(&ct->timeout)) {
-                       ct->timeout.expires = newtime;
-                       add_timer(&ct->timeout);
-                       event = IPCT_REFRESH;
-               }
+               if (newtime - ct->timeout.expires >= HZ)
+                       mod_timer_pending(&ct->timeout, newtime);
        }
 
 acct:
@@ -842,17 +871,13 @@ acct:
 
                acct = nf_conn_acct_find(ct);
                if (acct) {
+                       spin_lock_bh(&ct->lock);
                        acct[CTINFO2DIR(ctinfo)].packets++;
                        acct[CTINFO2DIR(ctinfo)].bytes +=
                                skb->len - skb_network_offset(skb);
+                       spin_unlock_bh(&ct->lock);
                }
        }
-
-       spin_unlock_bh(&nf_conntrack_lock);
-
-       /* must be unlocked when calling event cache */
-       if (event)
-               nf_conntrack_event_cache(event, ct);
 }
 EXPORT_SYMBOL_GPL(__nf_ct_refresh_acct);
 
@@ -864,14 +889,14 @@ bool __nf_ct_kill_acct(struct nf_conn *ct,
        if (do_acct) {
                struct nf_conn_counter *acct;
 
-               spin_lock_bh(&nf_conntrack_lock);
                acct = nf_conn_acct_find(ct);
                if (acct) {
+                       spin_lock_bh(&ct->lock);
                        acct[CTINFO2DIR(ctinfo)].packets++;
                        acct[CTINFO2DIR(ctinfo)].bytes +=
                                skb->len - skb_network_offset(skb);
+                       spin_unlock_bh(&ct->lock);
                }
-               spin_unlock_bh(&nf_conntrack_lock);
        }
 
        if (del_timer(&ct->timeout)) {
@@ -1001,15 +1026,22 @@ struct __nf_ct_flush_report {
        int report;
 };
 
-static int kill_all(struct nf_conn *i, void *data)
+static int kill_report(struct nf_conn *i, void *data)
 {
        struct __nf_ct_flush_report *fr = (struct __nf_ct_flush_report *)data;
 
-       /* get_next_corpse sets the dying bit for us */
-       nf_conntrack_event_report(IPCT_DESTROY,
-                                 i,
-                                 fr->pid,
-                                 fr->report);
+       /* If we fail to deliver the event, death_by_timeout() will retry */
+       if (nf_conntrack_event_report(IPCT_DESTROY, i,
+                                     fr->pid, fr->report) < 0)
+               return 1;
+
+       /* Avoid the delivery of the destroy event in death_by_timeout(). */
+       set_bit(IPS_DYING_BIT, &i->status);
+       return 1;
+}
+
+static int kill_all(struct nf_conn *i, void *data)
+{
        return 1;
 }
 
@@ -1023,15 +1055,30 @@ void nf_ct_free_hashtable(void *hash, int vmalloced, unsigned int size)
 }
 EXPORT_SYMBOL_GPL(nf_ct_free_hashtable);
 
-void nf_conntrack_flush(struct net *net, u32 pid, int report)
+void nf_conntrack_flush_report(struct net *net, u32 pid, int report)
 {
        struct __nf_ct_flush_report fr = {
                .pid    = pid,
                .report = report,
        };
-       nf_ct_iterate_cleanup(net, kill_all, &fr);
+       nf_ct_iterate_cleanup(net, kill_report, &fr);
+}
+EXPORT_SYMBOL_GPL(nf_conntrack_flush_report);
+
+static void nf_ct_release_dying_list(void)
+{
+       struct nf_conntrack_tuple_hash *h;
+       struct nf_conn *ct;
+       struct hlist_nulls_node *n;
+
+       spin_lock_bh(&nf_conntrack_lock);
+       hlist_nulls_for_each_entry(h, n, &init_net.ct.dying, hnnode) {
+               ct = nf_ct_tuplehash_to_ctrack(h);
+               /* never fails to remove them, no listeners at this point */
+               nf_ct_kill(ct);
+       }
+       spin_unlock_bh(&nf_conntrack_lock);
 }
-EXPORT_SYMBOL_GPL(nf_conntrack_flush);
 
 static void nf_conntrack_cleanup_init_net(void)
 {
@@ -1042,10 +1089,9 @@ static void nf_conntrack_cleanup_init_net(void)
 
 static void nf_conntrack_cleanup_net(struct net *net)
 {
-       nf_ct_event_cache_flush(net);
-       nf_conntrack_ecache_fini(net);
  i_see_dead_people:
-       nf_conntrack_flush(net, 0, 0);
+       nf_ct_iterate_cleanup(net, kill_all, NULL);
+       nf_ct_release_dying_list();
        if (atomic_read(&net->ct.count) != 0) {
                schedule();
                goto i_see_dead_people;
@@ -1056,6 +1102,7 @@ static void nf_conntrack_cleanup_net(struct net *net)
 
        nf_ct_free_hashtable(net->ct.hash, net->ct.hash_vmalloc,
                             nf_conntrack_htable_size);
+       nf_conntrack_ecache_fini(net);
        nf_conntrack_acct_fini(net);
        nf_conntrack_expect_fini(net);
        free_percpu(net->ct.stat);
@@ -1226,14 +1273,12 @@ static int nf_conntrack_init_net(struct net *net)
 
        atomic_set(&net->ct.count, 0);
        INIT_HLIST_NULLS_HEAD(&net->ct.unconfirmed, 0);
+       INIT_HLIST_NULLS_HEAD(&net->ct.dying, 0);
        net->ct.stat = alloc_percpu(struct ip_conntrack_stat);
        if (!net->ct.stat) {
                ret = -ENOMEM;
                goto err_stat;
        }
-       ret = nf_conntrack_ecache_init(net);
-       if (ret < 0)
-               goto err_ecache;
        net->ct.hash = nf_ct_alloc_hashtable(&nf_conntrack_htable_size,
                                             &net->ct.hash_vmalloc, 1);
        if (!net->ct.hash) {
@@ -1247,6 +1292,9 @@ static int nf_conntrack_init_net(struct net *net)
        ret = nf_conntrack_acct_init(net);
        if (ret < 0)
                goto err_acct;
+       ret = nf_conntrack_ecache_init(net);
+       if (ret < 0)
+               goto err_ecache;
 
        /* Set up fake conntrack:
            - to never be deleted, not in any hashes */
@@ -1259,14 +1307,14 @@ static int nf_conntrack_init_net(struct net *net)
 
        return 0;
 
+err_ecache:
+       nf_conntrack_acct_fini(net);
 err_acct:
        nf_conntrack_expect_fini(net);
 err_expect:
        nf_ct_free_hashtable(net->ct.hash, net->ct.hash_vmalloc,
                             nf_conntrack_htable_size);
 err_hash:
-       nf_conntrack_ecache_fini(net);
-err_ecache:
        free_percpu(net->ct.stat);
 err_stat:
        return ret;
index dee4190209ccc2420709bcbcab29527270625730..aee560b4768dda0522107a9aefeff5d382022516 100644 (file)
 #include <linux/stddef.h>
 #include <linux/err.h>
 #include <linux/percpu.h>
-#include <linux/notifier.h>
 #include <linux/kernel.h>
 #include <linux/netdevice.h>
 
 #include <net/netfilter/nf_conntrack.h>
 #include <net/netfilter/nf_conntrack_core.h>
+#include <net/netfilter/nf_conntrack_extend.h>
 
-ATOMIC_NOTIFIER_HEAD(nf_conntrack_chain);
-EXPORT_SYMBOL_GPL(nf_conntrack_chain);
+static DEFINE_MUTEX(nf_ct_ecache_mutex);
 
-ATOMIC_NOTIFIER_HEAD(nf_ct_expect_chain);
-EXPORT_SYMBOL_GPL(nf_ct_expect_chain);
+struct nf_ct_event_notifier *nf_conntrack_event_cb __read_mostly;
+EXPORT_SYMBOL_GPL(nf_conntrack_event_cb);
+
+struct nf_exp_event_notifier *nf_expect_event_cb __read_mostly;
+EXPORT_SYMBOL_GPL(nf_expect_event_cb);
 
 /* deliver cached events and clear cache entry - must be called with locally
  * disabled softirqs */
-static inline void
-__nf_ct_deliver_cached_events(struct nf_conntrack_ecache *ecache)
+void nf_ct_deliver_cached_events(struct nf_conn *ct)
 {
-       if (nf_ct_is_confirmed(ecache->ct) && !nf_ct_is_dying(ecache->ct)
-           && ecache->events) {
+       unsigned long events;
+       struct nf_ct_event_notifier *notify;
+       struct nf_conntrack_ecache *e;
+
+       rcu_read_lock();
+       notify = rcu_dereference(nf_conntrack_event_cb);
+       if (notify == NULL)
+               goto out_unlock;
+
+       e = nf_ct_ecache_find(ct);
+       if (e == NULL)
+               goto out_unlock;
+
+       events = xchg(&e->cache, 0);
+
+       if (nf_ct_is_confirmed(ct) && !nf_ct_is_dying(ct) && events) {
                struct nf_ct_event item = {
-                       .ct     = ecache->ct,
+                       .ct     = ct,
                        .pid    = 0,
                        .report = 0
                };
+               int ret;
+               /* We make a copy of the missed event cache without taking
+                * the lock, thus we may send missed events twice. However,
+                * this does not harm and it happens very rarely. */
+               unsigned long missed = e->missed;
 
-               atomic_notifier_call_chain(&nf_conntrack_chain,
-                                          ecache->events,
-                                          &item);
+               ret = notify->fcn(events | missed, &item);
+               if (unlikely(ret < 0 || missed)) {
+                       spin_lock_bh(&ct->lock);
+                       if (ret < 0)
+                               e->missed |= events;
+                       else
+                               e->missed &= ~missed;
+                       spin_unlock_bh(&ct->lock);
+               } 
        }
 
-       ecache->events = 0;
-       nf_ct_put(ecache->ct);
-       ecache->ct = NULL;
+out_unlock:
+       rcu_read_unlock();
 }
+EXPORT_SYMBOL_GPL(nf_ct_deliver_cached_events);
 
-/* Deliver all cached events for a particular conntrack. This is called
- * by code prior to async packet handling for freeing the skb */
-void nf_ct_deliver_cached_events(const struct nf_conn *ct)
+int nf_conntrack_register_notifier(struct nf_ct_event_notifier *new)
 {
-       struct net *net = nf_ct_net(ct);
-       struct nf_conntrack_ecache *ecache;
-
-       local_bh_disable();
-       ecache = per_cpu_ptr(net->ct.ecache, raw_smp_processor_id());
-       if (ecache->ct == ct)
-               __nf_ct_deliver_cached_events(ecache);
-       local_bh_enable();
+       int ret = 0;
+       struct nf_ct_event_notifier *notify;
+
+       mutex_lock(&nf_ct_ecache_mutex);
+       notify = rcu_dereference(nf_conntrack_event_cb);
+       if (notify != NULL) {
+               ret = -EBUSY;
+               goto out_unlock;
+       }
+       rcu_assign_pointer(nf_conntrack_event_cb, new);
+       mutex_unlock(&nf_ct_ecache_mutex);
+       return ret;
+
+out_unlock:
+       mutex_unlock(&nf_ct_ecache_mutex);
+       return ret;
 }
-EXPORT_SYMBOL_GPL(nf_ct_deliver_cached_events);
+EXPORT_SYMBOL_GPL(nf_conntrack_register_notifier);
 
-/* Deliver cached events for old pending events, if current conntrack != old */
-void __nf_ct_event_cache_init(struct nf_conn *ct)
+void nf_conntrack_unregister_notifier(struct nf_ct_event_notifier *new)
 {
-       struct net *net = nf_ct_net(ct);
-       struct nf_conntrack_ecache *ecache;
-
-       /* take care of delivering potentially old events */
-       ecache = per_cpu_ptr(net->ct.ecache, raw_smp_processor_id());
-       BUG_ON(ecache->ct == ct);
-       if (ecache->ct)
-               __nf_ct_deliver_cached_events(ecache);
-       /* initialize for this conntrack/packet */
-       ecache->ct = ct;
-       nf_conntrack_get(&ct->ct_general);
+       struct nf_ct_event_notifier *notify;
+
+       mutex_lock(&nf_ct_ecache_mutex);
+       notify = rcu_dereference(nf_conntrack_event_cb);
+       BUG_ON(notify != new);
+       rcu_assign_pointer(nf_conntrack_event_cb, NULL);
+       mutex_unlock(&nf_ct_ecache_mutex);
 }
-EXPORT_SYMBOL_GPL(__nf_ct_event_cache_init);
+EXPORT_SYMBOL_GPL(nf_conntrack_unregister_notifier);
 
-/* flush the event cache - touches other CPU's data and must not be called
- * while packets are still passing through the code */
-void nf_ct_event_cache_flush(struct net *net)
+int nf_ct_expect_register_notifier(struct nf_exp_event_notifier *new)
 {
-       struct nf_conntrack_ecache *ecache;
-       int cpu;
+       int ret = 0;
+       struct nf_exp_event_notifier *notify;
 
-       for_each_possible_cpu(cpu) {
-               ecache = per_cpu_ptr(net->ct.ecache, cpu);
-               if (ecache->ct)
-                       nf_ct_put(ecache->ct);
+       mutex_lock(&nf_ct_ecache_mutex);
+       notify = rcu_dereference(nf_expect_event_cb);
+       if (notify != NULL) {
+               ret = -EBUSY;
+               goto out_unlock;
        }
+       rcu_assign_pointer(nf_expect_event_cb, new);
+       mutex_unlock(&nf_ct_ecache_mutex);
+       return ret;
+
+out_unlock:
+       mutex_unlock(&nf_ct_ecache_mutex);
+       return ret;
 }
+EXPORT_SYMBOL_GPL(nf_ct_expect_register_notifier);
 
-int nf_conntrack_ecache_init(struct net *net)
+void nf_ct_expect_unregister_notifier(struct nf_exp_event_notifier *new)
 {
-       net->ct.ecache = alloc_percpu(struct nf_conntrack_ecache);
-       if (!net->ct.ecache)
-               return -ENOMEM;
-       return 0;
+       struct nf_exp_event_notifier *notify;
+
+       mutex_lock(&nf_ct_ecache_mutex);
+       notify = rcu_dereference(nf_expect_event_cb);
+       BUG_ON(notify != new);
+       rcu_assign_pointer(nf_expect_event_cb, NULL);
+       mutex_unlock(&nf_ct_ecache_mutex);
 }
+EXPORT_SYMBOL_GPL(nf_ct_expect_unregister_notifier);
 
-void nf_conntrack_ecache_fini(struct net *net)
+#define NF_CT_EVENTS_DEFAULT 1
+static int nf_ct_events __read_mostly = NF_CT_EVENTS_DEFAULT;
+static int nf_ct_events_retry_timeout __read_mostly = 15*HZ;
+
+#ifdef CONFIG_SYSCTL
+static struct ctl_table event_sysctl_table[] = {
+       {
+               .ctl_name       = CTL_UNNUMBERED,
+               .procname       = "nf_conntrack_events",
+               .data           = &init_net.ct.sysctl_events,
+               .maxlen         = sizeof(unsigned int),
+               .mode           = 0644,
+               .proc_handler   = proc_dointvec,
+       },
+       {
+               .ctl_name       = CTL_UNNUMBERED,
+               .procname       = "nf_conntrack_events_retry_timeout",
+               .data           = &init_net.ct.sysctl_events_retry_timeout,
+               .maxlen         = sizeof(unsigned int),
+               .mode           = 0644,
+               .proc_handler   = proc_dointvec_jiffies,
+       },
+       {}
+};
+#endif /* CONFIG_SYSCTL */
+
+static struct nf_ct_ext_type event_extend __read_mostly = {
+       .len    = sizeof(struct nf_conntrack_ecache),
+       .align  = __alignof__(struct nf_conntrack_ecache),
+       .id     = NF_CT_EXT_ECACHE,
+};
+
+#ifdef CONFIG_SYSCTL
+static int nf_conntrack_event_init_sysctl(struct net *net)
 {
-       free_percpu(net->ct.ecache);
+       struct ctl_table *table;
+
+       table = kmemdup(event_sysctl_table, sizeof(event_sysctl_table),
+                       GFP_KERNEL);
+       if (!table)
+               goto out;
+
+       table[0].data = &net->ct.sysctl_events;
+       table[1].data = &net->ct.sysctl_events_retry_timeout;
+
+       net->ct.event_sysctl_header =
+               register_net_sysctl_table(net,
+                                         nf_net_netfilter_sysctl_path, table);
+       if (!net->ct.event_sysctl_header) {
+               printk(KERN_ERR "nf_ct_event: can't register to sysctl.\n");
+               goto out_register;
+       }
+       return 0;
+
+out_register:
+       kfree(table);
+out:
+       return -ENOMEM;
 }
 
-int nf_conntrack_register_notifier(struct notifier_block *nb)
+static void nf_conntrack_event_fini_sysctl(struct net *net)
 {
-       return atomic_notifier_chain_register(&nf_conntrack_chain, nb);
+       struct ctl_table *table;
+
+       table = net->ct.event_sysctl_header->ctl_table_arg;
+       unregister_net_sysctl_table(net->ct.event_sysctl_header);
+       kfree(table);
+}
+#else
+static int nf_conntrack_event_init_sysctl(struct net *net)
+{
+       return 0;
 }
-EXPORT_SYMBOL_GPL(nf_conntrack_register_notifier);
 
-int nf_conntrack_unregister_notifier(struct notifier_block *nb)
+static void nf_conntrack_event_fini_sysctl(struct net *net)
 {
-       return atomic_notifier_chain_unregister(&nf_conntrack_chain, nb);
 }
-EXPORT_SYMBOL_GPL(nf_conntrack_unregister_notifier);
+#endif /* CONFIG_SYSCTL */
 
-int nf_ct_expect_register_notifier(struct notifier_block *nb)
+int nf_conntrack_ecache_init(struct net *net)
 {
-       return atomic_notifier_chain_register(&nf_ct_expect_chain, nb);
+       int ret;
+
+       net->ct.sysctl_events = nf_ct_events;
+       net->ct.sysctl_events_retry_timeout = nf_ct_events_retry_timeout;
+
+       if (net_eq(net, &init_net)) {
+               ret = nf_ct_extend_register(&event_extend);
+               if (ret < 0) {
+                       printk(KERN_ERR "nf_ct_event: Unable to register "
+                                       "event extension.\n");
+                       goto out_extend_register;
+               }
+       }
+
+       ret = nf_conntrack_event_init_sysctl(net);
+       if (ret < 0)
+               goto out_sysctl;
+
+       return 0;
+
+out_sysctl:
+       if (net_eq(net, &init_net))
+               nf_ct_extend_unregister(&event_extend);
+out_extend_register:
+       return ret;
 }
-EXPORT_SYMBOL_GPL(nf_ct_expect_register_notifier);
 
-int nf_ct_expect_unregister_notifier(struct notifier_block *nb)
+void nf_conntrack_ecache_fini(struct net *net)
 {
-       return atomic_notifier_chain_unregister(&nf_ct_expect_chain, nb);
+       nf_conntrack_event_fini_sysctl(net);
+       if (net_eq(net, &init_net))
+               nf_ct_extend_unregister(&event_extend);
 }
-EXPORT_SYMBOL_GPL(nf_ct_expect_unregister_notifier);
index 00fecc385f9b55e9aa6edb2452a7c6025f043618..5509dd1f14cfd3065e5a779fb420e705b3fd77a9 100644 (file)
@@ -338,11 +338,9 @@ static void update_nl_seq(struct nf_conn *ct, u32 nl_seq,
 
        if (info->seq_aft_nl_num[dir] < NUM_SEQ_TO_REMEMBER) {
                info->seq_aft_nl[dir][info->seq_aft_nl_num[dir]++] = nl_seq;
-               nf_conntrack_event_cache(IPCT_HELPINFO_VOLATILE, ct);
        } else if (oldest != NUM_SEQ_TO_REMEMBER &&
                   after(nl_seq, info->seq_aft_nl[dir][oldest])) {
                info->seq_aft_nl[dir][oldest] = nl_seq;
-               nf_conntrack_event_cache(IPCT_HELPINFO_VOLATILE, ct);
        }
 }
 
index 0fa5a422959fc63c13c75abb86747a77fc4c185c..65c2a7bc3afcdccef4ce0eefb35b38f6beda99d7 100644 (file)
@@ -136,6 +136,20 @@ static inline int unhelp(struct nf_conntrack_tuple_hash *i,
        return 0;
 }
 
+void nf_ct_helper_destroy(struct nf_conn *ct)
+{
+       struct nf_conn_help *help = nfct_help(ct);
+       struct nf_conntrack_helper *helper;
+
+       if (help) {
+               rcu_read_lock();
+               helper = rcu_dereference(help->helper);
+               if (helper && helper->destroy)
+                       helper->destroy(ct);
+               rcu_read_unlock();
+       }
+}
+
 int nf_conntrack_helper_register(struct nf_conntrack_helper *me)
 {
        unsigned int h = helper_hash(&me->tuple);
index 8a3875e36ec2d37ffbfa197fc4226e41a4a12fe4..497b2224536fe6fe29ec904dabda14b7a55afc89 100644 (file)
@@ -48,7 +48,7 @@ static int help(struct sk_buff *skb, unsigned int protoff,
 {
        struct nf_conntrack_expect *exp;
        struct iphdr *iph = ip_hdr(skb);
-       struct rtable *rt = skb->rtable;
+       struct rtable *rt = skb_rtable(skb);
        struct in_device *in_dev;
        __be32 mask = 0;
 
index c523f0b8cee53bd9e304af4db77a4a474c44bcbe..49479d1945700b14a8e86de3c6781ed471411694 100644 (file)
@@ -27,7 +27,6 @@
 #include <linux/netlink.h>
 #include <linux/spinlock.h>
 #include <linux/interrupt.h>
-#include <linux/notifier.h>
 
 #include <linux/netfilter.h>
 #include <net/netlink.h>
@@ -144,7 +143,7 @@ nla_put_failure:
 }
 
 static inline int
-ctnetlink_dump_protoinfo(struct sk_buff *skb, const struct nf_conn *ct)
+ctnetlink_dump_protoinfo(struct sk_buff *skb, struct nf_conn *ct)
 {
        struct nf_conntrack_l4proto *l4proto;
        struct nlattr *nest_proto;
@@ -346,23 +345,21 @@ nla_put_failure:
        return -1;
 }
 
-#define tuple(ct, dir) (&(ct)->tuplehash[dir].tuple)
-
 static int
 ctnetlink_fill_info(struct sk_buff *skb, u32 pid, u32 seq,
-                   int event, int nowait,
-                   const struct nf_conn *ct)
+                   int event, struct nf_conn *ct)
 {
        struct nlmsghdr *nlh;
        struct nfgenmsg *nfmsg;
        struct nlattr *nest_parms;
-       unsigned char *b = skb_tail_pointer(skb);
+       unsigned int flags = pid ? NLM_F_MULTI : 0;
 
        event |= NFNL_SUBSYS_CTNETLINK << 8;
-       nlh    = NLMSG_PUT(skb, pid, seq, event, sizeof(struct nfgenmsg));
-       nfmsg  = NLMSG_DATA(nlh);
+       nlh = nlmsg_put(skb, pid, seq, event, sizeof(*nfmsg), flags);
+       if (nlh == NULL)
+               goto nlmsg_failure;
 
-       nlh->nlmsg_flags    = (nowait && pid) ? NLM_F_MULTI : 0;
+       nfmsg = nlmsg_data(nlh);
        nfmsg->nfgen_family = nf_ct_l3num(ct);
        nfmsg->version      = NFNETLINK_V0;
        nfmsg->res_id       = 0;
@@ -370,14 +367,14 @@ ctnetlink_fill_info(struct sk_buff *skb, u32 pid, u32 seq,
        nest_parms = nla_nest_start(skb, CTA_TUPLE_ORIG | NLA_F_NESTED);
        if (!nest_parms)
                goto nla_put_failure;
-       if (ctnetlink_dump_tuples(skb, tuple(ct, IP_CT_DIR_ORIGINAL)) < 0)
+       if (ctnetlink_dump_tuples(skb, nf_ct_tuple(ct, IP_CT_DIR_ORIGINAL)) < 0)
                goto nla_put_failure;
        nla_nest_end(skb, nest_parms);
 
        nest_parms = nla_nest_start(skb, CTA_TUPLE_REPLY | NLA_F_NESTED);
        if (!nest_parms)
                goto nla_put_failure;
-       if (ctnetlink_dump_tuples(skb, tuple(ct, IP_CT_DIR_REPLY)) < 0)
+       if (ctnetlink_dump_tuples(skb, nf_ct_tuple(ct, IP_CT_DIR_REPLY)) < 0)
                goto nla_put_failure;
        nla_nest_end(skb, nest_parms);
 
@@ -395,132 +392,109 @@ ctnetlink_fill_info(struct sk_buff *skb, u32 pid, u32 seq,
            ctnetlink_dump_nat_seq_adj(skb, ct) < 0)
                goto nla_put_failure;
 
-       nlh->nlmsg_len = skb_tail_pointer(skb) - b;
+       nlmsg_end(skb, nlh);
        return skb->len;
 
 nlmsg_failure:
 nla_put_failure:
-       nlmsg_trim(skb, b);
+       nlmsg_cancel(skb, nlh);
        return -1;
 }
 
 #ifdef CONFIG_NF_CONNTRACK_EVENTS
-/*
- * The general structure of a ctnetlink event is
- *
- *  CTA_TUPLE_ORIG
- *    <l3/l4-proto-attributes>
- *  CTA_TUPLE_REPLY
- *    <l3/l4-proto-attributes>
- *  CTA_ID
- *  ...
- *  CTA_PROTOINFO
- *    <l4-proto-attributes>
- *  CTA_TUPLE_MASTER
- *    <l3/l4-proto-attributes>
- *
- * Therefore the formular is
- *
- *   size = sizeof(headers) + sizeof(generic_nlas) + 3 * sizeof(tuple_nlas)
- *             + sizeof(protoinfo_nlas)
- */
-static struct sk_buff *
-ctnetlink_alloc_skb(const struct nf_conntrack_tuple *tuple, gfp_t gfp)
+static inline size_t
+ctnetlink_proto_size(const struct nf_conn *ct)
 {
        struct nf_conntrack_l3proto *l3proto;
        struct nf_conntrack_l4proto *l4proto;
-       int len;
-
-#define NLA_TYPE_SIZE(type)            nla_total_size(sizeof(type))
-
-       /* proto independant part */
-       len = NLMSG_SPACE(sizeof(struct nfgenmsg))
-               + 3 * nla_total_size(0)         /* CTA_TUPLE_ORIG|REPL|MASTER */
-               + 3 * nla_total_size(0)         /* CTA_TUPLE_IP */
-               + 3 * nla_total_size(0)         /* CTA_TUPLE_PROTO */
-               + 3 * NLA_TYPE_SIZE(u_int8_t)   /* CTA_PROTO_NUM */
-               + NLA_TYPE_SIZE(u_int32_t)      /* CTA_ID */
-               + NLA_TYPE_SIZE(u_int32_t)      /* CTA_STATUS */
+       size_t len = 0;
+
+       rcu_read_lock();
+       l3proto = __nf_ct_l3proto_find(nf_ct_l3num(ct));
+       len += l3proto->nla_size;
+
+       l4proto = __nf_ct_l4proto_find(nf_ct_l3num(ct), nf_ct_protonum(ct));
+       len += l4proto->nla_size;
+       rcu_read_unlock();
+
+       return len;
+}
+
+static inline size_t
+ctnetlink_nlmsg_size(const struct nf_conn *ct)
+{
+       return NLMSG_ALIGN(sizeof(struct nfgenmsg))
+              + 3 * nla_total_size(0) /* CTA_TUPLE_ORIG|REPL|MASTER */
+              + 3 * nla_total_size(0) /* CTA_TUPLE_IP */
+              + 3 * nla_total_size(0) /* CTA_TUPLE_PROTO */
+              + 3 * nla_total_size(sizeof(u_int8_t)) /* CTA_PROTO_NUM */
+              + nla_total_size(sizeof(u_int32_t)) /* CTA_ID */
+              + nla_total_size(sizeof(u_int32_t)) /* CTA_STATUS */
 #ifdef CONFIG_NF_CT_ACCT
-               + 2 * nla_total_size(0)         /* CTA_COUNTERS_ORIG|REPL */
-               + 2 * NLA_TYPE_SIZE(uint64_t)   /* CTA_COUNTERS_PACKETS */
-               + 2 * NLA_TYPE_SIZE(uint64_t)   /* CTA_COUNTERS_BYTES */
+              + 2 * nla_total_size(0) /* CTA_COUNTERS_ORIG|REPL */
+              + 2 * nla_total_size(sizeof(uint64_t)) /* CTA_COUNTERS_PACKETS */
+              + 2 * nla_total_size(sizeof(uint64_t)) /* CTA_COUNTERS_BYTES */
 #endif
-               + NLA_TYPE_SIZE(u_int32_t)      /* CTA_TIMEOUT */
-               + nla_total_size(0)             /* CTA_PROTOINFO */
-               + nla_total_size(0)             /* CTA_HELP */
-               + nla_total_size(NF_CT_HELPER_NAME_LEN) /* CTA_HELP_NAME */
+              + nla_total_size(sizeof(u_int32_t)) /* CTA_TIMEOUT */
+              + nla_total_size(0) /* CTA_PROTOINFO */
+              + nla_total_size(0) /* CTA_HELP */
+              + nla_total_size(NF_CT_HELPER_NAME_LEN) /* CTA_HELP_NAME */
 #ifdef CONFIG_NF_CONNTRACK_SECMARK
-               + NLA_TYPE_SIZE(u_int32_t)      /* CTA_SECMARK */
+              + nla_total_size(sizeof(u_int32_t)) /* CTA_SECMARK */
 #endif
 #ifdef CONFIG_NF_NAT_NEEDED
-               + 2 * nla_total_size(0)         /* CTA_NAT_SEQ_ADJ_ORIG|REPL */
-               + 2 * NLA_TYPE_SIZE(u_int32_t)  /* CTA_NAT_SEQ_CORRECTION_POS */
-               + 2 * NLA_TYPE_SIZE(u_int32_t)  /* CTA_NAT_SEQ_CORRECTION_BEFORE */
-               + 2 * NLA_TYPE_SIZE(u_int32_t)  /* CTA_NAT_SEQ_CORRECTION_AFTER */
+              + 2 * nla_total_size(0) /* CTA_NAT_SEQ_ADJ_ORIG|REPL */
+              + 6 * nla_total_size(sizeof(u_int32_t)) /* CTA_NAT_SEQ_OFFSET */
 #endif
 #ifdef CONFIG_NF_CONNTRACK_MARK
-               + NLA_TYPE_SIZE(u_int32_t)      /* CTA_MARK */
+              + nla_total_size(sizeof(u_int32_t)) /* CTA_MARK */
 #endif
-               ;
-
-#undef NLA_TYPE_SIZE
-
-       rcu_read_lock();
-       l3proto = __nf_ct_l3proto_find(tuple->src.l3num);
-       len += l3proto->nla_size;
-
-       l4proto = __nf_ct_l4proto_find(tuple->src.l3num, tuple->dst.protonum);
-       len += l4proto->nla_size;
-       rcu_read_unlock();
-
-       return alloc_skb(len, gfp);
+              + ctnetlink_proto_size(ct)
+              ;
 }
 
-static int ctnetlink_conntrack_event(struct notifier_block *this,
-                                    unsigned long events, void *ptr)
+static int
+ctnetlink_conntrack_event(unsigned int events, struct nf_ct_event *item)
 {
        struct nlmsghdr *nlh;
        struct nfgenmsg *nfmsg;
        struct nlattr *nest_parms;
-       struct nf_ct_event *item = (struct nf_ct_event *)ptr;
        struct nf_conn *ct = item->ct;
        struct sk_buff *skb;
        unsigned int type;
-       sk_buff_data_t b;
        unsigned int flags = 0, group;
+       int err;
 
        /* ignore our fake conntrack entry */
        if (ct == &nf_conntrack_untracked)
-               return NOTIFY_DONE;
+               return 0;
 
-       if (events & IPCT_DESTROY) {
+       if (events & (1 << IPCT_DESTROY)) {
                type = IPCTNL_MSG_CT_DELETE;
                group = NFNLGRP_CONNTRACK_DESTROY;
-       } else  if (events & (IPCT_NEW | IPCT_RELATED)) {
+       } else  if (events & ((1 << IPCT_NEW) | (1 << IPCT_RELATED))) {
                type = IPCTNL_MSG_CT_NEW;
                flags = NLM_F_CREATE|NLM_F_EXCL;
                group = NFNLGRP_CONNTRACK_NEW;
-       } else  if (events & (IPCT_STATUS | IPCT_PROTOINFO)) {
+       } else  if (events) {
                type = IPCTNL_MSG_CT_NEW;
                group = NFNLGRP_CONNTRACK_UPDATE;
        } else
-               return NOTIFY_DONE;
+               return 0;
 
        if (!item->report && !nfnetlink_has_listeners(group))
-               return NOTIFY_DONE;
+               return 0;
 
-       skb = ctnetlink_alloc_skb(tuple(ct, IP_CT_DIR_ORIGINAL), GFP_ATOMIC);
-       if (!skb)
+       skb = nlmsg_new(ctnetlink_nlmsg_size(ct), GFP_ATOMIC);
+       if (skb == NULL)
                goto errout;
 
-       b = skb->tail;
-
        type |= NFNL_SUBSYS_CTNETLINK << 8;
-       nlh   = NLMSG_PUT(skb, item->pid, 0, type, sizeof(struct nfgenmsg));
-       nfmsg = NLMSG_DATA(nlh);
+       nlh = nlmsg_put(skb, item->pid, 0, type, sizeof(*nfmsg), flags);
+       if (nlh == NULL)
+               goto nlmsg_failure;
 
-       nlh->nlmsg_flags    = flags;
+       nfmsg = nlmsg_data(nlh);
        nfmsg->nfgen_family = nf_ct_l3num(ct);
        nfmsg->version  = NFNETLINK_V0;
        nfmsg->res_id   = 0;
@@ -529,14 +503,14 @@ static int ctnetlink_conntrack_event(struct notifier_block *this,
        nest_parms = nla_nest_start(skb, CTA_TUPLE_ORIG | NLA_F_NESTED);
        if (!nest_parms)
                goto nla_put_failure;
-       if (ctnetlink_dump_tuples(skb, tuple(ct, IP_CT_DIR_ORIGINAL)) < 0)
+       if (ctnetlink_dump_tuples(skb, nf_ct_tuple(ct, IP_CT_DIR_ORIGINAL)) < 0)
                goto nla_put_failure;
        nla_nest_end(skb, nest_parms);
 
        nest_parms = nla_nest_start(skb, CTA_TUPLE_REPLY | NLA_F_NESTED);
        if (!nest_parms)
                goto nla_put_failure;
-       if (ctnetlink_dump_tuples(skb, tuple(ct, IP_CT_DIR_REPLY)) < 0)
+       if (ctnetlink_dump_tuples(skb, nf_ct_tuple(ct, IP_CT_DIR_REPLY)) < 0)
                goto nla_put_failure;
        nla_nest_end(skb, nest_parms);
 
@@ -546,7 +520,7 @@ static int ctnetlink_conntrack_event(struct notifier_block *this,
        if (ctnetlink_dump_status(skb, ct) < 0)
                goto nla_put_failure;
 
-       if (events & IPCT_DESTROY) {
+       if (events & (1 << IPCT_DESTROY)) {
                if (ctnetlink_dump_counters(skb, ct, IP_CT_DIR_ORIGINAL) < 0 ||
                    ctnetlink_dump_counters(skb, ct, IP_CT_DIR_REPLY) < 0)
                        goto nla_put_failure;
@@ -554,47 +528,51 @@ static int ctnetlink_conntrack_event(struct notifier_block *this,
                if (ctnetlink_dump_timeout(skb, ct) < 0)
                        goto nla_put_failure;
 
-               if (events & IPCT_PROTOINFO
+               if (events & (1 << IPCT_PROTOINFO)
                    && ctnetlink_dump_protoinfo(skb, ct) < 0)
                        goto nla_put_failure;
 
-               if ((events & IPCT_HELPER || nfct_help(ct))
+               if ((events & (1 << IPCT_HELPER) || nfct_help(ct))
                    && ctnetlink_dump_helpinfo(skb, ct) < 0)
                        goto nla_put_failure;
 
 #ifdef CONFIG_NF_CONNTRACK_SECMARK
-               if ((events & IPCT_SECMARK || ct->secmark)
+               if ((events & (1 << IPCT_SECMARK) || ct->secmark)
                    && ctnetlink_dump_secmark(skb, ct) < 0)
                        goto nla_put_failure;
 #endif
 
-               if (events & IPCT_RELATED &&
+               if (events & (1 << IPCT_RELATED) &&
                    ctnetlink_dump_master(skb, ct) < 0)
                        goto nla_put_failure;
 
-               if (events & IPCT_NATSEQADJ &&
+               if (events & (1 << IPCT_NATSEQADJ) &&
                    ctnetlink_dump_nat_seq_adj(skb, ct) < 0)
                        goto nla_put_failure;
        }
 
 #ifdef CONFIG_NF_CONNTRACK_MARK
-       if ((events & IPCT_MARK || ct->mark)
+       if ((events & (1 << IPCT_MARK) || ct->mark)
            && ctnetlink_dump_mark(skb, ct) < 0)
                goto nla_put_failure;
 #endif
        rcu_read_unlock();
 
-       nlh->nlmsg_len = skb->tail - b;
-       nfnetlink_send(skb, item->pid, group, item->report);
-       return NOTIFY_DONE;
+       nlmsg_end(skb, nlh);
+       err = nfnetlink_send(skb, item->pid, group, item->report, GFP_ATOMIC);
+       if (err == -ENOBUFS || err == -EAGAIN)
+               return -ENOBUFS;
+
+       return 0;
 
 nla_put_failure:
        rcu_read_unlock();
+       nlmsg_cancel(skb, nlh);
 nlmsg_failure:
        kfree_skb(skb);
 errout:
        nfnetlink_set_err(0, group, -ENOBUFS);
-       return NOTIFY_DONE;
+       return 0;
 }
 #endif /* CONFIG_NF_CONNTRACK_EVENTS */
 
@@ -611,7 +589,7 @@ ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
        struct nf_conn *ct, *last;
        struct nf_conntrack_tuple_hash *h;
        struct hlist_nulls_node *n;
-       struct nfgenmsg *nfmsg = NLMSG_DATA(cb->nlh);
+       struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
        u_int8_t l3proto = nfmsg->nfgen_family;
 
        rcu_read_lock();
@@ -637,8 +615,7 @@ restart:
                        }
                        if (ctnetlink_fill_info(skb, NETLINK_CB(cb->skb).pid,
                                                cb->nlh->nlmsg_seq,
-                                               IPCTNL_MSG_CT_NEW,
-                                               1, ct) < 0) {
+                                               IPCTNL_MSG_CT_NEW, ct) < 0) {
                                cb->args[1] = (unsigned long)ct;
                                goto out;
                        }
@@ -792,7 +769,7 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,
        struct nf_conntrack_tuple_hash *h;
        struct nf_conntrack_tuple tuple;
        struct nf_conn *ct;
-       struct nfgenmsg *nfmsg = NLMSG_DATA(nlh);
+       struct nfgenmsg *nfmsg = nlmsg_data(nlh);
        u_int8_t u3 = nfmsg->nfgen_family;
        int err = 0;
 
@@ -802,9 +779,9 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,
                err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_REPLY, u3);
        else {
                /* Flush the whole table */
-               nf_conntrack_flush(&init_net, 
-                                  NETLINK_CB(skb).pid, 
-                                  nlmsg_report(nlh));
+               nf_conntrack_flush_report(&init_net,
+                                        NETLINK_CB(skb).pid,
+                                        nlmsg_report(nlh));
                return 0;
        }
 
@@ -825,10 +802,15 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,
                }
        }
 
-       nf_conntrack_event_report(IPCT_DESTROY,
-                                 ct,
-                                 NETLINK_CB(skb).pid,
-                                 nlmsg_report(nlh));
+       if (nf_conntrack_event_report(IPCT_DESTROY, ct,
+                                     NETLINK_CB(skb).pid,
+                                     nlmsg_report(nlh)) < 0) {
+               nf_ct_delete_from_lists(ct);
+               /* we failed to report the event, try later */
+               nf_ct_insert_dying_list(ct);
+               nf_ct_put(ct);
+               return 0;
+       }
 
        /* death_by_timeout would report the event again */
        set_bit(IPS_DYING_BIT, &ct->status);
@@ -847,7 +829,7 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
        struct nf_conntrack_tuple tuple;
        struct nf_conn *ct;
        struct sk_buff *skb2 = NULL;
-       struct nfgenmsg *nfmsg = NLMSG_DATA(nlh);
+       struct nfgenmsg *nfmsg = nlmsg_data(nlh);
        u_int8_t u3 = nfmsg->nfgen_family;
        int err = 0;
 
@@ -872,15 +854,15 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
        ct = nf_ct_tuplehash_to_ctrack(h);
 
        err = -ENOMEM;
-       skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
-       if (!skb2) {
+       skb2 = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+       if (skb2 == NULL) {
                nf_ct_put(ct);
                return -ENOMEM;
        }
 
        rcu_read_lock();
        err = ctnetlink_fill_info(skb2, NETLINK_CB(skb).pid, nlh->nlmsg_seq,
-                                 IPCTNL_MSG_CT_NEW, 1, ct);
+                                 IPCTNL_MSG_CT_NEW, ct);
        rcu_read_unlock();
        nf_ct_put(ct);
        if (err <= 0)
@@ -1280,6 +1262,7 @@ ctnetlink_create_conntrack(struct nlattr *cda[],
        }
 
        nf_ct_acct_ext_add(ct, GFP_ATOMIC);
+       nf_ct_ecache_ext_add(ct, GFP_ATOMIC);
 
 #if defined(CONFIG_NF_CONNTRACK_MARK)
        if (cda[CTA_MARK])
@@ -1325,7 +1308,7 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
 {
        struct nf_conntrack_tuple otuple, rtuple;
        struct nf_conntrack_tuple_hash *h = NULL;
-       struct nfgenmsg *nfmsg = NLMSG_DATA(nlh);
+       struct nfgenmsg *nfmsg = nlmsg_data(nlh);
        u_int8_t u3 = nfmsg->nfgen_family;
        int err = 0;
 
@@ -1367,13 +1350,13 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
                        else
                                events = IPCT_NEW;
 
-                       nf_conntrack_event_report(IPCT_STATUS |
-                                                 IPCT_HELPER |
-                                                 IPCT_PROTOINFO |
-                                                 IPCT_NATSEQADJ |
-                                                 IPCT_MARK | events,
-                                                 ct, NETLINK_CB(skb).pid,
-                                                 nlmsg_report(nlh));
+                       nf_conntrack_eventmask_report((1 << IPCT_STATUS) |
+                                                     (1 << IPCT_HELPER) |
+                                                     (1 << IPCT_PROTOINFO) |
+                                                     (1 << IPCT_NATSEQADJ) |
+                                                     (1 << IPCT_MARK) | events,
+                                                     ct, NETLINK_CB(skb).pid,
+                                                     nlmsg_report(nlh));
                        nf_ct_put(ct);
                } else
                        spin_unlock_bh(&nf_conntrack_lock);
@@ -1392,13 +1375,13 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
                if (err == 0) {
                        nf_conntrack_get(&ct->ct_general);
                        spin_unlock_bh(&nf_conntrack_lock);
-                       nf_conntrack_event_report(IPCT_STATUS |
-                                                 IPCT_HELPER |
-                                                 IPCT_PROTOINFO |
-                                                 IPCT_NATSEQADJ |
-                                                 IPCT_MARK,
-                                                 ct, NETLINK_CB(skb).pid,
-                                                 nlmsg_report(nlh));
+                       nf_conntrack_eventmask_report((1 << IPCT_STATUS) |
+                                                     (1 << IPCT_HELPER) |
+                                                     (1 << IPCT_PROTOINFO) |
+                                                     (1 << IPCT_NATSEQADJ) |
+                                                     (1 << IPCT_MARK),
+                                                     ct, NETLINK_CB(skb).pid,
+                                                     nlmsg_report(nlh));
                        nf_ct_put(ct);
                } else
                        spin_unlock_bh(&nf_conntrack_lock);
@@ -1503,19 +1486,18 @@ nla_put_failure:
 
 static int
 ctnetlink_exp_fill_info(struct sk_buff *skb, u32 pid, u32 seq,
-                   int event,
-                   int nowait,
-                   const struct nf_conntrack_expect *exp)
+                       int event, const struct nf_conntrack_expect *exp)
 {
        struct nlmsghdr *nlh;
        struct nfgenmsg *nfmsg;
-       unsigned char *b = skb_tail_pointer(skb);
+       unsigned int flags = pid ? NLM_F_MULTI : 0;
 
        event |= NFNL_SUBSYS_CTNETLINK_EXP << 8;
-       nlh    = NLMSG_PUT(skb, pid, seq, event, sizeof(struct nfgenmsg));
-       nfmsg  = NLMSG_DATA(nlh);
+       nlh = nlmsg_put(skb, pid, seq, event, sizeof(*nfmsg), flags);
+       if (nlh == NULL)
+               goto nlmsg_failure;
 
-       nlh->nlmsg_flags    = (nowait && pid) ? NLM_F_MULTI : 0;
+       nfmsg = nlmsg_data(nlh);
        nfmsg->nfgen_family = exp->tuple.src.l3num;
        nfmsg->version      = NFNETLINK_V0;
        nfmsg->res_id       = 0;
@@ -1523,49 +1505,46 @@ ctnetlink_exp_fill_info(struct sk_buff *skb, u32 pid, u32 seq,
        if (ctnetlink_exp_dump_expect(skb, exp) < 0)
                goto nla_put_failure;
 
-       nlh->nlmsg_len = skb_tail_pointer(skb) - b;
+       nlmsg_end(skb, nlh);
        return skb->len;
 
 nlmsg_failure:
 nla_put_failure:
-       nlmsg_trim(skb, b);
+       nlmsg_cancel(skb, nlh);
        return -1;
 }
 
 #ifdef CONFIG_NF_CONNTRACK_EVENTS
-static int ctnetlink_expect_event(struct notifier_block *this,
-                                 unsigned long events, void *ptr)
+static int
+ctnetlink_expect_event(unsigned int events, struct nf_exp_event *item)
 {
        struct nlmsghdr *nlh;
        struct nfgenmsg *nfmsg;
-       struct nf_exp_event *item = (struct nf_exp_event *)ptr;
        struct nf_conntrack_expect *exp = item->exp;
        struct sk_buff *skb;
        unsigned int type;
-       sk_buff_data_t b;
        int flags = 0;
 
-       if (events & IPEXP_NEW) {
+       if (events & (1 << IPEXP_NEW)) {
                type = IPCTNL_MSG_EXP_NEW;
                flags = NLM_F_CREATE|NLM_F_EXCL;
        } else
-               return NOTIFY_DONE;
+               return 0;
 
        if (!item->report &&
            !nfnetlink_has_listeners(NFNLGRP_CONNTRACK_EXP_NEW))
-               return NOTIFY_DONE;
+               return 0;
 
-       skb = alloc_skb(NLMSG_GOODSIZE, GFP_ATOMIC);
-       if (!skb)
+       skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
+       if (skb == NULL)
                goto errout;
 
-       b = skb->tail;
-
        type |= NFNL_SUBSYS_CTNETLINK_EXP << 8;
-       nlh   = NLMSG_PUT(skb, item->pid, 0, type, sizeof(struct nfgenmsg));
-       nfmsg = NLMSG_DATA(nlh);
+       nlh = nlmsg_put(skb, item->pid, 0, type, sizeof(*nfmsg), flags);
+       if (nlh == NULL)
+               goto nlmsg_failure;
 
-       nlh->nlmsg_flags    = flags;
+       nfmsg = nlmsg_data(nlh);
        nfmsg->nfgen_family = exp->tuple.src.l3num;
        nfmsg->version      = NFNETLINK_V0;
        nfmsg->res_id       = 0;
@@ -1575,17 +1554,19 @@ static int ctnetlink_expect_event(struct notifier_block *this,
                goto nla_put_failure;
        rcu_read_unlock();
 
-       nlh->nlmsg_len = skb->tail - b;
-       nfnetlink_send(skb, item->pid, NFNLGRP_CONNTRACK_EXP_NEW, item->report);
-       return NOTIFY_DONE;
+       nlmsg_end(skb, nlh);
+       nfnetlink_send(skb, item->pid, NFNLGRP_CONNTRACK_EXP_NEW,
+                      item->report, GFP_ATOMIC);
+       return 0;
 
 nla_put_failure:
        rcu_read_unlock();
+       nlmsg_cancel(skb, nlh);
 nlmsg_failure:
        kfree_skb(skb);
 errout:
        nfnetlink_set_err(0, 0, -ENOBUFS);
-       return NOTIFY_DONE;
+       return 0;
 }
 #endif
 static int ctnetlink_exp_done(struct netlink_callback *cb)
@@ -1600,7 +1581,7 @@ ctnetlink_exp_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
 {
        struct net *net = &init_net;
        struct nf_conntrack_expect *exp, *last;
-       struct nfgenmsg *nfmsg = NLMSG_DATA(cb->nlh);
+       struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
        struct hlist_node *n;
        u_int8_t l3proto = nfmsg->nfgen_family;
 
@@ -1617,10 +1598,11 @@ restart:
                                        continue;
                                cb->args[1] = 0;
                        }
-                       if (ctnetlink_exp_fill_info(skb, NETLINK_CB(cb->skb).pid,
+                       if (ctnetlink_exp_fill_info(skb,
+                                                   NETLINK_CB(cb->skb).pid,
                                                    cb->nlh->nlmsg_seq,
                                                    IPCTNL_MSG_EXP_NEW,
-                                                   1, exp) < 0) {
+                                                   exp) < 0) {
                                if (!atomic_inc_not_zero(&exp->use))
                                        continue;
                                cb->args[1] = (unsigned long)exp;
@@ -1652,7 +1634,7 @@ ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb,
        struct nf_conntrack_tuple tuple;
        struct nf_conntrack_expect *exp;
        struct sk_buff *skb2;
-       struct nfgenmsg *nfmsg = NLMSG_DATA(nlh);
+       struct nfgenmsg *nfmsg = nlmsg_data(nlh);
        u_int8_t u3 = nfmsg->nfgen_family;
        int err = 0;
 
@@ -1683,14 +1665,13 @@ ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb,
        }
 
        err = -ENOMEM;
-       skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
-       if (!skb2)
+       skb2 = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+       if (skb2 == NULL)
                goto out;
 
        rcu_read_lock();
        err = ctnetlink_exp_fill_info(skb2, NETLINK_CB(skb).pid,
-                                     nlh->nlmsg_seq, IPCTNL_MSG_EXP_NEW,
-                                     1, exp);
+                                     nlh->nlmsg_seq, IPCTNL_MSG_EXP_NEW, exp);
        rcu_read_unlock();
        if (err <= 0)
                goto free;
@@ -1713,7 +1694,7 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
        struct nf_conntrack_expect *exp;
        struct nf_conntrack_tuple tuple;
        struct nf_conntrack_helper *h;
-       struct nfgenmsg *nfmsg = NLMSG_DATA(nlh);
+       struct nfgenmsg *nfmsg = nlmsg_data(nlh);
        struct hlist_node *n, *next;
        u_int8_t u3 = nfmsg->nfgen_family;
        unsigned int i;
@@ -1854,7 +1835,7 @@ ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb,
 {
        struct nf_conntrack_tuple tuple;
        struct nf_conntrack_expect *exp;
-       struct nfgenmsg *nfmsg = NLMSG_DATA(nlh);
+       struct nfgenmsg *nfmsg = nlmsg_data(nlh);
        u_int8_t u3 = nfmsg->nfgen_family;
        int err = 0;
 
@@ -1891,12 +1872,12 @@ ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb,
 }
 
 #ifdef CONFIG_NF_CONNTRACK_EVENTS
-static struct notifier_block ctnl_notifier = {
-       .notifier_call  = ctnetlink_conntrack_event,
+static struct nf_ct_event_notifier ctnl_notifier = {
+       .fcn = ctnetlink_conntrack_event,
 };
 
-static struct notifier_block ctnl_notifier_exp = {
-       .notifier_call  = ctnetlink_expect_event,
+static struct nf_exp_event_notifier ctnl_notifier_exp = {
+       .fcn = ctnetlink_expect_event,
 };
 #endif
 
index aee0d6bea309e969f4dc62604243531d542c8892..1b816a2ea813b9c2383aaf2bc5978692deee40f3 100644 (file)
@@ -25,8 +25,6 @@
 #include <net/netfilter/nf_conntrack_ecache.h>
 #include <net/netfilter/nf_log.h>
 
-static DEFINE_RWLOCK(dccp_lock);
-
 /* Timeouts are based on values from RFC4340:
  *
  * - REQUEST:
@@ -492,7 +490,7 @@ static int dccp_packet(struct nf_conn *ct, const struct sk_buff *skb,
                return NF_ACCEPT;
        }
 
-       write_lock_bh(&dccp_lock);
+       spin_lock_bh(&ct->lock);
 
        role = ct->proto.dccp.role[dir];
        old_state = ct->proto.dccp.state;
@@ -536,13 +534,13 @@ static int dccp_packet(struct nf_conn *ct, const struct sk_buff *skb,
                ct->proto.dccp.last_dir = dir;
                ct->proto.dccp.last_pkt = type;
 
-               write_unlock_bh(&dccp_lock);
+               spin_unlock_bh(&ct->lock);
                if (LOG_INVALID(net, IPPROTO_DCCP))
                        nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
                                      "nf_ct_dccp: invalid packet ignored ");
                return NF_ACCEPT;
        case CT_DCCP_INVALID:
-               write_unlock_bh(&dccp_lock);
+               spin_unlock_bh(&ct->lock);
                if (LOG_INVALID(net, IPPROTO_DCCP))
                        nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
                                      "nf_ct_dccp: invalid state transition ");
@@ -552,7 +550,7 @@ static int dccp_packet(struct nf_conn *ct, const struct sk_buff *skb,
        ct->proto.dccp.last_dir = dir;
        ct->proto.dccp.last_pkt = type;
        ct->proto.dccp.state = new_state;
-       write_unlock_bh(&dccp_lock);
+       spin_unlock_bh(&ct->lock);
 
        if (new_state != old_state)
                nf_conntrack_event_cache(IPCT_PROTOINFO, ct);
@@ -621,36 +619,39 @@ static int dccp_print_tuple(struct seq_file *s,
                          ntohs(tuple->dst.u.dccp.port));
 }
 
-static int dccp_print_conntrack(struct seq_file *s, const struct nf_conn *ct)
+static int dccp_print_conntrack(struct seq_file *s, struct nf_conn *ct)
 {
        return seq_printf(s, "%s ", dccp_state_names[ct->proto.dccp.state]);
 }
 
 #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
 static int dccp_to_nlattr(struct sk_buff *skb, struct nlattr *nla,
-                         const struct nf_conn *ct)
+                         struct nf_conn *ct)
 {
        struct nlattr *nest_parms;
 
-       read_lock_bh(&dccp_lock);
+       spin_lock_bh(&ct->lock);
        nest_parms = nla_nest_start(skb, CTA_PROTOINFO_DCCP | NLA_F_NESTED);
        if (!nest_parms)
                goto nla_put_failure;
        NLA_PUT_U8(skb, CTA_PROTOINFO_DCCP_STATE, ct->proto.dccp.state);
        NLA_PUT_U8(skb, CTA_PROTOINFO_DCCP_ROLE,
                   ct->proto.dccp.role[IP_CT_DIR_ORIGINAL]);
+       NLA_PUT_BE64(skb, CTA_PROTOINFO_DCCP_HANDSHAKE_SEQ,
+                    cpu_to_be64(ct->proto.dccp.handshake_seq));
        nla_nest_end(skb, nest_parms);
-       read_unlock_bh(&dccp_lock);
+       spin_unlock_bh(&ct->lock);
        return 0;
 
 nla_put_failure:
-       read_unlock_bh(&dccp_lock);
+       spin_unlock_bh(&ct->lock);
        return -1;
 }
 
 static const struct nla_policy dccp_nla_policy[CTA_PROTOINFO_DCCP_MAX + 1] = {
        [CTA_PROTOINFO_DCCP_STATE]      = { .type = NLA_U8 },
        [CTA_PROTOINFO_DCCP_ROLE]       = { .type = NLA_U8 },
+       [CTA_PROTOINFO_DCCP_HANDSHAKE_SEQ] = { .type = NLA_U64 },
 };
 
 static int nlattr_to_dccp(struct nlattr *cda[], struct nf_conn *ct)
@@ -674,7 +675,7 @@ static int nlattr_to_dccp(struct nlattr *cda[], struct nf_conn *ct)
                return -EINVAL;
        }
 
-       write_lock_bh(&dccp_lock);
+       spin_lock_bh(&ct->lock);
        ct->proto.dccp.state = nla_get_u8(tb[CTA_PROTOINFO_DCCP_STATE]);
        if (nla_get_u8(tb[CTA_PROTOINFO_DCCP_ROLE]) == CT_DCCP_ROLE_CLIENT) {
                ct->proto.dccp.role[IP_CT_DIR_ORIGINAL] = CT_DCCP_ROLE_CLIENT;
@@ -683,7 +684,11 @@ static int nlattr_to_dccp(struct nlattr *cda[], struct nf_conn *ct)
                ct->proto.dccp.role[IP_CT_DIR_ORIGINAL] = CT_DCCP_ROLE_SERVER;
                ct->proto.dccp.role[IP_CT_DIR_REPLY] = CT_DCCP_ROLE_CLIENT;
        }
-       write_unlock_bh(&dccp_lock);
+       if (tb[CTA_PROTOINFO_DCCP_HANDSHAKE_SEQ]) {
+               ct->proto.dccp.handshake_seq =
+               be64_to_cpu(nla_get_be64(tb[CTA_PROTOINFO_DCCP_HANDSHAKE_SEQ]));
+       }
+       spin_unlock_bh(&ct->lock);
        return 0;
 }
 
index 117b80112fcbd08f6c8effc4590d64f637a9bdbe..a54a0af0edbaa753fee5f65a80c84e95cd1b955e 100644 (file)
@@ -176,7 +176,7 @@ static bool gre_invert_tuple(struct nf_conntrack_tuple *tuple,
 static bool gre_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff,
                             struct nf_conntrack_tuple *tuple)
 {
-       struct net *net = dev_net(skb->dev ? skb->dev : skb->dst->dev);
+       struct net *net = dev_net(skb->dev ? skb->dev : skb_dst(skb)->dev);
        const struct gre_hdr_pptp *pgrehdr;
        struct gre_hdr_pptp _pgrehdr;
        __be16 srckey;
@@ -219,8 +219,7 @@ static int gre_print_tuple(struct seq_file *s,
 }
 
 /* print private data for conntrack */
-static int gre_print_conntrack(struct seq_file *s,
-                              const struct nf_conn *ct)
+static int gre_print_conntrack(struct seq_file *s, struct nf_conn *ct)
 {
        return seq_printf(s, "timeout=%u, stream_timeout=%u ",
                          (ct->proto.gre.timeout / HZ),
index 101b4ad9e817bc421393503d3b59e1a8d98f7918..c10e6f36e31e84801c85692a3524cead603f7684 100644 (file)
@@ -25,9 +25,6 @@
 #include <net/netfilter/nf_conntrack_l4proto.h>
 #include <net/netfilter/nf_conntrack_ecache.h>
 
-/* Protects ct->proto.sctp */
-static DEFINE_RWLOCK(sctp_lock);
-
 /* FIXME: Examine ipfilter's timeouts and conntrack transitions more
    closely.  They're more complex. --RR
 
@@ -164,13 +161,13 @@ static int sctp_print_tuple(struct seq_file *s,
 }
 
 /* Print out the private part of the conntrack. */
-static int sctp_print_conntrack(struct seq_file *s, const struct nf_conn *ct)
+static int sctp_print_conntrack(struct seq_file *s, struct nf_conn *ct)
 {
        enum sctp_conntrack state;
 
-       read_lock_bh(&sctp_lock);
+       spin_lock_bh(&ct->lock);
        state = ct->proto.sctp.state;
-       read_unlock_bh(&sctp_lock);
+       spin_unlock_bh(&ct->lock);
 
        return seq_printf(s, "%s ", sctp_conntrack_names[state]);
 }
@@ -318,7 +315,7 @@ static int sctp_packet(struct nf_conn *ct,
        }
 
        old_state = new_state = SCTP_CONNTRACK_NONE;
-       write_lock_bh(&sctp_lock);
+       spin_lock_bh(&ct->lock);
        for_each_sctp_chunk (skb, sch, _sch, offset, dataoff, count) {
                /* Special cases of Verification tag check (Sec 8.5.1) */
                if (sch->type == SCTP_CID_INIT) {
@@ -371,7 +368,7 @@ static int sctp_packet(struct nf_conn *ct,
                if (old_state != new_state)
                        nf_conntrack_event_cache(IPCT_PROTOINFO, ct);
        }
-       write_unlock_bh(&sctp_lock);
+       spin_unlock_bh(&ct->lock);
 
        nf_ct_refresh_acct(ct, ctinfo, skb, sctp_timeouts[new_state]);
 
@@ -386,7 +383,7 @@ static int sctp_packet(struct nf_conn *ct,
        return NF_ACCEPT;
 
 out_unlock:
-       write_unlock_bh(&sctp_lock);
+       spin_unlock_bh(&ct->lock);
 out:
        return -NF_ACCEPT;
 }
@@ -469,11 +466,11 @@ static bool sctp_new(struct nf_conn *ct, const struct sk_buff *skb,
 #include <linux/netfilter/nfnetlink_conntrack.h>
 
 static int sctp_to_nlattr(struct sk_buff *skb, struct nlattr *nla,
-                         const struct nf_conn *ct)
+                         struct nf_conn *ct)
 {
        struct nlattr *nest_parms;
 
-       read_lock_bh(&sctp_lock);
+       spin_lock_bh(&ct->lock);
        nest_parms = nla_nest_start(skb, CTA_PROTOINFO_SCTP | NLA_F_NESTED);
        if (!nest_parms)
                goto nla_put_failure;
@@ -488,14 +485,14 @@ static int sctp_to_nlattr(struct sk_buff *skb, struct nlattr *nla,
                     CTA_PROTOINFO_SCTP_VTAG_REPLY,
                     ct->proto.sctp.vtag[IP_CT_DIR_REPLY]);
 
-       read_unlock_bh(&sctp_lock);
+       spin_unlock_bh(&ct->lock);
 
        nla_nest_end(skb, nest_parms);
 
        return 0;
 
 nla_put_failure:
-       read_unlock_bh(&sctp_lock);
+       spin_unlock_bh(&ct->lock);
        return -1;
 }
 
@@ -527,13 +524,13 @@ static int nlattr_to_sctp(struct nlattr *cda[], struct nf_conn *ct)
            !tb[CTA_PROTOINFO_SCTP_VTAG_REPLY])
                return -EINVAL;
 
-       write_lock_bh(&sctp_lock);
+       spin_lock_bh(&ct->lock);
        ct->proto.sctp.state = nla_get_u8(tb[CTA_PROTOINFO_SCTP_STATE]);
        ct->proto.sctp.vtag[IP_CT_DIR_ORIGINAL] =
                nla_get_be32(tb[CTA_PROTOINFO_SCTP_VTAG_ORIGINAL]);
        ct->proto.sctp.vtag[IP_CT_DIR_REPLY] =
                nla_get_be32(tb[CTA_PROTOINFO_SCTP_VTAG_REPLY]);
-       write_unlock_bh(&sctp_lock);
+       spin_unlock_bh(&ct->lock);
 
        return 0;
 }
index 97a6e93d742e21281c13bc0d86355303ed3703e9..33fc0a443f3de755772f5be4f686c1f44adf9cb1 100644 (file)
@@ -29,9 +29,6 @@
 #include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
 #include <net/netfilter/ipv6/nf_conntrack_ipv6.h>
 
-/* Protects ct->proto.tcp */
-static DEFINE_RWLOCK(tcp_lock);
-
 /* "Be conservative in what you do,
     be liberal in what you accept from others."
     If it's non-zero, we mark only out of window RST segments as INVALID. */
@@ -59,7 +56,7 @@ static const char *const tcp_conntrack_names[] = {
        "LAST_ACK",
        "TIME_WAIT",
        "CLOSE",
-       "LISTEN"
+       "SYN_SENT2",
 };
 
 #define SECS * HZ
@@ -82,6 +79,7 @@ static unsigned int tcp_timeouts[TCP_CONNTRACK_MAX] __read_mostly = {
        [TCP_CONNTRACK_LAST_ACK]        = 30 SECS,
        [TCP_CONNTRACK_TIME_WAIT]       = 2 MINS,
        [TCP_CONNTRACK_CLOSE]           = 10 SECS,
+       [TCP_CONNTRACK_SYN_SENT2]       = 2 MINS,
 };
 
 #define sNO TCP_CONNTRACK_NONE
@@ -93,7 +91,7 @@ static unsigned int tcp_timeouts[TCP_CONNTRACK_MAX] __read_mostly = {
 #define sLA TCP_CONNTRACK_LAST_ACK
 #define sTW TCP_CONNTRACK_TIME_WAIT
 #define sCL TCP_CONNTRACK_CLOSE
-#define sLI TCP_CONNTRACK_LISTEN
+#define sS2 TCP_CONNTRACK_SYN_SENT2
 #define sIV TCP_CONNTRACK_MAX
 #define sIG TCP_CONNTRACK_IGNORE
 
@@ -123,6 +121,7 @@ enum tcp_bit_set {
  *
  * NONE:       initial state
  * SYN_SENT:   SYN-only packet seen
+ * SYN_SENT2:  SYN-only packet seen from reply dir, simultaneous open
  * SYN_RECV:   SYN-ACK packet seen
  * ESTABLISHED:        ACK packet seen
  * FIN_WAIT:   FIN packet seen
@@ -131,26 +130,24 @@ enum tcp_bit_set {
  * TIME_WAIT:  last ACK seen
  * CLOSE:      closed connection (RST)
  *
- * LISTEN state is not used.
- *
  * Packets marked as IGNORED (sIG):
  *     if they may be either invalid or valid
  *     and the receiver may send back a connection
  *     closing RST or a SYN/ACK.
  *
  * Packets marked as INVALID (sIV):
- *     if they are invalid
- *     or we do not support the request (simultaneous open)
+ *     if we regard them as truly invalid packets
  */
 static const u8 tcp_conntracks[2][6][TCP_CONNTRACK_MAX] = {
        {
 /* ORIGINAL */
-/*          sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI   */
-/*syn*/           { sSS, sSS, sIG, sIG, sIG, sIG, sIG, sSS, sSS, sIV },
+/*          sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sS2   */
+/*syn*/           { sSS, sSS, sIG, sIG, sIG, sIG, sIG, sSS, sSS, sS2 },
 /*
  *     sNO -> sSS      Initialize a new connection
  *     sSS -> sSS      Retransmitted SYN
- *     sSR -> sIG      Late retransmitted SYN?
+ *     sS2 -> sS2      Late retransmitted SYN
+ *     sSR -> sIG
  *     sES -> sIG      Error: SYNs in window outside the SYN_SENT state
  *                     are errors. Receiver will reply with RST
  *                     and close the connection.
@@ -161,22 +158,30 @@ static const u8 tcp_conntracks[2][6][TCP_CONNTRACK_MAX] = {
  *     sTW -> sSS      Reopened connection (RFC 1122).
  *     sCL -> sSS
  */
-/*          sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI   */
-/*synack*/ { sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV },
+/*          sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sS2   */
+/*synack*/ { sIV, sIV, sIG, sIG, sIG, sIG, sIG, sIG, sIG, sSR },
 /*
- * A SYN/ACK from the client is always invalid:
- *     - either it tries to set up a simultaneous open, which is
- *       not supported;
- *     - or the firewall has just been inserted between the two hosts
- *       during the session set-up. The SYN will be retransmitted
- *       by the true client (or it'll time out).
+ *     sNO -> sIV      Too late and no reason to do anything
+ *     sSS -> sIV      Client can't send SYN and then SYN/ACK
+ *     sS2 -> sSR      SYN/ACK sent to SYN2 in simultaneous open
+ *     sSR -> sIG
+ *     sES -> sIG      Error: SYNs in window outside the SYN_SENT state
+ *                     are errors. Receiver will reply with RST
+ *                     and close the connection.
+ *                     Or we are not in sync and hold a dead connection.
+ *     sFW -> sIG
+ *     sCW -> sIG
+ *     sLA -> sIG
+ *     sTW -> sIG
+ *     sCL -> sIG
  */
-/*          sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI   */
+/*          sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sS2   */
 /*fin*/    { sIV, sIV, sFW, sFW, sLA, sLA, sLA, sTW, sCL, sIV },
 /*
  *     sNO -> sIV      Too late and no reason to do anything...
  *     sSS -> sIV      Client migth not send FIN in this state:
  *                     we enforce waiting for a SYN/ACK reply first.
+ *     sS2 -> sIV
  *     sSR -> sFW      Close started.
  *     sES -> sFW
  *     sFW -> sLA      FIN seen in both directions, waiting for
@@ -187,11 +192,12 @@ static const u8 tcp_conntracks[2][6][TCP_CONNTRACK_MAX] = {
  *     sTW -> sTW
  *     sCL -> sCL
  */
-/*          sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI   */
+/*          sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sS2   */
 /*ack*/           { sES, sIV, sES, sES, sCW, sCW, sTW, sTW, sCL, sIV },
 /*
  *     sNO -> sES      Assumed.
  *     sSS -> sIV      ACK is invalid: we haven't seen a SYN/ACK yet.
+ *     sS2 -> sIV
  *     sSR -> sES      Established state is reached.
  *     sES -> sES      :-)
  *     sFW -> sCW      Normal close request answered by ACK.
@@ -200,29 +206,31 @@ static const u8 tcp_conntracks[2][6][TCP_CONNTRACK_MAX] = {
  *     sTW -> sTW      Retransmitted last ACK. Remain in the same state.
  *     sCL -> sCL
  */
-/*          sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI   */
-/*rst*/    { sIV, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sIV },
+/*          sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sS2   */
+/*rst*/    { sIV, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL },
 /*none*/   { sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV }
        },
        {
 /* REPLY */
-/*          sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI   */
-/*syn*/           { sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV },
+/*          sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sS2   */
+/*syn*/           { sIV, sS2, sIV, sIV, sIV, sIV, sIV, sIV, sIV, sS2 },
 /*
  *     sNO -> sIV      Never reached.
- *     sSS -> sIV      Simultaneous open, not supported
- *     sSR -> sIV      Simultaneous open, not supported.
- *     sES -> sIV      Server may not initiate a connection.
+ *     sSS -> sS2      Simultaneous open
+ *     sS2 -> sS2      Retransmitted simultaneous SYN
+ *     sSR -> sIV      Invalid SYN packets sent by the server
+ *     sES -> sIV
  *     sFW -> sIV
  *     sCW -> sIV
  *     sLA -> sIV
  *     sTW -> sIV      Reopened connection, but server may not do it.
  *     sCL -> sIV
  */
-/*          sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI   */
-/*synack*/ { sIV, sSR, sSR, sIG, sIG, sIG, sIG, sIG, sIG, sIV },
+/*          sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sS2   */
+/*synack*/ { sIV, sSR, sSR, sIG, sIG, sIG, sIG, sIG, sIG, sSR },
 /*
  *     sSS -> sSR      Standard open.
+ *     sS2 -> sSR      Simultaneous open
  *     sSR -> sSR      Retransmitted SYN/ACK.
  *     sES -> sIG      Late retransmitted SYN/ACK?
  *     sFW -> sIG      Might be SYN/ACK answering ignored SYN
@@ -231,10 +239,11 @@ static const u8 tcp_conntracks[2][6][TCP_CONNTRACK_MAX] = {
  *     sTW -> sIG
  *     sCL -> sIG
  */
-/*          sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI   */
+/*          sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sS2   */
 /*fin*/    { sIV, sIV, sFW, sFW, sLA, sLA, sLA, sTW, sCL, sIV },
 /*
  *     sSS -> sIV      Server might not send FIN in this state.
+ *     sS2 -> sIV
  *     sSR -> sFW      Close started.
  *     sES -> sFW
  *     sFW -> sLA      FIN seen in both directions.
@@ -243,10 +252,11 @@ static const u8 tcp_conntracks[2][6][TCP_CONNTRACK_MAX] = {
  *     sTW -> sTW
  *     sCL -> sCL
  */
-/*          sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI   */
-/*ack*/           { sIV, sIG, sSR, sES, sCW, sCW, sTW, sTW, sCL, sIV },
+/*          sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sS2   */
+/*ack*/           { sIV, sIG, sSR, sES, sCW, sCW, sTW, sTW, sCL, sIG },
 /*
  *     sSS -> sIG      Might be a half-open connection.
+ *     sS2 -> sIG
  *     sSR -> sSR      Might answer late resent SYN.
  *     sES -> sES      :-)
  *     sFW -> sCW      Normal close request answered by ACK.
@@ -255,8 +265,8 @@ static const u8 tcp_conntracks[2][6][TCP_CONNTRACK_MAX] = {
  *     sTW -> sTW      Retransmitted last ACK.
  *     sCL -> sCL
  */
-/*          sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI   */
-/*rst*/    { sIV, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sIV },
+/*          sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sS2   */
+/*rst*/    { sIV, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL },
 /*none*/   { sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV, sIV }
        }
 };
@@ -296,13 +306,13 @@ static int tcp_print_tuple(struct seq_file *s,
 }
 
 /* Print out the private part of the conntrack. */
-static int tcp_print_conntrack(struct seq_file *s, const struct nf_conn *ct)
+static int tcp_print_conntrack(struct seq_file *s, struct nf_conn *ct)
 {
        enum tcp_conntrack state;
 
-       read_lock_bh(&tcp_lock);
+       spin_lock_bh(&ct->lock);
        state = ct->proto.tcp.state;
-       read_unlock_bh(&tcp_lock);
+       spin_unlock_bh(&ct->lock);
 
        return seq_printf(s, "%s ", tcp_conntrack_names[state]);
 }
@@ -521,13 +531,14 @@ static bool tcp_in_window(const struct nf_conn *ct,
                 receiver->td_end, receiver->td_maxend, receiver->td_maxwin,
                 receiver->td_scale);
 
-       if (sender->td_end == 0) {
+       if (sender->td_maxwin == 0) {
                /*
                 * Initialize sender data.
                 */
-               if (tcph->syn && tcph->ack) {
+               if (tcph->syn) {
                        /*
-                        * Outgoing SYN-ACK in reply to a SYN.
+                        * SYN-ACK in reply to a SYN
+                        * or SYN from reply direction in simultaneous open.
                         */
                        sender->td_end =
                        sender->td_maxend = end;
@@ -543,6 +554,9 @@ static bool tcp_in_window(const struct nf_conn *ct,
                              && receiver->flags & IP_CT_TCP_FLAG_WINDOW_SCALE))
                                sender->td_scale =
                                receiver->td_scale = 0;
+                       if (!tcph->ack)
+                               /* Simultaneous open */
+                               return true;
                } else {
                        /*
                         * We are in the middle of a connection,
@@ -716,14 +730,14 @@ void nf_conntrack_tcp_update(const struct sk_buff *skb,
 
        end = segment_seq_plus_len(ntohl(tcph->seq), skb->len, dataoff, tcph);
 
-       write_lock_bh(&tcp_lock);
+       spin_lock_bh(&ct->lock);
        /*
         * We have to worry for the ack in the reply packet only...
         */
        if (after(end, ct->proto.tcp.seen[dir].td_end))
                ct->proto.tcp.seen[dir].td_end = end;
        ct->proto.tcp.last_end = end;
-       write_unlock_bh(&tcp_lock);
+       spin_unlock_bh(&ct->lock);
        pr_debug("tcp_update: sender end=%u maxend=%u maxwin=%u scale=%i "
                 "receiver end=%u maxend=%u maxwin=%u scale=%i\n",
                 sender->td_end, sender->td_maxend, sender->td_maxwin,
@@ -832,7 +846,7 @@ static int tcp_packet(struct nf_conn *ct,
        th = skb_header_pointer(skb, dataoff, sizeof(_tcph), &_tcph);
        BUG_ON(th == NULL);
 
-       write_lock_bh(&tcp_lock);
+       spin_lock_bh(&ct->lock);
        old_state = ct->proto.tcp.state;
        dir = CTINFO2DIR(ctinfo);
        index = get_conntrack_index(th);
@@ -862,7 +876,7 @@ static int tcp_packet(struct nf_conn *ct,
                        && ct->proto.tcp.last_index == TCP_RST_SET)) {
                        /* Attempt to reopen a closed/aborted connection.
                         * Delete this connection and look up again. */
-                       write_unlock_bh(&tcp_lock);
+                       spin_unlock_bh(&ct->lock);
 
                        /* Only repeat if we can actually remove the timer.
                         * Destruction may already be in progress in process
@@ -898,7 +912,7 @@ static int tcp_packet(struct nf_conn *ct,
                         * that the client cannot but retransmit its SYN and
                         * thus initiate a clean new session.
                         */
-                       write_unlock_bh(&tcp_lock);
+                       spin_unlock_bh(&ct->lock);
                        if (LOG_INVALID(net, IPPROTO_TCP))
                                nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
                                          "nf_ct_tcp: killing out of sync session ");
@@ -911,7 +925,7 @@ static int tcp_packet(struct nf_conn *ct,
                ct->proto.tcp.last_end =
                    segment_seq_plus_len(ntohl(th->seq), skb->len, dataoff, th);
 
-               write_unlock_bh(&tcp_lock);
+               spin_unlock_bh(&ct->lock);
                if (LOG_INVALID(net, IPPROTO_TCP))
                        nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
                                  "nf_ct_tcp: invalid packet ignored ");
@@ -920,7 +934,7 @@ static int tcp_packet(struct nf_conn *ct,
                /* Invalid packet */
                pr_debug("nf_ct_tcp: Invalid dir=%i index=%u ostate=%u\n",
                         dir, get_conntrack_index(th), old_state);
-               write_unlock_bh(&tcp_lock);
+               spin_unlock_bh(&ct->lock);
                if (LOG_INVALID(net, IPPROTO_TCP))
                        nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
                                  "nf_ct_tcp: invalid state ");
@@ -930,7 +944,7 @@ static int tcp_packet(struct nf_conn *ct,
                    && (ct->proto.tcp.seen[!dir].flags & IP_CT_TCP_FLAG_MAXACK_SET)
                    && before(ntohl(th->seq), ct->proto.tcp.seen[!dir].td_maxack)) {
                        /* Invalid RST  */
-                       write_unlock_bh(&tcp_lock);
+                       spin_unlock_bh(&ct->lock);
                        if (LOG_INVALID(net, IPPROTO_TCP))
                                nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
                                          "nf_ct_tcp: invalid RST ");
@@ -961,7 +975,7 @@ static int tcp_packet(struct nf_conn *ct,
 
        if (!tcp_in_window(ct, &ct->proto.tcp, dir, index,
                           skb, dataoff, th, pf)) {
-               write_unlock_bh(&tcp_lock);
+               spin_unlock_bh(&ct->lock);
                return -NF_ACCEPT;
        }
      in_window:
@@ -990,9 +1004,8 @@ static int tcp_packet(struct nf_conn *ct,
                timeout = nf_ct_tcp_timeout_unacknowledged;
        else
                timeout = tcp_timeouts[new_state];
-       write_unlock_bh(&tcp_lock);
+       spin_unlock_bh(&ct->lock);
 
-       nf_conntrack_event_cache(IPCT_PROTOINFO_VOLATILE, ct);
        if (new_state != old_state)
                nf_conntrack_event_cache(IPCT_PROTOINFO, ct);
 
@@ -1086,7 +1099,7 @@ static bool tcp_new(struct nf_conn *ct, const struct sk_buff *skb,
 
        ct->proto.tcp.seen[1].td_end = 0;
        ct->proto.tcp.seen[1].td_maxend = 0;
-       ct->proto.tcp.seen[1].td_maxwin = 1;
+       ct->proto.tcp.seen[1].td_maxwin = 0;
        ct->proto.tcp.seen[1].td_scale = 0;
 
        /* tcp_packet will set them */
@@ -1108,12 +1121,12 @@ static bool tcp_new(struct nf_conn *ct, const struct sk_buff *skb,
 #include <linux/netfilter/nfnetlink_conntrack.h>
 
 static int tcp_to_nlattr(struct sk_buff *skb, struct nlattr *nla,
-                        const struct nf_conn *ct)
+                        struct nf_conn *ct)
 {
        struct nlattr *nest_parms;
        struct nf_ct_tcp_flags tmp = {};
 
-       read_lock_bh(&tcp_lock);
+       spin_lock_bh(&ct->lock);
        nest_parms = nla_nest_start(skb, CTA_PROTOINFO_TCP | NLA_F_NESTED);
        if (!nest_parms)
                goto nla_put_failure;
@@ -1133,14 +1146,14 @@ static int tcp_to_nlattr(struct sk_buff *skb, struct nlattr *nla,
        tmp.flags = ct->proto.tcp.seen[1].flags;
        NLA_PUT(skb, CTA_PROTOINFO_TCP_FLAGS_REPLY,
                sizeof(struct nf_ct_tcp_flags), &tmp);
-       read_unlock_bh(&tcp_lock);
+       spin_unlock_bh(&ct->lock);
 
        nla_nest_end(skb, nest_parms);
 
        return 0;
 
 nla_put_failure:
-       read_unlock_bh(&tcp_lock);
+       spin_unlock_bh(&ct->lock);
        return -1;
 }
 
@@ -1171,7 +1184,7 @@ static int nlattr_to_tcp(struct nlattr *cda[], struct nf_conn *ct)
            nla_get_u8(tb[CTA_PROTOINFO_TCP_STATE]) >= TCP_CONNTRACK_MAX)
                return -EINVAL;
 
-       write_lock_bh(&tcp_lock);
+       spin_lock_bh(&ct->lock);
        if (tb[CTA_PROTOINFO_TCP_STATE])
                ct->proto.tcp.state = nla_get_u8(tb[CTA_PROTOINFO_TCP_STATE]);
 
@@ -1198,7 +1211,7 @@ static int nlattr_to_tcp(struct nlattr *cda[], struct nf_conn *ct)
                ct->proto.tcp.seen[1].td_scale =
                        nla_get_u8(tb[CTA_PROTOINFO_TCP_WSCALE_REPLY]);
        }
-       write_unlock_bh(&tcp_lock);
+       spin_unlock_bh(&ct->lock);
 
        return 0;
 }
@@ -1327,6 +1340,13 @@ static struct ctl_table tcp_compat_sysctl_table[] = {
                .mode           = 0644,
                .proc_handler   = proc_dointvec_jiffies,
        },
+       {
+               .procname       = "ip_conntrack_tcp_timeout_syn_sent2",
+               .data           = &tcp_timeouts[TCP_CONNTRACK_SYN_SENT2],
+               .maxlen         = sizeof(unsigned int),
+               .mode           = 0644,
+               .proc_handler   = proc_dointvec_jiffies,
+       },
        {
                .procname       = "ip_conntrack_tcp_timeout_syn_recv",
                .data           = &tcp_timeouts[TCP_CONNTRACK_SYN_RECV],
index beb37311e1a5c3d3c20972d4bab070010572083d..2fefe147750a09b2f8d94f0e78f3b5f35e5b08b0 100644 (file)
@@ -248,14 +248,14 @@ static int nf_log_proc_dostring(ctl_table *table, int write, struct file *filp,
                rcu_assign_pointer(nf_loggers[tindex], logger);
                mutex_unlock(&nf_log_mutex);
        } else {
-               rcu_read_lock();
-               logger = rcu_dereference(nf_loggers[tindex]);
+               mutex_lock(&nf_log_mutex);
+               logger = nf_loggers[tindex];
                if (!logger)
                        table->data = "NONE";
                else
                        table->data = logger->name;
                r = proc_dostring(table, write, filp, buffer, lenp, ppos);
-               rcu_read_unlock();
+               mutex_unlock(&nf_log_mutex);
        }
 
        return r;
index 4f2310c93e015fb4350d4d641faf0b204010951a..3a6fd77f7761903ac46f83c77a49fd7bd58976d7 100644 (file)
@@ -204,10 +204,10 @@ int nf_queue(struct sk_buff *skb,
                                  queuenum);
 
        switch (pf) {
-       case AF_INET:
+       case NFPROTO_IPV4:
                skb->protocol = htons(ETH_P_IP);
                break;
-       case AF_INET6:
+       case NFPROTO_IPV6:
                skb->protocol = htons(ETH_P_IPV6);
                break;
        }
index b8ab37ad7ed56f60978d3827c31d722654c74fe0..92761a9883751ce2f266c5c8881c7074a94a07c0 100644 (file)
@@ -107,9 +107,10 @@ int nfnetlink_has_listeners(unsigned int group)
 }
 EXPORT_SYMBOL_GPL(nfnetlink_has_listeners);
 
-int nfnetlink_send(struct sk_buff *skb, u32 pid, unsigned group, int echo)
+int nfnetlink_send(struct sk_buff *skb, u32 pid,
+                  unsigned group, int echo, gfp_t flags)
 {
-       return nlmsg_notify(nfnl, skb, pid, group, echo, gfp_any());
+       return nlmsg_notify(nfnl, skb, pid, group, echo, flags);
 }
 EXPORT_SYMBOL_GPL(nfnetlink_send);
 
@@ -136,7 +137,7 @@ static int nfnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
                return -EPERM;
 
        /* All the messages must at least contain nfgenmsg */
-       if (nlh->nlmsg_len < NLMSG_SPACE(sizeof(struct nfgenmsg)))
+       if (nlh->nlmsg_len < NLMSG_LENGTH(sizeof(struct nfgenmsg)))
                return 0;
 
        type = nlh->nlmsg_type;
@@ -160,19 +161,14 @@ replay:
        {
                int min_len = NLMSG_SPACE(sizeof(struct nfgenmsg));
                u_int8_t cb_id = NFNL_MSG_TYPE(nlh->nlmsg_type);
-               u_int16_t attr_count = ss->cb[cb_id].attr_count;
-               struct nlattr *cda[attr_count+1];
-
-               if (likely(nlh->nlmsg_len >= min_len)) {
-                       struct nlattr *attr = (void *)nlh + NLMSG_ALIGN(min_len);
-                       int attrlen = nlh->nlmsg_len - NLMSG_ALIGN(min_len);
-
-                       err = nla_parse(cda, attr_count, attr, attrlen,
-                                       ss->cb[cb_id].policy);
-                       if (err < 0)
-                               return err;
-               } else
-                       return -EINVAL;
+               struct nlattr *cda[ss->cb[cb_id].attr_count + 1];
+               struct nlattr *attr = (void *)nlh + min_len;
+               int attrlen = nlh->nlmsg_len - min_len;
+
+               err = nla_parse(cda, ss->cb[cb_id].attr_count,
+                               attr, attrlen, ss->cb[cb_id].policy);
+               if (err < 0)
+                       return err;
 
                err = nc->call(nfnl, skb, nlh, cda);
                if (err == -EAGAIN)
index 8c860112ce05e85549caf068fb0d670e98d99328..71daa0934b6c4a2622d7b595e7f7efd4076fd21a 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * This is a module which is used for queueing packets and communicating with
- * userspace via nfetlink.
+ * userspace via nfnetlink.
  *
  * (C) 2005 by Harald Welte <laforge@netfilter.org>
  * (C) 2007 by Patrick McHardy <kaber@trash.net>
@@ -932,6 +932,8 @@ static void __exit nfnetlink_queue_fini(void)
 #endif
        nfnetlink_subsys_unregister(&nfqnl_subsys);
        netlink_unregister_notifier(&nfqnl_rtnl_notifier);
+
+       rcu_barrier(); /* Wait for completion of call_rcu()'s */
 }
 
 MODULE_DESCRIPTION("netfilter packet queue handler");
index 150e5cf62f8531d98b99fa4b04d2842238f149ba..025d1a0af78b43c14a38cc0c5b406b36dd5887f5 100644 (file)
@@ -329,6 +329,32 @@ int xt_find_revision(u8 af, const char *name, u8 revision, int target,
 }
 EXPORT_SYMBOL_GPL(xt_find_revision);
 
+static char *textify_hooks(char *buf, size_t size, unsigned int mask)
+{
+       static const char *const names[] = {
+               "PREROUTING", "INPUT", "FORWARD",
+               "OUTPUT", "POSTROUTING", "BROUTING",
+       };
+       unsigned int i;
+       char *p = buf;
+       bool np = false;
+       int res;
+
+       *p = '\0';
+       for (i = 0; i < ARRAY_SIZE(names); ++i) {
+               if (!(mask & (1 << i)))
+                       continue;
+               res = snprintf(p, size, "%s%s", np ? "/" : "", names[i]);
+               if (res > 0) {
+                       size -= res;
+                       p += res;
+               }
+               np = true;
+       }
+
+       return buf;
+}
+
 int xt_check_match(struct xt_mtchk_param *par,
                   unsigned int size, u_int8_t proto, bool inv_proto)
 {
@@ -338,26 +364,30 @@ int xt_check_match(struct xt_mtchk_param *par,
                 * ebt_among is exempt from centralized matchsize checking
                 * because it uses a dynamic-size data set.
                 */
-               printk("%s_tables: %s match: invalid size %Zu != %u\n",
+               pr_err("%s_tables: %s match: invalid size %Zu != %u\n",
                       xt_prefix[par->family], par->match->name,
                       XT_ALIGN(par->match->matchsize), size);
                return -EINVAL;
        }
        if (par->match->table != NULL &&
            strcmp(par->match->table, par->table) != 0) {
-               printk("%s_tables: %s match: only valid in %s table, not %s\n",
+               pr_err("%s_tables: %s match: only valid in %s table, not %s\n",
                       xt_prefix[par->family], par->match->name,
                       par->match->table, par->table);
                return -EINVAL;
        }
        if (par->match->hooks && (par->hook_mask & ~par->match->hooks) != 0) {
-               printk("%s_tables: %s match: bad hook_mask %#x/%#x\n",
+               char used[64], allow[64];
+
+               pr_err("%s_tables: %s match: used from hooks %s, but only "
+                      "valid from %s\n",
                       xt_prefix[par->family], par->match->name,
-                      par->hook_mask, par->match->hooks);
+                      textify_hooks(used, sizeof(used), par->hook_mask),
+                      textify_hooks(allow, sizeof(allow), par->match->hooks));
                return -EINVAL;
        }
        if (par->match->proto && (par->match->proto != proto || inv_proto)) {
-               printk("%s_tables: %s match: only valid for protocol %u\n",
+               pr_err("%s_tables: %s match: only valid for protocol %u\n",
                       xt_prefix[par->family], par->match->name,
                       par->match->proto);
                return -EINVAL;
@@ -484,26 +514,30 @@ int xt_check_target(struct xt_tgchk_param *par,
                    unsigned int size, u_int8_t proto, bool inv_proto)
 {
        if (XT_ALIGN(par->target->targetsize) != size) {
-               printk("%s_tables: %s target: invalid size %Zu != %u\n",
+               pr_err("%s_tables: %s target: invalid size %Zu != %u\n",
                       xt_prefix[par->family], par->target->name,
                       XT_ALIGN(par->target->targetsize), size);
                return -EINVAL;
        }
        if (par->target->table != NULL &&
            strcmp(par->target->table, par->table) != 0) {
-               printk("%s_tables: %s target: only valid in %s table, not %s\n",
+               pr_err("%s_tables: %s target: only valid in %s table, not %s\n",
                       xt_prefix[par->family], par->target->name,
                       par->target->table, par->table);
                return -EINVAL;
        }
        if (par->target->hooks && (par->hook_mask & ~par->target->hooks) != 0) {
-               printk("%s_tables: %s target: bad hook_mask %#x/%#x\n",
+               char used[64], allow[64];
+
+               pr_err("%s_tables: %s target: used from hooks %s, but only "
+                      "usable from %s\n",
                       xt_prefix[par->family], par->target->name,
-                      par->hook_mask, par->target->hooks);
+                      textify_hooks(used, sizeof(used), par->hook_mask),
+                      textify_hooks(allow, sizeof(allow), par->target->hooks));
                return -EINVAL;
        }
        if (par->target->proto && (par->target->proto != proto || inv_proto)) {
-               printk("%s_tables: %s target: only valid for protocol %u\n",
+               pr_err("%s_tables: %s target: only valid for protocol %u\n",
                       xt_prefix[par->family], par->target->name,
                       par->target->proto);
                return -EINVAL;
index f9977b3311f75692239c2f7c32ca7a417ed3eddb..498b45101df7f820e8bd97d6612406811d59afaf 100644 (file)
 #include <linux/module.h>
 #include <linux/skbuff.h>
 
+#include <linux/ip.h>
+#include <linux/ipv6.h>
+#include <linux/jhash.h>
+
 #include <linux/netfilter.h>
 #include <linux/netfilter_arp.h>
 #include <linux/netfilter/x_tables.h>
@@ -23,6 +27,8 @@ MODULE_ALIAS("ipt_NFQUEUE");
 MODULE_ALIAS("ip6t_NFQUEUE");
 MODULE_ALIAS("arpt_NFQUEUE");
 
+static u32 jhash_initval __read_mostly;
+
 static unsigned int
 nfqueue_tg(struct sk_buff *skb, const struct xt_target_param *par)
 {
@@ -31,32 +37,105 @@ nfqueue_tg(struct sk_buff *skb, const struct xt_target_param *par)
        return NF_QUEUE_NR(tinfo->queuenum);
 }
 
+static u32 hash_v4(const struct sk_buff *skb)
+{
+       const struct iphdr *iph = ip_hdr(skb);
+       u32 ipaddr;
+
+       /* packets in either direction go into same queue */
+       ipaddr = iph->saddr ^ iph->daddr;
+
+       return jhash_2words(ipaddr, iph->protocol, jhash_initval);
+}
+
+static unsigned int
+nfqueue_tg4_v1(struct sk_buff *skb, const struct xt_target_param *par)
+{
+       const struct xt_NFQ_info_v1 *info = par->targinfo;
+       u32 queue = info->queuenum;
+
+       if (info->queues_total > 1)
+               queue = hash_v4(skb) % info->queues_total + queue;
+       return NF_QUEUE_NR(queue);
+}
+
+#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
+static u32 hash_v6(const struct sk_buff *skb)
+{
+       const struct ipv6hdr *ip6h = ipv6_hdr(skb);
+       u32 addr[4];
+
+       addr[0] = ip6h->saddr.s6_addr32[0] ^ ip6h->daddr.s6_addr32[0];
+       addr[1] = ip6h->saddr.s6_addr32[1] ^ ip6h->daddr.s6_addr32[1];
+       addr[2] = ip6h->saddr.s6_addr32[2] ^ ip6h->daddr.s6_addr32[2];
+       addr[3] = ip6h->saddr.s6_addr32[3] ^ ip6h->daddr.s6_addr32[3];
+
+       return jhash2(addr, ARRAY_SIZE(addr), jhash_initval);
+}
+
+static unsigned int
+nfqueue_tg6_v1(struct sk_buff *skb, const struct xt_target_param *par)
+{
+       const struct xt_NFQ_info_v1 *info = par->targinfo;
+       u32 queue = info->queuenum;
+
+       if (info->queues_total > 1)
+               queue = hash_v6(skb) % info->queues_total + queue;
+       return NF_QUEUE_NR(queue);
+}
+#endif
+
+static bool nfqueue_tg_v1_check(const struct xt_tgchk_param *par)
+{
+       const struct xt_NFQ_info_v1 *info = par->targinfo;
+       u32 maxid;
+
+       if (info->queues_total == 0) {
+               pr_err("NFQUEUE: number of total queues is 0\n");
+               return false;
+       }
+       maxid = info->queues_total - 1 + info->queuenum;
+       if (maxid > 0xffff) {
+               pr_err("NFQUEUE: number of queues (%u) out of range (got %u)\n",
+                      info->queues_total, maxid);
+               return false;
+       }
+       return true;
+}
+
 static struct xt_target nfqueue_tg_reg[] __read_mostly = {
        {
                .name           = "NFQUEUE",
-               .family         = NFPROTO_IPV4,
+               .family         = NFPROTO_UNSPEC,
                .target         = nfqueue_tg,
                .targetsize     = sizeof(struct xt_NFQ_info),
                .me             = THIS_MODULE,
        },
        {
                .name           = "NFQUEUE",
-               .family         = NFPROTO_IPV6,
-               .target         = nfqueue_tg,
-               .targetsize     = sizeof(struct xt_NFQ_info),
+               .revision       = 1,
+               .family         = NFPROTO_IPV4,
+               .checkentry     = nfqueue_tg_v1_check,
+               .target         = nfqueue_tg4_v1,
+               .targetsize     = sizeof(struct xt_NFQ_info_v1),
                .me             = THIS_MODULE,
        },
+#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
        {
                .name           = "NFQUEUE",
-               .family         = NFPROTO_ARP,
-               .target         = nfqueue_tg,
-               .targetsize     = sizeof(struct xt_NFQ_info),
+               .revision       = 1,
+               .family         = NFPROTO_IPV6,
+               .checkentry     = nfqueue_tg_v1_check,
+               .target         = nfqueue_tg6_v1,
+               .targetsize     = sizeof(struct xt_NFQ_info_v1),
                .me             = THIS_MODULE,
        },
+#endif
 };
 
 static int __init nfqueue_tg_init(void)
 {
+       get_random_bytes(&jhash_initval, sizeof(jhash_initval));
        return xt_register_targets(nfqueue_tg_reg, ARRAY_SIZE(nfqueue_tg_reg));
 }
 
index 4f3b1f8087958e51b6a0161c848fa142335eb2e8..eda64c1cb1e5e9f430d4c44e1858ee9096659f92 100644 (file)
@@ -73,11 +73,11 @@ tcpmss_mangle_packet(struct sk_buff *skb,
        }
 
        if (info->mss == XT_TCPMSS_CLAMP_PMTU) {
-               if (dst_mtu(skb->dst) <= minlen) {
+               if (dst_mtu(skb_dst(skb)) <= minlen) {
                        if (net_ratelimit())
                                printk(KERN_ERR "xt_TCPMSS: "
                                       "unknown or invalid path-MTU (%u)\n",
-                                      dst_mtu(skb->dst));
+                                      dst_mtu(skb_dst(skb)));
                        return -1;
                }
                if (in_mtu <= minlen) {
@@ -86,7 +86,7 @@ tcpmss_mangle_packet(struct sk_buff *skb,
                                       "invalid path-MTU (%u)\n", in_mtu);
                        return -1;
                }
-               newmss = min(dst_mtu(skb->dst), in_mtu) - minlen;
+               newmss = min(dst_mtu(skb_dst(skb)), in_mtu) - minlen;
        } else
                newmss = info->mss;
 
diff --git a/net/netfilter/xt_osf.c b/net/netfilter/xt_osf.c
new file mode 100644 (file)
index 0000000..863e409
--- /dev/null
@@ -0,0 +1,428 @@
+/*
+ * Copyright (c) 2003+ Evgeniy Polyakov <zbr@ioremap.net>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+
+#include <linux/if.h>
+#include <linux/inetdevice.h>
+#include <linux/ip.h>
+#include <linux/list.h>
+#include <linux/rculist.h>
+#include <linux/skbuff.h>
+#include <linux/slab.h>
+#include <linux/tcp.h>
+
+#include <net/ip.h>
+#include <net/tcp.h>
+
+#include <linux/netfilter/nfnetlink.h>
+#include <linux/netfilter/x_tables.h>
+#include <net/netfilter/nf_log.h>
+#include <linux/netfilter/xt_osf.h>
+
+struct xt_osf_finger {
+       struct rcu_head                 rcu_head;
+       struct list_head                finger_entry;
+       struct xt_osf_user_finger       finger;
+};
+
+enum osf_fmatch_states {
+       /* Packet does not match the fingerprint */
+       FMATCH_WRONG = 0,
+       /* Packet matches the fingerprint */
+       FMATCH_OK,
+       /* Options do not match the fingerprint, but header does */
+       FMATCH_OPT_WRONG,
+};
+
+/*
+ * Indexed by dont-fragment bit.
+ * It is the only constant value in the fingerprint.
+ */
+static struct list_head xt_osf_fingers[2];
+
+static const struct nla_policy xt_osf_policy[OSF_ATTR_MAX + 1] = {
+       [OSF_ATTR_FINGER]       = { .len = sizeof(struct xt_osf_user_finger) },
+};
+
+static void xt_osf_finger_free_rcu(struct rcu_head *rcu_head)
+{
+       struct xt_osf_finger *f = container_of(rcu_head, struct xt_osf_finger, rcu_head);
+
+       kfree(f);
+}
+
+static int xt_osf_add_callback(struct sock *ctnl, struct sk_buff *skb,
+                       struct nlmsghdr *nlh, struct nlattr *osf_attrs[])
+{
+       struct xt_osf_user_finger *f;
+       struct xt_osf_finger *kf = NULL, *sf;
+       int err = 0;
+
+       if (!osf_attrs[OSF_ATTR_FINGER])
+               return -EINVAL;
+
+       if (!(nlh->nlmsg_flags & NLM_F_CREATE))
+               return -EINVAL;
+
+       f = nla_data(osf_attrs[OSF_ATTR_FINGER]);
+
+       kf = kmalloc(sizeof(struct xt_osf_finger), GFP_KERNEL);
+       if (!kf)
+               return -ENOMEM;
+
+       memcpy(&kf->finger, f, sizeof(struct xt_osf_user_finger));
+
+       list_for_each_entry(sf, &xt_osf_fingers[!!f->df], finger_entry) {
+               if (memcmp(&sf->finger, f, sizeof(struct xt_osf_user_finger)))
+                       continue;
+
+               kfree(kf);
+               kf = NULL;
+
+               if (nlh->nlmsg_flags & NLM_F_EXCL)
+                       err = -EEXIST;
+               break;
+       }
+
+       /*
+        * We are protected by nfnl mutex.
+        */
+       if (kf)
+               list_add_tail_rcu(&kf->finger_entry, &xt_osf_fingers[!!f->df]);
+
+       return err;
+}
+
+static int xt_osf_remove_callback(struct sock *ctnl, struct sk_buff *skb,
+                       struct nlmsghdr *nlh, struct nlattr *osf_attrs[])
+{
+       struct xt_osf_user_finger *f;
+       struct xt_osf_finger *sf;
+       int err = ENOENT;
+
+       if (!osf_attrs[OSF_ATTR_FINGER])
+               return -EINVAL;
+
+       f = nla_data(osf_attrs[OSF_ATTR_FINGER]);
+
+       list_for_each_entry(sf, &xt_osf_fingers[!!f->df], finger_entry) {
+               if (memcmp(&sf->finger, f, sizeof(struct xt_osf_user_finger)))
+                       continue;
+
+               /*
+                * We are protected by nfnl mutex.
+                */
+               list_del_rcu(&sf->finger_entry);
+               call_rcu(&sf->rcu_head, xt_osf_finger_free_rcu);
+
+               err = 0;
+               break;
+       }
+
+       return err;
+}
+
+static const struct nfnl_callback xt_osf_nfnetlink_callbacks[OSF_MSG_MAX] = {
+       [OSF_MSG_ADD]   = {
+               .call           = xt_osf_add_callback,
+               .attr_count     = OSF_ATTR_MAX,
+               .policy         = xt_osf_policy,
+       },
+       [OSF_MSG_REMOVE]        = {
+               .call           = xt_osf_remove_callback,
+               .attr_count     = OSF_ATTR_MAX,
+               .policy         = xt_osf_policy,
+       },
+};
+
+static const struct nfnetlink_subsystem xt_osf_nfnetlink = {
+       .name                   = "osf",
+       .subsys_id              = NFNL_SUBSYS_OSF,
+       .cb_count               = OSF_MSG_MAX,
+       .cb                     = xt_osf_nfnetlink_callbacks,
+};
+
+static inline int xt_osf_ttl(const struct sk_buff *skb, const struct xt_osf_info *info,
+                           unsigned char f_ttl)
+{
+       const struct iphdr *ip = ip_hdr(skb);
+
+       if (info->flags & XT_OSF_TTL) {
+               if (info->ttl == XT_OSF_TTL_TRUE)
+                       return ip->ttl == f_ttl;
+               if (info->ttl == XT_OSF_TTL_NOCHECK)
+                       return 1;
+               else if (ip->ttl <= f_ttl)
+                       return 1;
+               else {
+                       struct in_device *in_dev = __in_dev_get_rcu(skb->dev);
+                       int ret = 0;
+
+                       for_ifa(in_dev) {
+                               if (inet_ifa_match(ip->saddr, ifa)) {
+                                       ret = (ip->ttl == f_ttl);
+                                       break;
+                               }
+                       }
+                       endfor_ifa(in_dev);
+
+                       return ret;
+               }
+       }
+
+       return ip->ttl == f_ttl;
+}
+
+static bool xt_osf_match_packet(const struct sk_buff *skb,
+               const struct xt_match_param *p)
+{
+       const struct xt_osf_info *info = p->matchinfo;
+       const struct iphdr *ip = ip_hdr(skb);
+       const struct tcphdr *tcp;
+       struct tcphdr _tcph;
+       int fmatch = FMATCH_WRONG, fcount = 0;
+       unsigned int optsize = 0, check_WSS = 0;
+       u16 window, totlen, mss = 0;
+       bool df;
+       const unsigned char *optp = NULL, *_optp = NULL;
+       unsigned char opts[MAX_IPOPTLEN];
+       const struct xt_osf_finger *kf;
+       const struct xt_osf_user_finger *f;
+
+       if (!info)
+               return false;
+
+       tcp = skb_header_pointer(skb, ip_hdrlen(skb), sizeof(struct tcphdr), &_tcph);
+       if (!tcp)
+               return false;
+
+       if (!tcp->syn)
+               return false;
+
+       totlen = ntohs(ip->tot_len);
+       df = ntohs(ip->frag_off) & IP_DF;
+       window = ntohs(tcp->window);
+
+       if (tcp->doff * 4 > sizeof(struct tcphdr)) {
+               optsize = tcp->doff * 4 - sizeof(struct tcphdr);
+
+               _optp = optp = skb_header_pointer(skb, ip_hdrlen(skb) +
+                               sizeof(struct tcphdr), optsize, opts);
+       }
+
+       rcu_read_lock();
+       list_for_each_entry_rcu(kf, &xt_osf_fingers[df], finger_entry) {
+               f = &kf->finger;
+
+               if (!(info->flags & XT_OSF_LOG) && strcmp(info->genre, f->genre))
+                       continue;
+
+               optp = _optp;
+               fmatch = FMATCH_WRONG;
+
+               if (totlen == f->ss && xt_osf_ttl(skb, info, f->ttl)) {
+                       int foptsize, optnum;
+
+                       /*
+                        * Should not happen if userspace parser was written correctly.
+                        */
+                       if (f->wss.wc >= OSF_WSS_MAX)
+                               continue;
+
+                       /* Check options */
+
+                       foptsize = 0;
+                       for (optnum = 0; optnum < f->opt_num; ++optnum)
+                               foptsize += f->opt[optnum].length;
+
+                       if (foptsize > MAX_IPOPTLEN ||
+                               optsize > MAX_IPOPTLEN ||
+                               optsize != foptsize)
+                               continue;
+
+                       check_WSS = f->wss.wc;
+
+                       for (optnum = 0; optnum < f->opt_num; ++optnum) {
+                               if (f->opt[optnum].kind == (*optp)) {
+                                       __u32 len = f->opt[optnum].length;
+                                       const __u8 *optend = optp + len;
+                                       int loop_cont = 0;
+
+                                       fmatch = FMATCH_OK;
+
+                                       switch (*optp) {
+                                       case OSFOPT_MSS:
+                                               mss = optp[3];
+                                               mss <<= 8;
+                                               mss |= optp[2];
+
+                                               mss = ntohs(mss);
+                                               break;
+                                       case OSFOPT_TS:
+                                               loop_cont = 1;
+                                               break;
+                                       }
+
+                                       optp = optend;
+                               } else
+                                       fmatch = FMATCH_OPT_WRONG;
+
+                               if (fmatch != FMATCH_OK)
+                                       break;
+                       }
+
+                       if (fmatch != FMATCH_OPT_WRONG) {
+                               fmatch = FMATCH_WRONG;
+
+                               switch (check_WSS) {
+                               case OSF_WSS_PLAIN:
+                                       if (f->wss.val == 0 || window == f->wss.val)
+                                               fmatch = FMATCH_OK;
+                                       break;
+                               case OSF_WSS_MSS:
+                                       /*
+                                        * Some smart modems decrease mangle MSS to 
+                                        * SMART_MSS_2, so we check standard, decreased
+                                        * and the one provided in the fingerprint MSS
+                                        * values.
+                                        */
+#define SMART_MSS_1    1460
+#define SMART_MSS_2    1448
+                                       if (window == f->wss.val * mss ||
+                                           window == f->wss.val * SMART_MSS_1 ||
+                                           window == f->wss.val * SMART_MSS_2)
+                                               fmatch = FMATCH_OK;
+                                       break;
+                               case OSF_WSS_MTU:
+                                       if (window == f->wss.val * (mss + 40) ||
+                                           window == f->wss.val * (SMART_MSS_1 + 40) ||
+                                           window == f->wss.val * (SMART_MSS_2 + 40))
+                                               fmatch = FMATCH_OK;
+                                       break;
+                               case OSF_WSS_MODULO:
+                                       if ((window % f->wss.val) == 0)
+                                               fmatch = FMATCH_OK;
+                                       break;
+                               }
+                       }
+
+                       if (fmatch != FMATCH_OK)
+                               continue;
+
+                       fcount++;
+
+                       if (info->flags & XT_OSF_LOG)
+                               nf_log_packet(p->hooknum, 0, skb, p->in, p->out, NULL,
+                                       "%s [%s:%s] : %pi4:%d -> %pi4:%d hops=%d\n",
+                                       f->genre, f->version, f->subtype,
+                                       &ip->saddr, ntohs(tcp->source),
+                                       &ip->daddr, ntohs(tcp->dest),
+                                       f->ttl - ip->ttl);
+
+                       if ((info->flags & XT_OSF_LOG) &&
+                           info->loglevel == XT_OSF_LOGLEVEL_FIRST)
+                               break;
+               }
+       }
+       rcu_read_unlock();
+
+       if (!fcount && (info->flags & XT_OSF_LOG))
+               nf_log_packet(p->hooknum, 0, skb, p->in, p->out, NULL,
+                       "Remote OS is not known: %pi4:%u -> %pi4:%u\n",
+                               &ip->saddr, ntohs(tcp->source),
+                               &ip->daddr, ntohs(tcp->dest));
+
+       if (fcount)
+               fmatch = FMATCH_OK;
+
+       return fmatch == FMATCH_OK;
+}
+
+static struct xt_match xt_osf_match = {
+       .name           = "osf",
+       .revision       = 0,
+       .family         = NFPROTO_IPV4,
+       .proto          = IPPROTO_TCP,
+       .hooks          = (1 << NF_INET_LOCAL_IN) |
+                               (1 << NF_INET_PRE_ROUTING) |
+                               (1 << NF_INET_FORWARD),
+       .match          = xt_osf_match_packet,
+       .matchsize      = sizeof(struct xt_osf_info),
+       .me             = THIS_MODULE,
+};
+
+static int __init xt_osf_init(void)
+{
+       int err = -EINVAL;
+       int i;
+
+       for (i=0; i<ARRAY_SIZE(xt_osf_fingers); ++i)
+               INIT_LIST_HEAD(&xt_osf_fingers[i]);
+
+       err = nfnetlink_subsys_register(&xt_osf_nfnetlink);
+       if (err < 0) {
+               printk(KERN_ERR "Failed (%d) to register OSF nsfnetlink helper.\n", err);
+               goto err_out_exit;
+       }
+
+       err = xt_register_match(&xt_osf_match);
+       if (err) {
+               printk(KERN_ERR "Failed (%d) to register OS fingerprint "
+                               "matching module.\n", err);
+               goto err_out_remove;
+       }
+
+       return 0;
+
+err_out_remove:
+       nfnetlink_subsys_unregister(&xt_osf_nfnetlink);
+err_out_exit:
+       return err;
+}
+
+static void __exit xt_osf_fini(void)
+{
+       struct xt_osf_finger *f;
+       int i;
+
+       nfnetlink_subsys_unregister(&xt_osf_nfnetlink);
+       xt_unregister_match(&xt_osf_match);
+
+       rcu_read_lock();
+       for (i=0; i<ARRAY_SIZE(xt_osf_fingers); ++i) {
+
+               list_for_each_entry_rcu(f, &xt_osf_fingers[i], finger_entry) {
+                       list_del_rcu(&f->finger_entry);
+                       call_rcu(&f->rcu_head, xt_osf_finger_free_rcu);
+               }
+       }
+       rcu_read_unlock();
+
+       rcu_barrier();
+}
+
+module_init(xt_osf_init);
+module_exit(xt_osf_fini);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Evgeniy Polyakov <zbr@ioremap.net>");
+MODULE_DESCRIPTION("Passive OS fingerprint matching.");
+MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_OSF);
index 328bd20ddd254555c097af945c0c8d7ca87b05cb..4cbfebda8fa11795af6887e33761a374b50857ce 100644 (file)
@@ -86,7 +86,7 @@ match_policy_out(const struct sk_buff *skb, const struct xt_policy_info *info,
                 unsigned short family)
 {
        const struct xt_policy_elem *e;
-       const struct dst_entry *dst = skb->dst;
+       const struct dst_entry *dst = skb_dst(skb);
        int strict = info->flags & XT_POLICY_MATCH_STRICT;
        int i, pos;
 
index 67419287bc7e143003164d2850378066cac6cd41..484d1689bfde167d43474b3eeb35947b073e026c 100644 (file)
@@ -25,7 +25,7 @@ static bool
 realm_mt(const struct sk_buff *skb, const struct xt_match_param *par)
 {
        const struct xt_realm_info *info = par->matchinfo;
-       const struct dst_entry *dst = skb->dst;
+       const struct dst_entry *dst = skb_dst(skb);
 
        return (info->id == (dst->tclassid & info->mask)) ^ info->invert;
 }
index 1acc089be7e94b6e8570d9529895402d3e5a75df..ebf00ad5b1945f09718ba966b7371e480d4b25e5 100644 (file)
@@ -22,6 +22,8 @@
 #include <net/netfilter/nf_tproxy_core.h>
 #include <net/netfilter/ipv4/nf_defrag_ipv4.h>
 
+#include <linux/netfilter/xt_socket.h>
+
 #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
 #define XT_SOCKET_HAVE_CONNTRACK 1
 #include <net/netfilter/nf_conntrack.h>
@@ -86,7 +88,8 @@ extract_icmp_fields(const struct sk_buff *skb,
 
 
 static bool
-socket_mt(const struct sk_buff *skb, const struct xt_match_param *par)
+socket_match(const struct sk_buff *skb, const struct xt_match_param *par,
+            const struct xt_socket_mtinfo1 *info)
 {
        const struct iphdr *iph = ip_hdr(skb);
        struct udphdr _hdr, *hp = NULL;
@@ -141,10 +144,24 @@ socket_mt(const struct sk_buff *skb, const struct xt_match_param *par)
        sk = nf_tproxy_get_sock_v4(dev_net(skb->dev), protocol,
                                   saddr, daddr, sport, dport, par->in, false);
        if (sk != NULL) {
-               bool wildcard = (sk->sk_state != TCP_TIME_WAIT && inet_sk(sk)->rcv_saddr == 0);
+               bool wildcard;
+               bool transparent = true;
+
+               /* Ignore sockets listening on INADDR_ANY */
+               wildcard = (sk->sk_state != TCP_TIME_WAIT &&
+                           inet_sk(sk)->rcv_saddr == 0);
+
+               /* Ignore non-transparent sockets,
+                  if XT_SOCKET_TRANSPARENT is used */
+               if (info && info->flags & XT_SOCKET_TRANSPARENT)
+                       transparent = ((sk->sk_state != TCP_TIME_WAIT &&
+                                       inet_sk(sk)->transparent) ||
+                                      (sk->sk_state == TCP_TIME_WAIT &&
+                                       inet_twsk(sk)->tw_transparent));
 
                nf_tproxy_put_sock(sk);
-               if (wildcard)
+
+               if (wildcard || !transparent)
                        sk = NULL;
        }
 
@@ -157,23 +174,47 @@ socket_mt(const struct sk_buff *skb, const struct xt_match_param *par)
        return (sk != NULL);
 }
 
-static struct xt_match socket_mt_reg __read_mostly = {
-       .name           = "socket",
-       .family         = AF_INET,
-       .match          = socket_mt,
-       .hooks          = 1 << NF_INET_PRE_ROUTING,
-       .me             = THIS_MODULE,
+static bool
+socket_mt_v0(const struct sk_buff *skb, const struct xt_match_param *par)
+{
+       return socket_match(skb, par, NULL);
+}
+
+static bool
+socket_mt_v1(const struct sk_buff *skb, const struct xt_match_param *par)
+{
+       return socket_match(skb, par, par->matchinfo);
+}
+
+static struct xt_match socket_mt_reg[] __read_mostly = {
+       {
+               .name           = "socket",
+               .revision       = 0,
+               .family         = NFPROTO_IPV4,
+               .match          = socket_mt_v0,
+               .hooks          = 1 << NF_INET_PRE_ROUTING,
+               .me             = THIS_MODULE,
+       },
+       {
+               .name           = "socket",
+               .revision       = 1,
+               .family         = NFPROTO_IPV4,
+               .match          = socket_mt_v1,
+               .matchsize      = sizeof(struct xt_socket_mtinfo1),
+               .hooks          = 1 << NF_INET_PRE_ROUTING,
+               .me             = THIS_MODULE,
+       },
 };
 
 static int __init socket_mt_init(void)
 {
        nf_defrag_ipv4_enable();
-       return xt_register_match(&socket_mt_reg);
+       return xt_register_matches(socket_mt_reg, ARRAY_SIZE(socket_mt_reg));
 }
 
 static void __exit socket_mt_exit(void)
 {
-       xt_unregister_match(&socket_mt_reg);
+       xt_unregister_matches(socket_mt_reg, ARRAY_SIZE(socket_mt_reg));
 }
 
 module_init(socket_mt_init);
index bf1ab1a6790d6102005d871359ab6ec211c619dc..e639298bc9c810a77961113b67a5078fee9bbd6f 100644 (file)
@@ -785,18 +785,6 @@ static struct genl_ops netlbl_cipsov4_ops[] = {
  */
 int __init netlbl_cipsov4_genl_init(void)
 {
-       int ret_val, i;
-
-       ret_val = genl_register_family(&netlbl_cipsov4_gnl_family);
-       if (ret_val != 0)
-               return ret_val;
-
-       for (i = 0; i < ARRAY_SIZE(netlbl_cipsov4_ops); i++) {
-               ret_val = genl_register_ops(&netlbl_cipsov4_gnl_family,
-                               &netlbl_cipsov4_ops[i]);
-               if (ret_val != 0)
-                       return ret_val;
-       }
-
-       return 0;
+       return genl_register_family_with_ops(&netlbl_cipsov4_gnl_family,
+               netlbl_cipsov4_ops, ARRAY_SIZE(netlbl_cipsov4_ops));
 }
index 1821c5d50fb8ec448374c04619c30eab07baa15f..8203623e65ad3c09f94869d6c8b9358d7f04c4bf 100644 (file)
@@ -779,18 +779,6 @@ static struct genl_ops netlbl_mgmt_genl_ops[] = {
  */
 int __init netlbl_mgmt_genl_init(void)
 {
-       int ret_val, i;
-
-       ret_val = genl_register_family(&netlbl_mgmt_gnl_family);
-       if (ret_val != 0)
-               return ret_val;
-
-       for (i = 0; i < ARRAY_SIZE(netlbl_mgmt_genl_ops); i++) {
-               ret_val = genl_register_ops(&netlbl_mgmt_gnl_family,
-                               &netlbl_mgmt_genl_ops[i]);
-               if (ret_val != 0)
-                       return ret_val;
-       }
-
-       return 0;
+       return genl_register_family_with_ops(&netlbl_mgmt_gnl_family,
+               netlbl_mgmt_genl_ops, ARRAY_SIZE(netlbl_mgmt_genl_ops));
 }
index f3c5c68c6848ee5daa1463c236936f0ff0264b2b..fb357f010189ec12b70de5b3677aea7169874e6c 100644 (file)
@@ -1478,20 +1478,8 @@ static struct genl_ops netlbl_unlabel_genl_ops[] = {
  */
 int __init netlbl_unlabel_genl_init(void)
 {
-       int ret_val, i;
-
-       ret_val = genl_register_family(&netlbl_unlabel_gnl_family);
-       if (ret_val != 0)
-               return ret_val;
-
-       for (i = 0; i < ARRAY_SIZE(netlbl_unlabel_genl_ops); i++) {
-               ret_val = genl_register_ops(&netlbl_unlabel_gnl_family,
-                               &netlbl_unlabel_genl_ops[i]);
-               if (ret_val != 0)
-                       return ret_val;
-       }
-
-       return 0;
+       return genl_register_family_with_ops(&netlbl_unlabel_gnl_family,
+               netlbl_unlabel_genl_ops, ARRAY_SIZE(netlbl_unlabel_genl_ops));
 }
 
 /*
index 1d3dd30099df00f2983e95de4125da6d4cd923df..eed4c6a8afc0256fb6c3e1e267da6ca21233e823 100644 (file)
@@ -383,6 +383,52 @@ errout:
        return err;
 }
 
+/**
+ * genl_register_family_with_ops - register a generic netlink family
+ * @family: generic netlink family
+ * @ops: operations to be registered
+ * @n_ops: number of elements to register
+ *
+ * Registers the specified family and operations from the specified table.
+ * Only one family may be registered with the same family name or identifier.
+ *
+ * The family id may equal GENL_ID_GENERATE causing an unique id to
+ * be automatically generated and assigned.
+ *
+ * Either a doit or dumpit callback must be specified for every registered
+ * operation or the function will fail. Only one operation structure per
+ * command identifier may be registered.
+ *
+ * See include/net/genetlink.h for more documenation on the operations
+ * structure.
+ *
+ * This is equivalent to calling genl_register_family() followed by
+ * genl_register_ops() for every operation entry in the table taking
+ * care to unregister the family on error path.
+ *
+ * Return 0 on success or a negative error code.
+ */
+int genl_register_family_with_ops(struct genl_family *family,
+       struct genl_ops *ops, size_t n_ops)
+{
+       int err, i;
+
+       err = genl_register_family(family);
+       if (err)
+               return err;
+
+       for (i = 0; i < n_ops; ++i, ++ops) {
+               err = genl_register_ops(family, ops);
+               if (err)
+                       goto err_out;
+       }
+       return 0;
+err_out:
+       genl_unregister_family(family);
+       return err;
+}
+EXPORT_SYMBOL(genl_register_family_with_ops);
+
 /**
  * genl_unregister_family - unregister generic netlink family
  * @family: generic netlink family
index f546e81acc450278589f0b5025cbabf73cd5a432..4f76e5552d8e94dff5e43fd4d1861a8dede91751 100644 (file)
@@ -39,6 +39,7 @@
  *                                     will simply extend the hardware address
  *                                     byte arrays at the end of sockaddr_ll
  *                                     and packet_mreq.
+ *             Johann Baudy    :       Added TX RING.
  *
  *             This program is free software; you can redistribute it and/or
  *             modify it under the terms of the GNU General Public License
@@ -157,7 +158,25 @@ struct packet_mreq_max
 };
 
 #ifdef CONFIG_PACKET_MMAP
-static int packet_set_ring(struct sock *sk, struct tpacket_req *req, int closing);
+static int packet_set_ring(struct sock *sk, struct tpacket_req *req,
+               int closing, int tx_ring);
+
+struct packet_ring_buffer {
+       char *                  *pg_vec;
+       unsigned int            head;
+       unsigned int            frames_per_block;
+       unsigned int            frame_size;
+       unsigned int            frame_max;
+
+       unsigned int            pg_vec_order;
+       unsigned int            pg_vec_pages;
+       unsigned int            pg_vec_len;
+
+       atomic_t                pending;
+};
+
+struct packet_sock;
+static int tpacket_snd(struct packet_sock *po, struct msghdr *msg);
 #endif
 
 static void packet_flush_mclist(struct sock *sk);
@@ -167,11 +186,8 @@ struct packet_sock {
        struct sock             sk;
        struct tpacket_stats    stats;
 #ifdef CONFIG_PACKET_MMAP
-       char *                  *pg_vec;
-       unsigned int            head;
-       unsigned int            frames_per_block;
-       unsigned int            frame_size;
-       unsigned int            frame_max;
+       struct packet_ring_buffer       rx_ring;
+       struct packet_ring_buffer       tx_ring;
        int                     copy_thresh;
 #endif
        struct packet_type      prot_hook;
@@ -185,12 +201,10 @@ struct packet_sock {
        struct packet_mclist    *mclist;
 #ifdef CONFIG_PACKET_MMAP
        atomic_t                mapped;
-       unsigned int            pg_vec_order;
-       unsigned int            pg_vec_pages;
-       unsigned int            pg_vec_len;
        enum tpacket_versions   tp_version;
        unsigned int            tp_hdrlen;
        unsigned int            tp_reserve;
+       unsigned int            tp_loss:1;
 #endif
 };
 
@@ -206,36 +220,33 @@ struct packet_skb_cb {
 
 #ifdef CONFIG_PACKET_MMAP
 
-static void *packet_lookup_frame(struct packet_sock *po, unsigned int position,
-                                int status)
+static void __packet_set_status(struct packet_sock *po, void *frame, int status)
 {
-       unsigned int pg_vec_pos, frame_offset;
        union {
                struct tpacket_hdr *h1;
                struct tpacket2_hdr *h2;
                void *raw;
        } h;
 
-       pg_vec_pos = position / po->frames_per_block;
-       frame_offset = position % po->frames_per_block;
-
-       h.raw = po->pg_vec[pg_vec_pos] + (frame_offset * po->frame_size);
+       h.raw = frame;
        switch (po->tp_version) {
        case TPACKET_V1:
-               if (status != (h.h1->tp_status ? TP_STATUS_USER :
-                                               TP_STATUS_KERNEL))
-                       return NULL;
+               h.h1->tp_status = status;
+               flush_dcache_page(virt_to_page(&h.h1->tp_status));
                break;
        case TPACKET_V2:
-               if (status != (h.h2->tp_status ? TP_STATUS_USER :
-                                               TP_STATUS_KERNEL))
-                       return NULL;
+               h.h2->tp_status = status;
+               flush_dcache_page(virt_to_page(&h.h2->tp_status));
                break;
+       default:
+               printk(KERN_ERR "TPACKET version not supported\n");
+               BUG();
        }
-       return h.raw;
+
+       smp_wmb();
 }
 
-static void __packet_set_status(struct packet_sock *po, void *frame, int status)
+static int __packet_get_status(struct packet_sock *po, void *frame)
 {
        union {
                struct tpacket_hdr *h1;
@@ -243,16 +254,66 @@ static void __packet_set_status(struct packet_sock *po, void *frame, int status)
                void *raw;
        } h;
 
+       smp_rmb();
+
        h.raw = frame;
        switch (po->tp_version) {
        case TPACKET_V1:
-               h.h1->tp_status = status;
-               break;
+               flush_dcache_page(virt_to_page(&h.h1->tp_status));
+               return h.h1->tp_status;
        case TPACKET_V2:
-               h.h2->tp_status = status;
-               break;
+               flush_dcache_page(virt_to_page(&h.h2->tp_status));
+               return h.h2->tp_status;
+       default:
+               printk(KERN_ERR "TPACKET version not supported\n");
+               BUG();
+               return 0;
        }
 }
+
+static void *packet_lookup_frame(struct packet_sock *po,
+               struct packet_ring_buffer *rb,
+               unsigned int position,
+               int status)
+{
+       unsigned int pg_vec_pos, frame_offset;
+       union {
+               struct tpacket_hdr *h1;
+               struct tpacket2_hdr *h2;
+               void *raw;
+       } h;
+
+       pg_vec_pos = position / rb->frames_per_block;
+       frame_offset = position % rb->frames_per_block;
+
+       h.raw = rb->pg_vec[pg_vec_pos] + (frame_offset * rb->frame_size);
+
+       if (status != __packet_get_status(po, h.raw))
+               return NULL;
+
+       return h.raw;
+}
+
+static inline void *packet_current_frame(struct packet_sock *po,
+               struct packet_ring_buffer *rb,
+               int status)
+{
+       return packet_lookup_frame(po, rb, rb->head, status);
+}
+
+static inline void *packet_previous_frame(struct packet_sock *po,
+               struct packet_ring_buffer *rb,
+               int status)
+{
+       unsigned int previous = rb->head ? rb->head - 1 : rb->frame_max;
+       return packet_lookup_frame(po, rb, previous, status);
+}
+
+static inline void packet_increment_head(struct packet_ring_buffer *buff)
+{
+       buff->head = buff->head != buff->frame_max ? buff->head+1 : 0;
+}
+
 #endif
 
 static inline struct packet_sock *pkt_sk(struct sock *sk)
@@ -311,8 +372,7 @@ static int packet_rcv_spkt(struct sk_buff *skb, struct net_device *dev,  struct
                goto oom;
 
        /* drop any routing info */
-       dst_release(skb->dst);
-       skb->dst = NULL;
+       skb_dst_drop(skb);
 
        /* drop conntrack reference */
        nf_reset(skb);
@@ -560,8 +620,7 @@ static int packet_rcv(struct sk_buff *skb, struct net_device *dev, struct packet
 
        skb_set_owner_r(skb, sk);
        skb->dev = NULL;
-       dst_release(skb->dst);
-       skb->dst = NULL;
+       skb_dst_drop(skb);
 
        /* drop conntrack reference */
        nf_reset(skb);
@@ -648,7 +707,7 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, struct packe
                macoff = netoff - maclen;
        }
 
-       if (macoff + snaplen > po->frame_size) {
+       if (macoff + snaplen > po->rx_ring.frame_size) {
                if (po->copy_thresh &&
                    atomic_read(&sk->sk_rmem_alloc) + skb->truesize <
                    (unsigned)sk->sk_rcvbuf) {
@@ -661,16 +720,16 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, struct packe
                        if (copy_skb)
                                skb_set_owner_r(copy_skb, sk);
                }
-               snaplen = po->frame_size - macoff;
+               snaplen = po->rx_ring.frame_size - macoff;
                if ((int)snaplen < 0)
                        snaplen = 0;
        }
 
        spin_lock(&sk->sk_receive_queue.lock);
-       h.raw = packet_lookup_frame(po, po->head, TP_STATUS_KERNEL);
+       h.raw = packet_current_frame(po, &po->rx_ring, TP_STATUS_KERNEL);
        if (!h.raw)
                goto ring_is_full;
-       po->head = po->head != po->frame_max ? po->head+1 : 0;
+       packet_increment_head(&po->rx_ring);
        po->stats.tp_packets++;
        if (copy_skb) {
                status |= TP_STATUS_COPY;
@@ -727,7 +786,6 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, struct packe
 
        __packet_set_status(po, h.raw, status);
        smp_mb();
-
        {
                struct page *p_start, *p_end;
                u8 *h_end = h.raw + macoff + snaplen - 1;
@@ -760,10 +818,249 @@ ring_is_full:
        goto drop_n_restore;
 }
 
-#endif
+static void tpacket_destruct_skb(struct sk_buff *skb)
+{
+       struct packet_sock *po = pkt_sk(skb->sk);
+       void * ph;
 
+       BUG_ON(skb == NULL);
 
-static int packet_sendmsg(struct kiocb *iocb, struct socket *sock,
+       if (likely(po->tx_ring.pg_vec)) {
+               ph = skb_shinfo(skb)->destructor_arg;
+               BUG_ON(__packet_get_status(po, ph) != TP_STATUS_SENDING);
+               BUG_ON(atomic_read(&po->tx_ring.pending) == 0);
+               atomic_dec(&po->tx_ring.pending);
+               __packet_set_status(po, ph, TP_STATUS_AVAILABLE);
+       }
+
+       sock_wfree(skb);
+}
+
+static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff * skb,
+               void * frame, struct net_device *dev, int size_max,
+               __be16 proto, unsigned char * addr)
+{
+       union {
+               struct tpacket_hdr *h1;
+               struct tpacket2_hdr *h2;
+               void *raw;
+       } ph;
+       int to_write, offset, len, tp_len, nr_frags, len_max;
+       struct socket *sock = po->sk.sk_socket;
+       struct page *page;
+       void *data;
+       int err;
+
+       ph.raw = frame;
+
+       skb->protocol = proto;
+       skb->dev = dev;
+       skb->priority = po->sk.sk_priority;
+       skb_shinfo(skb)->destructor_arg = ph.raw;
+
+       switch (po->tp_version) {
+       case TPACKET_V2:
+               tp_len = ph.h2->tp_len;
+               break;
+       default:
+               tp_len = ph.h1->tp_len;
+               break;
+       }
+       if (unlikely(tp_len > size_max)) {
+               printk(KERN_ERR "packet size is too long (%d > %d)\n",
+                               tp_len, size_max);
+               return -EMSGSIZE;
+       }
+
+       skb_reserve(skb, LL_RESERVED_SPACE(dev));
+       skb_reset_network_header(skb);
+
+       data = ph.raw + po->tp_hdrlen - sizeof(struct sockaddr_ll);
+       to_write = tp_len;
+
+       if (sock->type == SOCK_DGRAM) {
+               err = dev_hard_header(skb, dev, ntohs(proto), addr,
+                               NULL, tp_len);
+               if (unlikely(err < 0))
+                       return -EINVAL;
+       } else if (dev->hard_header_len ) {
+               /* net device doesn't like empty head */
+               if (unlikely(tp_len <= dev->hard_header_len)) {
+                       printk(KERN_ERR "packet size is too short "
+                                       "(%d < %d)\n", tp_len,
+                                       dev->hard_header_len);
+                       return -EINVAL;
+               }
+
+               skb_push(skb, dev->hard_header_len);
+               err = skb_store_bits(skb, 0, data,
+                               dev->hard_header_len);
+               if (unlikely(err))
+                       return err;
+
+               data += dev->hard_header_len;
+               to_write -= dev->hard_header_len;
+       }
+
+       err = -EFAULT;
+       page = virt_to_page(data);
+       offset = offset_in_page(data);
+       len_max = PAGE_SIZE - offset;
+       len = ((to_write > len_max) ? len_max : to_write);
+
+       skb->data_len = to_write;
+       skb->len += to_write;
+       skb->truesize += to_write;
+       atomic_add(to_write, &po->sk.sk_wmem_alloc);
+
+       while (likely(to_write)) {
+               nr_frags = skb_shinfo(skb)->nr_frags;
+
+               if (unlikely(nr_frags >= MAX_SKB_FRAGS)) {
+                       printk(KERN_ERR "Packet exceed the number "
+                                       "of skb frags(%lu)\n",
+                                       MAX_SKB_FRAGS);
+                       return -EFAULT;
+               }
+
+               flush_dcache_page(page);
+               get_page(page);
+               skb_fill_page_desc(skb,
+                               nr_frags,
+                               page++, offset, len);
+               to_write -= len;
+               offset = 0;
+               len_max = PAGE_SIZE;
+               len = ((to_write > len_max) ? len_max : to_write);
+       }
+
+       return tp_len;
+}
+
+static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
+{
+       struct socket *sock;
+       struct sk_buff *skb;
+       struct net_device *dev;
+       __be16 proto;
+       int ifindex, err, reserve = 0;
+       void * ph;
+       struct sockaddr_ll *saddr=(struct sockaddr_ll *)msg->msg_name;
+       int tp_len, size_max;
+       unsigned char *addr;
+       int len_sum = 0;
+       int status = 0;
+
+       sock = po->sk.sk_socket;
+
+       mutex_lock(&po->pg_vec_lock);
+
+       err = -EBUSY;
+       if (saddr == NULL) {
+               ifindex = po->ifindex;
+               proto   = po->num;
+               addr    = NULL;
+       } else {
+               err = -EINVAL;
+               if (msg->msg_namelen < sizeof(struct sockaddr_ll))
+                       goto out;
+               if (msg->msg_namelen < (saddr->sll_halen
+                                       + offsetof(struct sockaddr_ll,
+                                               sll_addr)))
+                       goto out;
+               ifindex = saddr->sll_ifindex;
+               proto   = saddr->sll_protocol;
+               addr    = saddr->sll_addr;
+       }
+
+       dev = dev_get_by_index(sock_net(&po->sk), ifindex);
+       err = -ENXIO;
+       if (unlikely(dev == NULL))
+               goto out;
+
+       reserve = dev->hard_header_len;
+
+       err = -ENETDOWN;
+       if (unlikely(!(dev->flags & IFF_UP)))
+               goto out_put;
+
+       size_max = po->tx_ring.frame_size
+               - sizeof(struct skb_shared_info)
+               - po->tp_hdrlen
+               - LL_ALLOCATED_SPACE(dev)
+               - sizeof(struct sockaddr_ll);
+
+       if (size_max > dev->mtu + reserve)
+               size_max = dev->mtu + reserve;
+
+       do {
+               ph = packet_current_frame(po, &po->tx_ring,
+                               TP_STATUS_SEND_REQUEST);
+
+               if (unlikely(ph == NULL)) {
+                       schedule();
+                       continue;
+               }
+
+               status = TP_STATUS_SEND_REQUEST;
+               skb = sock_alloc_send_skb(&po->sk,
+                               LL_ALLOCATED_SPACE(dev)
+                               + sizeof(struct sockaddr_ll),
+                               0, &err);
+
+               if (unlikely(skb == NULL))
+                       goto out_status;
+
+               tp_len = tpacket_fill_skb(po, skb, ph, dev, size_max, proto,
+                               addr);
+
+               if (unlikely(tp_len < 0)) {
+                       if (po->tp_loss) {
+                               __packet_set_status(po, ph,
+                                               TP_STATUS_AVAILABLE);
+                               packet_increment_head(&po->tx_ring);
+                               kfree_skb(skb);
+                               continue;
+                       } else {
+                               status = TP_STATUS_WRONG_FORMAT;
+                               err = tp_len;
+                               goto out_status;
+                       }
+               }
+
+               skb->destructor = tpacket_destruct_skb;
+               __packet_set_status(po, ph, TP_STATUS_SENDING);
+               atomic_inc(&po->tx_ring.pending);
+
+               status = TP_STATUS_SEND_REQUEST;
+               err = dev_queue_xmit(skb);
+               if (unlikely(err > 0 && (err = net_xmit_errno(err)) != 0))
+                       goto out_xmit;
+               packet_increment_head(&po->tx_ring);
+               len_sum += tp_len;
+       }
+       while (likely((ph != NULL) || ((!(msg->msg_flags & MSG_DONTWAIT))
+                                       && (atomic_read(&po->tx_ring.pending))))
+             );
+
+       err = len_sum;
+       goto out_put;
+
+out_xmit:
+       skb->destructor = sock_wfree;
+       atomic_dec(&po->tx_ring.pending);
+out_status:
+       __packet_set_status(po, ph, status);
+       kfree_skb(skb);
+out_put:
+       dev_put(dev);
+out:
+       mutex_unlock(&po->pg_vec_lock);
+       return err;
+}
+#endif
+
+static int packet_snd(struct socket *sock,
                          struct msghdr *msg, size_t len)
 {
        struct sock *sk = sock->sk;
@@ -854,6 +1151,19 @@ out:
        return err;
 }
 
+static int packet_sendmsg(struct kiocb *iocb, struct socket *sock,
+               struct msghdr *msg, size_t len)
+{
+#ifdef CONFIG_PACKET_MMAP
+       struct sock *sk = sock->sk;
+       struct packet_sock *po = pkt_sk(sk);
+       if (po->tx_ring.pg_vec)
+               return tpacket_snd(po, msg);
+       else
+#endif
+               return packet_snd(sock, msg, len);
+}
+
 /*
  *     Close a PACKET socket. This is fairly simple. We immediately go
  *     to 'closed' state and remove our protocol entry in the device list.
@@ -864,6 +1174,9 @@ static int packet_release(struct socket *sock)
        struct sock *sk = sock->sk;
        struct packet_sock *po;
        struct net *net;
+#ifdef CONFIG_PACKET_MMAP
+       struct tpacket_req req;
+#endif
 
        if (!sk)
                return 0;
@@ -893,11 +1206,13 @@ static int packet_release(struct socket *sock)
        packet_flush_mclist(sk);
 
 #ifdef CONFIG_PACKET_MMAP
-       if (po->pg_vec) {
-               struct tpacket_req req;
-               memset(&req, 0, sizeof(req));
-               packet_set_ring(sk, &req, 1);
-       }
+       memset(&req, 0, sizeof(req));
+
+       if (po->rx_ring.pg_vec)
+               packet_set_ring(sk, &req, 1, 0);
+
+       if (po->tx_ring.pg_vec)
+               packet_set_ring(sk, &req, 1, 1);
 #endif
 
        /*
@@ -1253,9 +1568,9 @@ static int packet_dev_mc(struct net_device *dev, struct packet_mclist *i,
        switch (i->type) {
        case PACKET_MR_MULTICAST:
                if (what > 0)
-                       dev_mc_add(dev, i->addr, i->alen, 0);
+                       return dev_mc_add(dev, i->addr, i->alen, 0);
                else
-                       dev_mc_delete(dev, i->addr, i->alen, 0);
+                       return dev_mc_delete(dev, i->addr, i->alen, 0);
                break;
        case PACKET_MR_PROMISC:
                return dev_set_promiscuity(dev, what);
@@ -1263,6 +1578,12 @@ static int packet_dev_mc(struct net_device *dev, struct packet_mclist *i,
        case PACKET_MR_ALLMULTI:
                return dev_set_allmulti(dev, what);
                break;
+       case PACKET_MR_UNICAST:
+               if (what > 0)
+                       return dev_unicast_add(dev, i->addr);
+               else
+                       return dev_unicast_delete(dev, i->addr);
+               break;
        default:;
        }
        return 0;
@@ -1391,7 +1712,7 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv
        if (level != SOL_PACKET)
                return -ENOPROTOOPT;
 
-       switch(optname) {
+       switch (optname) {
        case PACKET_ADD_MEMBERSHIP:
        case PACKET_DROP_MEMBERSHIP:
        {
@@ -1415,6 +1736,7 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv
 
 #ifdef CONFIG_PACKET_MMAP
        case PACKET_RX_RING:
+       case PACKET_TX_RING:
        {
                struct tpacket_req req;
 
@@ -1422,7 +1744,7 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv
                        return -EINVAL;
                if (copy_from_user(&req,optval,sizeof(req)))
                        return -EFAULT;
-               return packet_set_ring(sk, &req, 0);
+               return packet_set_ring(sk, &req, 0, optname == PACKET_TX_RING);
        }
        case PACKET_COPY_THRESH:
        {
@@ -1442,7 +1764,7 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv
 
                if (optlen != sizeof(val))
                        return -EINVAL;
-               if (po->pg_vec)
+               if (po->rx_ring.pg_vec || po->tx_ring.pg_vec)
                        return -EBUSY;
                if (copy_from_user(&val, optval, sizeof(val)))
                        return -EFAULT;
@@ -1461,13 +1783,26 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv
 
                if (optlen != sizeof(val))
                        return -EINVAL;
-               if (po->pg_vec)
+               if (po->rx_ring.pg_vec || po->tx_ring.pg_vec)
                        return -EBUSY;
                if (copy_from_user(&val, optval, sizeof(val)))
                        return -EFAULT;
                po->tp_reserve = val;
                return 0;
        }
+       case PACKET_LOSS:
+       {
+               unsigned int val;
+
+               if (optlen != sizeof(val))
+                       return -EINVAL;
+               if (po->rx_ring.pg_vec || po->tx_ring.pg_vec)
+                       return -EBUSY;
+               if (copy_from_user(&val, optval, sizeof(val)))
+                       return -EFAULT;
+               po->tp_loss = !!val;
+               return 0;
+       }
 #endif
        case PACKET_AUXDATA:
        {
@@ -1517,7 +1852,7 @@ static int packet_getsockopt(struct socket *sock, int level, int optname,
        if (len < 0)
                return -EINVAL;
 
-       switch(optname) {
+       switch (optname) {
        case PACKET_STATISTICS:
                if (len > sizeof(struct tpacket_stats))
                        len = sizeof(struct tpacket_stats);
@@ -1573,6 +1908,12 @@ static int packet_getsockopt(struct socket *sock, int level, int optname,
                val = po->tp_reserve;
                data = &val;
                break;
+       case PACKET_LOSS:
+               if (len > sizeof(unsigned int))
+                       len = sizeof(unsigned int);
+               val = po->tp_loss;
+               data = &val;
+               break;
 #endif
        default:
                return -ENOPROTOOPT;
@@ -1643,7 +1984,7 @@ static int packet_ioctl(struct socket *sock, unsigned int cmd,
 {
        struct sock *sk = sock->sk;
 
-       switch(cmd) {
+       switch (cmd) {
                case SIOCOUTQ:
                {
                        int amount = atomic_read(&sk->sk_wmem_alloc);
@@ -1705,13 +2046,17 @@ static unsigned int packet_poll(struct file * file, struct socket *sock,
        unsigned int mask = datagram_poll(file, sock, wait);
 
        spin_lock_bh(&sk->sk_receive_queue.lock);
-       if (po->pg_vec) {
-               unsigned last = po->head ? po->head-1 : po->frame_max;
-
-               if (packet_lookup_frame(po, last, TP_STATUS_USER))
+       if (po->rx_ring.pg_vec) {
+               if (!packet_previous_frame(po, &po->rx_ring, TP_STATUS_KERNEL))
                        mask |= POLLIN | POLLRDNORM;
        }
        spin_unlock_bh(&sk->sk_receive_queue.lock);
+       spin_lock_bh(&sk->sk_write_queue.lock);
+       if (po->tx_ring.pg_vec) {
+               if (packet_current_frame(po, &po->tx_ring, TP_STATUS_AVAILABLE))
+                       mask |= POLLOUT | POLLWRNORM;
+       }
+       spin_unlock_bh(&sk->sk_write_queue.lock);
        return mask;
 }
 
@@ -1788,21 +2133,33 @@ out_free_pgvec:
        goto out;
 }
 
-static int packet_set_ring(struct sock *sk, struct tpacket_req *req, int closing)
+static int packet_set_ring(struct sock *sk, struct tpacket_req *req,
+               int closing, int tx_ring)
 {
        char **pg_vec = NULL;
        struct packet_sock *po = pkt_sk(sk);
        int was_running, order = 0;
+       struct packet_ring_buffer *rb;
+       struct sk_buff_head *rb_queue;
        __be16 num;
-       int err = 0;
+       int err;
 
-       if (req->tp_block_nr) {
-               int i;
+       rb = tx_ring ? &po->tx_ring : &po->rx_ring;
+       rb_queue = tx_ring ? &sk->sk_write_queue : &sk->sk_receive_queue;
 
-               /* Sanity tests and some calculations */
+       err = -EBUSY;
+       if (!closing) {
+               if (atomic_read(&po->mapped))
+                       goto out;
+               if (atomic_read(&rb->pending))
+                       goto out;
+       }
 
-               if (unlikely(po->pg_vec))
-                       return -EBUSY;
+       if (req->tp_block_nr) {
+               /* Sanity tests and some calculations */
+               err = -EBUSY;
+               if (unlikely(rb->pg_vec))
+                       goto out;
 
                switch (po->tp_version) {
                case TPACKET_V1:
@@ -1813,42 +2170,35 @@ static int packet_set_ring(struct sock *sk, struct tpacket_req *req, int closing
                        break;
                }
 
+               err = -EINVAL;
                if (unlikely((int)req->tp_block_size <= 0))
-                       return -EINVAL;
+                       goto out;
                if (unlikely(req->tp_block_size & (PAGE_SIZE - 1)))
-                       return -EINVAL;
+                       goto out;
                if (unlikely(req->tp_frame_size < po->tp_hdrlen +
-                                                 po->tp_reserve))
-                       return -EINVAL;
+                                       po->tp_reserve))
+                       goto out;
                if (unlikely(req->tp_frame_size & (TPACKET_ALIGNMENT - 1)))
-                       return -EINVAL;
+                       goto out;
 
-               po->frames_per_block = req->tp_block_size/req->tp_frame_size;
-               if (unlikely(po->frames_per_block <= 0))
-                       return -EINVAL;
-               if (unlikely((po->frames_per_block * req->tp_block_nr) !=
-                            req->tp_frame_nr))
-                       return -EINVAL;
+               rb->frames_per_block = req->tp_block_size/req->tp_frame_size;
+               if (unlikely(rb->frames_per_block <= 0))
+                       goto out;
+               if (unlikely((rb->frames_per_block * req->tp_block_nr) !=
+                                       req->tp_frame_nr))
+                       goto out;
 
                err = -ENOMEM;
                order = get_order(req->tp_block_size);
                pg_vec = alloc_pg_vec(req, order);
                if (unlikely(!pg_vec))
                        goto out;
-
-               for (i = 0; i < req->tp_block_nr; i++) {
-                       void *ptr = pg_vec[i];
-                       int k;
-
-                       for (k = 0; k < po->frames_per_block; k++) {
-                               __packet_set_status(po, ptr, TP_STATUS_KERNEL);
-                               ptr += req->tp_frame_size;
-                       }
-               }
-               /* Done */
-       } else {
+       }
+       /* Done */
+       else {
+               err = -EINVAL;
                if (unlikely(req->tp_frame_nr))
-                       return -EINVAL;
+                       goto out;
        }
 
        lock_sock(sk);
@@ -1872,23 +2222,24 @@ static int packet_set_ring(struct sock *sk, struct tpacket_req *req, int closing
        if (closing || atomic_read(&po->mapped) == 0) {
                err = 0;
 #define XC(a, b) ({ __typeof__ ((a)) __t; __t = (a); (a) = (b); __t; })
-
-               spin_lock_bh(&sk->sk_receive_queue.lock);
-               pg_vec = XC(po->pg_vec, pg_vec);
-               po->frame_max = (req->tp_frame_nr - 1);
-               po->head = 0;
-               po->frame_size = req->tp_frame_size;
-               spin_unlock_bh(&sk->sk_receive_queue.lock);
-
-               order = XC(po->pg_vec_order, order);
-               req->tp_block_nr = XC(po->pg_vec_len, req->tp_block_nr);
-
-               po->pg_vec_pages = req->tp_block_size/PAGE_SIZE;
-               po->prot_hook.func = po->pg_vec ? tpacket_rcv : packet_rcv;
-               skb_queue_purge(&sk->sk_receive_queue);
+               spin_lock_bh(&rb_queue->lock);
+               pg_vec = XC(rb->pg_vec, pg_vec);
+               rb->frame_max = (req->tp_frame_nr - 1);
+               rb->head = 0;
+               rb->frame_size = req->tp_frame_size;
+               spin_unlock_bh(&rb_queue->lock);
+
+               order = XC(rb->pg_vec_order, order);
+               req->tp_block_nr = XC(rb->pg_vec_len, req->tp_block_nr);
+
+               rb->pg_vec_pages = req->tp_block_size/PAGE_SIZE;
+               po->prot_hook.func = (po->rx_ring.pg_vec) ?
+                                               tpacket_rcv : packet_rcv;
+               skb_queue_purge(rb_queue);
 #undef XC
                if (atomic_read(&po->mapped))
-                       printk(KERN_DEBUG "packet_mmap: vma is busy: %d\n", atomic_read(&po->mapped));
+                       printk(KERN_DEBUG "packet_mmap: vma is busy: %d\n",
+                                               atomic_read(&po->mapped));
        }
        mutex_unlock(&po->pg_vec_lock);
 
@@ -1909,11 +2260,13 @@ out:
        return err;
 }
 
-static int packet_mmap(struct file *file, struct socket *sock, struct vm_area_struct *vma)
+static int packet_mmap(struct file *file, struct socket *sock,
+               struct vm_area_struct *vma)
 {
        struct sock *sk = sock->sk;
        struct packet_sock *po = pkt_sk(sk);
-       unsigned long size;
+       unsigned long size, expected_size;
+       struct packet_ring_buffer *rb;
        unsigned long start;
        int err = -EINVAL;
        int i;
@@ -1921,26 +2274,43 @@ static int packet_mmap(struct file *file, struct socket *sock, struct vm_area_st
        if (vma->vm_pgoff)
                return -EINVAL;
 
-       size = vma->vm_end - vma->vm_start;
-
        mutex_lock(&po->pg_vec_lock);
-       if (po->pg_vec == NULL)
+
+       expected_size = 0;
+       for (rb = &po->rx_ring; rb <= &po->tx_ring; rb++) {
+               if (rb->pg_vec) {
+                       expected_size += rb->pg_vec_len
+                                               * rb->pg_vec_pages
+                                               * PAGE_SIZE;
+               }
+       }
+
+       if (expected_size == 0)
                goto out;
-       if (size != po->pg_vec_len*po->pg_vec_pages*PAGE_SIZE)
+
+       size = vma->vm_end - vma->vm_start;
+       if (size != expected_size)
                goto out;
 
        start = vma->vm_start;
-       for (i = 0; i < po->pg_vec_len; i++) {
-               struct page *page = virt_to_page(po->pg_vec[i]);
-               int pg_num;
-
-               for (pg_num = 0; pg_num < po->pg_vec_pages; pg_num++, page++) {
-                       err = vm_insert_page(vma, start, page);
-                       if (unlikely(err))
-                               goto out;
-                       start += PAGE_SIZE;
+       for (rb = &po->rx_ring; rb <= &po->tx_ring; rb++) {
+               if (rb->pg_vec == NULL)
+                       continue;
+
+               for (i = 0; i < rb->pg_vec_len; i++) {
+                       struct page *page = virt_to_page(rb->pg_vec[i]);
+                       int pg_num;
+
+                       for (pg_num = 0; pg_num < rb->pg_vec_pages;
+                                       pg_num++,page++) {
+                               err = vm_insert_page(vma, start, page);
+                               if (unlikely(err))
+                                       goto out;
+                               start += PAGE_SIZE;
+                       }
                }
        }
+
        atomic_inc(&po->mapped);
        vma->vm_ops = &packet_mmap_ops;
        err = 0;
index 4aa888584d20991893272cd84688f4950c0c40e6..480839dfc5601fa1654d5f4a25606e5ab0fd977e 100644 (file)
@@ -115,10 +115,10 @@ static int gprs_recv(struct gprs_dev *gp, struct sk_buff *skb)
                rskb->truesize += rskb->len;
 
                /* Avoid nested fragments */
-               for (fs = skb_shinfo(skb)->frag_list; fs; fs = fs->next)
+               skb_walk_frags(skb, fs)
                        flen += fs->len;
                skb->next = skb_shinfo(skb)->frag_list;
-               skb_shinfo(skb)->frag_list = NULL;
+               skb_frag_list_init(skb);
                skb->len -= flen;
                skb->data_len -= flen;
                skb->truesize -= flen;
@@ -212,8 +212,9 @@ static int gprs_xmit(struct sk_buff *skb, struct net_device *dev)
                dev->stats.tx_bytes += len;
        }
 
-       if (!pep_writeable(sk))
-               netif_stop_queue(dev);
+       netif_stop_queue(dev);
+       if (pep_writeable(sk))
+               netif_wake_queue(dev);
        return 0;
 }
 
index 8ad2b53338817897c9de166e71bdc4a224b7e62a..eef833ea6d7b6b6d8e2aad01052d3f2337cd9115 100644 (file)
@@ -940,10 +940,10 @@ int pep_write(struct sock *sk, struct sk_buff *skb)
        rskb->truesize += rskb->len;
 
        /* Avoid nested fragments */
-       for (fs = skb_shinfo(skb)->frag_list; fs; fs = fs->next)
+       skb_walk_frags(skb, fs)
                flen += fs->len;
        skb->next = skb_shinfo(skb)->frag_list;
-       skb_shinfo(skb)->frag_list = NULL;
+       skb_frag_list_init(skb);
        skb->len -= flen;
        skb->data_len -= flen;
        skb->truesize -= flen;
index 20cf16fc572f20594fa05d25ee4554a4f30d3d0a..b11e7e5278646993bfda7d6ed78fa2daefd3efde 100644 (file)
@@ -35,7 +35,6 @@
 #include <linux/kernel.h>
 #include <linux/in.h>
 #include <linux/poll.h>
-#include <linux/version.h>
 #include <net/sock.h>
 
 #include "rds.h"
index 273f064930a8e1aec7f8539ed54d928447e7a53a..d14445c48304cb3f4b7a946372186d8578a9b530 100644 (file)
@@ -148,14 +148,12 @@ static struct rds_connection *__rds_conn_create(__be32 laddr, __be32 faddr,
        if (conn)
                goto out;
 
-       conn = kmem_cache_alloc(rds_conn_slab, gfp);
+       conn = kmem_cache_zalloc(rds_conn_slab, gfp);
        if (conn == NULL) {
                conn = ERR_PTR(-ENOMEM);
                goto out;
        }
 
-       memset(conn, 0, sizeof(*conn));
-
        INIT_HLIST_NODE(&conn->c_hash_node);
        conn->c_version = RDS_PROTOCOL_3_0;
        conn->c_laddr = laddr;
index 4933b380985eb730b496dd21152dc470fff7a10c..b9bcd32431e17f19dbc7b5b835a674d59ac8edef 100644 (file)
@@ -224,8 +224,8 @@ static int rds_ib_laddr_check(__be32 addr)
         * IB and iWARP capable NICs.
         */
        cm_id = rdma_create_id(NULL, NULL, RDMA_PS_TCP);
-       if (!cm_id)
-               return -EADDRNOTAVAIL;
+       if (IS_ERR(cm_id))
+               return PTR_ERR(cm_id);
 
        memset(&sin, 0, sizeof(sin));
        sin.sin_family = AF_INET;
index 069206cae733c3a9a88b5efda1b6478a92355b85..455ae73047fe738858eda2166456db0a46da48ac 100644 (file)
@@ -333,7 +333,7 @@ int rds_ib_xmit_rdma(struct rds_connection *conn, struct rds_rdma_op *op);
 void rds_ib_send_add_credits(struct rds_connection *conn, unsigned int credits);
 void rds_ib_advertise_credits(struct rds_connection *conn, unsigned int posted);
 int rds_ib_send_grab_credits(struct rds_ib_connection *ic, u32 wanted,
-                            u32 *adv_credits, int need_posted);
+                            u32 *adv_credits, int need_posted, int max_posted);
 
 /* ib_stats.c */
 DECLARE_PER_CPU(struct rds_ib_statistics, rds_ib_stats);
index 36d931573ff4f4cb52aec684564e142bbea388e9..5709bad28329d2c6d0304e7e85b2728f19cc9e6f 100644 (file)
@@ -524,7 +524,7 @@ void rds_ib_attempt_ack(struct rds_ib_connection *ic)
        }
 
        /* Can we get a send credit? */
-       if (!rds_ib_send_grab_credits(ic, 1, &adv_credits, 0)) {
+       if (!rds_ib_send_grab_credits(ic, 1, &adv_credits, 0, RDS_MAX_ADV_CREDIT)) {
                rds_ib_stats_inc(s_ib_tx_throttle);
                clear_bit(IB_ACK_IN_FLIGHT, &ic->i_ack_flags);
                return;
index 99a6ccae964cbd0e4fd5eccbaa9c38665be26f19..ff97e8eda858bbb2621c1108ab660ecbc0a6fddc 100644 (file)
@@ -137,7 +137,7 @@ int rds_ib_ring_empty(struct rds_ib_work_ring *ring)
 
 int rds_ib_ring_low(struct rds_ib_work_ring *ring)
 {
-       return __rds_ib_ring_used(ring) <= (ring->w_nr >> 2);
+       return __rds_ib_ring_used(ring) <= (ring->w_nr >> 1);
 }
 
 /*
index cb6c52cb1c4c1aa47a085e2d71bdf1b61cf2dfa7..23bf830db2d5a74987c507f2b8d39e20940eefda 100644 (file)
@@ -311,7 +311,7 @@ void rds_ib_send_cq_comp_handler(struct ib_cq *cq, void *context)
  * and using atomic_cmpxchg when updating the two counters.
  */
 int rds_ib_send_grab_credits(struct rds_ib_connection *ic,
-                            u32 wanted, u32 *adv_credits, int need_posted)
+                            u32 wanted, u32 *adv_credits, int need_posted, int max_posted)
 {
        unsigned int avail, posted, got = 0, advertise;
        long oldval, newval;
@@ -351,7 +351,7 @@ try_again:
         * available.
         */
        if (posted && (got || need_posted)) {
-               advertise = min_t(unsigned int, posted, RDS_MAX_ADV_CREDIT);
+               advertise = min_t(unsigned int, posted, max_posted);
                newval -= IB_SET_POST_CREDITS(advertise);
        }
 
@@ -498,7 +498,7 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm,
 
        credit_alloc = work_alloc;
        if (ic->i_flowctl) {
-               credit_alloc = rds_ib_send_grab_credits(ic, work_alloc, &posted, 0);
+               credit_alloc = rds_ib_send_grab_credits(ic, work_alloc, &posted, 0, RDS_MAX_ADV_CREDIT);
                adv_credits += posted;
                if (credit_alloc < work_alloc) {
                        rds_ib_ring_unalloc(&ic->i_send_ring, work_alloc - credit_alloc);
@@ -506,7 +506,7 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm,
                        flow_controlled++;
                }
                if (work_alloc == 0) {
-                       rds_ib_ring_unalloc(&ic->i_send_ring, work_alloc);
+                       set_bit(RDS_LL_SEND_FULL, &conn->c_flags);
                        rds_ib_stats_inc(s_ib_tx_throttle);
                        ret = -ENOMEM;
                        goto out;
@@ -571,7 +571,7 @@ int rds_ib_xmit(struct rds_connection *conn, struct rds_message *rm,
                /*
                 * Update adv_credits since we reset the ACK_REQUIRED bit.
                 */
-               rds_ib_send_grab_credits(ic, 0, &posted, 1);
+               rds_ib_send_grab_credits(ic, 0, &posted, 1, RDS_MAX_ADV_CREDIT - adv_credits);
                adv_credits += posted;
                BUG_ON(adv_credits > 255);
        } else if (ic->i_rm != rm)
index 1d885535214dba2ba7567bed1b005e391fa9d675..62aeef37aefe772626644edfa1a1be318a725337 100644 (file)
@@ -188,10 +188,7 @@ int rds_info_getsockopt(struct socket *sock, int optname, char __user *optval,
                ret = -ENOMEM;
                goto out;
        }
-       down_read(&current->mm->mmap_sem);
-       ret = get_user_pages(current, current->mm, start, nr_pages, 1, 0,
-                            pages, NULL);
-       up_read(&current->mm->mmap_sem);
+       ret = get_user_pages_fast(start, nr_pages, 1, pages);
        if (ret != nr_pages) {
                if (ret > 0)
                        nr_pages = ret;
index b732efb5b6345b0e5e923388258b500c4eb04208..d16e1cbc8e836559243e809fca5953f3471f0439 100644 (file)
@@ -233,8 +233,8 @@ static int rds_iw_laddr_check(__be32 addr)
         * IB and iWARP capable NICs.
         */
        cm_id = rdma_create_id(NULL, NULL, RDMA_PS_TCP);
-       if (!cm_id)
-               return -EADDRNOTAVAIL;
+       if (IS_ERR(cm_id))
+               return PTR_ERR(cm_id);
 
        memset(&sin, 0, sizeof(sin));
        sin.sin_family = AF_INET;
index b4fb27252895adb45a1cf635ee441741b392cc5d..0715dde323e77c88a56f50e591bb065a900efbca 100644 (file)
@@ -361,7 +361,7 @@ int rds_iw_xmit_rdma(struct rds_connection *conn, struct rds_rdma_op *op);
 void rds_iw_send_add_credits(struct rds_connection *conn, unsigned int credits);
 void rds_iw_advertise_credits(struct rds_connection *conn, unsigned int posted);
 int rds_iw_send_grab_credits(struct rds_iw_connection *ic, u32 wanted,
-                            u32 *adv_credits, int need_posted);
+                            u32 *adv_credits, int need_posted, int max_posted);
 
 /* ib_stats.c */
 DECLARE_PER_CPU(struct rds_iw_statistics, rds_iw_stats);
index fde470fa50d5457c72226d0336e00aeed8df534d..8683f5f66c4b2931583b84e1f40daeeecaf2e64b 100644 (file)
@@ -524,7 +524,7 @@ void rds_iw_attempt_ack(struct rds_iw_connection *ic)
        }
 
        /* Can we get a send credit? */
-       if (!rds_iw_send_grab_credits(ic, 1, &adv_credits, 0)) {
+       if (!rds_iw_send_grab_credits(ic, 1, &adv_credits, 0, RDS_MAX_ADV_CREDIT)) {
                rds_iw_stats_inc(s_iw_tx_throttle);
                clear_bit(IB_ACK_IN_FLIGHT, &ic->i_ack_flags);
                return;
index d422d4b5deef2b49c183d6030db61d09a98a8729..da8e3b63f66363c67a73700ba356179bbf2fbfc7 100644 (file)
@@ -137,7 +137,7 @@ int rds_iw_ring_empty(struct rds_iw_work_ring *ring)
 
 int rds_iw_ring_low(struct rds_iw_work_ring *ring)
 {
-       return __rds_iw_ring_used(ring) <= (ring->w_nr >> 2);
+       return __rds_iw_ring_used(ring) <= (ring->w_nr >> 1);
 }
 
 
index 22dd38ffd6080843afd8ddc3987ff2a4490369eb..44a6a0551f28951f8bb69fb2e224e308a7f99fc1 100644 (file)
@@ -347,7 +347,7 @@ void rds_iw_send_cq_comp_handler(struct ib_cq *cq, void *context)
  * and using atomic_cmpxchg when updating the two counters.
  */
 int rds_iw_send_grab_credits(struct rds_iw_connection *ic,
-                            u32 wanted, u32 *adv_credits, int need_posted)
+                            u32 wanted, u32 *adv_credits, int need_posted, int max_posted)
 {
        unsigned int avail, posted, got = 0, advertise;
        long oldval, newval;
@@ -387,7 +387,7 @@ try_again:
         * available.
         */
        if (posted && (got || need_posted)) {
-               advertise = min_t(unsigned int, posted, RDS_MAX_ADV_CREDIT);
+               advertise = min_t(unsigned int, posted, max_posted);
                newval -= IB_SET_POST_CREDITS(advertise);
        }
 
@@ -541,7 +541,7 @@ int rds_iw_xmit(struct rds_connection *conn, struct rds_message *rm,
 
        credit_alloc = work_alloc;
        if (ic->i_flowctl) {
-               credit_alloc = rds_iw_send_grab_credits(ic, work_alloc, &posted, 0);
+               credit_alloc = rds_iw_send_grab_credits(ic, work_alloc, &posted, 0, RDS_MAX_ADV_CREDIT);
                adv_credits += posted;
                if (credit_alloc < work_alloc) {
                        rds_iw_ring_unalloc(&ic->i_send_ring, work_alloc - credit_alloc);
@@ -549,7 +549,7 @@ int rds_iw_xmit(struct rds_connection *conn, struct rds_message *rm,
                        flow_controlled++;
                }
                if (work_alloc == 0) {
-                       rds_iw_ring_unalloc(&ic->i_send_ring, work_alloc);
+                       set_bit(RDS_LL_SEND_FULL, &conn->c_flags);
                        rds_iw_stats_inc(s_iw_tx_throttle);
                        ret = -ENOMEM;
                        goto out;
@@ -614,7 +614,7 @@ int rds_iw_xmit(struct rds_connection *conn, struct rds_message *rm,
                /*
                 * Update adv_credits since we reset the ACK_REQUIRED bit.
                 */
-               rds_iw_send_grab_credits(ic, 0, &posted, 1);
+               rds_iw_send_grab_credits(ic, 0, &posted, 1, RDS_MAX_ADV_CREDIT - adv_credits);
                adv_credits += posted;
                BUG_ON(adv_credits > 255);
        } else if (ic->i_rm != rm)
index eaeeb91e11196a07405ee9cbfc417c7da3793ea3..8dc83d2caa58d02d7036ea697a5fac65f470b564 100644 (file)
@@ -150,12 +150,9 @@ static int rds_pin_pages(unsigned long user_addr, unsigned int nr_pages,
 {
        int ret;
 
-       down_read(&current->mm->mmap_sem);
-       ret = get_user_pages(current, current->mm, user_addr,
-                            nr_pages, write, 0, pages, NULL);
-       up_read(&current->mm->mmap_sem);
+       ret = get_user_pages_fast(user_addr, nr_pages, write, pages);
 
-       if (0 <= ret && (unsigned) ret < nr_pages) {
+       if (ret >= 0 && ret < nr_pages) {
                while (ret--)
                        put_page(pages[ret]);
                ret = -EFAULT;
index 7b19024f97069e00340c20cb07daee54e28835de..7d0f901c93d505a3d33e08b4a1449dba31296e61 100644 (file)
@@ -34,7 +34,7 @@
 
 #include "rdma_transport.h"
 
-static struct rdma_cm_id *rds_iw_listen_id;
+static struct rdma_cm_id *rds_rdma_listen_id;
 
 int rds_rdma_cm_event_handler(struct rdma_cm_id *cm_id,
                              struct rdma_cm_event *event)
@@ -161,7 +161,7 @@ static int __init rds_rdma_listen_init(void)
 
        rdsdebug("cm %p listening on port %u\n", cm_id, RDS_PORT);
 
-       rds_iw_listen_id = cm_id;
+       rds_rdma_listen_id = cm_id;
        cm_id = NULL;
 out:
        if (cm_id)
@@ -171,10 +171,10 @@ out:
 
 static void rds_rdma_listen_stop(void)
 {
-       if (rds_iw_listen_id) {
-               rdsdebug("cm %p\n", rds_iw_listen_id);
-               rdma_destroy_id(rds_iw_listen_id);
-               rds_iw_listen_id = NULL;
+       if (rds_rdma_listen_id) {
+               rdsdebug("cm %p\n", rds_rdma_listen_id);
+               rdma_destroy_id(rds_rdma_listen_id);
+               rds_rdma_listen_id = NULL;
        }
 }
 
index 71794449ca4e58ffdbada8ac274a85b87418bf38..dbe111236783d81497a730f3765b6a748c60dacb 100644 (file)
@@ -132,7 +132,7 @@ struct rds_connection {
 #define RDS_FLAG_CONG_BITMAP   0x01
 #define RDS_FLAG_ACK_REQUIRED  0x02
 #define RDS_FLAG_RETRANSMITTED 0x04
-#define RDS_MAX_ADV_CREDIT     127
+#define RDS_MAX_ADV_CREDIT     255
 
 /*
  * Maximum space available for extension headers.
index 104fe033203da51eeef849782e1c291e072cdde6..a4a7f428cd7604d11e654133ef11d05adc9b2a9e 100644 (file)
@@ -854,11 +854,6 @@ int rds_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
 
        rm->m_daddr = daddr;
 
-       /* Parse any control messages the user may have included. */
-       ret = rds_cmsg_send(rs, rm, msg, &allocated_mr);
-       if (ret)
-               goto out;
-
        /* rds_conn_create has a spinlock that runs with IRQ off.
         * Caching the conn in the socket helps a lot. */
        if (rs->rs_conn && rs->rs_conn->c_faddr == daddr)
@@ -874,6 +869,11 @@ int rds_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
                rs->rs_conn = conn;
        }
 
+       /* Parse any control messages the user may have included. */
+       ret = rds_cmsg_send(rs, rm, msg, &allocated_mr);
+       if (ret)
+               goto out;
+
        if ((rm->m_rdma_cookie || rm->m_rdma_op)
         && conn->c_trans->xmit_rdma == NULL) {
                if (printk_ratelimit())
index 7f807b30cfbbc2b50a57d3d6531106a24db7d03d..eaf765876458f3a89e5a26af5d5ac3b09c556161 100644 (file)
@@ -10,22 +10,15 @@ menuconfig RFKILL
          To compile this driver as a module, choose M here: the
          module will be called rfkill.
 
-config RFKILL_INPUT
-       tristate "Input layer to RF switch connector"
-       depends on RFKILL && INPUT
-       help
-         Say Y here if you want kernel automatically toggle state
-         of RF switches on and off when user presses appropriate
-         button or a key on the keyboard. Without this module you
-         need a some kind of userspace application to control
-         state of the switches.
-
-         To compile this driver as a module, choose M here: the
-         module will be called rfkill-input.
-
 # LED trigger support
 config RFKILL_LEDS
        bool
-       depends on RFKILL && LEDS_TRIGGERS
+       depends on RFKILL
+       depends on LEDS_TRIGGERS = y || RFKILL = LEDS_TRIGGERS
        default y
 
+config RFKILL_INPUT
+       bool "RF switch input support" if EMBEDDED
+       depends on RFKILL
+       depends on INPUT = y || RFKILL = INPUT
+       default y if !EMBEDDED
index b38c430be05777d27c17f82e3e1bf46ca285c807..662105352691d3737a4556906828a01c70d022c5 100644 (file)
@@ -2,5 +2,6 @@
 # Makefile for the RF switch subsystem.
 #
 
-obj-$(CONFIG_RFKILL)                   += rfkill.o
-obj-$(CONFIG_RFKILL_INPUT)             += rfkill-input.o
+rfkill-y                       += core.o
+rfkill-$(CONFIG_RFKILL_INPUT)  += input.o
+obj-$(CONFIG_RFKILL)           += rfkill.o
diff --git a/net/rfkill/core.c b/net/rfkill/core.c
new file mode 100644 (file)
index 0000000..4e68ab4
--- /dev/null
@@ -0,0 +1,1205 @@
+/*
+ * Copyright (C) 2006 - 2007 Ivo van Doorn
+ * Copyright (C) 2007 Dmitry Torokhov
+ * Copyright 2009 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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the
+ * Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/workqueue.h>
+#include <linux/capability.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <linux/rfkill.h>
+#include <linux/spinlock.h>
+#include <linux/miscdevice.h>
+#include <linux/wait.h>
+#include <linux/poll.h>
+#include <linux/fs.h>
+
+#include "rfkill.h"
+
+#define POLL_INTERVAL          (5 * HZ)
+
+#define RFKILL_BLOCK_HW                BIT(0)
+#define RFKILL_BLOCK_SW                BIT(1)
+#define RFKILL_BLOCK_SW_PREV   BIT(2)
+#define RFKILL_BLOCK_ANY       (RFKILL_BLOCK_HW |\
+                                RFKILL_BLOCK_SW |\
+                                RFKILL_BLOCK_SW_PREV)
+#define RFKILL_BLOCK_SW_SETCALL        BIT(31)
+
+struct rfkill {
+       spinlock_t              lock;
+
+       const char              *name;
+       enum rfkill_type        type;
+
+       unsigned long           state;
+
+       u32                     idx;
+
+       bool                    registered;
+       bool                    suspended;
+       bool                    persistent;
+
+       const struct rfkill_ops *ops;
+       void                    *data;
+
+#ifdef CONFIG_RFKILL_LEDS
+       struct led_trigger      led_trigger;
+       const char              *ledtrigname;
+#endif
+
+       struct device           dev;
+       struct list_head        node;
+
+       struct delayed_work     poll_work;
+       struct work_struct      uevent_work;
+       struct work_struct      sync_work;
+};
+#define to_rfkill(d)   container_of(d, struct rfkill, dev)
+
+struct rfkill_int_event {
+       struct list_head        list;
+       struct rfkill_event     ev;
+};
+
+struct rfkill_data {
+       struct list_head        list;
+       struct list_head        events;
+       struct mutex            mtx;
+       wait_queue_head_t       read_wait;
+       bool                    input_handler;
+};
+
+
+MODULE_AUTHOR("Ivo van Doorn <IvDoorn@gmail.com>");
+MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
+MODULE_DESCRIPTION("RF switch support");
+MODULE_LICENSE("GPL");
+
+
+/*
+ * The locking here should be made much smarter, we currently have
+ * a bit of a stupid situation because drivers might want to register
+ * the rfkill struct under their own lock, and take this lock during
+ * rfkill method calls -- which will cause an AB-BA deadlock situation.
+ *
+ * To fix that, we need to rework this code here to be mostly lock-free
+ * and only use the mutex for list manipulations, not to protect the
+ * various other global variables. Then we can avoid holding the mutex
+ * around driver operations, and all is happy.
+ */
+static LIST_HEAD(rfkill_list); /* list of registered rf switches */
+static DEFINE_MUTEX(rfkill_global_mutex);
+static LIST_HEAD(rfkill_fds);  /* list of open fds of /dev/rfkill */
+
+static unsigned int rfkill_default_state = 1;
+module_param_named(default_state, rfkill_default_state, uint, 0444);
+MODULE_PARM_DESC(default_state,
+                "Default initial state for all radio types, 0 = radio off");
+
+static struct {
+       bool cur, sav;
+} rfkill_global_states[NUM_RFKILL_TYPES];
+
+static bool rfkill_epo_lock_active;
+
+
+#ifdef CONFIG_RFKILL_LEDS
+static void rfkill_led_trigger_event(struct rfkill *rfkill)
+{
+       struct led_trigger *trigger;
+
+       if (!rfkill->registered)
+               return;
+
+       trigger = &rfkill->led_trigger;
+
+       if (rfkill->state & RFKILL_BLOCK_ANY)
+               led_trigger_event(trigger, LED_OFF);
+       else
+               led_trigger_event(trigger, LED_FULL);
+}
+
+static void rfkill_led_trigger_activate(struct led_classdev *led)
+{
+       struct rfkill *rfkill;
+
+       rfkill = container_of(led->trigger, struct rfkill, led_trigger);
+
+       rfkill_led_trigger_event(rfkill);
+}
+
+const char *rfkill_get_led_trigger_name(struct rfkill *rfkill)
+{
+       return rfkill->led_trigger.name;
+}
+EXPORT_SYMBOL(rfkill_get_led_trigger_name);
+
+void rfkill_set_led_trigger_name(struct rfkill *rfkill, const char *name)
+{
+       BUG_ON(!rfkill);
+
+       rfkill->ledtrigname = name;
+}
+EXPORT_SYMBOL(rfkill_set_led_trigger_name);
+
+static int rfkill_led_trigger_register(struct rfkill *rfkill)
+{
+       rfkill->led_trigger.name = rfkill->ledtrigname
+                                       ? : dev_name(&rfkill->dev);
+       rfkill->led_trigger.activate = rfkill_led_trigger_activate;
+       return led_trigger_register(&rfkill->led_trigger);
+}
+
+static void rfkill_led_trigger_unregister(struct rfkill *rfkill)
+{
+       led_trigger_unregister(&rfkill->led_trigger);
+}
+#else
+static void rfkill_led_trigger_event(struct rfkill *rfkill)
+{
+}
+
+static inline int rfkill_led_trigger_register(struct rfkill *rfkill)
+{
+       return 0;
+}
+
+static inline void rfkill_led_trigger_unregister(struct rfkill *rfkill)
+{
+}
+#endif /* CONFIG_RFKILL_LEDS */
+
+static void rfkill_fill_event(struct rfkill_event *ev, struct rfkill *rfkill,
+                             enum rfkill_operation op)
+{
+       unsigned long flags;
+
+       ev->idx = rfkill->idx;
+       ev->type = rfkill->type;
+       ev->op = op;
+
+       spin_lock_irqsave(&rfkill->lock, flags);
+       ev->hard = !!(rfkill->state & RFKILL_BLOCK_HW);
+       ev->soft = !!(rfkill->state & (RFKILL_BLOCK_SW |
+                                       RFKILL_BLOCK_SW_PREV));
+       spin_unlock_irqrestore(&rfkill->lock, flags);
+}
+
+static void rfkill_send_events(struct rfkill *rfkill, enum rfkill_operation op)
+{
+       struct rfkill_data *data;
+       struct rfkill_int_event *ev;
+
+       list_for_each_entry(data, &rfkill_fds, list) {
+               ev = kzalloc(sizeof(*ev), GFP_KERNEL);
+               if (!ev)
+                       continue;
+               rfkill_fill_event(&ev->ev, rfkill, op);
+               mutex_lock(&data->mtx);
+               list_add_tail(&ev->list, &data->events);
+               mutex_unlock(&data->mtx);
+               wake_up_interruptible(&data->read_wait);
+       }
+}
+
+static void rfkill_event(struct rfkill *rfkill)
+{
+       if (!rfkill->registered || rfkill->suspended)
+               return;
+
+       kobject_uevent(&rfkill->dev.kobj, KOBJ_CHANGE);
+
+       /* also send event to /dev/rfkill */
+       rfkill_send_events(rfkill, RFKILL_OP_CHANGE);
+}
+
+static bool __rfkill_set_hw_state(struct rfkill *rfkill,
+                                 bool blocked, bool *change)
+{
+       unsigned long flags;
+       bool prev, any;
+
+       BUG_ON(!rfkill);
+
+       spin_lock_irqsave(&rfkill->lock, flags);
+       prev = !!(rfkill->state & RFKILL_BLOCK_HW);
+       if (blocked)
+               rfkill->state |= RFKILL_BLOCK_HW;
+       else
+               rfkill->state &= ~RFKILL_BLOCK_HW;
+       *change = prev != blocked;
+       any = rfkill->state & RFKILL_BLOCK_ANY;
+       spin_unlock_irqrestore(&rfkill->lock, flags);
+
+       rfkill_led_trigger_event(rfkill);
+
+       return any;
+}
+
+/**
+ * rfkill_set_block - wrapper for set_block method
+ *
+ * @rfkill: the rfkill struct to use
+ * @blocked: the new software state
+ *
+ * Calls the set_block method (when applicable) and handles notifications
+ * etc. as well.
+ */
+static void rfkill_set_block(struct rfkill *rfkill, bool blocked)
+{
+       unsigned long flags;
+       int err;
+
+       /*
+        * Some platforms (...!) generate input events which affect the
+        * _hard_ kill state -- whenever something tries to change the
+        * current software state query the hardware state too.
+        */
+       if (rfkill->ops->query)
+               rfkill->ops->query(rfkill, rfkill->data);
+
+       spin_lock_irqsave(&rfkill->lock, flags);
+       if (rfkill->state & RFKILL_BLOCK_SW)
+               rfkill->state |= RFKILL_BLOCK_SW_PREV;
+       else
+               rfkill->state &= ~RFKILL_BLOCK_SW_PREV;
+
+       if (blocked)
+               rfkill->state |= RFKILL_BLOCK_SW;
+       else
+               rfkill->state &= ~RFKILL_BLOCK_SW;
+
+       rfkill->state |= RFKILL_BLOCK_SW_SETCALL;
+       spin_unlock_irqrestore(&rfkill->lock, flags);
+
+       if (unlikely(rfkill->dev.power.power_state.event & PM_EVENT_SLEEP))
+               return;
+
+       err = rfkill->ops->set_block(rfkill->data, blocked);
+
+       spin_lock_irqsave(&rfkill->lock, flags);
+       if (err) {
+               /*
+                * Failed -- reset status to _prev, this may be different
+                * from what set set _PREV to earlier in this function
+                * if rfkill_set_sw_state was invoked.
+                */
+               if (rfkill->state & RFKILL_BLOCK_SW_PREV)
+                       rfkill->state |= RFKILL_BLOCK_SW;
+               else
+                       rfkill->state &= ~RFKILL_BLOCK_SW;
+       }
+       rfkill->state &= ~RFKILL_BLOCK_SW_SETCALL;
+       rfkill->state &= ~RFKILL_BLOCK_SW_PREV;
+       spin_unlock_irqrestore(&rfkill->lock, flags);
+
+       rfkill_led_trigger_event(rfkill);
+       rfkill_event(rfkill);
+}
+
+#ifdef CONFIG_RFKILL_INPUT
+static atomic_t rfkill_input_disabled = ATOMIC_INIT(0);
+
+/**
+ * __rfkill_switch_all - Toggle state of all switches of given type
+ * @type: type of interfaces to be affected
+ * @state: the new state
+ *
+ * This function sets the state of all switches of given type,
+ * unless a specific switch is claimed by userspace (in which case,
+ * that switch is left alone) or suspended.
+ *
+ * Caller must have acquired rfkill_global_mutex.
+ */
+static void __rfkill_switch_all(const enum rfkill_type type, bool blocked)
+{
+       struct rfkill *rfkill;
+
+       rfkill_global_states[type].cur = blocked;
+       list_for_each_entry(rfkill, &rfkill_list, node) {
+               if (rfkill->type != type)
+                       continue;
+
+               rfkill_set_block(rfkill, blocked);
+       }
+}
+
+/**
+ * rfkill_switch_all - Toggle state of all switches of given type
+ * @type: type of interfaces to be affected
+ * @state: the new state
+ *
+ * Acquires rfkill_global_mutex and calls __rfkill_switch_all(@type, @state).
+ * Please refer to __rfkill_switch_all() for details.
+ *
+ * Does nothing if the EPO lock is active.
+ */
+void rfkill_switch_all(enum rfkill_type type, bool blocked)
+{
+       if (atomic_read(&rfkill_input_disabled))
+               return;
+
+       mutex_lock(&rfkill_global_mutex);
+
+       if (!rfkill_epo_lock_active)
+               __rfkill_switch_all(type, blocked);
+
+       mutex_unlock(&rfkill_global_mutex);
+}
+
+/**
+ * rfkill_epo - emergency power off all transmitters
+ *
+ * This kicks all non-suspended rfkill devices to RFKILL_STATE_SOFT_BLOCKED,
+ * ignoring everything in its path but rfkill_global_mutex and rfkill->mutex.
+ *
+ * The global state before the EPO is saved and can be restored later
+ * using rfkill_restore_states().
+ */
+void rfkill_epo(void)
+{
+       struct rfkill *rfkill;
+       int i;
+
+       if (atomic_read(&rfkill_input_disabled))
+               return;
+
+       mutex_lock(&rfkill_global_mutex);
+
+       rfkill_epo_lock_active = true;
+       list_for_each_entry(rfkill, &rfkill_list, node)
+               rfkill_set_block(rfkill, true);
+
+       for (i = 0; i < NUM_RFKILL_TYPES; i++) {
+               rfkill_global_states[i].sav = rfkill_global_states[i].cur;
+               rfkill_global_states[i].cur = true;
+       }
+
+       mutex_unlock(&rfkill_global_mutex);
+}
+
+/**
+ * rfkill_restore_states - restore global states
+ *
+ * Restore (and sync switches to) the global state from the
+ * states in rfkill_default_states.  This can undo the effects of
+ * a call to rfkill_epo().
+ */
+void rfkill_restore_states(void)
+{
+       int i;
+
+       if (atomic_read(&rfkill_input_disabled))
+               return;
+
+       mutex_lock(&rfkill_global_mutex);
+
+       rfkill_epo_lock_active = false;
+       for (i = 0; i < NUM_RFKILL_TYPES; i++)
+               __rfkill_switch_all(i, rfkill_global_states[i].sav);
+       mutex_unlock(&rfkill_global_mutex);
+}
+
+/**
+ * rfkill_remove_epo_lock - unlock state changes
+ *
+ * Used by rfkill-input manually unlock state changes, when
+ * the EPO switch is deactivated.
+ */
+void rfkill_remove_epo_lock(void)
+{
+       if (atomic_read(&rfkill_input_disabled))
+               return;
+
+       mutex_lock(&rfkill_global_mutex);
+       rfkill_epo_lock_active = false;
+       mutex_unlock(&rfkill_global_mutex);
+}
+
+/**
+ * rfkill_is_epo_lock_active - returns true EPO is active
+ *
+ * Returns 0 (false) if there is NOT an active EPO contidion,
+ * and 1 (true) if there is an active EPO contition, which
+ * locks all radios in one of the BLOCKED states.
+ *
+ * Can be called in atomic context.
+ */
+bool rfkill_is_epo_lock_active(void)
+{
+       return rfkill_epo_lock_active;
+}
+
+/**
+ * rfkill_get_global_sw_state - returns global state for a type
+ * @type: the type to get the global state of
+ *
+ * Returns the current global state for a given wireless
+ * device type.
+ */
+bool rfkill_get_global_sw_state(const enum rfkill_type type)
+{
+       return rfkill_global_states[type].cur;
+}
+#endif
+
+
+bool rfkill_set_hw_state(struct rfkill *rfkill, bool blocked)
+{
+       bool ret, change;
+
+       ret = __rfkill_set_hw_state(rfkill, blocked, &change);
+
+       if (!rfkill->registered)
+               return ret;
+
+       if (change)
+               schedule_work(&rfkill->uevent_work);
+
+       return ret;
+}
+EXPORT_SYMBOL(rfkill_set_hw_state);
+
+static void __rfkill_set_sw_state(struct rfkill *rfkill, bool blocked)
+{
+       u32 bit = RFKILL_BLOCK_SW;
+
+       /* if in a ops->set_block right now, use other bit */
+       if (rfkill->state & RFKILL_BLOCK_SW_SETCALL)
+               bit = RFKILL_BLOCK_SW_PREV;
+
+       if (blocked)
+               rfkill->state |= bit;
+       else
+               rfkill->state &= ~bit;
+}
+
+bool rfkill_set_sw_state(struct rfkill *rfkill, bool blocked)
+{
+       unsigned long flags;
+       bool prev, hwblock;
+
+       BUG_ON(!rfkill);
+
+       spin_lock_irqsave(&rfkill->lock, flags);
+       prev = !!(rfkill->state & RFKILL_BLOCK_SW);
+       __rfkill_set_sw_state(rfkill, blocked);
+       hwblock = !!(rfkill->state & RFKILL_BLOCK_HW);
+       blocked = blocked || hwblock;
+       spin_unlock_irqrestore(&rfkill->lock, flags);
+
+       if (!rfkill->registered) {
+               rfkill->persistent = true;
+       } else {
+               if (prev != blocked && !hwblock)
+                       schedule_work(&rfkill->uevent_work);
+
+               rfkill_led_trigger_event(rfkill);
+       }
+
+       return blocked;
+}
+EXPORT_SYMBOL(rfkill_set_sw_state);
+
+void rfkill_set_states(struct rfkill *rfkill, bool sw, bool hw)
+{
+       unsigned long flags;
+       bool swprev, hwprev;
+
+       BUG_ON(!rfkill);
+
+       spin_lock_irqsave(&rfkill->lock, flags);
+
+       /*
+        * No need to care about prev/setblock ... this is for uevent only
+        * and that will get triggered by rfkill_set_block anyway.
+        */
+       swprev = !!(rfkill->state & RFKILL_BLOCK_SW);
+       hwprev = !!(rfkill->state & RFKILL_BLOCK_HW);
+       __rfkill_set_sw_state(rfkill, sw);
+
+       spin_unlock_irqrestore(&rfkill->lock, flags);
+
+       if (!rfkill->registered) {
+               rfkill->persistent = true;
+       } else {
+               if (swprev != sw || hwprev != hw)
+                       schedule_work(&rfkill->uevent_work);
+
+               rfkill_led_trigger_event(rfkill);
+       }
+}
+EXPORT_SYMBOL(rfkill_set_states);
+
+static ssize_t rfkill_name_show(struct device *dev,
+                               struct device_attribute *attr,
+                               char *buf)
+{
+       struct rfkill *rfkill = to_rfkill(dev);
+
+       return sprintf(buf, "%s\n", rfkill->name);
+}
+
+static const char *rfkill_get_type_str(enum rfkill_type type)
+{
+       switch (type) {
+       case RFKILL_TYPE_WLAN:
+               return "wlan";
+       case RFKILL_TYPE_BLUETOOTH:
+               return "bluetooth";
+       case RFKILL_TYPE_UWB:
+               return "ultrawideband";
+       case RFKILL_TYPE_WIMAX:
+               return "wimax";
+       case RFKILL_TYPE_WWAN:
+               return "wwan";
+       default:
+               BUG();
+       }
+
+       BUILD_BUG_ON(NUM_RFKILL_TYPES != RFKILL_TYPE_WWAN + 1);
+}
+
+static ssize_t rfkill_type_show(struct device *dev,
+                               struct device_attribute *attr,
+                               char *buf)
+{
+       struct rfkill *rfkill = to_rfkill(dev);
+
+       return sprintf(buf, "%s\n", rfkill_get_type_str(rfkill->type));
+}
+
+static ssize_t rfkill_idx_show(struct device *dev,
+                              struct device_attribute *attr,
+                              char *buf)
+{
+       struct rfkill *rfkill = to_rfkill(dev);
+
+       return sprintf(buf, "%d\n", rfkill->idx);
+}
+
+static u8 user_state_from_blocked(unsigned long state)
+{
+       if (state & RFKILL_BLOCK_HW)
+               return RFKILL_USER_STATE_HARD_BLOCKED;
+       if (state & RFKILL_BLOCK_SW)
+               return RFKILL_USER_STATE_SOFT_BLOCKED;
+
+       return RFKILL_USER_STATE_UNBLOCKED;
+}
+
+static ssize_t rfkill_state_show(struct device *dev,
+                                struct device_attribute *attr,
+                                char *buf)
+{
+       struct rfkill *rfkill = to_rfkill(dev);
+       unsigned long flags;
+       u32 state;
+
+       spin_lock_irqsave(&rfkill->lock, flags);
+       state = rfkill->state;
+       spin_unlock_irqrestore(&rfkill->lock, flags);
+
+       return sprintf(buf, "%d\n", user_state_from_blocked(state));
+}
+
+static ssize_t rfkill_state_store(struct device *dev,
+                                 struct device_attribute *attr,
+                                 const char *buf, size_t count)
+{
+       /*
+        * The intention was that userspace can only take control over
+        * a given device when/if rfkill-input doesn't control it due
+        * to user_claim. Since user_claim is currently unsupported,
+        * we never support changing the state from userspace -- this
+        * can be implemented again later.
+        */
+
+       return -EPERM;
+}
+
+static ssize_t rfkill_claim_show(struct device *dev,
+                                struct device_attribute *attr,
+                                char *buf)
+{
+       return sprintf(buf, "%d\n", 0);
+}
+
+static ssize_t rfkill_claim_store(struct device *dev,
+                                 struct device_attribute *attr,
+                                 const char *buf, size_t count)
+{
+       return -EOPNOTSUPP;
+}
+
+static struct device_attribute rfkill_dev_attrs[] = {
+       __ATTR(name, S_IRUGO, rfkill_name_show, NULL),
+       __ATTR(type, S_IRUGO, rfkill_type_show, NULL),
+       __ATTR(index, S_IRUGO, rfkill_idx_show, NULL),
+       __ATTR(state, S_IRUGO|S_IWUSR, rfkill_state_show, rfkill_state_store),
+       __ATTR(claim, S_IRUGO|S_IWUSR, rfkill_claim_show, rfkill_claim_store),
+       __ATTR_NULL
+};
+
+static void rfkill_release(struct device *dev)
+{
+       struct rfkill *rfkill = to_rfkill(dev);
+
+       kfree(rfkill);
+}
+
+static int rfkill_dev_uevent(struct device *dev, struct kobj_uevent_env *env)
+{
+       struct rfkill *rfkill = to_rfkill(dev);
+       unsigned long flags;
+       u32 state;
+       int error;
+
+       error = add_uevent_var(env, "RFKILL_NAME=%s", rfkill->name);
+       if (error)
+               return error;
+       error = add_uevent_var(env, "RFKILL_TYPE=%s",
+                              rfkill_get_type_str(rfkill->type));
+       if (error)
+               return error;
+       spin_lock_irqsave(&rfkill->lock, flags);
+       state = rfkill->state;
+       spin_unlock_irqrestore(&rfkill->lock, flags);
+       error = add_uevent_var(env, "RFKILL_STATE=%d",
+                              user_state_from_blocked(state));
+       return error;
+}
+
+void rfkill_pause_polling(struct rfkill *rfkill)
+{
+       BUG_ON(!rfkill);
+
+       if (!rfkill->ops->poll)
+               return;
+
+       cancel_delayed_work_sync(&rfkill->poll_work);
+}
+EXPORT_SYMBOL(rfkill_pause_polling);
+
+void rfkill_resume_polling(struct rfkill *rfkill)
+{
+       BUG_ON(!rfkill);
+
+       if (!rfkill->ops->poll)
+               return;
+
+       schedule_work(&rfkill->poll_work.work);
+}
+EXPORT_SYMBOL(rfkill_resume_polling);
+
+static int rfkill_suspend(struct device *dev, pm_message_t state)
+{
+       struct rfkill *rfkill = to_rfkill(dev);
+
+       rfkill_pause_polling(rfkill);
+
+       rfkill->suspended = true;
+
+       return 0;
+}
+
+static int rfkill_resume(struct device *dev)
+{
+       struct rfkill *rfkill = to_rfkill(dev);
+       bool cur;
+
+       cur = !!(rfkill->state & RFKILL_BLOCK_SW);
+       rfkill_set_block(rfkill, cur);
+
+       rfkill->suspended = false;
+
+       rfkill_resume_polling(rfkill);
+
+       return 0;
+}
+
+static struct class rfkill_class = {
+       .name           = "rfkill",
+       .dev_release    = rfkill_release,
+       .dev_attrs      = rfkill_dev_attrs,
+       .dev_uevent     = rfkill_dev_uevent,
+       .suspend        = rfkill_suspend,
+       .resume         = rfkill_resume,
+};
+
+bool rfkill_blocked(struct rfkill *rfkill)
+{
+       unsigned long flags;
+       u32 state;
+
+       spin_lock_irqsave(&rfkill->lock, flags);
+       state = rfkill->state;
+       spin_unlock_irqrestore(&rfkill->lock, flags);
+
+       return !!(state & RFKILL_BLOCK_ANY);
+}
+EXPORT_SYMBOL(rfkill_blocked);
+
+
+struct rfkill * __must_check rfkill_alloc(const char *name,
+                                         struct device *parent,
+                                         const enum rfkill_type type,
+                                         const struct rfkill_ops *ops,
+                                         void *ops_data)
+{
+       struct rfkill *rfkill;
+       struct device *dev;
+
+       if (WARN_ON(!ops))
+               return NULL;
+
+       if (WARN_ON(!ops->set_block))
+               return NULL;
+
+       if (WARN_ON(!name))
+               return NULL;
+
+       if (WARN_ON(type == RFKILL_TYPE_ALL || type >= NUM_RFKILL_TYPES))
+               return NULL;
+
+       rfkill = kzalloc(sizeof(*rfkill), GFP_KERNEL);
+       if (!rfkill)
+               return NULL;
+
+       spin_lock_init(&rfkill->lock);
+       INIT_LIST_HEAD(&rfkill->node);
+       rfkill->type = type;
+       rfkill->name = name;
+       rfkill->ops = ops;
+       rfkill->data = ops_data;
+
+       dev = &rfkill->dev;
+       dev->class = &rfkill_class;
+       dev->parent = parent;
+       device_initialize(dev);
+
+       return rfkill;
+}
+EXPORT_SYMBOL(rfkill_alloc);
+
+static void rfkill_poll(struct work_struct *work)
+{
+       struct rfkill *rfkill;
+
+       rfkill = container_of(work, struct rfkill, poll_work.work);
+
+       /*
+        * Poll hardware state -- driver will use one of the
+        * rfkill_set{,_hw,_sw}_state functions and use its
+        * return value to update the current status.
+        */
+       rfkill->ops->poll(rfkill, rfkill->data);
+
+       schedule_delayed_work(&rfkill->poll_work,
+               round_jiffies_relative(POLL_INTERVAL));
+}
+
+static void rfkill_uevent_work(struct work_struct *work)
+{
+       struct rfkill *rfkill;
+
+       rfkill = container_of(work, struct rfkill, uevent_work);
+
+       mutex_lock(&rfkill_global_mutex);
+       rfkill_event(rfkill);
+       mutex_unlock(&rfkill_global_mutex);
+}
+
+static void rfkill_sync_work(struct work_struct *work)
+{
+       struct rfkill *rfkill;
+       bool cur;
+
+       rfkill = container_of(work, struct rfkill, sync_work);
+
+       mutex_lock(&rfkill_global_mutex);
+       cur = rfkill_global_states[rfkill->type].cur;
+       rfkill_set_block(rfkill, cur);
+       mutex_unlock(&rfkill_global_mutex);
+}
+
+int __must_check rfkill_register(struct rfkill *rfkill)
+{
+       static unsigned long rfkill_no;
+       struct device *dev = &rfkill->dev;
+       int error;
+
+       BUG_ON(!rfkill);
+
+       mutex_lock(&rfkill_global_mutex);
+
+       if (rfkill->registered) {
+               error = -EALREADY;
+               goto unlock;
+       }
+
+       rfkill->idx = rfkill_no;
+       dev_set_name(dev, "rfkill%lu", rfkill_no);
+       rfkill_no++;
+
+       list_add_tail(&rfkill->node, &rfkill_list);
+
+       error = device_add(dev);
+       if (error)
+               goto remove;
+
+       error = rfkill_led_trigger_register(rfkill);
+       if (error)
+               goto devdel;
+
+       rfkill->registered = true;
+
+       INIT_DELAYED_WORK(&rfkill->poll_work, rfkill_poll);
+       INIT_WORK(&rfkill->uevent_work, rfkill_uevent_work);
+       INIT_WORK(&rfkill->sync_work, rfkill_sync_work);
+
+       if (rfkill->ops->poll)
+               schedule_delayed_work(&rfkill->poll_work,
+                       round_jiffies_relative(POLL_INTERVAL));
+
+       if (!rfkill->persistent || rfkill_epo_lock_active) {
+               schedule_work(&rfkill->sync_work);
+       } else {
+#ifdef CONFIG_RFKILL_INPUT
+               bool soft_blocked = !!(rfkill->state & RFKILL_BLOCK_SW);
+
+               if (!atomic_read(&rfkill_input_disabled))
+                       __rfkill_switch_all(rfkill->type, soft_blocked);
+#endif
+       }
+
+       rfkill_send_events(rfkill, RFKILL_OP_ADD);
+
+       mutex_unlock(&rfkill_global_mutex);
+       return 0;
+
+ devdel:
+       device_del(&rfkill->dev);
+ remove:
+       list_del_init(&rfkill->node);
+ unlock:
+       mutex_unlock(&rfkill_global_mutex);
+       return error;
+}
+EXPORT_SYMBOL(rfkill_register);
+
+void rfkill_unregister(struct rfkill *rfkill)
+{
+       BUG_ON(!rfkill);
+
+       if (rfkill->ops->poll)
+               cancel_delayed_work_sync(&rfkill->poll_work);
+
+       cancel_work_sync(&rfkill->uevent_work);
+       cancel_work_sync(&rfkill->sync_work);
+
+       rfkill->registered = false;
+
+       device_del(&rfkill->dev);
+
+       mutex_lock(&rfkill_global_mutex);
+       rfkill_send_events(rfkill, RFKILL_OP_DEL);
+       list_del_init(&rfkill->node);
+       mutex_unlock(&rfkill_global_mutex);
+
+       rfkill_led_trigger_unregister(rfkill);
+}
+EXPORT_SYMBOL(rfkill_unregister);
+
+void rfkill_destroy(struct rfkill *rfkill)
+{
+       if (rfkill)
+               put_device(&rfkill->dev);
+}
+EXPORT_SYMBOL(rfkill_destroy);
+
+static int rfkill_fop_open(struct inode *inode, struct file *file)
+{
+       struct rfkill_data *data;
+       struct rfkill *rfkill;
+       struct rfkill_int_event *ev, *tmp;
+
+       data = kzalloc(sizeof(*data), GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
+
+       INIT_LIST_HEAD(&data->events);
+       mutex_init(&data->mtx);
+       init_waitqueue_head(&data->read_wait);
+
+       mutex_lock(&rfkill_global_mutex);
+       mutex_lock(&data->mtx);
+       /*
+        * start getting events from elsewhere but hold mtx to get
+        * startup events added first
+        */
+       list_add(&data->list, &rfkill_fds);
+
+       list_for_each_entry(rfkill, &rfkill_list, node) {
+               ev = kzalloc(sizeof(*ev), GFP_KERNEL);
+               if (!ev)
+                       goto free;
+               rfkill_fill_event(&ev->ev, rfkill, RFKILL_OP_ADD);
+               list_add_tail(&ev->list, &data->events);
+       }
+       mutex_unlock(&data->mtx);
+       mutex_unlock(&rfkill_global_mutex);
+
+       file->private_data = data;
+
+       return nonseekable_open(inode, file);
+
+ free:
+       mutex_unlock(&data->mtx);
+       mutex_unlock(&rfkill_global_mutex);
+       mutex_destroy(&data->mtx);
+       list_for_each_entry_safe(ev, tmp, &data->events, list)
+               kfree(ev);
+       kfree(data);
+       return -ENOMEM;
+}
+
+static unsigned int rfkill_fop_poll(struct file *file, poll_table *wait)
+{
+       struct rfkill_data *data = file->private_data;
+       unsigned int res = POLLOUT | POLLWRNORM;
+
+       poll_wait(file, &data->read_wait, wait);
+
+       mutex_lock(&data->mtx);
+       if (!list_empty(&data->events))
+               res = POLLIN | POLLRDNORM;
+       mutex_unlock(&data->mtx);
+
+       return res;
+}
+
+static bool rfkill_readable(struct rfkill_data *data)
+{
+       bool r;
+
+       mutex_lock(&data->mtx);
+       r = !list_empty(&data->events);
+       mutex_unlock(&data->mtx);
+
+       return r;
+}
+
+static ssize_t rfkill_fop_read(struct file *file, char __user *buf,
+                              size_t count, loff_t *pos)
+{
+       struct rfkill_data *data = file->private_data;
+       struct rfkill_int_event *ev;
+       unsigned long sz;
+       int ret;
+
+       mutex_lock(&data->mtx);
+
+       while (list_empty(&data->events)) {
+               if (file->f_flags & O_NONBLOCK) {
+                       ret = -EAGAIN;
+                       goto out;
+               }
+               mutex_unlock(&data->mtx);
+               ret = wait_event_interruptible(data->read_wait,
+                                              rfkill_readable(data));
+               mutex_lock(&data->mtx);
+
+               if (ret)
+                       goto out;
+       }
+
+       ev = list_first_entry(&data->events, struct rfkill_int_event,
+                               list);
+
+       sz = min_t(unsigned long, sizeof(ev->ev), count);
+       ret = sz;
+       if (copy_to_user(buf, &ev->ev, sz))
+               ret = -EFAULT;
+
+       list_del(&ev->list);
+       kfree(ev);
+ out:
+       mutex_unlock(&data->mtx);
+       return ret;
+}
+
+static ssize_t rfkill_fop_write(struct file *file, const char __user *buf,
+                               size_t count, loff_t *pos)
+{
+       struct rfkill *rfkill;
+       struct rfkill_event ev;
+
+       /* we don't need the 'hard' variable but accept it */
+       if (count < sizeof(ev) - 1)
+               return -EINVAL;
+
+       if (copy_from_user(&ev, buf, sizeof(ev) - 1))
+               return -EFAULT;
+
+       if (ev.op != RFKILL_OP_CHANGE && ev.op != RFKILL_OP_CHANGE_ALL)
+               return -EINVAL;
+
+       if (ev.type >= NUM_RFKILL_TYPES)
+               return -EINVAL;
+
+       mutex_lock(&rfkill_global_mutex);
+
+       if (ev.op == RFKILL_OP_CHANGE_ALL) {
+               if (ev.type == RFKILL_TYPE_ALL) {
+                       enum rfkill_type i;
+                       for (i = 0; i < NUM_RFKILL_TYPES; i++)
+                               rfkill_global_states[i].cur = ev.soft;
+               } else {
+                       rfkill_global_states[ev.type].cur = ev.soft;
+               }
+       }
+
+       list_for_each_entry(rfkill, &rfkill_list, node) {
+               if (rfkill->idx != ev.idx && ev.op != RFKILL_OP_CHANGE_ALL)
+                       continue;
+
+               if (rfkill->type != ev.type && ev.type != RFKILL_TYPE_ALL)
+                       continue;
+
+               rfkill_set_block(rfkill, ev.soft);
+       }
+       mutex_unlock(&rfkill_global_mutex);
+
+       return count;
+}
+
+static int rfkill_fop_release(struct inode *inode, struct file *file)
+{
+       struct rfkill_data *data = file->private_data;
+       struct rfkill_int_event *ev, *tmp;
+
+       mutex_lock(&rfkill_global_mutex);
+       list_del(&data->list);
+       mutex_unlock(&rfkill_global_mutex);
+
+       mutex_destroy(&data->mtx);
+       list_for_each_entry_safe(ev, tmp, &data->events, list)
+               kfree(ev);
+
+#ifdef CONFIG_RFKILL_INPUT
+       if (data->input_handler)
+               if (atomic_dec_return(&rfkill_input_disabled) == 0)
+                       printk(KERN_DEBUG "rfkill: input handler enabled\n");
+#endif
+
+       kfree(data);
+
+       return 0;
+}
+
+#ifdef CONFIG_RFKILL_INPUT
+static long rfkill_fop_ioctl(struct file *file, unsigned int cmd,
+                            unsigned long arg)
+{
+       struct rfkill_data *data = file->private_data;
+
+       if (_IOC_TYPE(cmd) != RFKILL_IOC_MAGIC)
+               return -ENOSYS;
+
+       if (_IOC_NR(cmd) != RFKILL_IOC_NOINPUT)
+               return -ENOSYS;
+
+       mutex_lock(&data->mtx);
+
+       if (!data->input_handler) {
+               if (atomic_inc_return(&rfkill_input_disabled) == 1)
+                       printk(KERN_DEBUG "rfkill: input handler disabled\n");
+               data->input_handler = true;
+       }
+
+       mutex_unlock(&data->mtx);
+
+       return 0;
+}
+#endif
+
+static const struct file_operations rfkill_fops = {
+       .open           = rfkill_fop_open,
+       .read           = rfkill_fop_read,
+       .write          = rfkill_fop_write,
+       .poll           = rfkill_fop_poll,
+       .release        = rfkill_fop_release,
+#ifdef CONFIG_RFKILL_INPUT
+       .unlocked_ioctl = rfkill_fop_ioctl,
+       .compat_ioctl   = rfkill_fop_ioctl,
+#endif
+};
+
+static struct miscdevice rfkill_miscdev = {
+       .name   = "rfkill",
+       .fops   = &rfkill_fops,
+       .minor  = MISC_DYNAMIC_MINOR,
+};
+
+static int __init rfkill_init(void)
+{
+       int error;
+       int i;
+
+       for (i = 0; i < NUM_RFKILL_TYPES; i++)
+               rfkill_global_states[i].cur = !rfkill_default_state;
+
+       error = class_register(&rfkill_class);
+       if (error)
+               goto out;
+
+       error = misc_register(&rfkill_miscdev);
+       if (error) {
+               class_unregister(&rfkill_class);
+               goto out;
+       }
+
+#ifdef CONFIG_RFKILL_INPUT
+       error = rfkill_handler_init();
+       if (error) {
+               misc_deregister(&rfkill_miscdev);
+               class_unregister(&rfkill_class);
+               goto out;
+       }
+#endif
+
+ out:
+       return error;
+}
+subsys_initcall(rfkill_init);
+
+static void __exit rfkill_exit(void)
+{
+#ifdef CONFIG_RFKILL_INPUT
+       rfkill_handler_exit();
+#endif
+       misc_deregister(&rfkill_miscdev);
+       class_unregister(&rfkill_class);
+}
+module_exit(rfkill_exit);
diff --git a/net/rfkill/input.c b/net/rfkill/input.c
new file mode 100644 (file)
index 0000000..a7295ad
--- /dev/null
@@ -0,0 +1,342 @@
+/*
+ * Input layer to RF Kill interface connector
+ *
+ * Copyright (c) 2007 Dmitry Torokhov
+ * Copyright 2009 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.
+ *
+ * If you ever run into a situation in which you have a SW_ type rfkill
+ * input device, then you can revive code that was removed in the patch
+ * "rfkill-input: remove unused code".
+ */
+
+#include <linux/input.h>
+#include <linux/slab.h>
+#include <linux/workqueue.h>
+#include <linux/init.h>
+#include <linux/rfkill.h>
+#include <linux/sched.h>
+
+#include "rfkill.h"
+
+enum rfkill_input_master_mode {
+       RFKILL_INPUT_MASTER_UNLOCK = 0,
+       RFKILL_INPUT_MASTER_RESTORE = 1,
+       RFKILL_INPUT_MASTER_UNBLOCKALL = 2,
+       NUM_RFKILL_INPUT_MASTER_MODES
+};
+
+/* Delay (in ms) between consecutive switch ops */
+#define RFKILL_OPS_DELAY 200
+
+static enum rfkill_input_master_mode rfkill_master_switch_mode =
+                                       RFKILL_INPUT_MASTER_UNBLOCKALL;
+module_param_named(master_switch_mode, rfkill_master_switch_mode, uint, 0);
+MODULE_PARM_DESC(master_switch_mode,
+       "SW_RFKILL_ALL ON should: 0=do nothing (only unlock); 1=restore; 2=unblock all");
+
+static spinlock_t rfkill_op_lock;
+static bool rfkill_op_pending;
+static unsigned long rfkill_sw_pending[BITS_TO_LONGS(NUM_RFKILL_TYPES)];
+static unsigned long rfkill_sw_state[BITS_TO_LONGS(NUM_RFKILL_TYPES)];
+
+enum rfkill_sched_op {
+       RFKILL_GLOBAL_OP_EPO = 0,
+       RFKILL_GLOBAL_OP_RESTORE,
+       RFKILL_GLOBAL_OP_UNLOCK,
+       RFKILL_GLOBAL_OP_UNBLOCK,
+};
+
+static enum rfkill_sched_op rfkill_master_switch_op;
+static enum rfkill_sched_op rfkill_op;
+
+static void __rfkill_handle_global_op(enum rfkill_sched_op op)
+{
+       unsigned int i;
+
+       switch (op) {
+       case RFKILL_GLOBAL_OP_EPO:
+               rfkill_epo();
+               break;
+       case RFKILL_GLOBAL_OP_RESTORE:
+               rfkill_restore_states();
+               break;
+       case RFKILL_GLOBAL_OP_UNLOCK:
+               rfkill_remove_epo_lock();
+               break;
+       case RFKILL_GLOBAL_OP_UNBLOCK:
+               rfkill_remove_epo_lock();
+               for (i = 0; i < NUM_RFKILL_TYPES; i++)
+                       rfkill_switch_all(i, false);
+               break;
+       default:
+               /* memory corruption or bug, fail safely */
+               rfkill_epo();
+               WARN(1, "Unknown requested operation %d! "
+                       "rfkill Emergency Power Off activated\n",
+                       op);
+       }
+}
+
+static void __rfkill_handle_normal_op(const enum rfkill_type type,
+                                     const bool complement)
+{
+       bool blocked;
+
+       blocked = rfkill_get_global_sw_state(type);
+       if (complement)
+               blocked = !blocked;
+
+       rfkill_switch_all(type, blocked);
+}
+
+static void rfkill_op_handler(struct work_struct *work)
+{
+       unsigned int i;
+       bool c;
+
+       spin_lock_irq(&rfkill_op_lock);
+       do {
+               if (rfkill_op_pending) {
+                       enum rfkill_sched_op op = rfkill_op;
+                       rfkill_op_pending = false;
+                       memset(rfkill_sw_pending, 0,
+                               sizeof(rfkill_sw_pending));
+                       spin_unlock_irq(&rfkill_op_lock);
+
+                       __rfkill_handle_global_op(op);
+
+                       spin_lock_irq(&rfkill_op_lock);
+
+                       /*
+                        * handle global ops first -- during unlocked period
+                        * we might have gotten a new global op.
+                        */
+                       if (rfkill_op_pending)
+                               continue;
+               }
+
+               if (rfkill_is_epo_lock_active())
+                       continue;
+
+               for (i = 0; i < NUM_RFKILL_TYPES; i++) {
+                       if (__test_and_clear_bit(i, rfkill_sw_pending)) {
+                               c = __test_and_clear_bit(i, rfkill_sw_state);
+                               spin_unlock_irq(&rfkill_op_lock);
+
+                               __rfkill_handle_normal_op(i, c);
+
+                               spin_lock_irq(&rfkill_op_lock);
+                       }
+               }
+       } while (rfkill_op_pending);
+       spin_unlock_irq(&rfkill_op_lock);
+}
+
+static DECLARE_DELAYED_WORK(rfkill_op_work, rfkill_op_handler);
+static unsigned long rfkill_last_scheduled;
+
+static unsigned long rfkill_ratelimit(const unsigned long last)
+{
+       const unsigned long delay = msecs_to_jiffies(RFKILL_OPS_DELAY);
+       return (time_after(jiffies, last + delay)) ? 0 : delay;
+}
+
+static void rfkill_schedule_ratelimited(void)
+{
+       if (delayed_work_pending(&rfkill_op_work))
+               return;
+       schedule_delayed_work(&rfkill_op_work,
+                             rfkill_ratelimit(rfkill_last_scheduled));
+       rfkill_last_scheduled = jiffies;
+}
+
+static void rfkill_schedule_global_op(enum rfkill_sched_op op)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&rfkill_op_lock, flags);
+       rfkill_op = op;
+       rfkill_op_pending = true;
+       if (op == RFKILL_GLOBAL_OP_EPO && !rfkill_is_epo_lock_active()) {
+               /* bypass the limiter for EPO */
+               cancel_delayed_work(&rfkill_op_work);
+               schedule_delayed_work(&rfkill_op_work, 0);
+               rfkill_last_scheduled = jiffies;
+       } else
+               rfkill_schedule_ratelimited();
+       spin_unlock_irqrestore(&rfkill_op_lock, flags);
+}
+
+static void rfkill_schedule_toggle(enum rfkill_type type)
+{
+       unsigned long flags;
+
+       if (rfkill_is_epo_lock_active())
+               return;
+
+       spin_lock_irqsave(&rfkill_op_lock, flags);
+       if (!rfkill_op_pending) {
+               __set_bit(type, rfkill_sw_pending);
+               __change_bit(type, rfkill_sw_state);
+               rfkill_schedule_ratelimited();
+       }
+       spin_unlock_irqrestore(&rfkill_op_lock, flags);
+}
+
+static void rfkill_schedule_evsw_rfkillall(int state)
+{
+       if (state)
+               rfkill_schedule_global_op(rfkill_master_switch_op);
+       else
+               rfkill_schedule_global_op(RFKILL_GLOBAL_OP_EPO);
+}
+
+static void rfkill_event(struct input_handle *handle, unsigned int type,
+                       unsigned int code, int data)
+{
+       if (type == EV_KEY && data == 1) {
+               switch (code) {
+               case KEY_WLAN:
+                       rfkill_schedule_toggle(RFKILL_TYPE_WLAN);
+                       break;
+               case KEY_BLUETOOTH:
+                       rfkill_schedule_toggle(RFKILL_TYPE_BLUETOOTH);
+                       break;
+               case KEY_UWB:
+                       rfkill_schedule_toggle(RFKILL_TYPE_UWB);
+                       break;
+               case KEY_WIMAX:
+                       rfkill_schedule_toggle(RFKILL_TYPE_WIMAX);
+                       break;
+               }
+       } else if (type == EV_SW && code == SW_RFKILL_ALL)
+               rfkill_schedule_evsw_rfkillall(data);
+}
+
+static int rfkill_connect(struct input_handler *handler, struct input_dev *dev,
+                         const struct input_device_id *id)
+{
+       struct input_handle *handle;
+       int error;
+
+       handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL);
+       if (!handle)
+               return -ENOMEM;
+
+       handle->dev = dev;
+       handle->handler = handler;
+       handle->name = "rfkill";
+
+       /* causes rfkill_start() to be called */
+       error = input_register_handle(handle);
+       if (error)
+               goto err_free_handle;
+
+       error = input_open_device(handle);
+       if (error)
+               goto err_unregister_handle;
+
+       return 0;
+
+ err_unregister_handle:
+       input_unregister_handle(handle);
+ err_free_handle:
+       kfree(handle);
+       return error;
+}
+
+static void rfkill_start(struct input_handle *handle)
+{
+       /*
+        * Take event_lock to guard against configuration changes, we
+        * should be able to deal with concurrency with rfkill_event()
+        * just fine (which event_lock will also avoid).
+        */
+       spin_lock_irq(&handle->dev->event_lock);
+
+       if (test_bit(EV_SW, handle->dev->evbit) &&
+           test_bit(SW_RFKILL_ALL, handle->dev->swbit))
+               rfkill_schedule_evsw_rfkillall(test_bit(SW_RFKILL_ALL,
+                                                       handle->dev->sw));
+
+       spin_unlock_irq(&handle->dev->event_lock);
+}
+
+static void rfkill_disconnect(struct input_handle *handle)
+{
+       input_close_device(handle);
+       input_unregister_handle(handle);
+       kfree(handle);
+}
+
+static const struct input_device_id rfkill_ids[] = {
+       {
+               .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT,
+               .evbit = { BIT_MASK(EV_KEY) },
+               .keybit = { [BIT_WORD(KEY_WLAN)] = BIT_MASK(KEY_WLAN) },
+       },
+       {
+               .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT,
+               .evbit = { BIT_MASK(EV_KEY) },
+               .keybit = { [BIT_WORD(KEY_BLUETOOTH)] = BIT_MASK(KEY_BLUETOOTH) },
+       },
+       {
+               .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT,
+               .evbit = { BIT_MASK(EV_KEY) },
+               .keybit = { [BIT_WORD(KEY_UWB)] = BIT_MASK(KEY_UWB) },
+       },
+       {
+               .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT,
+               .evbit = { BIT_MASK(EV_KEY) },
+               .keybit = { [BIT_WORD(KEY_WIMAX)] = BIT_MASK(KEY_WIMAX) },
+       },
+       {
+               .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_SWBIT,
+               .evbit = { BIT(EV_SW) },
+               .swbit = { [BIT_WORD(SW_RFKILL_ALL)] = BIT_MASK(SW_RFKILL_ALL) },
+       },
+       { }
+};
+
+static struct input_handler rfkill_handler = {
+       .name = "rfkill",
+       .event = rfkill_event,
+       .connect = rfkill_connect,
+       .start = rfkill_start,
+       .disconnect = rfkill_disconnect,
+       .id_table = rfkill_ids,
+};
+
+int __init rfkill_handler_init(void)
+{
+       switch (rfkill_master_switch_mode) {
+       case RFKILL_INPUT_MASTER_UNBLOCKALL:
+               rfkill_master_switch_op = RFKILL_GLOBAL_OP_UNBLOCK;
+               break;
+       case RFKILL_INPUT_MASTER_RESTORE:
+               rfkill_master_switch_op = RFKILL_GLOBAL_OP_RESTORE;
+               break;
+       case RFKILL_INPUT_MASTER_UNLOCK:
+               rfkill_master_switch_op = RFKILL_GLOBAL_OP_UNLOCK;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       spin_lock_init(&rfkill_op_lock);
+
+       /* Avoid delay at first schedule */
+       rfkill_last_scheduled =
+                       jiffies - msecs_to_jiffies(RFKILL_OPS_DELAY) - 1;
+       return input_register_handler(&rfkill_handler);
+}
+
+void __exit rfkill_handler_exit(void)
+{
+       input_unregister_handler(&rfkill_handler);
+       cancel_delayed_work_sync(&rfkill_op_work);
+}
diff --git a/net/rfkill/rfkill-input.c b/net/rfkill/rfkill-input.c
deleted file mode 100644 (file)
index 84efde9..0000000
+++ /dev/null
@@ -1,459 +0,0 @@
-/*
- * Input layer to RF Kill interface connector
- *
- * Copyright (c) 2007 Dmitry Torokhov
- */
-
-/*
- * 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/input.h>
-#include <linux/slab.h>
-#include <linux/workqueue.h>
-#include <linux/init.h>
-#include <linux/rfkill.h>
-#include <linux/sched.h>
-
-#include "rfkill-input.h"
-
-MODULE_AUTHOR("Dmitry Torokhov <dtor@mail.ru>");
-MODULE_DESCRIPTION("Input layer to RF switch connector");
-MODULE_LICENSE("GPL");
-
-enum rfkill_input_master_mode {
-       RFKILL_INPUT_MASTER_DONOTHING = 0,
-       RFKILL_INPUT_MASTER_RESTORE = 1,
-       RFKILL_INPUT_MASTER_UNBLOCKALL = 2,
-       RFKILL_INPUT_MASTER_MAX,        /* marker */
-};
-
-/* Delay (in ms) between consecutive switch ops */
-#define RFKILL_OPS_DELAY 200
-
-static enum rfkill_input_master_mode rfkill_master_switch_mode =
-                                       RFKILL_INPUT_MASTER_UNBLOCKALL;
-module_param_named(master_switch_mode, rfkill_master_switch_mode, uint, 0);
-MODULE_PARM_DESC(master_switch_mode,
-       "SW_RFKILL_ALL ON should: 0=do nothing; 1=restore; 2=unblock all");
-
-enum rfkill_global_sched_op {
-       RFKILL_GLOBAL_OP_EPO = 0,
-       RFKILL_GLOBAL_OP_RESTORE,
-       RFKILL_GLOBAL_OP_UNLOCK,
-       RFKILL_GLOBAL_OP_UNBLOCK,
-};
-
-/*
- * Currently, the code marked with RFKILL_NEED_SWSET is inactive.
- * If handling of EV_SW SW_WLAN/WWAN/BLUETOOTH/etc is needed in the
- * future, when such events are added, that code will be necessary.
- */
-
-struct rfkill_task {
-       struct delayed_work dwork;
-
-       /* ensures that task is serialized */
-       struct mutex mutex;
-
-       /* protects everything below */
-       spinlock_t lock;
-
-       /* pending regular switch operations (1=pending) */
-       unsigned long sw_pending[BITS_TO_LONGS(RFKILL_TYPE_MAX)];
-
-#ifdef RFKILL_NEED_SWSET
-       /* set operation pending (1=pending) */
-       unsigned long sw_setpending[BITS_TO_LONGS(RFKILL_TYPE_MAX)];
-
-       /* desired state for pending set operation (1=unblock) */
-       unsigned long sw_newstate[BITS_TO_LONGS(RFKILL_TYPE_MAX)];
-#endif
-
-       /* should the state be complemented (1=yes) */
-       unsigned long sw_togglestate[BITS_TO_LONGS(RFKILL_TYPE_MAX)];
-
-       bool global_op_pending;
-       enum rfkill_global_sched_op op;
-
-       /* last time it was scheduled */
-       unsigned long last_scheduled;
-};
-
-static void __rfkill_handle_global_op(enum rfkill_global_sched_op op)
-{
-       unsigned int i;
-
-       switch (op) {
-       case RFKILL_GLOBAL_OP_EPO:
-               rfkill_epo();
-               break;
-       case RFKILL_GLOBAL_OP_RESTORE:
-               rfkill_restore_states();
-               break;
-       case RFKILL_GLOBAL_OP_UNLOCK:
-               rfkill_remove_epo_lock();
-               break;
-       case RFKILL_GLOBAL_OP_UNBLOCK:
-               rfkill_remove_epo_lock();
-               for (i = 0; i < RFKILL_TYPE_MAX; i++)
-                       rfkill_switch_all(i, RFKILL_STATE_UNBLOCKED);
-               break;
-       default:
-               /* memory corruption or bug, fail safely */
-               rfkill_epo();
-               WARN(1, "Unknown requested operation %d! "
-                       "rfkill Emergency Power Off activated\n",
-                       op);
-       }
-}
-
-#ifdef RFKILL_NEED_SWSET
-static void __rfkill_handle_normal_op(const enum rfkill_type type,
-                       const bool sp, const bool s, const bool c)
-{
-       enum rfkill_state state;
-
-       if (sp)
-               state = (s) ? RFKILL_STATE_UNBLOCKED :
-                             RFKILL_STATE_SOFT_BLOCKED;
-       else
-               state = rfkill_get_global_state(type);
-
-       if (c)
-               state = rfkill_state_complement(state);
-
-       rfkill_switch_all(type, state);
-}
-#else
-static void __rfkill_handle_normal_op(const enum rfkill_type type,
-                       const bool c)
-{
-       enum rfkill_state state;
-
-       state = rfkill_get_global_state(type);
-       if (c)
-               state = rfkill_state_complement(state);
-
-       rfkill_switch_all(type, state);
-}
-#endif
-
-static void rfkill_task_handler(struct work_struct *work)
-{
-       struct rfkill_task *task = container_of(work,
-                                       struct rfkill_task, dwork.work);
-       bool doit = true;
-
-       mutex_lock(&task->mutex);
-
-       spin_lock_irq(&task->lock);
-       while (doit) {
-               if (task->global_op_pending) {
-                       enum rfkill_global_sched_op op = task->op;
-                       task->global_op_pending = false;
-                       memset(task->sw_pending, 0, sizeof(task->sw_pending));
-                       spin_unlock_irq(&task->lock);
-
-                       __rfkill_handle_global_op(op);
-
-                       /* make sure we do at least one pass with
-                        * !task->global_op_pending */
-                       spin_lock_irq(&task->lock);
-                       continue;
-               } else if (!rfkill_is_epo_lock_active()) {
-                       unsigned int i = 0;
-
-                       while (!task->global_op_pending &&
-                                               i < RFKILL_TYPE_MAX) {
-                               if (test_and_clear_bit(i, task->sw_pending)) {
-                                       bool c;
-#ifdef RFKILL_NEED_SWSET
-                                       bool sp, s;
-                                       sp = test_and_clear_bit(i,
-                                                       task->sw_setpending);
-                                       s = test_bit(i, task->sw_newstate);
-#endif
-                                       c = test_and_clear_bit(i,
-                                                       task->sw_togglestate);
-                                       spin_unlock_irq(&task->lock);
-
-#ifdef RFKILL_NEED_SWSET
-                                       __rfkill_handle_normal_op(i, sp, s, c);
-#else
-                                       __rfkill_handle_normal_op(i, c);
-#endif
-
-                                       spin_lock_irq(&task->lock);
-                               }
-                               i++;
-                       }
-               }
-               doit = task->global_op_pending;
-       }
-       spin_unlock_irq(&task->lock);
-
-       mutex_unlock(&task->mutex);
-}
-
-static struct rfkill_task rfkill_task = {
-       .dwork = __DELAYED_WORK_INITIALIZER(rfkill_task.dwork,
-                               rfkill_task_handler),
-       .mutex = __MUTEX_INITIALIZER(rfkill_task.mutex),
-       .lock = __SPIN_LOCK_UNLOCKED(rfkill_task.lock),
-};
-
-static unsigned long rfkill_ratelimit(const unsigned long last)
-{
-       const unsigned long delay = msecs_to_jiffies(RFKILL_OPS_DELAY);
-       return (time_after(jiffies, last + delay)) ? 0 : delay;
-}
-
-static void rfkill_schedule_ratelimited(void)
-{
-       if (!delayed_work_pending(&rfkill_task.dwork)) {
-               schedule_delayed_work(&rfkill_task.dwork,
-                               rfkill_ratelimit(rfkill_task.last_scheduled));
-               rfkill_task.last_scheduled = jiffies;
-       }
-}
-
-static void rfkill_schedule_global_op(enum rfkill_global_sched_op op)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&rfkill_task.lock, flags);
-       rfkill_task.op = op;
-       rfkill_task.global_op_pending = true;
-       if (op == RFKILL_GLOBAL_OP_EPO && !rfkill_is_epo_lock_active()) {
-               /* bypass the limiter for EPO */
-               cancel_delayed_work(&rfkill_task.dwork);
-               schedule_delayed_work(&rfkill_task.dwork, 0);
-               rfkill_task.last_scheduled = jiffies;
-       } else
-               rfkill_schedule_ratelimited();
-       spin_unlock_irqrestore(&rfkill_task.lock, flags);
-}
-
-#ifdef RFKILL_NEED_SWSET
-/* Use this if you need to add EV_SW SW_WLAN/WWAN/BLUETOOTH/etc handling */
-
-static void rfkill_schedule_set(enum rfkill_type type,
-                               enum rfkill_state desired_state)
-{
-       unsigned long flags;
-
-       if (rfkill_is_epo_lock_active())
-               return;
-
-       spin_lock_irqsave(&rfkill_task.lock, flags);
-       if (!rfkill_task.global_op_pending) {
-               set_bit(type, rfkill_task.sw_pending);
-               set_bit(type, rfkill_task.sw_setpending);
-               clear_bit(type, rfkill_task.sw_togglestate);
-               if (desired_state)
-                       set_bit(type,  rfkill_task.sw_newstate);
-               else
-                       clear_bit(type, rfkill_task.sw_newstate);
-               rfkill_schedule_ratelimited();
-       }
-       spin_unlock_irqrestore(&rfkill_task.lock, flags);
-}
-#endif
-
-static void rfkill_schedule_toggle(enum rfkill_type type)
-{
-       unsigned long flags;
-
-       if (rfkill_is_epo_lock_active())
-               return;
-
-       spin_lock_irqsave(&rfkill_task.lock, flags);
-       if (!rfkill_task.global_op_pending) {
-               set_bit(type, rfkill_task.sw_pending);
-               change_bit(type, rfkill_task.sw_togglestate);
-               rfkill_schedule_ratelimited();
-       }
-       spin_unlock_irqrestore(&rfkill_task.lock, flags);
-}
-
-static void rfkill_schedule_evsw_rfkillall(int state)
-{
-       if (state) {
-               switch (rfkill_master_switch_mode) {
-               case RFKILL_INPUT_MASTER_UNBLOCKALL:
-                       rfkill_schedule_global_op(RFKILL_GLOBAL_OP_UNBLOCK);
-                       break;
-               case RFKILL_INPUT_MASTER_RESTORE:
-                       rfkill_schedule_global_op(RFKILL_GLOBAL_OP_RESTORE);
-                       break;
-               case RFKILL_INPUT_MASTER_DONOTHING:
-                       rfkill_schedule_global_op(RFKILL_GLOBAL_OP_UNLOCK);
-                       break;
-               default:
-                       /* memory corruption or driver bug! fail safely */
-                       rfkill_schedule_global_op(RFKILL_GLOBAL_OP_EPO);
-                       WARN(1, "Unknown rfkill_master_switch_mode (%d), "
-                               "driver bug or memory corruption detected!\n",
-                               rfkill_master_switch_mode);
-                       break;
-               }
-       } else
-               rfkill_schedule_global_op(RFKILL_GLOBAL_OP_EPO);
-}
-
-static void rfkill_event(struct input_handle *handle, unsigned int type,
-                       unsigned int code, int data)
-{
-       if (type == EV_KEY && data == 1) {
-               enum rfkill_type t;
-
-               switch (code) {
-               case KEY_WLAN:
-                       t = RFKILL_TYPE_WLAN;
-                       break;
-               case KEY_BLUETOOTH:
-                       t = RFKILL_TYPE_BLUETOOTH;
-                       break;
-               case KEY_UWB:
-                       t = RFKILL_TYPE_UWB;
-                       break;
-               case KEY_WIMAX:
-                       t = RFKILL_TYPE_WIMAX;
-                       break;
-               default:
-                       return;
-               }
-               rfkill_schedule_toggle(t);
-               return;
-       } else if (type == EV_SW) {
-               switch (code) {
-               case SW_RFKILL_ALL:
-                       rfkill_schedule_evsw_rfkillall(data);
-                       return;
-               default:
-                       return;
-               }
-       }
-}
-
-static int rfkill_connect(struct input_handler *handler, struct input_dev *dev,
-                         const struct input_device_id *id)
-{
-       struct input_handle *handle;
-       int error;
-
-       handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL);
-       if (!handle)
-               return -ENOMEM;
-
-       handle->dev = dev;
-       handle->handler = handler;
-       handle->name = "rfkill";
-
-       /* causes rfkill_start() to be called */
-       error = input_register_handle(handle);
-       if (error)
-               goto err_free_handle;
-
-       error = input_open_device(handle);
-       if (error)
-               goto err_unregister_handle;
-
-       return 0;
-
- err_unregister_handle:
-       input_unregister_handle(handle);
- err_free_handle:
-       kfree(handle);
-       return error;
-}
-
-static void rfkill_start(struct input_handle *handle)
-{
-       /* Take event_lock to guard against configuration changes, we
-        * should be able to deal with concurrency with rfkill_event()
-        * just fine (which event_lock will also avoid). */
-       spin_lock_irq(&handle->dev->event_lock);
-
-       if (test_bit(EV_SW, handle->dev->evbit)) {
-               if (test_bit(SW_RFKILL_ALL, handle->dev->swbit))
-                       rfkill_schedule_evsw_rfkillall(test_bit(SW_RFKILL_ALL,
-                                                       handle->dev->sw));
-               /* add resync for further EV_SW events here */
-       }
-
-       spin_unlock_irq(&handle->dev->event_lock);
-}
-
-static void rfkill_disconnect(struct input_handle *handle)
-{
-       input_close_device(handle);
-       input_unregister_handle(handle);
-       kfree(handle);
-}
-
-static const struct input_device_id rfkill_ids[] = {
-       {
-               .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT,
-               .evbit = { BIT_MASK(EV_KEY) },
-               .keybit = { [BIT_WORD(KEY_WLAN)] = BIT_MASK(KEY_WLAN) },
-       },
-       {
-               .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT,
-               .evbit = { BIT_MASK(EV_KEY) },
-               .keybit = { [BIT_WORD(KEY_BLUETOOTH)] = BIT_MASK(KEY_BLUETOOTH) },
-       },
-       {
-               .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT,
-               .evbit = { BIT_MASK(EV_KEY) },
-               .keybit = { [BIT_WORD(KEY_UWB)] = BIT_MASK(KEY_UWB) },
-       },
-       {
-               .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_KEYBIT,
-               .evbit = { BIT_MASK(EV_KEY) },
-               .keybit = { [BIT_WORD(KEY_WIMAX)] = BIT_MASK(KEY_WIMAX) },
-       },
-       {
-               .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_SWBIT,
-               .evbit = { BIT(EV_SW) },
-               .swbit = { [BIT_WORD(SW_RFKILL_ALL)] = BIT_MASK(SW_RFKILL_ALL) },
-       },
-       { }
-};
-
-static struct input_handler rfkill_handler = {
-       .event =        rfkill_event,
-       .connect =      rfkill_connect,
-       .disconnect =   rfkill_disconnect,
-       .start =        rfkill_start,
-       .name =         "rfkill",
-       .id_table =     rfkill_ids,
-};
-
-static int __init rfkill_handler_init(void)
-{
-       if (rfkill_master_switch_mode >= RFKILL_INPUT_MASTER_MAX)
-               return -EINVAL;
-
-       /*
-        * The penalty to not doing this is a possible RFKILL_OPS_DELAY delay
-        * at the first use.  Acceptable, but if we can avoid it, why not?
-        */
-       rfkill_task.last_scheduled =
-                       jiffies - msecs_to_jiffies(RFKILL_OPS_DELAY) - 1;
-       return input_register_handler(&rfkill_handler);
-}
-
-static void __exit rfkill_handler_exit(void)
-{
-       input_unregister_handler(&rfkill_handler);
-       cancel_delayed_work_sync(&rfkill_task.dwork);
-       rfkill_remove_epo_lock();
-}
-
-module_init(rfkill_handler_init);
-module_exit(rfkill_handler_exit);
diff --git a/net/rfkill/rfkill-input.h b/net/rfkill/rfkill-input.h
deleted file mode 100644 (file)
index fe8df6b..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (C) 2007 Ivo van Doorn
- */
-
-/*
- * 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 __RFKILL_INPUT_H
-#define __RFKILL_INPUT_H
-
-void rfkill_switch_all(enum rfkill_type type, enum rfkill_state state);
-void rfkill_epo(void);
-void rfkill_restore_states(void);
-void rfkill_remove_epo_lock(void);
-bool rfkill_is_epo_lock_active(void);
-enum rfkill_state rfkill_get_global_state(const enum rfkill_type type);
-
-#endif /* __RFKILL_INPUT_H */
diff --git a/net/rfkill/rfkill.c b/net/rfkill/rfkill.c
deleted file mode 100644 (file)
index 3eaa394..0000000
+++ /dev/null
@@ -1,882 +0,0 @@
-/*
- * Copyright (C) 2006 - 2007 Ivo van Doorn
- * Copyright (C) 2007 Dmitry Torokhov
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the
- * Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/workqueue.h>
-#include <linux/capability.h>
-#include <linux/list.h>
-#include <linux/mutex.h>
-#include <linux/rfkill.h>
-
-/* Get declaration of rfkill_switch_all() to shut up sparse. */
-#include "rfkill-input.h"
-
-
-MODULE_AUTHOR("Ivo van Doorn <IvDoorn@gmail.com>");
-MODULE_VERSION("1.0");
-MODULE_DESCRIPTION("RF switch support");
-MODULE_LICENSE("GPL");
-
-static LIST_HEAD(rfkill_list); /* list of registered rf switches */
-static DEFINE_MUTEX(rfkill_global_mutex);
-
-static unsigned int rfkill_default_state = RFKILL_STATE_UNBLOCKED;
-module_param_named(default_state, rfkill_default_state, uint, 0444);
-MODULE_PARM_DESC(default_state,
-                "Default initial state for all radio types, 0 = radio off");
-
-struct rfkill_gsw_state {
-       enum rfkill_state current_state;
-       enum rfkill_state default_state;
-};
-
-static struct rfkill_gsw_state rfkill_global_states[RFKILL_TYPE_MAX];
-static unsigned long rfkill_states_lockdflt[BITS_TO_LONGS(RFKILL_TYPE_MAX)];
-static bool rfkill_epo_lock_active;
-
-
-#ifdef CONFIG_RFKILL_LEDS
-static void rfkill_led_trigger(struct rfkill *rfkill,
-                              enum rfkill_state state)
-{
-       struct led_trigger *led = &rfkill->led_trigger;
-
-       if (!led->name)
-               return;
-       if (state != RFKILL_STATE_UNBLOCKED)
-               led_trigger_event(led, LED_OFF);
-       else
-               led_trigger_event(led, LED_FULL);
-}
-
-static void rfkill_led_trigger_activate(struct led_classdev *led)
-{
-       struct rfkill *rfkill = container_of(led->trigger,
-                       struct rfkill, led_trigger);
-
-       rfkill_led_trigger(rfkill, rfkill->state);
-}
-#endif /* CONFIG_RFKILL_LEDS */
-
-static void rfkill_uevent(struct rfkill *rfkill)
-{
-       kobject_uevent(&rfkill->dev.kobj, KOBJ_CHANGE);
-}
-
-static void update_rfkill_state(struct rfkill *rfkill)
-{
-       enum rfkill_state newstate, oldstate;
-
-       if (rfkill->get_state) {
-               mutex_lock(&rfkill->mutex);
-               if (!rfkill->get_state(rfkill->data, &newstate)) {
-                       oldstate = rfkill->state;
-                       rfkill->state = newstate;
-                       if (oldstate != newstate)
-                               rfkill_uevent(rfkill);
-               }
-               mutex_unlock(&rfkill->mutex);
-       }
-}
-
-/**
- * rfkill_toggle_radio - wrapper for toggle_radio hook
- * @rfkill: the rfkill struct to use
- * @force: calls toggle_radio even if cache says it is not needed,
- *     and also makes sure notifications of the state will be
- *     sent even if it didn't change
- * @state: the new state to call toggle_radio() with
- *
- * Calls rfkill->toggle_radio, enforcing the API for toggle_radio
- * calls and handling all the red tape such as issuing notifications
- * if the call is successful.
- *
- * Suspended devices are not touched at all, and -EAGAIN is returned.
- *
- * Note that the @force parameter cannot override a (possibly cached)
- * state of RFKILL_STATE_HARD_BLOCKED.  Any device making use of
- * RFKILL_STATE_HARD_BLOCKED implements either get_state() or
- * rfkill_force_state(), so the cache either is bypassed or valid.
- *
- * Note that we do call toggle_radio for RFKILL_STATE_SOFT_BLOCKED
- * even if the radio is in RFKILL_STATE_HARD_BLOCKED state, so as to
- * give the driver a hint that it should double-BLOCK the transmitter.
- *
- * Caller must have acquired rfkill->mutex.
- */
-static int rfkill_toggle_radio(struct rfkill *rfkill,
-                               enum rfkill_state state,
-                               int force)
-{
-       int retval = 0;
-       enum rfkill_state oldstate, newstate;
-
-       if (unlikely(rfkill->dev.power.power_state.event & PM_EVENT_SLEEP))
-               return -EBUSY;
-
-       oldstate = rfkill->state;
-
-       if (rfkill->get_state && !force &&
-           !rfkill->get_state(rfkill->data, &newstate))
-               rfkill->state = newstate;
-
-       switch (state) {
-       case RFKILL_STATE_HARD_BLOCKED:
-               /* typically happens when refreshing hardware state,
-                * such as on resume */
-               state = RFKILL_STATE_SOFT_BLOCKED;
-               break;
-       case RFKILL_STATE_UNBLOCKED:
-               /* force can't override this, only rfkill_force_state() can */
-               if (rfkill->state == RFKILL_STATE_HARD_BLOCKED)
-                       return -EPERM;
-               break;
-       case RFKILL_STATE_SOFT_BLOCKED:
-               /* nothing to do, we want to give drivers the hint to double
-                * BLOCK even a transmitter that is already in state
-                * RFKILL_STATE_HARD_BLOCKED */
-               break;
-       default:
-               WARN(1, KERN_WARNING
-                       "rfkill: illegal state %d passed as parameter "
-                       "to rfkill_toggle_radio\n", state);
-               return -EINVAL;
-       }
-
-       if (force || state != rfkill->state) {
-               retval = rfkill->toggle_radio(rfkill->data, state);
-               /* never allow a HARD->SOFT downgrade! */
-               if (!retval && rfkill->state != RFKILL_STATE_HARD_BLOCKED)
-                       rfkill->state = state;
-       }
-
-       if (force || rfkill->state != oldstate)
-               rfkill_uevent(rfkill);
-
-       return retval;
-}
-
-/**
- * __rfkill_switch_all - Toggle state of all switches of given type
- * @type: type of interfaces to be affected
- * @state: the new state
- *
- * This function toggles the state of all switches of given type,
- * unless a specific switch is claimed by userspace (in which case,
- * that switch is left alone) or suspended.
- *
- * Caller must have acquired rfkill_global_mutex.
- */
-static void __rfkill_switch_all(const enum rfkill_type type,
-                               const enum rfkill_state state)
-{
-       struct rfkill *rfkill;
-
-       if (WARN((state >= RFKILL_STATE_MAX || type >= RFKILL_TYPE_MAX),
-                       KERN_WARNING
-                       "rfkill: illegal state %d or type %d "
-                       "passed as parameter to __rfkill_switch_all\n",
-                       state, type))
-               return;
-
-       rfkill_global_states[type].current_state = state;
-       list_for_each_entry(rfkill, &rfkill_list, node) {
-               if ((!rfkill->user_claim) && (rfkill->type == type)) {
-                       mutex_lock(&rfkill->mutex);
-                       rfkill_toggle_radio(rfkill, state, 0);
-                       mutex_unlock(&rfkill->mutex);
-               }
-       }
-}
-
-/**
- * rfkill_switch_all - Toggle state of all switches of given type
- * @type: type of interfaces to be affected
- * @state: the new state
- *
- * Acquires rfkill_global_mutex and calls __rfkill_switch_all(@type, @state).
- * Please refer to __rfkill_switch_all() for details.
- *
- * Does nothing if the EPO lock is active.
- */
-void rfkill_switch_all(enum rfkill_type type, enum rfkill_state state)
-{
-       mutex_lock(&rfkill_global_mutex);
-       if (!rfkill_epo_lock_active)
-               __rfkill_switch_all(type, state);
-       mutex_unlock(&rfkill_global_mutex);
-}
-EXPORT_SYMBOL(rfkill_switch_all);
-
-/**
- * rfkill_epo - emergency power off all transmitters
- *
- * This kicks all non-suspended rfkill devices to RFKILL_STATE_SOFT_BLOCKED,
- * ignoring everything in its path but rfkill_global_mutex and rfkill->mutex.
- *
- * The global state before the EPO is saved and can be restored later
- * using rfkill_restore_states().
- */
-void rfkill_epo(void)
-{
-       struct rfkill *rfkill;
-       int i;
-
-       mutex_lock(&rfkill_global_mutex);
-
-       rfkill_epo_lock_active = true;
-       list_for_each_entry(rfkill, &rfkill_list, node) {
-               mutex_lock(&rfkill->mutex);
-               rfkill_toggle_radio(rfkill, RFKILL_STATE_SOFT_BLOCKED, 1);
-               mutex_unlock(&rfkill->mutex);
-       }
-       for (i = 0; i < RFKILL_TYPE_MAX; i++) {
-               rfkill_global_states[i].default_state =
-                               rfkill_global_states[i].current_state;
-               rfkill_global_states[i].current_state =
-                               RFKILL_STATE_SOFT_BLOCKED;
-       }
-       mutex_unlock(&rfkill_global_mutex);
-}
-EXPORT_SYMBOL_GPL(rfkill_epo);
-
-/**
- * rfkill_restore_states - restore global states
- *
- * Restore (and sync switches to) the global state from the
- * states in rfkill_default_states.  This can undo the effects of
- * a call to rfkill_epo().
- */
-void rfkill_restore_states(void)
-{
-       int i;
-
-       mutex_lock(&rfkill_global_mutex);
-
-       rfkill_epo_lock_active = false;
-       for (i = 0; i < RFKILL_TYPE_MAX; i++)
-               __rfkill_switch_all(i, rfkill_global_states[i].default_state);
-       mutex_unlock(&rfkill_global_mutex);
-}
-EXPORT_SYMBOL_GPL(rfkill_restore_states);
-
-/**
- * rfkill_remove_epo_lock - unlock state changes
- *
- * Used by rfkill-input manually unlock state changes, when
- * the EPO switch is deactivated.
- */
-void rfkill_remove_epo_lock(void)
-{
-       mutex_lock(&rfkill_global_mutex);
-       rfkill_epo_lock_active = false;
-       mutex_unlock(&rfkill_global_mutex);
-}
-EXPORT_SYMBOL_GPL(rfkill_remove_epo_lock);
-
-/**
- * rfkill_is_epo_lock_active - returns true EPO is active
- *
- * Returns 0 (false) if there is NOT an active EPO contidion,
- * and 1 (true) if there is an active EPO contition, which
- * locks all radios in one of the BLOCKED states.
- *
- * Can be called in atomic context.
- */
-bool rfkill_is_epo_lock_active(void)
-{
-       return rfkill_epo_lock_active;
-}
-EXPORT_SYMBOL_GPL(rfkill_is_epo_lock_active);
-
-/**
- * rfkill_get_global_state - returns global state for a type
- * @type: the type to get the global state of
- *
- * Returns the current global state for a given wireless
- * device type.
- */
-enum rfkill_state rfkill_get_global_state(const enum rfkill_type type)
-{
-       return rfkill_global_states[type].current_state;
-}
-EXPORT_SYMBOL_GPL(rfkill_get_global_state);
-
-/**
- * rfkill_force_state - Force the internal rfkill radio state
- * @rfkill: pointer to the rfkill class to modify.
- * @state: the current radio state the class should be forced to.
- *
- * This function updates the internal state of the radio cached
- * by the rfkill class.  It should be used when the driver gets
- * a notification by the firmware/hardware of the current *real*
- * state of the radio rfkill switch.
- *
- * Devices which are subject to external changes on their rfkill
- * state (such as those caused by a hardware rfkill line) MUST
- * have their driver arrange to call rfkill_force_state() as soon
- * as possible after such a change.
- *
- * This function may not be called from an atomic context.
- */
-int rfkill_force_state(struct rfkill *rfkill, enum rfkill_state state)
-{
-       enum rfkill_state oldstate;
-
-       BUG_ON(!rfkill);
-       if (WARN((state >= RFKILL_STATE_MAX),
-                       KERN_WARNING
-                       "rfkill: illegal state %d passed as parameter "
-                       "to rfkill_force_state\n", state))
-               return -EINVAL;
-
-       mutex_lock(&rfkill->mutex);
-
-       oldstate = rfkill->state;
-       rfkill->state = state;
-
-       if (state != oldstate)
-               rfkill_uevent(rfkill);
-
-       mutex_unlock(&rfkill->mutex);
-
-       return 0;
-}
-EXPORT_SYMBOL(rfkill_force_state);
-
-static ssize_t rfkill_name_show(struct device *dev,
-                               struct device_attribute *attr,
-                               char *buf)
-{
-       struct rfkill *rfkill = to_rfkill(dev);
-
-       return sprintf(buf, "%s\n", rfkill->name);
-}
-
-static const char *rfkill_get_type_str(enum rfkill_type type)
-{
-       switch (type) {
-       case RFKILL_TYPE_WLAN:
-               return "wlan";
-       case RFKILL_TYPE_BLUETOOTH:
-               return "bluetooth";
-       case RFKILL_TYPE_UWB:
-               return "ultrawideband";
-       case RFKILL_TYPE_WIMAX:
-               return "wimax";
-       case RFKILL_TYPE_WWAN:
-               return "wwan";
-       default:
-               BUG();
-       }
-}
-
-static ssize_t rfkill_type_show(struct device *dev,
-                               struct device_attribute *attr,
-                               char *buf)
-{
-       struct rfkill *rfkill = to_rfkill(dev);
-
-       return sprintf(buf, "%s\n", rfkill_get_type_str(rfkill->type));
-}
-
-static ssize_t rfkill_state_show(struct device *dev,
-                                struct device_attribute *attr,
-                                char *buf)
-{
-       struct rfkill *rfkill = to_rfkill(dev);
-
-       update_rfkill_state(rfkill);
-       return sprintf(buf, "%d\n", rfkill->state);
-}
-
-static ssize_t rfkill_state_store(struct device *dev,
-                                 struct device_attribute *attr,
-                                 const char *buf, size_t count)
-{
-       struct rfkill *rfkill = to_rfkill(dev);
-       unsigned long state;
-       int error;
-
-       if (!capable(CAP_NET_ADMIN))
-               return -EPERM;
-
-       error = strict_strtoul(buf, 0, &state);
-       if (error)
-               return error;
-
-       /* RFKILL_STATE_HARD_BLOCKED is illegal here... */
-       if (state != RFKILL_STATE_UNBLOCKED &&
-           state != RFKILL_STATE_SOFT_BLOCKED)
-               return -EINVAL;
-
-       error = mutex_lock_killable(&rfkill->mutex);
-       if (error)
-               return error;
-
-       if (!rfkill_epo_lock_active)
-               error = rfkill_toggle_radio(rfkill, state, 0);
-       else
-               error = -EPERM;
-
-       mutex_unlock(&rfkill->mutex);
-
-       return error ? error : count;
-}
-
-static ssize_t rfkill_claim_show(struct device *dev,
-                                struct device_attribute *attr,
-                                char *buf)
-{
-       struct rfkill *rfkill = to_rfkill(dev);
-
-       return sprintf(buf, "%d\n", rfkill->user_claim);
-}
-
-static ssize_t rfkill_claim_store(struct device *dev,
-                                 struct device_attribute *attr,
-                                 const char *buf, size_t count)
-{
-       struct rfkill *rfkill = to_rfkill(dev);
-       unsigned long claim_tmp;
-       bool claim;
-       int error;
-
-       if (!capable(CAP_NET_ADMIN))
-               return -EPERM;
-
-       if (rfkill->user_claim_unsupported)
-               return -EOPNOTSUPP;
-
-       error = strict_strtoul(buf, 0, &claim_tmp);
-       if (error)
-               return error;
-       claim = !!claim_tmp;
-
-       /*
-        * Take the global lock to make sure the kernel is not in
-        * the middle of rfkill_switch_all
-        */
-       error = mutex_lock_killable(&rfkill_global_mutex);
-       if (error)
-               return error;
-
-       if (rfkill->user_claim != claim) {
-               if (!claim && !rfkill_epo_lock_active) {
-                       mutex_lock(&rfkill->mutex);
-                       rfkill_toggle_radio(rfkill,
-                                       rfkill_global_states[rfkill->type].current_state,
-                                       0);
-                       mutex_unlock(&rfkill->mutex);
-               }
-               rfkill->user_claim = claim;
-       }
-
-       mutex_unlock(&rfkill_global_mutex);
-
-       return error ? error : count;
-}
-
-static struct device_attribute rfkill_dev_attrs[] = {
-       __ATTR(name, S_IRUGO, rfkill_name_show, NULL),
-       __ATTR(type, S_IRUGO, rfkill_type_show, NULL),
-       __ATTR(state, S_IRUGO|S_IWUSR, rfkill_state_show, rfkill_state_store),
-       __ATTR(claim, S_IRUGO|S_IWUSR, rfkill_claim_show, rfkill_claim_store),
-       __ATTR_NULL
-};
-
-static void rfkill_release(struct device *dev)
-{
-       struct rfkill *rfkill = to_rfkill(dev);
-
-       kfree(rfkill);
-       module_put(THIS_MODULE);
-}
-
-#ifdef CONFIG_PM
-static int rfkill_suspend(struct device *dev, pm_message_t state)
-{
-       struct rfkill *rfkill = to_rfkill(dev);
-
-       /* mark class device as suspended */
-       if (dev->power.power_state.event != state.event)
-               dev->power.power_state = state;
-
-       /* store state for the resume handler */
-       rfkill->state_for_resume = rfkill->state;
-
-       return 0;
-}
-
-static int rfkill_resume(struct device *dev)
-{
-       struct rfkill *rfkill = to_rfkill(dev);
-       enum rfkill_state newstate;
-
-       if (dev->power.power_state.event != PM_EVENT_ON) {
-               mutex_lock(&rfkill->mutex);
-
-               dev->power.power_state.event = PM_EVENT_ON;
-
-               /*
-                * rfkill->state could have been modified before we got
-                * called, and won't be updated by rfkill_toggle_radio()
-                * in force mode.  Sync it FIRST.
-                */
-               if (rfkill->get_state &&
-                   !rfkill->get_state(rfkill->data, &newstate))
-                       rfkill->state = newstate;
-
-               /*
-                * If we are under EPO, kick transmitter offline,
-                * otherwise restore to pre-suspend state.
-                *
-                * Issue a notification in any case
-                */
-               rfkill_toggle_radio(rfkill,
-                               rfkill_epo_lock_active ?
-                                       RFKILL_STATE_SOFT_BLOCKED :
-                                       rfkill->state_for_resume,
-                               1);
-
-               mutex_unlock(&rfkill->mutex);
-       }
-
-       return 0;
-}
-#else
-#define rfkill_suspend NULL
-#define rfkill_resume NULL
-#endif
-
-static int rfkill_dev_uevent(struct device *dev, struct kobj_uevent_env *env)
-{
-       struct rfkill *rfkill = to_rfkill(dev);
-       int error;
-
-       error = add_uevent_var(env, "RFKILL_NAME=%s", rfkill->name);
-       if (error)
-               return error;
-       error = add_uevent_var(env, "RFKILL_TYPE=%s",
-                               rfkill_get_type_str(rfkill->type));
-       if (error)
-               return error;
-       error = add_uevent_var(env, "RFKILL_STATE=%d", rfkill->state);
-       return error;
-}
-
-static struct class rfkill_class = {
-       .name           = "rfkill",
-       .dev_release    = rfkill_release,
-       .dev_attrs      = rfkill_dev_attrs,
-       .suspend        = rfkill_suspend,
-       .resume         = rfkill_resume,
-       .dev_uevent     = rfkill_dev_uevent,
-};
-
-static int rfkill_check_duplicity(const struct rfkill *rfkill)
-{
-       struct rfkill *p;
-       unsigned long seen[BITS_TO_LONGS(RFKILL_TYPE_MAX)];
-
-       memset(seen, 0, sizeof(seen));
-
-       list_for_each_entry(p, &rfkill_list, node) {
-               if (WARN((p == rfkill), KERN_WARNING
-                               "rfkill: illegal attempt to register "
-                               "an already registered rfkill struct\n"))
-                       return -EEXIST;
-               set_bit(p->type, seen);
-       }
-
-       /* 0: first switch of its kind */
-       return (test_bit(rfkill->type, seen)) ? 1 : 0;
-}
-
-static int rfkill_add_switch(struct rfkill *rfkill)
-{
-       int error;
-
-       mutex_lock(&rfkill_global_mutex);
-
-       error = rfkill_check_duplicity(rfkill);
-       if (error < 0)
-               goto unlock_out;
-
-       if (!error) {
-               /* lock default after first use */
-               set_bit(rfkill->type, rfkill_states_lockdflt);
-               rfkill_global_states[rfkill->type].current_state =
-                       rfkill_global_states[rfkill->type].default_state;
-       }
-
-       rfkill_toggle_radio(rfkill,
-                           rfkill_global_states[rfkill->type].current_state,
-                           0);
-
-       list_add_tail(&rfkill->node, &rfkill_list);
-
-       error = 0;
-unlock_out:
-       mutex_unlock(&rfkill_global_mutex);
-
-       return error;
-}
-
-static void rfkill_remove_switch(struct rfkill *rfkill)
-{
-       mutex_lock(&rfkill_global_mutex);
-       list_del_init(&rfkill->node);
-       mutex_unlock(&rfkill_global_mutex);
-
-       mutex_lock(&rfkill->mutex);
-       rfkill_toggle_radio(rfkill, RFKILL_STATE_SOFT_BLOCKED, 1);
-       mutex_unlock(&rfkill->mutex);
-}
-
-/**
- * rfkill_allocate - allocate memory for rfkill structure.
- * @parent: device that has rf switch on it
- * @type: type of the switch (RFKILL_TYPE_*)
- *
- * This function should be called by the network driver when it needs
- * rfkill structure.  Once the structure is allocated the driver should
- * finish its initialization by setting the name, private data, enable_radio
- * and disable_radio methods and then register it with rfkill_register().
- *
- * NOTE: If registration fails the structure shoudl be freed by calling
- * rfkill_free() otherwise rfkill_unregister() should be used.
- */
-struct rfkill * __must_check rfkill_allocate(struct device *parent,
-                                            enum rfkill_type type)
-{
-       struct rfkill *rfkill;
-       struct device *dev;
-
-       if (WARN((type >= RFKILL_TYPE_MAX),
-                       KERN_WARNING
-                       "rfkill: illegal type %d passed as parameter "
-                       "to rfkill_allocate\n", type))
-               return NULL;
-
-       rfkill = kzalloc(sizeof(struct rfkill), GFP_KERNEL);
-       if (!rfkill)
-               return NULL;
-
-       mutex_init(&rfkill->mutex);
-       INIT_LIST_HEAD(&rfkill->node);
-       rfkill->type = type;
-
-       dev = &rfkill->dev;
-       dev->class = &rfkill_class;
-       dev->parent = parent;
-       device_initialize(dev);
-
-       __module_get(THIS_MODULE);
-
-       return rfkill;
-}
-EXPORT_SYMBOL(rfkill_allocate);
-
-/**
- * rfkill_free - Mark rfkill structure for deletion
- * @rfkill: rfkill structure to be destroyed
- *
- * Decrements reference count of the rfkill structure so it is destroyed.
- * Note that rfkill_free() should _not_ be called after rfkill_unregister().
- */
-void rfkill_free(struct rfkill *rfkill)
-{
-       if (rfkill)
-               put_device(&rfkill->dev);
-}
-EXPORT_SYMBOL(rfkill_free);
-
-static void rfkill_led_trigger_register(struct rfkill *rfkill)
-{
-#ifdef CONFIG_RFKILL_LEDS
-       int error;
-
-       if (!rfkill->led_trigger.name)
-               rfkill->led_trigger.name = dev_name(&rfkill->dev);
-       if (!rfkill->led_trigger.activate)
-               rfkill->led_trigger.activate = rfkill_led_trigger_activate;
-       error = led_trigger_register(&rfkill->led_trigger);
-       if (error)
-               rfkill->led_trigger.name = NULL;
-#endif /* CONFIG_RFKILL_LEDS */
-}
-
-static void rfkill_led_trigger_unregister(struct rfkill *rfkill)
-{
-#ifdef CONFIG_RFKILL_LEDS
-       if (rfkill->led_trigger.name) {
-               led_trigger_unregister(&rfkill->led_trigger);
-               rfkill->led_trigger.name = NULL;
-       }
-#endif
-}
-
-/**
- * rfkill_register - Register a rfkill structure.
- * @rfkill: rfkill structure to be registered
- *
- * This function should be called by the network driver when the rfkill
- * structure needs to be registered. Immediately from registration the
- * switch driver should be able to service calls to toggle_radio.
- */
-int __must_check rfkill_register(struct rfkill *rfkill)
-{
-       static atomic_t rfkill_no = ATOMIC_INIT(0);
-       struct device *dev = &rfkill->dev;
-       int error;
-
-       if (WARN((!rfkill || !rfkill->toggle_radio ||
-                       rfkill->type >= RFKILL_TYPE_MAX ||
-                       rfkill->state >= RFKILL_STATE_MAX),
-                       KERN_WARNING
-                       "rfkill: attempt to register a "
-                       "badly initialized rfkill struct\n"))
-               return -EINVAL;
-
-       dev_set_name(dev, "rfkill%ld", (long)atomic_inc_return(&rfkill_no) - 1);
-
-       rfkill_led_trigger_register(rfkill);
-
-       error = rfkill_add_switch(rfkill);
-       if (error) {
-               rfkill_led_trigger_unregister(rfkill);
-               return error;
-       }
-
-       error = device_add(dev);
-       if (error) {
-               rfkill_remove_switch(rfkill);
-               rfkill_led_trigger_unregister(rfkill);
-               return error;
-       }
-
-       return 0;
-}
-EXPORT_SYMBOL(rfkill_register);
-
-/**
- * rfkill_unregister - Unregister a rfkill structure.
- * @rfkill: rfkill structure to be unregistered
- *
- * This function should be called by the network driver during device
- * teardown to destroy rfkill structure. Note that rfkill_free() should
- * _not_ be called after rfkill_unregister().
- */
-void rfkill_unregister(struct rfkill *rfkill)
-{
-       BUG_ON(!rfkill);
-       device_del(&rfkill->dev);
-       rfkill_remove_switch(rfkill);
-       rfkill_led_trigger_unregister(rfkill);
-       put_device(&rfkill->dev);
-}
-EXPORT_SYMBOL(rfkill_unregister);
-
-/**
- * rfkill_set_default - set initial value for a switch type
- * @type - the type of switch to set the default state of
- * @state - the new default state for that group of switches
- *
- * Sets the initial state rfkill should use for a given type.
- * The following initial states are allowed: RFKILL_STATE_SOFT_BLOCKED
- * and RFKILL_STATE_UNBLOCKED.
- *
- * This function is meant to be used by platform drivers for platforms
- * that can save switch state across power down/reboot.
- *
- * The default state for each switch type can be changed exactly once.
- * After a switch of that type is registered, the default state cannot
- * be changed anymore.  This guards against multiple drivers it the
- * same platform trying to set the initial switch default state, which
- * is not allowed.
- *
- * Returns -EPERM if the state has already been set once or is in use,
- * so drivers likely want to either ignore or at most printk(KERN_NOTICE)
- * if this function returns -EPERM.
- *
- * Returns 0 if the new default state was set, or an error if it
- * could not be set.
- */
-int rfkill_set_default(enum rfkill_type type, enum rfkill_state state)
-{
-       int error;
-
-       if (WARN((type >= RFKILL_TYPE_MAX ||
-                       (state != RFKILL_STATE_SOFT_BLOCKED &&
-                        state != RFKILL_STATE_UNBLOCKED)),
-                       KERN_WARNING
-                       "rfkill: illegal state %d or type %d passed as "
-                       "parameter to rfkill_set_default\n", state, type))
-               return -EINVAL;
-
-       mutex_lock(&rfkill_global_mutex);
-
-       if (!test_and_set_bit(type, rfkill_states_lockdflt)) {
-               rfkill_global_states[type].default_state = state;
-               rfkill_global_states[type].current_state = state;
-               error = 0;
-       } else
-               error = -EPERM;
-
-       mutex_unlock(&rfkill_global_mutex);
-       return error;
-}
-EXPORT_SYMBOL_GPL(rfkill_set_default);
-
-/*
- * Rfkill module initialization/deinitialization.
- */
-static int __init rfkill_init(void)
-{
-       int error;
-       int i;
-
-       /* RFKILL_STATE_HARD_BLOCKED is illegal here... */
-       if (rfkill_default_state != RFKILL_STATE_SOFT_BLOCKED &&
-           rfkill_default_state != RFKILL_STATE_UNBLOCKED)
-               return -EINVAL;
-
-       for (i = 0; i < RFKILL_TYPE_MAX; i++)
-               rfkill_global_states[i].default_state = rfkill_default_state;
-
-       error = class_register(&rfkill_class);
-       if (error) {
-               printk(KERN_ERR "rfkill: unable to register rfkill class\n");
-               return error;
-       }
-
-       return 0;
-}
-
-static void __exit rfkill_exit(void)
-{
-       class_unregister(&rfkill_class);
-}
-
-subsys_initcall(rfkill_init);
-module_exit(rfkill_exit);
diff --git a/net/rfkill/rfkill.h b/net/rfkill/rfkill.h
new file mode 100644 (file)
index 0000000..d1117cb
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2007 Ivo van Doorn
+ * Copyright 2009 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.
+ */
+
+#ifndef __RFKILL_INPUT_H
+#define __RFKILL_INPUT_H
+
+/* core code */
+void rfkill_switch_all(const enum rfkill_type type, bool blocked);
+void rfkill_epo(void);
+void rfkill_restore_states(void);
+void rfkill_remove_epo_lock(void);
+bool rfkill_is_epo_lock_active(void);
+bool rfkill_get_global_sw_state(const enum rfkill_type type);
+
+/* input handler */
+int rfkill_handler_init(void);
+void rfkill_handler_exit(void);
+
+#endif /* __RFKILL_INPUT_H */
index 7dcf2569613b612eb3a19f9777cbc71edaed902a..389d6e0d774070cd1e1d4d8b2290f3a343a7c989 100644 (file)
@@ -137,7 +137,7 @@ static int rose_xmit(struct sk_buff *skb, struct net_device *dev)
 
        if (!netif_running(dev)) {
                printk(KERN_ERR "ROSE: rose_xmit - called when iface is down\n");
-               return 1;
+               return NETDEV_TX_BUSY;
        }
        dev_kfree_skb(skb);
        stats->tx_errors++;
index e5becb92b3e7b0f17d43b3342a4621e51e162b4f..e4877ca6727c4b098ef1b6f08163fd7702d3eea2 100644 (file)
@@ -62,13 +62,7 @@ static u64 read_classid(struct cgroup *cgrp, struct cftype *cft)
 
 static int write_classid(struct cgroup *cgrp, struct cftype *cft, u64 value)
 {
-       if (!cgroup_lock_live_group(cgrp))
-               return -ENODEV;
-
        cgrp_cls_state(cgrp)->classid = (u32) value;
-
-       cgroup_unlock();
-
        return 0;
 }
 
index 0ef4e3065bcde9d2a33e0a15d5bb2e4ae87f590c..9402a7fd3785bd0153f80ccb627a7a8c75950952 100644 (file)
@@ -84,7 +84,7 @@ static u32 flow_get_dst(const struct sk_buff *skb)
        case htons(ETH_P_IPV6):
                return ntohl(ipv6_hdr(skb)->daddr.s6_addr32[3]);
        default:
-               return addr_fold(skb->dst) ^ (__force u16)skb->protocol;
+               return addr_fold(skb_dst(skb)) ^ (__force u16)skb->protocol;
        }
 }
 
@@ -163,7 +163,7 @@ static u32 flow_get_proto_dst(const struct sk_buff *skb)
                break;
        }
        default:
-               res = addr_fold(skb->dst) ^ (__force u16)skb->protocol;
+               res = addr_fold(skb_dst(skb)) ^ (__force u16)skb->protocol;
        }
 
        return res;
@@ -251,8 +251,8 @@ fallback:
 static u32 flow_get_rtclassid(const struct sk_buff *skb)
 {
 #ifdef CONFIG_NET_CLS_ROUTE
-       if (skb->dst)
-               return skb->dst->tclassid;
+       if (skb_dst(skb))
+               return skb_dst(skb)->tclassid;
 #endif
        return 0;
 }
index bdf1f4172eef5a7d13783e4192babb10ff526726..dd872d5383efe371fa4333dcc1af724039b047b5 100644 (file)
@@ -137,7 +137,7 @@ static int route4_classify(struct sk_buff *skb, struct tcf_proto *tp,
        u32 id, h;
        int iif, dont_cache = 0;
 
-       if ((dst = skb->dst) == NULL)
+       if ((dst = skb_dst(skb)) == NULL)
                goto failure;
 
        id = dst->tclassid;
index fad596bf32d76e89d72d712117e5ec451465ecdf..266151ae85a308444c5912ee974088a2fded41c3 100644 (file)
@@ -246,11 +246,11 @@ META_COLLECTOR(int_tcindex)
 
 META_COLLECTOR(int_rtclassid)
 {
-       if (unlikely(skb->dst == NULL))
+       if (unlikely(skb_dst(skb) == NULL))
                *err = -1;
        else
 #ifdef CONFIG_NET_CLS_ROUTE
-               dst->value = skb->dst->tclassid;
+               dst->value = skb_dst(skb)->tclassid;
 #else
                dst->value = 0;
 #endif
@@ -258,10 +258,10 @@ META_COLLECTOR(int_rtclassid)
 
 META_COLLECTOR(int_rtiif)
 {
-       if (unlikely(skb->rtable == NULL))
+       if (unlikely(skb_rtable(skb) == NULL))
                *err = -1;
        else
-               dst->value = skb->rtable->fl.iif;
+               dst->value = skb_rtable(skb)->fl.iif;
 }
 
 /**************************************************************************
index 32009793307be7fb39d969aa5fb029e03e01a1f6..24d17ce9c294f384f1a638b7888540455479f3aa 100644 (file)
@@ -484,7 +484,7 @@ void qdisc_watchdog_schedule(struct qdisc_watchdog *wd, psched_time_t expires)
 
        wd->qdisc->flags |= TCQ_F_THROTTLED;
        time = ktime_set(0, 0);
-       time = ktime_add_ns(time, PSCHED_US2NS(expires));
+       time = ktime_add_ns(time, PSCHED_TICKS2NS(expires));
        hrtimer_start(&wd->timer, time, HRTIMER_MODE_ABS);
 }
 EXPORT_SYMBOL(qdisc_watchdog_schedule);
@@ -1680,7 +1680,7 @@ static int psched_show(struct seq_file *seq, void *v)
 
        hrtimer_get_res(CLOCK_MONOTONIC, &ts);
        seq_printf(seq, "%08x %08x %08x %08x\n",
-                  (u32)NSEC_PER_USEC, (u32)PSCHED_US2NS(1),
+                  (u32)NSEC_PER_USEC, (u32)PSCHED_TICKS2NS(1),
                   1000000,
                   (u32)NSEC_PER_SEC/(u32)ktime_to_ns(timespec_to_ktime(ts)));
 
index d728d8111732f0d74b783c54927e2c42822f1dbe..23a167670fd5f11ed1affcfb07b9ad766b381b81 100644 (file)
@@ -509,7 +509,7 @@ static void cbq_ovl_delay(struct cbq_class *cl)
                        q->pmask |= (1<<TC_CBQ_MAXPRIO);
 
                        expires = ktime_set(0, 0);
-                       expires = ktime_add_ns(expires, PSCHED_US2NS(sched));
+                       expires = ktime_add_ns(expires, PSCHED_TICKS2NS(sched));
                        if (hrtimer_try_to_cancel(&q->delay_timer) &&
                            ktime_to_ns(ktime_sub(
                                        hrtimer_get_expires(&q->delay_timer),
@@ -620,7 +620,7 @@ static enum hrtimer_restart cbq_undelay(struct hrtimer *timer)
                ktime_t time;
 
                time = ktime_set(0, 0);
-               time = ktime_add_ns(time, PSCHED_US2NS(now + delay));
+               time = ktime_add_ns(time, PSCHED_TICKS2NS(now + delay));
                hrtimer_start(&q->delay_timer, time, HRTIMER_MODE_ABS);
        }
 
index 5f5efe4e6072e2959d6f6802a268cc7c5afca66b..27d03816ec3e8b307b3ac6eafc2ae1b8ca866c7d 100644 (file)
@@ -196,6 +196,21 @@ void __qdisc_run(struct Qdisc *q)
        clear_bit(__QDISC_STATE_RUNNING, &q->state);
 }
 
+unsigned long dev_trans_start(struct net_device *dev)
+{
+       unsigned long val, res = dev->trans_start;
+       unsigned int i;
+
+       for (i = 0; i < dev->num_tx_queues; i++) {
+               val = netdev_get_tx_queue(dev, i)->trans_start;
+               if (val && time_after(val, res))
+                       res = val;
+       }
+       dev->trans_start = res;
+       return res;
+}
+EXPORT_SYMBOL(dev_trans_start);
+
 static void dev_watchdog(unsigned long arg)
 {
        struct net_device *dev = (struct net_device *)arg;
@@ -205,25 +220,30 @@ static void dev_watchdog(unsigned long arg)
                if (netif_device_present(dev) &&
                    netif_running(dev) &&
                    netif_carrier_ok(dev)) {
-                       int some_queue_stopped = 0;
+                       int some_queue_timedout = 0;
                        unsigned int i;
+                       unsigned long trans_start;
 
                        for (i = 0; i < dev->num_tx_queues; i++) {
                                struct netdev_queue *txq;
 
                                txq = netdev_get_tx_queue(dev, i);
-                               if (netif_tx_queue_stopped(txq)) {
-                                       some_queue_stopped = 1;
+                               /*
+                                * old device drivers set dev->trans_start
+                                */
+                               trans_start = txq->trans_start ? : dev->trans_start;
+                               if (netif_tx_queue_stopped(txq) &&
+                                   time_after(jiffies, (trans_start +
+                                                        dev->watchdog_timeo))) {
+                                       some_queue_timedout = 1;
                                        break;
                                }
                        }
 
-                       if (some_queue_stopped &&
-                           time_after(jiffies, (dev->trans_start +
-                                                dev->watchdog_timeo))) {
+                       if (some_queue_timedout) {
                                char drivername[64];
-                               WARN_ONCE(1, KERN_INFO "NETDEV WATCHDOG: %s (%s): transmit timed out\n",
-                                      dev->name, netdev_drivername(dev, drivername, 64));
+                               WARN_ONCE(1, KERN_INFO "NETDEV WATCHDOG: %s (%s): transmit queue %u timed out\n",
+                                      dev->name, netdev_drivername(dev, drivername, 64), i);
                                dev->netdev_ops->ndo_tx_timeout(dev);
                        }
                        if (!mod_timer(&dev->watchdog_timer,
@@ -602,8 +622,10 @@ static void transition_one_qdisc(struct net_device *dev,
                clear_bit(__QDISC_STATE_DEACTIVATED, &new_qdisc->state);
 
        rcu_assign_pointer(dev_queue->qdisc, new_qdisc);
-       if (need_watchdog_p && new_qdisc != &noqueue_qdisc)
+       if (need_watchdog_p && new_qdisc != &noqueue_qdisc) {
+               dev_queue->trans_start = 0;
                *need_watchdog_p = 1;
+       }
 }
 
 void dev_activate(struct net_device *dev)
index 5022f9c1f34be595e391801728e124273f479692..362c2811b2dfe95b93daf0d3f10cf98a06373cd6 100644 (file)
@@ -372,7 +372,7 @@ cftree_update(struct hfsc_class *cl)
  *     ism: (psched_us/byte) << ISM_SHIFT
  *     dx: psched_us
  *
- * The clock source resolution with ktime is 1.024us.
+ * The clock source resolution with ktime and PSCHED_SHIFT 10 is 1.024us.
  *
  * sm and ism are scaled in order to keep effective digits.
  * SM_SHIFT and ISM_SHIFT are selected to keep at least 4 effective
@@ -383,9 +383,11 @@ cftree_update(struct hfsc_class *cl)
  *  bytes/1.024us 12.8e-3    128e-3     1280e-3    12800e-3   128000e-3
  *
  *  1.024us/byte  78.125     7.8125     0.78125    0.078125   0.0078125
+ *
+ * So, for PSCHED_SHIFT 10 we need: SM_SHIFT 20, ISM_SHIFT 18.
  */
-#define        SM_SHIFT        20
-#define        ISM_SHIFT       18
+#define        SM_SHIFT        (30 - PSCHED_SHIFT)
+#define        ISM_SHIFT       (8 + PSCHED_SHIFT)
 
 #define        SM_MASK         ((1ULL << SM_SHIFT) - 1)
 #define        ISM_MASK        ((1ULL << ISM_SHIFT) - 1)
index 33133d27b5390673c6540b1c39eff35b460b19a9..8706920a6d45b7c7b7cc67b866f94880a187f6f7 100644 (file)
@@ -149,7 +149,7 @@ static unsigned sfq_hash(struct sfq_sched_data *q, struct sk_buff *skb)
                break;
        }
        default:
-               h = (unsigned long)skb->dst ^ skb->protocol;
+               h = (unsigned long)skb_dst(skb) ^ skb->protocol;
                h2 = (unsigned long)skb->sk;
        }
 
index 3b64182972312f183d4dbdd4d506d862c3df891f..9c002b6e0533a7e170027ddc6f9e8da7c3bfdc74 100644 (file)
@@ -58,7 +58,6 @@ struct teql_master
        struct net_device *dev;
        struct Qdisc *slaves;
        struct list_head master_list;
-       struct net_device_stats stats;
 };
 
 struct teql_sched_data
@@ -223,7 +222,7 @@ __teql_resolve(struct sk_buff *skb, struct sk_buff *skb_res, struct net_device *
 {
        struct netdev_queue *dev_queue = netdev_get_tx_queue(dev, 0);
        struct teql_sched_data *q = qdisc_priv(dev_queue->qdisc);
-       struct neighbour *mn = skb->dst->neighbour;
+       struct neighbour *mn = skb_dst(skb)->neighbour;
        struct neighbour *n = q->ncache;
 
        if (mn->tbl == NULL)
@@ -263,8 +262,8 @@ static inline int teql_resolve(struct sk_buff *skb,
                return -ENODEV;
 
        if (dev->header_ops == NULL ||
-           skb->dst == NULL ||
-           skb->dst->neighbour == NULL)
+           skb_dst(skb) == NULL ||
+           skb_dst(skb)->neighbour == NULL)
                return 0;
        return __teql_resolve(skb, skb_res, dev);
 }
@@ -272,6 +271,7 @@ static inline int teql_resolve(struct sk_buff *skb,
 static int teql_master_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        struct teql_master *master = netdev_priv(dev);
+       struct netdev_queue *txq = netdev_get_tx_queue(dev, 0);
        struct Qdisc *start, *q;
        int busy;
        int nores;
@@ -308,11 +308,12 @@ restart:
                                if (!netif_tx_queue_stopped(slave_txq) &&
                                    !netif_tx_queue_frozen(slave_txq) &&
                                    slave_ops->ndo_start_xmit(skb, slave) == 0) {
+                                       txq_trans_update(slave_txq);
                                        __netif_tx_unlock(slave_txq);
                                        master->slaves = NEXT_SLAVE(q);
                                        netif_wake_queue(dev);
-                                       master->stats.tx_packets++;
-                                       master->stats.tx_bytes += length;
+                                       txq->tx_packets++;
+                                       txq->tx_bytes += length;
                                        return 0;
                                }
                                __netif_tx_unlock(slave_txq);
@@ -337,12 +338,12 @@ restart:
 
        if (busy) {
                netif_stop_queue(dev);
-               return 1;
+               return NETDEV_TX_BUSY;
        }
-       master->stats.tx_errors++;
+       dev->stats.tx_errors++;
 
 drop:
-       master->stats.tx_dropped++;
+       txq->tx_dropped++;
        dev_kfree_skb(skb);
        return 0;
 }
@@ -395,12 +396,6 @@ static int teql_master_close(struct net_device *dev)
        return 0;
 }
 
-static struct net_device_stats *teql_master_stats(struct net_device *dev)
-{
-       struct teql_master *m = netdev_priv(dev);
-       return &m->stats;
-}
-
 static int teql_master_mtu(struct net_device *dev, int new_mtu)
 {
        struct teql_master *m = netdev_priv(dev);
@@ -425,7 +420,6 @@ static const struct net_device_ops teql_netdev_ops = {
        .ndo_open       = teql_master_open,
        .ndo_stop       = teql_master_close,
        .ndo_start_xmit = teql_master_xmit,
-       .ndo_get_stats  = teql_master_stats,
        .ndo_change_mtu = teql_master_mtu,
 };
 
index f4b23043b610b85a7a004770569fa5a01e0e932a..525864bf4f07d6caef08520d195053d5b0e25edf 100644 (file)
@@ -293,7 +293,8 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
         * told otherwise.
         */
        asoc->peer.ipv4_address = 1;
-       asoc->peer.ipv6_address = 1;
+       if (asoc->base.sk->sk_family == PF_INET6)
+               asoc->peer.ipv6_address = 1;
        INIT_LIST_HEAD(&asoc->asocs);
 
        asoc->autoclose = sp->autoclose;
@@ -566,6 +567,21 @@ void sctp_assoc_rm_peer(struct sctp_association *asoc,
        if (asoc->init_last_sent_to == peer)
                asoc->init_last_sent_to = NULL;
 
+       /* If we remove the transport an SHUTDOWN was last sent to, set it
+        * to NULL. Combined with the update of the retran path above, this
+        * will cause the next SHUTDOWN to be sent to the next available
+        * transport, maintaining the cycle.
+        */
+       if (asoc->shutdown_last_sent_to == peer)
+               asoc->shutdown_last_sent_to = NULL;
+
+       /* If we remove the transport an ASCONF was last sent to, set it to
+        * NULL.
+        */
+       if (asoc->addip_last_asconf &&
+           asoc->addip_last_asconf->transport == peer)
+               asoc->addip_last_asconf->transport = NULL;
+
        asoc->peer.transport_count--;
 
        sctp_transport_free(peer);
@@ -1268,49 +1284,21 @@ void sctp_assoc_update_retran_path(struct sctp_association *asoc)
                                 ntohs(t->ipaddr.v4.sin_port));
 }
 
-/* Choose the transport for sending a INIT packet.  */
-struct sctp_transport *sctp_assoc_choose_init_transport(
-       struct sctp_association *asoc)
-{
-       struct sctp_transport *t;
-
-       /* Use the retran path. If the last INIT was sent over the
-        * retran path, update the retran path and use it.
-        */
-       if (!asoc->init_last_sent_to) {
-               t = asoc->peer.active_path;
-       } else {
-               if (asoc->init_last_sent_to == asoc->peer.retran_path)
-                       sctp_assoc_update_retran_path(asoc);
-               t = asoc->peer.retran_path;
-       }
-
-       SCTP_DEBUG_PRINTK_IPADDR("sctp_assoc_update_retran_path:association"
-                                " %p addr: ",
-                                " port: %d\n",
-                                asoc,
-                                (&t->ipaddr),
-                                ntohs(t->ipaddr.v4.sin_port));
-
-       return t;
-}
-
-/* Choose the transport for sending a SHUTDOWN packet.  */
-struct sctp_transport *sctp_assoc_choose_shutdown_transport(
-       struct sctp_association *asoc)
+/* Choose the transport for sending retransmit packet.  */
+struct sctp_transport *sctp_assoc_choose_alter_transport(
+       struct sctp_association *asoc, struct sctp_transport *last_sent_to)
 {
-       /* If this is the first time SHUTDOWN is sent, use the active path,
-        * else use the retran path. If the last SHUTDOWN was sent over the
+       /* If this is the first time packet is sent, use the active path,
+        * else use the retran path. If the last packet was sent over the
         * retran path, update the retran path and use it.
         */
-       if (!asoc->shutdown_last_sent_to)
+       if (!last_sent_to)
                return asoc->peer.active_path;
        else {
-               if (asoc->shutdown_last_sent_to == asoc->peer.retran_path)
+               if (last_sent_to == asoc->peer.retran_path)
                        sctp_assoc_update_retran_path(asoc);
                return asoc->peer.retran_path;
        }
-
 }
 
 /* Update the association's pmtu and frag_point by going through all the
@@ -1482,6 +1470,10 @@ int sctp_assoc_set_id(struct sctp_association *asoc, gfp_t gfp)
 {
        int assoc_id;
        int error = 0;
+
+       /* If the id is already assigned, keep it. */
+       if (asoc->assoc_id)
+               return error;
 retry:
        if (unlikely(!idr_pre_get(&sctp_assocs_id, gfp)))
                return -ENOMEM;
index d2e98803ffe30a5ffba004562ea23c00f59ff1c9..c0c973e67addd236fa438aca6ca84d3058495ebd 100644 (file)
@@ -81,13 +81,13 @@ static void sctp_add_backlog(struct sock *sk, struct sk_buff *skb);
 /* Calculate the SCTP checksum of an SCTP packet.  */
 static inline int sctp_rcv_checksum(struct sk_buff *skb)
 {
-       struct sk_buff *list = skb_shinfo(skb)->frag_list;
        struct sctphdr *sh = sctp_hdr(skb);
        __le32 cmp = sh->checksum;
+       struct sk_buff *list;
        __le32 val;
        __u32 tmp = sctp_start_cksum((__u8 *)sh, skb_headlen(skb));
 
-       for (; list; list = list->next)
+       skb_walk_frags(skb, list)
                tmp = sctp_update_cksum((__u8 *)list->data, skb_headlen(list),
                                        tmp);
 
index 7d08f522ec844ea73f9e69dc4a7061d4f6885de3..b764114445156dc69146856c118cbf1a725addca 100644 (file)
@@ -405,13 +405,14 @@ int sctp_packet_transmit(struct sctp_packet *packet)
                        sctp_assoc_sync_pmtu(asoc);
                }
        }
-       nskb->dst = dst_clone(tp->dst);
-       if (!nskb->dst)
+       dst = dst_clone(tp->dst);
+       skb_dst_set(nskb, dst);
+       if (dst)
                goto no_route;
-       dst = nskb->dst;
 
        /* Build the SCTP header.  */
        sh = (struct sctphdr *)skb_push(nskb, sizeof(struct sctphdr));
+       skb_reset_transport_header(nskb);
        sh->source = htons(packet->source_port);
        sh->dest   = htons(packet->destination_port);
 
@@ -527,15 +528,25 @@ int sctp_packet_transmit(struct sctp_packet *packet)
         * Note: Adler-32 is no longer applicable, as has been replaced
         * by CRC32-C as described in <draft-ietf-tsvwg-sctpcsum-02.txt>.
         */
-       if (!sctp_checksum_disable && !(dst->dev->features & NETIF_F_NO_CSUM)) {
+       if (!sctp_checksum_disable &&
+           !(dst->dev->features & (NETIF_F_NO_CSUM | NETIF_F_SCTP_CSUM))) {
                __u32 crc32 = sctp_start_cksum((__u8 *)sh, cksum_buf_len);
 
                /* 3) Put the resultant value into the checksum field in the
                 *    common header, and leave the rest of the bits unchanged.
                 */
                sh->checksum = sctp_end_cksum(crc32);
-       } else
-               nskb->ip_summed = CHECKSUM_UNNECESSARY;
+       } else {
+               if (dst->dev->features & NETIF_F_SCTP_CSUM) {
+                       /* no need to seed psuedo checksum for SCTP */
+                       nskb->ip_summed = CHECKSUM_PARTIAL;
+                       nskb->csum_start = (skb_transport_header(nskb) -
+                                           nskb->head);
+                       nskb->csum_offset = offsetof(struct sctphdr, checksum);
+               } else {
+                       nskb->ip_summed = CHECKSUM_UNNECESSARY;
+               }
+       }
 
        /* IP layer ECN support
         * From RFC 2481
index 8eb3e61cb7011d1032d5562c0f266281ddf00688..79cbd47f4df7482b08e11c976d290b5b94ee545b 100644 (file)
@@ -393,7 +393,7 @@ static int sctp_v4_addr_valid(union sctp_addr *addr,
                return 0;
 
        /* Is this a broadcast address? */
-       if (skb && skb->rtable->rt_flags & RTCF_BROADCAST)
+       if (skb && skb_rtable(skb)->rt_flags & RTCF_BROADCAST)
                return 0;
 
        return 1;
@@ -572,7 +572,7 @@ static void sctp_v4_get_saddr(struct sctp_sock *sk,
 /* What interface did this skb arrive on? */
 static int sctp_v4_skb_iif(const struct sk_buff *skb)
 {
-       return skb->rtable->rt_iif;
+       return skb_rtable(skb)->rt_iif;
 }
 
 /* Was this packet marked by Explicit Congestion Notification? */
@@ -848,8 +848,8 @@ static inline int sctp_v4_xmit(struct sk_buff *skb,
 
        SCTP_DEBUG_PRINTK("%s: skb:%p, len:%d, src:%pI4, dst:%pI4\n",
                          __func__, skb, skb->len,
-                         &skb->rtable->rt_src,
-                         &skb->rtable->rt_dst);
+                         &skb_rtable(skb)->rt_src,
+                         &skb_rtable(skb)->rt_dst);
 
        inet->pmtudisc = transport->param_flags & SPP_PMTUD_ENABLE ?
                         IP_PMTUDISC_DO : IP_PMTUDISC_DONT;
@@ -1370,6 +1370,8 @@ SCTP_STATIC __exit void sctp_exit(void)
        sctp_proc_exit();
        cleanup_sctp_mibs();
 
+       rcu_barrier(); /* Wait for completion of call_rcu()'s */
+
        kmem_cache_destroy(sctp_chunk_cachep);
        kmem_cache_destroy(sctp_bucket_cachep);
 }
index 6851ee94e974a76530d3f7587a4c7be064290b13..61cc6075b0dffd4bb7ebefdaa7a516b1e6030393 100644 (file)
@@ -2864,19 +2864,19 @@ static __be16 sctp_process_asconf_param(struct sctp_association *asoc,
        switch (addr_param->v4.param_hdr.type) {
        case SCTP_PARAM_IPV6_ADDRESS:
                if (!asoc->peer.ipv6_address)
-                       return SCTP_ERROR_INV_PARAM;
+                       return SCTP_ERROR_DNS_FAILED;
                break;
        case SCTP_PARAM_IPV4_ADDRESS:
                if (!asoc->peer.ipv4_address)
-                       return SCTP_ERROR_INV_PARAM;
+                       return SCTP_ERROR_DNS_FAILED;
                break;
        default:
-               return SCTP_ERROR_INV_PARAM;
+               return SCTP_ERROR_DNS_FAILED;
        }
 
        af = sctp_get_af_specific(param_type2af(addr_param->v4.param_hdr.type));
        if (unlikely(!af))
-               return SCTP_ERROR_INV_PARAM;
+               return SCTP_ERROR_DNS_FAILED;
 
        af->from_addr_param(&addr, addr_param, htons(asoc->peer.port), 0);
 
@@ -2886,7 +2886,7 @@ static __be16 sctp_process_asconf_param(struct sctp_association *asoc,
         *  make sure we check for that)
         */
        if (!af->is_any(&addr) && !af->addr_valid(&addr, NULL, asconf->skb))
-               return SCTP_ERROR_INV_PARAM;
+               return SCTP_ERROR_DNS_FAILED;
 
        switch (asconf_param->param_hdr.type) {
        case SCTP_PARAM_ADD_IP:
@@ -2954,12 +2954,12 @@ static __be16 sctp_process_asconf_param(struct sctp_association *asoc,
 
                peer = sctp_assoc_lookup_paddr(asoc, &addr);
                if (!peer)
-                       return SCTP_ERROR_INV_PARAM;
+                       return SCTP_ERROR_DNS_FAILED;
 
                sctp_assoc_set_primary(asoc, peer);
                break;
        default:
-               return SCTP_ERROR_INV_PARAM;
+               return SCTP_ERROR_UNKNOWN_PARAM;
                break;
        }
 
@@ -3273,7 +3273,7 @@ int sctp_process_asconf_ack(struct sctp_association *asoc,
                        retval = 1;
                        break;
 
-               case SCTP_ERROR_INV_PARAM:
+               case SCTP_ERROR_UNKNOWN_PARAM:
                        /* Disable sending this type of asconf parameter in
                         * future.
                         */
index e2020eb2c8ca53ecc5fa1bad42e49d7c487b05f7..86426aac16009ec3e886efc2dd8fdd3f82f6a612 100644 (file)
@@ -686,7 +686,8 @@ static void sctp_cmd_setup_t2(sctp_cmd_seq_t *cmds,
 {
        struct sctp_transport *t;
 
-       t = sctp_assoc_choose_shutdown_transport(asoc);
+       t = sctp_assoc_choose_alter_transport(asoc,
+                                             asoc->shutdown_last_sent_to);
        asoc->shutdown_last_sent_to = t;
        asoc->timeouts[SCTP_EVENT_TIMEOUT_T2_SHUTDOWN] = t->rto;
        chunk->transport = t;
@@ -777,7 +778,7 @@ static void sctp_cmd_setup_t4(sctp_cmd_seq_t *cmds,
 {
        struct sctp_transport *t;
 
-       t = asoc->peer.active_path;
+       t = sctp_assoc_choose_alter_transport(asoc, chunk->transport);
        asoc->timeouts[SCTP_EVENT_TIMEOUT_T4_RTO] = t->rto;
        chunk->transport = t;
 }
@@ -1379,7 +1380,8 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
 
                case SCTP_CMD_INIT_CHOOSE_TRANSPORT:
                        chunk = cmd->obj.ptr;
-                       t = sctp_assoc_choose_init_transport(asoc);
+                       t = sctp_assoc_choose_alter_transport(asoc,
+                                               asoc->init_last_sent_to);
                        asoc->init_last_sent_to = t;
                        chunk->transport = t;
                        t->init_sent_count++;
index 55a61aa69662ccbb26ddae10f5a30e2d7ce44d59..7288192f7df5998d4da5ffcfa6dd7ed386693278 100644 (file)
@@ -5432,9 +5432,13 @@ sctp_disposition_t sctp_sf_t2_timer_expire(const struct sctp_endpoint *ep,
        if (!reply)
                goto nomem;
 
-       /* Do some failure management (Section 8.2). */
-       sctp_add_cmd_sf(commands, SCTP_CMD_STRIKE,
-                       SCTP_TRANSPORT(asoc->shutdown_last_sent_to));
+       /* Do some failure management (Section 8.2).
+        * If we remove the transport an SHUTDOWN was last sent to, don't
+        * do failure management.
+        */
+       if (asoc->shutdown_last_sent_to)
+               sctp_add_cmd_sf(commands, SCTP_CMD_STRIKE,
+                               SCTP_TRANSPORT(asoc->shutdown_last_sent_to));
 
        /* Set the transport for the SHUTDOWN/ACK chunk and the timeout for
         * the T2-shutdown timer.
@@ -5471,7 +5475,9 @@ sctp_disposition_t sctp_sf_t4_timer_expire(
         * detection on the appropriate destination address as defined in
         * RFC2960 [5] section 8.1 and 8.2.
         */
-       sctp_add_cmd_sf(commands, SCTP_CMD_STRIKE, SCTP_TRANSPORT(transport));
+       if (transport)
+               sctp_add_cmd_sf(commands, SCTP_CMD_STRIKE,
+                               SCTP_TRANSPORT(transport));
 
        /* Reconfig T4 timer and transport. */
        sctp_add_cmd_sf(commands, SCTP_CMD_SETUP_T4, SCTP_CHUNK(chunk));
index 5c8186d88c612f1a117b01b5381f9ee0208d105e..6d9b3aafcc5dbd4327a0d5a89e4fa03d4b710e5c 100644 (file)
@@ -698,7 +698,7 @@ chunk_event_table_unknown[SCTP_STATE_NUM_STATES] = {
        TYPE_SCTP_FUNC(sctp_sf_do_prm_asconf), \
        /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
        TYPE_SCTP_FUNC(sctp_sf_error_shutdown), \
-} /* TYPE_SCTP_PRIMITIVE_REQUESTHEARTBEAT */
+} /* TYPE_SCTP_PRIMITIVE_ASCONF */
 
 /* The primary index for this table is the primitive type.
  * The secondary index for this table is the state.
index 5fb3a8c9792e741dac08902a0f8b7cc1f43dc872..0f01e5d8a24f914e77292785bdd727244488fa65 100644 (file)
@@ -1100,6 +1100,15 @@ static int __sctp_connect(struct sock* sk,
                goto out_free;
        }
 
+       /* In case the user of sctp_connectx() wants an association
+        * id back, assign one now.
+        */
+       if (assoc_id) {
+               err = sctp_assoc_set_id(asoc, GFP_KERNEL);
+               if (err < 0)
+                       goto out_free;
+       }
+
        err = sctp_primitive_ASSOCIATE(asoc, NULL);
        if (err < 0) {
                goto out_free;
@@ -1120,7 +1129,7 @@ static int __sctp_connect(struct sock* sk,
        timeo = sock_sndtimeo(sk, f_flags & O_NONBLOCK);
 
        err = sctp_wait_for_connect(asoc, &timeo);
-       if (!err && assoc_id)
+       if ((err == 0 || err == -EINPROGRESS) && assoc_id)
                *assoc_id = asoc->assoc_id;
 
        /* Don't free association on exit. */
@@ -1264,6 +1273,34 @@ SCTP_STATIC int sctp_setsockopt_connectx(struct sock* sk,
                return assoc_id;
 }
 
+/*
+ * New (hopefully final) interface for the API.  The option buffer is used
+ * both for the returned association id and the addresses.
+ */
+SCTP_STATIC int sctp_getsockopt_connectx3(struct sock* sk, int len,
+                                       char __user *optval,
+                                       int __user *optlen)
+{
+       sctp_assoc_t assoc_id = 0;
+       int err = 0;
+
+       if (len < sizeof(assoc_id))
+               return -EINVAL;
+
+       err = __sctp_setsockopt_connectx(sk,
+                       (struct sockaddr __user *)(optval + sizeof(assoc_id)),
+                       len - sizeof(assoc_id), &assoc_id);
+
+       if (err == 0 || err == -EINPROGRESS) {
+               if (copy_to_user(optval, &assoc_id, sizeof(assoc_id)))
+                       return -EFAULT;
+               if (put_user(sizeof(assoc_id), optlen))
+                       return -EFAULT;
+       }
+
+       return err;
+}
+
 /* API 3.1.4 close() - UDP Style Syntax
  * Applications use close() to perform graceful shutdown (as described in
  * Section 10.1 of [SCTP]) on ALL the associations currently represented
@@ -1844,7 +1881,7 @@ static int sctp_skb_pull(struct sk_buff *skb, int len)
        len -= skb_len;
        __skb_pull(skb, skb_len);
 
-       for (list = skb_shinfo(skb)->frag_list; list; list = list->next) {
+       skb_walk_frags(skb, list) {
                rlen = sctp_skb_pull(list, len);
                skb->len -= (len-rlen);
                skb->data_len -= (len-rlen);
@@ -5578,6 +5615,9 @@ SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname,
                retval = sctp_getsockopt_local_addrs(sk, len, optval,
                                                     optlen);
                break;
+       case SCTP_SOCKOPT_CONNECTX3:
+               retval = sctp_getsockopt_connectx3(sk, len, optval, optlen);
+               break;
        case SCTP_DEFAULT_SEND_PARAM:
                retval = sctp_getsockopt_default_send_param(sk, len,
                                                            optval, optlen);
@@ -6620,7 +6660,7 @@ static void sctp_sock_rfree_frag(struct sk_buff *skb)
                goto done;
 
        /* Don't forget the fragments. */
-       for (frag = skb_shinfo(skb)->frag_list; frag; frag = frag->next)
+       skb_walk_frags(skb, frag)
                sctp_sock_rfree_frag(frag);
 
 done:
@@ -6635,7 +6675,7 @@ static void sctp_skb_set_owner_r_frag(struct sk_buff *skb, struct sock *sk)
                goto done;
 
        /* Don't forget the fragments. */
-       for (frag = skb_shinfo(skb)->frag_list; frag; frag = frag->next)
+       skb_walk_frags(skb, frag)
                sctp_skb_set_owner_r_frag(frag, sk);
 
 done:
index f58e994e6852f72a956c24afbc17258f49955aa0..63eabbc71298a30b76196aa8f341db78bdf30f31 100644 (file)
@@ -49,8 +49,8 @@ static int zero = 0;
 static int one = 1;
 static int timer_max = 86400000; /* ms in one day */
 static int int_max = INT_MAX;
-static long sack_timer_min = 1;
-static long sack_timer_max = 500;
+static int sack_timer_min = 1;
+static int sack_timer_max = 500;
 
 extern int sysctl_sctp_mem[3];
 extern int sysctl_sctp_rmem[3];
@@ -223,7 +223,7 @@ static ctl_table sctp_table[] = {
                .ctl_name       = NET_SCTP_SACK_TIMEOUT,
                .procname       = "sack_timeout",
                .data           = &sctp_sack_timeout,
-               .maxlen         = sizeof(long),
+               .maxlen         = sizeof(int),
                .mode           = 0644,
                .proc_handler   = proc_dointvec_minmax,
                .strategy       = sysctl_intvec,
index 5f186ca550d798e7fa4e6bad1262d16aca82dae4..8b3560fd876d2b95b361460b16fa3d92291a3160 100644 (file)
@@ -976,9 +976,8 @@ static void sctp_ulpevent_receive_data(struct sctp_ulpevent *event,
         * In general, the skb passed from IP can have only 1 level of
         * fragments. But we allow multiple levels of fragments.
         */
-       for (frag = skb_shinfo(skb)->frag_list; frag; frag = frag->next) {
+       skb_walk_frags(skb, frag)
                sctp_ulpevent_receive_data(sctp_skb2event(frag), asoc);
-       }
 }
 
 /* Do accounting for bytes just read by user and release the references to
@@ -1003,7 +1002,7 @@ static void sctp_ulpevent_release_data(struct sctp_ulpevent *event)
                goto done;
 
        /* Don't forget the fragments. */
-       for (frag = skb_shinfo(skb)->frag_list; frag; frag = frag->next) {
+       skb_walk_frags(skb, frag) {
                /* NOTE:  skb_shinfos are recursive. Although IP returns
                 * skb's with only 1 level of fragments, SCTP reassembly can
                 * increase the levels.
@@ -1026,7 +1025,7 @@ static void sctp_ulpevent_release_frag_data(struct sctp_ulpevent *event)
                goto done;
 
        /* Don't forget the fragments. */
-       for (frag = skb_shinfo(skb)->frag_list; frag; frag = frag->next) {
+       skb_walk_frags(skb, frag) {
                /* NOTE:  skb_shinfos are recursive. Although IP returns
                 * skb's with only 1 level of fragments, SCTP reassembly can
                 * increase the levels.
index e630b38a604718a57c80a93e7556452859cf35c1..66d458fc69206e69a50663f12b0a491a750b7c80 100644 (file)
@@ -1548,6 +1548,7 @@ static void __exit exit_rpcsec_gss(void)
 {
        gss_svc_shutdown();
        rpcauth_unregister(&authgss_ops);
+       rcu_barrier(); /* Wait for completion of call_rcu()'s */
 }
 
 MODULE_LICENSE("GPL");
index e1859614601350c219e23116978a2f40ccc9a96d..6c2d61586551511ff303760923bf6a887e0ae7b1 100644 (file)
@@ -918,7 +918,7 @@ static void xs_udp_data_ready(struct sock *sk, int len)
        UDPX_INC_STATS_BH(sk, UDP_MIB_INDATAGRAMS);
 
        /* Something worked... */
-       dst_confirm(skb->dst);
+       dst_confirm(skb_dst(skb));
 
        xprt_adjust_cwnd(task, copied);
        xprt_update_rtt(task);
index f72ba774c246835228405e712a64c1387c6123e3..524ba5696d4d6530c1cf7cea80832cb8158cfaa9 100644 (file)
@@ -167,7 +167,7 @@ static int enable_bearer(struct tipc_bearer *tb_ptr)
        tb_ptr->mtu = dev->mtu;
        tb_ptr->blocked = 0;
        tb_ptr->addr.type = htonl(TIPC_MEDIA_TYPE_ETH);
-       memcpy(&tb_ptr->addr.dev_addr, &dev->dev_addr, ETH_ALEN);
+       memcpy(&tb_ptr->addr.dev_addr, dev->dev_addr, ETH_ALEN);
        return 0;
 }
 
index c387217bb23066d20c6324cd0c9ee0d8200a91bd..3c57005e44d1cd060e17d8e13ae93a1d75b65315 100644 (file)
@@ -68,7 +68,7 @@ static int handle_cmd(struct sk_buff *skb, struct genl_info *info)
        return 0;
 }
 
-static struct genl_family family = {
+static struct genl_family tipc_genl_family = {
        .id             = GENL_ID_GENERATE,
        .name           = TIPC_GENL_NAME,
        .version        = TIPC_GENL_VERSION,
@@ -76,39 +76,33 @@ static struct genl_family family = {
        .maxattr        = 0,
 };
 
-static struct genl_ops ops = {
+static struct genl_ops tipc_genl_ops = {
        .cmd            = TIPC_GENL_CMD,
        .doit           = handle_cmd,
 };
 
-static int family_registered = 0;
+static int tipc_genl_family_registered;
 
 int tipc_netlink_start(void)
 {
+       int res;
 
+       res = genl_register_family_with_ops(&tipc_genl_family,
+               &tipc_genl_ops, 1);
+       if (res) {
+               err("Failed to register netlink interface\n");
+               return res;
+       }
 
-       if (genl_register_family(&family))
-               goto err;
-
-       family_registered = 1;
-
-       if (genl_register_ops(&family, &ops))
-               goto err_unregister;
-
+       tipc_genl_family_registered = 1;
        return 0;
-
- err_unregister:
-       genl_unregister_family(&family);
-       family_registered = 0;
- err:
-       err("Failed to register netlink interface\n");
-       return -EFAULT;
 }
 
 void tipc_netlink_stop(void)
 {
-       if (family_registered) {
-               genl_unregister_family(&family);
-               family_registered = 0;
-       }
+       if (!tipc_genl_family_registered)
+               return;
+
+       genl_unregister_family(&tipc_genl_family);
+       tipc_genl_family_registered = 0;
 }
index 1b46747a5f5af2cc3521071984629fb1bb63d6dd..e4d97ab476d58482d0ab9c7060d50d3aadc54ccc 100644 (file)
@@ -1,23 +1,10 @@
 #
 # WiMAX LAN device configuration
 #
-# Note the ugly 'depends on' on WIMAX: that disallows RFKILL to be a
-# module if WIMAX is to be linked in. The WiMAX code is done in such a
-# way that it doesn't require and explicit dependency on RFKILL in
-# case an embedded system wants to rip it out.
-#
-# As well, enablement of the RFKILL code means we need the INPUT layer
-# support to inject events coming from hw rfkill switches. That
-# dependency could be killed if input.h provided appropriate means to
-# work when input is disabled.
-
-comment "WiMAX Wireless Broadband support requires CONFIG_INPUT enabled"
-       depends on INPUT = n && RFKILL != n
 
 menuconfig WIMAX
        tristate "WiMAX Wireless Broadband support"
-       depends on (y && RFKILL != m) || m
-       depends on (INPUT && RFKILL != n) || RFKILL = n
+       depends on RFKILL || !RFKILL
        help
 
          Select to configure support for devices that provide
index 5b80b941c2c9431e5d0e214653a0ead31e56311a..8f1510d0cc2bf54e9723bc6c07172ac4e763b634 100644 (file)
@@ -6,6 +6,7 @@ wimax-y :=              \
        op-msg.o        \
        op-reset.o      \
        op-rfkill.o     \
+       op-state-get.o  \
        stack.o
 
 wimax-$(CONFIG_DEBUG_FS) += debugfs.o
index 1c29123a3aa96a6ab5256b95224a95a290831f8e..0975adba6b71a9876bb0578420b989eca32b526d 100644 (file)
@@ -36,6 +36,7 @@ enum d_module {
        D_SUBMODULE_DECLARE(op_msg),
        D_SUBMODULE_DECLARE(op_reset),
        D_SUBMODULE_DECLARE(op_rfkill),
+       D_SUBMODULE_DECLARE(op_state_get),
        D_SUBMODULE_DECLARE(stack),
 };
 
index 94d216a464078136c890ad5333be1bc3f15449e5..6c9bedb7431e5f58d02b471c27a32981bffbccb1 100644 (file)
@@ -61,6 +61,7 @@ int wimax_debugfs_add(struct wimax_dev *wimax_dev)
        __debugfs_register("wimax_dl_", op_msg, dentry);
        __debugfs_register("wimax_dl_", op_reset, dentry);
        __debugfs_register("wimax_dl_", op_rfkill, dentry);
+       __debugfs_register("wimax_dl_", op_state_get, dentry);
        __debugfs_register("wimax_dl_", stack, dentry);
        result = 0;
 out:
index 9ad4d893a566b6e8e8b535a8e4fc0784c13c7098..d631a17186bcd06c9aa7ae19c0af7653badc6b41 100644 (file)
  * Don't use skb_push()/skb_pull()/skb_reserve() on the skb, as
  * wimax_msg_send() depends on skb->data being placed at the
  * beginning of the user message.
+ *
+ * Unlike other WiMAX stack calls, this call can be used way early,
+ * even before wimax_dev_add() is called, as long as the
+ * wimax_dev->net_dev pointer is set to point to a proper
+ * net_dev. This is so that drivers can use it early in case they need
+ * to send stuff around or communicate with user space.
  */
 struct sk_buff *wimax_msg_alloc(struct wimax_dev *wimax_dev,
                                const char *pipe_name,
@@ -115,7 +121,7 @@ struct sk_buff *wimax_msg_alloc(struct wimax_dev *wimax_dev,
                                gfp_t gfp_flags)
 {
        int result;
-       struct device *dev = wimax_dev->net_dev->dev.parent;
+       struct device *dev = wimax_dev_to_dev(wimax_dev);
        size_t msg_size;
        void *genl_msg;
        struct sk_buff *skb;
@@ -161,7 +167,6 @@ error_genlmsg_put:
 error_new:
        nlmsg_free(skb);
        return ERR_PTR(result);
-
 }
 EXPORT_SYMBOL_GPL(wimax_msg_alloc);
 
@@ -256,10 +261,16 @@ EXPORT_SYMBOL_GPL(wimax_msg_len);
  * Don't use skb_push()/skb_pull()/skb_reserve() on the skb, as
  * wimax_msg_send() depends on skb->data being placed at the
  * beginning of the user message.
+ *
+ * Unlike other WiMAX stack calls, this call can be used way early,
+ * even before wimax_dev_add() is called, as long as the
+ * wimax_dev->net_dev pointer is set to point to a proper
+ * net_dev. This is so that drivers can use it early in case they need
+ * to send stuff around or communicate with user space.
  */
 int wimax_msg_send(struct wimax_dev *wimax_dev, struct sk_buff *skb)
 {
-       struct device *dev = wimax_dev->net_dev->dev.parent;
+       struct device *dev = wimax_dev_to_dev(wimax_dev);
        void *msg = skb->data;
        size_t size = skb->len;
        might_sleep();
index 2b75aee042173b5edb5d13d12216180b67497688..70ef4df863b974ef4ad0e199b4e4fb424b96a892 100644 (file)
@@ -29,8 +29,8 @@
  * A non-polled generic rfkill device is embedded into the WiMAX
  * subsystem's representation of a device.
  *
- * FIXME: Need polled support? use a timer or add the implementation
- *     to the stack.
+ * FIXME: Need polled support? Let drivers provide a poll routine
+ *       and hand it to rfkill ops then?
  *
  * All device drivers have to do is after wimax_dev_init(), call
  * wimax_report_rfkill_hw() and wimax_report_rfkill_sw() to update
@@ -43,7 +43,7 @@
  *   wimax_rfkill()             Kernel calling wimax_rfkill()
  *     __wimax_rf_toggle_radio()
  *
- * wimax_rfkill_toggle_radio()  RF-Kill subsytem calling
+ * wimax_rfkill_set_radio_block()  RF-Kill subsytem calling
  *   __wimax_rf_toggle_radio()
  *
  * __wimax_rf_toggle_radio()
 #include <linux/wimax.h>
 #include <linux/security.h>
 #include <linux/rfkill.h>
-#include <linux/input.h>
 #include "wimax-internal.h"
 
 #define D_SUBMODULE op_rfkill
 #include "debug-levels.h"
 
-#if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
-
-
 /**
  * wimax_report_rfkill_hw - Reports changes in the hardware RF switch
  *
@@ -99,7 +95,6 @@ void wimax_report_rfkill_hw(struct wimax_dev *wimax_dev,
        int result;
        struct device *dev = wimax_dev_to_dev(wimax_dev);
        enum wimax_st wimax_state;
-       enum rfkill_state rfkill_state;
 
        d_fnstart(3, dev, "(wimax_dev %p state %u)\n", wimax_dev, state);
        BUG_ON(state == WIMAX_RF_QUERY);
@@ -112,16 +107,16 @@ void wimax_report_rfkill_hw(struct wimax_dev *wimax_dev,
 
        if (state != wimax_dev->rf_hw) {
                wimax_dev->rf_hw = state;
-               rfkill_state = state == WIMAX_RF_ON ?
-                       RFKILL_STATE_OFF : RFKILL_STATE_ON;
                if (wimax_dev->rf_hw == WIMAX_RF_ON
                    && wimax_dev->rf_sw == WIMAX_RF_ON)
                        wimax_state = WIMAX_ST_READY;
                else
                        wimax_state = WIMAX_ST_RADIO_OFF;
+
+               result = rfkill_set_hw_state(wimax_dev->rfkill,
+                                            state == WIMAX_RF_OFF);
+
                __wimax_state_change(wimax_dev, wimax_state);
-               input_report_key(wimax_dev->rfkill_input, KEY_WIMAX,
-                                rfkill_state);
        }
 error_not_ready:
        mutex_unlock(&wimax_dev->mutex);
@@ -174,6 +169,7 @@ void wimax_report_rfkill_sw(struct wimax_dev *wimax_dev,
                else
                        wimax_state = WIMAX_ST_RADIO_OFF;
                __wimax_state_change(wimax_dev, wimax_state);
+               rfkill_set_sw_state(wimax_dev->rfkill, state == WIMAX_RF_OFF);
        }
 error_not_ready:
        mutex_unlock(&wimax_dev->mutex);
@@ -249,36 +245,31 @@ out_no_change:
  *
  * NOTE: This call will block until the operation is completed.
  */
-static
-int wimax_rfkill_toggle_radio(void *data, enum rfkill_state state)
+static int wimax_rfkill_set_radio_block(void *data, bool blocked)
 {
        int result;
        struct wimax_dev *wimax_dev = data;
        struct device *dev = wimax_dev_to_dev(wimax_dev);
        enum wimax_rf_state rf_state;
 
-       d_fnstart(3, dev, "(wimax_dev %p state %u)\n", wimax_dev, state);
-       switch (state) {
-       case RFKILL_STATE_ON:
+       d_fnstart(3, dev, "(wimax_dev %p blocked %u)\n", wimax_dev, blocked);
+       rf_state = WIMAX_RF_ON;
+       if (blocked)
                rf_state = WIMAX_RF_OFF;
-               break;
-       case RFKILL_STATE_OFF:
-               rf_state = WIMAX_RF_ON;
-               break;
-       default:
-               BUG();
-       }
        mutex_lock(&wimax_dev->mutex);
        if (wimax_dev->state <= __WIMAX_ST_QUIESCING)
-               result = 0;     /* just pretend it didn't happen */
+               result = 0;
        else
                result = __wimax_rf_toggle_radio(wimax_dev, rf_state);
        mutex_unlock(&wimax_dev->mutex);
-       d_fnend(3, dev, "(wimax_dev %p state %u) = %d\n",
-               wimax_dev, state, result);
+       d_fnend(3, dev, "(wimax_dev %p blocked %u) = %d\n",
+               wimax_dev, blocked, result);
        return result;
 }
 
+static const struct rfkill_ops wimax_rfkill_ops = {
+       .set_block = wimax_rfkill_set_radio_block,
+};
 
 /**
  * wimax_rfkill - Set the software RF switch state for a WiMAX device
@@ -322,6 +313,7 @@ int wimax_rfkill(struct wimax_dev *wimax_dev, enum wimax_rf_state state)
                result = __wimax_rf_toggle_radio(wimax_dev, state);
                if (result < 0)
                        goto error;
+               rfkill_set_sw_state(wimax_dev->rfkill, state == WIMAX_RF_OFF);
                break;
        case WIMAX_RF_QUERY:
                break;
@@ -349,41 +341,20 @@ int wimax_rfkill_add(struct wimax_dev *wimax_dev)
 {
        int result;
        struct rfkill *rfkill;
-       struct input_dev *input_dev;
        struct device *dev = wimax_dev_to_dev(wimax_dev);
 
        d_fnstart(3, dev, "(wimax_dev %p)\n", wimax_dev);
        /* Initialize RF Kill */
        result = -ENOMEM;
-       rfkill = rfkill_allocate(dev, RFKILL_TYPE_WIMAX);
+       rfkill = rfkill_alloc(wimax_dev->name, dev, RFKILL_TYPE_WIMAX,
+                             &wimax_rfkill_ops, wimax_dev);
        if (rfkill == NULL)
                goto error_rfkill_allocate;
+
+       d_printf(1, dev, "rfkill %p\n", rfkill);
+
        wimax_dev->rfkill = rfkill;
 
-       rfkill->name = wimax_dev->name;
-       rfkill->state = RFKILL_STATE_OFF;
-       rfkill->data = wimax_dev;
-       rfkill->toggle_radio = wimax_rfkill_toggle_radio;
-       rfkill->user_claim_unsupported = 1;
-
-       /* Initialize the input device for the hw key */
-       input_dev = input_allocate_device();
-       if (input_dev == NULL)
-               goto error_input_allocate;
-       wimax_dev->rfkill_input = input_dev;
-       d_printf(1, dev, "rfkill %p input %p\n", rfkill, input_dev);
-
-       input_dev->name = wimax_dev->name;
-       /* FIXME: get a real device bus ID and stuff? do we care? */
-       input_dev->id.bustype = BUS_HOST;
-       input_dev->id.vendor = 0xffff;
-       input_dev->evbit[0] = BIT(EV_KEY);
-       set_bit(KEY_WIMAX, input_dev->keybit);
-
-       /* Register both */
-       result = input_register_device(wimax_dev->rfkill_input);
-       if (result < 0)
-               goto error_input_register;
        result = rfkill_register(wimax_dev->rfkill);
        if (result < 0)
                goto error_rfkill_register;
@@ -395,17 +366,8 @@ int wimax_rfkill_add(struct wimax_dev *wimax_dev)
        d_fnend(3, dev, "(wimax_dev %p) = 0\n", wimax_dev);
        return 0;
 
-       /* if rfkill_register() suceeds, can't use rfkill_free() any
-        * more, only rfkill_unregister() [it owns the refcount]; with
-        * the input device we have the same issue--hence the if. */
 error_rfkill_register:
-       input_unregister_device(wimax_dev->rfkill_input);
-       wimax_dev->rfkill_input = NULL;
-error_input_register:
-       if (wimax_dev->rfkill_input)
-               input_free_device(wimax_dev->rfkill_input);
-error_input_allocate:
-       rfkill_free(wimax_dev->rfkill);
+       rfkill_destroy(wimax_dev->rfkill);
 error_rfkill_allocate:
        d_fnend(3, dev, "(wimax_dev %p) = %d\n", wimax_dev, result);
        return result;
@@ -424,45 +386,12 @@ void wimax_rfkill_rm(struct wimax_dev *wimax_dev)
 {
        struct device *dev = wimax_dev_to_dev(wimax_dev);
        d_fnstart(3, dev, "(wimax_dev %p)\n", wimax_dev);
-       rfkill_unregister(wimax_dev->rfkill);   /* frees */
-       input_unregister_device(wimax_dev->rfkill_input);
+       rfkill_unregister(wimax_dev->rfkill);
+       rfkill_destroy(wimax_dev->rfkill);
        d_fnend(3, dev, "(wimax_dev %p)\n", wimax_dev);
 }
 
 
-#else /* #ifdef CONFIG_RFKILL */
-
-void wimax_report_rfkill_hw(struct wimax_dev *wimax_dev,
-                           enum wimax_rf_state state)
-{
-}
-EXPORT_SYMBOL_GPL(wimax_report_rfkill_hw);
-
-void wimax_report_rfkill_sw(struct wimax_dev *wimax_dev,
-                           enum wimax_rf_state state)
-{
-}
-EXPORT_SYMBOL_GPL(wimax_report_rfkill_sw);
-
-int wimax_rfkill(struct wimax_dev *wimax_dev,
-                enum wimax_rf_state state)
-{
-       return WIMAX_RF_ON << 1 | WIMAX_RF_ON;
-}
-EXPORT_SYMBOL_GPL(wimax_rfkill);
-
-int wimax_rfkill_add(struct wimax_dev *wimax_dev)
-{
-       return 0;
-}
-
-void wimax_rfkill_rm(struct wimax_dev *wimax_dev)
-{
-}
-
-#endif /* #ifdef CONFIG_RFKILL */
-
-
 /*
  * Exporting to user space over generic netlink
  *
diff --git a/net/wimax/op-state-get.c b/net/wimax/op-state-get.c
new file mode 100644 (file)
index 0000000..a76b8fc
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * Linux WiMAX
+ * Implement and export a method for getting a WiMAX device current state
+ *
+ * Copyright (C) 2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
+ *
+ * Based on previous WiMAX core work by:
+ *  Copyright (C) 2008 Intel Corporation <linux-wimax@intel.com>
+ *  Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.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., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+#include <net/wimax.h>
+#include <net/genetlink.h>
+#include <linux/wimax.h>
+#include <linux/security.h>
+#include "wimax-internal.h"
+
+#define D_SUBMODULE op_state_get
+#include "debug-levels.h"
+
+
+static const
+struct nla_policy wimax_gnl_state_get_policy[WIMAX_GNL_ATTR_MAX + 1] = {
+       [WIMAX_GNL_STGET_IFIDX] = {
+               .type = NLA_U32,
+       },
+};
+
+
+/*
+ * Exporting to user space over generic netlink
+ *
+ * Parse the state get command from user space, return a combination
+ * value that describe the current state.
+ *
+ * No attributes.
+ */
+static
+int wimax_gnl_doit_state_get(struct sk_buff *skb, struct genl_info *info)
+{
+       int result, ifindex;
+       struct wimax_dev *wimax_dev;
+       struct device *dev;
+
+       d_fnstart(3, NULL, "(skb %p info %p)\n", skb, info);
+       result = -ENODEV;
+       if (info->attrs[WIMAX_GNL_STGET_IFIDX] == NULL) {
+               printk(KERN_ERR "WIMAX_GNL_OP_STATE_GET: can't find IFIDX "
+                       "attribute\n");
+               goto error_no_wimax_dev;
+       }
+       ifindex = nla_get_u32(info->attrs[WIMAX_GNL_STGET_IFIDX]);
+       wimax_dev = wimax_dev_get_by_genl_info(info, ifindex);
+       if (wimax_dev == NULL)
+               goto error_no_wimax_dev;
+       dev = wimax_dev_to_dev(wimax_dev);
+       /* Execute the operation and send the result back to user space */
+       result = wimax_state_get(wimax_dev);
+       dev_put(wimax_dev->net_dev);
+error_no_wimax_dev:
+       d_fnend(3, NULL, "(skb %p info %p) = %d\n", skb, info, result);
+       return result;
+}
+
+
+struct genl_ops wimax_gnl_state_get = {
+       .cmd = WIMAX_GNL_OP_STATE_GET,
+       .flags = GENL_ADMIN_PERM,
+       .policy = wimax_gnl_state_get_policy,
+       .doit = wimax_gnl_doit_state_get,
+       .dumpit = NULL,
+};
index 933e1422b09f98de1939347fb4dbb92a963ea36e..79fb7d7c640f0b86869d8a8fd77a6f60de8ef4c2 100644 (file)
@@ -402,13 +402,15 @@ EXPORT_SYMBOL_GPL(wimax_dev_init);
 extern struct genl_ops
        wimax_gnl_msg_from_user,
        wimax_gnl_reset,
-       wimax_gnl_rfkill;
+       wimax_gnl_rfkill,
+       wimax_gnl_state_get;
 
 static
 struct genl_ops *wimax_gnl_ops[] = {
        &wimax_gnl_msg_from_user,
        &wimax_gnl_reset,
        &wimax_gnl_rfkill,
+       &wimax_gnl_state_get,
 };
 
 
@@ -533,6 +535,7 @@ struct d_level D_LEVEL[] = {
        D_SUBMODULE_DEFINE(op_msg),
        D_SUBMODULE_DEFINE(op_reset),
        D_SUBMODULE_DEFINE(op_rfkill),
+       D_SUBMODULE_DEFINE(op_state_get),
        D_SUBMODULE_DEFINE(stack),
 };
 size_t D_LEVEL_SIZE = ARRAY_SIZE(D_LEVEL);
index 3c3bc9e579edad5f7719577fc96ecea9f136250f..4428dd5e911de191f33be7b41018370bf6d53516 100644 (file)
@@ -1,5 +1,6 @@
 config CFG80211
-        tristate "Improved wireless configuration API"
+       tristate "Improved wireless configuration API"
+       depends on RFKILL || !RFKILL
 
 config CFG80211_REG_DEBUG
        bool "cfg80211 regulatory debugging"
@@ -10,6 +11,14 @@ config CFG80211_REG_DEBUG
 
          If unsure, say N.
 
+config CFG80211_DEBUGFS
+       bool "cfg80211 DebugFS entries"
+       depends on CFG80211 && DEBUG_FS
+       ---help---
+         You can enable this if you want to debugfs entries for cfg80211.
+
+         If unsure, say N.
+
 config WIRELESS_OLD_REGULATORY
        bool "Old wireless static regulatory definitions"
        default n
index 6d1e7b27b752a8d99a404502d94d2322f49940df..f78c4832a9ca546a12f63b30d1d869918b7c7c5d 100644 (file)
@@ -5,7 +5,8 @@ obj-$(CONFIG_LIB80211_CRYPT_WEP) += lib80211_crypt_wep.o
 obj-$(CONFIG_LIB80211_CRYPT_CCMP) += lib80211_crypt_ccmp.o
 obj-$(CONFIG_LIB80211_CRYPT_TKIP) += lib80211_crypt_tkip.o
 
-cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o scan.o nl80211.o mlme.o
+cfg80211-y += core.o sysfs.o radiotap.o util.o reg.o scan.o nl80211.o mlme.o ibss.o
+cfg80211-$(CONFIG_CFG80211_DEBUGFS) += debugfs.o
 cfg80211-$(CONFIG_WIRELESS_EXT) += wext-compat.o
 
 ccflags-y += -D__CHECK_ENDIAN__
index d1f556535f6d784b27a1d4773fc128d2d15eb737..d5850292b3df1785053cf51cd07073441eb482a6 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This is the linux wireless configuration interface.
  *
- * Copyright 2006-2008         Johannes Berg <johannes@sipsolutions.net>
+ * Copyright 2006-2009         Johannes Berg <johannes@sipsolutions.net>
  */
 
 #include <linux/if.h>
 #include <linux/debugfs.h>
 #include <linux/notifier.h>
 #include <linux/device.h>
+#include <linux/rtnetlink.h>
 #include <net/genetlink.h>
 #include <net/cfg80211.h>
-#include <net/wireless.h>
 #include "nl80211.h"
 #include "core.h"
 #include "sysfs.h"
+#include "debugfs.h"
 
 /* name for sysfs, %d is appended */
 #define PHY_NAME "phy"
@@ -227,9 +228,44 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
        return 0;
 }
 
+static void cfg80211_rfkill_poll(struct rfkill *rfkill, void *data)
+{
+       struct cfg80211_registered_device *drv = data;
+
+       drv->ops->rfkill_poll(&drv->wiphy);
+}
+
+static int cfg80211_rfkill_set_block(void *data, bool blocked)
+{
+       struct cfg80211_registered_device *drv = data;
+       struct wireless_dev *wdev;
+
+       if (!blocked)
+               return 0;
+
+       rtnl_lock();
+       mutex_lock(&drv->devlist_mtx);
+
+       list_for_each_entry(wdev, &drv->netdev_list, list)
+               dev_close(wdev->netdev);
+
+       mutex_unlock(&drv->devlist_mtx);
+       rtnl_unlock();
+
+       return 0;
+}
+
+static void cfg80211_rfkill_sync_work(struct work_struct *work)
+{
+       struct cfg80211_registered_device *drv;
+
+       drv = container_of(work, struct cfg80211_registered_device, rfkill_sync);
+       cfg80211_rfkill_set_block(drv, rfkill_blocked(drv->rfkill));
+}
+
 /* exported functions */
 
-struct wiphy *wiphy_new(struct cfg80211_ops *ops, int sizeof_priv)
+struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
 {
        static int wiphy_counter;
 
@@ -274,6 +310,28 @@ struct wiphy *wiphy_new(struct cfg80211_ops *ops, int sizeof_priv)
        drv->wiphy.dev.class = &ieee80211_class;
        drv->wiphy.dev.platform_data = drv;
 
+       drv->rfkill_ops.set_block = cfg80211_rfkill_set_block;
+       drv->rfkill = rfkill_alloc(dev_name(&drv->wiphy.dev),
+                                  &drv->wiphy.dev, RFKILL_TYPE_WLAN,
+                                  &drv->rfkill_ops, drv);
+
+       if (!drv->rfkill) {
+               kfree(drv);
+               return NULL;
+       }
+
+       INIT_WORK(&drv->rfkill_sync, cfg80211_rfkill_sync_work);
+
+       /*
+        * Initialize wiphy parameters to IEEE 802.11 MIB default values.
+        * Fragmentation and RTS threshold are disabled by default with the
+        * special -1 value.
+        */
+       drv->wiphy.retry_short = 7;
+       drv->wiphy.retry_long = 4;
+       drv->wiphy.frag_threshold = (u32) -1;
+       drv->wiphy.rts_threshold = (u32) -1;
+
        return &drv->wiphy;
 }
 EXPORT_SYMBOL(wiphy_new);
@@ -337,17 +395,23 @@ int wiphy_register(struct wiphy *wiphy)
        /* check and set up bitrates */
        ieee80211_set_bitrate_flags(wiphy);
 
+       res = device_add(&drv->wiphy.dev);
+       if (res)
+               return res;
+
+       res = rfkill_register(drv->rfkill);
+       if (res)
+               goto out_rm_dev;
+
        mutex_lock(&cfg80211_mutex);
 
        /* set up regulatory info */
        wiphy_update_regulatory(wiphy, NL80211_REGDOM_SET_BY_CORE);
 
-       res = device_add(&drv->wiphy.dev);
-       if (res)
-               goto out_unlock;
-
        list_add(&drv->list, &cfg80211_drv_list);
 
+       mutex_unlock(&cfg80211_mutex);
+
        /* add to debugfs */
        drv->wiphy.debugfsdir =
                debugfs_create_dir(wiphy_name(&drv->wiphy),
@@ -366,17 +430,41 @@ int wiphy_register(struct wiphy *wiphy)
                nl80211_send_reg_change_event(&request);
        }
 
-       res = 0;
-out_unlock:
-       mutex_unlock(&cfg80211_mutex);
+       cfg80211_debugfs_drv_add(drv);
+
+       return 0;
+
+ out_rm_dev:
+       device_del(&drv->wiphy.dev);
        return res;
 }
 EXPORT_SYMBOL(wiphy_register);
 
+void wiphy_rfkill_start_polling(struct wiphy *wiphy)
+{
+       struct cfg80211_registered_device *drv = wiphy_to_dev(wiphy);
+
+       if (!drv->ops->rfkill_poll)
+               return;
+       drv->rfkill_ops.poll = cfg80211_rfkill_poll;
+       rfkill_resume_polling(drv->rfkill);
+}
+EXPORT_SYMBOL(wiphy_rfkill_start_polling);
+
+void wiphy_rfkill_stop_polling(struct wiphy *wiphy)
+{
+       struct cfg80211_registered_device *drv = wiphy_to_dev(wiphy);
+
+       rfkill_pause_polling(drv->rfkill);
+}
+EXPORT_SYMBOL(wiphy_rfkill_stop_polling);
+
 void wiphy_unregister(struct wiphy *wiphy)
 {
        struct cfg80211_registered_device *drv = wiphy_to_dev(wiphy);
 
+       rfkill_unregister(drv->rfkill);
+
        /* protect the device list */
        mutex_lock(&cfg80211_mutex);
 
@@ -396,6 +484,8 @@ void wiphy_unregister(struct wiphy *wiphy)
        /* unlock again before freeing */
        mutex_unlock(&drv->mtx);
 
+       cfg80211_debugfs_drv_del(drv);
+
        /* If this device got a regulatory hint tell core its
         * free to listen now to a new shiny device regulatory hint */
        reg_device_remove(wiphy);
@@ -411,6 +501,7 @@ EXPORT_SYMBOL(wiphy_unregister);
 void cfg80211_dev_free(struct cfg80211_registered_device *drv)
 {
        struct cfg80211_internal_bss *scan, *tmp;
+       rfkill_destroy(drv->rfkill);
        mutex_destroy(&drv->mtx);
        mutex_destroy(&drv->devlist_mtx);
        list_for_each_entry_safe(scan, tmp, &drv->bss_list, list)
@@ -424,6 +515,15 @@ void wiphy_free(struct wiphy *wiphy)
 }
 EXPORT_SYMBOL(wiphy_free);
 
+void wiphy_rfkill_set_hw_state(struct wiphy *wiphy, bool blocked)
+{
+       struct cfg80211_registered_device *drv = wiphy_to_dev(wiphy);
+
+       if (rfkill_set_hw_state(drv->rfkill, blocked))
+               schedule_work(&drv->rfkill_sync);
+}
+EXPORT_SYMBOL(wiphy_rfkill_set_hw_state);
+
 static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
                                         unsigned long state,
                                         void *ndev)
@@ -432,7 +532,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
        struct cfg80211_registered_device *rdev;
 
        if (!dev->ieee80211_ptr)
-               return 0;
+               return NOTIFY_DONE;
 
        rdev = wiphy_to_dev(dev->ieee80211_ptr->wiphy);
 
@@ -448,8 +548,28 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
                                "symlink to netdev!\n");
                }
                dev->ieee80211_ptr->netdev = dev;
+#ifdef CONFIG_WIRELESS_EXT
+               dev->ieee80211_ptr->wext.default_key = -1;
+               dev->ieee80211_ptr->wext.default_mgmt_key = -1;
+#endif
                mutex_unlock(&rdev->devlist_mtx);
                break;
+       case NETDEV_GOING_DOWN:
+               if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC)
+                       break;
+               if (!dev->ieee80211_ptr->ssid_len)
+                       break;
+               cfg80211_leave_ibss(rdev, dev, true);
+               break;
+       case NETDEV_UP:
+#ifdef CONFIG_WIRELESS_EXT
+               if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC)
+                       break;
+               if (!dev->ieee80211_ptr->wext.ibss.ssid_len)
+                       break;
+               cfg80211_join_ibss(rdev, dev, &dev->ieee80211_ptr->wext.ibss);
+               break;
+#endif
        case NETDEV_UNREGISTER:
                mutex_lock(&rdev->devlist_mtx);
                if (!list_empty(&dev->ieee80211_ptr->list)) {
@@ -458,9 +578,13 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
                }
                mutex_unlock(&rdev->devlist_mtx);
                break;
+       case NETDEV_PRE_UP:
+               if (rfkill_blocked(rdev->rfkill))
+                       return notifier_from_errno(-ERFKILL);
+               break;
        }
 
-       return 0;
+       return NOTIFY_DONE;
 }
 
 static struct notifier_block cfg80211_netdev_notifier = {
index 0a592e4295f0cbdca4a2ffbabc96dd01b4da619a..bfa340c7abb5bba577482a85986d1954cf947be1 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Wireless configuration interface internals.
  *
- * Copyright 2006, 2007 Johannes Berg <johannes@sipsolutions.net>
+ * Copyright 2006-2009 Johannes Berg <johannes@sipsolutions.net>
  */
 #ifndef __NET_WIRELESS_CORE_H
 #define __NET_WIRELESS_CORE_H
 #include <linux/netdevice.h>
 #include <linux/kref.h>
 #include <linux/rbtree.h>
-#include <linux/mutex.h>
+#include <linux/debugfs.h>
+#include <linux/rfkill.h>
+#include <linux/workqueue.h>
 #include <net/genetlink.h>
-#include <net/wireless.h>
 #include <net/cfg80211.h>
 #include "reg.h"
 
 struct cfg80211_registered_device {
-       struct cfg80211_ops *ops;
+       const struct cfg80211_ops *ops;
        struct list_head list;
        /* we hold this mutex during any call so that
         * we cannot do multiple calls at once, and also
@@ -25,6 +26,11 @@ struct cfg80211_registered_device {
         * any call is in progress */
        struct mutex mtx;
 
+       /* rfkill support */
+       struct rfkill_ops rfkill_ops;
+       struct rfkill *rfkill;
+       struct work_struct rfkill_sync;
+
        /* ISO / IEC 3166 alpha2 for which this device is receiving
         * country IEs on, this can help disregard country IEs from APs
         * on the same alpha2 quickly. The alpha2 may differ from
@@ -52,6 +58,17 @@ struct cfg80211_registered_device {
        struct cfg80211_scan_request *scan_req; /* protected by RTNL */
        unsigned long suspend_at;
 
+#ifdef CONFIG_CFG80211_DEBUGFS
+       /* Debugfs entries */
+       struct wiphy_debugfsdentries {
+               struct dentry *rts_threshold;
+               struct dentry *fragmentation_threshold;
+               struct dentry *short_retry_limit;
+               struct dentry *long_retry_limit;
+               struct dentry *ht40allow_map;
+       } debugfs;
+#endif
+
        /* must be last because of the way we do wiphy_priv(),
         * and it should at least be aligned to NETDEV_ALIGN */
        struct wiphy wiphy __attribute__((__aligned__(NETDEV_ALIGN)));
@@ -74,10 +91,7 @@ bool wiphy_idx_valid(int wiphy_idx)
 extern struct mutex cfg80211_mutex;
 extern struct list_head cfg80211_drv_list;
 
-static inline void assert_cfg80211_lock(void)
-{
-       WARN_ON(!mutex_is_locked(&cfg80211_mutex));
-}
+#define assert_cfg80211_lock() WARN_ON(!mutex_is_locked(&cfg80211_mutex))
 
 /*
  * You can use this to mark a wiphy_idx as not having an associated wiphy.
@@ -148,4 +162,16 @@ void cfg80211_bss_expire(struct cfg80211_registered_device *dev);
 void cfg80211_bss_age(struct cfg80211_registered_device *dev,
                       unsigned long age_secs);
 
+/* IBSS */
+int cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
+                      struct net_device *dev,
+                      struct cfg80211_ibss_params *params);
+void cfg80211_clear_ibss(struct net_device *dev, bool nowext);
+int cfg80211_leave_ibss(struct cfg80211_registered_device *rdev,
+                       struct net_device *dev, bool nowext);
+
+/* internal helpers */
+int cfg80211_validate_key_settings(struct key_params *params, int key_idx,
+                                  const u8 *mac_addr);
+
 #endif /* __NET_WIRELESS_CORE_H */
diff --git a/net/wireless/debugfs.c b/net/wireless/debugfs.c
new file mode 100644 (file)
index 0000000..679ddfc
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * cfg80211 debugfs
+ *
+ * Copyright 2009      Luis R. Rodriguez <lrodriguez@atheros.com>
+ * Copyright 2007      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 "core.h"
+#include "debugfs.h"
+
+static int cfg80211_open_file_generic(struct inode *inode, struct file *file)
+{
+       file->private_data = inode->i_private;
+       return 0;
+}
+
+#define DEBUGFS_READONLY_FILE(name, buflen, fmt, value...)             \
+static ssize_t name## _read(struct file *file, char __user *userbuf,   \
+                           size_t count, loff_t *ppos)                 \
+{                                                                      \
+       struct wiphy *wiphy= file->private_data;                \
+       char buf[buflen];                                               \
+       int res;                                                        \
+                                                                       \
+       res = scnprintf(buf, buflen, fmt "\n", ##value);                \
+       return simple_read_from_buffer(userbuf, count, ppos, buf, res); \
+}                                                                      \
+                                                                       \
+static const struct file_operations name## _ops = {                    \
+       .read = name## _read,                                           \
+       .open = cfg80211_open_file_generic,                             \
+};
+
+DEBUGFS_READONLY_FILE(rts_threshold, 20, "%d",
+                     wiphy->rts_threshold)
+DEBUGFS_READONLY_FILE(fragmentation_threshold, 20, "%d",
+                     wiphy->frag_threshold);
+DEBUGFS_READONLY_FILE(short_retry_limit, 20, "%d",
+                     wiphy->retry_short)
+DEBUGFS_READONLY_FILE(long_retry_limit, 20, "%d",
+                     wiphy->retry_long);
+
+static int ht_print_chan(struct ieee80211_channel *chan,
+                        char *buf, int buf_size, int offset)
+{
+       if (WARN_ON(offset > buf_size))
+               return 0;
+
+       if (chan->flags & IEEE80211_CHAN_DISABLED)
+               return snprintf(buf + offset,
+                               buf_size - offset,
+                               "%d Disabled\n",
+                               chan->center_freq);
+
+       return snprintf(buf + offset,
+                       buf_size - offset,
+                       "%d HT40 %c%c\n",
+                       chan->center_freq,
+                       (chan->flags & IEEE80211_CHAN_NO_HT40MINUS) ? ' ' : '-',
+                       (chan->flags & IEEE80211_CHAN_NO_HT40PLUS)  ? ' ' : '+');
+}
+
+static ssize_t ht40allow_map_read(struct file *file,
+                                 char __user *user_buf,
+                                 size_t count, loff_t *ppos)
+{
+       struct wiphy *wiphy = file->private_data;
+       char *buf;
+       unsigned int offset = 0, buf_size = PAGE_SIZE, i, r;
+       enum ieee80211_band band;
+       struct ieee80211_supported_band *sband;
+
+       buf = kzalloc(buf_size, GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
+
+       mutex_lock(&cfg80211_mutex);
+
+       for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
+               sband = wiphy->bands[band];
+               if (!sband)
+                       continue;
+               for (i = 0; i < sband->n_channels; i++)
+                       offset += ht_print_chan(&sband->channels[i],
+                                               buf, buf_size, offset);
+       }
+
+       mutex_unlock(&cfg80211_mutex);
+
+       r = simple_read_from_buffer(user_buf, count, ppos, buf, offset);
+
+       kfree(buf);
+
+       return r;
+}
+
+static const struct file_operations ht40allow_map_ops = {
+       .read = ht40allow_map_read,
+       .open = cfg80211_open_file_generic,
+};
+
+#define DEBUGFS_ADD(name)                                              \
+       drv->debugfs.name = debugfs_create_file(#name, S_IRUGO, phyd,   \
+                                                 &drv->wiphy, &name## _ops);
+#define DEBUGFS_DEL(name)                                              \
+       debugfs_remove(drv->debugfs.name);                              \
+       drv->debugfs.name = NULL;
+
+void cfg80211_debugfs_drv_add(struct cfg80211_registered_device *drv)
+{
+       struct dentry *phyd = drv->wiphy.debugfsdir;
+
+       DEBUGFS_ADD(rts_threshold);
+       DEBUGFS_ADD(fragmentation_threshold);
+       DEBUGFS_ADD(short_retry_limit);
+       DEBUGFS_ADD(long_retry_limit);
+       DEBUGFS_ADD(ht40allow_map);
+}
+
+void cfg80211_debugfs_drv_del(struct cfg80211_registered_device *drv)
+{
+       DEBUGFS_DEL(rts_threshold);
+       DEBUGFS_DEL(fragmentation_threshold);
+       DEBUGFS_DEL(short_retry_limit);
+       DEBUGFS_DEL(long_retry_limit);
+       DEBUGFS_DEL(ht40allow_map);
+}
diff --git a/net/wireless/debugfs.h b/net/wireless/debugfs.h
new file mode 100644 (file)
index 0000000..c226983
--- /dev/null
@@ -0,0 +1,14 @@
+#ifndef __CFG80211_DEBUGFS_H
+#define __CFG80211_DEBUGFS_H
+
+#ifdef CONFIG_CFG80211_DEBUGFS
+void cfg80211_debugfs_drv_add(struct cfg80211_registered_device *drv);
+void cfg80211_debugfs_drv_del(struct cfg80211_registered_device *drv);
+#else
+static inline
+void cfg80211_debugfs_drv_add(struct cfg80211_registered_device *drv) {}
+static inline
+void cfg80211_debugfs_drv_del(struct cfg80211_registered_device *drv) {}
+#endif
+
+#endif /* __CFG80211_DEBUGFS_H */
diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c
new file mode 100644 (file)
index 0000000..a4a1c34
--- /dev/null
@@ -0,0 +1,369 @@
+/*
+ * Some IBSS support code for cfg80211.
+ *
+ * Copyright 2009      Johannes Berg <johannes@sipsolutions.net>
+ */
+
+#include <linux/etherdevice.h>
+#include <linux/if_arp.h>
+#include <net/cfg80211.h>
+#include "nl80211.h"
+
+
+void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, gfp_t gfp)
+{
+       struct wireless_dev *wdev = dev->ieee80211_ptr;
+       struct cfg80211_bss *bss;
+#ifdef CONFIG_WIRELESS_EXT
+       union iwreq_data wrqu;
+#endif
+
+       if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
+               return;
+
+       if (WARN_ON(!wdev->ssid_len))
+               return;
+
+       if (memcmp(bssid, wdev->bssid, ETH_ALEN) == 0)
+               return;
+
+       bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid,
+                              wdev->ssid, wdev->ssid_len,
+                              WLAN_CAPABILITY_IBSS, WLAN_CAPABILITY_IBSS);
+
+       if (WARN_ON(!bss))
+               return;
+
+       if (wdev->current_bss) {
+               cfg80211_unhold_bss(wdev->current_bss);
+               cfg80211_put_bss(wdev->current_bss);
+       }
+
+       cfg80211_hold_bss(bss);
+       wdev->current_bss = bss;
+       memcpy(wdev->bssid, bssid, ETH_ALEN);
+
+       nl80211_send_ibss_bssid(wiphy_to_dev(wdev->wiphy), dev, bssid, gfp);
+#ifdef CONFIG_WIRELESS_EXT
+       memset(&wrqu, 0, sizeof(wrqu));
+       memcpy(wrqu.ap_addr.sa_data, bssid, ETH_ALEN);
+       wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
+#endif
+}
+EXPORT_SYMBOL(cfg80211_ibss_joined);
+
+int cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
+                      struct net_device *dev,
+                      struct cfg80211_ibss_params *params)
+{
+       struct wireless_dev *wdev = dev->ieee80211_ptr;
+       int err;
+
+       if (wdev->ssid_len)
+               return -EALREADY;
+
+#ifdef CONFIG_WIRELESS_EXT
+       wdev->wext.ibss.channel = params->channel;
+#endif
+       err = rdev->ops->join_ibss(&rdev->wiphy, dev, params);
+
+       if (err)
+               return err;
+
+       memcpy(wdev->ssid, params->ssid, params->ssid_len);
+       wdev->ssid_len = params->ssid_len;
+
+       return 0;
+}
+
+void cfg80211_clear_ibss(struct net_device *dev, bool nowext)
+{
+       struct wireless_dev *wdev = dev->ieee80211_ptr;
+
+       if (wdev->current_bss) {
+               cfg80211_unhold_bss(wdev->current_bss);
+               cfg80211_put_bss(wdev->current_bss);
+       }
+
+       wdev->current_bss = NULL;
+       wdev->ssid_len = 0;
+       memset(wdev->bssid, 0, ETH_ALEN);
+#ifdef CONFIG_WIRELESS_EXT
+       if (!nowext)
+               wdev->wext.ibss.ssid_len = 0;
+#endif
+}
+
+int cfg80211_leave_ibss(struct cfg80211_registered_device *rdev,
+                       struct net_device *dev, bool nowext)
+{
+       int err;
+
+       err = rdev->ops->leave_ibss(&rdev->wiphy, dev);
+
+       if (err)
+               return err;
+
+       cfg80211_clear_ibss(dev, nowext);
+
+       return 0;
+}
+
+#ifdef CONFIG_WIRELESS_EXT
+static int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev,
+                                  struct wireless_dev *wdev)
+{
+       enum ieee80211_band band;
+       int i;
+
+       if (!wdev->wext.ibss.beacon_interval)
+               wdev->wext.ibss.beacon_interval = 100;
+
+       /* try to find an IBSS channel if none requested ... */
+       if (!wdev->wext.ibss.channel) {
+               for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
+                       struct ieee80211_supported_band *sband;
+                       struct ieee80211_channel *chan;
+
+                       sband = rdev->wiphy.bands[band];
+                       if (!sband)
+                               continue;
+
+                       for (i = 0; i < sband->n_channels; i++) {
+                               chan = &sband->channels[i];
+                               if (chan->flags & IEEE80211_CHAN_NO_IBSS)
+                                       continue;
+                               if (chan->flags & IEEE80211_CHAN_DISABLED)
+                                       continue;
+                               wdev->wext.ibss.channel = chan;
+                               break;
+                       }
+
+                       if (wdev->wext.ibss.channel)
+                               break;
+               }
+
+               if (!wdev->wext.ibss.channel)
+                       return -EINVAL;
+       }
+
+       /* don't join -- SSID is not there */
+       if (!wdev->wext.ibss.ssid_len)
+               return 0;
+
+       if (!netif_running(wdev->netdev))
+               return 0;
+
+       return cfg80211_join_ibss(wiphy_to_dev(wdev->wiphy),
+                                 wdev->netdev, &wdev->wext.ibss);
+}
+
+int cfg80211_ibss_wext_siwfreq(struct net_device *dev,
+                              struct iw_request_info *info,
+                              struct iw_freq *freq, char *extra)
+{
+       struct wireless_dev *wdev = dev->ieee80211_ptr;
+       struct ieee80211_channel *chan;
+       int err;
+
+       /* call only for ibss! */
+       if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
+               return -EINVAL;
+
+       if (!wiphy_to_dev(wdev->wiphy)->ops->join_ibss)
+               return -EOPNOTSUPP;
+
+       chan = cfg80211_wext_freq(wdev->wiphy, freq);
+       if (chan && IS_ERR(chan))
+               return PTR_ERR(chan);
+
+       if (chan &&
+           (chan->flags & IEEE80211_CHAN_NO_IBSS ||
+            chan->flags & IEEE80211_CHAN_DISABLED))
+               return -EINVAL;
+
+       if (wdev->wext.ibss.channel == chan)
+               return 0;
+
+       if (wdev->ssid_len) {
+               err = cfg80211_leave_ibss(wiphy_to_dev(wdev->wiphy),
+                                         dev, true);
+               if (err)
+                       return err;
+       }
+
+       if (chan) {
+               wdev->wext.ibss.channel = chan;
+               wdev->wext.ibss.channel_fixed = true;
+       } else {
+               /* cfg80211_ibss_wext_join will pick one if needed */
+               wdev->wext.ibss.channel_fixed = false;
+       }
+
+       return cfg80211_ibss_wext_join(wiphy_to_dev(wdev->wiphy), wdev);
+}
+/* temporary symbol - mark GPL - in the future the handler won't be */
+EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_siwfreq);
+
+int cfg80211_ibss_wext_giwfreq(struct net_device *dev,
+                              struct iw_request_info *info,
+                              struct iw_freq *freq, char *extra)
+{
+       struct wireless_dev *wdev = dev->ieee80211_ptr;
+       struct ieee80211_channel *chan = NULL;
+
+       /* call only for ibss! */
+       if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
+               return -EINVAL;
+
+       if (wdev->current_bss)
+               chan = wdev->current_bss->channel;
+       else if (wdev->wext.ibss.channel)
+               chan = wdev->wext.ibss.channel;
+
+       if (chan) {
+               freq->m = chan->center_freq;
+               freq->e = 6;
+               return 0;
+       }
+
+       /* no channel if not joining */
+       return -EINVAL;
+}
+/* temporary symbol - mark GPL - in the future the handler won't be */
+EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_giwfreq);
+
+int cfg80211_ibss_wext_siwessid(struct net_device *dev,
+                               struct iw_request_info *info,
+                               struct iw_point *data, char *ssid)
+{
+       struct wireless_dev *wdev = dev->ieee80211_ptr;
+       size_t len = data->length;
+       int err;
+
+       /* call only for ibss! */
+       if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
+               return -EINVAL;
+
+       if (!wiphy_to_dev(wdev->wiphy)->ops->join_ibss)
+               return -EOPNOTSUPP;
+
+       if (wdev->ssid_len) {
+               err = cfg80211_leave_ibss(wiphy_to_dev(wdev->wiphy),
+                                         dev, true);
+               if (err)
+                       return err;
+       }
+
+       /* iwconfig uses nul termination in SSID.. */
+       if (len > 0 && ssid[len - 1] == '\0')
+               len--;
+
+       wdev->wext.ibss.ssid = wdev->ssid;
+       memcpy(wdev->wext.ibss.ssid, ssid, len);
+       wdev->wext.ibss.ssid_len = len;
+
+       return cfg80211_ibss_wext_join(wiphy_to_dev(wdev->wiphy), wdev);
+}
+/* temporary symbol - mark GPL - in the future the handler won't be */
+EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_siwessid);
+
+int cfg80211_ibss_wext_giwessid(struct net_device *dev,
+                               struct iw_request_info *info,
+                               struct iw_point *data, char *ssid)
+{
+       struct wireless_dev *wdev = dev->ieee80211_ptr;
+
+       /* call only for ibss! */
+       if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
+               return -EINVAL;
+
+       data->flags = 0;
+
+       if (wdev->ssid_len) {
+               data->flags = 1;
+               data->length = wdev->ssid_len;
+               memcpy(ssid, wdev->ssid, data->length);
+       } else if (wdev->wext.ibss.ssid && wdev->wext.ibss.ssid_len) {
+               data->flags = 1;
+               data->length = wdev->wext.ibss.ssid_len;
+               memcpy(ssid, wdev->wext.ibss.ssid, data->length);
+       }
+
+       return 0;
+}
+/* temporary symbol - mark GPL - in the future the handler won't be */
+EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_giwessid);
+
+int cfg80211_ibss_wext_siwap(struct net_device *dev,
+                            struct iw_request_info *info,
+                            struct sockaddr *ap_addr, char *extra)
+{
+       struct wireless_dev *wdev = dev->ieee80211_ptr;
+       u8 *bssid = ap_addr->sa_data;
+       int err;
+
+       /* call only for ibss! */
+       if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
+               return -EINVAL;
+
+       if (!wiphy_to_dev(wdev->wiphy)->ops->join_ibss)
+               return -EOPNOTSUPP;
+
+       if (ap_addr->sa_family != ARPHRD_ETHER)
+               return -EINVAL;
+
+       /* automatic mode */
+       if (is_zero_ether_addr(bssid) || is_broadcast_ether_addr(bssid))
+               bssid = NULL;
+
+       /* both automatic */
+       if (!bssid && !wdev->wext.ibss.bssid)
+               return 0;
+
+       /* fixed already - and no change */
+       if (wdev->wext.ibss.bssid && bssid &&
+           compare_ether_addr(bssid, wdev->wext.ibss.bssid) == 0)
+               return 0;
+
+       if (wdev->ssid_len) {
+               err = cfg80211_leave_ibss(wiphy_to_dev(wdev->wiphy),
+                                         dev, true);
+               if (err)
+                       return err;
+       }
+
+       if (bssid) {
+               memcpy(wdev->wext.bssid, bssid, ETH_ALEN);
+               wdev->wext.ibss.bssid = wdev->wext.bssid;
+       } else
+               wdev->wext.ibss.bssid = NULL;
+
+       return cfg80211_ibss_wext_join(wiphy_to_dev(wdev->wiphy), wdev);
+}
+/* temporary symbol - mark GPL - in the future the handler won't be */
+EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_siwap);
+
+int cfg80211_ibss_wext_giwap(struct net_device *dev,
+                            struct iw_request_info *info,
+                            struct sockaddr *ap_addr, char *extra)
+{
+       struct wireless_dev *wdev = dev->ieee80211_ptr;
+
+       /* call only for ibss! */
+       if (WARN_ON(wdev->iftype != NL80211_IFTYPE_ADHOC))
+               return -EINVAL;
+
+       ap_addr->sa_family = ARPHRD_ETHER;
+
+       if (wdev->wext.ibss.bssid) {
+               memcpy(ap_addr->sa_data, wdev->wext.ibss.bssid, ETH_ALEN);
+               return 0;
+       }
+
+       memcpy(ap_addr->sa_data, wdev->bssid, ETH_ALEN);
+       return 0;
+}
+/* temporary symbol - mark GPL - in the future the handler won't be */
+EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_giwap);
+#endif
index bec5721b6f99ea351005991c72a6403635b1b763..42184361a1099745dc17b0aedd8ebc6d2217bd97 100644 (file)
@@ -28,19 +28,55 @@ void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len)
 }
 EXPORT_SYMBOL(cfg80211_send_rx_assoc);
 
-void cfg80211_send_rx_deauth(struct net_device *dev, const u8 *buf, size_t len)
+void cfg80211_send_deauth(struct net_device *dev, const u8 *buf, size_t len)
 {
        struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
        struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
-       nl80211_send_rx_deauth(rdev, dev, buf, len);
+       nl80211_send_deauth(rdev, dev, buf, len);
 }
-EXPORT_SYMBOL(cfg80211_send_rx_deauth);
+EXPORT_SYMBOL(cfg80211_send_deauth);
 
-void cfg80211_send_rx_disassoc(struct net_device *dev, const u8 *buf,
-                              size_t len)
+void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len)
 {
        struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
        struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
-       nl80211_send_rx_disassoc(rdev, dev, buf, len);
+       nl80211_send_disassoc(rdev, dev, buf, len);
 }
-EXPORT_SYMBOL(cfg80211_send_rx_disassoc);
+EXPORT_SYMBOL(cfg80211_send_disassoc);
+
+static void cfg80211_wext_disconnected(struct net_device *dev)
+{
+#ifdef CONFIG_WIRELESS_EXT
+       union iwreq_data wrqu;
+       memset(&wrqu, 0, sizeof(wrqu));
+       wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
+#endif
+}
+
+void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr)
+{
+       struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
+       struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
+       nl80211_send_auth_timeout(rdev, dev, addr);
+       cfg80211_wext_disconnected(dev);
+}
+EXPORT_SYMBOL(cfg80211_send_auth_timeout);
+
+void cfg80211_send_assoc_timeout(struct net_device *dev, const u8 *addr)
+{
+       struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
+       struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
+       nl80211_send_assoc_timeout(rdev, dev, addr);
+       cfg80211_wext_disconnected(dev);
+}
+EXPORT_SYMBOL(cfg80211_send_assoc_timeout);
+
+void cfg80211_michael_mic_failure(struct net_device *dev, const u8 *addr,
+                                 enum nl80211_key_type key_type, int key_id,
+                                 const u8 *tsc)
+{
+       struct wiphy *wiphy = dev->ieee80211_ptr->wiphy;
+       struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
+       nl80211_michael_mic_failure(rdev, dev, addr, key_type, key_id, tsc);
+}
+EXPORT_SYMBOL(cfg80211_michael_mic_failure);
index 2456e4ee445e04ab884fa17a2fb8ed835ab59996..24168560ebaeed9a50b80242b29d6f4a49acba84 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This is the new netlink-based wireless configuration interface.
  *
- * Copyright 2006, 2007        Johannes Berg <johannes@sipsolutions.net>
+ * Copyright 2006-2009 Johannes Berg <johannes@sipsolutions.net>
  */
 
 #include <linux/if.h>
@@ -57,10 +57,14 @@ static int get_drv_dev_by_info_ifindex(struct nlattr **attrs,
 static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = {
        [NL80211_ATTR_WIPHY] = { .type = NLA_U32 },
        [NL80211_ATTR_WIPHY_NAME] = { .type = NLA_NUL_STRING,
-                                     .len = BUS_ID_SIZE-1 },
+                                     .len = 20-1 },
        [NL80211_ATTR_WIPHY_TXQ_PARAMS] = { .type = NLA_NESTED },
        [NL80211_ATTR_WIPHY_FREQ] = { .type = NLA_U32 },
        [NL80211_ATTR_WIPHY_CHANNEL_TYPE] = { .type = NLA_U32 },
+       [NL80211_ATTR_WIPHY_RETRY_SHORT] = { .type = NLA_U8 },
+       [NL80211_ATTR_WIPHY_RETRY_LONG] = { .type = NLA_U8 },
+       [NL80211_ATTR_WIPHY_FRAG_THRESHOLD] = { .type = NLA_U32 },
+       [NL80211_ATTR_WIPHY_RTS_THRESHOLD] = { .type = NLA_U32 },
 
        [NL80211_ATTR_IFTYPE] = { .type = NLA_U32 },
        [NL80211_ATTR_IFINDEX] = { .type = NLA_U32 },
@@ -73,6 +77,7 @@ static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = {
        [NL80211_ATTR_KEY_IDX] = { .type = NLA_U8 },
        [NL80211_ATTR_KEY_CIPHER] = { .type = NLA_U32 },
        [NL80211_ATTR_KEY_DEFAULT] = { .type = NLA_FLAG },
+       [NL80211_ATTR_KEY_SEQ] = { .type = NLA_BINARY, .len = 8 },
 
        [NL80211_ATTR_BEACON_INTERVAL] = { .type = NLA_U32 },
        [NL80211_ATTR_DTIM_PERIOD] = { .type = NLA_U32 },
@@ -116,8 +121,45 @@ static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = {
                                .len = IEEE80211_MAX_SSID_LEN },
        [NL80211_ATTR_AUTH_TYPE] = { .type = NLA_U32 },
        [NL80211_ATTR_REASON_CODE] = { .type = NLA_U16 },
+       [NL80211_ATTR_FREQ_FIXED] = { .type = NLA_FLAG },
+       [NL80211_ATTR_TIMED_OUT] = { .type = NLA_FLAG },
+       [NL80211_ATTR_USE_MFP] = { .type = NLA_U32 },
+       [NL80211_ATTR_STA_FLAGS2] = {
+               .len = sizeof(struct nl80211_sta_flag_update),
+       },
+       [NL80211_ATTR_CONTROL_PORT] = { .type = NLA_FLAG },
 };
 
+/* IE validation */
+static bool is_valid_ie_attr(const struct nlattr *attr)
+{
+       const u8 *pos;
+       int len;
+
+       if (!attr)
+               return true;
+
+       pos = nla_data(attr);
+       len = nla_len(attr);
+
+       while (len) {
+               u8 elemlen;
+
+               if (len < 2)
+                       return false;
+               len -= 2;
+
+               elemlen = pos[1];
+               if (elemlen > len)
+                       return false;
+
+               len -= elemlen;
+               pos += 2 + elemlen;
+       }
+
+       return true;
+}
+
 /* message building helper */
 static inline void *nl80211hdr_put(struct sk_buff *skb, u32 pid, u32 seq,
                                   int flags, u8 cmd)
@@ -126,6 +168,30 @@ static inline void *nl80211hdr_put(struct sk_buff *skb, u32 pid, u32 seq,
        return genlmsg_put(skb, pid, seq, &nl80211_fam, flags, cmd);
 }
 
+static int nl80211_msg_put_channel(struct sk_buff *msg,
+                                  struct ieee80211_channel *chan)
+{
+       NLA_PUT_U32(msg, NL80211_FREQUENCY_ATTR_FREQ,
+                   chan->center_freq);
+
+       if (chan->flags & IEEE80211_CHAN_DISABLED)
+               NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_DISABLED);
+       if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN)
+               NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_PASSIVE_SCAN);
+       if (chan->flags & IEEE80211_CHAN_NO_IBSS)
+               NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_NO_IBSS);
+       if (chan->flags & IEEE80211_CHAN_RADAR)
+               NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_RADAR);
+
+       NLA_PUT_U32(msg, NL80211_FREQUENCY_ATTR_MAX_TX_POWER,
+                   DBM_TO_MBM(chan->max_power));
+
+       return 0;
+
+ nla_put_failure:
+       return -ENOBUFS;
+}
+
 /* netlink command implementations */
 
 static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
@@ -149,8 +215,24 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
 
        NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, dev->wiphy_idx);
        NLA_PUT_STRING(msg, NL80211_ATTR_WIPHY_NAME, wiphy_name(&dev->wiphy));
+
+       NLA_PUT_U8(msg, NL80211_ATTR_WIPHY_RETRY_SHORT,
+                  dev->wiphy.retry_short);
+       NLA_PUT_U8(msg, NL80211_ATTR_WIPHY_RETRY_LONG,
+                  dev->wiphy.retry_long);
+       NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FRAG_THRESHOLD,
+                   dev->wiphy.frag_threshold);
+       NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD,
+                   dev->wiphy.rts_threshold);
+
        NLA_PUT_U8(msg, NL80211_ATTR_MAX_NUM_SCAN_SSIDS,
                   dev->wiphy.max_scan_ssids);
+       NLA_PUT_U16(msg, NL80211_ATTR_MAX_SCAN_IE_LEN,
+                   dev->wiphy.max_scan_ie_len);
+
+       NLA_PUT(msg, NL80211_ATTR_CIPHER_SUITES,
+               sizeof(u32) * dev->wiphy.n_cipher_suites,
+               dev->wiphy.cipher_suites);
 
        nl_modes = nla_nest_start(msg, NL80211_ATTR_SUPPORTED_IFTYPES);
        if (!nl_modes)
@@ -202,20 +284,9 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
                                goto nla_put_failure;
 
                        chan = &dev->wiphy.bands[band]->channels[i];
-                       NLA_PUT_U32(msg, NL80211_FREQUENCY_ATTR_FREQ,
-                                   chan->center_freq);
-
-                       if (chan->flags & IEEE80211_CHAN_DISABLED)
-                               NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_DISABLED);
-                       if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN)
-                               NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_PASSIVE_SCAN);
-                       if (chan->flags & IEEE80211_CHAN_NO_IBSS)
-                               NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_NO_IBSS);
-                       if (chan->flags & IEEE80211_CHAN_RADAR)
-                               NLA_PUT_FLAG(msg, NL80211_FREQUENCY_ATTR_RADAR);
 
-                       NLA_PUT_U32(msg, NL80211_FREQUENCY_ATTR_MAX_TX_POWER,
-                                   DBM_TO_MBM(chan->max_power));
+                       if (nl80211_msg_put_channel(msg, chan))
+                               goto nla_put_failure;
 
                        nla_nest_end(msg, nl_freq);
                }
@@ -273,6 +344,7 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
        CMD(assoc, ASSOCIATE);
        CMD(deauth, DEAUTHENTICATE);
        CMD(disassoc, DISASSOCIATE);
+       CMD(join_ibss, JOIN_IBSS);
 
 #undef CMD
        nla_nest_end(msg, nl_cmds);
@@ -317,7 +389,7 @@ static int nl80211_get_wiphy(struct sk_buff *skb, struct genl_info *info)
        if (IS_ERR(dev))
                return PTR_ERR(dev);
 
-       msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
+       msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
        if (!msg)
                goto out_err;
 
@@ -365,6 +437,9 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
        struct cfg80211_registered_device *rdev;
        int result = 0, rem_txq_params = 0;
        struct nlattr *nl_txq_params;
+       u32 changed;
+       u8 retry_short = 0, retry_long = 0;
+       u32 frag_threshold = 0, rts_threshold = 0;
 
        rtnl_lock();
 
@@ -418,7 +493,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
                enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
                struct ieee80211_channel *chan;
                struct ieee80211_sta_ht_cap *ht_cap;
-               u32 freq, sec_freq;
+               u32 freq;
 
                if (!rdev->ops->set_channel) {
                        result = -EOPNOTSUPP;
@@ -444,33 +519,28 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
                if (!chan || chan->flags & IEEE80211_CHAN_DISABLED)
                        goto bad_res;
 
-               if (channel_type == NL80211_CHAN_HT40MINUS)
-                       sec_freq = freq - 20;
-               else if (channel_type == NL80211_CHAN_HT40PLUS)
-                       sec_freq = freq + 20;
-               else
-                       sec_freq = 0;
-
-               ht_cap = &rdev->wiphy.bands[chan->band]->ht_cap;
-
-               /* no HT capabilities */
-               if (channel_type != NL80211_CHAN_NO_HT &&
-                   !ht_cap->ht_supported)
+               if (channel_type == NL80211_CHAN_HT40MINUS &&
+                   (chan->flags & IEEE80211_CHAN_NO_HT40MINUS))
+                       goto bad_res;
+               else if (channel_type == NL80211_CHAN_HT40PLUS &&
+                        (chan->flags & IEEE80211_CHAN_NO_HT40PLUS))
                        goto bad_res;
 
-               if (sec_freq) {
-                       struct ieee80211_channel *schan;
+               /*
+                * At this point we know if that if HT40 was requested
+                * we are allowed to use it and the extension channel
+                * exists.
+                */
 
-                       /* no 40 MHz capabilities */
+               ht_cap = &rdev->wiphy.bands[chan->band]->ht_cap;
+
+               /* no HT capabilities or intolerant */
+               if (channel_type != NL80211_CHAN_NO_HT) {
+                       if (!ht_cap->ht_supported)
+                               goto bad_res;
                        if (!(ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) ||
                            (ht_cap->cap & IEEE80211_HT_CAP_40MHZ_INTOLERANT))
                                goto bad_res;
-
-                       schan = ieee80211_get_channel(&rdev->wiphy, sec_freq);
-
-                       /* Secondary channel not allowed */
-                       if (!schan || schan->flags & IEEE80211_CHAN_DISABLED)
-                               goto bad_res;
                }
 
                result = rdev->ops->set_channel(&rdev->wiphy, chan,
@@ -479,6 +549,84 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
                        goto bad_res;
        }
 
+       changed = 0;
+
+       if (info->attrs[NL80211_ATTR_WIPHY_RETRY_SHORT]) {
+               retry_short = nla_get_u8(
+                       info->attrs[NL80211_ATTR_WIPHY_RETRY_SHORT]);
+               if (retry_short == 0) {
+                       result = -EINVAL;
+                       goto bad_res;
+               }
+               changed |= WIPHY_PARAM_RETRY_SHORT;
+       }
+
+       if (info->attrs[NL80211_ATTR_WIPHY_RETRY_LONG]) {
+               retry_long = nla_get_u8(
+                       info->attrs[NL80211_ATTR_WIPHY_RETRY_LONG]);
+               if (retry_long == 0) {
+                       result = -EINVAL;
+                       goto bad_res;
+               }
+               changed |= WIPHY_PARAM_RETRY_LONG;
+       }
+
+       if (info->attrs[NL80211_ATTR_WIPHY_FRAG_THRESHOLD]) {
+               frag_threshold = nla_get_u32(
+                       info->attrs[NL80211_ATTR_WIPHY_FRAG_THRESHOLD]);
+               if (frag_threshold < 256) {
+                       result = -EINVAL;
+                       goto bad_res;
+               }
+               if (frag_threshold != (u32) -1) {
+                       /*
+                        * Fragments (apart from the last one) are required to
+                        * have even length. Make the fragmentation code
+                        * simpler by stripping LSB should someone try to use
+                        * odd threshold value.
+                        */
+                       frag_threshold &= ~0x1;
+               }
+               changed |= WIPHY_PARAM_FRAG_THRESHOLD;
+       }
+
+       if (info->attrs[NL80211_ATTR_WIPHY_RTS_THRESHOLD]) {
+               rts_threshold = nla_get_u32(
+                       info->attrs[NL80211_ATTR_WIPHY_RTS_THRESHOLD]);
+               changed |= WIPHY_PARAM_RTS_THRESHOLD;
+       }
+
+       if (changed) {
+               u8 old_retry_short, old_retry_long;
+               u32 old_frag_threshold, old_rts_threshold;
+
+               if (!rdev->ops->set_wiphy_params) {
+                       result = -EOPNOTSUPP;
+                       goto bad_res;
+               }
+
+               old_retry_short = rdev->wiphy.retry_short;
+               old_retry_long = rdev->wiphy.retry_long;
+               old_frag_threshold = rdev->wiphy.frag_threshold;
+               old_rts_threshold = rdev->wiphy.rts_threshold;
+
+               if (changed & WIPHY_PARAM_RETRY_SHORT)
+                       rdev->wiphy.retry_short = retry_short;
+               if (changed & WIPHY_PARAM_RETRY_LONG)
+                       rdev->wiphy.retry_long = retry_long;
+               if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
+                       rdev->wiphy.frag_threshold = frag_threshold;
+               if (changed & WIPHY_PARAM_RTS_THRESHOLD)
+                       rdev->wiphy.rts_threshold = rts_threshold;
+
+               result = rdev->ops->set_wiphy_params(&rdev->wiphy, changed);
+               if (result) {
+                       rdev->wiphy.retry_short = old_retry_short;
+                       rdev->wiphy.retry_long = old_retry_long;
+                       rdev->wiphy.frag_threshold = old_frag_threshold;
+                       rdev->wiphy.rts_threshold = old_rts_threshold;
+               }
+       }
 
  bad_res:
        mutex_unlock(&rdev->mtx);
@@ -489,6 +637,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
 
 
 static int nl80211_send_iface(struct sk_buff *msg, u32 pid, u32 seq, int flags,
+                             struct cfg80211_registered_device *rdev,
                              struct net_device *dev)
 {
        void *hdr;
@@ -498,6 +647,7 @@ static int nl80211_send_iface(struct sk_buff *msg, u32 pid, u32 seq, int flags,
                return -1;
 
        NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
+       NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
        NLA_PUT_STRING(msg, NL80211_ATTR_IFNAME, dev->name);
        NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, dev->ieee80211_ptr->iftype);
        return genlmsg_end(msg, hdr);
@@ -532,7 +682,7 @@ static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *
                        }
                        if (nl80211_send_iface(skb, NETLINK_CB(cb->skb).pid,
                                               cb->nlh->nlmsg_seq, NLM_F_MULTI,
-                                              wdev->netdev) < 0) {
+                                              dev, wdev->netdev) < 0) {
                                mutex_unlock(&dev->devlist_mtx);
                                goto out;
                        }
@@ -562,11 +712,12 @@ static int nl80211_get_interface(struct sk_buff *skb, struct genl_info *info)
        if (err)
                return err;
 
-       msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
+       msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
        if (!msg)
                goto out_err;
 
-       if (nl80211_send_iface(msg, info->snd_pid, info->snd_seq, 0, netdev) < 0)
+       if (nl80211_send_iface(msg, info->snd_pid, info->snd_seq, 0,
+                              dev, netdev) < 0)
                goto out_free;
 
        dev_put(netdev);
@@ -616,7 +767,7 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
        struct cfg80211_registered_device *drv;
        struct vif_params params;
        int err, ifindex;
-       enum nl80211_iftype type;
+       enum nl80211_iftype otype, ntype;
        struct net_device *dev;
        u32 _flags, *flags = NULL;
        bool change = false;
@@ -630,30 +781,27 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
                goto unlock_rtnl;
 
        ifindex = dev->ifindex;
-       type = dev->ieee80211_ptr->iftype;
+       otype = ntype = dev->ieee80211_ptr->iftype;
        dev_put(dev);
 
        if (info->attrs[NL80211_ATTR_IFTYPE]) {
-               enum nl80211_iftype ntype;
-
                ntype = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]);
-               if (type != ntype)
+               if (otype != ntype)
                        change = true;
-               type = ntype;
-               if (type > NL80211_IFTYPE_MAX) {
+               if (ntype > NL80211_IFTYPE_MAX) {
                        err = -EINVAL;
                        goto unlock;
                }
        }
 
        if (!drv->ops->change_virtual_intf ||
-           !(drv->wiphy.interface_modes & (1 << type))) {
+           !(drv->wiphy.interface_modes & (1 << ntype))) {
                err = -EOPNOTSUPP;
                goto unlock;
        }
 
        if (info->attrs[NL80211_ATTR_MESH_ID]) {
-               if (type != NL80211_IFTYPE_MESH_POINT) {
+               if (ntype != NL80211_IFTYPE_MESH_POINT) {
                        err = -EINVAL;
                        goto unlock;
                }
@@ -663,7 +811,7 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
        }
 
        if (info->attrs[NL80211_ATTR_MNTR_FLAGS]) {
-               if (type != NL80211_IFTYPE_MONITOR) {
+               if (ntype != NL80211_IFTYPE_MONITOR) {
                        err = -EINVAL;
                        goto unlock;
                }
@@ -678,12 +826,17 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
 
        if (change)
                err = drv->ops->change_virtual_intf(&drv->wiphy, ifindex,
-                                                   type, flags, &params);
+                                                   ntype, flags, &params);
        else
                err = 0;
 
        dev = __dev_get_by_index(&init_net, ifindex);
-       WARN_ON(!dev || (!err && dev->ieee80211_ptr->iftype != type));
+       WARN_ON(!dev || (!err && dev->ieee80211_ptr->iftype != ntype));
+
+       if (dev && !err && (ntype != otype)) {
+               if (otype == NL80211_IFTYPE_ADHOC)
+                       cfg80211_clear_ibss(dev, false);
+       }
 
  unlock:
        cfg80211_put_dev(drv);
@@ -832,7 +985,7 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
                goto out;
        }
 
-       msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
+       msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
        if (!msg) {
                err = -ENOMEM;
                goto out;
@@ -920,6 +1073,14 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
        }
 
        err = func(&drv->wiphy, dev, key_idx);
+#ifdef CONFIG_WIRELESS_EXT
+       if (!err) {
+               if (func == drv->ops->set_default_key)
+                       dev->ieee80211_ptr->wext.default_key = key_idx;
+               else
+                       dev->ieee80211_ptr->wext.default_mgmt_key = key_idx;
+       }
+#endif
 
  out:
        cfg80211_put_dev(drv);
@@ -934,7 +1095,7 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
 static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
 {
        struct cfg80211_registered_device *drv;
-       int err;
+       int err, i;
        struct net_device *dev;
        struct key_params params;
        u8 key_idx = 0;
@@ -950,6 +1111,11 @@ static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
                params.key_len = nla_len(info->attrs[NL80211_ATTR_KEY_DATA]);
        }
 
+       if (info->attrs[NL80211_ATTR_KEY_SEQ]) {
+               params.seq = nla_data(info->attrs[NL80211_ATTR_KEY_SEQ]);
+               params.seq_len = nla_len(info->attrs[NL80211_ATTR_KEY_SEQ]);
+       }
+
        if (info->attrs[NL80211_ATTR_KEY_IDX])
                key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
 
@@ -958,44 +1124,8 @@ static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
        if (info->attrs[NL80211_ATTR_MAC])
                mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
 
-       if (key_idx > 5)
-               return -EINVAL;
-
-       /*
-        * Disallow pairwise keys with non-zero index unless it's WEP
-        * (because current deployments use pairwise WEP keys with
-        * non-zero indizes but 802.11i clearly specifies to use zero)
-        */
-       if (mac_addr && key_idx &&
-           params.cipher != WLAN_CIPHER_SUITE_WEP40 &&
-           params.cipher != WLAN_CIPHER_SUITE_WEP104)
-               return -EINVAL;
-
-       /* TODO: add definitions for the lengths to linux/ieee80211.h */
-       switch (params.cipher) {
-       case WLAN_CIPHER_SUITE_WEP40:
-               if (params.key_len != 5)
-                       return -EINVAL;
-               break;
-       case WLAN_CIPHER_SUITE_TKIP:
-               if (params.key_len != 32)
-                       return -EINVAL;
-               break;
-       case WLAN_CIPHER_SUITE_CCMP:
-               if (params.key_len != 16)
-                       return -EINVAL;
-               break;
-       case WLAN_CIPHER_SUITE_WEP104:
-               if (params.key_len != 13)
-                       return -EINVAL;
-               break;
-       case WLAN_CIPHER_SUITE_AES_CMAC:
-               if (params.key_len != 16)
-                       return -EINVAL;
-               break;
-       default:
+       if (cfg80211_validate_key_settings(&params, key_idx, mac_addr))
                return -EINVAL;
-       }
 
        rtnl_lock();
 
@@ -1003,6 +1133,14 @@ static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
        if (err)
                goto unlock_rtnl;
 
+       for (i = 0; i < drv->wiphy.n_cipher_suites; i++)
+               if (params.cipher == drv->wiphy.cipher_suites[i])
+                       break;
+       if (i == drv->wiphy.n_cipher_suites) {
+               err = -EINVAL;
+               goto out;
+       }
+
        if (!drv->ops->add_key) {
                err = -EOPNOTSUPP;
                goto out;
@@ -1049,6 +1187,15 @@ static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info)
 
        err = drv->ops->del_key(&drv->wiphy, dev, key_idx, mac_addr);
 
+#ifdef CONFIG_WIRELESS_EXT
+       if (!err) {
+               if (key_idx == dev->ieee80211_ptr->wext.default_key)
+                       dev->ieee80211_ptr->wext.default_key = -1;
+               else if (key_idx == dev->ieee80211_ptr->wext.default_mgmt_key)
+                       dev->ieee80211_ptr->wext.default_mgmt_key = -1;
+       }
+#endif
+
  out:
        cfg80211_put_dev(drv);
        dev_put(dev);
@@ -1069,6 +1216,9 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
        struct beacon_parameters params;
        int haveinfo = 0;
 
+       if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_BEACON_TAIL]))
+               return -EINVAL;
+
        rtnl_lock();
 
        err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
@@ -1186,15 +1336,36 @@ static const struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] = {
        [NL80211_STA_FLAG_AUTHORIZED] = { .type = NLA_FLAG },
        [NL80211_STA_FLAG_SHORT_PREAMBLE] = { .type = NLA_FLAG },
        [NL80211_STA_FLAG_WME] = { .type = NLA_FLAG },
+       [NL80211_STA_FLAG_MFP] = { .type = NLA_FLAG },
 };
 
-static int parse_station_flags(struct nlattr *nla, u32 *staflags)
+static int parse_station_flags(struct genl_info *info,
+                              struct station_parameters *params)
 {
        struct nlattr *flags[NL80211_STA_FLAG_MAX + 1];
+       struct nlattr *nla;
        int flag;
 
-       *staflags = 0;
+       /*
+        * Try parsing the new attribute first so userspace
+        * can specify both for older kernels.
+        */
+       nla = info->attrs[NL80211_ATTR_STA_FLAGS2];
+       if (nla) {
+               struct nl80211_sta_flag_update *sta_flags;
+
+               sta_flags = nla_data(nla);
+               params->sta_flags_mask = sta_flags->mask;
+               params->sta_flags_set = sta_flags->set;
+               if ((params->sta_flags_mask |
+                    params->sta_flags_set) & BIT(__NL80211_STA_FLAG_INVALID))
+                       return -EINVAL;
+               return 0;
+       }
+
+       /* if present, parse the old attribute */
 
+       nla = info->attrs[NL80211_ATTR_STA_FLAGS];
        if (!nla)
                return 0;
 
@@ -1202,11 +1373,12 @@ static int parse_station_flags(struct nlattr *nla, u32 *staflags)
                             nla, sta_flags_policy))
                return -EINVAL;
 
-       *staflags = STATION_FLAG_CHANGED;
+       params->sta_flags_mask = (1 << __NL80211_STA_FLAG_AFTER_LAST) - 1;
+       params->sta_flags_mask &= ~1;
 
        for (flag = 1; flag <= NL80211_STA_FLAG_MAX; flag++)
                if (flags[flag])
-                       *staflags |= (1<<flag);
+                       params->sta_flags_set |= (1<<flag);
 
        return 0;
 }
@@ -1424,7 +1596,7 @@ static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
        if (err)
                goto out;
 
-       msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
+       msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
        if (!msg)
                goto out;
 
@@ -1502,8 +1674,7 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
                params.ht_capa =
                        nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
 
-       if (parse_station_flags(info->attrs[NL80211_ATTR_STA_FLAGS],
-                               &params.station_flags))
+       if (parse_station_flags(info, &params))
                return -EINVAL;
 
        if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION])
@@ -1516,6 +1687,12 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
        if (err)
                goto out_rtnl;
 
+       if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
+           dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN) {
+               err = -EINVAL;
+               goto out;
+       }
+
        err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], drv, &params.vlan);
        if (err)
                goto out;
@@ -1567,13 +1744,16 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
                nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
        params.listen_interval =
                nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
+
        params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]);
+       if (!params.aid || params.aid > IEEE80211_MAX_AID)
+               return -EINVAL;
+
        if (info->attrs[NL80211_ATTR_HT_CAPABILITY])
                params.ht_capa =
                        nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
 
-       if (parse_station_flags(info->attrs[NL80211_ATTR_STA_FLAGS],
-                               &params.station_flags))
+       if (parse_station_flags(info, &params))
                return -EINVAL;
 
        rtnl_lock();
@@ -1582,6 +1762,12 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
        if (err)
                goto out_rtnl;
 
+       if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
+           dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN) {
+               err = -EINVAL;
+               goto out;
+       }
+
        err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], drv, &params.vlan);
        if (err)
                goto out;
@@ -1625,6 +1811,12 @@ static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info)
        if (err)
                goto out_rtnl;
 
+       if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
+           dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN) {
+               err = -EINVAL;
+               goto out;
+       }
+
        if (!drv->ops->del_station) {
                err = -EOPNOTSUPP;
                goto out;
@@ -1808,7 +2000,7 @@ static int nl80211_get_mpath(struct sk_buff *skb, struct genl_info *info)
        if (err)
                goto out;
 
-       msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
+       msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
        if (!msg)
                goto out;
 
@@ -2124,7 +2316,7 @@ static int nl80211_get_mesh_params(struct sk_buff *skb,
                goto out;
 
        /* Draw up a netlink message to send back */
-       msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
+       msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
        if (!msg) {
                err = -ENOBUFS;
                goto out;
@@ -2302,7 +2494,7 @@ static int nl80211_get_reg(struct sk_buff *skb, struct genl_info *info)
        if (!cfg80211_regdomain)
                goto out;
 
-       msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
+       msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
        if (!msg) {
                err = -ENOBUFS;
                goto out;
@@ -2385,18 +2577,24 @@ static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
                        rem_reg_rules) {
                num_rules++;
                if (num_rules > NL80211_MAX_SUPP_REG_RULES)
-                       goto bad_reg;
+                       return -EINVAL;
        }
 
-       if (!reg_is_valid_request(alpha2))
-               return -EINVAL;
+       mutex_lock(&cfg80211_mutex);
+
+       if (!reg_is_valid_request(alpha2)) {
+               r = -EINVAL;
+               goto bad_reg;
+       }
 
        size_of_regd = sizeof(struct ieee80211_regdomain) +
                (num_rules * sizeof(struct ieee80211_reg_rule));
 
        rd = kzalloc(size_of_regd, GFP_KERNEL);
-       if (!rd)
-               return -ENOMEM;
+       if (!rd) {
+               r = -ENOMEM;
+               goto bad_reg;
+       }
 
        rd->n_reg_rules = num_rules;
        rd->alpha2[0] = alpha2[0];
@@ -2413,20 +2611,24 @@ static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
 
                rule_idx++;
 
-               if (rule_idx > NL80211_MAX_SUPP_REG_RULES)
+               if (rule_idx > NL80211_MAX_SUPP_REG_RULES) {
+                       r = -EINVAL;
                        goto bad_reg;
+               }
        }
 
        BUG_ON(rule_idx != num_rules);
 
-       mutex_lock(&cfg80211_mutex);
        r = set_regdom(rd);
+
        mutex_unlock(&cfg80211_mutex);
+
        return r;
 
  bad_reg:
+       mutex_unlock(&cfg80211_mutex);
        kfree(rd);
-       return -EINVAL;
+       return r;
 }
 
 static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
@@ -2442,6 +2644,9 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
        enum ieee80211_band band;
        size_t ie_len;
 
+       if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
+               return -EINVAL;
+
        rtnl_lock();
 
        err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
@@ -2492,6 +2697,11 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
        else
                ie_len = 0;
 
+       if (ie_len > wiphy->max_scan_ie_len) {
+               err = -EINVAL;
+               goto out;
+       }
+
        request = kzalloc(sizeof(*request)
                        + sizeof(*ssid) * n_ssids
                        + sizeof(channel) * n_channels
@@ -2554,7 +2764,8 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
 
        if (info->attrs[NL80211_ATTR_IE]) {
                request->ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
-               memcpy(request->ie, nla_data(info->attrs[NL80211_ATTR_IE]),
+               memcpy((void *)request->ie,
+                      nla_data(info->attrs[NL80211_ATTR_IE]),
                       request->ie_len);
        }
 
@@ -2710,6 +2921,15 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
        struct wiphy *wiphy;
        int err;
 
+       if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
+               return -EINVAL;
+
+       if (!info->attrs[NL80211_ATTR_MAC])
+               return -EINVAL;
+
+       if (!info->attrs[NL80211_ATTR_AUTH_TYPE])
+               return -EINVAL;
+
        rtnl_lock();
 
        err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
@@ -2731,11 +2951,6 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
                goto out;
        }
 
-       if (!info->attrs[NL80211_ATTR_MAC]) {
-               err = -EINVAL;
-               goto out;
-       }
-
        wiphy = &drv->wiphy;
        memset(&req, 0, sizeof(req));
 
@@ -2761,13 +2976,10 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
                req.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
        }
 
-       if (info->attrs[NL80211_ATTR_AUTH_TYPE]) {
-               req.auth_type =
-                       nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]);
-               if (!nl80211_valid_auth_type(req.auth_type)) {
-                       err = -EINVAL;
-                       goto out;
-               }
+       req.auth_type = nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]);
+       if (!nl80211_valid_auth_type(req.auth_type)) {
+               err = -EINVAL;
+               goto out;
        }
 
        err = drv->ops->auth(&drv->wiphy, dev, &req);
@@ -2788,6 +3000,13 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
        struct wiphy *wiphy;
        int err;
 
+       if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
+               return -EINVAL;
+
+       if (!info->attrs[NL80211_ATTR_MAC] ||
+           !info->attrs[NL80211_ATTR_SSID])
+               return -EINVAL;
+
        rtnl_lock();
 
        err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
@@ -2809,12 +3028,6 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
                goto out;
        }
 
-       if (!info->attrs[NL80211_ATTR_MAC] ||
-           !info->attrs[NL80211_ATTR_SSID]) {
-               err = -EINVAL;
-               goto out;
-       }
-
        wiphy = &drv->wiphy;
        memset(&req, 0, sizeof(req));
 
@@ -2838,6 +3051,19 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
                req.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
        }
 
+       if (info->attrs[NL80211_ATTR_USE_MFP]) {
+               enum nl80211_mfp use_mfp =
+                       nla_get_u32(info->attrs[NL80211_ATTR_USE_MFP]);
+               if (use_mfp == NL80211_MFP_REQUIRED)
+                       req.use_mfp = true;
+               else if (use_mfp != NL80211_MFP_NO) {
+                       err = -EINVAL;
+                       goto out;
+               }
+       }
+
+       req.control_port = info->attrs[NL80211_ATTR_CONTROL_PORT];
+
        err = drv->ops->assoc(&drv->wiphy, dev, &req);
 
 out:
@@ -2856,6 +3082,15 @@ static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info)
        struct wiphy *wiphy;
        int err;
 
+       if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
+               return -EINVAL;
+
+       if (!info->attrs[NL80211_ATTR_MAC])
+               return -EINVAL;
+
+       if (!info->attrs[NL80211_ATTR_REASON_CODE])
+               return -EINVAL;
+
        rtnl_lock();
 
        err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
@@ -2877,24 +3112,16 @@ static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info)
                goto out;
        }
 
-       if (!info->attrs[NL80211_ATTR_MAC]) {
-               err = -EINVAL;
-               goto out;
-       }
-
        wiphy = &drv->wiphy;
        memset(&req, 0, sizeof(req));
 
        req.peer_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
 
-       if (info->attrs[NL80211_ATTR_REASON_CODE]) {
-               req.reason_code =
-                       nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
-               if (req.reason_code == 0) {
-                       /* Reason Code 0 is reserved */
-                       err = -EINVAL;
-                       goto out;
-               }
+       req.reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
+       if (req.reason_code == 0) {
+               /* Reason Code 0 is reserved */
+               err = -EINVAL;
+               goto out;
        }
 
        if (info->attrs[NL80211_ATTR_IE]) {
@@ -2920,6 +3147,15 @@ static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info)
        struct wiphy *wiphy;
        int err;
 
+       if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
+               return -EINVAL;
+
+       if (!info->attrs[NL80211_ATTR_MAC])
+               return -EINVAL;
+
+       if (!info->attrs[NL80211_ATTR_REASON_CODE])
+               return -EINVAL;
+
        rtnl_lock();
 
        err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
@@ -2941,24 +3177,16 @@ static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info)
                goto out;
        }
 
-       if (!info->attrs[NL80211_ATTR_MAC]) {
-               err = -EINVAL;
-               goto out;
-       }
-
        wiphy = &drv->wiphy;
        memset(&req, 0, sizeof(req));
 
        req.peer_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
 
-       if (info->attrs[NL80211_ATTR_REASON_CODE]) {
-               req.reason_code =
-                       nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
-               if (req.reason_code == 0) {
-                       /* Reason Code 0 is reserved */
-                       err = -EINVAL;
-                       goto out;
-               }
+       req.reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]);
+       if (req.reason_code == 0) {
+               /* Reason Code 0 is reserved */
+               err = -EINVAL;
+               goto out;
        }
 
        if (info->attrs[NL80211_ATTR_IE]) {
@@ -2976,6 +3204,124 @@ unlock_rtnl:
        return err;
 }
 
+static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
+{
+       struct cfg80211_registered_device *drv;
+       struct net_device *dev;
+       struct cfg80211_ibss_params ibss;
+       struct wiphy *wiphy;
+       int err;
+
+       memset(&ibss, 0, sizeof(ibss));
+
+       if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
+               return -EINVAL;
+
+       if (!info->attrs[NL80211_ATTR_WIPHY_FREQ] ||
+           !info->attrs[NL80211_ATTR_SSID] ||
+           !nla_len(info->attrs[NL80211_ATTR_SSID]))
+               return -EINVAL;
+
+       ibss.beacon_interval = 100;
+
+       if (info->attrs[NL80211_ATTR_BEACON_INTERVAL]) {
+               ibss.beacon_interval =
+                       nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]);
+               if (ibss.beacon_interval < 1 || ibss.beacon_interval > 10000)
+                       return -EINVAL;
+       }
+
+       rtnl_lock();
+
+       err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
+       if (err)
+               goto unlock_rtnl;
+
+       if (!drv->ops->join_ibss) {
+               err = -EOPNOTSUPP;
+               goto out;
+       }
+
+       if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC) {
+               err = -EOPNOTSUPP;
+               goto out;
+       }
+
+       if (!netif_running(dev)) {
+               err = -ENETDOWN;
+               goto out;
+       }
+
+       wiphy = &drv->wiphy;
+
+       if (info->attrs[NL80211_ATTR_MAC])
+               ibss.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
+       ibss.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
+       ibss.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]);
+
+       if (info->attrs[NL80211_ATTR_IE]) {
+               ibss.ie = nla_data(info->attrs[NL80211_ATTR_IE]);
+               ibss.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
+       }
+
+       ibss.channel = ieee80211_get_channel(wiphy,
+               nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]));
+       if (!ibss.channel ||
+           ibss.channel->flags & IEEE80211_CHAN_NO_IBSS ||
+           ibss.channel->flags & IEEE80211_CHAN_DISABLED) {
+               err = -EINVAL;
+               goto out;
+       }
+
+       ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED];
+
+       err = cfg80211_join_ibss(drv, dev, &ibss);
+
+out:
+       cfg80211_put_dev(drv);
+       dev_put(dev);
+unlock_rtnl:
+       rtnl_unlock();
+       return err;
+}
+
+static int nl80211_leave_ibss(struct sk_buff *skb, struct genl_info *info)
+{
+       struct cfg80211_registered_device *drv;
+       struct net_device *dev;
+       int err;
+
+       rtnl_lock();
+
+       err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
+       if (err)
+               goto unlock_rtnl;
+
+       if (!drv->ops->leave_ibss) {
+               err = -EOPNOTSUPP;
+               goto out;
+       }
+
+       if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC) {
+               err = -EOPNOTSUPP;
+               goto out;
+       }
+
+       if (!netif_running(dev)) {
+               err = -ENETDOWN;
+               goto out;
+       }
+
+       err = cfg80211_leave_ibss(drv, dev, false);
+
+out:
+       cfg80211_put_dev(drv);
+       dev_put(dev);
+unlock_rtnl:
+       rtnl_unlock();
+       return err;
+}
+
 static struct genl_ops nl80211_ops[] = {
        {
                .cmd = NL80211_CMD_GET_WIPHY,
@@ -3177,6 +3523,18 @@ static struct genl_ops nl80211_ops[] = {
                .policy = nl80211_policy,
                .flags = GENL_ADMIN_PERM,
        },
+       {
+               .cmd = NL80211_CMD_JOIN_IBSS,
+               .doit = nl80211_join_ibss,
+               .policy = nl80211_policy,
+               .flags = GENL_ADMIN_PERM,
+       },
+       {
+               .cmd = NL80211_CMD_LEAVE_IBSS,
+               .doit = nl80211_leave_ibss,
+               .policy = nl80211_policy,
+               .flags = GENL_ADMIN_PERM,
+       },
 };
 static struct genl_multicast_group nl80211_mlme_mcgrp = {
        .name = "mlme",
@@ -3199,7 +3557,7 @@ void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev)
 {
        struct sk_buff *msg;
 
-       msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
+       msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
        if (!msg)
                return;
 
@@ -3211,11 +3569,43 @@ void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev)
        genlmsg_multicast(msg, 0, nl80211_config_mcgrp.id, GFP_KERNEL);
 }
 
+static int nl80211_add_scan_req(struct sk_buff *msg,
+                               struct cfg80211_registered_device *rdev)
+{
+       struct cfg80211_scan_request *req = rdev->scan_req;
+       struct nlattr *nest;
+       int i;
+
+       if (WARN_ON(!req))
+               return 0;
+
+       nest = nla_nest_start(msg, NL80211_ATTR_SCAN_SSIDS);
+       if (!nest)
+               goto nla_put_failure;
+       for (i = 0; i < req->n_ssids; i++)
+               NLA_PUT(msg, i, req->ssids[i].ssid_len, req->ssids[i].ssid);
+       nla_nest_end(msg, nest);
+
+       nest = nla_nest_start(msg, NL80211_ATTR_SCAN_FREQUENCIES);
+       if (!nest)
+               goto nla_put_failure;
+       for (i = 0; i < req->n_channels; i++)
+               NLA_PUT_U32(msg, i, req->channels[i]->center_freq);
+       nla_nest_end(msg, nest);
+
+       if (req->ie)
+               NLA_PUT(msg, NL80211_ATTR_IE, req->ie_len, req->ie);
+
+       return 0;
+ nla_put_failure:
+       return -ENOBUFS;
+}
+
 static int nl80211_send_scan_donemsg(struct sk_buff *msg,
-                                   struct cfg80211_registered_device *rdev,
-                                   struct net_device *netdev,
-                                   u32 pid, u32 seq, int flags,
-                                   u32 cmd)
+                                    struct cfg80211_registered_device *rdev,
+                                    struct net_device *netdev,
+                                    u32 pid, u32 seq, int flags,
+                                    u32 cmd)
 {
        void *hdr;
 
@@ -3226,7 +3616,8 @@ static int nl80211_send_scan_donemsg(struct sk_buff *msg,
        NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
        NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
 
-       /* XXX: we should probably bounce back the request? */
+       /* ignore errors and send incomplete event anyway */
+       nl80211_add_scan_req(msg, rdev);
 
        return genlmsg_end(msg, hdr);
 
@@ -3240,7 +3631,7 @@ void nl80211_send_scan_done(struct cfg80211_registered_device *rdev,
 {
        struct sk_buff *msg;
 
-       msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
+       msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
        if (!msg)
                return;
 
@@ -3258,7 +3649,7 @@ void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev,
 {
        struct sk_buff *msg;
 
-       msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
+       msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
        if (!msg)
                return;
 
@@ -3280,7 +3671,7 @@ void nl80211_send_reg_change_event(struct regulatory_request *request)
        struct sk_buff *msg;
        void *hdr;
 
-       msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
+       msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
        if (!msg)
                return;
 
@@ -3334,7 +3725,7 @@ static void nl80211_send_mlme_event(struct cfg80211_registered_device *rdev,
        struct sk_buff *msg;
        void *hdr;
 
-       msg = nlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC);
+       msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
        if (!msg)
                return;
 
@@ -3375,38 +3766,208 @@ void nl80211_send_rx_assoc(struct cfg80211_registered_device *rdev,
        nl80211_send_mlme_event(rdev, netdev, buf, len, NL80211_CMD_ASSOCIATE);
 }
 
-void nl80211_send_rx_deauth(struct cfg80211_registered_device *rdev,
-                           struct net_device *netdev, const u8 *buf,
-                           size_t len)
+void nl80211_send_deauth(struct cfg80211_registered_device *rdev,
+                        struct net_device *netdev, const u8 *buf, size_t len)
 {
        nl80211_send_mlme_event(rdev, netdev, buf, len,
                                NL80211_CMD_DEAUTHENTICATE);
 }
 
-void nl80211_send_rx_disassoc(struct cfg80211_registered_device *rdev,
-                             struct net_device *netdev, const u8 *buf,
-                             size_t len)
+void nl80211_send_disassoc(struct cfg80211_registered_device *rdev,
+                          struct net_device *netdev, const u8 *buf,
+                          size_t len)
 {
        nl80211_send_mlme_event(rdev, netdev, buf, len,
                                NL80211_CMD_DISASSOCIATE);
 }
 
+static void nl80211_send_mlme_timeout(struct cfg80211_registered_device *rdev,
+                                     struct net_device *netdev, int cmd,
+                                     const u8 *addr)
+{
+       struct sk_buff *msg;
+       void *hdr;
+
+       msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
+       if (!msg)
+               return;
+
+       hdr = nl80211hdr_put(msg, 0, 0, 0, cmd);
+       if (!hdr) {
+               nlmsg_free(msg);
+               return;
+       }
+
+       NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
+       NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
+       NLA_PUT_FLAG(msg, NL80211_ATTR_TIMED_OUT);
+       NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
+
+       if (genlmsg_end(msg, hdr) < 0) {
+               nlmsg_free(msg);
+               return;
+       }
+
+       genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, GFP_ATOMIC);
+       return;
+
+ nla_put_failure:
+       genlmsg_cancel(msg, hdr);
+       nlmsg_free(msg);
+}
+
+void nl80211_send_auth_timeout(struct cfg80211_registered_device *rdev,
+                              struct net_device *netdev, const u8 *addr)
+{
+       nl80211_send_mlme_timeout(rdev, netdev, NL80211_CMD_AUTHENTICATE,
+                                 addr);
+}
+
+void nl80211_send_assoc_timeout(struct cfg80211_registered_device *rdev,
+                               struct net_device *netdev, const u8 *addr)
+{
+       nl80211_send_mlme_timeout(rdev, netdev, NL80211_CMD_ASSOCIATE, addr);
+}
+
+void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev,
+                            struct net_device *netdev, const u8 *bssid,
+                            gfp_t gfp)
+{
+       struct sk_buff *msg;
+       void *hdr;
+
+       msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
+       if (!msg)
+               return;
+
+       hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_JOIN_IBSS);
+       if (!hdr) {
+               nlmsg_free(msg);
+               return;
+       }
+
+       NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
+       NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
+       NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid);
+
+       if (genlmsg_end(msg, hdr) < 0) {
+               nlmsg_free(msg);
+               return;
+       }
+
+       genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, gfp);
+       return;
+
+ nla_put_failure:
+       genlmsg_cancel(msg, hdr);
+       nlmsg_free(msg);
+}
+
+void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev,
+                                struct net_device *netdev, const u8 *addr,
+                                enum nl80211_key_type key_type, int key_id,
+                                const u8 *tsc)
+{
+       struct sk_buff *msg;
+       void *hdr;
+
+       msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
+       if (!msg)
+               return;
+
+       hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_MICHAEL_MIC_FAILURE);
+       if (!hdr) {
+               nlmsg_free(msg);
+               return;
+       }
+
+       NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
+       NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
+       if (addr)
+               NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
+       NLA_PUT_U32(msg, NL80211_ATTR_KEY_TYPE, key_type);
+       NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, key_id);
+       if (tsc)
+               NLA_PUT(msg, NL80211_ATTR_KEY_SEQ, 6, tsc);
+
+       if (genlmsg_end(msg, hdr) < 0) {
+               nlmsg_free(msg);
+               return;
+       }
+
+       genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, GFP_ATOMIC);
+       return;
+
+ nla_put_failure:
+       genlmsg_cancel(msg, hdr);
+       nlmsg_free(msg);
+}
+
+void nl80211_send_beacon_hint_event(struct wiphy *wiphy,
+                                   struct ieee80211_channel *channel_before,
+                                   struct ieee80211_channel *channel_after)
+{
+       struct sk_buff *msg;
+       void *hdr;
+       struct nlattr *nl_freq;
+
+       msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
+       if (!msg)
+               return;
+
+       hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_REG_BEACON_HINT);
+       if (!hdr) {
+               nlmsg_free(msg);
+               return;
+       }
+
+       /*
+        * Since we are applying the beacon hint to a wiphy we know its
+        * wiphy_idx is valid
+        */
+       NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, get_wiphy_idx(wiphy));
+
+       /* Before */
+       nl_freq = nla_nest_start(msg, NL80211_ATTR_FREQ_BEFORE);
+       if (!nl_freq)
+               goto nla_put_failure;
+       if (nl80211_msg_put_channel(msg, channel_before))
+               goto nla_put_failure;
+       nla_nest_end(msg, nl_freq);
+
+       /* After */
+       nl_freq = nla_nest_start(msg, NL80211_ATTR_FREQ_AFTER);
+       if (!nl_freq)
+               goto nla_put_failure;
+       if (nl80211_msg_put_channel(msg, channel_after))
+               goto nla_put_failure;
+       nla_nest_end(msg, nl_freq);
+
+       if (genlmsg_end(msg, hdr) < 0) {
+               nlmsg_free(msg);
+               return;
+       }
+
+       genlmsg_multicast(msg, 0, nl80211_regulatory_mcgrp.id, GFP_ATOMIC);
+
+       return;
+
+nla_put_failure:
+       genlmsg_cancel(msg, hdr);
+       nlmsg_free(msg);
+}
+
 /* initialisation/exit functions */
 
 int nl80211_init(void)
 {
-       int err, i;
+       int err;
 
-       err = genl_register_family(&nl80211_fam);
+       err = genl_register_family_with_ops(&nl80211_fam,
+               nl80211_ops, ARRAY_SIZE(nl80211_ops));
        if (err)
                return err;
 
-       for (i = 0; i < ARRAY_SIZE(nl80211_ops); i++) {
-               err = genl_register_ops(&nl80211_fam, &nl80211_ops[i]);
-               if (err)
-                       goto err_out;
-       }
-
        err = genl_register_mc_group(&nl80211_fam, &nl80211_config_mcgrp);
        if (err)
                goto err_out;
index b77af4ab80becebd45800e554660a8a9fe0ef56b..5c12ad13499b01d47ebb84f0f8ef570ba8ae6429 100644 (file)
@@ -17,11 +17,31 @@ extern void nl80211_send_rx_auth(struct cfg80211_registered_device *rdev,
 extern void nl80211_send_rx_assoc(struct cfg80211_registered_device *rdev,
                                  struct net_device *netdev,
                                  const u8 *buf, size_t len);
-extern void nl80211_send_rx_deauth(struct cfg80211_registered_device *rdev,
-                                  struct net_device *netdev,
-                                  const u8 *buf, size_t len);
-extern void nl80211_send_rx_disassoc(struct cfg80211_registered_device *rdev,
-                                    struct net_device *netdev,
-                                    const u8 *buf, size_t len);
+extern void nl80211_send_deauth(struct cfg80211_registered_device *rdev,
+                               struct net_device *netdev,
+                               const u8 *buf, size_t len);
+extern void nl80211_send_disassoc(struct cfg80211_registered_device *rdev,
+                                 struct net_device *netdev,
+                                 const u8 *buf, size_t len);
+extern void nl80211_send_auth_timeout(struct cfg80211_registered_device *rdev,
+                                     struct net_device *netdev,
+                                     const u8 *addr);
+extern void nl80211_send_assoc_timeout(struct cfg80211_registered_device *rdev,
+                                      struct net_device *netdev,
+                                      const u8 *addr);
+extern void
+nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev,
+                           struct net_device *netdev, const u8 *addr,
+                           enum nl80211_key_type key_type,
+                           int key_id, const u8 *tsc);
+
+extern void
+nl80211_send_beacon_hint_event(struct wiphy *wiphy,
+                              struct ieee80211_channel *channel_before,
+                              struct ieee80211_channel *channel_after);
+
+void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev,
+                            struct net_device *netdev, const u8 *bssid,
+                            gfp_t gfp);
 
 #endif /* __NET_WIRELESS_NL80211_H */
index 487cb627ddbae72eadeba33794ddffe392ca771d..5e14371cda704c2c103df0449f929069752148f8 100644 (file)
@@ -37,7 +37,6 @@
 #include <linux/random.h>
 #include <linux/nl80211.h>
 #include <linux/platform_device.h>
-#include <net/wireless.h>
 #include <net/cfg80211.h>
 #include "core.h"
 #include "reg.h"
@@ -49,12 +48,6 @@ static struct regulatory_request *last_request;
 /* To trigger userspace events */
 static struct platform_device *reg_pdev;
 
-/* Keep the ordering from large to small */
-static u32 supported_bandwidths[] = {
-       MHZ_TO_KHZ(40),
-       MHZ_TO_KHZ(20),
-};
-
 /*
  * Central wireless core regulatory domains, we only need two,
  * the current one and a world regulatory domain in case we have no
@@ -389,6 +382,8 @@ static int call_crda(const char *alpha2)
 /* Used by nl80211 before kmalloc'ing our regulatory domain */
 bool reg_is_valid_request(const char *alpha2)
 {
+       assert_cfg80211_lock();
+
        if (!last_request)
                return false;
 
@@ -436,19 +431,20 @@ static bool is_valid_rd(const struct ieee80211_regdomain *rd)
        return true;
 }
 
-/* Returns value in KHz */
-static u32 freq_max_bandwidth(const struct ieee80211_freq_range *freq_range,
-       u32 freq)
+static bool reg_does_bw_fit(const struct ieee80211_freq_range *freq_range,
+                           u32 center_freq_khz,
+                           u32 bw_khz)
 {
-       unsigned int i;
-       for (i = 0; i < ARRAY_SIZE(supported_bandwidths); i++) {
-               u32 start_freq_khz = freq - supported_bandwidths[i]/2;
-               u32 end_freq_khz = freq + supported_bandwidths[i]/2;
-               if (start_freq_khz >= freq_range->start_freq_khz &&
-                       end_freq_khz <= freq_range->end_freq_khz)
-                       return supported_bandwidths[i];
-       }
-       return 0;
+       u32 start_freq_khz, end_freq_khz;
+
+       start_freq_khz = center_freq_khz - (bw_khz/2);
+       end_freq_khz = center_freq_khz + (bw_khz/2);
+
+       if (start_freq_khz >= freq_range->start_freq_khz &&
+           end_freq_khz <= freq_range->end_freq_khz)
+               return true;
+
+       return false;
 }
 
 /**
@@ -848,14 +844,17 @@ static u32 map_regdom_flags(u32 rd_flags)
 
 static int freq_reg_info_regd(struct wiphy *wiphy,
                              u32 center_freq,
-                             u32 *bandwidth,
+                             u32 desired_bw_khz,
                              const struct ieee80211_reg_rule **reg_rule,
                              const struct ieee80211_regdomain *custom_regd)
 {
        int i;
        bool band_rule_found = false;
        const struct ieee80211_regdomain *regd;
-       u32 max_bandwidth = 0;
+       bool bw_fits = false;
+
+       if (!desired_bw_khz)
+               desired_bw_khz = MHZ_TO_KHZ(20);
 
        regd = custom_regd ? custom_regd : cfg80211_regdomain;
 
@@ -888,38 +887,54 @@ static int freq_reg_info_regd(struct wiphy *wiphy,
                if (!band_rule_found)
                        band_rule_found = freq_in_rule_band(fr, center_freq);
 
-               max_bandwidth = freq_max_bandwidth(fr, center_freq);
+               bw_fits = reg_does_bw_fit(fr,
+                                         center_freq,
+                                         desired_bw_khz);
 
-               if (max_bandwidth && *bandwidth <= max_bandwidth) {
+               if (band_rule_found && bw_fits) {
                        *reg_rule = rr;
-                       *bandwidth = max_bandwidth;
-                       break;
+                       return 0;
                }
        }
 
        if (!band_rule_found)
                return -ERANGE;
 
-       return !max_bandwidth;
+       return -EINVAL;
 }
 EXPORT_SYMBOL(freq_reg_info);
 
-int freq_reg_info(struct wiphy *wiphy, u32 center_freq, u32 *bandwidth,
-                        const struct ieee80211_reg_rule **reg_rule)
+int freq_reg_info(struct wiphy *wiphy,
+                 u32 center_freq,
+                 u32 desired_bw_khz,
+                 const struct ieee80211_reg_rule **reg_rule)
 {
        assert_cfg80211_lock();
-       return freq_reg_info_regd(wiphy, center_freq,
-               bandwidth, reg_rule, NULL);
+       return freq_reg_info_regd(wiphy,
+                                 center_freq,
+                                 desired_bw_khz,
+                                 reg_rule,
+                                 NULL);
 }
 
+/*
+ * Note that right now we assume the desired channel bandwidth
+ * is always 20 MHz for each individual channel (HT40 uses 20 MHz
+ * per channel, the primary and the extension channel). To support
+ * smaller custom bandwidths such as 5 MHz or 10 MHz we'll need a
+ * new ieee80211_channel.target_bw and re run the regulatory check
+ * on the wiphy with the target_bw specified. Then we can simply use
+ * that below for the desired_bw_khz below.
+ */
 static void handle_channel(struct wiphy *wiphy, enum ieee80211_band band,
                           unsigned int chan_idx)
 {
        int r;
-       u32 flags;
-       u32 max_bandwidth = 0;
+       u32 flags, bw_flags = 0;
+       u32 desired_bw_khz = MHZ_TO_KHZ(20);
        const struct ieee80211_reg_rule *reg_rule = NULL;
        const struct ieee80211_power_rule *power_rule = NULL;
+       const struct ieee80211_freq_range *freq_range = NULL;
        struct ieee80211_supported_band *sband;
        struct ieee80211_channel *chan;
        struct wiphy *request_wiphy = NULL;
@@ -934,8 +949,10 @@ static void handle_channel(struct wiphy *wiphy, enum ieee80211_band band,
 
        flags = chan->orig_flags;
 
-       r = freq_reg_info(wiphy, MHZ_TO_KHZ(chan->center_freq),
-               &max_bandwidth, &reg_rule);
+       r = freq_reg_info(wiphy,
+                         MHZ_TO_KHZ(chan->center_freq),
+                         desired_bw_khz,
+                         &reg_rule);
 
        if (r) {
                /*
@@ -978,6 +995,10 @@ static void handle_channel(struct wiphy *wiphy, enum ieee80211_band band,
        }
 
        power_rule = &reg_rule->power_rule;
+       freq_range = &reg_rule->freq_range;
+
+       if (freq_range->max_bandwidth_khz < MHZ_TO_KHZ(40))
+               bw_flags = IEEE80211_CHAN_NO_HT40;
 
        if (last_request->initiator == NL80211_REGDOM_SET_BY_DRIVER &&
            request_wiphy && request_wiphy == wiphy &&
@@ -988,19 +1009,19 @@ static void handle_channel(struct wiphy *wiphy, enum ieee80211_band band,
                 * settings
                 */
                chan->flags = chan->orig_flags =
-                       map_regdom_flags(reg_rule->flags);
+                       map_regdom_flags(reg_rule->flags) | bw_flags;
                chan->max_antenna_gain = chan->orig_mag =
                        (int) MBI_TO_DBI(power_rule->max_antenna_gain);
-               chan->max_bandwidth = KHZ_TO_MHZ(max_bandwidth);
+               chan->max_bandwidth = KHZ_TO_MHZ(desired_bw_khz);
                chan->max_power = chan->orig_mpwr =
                        (int) MBM_TO_DBM(power_rule->max_eirp);
                return;
        }
 
-       chan->flags = flags | map_regdom_flags(reg_rule->flags);
+       chan->flags = flags | bw_flags | map_regdom_flags(reg_rule->flags);
        chan->max_antenna_gain = min(chan->orig_mag,
                (int) MBI_TO_DBI(power_rule->max_antenna_gain));
-       chan->max_bandwidth = KHZ_TO_MHZ(max_bandwidth);
+       chan->max_bandwidth = KHZ_TO_MHZ(desired_bw_khz);
        if (chan->orig_mpwr)
                chan->max_power = min(chan->orig_mpwr,
                        (int) MBM_TO_DBM(power_rule->max_eirp));
@@ -1050,18 +1071,10 @@ static void handle_reg_beacon(struct wiphy *wiphy,
                              unsigned int chan_idx,
                              struct reg_beacon *reg_beacon)
 {
-#ifdef CONFIG_CFG80211_REG_DEBUG
-#define REG_DEBUG_BEACON_FLAG(desc) \
-       printk(KERN_DEBUG "cfg80211: Enabling " desc " on " \
-               "frequency: %d MHz (Ch %d) on %s\n", \
-               reg_beacon->chan.center_freq, \
-               ieee80211_frequency_to_channel(reg_beacon->chan.center_freq), \
-               wiphy_name(wiphy));
-#else
-#define REG_DEBUG_BEACON_FLAG(desc) do {} while (0)
-#endif
        struct ieee80211_supported_band *sband;
        struct ieee80211_channel *chan;
+       bool channel_changed = false;
+       struct ieee80211_channel chan_before;
 
        assert_cfg80211_lock();
 
@@ -1071,18 +1084,28 @@ static void handle_reg_beacon(struct wiphy *wiphy,
        if (likely(chan->center_freq != reg_beacon->chan.center_freq))
                return;
 
-       if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN) {
+       if (chan->beacon_found)
+               return;
+
+       chan->beacon_found = true;
+
+       chan_before.center_freq = chan->center_freq;
+       chan_before.flags = chan->flags;
+
+       if ((chan->flags & IEEE80211_CHAN_PASSIVE_SCAN) &&
+           !(chan->orig_flags & IEEE80211_CHAN_PASSIVE_SCAN)) {
                chan->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
-               REG_DEBUG_BEACON_FLAG("active scanning");
+               channel_changed = true;
        }
 
-       if (chan->flags & IEEE80211_CHAN_NO_IBSS) {
+       if ((chan->flags & IEEE80211_CHAN_NO_IBSS) &&
+           !(chan->orig_flags & IEEE80211_CHAN_NO_IBSS)) {
                chan->flags &= ~IEEE80211_CHAN_NO_IBSS;
-               REG_DEBUG_BEACON_FLAG("beaconing");
+               channel_changed = true;
        }
 
-       chan->beacon_found = true;
-#undef REG_DEBUG_BEACON_FLAG
+       if (channel_changed)
+               nl80211_send_beacon_hint_event(wiphy, &chan_before, chan);
 }
 
 /*
@@ -1155,6 +1178,93 @@ static void reg_process_beacons(struct wiphy *wiphy)
        wiphy_update_beacon_reg(wiphy);
 }
 
+static bool is_ht40_not_allowed(struct ieee80211_channel *chan)
+{
+       if (!chan)
+               return true;
+       if (chan->flags & IEEE80211_CHAN_DISABLED)
+               return true;
+       /* This would happen when regulatory rules disallow HT40 completely */
+       if (IEEE80211_CHAN_NO_HT40 == (chan->flags & (IEEE80211_CHAN_NO_HT40)))
+               return true;
+       return false;
+}
+
+static void reg_process_ht_flags_channel(struct wiphy *wiphy,
+                                        enum ieee80211_band band,
+                                        unsigned int chan_idx)
+{
+       struct ieee80211_supported_band *sband;
+       struct ieee80211_channel *channel;
+       struct ieee80211_channel *channel_before = NULL, *channel_after = NULL;
+       unsigned int i;
+
+       assert_cfg80211_lock();
+
+       sband = wiphy->bands[band];
+       BUG_ON(chan_idx >= sband->n_channels);
+       channel = &sband->channels[chan_idx];
+
+       if (is_ht40_not_allowed(channel)) {
+               channel->flags |= IEEE80211_CHAN_NO_HT40;
+               return;
+       }
+
+       /*
+        * We need to ensure the extension channels exist to
+        * be able to use HT40- or HT40+, this finds them (or not)
+        */
+       for (i = 0; i < sband->n_channels; i++) {
+               struct ieee80211_channel *c = &sband->channels[i];
+               if (c->center_freq == (channel->center_freq - 20))
+                       channel_before = c;
+               if (c->center_freq == (channel->center_freq + 20))
+                       channel_after = c;
+       }
+
+       /*
+        * Please note that this assumes target bandwidth is 20 MHz,
+        * if that ever changes we also need to change the below logic
+        * to include that as well.
+        */
+       if (is_ht40_not_allowed(channel_before))
+               channel->flags |= IEEE80211_CHAN_NO_HT40MINUS;
+       else
+               channel->flags &= ~IEEE80211_CHAN_NO_HT40MINUS;
+
+       if (is_ht40_not_allowed(channel_after))
+               channel->flags |= IEEE80211_CHAN_NO_HT40PLUS;
+       else
+               channel->flags &= ~IEEE80211_CHAN_NO_HT40PLUS;
+}
+
+static void reg_process_ht_flags_band(struct wiphy *wiphy,
+                                     enum ieee80211_band band)
+{
+       unsigned int i;
+       struct ieee80211_supported_band *sband;
+
+       BUG_ON(!wiphy->bands[band]);
+       sband = wiphy->bands[band];
+
+       for (i = 0; i < sband->n_channels; i++)
+               reg_process_ht_flags_channel(wiphy, band, i);
+}
+
+static void reg_process_ht_flags(struct wiphy *wiphy)
+{
+       enum ieee80211_band band;
+
+       if (!wiphy)
+               return;
+
+       for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
+               if (wiphy->bands[band])
+                       reg_process_ht_flags_band(wiphy, band);
+       }
+
+}
+
 void wiphy_update_regulatory(struct wiphy *wiphy,
                             enum nl80211_reg_initiator initiator)
 {
@@ -1168,6 +1278,7 @@ void wiphy_update_regulatory(struct wiphy *wiphy,
        }
 out:
        reg_process_beacons(wiphy);
+       reg_process_ht_flags(wiphy);
        if (wiphy->reg_notifier)
                wiphy->reg_notifier(wiphy, last_request);
 }
@@ -1178,9 +1289,11 @@ static void handle_channel_custom(struct wiphy *wiphy,
                                  const struct ieee80211_regdomain *regd)
 {
        int r;
-       u32 max_bandwidth = 0;
+       u32 desired_bw_khz = MHZ_TO_KHZ(20);
+       u32 bw_flags = 0;
        const struct ieee80211_reg_rule *reg_rule = NULL;
        const struct ieee80211_power_rule *power_rule = NULL;
+       const struct ieee80211_freq_range *freq_range = NULL;
        struct ieee80211_supported_band *sband;
        struct ieee80211_channel *chan;
 
@@ -1190,8 +1303,11 @@ static void handle_channel_custom(struct wiphy *wiphy,
        BUG_ON(chan_idx >= sband->n_channels);
        chan = &sband->channels[chan_idx];
 
-       r = freq_reg_info_regd(wiphy, MHZ_TO_KHZ(chan->center_freq),
-               &max_bandwidth, &reg_rule, regd);
+       r = freq_reg_info_regd(wiphy,
+                              MHZ_TO_KHZ(chan->center_freq),
+                              desired_bw_khz,
+                              &reg_rule,
+                              regd);
 
        if (r) {
                chan->flags = IEEE80211_CHAN_DISABLED;
@@ -1199,10 +1315,14 @@ static void handle_channel_custom(struct wiphy *wiphy,
        }
 
        power_rule = &reg_rule->power_rule;
+       freq_range = &reg_rule->freq_range;
+
+       if (freq_range->max_bandwidth_khz < MHZ_TO_KHZ(40))
+               bw_flags = IEEE80211_CHAN_NO_HT40;
 
-       chan->flags |= map_regdom_flags(reg_rule->flags);
+       chan->flags |= map_regdom_flags(reg_rule->flags) | bw_flags;
        chan->max_antenna_gain = (int) MBI_TO_DBI(power_rule->max_antenna_gain);
-       chan->max_bandwidth = KHZ_TO_MHZ(max_bandwidth);
+       chan->max_bandwidth = KHZ_TO_MHZ(desired_bw_khz);
        chan->max_power = (int) MBM_TO_DBM(power_rule->max_eirp);
 }
 
@@ -1224,13 +1344,22 @@ void wiphy_apply_custom_regulatory(struct wiphy *wiphy,
                                   const struct ieee80211_regdomain *regd)
 {
        enum ieee80211_band band;
+       unsigned int bands_set = 0;
 
        mutex_lock(&cfg80211_mutex);
        for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
-               if (wiphy->bands[band])
-                       handle_band_custom(wiphy, band, regd);
+               if (!wiphy->bands[band])
+                       continue;
+               handle_band_custom(wiphy, band, regd);
+               bands_set++;
        }
        mutex_unlock(&cfg80211_mutex);
+
+       /*
+        * no point in calling this if it won't have any effect
+        * on your device's supportd bands.
+        */
+       WARN_ON(!bands_set);
 }
 EXPORT_SYMBOL(wiphy_apply_custom_regulatory);
 
@@ -2000,7 +2129,12 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
                 * driver wanted to the wiphy to deal with conflicts
                 */
 
-               BUG_ON(request_wiphy->regd);
+               /*
+                * Userspace could have sent two replies with only
+                * one kernel request.
+                */
+               if (request_wiphy->regd)
+                       return -EALREADY;
 
                r = reg_copy_regd(&request_wiphy->regd, rd);
                if (r)
@@ -2042,7 +2176,13 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
         * the country IE rd with what CRDA believes that country should have
         */
 
-       BUG_ON(!country_ie_regdomain);
+       /*
+        * Userspace could have sent two replies with only
+        * one kernel request. By the second reply we would have
+        * already processed and consumed the country_ie_regdomain.
+        */
+       if (!country_ie_regdomain)
+               return -EALREADY;
        BUG_ON(rd == country_ie_regdomain);
 
        /*
@@ -2119,14 +2259,14 @@ void reg_device_remove(struct wiphy *wiphy)
 
        assert_cfg80211_lock();
 
+       kfree(wiphy->regd);
+
        if (last_request)
                request_wiphy = wiphy_idx_to_wiphy(last_request->wiphy_idx);
 
-       kfree(wiphy->regd);
-       if (!last_request || !request_wiphy)
-               return;
-       if (request_wiphy != wiphy)
+       if (!request_wiphy || request_wiphy != wiphy)
                return;
+
        last_request->wiphy_idx = WIPHY_IDX_STALE;
        last_request->country_ie_env = ENVIRON_ANY;
 }
index 1f260c40b6ca478954e6a67e8b65cdfb33a2666c..e95b638b919f5dba4203a0959c0437fd612f239e 100644 (file)
@@ -29,13 +29,14 @@ void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted)
                goto out;
 
        WARN_ON(request != wiphy_to_dev(request->wiphy)->scan_req);
-       wiphy_to_dev(request->wiphy)->scan_req = NULL;
 
        if (aborted)
                nl80211_send_scan_aborted(wiphy_to_dev(request->wiphy), dev);
        else
                nl80211_send_scan_done(wiphy_to_dev(request->wiphy), dev);
 
+       wiphy_to_dev(request->wiphy)->scan_req = NULL;
+
 #ifdef CONFIG_WIRELESS_EXT
        if (!aborted) {
                memset(&wrqu, 0, sizeof(wrqu));
@@ -377,18 +378,16 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev,
                        size_t used = dev->wiphy.bss_priv_size + sizeof(*res);
                        size_t ielen = res->pub.len_information_elements;
 
-                       if (ksize(found) >= used + ielen) {
+                       if (!found->ies_allocated && ksize(found) >= used + ielen) {
                                memcpy(found->pub.information_elements,
                                       res->pub.information_elements, ielen);
                                found->pub.len_information_elements = ielen;
                        } else {
                                u8 *ies = found->pub.information_elements;
 
-                               if (found->ies_allocated) {
-                                       if (ksize(ies) < ielen)
-                                               ies = krealloc(ies, ielen,
-                                                              GFP_ATOMIC);
-                               } else
+                               if (found->ies_allocated)
+                                       ies = krealloc(ies, ielen, GFP_ATOMIC);
+                               else
                                        ies = kmalloc(ielen, GFP_ATOMIC);
 
                                if (ies) {
@@ -415,6 +414,55 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev,
        return found;
 }
 
+struct cfg80211_bss*
+cfg80211_inform_bss(struct wiphy *wiphy,
+                   struct ieee80211_channel *channel,
+                   const u8 *bssid,
+                   u64 timestamp, u16 capability, u16 beacon_interval,
+                   const u8 *ie, size_t ielen,
+                   s32 signal, gfp_t gfp)
+{
+       struct cfg80211_internal_bss *res;
+       size_t privsz;
+
+       if (WARN_ON(!wiphy))
+               return NULL;
+
+       privsz = wiphy->bss_priv_size;
+
+       if (WARN_ON(wiphy->signal_type == NL80211_BSS_SIGNAL_UNSPEC &&
+                       (signal < 0 || signal > 100)))
+               return NULL;
+
+       res = kzalloc(sizeof(*res) + privsz + ielen, gfp);
+       if (!res)
+               return NULL;
+
+       memcpy(res->pub.bssid, bssid, ETH_ALEN);
+       res->pub.channel = channel;
+       res->pub.signal = signal;
+       res->pub.tsf = timestamp;
+       res->pub.beacon_interval = beacon_interval;
+       res->pub.capability = capability;
+       /* point to after the private area */
+       res->pub.information_elements = (u8 *)res + sizeof(*res) + privsz;
+       memcpy(res->pub.information_elements, ie, ielen);
+       res->pub.len_information_elements = ielen;
+
+       kref_init(&res->ref);
+
+       res = cfg80211_bss_update(wiphy_to_dev(wiphy), res, 0);
+       if (!res)
+               return NULL;
+
+       if (res->pub.capability & WLAN_CAPABILITY_ESS)
+               regulatory_hint_found_beacon(wiphy, channel, gfp);
+
+       /* cfg80211_bss_update gives us a referenced result */
+       return &res->pub;
+}
+EXPORT_SYMBOL(cfg80211_inform_bss);
+
 struct cfg80211_bss *
 cfg80211_inform_bss_frame(struct wiphy *wiphy,
                          struct ieee80211_channel *channel,
@@ -605,7 +653,7 @@ int cfg80211_wext_siwscan(struct net_device *dev,
        cfg80211_put_dev(rdev);
        return err;
 }
-EXPORT_SYMBOL(cfg80211_wext_siwscan);
+EXPORT_SYMBOL_GPL(cfg80211_wext_siwscan);
 
 static void ieee80211_scan_add_ies(struct iw_request_info *info,
                                   struct cfg80211_bss *bss,
@@ -914,5 +962,5 @@ int cfg80211_wext_giwscan(struct net_device *dev,
        cfg80211_put_dev(rdev);
        return res;
 }
-EXPORT_SYMBOL(cfg80211_wext_giwscan);
+EXPORT_SYMBOL_GPL(cfg80211_wext_giwscan);
 #endif
index 487cdd9bcffcb0137fb3f6dd04db210c005eae06..25550692dda6b7a4112adebfa28d2666666c79d3 100644 (file)
@@ -1,10 +1,12 @@
 /*
  * Wireless utility functions
  *
- * Copyright 2007      Johannes Berg <johannes@sipsolutions.net>
+ * Copyright 2007-2009 Johannes Berg <johannes@sipsolutions.net>
  */
-#include <net/wireless.h>
-#include <asm/bitops.h>
+#include <linux/bitops.h>
+#include <linux/etherdevice.h>
+#include <net/cfg80211.h>
+#include <net/ip.h>
 #include "core.h"
 
 struct ieee80211_rate *
@@ -138,3 +140,365 @@ void ieee80211_set_bitrate_flags(struct wiphy *wiphy)
                if (wiphy->bands[band])
                        set_mandatory_flags_band(wiphy->bands[band], band);
 }
+
+int cfg80211_validate_key_settings(struct key_params *params, int key_idx,
+                                  const u8 *mac_addr)
+{
+       if (key_idx > 5)
+               return -EINVAL;
+
+       /*
+        * Disallow pairwise keys with non-zero index unless it's WEP
+        * (because current deployments use pairwise WEP keys with
+        * non-zero indizes but 802.11i clearly specifies to use zero)
+        */
+       if (mac_addr && key_idx &&
+           params->cipher != WLAN_CIPHER_SUITE_WEP40 &&
+           params->cipher != WLAN_CIPHER_SUITE_WEP104)
+               return -EINVAL;
+
+       switch (params->cipher) {
+       case WLAN_CIPHER_SUITE_WEP40:
+               if (params->key_len != WLAN_KEY_LEN_WEP40)
+                       return -EINVAL;
+               break;
+       case WLAN_CIPHER_SUITE_TKIP:
+               if (params->key_len != WLAN_KEY_LEN_TKIP)
+                       return -EINVAL;
+               break;
+       case WLAN_CIPHER_SUITE_CCMP:
+               if (params->key_len != WLAN_KEY_LEN_CCMP)
+                       return -EINVAL;
+               break;
+       case WLAN_CIPHER_SUITE_WEP104:
+               if (params->key_len != WLAN_KEY_LEN_WEP104)
+                       return -EINVAL;
+               break;
+       case WLAN_CIPHER_SUITE_AES_CMAC:
+               if (params->key_len != WLAN_KEY_LEN_AES_CMAC)
+                       return -EINVAL;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       if (params->seq) {
+               switch (params->cipher) {
+               case WLAN_CIPHER_SUITE_WEP40:
+               case WLAN_CIPHER_SUITE_WEP104:
+                       /* These ciphers do not use key sequence */
+                       return -EINVAL;
+               case WLAN_CIPHER_SUITE_TKIP:
+               case WLAN_CIPHER_SUITE_CCMP:
+               case WLAN_CIPHER_SUITE_AES_CMAC:
+                       if (params->seq_len != 6)
+                               return -EINVAL;
+                       break;
+               }
+       }
+
+       return 0;
+}
+
+/* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */
+/* Ethernet-II snap header (RFC1042 for most EtherTypes) */
+const unsigned char rfc1042_header[] __aligned(2) =
+       { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
+EXPORT_SYMBOL(rfc1042_header);
+
+/* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */
+const unsigned char bridge_tunnel_header[] __aligned(2) =
+       { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
+EXPORT_SYMBOL(bridge_tunnel_header);
+
+unsigned int ieee80211_hdrlen(__le16 fc)
+{
+       unsigned int hdrlen = 24;
+
+       if (ieee80211_is_data(fc)) {
+               if (ieee80211_has_a4(fc))
+                       hdrlen = 30;
+               if (ieee80211_is_data_qos(fc))
+                       hdrlen += IEEE80211_QOS_CTL_LEN;
+               goto out;
+       }
+
+       if (ieee80211_is_ctl(fc)) {
+               /*
+                * ACK and CTS are 10 bytes, all others 16. To see how
+                * to get this condition consider
+                *   subtype mask:   0b0000000011110000 (0x00F0)
+                *   ACK subtype:    0b0000000011010000 (0x00D0)
+                *   CTS subtype:    0b0000000011000000 (0x00C0)
+                *   bits that matter:         ^^^      (0x00E0)
+                *   value of those: 0b0000000011000000 (0x00C0)
+                */
+               if ((fc & cpu_to_le16(0x00E0)) == cpu_to_le16(0x00C0))
+                       hdrlen = 10;
+               else
+                       hdrlen = 16;
+       }
+out:
+       return hdrlen;
+}
+EXPORT_SYMBOL(ieee80211_hdrlen);
+
+unsigned int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb)
+{
+       const struct ieee80211_hdr *hdr =
+                       (const struct ieee80211_hdr *)skb->data;
+       unsigned int hdrlen;
+
+       if (unlikely(skb->len < 10))
+               return 0;
+       hdrlen = ieee80211_hdrlen(hdr->frame_control);
+       if (unlikely(hdrlen > skb->len))
+               return 0;
+       return hdrlen;
+}
+EXPORT_SYMBOL(ieee80211_get_hdrlen_from_skb);
+
+static int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr)
+{
+       int ae = meshhdr->flags & MESH_FLAGS_AE;
+       /* 7.1.3.5a.2 */
+       switch (ae) {
+       case 0:
+               return 6;
+       case 1:
+               return 12;
+       case 2:
+               return 18;
+       case 3:
+               return 24;
+       default:
+               return 6;
+       }
+}
+
+int ieee80211_data_to_8023(struct sk_buff *skb, u8 *addr,
+                          enum nl80211_iftype iftype)
+{
+       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+       u16 hdrlen, ethertype;
+       u8 *payload;
+       u8 dst[ETH_ALEN];
+       u8 src[ETH_ALEN] __aligned(2);
+
+       if (unlikely(!ieee80211_is_data_present(hdr->frame_control)))
+               return -1;
+
+       hdrlen = ieee80211_hdrlen(hdr->frame_control);
+
+       /* convert IEEE 802.11 header + possible LLC headers into Ethernet
+        * header
+        * IEEE 802.11 address fields:
+        * ToDS FromDS Addr1 Addr2 Addr3 Addr4
+        *   0     0   DA    SA    BSSID n/a
+        *   0     1   DA    BSSID SA    n/a
+        *   1     0   BSSID SA    DA    n/a
+        *   1     1   RA    TA    DA    SA
+        */
+       memcpy(dst, ieee80211_get_DA(hdr), ETH_ALEN);
+       memcpy(src, ieee80211_get_SA(hdr), ETH_ALEN);
+
+       switch (hdr->frame_control &
+               cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) {
+       case cpu_to_le16(IEEE80211_FCTL_TODS):
+               if (unlikely(iftype != NL80211_IFTYPE_AP &&
+                            iftype != NL80211_IFTYPE_AP_VLAN))
+                       return -1;
+               break;
+       case cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS):
+               if (unlikely(iftype != NL80211_IFTYPE_WDS &&
+                            iftype != NL80211_IFTYPE_MESH_POINT))
+                       return -1;
+               if (iftype == NL80211_IFTYPE_MESH_POINT) {
+                       struct ieee80211s_hdr *meshdr =
+                               (struct ieee80211s_hdr *) (skb->data + hdrlen);
+                       hdrlen += ieee80211_get_mesh_hdrlen(meshdr);
+                       if (meshdr->flags & MESH_FLAGS_AE_A5_A6) {
+                               memcpy(dst, meshdr->eaddr1, ETH_ALEN);
+                               memcpy(src, meshdr->eaddr2, ETH_ALEN);
+                       }
+               }
+               break;
+       case cpu_to_le16(IEEE80211_FCTL_FROMDS):
+               if (iftype != NL80211_IFTYPE_STATION ||
+                   (is_multicast_ether_addr(dst) &&
+                    !compare_ether_addr(src, addr)))
+                       return -1;
+               break;
+       case cpu_to_le16(0):
+               if (iftype != NL80211_IFTYPE_ADHOC)
+                       return -1;
+               break;
+       }
+
+       if (unlikely(skb->len - hdrlen < 8))
+               return -1;
+
+       payload = skb->data + hdrlen;
+       ethertype = (payload[6] << 8) | payload[7];
+
+       if (likely((compare_ether_addr(payload, rfc1042_header) == 0 &&
+                   ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) ||
+                  compare_ether_addr(payload, bridge_tunnel_header) == 0)) {
+               /* remove RFC1042 or Bridge-Tunnel encapsulation and
+                * replace EtherType */
+               skb_pull(skb, hdrlen + 6);
+               memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN);
+               memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN);
+       } else {
+               struct ethhdr *ehdr;
+               __be16 len;
+
+               skb_pull(skb, hdrlen);
+               len = htons(skb->len);
+               ehdr = (struct ethhdr *) skb_push(skb, sizeof(struct ethhdr));
+               memcpy(ehdr->h_dest, dst, ETH_ALEN);
+               memcpy(ehdr->h_source, src, ETH_ALEN);
+               ehdr->h_proto = len;
+       }
+       return 0;
+}
+EXPORT_SYMBOL(ieee80211_data_to_8023);
+
+int ieee80211_data_from_8023(struct sk_buff *skb, u8 *addr,
+                            enum nl80211_iftype iftype, u8 *bssid, bool qos)
+{
+       struct ieee80211_hdr hdr;
+       u16 hdrlen, ethertype;
+       __le16 fc;
+       const u8 *encaps_data;
+       int encaps_len, skip_header_bytes;
+       int nh_pos, h_pos;
+       int head_need;
+
+       if (unlikely(skb->len < ETH_HLEN))
+               return -EINVAL;
+
+       nh_pos = skb_network_header(skb) - skb->data;
+       h_pos = skb_transport_header(skb) - skb->data;
+
+       /* convert Ethernet header to proper 802.11 header (based on
+        * operation mode) */
+       ethertype = (skb->data[12] << 8) | skb->data[13];
+       fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA);
+
+       switch (iftype) {
+       case NL80211_IFTYPE_AP:
+       case NL80211_IFTYPE_AP_VLAN:
+               fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS);
+               /* DA BSSID SA */
+               memcpy(hdr.addr1, skb->data, ETH_ALEN);
+               memcpy(hdr.addr2, addr, ETH_ALEN);
+               memcpy(hdr.addr3, skb->data + ETH_ALEN, ETH_ALEN);
+               hdrlen = 24;
+               break;
+       case NL80211_IFTYPE_STATION:
+               fc |= cpu_to_le16(IEEE80211_FCTL_TODS);
+               /* BSSID SA DA */
+               memcpy(hdr.addr1, bssid, ETH_ALEN);
+               memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN);
+               memcpy(hdr.addr3, skb->data, ETH_ALEN);
+               hdrlen = 24;
+               break;
+       case NL80211_IFTYPE_ADHOC:
+               /* DA SA BSSID */
+               memcpy(hdr.addr1, skb->data, ETH_ALEN);
+               memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN);
+               memcpy(hdr.addr3, bssid, ETH_ALEN);
+               hdrlen = 24;
+               break;
+       default:
+               return -EOPNOTSUPP;
+       }
+
+       if (qos) {
+               fc |= cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
+               hdrlen += 2;
+       }
+
+       hdr.frame_control = fc;
+       hdr.duration_id = 0;
+       hdr.seq_ctrl = 0;
+
+       skip_header_bytes = ETH_HLEN;
+       if (ethertype == ETH_P_AARP || ethertype == ETH_P_IPX) {
+               encaps_data = bridge_tunnel_header;
+               encaps_len = sizeof(bridge_tunnel_header);
+               skip_header_bytes -= 2;
+       } else if (ethertype > 0x600) {
+               encaps_data = rfc1042_header;
+               encaps_len = sizeof(rfc1042_header);
+               skip_header_bytes -= 2;
+       } else {
+               encaps_data = NULL;
+               encaps_len = 0;
+       }
+
+       skb_pull(skb, skip_header_bytes);
+       nh_pos -= skip_header_bytes;
+       h_pos -= skip_header_bytes;
+
+       head_need = hdrlen + encaps_len - skb_headroom(skb);
+
+       if (head_need > 0 || skb_cloned(skb)) {
+               head_need = max(head_need, 0);
+               if (head_need)
+                       skb_orphan(skb);
+
+               if (pskb_expand_head(skb, head_need, 0, GFP_ATOMIC)) {
+                       printk(KERN_ERR "failed to reallocate Tx buffer\n");
+                       return -ENOMEM;
+               }
+               skb->truesize += head_need;
+       }
+
+       if (encaps_data) {
+               memcpy(skb_push(skb, encaps_len), encaps_data, encaps_len);
+               nh_pos += encaps_len;
+               h_pos += encaps_len;
+       }
+
+       memcpy(skb_push(skb, hdrlen), &hdr, hdrlen);
+
+       nh_pos += hdrlen;
+       h_pos += hdrlen;
+
+       /* Update skb pointers to various headers since this modified frame
+        * is going to go through Linux networking code that may potentially
+        * need things like pointer to IP header. */
+       skb_set_mac_header(skb, 0);
+       skb_set_network_header(skb, nh_pos);
+       skb_set_transport_header(skb, h_pos);
+
+       return 0;
+}
+EXPORT_SYMBOL(ieee80211_data_from_8023);
+
+/* Given a data frame determine the 802.1p/1d tag to use. */
+unsigned int cfg80211_classify8021d(struct sk_buff *skb)
+{
+       unsigned int dscp;
+
+       /* skb->priority values from 256->263 are magic values to
+        * directly indicate a specific 802.1d priority.  This is used
+        * to allow 802.1d priority to be passed directly in from VLAN
+        * tags, etc.
+        */
+       if (skb->priority >= 256 && skb->priority <= 263)
+               return skb->priority - 256;
+
+       switch (skb->protocol) {
+       case htons(ETH_P_IP):
+               dscp = ip_hdr(skb)->tos & 0xfc;
+               break;
+       default:
+               return 0;
+       }
+
+       return dscp >> 5;
+}
+EXPORT_SYMBOL(cfg80211_classify8021d);
index 0fd1db6e95bbe26ef13a9d3524a42ff5765d97c9..d030c5315672817c120e0b6035ad77715637610b 100644 (file)
@@ -5,13 +5,14 @@
  * into cfg80211, when that happens all the exports here go away and
  * we directly assign the wireless handlers of wireless interfaces.
  *
- * Copyright 2008      Johannes Berg <johannes@sipsolutions.net>
+ * Copyright 2008-2009 Johannes Berg <johannes@sipsolutions.net>
  */
 
 #include <linux/wireless.h>
 #include <linux/nl80211.h>
+#include <linux/if_arp.h>
+#include <linux/etherdevice.h>
 #include <net/iw_handler.h>
-#include <net/wireless.h>
 #include <net/cfg80211.h>
 #include "core.h"
 
@@ -57,7 +58,7 @@ int cfg80211_wext_giwname(struct net_device *dev,
 
        return 0;
 }
-EXPORT_SYMBOL(cfg80211_wext_giwname);
+EXPORT_SYMBOL_GPL(cfg80211_wext_giwname);
 
 int cfg80211_wext_siwmode(struct net_device *dev, struct iw_request_info *info,
                          u32 *mode, char *extra)
@@ -108,7 +109,7 @@ int cfg80211_wext_siwmode(struct net_device *dev, struct iw_request_info *info,
 
        return ret;
 }
-EXPORT_SYMBOL(cfg80211_wext_siwmode);
+EXPORT_SYMBOL_GPL(cfg80211_wext_siwmode);
 
 int cfg80211_wext_giwmode(struct net_device *dev, struct iw_request_info *info,
                          u32 *mode, char *extra)
@@ -143,7 +144,7 @@ int cfg80211_wext_giwmode(struct net_device *dev, struct iw_request_info *info,
        }
        return 0;
 }
-EXPORT_SYMBOL(cfg80211_wext_giwmode);
+EXPORT_SYMBOL_GPL(cfg80211_wext_giwmode);
 
 
 int cfg80211_wext_giwrange(struct net_device *dev,
@@ -206,7 +207,6 @@ int cfg80211_wext_giwrange(struct net_device *dev,
        range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
                          IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
 
-
        for (band = 0; band < IEEE80211_NUM_BANDS; band ++) {
                int i;
                struct ieee80211_supported_band *sband;
@@ -240,4 +240,590 @@ int cfg80211_wext_giwrange(struct net_device *dev,
 
        return 0;
 }
-EXPORT_SYMBOL(cfg80211_wext_giwrange);
+EXPORT_SYMBOL_GPL(cfg80211_wext_giwrange);
+
+int cfg80211_wext_siwmlme(struct net_device *dev,
+                         struct iw_request_info *info,
+                         struct iw_point *data, char *extra)
+{
+       struct wireless_dev *wdev = dev->ieee80211_ptr;
+       struct iw_mlme *mlme = (struct iw_mlme *)extra;
+       struct cfg80211_registered_device *rdev;
+       union {
+               struct cfg80211_disassoc_request disassoc;
+               struct cfg80211_deauth_request deauth;
+       } cmd;
+
+       if (!wdev)
+               return -EOPNOTSUPP;
+
+       rdev = wiphy_to_dev(wdev->wiphy);
+
+       if (wdev->iftype != NL80211_IFTYPE_STATION)
+               return -EINVAL;
+
+       if (mlme->addr.sa_family != ARPHRD_ETHER)
+               return -EINVAL;
+
+       memset(&cmd, 0, sizeof(cmd));
+
+       switch (mlme->cmd) {
+       case IW_MLME_DEAUTH:
+               if (!rdev->ops->deauth)
+                       return -EOPNOTSUPP;
+               cmd.deauth.peer_addr = mlme->addr.sa_data;
+               cmd.deauth.reason_code = mlme->reason_code;
+               return rdev->ops->deauth(wdev->wiphy, dev, &cmd.deauth);
+       case IW_MLME_DISASSOC:
+               if (!rdev->ops->disassoc)
+                       return -EOPNOTSUPP;
+               cmd.disassoc.peer_addr = mlme->addr.sa_data;
+               cmd.disassoc.reason_code = mlme->reason_code;
+               return rdev->ops->disassoc(wdev->wiphy, dev, &cmd.disassoc);
+       default:
+               return -EOPNOTSUPP;
+       }
+}
+EXPORT_SYMBOL_GPL(cfg80211_wext_siwmlme);
+
+
+/**
+ * cfg80211_wext_freq - get wext frequency for non-"auto"
+ * @wiphy: the wiphy
+ * @freq: the wext freq encoding
+ *
+ * Returns a channel, %NULL for auto, or an ERR_PTR for errors!
+ */
+struct ieee80211_channel *cfg80211_wext_freq(struct wiphy *wiphy,
+                                            struct iw_freq *freq)
+{
+       struct ieee80211_channel *chan;
+       int f;
+
+       /*
+        * Parse frequency - return NULL for auto and
+        * -EINVAL for impossible things.
+        */
+       if (freq->e == 0) {
+               if (freq->m < 0)
+                       return NULL;
+               f = ieee80211_channel_to_frequency(freq->m);
+       } else {
+               int i, div = 1000000;
+               for (i = 0; i < freq->e; i++)
+                       div /= 10;
+               if (div <= 0)
+                       return ERR_PTR(-EINVAL);
+               f = freq->m / div;
+       }
+
+       /*
+        * Look up channel struct and return -EINVAL when
+        * it cannot be found.
+        */
+       chan = ieee80211_get_channel(wiphy, f);
+       if (!chan)
+               return ERR_PTR(-EINVAL);
+       return chan;
+}
+EXPORT_SYMBOL_GPL(cfg80211_wext_freq);
+
+int cfg80211_wext_siwrts(struct net_device *dev,
+                        struct iw_request_info *info,
+                        struct iw_param *rts, char *extra)
+{
+       struct wireless_dev *wdev = dev->ieee80211_ptr;
+       struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
+       u32 orts = wdev->wiphy->rts_threshold;
+       int err;
+
+       if (rts->disabled || !rts->fixed)
+               wdev->wiphy->rts_threshold = (u32) -1;
+       else if (rts->value < 0)
+               return -EINVAL;
+       else
+               wdev->wiphy->rts_threshold = rts->value;
+
+       err = rdev->ops->set_wiphy_params(wdev->wiphy,
+                                         WIPHY_PARAM_RTS_THRESHOLD);
+       if (err)
+               wdev->wiphy->rts_threshold = orts;
+
+       return err;
+}
+EXPORT_SYMBOL_GPL(cfg80211_wext_siwrts);
+
+int cfg80211_wext_giwrts(struct net_device *dev,
+                        struct iw_request_info *info,
+                        struct iw_param *rts, char *extra)
+{
+       struct wireless_dev *wdev = dev->ieee80211_ptr;
+
+       rts->value = wdev->wiphy->rts_threshold;
+       rts->disabled = rts->value == (u32) -1;
+       rts->fixed = 1;
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(cfg80211_wext_giwrts);
+
+int cfg80211_wext_siwfrag(struct net_device *dev,
+                         struct iw_request_info *info,
+                         struct iw_param *frag, char *extra)
+{
+       struct wireless_dev *wdev = dev->ieee80211_ptr;
+       struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
+       u32 ofrag = wdev->wiphy->frag_threshold;
+       int err;
+
+       if (frag->disabled || !frag->fixed)
+               wdev->wiphy->frag_threshold = (u32) -1;
+       else if (frag->value < 256)
+               return -EINVAL;
+       else {
+               /* Fragment length must be even, so strip LSB. */
+               wdev->wiphy->frag_threshold = frag->value & ~0x1;
+       }
+
+       err = rdev->ops->set_wiphy_params(wdev->wiphy,
+                                         WIPHY_PARAM_FRAG_THRESHOLD);
+       if (err)
+               wdev->wiphy->frag_threshold = ofrag;
+
+       return err;
+}
+EXPORT_SYMBOL_GPL(cfg80211_wext_siwfrag);
+
+int cfg80211_wext_giwfrag(struct net_device *dev,
+                         struct iw_request_info *info,
+                         struct iw_param *frag, char *extra)
+{
+       struct wireless_dev *wdev = dev->ieee80211_ptr;
+
+       frag->value = wdev->wiphy->frag_threshold;
+       frag->disabled = frag->value == (u32) -1;
+       frag->fixed = 1;
+
+       return 0;
+}
+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)
+{
+       struct wireless_dev *wdev = dev->ieee80211_ptr;
+       struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
+       u32 changed = 0;
+       u8 olong = wdev->wiphy->retry_long;
+       u8 oshort = wdev->wiphy->retry_short;
+       int err;
+
+       if (retry->disabled ||
+           (retry->flags & IW_RETRY_TYPE) != IW_RETRY_LIMIT)
+               return -EINVAL;
+
+       if (retry->flags & IW_RETRY_LONG) {
+               wdev->wiphy->retry_long = retry->value;
+               changed |= WIPHY_PARAM_RETRY_LONG;
+       } else if (retry->flags & IW_RETRY_SHORT) {
+               wdev->wiphy->retry_short = retry->value;
+               changed |= WIPHY_PARAM_RETRY_SHORT;
+       } else {
+               wdev->wiphy->retry_short = retry->value;
+               wdev->wiphy->retry_long = retry->value;
+               changed |= WIPHY_PARAM_RETRY_LONG;
+               changed |= WIPHY_PARAM_RETRY_SHORT;
+       }
+
+       if (!changed)
+               return 0;
+
+       err = rdev->ops->set_wiphy_params(wdev->wiphy, changed);
+       if (err) {
+               wdev->wiphy->retry_short = oshort;
+               wdev->wiphy->retry_long = olong;
+       }
+
+       return err;
+}
+EXPORT_SYMBOL_GPL(cfg80211_wext_siwretry);
+
+int cfg80211_wext_giwretry(struct net_device *dev,
+                          struct iw_request_info *info,
+                          struct iw_param *retry, char *extra)
+{
+       struct wireless_dev *wdev = dev->ieee80211_ptr;
+
+       retry->disabled = 0;
+
+       if (retry->flags == 0 || (retry->flags & IW_RETRY_SHORT)) {
+               /*
+                * First return short value, iwconfig will ask long value
+                * later if needed
+                */
+               retry->flags |= IW_RETRY_LIMIT;
+               retry->value = wdev->wiphy->retry_short;
+               if (wdev->wiphy->retry_long != wdev->wiphy->retry_short)
+                       retry->flags |= IW_RETRY_LONG;
+
+               return 0;
+       }
+
+       if (retry->flags & IW_RETRY_LONG) {
+               retry->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
+               retry->value = wdev->wiphy->retry_long;
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(cfg80211_wext_giwretry);
+
+static int cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
+                                  struct net_device *dev, const u8 *addr,
+                                  bool remove, bool tx_key, int idx,
+                                  struct key_params *params)
+{
+       struct wireless_dev *wdev = dev->ieee80211_ptr;
+       int err;
+
+       if (params->cipher == WLAN_CIPHER_SUITE_AES_CMAC) {
+               if (!rdev->ops->set_default_mgmt_key)
+                       return -EOPNOTSUPP;
+
+               if (idx < 4 || idx > 5)
+                       return -EINVAL;
+       } else if (idx < 0 || idx > 3)
+               return -EINVAL;
+
+       if (remove) {
+               err = rdev->ops->del_key(&rdev->wiphy, dev, idx, addr);
+               if (!err) {
+                       if (idx == wdev->wext.default_key)
+                               wdev->wext.default_key = -1;
+                       else if (idx == wdev->wext.default_mgmt_key)
+                               wdev->wext.default_mgmt_key = -1;
+               }
+               /*
+                * Applications using wireless extensions expect to be
+                * able to delete keys that don't exist, so allow that.
+                */
+               if (err == -ENOENT)
+                       return 0;
+
+               return err;
+       } else {
+               if (addr)
+                       tx_key = false;
+
+               if (cfg80211_validate_key_settings(params, idx, addr))
+                       return -EINVAL;
+
+               err = rdev->ops->add_key(&rdev->wiphy, dev, idx, addr, params);
+               if (err)
+                       return err;
+
+               if (tx_key || (!addr && wdev->wext.default_key == -1)) {
+                       err = rdev->ops->set_default_key(&rdev->wiphy,
+                                                        dev, idx);
+                       if (!err)
+                               wdev->wext.default_key = idx;
+                       return err;
+               }
+
+               if (params->cipher == WLAN_CIPHER_SUITE_AES_CMAC &&
+                   (tx_key || (!addr && wdev->wext.default_mgmt_key == -1))) {
+                       err = rdev->ops->set_default_mgmt_key(&rdev->wiphy,
+                                                             dev, idx);
+                       if (!err)
+                               wdev->wext.default_mgmt_key = idx;
+                       return err;
+               }
+
+               return 0;
+       }
+}
+
+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);
+       int idx, err;
+       bool remove = false;
+       struct key_params params;
+
+       /* no use -- only MFP (set_default_mgmt_key) is optional */
+       if (!rdev->ops->del_key ||
+           !rdev->ops->add_key ||
+           !rdev->ops->set_default_key)
+               return -EOPNOTSUPP;
+
+       idx = erq->flags & IW_ENCODE_INDEX;
+       if (idx == 0) {
+               idx = wdev->wext.default_key;
+               if (idx < 0)
+                       idx = 0;
+       } else if (idx < 1 || idx > 4)
+               return -EINVAL;
+       else
+               idx--;
+
+       if (erq->flags & IW_ENCODE_DISABLED)
+               remove = true;
+       else if (erq->length == 0) {
+               /* No key data - just set the default TX key index */
+               err = rdev->ops->set_default_key(&rdev->wiphy, dev, idx);
+               if (!err)
+                       wdev->wext.default_key = idx;
+               return err;
+       }
+
+       memset(&params, 0, sizeof(params));
+       params.key = keybuf;
+       params.key_len = erq->length;
+       if (erq->length == 5)
+               params.cipher = WLAN_CIPHER_SUITE_WEP40;
+       else if (erq->length == 13)
+               params.cipher = WLAN_CIPHER_SUITE_WEP104;
+       else if (!remove)
+               return -EINVAL;
+
+       return cfg80211_set_encryption(rdev, dev, NULL, remove,
+                                      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)
+{
+       struct wireless_dev *wdev = dev->ieee80211_ptr;
+       struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
+       struct iw_encode_ext *ext = (struct iw_encode_ext *) extra;
+       const u8 *addr;
+       int idx;
+       bool remove = false;
+       struct key_params params;
+       u32 cipher;
+
+       /* no use -- only MFP (set_default_mgmt_key) is optional */
+       if (!rdev->ops->del_key ||
+           !rdev->ops->add_key ||
+           !rdev->ops->set_default_key)
+               return -EOPNOTSUPP;
+
+       switch (ext->alg) {
+       case IW_ENCODE_ALG_NONE:
+               remove = true;
+               cipher = 0;
+               break;
+       case IW_ENCODE_ALG_WEP:
+               if (ext->key_len == 5)
+                       cipher = WLAN_CIPHER_SUITE_WEP40;
+               else if (ext->key_len == 13)
+                       cipher = WLAN_CIPHER_SUITE_WEP104;
+               else
+                       return -EINVAL;
+               break;
+       case IW_ENCODE_ALG_TKIP:
+               cipher = WLAN_CIPHER_SUITE_TKIP;
+               break;
+       case IW_ENCODE_ALG_CCMP:
+               cipher = WLAN_CIPHER_SUITE_CCMP;
+               break;
+       case IW_ENCODE_ALG_AES_CMAC:
+               cipher = WLAN_CIPHER_SUITE_AES_CMAC;
+               break;
+       default:
+               return -EOPNOTSUPP;
+       }
+
+       if (erq->flags & IW_ENCODE_DISABLED)
+               remove = true;
+
+       idx = erq->flags & IW_ENCODE_INDEX;
+       if (cipher == WLAN_CIPHER_SUITE_AES_CMAC) {
+               if (idx < 4 || idx > 5) {
+                       idx = wdev->wext.default_mgmt_key;
+                       if (idx < 0)
+                               return -EINVAL;
+               } else
+                       idx--;
+       } else {
+               if (idx < 1 || idx > 4) {
+                       idx = wdev->wext.default_key;
+                       if (idx < 0)
+                               return -EINVAL;
+               } else
+                       idx--;
+       }
+
+       addr = ext->addr.sa_data;
+       if (is_broadcast_ether_addr(addr))
+               addr = NULL;
+
+       memset(&params, 0, sizeof(params));
+       params.key = ext->key;
+       params.key_len = ext->key_len;
+       params.cipher = cipher;
+
+       if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) {
+               params.seq = ext->rx_seq;
+               params.seq_len = 6;
+       }
+
+       return cfg80211_set_encryption(
+                       rdev, dev, addr, remove,
+                       ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY,
+                       idx, &params);
+}
+EXPORT_SYMBOL_GPL(cfg80211_wext_siwencodeext);
+
+struct giwencode_cookie {
+       size_t buflen;
+       char *keybuf;
+};
+
+static void giwencode_get_key_cb(void *cookie, struct key_params *params)
+{
+       struct giwencode_cookie *data = cookie;
+
+       if (!params->key) {
+               data->buflen = 0;
+               return;
+       }
+
+       data->buflen = min_t(size_t, data->buflen, params->key_len);
+       memcpy(data->keybuf, params->key, data->buflen);
+}
+
+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;
+       struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
+       int idx, err;
+       struct giwencode_cookie data = {
+               .keybuf = keybuf,
+               .buflen = erq->length,
+       };
+
+       if (!rdev->ops->get_key)
+               return -EOPNOTSUPP;
+
+       idx = erq->flags & IW_ENCODE_INDEX;
+       if (idx == 0) {
+               idx = wdev->wext.default_key;
+               if (idx < 0)
+                       idx = 0;
+       } else if (idx < 1 || idx > 4)
+               return -EINVAL;
+       else
+               idx--;
+
+       erq->flags = idx + 1;
+
+       err = rdev->ops->get_key(&rdev->wiphy, dev, idx, NULL, &data,
+                                giwencode_get_key_cb);
+       if (!err) {
+               erq->length = data.buflen;
+               erq->flags |= IW_ENCODE_ENABLED;
+               return 0;
+       }
+
+       if (err == -ENOENT) {
+               erq->flags |= IW_ENCODE_DISABLED;
+               erq->length = 0;
+               return 0;
+       }
+
+       return err;
+}
+EXPORT_SYMBOL_GPL(cfg80211_wext_giwencode);
+
+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);
+       enum tx_power_setting type;
+       int dbm = 0;
+
+       if ((data->txpower.flags & IW_TXPOW_TYPE) != IW_TXPOW_DBM)
+               return -EINVAL;
+       if (data->txpower.flags & IW_TXPOW_RANGE)
+               return -EINVAL;
+
+       if (!rdev->ops->set_tx_power)
+               return -EOPNOTSUPP;
+
+       /* only change when not disabling */
+       if (!data->txpower.disabled) {
+               rfkill_set_sw_state(rdev->rfkill, false);
+
+               if (data->txpower.fixed) {
+                       /*
+                        * wext doesn't support negative values, see
+                        * below where it's for automatic
+                        */
+                       if (data->txpower.value < 0)
+                               return -EINVAL;
+                       dbm = data->txpower.value;
+                       type = TX_POWER_FIXED;
+                       /* TODO: do regulatory check! */
+               } else {
+                       /*
+                        * Automatic power level setting, max being the value
+                        * passed in from userland.
+                        */
+                       if (data->txpower.value < 0) {
+                               type = TX_POWER_AUTOMATIC;
+                       } else {
+                               dbm = data->txpower.value;
+                               type = TX_POWER_LIMITED;
+                       }
+               }
+       } else {
+               rfkill_set_sw_state(rdev->rfkill, true);
+               schedule_work(&rdev->rfkill_sync);
+               return 0;
+       }
+
+       return rdev->ops->set_tx_power(wdev->wiphy, type, 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)
+{
+       struct wireless_dev *wdev = dev->ieee80211_ptr;
+       struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
+       int err, val;
+
+       if ((data->txpower.flags & IW_TXPOW_TYPE) != IW_TXPOW_DBM)
+               return -EINVAL;
+       if (data->txpower.flags & IW_TXPOW_RANGE)
+               return -EINVAL;
+
+       if (!rdev->ops->get_tx_power)
+               return -EOPNOTSUPP;
+
+       err = rdev->ops->get_tx_power(wdev->wiphy, &val);
+       if (err)
+               return err;
+
+       /* well... oh well */
+       data->txpower.fixed = 1;
+       data->txpower.disabled = rfkill_blocked(rdev->rfkill);
+       data->txpower.value = val;
+       data->txpower.flags = IW_TXPOW_DBM;
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(cfg80211_wext_giwtxpower);
index 0e59f9ae9b81fadcff031f044a2b1bfa14e21d3c..252c2010c2e2c05b46c260d380f658c2913ea531 100644 (file)
@@ -636,8 +636,10 @@ static void wireless_seq_printf_stats(struct seq_file *seq,
 /*
  * Print info for /proc/net/wireless (print all entries)
  */
-static int wireless_seq_show(struct seq_file *seq, void *v)
+static int wireless_dev_seq_show(struct seq_file *seq, void *v)
 {
+       might_sleep();
+
        if (v == SEQ_START_TOKEN)
                seq_printf(seq, "Inter-| sta-|   Quality        |   Discarded "
                                "packets               | Missed | WE\n"
@@ -649,14 +651,46 @@ static int wireless_seq_show(struct seq_file *seq, void *v)
        return 0;
 }
 
+static void *wireless_dev_seq_start(struct seq_file *seq, loff_t *pos)
+{
+       struct net *net = seq_file_net(seq);
+       loff_t off;
+       struct net_device *dev;
+
+       rtnl_lock();
+       if (!*pos)
+               return SEQ_START_TOKEN;
+
+       off = 1;
+       for_each_netdev(net, dev)
+               if (off++ == *pos)
+                       return dev;
+       return NULL;
+}
+
+static void *wireless_dev_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+       struct net *net = seq_file_net(seq);
+
+       ++*pos;
+
+       return v == SEQ_START_TOKEN ?
+               first_net_device(net) : next_net_device(v);
+}
+
+static void wireless_dev_seq_stop(struct seq_file *seq, void *v)
+{
+       rtnl_unlock();
+}
+
 static const struct seq_operations wireless_seq_ops = {
-       .start = dev_seq_start,
-       .next  = dev_seq_next,
-       .stop  = dev_seq_stop,
-       .show  = wireless_seq_show,
+       .start = wireless_dev_seq_start,
+       .next  = wireless_dev_seq_next,
+       .stop  = wireless_dev_seq_stop,
+       .show  = wireless_dev_seq_show,
 };
 
-static int wireless_seq_open(struct inode *inode, struct file *file)
+static int seq_open_wireless(struct inode *inode, struct file *file)
 {
        return seq_open_net(inode, file, &wireless_seq_ops,
                            sizeof(struct seq_net_private));
@@ -664,7 +698,7 @@ static int wireless_seq_open(struct inode *inode, struct file *file)
 
 static const struct file_operations wireless_seq_fops = {
        .owner   = THIS_MODULE,
-       .open    = wireless_seq_open,
+       .open    = seq_open_wireless,
        .read    = seq_read,
        .llseek  = seq_lseek,
        .release = seq_release_net,
index 96036cf2216d09c7dea7907c31c73c3b42f5b7cf..d31ccb487730b174a44ae0cc15d53d7fe9106822 100644 (file)
@@ -696,8 +696,9 @@ int skb_icv_walk(const struct sk_buff *skb, struct hash_desc *desc,
 {
        int start = skb_headlen(skb);
        int i, copy = start - offset;
-       int err;
+       struct sk_buff *frag_iter;
        struct scatterlist sg;
+       int err;
 
        /* Checksum header. */
        if (copy > 0) {
@@ -742,28 +743,24 @@ int skb_icv_walk(const struct sk_buff *skb, struct hash_desc *desc,
                start = end;
        }
 
-       if (skb_shinfo(skb)->frag_list) {
-               struct sk_buff *list = skb_shinfo(skb)->frag_list;
-
-               for (; list; list = list->next) {
-                       int end;
-
-                       WARN_ON(start > offset + len);
-
-                       end = start + list->len;
-                       if ((copy = end - offset) > 0) {
-                               if (copy > len)
-                                       copy = len;
-                               err = skb_icv_walk(list, desc, offset-start,
-                                                  copy, icv_update);
-                               if (unlikely(err))
-                                       return err;
-                               if ((len -= copy) == 0)
-                                       return 0;
-                               offset += copy;
-                       }
-                       start = end;
+       skb_walk_frags(skb, frag_iter) {
+               int end;
+
+               WARN_ON(start > offset + len);
+
+               end = start + frag_iter->len;
+               if ((copy = end - offset) > 0) {
+                       if (copy > len)
+                               copy = len;
+                       err = skb_icv_walk(frag_iter, desc, offset-start,
+                                          copy, icv_update);
+                       if (unlikely(err))
+                               return err;
+                       if ((len -= copy) == 0)
+                               return 0;
+                       offset += copy;
                }
+               start = end;
        }
        BUG_ON(len);
        return 0;
index b4a13178fb40176e41d90ff171e971ac7d6f8935..e0009c17d809310e72ceb3207866f52d92107e09 100644 (file)
@@ -251,8 +251,7 @@ resume:
        nf_reset(skb);
 
        if (decaps) {
-               dst_release(skb->dst);
-               skb->dst = NULL;
+               skb_dst_drop(skb);
                netif_rx(skb);
                return 0;
        } else {
index c235597ba8dd9c1f24b7fb6a139a29bee66e5141..b9fe13138c070858980f8fa60334ca9b5990073f 100644 (file)
@@ -22,7 +22,7 @@ static int xfrm_output2(struct sk_buff *skb);
 
 static int xfrm_state_check_space(struct xfrm_state *x, struct sk_buff *skb)
 {
-       struct dst_entry *dst = skb->dst;
+       struct dst_entry *dst = skb_dst(skb);
        int nhead = dst->header_len + LL_RESERVED_SPACE(dst->dev)
                - skb_headroom(skb);
        int ntail = dst->dev->needed_tailroom - skb_tailroom(skb);
@@ -39,7 +39,7 @@ static int xfrm_state_check_space(struct xfrm_state *x, struct sk_buff *skb)
 
 static int xfrm_output_one(struct sk_buff *skb, int err)
 {
-       struct dst_entry *dst = skb->dst;
+       struct dst_entry *dst = skb_dst(skb);
        struct xfrm_state *x = dst->xfrm;
        struct net *net = xs_net(x);
 
@@ -94,12 +94,13 @@ resume:
                        goto error_nolock;
                }
 
-               if (!(skb->dst = dst_pop(dst))) {
+               dst = dst_pop(dst);
+               if (!dst) {
                        XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTERROR);
                        err = -EHOSTUNREACH;
                        goto error_nolock;
                }
-               dst = skb->dst;
+               skb_dst_set(skb, dst);
                x = dst->xfrm;
        } while (x && !(x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL));
 
@@ -119,16 +120,16 @@ int xfrm_output_resume(struct sk_buff *skb, int err)
        while (likely((err = xfrm_output_one(skb, err)) == 0)) {
                nf_reset(skb);
 
-               err = skb->dst->ops->local_out(skb);
+               err = skb_dst(skb)->ops->local_out(skb);
                if (unlikely(err != 1))
                        goto out;
 
-               if (!skb->dst->xfrm)
+               if (!skb_dst(skb)->xfrm)
                        return dst_output(skb);
 
-               err = nf_hook(skb->dst->ops->family,
+               err = nf_hook(skb_dst(skb)->ops->family,
                              NF_INET_POST_ROUTING, skb,
-                             NULL, skb->dst->dev, xfrm_output2);
+                             NULL, skb_dst(skb)->dev, xfrm_output2);
                if (unlikely(err != 1))
                        goto out;
        }
@@ -179,7 +180,7 @@ static int xfrm_output_gso(struct sk_buff *skb)
 
 int xfrm_output(struct sk_buff *skb)
 {
-       struct net *net = dev_net(skb->dst->dev);
+       struct net *net = dev_net(skb_dst(skb)->dev);
        int err;
 
        if (skb_is_gso(skb))
@@ -202,7 +203,7 @@ int xfrm_inner_extract_output(struct xfrm_state *x, struct sk_buff *skb)
        struct xfrm_mode *inner_mode;
        if (x->sel.family == AF_UNSPEC)
                inner_mode = xfrm_ip2inner_mode(x,
-                               xfrm_af2proto(skb->dst->ops->family));
+                               xfrm_af2proto(skb_dst(skb)->ops->family));
        else
                inner_mode = x->inner_mode;
 
index 9c068ab3a834fbb0948e130c0713e6e6edda536b..cb81ca35b0d6eae85ecac2f7967d556971519afb 100644 (file)
@@ -2027,6 +2027,8 @@ int __xfrm_route_forward(struct sk_buff *skb, unsigned short family)
 {
        struct net *net = dev_net(skb->dev);
        struct flowi fl;
+       struct dst_entry *dst;
+       int res;
 
        if (xfrm_decode_session(skb, &fl, family) < 0) {
                /* XXX: we should have something like FWDHDRERROR here. */
@@ -2034,7 +2036,11 @@ int __xfrm_route_forward(struct sk_buff *skb, unsigned short family)
                return 0;
        }
 
-       return xfrm_lookup(net, &skb->dst, &fl, NULL, 0) == 0;
+       dst = skb_dst(skb);
+
+       res = xfrm_lookup(net, &dst, &fl, NULL, 0) == 0;
+       skb_dst_set(skb, dst);
+       return res;
 }
 EXPORT_SYMBOL(__xfrm_route_forward);
 
index 195906bce2663f09e4fb65c4e39edb2cd20d0d33..15c2a08a66f1217e92028a38e861ad4981ab3fdd 100644 (file)
@@ -4495,7 +4495,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex,
         * when the packet is on it's final way out.
         * NOTE: there appear to be some IPv6 multicast cases where skb->dst
         *       is NULL, in this case go ahead and apply access control. */
-       if (skb->dst != NULL && skb->dst->xfrm != NULL)
+       if (skb_dst(skb) != NULL && skb_dst(skb)->xfrm != NULL)
                return NF_ACCEPT;
 #endif
        secmark_active = selinux_secmark_enabled();
index c0eb72013d671a75a155481749b702a262521d65..72b18452e1a12035f20e4269e0ed6d4474e135f2 100644 (file)
@@ -447,7 +447,7 @@ int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb,
        struct dst_entry *dst;
        int rc = 0;
 
-       dst = skb->dst;
+       dst = skb_dst(skb);
 
        if (dst) {
                struct dst_entry *dst_test;
This page took 4.169786 seconds and 5 git commands to generate.